diff --git a/CMakeLists.txt b/CMakeLists.txt index 82bd11d9e..bd7994c01 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1052,7 +1052,19 @@ if (WOLFSSL_TLS13) "-DHAVE_SUPPORTED_CURVES") endif() -# TODO: - Session ticket +# Session Ticket Extension +set(WOLFSSL_SESSION_TICKET_HELP_STRING "Enable Session Ticket (default: disabled)") +add_option("WOLFSSL_SESSION_TICKET" ${WOLFSSL_SESSION_TICKET_HELP_STRING} "no" "yes;no") + +if(WOLFSSL_NGINX OR WOLFSSL_WPAS OR WOLFSSL_HAPROXY OR WOLFSSL_LIGHTY) + override_cache(WOLFSSL_SESSION_TICKET "yes") +endif() + +if(WOLFSSL_SESSION_TICKET) + list(APPEND WOLFSSL_DEFINITIONS + "-DHAVE_TLS_EXTENSIONS" + "-DHAVE_SESSION_TICKET") +endif() # Extended master secret extension set(WOLFSSL_EXTENDED_MASTER_HELP_STRING "Enable Extended Master Secret (default: enabled)") @@ -1345,6 +1357,8 @@ file(APPEND ${OPTION_FILE} "#ifdef __cplusplus\n") file(APPEND ${OPTION_FILE} "extern \"C\" {\n") file(APPEND ${OPTION_FILE} "#endif\n\n") +list(REMOVE_DUPLICATES WOLFSSL_DEFINITIONS) + foreach(DEF IN LISTS WOLFSSL_DEFINITIONS) if(DEF MATCHES "^-D") if(DEF MATCHES "^-D(N)?DEBUG(=.+)?") diff --git a/IDE/ARDUINO/sketches/wolfssl_client/wolfssl_client.ino b/IDE/ARDUINO/sketches/wolfssl_client/wolfssl_client.ino index a7f18a467..b5c83aa41 100644 --- a/IDE/ARDUINO/sketches/wolfssl_client/wolfssl_client.ino +++ b/IDE/ARDUINO/sketches/wolfssl_client/wolfssl_client.ino @@ -1,6 +1,6 @@ /* wolfssl_client.ino * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/ARDUINO/sketches/wolfssl_server/wolfssl_server.ino b/IDE/ARDUINO/sketches/wolfssl_server/wolfssl_server.ino index 26fac5767..6d5478d5a 100644 --- a/IDE/ARDUINO/sketches/wolfssl_server/wolfssl_server.ino +++ b/IDE/ARDUINO/sketches/wolfssl_server/wolfssl_server.ino @@ -1,6 +1,6 @@ /* wolfssl_server.ino * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/CRYPTOCELL/main.c b/IDE/CRYPTOCELL/main.c index 32ff58d71..ea889b8c8 100644 --- a/IDE/CRYPTOCELL/main.c +++ b/IDE/CRYPTOCELL/main.c @@ -1,6 +1,6 @@ /* main.c * - * Copyright (C) 2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -18,6 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ + #include #include #include diff --git a/IDE/CRYPTOCELL/user_settings.h b/IDE/CRYPTOCELL/user_settings.h index 78087f11b..380422d23 100644 --- a/IDE/CRYPTOCELL/user_settings.h +++ b/IDE/CRYPTOCELL/user_settings.h @@ -1,6 +1,6 @@ /* user_settings.h * - * Copyright (C) 2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/ECLIPSE/DEOS/deos_malloc.c b/IDE/ECLIPSE/DEOS/deos_malloc.c index e8b213001..3a9c140a2 100644 --- a/IDE/ECLIPSE/DEOS/deos_malloc.c +++ b/IDE/ECLIPSE/DEOS/deos_malloc.c @@ -1,6 +1,6 @@ /* deos_malloc.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/ECLIPSE/DEOS/tls_wolfssl.c b/IDE/ECLIPSE/DEOS/tls_wolfssl.c index 1abf5526d..18a0cf005 100644 --- a/IDE/ECLIPSE/DEOS/tls_wolfssl.c +++ b/IDE/ECLIPSE/DEOS/tls_wolfssl.c @@ -1,6 +1,6 @@ /* tls_wolfssl.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/ECLIPSE/DEOS/tls_wolfssl.h b/IDE/ECLIPSE/DEOS/tls_wolfssl.h index 062826fba..d54205b42 100644 --- a/IDE/ECLIPSE/DEOS/tls_wolfssl.h +++ b/IDE/ECLIPSE/DEOS/tls_wolfssl.h @@ -1,6 +1,6 @@ /* tls_wolfssl.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/ECLIPSE/DEOS/user_settings.h b/IDE/ECLIPSE/DEOS/user_settings.h index 5283e3d8a..dbfe4f03a 100644 --- a/IDE/ECLIPSE/DEOS/user_settings.h +++ b/IDE/ECLIPSE/DEOS/user_settings.h @@ -1,6 +1,6 @@ /* user_setting.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/ECLIPSE/MICRIUM/client_wolfssl.c b/IDE/ECLIPSE/MICRIUM/client_wolfssl.c index 241eb1df9..4e28a92eb 100644 --- a/IDE/ECLIPSE/MICRIUM/client_wolfssl.c +++ b/IDE/ECLIPSE/MICRIUM/client_wolfssl.c @@ -1,6 +1,6 @@ /* client_wolfssl.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/ECLIPSE/MICRIUM/client_wolfssl.h b/IDE/ECLIPSE/MICRIUM/client_wolfssl.h index e95f818ec..e1600674f 100644 --- a/IDE/ECLIPSE/MICRIUM/client_wolfssl.h +++ b/IDE/ECLIPSE/MICRIUM/client_wolfssl.h @@ -1,6 +1,6 @@ /* client_wolfssl.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/ECLIPSE/MICRIUM/server_wolfssl.c b/IDE/ECLIPSE/MICRIUM/server_wolfssl.c index a8d0a8232..20fe49073 100644 --- a/IDE/ECLIPSE/MICRIUM/server_wolfssl.c +++ b/IDE/ECLIPSE/MICRIUM/server_wolfssl.c @@ -1,6 +1,6 @@ /* server_wolfssl.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/ECLIPSE/MICRIUM/server_wolfssl.h b/IDE/ECLIPSE/MICRIUM/server_wolfssl.h index c75e1b927..f338db11f 100644 --- a/IDE/ECLIPSE/MICRIUM/server_wolfssl.h +++ b/IDE/ECLIPSE/MICRIUM/server_wolfssl.h @@ -1,6 +1,6 @@ /* server_wolfssl.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/ECLIPSE/MICRIUM/user_settings.h b/IDE/ECLIPSE/MICRIUM/user_settings.h index affd9d9ca..154a67714 100644 --- a/IDE/ECLIPSE/MICRIUM/user_settings.h +++ b/IDE/ECLIPSE/MICRIUM/user_settings.h @@ -1,6 +1,6 @@ /* user_setting.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/ECLIPSE/MICRIUM/wolfsslRunTests.c b/IDE/ECLIPSE/MICRIUM/wolfsslRunTests.c index 84f02b254..538484d49 100644 --- a/IDE/ECLIPSE/MICRIUM/wolfsslRunTests.c +++ b/IDE/ECLIPSE/MICRIUM/wolfsslRunTests.c @@ -1,6 +1,6 @@ /* wolfsslRunTests.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/ECLIPSE/RTTHREAD/user_settings.h b/IDE/ECLIPSE/RTTHREAD/user_settings.h index f28c968c6..9ea3951ab 100644 --- a/IDE/ECLIPSE/RTTHREAD/user_settings.h +++ b/IDE/ECLIPSE/RTTHREAD/user_settings.h @@ -1,6 +1,6 @@ /* user_setting.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/ECLIPSE/RTTHREAD/wolfssl_test.c b/IDE/ECLIPSE/RTTHREAD/wolfssl_test.c index 0dce7d0d0..7268303fd 100644 --- a/IDE/ECLIPSE/RTTHREAD/wolfssl_test.c +++ b/IDE/ECLIPSE/RTTHREAD/wolfssl_test.c @@ -1,6 +1,6 @@ /* wolfsslRunTests.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Espressif/ESP-IDF/dummy_config_h b/IDE/Espressif/ESP-IDF/dummy_config_h index 8d42a0cbf..74a682e85 100644 --- a/IDE/Espressif/ESP-IDF/dummy_config_h +++ b/IDE/Espressif/ESP-IDF/dummy_config_h @@ -1,6 +1,6 @@ /* config.h - dummy * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/main/helper.c b/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/main/helper.c index f2084a87d..371aaa6cc 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/main/helper.c +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/main/helper.c @@ -1,6 +1,6 @@ /* helper.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_client/main/client-tls.c b/IDE/Espressif/ESP-IDF/examples/wolfssl_client/main/client-tls.c index 64730aa77..1a4d20a6c 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_client/main/client-tls.c +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_client/main/client-tls.c @@ -1,6 +1,6 @@ /* client-tls-callback.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_client/main/include/wifi_connect.h b/IDE/Espressif/ESP-IDF/examples/wolfssl_client/main/include/wifi_connect.h index 8212b30e3..ab7de663b 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_client/main/include/wifi_connect.h +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_client/main/include/wifi_connect.h @@ -1,6 +1,6 @@ /* user_settings.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_client/main/wifi_connect.c b/IDE/Espressif/ESP-IDF/examples/wolfssl_client/main/wifi_connect.c index f4758c6ec..58f9751d4 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_client/main/wifi_connect.c +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_client/main/wifi_connect.c @@ -1,6 +1,6 @@ /* wifi_connect.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_server/main/include/wifi_connect.h b/IDE/Espressif/ESP-IDF/examples/wolfssl_server/main/include/wifi_connect.h index 948173572..5dd9625ee 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_server/main/include/wifi_connect.h +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_server/main/include/wifi_connect.h @@ -1,6 +1,6 @@ /* wifi_connect.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_server/main/server-tls.c b/IDE/Espressif/ESP-IDF/examples/wolfssl_server/main/server-tls.c index a3beca538..c31e21855 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_server/main/server-tls.c +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_server/main/server-tls.c @@ -1,6 +1,6 @@ /* server-tls-callback.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_server/main/wifi_connect.c b/IDE/Espressif/ESP-IDF/examples/wolfssl_server/main/wifi_connect.c index 3848fbfe9..471ab3de5 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_server/main/wifi_connect.c +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_server/main/wifi_connect.c @@ -1,6 +1,6 @@ /* wifi_connect.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Espressif/ESP-IDF/user_settings.h b/IDE/Espressif/ESP-IDF/user_settings.h index 67b2d4391..2e6252322 100644 --- a/IDE/Espressif/ESP-IDF/user_settings.h +++ b/IDE/Espressif/ESP-IDF/user_settings.h @@ -1,6 +1,6 @@ /* user_settings.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/GCC-ARM/Header/user_settings.h b/IDE/GCC-ARM/Header/user_settings.h index dff00b0d9..c3b61925f 100644 --- a/IDE/GCC-ARM/Header/user_settings.h +++ b/IDE/GCC-ARM/Header/user_settings.h @@ -1,6 +1,6 @@ /* user_settings.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/GCC-ARM/Source/armtarget.c b/IDE/GCC-ARM/Source/armtarget.c index 8b276463f..c718c6ba5 100644 --- a/IDE/GCC-ARM/Source/armtarget.c +++ b/IDE/GCC-ARM/Source/armtarget.c @@ -1,6 +1,6 @@ /* armtarget.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/GCC-ARM/Source/benchmark_main.c b/IDE/GCC-ARM/Source/benchmark_main.c index 7f91e7ccb..d6d610fd0 100644 --- a/IDE/GCC-ARM/Source/benchmark_main.c +++ b/IDE/GCC-ARM/Source/benchmark_main.c @@ -1,6 +1,6 @@ /* benchmark_main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/GCC-ARM/Source/test_main.c b/IDE/GCC-ARM/Source/test_main.c index d3d525a76..9320c57c5 100644 --- a/IDE/GCC-ARM/Source/test_main.c +++ b/IDE/GCC-ARM/Source/test_main.c @@ -1,6 +1,6 @@ /* test_main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/GCC-ARM/Source/tls_client.c b/IDE/GCC-ARM/Source/tls_client.c index 43c0b73f9..66ea21626 100644 --- a/IDE/GCC-ARM/Source/tls_client.c +++ b/IDE/GCC-ARM/Source/tls_client.c @@ -1,6 +1,6 @@ /* tls_client.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/GCC-ARM/Source/wolf_main.c b/IDE/GCC-ARM/Source/wolf_main.c index de1ec7adf..c47b0cec6 100644 --- a/IDE/GCC-ARM/Source/wolf_main.c +++ b/IDE/GCC-ARM/Source/wolf_main.c @@ -1,6 +1,6 @@ /* wolf_main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/HEXAGON/DSP/Makefile b/IDE/HEXAGON/DSP/Makefile index 1cf0ccb0d..42022dda3 100644 --- a/IDE/HEXAGON/DSP/Makefile +++ b/IDE/HEXAGON/DSP/Makefile @@ -1,6 +1,6 @@ # Makefile # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -17,6 +17,7 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA +#/ ENVI=hexagon diff --git a/IDE/HEXAGON/Makefile b/IDE/HEXAGON/Makefile index 87ed33cd4..11dea412b 100644 --- a/IDE/HEXAGON/Makefile +++ b/IDE/HEXAGON/Makefile @@ -1,6 +1,6 @@ # Makefile # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -17,6 +17,7 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA +#/ ENVI=UbuntuARM diff --git a/IDE/HEXAGON/ecc-verify-benchmark.c b/IDE/HEXAGON/ecc-verify-benchmark.c index a9e7ad8d6..6bc183fed 100644 --- a/IDE/HEXAGON/ecc-verify-benchmark.c +++ b/IDE/HEXAGON/ecc-verify-benchmark.c @@ -1,6 +1,6 @@ /* ecc-verify-benchmark.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/HEXAGON/ecc-verify.c b/IDE/HEXAGON/ecc-verify.c index 835301c75..0ffed79ad 100644 --- a/IDE/HEXAGON/ecc-verify.c +++ b/IDE/HEXAGON/ecc-verify.c @@ -1,6 +1,6 @@ /* ecc-verify.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/IAR-EWARM/Projects/benchmark/benchmark-main.c b/IDE/IAR-EWARM/Projects/benchmark/benchmark-main.c index 49acf8060..44016be28 100644 --- a/IDE/IAR-EWARM/Projects/benchmark/benchmark-main.c +++ b/IDE/IAR-EWARM/Projects/benchmark/benchmark-main.c @@ -1,6 +1,6 @@ /* benchmark-main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/IAR-EWARM/Projects/benchmark/current_time.c b/IDE/IAR-EWARM/Projects/benchmark/current_time.c index 1e96a0bca..1fbc1d17f 100644 --- a/IDE/IAR-EWARM/Projects/benchmark/current_time.c +++ b/IDE/IAR-EWARM/Projects/benchmark/current_time.c @@ -1,6 +1,6 @@ /* current-time.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/IAR-EWARM/Projects/common/minimum-startup.c b/IDE/IAR-EWARM/Projects/common/minimum-startup.c index 3fbff1166..01ceaa51c 100644 --- a/IDE/IAR-EWARM/Projects/common/minimum-startup.c +++ b/IDE/IAR-EWARM/Projects/common/minimum-startup.c @@ -1,6 +1,6 @@ /* minimum-startup.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/IAR-EWARM/Projects/test/test-main.c b/IDE/IAR-EWARM/Projects/test/test-main.c index 28c1a01e2..4b1b61430 100644 --- a/IDE/IAR-EWARM/Projects/test/test-main.c +++ b/IDE/IAR-EWARM/Projects/test/test-main.c @@ -1,6 +1,6 @@ /* test-main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/LPCXPRESSO/lib_wolfssl/lpc_18xx_port.c b/IDE/LPCXPRESSO/lib_wolfssl/lpc_18xx_port.c index c02496838..810e5cf83 100644 --- a/IDE/LPCXPRESSO/lib_wolfssl/lpc_18xx_port.c +++ b/IDE/LPCXPRESSO/lib_wolfssl/lpc_18xx_port.c @@ -1,6 +1,6 @@ /* lpc_18xx_port.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/LPCXPRESSO/wolf_example/src/lpc_18xx_startup.c b/IDE/LPCXPRESSO/wolf_example/src/lpc_18xx_startup.c index ef7432167..e5b722c4f 100644 --- a/IDE/LPCXPRESSO/wolf_example/src/lpc_18xx_startup.c +++ b/IDE/LPCXPRESSO/wolf_example/src/lpc_18xx_startup.c @@ -1,6 +1,6 @@ /* lpc_18xx_startup.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/M68K/benchmark/main.cpp b/IDE/M68K/benchmark/main.cpp index 7a42ae48f..b66b805f6 100644 --- a/IDE/M68K/benchmark/main.cpp +++ b/IDE/M68K/benchmark/main.cpp @@ -1,6 +1,6 @@ /* main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/M68K/testwolfcrypt/main.cpp b/IDE/M68K/testwolfcrypt/main.cpp index 90f894a32..6380bd782 100644 --- a/IDE/M68K/testwolfcrypt/main.cpp +++ b/IDE/M68K/testwolfcrypt/main.cpp @@ -1,6 +1,6 @@ /* main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK-ARM/LPC43xx/time-LCP43xx.c b/IDE/MDK-ARM/LPC43xx/time-LCP43xx.c index 3cdf214d7..150415861 100644 --- a/IDE/MDK-ARM/LPC43xx/time-LCP43xx.c +++ b/IDE/MDK-ARM/LPC43xx/time-LCP43xx.c @@ -1,6 +1,6 @@ /* time.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK-ARM/MDK-ARM/wolfSSL/cert_data.c b/IDE/MDK-ARM/MDK-ARM/wolfSSL/cert_data.c index a094bb1dd..5b7402f57 100644 --- a/IDE/MDK-ARM/MDK-ARM/wolfSSL/cert_data.c +++ b/IDE/MDK-ARM/MDK-ARM/wolfSSL/cert_data.c @@ -1,6 +1,6 @@ /* certs_test.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK-ARM/MDK-ARM/wolfSSL/config-BARE-METAL.h b/IDE/MDK-ARM/MDK-ARM/wolfSSL/config-BARE-METAL.h index 21974401e..4a1e452fc 100644 --- a/IDE/MDK-ARM/MDK-ARM/wolfSSL/config-BARE-METAL.h +++ b/IDE/MDK-ARM/MDK-ARM/wolfSSL/config-BARE-METAL.h @@ -1,6 +1,6 @@ /* config-BEREFOOT.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK-ARM/MDK-ARM/wolfSSL/config-FS.h b/IDE/MDK-ARM/MDK-ARM/wolfSSL/config-FS.h index daeb75b88..b77821155 100644 --- a/IDE/MDK-ARM/MDK-ARM/wolfSSL/config-FS.h +++ b/IDE/MDK-ARM/MDK-ARM/wolfSSL/config-FS.h @@ -1,6 +1,6 @@ /* config-FS.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK-ARM/MDK-ARM/wolfSSL/config-RTX-TCP-FS.h b/IDE/MDK-ARM/MDK-ARM/wolfSSL/config-RTX-TCP-FS.h index 193eb2531..626a1c348 100644 --- a/IDE/MDK-ARM/MDK-ARM/wolfSSL/config-RTX-TCP-FS.h +++ b/IDE/MDK-ARM/MDK-ARM/wolfSSL/config-RTX-TCP-FS.h @@ -1,6 +1,6 @@ /* config-RTX-TCP-FS.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK-ARM/MDK-ARM/wolfSSL/config.h b/IDE/MDK-ARM/MDK-ARM/wolfSSL/config.h index de37fa143..fba3347eb 100644 --- a/IDE/MDK-ARM/MDK-ARM/wolfSSL/config.h +++ b/IDE/MDK-ARM/MDK-ARM/wolfSSL/config.h @@ -1,6 +1,6 @@ /* config.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK-ARM/MDK-ARM/wolfSSL/main.c b/IDE/MDK-ARM/MDK-ARM/wolfSSL/main.c index fab05b7e8..fd43e40cf 100644 --- a/IDE/MDK-ARM/MDK-ARM/wolfSSL/main.c +++ b/IDE/MDK-ARM/MDK-ARM/wolfSSL/main.c @@ -1,6 +1,6 @@ /* main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK-ARM/MDK-ARM/wolfSSL/shell.c b/IDE/MDK-ARM/MDK-ARM/wolfSSL/shell.c index fad4ec34b..0b8bf4063 100644 --- a/IDE/MDK-ARM/MDK-ARM/wolfSSL/shell.c +++ b/IDE/MDK-ARM/MDK-ARM/wolfSSL/shell.c @@ -1,6 +1,6 @@ /*shell.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK-ARM/MDK-ARM/wolfSSL/time-CortexM3-4.c b/IDE/MDK-ARM/MDK-ARM/wolfSSL/time-CortexM3-4.c index ed6b53d97..a057f6d63 100644 --- a/IDE/MDK-ARM/MDK-ARM/wolfSSL/time-CortexM3-4.c +++ b/IDE/MDK-ARM/MDK-ARM/wolfSSL/time-CortexM3-4.c @@ -1,6 +1,6 @@ /* time-STM32F2.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK-ARM/MDK-ARM/wolfSSL/time-dummy.c b/IDE/MDK-ARM/MDK-ARM/wolfSSL/time-dummy.c index b934398f1..07c8bb682 100644 --- a/IDE/MDK-ARM/MDK-ARM/wolfSSL/time-dummy.c +++ b/IDE/MDK-ARM/MDK-ARM/wolfSSL/time-dummy.c @@ -1,6 +1,6 @@ /* time-dummy.c.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK-ARM/MDK-ARM/wolfSSL/wolfssl_MDK_ARM.c b/IDE/MDK-ARM/MDK-ARM/wolfSSL/wolfssl_MDK_ARM.c index 7158af50d..d5636b493 100644 --- a/IDE/MDK-ARM/MDK-ARM/wolfSSL/wolfssl_MDK_ARM.c +++ b/IDE/MDK-ARM/MDK-ARM/wolfSSL/wolfssl_MDK_ARM.c @@ -1,6 +1,6 @@ /* wolfssl_KEIL_RL.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK-ARM/MDK-ARM/wolfSSL/wolfssl_MDK_ARM.h b/IDE/MDK-ARM/MDK-ARM/wolfSSL/wolfssl_MDK_ARM.h index b334a45e0..6a2165fab 100644 --- a/IDE/MDK-ARM/MDK-ARM/wolfSSL/wolfssl_MDK_ARM.h +++ b/IDE/MDK-ARM/MDK-ARM/wolfSSL/wolfssl_MDK_ARM.h @@ -1,6 +1,6 @@ /* wolfssl_KEIL_RL.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK-ARM/STM32F2xx_StdPeriph_Lib/time-STM32F2xx.c b/IDE/MDK-ARM/STM32F2xx_StdPeriph_Lib/time-STM32F2xx.c index 6480e10cc..8a2ce67b8 100644 --- a/IDE/MDK-ARM/STM32F2xx_StdPeriph_Lib/time-STM32F2xx.c +++ b/IDE/MDK-ARM/STM32F2xx_StdPeriph_Lib/time-STM32F2xx.c @@ -1,6 +1,6 @@ /* time-STM32F2xx.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK5-ARM/Conf/user_settings.h b/IDE/MDK5-ARM/Conf/user_settings.h index 5251f1470..98f168809 100644 --- a/IDE/MDK5-ARM/Conf/user_settings.h +++ b/IDE/MDK5-ARM/Conf/user_settings.h @@ -1,6 +1,6 @@ /* user_settings.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK5-ARM/Inc/wolfssl_MDK_ARM.h b/IDE/MDK5-ARM/Inc/wolfssl_MDK_ARM.h index 4645d7c39..00bce98bf 100644 --- a/IDE/MDK5-ARM/Inc/wolfssl_MDK_ARM.h +++ b/IDE/MDK5-ARM/Inc/wolfssl_MDK_ARM.h @@ -1,6 +1,6 @@ /* wolfssl_KEIL_ARM.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK5-ARM/Projects/CryptBenchmark/RTE/wolfSSL/user_settings.h b/IDE/MDK5-ARM/Projects/CryptBenchmark/RTE/wolfSSL/user_settings.h index 9ce8e4d0b..639e0fc50 100644 --- a/IDE/MDK5-ARM/Projects/CryptBenchmark/RTE/wolfSSL/user_settings.h +++ b/IDE/MDK5-ARM/Projects/CryptBenchmark/RTE/wolfSSL/user_settings.h @@ -1,6 +1,6 @@ /* user_settings.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK5-ARM/Projects/CryptBenchmark/main.c b/IDE/MDK5-ARM/Projects/CryptBenchmark/main.c index 1b32a4710..38c167ac0 100644 --- a/IDE/MDK5-ARM/Projects/CryptBenchmark/main.c +++ b/IDE/MDK5-ARM/Projects/CryptBenchmark/main.c @@ -1,6 +1,6 @@ /* main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK5-ARM/Projects/CryptTest/RTE/wolfSSL/user_settings.h b/IDE/MDK5-ARM/Projects/CryptTest/RTE/wolfSSL/user_settings.h index 1645d956c..96106ffc1 100644 --- a/IDE/MDK5-ARM/Projects/CryptTest/RTE/wolfSSL/user_settings.h +++ b/IDE/MDK5-ARM/Projects/CryptTest/RTE/wolfSSL/user_settings.h @@ -1,6 +1,6 @@ /* user_settings.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK5-ARM/Projects/CryptTest/main.c b/IDE/MDK5-ARM/Projects/CryptTest/main.c index ea6ad3851..7ff887cd8 100644 --- a/IDE/MDK5-ARM/Projects/CryptTest/main.c +++ b/IDE/MDK5-ARM/Projects/CryptTest/main.c @@ -1,6 +1,6 @@ /* main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK5-ARM/Projects/EchoClient/RTE/wolfSSL/user_settings.h b/IDE/MDK5-ARM/Projects/EchoClient/RTE/wolfSSL/user_settings.h index a62071372..4ddba7092 100644 --- a/IDE/MDK5-ARM/Projects/EchoClient/RTE/wolfSSL/user_settings.h +++ b/IDE/MDK5-ARM/Projects/EchoClient/RTE/wolfSSL/user_settings.h @@ -1,6 +1,6 @@ /* user_settings.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK5-ARM/Projects/EchoClient/main.c b/IDE/MDK5-ARM/Projects/EchoClient/main.c index 2c74bd3bb..62832e60a 100644 --- a/IDE/MDK5-ARM/Projects/EchoClient/main.c +++ b/IDE/MDK5-ARM/Projects/EchoClient/main.c @@ -1,6 +1,6 @@ /* main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK5-ARM/Projects/EchoServer/RTE/wolfSSL/user_settings.h b/IDE/MDK5-ARM/Projects/EchoServer/RTE/wolfSSL/user_settings.h index 4caaed5d0..36806c07e 100644 --- a/IDE/MDK5-ARM/Projects/EchoServer/RTE/wolfSSL/user_settings.h +++ b/IDE/MDK5-ARM/Projects/EchoServer/RTE/wolfSSL/user_settings.h @@ -1,6 +1,6 @@ /* user_settings.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK5-ARM/Projects/EchoServer/main.c b/IDE/MDK5-ARM/Projects/EchoServer/main.c index f3c252a58..2be031964 100644 --- a/IDE/MDK5-ARM/Projects/EchoServer/main.c +++ b/IDE/MDK5-ARM/Projects/EchoServer/main.c @@ -1,6 +1,6 @@ /* main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK5-ARM/Projects/SimpleClient/RTE/wolfSSL/user_settings.h b/IDE/MDK5-ARM/Projects/SimpleClient/RTE/wolfSSL/user_settings.h index 74630fa88..5f47c6c93 100644 --- a/IDE/MDK5-ARM/Projects/SimpleClient/RTE/wolfSSL/user_settings.h +++ b/IDE/MDK5-ARM/Projects/SimpleClient/RTE/wolfSSL/user_settings.h @@ -1,6 +1,6 @@ /* user_settings.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK5-ARM/Projects/SimpleClient/main.c b/IDE/MDK5-ARM/Projects/SimpleClient/main.c index 21f058eba..09447b745 100644 --- a/IDE/MDK5-ARM/Projects/SimpleClient/main.c +++ b/IDE/MDK5-ARM/Projects/SimpleClient/main.c @@ -1,6 +1,6 @@ /* main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK5-ARM/Projects/SimpleServer/RTE/wolfSSL/user_settings.h b/IDE/MDK5-ARM/Projects/SimpleServer/RTE/wolfSSL/user_settings.h index 74630fa88..5f47c6c93 100644 --- a/IDE/MDK5-ARM/Projects/SimpleServer/RTE/wolfSSL/user_settings.h +++ b/IDE/MDK5-ARM/Projects/SimpleServer/RTE/wolfSSL/user_settings.h @@ -1,6 +1,6 @@ /* user_settings.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK5-ARM/Projects/SimpleServer/main.c b/IDE/MDK5-ARM/Projects/SimpleServer/main.c index 823d17548..9f28ab1e2 100644 --- a/IDE/MDK5-ARM/Projects/SimpleServer/main.c +++ b/IDE/MDK5-ARM/Projects/SimpleServer/main.c @@ -1,6 +1,6 @@ /* main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK5-ARM/Projects/wolfSSL-Full/main.c b/IDE/MDK5-ARM/Projects/wolfSSL-Full/main.c index 3320923cc..57562cc60 100644 --- a/IDE/MDK5-ARM/Projects/wolfSSL-Full/main.c +++ b/IDE/MDK5-ARM/Projects/wolfSSL-Full/main.c @@ -1,6 +1,6 @@ /* main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK5-ARM/Projects/wolfSSL-Full/shell.c b/IDE/MDK5-ARM/Projects/wolfSSL-Full/shell.c index 37a8e52e4..489665e9a 100644 --- a/IDE/MDK5-ARM/Projects/wolfSSL-Full/shell.c +++ b/IDE/MDK5-ARM/Projects/wolfSSL-Full/shell.c @@ -1,6 +1,6 @@ /*shell.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK5-ARM/Projects/wolfSSL-Full/time-CortexM3-4.c b/IDE/MDK5-ARM/Projects/wolfSSL-Full/time-CortexM3-4.c index ee71c2a02..b64340f75 100644 --- a/IDE/MDK5-ARM/Projects/wolfSSL-Full/time-CortexM3-4.c +++ b/IDE/MDK5-ARM/Projects/wolfSSL-Full/time-CortexM3-4.c @@ -1,6 +1,6 @@ /* time-STM32F2.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK5-ARM/Projects/wolfSSL-Lib/RTE/wolfSSL/user_settings.h b/IDE/MDK5-ARM/Projects/wolfSSL-Lib/RTE/wolfSSL/user_settings.h index 74630fa88..5f47c6c93 100644 --- a/IDE/MDK5-ARM/Projects/wolfSSL-Lib/RTE/wolfSSL/user_settings.h +++ b/IDE/MDK5-ARM/Projects/wolfSSL-Lib/RTE/wolfSSL/user_settings.h @@ -1,6 +1,6 @@ /* user_settings.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MDK5-ARM/Src/ssl-dummy.c b/IDE/MDK5-ARM/Src/ssl-dummy.c index 7a6e6961f..1aec62898 100644 --- a/IDE/MDK5-ARM/Src/ssl-dummy.c +++ b/IDE/MDK5-ARM/Src/ssl-dummy.c @@ -1,6 +1,6 @@ /* ssl-dummy.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/MQX/client-tls.c b/IDE/MQX/client-tls.c index b16987624..ced96d33c 100644 --- a/IDE/MQX/client-tls.c +++ b/IDE/MQX/client-tls.c @@ -1,8 +1,8 @@ /* client-tls.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * - * This file is part of wolfSSL. (formerly known as CyaSSL) + * This file is part of wolfSSL. * * wolfSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,8 +16,9 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ + /* wolfSSL */ diff --git a/IDE/MQX/server-tls.c b/IDE/MQX/server-tls.c index 47f1a05c3..211f65513 100644 --- a/IDE/MQX/server-tls.c +++ b/IDE/MQX/server-tls.c @@ -1,8 +1,8 @@ /* server-tls.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * - * This file is part of wolfSSL. (formerly known as CyaSSL) + * This file is part of wolfSSL. * * wolfSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,8 +16,9 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ + /* wolfSSL */ #include diff --git a/IDE/MYSQL/CMakeLists_wolfCrypt.txt b/IDE/MYSQL/CMakeLists_wolfCrypt.txt index db977dd05..c7c13196e 100644 --- a/IDE/MYSQL/CMakeLists_wolfCrypt.txt +++ b/IDE/MYSQL/CMakeLists_wolfCrypt.txt @@ -1,6 +1,6 @@ # CMakeLists.txt # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -18,6 +18,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/include diff --git a/IDE/MYSQL/CMakeLists_wolfSSL.txt b/IDE/MYSQL/CMakeLists_wolfSSL.txt index 28bda396b..aab778220 100644 --- a/IDE/MYSQL/CMakeLists_wolfSSL.txt +++ b/IDE/MYSQL/CMakeLists_wolfSSL.txt @@ -1,6 +1,6 @@ # CMakeLists.txt # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -18,6 +18,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/include diff --git a/IDE/QNX/example-client/client-tls.c b/IDE/QNX/example-client/client-tls.c index 8b351440a..d6e890d4a 100644 --- a/IDE/QNX/example-client/client-tls.c +++ b/IDE/QNX/example-client/client-tls.c @@ -1,8 +1,8 @@ /* client-tls.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * - * This file is part of wolfSSL. (formerly known as CyaSSL) + * This file is part of wolfSSL. * * wolfSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ #include diff --git a/IDE/QNX/example-cmac/cmac-test.c b/IDE/QNX/example-cmac/cmac-test.c index 7b781e8c1..0027031d4 100644 --- a/IDE/QNX/example-cmac/cmac-test.c +++ b/IDE/QNX/example-cmac/cmac-test.c @@ -1,8 +1,8 @@ /* cmac-test.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * - * This file is part of wolfSSL. (formerly known as CyaSSL) + * This file is part of wolfSSL. * * wolfSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ #include diff --git a/IDE/QNX/example-server/server-tls.c b/IDE/QNX/example-server/server-tls.c index 6e8cb612e..ebd68ece8 100644 --- a/IDE/QNX/example-server/server-tls.c +++ b/IDE/QNX/example-server/server-tls.c @@ -1,8 +1,8 @@ /* server-tls.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * - * This file is part of wolfSSL. (formerly known as CyaSSL) + * This file is part of wolfSSL. * * wolfSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ #include diff --git a/IDE/RISCV/SIFIVE-HIFIVE1/main.c b/IDE/RISCV/SIFIVE-HIFIVE1/main.c index a3e4a19c0..84611784b 100644 --- a/IDE/RISCV/SIFIVE-HIFIVE1/main.c +++ b/IDE/RISCV/SIFIVE-HIFIVE1/main.c @@ -1,6 +1,6 @@ /* main.c * - * Copyright (C) 2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/RISCV/SIFIVE-HIFIVE1/user_settings.h b/IDE/RISCV/SIFIVE-HIFIVE1/user_settings.h index 19a5686b2..b70cb2624 100644 --- a/IDE/RISCV/SIFIVE-HIFIVE1/user_settings.h +++ b/IDE/RISCV/SIFIVE-HIFIVE1/user_settings.h @@ -1,6 +1,6 @@ /* user_settings.h * - * Copyright (C) 2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/arm_startup.c b/IDE/ROWLEY-CROSSWORKS-ARM/arm_startup.c index 8d7d07488..d838357b1 100644 --- a/IDE/ROWLEY-CROSSWORKS-ARM/arm_startup.c +++ b/IDE/ROWLEY-CROSSWORKS-ARM/arm_startup.c @@ -1,6 +1,6 @@ /* arm_startup.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/benchmark_main.c b/IDE/ROWLEY-CROSSWORKS-ARM/benchmark_main.c index 4d3b63983..8fc13dc6c 100644 --- a/IDE/ROWLEY-CROSSWORKS-ARM/benchmark_main.c +++ b/IDE/ROWLEY-CROSSWORKS-ARM/benchmark_main.c @@ -1,6 +1,6 @@ /* benchmark_main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/kinetis_hw.c b/IDE/ROWLEY-CROSSWORKS-ARM/kinetis_hw.c index 8476b0f58..ae5802316 100644 --- a/IDE/ROWLEY-CROSSWORKS-ARM/kinetis_hw.c +++ b/IDE/ROWLEY-CROSSWORKS-ARM/kinetis_hw.c @@ -1,6 +1,6 @@ /* kinetis_hw.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/retarget.c b/IDE/ROWLEY-CROSSWORKS-ARM/retarget.c index c0b6602af..b3841f671 100644 --- a/IDE/ROWLEY-CROSSWORKS-ARM/retarget.c +++ b/IDE/ROWLEY-CROSSWORKS-ARM/retarget.c @@ -1,6 +1,6 @@ /* retarget.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/test_main.c b/IDE/ROWLEY-CROSSWORKS-ARM/test_main.c index b26835b87..3b2b3e644 100644 --- a/IDE/ROWLEY-CROSSWORKS-ARM/test_main.c +++ b/IDE/ROWLEY-CROSSWORKS-ARM/test_main.c @@ -1,6 +1,6 @@ /* test_main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/cs+/Projects/common/strings.h b/IDE/Renesas/cs+/Projects/common/strings.h index fd2cf86e6..e3752588e 100644 --- a/IDE/Renesas/cs+/Projects/common/strings.h +++ b/IDE/Renesas/cs+/Projects/common/strings.h @@ -1,6 +1,6 @@ /* strings.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/cs+/Projects/common/unistd.h b/IDE/Renesas/cs+/Projects/common/unistd.h index d91dd4790..962ad47ee 100644 --- a/IDE/Renesas/cs+/Projects/common/unistd.h +++ b/IDE/Renesas/cs+/Projects/common/unistd.h @@ -1,6 +1,6 @@ /* unistd.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/cs+/Projects/common/user_settings.h b/IDE/Renesas/cs+/Projects/common/user_settings.h index 241316fc3..eef1d3331 100644 --- a/IDE/Renesas/cs+/Projects/common/user_settings.h +++ b/IDE/Renesas/cs+/Projects/common/user_settings.h @@ -1,6 +1,6 @@ /* user_settings.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/cs+/Projects/common/wolfssl_dummy.c b/IDE/Renesas/cs+/Projects/common/wolfssl_dummy.c index 7541fccc6..cfba7259e 100644 --- a/IDE/Renesas/cs+/Projects/common/wolfssl_dummy.c +++ b/IDE/Renesas/cs+/Projects/common/wolfssl_dummy.c @@ -1,6 +1,6 @@ /* wolfssl_dummy.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/cs+/Projects/t4_demo/wolf_client.c b/IDE/Renesas/cs+/Projects/t4_demo/wolf_client.c index ac7ff1e43..49628d8ba 100644 --- a/IDE/Renesas/cs+/Projects/t4_demo/wolf_client.c +++ b/IDE/Renesas/cs+/Projects/t4_demo/wolf_client.c @@ -1,6 +1,6 @@ /* wolf_client.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/cs+/Projects/t4_demo/wolf_main.c b/IDE/Renesas/cs+/Projects/t4_demo/wolf_main.c index 8e3f4c54b..c50c858c2 100644 --- a/IDE/Renesas/cs+/Projects/t4_demo/wolf_main.c +++ b/IDE/Renesas/cs+/Projects/t4_demo/wolf_main.c @@ -1,6 +1,6 @@ /* wolf_main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/cs+/Projects/t4_demo/wolf_server.c b/IDE/Renesas/cs+/Projects/t4_demo/wolf_server.c index bcb3e3390..97ca42816 100644 --- a/IDE/Renesas/cs+/Projects/t4_demo/wolf_server.c +++ b/IDE/Renesas/cs+/Projects/t4_demo/wolf_server.c @@ -1,6 +1,6 @@ /* wolf_server.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/cs+/Projects/test/test_main.c b/IDE/Renesas/cs+/Projects/test/test_main.c index 8defb1d14..9493273cb 100644 --- a/IDE/Renesas/cs+/Projects/test/test_main.c +++ b/IDE/Renesas/cs+/Projects/test/test_main.c @@ -1,6 +1,6 @@ /* test_main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/DK-S7G2/benchmark-template/src/app_entry.c b/IDE/Renesas/e2studio/DK-S7G2/benchmark-template/src/app_entry.c index be610ccdb..f78c41ca5 100644 --- a/IDE/Renesas/e2studio/DK-S7G2/benchmark-template/src/app_entry.c +++ b/IDE/Renesas/e2studio/DK-S7G2/benchmark-template/src/app_entry.c @@ -1,6 +1,6 @@ /* app_entry.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -18,6 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ + #include "app.h" #include "stdio.h" diff --git a/IDE/Renesas/e2studio/DK-S7G2/example_server-template/src/app_entry.c b/IDE/Renesas/e2studio/DK-S7G2/example_server-template/src/app_entry.c index a83322322..d7df11ce9 100644 --- a/IDE/Renesas/e2studio/DK-S7G2/example_server-template/src/app_entry.c +++ b/IDE/Renesas/e2studio/DK-S7G2/example_server-template/src/app_entry.c @@ -1,6 +1,6 @@ /* app_entry.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -18,6 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ + #include "app.h" diff --git a/IDE/Renesas/e2studio/DK-S7G2/wolfcrypttest-template/src/app_entry.c b/IDE/Renesas/e2studio/DK-S7G2/wolfcrypttest-template/src/app_entry.c index c9eee735e..a0821fa04 100644 --- a/IDE/Renesas/e2studio/DK-S7G2/wolfcrypttest-template/src/app_entry.c +++ b/IDE/Renesas/e2studio/DK-S7G2/wolfcrypttest-template/src/app_entry.c @@ -1,6 +1,6 @@ /* app_entry.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -18,6 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ + #include diff --git a/IDE/Renesas/e2studio/GR-ROSE/common/strings.h b/IDE/Renesas/e2studio/GR-ROSE/common/strings.h index fd2cf86e6..e3752588e 100644 --- a/IDE/Renesas/e2studio/GR-ROSE/common/strings.h +++ b/IDE/Renesas/e2studio/GR-ROSE/common/strings.h @@ -1,6 +1,6 @@ /* strings.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/GR-ROSE/common/unistd.h b/IDE/Renesas/e2studio/GR-ROSE/common/unistd.h index d91dd4790..962ad47ee 100644 --- a/IDE/Renesas/e2studio/GR-ROSE/common/unistd.h +++ b/IDE/Renesas/e2studio/GR-ROSE/common/unistd.h @@ -1,6 +1,6 @@ /* unistd.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/GR-ROSE/common/user_settings.h b/IDE/Renesas/e2studio/GR-ROSE/common/user_settings.h index f47e578dc..52d87c9c6 100644 --- a/IDE/Renesas/e2studio/GR-ROSE/common/user_settings.h +++ b/IDE/Renesas/e2studio/GR-ROSE/common/user_settings.h @@ -1,6 +1,6 @@ /* user_settings.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/GR-ROSE/common/wolfssl_dummy.c b/IDE/Renesas/e2studio/GR-ROSE/common/wolfssl_dummy.c index 8fa6340b4..a31c43cdc 100644 --- a/IDE/Renesas/e2studio/GR-ROSE/common/wolfssl_dummy.c +++ b/IDE/Renesas/e2studio/GR-ROSE/common/wolfssl_dummy.c @@ -1,6 +1,6 @@ /* wolfssl_dummy.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/GR-ROSE/test/src/key_data.c b/IDE/Renesas/e2studio/GR-ROSE/test/src/key_data.c index 01aa6015b..4a4fd08a3 100644 --- a/IDE/Renesas/e2studio/GR-ROSE/test/src/key_data.c +++ b/IDE/Renesas/e2studio/GR-ROSE/test/src/key_data.c @@ -1,6 +1,6 @@ /* key_data.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -18,6 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ + #include "key_data.h" diff --git a/IDE/Renesas/e2studio/GR-ROSE/test/src/key_data.h b/IDE/Renesas/e2studio/GR-ROSE/test/src/key_data.h index 958977c06..efc8c4576 100644 --- a/IDE/Renesas/e2studio/GR-ROSE/test/src/key_data.h +++ b/IDE/Renesas/e2studio/GR-ROSE/test/src/key_data.h @@ -1,6 +1,6 @@ /* key_data.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -18,6 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ + #ifndef KEY_DATA_H_ #define KEY_DATA_H_ diff --git a/IDE/Renesas/e2studio/GR-ROSE/test/src/test_main.c b/IDE/Renesas/e2studio/GR-ROSE/test/src/test_main.c index 7d336826a..5979896f8 100644 --- a/IDE/Renesas/e2studio/GR-ROSE/test/src/test_main.c +++ b/IDE/Renesas/e2studio/GR-ROSE/test/src/test_main.c @@ -1,6 +1,6 @@ /* test_main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/GR-ROSE/test/src/wolf_client.c b/IDE/Renesas/e2studio/GR-ROSE/test/src/wolf_client.c index ff09b1a80..cc1eeac79 100644 --- a/IDE/Renesas/e2studio/GR-ROSE/test/src/wolf_client.c +++ b/IDE/Renesas/e2studio/GR-ROSE/test/src/wolf_client.c @@ -1,6 +1,6 @@ /* wolf_client.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/GR-ROSE/test/src/wolf_server.c b/IDE/Renesas/e2studio/GR-ROSE/test/src/wolf_server.c index 5d38b0358..b193fbe71 100644 --- a/IDE/Renesas/e2studio/GR-ROSE/test/src/wolf_server.c +++ b/IDE/Renesas/e2studio/GR-ROSE/test/src/wolf_server.c @@ -1,6 +1,6 @@ /* wolf_server.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/GR-ROSE/test/src/wolfssl_demo.h b/IDE/Renesas/e2studio/GR-ROSE/test/src/wolfssl_demo.h index ca5482007..96e0eab3f 100644 --- a/IDE/Renesas/e2studio/GR-ROSE/test/src/wolfssl_demo.h +++ b/IDE/Renesas/e2studio/GR-ROSE/test/src/wolfssl_demo.h @@ -1,6 +1,6 @@ /* wolfssl_demo.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/Projects/common/strings.h b/IDE/Renesas/e2studio/Projects/common/strings.h index fd2cf86e6..e3752588e 100644 --- a/IDE/Renesas/e2studio/Projects/common/strings.h +++ b/IDE/Renesas/e2studio/Projects/common/strings.h @@ -1,6 +1,6 @@ /* strings.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/Projects/common/unistd.h b/IDE/Renesas/e2studio/Projects/common/unistd.h index d91dd4790..962ad47ee 100644 --- a/IDE/Renesas/e2studio/Projects/common/unistd.h +++ b/IDE/Renesas/e2studio/Projects/common/unistd.h @@ -1,6 +1,6 @@ /* unistd.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/Projects/common/user_settings.h b/IDE/Renesas/e2studio/Projects/common/user_settings.h index 3f110ef20..62648c9cc 100644 --- a/IDE/Renesas/e2studio/Projects/common/user_settings.h +++ b/IDE/Renesas/e2studio/Projects/common/user_settings.h @@ -1,6 +1,6 @@ /* user_settings.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/Projects/common/wolfssl_dummy.c b/IDE/Renesas/e2studio/Projects/common/wolfssl_dummy.c index 61cd51f74..9aa14dbf1 100644 --- a/IDE/Renesas/e2studio/Projects/common/wolfssl_dummy.c +++ b/IDE/Renesas/e2studio/Projects/common/wolfssl_dummy.c @@ -1,6 +1,6 @@ /* wolfssl_dummy.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/Projects/test/src/key_data.c b/IDE/Renesas/e2studio/Projects/test/src/key_data.c index c924f8f81..cef0a9c99 100644 --- a/IDE/Renesas/e2studio/Projects/test/src/key_data.c +++ b/IDE/Renesas/e2studio/Projects/test/src/key_data.c @@ -1,6 +1,6 @@ /* key_data.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -18,6 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ + #include "key_data.h" #ifdef WOLFSSL_RENESAS_TSIP diff --git a/IDE/Renesas/e2studio/Projects/test/src/key_data.h b/IDE/Renesas/e2studio/Projects/test/src/key_data.h index 8152b2946..e2e53e72a 100644 --- a/IDE/Renesas/e2studio/Projects/test/src/key_data.h +++ b/IDE/Renesas/e2studio/Projects/test/src/key_data.h @@ -1,6 +1,6 @@ /* key_data.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -18,6 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ + #ifndef KEY_DATA_H_ #define KEY_DATA_H_ #include diff --git a/IDE/Renesas/e2studio/Projects/test/src/test_main.c b/IDE/Renesas/e2studio/Projects/test/src/test_main.c index 252d08bfc..063d41a73 100644 --- a/IDE/Renesas/e2studio/Projects/test/src/test_main.c +++ b/IDE/Renesas/e2studio/Projects/test/src/test_main.c @@ -1,6 +1,6 @@ /* test_main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/Projects/test/src/wolf_client.c b/IDE/Renesas/e2studio/Projects/test/src/wolf_client.c index 7122bd811..5f0e96ac1 100644 --- a/IDE/Renesas/e2studio/Projects/test/src/wolf_client.c +++ b/IDE/Renesas/e2studio/Projects/test/src/wolf_client.c @@ -1,6 +1,6 @@ /* wolf_client.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/Projects/test/src/wolf_server.c b/IDE/Renesas/e2studio/Projects/test/src/wolf_server.c index 5d38b0358..b193fbe71 100644 --- a/IDE/Renesas/e2studio/Projects/test/src/wolf_server.c +++ b/IDE/Renesas/e2studio/Projects/test/src/wolf_server.c @@ -1,6 +1,6 @@ /* wolf_server.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/Projects/test/src/wolfssl_demo.h b/IDE/Renesas/e2studio/Projects/test/src/wolfssl_demo.h index 3127a9f7c..0241f9196 100644 --- a/IDE/Renesas/e2studio/Projects/test/src/wolfssl_demo.h +++ b/IDE/Renesas/e2studio/Projects/test/src/wolfssl_demo.h @@ -1,6 +1,6 @@ /* wolfssl_demo.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/RA6M3/benchmark-wolfcrypt/src/wolfssl_thread_entry.c b/IDE/Renesas/e2studio/RA6M3/benchmark-wolfcrypt/src/wolfssl_thread_entry.c index 67629b1c4..d56ee00db 100644 --- a/IDE/Renesas/e2studio/RA6M3/benchmark-wolfcrypt/src/wolfssl_thread_entry.c +++ b/IDE/Renesas/e2studio/RA6M3/benchmark-wolfcrypt/src/wolfssl_thread_entry.c @@ -1,6 +1,6 @@ /* wolfssl_thread_entry.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/RA6M3/client-wolfssl/src/wolfssl_thread_entry.c b/IDE/Renesas/e2studio/RA6M3/client-wolfssl/src/wolfssl_thread_entry.c index a7a6d3f72..c21a2cc17 100644 --- a/IDE/Renesas/e2studio/RA6M3/client-wolfssl/src/wolfssl_thread_entry.c +++ b/IDE/Renesas/e2studio/RA6M3/client-wolfssl/src/wolfssl_thread_entry.c @@ -1,6 +1,6 @@ /* wolfssl_thread_entry.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/RA6M3/client-wolfssl/wolfssl_thread_entry.h b/IDE/Renesas/e2studio/RA6M3/client-wolfssl/wolfssl_thread_entry.h index 8184edbb2..cd1ca54b7 100644 --- a/IDE/Renesas/e2studio/RA6M3/client-wolfssl/wolfssl_thread_entry.h +++ b/IDE/Renesas/e2studio/RA6M3/client-wolfssl/wolfssl_thread_entry.h @@ -1,6 +1,6 @@ /* wolfssl_thread_entry.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/RA6M3/common/src/freertos_tcp_port.c b/IDE/Renesas/e2studio/RA6M3/common/src/freertos_tcp_port.c index 9e5715316..a10162026 100644 --- a/IDE/Renesas/e2studio/RA6M3/common/src/freertos_tcp_port.c +++ b/IDE/Renesas/e2studio/RA6M3/common/src/freertos_tcp_port.c @@ -1,6 +1,6 @@ /* freertos_tcp_port.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/RA6M3/common/user_settings.h b/IDE/Renesas/e2studio/RA6M3/common/user_settings.h index 4a496e751..41550dd47 100644 --- a/IDE/Renesas/e2studio/RA6M3/common/user_settings.h +++ b/IDE/Renesas/e2studio/RA6M3/common/user_settings.h @@ -1,6 +1,6 @@ /* user_settings.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/RA6M3/common/util.h b/IDE/Renesas/e2studio/RA6M3/common/util.h index 805415b04..f1445ff45 100644 --- a/IDE/Renesas/e2studio/RA6M3/common/util.h +++ b/IDE/Renesas/e2studio/RA6M3/common/util.h @@ -1,6 +1,6 @@ /* util.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/RA6M3/server-wolfssl/src/wolfssl_thread_entry.c b/IDE/Renesas/e2studio/RA6M3/server-wolfssl/src/wolfssl_thread_entry.c index 04518edb8..d09dd5ccb 100644 --- a/IDE/Renesas/e2studio/RA6M3/server-wolfssl/src/wolfssl_thread_entry.c +++ b/IDE/Renesas/e2studio/RA6M3/server-wolfssl/src/wolfssl_thread_entry.c @@ -1,6 +1,6 @@ /* wolfssl_thread_entry.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/RA6M3/server-wolfssl/wolfssl_thread_entry.h b/IDE/Renesas/e2studio/RA6M3/server-wolfssl/wolfssl_thread_entry.h index 66ffb506f..003164f60 100644 --- a/IDE/Renesas/e2studio/RA6M3/server-wolfssl/wolfssl_thread_entry.h +++ b/IDE/Renesas/e2studio/RA6M3/server-wolfssl/wolfssl_thread_entry.h @@ -1,6 +1,6 @@ /* wolfssl_thread_entry.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/RA6M3/test-wolfcrypt/src/wolfssl_thread_entry.c b/IDE/Renesas/e2studio/RA6M3/test-wolfcrypt/src/wolfssl_thread_entry.c index 96629a8ba..665e8f11f 100644 --- a/IDE/Renesas/e2studio/RA6M3/test-wolfcrypt/src/wolfssl_thread_entry.c +++ b/IDE/Renesas/e2studio/RA6M3/test-wolfcrypt/src/wolfssl_thread_entry.c @@ -1,6 +1,6 @@ /* wolfssl_thread_entry.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/RX72NEnvisionKit/common/strings.h b/IDE/Renesas/e2studio/RX72NEnvisionKit/common/strings.h index fd2cf86e6..e3752588e 100644 --- a/IDE/Renesas/e2studio/RX72NEnvisionKit/common/strings.h +++ b/IDE/Renesas/e2studio/RX72NEnvisionKit/common/strings.h @@ -1,6 +1,6 @@ /* strings.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/RX72NEnvisionKit/common/unistd.h b/IDE/Renesas/e2studio/RX72NEnvisionKit/common/unistd.h index d91dd4790..962ad47ee 100644 --- a/IDE/Renesas/e2studio/RX72NEnvisionKit/common/unistd.h +++ b/IDE/Renesas/e2studio/RX72NEnvisionKit/common/unistd.h @@ -1,6 +1,6 @@ /* unistd.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/RX72NEnvisionKit/common/user_settings.h b/IDE/Renesas/e2studio/RX72NEnvisionKit/common/user_settings.h index bcc83bdb7..153ee8554 100644 --- a/IDE/Renesas/e2studio/RX72NEnvisionKit/common/user_settings.h +++ b/IDE/Renesas/e2studio/RX72NEnvisionKit/common/user_settings.h @@ -1,6 +1,6 @@ /* user_settings.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/RX72NEnvisionKit/common/wolfssl_dummy.c b/IDE/Renesas/e2studio/RX72NEnvisionKit/common/wolfssl_dummy.c index 8fa6340b4..a31c43cdc 100644 --- a/IDE/Renesas/e2studio/RX72NEnvisionKit/common/wolfssl_dummy.c +++ b/IDE/Renesas/e2studio/RX72NEnvisionKit/common/wolfssl_dummy.c @@ -1,6 +1,6 @@ /* wolfssl_dummy.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/key_data.c b/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/key_data.c index 6dfac9811..745c6fe29 100644 --- a/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/key_data.c +++ b/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/key_data.c @@ -1,6 +1,6 @@ /* key_data.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -18,6 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ + #include "key_data.h" /*------------------------------------------------------------------------- diff --git a/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/key_data.h b/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/key_data.h index 74e9ed242..b04ea27ea 100644 --- a/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/key_data.h +++ b/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/key_data.h @@ -1,6 +1,6 @@ /* key_data.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -18,6 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ + diff --git a/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/test_main.c b/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/test_main.c index 7d336826a..5979896f8 100644 --- a/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/test_main.c +++ b/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/test_main.c @@ -1,6 +1,6 @@ /* test_main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/wolf_client.c b/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/wolf_client.c index ff09b1a80..cc1eeac79 100644 --- a/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/wolf_client.c +++ b/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/wolf_client.c @@ -1,6 +1,6 @@ /* wolf_client.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/wolf_server.c b/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/wolf_server.c index 5d38b0358..b193fbe71 100644 --- a/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/wolf_server.c +++ b/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/wolf_server.c @@ -1,6 +1,6 @@ /* wolf_server.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/wolfssl_demo.h b/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/wolfssl_demo.h index b2a272245..d82743a7e 100644 --- a/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/wolfssl_demo.h +++ b/IDE/Renesas/e2studio/RX72NEnvisionKit/test/src/wolfssl_demo.h @@ -1,6 +1,6 @@ /* wolfssl_demo.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/STM32Cube/main.c b/IDE/STM32Cube/main.c index a2d8e0eb2..149f04397 100644 --- a/IDE/STM32Cube/main.c +++ b/IDE/STM32Cube/main.c @@ -1,6 +1,6 @@ /* main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/STM32Cube/wolfSSL_conf.h b/IDE/STM32Cube/wolfSSL_conf.h index 1f74bb4bc..793e12858 100644 --- a/IDE/STM32Cube/wolfSSL_conf.h +++ b/IDE/STM32Cube/wolfSSL_conf.h @@ -1,6 +1,6 @@ /* wolfSSL_conf.h (example of generated wolfSSL.I-CUBE-wolfSSL_conf.h) * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/STM32Cube/wolfssl_example.c b/IDE/STM32Cube/wolfssl_example.c index f604c1788..8347ed4dc 100644 --- a/IDE/STM32Cube/wolfssl_example.c +++ b/IDE/STM32Cube/wolfssl_example.c @@ -1,6 +1,6 @@ /* wolfssl_example.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/STM32Cube/wolfssl_example.h b/IDE/STM32Cube/wolfssl_example.h index f43884d87..341667fd8 100644 --- a/IDE/STM32Cube/wolfssl_example.h +++ b/IDE/STM32Cube/wolfssl_example.h @@ -1,6 +1,6 @@ /* wolfssl_example.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/VS-AZURE-SPHERE/client/client.c b/IDE/VS-AZURE-SPHERE/client/client.c index 82a236687..8b8c43812 100644 --- a/IDE/VS-AZURE-SPHERE/client/client.c +++ b/IDE/VS-AZURE-SPHERE/client/client.c @@ -1,6 +1,6 @@ /* client.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ #include "client.h" diff --git a/IDE/VS-AZURE-SPHERE/client/client.h b/IDE/VS-AZURE-SPHERE/client/client.h index e24aa3ac1..8443a084a 100644 --- a/IDE/VS-AZURE-SPHERE/client/client.h +++ b/IDE/VS-AZURE-SPHERE/client/client.h @@ -1,6 +1,6 @@ /* client.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -18,6 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ + #ifndef WOLFSSL_CLIENT_H #define WOLFSSL_CLIENT_H diff --git a/IDE/VS-AZURE-SPHERE/server/server.c b/IDE/VS-AZURE-SPHERE/server/server.c index 48a7922bf..a262dc417 100644 --- a/IDE/VS-AZURE-SPHERE/server/server.c +++ b/IDE/VS-AZURE-SPHERE/server/server.c @@ -1,8 +1,8 @@ /* server.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * - * This file is part of wolfSSL. (formerly known as CyaSSL) + * This file is part of wolfSSL. * * wolfSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ #include "server.h" diff --git a/IDE/VS-AZURE-SPHERE/server/server.h b/IDE/VS-AZURE-SPHERE/server/server.h index 29ea245be..d623782dc 100644 --- a/IDE/VS-AZURE-SPHERE/server/server.h +++ b/IDE/VS-AZURE-SPHERE/server/server.h @@ -1,6 +1,6 @@ /* server.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -18,6 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ + #ifndef WOLFSSL_SERVER_H diff --git a/IDE/WIN/user_settings.h b/IDE/WIN/user_settings.h index 43c7f3ab3..8152b1def 100644 --- a/IDE/WIN/user_settings.h +++ b/IDE/WIN/user_settings.h @@ -57,11 +57,23 @@ #define WOLFSSL_AESNI #endif - /* Single Precision Support for RSA/DH 1024/2048/3072 and ECC P-256 */ + /* Single Precision Support for RSA/DH 1024/2048/3072 and + * ECC P-256/P-384 */ #define WOLFSSL_SP #define WOLFSSL_HAVE_SP_ECC #define WOLFSSL_HAVE_SP_DH #define WOLFSSL_HAVE_SP_RSA + + #ifdef _WIN64 + /* Old versions of MASM compiler do not recognize newer + * instructions. */ + #if 0 + #define NO_AVX2_SUPPORT + #define NO_MOVBE_SUPPORT + #endif + #define WOLFSSL_SP_ASM + #define WOLFSSL_SP_X86_64_ASM + #endif #endif #else diff --git a/IDE/XCODE/Benchmark/wolfBench/AppDelegate.h b/IDE/XCODE/Benchmark/wolfBench/AppDelegate.h index ea0887488..dc7165087 100644 --- a/IDE/XCODE/Benchmark/wolfBench/AppDelegate.h +++ b/IDE/XCODE/Benchmark/wolfBench/AppDelegate.h @@ -1,6 +1,6 @@ /* AppDelegate.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/XCODE/Benchmark/wolfBench/AppDelegate.m b/IDE/XCODE/Benchmark/wolfBench/AppDelegate.m index 1dc369087..1da758448 100644 --- a/IDE/XCODE/Benchmark/wolfBench/AppDelegate.m +++ b/IDE/XCODE/Benchmark/wolfBench/AppDelegate.m @@ -1,6 +1,6 @@ /* AppDelegate.m * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/XCODE/Benchmark/wolfBench/ViewController.h b/IDE/XCODE/Benchmark/wolfBench/ViewController.h index 4990aabfd..4e9cfb8f3 100644 --- a/IDE/XCODE/Benchmark/wolfBench/ViewController.h +++ b/IDE/XCODE/Benchmark/wolfBench/ViewController.h @@ -1,6 +1,6 @@ /* ViewController.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/XCODE/Benchmark/wolfBench/ViewController.m b/IDE/XCODE/Benchmark/wolfBench/ViewController.m index fefbc87bd..ff0465b00 100644 --- a/IDE/XCODE/Benchmark/wolfBench/ViewController.m +++ b/IDE/XCODE/Benchmark/wolfBench/ViewController.m @@ -1,6 +1,6 @@ /* ViewController.m * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/XCODE/Benchmark/wolfBench/main.m b/IDE/XCODE/Benchmark/wolfBench/main.m index eddb4bef3..4ee19f302 100644 --- a/IDE/XCODE/Benchmark/wolfBench/main.m +++ b/IDE/XCODE/Benchmark/wolfBench/main.m @@ -1,6 +1,6 @@ /* main.m * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/XilinxSDK/user_settings.h b/IDE/XilinxSDK/user_settings.h index 670cc9cc7..01049b72b 100644 --- a/IDE/XilinxSDK/user_settings.h +++ b/IDE/XilinxSDK/user_settings.h @@ -1,6 +1,6 @@ /* user_settings.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/XilinxSDK/wolfssl_example.c b/IDE/XilinxSDK/wolfssl_example.c index c67a12f69..eea82bd75 100644 --- a/IDE/XilinxSDK/wolfssl_example.c +++ b/IDE/XilinxSDK/wolfssl_example.c @@ -1,6 +1,6 @@ /* wolfssl_example.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/mynewt/apps.wolfcrypttest.pkg.yml b/IDE/mynewt/apps.wolfcrypttest.pkg.yml index 2ce68544e..bac9422c6 100644 --- a/IDE/mynewt/apps.wolfcrypttest.pkg.yml +++ b/IDE/mynewt/apps.wolfcrypttest.pkg.yml @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -16,6 +16,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ # pkg.name: "apps/wolfcrypttest" diff --git a/IDE/mynewt/crypto.wolfssl.pkg.yml b/IDE/mynewt/crypto.wolfssl.pkg.yml index 0c516896a..f8951fef8 100644 --- a/IDE/mynewt/crypto.wolfssl.pkg.yml +++ b/IDE/mynewt/crypto.wolfssl.pkg.yml @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -16,6 +16,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ # pkg.name: "crypto/wolfssl" diff --git a/IDE/zephyr/lib/settings/user_settings-tls-generic.h b/IDE/zephyr/lib/settings/user_settings-tls-generic.h index b59b88355..912ac0782 100644 --- a/IDE/zephyr/lib/settings/user_settings-tls-generic.h +++ b/IDE/zephyr/lib/settings/user_settings-tls-generic.h @@ -1,10 +1,23 @@ /* wolfssl options.h * generated from configure options * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * + * wolfSSL 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. + * + * wolfSSL 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ #ifndef WOLFSSL_OPTIONS_H diff --git a/IDE/zephyr/wolfssl_tls_sock/src/tls_sock.c b/IDE/zephyr/wolfssl_tls_sock/src/tls_sock.c index f644c70da..695370deb 100644 --- a/IDE/zephyr/wolfssl_tls_sock/src/tls_sock.c +++ b/IDE/zephyr/wolfssl_tls_sock/src/tls_sock.c @@ -1,6 +1,6 @@ /* tls_sock.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/IDE/zephyr/wolfssl_tls_thread/src/tls_threaded.c b/IDE/zephyr/wolfssl_tls_thread/src/tls_threaded.c index c57d8df6a..6d8059b6e 100644 --- a/IDE/zephyr/wolfssl_tls_thread/src/tls_threaded.c +++ b/IDE/zephyr/wolfssl_tls_thread/src/tls_threaded.c @@ -1,6 +1,6 @@ /* tls_threaded.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/configure.ac b/configure.ac index 1d4e4212f..1ec1f11a5 100644 --- a/configure.ac +++ b/configure.ac @@ -1,12 +1,12 @@ # configure.ac # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. (formerly known as CyaSSL) # # AC_COPYRIGHT([Copyright (C) 2006-2020 wolfSSL Inc.]) -AC_PREREQ([2.63]) +AC_PREREQ([2.69]) AC_INIT([wolfssl],[4.7.1],[https://github.com/wolfssl/wolfssl/issues],[wolfssl],[https://www.wolfssl.com]) AC_CONFIG_AUX_DIR([build-aux]) @@ -22,16 +22,17 @@ CFLAGS="$CFLAGS $C_EXTRA_FLAGS $C_FLAGS" AC_PROG_CC AM_PROG_CC_C_O AC_CANONICAL_HOST +AC_CANONICAL_TARGET AC_CONFIG_MACRO_DIR([m4]) -AM_INIT_AUTOMAKE([1.11 -Wall -Werror -Wno-portability foreign tar-ustar subdir-objects no-define color-tests]) +AM_INIT_AUTOMAKE([1.14.1 -Wall -Werror -Wno-portability foreign tar-ustar subdir-objects no-define color-tests]) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) AC_ARG_PROGRAM AC_CONFIG_HEADERS([config.h:config.in]) -LT_PREREQ([2.2]) +LT_PREREQ([2.4.2]) LT_INIT([disable-static win32-dll]) #shared library versioning @@ -168,6 +169,9 @@ AX_DEBUG AS_IF([test "$ax_enable_debug" = "yes"], [AM_CFLAGS="$DEBUG_CFLAGS $AM_CFLAGS"], [AM_CFLAGS="$AM_CFLAGS -DNDEBUG"]) +AS_IF([test "$ax_enable_debug" = "yes"], + [AM_CCASFLAGS="$DEBUG_CFLAGS $AM_CCASFLAGS"], + [AM_CCASFLAGS="$AM_CCASFLAGS -DNDEBUG"]) # Start without certificates enabled and enable if a certificate algorithm is @@ -203,7 +207,7 @@ AS_CASE([$ENABLED_FIPS], FIPS_VERSION="v1" ], [ - AC_MSG_ERROR([Invalid value for --enable-fips \"$ENABLED_FIPS\" (allowed: ready, rand, v1, v2)]) + AC_MSG_ERROR([Invalid value for --enable-fips "$ENABLED_FIPS" (allowed: ready, rand, v1, v2)]) ]) AS_CASE([$FIPS_VERSION], @@ -449,6 +453,12 @@ then test "$enable_pkcs7" = "" && enable_pkcs7=yes test "$enable_ed25519" = "" && enable_ed25519=yes test "$enable_ed448" = "" && enable_ed448=yes + + if test "$ENABLED_LINUXKM_DEFAULTS" != "yes" + then + test "$enable_eccsi" = "" && enable_eccsi=yes + test "$enable_sakke" = "" && enable_sakke=yes + fi fi # Enable DH const table speedups (eliminates `-lm` math lib dependency) @@ -540,12 +550,18 @@ then AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_VALIDATE_ECC_IMPORT" fi - if test "$ENABLED_FIPS" != "yes" + if test "$ENABLED_FIPS" == "no" then test "$enable_xchacha" = "" && enable_xchacha=yes test "$enable_ed25519" = "" && enable_ed25519=yes test "$enable_ed448" = "" && enable_ed448=yes test "$enable_pkcs7" = "" && enable_pkcs7=yes + + if test "$ENABLED_LINUXKM_DEFAULTS" != "yes" + then + test "$enable_eccsi" = "" && enable_eccsi=yes + test "$enable_sakke" = "" && enable_sakke=yes + fi fi # Enable AES Decrypt, AES ECB, Alt Names, DER Load @@ -2224,6 +2240,36 @@ then AM_CFLAGS="$AM_CFLAGS -DHAVE_ECC_ENCRYPT" fi +# Elliptic Curve-Based Certificateless Signatures for Identity-Based Encryption (ECCSI) +AC_ARG_ENABLE([eccsi], + [AS_HELP_STRING([--enable-eccsi],[Enable ECCSI (default: disabled)])], + [ ENABLED_ECCSI=$enableval ], + [ ENABLED_ECCSI=no ] + ) + +if test "x$ENABLED_ECCSI" = "xyes" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFCRYPT_HAVE_ECCSI -DWOLFSSL_PUBLIC_MP" +fi + +# Sakai-Kasahara Key Encryption (SAKKE) - pairing based crypto +AC_ARG_ENABLE([sakke], + [AS_HELP_STRING([--enable-sakke],[Enable SAKKE - paring based crypto (default: disabled)])], + [ ENABLED_SAKKE=$enableval ], + [ ENABLED_SAKKE=no ] + ) + +if test "x$ENABLED_SAKKE" = "xsmall" +then + ENABLED_SAKKE="yes" + ENABLED_SAKKE_SMALL="yes" + AM_CFLAGS="$AM_CFLAGS -DWOLFCRYPT_SAKKE_SMALL" +fi +if test "x$ENABLED_SAKKE" = "xyes" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFCRYPT_HAVE_SAKKE" +fi + # PSK AC_ARG_ENABLE([psk], @@ -4651,6 +4697,11 @@ then AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_X86_64_BUILD" fi AS_IF([test "x$host_cpu" = "xaarch64"],[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AARCH64_BUILD"]) + + if test "$ENABLED_SAKKE" = "yes" && test "$ENABLED_SAKKE_SMALL" != "yes" + then + AM_CFLAGS="$AM_CFLAGS -funroll-loops -DTFM_SMALL_SET" + fi fi @@ -4944,6 +4995,7 @@ ENABLED_SP_FF_4096=no ENABLED_SP_ECC=no ENABLED_SP_EC_256=no ENABLED_SP_EC_384=no +ENABLED_SP_SAKKE_1024=$ENABLED_SAKKE ENABLED_SP_NO_MALLOC=no ENABLED_SP_NONBLOCK=no ENABLED_SP_SMALL=no @@ -4998,6 +5050,15 @@ do ENABLED_SP_ECC=yes ENABLED_SP_EC_384=yes ;; + smallec1024 | smallp1024 | small1024) + ENABLED_SP_ECC=yes + ENABLED_SP_SMALL=yes + ENABLED_SP_SAKKE_1024=yes + ;; + ec1024 | p1024 | 1024) + ENABLED_SP_ECC=yes + ENABLED_SP_SAKKE_1024=yes + ;; small2048) ENABLED_SP_SMALL=yes @@ -5116,6 +5177,10 @@ if test "$ENABLED_ECC" != "no" && test "$ENABLED_SP_ECC" = "yes"; then AM_CFLAGS="$AM_CFLAGS -DHAVE_ECC384 -DWOLFSSL_SP_384" AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_384" fi + if test "$ENABLED_SP_SAKKE_1024" = "yes"; then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_1024" + AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_1024" + fi fi if test "$ENABLED_SP_SMALL" = "yes"; then AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_SMALL" @@ -6157,6 +6222,8 @@ AM_CONDITIONAL([BUILD_FE448], [test "x$ENABLED_FE448" = "xyes" || test "x$ENABLE AM_CONDITIONAL([BUILD_GE448], [test "x$ENABLED_GE448" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_CURVE448],[test "x$ENABLED_CURVE448" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_CURVE448_SMALL],[test "x$ENABLED_CURVE448_SMALL" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_ECCSI],[test "x$ENABLED_ECCSI" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_SAKKE],[test "x$ENABLED_SAKKE" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_MEMORY],[test "x$ENABLED_MEMORY" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_RSA],[test "x$ENABLED_RSA" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_DH],[test "x$ENABLED_DH" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) @@ -6483,6 +6550,8 @@ echo " * CURVE448: $ENABLED_CURVE448" echo " * ED448: $ENABLED_ED448" echo " * FPECC: $ENABLED_FPECC" echo " * ECC_ENCRYPT: $ENABLED_ECC_ENCRYPT" +echo " * ECCSI $ENABLED_ECCSI" +echo " * SAKKE $ENABLED_SAKKE" echo " * ASN: $ENABLED_ASN" echo " * Anonymous cipher: $ENABLED_ANON" echo " * CODING: $ENABLED_CODING" diff --git a/ctaocrypt/src/misc.c b/ctaocrypt/src/misc.c index bd127625d..5d185c485 100644 --- a/ctaocrypt/src/misc.c +++ b/ctaocrypt/src/misc.c @@ -1,6 +1,6 @@ /* misc.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/ctaocrypt/src/wolfcrypt_first.c b/ctaocrypt/src/wolfcrypt_first.c index 74e759a7a..93d0a2597 100644 --- a/ctaocrypt/src/wolfcrypt_first.c +++ b/ctaocrypt/src/wolfcrypt_first.c @@ -1,6 +1,6 @@ /* wolfcrypt_first.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/ctaocrypt/src/wolfcrypt_last.c b/ctaocrypt/src/wolfcrypt_last.c index 60cb33a4e..b6d69d01a 100644 --- a/ctaocrypt/src/wolfcrypt_last.c +++ b/ctaocrypt/src/wolfcrypt_last.c @@ -1,6 +1,6 @@ /* wolfcrypt_last.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/callbacks.h b/cyassl/callbacks.h index 69dd3476b..7a1c1d43d 100644 --- a/cyassl/callbacks.h +++ b/cyassl/callbacks.h @@ -1,6 +1,6 @@ /* callbacks.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/crl.h b/cyassl/crl.h index 7f285a33e..a883879b9 100644 --- a/cyassl/crl.h +++ b/cyassl/crl.h @@ -1,6 +1,6 @@ /* crl.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/aes.h b/cyassl/ctaocrypt/aes.h index dae7812e8..3973c8f30 100644 --- a/cyassl/ctaocrypt/aes.h +++ b/cyassl/ctaocrypt/aes.h @@ -1,6 +1,6 @@ /* aes.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/arc4.h b/cyassl/ctaocrypt/arc4.h index 627d79735..ff7440c30 100644 --- a/cyassl/ctaocrypt/arc4.h +++ b/cyassl/ctaocrypt/arc4.h @@ -1,6 +1,6 @@ /* arc4.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/asn.h b/cyassl/ctaocrypt/asn.h index 673cce748..5ee090fa8 100644 --- a/cyassl/ctaocrypt/asn.h +++ b/cyassl/ctaocrypt/asn.h @@ -1,6 +1,6 @@ /* asn.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/asn_public.h b/cyassl/ctaocrypt/asn_public.h index 5e75943f0..b4dc6da66 100644 --- a/cyassl/ctaocrypt/asn_public.h +++ b/cyassl/ctaocrypt/asn_public.h @@ -1,6 +1,6 @@ /* asn_public.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/blake2-impl.h b/cyassl/ctaocrypt/blake2-impl.h index e815f0769..aa34a81cb 100644 --- a/cyassl/ctaocrypt/blake2-impl.h +++ b/cyassl/ctaocrypt/blake2-impl.h @@ -12,7 +12,7 @@ */ /* blake2-impl.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/blake2-int.h b/cyassl/ctaocrypt/blake2-int.h index 77244a232..062de2ff6 100644 --- a/cyassl/ctaocrypt/blake2-int.h +++ b/cyassl/ctaocrypt/blake2-int.h @@ -12,7 +12,7 @@ */ /* blake2-int.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/blake2.h b/cyassl/ctaocrypt/blake2.h index c1378d9cd..377a51577 100644 --- a/cyassl/ctaocrypt/blake2.h +++ b/cyassl/ctaocrypt/blake2.h @@ -1,6 +1,6 @@ /* blake2.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/camellia.h b/cyassl/ctaocrypt/camellia.h index 8c0ce8d4c..8db4a45e2 100644 --- a/cyassl/ctaocrypt/camellia.h +++ b/cyassl/ctaocrypt/camellia.h @@ -1,6 +1,6 @@ /* camellia.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/chacha.h b/cyassl/ctaocrypt/chacha.h index bfe099851..0ad52ba35 100644 --- a/cyassl/ctaocrypt/chacha.h +++ b/cyassl/ctaocrypt/chacha.h @@ -1,6 +1,6 @@ /* chacha.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/coding.h b/cyassl/ctaocrypt/coding.h index 9902a5aba..7b433c768 100644 --- a/cyassl/ctaocrypt/coding.h +++ b/cyassl/ctaocrypt/coding.h @@ -1,6 +1,6 @@ /* coding.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/compress.h b/cyassl/ctaocrypt/compress.h index 6bb26c6b0..f1f8cb39b 100644 --- a/cyassl/ctaocrypt/compress.h +++ b/cyassl/ctaocrypt/compress.h @@ -1,6 +1,6 @@ /* compress.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/des3.h b/cyassl/ctaocrypt/des3.h index 8e355196d..94fd5ea35 100644 --- a/cyassl/ctaocrypt/des3.h +++ b/cyassl/ctaocrypt/des3.h @@ -1,6 +1,6 @@ /* des3.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/dh.h b/cyassl/ctaocrypt/dh.h index 80d4e51d3..5cf584930 100644 --- a/cyassl/ctaocrypt/dh.h +++ b/cyassl/ctaocrypt/dh.h @@ -1,6 +1,6 @@ /* dh.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/dsa.h b/cyassl/ctaocrypt/dsa.h index d99429081..60c815987 100644 --- a/cyassl/ctaocrypt/dsa.h +++ b/cyassl/ctaocrypt/dsa.h @@ -1,6 +1,6 @@ /* dsa.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/ecc.h b/cyassl/ctaocrypt/ecc.h index b4b2f96c4..6e1e1dcb2 100644 --- a/cyassl/ctaocrypt/ecc.h +++ b/cyassl/ctaocrypt/ecc.h @@ -1,6 +1,6 @@ /* ecc.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/error-crypt.h b/cyassl/ctaocrypt/error-crypt.h index 55a973947..061de0292 100644 --- a/cyassl/ctaocrypt/error-crypt.h +++ b/cyassl/ctaocrypt/error-crypt.h @@ -1,6 +1,6 @@ /* error-crypt.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/fips_test.h b/cyassl/ctaocrypt/fips_test.h index cdfad6cae..561da88cb 100644 --- a/cyassl/ctaocrypt/fips_test.h +++ b/cyassl/ctaocrypt/fips_test.h @@ -1,6 +1,6 @@ /* fips_test.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/hc128.h b/cyassl/ctaocrypt/hc128.h index af1186bde..378389343 100644 --- a/cyassl/ctaocrypt/hc128.h +++ b/cyassl/ctaocrypt/hc128.h @@ -1,6 +1,6 @@ /* hc128.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/hmac.h b/cyassl/ctaocrypt/hmac.h index 4c0dd153a..04fb6fb11 100644 --- a/cyassl/ctaocrypt/hmac.h +++ b/cyassl/ctaocrypt/hmac.h @@ -1,6 +1,6 @@ /* hmac.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/integer.h b/cyassl/ctaocrypt/integer.h index 2aed0cd0f..2ee59a394 100644 --- a/cyassl/ctaocrypt/integer.h +++ b/cyassl/ctaocrypt/integer.h @@ -1,6 +1,6 @@ /* integer.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/logging.h b/cyassl/ctaocrypt/logging.h index 12fa22c61..37dc5763a 100644 --- a/cyassl/ctaocrypt/logging.h +++ b/cyassl/ctaocrypt/logging.h @@ -1,6 +1,6 @@ /* logging.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/md2.h b/cyassl/ctaocrypt/md2.h index e3e7816e6..b01cc6efe 100644 --- a/cyassl/ctaocrypt/md2.h +++ b/cyassl/ctaocrypt/md2.h @@ -1,6 +1,6 @@ /* md2.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/md4.h b/cyassl/ctaocrypt/md4.h index f550a71ad..463a68da1 100644 --- a/cyassl/ctaocrypt/md4.h +++ b/cyassl/ctaocrypt/md4.h @@ -1,6 +1,6 @@ /* md4.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/md5.h b/cyassl/ctaocrypt/md5.h index 4f5dc4727..77d99ae40 100644 --- a/cyassl/ctaocrypt/md5.h +++ b/cyassl/ctaocrypt/md5.h @@ -1,6 +1,6 @@ /* md5.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/memory.h b/cyassl/ctaocrypt/memory.h index a7f2a8b3a..0084be7d6 100644 --- a/cyassl/ctaocrypt/memory.h +++ b/cyassl/ctaocrypt/memory.h @@ -1,6 +1,6 @@ /* memory.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/misc.h b/cyassl/ctaocrypt/misc.h index 02c544101..f311fc916 100644 --- a/cyassl/ctaocrypt/misc.h +++ b/cyassl/ctaocrypt/misc.h @@ -1,6 +1,6 @@ /* misc.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/mpi_class.h b/cyassl/ctaocrypt/mpi_class.h index 01141a98b..134b71407 100644 --- a/cyassl/ctaocrypt/mpi_class.h +++ b/cyassl/ctaocrypt/mpi_class.h @@ -1,6 +1,6 @@ /* mpi_class.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/mpi_superclass.h b/cyassl/ctaocrypt/mpi_superclass.h index ca7531c21..3a5d80e58 100644 --- a/cyassl/ctaocrypt/mpi_superclass.h +++ b/cyassl/ctaocrypt/mpi_superclass.h @@ -1,6 +1,6 @@ /* mpi_superclass.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/pkcs7.h b/cyassl/ctaocrypt/pkcs7.h index 4b0488f25..3760567af 100644 --- a/cyassl/ctaocrypt/pkcs7.h +++ b/cyassl/ctaocrypt/pkcs7.h @@ -1,6 +1,6 @@ /* pkcs7.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/poly1305.h b/cyassl/ctaocrypt/poly1305.h index 72021ab27..e44be6cde 100644 --- a/cyassl/ctaocrypt/poly1305.h +++ b/cyassl/ctaocrypt/poly1305.h @@ -1,6 +1,6 @@ /* poly1305.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/port/pic32/pic32mz-crypt.h b/cyassl/ctaocrypt/port/pic32/pic32mz-crypt.h index e56e236c9..b6f603280 100644 --- a/cyassl/ctaocrypt/port/pic32/pic32mz-crypt.h +++ b/cyassl/ctaocrypt/port/pic32/pic32mz-crypt.h @@ -1,6 +1,6 @@ /* pic32mz-crypt.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/pwdbased.h b/cyassl/ctaocrypt/pwdbased.h index 9f1d1de36..75df424e0 100644 --- a/cyassl/ctaocrypt/pwdbased.h +++ b/cyassl/ctaocrypt/pwdbased.h @@ -1,6 +1,6 @@ /* pwdbased.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/rabbit.h b/cyassl/ctaocrypt/rabbit.h index 109e97331..365e4ba5d 100644 --- a/cyassl/ctaocrypt/rabbit.h +++ b/cyassl/ctaocrypt/rabbit.h @@ -1,6 +1,6 @@ /* rabbit.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/random.h b/cyassl/ctaocrypt/random.h index 9581ff92c..44ca532c5 100644 --- a/cyassl/ctaocrypt/random.h +++ b/cyassl/ctaocrypt/random.h @@ -1,6 +1,6 @@ /* random.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/ripemd.h b/cyassl/ctaocrypt/ripemd.h index 25bcf990e..b9c2feea7 100644 --- a/cyassl/ctaocrypt/ripemd.h +++ b/cyassl/ctaocrypt/ripemd.h @@ -1,6 +1,6 @@ /* ripemd.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/rsa.h b/cyassl/ctaocrypt/rsa.h index 18949e393..6a8b643e8 100644 --- a/cyassl/ctaocrypt/rsa.h +++ b/cyassl/ctaocrypt/rsa.h @@ -1,6 +1,6 @@ /* rsa.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/settings.h b/cyassl/ctaocrypt/settings.h index 83e8bdd22..adac2b4e4 100644 --- a/cyassl/ctaocrypt/settings.h +++ b/cyassl/ctaocrypt/settings.h @@ -1,6 +1,6 @@ /* settings.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/settings_comp.h b/cyassl/ctaocrypt/settings_comp.h index c886d8e62..8565e1aa2 100644 --- a/cyassl/ctaocrypt/settings_comp.h +++ b/cyassl/ctaocrypt/settings_comp.h @@ -1,6 +1,6 @@ /* settings_comp.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/sha.h b/cyassl/ctaocrypt/sha.h index 92c8e33ad..78b9342c6 100644 --- a/cyassl/ctaocrypt/sha.h +++ b/cyassl/ctaocrypt/sha.h @@ -1,6 +1,6 @@ /* sha.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/sha256.h b/cyassl/ctaocrypt/sha256.h index 000e834bb..a2fb7c0e6 100644 --- a/cyassl/ctaocrypt/sha256.h +++ b/cyassl/ctaocrypt/sha256.h @@ -1,6 +1,6 @@ /* sha256.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/sha512.h b/cyassl/ctaocrypt/sha512.h index 39c634235..cc679a592 100644 --- a/cyassl/ctaocrypt/sha512.h +++ b/cyassl/ctaocrypt/sha512.h @@ -1,6 +1,6 @@ /* sha512.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/tfm.h b/cyassl/ctaocrypt/tfm.h index 77990ef27..303793403 100644 --- a/cyassl/ctaocrypt/tfm.h +++ b/cyassl/ctaocrypt/tfm.h @@ -1,6 +1,6 @@ /* tfm.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/types.h b/cyassl/ctaocrypt/types.h index b6d97b51f..e86506286 100644 --- a/cyassl/ctaocrypt/types.h +++ b/cyassl/ctaocrypt/types.h @@ -1,6 +1,6 @@ /* types.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/visibility.h b/cyassl/ctaocrypt/visibility.h index f22c08481..51e2ca94f 100644 --- a/cyassl/ctaocrypt/visibility.h +++ b/cyassl/ctaocrypt/visibility.h @@ -1,6 +1,6 @@ /* visibility.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ctaocrypt/wc_port.h b/cyassl/ctaocrypt/wc_port.h index 50fb90ad9..b330803f0 100644 --- a/cyassl/ctaocrypt/wc_port.h +++ b/cyassl/ctaocrypt/wc_port.h @@ -1,6 +1,6 @@ /* port.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/error-ssl.h b/cyassl/error-ssl.h index e5189fac4..13fd5d600 100644 --- a/cyassl/error-ssl.h +++ b/cyassl/error-ssl.h @@ -1,6 +1,6 @@ /* error-ssl.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/internal.h b/cyassl/internal.h index 80d451e98..f7239e3f1 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -1,6 +1,6 @@ /* internal.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ocsp.h b/cyassl/ocsp.h index e06a1b53c..bb11e5624 100644 --- a/cyassl/ocsp.h +++ b/cyassl/ocsp.h @@ -1,6 +1,6 @@ /* ocsp.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/openssl/des.h b/cyassl/openssl/des.h index de4676402..79a06b741 100644 --- a/cyassl/openssl/des.h +++ b/cyassl/openssl/des.h @@ -1,6 +1,6 @@ /* des.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/openssl/evp.h b/cyassl/openssl/evp.h index b7ad1f50c..af81c100b 100644 --- a/cyassl/openssl/evp.h +++ b/cyassl/openssl/evp.h @@ -1,6 +1,6 @@ /* evp.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/openssl/hmac.h b/cyassl/openssl/hmac.h index 6dd377994..c93ef8d92 100644 --- a/cyassl/openssl/hmac.h +++ b/cyassl/openssl/hmac.h @@ -1,6 +1,6 @@ /* hmac.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/openssl/ssl.h b/cyassl/openssl/ssl.h index 3896292c1..3f2f3e351 100644 --- a/cyassl/openssl/ssl.h +++ b/cyassl/openssl/ssl.h @@ -1,6 +1,6 @@ /* ssl.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/options.h.in b/cyassl/options.h.in index ff991bdb5..fc90ce70b 100644 --- a/cyassl/options.h.in +++ b/cyassl/options.h.in @@ -1,6 +1,6 @@ /* options.h.in * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/sniffer.h b/cyassl/sniffer.h index 629785591..f92eeec08 100644 --- a/cyassl/sniffer.h +++ b/cyassl/sniffer.h @@ -1,6 +1,6 @@ /* sniffer.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/sniffer_error.h b/cyassl/sniffer_error.h index 8d7e8e159..d609f662d 100644 --- a/cyassl/sniffer_error.h +++ b/cyassl/sniffer_error.h @@ -1,6 +1,6 @@ /* sniffer_error.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/ssl.h b/cyassl/ssl.h index 5d36b366e..8599de128 100644 --- a/cyassl/ssl.h +++ b/cyassl/ssl.h @@ -1,6 +1,6 @@ /* ssl.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/version.h b/cyassl/version.h index 0f59b121b..cc5da906f 100644 --- a/cyassl/version.h +++ b/cyassl/version.h @@ -1,6 +1,6 @@ /* cyassl/version.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/cyassl/version.h.in b/cyassl/version.h.in index 25ce7d417..5fccf9ecb 100644 --- a/cyassl/version.h.in +++ b/cyassl/version.h.in @@ -1,6 +1,6 @@ /* cyassl_version.h.in * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/doc/dox_comments/header_files/doxygen_groups.h b/doc/dox_comments/header_files/doxygen_groups.h index cdb5a2a11..f8ac68330 100644 --- a/doc/dox_comments/header_files/doxygen_groups.h +++ b/doc/dox_comments/header_files/doxygen_groups.h @@ -13,6 +13,185 @@ \defgroup ECC Algorithms - ECC \defgroup ED25519 Algorithms - ED25519 \defgroup ED448 Algorithms - ED448 + \defgroup ECCSI_Overview Overview of ECCSI + ECCSI (Elliptic Curve-Based Certificateless Signatures for Identity-Based Encryption) is specified in RFC 6507 (https://tools.ietf.org/html/rfc6507). + + In Identity-Based cryptography, there is a Key Management Service that generates keys based on an identity for a client. + The private key (SSK) and public key (PVT) are delivered to the signer and the public key (PVT) only delivered to the verifier on request.\n\n + wolfCrypt offers the ability to: + -# Create KMS keys, + -# Generate signing key pairs, + -# Validate signing key pairs, + -# Sign messages and + -# Verify messages. + + KMS: + -# Initialize ECCSI Key: wc_InitEccsiKey() + -# Make and save or load ECCSI Key: + -# wc_MakeEccsiKey(), wc_ExportEccsiKey(), wc_ExportEccsiPublicKey() or + -# wc_ImportEccsiKey() + -# Wait for request: + -# Receive signing ID from client. + -# Generate signing key pair from ID: wc_MakeEccsiPair() + -# Encode result: + -# For signer, signing key pair: wc_EncodeEccsiPair() + -# Send KPAK and result + -# Free ECCSI Key: wc_FreeEccsiKey() + + Client, signer: + -# Initialize ECCSI Key: wc_InitEccsiKey() + -# (When signing pair not cached) Request KPAK and signing pair from KMS + -# Send signing ID to KMS. + -# Receive signing key pair from KMS. + -# Load KMS Public Key: wc_ImportEccsiPublicKey() + -# Decode signing key pair: wc_DecodeEccsiPair() + -# Validate the key pair: wc_ValidateEccsiPair() + -# (If not done above) Load KMS Public Key: wc_ImportEccsiPublicKey() + -# (If not cached) Calculate hash of the ID and PVT: wc_HashEccsiId() + -# For each message: + -# Set Hash of Identity: wc_SetEccsiHash() + -# Sign message: wc_SignEccsiHash() + -# Send hash ID, message and signature to peer. + -# Free ECCSI Key: wc_FreeEccsiKey() + + Client, verifier: + -# Receive hash ID, message and signature from signer. + -# Request KPAK (if not cached) and PVT (if not cached) for hash ID from KMS. + -# Receive KPAK (if not cached) and PVT (if not cached) for hash ID from KMS. + -# Initialize ECCSI Key: wc_InitEccsiKey() + -# Load KMS Public Key: wc_ImportEccsiPublicKey() + -# Decode PVT: wc_DecodeEccsiPvtFromSig() + -# Calculate hash of the ID and PVT: wc_HashEccsiId() + -# Set ECCSI key pair: wc_SetEccsiPair() + -# Verify signature of message: wc_VerifyEccsiHash() + -# Free ECCSI Key: wc_FreeEccsiKey() + + \defgroup ECCSI_Setup Setup ECCSI Key + Operations for establinshing an ECCSI key. + + Initialize ECCSI Key before use (wc_InitEccsiKey()).\n + Initialize ECCSI Key before use (wc_InitEccsiKey_ex()) for use with a curve other than P256.\n + Either make a new key (wc_MakeEccsiKey()), import an existing key (wc_ImportEccsiKey()) or import existing private key (wc_ImportEccsiPrivateKey()) and public key (wc_ImportEccsiPublicKey()).\n + Export the key (wc_ExportEccsiKey()) after making a new key for future use.\n + Export the private key (wc_ExportEccsiPrivateKey()) after making a new key for future use.\n + Export the public key (wc_ExportEccsiPublicKey()) from KMS to pass to client.\n + Import the public key (wc_ImportEccsiPublicKey()) into client.\n + Free the ECCSI Key (wc_FreeEccsiKey()) when finished. + + \defgroup ECCSI_Operations Operations for Signing and Verifying with ECCSI Key + These operations are for signing and verifying with ECCSI keys. + + Make an ECCSI key pair (wc_MakeEccsiPair()) with the signer's ID for use when signing.\n + Validate the ECCSI key pair (wc_ValidateEccsiPair()) with the signer's ID.\n + Validate the ECCSI Public Validation Token (PVT) (wc_ValidateEccsiPvt()).\n + Encode the ECCSI key pair (wc_EncodeEccsiPair()) for transfer to client.\n + Encode the ECCSI SSK (wc_EncodeEccsiSsk()) for transfer to client.\n + Encode the ECCSI PVT (wc_EncodeEccsiPvt()) for transfer to verifier.\n + Decode the ECCSI key pair (wc_DecodeEccsiPair()) on client for signing.\n + Decode the ECCSI SSK (wc_DecodeEccsiSsk()) on client for signing.\n + Decode the ECCSI PVT (wc_DecodeEccsiPvt()) on client for signing.\n + Decode the ECCSI PVT from the signature (wc_DecodeEccsiPvtFromSig()) on client for verifying.\n + Calculate hash of the ID (wc_HashEccsiId()) for signing/verifying using ID and Public Validation Token (PVT).\n + Sign (wc_SignEccsiHash()) a message with the hash of the ID and the Secret Signing Key (SSK) and Public Validation Token (PVT).\n + Verify (wc_VerifyEccsiHash()) a message with the hash of the signer's ID. + + \defgroup SAKKE_Overview Overview of SAKKE Key + SAKKE (Sakai-Kasahara Key Encryption) is specified in RFC 6508 (https://tools.ietf.org/html/rfc6508). + + SAKKE is used to transfer a secret to a peer using Identity Based cryptography.\n + The Key Management Service (KMS) is responsible for issuing Receiver Secret %Keys (RSKs). + Data up to (2^hashlen)^hashlen bytes of data can be transferred.\n + The sender must know the identity of the receiver and the KMS Public Key.\n + The receiver must have obtained a Receiver Secret Key (RSK) for the identity from a KMS in order to derive the secret. + + KMS: + -# Initialize SAKKE Key: wc_InitSakkeKey() + -# Make and save or load SAKKE Key: + -# wc_MakeSakkeKey(), wc_ExportSakkeKey(), wc_ExportSakkePublicKey() or + -# wc_ImportSakkeKey() + -# Wait for request: + -# Make an RSK base on ID for the client: wc_MakeSakkeRsk() + -# Encode RSK for transfer to client: wc_EncodeSakkeRsk() + -# Free SAKKE Key: wc_FreeSakkeKey() + + Key Exchange, Peer A: + -# Initialize SAKKE Key: wc_InitSakkeKey() + -# Load KMS Public Key: wc_ImportSakkePublicKey() + -# Generate a random SSV: wc_GenerateSakkeSSV() + -# Set the identity of Peer B: wc_SetSakkeIdentity() + -# Make an encapsulated SSV and auth data: wc_MakeSakkeEncapsulatedSSV() + -# Send encapsulated data to Peer B + -# Free SAKKE Key: wc_FreeSakkeKey() + + Key Exchange, Peer B: + -# Receive encapsulated data. + -# Initialize SAKKE Key: wc_InitSakkeKey() + -# Load KMS Public Key: wc_ImportSakkePublicKey() + -# Decode RSK transferred from KMS or stored locally: wc_DecodeSakkeRsk() + -# [Optional] Validate RSK before first use: wc_ValidateSakkeRsk() + -# Set the identity: wc_SetSakkeIdentity() + -# Set the RSK and, optionally precomputation table: wc_SetSakkeRsk() + -# Derive SSV with auth data: wc_DeriveSakkeSSV() + -# Free SAKKE Key: wc_FreeSakkeKey() + + Transfer secret, Peer A: + -# Initialize SAKKE Key: wc_InitSakkeKey() + -# Load KMS Public Key: wc_ImportSakkePublicKey() + -# Set the identity of Peer B: wc_SetSakkeIdentity() + -# Make an encapsulation of the SSV and auth data: wc_MakeSakkeEncapsulatedSSV() + -# Send encapsulated data to Peer B + -# Free SAKKE Key: wc_FreeSakkeKey() + + Transfer secret, Peer B: + -# Initialize SAKKE Key: wc_InitSakkeKey() + -# Load KMS Public Key: wc_ImportSakkePublicKey() + -# Decode RSK transferred from KMS or stored locally: wc_DecodeSakkeRsk() + -# [Optional] Validate RSK before first use: wc_ValidateSakkeRsk() + -# Receive encapsulated data. + -# Set the identity: wc_SetSakkeIdentity() + -# Set the RSK and, optionally precomputation table: wc_SetSakkeRsk() + -# Derive SSV and auth data: wc_DeriveSakkeSSV() + -# Free SAKKE Key: wc_FreeSakkeKey() + + \defgroup SAKKE_Setup Setup SAKKE Key + Operations for establishing a SAKKE key. + + Initialization SAKKE Key before use (wc_InitSakkeKey() or wc_InitSakkeKey_ex()).\n + Either make a new key (wc_MakeSakkeKey()) or import an existing key (wc_ImportSakkeKey()).\n + Export the key (wc_ExportSakkeKey()) after making a new key for future use.\n + If only the private part of the KMS SAKKE Key is available, make the public key (wc_MakeSakkePublicKey()).\n + Export the private key (wc_ExportSakkePrivateKey()) from KMS from storage.\n + Import the private key (wc_ImportSakkePrivateKey()) into KMS from storage.\n + Export the public key (wc_ExportSakkePublicKey()) from KMS to pass to client.\n + Import the public key (wc_ImportSakkePublicKey()) into client.\n + Set the identity to use (wc_SetSakkeIdentity()) into client.\n + Free the SAKKE Key (wc_FreeSakkeKey()) when finished. + + \defgroup SAKKE_RSK Operations on/with SAKKE RSK + These operations make, validate, encode and decode a Receiver Secret Key (RSK). + + An RSK is required to derive an SSV (see wc_DeriveSakkeSSV()).\n + On the KMS, make an RSK (wc_MakeSakkeRsk()) from the client's ID.\n + On the client, validate the RSK (wc_ValidateSakkeRsk()) with the ID.\n + Encode the RSK (wc_EncodeSakkeRsk()) to pass to client or for storage.\n + Decode the RSK (wc_DecodeSakkeRsk()) on the client when needed.\n + Import the RSK (wc_ImportSakkeRsk()) on the client when needed.\n + Set the RSK and, optionally, a pre-computation table (wc_SetSakkeRsk()) on the client when needed. + + \defgroup SAKKE_Operations Operations using SAKKE Key + These operations transfer a Shared Secret Value (SSV) from one client to another. The SSV may be randomly generated. + + Calculate the size of the authentication data (wc_GetSakkeAuthSize()) to determine where the SSV starts in a buffer.\n + Make the intermediate point I (wc_MakeSakkePointI()) to speed making an encapsulated and deriving SSV.\n + Get intermediate point I (wc_GetSakkePointI()) for storage.\n + Set intermediate point I (wc_SetSakkePointI()) from storage.\n + Generate a pre-computation table for intermediate point I (wc_GenerateSakkePointITable()) to further enhance performance. Store as necessary.\n + Set the pre-computation table for intermediate point I (wc_SetSakkePointITable()) to further enhance performance.\n + Clear the pre-computation table for intermediate point I (wc_ClearSakkePointITable()) to remove reference to external table pointer.\n + Make an encapsulated SSV (wc_MakeSakkeEncapsulatedSSV()) to share with another client. Data in SSV is modified.\n + Generate a random SSV (wc_GenerateSakkeSSV()) for key exchange.\n + Derive the SSV, (wc_DeriveSakkeSSV()) on the recipient from the encapsulated SSV. + \defgroup HC128 Algorithms - HC-128 \defgroup HMAC Algorithms - HMAC \defgroup IDEA Algorithms - IDEA diff --git a/doc/dox_comments/header_files/doxygen_pages.h b/doc/dox_comments/header_files/doxygen_pages.h index 015c73a3f..262236297 100644 --- a/doc/dox_comments/header_files/doxygen_pages.h +++ b/doc/dox_comments/header_files/doxygen_pages.h @@ -39,6 +39,8 @@
  • \ref ECC
  • \ref ED25519
  • \ref ED448
  • +
  • \ref ECCSI
  • +
  • \ref SAKKE
  • \ref HC128
  • \ref HMAC
  • \ref IDEA
  • @@ -56,3 +58,17 @@
  • \ref SRP
  • */ +/*! + \page ECCSI ECCSI API Reference + - \ref ECCSI_Overview + - \ref ECCSI_Setup + - \ref ECCSI_Operations +*/ +/*! + \page SAKKE SAKKE API Reference + - \ref SAKKE_Overview + - \ref SAKKE_Setup + - \ref SAKKE_RSK + - \ref SAKKE_Operations +*/ + diff --git a/doc/dox_comments/header_files/eccsi.h b/doc/dox_comments/header_files/eccsi.h new file mode 100644 index 000000000..b4f40aaf5 --- /dev/null +++ b/doc/dox_comments/header_files/eccsi.h @@ -0,0 +1,131 @@ + +/*! + \ingroup ECCSI_Setup +*/ +WOLFSSL_API int wc_InitEccsiKey(EccsiKey* key, void* heap, int devId); +/*! + \ingroup ECCSI_Setup +*/ +WOLFSSL_API int wc_InitEccsiKey_ex(EccsiKey* key, int keySz, int curveId, + void* heap, int devId); +/*! + \ingroup ECCSI_Setup +*/ +WOLFSSL_API void wc_FreeEccsiKey(EccsiKey* key); + +/*! + \ingroup ECCSI_Setup +*/ +WOLFSSL_API int wc_MakeEccsiKey(EccsiKey* key, WC_RNG* rng); + +/*! + \ingroup ECCSI_Operations +*/ +WOLFSSL_API int wc_MakeEccsiPair(EccsiKey* key, WC_RNG* rng, + enum wc_HashType hashType, const byte* id, word32 idSz, mp_int* ssk, + ecc_point* pvt); +/*! + \ingroup ECCSI_Operations +*/ +WOLFSSL_API int wc_ValidateEccsiPair(EccsiKey* key, enum wc_HashType hashType, + const byte* id, word32 idSz, const mp_int* ssk, ecc_point* pvt, + int* valid); +/*! + \ingroup ECCSI_Operations +*/ +WOLFSSL_API int wc_ValidateEccsiPvt(EccsiKey* key, const ecc_point* pvt, + int* valid); +/*! + \ingroup ECCSI_Operations +*/ +WOLFSSL_API int wc_EncodeEccsiPair(const EccsiKey* key, mp_int* ssk, + ecc_point* pvt, byte* data, word32* sz); +/*! + \ingroup ECCSI_Operations +*/ +WOLFSSL_API int wc_EncodeEccsiSsk(const EccsiKey* key, mp_int* ssk, byte* data, + word32* sz); +/*! + \ingroup ECCSI_Operations +*/ +WOLFSSL_API int wc_EncodeEccsiPvt(const EccsiKey* key, ecc_point* pvt, + byte* data, word32* sz, int raw); +/*! + \ingroup ECCSI_Operations +*/ +WOLFSSL_API int wc_DecodeEccsiPair(const EccsiKey* key, const byte* data, + word32 sz, mp_int* ssk, ecc_point* pvt); +/*! + \ingroup ECCSI_Operations +*/ +WOLFSSL_API int wc_DecodeEccsiSsk(const EccsiKey* key, const byte* data, + word32 sz, mp_int* ssk); +/*! + \ingroup ECCSI_Operations +*/ +WOLFSSL_API int wc_DecodeEccsiPvt(const EccsiKey* key, const byte* data, + word32 sz, ecc_point* pvt); +/*! + \ingroup ECCSI_Operations +*/ +WOLFSSL_API int wc_DecodeEccsiPvtFromSig(const EccsiKey* key, const byte* sig, + word32 sz, ecc_point* pvt); + +/*! + \ingroup ECCSI_Setup +*/ +WOLFSSL_API int wc_ExportEccsiKey(EccsiKey* key, byte* data, word32* sz); +/*! + \ingroup ECCSI_Setup +*/ +WOLFSSL_API int wc_ImportEccsiKey(EccsiKey* key, const byte* data, word32 sz); + +/*! + \ingroup ECCSI_Setup +*/ +WOLFSSL_API int wc_ExportEccsiPrivateKey(EccsiKey* key, byte* data, word32* sz); +/*! + \ingroup ECCSI_Setup +*/ +WOLFSSL_API int wc_ImportEccsiPrivateKey(EccsiKey* key, const byte* data, + word32 sz); + +/*! + \ingroup ECCSI_Setup +*/ +WOLFSSL_API int wc_ExportEccsiPublicKey(EccsiKey* key, byte* data, word32* sz, + int raw); +/*! + \ingroup ECCSI_Setup +*/ +WOLFSSL_API int wc_ImportEccsiPublicKey(EccsiKey* key, const byte* data, + word32 sz, int trusted); + +/*! + \ingroup ECCSI_Operations +*/ +WOLFSSL_API int wc_HashEccsiId(EccsiKey* key, enum wc_HashType hashType, + const byte* id, word32 idSz, ecc_point* pvt, byte* hash, byte* hashSz); +/*! + \ingroup ECCSI_Setup +*/ +WOLFSSL_API int wc_SetEccsiHash(EccsiKey* key, const byte* hash, byte hashSz); +/*! + \ingroup ECCSI_Setup +*/ +WOLFSSL_API int wc_SetEccsiPair(EccsiKey* key, const mp_int* ssk, + const ecc_point* pvt); + +/*! + \ingroup ECCSI_Operations +*/ +WOLFSSL_API int wc_SignEccsiHash(EccsiKey* key, WC_RNG* rng, + enum wc_HashType hashType, const byte* msg, word32 msgSz, byte* sig, + word32* sigSz); +/*! + \ingroup ECCSI_Operations +*/ +WOLFSSL_API int wc_VerifyEccsiHash(EccsiKey* key, enum wc_HashType hashType, + const byte* msg, word32 msgSz, const byte* sig, word32 sigSz, + int* verified); + diff --git a/doc/dox_comments/header_files/sakke.h b/doc/dox_comments/header_files/sakke.h new file mode 100644 index 000000000..021334c87 --- /dev/null +++ b/doc/dox_comments/header_files/sakke.h @@ -0,0 +1,143 @@ + +/*! + \ingroup SAKKE_Setup +*/ +WOLFSSL_API int wc_InitSakkeKey(SakkeKey* key, void* heap, int devId); +/*! + \ingroup SAKKE_Setup +*/ +WOLFSSL_API int wc_InitSakkeKey_ex(SakkeKey* key, int keySize, int curveId, + void* heap, int devId); +/*! + \ingroup SAKKE_Setup +*/ +WOLFSSL_API void wc_FreeSakkeKey(SakkeKey* key); + +/*! + \ingroup SAKKE_Setup +*/ +WOLFSSL_API int wc_MakeSakkeKey(SakkeKey* key, WC_RNG* rng); +/*! + \ingroup SAKKE_Setup +*/ +WOLFSSL_API int wc_MakeSakkePublicKey(SakkeKey* key, ecc_point* pub); + +/*! + \ingroup SAKKE_RSK +*/ +WOLFSSL_API int wc_MakeSakkeRsk(SakkeKey* key, const byte* id, word16 idSz, + ecc_point* rsk); +/*! + \ingroup SAKKE_RSK +*/ +WOLFSSL_API int wc_ValidateSakkeRsk(SakkeKey* key, const byte* id, word16 idSz, + ecc_point* rsk, int* valid); +/*! + \ingroup SAKKE_RSK +*/ +WOLFSSL_API int wc_GenerateSakkeRskTable(const SakkeKey* key, + const ecc_point* rsk, byte* table, word32* len); + + +/*! + \ingroup SAKKE_Setup +*/ +WOLFSSL_API int wc_ExportSakkeKey(SakkeKey* key, byte* data, word32* sz); +/*! + \ingroup SAKKE_Setup +*/ +WOLFSSL_API int wc_ImportSakkeKey(SakkeKey* key, const byte* data, word32 sz); +/*! + \ingroup SAKKE_Setup +*/ +WOLFSSL_API int wc_ExportSakkePrivateKey(SakkeKey* key, byte* data, word32* sz); +/*! + \ingroup SAKKE_Setup +*/ +WOLFSSL_API int wc_ImportSakkePrivateKey(SakkeKey* key, const byte* data, + word32 sz); + +/*! + \ingroup SAKKE_RSK +*/ +WOLFSSL_API int wc_EncodeSakkeRsk(const SakkeKey* key, ecc_point* rsk, + byte* out, word32* sz, int raw); +/*! + \ingroup SAKKE_RSK +*/ +WOLFSSL_API int wc_DecodeSakkeRsk(const SakkeKey* key, const byte* data, + word32 sz, ecc_point* rsk); + +/*! + \ingroup SAKKE_RSK +*/ +WOLFSSL_API int wc_ImportSakkeRsk(SakkeKey* key, const byte* data, word32 sz); + +/*! + \ingroup SAKKE_Setup +*/ +WOLFSSL_API int wc_ExportSakkePublicKey(SakkeKey* key, byte* data, + word32* sz, int raw); +/*! + \ingroup SAKKE_Setup +*/ +WOLFSSL_API int wc_ImportSakkePublicKey(SakkeKey* key, const byte* data, + word32 sz, int trusted); + +/*! + \ingroup SAKKE_Operations +*/ +WOLFSSL_API int wc_GetSakkeAuthSize(SakkeKey* key, word16* authSz); +/*! + \ingroup SAKKE_Setup +*/ +WOLFSSL_API int wc_SetSakkeIdentity(SakkeKey* key, const byte* id, word16 idSz); +/*! + \ingroup SAKKE_Operations +*/ +WOLFSSL_API int wc_MakeSakkePointI(SakkeKey* key, const byte* id, word16 idSz); +/*! + \ingroup SAKKE_Operations +*/ +WOLFSSL_API int wc_GetSakkePointI(SakkeKey* key, byte* data, word32* sz); +/*! + \ingroup SAKKE_Operations +*/ +WOLFSSL_API int wc_SetSakkePointI(SakkeKey* key, const byte* id, word16 idSz, + const byte* data, word32 sz); +/*! + \ingroup SAKKE_Operations +*/ +WOLFSSL_API int wc_GenerateSakkePointITable(SakkeKey* key, byte* table, + word32* len); +/*! + \ingroup SAKKE_Operations +*/ +WOLFSSL_API int wc_SetSakkePointITable(SakkeKey* key, byte* table, word32 len); +/*! + \ingroup SAKKE_Operations +*/ +WOLFSSL_API int wc_ClearSakkePointITable(SakkeKey* key); +/*! + \ingroup SAKKE_Operations +*/ +WOLFSSL_API int wc_MakeSakkeEncapsulatedSSV(SakkeKey* key, + enum wc_HashType hashType, byte* ssv, word16 ssvSz, byte* auth, + word16* authSz); +/*! + \ingroup SAKKE_Operations +*/ +WOLFSSL_API int wc_GenerateSakkeSSV(SakkeKey* key, WC_RNG* rng, byte* ssv, + word16* ssvSz); +/*! + \ingroup SAKKE_RSK +*/ +WOLFSSL_API int wc_SetSakkeRsk(SakkeKey* key, const ecc_point* rsk, byte* table, + word32 len); +/*! + \ingroup SAKKE_Operations +*/ +WOLFSSL_API int wc_DeriveSakkeSSV(SakkeKey* key, enum wc_HashType hashType, + byte* ssv, word16 ssvSz, const byte* auth, + word16 authSz); + diff --git a/examples/benchmark/tls_bench.c b/examples/benchmark/tls_bench.c index f130f28d1..aa593058f 100644 --- a/examples/benchmark/tls_bench.c +++ b/examples/benchmark/tls_bench.c @@ -1,6 +1,6 @@ /* tls_bench.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/examples/benchmark/tls_bench.h b/examples/benchmark/tls_bench.h index 483a3ae4f..62e0ba1b5 100644 --- a/examples/benchmark/tls_bench.h +++ b/examples/benchmark/tls_bench.h @@ -1,6 +1,6 @@ /* tls_bench.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/examples/client/client.c b/examples/client/client.c index a824b39a3..e47cf054f 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -1,6 +1,6 @@ /* client.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/examples/client/client.h b/examples/client/client.h index 72402e99f..bfdfe4144 100644 --- a/examples/client/client.h +++ b/examples/client/client.h @@ -1,6 +1,6 @@ /* client.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/examples/configs/user_settings_all.h b/examples/configs/user_settings_all.h index 905989d85..589a28eca 100644 --- a/examples/configs/user_settings_all.h +++ b/examples/configs/user_settings_all.h @@ -1,6 +1,6 @@ /* user_settings_all.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/examples/configs/user_settings_min_ecc.h b/examples/configs/user_settings_min_ecc.h index d00458d00..c23e34f1b 100644 --- a/examples/configs/user_settings_min_ecc.h +++ b/examples/configs/user_settings_min_ecc.h @@ -1,6 +1,6 @@ /* user_settings_min_ecc.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/examples/configs/user_settings_wolfboot_keytools.h b/examples/configs/user_settings_wolfboot_keytools.h index 4634c9d2c..230c73245 100644 --- a/examples/configs/user_settings_wolfboot_keytools.h +++ b/examples/configs/user_settings_wolfboot_keytools.h @@ -4,16 +4,16 @@ * Enabled via WOLFSSL_USER_SETTINGS. * * - * Copyright (C) 2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * - * This file is part of wolfBoot. + * This file is part of wolfSSL. * - * wolfBoot is free software; you can redistribute it and/or modify + * wolfSSL 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. * - * wolfBoot is distributed in the hope that it will be useful, + * wolfSSL 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. diff --git a/examples/echoclient/echoclient.c b/examples/echoclient/echoclient.c index c9cdd13ea..88866b18e 100644 --- a/examples/echoclient/echoclient.c +++ b/examples/echoclient/echoclient.c @@ -1,6 +1,6 @@ /* echoclient.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/examples/echoclient/echoclient.h b/examples/echoclient/echoclient.h index 0aebffbc2..b2b530956 100644 --- a/examples/echoclient/echoclient.h +++ b/examples/echoclient/echoclient.h @@ -1,6 +1,6 @@ /* echoclient.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/examples/echoserver/echoserver.c b/examples/echoserver/echoserver.c index 1ef3007f8..d50f84847 100644 --- a/examples/echoserver/echoserver.c +++ b/examples/echoserver/echoserver.c @@ -1,6 +1,6 @@ /* echoserver.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/examples/echoserver/echoserver.h b/examples/echoserver/echoserver.h index 622193f61..40bbfe684 100644 --- a/examples/echoserver/echoserver.h +++ b/examples/echoserver/echoserver.h @@ -1,6 +1,6 @@ /* echoserver.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/examples/sctp/sctp-client-dtls.c b/examples/sctp/sctp-client-dtls.c index c0a222463..8022e50ed 100644 --- a/examples/sctp/sctp-client-dtls.c +++ b/examples/sctp/sctp-client-dtls.c @@ -1,6 +1,6 @@ /* sctp-client-dtls.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/examples/sctp/sctp-client.c b/examples/sctp/sctp-client.c index cb01354d8..9a55cd210 100644 --- a/examples/sctp/sctp-client.c +++ b/examples/sctp/sctp-client.c @@ -1,6 +1,6 @@ /* sctp-client.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/examples/sctp/sctp-server-dtls.c b/examples/sctp/sctp-server-dtls.c index 50a20f241..5d14ca872 100644 --- a/examples/sctp/sctp-server-dtls.c +++ b/examples/sctp/sctp-server-dtls.c @@ -1,6 +1,6 @@ /* sctp-server-dtls.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/examples/sctp/sctp-server.c b/examples/sctp/sctp-server.c index 34b02c9ce..75034caaf 100644 --- a/examples/sctp/sctp-server.c +++ b/examples/sctp/sctp-server.c @@ -1,6 +1,6 @@ /* sctp-server.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/examples/server/server.c b/examples/server/server.c index 00e17e80e..d69b276c7 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -1,6 +1,6 @@ /* server.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/examples/server/server.h b/examples/server/server.h index 91927c7ea..45b5d5c1f 100644 --- a/examples/server/server.h +++ b/examples/server/server.h @@ -1,6 +1,6 @@ /* server.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/linuxkm/Kbuild b/linuxkm/Kbuild index 5909a1e2a..0fd689119 100644 --- a/linuxkm/Kbuild +++ b/linuxkm/Kbuild @@ -1,6 +1,6 @@ # Linux kernel-native Makefile ("Kbuild") for libwolfssl.ko # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -17,6 +17,7 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA +#/ SHELL=/bin/bash diff --git a/linuxkm/Makefile b/linuxkm/Makefile index 6293cfcf2..c0b5aaf09 100644 --- a/linuxkm/Makefile +++ b/linuxkm/Makefile @@ -1,6 +1,6 @@ # libwolfssl Linux kernel module Makefile (wraps Kbuild-native makefile) # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -17,6 +17,7 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA +#/ SHELL=/bin/bash diff --git a/linuxkm/get_thread_size.c b/linuxkm/get_thread_size.c index a3d4caac6..d475c8857 100644 --- a/linuxkm/get_thread_size.c +++ b/linuxkm/get_thread_size.c @@ -1,7 +1,7 @@ /* get_thread_size.c -- trivial program to determine stack frame size * for a Linux kernel thread, given a configured source tree. * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/linuxkm/module_exports.c.template b/linuxkm/module_exports.c.template index a78b7e281..aaa2f536a 100644 --- a/linuxkm/module_exports.c.template +++ b/linuxkm/module_exports.c.template @@ -1,7 +1,7 @@ /* module_exports.c.template -- static preamble for dynamically generated * module_exports.c (see Kbuild) * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/linuxkm/module_hooks.c b/linuxkm/module_hooks.c index 9bc8cb80a..bf31f8b11 100644 --- a/linuxkm/module_hooks.c +++ b/linuxkm/module_hooks.c @@ -1,6 +1,6 @@ /* module_hooks.c -- module load/unload hooks for libwolfssl.ko * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/m4/ax_linuxkm.m4 b/m4/ax_linuxkm.m4 index 6bba14254..f89ed5dab 100644 --- a/m4/ax_linuxkm.m4 +++ b/m4/ax_linuxkm.m4 @@ -1,6 +1,6 @@ # ax_linuxkm.m4 -- macros for getting attributes of default configured kernel # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -17,6 +17,7 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA +#/ AC_DEFUN([AC_PATH_DEFAULT_KERNEL_SOURCE], [ @@ -140,7 +141,7 @@ AC_DEFUN([AX_SIMD_CC_COMPILER_FLAGS], [ ;; *) - AC_MSG_ERROR(["Don\'t know how to construct assembler flags for target \"${host_cpu}\"."]) + AC_MSG_ERROR([Don't know how to construct assembler flags for target "${host_cpu}".]) ;; esac diff --git a/m4/ax_pthread.m4 b/m4/ax_pthread.m4 index ada7071f2..e5858e50c 100644 --- a/m4/ax_pthread.m4 +++ b/m4/ax_pthread.m4 @@ -14,20 +14,24 @@ # flags that are needed. (The user can also force certain compiler # flags/libs to be tested by setting these environment variables.) # -# Also sets PTHREAD_CC to any special C compiler that is needed for -# multi-threaded programs (defaults to the value of CC otherwise). (This -# is necessary on AIX to use the special cc_r compiler alias.) +# Also sets PTHREAD_CC and PTHREAD_CXX to any special C compiler that is +# needed for multi-threaded programs (defaults to the value of CC +# respectively CXX otherwise). (This is necessary on e.g. AIX to use the +# special cc_r/CC_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these flags, # but also to link with them as well. For example, you might link with # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# $PTHREAD_CXX $CXXFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # # If you are only building threaded programs, you may wish to use these # variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" # CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS" # CC="$PTHREAD_CC" +# CXX="$PTHREAD_CXX" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant # has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to @@ -55,6 +59,7 @@ # # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2011 Daniel Richard G. +# Copyright (c) 2019 Marc Stevens # # 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 @@ -82,11 +87,11 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 24 +#serial 30 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ -AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_CANONICAL_TARGET]) AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_PROG_SED]) AC_LANG_PUSH([C]) @@ -104,6 +109,7 @@ if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) + AS_IF([test "x$PTHREAD_CXX" != "x"], [CXX="$PTHREAD_CXX"]) CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) @@ -123,10 +129,12 @@ fi # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). -# Create a list of thread flags to try. Items starting with a "-" are -# C compiler flags, and other items are library names, except for "none" -# which indicates that we try without any flags at all, and "pthread-config" -# which is a program returning the flags for the Pth emulation library. +# Create a list of thread flags to try. Items with a "," contain both +# C compiler flags (before ",") and linker flags (after ","). Other items +# starting with a "-" are C compiler flags, and remaining items are +# library names, except for "none" which indicates that we try without +# any flags at all, and "pthread-config" which is a program returning +# the flags for the Pth emulation library. ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" @@ -150,7 +158,7 @@ ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread -- # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) -case $host_os in +case $target_os in freebsd*) @@ -194,36 +202,10 @@ case $host_os in # that too in a future libc.) So we'll check first for the # standard Solaris way of linking pthreads (-mt -lpthread). - ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" + ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags" ;; esac -# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) - -AS_IF([test "x$GCC" = "xyes"], - [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"]) - -# The presence of a feature test macro requesting re-entrant function -# definitions is, on some systems, a strong hint that pthreads support is -# correctly enabled - -case $host_os in - darwin* | hpux* | linux* | osf* | solaris*) - ax_pthread_check_macro="_REENTRANT" - ;; - - aix*) - ax_pthread_check_macro="_THREAD_SAFE" - ;; - - *) - ax_pthread_check_macro="--" - ;; -esac -AS_IF([test "x$ax_pthread_check_macro" = "x--"], - [ax_pthread_check_cond=0], - [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) - # Are we compiling with Clang? AC_CACHE_CHECK([whether $CC is Clang], @@ -242,83 +224,47 @@ AC_CACHE_CHECK([whether $CC is Clang], ]) ax_pthread_clang="$ax_cv_PTHREAD_CLANG" -ax_pthread_clang_warning=no -# Clang needs special handling, because older versions handle the -pthread -# option in a rather... idiosyncratic way +# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) -if test "x$ax_pthread_clang" = "xyes"; then +# Note that for GCC and Clang -pthread generally implies -lpthread, +# except when -nostdlib is passed. +# This is problematic using libtool to build C++ shared libraries with pthread: +# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460 +# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333 +# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555 +# To solve this, first try -pthread together with -lpthread for GCC - # Clang takes -pthread; it has never supported any other flag +AS_IF([test "x$GCC" = "xyes"], + [ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"]) - # (Note 1: This will need to be revisited if a system that Clang - # supports has POSIX threads in a separate library. This tends not - # to be the way of modern systems, but it's conceivable.) +# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first - # (Note 2: On some systems, notably Darwin, -pthread is not needed - # to get POSIX threads support; the API is always present and - # active. We could reasonably leave PTHREAD_CFLAGS empty. But - # -pthread does define _REENTRANT, and while the Darwin headers - # ignore this macro, third-party headers might not.) +AS_IF([test "x$ax_pthread_clang" = "xyes"], + [ax_pthread_flags="-pthread,-lpthread -pthread"]) - PTHREAD_CFLAGS="-pthread" - PTHREAD_LIBS= - ax_pthread_ok=yes +# The presence of a feature test macro requesting re-entrant function +# definitions is, on some systems, a strong hint that pthreads support is +# correctly enabled - # However, older versions of Clang make a point of warning the user - # that, in an invocation where only linking and no compilation is - # taking place, the -pthread option has no effect ("argument unused - # during compilation"). They expect -pthread to be passed in only - # when source code is being compiled. - # - # Problem is, this is at odds with the way Automake and most other - # C build frameworks function, which is that the same flags used in - # compilation (CFLAGS) are also used in linking. Many systems - # supported by AX_PTHREAD require exactly this for POSIX threads - # support, and in fact it is often not straightforward to specify a - # flag that is used only in the compilation phase and not in - # linking. Such a scenario is extremely rare in practice. - # - # Even though use of the -pthread flag in linking would only print - # a warning, this can be a nuisance for well-run software projects - # that build with -Werror. So if the active version of Clang has - # this misfeature, we search for an option to squash it. +case $target_os in + darwin* | hpux* | linux* | osf* | solaris*) + ax_pthread_check_macro="_REENTRANT" + ;; - AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], - [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], - [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown - # Create an alternate version of $ac_link that compiles and - # links in two steps (.c -> .o, .o -> exe) instead of one - # (.c -> exe), because the warning occurs only in the second - # step - ax_pthread_save_ac_link="$ac_link" - ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' - ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` - ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" - ax_pthread_save_CFLAGS="$CFLAGS" - for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do - AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) - CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" - ac_link="$ax_pthread_save_ac_link" - AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], - [ac_link="$ax_pthread_2step_ac_link" - AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], - [break]) - ]) - done - ac_link="$ax_pthread_save_ac_link" - CFLAGS="$ax_pthread_save_CFLAGS" - AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) - ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" - ]) + aix*) + ax_pthread_check_macro="_THREAD_SAFE" + ;; - case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in - no | unknown) ;; - *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; - esac + *) + ax_pthread_check_macro="--" + ;; +esac +AS_IF([test "x$ax_pthread_check_macro" = "x--"], + [ax_pthread_check_cond=0], + [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) -fi # $ax_pthread_clang = yes if test "x$ax_pthread_ok" = "xno"; then for ax_pthread_try_flag in $ax_pthread_flags; do @@ -328,10 +274,10 @@ for ax_pthread_try_flag in $ax_pthread_flags; do AC_MSG_CHECKING([whether pthreads work without any flags]) ;; - -mt,pthread) - AC_MSG_CHECKING([whether pthreads work with -mt -lpthread]) - PTHREAD_CFLAGS="-mt" - PTHREAD_LIBS="-lpthread" + *,*) + PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"` + PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"` + AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"]) ;; -*) @@ -368,10 +314,16 @@ for ax_pthread_try_flag in $ax_pthread_flags; do # We try pthread_create on general principles. AC_LINK_IFELSE([AC_LANG_PROGRAM([#include -dnl# if $ax_pthread_check_cond -dnl# error "$ax_pthread_check_macro must be defined" -dnl# endif - static void routine(void *a) { a = 0; } +# if $ax_pthread_check_cond +# error "$ax_pthread_check_macro must be defined" +# endif + static void *some_global = NULL; + static void routine(void *a) + { + /* To avoid any unused-parameter or + unused-but-set-parameter warning. */ + some_global = a; + } static void *start_routine(void *a) { return a; }], [pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); @@ -393,6 +345,80 @@ dnl# endif done fi + +# Clang needs special handling, because older versions handle the -pthread +# option in a rather... idiosyncratic way + +if test "x$ax_pthread_clang" = "xyes"; then + + # Clang takes -pthread; it has never supported any other flag + + # (Note 1: This will need to be revisited if a system that Clang + # supports has POSIX threads in a separate library. This tends not + # to be the way of modern systems, but it's conceivable.) + + # (Note 2: On some systems, notably Darwin, -pthread is not needed + # to get POSIX threads support; the API is always present and + # active. We could reasonably leave PTHREAD_CFLAGS empty. But + # -pthread does define _REENTRANT, and while the Darwin headers + # ignore this macro, third-party headers might not.) + + # However, older versions of Clang make a point of warning the user + # that, in an invocation where only linking and no compilation is + # taking place, the -pthread option has no effect ("argument unused + # during compilation"). They expect -pthread to be passed in only + # when source code is being compiled. + # + # Problem is, this is at odds with the way Automake and most other + # C build frameworks function, which is that the same flags used in + # compilation (CFLAGS) are also used in linking. Many systems + # supported by AX_PTHREAD require exactly this for POSIX threads + # support, and in fact it is often not straightforward to specify a + # flag that is used only in the compilation phase and not in + # linking. Such a scenario is extremely rare in practice. + # + # Even though use of the -pthread flag in linking would only print + # a warning, this can be a nuisance for well-run software projects + # that build with -Werror. So if the active version of Clang has + # this misfeature, we search for an option to squash it. + + AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown + # Create an alternate version of $ac_link that compiles and + # links in two steps (.c -> .o, .o -> exe) instead of one + # (.c -> exe), because the warning occurs only in the second + # step + ax_pthread_save_ac_link="$ac_link" + ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' + ax_pthread_link_step=`AS_ECHO(["$ac_link"]) | sed "$ax_pthread_sed"` + ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" + ax_pthread_save_CFLAGS="$CFLAGS" + for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do + AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) + CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" + ac_link="$ax_pthread_save_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [ac_link="$ax_pthread_2step_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [break]) + ]) + done + ac_link="$ax_pthread_save_ac_link" + CFLAGS="$ax_pthread_save_CFLAGS" + AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) + ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" + ]) + + case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in + no | unknown) ;; + *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; + esac + +fi # $ax_pthread_clang = yes + + + # Various other checks: if test "x$ax_pthread_ok" = "xyes"; then ax_pthread_save_CFLAGS="$CFLAGS" @@ -424,7 +450,7 @@ if test "x$ax_pthread_ok" = "xyes"; then AC_CACHE_CHECK([whether more special flags are required for pthreads], [ax_cv_PTHREAD_SPECIAL_FLAGS], [ax_cv_PTHREAD_SPECIAL_FLAGS=no - case $host_os in + case $target_os in solaris*) ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" ;; @@ -438,7 +464,8 @@ if test "x$ax_pthread_ok" = "xyes"; then AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], [ax_cv_PTHREAD_PRIO_INHERIT], [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], - [[int i = PTHREAD_PRIO_INHERIT;]])], + [[int i = PTHREAD_PRIO_INHERIT; + return i;]])], [ax_cv_PTHREAD_PRIO_INHERIT=yes], [ax_cv_PTHREAD_PRIO_INHERIT=no]) ]) @@ -453,25 +480,35 @@ if test "x$ax_pthread_ok" = "xyes"; then # More AIX lossage: compile with *_r variant if test "x$GCC" != "xyes"; then - case $host_os in + case $target_os in aix*) AS_CASE(["x/$CC"], [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], [#handle absolute path differently from PATH based program lookup AS_CASE(["x$CC"], [x/*], - [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], - [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) + [ + AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"]) + AS_IF([test "x${CXX}" != "x"], [AS_IF([AS_EXECUTABLE_P([${CXX}_r])],[PTHREAD_CXX="${CXX}_r"])]) + ], + [ + AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC]) + AS_IF([test "x${CXX}" != "x"], [AC_CHECK_PROGS([PTHREAD_CXX],[${CXX}_r],[$CXX])]) + ] + ) + ]) ;; esac fi fi test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" +test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX" AC_SUBST([PTHREAD_LIBS]) AC_SUBST([PTHREAD_CFLAGS]) AC_SUBST([PTHREAD_CC]) +AC_SUBST([PTHREAD_CXX]) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test "x$ax_pthread_ok" = "xyes"; then diff --git a/m4/ax_tls.m4 b/m4/ax_tls.m4 index 3f6b5e10b..deba1feb6 100644 --- a/m4/ax_tls.m4 +++ b/m4/ax_tls.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_tls.html +# https://www.gnu.org/software/autoconf-archive/ax_tls.html # =========================================================================== # # SYNOPSIS @@ -9,9 +9,9 @@ # DESCRIPTION # # Provides a test for the compiler support of thread local storage (TLS) -# extensions. Defines TLS if it is found. Currently knows about GCC/ICC -# and MSVC. I think SunPro uses the same as GCC, and Borland apparently -# supports either. +# extensions. Defines TLS if it is found. Currently knows about C++11, +# GCC/ICC, and MSVC. I think SunPro uses the same as GCC, and Borland +# apparently supports either. # # LICENSE # @@ -29,7 +29,7 @@ # Public License for more details. # # You should have received a copy of the GNU General Public License along -# with this program. If not, see . +# with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure @@ -44,7 +44,7 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 11 +#serial 15 # Define m4_ifblank and m4_ifnblank macros from introduced in # autotools 2.64 m4sugar.m4 if using an earlier autotools. @@ -55,7 +55,6 @@ ifdef([m4_ifblank], [], [ ]), [], [$2], [$3])]) ]) - ifdef([m4_ifnblank], [], [ m4_define([m4_ifnblank], [m4_if(m4_translit([[$1]], [ ][ ][ @@ -63,30 +62,25 @@ ifdef([m4_ifnblank], [], [ ]) AC_DEFUN([AX_TLS], [ - AC_MSG_CHECKING(for thread local storage (TLS) class) - AC_CACHE_VAL(ac_cv_tls, [ - ax_tls_keywords="__thread __declspec(thread) none" - for ax_tls_keyword in $ax_tls_keywords; do + AC_MSG_CHECKING([for thread local storage (TLS) class]) + AC_CACHE_VAL([ac_cv_tls], + [for ax_tls_keyword in thread_local _Thread_local __thread '__declspec(thread)' none; do AS_CASE([$ax_tls_keyword], [none], [ac_cv_tls=none ; break], - [AC_TRY_COMPILE( - [#include - static void - foo(void) { - static ] $ax_tls_keyword [ int bar; - exit(1); - }], - [], - [ac_cv_tls=$ax_tls_keyword ; break], - ac_cv_tls=none - )]) - done - ]) - AC_MSG_RESULT($ac_cv_tls) + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [#include ], + [static $ax_tls_keyword int bar;] + )], + [ac_cv_tls=$ax_tls_keyword ; break], + [ac_cv_tls=none] + )] + ) + done ] + ) + AC_MSG_RESULT([$ac_cv_tls]) AS_IF([test "$ac_cv_tls" != "none"], - AC_DEFINE_UNQUOTED([TLS], $ac_cv_tls, [If the compiler supports a TLS storage class define it to that here]) - m4_ifnblank([$1], [$1]), - m4_ifnblank([$2], [$2]) - ) + [AC_DEFINE_UNQUOTED([TLS],[$ac_cv_tls],[If the compiler supports a TLS storage class, define it to that here]) + m4_ifnblank([$1],[$1],[[:]])], + [m4_ifnblank([$2],[$2],[[:]])]) ]) diff --git a/mcapi/crypto.c b/mcapi/crypto.c index 18ec920c3..568cd8849 100644 --- a/mcapi/crypto.c +++ b/mcapi/crypto.c @@ -1,6 +1,6 @@ /* crypto.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/mcapi/crypto.h b/mcapi/crypto.h index ddb450b63..8698fd1e2 100644 --- a/mcapi/crypto.h +++ b/mcapi/crypto.h @@ -1,6 +1,6 @@ /* crypto.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/mcapi/mcapi_test.c b/mcapi/mcapi_test.c index cf0c31075..6ca547087 100644 --- a/mcapi/mcapi_test.c +++ b/mcapi/mcapi_test.c @@ -1,6 +1,6 @@ /* mcapi_test.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/mplabx/benchmark_main.c b/mplabx/benchmark_main.c index 461e53bea..5a7da70c0 100644 --- a/mplabx/benchmark_main.c +++ b/mplabx/benchmark_main.c @@ -1,6 +1,6 @@ /* benchmark_main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/mplabx/test_main.c b/mplabx/test_main.c index 8d1881cc4..101937678 100644 --- a/mplabx/test_main.c +++ b/mplabx/test_main.c @@ -1,6 +1,6 @@ /* main.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/scripts/tls13.test b/scripts/tls13.test index 70f007265..2c9c6c4ce 100755 --- a/scripts/tls13.test +++ b/scripts/tls13.test @@ -1,7 +1,7 @@ #!/bin/sh # tls13.test -# copyright wolfSSL 2016 +# Copyright wolfSSL 2016-2021 # if we can, isolate the network namespace to eliminate port collisions. if [ "${AM_BWRAPPED-}" != "yes" ]; then diff --git a/src/bio.c b/src/bio.c index 18d74aca1..6509efcd2 100644 --- a/src/bio.c +++ b/src/bio.c @@ -1,6 +1,6 @@ /* bio.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/crl.c b/src/crl.c index 1663b347a..34f6281a8 100644 --- a/src/crl.c +++ b/src/crl.c @@ -1,6 +1,6 @@ /* crl.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -911,7 +911,7 @@ static void* DoMonitor(void* arg) if (kevent(crl->mfd, &change, 1, NULL, 0, NULL) < 0) { WOLFSSL_MSG("kevent monitor customer event failed"); SignalSetup(crl, MONITOR_SETUP_E); - close(crl->mfd); + (void)close(crl->mfd); return NULL; } @@ -923,7 +923,7 @@ static void* DoMonitor(void* arg) if (fPEM == -1) { WOLFSSL_MSG("PEM event dir open failed"); SignalSetup(crl, MONITOR_SETUP_E); - close(crl->mfd); + (void)close(crl->mfd); return NULL; } } @@ -933,8 +933,8 @@ static void* DoMonitor(void* arg) if (fDER == -1) { WOLFSSL_MSG("DER event dir open failed"); if (fPEM != -1) - close(fPEM); - close(crl->mfd); + (void)close(fPEM); + (void)close(crl->mfd); SignalSetup(crl, MONITOR_SETUP_E); return NULL; } @@ -951,10 +951,10 @@ static void* DoMonitor(void* arg) /* signal to calling thread we're setup */ if (SignalSetup(crl, 1) != 0) { if (fPEM != -1) - close(fPEM); + (void)close(fPEM); if (fDER != -1) - close(fDER); - close(crl->mfd); + (void)close(fDER); + (void)close(crl->mfd); return NULL; } @@ -980,11 +980,11 @@ static void* DoMonitor(void* arg) } if (fPEM != -1) - close(fPEM); + (void)close(fPEM); if (fDER != -1) - close(fDER); + (void)close(fDER); - close(crl->mfd); + (void)close(crl->mfd); return NULL; } @@ -1045,7 +1045,7 @@ static void* DoMonitor(void* arg) notifyFd = inotify_init(); if (notifyFd < 0) { WOLFSSL_MSG("inotify failed"); - close(crl->mfd); + (void)close(crl->mfd); SignalSetup(crl, MONITOR_SETUP_E); return NULL; } @@ -1055,8 +1055,8 @@ static void* DoMonitor(void* arg) IN_DELETE); if (wd < 0) { WOLFSSL_MSG("PEM notify add watch failed"); - close(crl->mfd); - close(notifyFd); + (void)close(crl->mfd); + (void)close(notifyFd); SignalSetup(crl, MONITOR_SETUP_E); return NULL; } @@ -1067,8 +1067,8 @@ static void* DoMonitor(void* arg) IN_DELETE); if (wd < 0) { WOLFSSL_MSG("DER notify add watch failed"); - close(crl->mfd); - close(notifyFd); + (void)close(crl->mfd); + (void)close(notifyFd); SignalSetup(crl, MONITOR_SETUP_E); return NULL; } @@ -1088,8 +1088,8 @@ static void* DoMonitor(void* arg) if (wd > 0) inotify_rm_watch(notifyFd, wd); - close(crl->mfd); - close(notifyFd); + (void)close(crl->mfd); + (void)close(notifyFd); return NULL; } @@ -1143,8 +1143,8 @@ static void* DoMonitor(void* arg) if (wd > 0) inotify_rm_watch(notifyFd, wd); - close(crl->mfd); - close(notifyFd); + (void)close(crl->mfd); + (void)close(notifyFd); return NULL; } diff --git a/src/include.am b/src/include.am index ee6be660e..e1c6b461d 100644 --- a/src/include.am +++ b/src/include.am @@ -444,6 +444,12 @@ if !BUILD_FIPS_V2 if BUILD_ECC src_libwolfssl_la_SOURCES += wolfcrypt/src/ecc.c endif +if BUILD_ECCSI +src_libwolfssl_la_SOURCES += wolfcrypt/src/eccsi.c +endif +if BUILD_SAKKE +src_libwolfssl_la_SOURCES += wolfcrypt/src/sakke.c +endif endif if BUILD_CURVE25519 diff --git a/src/internal.c b/src/internal.c index 0b07103af..7397c73ef 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1,6 +1,6 @@ /* internal.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -3586,6 +3586,8 @@ static WC_INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output) break; #endif #endif + default: + break; } (void)hashAlgo; (void)output; @@ -3620,6 +3622,8 @@ static void SetDigest(WOLFSSL* ssl, int hashAlgo) ssl->buffers.digest.length = WC_SHA512_DIGEST_SIZE; break; #endif /* WOLFSSL_SHA512 */ + default: + break; } /* switch */ } #endif /* !WOLFSSL_NO_TLS12 && !WOLFSSL_NO_CLIENT_AUTH */ @@ -3666,6 +3670,8 @@ static int TypeHash(int hashAlgo) case sha_mac: return SHAh; #endif + default: + break; } return 0; @@ -8850,62 +8856,61 @@ static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender) if (first == CHACHA_BYTE) { switch (second) { - case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 : - if (requirement == REQUIRES_RSA) - return 1; - break; + case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 : + if (requirement == REQUIRES_RSA) + return 1; + break; - case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 : - if (requirement == REQUIRES_ECC) - return 1; - break; + case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 : + if (requirement == REQUIRES_ECC) + return 1; + break; - case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 : - if (requirement == REQUIRES_RSA) - return 1; - if (requirement == REQUIRES_DHE) - return 1; - break; + case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 : + if (requirement == REQUIRES_RSA) + return 1; + if (requirement == REQUIRES_DHE) + return 1; + break; - case TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 : - if (requirement == REQUIRES_RSA) - return 1; - break; + case TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 : + if (requirement == REQUIRES_RSA) + return 1; + break; - case TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 : - if (requirement == REQUIRES_ECC) - return 1; - break; + case TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 : + if (requirement == REQUIRES_ECC) + return 1; + break; - case TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 : - if (requirement == REQUIRES_RSA) - return 1; - if (requirement == REQUIRES_DHE) - return 1; - break; + case TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 : + if (requirement == REQUIRES_RSA) + return 1; + if (requirement == REQUIRES_DHE) + return 1; + break; - case TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 : - if (requirement == REQUIRES_PSK) - return 1; - break; + case TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 : + if (requirement == REQUIRES_PSK) + return 1; + break; - case TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 : - if (requirement == REQUIRES_PSK) - return 1; - break; + case TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 : + if (requirement == REQUIRES_PSK) + return 1; + break; - case TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 : - if (requirement == REQUIRES_PSK) - return 1; - if (requirement == REQUIRES_DHE) - return 1; - break; - } + case TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 : + if (requirement == REQUIRES_PSK) + return 1; + if (requirement == REQUIRES_DHE) + return 1; + break; + } if (requirement == REQUIRES_AEAD) return 1; - } #endif /* HAVE_CHACHA */ @@ -10969,7 +10974,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, args->idx += extSz; listSz -= extSz + OPAQUE16_LEN; ret = TLSX_Parse(ssl, args->exts[args->totalCerts].buffer, - args->exts[args->totalCerts].length, certificate, NULL); + (word16)args->exts[args->totalCerts].length, + certificate, NULL); if (ret < 0) { ERROR_OUT(ret, exit_ppc); } @@ -14023,7 +14029,7 @@ static int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input, return ret; } if ((ret = wc_Poly1305_MAC(ssl->auth.poly1305, add, - sizeof(add), (byte*)input, msgLen, tag, sizeof(tag))) != 0) { + sizeof(add), input, msgLen, tag, sizeof(tag))) != 0) { ForceZero(poly, sizeof(poly)); return ret; } @@ -14356,6 +14362,9 @@ static WC_INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 #endif /* BUILD_AESGCM || HAVE_AESCCM */ break; } + + default: + break; } /* Reset state */ @@ -14645,6 +14654,9 @@ static WC_INLINE int Decrypt(WOLFSSL* ssl, byte* plain, const byte* input, #endif /* BUILD_AESGCM || HAVE_AESCCM */ break; } + + default: + break; } /* Reset state */ @@ -15571,7 +15583,7 @@ int ProcessReply(WOLFSSL* ssl) ret = Decrypt(ssl, in->buffer + in->idx, in->buffer + in->idx, - ssl->curSize - digestSz); + ssl->curSize - (word16)digestSz); if (ret == 0) { ssl->keys.padSz = in->buffer[in->idx + ssl->curSize - @@ -15916,7 +15928,7 @@ int ProcessReply(WOLFSSL* ssl) if (ssl->options.startedETMRead) { word32 digestSz = MacSize(ssl); ssl->buffers.inputBuffer.idx += digestSz; - ssl->curSize -= digestSz; + ssl->curSize -= (word16)digestSz; } #endif } @@ -16854,8 +16866,9 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY) if (ssl->options.startedETMWrite) { ret = Encrypt(ssl, output + args->headerSz, - output + args->headerSz, - args->size - args->digestSz, asyncOkay); + output + args->headerSz, + (word16)(args->size - args->digestSz), + asyncOkay); } else #endif @@ -16919,6 +16932,9 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, } #endif /* HAVE_ENCRYPT_THEN_MAC && !WOLFSSL_AEAD_ONLY */ } + FALL_THROUGH; + default: + break; } exit_buildmsg: @@ -19963,7 +19979,7 @@ static int MatchSigAlgo(WOLFSSL* ssl, int sigAlgo) defined(USE_ECDSA_KEYSZ_HASH_ALGO) static int CmpEccStrength(int hashAlgo, int curveSz) { - int dgstSz = GetMacDigestSize(hashAlgo); + int dgstSz = GetMacDigestSize((byte)hashAlgo); if (dgstSz <= 0) return -1; return dgstSz - (curveSz & (~0x3)); @@ -21698,6 +21714,7 @@ exit_dpk: case WOLFSSL_ECC_SECP521R1: return ECC_SECP521R1_OID; #endif /* !NO_ECC_SECP */ #endif + default: break; } return ret; @@ -21750,7 +21767,7 @@ static int GetDhPublicKey(WOLFSSL* ssl, const byte* input, word32 size, word16 length; #ifdef HAVE_FFDHE const DhParams* params = NULL; - int group = 0; + word16 group = 0; #endif if (ssl->buffers.weOwnDH) { @@ -26538,6 +26555,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, goto exit_sske; break; #endif /* HAVE_ED448 */ + default: + break; } /* switch(ssl->specs.sig_algo) */ break; } @@ -26557,7 +26576,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, preSigSz = args->length; if (!ssl->options.usingAnon_cipher) { - word16 keySz; + word16 keySz = 0; /* sig length */ args->length += LENGTH_SZ; @@ -26580,7 +26599,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } } - if (keySz == 0) { /* test if keySz has error */ + /* test if keySz has error */ + if (keySz == 0) { ERROR_OUT(keySz, exit_sske); } @@ -26754,10 +26774,14 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; } #endif /* NO_RSA */ + default: + break; } /* switch (ssl->suites->sigAlgo) */ break; } #endif /* !defined(NO_DH) && !defined(NO_RSA) */ + default: + break; } /* switch(ssl->specs.kea) */ /* Check for error */ @@ -26878,6 +26902,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; } #endif + default: + ERROR_OUT(ALGO_ID_E, exit_sske); } /* switch(ssl->specs.sig_algo) */ break; } @@ -26912,11 +26938,15 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; } #endif /* NO_RSA */ + default: + break; } /* switch (ssl->suites->sigAlgo) */ break; } #endif /* !defined(NO_DH) && !defined(NO_RSA) */ + default: + break; } /* switch(ssl->specs.kea) */ /* Check for error */ @@ -27063,6 +27093,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; } #endif /* !defined(NO_DH) && !defined(NO_RSA) */ + default: + break; } /* switch(ssl->specs.kea) */ /* Check for error */ @@ -28239,8 +28271,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef HAVE_TLS_EXTENSIONS /* tls extensions */ - if ((ret = TLSX_Parse(ssl, (byte *) input + i, totalExtSz, - client_hello, &clSuites))) + if ((ret = TLSX_Parse(ssl, input + i, totalExtSz, client_hello, + &clSuites))) goto out; #ifdef WOLFSSL_TLS13 if (TLSX_Find(ssl->extensions, @@ -28742,6 +28774,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* Advance state and proceed */ ssl->options.asyncState = TLS_ASYNC_END; } /* case TLS_ASYNC_FINALIZE */ + FALL_THROUGH; case TLS_ASYNC_END: { diff --git a/src/keys.c b/src/keys.c index deb62ed43..71da4eb73 100644 --- a/src/keys.c +++ b/src/keys.c @@ -1,6 +1,6 @@ /* keys.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -1203,6 +1203,8 @@ int SetCipherSpecs(WOLFSSL* ssl) break; #endif #endif /* WOLFSSL_TLS13 */ + default: + break; } } diff --git a/src/ocsp.c b/src/ocsp.c index 07eefb731..06a4ecb5f 100644 --- a/src/ocsp.c +++ b/src/ocsp.c @@ -1,6 +1,6 @@ /* ocsp.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/sniffer.c b/src/sniffer.c index 3411bc7c5..372e07c59 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -1,6 +1,6 @@ /* sniffer.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -5517,7 +5517,7 @@ int ssl_Trace(const char* traceFile, char* error) if (traceFile) { /* Don't try to reopen the file */ if (TraceFile == NULL) { - TraceFile = fopen(traceFile, "a"); + TraceFile = XFOPEN(traceFile, "a"); if (!TraceFile) { SetError(BAD_TRACE_FILE_STR, error, NULL, 0); return -1; diff --git a/src/ssl.c b/src/ssl.c index 28e1f6f6e..c431705b0 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1,6 +1,6 @@ /* ssl.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -5704,21 +5704,9 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, case CTC_SHA256wECDSA: case CTC_SHA384wECDSA: case CTC_SHA512wECDSA: - WOLFSSL_MSG("ECDSA cert signature"); - if (ssl) - ssl->options.haveECDSAsig = 1; - else if (ctx) - ctx->haveECDSAsig = 1; - break; case CTC_ED25519: - WOLFSSL_MSG("ED25519 cert signature"); - if (ssl) - ssl->options.haveECDSAsig = 1; - else if (ctx) - ctx->haveECDSAsig = 1; - break; case CTC_ED448: - WOLFSSL_MSG("ED448 cert signature"); + WOLFSSL_MSG("ECDSA/ED25519/ED448 cert signature"); if (ssl) ssl->options.haveECDSAsig = 1; else if (ctx) @@ -6238,7 +6226,7 @@ int CM_VerifyBuffer_ex(WOLFSSL_CERT_MANAGER* cm, const byte* buff, #endif } else { - InitDecodedCert(cert, (byte*)buff, (word32)sz, cm->heap); + InitDecodedCert(cert, buff, (word32)sz, cm->heap); } if (ret == 0) @@ -11384,8 +11372,10 @@ int wolfSSL_restore_session_cache(const char *fname) #endif /* NO_SESSION_CACHE */ -void wolfSSL_load_error_strings(void) /* compatibility only */ -{} +void wolfSSL_load_error_strings(void) +{ + /* compatibility only */ +} int wolfSSL_library_init(void) @@ -13411,7 +13401,7 @@ WOLFSSL_SESSION* GetSessionClient(WOLFSSL* ssl, const byte* id, int len) if (idx < 0) idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */ - for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) { + for (; count > 0; --count) { WOLFSSL_SESSION* current; ClientSession clSess; @@ -13435,6 +13425,8 @@ WOLFSSL_SESSION* GetSessionClient(WOLFSSL* ssl, const byte* id, int len) } else { WOLFSSL_MSG("ServerID not a match from client table"); } + + idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1; } wc_UnLockMutex(&session_mutex); @@ -13536,7 +13528,7 @@ WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret, if (idx < 0) idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */ - for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) { + for (; count > 0; --count) { WOLFSSL_SESSION* current; if (idx >= SESSIONS_PER_ROW || idx < 0) { /* sanity check */ @@ -13559,6 +13551,8 @@ WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret, } else { WOLFSSL_MSG("SessionID not a match at this idx"); } + + idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1; } wc_UnLockMutex(&session_mutex); @@ -22485,6 +22479,8 @@ static const char* wolfssl_ffdhe_name(word16 group) case WOLFSSL_FFDHE_8192: str = "FFDHE_8192"; break; + default: + break; } return str; } @@ -24693,32 +24689,40 @@ int wolfSSL_COMP_add_compression_method(int method, void* data) } #endif -#ifndef NO_WOLFSSL_STUB +/* wolfSSL_set_dynlock_create_callback + * CRYPTO_set_dynlock_create_callback has been deprecated since openSSL 1.0.1. + * This function exists for compatibility purposes because wolfSSL satisfies + * thread safety without relying on the callback. + */ void wolfSSL_set_dynlock_create_callback(WOLFSSL_dynlock_value* (*f)( const char*, int)) { WOLFSSL_STUB("CRYPTO_set_dynlock_create_callback"); (void)f; } -#endif - -#ifndef NO_WOLFSSL_STUB +/* wolfSSL_set_dynlock_lock_callback + * CRYPTO_set_dynlock_lock_callback has been deprecated since openSSL 1.0.1. + * This function exists for compatibility purposes because wolfSSL satisfies + * thread safety without relying on the callback. + */ void wolfSSL_set_dynlock_lock_callback( void (*f)(int, WOLFSSL_dynlock_value*, const char*, int)) { WOLFSSL_STUB("CRYPTO_set_set_dynlock_lock_callback"); (void)f; } -#endif - -#ifndef NO_WOLFSSL_STUB +/* wolfSSL_set_dynlock_destroy_callback + * CRYPTO_set_dynlock_destroy_callback has been deprecated since openSSL 1.0.1. + * This function exists for compatibility purposes because wolfSSL satisfies + * thread safety without relying on the callback. + */ void wolfSSL_set_dynlock_destroy_callback( void (*f)(WOLFSSL_dynlock_value*, const char*, int)) { WOLFSSL_STUB("CRYPTO_set_set_dynlock_destroy_callback"); (void)f; } -#endif + #endif /* OPENSSL_EXTRA */ @@ -30197,8 +30201,9 @@ int wolfSSL_ASN1_TIME_set_string(WOLFSSL_ASN1_TIME *s, const char *str) } if (s) { XMEMCPY(s->data, str, slen); - s->length = slen; - s->type = slen == ASN_UTC_TIME_SIZE ? ASN_UTC_TIME : ASN_GENERALIZED_TIME; + s->length = slen - 1; /* do not include null terminator in length */ + s->type = slen == ASN_UTC_TIME_SIZE ? V_ASN1_UTCTIME : + V_ASN1_GENERALIZEDTIME; } return WOLFSSL_SUCCESS; } @@ -42168,7 +42173,8 @@ err: #endif #endif /* !NO_BIO */ - int wolfSSL_PEM_get_EVP_CIPHER_INFO(char* header, EncryptedInfo* cipher) + int wolfSSL_PEM_get_EVP_CIPHER_INFO(const char* header, + EncryptedInfo* cipher) { if (header == NULL || cipher == NULL) return WOLFSSL_FAILURE; @@ -51952,9 +51958,6 @@ WOLFSSL_ASN1_TIME* wolfSSL_ASN1_TIME_adj(WOLFSSL_ASN1_TIME *s, time_t t, char utc_str[ASN_UTC_TIME_SIZE]; int utc_year = 0,utc_mon,utc_day,utc_hour,utc_min,utc_sec; - s->type = V_ASN1_UTCTIME; - s->length = ASN_UTC_TIME_SIZE; - if (ts->tm_year >= 50 && ts->tm_year < 100){ utc_year = ts->tm_year; } else if (ts->tm_year >= 100 && ts->tm_year < 150){ @@ -51968,15 +51971,13 @@ WOLFSSL_ASN1_TIME* wolfSSL_ASN1_TIME_adj(WOLFSSL_ASN1_TIME *s, time_t t, XSNPRINTF((char *)utc_str, sizeof(utc_str), "%02d%02d%02d%02d%02d%02dZ", utc_year, utc_mon, utc_day, utc_hour, utc_min, utc_sec); - XMEMCPY(s->data, (byte *)utc_str, s->length); + if (wolfSSL_ASN1_TIME_set_string(s, utc_str) != WOLFSSL_SUCCESS) + return NULL; /* GeneralizedTime */ } else { char gt_str[ASN_GENERALIZED_TIME_MAX]; int gt_year,gt_mon,gt_day,gt_hour,gt_min,gt_sec; - s->type = V_ASN1_GENERALIZEDTIME; - s->length = ASN_GENERALIZED_TIME_SIZE; - gt_year = ts->tm_year + 1900; gt_mon = ts->tm_mon + 1; gt_day = ts->tm_mday; @@ -51986,7 +51987,8 @@ WOLFSSL_ASN1_TIME* wolfSSL_ASN1_TIME_adj(WOLFSSL_ASN1_TIME *s, time_t t, XSNPRINTF((char *)gt_str, sizeof(gt_str), "%4d%02d%02d%02d%02d%02dZ", gt_year, gt_mon, gt_day, gt_hour, gt_min,gt_sec); - XMEMCPY(s->data, (byte *)gt_str, s->length); + if (wolfSSL_ASN1_TIME_set_string(s, gt_str) != WOLFSSL_SUCCESS) + return NULL; } return s; @@ -53911,61 +53913,93 @@ int wolfSSL_X509_set_serialNumber(WOLFSSL_X509* x509, WOLFSSL_ASN1_INTEGER* s) int wolfSSL_X509_set_pubkey(WOLFSSL_X509 *cert, WOLFSSL_EVP_PKEY *pkey) { byte* p = NULL; + int derSz; WOLFSSL_ENTER("wolfSSL_X509_set_pubkey"); if (cert == NULL || pkey == NULL) return WOLFSSL_FAILURE; - if (pkey->type == EVP_PKEY_RSA -#ifndef NO_DSA - || pkey->type == EVP_PKEY_DSA -#endif /* !NO_DSA */ - ) { - p = (byte*)XMALLOC(pkey->pkey_sz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); - if (p == NULL) - return WOLFSSL_FAILURE; + /* Regenerate since pkey->pkey.ptr may contain private key */ + switch (pkey->type) { +#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA) + case EVP_PKEY_RSA: + { + RsaKey* rsa; - if (cert->pubKey.buffer != NULL) - XFREE(cert->pubKey.buffer, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); - cert->pubKey.buffer = p; - XMEMCPY(cert->pubKey.buffer, pkey->pkey.ptr, pkey->pkey_sz); - cert->pubKey.length = pkey->pkey_sz; -#ifndef NO_DSA - if (pkey->type == EVP_PKEY_DSA) - cert->pubKeyOID = DSAk; - else -#endif /* !NO_DSA */ + if (pkey->rsa == NULL || pkey->rsa->internal == NULL) + return WOLFSSL_FAILURE; + + rsa = (RsaKey*)pkey->rsa->internal; + derSz = wc_RsaPublicKeyDerSize(rsa, 1); + if (derSz <= 0) + return WOLFSSL_FAILURE; + + p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); + if (p == NULL) + return WOLFSSL_FAILURE; + + if ((derSz = wc_RsaKeyToPublicDer(rsa, p, derSz)) <= 0) { + XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); + return WOLFSSL_FAILURE; + } cert->pubKeyOID = RSAk; - } -#ifdef HAVE_ECC - else if (pkey->type == EVP_PKEY_EC) { - /* Generate since pkey->pkey.ptr may contain private key */ - ecc_key* ecc; - int derSz; - - if (pkey->ecc == NULL || pkey->ecc->internal == NULL) - return WOLFSSL_FAILURE; - - ecc = (ecc_key*)pkey->ecc->internal; - derSz = wc_EccPublicKeyDerSize(ecc, 1); - if (derSz <= 0) - return WOLFSSL_FAILURE; - - p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); - if (p == NULL) - return WOLFSSL_FAILURE; - - if ((derSz = wc_EccPublicKeyToDer(ecc, p, derSz, 1)) <= 0) { - XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); - return WOLFSSL_FAILURE; } - cert->pubKey.buffer = p; - cert->pubKey.length = derSz; - cert->pubKeyOID = ECDSAk; - } -#endif /* HAVE_ECC */ - else + break; +#endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !NO_RSA */ +#if !defined(HAVE_SELFTEST) && (defined(WOLFSSL_KEY_GEN) || \ + defined(WOLFSSL_CERT_GEN)) && !defined(NO_DSA) + case EVP_PKEY_DSA: + { + DsaKey* dsa; + + if (pkey->dsa == NULL || pkey->dsa->internal == NULL) + return WOLFSSL_FAILURE; + + dsa = (DsaKey*)pkey->dsa->internal; + /* size of pub, priv, p, q, g + ASN.1 additional information */ + derSz = 5 * mp_unsigned_bin_size(&dsa->g) + MAX_ALGO_SZ; + p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); + if (p == NULL) + return WOLFSSL_FAILURE; + + if ((derSz = wc_DsaKeyToPublicDer(dsa, p, derSz)) <= 0) { + XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); + return WOLFSSL_FAILURE; + } + cert->pubKeyOID = RSAk; + } + break; +#endif /* !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) && !NO_DSA */ +#ifdef HAVE_ECC + case EVP_PKEY_EC: + { + ecc_key* ecc; + + if (pkey->ecc == NULL || pkey->ecc->internal == NULL) + return WOLFSSL_FAILURE; + + ecc = (ecc_key*)pkey->ecc->internal; + derSz = wc_EccPublicKeyDerSize(ecc, 1); + if (derSz <= 0) + return WOLFSSL_FAILURE; + + p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); + if (p == NULL) + return WOLFSSL_FAILURE; + + if ((derSz = wc_EccPublicKeyToDer(ecc, p, derSz, 1)) <= 0) { + XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); + return WOLFSSL_FAILURE; + } + cert->pubKeyOID = ECDSAk; + } + break; +#endif + default: return WOLFSSL_FAILURE; + } + cert->pubKey.buffer = p; + cert->pubKey.length = derSz; return WOLFSSL_SUCCESS; } diff --git a/src/tls.c b/src/tls.c index b631afd57..60fcc7a48 100644 --- a/src/tls.c +++ b/src/tls.c @@ -1,6 +1,6 @@ /* tls.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -778,6 +778,9 @@ static int Hmac_HashUpdate(Hmac* hmac, const byte* data, word32 sz) ret = wc_Sha512Update(&hmac->hash.sha512, data, sz); break; #endif /* WOLFSSL_SHA512 */ + + default: + break; } return ret; @@ -817,6 +820,9 @@ static int Hmac_HashFinalRaw(Hmac* hmac, unsigned char* hash) ret = wc_Sha512FinalRaw(&hmac->hash.sha512, hash); break; #endif /* WOLFSSL_SHA512 */ + + default: + break; } return ret; @@ -866,16 +872,17 @@ static int Hmac_OuterHash(Hmac* hmac, unsigned char* mac) static int Hmac_UpdateFinal_CT(Hmac* hmac, byte* digest, const byte* in, word32 sz, byte* header) { - byte lenBytes[8]; - int i, j, k; - int blockBits, blockMask; - int lastBlockLen, macLen, extraLen, eocIndex; - int blocks, safeBlocks, lenBlock, eocBlock; - int maxLen; - int blockSz, padSz; - int ret; - word32 realLen; - byte extraBlock; + byte lenBytes[8]; + int i, j; + unsigned int k; + int blockBits, blockMask; + int lastBlockLen, macLen, extraLen, eocIndex; + int blocks, safeBlocks, lenBlock, eocBlock; + unsigned int maxLen; + int blockSz, padSz; + int ret; + word32 realLen; + byte extraBlock; switch (hmac->macType) { #ifndef NO_SHA @@ -972,7 +979,7 @@ static int Hmac_UpdateFinal_CT(Hmac* hmac, byte* digest, const byte* in, unsigned char isEocBlock = ctMaskEq(i, eocBlock); unsigned char isOutBlock = ctMaskEq(i, lenBlock); - for (j = 0; j < blockSz; j++, k++) { + for (j = 0; j < blockSz; j++) { unsigned char atEoc = ctMaskEq(j, eocIndex) & isEocBlock; unsigned char pastEoc = ctMaskGT(j, eocIndex) & isEocBlock; unsigned char b = 0; @@ -981,6 +988,7 @@ static int Hmac_UpdateFinal_CT(Hmac* hmac, byte* digest, const byte* in, b = header[k]; else if (k < maxLen) b = in[k - WOLFSSL_TLS_HMAC_INNER_SZ]; + k++; b = ctMaskSel(atEoc, 0x80, b); b &= (unsigned char)~(word32)pastEoc; @@ -1095,7 +1103,7 @@ static int Hmac_UpdateFinal(Hmac* hmac, byte* digest, const byte* in, blocks += ((maxSz + padSz) % blockSz) < padSz; msgBlocks = realSz >> blockBits; /* #Extra blocks to process. */ - blocks -= msgBlocks + (((realSz + padSz) % blockSz) < padSz); + blocks -= (msgBlocks + (((realSz + padSz) % blockSz) < padSz)) ? 1 : 0; /* Calculate whole blocks. */ msgBlocks--; @@ -1306,7 +1314,7 @@ static WC_INLINE word16 TLSX_ToSemaphore(word16 type) ((semaphore)[(light) / 8] &= (byte) ~(0x01 << ((light) % 8))) /** Creates a new extension. */ -static TLSX* TLSX_New(TLSX_Type type, void* data, void* heap) +static TLSX* TLSX_New(TLSX_Type type, const void* data, void* heap) { TLSX* extension = (TLSX*)XMALLOC(sizeof(TLSX), heap, DYNAMIC_TYPE_TLSX); @@ -1314,7 +1322,7 @@ static TLSX* TLSX_New(TLSX_Type type, void* data, void* heap) if (extension) { extension->type = type; - extension->data = data; + extension->data = (void*)data; extension->resp = 0; extension->next = NULL; } @@ -1326,7 +1334,7 @@ static TLSX* TLSX_New(TLSX_Type type, void* data, void* heap) * Creates a new extension and pushes it to the provided list. * Checks for duplicate extensions, keeps the newest. */ -static int TLSX_Push(TLSX** list, TLSX_Type type, void* data, void* heap) +static int TLSX_Push(TLSX** list, TLSX_Type type, const void* data, void* heap) { TLSX* extension = TLSX_New(type, data, heap); @@ -1592,7 +1600,7 @@ static int TLSX_SetALPN(TLSX** extensions, const void* data, word16 size, /** Parses a buffer of ALPN extensions and set the first one matching * client and server requirements */ -static int TLSX_ALPN_ParseAndSet(WOLFSSL *ssl, byte *input, word16 length, +static int TLSX_ALPN_ParseAndSet(WOLFSSL *ssl, const byte *input, word16 length, byte isRequest) { word16 size = 0, offset = 0, idx = 0; @@ -1973,8 +1981,8 @@ byte TLSX_SNI_Status(TLSX* extensions, byte type) } /** Parses a buffer of SNI extensions. */ -static int TLSX_SNI_Parse(WOLFSSL* ssl, byte* input, word16 length, - byte isRequest) +static int TLSX_SNI_Parse(WOLFSSL* ssl, const byte* input, word16 length, + byte isRequest) { #ifndef NO_WOLFSSL_SERVER word16 size = 0; @@ -2744,8 +2752,8 @@ static word16 TLSX_MFL_Write(byte* data, byte* output) return ENUM_LEN; } -static int TLSX_MFL_Parse(WOLFSSL* ssl, byte* input, word16 length, - byte isRequest) +static int TLSX_MFL_Parse(WOLFSSL* ssl, const byte* input, word16 length, + byte isRequest) { if (length != ENUM_LEN) return BUFFER_ERROR; @@ -2830,8 +2838,8 @@ int TLSX_UseMaxFragment(TLSX** extensions, byte mfl, void* heap) #ifdef HAVE_TRUNCATED_HMAC -static int TLSX_THM_Parse(WOLFSSL* ssl, byte* input, word16 length, - byte isRequest) +static int TLSX_THM_Parse(WOLFSSL* ssl, const byte* input, word16 length, + byte isRequest) { if (length != 0 || input == NULL) return BUFFER_ERROR; @@ -2976,8 +2984,8 @@ static word16 TLSX_CSR_Write(CertificateStatusRequest* csr, byte* output, return 0; } -static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length, - byte isRequest) +static int TLSX_CSR_Parse(WOLFSSL* ssl, const byte* input, word16 length, + byte isRequest) { int ret; #if !defined(NO_WOLFSSL_SERVER) @@ -3066,7 +3074,7 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length, ret = BUFFER_ERROR; } if (ret == 0) { - csr->response.buffer = input + offset; + csr->response.buffer = (byte*)(input + offset); csr->response.length = resp_length; } @@ -3423,8 +3431,8 @@ static word16 TLSX_CSR2_Write(CertificateStatusRequestItemV2* csr2, return 0; } -static int TLSX_CSR2_Parse(WOLFSSL* ssl, byte* input, word16 length, - byte isRequest) +static int TLSX_CSR2_Parse(WOLFSSL* ssl, const byte* input, word16 length, + byte isRequest) { int ret; @@ -3868,51 +3876,68 @@ static int TLSX_PointFormat_Append(PointFormat* list, byte format, void* heap) #if defined(WOLFSSL_TLS13) || !defined(NO_WOLFSSL_CLIENT) +#if defined(HAVE_FFDHE) && (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448)) +static void TLSX_SupportedCurve_ValidateRequest(const WOLFSSL* ssl, + const byte* semaphore) +{ + /* If all pre-defined parameter types for key exchange are supported then + * always send SupportedGroups extension. + */ + (void)ssl; + (void)semaphore; +} +#else static void TLSX_SupportedCurve_ValidateRequest(WOLFSSL* ssl, byte* semaphore) { word16 i; - for (i = 0; i < ssl->suites->suiteSz; i+= 2) { + for (i = 0; i < ssl->suites->suiteSz; i += 2) { if (ssl->suites->suites[i] == TLS13_BYTE) return; - if (ssl->suites->suites[i] == ECC_BYTE || - ssl->suites->suites[i] == CHACHA_BYTE) { + if ((ssl->suites->suites[i] == ECC_BYTE) || + (ssl->suites->suites[i] == CHACHA_BYTE)) { #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ defined(HAVE_CURVE448) return; #endif } - else { #ifdef HAVE_FFDHE + else { return; - #endif } + #endif } /* turns semaphore on to avoid sending this extension. */ TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_GROUPS)); } +#endif +/* Only send PointFormats if TLSv13, ECC or CHACHA cipher suite present. + */ static void TLSX_PointFormat_ValidateRequest(WOLFSSL* ssl, byte* semaphore) { word16 i; - for (i = 0; i < ssl->suites->suiteSz; i+= 2) { + for (i = 0; i < ssl->suites->suiteSz; i += 2) { if (ssl->suites->suites[i] == TLS13_BYTE) return; - if (ssl->suites->suites[i] == ECC_BYTE || - ssl->suites->suites[i] == CHACHA_BYTE) { + if ((ssl->suites->suites[i] == ECC_BYTE) || + (ssl->suites->suites[i] == CHACHA_BYTE)) { #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ defined(HAVE_CURVE448) return; #endif } } - #ifdef HAVE_FFDHE - return; - #endif - /* turns semaphore on to avoid sending this extension. */ - TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS)); +#ifdef HAVE_FFDHE + (void)semaphore; + return; +#else + /* turns semaphore on to avoid sending this extension. */ + TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS)); +#endif } #endif /* WOLFSSL_TLS13 || !NO_WOLFSSL_CLIENT */ @@ -3928,23 +3953,15 @@ static void TLSX_PointFormat_ValidateResponse(WOLFSSL* ssl, byte* semaphore) if (ssl->options.cipherSuite0 == TLS13_BYTE) return; +#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) if (ssl->options.cipherSuite0 == ECC_BYTE || ssl->options.cipherSuite0 == CHACHA_BYTE) { -#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) return; -#endif } - else { -#ifdef HAVE_FFDHE - return; #endif - } -#if !defined(HAVE_FFDHE) || (!defined(HAVE_ECC) && !defined(HAVE_CURVE25519) \ - && !defined(HAVE_CURVE448)) /* turns semaphore on to avoid sending this extension. */ TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS)); -#endif } #endif /* !NO_WOLFSSL_SERVER */ @@ -4015,8 +4032,8 @@ static word16 TLSX_PointFormat_Write(PointFormat* list, byte* output) #if !defined(NO_WOLFSSL_SERVER) || (defined(WOLFSSL_TLS13) && \ !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)) -static int TLSX_SupportedCurve_Parse(WOLFSSL* ssl, byte* input, word16 length, - byte isRequest) +static int TLSX_SupportedCurve_Parse(WOLFSSL* ssl, const byte* input, + word16 length, byte isRequest) { word16 offset; word16 name; @@ -4229,6 +4246,8 @@ int TLSX_SupportedFFDHE_Set(WOLFSSL* ssl) params = wc_Dh_ffdhe8192_Get(); break; #endif + default: + break; } if (params == NULL) return BAD_FUNC_ARG; @@ -4293,8 +4312,8 @@ int TLSX_SupportedCurve_Preferred(WOLFSSL* ssl, int checkSupported) #ifndef NO_WOLFSSL_SERVER -static int TLSX_PointFormat_Parse(WOLFSSL* ssl, byte* input, word16 length, - byte isRequest) +static int TLSX_PointFormat_Parse(WOLFSSL* ssl, const byte* input, + word16 length, byte isRequest) { int ret; @@ -4845,8 +4864,8 @@ static word16 TLSX_SecureRenegotiation_Write(SecureRenegotiation* data, return offset; } -static int TLSX_SecureRenegotiation_Parse(WOLFSSL* ssl, byte* input, - word16 length, byte isRequest) +static int TLSX_SecureRenegotiation_Parse(WOLFSSL* ssl, const byte* input, + word16 length, byte isRequest) { int ret = SECURE_RENEGOTIATION_E; @@ -4860,6 +4879,8 @@ static int TLSX_SecureRenegotiation_Parse(WOLFSSL* ssl, byte* input, } if (ret != 0 && ret != SECURE_RENEGOTIATION_E) { } + else if (ssl->secure_renegotiation == NULL) { + } else if (!ssl->secure_renegotiation->enabled) { if (*input == 0) { input++; /* get past size */ @@ -5023,7 +5044,7 @@ static word16 TLSX_SessionTicket_GetSize(SessionTicket* ticket, int isRequest) } static word16 TLSX_SessionTicket_Write(SessionTicket* ticket, byte* output, - int isRequest) + int isRequest) { word16 offset = 0; /* empty ticket */ @@ -5036,8 +5057,8 @@ static word16 TLSX_SessionTicket_Write(SessionTicket* ticket, byte* output, } -static int TLSX_SessionTicket_Parse(WOLFSSL* ssl, byte* input, word16 length, - byte isRequest) +static int TLSX_SessionTicket_Parse(WOLFSSL* ssl, const byte* input, + word16 length, byte isRequest) { int ret = 0; @@ -5247,7 +5268,7 @@ static void TLSX_QSH_ValidateRequest(WOLFSSL* ssl, byte* semaphore) { int i; - for (i = 0; i < ssl->suites->suiteSz; i+= 2) + for (i = 0; i < ssl->suites->suiteSz; i += 2) if (ssl->suites->suites[i] == QSH_BYTE) return; @@ -5398,8 +5419,8 @@ static void TLSX_QSHAgreement(TLSX** extensions, void* heap) length length of total extension found isRequest set to 1 if being sent to the server */ -static int TLSX_QSH_Parse(WOLFSSL* ssl, byte* input, word16 length, - byte isRequest) +static int TLSX_QSH_Parse(WOLFSSL* ssl, const byte* input, word16 length, + byte isRequest) { byte numKeys = 0; word16 offset = 0; @@ -5564,7 +5585,7 @@ static int TLSX_QSH_Parse(WOLFSSL* ssl, byte* input, word16 length, /* Used for parsing in QSHCipher structs on Key Exchange */ int TLSX_QSHCipher_Parse(WOLFSSL* ssl, const byte* input, word16 length, - byte isServer) + byte isServer) { QSHKey* key; word16 Max_Secret_Len = 48; @@ -5578,6 +5599,9 @@ int TLSX_QSHCipher_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte buff[145]; /* size enough for 3 secrets */ buffer* buf; + if (offset_len + OPAQUE24_LEN > length) + return BUFFER_ERROR; + /* pointer to location where secret should be stored */ if (isServer) { buf = ssl->QSH_secret->CliSi; @@ -5846,8 +5870,8 @@ static int TLSX_EncryptThenMac_Write(void* data, byte* output, byte msgType, * MEMORY_E when unable to allocate memory and * 0 otherwise. */ -static int TLSX_EncryptThenMac_Parse(WOLFSSL* ssl, byte* input, word16 length, - byte msgType) +static int TLSX_EncryptThenMac_Parse(WOLFSSL* ssl, const byte* input, + word16 length, byte msgType) { int ret; @@ -6068,7 +6092,7 @@ static int TLSX_SupportedVersions_Write(void* data, byte* output, * msgType The type of the message this extension is being parsed from. * returns 0 on success, otherwise failure. */ -static int TLSX_SupportedVersions_Parse(WOLFSSL* ssl, byte* input, +static int TLSX_SupportedVersions_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType) { ProtocolVersion pv = ssl->ctx->method->version; @@ -6212,7 +6236,7 @@ static int TLSX_SetSupportedVersions(TLSX** extensions, const void* data, if (extensions == NULL || data == NULL) return BAD_FUNC_ARG; - return TLSX_Push(extensions, TLSX_SUPPORTED_VERSIONS, (void *)data, heap); + return TLSX_Push(extensions, TLSX_SUPPORTED_VERSIONS, data, heap); } #define SV_GET_SIZE TLSX_SupportedVersions_GetSize @@ -6294,8 +6318,8 @@ static int TLSX_Cookie_Write(Cookie* cookie, byte* output, byte msgType, * msgType The type of the message this extension is being parsed from. * returns 0 on success and other values indicate failure. */ -static int TLSX_Cookie_Parse(WOLFSSL* ssl, byte* input, word16 length, - byte msgType) +static int TLSX_Cookie_Parse(WOLFSSL* ssl, const byte* input, word16 length, + byte msgType) { word16 len; word16 idx = 0; @@ -6343,7 +6367,7 @@ static int TLSX_Cookie_Parse(WOLFSSL* ssl, byte* input, word16 length, * resp Indicates the extension will go into a response (HelloRetryRequest). * returns 0 on success and other values indicate failure. */ -int TLSX_Cookie_Use(WOLFSSL* ssl, byte* data, word16 len, byte* mac, +int TLSX_Cookie_Use(WOLFSSL* ssl, const byte* data, word16 len, byte* mac, byte macSz, int resp) { int ret = 0; @@ -6424,8 +6448,8 @@ static word16 TLSX_SignatureAlgorithms_GetSize(void* data) * length The length of the list in bytes. * returns 0 on success, BUFFER_ERROR when the length is not even. */ -static int TLSX_SignatureAlgorithms_MapPss(WOLFSSL *ssl, byte* input, - word16 length) +static int TLSX_SignatureAlgorithms_MapPss(WOLFSSL *ssl, const byte* input, + word16 length) { word16 i; @@ -6474,7 +6498,7 @@ static word16 TLSX_SignatureAlgorithms_Write(void* data, byte* output) * length The length of the extension data. * returns 0 on success, otherwise failure. */ -static int TLSX_SignatureAlgorithms_Parse(WOLFSSL *ssl, byte* input, +static int TLSX_SignatureAlgorithms_Parse(WOLFSSL *ssl, const byte* input, word16 length, byte isRequest, Suites* suites) { word16 len; @@ -6521,7 +6545,7 @@ static int TLSX_SetSignatureAlgorithms(TLSX** extensions, const void* data, if (extensions == NULL) return BAD_FUNC_ARG; - return TLSX_Push(extensions, TLSX_SIGNATURE_ALGORITHMS, (void *)data, heap); + return TLSX_Push(extensions, TLSX_SIGNATURE_ALGORITHMS, data, heap); } #define SA_GET_SIZE TLSX_SignatureAlgorithms_GetSize @@ -6569,7 +6593,7 @@ static word16 TLSX_SignatureAlgorithmsCert_Write(void* data, byte* output) * length The length of the extension data. * returns 0 on success, otherwise failure. */ -static int TLSX_SignatureAlgorithmsCert_Parse(WOLFSSL *ssl, byte* input, +static int TLSX_SignatureAlgorithmsCert_Parse(WOLFSSL *ssl, const byte* input, word16 length, byte isRequest) { word16 len; @@ -6607,13 +6631,12 @@ static int TLSX_SignatureAlgorithmsCert_Parse(WOLFSSL *ssl, byte* input, * returns 0 on success, otherwise failure. */ static int TLSX_SetSignatureAlgorithmsCert(TLSX** extensions, const void* data, - void* heap) + void* heap) { if (extensions == NULL) return BAD_FUNC_ARG; - return TLSX_Push(extensions, TLSX_SIGNATURE_ALGORITHMS_CERT, (void *)data, - heap); + return TLSX_Push(extensions, TLSX_SIGNATURE_ALGORITHMS_CERT, data, heap); } #define SAC_GET_SIZE TLSX_SignatureAlgorithmsCert_GetSize @@ -6715,9 +6738,8 @@ static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse) } /* Set key */ - ret = wc_DhSetKey(dhKey, - (byte*)params->p, params->p_len, - (byte*)params->g, params->g_len); + ret = wc_DhSetKey(dhKey, params->p, params->p_len, params->g, + params->g_len); if (ret != 0) goto end; @@ -7150,7 +7172,7 @@ static word16 TLSX_KeyShare_GetSize(KeyShareEntry* list, byte msgType) if (!isRequest && current->key == NULL) continue; - len += KE_GROUP_LEN + OPAQUE16_LEN + current->pubKeyLen; + len += (word16)(KE_GROUP_LEN + OPAQUE16_LEN + current->pubKeyLen); } return len; @@ -7268,7 +7290,7 @@ static int TLSX_KeyShare_ProcessDh(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) } /* Set key */ - ret = wc_DhSetKey(dhKey, (byte*)params->p, params->p_len, (byte*)params->g, + ret = wc_DhSetKey(dhKey, params->p, params->p_len, params->g, params->g_len); if (ret != 0) { wc_FreeDhKey(dhKey); @@ -7309,7 +7331,7 @@ static int TLSX_KeyShare_ProcessDh(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) ssl->arrays->preMasterSz = params->p_len; } - ssl->options.dhKeySz = params->p_len; + ssl->options.dhKeySz = (word16)params->p_len; wc_FreeDhKey(dhKey); #ifdef WOLFSSL_SMALL_STACK @@ -7643,8 +7665,8 @@ static int TLSX_KeyShare_Process(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) * returns a positive number to indicate amount of data parsed and a negative * number on error. */ -static int TLSX_KeyShareEntry_Parse(WOLFSSL* ssl, byte* input, word16 length, - KeyShareEntry **kse) +static int TLSX_KeyShareEntry_Parse(WOLFSSL* ssl, const byte* input, + word16 length, KeyShareEntry **kse) { int ret; word16 group; @@ -7753,7 +7775,7 @@ static int TLSX_SupportedGroups_Find(WOLFSSL* ssl, word16 name) * msgType The type of the message this extension is being parsed from. * returns 0 on success and other values indicate failure. */ -static int TLSX_KeyShare_Parse(WOLFSSL* ssl, byte* input, word16 length, +static int TLSX_KeyShare_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType) { int ret; @@ -7784,8 +7806,9 @@ static int TLSX_KeyShare_Parse(WOLFSSL* ssl, byte* input, word16 length, offset += OPAQUE16_LEN; while (offset < (int)length) { - ret = TLSX_KeyShareEntry_Parse(ssl, &input[offset], length - offset, - &keyShareEntry); + ret = TLSX_KeyShareEntry_Parse(ssl, &input[offset], + length - (word16)offset, + &keyShareEntry); if (ret < 0) return ret; @@ -8349,7 +8372,7 @@ static int TLSX_PreSharedKey_GetSize(PreSharedKey* list, byte msgType, while (list != NULL) { /* Each entry has: identity, ticket age and binder. */ len += OPAQUE16_LEN + list->identityLen + OPAQUE32_LEN + - OPAQUE8_LEN + list->binderLen; + OPAQUE8_LEN + (word16)list->binderLen; list = list->next; } *pSz += len; @@ -8382,7 +8405,7 @@ int TLSX_PreSharedKey_GetSizeBinders(PreSharedKey* list, byte msgType, /* Length of all binders. */ len = OPAQUE16_LEN; while (list != NULL) { - len += OPAQUE8_LEN + list->binderLen; + len += OPAQUE8_LEN + (word16)list->binderLen; list = list->next; } @@ -8414,10 +8437,10 @@ int TLSX_PreSharedKey_WriteBinders(PreSharedKey* list, byte* output, idx += OPAQUE16_LEN; while (current != NULL) { /* Binder data length. */ - output[idx++] = current->binderLen; + output[idx++] = (byte)current->binderLen; /* Binder data. */ XMEMCPY(output + idx, current->binder, current->binderLen); - idx += current->binderLen; + idx += (word16)current->binderLen; current = current->next; } @@ -8508,8 +8531,8 @@ static int TLSX_PreSharedKey_Write(PreSharedKey* list, byte* output, * msgType The type of the message this extension is being parsed from. * returns 0 on success and other values indicate failure. */ -static int TLSX_PreSharedKey_Parse(WOLFSSL* ssl, byte* input, word16 length, - byte msgType) +static int TLSX_PreSharedKey_Parse(WOLFSSL* ssl, const byte* input, + word16 length, byte msgType) { TLSX* extension; PreSharedKey* list; @@ -8533,9 +8556,9 @@ static int TLSX_PreSharedKey_Parse(WOLFSSL* ssl, byte* input, word16 length, /* Create a pre-shared key object for each identity. */ while (len > 0) { - byte* identity; - word16 identityLen; - word32 age; + const byte* identity; + word16 identityLen; + word32 age; if (len < OPAQUE16_LEN) return BUFFER_E; @@ -8588,10 +8611,10 @@ static int TLSX_PreSharedKey_Parse(WOLFSSL* ssl, byte* input, word16 length, /* Copy binder into static buffer. */ XMEMCPY(list->binder, input + idx, list->binderLen); - idx += list->binderLen; + idx += (word16)list->binderLen; /* Done with binder entry. */ - len -= OPAQUE8_LEN + list->binderLen; + len -= OPAQUE8_LEN + (word16)list->binderLen; /* Next identity. */ list = list->next; @@ -8654,7 +8677,7 @@ static int TLSX_PreSharedKey_Parse(WOLFSSL* ssl, byte* input, word16 length, * preSharedKey The new pre-shared key object. * returns 0 on success and other values indicate failure. */ -static int TLSX_PreSharedKey_New(PreSharedKey** list, byte* identity, +static int TLSX_PreSharedKey_New(PreSharedKey** list, const byte* identity, word16 len, void *heap, PreSharedKey** preSharedKey) { @@ -8721,8 +8744,8 @@ static WC_INLINE byte GetHmacLength(int hmac) * preSharedKey The new pre-shared key object. * returns 0 on success and other values indicate failure. */ -int TLSX_PreSharedKey_Use(WOLFSSL* ssl, byte* identity, word16 len, word32 age, - byte hmac, byte cipherSuite0, +int TLSX_PreSharedKey_Use(WOLFSSL* ssl, const byte* identity, word16 len, + word32 age, byte hmac, byte cipherSuite0, byte cipherSuite, byte resumption, PreSharedKey **preSharedKey) { @@ -8832,7 +8855,7 @@ static int TLSX_PskKeModes_Write(byte modes, byte* output, byte msgType, { if (msgType == client_hello) { /* Format: Len | Modes* */ - int idx = OPAQUE8_LEN; + word16 idx = OPAQUE8_LEN; /* Write out each possible mode. */ if (modes & (1 << PSK_KE)) @@ -8840,7 +8863,7 @@ static int TLSX_PskKeModes_Write(byte modes, byte* output, byte msgType, if (modes & (1 << PSK_DHE_KE)) output[idx++] = PSK_DHE_KE; /* Write out length of mode list. */ - output[0] = idx - OPAQUE8_LEN; + output[0] = (byte)(idx - OPAQUE8_LEN); *pSz += idx; return 0; @@ -8858,7 +8881,7 @@ static int TLSX_PskKeModes_Write(byte modes, byte* output, byte msgType, * msgType The type of the message this extension is being parsed from. * returns 0 on success and other values indicate failure. */ -static int TLSX_PskKeModes_Parse(WOLFSSL* ssl, byte* input, word16 length, +static int TLSX_PskKeModes_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType) { int ret; @@ -8991,8 +9014,8 @@ static int TLSX_PostHandAuth_Write(byte* output, byte msgType, word16* pSz) * msgType The type of the message this extension is being parsed from. * returns 0 on success and other values indicate failure. */ -static int TLSX_PostHandAuth_Parse(WOLFSSL* ssl, byte* input, word16 length, - byte msgType) +static int TLSX_PostHandAuth_Parse(WOLFSSL* ssl, const byte* input, + word16 length, byte msgType) { (void)input; @@ -9100,7 +9123,7 @@ static int TLSX_EarlyData_Write(word32 maxSz, byte* output, byte msgType, * msgType The type of the message this extension is being parsed from. * returns 0 on success and other values indicate failure. */ -static int TLSX_EarlyData_Parse(WOLFSSL* ssl, byte* input, word16 length, +static int TLSX_EarlyData_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType) { if (msgType == client_hello) { @@ -9333,6 +9356,9 @@ void TLSX_FreeAll(TLSX* list, void* heap) KS_FREE_ALL((KeyShareEntry*)extension->data, heap); break; #endif + + default: + break; } XFREE(extension, heap, DYNAMIC_TYPE_TLSX); @@ -9459,7 +9485,7 @@ static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType, break; case TLSX_PSK_KEY_EXCHANGE_MODES: - ret = PKM_GET_SIZE(extension->val, msgType, &length); + ret = PKM_GET_SIZE((byte)extension->val, msgType, &length); break; #endif @@ -9485,6 +9511,8 @@ static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType, length += KS_GET_SIZE((KeyShareEntry*)extension->data, msgType); break; #endif + default: + break; } /* marks the extension as processed so ctx level */ @@ -9642,7 +9670,7 @@ static int TLSX_Write(TLSX* list, byte* output, byte* semaphore, case TLSX_PSK_KEY_EXCHANGE_MODES: WOLFSSL_MSG("PSK Key Exchange Modes extension to write"); - ret = PKM_WRITE(extension->val, output + offset, msgType, + ret = PKM_WRITE((byte)extension->val, output + offset, msgType, &offset); break; #endif @@ -9675,6 +9703,8 @@ static int TLSX_Write(TLSX* list, byte* output, byte* semaphore, output + offset, msgType); break; #endif + default: + break; } /* writes extension data length. */ @@ -10886,6 +10916,9 @@ int TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType, word16* pOffset break; #endif #endif + + default: + break; } offset += OPAQUE16_LEN; /* extensions length */ @@ -10930,8 +10963,8 @@ int TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType, word16* pOffset #endif /* WOLFSSL_TLS13 || !NO_WOLFSSL_SERVER */ #ifdef WOLFSSL_TLS13 -int TLSX_ParseVersion(WOLFSSL* ssl, byte* input, word16 length, byte msgType, - int* found) +int TLSX_ParseVersion(WOLFSSL* ssl, const byte* input, word16 length, + byte msgType, int* found) { int ret = 0; int offset = 0; @@ -10974,7 +11007,7 @@ int TLSX_ParseVersion(WOLFSSL* ssl, byte* input, word16 length, byte msgType, #endif /** Parses a buffer of TLS extensions. */ -int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, +int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType, Suites *suites) { int ret = 0; diff --git a/src/tls13.c b/src/tls13.c index adf63c78d..25de3907d 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -1,6 +1,6 @@ /* tls13.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -84,6 +84,11 @@ #include #endif +#if defined(__MACH__) || defined(__FreeBSD__) +#include +#endif /* __MACH__ || __FreeBSD__ */ + + #include #include #include @@ -174,6 +179,9 @@ static int Tls13_HKDF_Extract(byte* prk, const byte* salt, int saltLen, len = WC_SHA512_DIGEST_SIZE; break; #endif + + default: + break; } /* When length is 0 then use zeroed data of digest length. */ @@ -385,32 +393,35 @@ static int DeriveKey(WOLFSSL* ssl, byte* output, int outputLen, int digestAlg = 0; switch (hashAlgo) { - #ifndef NO_SHA256 - case sha256_mac: - hashSz = WC_SHA256_DIGEST_SIZE; - digestAlg = WC_SHA256; - if (includeMsgs) - ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256, hash); + #ifndef NO_SHA256 + case sha256_mac: + hashSz = WC_SHA256_DIGEST_SIZE; + digestAlg = WC_SHA256; + if (includeMsgs) + ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256, hash); break; - #endif + #endif - #ifdef WOLFSSL_SHA384 - case sha384_mac: - hashSz = WC_SHA384_DIGEST_SIZE; - digestAlg = WC_SHA384; - if (includeMsgs) - ret = wc_Sha384GetHash(&ssl->hsHashes->hashSha384, hash); + #ifdef WOLFSSL_SHA384 + case sha384_mac: + hashSz = WC_SHA384_DIGEST_SIZE; + digestAlg = WC_SHA384; + if (includeMsgs) + ret = wc_Sha384GetHash(&ssl->hsHashes->hashSha384, hash); break; - #endif + #endif - #ifdef WOLFSSL_TLS13_SHA512 - case sha512_mac: - hashSz = WC_SHA512_DIGEST_SIZE; - digestAlg = WC_SHA512; - if (includeMsgs) - ret = wc_Sha512GetHash(&ssl->hsHashes->hashSha512, hash); + #ifdef WOLFSSL_TLS13_SHA512 + case sha512_mac: + hashSz = WC_SHA512_DIGEST_SIZE; + digestAlg = WC_SHA512; + if (includeMsgs) + ret = wc_Sha512GetHash(&ssl->hsHashes->hashSha512, hash); + break; + #endif + + default: break; - #endif } if (ret != 0) return ret; @@ -1071,6 +1082,8 @@ static int BuildTls13HandshakeHmac(WOLFSSL* ssl, byte* key, byte* hash, ret = wc_Sha512GetHash(&ssl->hsHashes->hashSha512, hash); break; #endif /* WOLFSSL_TLS13_SHA512 */ + default: + break; } if (ret != 0) return ret; @@ -1195,6 +1208,9 @@ int DeriveTls13Keys(WOLFSSL* ssl, int secret, int side, int store) goto end; } break; + + default: + break; } if (!store) @@ -1725,8 +1741,8 @@ static int ChaCha20Poly1305_Encrypt(WOLFSSL* ssl, byte* output, if (ret != 0) return ret; /* Add authentication code of encrypted data to end. */ - ret = wc_Poly1305_MAC(ssl->auth.poly1305, (byte*)aad, aadSz, output, sz, - tag, POLY1305_AUTH_SZ); + ret = wc_Poly1305_MAC(ssl->auth.poly1305, aad, aadSz, output, sz, tag, + POLY1305_AUTH_SZ); return ret; } @@ -1950,6 +1966,9 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input, break; } + + default: + break; } /* Reset state */ @@ -2002,8 +2021,8 @@ static int ChaCha20Poly1305_Decrypt(WOLFSSL* ssl, byte* output, if (ret != 0) return ret; /* Generate authentication tag for encrypted data. */ - if ((ret = wc_Poly1305_MAC(ssl->auth.poly1305, (byte*)aad, aadSz, - (byte*)input, sz, tag, sizeof(tag))) != 0) { + if ((ret = wc_Poly1305_MAC(ssl->auth.poly1305, aad, aadSz, input, sz, tag, + sizeof(tag))) != 0) { return ret; } @@ -2233,6 +2252,9 @@ int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, word16 sz, break; } + + default: + break; } #ifndef WOLFSSL_EARLY_DATA @@ -2402,6 +2424,9 @@ int BuildTls13Message(WOLFSSL* ssl, byte* output, int outSz, const byte* input, } break; } + + default: + break; } exit_buildmsg: @@ -3074,8 +3099,8 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, return BUFFER_ERROR; /* Need to negotiate version first. */ - if ((ret = TLSX_ParseVersion(ssl, (byte*)input + i, totalExtSz, - *extMsgType, &foundVersion))) { + if ((ret = TLSX_ParseVersion(ssl, input + i, totalExtSz, *extMsgType, + &foundVersion))) { return ret; } if (!foundVersion) { @@ -3091,8 +3116,7 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } /* Parse and handle extensions. */ - ret = TLSX_Parse(ssl, (byte *) input + i, totalExtSz, *extMsgType, - NULL); + ret = TLSX_Parse(ssl, input + i, totalExtSz, *extMsgType, NULL); if (ret != 0) return ret; @@ -3252,9 +3276,10 @@ static int DoTls13EncryptedExtensions(WOLFSSL* ssl, const byte* input, /* Extension data. */ if (i - begin + totalExtSz > totalSz) return BUFFER_ERROR; - if ((ret = TLSX_Parse(ssl, (byte *)(input + i), totalExtSz, - encrypted_extensions, NULL))) + if ((ret = TLSX_Parse(ssl, input + i, totalExtSz, encrypted_extensions, + NULL))) { return ret; + } /* Move index to byte after message. */ *inOutIdx = i + totalExtSz; @@ -3358,8 +3383,8 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input, return BUFFER_ERROR; if (len == 0) return INVALID_PARAMETER; - if ((ret = TLSX_Parse(ssl, (byte *)(input + *inOutIdx), len, - certificate_request, &peerSuites))) { + if ((ret = TLSX_Parse(ssl, input + *inOutIdx, len, certificate_request, + &peerSuites))) { return ret; } *inOutIdx += len; @@ -3406,8 +3431,8 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input, */ static void RefineSuites(WOLFSSL* ssl, Suites* peerSuites) { - byte suites[WOLFSSL_MAX_SUITE_SZ]; - int suiteSz = 0; + byte suites[WOLFSSL_MAX_SUITE_SZ]; + word16 suiteSz = 0; word16 i, j; XMEMSET(suites, 0, WOLFSSL_MAX_SUITE_SZ); @@ -3685,7 +3710,7 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz, ext = TLSX_Find(ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES); if (ext == NULL) return MISSING_HANDSHAKE_DATA; - modes = ext->val; + modes = (word16)ext->val; #ifdef HAVE_SUPPORTED_CURVES ext = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE); @@ -3952,8 +3977,8 @@ static int DoTls13SupportedVersions(WOLFSSL* ssl, const byte* input, word32 i, return BUFFER_ERROR; /* Need to negotiate version first. */ - if ((ret = TLSX_ParseVersion(ssl, (byte*)input + i, totalExtSz, - client_hello, &foundVersion))) { + if ((ret = TLSX_ParseVersion(ssl, input + i, totalExtSz, client_hello, + &foundVersion))) { return ret; } } @@ -4126,7 +4151,7 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, return ret; /* Parse extensions */ - if ((ret = TLSX_Parse(ssl, (byte*)input + i, totalExtSz, client_hello, + if ((ret = TLSX_Parse(ssl, input + i, totalExtSz, client_hello, &clSuites))) { return ret; } @@ -4590,6 +4615,8 @@ static WC_INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output) output[1] = hashAlgo; break; #endif + default: + break; } } @@ -4671,6 +4698,8 @@ static WC_INLINE int GetMsgHash(WOLFSSL* ssl, byte* hash) ret = WC_SHA512_DIGEST_SIZE; break; #endif /* WOLFSSL_TLS13_SHA512 */ + default: + break; } return ret; } @@ -4851,6 +4880,8 @@ static int CreateECCEncodedSig(byte* sigData, int sigDataSz, int hashAlgo) hashSz = WC_SHA512_DIGEST_SIZE; break; #endif + default: + break; } if (ret != 0) @@ -5995,11 +6026,13 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, ssl->options.serverState = SERVER_CERT_VERIFY_COMPLETE; #endif } /* case TLS_ASYNC_FINALIZE */ + FALL_THROUGH; case TLS_ASYNC_END: { break; } + default: ret = INPUT_CASE_ERROR; } /* switch(ssl->options.asyncState) */ @@ -8143,7 +8176,7 @@ int wolfSSL_CTX_set_groups(WOLFSSL_CTX* ctx, int* groups, int count) TLSX_Remove(&ctx->extensions, TLSX_SUPPORTED_GROUPS, ctx->heap); return ret; } - ctx->group[i] = groups[i]; + ctx->group[i] = (word16)groups[i]; } ctx->numGroups = (byte)count; @@ -8178,7 +8211,7 @@ int wolfSSL_set_groups(WOLFSSL* ssl, int* groups, int count) TLSX_Remove(&ssl->extensions, TLSX_SUPPORTED_GROUPS, ssl->heap); return ret; } - ssl->group[i] = groups[i]; + ssl->group[i] = (word16)groups[i]; } ssl->numGroups = (byte)count; diff --git a/src/wolfio.c b/src/wolfio.c index 1924fc3d4..cff63d3e2 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -1,6 +1,6 @@ /* wolfio.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -255,7 +255,12 @@ int EmbedReceive(WOLFSSL *ssl, char *buf, int sz, void *ctx) int err = wolfSSL_LastError(recvd); WOLFSSL_MSG("Embed Receive error"); - if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) { +#if SOCKET_EWOULDBLOCK != SOCKET_EAGAIN + if ((err == SOCKET_EWOULDBLOCK) || (err == SOCKET_EAGAIN)) +#else + if (err == SOCKET_EWOULDBLOCK) +#endif + { WOLFSSL_MSG("\tWould block"); return WOLFSSL_CBIO_ERR_WANT_READ; } @@ -306,7 +311,12 @@ int EmbedSend(WOLFSSL* ssl, char *buf, int sz, void *ctx) int err = wolfSSL_LastError(sent); WOLFSSL_MSG("Embed Send error"); - if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) { +#if SOCKET_EWOULDBLOCK != SOCKET_EAGAIN + if ((err == SOCKET_EWOULDBLOCK) || (err == SOCKET_EAGAIN)) +#else + if (err == SOCKET_EWOULDBLOCK) +#endif + { WOLFSSL_MSG("\tWould Block"); return WOLFSSL_CBIO_ERR_WANT_WRITE; } @@ -2273,7 +2283,7 @@ void wolfSSL_SetIO_Mynewt(WOLFSSL* ssl, struct mn_socket* mnSocket, struct mn_so if (ssl && ssl->mnCtx) { Mynewt_Ctx *mynewt_ctx = (Mynewt_Ctx *)ssl->mnCtx; mynewt_ctx->mnSocket = mnSocket; - memcpy(&mynewt_ctx->mnSockAddrIn, mnSockAddrIn, sizeof(struct mn_sockaddr_in)); + XMEMCPY(&mynewt_ctx->mnSockAddrIn, mnSockAddrIn, sizeof(struct mn_sockaddr_in)); mn_socket_set_cbs(mynewt_ctx->mnSocket, mnSocket, &mynewt_sock_cbs); } } diff --git a/sslSniffer/sslSnifferTest/snifftest.c b/sslSniffer/sslSnifferTest/snifftest.c index af6bbe56d..2816b179f 100644 --- a/sslSniffer/sslSnifferTest/snifftest.c +++ b/sslSniffer/sslSnifferTest/snifftest.c @@ -1,6 +1,6 @@ /* snifftest.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/swig/wolfssl.i b/swig/wolfssl.i index 2571cda3f..57c4ee7c6 100644 --- a/swig/wolfssl.i +++ b/swig/wolfssl.i @@ -1,6 +1,6 @@ /* wolfssl.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/swig/wolfssl_adds.c b/swig/wolfssl_adds.c index fd055ff80..74356eda7 100644 --- a/swig/wolfssl_adds.c +++ b/swig/wolfssl_adds.c @@ -1,6 +1,6 @@ /* wolfssl_adds.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/tests/api.c b/tests/api.c index 3fd9b0085..d6a1f7ce3 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1,6 +1,6 @@ /* api.c API unit tests * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -476,7 +476,7 @@ static int test_wolfCrypt_Init(void) /*----------------------------------------------------------------------------* | Platform dependent function test *----------------------------------------------------------------------------*/ - static int test_fileAccess() + static int test_fileAccess(void) { #if defined(WOLFSSL_TEST_PLATFORMDEPEND) && !defined(NO_FILESYSTEM) const char *fname[] = { @@ -2780,7 +2780,7 @@ static void test_wolfSSL_EVP_get_cipherbynid(void) } -static void test_wolfSSL_EVP_CIPHER_CTX() +static void test_wolfSSL_EVP_CIPHER_CTX(void) { #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128) EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); @@ -15054,7 +15054,7 @@ static int test_wc_CheckProbablePrime (void) ret = 0; } } - + /* Good case */ if (ret == 0) { ret = wc_CheckProbablePrime(p, pSz, q, qSz, e, eSz, @@ -15197,7 +15197,7 @@ static int test_wc_RsaPSS_VerifyCheck (void) ret = wc_Hash(WC_HASH_TYPE_SHA256, pSignature, sz, digest, digestSz); } - + if (ret == 0) { ret = wc_RsaPSS_Sign(digest, digestSz, pSignature, pSignatureSz, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, &key, &rng); @@ -15234,8 +15234,8 @@ static int test_wc_RsaPSS_VerifyCheck (void) if (ret == BAD_FUNC_ARG) { ret = 0; } - } - + } + /* Good case */ if (ret == 0) { ret = wc_RsaPSS_VerifyCheck(pSignature, sz, pt, outLen, @@ -15267,8 +15267,8 @@ static int test_wc_RsaPSS_VerifyCheckInline (void) word32 digestSz; unsigned char pSignature[2048/8]; /* 2048 is RSA_KEY_SIZE */ unsigned char pDecrypted[2048/8]; - pt = pDecrypted; - + pt = pDecrypted; + printf(testingFmt, "wc_RsaPSS_VerifyCheckInline()"); @@ -15291,7 +15291,7 @@ static int test_wc_RsaPSS_VerifyCheckInline (void) ret = wc_Hash(WC_HASH_TYPE_SHA256, pSignature, sz, digest, digestSz); } - + if (ret == 0) { ret = wc_RsaPSS_Sign(digest, digestSz, pSignature, sizeof(pSignature), WC_HASH_TYPE_SHA256, WC_MGF1SHA256, &key, &rng); @@ -22570,7 +22570,7 @@ static int test_wc_EccPrivateKeyToDer (void) } if (ret == 0) { ret = wc_EccPrivateKeyToDer(&eccKey, NULL, inLen); - if (ret == BAD_FUNC_ARG) { + if (ret == LENGTH_ONLY_E) { ret = 0; } } @@ -28477,7 +28477,7 @@ static void test_wolfSSL_CTX_get0_set1_param(void) WOLFSSL_X509_VERIFY_PARAM* pvpm; char testIPv4[] = "127.0.0.1"; char testhostName[] = "foo.hoge.com"; - + printf(testingFmt, "wolfSSL_CTX_get0_set1_param()"); #ifndef NO_WOLFSSL_SERVER @@ -28500,15 +28500,15 @@ static void test_wolfSSL_CTX_get0_set1_param(void) ret = SSL_CTX_set1_param(ctx, pvpm); AssertIntEQ(1, ret); - AssertIntEQ(0, XSTRNCMP(pParam->hostName, testhostName, + AssertIntEQ(0, XSTRNCMP(pParam->hostName, testhostName, (int)XSTRLEN(testhostName))); AssertIntEQ(0x01, pParam->hostFlags); AssertIntEQ(0, XSTRNCMP(pParam->ipasc, testIPv4, WOLFSSL_MAX_IPSTR)); - + SSL_CTX_free(ctx); XFREE(pvpm, NULL, DYNAMIC_TYPE_OPENSSL); - + printf(resultFmt, passed); #endif /* OPENSSL_EXTRA && !defined(NO_RSA)*/ } @@ -29113,7 +29113,7 @@ static int msgCb(SSL_CTX *ctx, SSL *ssl) { (void) ctx; (void) ssl; - #ifdef OPENSSL_ALL + #if defined(OPENSSL_ALL) && defined(SESSION_CERTS) STACK_OF(X509)* sk; X509* x509; int i, num; @@ -29125,7 +29125,7 @@ static int msgCb(SSL_CTX *ctx, SSL *ssl) AssertIntEQ(((WOLFSSL_X509_CHAIN *)SSL_get_peer_cert_chain(ssl))->count, 2); #endif - #ifdef OPENSSL_ALL + #if defined(OPENSSL_ALL) && defined(SESSION_CERTS) bio = BIO_new(BIO_s_file()); BIO_set_fp(bio, stdout, BIO_NOCLOSE); sk = SSL_get_peer_cert_chain(ssl); @@ -30147,6 +30147,202 @@ static void test_wolfSSL_X509_get_ext_count(void) #endif } +static void test_wolfSSL_X509_sign2(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ + defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_ALT_NAMES) && \ + defined(WOLFSSL_CERT_EXT) && \ + (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)) + + WOLFSSL_X509 *x509, *ca; + const unsigned char *der; + const unsigned char *pt; + WOLFSSL_EVP_PKEY *priv; + WOLFSSL_X509_NAME *name; + WOLFSSL_ASN1_TIME *notBefore, *notAfter; + int derSz; + + const int year = 365*24*60*60; + const int day = 24*60*60; + const int hour = 60*60; + const int mini = 60; + time_t t; + + const unsigned char expected[] = { + 0x30, 0x82, 0x04, 0x25, 0x30, 0x82, 0x03, 0x0D, + 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, + 0xF1, 0x5C, 0x99, 0x43, 0x66, 0x3D, 0x96, 0x04, + 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30, + 0x81, 0x94, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, + 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, + 0x04, 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, + 0x6D, 0x61, 0x6E, 0x31, 0x11, 0x30, 0x0F, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x08, 0x53, 0x61, + 0x77, 0x74, 0x6F, 0x6F, 0x74, 0x68, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, + 0x0A, 0x43, 0x6F, 0x6E, 0x73, 0x75, 0x6C, 0x74, + 0x69, 0x6E, 0x67, 0x31, 0x18, 0x30, 0x16, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, + 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, + 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, + 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, + 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, + 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, + 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x1E, + 0x17, 0x0D, 0x30, 0x30, 0x30, 0x32, 0x31, 0x35, + 0x32, 0x30, 0x33, 0x30, 0x30, 0x30, 0x5A, 0x17, + 0x0D, 0x30, 0x31, 0x30, 0x32, 0x31, 0x34, 0x32, + 0x30, 0x33, 0x30, 0x30, 0x30, 0x5A, 0x30, 0x81, + 0x9E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, + 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, + 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, + 0x61, 0x6E, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, + 0x55, 0x04, 0x0A, 0x0C, 0x0C, 0x77, 0x6F, 0x6C, + 0x66, 0x53, 0x53, 0x4C, 0x5F, 0x32, 0x30, 0x34, + 0x38, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, + 0x04, 0x0B, 0x0C, 0x10, 0x50, 0x72, 0x6F, 0x67, + 0x72, 0x61, 0x6D, 0x6D, 0x69, 0x6E, 0x67, 0x2D, + 0x32, 0x30, 0x34, 0x38, 0x31, 0x18, 0x30, 0x16, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, + 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, + 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, + 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, + 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, + 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x30, + 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, + 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, + 0x05, 0x00, 0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, + 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, + 0xC3, 0x03, 0xD1, 0x2B, 0xFE, 0x39, 0xA4, 0x32, + 0x45, 0x3B, 0x53, 0xC8, 0x84, 0x2B, 0x2A, 0x7C, + 0x74, 0x9A, 0xBD, 0xAA, 0x2A, 0x52, 0x07, 0x47, + 0xD6, 0xA6, 0x36, 0xB2, 0x07, 0x32, 0x8E, 0xD0, + 0xBA, 0x69, 0x7B, 0xC6, 0xC3, 0x44, 0x9E, 0xD4, + 0x81, 0x48, 0xFD, 0x2D, 0x68, 0xA2, 0x8B, 0x67, + 0xBB, 0xA1, 0x75, 0xC8, 0x36, 0x2C, 0x4A, 0xD2, + 0x1B, 0xF7, 0x8B, 0xBA, 0xCF, 0x0D, 0xF9, 0xEF, + 0xEC, 0xF1, 0x81, 0x1E, 0x7B, 0x9B, 0x03, 0x47, + 0x9A, 0xBF, 0x65, 0xCC, 0x7F, 0x65, 0x24, 0x69, + 0xA6, 0xE8, 0x14, 0x89, 0x5B, 0xE4, 0x34, 0xF7, + 0xC5, 0xB0, 0x14, 0x93, 0xF5, 0x67, 0x7B, 0x3A, + 0x7A, 0x78, 0xE1, 0x01, 0x56, 0x56, 0x91, 0xA6, + 0x13, 0x42, 0x8D, 0xD2, 0x3C, 0x40, 0x9C, 0x4C, + 0xEF, 0xD1, 0x86, 0xDF, 0x37, 0x51, 0x1B, 0x0C, + 0xA1, 0x3B, 0xF5, 0xF1, 0xA3, 0x4A, 0x35, 0xE4, + 0xE1, 0xCE, 0x96, 0xDF, 0x1B, 0x7E, 0xBF, 0x4E, + 0x97, 0xD0, 0x10, 0xE8, 0xA8, 0x08, 0x30, 0x81, + 0xAF, 0x20, 0x0B, 0x43, 0x14, 0xC5, 0x74, 0x67, + 0xB4, 0x32, 0x82, 0x6F, 0x8D, 0x86, 0xC2, 0x88, + 0x40, 0x99, 0x36, 0x83, 0xBA, 0x1E, 0x40, 0x72, + 0x22, 0x17, 0xD7, 0x52, 0x65, 0x24, 0x73, 0xB0, + 0xCE, 0xEF, 0x19, 0xCD, 0xAE, 0xFF, 0x78, 0x6C, + 0x7B, 0xC0, 0x12, 0x03, 0xD4, 0x4E, 0x72, 0x0D, + 0x50, 0x6D, 0x3B, 0xA3, 0x3B, 0xA3, 0x99, 0x5E, + 0x9D, 0xC8, 0xD9, 0x0C, 0x85, 0xB3, 0xD9, 0x8A, + 0xD9, 0x54, 0x26, 0xDB, 0x6D, 0xFA, 0xAC, 0xBB, + 0xFF, 0x25, 0x4C, 0xC4, 0xD1, 0x79, 0xF4, 0x71, + 0xD3, 0x86, 0x40, 0x18, 0x13, 0xB0, 0x63, 0xB5, + 0x72, 0x4E, 0x30, 0xC4, 0x97, 0x84, 0x86, 0x2D, + 0x56, 0x2F, 0xD7, 0x15, 0xF7, 0x7F, 0xC0, 0xAE, + 0xF5, 0xFC, 0x5B, 0xE5, 0xFB, 0xA1, 0xBA, 0xD3, + 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, 0x6E, 0x30, + 0x6C, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x1D, 0x13, + 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, + 0x1C, 0x06, 0x03, 0x55, 0x1D, 0x11, 0x04, 0x15, + 0x30, 0x13, 0x87, 0x04, 0x7F, 0x00, 0x00, 0x01, + 0x82, 0x0B, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, + 0x65, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x1D, 0x06, + 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, + 0x33, 0xD8, 0x45, 0x66, 0xD7, 0x68, 0x87, 0x18, + 0x7E, 0x54, 0x0D, 0x70, 0x27, 0x91, 0xC7, 0x26, + 0xD7, 0x85, 0x65, 0xC0, 0x30, 0x1F, 0x06, 0x03, + 0x55, 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, + 0x14, 0x33, 0xD8, 0x45, 0x66, 0xD7, 0x68, 0x87, + 0x18, 0x7E, 0x54, 0x0D, 0x70, 0x27, 0x91, 0xC7, + 0x26, 0xD7, 0x85, 0x65, 0xC0, 0x30, 0x0D, 0x06, + 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, + 0x01, 0x0B, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, + 0x00, 0x19, 0xE7, 0xD0, 0x9A, 0xF9, 0x90, 0xAA, + 0xAD, 0x63, 0x58, 0x21, 0x38, 0xA2, 0x4D, 0x30, + 0x9A, 0x6F, 0x88, 0x9E, 0x9B, 0xFB, 0xDE, 0x73, + 0xF2, 0x38, 0xFC, 0x7E, 0x60, 0xC5, 0xFA, 0xBB, + 0x64, 0xA0, 0xD2, 0xC0, 0xBD, 0xB6, 0x4A, 0xAC, + 0x38, 0x90, 0xF5, 0xEE, 0xEC, 0x43, 0x90, 0x7D, + 0x5B, 0xF0, 0x22, 0xA0, 0xAC, 0x59, 0x10, 0xE2, + 0x8D, 0x16, 0xDA, 0x3A, 0xAB, 0x0F, 0x94, 0x11, + 0x6C, 0x0C, 0x61, 0xC1, 0xFD, 0xB5, 0xA3, 0xFC, + 0xE7, 0xFD, 0x0C, 0x63, 0x20, 0xE5, 0x00, 0xCE, + 0xFD, 0xEE, 0x21, 0xE1, 0xE1, 0x9D, 0x48, 0x9B, + 0x71, 0x9C, 0x80, 0x39, 0x5E, 0x5A, 0xD3, 0x32, + 0xA6, 0xAC, 0x3F, 0x84, 0x8C, 0xB6, 0xBC, 0x70, + 0x90, 0xE9, 0xC1, 0x0F, 0xAB, 0xA5, 0x97, 0xD4, + 0xE0, 0x8E, 0x3B, 0xBB, 0x02, 0xE0, 0xED, 0xB0, + 0x10, 0xE8, 0x3F, 0x49, 0xD2, 0x46, 0x4E, 0xE7, + 0x72, 0x0F, 0x1A, 0xFD, 0xE4, 0x59, 0x84, 0x24, + 0xA9, 0x7B, 0x9D, 0x8E, 0x8C, 0xBC, 0xEA, 0xD1, + 0x04, 0x1F, 0xC6, 0x30, 0x47, 0xBD, 0xCC, 0xD1, + 0xBC, 0x87, 0x00, 0xB5, 0x23, 0x3C, 0x60, 0x8F, + 0xB2, 0xDB, 0x71, 0xD2, 0xF5, 0xBA, 0xEB, 0xB1, + 0xD0, 0x53, 0xAC, 0x2E, 0x2C, 0xA5, 0x5D, 0x41, + 0xCD, 0x9B, 0x4F, 0x8B, 0x41, 0xA1, 0x5D, 0x8E, + 0xD9, 0x89, 0x5B, 0x5C, 0x58, 0x1C, 0x4A, 0xE6, + 0x22, 0xC8, 0x15, 0x2D, 0x8E, 0x24, 0x48, 0xF8, + 0xB2, 0x3C, 0x7A, 0x72, 0x62, 0xEC, 0xB2, 0x76, + 0xAD, 0x3D, 0x42, 0x29, 0xE9, 0x3B, 0x4E, 0x7F, + 0x06, 0xA4, 0xA4, 0x72, 0x55, 0xDD, 0x1C, 0x69, + 0x5E, 0x2B, 0x7E, 0xB7, 0x7C, 0xBD, 0xF6, 0x2F, + 0xC9, 0x9A, 0x33, 0x31, 0xD9, 0x92, 0x32, 0xB6, + 0x60, 0x4D, 0x8F, 0x5B, 0xF2, 0xAE, 0xD5, 0x72, + 0x88, 0x92, 0x75, 0xC4, 0xDC, 0xBD, 0x0B, 0xB8, 0x9D + }; + + printf(testingFmt, "wolfSSL_X509_sign2"); + + pt = ca_key_der_2048; + AssertNotNull(priv = wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, NULL, &pt, + sizeof_ca_key_der_2048)); + + pt = client_cert_der_2048; + AssertNotNull(x509 = wolfSSL_d2i_X509(NULL, &pt, + sizeof_client_cert_der_2048)); + + pt = ca_cert_der_2048; + AssertNotNull(ca = wolfSSL_d2i_X509(NULL, &pt, sizeof_ca_cert_der_2048)); + AssertNotNull(name = wolfSSL_X509_get_subject_name(ca)); + AssertIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS); + + t = (time_t)30 * year + 45 * day + 20 * hour + 30 * mini + 7 * day; + AssertNotNull(notBefore = wolfSSL_ASN1_TIME_adj(NULL, t, 0, 0)); + AssertNotNull(notAfter = wolfSSL_ASN1_TIME_adj(NULL, t, 365, 0)); + AssertIntEQ(notAfter->length, 13); + + AssertTrue(wolfSSL_X509_set_notBefore(x509, notBefore)); + AssertTrue(wolfSSL_X509_set_notAfter(x509, notAfter)); + + wolfSSL_X509_sign(x509, priv, EVP_sha256()); + AssertNotNull((der = wolfSSL_X509_get_der(x509, &derSz))); + + AssertIntEQ(derSz, sizeof(expected)); + AssertIntEQ(XMEMCMP(der, expected, derSz), 0); + + wolfSSL_X509_free(ca); + wolfSSL_X509_free(x509); + wolfSSL_EVP_PKEY_free(priv); + wolfSSL_ASN1_TIME_free(notBefore); + wolfSSL_ASN1_TIME_free(notAfter); + printf(resultFmt, passed); +#endif +} + + static void test_wolfSSL_X509_sign(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ @@ -30384,7 +30580,7 @@ static void test_wolfSSL_X509_VERIFY_PARAM(void) char testIPv6[] = "0001:0000:0000:0000:0000:0000:0000:0000/32"; char testhostName1[] = "foo.hoge.com"; char testhostName2[] = "foobar.hoge.com"; - + printf(testingFmt, "wolfSSL_X509()"); paramTo = wolfSSL_X509_VERIFY_PARAM_new(); @@ -30398,9 +30594,9 @@ static void test_wolfSSL_X509_VERIFY_PARAM(void) ret = wolfSSL_X509_VERIFY_PARAM_set1_host(paramFrom, testhostName1, (int)XSTRLEN(testhostName1)); AssertIntEQ(1, ret); - AssertIntEQ(0, XSTRNCMP(paramFrom->hostName, testhostName1, + AssertIntEQ(0, XSTRNCMP(paramFrom->hostName, testhostName1, (int)XSTRLEN(testhostName1))); - + wolfSSL_X509_VERIFY_PARAM_set_hostflags(NULL, 0x00); wolfSSL_X509_VERIFY_PARAM_set_hostflags(paramFrom, 0x01); @@ -30433,7 +30629,7 @@ static void test_wolfSSL_X509_VERIFY_PARAM(void) /* inherit flags test : VPARAM_DEFAULT */ ret = wolfSSL_X509_VERIFY_PARAM_set1(paramTo, paramFrom); AssertIntEQ(1, ret); - AssertIntEQ(0, XSTRNCMP(paramTo->hostName, testhostName1, + AssertIntEQ(0, XSTRNCMP(paramTo->hostName, testhostName1, (int)XSTRLEN(testhostName1))); AssertIntEQ(0x01, paramTo->hostFlags); AssertIntEQ(0, XSTRNCMP(paramTo->ipasc, testIPv6, WOLFSSL_MAX_IPSTR)); @@ -30443,12 +30639,12 @@ static void test_wolfSSL_X509_VERIFY_PARAM(void) (int)XSTRLEN(testhostName2)); wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(paramTo, testIPv4); wolfSSL_X509_VERIFY_PARAM_set_hostflags(paramTo, 0x00); - + paramTo->inherit_flags = WOLFSSL_VPARAM_OVERWRITE; ret = wolfSSL_X509_VERIFY_PARAM_set1(paramTo, paramFrom); AssertIntEQ(1, ret); - AssertIntEQ(0, XSTRNCMP(paramTo->hostName, testhostName1, + AssertIntEQ(0, XSTRNCMP(paramTo->hostName, testhostName1, (int)XSTRLEN(testhostName1))); AssertIntEQ(0x01, paramTo->hostFlags); AssertIntEQ(0, XSTRNCMP(paramTo->ipasc, testIPv6, WOLFSSL_MAX_IPSTR)); @@ -30458,12 +30654,12 @@ static void test_wolfSSL_X509_VERIFY_PARAM(void) (int)XSTRLEN(testhostName2)); wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(paramTo, testIPv4); wolfSSL_X509_VERIFY_PARAM_set_hostflags(paramTo, 0x10); - + paramTo->inherit_flags = WOLFSSL_VPARAM_RESET_FLAGS; ret = wolfSSL_X509_VERIFY_PARAM_set1(paramTo, paramFrom); AssertIntEQ(1, ret); - AssertIntEQ(0, XSTRNCMP(paramTo->hostName, testhostName1, + AssertIntEQ(0, XSTRNCMP(paramTo->hostName, testhostName1, (int)XSTRLEN(testhostName1))); AssertIntEQ(0x01, paramTo->hostFlags); AssertIntEQ(0, XSTRNCMP(paramTo->ipasc, testIPv6, WOLFSSL_MAX_IPSTR)); @@ -30473,12 +30669,12 @@ static void test_wolfSSL_X509_VERIFY_PARAM(void) (int)XSTRLEN(testhostName2)); wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(paramTo, testIPv4); wolfSSL_X509_VERIFY_PARAM_set_hostflags(paramTo, 0x00); - + paramTo->inherit_flags = WOLFSSL_VPARAM_LOCKED; ret = wolfSSL_X509_VERIFY_PARAM_set1(paramTo, paramFrom); AssertIntEQ(1, ret); - AssertIntEQ(0, XSTRNCMP(paramTo->hostName, testhostName2, + AssertIntEQ(0, XSTRNCMP(paramTo->hostName, testhostName2, (int)XSTRLEN(testhostName2))); AssertIntEQ(0x00, paramTo->hostFlags); AssertIntEQ(0, XSTRNCMP(paramTo->ipasc, testIPv4, WOLFSSL_MAX_IPSTR)); @@ -30603,16 +30799,16 @@ static void test_wolfSSL_RAND_bytes(void) { #if defined(OPENSSL_EXTRA) const int size1 = RNG_MAX_BLOCK_LEN; /* in bytes */ - const int size2 = RNG_MAX_BLOCK_LEN + 1; /* in bytes */ + const int size2 = RNG_MAX_BLOCK_LEN + 1; /* in bytes */ const int size3 = RNG_MAX_BLOCK_LEN * 2; /* in bytes */ const int size4 = RNG_MAX_BLOCK_LEN * 4; /* in bytes */ int max_bufsize; byte *my_buf; - + printf(testingFmt, "test_wolfSSL_RAND_bytes()"); max_bufsize = size4; - + my_buf = (byte*)XMALLOC(max_bufsize * sizeof(byte), NULL, DYNAMIC_TYPE_TMP_BUFFER); AssertNotNull(my_buf); @@ -30621,7 +30817,7 @@ static void test_wolfSSL_RAND_bytes(void) AssertIntEQ(wolfSSL_RAND_bytes(my_buf, size2), 1); AssertIntEQ(wolfSSL_RAND_bytes(my_buf, size3), 1); AssertIntEQ(wolfSSL_RAND_bytes(my_buf, size4), 1); - + XFREE(my_buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); printf(resultFmt, passed); @@ -31002,15 +31198,15 @@ static void test_wolfSSL_ERR_print_errors(void) AssertNotNull(bio = BIO_new(BIO_s_mem())); ERR_clear_error(); /* clear out any error nodes */ ERR_put_error(0,SYS_F_ACCEPT, -173, "ssl.c", 0); - /* Choosing -295 as an unused errno between MIN_CODE_E < x < WC_LAST_E. */ - ERR_put_error(0,SYS_F_BIND, -295, "asn.c", 100); + /* Choosing -299 as an unused errno between MIN_CODE_E < x < WC_LAST_E. */ + ERR_put_error(0,SYS_F_BIND, -299, "asn.c", 100); ERR_print_errors(bio); AssertIntEQ(BIO_gets(bio, buf, sizeof(buf)), 56); AssertIntEQ(XSTRNCMP("error:173:wolfSSL library:Bad function argument:ssl.c:0", buf, 55), 0); AssertIntEQ(BIO_gets(bio, buf, sizeof(buf)), 57); - AssertIntEQ(XSTRNCMP("error:295:wolfSSL library:unknown error number:asn.c:100", + AssertIntEQ(XSTRNCMP("error:299:wolfSSL library:unknown error number:asn.c:100", buf, 56), 0); AssertIntEQ(BIO_gets(bio, buf, sizeof(buf)), 1); AssertIntEQ(buf[0], '\0'); @@ -33313,7 +33509,7 @@ static void test_wolfSSL_SHA(void) XMEMSET(out, 0, WC_SHA_DIGEST_SIZE); AssertNotNull(SHA1(in, XSTRLEN((char*)in), out)); AssertIntEQ(XMEMCMP(out, expected, WC_SHA_DIGEST_SIZE), 0); - + /* SHA interface test */ XMEMSET(out, 0, WC_SHA_DIGEST_SIZE); AssertNotNull(SHA(in, XSTRLEN((char*)in), out)); @@ -33533,26 +33729,26 @@ static void test_wolfSSL_MD5(void) byte input1[] = ""; byte input2[] = "message digest"; byte hash[WC_MD5_DIGEST_SIZE]; - unsigned char output1[] = + unsigned char output1[] = "\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e"; unsigned char output2[] = "\xf9\x6b\x69\x7d\x7c\xb7\x93\x8d\x52\x5a\x2f\x31\xaa\xf1\x61\xd0"; WOLFSSL_MD5_CTX md5; - + printf(testingFmt, "wolfSSL_MD5()"); - + XMEMSET(&md5, 0, sizeof(md5)); - + /* Init MD5 CTX */ AssertIntEQ(wolfSSL_MD5_Init(&md5), 1); - AssertIntEQ(wolfSSL_MD5_Update(&md5, input1, + AssertIntEQ(wolfSSL_MD5_Update(&md5, input1, XSTRLEN((const char*)&input1)), 1); AssertIntEQ(wolfSSL_MD5_Final(hash, &md5), 1); AssertIntEQ(XMEMCMP(&hash, output1, WC_MD5_DIGEST_SIZE), 0); - + /* Init MD5 CTX */ AssertIntEQ(wolfSSL_MD5_Init(&md5), 1); - AssertIntEQ(wolfSSL_MD5_Update(&md5, input2, + AssertIntEQ(wolfSSL_MD5_Update(&md5, input2, (int)XSTRLEN((const char*)input2)), 1); AssertIntEQ(wolfSSL_MD5_Final(hash, &md5), 1); AssertIntEQ(XMEMCMP(&hash, output2, WC_MD5_DIGEST_SIZE), 0); @@ -33576,18 +33772,18 @@ static void test_wolfSSL_MD5_Transform(void) byte input2[] = "abc"; byte local[WC_MD5_BLOCK_SIZE]; word32 sLen = 0; - unsigned char output1[] = + unsigned char output1[] = "\xac\x1d\x1f\x03\xd0\x8e\xa5\x6e\xb7\x67\xab\x1f\x91\x77\x31\x74"; unsigned char output2[] = "\x8d\x79\xd3\xef\x90\x25\x17\x67\xc7\x79\x13\xa4\xbc\x7b\xa7\xe3"; WOLFSSL_MD5_CTX md5; - + printf(testingFmt, "wolfSSL_MD5_Transform()"); - + XMEMSET(&md5, 0, sizeof(md5)); XMEMSET(&local, 0, sizeof(local)); - + /* sanity check */ AssertIntEQ(wolfSSL_MD5_Transform(NULL, NULL), 0); AssertIntEQ(wolfSSL_MD5_Transform(NULL, (const byte*)&input1), 0); @@ -33595,24 +33791,24 @@ static void test_wolfSSL_MD5_Transform(void) AssertIntEQ(wc_Md5Transform(NULL, NULL), BAD_FUNC_ARG); AssertIntEQ(wc_Md5Transform(NULL, (const byte*)&input1), BAD_FUNC_ARG); AssertIntEQ(wc_Md5Transform((wc_Md5*)&md5, NULL), BAD_FUNC_ARG); - + /* Init MD5 CTX */ AssertIntEQ(wolfSSL_MD5_Init(&md5), 1); /* Do Transform*/ sLen = (word32)XSTRLEN((char*)input1); XMEMCPY(local, input1, sLen); AssertIntEQ(wolfSSL_MD5_Transform(&md5, (const byte*)&local[0]), 1); - - AssertIntEQ(XMEMCMP(&((wc_Md5*)&md5)->digest[0], output1, + + AssertIntEQ(XMEMCMP(&((wc_Md5*)&md5)->digest[0], output1, WC_MD5_DIGEST_SIZE), 0); - + /* Init MD5 CTX */ AssertIntEQ(wolfSSL_MD5_Init(&md5), 1); sLen = (word32)XSTRLEN((char*)input2); XMEMSET(local, 0, WC_MD5_BLOCK_SIZE); XMEMCPY(local, input2, sLen); AssertIntEQ(wolfSSL_MD5_Transform(&md5, (const byte*)&local[0]), 1); - AssertIntEQ(XMEMCMP(&((wc_Md5*)&md5)->digest[0], output2, + AssertIntEQ(XMEMCMP(&((wc_Md5*)&md5)->digest[0], output2, WC_MD5_DIGEST_SIZE), 0); printf(resultFmt, passed); @@ -33651,7 +33847,7 @@ static void test_wolfSSL_SHA_Transform(void) byte input2[] = "abc"; byte local[WC_SHA_BLOCK_SIZE]; word32 sLen = 0; - unsigned char output1[] = + unsigned char output1[] = "\xe5\x04\xb4\x92\xed\x8c\x58\x56\x4e\xcd\x1a\x6c\x68\x3f\x05\xbf" "\x93\x3a\xf7\x09"; unsigned char output2[] = @@ -33659,12 +33855,12 @@ static void test_wolfSSL_SHA_Transform(void) "\xb8\x08\x6e\x7c"; WOLFSSL_SHA_CTX sha; - + printf(testingFmt, "wolfSSL_SHA_Transform()"); - + XMEMSET(&sha, 0, sizeof(sha)); XMEMSET(&local, 0, sizeof(local)); - + /* sanity check */ AssertIntEQ(wolfSSL_SHA_Transform(NULL, NULL), 0); AssertIntEQ(wolfSSL_SHA_Transform(NULL, (const byte*)&input1), 0); @@ -33672,25 +33868,25 @@ static void test_wolfSSL_SHA_Transform(void) AssertIntEQ(wc_ShaTransform(NULL, NULL), BAD_FUNC_ARG); AssertIntEQ(wc_ShaTransform(NULL, (const byte*)&input1), BAD_FUNC_ARG); AssertIntEQ(wc_ShaTransform((wc_Sha*)&sha, NULL), BAD_FUNC_ARG); - + /* Init SHA CTX */ AssertIntEQ(wolfSSL_SHA_Init(&sha), 1); /* Do Transform*/ sLen = (word32)XSTRLEN((char*)input1); XMEMCPY(local, input1, sLen); AssertIntEQ(wolfSSL_SHA_Transform(&sha, (const byte*)&local[0]), 1); - AssertIntEQ(XMEMCMP(&((wc_Sha*)&sha)->digest[0], output1, + AssertIntEQ(XMEMCMP(&((wc_Sha*)&sha)->digest[0], output1, WC_SHA_DIGEST_SIZE), 0); - + /* Init SHA256 CTX */ AssertIntEQ(wolfSSL_SHA_Init(&sha), 1); sLen = (word32)XSTRLEN((char*)input2); XMEMSET(local, 0, WC_SHA_BLOCK_SIZE); XMEMCPY(local, input2, sLen); AssertIntEQ(wolfSSL_SHA_Transform(&sha, (const byte*)&local[0]), 1); - AssertIntEQ(XMEMCMP(&((wc_Sha*)&sha)->digest[0], output2, + AssertIntEQ(XMEMCMP(&((wc_Sha*)&sha)->digest[0], output2, WC_SHA_DIGEST_SIZE), 0); - + printf(resultFmt, passed); #endif #endif @@ -33705,20 +33901,20 @@ static void test_wolfSSL_SHA256_Transform(void) byte input2[] = "abc"; byte local[WC_SHA256_BLOCK_SIZE]; word32 sLen = 0; - unsigned char output1[] = + unsigned char output1[] = "\xbe\x98\x56\xda\x69\xb4\xb9\x17\x99\x57\x33\x62\xca\xbe\x9f\x77" "\x91\xd4\xe5\x8c\x43\x62\xd2\xc0\xea\xf9\xfe\xba\xd8\xa9\x37\x18"; unsigned char output2[] = "\x67\xd4\x4e\x1d\x67\x61\x7c\x67\x26\x76\x10\x44\xb8\xff\x10\x78" "\x39\x9a\xc8\x40\x8c\x60\x16\x73\x05\xd6\x61\xa6\x35\x8c\xf2\x91"; - + WOLFSSL_SHA256_CTX sha256; - + printf(testingFmt, "wolfSSL_SHA256_Transform()"); - + XMEMSET(&sha256, 0, sizeof(sha256)); XMEMSET(&local, 0, sizeof(local)); - + /* sanity check */ AssertIntEQ(wolfSSL_SHA256_Transform(NULL, NULL), 0); AssertIntEQ(wolfSSL_SHA256_Transform(NULL, (const byte*)&input1), 0); @@ -33726,25 +33922,25 @@ static void test_wolfSSL_SHA256_Transform(void) AssertIntEQ(wc_Sha256Transform(NULL, NULL), BAD_FUNC_ARG); AssertIntEQ(wc_Sha256Transform(NULL, (const byte*)&input1), BAD_FUNC_ARG); AssertIntEQ(wc_Sha256Transform((wc_Sha256*)&sha256, NULL), BAD_FUNC_ARG); - + /* Init SHA256 CTX */ AssertIntEQ(wolfSSL_SHA256_Init(&sha256), 1); /* Do Transform*/ sLen = (word32)XSTRLEN((char*)input1); XMEMCPY(local, input1, sLen); AssertIntEQ(wolfSSL_SHA256_Transform(&sha256, (const byte*)&local[0]), 1); - AssertIntEQ(XMEMCMP(&((wc_Sha256*)&sha256)->digest[0], output1, + AssertIntEQ(XMEMCMP(&((wc_Sha256*)&sha256)->digest[0], output1, WC_SHA256_DIGEST_SIZE), 0); - + /* Init SHA256 CTX */ AssertIntEQ(wolfSSL_SHA256_Init(&sha256), 1); sLen = (word32)XSTRLEN((char*)input2); XMEMSET(local, 0, WC_SHA256_BLOCK_SIZE); XMEMCPY(local, input2, sLen); AssertIntEQ(wolfSSL_SHA256_Transform(&sha256, (const byte*)&local[0]), 1); - AssertIntEQ(XMEMCMP(&((wc_Sha256*)&sha256)->digest[0], output2, + AssertIntEQ(XMEMCMP(&((wc_Sha256*)&sha256)->digest[0], output2, WC_SHA256_DIGEST_SIZE), 0); - + printf(resultFmt, passed); #endif #endif @@ -33783,7 +33979,7 @@ static void test_wolfSSL_SHA512_Transform(void) byte input2[] = "abc"; byte local[WC_SHA512_BLOCK_SIZE]; word32 sLen = 0; - unsigned char output1[] = + unsigned char output1[] = "\xe8\xcb\x4a\x77\xd5\x81\x78\xcf\x70\x80\xc7\xfb\xe0\x62\x33\x53" "\xda\x0e\x46\x87\x9d\x63\x67\x02\xb0\x31\x59\xe8\x40\xcb\x86\x30" "\xa3\x23\xa0\x88\x52\xc9\x7d\x71\xe0\xb5\xe0\x4c\xc1\xb2\xba\x96" @@ -33793,14 +33989,14 @@ static void test_wolfSSL_SHA512_Transform(void) "\x41\x31\xab\xca\x3d\x26\xb4\xa9\xab\xd7\x67\xe1\xaf\xaa\xc6\xe2" "\x83\x4e\xba\x2c\x54\x2e\x8f\x31\x98\x38\x2b\x8f\x9d\xec\x88\xbe" "\x4d\x5e\x8b\x53\x9d\x4e\xd2\x14\xf0\x96\x20\xaf\x69\x6c\x68\xde"; - + WOLFSSL_SHA512_CTX sha512; - + printf(testingFmt, "wolfSSL_SHA512_Transform()"); - + XMEMSET(&sha512, 0, sizeof(sha512)); XMEMSET(&local, 0, sizeof(local)); - + /* sanity check */ AssertIntEQ(wolfSSL_SHA512_Transform(NULL, NULL), 0); AssertIntEQ(wolfSSL_SHA512_Transform(NULL, (const byte*)&input1), 0); @@ -33808,7 +34004,7 @@ static void test_wolfSSL_SHA512_Transform(void) AssertIntEQ(wc_Sha512Transform(NULL, NULL), BAD_FUNC_ARG); AssertIntEQ(wc_Sha512Transform(NULL, (const byte*)&input1), BAD_FUNC_ARG); AssertIntEQ(wc_Sha512Transform((wc_Sha512*)&sha512, NULL), BAD_FUNC_ARG); - + /* Init SHA512 CTX */ AssertIntEQ(wolfSSL_SHA512_Init(&sha512), 1); @@ -33816,16 +34012,16 @@ static void test_wolfSSL_SHA512_Transform(void) sLen = (word32)XSTRLEN((char*)input1); XMEMCPY(local, input1, sLen); AssertIntEQ(wolfSSL_SHA512_Transform(&sha512, (const byte*)&local[0]), 1); - AssertIntEQ(XMEMCMP(&((wc_Sha512*)&sha512)->digest[0], output1, + AssertIntEQ(XMEMCMP(&((wc_Sha512*)&sha512)->digest[0], output1, WC_SHA512_DIGEST_SIZE), 0); - + /* Init SHA512 CTX */ AssertIntEQ(wolfSSL_SHA512_Init(&sha512), 1); sLen = (word32)XSTRLEN((char*)input2); XMEMSET(local, 0, WC_SHA512_BLOCK_SIZE); XMEMCPY(local, input2, sLen); AssertIntEQ(wolfSSL_SHA512_Transform(&sha512, (const byte*)&local[0]), 1); - AssertIntEQ(XMEMCMP(&((wc_Sha512*)&sha512)->digest[0], output2, + AssertIntEQ(XMEMCMP(&((wc_Sha512*)&sha512)->digest[0], output2, WC_SHA512_DIGEST_SIZE), 0); (void)input1; printf(resultFmt, passed); @@ -34348,7 +34544,7 @@ static void test_wolfSSL_DES_ncbc(void){ #endif } -static void test_wolfSSL_AES_cbc_encrypt() +static void test_wolfSSL_AES_cbc_encrypt(void) { #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(OPENSSL_EXTRA) AES_KEY aes; @@ -34779,7 +34975,7 @@ static void test_wolfSSL_X509_PUBKEY_get(void) printf(resultFmt,retEvpPkey == NULL ? passed : failed); } -static void test_wolfSSL_d2i_DHparams() +static void test_wolfSSL_d2i_DHparams(void) { #if !defined(NO_DH) #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2)) @@ -34841,7 +35037,7 @@ static void test_wolfSSL_d2i_DHparams() #endif /* !NO_DH */ } -static void test_wolfSSL_i2d_DHparams() +static void test_wolfSSL_i2d_DHparams(void) { #if !defined(NO_DH) #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2)) @@ -35954,7 +36150,7 @@ static void test_wolfSSL_EVP_CIPHER_block_size(void) #endif #endif -#ifdef WOLFSSL_AES_ECB +#ifdef HAVE_AES_ECB #ifdef WOLFSSL_AES_128 AssertIntEQ(EVP_CIPHER_block_size(EVP_aes_128_ecb()), AES_BLOCK_SIZE); #endif @@ -36032,7 +36228,7 @@ static void test_wolfSSL_EVP_CIPHER_iv_length(void) NID_des_ede3_cbc, #endif #ifdef HAVE_IDEA - NID_idea_cbc, + NID_idea_cbc, #endif }; int iv_lengths[] = { @@ -36244,7 +36440,7 @@ static void test_IncCtr(void) ctx->cipher.aes.keylen = 128; - AssertIntEQ(wolfSSL_EVP_CIPHER_CTX_ctrl(ctx, type, arg, ptr), 0); + AssertIntEQ(wolfSSL_EVP_CIPHER_CTX_ctrl(ctx, type, arg, ptr), 0); EVP_CIPHER_CTX_free(ctx); @@ -36864,7 +37060,7 @@ static void test_wolfSSL_X509_cmp(void) #endif } -static void test_wolfSSL_PKEY_up_ref() +static void test_wolfSSL_PKEY_up_ref(void) { #if defined(OPENSSL_ALL) EVP_PKEY* pkey; @@ -36882,7 +37078,7 @@ static void test_wolfSSL_PKEY_up_ref() #endif } -static void test_wolfSSL_i2d_PrivateKey() +static void test_wolfSSL_i2d_PrivateKey(void) { #if (!defined(NO_RSA) || defined(HAVE_ECC)) && defined(OPENSSL_EXTRA) && !defined(NO_ASN) && !defined(NO_PWDBASED) @@ -36929,7 +37125,7 @@ static void test_wolfSSL_i2d_PrivateKey() #endif } -static void test_wolfSSL_OCSP_id_get0_info() +static void test_wolfSSL_OCSP_id_get0_info(void) { #if defined(OPENSSL_ALL) && defined(HAVE_OCSP) && !defined(NO_FILESYSTEM) X509* cert; @@ -36977,7 +37173,7 @@ static void test_wolfSSL_OCSP_id_get0_info() #endif } -static void test_wolfSSL_i2d_OCSP_CERTID() +static void test_wolfSSL_i2d_OCSP_CERTID(void) { #if defined(OPENSSL_ALL) && defined(HAVE_OCSP) WOLFSSL_OCSP_CERTID certId; @@ -36996,7 +37192,7 @@ static void test_wolfSSL_i2d_OCSP_CERTID() int ret, i; printf(testingFmt, "wolfSSL_i2d_OCSP_CERTID()"); - + XMEMSET(&certId, 0, sizeof(WOLFSSL_OCSP_CERTID)); certId.rawCertId = rawCertId; certId.rawCertIdSize = sizeof(rawCertId); @@ -37032,7 +37228,7 @@ static void test_wolfSSL_i2d_OCSP_CERTID() #endif } -static void test_wolfSSL_OCSP_SINGLERESP_get0_id() +static void test_wolfSSL_OCSP_SINGLERESP_get0_id(void) { #if defined(OPENSSL_ALL) && defined(HAVE_OCSP) WOLFSSL_OCSP_SINGLERESP single; @@ -37040,7 +37236,7 @@ static void test_wolfSSL_OCSP_SINGLERESP_get0_id() XMEMSET(&single, 0, sizeof(single)); certId = wolfSSL_OCSP_SINGLERESP_get0_id(&single); - + printf(testingFmt, "wolfSSL_OCSP_SINGLERESP_get0_id()"); AssertPtrEq(&single, certId); @@ -37049,9 +37245,9 @@ static void test_wolfSSL_OCSP_SINGLERESP_get0_id() #endif } -static void test_wolfSSL_OCSP_single_get0_status() +static void test_wolfSSL_OCSP_single_get0_status(void) { -#if defined(OPENSSL_ALL) && defined(HAVE_OCSP) +#if defined(OPENSSL_ALL) && defined(HAVE_OCSP) WOLFSSL_OCSP_SINGLERESP single; CertStatus certStatus; WOLFSSL_ASN1_TIME* thisDate; @@ -37081,7 +37277,7 @@ static void test_wolfSSL_OCSP_single_get0_status() #endif } -static void test_wolfSSL_OCSP_resp_count() +static void test_wolfSSL_OCSP_resp_count(void) { #if defined(OPENSSL_ALL) && defined(HAVE_OCSP) WOLFSSL_OCSP_BASICRESP basicResp; @@ -37110,7 +37306,7 @@ static void test_wolfSSL_OCSP_resp_count() #endif } -static void test_wolfSSL_OCSP_resp_get0() +static void test_wolfSSL_OCSP_resp_get0(void) { #if defined(OPENSSL_ALL) && defined(HAVE_OCSP) WOLFSSL_OCSP_BASICRESP basicResp; @@ -37219,7 +37415,7 @@ static void test_wolfSSL_RSA_padding_add_PKCS1_PSS(void) #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ #endif /* OPENSSL_ALL && WC_RSA_PSS && !WC_NO_RNG*/ } -#endif +#endif static void test_wolfSSL_EC_get_builtin_curves(void) { @@ -39649,7 +39845,7 @@ static void test_wolfSSL_X509_load_crl_file(void) AssertNotNull(store = wolfSSL_X509_STORE_new()); AssertNotNull(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file())); - + AssertIntEQ(wolfSSL_X509_LOOKUP_load_file(lookup, "certs/ca-cert.pem", X509_FILETYPE_PEM), 1); AssertIntEQ(wolfSSL_X509_LOOKUP_load_file(lookup, "certs/server-revoked-cert.pem", @@ -39661,12 +39857,12 @@ static void test_wolfSSL_X509_load_crl_file(void) AssertIntEQ(wolfSSL_CertManagerVerify(store->cm, "certs/server-revoked-cert.pem", WOLFSSL_FILETYPE_PEM), 1); } - + for (i = 0; pem[i][0] != '\0'; i++) { AssertIntEQ(wolfSSL_X509_load_crl_file(lookup, pem[i], WOLFSSL_FILETYPE_PEM), 1); } - + if (store) { /* since store knows crl list */ AssertIntEQ(wolfSSL_CertManagerVerify(store->cm, "certs/server-revoked-cert.pem", @@ -39675,10 +39871,10 @@ static void test_wolfSSL_X509_load_crl_file(void) /* once feeing store */ wolfSSL_X509_STORE_free(store); store = NULL; - + AssertNotNull(store = wolfSSL_X509_STORE_new()); AssertNotNull(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file())); - + AssertIntEQ(wolfSSL_X509_LOOKUP_load_file(lookup, "certs/ca-cert.pem", X509_FILETYPE_PEM), 1); AssertIntEQ(wolfSSL_X509_LOOKUP_load_file(lookup, "certs/server-revoked-cert.pem", @@ -39690,21 +39886,21 @@ static void test_wolfSSL_X509_load_crl_file(void) AssertIntEQ(wolfSSL_CertManagerVerify(store->cm, "certs/server-revoked-cert.pem", WOLFSSL_FILETYPE_PEM), 1); } - + for (i = 0; der[i][0] != '\0'; i++) { AssertIntEQ(wolfSSL_X509_load_crl_file(lookup, der[i], WOLFSSL_FILETYPE_ASN1), 1); } - + if (store) { /* since store knows crl list */ AssertIntEQ(wolfSSL_CertManagerVerify(store->cm, "certs/server-revoked-cert.pem", WOLFSSL_FILETYPE_PEM ), CRL_CERT_REVOKED); } - + wolfSSL_X509_STORE_free(store); store = NULL; - + printf(resultFmt, passed); #endif } @@ -40069,23 +40265,23 @@ static void test_wolfssl_EVP_aes_gcm_AAD_2_parts(void) #if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AESGCM) && \ !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) -static void test_wolfssl_EVP_aes_gcm_zeroLen() -{ +static void test_wolfssl_EVP_aes_gcm_zeroLen(void) +{ /* Zero length plain text */ - byte key[] = + byte key[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; /* align */ - byte iv[] = + byte iv[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; /* align */ byte plaintxt[0]; int ivSz = 12; int plaintxtSz = 0; unsigned char tag[16]; - unsigned char tag_kat[] = + unsigned char tag_kat[] = {0x53,0x0f,0x8a,0xfb,0xc7,0x45,0x36,0xb9, 0xa9,0x63,0xb4,0xf1,0xc4,0xcb,0x73,0x8b}; @@ -40108,7 +40304,7 @@ static void test_wolfssl_EVP_aes_gcm_zeroLen() AssertIntEQ(0, ciphertxtSz); AssertIntEQ(0, XMEMCMP(tag, tag_kat, sizeof(tag))); - + EVP_CIPHER_CTX_init(de); AssertIntEQ(1, EVP_DecryptInit_ex(de, EVP_aes_256_gcm(), NULL, key, iv)); AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(de, EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); @@ -40118,7 +40314,7 @@ static void test_wolfssl_EVP_aes_gcm_zeroLen() AssertIntEQ(1, EVP_DecryptFinal_ex(de, decryptedtxt, &len)); decryptedtxtSz += len; AssertIntEQ(0, decryptedtxtSz); - + EVP_CIPHER_CTX_free(en); EVP_CIPHER_CTX_free(de); } @@ -40230,7 +40426,7 @@ static void test_wolfssl_EVP_aes_gcm(void) AssertIntEQ(0, len); AssertIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&de[i]), 1); } - + test_wolfssl_EVP_aes_gcm_zeroLen(); printf(resultFmt, passed); @@ -40283,7 +40479,7 @@ static void test_wolfSSL_PEM_X509_INFO_read_bio(void) } #endif /* !NO_BIO */ -static void test_wolfSSL_X509_NAME_ENTRY_get_object() +static void test_wolfSSL_X509_NAME_ENTRY_get_object(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_RSA) X509 *x509; @@ -40309,7 +40505,7 @@ static void test_wolfSSL_X509_NAME_ENTRY_get_object() #endif } -static void test_wolfSSL_ASN1_INTEGER_set() +static void test_wolfSSL_ASN1_INTEGER_set(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_ASN) ASN1_INTEGER *a; @@ -40407,7 +40603,7 @@ ASN1_SEQUENCE(DPP_BOOTSTRAPPING_KEY) = { IMPLEMENT_ASN1_FUNCTIONS(DPP_BOOTSTRAPPING_KEY); #endif -static void test_wolfSSL_IMPLEMENT_ASN1_FUNCTIONS() +static void test_wolfSSL_IMPLEMENT_ASN1_FUNCTIONS(void) { /* Testing code used in dpp.c in hostap */ #if defined(OPENSSL_ALL) && defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256) @@ -40465,7 +40661,7 @@ static void test_wolfSSL_IMPLEMENT_ASN1_FUNCTIONS() #endif /* WOLFSSL_WPAS && HAVE_ECC && USE_CERT_BUFFERS_256 */ } -static void test_wolfSSL_i2c_ASN1_INTEGER() +static void test_wolfSSL_i2c_ASN1_INTEGER(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_ASN) ASN1_INTEGER *a; @@ -40601,7 +40797,7 @@ static int test_ForceZero(void) #ifndef NO_BIO -static void test_wolfSSL_X509_print() +static void test_wolfSSL_X509_print(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && \ !defined(NO_RSA) && !defined(HAVE_FAST_RSA) && defined(XSNPRINTF) @@ -40645,7 +40841,7 @@ static void test_wolfSSL_X509_print() #endif } -static void test_wolfSSL_RSA_print() +static void test_wolfSSL_RSA_print(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && \ !defined(NO_RSA) && !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \ @@ -40664,7 +40860,7 @@ static void test_wolfSSL_RSA_print() #endif } -static void test_wolfSSL_BIO_get_len() +static void test_wolfSSL_BIO_get_len(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_BIO) BIO *bio; @@ -40797,7 +40993,7 @@ static void test_wolfSSL_ASN1_get_object(void) #endif /* OPENSSL_EXTRA && HAVE_ECC && USE_CERT_BUFFERS_256 */ } -static void test_wolfSSL_RSA_verify() +static void test_wolfSSL_RSA_verify(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(HAVE_FAST_RSA) && \ !defined(NO_FILESYSTEM) && defined(HAVE_CRL) @@ -40982,7 +41178,7 @@ static void test_openssl_generate_key_and_cert(void) #endif /* OPENSSL_EXTRA */ } -static void test_stubs_are_stubs() +static void test_stubs_are_stubs(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_WOLFSSL_STUB) WOLFSSL_CTX* ctx = NULL; @@ -41021,7 +41217,7 @@ static void test_stubs_are_stubs() #endif /* OPENSSL_EXTRA && !NO_WOLFSSL_STUB */ } -static void test_wolfSSL_CTX_LoadCRL() +static void test_wolfSSL_CTX_LoadCRL(void) { #ifdef HAVE_CRL WOLFSSL_CTX* ctx = NULL; @@ -41723,6 +41919,7 @@ void ApiTest(void) test_wolfSSL_X509(); test_wolfSSL_X509_VERIFY_PARAM(); test_wolfSSL_X509_sign(); + test_wolfSSL_X509_sign2(); test_wolfSSL_X509_get0_tbs_sigalg(); test_wolfSSL_X509_ALGOR_get0(); test_wolfSSL_X509_get_X509_PUBKEY(); @@ -41825,9 +42022,9 @@ void ApiTest(void) test_wolfSSL_OCSP_resp_count(); test_wolfSSL_OCSP_resp_get0(); test_wolfSSL_EVP_PKEY_derive(); -#ifndef NO_RSA +#ifndef NO_RSA test_wolfSSL_RSA_padding_add_PKCS1_PSS(); -#endif +#endif #if defined(OPENSSL_ALL) test_wolfSSL_X509_PUBKEY_get(); diff --git a/tests/hash.c b/tests/hash.c index ef0ee0c93..fd5e79c64 100644 --- a/tests/hash.c +++ b/tests/hash.c @@ -1,6 +1,6 @@ /* hash.c has unit tests * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/tests/srp.c b/tests/srp.c index 1132f35b0..7cd13326d 100644 --- a/tests/srp.c +++ b/tests/srp.c @@ -1,6 +1,6 @@ /* srp.c SRP unit tests * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/tests/suites.c b/tests/suites.c index 7828b273b..2e1a09f65 100644 --- a/tests/suites.c +++ b/tests/suites.c @@ -1,6 +1,6 @@ /* suites.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/tests/unit.c b/tests/unit.c index 670e1d198..5d7325983 100644 --- a/tests/unit.c +++ b/tests/unit.c @@ -1,6 +1,6 @@ /* unit.c API unit tests driver * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/tests/unit.h b/tests/unit.h index 67f49f5f9..c86124b6d 100644 --- a/tests/unit.h +++ b/tests/unit.h @@ -1,6 +1,6 @@ /* unit.c API unit tests driver * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/testsuite/testsuite.c b/testsuite/testsuite.c index d390b5483..1091d3f48 100644 --- a/testsuite/testsuite.c +++ b/testsuite/testsuite.c @@ -1,6 +1,6 @@ /* testsuite.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 3689e7726..adea5980f 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -1,6 +1,6 @@ /* benchmark.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -108,6 +108,20 @@ #undef NO_FILESYSTEM #define NO_FILESYSTEM +#elif defined(ANDROID) + #ifdef XMALLOC_USER + #include /* we're using malloc / free direct here */ + #endif + #ifndef STRING_USER + #include + #endif + #include + + #define printf(...) \ + __android_log_print(ANDROID_LOG_DEBUG, "TAG", __VA_ARGS__) + #define fprintf(fp, ...) \ + __android_log_print(ANDROID_LOG_DEBUG, "TAG", __VA_ARGS__) + #else #if defined(XMALLOC_USER) || defined(FREESCALE_MQX) /* MQX classic needs for EXIT_FAILURE */ @@ -170,6 +184,12 @@ #ifdef HAVE_ED448 #include #endif +#ifdef WOLFCRYPT_HAVE_ECCSI + #include +#endif +#ifdef WOLFCRYPT_HAVE_SAKKE + #include +#endif #include #ifdef HAVE_NTRU @@ -289,6 +309,14 @@ #define BENCH_ED448_SIGN 0x00800000 #define BENCH_ECC_P256 0x01000000 #define BENCH_ECC_P384 0x02000000 +#define BENCH_ECCSI_KEYGEN 0x00000020 +#define BENCH_ECCSI_PAIRGEN 0x00000040 +#define BENCH_ECCSI_VALIDATE 0x00000080 +#define BENCH_ECCSI 0x00000400 +#define BENCH_SAKKE_KEYGEN 0x10000000 +#define BENCH_SAKKE_RSKGEN 0x20000000 +#define BENCH_SAKKE_VALIDATE 0x40000000 +#define BENCH_SAKKE 0x80000000 /* Other */ #define BENCH_RNG 0x00000001 @@ -318,13 +346,13 @@ typedef struct bench_alg { /* Command line option string. */ const char* str; /* Bit values to set. */ - int val; + word32 val; } bench_alg; #ifndef MAIN_NO_ARGS /* All recognized cipher algorithm choosing command line options. */ static const bench_alg bench_cipher_opt[] = { - { "-cipher", -1 }, + { "-cipher", 0xffffffff }, #ifdef HAVE_AES_CBC { "-aes-cbc", BENCH_AES_CBC }, #endif @@ -373,12 +401,12 @@ static const bench_alg bench_cipher_opt[] = { #ifdef HAVE_IDEA { "-idea", BENCH_IDEA }, #endif - { NULL, 0} + { NULL, 0 } }; /* All recognized digest algorithm choosing command line options. */ static const bench_alg bench_digest_opt[] = { - { "-digest", -1 }, + { "-digest", 0xffffffff }, #ifndef NO_MD5 { "-md5", BENCH_MD5 }, #endif @@ -428,12 +456,12 @@ static const bench_alg bench_digest_opt[] = { #ifdef HAVE_BLAKE2S { "-blake2s", BENCH_BLAKE2S }, #endif - { NULL, 0} + { NULL, 0 } }; /* All recognized MAC algorithm choosing command line options. */ static const bench_alg bench_mac_opt[] = { - { "-mac", -1 }, + { "-mac", 0xffffffff }, #ifdef WOLFSSL_CMAC { "-cmac", BENCH_CMAC }, #endif @@ -461,12 +489,12 @@ static const bench_alg bench_mac_opt[] = { { "-pbkdf2", BENCH_PBKDF2 }, #endif #endif - { NULL, 0} + { NULL, 0 } }; /* All recognized asymmetric algorithm choosing command line options. */ static const bench_alg bench_asym_opt[] = { - { "-asym", -1 }, + { "-asym", 0xffffffff }, #ifndef NO_RSA #ifdef WOLFSSL_KEY_GEN { "-rsa-kg", BENCH_RSA_KEYGEN }, @@ -509,13 +537,25 @@ static const bench_alg bench_asym_opt[] = { { "-ed448-kg", BENCH_ED448_KEYGEN }, { "-ed448", BENCH_ED448_SIGN }, #endif - { NULL, 0} +#ifdef WOLFCRYPT_HAVE_ECCSI + { "-eccsi-kg", BENCH_ECCSI_KEYGEN }, + { "-eccsi-pair", BENCH_ECCSI_PAIRGEN }, + { "-eccsi-val", BENCH_ECCSI_VALIDATE }, + { "-eccsi", BENCH_ECCSI }, +#endif +#ifdef WOLFCRYPT_HAVE_SAKKE + { "-sakke-kg", BENCH_SAKKE_KEYGEN }, + { "-sakke-rsk", BENCH_SAKKE_RSKGEN }, + { "-sakke-val", BENCH_SAKKE_VALIDATE }, + { "-sakke", BENCH_SAKKE }, +#endif + { NULL, 0 } }; /* All recognized other cryptographic algorithm choosing command line options. */ static const bench_alg bench_other_opt[] = { - { "-other", -1 }, + { "-other", 0xffffffff }, #ifndef WC_NO_RNG { "-rng", BENCH_RNG }, #endif @@ -600,11 +640,11 @@ static const char* bench_result_words1[][4] = { defined(HAVE_ED25519) || defined(HAVE_CURVE448) || \ defined(HAVE_CURVE448_SHARED_SECRET) || defined(HAVE_ED448) -static const char* bench_desc_words[][9] = { - /* 0 1 2 3 4 5 6 7 8 */ - {"public", "private", "key gen", "agree" , "sign", "verify", "encryption", "decryption", NULL}, /* 0 English */ +static const char* bench_desc_words[][14] = { + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 */ + {"public", "private", "key gen", "agree" , "sign", "verify", "encryption", "decryption", "rsk gen", "encap", "derive", "valid", "pair gen", NULL}, /* 0 English */ #ifndef NO_MULTIBYTE_PRINT - {"公開鍵", "秘密鍵" ,"鍵生成" , "鍵共有" , "署名", "検証" , "暗号化" , "復号化" , NULL}, /* 1 Japanese */ + {"公開鍵", "秘密鍵" ,"鍵生成" , "鍵共有" , "署名", "検証" , "暗号化" , "復号化" , "rsk gen", "encap", "derive", "valid", "pair gen", NULL}, /* 1 Japanese */ #endif }; @@ -1914,6 +1954,44 @@ static void* benchmarks_do(void* args) bench_ed448KeySign(); #endif +#ifdef WOLFCRYPT_HAVE_ECCSI + #ifdef WOLFCRYPT_ECCSI_KMS + if (bench_all || (bench_asym_algs & BENCH_ECCSI_KEYGEN)) { + bench_eccsiKeyGen(); + } + if (bench_all || (bench_asym_algs & BENCH_ECCSI_PAIRGEN)) { + bench_eccsiPairGen(); + } + #endif + #ifdef WOLFCRYPT_ECCSI_CLIENT + if (bench_all || (bench_asym_algs & BENCH_ECCSI_VALIDATE)) { + bench_eccsiValidate(); + } + if (bench_all || (bench_asym_algs & BENCH_ECCSI)) { + bench_eccsi(); + } + #endif +#endif + +#ifdef WOLFCRYPT_HAVE_SAKKE + #ifdef WOLFCRYPT_SAKKE_KMS + if (bench_all || (bench_asym_algs & BENCH_SAKKE_KEYGEN)) { + bench_sakkeKeyGen(); + } + if (bench_all || (bench_asym_algs & BENCH_SAKKE_RSKGEN)) { + bench_sakkeRskGen(); + } + #endif + #ifdef WOLFCRYPT_SAKKE_CLIENT + if (bench_all || (bench_asym_algs & BENCH_SAKKE_VALIDATE)) { + bench_sakkeValidate(); + } + if (bench_all || (bench_asym_algs & BENCH_SAKKE)) { + bench_sakke(); + } + #endif +#endif + exit: /* free benchmark buffers */ XFREE(bench_plain, HEAP_HINT, DYNAMIC_TYPE_WOLF_BIGINT); @@ -5359,12 +5437,20 @@ void bench_ecc_curve(int curveId) void bench_eccMakeKey(int doAsync, int curveId) { int ret = 0, i, times, count, pending = 0; + int deviceID; int keySize; ecc_key genKey[BENCH_MAX_PENDING]; char name[BENCH_ECC_NAME_SZ]; double start; const char**desc = bench_desc_words[lng_index]; + +#ifdef WOLFSSL_ASYNC_CRYPT + deviceID = doAsync ? devId : INVALID_DEVID; +#else + deviceID = devId; +#endif + keySize = wc_ecc_get_curve_size_from_id(curveId); /* clear for done cleanup */ @@ -5382,8 +5468,7 @@ void bench_eccMakeKey(int doAsync, int curveId) ×, genTimes, &pending)) { wc_ecc_free(&genKey[i]); - ret = wc_ecc_init_ex(&genKey[i], HEAP_HINT, doAsync ? - devId : INVALID_DEVID); + ret = wc_ecc_init_ex(&genKey[i], HEAP_HINT, deviceID); if (ret < 0) { goto exit; } @@ -5416,6 +5501,7 @@ exit: void bench_ecc(int doAsync, int curveId) { int ret = 0, i, times, count, pending = 0; + int deviceID; int keySize; char name[BENCH_ECC_NAME_SZ]; ecc_key genKey[BENCH_MAX_PENDING]; @@ -5439,6 +5525,12 @@ void bench_ecc(int doAsync, int curveId) DECLARE_ARRAY(digest, byte, BENCH_MAX_PENDING, MAX_ECC_BYTES, HEAP_HINT); #endif +#ifdef WOLFSSL_ASYNC_CRYPT + deviceID = doAsync ? devId : INVALID_DEVID; +#else + deviceID = devId; +#endif + /* clear for done cleanup */ XMEMSET(&genKey, 0, sizeof(genKey)); #ifdef HAVE_ECC_DHE @@ -5449,8 +5541,7 @@ void bench_ecc(int doAsync, int curveId) /* init keys */ for (i = 0; i < BENCH_MAX_PENDING; i++) { /* setup an context for each key */ - if ((ret = wc_ecc_init_ex(&genKey[i], HEAP_HINT, - doAsync ? devId : INVALID_DEVID)) < 0) { + if ((ret = wc_ecc_init_ex(&genKey[i], HEAP_HINT, deviceID)) < 0) { goto exit; } ret = wc_ecc_make_key_ex(&gRng, keySize, &genKey[i], curveId); @@ -5462,7 +5553,7 @@ void bench_ecc(int doAsync, int curveId) } #ifdef HAVE_ECC_DHE - if ((ret = wc_ecc_init_ex(&genKey2[i], HEAP_HINT, INVALID_DEVID)) < 0) { + if ((ret = wc_ecc_init_ex(&genKey2[i], HEAP_HINT, deviceID)) < 0) { goto exit; } if ((ret = wc_ecc_make_key_ex(&gRng, keySize, &genKey2[i], @@ -6034,6 +6125,422 @@ exit_ed_verify: } #endif /* HAVE_ED448 */ +#ifdef WOLFCRYPT_HAVE_ECCSI +#ifdef WOLFCRYPT_ECCSI_KMS +void bench_eccsiKeyGen(void) +{ + EccsiKey genKey; + double start; + int i, count; + const char**desc = bench_desc_words[lng_index]; + int ret; + + /* Key Gen */ + bench_stats_start(&count, &start); + do { + for (i = 0; i < genTimes; i++) { + wc_InitEccsiKey(&genKey, NULL, INVALID_DEVID); + ret = wc_MakeEccsiKey(&genKey, &gRng); + if (ret != 0) { + printf("wc_MakeEccsiKey failed: %d\n", ret); + break; + } + wc_FreeEccsiKey(&genKey); + } + count += i; + } while (bench_stats_sym_check(start)); + bench_stats_asym_finish("ECCSI", 256, desc[2], 0, count, start, 0); +} + +void bench_eccsiPairGen(void) +{ + EccsiKey genKey; + double start; + int i, count; + const char**desc = bench_desc_words[lng_index]; + mp_int ssk; + ecc_point* pvt; + byte id[] = { 0x01, 0x23, 0x34, 0x45 }; + int ret; + + mp_init(&ssk); + pvt = wc_ecc_new_point(); + wc_InitEccsiKey(&genKey, NULL, INVALID_DEVID); + (void)wc_MakeEccsiKey(&genKey, &gRng); + + /* RSK Gen */ + bench_stats_start(&count, &start); + do { + for (i = 0; i < genTimes; i++) { + ret = wc_MakeEccsiPair(&genKey, &gRng, WC_HASH_TYPE_SHA256, id, + sizeof(id), &ssk, pvt); + if (ret != 0) { + printf("wc_MakeEccsiPair failed: %d\n", ret); + break; + } + } + count += i; + } while (bench_stats_sym_check(start)); + bench_stats_asym_finish("ECCSI", 256, desc[12], 0, count, start, 0); + + wc_FreeEccsiKey(&genKey); + wc_ecc_del_point(pvt); + mp_free(&ssk); +} +#endif + +#ifdef WOLFCRYPT_ECCSI_CLIENT +void bench_eccsiValidate(void) +{ + EccsiKey genKey; + double start; + int i, count; + const char**desc = bench_desc_words[lng_index]; + mp_int ssk; + ecc_point* pvt; + byte id[] = { 0x01, 0x23, 0x34, 0x45 }; + int valid; + int ret; + + mp_init(&ssk); + pvt = wc_ecc_new_point(); + wc_InitEccsiKey(&genKey, NULL, INVALID_DEVID); + (void)wc_MakeEccsiKey(&genKey, &gRng); + (void)wc_MakeEccsiPair(&genKey, &gRng, WC_HASH_TYPE_SHA256, id, sizeof(id), + &ssk, pvt); + + /* Validation of RSK */ + bench_stats_start(&count, &start); + do { + for (i = 0; i < genTimes; i++) { + ret = wc_ValidateEccsiPair(&genKey, WC_HASH_TYPE_SHA256, id, + sizeof(id), &ssk, pvt, &valid); + if (ret != 0 || !valid) { + printf("wc_ValidateEccsiPair failed: %d (valid=%d))\n", ret, + valid); + break; + } + } + count += i; + } while (bench_stats_sym_check(start)); + bench_stats_asym_finish("ECCSI", 256, desc[11], 0, count, start, 0); + + wc_FreeEccsiKey(&genKey); + wc_ecc_del_point(pvt); + mp_free(&ssk); +} + +void bench_eccsi(void) +{ + EccsiKey genKey; + double start; + int i, count; + const char**desc = bench_desc_words[lng_index]; + mp_int ssk; + ecc_point* pvt; + byte id[] = { 0x01, 0x23, 0x34, 0x45 }; + byte msg[] = { 0x01, 0x23, 0x34, 0x45 }; + byte hash[WC_SHA256_DIGEST_SIZE]; + byte hashSz = (byte)sizeof(hash); + byte sig[257]; + word32 sigSz = sizeof(sig); + int ret; + int verified; + + mp_init(&ssk); + pvt = wc_ecc_new_point(); + (void)wc_InitEccsiKey(&genKey, NULL, INVALID_DEVID); + (void)wc_MakeEccsiKey(&genKey, &gRng); + (void)wc_MakeEccsiPair(&genKey, &gRng, WC_HASH_TYPE_SHA256, id, sizeof(id), + &ssk, pvt); + (void)wc_HashEccsiId(&genKey, WC_HASH_TYPE_SHA256, id, sizeof(id), pvt, + hash, &hashSz); + (void)wc_SetEccsiHash(&genKey, hash, hashSz); + (void)wc_SetEccsiPair(&genKey, &ssk, pvt); + + /* Encapsulate */ + bench_stats_start(&count, &start); + do { + for (i = 0; i < genTimes; i++) { + ret = wc_SignEccsiHash(&genKey, &gRng, WC_HASH_TYPE_SHA256, msg, + sizeof(msg), sig, &sigSz); + if (ret != 0) { + printf("wc_SignEccsiHash failed: %d\n", ret); + break; + } + } + count += i; + } while (bench_stats_sym_check(start)); + bench_stats_asym_finish("ECCSI", 256, desc[4], 0, count, start, 0); + + /* Derive */ + bench_stats_start(&count, &start); + do { + for (i = 0; i < genTimes; i++) { + ret = wc_VerifyEccsiHash(&genKey, WC_HASH_TYPE_SHA256, msg, + sizeof(msg), sig, sigSz, &verified); + if (ret != 0 || !verified) { + printf("wc_VerifyEccsiHash failed: %d (verified: %d)\n", ret, + verified); + break; + } + } + count += i; + } while (bench_stats_sym_check(start)); + bench_stats_asym_finish("ECCSI", 256, desc[5], 0, count, start, 0); + + wc_FreeEccsiKey(&genKey); + wc_ecc_del_point(pvt); +} +#endif /* WOLFCRYPT_ECCSI_CLIENT */ +#endif /* WOLFCRYPT_HAVE_ECCSI */ + +#ifdef WOLFCRYPT_HAVE_SAKKE +#ifdef WOLFCRYPT_SAKKE_KMS +void bench_sakkeKeyGen(void) +{ + SakkeKey genKey; + double start; + int i, count; + const char**desc = bench_desc_words[lng_index]; + int ret; + + /* Key Gen */ + bench_stats_start(&count, &start); + do { + for (i = 0; i < genTimes; i++) { + wc_InitSakkeKey_ex(&genKey, 128, ECC_SAKKE_1, NULL, INVALID_DEVID); + ret = wc_MakeSakkeKey(&genKey, &gRng); + if (ret != 0) { + printf("wc_MakeSakkeKey failed: %d\n", ret); + break; + } + wc_FreeSakkeKey(&genKey); + } + count += i; + } while (bench_stats_sym_check(start)); + bench_stats_asym_finish("SAKKE", 1024, desc[2], 0, count, start, 0); +} + +void bench_sakkeRskGen(void) +{ + SakkeKey genKey; + double start; + int i, count; + const char**desc = bench_desc_words[lng_index]; + ecc_point* rsk; + byte id[] = { 0x01, 0x23, 0x34, 0x45 }; + int ret; + + rsk = wc_ecc_new_point(); + wc_InitSakkeKey_ex(&genKey, 128, ECC_SAKKE_1, NULL, INVALID_DEVID); + (void)wc_MakeSakkeKey(&genKey, &gRng); + + /* RSK Gen */ + bench_stats_start(&count, &start); + do { + for (i = 0; i < genTimes; i++) { + ret = wc_MakeSakkeRsk(&genKey, id, sizeof(id), rsk); + if (ret != 0) { + printf("wc_MakeSakkeRsk failed: %d\n", ret); + break; + } + } + count += i; + } while (bench_stats_sym_check(start)); + bench_stats_asym_finish("SAKKE", 1024, desc[8], 0, count, start, 0); + + wc_FreeSakkeKey(&genKey); + wc_ecc_del_point(rsk); +} +#endif + +#ifdef WOLFCRYPT_SAKKE_CLIENT +void bench_sakkeValidate(void) +{ + SakkeKey genKey; + double start; + int i, count; + const char**desc = bench_desc_words[lng_index]; + ecc_point* rsk; + byte id[] = { 0x01, 0x23, 0x34, 0x45 }; + int valid; + int ret; + + rsk = wc_ecc_new_point(); + (void)wc_InitSakkeKey_ex(&genKey, 128, ECC_SAKKE_1, NULL, INVALID_DEVID); + (void)wc_MakeSakkeKey(&genKey, &gRng); + (void)wc_MakeSakkeRsk(&genKey, id, sizeof(id), rsk); + (void)wc_ValidateSakkeRsk(&genKey, id, sizeof(id), rsk, &valid); + + /* Validation of RSK */ + bench_stats_start(&count, &start); + do { + for (i = 0; i < genTimes; i++) { + ret = wc_ValidateSakkeRsk(&genKey, id, sizeof(id), rsk, &valid); + if (ret != 0 || !valid) { + printf("wc_ValidateSakkeRsk failed: %d (valid=%d))\n", ret, + valid); + break; + } + } + count += i; + } while (bench_stats_sym_check(start)); + bench_stats_asym_finish("SAKKE", 1024, desc[11], 0, count, start, 0); + + wc_FreeSakkeKey(&genKey); + wc_ecc_del_point(rsk); +} + +void bench_sakke(void) +{ + SakkeKey genKey; + double start; + int i, count; + const char**desc = bench_desc_words[lng_index]; + ecc_point* rsk; + byte id[] = { 0x01, 0x23, 0x34, 0x45 }; + byte ssv[] = { 0x01, 0x23, 0x34, 0x45 }; + byte derSSV[sizeof(ssv)]; + byte auth[257]; + word16 authSz = sizeof(auth); + int ret = 0; + byte* table = NULL; + word32 len = 0; + byte* iTable = NULL; + word32 iTableLen = 0; + + rsk = wc_ecc_new_point(); + (void)wc_InitSakkeKey_ex(&genKey, 128, ECC_SAKKE_1, NULL, INVALID_DEVID); + (void)wc_MakeSakkeKey(&genKey, &gRng); + (void)wc_MakeSakkeRsk(&genKey, id, sizeof(id), rsk); + (void)wc_SetSakkeRsk(&genKey, rsk, NULL, 0); + (void)wc_SetSakkeIdentity(&genKey, id, sizeof(id)); + + /* Encapsulate */ + bench_stats_start(&count, &start); + do { + for (i = 0; i < genTimes; i++) { + ret = wc_MakeSakkeEncapsulatedSSV(&genKey, WC_HASH_TYPE_SHA256, ssv, + sizeof(ssv), auth, &authSz); + if (ret != 0) { + printf("wc_MakeSakkeEncapsulatedSSV failed: %d\n", ret); + break; + } + } + count += i; + } while (bench_stats_sym_check(start)); + bench_stats_asym_finish("SAKKE", 1024, desc[9], 0, count, start, 0); + + /* Derive */ + bench_stats_start(&count, &start); + do { + for (i = 0; i < genTimes; i++) { + XMEMCPY(derSSV, ssv, sizeof(ssv)); + ret = wc_DeriveSakkeSSV(&genKey, WC_HASH_TYPE_SHA256, derSSV, + sizeof(derSSV), auth, authSz); + if (ret != 0) { + printf("wc_DeriveSakkeSSV failed: %d\n", ret); + break; + } + } + if (ret != 0) break; + count += i; + } while (bench_stats_sym_check(start)); + bench_stats_asym_finish("SAKKE", 1024, desc[10], 0, count, start, 0); + + /* Calculate Point I and generate table. */ + (void)wc_MakeSakkePointI(&genKey, id, sizeof(id)); + iTableLen = 0; + (void)wc_GenerateSakkePointITable(&genKey, NULL, &iTableLen); + if (iTableLen != 0) { + iTable = (byte*)XMALLOC(iTableLen, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + (void)wc_GenerateSakkePointITable(&genKey, iTable, &iTableLen); + } + + /* Encapsulate with Point I table */ + bench_stats_start(&count, &start); + do { + for (i = 0; i < genTimes; i++) { + ret = wc_MakeSakkeEncapsulatedSSV(&genKey, WC_HASH_TYPE_SHA256, ssv, + sizeof(ssv), auth, &authSz); + if (ret != 0) { + printf("wc_MakeSakkeEncapsulatedSSV failed: %d\n", ret); + break; + } + } + count += i; + } while (bench_stats_sym_check(start)); + bench_stats_asym_finish("SAKKE", 1024, desc[9], 0, count, start, 0); + + (void)wc_SetSakkeRsk(&genKey, rsk, table, len); + + /* Derive with Point I table */ + bench_stats_start(&count, &start); + do { + for (i = 0; i < genTimes; i++) { + XMEMCPY(derSSV, ssv, sizeof(ssv)); + ret = wc_DeriveSakkeSSV(&genKey, WC_HASH_TYPE_SHA256, derSSV, + sizeof(derSSV), auth, authSz); + if (ret != 0) { + printf("wc_DeriveSakkeSSV failed: %d\n", ret); + break; + } + } + if (ret != 0) break; + count += i; + } while (bench_stats_sym_check(start)); + bench_stats_asym_finish("SAKKE", 1024, desc[10], 0, count, start, 0); + + len = 0; + wc_GenerateSakkeRskTable(&genKey, rsk, NULL, &len); + if (len > 0) { + table = (byte*)XMALLOC(len, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + wc_GenerateSakkeRskTable(&genKey, rsk, table, &len); + } + (void)wc_SetSakkeRsk(&genKey, rsk, table, len); + + /* Derive with Point I table and RSK table */ + bench_stats_start(&count, &start); + do { + for (i = 0; i < genTimes; i++) { + XMEMCPY(derSSV, ssv, sizeof(ssv)); + ret = wc_DeriveSakkeSSV(&genKey, WC_HASH_TYPE_SHA256, derSSV, + sizeof(derSSV), auth, authSz); + if (ret != 0) { + printf("wc_DeriveSakkeSSV failed: %d\n", ret); + break; + } + } + if (ret != 0) break; + count += i; + } while (bench_stats_sym_check(start)); + bench_stats_asym_finish("SAKKE", 1024, desc[10], 0, count, start, 0); + + wc_ClearSakkePointITable(&genKey); + /* Derive with RSK table */ + bench_stats_start(&count, &start); + do { + for (i = 0; i < genTimes; i++) { + XMEMCPY(derSSV, ssv, sizeof(ssv)); + ret = wc_DeriveSakkeSSV(&genKey, WC_HASH_TYPE_SHA256, derSSV, + sizeof(derSSV), auth, authSz); + if (ret != 0) { + printf("wc_DeriveSakkeSSV failed: %d\n", ret); + break; + } + } + if (ret != 0) break; + count += i; + } while (bench_stats_sym_check(start)); + bench_stats_asym_finish("SAKKE", 1024, desc[10], 0, count, start, 0); + + wc_FreeSakkeKey(&genKey); + wc_ecc_del_point(rsk); +} +#endif /* WOLFCRYPT_SAKKE_CLIENT */ +#endif /* WOLFCRYPT_HAVE_SAKKE */ + #ifndef HAVE_STACK_SIZE #if defined(_WIN32) && !defined(INTIME_RTOS) diff --git a/wolfcrypt/benchmark/benchmark.h b/wolfcrypt/benchmark/benchmark.h index 23330cbc9..e9b13a410 100644 --- a/wolfcrypt/benchmark/benchmark.h +++ b/wolfcrypt/benchmark/benchmark.h @@ -1,6 +1,6 @@ /* wolfcrypt/benchmark/benchmark.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -94,6 +94,14 @@ void bench_curve448KeyGen(void); void bench_curve448KeyAgree(void); void bench_ed448KeyGen(void); void bench_ed448KeySign(void); +void bench_eccsiKeyGen(void); +void bench_eccsiPairGen(void); +void bench_eccsiValidate(void); +void bench_eccsi(void); +void bench_sakkeKeyGen(void); +void bench_sakkeRskGen(void); +void bench_sakkeValidate(void); +void bench_sakke(void); void bench_ntru(void); void bench_ntruKeyGen(void); void bench_rng(void); diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 4bb011dfd..b1c0d6a1f 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -1,6 +1,6 @@ /* aes.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -4355,12 +4355,12 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) if (!((len == 16) || (len == 24) || (len == 32))) return BAD_FUNC_ARG; + if (aes == NULL) + return BAD_FUNC_ARG; #ifdef OPENSSL_EXTRA - if (aes != NULL) { - XMEMSET(aes->aadH, 0, sizeof(aes->aadH)); - aes->aadLen = 0; - } + XMEMSET(aes->aadH, 0, sizeof(aes->aadH)); + aes->aadLen = 0; #endif XMEMSET(iv, 0, AES_BLOCK_SIZE); ret = wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION); @@ -5262,7 +5262,7 @@ static void AES_GCM_decrypt(const unsigned char *in, unsigned char *out, else aes_gcm_calc_iv(KEY, ivec, ibytes, nr, H, Y, T); - for (i=0; i 0) { + XMEMCPY(output + idx, bitString, bitStringSz); + idx += bitStringSz; + } /* y */ XMEMCPY(output + idx, y, ySz); idx += ySz; @@ -6892,7 +6929,7 @@ static word32 SetDigest(const byte* digest, word32 digSz, byte* output) static word32 BytePrecision(word32 value) { word32 i; - for (i = sizeof(value); i; --i) + for (i = (word32)sizeof(value); i; --i) if (value >> ((i - 1) * WOLFSSL_BIT_SIZE)) break; @@ -7728,6 +7765,9 @@ static int ConfirmSignature(SignatureCtx* sigCtx, break; } /* SIG_STATE_CHECK */ + + default: + break; } /* switch (sigCtx->state) */ exit_cs: @@ -7881,6 +7921,8 @@ static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert) #endif /* !WOLFSSL_NO_ASN_STRICT */ break; } + default: + break; }; /* switch */ base = base->next; } @@ -7960,6 +8002,8 @@ static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert) } break; } + default: + break; } /* switch */ base = base->next; } @@ -8148,9 +8192,8 @@ static int DecodeAltNames(const byte* input, int sz, DecodedCert* cert) break; } if (input[idx + i] == '/') { - i = strLen; /* error, found relative path since '/' was - * encountered before ':'. Returning error - * value in next if statement. */ + WOLFSSL_MSG("\tAlt Name must be absolute URI"); + return ASN_ALT_NAME_E; } } @@ -8678,6 +8721,8 @@ static int DecodeExtKeyUsage(const byte* input, int sz, DecodedCert* cert) case EKU_OCSP_SIGN_OID: cert->extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN; break; + default: + break; } #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) @@ -10408,7 +10453,8 @@ wcchar END_PUB_KEY = "-----END PUBLIC KEY-----"; const int pem_struct_min_sz = XSTR_SIZEOF("-----BEGIN X509 CRL-----" "-----END X509 CRL-----"); -static WC_INLINE char* SkipEndOfLineChars(char* line, const char* endOfLine) +static WC_INLINE const char* SkipEndOfLineChars(const char* line, + const char* endOfLine) { /* eat end of line characters */ while (line < endOfLine && @@ -10588,18 +10634,19 @@ int wc_EncryptedInfoGet(EncryptedInfo* info, const char* cipherInfo) return ret; } -int wc_EncryptedInfoParse(EncryptedInfo* info, char** pBuffer, size_t bufSz) +int wc_EncryptedInfoParse(EncryptedInfo* info, const char** pBuffer, + size_t bufSz) { - int err = 0; - char* bufferStart; - char* bufferEnd; - char* line; - word32 lineSz; - char* finish; - word32 finishSz; - char* start = NULL; - word32 startSz; - char* newline = NULL; + int err = 0; + const char* bufferStart; + const char* bufferEnd; + char* line; + word32 lineSz; + char* finish; + word32 finishSz; + char* start = NULL; + word32 startSz; + const char* newline = NULL; if (info == NULL || pBuffer == NULL || bufSz == 0) return BAD_FUNC_ARG; @@ -10868,10 +10915,10 @@ int PemToDer(const unsigned char* buff, long longSz, int type, { const char* header = NULL; const char* footer = NULL; - char* headerEnd; - char* footerEnd; - char* consumedEnd; - char* bufferEnd = (char*)(buff + longSz); + const char* headerEnd; + const char* footerEnd; + const char* consumedEnd; + const char* bufferEnd = (const char*)(buff + longSz); long neededSz; int ret = 0; int sz = (int)longSz; @@ -10944,7 +10991,7 @@ int PemToDer(const unsigned char* buff, long longSz, int type, if (!headerEnd) { #ifdef OPENSSL_EXTRA if (type == PRIVATEKEY_TYPE) { - char* beginEnd; + const char* beginEnd; int endLen; /* see if there is a -----BEGIN * PRIVATE KEY----- header */ headerEnd = XSTRNSTR((char*)buff, PRIV_KEY_SUFFIX, sz); @@ -11059,7 +11106,7 @@ int PemToDer(const unsigned char* buff, long longSz, int type, } if (info) - info->consumed = (long)(consumedEnd - (char*)buff); + info->consumed = (long)(consumedEnd - (const char*)buff); /* set up der buffer */ neededSz = (long)(footerEnd - headerEnd); @@ -12175,7 +12222,7 @@ int wc_EccPublicKeyToDer(ecc_key* key, byte* output, word32 inLen, #if defined(HAVE_SELFTEST) || defined(HAVE_FIPS) /* older version of ecc.c can not handle dp being NULL */ - if (key != NULL && key->dp == NULL) { + if (key->dp == NULL) { keySz = 1 + 2 * MAX_ECC_BYTES; ret = LENGTH_ONLY_E; } @@ -16432,7 +16479,7 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx, #if defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT) /* build DER formatted ECC key, include optional public key if requested, * return length on success, negative on error */ -static int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 inLen, +static int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 *inLen, int pubIn) { byte curve[MAX_ALGO_SZ+2]; @@ -16452,7 +16499,7 @@ static int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 inLen, word32 idx = 0, prvidx = 0, pubidx = 0, curveidx = 0; word32 seqSz, privSz, pubSz = ECC_BUFSIZE; - if (key == NULL || output == NULL || inLen == 0) + if (key == NULL || (output == NULL && inLen == NULL)) return BAD_FUNC_ARG; /* curve */ @@ -16486,7 +16533,12 @@ static int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 inLen, return BUFFER_E; } #endif - prvidx += SetOctetString8Bit(privSz, &prv[prvidx]); + if (privSz < ASN_LONG_LENGTH) { + prvidx += SetOctetString8Bit(privSz, &prv[prvidx]); + } + else { + prvidx += SetOctetString(privSz, &prv[prvidx]); + } ret = wc_ecc_export_private_only(key, prv + prvidx, &privSz); if (ret < 0) { #ifndef WOLFSSL_NO_MALLOC @@ -16543,7 +16595,15 @@ static int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 inLen, seqSz = SetSequence(verSz + prvidx + pubidx + curveidx, seq); totalSz = prvidx + pubidx + curveidx + verSz + seqSz; - if (totalSz > (int)inLen) { + if (output == NULL) { + *inLen = totalSz; + XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (pubIn) { + XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + } + return LENGTH_ONLY_E; + } + if (inLen != NULL && totalSz > (int)*inLen) { #ifndef WOLFSSL_NO_MALLOC XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER); if (pubIn) { @@ -16589,17 +16649,33 @@ static int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 inLen, * length on success else < 0 */ int wc_EccKeyToDer(ecc_key* key, byte* output, word32 inLen) { - return wc_BuildEccKeyDer(key, output, inLen, 1); + return wc_BuildEccKeyDer(key, output, &inLen, 1); } +/* Write only private ecc key to DER format, + * length on success else < 0 */ +int wc_EccKeyDerSize(ecc_key* key, int pub) +{ + word32 sz = 0; + int ret; + + ret = wc_BuildEccKeyDer(key, NULL, &sz, pub); + + if (ret != LENGTH_ONLY_E) { + return ret; + } + return sz; + } /* Write only private ecc key to DER format, * length on success else < 0 */ int wc_EccPrivateKeyToDer(ecc_key* key, byte* output, word32 inLen) { - return wc_BuildEccKeyDer(key, output, inLen, 0); + return wc_BuildEccKeyDer(key, output, &inLen, 0); } + + #ifdef HAVE_PKCS8 /* Write only private ecc key or both private and public parts to unencrypted * PKCS#8 format. @@ -16621,6 +16697,7 @@ static int eccToPKCS8(ecc_key* key, byte* output, word32* outLen, #else byte* tmpDer = NULL; #endif + word32 sz = ECC_BUFSIZE; if (key == NULL || key->dp == NULL || outLen == NULL) return BAD_FUNC_ARG; @@ -16639,7 +16716,7 @@ static int eccToPKCS8(ecc_key* key, byte* output, word32* outLen, #endif XMEMSET(tmpDer, 0, ECC_BUFSIZE); - tmpDerSz = wc_BuildEccKeyDer(key, tmpDer, ECC_BUFSIZE, includePublic); + tmpDerSz = wc_BuildEccKeyDer(key, tmpDer, &sz, includePublic); if (tmpDerSz < 0) { #ifndef WOLFSSL_NO_MALLOC XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER); diff --git a/wolfcrypt/src/blake2b.c b/wolfcrypt/src/blake2b.c index 1d89fbe78..24f54cfd7 100644 --- a/wolfcrypt/src/blake2b.c +++ b/wolfcrypt/src/blake2b.c @@ -12,7 +12,7 @@ */ /* blake2b.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/blake2s.c b/wolfcrypt/src/blake2s.c index 7c74cac15..30ae6c038 100644 --- a/wolfcrypt/src/blake2s.c +++ b/wolfcrypt/src/blake2s.c @@ -12,7 +12,7 @@ */ /* blake2s.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/camellia.c b/wolfcrypt/src/camellia.c index 89ee6617a..a7cb268b7 100644 --- a/wolfcrypt/src/camellia.c +++ b/wolfcrypt/src/camellia.c @@ -27,7 +27,7 @@ /* camellia.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/chacha.c b/wolfcrypt/src/chacha.c index 32feccf86..464a20e6a 100644 --- a/wolfcrypt/src/chacha.c +++ b/wolfcrypt/src/chacha.c @@ -1,6 +1,6 @@ /* chacha.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/chacha20_poly1305.c b/wolfcrypt/src/chacha20_poly1305.c index 86edc0b97..417b3e226 100644 --- a/wolfcrypt/src/chacha20_poly1305.c +++ b/wolfcrypt/src/chacha20_poly1305.c @@ -1,6 +1,6 @@ /* chacha.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/chacha_asm.S b/wolfcrypt/src/chacha_asm.S index f5f6989fd..61ac921ac 100644 --- a/wolfcrypt/src/chacha_asm.S +++ b/wolfcrypt/src/chacha_asm.S @@ -1,6 +1,6 @@ /* chacha_asm * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/cmac.c b/wolfcrypt/src/cmac.c index 20b4e61bb..5f5a1f8b4 100644 --- a/wolfcrypt/src/cmac.c +++ b/wolfcrypt/src/cmac.c @@ -1,6 +1,6 @@ /* cmac.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/coding.c b/wolfcrypt/src/coding.c index 8959397b6..822c5e48f 100644 --- a/wolfcrypt/src/coding.c +++ b/wolfcrypt/src/coding.c @@ -1,6 +1,6 @@ /* coding.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/compress.c b/wolfcrypt/src/compress.c index adebbf458..36f2931ca 100644 --- a/wolfcrypt/src/compress.c +++ b/wolfcrypt/src/compress.c @@ -1,6 +1,6 @@ /* compress.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/cpuid.c b/wolfcrypt/src/cpuid.c index 006da8cf7..1214ba429 100644 --- a/wolfcrypt/src/cpuid.c +++ b/wolfcrypt/src/cpuid.c @@ -1,6 +1,6 @@ /* cpuid.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index 683d0cd00..e15706108 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -1,6 +1,6 @@ /* cryptocb.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -15,7 +15,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ /* This framework provides a central place for crypto hardware integration diff --git a/wolfcrypt/src/curve25519.c b/wolfcrypt/src/curve25519.c index 8d086bed5..a7d67b2cd 100644 --- a/wolfcrypt/src/curve25519.c +++ b/wolfcrypt/src/curve25519.c @@ -1,6 +1,6 @@ /* curve25519.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/curve448.c b/wolfcrypt/src/curve448.c index 135f2380e..e926351fd 100644 --- a/wolfcrypt/src/curve448.c +++ b/wolfcrypt/src/curve448.c @@ -1,6 +1,6 @@ /* curve448.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/des3.c b/wolfcrypt/src/des3.c index a6548dc5d..97ead9717 100644 --- a/wolfcrypt/src/des3.c +++ b/wolfcrypt/src/des3.c @@ -1,6 +1,6 @@ /* des3.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/dh.c b/wolfcrypt/src/dh.c index 245765c02..c7803c33b 100644 --- a/wolfcrypt/src/dh.c +++ b/wolfcrypt/src/dh.c @@ -1,6 +1,6 @@ /* dh.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/dsa.c b/wolfcrypt/src/dsa.c index dbfa010ef..53a8d6099 100644 --- a/wolfcrypt/src/dsa.c +++ b/wolfcrypt/src/dsa.c @@ -1,6 +1,6 @@ /* dsa.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index deb2861fc..696da3eb1 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -1,6 +1,6 @@ /* ecc.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -56,9 +56,9 @@ Possible ECC enable options: * WOLFSSL_ECC_CURVE_STATIC: default off (on for windows) For the ECC curve paramaters `ecc_set_type` use fixed array for hex string - * WC_ECC_NONBLOCK: Enable non-blocking support for sign/verify. + * WC_ECC_NONBLOCK: Enable non-blocking support for sign/verify. Requires SP with WOLFSSL_SP_NONBLOCK - * WC_ECC_NONBLOCK_ONLY Enable the non-blocking function only, no fall-back to + * WC_ECC_NONBLOCK_ONLY Enable the non-blocking function only, no fall-back to normal blocking API's * WOLFSSL_ECDSA_SET_K: Enables the setting of the 'k' value to use during ECDSA * signing. If the value is invalid, a new random 'k' is @@ -1138,6 +1138,26 @@ const ecc_set_type ecc_sets[] = { }, #endif /* !NO_ECC_SECP */ #endif /* ECC521 */ +#ifdef WOLFCRYPT_HAVE_SAKKE + { + 128, + ECC_SAKKE_1, + "SAKKE1", + "997ABB1F0A563FDA65C61198DAD0657A416C0CE19CB48261BE9AE358B3E01A2EF40AAB27E2FC0F1B228730D531A59CB0E791B39FF7C88A19356D27F4A666A6D0E26C6487326B4CD4512AC5CD65681CE1B6AFF4A831852A82A7CF3C521C3C09AA9F94D6AF56971F1FFCE3E82389857DB080C5DF10AC7ACE87666D807AFEA85FEB", + "997ABB1F0A563FDA65C61198DAD0657A416C0CE19CB48261BE9AE358B3E01A2EF40AAB27E2FC0F1B228730D531A59CB0E791B39FF7C88A19356D27F4A666A6D0E26C6487326B4CD4512AC5CD65681CE1B6AFF4A831852A82A7CF3C521C3C09AA9F94D6AF56971F1FFCE3E82389857DB080C5DF10AC7ACE87666D807AFEA85FE8", + "0", + "265EAEC7C2958FF69971846636B4195E905B0338672D20986FA6B8D62CF8068BBD02AAC9F8BF03C6C8A1CC354C69672C39E46CE7FDF222864D5B49FD2999A9B4389B1921CC9AD335144AB173595A07386DABFD2A0C614AA0A9F3CF14870F026AA7E535ABD5A5C7C7FF38FA08E2615F6C203177C42B1EB3A1D99B601EBFAA17FB", + "53FC09EE332C29AD0A7990053ED9B52A2B1A2FD60AEC69C698B2F204B6FF7CBFB5EDB6C0F6CE2308AB10DB9030B09E1043D5F22CDB9DFA55718BD9E7406CE8909760AF765DD5BCCB337C86548B72F2E1A702C3397A60DE74A7C1514DBA66910DD5CFB4CC80728D87EE9163A5B63F73EC80EC46C4967E0979880DC8ABEAE63895", + "0A8249063F6009F1F9F1F0533634A135D3E82016029906963D778D821E141178F5EA69F4654EC2B9E7F7F5E5F0DE55F66B598CCF9A140B2E416CFF0CA9E032B970DAE117AD547C6CCAD696B5B7652FE0AC6F1E80164AA989492D979FC5A4D5F213515AD7E9CB99A980BDAD5AD5BB4636ADB9B5706A67DCDE75573FD71BEF16D7", + #ifndef WOLFSSL_ECC_CURVE_STATIC + NULL, 0, + #else + {0}, 0, + #endif + 0, + 4, + }, +#endif #if defined(WOLFSSL_CUSTOM_CURVES) && defined(ECC_CACHE_CURVE) /* place holder for custom curve index for cache */ { @@ -1332,7 +1352,7 @@ static void wc_ecc_curve_free(ecc_curve_spec* curve) } } -static int wc_ecc_curve_cache_load_item(ecc_curve_spec* curve, const char* src, +static int wc_ecc_curve_cache_load_item(ecc_curve_spec* curve, const char* src, mp_int** dst, byte mask) { int err; @@ -2491,8 +2511,8 @@ int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp) #define WINSIZE 4 #define M_POINTS 8 -static int ecc_mulmod(mp_int* k, ecc_point* tG, ecc_point* R, ecc_point** M, - mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng) +static int ecc_mulmod(const mp_int* k, ecc_point* tG, ecc_point* R, + ecc_point** M, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng) { int err = MP_OKAY; int i; @@ -2712,8 +2732,8 @@ static int wc_ecc_gen_z(WC_RNG* rng, int size, ecc_point* p, * * Assumes: k < order. */ -static int ecc_mulmod(mp_int* k, ecc_point* P, ecc_point* Q, ecc_point** R, - mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng) +static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q, + ecc_point** R, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng) { int err = MP_OKAY; int bytes = (mp_count_bits(modulus) + 7) / 8; @@ -2723,6 +2743,7 @@ static int ecc_mulmod(mp_int* k, ecc_point* P, ecc_point* Q, ecc_point** R, int t = 0; mp_digit b; mp_digit v = 0; + mp_int* kt = R[2]->x; #ifndef WC_NO_CACHE_RESISTANT /* First bit always 1 (fix at end) and swap equals first bit */ int swap = 1; @@ -2759,12 +2780,15 @@ static int ecc_mulmod(mp_int* k, ecc_point* P, ecc_point* Q, ecc_point** R, if (cnt > t) { cnt = t; } - err = mp_grow(k, modulus->used + 1); + err = mp_copy(k, kt); + } + if (err == MP_OKAY) { + err = mp_grow(kt, modulus->used + 1); } /* Step 2: for j = 1 to t-1 do */ for (i = 1; (err == MP_OKAY) && (i < t); i++) { if (--cnt == 0) { - v = k->dp[j++]; + v = kt->dp[j++]; cnt = DIGIT_BIT; } @@ -2968,10 +2992,11 @@ static void ecc_key_tmp_final(ecc_key* key, void* heap) return MP_OKAY on success */ #ifdef FP_ECC -static int normal_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, - mp_int* modulus, WC_RNG* rng, int map, void* heap) +static int normal_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R, + mp_int* a, mp_int* modulus, WC_RNG* rng, int map, + void* heap) #else -int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, +int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, mp_int* modulus, int map, void* heap) #endif #if !defined(WOLFSSL_SP_MATH) @@ -3099,7 +3124,7 @@ exit: (1==map, 0 == leave in projective) return MP_OKAY on success */ -int wc_ecc_mulmod_ex2(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, +int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, mp_int* modulus, mp_int* order, WC_RNG* rng, int map, void* heap) #if !defined(WOLFSSL_SP_MATH) @@ -3177,7 +3202,7 @@ int wc_ecc_mulmod_ex2(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, if (err == MP_OKAY) err = mp_sub_d(order, 1, &t); if (err == MP_OKAY) { - int kIsMinusOne = (mp_cmp(k, &t) == MP_EQ); + int kIsMinusOne = (mp_cmp((mp_int*)k, &t) == MP_EQ); err = mp_cond_copy(tG->x, kIsMinusOne, R->x); if (err == 0) { err = mp_sub(modulus, tG->y, &t); @@ -3256,7 +3281,7 @@ exit: otherwise it's left in jacobian-montgomery form return MP_OKAY if successful */ -int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, +int wc_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, mp_int* modulus, int map) { return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, NULL); @@ -3330,11 +3355,21 @@ void wc_ecc_del_point(ecc_point* p) } +void wc_ecc_forcezero_point(ecc_point* p) +{ + if (p != NULL) { + mp_forcezero(p->x); + mp_forcezero(p->y); + mp_forcezero(p->z); + } +} + + /** Copy the value of a point to an other one p The point to copy r The created point */ -int wc_ecc_copy_point(ecc_point* p, ecc_point *r) +int wc_ecc_copy_point(const ecc_point* p, ecc_point *r) { int ret; @@ -3982,7 +4017,7 @@ static int wc_ecc_shared_secret_gen_async(ecc_key* private_key, int err; #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA) - if (private_key->dp + if (private_key->dp #ifdef WOLFSSL_CUSTOM_CURVES && private_key->dp->id != ECC_CURVE_CUSTOM #endif @@ -4223,7 +4258,7 @@ int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order) /* load random buffer data into k */ if (err == 0) - err = mp_read_unsigned_bin(k, (byte*)buf, size); + err = mp_read_unsigned_bin(k, buf, size); /* the key should be smaller than the order of base point */ if (err == MP_OKAY) { @@ -5226,6 +5261,152 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, } #elif !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ !defined(WOLFSSL_CRYPTOCELL) +#ifndef WOLFSSL_SP_MATH +static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng, + ecc_curve_spec* curve, mp_int* e, mp_int* r, + mp_int* s) +{ + int err = MP_OKAY; + int loop_check = 0; +#ifdef WOLFSSL_SMALL_STACK + mp_int* b = NULL; +#else + mp_int b[1]; +#endif + +#ifdef WOLFSSL_SMALL_STACK + b = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC); + if (b == NULL) + err = MEMORY_E; +#endif + + if (err == MP_OKAY) { + err = mp_init(b); + } + +#ifdef WOLFSSL_CUSTOM_CURVES + /* if custom curve, apply params to pubkey */ + if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) { + err = wc_ecc_set_custom_curve(pubkey, key->dp); + } +#endif + + if (err == MP_OKAY) { + /* Generate blinding value - non-zero value. */ + do { + if (++loop_check > 64) { + err = RNG_FAILURE_E; + break; + } + + err = wc_ecc_gen_k(rng, key->dp->size, b, curve->order); + } + while (err == MP_ZERO_E); + loop_check = 0; + } + + for (; err == MP_OKAY;) { + if (++loop_check > 64) { + err = RNG_FAILURE_E; + break; + } +#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) + if (key->sign_k != NULL) { + if (loop_check > 1) { + err = RNG_FAILURE_E; + break; + } + + /* use provided sign_k */ + err = mp_copy(key->sign_k, &pubkey->k); + if (err != MP_OKAY) break; + + /* free sign_k, so only used once */ + mp_forcezero(key->sign_k); + mp_free(key->sign_k); + XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC); + key->sign_k = NULL; + #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP + loop_check = 64; + #endif + + /* compute public key based on provided "k" */ + err = ecc_make_pub_ex(pubkey, curve, NULL, rng); + } + else +#endif + { + err = wc_ecc_make_key_ex(rng, key->dp->size, pubkey, + key->dp->id); + } + if (err != MP_OKAY) break; + + /* find r = x1 mod n */ + err = mp_mod(pubkey->pubkey.x, curve->order, r); + if (err != MP_OKAY) break; + + if (mp_iszero(r) == MP_NO) { + mp_int* ep = &pubkey->k; + mp_int* kp = &pubkey->k; + mp_int* x = &key->k; + + /* find s = (e + xr)/k + = b.(e/k.b + x.r/k.b) */ + + /* k' = k.b */ + err = mp_mulmod(&pubkey->k, b, curve->order, kp); + if (err != MP_OKAY) break; + + /* k' = 1/k.b + = 1/k' */ + err = mp_invmod(kp, curve->order, kp); + if (err != MP_OKAY) break; + + /* s = x.r */ + err = mp_mulmod(x, r, curve->order, s); + if (err != MP_OKAY) break; + + /* s = x.r/k.b + = k'.s */ + err = mp_mulmod(kp, s, curve->order, s); + if (err != MP_OKAY) break; + + /* e' = e/k.b + = e.k' */ + err = mp_mulmod(kp, e, curve->order, ep); + if (err != MP_OKAY) break; + + /* s = e/k.b + x.r/k.b = (e + x.r)/k.b + = e' + s */ + err = mp_addmod_ct(ep, s, curve->order, s); + if (err != MP_OKAY) break; + + /* s = b.(e + x.r)/k.b = (e + x.r)/k + = b.s */ + err = mp_mulmod(s, b, curve->order, s); + if (err != MP_OKAY) break; + + if (mp_iszero(s) == MP_NO) { + /* sign successful */ + break; + } + } + #ifndef ALT_ECC_SIZE + mp_clear(pubkey->pubkey.x); + mp_clear(pubkey->pubkey.y); + mp_clear(pubkey->pubkey.z); + #endif + mp_forcezero(&pubkey->k); + } + mp_clear(b); +#ifdef WOLFSSL_SMALL_STACK + XFREE(b, key->heap, DYNAMIC_TYPE_ECC); +#endif + + return err; +} +#endif + /** Sign a message digest in The message digest to sign @@ -5270,8 +5451,8 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, } #if defined(WOLFSSL_SP_MATH) - if (key->idx == ECC_CUSTOM_IDX || - (ecc_sets[key->idx].id != ECC_SECP256R1 && + if (key->idx == ECC_CUSTOM_IDX || + (ecc_sets[key->idx].id != ECC_SECP256R1 && ecc_sets[key->idx].id != ECC_SECP384R1)) { return WC_KEY_SIZE_E; } @@ -5297,19 +5478,19 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, if (ecc_sets[key->idx].id == ECC_SECP256R1) { #ifdef WC_ECC_NONBLOCK if (key->nb_ctx) { - return sp_ecc_sign_256_nb(&key->nb_ctx->sp_ctx, in, inlen, rng, + return sp_ecc_sign_256_nb(&key->nb_ctx->sp_ctx, in, inlen, rng, &key->k, r, s, sign_k, key->heap); } #ifdef WC_ECC_NONBLOCK_ONLY do { /* perform blocking call to non-blocking function */ - err = sp_ecc_sign_256_nb(&nb_ctx.sp_ctx, in, inlen, rng, + err = sp_ecc_sign_256_nb(&nb_ctx.sp_ctx, in, inlen, rng, &key->k, r, s, sign_k, key->heap); } while (err == FP_WOULDBLOCK); return err; #endif #endif /* WC_ECC_NONBLOCK */ #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY)) - return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, sign_k, + return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, sign_k, key->heap); #endif } @@ -5318,19 +5499,19 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, if (ecc_sets[key->idx].id == ECC_SECP384R1) { #ifdef WC_ECC_NONBLOCK if (key->nb_ctx) { - return sp_ecc_sign_384_nb(&key->nb_ctx->sp_ctx, in, inlen, rng, + return sp_ecc_sign_384_nb(&key->nb_ctx->sp_ctx, in, inlen, rng, &key->k, r, s, sign_k, key->heap); } #ifdef WC_ECC_NONBLOCK_ONLY do { /* perform blocking call to non-blocking function */ - err = sp_ecc_sign_384_nb(&nb_ctx.sp_ctx, in, inlen, rng, + err = sp_ecc_sign_384_nb(&nb_ctx.sp_ctx, in, inlen, rng, &key->k, r, s, sign_k, key->heap); } while (err == FP_WOULDBLOCK); return err; #endif #endif /* WC_ECC_NONBLOCK */ #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY)) - return sp_ecc_sign_384(in, inlen, rng, &key->k, r, s, sign_k, + return sp_ecc_sign_384(in, inlen, rng, &key->k, r, s, sign_k, key->heap); #endif } @@ -5410,7 +5591,7 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, /* truncate down to byte size, may be all that's needed */ if ((WOLFSSL_BIT_SIZE * inlen) > orderBits) inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE; - err = mp_read_unsigned_bin(e, (byte*)in, inlen); + err = mp_read_unsigned_bin(e, in, inlen); /* may still need bit truncation too */ if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits) @@ -5419,7 +5600,6 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, /* make up a key and export the public copy */ if (err == MP_OKAY) { - int loop_check = 0; #ifdef WOLFSSL_SMALL_STACK ecc_key* pubkey; #else @@ -5507,149 +5687,15 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, #endif /* don't use async for key, since we don't support async return here */ - if (err == MP_OKAY && (err = wc_ecc_init_ex(pubkey, key->heap, - INVALID_DEVID)) == MP_OKAY) { - #ifdef WOLFSSL_SMALL_STACK - mp_int* b = NULL; - #else - mp_int b[1]; - #endif - - #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + err = wc_ecc_init_ex(pubkey, key->heap, INVALID_DEVID); if (err == MP_OKAY) { - b = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, - DYNAMIC_TYPE_ECC); - if (b == NULL) - err = MEMORY_E; - } - #endif - - if (err == MP_OKAY) { - err = mp_init(b); - } - - #ifdef WOLFSSL_CUSTOM_CURVES - /* if custom curve, apply params to pubkey */ - if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) { - err = wc_ecc_set_custom_curve(pubkey, key->dp); - } - #endif - - if (err == MP_OKAY) { - /* Generate blinding value - non-zero value. */ - do { - if (++loop_check > 64) { - err = RNG_FAILURE_E; - break; - } - - err = wc_ecc_gen_k(rng, key->dp->size, b, curve->order); - } - while (err == MP_ZERO_E); - loop_check = 0; - } - - for (; err == MP_OKAY;) { - if (++loop_check > 64) { - err = RNG_FAILURE_E; - break; - } - #if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) - if (key->sign_k != NULL) { - if (loop_check > 1) { - err = RNG_FAILURE_E; - break; - } - - /* use provided sign_k */ - err = mp_copy(key->sign_k, &pubkey->k); - if (err != MP_OKAY) break; - - /* free sign_k, so only used once */ - mp_forcezero(key->sign_k); - mp_free(key->sign_k); - XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC); - key->sign_k = NULL; - #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP - loop_check = 64; + err = ecc_sign_hash_sw(key, pubkey, rng, curve, e, r, s); + wc_ecc_free(pubkey); + #ifdef WOLFSSL_SMALL_STACK + XFREE(pubkey, key->heap, DYNAMIC_TYPE_ECC); #endif - - /* compute public key based on provided "k" */ - err = ecc_make_pub_ex(pubkey, curve, NULL, rng); - } - else - #endif - { - err = wc_ecc_make_key_ex(rng, key->dp->size, pubkey, - key->dp->id); - } - if (err != MP_OKAY) break; - - /* find r = x1 mod n */ - err = mp_mod(pubkey->pubkey.x, curve->order, r); - if (err != MP_OKAY) break; - - if (mp_iszero(r) == MP_NO) { - mp_int* ep = &pubkey->k; - mp_int* kp = &pubkey->k; - mp_int* x = &key->k; - - /* find s = (e + xr)/k - = b.(e/k.b + x.r/k.b) */ - - /* k' = k.b */ - err = mp_mulmod(&pubkey->k, b, curve->order, kp); - if (err != MP_OKAY) break; - - /* k' = 1/k.b - = 1/k' */ - err = mp_invmod(kp, curve->order, kp); - if (err != MP_OKAY) break; - - /* s = x.r */ - err = mp_mulmod(x, r, curve->order, s); - if (err != MP_OKAY) break; - - /* s = x.r/k.b - = k'.s */ - err = mp_mulmod(kp, s, curve->order, s); - if (err != MP_OKAY) break; - - /* e' = e/k.b - = e.k' */ - err = mp_mulmod(kp, e, curve->order, ep); - if (err != MP_OKAY) break; - - /* s = e/k.b + x.r/k.b = (e + x.r)/k.b - = e' + s */ - err = mp_addmod_ct(ep, s, curve->order, s); - if (err != MP_OKAY) break; - - /* s = b.(e + x.r)/k.b = (e + x.r)/k - = b.s */ - err = mp_mulmod(s, b, curve->order, s); - if (err != MP_OKAY) break; - - if (mp_iszero(s) == MP_NO) { - /* sign successful */ - break; - } - } - #ifndef ALT_ECC_SIZE - mp_clear(pubkey->pubkey.x); - mp_clear(pubkey->pubkey.y); - mp_clear(pubkey->pubkey.z); - #endif - mp_forcezero(&pubkey->k); } - mp_clear(b); - #ifdef WOLFSSL_SMALL_STACK - XFREE(b, key->heap, DYNAMIC_TYPE_ECC); - #endif - wc_ecc_free(pubkey); - #ifdef WOLFSSL_SMALL_STACK - XFREE(pubkey, key->heap, DYNAMIC_TYPE_ECC); - #endif } } @@ -6075,12 +6121,11 @@ int ecc_mul2add(ecc_point* A, mp_int* kA, if (err == MP_OKAY) { /* precomp [0,i](A + B) table */ - err = ecc_projective_dbl_point_safe(precomp[1<<2], precomp[2<<2], a, - modulus, mp); + err = ecc_projective_dbl_point_safe(precomp[4], precomp[8], a, modulus, mp); } if (err == MP_OKAY) { - err = ecc_projective_add_point_safe(precomp[1<<2], precomp[2<<2], - precomp[3<<2], a, modulus, mp, NULL); + err = ecc_projective_add_point_safe(precomp[4], precomp[8], precomp[12], a, + modulus, mp, NULL); } if (err == MP_OKAY) { @@ -6103,7 +6148,7 @@ int ecc_mul2add(ecc_point* A, mp_int* kA, bitbufB = tB[0]; /* for every byte of the multiplicands */ - for (x = 0;; ) { + for (x = 0; x < (int)len || nibble != 3; ) { /* grab a nibble */ if (++nibble == 4) { if (x == (int)len) break; @@ -6542,18 +6587,18 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, #if defined(WOLFSSL_DSP) && !defined(FREESCALE_LTC_ECC) if (key->handle != -1) { - return sp_dsp_ecc_verify_256(key->handle, hash, hashlen, key->pubkey.x, + return sp_dsp_ecc_verify_256(key->handle, hash, hashlen, key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res, key->heap); } if (wolfSSL_GetHandleCbSet() == 1) { - return sp_dsp_ecc_verify_256(0, hash, hashlen, key->pubkey.x, + return sp_dsp_ecc_verify_256(0, hash, hashlen, key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res, key->heap); } #endif #if defined(WOLFSSL_SP_MATH) && !defined(FREESCALE_LTC_ECC) - if (key->idx == ECC_CUSTOM_IDX || - (ecc_sets[key->idx].id != ECC_SECP256R1 && + if (key->idx == ECC_CUSTOM_IDX || + (ecc_sets[key->idx].id != ECC_SECP256R1 && ecc_sets[key->idx].id != ECC_SECP384R1)) { return WC_KEY_SIZE_E; } @@ -6575,21 +6620,21 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, if (ecc_sets[key->idx].id == ECC_SECP256R1) { #ifdef WC_ECC_NONBLOCK if (key->nb_ctx) { - return sp_ecc_verify_256_nb(&key->nb_ctx->sp_ctx, hash, hashlen, - key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res, + return sp_ecc_verify_256_nb(&key->nb_ctx->sp_ctx, hash, hashlen, + key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res, key->heap); } #ifdef WC_ECC_NONBLOCK_ONLY do { /* perform blocking call to non-blocking function */ - err = sp_ecc_verify_256_nb(&nb_ctx.sp_ctx, hash, hashlen, - key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res, + err = sp_ecc_verify_256_nb(&nb_ctx.sp_ctx, hash, hashlen, + key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res, key->heap); } while (err == FP_WOULDBLOCK); return err; #endif #endif /* WC_ECC_NONBLOCK */ #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY)) - return sp_ecc_verify_256(hash, hashlen, key->pubkey.x, + return sp_ecc_verify_256(hash, hashlen, key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res, key->heap); #endif } @@ -6598,21 +6643,21 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, if (ecc_sets[key->idx].id == ECC_SECP384R1) { #ifdef WC_ECC_NONBLOCK if (key->nb_ctx) { - return sp_ecc_verify_384_nb(&key->nb_ctx->sp_ctx, hash, hashlen, - key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res, + return sp_ecc_verify_384_nb(&key->nb_ctx->sp_ctx, hash, hashlen, + key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res, key->heap); } #ifdef WC_ECC_NONBLOCK_ONLY do { /* perform blocking call to non-blocking function */ - err = sp_ecc_verify_384_nb(&nb_ctx.sp_ctx, hash, hashlen, - key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res, + err = sp_ecc_verify_384_nb(&nb_ctx.sp_ctx, hash, hashlen, + key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res, key->heap); } while (err == FP_WOULDBLOCK); return err; #endif #endif /* WC_ECC_NONBLOCK */ #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY)) - return sp_ecc_verify_384(hash, hashlen, key->pubkey.x, + return sp_ecc_verify_384(hash, hashlen, key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res, key->heap); #endif } @@ -6868,8 +6913,9 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, #ifdef HAVE_ECC_KEY_IMPORT /* import point from der * if shortKeySize != 0 then keysize is always (inLen-1)>>1 */ -int wc_ecc_import_point_der_ex(byte* in, word32 inLen, const int curve_idx, - ecc_point* point, int shortKeySize) +int wc_ecc_import_point_der_ex(const byte* in, word32 inLen, + const int curve_idx, ecc_point* point, + int shortKeySize) { int err = 0; #ifdef HAVE_COMP_KEY @@ -6934,7 +6980,7 @@ int wc_ecc_import_point_der_ex(byte* in, word32 inLen, const int curve_idx, /* read data */ if (err == MP_OKAY) - err = mp_read_unsigned_bin(point->x, (byte*)in, keysize); + err = mp_read_unsigned_bin(point->x, in, keysize); #ifdef HAVE_COMP_KEY if (err == MP_OKAY && compressed == 1) { /* build y */ @@ -7037,7 +7083,7 @@ int wc_ecc_import_point_der_ex(byte* in, word32 inLen, const int curve_idx, #ifdef HAVE_COMP_KEY if (compressed == 0) #endif - err = mp_read_unsigned_bin(point->y, (byte*)in + keysize, keysize); + err = mp_read_unsigned_bin(point->y, in + keysize, keysize); } if (err == MP_OKAY) err = mp_set(point->z, 1); @@ -7052,7 +7098,7 @@ int wc_ecc_import_point_der_ex(byte* in, word32 inLen, const int curve_idx, } /* function for backwards compatiblity with previous implementations */ -int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx, +int wc_ecc_import_point_der(const byte* in, word32 inLen, const int curve_idx, ecc_point* point) { return wc_ecc_import_point_der_ex(in, inLen, curve_idx, point, 1); @@ -7676,13 +7722,19 @@ int wc_ecc_check_key(ecc_key* key) #ifdef WOLFSSL_HAVE_SP_ECC #ifndef WOLFSSL_SP_NO_256 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) { - return sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y, + return sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y, key->type == ECC_PRIVATEKEY ? &key->k : NULL, key->heap); } #endif #ifdef WOLFSSL_SP_384 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) { - return sp_ecc_check_key_384(key->pubkey.x, key->pubkey.y, + return sp_ecc_check_key_384(key->pubkey.x, key->pubkey.y, + key->type == ECC_PRIVATEKEY ? &key->k : NULL, key->heap); + } +#endif +#ifdef WOLFSSL_SP_1024 + if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SAKKE_1) { + return sp_ecc_check_key_1024(key->pubkey.x, key->pubkey.y, key->type == ECC_PRIVATEKEY ? &key->k : NULL, key->heap); } #endif @@ -7893,7 +7945,7 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, /* read data */ if (err == MP_OKAY) - err = mp_read_unsigned_bin(key->pubkey.x, (byte*)in, keysize); + err = mp_read_unsigned_bin(key->pubkey.x, in, keysize); #ifdef HAVE_COMP_KEY if (err == MP_OKAY && compressed == 1) { /* build y */ @@ -7991,7 +8043,7 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, if (compressed == 0) #endif { - err = mp_read_unsigned_bin(key->pubkey.y, (byte*)in + keysize, + err = mp_read_unsigned_bin(key->pubkey.y, in + keysize, keysize); } } @@ -8684,7 +8736,7 @@ int wc_ecc_sig_size_calc(int sz) } /* maximum signature size based on actual key curve */ -int wc_ecc_sig_size(ecc_key* key) +int wc_ecc_sig_size(const ecc_key* key) { int maxSigSz; int orderBits, keySz; @@ -9532,10 +9584,14 @@ static int build_lut(int idx, mp_int* a, mp_int* modulus, mp_digit mp, } /* perform a fixed point ECC mulmod */ -static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* a, +static int accel_fp_mul(int idx, const mp_int* k, ecc_point *R, mp_int* a, mp_int* modulus, mp_digit mp, int map) { -#define KB_SIZE 128 +#ifdef WOLFCRYPT_HAVE_SAKKE + #define KB_SIZE 256 +#else + #define KB_SIZE 128 +#endif #ifdef WOLFSSL_SMALL_STACK unsigned char* kb = NULL; @@ -9565,6 +9621,9 @@ static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* a, err = MP_INIT_E; goto done; } + if ((err = mp_copy(k, tk)) != MP_OKAY) + goto done; + /* if it's smaller than modulus we fine */ if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) { /* find order */ @@ -9582,18 +9641,10 @@ static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* a, } /* k must be less than modulus */ - if (mp_cmp(k, order) != MP_LT) { - if ((err = mp_mod(k, order, tk)) != MP_OKAY) { + if (mp_cmp(tk, order) != MP_LT) { + if ((err = mp_mod(tk, order, tk)) != MP_OKAY) { goto done; } - } else { - if ((err = mp_copy(k, tk)) != MP_OKAY) { - goto done; - } - } - } else { - if ((err = mp_copy(k, tk)) != MP_OKAY) { - goto done; } } @@ -10119,7 +10170,7 @@ int ecc_mul2add(ecc_point* A, mp_int* kA, otherwise it's left in jacobian-montgomery form return MP_OKAY if successful */ -int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, +int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, mp_int* modulus, int map, void* heap) { #if !defined(WOLFSSL_SP_MATH) @@ -10228,7 +10279,7 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, otherwise it's left in jacobian-montgomery form return MP_OKAY if successful */ -int wc_ecc_mulmod_ex2(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, +int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, mp_int* modulus, mp_int* order, WC_RNG* rng, int map, void* heap) { #if !defined(WOLFSSL_SP_MATH) diff --git a/wolfcrypt/src/eccsi.c b/wolfcrypt/src/eccsi.c new file mode 100644 index 000000000..555020c35 --- /dev/null +++ b/wolfcrypt/src/eccsi.c @@ -0,0 +1,2225 @@ +/* eccsi.c + * + * Copyright (C) 2006-2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL 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. + * + * wolfSSL 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif + +#ifdef WOLFCRYPT_HAVE_ECCSI + +#include +#include +#include +#ifdef WOLFSSL_HAVE_SP_ECC + #include +#endif + +/** + * Initialize the components of the ECCSI key and use the specified curve. + * + * Must be called before performing any operations. + * Free the ECCSI key with wc_FreeEccsiKey() when no longer needed. + * + * @param [in] key ECCSI key to initialize. + * @param [in] heap Heap hint. + * @param [in] devId Device identifier. + * Use INVALID_DEVID when no device used. + * @return 0 on success. + * @return BAD_FUNC_ARG when key is NULL. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int wc_InitEccsiKey_ex(EccsiKey* key, int keySz, int curveId, void* heap, + int devId) +{ + int err = 0; + ecc_key* ecc = NULL; + ecc_key* pubkey = NULL; + EccsiKeyParams* params = NULL; + + if (key == NULL) { + err = BAD_FUNC_ARG; + } + + if (err == 0) { + XMEMSET(key, 0, sizeof(*key)); + key->heap = heap; + params = &key->params; + + err = wc_ecc_init_ex(&key->ecc, heap, devId); + } + if (err == 0) { + ecc = &key->ecc; + err = wc_ecc_init_ex(&key->pubkey, heap, devId); + } + if (err == 0) { + key->pvt = wc_ecc_new_point_h(heap); + if (key->pvt == NULL) { + err = MEMORY_E; + } + } + if (err == 0) { + pubkey = &key->pubkey; + err = mp_init_multi(¶ms->order, +#ifdef WOLFCRYPT_ECCSI_CLIENT + ¶ms->a, ¶ms->b, ¶ms->prime, &key->tmp, &key->ssk +#else + NULL, NULL, NULL, NULL, NULL +#endif + ); + } + if (err == 0) { + err = wc_ecc_set_curve(&key->ecc, keySz, curveId); + } + if (err == 0) { + err = wc_ecc_set_curve(&key->pubkey, keySz, curveId); + } + + if (err != 0) { + wc_ecc_free(pubkey); + wc_ecc_free(ecc); + } + + return err; +} + +/** + * Initialize the components of the ECCSI key. + * Default curve used: NIST_P256 (ECC_SECP256R1) + * + * Must be called before performing any operations. + * Free the ECCSI key with wc_FreeEccsiKey() when no longer needed. + * + * @param [in] key ECCSI key to initialize. + * @param [in] heap Heap hint. + * @param [in] devId Device identifier. + * Use INVALID_DEVID when no device used. + * @return 0 on success. + * @return BAD_FUNC_ARG when key is NULL. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int wc_InitEccsiKey(EccsiKey* key, void* heap, int devId) +{ + return wc_InitEccsiKey_ex(key, 32, ECC_SECP256R1, heap, devId); +} + +/** + * Frees memory associated with components of the ECCIS key. + * + * Must be called when finished with the ECCIS key. + * + * @param [in] key ECCIS key. + */ +void wc_FreeEccsiKey(EccsiKey* key) +{ + if (key != NULL) { + EccsiKeyParams* params = &key->params; + + wc_ecc_del_point_h(params->base, key->heap); +#ifdef WOLFCRYPT_ECCSI_CLIENT + mp_free(&key->ssk); + mp_free(&key->tmp); + mp_free(¶ms->prime); + mp_free(¶ms->b); + mp_free(¶ms->a); +#endif + mp_free(¶ms->order); + wc_ecc_del_point_h(key->pvt, key->heap); + wc_ecc_free(&key->pubkey); + wc_ecc_free(&key->ecc); + } +} + +/* + * Order, as a hex string in the ECC object, loaded into mp_int in key. + * Flags that the order is available so it isn't loaded multiple times. + * + * @param [in] key ECCSI key. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +static int eccsi_load_order(EccsiKey* key) +{ + int err = 0; + + if (!key->params.haveOrder) { + err = mp_read_radix(&key->params.order, key->ecc.dp->order, + MP_RADIX_HEX); + if (err == 0) { + key->params.haveOrder = 1; + } + } + + return err; +} + +#ifdef WOLFCRYPT_ECCSI_CLIENT +/* + * Parameters, as a hex strings in the ECC object, loaded into mp_ints in key. + * + * Parameters loaded: order, A, B, prime. + * Flags that each parameter is available so they aren't loaded multiple times. + * + * @param [in] key ECCSI key. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +static int eccsi_load_ecc_params(EccsiKey* key) +{ + int err = 0; + EccsiKeyParams* params = &key->params; + + err = eccsi_load_order(key); + if ((err == 0) && (!params->haveA)) { + err = mp_read_radix(¶ms->a, key->ecc.dp->Af, MP_RADIX_HEX); + if (err == 0) { + params->haveA = 1; + } + } + if ((err == 0) && (!params->haveB)) { + err = mp_read_radix(¶ms->b, key->ecc.dp->Bf, MP_RADIX_HEX); + if (err == 0) { + params->haveB = 1; + } + } + if ((err == 0) && (!params->havePrime)) { + err = mp_read_radix(¶ms->prime, key->ecc.dp->prime, MP_RADIX_HEX); + if (err == 0) { + params->havePrime = 1; + } + } + + return err; +} +#endif /* WOLFCRYPT_ECCSI_CLIENT */ + +/* + * Get the base point, hex encoded in the ECC object, as an ecc_point. + * + * Flags that base is available so it isn't loaded multiple times. + + * @param [in] key ECCSI key. + * @param [out] base Base point of curve. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +static int eccsi_load_base(EccsiKey* key) +{ + int err = 0; + EccsiKeyParams* params = &key->params; + + if (!params->haveBase) { + if (params->base == NULL) { + params->base = wc_ecc_new_point_h(key->heap); + if (params->base == NULL) { + err = MEMORY_E; + } + } + if (err == 0) { + err = mp_read_radix(params->base->x, key->ecc.dp->Gx, MP_RADIX_HEX); + } + if (err == 0) { + err = mp_read_radix(params->base->y, key->ecc.dp->Gy, MP_RADIX_HEX); + } + if (err == 0) { + err = mp_set(params->base->z, 1); + } + if (err == 0) { + params->haveBase = 1; + } + } + + return err; +} + +/* + * Encode the base point of the curve. + * + * Base point is hex encoded in the ECC object or cached as an ECC point from + * previous load calls. + * + * @param [in] key ECCSI key. + * @param [out] data Buffer to encode base point into. + * @param [out] dataSz Length of base point in bytes. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value when an internal operation fails. + */ +static int eccsi_encode_base(EccsiKey* key, byte* data, word32* dataSz) +{ + int err; + int idx = wc_ecc_get_curve_idx(key->ecc.dp->id); + + err = eccsi_load_base(key); + if (err == 0) { + err = wc_ecc_export_point_der(idx, key->params.base, data, dataSz); + } + + return err; +} + +#ifndef WOLFSSL_HAVE_SP_ECC +/* + * Convert the KPAK to montgomery form. + * + * The KPAK is needed in Montgomery form for verification. + * + * @param [in] key ECCSI key. + * @return 0 on success. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value when an internal operation fails. + */ +static int eccsi_kpak_to_mont(EccsiKey* key) +{ + int err = 0; + ecc_point* kpak = &key->ecc.pubkey; + mp_int* mu = &key->tmp; + mp_int* prime = &key->params.prime; + + if (!key->kpakMont) { + err = mp_montgomery_calc_normalization(mu, prime); + if (err == 0) { + err = mp_mulmod(kpak->x, mu, prime, kpak->x); + } + if (err == 0) { + err = mp_mulmod(kpak->y, mu, prime, kpak->y); + } + if (err == 0) { + err = mp_mulmod(kpak->z, mu, prime, kpak->z); + } + if (err == 0) { + key->kpakMont = 1; + } + } + + return err; +} +#endif + +/* + * Convert the KPAK from montgomery form. + * + * The KPAK is needed in Montgomery form for verification. + * + * @param [in] key ECCSI key. + * @return 0 on success. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value when an internal operation fails. + */ +static int eccsi_kpak_from_mont(EccsiKey* key) +{ + int err = 0; + ecc_point* kpak = &key->ecc.pubkey; + mp_digit mp; + mp_int* prime = &key->params.prime; + + if (key->kpakMont) { + err = mp_montgomery_setup(prime, &mp); + if (err == 0) { + err = mp_montgomery_reduce(kpak->x, prime, mp); + } + if (err == 0) { + err = mp_montgomery_reduce(kpak->y, prime, mp); + } + if (err == 0) { + err = mp_montgomery_reduce(kpak->z, prime, mp); + } + if (err == 0) { + key->kpakMont = 0; + } + } + + return err; +} + +/* + * Compute HS = hash( G | KPAK | ID | PVT ) + * + * Use when making a (SSK,PVT) pair, signing and verifying. + * + * @param [in] key ECCSI key. + * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256 + * @param [in] id Identity to create hash from. + * @param [in] idSz Length of identity in bytes. + * @param [in] pvt Public Validation Token (PVT) as an ECC point. + * @param [out] hash Buffer to hold hash data. + * @param [out] hashSz Length of hash data in bytes. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value when an internal operation fails. + */ +static int eccsi_compute_hs(EccsiKey* key, enum wc_HashType hashType, + const byte* id, word32 idSz, ecc_point* pvt, byte* hash, byte* hashSz) +{ + int err; + word32 dataSz = 0; + int idx = wc_ecc_get_curve_idx(key->ecc.dp->id); + ecc_point* kpak = &key->ecc.pubkey; + + /* HS = hash( G | KPAK | ID | PVT ) */ + err = wc_HashInit_ex(&key->hash, hashType, key->heap, INVALID_DEVID); + if (err == 0) { + /* Base Point - G */ + dataSz = sizeof(key->data); + err = eccsi_encode_base(key, key->data, &dataSz); + } + if (err == 0) { + err = wc_HashUpdate(&key->hash, hashType, key->data, dataSz); + } + if (err == 0) { + err = eccsi_kpak_from_mont(key); + } + if (err == 0) { + dataSz = sizeof(key->data); + /* KPAK - public key */ + err = wc_ecc_export_point_der(idx, kpak, key->data, &dataSz); + } + if (err == 0) { + err = wc_HashUpdate(&key->hash, hashType, key->data, dataSz); + } + if (err == 0) { + /* Id - Signer's ID */ + err = wc_HashUpdate(&key->hash, hashType, id, idSz); + } + if (err == 0) { + dataSz = sizeof(key->data); + /* PVT - Public Validation Token */ + err = wc_ecc_export_point_der(idx, pvt, key->data, &dataSz); + } + if (err == 0) { + /* PVT - Public Validation Token */ + err = wc_HashUpdate(&key->hash, hashType, key->data, dataSz); + } + if (err == 0) { + err = wc_HashFinal(&key->hash, hashType, hash); + } + + if (err == 0) { + *hashSz = (byte)wc_HashGetDigestSize(hashType); + } + + return err; +} + +#ifdef WOLFCRYPT_ECCSI_KMS +/** + * Generate KMS Secret Auth Key (KSAK) and KMS Public Auth Key (KPAK). + * + * RFC 6507, Section 4.2 + * + * Called when establishing a new KMS.\n + * KSAK must be kept secret while KPAK is required by clients for signing + * and verifying.\n + * Export key using wc_ExportEccsiKey(), once generated, to reuse the key.\n + * Export KPAK using wc_ExportEccsiPublicKey(), once generate to send to + * clients. + * + * Creates a random private key and multiplies it by the base point to calculate + * the public key. + * + * @param [in] key ECCSI key. + * @param [in] rng Random number generator. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or rng is NULL. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value when an internal operation fails. + */ +int wc_MakeEccsiKey(EccsiKey* key, WC_RNG* rng) +{ + int err = 0; + + if ((key == NULL) || (rng == NULL)) { + err = BAD_FUNC_ARG; + } + + if (err == 0) { + err = wc_ecc_make_key_ex(rng, key->ecc.dp->size, &key->ecc, + key->ecc.dp->id); + } + + return err; +} + +/* + * Encode a point into a buffer. + * + * X and y ordinate of point concatenated. Each number is zero padded tosize. + * Descriptor byte (0x04) is prepeneded when not raw. + * + * @param [in] point ECC point to encode. + * @param [in] size Size of prime in bytes - maximum ordinate length. + * @param [out] data Buffer to hold encoded data. + * NULL when needing length of encoded data. + * @param [in,out] sz In, the size of the buffer in bytes. + * Out, the size of the encoded data in bytes. + * @param [in] raw On 0, prepend descriptor byte. + * On 1, only include ordinates. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or sz is NULL. + * @return LENGTH_ONLY_E when data is NULL - sz will hold the size in bytes of + * the encoded data. + * @return BUFFER_E when size of buffer is too small. + */ +static int eccsi_encode_point(ecc_point* point, word32 size, byte* data, + word32* sz, int raw) +{ + int err = 0; + + if (data == NULL) { + *sz = size * 2 + !raw; + err = LENGTH_ONLY_E; + } + if ((err == 0) && (*sz < size * 2 + !raw)) { + err = BUFFER_E; + } + + if (err == 0) { + if (!raw) { + data[0] = 0x04; + data++; + } + + /* Write out the point's x ordinate into key size bytes. */ + err = mp_to_unsigned_bin_len(point->x, data, size); + } + if (err == 0) { + data += size; + /* Write out the point's y ordinate into key size bytes. */ + err = mp_to_unsigned_bin_len(point->y, data, size); + } + if (err == 0) { + *sz = size * 2 + !raw; + } + + return err; +} + +/* + * Decode the data into an ECC point. + * + * X and y ordinate of point concatenated. Each number is zero padded to + * key size. Supports prepended descriptor byte (0x04). + * + * @param [out] point ECC point to encode. + * @param [in] size Size of prime in bytes - maximum ordinate length. + * @param [in] data Encoded public key. + * @param [in] sz Size of the encoded public key in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or z is NULL. + * @return BUFFER_E when size of data is not equal to the expected size. + * @return ASN_PARSE_E when format byte is invalid. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + */ +static int eccsi_decode_point(ecc_point* point, word32 size, const byte* data, + word32 sz) +{ + int err = 0; + + if ((err == 0) && (sz != size * 2) && (sz != size * 2 + 1)) { + err = BUFFER_E; + } + + if ((err == 0) && (sz & 1)) { + if (data[0] != 0x04) { + err = ASN_PARSE_E; + } + data++; + } + + if (err == 0) { + /* Read the public key point's x value from key size bytes. */ + err = mp_read_unsigned_bin(point->x, data, size); + } + if (err == 0) { + data += size; + /* Read the public key point's y value from key size bytes. */ + err = mp_read_unsigned_bin(point->y, data, size); + } + if (err == 0) { + err = mp_set(point->z, 1); + } + + return err; +} + +/* + * Encode the ECCSI key. + * + * Encodes the private key as big-endian bytes of fixed length. + * Encodes the public key x and y ordinates as big-endian bytes of fixed length. + * + * @param [in] key ECCSI key. + * @param [out] data Buffer to hold encoded ECCSI key. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails (WOLFSSL_SMALL_STACK). + */ +static int eccsi_encode_key(EccsiKey* key, byte* data) +{ + int err; + word32 sz = (word32)key->ecc.dp->size * 2; + + /* Write out the secret value into key size bytes. */ + err = mp_to_unsigned_bin_len(&key->ecc.k, data, key->ecc.dp->size); + if (err == 0) { + data += key->ecc.dp->size; + /* Write the public key. */ + err = eccsi_encode_point(&key->ecc.pubkey, (word32)key->ecc.dp->size, + data, &sz, 1); + } + + return err; +} + +/** + * Export the ECCSI key as encoded public/private ECC key. + * + * Use when saving the KMS key pair. + * + * Private key, x ordinate of public key and y ordinate of public key + * concatenated. Each number is zero padded to key size. + * + * @param [in] key ECCSI key. + * @param [out] data Buffer to hold encoded ECCSI key. + * NULL when requesting required length. + * @param [in,out] sz On in, size of buffer in bytes. + * On out, size of encoded ECCSI key in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or sz is NULL + * @return BAD_STATE_E when no key to export. + * @return LENGTH_ONLY_E when data is NULL - sz is set. + * @return BUFFER_E when the buffer passed in is too small. + * @return MEMORY_E when dynamic memory allocation fails (WOLFSSL_SMALL_STACK). + */ +int wc_ExportEccsiKey(EccsiKey* key, byte* data, word32* sz) +{ + int err = 0; + + if ((key == NULL) || (sz == NULL)) { + err = BAD_FUNC_ARG; + } + + if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY)) { + err = BAD_STATE_E; + } + + if (err == 0) { + if (data == NULL) { + *sz = key->ecc.dp->size * 3; + err = LENGTH_ONLY_E; + } + else if (*sz < (word32)key->ecc.dp->size * 3) { + err = BUFFER_E; + } + else { + *sz = key->ecc.dp->size * 3; + } + } + if (err == 0) { + err = eccsi_kpak_from_mont(key); + } + if (err == 0) { + /* Encode key */ + err = eccsi_encode_key(key, data); + } + + return err; +} + +/* + * Import the ECCSI key as encoded public/private ECC key. + * + * Decodes the private key as big-endian bytes of fixed length. + * Decodes the public key x and y ordinates as big-endian bytes of fixed length. + * + * @param [in] key ECCSI key. + * @param [in] data Buffer holding encoded ECCSI key. + * @return 0 on success. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + */ +static int eccsi_decode_key(EccsiKey* key, const byte* data) +{ + int err; + + /* Read the secret value from key size bytes. */ + err = mp_read_unsigned_bin(&key->ecc.k, data, key->ecc.dp->size); + if (err == 0) { + data += key->ecc.dp->size; + /* Read public key. */ + err = eccsi_decode_point(&key->ecc.pubkey, (word32)key->ecc.dp->size, + data, key->ecc.dp->size * 2); + } + + return err; +} + +/** + * Import the ECCSI key as encoded public/private ECC key. + * + * Use when restoring the KMS key pair. + * + * Private key, x ordinate of public key and y ordinate of public key + * concatenated. Each number is zero padded to key size. + * + * @param [in] key ECCSI key. + * @param [in] data Buffer holding encoded ECCSI key. + * @param [in] sz Size of encoded ECCSI key in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or data is NULL. + * @return BUFFER_E when size of data is not equal to the expected size. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + */ +int wc_ImportEccsiKey(EccsiKey* key, const byte* data, word32 sz) +{ + int err = 0; + + if ((key == NULL) || (data == NULL)) { + err = BAD_FUNC_ARG; + } + if ((err == 0) && (sz != (word32)key->ecc.dp->size * 3)) { + err = BUFFER_E; + } + + if (err == 0) { + key->kpakMont = 0; + + /* Decode key */ + err = eccsi_decode_key(key, data); + } + if (err == 0) { + key->ecc.type = ECC_PRIVATEKEY; + } + + return err; +} + +/** + * Export the ECCSI private key. + * + * Use when saving the KMS key. + * + * Private key is zero padded to key size. + * + * @param [in] key ECCSI key. + * @param [out] data Buffer to hold encoded ECCSI private key. + * NULL when requesting required length. + * @param [in,out] sz On in, size of buffer in bytes. + * On out, size of encoded ECCSI private key in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or sz is NULL + * @return BAD_STATE_E when no key to export. + * @return LENGTH_ONLY_E when data is NULL - sz is set. + * @return BUFFER_E when the buffer passed in is too small. + * @return MEMORY_E when dynamic memory allocation fails (WOLFSSL_SMALL_STACK). + */ +int wc_ExportEccsiPrivateKey(EccsiKey* key, byte* data, word32* sz) +{ + int err = 0; + + if ((key == NULL) || (sz == NULL)) { + err = BAD_FUNC_ARG; + } + + if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY)) { + err = BAD_STATE_E; + } + + if (err == 0) { + if (data == NULL) { + *sz = key->ecc.dp->size; + err = LENGTH_ONLY_E; + } + else if (*sz < (word32)key->ecc.dp->size) { + err = BUFFER_E; + } + else { + *sz = key->ecc.dp->size; + } + } + if (err == 0) { + err = mp_to_unsigned_bin_len(&key->ecc.k, data, key->ecc.dp->size); + } + + return err; +} + +/** + * Import the ECCSI private key. + * + * Use when restoring the KMS key pair. + * + * Private key is zero padded to key size. + * + * @param [in] key ECCSI key. + * @param [in] data Buffer holding encoded ECCSI private key. + * @param [in] sz Size of encoded ECCSI private key in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or data is NULL. + * @return BUFFER_E when size of data is not equal to the expected size. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + */ +int wc_ImportEccsiPrivateKey(EccsiKey* key, const byte* data, word32 sz) +{ + int err = 0; + + if ((key == NULL) || (data == NULL)) { + err = BAD_FUNC_ARG; + } + if ((err == 0) && (sz != (word32)key->ecc.dp->size)) { + err = BUFFER_E; + } + + if (err == 0) { + err = mp_read_unsigned_bin(&key->ecc.k, data, key->ecc.dp->size); + } + + return err; +} + +/** + * Export the KMS Public Auth Key (KPAK) from the ECCSI object. + * + * KPAK is required by all clients in order to perform cryptographic operations. + * + * X and y ordinate of public key concatenated. Each number is zero padded to + * key size. + * Descriptor byte (0x04) is prepeneded when not raw. + * + * @param [in] key ECCSI key. + * @param [out] data Buffer to hold the encoded public key. + * @param [in,out] sz On in, size of buffer in bytes. + * On out, length of encoded public key in bytes. + * @param [in] raw On 0, prepend descriptor byte. + * On 1, only include ordinates. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or sz is NULL. + * @return LENGTH_ONLY_E when data is NULL - sz is set. + * @return BUFFER_E when the buffer passed in is too small. + */ +int wc_ExportEccsiPublicKey(EccsiKey* key, byte* data, word32* sz, int raw) +{ + int err = 0; + + if ((key == NULL) || (sz == NULL)) { + err = BAD_FUNC_ARG; + } + if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY) && + (key->ecc.type != ECC_PUBLICKEY)) { + err = BAD_STATE_E; + } + + if ((err == 0) && (data != NULL)) { + err = eccsi_kpak_from_mont(key); + } + if (err == 0) { + /* Write out public key. */ + err = eccsi_encode_point(&key->ecc.pubkey, (word32)key->ecc.dp->size, + data, sz, raw); + } + + return err; +} + +/* + * Generates an (SSK, PVT) Pair - signing key pair. + * + * RFC 6507, Section 5.1.1 + * + * @param [in] key ECCSI key. + * @param [in] rng Random number generator. + * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256 + * @param [in] id Identity to create hash from. + * @param [in] idSz Length of identity in bytes. + * @param [out] ssk Secret Signing Key as an MP integer. + * @param [out] pvt Public Validation Token (PVT) as an ECC point. + * @return 0 on success. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value when an internal operation fails. + */ +static int eccsi_make_pair(EccsiKey* key, WC_RNG* rng, + enum wc_HashType hashType, const byte* id, word32 idSz, mp_int* ssk, + ecc_point* pvt) +{ + int err = 0; + byte hashSz = 0; + int genTryCnt = 0; + + do { + /* Don't infinitely make pairs when random number generator fails. */ + if ((++genTryCnt) > ECCSI_MAX_GEN_COUNT) { + err = RNG_FAILURE_E; + } + + if (err == 0) { + /* Step 1 and 2: Generate ephemeral key - v, PVT = [v]G */ + err = wc_ecc_make_key_ex(rng, key->ecc.dp->size, &key->pubkey, + key->ecc.dp->id); + } + if (err == 0) { + err = wc_ecc_copy_point(&key->pubkey.pubkey, pvt); + } + + /* Step 3: Compute HS */ + if (err == 0) { + hashSz = (byte)sizeof(key->data); + err = eccsi_compute_hs(key, hashType, id, idSz, pvt, key->data, + &hashSz); + } + + /* Step 4: Compute SSK = ( KSAK + HS * v ) modulo q */ + if (err == 0) { + err = mp_read_unsigned_bin(ssk, key->data, hashSz); + } + if (err == 0) { + err = mp_mulmod(ssk, &key->pubkey.k, &key->params.order, ssk); + } + if (err == 0) { + err = mp_addmod(ssk, &key->ecc.k, &key->params.order, ssk); + } + } + while ((err == 0) && (mp_iszero(ssk) || + (mp_cmp(ssk, &key->ecc.k) == MP_EQ))); + /* Step 5: ensure SSK and HS are non-zero (code lines above) */ + + /* Step 6: Copy out SSK (done during calc) and PVT. Erase v */ + mp_forcezero(&key->pubkey.k); + + return err; +} + +/** + * Generates an (SSK, PVT) Pair - signing key pair. + * + * RFC 6507, Section 5.1.1 + * + * ID should include information to indicate a revocation date.\n + * SSK must be zeroized after sending to client.\n + * SSK is sent to signing client only.\n + * PVT is sent to all client types. + * + * @param [in] key ECCSI key. + * @param [in] rng Random number generator. + * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256 + * @param [in] id Identity to create hash from. + * @param [in] idSz Length of identity in bytes. + * @param [out] ssk Secret Signing Key as an MP integer. + * @param [out] pvt Public Validation Token (PVT) as an ECC point. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, rng, id, ssk or pvt is NULL. + * @return BAD_STATE_E when curve not set (key not set). + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value when an internal operation fails. + */ +int wc_MakeEccsiPair(EccsiKey* key, WC_RNG* rng, enum wc_HashType hashType, + const byte* id, word32 idSz, mp_int* ssk, ecc_point* pvt) +{ + int err = 0; + + if ((key == NULL) || (rng == NULL) || (id == NULL) || (ssk == NULL) || + (pvt == NULL)) { + err = BAD_FUNC_ARG; + } + if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY)) { + err = BAD_STATE_E; + } + + if (err == 0) { + err = eccsi_load_order(key); + } + if (err == 0) { + err = eccsi_make_pair(key, rng, hashType, id, idSz, ssk, pvt); + } + + return err; +} + +/** + * Encode the SSK and PVT into a buffer. + * + * SSK and PVT required by client signing messages. + * + * @param [in] key ECCSI key. + * @param [in] ssk Secret Signing Key as an MP integer. + * @param [in] pvt Public Validation Token (PVT) as an ECC point. + * @param [out] data Buffer to encode key pair into. + * @param [in,out] sz In, size of buffer in bytes. + * Out, size of encoded pair data in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, ssk, pvt or sz is NULL. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + * @return LENGTH_ONLY_E when data is NULL - sz is set. + */ +int wc_EncodeEccsiPair(const EccsiKey* key, mp_int* ssk, ecc_point* pvt, + byte* data, word32* sz) +{ + int err = 0; + + if ((key == NULL) || (ssk == NULL) || (pvt == NULL) || (sz == NULL)) { + err = BAD_FUNC_ARG; + } + + if ((err == 0) && (data == NULL)) { + *sz = key->ecc.dp->size * 3; + err = LENGTH_ONLY_E; + } + if ((err == 0) && (*sz < (word32)(key->ecc.dp->size * 3))) { + err = BUFFER_E; + } + + if (err == 0) { + err = mp_to_unsigned_bin_len(ssk, data, key->ecc.dp->size); + } + if (err == 0) { + data += key->ecc.dp->size; + /* Write out the PVT's x ordinate into key size bytes. */ + err = mp_to_unsigned_bin_len(pvt->x, data, key->ecc.dp->size); + } + if (err == 0) { + data += key->ecc.dp->size; + /* Write out the PVT's y ordinate into key size bytes. */ + err = mp_to_unsigned_bin_len(pvt->y, data, key->ecc.dp->size); + } + if (err == 0) { + *sz = key->ecc.dp->size * 3; + } + + return err; +} + +/** + * Encode the Secret Signing Key (SSK). + * + * Use when saving the key pair. + * + * SSK is zero padded to key size. + * + * @param [in] key ECCSI key. + * @param [in] ssk Secret Signing Key as an MP integer. + * @param [out] data Buffer to hold encoded SSK. + * NULL when requesting required length. + * @param [in,out] sz On in, size of buffer in bytes. + * On out, size of encoded ECCSI key in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, ssk or sz is NULL + * @return BAD_STATE_E when no key to export. + * @return LENGTH_ONLY_E when data is NULL - sz is set. + * @return BUFFER_E when the buffer passed in is too small. + * @return MEMORY_E when dynamic memory allocation fails (WOLFSSL_SMALL_STACK). + */ +int wc_EncodeEccsiSsk(const EccsiKey* key, mp_int* ssk, byte* data, word32* sz) +{ + int err = 0; + + if ((key == NULL) || (ssk == NULL) || (sz == NULL)) { + err = BAD_FUNC_ARG; + } + + if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY)) { + err = BAD_STATE_E; + } + + if (err == 0) { + if (data == NULL) { + *sz = key->ecc.dp->size; + err = LENGTH_ONLY_E; + } + else if (*sz < (word32)key->ecc.dp->size) { + err = BUFFER_E; + } + else { + *sz = key->ecc.dp->size; + } + } + if (err == 0) { + err = mp_to_unsigned_bin_len(ssk, data, key->ecc.dp->size); + } + + return err; +} + +/** + * Decode the Secret Signing Key (SSK). + * + * Use when restoring the key pair. + * + * SSK is zero padded to key size. + * + * @param [in] key ECCSI key. + * @param [in] data Buffer holding encoded ECCSI key. + * @param [in] sz Size of encoded ECCSI key in bytes. + * @param [out] ssk Secret Signing Key as an MP integer. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, data or ssk is NULL. + * @return BUFFER_E when size of data is not equal to the expected size. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + */ +int wc_DecodeEccsiSsk(const EccsiKey* key, const byte* data, word32 sz, + mp_int* ssk) +{ + int err = 0; + + if ((key == NULL) || (data == NULL) || (ssk == NULL)) { + err = BAD_FUNC_ARG; + } + if ((err == 0) && (sz != (word32)key->ecc.dp->size)) { + err = BUFFER_E; + } + + if (err == 0) { + err = mp_read_unsigned_bin(ssk, data, key->ecc.dp->size); + } + + return err; +} + +/** + * Encode the PVT into a buffer. + * + * PVT required by client verifying messages. + * + * X and y ordinate of public key concatenated. Each number is zero padded to + * key size. + * Descriptor byte (0x04) is prepeneded when not raw. + * + * @param [in] key ECCSI key. + * @param [in] pvt Public Validation Token (PVT) as an ECC point. + * @param [out] data Buffer to encode key pair into. + * @param [in,out] sz In, size of buffer in bytes. + * Out, size of encoded pair data in bytes. + * @param [in] raw On 0, prepend descriptor byte. + * On 1, only include ordinates. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, pvt or sz is NULL. + * @return BAD_STATE_E when PVT has not been set. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + * @return LENGTH_ONLY_E when data is NULL - sz is set. + */ +int wc_EncodeEccsiPvt(const EccsiKey* key, ecc_point* pvt, byte* data, + word32* sz, int raw) +{ + int err = 0; + + if ((key == NULL) || (pvt == NULL) || (sz == NULL)) { + err = BAD_FUNC_ARG; + } + + if (err == 0) { + err = eccsi_encode_point(pvt, (word32)key->ecc.dp->size, data, sz, raw); + } + + return err; +} + +#endif /* WOLFCRYPT_ECCSI_KMS */ + +#ifdef WOLFCRYPT_ECCSI_CLIENT +/** + * Decode the SSK and PVT data into separate variables. + * + * A signing client decodes the data so that it can validate the pair and sign. + * + * @param [in] key ECCSI key. + * @param [in] data Buffer holding key pair data. + * @param [in] sz Size of data in bytes. + * @param [out] ssk Secret Signing Key as an MP integer. + * @param [out] pvt Public Validation Token (PVT) as an ECC point. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, data, ssk or pvt is NULL. + * @return LENGTH_ONLY_E when data is NULL - sz is set. + * @return BUFFER_E when size of data is not equal to the expected size. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + */ +int wc_DecodeEccsiPair(const EccsiKey* key, const byte* data, word32 sz, + mp_int* ssk, ecc_point* pvt) +{ + int err = 0; + + if ((key == NULL) || (data == NULL) || (ssk == NULL) || (pvt == NULL)) { + err = BAD_FUNC_ARG; + } + if ((err == 0) && (sz != (word32)(key->ecc.dp->size * 3))) { + err = BUFFER_E; + } + + if (err == 0) { + /* Read the SSK value from key size bytes. */ + err = mp_read_unsigned_bin(ssk, data, key->ecc.dp->size); + } + if (err == 0) { + data += key->ecc.dp->size; + /* Read the PVT's x value from key size bytes. */ + err = mp_read_unsigned_bin(pvt->x, data, key->ecc.dp->size); + } + if (err == 0) { + data += key->ecc.dp->size; + /* Read the PVT's y value from key size bytes. */ + err = mp_read_unsigned_bin(pvt->y, data, key->ecc.dp->size); + } + if (err == 0) { + err = mp_set(pvt->z, 1); + } + + return err; +} + +/** + * Decode the PVT data into an ECC point. + * + * A verifying client decodes the data so that it can verify a message. + * + * X and y ordinate of public key concatenated. Each number is zero padded to + * key size. + * Descriptor byte (0x04) is prepeneded when not raw. + * + * @param [in] key ECCSI key. + * @param [in] data Buffer holding PVT data. + * @param [in] sz Size of data in bytes. + * @param [out] pvt Public Validation Token (PVT) as an ECC point. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, data, ssk or pvt is NULL. + * @return BUFFER_E when size of data is not equal to the expected size. + * @return ASN_PARSE_E when format byte is invalid. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + */ +int wc_DecodeEccsiPvt(const EccsiKey* key, const byte* data, word32 sz, + ecc_point* pvt) +{ + int err = 0; + + if ((key == NULL) || (data == NULL) || (pvt == NULL)) { + err = BAD_FUNC_ARG; + } + + if (err == 0) { + err = eccsi_decode_point(pvt, (word32)key->ecc.dp->size, data, sz); + } + + return err; +} + +/** + * Decode the PVT data, from a signature, into an ECC point. + * + * A verifying client decodes the data so that it can calculate the identity + * hash. + * + * X and y ordinate of public key concatenated. Each number is zero padded to + * key size. + * Descriptor byte (0x04) is prepeneded when not raw. + * + * @param [in] key ECCSI key. + * @param [in] sig Buffer holding signature data. + * @param [in] sz Size of data in bytes. + * @param [out] pvt Public Validation Token (PVT) as an ECC point. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, data, ssk or pvt is NULL. + * @return BUFFER_E when size of data is not equal to the expected size. + * @return ASN_PARSE_E when format byte is invalid. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + */ +int wc_DecodeEccsiPvtFromSig(const EccsiKey* key, const byte* sig, word32 sz, + ecc_point* pvt) +{ + int err = 0; + + if ((key == NULL) || (sig == NULL) || (pvt == NULL)) { + err = BAD_FUNC_ARG; + } + + if (err == 0) { + word32 rSz = key->ecc.dp->size * 2; + err = eccsi_decode_point(pvt, (word32)key->ecc.dp->size, sig + rSz, + sz - rSz); + } + + return err; +} + +/** + * Import the KMS Public Auth Key (KPAK) into the ECCSI object. + * + * Clients import the KPAK to perform cryptographic operations. + * + * X and y ordinate of public key concatenated. Each number is zero padded to + * key size. + * Descriptor byte (0x04) is prepeneded when not raw. + * + * @param [in] key ECCSI key. + * @param [in] data Encoded public key as an array of bytes. + * @param [in] sz Length of encoded KPAK in bytes. + * @param [in] trusted 1 when public key is trusted. + * 0 when validation is required to be performed. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or data is NULL. + * @return BUFFER_E when size of data is not equal to the expected size. + * @return ASN_PARSE_E when format byte is invalid. + * @return ECC_OUT_OF_RANGE_E when point is invalid. + * @return ECC_INF_E when point is at infinity and invalid. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + */ +int wc_ImportEccsiPublicKey(EccsiKey* key, const byte* data, word32 sz, + int trusted) +{ + int err = 0; + + if ((key == NULL) || (data == NULL)) { + err = BAD_FUNC_ARG; + } + + if (err == 0) { + key->kpakMont = 0; + + /* Read the public key. */ + err = eccsi_decode_point(&key->ecc.pubkey, (word32)key->ecc.dp->size, + data, sz); + } + if (err == 0) { + key->ecc.type = ECC_PUBLICKEY; + } + if ((err == 0) && (!trusted)) { + err = wc_ecc_check_key(&key->ecc); + } + + return err; +} + +/* + * Scalar multiply the base point of the curve and add a point. + * + * @param [in] key ECCSI key. + * @param [in] n MP integer representing scalar to multiply by. + * @param [in] a ECC point to add. + * @param [out] res ECC point representation of the resulting point. + * @param [in] mp Montgomery reduction multiplier. + * @param [in] map 0 indicates to leave in projective representation. + * 1 indicates map projective point to affine. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value when an internal operation fails. + */ +static int eccsi_mulmod_base_add(EccsiKey* key, const mp_int* n, + ecc_point* a, ecc_point* res, mp_digit mp, int map) +{ + int err = 0; + +#ifdef WOLFSSL_HAVE_SP_ECC +#ifndef WOLFSSL_SP_NO_256 + if ((key->ecc.idx != ECC_CUSTOM_IDX) && + (ecc_sets[key->ecc.idx].id == ECC_SECP256R1)) { + err = sp_ecc_mulmod_base_add_256(n, a, 1, res, map, key->heap); + } + else +#endif +#endif +#ifndef WOLFSSL_SP_MATH + { + EccsiKeyParams* params = &key->params; + err = wc_ecc_mulmod(n, params->base, params->base, ¶ms->a, + ¶ms->prime, 0); + key->params.haveBase = 0; + if (err == 0) { + err = ecc_projective_add_point(params->base, a, res, ¶ms->a, + ¶ms->prime, mp); + } + if ((err == 0) && map) { + err = ecc_map(res, ¶ms->prime, mp); + } + } +#else + { + err = NOT_COMPILED_IN; + } + (void)mp; +#endif + + return err; +} + +/* + * Scalar multiply a point on the curve. + * + * @param [in] key ECCSI key. + * @param [in] n MP integer representing scalar to multiply by. + * @param [in] point ECC point representation of a point on the curve. + * @param [out] res ECC point representation of the resulting point. + * @param [in] map 0 indicates to leave in projective representation. + * 1 indicates map projective point to affine. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value when an internal operation fails. + */ +static int eccsi_mulmod_point(EccsiKey* key, const mp_int* n, ecc_point* point, + ecc_point* res, int map) +{ + int err; + +#ifdef WOLFSSL_HAVE_SP_ECC +#ifndef WOLFSSL_SP_NO_256 + if ((key->ecc.idx != ECC_CUSTOM_IDX) && + (ecc_sets[key->ecc.idx].id == ECC_SECP256R1)) { + err = sp_ecc_mulmod_256(n, point, res, map, key->heap); + } + else +#endif +#endif + { + EccsiKeyParams* params = &key->params; + + err = wc_ecc_mulmod(n, point, res, ¶ms->a, ¶ms->prime, map); + } + + return err; +} + +/* + * Scalar multiply a point on the curve and add a. + * + * @param [in] key ECCSI key. + * @param [in] n MP integer representing scalar to multiply by. + * @param [in] point ECC point representation of a point on the curve. + * @param [in] a ECC point to add. + * @param [out] res ECC point representation of the resulting point. + * @param [in] mp Montgomery reduction multiplier. + * @param [in] map 0 indicates to leave in projective representation. + * 1 indicates map projective point to affine. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value when an internal operation fails. + */ +static int eccsi_mulmod_point_add(EccsiKey* key, const mp_int* n, + ecc_point* point, ecc_point* a, ecc_point* res, mp_digit mp, int map) +{ +#ifdef WOLFSSL_HAVE_SP_ECC +#ifndef WOLFSSL_SP_NO_256 + int err = NOT_COMPILED_IN; + + if ((key->ecc.idx != ECC_CUSTOM_IDX) && + (ecc_sets[key->ecc.idx].id == ECC_SECP256R1)) { + err = sp_ecc_mulmod_add_256(n, point, a, 0, res, map, key->heap); + } + + (void)mp; + + return err; +#endif +#else + int err; + EccsiKeyParams* params = &key->params; + + err = wc_ecc_mulmod(n, point, res, ¶ms->a, ¶ms->prime, 0); + if (err == 0) { + err = ecc_projective_add_point(res, a, res, &key->params.a, + ¶ms->prime, mp); + } + if ((err == 0) && map) { + err = ecc_map(res, ¶ms->prime, mp); + } + + return err; +#endif +} + +/** + * Validate an (SSV, PVT) Pair. + * + * RFC 6507, Section 5.1.2 + * + * A signing client should validate the key pair before first use. + * + * @param [in] key ECCSI key. + * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256 + * @param [in] id Identity to create hash from. + * @param [in] idSz Length of identity in bytes. + * @param [in] ssk Secret Signing Key as an MP integer. + * @param [in] pvt Public Validation Token (PVT) as an ECC point. + * @param [out] valid 1 when pair is valid and 0 otherwise. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, id, ssk, pvt or valid is NULL. + * @return BAD_STATE_E when curve not set (key not set). + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + * @return IS_POINT_E when point is not on the curve. + * @return Other -ve value when an internal operation fails. + */ +int wc_ValidateEccsiPair(EccsiKey* key, enum wc_HashType hashType, + const byte* id, word32 idSz, const mp_int* ssk, ecc_point* pvt, + int* valid) +{ + int err = 0; + ecc_point* res = NULL; + mp_int* hs = NULL; + mp_digit mp = 0; + byte hashSz = 0; + EccsiKeyParams* params = &key->params; + + if ((key == NULL) || (id == NULL) || (ssk == NULL) || (pvt == NULL) || + (valid == NULL)) { + err = BAD_FUNC_ARG; + } + if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY) && + (key->ecc.type != ECC_PUBLICKEY)) { + err = BAD_STATE_E; + } + + if (err == 0) { + hs = &key->tmp; + res = &key->pubkey.pubkey; + + err = eccsi_load_base(key); + } + if (err == 0) { + err = eccsi_load_ecc_params(key); + } + if (err == 0) { + err = mp_montgomery_setup(¶ms->prime, &mp); + } + + /* Step 1: Validate PVT is on curve */ + if (err == 0) { + err = wc_ecc_is_point(pvt, ¶ms->a, ¶ms->b, ¶ms->prime); + if (err == -1) { + err = IS_POINT_E; + } + } + + /* Step 2: Compute HS = hash( G | KPAK | ID | PVT ) */ + if (err == 0) { + hashSz = (byte)sizeof(key->data); + /* Converts KPAK from mont. */ + err = eccsi_compute_hs(key, hashType, id, idSz, pvt, key->data, + &hashSz); + } + + /* Step 3: Validate that KPAK = [SSK]G - [HS]PVT */ + if (err == 0) { + err = mp_read_unsigned_bin(hs, key->data, hashSz); + } + /* [HS]PVT */ + if (err == 0) { + err = eccsi_mulmod_point(key, hs, pvt, res, 0); + } + /* -[HS]PVT */ + if (err == 0) { + err = mp_sub(¶ms->prime, res->y, res->y); + } + /* [SSK]G + -[HS]PVT */ + if (err == 0) { + err = eccsi_mulmod_base_add(key, ssk, res, res, mp, 1); + } + if (valid != NULL) { + *valid = (err == 0); + if (err == 0) { + ecc_point* kpak = &key->ecc.pubkey; + /* Compare KPAK and [SSK]G + -[HS]PVT */ + *valid = (wc_ecc_cmp_point(res, kpak) == MP_EQ); + } + } + + return err; +} + +/** + * Validate Public Validation Token (PVT) is on the curve. + * + * RFC 6507, Section 5.1.2, Step 1 + * + * A verifying client should validate the PVT before first use. + * + * @param [in] key ECCSI key. + * @param [in] pvt Public Validation Token (PVT) as an ECC point. + * @param [out] valid 1 when PVT is valid and 0 otherwise. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, pvt or valid is NULL. + * @return BAD_STATE_E when curve not set (key not set). + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value when an internal operation fails. + */ +int wc_ValidateEccsiPvt(EccsiKey* key, const ecc_point* pvt, int* valid) +{ + int err = 0; + + if ((key == NULL)| (pvt == NULL) || (valid == NULL)) { + err = BAD_FUNC_ARG; + } + + if (err == 0) { + err = wc_ecc_set_curve(&key->pubkey, key->ecc.dp->size, + key->ecc.dp->id); + } + if (err == 0) { + err = wc_ecc_copy_point(pvt, &key->pubkey.pubkey); + } + if (err == 0) { + *valid = (wc_ecc_check_key(&key->pubkey) == 0); + } + + return err; +} + +/** + * Creates the Hash of the ID and PVT with the ECCSI key. + * + * The hash ID is required as input to the sign and verify operations.\n + * Signing clients may cache this value. + * + * RFC 6507, Section 5.2.1, Step 3 + * + * Set the calculated hash internally for use. + * + * @param [in] key ECCSI key. + * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256 + * @param [in] id Identity to create hash from. + * @param [in] idSz Length of identity in bytes. + * @param [in] pvt Public Validation Token (PVT) as an ECC point. + * @param [out] hash Buffer to hold hash result. + * @param [out] hashSz Length of hash data in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, id, pvt, hash or hashSz is NULL. + * @return BAD_STATE_E when public key not set. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value when an internal operation fails. + */ +int wc_HashEccsiId(EccsiKey* key, enum wc_HashType hashType, const byte* id, + word32 idSz, ecc_point* pvt, byte* hash, byte* hashSz) +{ + int err = 0; + + if ((key == NULL) || (id == NULL) || (pvt == NULL) || (hash == NULL) || + (hashSz == NULL)) { + err = BAD_FUNC_ARG; + } + if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY) && + (key->ecc.type != ECC_PUBLICKEY)) { + err = BAD_STATE_E; + } + /* Load the curve parameters for operations */ + if (err == 0) { + err = eccsi_load_ecc_params(key); + } + if (err == 0) { + err = eccsi_compute_hs(key, hashType, id, idSz, pvt, hash, hashSz); + } + if (err == 0) { + XMEMCPY(key->idHash, hash, *hashSz); + key->idHashSz = *hashSz; + } + + return err; +} + +/** + * Set the identity hash for use with signing/verification. + * + * @param [in] key ECCSI key. + * @param [in] hash Buffer with hash of identity. + * @param [in] hashSz Length of hash data in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or hash is NULL, or hashSz is greater than + * WC_MAX_DIGEST_SIZE. + */ +int wc_SetEccsiHash(EccsiKey* key, const byte* hash, byte hashSz) +{ + int err = 0; + + if ((key == NULL) || (hash == NULL) || (hashSz > WC_MAX_DIGEST_SIZE)) { + err = BAD_FUNC_ARG; + } + if (err == 0) { + XMEMCPY(key->idHash, hash, hashSz); + key->idHashSz = hashSz; + } + + return err; +} + +/** + * Set an (SSV, PVT) Pair for signing. + * + * @param [in] key ECCSI key. + * @param [in] ssk Secret Signing Key as an MP integer. + * @param [in] pvt Public Validation Token (PVT) as an ECC point. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, ssk or pvt is NULL. + */ +int wc_SetEccsiPair(EccsiKey* key, const mp_int* ssk, const ecc_point* pvt) +{ + int err = 0; + + if ((key == NULL) || (ssk == NULL) || (pvt == NULL)) { + err = BAD_FUNC_ARG; + } + if (err == 0) { + mp_copy(ssk, &key->ssk); + wc_ecc_copy_point(pvt, key->pvt); + } + + return err; +} + +#ifdef ECCSI_ORDER_MORE_BITS_THAN_PRIME +/* + * Fit the number to the maximum number of bytes. + * + * If the number is too big then subtract from order. + * RFC 6507, Section 5.2.1, Note at end. + * This should only happen when order is larger than prime in bits. + * + * @param [in] a MP integer to fix. + * @param [in] order MP integer representing order of curve. + * @param [in] max Maximum number of bytes to encode into. + * @param [out] r MP integer that is the result after fixing. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +static int eccsi_fit_to_octets(const mp_int* a, mp_int* order, int max, + mp_int* r) +{ + int err; + + if (mp_count_bits(a) > max * 8) { + err = mp_sub(order, (mp_int*)a, r); + } + else + { + err = mp_copy(a, r); + } + + return err; +} +#else +/* + * Fit the number to the maximum number of bytes. + * + * If the number is too big then subtract from order. + * RFC 6507, Section 5.2.1, Note at end. + * This should only happen when order is larger than prime in bits. + * + * @param [in] a MP integer to fix. + * @param [in] order MP integer representing order of curve. + * @param [in] max Maximum number of bytes to encode into. + * @param [out] r MP integer that is the result after fixing. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +static int eccsi_fit_to_octets(const mp_int* a, const mp_int* order, int max, + mp_int* r) +{ + (void)order; + (void)max; + + /* Duplicate line to stop static analyzer complaining. */ + return mp_copy(a, r); +} +#endif + +/* + * Compute the HE = hash( HS | r | M ), hash value of signature. + * + * Partial result required for signing and verification. + * + * @param [in] key ECCSI key. + * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256 + * @param [in] r MP integer that is the first signature element. + * @param [in] msg Message of signature. + * @param [in] msgSz Length of message in bytes. + * @param [out] he Signature hash. + * @param [out] heSz Length of signature hash in bytes + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value when an internal operation fails. + */ +static int eccsi_compute_he(EccsiKey* key, enum wc_HashType hashType, + mp_int* r, const byte* msg, word32 msgSz, byte* he, word32* heSz) +{ + int err = 0; + word32 dataSz = key->ecc.dp->size; + + /* HE = hash( HS | r | M ) */ + err = wc_HashInit_ex(&key->hash, hashType, key->heap, INVALID_DEVID); + if (err == 0) { + /* HS */ + err = wc_HashUpdate(&key->hash, hashType, key->idHash, key->idHashSz); + } + if (err == 0) { + err = mp_to_unsigned_bin_len(r, key->data, dataSz); + } + if (err == 0) { + /* r */ + err = wc_HashUpdate(&key->hash, hashType, key->data, dataSz); + } + if (err == 0) { + /* M */ + err = wc_HashUpdate(&key->hash, hashType, msg, msgSz); + } + if (err == 0) { + err = wc_HashFinal(&key->hash, hashType, he); + } + if (err == 0) { + *heSz = wc_HashGetDigestSize(hashType); + } + + return err; +} + +/* + * Encode the signature = ( r | s | PVT ) + * + * @param [in] key ECCSI key. + * @param [in] r MP integer that is the first signature element. + * @param [in] s MP integer that is the second signature element. + * @param [in] pvt ECC point representing Public Validation Token. + * @param [out] sig Signature of message. + * @param [out] sigSz Length of signature in bytes. + */ +static int eccsi_encode_sig(const EccsiKey* key, mp_int* r, mp_int* s, + byte* sig, word32* sigSz) +{ + int err; + word32 sz = key->ecc.dp->size; + + err = mp_to_unsigned_bin_len(r, sig, sz); + if (err == 0) { + err = mp_to_unsigned_bin_len(s, sig + sz, sz); + } + if (err == 0) { + *sigSz = key->ecc.dp->size * 2 + 1; + err = wc_ecc_export_point_der(wc_ecc_get_curve_idx(key->ecc.dp->id), + key->pvt, sig + sz * 2, sigSz); + } + if (err == 0) { + *sigSz = sz * 4 + 1; + } + + return err; +} + +/* + * Sign the ECCSI hash (of ID with the key) to two mp_int objects: r and s. + * + * RFC 6507, Section 5.2.1, Steps 1 to 4 + * + * @param [in] key ECCSI key. + * @param [in] rng Random number generator. + * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256 + * @param [in] msg Message to sign. + * @param [in] msgSz Length of message in bytes. + * @param [out] r First big number integer part of signature. + * @param [out] s Second big number integer part of signature. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value when an internal operation fails. + */ +static int eccsi_gen_sig(EccsiKey* key, WC_RNG* rng, enum wc_HashType hashType, + const byte* msg, word32 msgSz, mp_int* r, mp_int* s) +{ + int err = 0; + word32 sz = key->ecc.dp->size; + word32 heSz = 0; + const mp_int* jx = NULL; + mp_int* he = &key->tmp; + int genTryCnt = 0; + + do { + /* Don't infinitely gen sigs when random number generator fails. */ + if ((++genTryCnt) > ECCSI_MAX_GEN_COUNT) { + err = RNG_FAILURE_E; + } + + if (err == 0) { + /* Step 1 and 2: Generate ephemeral key - j, J = [j]G, r = Jx */ + err = wc_ecc_make_key_ex(rng, sz, &key->pubkey, key->ecc.dp->id); + } + if (err == 0) { + jx = key->pubkey.pubkey.x; + err = eccsi_fit_to_octets(jx, &key->params.order, sz, r); + } + + /* Step 3: Compute HE = hash( HS | r | M ) */ + if (err == 0) { + err = eccsi_compute_he(key, hashType, r, msg, msgSz, key->data, + &heSz); + } + + /* Step 4: Verify that HE + r * SSK is non-zero modulo q */ + if (err == 0) { + err = mp_read_unsigned_bin(he, key->data, heSz); + } + /* s' = r * SSK */ + if (err == 0) { + err = mp_mulmod(r, &key->ssk, &key->params.order, s); + } + /* s' = HE + r * SSK */ + if (err == 0) { + err = mp_addmod(he, s, &key->params.order, s); + } + } + while ((err == 0) && (mp_iszero(s) || (mp_cmp(s, he) == MP_EQ))); + + return err; +} + + +/** + * Sign the ECCSI hash (of ID with the key). + * + * RFC 6507, Section 5.2.1 + * + * Must have imported KPAK using wc_ImportEccsiPublicKey() before calling.\n + * Use wc_HashEccsiId() to calculate the hash and wc_SetEccsiHash() to set + * the identity hash to use. + * + * @param [in] key ECCSI key. + * @param [in] rng Random number generator. + * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256 + * @param [in] msg Message to sign. + * @param [in] msgSz Length of message in bytes. + * @param [out] sig Signature of message. + * @param [out] sigSz Length of signature in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, rng, msg or sigSz is NULL. + * @return BAD_STATE_E when the curve or id hash has not been set (no key set). + * @return LENGTH_ONLY_E when sig is NULL - sigSz is set. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value when an internal operation fails. + */ +int wc_SignEccsiHash(EccsiKey* key, WC_RNG* rng, enum wc_HashType hashType, + const byte* msg, word32 msgSz, byte* sig, word32* sigSz) +{ + int err = 0; + mp_int* r = NULL; + mp_int* s = NULL; + mp_int* j = NULL; + word32 sz = 0; + + if ((key == NULL) || (rng == NULL) || (msg == NULL) || (sigSz == NULL)) { + err = BAD_FUNC_ARG; + } + if ((err == 0) && (key->ecc.type != ECC_PUBLICKEY) && + (key->ecc.type != ECC_PRIVATEKEY)) { + err = BAD_STATE_E; + } + if ((err == 0) && (sig != NULL) && (key->idHashSz == 0)) { + err = BAD_STATE_E; + } + + if (err == 0) { + sz = key->ecc.dp->size; + if (sig == NULL) { + *sigSz = sz * 4 + 1; + err = LENGTH_ONLY_E; + } + } + if ((err == 0) && (*sigSz < sz * 4 + 1)) { + err = BAD_FUNC_ARG; + } + + if (err == 0) { + r = key->pubkey.pubkey.y; + s = key->pubkey.pubkey.z; + + err = eccsi_load_order(key); + } + + if (err == 0) { + /* Steps 1 to 4. */ + err = eccsi_gen_sig(key, rng, hashType, msg, msgSz, r, s); + } + + /* Step 5: s' = ( (( HE + r * SSK )^-1) * j ) modulo q, erase j */ + if (err == 0) { + err = mp_invmod(s, &key->params.order, s); + } + if (err == 0) { + j = &key->pubkey.k; + err = mp_mulmod(s, j, &key->params.order, s); + } + if (err == 0) { + mp_forcezero(j); + + /* Step 6: s = s' fitted */ + err = eccsi_fit_to_octets(s, &key->params.order, sz, s); + } + + /* Step 7: Output Signature = ( r | s | PVT ) */ + if (err == 0) { + err = eccsi_encode_sig(key, r, s, sig, sigSz); + } + + return err; +} + +/* + * Decode the s part of the signature = ( r | s | PVT ) + * + * @param [in] key ECCSI key. + * @param [in] sig Signature of message. + * @param [in] sigSz Length of signature in bytes. + * @param [out] s MP integer that is the second signature element. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value when an internal operation fails. + */ +static int eccsi_decode_sig_s(const EccsiKey* key, const byte* sig, + word32 sigSz, mp_int* s) +{ + int err = 0; + word32 sz = key->ecc.dp->size; + + if (sigSz != sz * 4 + 1) { + err = BAD_FUNC_ARG; + } + + if (err == 0) { + err = mp_read_unsigned_bin(s, sig + sz, sz); + } + + return err; +} + +/* + * Decode the r and pvt part of the signature = ( r | s | PVT ) + * + * @param [in] key ECCSI key. + * @param [in] sig Signature of message. + * @param [in] sigSz Length of signature in bytes. + * @param [out] r MP integer that is the first signature element. + * @param [out] pvt ECC point representing Public Validation Token. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value when an internal operation fails. + */ +static int eccsi_decode_sig_r_pvt(const EccsiKey* key, const byte* sig, + word32 sigSz, mp_int* r, ecc_point* pvt) +{ + int err = 0; + word32 sz = key->ecc.dp->size; + + if (sigSz != sz * 4 + 1) { + err = BAD_FUNC_ARG; + } + + if (err == 0) { + err = mp_read_unsigned_bin(r, sig, sz); + } + if (err == 0) { + err = wc_ecc_import_point_der(sig + sz * 2, sz * 2 + 1, + wc_ecc_get_curve_idx(key->ecc.dp->id), pvt); + } + + return err; +} + +/* + * Calculate Y point as part of verification process. + * + * Y = [HS]PVT + KPAK + * + * @param [in] key ECCSI key. + * @param [in] pvt ECC point representing Public Validation Token. + * @param [in] mp Montgomery reduction multiplier. + * @param [out] y ECC point representing calculated value Y. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other value when an an internal operation fails. + */ +static int eccsi_calc_y(EccsiKey* key, ecc_point* pvt, mp_digit mp, + ecc_point* y) +{ + int err; + mp_int* hs = &key->ssk; + + err = mp_read_unsigned_bin(hs, key->idHash, key->idHashSz); +#ifndef WOLFSSL_HAVE_SP_ECC + /* Need KPAK in montogmery form. */ + if (err == 0) { + err = eccsi_kpak_to_mont(key); + } +#endif + /* [HS]PVT + KPAK */ + if (err == 0) { + ecc_point* kpak = &key->ecc.pubkey; + err = eccsi_mulmod_point_add(key, hs, pvt, kpak, y, mp, 1); + } + + return err; +} + +/* + * Calculate J point as part of verification process. + * + * J = [s]( [HE]G + [r]Y ) + * + * @param [in] key ECCSI key. + * @param [in] hem MP int representation of HE = Hash (hs, r and message). + * @param [in] sig Signature of message. + * @param [in] sigSz Length of signature in bytes. + * @param [in] y ECC point representing [r]Y. + * @param [in] mp Montgomery reduction multiplier. + * @param [out] j ECC point representing calculated value J. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other value when an an internal operation fails. + */ +static int eccsi_calc_j(EccsiKey* key, const mp_int* hem, const byte* sig, + word32 sigSz, ecc_point* y, mp_digit mp, ecc_point* j) +{ + int err; + mp_int* s = &key->tmp; + + /* [HE]G + [r]Y */ + err = eccsi_mulmod_base_add(key, hem, y, j, mp, 1); + if (err == 0) { + err = eccsi_decode_sig_s(key, sig, sigSz, s); + } + /* [s]( [HE]G + [r]Y ) */ + if (err == 0) { + err = eccsi_mulmod_point(key, s, j, j, 1); + } + + return err; +} + +/** + * Verify the ECCSI hash (of ID with the key). + * + * RFC 6507, Section 5.2.2 + * + * Must have imported KPAK using wc_ImportEccsiPublicKey() before calling.\n + * Use wc_HashEccsiId() to calculate the hash and wc_SetEccsiHash() to set + * the identity hash to use. + * + * @param [in] key ECCSI key. + * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256 + * @param [in] msg Message to verify. + * @param [in] msgSz Length of message in bytes. + * @param [in] sig Signature of message. + * @param [in] sigSz Length of signature in bytes. + * @param [out] verified 1 when the signature was verified and 0 otherwise. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, hash, msg, sig or ret is NULL. + * @return BAD_STATE_E when the curve or id hash has not been set (no key set). + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other value when an an internal operation fails. + */ +int wc_VerifyEccsiHash(EccsiKey* key, enum wc_HashType hashType, + const byte* msg, word32 msgSz, const byte* sig, word32 sigSz, + int* verified) +{ + int err = 0; + byte* he = NULL; + word32 heSz = 0; + mp_int* r = NULL; + mp_int* jx = NULL; + mp_int* hem = NULL; + ecc_point* pvt = NULL; + ecc_point* y = NULL; + ecc_point* j = NULL; + mp_digit mp = 0; + EccsiKeyParams* params = &key->params; + + if ((key == NULL) || (msg == NULL) || (sig == NULL) || (verified == NULL)) { + err = BAD_FUNC_ARG; + } + if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY) && + (key->ecc.type != ECC_PUBLICKEY)) { + err = BAD_STATE_E; + } + if ((err == 0) && (key->idHashSz == 0)) { + err = BAD_STATE_E; + } + + /* Decode the signature into components. */ + if (err == 0) { + r = &key->pubkey.k; + pvt = &key->pubkey.pubkey; + err = eccsi_decode_sig_r_pvt(key, sig, sigSz, r, pvt); + } + + /* Load the curve parameters for operations */ + if (err == 0) { + err = eccsi_load_base(key); + } + if (err == 0) { + err = eccsi_load_ecc_params(key); + } + if (err == 0) { + err = mp_montgomery_setup(¶ms->prime, &mp); + } + + /* Step 1: Validate PVT is on curve */ + if (err == 0) { + err = wc_ecc_is_point(pvt, ¶ms->a, ¶ms->b, ¶ms->prime); + } + + /* Step 2: Compute HS = hash( G | KPAK | ID | PVT ) + * HS is key->idHash, key->idHashSz */ + + /* Step 3: Compute HE = hash( HS | r | M ) */ + if (err == 0) { + he = key->data; + err = eccsi_compute_he(key, hashType, r, msg, msgSz, he, &heSz); + } + + /* Step 4: Y = [HS]PVT + KPAK */ + if (err == 0) { + y = pvt; + err = eccsi_calc_y(key, pvt, mp, y); + } + + /* Step 5: Compute J = [s]( [HE]G + [r]Y ) */ + /* [r]Y */ + if (err == 0) { + hem = &key->tmp; + err = mp_read_unsigned_bin(hem, he, heSz); + } + if (err == 0) { + err = eccsi_mulmod_point(key, r, y, y, 0); + } + if (err == 0) { + j = params->base; + err = eccsi_calc_j(key, hem, sig, sigSz, y, mp, j); + key->params.haveBase = 0; + } + + /* Step 6: Jx fitting, compare with r */ + if (err == 0) { + jx = &key->tmp; + err = eccsi_fit_to_octets(j->x, ¶ms->order, key->ecc.dp->size, jx); + } + + if (verified != NULL) { + *verified = ((err == 0) && (mp_cmp(jx, r) == MP_EQ)); + } + + return err; +} +#endif /* WOLFCRYPT_ECCSI_CLIENT */ + +#endif /* WOLFCRYPT_HAVE_ECCSI */ + diff --git a/wolfcrypt/src/ed25519.c b/wolfcrypt/src/ed25519.c index 64aee3389..a01e0bffd 100644 --- a/wolfcrypt/src/ed25519.c +++ b/wolfcrypt/src/ed25519.c @@ -1,6 +1,6 @@ /* ed25519.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/ed448.c b/wolfcrypt/src/ed448.c index 366c7105b..bb401d28c 100644 --- a/wolfcrypt/src/ed448.c +++ b/wolfcrypt/src/ed448.c @@ -1,6 +1,6 @@ /* ed448.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/error.c b/wolfcrypt/src/error.c index b9ec96085..24eb04449 100644 --- a/wolfcrypt/src/error.c +++ b/wolfcrypt/src/error.c @@ -1,6 +1,6 @@ /* error.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -518,6 +518,9 @@ const char* wc_GetErrorString(int error) case ASN_SELF_SIGNED_E: return "ASN self-signed certificate error"; + case SAKKE_VERIFY_FAIL_E: + return "SAKKE derivation verification error"; + default: return "unknown error number"; diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 798eea120..b87a32a70 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -1,6 +1,6 @@ /* evp.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fe_low_mem.c b/wolfcrypt/src/fe_low_mem.c index b42cdfdfd..f683cd7d5 100644 --- a/wolfcrypt/src/fe_low_mem.c +++ b/wolfcrypt/src/fe_low_mem.c @@ -1,6 +1,6 @@ /* fe_low_mem.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fe_operations.c b/wolfcrypt/src/fe_operations.c index 8a0248a5f..9fc299d2c 100644 --- a/wolfcrypt/src/fe_operations.c +++ b/wolfcrypt/src/fe_operations.c @@ -1,6 +1,6 @@ /* fe_operations.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fe_x25519_asm.S b/wolfcrypt/src/fe_x25519_asm.S index 2a85fab8d..48b1a17f5 100644 --- a/wolfcrypt/src/fe_x25519_asm.S +++ b/wolfcrypt/src/fe_x25519_asm.S @@ -1,6 +1,6 @@ /* fe_x25519_asm * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_mont_small.i b/wolfcrypt/src/fp_mont_small.i index 380b0a25b..4cfe411f0 100644 --- a/wolfcrypt/src/fp_mont_small.i +++ b/wolfcrypt/src/fp_mont_small.i @@ -1,6 +1,6 @@ /* fp_mont_small.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_mul_comba_12.i b/wolfcrypt/src/fp_mul_comba_12.i index 0f0683d74..8d29a06fd 100644 --- a/wolfcrypt/src/fp_mul_comba_12.i +++ b/wolfcrypt/src/fp_mul_comba_12.i @@ -1,6 +1,6 @@ /* fp_mul_comba_12.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_mul_comba_17.i b/wolfcrypt/src/fp_mul_comba_17.i index fb3205515..c5e1a7203 100644 --- a/wolfcrypt/src/fp_mul_comba_17.i +++ b/wolfcrypt/src/fp_mul_comba_17.i @@ -1,6 +1,6 @@ /* fp_mul_comba_17.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_mul_comba_20.i b/wolfcrypt/src/fp_mul_comba_20.i index 372f51f41..599d3e516 100644 --- a/wolfcrypt/src/fp_mul_comba_20.i +++ b/wolfcrypt/src/fp_mul_comba_20.i @@ -1,6 +1,6 @@ /* fp_mul_comba_20.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_mul_comba_24.i b/wolfcrypt/src/fp_mul_comba_24.i index 17705f7df..561dda2db 100644 --- a/wolfcrypt/src/fp_mul_comba_24.i +++ b/wolfcrypt/src/fp_mul_comba_24.i @@ -1,6 +1,6 @@ /* fp_mul_comba_24.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_mul_comba_28.i b/wolfcrypt/src/fp_mul_comba_28.i index 594db74ef..a2ae5606d 100644 --- a/wolfcrypt/src/fp_mul_comba_28.i +++ b/wolfcrypt/src/fp_mul_comba_28.i @@ -1,6 +1,6 @@ /* fp_mul_comba_28.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_mul_comba_3.i b/wolfcrypt/src/fp_mul_comba_3.i index 0befff860..a4981726a 100644 --- a/wolfcrypt/src/fp_mul_comba_3.i +++ b/wolfcrypt/src/fp_mul_comba_3.i @@ -1,6 +1,6 @@ /* fp_mul_comba_3.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_mul_comba_32.i b/wolfcrypt/src/fp_mul_comba_32.i index 97dc076be..63543435d 100644 --- a/wolfcrypt/src/fp_mul_comba_32.i +++ b/wolfcrypt/src/fp_mul_comba_32.i @@ -1,6 +1,6 @@ /* fp_mul_comba_32.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_mul_comba_4.i b/wolfcrypt/src/fp_mul_comba_4.i index 803c6151a..6f6f542bb 100644 --- a/wolfcrypt/src/fp_mul_comba_4.i +++ b/wolfcrypt/src/fp_mul_comba_4.i @@ -1,6 +1,6 @@ /* fp_mul_comba_4.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_mul_comba_48.i b/wolfcrypt/src/fp_mul_comba_48.i index 0d1533458..c1f307f76 100644 --- a/wolfcrypt/src/fp_mul_comba_48.i +++ b/wolfcrypt/src/fp_mul_comba_48.i @@ -1,6 +1,6 @@ /* fp_mul_comba_48.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_mul_comba_6.i b/wolfcrypt/src/fp_mul_comba_6.i index 815badcb8..a076e47ab 100644 --- a/wolfcrypt/src/fp_mul_comba_6.i +++ b/wolfcrypt/src/fp_mul_comba_6.i @@ -1,6 +1,6 @@ /* fp_mul_comba_6.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_mul_comba_64.i b/wolfcrypt/src/fp_mul_comba_64.i index 7080fa2a3..ba6a21a4a 100644 --- a/wolfcrypt/src/fp_mul_comba_64.i +++ b/wolfcrypt/src/fp_mul_comba_64.i @@ -1,6 +1,6 @@ /* fp_mul_comba_64.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_mul_comba_7.i b/wolfcrypt/src/fp_mul_comba_7.i index b969a9a3b..bc07b24ab 100644 --- a/wolfcrypt/src/fp_mul_comba_7.i +++ b/wolfcrypt/src/fp_mul_comba_7.i @@ -1,6 +1,6 @@ /* fp_mul_comba_7.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_mul_comba_8.i b/wolfcrypt/src/fp_mul_comba_8.i index 1d61a7781..f8fc01ea9 100644 --- a/wolfcrypt/src/fp_mul_comba_8.i +++ b/wolfcrypt/src/fp_mul_comba_8.i @@ -1,6 +1,6 @@ /* fp_mul_comba_8.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_mul_comba_9.i b/wolfcrypt/src/fp_mul_comba_9.i index 0eedd7597..87eef030b 100644 --- a/wolfcrypt/src/fp_mul_comba_9.i +++ b/wolfcrypt/src/fp_mul_comba_9.i @@ -1,6 +1,6 @@ /* fp_mul_comba_9.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_mul_comba_small_set.i b/wolfcrypt/src/fp_mul_comba_small_set.i index 62ab909cf..d2d12d31e 100644 --- a/wolfcrypt/src/fp_mul_comba_small_set.i +++ b/wolfcrypt/src/fp_mul_comba_small_set.i @@ -1,6 +1,6 @@ /* fp_mul_comba_small_set.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_sqr_comba_12.i b/wolfcrypt/src/fp_sqr_comba_12.i index cded4b123..5aa809e4e 100644 --- a/wolfcrypt/src/fp_sqr_comba_12.i +++ b/wolfcrypt/src/fp_sqr_comba_12.i @@ -1,6 +1,6 @@ /* fp_sqr_comba_12.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_sqr_comba_17.i b/wolfcrypt/src/fp_sqr_comba_17.i index d2418d931..c669683ed 100644 --- a/wolfcrypt/src/fp_sqr_comba_17.i +++ b/wolfcrypt/src/fp_sqr_comba_17.i @@ -1,6 +1,6 @@ /* fp_sqr_comba_17.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_sqr_comba_20.i b/wolfcrypt/src/fp_sqr_comba_20.i index 78fd3fd96..0d965a81b 100644 --- a/wolfcrypt/src/fp_sqr_comba_20.i +++ b/wolfcrypt/src/fp_sqr_comba_20.i @@ -1,6 +1,6 @@ /* fp_sqr_comba_20.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_sqr_comba_24.i b/wolfcrypt/src/fp_sqr_comba_24.i index 602b36c09..971ddd2b9 100644 --- a/wolfcrypt/src/fp_sqr_comba_24.i +++ b/wolfcrypt/src/fp_sqr_comba_24.i @@ -1,6 +1,6 @@ /* fp_sqr_comba_24.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_sqr_comba_28.i b/wolfcrypt/src/fp_sqr_comba_28.i index 57c1acc30..7c4c78850 100644 --- a/wolfcrypt/src/fp_sqr_comba_28.i +++ b/wolfcrypt/src/fp_sqr_comba_28.i @@ -1,6 +1,6 @@ /* fp_sqr_comba_28.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_sqr_comba_3.i b/wolfcrypt/src/fp_sqr_comba_3.i index 51c3d7422..3b47cba8c 100644 --- a/wolfcrypt/src/fp_sqr_comba_3.i +++ b/wolfcrypt/src/fp_sqr_comba_3.i @@ -1,6 +1,6 @@ /* fp_sqr_comba_3.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_sqr_comba_32.i b/wolfcrypt/src/fp_sqr_comba_32.i index 4fcf3497b..02b027385 100644 --- a/wolfcrypt/src/fp_sqr_comba_32.i +++ b/wolfcrypt/src/fp_sqr_comba_32.i @@ -1,6 +1,6 @@ /* fp_sqr_comba_32.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_sqr_comba_4.i b/wolfcrypt/src/fp_sqr_comba_4.i index b7f257288..13935083c 100644 --- a/wolfcrypt/src/fp_sqr_comba_4.i +++ b/wolfcrypt/src/fp_sqr_comba_4.i @@ -1,6 +1,6 @@ /* fp_sqr_comba_4.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_sqr_comba_48.i b/wolfcrypt/src/fp_sqr_comba_48.i index 0f24532b1..d817aa9b5 100644 --- a/wolfcrypt/src/fp_sqr_comba_48.i +++ b/wolfcrypt/src/fp_sqr_comba_48.i @@ -1,6 +1,6 @@ /* fp_sqr_comba_48.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_sqr_comba_6.i b/wolfcrypt/src/fp_sqr_comba_6.i index b36416844..1e4651a9d 100644 --- a/wolfcrypt/src/fp_sqr_comba_6.i +++ b/wolfcrypt/src/fp_sqr_comba_6.i @@ -1,6 +1,6 @@ /* fp_sqr_comba_6.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_sqr_comba_64.i b/wolfcrypt/src/fp_sqr_comba_64.i index b9b2c8ab7..f8af68dc7 100644 --- a/wolfcrypt/src/fp_sqr_comba_64.i +++ b/wolfcrypt/src/fp_sqr_comba_64.i @@ -1,6 +1,6 @@ /* fp_sqr_comba_64.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_sqr_comba_7.i b/wolfcrypt/src/fp_sqr_comba_7.i index 09bf9954a..807ef5920 100644 --- a/wolfcrypt/src/fp_sqr_comba_7.i +++ b/wolfcrypt/src/fp_sqr_comba_7.i @@ -1,6 +1,6 @@ /* fp_sqr_comba_7.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_sqr_comba_8.i b/wolfcrypt/src/fp_sqr_comba_8.i index 23fd8e41d..53054689b 100644 --- a/wolfcrypt/src/fp_sqr_comba_8.i +++ b/wolfcrypt/src/fp_sqr_comba_8.i @@ -1,6 +1,6 @@ /* fp_sqr_comba_8.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_sqr_comba_9.i b/wolfcrypt/src/fp_sqr_comba_9.i index ed6451a77..c405c954f 100644 --- a/wolfcrypt/src/fp_sqr_comba_9.i +++ b/wolfcrypt/src/fp_sqr_comba_9.i @@ -1,6 +1,6 @@ /* fp_sqr_comba_9.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/fp_sqr_comba_small_set.i b/wolfcrypt/src/fp_sqr_comba_small_set.i index a81ee10e2..64ae83c3d 100644 --- a/wolfcrypt/src/fp_sqr_comba_small_set.i +++ b/wolfcrypt/src/fp_sqr_comba_small_set.i @@ -1,6 +1,6 @@ /* fp_sqr_comba_small_set.i * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/ge_low_mem.c b/wolfcrypt/src/ge_low_mem.c index a6b5b68be..a7b793842 100644 --- a/wolfcrypt/src/ge_low_mem.c +++ b/wolfcrypt/src/ge_low_mem.c @@ -1,6 +1,6 @@ /* ge_low_mem.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/ge_operations.c b/wolfcrypt/src/ge_operations.c index beaa56e66..f743ef87b 100644 --- a/wolfcrypt/src/ge_operations.c +++ b/wolfcrypt/src/ge_operations.c @@ -1,6 +1,6 @@ /* ge_operations.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/hash.c b/wolfcrypt/src/hash.c index b820dc3c5..921210bce 100644 --- a/wolfcrypt/src/hash.c +++ b/wolfcrypt/src/hash.c @@ -1,6 +1,6 @@ /* hash.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/hc128.c b/wolfcrypt/src/hc128.c index 96f02d16d..000501da9 100644 --- a/wolfcrypt/src/hc128.c +++ b/wolfcrypt/src/hc128.c @@ -1,6 +1,6 @@ /* hc128.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/hmac.c b/wolfcrypt/src/hmac.c index f0e62c76e..818c505af 100644 --- a/wolfcrypt/src/hmac.c +++ b/wolfcrypt/src/hmac.c @@ -1,6 +1,6 @@ /* hmac.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -1164,6 +1164,8 @@ void wc_HmacFree(Hmac* hmac) wc_Sha512Free(&hmac->hash.sha512); break; #endif /* WOLFSSL_SHA512 */ + default: + break; } } diff --git a/wolfcrypt/src/idea.c b/wolfcrypt/src/idea.c index 600c90654..1fb82e69b 100644 --- a/wolfcrypt/src/idea.c +++ b/wolfcrypt/src/idea.c @@ -1,6 +1,6 @@ /* idea.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index bf58078ac..c5a14e50c 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -8,6 +8,7 @@ EXTRA_DIST += wolfcrypt/src/asm.c EXTRA_DIST += wolfcrypt/src/aes_asm.asm EXTRA_DIST += wolfcrypt/src/wc_dsp.c EXTRA_DIST += wolfcrypt/src/sp_dsp32.c +EXTRA_DIST += wolfcrypt/src/sp_x86_64_asm.asm EXTRA_DIST += \ wolfcrypt/src/ecc_fp.c \ diff --git a/wolfcrypt/src/integer.c b/wolfcrypt/src/integer.c index 83485ecb0..fbdff4c6f 100644 --- a/wolfcrypt/src/integer.c +++ b/wolfcrypt/src/integer.c @@ -1,6 +1,6 @@ /* integer.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -238,7 +238,7 @@ void mp_forcezero(mp_int * a) /* get the size for an unsigned equivalent */ -int mp_unsigned_bin_size (mp_int * a) +int mp_unsigned_bin_size (const mp_int * a) { int size = mp_count_bits (a); return (size / 8 + ((size & 7) != 0 ? 1 : 0)); @@ -246,7 +246,7 @@ int mp_unsigned_bin_size (mp_int * a) /* returns the number of bits in an int */ -int mp_count_bits (mp_int * a) +int mp_count_bits (const mp_int * a) { int r; mp_digit q; @@ -350,7 +350,7 @@ int mp_init_copy (mp_int * a, mp_int * b) /* copy, b = a */ -int mp_copy (mp_int * a, mp_int * b) +int mp_copy (const mp_int * a, mp_int * b) { int res, n; diff --git a/wolfcrypt/src/logging.c b/wolfcrypt/src/logging.c index 5a9908831..447dbcb30 100644 --- a/wolfcrypt/src/logging.c +++ b/wolfcrypt/src/logging.c @@ -1,6 +1,6 @@ /* logging.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -227,20 +227,24 @@ void wolfSSL_Debugging_OFF(void) */ void WOLFSSL_START(int funcNum) { - double now = current_time(0) * 1000.0; -#ifdef WOLFSSL_FUNC_TIME_LOG - fprintf(stderr, "%17.3f: START - %s\n", now, wc_func_name[funcNum]); -#endif - wc_func_start[funcNum] = now; + if (funcNum < WC_FUNC_COUNT) { + double now = current_time(0) * 1000.0; + #ifdef WOLFSSL_FUNC_TIME_LOG + fprintf(stderr, "%17.3f: START - %s\n", now, wc_func_name[funcNum]); + #endif + wc_func_start[funcNum] = now; + } } void WOLFSSL_END(int funcNum) { - double now = current_time(0) * 1000.0; - wc_func_time[funcNum] += now - wc_func_start[funcNum]; -#ifdef WOLFSSL_FUNC_TIME_LOG - fprintf(stderr, "%17.3f: END - %s\n", now, wc_func_name[funcNum]); -#endif + if (funcNum < WC_FUNC_COUNT) { + double now = current_time(0) * 1000.0; + wc_func_time[funcNum] += now - wc_func_start[funcNum]; + #ifdef WOLFSSL_FUNC_TIME_LOG + fprintf(stderr, "%17.3f: END - %s\n", now, wc_func_name[funcNum]); + #endif + } } void WOLFSSL_TIME(int count) diff --git a/wolfcrypt/src/md2.c b/wolfcrypt/src/md2.c index c2f34203d..d4f16859f 100644 --- a/wolfcrypt/src/md2.c +++ b/wolfcrypt/src/md2.c @@ -1,6 +1,6 @@ /* md2.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/md4.c b/wolfcrypt/src/md4.c index f6f67454a..d6e061051 100644 --- a/wolfcrypt/src/md4.c +++ b/wolfcrypt/src/md4.c @@ -1,6 +1,6 @@ /* md4.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/md5.c b/wolfcrypt/src/md5.c index 9c1840e25..22774d54d 100644 --- a/wolfcrypt/src/md5.c +++ b/wolfcrypt/src/md5.c @@ -1,6 +1,6 @@ /* md5.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -196,7 +196,7 @@ static int Transform_Len(wc_Md5* md5, const byte* data, word32 len) static int Transform(wc_Md5* md5, const byte* data) { - word32* buffer = (word32*)data; + const word32* buffer = (const word32*)data; /* Copy context->state[] to working vars */ word32 a = md5->digest[0]; word32 b = md5->digest[1]; diff --git a/wolfcrypt/src/memory.c b/wolfcrypt/src/memory.c index 2352c5e00..5f2b39e73 100644 --- a/wolfcrypt/src/memory.c +++ b/wolfcrypt/src/memory.c @@ -1,6 +1,6 @@ /* memory.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -1031,7 +1031,7 @@ void XFREE(void *p, void* heap, int type) void *xmalloc(size_t n, void* heap, int type, const char* func, const char* file, unsigned int line) { - void* p; + void* p = NULL; word32* p32; if (malloc_function) @@ -1039,11 +1039,13 @@ void *xmalloc(size_t n, void* heap, int type, const char* func, else p32 = malloc(n + sizeof(word32) * 4); - p32[0] = (word32)n; - p = (void*)(p32 + 4); + if (p32 != NULL) { + p32[0] = (word32)n; + p = (void*)(p32 + 4); - fprintf(stderr, "Alloc: %p -> %u (%d) at %s:%s:%u\n", p, (word32)n, type, - func, file, line); + fprintf(stderr, "Alloc: %p -> %u (%d) at %s:%s:%u\n", p, (word32)n, + type, func, file, line); + } (void)heap; diff --git a/wolfcrypt/src/misc.c b/wolfcrypt/src/misc.c index d82d5dbc7..13bcc3aca 100644 --- a/wolfcrypt/src/misc.c +++ b/wolfcrypt/src/misc.c @@ -1,6 +1,6 @@ /* misc.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/pkcs12.c b/wolfcrypt/src/pkcs12.c index 10bb8b3cc..824f91aa0 100644 --- a/wolfcrypt/src/pkcs12.c +++ b/wolfcrypt/src/pkcs12.c @@ -1,6 +1,6 @@ /* pkcs12.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -536,6 +536,7 @@ static int wc_PKCS12_create_mac(WC_PKCS12* pkcs12, byte* data, word32 dataSz, /* get hash type used and resulting size of HMAC key */ hashT = wc_OidGetHash(mac->oid); if (hashT == WC_HASH_TYPE_NONE) { + ForceZero(unicodePasswd, MAX_UNICODE_SZ); WOLFSSL_MSG("Unsupported hash used"); return BAD_FUNC_ARG; } @@ -543,12 +544,15 @@ static int wc_PKCS12_create_mac(WC_PKCS12* pkcs12, byte* data, word32 dataSz, /* check out buffer is large enough */ if (kLen < 0 || outSz < (word32)kLen) { + ForceZero(unicodePasswd, MAX_UNICODE_SZ); return BAD_FUNC_ARG; } /* idx contains size of unicodePasswd */ - if ((ret = wc_PKCS12_PBKDF_ex(key, unicodePasswd, idx, mac->salt, - mac->saltSz, mac->itt, kLen, (int)hashT, id, pkcs12->heap)) < 0) { + ret = wc_PKCS12_PBKDF_ex(key, unicodePasswd, idx, mac->salt, mac->saltSz, + mac->itt, kLen, (int)hashT, id, pkcs12->heap); + ForceZero(unicodePasswd, MAX_UNICODE_SZ); + if (ret < 0) { return ret; } diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 90c740e8e..460e00575 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -1,6 +1,6 @@ /* pkcs7.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/poly1305.c b/wolfcrypt/src/poly1305.c index 4fde6be95..2c4aa12af 100644 --- a/wolfcrypt/src/poly1305.c +++ b/wolfcrypt/src/poly1305.c @@ -1,6 +1,6 @@ /* poly1305.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -723,8 +723,10 @@ int wc_Poly1305Update(Poly1305* ctx, const byte* m, word32 bytes) poly1305_calc_powers_avx2(ctx); poly1305_blocks_avx2(ctx, ctx->buffer, sizeof(ctx->buffer)); ctx->leftover = 0; - } else + } + else { SAVE_VECTOR_REGISTERS(); + } /* process full blocks */ if (bytes >= sizeof(ctx->buffer)) { @@ -804,8 +806,8 @@ int wc_Poly1305_Pad(Poly1305* ctx, word32 lenToPad) XMEMSET(padding, 0, sizeof(padding)); /* Pad length to 16 bytes */ - paddingLen = -(int)lenToPad & (WC_POLY1305_PAD_SZ - 1); - if (paddingLen > 0) { + paddingLen = (-(int)lenToPad) & (WC_POLY1305_PAD_SZ - 1); + if ((paddingLen > 0) && (paddingLen < WC_POLY1305_PAD_SZ)) { ret = wc_Poly1305Update(ctx, padding, paddingLen); } return ret; @@ -870,8 +872,8 @@ int wc_Poly1305_EncodeSizes64(Poly1305* ctx, word64 aadSz, word64 dataSz) tagSz : Size of input tag buffer (must be at least WC_POLY1305_MAC_SZ(16)) */ -int wc_Poly1305_MAC(Poly1305* ctx, byte* additional, word32 addSz, - byte* input, word32 sz, byte* tag, word32 tagSz) +int wc_Poly1305_MAC(Poly1305* ctx, const byte* additional, word32 addSz, + const byte* input, word32 sz, byte* tag, word32 tagSz) { int ret; diff --git a/wolfcrypt/src/poly1305_asm.S b/wolfcrypt/src/poly1305_asm.S index 126e59aca..7b2265fe6 100644 --- a/wolfcrypt/src/poly1305_asm.S +++ b/wolfcrypt/src/poly1305_asm.S @@ -1,6 +1,6 @@ /* poly1305_asm * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/Espressif/esp32_aes.c b/wolfcrypt/src/port/Espressif/esp32_aes.c index f2fb8a5be..cce7a3016 100644 --- a/wolfcrypt/src/port/Espressif/esp32_aes.c +++ b/wolfcrypt/src/port/Espressif/esp32_aes.c @@ -1,6 +1,6 @@ /* esp32_aes.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/Espressif/esp32_mp.c b/wolfcrypt/src/port/Espressif/esp32_mp.c index 2174089b1..b6ad0e79c 100644 --- a/wolfcrypt/src/port/Espressif/esp32_mp.c +++ b/wolfcrypt/src/port/Espressif/esp32_mp.c @@ -1,6 +1,6 @@ /* esp32_mp.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/Espressif/esp32_sha.c b/wolfcrypt/src/port/Espressif/esp32_sha.c index 94789cd64..2f8f38fd9 100644 --- a/wolfcrypt/src/port/Espressif/esp32_sha.c +++ b/wolfcrypt/src/port/Espressif/esp32_sha.c @@ -1,6 +1,6 @@ /* esp32_sha.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/Espressif/esp32_util.c b/wolfcrypt/src/port/Espressif/esp32_util.c index b501b5ea6..d73cd2fe8 100644 --- a/wolfcrypt/src/port/Espressif/esp32_util.c +++ b/wolfcrypt/src/port/Espressif/esp32_util.c @@ -1,6 +1,6 @@ /* esp32_util.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/Renesas/renesas_tsip_aes.c b/wolfcrypt/src/port/Renesas/renesas_tsip_aes.c index ce04ff54f..e4fd7f93d 100644 --- a/wolfcrypt/src/port/Renesas/renesas_tsip_aes.c +++ b/wolfcrypt/src/port/Renesas/renesas_tsip_aes.c @@ -1,6 +1,6 @@ /* renesas_tsip_aes.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/Renesas/renesas_tsip_sha.c b/wolfcrypt/src/port/Renesas/renesas_tsip_sha.c index b12d8eee9..c485eecd5 100644 --- a/wolfcrypt/src/port/Renesas/renesas_tsip_sha.c +++ b/wolfcrypt/src/port/Renesas/renesas_tsip_sha.c @@ -1,6 +1,6 @@ /* renesas_tsip_sha.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/Renesas/renesas_tsip_util.c b/wolfcrypt/src/port/Renesas/renesas_tsip_util.c index 1ed66e6bb..6c4a93622 100644 --- a/wolfcrypt/src/port/Renesas/renesas_tsip_util.c +++ b/wolfcrypt/src/port/Renesas/renesas_tsip_util.c @@ -1,6 +1,6 @@ /* renesas_tsip_util.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/af_alg/afalg_aes.c b/wolfcrypt/src/port/af_alg/afalg_aes.c index 2d1d41a6a..a5dbd79c4 100644 --- a/wolfcrypt/src/port/af_alg/afalg_aes.c +++ b/wolfcrypt/src/port/af_alg/afalg_aes.c @@ -1,6 +1,6 @@ /* afalg_aes.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -565,7 +565,6 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, ret = setsockopt(aes->alFd, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL, authTagSz); if (ret != 0) { - perror("set tag"); WOLFSSL_MSG("Unable to set AF_ALG tag size "); return WC_AFALG_SOCK_E; } diff --git a/wolfcrypt/src/port/af_alg/afalg_hash.c b/wolfcrypt/src/port/af_alg/afalg_hash.c index 41e57bc80..6b2069a34 100644 --- a/wolfcrypt/src/port/af_alg/afalg_hash.c +++ b/wolfcrypt/src/port/af_alg/afalg_hash.c @@ -1,6 +1,6 @@ /* afalg_hash.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -44,11 +44,11 @@ static void AfalgHashFree(wolfssl_AFALG_Hash* hash) return; if (hash->alFd > 0) { - close(hash->alFd); + (void)close(hash->alFd); hash->alFd = -1; /* avoid possible double close on socket */ } if (hash->rdFd > 0) { - close(hash->rdFd); + (void)close(hash->rdFd); hash->rdFd = -1; /* avoid possible double close on socket */ } @@ -86,7 +86,7 @@ static int AfalgHashInit(wolfssl_AFALG_Hash* hash, void* heap, int devId, hash->rdFd = wc_Afalg_CreateRead(hash->alFd, WC_TYPE_HASH, type); if (hash->rdFd < 0) { - close(hash->alFd); + (void)close(hash->alFd); return WC_AFALG_SOCK_E; } diff --git a/wolfcrypt/src/port/af_alg/wc_afalg.c b/wolfcrypt/src/port/af_alg/wc_afalg.c index 0a91b5180..5e0ad7e39 100644 --- a/wolfcrypt/src/port/af_alg/wc_afalg.c +++ b/wolfcrypt/src/port/af_alg/wc_afalg.c @@ -1,6 +1,6 @@ /* wc_afalg.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/arm/armv8-32-curve25519.S b/wolfcrypt/src/port/arm/armv8-32-curve25519.S index 1fcf6f869..f52fc07ac 100644 --- a/wolfcrypt/src/port/arm/armv8-32-curve25519.S +++ b/wolfcrypt/src/port/arm/armv8-32-curve25519.S @@ -1,6 +1,6 @@ /* armv8-32-curve25519 * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/arm/armv8-32-curve25519.c b/wolfcrypt/src/port/arm/armv8-32-curve25519.c index c2c73f3c3..607ad913e 100644 --- a/wolfcrypt/src/port/arm/armv8-32-curve25519.c +++ b/wolfcrypt/src/port/arm/armv8-32-curve25519.c @@ -1,6 +1,6 @@ /* armv8-32-curve25519 * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/arm/armv8-32-sha512-asm.S b/wolfcrypt/src/port/arm/armv8-32-sha512-asm.S index 685f87cc7..23e67fa3d 100644 --- a/wolfcrypt/src/port/arm/armv8-32-sha512-asm.S +++ b/wolfcrypt/src/port/arm/armv8-32-sha512-asm.S @@ -1,6 +1,6 @@ /* armv8-32-sha512-asm * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/arm/armv8-32-sha512-asm.c b/wolfcrypt/src/port/arm/armv8-32-sha512-asm.c index 6786d30b0..a52cd75c6 100644 --- a/wolfcrypt/src/port/arm/armv8-32-sha512-asm.c +++ b/wolfcrypt/src/port/arm/armv8-32-sha512-asm.c @@ -1,6 +1,6 @@ /* armv8-32-sha512-asm * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/arm/armv8-aes.c b/wolfcrypt/src/port/arm/armv8-aes.c index 021ee7963..5f92cbe6f 100644 --- a/wolfcrypt/src/port/arm/armv8-aes.c +++ b/wolfcrypt/src/port/arm/armv8-aes.c @@ -1,6 +1,6 @@ /* armv8-aes.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/arm/armv8-chacha.c b/wolfcrypt/src/port/arm/armv8-chacha.c index 11473d47e..c6af98a67 100644 --- a/wolfcrypt/src/port/arm/armv8-chacha.c +++ b/wolfcrypt/src/port/arm/armv8-chacha.c @@ -1,6 +1,6 @@ /* armv8-chacha.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -17,7 +17,6 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA - * */ /* The paper NEON crypto by Daniel J. Bernstein and Peter Schwabe was used to optimize for ARM diff --git a/wolfcrypt/src/port/arm/armv8-curve25519.S b/wolfcrypt/src/port/arm/armv8-curve25519.S index e8da5267f..b05f0a23b 100644 --- a/wolfcrypt/src/port/arm/armv8-curve25519.S +++ b/wolfcrypt/src/port/arm/armv8-curve25519.S @@ -1,6 +1,6 @@ /* armv8-curve25519 * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -860,6 +860,9 @@ _fe_invert: str x0, [x29, #144] str x1, [x29, #152] add x0, x29, #16 +#ifndef NDEBUG + ldr x1, [x29, #152] +#endif /* !NDEBUG */ #ifndef __APPLE__ bl fe_sq #else @@ -872,12 +875,18 @@ _fe_invert: #else bl _fe_sq #endif /* __APPLE__ */ +#ifndef NDEBUG + add x0, x29, #48 +#endif /* !NDEBUG */ add x1, x29, #48 #ifndef __APPLE__ bl fe_sq #else bl _fe_sq #endif /* __APPLE__ */ +#ifndef NDEBUG + add x0, x29, #48 +#endif /* !NDEBUG */ ldr x1, [x29, #152] add x2, x29, #48 #ifndef __APPLE__ @@ -894,6 +903,9 @@ _fe_invert: bl _fe_mul #endif /* __APPLE__ */ add x0, x29, #0x50 +#ifndef NDEBUG + add x1, x29, #16 +#endif /* !NDEBUG */ #ifndef __APPLE__ bl fe_sq #else @@ -908,12 +920,18 @@ _fe_invert: bl _fe_mul #endif /* __APPLE__ */ add x0, x29, #0x50 +#ifndef NDEBUG + add x1, x29, #48 +#endif /* !NDEBUG */ #ifndef __APPLE__ bl fe_sq #else bl _fe_sq #endif /* __APPLE__ */ - mov x20, #4 + mov x20, #3 +#ifndef NDEBUG + add x0, x29, #0x50 +#endif /* !NDEBUG */ add x1, x29, #0x50 L_fe_invert1: #ifndef __APPLE__ @@ -921,10 +939,12 @@ L_fe_invert1: #else bl _fe_sq #endif /* __APPLE__ */ - sub x20, x20, #1 - cmp x20, #0 - bne L_fe_invert1 + subs x20, x20, #1 + bcs L_fe_invert1 add x0, x29, #48 +#ifndef NDEBUG + add x1, x29, #0x50 +#endif /* !NDEBUG */ add x2, x29, #48 #ifndef __APPLE__ bl fe_mul @@ -938,7 +958,10 @@ L_fe_invert1: #else bl _fe_sq #endif /* __APPLE__ */ - mov x20, #9 + mov x20, #8 +#ifndef NDEBUG + add x0, x29, #0x50 +#endif /* !NDEBUG */ add x1, x29, #0x50 L_fe_invert2: #ifndef __APPLE__ @@ -946,9 +969,14 @@ L_fe_invert2: #else bl _fe_sq #endif /* __APPLE__ */ - sub x20, x20, #1 - cmp x20, #0 - bne L_fe_invert2 + subs x20, x20, #1 + bcs L_fe_invert2 +#ifndef NDEBUG + add x0, x29, #0x50 +#endif /* !NDEBUG */ +#ifndef NDEBUG + add x1, x29, #0x50 +#endif /* !NDEBUG */ add x2, x29, #48 #ifndef __APPLE__ bl fe_mul @@ -956,12 +984,18 @@ L_fe_invert2: bl _fe_mul #endif /* __APPLE__ */ add x0, x29, #0x70 +#ifndef NDEBUG + add x1, x29, #0x50 +#endif /* !NDEBUG */ #ifndef __APPLE__ bl fe_sq #else bl _fe_sq #endif /* __APPLE__ */ - mov x20, #19 + mov x20, #18 +#ifndef NDEBUG + add x0, x29, #0x70 +#endif /* !NDEBUG */ add x1, x29, #0x70 L_fe_invert3: #ifndef __APPLE__ @@ -969,17 +1003,22 @@ L_fe_invert3: #else bl _fe_sq #endif /* __APPLE__ */ - sub x20, x20, #1 - cmp x20, #0 - bne L_fe_invert3 + subs x20, x20, #1 + bcs L_fe_invert3 add x0, x29, #0x50 +#ifndef NDEBUG + add x1, x29, #0x70 +#endif /* !NDEBUG */ add x2, x29, #0x50 #ifndef __APPLE__ bl fe_mul #else bl _fe_mul #endif /* __APPLE__ */ - mov x20, #10 + mov x20, #9 +#ifndef NDEBUG + add x0, x29, #0x50 +#endif /* !NDEBUG */ add x1, x29, #0x50 L_fe_invert4: #ifndef __APPLE__ @@ -987,10 +1026,12 @@ L_fe_invert4: #else bl _fe_sq #endif /* __APPLE__ */ - sub x20, x20, #1 - cmp x20, #0 - bne L_fe_invert4 + subs x20, x20, #1 + bcs L_fe_invert4 add x0, x29, #48 +#ifndef NDEBUG + add x1, x29, #0x50 +#endif /* !NDEBUG */ add x2, x29, #48 #ifndef __APPLE__ bl fe_mul @@ -1004,7 +1045,10 @@ L_fe_invert4: #else bl _fe_sq #endif /* __APPLE__ */ - mov x20, #49 + mov x20, #48 +#ifndef NDEBUG + add x0, x29, #0x50 +#endif /* !NDEBUG */ add x1, x29, #0x50 L_fe_invert5: #ifndef __APPLE__ @@ -1012,9 +1056,14 @@ L_fe_invert5: #else bl _fe_sq #endif /* __APPLE__ */ - sub x20, x20, #1 - cmp x20, #0 - bne L_fe_invert5 + subs x20, x20, #1 + bcs L_fe_invert5 +#ifndef NDEBUG + add x0, x29, #0x50 +#endif /* !NDEBUG */ +#ifndef NDEBUG + add x1, x29, #0x50 +#endif /* !NDEBUG */ add x2, x29, #48 #ifndef __APPLE__ bl fe_mul @@ -1022,12 +1071,18 @@ L_fe_invert5: bl _fe_mul #endif /* __APPLE__ */ add x0, x29, #0x70 +#ifndef NDEBUG + add x1, x29, #0x50 +#endif /* !NDEBUG */ #ifndef __APPLE__ bl fe_sq #else bl _fe_sq #endif /* __APPLE__ */ - mov x20, #0x63 + mov x20, #0x62 +#ifndef NDEBUG + add x0, x29, #0x70 +#endif /* !NDEBUG */ add x1, x29, #0x70 L_fe_invert6: #ifndef __APPLE__ @@ -1035,17 +1090,22 @@ L_fe_invert6: #else bl _fe_sq #endif /* __APPLE__ */ - sub x20, x20, #1 - cmp x20, #0 - bne L_fe_invert6 + subs x20, x20, #1 + bcs L_fe_invert6 add x0, x29, #0x50 +#ifndef NDEBUG + add x1, x29, #0x70 +#endif /* !NDEBUG */ add x2, x29, #0x50 #ifndef __APPLE__ bl fe_mul #else bl _fe_mul #endif /* __APPLE__ */ - mov x20, #50 + mov x20, #49 +#ifndef NDEBUG + add x0, x29, #0x50 +#endif /* !NDEBUG */ add x1, x29, #0x50 L_fe_invert7: #ifndef __APPLE__ @@ -1053,17 +1113,22 @@ L_fe_invert7: #else bl _fe_sq #endif /* __APPLE__ */ - sub x20, x20, #1 - cmp x20, #0 - bne L_fe_invert7 + subs x20, x20, #1 + bcs L_fe_invert7 add x0, x29, #48 +#ifndef NDEBUG + add x1, x29, #0x50 +#endif /* !NDEBUG */ add x2, x29, #48 #ifndef __APPLE__ bl fe_mul #else bl _fe_mul #endif /* __APPLE__ */ - mov x20, #5 + mov x20, #4 +#ifndef NDEBUG + add x0, x29, #48 +#endif /* !NDEBUG */ add x1, x29, #48 L_fe_invert8: #ifndef __APPLE__ @@ -1071,10 +1136,12 @@ L_fe_invert8: #else bl _fe_sq #endif /* __APPLE__ */ - sub x20, x20, #1 - cmp x20, #0 - bne L_fe_invert8 + subs x20, x20, #1 + bcs L_fe_invert8 ldr x0, [x29, #144] +#ifndef NDEBUG + add x1, x29, #48 +#endif /* !NDEBUG */ add x2, x29, #16 #ifndef __APPLE__ bl fe_mul @@ -2428,12 +2495,18 @@ L_curve25519_bits: #else bl _fe_sq #endif /* __APPLE__ */ +#ifndef NDEBUG + add x0, x29, #0x50 +#endif /* !NDEBUG */ add x1, x29, #0x50 #ifndef __APPLE__ bl fe_sq #else bl _fe_sq #endif /* __APPLE__ */ +#ifndef NDEBUG + add x0, x29, #0x50 +#endif /* !NDEBUG */ add x1, x29, #16 add x2, x29, #0x50 #ifndef __APPLE__ @@ -2450,6 +2523,9 @@ L_curve25519_bits: bl _fe_mul #endif /* __APPLE__ */ add x0, x29, #0x70 +#ifndef NDEBUG + add x1, x29, #48 +#endif /* !NDEBUG */ #ifndef __APPLE__ bl fe_sq #else @@ -2464,12 +2540,18 @@ L_curve25519_bits: bl _fe_mul #endif /* __APPLE__ */ add x0, x29, #0x70 +#ifndef NDEBUG + add x1, x29, #0x50 +#endif /* !NDEBUG */ #ifndef __APPLE__ bl fe_sq #else bl _fe_sq #endif /* __APPLE__ */ - mov x24, #4 + mov x24, #3 +#ifndef NDEBUG + add x0, x29, #0x70 +#endif /* !NDEBUG */ add x1, x29, #0x70 L_curve25519_inv_1: #ifndef __APPLE__ @@ -2477,10 +2559,12 @@ L_curve25519_inv_1: #else bl _fe_sq #endif /* __APPLE__ */ - sub x24, x24, #1 - cmp x24, #0 - bne L_curve25519_inv_1 + subs x24, x24, #1 + bcs L_curve25519_inv_1 add x0, x29, #0x50 +#ifndef NDEBUG + add x1, x29, #0x70 +#endif /* !NDEBUG */ add x2, x29, #0x50 #ifndef __APPLE__ bl fe_mul @@ -2494,7 +2578,10 @@ L_curve25519_inv_1: #else bl _fe_sq #endif /* __APPLE__ */ - mov x24, #9 + mov x24, #8 +#ifndef NDEBUG + add x0, x29, #0x70 +#endif /* !NDEBUG */ add x1, x29, #0x70 L_curve25519_inv_2: #ifndef __APPLE__ @@ -2502,9 +2589,14 @@ L_curve25519_inv_2: #else bl _fe_sq #endif /* __APPLE__ */ - sub x24, x24, #1 - cmp x24, #0 - bne L_curve25519_inv_2 + subs x24, x24, #1 + bcs L_curve25519_inv_2 +#ifndef NDEBUG + add x0, x29, #0x70 +#endif /* !NDEBUG */ +#ifndef NDEBUG + add x1, x29, #0x70 +#endif /* !NDEBUG */ add x2, x29, #0x50 #ifndef __APPLE__ bl fe_mul @@ -2512,12 +2604,18 @@ L_curve25519_inv_2: bl _fe_mul #endif /* __APPLE__ */ add x0, x29, #0x90 +#ifndef NDEBUG + add x1, x29, #0x70 +#endif /* !NDEBUG */ #ifndef __APPLE__ bl fe_sq #else bl _fe_sq #endif /* __APPLE__ */ - mov x24, #19 + mov x24, #18 +#ifndef NDEBUG + add x0, x29, #0x90 +#endif /* !NDEBUG */ add x1, x29, #0x90 L_curve25519_inv_3: #ifndef __APPLE__ @@ -2525,17 +2623,22 @@ L_curve25519_inv_3: #else bl _fe_sq #endif /* __APPLE__ */ - sub x24, x24, #1 - cmp x24, #0 - bne L_curve25519_inv_3 + subs x24, x24, #1 + bcs L_curve25519_inv_3 add x0, x29, #0x70 +#ifndef NDEBUG + add x1, x29, #0x90 +#endif /* !NDEBUG */ add x2, x29, #0x70 #ifndef __APPLE__ bl fe_mul #else bl _fe_mul #endif /* __APPLE__ */ - mov x24, #10 + mov x24, #9 +#ifndef NDEBUG + add x0, x29, #0x70 +#endif /* !NDEBUG */ add x1, x29, #0x70 L_curve25519_inv_4: #ifndef __APPLE__ @@ -2543,10 +2646,12 @@ L_curve25519_inv_4: #else bl _fe_sq #endif /* __APPLE__ */ - sub x24, x24, #1 - cmp x24, #0 - bne L_curve25519_inv_4 + subs x24, x24, #1 + bcs L_curve25519_inv_4 add x0, x29, #0x50 +#ifndef NDEBUG + add x1, x29, #0x70 +#endif /* !NDEBUG */ add x2, x29, #0x50 #ifndef __APPLE__ bl fe_mul @@ -2560,7 +2665,10 @@ L_curve25519_inv_4: #else bl _fe_sq #endif /* __APPLE__ */ - mov x24, #49 + mov x24, #48 +#ifndef NDEBUG + add x0, x29, #0x70 +#endif /* !NDEBUG */ add x1, x29, #0x70 L_curve25519_inv_5: #ifndef __APPLE__ @@ -2568,9 +2676,14 @@ L_curve25519_inv_5: #else bl _fe_sq #endif /* __APPLE__ */ - sub x24, x24, #1 - cmp x24, #0 - bne L_curve25519_inv_5 + subs x24, x24, #1 + bcs L_curve25519_inv_5 +#ifndef NDEBUG + add x0, x29, #0x70 +#endif /* !NDEBUG */ +#ifndef NDEBUG + add x1, x29, #0x70 +#endif /* !NDEBUG */ add x2, x29, #0x50 #ifndef __APPLE__ bl fe_mul @@ -2578,12 +2691,18 @@ L_curve25519_inv_5: bl _fe_mul #endif /* __APPLE__ */ add x0, x29, #0x90 +#ifndef NDEBUG + add x1, x29, #0x70 +#endif /* !NDEBUG */ #ifndef __APPLE__ bl fe_sq #else bl _fe_sq #endif /* __APPLE__ */ - mov x24, #0x63 + mov x24, #0x62 +#ifndef NDEBUG + add x0, x29, #0x90 +#endif /* !NDEBUG */ add x1, x29, #0x90 L_curve25519_inv_6: #ifndef __APPLE__ @@ -2591,17 +2710,22 @@ L_curve25519_inv_6: #else bl _fe_sq #endif /* __APPLE__ */ - sub x24, x24, #1 - cmp x24, #0 - bne L_curve25519_inv_6 + subs x24, x24, #1 + bcs L_curve25519_inv_6 add x0, x29, #0x70 +#ifndef NDEBUG + add x1, x29, #0x90 +#endif /* !NDEBUG */ add x2, x29, #0x70 #ifndef __APPLE__ bl fe_mul #else bl _fe_mul #endif /* __APPLE__ */ - mov x24, #50 + mov x24, #49 +#ifndef NDEBUG + add x0, x29, #0x70 +#endif /* !NDEBUG */ add x1, x29, #0x70 L_curve25519_inv_7: #ifndef __APPLE__ @@ -2609,17 +2733,22 @@ L_curve25519_inv_7: #else bl _fe_sq #endif /* __APPLE__ */ - sub x24, x24, #1 - cmp x24, #0 - bne L_curve25519_inv_7 + subs x24, x24, #1 + bcs L_curve25519_inv_7 add x0, x29, #0x50 +#ifndef NDEBUG + add x1, x29, #0x70 +#endif /* !NDEBUG */ add x2, x29, #0x50 #ifndef __APPLE__ bl fe_mul #else bl _fe_mul #endif /* __APPLE__ */ - mov x24, #5 + mov x24, #4 +#ifndef NDEBUG + add x0, x29, #0x50 +#endif /* !NDEBUG */ add x1, x29, #0x50 L_curve25519_inv_8: #ifndef __APPLE__ @@ -2627,10 +2756,12 @@ L_curve25519_inv_8: #else bl _fe_sq #endif /* __APPLE__ */ - sub x24, x24, #1 - cmp x24, #0 - bne L_curve25519_inv_8 + subs x24, x24, #1 + bcs L_curve25519_inv_8 add x0, x29, #16 +#ifndef NDEBUG + add x1, x29, #0x50 +#endif /* !NDEBUG */ add x2, x29, #48 #ifndef __APPLE__ bl fe_mul @@ -2805,11 +2936,14 @@ _fe_pow22523: #endif /* __APPLE__ */ stp x29, x30, [sp, #-144]! add x29, sp, #0 - str x21, [x29, #136] + str x23, [x29, #136] # pow22523 str x0, [x29, #112] str x1, [x29, #120] add x0, x29, #16 +#ifndef NDEBUG + ldr x1, [x29, #120] +#endif /* !NDEBUG */ #ifndef __APPLE__ bl fe_sq #else @@ -2822,12 +2956,18 @@ _fe_pow22523: #else bl _fe_sq #endif /* __APPLE__ */ +#ifndef NDEBUG + add x0, x29, #48 +#endif /* !NDEBUG */ add x1, x29, #48 #ifndef __APPLE__ bl fe_sq #else bl _fe_sq #endif /* __APPLE__ */ +#ifndef NDEBUG + add x0, x29, #48 +#endif /* !NDEBUG */ ldr x1, [x29, #120] add x2, x29, #48 #ifndef __APPLE__ @@ -2843,11 +2983,20 @@ _fe_pow22523: #else bl _fe_mul #endif /* __APPLE__ */ +#ifndef NDEBUG + add x0, x29, #16 +#endif /* !NDEBUG */ +#ifndef NDEBUG + add x1, x29, #16 +#endif /* !NDEBUG */ #ifndef __APPLE__ bl fe_sq #else bl _fe_sq #endif /* __APPLE__ */ +#ifndef NDEBUG + add x0, x29, #16 +#endif /* !NDEBUG */ add x1, x29, #48 add x2, x29, #16 #ifndef __APPLE__ @@ -2862,7 +3011,10 @@ _fe_pow22523: #else bl _fe_sq #endif /* __APPLE__ */ - mov x21, #4 + mov x23, #3 +#ifndef NDEBUG + add x0, x29, #48 +#endif /* !NDEBUG */ add x1, x29, #48 L_fe_pow22523_1: #ifndef __APPLE__ @@ -2870,10 +3022,12 @@ L_fe_pow22523_1: #else bl _fe_sq #endif /* __APPLE__ */ - sub x21, x21, #1 - cmp x21, #0 - bne L_fe_pow22523_1 + subs x23, x23, #1 + bcs L_fe_pow22523_1 add x0, x29, #16 +#ifndef NDEBUG + add x1, x29, #48 +#endif /* !NDEBUG */ add x2, x29, #16 #ifndef __APPLE__ bl fe_mul @@ -2887,7 +3041,10 @@ L_fe_pow22523_1: #else bl _fe_sq #endif /* __APPLE__ */ - mov x21, #9 + mov x23, #8 +#ifndef NDEBUG + add x0, x29, #48 +#endif /* !NDEBUG */ add x1, x29, #48 L_fe_pow22523_2: #ifndef __APPLE__ @@ -2895,9 +3052,14 @@ L_fe_pow22523_2: #else bl _fe_sq #endif /* __APPLE__ */ - sub x21, x21, #1 - cmp x21, #0 - bne L_fe_pow22523_2 + subs x23, x23, #1 + bcs L_fe_pow22523_2 +#ifndef NDEBUG + add x0, x29, #48 +#endif /* !NDEBUG */ +#ifndef NDEBUG + add x1, x29, #48 +#endif /* !NDEBUG */ add x2, x29, #16 #ifndef __APPLE__ bl fe_mul @@ -2905,12 +3067,18 @@ L_fe_pow22523_2: bl _fe_mul #endif /* __APPLE__ */ add x0, x29, #0x50 +#ifndef NDEBUG + add x1, x29, #48 +#endif /* !NDEBUG */ #ifndef __APPLE__ bl fe_sq #else bl _fe_sq #endif /* __APPLE__ */ - mov x21, #19 + mov x23, #18 +#ifndef NDEBUG + add x0, x29, #0x50 +#endif /* !NDEBUG */ add x1, x29, #0x50 L_fe_pow22523_3: #ifndef __APPLE__ @@ -2918,17 +3086,22 @@ L_fe_pow22523_3: #else bl _fe_sq #endif /* __APPLE__ */ - sub x21, x21, #1 - cmp x21, #0 - bne L_fe_pow22523_3 + subs x23, x23, #1 + bcs L_fe_pow22523_3 add x0, x29, #48 +#ifndef NDEBUG + add x1, x29, #0x50 +#endif /* !NDEBUG */ add x2, x29, #48 #ifndef __APPLE__ bl fe_mul #else bl _fe_mul #endif /* __APPLE__ */ - mov x21, #10 + mov x23, #9 +#ifndef NDEBUG + add x0, x29, #48 +#endif /* !NDEBUG */ add x1, x29, #48 L_fe_pow22523_4: #ifndef __APPLE__ @@ -2936,10 +3109,12 @@ L_fe_pow22523_4: #else bl _fe_sq #endif /* __APPLE__ */ - sub x21, x21, #1 - cmp x21, #0 - bne L_fe_pow22523_4 + subs x23, x23, #1 + bcs L_fe_pow22523_4 add x0, x29, #16 +#ifndef NDEBUG + add x1, x29, #48 +#endif /* !NDEBUG */ add x2, x29, #16 #ifndef __APPLE__ bl fe_mul @@ -2953,7 +3128,10 @@ L_fe_pow22523_4: #else bl _fe_sq #endif /* __APPLE__ */ - mov x21, #49 + mov x23, #48 +#ifndef NDEBUG + add x0, x29, #48 +#endif /* !NDEBUG */ add x1, x29, #48 L_fe_pow22523_5: #ifndef __APPLE__ @@ -2961,9 +3139,14 @@ L_fe_pow22523_5: #else bl _fe_sq #endif /* __APPLE__ */ - sub x21, x21, #1 - cmp x21, #0 - bne L_fe_pow22523_5 + subs x23, x23, #1 + bcs L_fe_pow22523_5 +#ifndef NDEBUG + add x0, x29, #48 +#endif /* !NDEBUG */ +#ifndef NDEBUG + add x1, x29, #48 +#endif /* !NDEBUG */ add x2, x29, #16 #ifndef __APPLE__ bl fe_mul @@ -2971,12 +3154,18 @@ L_fe_pow22523_5: bl _fe_mul #endif /* __APPLE__ */ add x0, x29, #0x50 +#ifndef NDEBUG + add x1, x29, #48 +#endif /* !NDEBUG */ #ifndef __APPLE__ bl fe_sq #else bl _fe_sq #endif /* __APPLE__ */ - mov x21, #0x63 + mov x23, #0x62 +#ifndef NDEBUG + add x0, x29, #0x50 +#endif /* !NDEBUG */ add x1, x29, #0x50 L_fe_pow22523_6: #ifndef __APPLE__ @@ -2984,17 +3173,22 @@ L_fe_pow22523_6: #else bl _fe_sq #endif /* __APPLE__ */ - sub x21, x21, #1 - cmp x21, #0 - bne L_fe_pow22523_6 + subs x23, x23, #1 + bcs L_fe_pow22523_6 add x0, x29, #48 +#ifndef NDEBUG + add x1, x29, #0x50 +#endif /* !NDEBUG */ add x2, x29, #48 #ifndef __APPLE__ bl fe_mul #else bl _fe_mul #endif /* __APPLE__ */ - mov x21, #50 + mov x23, #49 +#ifndef NDEBUG + add x0, x29, #48 +#endif /* !NDEBUG */ add x1, x29, #48 L_fe_pow22523_7: #ifndef __APPLE__ @@ -3002,17 +3196,22 @@ L_fe_pow22523_7: #else bl _fe_sq #endif /* __APPLE__ */ - sub x21, x21, #1 - cmp x21, #0 - bne L_fe_pow22523_7 + subs x23, x23, #1 + bcs L_fe_pow22523_7 add x0, x29, #16 +#ifndef NDEBUG + add x1, x29, #48 +#endif /* !NDEBUG */ add x2, x29, #16 #ifndef __APPLE__ bl fe_mul #else bl _fe_mul #endif /* __APPLE__ */ - mov x21, #2 + mov x23, #1 +#ifndef NDEBUG + add x0, x29, #16 +#endif /* !NDEBUG */ add x1, x29, #16 L_fe_pow22523_8: #ifndef __APPLE__ @@ -3020,17 +3219,19 @@ L_fe_pow22523_8: #else bl _fe_sq #endif /* __APPLE__ */ - sub x21, x21, #1 - cmp x21, #0 - bne L_fe_pow22523_8 + subs x23, x23, #1 + bcs L_fe_pow22523_8 ldr x0, [x29, #112] +#ifndef NDEBUG + add x1, x29, #16 +#endif /* !NDEBUG */ ldr x2, [x29, #120] #ifndef __APPLE__ bl fe_mul #else bl _fe_mul #endif /* __APPLE__ */ - ldr x21, [x29, #136] + ldr x23, [x29, #136] ldp x29, x30, [sp], #0x90 ret #ifndef __APPLE__ diff --git a/wolfcrypt/src/port/arm/armv8-curve25519.c b/wolfcrypt/src/port/arm/armv8-curve25519.c index a72ae8fbd..213512297 100644 --- a/wolfcrypt/src/port/arm/armv8-curve25519.c +++ b/wolfcrypt/src/port/arm/armv8-curve25519.c @@ -1,6 +1,6 @@ /* armv8-curve25519 * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -35,10 +35,7 @@ void fe_init() { __asm__ __volatile__ ( - "stp x29, x30, [sp, #-16]!\n\t" - "add x29, sp, #0\n\t" "\n\t" - "ldp x29, x30, [sp], #16\n\t" : : : "memory" @@ -48,14 +45,11 @@ void fe_init() void fe_frombytes(fe out, const unsigned char* in) { __asm__ __volatile__ ( - "stp x29, x30, [sp, #-16]!\n\t" - "add x29, sp, #0\n\t" "ldp x2, x3, [%x[in]]\n\t" "ldp x4, x5, [%x[in], #16]\n\t" "and x5, x5, #0x7fffffffffffffff\n\t" "stp x2, x3, [%x[out]]\n\t" "stp x4, x5, [%x[out], #16]\n\t" - "ldp x29, x30, [sp], #16\n\t" : [out] "+r" (out), [in] "+r" (in) : : "memory", "x2", "x3", "x4", "x5", "x6" @@ -65,8 +59,6 @@ void fe_frombytes(fe out, const unsigned char* in) void fe_tobytes(unsigned char* out, const fe n) { __asm__ __volatile__ ( - "stp x29, x30, [sp, #-16]!\n\t" - "add x29, sp, #0\n\t" "mov x7, #19\n\t" "ldp x2, x3, [%x[n]]\n\t" "ldp x4, x5, [%x[n], #16]\n\t" @@ -82,7 +74,6 @@ void fe_tobytes(unsigned char* out, const fe n) "and x5, x5, #0x7fffffffffffffff\n\t" "stp x2, x3, [%x[out]]\n\t" "stp x4, x5, [%x[out], #16]\n\t" - "ldp x29, x30, [sp], #16\n\t" : [out] "+r" (out), [n] "+r" (n) : : "memory", "x2", "x3", "x4", "x5", "x6", "x7" @@ -92,13 +83,10 @@ void fe_tobytes(unsigned char* out, const fe n) void fe_1(fe n) { __asm__ __volatile__ ( - "stp x29, x30, [sp, #-16]!\n\t" - "add x29, sp, #0\n\t" /* Set one */ "mov x1, #1\n\t" "stp x1, xzr, [%x[n]]\n\t" "stp xzr, xzr, [%x[n], #16]\n\t" - "ldp x29, x30, [sp], #16\n\t" : [n] "+r" (n) : : "memory", "x1" @@ -108,12 +96,9 @@ void fe_1(fe n) void fe_0(fe n) { __asm__ __volatile__ ( - "stp x29, x30, [sp, #-16]!\n\t" - "add x29, sp, #0\n\t" /* Set zero */ "stp xzr, xzr, [%x[n]]\n\t" "stp xzr, xzr, [%x[n], #16]\n\t" - "ldp x29, x30, [sp], #16\n\t" : [n] "+r" (n) : : "memory" @@ -123,14 +108,11 @@ void fe_0(fe n) void fe_copy(fe r, const fe a) { __asm__ __volatile__ ( - "stp x29, x30, [sp, #-16]!\n\t" - "add x29, sp, #0\n\t" /* Copy */ "ldp x2, x3, [%x[a]]\n\t" "ldp x4, x5, [%x[a], #16]\n\t" "stp x2, x3, [%x[r]]\n\t" "stp x4, x5, [%x[r], #16]\n\t" - "ldp x29, x30, [sp], #16\n\t" : [r] "+r" (r), [a] "+r" (a) : : "memory", "x2", "x3", "x4", "x5" @@ -140,8 +122,6 @@ void fe_copy(fe r, const fe a) void fe_sub(fe r, const fe a, const fe b) { __asm__ __volatile__ ( - "stp x29, x30, [sp, #-16]!\n\t" - "add x29, sp, #0\n\t" /* Sub */ "ldp x3, x4, [%x[a]]\n\t" "ldp x5, x6, [%x[a], #16]\n\t" @@ -163,7 +143,6 @@ void fe_sub(fe r, const fe a, const fe b) "adc x6, x6, x13\n\t" "stp x3, x4, [%x[r]]\n\t" "stp x5, x6, [%x[r], #16]\n\t" - "ldp x29, x30, [sp], #16\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13" @@ -173,8 +152,6 @@ void fe_sub(fe r, const fe a, const fe b) void fe_add(fe r, const fe a, const fe b) { __asm__ __volatile__ ( - "stp x29, x30, [sp, #-16]!\n\t" - "add x29, sp, #0\n\t" /* Add */ "ldp x3, x4, [%x[a]]\n\t" "ldp x5, x6, [%x[a], #16]\n\t" @@ -196,7 +173,6 @@ void fe_add(fe r, const fe a, const fe b) "sbc x6, x6, x13\n\t" "stp x3, x4, [%x[r]]\n\t" "stp x5, x6, [%x[r], #16]\n\t" - "ldp x29, x30, [sp], #16\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13" @@ -206,8 +182,6 @@ void fe_add(fe r, const fe a, const fe b) void fe_neg(fe r, const fe a) { __asm__ __volatile__ ( - "stp x29, x30, [sp, #-16]!\n\t" - "add x29, sp, #0\n\t" "ldp x2, x3, [%x[a]]\n\t" "ldp x4, x5, [%x[a], #16]\n\t" "mov x6, #-19\n\t" @@ -220,7 +194,6 @@ void fe_neg(fe r, const fe a) "sbc x9, x9, x5\n\t" "stp x6, x7, [%x[r]]\n\t" "stp x8, x9, [%x[r], #16]\n\t" - "ldp x29, x30, [sp], #16\n\t" : [r] "+r" (r), [a] "+r" (a) : : "memory", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9" @@ -230,8 +203,6 @@ void fe_neg(fe r, const fe a) int fe_isnonzero(const fe a) { __asm__ __volatile__ ( - "stp x29, x30, [sp, #-16]!\n\t" - "add x29, sp, #0\n\t" "mov x6, #19\n\t" "ldp x1, x2, [%x[a]]\n\t" "ldp x3, x4, [%x[a], #16]\n\t" @@ -248,7 +219,6 @@ int fe_isnonzero(const fe a) "orr %x[a], x1, x2\n\t" "orr x3, x3, x4\n\t" "orr %x[a], %x[a], x3\n\t" - "ldp x29, x30, [sp], #16\n\t" : [a] "+r" (a) : : "memory", "x1", "x2", "x3", "x4", "x5", "x6" @@ -259,8 +229,6 @@ int fe_isnonzero(const fe a) int fe_isnegative(const fe a) { __asm__ __volatile__ ( - "stp x29, x30, [sp, #-16]!\n\t" - "add x29, sp, #0\n\t" "mov x6, #19\n\t" "ldp x1, x2, [%x[a]]\n\t" "ldp x3, x4, [%x[a], #16]\n\t" @@ -270,7 +238,6 @@ int fe_isnegative(const fe a) "adc x5, x4, xzr\n\t" "and %x[a], x1, #1\n\t" "eor %x[a], %x[a], x5, lsr 63\n\t" - "ldp x29, x30, [sp], #16\n\t" : [a] "+r" (a) : : "memory", "x1", "x2", "x3", "x4", "x5", "x6" @@ -495,8 +462,6 @@ void fe_cmov_table(fe* r, fe* base, signed char b) void fe_mul(fe r, const fe a, const fe b) { __asm__ __volatile__ ( - "stp x29, x30, [sp, #-16]!\n\t" - "add x29, sp, #0\n\t" /* Multiply */ "ldp x14, x15, [%x[a]]\n\t" "ldp x16, x17, [%x[a], #16]\n\t" @@ -637,7 +602,6 @@ void fe_mul(fe r, const fe a, const fe b) /* Store */ "stp x6, x7, [%x[r]]\n\t" "stp x8, x9, [%x[r], #16]\n\t" - "ldp x29, x30, [sp], #16\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22" @@ -647,8 +611,6 @@ void fe_mul(fe r, const fe a, const fe b) void fe_sq(fe r, const fe a) { __asm__ __volatile__ ( - "stp x29, x30, [sp, #-16]!\n\t" - "add x29, sp, #0\n\t" /* Square */ "ldp x13, x14, [%x[a]]\n\t" "ldp x15, x16, [%x[a], #16]\n\t" @@ -755,7 +717,6 @@ void fe_sq(fe r, const fe a) /* Store */ "stp x5, x6, [%x[r]]\n\t" "stp x7, x8, [%x[r], #16]\n\t" - "ldp x29, x30, [sp], #16\n\t" : [r] "+r" (r), [a] "+r" (a) : : "memory", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16" @@ -771,6 +732,9 @@ void fe_invert(fe r, const fe a) "str %x[r], [x29, #144]\n\t" "str %x[a], [x29, #152]\n\t" "add x0, x29, #16\n\t" +#ifndef NDEBUG + "ldr x1, [x29, #152]\n\t" +#endif /* !NDEBUG */ #ifndef __APPLE__ "bl fe_sq\n\t" #else @@ -783,12 +747,18 @@ void fe_invert(fe r, const fe a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ +#ifndef NDEBUG + "add x0, x29, #48\n\t" +#endif /* !NDEBUG */ "add x1, x29, #48\n\t" #ifndef __APPLE__ "bl fe_sq\n\t" #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ +#ifndef NDEBUG + "add x0, x29, #48\n\t" +#endif /* !NDEBUG */ "ldr x1, [x29, #152]\n\t" "add x2, x29, #48\n\t" #ifndef __APPLE__ @@ -805,6 +775,9 @@ void fe_invert(fe r, const fe a) "bl _fe_mul\n\t" #endif /* __APPLE__ */ "add x0, x29, #0x50\n\t" +#ifndef NDEBUG + "add x1, x29, #16\n\t" +#endif /* !NDEBUG */ #ifndef __APPLE__ "bl fe_sq\n\t" #else @@ -819,12 +792,18 @@ void fe_invert(fe r, const fe a) "bl _fe_mul\n\t" #endif /* __APPLE__ */ "add x0, x29, #0x50\n\t" +#ifndef NDEBUG + "add x1, x29, #48\n\t" +#endif /* !NDEBUG */ #ifndef __APPLE__ "bl fe_sq\n\t" #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "mov x20, #4\n\t" + "mov x20, #3\n\t" +#ifndef NDEBUG + "add x0, x29, #0x50\n\t" +#endif /* !NDEBUG */ "add x1, x29, #0x50\n\t" "\n" "L_fe_invert1_%=: \n\t" @@ -833,10 +812,12 @@ void fe_invert(fe r, const fe a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x20, x20, #1\n\t" - "cmp x20, #0\n\t" - "bne L_fe_invert1_%=\n\t" + "subs x20, x20, #1\n\t" + "bcs L_fe_invert1_%=\n\t" "add x0, x29, #48\n\t" +#ifndef NDEBUG + "add x1, x29, #0x50\n\t" +#endif /* !NDEBUG */ "add x2, x29, #48\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" @@ -850,7 +831,10 @@ void fe_invert(fe r, const fe a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "mov x20, #9\n\t" + "mov x20, #8\n\t" +#ifndef NDEBUG + "add x0, x29, #0x50\n\t" +#endif /* !NDEBUG */ "add x1, x29, #0x50\n\t" "\n" "L_fe_invert2_%=: \n\t" @@ -859,9 +843,14 @@ void fe_invert(fe r, const fe a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x20, x20, #1\n\t" - "cmp x20, #0\n\t" - "bne L_fe_invert2_%=\n\t" + "subs x20, x20, #1\n\t" + "bcs L_fe_invert2_%=\n\t" +#ifndef NDEBUG + "add x0, x29, #0x50\n\t" +#endif /* !NDEBUG */ +#ifndef NDEBUG + "add x1, x29, #0x50\n\t" +#endif /* !NDEBUG */ "add x2, x29, #48\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" @@ -869,12 +858,18 @@ void fe_invert(fe r, const fe a) "bl _fe_mul\n\t" #endif /* __APPLE__ */ "add x0, x29, #0x70\n\t" +#ifndef NDEBUG + "add x1, x29, #0x50\n\t" +#endif /* !NDEBUG */ #ifndef __APPLE__ "bl fe_sq\n\t" #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "mov x20, #19\n\t" + "mov x20, #18\n\t" +#ifndef NDEBUG + "add x0, x29, #0x70\n\t" +#endif /* !NDEBUG */ "add x1, x29, #0x70\n\t" "\n" "L_fe_invert3_%=: \n\t" @@ -883,17 +878,22 @@ void fe_invert(fe r, const fe a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x20, x20, #1\n\t" - "cmp x20, #0\n\t" - "bne L_fe_invert3_%=\n\t" + "subs x20, x20, #1\n\t" + "bcs L_fe_invert3_%=\n\t" "add x0, x29, #0x50\n\t" +#ifndef NDEBUG + "add x1, x29, #0x70\n\t" +#endif /* !NDEBUG */ "add x2, x29, #0x50\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" #else "bl _fe_mul\n\t" #endif /* __APPLE__ */ - "mov x20, #10\n\t" + "mov x20, #9\n\t" +#ifndef NDEBUG + "add x0, x29, #0x50\n\t" +#endif /* !NDEBUG */ "add x1, x29, #0x50\n\t" "\n" "L_fe_invert4_%=: \n\t" @@ -902,10 +902,12 @@ void fe_invert(fe r, const fe a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x20, x20, #1\n\t" - "cmp x20, #0\n\t" - "bne L_fe_invert4_%=\n\t" + "subs x20, x20, #1\n\t" + "bcs L_fe_invert4_%=\n\t" "add x0, x29, #48\n\t" +#ifndef NDEBUG + "add x1, x29, #0x50\n\t" +#endif /* !NDEBUG */ "add x2, x29, #48\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" @@ -919,7 +921,10 @@ void fe_invert(fe r, const fe a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "mov x20, #49\n\t" + "mov x20, #48\n\t" +#ifndef NDEBUG + "add x0, x29, #0x50\n\t" +#endif /* !NDEBUG */ "add x1, x29, #0x50\n\t" "\n" "L_fe_invert5_%=: \n\t" @@ -928,9 +933,14 @@ void fe_invert(fe r, const fe a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x20, x20, #1\n\t" - "cmp x20, #0\n\t" - "bne L_fe_invert5_%=\n\t" + "subs x20, x20, #1\n\t" + "bcs L_fe_invert5_%=\n\t" +#ifndef NDEBUG + "add x0, x29, #0x50\n\t" +#endif /* !NDEBUG */ +#ifndef NDEBUG + "add x1, x29, #0x50\n\t" +#endif /* !NDEBUG */ "add x2, x29, #48\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" @@ -938,12 +948,18 @@ void fe_invert(fe r, const fe a) "bl _fe_mul\n\t" #endif /* __APPLE__ */ "add x0, x29, #0x70\n\t" +#ifndef NDEBUG + "add x1, x29, #0x50\n\t" +#endif /* !NDEBUG */ #ifndef __APPLE__ "bl fe_sq\n\t" #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "mov x20, #0x63\n\t" + "mov x20, #0x62\n\t" +#ifndef NDEBUG + "add x0, x29, #0x70\n\t" +#endif /* !NDEBUG */ "add x1, x29, #0x70\n\t" "\n" "L_fe_invert6_%=: \n\t" @@ -952,17 +968,22 @@ void fe_invert(fe r, const fe a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x20, x20, #1\n\t" - "cmp x20, #0\n\t" - "bne L_fe_invert6_%=\n\t" + "subs x20, x20, #1\n\t" + "bcs L_fe_invert6_%=\n\t" "add x0, x29, #0x50\n\t" +#ifndef NDEBUG + "add x1, x29, #0x70\n\t" +#endif /* !NDEBUG */ "add x2, x29, #0x50\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" #else "bl _fe_mul\n\t" #endif /* __APPLE__ */ - "mov x20, #50\n\t" + "mov x20, #49\n\t" +#ifndef NDEBUG + "add x0, x29, #0x50\n\t" +#endif /* !NDEBUG */ "add x1, x29, #0x50\n\t" "\n" "L_fe_invert7_%=: \n\t" @@ -971,17 +992,22 @@ void fe_invert(fe r, const fe a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x20, x20, #1\n\t" - "cmp x20, #0\n\t" - "bne L_fe_invert7_%=\n\t" + "subs x20, x20, #1\n\t" + "bcs L_fe_invert7_%=\n\t" "add x0, x29, #48\n\t" +#ifndef NDEBUG + "add x1, x29, #0x50\n\t" +#endif /* !NDEBUG */ "add x2, x29, #48\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" #else "bl _fe_mul\n\t" #endif /* __APPLE__ */ - "mov x20, #5\n\t" + "mov x20, #4\n\t" +#ifndef NDEBUG + "add x0, x29, #48\n\t" +#endif /* !NDEBUG */ "add x1, x29, #48\n\t" "\n" "L_fe_invert8_%=: \n\t" @@ -990,10 +1016,12 @@ void fe_invert(fe r, const fe a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x20, x20, #1\n\t" - "cmp x20, #0\n\t" - "bne L_fe_invert8_%=\n\t" + "subs x20, x20, #1\n\t" + "bcs L_fe_invert8_%=\n\t" "ldr x0, [x29, #144]\n\t" +#ifndef NDEBUG + "add x1, x29, #48\n\t" +#endif /* !NDEBUG */ "add x2, x29, #16\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" @@ -1003,7 +1031,7 @@ void fe_invert(fe r, const fe a) "ldp x29, x30, [sp], #0xa0\n\t" : [r] "+r" (r), [a] "+r" (a) : - : "memory", "x20" + : "memory", "x2", "x20" ); } @@ -2334,12 +2362,18 @@ int curve25519(byte* r, const byte* n, const byte* a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ +#ifndef NDEBUG + "add x0, x29, #0x50\n\t" +#endif /* !NDEBUG */ "add x1, x29, #0x50\n\t" #ifndef __APPLE__ "bl fe_sq\n\t" #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ +#ifndef NDEBUG + "add x0, x29, #0x50\n\t" +#endif /* !NDEBUG */ "add x1, x29, #16\n\t" "add x2, x29, #0x50\n\t" #ifndef __APPLE__ @@ -2356,6 +2390,9 @@ int curve25519(byte* r, const byte* n, const byte* a) "bl _fe_mul\n\t" #endif /* __APPLE__ */ "add x0, x29, #0x70\n\t" +#ifndef NDEBUG + "add x1, x29, #48\n\t" +#endif /* !NDEBUG */ #ifndef __APPLE__ "bl fe_sq\n\t" #else @@ -2370,12 +2407,18 @@ int curve25519(byte* r, const byte* n, const byte* a) "bl _fe_mul\n\t" #endif /* __APPLE__ */ "add x0, x29, #0x70\n\t" +#ifndef NDEBUG + "add x1, x29, #0x50\n\t" +#endif /* !NDEBUG */ #ifndef __APPLE__ "bl fe_sq\n\t" #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "mov x24, #4\n\t" + "mov x24, #3\n\t" +#ifndef NDEBUG + "add x0, x29, #0x70\n\t" +#endif /* !NDEBUG */ "add x1, x29, #0x70\n\t" "\n" "L_curve25519_inv_1_%=: \n\t" @@ -2384,10 +2427,12 @@ int curve25519(byte* r, const byte* n, const byte* a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x24, x24, #1\n\t" - "cmp x24, #0\n\t" - "bne L_curve25519_inv_1_%=\n\t" + "subs x24, x24, #1\n\t" + "bcs L_curve25519_inv_1_%=\n\t" "add x0, x29, #0x50\n\t" +#ifndef NDEBUG + "add x1, x29, #0x70\n\t" +#endif /* !NDEBUG */ "add x2, x29, #0x50\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" @@ -2401,7 +2446,10 @@ int curve25519(byte* r, const byte* n, const byte* a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "mov x24, #9\n\t" + "mov x24, #8\n\t" +#ifndef NDEBUG + "add x0, x29, #0x70\n\t" +#endif /* !NDEBUG */ "add x1, x29, #0x70\n\t" "\n" "L_curve25519_inv_2_%=: \n\t" @@ -2410,9 +2458,14 @@ int curve25519(byte* r, const byte* n, const byte* a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x24, x24, #1\n\t" - "cmp x24, #0\n\t" - "bne L_curve25519_inv_2_%=\n\t" + "subs x24, x24, #1\n\t" + "bcs L_curve25519_inv_2_%=\n\t" +#ifndef NDEBUG + "add x0, x29, #0x70\n\t" +#endif /* !NDEBUG */ +#ifndef NDEBUG + "add x1, x29, #0x70\n\t" +#endif /* !NDEBUG */ "add x2, x29, #0x50\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" @@ -2420,12 +2473,18 @@ int curve25519(byte* r, const byte* n, const byte* a) "bl _fe_mul\n\t" #endif /* __APPLE__ */ "add x0, x29, #0x90\n\t" +#ifndef NDEBUG + "add x1, x29, #0x70\n\t" +#endif /* !NDEBUG */ #ifndef __APPLE__ "bl fe_sq\n\t" #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "mov x24, #19\n\t" + "mov x24, #18\n\t" +#ifndef NDEBUG + "add x0, x29, #0x90\n\t" +#endif /* !NDEBUG */ "add x1, x29, #0x90\n\t" "\n" "L_curve25519_inv_3_%=: \n\t" @@ -2434,17 +2493,22 @@ int curve25519(byte* r, const byte* n, const byte* a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x24, x24, #1\n\t" - "cmp x24, #0\n\t" - "bne L_curve25519_inv_3_%=\n\t" + "subs x24, x24, #1\n\t" + "bcs L_curve25519_inv_3_%=\n\t" "add x0, x29, #0x70\n\t" +#ifndef NDEBUG + "add x1, x29, #0x90\n\t" +#endif /* !NDEBUG */ "add x2, x29, #0x70\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" #else "bl _fe_mul\n\t" #endif /* __APPLE__ */ - "mov x24, #10\n\t" + "mov x24, #9\n\t" +#ifndef NDEBUG + "add x0, x29, #0x70\n\t" +#endif /* !NDEBUG */ "add x1, x29, #0x70\n\t" "\n" "L_curve25519_inv_4_%=: \n\t" @@ -2453,10 +2517,12 @@ int curve25519(byte* r, const byte* n, const byte* a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x24, x24, #1\n\t" - "cmp x24, #0\n\t" - "bne L_curve25519_inv_4_%=\n\t" + "subs x24, x24, #1\n\t" + "bcs L_curve25519_inv_4_%=\n\t" "add x0, x29, #0x50\n\t" +#ifndef NDEBUG + "add x1, x29, #0x70\n\t" +#endif /* !NDEBUG */ "add x2, x29, #0x50\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" @@ -2470,7 +2536,10 @@ int curve25519(byte* r, const byte* n, const byte* a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "mov x24, #49\n\t" + "mov x24, #48\n\t" +#ifndef NDEBUG + "add x0, x29, #0x70\n\t" +#endif /* !NDEBUG */ "add x1, x29, #0x70\n\t" "\n" "L_curve25519_inv_5_%=: \n\t" @@ -2479,9 +2548,14 @@ int curve25519(byte* r, const byte* n, const byte* a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x24, x24, #1\n\t" - "cmp x24, #0\n\t" - "bne L_curve25519_inv_5_%=\n\t" + "subs x24, x24, #1\n\t" + "bcs L_curve25519_inv_5_%=\n\t" +#ifndef NDEBUG + "add x0, x29, #0x70\n\t" +#endif /* !NDEBUG */ +#ifndef NDEBUG + "add x1, x29, #0x70\n\t" +#endif /* !NDEBUG */ "add x2, x29, #0x50\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" @@ -2489,12 +2563,18 @@ int curve25519(byte* r, const byte* n, const byte* a) "bl _fe_mul\n\t" #endif /* __APPLE__ */ "add x0, x29, #0x90\n\t" +#ifndef NDEBUG + "add x1, x29, #0x70\n\t" +#endif /* !NDEBUG */ #ifndef __APPLE__ "bl fe_sq\n\t" #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "mov x24, #0x63\n\t" + "mov x24, #0x62\n\t" +#ifndef NDEBUG + "add x0, x29, #0x90\n\t" +#endif /* !NDEBUG */ "add x1, x29, #0x90\n\t" "\n" "L_curve25519_inv_6_%=: \n\t" @@ -2503,17 +2583,22 @@ int curve25519(byte* r, const byte* n, const byte* a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x24, x24, #1\n\t" - "cmp x24, #0\n\t" - "bne L_curve25519_inv_6_%=\n\t" + "subs x24, x24, #1\n\t" + "bcs L_curve25519_inv_6_%=\n\t" "add x0, x29, #0x70\n\t" +#ifndef NDEBUG + "add x1, x29, #0x90\n\t" +#endif /* !NDEBUG */ "add x2, x29, #0x70\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" #else "bl _fe_mul\n\t" #endif /* __APPLE__ */ - "mov x24, #50\n\t" + "mov x24, #49\n\t" +#ifndef NDEBUG + "add x0, x29, #0x70\n\t" +#endif /* !NDEBUG */ "add x1, x29, #0x70\n\t" "\n" "L_curve25519_inv_7_%=: \n\t" @@ -2522,17 +2607,22 @@ int curve25519(byte* r, const byte* n, const byte* a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x24, x24, #1\n\t" - "cmp x24, #0\n\t" - "bne L_curve25519_inv_7_%=\n\t" + "subs x24, x24, #1\n\t" + "bcs L_curve25519_inv_7_%=\n\t" "add x0, x29, #0x50\n\t" +#ifndef NDEBUG + "add x1, x29, #0x70\n\t" +#endif /* !NDEBUG */ "add x2, x29, #0x50\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" #else "bl _fe_mul\n\t" #endif /* __APPLE__ */ - "mov x24, #5\n\t" + "mov x24, #4\n\t" +#ifndef NDEBUG + "add x0, x29, #0x50\n\t" +#endif /* !NDEBUG */ "add x1, x29, #0x50\n\t" "\n" "L_curve25519_inv_8_%=: \n\t" @@ -2541,10 +2631,12 @@ int curve25519(byte* r, const byte* n, const byte* a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x24, x24, #1\n\t" - "cmp x24, #0\n\t" - "bne L_curve25519_inv_8_%=\n\t" + "subs x24, x24, #1\n\t" + "bcs L_curve25519_inv_8_%=\n\t" "add x0, x29, #16\n\t" +#ifndef NDEBUG + "add x1, x29, #0x50\n\t" +#endif /* !NDEBUG */ "add x2, x29, #48\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" @@ -2710,6 +2802,9 @@ void fe_pow22523(fe r, const fe a) "str %x[r], [x29, #112]\n\t" "str %x[a], [x29, #120]\n\t" "add x0, x29, #16\n\t" +#ifndef NDEBUG + "ldr x1, [x29, #120]\n\t" +#endif /* !NDEBUG */ #ifndef __APPLE__ "bl fe_sq\n\t" #else @@ -2722,12 +2817,18 @@ void fe_pow22523(fe r, const fe a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ +#ifndef NDEBUG + "add x0, x29, #48\n\t" +#endif /* !NDEBUG */ "add x1, x29, #48\n\t" #ifndef __APPLE__ "bl fe_sq\n\t" #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ +#ifndef NDEBUG + "add x0, x29, #48\n\t" +#endif /* !NDEBUG */ "ldr x1, [x29, #120]\n\t" "add x2, x29, #48\n\t" #ifndef __APPLE__ @@ -2743,11 +2844,20 @@ void fe_pow22523(fe r, const fe a) #else "bl _fe_mul\n\t" #endif /* __APPLE__ */ +#ifndef NDEBUG + "add x0, x29, #16\n\t" +#endif /* !NDEBUG */ +#ifndef NDEBUG + "add x1, x29, #16\n\t" +#endif /* !NDEBUG */ #ifndef __APPLE__ "bl fe_sq\n\t" #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ +#ifndef NDEBUG + "add x0, x29, #16\n\t" +#endif /* !NDEBUG */ "add x1, x29, #48\n\t" "add x2, x29, #16\n\t" #ifndef __APPLE__ @@ -2762,7 +2872,10 @@ void fe_pow22523(fe r, const fe a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "mov x21, #4\n\t" + "mov x23, #3\n\t" +#ifndef NDEBUG + "add x0, x29, #48\n\t" +#endif /* !NDEBUG */ "add x1, x29, #48\n\t" "\n" "L_fe_pow22523_1_%=: \n\t" @@ -2771,10 +2884,12 @@ void fe_pow22523(fe r, const fe a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x21, x21, #1\n\t" - "cmp x21, #0\n\t" - "bne L_fe_pow22523_1_%=\n\t" + "subs x23, x23, #1\n\t" + "bcs L_fe_pow22523_1_%=\n\t" "add x0, x29, #16\n\t" +#ifndef NDEBUG + "add x1, x29, #48\n\t" +#endif /* !NDEBUG */ "add x2, x29, #16\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" @@ -2788,7 +2903,10 @@ void fe_pow22523(fe r, const fe a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "mov x21, #9\n\t" + "mov x23, #8\n\t" +#ifndef NDEBUG + "add x0, x29, #48\n\t" +#endif /* !NDEBUG */ "add x1, x29, #48\n\t" "\n" "L_fe_pow22523_2_%=: \n\t" @@ -2797,9 +2915,14 @@ void fe_pow22523(fe r, const fe a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x21, x21, #1\n\t" - "cmp x21, #0\n\t" - "bne L_fe_pow22523_2_%=\n\t" + "subs x23, x23, #1\n\t" + "bcs L_fe_pow22523_2_%=\n\t" +#ifndef NDEBUG + "add x0, x29, #48\n\t" +#endif /* !NDEBUG */ +#ifndef NDEBUG + "add x1, x29, #48\n\t" +#endif /* !NDEBUG */ "add x2, x29, #16\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" @@ -2807,12 +2930,18 @@ void fe_pow22523(fe r, const fe a) "bl _fe_mul\n\t" #endif /* __APPLE__ */ "add x0, x29, #0x50\n\t" +#ifndef NDEBUG + "add x1, x29, #48\n\t" +#endif /* !NDEBUG */ #ifndef __APPLE__ "bl fe_sq\n\t" #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "mov x21, #19\n\t" + "mov x23, #18\n\t" +#ifndef NDEBUG + "add x0, x29, #0x50\n\t" +#endif /* !NDEBUG */ "add x1, x29, #0x50\n\t" "\n" "L_fe_pow22523_3_%=: \n\t" @@ -2821,17 +2950,22 @@ void fe_pow22523(fe r, const fe a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x21, x21, #1\n\t" - "cmp x21, #0\n\t" - "bne L_fe_pow22523_3_%=\n\t" + "subs x23, x23, #1\n\t" + "bcs L_fe_pow22523_3_%=\n\t" "add x0, x29, #48\n\t" +#ifndef NDEBUG + "add x1, x29, #0x50\n\t" +#endif /* !NDEBUG */ "add x2, x29, #48\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" #else "bl _fe_mul\n\t" #endif /* __APPLE__ */ - "mov x21, #10\n\t" + "mov x23, #9\n\t" +#ifndef NDEBUG + "add x0, x29, #48\n\t" +#endif /* !NDEBUG */ "add x1, x29, #48\n\t" "\n" "L_fe_pow22523_4_%=: \n\t" @@ -2840,10 +2974,12 @@ void fe_pow22523(fe r, const fe a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x21, x21, #1\n\t" - "cmp x21, #0\n\t" - "bne L_fe_pow22523_4_%=\n\t" + "subs x23, x23, #1\n\t" + "bcs L_fe_pow22523_4_%=\n\t" "add x0, x29, #16\n\t" +#ifndef NDEBUG + "add x1, x29, #48\n\t" +#endif /* !NDEBUG */ "add x2, x29, #16\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" @@ -2857,7 +2993,10 @@ void fe_pow22523(fe r, const fe a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "mov x21, #49\n\t" + "mov x23, #48\n\t" +#ifndef NDEBUG + "add x0, x29, #48\n\t" +#endif /* !NDEBUG */ "add x1, x29, #48\n\t" "\n" "L_fe_pow22523_5_%=: \n\t" @@ -2866,9 +3005,14 @@ void fe_pow22523(fe r, const fe a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x21, x21, #1\n\t" - "cmp x21, #0\n\t" - "bne L_fe_pow22523_5_%=\n\t" + "subs x23, x23, #1\n\t" + "bcs L_fe_pow22523_5_%=\n\t" +#ifndef NDEBUG + "add x0, x29, #48\n\t" +#endif /* !NDEBUG */ +#ifndef NDEBUG + "add x1, x29, #48\n\t" +#endif /* !NDEBUG */ "add x2, x29, #16\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" @@ -2876,12 +3020,18 @@ void fe_pow22523(fe r, const fe a) "bl _fe_mul\n\t" #endif /* __APPLE__ */ "add x0, x29, #0x50\n\t" +#ifndef NDEBUG + "add x1, x29, #48\n\t" +#endif /* !NDEBUG */ #ifndef __APPLE__ "bl fe_sq\n\t" #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "mov x21, #0x63\n\t" + "mov x23, #0x62\n\t" +#ifndef NDEBUG + "add x0, x29, #0x50\n\t" +#endif /* !NDEBUG */ "add x1, x29, #0x50\n\t" "\n" "L_fe_pow22523_6_%=: \n\t" @@ -2890,17 +3040,22 @@ void fe_pow22523(fe r, const fe a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x21, x21, #1\n\t" - "cmp x21, #0\n\t" - "bne L_fe_pow22523_6_%=\n\t" + "subs x23, x23, #1\n\t" + "bcs L_fe_pow22523_6_%=\n\t" "add x0, x29, #48\n\t" +#ifndef NDEBUG + "add x1, x29, #0x50\n\t" +#endif /* !NDEBUG */ "add x2, x29, #48\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" #else "bl _fe_mul\n\t" #endif /* __APPLE__ */ - "mov x21, #50\n\t" + "mov x23, #49\n\t" +#ifndef NDEBUG + "add x0, x29, #48\n\t" +#endif /* !NDEBUG */ "add x1, x29, #48\n\t" "\n" "L_fe_pow22523_7_%=: \n\t" @@ -2909,17 +3064,22 @@ void fe_pow22523(fe r, const fe a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x21, x21, #1\n\t" - "cmp x21, #0\n\t" - "bne L_fe_pow22523_7_%=\n\t" + "subs x23, x23, #1\n\t" + "bcs L_fe_pow22523_7_%=\n\t" "add x0, x29, #16\n\t" +#ifndef NDEBUG + "add x1, x29, #48\n\t" +#endif /* !NDEBUG */ "add x2, x29, #16\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" #else "bl _fe_mul\n\t" #endif /* __APPLE__ */ - "mov x21, #2\n\t" + "mov x23, #1\n\t" +#ifndef NDEBUG + "add x0, x29, #16\n\t" +#endif /* !NDEBUG */ "add x1, x29, #16\n\t" "\n" "L_fe_pow22523_8_%=: \n\t" @@ -2928,10 +3088,12 @@ void fe_pow22523(fe r, const fe a) #else "bl _fe_sq\n\t" #endif /* __APPLE__ */ - "sub x21, x21, #1\n\t" - "cmp x21, #0\n\t" - "bne L_fe_pow22523_8_%=\n\t" + "subs x23, x23, #1\n\t" + "bcs L_fe_pow22523_8_%=\n\t" "ldr x0, [x29, #112]\n\t" +#ifndef NDEBUG + "add x1, x29, #16\n\t" +#endif /* !NDEBUG */ "ldr x2, [x29, #120]\n\t" #ifndef __APPLE__ "bl fe_mul\n\t" @@ -2941,7 +3103,7 @@ void fe_pow22523(fe r, const fe a) "ldp x29, x30, [sp], #0x80\n\t" : [r] "+r" (r), [a] "+r" (a) : - : "memory", "x21" + : "memory", "x2", "x23" ); } @@ -3391,7 +3553,7 @@ void fe_ge_to_p2(fe rx, fe ry, fe rz, const fe px, const fe py, const fe pz, con void fe_ge_to_p3(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe pz, const fe pt) { __asm__ __volatile__ ( - "stp x29, x30, [sp, #-80]!\n\t" + "stp x29, x30, [sp, #-96]!\n\t" "add x29, sp, #0\n\t" "str %x[ry], [x29, #16]\n\t" "str %x[rz], [x29, #24]\n\t" @@ -3959,7 +4121,7 @@ void fe_ge_to_p3(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe /* Store */ "stp x3, x4, [x0]\n\t" "stp x5, x6, [x0, #16]\n\t" - "ldp x29, x30, [sp], #0x50\n\t" + "ldp x29, x30, [sp], #0x60\n\t" : [rx] "+r" (rx), [ry] "+r" (ry), [rz] "+r" (rz), [rt] "+r" (rt), [px] "+r" (px), [py] "+r" (py), [pz] "+r" (pz), [pt] "+r" (pt) : : "memory", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26" @@ -4513,8 +4675,11 @@ void fe_ge_dbl(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe pz void fe_ge_madd(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe pz, const fe pt, const fe qxy2d, const fe qyplusx, const fe qyminusx) { __asm__ __volatile__ ( - "stp x29, x30, [sp, #-80]!\n\t" + "stp x29, x30, [sp, #-112]!\n\t" "add x29, sp, #0\n\t" + "str %x[qyminusx], [sp, #104]\n\t" + "str %x[qyplusx], [sp, #96]\n\t" + "str %x[qxy2d], [sp, #88]\n\t" "str %x[rx], [x29, #16]\n\t" "str %x[ry], [x29, #24]\n\t" "str %x[rz], [x29, #32]\n\t" @@ -4560,7 +4725,7 @@ void fe_ge_madd(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe p "adcs x10, x10, x28\n\t" "adc x11, x11, x26\n\t" "ldr x0, [x29, #32]\n\t" - "ldr x2, [x29, #168]\n\t" + "ldr x2, [sp, #96]\n\t" /* Multiply */ "ldp x21, x22, [x2]\n\t" "ldp x23, x24, [x2, #16]\n\t" @@ -4698,7 +4863,7 @@ void fe_ge_madd(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe p "adc x15, x15, xzr\n\t" /* Store */ "ldr x0, [x29, #24]\n\t" - "ldr x1, [x29, #176]\n\t" + "ldr x1, [sp, #104]\n\t" /* Multiply */ "ldp x21, x22, [x1]\n\t" "ldp x23, x24, [x1, #16]\n\t" @@ -4872,7 +5037,7 @@ void fe_ge_madd(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe p "stp x16, x17, [x1]\n\t" "stp x19, x20, [x1, #16]\n\t" "ldr x0, [x29, #40]\n\t" - "ldr x1, [x29, #160]\n\t" + "ldr x1, [sp, #88]\n\t" "ldr x3, [x29, #72]\n\t" /* Multiply */ "ldp x16, x17, [x1]\n\t" @@ -5066,21 +5231,21 @@ void fe_ge_madd(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe p "stp x14, x15, [x0, #16]\n\t" "stp x16, x17, [x1]\n\t" "stp x19, x20, [x1, #16]\n\t" - "ldp x29, x30, [sp], #0x50\n\t" - : [rx] "+r" (rx), [ry] "+r" (ry), [rz] "+r" (rz), [rt] "+r" (rt), [px] "+r" (px), [py] "+r" (py), [pz] "+r" (pz), [pt] "+r" (pt) + "ldp x29, x30, [sp], #0x70\n\t" + : [rx] "+r" (rx), [ry] "+r" (ry), [rz] "+r" (rz), [rt] "+r" (rt), [px] "+r" (px), [py] "+r" (py), [pz] "+r" (pz), [pt] "+r" (pt), [qxy2d] "+r" (qxy2d), [qyplusx] "+r" (qyplusx), [qyminusx] "+r" (qyminusx) : - : "memory", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28" + : "memory", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28" ); - (void)qxy2d; - (void)qyplusx; - (void)qyminusx; } void fe_ge_msub(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe pz, const fe pt, const fe qxy2d, const fe qyplusx, const fe qyminusx) { __asm__ __volatile__ ( - "stp x29, x30, [sp, #-80]!\n\t" + "stp x29, x30, [sp, #-112]!\n\t" "add x29, sp, #0\n\t" + "str %x[qyminusx], [sp, #104]\n\t" + "str %x[qyplusx], [sp, #96]\n\t" + "str %x[qxy2d], [sp, #88]\n\t" "str %x[rx], [x29, #16]\n\t" "str %x[ry], [x29, #24]\n\t" "str %x[rz], [x29, #32]\n\t" @@ -5126,7 +5291,7 @@ void fe_ge_msub(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe p "adcs x10, x10, x28\n\t" "adc x11, x11, x26\n\t" "ldr x0, [x29, #32]\n\t" - "ldr x2, [x29, #176]\n\t" + "ldr x2, [sp, #104]\n\t" /* Multiply */ "ldp x21, x22, [x2]\n\t" "ldp x23, x24, [x2, #16]\n\t" @@ -5264,7 +5429,7 @@ void fe_ge_msub(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe p "adc x15, x15, xzr\n\t" /* Store */ "ldr x0, [x29, #24]\n\t" - "ldr x1, [x29, #168]\n\t" + "ldr x1, [sp, #96]\n\t" /* Multiply */ "ldp x21, x22, [x1]\n\t" "ldp x23, x24, [x1, #16]\n\t" @@ -5438,7 +5603,7 @@ void fe_ge_msub(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe p "stp x16, x17, [x1]\n\t" "stp x19, x20, [x1, #16]\n\t" "ldr x0, [x29, #40]\n\t" - "ldr x1, [x29, #160]\n\t" + "ldr x1, [sp, #88]\n\t" "ldr x3, [x29, #72]\n\t" /* Multiply */ "ldp x16, x17, [x1]\n\t" @@ -5632,21 +5797,22 @@ void fe_ge_msub(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe p "stp x14, x15, [x1, #16]\n\t" "stp x16, x17, [x0]\n\t" "stp x19, x20, [x0, #16]\n\t" - "ldp x29, x30, [sp], #0x50\n\t" - : [rx] "+r" (rx), [ry] "+r" (ry), [rz] "+r" (rz), [rt] "+r" (rt), [px] "+r" (px), [py] "+r" (py), [pz] "+r" (pz), [pt] "+r" (pt) + "ldp x29, x30, [sp], #0x70\n\t" + : [rx] "+r" (rx), [ry] "+r" (ry), [rz] "+r" (rz), [rt] "+r" (rt), [px] "+r" (px), [py] "+r" (py), [pz] "+r" (pz), [pt] "+r" (pt), [qxy2d] "+r" (qxy2d), [qyplusx] "+r" (qyplusx), [qyminusx] "+r" (qyminusx) : - : "memory", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28" + : "memory", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28" ); - (void)qxy2d; - (void)qyplusx; - (void)qyminusx; } void fe_ge_add(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe pz, const fe pt, const fe qz, const fe qt2d, const fe qyplusx, const fe qyminusx) { __asm__ __volatile__ ( - "stp x29, x30, [sp, #-80]!\n\t" + "stp x29, x30, [sp, #-128]!\n\t" "add x29, sp, #0\n\t" + "str %x[qyminusx], [sp, #120]\n\t" + "str %x[qyplusx], [sp, #112]\n\t" + "str %x[qt2d], [sp, #104]\n\t" + "str %x[qz], [sp, #96]\n\t" "str %x[rx], [x29, #16]\n\t" "str %x[ry], [x29, #24]\n\t" "str %x[rz], [x29, #32]\n\t" @@ -5692,7 +5858,7 @@ void fe_ge_add(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe pz "adcs x10, x10, x28\n\t" "adc x11, x11, x26\n\t" "ldr x0, [x29, #32]\n\t" - "ldr x2, [x29, #176]\n\t" + "ldr x2, [sp, #112]\n\t" /* Multiply */ "ldp x21, x22, [x2]\n\t" "ldp x23, x24, [x2, #16]\n\t" @@ -5830,7 +5996,7 @@ void fe_ge_add(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe pz "adc x15, x15, xzr\n\t" /* Store */ "ldr x0, [x29, #24]\n\t" - "ldr x1, [x29, #184]\n\t" + "ldr x1, [sp, #120]\n\t" /* Multiply */ "ldp x21, x22, [x1]\n\t" "ldp x23, x24, [x1, #16]\n\t" @@ -6005,7 +6171,7 @@ void fe_ge_add(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe pz "stp x19, x20, [x1, #16]\n\t" "ldr x0, [x29, #48]\n\t" "ldr x1, [x29, #64]\n\t" - "ldr x2, [x29, #160]\n\t" + "ldr x2, [sp, #96]\n\t" /* Multiply */ "ldp x12, x13, [x1]\n\t" "ldp x14, x15, [x1, #16]\n\t" @@ -6161,7 +6327,7 @@ void fe_ge_add(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe pz "sbcs x6, x6, x28\n\t" "sbc x7, x7, x26\n\t" "ldr x0, [x29, #40]\n\t" - "ldr x1, [x29, #168]\n\t" + "ldr x1, [sp, #104]\n\t" "ldr x2, [x29, #72]\n\t" /* Multiply */ "ldp x16, x17, [x1]\n\t" @@ -6337,22 +6503,22 @@ void fe_ge_add(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe pz "stp x14, x15, [x0, #16]\n\t" "stp x16, x17, [x1]\n\t" "stp x19, x20, [x1, #16]\n\t" - "ldp x29, x30, [sp], #0x50\n\t" - : [rx] "+r" (rx), [ry] "+r" (ry), [rz] "+r" (rz), [rt] "+r" (rt), [px] "+r" (px), [py] "+r" (py), [pz] "+r" (pz), [pt] "+r" (pt) + "ldp x29, x30, [sp], #0x80\n\t" + : [rx] "+r" (rx), [ry] "+r" (ry), [rz] "+r" (rz), [rt] "+r" (rt), [px] "+r" (px), [py] "+r" (py), [pz] "+r" (pz), [pt] "+r" (pt), [qz] "+r" (qz), [qt2d] "+r" (qt2d), [qyplusx] "+r" (qyplusx), [qyminusx] "+r" (qyminusx) : - : "memory", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28" + : "memory", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28" ); - (void)qz; - (void)qt2d; - (void)qyplusx; - (void)qyminusx; } void fe_ge_sub(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe pz, const fe pt, const fe qz, const fe qt2d, const fe qyplusx, const fe qyminusx) { __asm__ __volatile__ ( - "stp x29, x30, [sp, #-80]!\n\t" + "stp x29, x30, [sp, #-128]!\n\t" "add x29, sp, #0\n\t" + "str %x[qyminusx], [sp, #120]\n\t" + "str %x[qyplusx], [sp, #112]\n\t" + "str %x[qt2d], [sp, #104]\n\t" + "str %x[qz], [sp, #96]\n\t" "str %x[rx], [x29, #16]\n\t" "str %x[ry], [x29, #24]\n\t" "str %x[rz], [x29, #32]\n\t" @@ -6398,7 +6564,7 @@ void fe_ge_sub(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe pz "adcs x10, x10, x28\n\t" "adc x11, x11, x26\n\t" "ldr x0, [x29, #32]\n\t" - "ldr x2, [x29, #184]\n\t" + "ldr x2, [sp, #120]\n\t" /* Multiply */ "ldp x21, x22, [x2]\n\t" "ldp x23, x24, [x2, #16]\n\t" @@ -6536,7 +6702,7 @@ void fe_ge_sub(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe pz "adc x15, x15, xzr\n\t" /* Store */ "ldr x0, [x29, #24]\n\t" - "ldr x1, [x29, #176]\n\t" + "ldr x1, [sp, #112]\n\t" /* Multiply */ "ldp x21, x22, [x1]\n\t" "ldp x23, x24, [x1, #16]\n\t" @@ -6711,7 +6877,7 @@ void fe_ge_sub(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe pz "stp x19, x20, [x1, #16]\n\t" "ldr x0, [x29, #48]\n\t" "ldr x1, [x29, #64]\n\t" - "ldr x2, [x29, #160]\n\t" + "ldr x2, [sp, #96]\n\t" /* Multiply */ "ldp x12, x13, [x1]\n\t" "ldp x14, x15, [x1, #16]\n\t" @@ -6867,7 +7033,7 @@ void fe_ge_sub(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe pz "sbcs x6, x6, x28\n\t" "sbc x7, x7, x26\n\t" "ldr x0, [x29, #40]\n\t" - "ldr x1, [x29, #168]\n\t" + "ldr x1, [sp, #104]\n\t" "ldr x2, [x29, #72]\n\t" /* Multiply */ "ldp x16, x17, [x1]\n\t" @@ -7043,15 +7209,11 @@ void fe_ge_sub(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe pz "stp x14, x15, [x0, #16]\n\t" "stp x16, x17, [x1]\n\t" "stp x19, x20, [x1, #16]\n\t" - "ldp x29, x30, [sp], #0x50\n\t" - : [rx] "+r" (rx), [ry] "+r" (ry), [rz] "+r" (rz), [rt] "+r" (rt), [px] "+r" (px), [py] "+r" (py), [pz] "+r" (pz), [pt] "+r" (pt) + "ldp x29, x30, [sp], #0x80\n\t" + : [rx] "+r" (rx), [ry] "+r" (ry), [rz] "+r" (rz), [rt] "+r" (rt), [px] "+r" (px), [py] "+r" (py), [pz] "+r" (pz), [pt] "+r" (pt), [qz] "+r" (qz), [qt2d] "+r" (qt2d), [qyplusx] "+r" (qyplusx), [qyminusx] "+r" (qyminusx) : - : "memory", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28" + : "memory", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28" ); - (void)qz; - (void)qt2d; - (void)qyplusx; - (void)qyminusx; } #endif /* __aarch64__ */ diff --git a/wolfcrypt/src/port/arm/armv8-poly1305.c b/wolfcrypt/src/port/arm/armv8-poly1305.c index 11f3c7c63..18f255952 100644 --- a/wolfcrypt/src/port/arm/armv8-poly1305.c +++ b/wolfcrypt/src/port/arm/armv8-poly1305.c @@ -1,6 +1,6 @@ /* armv8-poly1305.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/arm/armv8-sha256.c b/wolfcrypt/src/port/arm/armv8-sha256.c index 264c8e8ed..8ae994fc8 100644 --- a/wolfcrypt/src/port/arm/armv8-sha256.c +++ b/wolfcrypt/src/port/arm/armv8-sha256.c @@ -1,6 +1,6 @@ /* armv8-sha256.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/arm/armv8-sha512-asm.S b/wolfcrypt/src/port/arm/armv8-sha512-asm.S index 8cff141da..0236bb8a4 100644 --- a/wolfcrypt/src/port/arm/armv8-sha512-asm.S +++ b/wolfcrypt/src/port/arm/armv8-sha512-asm.S @@ -1,6 +1,6 @@ /* armv8-sha512-asm * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -162,16 +162,18 @@ _Transform_Sha512_Len: stp d8, d9, [x29, #96] stp d10, d11, [x29, #112] #ifndef __APPLE__ - adr x3, L_SHA512_transform_neon_len_k + adrp x3, L_SHA512_transform_neon_len_k + add x3, x3, :lo12:L_SHA512_transform_neon_len_k #else - adrp x3, L_SHA512_transform_neon_len_k@PAGE - add x3, x3, :lo12:L_SHA512_transform_neon_len_k@PAGEOFF + adrp x3, L_SHA512_transform_neon_len_k@PAGE + add x3, x3, :lo12:L_SHA512_transform_neon_len_k@PAGEOFF #endif /* __APPLE__ */ #ifndef __APPLE__ - adr x27, L_SHA512_transform_neon_len_ror8 + adrp x27, L_SHA512_transform_neon_len_ror8 + add x27, x27, :lo12:L_SHA512_transform_neon_len_ror8 #else - adrp x27, L_SHA512_transform_neon_len_ror8@PAGE - add x27, x27, :lo12:L_SHA512_transform_neon_len_ror8@PAGEOFF + adrp x27, L_SHA512_transform_neon_len_ror8@PAGE + add x27, x27, :lo12:L_SHA512_transform_neon_len_ror8@PAGEOFF #endif /* __APPLE__ */ ld1 {v11.16b}, [x27] # Load digest into working vars @@ -1065,10 +1067,11 @@ L_sha512_len_neon_start: add x5, x5, x20 add x4, x4, x19 #ifndef __APPLE__ - adr x3, L_SHA512_transform_neon_len_k + adrp x3, L_SHA512_transform_neon_len_k + add x3, x3, :lo12:L_SHA512_transform_neon_len_k #else - adrp x3, L_SHA512_transform_neon_len_k@PAGE - add x3, x3, :lo12:L_SHA512_transform_neon_len_k@PAGEOFF + adrp x3, L_SHA512_transform_neon_len_k@PAGE + add x3, x3, :lo12:L_SHA512_transform_neon_len_k@PAGEOFF #endif /* __APPLE__ */ subs w2, w2, #0x80 bne L_sha512_len_neon_begin diff --git a/wolfcrypt/src/port/arm/armv8-sha512-asm.c b/wolfcrypt/src/port/arm/armv8-sha512-asm.c index 49dffd778..21679d21e 100644 --- a/wolfcrypt/src/port/arm/armv8-sha512-asm.c +++ b/wolfcrypt/src/port/arm/armv8-sha512-asm.c @@ -1,6 +1,6 @@ /* armv8-sha512-asm * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -123,19 +123,19 @@ static const uint64_t L_SHA512_transform_neon_len_ror8[] = { void Transform_Sha512_Len(wc_Sha512* sha512, const byte* data, word32 len) { __asm__ __volatile__ ( - "stp x29, x30, [sp, #-16]!\n\t" - "add x29, sp, #0\n\t" #ifndef __APPLE__ - "adr x3, %[L_SHA512_transform_neon_len_k]\n\t" + "adrp x3, %[L_SHA512_transform_neon_len_k]\n\t" + "add x3, x3, :lo12:%[L_SHA512_transform_neon_len_k]\n\t" #else - "adrp x3, %[L_SHA512_transform_neon_len_k]@PAGE\n\t" - "add x3, x3, %[L_SHA512_transform_neon_len_k]@PAGEOFF\n\t" + "adrp x3, %[L_SHA512_transform_neon_len_k]@PAGE\n\t" + "add x3, x3, %[L_SHA512_transform_neon_len_k]@PAGEOFF\n\t" #endif /* __APPLE__ */ #ifndef __APPLE__ - "adr x27, %[L_SHA512_transform_neon_len_ror8]\n\t" + "adrp x27, %[L_SHA512_transform_neon_len_ror8]\n\t" + "add x27, x27, :lo12:%[L_SHA512_transform_neon_len_ror8]\n\t" #else - "adrp x27, %[L_SHA512_transform_neon_len_ror8]@PAGE\n\t" - "add x27, x27, %[L_SHA512_transform_neon_len_ror8]@PAGEOFF\n\t" + "adrp x27, %[L_SHA512_transform_neon_len_ror8]@PAGE\n\t" + "add x27, x27, %[L_SHA512_transform_neon_len_ror8]@PAGEOFF\n\t" #endif /* __APPLE__ */ "ld1 {v11.16b}, [x27]\n\t" /* Load digest into working vars */ @@ -1031,10 +1031,11 @@ void Transform_Sha512_Len(wc_Sha512* sha512, const byte* data, word32 len) "add x5, x5, x20\n\t" "add x4, x4, x19\n\t" #ifndef __APPLE__ - "adr x3, %[L_SHA512_transform_neon_len_k]\n\t" + "adrp x3, %[L_SHA512_transform_neon_len_k]\n\t" + "add x3, x3, :lo12:%[L_SHA512_transform_neon_len_k]\n\t" #else - "adrp x3, %[L_SHA512_transform_neon_len_k]@PAGE\n\t" - "add x3, x3, %[L_SHA512_transform_neon_len_k]@PAGEOFF\n\t" + "adrp x3, %[L_SHA512_transform_neon_len_k]@PAGE\n\t" + "add x3, x3, %[L_SHA512_transform_neon_len_k]@PAGEOFF\n\t" #endif /* __APPLE__ */ "subs %w[len], %w[len], #0x80\n\t" "bne L_sha512_len_neon_begin_%=\n\t" @@ -1042,7 +1043,6 @@ void Transform_Sha512_Len(wc_Sha512* sha512, const byte* data, word32 len) "stp x6, x7, [%x[sha512], #16]\n\t" "stp x8, x9, [%x[sha512], #32]\n\t" "stp x10, x11, [%x[sha512], #48]\n\t" - "ldp x29, x30, [sp], #16\n\t" : [sha512] "+r" (sha512), [data] "+r" (data), [len] "+r" (len) : [L_SHA512_transform_neon_len_k] "S" (L_SHA512_transform_neon_len_k), [L_SHA512_transform_neon_len_ror8] "S" (L_SHA512_transform_neon_len_ror8) : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11" diff --git a/wolfcrypt/src/port/arm/armv8-sha512.c b/wolfcrypt/src/port/arm/armv8-sha512.c index 83008d924..6258a6bdd 100644 --- a/wolfcrypt/src/port/arm/armv8-sha512.c +++ b/wolfcrypt/src/port/arm/armv8-sha512.c @@ -1,6 +1,6 @@ /* sha512.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/arm/cryptoCell.c b/wolfcrypt/src/port/arm/cryptoCell.c index c3bd2d9c5..4297b50fc 100644 --- a/wolfcrypt/src/port/arm/cryptoCell.c +++ b/wolfcrypt/src/port/arm/cryptoCell.c @@ -1,6 +1,6 @@ /* cryptoCell.c * - * Copyright (C) 2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/arm/cryptoCellHash.c b/wolfcrypt/src/port/arm/cryptoCellHash.c index bc729f7f0..9e0497ef8 100644 --- a/wolfcrypt/src/port/arm/cryptoCellHash.c +++ b/wolfcrypt/src/port/arm/cryptoCellHash.c @@ -1,6 +1,6 @@ /* cryptoCellHash.c * - * Copyright (C) 2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/atmel/atmel.c b/wolfcrypt/src/port/atmel/atmel.c index 5f9f597f1..46c25ae19 100644 --- a/wolfcrypt/src/port/atmel/atmel.c +++ b/wolfcrypt/src/port/atmel/atmel.c @@ -1,6 +1,6 @@ /* atmel.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/caam/caam_aes.c b/wolfcrypt/src/port/caam/caam_aes.c index 5487623c9..e90982641 100644 --- a/wolfcrypt/src/port/caam/caam_aes.c +++ b/wolfcrypt/src/port/caam/caam_aes.c @@ -1,6 +1,6 @@ /* caam_aes.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/caam/caam_driver.c b/wolfcrypt/src/port/caam/caam_driver.c index 1429f1a70..8ef1ac3dd 100644 --- a/wolfcrypt/src/port/caam/caam_driver.c +++ b/wolfcrypt/src/port/caam/caam_driver.c @@ -1,6 +1,6 @@ /* caam_driver.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/caam/caam_error.c b/wolfcrypt/src/port/caam/caam_error.c index a04391e31..0a21ae291 100644 --- a/wolfcrypt/src/port/caam/caam_error.c +++ b/wolfcrypt/src/port/caam/caam_error.c @@ -1,6 +1,6 @@ /* caam_error.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/caam/caam_integrity.c b/wolfcrypt/src/port/caam/caam_integrity.c index 0e7bb0a21..1cf93d5cd 100644 --- a/wolfcrypt/src/port/caam/caam_integrity.c +++ b/wolfcrypt/src/port/caam/caam_integrity.c @@ -1,6 +1,6 @@ /* caam_integrity.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/caam/caam_qnx.c b/wolfcrypt/src/port/caam/caam_qnx.c index 435390df2..336acfbb9 100644 --- a/wolfcrypt/src/port/caam/caam_qnx.c +++ b/wolfcrypt/src/port/caam/caam_qnx.c @@ -1,6 +1,6 @@ /* caam_qnx.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/caam/caam_sha.c b/wolfcrypt/src/port/caam/caam_sha.c index 74d62fb97..b681617ef 100644 --- a/wolfcrypt/src/port/caam/caam_sha.c +++ b/wolfcrypt/src/port/caam/caam_sha.c @@ -1,6 +1,6 @@ /* caam_sha.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/caam/wolfcaam_cmac.c b/wolfcrypt/src/port/caam/wolfcaam_cmac.c index f67944a63..c59bfca13 100644 --- a/wolfcrypt/src/port/caam/wolfcaam_cmac.c +++ b/wolfcrypt/src/port/caam/wolfcaam_cmac.c @@ -1,6 +1,6 @@ /* wolfcaam_cmac.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/caam/wolfcaam_ecdsa.c b/wolfcrypt/src/port/caam/wolfcaam_ecdsa.c index a53247b75..f80c33617 100644 --- a/wolfcrypt/src/port/caam/wolfcaam_ecdsa.c +++ b/wolfcrypt/src/port/caam/wolfcaam_ecdsa.c @@ -1,6 +1,6 @@ /* wolfcaam_ecdsa.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/caam/wolfcaam_init.c b/wolfcrypt/src/port/caam/wolfcaam_init.c index 3a0b5e7c6..aa1d44e73 100644 --- a/wolfcrypt/src/port/caam/wolfcaam_init.c +++ b/wolfcrypt/src/port/caam/wolfcaam_init.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/caam/wolfcaam_qnx.c b/wolfcrypt/src/port/caam/wolfcaam_qnx.c index 741e3700c..1e9c50ef3 100644 --- a/wolfcrypt/src/port/caam/wolfcaam_qnx.c +++ b/wolfcrypt/src/port/caam/wolfcaam_qnx.c @@ -1,6 +1,6 @@ /* wolfcaam_qnx.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/cavium/cavium_octeon_sync.c b/wolfcrypt/src/port/cavium/cavium_octeon_sync.c index 078e8cb52..8329e5c77 100644 --- a/wolfcrypt/src/port/cavium/cavium_octeon_sync.c +++ b/wolfcrypt/src/port/cavium/cavium_octeon_sync.c @@ -1,13 +1,13 @@ /* cavium_octeon_sync.c * - * Copyright(C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * - * This file is part of wolfSSL.(formerly known as CyaSSL) + * This file is part of wolfSSL. * * wolfSSL 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. + * (at your option) any later version. * * wolfSSL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ #ifdef HAVE_CONFIG_H diff --git a/wolfcrypt/src/port/cypress/psoc6_crypto.c b/wolfcrypt/src/port/cypress/psoc6_crypto.c index b00be7714..05e63b0c8 100644 --- a/wolfcrypt/src/port/cypress/psoc6_crypto.c +++ b/wolfcrypt/src/port/cypress/psoc6_crypto.c @@ -1,6 +1,6 @@ /* psoc6_crypto.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_aes.c b/wolfcrypt/src/port/devcrypto/devcrypto_aes.c index 1f6d09d72..5a7221b4d 100644 --- a/wolfcrypt/src/port/devcrypto/devcrypto_aes.c +++ b/wolfcrypt/src/port/devcrypto/devcrypto_aes.c @@ -1,6 +1,6 @@ /* devcrypto_aes.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_hash.c b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c index f73224dd8..09ed5f1ab 100644 --- a/wolfcrypt/src/port/devcrypto/devcrypto_hash.c +++ b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c @@ -1,6 +1,6 @@ /* devcrypto_hash.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/devcrypto/wc_devcrypto.c b/wolfcrypt/src/port/devcrypto/wc_devcrypto.c index 2c80518a3..23a613932 100644 --- a/wolfcrypt/src/port/devcrypto/wc_devcrypto.c +++ b/wolfcrypt/src/port/devcrypto/wc_devcrypto.c @@ -1,6 +1,6 @@ /* wc_devcrypto.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -72,7 +72,7 @@ int wc_DevCryptoCreate(WC_CRYPTODEV* ctx, int type, byte* key, word32 keySz) } if (fcntl(fd, F_SETFD, 1) == -1) { WOLFSSL_MSG("Error setting F_SETFD with fcntl"); - close(fd); + (void)close(fd); return WC_DEVCRYPTO_E; } @@ -89,7 +89,7 @@ int wc_DevCryptoCreate(WC_CRYPTODEV* ctx, int type, byte* key, word32 keySz) } if (ioctl(ctx->cfd, CIOCGSESSION, &ctx->sess)) { - close(fd); + (void)close(fd); WOLFSSL_MSG("Error starting cryptodev session"); return WC_DEVCRYPTO_E; } @@ -108,7 +108,7 @@ void wc_DevCryptoFree(WC_CRYPTODEV* ctx) if (ioctl(ctx->cfd, CIOCFSESSION, &ctx->sess.ses)) { WOLFSSL_MSG("Error stopping cryptodev session"); } - close(ctx->cfd); + (void)close(ctx->cfd); } } diff --git a/wolfcrypt/src/port/intel/quickassist_sync.c b/wolfcrypt/src/port/intel/quickassist_sync.c index e03bca91f..14a45dc99 100644 --- a/wolfcrypt/src/port/intel/quickassist_sync.c +++ b/wolfcrypt/src/port/intel/quickassist_sync.c @@ -1,8 +1,8 @@ /* quickassist_sync.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * - * This file is part of wolfSSL. (formerly known as CyaSSL) + * This file is part of wolfSSL. * * wolfSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ #ifdef HAVE_CONFIG_H diff --git a/wolfcrypt/src/port/mynewt/mynewt_port.c b/wolfcrypt/src/port/mynewt/mynewt_port.c index 8a4e903fb..ee284d76b 100644 --- a/wolfcrypt/src/port/mynewt/mynewt_port.c +++ b/wolfcrypt/src/port/mynewt/mynewt_port.c @@ -1,6 +1,6 @@ /* mynewt_port.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/nrf51.c b/wolfcrypt/src/port/nrf51.c index 042fe9da4..4a2eda0bb 100644 --- a/wolfcrypt/src/port/nrf51.c +++ b/wolfcrypt/src/port/nrf51.c @@ -1,6 +1,6 @@ /* nrf51.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/nxp/dcp_port.c b/wolfcrypt/src/port/nxp/dcp_port.c index 5ef5b7588..c8efcae84 100644 --- a/wolfcrypt/src/port/nxp/dcp_port.c +++ b/wolfcrypt/src/port/nxp/dcp_port.c @@ -1,6 +1,6 @@ /* dcp_port.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/nxp/ksdk_port.c b/wolfcrypt/src/port/nxp/ksdk_port.c index dd8a88098..6d601a407 100644 --- a/wolfcrypt/src/port/nxp/ksdk_port.c +++ b/wolfcrypt/src/port/nxp/ksdk_port.c @@ -1,6 +1,6 @@ /* ksdk_port.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/pic32/pic32mz-crypt.c b/wolfcrypt/src/port/pic32/pic32mz-crypt.c index 80920110e..5db1e4ad4 100644 --- a/wolfcrypt/src/port/pic32/pic32mz-crypt.c +++ b/wolfcrypt/src/port/pic32/pic32mz-crypt.c @@ -1,6 +1,6 @@ /* pic32mz-crypt.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/silabs/silabs_aes.c b/wolfcrypt/src/port/silabs/silabs_aes.c index e98b52f77..2177a58e6 100644 --- a/wolfcrypt/src/port/silabs/silabs_aes.c +++ b/wolfcrypt/src/port/silabs/silabs_aes.c @@ -1,6 +1,6 @@ /* silabs_aes.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/silabs/silabs_ecc.c b/wolfcrypt/src/port/silabs/silabs_ecc.c index 10c243784..78825bb85 100644 --- a/wolfcrypt/src/port/silabs/silabs_ecc.c +++ b/wolfcrypt/src/port/silabs/silabs_ecc.c @@ -1,6 +1,6 @@ /* silabs_ecc.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/silabs/silabs_hash.c b/wolfcrypt/src/port/silabs/silabs_hash.c index 8de8cdd61..afb48a0af 100644 --- a/wolfcrypt/src/port/silabs/silabs_hash.c +++ b/wolfcrypt/src/port/silabs/silabs_hash.c @@ -1,6 +1,6 @@ /* silabs_se_hash.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/silabs/silabs_random.c b/wolfcrypt/src/port/silabs/silabs_random.c index 582f400a8..c4a35d167 100644 --- a/wolfcrypt/src/port/silabs/silabs_random.c +++ b/wolfcrypt/src/port/silabs/silabs_random.c @@ -1,6 +1,6 @@ /* silabs_random.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/st/stm32.c b/wolfcrypt/src/port/st/stm32.c index 17778c097..2c23ed48c 100644 --- a/wolfcrypt/src/port/st/stm32.c +++ b/wolfcrypt/src/port/st/stm32.c @@ -1,6 +1,6 @@ /* stm32.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/st/stsafe.c b/wolfcrypt/src/port/st/stsafe.c index 239b159ae..1151e7430 100644 --- a/wolfcrypt/src/port/st/stsafe.c +++ b/wolfcrypt/src/port/st/stsafe.c @@ -1,6 +1,6 @@ /* stsafe.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/ti/ti-aes.c b/wolfcrypt/src/port/ti/ti-aes.c index 52f2ceb97..ae7a2faef 100644 --- a/wolfcrypt/src/port/ti/ti-aes.c +++ b/wolfcrypt/src/port/ti/ti-aes.c @@ -1,6 +1,6 @@ /* port/ti/ti-aes.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/ti/ti-ccm.c b/wolfcrypt/src/port/ti/ti-ccm.c index 5c0051e03..9af5ede2e 100644 --- a/wolfcrypt/src/port/ti/ti-ccm.c +++ b/wolfcrypt/src/port/ti/ti-ccm.c @@ -1,6 +1,6 @@ /* port/ti/ti_ccm.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/ti/ti-des3.c b/wolfcrypt/src/port/ti/ti-des3.c index 6e93567d7..788ec8b4e 100644 --- a/wolfcrypt/src/port/ti/ti-des3.c +++ b/wolfcrypt/src/port/ti/ti-des3.c @@ -1,6 +1,6 @@ /* port/ti/ti-des.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/ti/ti-hash.c b/wolfcrypt/src/port/ti/ti-hash.c index ab8f2cc22..ee82f003b 100644 --- a/wolfcrypt/src/port/ti/ti-hash.c +++ b/wolfcrypt/src/port/ti/ti-hash.c @@ -1,6 +1,6 @@ /* port/ti/ti-hash.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/xilinx/xil-aesgcm.c b/wolfcrypt/src/port/xilinx/xil-aesgcm.c index 6af4b3177..8aa71c7a8 100644 --- a/wolfcrypt/src/port/xilinx/xil-aesgcm.c +++ b/wolfcrypt/src/port/xilinx/xil-aesgcm.c @@ -1,6 +1,6 @@ /* xil-aesgcm.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/port/xilinx/xil-sha3.c b/wolfcrypt/src/port/xilinx/xil-sha3.c index 2f42e1d78..f116c1b96 100644 --- a/wolfcrypt/src/port/xilinx/xil-sha3.c +++ b/wolfcrypt/src/port/xilinx/xil-sha3.c @@ -1,6 +1,6 @@ /* xil-sha3.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/pwdbased.c b/wolfcrypt/src/pwdbased.c index 5a8251550..5ca96e6b6 100644 --- a/wolfcrypt/src/pwdbased.c +++ b/wolfcrypt/src/pwdbased.c @@ -1,6 +1,6 @@ /* pwdbased.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -376,7 +376,7 @@ int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen, (void)heap; - if (output == NULL || passLen < 0 || saltLen < 0 || kLen < 0) { + if (output == NULL || passLen <= 0 || saltLen <= 0 || kLen < 0) { return BAD_FUNC_ARG; } @@ -387,11 +387,15 @@ int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen, ret = wc_HashGetDigestSize(hashT); if (ret < 0) return ret; + if (ret == 0) + return BAD_STATE_E; u = ret; ret = wc_HashGetBlockSize(hashT); if (ret < 0) return ret; + if (ret == 0) + return BAD_STATE_E; v = ret; #ifdef WOLFSSL_SMALL_STACK diff --git a/wolfcrypt/src/rabbit.c b/wolfcrypt/src/rabbit.c index 820fd0ac3..ce774b07f 100644 --- a/wolfcrypt/src/rabbit.c +++ b/wolfcrypt/src/rabbit.c @@ -1,6 +1,6 @@ /* rabbit.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 9dd91cf47..bac75203e 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -1,6 +1,6 @@ /* random.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -310,7 +310,7 @@ enum { drbgReseed = 1, drbgGenerateW = 2, drbgGenerateH = 3, - drbgInitV + drbgInitV = 4 }; typedef struct DRBG_internal DRBG_internal; @@ -353,7 +353,8 @@ static int Hash_df(DRBG_internal* drbg, byte* out, word32 outSz, byte type, len = (outSz / OUTPUT_BLOCK_LEN) + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0); - for (i = 0, ctr = 1; i < len; i++, ctr++) { + ctr = 1; + for (i = 0; i < len; i++) { #ifndef WOLFSSL_SMALL_STACK_CACHE #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId); @@ -366,8 +367,10 @@ static int Hash_df(DRBG_internal* drbg, byte* out, word32 outSz, byte type, if (ret == 0) #endif ret = wc_Sha256Update(sha, &ctr, sizeof(ctr)); - if (ret == 0) + if (ret == 0) { + ctr++; ret = wc_Sha256Update(sha, (byte*)&bits, sizeof(bits)); + } if (ret == 0) { /* churning V is the only string that doesn't have the type added */ @@ -551,10 +554,12 @@ static WC_INLINE void array_add(byte* d, word32 dLen, const byte* s, word32 sLen if (dLen > 0 && sLen > 0 && dLen >= sLen) { int sIdx, dIdx; - for (sIdx = sLen - 1, dIdx = dLen - 1; sIdx >= 0; dIdx--, sIdx--) { + dIdx = dLen - 1; + for (sIdx = sLen - 1; sIdx >= 0; sIdx--) { carry += (word16)d[dIdx] + (word16)s[sIdx]; d[dIdx] = (byte)carry; carry >>= 8; + dIdx--; } for (; carry != 0 && dIdx >= 0; dIdx--) { diff --git a/wolfcrypt/src/rc2.c b/wolfcrypt/src/rc2.c index 51a6b7193..9051c5f5e 100644 --- a/wolfcrypt/src/rc2.c +++ b/wolfcrypt/src/rc2.c @@ -1,6 +1,6 @@ /* rc2.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/ripemd.c b/wolfcrypt/src/ripemd.c index 484c62fe4..323e0edc4 100644 --- a/wolfcrypt/src/ripemd.c +++ b/wolfcrypt/src/ripemd.c @@ -1,6 +1,6 @@ /* ripemd.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index f1512174b..a6c18e6f2 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -1,6 +1,6 @@ /* rsa.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -171,12 +171,12 @@ int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out, } -int wc_RsaEncryptSize(RsaKey* key) +int wc_RsaEncryptSize(const RsaKey* key) { if (key == NULL) { return BAD_FUNC_ARG; } - return RsaEncryptSize_fips(key); + return RsaEncryptSize_fips((RsaKey*)key); } @@ -1666,7 +1666,11 @@ static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen, } /* check the padding until we find the separator */ - for (i = 2; i < pkcsBlockLen && pkcsBlock[i++] == 0xFF; ) { } + for (i = 2; i < pkcsBlockLen; ) { + if (pkcsBlock[i++] != 0xFF) { + break; + } + } /* Minimum of 11 bytes of pre-message data and must have separator. */ if (i < RSA_MIN_PAD_SZ || pkcsBlock[i-1] != 0) { @@ -1682,8 +1686,9 @@ static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen, word16 j; word16 pastSep = 0; + i = 0; /* Decrypted with private key - unpad must be constant time. */ - for (i = 0, j = 2; j < pkcsBlockLen; j++) { + for (j = 2; j < pkcsBlockLen; j++) { /* Update i if not passed the separator and at separator. */ i |= (~pastSep) & ctMask16Eq(pkcsBlock[j], 0x00) & (j + 1); pastSep |= ctMask16Eq(pkcsBlock[j], 0x00); @@ -2199,6 +2204,8 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out, case RSA_PUBLIC_ENCRYPT: case RSA_PUBLIC_DECRYPT: return sp_RsaPublic_2048(in, inLen, &key->e, &key->n, out, outLen); + default: + break; } } #endif @@ -2228,6 +2235,8 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out, case RSA_PUBLIC_ENCRYPT: case RSA_PUBLIC_DECRYPT: return sp_RsaPublic_3072(in, inLen, &key->e, &key->n, out, outLen); + default: + break; } } #endif @@ -2257,6 +2266,8 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out, case RSA_PUBLIC_ENCRYPT: case RSA_PUBLIC_DECRYPT: return sp_RsaPublic_4096(in, inLen, &key->e, &key->n, out, outLen); + default: + break; } } #endif @@ -2302,7 +2313,7 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out, #endif #ifndef TEST_UNPAD_CONSTANT_TIME - if (ret == 0 && mp_read_unsigned_bin(tmp, (byte*)in, inLen) != MP_OKAY) + if (ret == 0 && mp_read_unsigned_bin(tmp, in, inLen) != MP_OKAY) ret = MP_READ_E; if (ret == 0) { @@ -3009,7 +3020,7 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out, labelSz : size of optional label buffer saltLen : Length of salt used in PSS rng : random number generator */ -static int RsaPrivateDecryptEx(byte* in, word32 inLen, byte* out, +static int RsaPrivateDecryptEx(const byte* in, word32 inLen, byte* out, word32 outLen, byte** outPtr, RsaKey* key, int rsa_type, byte pad_value, int pad_type, enum wc_HashType hash, int mgf, @@ -3128,10 +3139,11 @@ static int RsaPrivateDecryptEx(byte* in, word32 inLen, byte* out, if (outPtr == NULL) { #if !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WOLFSSL_RSA_VERIFY_INLINE) if (rsa_type == RSA_PRIVATE_DECRYPT) { - word32 i, j; + word32 i = 0; + word32 j; int start = (int)((size_t)pad - (size_t)key->data); - for (i = 0, j = 0; j < key->dataLen; j++) { + for (j = 0; j < key->dataLen; j++) { out[i] = key->data[j]; c = ctMaskGTE(j, start); c &= ctMaskLT(i, outLen); @@ -3265,7 +3277,7 @@ int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, #else rng = NULL; #endif - return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key, + return RsaPrivateDecryptEx(in, inLen, out, outLen, NULL, key, RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, WC_RSA_PKCSV15_PAD, WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, 0, rng); } @@ -3282,7 +3294,7 @@ int wc_RsaPrivateDecrypt_ex(const byte* in, word32 inLen, byte* out, #else rng = NULL; #endif - return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key, + return RsaPrivateDecryptEx(in, inLen, out, outLen, NULL, key, RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, type, hash, mgf, label, labelSz, 0, rng); } @@ -3334,11 +3346,11 @@ int wc_RsaSSL_Verify_ex2(const byte* in, word32 inLen, byte* out, word32 outLen #endif #ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER - return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key, + return RsaPrivateDecryptEx(in, inLen, out, outLen, NULL, key, RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, pad_type, hash, wc_hash2mgf(hash), NULL, 0, RSA_PSS_SALT_LEN_DEFAULT, rng); #else - return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key, + return RsaPrivateDecryptEx(in, inLen, out, outLen, NULL, key, RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, pad_type, hash, wc_hash2mgf(hash), NULL, 0, RSA_PSS_SALT_LEN_DISCOVER, rng); #endif @@ -3727,7 +3739,7 @@ int wc_RsaPSS_Sign_ex(const byte* in, word32 inLen, byte* out, word32 outLen, #if !defined(WOLFSSL_RSA_VERIFY_ONLY) || !defined(WOLFSSL_SP_MATH) || \ defined(WC_RSA_PSS) -int wc_RsaEncryptSize(RsaKey* key) +int wc_RsaEncryptSize(const RsaKey* key) { int ret; diff --git a/wolfcrypt/src/sakke.c b/wolfcrypt/src/sakke.c new file mode 100644 index 000000000..789347528 --- /dev/null +++ b/wolfcrypt/src/sakke.c @@ -0,0 +1,6803 @@ +/* sakke.c + * + * Copyright (C) 2006-2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL 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. + * + * wolfSSL 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif + +#ifdef WOLFSSL_HAVE_SP_ECC + #include +#endif + +#ifdef WOLFCRYPT_HAVE_SAKKE + +#include +#include +#include + +/* SAKKE Build Options: + * WOLFSSL_SAKKE_SMALL: Small code size version of SAKKE. + * WOLFSSL_SAKKE_SMALL_MODEXP: Small code size for just SAKKE modexp. + */ + + +#ifdef WOLFCRYPT_SAKKE_CLIENT +/* + * Initialize the client components of the SAKKE key. + * + * @param [in] key SAKKE key to initialize. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +static int sakke_init_client(SakkeKey* key) +{ + int err = 0; + + key->tmp.p1 = wc_ecc_new_point_h(key->ecc.heap); + if (key->tmp.p1 == NULL) { + err = MEMORY_E; + } + if (err == 0) { + key->tmp.p2 = wc_ecc_new_point_h(key->ecc.heap); + if (key->tmp.p2 == NULL) { + err = MEMORY_E; + } + } + if (err == 0) { + key->tmp.p3 = wc_ecc_new_point_h(key->ecc.heap); + if (key->tmp.p3 == NULL) { + err = MEMORY_E; + } + } + if (err == 0) { + key->rsk.rsk = wc_ecc_new_point_h(key->ecc.heap); + if (key->rsk.rsk == NULL) { + err = MEMORY_E; + } + } + if (err == 0) { + key->i.i = wc_ecc_new_point_h(key->ecc.heap); + if (key->i.i == NULL) { + err = MEMORY_E; + } + } + + return err; +} +#endif + +/** + * Initialize the components of the SAKKE key. + * + * Must be called before performing any operations. + * Free the SAKKE key with wc_FreeSakkeKey() when no longer needed. + * + * @param [in] key SAKKE key to initialize. + * @param [in] keySize Size of the curve. For SAKKE set 1, use 128. + * @param [in] curveId ID of curve. For SAKKE set 1, use ECC_SAKKE_1. + * @param [in] heap Heap hint. + * @param [in] devId Device identifier. + * Use INVALID_DEVID when no device used. + * @return 0 on success. + * @return BAD_FUNC_ARG when key is NULL. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int wc_InitSakkeKey_ex(SakkeKey* key, int keySize, int curveId, void* heap, + int devId) +{ + int err = 0; + SakkeKeyParams* params = NULL; + + if (key == NULL) { + err = BAD_FUNC_ARG; + } + + if (err == 0) { + XMEMSET(key, 0, sizeof(*key)); + key->heap = heap; + params = &key->params; + + err = wc_ecc_init_ex(&key->ecc, heap, devId); + } + if (err == 0) { + err = wc_ecc_set_curve(&key->ecc, keySize, curveId); + } + if (err == 0) { + params->base = wc_ecc_new_point_h(key->ecc.heap); + if (params->base == NULL) { + err = MEMORY_E; + } +#ifdef WOLFCRYPT_SAKKE_CLIENT + if (err == 0) { + err = sakke_init_client(key); + } +#endif + if (err == 0) { + err = mp_init_multi(¶ms->prime, ¶ms->q, ¶ms->g, + ¶ms->a, &key->tmp.m1, +#ifdef WOLFCRYPT_SAKKE_CLIENT + &key->tmp.m2 +#else + NULL +#endif + ); + } + if (err == 0) { + key->mpInit = 1; + } + + if (err != 0) { + wc_FreeSakkeKey(key); + } + } + + return err; +} + +/** + * Initialize the components of the SAKKE key. + * + * Must be called before performing any operations. + * Free the SAKKE key with wc_FreeSakkeKey() when no longer needed. + * + * @param [in] key SAKKE key to initialize. + * @param [in] heap Heap hint. + * @param [in] devId Device identifier. + * Use INVALID_DEVID when no device used. + * @return 0 on success. + * @return BAD_FUNC_ARG when key is NULL. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int wc_InitSakkeKey(SakkeKey* key, void* heap, int devId) +{ + return wc_InitSakkeKey_ex(key, 128, ECC_SAKKE_1, heap, devId); +} + +/** + * Frees memory associated with components of the SAKKE key. + * + * Must be called when finished with the SAKKE key. + * + * @param [in] key SAKKE key. + */ +void wc_FreeSakkeKey(SakkeKey* key) +{ + if (key != NULL) { + SakkeKeyParams* params = &key->params; + + if (key->mpInit) { + mp_free(¶ms->prime); + mp_free(¶ms->q); + mp_free(¶ms->g); + mp_free(¶ms->a); + mp_free(&key->tmp.m1); +#ifdef WOLFCRYPT_SAKKE_CLIENT + mp_free(&key->tmp.m2); +#endif + } +#ifdef WOLFCRYPT_SAKKE_CLIENT + if (key->i.i != NULL) { + wc_ecc_del_point_h(key->i.i, key->ecc.heap); + } + if (key->rsk.rsk != NULL) { + wc_ecc_del_point_h(key->rsk.rsk, key->ecc.heap); + } + if (key->tmp.p3 != NULL) { + wc_ecc_del_point_h(key->tmp.p3, key->ecc.heap); + } + if (key->tmp.p2 != NULL) { + wc_ecc_del_point_h(key->tmp.p2, key->ecc.heap); + } + if (key->tmp.p1 != NULL) { + wc_ecc_del_point_h(key->tmp.p1, key->ecc.heap); + } +#endif + if (params->base != NULL) { + wc_ecc_del_point_h(params->base, key->ecc.heap); + } + wc_ecc_free(&key->ecc); + } +} + +/* + * Load order (q), prime (p) and a, hex strings in ECC object, into fields of + * key. + * + * Flags that the p, q and a are available so it isn't loaded multiple times. + * + * @param [in] key SAKKE key. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +static int sakke_load_params(SakkeKey* key) +{ + int err = 0; + SakkeKeyParams* params = &key->params; + + if (!params->havePrime) { + /* Load prime or modulus from string. */ + err = mp_read_radix(¶ms->prime, key->ecc.dp->prime, MP_RADIX_HEX); + if (err == 0) { + params->havePrime = 1; + } + } + if (!params->haveQ) { + /* Load order from string. */ + err = mp_read_radix(¶ms->q, key->ecc.dp->order, MP_RADIX_HEX); + if (err == 0) { + params->haveQ = 1; + } + } + if (!params->haveA) { + /* Load parameter A from string. */ + err = mp_read_radix(¶ms->a, key->ecc.dp->Af, MP_RADIX_HEX); + if (err == 0) { + params->haveA = 1; + } + } + + return err; +} + +/* + * Load the base point, hex encoded in the ECC object, as an ecc_point. + * + * @param [in] key SAKKE key. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +static int sakke_load_base_point(SakkeKey* key) +{ + int err = 0; + SakkeKeyParams* params = &key->params; + + if (!params->haveBase) { + /* Load base point modulus from string. */ + err = mp_read_radix(params->base->x, key->ecc.dp->Gx, MP_RADIX_HEX); + if (err == 0) { + err = mp_read_radix(params->base->y, key->ecc.dp->Gy, MP_RADIX_HEX); + } + if (err == 0) { + /* Affine co-ordinates have a Z of 1 in Jacobian. */ + err = mp_set(params->base->z, 1); + } + if (err == 0) { + /* Base point loaded. */ + params->haveBase = 1; + } + } + + return err; +} + +#ifdef WOLFSSL_HAVE_SP_ECC +/* + * Scalar multiply the base point. + * + * @param [in] key SAKKE key. + * @param [in] n MP integer that is the scalar. + * @param [out] res ECC point to hold the result. + * @param [in] map Map the result to affine co-ordinates. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +static int sakke_mulmod_base(SakkeKey* key, const mp_int* n, ecc_point* res, + int map) +{ + int err = NOT_COMPILED_IN; + +#ifdef WOLFSSL_SP_1024 + if ((key->ecc.idx != ECC_CUSTOM_IDX) && + (ecc_sets[key->ecc.idx].id == ECC_SAKKE_1)) { + err = sp_ecc_mulmod_base_1024(n, res, map, key->heap); + } +#endif + + return err; +} + +/* + * Scalar multiply the base point and add a point. + * + * @param [in] key SAKKE key. + * @param [in] n MP integer that is the scalar. + * @param [in] a ECC point to add. + * @param [out] res ECC point to hold the result. + * @param [in] map Map the result to affine co-ordinates. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +static int sakke_mulmod_base_add(SakkeKey* key, const mp_int* n, + const ecc_point* a, ecc_point* res, int map) +{ + int err = NOT_COMPILED_IN; + +#ifdef WOLFSSL_SP_1024 + if ((key->ecc.idx != ECC_CUSTOM_IDX) && + (ecc_sets[key->ecc.idx].id == ECC_SAKKE_1)) { + err = sp_ecc_mulmod_base_add_1024(n, a, 0, res, map, key->heap); + } +#endif + + return err; +} +#else +/* + * Scalar multiply the base point. + * + * @param [in] key SAKKE key. + * @param [in] n MP integer that is the scalar. + * @param [out] res ECC point to hold the result. + * @param [in] map Map the result to affine co-ordinates. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +static int sakke_mulmod_base(SakkeKey* key, const mp_int* n, ecc_point* res, + int map) +{ + int err; + SakkeKeyParams* params = &key->params; + + err = wc_ecc_mulmod(n, params->base, res, ¶ms->a, ¶ms->prime, map); + + return err; +} + +/* + * Scalar multiply the base point and add a point. + * + * @param [in] key SAKKE key. + * @param [in] n MP integer that is the scalar. + * @param [in] a ECC point to add. Point ordinates must be in Montgomery + * form. + * @param [out] res ECC point to hold the result. + * @param [in] map Map the result to affine co-ordinates. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +static int sakke_mulmod_base_add(SakkeKey* key, const mp_int* n, ecc_point* a, + ecc_point* res, int map) +{ + int err; + mp_digit mp = 0; + SakkeKeyParams* params = &key->params; + + /* Scalar multiply base by n - leaves ordinates in Montogmert form. */ + err = wc_ecc_mulmod(n, params->base, res, ¶ms->a, ¶ms->prime, 0); + if (err == 0) { + err = mp_montgomery_setup(¶ms->prime, &mp); + } + if (err == 0) { + /* Add a to result. */ + err = ecc_projective_add_point(res, a, res, ¶ms->a, + ¶ms->prime, mp); + } + if ((err == 0) && map) { + /* Map result back to affine co-ordinates. */ + err = ecc_map(res, ¶ms->prime, mp); + } + + return err; +} +#endif + +#ifdef WOLFSSL_HAVE_SP_ECC +/* + * Scalar multiply a point. + * + * @param [in] key SAKKE key. + * @param [in] n MP integer that is the scalar. + * @param [in] p ECC point to multiply. + * @param [in] table Precomputation table for p. May be NULL. + * @param [out] res ECC point to hold the result. + * @param [in] map Map the result to affine co-ordinates. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +static int sakke_mulmod_point(SakkeKey* key, const mp_int* n, + const ecc_point* p, byte* table, ecc_point* res, int map) +{ + int err = NOT_COMPILED_IN; + +#ifdef WOLFSSL_SP_1024 + if ((key->ecc.idx != ECC_CUSTOM_IDX) && + (ecc_sets[key->ecc.idx].id == ECC_SAKKE_1)) { + if (table == NULL) { + err = sp_ecc_mulmod_1024(n, p, res, map, key->heap); + } + else { + err = sp_ecc_mulmod_table_1024(n, p, table, res, map, key->heap); + } + } +#endif + + return err; +} +#else +/* + * Scalar multiply a point. + * + * @param [in] key SAKKE key. + * @param [in] n MP integer that is the scalar. + * @param [in] p ECC point to multiply. + * @param [in] table Precomputation table for p. May be NULL. + * @param [out] res ECC point to hold the result. + * @param [in] map Map the result to affine co-ordinates. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +static int sakke_mulmod_point(SakkeKey* key, const mp_int* n, ecc_point* p, + const byte* table, ecc_point* res, int map) +{ + int err; + SakkeKeyParams* params = &key->params; + + err = wc_ecc_mulmod(n, p, res, ¶ms->a, ¶ms->prime, map); + + (void)table; + return err; +} +#endif + +#ifdef WOLFCRYPT_SAKKE_KMS +/** + * Generate KMS Master Secret (z_T) and KMS Public Key (Z_T). + * + * RFC 6508, Section 4.1 + * + * Called when establishing a new KMS.\n + * z_T must be kept secret while Z_T is required by clients for encapsulating + * and deriving. + * Export key using wc_ExportSakkeKey(), once generated, to reuse the key.\n + * Export KPAK using wc_ExportSakkePublicKey(), once generate to send to + * clients. + * + * @param [in] key SAKKE key. + * @param [in] rng Random number generator. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or rng is NULL. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + * @return Other value when an an internal operation fails. + */ +int wc_MakeSakkeKey(SakkeKey* key, WC_RNG* rng) +{ + int err = 0; + int digits = 0; + + if ((key == NULL) || (rng == NULL)) { + err = BAD_FUNC_ARG; + } + + if (err == 0) { + digits = (key->ecc.dp->size * 8 + DIGIT_BIT - 1) / DIGIT_BIT; + + err = sakke_load_params(key); + } + if (err == 0) { + err = sakke_load_base_point(key); + } + if (err == 0) { + int genTryCnt = 0; + + /* Generate a random number that is not 0 - master secret. */ + do { + /* Don't infinitely loop on random number generation failure. */ + if ((++genTryCnt) > SAKKE_MAX_GEN_COUNT) { + err = RNG_FAILURE_E; + } + if (err == 0) { + err = mp_rand(&key->ecc.k, digits, rng); + } + if (err == 0) { + err = mp_mod(&key->ecc.k, &key->params.q, &key->ecc.k); + } + } + while ((err == 0) && mp_iszero(&key->ecc.k)); + } + if (err == 0) { + /* Calculate public key by multiply master secret by base point. */ + err = sakke_mulmod_base(key, &key->ecc.k, &key->ecc.pubkey, 1); + } + if (err == 0) { + key->ecc.type = ECC_PRIVATEKEY; + } + + return err; +} + +/** + * Generates the KMS Public Key (Z_T) from the KMS Master Secret (z_T). + * + * Only z_T is required to calculate Receiver Secret Key (RSK). + * + * @param [in] key SAKKE key. + * @param [out] pub ECC point containing KPAK. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or pub is NULL. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + * @return Other value when an an internal operation fails. + */ +int wc_MakeSakkePublicKey(SakkeKey* key, ecc_point* pub) +{ + int err = 0; + + if ((key == NULL) || (pub == NULL)) { + err = BAD_FUNC_ARG; + } + + if (err == 0) { + err = sakke_load_params(key); + } + if (err == 0) { + err = sakke_load_base_point(key); + } + if (err == 0) { + err = sakke_mulmod_base(key, &key->ecc.k, pub, 1); + } + + return err; +} + +/** + * Export the SAKKE key as encoded public/private ECC key. + * + * Use when saving the KMS key pair. + * + * Private key, x ordinate of public key and y ordinate of public key + * concatenated. Each number is zero padded to key size. + * + * @param [in] key SAKKE key. + * @param [out] data Buffer to hold encoded SAKKE key. + * @param [in,out] sz In, size of buffer in bytes. + * Out, size of encoded SAKKE key in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or sz is NULL. + * @return LENGTH_ONLY_E when data is NULL - sz is set. + * @return BUFFER_E when size of buffer is too small. + */ +int wc_ExportSakkeKey(SakkeKey* key, byte* data, word32* sz) +{ + int err = 0; + + if ((key == NULL) || (sz == NULL)) { + err = BAD_FUNC_ARG; + } + + if ((err == 0) && (data == NULL)) { + *sz = 3 * key->ecc.dp->size; + err = LENGTH_ONLY_E; + } + if ((err >= 0) && (*sz < (word32)(3 * key->ecc.dp->size))) { + err = BUFFER_E; + } + if (err == 0) { + /* Write out the secret value into key size bytes. */ + err = mp_to_unsigned_bin_len(&key->ecc.k, data, key->ecc.dp->size); + } + if (err == 0) { + data += key->ecc.dp->size; + /* Write out the public key point's x ordinate into key size bytes. */ + err = mp_to_unsigned_bin_len(key->ecc.pubkey.x, data, + key->ecc.dp->size); + } + if (err == 0) { + data += key->ecc.dp->size; + /* Write out the public key point's y ordinate into key size bytes. */ + err = mp_to_unsigned_bin_len(key->ecc.pubkey.y, data, + key->ecc.dp->size); + } + if (err == 0) { + *sz = 3 * key->ecc.dp->size; + } + + return err; +} + +/** + * Import the SAKKE key as DER encoded public/private ECC key. + * + * Use when restoring the KMS key pair. + * + * Private key, x ordinate of public key and y ordinate of public key + * concatenated. Each number is zero padded to key size. + * + * @param [in] key SAKKE key. + * @param [in] data Buffer holding encoded SAKKE key. + * @param [in] sz Size of encoded SAKKE key in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or data is NULL. + * @return BUFFER_E when size of data is not equal to the expected size. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + */ +int wc_ImportSakkeKey(SakkeKey* key, const byte* data, word32 sz) +{ + int err = 0; + + if ((key == NULL) || (data == NULL)) { + err = BAD_FUNC_ARG; + } + if ((err == 0) && (sz != (word32)key->ecc.dp->size * 3)) { + err = BUFFER_E; + } + + if (err == 0) { + /* Read the secret value from key size bytes. */ + err = mp_read_unsigned_bin(&key->ecc.k, data, key->ecc.dp->size); + } + if (err == 0) { + data += key->ecc.dp->size; + /* Read the public key point's x value from key size bytes. */ + err = mp_read_unsigned_bin(key->ecc.pubkey.x, data, key->ecc.dp->size); + } + if (err == 0) { + data += key->ecc.dp->size; + /* Read the public key point's y value from key size bytes. */ + err = mp_read_unsigned_bin(key->ecc.pubkey.y, data, key->ecc.dp->size); + } + if (err == 0) { + err = mp_set(key->ecc.pubkey.z, 1); + } + if (err == 0) { + key->ecc.type = ECC_PRIVATEKEY; + } + + return err; +} + +/** + * Export the SAKKE key as DER encoded private ECC key. + * + * Use when saving the KMS private key. + * + * Private key zero padded to key size. + * + * @param [in] key SAKKE key. + * @param [out] data Buffer to hold encoded SAKKE key. + * @param [in,out] sz In, size of buffer in bytes. + * Out, size of encoded SAKKE key in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or sz is NULL. + * @return LENGTH_ONLY_E when data is NULL - sz is set. + * @return BUFFER_E when size of buffer is too small. + */ +int wc_ExportSakkePrivateKey(SakkeKey* key, byte* data, word32* sz) +{ + int err = 0; + + if ((key == NULL) || (sz == NULL)) { + err = BAD_FUNC_ARG; + } + + if ((err == 0) && (data == NULL)) { + *sz = key->ecc.dp->size; + err = LENGTH_ONLY_E; + } + if ((err >= 0) && (*sz < (word32)key->ecc.dp->size)) { + err = BUFFER_E; + } + if (err == 0) { + /* Write out the secret value into key size bytes. */ + err = mp_to_unsigned_bin_len(&key->ecc.k, data, key->ecc.dp->size); + } + if (err == 0) { + *sz = key->ecc.dp->size; + } + + return err; +} + +/** + * Import the SAKKE key as DER encoded private ECC key. + * + * Use when restoring the KMS private key. + * Use wc_MakeSakkePublicKey() to recalculate the public key. + * + * Private key zero padded to key size. + * + * @param [in] key SAKKE key. + * @param [in] data Buffer holding encoded SAKKE key. + * @param [in] sz Size of encoded SAKKE key in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or data is NULL. + * @return BUFFER_E when size of data is not equal to the expected size. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + */ +int wc_ImportSakkePrivateKey(SakkeKey* key, const byte* data, word32 sz) +{ + int err = 0; + + if ((key == NULL) || (data == NULL)) { + err = BAD_FUNC_ARG; + } + + if ((err == 0) && (sz != (word32)key->ecc.dp->size)) { + err = BUFFER_E; + } + + if (err == 0) { + /* Read the secret value from key size bytes. */ + err = mp_read_unsigned_bin(&key->ecc.k, data, key->ecc.dp->size); + } + + return err; +} + +/* + * Convert the public key from montgomery form. + * + * The public key is needed in Montgomery form for validation and derivation. + * + * @param [in] key SAKKE key. + * @return 0 on success. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + * @return Other value when an an internal operation fails. + */ +static int sakke_z_from_mont(SakkeKey* key) +{ + int err = 0; + mp_digit mp; + ecc_point* z = &key->ecc.pubkey; + mp_int* prime = &key->params.prime; + + if (key->zMont) { + err = mp_montgomery_setup(prime, &mp); + if (err == 0) { + err = mp_montgomery_reduce(z->x, prime, mp); + } + if (err == 0) { + err = mp_montgomery_reduce(z->y, prime, mp); + } + if (err == 0) { + err = mp_montgomery_reduce(z->z, prime, mp); + } + if (err == 0) { + key->zMont = 0; + } + } + + return err; +} + +/* + * Encode a point into a buffer. + * + * X and y ordinate of point concatenated. Each number is zero padded tosize. + * Descriptor byte (0x04) is prepeneded when not raw. + * + * @param [in] point ECC point to encode. + * @param [in] size Size of prime in bytes - maximum ordinate length. + * @param [out] data Buffer to hold encoded data. + * NULL when needing length of encoded data. + * @param [in,out] sz In, the size of the buffer in bytes. + * Out, the size of the encoded data in bytes. + * @param [in] raw On 0, prepend descriptor byte. + * On 1, only include ordinates. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or sz is NULL. + * @return LENGTH_ONLY_E when data is NULL - sz will hold the size in bytes of + * the encoded data. + * @return BUFFER_E when size of buffer is too small. + */ +static int sakke_encode_point(ecc_point* point, word32 size, byte* data, + word32* sz, int raw) +{ + int err = 0; + + if (data == NULL) { + *sz = size * 2 + !raw; + err = LENGTH_ONLY_E; + } + if ((err == 0) && (*sz < size * 2 + !raw)) { + err = BUFFER_E; + } + + if (err == 0) { + if (!raw) { + data[0] = 0x04; + data++; + } + + /* Write out the point's x ordinate into key size bytes. */ + err = mp_to_unsigned_bin_len(point->x, data, size); + } + if (err == 0) { + data += size; + /* Write out the point's y ordinate into key size bytes. */ + err = mp_to_unsigned_bin_len(point->y, data, size); + } + if (err == 0) { + *sz = size * 2 + !raw; + } + + return err; +} + +/* + * Decode the data into an ECC point. + * + * X and y ordinate of point concatenated. Each number is zero padded to + * key size. Supports prepended descriptor byte (0x04). + * + * @param [out] point ECC point to encode. + * @param [in] size Size of prime in bytes - maximum ordinate length. + * @param [in] data Encoded public key. + * @param [in] sz Size of the encoded public key in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or z is NULL. + * @return BUFFER_E when size of data is not equal to the expected size. + * @return ASN_PARSE_E when format byte is invalid. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + */ +static int sakke_decode_point(ecc_point* point, word32 size, const byte* data, + word32 sz) +{ + int err = 0; + + if ((err == 0) && (sz != size * 2) && (sz != size * 2 + 1)) { + err = BUFFER_E; + } + + if ((err == 0) && (sz & 1)) { + if (data[0] != 0x04) { + err = ASN_PARSE_E; + } + data++; + } + + if (err == 0) { + /* Read the public key point's x value from key size bytes. */ + err = mp_read_unsigned_bin(point->x, data, size); + } + if (err == 0) { + data += size; + /* Read the public key point's y value from key size bytes. */ + err = mp_read_unsigned_bin(point->y, data, size); + } + if (err == 0) { + err = mp_set(point->z, 1); + } + + return err; +} + + +/** + * Encode the KMS public key (Z_T) into a buffer. + * + * Z_T is required by all clients in order to perform cryptographic operations. + * + * X and y ordinate of public key concatenated. Each number is zero padded to + * key size. + * Descriptor byte (0x04) is prepeneded when not raw. + * + * @param [in] key SAKKE key. + * @param [out] data Buffer to hold encoded data. + * NULL when needing length of encoded data. + * @param [in,out] sz In, the size of the buffer in bytes. + * Out, the size of the encoded data in bytes. + * @param [in] raw On 0, prepend descriptor byte. + * On 1, only include ordinates. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or sz is NULL. + * @return LENGTH_ONLY_E when data is NULL - sz will hold the size in bytes of + * the encoded data. + * @return BUFFER_E when size of buffer is too small. + */ +int wc_ExportSakkePublicKey(SakkeKey* key, byte* data, word32* sz, int raw) +{ + int err = 0; + + if ((key == NULL) || (sz == NULL)) { + err = BAD_FUNC_ARG; + } + + if ((err == 0) && (data != NULL)) { + err = sakke_z_from_mont(key); + } + + if (err == 0) { + err = sakke_encode_point(&key->ecc.pubkey, (word32)key->ecc.dp->size, + data, sz, raw); + } + + return err; +} + +/** + * Calculates the Receiver Secret Key (RSK) for the identity. + * + * RFC 6508, Section 6.1.1 + * + * RSK = [ (a + z_T) ^ 1 modulo q ]P\n + * RSK is required by receiver to derive SSV. + * + * @param [in] key SAKKE key. + * @param [in] id Identity to create hash for. + * @param [in] idSz Length of identity in bytes. + * @param [out] rsk Receiver Secret Key as an ECC point. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, id, or rsk is NULL. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + * @return Other value when an an internal operation fails. + */ +int wc_MakeSakkeRsk(SakkeKey* key, const byte* id, word16 idSz, ecc_point* rsk) +{ + int err = 0; + mp_int* a = NULL; + + if ((key == NULL) || (id == NULL) || (rsk == NULL)) { + err = BAD_FUNC_ARG; + } + + if (err == 0) { + err = sakke_load_params(key); + } + if (err == 0) { + err = sakke_load_base_point(key); + } + + /* Compute RSK = [ (a + z_T) ^ 1 modulo q ]P */ + if (err == 0) { + a = &key->tmp.m1; + err = mp_read_unsigned_bin(a, id, idSz); + } + /* a + z_T */ + if (err == 0) { + err = mp_addmod(a, &key->ecc.k, &key->params.q, a); + } + /* (a + z_T) ^ 1 modulo q */ + if (err == 0) { + err = mp_invmod(a, &key->params.q, a); + } + + /* [ (a + z_T) ^ 1 modulo q ]P */ + if (err == 0) { + err = sakke_mulmod_base(key, a, rsk, 1); + } + + return err; +} + +/** + * Encode the SAKKE Receiver Secret Key (RSK) as DER encoded public ECC key. + * + * Encode the RSK to send to ther receiving client. + * + * X and y ordinate of RSK point concatenated. Each number is zero padded to + * key size. + * Descriptor byte (0x04) is prepeneded when not raw. + * + * @param [in] key SAKKE key. + * @param [in] rsk ECC point that is the Receiver Secret Key (RSK). + * @param [out] out Buffer to hold encoded RSK. + * @param [in,out] sz In, size of buffer in bytes. + * Out, size of encoded RSK in bytes. + * @param [in] raw On 0, prepend descriptor byte. + * On 1, only include ordinates. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, rsk, or sz is NULL. + * @return LENGTH_ONLY_E when data is NULL - sz will hold the size in bytes of + * the encoded data. + * @return BUFFER_E when size of buffer is too small. + */ +int wc_EncodeSakkeRsk(const SakkeKey* key, ecc_point* rsk, byte* out, + word32* sz, int raw) +{ + int err = 0; + + if ((key == NULL) || (rsk == NULL) || (sz == NULL)) { + err = BAD_FUNC_ARG; + } + + if (err == 0) { + err = sakke_encode_point(rsk, (word32)key->ecc.dp->size, out, sz, raw); + } + + return err; +} + +#endif /* WOLFCRYPT_SAKKE_KMS */ + +#ifdef WOLFCRYPT_SAKKE_CLIENT + +/** + * Decode the KMS public key (Z_T) into the key. + * + * A client imports Z_T to perform derivation of SSV. + * + * X and y ordinate of public key concatenated. Each number is zero padded to + * key size. Supports prepended descriptor byte (0x04). + * + * @param [in] key SAKKE key. + * @param [in] data Encoded public key. + * @param [in] sz Size of the encoded public key in bytes. + * @param [in] trusted 1 when public key is trusted. + * 0 when validation is required to be performed. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or z is NULL. + * @return BUFFER_E when size of data is not equal to the expected size. + * @return ASN_PARSE_E when format byte is invalid. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + * @return ECC_OUT_OF_RANGE_E when point is invalid. + * @return ECC_INF_E when point is at infinity and invalid. + */ +int wc_ImportSakkePublicKey(SakkeKey* key, const byte* data, word32 sz, + int trusted) +{ + int err = 0; + + if ((key == NULL) || (data == NULL)) { + err = BAD_FUNC_ARG; + } + + if (err == 0) { + err = sakke_decode_point(&key->ecc.pubkey, (word32)key->ecc.dp->size, + data, sz); + } + if (err == 0) { + key->ecc.type = ECC_PUBLICKEY; + key->zMont = 0; + } + if ((err == 0) && (!trusted)) { + err = wc_ecc_check_key(&key->ecc); + } + + return err; +} + +/** + * Decode the SAKKE Receiver Secret Key (RSK) as DER encoded public ECC key. + * + * A receiving client needs the RSK for deriving SSV. + * + * X and y ordinate of RSK point concatenated. Each number is zero padded to + * key size. Supports prepended descriptor byte (0x04). + * + * @param [in] key SAKKE key. + * @param [in] data Buffer holding encoded SAKKE key. + * @param [in] sz Size of encoded RSK in bytes. + * @param [out] rsk ECC point to hold the Receiver Secret Key (RSK). + * @return 0 on success. + * @return BAD_FUNC_ARG when key, data or rsk is NULL. + * @return BUFFER_E when size of data is not equal to the expected size. + * @return ASN_PARSE_E when format byte is invalid. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + */ +int wc_DecodeSakkeRsk(const SakkeKey* key, const byte* data, word32 sz, + ecc_point* rsk) +{ + int err = 0; + + if ((key == NULL) || (data == NULL) || (rsk == NULL)) { + err = BAD_FUNC_ARG; + } + + if (err == 0) { + err = sakke_decode_point(rsk, (word32)key->ecc.dp->size, data, sz); + } + + return err; +} + +/** + * Decode the SAKKE Receiver Secret Key (RSK) as DER encoded public ECC key and + * stores internally. + * + * A receiving client needs the RSK for deriving SSV. + * + * X and y ordinate of RSK point concatenated. Each number is zero padded to + * key size. Supports prepended descriptor byte (0x04). + * + * @param [in] key SAKKE key. + * @param [in] data Buffer holding encoded SAKKE key. + * @param [in] sz Size of encoded RSK in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or data is NULL. + * @return BUFFER_E when size of data is not equal to the expected size. + * @return MP_MEM or MEMORY_E when dynamic memory allocation fails. + */ +int wc_ImportSakkeRsk(SakkeKey* key, const byte* data, word32 sz) +{ + int err = 0; + + if ((key == NULL) || (data == NULL)) { + err = BAD_FUNC_ARG; + } + + if (err == 0) { + err = wc_DecodeSakkeRsk(key, data, sz, key->rsk.rsk); + } + + return err; +} + +/* Base (g) for SAKKE parameter set 1. */ +static const byte sakke_param_set_1_base[] = { + 0x66, 0xFC, 0x2A, 0x43, 0x2B, 0x6E, 0xA3, 0x92, + 0x14, 0x8F, 0x15, 0x86, 0x7D, 0x62, 0x30, 0x68, + 0xC6, 0xA8, 0x7B, 0xD1, 0xFB, 0x94, 0xC4, 0x1E, + 0x27, 0xFA, 0xBE, 0x65, 0x8E, 0x01, 0x5A, 0x87, + 0x37, 0x1E, 0x94, 0x74, 0x4C, 0x96, 0xFE, 0xDA, + 0x44, 0x9A, 0xE9, 0x56, 0x3F, 0x8B, 0xC4, 0x46, + 0xCB, 0xFD, 0xA8, 0x5D, 0x5D, 0x00, 0xEF, 0x57, + 0x70, 0x72, 0xDA, 0x8F, 0x54, 0x17, 0x21, 0xBE, + 0xEE, 0x0F, 0xAE, 0xD1, 0x82, 0x8E, 0xAB, 0x90, + 0xB9, 0x9D, 0xFB, 0x01, 0x38, 0xC7, 0x84, 0x33, + 0x55, 0xDF, 0x04, 0x60, 0xB4, 0xA9, 0xFD, 0x74, + 0xB4, 0xF1, 0xA3, 0x2B, 0xCA, 0xFA, 0x1F, 0xFA, + 0xD6, 0x82, 0xC0, 0x33, 0xA7, 0x94, 0x2B, 0xCC, + 0xE3, 0x72, 0x0F, 0x20, 0xB9, 0xB7, 0xB0, 0x40, + 0x3C, 0x8C, 0xAE, 0x87, 0xB7, 0xA0, 0x04, 0x2A, + 0xCD, 0xE0, 0xFA, 0xB3, 0x64, 0x61, 0xEA, 0x46 +}; + +/* + * Load Pairing Base (g), hex strings in ECC object, into field of key. + * + * Flags that the g is available so it isn't loaded multiple times. + * + * @param [in] key SAKKE key. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_load_pairing_base(SakkeKey* key) +{ + int err = 0; + SakkeKeyParams* params = &key->params; + + if (!params->haveG) { + if (key->ecc.dp->id != ECC_SAKKE_1) { + err = NOT_COMPILED_IN; + } + if (err == 0) { + err = mp_read_unsigned_bin(¶ms->g, sakke_param_set_1_base, + sizeof(sakke_param_set_1_base)); + if (err == 0) { + params->haveG = 1; + } + } + } + + return err; +} + +#ifndef WOLFSSL_HAVE_SP_ECC +/* + * Put point into Montgomery form. + * + * @param [in] p ECC point. + * @param [in] prime Prime modulus. + * @param [in] mu Temporary MP integer to hold mu. + * @param [in] set 1 when mu is set and 0 when it needs to be calculated. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_point_to_mont(ecc_point* p, mp_int* prime, mp_int* mu, int set) +{ + int err = 0; + + if (!set) { + /* Calculate multiplier that converts to Montgmery form. */ + err = mp_montgomery_calc_normalization(mu, prime); + } + if (err == 0) { + err = mp_mulmod(p->x, mu, prime, p->x); + } + if (err == 0) { + err = mp_mulmod(p->y, mu, prime, p->y); + } + if (err == 0) { + err = mp_mulmod(p->z, mu, prime, p->z); + } + + return err; +} + +/* + * Take point out of Montgomery form. + * + * @param [in] p ECC point. + * @param [in] prime Prime modulus. + * @param [in] mp Multiplier to use when converting from Montgomery form. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_point_from_mont(ecc_point* p, mp_int* prime, mp_digit mp) +{ + int err; + + err = mp_montgomery_reduce(p->x, prime, mp); + if (err == 0) { + err = mp_montgomery_reduce(p->y, prime, mp); + } + if (err == 0) { + err = mp_montgomery_reduce(p->z, prime, mp); + } + + return err; +} + +/* + * Put Z into Montgomery form. + * + * @param [in] key SAKKE key. + * @param [in] mu Temporary MP integer. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_z_to_mont(SakkeKey* key, mp_int* tmp) +{ + int err = 0; + ecc_point* z = &key->ecc.pubkey; + + if (!key->zMont) { + err = sakke_point_to_mont(z, &key->params.prime, tmp, 0); + if (err == 0) { + key->zMont = 1; + } + } + + return err; +} +#endif + +#ifdef WOLFSSL_HAVE_SP_ECC +/** + * Generate a pre-computation table for the RSK point. + * + * The table contains sensitive data. + * + * @param [in] key SAKKE key. + * @param [in] rsk Point to generate table for. + * @param [out] table Pre-generated values. Passing NULL indicates that + * the length of the table is required. + * @param [in,out] len On in, the size of table buffer in bytes. + * On out, the size of the pre-generated data in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, rsk or len is NULL. + * @return LENGTH_ONLY_E when table is NULL. + * @return BAD_LENGTH_E when table is specified and len is too small. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int wc_GenerateSakkeRskTable(const SakkeKey* key, const ecc_point* rsk, + byte* table, word32* len) +{ + int err = 0; + + if ((key == NULL) || (rsk == NULL) || (len == 0)) { + err = BAD_FUNC_ARG; + } + if (err == 0) { +#ifdef WOLFSSL_SP_1024 + err = sp_Pairing_gen_precomp_1024(rsk, table, len); +#else + err = NOT_COMPILED_IN; +#endif + } + + return err; +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * @param [in] key SAKKE key. + * @param [in] p First point on E(F_p)[q]. + * @param [in] q Second point on E(F_p)[q]. + * @param [out] r Result of calculation. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_pairing(const SakkeKey* key, const ecc_point* p, + const ecc_point* q, mp_int* r, const byte* table, word32 len) +{ + int err = NOT_COMPILED_IN; + +#ifdef WOLFSSL_SP_1024 + if ((key->ecc.idx != ECC_CUSTOM_IDX) && + (ecc_sets[key->ecc.idx].id == ECC_SAKKE_1)) { + if (table == NULL) { + err = sp_Pairing_1024(p, q, r); + } + else { + err = sp_Pairing_precomp_1024(p, q, r, table, len); + } + } +#else + (void)key; + (void)p; + (void)q; + (void)r; + (void)table; + (void)len; +#endif + + return err; +} + +#else /* WOLFSSL_HAVE_SP_ECC */ +/** + * Generate a pre-computation table for the RSK point. + * + * Empty table as not supported in this implementation. + * + * @param [in] key SAKKE key. + * @param [in] rsk Point to generate table for. + * @param [out] table Pre-generated values. Passing NULL indicates that + * the length of the table is required. + * @param [in,out] len On in, the size of table buffer in bytes. + * On out, the size of the pre-generated data in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, rsk or len is NULL. + * @return LENGTH_ONLY_E when table is NULL. + * @return BAD_LENGTH_E when table is specified and len is too small. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int wc_GenerateSakkeRskTable(const SakkeKey* key, const ecc_point* rsk, + byte* table, word32* len) +{ + int err = 0; + + if ((key == NULL) || (rsk == NULL) || (len == 0)) { + err = BAD_FUNC_ARG; + } + if ((err == 0) && (table == NULL)) { + *len = 0; + err = LENGTH_ONLY_E; + } + if ((err == 0) && (*len != 0)) { + err = BUFFER_E; + } + if (err == 0) { + *len = 0; + } + + (void)table; + + return err; +} + +/* + * Square a modulo m in Montgomery. + * + * @param [in] a MP integer that is number to square. + * @param [in] m MP integer that is modulus. + * @param [out] r MP integer that is the result. + * @param [in] mp Multiplier to use when converting from Montgomery form. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_mont_sqrmod(mp_int* a, mp_int* m, mp_int* r, mp_digit mp) +{ + int err; + + err = mp_sqr(a, r); + if (err == 0) { + err = mp_montgomery_reduce(r, m, mp); + } + + return err; +} + +/* + * Multiply a by b modulo m in Montgomery. + * + * @param [in] a MP integer that is first number to multiply. + * @param [in] b MP integer that is second number to multiply. + * @param [in] m MP integer that is modulus. + * @param [out] r MP integer that is the result. + * @param [in] mp Multiplier to use when converting from Montgomery form. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_mont_mulmod(mp_int* a, mp_int* b, mp_int* m, mp_int* r, + mp_digit mp) +{ + int err; + + err = mp_mul(a, b, r); + if (err == 0) { + err = mp_montgomery_reduce(r, m, mp); + } + + return err; +} + +/* + * Add a and b modulo m. r = a + b % m + * + * @param [in] a MP integer that is first number to add. + * @param [in] b MP integer that is second number to add. + * @param [out] m MP integer that is modulus. + * @param [in] r MP integer that is the result. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_addmod(mp_int* a, mp_int* b, mp_int* m, mp_int* r) +{ + int err; + + err = mp_add(a, b, r); + if ((err == 0) && (mp_cmp(r, m) != MP_LT)) { + err = mp_sub(r, m, r); + } + + return err; +} + +/* + * Triple a modulo m. r = 3.a % m + * + * @param [in] a MP integer that is number to triple + * @param [out] m MP integer that is modulus. + * @param [in] r MP integer that is the result. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_tplmod(mp_int* a, mp_int* m, mp_int* r) +{ + int err; + + err = mp_mul_d(a, 3, r); + if ((err == 0) && (mp_cmp(r, m) != MP_LT)) { + err = mp_sub(r, m, r); + } + if ((err == 0) && (mp_cmp(r, m) != MP_LT)) { + err = mp_sub(r, m, r); + } + if ((err == 0) && (mp_cmp(r, m) != MP_LT)) { + err = mp_sub(r, m, r); + } + + return err; +} + +/* + * Subtract b from a modulo m. r = a - b % m + * + * @param [in] a MP integer that is first number to add. + * @param [in] b MP integer that is second number to add. + * @param [in] m MP integer that is modulus. + * @param [out] r MP integer that is the result. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_submod(mp_int* a, mp_int* b, mp_int* m, mp_int* r) +{ + int err; + +#if !defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_INT_NEGATIVE) + err = mp_sub(a, b, r); + if ((err == 0) && mp_isneg(r)) { + err = mp_add(r, m, r); + } +#else + err = sp_submod_ct(a, b, m, r); +#endif + + return err; +} + +/* + * Square the element of PF_p[q] (projectivization of F_p with order q). + * + * Calculation: + * r.x = (p.x + p.y) * (p.x - p.y) + * r.y = (p.x * p.y) * 2 + * + * @param [in] p MP projective integer - value to square. + * @param [in] prime MP integer that is the modulus of the field. + * @param [in] mp Multiplier to use when converting from Montgomery form. + * @param [out] r MP projective integer - Result of square. + * @param [in] t1 MP integer temporary. + * @param [in] t2 MP integer temporary. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_proj_sqr(mp_proj* p, mp_int* prime, mp_digit mp, mp_proj* r, + mp_int* t1, mp_int* t2) +{ + int err; + + /* t1 = p.x + p.y */ + err = sakke_addmod(p->x, p->y, prime, t1); + /* t2 = p.x - p.y */ + if (err == 0) { + err = sakke_submod(p->x, p->y, prime, t2); + } + /* r.y = p.x * p.y */ + if (err == 0) { + err = sakke_mont_mulmod(p->x, p->y, prime, r->y, mp); + } + /* r.x = (p.x + p.y) * (p.x - p.y) */ + if (err == 0) { + err = sakke_mont_mulmod(t1, t2, prime, r->x, mp); + } + /* r.y = (p.x * p.y) * 2 */ + if (err == 0) { + err = sakke_addmod(r->y, r->y, prime, r->y); + } + + return err; +} + +/* + * Multiply two elements of PF_p[q] (projectivization of F_p with order q). + * + * q must not be the same object as r. + * Calculation: + * r.x = (p.x * q.x) - (p.y * q.y) + * r.y = (p.x * q.y) + (p.y * q.x) + * + * @param [in] p MP projective integer - first value to multiply. + * @param [in] q MP projective integer - second value to multiply. + * @param [in] prime MP integer that is the modulus of the field. + * @param [in] mp Multiplier to use when converting from Montgomery form. + * @param [out] r Result of operation. + * @param [in] t1 MP integer temporary. + * @param [in] t2 MP integer temporary. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_proj_mul(mp_proj* p, mp_proj* q, mp_int* prime, mp_digit mp, + mp_proj* r, mp_int* t1, mp_int* t2) +{ + int err; + + /* t1 = p.x * q.y */ + err = sakke_mont_mulmod(p->x, q->y, prime, t1, mp); + /* r->x = p.x * q.x */ + if (err == 0) { + err = sakke_mont_mulmod(p->x, q->x, prime, r->x, mp); + } + /* t2 = p.y * q.y */ + if (err == 0) { + err = sakke_mont_mulmod(p->y, q->y, prime, t2, mp); + } + /* r.x = (p.x * q.x) - (p.y * q.y) */ + if (err == 0) { + err = sakke_submod(r->x, t2, prime, r->x); + } + /* r.y = p.y * q.x */ + if (err == 0) { + err = sakke_mont_mulmod(p->y, q->x, prime, r->y, mp); + } + /* r.y = (p.x * q.y) + (p.y * q.x) */ + if (err == 0) { + err = sakke_addmod(t1, r->y, prime, r->y); + } + + return err; +} + +/* + * Multiply two elements of PF_p[q] (projectivization of F_p with order q). + * + * q must not be the same object as r. + * Calculation: + * r.x = (p.x * q.x) - (p.y * q.y) + * r.y = (p.x * q.y) + (p.y * q.x) + * But qx = 1 + * r.x = p.x - (p.y * q.y) + * r.y = (p.x * q.y) + p.y + * + * @param [in] p MP projective integer - first value to multiply. + * @param [in] q MP projective integer - second value to multiply. + * @param [in] prime MP integer that is the modulus of the field. + * @param [in] mp Multiplier to use when converting from Montgomery form. + * @param [out] r Result of operation. + * @param [in] t1 MP integer temporary. + * @param [in] t2 MP integer temporary. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_proj_mul_qx1(mp_proj* p, mp_int* q, mp_int* prime, mp_digit mp, + mp_proj* r, mp_int* t1, mp_int* t2) +{ + int err; + + /* t1 = p.x * q.y */ + err = sakke_mont_mulmod(p->x, q, prime, t1, mp); + /* t2 = p.y * q.y */ + if (err == 0) { + err = sakke_mont_mulmod(p->y, q, prime, t2, mp); + } + /* r.x = p.x - (p.y * q.y) */ + if (err == 0) { + err = sakke_submod(p->x, t2, prime, r->x); + } + /* r.y = (p.x * q.y) + p.y */ + if (err == 0) { + err = sakke_addmod(t1, p->y, prime, r->y); + } + + return err; +} + +/* + * Calculate the gradient of line through P, P and [-2]P. + * + * @param [in] p ECC point - first point on the elliptic curve. + * @param [in] t2 MP integer temporary. + * @param [in] prime MP integer that is the modulus of the field. + * @param [in] mp Multiplier to use when converting from Montgomery form. + * @param [out] l MP integer representing gradient. + * @param [out] z2 MP integer representing p.z^2. + */ +static int sakke_calc_dbl_rx(ecc_point* p, ecc_point* q, mp_int* prime, + mp_digit mp, mp_proj* r, mp_int* l, mp_int* z2) +{ + int err; + mp_int* t = r->y; + + /* z2 = p.z^2 */ + err = sakke_mont_sqrmod(p->z, prime, z2, mp); + /* t = p.x + p.z^2 */ + if (err == 0) { + err = sakke_addmod(p->x, z2, prime, l); + } + /* r1 = p.x - p.z^2 */ + if (err == 0) { + err = sakke_submod(p->x, z2, prime, t); + } + /* l = ((p.x - p.z^2) * (p.x + p.z^2) = p.x ^ 2 - p.z^4 */ + if (err == 0) { + err = sakke_mont_mulmod(l, t, prime, l, mp); + } + /* l = ((p.x ^ 2) - p.z^4) * 3 */ + if (err == 0) { + err = sakke_tplmod(l, prime, l); + } + /* t = q.x * p.z^2 */ + if (err == 0) { + err = sakke_mont_mulmod(q->x, z2, prime, t, mp); + } + /* t = p.x + q.x * p.z^2 */ + if (err == 0) { + err = sakke_addmod(p->x, t, prime, t); + } + /* r.x = l * (p.x + q.x * p.z^2) */ + if (err == 0) { + err = sakke_mont_mulmod(l, t, prime, r->x, mp); + } + + return err; +} + +#ifdef WOLFSSL_SAKKE_SMALL +/* + * Calculate gradient of line through P, P and [-2]P and accumulate line. + * + * Calculation: + * l = 3 * (p.x^2 - p.z^4) = 3 * (p.x - p.z^2) * (p.x + p.z^2) + * r.x = l * (p.x + q.x * p.z^2) - 2 * p.y^2 + * r.y = 2 * p.y * p.z^3 * q.y + * v* = v*^2 * r* + * + * @param [in] p ECC point - first point on the elliptic curve. + * @param [in] q ECC point - second point on the elliptic curve. + * @param [in] prime MP integer that is the modulus of the field. + * @param [in] mp Multiplier to use when converting from Montgomery form. + * @param [out] r MP projective integer - gradient in PF_p[q]. + * @param [in] t1 MP integer temporary. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_accumulate_line_dbl(mp_proj* v, ecc_point* p, ecc_point* q, + mp_int* prime, mp_digit mp, mp_proj* r, mp_int** t) +{ + int err; + mp_int* t1 = t[0]; + mp_int* t2 = r->z; + mp_int* z2 = t[1]; + mp_int* l = t1; + + /* v = v^2 */ + err = sakke_proj_sqr(v, prime, mp, v, t1, t2); + /* l = 3 * (p.x^2 - p.z^4), z2 = p.z^2, rx = l * (p.x + q.x * p.z^2) */ + if (err == 0) { + err = sakke_calc_dbl_rx(p, q, prime, mp, r, l, z2); + } + /* t1 = p.y ^ 2 */ + if (err == 0) { + err = sakke_mont_sqrmod(p->y, prime, t1, mp); + } + /* t1 = 2 * (p.y ^ 2) */ + if (err == 0) { + err = sakke_addmod(t1, t1, prime, t1); + } + /* r.x -= 2 * (p.y ^ 2) */ + if (err == 0) { + err = sakke_submod(r->x, t1, prime, r->x); + } + /* r.y = p.y * 2 */ + if (err == 0) { + err = sakke_addmod(p->y, p->y, prime, r->y); + } + /* r.y = (p.y * 2) * q.y */ + if (err == 0) { + err = sakke_mont_mulmod(r->y, q->y, prime, r->y, mp); + } + /* t2 = p.z^3 */ + if (err == 0) { + err = sakke_mont_mulmod(p->z, z2, prime, t2, mp); + } + /* r.y *= p.z^3 */ + if (err == 0) { + err = sakke_mont_mulmod(r->y, t2, prime, r->y, mp); + } + /* v = v^2 * r */ + if (err == 0) { + err = sakke_proj_mul(v, r, prime, mp, v, t1, t2); + } + + return err; +} + +/* + * Calculate gradient of line through C, P and -C-P and accumulate line. + * + * Calculations: + * r.x = (q.x + p.x) * c.y - (q.x * c.z^2 + c.x) * p.y * c.z + * r.y = (c.x - p.x * c.z^2) * q.y * c.z + * v* = v* * r* + * + * @param [in] p First point on elliptic curve. + * @param [in] q Second point on elliptic curve. + * @param [in] c Third point on elliptic curve. + * @param [in] prime MP integer that is the modulus of the field. + * @param [in] mp Multiplier to use when converting from Montgomery form. + * @param [out] r Resulting gradient in PF_p[q]. + * @param [in] t MP integer temporary. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_accumulate_line_add_one(mp_proj* v, mp_int* prime, mp_digit mp, + ecc_point* p, ecc_point* q, ecc_point* c, mp_proj* r, mp_int* t1) +{ + int err; + mp_int* t2 = r->z; + + /* r.x = (q.x + p.x) * c.y */ + err = sakke_addmod(q->x, p->x, prime, r->x); + if (err == 0) { + err = sakke_mont_mulmod(r->x, c->y, prime, r->x, mp); + } + /* t2 = c.z^2 */ + if (err == 0) { + err = sakke_mont_sqrmod(c->z, prime, t2, mp); + } + /* t = q.x * c.z^2 */ + if (err == 0) { + err = sakke_mont_mulmod(q->x, t2, prime, t1, mp); + } + /* t = q.x * c.z^2 + c.x */ + if (err == 0) { + err = sakke_addmod(t1, c->x, prime, t1); + } + /* t = (q.x * c.z^2 + c.x) * p.y */ + if (err == 0) { + err = sakke_mont_mulmod(t1, p->y, prime, t1, mp); + } + /* t *= c.z */ + if (err == 0) { + err = sakke_mont_mulmod(t1, c->z, prime, t1, mp); + } + /* r.x -= t */ + if (err == 0) { + err = sakke_submod(r->x, t1, prime, r->x); + } + /* t = p.x * c.z^2 */ + if (err == 0) { + err = sakke_mont_mulmod(p->x, t2, prime, t1, mp); + } + /* r.y = c.x - p.x * c.z^2 */ + if (err == 0) { + err = sakke_submod(c->x, t1, prime, r->y); + } + /* r.y = (c.x - p.x) * q.y */ + if (err == 0) { + err = sakke_mont_mulmod(r->y, q->y, prime, r->y, mp); + } + /* r.y = c.x - p.x) * q.y * c.z */ + if (err == 0) { + err = sakke_mont_mulmod(r->y, c->z, prime, r->y, mp); + } + /* v = v * r */ + if (err == 0) { + err = sakke_proj_mul(v, r, prime, mp, v, t1, t2); + } + + return err; +} +#else +/* + * Calculate gradient of line through P, P and [-2]P and accumulate line. + * Double the point p. + * + * Calculation: + * l = 3 * (p.x^2 - p.z^4) = 3 * (p.x - p.z^2) * (p.x + p.z^2) + * r.x = l * (p.x + q.x * p.z^2) - 2 * p.y^2 + * r.y = 2 * p.y * p.z^3 * q.y + * v* = v*^2 * r* + * p'.x = l^2 - 8 * p.y^2 * p.x + * p'.y = (4 * p.y^2 * p.x - p'.x) * l - 8 * p.y^4 + * p'.z = 2 * p.y * p.z + * + * @param [in] p ECC point - first point on the elliptic curve. + * @param [in] q ECC point - second point on the elliptic curve. + * @param [in] prime MP integer that is the modulus of the field. + * @param [in] mp Multiplier to use when converting from Montgomery form. + * @param [out] r MP projective integer - gradient in PF_p[q]. + * @param [in] t1 MP integer temporary. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_accumulate_line_dbl(mp_proj* v, ecc_point* p, ecc_point* q, + mp_int* prime, mp_digit mp, mp_proj* r, mp_int** t) +{ + int err; + mp_int* t1 = t[0]; + mp_int* t2 = r->z; + mp_int* z2 = t[1]; + mp_int tmp[2]; + mp_int* l = &tmp[0]; + mp_int* ty = &tmp[1]; + + err = mp_init(l); + if (err == 0) { + err = mp_init(ty); + } + + /* v = v^2 */ + if (err == 0) { + err = sakke_proj_sqr(v, prime, mp, v, t1, t2); + } + /* l = 3 * (p.x^2 - p.z^4), z2 = p.z^2, rx = l * (p.x + q.x * p.z^2) */ + if (err == 0) { + err = sakke_calc_dbl_rx(p, q, prime, mp, r, l, z2); + } + /* ty = p.y ^ 2 */ + if (err == 0) { + err = sakke_mont_sqrmod(p->y, prime, ty, mp); + } + /* ty = 2 * (p.y ^ 2) */ + if (err == 0) { + err = sakke_addmod(ty, ty, prime, ty); + } + /* r.x -= 2 * (p.y ^ 2) */ + if (err == 0) { + err = sakke_submod(r->x, ty, prime, r->x); + } + /* r.y = p.y * 2 */ + if (err == 0) { + err = sakke_addmod(p->y, p->y, prime, r->y); + } + /* r.y = p.y * 2 * p.z */ + if (err == 0) { + err = sakke_mont_mulmod(r->y, p->z, prime, p->z, mp); + } + /* r.y = p.y * 2 * p.z^3 */ + if (err == 0) { + err = sakke_mont_mulmod(p->z, z2, prime, r->y, mp); + } + /* r.y = (p.y * 2 * p.z^3) * q.y */ + if (err == 0) { + err = sakke_mont_mulmod(r->y, q->y, prime, r->y, mp); + } + /* v = v^2 * r */ + if (err == 0) { + err = sakke_proj_mul(v, r, prime, mp, v, t1, t2); + } + + /* Double point using previously calculated values + * l = 3 * (X - Z^2).(X + Z^2) + * ty = 2 * Y^2 + * Z = 2 * Y * Z + */ + /* Y = 2 * 2 * Y^2 */ + if (err == 0) { + err = sakke_addmod(ty, ty, prime, p->y); + } + /* T2 = 4 * Y^4 */ + if (err == 0) { + err = sakke_mont_sqrmod(ty, prime, t2, mp); + } + /* T2 = 8 * Y^4 */ + if (err == 0) { + err = sakke_addmod(t2, t2, prime, t2); + } + /* Y = Y * X */ + if (err == 0) { + err = sakke_mont_mulmod(p->y, p->x, prime, p->y, mp); + } + /* X = l * l */ + if (err == 0) { + err = sakke_mont_sqrmod(l, prime, p->x, mp); + } + /* X = X - Y */ + if (err == 0) { + err = sakke_submod(p->x, p->y, prime, p->x); + } + /* X = X - Y */ + if (err == 0) { + err = sakke_submod(p->x, p->y, prime, p->x); + } + /* Y = Y - X */ + if (err == 0) { + err = sakke_submod(p->y, p->x, prime, p->y); + } + /* Y = Y * l */ + if (err == 0) { + err = sakke_mont_mulmod(p->y, l, prime, p->y, mp); + } + /* Y = Y - T2 */ + if (err == 0) { + err = sakke_submod(p->y, t2, prime, p->y); + } + + mp_free(ty); + mp_free(l); + + return err; +} + +/* + * Calculate gradient of line through C, P and -C-P and accumulate line. + * Add point p into c. + * + * Calculations: + * r.x = (q.x + p.x) * c.y - (q.x * c.z^2 + c.x) * p.y * c.z + * r.y = (c.x - p.x * c.z^2) * q.y * c.z + * v* = v* * r* + * r = p.y * c.z^3 - c.y + * c'.x = r^2 + h^3 - 2 * c.x * h^2 + * c'.y = r * (c'.x - c.x * h^2) - c.y * h^3 + * c'.z = (c.x - p.x * c.z^2) * c.z + * + * @param [in] p First point on elliptic curve. + * @param [in] q Second point on elliptic curve. + * @param [in] c Third point on elliptic curve. + * @param [in] prime MP integer that is the modulus of the field. + * @param [in] mp Multiplier to use when converting from Montgomery form. + * @param [out] r Resulting gradient in PF_p[q]. + * @param [in] t MP integer temporary. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_accumulate_line_add_one(mp_proj* v, mp_int* prime, mp_digit mp, + ecc_point* p, ecc_point* q, ecc_point* c, mp_proj* r, mp_int** t) +{ + int err; + mp_int* t1 = t[0]; + mp_int* t2 = t[1]; + mp_int tmp[4]; + mp_int* h = &tmp[0]; + mp_int* ty = &tmp[1]; + mp_int* tz = &tmp[2]; + mp_int* t3 = &tmp[3]; + + err = mp_init_multi(h, ty, tz, t3, NULL, NULL); + + /* r.x = (q.x + p.x) * c.y */ + if (err == 0) { + err = sakke_addmod(q->x, p->x, prime, r->x); + } + if (err == 0) { + err = sakke_mont_mulmod(r->x, c->y, prime, r->x, mp); + } + /* tz = c.z^2 */ + if (err == 0) { + err = sakke_mont_sqrmod(c->z, prime, tz, mp); + } + /* t = q.x * c.z^2 */ + if (err == 0) { + err = sakke_mont_mulmod(q->x, tz, prime, t1, mp); + } + /* t = q.x * c.z^2 + c.x */ + if (err == 0) { + err = sakke_addmod(t1, c->x, prime, t1); + } + /* ty = p.y * c.z */ + if (err == 0) { + err = sakke_mont_mulmod(p->y, c->z, prime, ty, mp); + } + /* t = (q.x * c.z^2 + c.x) * p.y * c.z */ + if (err == 0) { + err = sakke_mont_mulmod(t1, ty, prime, t1, mp); + } + /* r.x -= t */ + if (err == 0) { + err = sakke_submod(r->x, t1, prime, r->x); + } + /* t = p.x * c.z^2 */ + if (err == 0) { + err = sakke_mont_mulmod(p->x, tz, prime, t1, mp); + } + /* h = c.x - p.x * c.z^2 */ + if (err == 0) { + err = sakke_submod(c->x, t1, prime, h); + } + /* t3 = (c.x - p.x * c.z^2 ) * c.z*/ + if (err == 0) { + err = sakke_mont_mulmod(h, c->z, prime, t3, mp); + } + /* r.y = (c.x - p.x * c.z^2) * c.z * q.y */ + if (err == 0) { + err = sakke_mont_mulmod(t3, q->y, prime, r->y, mp); + } + /* v = v * r */ + if (err == 0) { + err = sakke_proj_mul(v, r, prime, mp, v, t1, t2); + } + + /* Add p to c using previously calculated values. + * h = c.x - p.x * c.z^2 + * ty = p.y * c.z + * tz = c.z^2 + * t3 = (c.x - p.x * c.z^2) * c.z + */ + + /* R = p.y * c.z^3 - c.y */ + if (err == 0) { + err = sakke_mont_mulmod(ty, tz, prime, ty, mp); + } + if (err == 0) { + err = sakke_submod(ty, c->y, prime, ty); + } + /* c'.z = -H * c.z */ + if (err == 0) { + err = sakke_submod(prime, t3, prime, c->z); + } + /* c'.x = R^2 + H^3 - 2 * c.x * H^2 */ + if (err == 0) { + err = sakke_mont_sqrmod(ty, prime, t1, mp); + } + if (err == 0) { + err = sakke_mont_sqrmod(h, prime, t2, mp); + } + if (err == 0) { + err = sakke_mont_mulmod(c->x, t2, prime, t3, mp); + } + if (err == 0) { + err = sakke_mont_mulmod(t2, h, prime, t2, mp); + } + if (err == 0) { + err = sakke_addmod(t1, t2, prime, c->x); + } + if (err == 0) { + err = sakke_addmod(t3, t3, prime, t1); + } + if (err == 0) { + err = sakke_submod(c->x, t1, prime, c->x); + } + /* c'.y = R * (c.x * H^2 - c'.x) + c.y * H^3 */ + if (err == 0) { + err = sakke_submod(t3, c->x, prime, t3); + } + if (err == 0) { + err = sakke_mont_mulmod(t3, ty, prime, t3, mp); + } + if (err == 0) { + err = sakke_mont_mulmod(t2, c->y, prime, t2, mp); + } + if (err == 0) { + err = sakke_addmod(t3, t2, prime, c->y); + } + + mp_free(t3); + mp_free(tz); + mp_free(ty); + mp_free(h); + + return err; +} +#endif /* WOLFSSL_SAKKE_SMALL */ + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * @param [in] key SAKKE key. + * @param [in] p First point on E(F_p)[q]. + * @param [in] q Second point on E(F_p)[q]. + * @param [out] r Result of calculation. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_pairing(SakkeKey* key, ecc_point* p, ecc_point* q, mp_int* r, + const byte* table, word32 len) +{ + int err; + ecc_point* v = key->params.base; + ecc_point* c = key->tmp.p1; + mp_proj* t2 = key->tmp.p3; + mp_int* t3 = &key->tmp.m2; + mp_int* prime = &key->params.prime; + mp_int* t[] = { &key->tmp.m1, t3 }; + int i; + mp_digit mp = 0; + SakkeKeyParams* params = &key->params; + + (void)table; + (void)len; + + err = sakke_point_to_mont(p, prime, &key->tmp.m1, 0); + if (err == 0) { + err = sakke_point_to_mont(q, prime, &key->tmp.m1, 1); + } + if (err == 0) { + err = wc_ecc_copy_point(p, c); + } + /* Set v to 1. */ + if (err == 0) { + params->haveBase = 0; + err = mp_set(v->x, 1); + } + if (err == 0) { + err = mp_set(v->y, 0); + } + if (err == 0) { + err = mp_montgomery_setup(prime, &mp); + } + + for (i = mp_count_bits(¶ms->q) - 2; (err == 0) && (i >= 0); i--) { +#ifdef WOLFSSL_SAKKE_SMALL + /* Accumulate line into v and double point. */ + err = sakke_accumulate_line_dbl(v, c, q, prime, mp, t2, t); + if (err == 0) { + err = ecc_projective_dbl_point(c, c, NULL, prime, mp); + } + + if ((err == 0) && (i > 0) && mp_is_bit_set(¶ms->q, i)) { + /* Accumulate line into v and add P into C. */ + err = sakke_accumulate_line_add_one(v, prime, mp, p, q, c, t2, + &key->tmp.m1); + if (err == 0) { + err = ecc_projective_add_point(p, c, c, NULL, prime, mp); + } + } +#else + /* Accumulate line into v and double point. */ + err = sakke_accumulate_line_dbl(v, c, q, prime, mp, t2, t); + + if ((err == 0) && (i > 0) && mp_is_bit_set(¶ms->q, i)) { + /* Accumulate line into v and add P into C. */ + err = sakke_accumulate_line_add_one(v, prime, mp, p, q, c, t2, t); + } +#endif /* WOLFSSL_SAKKE_SMALL */ + } + + /* Final exponentiation */ + if (err == 0) { + err = sakke_proj_sqr(v, prime, mp, v, &key->tmp.m1, t3); + } + if (err == 0) { + err = sakke_proj_sqr(v, prime, mp, v, &key->tmp.m1, t3); + } + /* Convert from PF_p[q] to F_p */ + if (err == 0) { + err = mp_invmod(v->x, prime, r); + } + if (err == 0) { + err = mp_mulmod(r, v->y, prime, r); + } + + if (err == 0) { + err = sakke_point_from_mont(p, prime, mp); + } + if (err == 0) { + err = sakke_point_from_mont(q, prime, mp); + } + + return err; +} +#endif /* WOLFSSL_HAVE_SP_ECC */ + +/** + * Set the Receiver Secret Key (RSK) and any table associated with it. + * + * @param [in] key SAKKE key. + * @param [in] rsk Receiver Secret Key (RSK) as an ECC point. + * @param [in] table Pre-computation table. May be NULL. + * @param [in] len Size of pre-compuration table in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or rsk is NULL. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int wc_SetSakkeRsk(SakkeKey* key, const ecc_point* rsk, byte* table, word32 len) +{ + int err = 0; + + if ((key == NULL) || (rsk == NULL)) { + err = BAD_FUNC_ARG; + } + if (err == 0) { + key->rsk.set = 0; + err = wc_ecc_copy_point(rsk, key->rsk.rsk); + } + if (err == 0) { + key->rsk.table = table; + key->rsk.tableLen = len; + key->rsk.set = 1; + } + + return err; +} + +/* + * Compute the elliptic curve point I for device B. Partial for point R. + * + * RFC 6508, Section 6.2.1, Step 3.\n + * RFC 6508, Section 6.2.2, Step 5.\n + * I = [b]P + Z_S + * + * @param [in] key SAKKE key. + * @param [in] id Identifier to of device B. + * @param [in] idSz Size of identifier in bytes. + * @param [out] i ECC point - partial for point R. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_compute_point_i(SakkeKey* key, const byte* id, word16 idSz, + ecc_point* i) +{ + int err; + mp_int* b = &key->ecc.k; + + /* Load b - ID of receiver */ + err = mp_read_unsigned_bin(b, id, idSz); + if (err == 0) { + err = sakke_load_base_point(key); + } +#ifndef WOLFSSL_HAVE_SP_ECC + /* Convert to montgomery form for add operation. */ + if (err == 0) { + err = sakke_z_to_mont(key, &key->tmp.m2); + } +#endif + /* [b]P + Z_S */ + if (err == 0) { + ecc_point* z = &key->ecc.pubkey; + err = sakke_mulmod_base_add(key, b, z, i, 1); + } + return err; +} + +/** + * Validate the Receiver Secret Key (RSK) with the identity. + * + * RFC 6508, Section 6.1.2 + * + * A receiving client should validate an RSK before use. + * + * @param [in] key SAKKE key. + * @param [in] id Identity to use. + * @param [in] idSz Size of identity in bytes. + * @param [in] rsk Receiver Secret Key as an ECC point. + * @param [out] valid 1 indicates RSK is valid for identity. + * 0 otherwise. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, id, rsk or valid is NULL. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +int wc_ValidateSakkeRsk(SakkeKey* key, const byte* id, word16 idSz, + ecc_point* rsk, int* valid) +{ + int err = 0; + mp_int* a = NULL; + + if ((key == NULL) || (id == NULL) || (rsk == NULL) || (valid == NULL)) { + err = BAD_FUNC_ARG; + } + + /* Load elliptic curve parameters */ + if (err == 0) { + err = sakke_load_params(key); + } + if (err == 0) { + err = sakke_load_base_point(key); + } + /* Load pairing base - g */ + if (err == 0) { + err = sakke_load_pairing_base(key); + } + /* Load a - identifier */ + if (err == 0) { + a = &key->tmp.m1; + err = mp_read_unsigned_bin(a, id, idSz); + } + + if (err == 0) { + /* I = [b]P + Z_S */ + err = sakke_compute_point_i(key, id, idSz, key->i.i); + if ((err == 0) && (idSz <= SAKKE_ID_MAX_SIZE)) { + XMEMCPY(key->i.id, id, idSz); + key->i.idSz = idSz; + } + } + /* < [a]P + Z, K_(a,T) > = < K_(a,T), [a]P + Z > = < rsk, i >*/ + if (err == 0) { + err = sakke_pairing(key, rsk, key->i.i, a, NULL, 0); + } + + /* Compare pairing result with generator. */ + if (valid != NULL) { + *valid = ((err == 0) && (mp_cmp(a, &key->params.g) == MP_EQ)); + } + + return err; +} + +/** + * Get the size of the authentication data that is the first part of the + * encapsulated data. + * + * Clients need to know how long the authentication data so as the SSV starts + * after the authentication data in a buffer.\n + * For SAKKE parameter set 1: 257 bytes + * + * @param [in] key SAKKE key. + * @param [out] authSz Size of authentication data in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or authSz is NULL. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +int wc_GetSakkeAuthSize(SakkeKey* key, word16* authSz) +{ + int err = 0; + + if ((key == NULL) || (authSz == NULL)) { + err = BAD_FUNC_ARG; + } + + if (err == 0) { + err = sakke_load_params(key); + } + if (err == 0) { + word16 n = (word16)((mp_count_bits(&key->params.prime) + 7) / 8); + *authSz = 1 + 2 * n; + } + + return err; +} + +#ifdef WOLFSSL_HAVE_SP_ECC +/* + * Modular exponentiate the value in F_p*. + * + * @param [in] key SAKKE key. + * @param [in] b MP integer that is the base to exponentiate. + * @param [in] e MP integer that is the exponent. + * @param [out] r Result of exponentiation. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_modexp(const SakkeKey* key, const mp_int* b, mp_int* e, + mp_int* r) +{ + int err = NOT_COMPILED_IN; + +#ifdef WOLFSSL_SP_1024 + if ((key->ecc.idx != ECC_CUSTOM_IDX) && + (ecc_sets[key->ecc.idx].id == ECC_SAKKE_1)) { + err = sp_ModExp_Fp_star_1024(b, e, r); + } +#endif + + return err; +} +#else +#ifdef WOLFSSL_SAKKE_SMALL +/* + * Modular exponentiate the value in F_p*. + * + * @param [in] key SAKKE key. + * @param [in] b MP integer that is the base to exponentiate. + * @param [in] e MP integer that is the exponent. + * @param [out] c Result of exponentiation. + * @param [in] mp Multiplier to use when converting from Montgomery form. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_modexp_loop(SakkeKey* key, mp_int* b, mp_int* e, mp_proj* c, + mp_digit mp) +{ + int err; + mp_int* t1 = &key->tmp.m1; + mp_int* t2 = &key->tmp.m2; + mp_int* by = key->tmp.p1->z; + mp_int* prime = &key->params.prime; + int i; + + /* Set the working value to the base in PF_p[q] */ + err = mp_montgomery_calc_normalization(c->x, prime); + /* Set c->y as montgomery form of b - base */ + if (err == 0) { + err = mp_mulmod(b, c->x, prime, by); + } + /* Set by as montgomery form of b - base */ + if (err == 0) { + err = mp_copy(by, c->y); + } + /* Simple non-constant time exponentiation over a field. */ + for (i = mp_count_bits(e) - 2; (err == 0) && (i >= 0); i--) { + err = sakke_proj_sqr(c, prime, mp, c, t1, t2); + if (err == 0) { + if (mp_is_bit_set(e, i)) { + err = sakke_proj_mul_qx1(c, by, prime, mp, c, t1, t2); + } + } + } + + return err; +} + +#elif defined(WOLFSSL_SAKKE_SMALL_MODEXP) || !defined(USE_FAST_MATH) + +/* + * Modular exponentiate the value in F_p*. + * + * @param [in] key SAKKE key. + * @param [in] b MP integer that is the base to exponentiate. + * @param [in] e MP integer that is the exponent. + * @param [out] r Result of exponentiation. + * @param [in] mp Multiplier to use when converting from Montgomery form. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_modexp_loop(SakkeKey* key, mp_int* b, mp_int* e, mp_proj* r, + mp_digit mp) +{ + int err; +#ifdef WC_NO_CACHE_RESISTANT + mp_proj* c[2] = { r, key->tmp.p2 }; +#else + mp_proj* c[3] = { r, key->tmp.p3, key->tmp.p2 }; +#endif + mp_int* t1 = &key->tmp.m1; + mp_int* t2 = &key->tmp.m2; + mp_int* by = key->tmp.p1->z; + mp_int* prime = &key->params.prime; + int i; + + /* Set the working value to the base in PF_p[q] */ + err = mp_montgomery_calc_normalization(c[0]->x, prime); + /* Set c[0] to [mont_one, zero] */ + if (err == 0) { + mp_zero(c[0]->y); + } + /* Set by is montgomery form of b - base */ + if (err == 0) { + err = mp_mulmod(b, c[0]->x, prime, by); + } + for (i = mp_count_bits(&key->params.q) - 1; (err == 0) && (i >= 0); i--) { + int j = mp_is_bit_set(e, i); + err = sakke_proj_sqr(c[0], prime, mp, c[0], t1, t2); + if (err == 0) { +#ifdef WC_NO_CACHE_RESISTANT + err = sakke_proj_mul_qx1(c[0], by, prime, mp, c[j^1], t1, t2); +#else + err = sakke_proj_mul_qx1(c[0], by, prime, mp, c[2], t1, t2); + mp_copy(c[2]->x, + (mp_int*) ( ((wolfssl_word)c[0]->x & wc_off_on_addr[j]) + + ((wolfssl_word)c[1]->x & wc_off_on_addr[j^1]) ) ); + mp_copy(c[2]->y, + (mp_int*) ( ((wolfssl_word)c[0]->y & wc_off_on_addr[j]) + + ((wolfssl_word)c[1]->y & wc_off_on_addr[j^1]) ) ); +#endif + } + } + + return err; +} + +#else + +/* Table for 8-bit striping exponentiation. */ +static const byte sakke_1024_g_table[256][128] = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x59, 0xe9, 0x3c, 0x6a, 0x6b, 0xd3, 0xba, 0xf4, 0xaf, 0xd5, + 0x88, 0x91, 0xe8, 0x6c, 0xb2, 0x21, 0x61, 0x52, 0xba, 0x02, + 0xc7, 0x27, 0xc9, 0x8e, 0x21, 0xf1, 0x1c, 0x06, 0x7d, 0x3b, + 0x4f, 0x7d, 0x66, 0xdb, 0xd0, 0x9a, 0x9b, 0x67, 0xe0, 0x96, + 0x6f, 0xaf, 0x7a, 0x00, 0x61, 0xc1, 0xf3, 0x0d, 0x0e, 0x74, + 0x1a, 0x1b, 0x2d, 0x8e, 0xae, 0x58, 0xd6, 0xd8, 0x59, 0xbf, + 0x16, 0xac, 0x6c, 0x6f, 0xad, 0xde, 0xdc, 0x85, 0x8f, 0x88, + 0x71, 0x7c, 0x27, 0xbe, 0x88, 0x2c, 0x2f, 0xd1, 0x51, 0xe6, + 0xd8, 0x9e, 0x2d, 0x14, 0x72, 0xbf, 0x1a, 0xfb, 0x3a, 0xf4, + 0x9b, 0xb4, 0xb3, 0x65, 0x76, 0xd1, 0x26, 0x46, 0xf8, 0x15, + 0x82, 0x64, 0x24, 0x75, 0x40, 0xe8, 0xf3, 0xdf, 0x43, 0xca, + 0x4a, 0x73, 0xea, 0xc9, 0xe9, 0x71, 0xe1, 0x00, 0x7a, 0x58, + 0x17, 0x0a, 0x46, 0xd2, 0x33, 0x5c, 0x16, 0x85 }, + { 0x63, 0xef, 0x18, 0x7b, 0x74, 0xf6, 0x2e, 0x03, 0xbe, 0x85, + 0xac, 0x6a, 0x9b, 0x6a, 0x52, 0xb9, 0x5f, 0x19, 0xc2, 0x0d, + 0x6f, 0x83, 0x73, 0xd3, 0x16, 0xf1, 0x86, 0x31, 0x50, 0xa9, + 0xd0, 0xd9, 0x13, 0x94, 0x6d, 0x17, 0x9f, 0x7b, 0xfa, 0x2e, + 0xdd, 0x9f, 0x6a, 0x91, 0x0a, 0x18, 0x0e, 0xb6, 0x51, 0xf7, + 0x11, 0x9b, 0x4a, 0xc8, 0x43, 0x1c, 0xfd, 0x45, 0x62, 0x67, + 0x40, 0x38, 0x98, 0x13, 0x81, 0x3d, 0x1c, 0xb2, 0x2e, 0xcb, + 0x96, 0x52, 0xb9, 0xbd, 0x3a, 0xfd, 0xf5, 0xcb, 0x6a, 0xb5, + 0x11, 0x8b, 0xd7, 0x92, 0xc1, 0x13, 0x99, 0xfa, 0x97, 0x53, + 0x79, 0x4c, 0x8f, 0x5c, 0x14, 0x18, 0x85, 0x88, 0xaa, 0x99, + 0x3f, 0x52, 0x09, 0x28, 0x9e, 0xa5, 0xa4, 0x4e, 0xa1, 0x9f, + 0x65, 0x30, 0xbb, 0xc9, 0xcc, 0x9f, 0x00, 0xae, 0xf1, 0xe6, + 0xe5, 0x4d, 0xd3, 0x6f, 0x71, 0xdd, 0x45, 0x94 }, + { 0x4f, 0xe6, 0x79, 0x1c, 0xf1, 0x92, 0xda, 0x23, 0x90, 0xdc, + 0xc7, 0x94, 0xdd, 0xac, 0x2c, 0xda, 0x50, 0x5e, 0x8e, 0xc2, + 0xeb, 0x19, 0x96, 0x33, 0x68, 0x2e, 0xcc, 0x49, 0x47, 0x68, + 0x5f, 0xbe, 0xab, 0x0c, 0xb6, 0x3c, 0x12, 0x9f, 0x85, 0xcb, + 0xb1, 0x36, 0x09, 0x86, 0x15, 0x55, 0x9c, 0x41, 0x7f, 0xf3, + 0x35, 0x4e, 0x3f, 0x98, 0x60, 0xc8, 0xa0, 0xed, 0x29, 0x9b, + 0x0f, 0x5c, 0x6c, 0xd1, 0xae, 0x18, 0x28, 0x30, 0x73, 0x3f, + 0xa3, 0xbe, 0x93, 0x3e, 0x0d, 0x41, 0xb3, 0x30, 0xbc, 0x4d, + 0x5b, 0x40, 0x74, 0x74, 0xbb, 0x60, 0xf8, 0xcf, 0xbd, 0xa4, + 0x1b, 0x1f, 0x72, 0x41, 0x09, 0x8b, 0x6f, 0xdb, 0xf0, 0xa2, + 0xc7, 0xaf, 0xd8, 0x1d, 0x73, 0x92, 0xf7, 0x41, 0xce, 0x42, + 0x9b, 0x60, 0x1c, 0x1b, 0xdb, 0x57, 0x2b, 0xec, 0x82, 0xf8, + 0x7c, 0x37, 0x6b, 0x7f, 0x01, 0x6f, 0x45, 0xe7 }, + { 0x04, 0x48, 0x2a, 0x18, 0x56, 0x1d, 0xb2, 0x97, 0x55, 0x5d, + 0x1f, 0xfe, 0xbe, 0x78, 0xd9, 0xd2, 0x18, 0xc2, 0x1f, 0x61, + 0x1a, 0x04, 0x01, 0x70, 0x30, 0x95, 0x70, 0xc4, 0x4e, 0x9a, + 0x1e, 0x52, 0xfa, 0x4d, 0xb1, 0x14, 0x8e, 0x95, 0x07, 0x61, + 0x30, 0xcf, 0xa7, 0xce, 0x5c, 0xac, 0x4a, 0xab, 0xb5, 0x5e, + 0xfd, 0xd0, 0x60, 0x68, 0x9a, 0x9a, 0xea, 0x52, 0xd0, 0x26, + 0x23, 0x3f, 0x98, 0xd5, 0xaa, 0xa7, 0xa6, 0x1a, 0x7b, 0x81, + 0xce, 0xa6, 0x43, 0x0a, 0x6d, 0xe5, 0xe8, 0x8c, 0xea, 0xf6, + 0x9d, 0xfd, 0xe9, 0xed, 0xb2, 0xc1, 0x7b, 0x09, 0x00, 0xc8, + 0x75, 0xe2, 0x71, 0x3b, 0xd7, 0x21, 0x0c, 0x44, 0x71, 0xc6, + 0xdb, 0x41, 0x81, 0xcc, 0x23, 0x7c, 0x7e, 0x88, 0xe9, 0x61, + 0xb3, 0x22, 0xcc, 0x84, 0x5e, 0x65, 0x1d, 0x57, 0x17, 0xc1, + 0x94, 0xa4, 0x23, 0xd5, 0x05, 0xe8, 0x73, 0x3c }, + { 0x83, 0x3a, 0x0f, 0xf8, 0xde, 0xdb, 0xf8, 0x9f, 0x1a, 0x9c, + 0x3f, 0x25, 0x68, 0xcc, 0xdb, 0x44, 0xfa, 0x13, 0x50, 0xd3, + 0xe7, 0x34, 0x27, 0x02, 0x0d, 0x26, 0x7f, 0xd9, 0x86, 0x92, + 0x07, 0x7a, 0x66, 0xe1, 0xa4, 0x9f, 0xd7, 0x35, 0x57, 0xe9, + 0x5b, 0x51, 0x85, 0x4d, 0x35, 0x45, 0x96, 0x68, 0x40, 0xc2, + 0x7a, 0x04, 0x32, 0xa3, 0xd2, 0x22, 0x96, 0x3b, 0x05, 0x3e, + 0xd7, 0xb2, 0xea, 0x45, 0xc8, 0xe4, 0x49, 0x9c, 0x57, 0x12, + 0x8d, 0x37, 0xd6, 0xf2, 0x1f, 0x1a, 0x7e, 0x44, 0xfe, 0xb5, + 0x28, 0xfc, 0x30, 0x7c, 0x45, 0x31, 0xbc, 0x60, 0x56, 0x0b, + 0xee, 0x25, 0xbd, 0x8c, 0x22, 0x60, 0xa0, 0xe5, 0x4f, 0x02, + 0xf3, 0x37, 0x36, 0x30, 0x72, 0x3c, 0x99, 0xfc, 0x21, 0x88, + 0xab, 0x4f, 0x81, 0x69, 0xf9, 0x46, 0x61, 0xcd, 0xc1, 0xe7, + 0xe7, 0x75, 0x8a, 0xc2, 0x73, 0xd4, 0x86, 0xd8 }, + { 0x69, 0x2b, 0x3c, 0xe3, 0xeb, 0x24, 0x96, 0x5f, 0x2e, 0x2d, + 0xf9, 0x5a, 0x85, 0xf8, 0x11, 0xa0, 0x74, 0x1f, 0xd5, 0x1a, + 0xf4, 0xf0, 0x5c, 0x0c, 0x03, 0xf7, 0x3e, 0xa6, 0xa2, 0xb7, + 0x44, 0xf1, 0x1f, 0xec, 0x95, 0xe1, 0xd8, 0xa1, 0x05, 0x8a, + 0x22, 0xd6, 0x39, 0xc8, 0xcb, 0x11, 0x87, 0xdb, 0x42, 0x13, + 0xbe, 0x88, 0x2d, 0xd0, 0x6e, 0xc0, 0xf3, 0x66, 0xed, 0x59, + 0xe9, 0xdb, 0xad, 0xd1, 0x33, 0x9e, 0xda, 0xd6, 0xa1, 0xd5, + 0xc2, 0x70, 0xe5, 0x13, 0x35, 0x0b, 0xe6, 0xeb, 0x26, 0x0b, + 0x04, 0xbe, 0x5a, 0xee, 0xb4, 0xc1, 0x6a, 0x2a, 0x56, 0xfe, + 0xe0, 0x7b, 0x09, 0x8c, 0x0a, 0x88, 0x93, 0x1b, 0xa5, 0x1e, + 0xa6, 0x25, 0x75, 0xa6, 0xe5, 0x6b, 0xb9, 0xe2, 0xa9, 0x0c, + 0x51, 0x4d, 0x3b, 0x72, 0x94, 0xf3, 0x27, 0xd0, 0xf0, 0xcc, + 0xa8, 0xc4, 0x19, 0xc7, 0xab, 0x37, 0x6b, 0x76 }, + { 0x33, 0x3e, 0x43, 0x0a, 0xf4, 0x00, 0x42, 0xd6, 0xc0, 0xcf, + 0x0a, 0xaf, 0x81, 0xde, 0x5f, 0xe0, 0x77, 0x41, 0x91, 0xb1, + 0x89, 0xef, 0x09, 0xf2, 0x64, 0x47, 0x90, 0x38, 0x70, 0x36, + 0x1f, 0x25, 0x32, 0xd6, 0x43, 0x31, 0xd4, 0x12, 0x83, 0x27, + 0x8c, 0x4e, 0x85, 0x33, 0x54, 0x52, 0x64, 0x3c, 0x05, 0xb9, + 0x49, 0x1c, 0xa0, 0x9d, 0x46, 0x95, 0x58, 0x1f, 0xa3, 0x97, + 0x3d, 0x65, 0x29, 0x36, 0x54, 0xc2, 0x40, 0xd7, 0x7d, 0x2a, + 0xf8, 0x31, 0x17, 0x4d, 0x0b, 0x40, 0x74, 0xe2, 0x52, 0xf9, + 0x2f, 0x42, 0x6c, 0xae, 0x4d, 0xe4, 0xe6, 0x65, 0xc8, 0x14, + 0x5c, 0x6d, 0xb2, 0xed, 0xbe, 0x8c, 0x16, 0x3d, 0x9a, 0x01, + 0xe0, 0xab, 0x96, 0xee, 0x43, 0xec, 0xf4, 0x63, 0x47, 0xa3, + 0x76, 0x16, 0x66, 0xa4, 0x6e, 0xa5, 0x8f, 0x92, 0x81, 0x6f, + 0x0c, 0xe6, 0xcb, 0x72, 0xd2, 0xa1, 0x27, 0xb4 }, + { 0x10, 0xe8, 0xb3, 0x1d, 0xd6, 0xbb, 0xd7, 0x08, 0xae, 0x12, + 0x76, 0x36, 0x2f, 0x77, 0x91, 0xd1, 0xbb, 0x18, 0xd1, 0x75, + 0x4a, 0xeb, 0x02, 0xa3, 0x8a, 0xdc, 0x6f, 0xe5, 0x45, 0x9e, + 0xa4, 0x62, 0xeb, 0x9a, 0x71, 0xa1, 0x15, 0xaa, 0xa4, 0x08, + 0x94, 0xfe, 0x18, 0x62, 0x65, 0x72, 0xcd, 0x52, 0xb3, 0xa1, + 0x04, 0xe5, 0xcd, 0xde, 0xb5, 0x8c, 0x3f, 0xc2, 0x1e, 0x74, + 0x04, 0x63, 0x13, 0x86, 0xb5, 0x44, 0x34, 0x83, 0xfe, 0x3e, + 0xe7, 0x55, 0x94, 0x8a, 0x37, 0xaf, 0xf1, 0x3b, 0x85, 0x87, + 0xd9, 0xd0, 0x4d, 0xd9, 0x65, 0xc9, 0x13, 0xbb, 0x1f, 0xfc, + 0x9d, 0x7d, 0x0b, 0x06, 0x10, 0x37, 0xef, 0x29, 0x1e, 0xa4, + 0x85, 0x03, 0x73, 0x60, 0xa4, 0x01, 0x3c, 0x5f, 0x18, 0x08, + 0xb6, 0x64, 0x57, 0xa7, 0x73, 0x06, 0xb5, 0x3f, 0x79, 0xbe, + 0x5d, 0xf0, 0x4d, 0xe4, 0xcf, 0x26, 0xd3, 0xb7 }, + { 0x64, 0x85, 0x52, 0x4c, 0x0c, 0xdc, 0xc4, 0xbc, 0xfd, 0x26, + 0x1c, 0x83, 0x2a, 0x84, 0x95, 0xab, 0x38, 0x64, 0x6b, 0x32, + 0xe7, 0xac, 0x0a, 0x06, 0x9a, 0x87, 0x39, 0x3f, 0x5b, 0x6f, + 0x55, 0x57, 0x3c, 0x8e, 0x1d, 0xb2, 0xda, 0x0a, 0x55, 0x68, + 0xcb, 0x1f, 0xbc, 0x54, 0xf3, 0x5e, 0x1a, 0x88, 0xcf, 0xcb, + 0x6e, 0xae, 0x4f, 0xdc, 0x3f, 0x7f, 0xfe, 0x59, 0x0d, 0xfe, + 0x03, 0x6c, 0x03, 0x57, 0x90, 0x38, 0xf9, 0x5d, 0x2f, 0xbe, + 0xb5, 0x4c, 0x6d, 0xc7, 0xfc, 0x7c, 0x26, 0xd5, 0x5e, 0xf5, + 0x97, 0x82, 0xe9, 0xe4, 0x93, 0x82, 0x54, 0x7a, 0xb1, 0x65, + 0x4d, 0x17, 0x1a, 0xf9, 0x9c, 0x15, 0x18, 0x77, 0xe2, 0xb0, + 0x26, 0xb1, 0xe8, 0x5b, 0x38, 0xdc, 0xd6, 0x30, 0x74, 0xce, + 0x15, 0xb8, 0x03, 0xad, 0x24, 0x77, 0x56, 0x67, 0x61, 0x66, + 0xb8, 0x7f, 0x03, 0xe5, 0x3e, 0xd9, 0xf1, 0xaf }, + { 0x1f, 0x76, 0xf3, 0xf2, 0xf2, 0x34, 0x56, 0x3c, 0xa4, 0x06, + 0x1c, 0x7a, 0x2d, 0xf8, 0xb4, 0x49, 0x65, 0x46, 0xa6, 0x0c, + 0x00, 0xa3, 0x3d, 0x80, 0x24, 0x07, 0x8b, 0xac, 0xfa, 0x38, + 0x3f, 0x09, 0xa6, 0x50, 0xa8, 0xf5, 0x63, 0x2d, 0x28, 0xb2, + 0x32, 0x75, 0x8d, 0x24, 0x57, 0x4b, 0x99, 0x97, 0x13, 0x5c, + 0x44, 0x37, 0x19, 0x81, 0x18, 0x2d, 0x5d, 0x51, 0x81, 0xd5, + 0xb9, 0x14, 0xbe, 0x7c, 0x70, 0x0b, 0x19, 0x03, 0x57, 0x0c, + 0xbb, 0x5b, 0x92, 0x41, 0x1f, 0xeb, 0x91, 0x7b, 0x1e, 0x7a, + 0xb9, 0xf0, 0x76, 0x4d, 0x49, 0xa0, 0x1f, 0x05, 0x38, 0x18, + 0x6a, 0xe9, 0xd2, 0xa1, 0x82, 0xcb, 0x23, 0x37, 0x88, 0x3a, + 0xba, 0x5d, 0xbd, 0x93, 0x88, 0x42, 0x27, 0xf0, 0x89, 0xaf, + 0xf7, 0x42, 0x2a, 0xa0, 0x3f, 0xba, 0x35, 0xa6, 0x42, 0x8a, + 0x1a, 0xbf, 0xb3, 0xe2, 0xc4, 0xa6, 0xff, 0x2a }, + { 0x04, 0x92, 0x4f, 0xfb, 0x3d, 0x10, 0x8e, 0x05, 0xd0, 0xf3, + 0x67, 0xbb, 0x04, 0x9e, 0xa7, 0x26, 0xc0, 0x28, 0xca, 0x94, + 0x4e, 0xd2, 0xa5, 0x38, 0xfd, 0x9f, 0xc3, 0x3c, 0x04, 0xed, + 0x89, 0x9d, 0x3c, 0x25, 0x62, 0xaf, 0xf1, 0xd4, 0x99, 0x5a, + 0xaf, 0x92, 0xa4, 0xcc, 0xdc, 0x84, 0xbc, 0x92, 0x3a, 0x6f, + 0x93, 0xdd, 0x18, 0x12, 0xac, 0xb7, 0x7f, 0x87, 0x80, 0x26, + 0x2e, 0xe5, 0xfd, 0xe8, 0xa9, 0x8a, 0x5a, 0x8c, 0x9b, 0xb9, + 0x44, 0x3a, 0xb2, 0x7b, 0xf6, 0x93, 0x11, 0x6b, 0x74, 0x88, + 0xa9, 0x9f, 0x29, 0x15, 0x3a, 0xdc, 0xe7, 0x1e, 0xf8, 0x31, + 0x46, 0x4f, 0x7d, 0x0a, 0xfa, 0x48, 0x85, 0x76, 0x1f, 0x41, + 0xed, 0x56, 0xba, 0x82, 0x35, 0xf3, 0x11, 0x7b, 0x5f, 0x6d, + 0xb2, 0xdf, 0x79, 0x07, 0x05, 0x56, 0x1f, 0x69, 0xc8, 0x7a, + 0x9a, 0xa2, 0xc1, 0x43, 0x44, 0xc4, 0x36, 0xb0 }, + { 0x4d, 0xfc, 0xe8, 0x09, 0xc3, 0x80, 0xae, 0x35, 0x08, 0xcd, + 0x84, 0x9c, 0xc1, 0x46, 0x84, 0x26, 0x58, 0xa8, 0x2b, 0x76, + 0x9f, 0x14, 0x27, 0x99, 0x87, 0x80, 0xa7, 0x84, 0xf3, 0xc5, + 0x3b, 0xce, 0xda, 0xd9, 0xe1, 0x82, 0x90, 0x62, 0xfa, 0x49, + 0xb4, 0x0b, 0x07, 0x2e, 0x25, 0x07, 0x26, 0x61, 0x79, 0xa7, + 0xb2, 0xcb, 0x15, 0x08, 0x27, 0x2a, 0xc9, 0x7e, 0x24, 0xa3, + 0x92, 0x5e, 0x5f, 0x4e, 0xf8, 0xa0, 0xdf, 0x66, 0xe0, 0x12, + 0x90, 0xd3, 0x4a, 0xe8, 0xb7, 0xd4, 0x20, 0x99, 0x1b, 0x8c, + 0x4b, 0x8e, 0xbb, 0x8e, 0x14, 0xd7, 0xe9, 0x5b, 0x76, 0x73, + 0x91, 0xc0, 0x41, 0xd6, 0xe1, 0x8e, 0x42, 0x4e, 0x20, 0x64, + 0x6e, 0xbe, 0x55, 0x7b, 0xe6, 0x1f, 0xd3, 0x2b, 0x5e, 0x1c, + 0x69, 0x77, 0xd3, 0xb3, 0x30, 0x25, 0xe2, 0xea, 0xe4, 0x8c, + 0x06, 0x54, 0x8e, 0x3d, 0xc6, 0x73, 0x56, 0x2f }, + { 0x0d, 0x07, 0x59, 0x08, 0xb8, 0xa0, 0x68, 0x02, 0xdc, 0x7d, + 0xaf, 0xf8, 0x93, 0x39, 0xbd, 0x23, 0xc5, 0x62, 0x59, 0x5d, + 0xe4, 0x28, 0xa4, 0x08, 0x59, 0xe9, 0xe8, 0x1d, 0xe2, 0x15, + 0x3c, 0x22, 0x24, 0xa5, 0x71, 0x53, 0x9f, 0x3a, 0x53, 0x2f, + 0x30, 0x7f, 0xd7, 0xd8, 0x47, 0xd0, 0x12, 0x28, 0x7f, 0xce, + 0xcb, 0x04, 0x5c, 0x4e, 0xd9, 0xba, 0xf1, 0x73, 0xdc, 0x2e, + 0x81, 0xdc, 0x56, 0xb3, 0x1e, 0x10, 0xf1, 0x39, 0xd1, 0x5c, + 0x8d, 0x8a, 0x83, 0xfa, 0x8c, 0xc5, 0xca, 0x91, 0x6e, 0x7c, + 0xd6, 0x89, 0x13, 0x82, 0x45, 0xf0, 0xff, 0x47, 0x4c, 0x65, + 0x26, 0x23, 0x55, 0x4a, 0xdf, 0x3c, 0x34, 0x10, 0x2c, 0x26, + 0xbb, 0x2d, 0x1b, 0x2b, 0x10, 0xcc, 0x60, 0x0b, 0xe2, 0x7d, + 0x02, 0x63, 0xd5, 0x2d, 0xa0, 0x15, 0x97, 0x79, 0x30, 0xdd, + 0x45, 0x06, 0x9c, 0xb2, 0xd5, 0x27, 0xb7, 0x80 }, + { 0x24, 0xfa, 0x96, 0x1c, 0x2f, 0x08, 0x53, 0x5a, 0xf2, 0xcd, + 0xe2, 0x15, 0xa4, 0x36, 0x0d, 0xfe, 0xfb, 0xee, 0xd7, 0xed, + 0x70, 0x0c, 0x11, 0x51, 0x28, 0x3f, 0x74, 0x4d, 0x39, 0x3f, + 0x2e, 0x2a, 0xb6, 0x86, 0x12, 0xb9, 0xf0, 0x49, 0x28, 0xe9, + 0xf5, 0xda, 0xfc, 0xec, 0x52, 0x61, 0x17, 0xe5, 0xef, 0x0d, + 0x22, 0x44, 0x1c, 0xfc, 0xbc, 0x52, 0x88, 0x3d, 0x0b, 0xb5, + 0xa8, 0xd6, 0x4e, 0xf6, 0x39, 0x2f, 0x28, 0x96, 0x27, 0x26, + 0x95, 0xbe, 0x01, 0x48, 0xcf, 0x1c, 0x79, 0x10, 0xc6, 0x82, + 0x5c, 0x05, 0xc2, 0xf5, 0x6d, 0xca, 0x36, 0x15, 0x83, 0xb9, + 0x60, 0x21, 0xf6, 0x22, 0xda, 0x0d, 0x1f, 0x02, 0xa2, 0xe4, + 0x85, 0x59, 0xf8, 0x51, 0x88, 0xc0, 0xd2, 0x61, 0x59, 0xca, + 0x41, 0x3b, 0x88, 0xfc, 0xd2, 0x4f, 0xbe, 0x99, 0xb2, 0xe5, + 0x87, 0x0a, 0xf2, 0xa7, 0xde, 0x08, 0x5f, 0x2a }, + { 0x37, 0x1c, 0xc2, 0x3d, 0xfc, 0x4f, 0x01, 0x14, 0x94, 0xd7, + 0xa0, 0x3d, 0x4a, 0x6f, 0xb6, 0xe1, 0x20, 0x1f, 0x61, 0xd1, + 0x77, 0x52, 0xfa, 0x60, 0x8e, 0xff, 0x77, 0xe3, 0x75, 0x56, + 0x03, 0xf3, 0xf6, 0x35, 0xb1, 0xfc, 0x8f, 0x4d, 0x7d, 0x4e, + 0x5e, 0x1b, 0x8b, 0x7f, 0xe5, 0x0e, 0xe1, 0x73, 0x8c, 0xeb, + 0x75, 0x9f, 0x39, 0xad, 0x43, 0xab, 0x27, 0x3e, 0x1c, 0x8f, + 0x41, 0x95, 0x01, 0x58, 0xc0, 0x32, 0x14, 0xe9, 0xcc, 0x94, + 0x2f, 0x9e, 0x5a, 0x57, 0xf4, 0x86, 0xc9, 0x89, 0x51, 0x45, + 0xba, 0xb4, 0x6a, 0xf4, 0xd6, 0xc2, 0x7d, 0x12, 0x18, 0xb1, + 0x91, 0xdf, 0xcc, 0x89, 0xa0, 0x60, 0x22, 0x84, 0xf3, 0x45, + 0x68, 0x96, 0x43, 0xdb, 0x17, 0x4d, 0xaa, 0x90, 0x6e, 0x82, + 0xd5, 0x44, 0x64, 0x30, 0x57, 0xd8, 0xfb, 0xd9, 0x03, 0x26, + 0x07, 0x67, 0xdb, 0x3f, 0x61, 0x6d, 0xf7, 0xf6 }, + { 0x92, 0xb6, 0xbc, 0xa0, 0x0c, 0x80, 0xfb, 0x7f, 0x3e, 0x60, + 0x2e, 0x4f, 0xc9, 0xf4, 0xd7, 0x8f, 0x33, 0x0f, 0x6a, 0x7a, + 0xf1, 0xbc, 0x13, 0xe8, 0x03, 0xc2, 0xc0, 0xe8, 0x5b, 0xa6, + 0xe6, 0xc6, 0x06, 0xf6, 0xa5, 0x8d, 0x76, 0x40, 0xc3, 0x0e, + 0x70, 0xd9, 0x7d, 0x07, 0x26, 0xdd, 0xe2, 0x4a, 0x45, 0x69, + 0x7e, 0x91, 0xe8, 0x7d, 0x34, 0x74, 0x40, 0xa4, 0x94, 0xd3, + 0x3a, 0x80, 0x20, 0x38, 0x3f, 0x9a, 0x6d, 0x78, 0x99, 0xcb, + 0x39, 0x53, 0x12, 0x80, 0xf1, 0x56, 0xe0, 0x02, 0x40, 0xf2, + 0x88, 0x36, 0xcd, 0x08, 0xdc, 0x4c, 0x80, 0x7b, 0xdc, 0x4f, + 0x7e, 0x36, 0x08, 0x10, 0x01, 0x27, 0xcc, 0x28, 0xc1, 0x64, + 0x6f, 0x57, 0x64, 0x2f, 0x77, 0xa8, 0x92, 0x02, 0xf6, 0x50, + 0xb3, 0x1b, 0x6d, 0x19, 0x6e, 0xbf, 0x36, 0x4d, 0x9c, 0x06, + 0x28, 0x9b, 0x11, 0x5d, 0xda, 0x90, 0xc3, 0x51 }, + { 0x71, 0xff, 0x62, 0xc9, 0x4f, 0x02, 0xf8, 0x9d, 0xe7, 0xdb, + 0x4b, 0x98, 0xcf, 0x33, 0x87, 0x1c, 0x21, 0x5a, 0xd8, 0x30, + 0x1f, 0x27, 0x7e, 0x31, 0x9a, 0xaf, 0x6e, 0x67, 0x79, 0x0e, + 0x30, 0x88, 0xd7, 0xec, 0x5e, 0xda, 0xa3, 0xb6, 0x27, 0x59, + 0xf4, 0x01, 0x41, 0xb8, 0x3f, 0xd5, 0x8f, 0x65, 0xfe, 0x2b, + 0xae, 0x08, 0x4a, 0x9b, 0x63, 0xb6, 0xa4, 0xe1, 0xd8, 0x72, + 0x5c, 0xde, 0xbb, 0x70, 0xe8, 0xf0, 0x9e, 0x7e, 0x00, 0xf0, + 0xc0, 0xf9, 0xcd, 0x47, 0x2a, 0xfa, 0xea, 0x3b, 0x91, 0x53, + 0xed, 0xfb, 0x7b, 0xaa, 0x4a, 0x92, 0xca, 0x27, 0x0b, 0xee, + 0x9c, 0xee, 0x1b, 0xb1, 0x41, 0x3f, 0x6b, 0x4e, 0x32, 0xad, + 0xa7, 0xcc, 0x19, 0x54, 0x81, 0xc3, 0x29, 0xc4, 0x92, 0xb0, + 0xa3, 0x30, 0x0e, 0x82, 0x57, 0x12, 0xb8, 0xb1, 0x6f, 0x12, + 0x2e, 0x3d, 0x5c, 0x83, 0x5f, 0x00, 0x82, 0x2e }, + { 0x40, 0xfd, 0x47, 0xe7, 0x5f, 0x95, 0x82, 0x73, 0xe6, 0xa8, + 0x3f, 0xe9, 0xdf, 0x1b, 0xba, 0x69, 0x6c, 0x18, 0xb3, 0x50, + 0x84, 0xef, 0x6b, 0x4c, 0xf1, 0xe1, 0x9f, 0xc6, 0xfd, 0xc3, + 0x7d, 0xda, 0x38, 0xdb, 0xb6, 0x3e, 0xa3, 0xd2, 0x66, 0x1c, + 0xd3, 0xaa, 0x0f, 0x7d, 0xd2, 0x22, 0x64, 0x32, 0xed, 0xde, + 0x69, 0x2a, 0x72, 0xcc, 0xd1, 0xf0, 0x92, 0xed, 0xc4, 0xb1, + 0xb6, 0xd4, 0xf6, 0x8a, 0x75, 0x3f, 0x28, 0xa0, 0x33, 0xaf, + 0x53, 0x6b, 0x8b, 0x83, 0x2d, 0x46, 0xf5, 0x98, 0x28, 0xc1, + 0xe1, 0xe9, 0xf9, 0x90, 0xca, 0x04, 0x41, 0x80, 0xa4, 0xc5, + 0x98, 0xe1, 0x09, 0xe6, 0x50, 0x33, 0x83, 0xf5, 0xef, 0x9f, + 0xff, 0xf1, 0x20, 0xa5, 0x3b, 0x11, 0xa8, 0xa5, 0xf1, 0xcd, + 0x65, 0x78, 0xe2, 0xee, 0x4a, 0xcd, 0x5e, 0xbc, 0x71, 0xe6, + 0xaa, 0x4c, 0x71, 0x02, 0x2a, 0x4a, 0x84, 0xd9 }, + { 0x5b, 0x1c, 0x11, 0x57, 0xe6, 0x39, 0x33, 0x8c, 0x0b, 0x33, + 0x4d, 0x98, 0xdf, 0xfb, 0xe2, 0x86, 0x68, 0xd8, 0x21, 0x11, + 0xd8, 0x54, 0xa6, 0x95, 0x18, 0xb9, 0xfa, 0xb3, 0xf9, 0xb6, + 0xae, 0x43, 0x1a, 0xc1, 0x6a, 0x26, 0x1f, 0x57, 0x8a, 0xa3, + 0x20, 0xcf, 0x0b, 0x97, 0xf7, 0x30, 0x08, 0x4d, 0xe5, 0x2c, + 0x01, 0x39, 0xec, 0x6c, 0x21, 0x74, 0x14, 0xd6, 0x8a, 0x08, + 0x41, 0x13, 0x42, 0x5c, 0x2d, 0x85, 0xd4, 0x52, 0x1b, 0x46, + 0x83, 0x37, 0x93, 0x38, 0x9c, 0x05, 0x41, 0x71, 0xfb, 0x69, + 0x95, 0xd5, 0xc9, 0x6e, 0xb5, 0xa2, 0x19, 0x50, 0xcf, 0xc2, + 0x21, 0x4a, 0x8a, 0xc8, 0xff, 0x88, 0x69, 0xbe, 0xeb, 0xa1, + 0x2e, 0xb6, 0xef, 0xc2, 0xdd, 0x9e, 0xc8, 0x8e, 0x69, 0x86, + 0x25, 0x48, 0x6d, 0xbb, 0xfc, 0x1e, 0xea, 0xb6, 0xf2, 0xfb, + 0x5b, 0x88, 0xb7, 0x46, 0x26, 0x71, 0x40, 0xa4 }, + { 0x96, 0x3a, 0xb8, 0x3a, 0xa7, 0x56, 0xee, 0xf4, 0x84, 0xde, + 0x9c, 0xb8, 0x33, 0xe5, 0x0a, 0xb3, 0xce, 0x16, 0x48, 0x01, + 0x6e, 0x1c, 0x63, 0x44, 0xe4, 0xd3, 0xfc, 0x44, 0xda, 0x0f, + 0xd5, 0x91, 0xb6, 0xad, 0x1c, 0xf4, 0x78, 0x5e, 0x67, 0xa3, + 0x0a, 0xc3, 0xbd, 0x66, 0xc7, 0x79, 0x1a, 0x48, 0x1f, 0x91, + 0x65, 0x1c, 0x7d, 0xa1, 0x2c, 0x10, 0x4f, 0xd1, 0xac, 0xe6, + 0x81, 0xc6, 0x5f, 0x57, 0xab, 0x18, 0xd8, 0x30, 0xea, 0x6e, + 0xdc, 0xa8, 0x28, 0x09, 0xc7, 0x64, 0xa4, 0xf3, 0x2c, 0x9d, + 0x16, 0xe7, 0x06, 0xe7, 0x05, 0x6d, 0xcf, 0x94, 0xcb, 0x2d, + 0x66, 0xa3, 0x63, 0x24, 0x20, 0xdc, 0x31, 0x6d, 0xc6, 0x5f, + 0xcb, 0x54, 0xdc, 0xe4, 0xf4, 0x2b, 0xa3, 0xc5, 0xfe, 0x69, + 0x4c, 0x73, 0x8d, 0xc6, 0x4e, 0xd2, 0x02, 0xfc, 0x92, 0xc2, + 0x90, 0xed, 0xaa, 0xb1, 0x72, 0xb6, 0xbb, 0x8f }, + { 0x44, 0x34, 0x80, 0xfc, 0xbe, 0x45, 0xc5, 0x58, 0x6b, 0x82, + 0xb8, 0x99, 0x07, 0x6b, 0x98, 0x84, 0xc8, 0x9b, 0x91, 0xfd, + 0x83, 0xc1, 0xdc, 0x07, 0x66, 0x59, 0x4a, 0xaa, 0x83, 0x73, + 0x82, 0xda, 0x01, 0x1b, 0x25, 0x21, 0xa6, 0x0c, 0xfb, 0x6a, + 0x03, 0x7d, 0x13, 0x21, 0xb9, 0x9f, 0x4e, 0x3b, 0x8e, 0x55, + 0x09, 0x69, 0x7d, 0x7d, 0x95, 0x78, 0x81, 0x89, 0xe8, 0xb0, + 0x7c, 0x20, 0xbf, 0xd8, 0x36, 0x45, 0xbc, 0xb6, 0x33, 0x19, + 0xad, 0xac, 0xfe, 0x8c, 0x39, 0x0d, 0xbb, 0xa7, 0x55, 0x70, + 0x71, 0x00, 0x6f, 0x29, 0x04, 0x05, 0x7d, 0xce, 0x3f, 0xee, + 0x20, 0x4d, 0xf5, 0x50, 0x71, 0xbc, 0x84, 0xe5, 0x5b, 0x3e, + 0xe7, 0xc9, 0x9e, 0x15, 0xd1, 0x6e, 0x7d, 0x58, 0x8a, 0x3c, + 0x35, 0x64, 0x96, 0x56, 0x88, 0x15, 0x5c, 0xfe, 0x45, 0xfe, + 0x94, 0x4b, 0x47, 0xd8, 0xdf, 0x4e, 0xa5, 0xa3 }, + { 0x97, 0x11, 0x8a, 0x88, 0xcf, 0xfa, 0xa7, 0xeb, 0xab, 0x6d, + 0x1e, 0xb0, 0xa1, 0x70, 0x03, 0x71, 0xb9, 0xd3, 0x55, 0xcf, + 0x8e, 0xb0, 0x3e, 0x6d, 0x9b, 0x6c, 0x22, 0x4b, 0xf6, 0xd7, + 0x2b, 0x58, 0xd5, 0xb1, 0x38, 0xd8, 0xc4, 0x42, 0xbe, 0x82, + 0xc2, 0xda, 0xda, 0x9e, 0x06, 0x5a, 0x8e, 0xe9, 0x38, 0x14, + 0x90, 0x71, 0xd3, 0x16, 0x05, 0xac, 0xdb, 0xef, 0x7c, 0x00, + 0xc1, 0x17, 0xa7, 0x8d, 0xa3, 0x86, 0x89, 0x17, 0xe7, 0x21, + 0xba, 0x7b, 0x24, 0x12, 0x84, 0xed, 0x24, 0x57, 0x2a, 0xc6, + 0xc2, 0xa9, 0xd0, 0xf2, 0xfb, 0x43, 0xa8, 0x6a, 0xb2, 0x29, + 0x65, 0x37, 0xfb, 0xfe, 0x9b, 0x77, 0xef, 0x3e, 0x6b, 0x31, + 0xd6, 0xf9, 0x61, 0x52, 0x42, 0xe2, 0xd0, 0xe4, 0x0f, 0xa5, + 0x47, 0x87, 0x4a, 0xec, 0x4f, 0x2e, 0x3e, 0x85, 0x7a, 0x7a, + 0xf8, 0xff, 0xff, 0xb4, 0x91, 0x14, 0x22, 0x1a }, + { 0x17, 0xc0, 0x77, 0x8d, 0x4b, 0x71, 0xfa, 0x82, 0xd5, 0x6a, + 0x17, 0x7a, 0xa5, 0x73, 0x38, 0x7c, 0x30, 0xb5, 0x40, 0x5a, + 0x27, 0x0f, 0x45, 0xf6, 0x55, 0x4f, 0xe7, 0x63, 0xfe, 0x52, + 0xea, 0xe7, 0xdb, 0xa2, 0xba, 0x26, 0x85, 0xc3, 0xfc, 0x72, + 0xe4, 0xe7, 0x62, 0x99, 0x8a, 0x02, 0x23, 0xa5, 0xa4, 0x2c, + 0x02, 0xf4, 0x10, 0x2f, 0xee, 0x2a, 0xa2, 0x73, 0x00, 0x83, + 0x3b, 0x06, 0xef, 0xa5, 0x5b, 0xa7, 0x0a, 0x49, 0x8a, 0x88, + 0x2f, 0xf2, 0xb8, 0x58, 0x63, 0x7b, 0x14, 0xb3, 0xe5, 0x01, + 0xa8, 0xb0, 0xd8, 0x20, 0x3e, 0xf2, 0xa1, 0xc4, 0x9d, 0x35, + 0x2f, 0xbb, 0x0f, 0xbf, 0xb7, 0x81, 0xe7, 0x79, 0xa3, 0xca, + 0xa0, 0x20, 0x70, 0xb4, 0x24, 0xe0, 0xdd, 0x81, 0x04, 0x77, + 0x4f, 0xbf, 0x80, 0x83, 0xc8, 0x1b, 0xa9, 0x3a, 0x68, 0x66, + 0xbf, 0x9c, 0x59, 0xa2, 0xcd, 0xec, 0xb5, 0xd8 }, + { 0x12, 0x19, 0xd5, 0xc8, 0x57, 0x1f, 0xe4, 0xc6, 0xd6, 0xce, + 0x84, 0xe1, 0xa4, 0x52, 0xed, 0x66, 0x9f, 0xfe, 0xc3, 0xa1, + 0xe2, 0xbf, 0x5d, 0x84, 0x6d, 0xd1, 0x2a, 0xe0, 0x1a, 0xd2, + 0x3a, 0x38, 0x5a, 0x8d, 0xb7, 0x9b, 0xa9, 0x6c, 0xc9, 0xa3, + 0x72, 0x3f, 0x43, 0x09, 0xa0, 0xff, 0xce, 0x0e, 0x7a, 0x0d, + 0x91, 0x57, 0x37, 0x85, 0x9a, 0x6a, 0x16, 0xe1, 0x2c, 0x45, + 0xe8, 0x6d, 0x5f, 0xd5, 0xf2, 0x24, 0x95, 0x2b, 0x18, 0x69, + 0x1c, 0x4a, 0x76, 0x8b, 0xca, 0x70, 0x05, 0x28, 0xbd, 0x40, + 0xa1, 0xa1, 0xde, 0xcd, 0x96, 0x7a, 0x2e, 0xca, 0x8c, 0x3f, + 0xa1, 0x77, 0xf5, 0xb0, 0x43, 0x77, 0x40, 0xfa, 0x45, 0x18, + 0xba, 0x09, 0xf3, 0xc4, 0xa2, 0xf5, 0xac, 0x9d, 0x9e, 0xbb, + 0xa9, 0x78, 0xc9, 0x88, 0x4e, 0x56, 0x65, 0x6e, 0xc5, 0x72, + 0x0e, 0x6d, 0xff, 0x1d, 0x27, 0x35, 0xe3, 0x7b }, + { 0x2c, 0x8d, 0x7a, 0xb2, 0xd6, 0x57, 0xf2, 0x30, 0x13, 0x14, + 0xa8, 0x2f, 0x7e, 0x62, 0x6f, 0x42, 0x70, 0xb5, 0x7e, 0x1f, + 0x0b, 0xe2, 0x9e, 0xce, 0x76, 0xf9, 0x28, 0x39, 0x3a, 0x07, + 0x93, 0xf9, 0x3c, 0x29, 0x6b, 0x0d, 0xd2, 0x34, 0xa0, 0x7a, + 0x28, 0x65, 0xdd, 0x61, 0xcb, 0xa5, 0x7c, 0xc8, 0x43, 0x08, + 0xf7, 0x62, 0xa0, 0x4e, 0x6b, 0x87, 0x21, 0x6a, 0x61, 0xd0, + 0x7f, 0xac, 0x67, 0xc6, 0x95, 0xcd, 0x99, 0x90, 0xeb, 0x24, + 0xc3, 0x88, 0x14, 0x84, 0xbd, 0xb1, 0x8b, 0xac, 0x11, 0xd6, + 0x51, 0xd3, 0xd0, 0x75, 0xa9, 0x74, 0x3e, 0x6b, 0xff, 0xff, + 0xca, 0xd8, 0xe5, 0x80, 0xbd, 0xbd, 0x0f, 0x82, 0xb0, 0xed, + 0x8d, 0x15, 0x02, 0x74, 0xe6, 0x12, 0x7e, 0x51, 0x57, 0xbb, + 0x09, 0x09, 0x3a, 0x3a, 0xb3, 0x9d, 0x2f, 0x03, 0xe7, 0x73, + 0x43, 0xea, 0xa6, 0x7f, 0x26, 0x29, 0x69, 0xeb }, + { 0x22, 0x99, 0xd2, 0x77, 0x4b, 0x09, 0xd9, 0x58, 0x96, 0xeb, + 0x70, 0x5a, 0x1b, 0x40, 0x4c, 0x44, 0x59, 0x60, 0x13, 0xdb, + 0x94, 0xa2, 0x0b, 0x11, 0xb0, 0xfd, 0x1c, 0xd5, 0xd1, 0xd3, + 0x98, 0xfb, 0xd4, 0x42, 0x8b, 0x2e, 0xed, 0x8c, 0xd5, 0x9a, + 0x74, 0x74, 0xbf, 0x0d, 0x77, 0xf8, 0x4a, 0x34, 0x6c, 0x98, + 0xd0, 0x5d, 0xc6, 0x7d, 0x6a, 0x8a, 0x69, 0xce, 0xd5, 0xaa, + 0xac, 0xa2, 0xd7, 0xef, 0xda, 0x89, 0x78, 0xbd, 0x29, 0xe3, + 0x7f, 0xeb, 0x11, 0x8a, 0xab, 0x77, 0x5a, 0x4d, 0xf3, 0x81, + 0x99, 0xda, 0xe4, 0x69, 0xd4, 0x5e, 0xbb, 0xa7, 0x8c, 0x4b, + 0x14, 0xdd, 0x9d, 0xf6, 0x43, 0x6a, 0x22, 0x9f, 0x89, 0xf5, + 0x8d, 0xd0, 0x96, 0x3f, 0x63, 0xe6, 0x65, 0xd8, 0x13, 0x10, + 0x10, 0x8d, 0xdf, 0x51, 0xea, 0xa5, 0x6e, 0xf8, 0x3b, 0x44, + 0x67, 0xcf, 0x58, 0x92, 0x08, 0x25, 0xe4, 0xd6 }, + { 0x21, 0xac, 0x67, 0x79, 0x19, 0x36, 0x61, 0x8e, 0xaf, 0x9f, + 0xfa, 0x57, 0x27, 0xb4, 0x6c, 0x26, 0x97, 0x1b, 0x73, 0x6f, + 0x52, 0xca, 0x0d, 0x50, 0x71, 0xc4, 0x41, 0x35, 0xf0, 0xb6, + 0x59, 0x34, 0xc7, 0xad, 0x1d, 0x2b, 0x82, 0x1c, 0x44, 0x6b, + 0xe8, 0xd3, 0x8b, 0x48, 0x25, 0x31, 0x7e, 0x95, 0x0c, 0xf5, + 0x62, 0x91, 0xac, 0xe0, 0x07, 0x4e, 0x69, 0x25, 0xb1, 0xb3, + 0x04, 0x2d, 0xf4, 0x8e, 0x33, 0x6f, 0xd1, 0x3d, 0x91, 0x6e, + 0xe9, 0x8b, 0xed, 0x5d, 0x51, 0x89, 0xbe, 0xc4, 0xf8, 0xa0, + 0xdc, 0x96, 0x3f, 0x2d, 0x41, 0x1d, 0xb5, 0xf6, 0xa4, 0xb2, + 0x80, 0xcd, 0xe5, 0x3c, 0x01, 0xfd, 0x40, 0x5a, 0xe2, 0x87, + 0x8f, 0xcd, 0xc6, 0x8c, 0x58, 0x66, 0xd8, 0xe1, 0x3e, 0x9f, + 0x1d, 0xb2, 0xac, 0x19, 0x8f, 0x1e, 0xbf, 0x6d, 0xd3, 0x1e, + 0x5b, 0x9c, 0xd5, 0x8d, 0xc6, 0x43, 0x97, 0xe6 }, + { 0x0e, 0x8e, 0xc1, 0xe7, 0x0e, 0x62, 0xd9, 0xd8, 0x66, 0x3d, + 0x88, 0xd6, 0x24, 0x48, 0x3a, 0x56, 0x01, 0x5f, 0x7e, 0x78, + 0x92, 0xc2, 0xe1, 0xbb, 0x30, 0x46, 0x3e, 0xe4, 0xe7, 0xf7, + 0xbe, 0x9f, 0x61, 0x22, 0x11, 0xdb, 0xee, 0x01, 0x64, 0xcd, + 0xc3, 0xf1, 0xc4, 0x31, 0xb2, 0x61, 0xca, 0x1c, 0xff, 0xa3, + 0x49, 0x6a, 0x3e, 0x60, 0x2f, 0x74, 0xfc, 0x0e, 0x1a, 0x45, + 0x61, 0x5a, 0x43, 0x89, 0x4f, 0x39, 0x89, 0x97, 0x0f, 0xf2, + 0x7b, 0x9c, 0x70, 0x97, 0x8a, 0x59, 0x03, 0x7c, 0x19, 0xb8, + 0x13, 0xd6, 0xf3, 0x75, 0xa0, 0xf2, 0x28, 0x14, 0xdf, 0xc1, + 0x9b, 0x09, 0xb3, 0x3c, 0x36, 0x25, 0x6f, 0xcd, 0x42, 0x36, + 0x38, 0x07, 0xb7, 0xd3, 0x49, 0x20, 0x33, 0xf8, 0x4d, 0xf5, + 0xd4, 0xb4, 0x12, 0x72, 0x24, 0x73, 0x97, 0xbd, 0xfc, 0x18, + 0xab, 0x42, 0x0e, 0x3f, 0x2d, 0x7f, 0xbc, 0xd2 }, + { 0x65, 0x3a, 0x79, 0x5f, 0x5d, 0x10, 0x36, 0x35, 0xd8, 0x50, + 0xc1, 0xc0, 0x1b, 0x6b, 0x73, 0xfd, 0xe2, 0xa2, 0xbd, 0x12, + 0xf4, 0xb1, 0x3e, 0x5b, 0x76, 0xaa, 0x0f, 0x56, 0x86, 0x4d, + 0x83, 0x26, 0x58, 0x19, 0x2c, 0x86, 0xa2, 0x94, 0xa3, 0x25, + 0x67, 0xb1, 0x21, 0x7e, 0xd0, 0x77, 0x36, 0x66, 0xe1, 0x84, + 0x7a, 0x4c, 0x49, 0x5d, 0x83, 0x25, 0x78, 0x30, 0xae, 0x28, + 0x9b, 0x23, 0x7e, 0x91, 0x59, 0xef, 0x6c, 0xdd, 0xe0, 0xb9, + 0x14, 0x53, 0x42, 0xee, 0x03, 0x82, 0x4c, 0x67, 0xa7, 0x71, + 0xb7, 0x4b, 0x3d, 0xe7, 0x95, 0x9c, 0x48, 0xe3, 0x30, 0x78, + 0x5b, 0xd4, 0x88, 0xd2, 0x21, 0xa1, 0x31, 0x6d, 0x02, 0x3e, + 0xdd, 0x58, 0xa3, 0x15, 0x90, 0x34, 0x48, 0x20, 0xa5, 0x17, + 0x36, 0x17, 0x99, 0xac, 0x17, 0x5d, 0x66, 0x40, 0x07, 0x1a, + 0xa8, 0x8c, 0xcc, 0x29, 0x8a, 0x08, 0x78, 0xdd }, + { 0x30, 0xdf, 0xc4, 0x7b, 0xd4, 0x44, 0x67, 0x5e, 0x08, 0x3f, + 0x65, 0xa5, 0xfb, 0x9d, 0x79, 0x76, 0x11, 0x18, 0x6d, 0x31, + 0x9a, 0x40, 0xda, 0x4b, 0xd2, 0x89, 0xeb, 0x4f, 0x27, 0xfb, + 0x0f, 0xd1, 0xf9, 0x94, 0xa1, 0x14, 0x7c, 0x6a, 0x42, 0xb1, + 0x46, 0xec, 0xbd, 0x3f, 0x1f, 0xef, 0x20, 0xe9, 0xbd, 0x75, + 0x73, 0x9c, 0xee, 0x7d, 0xaa, 0x26, 0xc9, 0x97, 0xf9, 0x3e, + 0xb2, 0x12, 0x5e, 0x8e, 0x14, 0xf9, 0x70, 0xcb, 0xdb, 0x45, + 0xd7, 0x63, 0x0b, 0x12, 0x83, 0x9a, 0xc5, 0xd1, 0xb1, 0x13, + 0xe2, 0x06, 0xb1, 0xd8, 0x1d, 0xb7, 0x25, 0xc7, 0x3a, 0xa7, + 0x04, 0xde, 0xe2, 0xb1, 0x2d, 0x52, 0xb0, 0xe5, 0x28, 0x8d, + 0x27, 0xf1, 0x31, 0xb5, 0xbc, 0xa7, 0xd7, 0xc3, 0xc9, 0x76, + 0x03, 0xd0, 0xb3, 0x5b, 0x8e, 0x5e, 0x7f, 0xa0, 0x2b, 0x60, + 0xcf, 0xe2, 0x89, 0x85, 0x50, 0xdc, 0xb1, 0x99 }, + { 0x57, 0x2a, 0x59, 0x1f, 0x54, 0xc2, 0x12, 0xcf, 0xe1, 0x6f, + 0xe8, 0x72, 0x39, 0x7f, 0x25, 0x01, 0x15, 0x35, 0xc7, 0xda, + 0xae, 0x0f, 0xe2, 0x18, 0x9a, 0xc5, 0x2a, 0x4d, 0x40, 0x7a, + 0x3a, 0xa0, 0x98, 0x3a, 0xf1, 0x75, 0x25, 0x18, 0x49, 0x39, + 0x5d, 0xa6, 0x9e, 0x0b, 0xeb, 0x1a, 0xe2, 0x89, 0x27, 0x61, + 0x92, 0xbf, 0x07, 0xd7, 0xc3, 0xc8, 0x86, 0xe1, 0x14, 0xa6, + 0x2d, 0xdf, 0x7a, 0xc6, 0x17, 0x07, 0x3c, 0xe6, 0x3e, 0x2f, + 0x69, 0x84, 0xb7, 0xbe, 0x23, 0x36, 0xc4, 0xb7, 0x8e, 0x1c, + 0xa3, 0x51, 0x4b, 0x21, 0x98, 0x83, 0x11, 0x0f, 0xb1, 0xa3, + 0xdf, 0x7a, 0x30, 0x59, 0x06, 0x8e, 0xa2, 0xb9, 0xc2, 0x04, + 0x56, 0xa6, 0xa2, 0x14, 0xab, 0x07, 0x02, 0xdf, 0x8b, 0x53, + 0x35, 0x61, 0x25, 0x02, 0x7e, 0x54, 0xb4, 0xd4, 0xe8, 0x12, + 0xbc, 0xfc, 0x5a, 0xe2, 0x9e, 0xaa, 0xdf, 0xe8 }, + { 0x65, 0xc2, 0xcb, 0xe1, 0xd8, 0xc8, 0x2c, 0x3c, 0x80, 0xc8, + 0x65, 0x53, 0x24, 0x91, 0x9a, 0x4e, 0x12, 0x0c, 0x6f, 0xbc, + 0x6c, 0x8b, 0x19, 0x0e, 0x81, 0x42, 0xdb, 0x5c, 0x90, 0xaf, + 0xd0, 0x7b, 0x6e, 0x3e, 0x49, 0x9d, 0x8d, 0x15, 0x76, 0x7a, + 0x90, 0x2f, 0xe9, 0x29, 0xf9, 0x08, 0xab, 0x43, 0xa3, 0x84, + 0x67, 0xdc, 0xe5, 0x3d, 0x1a, 0xa9, 0x15, 0xbc, 0xf3, 0xc6, + 0x11, 0xcb, 0x8c, 0x31, 0xf1, 0xd3, 0x62, 0x2b, 0x67, 0xf3, + 0x3f, 0x76, 0xb7, 0x05, 0xed, 0x61, 0x3d, 0x67, 0x4f, 0xe5, + 0xbb, 0xa5, 0x97, 0xce, 0xca, 0x03, 0x06, 0xd8, 0x6d, 0x96, + 0x71, 0xc0, 0x2f, 0xed, 0x95, 0x78, 0xbd, 0x3c, 0xbf, 0x9b, + 0xf2, 0x21, 0x26, 0xd4, 0xf9, 0xce, 0xb4, 0xb2, 0x3e, 0xef, + 0xd6, 0x90, 0x3f, 0x05, 0x43, 0x18, 0x32, 0x77, 0x33, 0xbc, + 0x49, 0x66, 0x84, 0x19, 0x09, 0xa5, 0x55, 0x3a }, + { 0x83, 0x14, 0x40, 0xd5, 0x3b, 0xa7, 0x7f, 0x66, 0xd8, 0x05, + 0x50, 0x16, 0x0e, 0x78, 0x88, 0xb9, 0x25, 0x33, 0xad, 0x58, + 0xa0, 0xdc, 0xf4, 0xab, 0x43, 0x53, 0xd7, 0x2e, 0x1a, 0x09, + 0x98, 0x52, 0x46, 0xdb, 0x73, 0x8d, 0xdf, 0xae, 0x7a, 0x1a, + 0x78, 0x3e, 0xff, 0x1b, 0x94, 0xef, 0x7e, 0xd3, 0xa5, 0xc4, + 0xf1, 0xdc, 0x22, 0x9b, 0xd3, 0xde, 0x8c, 0x3c, 0xa3, 0x49, + 0x73, 0xe1, 0xd2, 0xf1, 0x5e, 0x34, 0xe3, 0x00, 0x47, 0x73, + 0x81, 0x83, 0x92, 0xea, 0x15, 0xec, 0x95, 0x01, 0x17, 0x70, + 0x82, 0x9b, 0xc6, 0xb3, 0x41, 0x3f, 0x57, 0x9e, 0xb6, 0x88, + 0x42, 0x77, 0x08, 0x45, 0x2d, 0x44, 0x79, 0xc1, 0x62, 0xe5, + 0x67, 0x9d, 0xd1, 0x58, 0x76, 0x47, 0x2c, 0xf6, 0x6b, 0xa0, + 0xee, 0xd7, 0x27, 0xdc, 0x3b, 0x0a, 0x86, 0xe8, 0x62, 0x45, + 0x68, 0x4c, 0xda, 0x20, 0xa6, 0x60, 0xbb, 0x63 }, + { 0x50, 0x4c, 0x3a, 0x8a, 0x6d, 0x5f, 0x45, 0x66, 0x4a, 0x98, + 0x5a, 0x70, 0xe1, 0x5a, 0x28, 0x15, 0x38, 0x53, 0x99, 0xcd, + 0xbc, 0xf1, 0x19, 0xca, 0x57, 0x39, 0xac, 0x8f, 0x98, 0x5f, + 0xb4, 0x6d, 0xe9, 0x56, 0x63, 0xcc, 0x1b, 0x41, 0x1e, 0x3e, + 0x3c, 0xd1, 0x7f, 0x7f, 0x82, 0x14, 0x7b, 0x71, 0x7e, 0x0c, + 0x7a, 0x3c, 0x64, 0xca, 0xdf, 0xc6, 0x04, 0x88, 0x38, 0x2f, + 0x48, 0x53, 0x6b, 0x3b, 0xc9, 0x97, 0x7d, 0xb5, 0x63, 0x8c, + 0xe1, 0x1a, 0xea, 0x3f, 0xce, 0x98, 0x3d, 0xe0, 0x78, 0xdd, + 0x73, 0x5b, 0x86, 0x0a, 0x10, 0x1e, 0x85, 0x17, 0x92, 0x9d, + 0x7f, 0x66, 0xdf, 0xd2, 0x7a, 0x66, 0xc4, 0x5c, 0x28, 0xe6, + 0x1d, 0x3e, 0x44, 0xf0, 0xe8, 0x97, 0xf3, 0xe8, 0x82, 0x0b, + 0x3c, 0x0d, 0x5d, 0x06, 0x6e, 0x29, 0xd0, 0xfa, 0x46, 0xac, + 0xf4, 0x3e, 0x2e, 0x32, 0xf6, 0x11, 0xb2, 0xda }, + { 0x49, 0x6e, 0x46, 0x99, 0xc7, 0x1d, 0x21, 0xd2, 0xc2, 0x7a, + 0xf0, 0xb1, 0x69, 0xf5, 0x6a, 0xdd, 0x38, 0xca, 0xf7, 0xd0, + 0x77, 0xfd, 0xc5, 0x20, 0xbf, 0x2e, 0xa6, 0xc9, 0xf8, 0x43, + 0x04, 0x22, 0x5e, 0xca, 0xc3, 0xe5, 0x6d, 0xe9, 0x37, 0xdc, + 0x2a, 0xe6, 0x84, 0xde, 0x55, 0x37, 0xb7, 0xda, 0x85, 0xa7, + 0xa9, 0xc3, 0xe6, 0xe2, 0x8e, 0xac, 0xbc, 0x70, 0xb3, 0xce, + 0xa6, 0x96, 0x73, 0xea, 0xb3, 0x5e, 0x56, 0x7e, 0xa6, 0xe8, + 0xa3, 0xbb, 0x4c, 0x23, 0xc6, 0xb6, 0x67, 0x0b, 0x27, 0x02, + 0xa2, 0xdc, 0x00, 0x1d, 0x7e, 0xe8, 0x1e, 0xe1, 0x6a, 0xd3, + 0x89, 0x56, 0xaa, 0xbc, 0xc6, 0x74, 0x29, 0x83, 0x24, 0x30, + 0xe5, 0xa1, 0x29, 0xed, 0x23, 0x4d, 0x24, 0x1c, 0x43, 0x7c, + 0xe2, 0x5f, 0x98, 0x5c, 0xff, 0x38, 0x50, 0x94, 0x74, 0xe3, + 0x00, 0xb5, 0x52, 0x83, 0xb8, 0xfa, 0x53, 0xc7 }, + { 0x13, 0x38, 0x91, 0x73, 0x13, 0x03, 0x7f, 0xe8, 0x4f, 0x2b, + 0x5c, 0xcf, 0xcb, 0x37, 0x44, 0xb5, 0x35, 0x4c, 0xdc, 0xdb, + 0xe5, 0xf0, 0x69, 0x52, 0xc1, 0x4b, 0x21, 0x5e, 0xb0, 0xd6, + 0x86, 0x3a, 0x8b, 0xa0, 0xd9, 0xe9, 0xae, 0xab, 0x51, 0xf9, + 0xd6, 0x7a, 0xac, 0xaf, 0x76, 0x5b, 0xa2, 0x68, 0xce, 0xb4, + 0x0e, 0xdc, 0x95, 0x11, 0x67, 0xb7, 0x97, 0xbf, 0x6a, 0x54, + 0x22, 0x03, 0xd5, 0xc4, 0x5a, 0x21, 0xec, 0xe6, 0x2c, 0xd6, + 0x40, 0xc5, 0xbd, 0x01, 0xfa, 0x86, 0xbb, 0x04, 0x79, 0x3b, + 0xc4, 0x63, 0xbd, 0xa6, 0x17, 0xc0, 0x81, 0xb8, 0x40, 0xbf, + 0xd0, 0x80, 0x81, 0xf3, 0x21, 0x6a, 0xbc, 0x85, 0x97, 0x52, + 0x36, 0x86, 0xbd, 0xcc, 0x65, 0x9b, 0xcf, 0xaf, 0x48, 0x33, + 0xe0, 0x9b, 0xc2, 0xe3, 0x76, 0x84, 0x0e, 0xb2, 0xa6, 0x14, + 0xba, 0x14, 0xfc, 0x82, 0x9f, 0xa9, 0x34, 0x67 }, + { 0x42, 0x2e, 0xb5, 0x73, 0xf3, 0x83, 0x3f, 0xbd, 0x4c, 0x81, + 0x02, 0xb4, 0x6d, 0xa1, 0xf3, 0x45, 0xd2, 0xce, 0xfa, 0x09, + 0x69, 0x5e, 0x3a, 0x02, 0x02, 0xc5, 0x10, 0x4d, 0x4d, 0xea, + 0x47, 0x96, 0x50, 0xf0, 0xc0, 0xa6, 0x04, 0x85, 0xdf, 0xf4, + 0x4b, 0xb2, 0x95, 0x2e, 0x55, 0xfb, 0xdb, 0xac, 0x9e, 0x7a, + 0x9b, 0x46, 0x3b, 0x45, 0xfe, 0xa5, 0xae, 0xc0, 0xfc, 0xb2, + 0x6b, 0xc8, 0xaa, 0x2a, 0x68, 0x07, 0x41, 0x72, 0x54, 0x33, + 0x04, 0xef, 0x0b, 0xc4, 0x93, 0xf9, 0x50, 0xa3, 0x4a, 0x7b, + 0xec, 0xc4, 0xcf, 0xb0, 0x26, 0x09, 0x90, 0xc8, 0xbb, 0x57, + 0x76, 0x2d, 0x38, 0xf3, 0x7e, 0x01, 0x81, 0xe3, 0x4e, 0xb9, + 0xc7, 0xce, 0xa9, 0x5c, 0x4b, 0xcd, 0x41, 0x9f, 0xde, 0x8e, + 0x53, 0x14, 0xfd, 0xac, 0x17, 0xbc, 0x44, 0xae, 0x2a, 0xc6, + 0xee, 0x68, 0x06, 0x40, 0x45, 0x00, 0x3c, 0xd1 }, + { 0x36, 0x85, 0x41, 0xcf, 0x2c, 0x25, 0x25, 0x82, 0xcf, 0xba, + 0x27, 0xd7, 0xa0, 0xda, 0x2d, 0xc6, 0xa9, 0xfb, 0xbb, 0x4c, + 0xb7, 0xfd, 0x2b, 0x05, 0x7d, 0x19, 0xb9, 0xc2, 0x72, 0x79, + 0x99, 0xff, 0x09, 0xfe, 0xbc, 0x9c, 0x74, 0x73, 0x12, 0xe1, + 0x40, 0xf1, 0xc7, 0xe1, 0x66, 0xa3, 0xf2, 0xbf, 0xee, 0x63, + 0xfa, 0x8b, 0x88, 0x9d, 0xf8, 0xbc, 0x26, 0xea, 0x5a, 0x54, + 0xd6, 0x60, 0x59, 0xfe, 0xf2, 0xe2, 0x0c, 0xb4, 0x5b, 0x0f, + 0xd3, 0xad, 0xc8, 0x9e, 0x89, 0x20, 0xcb, 0xa0, 0x3c, 0xdc, + 0xf2, 0xa6, 0xba, 0x41, 0xda, 0xfb, 0x73, 0x6a, 0x72, 0x53, + 0x76, 0xac, 0x54, 0xb1, 0x27, 0x23, 0xcf, 0x7c, 0x94, 0xe2, + 0x64, 0xea, 0x58, 0x03, 0x57, 0xc1, 0xe9, 0x19, 0x07, 0x28, + 0x14, 0x59, 0xb0, 0x86, 0x1f, 0x6d, 0x97, 0x14, 0xba, 0x0e, + 0xac, 0x59, 0x2e, 0xb6, 0xa6, 0xad, 0x3f, 0x47 }, + { 0x59, 0xa5, 0xbf, 0x59, 0x22, 0x26, 0x13, 0x34, 0xb8, 0x97, + 0x78, 0x80, 0x22, 0x41, 0xa5, 0x66, 0x07, 0x3b, 0xf8, 0x69, + 0xc7, 0xf9, 0x27, 0xe9, 0x09, 0xd8, 0xcf, 0x2d, 0x86, 0xa5, + 0x86, 0xf4, 0x16, 0x69, 0x78, 0x6a, 0x97, 0xe9, 0x4c, 0x11, + 0xe2, 0x64, 0xfa, 0x41, 0xb6, 0xa1, 0x3d, 0x00, 0xb0, 0x0d, + 0xbf, 0x9d, 0x2a, 0xc1, 0xaf, 0x48, 0xe6, 0x7c, 0x10, 0x2a, + 0xf5, 0x15, 0xe2, 0x3e, 0x34, 0xb4, 0x73, 0xf0, 0x65, 0x4b, + 0xe2, 0xf2, 0xd0, 0x20, 0x8a, 0x03, 0xbd, 0x07, 0xd8, 0x77, + 0xd5, 0xa6, 0xf2, 0xaf, 0xac, 0x06, 0x7f, 0xe8, 0x79, 0x75, + 0x41, 0xb6, 0x0e, 0x84, 0x2d, 0xc2, 0x69, 0xb5, 0x3c, 0x2a, + 0xaf, 0xc8, 0xdf, 0xc2, 0x4e, 0x6a, 0xe1, 0x8f, 0x08, 0x0f, + 0x79, 0x5b, 0x1b, 0x67, 0x7d, 0xe5, 0xac, 0xfa, 0x33, 0x3a, + 0x51, 0x0d, 0x3c, 0x9e, 0x22, 0x79, 0x9d, 0x37 }, + { 0x46, 0x75, 0x64, 0xc1, 0x43, 0xeb, 0x79, 0x9c, 0xf1, 0x4e, + 0xf6, 0x18, 0xd3, 0xd3, 0xe0, 0xf8, 0x04, 0xda, 0x45, 0xf8, + 0x98, 0x4c, 0xfd, 0x36, 0x8d, 0x0b, 0x5c, 0xbe, 0x4a, 0xcc, + 0x5f, 0x4d, 0x77, 0xe7, 0xe0, 0x79, 0xb1, 0x3f, 0x3b, 0xd1, + 0x36, 0xdd, 0xc2, 0x37, 0x2a, 0xaa, 0x91, 0x35, 0xaa, 0x1b, + 0x05, 0xe0, 0x39, 0x84, 0x8b, 0xc9, 0x9c, 0xaa, 0x06, 0xb7, + 0xa6, 0x15, 0x6f, 0x8a, 0x6a, 0x6a, 0x71, 0xaa, 0xda, 0xdb, + 0x47, 0xfb, 0xf9, 0x38, 0x60, 0xd0, 0x94, 0x22, 0x81, 0x00, + 0x82, 0x67, 0xfd, 0x78, 0xf8, 0xdd, 0x3c, 0x6c, 0x08, 0xbe, + 0xe9, 0xf1, 0xd9, 0x1b, 0x9a, 0xa0, 0xda, 0x93, 0xcf, 0xcc, + 0xda, 0xa7, 0xd3, 0x97, 0x07, 0x88, 0x87, 0x67, 0xa9, 0xd4, + 0x6a, 0x7f, 0x18, 0x6c, 0x1a, 0xbc, 0xeb, 0x96, 0x99, 0x72, + 0xe9, 0xd1, 0xc9, 0x1e, 0x81, 0x34, 0x71, 0x91 }, + { 0x8a, 0x0d, 0xee, 0x16, 0x4e, 0xe9, 0x84, 0xd5, 0x0d, 0x0f, + 0x7a, 0xdb, 0xed, 0x6a, 0x1e, 0x03, 0x17, 0x73, 0xf0, 0x16, + 0x7b, 0x7c, 0x50, 0xd9, 0x06, 0x8f, 0x39, 0xcb, 0x4f, 0x81, + 0xe0, 0x9e, 0xfe, 0x8d, 0x72, 0x8c, 0x7a, 0x03, 0x62, 0x18, + 0xf3, 0x16, 0x77, 0x32, 0x2f, 0x15, 0xb8, 0x50, 0x9f, 0x71, + 0xbc, 0x0c, 0xa5, 0xd2, 0xa0, 0x06, 0xa2, 0x8f, 0xe1, 0x28, + 0xc7, 0x9e, 0xdc, 0xb2, 0x8e, 0xb4, 0x8b, 0x15, 0x01, 0x1b, + 0xc6, 0xf3, 0xac, 0x92, 0xb6, 0xa2, 0xea, 0x87, 0x74, 0x86, + 0x61, 0xc5, 0x03, 0x18, 0x94, 0xd3, 0x5c, 0x61, 0xa2, 0xfe, + 0xb4, 0xaf, 0x68, 0xa2, 0xb9, 0xb0, 0x32, 0x23, 0x5f, 0xc1, + 0x43, 0xba, 0xec, 0x39, 0x90, 0x95, 0xd5, 0x75, 0x6d, 0x20, + 0xb8, 0xaa, 0x03, 0x7f, 0x33, 0xaf, 0x92, 0xdc, 0x47, 0x52, + 0x8d, 0x72, 0x59, 0x04, 0xb6, 0xff, 0xf5, 0xd7 }, + { 0x7b, 0x04, 0xb5, 0xd2, 0xee, 0x97, 0xce, 0x23, 0x2c, 0xe7, + 0xfe, 0x7d, 0xb6, 0xf6, 0xbe, 0xd2, 0x9e, 0x9d, 0xb1, 0x9f, + 0xc1, 0xf0, 0x00, 0x73, 0x77, 0x78, 0xa9, 0x66, 0x3f, 0xe0, + 0xa1, 0x7c, 0xe8, 0x9b, 0xbc, 0x1d, 0x7b, 0x62, 0x84, 0x03, + 0xf1, 0xe8, 0x0c, 0x84, 0x55, 0x4c, 0xc2, 0x77, 0xf9, 0x7c, + 0xfd, 0x0e, 0x7e, 0x20, 0xa2, 0xc3, 0x31, 0x0d, 0x91, 0xf1, + 0xe3, 0xe1, 0x81, 0x09, 0xc0, 0x36, 0x7e, 0xf8, 0xbb, 0xaa, + 0x1e, 0x8c, 0x6a, 0x8e, 0x45, 0x3e, 0xc7, 0xee, 0x80, 0x8d, + 0xdb, 0x8d, 0x1b, 0x57, 0xc9, 0x1e, 0x21, 0x5f, 0x56, 0xa7, + 0x85, 0xf9, 0x40, 0x44, 0x5e, 0x43, 0xbb, 0xb4, 0x6a, 0xa6, + 0x3f, 0x19, 0x61, 0xe2, 0x14, 0xc4, 0xc7, 0x51, 0xa4, 0x0c, + 0xce, 0x36, 0xb8, 0x08, 0x4d, 0x9f, 0xe8, 0x6c, 0x30, 0x05, + 0x50, 0x49, 0x91, 0xbf, 0x47, 0x36, 0x6e, 0x6f }, + { 0x1c, 0x6a, 0x95, 0xa4, 0xc9, 0x9b, 0xe3, 0x1c, 0x51, 0x5b, + 0x08, 0x1c, 0x9c, 0x7b, 0x27, 0x2c, 0x4f, 0x14, 0xd0, 0x32, + 0x37, 0x86, 0x97, 0x7a, 0xd8, 0x51, 0x19, 0xa0, 0xa8, 0xd8, + 0x18, 0x22, 0xe5, 0x46, 0x5a, 0x55, 0x33, 0x88, 0x63, 0x72, + 0x3a, 0xe2, 0x1b, 0x23, 0xa6, 0xdd, 0x80, 0x2f, 0xcd, 0x4d, + 0x50, 0x89, 0xc6, 0x22, 0xd6, 0xe3, 0x07, 0x29, 0x02, 0xd7, + 0x66, 0xe3, 0xad, 0xf0, 0x0a, 0xa2, 0xac, 0x6e, 0xcf, 0xa5, + 0x18, 0x57, 0x2e, 0xc6, 0xf0, 0xbb, 0xe1, 0xbb, 0xef, 0x41, + 0x60, 0x77, 0x38, 0xfb, 0xe0, 0xc1, 0x48, 0xec, 0xc7, 0x35, + 0x17, 0x31, 0xc3, 0xc3, 0xc3, 0x7c, 0x83, 0x3a, 0x10, 0x13, + 0xe9, 0x56, 0xd5, 0x1f, 0x3d, 0x56, 0x68, 0x61, 0xe7, 0x78, + 0x51, 0xe0, 0x1a, 0x73, 0x4c, 0x5e, 0x8e, 0xb8, 0x10, 0x97, + 0x5b, 0x54, 0x6b, 0xc7, 0x82, 0xc5, 0xfa, 0xf8 }, + { 0x72, 0x70, 0x8a, 0x02, 0x30, 0xa8, 0x64, 0xc9, 0xa5, 0xc0, + 0x9c, 0x84, 0x14, 0xf6, 0x87, 0x9c, 0xd4, 0xb3, 0x91, 0x9e, + 0x08, 0x18, 0xe4, 0xbe, 0x4c, 0xec, 0x87, 0x09, 0xe6, 0x56, + 0x25, 0xfb, 0x5c, 0x91, 0x22, 0x6e, 0xba, 0x9a, 0xbd, 0xa3, + 0x2a, 0x46, 0x48, 0x81, 0x34, 0xbd, 0x9a, 0xf1, 0x83, 0x6f, + 0x61, 0x64, 0x4b, 0x70, 0xab, 0x45, 0x99, 0xdd, 0x0a, 0xd6, + 0xdb, 0xbb, 0xa8, 0xfe, 0x47, 0x5a, 0x79, 0x23, 0xb7, 0x5f, + 0x3b, 0x76, 0xf4, 0xaa, 0xda, 0xb8, 0x1a, 0x1d, 0x9f, 0xb1, + 0x6f, 0x87, 0xbd, 0xf4, 0x75, 0xcb, 0xad, 0x1f, 0x92, 0xc9, + 0xc0, 0x98, 0xf0, 0x81, 0xd9, 0x27, 0xf4, 0x12, 0xab, 0x39, + 0x82, 0x48, 0x9e, 0x27, 0xae, 0xf5, 0xd2, 0xc4, 0xcc, 0xad, + 0xe8, 0x48, 0x82, 0x9c, 0x18, 0x23, 0x4d, 0x17, 0xde, 0x1c, + 0xa6, 0xb1, 0x4a, 0xd5, 0xc2, 0x82, 0x13, 0x63 }, + { 0x74, 0x91, 0xc7, 0x4c, 0x73, 0x26, 0x5d, 0x21, 0x7d, 0xb5, + 0x5c, 0x0b, 0x43, 0x69, 0x51, 0x13, 0x95, 0x25, 0xc4, 0x73, + 0x73, 0x46, 0x7e, 0x9d, 0xf1, 0x69, 0xd3, 0xcc, 0xfa, 0xe1, + 0x03, 0xf7, 0xc8, 0x65, 0xf9, 0xfb, 0x61, 0xa8, 0x5b, 0xd5, + 0x9e, 0x08, 0x18, 0x69, 0xf7, 0x09, 0x69, 0x1c, 0xcf, 0xe8, + 0xb5, 0xce, 0xbb, 0x16, 0xb5, 0x15, 0x35, 0x5e, 0xb6, 0xe2, + 0x3e, 0x5c, 0x1b, 0x2a, 0xdb, 0x62, 0xd5, 0xb0, 0xb3, 0x5c, + 0x93, 0x65, 0x2b, 0x59, 0x06, 0x49, 0xc9, 0x79, 0x3e, 0x1c, + 0x73, 0x3d, 0xa7, 0x13, 0xce, 0xc6, 0xf4, 0x32, 0xe2, 0x41, + 0x6c, 0x2a, 0xbb, 0x04, 0x3d, 0xa3, 0x82, 0x4c, 0x71, 0x46, + 0x90, 0x88, 0x08, 0x81, 0xd7, 0x0f, 0x0f, 0xee, 0x0e, 0x28, + 0x78, 0x5c, 0xa1, 0xba, 0xe0, 0x9c, 0x7f, 0x9d, 0x45, 0xba, + 0x4f, 0x33, 0xc0, 0xb1, 0xf3, 0x4a, 0x46, 0x6c }, + { 0x8b, 0xcf, 0xd3, 0xe5, 0x74, 0x17, 0x68, 0x41, 0x68, 0x29, + 0xd1, 0xc2, 0x68, 0x90, 0x6b, 0x76, 0xb7, 0x32, 0x9f, 0xab, + 0xbc, 0xe6, 0x86, 0x64, 0xcb, 0x59, 0x14, 0x93, 0xc6, 0xe8, + 0xdc, 0xbb, 0x00, 0xfd, 0x4b, 0x01, 0x0b, 0x3b, 0xa2, 0x2e, + 0xe5, 0x48, 0x7e, 0x25, 0xd3, 0xdd, 0x4a, 0xbd, 0x1f, 0xda, + 0x9f, 0x37, 0xc8, 0x5d, 0x3c, 0xb9, 0xd6, 0xc4, 0x70, 0x9f, + 0x01, 0x2a, 0xa3, 0xba, 0x69, 0xe7, 0x57, 0x84, 0xd9, 0xfc, + 0x5a, 0xdc, 0x93, 0xe2, 0x95, 0xc8, 0x59, 0x74, 0xb2, 0x01, + 0xda, 0xa7, 0xd8, 0x98, 0xe4, 0x2b, 0xcd, 0x5a, 0x2d, 0xfb, + 0x29, 0xee, 0x59, 0xef, 0x9c, 0xed, 0x31, 0x7c, 0xcf, 0x6b, + 0xae, 0xb8, 0x2c, 0x8e, 0xac, 0x86, 0xc5, 0x8c, 0xd6, 0x22, + 0x19, 0xa1, 0x1b, 0x8a, 0xc6, 0x33, 0xba, 0x4b, 0x26, 0x0b, + 0x31, 0x2e, 0xd5, 0xbf, 0x80, 0xd2, 0xb9, 0x4d }, + { 0x53, 0xca, 0xdc, 0xf7, 0xbd, 0x37, 0xab, 0x49, 0x3e, 0x18, + 0xd1, 0xe4, 0x90, 0x5a, 0x93, 0x78, 0xbd, 0x78, 0x01, 0x0e, + 0x1d, 0xb9, 0x32, 0xad, 0xf1, 0x4d, 0xda, 0x81, 0x52, 0x89, + 0x04, 0x18, 0x6f, 0x54, 0x25, 0x09, 0x05, 0x7f, 0xe9, 0x1e, + 0xd1, 0xe5, 0xf8, 0xaf, 0x67, 0x1e, 0xc3, 0x79, 0xd9, 0xe8, + 0xd2, 0x06, 0x40, 0x22, 0xa6, 0x91, 0x09, 0xd7, 0x97, 0x0b, + 0x50, 0x74, 0x62, 0x57, 0x83, 0x44, 0x6b, 0x89, 0x6a, 0xf2, + 0x0e, 0xad, 0xd5, 0x8b, 0x3d, 0xf2, 0x2f, 0x58, 0x63, 0x89, + 0x0a, 0x06, 0x96, 0x48, 0x27, 0xdf, 0xfd, 0x4f, 0x15, 0x52, + 0x7e, 0x5e, 0x1f, 0x99, 0x22, 0x27, 0x53, 0x65, 0xe0, 0xd8, + 0x77, 0x92, 0x47, 0x87, 0xb9, 0x37, 0xf7, 0xc3, 0xc0, 0x68, + 0xba, 0x16, 0x95, 0xf0, 0xb2, 0xf1, 0x11, 0x87, 0x08, 0x33, + 0x06, 0x88, 0x27, 0x34, 0xd3, 0xc8, 0xc3, 0x14 }, + { 0x90, 0x84, 0x99, 0x64, 0xbf, 0x8c, 0x62, 0xb1, 0x69, 0xbd, + 0x75, 0xe9, 0xc3, 0x2d, 0x10, 0x46, 0x75, 0x42, 0xa5, 0xae, + 0xb6, 0x9a, 0x97, 0x60, 0x10, 0x6f, 0x19, 0x0a, 0xa6, 0x50, + 0xec, 0x5c, 0x36, 0x94, 0x14, 0x85, 0x10, 0xf2, 0x62, 0x24, + 0x3d, 0xcd, 0xb9, 0xd2, 0x1e, 0x79, 0x42, 0x9e, 0xca, 0xf6, + 0x78, 0x4b, 0x49, 0x1f, 0x2b, 0xed, 0x01, 0x8b, 0x4e, 0xab, + 0x9e, 0x42, 0x87, 0x9c, 0x61, 0x75, 0x2e, 0x59, 0xda, 0x55, + 0xdd, 0x53, 0x4e, 0x10, 0x64, 0x82, 0x23, 0x96, 0x24, 0xd1, + 0x8c, 0x1e, 0x58, 0x67, 0x7d, 0xc9, 0xe5, 0x95, 0xab, 0xa6, + 0x79, 0x4b, 0xb1, 0x73, 0xb3, 0x17, 0xb3, 0x01, 0x83, 0x45, + 0xe2, 0x2b, 0x6a, 0x33, 0x64, 0x91, 0xb0, 0xf8, 0x12, 0x20, + 0x6d, 0x15, 0xd8, 0x86, 0x60, 0x6c, 0x88, 0x8a, 0xbf, 0x67, + 0x1b, 0xb5, 0xed, 0xf7, 0x5e, 0x53, 0xd0, 0xff }, + { 0x3d, 0x7f, 0x6f, 0xfa, 0x46, 0x8c, 0xd7, 0xe8, 0xc2, 0xb7, + 0x5b, 0xe4, 0x73, 0x58, 0x0d, 0x22, 0xd4, 0xed, 0xbd, 0x5e, + 0x08, 0xdc, 0x4c, 0xc0, 0xcd, 0xee, 0x18, 0xf0, 0xe9, 0x3c, + 0x92, 0x68, 0x3e, 0x19, 0x49, 0xab, 0xf6, 0xb7, 0xde, 0x33, + 0xf6, 0x86, 0x22, 0x09, 0xc4, 0x21, 0xfb, 0x7a, 0xbd, 0x86, + 0xd2, 0xca, 0xc4, 0x10, 0x12, 0x4b, 0x49, 0xd3, 0x2d, 0x7b, + 0x87, 0x5e, 0xc5, 0x16, 0xc9, 0x21, 0xb3, 0x37, 0x60, 0x89, + 0xa4, 0xf2, 0x96, 0xfd, 0xa5, 0x0e, 0xbb, 0x5a, 0x42, 0xf8, + 0xf9, 0xb4, 0x38, 0x2d, 0x4e, 0x62, 0x42, 0x3e, 0x6e, 0x67, + 0xfe, 0xbd, 0x7c, 0x71, 0x48, 0x7c, 0x1b, 0x0c, 0xbb, 0x8f, + 0x67, 0x72, 0xde, 0x9a, 0x92, 0xa9, 0x3a, 0x9d, 0xa5, 0x1a, + 0x17, 0x88, 0x18, 0x48, 0x62, 0x64, 0x9d, 0xb5, 0xf0, 0x56, + 0xb1, 0x39, 0x0c, 0xf6, 0x5a, 0x93, 0xc6, 0x61 }, + { 0x8f, 0xb1, 0x2d, 0x3f, 0x6d, 0xde, 0x74, 0xe6, 0x40, 0x99, + 0x4d, 0x6f, 0xfd, 0x43, 0x4e, 0x7c, 0x3e, 0x18, 0xc4, 0xfd, + 0x22, 0x54, 0xab, 0xee, 0x30, 0x3f, 0x9e, 0xb9, 0x1d, 0x16, + 0xa5, 0x55, 0x3f, 0x06, 0x4e, 0xd4, 0x51, 0x1e, 0x60, 0x19, + 0x56, 0x75, 0x28, 0xe3, 0x9c, 0x9c, 0x60, 0x17, 0xb5, 0x41, + 0x92, 0x03, 0x94, 0x92, 0xf2, 0x3a, 0x5f, 0xc6, 0x89, 0x35, + 0x54, 0x8b, 0xa5, 0x62, 0x55, 0x77, 0x1b, 0xf5, 0x55, 0x65, + 0x16, 0x33, 0x65, 0x9a, 0x34, 0x2c, 0xd8, 0x3c, 0x21, 0xf4, + 0x56, 0x12, 0x46, 0x7f, 0x7f, 0x19, 0x5b, 0x60, 0x85, 0x19, + 0xdf, 0x2b, 0xb2, 0xae, 0x4d, 0x82, 0xbc, 0x69, 0x0a, 0xf5, + 0x42, 0xdc, 0xe6, 0x8e, 0x56, 0x68, 0x0b, 0x08, 0x90, 0xfe, + 0xed, 0xc9, 0x9d, 0x75, 0x9d, 0xa6, 0x97, 0x03, 0x38, 0xdf, + 0xea, 0x7b, 0x29, 0x0c, 0xdf, 0xfb, 0xd5, 0xd1 }, + { 0x3f, 0xcc, 0x67, 0x31, 0x75, 0xd2, 0x37, 0xb1, 0x4f, 0x93, + 0x03, 0xa2, 0x06, 0xff, 0x34, 0x53, 0xbe, 0x94, 0x6a, 0x59, + 0x19, 0xab, 0x1c, 0x97, 0xe7, 0x85, 0x8e, 0xcd, 0x37, 0x59, + 0x81, 0xec, 0x9b, 0x64, 0x3e, 0x77, 0x86, 0x7c, 0xa0, 0xe9, + 0x5f, 0x20, 0xfd, 0x2e, 0x4f, 0x47, 0x49, 0x9d, 0xaf, 0x77, + 0x1f, 0x6d, 0xfe, 0x23, 0x9f, 0x83, 0x29, 0xdd, 0x85, 0x0a, + 0x26, 0x8a, 0x5a, 0xf7, 0x87, 0x89, 0x69, 0x96, 0x29, 0x32, + 0xfb, 0x89, 0x13, 0x58, 0xf9, 0x7b, 0x4c, 0x2f, 0x13, 0x07, + 0x14, 0x68, 0x1a, 0x14, 0xf6, 0xf5, 0x80, 0xa0, 0x4a, 0x2b, + 0x69, 0x6a, 0x71, 0x6b, 0xa4, 0xdd, 0xe8, 0x9f, 0xfa, 0xd0, + 0x57, 0x8c, 0xae, 0x91, 0x4f, 0x21, 0x28, 0x23, 0x07, 0x8a, + 0xc3, 0xef, 0x45, 0x3e, 0x09, 0xf0, 0xb8, 0x7b, 0x7e, 0x4d, + 0x6c, 0x63, 0x81, 0xa2, 0x29, 0x3c, 0xb7, 0xa4 }, + { 0x64, 0x51, 0x46, 0xfd, 0xc7, 0x15, 0x1c, 0x34, 0xd4, 0x13, + 0x45, 0xdc, 0xb3, 0xfa, 0x86, 0x85, 0x75, 0xf0, 0xfb, 0xac, + 0xaf, 0x42, 0x99, 0x39, 0x24, 0xec, 0x69, 0x03, 0x7e, 0x62, + 0xa1, 0x88, 0xbe, 0xbe, 0x30, 0xcf, 0xa1, 0xf5, 0x24, 0x9c, + 0xc3, 0xa5, 0xa0, 0x5d, 0x56, 0x46, 0x12, 0xb7, 0x15, 0x44, + 0x24, 0xa3, 0x6b, 0x0f, 0x25, 0x4b, 0x60, 0xdd, 0x62, 0xcf, + 0xdf, 0x0c, 0xb3, 0xc2, 0x2a, 0x2f, 0x5d, 0x62, 0xf1, 0x0f, + 0xdb, 0xd2, 0x56, 0x08, 0x5a, 0x59, 0x5b, 0x51, 0xbc, 0x46, + 0x12, 0xf3, 0xe4, 0xc0, 0x9f, 0xb3, 0xf1, 0xdc, 0x1d, 0x4c, + 0x93, 0xf4, 0x7d, 0xeb, 0x92, 0x6b, 0xf2, 0x12, 0x08, 0x55, + 0x2c, 0x37, 0xa1, 0x22, 0x24, 0x29, 0xcb, 0xfd, 0x95, 0xa6, + 0x4a, 0xaf, 0xfa, 0xf7, 0x0e, 0x1f, 0xc1, 0x40, 0x1b, 0x90, + 0x50, 0x9d, 0xeb, 0xd5, 0xdf, 0x21, 0xf9, 0x20 }, + { 0x44, 0x8d, 0x3d, 0x72, 0xab, 0xfb, 0x9f, 0x2e, 0x2a, 0x7c, + 0xa4, 0xa9, 0x4d, 0x00, 0x5d, 0xda, 0x6d, 0xc7, 0x85, 0x05, + 0x6c, 0x05, 0x0a, 0x74, 0x92, 0xd7, 0x0a, 0x9f, 0x54, 0xba, + 0x14, 0xce, 0xca, 0xd0, 0x3b, 0xe7, 0xc0, 0x58, 0xfa, 0x80, + 0x1d, 0xc0, 0x77, 0x55, 0x29, 0xaa, 0x26, 0x5d, 0x43, 0x4d, + 0x09, 0xb9, 0x81, 0x97, 0xbe, 0x85, 0x7a, 0xf2, 0xd3, 0x5f, + 0x98, 0x58, 0xfa, 0x48, 0xf1, 0x78, 0x9c, 0x69, 0x6e, 0xd1, + 0xa9, 0xc3, 0x01, 0xbc, 0x30, 0x05, 0x7b, 0xb1, 0xd0, 0x00, + 0x6e, 0x21, 0xd5, 0x8f, 0xd3, 0x14, 0x12, 0xb8, 0x95, 0x45, + 0xa6, 0xaa, 0x51, 0xdc, 0x5a, 0x74, 0xca, 0x53, 0x19, 0x19, + 0xef, 0x3d, 0x8e, 0x00, 0x20, 0x37, 0x57, 0xac, 0x7e, 0x50, + 0xfc, 0x17, 0xbb, 0xa6, 0xf1, 0x36, 0x00, 0x63, 0x26, 0xe1, + 0xec, 0xec, 0x63, 0x3a, 0xba, 0x19, 0x24, 0xf9 }, + { 0x76, 0x88, 0x14, 0x79, 0xcb, 0x70, 0x19, 0xa5, 0x72, 0x49, + 0x71, 0x75, 0xd9, 0x2a, 0x30, 0x9f, 0x28, 0x5a, 0x33, 0xdf, + 0x99, 0x63, 0xc4, 0x59, 0x4d, 0x8c, 0x5d, 0x67, 0x25, 0x92, + 0x8c, 0x78, 0x20, 0x81, 0x78, 0xec, 0x96, 0xf2, 0xfd, 0x89, + 0x3d, 0xcd, 0x13, 0x1f, 0xb4, 0x6f, 0x7c, 0xbc, 0xb8, 0x25, + 0xb1, 0x62, 0xd0, 0xe2, 0xf3, 0x37, 0x40, 0x2e, 0xf5, 0x84, + 0xe5, 0x48, 0x44, 0xc9, 0x10, 0x8a, 0x28, 0xb8, 0xf6, 0xa4, + 0x47, 0x0a, 0x0c, 0x61, 0xec, 0x99, 0x56, 0x66, 0xef, 0xdf, + 0xd3, 0xaa, 0xc7, 0x15, 0xa5, 0x0e, 0xaa, 0x91, 0x13, 0xad, + 0xe4, 0xec, 0x5f, 0xf6, 0xe4, 0xa3, 0x95, 0x5c, 0xe4, 0x2a, + 0x3c, 0xd9, 0xf3, 0x3b, 0xb3, 0xf4, 0x56, 0x13, 0x4b, 0x07, + 0x44, 0x14, 0x86, 0x83, 0x51, 0xbc, 0xa9, 0xae, 0x81, 0x5a, + 0xdc, 0x56, 0xf1, 0x45, 0x29, 0xb3, 0x39, 0x89 }, + { 0x67, 0x0e, 0xb0, 0x1c, 0x5e, 0x5a, 0x86, 0x26, 0xf3, 0x76, + 0x00, 0xfb, 0x53, 0x2c, 0xe1, 0x80, 0x67, 0x13, 0x52, 0x60, + 0x59, 0xfa, 0xe5, 0x06, 0x50, 0xb9, 0xd0, 0x6e, 0xdd, 0xab, + 0xed, 0x19, 0xa4, 0x79, 0x24, 0x1c, 0x9f, 0xff, 0x0e, 0x3a, + 0xde, 0x25, 0x3f, 0x4c, 0x56, 0xcc, 0xe8, 0x15, 0xc3, 0x59, + 0x25, 0xd0, 0x4b, 0x18, 0x69, 0x2d, 0x17, 0x91, 0x4e, 0x1d, + 0xb0, 0xb7, 0x12, 0xa7, 0x1c, 0xff, 0x0e, 0xe7, 0xd0, 0x8a, + 0x26, 0x5d, 0x75, 0xb8, 0xd5, 0x75, 0x8b, 0xf2, 0xe1, 0xd7, + 0x4b, 0xc0, 0x62, 0x64, 0xa0, 0xb2, 0xae, 0xe5, 0xc2, 0xc5, + 0x63, 0xb4, 0x4a, 0x9e, 0xad, 0x62, 0x63, 0x60, 0x44, 0x21, + 0x2a, 0x33, 0x54, 0x15, 0xe8, 0xa2, 0x2c, 0xe0, 0x03, 0xa5, + 0xe2, 0x1a, 0x5e, 0x11, 0xb9, 0xad, 0x92, 0xbf, 0x65, 0xdb, + 0xba, 0x43, 0xa1, 0x14, 0x91, 0x76, 0x7e, 0xed }, + { 0x50, 0x48, 0x52, 0xe7, 0x63, 0x5d, 0xff, 0x27, 0xb7, 0x7f, + 0x03, 0x66, 0x00, 0x75, 0x16, 0x6a, 0x2d, 0x0f, 0x2f, 0x98, + 0x1c, 0xba, 0xae, 0x32, 0x1f, 0xa9, 0xc8, 0xf5, 0x91, 0x12, + 0xf7, 0xd6, 0x2e, 0xe9, 0xcc, 0x15, 0x4b, 0xb9, 0x0b, 0x1f, + 0x23, 0x55, 0x29, 0x32, 0x7f, 0x4b, 0x79, 0x6b, 0x7b, 0x82, + 0x12, 0x50, 0xdb, 0x23, 0x45, 0xe9, 0x80, 0x93, 0x89, 0x9e, + 0x5d, 0x64, 0xee, 0xce, 0x7d, 0x93, 0x23, 0x40, 0x97, 0x5a, + 0x46, 0xf0, 0xa6, 0x9e, 0x94, 0x30, 0xb5, 0xe4, 0xb4, 0x76, + 0xfc, 0x3b, 0x3b, 0x4e, 0x7c, 0x2d, 0x13, 0x22, 0x43, 0x52, + 0xf3, 0x8d, 0xbe, 0xac, 0x7e, 0xff, 0x69, 0xa1, 0x04, 0xf2, + 0x92, 0x24, 0xdd, 0xf1, 0x91, 0x78, 0x05, 0x41, 0x2a, 0x1a, + 0x38, 0x45, 0xcf, 0x08, 0xec, 0xc5, 0x7f, 0x24, 0x31, 0xad, + 0xdf, 0x73, 0xc0, 0xaf, 0x73, 0xcd, 0xbb, 0x43 }, + { 0x99, 0x2f, 0xe1, 0x51, 0xf7, 0xe9, 0x0c, 0xc4, 0xfb, 0x24, + 0xdc, 0x40, 0x52, 0x40, 0xf8, 0xb0, 0x50, 0xd0, 0xce, 0xe7, + 0x61, 0x8c, 0xe6, 0xc4, 0x3f, 0x4c, 0x9a, 0x19, 0xb9, 0x1e, + 0xae, 0x9c, 0x2f, 0x3a, 0x73, 0x08, 0xe9, 0xa9, 0xe1, 0x3f, + 0xd0, 0x5e, 0xf6, 0x9b, 0xe8, 0x66, 0x7d, 0x30, 0xab, 0xff, + 0xd9, 0xfc, 0xa9, 0xc7, 0xde, 0xb9, 0xa0, 0x53, 0x00, 0x02, + 0x05, 0x8b, 0x31, 0x77, 0x8a, 0x31, 0xb1, 0x2a, 0x1f, 0xab, + 0xf0, 0x27, 0x77, 0x35, 0x14, 0x0e, 0xd3, 0xc4, 0x29, 0xa0, + 0xc6, 0x6f, 0xd6, 0x17, 0x38, 0x53, 0xaf, 0x38, 0x71, 0x30, + 0x5c, 0x24, 0x2d, 0x95, 0x09, 0x08, 0xb0, 0x1b, 0x16, 0xd3, + 0xcb, 0xe8, 0xe9, 0x93, 0xad, 0x01, 0xde, 0x92, 0x84, 0xba, + 0xaa, 0xf6, 0x32, 0x6c, 0x07, 0x6a, 0xec, 0x6c, 0x90, 0x78, + 0x2f, 0x0f, 0x3c, 0xe5, 0xa2, 0xf3, 0x92, 0xfa }, + { 0x5a, 0x68, 0xbf, 0xa8, 0x4c, 0x5b, 0x71, 0xe0, 0x13, 0x4e, + 0xcf, 0x4b, 0x9c, 0x8e, 0xb9, 0xfb, 0x1d, 0xc8, 0x16, 0x8a, + 0x99, 0x2b, 0xcc, 0x2a, 0xca, 0x92, 0xe4, 0x84, 0x9b, 0x60, + 0x82, 0xa9, 0x73, 0x21, 0xbe, 0xb9, 0xa2, 0xb0, 0xab, 0xd2, + 0x6e, 0xea, 0x5e, 0x98, 0x38, 0xa5, 0xe3, 0x3d, 0x62, 0x6e, + 0xe7, 0x5f, 0xc4, 0x41, 0x32, 0x5c, 0xc4, 0x45, 0x1e, 0x9c, + 0xef, 0x10, 0x35, 0x50, 0xa9, 0xbe, 0x08, 0x0a, 0xcd, 0x50, + 0xe9, 0x6b, 0xba, 0x5b, 0xb4, 0xa8, 0x47, 0x47, 0x55, 0x73, + 0x20, 0xb8, 0x4f, 0xa8, 0x48, 0x0c, 0xb3, 0xae, 0xe3, 0x8c, + 0xb0, 0x9f, 0xdd, 0x98, 0xef, 0xec, 0x98, 0x21, 0xe1, 0xae, + 0xa3, 0x1e, 0x48, 0xc6, 0x97, 0xb4, 0x27, 0xb0, 0x44, 0xf0, + 0xa8, 0x28, 0xa4, 0xde, 0xd6, 0x9d, 0x87, 0x87, 0x2f, 0x98, + 0x44, 0x54, 0xdb, 0x31, 0x38, 0xf1, 0x97, 0xaa }, + { 0x78, 0xac, 0xfd, 0xf9, 0x9f, 0x5e, 0xf4, 0x39, 0x56, 0xce, + 0x6e, 0xf7, 0xbe, 0xf1, 0x62, 0x8f, 0xd1, 0x5c, 0x8f, 0xa0, + 0xa6, 0x33, 0x7b, 0x7c, 0x4b, 0xc2, 0x4a, 0x46, 0x08, 0x5a, + 0xd5, 0xe7, 0xeb, 0x40, 0xb0, 0x45, 0x81, 0x89, 0x7b, 0xc1, + 0xff, 0x98, 0x2e, 0x0a, 0x0d, 0x5c, 0xa5, 0x77, 0x71, 0xe0, + 0xdc, 0x98, 0x40, 0x11, 0xa3, 0x96, 0x91, 0xca, 0x1e, 0x3a, + 0xb8, 0xcb, 0xbb, 0xec, 0x6a, 0xb3, 0x63, 0xa8, 0x50, 0x9b, + 0xef, 0x61, 0x48, 0x71, 0x54, 0x8a, 0xe2, 0x41, 0x8f, 0x2e, + 0x6a, 0x22, 0xf4, 0x93, 0xf4, 0xdb, 0x3c, 0x0e, 0x2f, 0x5a, + 0x24, 0x53, 0x02, 0x6d, 0x39, 0x17, 0xed, 0x16, 0x86, 0x5b, + 0x0d, 0x3b, 0x9d, 0x04, 0x14, 0xde, 0x58, 0x85, 0x5b, 0x1c, + 0x0c, 0x26, 0xd1, 0x05, 0xff, 0xf9, 0x55, 0x02, 0xf8, 0xb0, + 0xb4, 0xff, 0x3b, 0x45, 0xff, 0x0a, 0x2b, 0xfb }, + { 0x0a, 0xd9, 0x2d, 0x73, 0xd0, 0x75, 0xa3, 0x66, 0x8c, 0xb4, + 0xb4, 0x8c, 0xb0, 0x61, 0xc9, 0x49, 0x6f, 0x10, 0xae, 0x0f, + 0x90, 0x8b, 0x4a, 0x29, 0x66, 0xbc, 0xb8, 0xf0, 0x8b, 0xaa, + 0x6e, 0xd2, 0xf2, 0x5c, 0x93, 0xf6, 0x90, 0xae, 0x48, 0x90, + 0x2d, 0xfc, 0x53, 0x32, 0x37, 0xde, 0x86, 0x1f, 0xe8, 0xda, + 0x25, 0x3c, 0xbf, 0x31, 0xbe, 0x71, 0x98, 0x62, 0xbb, 0x76, + 0xa0, 0x41, 0x23, 0x1a, 0x53, 0x81, 0x52, 0x18, 0xb8, 0x3a, + 0x58, 0xe0, 0xe2, 0x30, 0x6e, 0xa0, 0xae, 0x36, 0xb6, 0xf7, + 0xde, 0x76, 0xa1, 0x24, 0x05, 0xe9, 0xf1, 0x23, 0xcd, 0x93, + 0x39, 0x29, 0x48, 0x14, 0xcc, 0x52, 0xd2, 0xd6, 0x02, 0x67, + 0x1f, 0x4a, 0x34, 0x87, 0x39, 0xed, 0xc6, 0xb9, 0xdf, 0xa2, + 0x2e, 0x1b, 0x95, 0x42, 0x02, 0xa0, 0xc7, 0x7f, 0x61, 0xc4, + 0x45, 0xbf, 0x7f, 0x15, 0xf8, 0x52, 0x01, 0x89 }, + { 0x95, 0xbb, 0xd8, 0xa0, 0x70, 0xa6, 0xe9, 0xae, 0x8e, 0xf4, + 0xdc, 0xaf, 0x07, 0x5b, 0x3c, 0xed, 0x1a, 0x4f, 0xe9, 0x34, + 0x27, 0x9a, 0xa6, 0x6b, 0x1b, 0x78, 0xb4, 0xba, 0x0b, 0x50, + 0xa9, 0xeb, 0x5e, 0xbf, 0x80, 0xb7, 0x94, 0xb9, 0x0b, 0xcf, + 0x08, 0xfa, 0x64, 0xd3, 0x46, 0x42, 0x10, 0x97, 0xdc, 0x2a, + 0xc1, 0x7b, 0xa3, 0xd7, 0xd8, 0x8f, 0xec, 0x1c, 0xcf, 0xd1, + 0x98, 0xc3, 0x11, 0x63, 0x9a, 0xdc, 0x51, 0x51, 0xb3, 0xae, + 0xd5, 0xf6, 0x3e, 0xf2, 0xcb, 0x4d, 0x4a, 0xeb, 0x7f, 0xe8, + 0xf2, 0x2a, 0x8f, 0x4b, 0x02, 0xf4, 0x01, 0x61, 0x84, 0x7b, + 0x79, 0x95, 0x13, 0xe6, 0x81, 0xed, 0xea, 0x3b, 0xe0, 0x93, + 0xd4, 0xbe, 0x89, 0x02, 0xbe, 0x99, 0x15, 0x4b, 0x34, 0x66, + 0xc2, 0x80, 0x47, 0x78, 0xc6, 0x20, 0x80, 0xcd, 0x89, 0xab, + 0xbf, 0xb9, 0x5f, 0xed, 0xc2, 0xca, 0x54, 0x8a }, + { 0x37, 0x5a, 0x88, 0x4f, 0xc1, 0x25, 0xa9, 0x19, 0x48, 0x0d, + 0xc6, 0x6f, 0xb8, 0x86, 0x7a, 0x2a, 0xad, 0x14, 0x70, 0x59, + 0xf2, 0x0d, 0xfc, 0xf5, 0xa0, 0xa1, 0x0d, 0x6d, 0xdf, 0xb9, + 0xcf, 0x21, 0xe2, 0x9f, 0xb0, 0x60, 0x2a, 0xeb, 0xe4, 0x87, + 0xab, 0x1d, 0x86, 0xb7, 0x2a, 0x35, 0x94, 0x7f, 0x89, 0x30, + 0x53, 0xfc, 0xc0, 0x55, 0x4e, 0xc1, 0x69, 0xff, 0x35, 0xea, + 0x51, 0x4f, 0x5c, 0x04, 0xca, 0xc1, 0xe5, 0xd0, 0xbd, 0x07, + 0xd9, 0x0f, 0xfa, 0x42, 0x9c, 0x71, 0xe2, 0xf0, 0xe3, 0x89, + 0x07, 0x2b, 0xaa, 0x63, 0x5c, 0x16, 0xd3, 0x36, 0x31, 0x4e, + 0xf4, 0xe0, 0xaa, 0xde, 0x06, 0x6a, 0x2b, 0xfa, 0xaf, 0x47, + 0x8e, 0x83, 0x5c, 0x42, 0xe2, 0x47, 0xc9, 0xec, 0xfc, 0x1b, + 0xd6, 0xa7, 0x75, 0x67, 0xa8, 0x87, 0xb8, 0x23, 0xe3, 0x63, + 0x59, 0xf9, 0x24, 0x95, 0xe6, 0x14, 0xbb, 0xd0 }, + { 0x26, 0x8d, 0x81, 0x8b, 0x08, 0xcb, 0x84, 0xec, 0x66, 0xbb, + 0x09, 0x3b, 0x38, 0x41, 0x53, 0x79, 0x9f, 0xe0, 0xdd, 0xa7, + 0x19, 0x68, 0x83, 0x8a, 0x01, 0xcd, 0xcd, 0xe2, 0x4f, 0xd1, + 0x2a, 0xdb, 0xde, 0xc7, 0x5c, 0x81, 0xaf, 0xa6, 0x3c, 0x55, + 0xc7, 0x30, 0x3c, 0x80, 0x1e, 0xaa, 0x8c, 0x47, 0x26, 0xaa, + 0x69, 0xea, 0x60, 0x79, 0xc9, 0xa0, 0xfd, 0x97, 0xfb, 0xb0, + 0xb9, 0x1a, 0x67, 0x63, 0xfd, 0xf3, 0x67, 0x63, 0x54, 0x1e, + 0x06, 0x67, 0xb9, 0x3e, 0xd9, 0xc9, 0x2f, 0x1c, 0x59, 0x50, + 0x40, 0x32, 0x5f, 0x99, 0xc8, 0xd3, 0x06, 0x68, 0xba, 0xeb, + 0xc6, 0x64, 0xd1, 0x3a, 0x0d, 0x86, 0x67, 0x88, 0x64, 0xa0, + 0xe4, 0xfd, 0x73, 0xca, 0xf7, 0x70, 0x7e, 0xc0, 0x1b, 0xdb, + 0x1a, 0x54, 0x1a, 0x16, 0x1e, 0x2a, 0x87, 0x5c, 0x6d, 0xab, + 0x17, 0x8c, 0xbe, 0x2e, 0x12, 0x17, 0xf7, 0xea }, + { 0x8b, 0x02, 0x73, 0x5c, 0x05, 0x6c, 0xa4, 0x4b, 0x84, 0x19, + 0xed, 0x4b, 0x01, 0xb5, 0x3a, 0x56, 0x3e, 0xb9, 0x3b, 0x33, + 0x4f, 0x5f, 0x2b, 0xf5, 0x11, 0x71, 0xfe, 0x3c, 0x44, 0x35, + 0x51, 0x6a, 0xe2, 0x4c, 0x02, 0x8a, 0x2e, 0x7a, 0x20, 0x8e, + 0x81, 0x6b, 0x63, 0x3a, 0x0f, 0x97, 0x91, 0x89, 0x88, 0x3f, + 0xad, 0x37, 0xbd, 0x70, 0x7c, 0x2e, 0xa5, 0xe7, 0x7e, 0xed, + 0x3a, 0x7d, 0x83, 0x75, 0x86, 0xef, 0x4e, 0xdb, 0x33, 0x9e, + 0x4a, 0x78, 0x7f, 0x7d, 0x31, 0x64, 0x2b, 0x72, 0x01, 0x40, + 0xb5, 0xae, 0x04, 0xe4, 0x64, 0x38, 0xd7, 0xee, 0x37, 0xb0, + 0xcb, 0x5b, 0x9f, 0xa8, 0xe0, 0x66, 0xda, 0x40, 0x99, 0xf2, + 0xb2, 0x4e, 0xe9, 0xde, 0x24, 0x0c, 0x10, 0x13, 0xbe, 0xcc, + 0xc1, 0xab, 0x4f, 0xc3, 0x2e, 0x67, 0x47, 0x3d, 0x10, 0x3b, + 0x73, 0xda, 0xe3, 0x58, 0x41, 0x58, 0x05, 0x55 }, + { 0x40, 0x0e, 0x3a, 0xa0, 0x4b, 0x4d, 0x85, 0xfe, 0x5a, 0xb4, + 0x5c, 0x3f, 0x04, 0x36, 0x50, 0x42, 0x58, 0x22, 0xa7, 0x82, + 0xfd, 0x35, 0x40, 0xd8, 0xb3, 0x2e, 0xcf, 0x7e, 0x58, 0x77, + 0x3d, 0x4c, 0xf5, 0x71, 0xff, 0xdb, 0xc3, 0x00, 0x6c, 0x0d, + 0xd1, 0xf0, 0x02, 0x4c, 0x8a, 0x0c, 0x81, 0x82, 0x3e, 0x14, + 0x9a, 0xf9, 0x5e, 0x98, 0x97, 0x34, 0x16, 0x7d, 0x82, 0x81, + 0xd7, 0xe3, 0xad, 0x1b, 0xba, 0xe6, 0xc7, 0xfe, 0x8e, 0x1b, + 0x76, 0xc2, 0xd9, 0x55, 0x2d, 0x19, 0xaf, 0xbc, 0xe2, 0x65, + 0x97, 0xc6, 0x76, 0x8e, 0xe6, 0x49, 0x1f, 0xfe, 0x48, 0x5d, + 0x7a, 0xb4, 0x0d, 0x99, 0x5b, 0xc9, 0xec, 0x71, 0xbc, 0x5a, + 0x91, 0xbd, 0xf9, 0x2f, 0xac, 0x12, 0x0e, 0x6e, 0x2b, 0xfc, + 0x3b, 0x21, 0x1d, 0xe4, 0xc0, 0x26, 0xf3, 0xfc, 0x28, 0xc1, + 0xb8, 0x9b, 0xb4, 0x64, 0xe1, 0x01, 0x91, 0x95 }, + { 0x13, 0x1c, 0x3d, 0xa2, 0x8d, 0xa6, 0xe0, 0x39, 0x4a, 0x42, + 0xb9, 0xac, 0xf3, 0xa6, 0xa1, 0x98, 0x36, 0x2f, 0x76, 0x47, + 0xad, 0xaf, 0x1f, 0x4d, 0x09, 0xc1, 0x57, 0xd4, 0x4a, 0x13, + 0x00, 0x9b, 0xc8, 0x07, 0xc7, 0x79, 0x96, 0x71, 0x85, 0xb1, + 0x27, 0xc3, 0xe0, 0x32, 0x67, 0xcb, 0x58, 0x6f, 0x3e, 0xd3, + 0x50, 0xb9, 0xf1, 0x64, 0x51, 0xa7, 0xa3, 0xc2, 0x85, 0x06, + 0xc8, 0x9f, 0xc3, 0xf5, 0xfe, 0xd6, 0x60, 0xd5, 0x06, 0x21, + 0xa9, 0x9b, 0xff, 0x38, 0x67, 0xb8, 0xa5, 0x01, 0x22, 0x96, + 0x65, 0xb2, 0x2e, 0xc9, 0x73, 0xc2, 0x53, 0xdb, 0xda, 0x17, + 0xc4, 0x1b, 0xc5, 0x10, 0x7a, 0xb7, 0x5e, 0x13, 0xaa, 0xc3, + 0xe5, 0xe0, 0xac, 0x2e, 0x65, 0x92, 0x23, 0xb1, 0xc6, 0x0e, + 0xc7, 0x7d, 0x37, 0xa2, 0xed, 0x64, 0x24, 0x13, 0x60, 0x74, + 0x47, 0x32, 0x16, 0x49, 0x5e, 0x46, 0xe4, 0xa2 }, + { 0x71, 0xd1, 0xa4, 0x6a, 0x34, 0x54, 0x5c, 0xe9, 0xde, 0x80, + 0x98, 0xad, 0x44, 0xaa, 0x0f, 0xf0, 0xb9, 0x20, 0xaa, 0xc1, + 0xb2, 0xc1, 0x76, 0x15, 0xa7, 0xc0, 0x74, 0xf1, 0x1c, 0xb0, + 0xe8, 0xff, 0x13, 0x15, 0x14, 0xd7, 0x5d, 0x75, 0xf1, 0x54, + 0x6b, 0x79, 0xcf, 0x97, 0xc4, 0xc6, 0x90, 0xc9, 0x0f, 0xf7, + 0x83, 0x8b, 0x9d, 0xf1, 0xe7, 0xc8, 0x06, 0x0c, 0xa4, 0xdf, + 0xcb, 0x02, 0xdb, 0x90, 0x60, 0xc2, 0x61, 0xaf, 0x73, 0x0e, + 0x83, 0xfd, 0x19, 0x8c, 0x44, 0x4b, 0xf4, 0xc2, 0x08, 0x3c, + 0x99, 0xbb, 0x45, 0x04, 0xcd, 0x3b, 0x2f, 0x32, 0x3d, 0x32, + 0xd6, 0x10, 0xfd, 0xa2, 0x51, 0xb9, 0xc5, 0x8d, 0x41, 0x1a, + 0x80, 0xf5, 0xf4, 0xa2, 0x7c, 0x08, 0x99, 0xbd, 0xec, 0x03, + 0xf8, 0x12, 0xf4, 0x15, 0xb4, 0x25, 0xd0, 0x4f, 0x44, 0x36, + 0x4a, 0x78, 0x5f, 0xf1, 0xa7, 0xda, 0x83, 0xba }, + { 0x6c, 0xd2, 0x69, 0x9f, 0x11, 0x67, 0xf5, 0x21, 0xb9, 0x5c, + 0xc4, 0x16, 0x53, 0x3d, 0x0a, 0xcb, 0x39, 0x64, 0xff, 0x3a, + 0x24, 0xc5, 0x2d, 0x4b, 0x3e, 0x90, 0xd7, 0x16, 0x36, 0x48, + 0xfa, 0xb9, 0x00, 0x8e, 0xab, 0xdf, 0x32, 0x5f, 0xc1, 0x3a, + 0xd8, 0xcc, 0xf9, 0x0c, 0x17, 0xd3, 0xb6, 0xd5, 0x82, 0x4f, + 0xda, 0xdd, 0x5e, 0x4d, 0x60, 0xf6, 0x0f, 0x47, 0xb3, 0xa8, + 0x4f, 0x78, 0x54, 0x0b, 0xc3, 0xb4, 0x4a, 0x85, 0x60, 0xa4, + 0x56, 0x41, 0x1f, 0x65, 0xda, 0xfd, 0x6e, 0x65, 0xe3, 0xd7, + 0xf6, 0x37, 0xa5, 0x88, 0x79, 0x3c, 0xec, 0xcf, 0xc5, 0x41, + 0x0d, 0xb6, 0xca, 0x3b, 0xed, 0x06, 0x27, 0xd3, 0x8b, 0xa4, + 0x8d, 0x72, 0x62, 0x2c, 0xaa, 0x5a, 0xab, 0x2a, 0xc5, 0xd4, + 0xd1, 0x30, 0xa0, 0xd8, 0xec, 0xc3, 0x77, 0x2d, 0xda, 0x0d, + 0x76, 0x17, 0x8f, 0x76, 0xfa, 0x1b, 0x38, 0x2e }, + { 0x32, 0x7c, 0x06, 0x3f, 0xda, 0x34, 0x5d, 0xc2, 0x19, 0xee, + 0xe2, 0x74, 0xc7, 0xee, 0xb8, 0x26, 0xfa, 0x2e, 0xfc, 0xb8, + 0x6c, 0x88, 0xc9, 0x65, 0xe8, 0xf0, 0x37, 0x42, 0x30, 0xab, + 0x19, 0x6f, 0x93, 0x38, 0xc3, 0x4d, 0xf2, 0x73, 0x55, 0x69, + 0x4b, 0x4b, 0x19, 0xa6, 0xc6, 0x1a, 0x04, 0xbc, 0x0d, 0xe4, + 0x17, 0xeb, 0xe2, 0xba, 0xc3, 0x9b, 0xd3, 0x0f, 0xe4, 0x0b, + 0xa5, 0x8a, 0xcb, 0xb4, 0x7b, 0xbd, 0xc7, 0x49, 0x16, 0xab, + 0x7b, 0x5e, 0xe1, 0x5f, 0x28, 0x2c, 0x08, 0x7a, 0xda, 0xdd, + 0x89, 0x27, 0x95, 0xa7, 0x58, 0x57, 0x42, 0xf2, 0xeb, 0x70, + 0x93, 0xd0, 0xcd, 0x8f, 0x14, 0x42, 0x22, 0xdd, 0x68, 0x93, + 0x7c, 0x5a, 0x8c, 0x82, 0x54, 0x00, 0x34, 0xf8, 0x30, 0xf3, + 0x73, 0x26, 0xb0, 0x3d, 0xcf, 0xe2, 0x99, 0xd1, 0xbd, 0xfb, + 0x2d, 0x8c, 0x0b, 0x3b, 0x12, 0xf4, 0xf3, 0xac }, + { 0x02, 0x0f, 0x19, 0xd1, 0xc0, 0xdf, 0x68, 0x56, 0xeb, 0x6b, + 0x9d, 0x2a, 0x36, 0x70, 0x11, 0x2c, 0x9a, 0xfb, 0xa8, 0x22, + 0x48, 0xb0, 0x1a, 0xf2, 0x7a, 0x42, 0xa9, 0x4b, 0xda, 0x5f, + 0xa5, 0xbf, 0x1a, 0xf4, 0xc4, 0x96, 0x6c, 0x27, 0xb8, 0x3b, + 0x72, 0xaa, 0x22, 0xb2, 0xee, 0xcb, 0x4f, 0x87, 0x06, 0x23, + 0xa1, 0xfe, 0x39, 0xf3, 0xcd, 0x22, 0x1b, 0xe4, 0xe0, 0x59, + 0x93, 0xb4, 0x87, 0x80, 0x37, 0x04, 0x00, 0xf2, 0x13, 0x0b, + 0xfb, 0x7c, 0xd1, 0x59, 0x50, 0x9e, 0xda, 0x81, 0x33, 0x36, + 0xe5, 0x8d, 0xfc, 0xc8, 0x36, 0x6d, 0x6a, 0x5f, 0xc4, 0x21, + 0x6b, 0x79, 0x02, 0x2d, 0xe2, 0x71, 0xc3, 0xe7, 0xc2, 0xaa, + 0xb1, 0xc2, 0x5a, 0x16, 0xe6, 0x4e, 0xcc, 0x7b, 0x14, 0x02, + 0xa8, 0x66, 0xbb, 0xe9, 0x86, 0x9d, 0x19, 0x43, 0xae, 0xfe, + 0xab, 0x39, 0x9e, 0xff, 0x5b, 0x47, 0xcd, 0x53 }, + { 0x79, 0xe7, 0x27, 0x20, 0xb0, 0x05, 0x05, 0x44, 0xf7, 0x57, + 0xe1, 0xff, 0x0c, 0x88, 0x8f, 0x60, 0x99, 0xd0, 0x90, 0xeb, + 0xac, 0xca, 0x11, 0x60, 0x54, 0xb0, 0x09, 0x2a, 0xf1, 0x8a, + 0x07, 0x70, 0x26, 0x27, 0x43, 0x86, 0x8b, 0x4f, 0x6b, 0xba, + 0x47, 0x69, 0x9e, 0xbe, 0x72, 0x0c, 0x3a, 0xdb, 0x91, 0x60, + 0x58, 0xec, 0x5b, 0x23, 0x17, 0x27, 0x5f, 0xba, 0x16, 0xd3, + 0xcc, 0xdd, 0xef, 0xce, 0x79, 0xfb, 0xbf, 0xd3, 0xa3, 0xd0, + 0x57, 0xcf, 0xe3, 0x7e, 0xe2, 0xf2, 0x4c, 0xd6, 0x11, 0x47, + 0x3b, 0x93, 0x7e, 0xe3, 0x3a, 0x48, 0x62, 0x68, 0xe9, 0xff, + 0x02, 0x3d, 0x10, 0x28, 0x5a, 0x24, 0x94, 0x40, 0x30, 0x2d, + 0xd2, 0xbc, 0xcc, 0x4d, 0x9a, 0x78, 0x0a, 0x19, 0xe6, 0x52, + 0x58, 0x40, 0xb6, 0x18, 0xeb, 0xc6, 0xdb, 0x1d, 0xe5, 0xc5, + 0x37, 0x05, 0x1a, 0x86, 0xa4, 0xdb, 0xba, 0x20 }, + { 0x00, 0x1d, 0x3c, 0xe3, 0x70, 0x15, 0x84, 0x6d, 0xe4, 0x28, + 0xb2, 0xb5, 0x95, 0x11, 0xa0, 0x56, 0xa4, 0x48, 0x79, 0x27, + 0x38, 0xa1, 0x93, 0x9d, 0x37, 0xaf, 0x7f, 0x83, 0xfb, 0xd1, + 0x5e, 0x05, 0xe9, 0xb5, 0xbb, 0x45, 0x2a, 0x9f, 0x55, 0x8c, + 0x58, 0xda, 0xa7, 0x3a, 0xa1, 0x26, 0x85, 0x1c, 0x14, 0xa3, + 0x85, 0x4e, 0xcb, 0xc5, 0x38, 0xf9, 0x70, 0xc7, 0x9c, 0x56, + 0x66, 0xcd, 0xbd, 0x8d, 0xe9, 0x61, 0xaf, 0x3e, 0x77, 0x43, + 0xa9, 0x85, 0xf2, 0x52, 0xca, 0x0c, 0x78, 0x93, 0x75, 0xa1, + 0x9f, 0x29, 0xd9, 0x7b, 0xde, 0x16, 0x67, 0x6f, 0x54, 0x84, + 0x55, 0xa0, 0xb9, 0x80, 0x44, 0x6d, 0xd2, 0x45, 0x3c, 0x39, + 0x5a, 0x3e, 0xe7, 0xaa, 0xd6, 0x1f, 0xd6, 0xba, 0x48, 0xc0, + 0xa1, 0xdf, 0xb1, 0xa3, 0x97, 0x4e, 0xaa, 0xe6, 0xb3, 0x10, + 0x63, 0x2a, 0xcf, 0x25, 0x28, 0x20, 0xa2, 0x39 }, + { 0x4b, 0xb8, 0xc6, 0xfc, 0x40, 0xaf, 0xc6, 0x84, 0xb3, 0x28, + 0x03, 0x60, 0x79, 0x0b, 0x7a, 0x04, 0x05, 0x75, 0x90, 0x47, + 0xfc, 0x58, 0x5e, 0x46, 0x07, 0x1b, 0xd5, 0xfc, 0x11, 0xd4, + 0x01, 0x94, 0x34, 0xcc, 0x13, 0x4a, 0xfc, 0xd2, 0xc4, 0x04, + 0xe7, 0x36, 0x94, 0xbc, 0xf3, 0x69, 0x3a, 0x18, 0xcc, 0x12, + 0xa4, 0x9d, 0x56, 0x83, 0x3e, 0xdc, 0x65, 0xed, 0x39, 0xc7, + 0x59, 0x4d, 0x02, 0xb3, 0xb4, 0xc8, 0x0e, 0x2f, 0xff, 0xb8, + 0x16, 0x5d, 0x91, 0xcd, 0xd7, 0x54, 0x75, 0x0f, 0x28, 0xe4, + 0xb1, 0xa1, 0xf7, 0x0b, 0x51, 0x2f, 0x79, 0x7c, 0xa5, 0xab, + 0x62, 0xb8, 0xd9, 0x08, 0x97, 0xb1, 0x95, 0x10, 0x44, 0xe6, + 0xc3, 0x43, 0xf5, 0x39, 0x2e, 0x56, 0x2e, 0x7d, 0xe7, 0xc0, + 0xf6, 0xdb, 0xf3, 0xe3, 0x93, 0x8a, 0x00, 0x9c, 0x56, 0x64, + 0xd6, 0xbe, 0x36, 0xb9, 0xe1, 0x45, 0xb1, 0xd7 }, + { 0x36, 0x99, 0xa8, 0x81, 0xb6, 0xa7, 0x7e, 0x78, 0x2e, 0x8f, + 0xea, 0x9e, 0x9a, 0x13, 0x5d, 0x89, 0xd4, 0xf9, 0xcf, 0xa5, + 0x6c, 0x43, 0x28, 0x27, 0x99, 0xa3, 0xe8, 0x8d, 0x10, 0xff, + 0xa6, 0x90, 0xc0, 0x3f, 0x5d, 0xf9, 0x59, 0x12, 0x0b, 0xfc, + 0x56, 0x96, 0xd5, 0x45, 0x36, 0xd5, 0x05, 0x29, 0xac, 0xd1, + 0xd6, 0xf2, 0x70, 0x9d, 0xc5, 0x90, 0x86, 0x0c, 0x21, 0x8a, + 0xc8, 0x2c, 0x9c, 0x16, 0x2f, 0x12, 0x4e, 0x3b, 0x29, 0x35, + 0x19, 0xeb, 0xeb, 0x8a, 0xf4, 0x44, 0x01, 0x99, 0xb5, 0x3c, + 0x48, 0x7f, 0xe9, 0xcd, 0x9f, 0xeb, 0xc0, 0x05, 0x39, 0xe4, + 0xec, 0xf0, 0x8c, 0xb8, 0x14, 0x39, 0x37, 0xe5, 0xb6, 0xd6, + 0x60, 0x07, 0x27, 0x3b, 0xfe, 0xa3, 0x66, 0xc0, 0xa9, 0x36, + 0x9c, 0x6e, 0x69, 0x68, 0xa4, 0x0d, 0xb1, 0x33, 0xc9, 0xde, + 0x31, 0x20, 0xe2, 0xdd, 0xfd, 0x0f, 0x87, 0x96 }, + { 0x4f, 0x3a, 0x4b, 0x03, 0x20, 0x8a, 0xff, 0x8b, 0x1d, 0xf0, + 0x8e, 0x9f, 0x82, 0x53, 0x51, 0x87, 0x72, 0x71, 0xf3, 0x9e, + 0x5e, 0xc3, 0x1c, 0xaa, 0xca, 0x94, 0x75, 0xe9, 0x78, 0x1c, + 0xb4, 0x73, 0xb9, 0xe0, 0x8e, 0xc0, 0x3d, 0x7a, 0x4d, 0x52, + 0x83, 0x8d, 0xaa, 0x54, 0xd3, 0xb7, 0xc2, 0x35, 0xee, 0x2c, + 0xd2, 0x0d, 0x6a, 0x8d, 0x4f, 0x9f, 0x8c, 0x23, 0xc2, 0x5f, + 0x14, 0x26, 0xa8, 0x0d, 0x79, 0x5e, 0xc6, 0xcb, 0xc5, 0xe6, + 0x7c, 0x02, 0x94, 0xdb, 0xdf, 0xe2, 0xe9, 0xac, 0x3a, 0x75, + 0x82, 0xc5, 0x3a, 0x7e, 0x88, 0x34, 0xe9, 0xc5, 0xcb, 0xde, + 0x41, 0x6e, 0x20, 0x58, 0xb3, 0x7f, 0x06, 0xc1, 0x71, 0x51, + 0x4f, 0x7c, 0xbf, 0x4d, 0xb7, 0xe2, 0xe9, 0xb3, 0x65, 0x37, + 0x10, 0x6f, 0xe9, 0xcf, 0x3a, 0x2d, 0xf1, 0xd2, 0x81, 0x54, + 0x5b, 0xca, 0x33, 0x72, 0x1e, 0xb1, 0xc6, 0x4d }, + { 0x6d, 0x87, 0x44, 0x46, 0xa6, 0xd1, 0x79, 0xfd, 0x9e, 0x52, + 0x5c, 0x03, 0x0b, 0x5a, 0x7b, 0x80, 0x44, 0xf2, 0x4f, 0x4a, + 0x52, 0xae, 0x84, 0xdb, 0x49, 0xbe, 0x1c, 0x18, 0x7a, 0x02, + 0x32, 0x5e, 0x13, 0x15, 0x2b, 0x3e, 0xb0, 0x20, 0x60, 0x7a, + 0x56, 0xd7, 0x14, 0xab, 0xd1, 0x04, 0x9d, 0xf4, 0xc4, 0x3d, + 0x54, 0xfa, 0x5a, 0xc4, 0x88, 0xaa, 0x9f, 0x53, 0x59, 0xfd, + 0xdf, 0x86, 0xe0, 0xa2, 0xf9, 0x60, 0x38, 0x68, 0x6d, 0xf2, + 0x0d, 0x7c, 0xb4, 0xec, 0xd5, 0xdb, 0xd7, 0x2b, 0x21, 0xc1, + 0x24, 0x54, 0xbb, 0x9c, 0x42, 0x1e, 0xec, 0x37, 0xb9, 0x63, + 0x4a, 0x97, 0xe3, 0xe0, 0xf1, 0x6e, 0xb1, 0x14, 0x63, 0x4e, + 0x07, 0xd8, 0xe3, 0x11, 0x8b, 0x0f, 0x98, 0x52, 0xaf, 0xb3, + 0x6d, 0x1d, 0x23, 0xe3, 0x7f, 0xa6, 0xda, 0x22, 0x6d, 0x4e, + 0x0f, 0x7b, 0x81, 0x07, 0x1e, 0xd0, 0x95, 0xf8 }, + { 0x3c, 0xf3, 0x84, 0xc9, 0xff, 0x9c, 0x56, 0x09, 0x95, 0xa4, + 0xac, 0xa9, 0x7b, 0xb7, 0x0f, 0x3d, 0x95, 0xa3, 0x97, 0x34, + 0x90, 0x4f, 0xc5, 0x31, 0x17, 0xf5, 0x14, 0xad, 0x07, 0xac, + 0x75, 0x9d, 0x0f, 0x5d, 0x79, 0x1f, 0xaf, 0x08, 0x48, 0xbc, + 0x5c, 0xaa, 0xc2, 0x70, 0x7d, 0xeb, 0x85, 0x80, 0xa0, 0xed, + 0xc4, 0xa7, 0x42, 0xc1, 0xd2, 0x13, 0xe0, 0x3f, 0x1f, 0x34, + 0xf3, 0xfd, 0x3b, 0x74, 0x6e, 0x1a, 0x0f, 0x01, 0xf5, 0x7f, + 0x7c, 0xeb, 0x27, 0xfb, 0xa8, 0x76, 0xcf, 0x28, 0xcc, 0xc2, + 0x05, 0xf6, 0xdf, 0x92, 0x31, 0xae, 0x94, 0xe4, 0x99, 0xc2, + 0xb4, 0xdc, 0xf8, 0xd4, 0x4f, 0x12, 0x4e, 0x19, 0xe0, 0xdf, + 0x88, 0xfe, 0xe9, 0x1a, 0x71, 0xa7, 0x5a, 0x6d, 0x9d, 0xc6, + 0x9e, 0xa1, 0x1f, 0xd5, 0x31, 0x6c, 0x37, 0x81, 0xcc, 0xc8, + 0xd2, 0x9d, 0x07, 0xaa, 0xbe, 0x9a, 0x42, 0xf5 }, + { 0x2b, 0x24, 0x88, 0x50, 0xee, 0x73, 0xdf, 0x26, 0x3c, 0x67, + 0xe7, 0x3c, 0x71, 0x03, 0x07, 0x70, 0x8c, 0x8c, 0x54, 0x05, + 0xd8, 0x56, 0x0a, 0x65, 0x26, 0x48, 0x28, 0xd9, 0xd4, 0x55, + 0xe8, 0x20, 0x85, 0x52, 0x5d, 0x65, 0xbe, 0x99, 0xa6, 0x08, + 0x09, 0x98, 0x06, 0xbb, 0x74, 0x7e, 0x5d, 0x2a, 0xf4, 0xd9, + 0x7a, 0xfb, 0x14, 0x83, 0x21, 0xbd, 0xf3, 0x80, 0xfc, 0xb5, + 0x05, 0xe4, 0x51, 0xe9, 0x51, 0x17, 0x4e, 0x1a, 0x57, 0x7b, + 0x24, 0xf4, 0xb6, 0xc5, 0xd9, 0x91, 0x62, 0x93, 0x62, 0xe1, + 0x1e, 0xf3, 0x39, 0xb7, 0xfe, 0x24, 0xf3, 0x9a, 0x90, 0x58, + 0x0b, 0x90, 0xce, 0x26, 0xa8, 0xe1, 0xca, 0x86, 0x02, 0xa8, + 0x79, 0xb2, 0x09, 0xf7, 0x2b, 0x4a, 0x1b, 0x8d, 0xe7, 0x2b, + 0xf7, 0xb3, 0x49, 0x72, 0x17, 0x42, 0x67, 0x6b, 0x03, 0x99, + 0x70, 0x05, 0x06, 0xba, 0xce, 0x1f, 0xc9, 0xe3 }, + { 0x93, 0x8b, 0x3b, 0xcc, 0x6a, 0x3a, 0xc2, 0x15, 0x17, 0x26, + 0x1e, 0xce, 0x74, 0x41, 0x4a, 0x1c, 0xa1, 0x08, 0xb5, 0x4d, + 0x1d, 0x46, 0x21, 0xd1, 0x52, 0x48, 0x67, 0x58, 0xe8, 0x1b, + 0x0d, 0xf0, 0xac, 0x07, 0xf2, 0xa3, 0x73, 0xce, 0x49, 0xe8, + 0xb2, 0xf9, 0xd4, 0x41, 0xc1, 0x26, 0xbc, 0xbe, 0x63, 0x48, + 0xf7, 0xf2, 0xe6, 0x6c, 0x66, 0xf6, 0x4b, 0x90, 0x36, 0x3d, + 0x74, 0xc6, 0x69, 0x75, 0x12, 0x48, 0xc5, 0x8f, 0x62, 0xd8, + 0x43, 0xb9, 0x6c, 0x56, 0xb8, 0xef, 0x81, 0x0f, 0xcc, 0x6c, + 0xdb, 0x0e, 0x58, 0x7c, 0xb5, 0xed, 0x29, 0x45, 0x07, 0x1a, + 0x02, 0x10, 0xa6, 0xb2, 0x34, 0x4a, 0x52, 0xc2, 0x07, 0xd6, + 0xa8, 0xb2, 0x3e, 0x40, 0x07, 0xa2, 0x86, 0x19, 0x1f, 0x2c, + 0xa1, 0xc7, 0x78, 0x22, 0x4c, 0x18, 0x4f, 0xb4, 0x10, 0xb2, + 0x21, 0x73, 0xcd, 0xe6, 0x85, 0x41, 0x15, 0x9f }, + { 0x6c, 0xff, 0x58, 0xa5, 0xd9, 0xe8, 0x9d, 0x6b, 0x24, 0xe8, + 0xc9, 0xed, 0x15, 0x30, 0x73, 0x41, 0x98, 0x47, 0x46, 0x07, + 0x84, 0xe8, 0x3c, 0x06, 0x8a, 0xe7, 0xe0, 0xe8, 0xf2, 0xda, + 0xce, 0x56, 0x79, 0x70, 0x17, 0x9b, 0x93, 0x74, 0x7e, 0xa5, + 0x60, 0xf7, 0xa1, 0xb5, 0xa5, 0x5b, 0x44, 0xb7, 0xae, 0x46, + 0x55, 0xe5, 0x74, 0xd6, 0xeb, 0x5f, 0xb5, 0x66, 0xb7, 0x90, + 0x92, 0x53, 0x3d, 0x97, 0x74, 0x02, 0x05, 0x76, 0x56, 0xf7, + 0x6d, 0x5f, 0x81, 0x8c, 0x2a, 0xec, 0xf5, 0x54, 0x2d, 0xf5, + 0xe6, 0x0f, 0xb6, 0x1a, 0xda, 0x0b, 0xb6, 0x4c, 0xf3, 0x04, + 0xfc, 0x58, 0x49, 0x10, 0x1b, 0x06, 0x1c, 0x3a, 0x04, 0x34, + 0xaa, 0xa6, 0x57, 0xa9, 0x97, 0x08, 0x96, 0x06, 0xdc, 0xd7, + 0x3a, 0xcb, 0x8e, 0x65, 0xfb, 0x2a, 0x80, 0xe8, 0x80, 0x36, + 0xa9, 0xe4, 0xa1, 0x6b, 0xe4, 0xde, 0xd3, 0x40 }, + { 0x5f, 0xe4, 0xac, 0x8f, 0x31, 0xb7, 0x93, 0x27, 0x5f, 0x67, + 0xf8, 0xaa, 0xeb, 0x93, 0x6a, 0xf7, 0x3c, 0x62, 0x7f, 0xc5, + 0x48, 0x63, 0xb3, 0xac, 0xc3, 0x3f, 0x83, 0xd8, 0x04, 0x6e, + 0x2e, 0x48, 0x7f, 0xa8, 0x47, 0xe6, 0x6e, 0xc1, 0x3f, 0x84, + 0x13, 0x3d, 0x54, 0x44, 0xcc, 0xc8, 0xc7, 0xdf, 0xb1, 0xd4, + 0x04, 0xdc, 0x38, 0xd3, 0x17, 0xe0, 0x0b, 0x68, 0x0b, 0x0a, + 0xff, 0x18, 0x20, 0xb8, 0xfb, 0xbb, 0x2f, 0xa6, 0xd0, 0x23, + 0x3f, 0xdc, 0x35, 0x00, 0x10, 0x13, 0x80, 0x9f, 0x50, 0xf4, + 0x05, 0x5c, 0x3b, 0x1e, 0x9b, 0x45, 0x38, 0x96, 0xd1, 0x48, + 0x46, 0x7d, 0x60, 0x7d, 0x97, 0x98, 0x25, 0x5e, 0x90, 0x7a, + 0x03, 0xe4, 0x15, 0xb7, 0xf7, 0x99, 0x8d, 0x0b, 0x09, 0xbd, + 0x88, 0x05, 0xe1, 0xd1, 0xf2, 0x25, 0x1d, 0x2f, 0xe7, 0xd6, + 0x50, 0x8c, 0x01, 0xb0, 0x03, 0xe5, 0x1f, 0x68 }, + { 0x81, 0x37, 0x71, 0x64, 0x12, 0x1c, 0x05, 0x48, 0x20, 0x93, + 0x1c, 0x89, 0xeb, 0x2a, 0xbd, 0xad, 0x86, 0xe2, 0x54, 0xc9, + 0x69, 0x77, 0xa4, 0x20, 0x29, 0x0d, 0x95, 0xf2, 0x20, 0x10, + 0xf2, 0xe7, 0x8d, 0xcc, 0x0c, 0x42, 0x49, 0xa2, 0x78, 0x64, + 0x69, 0xc9, 0xcf, 0xb0, 0xb1, 0x84, 0xce, 0xe8, 0xdd, 0x8d, + 0xec, 0x2b, 0x34, 0xe7, 0xe7, 0x12, 0x55, 0xc3, 0x85, 0x93, + 0x00, 0xbb, 0x42, 0xdc, 0xba, 0xfc, 0x1d, 0x34, 0x6b, 0x83, + 0xe9, 0x5c, 0x18, 0x63, 0x7c, 0x7c, 0x7f, 0xef, 0x96, 0xd0, + 0x06, 0x6c, 0x55, 0xfb, 0x99, 0xa4, 0x6e, 0xaf, 0x54, 0x54, + 0xa7, 0xd4, 0x69, 0x37, 0x1c, 0x95, 0xfd, 0xd1, 0x1f, 0x04, + 0x9c, 0x22, 0xbc, 0xd4, 0x7b, 0x01, 0x87, 0x26, 0x6f, 0xb0, + 0x7b, 0x4a, 0x05, 0xdb, 0x12, 0xa3, 0xad, 0x5c, 0x7e, 0xd4, + 0x58, 0x1a, 0xa4, 0xbf, 0x8b, 0x6f, 0x40, 0x1e }, + { 0x79, 0xc2, 0x80, 0xee, 0x9c, 0xd2, 0xdb, 0x98, 0xbf, 0x24, + 0x73, 0x5c, 0xd2, 0xf1, 0x46, 0xfe, 0x4d, 0x7b, 0xb3, 0x61, + 0x82, 0xe8, 0xc5, 0xba, 0x92, 0x32, 0xb3, 0x7e, 0xa6, 0x00, + 0x85, 0x15, 0x31, 0xfc, 0x58, 0x82, 0xf8, 0xf2, 0xc0, 0x75, + 0x8c, 0xcd, 0x79, 0xb0, 0x67, 0x62, 0x2c, 0x9e, 0xe0, 0xcf, + 0x16, 0xee, 0xc4, 0x7c, 0xa8, 0x96, 0xd7, 0xf6, 0x58, 0x52, + 0x7c, 0x25, 0x0c, 0x78, 0x57, 0x3e, 0xbd, 0x17, 0x51, 0xfd, + 0xff, 0x34, 0x56, 0x2a, 0xbc, 0xfa, 0x67, 0x7d, 0x0a, 0x92, + 0xba, 0xda, 0xd7, 0xb1, 0x02, 0xf7, 0x1b, 0xef, 0x3e, 0x2c, + 0xfb, 0xd9, 0xb3, 0x85, 0x38, 0x2a, 0x24, 0x2f, 0xa7, 0xf9, + 0x62, 0x74, 0x46, 0x17, 0x5f, 0x02, 0x73, 0x7d, 0x48, 0x76, + 0xee, 0xdf, 0x6e, 0x13, 0x88, 0xc2, 0x10, 0x78, 0xa7, 0xad, + 0x62, 0x66, 0xb2, 0x5e, 0x9c, 0x5a, 0x8e, 0xdf }, + { 0x75, 0x80, 0x73, 0xa4, 0xa9, 0xe3, 0xff, 0x4f, 0x9f, 0xd9, + 0xf7, 0x91, 0x52, 0xc8, 0xf4, 0x08, 0x3f, 0x9d, 0xd5, 0x78, + 0xb5, 0xbe, 0x5b, 0xe4, 0x26, 0xdb, 0xc5, 0x8e, 0x73, 0xe4, + 0x0e, 0x3b, 0xe0, 0xb0, 0x44, 0x26, 0xb5, 0x1e, 0x38, 0xbc, + 0x3e, 0x3a, 0xf3, 0xc6, 0x9c, 0x66, 0x27, 0x4b, 0x1b, 0x2b, + 0xf8, 0x9f, 0x18, 0x3e, 0xae, 0x42, 0x6c, 0x51, 0x23, 0x5c, + 0xce, 0xe6, 0xb6, 0x06, 0x57, 0x0c, 0x5b, 0xb7, 0x81, 0x6b, + 0x62, 0x30, 0x24, 0xd2, 0x8c, 0xa0, 0x6b, 0xc1, 0x4b, 0x2e, + 0x17, 0xaa, 0x5a, 0xea, 0x8e, 0x1a, 0xb8, 0x20, 0x73, 0x39, + 0xe7, 0x21, 0x67, 0x6d, 0xe2, 0x50, 0xab, 0x83, 0x89, 0x97, + 0x82, 0xc1, 0x00, 0x1c, 0xac, 0xf0, 0x64, 0xdc, 0x9f, 0xc4, + 0x88, 0x5e, 0xa8, 0xc0, 0x49, 0x16, 0xb0, 0x4a, 0xc4, 0x8e, + 0xbd, 0xcc, 0x82, 0x03, 0xf2, 0xb4, 0x81, 0x22 }, + { 0x3f, 0x3e, 0x34, 0x58, 0xfa, 0xf6, 0x6a, 0xa8, 0x93, 0x42, + 0xa7, 0xfa, 0x86, 0x61, 0xd3, 0x2d, 0xfb, 0xab, 0x9f, 0xa1, + 0x49, 0xe9, 0xe1, 0x04, 0x06, 0xe5, 0x25, 0x99, 0xb4, 0xfd, + 0x4c, 0x45, 0x2d, 0x21, 0x64, 0x76, 0x08, 0xc7, 0xf3, 0xff, + 0x3d, 0x0b, 0x10, 0xbf, 0xfd, 0x7b, 0xe6, 0xc7, 0xbd, 0xa4, + 0xc8, 0x24, 0x29, 0x7e, 0xe2, 0x03, 0x4b, 0xc0, 0xd0, 0x30, + 0xa9, 0xfd, 0x97, 0x83, 0x14, 0x64, 0x6e, 0x53, 0xcf, 0x4b, + 0x84, 0x32, 0xde, 0xf4, 0x44, 0xc1, 0x13, 0x66, 0x84, 0x3a, + 0x56, 0xd5, 0x75, 0x0c, 0x3c, 0x47, 0x4d, 0xbd, 0x2e, 0x16, + 0x6d, 0xe7, 0xc8, 0xa0, 0xe2, 0x4c, 0xc5, 0xd1, 0x8a, 0x2a, + 0x75, 0x53, 0x66, 0x07, 0xe8, 0x4b, 0xd3, 0x85, 0xac, 0x79, + 0x54, 0x13, 0xf2, 0x06, 0xbf, 0xd6, 0x13, 0xa2, 0xa1, 0xb6, + 0x7d, 0x27, 0xb0, 0x57, 0x86, 0x91, 0xca, 0x22 }, + { 0x64, 0x0d, 0x20, 0xc4, 0x34, 0xc2, 0x94, 0xef, 0x1e, 0x9e, + 0x17, 0xed, 0x6c, 0x48, 0x29, 0x5e, 0x44, 0x1e, 0xed, 0xe2, + 0x2a, 0x0e, 0x2f, 0x63, 0x56, 0xd9, 0xf8, 0x07, 0x3c, 0x83, + 0x14, 0xae, 0xe7, 0x7b, 0x2e, 0x4c, 0xc1, 0x43, 0x3d, 0x67, + 0xc8, 0xee, 0x32, 0x3e, 0x30, 0xc7, 0x8d, 0x2b, 0xd8, 0x2d, + 0x5e, 0x9f, 0x65, 0x45, 0x7d, 0x95, 0x87, 0x34, 0xed, 0xdc, + 0xfc, 0x40, 0xe8, 0x1b, 0xb7, 0x63, 0x87, 0x58, 0x35, 0x29, + 0x2c, 0x32, 0xb8, 0xfa, 0x29, 0x56, 0x19, 0x9e, 0x5f, 0x98, + 0xf9, 0x9e, 0xe9, 0xdf, 0xed, 0xe1, 0xf0, 0x9c, 0x8a, 0x69, + 0x65, 0x53, 0xfd, 0x9b, 0xb9, 0xc3, 0x42, 0x3e, 0xca, 0x49, + 0x51, 0x5a, 0x29, 0x35, 0x02, 0x76, 0xcd, 0x9c, 0x9b, 0xf4, + 0xef, 0xf5, 0xb6, 0x77, 0xd4, 0xac, 0x49, 0xdf, 0x64, 0xeb, + 0x51, 0xec, 0x35, 0xaf, 0x95, 0x15, 0x97, 0xaa }, + { 0x0f, 0x9c, 0x1c, 0xa8, 0xc0, 0xd9, 0x28, 0x16, 0xb9, 0x68, + 0x90, 0x2a, 0xc7, 0x2e, 0x05, 0xc1, 0x8e, 0xe4, 0x0d, 0x66, + 0x34, 0x9a, 0xa6, 0x39, 0xf3, 0x9e, 0x46, 0x09, 0x91, 0x2b, + 0xd1, 0x7a, 0xdf, 0xe5, 0x2b, 0x11, 0x87, 0x6c, 0x29, 0xc3, + 0x69, 0xa0, 0x74, 0xb6, 0x28, 0x57, 0x42, 0xe8, 0xb6, 0x30, + 0x2b, 0x33, 0x0f, 0x32, 0xd3, 0x67, 0x8b, 0xc4, 0x09, 0x4d, + 0x57, 0x46, 0x0e, 0x65, 0xca, 0x8e, 0x35, 0x1d, 0xfc, 0x9f, + 0x1b, 0x73, 0x4e, 0x46, 0x1a, 0xca, 0x6d, 0x4a, 0xd4, 0xc2, + 0x29, 0xb6, 0xef, 0x13, 0x30, 0x3f, 0x07, 0xa8, 0x8d, 0x9d, + 0x47, 0xdc, 0x25, 0x49, 0xfc, 0x46, 0xd8, 0x0b, 0xdc, 0xfc, + 0x1d, 0xe5, 0x0d, 0xb7, 0xb3, 0x6e, 0x74, 0x07, 0x45, 0xac, + 0xd5, 0x2a, 0x07, 0x4c, 0x35, 0x45, 0xf3, 0x15, 0x05, 0x3a, + 0x4e, 0x9a, 0x0b, 0x8e, 0x32, 0x84, 0xd5, 0x13 }, + { 0x7e, 0x31, 0xc1, 0x2f, 0x45, 0xd3, 0x6e, 0xc5, 0x34, 0xbd, + 0x9b, 0xa7, 0x09, 0x8a, 0x82, 0x40, 0x9b, 0x9a, 0xce, 0xc6, + 0xe6, 0xe6, 0xff, 0x33, 0x63, 0x94, 0x9c, 0x91, 0x3e, 0x72, + 0x63, 0xf8, 0x3d, 0xb4, 0x7f, 0x70, 0xc6, 0x5e, 0x3e, 0xaf, + 0x48, 0x59, 0x3d, 0xb8, 0xb6, 0x63, 0x0f, 0xb1, 0x83, 0x20, + 0x27, 0x89, 0xd7, 0x69, 0x4f, 0x9b, 0x58, 0xad, 0x74, 0xb0, + 0x7b, 0x29, 0x0d, 0xfd, 0x5e, 0xa6, 0x0d, 0xfa, 0x66, 0x08, + 0xb3, 0x88, 0xcf, 0x25, 0x67, 0x30, 0x0a, 0x3b, 0x13, 0x26, + 0x73, 0x13, 0x99, 0xa3, 0x0b, 0x4d, 0xca, 0x09, 0x4b, 0x63, + 0x88, 0x54, 0xd5, 0x37, 0x34, 0x51, 0x72, 0xc9, 0x18, 0xcb, + 0x65, 0xe4, 0x08, 0xf9, 0x13, 0xa3, 0x20, 0xd8, 0x97, 0xf0, + 0xc5, 0xcc, 0xb6, 0xaa, 0x53, 0x47, 0x15, 0xd3, 0x62, 0x8c, + 0x1e, 0xbb, 0xaa, 0xb3, 0x67, 0x43, 0x3d, 0xf3 }, + { 0x1a, 0x21, 0x9c, 0x45, 0x32, 0x6d, 0x53, 0x57, 0x4d, 0xe4, + 0x1a, 0x30, 0x7e, 0x23, 0xba, 0x60, 0xac, 0x19, 0x6c, 0xf5, + 0x33, 0x7c, 0xa1, 0xbb, 0xc5, 0x3b, 0x7e, 0x03, 0xfc, 0x4f, + 0xbb, 0x2e, 0x86, 0xbe, 0x92, 0xd3, 0xef, 0xc4, 0xd9, 0x3c, + 0x4f, 0x64, 0xee, 0x41, 0x0e, 0x2b, 0x37, 0x47, 0x74, 0x1f, + 0x0d, 0x73, 0x15, 0x6c, 0x4e, 0xe1, 0xfa, 0x91, 0x92, 0x5d, + 0xdc, 0xc7, 0x22, 0x23, 0x76, 0xb3, 0xbf, 0xad, 0xfc, 0x94, + 0x70, 0x76, 0x33, 0x6e, 0x30, 0x9e, 0xde, 0x13, 0xfd, 0x1b, + 0x7a, 0x46, 0x31, 0xbe, 0x79, 0x69, 0xa1, 0x0d, 0xfd, 0xd5, + 0xfc, 0x30, 0xcf, 0xfb, 0xb4, 0x06, 0x66, 0x0c, 0x8d, 0xfa, + 0x95, 0x9c, 0xb3, 0xbc, 0xb9, 0xc3, 0x00, 0x5f, 0x94, 0x43, + 0x1f, 0x97, 0x1e, 0xfa, 0xcb, 0x00, 0x24, 0xab, 0x61, 0xd8, + 0xbe, 0x28, 0x1d, 0x68, 0x0d, 0xfd, 0x2d, 0xd7 }, + { 0x17, 0xaa, 0xa9, 0x99, 0xbc, 0x90, 0x19, 0x2f, 0xe0, 0x2b, + 0xcf, 0x77, 0xb6, 0xd0, 0xbf, 0x93, 0x6a, 0xc1, 0x53, 0x7e, + 0xf8, 0x03, 0x06, 0x62, 0xf0, 0x4c, 0xe5, 0x90, 0xbe, 0xa6, + 0x94, 0x03, 0x73, 0xcd, 0x50, 0x2d, 0x43, 0x74, 0x42, 0xd1, + 0x92, 0xff, 0x23, 0x29, 0x95, 0x56, 0x6b, 0xe6, 0x42, 0x2a, + 0x33, 0x0a, 0xc4, 0xf8, 0x9c, 0xb8, 0x95, 0x3e, 0x69, 0xb2, + 0x5b, 0x53, 0xf1, 0xc3, 0x4d, 0x6c, 0x45, 0x7f, 0x69, 0xe5, + 0x7f, 0x8e, 0xfd, 0x0d, 0xe2, 0xcb, 0x2b, 0x0c, 0x81, 0x20, + 0x78, 0xe1, 0x0e, 0xc1, 0x82, 0xcc, 0x60, 0x43, 0x99, 0x7c, + 0x8e, 0x35, 0xa2, 0xfc, 0x0e, 0xdb, 0xc0, 0xce, 0xc2, 0xe2, + 0xff, 0xdc, 0x77, 0x71, 0xc2, 0x63, 0x90, 0x67, 0x3d, 0x8a, + 0x19, 0x2f, 0x2e, 0x23, 0x18, 0x06, 0x7b, 0x6c, 0x99, 0x63, + 0xfd, 0xcf, 0x7e, 0xf8, 0xaa, 0x4d, 0xb0, 0xbc }, + { 0x6b, 0x28, 0x2a, 0xf0, 0xa5, 0xf3, 0xb2, 0x4a, 0xfb, 0xd5, + 0xff, 0x8c, 0x22, 0x64, 0x74, 0xbc, 0x3b, 0x4b, 0x2d, 0x8f, + 0xbe, 0x76, 0x08, 0xef, 0xa2, 0x8f, 0xd8, 0x6b, 0xa5, 0xbf, + 0xd2, 0x67, 0x0f, 0x45, 0x6a, 0x4c, 0x0f, 0x97, 0xfa, 0x97, + 0x78, 0xbe, 0xdd, 0xe1, 0x21, 0x4f, 0x96, 0xc5, 0xe8, 0x92, + 0x5e, 0x91, 0xb4, 0x3b, 0x68, 0x13, 0x0a, 0x44, 0xa0, 0xe5, + 0x0e, 0x4a, 0x49, 0xbe, 0x94, 0xb5, 0x5c, 0x87, 0x4f, 0xf0, + 0x6b, 0x25, 0xf4, 0x00, 0xac, 0x1e, 0xdd, 0x20, 0x45, 0xc0, + 0x72, 0x17, 0xfd, 0xd9, 0xbd, 0xd6, 0x72, 0xcf, 0x23, 0xf9, + 0x9c, 0x36, 0xdd, 0x95, 0xf7, 0xa9, 0xa6, 0xff, 0x3b, 0x35, + 0xea, 0x17, 0xe2, 0x7c, 0x1a, 0x14, 0x40, 0xe5, 0x5b, 0x88, + 0x46, 0x2f, 0x83, 0x5d, 0xee, 0x43, 0x3b, 0x94, 0x68, 0x51, + 0x0d, 0x3d, 0x56, 0x43, 0x8e, 0x55, 0xdb, 0x2e }, + { 0x6d, 0x4f, 0x5d, 0x23, 0x54, 0x70, 0x6e, 0xbf, 0xb6, 0x64, + 0xf5, 0x29, 0xee, 0x8d, 0x97, 0x62, 0x13, 0xe6, 0x44, 0x27, + 0x2b, 0x41, 0x2d, 0xfb, 0x42, 0x9d, 0x16, 0x7b, 0x48, 0x02, + 0xc2, 0x45, 0x76, 0xa5, 0x45, 0xc6, 0xc2, 0xbe, 0x9f, 0x3d, + 0x80, 0xb0, 0xbd, 0x68, 0xb2, 0x30, 0x6b, 0x0e, 0xee, 0x37, + 0x8b, 0xf4, 0xa8, 0x02, 0x45, 0xde, 0x69, 0xe9, 0xbe, 0x5c, + 0x59, 0x45, 0x50, 0x88, 0x2a, 0x2b, 0x2d, 0x2d, 0x0b, 0xfd, + 0x87, 0xb1, 0x10, 0x2d, 0xdf, 0x09, 0x8f, 0xd2, 0xfb, 0x64, + 0x14, 0x5d, 0x94, 0x66, 0x95, 0xa7, 0xac, 0xb4, 0x91, 0x14, + 0x14, 0xd3, 0x08, 0x3e, 0x16, 0xc4, 0x3f, 0x94, 0x66, 0xd3, + 0x75, 0x54, 0x78, 0x33, 0x72, 0xbd, 0x6e, 0x3d, 0xeb, 0x44, + 0x68, 0x42, 0x59, 0x1c, 0x38, 0xd6, 0xa4, 0x45, 0xe2, 0x8c, + 0x78, 0xfc, 0x02, 0x5f, 0x63, 0x41, 0xa5, 0x95 }, + { 0x4a, 0xaf, 0x0b, 0x4f, 0xd6, 0x5d, 0x34, 0xad, 0x6e, 0xda, + 0x93, 0xc4, 0x40, 0xdb, 0x81, 0xb4, 0x55, 0x1f, 0xc8, 0x72, + 0xb9, 0x97, 0x7d, 0x90, 0xe7, 0x8b, 0xd7, 0xa5, 0x74, 0x07, + 0x0b, 0xb3, 0x9c, 0x2a, 0x5e, 0x92, 0x58, 0xf3, 0x75, 0x80, + 0xb2, 0x08, 0x51, 0x70, 0x01, 0x16, 0xde, 0xb6, 0xe0, 0xfe, + 0x46, 0x78, 0x24, 0xd0, 0x5f, 0x74, 0xd2, 0xf0, 0xa7, 0xdd, + 0x2f, 0x07, 0xae, 0xa3, 0xa9, 0xe3, 0xd5, 0x9f, 0x79, 0xb7, + 0x8a, 0x26, 0x72, 0xeb, 0xa5, 0x7e, 0x88, 0x18, 0x43, 0x4d, + 0x02, 0x8d, 0xca, 0x62, 0x63, 0xc9, 0x64, 0x87, 0x3e, 0x30, + 0x8e, 0x6f, 0xf3, 0x7d, 0xcb, 0xa6, 0x33, 0x5c, 0xe6, 0xce, + 0xa7, 0xac, 0x78, 0x1e, 0x0a, 0x12, 0x6d, 0x42, 0xb3, 0xb8, + 0x1e, 0x5b, 0xfd, 0xc8, 0x07, 0xe0, 0x7b, 0xb6, 0xd0, 0xbf, + 0x35, 0xc8, 0xf2, 0xb6, 0x00, 0xba, 0x9f, 0x88 }, + { 0x8b, 0x2c, 0xbd, 0x39, 0x82, 0xbc, 0x63, 0x37, 0xa1, 0xd4, + 0x16, 0x5b, 0x1c, 0x2e, 0x14, 0xd7, 0xf9, 0x9c, 0x52, 0x6b, + 0xd6, 0xeb, 0xf3, 0xa9, 0x14, 0x4d, 0xad, 0xe1, 0xa7, 0x21, + 0xec, 0xd9, 0x72, 0xae, 0xc5, 0x77, 0xb2, 0xc1, 0x1f, 0xb1, + 0x16, 0xde, 0xde, 0x4e, 0x09, 0x70, 0x18, 0xc7, 0x11, 0xa5, + 0xa8, 0x04, 0x8b, 0xe4, 0x4a, 0xa0, 0x06, 0xf9, 0x83, 0x6b, + 0x85, 0x72, 0x86, 0x36, 0x64, 0xde, 0x98, 0x9a, 0x25, 0xbc, + 0x04, 0xdb, 0xc1, 0xcd, 0xd5, 0x2f, 0xa0, 0x61, 0xdb, 0xdb, + 0x4e, 0xef, 0x38, 0x6b, 0x8b, 0xd9, 0xc4, 0x66, 0xb2, 0x49, + 0x0f, 0xc0, 0x92, 0x1d, 0x32, 0xdd, 0xd8, 0xdb, 0xfa, 0xb5, + 0x17, 0x3b, 0x86, 0x85, 0xef, 0x3c, 0xae, 0x87, 0x8f, 0xa3, + 0xec, 0x58, 0xb0, 0x9e, 0x7d, 0xad, 0xbc, 0x18, 0x1e, 0xad, + 0x9b, 0xef, 0x25, 0x06, 0x35, 0x14, 0xc7, 0xaf }, + { 0x57, 0xe2, 0x83, 0x04, 0x7d, 0xbe, 0x36, 0x70, 0x22, 0x0e, + 0xea, 0xec, 0x8f, 0xc5, 0xc8, 0x31, 0x86, 0xc2, 0x82, 0x4e, + 0x87, 0x4c, 0xcd, 0x58, 0x39, 0x9a, 0x79, 0xc8, 0xf0, 0x24, + 0x3c, 0xf5, 0x23, 0xdf, 0x80, 0xe6, 0x08, 0x6e, 0x33, 0xf6, + 0x04, 0x1e, 0xc0, 0xb5, 0x45, 0x61, 0x6b, 0xfd, 0xd1, 0x55, + 0xf5, 0x78, 0x03, 0xbf, 0x1d, 0x4c, 0xcc, 0x64, 0xee, 0xb3, + 0x35, 0xde, 0xea, 0xe7, 0x9a, 0xa3, 0xf4, 0xb3, 0xee, 0x40, + 0x5e, 0x89, 0xc7, 0x0c, 0xa9, 0x3b, 0x06, 0xba, 0x06, 0xd2, + 0xca, 0x14, 0xf1, 0xa7, 0xa3, 0x19, 0x48, 0x8a, 0xbd, 0x32, + 0x98, 0xd1, 0x48, 0x7c, 0x2a, 0x2d, 0x3f, 0xc2, 0x57, 0xb3, + 0xc5, 0x76, 0x2b, 0x9c, 0x83, 0x07, 0xd1, 0x30, 0xc6, 0x34, + 0xea, 0x45, 0x0b, 0xa2, 0x02, 0xf6, 0xcf, 0x9d, 0x42, 0xec, + 0x28, 0xec, 0x1b, 0xf2, 0x8a, 0x52, 0xe9, 0x91 }, + { 0x4f, 0x12, 0xe0, 0x37, 0x69, 0x6f, 0xfd, 0xa6, 0xe8, 0xbe, + 0xe9, 0xd4, 0xc9, 0x1d, 0x60, 0x63, 0xd0, 0xd3, 0xcb, 0x56, + 0x19, 0xd4, 0xa2, 0xd7, 0x3a, 0xc0, 0xfb, 0xd5, 0x7c, 0xba, + 0x21, 0x7d, 0xeb, 0x28, 0x9d, 0x0a, 0xa9, 0x36, 0x17, 0xb0, + 0x5e, 0xcb, 0xbc, 0x8c, 0xad, 0x54, 0xef, 0x05, 0xef, 0x96, + 0xf7, 0x31, 0x53, 0xde, 0x1b, 0x2f, 0x96, 0xb3, 0x7e, 0x87, + 0xb6, 0x05, 0x47, 0x05, 0x46, 0x98, 0x99, 0x25, 0x20, 0x30, + 0xfa, 0x5a, 0x76, 0xd4, 0xf2, 0xb7, 0x0c, 0xa3, 0x76, 0x01, + 0x65, 0xc0, 0xf4, 0x92, 0x53, 0x39, 0x8a, 0x72, 0x65, 0x5c, + 0x4b, 0x9b, 0x28, 0x42, 0x3b, 0x20, 0xd7, 0x6b, 0xf7, 0x5e, + 0x52, 0x2b, 0xc8, 0x8d, 0x40, 0x44, 0xad, 0xba, 0x80, 0x49, + 0x84, 0x36, 0xbd, 0xd0, 0x6a, 0x99, 0x8b, 0xeb, 0xb1, 0xd2, + 0x6e, 0x60, 0xb6, 0x98, 0xfb, 0xcd, 0xf6, 0x66 }, + { 0x83, 0xd2, 0x33, 0x3e, 0xb1, 0x26, 0x6f, 0x91, 0xa8, 0xf7, + 0x8e, 0xa7, 0x58, 0x58, 0xaf, 0xb2, 0x1a, 0x49, 0x6e, 0xa9, + 0x5b, 0x52, 0x1e, 0xcb, 0x73, 0xe6, 0x9c, 0x6e, 0xa9, 0x44, + 0x8b, 0x02, 0xf8, 0x88, 0xe9, 0x2c, 0xf2, 0x77, 0xba, 0xb1, + 0x45, 0xb2, 0x32, 0xb2, 0x9b, 0xd6, 0x44, 0x4a, 0x61, 0xa0, + 0x86, 0x6d, 0x32, 0x02, 0x53, 0x71, 0x9d, 0x9e, 0xd8, 0x9f, + 0xf9, 0xc1, 0xd4, 0xdd, 0x8c, 0x34, 0xd2, 0x2c, 0xb9, 0x5a, + 0xe1, 0x6a, 0x74, 0xe7, 0xce, 0xe7, 0x93, 0xc4, 0x80, 0x4e, + 0xfb, 0x6b, 0xa8, 0x8c, 0x70, 0xa8, 0xa0, 0xfa, 0x36, 0x46, + 0x4c, 0x65, 0x14, 0x6d, 0x13, 0x20, 0xfa, 0x15, 0xb4, 0x84, + 0x4b, 0x28, 0x4e, 0x2a, 0x12, 0x46, 0xa4, 0x54, 0x73, 0x83, + 0x81, 0x34, 0x80, 0x4a, 0x5c, 0x55, 0x37, 0x86, 0x51, 0x9a, + 0x4c, 0xcf, 0xa4, 0x22, 0x15, 0xf1, 0xa6, 0x10 }, + { 0x73, 0x62, 0xf1, 0x3e, 0xc5, 0xa3, 0x16, 0x21, 0x46, 0x35, + 0x32, 0x15, 0x2f, 0x40, 0xa5, 0x5b, 0x82, 0x26, 0xb6, 0xaf, + 0xb7, 0xd1, 0xe5, 0x86, 0x8e, 0xdb, 0x61, 0x22, 0xf8, 0xe8, + 0x6e, 0xf3, 0x28, 0xb2, 0x28, 0x0e, 0x3d, 0x40, 0x75, 0x4c, + 0xa0, 0x1e, 0x0f, 0x59, 0x6b, 0xf7, 0x6d, 0xad, 0x17, 0xde, + 0x4b, 0xfe, 0xd5, 0xbe, 0xe3, 0x97, 0xd6, 0xb4, 0x3e, 0xf6, + 0xf4, 0x5d, 0x9f, 0xbb, 0xb3, 0x97, 0x8d, 0xb8, 0xd8, 0x54, + 0xdf, 0xb2, 0x52, 0x8f, 0xef, 0x00, 0x93, 0xf5, 0x5f, 0x0a, + 0xe8, 0x12, 0x01, 0x19, 0x70, 0xe7, 0x3d, 0x77, 0x15, 0x9d, + 0x66, 0x60, 0xa8, 0x11, 0x7a, 0x87, 0x69, 0xf1, 0xf2, 0x88, + 0x89, 0x3c, 0xd6, 0x96, 0x05, 0xb6, 0xab, 0x30, 0x18, 0xd2, + 0x24, 0x1b, 0xa1, 0xee, 0x1a, 0xe1, 0x50, 0xa2, 0xfc, 0x9c, + 0x1c, 0x63, 0x32, 0x88, 0x67, 0xb4, 0x78, 0xd7 }, + { 0x2f, 0x10, 0x69, 0x3f, 0xa3, 0x8c, 0x0e, 0xad, 0xd9, 0xb1, + 0x6f, 0x02, 0xda, 0x0a, 0x20, 0xa8, 0xf0, 0x86, 0x1d, 0x92, + 0x90, 0x98, 0x36, 0x95, 0x1f, 0xc3, 0x9b, 0xac, 0x89, 0xf0, + 0xbf, 0x0b, 0xe7, 0xaf, 0x9c, 0xd7, 0x2f, 0x2b, 0x39, 0x9e, + 0x0e, 0xb1, 0xe7, 0x15, 0xff, 0x56, 0x8f, 0x64, 0x2c, 0x91, + 0x15, 0x4e, 0xae, 0xc8, 0x91, 0xf9, 0x63, 0xe2, 0xfd, 0xbf, + 0xb6, 0xc1, 0xa4, 0x55, 0xb6, 0x51, 0x0c, 0xd8, 0xe3, 0xa8, + 0xd0, 0xd5, 0xd9, 0x36, 0x1d, 0x68, 0x39, 0x87, 0x79, 0x5e, + 0x37, 0x6f, 0x4f, 0x58, 0xf0, 0xaa, 0x86, 0x08, 0xbb, 0xf0, + 0xa8, 0x1a, 0x4b, 0x6f, 0xbb, 0xf4, 0x18, 0x94, 0x56, 0x88, + 0x81, 0x4b, 0x49, 0x47, 0x50, 0xa5, 0xce, 0xce, 0xd2, 0x19, + 0x4f, 0x1b, 0x8c, 0xc0, 0xa6, 0x5f, 0xa5, 0x1c, 0x36, 0x57, + 0x79, 0x2e, 0xb2, 0x7c, 0x73, 0xc0, 0xc4, 0x30 }, + { 0x98, 0x5f, 0x83, 0xe4, 0x4f, 0xe7, 0xa0, 0x43, 0x27, 0x75, + 0xdb, 0xdd, 0x96, 0x43, 0x7c, 0xdb, 0x1e, 0xff, 0x68, 0xd4, + 0xad, 0x6f, 0x19, 0x40, 0x5b, 0x53, 0xd2, 0x79, 0x9d, 0xaa, + 0x9e, 0x4f, 0x25, 0x51, 0xc8, 0xe4, 0xaf, 0x39, 0x53, 0xc8, + 0x7c, 0x7a, 0xfb, 0x14, 0x08, 0xea, 0x2f, 0x6e, 0x82, 0x8c, + 0x3a, 0x05, 0xd5, 0x9c, 0xda, 0x99, 0xa6, 0x86, 0xae, 0x49, + 0x47, 0xf3, 0x82, 0x83, 0x64, 0xba, 0x66, 0xfc, 0x8f, 0xaa, + 0x62, 0x9e, 0x67, 0x59, 0xac, 0xfe, 0x10, 0xd6, 0x33, 0xac, + 0x9c, 0xbd, 0x11, 0x13, 0xdc, 0x96, 0xa2, 0x01, 0x1f, 0xb2, + 0xf8, 0x9f, 0x36, 0x9e, 0xe5, 0x48, 0x04, 0xb6, 0x18, 0x91, + 0x1e, 0xd6, 0x06, 0x26, 0xe4, 0x68, 0xbf, 0xd6, 0xa9, 0xf6, + 0x35, 0xa6, 0xf9, 0x74, 0x84, 0x2f, 0x2f, 0xd9, 0x08, 0x7b, + 0x07, 0xa6, 0xce, 0x91, 0x0c, 0x06, 0xde, 0xd2 }, + { 0x0c, 0x88, 0xe5, 0x40, 0x0f, 0xe9, 0x62, 0xf1, 0x54, 0xd7, + 0x79, 0xd5, 0x50, 0xdc, 0xc7, 0x99, 0xbb, 0xf1, 0x5a, 0x6f, + 0x1e, 0x78, 0x1c, 0xa7, 0x2d, 0x9f, 0x17, 0x9c, 0x0d, 0x8c, + 0xbc, 0x2e, 0x68, 0xfd, 0xda, 0xa9, 0x92, 0xc0, 0x03, 0xb3, + 0x07, 0x01, 0x9c, 0x93, 0x1a, 0x44, 0x3c, 0xfa, 0xb0, 0x7d, + 0x2c, 0xd1, 0xe9, 0xdf, 0x45, 0xcc, 0xa5, 0x25, 0x9e, 0x63, + 0x9a, 0xbc, 0x45, 0x2a, 0xee, 0x66, 0x84, 0xba, 0xe3, 0x4c, + 0x5c, 0x22, 0x5a, 0xc5, 0xee, 0xa3, 0xf8, 0xb2, 0x4f, 0x0e, + 0x3d, 0xc3, 0xf0, 0x76, 0x9c, 0x8a, 0xc1, 0xe1, 0x0c, 0x5b, + 0x02, 0x8b, 0x74, 0xf4, 0x1b, 0x68, 0x70, 0x79, 0xcf, 0x02, + 0xed, 0x94, 0x33, 0x40, 0x4c, 0x11, 0x20, 0x18, 0x39, 0xd6, + 0xb5, 0x2d, 0x70, 0x13, 0x11, 0x60, 0xc2, 0x4b, 0x57, 0x51, + 0x89, 0x60, 0x3c, 0x16, 0xea, 0xf4, 0x52, 0x94 }, + { 0x8e, 0x25, 0x60, 0xb8, 0xaf, 0x11, 0x07, 0x15, 0x4e, 0x5d, + 0xe4, 0x99, 0x3a, 0x25, 0xce, 0xd6, 0xeb, 0xae, 0xa0, 0x19, + 0xfa, 0x87, 0x77, 0x2f, 0x89, 0xf3, 0x36, 0x27, 0x3b, 0x3a, + 0x2c, 0xd7, 0x8c, 0x17, 0xae, 0x85, 0x98, 0x7b, 0x90, 0x7a, + 0x8c, 0x19, 0xfd, 0x8f, 0x92, 0x2d, 0xbc, 0xe8, 0x67, 0x4e, + 0xac, 0x95, 0x5a, 0x33, 0x06, 0x5a, 0xeb, 0xbb, 0x1f, 0xaf, + 0xee, 0xd0, 0xe1, 0x97, 0x7b, 0x32, 0x8e, 0x6f, 0xf2, 0xbc, + 0x37, 0x92, 0x75, 0x98, 0x84, 0x64, 0xb8, 0x0e, 0x32, 0xae, + 0xbb, 0x9d, 0x5a, 0x38, 0xf7, 0x4f, 0x8d, 0x3a, 0xe2, 0x80, + 0x14, 0xc1, 0x07, 0x5e, 0x3c, 0x8e, 0xce, 0xca, 0xf0, 0x84, + 0x8a, 0x75, 0x3e, 0xf2, 0x33, 0x4c, 0x9d, 0x9e, 0x5a, 0xeb, + 0xc6, 0x80, 0xf7, 0x5b, 0x4b, 0xf6, 0x3a, 0x3c, 0xab, 0x6a, + 0x84, 0xf7, 0x1a, 0x6a, 0xe8, 0xf4, 0x43, 0x57 }, + { 0x59, 0x00, 0x5f, 0x22, 0x83, 0x24, 0xf2, 0xe5, 0xfe, 0xf3, + 0xd9, 0x2b, 0x92, 0xfd, 0x9a, 0x29, 0x88, 0xbe, 0x0c, 0x92, + 0x8f, 0x92, 0x23, 0x15, 0x23, 0x0c, 0xc7, 0x7c, 0x53, 0x91, + 0xca, 0x50, 0xb4, 0x1a, 0xb2, 0x65, 0x23, 0x31, 0xd6, 0x11, + 0x61, 0x27, 0x5a, 0xc2, 0x0a, 0xdf, 0x09, 0xc7, 0x40, 0x40, + 0x34, 0x5c, 0x8e, 0x0a, 0x28, 0xab, 0x89, 0x29, 0xd4, 0xde, + 0x97, 0x52, 0x3b, 0x1f, 0x60, 0x78, 0x34, 0x0a, 0x65, 0x10, + 0x46, 0xd5, 0x27, 0x19, 0xdb, 0x5d, 0xa3, 0x83, 0xbb, 0xa7, + 0x49, 0xa8, 0x02, 0x00, 0xb1, 0x16, 0x01, 0x18, 0x1e, 0x0b, + 0x15, 0xcd, 0x3a, 0x94, 0x08, 0xff, 0x22, 0x23, 0x76, 0x32, + 0x9d, 0xfd, 0x95, 0x0e, 0xb6, 0x38, 0x28, 0x31, 0x9c, 0xdd, + 0x27, 0xc7, 0x45, 0xa1, 0x07, 0x9f, 0xba, 0xb2, 0xcf, 0x9e, + 0x56, 0xd3, 0x74, 0x6c, 0x31, 0x41, 0xab, 0xa6 }, + { 0x57, 0xa7, 0x8e, 0x26, 0xd7, 0x83, 0xdf, 0x6e, 0xe4, 0x49, + 0x59, 0x36, 0xb4, 0x3b, 0xae, 0x8d, 0xe9, 0x79, 0x18, 0x51, + 0x32, 0x62, 0xa3, 0x38, 0x00, 0x85, 0xac, 0x6e, 0x17, 0x38, + 0x2d, 0xa1, 0x00, 0x80, 0xfc, 0x0c, 0xf3, 0x9e, 0xad, 0x9c, + 0x2d, 0xf1, 0x90, 0xac, 0xb0, 0xe0, 0x86, 0x18, 0x97, 0x71, + 0x43, 0x01, 0x44, 0xa6, 0x63, 0xda, 0x19, 0x17, 0x57, 0x14, + 0x85, 0x58, 0xca, 0x58, 0xd0, 0xa7, 0x51, 0xf1, 0x48, 0x8c, + 0x0d, 0xe6, 0x91, 0x3d, 0xd0, 0x1c, 0xb1, 0x8b, 0x72, 0xb2, + 0x54, 0x89, 0x16, 0xf7, 0x3f, 0xf3, 0x89, 0x7f, 0x2b, 0x70, + 0x43, 0xb1, 0x50, 0x44, 0x6c, 0xde, 0x8c, 0x97, 0xf9, 0x32, + 0x3a, 0x86, 0x56, 0xb6, 0x85, 0xa7, 0x5d, 0x92, 0x66, 0xc5, + 0x97, 0x3f, 0xbe, 0x73, 0xaa, 0xc0, 0xe9, 0x66, 0xfb, 0x79, + 0x6b, 0xb1, 0x75, 0x0c, 0x3c, 0x4c, 0x1c, 0x74 }, + { 0x1c, 0xa3, 0x70, 0xc5, 0x81, 0xc4, 0x72, 0xe8, 0x32, 0x51, + 0xe4, 0x12, 0x8f, 0x6a, 0xda, 0x87, 0xb4, 0xc5, 0x33, 0xa7, + 0xf6, 0xd3, 0x5b, 0x7e, 0x85, 0x24, 0x07, 0xd8, 0x08, 0xd8, + 0xa0, 0x36, 0x41, 0x91, 0x04, 0x8f, 0xac, 0x0f, 0x46, 0x2d, + 0x6c, 0xa5, 0xef, 0x6a, 0xc4, 0x54, 0xe2, 0x88, 0xe6, 0xec, + 0x93, 0x01, 0xe0, 0x84, 0x17, 0xd7, 0x65, 0x8f, 0x58, 0x9b, + 0x0c, 0x45, 0x44, 0xd0, 0xec, 0xfa, 0x24, 0x45, 0xad, 0x96, + 0xad, 0xc3, 0xc4, 0x6b, 0x39, 0x18, 0x67, 0xf0, 0x86, 0x43, + 0xe5, 0xd7, 0xa6, 0x7d, 0xc2, 0x0e, 0xf5, 0x00, 0x9c, 0x8d, + 0x59, 0xf5, 0x40, 0xdf, 0x57, 0x9d, 0x72, 0xdf, 0x32, 0x32, + 0x33, 0xb9, 0x3d, 0xeb, 0x8c, 0x54, 0x27, 0x83, 0x18, 0x86, + 0xcf, 0x3b, 0x2b, 0x49, 0xa9, 0x27, 0x94, 0x10, 0xc3, 0xac, + 0x16, 0x1b, 0x34, 0x6f, 0x40, 0xdb, 0xdd, 0xd8 }, + { 0x25, 0x84, 0xb3, 0x4c, 0x4c, 0x33, 0xac, 0x79, 0x32, 0xdb, + 0x52, 0xf4, 0xe6, 0x26, 0x5b, 0xaa, 0x53, 0xd0, 0x44, 0x8a, + 0x1d, 0xbd, 0x3b, 0x03, 0x83, 0xbf, 0x46, 0x4e, 0x2e, 0xfd, + 0x90, 0x03, 0x71, 0xa1, 0x17, 0x20, 0x2b, 0x42, 0x50, 0x72, + 0x6c, 0x31, 0x1c, 0x3d, 0xc0, 0x86, 0x7e, 0x39, 0xca, 0xd4, + 0x67, 0xb5, 0x08, 0xcd, 0x1c, 0xd2, 0x0d, 0xd2, 0x80, 0x1d, + 0xf9, 0x9d, 0xae, 0x74, 0x22, 0x4b, 0x28, 0x82, 0xe1, 0x88, + 0xf1, 0x2d, 0xb5, 0xde, 0xcf, 0xd0, 0x23, 0x90, 0x4c, 0x35, + 0x0b, 0xf1, 0x61, 0xa1, 0xc7, 0xbd, 0x31, 0xf7, 0x78, 0xde, + 0x52, 0x3a, 0x9c, 0xda, 0x12, 0x8b, 0xb5, 0xfe, 0x87, 0xf4, + 0xf5, 0xb0, 0x1f, 0xdb, 0x49, 0x05, 0xaa, 0xbf, 0x41, 0x16, + 0x32, 0x02, 0x73, 0x12, 0x87, 0x9c, 0xfd, 0x19, 0x98, 0xb3, + 0x94, 0xbd, 0x51, 0x71, 0xa8, 0x01, 0xb6, 0x8a }, + { 0x7e, 0x81, 0x13, 0x74, 0x3f, 0x9a, 0xb0, 0x85, 0xac, 0xdd, + 0xb6, 0xff, 0x95, 0x1c, 0xa4, 0x9a, 0xe1, 0xc8, 0x35, 0x45, + 0x69, 0x80, 0x7b, 0xaa, 0xaf, 0xb6, 0x02, 0x69, 0xff, 0x51, + 0xa9, 0xff, 0xfe, 0x6a, 0xd2, 0x2e, 0xf2, 0xd5, 0x73, 0x7c, + 0x6b, 0x3f, 0xaa, 0xbe, 0x18, 0x78, 0x97, 0xe0, 0x59, 0x27, + 0xdd, 0x51, 0xdc, 0x7c, 0xb4, 0x88, 0x00, 0x26, 0x67, 0x06, + 0x4d, 0xf6, 0xc7, 0xd0, 0x2e, 0x42, 0xc3, 0xe1, 0x62, 0xee, + 0x7c, 0xc8, 0x76, 0xdd, 0x30, 0x45, 0xa8, 0xb9, 0xa6, 0x57, + 0x3f, 0x27, 0x18, 0x54, 0xac, 0x05, 0x45, 0x24, 0x04, 0xc2, + 0xbb, 0x36, 0xfa, 0x17, 0xd8, 0x0d, 0x45, 0x5d, 0x18, 0x5c, + 0x48, 0x74, 0x91, 0x3d, 0x42, 0x2e, 0x71, 0xf7, 0xfd, 0x60, + 0xb5, 0xf8, 0xa5, 0xe7, 0x40, 0xba, 0x45, 0xfb, 0xe5, 0x23, + 0x3c, 0xb8, 0x63, 0x89, 0x2a, 0xee, 0xc6, 0x88 }, + { 0x43, 0x6b, 0x8c, 0x64, 0xdf, 0x84, 0x85, 0xa6, 0x00, 0x1c, + 0x79, 0x18, 0xba, 0x56, 0xfa, 0x91, 0x63, 0x76, 0xc1, 0xa2, + 0x63, 0xdb, 0x2b, 0xfe, 0xfe, 0x0c, 0x9f, 0x81, 0x39, 0x6d, + 0xa4, 0x22, 0xe4, 0x53, 0x86, 0x67, 0x32, 0xa1, 0xad, 0x94, + 0x23, 0xe0, 0xb4, 0x6c, 0xae, 0xec, 0x0b, 0xfe, 0x97, 0xd7, + 0x1e, 0xff, 0x50, 0x04, 0xf2, 0x86, 0xbb, 0x07, 0x6b, 0x98, + 0xe3, 0x91, 0xc0, 0xcd, 0xda, 0x77, 0x4d, 0xe5, 0xf5, 0xff, + 0x43, 0xcb, 0x0c, 0x1c, 0x15, 0x5a, 0x23, 0x86, 0xc4, 0x53, + 0x98, 0x45, 0xcd, 0x06, 0x15, 0xb0, 0xcd, 0x5e, 0x2f, 0xd0, + 0x9d, 0xb0, 0xe5, 0x89, 0x66, 0x9c, 0xb5, 0x38, 0x12, 0xd3, + 0x6c, 0x46, 0xd1, 0xd3, 0x3e, 0x02, 0xd0, 0xb8, 0x04, 0x09, + 0xb4, 0x7d, 0x91, 0x91, 0x8e, 0xa8, 0xce, 0x11, 0x17, 0xe1, + 0xad, 0x72, 0x2a, 0x8b, 0x83, 0x0a, 0x88, 0xb1 }, + { 0x52, 0x66, 0xca, 0x9e, 0x6d, 0xbe, 0x95, 0xe1, 0x1d, 0xf7, + 0xaa, 0xe4, 0x07, 0x68, 0xcb, 0x66, 0x6f, 0x7c, 0x90, 0xe1, + 0x53, 0x7d, 0xa5, 0xff, 0xe5, 0xdc, 0xde, 0x62, 0x17, 0x95, + 0x44, 0x05, 0x50, 0x60, 0x07, 0x5e, 0x02, 0x43, 0xdc, 0xb6, + 0xe5, 0x01, 0x85, 0x17, 0xcd, 0x51, 0xe5, 0x3f, 0xe6, 0x14, + 0x14, 0x8e, 0xd4, 0x73, 0x94, 0xa3, 0x79, 0x90, 0x8b, 0x90, + 0x8c, 0x92, 0x79, 0x9d, 0xe4, 0xf9, 0xd4, 0x1e, 0x18, 0xd9, + 0x70, 0x68, 0xdd, 0x7d, 0x68, 0xc9, 0x43, 0xc8, 0xc2, 0x86, + 0x63, 0x3b, 0x95, 0xde, 0xb2, 0x3b, 0x41, 0xdf, 0x01, 0xa5, + 0x2e, 0x33, 0x07, 0x1a, 0x34, 0x7a, 0x54, 0x89, 0x16, 0xaf, + 0xfc, 0x94, 0x51, 0xdc, 0x5a, 0x77, 0x65, 0xd3, 0x0c, 0x18, + 0xee, 0xbd, 0xdf, 0xa6, 0x1e, 0x94, 0xa0, 0x77, 0xdf, 0x84, + 0x88, 0x11, 0x7e, 0x9d, 0x8a, 0xb7, 0x64, 0xbc }, + { 0x41, 0xf3, 0x25, 0xb9, 0x9c, 0xd8, 0x4a, 0x2b, 0xc1, 0x7a, + 0x09, 0x20, 0x1f, 0xc6, 0x70, 0x3a, 0x0f, 0x32, 0xb4, 0x49, + 0x4f, 0xb4, 0xcb, 0x67, 0xa9, 0x75, 0x04, 0x4e, 0x62, 0x6b, + 0xea, 0x27, 0x7d, 0xec, 0x36, 0x2b, 0x7b, 0xd3, 0xe2, 0x20, + 0x89, 0x9a, 0x20, 0xb4, 0x14, 0x6e, 0xf8, 0xff, 0x20, 0x7c, + 0x13, 0x47, 0x2b, 0x2f, 0x3b, 0xff, 0x6f, 0xb8, 0xcb, 0x1d, + 0x14, 0x96, 0x0d, 0x7c, 0xf1, 0xe2, 0x98, 0xfd, 0x94, 0x0c, + 0xe1, 0xe8, 0x8f, 0x34, 0xe1, 0x74, 0x86, 0xc3, 0x1f, 0xf0, + 0x35, 0x19, 0xc6, 0xe3, 0x19, 0xfd, 0x70, 0xc1, 0x3e, 0x6e, + 0x69, 0x24, 0x30, 0x25, 0x7c, 0xfc, 0x21, 0x38, 0xa1, 0xe8, + 0xfd, 0xe5, 0xa4, 0xfd, 0xb3, 0x41, 0x84, 0x40, 0xeb, 0x04, + 0xf4, 0x9d, 0xf9, 0xe4, 0xaf, 0x5a, 0x7c, 0x38, 0xe5, 0x40, + 0x84, 0xdd, 0xee, 0x6d, 0x13, 0x86, 0xb3, 0xdb }, + { 0x56, 0xb3, 0x0f, 0xb6, 0xe5, 0x8c, 0xea, 0x9e, 0x7d, 0xb3, + 0xd3, 0x7b, 0xd9, 0xaa, 0x18, 0xfd, 0x49, 0xef, 0x46, 0x70, + 0xeb, 0x8c, 0x34, 0x68, 0x00, 0xf2, 0xe3, 0xac, 0x24, 0x2c, + 0xa8, 0xfd, 0x89, 0x47, 0xba, 0x6d, 0x9b, 0xfd, 0x07, 0xdd, + 0xc6, 0x47, 0x70, 0x5e, 0xa7, 0x61, 0xba, 0x43, 0x3d, 0xb6, + 0xd2, 0x8d, 0x23, 0x40, 0x0a, 0xa7, 0x59, 0x23, 0x52, 0x1f, + 0x1d, 0xac, 0x89, 0x44, 0xdf, 0xe2, 0xdc, 0x47, 0xf1, 0x7b, + 0x73, 0x41, 0x98, 0x27, 0x6d, 0x96, 0x28, 0x9e, 0x7b, 0xb9, + 0x2a, 0x57, 0x8c, 0xb5, 0x06, 0x3e, 0x7b, 0x38, 0x59, 0x05, + 0xe1, 0xd9, 0x4b, 0xed, 0x33, 0x8d, 0x34, 0x06, 0x47, 0x04, + 0xa6, 0x20, 0x08, 0x3b, 0xa8, 0xef, 0x28, 0x22, 0x4d, 0x86, + 0x4c, 0xe5, 0xe7, 0x48, 0x49, 0x8e, 0x00, 0x72, 0x8a, 0xfc, + 0x31, 0x2e, 0xd5, 0x13, 0xce, 0x28, 0x43, 0xa4 }, + { 0x13, 0x53, 0xcc, 0x57, 0x58, 0xbd, 0xd1, 0x46, 0x89, 0x90, + 0x81, 0xe5, 0xdc, 0xcf, 0x7f, 0x07, 0xe4, 0x72, 0xfb, 0x8b, + 0x17, 0xc0, 0xd9, 0x69, 0x58, 0xf8, 0x8c, 0x51, 0xc6, 0x52, + 0x3a, 0x79, 0x3e, 0xdf, 0x81, 0xf5, 0x85, 0xd3, 0xcd, 0x83, + 0xde, 0xa9, 0xb4, 0xfa, 0xf8, 0x72, 0x04, 0xae, 0x30, 0x92, + 0x23, 0x77, 0x90, 0xbb, 0x1c, 0xd8, 0xc4, 0xe0, 0xb7, 0xf8, + 0x94, 0x39, 0x2a, 0x91, 0x78, 0xb6, 0x34, 0xa5, 0xad, 0xe8, + 0xa8, 0x8d, 0x0b, 0xfa, 0xef, 0xa5, 0x1f, 0x2f, 0xae, 0xcb, + 0xc3, 0x4e, 0x40, 0x75, 0x65, 0xf8, 0x07, 0xd3, 0x21, 0x23, + 0x53, 0x3c, 0xb2, 0xe8, 0x1c, 0x3a, 0x3b, 0xed, 0x9a, 0x44, + 0x92, 0x4b, 0x00, 0x8a, 0x20, 0xd8, 0x87, 0x98, 0x3a, 0xda, + 0x44, 0x1f, 0x7a, 0xf9, 0x22, 0xdc, 0x87, 0x32, 0xc8, 0x91, + 0x07, 0xec, 0xdc, 0xaa, 0xcd, 0x80, 0xa4, 0x28 }, + { 0x3e, 0xc2, 0x18, 0x5d, 0xf4, 0x51, 0xdf, 0x58, 0x72, 0x3a, + 0x83, 0x0e, 0x5a, 0x21, 0xe7, 0x89, 0x8d, 0x1d, 0xf4, 0x3c, + 0xbb, 0x1c, 0xc1, 0xf1, 0x8f, 0x41, 0x93, 0xa9, 0xa6, 0xb1, + 0x6e, 0xbd, 0xbc, 0x69, 0xcf, 0xc0, 0x52, 0x87, 0x7a, 0xe5, + 0x75, 0xf4, 0xe5, 0x70, 0xf8, 0xa3, 0x62, 0x35, 0xa5, 0x58, + 0xf9, 0x28, 0x15, 0x5c, 0xe6, 0xde, 0x8a, 0x79, 0x7f, 0xc7, + 0x95, 0x8d, 0xdb, 0xad, 0x49, 0x68, 0x5d, 0x86, 0xcd, 0x39, + 0xe4, 0x2b, 0x84, 0x16, 0xa7, 0xe0, 0x72, 0xd6, 0x72, 0x97, + 0xf1, 0x58, 0x3e, 0xd6, 0x27, 0xf8, 0x12, 0x94, 0x2a, 0xb3, + 0xa1, 0x64, 0x6a, 0x7b, 0x8e, 0x82, 0xd9, 0x35, 0xbf, 0x51, + 0x20, 0x47, 0x04, 0x0c, 0x8d, 0x94, 0x34, 0xa0, 0xdc, 0xe8, + 0xb8, 0xe7, 0x59, 0xe8, 0xb5, 0xa2, 0x64, 0x9b, 0x89, 0xc7, + 0x28, 0xa5, 0x64, 0x97, 0x39, 0xbf, 0x6e, 0x18 }, + { 0x89, 0xb3, 0x56, 0xb6, 0xa2, 0x11, 0xab, 0xe5, 0x30, 0x87, + 0xdc, 0x5c, 0xe9, 0xd4, 0x47, 0xa3, 0x5f, 0x1d, 0xe8, 0xcc, + 0x39, 0xbd, 0xd6, 0x66, 0xbc, 0x93, 0xc5, 0xf3, 0x54, 0x97, + 0xaa, 0x72, 0xb5, 0x27, 0xc5, 0x7b, 0x8b, 0xc9, 0x76, 0x07, + 0xb4, 0xa6, 0x7a, 0xe7, 0xd3, 0x89, 0x51, 0xe0, 0xb0, 0xd8, + 0x4b, 0x1f, 0x8d, 0x7d, 0x43, 0x29, 0x8e, 0x40, 0x61, 0x21, + 0x06, 0xbc, 0x05, 0x50, 0xba, 0x18, 0x8c, 0x56, 0x7b, 0xc2, + 0x8b, 0x9d, 0x60, 0x24, 0x2a, 0xcb, 0x12, 0xf0, 0xd2, 0xc8, + 0x69, 0xd4, 0x9c, 0xe1, 0xc7, 0x78, 0x50, 0xbe, 0x35, 0x03, + 0x14, 0x9f, 0x37, 0xf3, 0x51, 0xf9, 0xb7, 0xdd, 0x2d, 0x25, + 0x04, 0x7a, 0xe0, 0x9c, 0x92, 0xe0, 0x2d, 0x93, 0xa0, 0x9f, + 0x80, 0xf6, 0x69, 0x82, 0xc6, 0xcc, 0x6e, 0x51, 0xd4, 0x12, + 0xb9, 0xd4, 0xc7, 0xd7, 0x1f, 0x0b, 0xc2, 0xd7 }, + { 0x39, 0xc4, 0xf1, 0x0d, 0x57, 0xc5, 0xd1, 0x26, 0x65, 0x6f, + 0x18, 0xe0, 0x8a, 0x0d, 0x4f, 0x52, 0x7e, 0x12, 0x02, 0xbe, + 0x87, 0xad, 0xc2, 0xf9, 0x4e, 0xf3, 0xa8, 0x0e, 0xdc, 0x60, + 0xee, 0xe5, 0x2c, 0xc2, 0x7c, 0xef, 0x00, 0xbf, 0x79, 0x28, + 0xe1, 0xbb, 0x97, 0x02, 0x55, 0x84, 0xbc, 0x86, 0x9c, 0xf5, + 0x81, 0x7f, 0x87, 0x64, 0x86, 0x43, 0x01, 0x16, 0x19, 0xc9, + 0xcb, 0x16, 0x2d, 0xc2, 0xee, 0x62, 0x8e, 0xce, 0xf4, 0x26, + 0xda, 0xea, 0x63, 0xe1, 0x1d, 0x26, 0x37, 0x43, 0x36, 0x58, + 0x11, 0xb0, 0x4f, 0x72, 0x0e, 0x41, 0xd9, 0x4e, 0x56, 0x64, + 0xa2, 0xda, 0x8b, 0x86, 0x57, 0xa3, 0xf5, 0xb5, 0x6b, 0xf7, + 0xad, 0xac, 0x9e, 0x5c, 0x41, 0x3a, 0xbf, 0xc9, 0x1c, 0x1d, + 0x4b, 0x72, 0x0f, 0xb8, 0x0b, 0xaa, 0xa8, 0x71, 0xb7, 0xa9, + 0xed, 0x6d, 0xb0, 0xaf, 0xdf, 0xdc, 0xc8, 0x37 }, + { 0x41, 0x4b, 0x54, 0x2d, 0x49, 0x15, 0x2b, 0x00, 0xcf, 0xf1, + 0x64, 0x78, 0x90, 0x69, 0xfb, 0xcc, 0x0b, 0x9a, 0x17, 0x07, + 0xb6, 0xe5, 0x79, 0xcf, 0x44, 0xc6, 0xc9, 0x77, 0x5a, 0xed, + 0x24, 0xc4, 0xfd, 0xe5, 0xbe, 0x8d, 0x73, 0xf7, 0xe3, 0x39, + 0x28, 0x17, 0xeb, 0xb3, 0xd4, 0x6f, 0xf5, 0x1b, 0xbe, 0xc7, + 0x76, 0x7e, 0xc7, 0xd4, 0xc5, 0x56, 0xf2, 0xb6, 0x37, 0x25, + 0xf1, 0xaa, 0x12, 0x02, 0xa7, 0xbc, 0x17, 0x75, 0x89, 0x4c, + 0x44, 0x44, 0xc8, 0x41, 0xe9, 0xea, 0x3b, 0xd1, 0x62, 0x83, + 0x6d, 0x1e, 0x6d, 0x35, 0xa8, 0x1a, 0x0a, 0x78, 0x7d, 0xac, + 0x80, 0xd0, 0x81, 0x1a, 0xc7, 0x2d, 0x79, 0xb6, 0x8b, 0x67, + 0x02, 0x06, 0x8d, 0x84, 0xed, 0xc1, 0xcd, 0xad, 0x4b, 0xd4, + 0xee, 0x54, 0x55, 0x5b, 0x09, 0x18, 0xa5, 0x18, 0xaa, 0x9d, + 0xb3, 0xa9, 0xb6, 0x8c, 0xe8, 0x8a, 0xec, 0xd3 }, + { 0x52, 0x67, 0x8d, 0x6a, 0xe0, 0x0b, 0x8b, 0x2a, 0x43, 0x97, + 0x78, 0x74, 0x44, 0x4e, 0x85, 0x15, 0x3c, 0x73, 0x62, 0xfa, + 0x96, 0x08, 0xf5, 0xbf, 0xf4, 0x8e, 0x62, 0x3e, 0x27, 0x0d, + 0x17, 0xa6, 0x13, 0x33, 0x8e, 0xf8, 0xed, 0x55, 0x6a, 0x6c, + 0x74, 0xab, 0x92, 0x48, 0xd1, 0x84, 0x30, 0x07, 0xaf, 0x1f, + 0x4a, 0x6e, 0x74, 0x0d, 0xb2, 0x9c, 0xb2, 0xe4, 0xd6, 0x6c, + 0x1b, 0xa2, 0xae, 0xa9, 0x70, 0x8f, 0x9b, 0x32, 0x44, 0xaf, + 0x08, 0x2e, 0xe1, 0x31, 0xe8, 0x8f, 0x94, 0x50, 0x69, 0x0a, + 0x9f, 0x9d, 0x35, 0xac, 0x81, 0xc6, 0xe6, 0xd7, 0x3e, 0xf0, + 0x56, 0x02, 0x90, 0x13, 0xe4, 0xec, 0xc7, 0x88, 0xc6, 0x17, + 0x05, 0x12, 0x0e, 0x70, 0x42, 0x5f, 0xb5, 0x12, 0xde, 0xbb, + 0x20, 0xaf, 0x5b, 0x7f, 0x4e, 0x1b, 0x90, 0xe6, 0x71, 0x3a, + 0x33, 0xc3, 0x1e, 0x58, 0x60, 0x6e, 0x17, 0x3b }, + { 0x70, 0x40, 0xba, 0x5b, 0xc1, 0x0c, 0xee, 0xdd, 0x04, 0x5a, + 0xc6, 0x14, 0xc8, 0xef, 0xce, 0xa6, 0x23, 0xa5, 0x9c, 0x1d, + 0xbf, 0x22, 0xf6, 0x82, 0xb8, 0xee, 0x84, 0x2a, 0x5d, 0x99, + 0x74, 0xc9, 0x4b, 0x58, 0xf9, 0xb2, 0xd3, 0x05, 0x3b, 0x4f, + 0x3e, 0xcd, 0x40, 0x75, 0x0f, 0x79, 0x48, 0xa9, 0x0e, 0x41, + 0x19, 0x6e, 0xf6, 0xd2, 0xd7, 0xff, 0xf3, 0x9c, 0x49, 0x0e, + 0x5a, 0xa5, 0x69, 0x5c, 0xfa, 0xb4, 0x18, 0xd3, 0x2c, 0x1b, + 0xf9, 0x06, 0x1a, 0x33, 0xe9, 0x4f, 0x3f, 0x7d, 0x9e, 0x09, + 0x2b, 0xd6, 0x18, 0x04, 0x93, 0x33, 0x44, 0x85, 0x25, 0x8c, + 0x2c, 0x52, 0xa5, 0x71, 0xf8, 0x9b, 0x85, 0x09, 0xd4, 0x14, + 0x2d, 0xfd, 0x49, 0x1f, 0x0e, 0x03, 0xf4, 0x96, 0x92, 0x7a, + 0x5f, 0x81, 0x52, 0xd6, 0x65, 0x3c, 0xa9, 0x2b, 0xc0, 0xab, + 0x5d, 0xff, 0x1c, 0x59, 0xdf, 0x36, 0xae, 0xb4 }, + { 0x90, 0x43, 0xa6, 0xd6, 0x0b, 0xd1, 0xc9, 0xc1, 0x3d, 0x28, + 0x1e, 0x1a, 0xfe, 0x87, 0x32, 0x48, 0xff, 0x2d, 0xff, 0x4e, + 0x70, 0xf4, 0xea, 0xa3, 0xfa, 0xc3, 0xe5, 0x82, 0x43, 0x65, + 0x78, 0x4a, 0x97, 0xd2, 0xb7, 0x21, 0xb7, 0x74, 0xc3, 0x1e, + 0xaf, 0x9a, 0x23, 0xe8, 0xe7, 0xe3, 0x86, 0x0e, 0xc1, 0xfe, + 0x0d, 0x8a, 0xde, 0x1d, 0x33, 0x6f, 0x65, 0x27, 0x34, 0x9f, + 0xfb, 0x29, 0x4c, 0x4a, 0x2f, 0xd4, 0xf0, 0xc6, 0x5b, 0x25, + 0xf0, 0x06, 0x34, 0x92, 0x27, 0x6b, 0x86, 0x67, 0x69, 0x6b, + 0x1e, 0x01, 0xa7, 0x42, 0x28, 0x14, 0xc1, 0x77, 0x88, 0x86, + 0xd8, 0x76, 0xd2, 0xcd, 0xa9, 0xd2, 0x9d, 0x76, 0x94, 0xf1, + 0x27, 0x3b, 0x61, 0x73, 0x0a, 0x09, 0x66, 0x50, 0x1a, 0xd9, + 0x3d, 0x4f, 0x31, 0xa6, 0x35, 0x03, 0x18, 0x43, 0x27, 0xe0, + 0x2c, 0x36, 0x4f, 0x81, 0x51, 0x5a, 0x1a, 0x96 }, + { 0x26, 0x36, 0x2b, 0x48, 0x3a, 0x12, 0x5f, 0x35, 0xb0, 0x76, + 0x0a, 0x3c, 0xb7, 0x3e, 0xac, 0x46, 0xe4, 0x5c, 0x75, 0xdf, + 0xff, 0xaa, 0xd0, 0x78, 0x7b, 0xd2, 0xc1, 0x38, 0x1e, 0x35, + 0x79, 0xb2, 0x95, 0x77, 0x1f, 0xa2, 0xdb, 0x4e, 0x80, 0x1a, + 0x79, 0xbc, 0x85, 0xc6, 0x4e, 0x8d, 0xa1, 0x54, 0x2c, 0x8d, + 0x38, 0x34, 0x40, 0xc9, 0x2a, 0xf9, 0xfb, 0x12, 0xea, 0x4d, + 0xf5, 0x97, 0xf6, 0x63, 0xc3, 0xc3, 0x46, 0x3a, 0xe4, 0x06, + 0x98, 0x80, 0x99, 0x6b, 0x08, 0x22, 0xce, 0xdf, 0xcd, 0x94, + 0x8a, 0xd7, 0xa0, 0x3a, 0x9c, 0xbe, 0x10, 0x6f, 0xb8, 0x01, + 0xc8, 0x3d, 0x34, 0xa2, 0xea, 0x06, 0x92, 0x87, 0x54, 0xbd, + 0x61, 0x62, 0x00, 0xf3, 0x2a, 0xc1, 0x60, 0xcc, 0xe0, 0x08, + 0x88, 0xac, 0x1b, 0x2d, 0xed, 0x5c, 0xab, 0xbc, 0x3b, 0xe3, + 0x15, 0x11, 0xa0, 0xfe, 0x76, 0x6c, 0x79, 0x37 }, + { 0x2e, 0x95, 0x2b, 0x20, 0x55, 0x5c, 0x93, 0x5e, 0x45, 0x2f, + 0xe2, 0x31, 0x09, 0xff, 0x59, 0xba, 0x9c, 0x86, 0xe0, 0xb2, + 0x96, 0xc6, 0xb5, 0xee, 0x92, 0xc2, 0x65, 0x63, 0xc1, 0x43, + 0x92, 0x73, 0x5a, 0xce, 0x53, 0xd1, 0xbe, 0xe0, 0xf2, 0xe9, + 0x19, 0x3f, 0x88, 0xc8, 0x05, 0x4d, 0x54, 0x71, 0x7b, 0x60, + 0xd4, 0x64, 0xa7, 0xbf, 0x21, 0xda, 0x45, 0xe4, 0xf2, 0xa5, + 0xbe, 0xa9, 0xcd, 0x49, 0x21, 0xfb, 0xd3, 0x10, 0x1e, 0x06, + 0xd4, 0x85, 0x39, 0x1f, 0x68, 0x8a, 0x44, 0xf9, 0x71, 0x45, + 0xa5, 0xee, 0xb2, 0xb1, 0x4c, 0x0d, 0xa1, 0xe9, 0xfd, 0x3d, + 0x20, 0xea, 0xff, 0x55, 0x2b, 0xac, 0xdb, 0x70, 0x90, 0x72, + 0xcb, 0x86, 0xb3, 0x33, 0x8b, 0x07, 0xbb, 0x86, 0xaf, 0x5e, + 0x4b, 0x75, 0x2d, 0x0e, 0xe8, 0x77, 0x69, 0xe9, 0xee, 0x71, + 0x25, 0xc6, 0x8d, 0x28, 0xee, 0xfc, 0x3e, 0x89 }, + { 0x12, 0x36, 0xd0, 0x17, 0x30, 0x37, 0x8e, 0x4b, 0x1c, 0x0a, + 0x84, 0xc9, 0xeb, 0x53, 0xef, 0x06, 0xa5, 0xc1, 0x48, 0x96, + 0xdb, 0x2f, 0x02, 0x73, 0x2b, 0xcd, 0x96, 0xb0, 0xb0, 0x93, + 0x77, 0xe0, 0xff, 0x60, 0x4a, 0x11, 0x17, 0x55, 0x9a, 0x30, + 0x7c, 0x14, 0xef, 0x33, 0x53, 0xb1, 0xfa, 0x97, 0x7a, 0xaa, + 0x53, 0xf2, 0xa4, 0x4d, 0x2f, 0xa8, 0x8e, 0xf8, 0x3f, 0xb3, + 0x9d, 0x6e, 0xbc, 0xb1, 0xa5, 0xc2, 0x6e, 0x3a, 0x7f, 0xbd, + 0x85, 0x6d, 0x02, 0x51, 0x13, 0xec, 0x6c, 0x12, 0x20, 0x76, + 0x28, 0x35, 0xb3, 0x86, 0x18, 0x1e, 0x5e, 0x33, 0xbc, 0x70, + 0x2f, 0x26, 0xa2, 0x63, 0xec, 0xc9, 0x58, 0x0e, 0x2e, 0xc9, + 0x35, 0x5f, 0xf2, 0xb5, 0x10, 0x3e, 0x45, 0xb6, 0x00, 0x7b, + 0x1b, 0x86, 0xe6, 0x8a, 0x5d, 0xbe, 0xd4, 0x3d, 0xfc, 0x58, + 0x2a, 0x84, 0x6b, 0xca, 0xd7, 0x5f, 0x88, 0x6e }, + { 0x02, 0xa4, 0x80, 0x14, 0x62, 0x0c, 0xb5, 0x6e, 0x35, 0x3c, + 0x2d, 0x85, 0x4b, 0x9e, 0xc7, 0xea, 0xe6, 0x16, 0xf5, 0x55, + 0x6c, 0x97, 0xf0, 0xe9, 0x19, 0x88, 0x19, 0x41, 0xd1, 0x46, + 0x58, 0xf3, 0xb3, 0xfc, 0xd3, 0x65, 0x24, 0x38, 0x90, 0x6d, + 0xbb, 0x0c, 0x5d, 0x66, 0x74, 0xcc, 0x95, 0xcb, 0x7d, 0x2c, + 0x72, 0x7d, 0xba, 0x75, 0x30, 0xe9, 0x3b, 0xdd, 0xe1, 0xa8, + 0x70, 0x6e, 0xf8, 0x17, 0x65, 0xba, 0xf5, 0x94, 0x33, 0x0a, + 0x32, 0x82, 0xf0, 0xec, 0x0b, 0x38, 0x42, 0x31, 0x45, 0x76, + 0x55, 0x4f, 0xbb, 0x9f, 0xed, 0x01, 0x08, 0x00, 0x86, 0x52, + 0x46, 0x29, 0x0e, 0x2b, 0xe7, 0xe2, 0x37, 0x12, 0x71, 0x4c, + 0x93, 0x4b, 0xc2, 0xb0, 0x13, 0x00, 0xdf, 0xa0, 0x61, 0x3b, + 0xc3, 0x4b, 0x29, 0xae, 0x47, 0x68, 0x64, 0x60, 0x97, 0xae, + 0xd7, 0x48, 0x1c, 0x8f, 0xc0, 0x84, 0x37, 0x3b }, + { 0x1d, 0x8b, 0xde, 0x6f, 0x8f, 0x21, 0x7f, 0xe0, 0x31, 0x39, + 0x04, 0x14, 0xb5, 0x5f, 0x75, 0xf3, 0xa4, 0x4e, 0x2c, 0x25, + 0xc3, 0x55, 0x6d, 0x18, 0xbe, 0x2d, 0xa8, 0x87, 0xa2, 0xe8, + 0xc3, 0xda, 0x43, 0x04, 0x46, 0x60, 0x91, 0xeb, 0x25, 0x99, + 0x19, 0x2a, 0x64, 0xb7, 0x36, 0x9f, 0x46, 0xc7, 0x32, 0x39, + 0x5d, 0xee, 0x1e, 0x01, 0x14, 0xde, 0xee, 0x95, 0x7c, 0x67, + 0x49, 0xfc, 0xb8, 0x80, 0xde, 0xc0, 0xff, 0xbf, 0x8e, 0xc9, + 0x55, 0xfd, 0x99, 0xab, 0x26, 0xbd, 0x9f, 0x15, 0x4d, 0x1f, + 0xf0, 0xa7, 0xb4, 0x27, 0xaa, 0xda, 0xc2, 0x58, 0xf5, 0xd6, + 0x3b, 0xbb, 0x83, 0x83, 0x50, 0x83, 0xe8, 0x7e, 0x1b, 0x46, + 0xd8, 0x28, 0x93, 0x7d, 0x71, 0x7c, 0x9c, 0x27, 0x69, 0xd0, + 0x11, 0xc5, 0x22, 0x9a, 0x1c, 0x54, 0x90, 0x59, 0xba, 0xa6, + 0x11, 0xd6, 0xd2, 0x3d, 0x50, 0x6c, 0xcd, 0x38 }, + { 0x34, 0x9c, 0x69, 0x43, 0xc6, 0x10, 0x13, 0xc1, 0xf5, 0x65, + 0xb2, 0x8b, 0xcc, 0x83, 0x20, 0x9e, 0xb3, 0x6e, 0xd3, 0x5c, + 0xde, 0xb9, 0x3b, 0x87, 0xb9, 0xb0, 0x0a, 0x02, 0x36, 0x0d, + 0x3a, 0x26, 0xdc, 0x37, 0x5c, 0x84, 0xee, 0x8d, 0x21, 0x39, + 0xd8, 0x19, 0x6b, 0x5b, 0xb6, 0xfc, 0x65, 0x5a, 0x74, 0xfc, + 0x2a, 0x6a, 0xbf, 0xb1, 0x76, 0x38, 0x79, 0x93, 0xf5, 0x7a, + 0xac, 0x94, 0xd4, 0xd1, 0x59, 0x4d, 0x4d, 0x43, 0xf8, 0x8b, + 0x05, 0xe6, 0x41, 0x4d, 0xec, 0xcb, 0xa6, 0x72, 0xba, 0x38, + 0xf4, 0x21, 0x38, 0x26, 0x6f, 0x1b, 0xb6, 0x5c, 0x93, 0x97, + 0xc9, 0x7a, 0xb1, 0x0f, 0xec, 0x10, 0xdb, 0xe0, 0x67, 0x16, + 0x5a, 0x06, 0x07, 0x76, 0x86, 0x2b, 0xbc, 0xb7, 0xd6, 0xf0, + 0x58, 0x46, 0x6e, 0x54, 0xf1, 0x9c, 0xb0, 0x6e, 0xcb, 0x9f, + 0x03, 0xcd, 0x39, 0xf8, 0xa2, 0x02, 0x89, 0x24 }, + { 0x05, 0x65, 0x87, 0xab, 0x89, 0xc2, 0xd8, 0xfa, 0xa3, 0x2f, + 0x32, 0x7e, 0x87, 0x25, 0x57, 0x69, 0x21, 0x19, 0x52, 0x99, + 0x08, 0x17, 0xc5, 0xc2, 0x9c, 0xf8, 0x42, 0xd5, 0x27, 0x18, + 0x2a, 0xc9, 0xd0, 0xd3, 0xa1, 0x77, 0x07, 0x38, 0x96, 0x35, + 0x96, 0x08, 0x9e, 0x8a, 0x5f, 0x0e, 0x12, 0x9b, 0x3a, 0x7f, + 0x3e, 0x90, 0xf4, 0xbd, 0x1f, 0x91, 0xc9, 0x91, 0xf1, 0xc7, + 0xed, 0x0b, 0xd5, 0x0a, 0x24, 0x3a, 0x66, 0x6e, 0x53, 0x37, + 0xf4, 0x53, 0xc5, 0xa8, 0xe2, 0xec, 0x21, 0x46, 0x7e, 0xbf, + 0x2d, 0x74, 0x29, 0x38, 0x73, 0x7c, 0x70, 0xf0, 0x40, 0x0b, + 0xa5, 0x79, 0xba, 0xef, 0x0c, 0x18, 0x74, 0x9f, 0x75, 0x64, + 0x08, 0x50, 0x99, 0x3e, 0xb6, 0xf4, 0x58, 0xa2, 0x21, 0xc2, + 0xb7, 0x80, 0xd5, 0xc2, 0xc4, 0x71, 0x47, 0x00, 0x20, 0x7e, + 0xd1, 0xb3, 0x94, 0x44, 0x4d, 0xe6, 0xc8, 0x8a }, + { 0x1b, 0x87, 0xf2, 0xed, 0xb8, 0x6c, 0xdb, 0xde, 0x81, 0x5f, + 0x15, 0x65, 0x3f, 0x1d, 0x0f, 0x6c, 0xc4, 0x38, 0x76, 0x4b, + 0xf6, 0xca, 0xae, 0x00, 0x63, 0xd0, 0xa0, 0xe9, 0x0f, 0xb1, + 0x54, 0x38, 0x6f, 0x3c, 0x0d, 0x68, 0x88, 0x3e, 0x09, 0x72, + 0x58, 0xfd, 0x14, 0x37, 0x6f, 0xff, 0x25, 0x4f, 0xc2, 0xca, + 0xee, 0x3f, 0x31, 0x90, 0xb5, 0x1e, 0xc2, 0xa8, 0x9e, 0x9f, + 0xc4, 0x05, 0x2e, 0xe1, 0xc4, 0xad, 0x91, 0x8f, 0x7e, 0x87, + 0x2a, 0xbb, 0x0e, 0x5b, 0x34, 0xd8, 0x9b, 0xd2, 0x70, 0x3e, + 0x6b, 0xe8, 0x4c, 0x8f, 0x2a, 0xc2, 0xd2, 0xf6, 0x57, 0xc9, + 0x50, 0x36, 0x36, 0xb3, 0x59, 0x76, 0x89, 0x49, 0x4c, 0x5e, + 0xb6, 0x1a, 0x8c, 0x13, 0x5f, 0x03, 0x02, 0x1f, 0xa9, 0xab, + 0x46, 0xb9, 0x5f, 0xaf, 0xf7, 0xcb, 0x98, 0xe5, 0x14, 0x44, + 0x00, 0x85, 0x62, 0xed, 0x1c, 0xe4, 0x73, 0x3d }, + { 0x8e, 0x02, 0x27, 0xc4, 0x3e, 0x95, 0xbc, 0x23, 0xb2, 0x2b, + 0x87, 0xb1, 0xc4, 0xa3, 0xe5, 0x9e, 0xbe, 0x3f, 0x3c, 0x77, + 0x88, 0x84, 0x8a, 0x99, 0x37, 0x4b, 0xf4, 0x16, 0x97, 0x12, + 0xa0, 0xca, 0xe2, 0x43, 0x0d, 0xe8, 0xed, 0xfc, 0xa0, 0xcc, + 0x8d, 0xf9, 0xcb, 0x47, 0x7e, 0xb8, 0x05, 0x6d, 0x87, 0xb9, + 0xb9, 0x4d, 0x39, 0x63, 0x29, 0x90, 0x4d, 0x62, 0x1e, 0x73, + 0xba, 0x32, 0x23, 0xa3, 0xb0, 0x50, 0x79, 0x1e, 0x7a, 0xa8, + 0xcc, 0x54, 0xce, 0x3e, 0x84, 0xe0, 0x2d, 0x10, 0x52, 0xc2, + 0x07, 0x70, 0xf0, 0x7a, 0x95, 0xd6, 0x80, 0x66, 0x0e, 0x3f, + 0x55, 0x56, 0xc4, 0x70, 0x31, 0xc6, 0x00, 0x54, 0x50, 0xbd, + 0xc2, 0x98, 0xd1, 0xef, 0xfb, 0xac, 0xff, 0xd9, 0xdd, 0x8f, + 0x37, 0x79, 0xa3, 0xe4, 0xb5, 0xa7, 0xce, 0x6b, 0xa7, 0x79, + 0x35, 0x79, 0x2b, 0xbb, 0x2b, 0x0b, 0x15, 0xb1 }, + { 0x14, 0xb1, 0x5a, 0xb5, 0x40, 0x54, 0x5d, 0x6e, 0x84, 0x8e, + 0xcb, 0x11, 0x4e, 0xa2, 0x06, 0xbc, 0x52, 0x8e, 0x59, 0x93, + 0x53, 0x94, 0xe9, 0x50, 0x5e, 0x9a, 0x26, 0xd3, 0x38, 0xa0, + 0x84, 0xdb, 0x3a, 0x3c, 0x16, 0xb3, 0xbd, 0xa9, 0xf3, 0x06, + 0xb3, 0xae, 0x38, 0x99, 0x4b, 0x7e, 0xf0, 0xe2, 0xc6, 0xf9, + 0xdd, 0x0d, 0xa6, 0x16, 0x5e, 0x5d, 0x22, 0x8a, 0x46, 0xe4, + 0x37, 0x8c, 0x26, 0x1d, 0xb9, 0x8e, 0xce, 0x1b, 0x0c, 0x1a, + 0x8d, 0xeb, 0xd0, 0x0e, 0x60, 0x3a, 0xbb, 0x3f, 0x82, 0x98, + 0x86, 0xec, 0xa7, 0x14, 0x32, 0x24, 0xb4, 0xf5, 0x1c, 0xc5, + 0x74, 0xcb, 0x8b, 0xdc, 0xc9, 0x0c, 0xd0, 0x28, 0x33, 0xe0, + 0x67, 0xcd, 0xca, 0xe3, 0x02, 0x17, 0x3a, 0x1f, 0xda, 0xf1, + 0xea, 0xd7, 0xdc, 0xcd, 0x5d, 0xf5, 0xff, 0x05, 0x6e, 0xeb, + 0x00, 0x0e, 0x22, 0xa8, 0x32, 0x10, 0x96, 0x4d }, + { 0x74, 0x2b, 0xbe, 0xd8, 0xc4, 0x38, 0x9e, 0x2e, 0x1e, 0x16, + 0xac, 0x76, 0x00, 0x9a, 0x55, 0xf5, 0xce, 0x57, 0xe1, 0xca, + 0x61, 0x2b, 0x57, 0x1f, 0xcb, 0xba, 0x6e, 0x30, 0x47, 0xea, + 0x72, 0x2f, 0xdf, 0x20, 0xe0, 0xe9, 0x4b, 0x63, 0xd7, 0x01, + 0xdb, 0xee, 0x97, 0xa8, 0x18, 0xfb, 0xf9, 0xfa, 0xca, 0x88, + 0x95, 0x3d, 0x60, 0x94, 0x76, 0x3c, 0xcc, 0x89, 0x6a, 0xe7, + 0x29, 0x2e, 0x9d, 0x87, 0xd6, 0xf1, 0x8d, 0x2f, 0x3f, 0x09, + 0xb4, 0xee, 0xc0, 0xad, 0x9f, 0xfa, 0xc8, 0x7b, 0x28, 0xe1, + 0xa4, 0xee, 0x0d, 0xef, 0x0d, 0x5d, 0x4e, 0x05, 0x79, 0xa0, + 0xd4, 0xe7, 0x45, 0x87, 0x08, 0x0b, 0x5f, 0x23, 0x25, 0xd9, + 0x81, 0x76, 0xa7, 0xe0, 0x33, 0xf9, 0xb5, 0x69, 0x90, 0x72, + 0xcb, 0x8e, 0x3d, 0xfe, 0x2b, 0xe1, 0x60, 0xfd, 0x7a, 0xa5, + 0x0f, 0x6d, 0x86, 0xc9, 0x66, 0x4c, 0x59, 0xa2 }, + { 0x97, 0xbd, 0x5a, 0x14, 0xb5, 0xc9, 0x41, 0x24, 0x15, 0x1e, + 0x33, 0x08, 0xf7, 0xcd, 0xd6, 0x9b, 0x71, 0x7d, 0x1c, 0xe6, + 0xe1, 0xec, 0xc1, 0x7c, 0xb3, 0x90, 0x8b, 0xbf, 0xb8, 0x65, + 0xc7, 0xf9, 0xb6, 0xbc, 0x34, 0xe8, 0x7d, 0x11, 0xe4, 0x15, + 0xed, 0x8b, 0x3d, 0xfe, 0xeb, 0x8f, 0xe0, 0xc9, 0xe6, 0xc3, + 0x5b, 0xb3, 0x4b, 0x18, 0x7c, 0x7d, 0x4c, 0x82, 0x60, 0x57, + 0x46, 0xe2, 0xa2, 0x78, 0xc8, 0xc2, 0xe0, 0x2d, 0x1f, 0x72, + 0xe0, 0x11, 0x4d, 0x88, 0xd5, 0x40, 0xe3, 0x64, 0xab, 0x94, + 0x78, 0x9d, 0xba, 0x22, 0xa9, 0xb7, 0xad, 0x78, 0x7d, 0x54, + 0xc6, 0x4b, 0x54, 0xe6, 0x6a, 0x7d, 0xde, 0x68, 0xa6, 0xe0, + 0x8c, 0xb5, 0xca, 0xc7, 0x07, 0xf8, 0xfa, 0x1f, 0x24, 0xd8, + 0xca, 0x1f, 0x4b, 0xbb, 0xfd, 0x5b, 0xc1, 0x64, 0x3a, 0xbf, + 0x23, 0xea, 0x86, 0xdc, 0xc1, 0xdc, 0x2c, 0x73 }, + { 0x31, 0x7c, 0x6d, 0x31, 0x48, 0xcc, 0x54, 0x69, 0xf8, 0x92, + 0xc5, 0x8c, 0x86, 0x4f, 0xba, 0x2e, 0x50, 0xf5, 0x3b, 0xe4, + 0xa6, 0x42, 0x4c, 0x2a, 0x4d, 0x63, 0x36, 0x7a, 0xff, 0xab, + 0xda, 0x18, 0xf0, 0x53, 0xe8, 0x48, 0x0c, 0xec, 0x8b, 0x9a, + 0xb0, 0xd9, 0xb9, 0xba, 0x26, 0xf8, 0x30, 0x5f, 0x03, 0x89, + 0xbb, 0xd8, 0xca, 0x60, 0x13, 0xc3, 0xaf, 0x77, 0xd2, 0xd1, + 0x0a, 0x8a, 0x0a, 0xf4, 0x52, 0xe8, 0x4c, 0x5f, 0xa2, 0x0c, + 0x8b, 0x96, 0x9d, 0xf7, 0x6b, 0x9b, 0x58, 0x2d, 0xe7, 0x5f, + 0xce, 0x84, 0x35, 0xa8, 0x55, 0x0f, 0x29, 0xd8, 0xb4, 0xf1, + 0x5f, 0x52, 0xc7, 0x2a, 0x45, 0xf4, 0xb8, 0xb4, 0x93, 0x74, + 0x5a, 0xbb, 0xbf, 0xdd, 0x7e, 0x52, 0xe5, 0x5b, 0xe6, 0x5e, + 0x91, 0xe5, 0x70, 0x3d, 0x4b, 0x6d, 0xdd, 0x42, 0xc4, 0x0e, + 0xe0, 0x1c, 0x62, 0xfe, 0x81, 0xe8, 0x28, 0x61 }, + { 0x6a, 0xe5, 0x97, 0x39, 0x9d, 0xa0, 0xb8, 0xfd, 0x45, 0x16, + 0x51, 0xf0, 0xee, 0x3d, 0x3f, 0x17, 0x9c, 0xc3, 0x48, 0x3c, + 0x1d, 0x90, 0x63, 0x0b, 0x37, 0x69, 0x79, 0x6a, 0xc2, 0x76, + 0x3c, 0x30, 0x49, 0x02, 0x22, 0x79, 0x52, 0x5f, 0x86, 0x36, + 0xf9, 0xd7, 0x06, 0x41, 0xec, 0xcb, 0xc1, 0x1c, 0xfc, 0x1a, + 0xe3, 0xf5, 0xef, 0xbe, 0x40, 0x08, 0x6d, 0xb9, 0x6d, 0x16, + 0xdc, 0x3f, 0x49, 0xda, 0xe9, 0xa1, 0xd2, 0x7f, 0x02, 0x2d, + 0xe1, 0x81, 0x59, 0xaf, 0xce, 0x48, 0x11, 0x0e, 0x0d, 0x6e, + 0xa0, 0x14, 0x6b, 0x5a, 0x41, 0x25, 0x2a, 0x19, 0x7f, 0xbe, + 0xf6, 0x8a, 0x71, 0x8e, 0xb2, 0x3d, 0x6b, 0x01, 0x40, 0x2f, + 0xe0, 0xc1, 0x0e, 0xa0, 0x8d, 0x5d, 0x20, 0x22, 0xff, 0x20, + 0x40, 0x8f, 0x55, 0x24, 0x0b, 0xc9, 0x31, 0x0f, 0xac, 0xae, + 0x0c, 0x35, 0x25, 0xb0, 0x2c, 0xb7, 0xd4, 0x2b }, + { 0x66, 0x49, 0x04, 0x8d, 0xbc, 0x63, 0xfe, 0x72, 0xa8, 0x4e, + 0xe5, 0xf1, 0xe7, 0x44, 0xb8, 0x2b, 0x9e, 0xf9, 0xcf, 0x3e, + 0xf1, 0x51, 0xa7, 0x26, 0x8a, 0x85, 0x95, 0xb2, 0xfa, 0x2a, + 0xff, 0xfc, 0x8f, 0xe7, 0x3b, 0xff, 0x97, 0xb6, 0x49, 0x7e, + 0x28, 0x88, 0x05, 0x34, 0xd3, 0x46, 0xf2, 0x14, 0x1a, 0x89, + 0xae, 0x22, 0xd6, 0xcf, 0x00, 0x7a, 0xb0, 0xff, 0x72, 0x26, + 0x2d, 0x97, 0xa7, 0x74, 0xee, 0x26, 0x1f, 0xb1, 0x5a, 0x2a, + 0xfa, 0x4c, 0xc5, 0x64, 0x86, 0x1f, 0xfd, 0x5f, 0x87, 0xb7, + 0xcf, 0x2c, 0x5b, 0x59, 0x8e, 0x61, 0xf9, 0x44, 0xc0, 0x6f, + 0x4a, 0x85, 0x4e, 0x0c, 0x33, 0x89, 0x1d, 0x5f, 0x23, 0x2a, + 0x5e, 0xfd, 0x55, 0xbe, 0xb6, 0x25, 0x4b, 0xd5, 0x07, 0x94, + 0x93, 0x6c, 0x20, 0x75, 0x42, 0x29, 0x30, 0xb1, 0x73, 0xd8, + 0x57, 0xb1, 0x3b, 0xc7, 0xbf, 0xf4, 0xd2, 0xee }, + { 0x4e, 0xb9, 0x3b, 0x5c, 0xf3, 0xfa, 0x49, 0xec, 0x6f, 0x2d, + 0x7a, 0xda, 0x0f, 0x13, 0x87, 0x3a, 0x3e, 0x0e, 0x98, 0xe2, + 0xa9, 0x3b, 0x0d, 0xe4, 0x96, 0xf0, 0x52, 0x6d, 0x16, 0xab, + 0xed, 0xdd, 0x2c, 0x9c, 0x1c, 0xc1, 0x83, 0xf0, 0xf1, 0xc9, + 0xfa, 0x17, 0x63, 0x77, 0xef, 0x6b, 0x1e, 0x86, 0x48, 0xb7, + 0x93, 0x56, 0xcf, 0x6c, 0x80, 0xc7, 0x09, 0x13, 0x6a, 0x6e, + 0x28, 0x30, 0xec, 0xe2, 0x85, 0x06, 0xab, 0x37, 0x9c, 0x58, + 0x1e, 0x46, 0xdc, 0xcc, 0xbf, 0xb5, 0x7d, 0x65, 0x48, 0x68, + 0x31, 0x8d, 0xbc, 0x70, 0x34, 0xb0, 0xab, 0x0b, 0x5a, 0x03, + 0x2f, 0x8a, 0xa2, 0x9b, 0xe3, 0xdb, 0x4a, 0x6d, 0xd2, 0x26, + 0xbf, 0xfc, 0x14, 0x8e, 0x81, 0x49, 0x3d, 0x9f, 0xfa, 0xb5, + 0x22, 0x6f, 0xd4, 0x7b, 0x0b, 0xd8, 0x25, 0xaa, 0xda, 0xa0, + 0x91, 0xb7, 0xbb, 0x78, 0x1e, 0x8b, 0x76, 0x0d }, + { 0x2b, 0x58, 0x2d, 0x93, 0x7c, 0x04, 0x3f, 0x68, 0xcd, 0xf5, + 0xc9, 0x0b, 0xc7, 0x00, 0x1c, 0xc8, 0x53, 0xe7, 0x81, 0xde, + 0x86, 0x80, 0x41, 0x72, 0x56, 0x05, 0xe2, 0x23, 0xe9, 0xc6, + 0xc4, 0xe0, 0xbf, 0x56, 0x54, 0x06, 0xa1, 0x9d, 0x48, 0xb6, + 0x82, 0xcf, 0xfd, 0xb3, 0xd9, 0x9f, 0x0c, 0x16, 0x18, 0x9a, + 0x5c, 0xc8, 0xbd, 0x8a, 0x68, 0x78, 0x12, 0xae, 0xef, 0xef, + 0xef, 0x3d, 0x51, 0x73, 0x93, 0x1c, 0x3f, 0x52, 0x75, 0x87, + 0x8a, 0x2a, 0xaf, 0xbb, 0xb6, 0x85, 0xfd, 0x33, 0x67, 0x6f, + 0x82, 0x22, 0x24, 0x19, 0xc1, 0x3c, 0xa2, 0xca, 0xbb, 0x9e, + 0x88, 0x97, 0x05, 0xba, 0x00, 0x68, 0x1d, 0x84, 0x9a, 0x57, + 0x55, 0x52, 0x79, 0xb7, 0x1b, 0x00, 0x14, 0xdf, 0x49, 0x1c, + 0x3f, 0x6f, 0xd1, 0x3d, 0x74, 0xf5, 0xc4, 0x02, 0x3f, 0x51, + 0xbd, 0x89, 0xf7, 0xe5, 0xe1, 0x1f, 0xae, 0x32 }, + { 0x78, 0x61, 0x51, 0x09, 0x86, 0x2d, 0xb4, 0xc0, 0x4f, 0xa4, + 0x9c, 0xe3, 0xfa, 0x57, 0x4a, 0xfd, 0xc1, 0xd8, 0xeb, 0x48, + 0xeb, 0x7c, 0xee, 0x9a, 0x4b, 0xee, 0x10, 0xd7, 0xb3, 0xf2, + 0xf7, 0xaa, 0xfe, 0x8e, 0x33, 0xcd, 0xe9, 0x3a, 0xcf, 0xcd, + 0x91, 0x5c, 0x3d, 0x06, 0xf5, 0x08, 0x64, 0xa3, 0x71, 0xcb, + 0x93, 0x6b, 0x83, 0x1e, 0xdd, 0xfb, 0xa8, 0xe3, 0x92, 0x64, + 0x9e, 0x34, 0x8c, 0x09, 0xce, 0xed, 0x17, 0x2c, 0x2f, 0x11, + 0xc4, 0x1c, 0x85, 0xe2, 0x11, 0x03, 0xd9, 0xef, 0xf3, 0x2a, + 0x78, 0x75, 0x0d, 0xb4, 0xc9, 0x8d, 0xbd, 0xd5, 0xdc, 0xba, + 0xc9, 0xf3, 0xb5, 0x7f, 0xa2, 0x1c, 0x5d, 0x60, 0x38, 0x26, + 0x54, 0x77, 0x65, 0x06, 0xc0, 0x97, 0xb3, 0xd2, 0x07, 0xff, + 0xf6, 0x6f, 0xa7, 0x33, 0x80, 0xf5, 0xe2, 0xb6, 0x9e, 0xca, + 0xa1, 0x16, 0x5c, 0x82, 0x81, 0xab, 0xc2, 0xae }, + { 0x54, 0x0b, 0x6b, 0xb7, 0x6b, 0xc9, 0xc0, 0x25, 0x9f, 0x9a, + 0x28, 0xab, 0x84, 0x16, 0x1c, 0x68, 0x6d, 0x51, 0xf9, 0x3c, + 0x3a, 0xa9, 0x56, 0xf9, 0xb4, 0xd8, 0x0e, 0xc0, 0xc3, 0xaf, + 0xa2, 0xcf, 0x64, 0x37, 0x36, 0x05, 0x54, 0x28, 0xde, 0xb5, + 0x0c, 0x8a, 0xdc, 0x05, 0x34, 0x37, 0x4c, 0x20, 0x18, 0xd4, + 0x04, 0xe4, 0x67, 0xb8, 0xe8, 0x7b, 0x57, 0xb7, 0x8b, 0x93, + 0x8e, 0xec, 0x6e, 0x1e, 0x9b, 0x0a, 0x43, 0xee, 0x28, 0x4d, + 0x3c, 0xcf, 0xbb, 0xe4, 0xed, 0x12, 0xf4, 0x27, 0xef, 0x5a, + 0x7a, 0x14, 0xcf, 0xfe, 0x82, 0xbd, 0x5f, 0xcd, 0x2a, 0x3a, + 0x43, 0x97, 0xd7, 0xcd, 0xbb, 0x24, 0x37, 0x9a, 0xe0, 0x94, + 0x51, 0xb4, 0xf1, 0xab, 0xc7, 0x6e, 0xe1, 0xe8, 0xf8, 0xc3, + 0xa4, 0x54, 0x63, 0x1a, 0xa1, 0x44, 0xfd, 0x0f, 0x0d, 0xa5, + 0x3f, 0xe3, 0xf4, 0x80, 0x7a, 0xe7, 0x2c, 0x21 }, + { 0x89, 0x7c, 0xab, 0x14, 0x92, 0xe0, 0x38, 0x8c, 0x2c, 0xa2, + 0x58, 0x67, 0x52, 0xdd, 0x50, 0xf6, 0xe1, 0xc2, 0x87, 0x76, + 0x5e, 0x20, 0xe8, 0x18, 0x3d, 0xb7, 0xd1, 0xa3, 0x44, 0x61, + 0xcd, 0x29, 0xe0, 0xb5, 0x05, 0xa1, 0x75, 0x02, 0x05, 0x38, + 0xf6, 0x9d, 0x98, 0xf0, 0x7c, 0xad, 0xf0, 0xe9, 0xdc, 0xe7, + 0xda, 0xbe, 0x0c, 0x92, 0x4d, 0x60, 0x2a, 0x97, 0x3d, 0x97, + 0xaa, 0xbf, 0x65, 0x85, 0x43, 0xaf, 0xbc, 0x78, 0xea, 0x36, + 0x2f, 0x45, 0x43, 0x6d, 0xb2, 0x93, 0x1d, 0x62, 0x98, 0xeb, + 0x2e, 0x4a, 0x83, 0x7e, 0xb9, 0xbc, 0x53, 0xde, 0x6a, 0x21, + 0xe9, 0xad, 0x58, 0x77, 0x57, 0x0f, 0x1f, 0xb0, 0x7a, 0x49, + 0xac, 0xdc, 0x78, 0x9a, 0xea, 0xfa, 0xe1, 0x45, 0xbb, 0xa8, + 0xcd, 0x81, 0x4e, 0xf5, 0x66, 0x12, 0xd8, 0x6e, 0x05, 0xd0, + 0x04, 0xe1, 0x73, 0x4c, 0x32, 0x1d, 0x31, 0x5d }, + { 0x64, 0xb0, 0x07, 0x63, 0x47, 0x6b, 0x0e, 0xc5, 0xdc, 0x62, + 0xc4, 0xa4, 0xff, 0xf6, 0x73, 0xaa, 0x2f, 0xf4, 0x7d, 0xac, + 0x30, 0xeb, 0x93, 0xa5, 0x2c, 0x82, 0x2e, 0x67, 0x20, 0xa5, + 0x18, 0x2d, 0xab, 0x90, 0x6b, 0xa3, 0xbf, 0x6c, 0xd9, 0x49, + 0x82, 0xf6, 0x29, 0xaa, 0xa6, 0xc2, 0x4f, 0xa6, 0x56, 0x4f, + 0x2a, 0x4d, 0xcf, 0x0a, 0xc9, 0x3e, 0x44, 0xf8, 0xf7, 0xfb, + 0x14, 0xfa, 0x88, 0xd2, 0xd8, 0x83, 0x62, 0x8b, 0x6c, 0x91, + 0x2f, 0xe0, 0x70, 0xd2, 0xed, 0x84, 0x0d, 0x1a, 0x83, 0x1e, + 0x74, 0x98, 0x4b, 0x11, 0xf3, 0x83, 0x37, 0x1c, 0x44, 0x92, + 0x81, 0x05, 0xb9, 0x74, 0x11, 0xa0, 0x86, 0xad, 0x0d, 0x3a, + 0x7a, 0xc8, 0x96, 0x74, 0x06, 0x87, 0xbf, 0x2c, 0x40, 0x58, + 0x14, 0x15, 0xc1, 0x1d, 0x36, 0x4c, 0xa4, 0x38, 0x20, 0x0a, + 0x59, 0xed, 0x38, 0x13, 0x0d, 0x8b, 0xab, 0x8a }, + { 0x7d, 0xd2, 0x2e, 0xa6, 0x66, 0x18, 0xed, 0x8c, 0x29, 0x1f, + 0xb8, 0x2c, 0x09, 0xe5, 0x0e, 0x84, 0x25, 0x55, 0x94, 0x24, + 0x19, 0xd6, 0x8e, 0x36, 0xe3, 0x92, 0x51, 0x53, 0x57, 0x6c, + 0xa9, 0x64, 0x0b, 0x52, 0xc3, 0x9f, 0xb0, 0x70, 0xa2, 0x93, + 0x80, 0x17, 0x8b, 0x12, 0xc2, 0x37, 0x00, 0x2a, 0xfb, 0xc7, + 0x6f, 0x56, 0xe1, 0x21, 0x7a, 0x95, 0x42, 0xda, 0xf0, 0xbb, + 0x9e, 0xf5, 0x55, 0x1c, 0x21, 0x7c, 0xab, 0x32, 0xc3, 0x9b, + 0x5a, 0xcf, 0x3f, 0x8f, 0xc0, 0x9d, 0xdc, 0x08, 0x4e, 0x01, + 0xd8, 0x78, 0x49, 0x35, 0x01, 0xec, 0x5c, 0xf1, 0xcc, 0xfd, + 0x3b, 0x33, 0xce, 0x26, 0xca, 0xd0, 0x7c, 0xe7, 0xf4, 0xc4, + 0x07, 0x38, 0xee, 0xd4, 0xc7, 0xf1, 0x3e, 0x29, 0x6c, 0x25, + 0x36, 0x93, 0xb1, 0xdb, 0x7f, 0x73, 0xb7, 0xef, 0x99, 0x52, + 0x1e, 0x3f, 0x53, 0x3e, 0xb3, 0xc9, 0xa4, 0x04 }, + { 0x31, 0x37, 0x7c, 0x66, 0x5f, 0x18, 0xfc, 0xc8, 0x95, 0x59, + 0xc8, 0x8a, 0xb1, 0x3b, 0x74, 0x89, 0x5c, 0x8f, 0x98, 0xfc, + 0x51, 0xca, 0xdf, 0x0f, 0x68, 0x5f, 0xf9, 0x4b, 0xbd, 0x3b, + 0x9d, 0x82, 0x95, 0xf9, 0x49, 0x30, 0xda, 0xc6, 0xf7, 0x90, + 0x60, 0xaf, 0xd4, 0x47, 0xb6, 0xf6, 0xa9, 0x16, 0x41, 0x64, + 0x03, 0xc1, 0x14, 0x14, 0xa4, 0x85, 0x67, 0xa9, 0xf6, 0x33, + 0x20, 0x1a, 0x42, 0x37, 0x6b, 0x0d, 0x3d, 0xdd, 0x83, 0x24, + 0x7b, 0x72, 0x8c, 0xf4, 0xeb, 0x32, 0x82, 0xe5, 0x74, 0x2b, + 0x39, 0xa1, 0x48, 0x92, 0x96, 0x95, 0x7f, 0x34, 0x2c, 0x75, + 0xd4, 0xb9, 0x30, 0x63, 0x57, 0x18, 0x95, 0x6d, 0x7f, 0x26, + 0xe5, 0x12, 0x77, 0xfc, 0x1e, 0x6e, 0xe5, 0x37, 0x9f, 0x5a, + 0x84, 0x5a, 0xde, 0x0c, 0xc7, 0x04, 0x55, 0x62, 0xfb, 0x25, + 0x7f, 0xfe, 0x84, 0x4b, 0x49, 0xcb, 0xb3, 0xbf }, + { 0x3d, 0xac, 0xc5, 0x0c, 0xa1, 0x1e, 0x52, 0x71, 0x3a, 0x5f, + 0xd6, 0x95, 0x58, 0x7e, 0xda, 0xbd, 0xef, 0x45, 0x42, 0x3c, + 0x64, 0x8a, 0x01, 0x79, 0xe2, 0x89, 0xd0, 0x24, 0x0c, 0x8f, + 0x45, 0x24, 0xb3, 0x5a, 0x98, 0x24, 0x00, 0xd5, 0xe4, 0x67, + 0xd8, 0xf9, 0x93, 0xb6, 0x05, 0x62, 0x4d, 0xd2, 0xfc, 0xf3, + 0x64, 0xfa, 0xa9, 0x50, 0x70, 0xe0, 0x44, 0x09, 0x76, 0x63, + 0x03, 0xd3, 0xe6, 0x0a, 0xe5, 0x2e, 0xfb, 0x53, 0x69, 0xe9, + 0x0a, 0x6f, 0x43, 0x98, 0x80, 0xcf, 0x25, 0x96, 0xda, 0xd2, + 0x75, 0x2e, 0xd1, 0x59, 0x71, 0xbf, 0xe6, 0x07, 0x9d, 0x95, + 0xcd, 0x4f, 0xb0, 0x9a, 0x19, 0xb5, 0x0c, 0x2d, 0xd4, 0x8a, + 0xf7, 0xb4, 0xb3, 0x75, 0x7e, 0x93, 0xe8, 0x5d, 0x75, 0x76, + 0xcb, 0x63, 0x2d, 0xcc, 0xca, 0x9f, 0x01, 0xcc, 0x36, 0xf8, + 0x35, 0xc5, 0xde, 0x09, 0x7d, 0xcf, 0xb3, 0x5f }, + { 0x86, 0x69, 0x49, 0xe1, 0x69, 0x47, 0x44, 0xf7, 0x46, 0x9b, + 0x75, 0x61, 0x23, 0x24, 0x8a, 0x31, 0xbe, 0xd3, 0xf2, 0xc3, + 0xe0, 0x69, 0xdf, 0x05, 0x5d, 0xd2, 0xdf, 0x7a, 0x60, 0xdf, + 0x19, 0x4d, 0xcd, 0x1e, 0xfd, 0xb4, 0xf3, 0xe9, 0xdf, 0x64, + 0x6f, 0xd5, 0x76, 0x87, 0xf9, 0xdd, 0x9f, 0x0a, 0x7a, 0xb2, + 0x44, 0x04, 0xb1, 0x7b, 0x28, 0x42, 0xe5, 0x1a, 0x0d, 0x53, + 0x88, 0x07, 0xf3, 0xa0, 0x0a, 0x9b, 0xa3, 0x85, 0xb9, 0xbf, + 0xd2, 0xfb, 0xf3, 0xfb, 0x62, 0x10, 0xae, 0xc2, 0x3e, 0xaf, + 0xf7, 0xb7, 0xb9, 0xba, 0xdf, 0x1c, 0xdb, 0x49, 0xf3, 0x5e, + 0x45, 0x18, 0xaa, 0x28, 0x6f, 0xd0, 0xb6, 0xc6, 0x4d, 0x28, + 0xd8, 0x48, 0x1e, 0x45, 0x80, 0x7f, 0x5c, 0xe9, 0xbe, 0x78, + 0x2e, 0x8a, 0xa4, 0x6d, 0xcb, 0xe1, 0x70, 0x53, 0xc5, 0x27, + 0xcb, 0x3e, 0x4f, 0x94, 0x64, 0x99, 0xae, 0x4c }, + { 0x57, 0x43, 0x52, 0xb8, 0x8b, 0x1f, 0xa5, 0x98, 0xdc, 0x38, + 0x84, 0xff, 0x5b, 0x08, 0x31, 0x77, 0xc2, 0xd3, 0x83, 0x73, + 0x94, 0xf7, 0xec, 0x4e, 0x37, 0xa5, 0x05, 0x69, 0xc2, 0x95, + 0xdc, 0x46, 0xfa, 0x84, 0x4e, 0xb0, 0x7b, 0x96, 0xd4, 0x80, + 0x0d, 0x2b, 0x84, 0x1b, 0x33, 0x29, 0xdb, 0x82, 0x85, 0x2d, + 0x44, 0x35, 0x4e, 0x2d, 0x5d, 0xd0, 0xd7, 0x9d, 0xb1, 0xbb, + 0xd7, 0x4c, 0x70, 0x91, 0x3b, 0x66, 0x4b, 0x1e, 0x7d, 0x08, + 0x77, 0xb5, 0x50, 0x01, 0x39, 0x4e, 0x99, 0x0c, 0x03, 0xa0, + 0x38, 0x59, 0x8e, 0xa1, 0x06, 0x6c, 0xb4, 0xd7, 0x93, 0xaf, + 0x1f, 0xbd, 0xd3, 0xb2, 0x18, 0xab, 0xc9, 0x58, 0x1c, 0x3e, + 0x84, 0x8e, 0x3d, 0x58, 0x0c, 0x92, 0xe9, 0x21, 0xb2, 0x3c, + 0xf2, 0x90, 0x2c, 0xd6, 0xf3, 0x33, 0xf5, 0x4a, 0x6f, 0xbf, + 0x3a, 0x9a, 0x0d, 0xa5, 0x3f, 0x4a, 0xb0, 0x7a }, + { 0x3e, 0x43, 0x1a, 0xf2, 0x06, 0xae, 0x3c, 0x4f, 0x24, 0x18, + 0xc6, 0x24, 0xd3, 0xb6, 0xa3, 0xa1, 0x38, 0x84, 0xd5, 0xd8, + 0xf8, 0x53, 0xa9, 0x4e, 0x5f, 0xcb, 0xcc, 0x09, 0x69, 0x96, + 0x01, 0x1a, 0x44, 0x45, 0x21, 0xa1, 0x09, 0x9f, 0x68, 0x73, + 0x3f, 0x20, 0x43, 0x40, 0xd2, 0x94, 0x64, 0x93, 0x25, 0x3a, + 0x3a, 0x69, 0xf0, 0xd6, 0x78, 0x2b, 0xa9, 0x63, 0x35, 0xbc, + 0x09, 0x1c, 0x19, 0xeb, 0x4e, 0x76, 0x48, 0xc7, 0x61, 0xc2, + 0x20, 0x1d, 0x99, 0x6c, 0xca, 0xf0, 0xde, 0x20, 0x28, 0xd8, + 0x2e, 0xc2, 0x7e, 0x49, 0x28, 0x59, 0x85, 0xdf, 0x8a, 0x84, + 0xec, 0x00, 0xba, 0xa7, 0x01, 0x98, 0xdd, 0x9d, 0xa8, 0x60, + 0x78, 0x27, 0x0d, 0x56, 0x7c, 0x44, 0xab, 0x59, 0x7b, 0xe6, + 0x5f, 0xd0, 0x3c, 0x19, 0xfd, 0x26, 0x0b, 0x48, 0x7e, 0xaf, + 0xed, 0x21, 0x93, 0xf7, 0x0d, 0x5d, 0x7c, 0xe9 }, + { 0x6d, 0xad, 0x3f, 0x15, 0xe2, 0x66, 0x4d, 0x35, 0x1c, 0x3d, + 0x7d, 0x82, 0xa2, 0x03, 0xce, 0xf1, 0x8a, 0x0f, 0xbb, 0xd1, + 0x86, 0xbb, 0xfa, 0x41, 0xf2, 0x69, 0x31, 0xba, 0xad, 0x89, + 0x6c, 0x2a, 0xcd, 0x57, 0x76, 0x66, 0x53, 0xbb, 0xb3, 0x43, + 0x4f, 0x1c, 0x96, 0x86, 0x11, 0xe9, 0x35, 0xc5, 0x7f, 0xc2, + 0xa3, 0xed, 0x85, 0x1e, 0xe4, 0x1e, 0xfd, 0x1b, 0xfe, 0x44, + 0x1a, 0x94, 0x2f, 0x7d, 0x33, 0x6a, 0x4f, 0xda, 0xae, 0xfd, + 0xb6, 0x46, 0xd0, 0x90, 0xa6, 0xa3, 0xaa, 0x45, 0x6d, 0x6f, + 0xfe, 0xb2, 0xaf, 0xa6, 0x36, 0xf0, 0xb7, 0x55, 0x43, 0xae, + 0x07, 0x41, 0xd9, 0x2f, 0x29, 0x00, 0xa8, 0x6d, 0x15, 0x98, + 0x50, 0x93, 0xa6, 0xd3, 0xbf, 0x3a, 0xf4, 0xd0, 0x54, 0x41, + 0x07, 0x68, 0x36, 0x50, 0x1a, 0xae, 0xd0, 0xc0, 0x33, 0xc3, + 0xf9, 0x67, 0xd9, 0x39, 0x83, 0xd3, 0x81, 0xf1 }, + { 0x24, 0x38, 0xe9, 0xd4, 0x5f, 0x51, 0x7a, 0x3f, 0xc8, 0x7a, + 0x53, 0x90, 0x27, 0xd2, 0xd5, 0x5f, 0xfc, 0x3e, 0xe7, 0xc6, + 0x0b, 0xff, 0x83, 0x7c, 0x56, 0x59, 0x0b, 0xa4, 0x93, 0x83, + 0xd2, 0xd3, 0x08, 0xe5, 0x84, 0x48, 0x67, 0x23, 0x75, 0xc5, + 0x11, 0x09, 0xa6, 0x13, 0xdf, 0x3a, 0x8d, 0xc3, 0x51, 0x7f, + 0x2f, 0x1d, 0xbe, 0xbd, 0x01, 0x29, 0xb0, 0x69, 0x59, 0x9d, + 0xf8, 0x95, 0x8c, 0x6f, 0x7a, 0x41, 0x40, 0x21, 0x71, 0x98, + 0xb2, 0x1b, 0x97, 0x4a, 0x9f, 0x03, 0x8c, 0x0a, 0xcb, 0xa7, + 0x06, 0x1b, 0xc9, 0x26, 0xc3, 0xd9, 0x6a, 0x19, 0x15, 0x09, + 0x0f, 0x55, 0xd9, 0x90, 0x3c, 0x43, 0x5e, 0x76, 0x90, 0x4a, + 0x33, 0xc5, 0x8e, 0xb6, 0x2c, 0xc2, 0x78, 0xc6, 0xf1, 0x33, + 0x21, 0xd5, 0x62, 0x19, 0xc5, 0xb6, 0xe7, 0xdf, 0xb1, 0x28, + 0xd1, 0x94, 0x0b, 0x7d, 0x12, 0xec, 0x35, 0xa1 }, + { 0x13, 0xf3, 0x90, 0x11, 0xaf, 0xe3, 0x0e, 0x01, 0x00, 0xa8, + 0xb7, 0xb2, 0x96, 0x20, 0x0e, 0x67, 0x9d, 0x2a, 0x97, 0xcd, + 0xff, 0x79, 0x5b, 0xb3, 0xf4, 0xad, 0xa5, 0x11, 0xbd, 0x41, + 0x6b, 0x67, 0xdd, 0xb4, 0x7c, 0x73, 0x68, 0xf1, 0xf7, 0xf2, + 0x8b, 0x33, 0xef, 0x46, 0x2a, 0x51, 0x34, 0x90, 0xf1, 0xb4, + 0x63, 0x3c, 0xd7, 0x70, 0x1f, 0x5b, 0x20, 0x5b, 0x4c, 0x89, + 0x1b, 0xe2, 0x81, 0xcb, 0x71, 0x50, 0xe0, 0x4b, 0x6b, 0xbc, + 0x4f, 0xb1, 0xf7, 0x37, 0xc3, 0xc2, 0xf1, 0xda, 0x60, 0x10, + 0x6f, 0x14, 0x42, 0x9c, 0xd0, 0xb3, 0xe2, 0x31, 0xbd, 0x0d, + 0xac, 0x54, 0xe6, 0x3f, 0x24, 0x90, 0x61, 0xc6, 0x1d, 0x94, + 0x12, 0xe5, 0x1e, 0xb5, 0xae, 0xf1, 0xcd, 0xc9, 0x97, 0xb6, + 0x5d, 0xdf, 0xe5, 0x5f, 0x1a, 0x32, 0xf3, 0xc9, 0xbe, 0xd5, + 0xc4, 0xa4, 0x53, 0x08, 0x88, 0x15, 0xaf, 0x3c }, + { 0x45, 0x8d, 0x4b, 0x6b, 0x68, 0x07, 0x03, 0xb6, 0x17, 0xa7, + 0xce, 0x24, 0xcb, 0xda, 0x1b, 0x0b, 0x29, 0x84, 0x66, 0xd4, + 0x72, 0x2b, 0x7b, 0xc9, 0xbc, 0x07, 0x5b, 0x73, 0xd8, 0xc4, + 0xba, 0x8b, 0x33, 0xdd, 0x77, 0xa0, 0x1c, 0xf2, 0xb8, 0x66, + 0x24, 0x97, 0xe0, 0xbf, 0xa4, 0xd8, 0xd0, 0x18, 0xfe, 0x31, + 0x1a, 0xd0, 0x1b, 0xbd, 0xa0, 0x05, 0xce, 0xea, 0x99, 0xd5, + 0x56, 0x41, 0x51, 0x10, 0x29, 0x3b, 0xb5, 0xe7, 0x53, 0x5c, + 0x5d, 0x0b, 0x2a, 0x83, 0x8c, 0xa8, 0x26, 0x3b, 0x60, 0x62, + 0x3f, 0x90, 0xd7, 0x10, 0x68, 0xc0, 0xe5, 0x84, 0xcb, 0xb8, + 0x30, 0x24, 0x99, 0x80, 0x45, 0xdf, 0xde, 0x8d, 0x80, 0x45, + 0x26, 0x8b, 0xca, 0x77, 0xf8, 0x79, 0x30, 0x68, 0x1c, 0x9a, + 0x51, 0x5a, 0x50, 0x61, 0x10, 0xf3, 0x4a, 0x29, 0xff, 0x46, + 0x3d, 0xd2, 0x96, 0xef, 0x7b, 0xd0, 0xc8, 0x27 }, + { 0x5f, 0x13, 0xf5, 0xfa, 0xb6, 0xfb, 0xbf, 0x91, 0x62, 0x8e, + 0x3b, 0x06, 0x56, 0x68, 0xf9, 0x5c, 0x00, 0xae, 0x04, 0x57, + 0x62, 0x4d, 0xb0, 0x1a, 0x32, 0x59, 0xef, 0x18, 0x2f, 0x72, + 0x55, 0x6b, 0x68, 0xef, 0x0b, 0x70, 0x8f, 0x27, 0xd4, 0x9f, + 0x21, 0xae, 0x03, 0x19, 0x97, 0x84, 0x70, 0x64, 0xfe, 0x5b, + 0x5c, 0xb5, 0x85, 0xc9, 0xeb, 0x8a, 0x3e, 0xfc, 0x2e, 0x9b, + 0x1b, 0x48, 0x20, 0xc3, 0xea, 0xe9, 0x5e, 0xa5, 0x99, 0x23, + 0x02, 0x20, 0xe1, 0x0a, 0x14, 0x49, 0xa1, 0xb3, 0x64, 0x10, + 0x46, 0xb9, 0xb0, 0x00, 0x73, 0x04, 0x02, 0xbd, 0x18, 0x12, + 0xe8, 0x19, 0x36, 0x94, 0xd0, 0x0d, 0x7a, 0x4a, 0xdc, 0x3c, + 0x2f, 0x65, 0x49, 0xa8, 0x69, 0x8b, 0x58, 0x58, 0xf9, 0x94, + 0xf7, 0x00, 0x05, 0xa5, 0x69, 0x6e, 0x4d, 0x32, 0x0a, 0x0d, + 0x8a, 0x26, 0xa2, 0x0e, 0x4d, 0x54, 0xd8, 0xb2 }, + { 0x21, 0x96, 0x49, 0x5d, 0xa3, 0x7b, 0xa4, 0xa2, 0x11, 0x62, + 0x5a, 0x44, 0x05, 0xf8, 0x02, 0xf6, 0x35, 0x0d, 0xc5, 0x65, + 0x6f, 0x5a, 0x17, 0x4d, 0x7c, 0x0a, 0x3c, 0x53, 0x17, 0x71, + 0x3a, 0x1a, 0x37, 0xc9, 0xe3, 0xa2, 0xe8, 0x03, 0xe6, 0x9c, + 0x90, 0xac, 0xb2, 0x90, 0x25, 0xce, 0xc9, 0x9c, 0x73, 0x71, + 0x3e, 0x66, 0x55, 0xbf, 0x1c, 0xa7, 0x0e, 0xed, 0x92, 0xdf, + 0x6b, 0x9c, 0x48, 0x2d, 0xfd, 0xf0, 0xec, 0xe7, 0xc3, 0x59, + 0x89, 0xca, 0x1f, 0x0f, 0xdf, 0x17, 0x7d, 0x11, 0x67, 0x4e, + 0xf7, 0x41, 0xc8, 0xf2, 0x29, 0x0d, 0xf0, 0x5c, 0xc4, 0xd3, + 0x31, 0x7b, 0x68, 0x21, 0x7f, 0xfd, 0xde, 0xfa, 0x6a, 0xbc, + 0x9a, 0x66, 0xe3, 0xab, 0xea, 0x66, 0xbf, 0x88, 0xea, 0x8b, + 0x36, 0x77, 0xae, 0xa1, 0xbd, 0xe9, 0x6f, 0x88, 0x3e, 0xc8, + 0x7c, 0x6e, 0xd9, 0xae, 0x3a, 0x9b, 0x0d, 0xc6 }, + { 0x93, 0xad, 0x0e, 0xb0, 0x04, 0x47, 0x5f, 0x08, 0x29, 0x71, + 0xce, 0xa7, 0x3d, 0x56, 0xfa, 0x62, 0x5a, 0xa0, 0xc4, 0x7d, + 0x6c, 0xe5, 0x48, 0xa0, 0x04, 0xa1, 0x79, 0x40, 0xd2, 0x18, + 0x97, 0xc1, 0x33, 0xef, 0x7b, 0xc3, 0x42, 0x7f, 0x34, 0x35, + 0x2c, 0x3c, 0x8c, 0xbd, 0x14, 0x41, 0x54, 0xb0, 0x9f, 0xf1, + 0x09, 0x52, 0x9a, 0xaa, 0xa4, 0x04, 0xc4, 0x8e, 0xfc, 0x6b, + 0x95, 0xb1, 0x97, 0xf9, 0xf3, 0x69, 0x31, 0x29, 0x8e, 0x8f, + 0x7d, 0xb5, 0x97, 0x09, 0xbc, 0x28, 0x51, 0x6e, 0xc8, 0xec, + 0x84, 0xad, 0xb1, 0xa2, 0xd7, 0x38, 0xf1, 0xff, 0x3c, 0x2b, + 0x79, 0x86, 0xcb, 0x6e, 0xc2, 0x50, 0xbe, 0xef, 0xce, 0x58, + 0x0a, 0xe2, 0x2b, 0xc5, 0xc6, 0xa0, 0xce, 0xab, 0xdf, 0xe2, + 0x66, 0x9e, 0xab, 0x9e, 0x91, 0xd7, 0x65, 0xd1, 0x4c, 0xf4, + 0x00, 0xcb, 0x2f, 0xd3, 0x13, 0x14, 0x26, 0x80 }, + { 0x73, 0xf8, 0xc3, 0xf0, 0xea, 0x41, 0xc0, 0x34, 0x44, 0x08, + 0xdd, 0x42, 0x58, 0x44, 0xd1, 0xf9, 0x2b, 0x95, 0x22, 0x09, + 0x57, 0x6e, 0x58, 0x8d, 0xc5, 0xfc, 0x88, 0xd5, 0x44, 0x17, + 0xea, 0xde, 0x05, 0x86, 0xf7, 0x2f, 0xbc, 0xcd, 0xe4, 0x51, + 0xe5, 0x67, 0x4c, 0x4b, 0xf8, 0x23, 0xd7, 0x97, 0xef, 0x8a, + 0x94, 0x48, 0xc9, 0x01, 0x6c, 0x8c, 0x1d, 0x56, 0x46, 0xb8, + 0x14, 0x3f, 0xe0, 0x79, 0xc0, 0x4e, 0xd0, 0xb7, 0x26, 0xe6, + 0x62, 0xf7, 0x25, 0x4c, 0x05, 0xc3, 0xe0, 0x2f, 0xcc, 0xcf, + 0x18, 0xf6, 0xf0, 0x9c, 0x13, 0x02, 0xe3, 0x23, 0x3c, 0x38, + 0xd3, 0xfb, 0x68, 0x7a, 0x5b, 0x3d, 0x63, 0xa9, 0xb8, 0xd5, + 0xd3, 0x39, 0x22, 0xde, 0x62, 0x74, 0xe3, 0x86, 0x3b, 0x6b, + 0x50, 0xf2, 0x61, 0xe4, 0x77, 0xf7, 0x65, 0x15, 0xe8, 0xdd, + 0x7a, 0x0b, 0x69, 0x67, 0x98, 0x8a, 0x99, 0x63 }, + { 0x01, 0x08, 0xae, 0x39, 0xad, 0xbe, 0xdd, 0x75, 0xdf, 0xed, + 0x25, 0xd9, 0x7c, 0xaa, 0x51, 0xb8, 0x7c, 0xf9, 0xd4, 0x07, + 0x21, 0x34, 0x1a, 0x8a, 0x0f, 0x26, 0x87, 0x45, 0xfc, 0xa3, + 0x25, 0xe4, 0xa2, 0xe0, 0x58, 0xfc, 0xb1, 0x5a, 0xe2, 0x06, + 0xa1, 0x4e, 0x05, 0x52, 0x2d, 0x16, 0xe3, 0x61, 0x96, 0x3d, + 0xee, 0xa6, 0x28, 0xb7, 0x91, 0xcc, 0xef, 0xff, 0x6d, 0xae, + 0x33, 0x21, 0xed, 0xcd, 0x74, 0x9e, 0x0d, 0x98, 0xea, 0x36, + 0xa0, 0x15, 0x62, 0x6e, 0xec, 0xf1, 0x29, 0x3a, 0xa8, 0xcf, + 0xaa, 0x58, 0x44, 0x28, 0x51, 0x9f, 0x7b, 0xf3, 0x78, 0x04, + 0xc9, 0xad, 0x85, 0x7c, 0xae, 0xa6, 0x1d, 0x39, 0x09, 0x44, + 0xcb, 0x20, 0x88, 0x8e, 0x0d, 0xb5, 0xbe, 0x17, 0x6e, 0x8f, + 0x15, 0xa0, 0x3b, 0x14, 0x27, 0xf3, 0x3a, 0xc7, 0x18, 0x36, + 0x89, 0x53, 0x4f, 0xc8, 0x5d, 0xf7, 0x63, 0xdd }, + { 0x80, 0x7c, 0x06, 0xd8, 0xeb, 0x13, 0xc1, 0xdf, 0x34, 0x8b, + 0xb4, 0x2f, 0xa0, 0xc4, 0x52, 0x33, 0x88, 0x48, 0x08, 0x9b, + 0xac, 0x85, 0xa4, 0xe1, 0xdf, 0xfc, 0x46, 0xab, 0xd5, 0x09, + 0x7e, 0x1f, 0x0c, 0x9a, 0xad, 0x75, 0x44, 0x5d, 0xad, 0x00, + 0x88, 0x89, 0x1e, 0x36, 0xfb, 0x3a, 0x9b, 0x17, 0xfb, 0xbe, + 0x4b, 0xe8, 0x1e, 0xe0, 0xa5, 0x99, 0xc3, 0xf6, 0x5b, 0x99, + 0x46, 0xc5, 0xda, 0xfc, 0xdd, 0xc8, 0x38, 0x03, 0x9d, 0x59, + 0x51, 0x1a, 0x16, 0xaf, 0x05, 0x99, 0x0c, 0xc6, 0x9c, 0x89, + 0xfc, 0x8b, 0xef, 0xe7, 0x54, 0xe3, 0x09, 0x0b, 0xde, 0x10, + 0xb0, 0x73, 0xe9, 0xbb, 0x00, 0x4d, 0x24, 0xdb, 0x7d, 0xae, + 0x8d, 0x0b, 0x91, 0xc8, 0x77, 0x3a, 0x53, 0xe6, 0xe2, 0x61, + 0xd8, 0xa6, 0xaa, 0x05, 0xb1, 0x1e, 0xab, 0x0c, 0x73, 0x25, + 0x54, 0xd1, 0x78, 0xf3, 0xa9, 0xe8, 0x8f, 0x63 }, + { 0x16, 0x42, 0x4c, 0x6c, 0x99, 0x60, 0x7a, 0x61, 0xb2, 0xfd, + 0xfa, 0x36, 0xb5, 0x53, 0x99, 0xfc, 0x26, 0x92, 0xc6, 0x26, + 0x17, 0x58, 0x3b, 0x53, 0xaa, 0xc4, 0xff, 0xcf, 0xc3, 0x9b, + 0x06, 0x34, 0x93, 0xf1, 0x80, 0xf7, 0xfa, 0x2f, 0x35, 0x8b, + 0x5d, 0xf7, 0x6b, 0x3a, 0xef, 0x0f, 0x27, 0x5a, 0x08, 0xff, + 0x7d, 0x15, 0x99, 0x82, 0x11, 0xa4, 0x89, 0xb5, 0x68, 0x81, + 0xf7, 0x21, 0x09, 0xbd, 0xce, 0x15, 0x25, 0xc9, 0xed, 0x39, + 0x9c, 0x0e, 0x97, 0x4d, 0xb3, 0xde, 0xda, 0x86, 0x1d, 0x3b, + 0x53, 0xa9, 0xa9, 0x42, 0x99, 0x8c, 0x95, 0xfb, 0xe5, 0x93, + 0x43, 0xe4, 0x60, 0xad, 0x1a, 0xf2, 0x7b, 0xdb, 0x20, 0x1a, + 0x8b, 0x70, 0x55, 0x7c, 0x24, 0x48, 0x4c, 0x92, 0xa0, 0x2f, + 0x8f, 0xdb, 0xba, 0x9d, 0x54, 0x83, 0x8b, 0xb7, 0xb7, 0xaf, + 0x00, 0xa9, 0x69, 0xec, 0x98, 0xee, 0x0e, 0xf6 }, + { 0x55, 0x44, 0xe6, 0x02, 0xa4, 0xf4, 0x47, 0x8a, 0xdd, 0xda, + 0xf4, 0xb9, 0xfb, 0x58, 0x31, 0xb1, 0x3d, 0xfe, 0x6b, 0xc1, + 0x72, 0x53, 0xa5, 0x1b, 0xa3, 0xc9, 0xad, 0xff, 0xac, 0xcc, + 0xb8, 0x5c, 0x47, 0x4a, 0x3e, 0x14, 0xf0, 0x3d, 0xed, 0x28, + 0x3d, 0x16, 0xfc, 0x45, 0x45, 0xb0, 0xe9, 0xeb, 0xa9, 0xe6, + 0x55, 0xe4, 0x2e, 0x7f, 0x34, 0x04, 0x44, 0xff, 0x67, 0xb9, + 0xed, 0x64, 0xd1, 0x2c, 0xd4, 0x39, 0x61, 0x41, 0x4b, 0x8e, + 0xfa, 0x0c, 0x88, 0xae, 0x40, 0x98, 0xbc, 0xc7, 0x72, 0x72, + 0xbc, 0xec, 0xd2, 0x58, 0xca, 0xf2, 0xd1, 0x22, 0x98, 0x38, + 0x45, 0x50, 0x9b, 0xe9, 0x96, 0x74, 0x30, 0xb7, 0xab, 0x25, + 0xa9, 0xdf, 0x69, 0x1a, 0x32, 0xc8, 0x2e, 0x99, 0xef, 0xe8, + 0xb0, 0x89, 0x25, 0x44, 0xc1, 0xc2, 0xfe, 0x3a, 0xf4, 0x18, + 0x5d, 0xd6, 0x5c, 0x55, 0xdd, 0x27, 0x44, 0xa9 }, + { 0x57, 0x35, 0x99, 0x5c, 0xe2, 0x41, 0xd2, 0x61, 0xdd, 0x7d, + 0x3e, 0xdd, 0x1e, 0xd6, 0x0f, 0x42, 0xc1, 0xa4, 0xcd, 0xce, + 0x2d, 0xec, 0x53, 0xcf, 0x80, 0xb7, 0xec, 0xdc, 0x22, 0x99, + 0x4b, 0x43, 0x72, 0x0b, 0x59, 0xde, 0x19, 0xb1, 0xb5, 0x40, + 0xd0, 0xf7, 0x0e, 0x6e, 0xb2, 0x79, 0x46, 0x81, 0x76, 0xc8, + 0x8b, 0xd2, 0x09, 0xd0, 0x9a, 0xf1, 0x83, 0x10, 0x74, 0x46, + 0xcb, 0x42, 0x03, 0x3c, 0x20, 0x53, 0xc5, 0xe0, 0x1f, 0x6c, + 0x7d, 0x29, 0x83, 0x49, 0xdd, 0x73, 0xc2, 0x90, 0xd9, 0xd8, + 0x16, 0x3d, 0x05, 0x00, 0xed, 0x94, 0x58, 0x70, 0x35, 0x2c, + 0x8c, 0x3f, 0x2d, 0x34, 0x1a, 0xb1, 0xe9, 0xd9, 0xe1, 0xe9, + 0x08, 0x83, 0x30, 0x8c, 0xae, 0x27, 0x42, 0xdb, 0x7b, 0x42, + 0xc5, 0xa8, 0x01, 0x22, 0x71, 0x6f, 0x63, 0xbd, 0xc8, 0xef, + 0x89, 0x7c, 0x53, 0x13, 0xba, 0xa8, 0x0b, 0x4f }, + { 0x88, 0x54, 0x86, 0xdf, 0x3e, 0xc4, 0x5e, 0xf0, 0xe4, 0x68, + 0xed, 0x5f, 0x04, 0x9a, 0x69, 0x17, 0xbb, 0xd3, 0xb0, 0x81, + 0x8a, 0x95, 0x40, 0xc2, 0x5c, 0xc2, 0x28, 0x21, 0x76, 0x8a, + 0xd9, 0x9a, 0xf8, 0x72, 0x9b, 0xc0, 0xea, 0xce, 0x64, 0xc9, + 0xac, 0x39, 0x04, 0xe4, 0xc9, 0xcf, 0x34, 0x65, 0xdb, 0x9a, + 0x59, 0x84, 0xbb, 0x1f, 0xf9, 0x4d, 0xd1, 0x43, 0xb2, 0xda, + 0x4a, 0x4c, 0x5e, 0x89, 0x7b, 0x0c, 0x46, 0xcd, 0x7c, 0x1b, + 0x7d, 0xfd, 0x1b, 0x71, 0x85, 0xcf, 0x08, 0x86, 0x87, 0x73, + 0xec, 0x49, 0x74, 0x21, 0x5b, 0x60, 0x0f, 0x33, 0x4e, 0xee, + 0x44, 0x19, 0x61, 0x18, 0xa1, 0xf5, 0xab, 0xde, 0xb0, 0x33, + 0xe3, 0x03, 0x1b, 0xec, 0xc0, 0x1e, 0xeb, 0xbd, 0x27, 0x1e, + 0xc6, 0x12, 0x68, 0x56, 0xc1, 0x64, 0x33, 0xab, 0x33, 0x88, + 0xdc, 0x4b, 0xa3, 0xfb, 0xa0, 0x23, 0x70, 0x56 }, + { 0x31, 0xce, 0xcf, 0xe8, 0xd4, 0xab, 0x96, 0x2d, 0xc5, 0xdd, + 0x4d, 0x3e, 0xc9, 0x1f, 0xf9, 0xd7, 0x29, 0x08, 0x32, 0x87, + 0xaa, 0xa4, 0xce, 0x0c, 0x33, 0xd8, 0x16, 0x97, 0xf1, 0x19, + 0xd6, 0xe0, 0x4d, 0x0e, 0x8b, 0xcf, 0x99, 0x4f, 0xc5, 0x03, + 0x1a, 0x0b, 0x96, 0xe4, 0x0f, 0x81, 0xf9, 0x1c, 0x98, 0xb5, + 0xd0, 0xab, 0x18, 0x5e, 0xae, 0x19, 0x29, 0xe1, 0x1a, 0xa2, + 0x68, 0x85, 0xe6, 0xb9, 0xbc, 0xb0, 0xe8, 0xa2, 0x71, 0xd3, + 0x68, 0x10, 0x9e, 0x24, 0x96, 0x0f, 0x1a, 0x1b, 0x73, 0xc6, + 0x76, 0x07, 0xdd, 0x08, 0x55, 0xef, 0x8d, 0xef, 0xac, 0xa6, + 0x9a, 0xe8, 0x24, 0x1e, 0xe8, 0xff, 0x20, 0x55, 0xa3, 0x1b, + 0x19, 0xfe, 0x33, 0x39, 0xcc, 0xb0, 0x07, 0x0b, 0x32, 0x5b, + 0xe3, 0x24, 0x3d, 0xb2, 0x71, 0x9f, 0x25, 0xa7, 0xb4, 0x51, + 0x6a, 0x94, 0x2c, 0x93, 0x4b, 0xdf, 0xf4, 0x64 }, + { 0x69, 0x61, 0xb4, 0x6a, 0xda, 0x25, 0x47, 0xb3, 0x5d, 0x8f, + 0x3c, 0xf0, 0x9a, 0x6a, 0x4e, 0xc3, 0x11, 0xb0, 0x86, 0x3b, + 0xd6, 0xd6, 0xf1, 0xd2, 0x72, 0xfe, 0xfc, 0x05, 0x75, 0xd9, + 0xcb, 0x3d, 0x2b, 0x7c, 0x79, 0x45, 0xff, 0x32, 0x52, 0xf8, + 0x65, 0xff, 0xa5, 0xf6, 0x6c, 0x74, 0x2a, 0xc4, 0x48, 0x0e, + 0xd4, 0xfb, 0xc5, 0x51, 0x6c, 0xa9, 0xf5, 0x02, 0xf6, 0x6d, + 0xec, 0xd6, 0xfa, 0x3d, 0x83, 0x9a, 0xa7, 0xbd, 0xc9, 0xd2, + 0x0f, 0xf1, 0x10, 0x09, 0xc0, 0xd9, 0xb4, 0xfb, 0xb5, 0x9c, + 0x98, 0x00, 0xa2, 0x3f, 0xae, 0xcd, 0x69, 0x75, 0x96, 0x63, + 0xe6, 0xad, 0x5b, 0xb5, 0x23, 0xbd, 0x8e, 0x9d, 0xe8, 0x4d, + 0xa3, 0xd0, 0xfa, 0x90, 0xfe, 0x59, 0x02, 0xd4, 0x92, 0x1c, + 0x36, 0xa0, 0xe5, 0xdd, 0x32, 0xb3, 0xb1, 0x94, 0x36, 0xdf, + 0x43, 0x7b, 0xfd, 0x9a, 0xfc, 0x8b, 0x21, 0xe8 }, + { 0x6a, 0x63, 0xa9, 0x0c, 0x53, 0x75, 0x52, 0x12, 0x19, 0x64, + 0xe2, 0x2f, 0x07, 0x81, 0xaa, 0xd9, 0x89, 0xa9, 0xa3, 0x2e, + 0xcd, 0x3f, 0x79, 0x4f, 0xdd, 0xae, 0xc4, 0x2b, 0x73, 0xce, + 0x5b, 0xe9, 0x2e, 0x25, 0x4d, 0x9e, 0x36, 0x05, 0x1f, 0x9f, + 0x1e, 0xb5, 0x1f, 0x32, 0x54, 0xe8, 0x41, 0x23, 0x69, 0x7e, + 0x20, 0xa2, 0x97, 0x07, 0xfa, 0x21, 0xda, 0x78, 0x2d, 0x1d, + 0x93, 0x41, 0x3c, 0xa7, 0xd6, 0x71, 0x20, 0xe6, 0xb6, 0x55, + 0xaf, 0x5d, 0xf9, 0x78, 0x1e, 0xdd, 0x24, 0x6e, 0x3f, 0xd2, + 0x4e, 0x4b, 0x88, 0xed, 0xfb, 0x8c, 0xe1, 0x90, 0xa6, 0xe7, + 0x19, 0xfd, 0x9c, 0x6f, 0x40, 0x0e, 0xa1, 0xf9, 0x1d, 0x44, + 0x70, 0x9d, 0x54, 0xf0, 0xec, 0xa1, 0x7a, 0x5b, 0xdb, 0x28, + 0xa0, 0x4c, 0x1e, 0xd5, 0x54, 0x6b, 0x57, 0xaf, 0x14, 0xd9, + 0xd0, 0x7b, 0x58, 0x7e, 0xcb, 0x35, 0xe2, 0xac }, + { 0x51, 0xed, 0x4a, 0x22, 0xd1, 0x51, 0xd9, 0x0e, 0xff, 0xc8, + 0x9f, 0xfd, 0x82, 0x55, 0x29, 0x61, 0xa5, 0x47, 0x64, 0x46, + 0x82, 0x35, 0xcd, 0x0b, 0x8c, 0x27, 0xf8, 0x92, 0x86, 0x17, + 0xf1, 0x65, 0xc2, 0x0b, 0x93, 0x07, 0x0e, 0x02, 0x1e, 0xd3, + 0xa5, 0x3a, 0x81, 0xb3, 0x6e, 0xa5, 0x02, 0xea, 0x80, 0x9b, + 0xf0, 0x74, 0xe8, 0x44, 0xa5, 0x76, 0xab, 0xcc, 0x78, 0x13, + 0x5c, 0xa4, 0x71, 0xdd, 0xd6, 0xed, 0x58, 0x16, 0x5b, 0xa3, + 0xf4, 0xa1, 0x65, 0x88, 0x80, 0xc1, 0x5a, 0x4d, 0x3e, 0x7c, + 0xf8, 0x65, 0x80, 0x21, 0x7b, 0x37, 0x0f, 0x7f, 0x08, 0x6a, + 0x3c, 0xdf, 0x0c, 0xd6, 0xd2, 0xf6, 0x01, 0x66, 0x77, 0x14, + 0x3e, 0xb9, 0x4d, 0x4f, 0xe4, 0xa2, 0x96, 0x72, 0x38, 0x8c, + 0x51, 0x9b, 0x2c, 0x01, 0x66, 0x8a, 0xb7, 0x4f, 0x61, 0x08, + 0x76, 0x55, 0x4e, 0x00, 0x3d, 0x7a, 0xcb, 0xbb }, + { 0x2d, 0x69, 0x51, 0xbc, 0x2b, 0x8b, 0x5c, 0xe5, 0x41, 0x73, + 0xd9, 0x4a, 0xe9, 0xf4, 0x92, 0x56, 0xeb, 0x7a, 0xfe, 0x26, + 0x74, 0xa9, 0x79, 0x3c, 0x0d, 0x5f, 0x6f, 0xb1, 0xd2, 0xd1, + 0x69, 0xbf, 0x93, 0xdf, 0x3f, 0x2a, 0xe1, 0xef, 0x97, 0x12, + 0xaf, 0x0a, 0x92, 0x60, 0x6c, 0x29, 0xfe, 0x48, 0x7a, 0x87, + 0x21, 0x38, 0x23, 0x50, 0x0e, 0xcc, 0x0e, 0x29, 0x71, 0x1f, + 0x71, 0x06, 0x61, 0x5e, 0x41, 0xc5, 0x3c, 0xf6, 0x28, 0xce, + 0x68, 0x5f, 0x68, 0xfc, 0x32, 0x0c, 0x5e, 0xd7, 0xc8, 0x97, + 0xf2, 0xa6, 0x0d, 0x2d, 0x6c, 0xeb, 0x5d, 0x5e, 0xfd, 0x67, + 0x48, 0x0e, 0xce, 0x64, 0x3b, 0x9b, 0x75, 0xa7, 0xa0, 0x55, + 0xdb, 0x50, 0xbf, 0x7d, 0x3e, 0xf9, 0xbe, 0x15, 0xb5, 0x72, + 0x96, 0x5f, 0xea, 0x8d, 0x91, 0xa3, 0xbb, 0x27, 0xca, 0xf2, + 0x37, 0xd6, 0x96, 0x3a, 0x44, 0x97, 0x01, 0xb4 }, + { 0x65, 0xc4, 0x8e, 0x78, 0xe0, 0x8c, 0xc5, 0xf0, 0xa2, 0x4e, + 0xba, 0x02, 0x16, 0x5b, 0x3a, 0xee, 0x46, 0x49, 0x04, 0xc1, + 0xb8, 0x3b, 0x93, 0xf9, 0x75, 0xc4, 0xd0, 0x89, 0xa7, 0xaf, + 0x22, 0x68, 0x0b, 0xad, 0x73, 0x0c, 0xbc, 0xf9, 0x31, 0xa0, + 0x32, 0x20, 0x48, 0xb1, 0x44, 0x7b, 0x5e, 0x6d, 0x92, 0x43, + 0x53, 0xf5, 0x8b, 0x92, 0xa7, 0x42, 0xd4, 0xb6, 0x4d, 0x78, + 0xe7, 0x0e, 0x16, 0x27, 0x83, 0xd9, 0x5d, 0x9c, 0x2b, 0x87, + 0x4f, 0x55, 0x82, 0x0a, 0x8f, 0x66, 0x71, 0x1e, 0x71, 0xa0, + 0xc7, 0x95, 0xcb, 0x7d, 0xc2, 0x74, 0x35, 0x19, 0x6e, 0x7f, + 0xea, 0x3a, 0x0b, 0x0f, 0x42, 0xf1, 0x29, 0x57, 0x34, 0x15, + 0xcf, 0xc7, 0x75, 0x18, 0xd4, 0x99, 0x4e, 0x8b, 0x8f, 0x42, + 0x9e, 0xee, 0x33, 0x3f, 0x24, 0x8f, 0x86, 0xf4, 0xe1, 0x09, + 0xdd, 0x00, 0x7d, 0x9f, 0x90, 0x4e, 0x22, 0x2e }, + { 0x36, 0xb5, 0xcd, 0x2c, 0x7a, 0x6b, 0x22, 0x6f, 0xf6, 0x3d, + 0xd9, 0xff, 0xd4, 0x38, 0xba, 0x2d, 0x40, 0x2d, 0x57, 0x85, + 0xa8, 0xd9, 0xa3, 0xcb, 0xe2, 0x28, 0x0f, 0xa6, 0xef, 0x24, + 0x54, 0x45, 0xe1, 0x06, 0xf4, 0x89, 0x08, 0xb0, 0x55, 0x3a, + 0xd8, 0x28, 0x67, 0xed, 0xb2, 0x89, 0x5d, 0x2e, 0xf0, 0x6f, + 0x0a, 0x46, 0x25, 0xe7, 0xec, 0xe0, 0x38, 0x09, 0xfa, 0x28, + 0x07, 0xd3, 0xe0, 0x13, 0x76, 0xa3, 0xf2, 0xd1, 0x10, 0xf1, + 0x8d, 0x12, 0xdb, 0xf6, 0x7f, 0x0b, 0x4d, 0x31, 0x88, 0xc0, + 0xf5, 0x4d, 0x3e, 0xee, 0x94, 0x73, 0x51, 0x07, 0xfb, 0x1c, + 0x58, 0x1c, 0x31, 0x20, 0x4c, 0xef, 0x28, 0x4a, 0xdf, 0x8f, + 0x59, 0xfc, 0xec, 0x77, 0x03, 0x01, 0xcb, 0x14, 0xb2, 0x14, + 0x3b, 0x06, 0x56, 0x83, 0xd8, 0xcd, 0xfc, 0xea, 0x23, 0xb4, + 0x1a, 0x1c, 0x73, 0xce, 0xde, 0x22, 0x2c, 0x22 }, + { 0x08, 0xd7, 0xc1, 0x44, 0xdb, 0x39, 0xbf, 0xd8, 0x06, 0x92, + 0xf4, 0xc5, 0x39, 0xa5, 0x1d, 0xc8, 0xd2, 0x7c, 0xc9, 0x60, + 0xf7, 0x44, 0x5e, 0x8a, 0x18, 0xf7, 0x3c, 0xaf, 0x52, 0x23, + 0x89, 0xff, 0x45, 0x59, 0x3d, 0xf1, 0x37, 0x6a, 0x9a, 0xb6, + 0x14, 0xe1, 0x82, 0xa7, 0x93, 0xcf, 0x99, 0xc4, 0xff, 0x50, + 0x15, 0x1e, 0xea, 0xa7, 0x4d, 0xf8, 0x8d, 0x0e, 0x85, 0xf9, + 0x36, 0xa5, 0x1a, 0x37, 0xc6, 0xa2, 0x1d, 0x11, 0x2f, 0x41, + 0x22, 0x44, 0x74, 0x83, 0x97, 0x79, 0x0c, 0xc2, 0xe8, 0x10, + 0x74, 0x50, 0x19, 0x83, 0x78, 0x1a, 0x67, 0x8a, 0x0d, 0x47, + 0x5d, 0x79, 0x8d, 0x93, 0x5a, 0x5e, 0xa1, 0x9e, 0xaf, 0x39, + 0xc8, 0x5a, 0xf1, 0xa3, 0x90, 0xa3, 0x57, 0xfa, 0x9b, 0x45, + 0x9c, 0xd8, 0x64, 0xd8, 0x0b, 0x41, 0x45, 0x20, 0xc7, 0x50, + 0x87, 0xff, 0x4e, 0x20, 0x54, 0x56, 0x79, 0xa7 }, + { 0x5f, 0x2a, 0xa8, 0xee, 0xba, 0xb7, 0x02, 0x02, 0x8e, 0x2c, + 0x38, 0x79, 0x04, 0x00, 0x4a, 0xd9, 0x1d, 0x30, 0x50, 0xae, + 0xb5, 0xee, 0x14, 0x7b, 0x4c, 0x38, 0x5e, 0x8b, 0xc7, 0x36, + 0x7d, 0x1f, 0xb5, 0x90, 0x52, 0x64, 0x0f, 0x9b, 0x2b, 0x49, + 0xf3, 0xfe, 0x9c, 0x42, 0xbb, 0x0c, 0xd2, 0xbf, 0x01, 0x97, + 0x24, 0x3e, 0xe3, 0x47, 0x69, 0x4a, 0x3f, 0xe1, 0xe8, 0xb5, + 0x89, 0x83, 0x08, 0xe3, 0x95, 0xe9, 0x5b, 0xb8, 0xa8, 0xde, + 0x7a, 0xa4, 0x7c, 0xc6, 0xe8, 0x38, 0x5f, 0xce, 0x17, 0xbd, + 0xf3, 0xc1, 0xa1, 0x01, 0x61, 0x30, 0xa4, 0xc6, 0x7a, 0x96, + 0x6d, 0x8b, 0xd1, 0x58, 0x7b, 0x7e, 0x77, 0x31, 0x23, 0x74, + 0x2a, 0x67, 0x8c, 0xdf, 0xf0, 0xec, 0xcd, 0x74, 0xdb, 0x6b, + 0xd6, 0x41, 0x87, 0xea, 0x91, 0x92, 0xd4, 0x8c, 0x21, 0x56, + 0x80, 0x9c, 0x0d, 0x96, 0x3e, 0xcc, 0xa7, 0x73 }, + { 0x62, 0x50, 0x1a, 0x98, 0xb4, 0x6f, 0xf9, 0x49, 0xa3, 0x16, + 0x49, 0x80, 0x83, 0xc9, 0xf2, 0x24, 0xe8, 0x84, 0xac, 0x76, + 0x78, 0x4b, 0xe8, 0x2f, 0xd9, 0xff, 0x03, 0x40, 0x02, 0xbc, + 0xd3, 0xc7, 0xc2, 0x82, 0x78, 0xb4, 0x86, 0x6e, 0x5a, 0xe8, + 0x59, 0xdc, 0x52, 0xe6, 0x1e, 0xa6, 0xf0, 0x6e, 0xed, 0xcf, + 0x2d, 0x1a, 0xe2, 0xd9, 0xd3, 0x86, 0x95, 0x9a, 0xfc, 0xba, + 0x8e, 0x2d, 0x85, 0xd1, 0x2b, 0xab, 0xb2, 0x7e, 0x18, 0xbe, + 0x05, 0xf6, 0x7d, 0xab, 0xa1, 0x27, 0x05, 0xeb, 0x67, 0xb8, + 0x26, 0xf6, 0xee, 0x3b, 0x0f, 0xcb, 0x53, 0x4c, 0xef, 0x34, + 0x9c, 0x61, 0xc6, 0x82, 0xe4, 0xd6, 0x0a, 0x69, 0xe8, 0xd3, + 0xe6, 0x42, 0xdd, 0x46, 0xa5, 0xaa, 0x68, 0x5e, 0xda, 0x10, + 0x6e, 0xbf, 0xb7, 0xbf, 0x38, 0x80, 0xd0, 0xa1, 0x9f, 0x66, + 0xe2, 0x08, 0xd4, 0x64, 0x12, 0x66, 0x52, 0x4b }, + { 0x49, 0x7b, 0x15, 0xfe, 0xfd, 0x3f, 0xc6, 0x65, 0xcc, 0x9c, + 0x5f, 0x73, 0xa1, 0xf3, 0x53, 0x1a, 0xab, 0xaa, 0x4c, 0x49, + 0xc0, 0xde, 0xa5, 0x86, 0x78, 0x49, 0x9b, 0x73, 0x91, 0xf9, + 0xda, 0x5e, 0xd1, 0xac, 0xf7, 0xa0, 0xb5, 0xc4, 0xeb, 0x10, + 0xfd, 0x74, 0x10, 0x1c, 0x9a, 0x6f, 0xea, 0x8a, 0x51, 0x9d, + 0x21, 0x33, 0xd5, 0x9b, 0x17, 0x41, 0xbd, 0x9a, 0x8e, 0x31, + 0x4f, 0x0d, 0x1b, 0x70, 0x52, 0xfb, 0xf5, 0x4d, 0xce, 0xcc, + 0xfe, 0x77, 0x62, 0x28, 0x06, 0xe0, 0x2e, 0xa8, 0xab, 0xd3, + 0x81, 0x30, 0xc9, 0xb0, 0xed, 0x55, 0x3e, 0xac, 0xfa, 0x3c, + 0x91, 0x97, 0x20, 0xaa, 0x45, 0x36, 0xa2, 0x88, 0xda, 0xc8, + 0x46, 0xe6, 0x4b, 0x19, 0xe8, 0x25, 0x30, 0x02, 0x8c, 0x8d, + 0x3d, 0x67, 0xca, 0x6a, 0x33, 0xdb, 0xa5, 0xe0, 0xe4, 0xbd, + 0x56, 0x3f, 0x7d, 0x9a, 0xad, 0x26, 0x40, 0x86 }, + { 0x18, 0xd4, 0x6a, 0x6c, 0x9e, 0x51, 0x4c, 0xb7, 0xb7, 0xae, + 0x7e, 0x5c, 0x2f, 0xf6, 0x37, 0xe6, 0xc2, 0xee, 0xbd, 0x13, + 0xed, 0xea, 0x10, 0x71, 0xda, 0xfa, 0x33, 0xfe, 0x06, 0x80, + 0x12, 0xca, 0x40, 0x5d, 0x3e, 0x84, 0xd6, 0x30, 0x8e, 0xdc, + 0xdd, 0x8d, 0xff, 0xbf, 0x86, 0xa9, 0xb7, 0xce, 0x2a, 0x80, + 0xd0, 0xd2, 0x42, 0xc0, 0x07, 0xf4, 0x99, 0xaa, 0x68, 0xac, + 0xba, 0x3e, 0xbd, 0x91, 0x8f, 0x31, 0xf0, 0x44, 0x3e, 0x21, + 0x6d, 0xbf, 0x9c, 0xd0, 0x6d, 0x31, 0xca, 0x90, 0xf0, 0x2e, + 0x81, 0x09, 0xfc, 0x75, 0xa2, 0x9c, 0x53, 0x9f, 0x8c, 0x8c, + 0xdb, 0xa2, 0x02, 0xa0, 0xf5, 0xb4, 0xc8, 0x65, 0x22, 0xf8, + 0x4a, 0xc3, 0x7d, 0xa9, 0xdb, 0xb0, 0x3d, 0xd3, 0x9a, 0xb2, + 0x53, 0x9a, 0xf4, 0x91, 0xa0, 0xfe, 0xc7, 0x19, 0x2a, 0x6f, + 0x8a, 0x56, 0xcb, 0xaa, 0xf4, 0x55, 0x68, 0xe9 }, + { 0x55, 0x04, 0x46, 0x01, 0xd3, 0xf6, 0x2e, 0x40, 0x69, 0xe6, + 0xf8, 0xe4, 0x5a, 0x38, 0xfe, 0xf9, 0x10, 0xd5, 0x4f, 0x8a, + 0x7e, 0x93, 0x05, 0x0d, 0x45, 0xf9, 0x3d, 0x41, 0xa0, 0x6e, + 0x70, 0x8c, 0x3f, 0x0d, 0xb5, 0xcd, 0x7b, 0xb5, 0xe7, 0x51, + 0x37, 0x0d, 0xe9, 0xc8, 0xdc, 0xd7, 0x05, 0xad, 0x14, 0x10, + 0x9d, 0x29, 0x7c, 0x29, 0x54, 0xf3, 0xab, 0x0b, 0x36, 0xf9, + 0xd8, 0x51, 0x76, 0xac, 0x70, 0xeb, 0x06, 0x03, 0x6d, 0xa7, + 0xa5, 0x2b, 0x74, 0x07, 0xa7, 0x88, 0xb1, 0x41, 0x71, 0xb9, + 0x6c, 0xfe, 0x05, 0x71, 0x13, 0xac, 0x73, 0x45, 0x2e, 0x0d, + 0x83, 0x25, 0xa3, 0x25, 0xfd, 0x40, 0xac, 0x0a, 0xbc, 0xda, + 0xb4, 0xce, 0xb4, 0xe4, 0xc4, 0xeb, 0x2f, 0x3e, 0x42, 0xae, + 0x8a, 0xdd, 0x07, 0x45, 0xdd, 0xb2, 0x49, 0x7c, 0xba, 0xf4, + 0x86, 0x8c, 0xbb, 0x22, 0xa7, 0x8b, 0x78, 0x02 }, + { 0x0d, 0xa3, 0x13, 0xfc, 0xd7, 0xb0, 0xec, 0x4f, 0x56, 0x3a, + 0x8f, 0xf7, 0xc6, 0xf5, 0xd7, 0xdb, 0xf3, 0x42, 0x52, 0x09, + 0x3d, 0xd7, 0x9f, 0x93, 0xa1, 0x21, 0x18, 0xac, 0x9a, 0x2b, + 0xd0, 0x1b, 0x27, 0x07, 0x41, 0x76, 0xf5, 0x32, 0x97, 0x3f, + 0x47, 0x7c, 0xa3, 0xdb, 0x9f, 0xf1, 0x00, 0xbc, 0xbc, 0xb5, + 0x31, 0x89, 0x70, 0xc2, 0xae, 0xe3, 0xe2, 0x22, 0x0e, 0x85, + 0x9a, 0xee, 0xfe, 0x98, 0x33, 0x65, 0xc8, 0xe5, 0x29, 0xad, + 0x51, 0x66, 0x90, 0x42, 0x59, 0x6b, 0x91, 0x79, 0x2e, 0x6b, + 0x1c, 0xde, 0x06, 0xe7, 0x40, 0x0d, 0x14, 0x4f, 0x1d, 0x21, + 0xfb, 0xfa, 0x29, 0x51, 0xfc, 0x83, 0x39, 0x72, 0x1f, 0xfe, + 0x29, 0xad, 0x5f, 0x82, 0x7c, 0xd8, 0x66, 0x3e, 0x11, 0x23, + 0x6f, 0xb8, 0x54, 0x20, 0x74, 0xd7, 0x41, 0xd0, 0x00, 0x14, + 0xd1, 0xc5, 0xc9, 0x10, 0x06, 0xcb, 0x9c, 0xc9 }, + { 0x63, 0x63, 0x0b, 0xe8, 0xdb, 0x41, 0x4a, 0xcc, 0x62, 0x02, + 0x30, 0xd8, 0x1e, 0x82, 0x29, 0x0e, 0x44, 0x16, 0x74, 0x10, + 0xa1, 0x16, 0x2d, 0x03, 0x50, 0x94, 0x0c, 0x26, 0x94, 0x1c, + 0x25, 0x54, 0xad, 0xfa, 0xe4, 0xe1, 0x73, 0x10, 0x83, 0xef, + 0x6d, 0x7c, 0x2e, 0xa0, 0xf8, 0x70, 0x46, 0x64, 0xe2, 0x95, + 0x9b, 0xea, 0x09, 0xc2, 0x8f, 0x27, 0x3a, 0xf0, 0xec, 0xbb, + 0xca, 0x3d, 0xe5, 0x0c, 0x47, 0x3d, 0x50, 0xd6, 0x1f, 0x1b, + 0x7f, 0x00, 0x4d, 0x29, 0xa6, 0x16, 0xf0, 0x3d, 0x06, 0x60, + 0xd5, 0x53, 0x1a, 0x0d, 0x04, 0x9a, 0xea, 0xc2, 0x2d, 0x2b, + 0xf4, 0xff, 0xc9, 0xe2, 0xce, 0x18, 0x0d, 0x3e, 0x9a, 0x74, + 0x7c, 0xb0, 0x04, 0x2a, 0x48, 0x71, 0x39, 0x94, 0x67, 0xb8, + 0xa8, 0x23, 0xca, 0x21, 0xd7, 0x0c, 0x00, 0x89, 0x3e, 0x9c, + 0x37, 0x12, 0x5a, 0x8c, 0x15, 0xaa, 0x25, 0x57 }, + { 0x30, 0x6a, 0x98, 0x71, 0xf1, 0x66, 0x88, 0xed, 0x29, 0x58, + 0x45, 0xc0, 0x68, 0x54, 0x4e, 0xb0, 0x68, 0x07, 0x4f, 0x37, + 0xd5, 0xe5, 0xaa, 0x72, 0xeb, 0x0c, 0xd4, 0x78, 0xf8, 0xac, + 0x8f, 0x89, 0xfc, 0xe5, 0x18, 0x6c, 0xe5, 0x58, 0xf6, 0xbe, + 0x36, 0x9b, 0x3e, 0x98, 0xbb, 0x44, 0x3c, 0x07, 0x56, 0xae, + 0xaf, 0xa8, 0x5a, 0x14, 0x36, 0xfa, 0x3d, 0x4f, 0xd9, 0x77, + 0x26, 0x1d, 0x1b, 0x79, 0xca, 0x3d, 0x70, 0x25, 0x58, 0xe2, + 0x60, 0x6d, 0x1f, 0x69, 0xb2, 0x0c, 0x13, 0xce, 0xa0, 0x45, + 0x9d, 0x99, 0x7d, 0x18, 0xb4, 0xb7, 0x0c, 0x4c, 0xbf, 0x3f, + 0x38, 0xf4, 0x49, 0xb9, 0xdc, 0x38, 0x88, 0x3e, 0x04, 0xd6, + 0xde, 0x2c, 0x59, 0xad, 0x1b, 0x4d, 0x33, 0xdd, 0x6c, 0x40, + 0x2d, 0x89, 0x49, 0xe7, 0x58, 0x23, 0xeb, 0x62, 0xf8, 0x79, + 0xbf, 0x8d, 0x52, 0x22, 0x8a, 0x7d, 0x2e, 0x41 }, + { 0x28, 0x33, 0xac, 0x41, 0xe8, 0x10, 0x3e, 0x37, 0x64, 0x43, + 0xeb, 0xe0, 0x58, 0xe5, 0x7c, 0xd4, 0x71, 0xab, 0xa7, 0x31, + 0x93, 0xc9, 0xd5, 0x88, 0x93, 0x06, 0x21, 0x5b, 0x77, 0xf4, + 0xc0, 0x1c, 0x55, 0x1e, 0x7a, 0x17, 0x6e, 0x72, 0xa1, 0x3d, + 0xf9, 0xfa, 0x62, 0x8d, 0x1b, 0xea, 0xa5, 0x11, 0xf6, 0xd4, + 0x18, 0xf8, 0x82, 0x07, 0x5f, 0x91, 0xc0, 0x75, 0xc7, 0x01, + 0xf5, 0x32, 0x70, 0x1b, 0x28, 0xe6, 0xf6, 0x31, 0x82, 0xa9, + 0xd2, 0x2b, 0x4a, 0xf2, 0x2b, 0xc0, 0x0a, 0xc9, 0xc2, 0xde, + 0x60, 0xe5, 0x64, 0xd8, 0xc7, 0xaf, 0xb8, 0x99, 0x35, 0x28, + 0x32, 0x38, 0x9a, 0x2d, 0x60, 0x23, 0x87, 0xb6, 0xef, 0x20, + 0xc5, 0xbf, 0xee, 0x67, 0xa9, 0xbe, 0x01, 0x52, 0xc0, 0xdb, + 0x41, 0x20, 0x1e, 0xdf, 0x27, 0xca, 0x0e, 0x6f, 0x65, 0x8f, + 0xbc, 0x45, 0x1e, 0x9d, 0x63, 0x4e, 0xc1, 0x36 }, + { 0x12, 0x0c, 0xd4, 0x54, 0xa4, 0x9d, 0x63, 0x03, 0x67, 0x30, + 0x20, 0xed, 0x0b, 0xcf, 0x35, 0x38, 0xbd, 0x59, 0xc7, 0x57, + 0xde, 0x5c, 0x01, 0x91, 0x65, 0x5b, 0xa9, 0xe4, 0x08, 0x77, + 0x87, 0xd9, 0xe1, 0xdc, 0xbc, 0xd6, 0x99, 0x76, 0x32, 0x7e, + 0xf4, 0x2f, 0xaa, 0x97, 0x20, 0x6b, 0x5f, 0xaa, 0xc0, 0x9c, + 0x1c, 0x5a, 0x47, 0x22, 0xb4, 0xd7, 0xec, 0xb6, 0x8b, 0xd1, + 0x04, 0xba, 0xa4, 0x31, 0x1b, 0x87, 0xa5, 0x8e, 0x13, 0x93, + 0xc6, 0xe6, 0xd5, 0xf3, 0x23, 0xf8, 0x27, 0x32, 0x04, 0x49, + 0x7d, 0x5a, 0x27, 0x00, 0xdc, 0xfa, 0x19, 0x41, 0xb4, 0x38, + 0xe4, 0xcf, 0xfd, 0xc6, 0x03, 0x39, 0x35, 0x12, 0xaf, 0xe7, + 0x9d, 0x34, 0x3d, 0xc2, 0x9d, 0x7c, 0x1f, 0x0b, 0x8c, 0x57, + 0xa7, 0x28, 0xac, 0x3d, 0x9d, 0xa8, 0x1c, 0x08, 0xdb, 0x24, + 0x7e, 0x56, 0x4b, 0x86, 0x8d, 0xa5, 0xec, 0x5c }, + { 0x02, 0x1c, 0xfd, 0x16, 0x7f, 0xde, 0xea, 0x3e, 0x8e, 0xf1, + 0x67, 0x7e, 0x70, 0x19, 0x33, 0x6e, 0xd5, 0x69, 0x84, 0x96, + 0xeb, 0x40, 0x54, 0xbc, 0x15, 0x1f, 0x69, 0x3a, 0x9b, 0xe0, + 0x24, 0x30, 0xa6, 0x7a, 0xd9, 0xf6, 0x8f, 0x01, 0x03, 0xcb, + 0x75, 0x8d, 0xaf, 0x64, 0x5e, 0xb3, 0x3e, 0x34, 0x66, 0xda, + 0xe2, 0xc2, 0xd4, 0x67, 0xfa, 0x92, 0xde, 0x1f, 0xaa, 0x12, + 0x0b, 0xc9, 0xae, 0xc1, 0x2e, 0xf0, 0x5b, 0x4b, 0x0e, 0x93, + 0xdf, 0xf2, 0xbd, 0x16, 0xf5, 0x58, 0x29, 0xdb, 0xdd, 0xcd, + 0xef, 0x2f, 0xf3, 0x80, 0x21, 0xa4, 0xf0, 0xd3, 0x3d, 0xe4, + 0x87, 0xf0, 0x47, 0x21, 0xab, 0x5c, 0x64, 0x2e, 0xd3, 0xa6, + 0x9b, 0x95, 0x77, 0x74, 0x9b, 0x6a, 0x68, 0x41, 0x5a, 0x8d, + 0x06, 0x65, 0xbc, 0x00, 0x3e, 0xf0, 0x2c, 0xce, 0x58, 0xee, + 0xeb, 0xfd, 0xb8, 0xf4, 0xca, 0xb0, 0xf9, 0xee }, + { 0x07, 0x26, 0x5b, 0x46, 0xc7, 0x3c, 0xf7, 0x8e, 0x71, 0xed, + 0xcd, 0x9c, 0xa2, 0x05, 0x95, 0xa3, 0x5d, 0xed, 0xc2, 0x31, + 0xeb, 0x12, 0x8b, 0xb6, 0x80, 0x7c, 0x22, 0xdf, 0xbf, 0x8e, + 0xd5, 0x9c, 0xc8, 0x8f, 0xa8, 0x17, 0xfd, 0x0a, 0xe2, 0x8a, + 0xdc, 0x0c, 0x7e, 0x57, 0x99, 0x74, 0x30, 0x2c, 0xaf, 0x86, + 0xe3, 0x91, 0xed, 0x2a, 0xb5, 0x1a, 0xb9, 0x7a, 0xd5, 0xf9, + 0x22, 0x4a, 0x47, 0x0f, 0xfa, 0xeb, 0x52, 0xef, 0x15, 0x60, + 0x08, 0xb5, 0x52, 0x67, 0x07, 0x3f, 0x66, 0x34, 0x3d, 0x5a, + 0x0d, 0x8f, 0x71, 0x7e, 0x3d, 0x3b, 0xb1, 0x8b, 0xfd, 0xb1, + 0x67, 0x76, 0x30, 0x4a, 0xe4, 0xca, 0x1e, 0x5e, 0xc7, 0xb7, + 0x0f, 0x39, 0x93, 0xc8, 0x55, 0x36, 0x8d, 0x10, 0xf2, 0xcf, + 0x77, 0x13, 0x70, 0x3b, 0xde, 0x37, 0xd6, 0x4a, 0xd2, 0x54, + 0x5c, 0x73, 0x71, 0x5f, 0xdf, 0x5c, 0x36, 0xf3 }, + { 0x36, 0xc5, 0x75, 0x4b, 0x31, 0xd1, 0x49, 0x6c, 0x6e, 0x9d, + 0x66, 0x7d, 0x0c, 0xc2, 0xf4, 0xbd, 0x8f, 0x47, 0x57, 0x5d, + 0x06, 0x44, 0x08, 0x0e, 0xdd, 0x88, 0xde, 0xee, 0x7a, 0x0a, + 0xc6, 0xe9, 0x6d, 0xcc, 0xa4, 0x9b, 0x49, 0xc1, 0x2a, 0xa2, + 0xcd, 0x9c, 0x0c, 0x08, 0xad, 0xaf, 0x79, 0x6f, 0x33, 0x3f, + 0x27, 0xd0, 0xf8, 0xa4, 0x3a, 0x97, 0x03, 0x89, 0xf3, 0x41, + 0x3b, 0xd3, 0x43, 0x02, 0xf8, 0xad, 0xf7, 0x2f, 0x06, 0x95, + 0x7b, 0x1f, 0xea, 0x39, 0x9c, 0xaa, 0x25, 0x57, 0x75, 0x3b, + 0x55, 0xea, 0x0e, 0x3a, 0x69, 0x73, 0xb9, 0x5a, 0x0e, 0x0e, + 0x1b, 0x1a, 0x52, 0x3c, 0x42, 0x8d, 0x23, 0x9e, 0xa8, 0xaa, + 0x7a, 0x94, 0x3f, 0x3b, 0xaf, 0x82, 0x6d, 0xfa, 0x5b, 0x86, + 0x0f, 0xc4, 0xc5, 0x9a, 0xaf, 0x89, 0xc4, 0x02, 0x77, 0x16, + 0x73, 0xdd, 0x99, 0xf0, 0xbd, 0x66, 0x23, 0x2f }, + { 0x06, 0xfb, 0xf8, 0x61, 0x19, 0x46, 0x94, 0x4e, 0xfc, 0x8a, + 0x8a, 0xc9, 0xa2, 0x97, 0x5e, 0xb5, 0xa2, 0xdd, 0xad, 0xe5, + 0xc1, 0x64, 0xd9, 0x4f, 0x40, 0xc0, 0x15, 0x32, 0xc9, 0x58, + 0x22, 0xde, 0xc0, 0x78, 0x44, 0x94, 0xc4, 0x8a, 0xf5, 0xae, + 0x3d, 0x67, 0x42, 0xe9, 0x6b, 0x0b, 0x17, 0x05, 0xa9, 0x4c, + 0x3a, 0x40, 0x50, 0x51, 0x3d, 0xed, 0x6c, 0x49, 0x07, 0x5b, + 0x37, 0xef, 0x67, 0x77, 0x1c, 0x09, 0xdf, 0xf3, 0xc4, 0x18, + 0x00, 0xc5, 0x52, 0x97, 0xda, 0x6b, 0x4b, 0x23, 0xe4, 0xba, + 0x1c, 0x18, 0xd0, 0xf7, 0xcd, 0x6d, 0xef, 0x49, 0xc9, 0x05, + 0x46, 0x6a, 0x74, 0x0f, 0x8c, 0x79, 0x63, 0x39, 0x84, 0x4a, + 0x80, 0x79, 0x97, 0x4e, 0x4b, 0x0e, 0xaf, 0x4e, 0x92, 0x1b, + 0x80, 0x55, 0xa6, 0x99, 0x11, 0x22, 0x7e, 0x78, 0x9c, 0x4f, + 0x91, 0x20, 0x04, 0x6e, 0xf3, 0x23, 0xd8, 0x4b }, + { 0x5e, 0x9c, 0xa0, 0xfd, 0x1f, 0x0f, 0xa9, 0xea, 0x5e, 0x64, + 0x29, 0x53, 0x04, 0xbb, 0x5a, 0xb1, 0x2a, 0x7d, 0x84, 0x11, + 0xa0, 0x3e, 0x8f, 0x0e, 0xd9, 0xd1, 0x96, 0x53, 0xd9, 0x5e, + 0xef, 0xa1, 0x83, 0x3d, 0x46, 0xa1, 0x36, 0x19, 0xcf, 0x4d, + 0x96, 0xd2, 0xe9, 0x57, 0x9d, 0xa0, 0x79, 0x33, 0x7c, 0x88, + 0xb1, 0x0b, 0x23, 0xd3, 0x43, 0x4e, 0xc9, 0x21, 0xe6, 0x9d, + 0x95, 0x71, 0xae, 0x28, 0x42, 0x2c, 0x32, 0x6d, 0xf0, 0x66, + 0x12, 0xa5, 0xe4, 0x0a, 0xbc, 0x9d, 0x5c, 0xbf, 0x6b, 0xf3, + 0x4c, 0x5f, 0x2a, 0x2a, 0xfb, 0x65, 0xbd, 0x03, 0x98, 0x2b, + 0x61, 0xf5, 0xb3, 0x0a, 0x1a, 0x23, 0x7b, 0xeb, 0x07, 0x1a, + 0xe4, 0xd7, 0x41, 0x7c, 0x05, 0xfe, 0xf5, 0x9b, 0x0f, 0xde, + 0xf8, 0xb9, 0xd8, 0x3b, 0x58, 0xc8, 0x1d, 0x04, 0x0f, 0xeb, + 0x2d, 0x65, 0x33, 0x8e, 0x3f, 0x45, 0xaa, 0x97 }, + { 0x94, 0x06, 0x22, 0xb3, 0xc6, 0x83, 0x6a, 0xf8, 0x8c, 0xc2, + 0x04, 0x5b, 0x49, 0x95, 0x5f, 0x34, 0x69, 0xb1, 0xf1, 0xc7, + 0x36, 0x24, 0x24, 0xa6, 0x75, 0xb3, 0x18, 0xdc, 0x76, 0x93, + 0x69, 0x14, 0xd3, 0x39, 0x17, 0x17, 0x06, 0x4d, 0xdc, 0x77, + 0xea, 0xcc, 0x55, 0x13, 0x65, 0x64, 0x78, 0xe3, 0x7b, 0xc9, + 0x3a, 0x45, 0x03, 0xe3, 0xe0, 0x13, 0x7f, 0x16, 0x5f, 0xd3, + 0xa8, 0xf9, 0xac, 0x8a, 0x6a, 0xdc, 0x4b, 0x9e, 0x1e, 0x84, + 0x72, 0x8b, 0x26, 0xe3, 0x6f, 0xbe, 0x61, 0xf6, 0x4b, 0x56, + 0xfc, 0x79, 0x56, 0x2c, 0xd4, 0x03, 0x4a, 0x9a, 0xc1, 0xfc, + 0x9c, 0x7b, 0xc7, 0x58, 0xc6, 0xa3, 0xe9, 0x52, 0xdc, 0x2c, + 0x0d, 0x17, 0x46, 0x7c, 0x65, 0xfb, 0x9e, 0xfc, 0xff, 0xdb, + 0x0e, 0xb2, 0xe2, 0xda, 0x40, 0xbf, 0xe7, 0x8a, 0x95, 0xa2, + 0x5b, 0xd5, 0x45, 0x71, 0x19, 0x7c, 0x5d, 0xc4 }, + { 0x80, 0xbb, 0x16, 0x64, 0x78, 0x5b, 0xed, 0xb6, 0xb9, 0xf4, + 0x98, 0x24, 0xbd, 0xe6, 0xbd, 0x71, 0xe2, 0xb4, 0x9c, 0x8c, + 0xcf, 0xde, 0x33, 0x68, 0xd8, 0xa9, 0x98, 0xa4, 0xf1, 0x90, + 0xa2, 0xc8, 0x2e, 0x0f, 0x86, 0x08, 0x3c, 0x23, 0xba, 0x9c, + 0x1e, 0xf1, 0xea, 0x8a, 0x49, 0x7a, 0x40, 0xda, 0xaf, 0x3f, + 0x5d, 0xe2, 0xce, 0xd2, 0xbf, 0x77, 0x69, 0xaa, 0x40, 0x75, + 0xae, 0x9c, 0x44, 0xb2, 0x0f, 0x82, 0xb3, 0xa6, 0xad, 0x98, + 0x02, 0xb6, 0x47, 0xe9, 0x7d, 0xa8, 0xf0, 0x16, 0x52, 0xa4, + 0xde, 0x6d, 0x87, 0x54, 0x6f, 0xc8, 0x3b, 0x11, 0x05, 0x41, + 0xaf, 0x9d, 0x3d, 0x26, 0x22, 0x46, 0xc6, 0x32, 0x1e, 0x0a, + 0x67, 0x3e, 0x14, 0xa5, 0x8c, 0xf0, 0xc4, 0xd5, 0x5b, 0x97, + 0xab, 0xd5, 0x3b, 0x29, 0x62, 0x5d, 0xd3, 0xf8, 0xf1, 0x15, + 0x47, 0x10, 0xcc, 0xb7, 0x0d, 0x99, 0x79, 0x73 }, + { 0x07, 0x7b, 0xa5, 0xea, 0x41, 0x21, 0x23, 0x50, 0xed, 0xfc, + 0x15, 0x48, 0x63, 0xb8, 0x5a, 0x35, 0x95, 0x10, 0x79, 0x18, + 0x11, 0x0c, 0x77, 0x9c, 0x96, 0x95, 0x98, 0xdd, 0xcc, 0x58, + 0x00, 0x0b, 0x64, 0x97, 0x59, 0x63, 0xcb, 0x11, 0x8f, 0xf9, + 0x79, 0xea, 0x49, 0xc2, 0x54, 0xe2, 0x9c, 0xdc, 0xcd, 0x65, + 0xd2, 0x37, 0x1f, 0x20, 0xb3, 0x22, 0x7d, 0x5a, 0x6f, 0xf6, + 0x54, 0xeb, 0x49, 0xff, 0x0b, 0x66, 0xd7, 0x89, 0x76, 0xf8, + 0x2d, 0xbd, 0xb6, 0xba, 0x85, 0x00, 0x8b, 0xb4, 0xcb, 0x93, + 0xc3, 0xbf, 0xd6, 0xa8, 0x3e, 0x70, 0x86, 0xfa, 0x2f, 0xb9, + 0xe0, 0xc3, 0xa2, 0xa7, 0xba, 0x07, 0x9f, 0x15, 0x53, 0xde, + 0x13, 0x3b, 0x23, 0x38, 0x46, 0x1e, 0x70, 0xcf, 0x87, 0x93, + 0xb2, 0x73, 0x15, 0x5e, 0xe5, 0x61, 0xac, 0x5e, 0x68, 0x83, + 0x05, 0xe5, 0x75, 0xfe, 0xfd, 0x14, 0x5c, 0xb5 }, + { 0x6b, 0x20, 0x06, 0xdf, 0x45, 0x91, 0xa2, 0xe2, 0xba, 0xf7, + 0x58, 0x1d, 0x9b, 0xc7, 0x7d, 0x21, 0x5b, 0x3c, 0x81, 0xb2, + 0xf4, 0x73, 0x96, 0x53, 0x09, 0x01, 0x26, 0x5c, 0xaf, 0xf0, + 0x75, 0x86, 0x81, 0x38, 0x99, 0x5a, 0x52, 0x35, 0x0e, 0x80, + 0xc9, 0x31, 0x79, 0xbd, 0xd3, 0xf5, 0x5c, 0x07, 0xab, 0xe5, + 0x23, 0x6e, 0x62, 0x99, 0xae, 0x7f, 0x2b, 0xe7, 0x02, 0x0d, + 0x45, 0xad, 0x59, 0x20, 0x9d, 0x28, 0x6e, 0xa7, 0x2c, 0xda, + 0xde, 0x77, 0xd5, 0x69, 0xaf, 0x36, 0x9a, 0xbf, 0x49, 0xee, + 0xd4, 0x6e, 0xc7, 0xe5, 0xf4, 0x64, 0xe8, 0xb3, 0xbb, 0x1d, + 0x31, 0xd1, 0x0e, 0x80, 0xc7, 0x60, 0x01, 0xdc, 0x1f, 0x98, + 0x8a, 0x32, 0xf1, 0x0f, 0x19, 0x12, 0xed, 0xc5, 0x80, 0x6d, + 0x02, 0x72, 0x43, 0x12, 0x14, 0x45, 0x05, 0x02, 0xa0, 0xab, + 0x0b, 0x3a, 0x38, 0xd3, 0xcd, 0xd8, 0x6f, 0x61 }, + { 0x53, 0x21, 0x7e, 0xa6, 0xbd, 0x26, 0xb5, 0x50, 0x85, 0x5b, + 0x91, 0x1c, 0x66, 0x86, 0x8a, 0xfc, 0x84, 0x95, 0x40, 0xc0, + 0x32, 0xc3, 0x8e, 0x83, 0x24, 0xd1, 0x16, 0xe6, 0x38, 0xd6, + 0xb0, 0xa0, 0x26, 0x2a, 0x6f, 0xb8, 0xc9, 0x17, 0xb1, 0x6c, + 0xd6, 0xc1, 0x2e, 0x10, 0x62, 0x57, 0x41, 0xa4, 0x5c, 0x8d, + 0x7a, 0x75, 0x27, 0x55, 0xf8, 0x94, 0xb4, 0x76, 0xf4, 0x1e, + 0x9d, 0xc1, 0x2c, 0xe9, 0x10, 0xd0, 0xcb, 0x97, 0x6f, 0xa8, + 0xb7, 0x75, 0x70, 0xa9, 0xf4, 0x0c, 0x15, 0x31, 0xc0, 0x5a, + 0x54, 0xf1, 0xa7, 0x01, 0x35, 0x7f, 0x67, 0x9e, 0x4f, 0x8a, + 0x61, 0x84, 0xd2, 0x12, 0x5c, 0xaf, 0x84, 0x72, 0x8f, 0x25, + 0x53, 0xd5, 0x12, 0x5e, 0xd5, 0x71, 0x8d, 0x33, 0x00, 0x0e, + 0x7f, 0x99, 0x93, 0x1f, 0x53, 0x6a, 0x96, 0x2b, 0xb4, 0xfd, + 0xb2, 0xfe, 0x50, 0xa8, 0x96, 0x5b, 0x1b, 0xc1 }, + { 0x03, 0x86, 0x93, 0x1e, 0xd9, 0xad, 0xbe, 0xef, 0x64, 0xbd, + 0x60, 0x01, 0x61, 0x83, 0x0a, 0xc2, 0xa0, 0x8d, 0x33, 0x79, + 0xf9, 0x78, 0x1b, 0x12, 0x99, 0x89, 0x3d, 0xd0, 0xf2, 0xbd, + 0x29, 0x5b, 0xf8, 0xe2, 0xd1, 0x73, 0x60, 0x44, 0xa9, 0xa6, + 0xa9, 0xe0, 0x8d, 0xcb, 0x4a, 0x6d, 0x65, 0xa1, 0xc8, 0x1e, + 0x01, 0xc9, 0xe9, 0xa0, 0x6f, 0x07, 0xa7, 0x27, 0xda, 0xcc, + 0x35, 0xcc, 0x05, 0x2f, 0x0f, 0x93, 0x8d, 0x1e, 0x42, 0xce, + 0x9e, 0xa8, 0xc4, 0xfa, 0xe9, 0xe8, 0xc3, 0xd4, 0xb1, 0xe1, + 0xa0, 0x7a, 0x96, 0xb3, 0x41, 0xc8, 0x15, 0xef, 0x6d, 0xc3, + 0xb8, 0x48, 0x38, 0x1a, 0x4f, 0xf7, 0xab, 0x7d, 0xaa, 0x2d, + 0xe4, 0xa5, 0x43, 0x44, 0x96, 0x4e, 0xb8, 0x5e, 0xca, 0xcb, + 0xd2, 0x6e, 0x96, 0x8d, 0xa9, 0xcb, 0xe6, 0x21, 0x14, 0x6c, + 0xfc, 0x84, 0x04, 0x73, 0x25, 0x9f, 0x52, 0xb4 }, + { 0x2c, 0xaa, 0xf7, 0x49, 0x15, 0x04, 0x1c, 0x20, 0x0e, 0x49, + 0x67, 0xcd, 0xb4, 0xa8, 0x74, 0x8b, 0xcd, 0x3a, 0x21, 0xd6, + 0xd5, 0x8c, 0x6d, 0xb8, 0x1b, 0xa0, 0x97, 0xfc, 0xb7, 0x66, + 0x86, 0x3d, 0x81, 0xce, 0x36, 0xef, 0x8b, 0xbd, 0xcc, 0xb2, + 0x45, 0x9e, 0x93, 0x67, 0xbf, 0x32, 0x0e, 0x0e, 0x82, 0x59, + 0x68, 0x87, 0xe5, 0xef, 0x50, 0x2f, 0x67, 0x7e, 0xdc, 0x88, + 0x29, 0x72, 0x72, 0x1a, 0x75, 0xba, 0xcd, 0x75, 0x0f, 0x9c, + 0x6c, 0x40, 0x41, 0x86, 0x79, 0xfd, 0x49, 0xff, 0xf5, 0xc4, + 0x55, 0xcb, 0xe7, 0x09, 0x03, 0x31, 0x6a, 0xd2, 0x35, 0x4f, + 0xf4, 0x47, 0x11, 0x15, 0x94, 0xcd, 0x61, 0xca, 0x2e, 0x78, + 0x69, 0x9c, 0xe4, 0xd6, 0x3b, 0xc2, 0x38, 0xcf, 0x53, 0x6e, + 0xba, 0xed, 0xed, 0x9d, 0x2b, 0x67, 0xe3, 0x55, 0xbb, 0x07, + 0xd0, 0xd7, 0xab, 0xb3, 0xd0, 0x98, 0x85, 0xa5 }, + { 0x86, 0xd7, 0xf5, 0x32, 0x45, 0xfe, 0x3b, 0xd8, 0x65, 0xa1, + 0xbb, 0xe2, 0x93, 0x50, 0x36, 0x1e, 0xc7, 0xc7, 0x1f, 0x3d, + 0x09, 0xd8, 0xff, 0x91, 0x36, 0xe8, 0x86, 0xe2, 0x70, 0xb0, + 0x55, 0x18, 0xb5, 0x6e, 0x45, 0xf1, 0xad, 0x50, 0xd9, 0xd9, + 0x6b, 0xb5, 0xd5, 0x11, 0xc1, 0x8a, 0x2b, 0xe7, 0x65, 0x6a, + 0x47, 0xca, 0x57, 0xd1, 0xa1, 0x70, 0x11, 0x72, 0x5d, 0x69, + 0xab, 0xac, 0x96, 0xf9, 0x30, 0x2c, 0x8f, 0x78, 0xf5, 0x67, + 0x23, 0xde, 0xb9, 0x09, 0xd2, 0x32, 0xd9, 0x25, 0xdc, 0xf2, + 0x9c, 0xe8, 0xe6, 0x81, 0x2d, 0xf3, 0x1f, 0xa4, 0x6c, 0xa8, + 0xb3, 0x20, 0x35, 0x6d, 0x39, 0x82, 0x48, 0xd0, 0xab, 0x75, + 0x7a, 0xe5, 0xb7, 0x0b, 0x26, 0x8e, 0xd1, 0xa5, 0x78, 0x1a, + 0x8c, 0x86, 0xb3, 0xe4, 0xea, 0x23, 0x22, 0x47, 0x15, 0x45, + 0x44, 0xf9, 0x80, 0x06, 0x6e, 0xd2, 0x04, 0x24 }, + { 0x68, 0x2a, 0x55, 0xe3, 0x86, 0xc0, 0xb4, 0xdd, 0x5a, 0x4c, + 0x3c, 0x6f, 0xcb, 0xc1, 0xff, 0x85, 0x52, 0xc9, 0x4d, 0x0f, + 0x7d, 0x83, 0x6c, 0x5a, 0x5f, 0xfe, 0x5f, 0x94, 0x3d, 0xb6, + 0x08, 0x3c, 0x68, 0xee, 0xea, 0x62, 0xea, 0xe7, 0x5b, 0x16, + 0x68, 0xa6, 0x76, 0xdb, 0x88, 0x37, 0xd5, 0x1d, 0x00, 0x7f, + 0x3b, 0xaf, 0x24, 0x19, 0x8f, 0xd2, 0x4f, 0x5b, 0x45, 0x39, + 0x6e, 0x2b, 0xd8, 0x11, 0x0f, 0xb2, 0x39, 0xa8, 0x57, 0x9b, + 0xcc, 0x13, 0x36, 0x9f, 0x3b, 0xd9, 0x83, 0x55, 0xb0, 0x58, + 0x58, 0x30, 0x06, 0x44, 0xfb, 0xea, 0x45, 0xb8, 0x4d, 0xa3, + 0xb9, 0xdb, 0x88, 0x7e, 0xc6, 0x66, 0xd3, 0xe3, 0xac, 0x54, + 0x90, 0x89, 0x8d, 0x1c, 0xfa, 0xe5, 0x0e, 0x52, 0x26, 0xcd, + 0x01, 0xb4, 0xb6, 0x97, 0x50, 0x98, 0x8b, 0xc3, 0xd9, 0x13, + 0x99, 0xf1, 0x6e, 0xb6, 0xb0, 0xbf, 0x71, 0x9a }, + { 0x02, 0x22, 0x7f, 0xa6, 0xfe, 0xfe, 0x4d, 0xcd, 0x05, 0x4f, + 0x25, 0x42, 0xe4, 0x0d, 0x39, 0x05, 0xd2, 0xcd, 0xf0, 0x1b, + 0x76, 0x88, 0xd7, 0x0c, 0xdc, 0xec, 0xc3, 0xab, 0x7b, 0x4c, + 0x7c, 0x91, 0xad, 0x73, 0x70, 0x52, 0xc6, 0xfd, 0xd7, 0xa6, + 0x41, 0x5d, 0x46, 0xa0, 0x85, 0x2f, 0x76, 0x11, 0x2c, 0xc3, + 0x0a, 0x31, 0xff, 0x4b, 0x04, 0x5c, 0x9b, 0xc7, 0xfd, 0x4f, + 0x14, 0x52, 0xd0, 0xac, 0x6c, 0x44, 0x76, 0x84, 0x49, 0xcd, + 0xc2, 0x1a, 0x15, 0x43, 0xf2, 0x7e, 0x23, 0x24, 0xa6, 0x8b, + 0xc8, 0x99, 0x27, 0xe6, 0x8a, 0x87, 0x72, 0x27, 0x1b, 0x13, + 0x34, 0x2f, 0x14, 0x29, 0x66, 0x29, 0x89, 0x0d, 0x39, 0x65, + 0xec, 0xc3, 0xe5, 0xe7, 0xd6, 0xae, 0x0c, 0xc5, 0xb7, 0x5a, + 0x46, 0xe3, 0x22, 0x76, 0x02, 0x6c, 0x34, 0xc7, 0x24, 0x5d, + 0xc8, 0xf2, 0x35, 0xa4, 0x58, 0x74, 0x95, 0xaa }, + { 0x54, 0x7e, 0x24, 0x9a, 0x29, 0x26, 0x97, 0x78, 0x44, 0x6e, + 0x6a, 0x62, 0x15, 0xeb, 0xc7, 0xd0, 0x34, 0x27, 0xe5, 0x4d, + 0x7d, 0xd3, 0x75, 0x78, 0x64, 0xfc, 0x55, 0xfc, 0x28, 0xff, + 0xba, 0x81, 0x97, 0x1e, 0xb9, 0x15, 0xd5, 0xc4, 0xe8, 0x43, + 0x5f, 0x37, 0x16, 0xdf, 0xe3, 0x42, 0x0e, 0xea, 0xf5, 0xa5, + 0xc2, 0x2e, 0xbb, 0xc9, 0xf1, 0xa5, 0x64, 0xd1, 0x6e, 0x9f, + 0x88, 0x11, 0x67, 0xf4, 0xb0, 0x21, 0xe1, 0x4e, 0x07, 0x10, + 0xae, 0x9a, 0xbc, 0x1f, 0x27, 0x9d, 0x68, 0xfa, 0x4f, 0xce, + 0x21, 0xc9, 0x55, 0xf9, 0x8e, 0x08, 0xcb, 0x04, 0x09, 0x59, + 0xd0, 0x44, 0xb4, 0xcb, 0xec, 0xa0, 0x9d, 0x10, 0x90, 0xbf, + 0x96, 0xf7, 0xc5, 0xe5, 0xcb, 0x12, 0x8e, 0x09, 0x4f, 0x2c, + 0x8b, 0x22, 0x8e, 0xfe, 0xed, 0x46, 0xfd, 0xfd, 0x22, 0x5d, + 0x18, 0x05, 0xef, 0xd9, 0xb7, 0x51, 0x94, 0x8b }, + { 0x45, 0xa4, 0x1c, 0xc0, 0xd2, 0xb0, 0x8e, 0xea, 0xc4, 0x2d, + 0xc7, 0x45, 0xbf, 0xe6, 0xc1, 0xeb, 0x1c, 0x68, 0x5c, 0xea, + 0x3c, 0x61, 0x32, 0xe6, 0xfc, 0xeb, 0x5c, 0x90, 0x8b, 0xcb, + 0x25, 0x05, 0x34, 0x79, 0xbe, 0xa1, 0xc2, 0x20, 0x21, 0x8b, + 0x74, 0x75, 0xe0, 0xe8, 0x31, 0x91, 0xd4, 0xe3, 0xd2, 0x45, + 0x65, 0x69, 0x79, 0x32, 0xa1, 0xf0, 0xe5, 0x7e, 0x4d, 0x29, + 0x61, 0x6f, 0xde, 0xda, 0x7f, 0xfd, 0xdf, 0x84, 0x03, 0xdc, + 0xf1, 0xce, 0xa0, 0xc5, 0xbb, 0x1d, 0xdd, 0xee, 0xc0, 0x25, + 0x18, 0xc9, 0x9d, 0x83, 0xaa, 0x2f, 0x7d, 0x51, 0x3d, 0x2c, + 0x09, 0xba, 0xf9, 0x34, 0x28, 0x23, 0x5b, 0x41, 0x27, 0xea, + 0x9d, 0xe5, 0xe7, 0x0a, 0xf6, 0x51, 0x51, 0xe1, 0x0a, 0x63, + 0xf3, 0xd8, 0xb4, 0xe6, 0xcd, 0xcc, 0x79, 0x55, 0xcf, 0x50, + 0x47, 0x06, 0x86, 0x8a, 0xa1, 0xff, 0xda, 0x27 }, + { 0x12, 0x87, 0x63, 0xc9, 0x42, 0xee, 0x40, 0xc8, 0xba, 0x85, + 0x0a, 0xc9, 0xd0, 0x87, 0xda, 0x02, 0xa8, 0x4c, 0x06, 0xb6, + 0xb6, 0xac, 0x2a, 0xf6, 0x36, 0x2d, 0x7a, 0x77, 0xd8, 0x8e, + 0x69, 0x44, 0x2d, 0x32, 0x59, 0xd4, 0x8a, 0x0f, 0x29, 0x8c, + 0x0f, 0x0b, 0xd9, 0xbd, 0x28, 0xff, 0xf6, 0xdd, 0x14, 0x56, + 0x01, 0xed, 0x3d, 0x58, 0x9b, 0xea, 0xc8, 0x7b, 0xe1, 0xe4, + 0x49, 0xdf, 0x78, 0x1e, 0x96, 0x32, 0x3d, 0x25, 0x24, 0x21, + 0xe3, 0x75, 0xb2, 0xaf, 0xbd, 0xdc, 0x0d, 0xf3, 0x18, 0x4e, + 0x93, 0xdf, 0x7d, 0xa4, 0x98, 0x4f, 0xd1, 0x1f, 0x2c, 0x9e, + 0x4f, 0x52, 0xa2, 0x85, 0x74, 0x1a, 0x4f, 0x54, 0x12, 0xd2, + 0xa9, 0xbe, 0xb1, 0x7e, 0xdc, 0x1e, 0xa7, 0x58, 0x5e, 0xeb, + 0x4c, 0x66, 0x41, 0xff, 0x96, 0x2f, 0xa1, 0x7c, 0xf7, 0x0e, + 0x3e, 0xa9, 0xb2, 0xc7, 0x4d, 0xbb, 0xf0, 0xe1 }, + { 0x75, 0xe9, 0x6b, 0xcc, 0xfc, 0x4f, 0x74, 0xd2, 0x1e, 0x82, + 0x04, 0xb7, 0x68, 0xbb, 0x63, 0x7f, 0x6a, 0x7e, 0x00, 0x67, + 0xb4, 0x12, 0x6d, 0x72, 0x5e, 0x8c, 0xa1, 0xf9, 0xb2, 0x0f, + 0xcd, 0x74, 0x7e, 0x8d, 0xa5, 0x13, 0x99, 0xb3, 0xa0, 0xeb, + 0x21, 0x60, 0xcb, 0x18, 0xb1, 0x3e, 0xb7, 0x1b, 0x07, 0x36, + 0x55, 0x61, 0xb1, 0xc9, 0x95, 0xf3, 0xb4, 0x76, 0x56, 0x5e, + 0x03, 0x21, 0x81, 0x23, 0x3f, 0x1d, 0x8d, 0x88, 0xc1, 0xde, + 0x7e, 0xbc, 0xfe, 0x9f, 0xda, 0x66, 0x8b, 0x88, 0x17, 0x52, + 0x5b, 0x29, 0xd2, 0x13, 0x9a, 0x2e, 0x8e, 0x03, 0x7c, 0x75, + 0xf5, 0xc4, 0xcb, 0x08, 0x85, 0x48, 0xb2, 0x11, 0x5d, 0xa3, + 0x86, 0x61, 0x57, 0x67, 0xe9, 0x63, 0x1d, 0x14, 0x70, 0xfe, + 0xde, 0xd2, 0x7c, 0xc2, 0x00, 0x44, 0x34, 0xb0, 0x8f, 0x6e, + 0x29, 0xa8, 0x0f, 0x07, 0xac, 0xba, 0xc1, 0x78 }, + { 0x30, 0x9a, 0x6e, 0x9a, 0xba, 0x26, 0x89, 0x49, 0xd8, 0x8f, + 0x56, 0x6b, 0xa1, 0x6e, 0x52, 0x3d, 0x8a, 0x86, 0xf0, 0x9b, + 0x5d, 0x6b, 0x81, 0x96, 0xae, 0xba, 0x4f, 0xe4, 0x8a, 0xe5, + 0xb6, 0x87, 0xfe, 0x02, 0xf8, 0x3c, 0xb1, 0x48, 0x76, 0x27, + 0x9c, 0x57, 0xb0, 0x29, 0xcf, 0x3d, 0xe4, 0x92, 0x98, 0x5e, + 0xf8, 0xd2, 0x42, 0xd1, 0xd9, 0x92, 0xe8, 0x0b, 0x2e, 0x7a, + 0xc1, 0x5b, 0x24, 0x89, 0xa7, 0x67, 0x26, 0x83, 0xea, 0x87, + 0x6f, 0x48, 0x60, 0x08, 0x3b, 0xd8, 0x81, 0x50, 0x91, 0x29, + 0xa9, 0x78, 0x88, 0x36, 0x4f, 0x53, 0xf5, 0x5f, 0x91, 0xd8, + 0x5d, 0x46, 0x4d, 0x6f, 0xd5, 0xb7, 0x12, 0xb6, 0xbf, 0x83, + 0x6c, 0x07, 0x15, 0x0f, 0x64, 0xa8, 0x46, 0xd1, 0xea, 0x98, + 0x7d, 0x2a, 0xdf, 0x58, 0x50, 0x58, 0x7c, 0x38, 0x45, 0x25, + 0x18, 0x9d, 0x1f, 0xdc, 0x0d, 0x19, 0x71, 0x6e }, + { 0x04, 0x58, 0x25, 0x8a, 0xd7, 0x59, 0x37, 0x89, 0xee, 0xb3, + 0x66, 0x53, 0x57, 0x69, 0xb2, 0x02, 0xe3, 0x59, 0x78, 0xfd, + 0x71, 0x4f, 0xea, 0x55, 0xcf, 0x96, 0x73, 0xc7, 0x75, 0xd6, + 0x8a, 0xc1, 0xd4, 0x2e, 0x87, 0x7f, 0xdb, 0x2a, 0x35, 0x8a, + 0x92, 0x4d, 0xbe, 0x7d, 0x53, 0xbe, 0x7e, 0xfd, 0xd3, 0x1c, + 0xcf, 0xd6, 0x21, 0xc2, 0xb6, 0x3d, 0x26, 0x7f, 0x8d, 0x8f, + 0x8e, 0x1e, 0xee, 0x88, 0x0f, 0xbb, 0x17, 0x14, 0x1f, 0xa2, + 0x64, 0xe8, 0xa1, 0x5b, 0x33, 0x62, 0xc4, 0x9d, 0x5c, 0xcb, + 0xc5, 0x81, 0xef, 0x87, 0xeb, 0x90, 0x86, 0x81, 0xc0, 0xc3, + 0xac, 0xdb, 0x75, 0x50, 0xed, 0x3a, 0x8f, 0xa1, 0x5a, 0x85, + 0xbe, 0xd3, 0x6c, 0xc5, 0xcc, 0x7b, 0xeb, 0x01, 0x7f, 0xe0, + 0x9f, 0x5c, 0x1a, 0x5f, 0xe7, 0x0f, 0xb8, 0xc5, 0x0c, 0x4d, + 0xef, 0x27, 0xee, 0x50, 0xbd, 0xfb, 0xe9, 0x7a }, + { 0x53, 0xf4, 0xa3, 0xe0, 0x95, 0xb7, 0x73, 0x58, 0xa2, 0xb8, + 0x80, 0xe5, 0x6f, 0x86, 0xc0, 0x29, 0x00, 0x4b, 0x87, 0x57, + 0xe4, 0x1f, 0xac, 0xc0, 0xba, 0xaf, 0x66, 0x3c, 0x96, 0xd1, + 0x09, 0x91, 0x7f, 0x74, 0x91, 0x5b, 0x2e, 0x84, 0xec, 0x34, + 0xbe, 0xe1, 0x48, 0x43, 0x4f, 0x02, 0x90, 0x4b, 0x83, 0xc8, + 0xf6, 0xa6, 0xe7, 0xb6, 0xd8, 0x86, 0xc0, 0x89, 0x5b, 0xff, + 0x39, 0x77, 0x7e, 0x00, 0xb3, 0x5f, 0xce, 0x26, 0xd6, 0xb3, + 0xc7, 0x42, 0x98, 0xc0, 0x56, 0x58, 0x43, 0x34, 0x6b, 0x9c, + 0xe0, 0xee, 0x85, 0x1d, 0xa3, 0x07, 0x67, 0xc3, 0xf5, 0x6a, + 0x8d, 0xef, 0x0f, 0x0e, 0x6b, 0x5f, 0x28, 0x5d, 0x67, 0x45, + 0xca, 0x2e, 0x89, 0x2e, 0x0e, 0x66, 0xcb, 0xa7, 0x0d, 0x2e, + 0x66, 0x57, 0x2d, 0x40, 0x58, 0x57, 0x57, 0x79, 0xdf, 0xa2, + 0x5d, 0xf7, 0x1a, 0x74, 0xa0, 0x42, 0xdb, 0xdf }, + { 0x0a, 0x99, 0xe6, 0x53, 0xd7, 0x23, 0xd2, 0x36, 0xaa, 0xf9, + 0x8d, 0x74, 0x69, 0x08, 0xd5, 0x63, 0x85, 0x01, 0x56, 0x2e, + 0x30, 0x5e, 0x99, 0xf0, 0x13, 0xa3, 0xf1, 0x45, 0x51, 0xd9, + 0x10, 0x73, 0x7c, 0x26, 0x4e, 0x6d, 0x48, 0x3e, 0xd8, 0x9a, + 0x16, 0xe8, 0xd9, 0x89, 0x24, 0x9e, 0x26, 0xf2, 0xfe, 0xb8, + 0xcc, 0xa0, 0xc4, 0x58, 0x45, 0xcf, 0x97, 0xc8, 0xdc, 0x0e, + 0xfc, 0x1c, 0xb5, 0xb5, 0xd3, 0x59, 0x47, 0xf5, 0xf3, 0xa8, + 0xf7, 0xf0, 0x38, 0xee, 0xc0, 0xcd, 0x28, 0x5d, 0xf2, 0xbf, + 0x42, 0xaa, 0x1a, 0xb6, 0x2b, 0x77, 0xb7, 0xa9, 0xe2, 0x6d, + 0x90, 0xb1, 0x76, 0x31, 0x91, 0x60, 0x7d, 0x2e, 0xfa, 0xea, + 0x79, 0x75, 0x7c, 0xb6, 0xf0, 0x6b, 0xcb, 0xf8, 0xa0, 0xc1, + 0xcb, 0x5a, 0xba, 0x60, 0xc5, 0x77, 0xaf, 0xab, 0x5a, 0xeb, + 0x11, 0xbb, 0x08, 0xce, 0x89, 0xfc, 0x48, 0xe7 }, + { 0x3a, 0x95, 0xcb, 0x45, 0x01, 0x0f, 0xcb, 0xc0, 0xb5, 0x95, + 0xdb, 0xd1, 0x3e, 0xeb, 0xf7, 0xea, 0x96, 0x50, 0xfc, 0x31, + 0x75, 0x32, 0x55, 0x48, 0x9f, 0x76, 0x87, 0x75, 0x33, 0x26, + 0x39, 0xe7, 0xd9, 0x73, 0x43, 0xee, 0x83, 0x23, 0xdd, 0xfa, + 0xfe, 0x20, 0x21, 0xe3, 0x42, 0x48, 0xe3, 0xd8, 0xc1, 0x26, + 0xa9, 0x3a, 0x0d, 0x0e, 0x30, 0x63, 0xcf, 0x74, 0x72, 0x73, + 0xf7, 0x84, 0x85, 0x23, 0xc5, 0xcd, 0x9a, 0xbe, 0x29, 0xb7, + 0x4d, 0x9a, 0x9a, 0xd3, 0x18, 0x93, 0x8c, 0x17, 0x0a, 0x36, + 0xa6, 0xf2, 0xdf, 0x8b, 0x46, 0x65, 0x52, 0xdb, 0xc6, 0x0f, + 0xf5, 0x7a, 0xab, 0x79, 0x3a, 0x2d, 0x61, 0x25, 0x4b, 0xe1, + 0x13, 0x78, 0xe9, 0x07, 0x22, 0x9f, 0xd2, 0x29, 0x0c, 0x16, + 0x81, 0xb5, 0xc1, 0x63, 0x06, 0x7b, 0x9a, 0xa1, 0xa1, 0x60, + 0x23, 0x53, 0x6f, 0x46, 0xab, 0xbc, 0x05, 0x59 }, + { 0x36, 0x6d, 0x22, 0x2e, 0x03, 0x0b, 0x72, 0x45, 0x5d, 0x71, + 0x3c, 0x1d, 0xda, 0xd6, 0x72, 0xc3, 0x93, 0x59, 0x7f, 0x66, + 0x32, 0x97, 0x84, 0xf1, 0x48, 0x5b, 0xb4, 0x36, 0xcd, 0xba, + 0x93, 0xda, 0x01, 0x70, 0x2d, 0xc1, 0x47, 0x44, 0xae, 0xe6, + 0xa5, 0xfb, 0x63, 0x9b, 0x41, 0xcc, 0xab, 0xa3, 0x2a, 0x2f, + 0xa3, 0xa0, 0x24, 0x53, 0x2a, 0xb3, 0x01, 0x57, 0xca, 0xa4, + 0x8c, 0xd0, 0x92, 0xda, 0xf0, 0x07, 0x7c, 0xdb, 0xd2, 0x7e, + 0x64, 0xdb, 0x54, 0x5d, 0x09, 0x25, 0x51, 0x86, 0xd2, 0x18, + 0x1a, 0x5b, 0xc3, 0xc3, 0xa6, 0x90, 0x2b, 0xda, 0x0c, 0x57, + 0x98, 0xab, 0x32, 0xcd, 0x08, 0xd2, 0x79, 0x65, 0xc0, 0xb0, + 0x91, 0xca, 0xd8, 0xce, 0x02, 0xa9, 0x2c, 0x77, 0x71, 0x69, + 0x43, 0x8a, 0x8d, 0xd1, 0xcb, 0x4b, 0xc1, 0xd5, 0xc4, 0x8f, + 0x95, 0x4e, 0x68, 0xcb, 0x39, 0xd7, 0xff, 0x2e }, + { 0x90, 0x72, 0xba, 0x99, 0x79, 0xde, 0xfd, 0x25, 0x17, 0x3d, + 0xcc, 0xd2, 0x06, 0x61, 0xbf, 0xda, 0x44, 0x28, 0x71, 0x53, + 0xd3, 0x08, 0x93, 0xfd, 0x4b, 0xb7, 0x6e, 0x73, 0xe5, 0x93, + 0x2b, 0x7e, 0x05, 0x5e, 0xa6, 0xdd, 0xad, 0xf1, 0xb3, 0x68, + 0x43, 0x40, 0x8d, 0xe1, 0x5f, 0x97, 0x1b, 0x8e, 0x4e, 0x8b, + 0x31, 0x45, 0xdd, 0x2f, 0x17, 0x59, 0x98, 0xed, 0x14, 0x99, + 0x2b, 0x8a, 0x78, 0xd8, 0x6d, 0xc5, 0xfe, 0xe7, 0x3f, 0x48, + 0xca, 0x07, 0x66, 0x92, 0x71, 0x2c, 0x7b, 0x5a, 0xd0, 0x7d, + 0xae, 0x14, 0x11, 0x47, 0xd3, 0x2a, 0xcd, 0x21, 0x0b, 0x8e, + 0xbf, 0x05, 0xa5, 0x38, 0xbf, 0x49, 0x72, 0x2a, 0x80, 0xa5, + 0xcf, 0x11, 0x44, 0x60, 0x7b, 0x53, 0xfa, 0x65, 0x7a, 0x1a, + 0x03, 0x10, 0x0f, 0xce, 0x40, 0x1b, 0xa9, 0x0d, 0xa4, 0x4d, + 0xd5, 0x0b, 0x48, 0x75, 0x57, 0x3e, 0xa5, 0xb2 }, + { 0x8d, 0x92, 0xc6, 0xbd, 0x35, 0x54, 0x6c, 0x29, 0x26, 0xac, + 0x96, 0x52, 0x43, 0x9d, 0x16, 0x54, 0x7e, 0x8f, 0x23, 0xd9, + 0xb6, 0xa8, 0x8f, 0x46, 0x7e, 0x60, 0x8d, 0x97, 0x7d, 0x6c, + 0x02, 0xee, 0x4d, 0x81, 0x5a, 0x40, 0x7f, 0x0f, 0x15, 0x3f, + 0x6b, 0x19, 0xbe, 0xa9, 0x35, 0xe1, 0x1b, 0xda, 0x33, 0xb2, + 0x88, 0x6d, 0x6b, 0x87, 0x1f, 0x8d, 0x56, 0x17, 0x1e, 0xcf, + 0xb0, 0xa0, 0xf5, 0x92, 0x6a, 0xe0, 0xe2, 0x2b, 0xfb, 0xdf, + 0xa5, 0xba, 0xea, 0x3e, 0x8a, 0xc6, 0x8a, 0xd1, 0x22, 0x42, + 0xa6, 0xe4, 0xc9, 0x87, 0x72, 0x9c, 0x09, 0xe3, 0x4e, 0xd0, + 0x72, 0xb3, 0x8f, 0x0e, 0xc9, 0xb3, 0x6a, 0x38, 0x28, 0x6f, + 0x3f, 0x3d, 0xf1, 0xd5, 0x0b, 0x0e, 0x8b, 0xb1, 0xcd, 0x3a, + 0x9c, 0x43, 0xfb, 0xf1, 0x64, 0x9f, 0xc8, 0x31, 0xce, 0xe8, + 0x47, 0x4d, 0xe4, 0xdd, 0x96, 0x20, 0xea, 0x39 }, + { 0x4e, 0x4b, 0xec, 0x17, 0x5c, 0x1a, 0xe5, 0xc0, 0x8d, 0x43, + 0xd8, 0x98, 0x8d, 0xd8, 0x27, 0xea, 0xf8, 0x05, 0x39, 0x6c, + 0x29, 0x05, 0x3e, 0xf5, 0x30, 0xaa, 0x52, 0xb1, 0xcb, 0xbb, + 0x54, 0x70, 0xa8, 0x8f, 0xda, 0xbf, 0x78, 0x88, 0x4c, 0x25, + 0x54, 0xbf, 0x9d, 0xe1, 0x53, 0xbd, 0xe6, 0x3d, 0xbe, 0x6a, + 0x50, 0x2b, 0x81, 0xf9, 0x0b, 0xdc, 0x97, 0xad, 0xec, 0x2d, + 0xf0, 0xa6, 0x21, 0xb0, 0xab, 0xcc, 0x81, 0x5a, 0xfa, 0x57, + 0xae, 0x0a, 0x91, 0x6a, 0x77, 0x9c, 0xbd, 0xa0, 0xb9, 0x47, + 0x87, 0x4e, 0xe8, 0x40, 0xf9, 0x3f, 0x58, 0x1c, 0x12, 0x45, + 0xad, 0xbc, 0x43, 0x5c, 0xfe, 0xe1, 0x9e, 0xce, 0x2e, 0x1f, + 0x1c, 0xd4, 0x4b, 0xc3, 0x57, 0xd1, 0xb2, 0x26, 0xde, 0x80, + 0x84, 0x99, 0xfb, 0xe3, 0x52, 0x54, 0x3e, 0x0e, 0x42, 0xf8, + 0xb3, 0xe0, 0xd7, 0xce, 0xab, 0xeb, 0x0f, 0xf7 }, + { 0x7a, 0x4a, 0xa3, 0xf5, 0x6f, 0x9d, 0xed, 0x24, 0x72, 0xe6, + 0x7d, 0x1a, 0xb4, 0x87, 0x76, 0x77, 0x64, 0x7e, 0x3d, 0x28, + 0xec, 0x7e, 0x81, 0xa2, 0x02, 0xb9, 0x4c, 0xb3, 0x32, 0x92, + 0x81, 0x3a, 0x44, 0x9c, 0x20, 0xa5, 0x98, 0xf5, 0x08, 0xa8, + 0xa9, 0xc8, 0x08, 0x00, 0xec, 0x2c, 0x63, 0xfe, 0x2c, 0x0e, + 0x8f, 0x30, 0xff, 0x56, 0xa9, 0xa1, 0xa6, 0xdc, 0xe0, 0x67, + 0xb4, 0xe8, 0x33, 0xa5, 0x0b, 0xd4, 0xbc, 0x6b, 0xd4, 0xfd, + 0x13, 0x5e, 0x47, 0x70, 0x45, 0x81, 0xb9, 0x0a, 0xf0, 0xb5, + 0x8d, 0x1b, 0x95, 0xd0, 0x9e, 0xd7, 0x46, 0xf0, 0x64, 0x4b, + 0xba, 0x98, 0x16, 0xe3, 0x51, 0x58, 0xe7, 0x91, 0x5f, 0xd2, + 0x84, 0x3f, 0xe7, 0xd8, 0xa6, 0x85, 0x2e, 0xf3, 0xd7, 0x02, + 0xa5, 0xdd, 0x45, 0x7c, 0x4a, 0x3f, 0x19, 0xea, 0x9a, 0x94, + 0xbf, 0x84, 0x83, 0xa2, 0xfc, 0xc0, 0x96, 0x76 }, + { 0x60, 0x28, 0x2a, 0x7b, 0xf7, 0xf0, 0xad, 0xe1, 0x0c, 0xbd, + 0x7d, 0xc8, 0xc0, 0xa2, 0x69, 0xc5, 0xdc, 0x9d, 0xfa, 0x4f, + 0xb4, 0x1a, 0xb5, 0xdf, 0x48, 0xfc, 0xeb, 0xde, 0x9f, 0xd0, + 0x9d, 0xf8, 0x15, 0x99, 0x2f, 0xb4, 0x28, 0xd6, 0x9b, 0x12, + 0x38, 0xe0, 0xbf, 0x42, 0x1a, 0x19, 0x27, 0x4f, 0xc1, 0xee, + 0xb3, 0xf3, 0xa9, 0xd3, 0xfe, 0x55, 0x67, 0xdc, 0xa1, 0x9d, + 0xcd, 0xce, 0x38, 0x1e, 0x77, 0x5d, 0xce, 0x9d, 0xb0, 0x51, + 0x2e, 0xa6, 0x96, 0xcc, 0x64, 0x0f, 0xcd, 0x3f, 0x4b, 0xb7, + 0x74, 0xf8, 0xfe, 0xe0, 0x34, 0xa2, 0xc8, 0x3b, 0x5a, 0xc6, + 0x81, 0x32, 0xaf, 0xfa, 0x1f, 0xcf, 0x97, 0x54, 0x4f, 0xc5, + 0x9b, 0x3f, 0x9c, 0x54, 0x23, 0xa4, 0x78, 0xe4, 0x39, 0xcf, + 0x8d, 0x24, 0xdc, 0x81, 0x2d, 0x4f, 0xb2, 0x42, 0xcb, 0x50, + 0x55, 0x9e, 0xf1, 0xba, 0xe2, 0x7a, 0x00, 0x45 }, + { 0x5f, 0x4a, 0xe9, 0xc7, 0x23, 0xc6, 0xb9, 0x42, 0x3f, 0xd2, + 0x86, 0xd9, 0x4a, 0x5f, 0xbe, 0x70, 0xe4, 0x7a, 0x75, 0x39, + 0x68, 0xcc, 0x39, 0xed, 0x2d, 0x6a, 0x40, 0x7d, 0xfb, 0xc5, + 0xc3, 0x72, 0x55, 0x50, 0xf7, 0xac, 0xd8, 0xc7, 0x3a, 0x43, + 0xe9, 0x01, 0x66, 0xd0, 0x0f, 0xa5, 0x16, 0xae, 0x5f, 0xb7, + 0x42, 0xf9, 0x19, 0x01, 0x91, 0x38, 0xc3, 0x0b, 0x71, 0x4e, + 0x16, 0xfe, 0x46, 0x6a, 0xf1, 0xe8, 0x2f, 0xfe, 0x00, 0x86, + 0x9b, 0xcd, 0x38, 0x69, 0x2c, 0xa8, 0x2c, 0xad, 0x14, 0x40, + 0x4c, 0x99, 0xf2, 0x58, 0x91, 0xa7, 0xb6, 0x42, 0xc6, 0x3a, + 0x34, 0x17, 0xb5, 0xe6, 0xb4, 0x05, 0xf2, 0x1b, 0x69, 0xfb, + 0xc7, 0x77, 0x6a, 0x10, 0x67, 0x68, 0x28, 0xf9, 0x4f, 0x1f, + 0x65, 0x16, 0x38, 0xa3, 0x22, 0xc8, 0x3c, 0x42, 0x06, 0x1d, + 0x7c, 0x07, 0xe5, 0x38, 0xdc, 0xee, 0xa2, 0xe7 }, + { 0x92, 0xa0, 0x14, 0x23, 0xdc, 0x46, 0xaf, 0xd2, 0x9c, 0xd3, + 0xe2, 0x91, 0x40, 0x1a, 0xa5, 0x03, 0x93, 0x9a, 0x7f, 0x26, + 0xac, 0xa4, 0xaa, 0x80, 0x2f, 0x64, 0xce, 0x73, 0x51, 0x0e, + 0x4d, 0x9c, 0xa2, 0x35, 0x27, 0x35, 0x2f, 0x27, 0x52, 0xaf, + 0xf5, 0xb3, 0xb4, 0xc6, 0xc9, 0x01, 0x42, 0x0c, 0x32, 0xee, + 0x98, 0xd4, 0x15, 0x66, 0x1c, 0x2d, 0x88, 0xb3, 0x46, 0x49, + 0x6b, 0x73, 0x66, 0xa9, 0xbb, 0xca, 0xdb, 0x87, 0x7a, 0x68, + 0xfc, 0x0a, 0xa4, 0xbc, 0xa8, 0x6e, 0xa8, 0x65, 0x88, 0x17, + 0xb9, 0x8c, 0x47, 0x1e, 0xf9, 0xe5, 0xee, 0x02, 0xc4, 0x15, + 0x1b, 0x0a, 0xa3, 0x76, 0x61, 0xb3, 0x25, 0x48, 0x8a, 0x0d, + 0x9f, 0x21, 0x95, 0xea, 0x44, 0x9a, 0x01, 0xfb, 0xfd, 0xd4, + 0xb0, 0x51, 0x28, 0x6d, 0x45, 0xd0, 0x16, 0xda, 0x19, 0x92, + 0xd9, 0x6a, 0x2d, 0xda, 0x53, 0xf4, 0xd5, 0x61 }, + { 0x0f, 0xc8, 0xfe, 0x1e, 0xaa, 0x88, 0xcb, 0x9b, 0x90, 0x74, + 0x87, 0x06, 0x16, 0x1c, 0x51, 0x5b, 0x6f, 0x2c, 0x42, 0x8b, + 0x89, 0x60, 0x95, 0x7e, 0xf9, 0x60, 0xb5, 0xb9, 0x94, 0x06, + 0xc3, 0xbd, 0x86, 0xdc, 0x2b, 0xa3, 0xe4, 0x88, 0x78, 0x9e, + 0x9c, 0xa1, 0x9a, 0x43, 0xd9, 0x9b, 0x08, 0x57, 0x2a, 0x22, + 0x62, 0x63, 0x16, 0xa4, 0xc8, 0x7e, 0x04, 0x57, 0x9f, 0x2c, + 0xac, 0xb5, 0xe4, 0x6e, 0x9f, 0x62, 0x30, 0xd7, 0x74, 0x24, + 0x01, 0x95, 0x82, 0x3f, 0xee, 0x7a, 0x82, 0x56, 0x6a, 0xbd, + 0x27, 0x4d, 0xd8, 0x5e, 0x05, 0x8d, 0x90, 0xbd, 0xe8, 0x7f, + 0x7d, 0x01, 0x7a, 0x67, 0x56, 0xfb, 0x9a, 0xb7, 0x13, 0xe2, + 0x48, 0x14, 0x19, 0x41, 0x96, 0x3e, 0x25, 0xbb, 0x86, 0x48, + 0xf1, 0x28, 0xda, 0x8c, 0x90, 0x0f, 0xb7, 0xd5, 0x27, 0xfa, + 0xe9, 0xf2, 0x4b, 0xe1, 0x1c, 0x2f, 0x7d, 0xbd }, + { 0x2d, 0x0b, 0xa8, 0x62, 0xdf, 0xd3, 0x78, 0x9f, 0x3c, 0x95, + 0x4d, 0x86, 0xd9, 0x98, 0x92, 0xdd, 0x39, 0x28, 0x5e, 0x51, + 0x5d, 0xc6, 0xdc, 0xbe, 0x3a, 0xd2, 0x75, 0x30, 0x5e, 0x88, + 0x74, 0xc5, 0xc6, 0xcc, 0xf5, 0xce, 0x70, 0x1a, 0xfb, 0xf3, + 0x2b, 0x3f, 0x1d, 0xab, 0xa2, 0xc4, 0xb1, 0x60, 0x95, 0xe8, + 0xf4, 0x6e, 0x78, 0xc1, 0x31, 0x8f, 0xe1, 0x50, 0xb6, 0xb4, + 0x2b, 0xf3, 0x29, 0x41, 0xdf, 0x36, 0x7c, 0x75, 0x1d, 0x89, + 0x83, 0x7e, 0xb1, 0x39, 0x1e, 0x70, 0xc8, 0x60, 0xf3, 0xff, + 0xc2, 0x64, 0x86, 0x8e, 0x16, 0x2c, 0xab, 0x31, 0xbd, 0x7e, + 0xa7, 0x03, 0x5e, 0x6f, 0x75, 0x29, 0x35, 0x4c, 0x24, 0x10, + 0xf8, 0xbe, 0x75, 0xc2, 0x2b, 0xe6, 0x2f, 0x9c, 0xf6, 0x4e, + 0x96, 0x35, 0xf3, 0x93, 0xbb, 0x3c, 0xa4, 0x8b, 0x15, 0x59, + 0x68, 0xae, 0x1b, 0xed, 0xfe, 0xb9, 0x0f, 0x2d }, + { 0x96, 0x3c, 0x87, 0x12, 0x4d, 0x41, 0xdb, 0xfc, 0xcc, 0xf6, + 0x4c, 0x75, 0x48, 0xa3, 0x76, 0xda, 0x70, 0x53, 0x75, 0xa4, + 0x09, 0xb6, 0x23, 0x5b, 0x0d, 0x12, 0x9f, 0x4a, 0x89, 0x49, + 0x76, 0x81, 0x26, 0x4c, 0xf1, 0xf9, 0xe2, 0x3c, 0xfb, 0xb7, + 0x7b, 0xe7, 0xee, 0xca, 0xa9, 0x33, 0xae, 0x7a, 0x5d, 0x3e, + 0x36, 0x7f, 0xb7, 0xf7, 0x0d, 0x81, 0xb9, 0x77, 0x17, 0x55, + 0x92, 0xa5, 0xed, 0x54, 0xc1, 0xd2, 0x8c, 0x9f, 0xd5, 0x35, + 0x4d, 0x69, 0xee, 0x33, 0x4d, 0xa1, 0xd1, 0x36, 0x67, 0x77, + 0x5e, 0xb0, 0x92, 0x5e, 0x9a, 0x81, 0xe5, 0x1e, 0xa9, 0x35, + 0x3d, 0xde, 0xa4, 0xee, 0x2f, 0x39, 0xfc, 0xcd, 0x60, 0xd7, + 0xfe, 0x6f, 0xc7, 0x06, 0x9b, 0x52, 0x0b, 0xf8, 0xd0, 0xd9, + 0x3f, 0xbd, 0xeb, 0x35, 0x4e, 0xae, 0xb7, 0x6a, 0xbb, 0xcc, + 0xea, 0xcd, 0x8e, 0xe8, 0xb4, 0x72, 0xe1, 0xaf }, + { 0x2d, 0x03, 0xeb, 0x3c, 0xff, 0x55, 0xd7, 0xbd, 0x17, 0x51, + 0xfb, 0xad, 0xa8, 0xce, 0xc7, 0xef, 0xb2, 0x96, 0xbe, 0x59, + 0x5d, 0x57, 0xbe, 0xac, 0x71, 0xda, 0x4f, 0xfa, 0x4e, 0x00, + 0xc0, 0xc0, 0x9d, 0x8f, 0xbb, 0x9e, 0x2e, 0xcf, 0x3c, 0x63, + 0x3e, 0xb6, 0x63, 0x0a, 0xee, 0xee, 0x42, 0x15, 0xfb, 0x9e, + 0x02, 0x84, 0xe3, 0xe6, 0x96, 0xbb, 0x53, 0xe8, 0xbd, 0xf9, + 0x43, 0xad, 0x74, 0x9c, 0xff, 0xca, 0x86, 0xaf, 0xf8, 0x48, + 0xc1, 0x06, 0xd0, 0xa2, 0x5d, 0x9a, 0xd8, 0x0a, 0x7f, 0x60, + 0x85, 0x6a, 0xff, 0x17, 0xbb, 0x51, 0x91, 0x1e, 0x43, 0x4d, + 0x76, 0x51, 0x90, 0x29, 0xec, 0x72, 0x0a, 0x7d, 0x19, 0xfd, + 0x29, 0x72, 0x0c, 0xea, 0x0e, 0xba, 0xd8, 0x67, 0xf7, 0x7f, + 0xe0, 0xe1, 0x9b, 0xdb, 0x01, 0x95, 0x73, 0x3b, 0x12, 0xb5, + 0xba, 0xe2, 0x90, 0xcb, 0xde, 0x36, 0xa8, 0x14 }, + { 0x84, 0x2e, 0x40, 0xc1, 0xc5, 0x4b, 0xac, 0xd9, 0xa3, 0xca, + 0x8d, 0x24, 0xa7, 0xcf, 0x61, 0xb7, 0xc2, 0x4f, 0x8a, 0x79, + 0x3e, 0xe6, 0xb7, 0xa7, 0xd9, 0x09, 0x32, 0x1b, 0x66, 0x37, + 0x82, 0x6b, 0xb9, 0x43, 0x85, 0xa2, 0x63, 0xef, 0xcd, 0x37, + 0x2d, 0x44, 0xc7, 0x37, 0xec, 0x2e, 0xe4, 0x11, 0x62, 0x69, + 0x84, 0xfe, 0xed, 0x21, 0x9b, 0x6c, 0x88, 0x9e, 0xe7, 0x71, + 0xf7, 0x55, 0xba, 0x6e, 0x88, 0x9f, 0x9b, 0xd7, 0x6b, 0xd7, + 0x33, 0x5e, 0xf3, 0xc4, 0x46, 0x0f, 0x13, 0xb0, 0xf3, 0xe3, + 0x6f, 0x14, 0xef, 0xb5, 0x5e, 0xe8, 0xed, 0x23, 0xc2, 0x82, + 0x72, 0xb3, 0x8c, 0xb9, 0x5d, 0x5b, 0x89, 0x1d, 0xf4, 0x4b, + 0x3f, 0x71, 0x03, 0x5b, 0x44, 0x2d, 0xf6, 0x04, 0xaa, 0xd9, + 0xd9, 0xe0, 0xa8, 0x78, 0xf2, 0x76, 0x0d, 0x14, 0x7e, 0xe2, + 0xeb, 0x16, 0x92, 0x5f, 0x04, 0xf2, 0xec, 0x1d }, + { 0x0e, 0x63, 0x31, 0x9a, 0xca, 0xc9, 0x13, 0x28, 0xa5, 0x96, + 0xb7, 0xcb, 0xbc, 0x31, 0xfe, 0x6c, 0x2d, 0x52, 0x66, 0xac, + 0x51, 0x28, 0xfc, 0x09, 0x77, 0x73, 0xc2, 0xa5, 0x62, 0x23, + 0xd0, 0x93, 0xcc, 0x6a, 0xe2, 0x97, 0x28, 0x5a, 0x40, 0x9f, + 0xd5, 0x96, 0x48, 0x14, 0x0d, 0x93, 0x32, 0xd2, 0x8c, 0xaf, + 0x6d, 0x9a, 0xcc, 0x87, 0x97, 0xcc, 0xb7, 0xf4, 0xcb, 0x08, + 0xe3, 0x07, 0x75, 0x13, 0xac, 0x52, 0x76, 0xc1, 0xdd, 0xe4, + 0x55, 0x06, 0xc5, 0x54, 0xec, 0x0a, 0xca, 0x5f, 0xca, 0x2f, + 0x82, 0x7f, 0x82, 0xca, 0x1e, 0xfe, 0x42, 0xd0, 0xbd, 0xac, + 0x5b, 0xf6, 0x57, 0xb2, 0xe2, 0x80, 0x69, 0x0d, 0xec, 0xb4, + 0xc6, 0x69, 0x59, 0x67, 0x16, 0xe6, 0xfe, 0xd1, 0x13, 0x11, + 0xe1, 0x77, 0x02, 0x32, 0x8c, 0xca, 0x4f, 0x5b, 0x30, 0xcd, + 0x5a, 0x26, 0x8e, 0xd6, 0xa6, 0x61, 0xd8, 0x43 }, + { 0x88, 0x83, 0x9d, 0xa2, 0x18, 0x72, 0x70, 0x5a, 0x49, 0x39, + 0xec, 0xef, 0x28, 0xe1, 0xa7, 0xc2, 0x0b, 0x7a, 0x9d, 0x51, + 0xff, 0xa5, 0xa3, 0x5b, 0x27, 0xa5, 0xa2, 0x22, 0xff, 0x83, + 0x89, 0xe2, 0xb0, 0x73, 0xbc, 0x04, 0xb3, 0xab, 0xaf, 0x32, + 0x90, 0xf3, 0x80, 0x18, 0x9b, 0x4c, 0xe3, 0xb6, 0x93, 0x4d, + 0xef, 0xa4, 0x9c, 0x22, 0xa0, 0x06, 0xb4, 0x15, 0x28, 0xb5, + 0x9b, 0x7b, 0x42, 0xd5, 0x5b, 0x1a, 0x3d, 0xb5, 0x69, 0xd3, + 0xe6, 0xa1, 0xe3, 0x65, 0x9c, 0x29, 0x0b, 0xfc, 0xc7, 0xf5, + 0x03, 0x79, 0xa9, 0x6b, 0x3f, 0xcc, 0xc5, 0x2d, 0x3d, 0xfc, + 0xf1, 0xb8, 0x52, 0x6c, 0x07, 0x0e, 0x9d, 0x5f, 0xa3, 0x8d, + 0xaa, 0x9a, 0xc5, 0x54, 0x82, 0xc6, 0xcf, 0x10, 0xe2, 0x5b, + 0x9b, 0x14, 0x86, 0xb6, 0x60, 0xde, 0x28, 0x5e, 0x60, 0x5a, + 0xb5, 0xcd, 0x2f, 0xad, 0xf0, 0x36, 0x0a, 0xc2 }, + { 0x64, 0x12, 0x8c, 0xfe, 0xa1, 0xf5, 0x0c, 0x26, 0xfc, 0x59, + 0xcc, 0xa7, 0x1d, 0x2e, 0x21, 0xc9, 0x39, 0xd0, 0xa5, 0x1d, + 0x44, 0x15, 0xc3, 0x69, 0xf3, 0x7f, 0xb2, 0xeb, 0xdb, 0x68, + 0x1b, 0x90, 0x35, 0x79, 0x1b, 0x90, 0xe9, 0xea, 0xef, 0x52, + 0x8f, 0x88, 0xb1, 0xdb, 0xb0, 0x52, 0x19, 0x0b, 0x1f, 0xaa, + 0x36, 0xb9, 0x6f, 0xc0, 0x51, 0x80, 0x42, 0x94, 0xf4, 0xf7, + 0x35, 0x5b, 0x67, 0x76, 0xc9, 0x34, 0xdb, 0x47, 0x0e, 0x72, + 0x73, 0xef, 0x21, 0x7f, 0x27, 0x57, 0x30, 0x00, 0xe9, 0xac, + 0xf5, 0xcc, 0xa6, 0x4a, 0xdd, 0x20, 0x38, 0x5a, 0xe7, 0x26, + 0x9c, 0x86, 0xfa, 0x2e, 0xe3, 0xca, 0xfe, 0xe5, 0x71, 0xe6, + 0x37, 0x3e, 0x3d, 0x13, 0xd4, 0xda, 0xfc, 0x0c, 0x10, 0x5f, + 0x9f, 0x21, 0x3a, 0xca, 0xf1, 0x26, 0x58, 0x98, 0x1d, 0x50, + 0x56, 0xb6, 0x6c, 0x30, 0x70, 0x1c, 0xe2, 0x9a }, + { 0x93, 0x63, 0x4a, 0x09, 0xbd, 0xab, 0xcb, 0xda, 0x01, 0x4f, + 0x54, 0xda, 0x17, 0x4a, 0x13, 0x2e, 0x32, 0x2c, 0xf0, 0xc2, + 0x7c, 0xe9, 0x87, 0x1b, 0x45, 0x99, 0xe9, 0x05, 0xe2, 0x53, + 0xe3, 0x7d, 0xd8, 0x65, 0xd0, 0x59, 0x01, 0x6d, 0xae, 0x01, + 0x09, 0x10, 0x49, 0xdb, 0x88, 0xb3, 0xa2, 0x06, 0xc6, 0x6b, + 0xa6, 0x86, 0x8f, 0x12, 0xcf, 0xd3, 0xdd, 0x4e, 0x27, 0x08, + 0x30, 0xc9, 0x28, 0xd1, 0x84, 0x92, 0x28, 0xc0, 0xd5, 0x1a, + 0xa4, 0x75, 0x78, 0xdf, 0xf0, 0x0c, 0xd4, 0x48, 0xf3, 0x45, + 0x3d, 0x18, 0xf0, 0xed, 0xf3, 0x82, 0x30, 0xf7, 0xf3, 0x9f, + 0x00, 0x33, 0xfa, 0xa8, 0xbb, 0xb0, 0x07, 0x5c, 0xa3, 0x46, + 0xbc, 0x83, 0xaf, 0x98, 0x41, 0x44, 0x04, 0x41, 0x93, 0xca, + 0x7c, 0xec, 0x5c, 0x7e, 0x24, 0x9c, 0xd3, 0x40, 0xf0, 0x59, + 0xf0, 0x36, 0x78, 0xa2, 0xe8, 0xf5, 0xb0, 0xb5 }, + { 0x26, 0x6c, 0xb4, 0x67, 0xbc, 0x06, 0x35, 0x7e, 0x4b, 0x4c, + 0x5b, 0xf2, 0x26, 0xde, 0xee, 0xe7, 0xc4, 0x08, 0xc3, 0x2d, + 0x9d, 0xcc, 0x22, 0xb2, 0x36, 0x20, 0x77, 0xa3, 0xb4, 0x04, + 0x87, 0x63, 0x1e, 0xd6, 0x72, 0xda, 0x4f, 0x87, 0xd7, 0x8e, + 0x30, 0x2f, 0x90, 0x9c, 0xd1, 0x39, 0xd6, 0x3b, 0x53, 0x72, + 0x77, 0x7b, 0x37, 0x3e, 0x0c, 0xfb, 0x97, 0xf0, 0x00, 0x9a, + 0x3f, 0x1c, 0xf6, 0x1e, 0xbb, 0xc1, 0x10, 0x71, 0xb9, 0xde, + 0xda, 0x81, 0xe4, 0xcb, 0xa6, 0x01, 0x6f, 0xa9, 0x5e, 0xab, + 0x72, 0x95, 0x57, 0x2b, 0x80, 0x38, 0xe6, 0x6d, 0x29, 0x65, + 0x5c, 0xf1, 0x2b, 0x5f, 0x46, 0xfd, 0x7e, 0x9b, 0x6b, 0x85, + 0xa9, 0x84, 0x7c, 0xfe, 0x91, 0x3a, 0xb8, 0x32, 0x22, 0x38, + 0x17, 0x10, 0xc5, 0x7e, 0x18, 0x66, 0xc1, 0xa4, 0xc1, 0x24, + 0x62, 0x82, 0x6b, 0x27, 0xa9, 0xa2, 0xe3, 0x04 }, + { 0x4b, 0x1d, 0x5a, 0x1b, 0x52, 0x45, 0x4e, 0xe1, 0xbc, 0xb0, + 0x29, 0xa8, 0x3c, 0x8f, 0x2a, 0xf3, 0x78, 0x2f, 0xd0, 0xd1, + 0xf7, 0x47, 0x3a, 0xc1, 0x7e, 0xe7, 0xb5, 0xbc, 0x53, 0x15, + 0xb8, 0xd7, 0x09, 0x32, 0xbf, 0xcb, 0xa1, 0xb7, 0xd1, 0x20, + 0x15, 0x48, 0x82, 0x8e, 0xc3, 0x6a, 0xb6, 0x11, 0xc1, 0x54, + 0xe8, 0x92, 0x63, 0xab, 0x8c, 0x9e, 0x68, 0xb2, 0xf4, 0xeb, + 0x9d, 0x5c, 0xf3, 0x64, 0xe3, 0xc3, 0x28, 0x7d, 0x09, 0xf3, + 0x51, 0x1d, 0x60, 0x6e, 0x1e, 0xb9, 0x88, 0x70, 0xdc, 0x95, + 0x55, 0xca, 0xa8, 0x33, 0xa5, 0x36, 0xbf, 0x78, 0xcf, 0x44, + 0xb2, 0xec, 0xf1, 0x99, 0x11, 0xa6, 0x5b, 0x34, 0xae, 0x3e, + 0xfa, 0x00, 0x4b, 0x84, 0x14, 0x35, 0x8d, 0xde, 0x2b, 0x9e, + 0x65, 0x97, 0x4b, 0x4f, 0xd0, 0x78, 0x3c, 0x1a, 0xa4, 0xdb, + 0x6f, 0xaa, 0x41, 0x54, 0xb5, 0x63, 0x63, 0xe8 }, + { 0x81, 0x86, 0xb9, 0x3f, 0x50, 0x8e, 0x4b, 0x27, 0xe0, 0x74, + 0x39, 0xfa, 0xb6, 0x22, 0xd4, 0x2a, 0xc8, 0x31, 0xfd, 0xce, + 0x12, 0x0b, 0xf6, 0x19, 0x6f, 0xc0, 0x77, 0x62, 0xbe, 0x6a, + 0xbb, 0xd0, 0xbb, 0xf7, 0xee, 0x13, 0x3e, 0xa5, 0xa2, 0xec, + 0x0d, 0x4e, 0x56, 0xf1, 0x30, 0xee, 0xa0, 0xe3, 0x10, 0x81, + 0x0f, 0x3d, 0x52, 0x07, 0xec, 0x91, 0x7c, 0xc8, 0x00, 0xd4, + 0x65, 0x75, 0x7d, 0x4e, 0x32, 0x87, 0x36, 0x1b, 0x0d, 0xf5, + 0x11, 0xc8, 0xd7, 0xde, 0x5e, 0x12, 0xfc, 0xa3, 0xda, 0xda, + 0xba, 0x31, 0xf6, 0xb5, 0xb1, 0x5e, 0x08, 0x0a, 0x90, 0x12, + 0x3a, 0x0a, 0x79, 0x7e, 0x81, 0x07, 0x88, 0xb3, 0xf1, 0xca, + 0xac, 0xfa, 0x5a, 0x43, 0x5c, 0x62, 0x15, 0x63, 0x36, 0x0e, + 0x39, 0x56, 0x37, 0x35, 0x52, 0x5e, 0x18, 0x8c, 0x09, 0x9d, + 0x12, 0xfe, 0x51, 0x74, 0x63, 0xd5, 0x2c, 0x0c }, + { 0x0b, 0xf9, 0x7e, 0x97, 0xc9, 0xee, 0x2b, 0x2a, 0x47, 0x43, + 0xde, 0x57, 0xf3, 0x4a, 0x9b, 0xfa, 0x79, 0xcf, 0xc6, 0xd7, + 0x22, 0xc3, 0xab, 0x57, 0x12, 0xbf, 0xff, 0x1a, 0x27, 0xb5, + 0x21, 0x4e, 0xb1, 0x39, 0xc0, 0x76, 0x90, 0xbe, 0x35, 0x7e, + 0x30, 0x08, 0x6c, 0xf4, 0x43, 0x58, 0x0b, 0x7a, 0xab, 0xa6, + 0x58, 0x91, 0x05, 0xd4, 0x11, 0x0a, 0x4b, 0xb8, 0x63, 0xb9, + 0xd9, 0x47, 0x7c, 0x91, 0x35, 0x1e, 0x6a, 0x00, 0x9b, 0x7d, + 0x9b, 0x1c, 0x7b, 0x5d, 0xc4, 0x44, 0x83, 0x1c, 0x04, 0x97, + 0xec, 0xb0, 0x1c, 0x0b, 0xbe, 0xb4, 0xd6, 0x44, 0xed, 0x30, + 0xed, 0x65, 0xce, 0x68, 0xb8, 0xfe, 0x50, 0xaa, 0x50, 0x57, + 0xa4, 0xfc, 0x3d, 0x82, 0xc1, 0xcf, 0x16, 0x68, 0x1f, 0x5f, + 0x5d, 0xda, 0x7e, 0x04, 0x2c, 0x05, 0xbf, 0xaf, 0x7d, 0xb4, + 0xc6, 0x19, 0xd1, 0x54, 0x09, 0x31, 0x28, 0x67 }, + { 0x8f, 0xe5, 0x48, 0x2c, 0x3e, 0x40, 0xaa, 0xbb, 0x3b, 0xd9, + 0x1b, 0xb4, 0xfe, 0xaa, 0xc2, 0x3f, 0x57, 0x6a, 0x87, 0x0d, + 0x56, 0x76, 0xf1, 0x20, 0xe6, 0xbf, 0xa9, 0xe0, 0x0a, 0x9d, + 0x0b, 0xc8, 0x6b, 0x7a, 0xc0, 0xab, 0x9e, 0x69, 0xd9, 0x4e, + 0x3d, 0xe3, 0x7a, 0x9a, 0x9f, 0x5e, 0xf4, 0x39, 0xe2, 0x2c, + 0x79, 0x76, 0xad, 0x47, 0x35, 0x99, 0xd3, 0xd7, 0x41, 0x6e, + 0x1d, 0x2d, 0xc7, 0xdf, 0x9e, 0xb8, 0x1a, 0x0f, 0x32, 0xf1, + 0x28, 0x06, 0x18, 0x96, 0xec, 0xda, 0xb3, 0x93, 0x97, 0x30, + 0x65, 0xce, 0x25, 0xf1, 0x95, 0xbc, 0x3e, 0x13, 0x98, 0xa6, + 0x97, 0xa4, 0x62, 0xfd, 0xcc, 0x09, 0x1a, 0xc6, 0xf6, 0x8b, + 0x0d, 0x9a, 0x0d, 0x99, 0x7e, 0x83, 0x61, 0x2b, 0x65, 0xf6, + 0x91, 0x8a, 0x54, 0xce, 0x18, 0xea, 0x6c, 0x30, 0x6e, 0x8b, + 0x96, 0xec, 0x4e, 0xc8, 0xdd, 0xa1, 0x9e, 0x96 }, + { 0x39, 0x28, 0xc6, 0x69, 0xbb, 0xc8, 0xbc, 0x3f, 0x4a, 0xeb, + 0x62, 0x06, 0xb4, 0x2d, 0x3b, 0xf6, 0x18, 0x9e, 0xd1, 0x8b, + 0x6b, 0x4b, 0x5c, 0x8d, 0x95, 0xa9, 0x13, 0xb9, 0xca, 0xd2, + 0xde, 0xd6, 0xa6, 0x7c, 0x11, 0x4c, 0x64, 0x27, 0x5d, 0x2c, + 0x4c, 0x91, 0x8b, 0xb1, 0x23, 0xda, 0xb5, 0x66, 0xa7, 0xd4, + 0x84, 0xbe, 0x0f, 0x64, 0x0a, 0x5f, 0xc5, 0xc0, 0x09, 0xa1, + 0x52, 0x19, 0x9f, 0x43, 0x69, 0x67, 0x9f, 0x1e, 0x50, 0xb4, + 0xd1, 0x8f, 0xc8, 0x7e, 0xf5, 0x15, 0xb6, 0x4a, 0xe8, 0xb6, + 0xdc, 0x62, 0x07, 0x8d, 0xf0, 0x2e, 0xb0, 0xda, 0x99, 0x61, + 0xf5, 0xbc, 0xe7, 0x1c, 0x29, 0x4e, 0x80, 0x3d, 0xe0, 0xad, + 0x30, 0x8f, 0xb4, 0x1c, 0x5c, 0x6c, 0x8f, 0x3a, 0x25, 0xd0, + 0x61, 0x92, 0x4c, 0x3e, 0xb8, 0x03, 0x4f, 0x1d, 0x20, 0x38, + 0x85, 0xae, 0x67, 0xc2, 0xce, 0x9a, 0x4d, 0x1e }, + { 0x6c, 0xcc, 0x88, 0x8f, 0x35, 0x51, 0x34, 0xf6, 0x17, 0x04, + 0xd2, 0xe1, 0x91, 0x50, 0xd0, 0xd9, 0x81, 0xc3, 0x5b, 0x3e, + 0xf0, 0x71, 0xcd, 0xe4, 0xf0, 0x1d, 0xff, 0x93, 0x73, 0x89, + 0x27, 0x54, 0x3b, 0xaa, 0xdc, 0x8b, 0x21, 0xd4, 0x05, 0xd1, + 0x1b, 0x14, 0xd9, 0xe6, 0xbe, 0xa1, 0xc1, 0xfd, 0xad, 0xee, + 0xfa, 0x98, 0xc2, 0x59, 0xd0, 0xd4, 0x68, 0x1d, 0xf6, 0xdd, + 0xa7, 0xc9, 0x30, 0xeb, 0x7f, 0xae, 0x8b, 0xbe, 0x4e, 0x3b, + 0x2f, 0x0d, 0x31, 0x67, 0x4a, 0x4f, 0x67, 0xce, 0xe9, 0x84, + 0x5a, 0xd8, 0xa5, 0x96, 0x21, 0x21, 0xb7, 0x7b, 0x42, 0x60, + 0x42, 0xbc, 0x40, 0x7b, 0x85, 0xc4, 0x90, 0x44, 0x8f, 0xbd, + 0xd3, 0x6f, 0x33, 0x1e, 0xf3, 0xaa, 0xc9, 0x4e, 0x7a, 0x91, + 0x12, 0xa4, 0x03, 0xf6, 0x2a, 0x44, 0xf2, 0x61, 0x79, 0xa1, + 0xde, 0x4b, 0xea, 0x4a, 0xda, 0xcb, 0x4b, 0x64 }, + { 0x2f, 0x15, 0x19, 0x80, 0xb2, 0x6f, 0xae, 0xf9, 0x6a, 0xfa, + 0x63, 0x57, 0xad, 0x4e, 0xd7, 0xbd, 0x03, 0x5f, 0xf1, 0x10, + 0xc8, 0xc0, 0xf8, 0x15, 0x8f, 0x79, 0x2b, 0x21, 0x1a, 0xca, + 0x3c, 0xe9, 0x53, 0xd5, 0xb8, 0x43, 0x74, 0xb9, 0x13, 0x93, + 0xa1, 0x7e, 0x14, 0x84, 0x25, 0x9d, 0x52, 0x54, 0x17, 0xed, + 0x0f, 0x5d, 0x39, 0x73, 0xca, 0xcf, 0xa4, 0x84, 0x13, 0x78, + 0xfa, 0xb1, 0xe8, 0xbe, 0xcb, 0x8f, 0xd9, 0x8b, 0x9c, 0xbd, + 0x35, 0x1a, 0x31, 0x20, 0x24, 0xa9, 0x09, 0xb8, 0xce, 0x1e, + 0x0b, 0x8c, 0x1a, 0x82, 0x99, 0xad, 0x8e, 0xb7, 0x68, 0x25, + 0xa6, 0xe6, 0x01, 0x4e, 0xdc, 0xfc, 0x12, 0x76, 0xf4, 0xce, + 0xba, 0xeb, 0xf3, 0x2f, 0x0d, 0xcd, 0x1e, 0xde, 0xfe, 0xde, + 0x67, 0xaa, 0xbc, 0xa3, 0x26, 0x5f, 0xf7, 0x95, 0x9d, 0xdd, + 0xf8, 0xd3, 0x6f, 0x0e, 0x7a, 0xd7, 0x50, 0x4c }, + { 0x35, 0x4b, 0x05, 0xb7, 0x0a, 0xc5, 0x8d, 0x65, 0x6c, 0x80, + 0x5c, 0xe8, 0xbe, 0xb5, 0x4a, 0xaa, 0x1c, 0x21, 0x90, 0x85, + 0xa8, 0xeb, 0x99, 0x20, 0xf7, 0xbe, 0x03, 0x89, 0x20, 0x5c, + 0x4e, 0x92, 0x3a, 0x20, 0x2c, 0x70, 0xfd, 0x22, 0xdf, 0x11, + 0xe6, 0x17, 0x32, 0x71, 0xf4, 0xab, 0x67, 0xb3, 0x44, 0xed, + 0xf3, 0xf9, 0x13, 0xbe, 0xee, 0xf6, 0x63, 0x8f, 0x6b, 0x74, + 0x94, 0x98, 0xfd, 0x7d, 0xc7, 0x1d, 0xb2, 0x90, 0x15, 0xa3, + 0x1b, 0xdf, 0x83, 0x81, 0xe3, 0xd8, 0x0a, 0xef, 0x5a, 0x85, + 0x03, 0x1d, 0xb9, 0xe7, 0xf3, 0x35, 0x5a, 0x17, 0xba, 0xaa, + 0x17, 0x67, 0x9d, 0x88, 0xc6, 0x58, 0x6d, 0x6c, 0xf4, 0xc0, + 0xb6, 0xce, 0x47, 0xec, 0x3e, 0x5a, 0x97, 0x92, 0x6c, 0x05, + 0xb7, 0x5b, 0x12, 0x1f, 0xbb, 0xc2, 0xbc, 0x03, 0x99, 0x55, + 0x0c, 0x86, 0x31, 0xda, 0x29, 0xd2, 0xd4, 0x39 }, + { 0x48, 0xdc, 0x55, 0xc4, 0xae, 0x35, 0x23, 0xa1, 0xd4, 0x1b, + 0xe8, 0x93, 0xcf, 0x09, 0xfa, 0xc2, 0x3e, 0x7d, 0xac, 0xb8, + 0x70, 0xac, 0xc7, 0x05, 0x99, 0x38, 0xf9, 0x32, 0xe5, 0x5e, + 0xfc, 0xf9, 0x61, 0x96, 0xe2, 0x17, 0xa4, 0x68, 0x1b, 0xe2, + 0x84, 0x7a, 0xf9, 0xfc, 0x44, 0x82, 0xf1, 0x3b, 0xf3, 0x1d, + 0x33, 0x32, 0xec, 0xa6, 0x86, 0x30, 0xf3, 0x24, 0x1a, 0xb8, + 0xa9, 0xf8, 0x1a, 0x18, 0xa3, 0x2f, 0xb5, 0xbc, 0xbb, 0xbc, + 0xe7, 0x6f, 0x52, 0x59, 0x1a, 0xc3, 0x2f, 0xf0, 0xa7, 0x2b, + 0x00, 0x05, 0x8e, 0x3f, 0x5c, 0x3d, 0x97, 0x1e, 0xb7, 0x13, + 0x8a, 0x7f, 0x96, 0x5c, 0x7d, 0x01, 0xa7, 0x3e, 0x8c, 0xe3, + 0xa6, 0x6c, 0xae, 0x1a, 0xff, 0xbe, 0x82, 0x4f, 0x3c, 0xdd, + 0xcc, 0xfb, 0x01, 0xee, 0xc4, 0x2d, 0x4c, 0xad, 0x50, 0xcd, + 0x71, 0x71, 0xe2, 0x36, 0x7a, 0x91, 0x70, 0xe9 }, + { 0x5f, 0x6a, 0x8e, 0xdd, 0x0b, 0x6d, 0xc0, 0x21, 0x40, 0x5c, + 0xe4, 0xc5, 0x66, 0xe3, 0x8c, 0x68, 0x87, 0x25, 0xe2, 0x4b, + 0xb9, 0x3b, 0x9c, 0x33, 0xcb, 0x94, 0xcc, 0xff, 0x98, 0x6b, + 0x8d, 0x62, 0x19, 0xf2, 0x9d, 0x71, 0x8b, 0x8a, 0xf2, 0xcd, + 0x85, 0x1c, 0x9f, 0x4b, 0x1d, 0x0d, 0x7b, 0x3a, 0x5d, 0x67, + 0xb9, 0x73, 0xba, 0x15, 0x59, 0x04, 0xcd, 0xeb, 0xa9, 0xf7, + 0x71, 0x31, 0x3c, 0x58, 0x18, 0x70, 0x70, 0x75, 0x8a, 0x51, + 0xcf, 0x02, 0x15, 0x4e, 0x10, 0x77, 0x8a, 0xf5, 0x88, 0x69, + 0x38, 0x2e, 0xb6, 0xe7, 0xa5, 0x12, 0x15, 0x1c, 0x98, 0x2d, + 0xef, 0x67, 0x97, 0xd0, 0x0e, 0x38, 0x41, 0x78, 0x06, 0x40, + 0x83, 0xc7, 0xd2, 0x45, 0x2f, 0x13, 0x56, 0xaf, 0x25, 0xc9, + 0xeb, 0x41, 0xe4, 0x6e, 0xc3, 0x62, 0x68, 0x98, 0x97, 0x0c, + 0x8e, 0x62, 0x38, 0x26, 0xa5, 0x09, 0x21, 0x93 }, + { 0x1c, 0xa6, 0x50, 0x72, 0xca, 0x7f, 0x87, 0xac, 0x2e, 0x12, + 0xe0, 0x7a, 0x9e, 0xb8, 0x14, 0xbb, 0x9b, 0x33, 0x48, 0x0d, + 0x5a, 0x87, 0x97, 0xd3, 0x15, 0x6c, 0xcb, 0x70, 0x8b, 0xfb, + 0x7c, 0xf0, 0x84, 0x0f, 0x04, 0x21, 0xf2, 0x7d, 0xb4, 0x90, + 0xcc, 0xe6, 0x56, 0x2b, 0xf4, 0x3c, 0xe0, 0x1e, 0x64, 0x8d, + 0xa3, 0x42, 0x0e, 0xa2, 0x43, 0xdb, 0xe4, 0x42, 0x8a, 0xcd, + 0xdf, 0x32, 0x57, 0x97, 0x4c, 0xa2, 0xb9, 0xe4, 0x4f, 0xe1, + 0xf7, 0x39, 0x53, 0x79, 0x51, 0xb3, 0xb8, 0xa5, 0x97, 0x94, + 0x00, 0x5c, 0xfb, 0xba, 0x4e, 0xa4, 0x57, 0xa8, 0x78, 0x04, + 0x66, 0x4a, 0x04, 0xaa, 0xb2, 0x6d, 0x4c, 0xd5, 0x8f, 0x16, + 0xbc, 0xe3, 0xa4, 0xcf, 0xfb, 0xc1, 0x2d, 0x8c, 0x69, 0x20, + 0x10, 0x28, 0x3f, 0x36, 0x97, 0x66, 0x2f, 0x76, 0xa4, 0x07, + 0x83, 0x70, 0x4c, 0xa5, 0x8f, 0x9a, 0x86, 0x90 }, + { 0x46, 0x2c, 0xaf, 0xb6, 0xcb, 0xad, 0x3c, 0xee, 0xac, 0x44, + 0xfd, 0x91, 0x35, 0xff, 0xff, 0x64, 0xac, 0xa6, 0x63, 0x99, + 0x1f, 0xb3, 0x07, 0xa1, 0x05, 0x5d, 0xec, 0x1c, 0x14, 0xf9, + 0xa1, 0x92, 0x9f, 0x7a, 0xff, 0x32, 0x49, 0xfa, 0xca, 0xba, + 0xd0, 0xd7, 0x10, 0xc0, 0x68, 0x98, 0x09, 0x85, 0x7f, 0xad, + 0x3b, 0xd1, 0xe6, 0x67, 0x54, 0x3c, 0x4d, 0xd2, 0xdb, 0x49, + 0x96, 0x46, 0xaa, 0x34, 0xef, 0x8d, 0x44, 0x3e, 0x0d, 0x85, + 0x8c, 0x5f, 0x39, 0xb7, 0x52, 0x43, 0x8b, 0xbe, 0x33, 0x91, + 0x1d, 0x96, 0xb5, 0x07, 0x89, 0xb7, 0x8d, 0xa8, 0x9b, 0x74, + 0xd8, 0xfe, 0x56, 0x47, 0xdd, 0x68, 0x56, 0xed, 0x1e, 0xa4, + 0x7d, 0x80, 0x06, 0x8f, 0xc1, 0xc1, 0x53, 0x0e, 0x59, 0xe3, + 0x68, 0xb5, 0x66, 0xaf, 0xfd, 0xca, 0x40, 0xa7, 0x46, 0xdb, + 0xfb, 0xb3, 0x21, 0xcf, 0x2b, 0x9d, 0x25, 0xa0 }, + { 0x12, 0x93, 0xc9, 0x8c, 0x6c, 0xd9, 0x36, 0x08, 0x2a, 0x29, + 0x15, 0x03, 0xb5, 0x46, 0xea, 0xfd, 0xd2, 0xfb, 0x77, 0x18, + 0x3e, 0x8f, 0x9d, 0x13, 0x23, 0x15, 0x5e, 0x22, 0x51, 0x3f, + 0x83, 0xc0, 0xaa, 0x78, 0x4f, 0xab, 0x65, 0xf4, 0x85, 0x76, + 0x06, 0xfe, 0xe7, 0xfe, 0xd9, 0xba, 0xa6, 0xd3, 0x0f, 0x75, + 0xd2, 0x35, 0xa7, 0x32, 0xd1, 0xcc, 0xbc, 0x87, 0x5d, 0x03, + 0x0a, 0x2e, 0xbe, 0x41, 0xdf, 0xef, 0xc9, 0x7d, 0xa9, 0xc3, + 0x91, 0x7f, 0x4e, 0x7e, 0x8d, 0xfc, 0x25, 0xa9, 0xa1, 0x2b, + 0xa1, 0xa2, 0xbe, 0x74, 0x6e, 0xf1, 0x83, 0x31, 0x18, 0x75, + 0x39, 0x3d, 0x1c, 0x93, 0xe2, 0x98, 0x15, 0xef, 0x04, 0x3e, + 0x72, 0x6b, 0x91, 0x4a, 0xf7, 0x87, 0x9f, 0x59, 0xdd, 0xfa, + 0x55, 0xf8, 0x95, 0xf7, 0x35, 0xcc, 0x82, 0xb8, 0x74, 0x04, + 0x16, 0x60, 0xa6, 0x47, 0xde, 0x32, 0x37, 0xdd }, + { 0x53, 0xb7, 0x9a, 0xa1, 0x68, 0xea, 0x94, 0xba, 0x73, 0xe4, + 0xb5, 0xf3, 0xe4, 0x6f, 0x8f, 0xb1, 0xed, 0xb2, 0x58, 0x4c, + 0x39, 0x46, 0x98, 0x8b, 0xc6, 0x92, 0x9c, 0xd4, 0xfd, 0xfd, + 0x61, 0x4f, 0xa0, 0xa4, 0x7f, 0x05, 0x06, 0x4e, 0x71, 0x42, + 0x16, 0xe7, 0x9e, 0x41, 0x74, 0xad, 0x91, 0x07, 0xd0, 0x5c, + 0x23, 0xc5, 0x49, 0x40, 0xc3, 0xe8, 0x58, 0xcf, 0xb2, 0xfb, + 0x1a, 0xe9, 0xd7, 0xc7, 0xbe, 0x1c, 0x0f, 0xb8, 0xa1, 0xbd, + 0x18, 0x9e, 0xca, 0x83, 0xcb, 0x86, 0xe7, 0x7b, 0x11, 0x1a, + 0xb0, 0xb0, 0x28, 0x9c, 0x8c, 0x87, 0x53, 0x0d, 0x49, 0x5f, + 0x6a, 0xbf, 0x33, 0xb3, 0x75, 0x22, 0x82, 0x38, 0xc7, 0x08, + 0x87, 0xe7, 0x71, 0xc1, 0xb7, 0xd7, 0xc7, 0xdb, 0x4a, 0x36, + 0xb7, 0x11, 0xa6, 0xab, 0x40, 0x3d, 0x96, 0xea, 0xfa, 0xc7, + 0x72, 0x78, 0x12, 0x51, 0x49, 0xd5, 0x3b, 0x77 }, + { 0x82, 0x90, 0xd6, 0xd1, 0x56, 0xc2, 0xe8, 0x33, 0x40, 0xa6, + 0xf7, 0xd5, 0xf3, 0x87, 0x2c, 0x9d, 0x15, 0x0f, 0xb4, 0xa9, + 0x58, 0x40, 0x11, 0x04, 0xc8, 0x9d, 0xc0, 0x1b, 0x32, 0x81, + 0x51, 0xe1, 0xe5, 0xef, 0x49, 0x97, 0xc8, 0x3a, 0xf2, 0xa8, + 0x04, 0x09, 0x99, 0x03, 0xc9, 0xd5, 0xda, 0x0f, 0xb9, 0x28, + 0x7f, 0x58, 0x53, 0x46, 0x61, 0x1d, 0x64, 0x00, 0xbc, 0x54, + 0x23, 0x45, 0x96, 0xc4, 0x0d, 0x53, 0x9d, 0x8d, 0x47, 0x39, + 0x7c, 0x05, 0x23, 0x11, 0x98, 0x69, 0x29, 0xfe, 0x89, 0xa2, + 0x64, 0x96, 0x8e, 0xe6, 0x51, 0x2c, 0x67, 0x38, 0xfe, 0xd5, + 0xab, 0xce, 0x7b, 0x4e, 0xc0, 0x14, 0x02, 0x2e, 0xaf, 0x3d, + 0xf1, 0x9e, 0xfa, 0xfe, 0xef, 0x1e, 0x4b, 0x30, 0xa9, 0xdd, + 0x93, 0x9a, 0xd3, 0xa5, 0xbb, 0xa0, 0x67, 0x82, 0x17, 0x28, + 0x21, 0x6f, 0xaf, 0xce, 0x44, 0xbb, 0xb6, 0xa1 }, + { 0x50, 0x6e, 0xf1, 0xab, 0x30, 0x4f, 0xab, 0xb0, 0x6f, 0xa1, + 0xd9, 0x69, 0xee, 0x95, 0x2e, 0x14, 0x45, 0x9f, 0x29, 0x7b, + 0xa0, 0xaa, 0x98, 0x4e, 0x00, 0xf3, 0x32, 0xe1, 0xec, 0x47, + 0xb3, 0xcf, 0xfd, 0x22, 0x3e, 0x26, 0xf0, 0x6a, 0x2a, 0x08, + 0x51, 0xcc, 0x6e, 0xf9, 0xb3, 0x3f, 0xa0, 0xe1, 0x1b, 0xea, + 0xd0, 0x2c, 0xa6, 0x75, 0x23, 0x5a, 0x6e, 0x6b, 0x55, 0xe9, + 0xdb, 0x32, 0x16, 0x60, 0x23, 0x80, 0xed, 0x5c, 0xed, 0x96, + 0x78, 0x11, 0xcc, 0x20, 0x8d, 0xe6, 0x33, 0xaa, 0xfc, 0xa5, + 0xa2, 0x71, 0x4c, 0xa6, 0x0b, 0xca, 0xdb, 0x5f, 0xe6, 0x2a, + 0xe5, 0x2d, 0x2d, 0x67, 0x84, 0xa9, 0xb4, 0x25, 0x57, 0xfe, + 0x0d, 0xc7, 0xb8, 0x09, 0xd4, 0x23, 0x59, 0xa4, 0xd7, 0x89, + 0x00, 0x7e, 0xda, 0x13, 0x4a, 0x39, 0x69, 0xec, 0x57, 0xfa, + 0xf8, 0x46, 0x37, 0xc6, 0xd8, 0x54, 0x69, 0x46 }, + { 0x41, 0x5b, 0x7d, 0xbf, 0x15, 0x20, 0x03, 0x44, 0xda, 0xaf, + 0x3f, 0xdb, 0x4d, 0x85, 0xc6, 0x78, 0x6c, 0xcd, 0x2f, 0xbf, + 0xf7, 0x1a, 0x70, 0x6e, 0x14, 0x04, 0xcc, 0xf8, 0xb9, 0x8f, + 0xcb, 0xc7, 0xfa, 0xbe, 0x77, 0x43, 0xfa, 0x8f, 0xeb, 0x1f, + 0xe1, 0x4a, 0x45, 0x6f, 0x8e, 0xed, 0x67, 0x65, 0x6e, 0xec, + 0x74, 0xd2, 0x37, 0x9d, 0x92, 0xd1, 0xdf, 0xea, 0x34, 0x23, + 0xd4, 0xdc, 0xbc, 0x3c, 0xdd, 0x35, 0x4c, 0xac, 0xbd, 0xc8, + 0x9a, 0x16, 0xa2, 0x8d, 0x63, 0x3d, 0xdf, 0x73, 0xad, 0x9c, + 0x36, 0xa6, 0xaf, 0x39, 0xe3, 0x07, 0x1b, 0x58, 0xf5, 0x09, + 0x0a, 0x7e, 0xa7, 0x30, 0x75, 0xaa, 0xa2, 0xda, 0xf1, 0xa5, + 0x9d, 0xd1, 0xc3, 0xd5, 0x66, 0xac, 0xeb, 0x3f, 0x9d, 0xeb, + 0x27, 0xce, 0x71, 0x30, 0xb9, 0x6f, 0xea, 0x9f, 0xa9, 0x84, + 0x11, 0xb4, 0xeb, 0x27, 0x35, 0xbf, 0xf1, 0x63 }, + { 0x1e, 0xc3, 0x14, 0xf1, 0xaf, 0x58, 0x87, 0x9d, 0x52, 0x5d, + 0xc9, 0xbd, 0xec, 0x83, 0x1d, 0x59, 0xfc, 0xe0, 0xfa, 0xfc, + 0xc1, 0x75, 0xd4, 0x3f, 0x00, 0x69, 0x65, 0xed, 0xb4, 0x12, + 0x2e, 0x05, 0x35, 0x22, 0xce, 0xf0, 0xa2, 0xb5, 0x51, 0x1c, + 0x76, 0x9a, 0x2e, 0xf9, 0x85, 0xf0, 0x68, 0xaa, 0x01, 0xdc, + 0x4c, 0x3f, 0xe6, 0x93, 0x65, 0x08, 0xf9, 0x31, 0x8c, 0x91, + 0x97, 0xf0, 0x0f, 0x11, 0x45, 0x49, 0x97, 0x51, 0x86, 0x32, + 0x0a, 0x01, 0x0c, 0xda, 0x36, 0xd9, 0x6e, 0x0e, 0x54, 0xc2, + 0xfc, 0x6a, 0xc6, 0xc6, 0x0f, 0xeb, 0x9f, 0x3b, 0x71, 0x2f, + 0xa1, 0x3c, 0xe9, 0xe5, 0xa2, 0xb8, 0x4b, 0xc7, 0x09, 0x5d, + 0x93, 0xc8, 0xf2, 0x90, 0xfd, 0x67, 0xd2, 0x89, 0xf0, 0x3a, + 0x4c, 0x32, 0x06, 0x8a, 0x3d, 0x68, 0xcb, 0x80, 0x32, 0x72, + 0x97, 0x01, 0x05, 0x86, 0x7d, 0x83, 0x77, 0xa7 }, + { 0x17, 0xe9, 0x1d, 0x12, 0x7f, 0xff, 0x57, 0x88, 0xad, 0x5c, + 0xc0, 0x8f, 0x2d, 0xc1, 0x05, 0xde, 0x71, 0x93, 0x6c, 0xb4, + 0x52, 0xab, 0xfa, 0x6b, 0x76, 0x51, 0x35, 0xd2, 0x3d, 0xe5, + 0xa6, 0x64, 0xbb, 0x32, 0xf1, 0x7c, 0x96, 0x93, 0x9c, 0x82, + 0xe0, 0xc8, 0xb6, 0xf7, 0xf5, 0x87, 0x5a, 0xec, 0xa9, 0x31, + 0xb9, 0x9d, 0x77, 0x46, 0xe0, 0xc7, 0xd3, 0xbb, 0x0a, 0x97, + 0x26, 0xec, 0xcf, 0xa0, 0xf0, 0x01, 0xc4, 0x6e, 0xdd, 0x2f, + 0x9e, 0x6f, 0x01, 0x8b, 0x1c, 0x63, 0xae, 0x4b, 0x9b, 0xc6, + 0x34, 0x13, 0x02, 0xf9, 0xf7, 0xde, 0x17, 0x11, 0x50, 0x77, + 0x33, 0x20, 0xb5, 0x42, 0xf8, 0xdf, 0xcd, 0xe4, 0xa3, 0x8f, + 0x63, 0x7e, 0xc2, 0xc5, 0x39, 0x2b, 0x10, 0xfc, 0xe5, 0x34, + 0x68, 0x87, 0xaa, 0x7e, 0x14, 0xda, 0x45, 0x7e, 0x3f, 0x74, + 0x06, 0x63, 0xfe, 0xef, 0x2c, 0x83, 0x10, 0xc2 }, + { 0x11, 0x8f, 0x3b, 0x4b, 0x3d, 0xdd, 0x0c, 0x01, 0xdf, 0x24, + 0x22, 0x82, 0xaf, 0xc4, 0xa0, 0xd5, 0x16, 0x29, 0xf7, 0xc2, + 0x63, 0xf7, 0xb9, 0x7e, 0xf3, 0x01, 0xa3, 0x8f, 0xb1, 0x8a, + 0xe1, 0xf9, 0xca, 0x7c, 0x98, 0xed, 0x57, 0x25, 0x71, 0xdf, + 0x6e, 0x65, 0x3e, 0xa4, 0x1d, 0xeb, 0x3e, 0x28, 0x99, 0x58, + 0x4a, 0xeb, 0x91, 0xd4, 0xa3, 0xb6, 0x0d, 0x76, 0x59, 0x57, + 0xb5, 0x99, 0x73, 0x2d, 0x35, 0x49, 0x97, 0xe4, 0x77, 0x96, + 0x3e, 0x0e, 0xa7, 0xbd, 0x46, 0x92, 0x8c, 0x36, 0x5a, 0xec, + 0x54, 0x50, 0x9e, 0x65, 0xd1, 0x2a, 0x19, 0xee, 0x39, 0x52, + 0x49, 0xa3, 0xd2, 0x89, 0xe9, 0xc7, 0x3e, 0xa6, 0x62, 0x27, + 0xce, 0x9d, 0x6b, 0x31, 0xc8, 0xab, 0x4b, 0x52, 0x00, 0x86, + 0x78, 0x4b, 0xc6, 0x44, 0xd4, 0xfd, 0x19, 0xc7, 0x76, 0xd4, + 0xbe, 0x92, 0xce, 0xd3, 0xb7, 0xe0, 0x51, 0xca }, + { 0x01, 0xd0, 0xa6, 0x7c, 0x8d, 0x03, 0xe7, 0x27, 0x3b, 0x9b, + 0x53, 0x6a, 0x44, 0xf1, 0x70, 0x24, 0x22, 0xce, 0x8a, 0x79, + 0x44, 0xf5, 0x93, 0xc2, 0x21, 0xd2, 0xb6, 0x31, 0x21, 0xb6, + 0x17, 0x10, 0x1d, 0xbd, 0xbd, 0x1a, 0xc2, 0xdd, 0x61, 0x7f, + 0x87, 0x8e, 0xcc, 0x0d, 0x00, 0x71, 0x5b, 0xa1, 0x15, 0x61, + 0x8d, 0x0b, 0x1b, 0xdf, 0xe5, 0x2f, 0x5b, 0xc1, 0x8b, 0x4f, + 0xdf, 0x75, 0x86, 0x95, 0x73, 0x5e, 0xb6, 0x86, 0xe7, 0x7a, + 0x4c, 0x05, 0xa3, 0xe1, 0x78, 0x34, 0x5b, 0x08, 0x46, 0xe5, + 0xc2, 0x44, 0xa6, 0x09, 0x5d, 0xd6, 0x14, 0x7a, 0x83, 0x63, + 0x7f, 0xfb, 0x3e, 0xcc, 0x1d, 0xba, 0xc0, 0xbe, 0x87, 0x86, + 0x7e, 0x60, 0xd9, 0x8b, 0x16, 0xff, 0x49, 0x60, 0x4c, 0xf7, + 0x6d, 0x86, 0x1a, 0xef, 0x84, 0xda, 0x8c, 0x58, 0xd1, 0x75, + 0x74, 0xa0, 0xa0, 0xa8, 0x7a, 0xd4, 0x76, 0x2b }, + { 0x1b, 0x62, 0x5b, 0x06, 0x7d, 0xa6, 0x32, 0x0f, 0xc9, 0xad, + 0xba, 0x24, 0x99, 0x7c, 0x08, 0xe6, 0xdd, 0x52, 0x7b, 0x43, + 0xc5, 0x6b, 0xb0, 0x44, 0xca, 0xdd, 0x2d, 0xfa, 0x48, 0x6e, + 0x2f, 0x84, 0x5a, 0xd8, 0xb5, 0x72, 0xc9, 0x50, 0xd5, 0xd4, + 0x7f, 0x47, 0xd4, 0x56, 0xb4, 0xed, 0x85, 0x69, 0x52, 0x36, + 0x4b, 0xa1, 0xfa, 0xbd, 0x59, 0x52, 0xcd, 0x57, 0x2d, 0xfd, + 0x2a, 0xf0, 0x3b, 0x37, 0x59, 0x6c, 0xce, 0xb5, 0xd2, 0xe8, + 0x65, 0x0a, 0x03, 0xd5, 0x45, 0x21, 0x11, 0xe6, 0x8d, 0xa6, + 0x7b, 0x67, 0xec, 0xdb, 0xe7, 0x6c, 0x0d, 0x63, 0x74, 0xa6, + 0x9b, 0xdd, 0x4c, 0xb6, 0x63, 0xe3, 0x71, 0x35, 0xe8, 0x1d, + 0xd8, 0x3c, 0x7a, 0x45, 0x01, 0x9b, 0x5d, 0x16, 0xa4, 0x2c, + 0x4a, 0x18, 0xe9, 0x47, 0x79, 0x90, 0xfb, 0x88, 0xc2, 0xae, + 0x7b, 0x96, 0x42, 0x36, 0x1e, 0x46, 0x53, 0x3c }, + { 0x33, 0x3e, 0xca, 0x96, 0x19, 0xfc, 0x94, 0x8d, 0xbd, 0xf1, + 0x43, 0x28, 0x84, 0x00, 0x73, 0x6e, 0x15, 0x39, 0x79, 0x21, + 0xa7, 0x07, 0x66, 0x39, 0x13, 0xf5, 0xca, 0x6f, 0xbf, 0x06, + 0x97, 0x68, 0x32, 0x1f, 0xaa, 0xc2, 0x98, 0x26, 0x65, 0x6a, + 0xc4, 0xca, 0x56, 0x7c, 0x36, 0x0c, 0xb3, 0x65, 0xf6, 0x68, + 0x20, 0x65, 0x3f, 0x7d, 0xf0, 0xc2, 0x6d, 0x6e, 0x32, 0x58, + 0x24, 0x33, 0xda, 0x34, 0xdb, 0x1f, 0x80, 0xc6, 0x34, 0xd8, + 0x52, 0xd7, 0x87, 0xdc, 0xb5, 0x34, 0x2b, 0x41, 0xc5, 0xdd, + 0x6b, 0x24, 0x5e, 0x5c, 0x1f, 0x49, 0x09, 0x8b, 0x2b, 0x97, + 0x1c, 0xba, 0x87, 0x15, 0x6b, 0xc9, 0xf3, 0x3c, 0x43, 0x4f, + 0xbb, 0xa9, 0x75, 0x8b, 0xbf, 0x44, 0x43, 0x88, 0xfe, 0x88, + 0x38, 0xb5, 0xc0, 0x1b, 0x2f, 0x01, 0xaf, 0x6f, 0xeb, 0xeb, + 0x44, 0xdf, 0xaa, 0x7b, 0x4f, 0xd8, 0x44, 0x6d }, + { 0x72, 0xfc, 0x21, 0x10, 0x87, 0x28, 0xd1, 0x35, 0xae, 0x9d, + 0x9c, 0x07, 0x4c, 0xcf, 0x07, 0x46, 0x4d, 0x25, 0xc7, 0x42, + 0xf2, 0xcd, 0x13, 0x4f, 0x76, 0x50, 0x82, 0xa5, 0x37, 0xe7, + 0xb1, 0x5d, 0x55, 0x7b, 0x32, 0x2a, 0x65, 0xcd, 0x44, 0x9d, + 0x98, 0x7d, 0xa7, 0x4a, 0xe5, 0x4b, 0x64, 0xa7, 0xf3, 0x5e, + 0x8c, 0xf1, 0x33, 0x93, 0x74, 0x3e, 0x90, 0xc1, 0x6e, 0xeb, + 0xcb, 0x25, 0xb9, 0x99, 0x5a, 0x17, 0xf8, 0xe5, 0x1d, 0x61, + 0x6e, 0x91, 0xd7, 0x24, 0x08, 0xdc, 0x52, 0x35, 0x96, 0x61, + 0x5d, 0xb3, 0x56, 0x5a, 0x7f, 0x5c, 0x01, 0xf0, 0x2b, 0x3a, + 0x13, 0xa4, 0x13, 0xfb, 0x3b, 0x5b, 0xaa, 0xd3, 0x62, 0x36, + 0x54, 0x70, 0x3f, 0xe7, 0x62, 0x3c, 0x7a, 0x4f, 0xbc, 0xfc, + 0xe9, 0x48, 0x38, 0xc2, 0x51, 0x8f, 0xd4, 0x1d, 0xbb, 0xca, + 0x23, 0x33, 0x79, 0x48, 0xac, 0x77, 0x5d, 0x81 }, + { 0x48, 0x09, 0x46, 0xf8, 0xb1, 0x1e, 0xd9, 0x2d, 0x23, 0x8e, + 0xf1, 0x7c, 0x88, 0x40, 0xa6, 0xc6, 0xe1, 0xa2, 0x73, 0x8e, + 0xa1, 0x7e, 0x35, 0xa4, 0xe5, 0x73, 0xf6, 0x48, 0x9d, 0xef, + 0xf9, 0xa0, 0x03, 0x80, 0x3d, 0x84, 0x56, 0x17, 0x70, 0x40, + 0x1e, 0xe4, 0x8d, 0xe3, 0x2f, 0x7b, 0x16, 0x5b, 0x76, 0x0f, + 0x8d, 0x28, 0x5c, 0x2f, 0xfc, 0x3c, 0x22, 0x8a, 0x39, 0x1b, + 0x5d, 0x33, 0x6d, 0x51, 0xfb, 0xbd, 0xcf, 0x0c, 0x7d, 0x3d, + 0xe6, 0x66, 0xeb, 0x9a, 0xde, 0x06, 0x9a, 0x3d, 0xf8, 0x5e, + 0x4a, 0x1f, 0xee, 0x78, 0xbc, 0xe8, 0x20, 0x62, 0x91, 0xc8, + 0xcc, 0xa9, 0x55, 0xa0, 0x60, 0x81, 0x4a, 0x9e, 0xa6, 0xfb, + 0xe5, 0x50, 0xc8, 0xee, 0xd7, 0x7d, 0x58, 0x67, 0x55, 0xf3, + 0x59, 0x09, 0xd8, 0x3f, 0x95, 0xcf, 0x45, 0x80, 0x55, 0xff, + 0xa9, 0x06, 0xb2, 0x03, 0xf9, 0x60, 0x04, 0xc8 }, + { 0x8d, 0xab, 0x61, 0xfd, 0xc7, 0x38, 0x69, 0x02, 0x16, 0xe8, + 0xe8, 0xae, 0xcf, 0x68, 0xaf, 0xc7, 0xf8, 0x6f, 0x2b, 0xe6, + 0xc1, 0xf8, 0x53, 0x9f, 0xc0, 0x1c, 0x2e, 0xb2, 0x46, 0x46, + 0x4d, 0x9e, 0xa1, 0xae, 0x66, 0x6b, 0x4b, 0xa8, 0x46, 0xe4, + 0xcb, 0x3b, 0x43, 0x61, 0xe4, 0xbb, 0xd0, 0x07, 0x00, 0x89, + 0xc0, 0x6e, 0x7d, 0x06, 0xe6, 0x84, 0xe2, 0x77, 0x5e, 0xb6, + 0x09, 0x92, 0xf7, 0xd0, 0x3b, 0x72, 0xb0, 0x4d, 0x6c, 0x2b, + 0x7d, 0xd4, 0xc8, 0x86, 0x9a, 0xba, 0xe2, 0x0f, 0xd6, 0x24, + 0x84, 0x97, 0x50, 0x96, 0x2c, 0xaa, 0xf8, 0x92, 0xa1, 0xa9, + 0x90, 0x24, 0xc6, 0x30, 0xb8, 0xc0, 0x48, 0xa4, 0x88, 0x99, + 0xab, 0x18, 0xd6, 0xf4, 0x0e, 0x2f, 0x67, 0x86, 0x62, 0x98, + 0x58, 0x7a, 0x19, 0xe6, 0x5c, 0x5e, 0x53, 0xeb, 0x36, 0x95, + 0x84, 0xc7, 0x47, 0xa8, 0xfd, 0x71, 0xf1, 0x19 }, + { 0x6f, 0x77, 0xe6, 0x2d, 0xf9, 0x9b, 0x29, 0xe7, 0xe0, 0x3c, + 0xa8, 0x79, 0x11, 0x8f, 0x69, 0x0c, 0x9d, 0xef, 0x7a, 0xd1, + 0x67, 0xb9, 0x7e, 0xe1, 0x3e, 0xb2, 0x1b, 0x14, 0xcb, 0xd7, + 0xce, 0xf1, 0x55, 0xbe, 0x8a, 0x15, 0x2c, 0xaf, 0x08, 0x0e, + 0x5e, 0xce, 0x77, 0xab, 0xb8, 0x16, 0x9f, 0xed, 0x86, 0x94, + 0x22, 0x9f, 0x31, 0xdc, 0xc9, 0x57, 0xa1, 0x04, 0x44, 0xeb, + 0xa5, 0x90, 0x70, 0x0d, 0x80, 0x27, 0x14, 0xc1, 0x9e, 0xc5, + 0x15, 0x02, 0x87, 0x7f, 0x8b, 0xcf, 0x3f, 0x06, 0xfd, 0xc2, + 0x1d, 0xe7, 0x6a, 0xed, 0x91, 0x1f, 0x32, 0xe6, 0xd3, 0xd2, + 0x39, 0xbb, 0x34, 0x86, 0x54, 0x02, 0x35, 0xb2, 0xba, 0x2b, + 0x08, 0xc4, 0x62, 0x1a, 0x2d, 0x88, 0xb5, 0x20, 0x34, 0xd4, + 0x78, 0xb4, 0xac, 0xd4, 0x29, 0x7e, 0xff, 0x4f, 0x9b, 0xa2, + 0x42, 0xa5, 0xc9, 0x03, 0xd5, 0x4d, 0x1d, 0x45 }, + { 0x63, 0x81, 0x9c, 0x91, 0xc3, 0xd2, 0xcf, 0x80, 0x79, 0x9d, + 0x78, 0x86, 0x81, 0x84, 0xf0, 0xeb, 0x23, 0x44, 0xe0, 0x0f, + 0x68, 0xbe, 0xd1, 0x02, 0xee, 0x6d, 0x75, 0x78, 0xc1, 0xcf, + 0x55, 0x80, 0x86, 0x13, 0x60, 0x73, 0x2e, 0x5a, 0x8b, 0xe6, + 0xae, 0x5e, 0x2e, 0x76, 0xd6, 0x69, 0x84, 0x0a, 0x31, 0x4d, + 0x5d, 0x57, 0x77, 0x3b, 0x7b, 0x3a, 0x91, 0xe0, 0xa2, 0xef, + 0x06, 0xc0, 0xcc, 0x42, 0x99, 0xaa, 0xfa, 0xbf, 0xf8, 0x5c, + 0x3f, 0xbf, 0x11, 0xaa, 0x01, 0x2f, 0xff, 0x3b, 0xf3, 0xb5, + 0x97, 0x92, 0xa8, 0xfd, 0x6f, 0x38, 0xea, 0xc7, 0x22, 0xeb, + 0x71, 0x13, 0xa8, 0x13, 0x35, 0x9f, 0x34, 0x65, 0xb4, 0x66, + 0x4b, 0x71, 0xb0, 0x2f, 0x17, 0x55, 0xe0, 0x35, 0x73, 0x54, + 0x1c, 0xd1, 0x17, 0x7b, 0xa4, 0x53, 0x64, 0x01, 0xaa, 0xd6, + 0xa2, 0x71, 0xbd, 0xed, 0xe4, 0x0b, 0xbf, 0x59 }, + { 0x67, 0xd4, 0x8d, 0x12, 0x82, 0x65, 0xd7, 0xee, 0xc8, 0x0a, + 0xfe, 0xec, 0x55, 0xe4, 0x9b, 0x47, 0xe4, 0x3a, 0x0b, 0xe7, + 0x0a, 0x2f, 0x8c, 0xab, 0xc0, 0xd0, 0x31, 0x9a, 0x50, 0x4b, + 0x6b, 0xc1, 0xe0, 0xfc, 0x16, 0xd3, 0x4e, 0xbd, 0x45, 0x3e, + 0xe1, 0x31, 0xcc, 0x9a, 0xbd, 0xa6, 0x12, 0x5a, 0x10, 0xb2, + 0xcf, 0xe7, 0x97, 0x6a, 0x84, 0x4b, 0x1f, 0xf6, 0x0c, 0x51, + 0xa0, 0xd3, 0xd8, 0x1a, 0xc5, 0xb3, 0x37, 0x6f, 0x17, 0x1d, + 0x12, 0x04, 0x5a, 0xab, 0xf3, 0x91, 0xfa, 0xde, 0x65, 0x00, + 0xeb, 0xf5, 0x75, 0x89, 0x2a, 0xea, 0x4f, 0xbf, 0xf9, 0x66, + 0x64, 0xee, 0x1b, 0xf9, 0x6b, 0x91, 0xcb, 0x2a, 0xc0, 0x7c, + 0xe4, 0xc4, 0x7b, 0x70, 0x3d, 0x07, 0xf5, 0xf0, 0x90, 0x70, + 0x38, 0xa7, 0x9e, 0xc3, 0xa1, 0xfc, 0xeb, 0x12, 0x67, 0xea, + 0xca, 0x53, 0x92, 0xe1, 0x78, 0x84, 0xb0, 0x73 }, + { 0x27, 0x95, 0x0e, 0x38, 0xe8, 0x38, 0x4d, 0xc7, 0xa3, 0xd7, + 0xeb, 0xc3, 0x1f, 0x0e, 0x43, 0xf5, 0x2c, 0xf1, 0x13, 0xa9, + 0x28, 0xb0, 0x1d, 0xf5, 0xd4, 0x90, 0x0d, 0x0f, 0x10, 0xd1, + 0xc1, 0x84, 0x3e, 0xfc, 0xaa, 0x50, 0xab, 0xf2, 0x94, 0x01, + 0xfe, 0x8b, 0xb1, 0x20, 0x5e, 0xe6, 0x05, 0x96, 0xfd, 0xd5, + 0x6b, 0x1b, 0x4d, 0xc9, 0x27, 0xcd, 0x95, 0xf6, 0x2c, 0x85, + 0xc5, 0xb6, 0x49, 0xd4, 0x84, 0x22, 0x9d, 0xf4, 0x75, 0x61, + 0xa0, 0x10, 0x47, 0x2d, 0xdc, 0x3d, 0x64, 0xa2, 0xf9, 0xa8, + 0xde, 0xe7, 0xca, 0x2b, 0x75, 0xba, 0x8c, 0x3d, 0x89, 0xa2, + 0x42, 0xe7, 0xf7, 0x7e, 0x62, 0x93, 0xfb, 0xb6, 0x39, 0xca, + 0x07, 0x20, 0x4e, 0xbc, 0x6b, 0xd1, 0x1d, 0xb0, 0xae, 0x73, + 0x66, 0xcd, 0xd7, 0x1a, 0xbd, 0x0e, 0x27, 0x48, 0x0a, 0x63, + 0x06, 0x8d, 0x59, 0xa7, 0xea, 0x2d, 0x56, 0xd6 }, + { 0x54, 0xff, 0x78, 0x84, 0x79, 0xb2, 0x5d, 0x71, 0xa1, 0xc9, + 0x98, 0x13, 0xff, 0x22, 0x25, 0xab, 0xae, 0x80, 0x45, 0x3f, + 0xbb, 0x1e, 0x5b, 0xd8, 0xa7, 0xf0, 0x44, 0x0c, 0x9f, 0x68, + 0x4f, 0x25, 0x33, 0x5c, 0xc4, 0xf8, 0x5d, 0x15, 0xdf, 0xbf, + 0xff, 0x3a, 0xba, 0x5c, 0x69, 0x62, 0x80, 0x46, 0x55, 0xce, + 0x84, 0x91, 0x58, 0x80, 0xcd, 0xaf, 0x8e, 0xe0, 0x0e, 0x1a, + 0x8e, 0xef, 0x6c, 0xc9, 0x4e, 0x01, 0x41, 0xae, 0x85, 0x02, + 0xaa, 0x89, 0x20, 0x73, 0x95, 0x4c, 0xd2, 0xe9, 0x6d, 0xdf, + 0x14, 0x42, 0xbf, 0x36, 0x7d, 0xd4, 0xc5, 0x31, 0x46, 0x71, + 0x6f, 0x79, 0xa9, 0x25, 0xe7, 0xe7, 0xbb, 0x48, 0x27, 0xfa, + 0x4e, 0xb2, 0x1f, 0x6b, 0x4c, 0x93, 0x46, 0x89, 0x2f, 0xe3, + 0x74, 0xcb, 0x4b, 0x9f, 0xd0, 0x33, 0x04, 0x8b, 0x5d, 0xe9, + 0xea, 0xb2, 0x1f, 0xf0, 0xe1, 0xd0, 0xfa, 0x79 }, + { 0x8a, 0xdb, 0xad, 0x85, 0x3f, 0x18, 0x30, 0xfe, 0x4e, 0x4e, + 0x45, 0x73, 0xee, 0x30, 0xb2, 0x86, 0x8a, 0xcd, 0xa9, 0x65, + 0x9f, 0xa1, 0x01, 0xe6, 0x17, 0x87, 0x55, 0x00, 0x28, 0xc9, + 0x30, 0x2c, 0x06, 0x9e, 0x82, 0xdc, 0x36, 0x78, 0xa4, 0x27, + 0xd6, 0xa2, 0xc0, 0x1d, 0x8b, 0x6a, 0x6c, 0x6b, 0x28, 0x94, + 0x5e, 0x31, 0xc9, 0x55, 0xae, 0xad, 0x91, 0x53, 0x62, 0xdc, + 0xb7, 0x86, 0xea, 0x9f, 0x33, 0x9d, 0xf0, 0x81, 0x0c, 0xcd, + 0x9e, 0xc9, 0xc6, 0x8f, 0x1b, 0x3b, 0x4a, 0x2c, 0x08, 0xe3, + 0xbb, 0x74, 0xe5, 0x8f, 0xdc, 0xb0, 0xc0, 0x0f, 0xe3, 0x28, + 0x54, 0x41, 0x8d, 0xf9, 0x0d, 0x2b, 0x50, 0xa5, 0xa5, 0xad, + 0xc0, 0x41, 0x81, 0x15, 0xe2, 0x4a, 0x46, 0x04, 0xfa, 0x3b, + 0x21, 0xf6, 0x92, 0x26, 0x46, 0x5b, 0xe6, 0xf3, 0xa5, 0x1e, + 0x27, 0xc6, 0xee, 0x30, 0xde, 0x40, 0xb0, 0x68 }, + { 0x73, 0x93, 0x00, 0x36, 0xc0, 0x94, 0x5e, 0x5f, 0xf3, 0x42, + 0xc1, 0xaa, 0x02, 0x7e, 0x71, 0xc1, 0xb7, 0x5c, 0x41, 0xa6, + 0x66, 0xcb, 0xc9, 0x6c, 0xf5, 0x88, 0xb4, 0xf8, 0x17, 0x17, + 0xe1, 0xaf, 0x14, 0xeb, 0x86, 0xf3, 0x58, 0x40, 0x7a, 0x1d, + 0xdb, 0xe3, 0x86, 0xcb, 0x81, 0x6c, 0x07, 0x30, 0x40, 0x3f, + 0x16, 0x8c, 0x30, 0x26, 0xcd, 0x41, 0x95, 0xb1, 0x6c, 0xcc, + 0xcd, 0x5e, 0x87, 0xe7, 0x40, 0xd8, 0x6f, 0x30, 0x12, 0x43, + 0xf3, 0xef, 0x40, 0x90, 0xcf, 0xa6, 0x1b, 0x46, 0x4b, 0x28, + 0xcd, 0xbc, 0x2a, 0xd2, 0x09, 0x84, 0xfb, 0x0e, 0x6a, 0xa1, + 0xf5, 0xde, 0x8e, 0x1c, 0x0f, 0x7f, 0x45, 0x6b, 0x9c, 0xf2, + 0xe2, 0x33, 0x6d, 0x4f, 0x3c, 0xec, 0x67, 0x66, 0x7c, 0xc1, + 0xfc, 0xc2, 0xf4, 0x2f, 0xda, 0xf7, 0xf3, 0x9b, 0xcc, 0x79, + 0x06, 0x0a, 0xe1, 0x1f, 0x09, 0x69, 0xd5, 0x24 }, + { 0x8b, 0xc6, 0xec, 0x4a, 0xe4, 0x29, 0x65, 0xe2, 0x5b, 0xd1, + 0x01, 0x82, 0xaa, 0x7c, 0x99, 0xd3, 0x9c, 0x28, 0xa9, 0x67, + 0x73, 0xea, 0xf2, 0x23, 0xcf, 0x56, 0x13, 0x48, 0xe0, 0x96, + 0x1b, 0x31, 0x45, 0xb9, 0xe6, 0x1b, 0x73, 0x1f, 0xc4, 0x47, + 0x61, 0xa5, 0x14, 0xe1, 0xb5, 0x24, 0x63, 0x2f, 0x43, 0x4a, + 0xc7, 0xb1, 0x64, 0xac, 0x8f, 0x15, 0x70, 0x5d, 0xdd, 0x5a, + 0xd9, 0x11, 0x08, 0xcc, 0xda, 0xcd, 0xfd, 0x5d, 0xd2, 0x9c, + 0x01, 0xaa, 0x4b, 0xd7, 0xd6, 0x9d, 0x61, 0x17, 0x9c, 0xae, + 0x17, 0x15, 0x90, 0x3e, 0x6a, 0x4f, 0x69, 0x85, 0x92, 0xb3, + 0x05, 0xd1, 0x02, 0x2c, 0xeb, 0x91, 0x69, 0x64, 0x2e, 0x08, + 0xf1, 0x8f, 0xd5, 0xbc, 0x8b, 0x98, 0x68, 0x19, 0xf5, 0x51, + 0x4f, 0x25, 0x78, 0x8b, 0x59, 0x1d, 0xf4, 0x18, 0x1a, 0xab, + 0x95, 0x4f, 0x75, 0x7d, 0x22, 0xcd, 0xaf, 0x42 }, + { 0x8e, 0x85, 0x43, 0x7d, 0xbe, 0x9c, 0x7e, 0x15, 0x2b, 0x3c, + 0x8f, 0x71, 0xdc, 0xeb, 0x89, 0x55, 0xab, 0x01, 0x2c, 0x2c, + 0x58, 0x47, 0xa4, 0xd7, 0x28, 0x44, 0xd9, 0x6a, 0x98, 0x2f, + 0xc0, 0xd4, 0xd6, 0xa7, 0xdf, 0x0d, 0xaa, 0x60, 0xaa, 0x6a, + 0xd3, 0x08, 0xfc, 0x21, 0xae, 0x9b, 0x2a, 0xa8, 0xfc, 0x9a, + 0xc3, 0xb9, 0x48, 0xd6, 0x5c, 0xbb, 0xe5, 0x65, 0x43, 0x1c, + 0x8b, 0x65, 0xc9, 0xa1, 0xe3, 0x14, 0x71, 0xee, 0x6b, 0xe6, + 0xc8, 0xca, 0x73, 0x24, 0x83, 0xe3, 0x51, 0xb7, 0xda, 0x61, + 0xa0, 0xac, 0xfc, 0xa2, 0x2b, 0x29, 0xb2, 0xb7, 0x51, 0x0e, + 0x18, 0x60, 0x84, 0x57, 0xaa, 0x6e, 0x66, 0x55, 0xfc, 0x9c, + 0xbb, 0x60, 0x54, 0xa6, 0x06, 0xfe, 0x43, 0x7c, 0x40, 0x1e, + 0x36, 0x0c, 0xff, 0x54, 0x80, 0x0c, 0x09, 0x38, 0x8a, 0x30, + 0xd0, 0x96, 0xe5, 0xc0, 0xe7, 0xf2, 0xa3, 0x2b }, +}; + +/* + * Loop for modular exponentiate the value in F_p*. + * + * Using 8-bit stripe table. + * + * @param [in] key SAKKE key. + * @param [in] b MP integer that is the base to exponentiate. + * @param [in] e MP integer that is the exponent. + * @param [out] c Result of exponentiation. + * @param [in] mp Multiplier to use when converting from Montgomery form. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_modexp_loop(SakkeKey* key, const mp_int* b, mp_int* e, + mp_proj* c, mp_digit mp) +{ + int err = 0; + mp_int* t1 = &key->tmp.m1; + mp_int* t2 = &key->tmp.m2; + mp_int* by = key->tmp.p1->z; + mp_int* prime = &key->params.prime; + unsigned char eb[128]; + int i; + int y; + + /* Use table for values of b exponentiated. */ + (void)b; + + (void)mp_to_unsigned_bin_len(e, eb, sizeof(eb)); + + /* Set the working value to the base in PF_p[q] */ + err = mp_montgomery_calc_normalization(c->x, prime); + if (err == 0) { + y = (eb[112] >> 7) & 1; + y |= ((eb[ 96] >> 7) & 1) << 1; + y |= ((eb[ 80] >> 7) & 1) << 2; + y |= ((eb[ 64] >> 7) & 1) << 3; + y |= ((eb[ 48] >> 7) & 1) << 4; + y |= ((eb[ 32] >> 7) & 1) << 5; + y |= ((eb[ 16] >> 7) & 1) << 6; + y |= ((eb[ 0] >> 7) & 1) << 7; + + (void)mp_read_unsigned_bin(c->y, sakke_1024_g_table[y], 128); + } + for (i = 128 - 2; (err == 0) && (i >= 0); i--) { + y = (eb[127 - i / 8 ] >> (i & 0x7)) & 1; + y |= ((eb[127 - (i / 8 + 16)] >> (i & 0x7)) & 1) << 1; + y |= ((eb[127 - (i / 8 + 32)] >> (i & 0x7)) & 1) << 2; + y |= ((eb[127 - (i / 8 + 48)] >> (i & 0x7)) & 1) << 3; + y |= ((eb[127 - (i / 8 + 64)] >> (i & 0x7)) & 1) << 4; + y |= ((eb[127 - (i / 8 + 80)] >> (i & 0x7)) & 1) << 5; + y |= ((eb[127 - (i / 8 + 96)] >> (i & 0x7)) & 1) << 6; + y |= ((eb[127 - (i / 8 + 112)] >> (i & 0x7)) & 1) << 7; + + err = sakke_proj_sqr(c, prime, mp, c, t1, t2); + if (err == 0) { + (void)mp_read_unsigned_bin(by, sakke_1024_g_table[y], 128); + err = sakke_proj_mul_qx1(c, by, prime, mp, c, t1, t2); + } + } + + return err; +} +#endif /* WOLFSSL_SAKKE_SMALL */ + +/* + * Modular exponentiate the value in F_p*. + * + * @param [in] key SAKKE key. + * @param [in] b MP integer that is the base to exponentiate. + * @param [in] e MP integer that is the exponent. + * @param [out] r Result of exponentiation. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_modexp(SakkeKey* key, mp_int* b, mp_int* e, mp_int* r) +{ + int err; + mp_digit mp; + mp_int* prime = &key->params.prime; + mp_proj* c = key->tmp.p1; + + (void)b; + + err = mp_montgomery_setup(prime, &mp); + if (err == 0) { + err = sakke_modexp_loop(key, b, e, c, mp); + } + + if (err == 0) { + err = mp_montgomery_reduce(c->x, prime, mp); + } + if (err == 0) { + err = mp_montgomery_reduce(c->y, prime, mp); + } + /* Convert value back from PF_p[q] to F_p* */ + if (err == 0) { + err = mp_invmod(c->x, prime, c->x); + } + if (err == 0) { + err = mp_mulmod(c->x, c->y, prime, r); + } + + return err; +} +#endif /* WOLFSSL_HAVE_SP_ECC */ + +/* + * Calculate the hash values h and v. + * + * RFC 6508, section 5.1, Steps 4.a and 4.b. + * + * @param [in] key SAKKE key. + * @param [in] hashType Hash algorithm to use. + * @param [in] hashSz Size of output of hash algorithm in bytes. + * @param [in] a Hash of data and extra. + * @param [in] h Rolling hash result. + * @param [out] v Output bytes of hashing. + * @return 0 on success. + * @return BAD_FUNC_ARG when hashType is not supported. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_calc_h_v(SakkeKey* key, enum wc_HashType hashType, + word32 hashSz, const byte* a, byte* h, byte* v) +{ + int err; + + /* Step 4.a: h_i = hashfn(h_(i - 1)) */ + err = wc_HashUpdate(&key->hash, hashType, h, hashSz); + if (err == 0) { + err = wc_HashFinal(&key->hash, hashType, h); + } + + /* Step 4.b: v_i = hashfn(h_i | A) */ + if (err == 0) { + err = wc_HashUpdate(&key->hash, hashType, h, hashSz); + } + if (err == 0) { + err = wc_HashUpdate(&key->hash, hashType, a, hashSz); + } + if (err == 0) { + err = wc_HashFinal(&key->hash, hashType, v); + } + + return err; +} + +/* + * XOR hash output v into output, with length n, starting at index i. + * + * @param [in] v Output bytes of hashing. + * @param [in] hashSz Size of output of hash algorithm in bytes. + * @param [in,out] out Data to be XORed. + * @param [in] idx Index to start XORing into. + * @param [in] n Length of data to XOR (mask) in bytes. + */ +static void sakke_xor_in_v(const byte* v, word32 hashSz, byte* out, int idx, + int n) +{ + int o; + word32 i; + + if (idx == 0) { + i = hashSz - (n % hashSz); + if (i == hashSz) { + i = 0; + } + } + else { + i = 0; + } + o = i; + for (; i < hashSz; i++) { + out[idx + i - o] ^= v[i]; + } +} + +/* + * Hash octet strings to an integer range. + * + * RFC 6508, section 5.1, Steps 1 to 4. + * + * @param [in] key SAKKE key. + * @param [in] hashType Hash algorithm to use. + * @param [in] data First block of data. + * @param [in] sz Size of first block of data in bytes. + * @param [in] extra Extra block of data. + * @param [in] extraSz Size of extra block of data in bytes. + * @param [out] a Output bytes of hashing. + * @return 0 on success. + * @return BAD_FUNC_ARG when hashType is not supported. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_calc_a(SakkeKey* key, enum wc_HashType hashType, + const byte* data, word32 sz, const byte* extra, word32 extraSz, byte* a) +{ + int err; + + /* Step 1: A = hashfn( s ), where s = data | extra */ + err = wc_HashInit_ex(&key->hash, hashType, key->heap, INVALID_DEVID); + if (err == 0) { + err = wc_HashUpdate(&key->hash, hashType, data, sz); + } + if ((err == 0) && (extra != NULL)) { + err = wc_HashUpdate(&key->hash, hashType, extra, extraSz); + } + if (err == 0) { + err = wc_HashFinal(&key->hash, hashType, a); + } + + return err; +} + +/* + * Hash octet strings to an integer range. + * + * RFC 6508, section 5.1, Steps 1 to 4. + * + * @param [in] key SAKKE key. + * @param [in] hashType Hash algorithm to use. + * @param [in] a Hash of original data. + * @param [out] out Output bytes of hashing. + * @param [in] n Size of output buffer in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when hashType is not supported. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_hash_to_range(SakkeKey* key, enum wc_HashType hashType, + const byte* a, byte* out, word32 n) +{ + int err = 0; + byte h[WC_MAX_DIGEST_SIZE]; + byte v[WC_MAX_DIGEST_SIZE]; + word32 hashSz = wc_HashGetDigestSize(hashType); + word32 i; + + /* Step 1: A = hashfn( s ), where s = data | extra + * See sakke_calc_a (need function parameters to be 7 or less) + */ + + /* Step 2: h_0 = 00...00, a string of null bits of length hashlen bits */ + XMEMSET(h, 0, hashSz); + + /* Step 3: l = Ceiling(lg(n)/hashlen) */ + /* Step 4: For each i in 1 to l, do */ + for (i = 0; (err == 0) && (i < n); i += hashSz) { + /* Steps 4.a and 4.b */ + err = sakke_calc_h_v(key, hashType, hashSz, a, h, v); + + /* XOR in the result into output buffer. */ + if (err == 0) { + sakke_xor_in_v(v, hashSz, out, i, n); + } + } + + return err; +} + +/* + * Hash octet strings to an integer range - RFC 6508 section 5.1. + * Steps 1 to 6. + * + * @param [in] key SAKKE key. + * @param [in] hashType Hash algorithm to use. + * @param [in] a Hash of original data. + * @param [in] q MP integer representing modulus. + * @param [in] n Size of output in bytes. + * @param [out] r MP integer representing modulo reduced hashes. + * @return 0 on success. + * @return BAD_FUNC_ARG when hashType is not supported. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_hash_to_range_int(SakkeKey* key, enum wc_HashType hashType, + const byte* a, mp_int* q, word32 n, mp_int* r) +{ + int err; + byte* rb = key->data; + + /* Make all zeros so that hash output can be XORed in. */ + XMEMSET(rb, 0, n); + + /* Steps 1-4 */ + err = sakke_hash_to_range(key, hashType, a, rb, n); + if (err == 0) { + /* Steps 5 v' = v_1 | ... | v_l */ + err = mp_read_unsigned_bin(r, rb, n); + } + if (err == 0) { + /* Steps 6 v = v' mod n */ + err = mp_mod(r, q, r); + } + + return err; +} + +/** + * Set the identity to perform operations with. + * + * @param [in] key SAKKE key. + * @param [in] id Identity. + * @param [in] idSz Size of identity in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or id is NULL or idSz > SAKKE_ID_MAX_SIZE. + */ +int wc_SetSakkeIdentity(SakkeKey* key, const byte* id, word16 idSz) +{ + int err = 0; + + if ((key == NULL) || (id == NULL) || (idSz > SAKKE_ID_MAX_SIZE)) { + err = BAD_FUNC_ARG; + } + + if (err == 0) { + XMEMCPY(key->id, id, idSz); + key->idSz = idSz; + } + + return err; +} + +/** + * Compute the elliptic curve point I for identity. Partial for point R. + * + * RFC 6508, Section 6.2.1, Step 3.\n + * RFC 6508, Section 6.2.2, Step 5.\n + * I = [b]P + Z_S + * + * @param [in] key SAKKE key. + * @param [in] id Identity. + * @param [in] idSz Size of identity in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or id is NULL or idSz > SAKKE_ID_MAX_SIZE. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +int wc_MakeSakkePointI(SakkeKey* key, const byte* id, word16 idSz) +{ + int err = 0; + + if ((key == NULL) || (id == NULL) || (idSz > SAKKE_ID_MAX_SIZE)) { + err = BAD_FUNC_ARG; + } + + if (err == 0) { + err = sakke_load_params(key); + } + if (err == 0) { + /* I = [b]P + Z_S */ + err = sakke_compute_point_i(key, id, idSz, key->i.i); + } + if (err == 0) { + XMEMCPY(key->i.id, id, idSz); + key->i.idSz = idSz; + } + + return err; +} + +/** + * Get the elliptic curve point I - a partial calculation for point R. + * + * RFC 6508, Section 6.2.1, Step 3.\n + * RFC 6508, Section 6.2.2, Step 5.\n + * I = [b]P + Z_S + * + * @param [in] key SAKKE key. + * @param [out] data Encoding of point I. + * @param [in,out] sz On in, the size of data in bytes. + * On out, the size of the encoding in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or sz is NULL. + * @return LENGTH_ONLY_E when data is NULL. Number of bytes required returned + * in sz. + * @return BUFFER_E when sz is too small to hold encoding. + */ +int wc_GetSakkePointI(SakkeKey* key, byte* data, word32* sz) +{ + int err = 0; + + if ((key == NULL) || (sz == NULL)) { + err = BAD_FUNC_ARG; + } + + if ((err == 0) && (data == NULL)) { + *sz = key->ecc.dp->size * 2; + err = LENGTH_ONLY_E; + } + if ((err == 0) && (*sz < (word32)key->ecc.dp->size * 2)) { + err = BUFFER_E; + } + + if (err == 0) { + /* Write out the x ordinate into key size bytes. */ + err = mp_to_unsigned_bin_len(key->i.i->x, data, key->ecc.dp->size); + } + if (err == 0) { + data += key->ecc.dp->size; + /* Write data the y ordinate into key size bytes. */ + err = mp_to_unsigned_bin_len(key->i.i->y, data, key->ecc.dp->size); + } + if (err == 0) { + *sz = key->ecc.dp->size * 2; + } + + return err; +} + +/** + * Set the elliptic curve point I - a partial calucation for point R - and the + * identity that it belongs to. + * + * RFC 6508, Section 6.2.1, Step 3.\n + * RFC 6508, Section 6.2.2, Step 5.\n + * I = [b]P + Z_S + * + * @param [in] key SAKKE key. + * @param [out] data Encoding of point I. + * @param [in,out] sz On in, the size of data in bytes. + * On out, the size of the encoding in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, id or data is NULL. + * @return BUFFER_E when idSz is too big to store or sz is not the required + * size. + */ +int wc_SetSakkePointI(SakkeKey* key, const byte* id, word16 idSz, + const byte* data, word32 sz) +{ + int err = 0; + + if ((key == NULL) || (id == NULL) || (data == NULL)) { + err = BAD_FUNC_ARG; + } + if ((err == 0) && ((idSz > SAKKE_ID_MAX_SIZE) || + (sz != (word32)key->ecc.dp->size * 2))) { + err = BUFFER_E; + } + + if (err == 0) { + /* Read the x value from key size bytes. */ + err = mp_read_unsigned_bin(key->i.i->x, data, key->ecc.dp->size); + } + if (err == 0) { + data += key->ecc.dp->size; + /* Read the y value from key size bytes. */ + err = mp_read_unsigned_bin(key->i.i->y, data, key->ecc.dp->size); + } + if (err == 0) { + err = mp_set(key->i.i->z, 1); + } + if (err == 0) { + XMEMCPY(key->i.id, id, idSz); + key->i.idSz = idSz; + } + + return err; +} + +/** + * Generate the pre-computation table for point I. + * + * A reference to the table is stored if successfully generated. + * + * @param [in] key SAKKE key. + * @param [in,out] table Pre-computation table. + * NULL to indicate that only length required. + * @param [in,out] len On in, the size of table buffer in bytes. + * On out, the size of table data in bytes. + * @return BAD_FUNC_ARG then key or len is NULL. + * @return LENGTH_ONLY_E when only the length is returned. + * @return BUFFER_E when len is too small. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int wc_GenerateSakkePointITable(SakkeKey* key, byte* table, word32* len) +{ + int err = 0; + + if ((key == NULL) || (len == NULL)) { + err = BAD_FUNC_ARG; + } + +#ifdef WOLFSSL_HAVE_SP_ECC + if (err == 0) { + err = sp_ecc_gen_table_1024(key->i.i, table, len, key->heap); + } + if (err == 0) { + key->i.table = table; + key->i.tableLen = *len; + } +#else + if ((err == 0) && (table == NULL)) { + *len = 0; + err = LENGTH_ONLY_E; + } + if ((err == 0) && (*len != 0)) { + *len = 0; + err = BUFFER_E; + } + if (err == 0) { + *len = 0; + key->i.table = table; + key->i.tableLen = *len; + } + (void)table; +#endif + + return err; +} + +/** + * Sets the pre-computation table for point I. + * Speeds up making and deriving the encapsulated SSV. + * + * @param [in] key SAKKE key. + * @param [in] table Pre-computation table for Point I. + * @param [in] len Length of pre-computation table in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or table is NULL. + */ +int wc_SetSakkePointITable(SakkeKey* key, byte* table, word32 len) +{ + int err = 0; +#ifdef WOLFSSL_HAVE_SP_ECC + word32 sz = 0; +#endif + + if ((key == NULL) || (table == NULL)) { + err = BAD_FUNC_ARG; + } + +#ifdef WOLFSSL_HAVE_SP_ECC + if (err == 0) { + err = sp_ecc_gen_table_1024(key->i.i, NULL, &sz, NULL); + if (err == LENGTH_ONLY_E) { + err = 0; + } + } + if ((err == 0) && (len != sz)) { + err = BUFFER_E; + } +#else + if ((err == 0) && (len != 0)) { + err = BUFFER_E; + } +#endif + + if (err == 0) { + key->i.table = table; + key->i.tableLen = len; + } + + return err; +} + +/** + * Clears the pre-computation table for point I. + * + * Must be called once the table has been disposed of. + * + * @param [in] key SAKKE key. + * @return 0 on success. + * @return BAD_FUNC_ARG when key is NULL. + */ +int wc_ClearSakkePointITable(SakkeKey* key) +{ + int err = 0; + + if (key == NULL) { + err = BAD_FUNC_ARG; + } + + if (err == 0) { + key->i.table = NULL; + key->i.tableLen = 0; + } + + return err; +} + +/* + * Compute the elliptic curve point R for device B. + * + * RFC 6508, Section 6.2.1, Step 3.\n + * RFC 6508, Section 6.2.2, Step 5.\n + * R = [r]([b]P + Z_S) + * + * @param [in] key SAKKE key. + * @param [in] id Identifier to of device B. + * @param [in] idSz Size of identifier in bytes. + * @param [in] z ECC point - KMS Public Key Z_S. + * @param [in] n Number of bytes in r. + * @param [in] out Result R encoded to bytes. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sakke_compute_point_r(SakkeKey* key, const byte* id, word16 idSz, + const mp_int* r, word32 n, byte* out) +{ + int err = 0; + ecc_point* i = key->i.i; + ecc_point* rp = key->tmp.p2; + word32 sz; + + if ((key->i.idSz == 0) || (key->i.idSz != idSz) || + (XMEMCMP(id, key->i.id, idSz) != 0)) { + /* I = [b]P + Z_S */ + err = sakke_compute_point_i(key, id, idSz, i); + if ((err == 0) && (idSz <= SAKKE_ID_MAX_SIZE)) { + XMEMCPY(key->i.id, id, idSz); + key->i.idSz = idSz; + } + key->i.table = NULL; + key->i.tableLen = 0; + } + /* [r]([b]P + Z_S) */ + if (err == 0) { + err = sakke_mulmod_point(key, r, i, key->i.table, rp, 1); + } + /* Export to canonical form */ + if (err == 0) { + sz = n * 2 + 1; + err = wc_ecc_export_point_der(wc_ecc_get_curve_idx(key->ecc.dp->id), rp, + out, &sz); + } + + return err; +} + +/** + * Makes the Shared Secret Value (SSV) encapsulated and returns the + * authentication data. + * + * RFC 6508, Section 6.2.1. + * + * SSV is overwritten with encapsulated SSV. + * + * Call wc_SetSakkeIdentity() to set the identity to use with operation. + * + * @param [in] key SAKKE key. + * @param [in,out] ssv On in, Shared Secret Value (SSV) data. + * On out, encrypted Shared Secret Value (SSV) data. + * @param [in] ssvSz Size of SSV in bytes. + * @param [in] hashType Hash algorithm to use. + * @param [out] auth Authentication data. + * @param [out] authSz Size of authentication data in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, ssv or encSz is NULL, ssvSz is to big or + * encSz is too small. + * @return BAD_STATE_E when identity not set. + * @return LENGTH_ONLY_E when auth is NULL. authSz contains required size of + * auth in bytes. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +int wc_MakeSakkeEncapsulatedSSV(SakkeKey* key, enum wc_HashType hashType, + byte* ssv, word16 ssvSz, byte* auth, word16* authSz) +{ + int err = 0; + mp_int* r = NULL; + word16 n = 0; + word16 outSz = 0; + byte a[WC_MAX_DIGEST_SIZE]; + + if ((key == NULL) || (ssv == NULL) || (authSz == NULL)) { + err = BAD_FUNC_ARG; + } + if ((err == 0) && (key->idSz == 0)) { + err = BAD_STATE_E; + } + + /* Load parameters */ + if (err == 0) { + err = sakke_load_params(key); + } + if (err == 0) { + n = (word16)((mp_count_bits(&key->params.prime) + 7) / 8); + + /* Uncompressed point */ + outSz = 1 + 2 * n; + + if ((auth != NULL) && (*authSz < outSz)) { + err = BAD_FUNC_ARG; + } + } + if (err == 0) { + *authSz = outSz; + + if (auth == NULL) { + err = LENGTH_ONLY_E; + } + } + + if (err == 0) { + err = sakke_load_base_point(key); + } + if (err == 0) { + err = sakke_load_pairing_base(key); + } + + /* Step 1: Generate a random SSV 0..(2^n)-1 + * Already generated - see wc_MakeSakkeEncapsulated() + */ + /* Step 2: Compute r = HashToIntegerRange( SSV | b, q, Hash ) */ + if (err == 0) { + err = sakke_calc_a(key, hashType, ssv, ssvSz, key->id, key->idSz, a); + } + if (err == 0) { + r = key->tmp.p3->z; + err = sakke_hash_to_range_int(key, hashType, a, &key->params.q, n, r); + } + /* Step 3: Compute R_(b,S) = [r]([b]P + Z_S) in E(F_p) */ + if (err == 0) { + err = sakke_compute_point_r(key, key->id, key->idSz, r, n, auth); + } + + /* Step 4.a: Compute g^r */ + if (err == 0) { + err = sakke_modexp(key, &key->params.g, r, r); + } + + /* Step 4.b: Compute H := SSV XOR HashToIntegerRange( g^r, 2^n, Hash ) */ + if (err == 0) { + err = mp_to_unsigned_bin_len(r, key->data, n); + } + /* ssv ^= HashToIntegerRange( g^r, 2^n, Hash ) */ + if (err == 0) { + err = sakke_calc_a(key, hashType, key->data, n, NULL, 0, a); + } + if (err == 0) { + err = sakke_hash_to_range(key, hashType, a, ssv, ssvSz); + } + + /* Step 5: Form the Encapsulated Data ( R_(b,S), H ) + * R_(b,S) encoded in sakke_compute_point_r, H is a pointer into enc. + */ + + /* Step 6: Output SSV - already encoded in buffer */ + + return err; +} + +/** + * Generate a random Shared Secret Value (SSV). + * + * RFC 6508, Section 6.2.1, Step 1. + * + * @param [in] key SAKKE key. + * @param [in] rng Random number generator. + * @param [out] ssv Shared Secret Value (SSV) data. + * @param [out] ssvSz Size of SSV in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, rng or ssvSz is NULL or ssvSz is to small. + * @return LENGTH_ONLY_E when ssv is NULL. ssvSz contains the required size of + * in bytes. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +int wc_GenerateSakkeSSV(SakkeKey* key, WC_RNG* rng, byte* ssv, word16* ssvSz) +{ + int err = 0; + word16 n = 0; + + if ((key == NULL) || (rng == NULL) || (ssvSz == NULL)) { + err = BAD_FUNC_ARG; + } + + /* Load parameters */ + if (err == 0) { + err = sakke_load_params(key); + } + if (err == 0) { + n = (word16)((mp_count_bits(&key->params.prime) + 7) / 8); + + if ((ssv != NULL) && (*ssvSz > n)) { + err = BAD_FUNC_ARG; + } + } + if (err == 0) { + /* Return length only if an ouput buffer is NULL. */ + if (ssv == NULL) { + *ssvSz = (word16) (n / 8); + err = LENGTH_ONLY_E; + } + else { + n = *ssvSz; + } + } + + /* Step 1: Select a random ephemeral integer value. Range 0..(2^n - 1) */ + if (err == 0) { + err = wc_RNG_GenerateBlock(rng, ssv, n); + } + + return err; +} + +/** + * Derive the Shared Secret Value from the encapsulated data using the set + * RSK + * + * RFC 6508, Section 6.2.2. + * + * Encapsulated SSV is overwritten with SSV. + * + * Call wc_SetSakkeIdentity() to set the identity to use with operation. + * + * Call wc_SetSakkeRSK() to set the Receiver Secret Key (RSK) to use with + * operation. + * + * @param [in] key SAKKE key. + * @param [in] hashType Hash algorithm to use. + * @param [in,out] ssv On in, encrypted Secret Shared Value (SSV) data. + * On out, Secret Shared Value (SSV) data. + * @param [in] ssvSz Size of SSV in bytes. + * @param [in] auth Authentication data. + * @param [in] authSz Size of authentication data in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, ssv or auth is NULL. + * @return BAD_STATE_E when RSK or identity not set. + * @return SAKKE_VERIFY_FAIL_E when calculated R doesn't match the encapsulated + * data's R. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +int wc_DeriveSakkeSSV(SakkeKey* key, enum wc_HashType hashType, byte* ssv, + word16 ssvSz, const byte* auth, word16 authSz) +{ + int err = 0; + word16 n = 0; + ecc_point* r = NULL; + mp_int* w = NULL; + mp_int* ri = NULL; + byte* wb = NULL; + byte* test = NULL; + byte a[WC_MAX_DIGEST_SIZE] = {0}; + + if ((key == NULL) || (ssv == NULL) || (auth == NULL)) { + err = BAD_FUNC_ARG; + } + if ((err == 0) && (!key->rsk.set || (key->idSz == 0))) { + err = BAD_STATE_E; + } + + /* Load parameters */ + if (err == 0) { + err = sakke_load_params(key); + } + if (err == 0) { + n = (word16)((mp_count_bits(&key->params.prime) + 7) / 8); + + if (authSz != 2 * n + 1) { + err = BAD_FUNC_ARG; + } + } + if (err == 0) { + err = sakke_load_base_point(key); + } + + /* Step 1: Parse the Encapsulated Data ( R_(b,S), H ) + * H = auth, so already extracted. */ + if (err == 0) { + r = key->tmp.p2; + + err = wc_ecc_import_point_der(auth, n * 2 + 1, + wc_ecc_get_curve_idx(key->ecc.dp->id), r); + } + + /* Step 2: w = < R_(b,S), K_(b,S) > = < K_(b,S), R_(b,S) > = < rsk , r > */ + if (err == 0) { + w = &key->tmp.m1; + + err = sakke_pairing(key, key->rsk.rsk, r, w, key->rsk.table, + key->rsk.tableLen); + } + + /* Step 3: Compute SSV = H XOR HashToIntegerRange( w, 2^n, Hash ) */ + if (err == 0) { + wb = key->data; + err = mp_to_unsigned_bin_len(w, wb, n); + } + /* HashToIntegerRange( w, 2^n, Hash ) */ + if (err == 0) { + err = sakke_calc_a(key, hashType, wb, n, NULL, 0, a); + } + if (err == 0) { + err = sakke_hash_to_range(key, hashType, a, ssv, ssvSz); + } + + /* Step 4: r = HashToIntegerRange( SSV | b, q, Hash ) */ + if (err == 0) { + err = sakke_calc_a(key, hashType, ssv, ssvSz, key->id, key->idSz, a); + } + if (err == 0) { + ri = &key->tmp.m1; + err = sakke_hash_to_range_int(key, hashType, a, &key->params.q, n, ri); + } + + /* Step 5: Compute TEST = [r]([b]P + Z_S) == R_(b,S) */ + if (err == 0) { + test = key->data; + + err = sakke_compute_point_r(key, key->id, key->idSz, ri, n, test); + } + if ((err == 0) && (XMEMCMP(auth, test, 2 * n + 1) != 0)) { + err = SAKKE_VERIFY_FAIL_E; + } + + return err; +} +#endif /* WOLFCRYPT_SAKKE_CLIENT */ + +#endif /* WOLFCRYPT_HAVE_SAKKE */ + diff --git a/wolfcrypt/src/sha.c b/wolfcrypt/src/sha.c index 6b97752bf..74a20ec10 100644 --- a/wolfcrypt/src/sha.c +++ b/wolfcrypt/src/sha.c @@ -1,6 +1,6 @@ /* sha.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 3ee43f4ab..1195223a4 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -1,6 +1,6 @@ /* sha256.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -167,6 +167,9 @@ where 0 <= L < 2^64. #ifndef NO_AVX2_SUPPORT #define HAVE_INTEL_AVX2 #endif +#else + #undef HAVE_INTEL_AVX1 + #undef HAVE_INTEL_AVX2 #endif /* USE_INTEL_SPEEDUP */ #if defined(HAVE_INTEL_AVX2) @@ -841,7 +844,7 @@ static int InitSha256(wc_Sha256* sha256) S[i] = sha256->digest[i]; for (i = 0; i < 16; i++) - W[i] = *((word32*)&data[i*sizeof(word32)]); + W[i] = *((const word32*)&data[i*sizeof(word32)]); for (i = 16; i < WC_SHA256_BLOCK_SIZE; i++) W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15]) + W[i-16]; diff --git a/wolfcrypt/src/sha256_asm.S b/wolfcrypt/src/sha256_asm.S index bb2e6bb8c..8d1e469e1 100644 --- a/wolfcrypt/src/sha256_asm.S +++ b/wolfcrypt/src/sha256_asm.S @@ -1,6 +1,6 @@ /* sha256_asm * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/sha3.c b/wolfcrypt/src/sha3.c index 8cd9c9d58..74375640f 100644 --- a/wolfcrypt/src/sha3.c +++ b/wolfcrypt/src/sha3.c @@ -1,6 +1,6 @@ /* sha3.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -554,7 +554,7 @@ static word64 Load64BitBigEndian(const byte* a) return n; #else - return *(word64*)a; + return *(const word64*)a; #endif } @@ -1193,7 +1193,7 @@ int wc_Shake256_Final(wc_Shake* shake, byte* hash, word32 hashLen) return BAD_FUNC_ARG; } - ret = Sha3Final(shake, 0x1f, hash, WC_SHA3_256_COUNT, hashLen); + ret = Sha3Final(shake, 0x1f, hash, WC_SHA3_256_COUNT, (byte)hashLen); if (ret != 0) return ret; diff --git a/wolfcrypt/src/sha512.c b/wolfcrypt/src/sha512.c index a71d152a2..48744e661 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -1,6 +1,6 @@ /* sha512.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/sha512_asm.S b/wolfcrypt/src/sha512_asm.S index d72c24e8d..12fc4bb45 100644 --- a/wolfcrypt/src/sha512_asm.S +++ b/wolfcrypt/src/sha512_asm.S @@ -1,6 +1,6 @@ /* sha512_asm * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/signature.c b/wolfcrypt/src/signature.c index 50c883906..948d17c33 100644 --- a/wolfcrypt/src/signature.c +++ b/wolfcrypt/src/signature.c @@ -1,6 +1,6 @@ /* signature.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/sp_arm32.c b/wolfcrypt/src/sp_arm32.c index d2f8c8907..2af49347f 100644 --- a/wolfcrypt/src/sp_arm32.c +++ b/wolfcrypt/src/sp_arm32.c @@ -1,6 +1,6 @@ /* sp.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -58,7 +58,8 @@ */ static void sp_2048_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -100,7 +101,8 @@ static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 32 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -134,7 +136,9 @@ static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -173,7 +177,10 @@ static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a) */ static void sp_2048_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; j = 2048 / 8 - 1; a[j] = 0; @@ -215,66 +222,60 @@ static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) "sub sp, sp, #32\n\t" "mov r10, #0\n\t" "# A[0] * B[0]\n\t" - "ldr r8, [%[a], #0]\n\t" - "ldr r9, [%[b], #0]\n\t" - "umull r3, r4, r8, r9\n\t" + "ldr r11, [%[a], #0]\n\t" + "ldr r12, [%[b], #0]\n\t" + "umull r3, r4, r11, r12\n\t" "mov r5, #0\n\t" "str r3, [sp]\n\t" "# A[0] * B[1]\n\t" - "ldr r8, [%[a], #0]\n\t" "ldr r9, [%[b], #4]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r10, r10\n\t" "# A[1] * B[0]\n\t" "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #0]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "str r4, [sp, #4]\n\t" + "# A[2] * B[0]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "# A[1] * B[1]\n\t" + "ldr r11, [%[a], #4]\n\t" + "ldr r12, [%[b], #4]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" "# A[0] * B[2]\n\t" "ldr r8, [%[a], #0]\n\t" "ldr r9, [%[b], #8]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r10, r10\n\t" - "# A[1] * B[1]\n\t" - "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #4]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[2] * B[0]\n\t" - "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #0]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "str r5, [sp, #8]\n\t" "# A[0] * B[3]\n\t" - "ldr r8, [%[a], #0]\n\t" "ldr r9, [%[b], #12]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r10, r10\n\t" "# A[1] * B[2]\n\t" - "ldr r8, [%[a], #4]\n\t" "ldr r9, [%[b], #8]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "# A[2] * B[1]\n\t" "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #4]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" @@ -286,13 +287,25 @@ static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "str r3, [sp, #12]\n\t" - "# A[0] * B[4]\n\t" - "ldr r8, [%[a], #0]\n\t" - "ldr r9, [%[b], #16]\n\t" + "# A[4] * B[0]\n\t" + "ldr r8, [%[a], #16]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r10, r10\n\t" + "# A[3] * B[1]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[2] * B[2]\n\t" + "ldr r11, [%[a], #8]\n\t" + "ldr r12, [%[b], #8]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" "# A[1] * B[3]\n\t" "ldr r8, [%[a], #4]\n\t" "ldr r9, [%[b], #12]\n\t" @@ -300,30 +313,15 @@ static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" - "# A[2] * B[2]\n\t" - "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #8]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[3] * B[1]\n\t" - "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #4]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[4] * B[0]\n\t" - "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #0]\n\t" + "# A[0] * B[4]\n\t" + "ldr r8, [%[a], #0]\n\t" + "ldr r9, [%[b], #16]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "str r4, [sp, #16]\n\t" "# A[0] * B[5]\n\t" - "ldr r8, [%[a], #0]\n\t" "ldr r9, [%[b], #20]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" @@ -337,16 +335,14 @@ static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "# A[2] * B[3]\n\t" - "ldr r8, [%[a], #8]\n\t" "ldr r9, [%[b], #12]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "# A[3] * B[2]\n\t" "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #8]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" @@ -365,20 +361,32 @@ static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "str r5, [sp, #20]\n\t" - "# A[0] * B[6]\n\t" - "ldr r8, [%[a], #0]\n\t" - "ldr r9, [%[b], #24]\n\t" + "# A[6] * B[0]\n\t" + "ldr r8, [%[a], #24]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r10, r10\n\t" - "# A[1] * B[5]\n\t" - "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #20]\n\t" + "# A[5] * B[1]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #4]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" + "# A[4] * B[2]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[3] * B[3]\n\t" + "ldr r11, [%[a], #12]\n\t" + "ldr r12, [%[b], #12]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" "# A[2] * B[4]\n\t" "ldr r8, [%[a], #8]\n\t" "ldr r9, [%[b], #16]\n\t" @@ -386,37 +394,22 @@ static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" - "# A[3] * B[3]\n\t" - "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #12]\n\t" + "# A[1] * B[5]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #20]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" - "# A[4] * B[2]\n\t" - "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #8]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[5] * B[1]\n\t" - "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #4]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[6] * B[0]\n\t" - "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #0]\n\t" + "# A[0] * B[6]\n\t" + "ldr r8, [%[a], #0]\n\t" + "ldr r9, [%[b], #24]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "str r3, [sp, #24]\n\t" "# A[0] * B[7]\n\t" - "ldr r8, [%[a], #0]\n\t" "ldr r9, [%[b], #28]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" @@ -437,16 +430,14 @@ static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "# A[3] * B[4]\n\t" - "ldr r8, [%[a], #12]\n\t" "ldr r9, [%[b], #16]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "# A[4] * B[3]\n\t" "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #12]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" @@ -472,20 +463,32 @@ static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "str r4, [sp, #28]\n\t" - "# A[1] * B[7]\n\t" - "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #28]\n\t" + "# A[7] * B[1]\n\t" + "ldr r9, [%[b], #4]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r10, r10\n\t" - "# A[2] * B[6]\n\t" - "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #24]\n\t" + "# A[6] * B[2]\n\t" + "ldr r8, [%[a], #24]\n\t" + "ldr r9, [%[b], #8]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" + "# A[5] * B[3]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[4] * B[4]\n\t" + "ldr r11, [%[a], #16]\n\t" + "ldr r12, [%[b], #16]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" "# A[3] * B[5]\n\t" "ldr r8, [%[a], #12]\n\t" "ldr r9, [%[b], #20]\n\t" @@ -493,30 +496,16 @@ static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" - "# A[4] * B[4]\n\t" - "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #16]\n\t" + "# A[2] * B[6]\n\t" + "ldr r8, [%[a], #8]\n\t" + "ldr r9, [%[b], #24]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" - "# A[5] * B[3]\n\t" - "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #12]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[6] * B[2]\n\t" - "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #8]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[7] * B[1]\n\t" - "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #4]\n\t" + "# A[1] * B[7]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #28]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" @@ -524,7 +513,6 @@ static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) "str r5, [%[r], #32]\n\t" "# A[2] * B[7]\n\t" "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #28]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" @@ -537,16 +525,14 @@ static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "# A[4] * B[5]\n\t" - "ldr r8, [%[a], #16]\n\t" "ldr r9, [%[b], #20]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "# A[5] * B[4]\n\t" "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #16]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" @@ -565,13 +551,25 @@ static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "str r3, [%[r], #36]\n\t" - "# A[3] * B[7]\n\t" - "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #28]\n\t" + "# A[7] * B[3]\n\t" + "ldr r9, [%[b], #12]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r10, r10\n\t" + "# A[6] * B[4]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[5] * B[5]\n\t" + "ldr r11, [%[a], #20]\n\t" + "ldr r12, [%[b], #20]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" "# A[4] * B[6]\n\t" "ldr r8, [%[a], #16]\n\t" "ldr r9, [%[b], #24]\n\t" @@ -579,23 +577,9 @@ static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" - "# A[5] * B[5]\n\t" - "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #20]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[6] * B[4]\n\t" - "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #16]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[7] * B[3]\n\t" - "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #12]\n\t" + "# A[3] * B[7]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #28]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" @@ -603,22 +587,19 @@ static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) "str r4, [%[r], #40]\n\t" "# A[4] * B[7]\n\t" "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #28]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r10, r10\n\t" "# A[5] * B[6]\n\t" - "ldr r8, [%[a], #20]\n\t" "ldr r9, [%[b], #24]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "# A[6] * B[5]\n\t" "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #20]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" @@ -630,71 +611,52 @@ static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "str r5, [%[r], #44]\n\t" + "# A[7] * B[5]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "# A[6] * B[6]\n\t" + "ldr r11, [%[a], #24]\n\t" + "ldr r12, [%[b], #24]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" "# A[5] * B[7]\n\t" "ldr r8, [%[a], #20]\n\t" "ldr r9, [%[b], #28]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r10, r10\n\t" - "# A[6] * B[6]\n\t" - "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #24]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[7] * B[5]\n\t" - "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #20]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "str r3, [%[r], #48]\n\t" "# A[6] * B[7]\n\t" - "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #28]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r10, r10\n\t" "# A[7] * B[6]\n\t" "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #24]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "str r4, [%[r], #52]\n\t" "# A[7] * B[7]\n\t" - "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #28]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adc r3, r3, r7\n\t" "str r5, [%[r], #56]\n\t" "str r3, [%[r], #60]\n\t" - "ldr r3, [sp, #0]\n\t" - "ldr r4, [sp, #4]\n\t" - "ldr r5, [sp, #8]\n\t" - "ldr r6, [sp, #12]\n\t" - "str r3, [%[r], #0]\n\t" - "str r4, [%[r], #4]\n\t" - "str r5, [%[r], #8]\n\t" - "str r6, [%[r], #12]\n\t" - "ldr r3, [sp, #16]\n\t" - "ldr r4, [sp, #20]\n\t" - "ldr r5, [sp, #24]\n\t" - "ldr r6, [sp, #28]\n\t" - "str r3, [%[r], #16]\n\t" - "str r4, [%[r], #20]\n\t" - "str r5, [%[r], #24]\n\t" - "str r6, [%[r], #28]\n\t" - "add sp, sp, #32\n\t" + "ldm sp!, {r3, r4, r5, r6}\n\t" + "stm %[r]!, {r3, r4, r5, r6}\n\t" + "ldm sp!, {r3, r4, r5, r6}\n\t" + "stm %[r]!, {r3, r4, r5, r6}\n\t" + "sub %[r], %[r], #32\n\t" : : [r] "r" (r), [a] "r" (a), [b] "r" (b) - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" + : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); } @@ -707,7 +669,7 @@ static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a) { __asm__ __volatile__ ( "sub sp, sp, #32\n\t" - "mov r14, #0\n\t" + "mov r12, #0\n\t" "# A[0] * A[0]\n\t" "ldr r10, [%[a], #0]\n\t" "umull r8, r3, r10, r10\n\t" @@ -719,10 +681,10 @@ static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r14, r14\n\t" + "adc r2, r12, r12\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" + "adc r2, r2, r12\n\t" "str r3, [sp, #4]\n\t" "# A[0] * A[2]\n\t" "ldr r10, [%[a], #8]\n\t" @@ -730,16 +692,16 @@ static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r4, r4, r8\n\t" "adcs r2, r2, r9\n\t" - "adc r3, r14, r14\n\t" + "adc r3, r12, r12\n\t" "adds r4, r4, r8\n\t" "adcs r2, r2, r9\n\t" - "adc r3, r3, r14\n\t" + "adc r3, r3, r12\n\t" "# A[1] * A[1]\n\t" "ldr r10, [%[a], #4]\n\t" "umull r8, r9, r10, r10\n\t" "adds r4, r4, r8\n\t" "adcs r2, r2, r9\n\t" - "adc r3, r3, r14\n\t" + "adc r3, r3, r12\n\t" "str r4, [sp, #8]\n\t" "# A[0] * A[3]\n\t" "ldr r10, [%[a], #12]\n\t" @@ -747,20 +709,20 @@ static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r2, r2, r8\n\t" "adcs r3, r3, r9\n\t" - "adc r4, r14, r14\n\t" + "adc r4, r12, r12\n\t" "adds r2, r2, r8\n\t" "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" + "adc r4, r4, r12\n\t" "# A[1] * A[2]\n\t" "ldr r10, [%[a], #8]\n\t" "ldr r8, [%[a], #4]\n\t" "umull r8, r9, r10, r8\n\t" "adds r2, r2, r8\n\t" "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" + "adc r4, r4, r12\n\t" "adds r2, r2, r8\n\t" "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" + "adc r4, r4, r12\n\t" "str r2, [sp, #12]\n\t" "# A[0] * A[4]\n\t" "ldr r10, [%[a], #16]\n\t" @@ -768,26 +730,26 @@ static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r14, r14\n\t" + "adc r2, r12, r12\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" + "adc r2, r2, r12\n\t" "# A[1] * A[3]\n\t" "ldr r10, [%[a], #12]\n\t" "ldr r8, [%[a], #4]\n\t" "umull r8, r9, r10, r8\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" + "adc r2, r2, r12\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" + "adc r2, r2, r12\n\t" "# A[2] * A[2]\n\t" "ldr r10, [%[a], #8]\n\t" "umull r8, r9, r10, r10\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" + "adc r2, r2, r12\n\t" "str r3, [sp, #16]\n\t" "# A[0] * A[5]\n\t" "ldr r10, [%[a], #20]\n\t" @@ -801,14 +763,14 @@ static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[2] * A[3]\n\t" "ldr r10, [%[a], #12]\n\t" "ldr r8, [%[a], #8]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "adds r5, r5, r5\n\t" "adcs r6, r6, r6\n\t" "adc r7, r7, r7\n\t" @@ -828,14 +790,14 @@ static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[2] * A[4]\n\t" "ldr r10, [%[a], #16]\n\t" "ldr r8, [%[a], #8]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[3] * A[3]\n\t" "ldr r10, [%[a], #12]\n\t" "umull r8, r9, r10, r10\n\t" @@ -844,7 +806,7 @@ static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a) "adc r7, r7, r7\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "adds r2, r2, r5\n\t" "adcs r3, r3, r6\n\t" "adc r4, r4, r7\n\t" @@ -861,21 +823,21 @@ static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[2] * A[5]\n\t" "ldr r10, [%[a], #20]\n\t" "ldr r8, [%[a], #8]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[3] * A[4]\n\t" "ldr r10, [%[a], #16]\n\t" "ldr r8, [%[a], #12]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "adds r5, r5, r5\n\t" "adcs r6, r6, r6\n\t" "adc r7, r7, r7\n\t" @@ -895,14 +857,14 @@ static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[3] * A[5]\n\t" "ldr r10, [%[a], #20]\n\t" "ldr r8, [%[a], #12]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[4] * A[4]\n\t" "ldr r10, [%[a], #16]\n\t" "umull r8, r9, r10, r10\n\t" @@ -911,7 +873,7 @@ static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a) "adc r7, r7, r7\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "adds r4, r4, r5\n\t" "adcs r2, r2, r6\n\t" "adc r3, r3, r7\n\t" @@ -928,14 +890,14 @@ static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[4] * A[5]\n\t" "ldr r10, [%[a], #20]\n\t" "ldr r8, [%[a], #16]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "adds r5, r5, r5\n\t" "adcs r6, r6, r6\n\t" "adc r7, r7, r7\n\t" @@ -949,26 +911,26 @@ static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r14, r14\n\t" + "adc r2, r12, r12\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" + "adc r2, r2, r12\n\t" "# A[4] * A[6]\n\t" "ldr r10, [%[a], #24]\n\t" "ldr r8, [%[a], #16]\n\t" "umull r8, r9, r10, r8\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" + "adc r2, r2, r12\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" + "adc r2, r2, r12\n\t" "# A[5] * A[5]\n\t" "ldr r10, [%[a], #20]\n\t" "umull r8, r9, r10, r10\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" + "adc r2, r2, r12\n\t" "str r3, [%[r], #40]\n\t" "# A[4] * A[7]\n\t" "ldr r10, [%[a], #28]\n\t" @@ -976,20 +938,20 @@ static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r4, r4, r8\n\t" "adcs r2, r2, r9\n\t" - "adc r3, r14, r14\n\t" + "adc r3, r12, r12\n\t" "adds r4, r4, r8\n\t" "adcs r2, r2, r9\n\t" - "adc r3, r3, r14\n\t" + "adc r3, r3, r12\n\t" "# A[5] * A[6]\n\t" "ldr r10, [%[a], #24]\n\t" "ldr r8, [%[a], #20]\n\t" "umull r8, r9, r10, r8\n\t" "adds r4, r4, r8\n\t" "adcs r2, r2, r9\n\t" - "adc r3, r3, r14\n\t" + "adc r3, r3, r12\n\t" "adds r4, r4, r8\n\t" "adcs r2, r2, r9\n\t" - "adc r3, r3, r14\n\t" + "adc r3, r3, r12\n\t" "str r4, [%[r], #44]\n\t" "# A[5] * A[7]\n\t" "ldr r10, [%[a], #28]\n\t" @@ -997,16 +959,16 @@ static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r2, r2, r8\n\t" "adcs r3, r3, r9\n\t" - "adc r4, r14, r14\n\t" + "adc r4, r12, r12\n\t" "adds r2, r2, r8\n\t" "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" + "adc r4, r4, r12\n\t" "# A[6] * A[6]\n\t" "ldr r10, [%[a], #24]\n\t" "umull r8, r9, r10, r10\n\t" "adds r2, r2, r8\n\t" "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" + "adc r4, r4, r12\n\t" "str r2, [%[r], #48]\n\t" "# A[6] * A[7]\n\t" "ldr r10, [%[a], #28]\n\t" @@ -1014,10 +976,10 @@ static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r14, r14\n\t" + "adc r2, r12, r12\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" + "adc r2, r2, r12\n\t" "str r3, [%[r], #52]\n\t" "# A[7] * A[7]\n\t" "ldr r10, [%[a], #28]\n\t" @@ -1026,26 +988,14 @@ static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a) "adc r2, r2, r9\n\t" "str r4, [%[r], #56]\n\t" "str r2, [%[r], #60]\n\t" - "ldr r2, [sp, #0]\n\t" - "ldr r3, [sp, #4]\n\t" - "ldr r4, [sp, #8]\n\t" - "ldr r8, [sp, #12]\n\t" - "str r2, [%[r], #0]\n\t" - "str r3, [%[r], #4]\n\t" - "str r4, [%[r], #8]\n\t" - "str r8, [%[r], #12]\n\t" - "ldr r2, [sp, #16]\n\t" - "ldr r3, [sp, #20]\n\t" - "ldr r4, [sp, #24]\n\t" - "ldr r8, [sp, #28]\n\t" - "str r2, [%[r], #16]\n\t" - "str r3, [%[r], #20]\n\t" - "str r4, [%[r], #24]\n\t" - "str r8, [%[r], #28]\n\t" - "add sp, sp, #32\n\t" + "ldm sp!, {r2, r3, r4, r8}\n\t" + "stm %[r]!, {r2, r3, r4, r8}\n\t" + "ldm sp!, {r2, r3, r4, r8}\n\t" + "stm %[r]!, {r2, r3, r4, r8}\n\t" + "sub %[r], %[r], #32\n\t" : : [r] "r" (r), [a] "r" (a) - : "memory", "r2", "r3", "r4", "r8", "r9", "r10", "r8", "r5", "r6", "r7", "r14" + : "memory", "r2", "r3", "r4", "r8", "r9", "r10", "r8", "r5", "r6", "r7", "r12" ); } @@ -1312,7 +1262,9 @@ SP_NOINLINE static void sp_2048_mul_16(sp_digit* r, const sp_digit* a, sp_digit a1[8]; sp_digit b1[8]; sp_digit z2[16]; - sp_digit u, ca, cb; + sp_digit u; + sp_digit ca; + sp_digit cb; ca = sp_2048_add_8(a1, a, &a[8]); cb = sp_2048_add_8(b1, b, &b[8]); @@ -1699,7 +1651,9 @@ SP_NOINLINE static void sp_2048_mul_32(sp_digit* r, const sp_digit* a, sp_digit a1[16]; sp_digit b1[16]; sp_digit z2[32]; - sp_digit u, ca, cb; + sp_digit u; + sp_digit ca; + sp_digit cb; ca = sp_2048_add_16(a1, a, &a[16]); cb = sp_2048_add_16(b1, b, &b[16]); @@ -2342,7 +2296,9 @@ SP_NOINLINE static void sp_2048_mul_64(sp_digit* r, const sp_digit* a, sp_digit a1[32]; sp_digit b1[32]; sp_digit z2[64]; - sp_digit u, ca, cb; + sp_digit u; + sp_digit ca; + sp_digit cb; ca = sp_2048_add_32(a1, a, &a[32]); cb = sp_2048_add_32(b1, b, &b[32]); @@ -2857,7 +2813,7 @@ static void sp_2048_sqr_32(sp_digit* r, const sp_digit* a) } #endif /* WOLFSSL_SP_SMALL */ -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ /* Caclulate the bottom digit of -1/a mod 2^n. * @@ -2866,7 +2822,8 @@ static void sp_2048_sqr_32(sp_digit* r, const sp_digit* a) */ static void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho) { - sp_digit x, b; + sp_digit x; + sp_digit b; b = a[0]; x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ @@ -2875,7 +2832,7 @@ static void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho) x *= 2 - b * x; /* here x*a==1 mod 2**32 */ /* rho = -1/m mod b */ - *rho = -x; + *rho = (sp_digit)0 - x; } /* Mul a by digit b into r. (r = a * b) @@ -2925,499 +2882,437 @@ static void sp_2048_mul_d_64(sp_digit* r, const sp_digit* a, "str r3, [%[r]]\n\t" "# A[1] * B\n\t" "ldr r8, [%[a], #4]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #4]\n\t" "# A[2] * B\n\t" "ldr r8, [%[a], #8]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #8]\n\t" "# A[3] * B\n\t" "ldr r8, [%[a], #12]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #12]\n\t" "# A[4] * B\n\t" "ldr r8, [%[a], #16]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #16]\n\t" "# A[5] * B\n\t" "ldr r8, [%[a], #20]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #20]\n\t" "# A[6] * B\n\t" "ldr r8, [%[a], #24]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #24]\n\t" "# A[7] * B\n\t" "ldr r8, [%[a], #28]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #28]\n\t" "# A[8] * B\n\t" "ldr r8, [%[a], #32]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #32]\n\t" "# A[9] * B\n\t" "ldr r8, [%[a], #36]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #36]\n\t" "# A[10] * B\n\t" "ldr r8, [%[a], #40]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #40]\n\t" "# A[11] * B\n\t" "ldr r8, [%[a], #44]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #44]\n\t" "# A[12] * B\n\t" "ldr r8, [%[a], #48]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #48]\n\t" "# A[13] * B\n\t" "ldr r8, [%[a], #52]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #52]\n\t" "# A[14] * B\n\t" "ldr r8, [%[a], #56]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #56]\n\t" "# A[15] * B\n\t" "ldr r8, [%[a], #60]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #60]\n\t" "# A[16] * B\n\t" "ldr r8, [%[a], #64]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #64]\n\t" "# A[17] * B\n\t" "ldr r8, [%[a], #68]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #68]\n\t" "# A[18] * B\n\t" "ldr r8, [%[a], #72]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #72]\n\t" "# A[19] * B\n\t" "ldr r8, [%[a], #76]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #76]\n\t" "# A[20] * B\n\t" "ldr r8, [%[a], #80]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #80]\n\t" "# A[21] * B\n\t" "ldr r8, [%[a], #84]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #84]\n\t" "# A[22] * B\n\t" "ldr r8, [%[a], #88]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #88]\n\t" "# A[23] * B\n\t" "ldr r8, [%[a], #92]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #92]\n\t" "# A[24] * B\n\t" "ldr r8, [%[a], #96]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #96]\n\t" "# A[25] * B\n\t" "ldr r8, [%[a], #100]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #100]\n\t" "# A[26] * B\n\t" "ldr r8, [%[a], #104]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #104]\n\t" "# A[27] * B\n\t" "ldr r8, [%[a], #108]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #108]\n\t" "# A[28] * B\n\t" "ldr r8, [%[a], #112]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #112]\n\t" "# A[29] * B\n\t" "ldr r8, [%[a], #116]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #116]\n\t" "# A[30] * B\n\t" "ldr r8, [%[a], #120]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #120]\n\t" "# A[31] * B\n\t" "ldr r8, [%[a], #124]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #124]\n\t" "# A[32] * B\n\t" "ldr r8, [%[a], #128]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #128]\n\t" "# A[33] * B\n\t" "ldr r8, [%[a], #132]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #132]\n\t" "# A[34] * B\n\t" "ldr r8, [%[a], #136]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #136]\n\t" "# A[35] * B\n\t" "ldr r8, [%[a], #140]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #140]\n\t" "# A[36] * B\n\t" "ldr r8, [%[a], #144]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #144]\n\t" "# A[37] * B\n\t" "ldr r8, [%[a], #148]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #148]\n\t" "# A[38] * B\n\t" "ldr r8, [%[a], #152]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #152]\n\t" "# A[39] * B\n\t" "ldr r8, [%[a], #156]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #156]\n\t" "# A[40] * B\n\t" "ldr r8, [%[a], #160]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #160]\n\t" "# A[41] * B\n\t" "ldr r8, [%[a], #164]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #164]\n\t" "# A[42] * B\n\t" "ldr r8, [%[a], #168]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #168]\n\t" "# A[43] * B\n\t" "ldr r8, [%[a], #172]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #172]\n\t" "# A[44] * B\n\t" "ldr r8, [%[a], #176]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #176]\n\t" "# A[45] * B\n\t" "ldr r8, [%[a], #180]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #180]\n\t" "# A[46] * B\n\t" "ldr r8, [%[a], #184]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #184]\n\t" "# A[47] * B\n\t" "ldr r8, [%[a], #188]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #188]\n\t" "# A[48] * B\n\t" "ldr r8, [%[a], #192]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #192]\n\t" "# A[49] * B\n\t" "ldr r8, [%[a], #196]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #196]\n\t" "# A[50] * B\n\t" "ldr r8, [%[a], #200]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #200]\n\t" "# A[51] * B\n\t" "ldr r8, [%[a], #204]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #204]\n\t" "# A[52] * B\n\t" "ldr r8, [%[a], #208]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #208]\n\t" "# A[53] * B\n\t" "ldr r8, [%[a], #212]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #212]\n\t" "# A[54] * B\n\t" "ldr r8, [%[a], #216]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #216]\n\t" "# A[55] * B\n\t" "ldr r8, [%[a], #220]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #220]\n\t" "# A[56] * B\n\t" "ldr r8, [%[a], #224]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #224]\n\t" "# A[57] * B\n\t" "ldr r8, [%[a], #228]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #228]\n\t" "# A[58] * B\n\t" "ldr r8, [%[a], #232]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #232]\n\t" "# A[59] * B\n\t" "ldr r8, [%[a], #236]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #236]\n\t" "# A[60] * B\n\t" "ldr r8, [%[a], #240]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #240]\n\t" "# A[61] * B\n\t" "ldr r8, [%[a], #244]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #244]\n\t" "# A[62] * B\n\t" "ldr r8, [%[a], #248]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #248]\n\t" "# A[63] * B\n\t" "ldr r8, [%[a], #252]\n\t" @@ -3666,6 +3561,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, sp_digit ca = 0; __asm__ __volatile__ ( + "ldr r11, [%[m], #0]\n\t" "# i = 0\n\t" "mov r12, #0\n\t" "ldr r10, [%[a], #0]\n\t" @@ -3674,13 +3570,12 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "# mu = a[i] * mp\n\t" "mul r8, %[mp], r10\n\t" "# a[i+0] += m[0] * mu\n\t" - "ldr r7, [%[m], #0]\n\t" "ldr r9, [%[a], #0]\n\t" - "umull r6, r7, r8, r7\n\t" + "umull r6, r7, r8, r11\n\t" "adds r10, r10, r6\n\t" "adc r5, r7, #0\n\t" "# a[i+1] += m[1] * mu\n\t" - "ldr r7, [%[m], #4]\n\t" + "ldr r7, [%[m], #4]\n\t" "ldr r9, [%[a], #4]\n\t" "umull r6, r7, r8, r7\n\t" "adds r10, r14, r6\n\t" @@ -3688,7 +3583,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "adds r10, r10, r5\n\t" "adc r4, r4, #0\n\t" "# a[i+2] += m[2] * mu\n\t" - "ldr r7, [%[m], #8]\n\t" + "ldr r7, [%[m], #8]\n\t" "ldr r14, [%[a], #8]\n\t" "umull r6, r7, r8, r7\n\t" "adds r14, r14, r6\n\t" @@ -3696,7 +3591,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "adds r14, r14, r4\n\t" "adc r5, r5, #0\n\t" "# a[i+3] += m[3] * mu\n\t" - "ldr r7, [%[m], #12]\n\t" + "ldr r7, [%[m], #12]\n\t" "ldr r9, [%[a], #12]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3705,7 +3600,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #12]\n\t" "adc r4, r4, #0\n\t" "# a[i+4] += m[4] * mu\n\t" - "ldr r7, [%[m], #16]\n\t" + "ldr r7, [%[m], #16]\n\t" "ldr r9, [%[a], #16]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3714,7 +3609,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #16]\n\t" "adc r5, r5, #0\n\t" "# a[i+5] += m[5] * mu\n\t" - "ldr r7, [%[m], #20]\n\t" + "ldr r7, [%[m], #20]\n\t" "ldr r9, [%[a], #20]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3723,7 +3618,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #20]\n\t" "adc r4, r4, #0\n\t" "# a[i+6] += m[6] * mu\n\t" - "ldr r7, [%[m], #24]\n\t" + "ldr r7, [%[m], #24]\n\t" "ldr r9, [%[a], #24]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3732,7 +3627,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #24]\n\t" "adc r5, r5, #0\n\t" "# a[i+7] += m[7] * mu\n\t" - "ldr r7, [%[m], #28]\n\t" + "ldr r7, [%[m], #28]\n\t" "ldr r9, [%[a], #28]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3741,7 +3636,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #28]\n\t" "adc r4, r4, #0\n\t" "# a[i+8] += m[8] * mu\n\t" - "ldr r7, [%[m], #32]\n\t" + "ldr r7, [%[m], #32]\n\t" "ldr r9, [%[a], #32]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3750,7 +3645,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #32]\n\t" "adc r5, r5, #0\n\t" "# a[i+9] += m[9] * mu\n\t" - "ldr r7, [%[m], #36]\n\t" + "ldr r7, [%[m], #36]\n\t" "ldr r9, [%[a], #36]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3759,7 +3654,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #36]\n\t" "adc r4, r4, #0\n\t" "# a[i+10] += m[10] * mu\n\t" - "ldr r7, [%[m], #40]\n\t" + "ldr r7, [%[m], #40]\n\t" "ldr r9, [%[a], #40]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3768,7 +3663,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #40]\n\t" "adc r5, r5, #0\n\t" "# a[i+11] += m[11] * mu\n\t" - "ldr r7, [%[m], #44]\n\t" + "ldr r7, [%[m], #44]\n\t" "ldr r9, [%[a], #44]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3777,7 +3672,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #44]\n\t" "adc r4, r4, #0\n\t" "# a[i+12] += m[12] * mu\n\t" - "ldr r7, [%[m], #48]\n\t" + "ldr r7, [%[m], #48]\n\t" "ldr r9, [%[a], #48]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3786,7 +3681,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #48]\n\t" "adc r5, r5, #0\n\t" "# a[i+13] += m[13] * mu\n\t" - "ldr r7, [%[m], #52]\n\t" + "ldr r7, [%[m], #52]\n\t" "ldr r9, [%[a], #52]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3795,7 +3690,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #52]\n\t" "adc r4, r4, #0\n\t" "# a[i+14] += m[14] * mu\n\t" - "ldr r7, [%[m], #56]\n\t" + "ldr r7, [%[m], #56]\n\t" "ldr r9, [%[a], #56]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3804,7 +3699,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #56]\n\t" "adc r5, r5, #0\n\t" "# a[i+15] += m[15] * mu\n\t" - "ldr r7, [%[m], #60]\n\t" + "ldr r7, [%[m], #60]\n\t" "ldr r9, [%[a], #60]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3813,7 +3708,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #60]\n\t" "adc r4, r4, #0\n\t" "# a[i+16] += m[16] * mu\n\t" - "ldr r7, [%[m], #64]\n\t" + "ldr r7, [%[m], #64]\n\t" "ldr r9, [%[a], #64]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3822,7 +3717,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #64]\n\t" "adc r5, r5, #0\n\t" "# a[i+17] += m[17] * mu\n\t" - "ldr r7, [%[m], #68]\n\t" + "ldr r7, [%[m], #68]\n\t" "ldr r9, [%[a], #68]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3831,7 +3726,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #68]\n\t" "adc r4, r4, #0\n\t" "# a[i+18] += m[18] * mu\n\t" - "ldr r7, [%[m], #72]\n\t" + "ldr r7, [%[m], #72]\n\t" "ldr r9, [%[a], #72]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3840,7 +3735,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #72]\n\t" "adc r5, r5, #0\n\t" "# a[i+19] += m[19] * mu\n\t" - "ldr r7, [%[m], #76]\n\t" + "ldr r7, [%[m], #76]\n\t" "ldr r9, [%[a], #76]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3849,7 +3744,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #76]\n\t" "adc r4, r4, #0\n\t" "# a[i+20] += m[20] * mu\n\t" - "ldr r7, [%[m], #80]\n\t" + "ldr r7, [%[m], #80]\n\t" "ldr r9, [%[a], #80]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3858,7 +3753,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #80]\n\t" "adc r5, r5, #0\n\t" "# a[i+21] += m[21] * mu\n\t" - "ldr r7, [%[m], #84]\n\t" + "ldr r7, [%[m], #84]\n\t" "ldr r9, [%[a], #84]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3867,7 +3762,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #84]\n\t" "adc r4, r4, #0\n\t" "# a[i+22] += m[22] * mu\n\t" - "ldr r7, [%[m], #88]\n\t" + "ldr r7, [%[m], #88]\n\t" "ldr r9, [%[a], #88]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3876,7 +3771,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #88]\n\t" "adc r5, r5, #0\n\t" "# a[i+23] += m[23] * mu\n\t" - "ldr r7, [%[m], #92]\n\t" + "ldr r7, [%[m], #92]\n\t" "ldr r9, [%[a], #92]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3885,7 +3780,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #92]\n\t" "adc r4, r4, #0\n\t" "# a[i+24] += m[24] * mu\n\t" - "ldr r7, [%[m], #96]\n\t" + "ldr r7, [%[m], #96]\n\t" "ldr r9, [%[a], #96]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3894,7 +3789,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #96]\n\t" "adc r5, r5, #0\n\t" "# a[i+25] += m[25] * mu\n\t" - "ldr r7, [%[m], #100]\n\t" + "ldr r7, [%[m], #100]\n\t" "ldr r9, [%[a], #100]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3903,7 +3798,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #100]\n\t" "adc r4, r4, #0\n\t" "# a[i+26] += m[26] * mu\n\t" - "ldr r7, [%[m], #104]\n\t" + "ldr r7, [%[m], #104]\n\t" "ldr r9, [%[a], #104]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3912,7 +3807,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #104]\n\t" "adc r5, r5, #0\n\t" "# a[i+27] += m[27] * mu\n\t" - "ldr r7, [%[m], #108]\n\t" + "ldr r7, [%[m], #108]\n\t" "ldr r9, [%[a], #108]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3921,7 +3816,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #108]\n\t" "adc r4, r4, #0\n\t" "# a[i+28] += m[28] * mu\n\t" - "ldr r7, [%[m], #112]\n\t" + "ldr r7, [%[m], #112]\n\t" "ldr r9, [%[a], #112]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3930,7 +3825,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #112]\n\t" "adc r5, r5, #0\n\t" "# a[i+29] += m[29] * mu\n\t" - "ldr r7, [%[m], #116]\n\t" + "ldr r7, [%[m], #116]\n\t" "ldr r9, [%[a], #116]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3939,7 +3834,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r9, [%[a], #116]\n\t" "adc r4, r4, #0\n\t" "# a[i+30] += m[30] * mu\n\t" - "ldr r7, [%[m], #120]\n\t" + "ldr r7, [%[m], #120]\n\t" "ldr r9, [%[a], #120]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -3970,7 +3865,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "str r14, [%[a], #4]\n\t" : [ca] "+r" (ca), [a] "+r" (a) : [m] "r" (m), [mp] "r" (mp) - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12", "r11" ); sp_2048_cond_sub_32(a - 32, a, m, (sp_digit)0 - ca); @@ -3985,8 +3880,8 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_2048_mont_mul_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_2048_mul_32(r, a, b); sp_2048_mont_reduce_32(r, m, mp); @@ -3999,8 +3894,8 @@ static void sp_2048_mont_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_sqr_32(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_2048_mont_sqr_32(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_2048_sqr_32(r, a); sp_2048_mont_reduce_32(r, m, mp); @@ -4053,243 +3948,213 @@ static void sp_2048_mul_d_32(sp_digit* r, const sp_digit* a, "str r3, [%[r]]\n\t" "# A[1] * B\n\t" "ldr r8, [%[a], #4]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #4]\n\t" "# A[2] * B\n\t" "ldr r8, [%[a], #8]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #8]\n\t" "# A[3] * B\n\t" "ldr r8, [%[a], #12]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #12]\n\t" "# A[4] * B\n\t" "ldr r8, [%[a], #16]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #16]\n\t" "# A[5] * B\n\t" "ldr r8, [%[a], #20]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #20]\n\t" "# A[6] * B\n\t" "ldr r8, [%[a], #24]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #24]\n\t" "# A[7] * B\n\t" "ldr r8, [%[a], #28]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #28]\n\t" "# A[8] * B\n\t" "ldr r8, [%[a], #32]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #32]\n\t" "# A[9] * B\n\t" "ldr r8, [%[a], #36]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #36]\n\t" "# A[10] * B\n\t" "ldr r8, [%[a], #40]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #40]\n\t" "# A[11] * B\n\t" "ldr r8, [%[a], #44]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #44]\n\t" "# A[12] * B\n\t" "ldr r8, [%[a], #48]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #48]\n\t" "# A[13] * B\n\t" "ldr r8, [%[a], #52]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #52]\n\t" "# A[14] * B\n\t" "ldr r8, [%[a], #56]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #56]\n\t" "# A[15] * B\n\t" "ldr r8, [%[a], #60]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #60]\n\t" "# A[16] * B\n\t" "ldr r8, [%[a], #64]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #64]\n\t" "# A[17] * B\n\t" "ldr r8, [%[a], #68]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #68]\n\t" "# A[18] * B\n\t" "ldr r8, [%[a], #72]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #72]\n\t" "# A[19] * B\n\t" "ldr r8, [%[a], #76]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #76]\n\t" "# A[20] * B\n\t" "ldr r8, [%[a], #80]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #80]\n\t" "# A[21] * B\n\t" "ldr r8, [%[a], #84]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #84]\n\t" "# A[22] * B\n\t" "ldr r8, [%[a], #88]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #88]\n\t" "# A[23] * B\n\t" "ldr r8, [%[a], #92]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #92]\n\t" "# A[24] * B\n\t" "ldr r8, [%[a], #96]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #96]\n\t" "# A[25] * B\n\t" "ldr r8, [%[a], #100]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #100]\n\t" "# A[26] * B\n\t" "ldr r8, [%[a], #104]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #104]\n\t" "# A[27] * B\n\t" "ldr r8, [%[a], #108]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #108]\n\t" "# A[28] * B\n\t" "ldr r8, [%[a], #112]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #112]\n\t" "# A[29] * B\n\t" "ldr r8, [%[a], #116]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #116]\n\t" "# A[30] * B\n\t" "ldr r8, [%[a], #120]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #120]\n\t" "# A[31] * B\n\t" "ldr r8, [%[a], #124]\n\t" @@ -4846,7 +4711,8 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -4912,34 +4778,34 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 32); for (; i>=0 || c>=4; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 28); + y = (byte)(n >> 28); n <<= 4; c = 28; } else if (c < 4) { - y = (int)(n >> 28); + y = (byte)(n >> 28); n = e[i--]; c = 4 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 28) & 0xf); + y = (byte)((n >> 28) & 0xf); n <<= 4; c -= 4; } @@ -4991,7 +4857,8 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -5073,34 +4940,34 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 32); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -5131,7 +4998,7 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, } #endif /* WOLFSSL_SP_SMALL */ -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) /* r = 2^n mod m where n is the number of bits to reduce by. @@ -5148,7 +5015,7 @@ static void sp_2048_mont_norm_64(sp_digit* r, const sp_digit* m) sp_2048_sub_in_place_64(r, m); } -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */ /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -5527,6 +5394,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, sp_digit ca = 0; __asm__ __volatile__ ( + "ldr r11, [%[m], #0]\n\t" "# i = 0\n\t" "mov r12, #0\n\t" "ldr r10, [%[a], #0]\n\t" @@ -5535,13 +5403,12 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "# mu = a[i] * mp\n\t" "mul r8, %[mp], r10\n\t" "# a[i+0] += m[0] * mu\n\t" - "ldr r7, [%[m], #0]\n\t" "ldr r9, [%[a], #0]\n\t" - "umull r6, r7, r8, r7\n\t" + "umull r6, r7, r8, r11\n\t" "adds r10, r10, r6\n\t" "adc r5, r7, #0\n\t" "# a[i+1] += m[1] * mu\n\t" - "ldr r7, [%[m], #4]\n\t" + "ldr r7, [%[m], #4]\n\t" "ldr r9, [%[a], #4]\n\t" "umull r6, r7, r8, r7\n\t" "adds r10, r14, r6\n\t" @@ -5549,7 +5416,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "adds r10, r10, r5\n\t" "adc r4, r4, #0\n\t" "# a[i+2] += m[2] * mu\n\t" - "ldr r7, [%[m], #8]\n\t" + "ldr r7, [%[m], #8]\n\t" "ldr r14, [%[a], #8]\n\t" "umull r6, r7, r8, r7\n\t" "adds r14, r14, r6\n\t" @@ -5557,7 +5424,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "adds r14, r14, r4\n\t" "adc r5, r5, #0\n\t" "# a[i+3] += m[3] * mu\n\t" - "ldr r7, [%[m], #12]\n\t" + "ldr r7, [%[m], #12]\n\t" "ldr r9, [%[a], #12]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5566,7 +5433,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #12]\n\t" "adc r4, r4, #0\n\t" "# a[i+4] += m[4] * mu\n\t" - "ldr r7, [%[m], #16]\n\t" + "ldr r7, [%[m], #16]\n\t" "ldr r9, [%[a], #16]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5575,7 +5442,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #16]\n\t" "adc r5, r5, #0\n\t" "# a[i+5] += m[5] * mu\n\t" - "ldr r7, [%[m], #20]\n\t" + "ldr r7, [%[m], #20]\n\t" "ldr r9, [%[a], #20]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5584,7 +5451,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #20]\n\t" "adc r4, r4, #0\n\t" "# a[i+6] += m[6] * mu\n\t" - "ldr r7, [%[m], #24]\n\t" + "ldr r7, [%[m], #24]\n\t" "ldr r9, [%[a], #24]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5593,7 +5460,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #24]\n\t" "adc r5, r5, #0\n\t" "# a[i+7] += m[7] * mu\n\t" - "ldr r7, [%[m], #28]\n\t" + "ldr r7, [%[m], #28]\n\t" "ldr r9, [%[a], #28]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5602,7 +5469,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #28]\n\t" "adc r4, r4, #0\n\t" "# a[i+8] += m[8] * mu\n\t" - "ldr r7, [%[m], #32]\n\t" + "ldr r7, [%[m], #32]\n\t" "ldr r9, [%[a], #32]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5611,7 +5478,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #32]\n\t" "adc r5, r5, #0\n\t" "# a[i+9] += m[9] * mu\n\t" - "ldr r7, [%[m], #36]\n\t" + "ldr r7, [%[m], #36]\n\t" "ldr r9, [%[a], #36]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5620,7 +5487,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #36]\n\t" "adc r4, r4, #0\n\t" "# a[i+10] += m[10] * mu\n\t" - "ldr r7, [%[m], #40]\n\t" + "ldr r7, [%[m], #40]\n\t" "ldr r9, [%[a], #40]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5629,7 +5496,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #40]\n\t" "adc r5, r5, #0\n\t" "# a[i+11] += m[11] * mu\n\t" - "ldr r7, [%[m], #44]\n\t" + "ldr r7, [%[m], #44]\n\t" "ldr r9, [%[a], #44]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5638,7 +5505,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #44]\n\t" "adc r4, r4, #0\n\t" "# a[i+12] += m[12] * mu\n\t" - "ldr r7, [%[m], #48]\n\t" + "ldr r7, [%[m], #48]\n\t" "ldr r9, [%[a], #48]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5647,7 +5514,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #48]\n\t" "adc r5, r5, #0\n\t" "# a[i+13] += m[13] * mu\n\t" - "ldr r7, [%[m], #52]\n\t" + "ldr r7, [%[m], #52]\n\t" "ldr r9, [%[a], #52]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5656,7 +5523,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #52]\n\t" "adc r4, r4, #0\n\t" "# a[i+14] += m[14] * mu\n\t" - "ldr r7, [%[m], #56]\n\t" + "ldr r7, [%[m], #56]\n\t" "ldr r9, [%[a], #56]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5665,7 +5532,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #56]\n\t" "adc r5, r5, #0\n\t" "# a[i+15] += m[15] * mu\n\t" - "ldr r7, [%[m], #60]\n\t" + "ldr r7, [%[m], #60]\n\t" "ldr r9, [%[a], #60]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5674,7 +5541,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #60]\n\t" "adc r4, r4, #0\n\t" "# a[i+16] += m[16] * mu\n\t" - "ldr r7, [%[m], #64]\n\t" + "ldr r7, [%[m], #64]\n\t" "ldr r9, [%[a], #64]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5683,7 +5550,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #64]\n\t" "adc r5, r5, #0\n\t" "# a[i+17] += m[17] * mu\n\t" - "ldr r7, [%[m], #68]\n\t" + "ldr r7, [%[m], #68]\n\t" "ldr r9, [%[a], #68]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5692,7 +5559,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #68]\n\t" "adc r4, r4, #0\n\t" "# a[i+18] += m[18] * mu\n\t" - "ldr r7, [%[m], #72]\n\t" + "ldr r7, [%[m], #72]\n\t" "ldr r9, [%[a], #72]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5701,7 +5568,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #72]\n\t" "adc r5, r5, #0\n\t" "# a[i+19] += m[19] * mu\n\t" - "ldr r7, [%[m], #76]\n\t" + "ldr r7, [%[m], #76]\n\t" "ldr r9, [%[a], #76]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5710,7 +5577,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #76]\n\t" "adc r4, r4, #0\n\t" "# a[i+20] += m[20] * mu\n\t" - "ldr r7, [%[m], #80]\n\t" + "ldr r7, [%[m], #80]\n\t" "ldr r9, [%[a], #80]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5719,7 +5586,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #80]\n\t" "adc r5, r5, #0\n\t" "# a[i+21] += m[21] * mu\n\t" - "ldr r7, [%[m], #84]\n\t" + "ldr r7, [%[m], #84]\n\t" "ldr r9, [%[a], #84]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5728,7 +5595,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #84]\n\t" "adc r4, r4, #0\n\t" "# a[i+22] += m[22] * mu\n\t" - "ldr r7, [%[m], #88]\n\t" + "ldr r7, [%[m], #88]\n\t" "ldr r9, [%[a], #88]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5737,7 +5604,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #88]\n\t" "adc r5, r5, #0\n\t" "# a[i+23] += m[23] * mu\n\t" - "ldr r7, [%[m], #92]\n\t" + "ldr r7, [%[m], #92]\n\t" "ldr r9, [%[a], #92]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5746,7 +5613,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #92]\n\t" "adc r4, r4, #0\n\t" "# a[i+24] += m[24] * mu\n\t" - "ldr r7, [%[m], #96]\n\t" + "ldr r7, [%[m], #96]\n\t" "ldr r9, [%[a], #96]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5755,7 +5622,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #96]\n\t" "adc r5, r5, #0\n\t" "# a[i+25] += m[25] * mu\n\t" - "ldr r7, [%[m], #100]\n\t" + "ldr r7, [%[m], #100]\n\t" "ldr r9, [%[a], #100]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5764,7 +5631,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #100]\n\t" "adc r4, r4, #0\n\t" "# a[i+26] += m[26] * mu\n\t" - "ldr r7, [%[m], #104]\n\t" + "ldr r7, [%[m], #104]\n\t" "ldr r9, [%[a], #104]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5773,7 +5640,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #104]\n\t" "adc r5, r5, #0\n\t" "# a[i+27] += m[27] * mu\n\t" - "ldr r7, [%[m], #108]\n\t" + "ldr r7, [%[m], #108]\n\t" "ldr r9, [%[a], #108]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5782,7 +5649,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #108]\n\t" "adc r4, r4, #0\n\t" "# a[i+28] += m[28] * mu\n\t" - "ldr r7, [%[m], #112]\n\t" + "ldr r7, [%[m], #112]\n\t" "ldr r9, [%[a], #112]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5791,7 +5658,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #112]\n\t" "adc r5, r5, #0\n\t" "# a[i+29] += m[29] * mu\n\t" - "ldr r7, [%[m], #116]\n\t" + "ldr r7, [%[m], #116]\n\t" "ldr r9, [%[a], #116]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5800,7 +5667,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #116]\n\t" "adc r4, r4, #0\n\t" "# a[i+30] += m[30] * mu\n\t" - "ldr r7, [%[m], #120]\n\t" + "ldr r7, [%[m], #120]\n\t" "ldr r9, [%[a], #120]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5809,7 +5676,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #120]\n\t" "adc r5, r5, #0\n\t" "# a[i+31] += m[31] * mu\n\t" - "ldr r7, [%[m], #124]\n\t" + "ldr r7, [%[m], #124]\n\t" "ldr r9, [%[a], #124]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5818,7 +5685,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #124]\n\t" "adc r4, r4, #0\n\t" "# a[i+32] += m[32] * mu\n\t" - "ldr r7, [%[m], #128]\n\t" + "ldr r7, [%[m], #128]\n\t" "ldr r9, [%[a], #128]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5827,7 +5694,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #128]\n\t" "adc r5, r5, #0\n\t" "# a[i+33] += m[33] * mu\n\t" - "ldr r7, [%[m], #132]\n\t" + "ldr r7, [%[m], #132]\n\t" "ldr r9, [%[a], #132]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5836,7 +5703,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #132]\n\t" "adc r4, r4, #0\n\t" "# a[i+34] += m[34] * mu\n\t" - "ldr r7, [%[m], #136]\n\t" + "ldr r7, [%[m], #136]\n\t" "ldr r9, [%[a], #136]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5845,7 +5712,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #136]\n\t" "adc r5, r5, #0\n\t" "# a[i+35] += m[35] * mu\n\t" - "ldr r7, [%[m], #140]\n\t" + "ldr r7, [%[m], #140]\n\t" "ldr r9, [%[a], #140]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5854,7 +5721,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #140]\n\t" "adc r4, r4, #0\n\t" "# a[i+36] += m[36] * mu\n\t" - "ldr r7, [%[m], #144]\n\t" + "ldr r7, [%[m], #144]\n\t" "ldr r9, [%[a], #144]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5863,7 +5730,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #144]\n\t" "adc r5, r5, #0\n\t" "# a[i+37] += m[37] * mu\n\t" - "ldr r7, [%[m], #148]\n\t" + "ldr r7, [%[m], #148]\n\t" "ldr r9, [%[a], #148]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5872,7 +5739,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #148]\n\t" "adc r4, r4, #0\n\t" "# a[i+38] += m[38] * mu\n\t" - "ldr r7, [%[m], #152]\n\t" + "ldr r7, [%[m], #152]\n\t" "ldr r9, [%[a], #152]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5881,7 +5748,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #152]\n\t" "adc r5, r5, #0\n\t" "# a[i+39] += m[39] * mu\n\t" - "ldr r7, [%[m], #156]\n\t" + "ldr r7, [%[m], #156]\n\t" "ldr r9, [%[a], #156]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5890,7 +5757,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #156]\n\t" "adc r4, r4, #0\n\t" "# a[i+40] += m[40] * mu\n\t" - "ldr r7, [%[m], #160]\n\t" + "ldr r7, [%[m], #160]\n\t" "ldr r9, [%[a], #160]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5899,7 +5766,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #160]\n\t" "adc r5, r5, #0\n\t" "# a[i+41] += m[41] * mu\n\t" - "ldr r7, [%[m], #164]\n\t" + "ldr r7, [%[m], #164]\n\t" "ldr r9, [%[a], #164]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5908,7 +5775,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #164]\n\t" "adc r4, r4, #0\n\t" "# a[i+42] += m[42] * mu\n\t" - "ldr r7, [%[m], #168]\n\t" + "ldr r7, [%[m], #168]\n\t" "ldr r9, [%[a], #168]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5917,7 +5784,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #168]\n\t" "adc r5, r5, #0\n\t" "# a[i+43] += m[43] * mu\n\t" - "ldr r7, [%[m], #172]\n\t" + "ldr r7, [%[m], #172]\n\t" "ldr r9, [%[a], #172]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5926,7 +5793,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #172]\n\t" "adc r4, r4, #0\n\t" "# a[i+44] += m[44] * mu\n\t" - "ldr r7, [%[m], #176]\n\t" + "ldr r7, [%[m], #176]\n\t" "ldr r9, [%[a], #176]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5935,7 +5802,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #176]\n\t" "adc r5, r5, #0\n\t" "# a[i+45] += m[45] * mu\n\t" - "ldr r7, [%[m], #180]\n\t" + "ldr r7, [%[m], #180]\n\t" "ldr r9, [%[a], #180]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5944,7 +5811,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #180]\n\t" "adc r4, r4, #0\n\t" "# a[i+46] += m[46] * mu\n\t" - "ldr r7, [%[m], #184]\n\t" + "ldr r7, [%[m], #184]\n\t" "ldr r9, [%[a], #184]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5953,7 +5820,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #184]\n\t" "adc r5, r5, #0\n\t" "# a[i+47] += m[47] * mu\n\t" - "ldr r7, [%[m], #188]\n\t" + "ldr r7, [%[m], #188]\n\t" "ldr r9, [%[a], #188]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5962,7 +5829,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #188]\n\t" "adc r4, r4, #0\n\t" "# a[i+48] += m[48] * mu\n\t" - "ldr r7, [%[m], #192]\n\t" + "ldr r7, [%[m], #192]\n\t" "ldr r9, [%[a], #192]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5971,7 +5838,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #192]\n\t" "adc r5, r5, #0\n\t" "# a[i+49] += m[49] * mu\n\t" - "ldr r7, [%[m], #196]\n\t" + "ldr r7, [%[m], #196]\n\t" "ldr r9, [%[a], #196]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5980,7 +5847,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #196]\n\t" "adc r4, r4, #0\n\t" "# a[i+50] += m[50] * mu\n\t" - "ldr r7, [%[m], #200]\n\t" + "ldr r7, [%[m], #200]\n\t" "ldr r9, [%[a], #200]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5989,7 +5856,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #200]\n\t" "adc r5, r5, #0\n\t" "# a[i+51] += m[51] * mu\n\t" - "ldr r7, [%[m], #204]\n\t" + "ldr r7, [%[m], #204]\n\t" "ldr r9, [%[a], #204]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -5998,7 +5865,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #204]\n\t" "adc r4, r4, #0\n\t" "# a[i+52] += m[52] * mu\n\t" - "ldr r7, [%[m], #208]\n\t" + "ldr r7, [%[m], #208]\n\t" "ldr r9, [%[a], #208]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -6007,7 +5874,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #208]\n\t" "adc r5, r5, #0\n\t" "# a[i+53] += m[53] * mu\n\t" - "ldr r7, [%[m], #212]\n\t" + "ldr r7, [%[m], #212]\n\t" "ldr r9, [%[a], #212]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -6016,7 +5883,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #212]\n\t" "adc r4, r4, #0\n\t" "# a[i+54] += m[54] * mu\n\t" - "ldr r7, [%[m], #216]\n\t" + "ldr r7, [%[m], #216]\n\t" "ldr r9, [%[a], #216]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -6025,7 +5892,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #216]\n\t" "adc r5, r5, #0\n\t" "# a[i+55] += m[55] * mu\n\t" - "ldr r7, [%[m], #220]\n\t" + "ldr r7, [%[m], #220]\n\t" "ldr r9, [%[a], #220]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -6034,7 +5901,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #220]\n\t" "adc r4, r4, #0\n\t" "# a[i+56] += m[56] * mu\n\t" - "ldr r7, [%[m], #224]\n\t" + "ldr r7, [%[m], #224]\n\t" "ldr r9, [%[a], #224]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -6043,7 +5910,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #224]\n\t" "adc r5, r5, #0\n\t" "# a[i+57] += m[57] * mu\n\t" - "ldr r7, [%[m], #228]\n\t" + "ldr r7, [%[m], #228]\n\t" "ldr r9, [%[a], #228]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -6052,7 +5919,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #228]\n\t" "adc r4, r4, #0\n\t" "# a[i+58] += m[58] * mu\n\t" - "ldr r7, [%[m], #232]\n\t" + "ldr r7, [%[m], #232]\n\t" "ldr r9, [%[a], #232]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -6061,7 +5928,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #232]\n\t" "adc r5, r5, #0\n\t" "# a[i+59] += m[59] * mu\n\t" - "ldr r7, [%[m], #236]\n\t" + "ldr r7, [%[m], #236]\n\t" "ldr r9, [%[a], #236]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -6070,7 +5937,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #236]\n\t" "adc r4, r4, #0\n\t" "# a[i+60] += m[60] * mu\n\t" - "ldr r7, [%[m], #240]\n\t" + "ldr r7, [%[m], #240]\n\t" "ldr r9, [%[a], #240]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -6079,7 +5946,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #240]\n\t" "adc r5, r5, #0\n\t" "# a[i+61] += m[61] * mu\n\t" - "ldr r7, [%[m], #244]\n\t" + "ldr r7, [%[m], #244]\n\t" "ldr r9, [%[a], #244]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -6088,7 +5955,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r9, [%[a], #244]\n\t" "adc r4, r4, #0\n\t" "# a[i+62] += m[62] * mu\n\t" - "ldr r7, [%[m], #248]\n\t" + "ldr r7, [%[m], #248]\n\t" "ldr r9, [%[a], #248]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -6119,7 +5986,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, "str r14, [%[a], #4]\n\t" : [ca] "+r" (ca), [a] "+r" (a) : [m] "r" (m), [mp] "r" (mp) - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12", "r11" ); sp_2048_cond_sub_64(a - 64, a, m, (sp_digit)0 - ca); @@ -6134,8 +6001,8 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_mul_64(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_2048_mont_mul_64(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_2048_mul_64(r, a, b); sp_2048_mont_reduce_64(r, m, mp); @@ -6148,8 +6015,8 @@ static void sp_2048_mont_mul_64(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_sqr_64(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_2048_mont_sqr_64(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_2048_sqr_64(r, a); sp_2048_mont_reduce_64(r, m, mp); @@ -7135,7 +7002,8 @@ static int sp_2048_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -7201,34 +7069,34 @@ static int sp_2048_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 64); for (; i>=0 || c>=4; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 28); + y = (byte)(n >> 28); n <<= 4; c = 28; } else if (c < 4) { - y = (int)(n >> 28); + y = (byte)(n >> 28); n = e[i--]; c = 4 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 28) & 0xf); + y = (byte)((n >> 28) & 0xf); n <<= 4; c -= 4; } @@ -7280,7 +7148,8 @@ static int sp_2048_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -7362,34 +7231,34 @@ static int sp_2048_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 64); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -7434,11 +7303,13 @@ static int sp_2048_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPublic_2048(const byte* in, word32 inLen, const mp_int* em, + const mp_int* mm, byte* out, word32* outLen) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_digit a[128], m[64], r[128]; + sp_digit a[128]; + sp_digit m[64]; + sp_digit r[128]; #else sp_digit* d = NULL; sp_digit* a = NULL; @@ -7781,9 +7652,9 @@ static sp_digit sp_2048_cond_add_32(sp_digit* r, const sp_digit* a, const sp_dig * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_2048(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM) sp_digit* a = NULL; @@ -7847,8 +7718,11 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, #else #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit a[64 * 2]; - sp_digit p[32], q[32], dp[32]; - sp_digit tmpa[64], tmpb[64]; + sp_digit p[32]; + sp_digit q[32]; + sp_digit dp[32]; + sp_digit tmpa[64]; + sp_digit tmpb[64]; #else sp_digit* t = NULL; sp_digit* a = NULL; @@ -7945,7 +7819,7 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, XMEMSET(q, 0, sizeof(q)); XMEMSET(dp, 0, sizeof(dp)); #endif -#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */ +#endif /* SP_RSA_PRIVATE_EXP_D | RSA_LOW_MEM */ return err; } #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -7968,17 +7842,19 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->used = 64; mp_clamp(r); #elif DIGIT_BIT < 32 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 64; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -7991,14 +7867,16 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 64; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 32 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -8025,10 +7903,13 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_2048(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[128], e[64], m[64]; + sp_digit b[128]; + sp_digit e[64]; + sp_digit m[64]; sp_digit* r = b; int expBits = mp_count_bits(exp); @@ -8479,10 +8360,12 @@ static int sp_2048_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits, sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -8517,34 +8400,34 @@ static int sp_2048_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } - sp_2048_lshift_64(r, norm, (byte)y); + sp_2048_lshift_64(r, norm, y); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -8555,7 +8438,7 @@ static int sp_2048_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits, sp_2048_mont_sqr_64(r, r, m, mp); sp_2048_mont_sqr_64(r, r, m, mp); - sp_2048_lshift_64(r, r, (byte)y); + sp_2048_lshift_64(r, r, y); sp_2048_mul_d_64(tmp, norm, r[64]); r[64] = 0; o = sp_2048_add_64(r, r, tmp); @@ -8591,11 +8474,13 @@ static int sp_2048_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, - mp_int* mod, byte* out, word32* outLen) +int sp_DhExp_2048(const mp_int* base, const byte* exp, word32 expLen, + const mp_int* mod, byte* out, word32* outLen) { int err = MP_OKAY; - sp_digit b[128], e[64], m[64]; + sp_digit b[128]; + sp_digit e[64]; + sp_digit m[64]; sp_digit* r = b; word32 i; @@ -8630,6 +8515,7 @@ int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, sp_2048_to_bin(r, out); *outLen = 256; for (i=0; i<256 && out[i] == 0; i++) { + /* Search for first non-zero. */ } *outLen -= i; XMEMMOVE(out, out + i, *outLen); @@ -8651,10 +8537,13 @@ int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_1024(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[64], e[32], m[32]; + sp_digit b[64]; + sp_digit e[32]; + sp_digit m[32]; sp_digit* r = b; int expBits = mp_count_bits(exp); @@ -8691,7 +8580,7 @@ int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) return err; } -#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */ +#endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */ #endif /* !WOLFSSL_SP_NO_2048 */ @@ -8705,7 +8594,8 @@ int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) */ static void sp_3072_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -8747,7 +8637,8 @@ static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 32 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -8781,7 +8672,9 @@ static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -8820,7 +8713,10 @@ static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a) */ static void sp_3072_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; j = 3072 / 8 - 1; a[j] = 0; @@ -8862,66 +8758,60 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "sub sp, sp, #48\n\t" "mov r10, #0\n\t" "# A[0] * B[0]\n\t" - "ldr r8, [%[a], #0]\n\t" - "ldr r9, [%[b], #0]\n\t" - "umull r3, r4, r8, r9\n\t" + "ldr r11, [%[a], #0]\n\t" + "ldr r12, [%[b], #0]\n\t" + "umull r3, r4, r11, r12\n\t" "mov r5, #0\n\t" "str r3, [sp]\n\t" "# A[0] * B[1]\n\t" - "ldr r8, [%[a], #0]\n\t" "ldr r9, [%[b], #4]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r10, r10\n\t" "# A[1] * B[0]\n\t" "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #0]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "str r4, [sp, #4]\n\t" + "# A[2] * B[0]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "# A[1] * B[1]\n\t" + "ldr r11, [%[a], #4]\n\t" + "ldr r12, [%[b], #4]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" "# A[0] * B[2]\n\t" "ldr r8, [%[a], #0]\n\t" "ldr r9, [%[b], #8]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r10, r10\n\t" - "# A[1] * B[1]\n\t" - "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #4]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[2] * B[0]\n\t" - "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #0]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "str r5, [sp, #8]\n\t" "# A[0] * B[3]\n\t" - "ldr r8, [%[a], #0]\n\t" "ldr r9, [%[b], #12]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r10, r10\n\t" "# A[1] * B[2]\n\t" - "ldr r8, [%[a], #4]\n\t" "ldr r9, [%[b], #8]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "# A[2] * B[1]\n\t" "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #4]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" @@ -8933,13 +8823,25 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "str r3, [sp, #12]\n\t" - "# A[0] * B[4]\n\t" - "ldr r8, [%[a], #0]\n\t" - "ldr r9, [%[b], #16]\n\t" + "# A[4] * B[0]\n\t" + "ldr r8, [%[a], #16]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r10, r10\n\t" + "# A[3] * B[1]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[2] * B[2]\n\t" + "ldr r11, [%[a], #8]\n\t" + "ldr r12, [%[b], #8]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" "# A[1] * B[3]\n\t" "ldr r8, [%[a], #4]\n\t" "ldr r9, [%[b], #12]\n\t" @@ -8947,30 +8849,15 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" - "# A[2] * B[2]\n\t" - "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #8]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[3] * B[1]\n\t" - "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #4]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[4] * B[0]\n\t" - "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #0]\n\t" + "# A[0] * B[4]\n\t" + "ldr r8, [%[a], #0]\n\t" + "ldr r9, [%[b], #16]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "str r4, [sp, #16]\n\t" "# A[0] * B[5]\n\t" - "ldr r8, [%[a], #0]\n\t" "ldr r9, [%[b], #20]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" @@ -8984,16 +8871,14 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "# A[2] * B[3]\n\t" - "ldr r8, [%[a], #8]\n\t" "ldr r9, [%[b], #12]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "# A[3] * B[2]\n\t" "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #8]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" @@ -9012,20 +8897,32 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "str r5, [sp, #20]\n\t" - "# A[0] * B[6]\n\t" - "ldr r8, [%[a], #0]\n\t" - "ldr r9, [%[b], #24]\n\t" + "# A[6] * B[0]\n\t" + "ldr r8, [%[a], #24]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r10, r10\n\t" - "# A[1] * B[5]\n\t" - "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #20]\n\t" + "# A[5] * B[1]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #4]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" + "# A[4] * B[2]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[3] * B[3]\n\t" + "ldr r11, [%[a], #12]\n\t" + "ldr r12, [%[b], #12]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" "# A[2] * B[4]\n\t" "ldr r8, [%[a], #8]\n\t" "ldr r9, [%[b], #16]\n\t" @@ -9033,37 +8930,22 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" - "# A[3] * B[3]\n\t" - "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #12]\n\t" + "# A[1] * B[5]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #20]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" - "# A[4] * B[2]\n\t" - "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #8]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[5] * B[1]\n\t" - "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #4]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[6] * B[0]\n\t" - "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #0]\n\t" + "# A[0] * B[6]\n\t" + "ldr r8, [%[a], #0]\n\t" + "ldr r9, [%[b], #24]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "str r3, [sp, #24]\n\t" "# A[0] * B[7]\n\t" - "ldr r8, [%[a], #0]\n\t" "ldr r9, [%[b], #28]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" @@ -9084,16 +8966,14 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "# A[3] * B[4]\n\t" - "ldr r8, [%[a], #12]\n\t" "ldr r9, [%[b], #16]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "# A[4] * B[3]\n\t" "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #12]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" @@ -9119,44 +8999,15 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "str r4, [sp, #28]\n\t" - "# A[0] * B[8]\n\t" - "ldr r8, [%[a], #0]\n\t" - "ldr r9, [%[b], #32]\n\t" + "# A[8] * B[0]\n\t" + "ldr r8, [%[a], #32]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r10, r10\n\t" - "# A[1] * B[7]\n\t" - "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #28]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[2] * B[6]\n\t" - "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #24]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[3] * B[5]\n\t" - "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #20]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[4] * B[4]\n\t" - "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #16]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[5] * B[3]\n\t" - "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #12]\n\t" + "# A[7] * B[1]\n\t" + "ldr r8, [%[a], #28]\n\t" + "ldr r9, [%[b], #4]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" @@ -9168,23 +9019,49 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" - "# A[7] * B[1]\n\t" - "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #4]\n\t" + "# A[5] * B[3]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[4] * B[4]\n\t" + "ldr r11, [%[a], #16]\n\t" + "ldr r12, [%[b], #16]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[3] * B[5]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #20]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" - "# A[8] * B[0]\n\t" - "ldr r8, [%[a], #32]\n\t" - "ldr r9, [%[b], #0]\n\t" + "# A[2] * B[6]\n\t" + "ldr r8, [%[a], #8]\n\t" + "ldr r9, [%[b], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[1] * B[7]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #28]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[0] * B[8]\n\t" + "ldr r8, [%[a], #0]\n\t" + "ldr r9, [%[b], #32]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "str r5, [sp, #32]\n\t" "# A[0] * B[9]\n\t" - "ldr r8, [%[a], #0]\n\t" "ldr r9, [%[b], #36]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" @@ -9212,16 +9089,14 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "# A[4] * B[5]\n\t" - "ldr r8, [%[a], #16]\n\t" "ldr r9, [%[b], #20]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "# A[5] * B[4]\n\t" "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #16]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" @@ -9254,58 +9129,15 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "str r3, [sp, #36]\n\t" - "# A[0] * B[10]\n\t" - "ldr r8, [%[a], #0]\n\t" - "ldr r9, [%[b], #40]\n\t" + "# A[10] * B[0]\n\t" + "ldr r8, [%[a], #40]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r10, r10\n\t" - "# A[1] * B[9]\n\t" - "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #36]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[2] * B[8]\n\t" - "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #32]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[3] * B[7]\n\t" - "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #28]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[4] * B[6]\n\t" - "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #24]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[5] * B[5]\n\t" - "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #20]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[6] * B[4]\n\t" - "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #16]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[7] * B[3]\n\t" - "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #12]\n\t" + "# A[9] * B[1]\n\t" + "ldr r8, [%[a], #36]\n\t" + "ldr r9, [%[b], #4]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" @@ -9317,23 +9149,63 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" - "# A[9] * B[1]\n\t" - "ldr r8, [%[a], #36]\n\t" - "ldr r9, [%[b], #4]\n\t" + "# A[7] * B[3]\n\t" + "ldr r8, [%[a], #28]\n\t" + "ldr r9, [%[b], #12]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" - "# A[10] * B[0]\n\t" - "ldr r8, [%[a], #40]\n\t" - "ldr r9, [%[b], #0]\n\t" + "# A[6] * B[4]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[5] * B[5]\n\t" + "ldr r11, [%[a], #20]\n\t" + "ldr r12, [%[b], #20]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[4] * B[6]\n\t" + "ldr r8, [%[a], #16]\n\t" + "ldr r9, [%[b], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[3] * B[7]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #28]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[2] * B[8]\n\t" + "ldr r8, [%[a], #8]\n\t" + "ldr r9, [%[b], #32]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[1] * B[9]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #36]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[0] * B[10]\n\t" + "ldr r8, [%[a], #0]\n\t" + "ldr r9, [%[b], #40]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "str r4, [sp, #40]\n\t" "# A[0] * B[11]\n\t" - "ldr r8, [%[a], #0]\n\t" "ldr r9, [%[b], #44]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" @@ -9368,16 +9240,14 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "# A[5] * B[6]\n\t" - "ldr r8, [%[a], #20]\n\t" "ldr r9, [%[b], #24]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "# A[6] * B[5]\n\t" "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #20]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" @@ -9417,58 +9287,15 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "str r5, [sp, #44]\n\t" - "# A[1] * B[11]\n\t" - "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #44]\n\t" + "# A[11] * B[1]\n\t" + "ldr r9, [%[b], #4]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r10, r10\n\t" - "# A[2] * B[10]\n\t" - "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #40]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[3] * B[9]\n\t" - "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #36]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[4] * B[8]\n\t" - "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #32]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[5] * B[7]\n\t" - "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #28]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[6] * B[6]\n\t" - "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #24]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[7] * B[5]\n\t" - "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #20]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[8] * B[4]\n\t" - "ldr r8, [%[a], #32]\n\t" - "ldr r9, [%[b], #16]\n\t" + "# A[10] * B[2]\n\t" + "ldr r8, [%[a], #40]\n\t" + "ldr r9, [%[b], #8]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" @@ -9480,16 +9307,57 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" - "# A[10] * B[2]\n\t" - "ldr r8, [%[a], #40]\n\t" - "ldr r9, [%[b], #8]\n\t" + "# A[8] * B[4]\n\t" + "ldr r8, [%[a], #32]\n\t" + "ldr r9, [%[b], #16]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" - "# A[11] * B[1]\n\t" - "ldr r8, [%[a], #44]\n\t" - "ldr r9, [%[b], #4]\n\t" + "# A[7] * B[5]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[6] * B[6]\n\t" + "ldr r11, [%[a], #24]\n\t" + "ldr r12, [%[b], #24]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[5] * B[7]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #28]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[4] * B[8]\n\t" + "ldr r8, [%[a], #16]\n\t" + "ldr r9, [%[b], #32]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[3] * B[9]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #36]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[2] * B[10]\n\t" + "ldr r8, [%[a], #8]\n\t" + "ldr r9, [%[b], #40]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[1] * B[11]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #44]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" @@ -9497,7 +9365,6 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "str r3, [%[r], #48]\n\t" "# A[2] * B[11]\n\t" "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #44]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" @@ -9524,16 +9391,14 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "# A[6] * B[7]\n\t" - "ldr r8, [%[a], #24]\n\t" "ldr r9, [%[b], #28]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "# A[7] * B[6]\n\t" "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #24]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" @@ -9566,44 +9431,15 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "str r4, [%[r], #52]\n\t" - "# A[3] * B[11]\n\t" - "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #44]\n\t" + "# A[11] * B[3]\n\t" + "ldr r9, [%[b], #12]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r10, r10\n\t" - "# A[4] * B[10]\n\t" - "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #40]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[5] * B[9]\n\t" - "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #36]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[6] * B[8]\n\t" - "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #32]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[7] * B[7]\n\t" - "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #28]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[8] * B[6]\n\t" - "ldr r8, [%[a], #32]\n\t" - "ldr r9, [%[b], #24]\n\t" + "# A[10] * B[4]\n\t" + "ldr r8, [%[a], #40]\n\t" + "ldr r9, [%[b], #16]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" @@ -9615,16 +9451,43 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" - "# A[10] * B[4]\n\t" - "ldr r8, [%[a], #40]\n\t" - "ldr r9, [%[b], #16]\n\t" + "# A[8] * B[6]\n\t" + "ldr r8, [%[a], #32]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[7] * B[7]\n\t" + "ldr r11, [%[a], #28]\n\t" + "ldr r12, [%[b], #28]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[6] * B[8]\n\t" + "ldr r8, [%[a], #24]\n\t" + "ldr r9, [%[b], #32]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" - "# A[11] * B[3]\n\t" - "ldr r8, [%[a], #44]\n\t" - "ldr r9, [%[b], #12]\n\t" + "# A[5] * B[9]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #36]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[4] * B[10]\n\t" + "ldr r8, [%[a], #16]\n\t" + "ldr r9, [%[b], #40]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[3] * B[11]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #44]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" @@ -9632,7 +9495,6 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "str r5, [%[r], #56]\n\t" "# A[4] * B[11]\n\t" "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #44]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" @@ -9652,16 +9514,14 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "# A[7] * B[8]\n\t" - "ldr r8, [%[a], #28]\n\t" "ldr r9, [%[b], #32]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "# A[8] * B[7]\n\t" "ldr r8, [%[a], #32]\n\t" - "ldr r9, [%[b], #28]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" @@ -9687,20 +9547,32 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "str r3, [%[r], #60]\n\t" - "# A[5] * B[11]\n\t" - "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #44]\n\t" + "# A[11] * B[5]\n\t" + "ldr r9, [%[b], #20]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r10, r10\n\t" - "# A[6] * B[10]\n\t" - "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #40]\n\t" + "# A[10] * B[6]\n\t" + "ldr r8, [%[a], #40]\n\t" + "ldr r9, [%[b], #24]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" + "# A[9] * B[7]\n\t" + "ldr r8, [%[a], #36]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[8] * B[8]\n\t" + "ldr r11, [%[a], #32]\n\t" + "ldr r12, [%[b], #32]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" "# A[7] * B[9]\n\t" "ldr r8, [%[a], #28]\n\t" "ldr r9, [%[b], #36]\n\t" @@ -9708,30 +9580,16 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" - "# A[8] * B[8]\n\t" - "ldr r8, [%[a], #32]\n\t" - "ldr r9, [%[b], #32]\n\t" + "# A[6] * B[10]\n\t" + "ldr r8, [%[a], #24]\n\t" + "ldr r9, [%[b], #40]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" - "# A[9] * B[7]\n\t" - "ldr r8, [%[a], #36]\n\t" - "ldr r9, [%[b], #28]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[10] * B[6]\n\t" - "ldr r8, [%[a], #40]\n\t" - "ldr r9, [%[b], #24]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[11] * B[5]\n\t" - "ldr r8, [%[a], #44]\n\t" - "ldr r9, [%[b], #20]\n\t" + "# A[5] * B[11]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #44]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" @@ -9739,7 +9597,6 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "str r4, [%[r], #64]\n\t" "# A[6] * B[11]\n\t" "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #44]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" @@ -9752,16 +9609,14 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "# A[8] * B[9]\n\t" - "ldr r8, [%[a], #32]\n\t" "ldr r9, [%[b], #36]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "# A[9] * B[8]\n\t" "ldr r8, [%[a], #36]\n\t" - "ldr r9, [%[b], #32]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" @@ -9780,13 +9635,25 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "str r5, [%[r], #68]\n\t" - "# A[7] * B[11]\n\t" - "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #44]\n\t" + "# A[11] * B[7]\n\t" + "ldr r9, [%[b], #28]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r10, r10\n\t" + "# A[10] * B[8]\n\t" + "ldr r8, [%[a], #40]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[9] * B[9]\n\t" + "ldr r11, [%[a], #36]\n\t" + "ldr r12, [%[b], #36]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" "# A[8] * B[10]\n\t" "ldr r8, [%[a], #32]\n\t" "ldr r9, [%[b], #40]\n\t" @@ -9794,23 +9661,9 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" - "# A[9] * B[9]\n\t" - "ldr r8, [%[a], #36]\n\t" - "ldr r9, [%[b], #36]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[10] * B[8]\n\t" - "ldr r8, [%[a], #40]\n\t" - "ldr r9, [%[b], #32]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[11] * B[7]\n\t" - "ldr r8, [%[a], #44]\n\t" - "ldr r9, [%[b], #28]\n\t" + "# A[7] * B[11]\n\t" + "ldr r8, [%[a], #28]\n\t" + "ldr r9, [%[b], #44]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" @@ -9818,22 +9671,19 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "str r3, [%[r], #72]\n\t" "# A[8] * B[11]\n\t" "ldr r8, [%[a], #32]\n\t" - "ldr r9, [%[b], #44]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r10, r10\n\t" "# A[9] * B[10]\n\t" - "ldr r8, [%[a], #36]\n\t" "ldr r9, [%[b], #40]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "# A[10] * B[9]\n\t" "ldr r8, [%[a], #40]\n\t" - "ldr r9, [%[b], #36]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" @@ -9845,79 +9695,54 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "str r4, [%[r], #76]\n\t" + "# A[11] * B[9]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "# A[10] * B[10]\n\t" + "ldr r11, [%[a], #40]\n\t" + "ldr r12, [%[b], #40]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" "# A[9] * B[11]\n\t" "ldr r8, [%[a], #36]\n\t" "ldr r9, [%[b], #44]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r10, r10\n\t" - "# A[10] * B[10]\n\t" - "ldr r8, [%[a], #40]\n\t" - "ldr r9, [%[b], #40]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[11] * B[9]\n\t" - "ldr r8, [%[a], #44]\n\t" - "ldr r9, [%[b], #36]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "str r5, [%[r], #80]\n\t" "# A[10] * B[11]\n\t" - "ldr r8, [%[a], #40]\n\t" - "ldr r9, [%[b], #44]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r10, r10\n\t" "# A[11] * B[10]\n\t" "ldr r8, [%[a], #44]\n\t" - "ldr r9, [%[b], #40]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "str r3, [%[r], #84]\n\t" "# A[11] * B[11]\n\t" - "ldr r8, [%[a], #44]\n\t" - "ldr r9, [%[b], #44]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adc r5, r5, r7\n\t" "str r4, [%[r], #88]\n\t" "str r5, [%[r], #92]\n\t" - "ldr r3, [sp, #0]\n\t" - "ldr r4, [sp, #4]\n\t" - "ldr r5, [sp, #8]\n\t" - "ldr r6, [sp, #12]\n\t" - "str r3, [%[r], #0]\n\t" - "str r4, [%[r], #4]\n\t" - "str r5, [%[r], #8]\n\t" - "str r6, [%[r], #12]\n\t" - "ldr r3, [sp, #16]\n\t" - "ldr r4, [sp, #20]\n\t" - "ldr r5, [sp, #24]\n\t" - "ldr r6, [sp, #28]\n\t" - "str r3, [%[r], #16]\n\t" - "str r4, [%[r], #20]\n\t" - "str r5, [%[r], #24]\n\t" - "str r6, [%[r], #28]\n\t" - "ldr r3, [sp, #32]\n\t" - "ldr r4, [sp, #36]\n\t" - "ldr r5, [sp, #40]\n\t" - "ldr r6, [sp, #44]\n\t" - "str r3, [%[r], #32]\n\t" - "str r4, [%[r], #36]\n\t" - "str r5, [%[r], #40]\n\t" - "str r6, [%[r], #44]\n\t" - "add sp, sp, #48\n\t" + "ldm sp!, {r3, r4, r5, r6}\n\t" + "stm %[r]!, {r3, r4, r5, r6}\n\t" + "ldm sp!, {r3, r4, r5, r6}\n\t" + "stm %[r]!, {r3, r4, r5, r6}\n\t" + "ldm sp!, {r3, r4, r5, r6}\n\t" + "stm %[r]!, {r3, r4, r5, r6}\n\t" + "sub %[r], %[r], #48\n\t" : : [r] "r" (r), [a] "r" (a), [b] "r" (b) - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" + : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); } @@ -9930,7 +9755,7 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) { __asm__ __volatile__ ( "sub sp, sp, #48\n\t" - "mov r14, #0\n\t" + "mov r12, #0\n\t" "# A[0] * A[0]\n\t" "ldr r10, [%[a], #0]\n\t" "umull r8, r3, r10, r10\n\t" @@ -9942,10 +9767,10 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r14, r14\n\t" + "adc r2, r12, r12\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" + "adc r2, r2, r12\n\t" "str r3, [sp, #4]\n\t" "# A[0] * A[2]\n\t" "ldr r10, [%[a], #8]\n\t" @@ -9953,16 +9778,16 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r4, r4, r8\n\t" "adcs r2, r2, r9\n\t" - "adc r3, r14, r14\n\t" + "adc r3, r12, r12\n\t" "adds r4, r4, r8\n\t" "adcs r2, r2, r9\n\t" - "adc r3, r3, r14\n\t" + "adc r3, r3, r12\n\t" "# A[1] * A[1]\n\t" "ldr r10, [%[a], #4]\n\t" "umull r8, r9, r10, r10\n\t" "adds r4, r4, r8\n\t" "adcs r2, r2, r9\n\t" - "adc r3, r3, r14\n\t" + "adc r3, r3, r12\n\t" "str r4, [sp, #8]\n\t" "# A[0] * A[3]\n\t" "ldr r10, [%[a], #12]\n\t" @@ -9970,20 +9795,20 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r2, r2, r8\n\t" "adcs r3, r3, r9\n\t" - "adc r4, r14, r14\n\t" + "adc r4, r12, r12\n\t" "adds r2, r2, r8\n\t" "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" + "adc r4, r4, r12\n\t" "# A[1] * A[2]\n\t" "ldr r10, [%[a], #8]\n\t" "ldr r8, [%[a], #4]\n\t" "umull r8, r9, r10, r8\n\t" "adds r2, r2, r8\n\t" "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" + "adc r4, r4, r12\n\t" "adds r2, r2, r8\n\t" "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" + "adc r4, r4, r12\n\t" "str r2, [sp, #12]\n\t" "# A[0] * A[4]\n\t" "ldr r10, [%[a], #16]\n\t" @@ -9991,26 +9816,26 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r14, r14\n\t" + "adc r2, r12, r12\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" + "adc r2, r2, r12\n\t" "# A[1] * A[3]\n\t" "ldr r10, [%[a], #12]\n\t" "ldr r8, [%[a], #4]\n\t" "umull r8, r9, r10, r8\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" + "adc r2, r2, r12\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" + "adc r2, r2, r12\n\t" "# A[2] * A[2]\n\t" "ldr r10, [%[a], #8]\n\t" "umull r8, r9, r10, r10\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" + "adc r2, r2, r12\n\t" "str r3, [sp, #16]\n\t" "# A[0] * A[5]\n\t" "ldr r10, [%[a], #20]\n\t" @@ -10024,14 +9849,14 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[2] * A[3]\n\t" "ldr r10, [%[a], #12]\n\t" "ldr r8, [%[a], #8]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "adds r5, r5, r5\n\t" "adcs r6, r6, r6\n\t" "adc r7, r7, r7\n\t" @@ -10051,14 +9876,14 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[2] * A[4]\n\t" "ldr r10, [%[a], #16]\n\t" "ldr r8, [%[a], #8]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[3] * A[3]\n\t" "ldr r10, [%[a], #12]\n\t" "umull r8, r9, r10, r10\n\t" @@ -10067,7 +9892,7 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "adc r7, r7, r7\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "adds r2, r2, r5\n\t" "adcs r3, r3, r6\n\t" "adc r4, r4, r7\n\t" @@ -10084,21 +9909,21 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[2] * A[5]\n\t" "ldr r10, [%[a], #20]\n\t" "ldr r8, [%[a], #8]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[3] * A[4]\n\t" "ldr r10, [%[a], #16]\n\t" "ldr r8, [%[a], #12]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "adds r5, r5, r5\n\t" "adcs r6, r6, r6\n\t" "adc r7, r7, r7\n\t" @@ -10118,21 +9943,21 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[2] * A[6]\n\t" "ldr r10, [%[a], #24]\n\t" "ldr r8, [%[a], #8]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[3] * A[5]\n\t" "ldr r10, [%[a], #20]\n\t" "ldr r8, [%[a], #12]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[4] * A[4]\n\t" "ldr r10, [%[a], #16]\n\t" "umull r8, r9, r10, r10\n\t" @@ -10141,7 +9966,7 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "adc r7, r7, r7\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "adds r4, r4, r5\n\t" "adcs r2, r2, r6\n\t" "adc r3, r3, r7\n\t" @@ -10158,28 +9983,28 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[2] * A[7]\n\t" "ldr r10, [%[a], #28]\n\t" "ldr r8, [%[a], #8]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[3] * A[6]\n\t" "ldr r10, [%[a], #24]\n\t" "ldr r8, [%[a], #12]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[4] * A[5]\n\t" "ldr r10, [%[a], #20]\n\t" "ldr r8, [%[a], #16]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "adds r5, r5, r5\n\t" "adcs r6, r6, r6\n\t" "adc r7, r7, r7\n\t" @@ -10199,28 +10024,28 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[2] * A[8]\n\t" "ldr r10, [%[a], #32]\n\t" "ldr r8, [%[a], #8]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[3] * A[7]\n\t" "ldr r10, [%[a], #28]\n\t" "ldr r8, [%[a], #12]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[4] * A[6]\n\t" "ldr r10, [%[a], #24]\n\t" "ldr r8, [%[a], #16]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[5] * A[5]\n\t" "ldr r10, [%[a], #20]\n\t" "umull r8, r9, r10, r10\n\t" @@ -10229,7 +10054,7 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "adc r7, r7, r7\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "adds r3, r3, r5\n\t" "adcs r4, r4, r6\n\t" "adc r2, r2, r7\n\t" @@ -10246,35 +10071,35 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[2] * A[9]\n\t" "ldr r10, [%[a], #36]\n\t" "ldr r8, [%[a], #8]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[3] * A[8]\n\t" "ldr r10, [%[a], #32]\n\t" "ldr r8, [%[a], #12]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[4] * A[7]\n\t" "ldr r10, [%[a], #28]\n\t" "ldr r8, [%[a], #16]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[5] * A[6]\n\t" "ldr r10, [%[a], #24]\n\t" "ldr r8, [%[a], #20]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "adds r5, r5, r5\n\t" "adcs r6, r6, r6\n\t" "adc r7, r7, r7\n\t" @@ -10294,28 +10119,28 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[3] * A[9]\n\t" "ldr r10, [%[a], #36]\n\t" "ldr r8, [%[a], #12]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[4] * A[8]\n\t" "ldr r10, [%[a], #32]\n\t" "ldr r8, [%[a], #16]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[5] * A[7]\n\t" "ldr r10, [%[a], #28]\n\t" "ldr r8, [%[a], #20]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[6] * A[6]\n\t" "ldr r10, [%[a], #24]\n\t" "umull r8, r9, r10, r10\n\t" @@ -10324,7 +10149,7 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "adc r7, r7, r7\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "adds r2, r2, r5\n\t" "adcs r3, r3, r6\n\t" "adc r4, r4, r7\n\t" @@ -10341,28 +10166,28 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[4] * A[9]\n\t" "ldr r10, [%[a], #36]\n\t" "ldr r8, [%[a], #16]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[5] * A[8]\n\t" "ldr r10, [%[a], #32]\n\t" "ldr r8, [%[a], #20]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[6] * A[7]\n\t" "ldr r10, [%[a], #28]\n\t" "ldr r8, [%[a], #24]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "adds r5, r5, r5\n\t" "adcs r6, r6, r6\n\t" "adc r7, r7, r7\n\t" @@ -10382,21 +10207,21 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[5] * A[9]\n\t" "ldr r10, [%[a], #36]\n\t" "ldr r8, [%[a], #20]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[6] * A[8]\n\t" "ldr r10, [%[a], #32]\n\t" "ldr r8, [%[a], #24]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[7] * A[7]\n\t" "ldr r10, [%[a], #28]\n\t" "umull r8, r9, r10, r10\n\t" @@ -10405,7 +10230,7 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "adc r7, r7, r7\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "adds r4, r4, r5\n\t" "adcs r2, r2, r6\n\t" "adc r3, r3, r7\n\t" @@ -10422,21 +10247,21 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[6] * A[9]\n\t" "ldr r10, [%[a], #36]\n\t" "ldr r8, [%[a], #24]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[7] * A[8]\n\t" "ldr r10, [%[a], #32]\n\t" "ldr r8, [%[a], #28]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "adds r5, r5, r5\n\t" "adcs r6, r6, r6\n\t" "adc r7, r7, r7\n\t" @@ -10456,14 +10281,14 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[7] * A[9]\n\t" "ldr r10, [%[a], #36]\n\t" "ldr r8, [%[a], #28]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[8] * A[8]\n\t" "ldr r10, [%[a], #32]\n\t" "umull r8, r9, r10, r10\n\t" @@ -10472,7 +10297,7 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "adc r7, r7, r7\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "adds r3, r3, r5\n\t" "adcs r4, r4, r6\n\t" "adc r2, r2, r7\n\t" @@ -10489,14 +10314,14 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "# A[8] * A[9]\n\t" "ldr r10, [%[a], #36]\n\t" "ldr r8, [%[a], #32]\n\t" "umull r8, r9, r10, r8\n\t" "adds r5, r5, r8\n\t" "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" + "adc r7, r7, r12\n\t" "adds r5, r5, r5\n\t" "adcs r6, r6, r6\n\t" "adc r7, r7, r7\n\t" @@ -10510,26 +10335,26 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r2, r2, r8\n\t" "adcs r3, r3, r9\n\t" - "adc r4, r14, r14\n\t" + "adc r4, r12, r12\n\t" "adds r2, r2, r8\n\t" "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" + "adc r4, r4, r12\n\t" "# A[8] * A[10]\n\t" "ldr r10, [%[a], #40]\n\t" "ldr r8, [%[a], #32]\n\t" "umull r8, r9, r10, r8\n\t" "adds r2, r2, r8\n\t" "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" + "adc r4, r4, r12\n\t" "adds r2, r2, r8\n\t" "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" + "adc r4, r4, r12\n\t" "# A[9] * A[9]\n\t" "ldr r10, [%[a], #36]\n\t" "umull r8, r9, r10, r10\n\t" "adds r2, r2, r8\n\t" "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" + "adc r4, r4, r12\n\t" "str r2, [%[r], #72]\n\t" "# A[8] * A[11]\n\t" "ldr r10, [%[a], #44]\n\t" @@ -10537,20 +10362,20 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r14, r14\n\t" + "adc r2, r12, r12\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" + "adc r2, r2, r12\n\t" "# A[9] * A[10]\n\t" "ldr r10, [%[a], #40]\n\t" "ldr r8, [%[a], #36]\n\t" "umull r8, r9, r10, r8\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" + "adc r2, r2, r12\n\t" "adds r3, r3, r8\n\t" "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" + "adc r2, r2, r12\n\t" "str r3, [%[r], #76]\n\t" "# A[9] * A[11]\n\t" "ldr r10, [%[a], #44]\n\t" @@ -10558,16 +10383,16 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r4, r4, r8\n\t" "adcs r2, r2, r9\n\t" - "adc r3, r14, r14\n\t" + "adc r3, r12, r12\n\t" "adds r4, r4, r8\n\t" "adcs r2, r2, r9\n\t" - "adc r3, r3, r14\n\t" + "adc r3, r3, r12\n\t" "# A[10] * A[10]\n\t" "ldr r10, [%[a], #40]\n\t" "umull r8, r9, r10, r10\n\t" "adds r4, r4, r8\n\t" "adcs r2, r2, r9\n\t" - "adc r3, r3, r14\n\t" + "adc r3, r3, r12\n\t" "str r4, [%[r], #80]\n\t" "# A[10] * A[11]\n\t" "ldr r10, [%[a], #44]\n\t" @@ -10575,10 +10400,10 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "umull r8, r9, r10, r8\n\t" "adds r2, r2, r8\n\t" "adcs r3, r3, r9\n\t" - "adc r4, r14, r14\n\t" + "adc r4, r12, r12\n\t" "adds r2, r2, r8\n\t" "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" + "adc r4, r4, r12\n\t" "str r2, [%[r], #84]\n\t" "# A[11] * A[11]\n\t" "ldr r10, [%[a], #44]\n\t" @@ -10587,34 +10412,16 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "adc r4, r4, r9\n\t" "str r3, [%[r], #88]\n\t" "str r4, [%[r], #92]\n\t" - "ldr r2, [sp, #0]\n\t" - "ldr r3, [sp, #4]\n\t" - "ldr r4, [sp, #8]\n\t" - "ldr r8, [sp, #12]\n\t" - "str r2, [%[r], #0]\n\t" - "str r3, [%[r], #4]\n\t" - "str r4, [%[r], #8]\n\t" - "str r8, [%[r], #12]\n\t" - "ldr r2, [sp, #16]\n\t" - "ldr r3, [sp, #20]\n\t" - "ldr r4, [sp, #24]\n\t" - "ldr r8, [sp, #28]\n\t" - "str r2, [%[r], #16]\n\t" - "str r3, [%[r], #20]\n\t" - "str r4, [%[r], #24]\n\t" - "str r8, [%[r], #28]\n\t" - "ldr r2, [sp, #32]\n\t" - "ldr r3, [sp, #36]\n\t" - "ldr r4, [sp, #40]\n\t" - "ldr r8, [sp, #44]\n\t" - "str r2, [%[r], #32]\n\t" - "str r3, [%[r], #36]\n\t" - "str r4, [%[r], #40]\n\t" - "str r8, [%[r], #44]\n\t" - "add sp, sp, #48\n\t" + "ldm sp!, {r2, r3, r4, r8}\n\t" + "stm %[r]!, {r2, r3, r4, r8}\n\t" + "ldm sp!, {r2, r3, r4, r8}\n\t" + "stm %[r]!, {r2, r3, r4, r8}\n\t" + "ldm sp!, {r2, r3, r4, r8}\n\t" + "stm %[r]!, {r2, r3, r4, r8}\n\t" + "sub %[r], %[r], #48\n\t" : : [r] "r" (r), [a] "r" (a) - : "memory", "r2", "r3", "r4", "r8", "r9", "r10", "r8", "r5", "r6", "r7", "r14" + : "memory", "r2", "r3", "r4", "r8", "r9", "r10", "r8", "r5", "r6", "r7", "r12" ); } @@ -10965,7 +10772,9 @@ SP_NOINLINE static void sp_3072_mul_24(sp_digit* r, const sp_digit* a, sp_digit a1[12]; sp_digit b1[12]; sp_digit z2[24]; - sp_digit u, ca, cb; + sp_digit u; + sp_digit ca; + sp_digit cb; ca = sp_3072_add_12(a1, a, &a[12]); cb = sp_3072_add_12(b1, b, &b[12]); @@ -11480,7 +11289,9 @@ SP_NOINLINE static void sp_3072_mul_48(sp_digit* r, const sp_digit* a, sp_digit a1[24]; sp_digit b1[24]; sp_digit z2[48]; - sp_digit u, ca, cb; + sp_digit u; + sp_digit ca; + sp_digit cb; ca = sp_3072_add_24(a1, a, &a[24]); cb = sp_3072_add_24(b1, b, &b[24]); @@ -12379,7 +12190,9 @@ SP_NOINLINE static void sp_3072_mul_96(sp_digit* r, const sp_digit* a, sp_digit a1[48]; sp_digit b1[48]; sp_digit z2[96]; - sp_digit u, ca, cb; + sp_digit u; + sp_digit ca; + sp_digit cb; ca = sp_3072_add_48(a1, a, &a[48]); cb = sp_3072_add_48(b1, b, &b[48]); @@ -12894,7 +12707,7 @@ static void sp_3072_sqr_48(sp_digit* r, const sp_digit* a) } #endif /* WOLFSSL_SP_SMALL */ -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ /* Caclulate the bottom digit of -1/a mod 2^n. * @@ -12903,7 +12716,8 @@ static void sp_3072_sqr_48(sp_digit* r, const sp_digit* a) */ static void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho) { - sp_digit x, b; + sp_digit x; + sp_digit b; b = a[0]; x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ @@ -12912,7 +12726,7 @@ static void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho) x *= 2 - b * x; /* here x*a==1 mod 2**32 */ /* rho = -1/m mod b */ - *rho = -x; + *rho = (sp_digit)0 - x; } /* Mul a by digit b into r. (r = a * b) @@ -12962,755 +12776,661 @@ static void sp_3072_mul_d_96(sp_digit* r, const sp_digit* a, "str r3, [%[r]]\n\t" "# A[1] * B\n\t" "ldr r8, [%[a], #4]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #4]\n\t" "# A[2] * B\n\t" "ldr r8, [%[a], #8]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #8]\n\t" "# A[3] * B\n\t" "ldr r8, [%[a], #12]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #12]\n\t" "# A[4] * B\n\t" "ldr r8, [%[a], #16]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #16]\n\t" "# A[5] * B\n\t" "ldr r8, [%[a], #20]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #20]\n\t" "# A[6] * B\n\t" "ldr r8, [%[a], #24]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #24]\n\t" "# A[7] * B\n\t" "ldr r8, [%[a], #28]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #28]\n\t" "# A[8] * B\n\t" "ldr r8, [%[a], #32]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #32]\n\t" "# A[9] * B\n\t" "ldr r8, [%[a], #36]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #36]\n\t" "# A[10] * B\n\t" "ldr r8, [%[a], #40]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #40]\n\t" "# A[11] * B\n\t" "ldr r8, [%[a], #44]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #44]\n\t" "# A[12] * B\n\t" "ldr r8, [%[a], #48]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #48]\n\t" "# A[13] * B\n\t" "ldr r8, [%[a], #52]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #52]\n\t" "# A[14] * B\n\t" "ldr r8, [%[a], #56]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #56]\n\t" "# A[15] * B\n\t" "ldr r8, [%[a], #60]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #60]\n\t" "# A[16] * B\n\t" "ldr r8, [%[a], #64]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #64]\n\t" "# A[17] * B\n\t" "ldr r8, [%[a], #68]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #68]\n\t" "# A[18] * B\n\t" "ldr r8, [%[a], #72]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #72]\n\t" "# A[19] * B\n\t" "ldr r8, [%[a], #76]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #76]\n\t" "# A[20] * B\n\t" "ldr r8, [%[a], #80]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #80]\n\t" "# A[21] * B\n\t" "ldr r8, [%[a], #84]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #84]\n\t" "# A[22] * B\n\t" "ldr r8, [%[a], #88]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #88]\n\t" "# A[23] * B\n\t" "ldr r8, [%[a], #92]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #92]\n\t" "# A[24] * B\n\t" "ldr r8, [%[a], #96]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #96]\n\t" "# A[25] * B\n\t" "ldr r8, [%[a], #100]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #100]\n\t" "# A[26] * B\n\t" "ldr r8, [%[a], #104]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #104]\n\t" "# A[27] * B\n\t" "ldr r8, [%[a], #108]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #108]\n\t" "# A[28] * B\n\t" "ldr r8, [%[a], #112]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #112]\n\t" "# A[29] * B\n\t" "ldr r8, [%[a], #116]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #116]\n\t" "# A[30] * B\n\t" "ldr r8, [%[a], #120]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #120]\n\t" "# A[31] * B\n\t" "ldr r8, [%[a], #124]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #124]\n\t" "# A[32] * B\n\t" "ldr r8, [%[a], #128]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #128]\n\t" "# A[33] * B\n\t" "ldr r8, [%[a], #132]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #132]\n\t" "# A[34] * B\n\t" "ldr r8, [%[a], #136]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #136]\n\t" "# A[35] * B\n\t" "ldr r8, [%[a], #140]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #140]\n\t" "# A[36] * B\n\t" "ldr r8, [%[a], #144]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #144]\n\t" "# A[37] * B\n\t" "ldr r8, [%[a], #148]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #148]\n\t" "# A[38] * B\n\t" "ldr r8, [%[a], #152]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #152]\n\t" "# A[39] * B\n\t" "ldr r8, [%[a], #156]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #156]\n\t" "# A[40] * B\n\t" "ldr r8, [%[a], #160]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #160]\n\t" "# A[41] * B\n\t" "ldr r8, [%[a], #164]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #164]\n\t" "# A[42] * B\n\t" "ldr r8, [%[a], #168]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #168]\n\t" "# A[43] * B\n\t" "ldr r8, [%[a], #172]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #172]\n\t" "# A[44] * B\n\t" "ldr r8, [%[a], #176]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #176]\n\t" "# A[45] * B\n\t" "ldr r8, [%[a], #180]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #180]\n\t" "# A[46] * B\n\t" "ldr r8, [%[a], #184]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #184]\n\t" "# A[47] * B\n\t" "ldr r8, [%[a], #188]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #188]\n\t" "# A[48] * B\n\t" "ldr r8, [%[a], #192]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #192]\n\t" "# A[49] * B\n\t" "ldr r8, [%[a], #196]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #196]\n\t" "# A[50] * B\n\t" "ldr r8, [%[a], #200]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #200]\n\t" "# A[51] * B\n\t" "ldr r8, [%[a], #204]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #204]\n\t" "# A[52] * B\n\t" "ldr r8, [%[a], #208]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #208]\n\t" "# A[53] * B\n\t" "ldr r8, [%[a], #212]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #212]\n\t" "# A[54] * B\n\t" "ldr r8, [%[a], #216]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #216]\n\t" "# A[55] * B\n\t" "ldr r8, [%[a], #220]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #220]\n\t" "# A[56] * B\n\t" "ldr r8, [%[a], #224]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #224]\n\t" "# A[57] * B\n\t" "ldr r8, [%[a], #228]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #228]\n\t" "# A[58] * B\n\t" "ldr r8, [%[a], #232]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #232]\n\t" "# A[59] * B\n\t" "ldr r8, [%[a], #236]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #236]\n\t" "# A[60] * B\n\t" "ldr r8, [%[a], #240]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #240]\n\t" "# A[61] * B\n\t" "ldr r8, [%[a], #244]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #244]\n\t" "# A[62] * B\n\t" "ldr r8, [%[a], #248]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #248]\n\t" "# A[63] * B\n\t" "ldr r8, [%[a], #252]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #252]\n\t" "# A[64] * B\n\t" "ldr r8, [%[a], #256]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #256]\n\t" "# A[65] * B\n\t" "ldr r8, [%[a], #260]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #260]\n\t" "# A[66] * B\n\t" "ldr r8, [%[a], #264]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #264]\n\t" "# A[67] * B\n\t" "ldr r8, [%[a], #268]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #268]\n\t" "# A[68] * B\n\t" "ldr r8, [%[a], #272]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #272]\n\t" "# A[69] * B\n\t" "ldr r8, [%[a], #276]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #276]\n\t" "# A[70] * B\n\t" "ldr r8, [%[a], #280]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #280]\n\t" "# A[71] * B\n\t" "ldr r8, [%[a], #284]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #284]\n\t" "# A[72] * B\n\t" "ldr r8, [%[a], #288]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #288]\n\t" "# A[73] * B\n\t" "ldr r8, [%[a], #292]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #292]\n\t" "# A[74] * B\n\t" "ldr r8, [%[a], #296]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #296]\n\t" "# A[75] * B\n\t" "ldr r8, [%[a], #300]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #300]\n\t" "# A[76] * B\n\t" "ldr r8, [%[a], #304]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #304]\n\t" "# A[77] * B\n\t" "ldr r8, [%[a], #308]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #308]\n\t" "# A[78] * B\n\t" "ldr r8, [%[a], #312]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #312]\n\t" "# A[79] * B\n\t" "ldr r8, [%[a], #316]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #316]\n\t" "# A[80] * B\n\t" "ldr r8, [%[a], #320]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #320]\n\t" "# A[81] * B\n\t" "ldr r8, [%[a], #324]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #324]\n\t" "# A[82] * B\n\t" "ldr r8, [%[a], #328]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #328]\n\t" "# A[83] * B\n\t" "ldr r8, [%[a], #332]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #332]\n\t" "# A[84] * B\n\t" "ldr r8, [%[a], #336]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #336]\n\t" "# A[85] * B\n\t" "ldr r8, [%[a], #340]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #340]\n\t" "# A[86] * B\n\t" "ldr r8, [%[a], #344]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #344]\n\t" "# A[87] * B\n\t" "ldr r8, [%[a], #348]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #348]\n\t" "# A[88] * B\n\t" "ldr r8, [%[a], #352]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #352]\n\t" "# A[89] * B\n\t" "ldr r8, [%[a], #356]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #356]\n\t" "# A[90] * B\n\t" "ldr r8, [%[a], #360]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #360]\n\t" "# A[91] * B\n\t" "ldr r8, [%[a], #364]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #364]\n\t" "# A[92] * B\n\t" "ldr r8, [%[a], #368]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #368]\n\t" "# A[93] * B\n\t" "ldr r8, [%[a], #372]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #372]\n\t" "# A[94] * B\n\t" "ldr r8, [%[a], #376]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #376]\n\t" "# A[95] * B\n\t" "ldr r8, [%[a], #380]\n\t" @@ -14039,6 +13759,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, sp_digit ca = 0; __asm__ __volatile__ ( + "ldr r11, [%[m], #0]\n\t" "# i = 0\n\t" "mov r12, #0\n\t" "ldr r10, [%[a], #0]\n\t" @@ -14047,13 +13768,12 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "# mu = a[i] * mp\n\t" "mul r8, %[mp], r10\n\t" "# a[i+0] += m[0] * mu\n\t" - "ldr r7, [%[m], #0]\n\t" "ldr r9, [%[a], #0]\n\t" - "umull r6, r7, r8, r7\n\t" + "umull r6, r7, r8, r11\n\t" "adds r10, r10, r6\n\t" "adc r5, r7, #0\n\t" "# a[i+1] += m[1] * mu\n\t" - "ldr r7, [%[m], #4]\n\t" + "ldr r7, [%[m], #4]\n\t" "ldr r9, [%[a], #4]\n\t" "umull r6, r7, r8, r7\n\t" "adds r10, r14, r6\n\t" @@ -14061,7 +13781,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "adds r10, r10, r5\n\t" "adc r4, r4, #0\n\t" "# a[i+2] += m[2] * mu\n\t" - "ldr r7, [%[m], #8]\n\t" + "ldr r7, [%[m], #8]\n\t" "ldr r14, [%[a], #8]\n\t" "umull r6, r7, r8, r7\n\t" "adds r14, r14, r6\n\t" @@ -14069,7 +13789,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "adds r14, r14, r4\n\t" "adc r5, r5, #0\n\t" "# a[i+3] += m[3] * mu\n\t" - "ldr r7, [%[m], #12]\n\t" + "ldr r7, [%[m], #12]\n\t" "ldr r9, [%[a], #12]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14078,7 +13798,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #12]\n\t" "adc r4, r4, #0\n\t" "# a[i+4] += m[4] * mu\n\t" - "ldr r7, [%[m], #16]\n\t" + "ldr r7, [%[m], #16]\n\t" "ldr r9, [%[a], #16]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14087,7 +13807,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #16]\n\t" "adc r5, r5, #0\n\t" "# a[i+5] += m[5] * mu\n\t" - "ldr r7, [%[m], #20]\n\t" + "ldr r7, [%[m], #20]\n\t" "ldr r9, [%[a], #20]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14096,7 +13816,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #20]\n\t" "adc r4, r4, #0\n\t" "# a[i+6] += m[6] * mu\n\t" - "ldr r7, [%[m], #24]\n\t" + "ldr r7, [%[m], #24]\n\t" "ldr r9, [%[a], #24]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14105,7 +13825,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #24]\n\t" "adc r5, r5, #0\n\t" "# a[i+7] += m[7] * mu\n\t" - "ldr r7, [%[m], #28]\n\t" + "ldr r7, [%[m], #28]\n\t" "ldr r9, [%[a], #28]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14114,7 +13834,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #28]\n\t" "adc r4, r4, #0\n\t" "# a[i+8] += m[8] * mu\n\t" - "ldr r7, [%[m], #32]\n\t" + "ldr r7, [%[m], #32]\n\t" "ldr r9, [%[a], #32]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14123,7 +13843,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #32]\n\t" "adc r5, r5, #0\n\t" "# a[i+9] += m[9] * mu\n\t" - "ldr r7, [%[m], #36]\n\t" + "ldr r7, [%[m], #36]\n\t" "ldr r9, [%[a], #36]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14132,7 +13852,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #36]\n\t" "adc r4, r4, #0\n\t" "# a[i+10] += m[10] * mu\n\t" - "ldr r7, [%[m], #40]\n\t" + "ldr r7, [%[m], #40]\n\t" "ldr r9, [%[a], #40]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14141,7 +13861,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #40]\n\t" "adc r5, r5, #0\n\t" "# a[i+11] += m[11] * mu\n\t" - "ldr r7, [%[m], #44]\n\t" + "ldr r7, [%[m], #44]\n\t" "ldr r9, [%[a], #44]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14150,7 +13870,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #44]\n\t" "adc r4, r4, #0\n\t" "# a[i+12] += m[12] * mu\n\t" - "ldr r7, [%[m], #48]\n\t" + "ldr r7, [%[m], #48]\n\t" "ldr r9, [%[a], #48]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14159,7 +13879,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #48]\n\t" "adc r5, r5, #0\n\t" "# a[i+13] += m[13] * mu\n\t" - "ldr r7, [%[m], #52]\n\t" + "ldr r7, [%[m], #52]\n\t" "ldr r9, [%[a], #52]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14168,7 +13888,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #52]\n\t" "adc r4, r4, #0\n\t" "# a[i+14] += m[14] * mu\n\t" - "ldr r7, [%[m], #56]\n\t" + "ldr r7, [%[m], #56]\n\t" "ldr r9, [%[a], #56]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14177,7 +13897,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #56]\n\t" "adc r5, r5, #0\n\t" "# a[i+15] += m[15] * mu\n\t" - "ldr r7, [%[m], #60]\n\t" + "ldr r7, [%[m], #60]\n\t" "ldr r9, [%[a], #60]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14186,7 +13906,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #60]\n\t" "adc r4, r4, #0\n\t" "# a[i+16] += m[16] * mu\n\t" - "ldr r7, [%[m], #64]\n\t" + "ldr r7, [%[m], #64]\n\t" "ldr r9, [%[a], #64]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14195,7 +13915,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #64]\n\t" "adc r5, r5, #0\n\t" "# a[i+17] += m[17] * mu\n\t" - "ldr r7, [%[m], #68]\n\t" + "ldr r7, [%[m], #68]\n\t" "ldr r9, [%[a], #68]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14204,7 +13924,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #68]\n\t" "adc r4, r4, #0\n\t" "# a[i+18] += m[18] * mu\n\t" - "ldr r7, [%[m], #72]\n\t" + "ldr r7, [%[m], #72]\n\t" "ldr r9, [%[a], #72]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14213,7 +13933,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #72]\n\t" "adc r5, r5, #0\n\t" "# a[i+19] += m[19] * mu\n\t" - "ldr r7, [%[m], #76]\n\t" + "ldr r7, [%[m], #76]\n\t" "ldr r9, [%[a], #76]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14222,7 +13942,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #76]\n\t" "adc r4, r4, #0\n\t" "# a[i+20] += m[20] * mu\n\t" - "ldr r7, [%[m], #80]\n\t" + "ldr r7, [%[m], #80]\n\t" "ldr r9, [%[a], #80]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14231,7 +13951,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #80]\n\t" "adc r5, r5, #0\n\t" "# a[i+21] += m[21] * mu\n\t" - "ldr r7, [%[m], #84]\n\t" + "ldr r7, [%[m], #84]\n\t" "ldr r9, [%[a], #84]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14240,7 +13960,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #84]\n\t" "adc r4, r4, #0\n\t" "# a[i+22] += m[22] * mu\n\t" - "ldr r7, [%[m], #88]\n\t" + "ldr r7, [%[m], #88]\n\t" "ldr r9, [%[a], #88]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14249,7 +13969,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #88]\n\t" "adc r5, r5, #0\n\t" "# a[i+23] += m[23] * mu\n\t" - "ldr r7, [%[m], #92]\n\t" + "ldr r7, [%[m], #92]\n\t" "ldr r9, [%[a], #92]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14258,7 +13978,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #92]\n\t" "adc r4, r4, #0\n\t" "# a[i+24] += m[24] * mu\n\t" - "ldr r7, [%[m], #96]\n\t" + "ldr r7, [%[m], #96]\n\t" "ldr r9, [%[a], #96]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14267,7 +13987,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #96]\n\t" "adc r5, r5, #0\n\t" "# a[i+25] += m[25] * mu\n\t" - "ldr r7, [%[m], #100]\n\t" + "ldr r7, [%[m], #100]\n\t" "ldr r9, [%[a], #100]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14276,7 +13996,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #100]\n\t" "adc r4, r4, #0\n\t" "# a[i+26] += m[26] * mu\n\t" - "ldr r7, [%[m], #104]\n\t" + "ldr r7, [%[m], #104]\n\t" "ldr r9, [%[a], #104]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14285,7 +14005,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #104]\n\t" "adc r5, r5, #0\n\t" "# a[i+27] += m[27] * mu\n\t" - "ldr r7, [%[m], #108]\n\t" + "ldr r7, [%[m], #108]\n\t" "ldr r9, [%[a], #108]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14294,7 +14014,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #108]\n\t" "adc r4, r4, #0\n\t" "# a[i+28] += m[28] * mu\n\t" - "ldr r7, [%[m], #112]\n\t" + "ldr r7, [%[m], #112]\n\t" "ldr r9, [%[a], #112]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14303,7 +14023,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #112]\n\t" "adc r5, r5, #0\n\t" "# a[i+29] += m[29] * mu\n\t" - "ldr r7, [%[m], #116]\n\t" + "ldr r7, [%[m], #116]\n\t" "ldr r9, [%[a], #116]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14312,7 +14032,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #116]\n\t" "adc r4, r4, #0\n\t" "# a[i+30] += m[30] * mu\n\t" - "ldr r7, [%[m], #120]\n\t" + "ldr r7, [%[m], #120]\n\t" "ldr r9, [%[a], #120]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14321,7 +14041,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #120]\n\t" "adc r5, r5, #0\n\t" "# a[i+31] += m[31] * mu\n\t" - "ldr r7, [%[m], #124]\n\t" + "ldr r7, [%[m], #124]\n\t" "ldr r9, [%[a], #124]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14330,7 +14050,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #124]\n\t" "adc r4, r4, #0\n\t" "# a[i+32] += m[32] * mu\n\t" - "ldr r7, [%[m], #128]\n\t" + "ldr r7, [%[m], #128]\n\t" "ldr r9, [%[a], #128]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14339,7 +14059,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #128]\n\t" "adc r5, r5, #0\n\t" "# a[i+33] += m[33] * mu\n\t" - "ldr r7, [%[m], #132]\n\t" + "ldr r7, [%[m], #132]\n\t" "ldr r9, [%[a], #132]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14348,7 +14068,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #132]\n\t" "adc r4, r4, #0\n\t" "# a[i+34] += m[34] * mu\n\t" - "ldr r7, [%[m], #136]\n\t" + "ldr r7, [%[m], #136]\n\t" "ldr r9, [%[a], #136]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14357,7 +14077,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #136]\n\t" "adc r5, r5, #0\n\t" "# a[i+35] += m[35] * mu\n\t" - "ldr r7, [%[m], #140]\n\t" + "ldr r7, [%[m], #140]\n\t" "ldr r9, [%[a], #140]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14366,7 +14086,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #140]\n\t" "adc r4, r4, #0\n\t" "# a[i+36] += m[36] * mu\n\t" - "ldr r7, [%[m], #144]\n\t" + "ldr r7, [%[m], #144]\n\t" "ldr r9, [%[a], #144]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14375,7 +14095,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #144]\n\t" "adc r5, r5, #0\n\t" "# a[i+37] += m[37] * mu\n\t" - "ldr r7, [%[m], #148]\n\t" + "ldr r7, [%[m], #148]\n\t" "ldr r9, [%[a], #148]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14384,7 +14104,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #148]\n\t" "adc r4, r4, #0\n\t" "# a[i+38] += m[38] * mu\n\t" - "ldr r7, [%[m], #152]\n\t" + "ldr r7, [%[m], #152]\n\t" "ldr r9, [%[a], #152]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14393,7 +14113,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #152]\n\t" "adc r5, r5, #0\n\t" "# a[i+39] += m[39] * mu\n\t" - "ldr r7, [%[m], #156]\n\t" + "ldr r7, [%[m], #156]\n\t" "ldr r9, [%[a], #156]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14402,7 +14122,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #156]\n\t" "adc r4, r4, #0\n\t" "# a[i+40] += m[40] * mu\n\t" - "ldr r7, [%[m], #160]\n\t" + "ldr r7, [%[m], #160]\n\t" "ldr r9, [%[a], #160]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14411,7 +14131,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #160]\n\t" "adc r5, r5, #0\n\t" "# a[i+41] += m[41] * mu\n\t" - "ldr r7, [%[m], #164]\n\t" + "ldr r7, [%[m], #164]\n\t" "ldr r9, [%[a], #164]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14420,7 +14140,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #164]\n\t" "adc r4, r4, #0\n\t" "# a[i+42] += m[42] * mu\n\t" - "ldr r7, [%[m], #168]\n\t" + "ldr r7, [%[m], #168]\n\t" "ldr r9, [%[a], #168]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14429,7 +14149,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #168]\n\t" "adc r5, r5, #0\n\t" "# a[i+43] += m[43] * mu\n\t" - "ldr r7, [%[m], #172]\n\t" + "ldr r7, [%[m], #172]\n\t" "ldr r9, [%[a], #172]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14438,7 +14158,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #172]\n\t" "adc r4, r4, #0\n\t" "# a[i+44] += m[44] * mu\n\t" - "ldr r7, [%[m], #176]\n\t" + "ldr r7, [%[m], #176]\n\t" "ldr r9, [%[a], #176]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14447,7 +14167,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #176]\n\t" "adc r5, r5, #0\n\t" "# a[i+45] += m[45] * mu\n\t" - "ldr r7, [%[m], #180]\n\t" + "ldr r7, [%[m], #180]\n\t" "ldr r9, [%[a], #180]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14456,7 +14176,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r9, [%[a], #180]\n\t" "adc r4, r4, #0\n\t" "# a[i+46] += m[46] * mu\n\t" - "ldr r7, [%[m], #184]\n\t" + "ldr r7, [%[m], #184]\n\t" "ldr r9, [%[a], #184]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -14487,7 +14207,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "str r14, [%[a], #4]\n\t" : [ca] "+r" (ca), [a] "+r" (a) : [m] "r" (m), [mp] "r" (mp) - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12", "r11" ); sp_3072_cond_sub_48(a - 48, a, m, (sp_digit)0 - ca); @@ -14502,8 +14222,8 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_mul_48(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_3072_mont_mul_48(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_3072_mul_48(r, a, b); sp_3072_mont_reduce_48(r, m, mp); @@ -14516,8 +14236,8 @@ static void sp_3072_mont_mul_48(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_sqr_48(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_3072_mont_sqr_48(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_3072_sqr_48(r, a); sp_3072_mont_reduce_48(r, m, mp); @@ -14570,371 +14290,325 @@ static void sp_3072_mul_d_48(sp_digit* r, const sp_digit* a, "str r3, [%[r]]\n\t" "# A[1] * B\n\t" "ldr r8, [%[a], #4]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #4]\n\t" "# A[2] * B\n\t" "ldr r8, [%[a], #8]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #8]\n\t" "# A[3] * B\n\t" "ldr r8, [%[a], #12]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #12]\n\t" "# A[4] * B\n\t" "ldr r8, [%[a], #16]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #16]\n\t" "# A[5] * B\n\t" "ldr r8, [%[a], #20]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #20]\n\t" "# A[6] * B\n\t" "ldr r8, [%[a], #24]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #24]\n\t" "# A[7] * B\n\t" "ldr r8, [%[a], #28]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #28]\n\t" "# A[8] * B\n\t" "ldr r8, [%[a], #32]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #32]\n\t" "# A[9] * B\n\t" "ldr r8, [%[a], #36]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #36]\n\t" "# A[10] * B\n\t" "ldr r8, [%[a], #40]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #40]\n\t" "# A[11] * B\n\t" "ldr r8, [%[a], #44]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #44]\n\t" "# A[12] * B\n\t" "ldr r8, [%[a], #48]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #48]\n\t" "# A[13] * B\n\t" "ldr r8, [%[a], #52]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #52]\n\t" "# A[14] * B\n\t" "ldr r8, [%[a], #56]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #56]\n\t" "# A[15] * B\n\t" "ldr r8, [%[a], #60]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #60]\n\t" "# A[16] * B\n\t" "ldr r8, [%[a], #64]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #64]\n\t" "# A[17] * B\n\t" "ldr r8, [%[a], #68]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #68]\n\t" "# A[18] * B\n\t" "ldr r8, [%[a], #72]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #72]\n\t" "# A[19] * B\n\t" "ldr r8, [%[a], #76]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #76]\n\t" "# A[20] * B\n\t" "ldr r8, [%[a], #80]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #80]\n\t" "# A[21] * B\n\t" "ldr r8, [%[a], #84]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #84]\n\t" "# A[22] * B\n\t" "ldr r8, [%[a], #88]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #88]\n\t" "# A[23] * B\n\t" "ldr r8, [%[a], #92]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #92]\n\t" "# A[24] * B\n\t" "ldr r8, [%[a], #96]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #96]\n\t" "# A[25] * B\n\t" "ldr r8, [%[a], #100]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #100]\n\t" "# A[26] * B\n\t" "ldr r8, [%[a], #104]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #104]\n\t" "# A[27] * B\n\t" "ldr r8, [%[a], #108]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #108]\n\t" "# A[28] * B\n\t" "ldr r8, [%[a], #112]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #112]\n\t" "# A[29] * B\n\t" "ldr r8, [%[a], #116]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #116]\n\t" "# A[30] * B\n\t" "ldr r8, [%[a], #120]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #120]\n\t" "# A[31] * B\n\t" "ldr r8, [%[a], #124]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #124]\n\t" "# A[32] * B\n\t" "ldr r8, [%[a], #128]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #128]\n\t" "# A[33] * B\n\t" "ldr r8, [%[a], #132]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #132]\n\t" "# A[34] * B\n\t" "ldr r8, [%[a], #136]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #136]\n\t" "# A[35] * B\n\t" "ldr r8, [%[a], #140]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #140]\n\t" "# A[36] * B\n\t" "ldr r8, [%[a], #144]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #144]\n\t" "# A[37] * B\n\t" "ldr r8, [%[a], #148]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #148]\n\t" "# A[38] * B\n\t" "ldr r8, [%[a], #152]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #152]\n\t" "# A[39] * B\n\t" "ldr r8, [%[a], #156]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #156]\n\t" "# A[40] * B\n\t" "ldr r8, [%[a], #160]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #160]\n\t" "# A[41] * B\n\t" "ldr r8, [%[a], #164]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #164]\n\t" "# A[42] * B\n\t" "ldr r8, [%[a], #168]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #168]\n\t" "# A[43] * B\n\t" "ldr r8, [%[a], #172]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #172]\n\t" "# A[44] * B\n\t" "ldr r8, [%[a], #176]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #176]\n\t" "# A[45] * B\n\t" "ldr r8, [%[a], #180]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #180]\n\t" "# A[46] * B\n\t" "ldr r8, [%[a], #184]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #184]\n\t" "# A[47] * B\n\t" "ldr r8, [%[a], #188]\n\t" @@ -15667,7 +15341,8 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -15733,34 +15408,34 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 48); for (; i>=0 || c>=4; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 28); + y = (byte)(n >> 28); n <<= 4; c = 28; } else if (c < 4) { - y = (int)(n >> 28); + y = (byte)(n >> 28); n = e[i--]; c = 4 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 28) & 0xf); + y = (byte)((n >> 28) & 0xf); n <<= 4; c -= 4; } @@ -15812,7 +15487,8 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -15894,34 +15570,34 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 48); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -15952,7 +15628,7 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, } #endif /* WOLFSSL_SP_SMALL */ -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) /* r = 2^n mod m where n is the number of bits to reduce by. @@ -15969,7 +15645,7 @@ static void sp_3072_mont_norm_96(sp_digit* r, const sp_digit* m) sp_3072_sub_in_place_96(r, m); } -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */ /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -16508,6 +16184,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, sp_digit ca = 0; __asm__ __volatile__ ( + "ldr r11, [%[m], #0]\n\t" "# i = 0\n\t" "mov r12, #0\n\t" "ldr r10, [%[a], #0]\n\t" @@ -16516,13 +16193,12 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "# mu = a[i] * mp\n\t" "mul r8, %[mp], r10\n\t" "# a[i+0] += m[0] * mu\n\t" - "ldr r7, [%[m], #0]\n\t" "ldr r9, [%[a], #0]\n\t" - "umull r6, r7, r8, r7\n\t" + "umull r6, r7, r8, r11\n\t" "adds r10, r10, r6\n\t" "adc r5, r7, #0\n\t" "# a[i+1] += m[1] * mu\n\t" - "ldr r7, [%[m], #4]\n\t" + "ldr r7, [%[m], #4]\n\t" "ldr r9, [%[a], #4]\n\t" "umull r6, r7, r8, r7\n\t" "adds r10, r14, r6\n\t" @@ -16530,7 +16206,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "adds r10, r10, r5\n\t" "adc r4, r4, #0\n\t" "# a[i+2] += m[2] * mu\n\t" - "ldr r7, [%[m], #8]\n\t" + "ldr r7, [%[m], #8]\n\t" "ldr r14, [%[a], #8]\n\t" "umull r6, r7, r8, r7\n\t" "adds r14, r14, r6\n\t" @@ -16538,7 +16214,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "adds r14, r14, r4\n\t" "adc r5, r5, #0\n\t" "# a[i+3] += m[3] * mu\n\t" - "ldr r7, [%[m], #12]\n\t" + "ldr r7, [%[m], #12]\n\t" "ldr r9, [%[a], #12]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16547,7 +16223,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #12]\n\t" "adc r4, r4, #0\n\t" "# a[i+4] += m[4] * mu\n\t" - "ldr r7, [%[m], #16]\n\t" + "ldr r7, [%[m], #16]\n\t" "ldr r9, [%[a], #16]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16556,7 +16232,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #16]\n\t" "adc r5, r5, #0\n\t" "# a[i+5] += m[5] * mu\n\t" - "ldr r7, [%[m], #20]\n\t" + "ldr r7, [%[m], #20]\n\t" "ldr r9, [%[a], #20]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16565,7 +16241,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #20]\n\t" "adc r4, r4, #0\n\t" "# a[i+6] += m[6] * mu\n\t" - "ldr r7, [%[m], #24]\n\t" + "ldr r7, [%[m], #24]\n\t" "ldr r9, [%[a], #24]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16574,7 +16250,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #24]\n\t" "adc r5, r5, #0\n\t" "# a[i+7] += m[7] * mu\n\t" - "ldr r7, [%[m], #28]\n\t" + "ldr r7, [%[m], #28]\n\t" "ldr r9, [%[a], #28]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16583,7 +16259,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #28]\n\t" "adc r4, r4, #0\n\t" "# a[i+8] += m[8] * mu\n\t" - "ldr r7, [%[m], #32]\n\t" + "ldr r7, [%[m], #32]\n\t" "ldr r9, [%[a], #32]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16592,7 +16268,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #32]\n\t" "adc r5, r5, #0\n\t" "# a[i+9] += m[9] * mu\n\t" - "ldr r7, [%[m], #36]\n\t" + "ldr r7, [%[m], #36]\n\t" "ldr r9, [%[a], #36]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16601,7 +16277,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #36]\n\t" "adc r4, r4, #0\n\t" "# a[i+10] += m[10] * mu\n\t" - "ldr r7, [%[m], #40]\n\t" + "ldr r7, [%[m], #40]\n\t" "ldr r9, [%[a], #40]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16610,7 +16286,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #40]\n\t" "adc r5, r5, #0\n\t" "# a[i+11] += m[11] * mu\n\t" - "ldr r7, [%[m], #44]\n\t" + "ldr r7, [%[m], #44]\n\t" "ldr r9, [%[a], #44]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16619,7 +16295,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #44]\n\t" "adc r4, r4, #0\n\t" "# a[i+12] += m[12] * mu\n\t" - "ldr r7, [%[m], #48]\n\t" + "ldr r7, [%[m], #48]\n\t" "ldr r9, [%[a], #48]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16628,7 +16304,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #48]\n\t" "adc r5, r5, #0\n\t" "# a[i+13] += m[13] * mu\n\t" - "ldr r7, [%[m], #52]\n\t" + "ldr r7, [%[m], #52]\n\t" "ldr r9, [%[a], #52]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16637,7 +16313,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #52]\n\t" "adc r4, r4, #0\n\t" "# a[i+14] += m[14] * mu\n\t" - "ldr r7, [%[m], #56]\n\t" + "ldr r7, [%[m], #56]\n\t" "ldr r9, [%[a], #56]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16646,7 +16322,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #56]\n\t" "adc r5, r5, #0\n\t" "# a[i+15] += m[15] * mu\n\t" - "ldr r7, [%[m], #60]\n\t" + "ldr r7, [%[m], #60]\n\t" "ldr r9, [%[a], #60]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16655,7 +16331,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #60]\n\t" "adc r4, r4, #0\n\t" "# a[i+16] += m[16] * mu\n\t" - "ldr r7, [%[m], #64]\n\t" + "ldr r7, [%[m], #64]\n\t" "ldr r9, [%[a], #64]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16664,7 +16340,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #64]\n\t" "adc r5, r5, #0\n\t" "# a[i+17] += m[17] * mu\n\t" - "ldr r7, [%[m], #68]\n\t" + "ldr r7, [%[m], #68]\n\t" "ldr r9, [%[a], #68]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16673,7 +16349,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #68]\n\t" "adc r4, r4, #0\n\t" "# a[i+18] += m[18] * mu\n\t" - "ldr r7, [%[m], #72]\n\t" + "ldr r7, [%[m], #72]\n\t" "ldr r9, [%[a], #72]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16682,7 +16358,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #72]\n\t" "adc r5, r5, #0\n\t" "# a[i+19] += m[19] * mu\n\t" - "ldr r7, [%[m], #76]\n\t" + "ldr r7, [%[m], #76]\n\t" "ldr r9, [%[a], #76]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16691,7 +16367,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #76]\n\t" "adc r4, r4, #0\n\t" "# a[i+20] += m[20] * mu\n\t" - "ldr r7, [%[m], #80]\n\t" + "ldr r7, [%[m], #80]\n\t" "ldr r9, [%[a], #80]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16700,7 +16376,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #80]\n\t" "adc r5, r5, #0\n\t" "# a[i+21] += m[21] * mu\n\t" - "ldr r7, [%[m], #84]\n\t" + "ldr r7, [%[m], #84]\n\t" "ldr r9, [%[a], #84]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16709,7 +16385,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #84]\n\t" "adc r4, r4, #0\n\t" "# a[i+22] += m[22] * mu\n\t" - "ldr r7, [%[m], #88]\n\t" + "ldr r7, [%[m], #88]\n\t" "ldr r9, [%[a], #88]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16718,7 +16394,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #88]\n\t" "adc r5, r5, #0\n\t" "# a[i+23] += m[23] * mu\n\t" - "ldr r7, [%[m], #92]\n\t" + "ldr r7, [%[m], #92]\n\t" "ldr r9, [%[a], #92]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16727,7 +16403,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #92]\n\t" "adc r4, r4, #0\n\t" "# a[i+24] += m[24] * mu\n\t" - "ldr r7, [%[m], #96]\n\t" + "ldr r7, [%[m], #96]\n\t" "ldr r9, [%[a], #96]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16736,7 +16412,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #96]\n\t" "adc r5, r5, #0\n\t" "# a[i+25] += m[25] * mu\n\t" - "ldr r7, [%[m], #100]\n\t" + "ldr r7, [%[m], #100]\n\t" "ldr r9, [%[a], #100]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16745,7 +16421,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #100]\n\t" "adc r4, r4, #0\n\t" "# a[i+26] += m[26] * mu\n\t" - "ldr r7, [%[m], #104]\n\t" + "ldr r7, [%[m], #104]\n\t" "ldr r9, [%[a], #104]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16754,7 +16430,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #104]\n\t" "adc r5, r5, #0\n\t" "# a[i+27] += m[27] * mu\n\t" - "ldr r7, [%[m], #108]\n\t" + "ldr r7, [%[m], #108]\n\t" "ldr r9, [%[a], #108]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16763,7 +16439,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #108]\n\t" "adc r4, r4, #0\n\t" "# a[i+28] += m[28] * mu\n\t" - "ldr r7, [%[m], #112]\n\t" + "ldr r7, [%[m], #112]\n\t" "ldr r9, [%[a], #112]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16772,7 +16448,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #112]\n\t" "adc r5, r5, #0\n\t" "# a[i+29] += m[29] * mu\n\t" - "ldr r7, [%[m], #116]\n\t" + "ldr r7, [%[m], #116]\n\t" "ldr r9, [%[a], #116]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16781,7 +16457,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #116]\n\t" "adc r4, r4, #0\n\t" "# a[i+30] += m[30] * mu\n\t" - "ldr r7, [%[m], #120]\n\t" + "ldr r7, [%[m], #120]\n\t" "ldr r9, [%[a], #120]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16790,7 +16466,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #120]\n\t" "adc r5, r5, #0\n\t" "# a[i+31] += m[31] * mu\n\t" - "ldr r7, [%[m], #124]\n\t" + "ldr r7, [%[m], #124]\n\t" "ldr r9, [%[a], #124]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16799,7 +16475,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #124]\n\t" "adc r4, r4, #0\n\t" "# a[i+32] += m[32] * mu\n\t" - "ldr r7, [%[m], #128]\n\t" + "ldr r7, [%[m], #128]\n\t" "ldr r9, [%[a], #128]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16808,7 +16484,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #128]\n\t" "adc r5, r5, #0\n\t" "# a[i+33] += m[33] * mu\n\t" - "ldr r7, [%[m], #132]\n\t" + "ldr r7, [%[m], #132]\n\t" "ldr r9, [%[a], #132]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16817,7 +16493,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #132]\n\t" "adc r4, r4, #0\n\t" "# a[i+34] += m[34] * mu\n\t" - "ldr r7, [%[m], #136]\n\t" + "ldr r7, [%[m], #136]\n\t" "ldr r9, [%[a], #136]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16826,7 +16502,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #136]\n\t" "adc r5, r5, #0\n\t" "# a[i+35] += m[35] * mu\n\t" - "ldr r7, [%[m], #140]\n\t" + "ldr r7, [%[m], #140]\n\t" "ldr r9, [%[a], #140]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16835,7 +16511,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #140]\n\t" "adc r4, r4, #0\n\t" "# a[i+36] += m[36] * mu\n\t" - "ldr r7, [%[m], #144]\n\t" + "ldr r7, [%[m], #144]\n\t" "ldr r9, [%[a], #144]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16844,7 +16520,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #144]\n\t" "adc r5, r5, #0\n\t" "# a[i+37] += m[37] * mu\n\t" - "ldr r7, [%[m], #148]\n\t" + "ldr r7, [%[m], #148]\n\t" "ldr r9, [%[a], #148]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16853,7 +16529,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #148]\n\t" "adc r4, r4, #0\n\t" "# a[i+38] += m[38] * mu\n\t" - "ldr r7, [%[m], #152]\n\t" + "ldr r7, [%[m], #152]\n\t" "ldr r9, [%[a], #152]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16862,7 +16538,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #152]\n\t" "adc r5, r5, #0\n\t" "# a[i+39] += m[39] * mu\n\t" - "ldr r7, [%[m], #156]\n\t" + "ldr r7, [%[m], #156]\n\t" "ldr r9, [%[a], #156]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16871,7 +16547,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #156]\n\t" "adc r4, r4, #0\n\t" "# a[i+40] += m[40] * mu\n\t" - "ldr r7, [%[m], #160]\n\t" + "ldr r7, [%[m], #160]\n\t" "ldr r9, [%[a], #160]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16880,7 +16556,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #160]\n\t" "adc r5, r5, #0\n\t" "# a[i+41] += m[41] * mu\n\t" - "ldr r7, [%[m], #164]\n\t" + "ldr r7, [%[m], #164]\n\t" "ldr r9, [%[a], #164]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16889,7 +16565,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #164]\n\t" "adc r4, r4, #0\n\t" "# a[i+42] += m[42] * mu\n\t" - "ldr r7, [%[m], #168]\n\t" + "ldr r7, [%[m], #168]\n\t" "ldr r9, [%[a], #168]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16898,7 +16574,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #168]\n\t" "adc r5, r5, #0\n\t" "# a[i+43] += m[43] * mu\n\t" - "ldr r7, [%[m], #172]\n\t" + "ldr r7, [%[m], #172]\n\t" "ldr r9, [%[a], #172]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16907,7 +16583,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #172]\n\t" "adc r4, r4, #0\n\t" "# a[i+44] += m[44] * mu\n\t" - "ldr r7, [%[m], #176]\n\t" + "ldr r7, [%[m], #176]\n\t" "ldr r9, [%[a], #176]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16916,7 +16592,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #176]\n\t" "adc r5, r5, #0\n\t" "# a[i+45] += m[45] * mu\n\t" - "ldr r7, [%[m], #180]\n\t" + "ldr r7, [%[m], #180]\n\t" "ldr r9, [%[a], #180]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16925,7 +16601,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #180]\n\t" "adc r4, r4, #0\n\t" "# a[i+46] += m[46] * mu\n\t" - "ldr r7, [%[m], #184]\n\t" + "ldr r7, [%[m], #184]\n\t" "ldr r9, [%[a], #184]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16934,7 +16610,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #184]\n\t" "adc r5, r5, #0\n\t" "# a[i+47] += m[47] * mu\n\t" - "ldr r7, [%[m], #188]\n\t" + "ldr r7, [%[m], #188]\n\t" "ldr r9, [%[a], #188]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16943,7 +16619,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #188]\n\t" "adc r4, r4, #0\n\t" "# a[i+48] += m[48] * mu\n\t" - "ldr r7, [%[m], #192]\n\t" + "ldr r7, [%[m], #192]\n\t" "ldr r9, [%[a], #192]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16952,7 +16628,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #192]\n\t" "adc r5, r5, #0\n\t" "# a[i+49] += m[49] * mu\n\t" - "ldr r7, [%[m], #196]\n\t" + "ldr r7, [%[m], #196]\n\t" "ldr r9, [%[a], #196]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16961,7 +16637,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #196]\n\t" "adc r4, r4, #0\n\t" "# a[i+50] += m[50] * mu\n\t" - "ldr r7, [%[m], #200]\n\t" + "ldr r7, [%[m], #200]\n\t" "ldr r9, [%[a], #200]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16970,7 +16646,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #200]\n\t" "adc r5, r5, #0\n\t" "# a[i+51] += m[51] * mu\n\t" - "ldr r7, [%[m], #204]\n\t" + "ldr r7, [%[m], #204]\n\t" "ldr r9, [%[a], #204]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16979,7 +16655,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #204]\n\t" "adc r4, r4, #0\n\t" "# a[i+52] += m[52] * mu\n\t" - "ldr r7, [%[m], #208]\n\t" + "ldr r7, [%[m], #208]\n\t" "ldr r9, [%[a], #208]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16988,7 +16664,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #208]\n\t" "adc r5, r5, #0\n\t" "# a[i+53] += m[53] * mu\n\t" - "ldr r7, [%[m], #212]\n\t" + "ldr r7, [%[m], #212]\n\t" "ldr r9, [%[a], #212]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -16997,7 +16673,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #212]\n\t" "adc r4, r4, #0\n\t" "# a[i+54] += m[54] * mu\n\t" - "ldr r7, [%[m], #216]\n\t" + "ldr r7, [%[m], #216]\n\t" "ldr r9, [%[a], #216]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17006,7 +16682,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #216]\n\t" "adc r5, r5, #0\n\t" "# a[i+55] += m[55] * mu\n\t" - "ldr r7, [%[m], #220]\n\t" + "ldr r7, [%[m], #220]\n\t" "ldr r9, [%[a], #220]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17015,7 +16691,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #220]\n\t" "adc r4, r4, #0\n\t" "# a[i+56] += m[56] * mu\n\t" - "ldr r7, [%[m], #224]\n\t" + "ldr r7, [%[m], #224]\n\t" "ldr r9, [%[a], #224]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17024,7 +16700,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #224]\n\t" "adc r5, r5, #0\n\t" "# a[i+57] += m[57] * mu\n\t" - "ldr r7, [%[m], #228]\n\t" + "ldr r7, [%[m], #228]\n\t" "ldr r9, [%[a], #228]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17033,7 +16709,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #228]\n\t" "adc r4, r4, #0\n\t" "# a[i+58] += m[58] * mu\n\t" - "ldr r7, [%[m], #232]\n\t" + "ldr r7, [%[m], #232]\n\t" "ldr r9, [%[a], #232]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17042,7 +16718,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #232]\n\t" "adc r5, r5, #0\n\t" "# a[i+59] += m[59] * mu\n\t" - "ldr r7, [%[m], #236]\n\t" + "ldr r7, [%[m], #236]\n\t" "ldr r9, [%[a], #236]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17051,7 +16727,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #236]\n\t" "adc r4, r4, #0\n\t" "# a[i+60] += m[60] * mu\n\t" - "ldr r7, [%[m], #240]\n\t" + "ldr r7, [%[m], #240]\n\t" "ldr r9, [%[a], #240]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17060,7 +16736,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #240]\n\t" "adc r5, r5, #0\n\t" "# a[i+61] += m[61] * mu\n\t" - "ldr r7, [%[m], #244]\n\t" + "ldr r7, [%[m], #244]\n\t" "ldr r9, [%[a], #244]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17069,7 +16745,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #244]\n\t" "adc r4, r4, #0\n\t" "# a[i+62] += m[62] * mu\n\t" - "ldr r7, [%[m], #248]\n\t" + "ldr r7, [%[m], #248]\n\t" "ldr r9, [%[a], #248]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17078,7 +16754,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #248]\n\t" "adc r5, r5, #0\n\t" "# a[i+63] += m[63] * mu\n\t" - "ldr r7, [%[m], #252]\n\t" + "ldr r7, [%[m], #252]\n\t" "ldr r9, [%[a], #252]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17087,7 +16763,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #252]\n\t" "adc r4, r4, #0\n\t" "# a[i+64] += m[64] * mu\n\t" - "ldr r7, [%[m], #256]\n\t" + "ldr r7, [%[m], #256]\n\t" "ldr r9, [%[a], #256]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17096,7 +16772,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #256]\n\t" "adc r5, r5, #0\n\t" "# a[i+65] += m[65] * mu\n\t" - "ldr r7, [%[m], #260]\n\t" + "ldr r7, [%[m], #260]\n\t" "ldr r9, [%[a], #260]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17105,7 +16781,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #260]\n\t" "adc r4, r4, #0\n\t" "# a[i+66] += m[66] * mu\n\t" - "ldr r7, [%[m], #264]\n\t" + "ldr r7, [%[m], #264]\n\t" "ldr r9, [%[a], #264]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17114,7 +16790,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #264]\n\t" "adc r5, r5, #0\n\t" "# a[i+67] += m[67] * mu\n\t" - "ldr r7, [%[m], #268]\n\t" + "ldr r7, [%[m], #268]\n\t" "ldr r9, [%[a], #268]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17123,7 +16799,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #268]\n\t" "adc r4, r4, #0\n\t" "# a[i+68] += m[68] * mu\n\t" - "ldr r7, [%[m], #272]\n\t" + "ldr r7, [%[m], #272]\n\t" "ldr r9, [%[a], #272]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17132,7 +16808,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #272]\n\t" "adc r5, r5, #0\n\t" "# a[i+69] += m[69] * mu\n\t" - "ldr r7, [%[m], #276]\n\t" + "ldr r7, [%[m], #276]\n\t" "ldr r9, [%[a], #276]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17141,7 +16817,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #276]\n\t" "adc r4, r4, #0\n\t" "# a[i+70] += m[70] * mu\n\t" - "ldr r7, [%[m], #280]\n\t" + "ldr r7, [%[m], #280]\n\t" "ldr r9, [%[a], #280]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17150,7 +16826,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #280]\n\t" "adc r5, r5, #0\n\t" "# a[i+71] += m[71] * mu\n\t" - "ldr r7, [%[m], #284]\n\t" + "ldr r7, [%[m], #284]\n\t" "ldr r9, [%[a], #284]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17159,7 +16835,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #284]\n\t" "adc r4, r4, #0\n\t" "# a[i+72] += m[72] * mu\n\t" - "ldr r7, [%[m], #288]\n\t" + "ldr r7, [%[m], #288]\n\t" "ldr r9, [%[a], #288]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17168,7 +16844,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #288]\n\t" "adc r5, r5, #0\n\t" "# a[i+73] += m[73] * mu\n\t" - "ldr r7, [%[m], #292]\n\t" + "ldr r7, [%[m], #292]\n\t" "ldr r9, [%[a], #292]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17177,7 +16853,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #292]\n\t" "adc r4, r4, #0\n\t" "# a[i+74] += m[74] * mu\n\t" - "ldr r7, [%[m], #296]\n\t" + "ldr r7, [%[m], #296]\n\t" "ldr r9, [%[a], #296]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17186,7 +16862,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #296]\n\t" "adc r5, r5, #0\n\t" "# a[i+75] += m[75] * mu\n\t" - "ldr r7, [%[m], #300]\n\t" + "ldr r7, [%[m], #300]\n\t" "ldr r9, [%[a], #300]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17195,7 +16871,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #300]\n\t" "adc r4, r4, #0\n\t" "# a[i+76] += m[76] * mu\n\t" - "ldr r7, [%[m], #304]\n\t" + "ldr r7, [%[m], #304]\n\t" "ldr r9, [%[a], #304]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17204,7 +16880,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #304]\n\t" "adc r5, r5, #0\n\t" "# a[i+77] += m[77] * mu\n\t" - "ldr r7, [%[m], #308]\n\t" + "ldr r7, [%[m], #308]\n\t" "ldr r9, [%[a], #308]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17213,7 +16889,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #308]\n\t" "adc r4, r4, #0\n\t" "# a[i+78] += m[78] * mu\n\t" - "ldr r7, [%[m], #312]\n\t" + "ldr r7, [%[m], #312]\n\t" "ldr r9, [%[a], #312]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17222,7 +16898,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #312]\n\t" "adc r5, r5, #0\n\t" "# a[i+79] += m[79] * mu\n\t" - "ldr r7, [%[m], #316]\n\t" + "ldr r7, [%[m], #316]\n\t" "ldr r9, [%[a], #316]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17231,7 +16907,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #316]\n\t" "adc r4, r4, #0\n\t" "# a[i+80] += m[80] * mu\n\t" - "ldr r7, [%[m], #320]\n\t" + "ldr r7, [%[m], #320]\n\t" "ldr r9, [%[a], #320]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17240,7 +16916,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #320]\n\t" "adc r5, r5, #0\n\t" "# a[i+81] += m[81] * mu\n\t" - "ldr r7, [%[m], #324]\n\t" + "ldr r7, [%[m], #324]\n\t" "ldr r9, [%[a], #324]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17249,7 +16925,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #324]\n\t" "adc r4, r4, #0\n\t" "# a[i+82] += m[82] * mu\n\t" - "ldr r7, [%[m], #328]\n\t" + "ldr r7, [%[m], #328]\n\t" "ldr r9, [%[a], #328]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17258,7 +16934,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #328]\n\t" "adc r5, r5, #0\n\t" "# a[i+83] += m[83] * mu\n\t" - "ldr r7, [%[m], #332]\n\t" + "ldr r7, [%[m], #332]\n\t" "ldr r9, [%[a], #332]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17267,7 +16943,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #332]\n\t" "adc r4, r4, #0\n\t" "# a[i+84] += m[84] * mu\n\t" - "ldr r7, [%[m], #336]\n\t" + "ldr r7, [%[m], #336]\n\t" "ldr r9, [%[a], #336]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17276,7 +16952,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #336]\n\t" "adc r5, r5, #0\n\t" "# a[i+85] += m[85] * mu\n\t" - "ldr r7, [%[m], #340]\n\t" + "ldr r7, [%[m], #340]\n\t" "ldr r9, [%[a], #340]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17285,7 +16961,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #340]\n\t" "adc r4, r4, #0\n\t" "# a[i+86] += m[86] * mu\n\t" - "ldr r7, [%[m], #344]\n\t" + "ldr r7, [%[m], #344]\n\t" "ldr r9, [%[a], #344]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17294,7 +16970,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #344]\n\t" "adc r5, r5, #0\n\t" "# a[i+87] += m[87] * mu\n\t" - "ldr r7, [%[m], #348]\n\t" + "ldr r7, [%[m], #348]\n\t" "ldr r9, [%[a], #348]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17303,7 +16979,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #348]\n\t" "adc r4, r4, #0\n\t" "# a[i+88] += m[88] * mu\n\t" - "ldr r7, [%[m], #352]\n\t" + "ldr r7, [%[m], #352]\n\t" "ldr r9, [%[a], #352]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17312,7 +16988,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #352]\n\t" "adc r5, r5, #0\n\t" "# a[i+89] += m[89] * mu\n\t" - "ldr r7, [%[m], #356]\n\t" + "ldr r7, [%[m], #356]\n\t" "ldr r9, [%[a], #356]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17321,7 +16997,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #356]\n\t" "adc r4, r4, #0\n\t" "# a[i+90] += m[90] * mu\n\t" - "ldr r7, [%[m], #360]\n\t" + "ldr r7, [%[m], #360]\n\t" "ldr r9, [%[a], #360]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17330,7 +17006,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #360]\n\t" "adc r5, r5, #0\n\t" "# a[i+91] += m[91] * mu\n\t" - "ldr r7, [%[m], #364]\n\t" + "ldr r7, [%[m], #364]\n\t" "ldr r9, [%[a], #364]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17339,7 +17015,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #364]\n\t" "adc r4, r4, #0\n\t" "# a[i+92] += m[92] * mu\n\t" - "ldr r7, [%[m], #368]\n\t" + "ldr r7, [%[m], #368]\n\t" "ldr r9, [%[a], #368]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17348,7 +17024,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #368]\n\t" "adc r5, r5, #0\n\t" "# a[i+93] += m[93] * mu\n\t" - "ldr r7, [%[m], #372]\n\t" + "ldr r7, [%[m], #372]\n\t" "ldr r9, [%[a], #372]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17357,7 +17033,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r9, [%[a], #372]\n\t" "adc r4, r4, #0\n\t" "# a[i+94] += m[94] * mu\n\t" - "ldr r7, [%[m], #376]\n\t" + "ldr r7, [%[m], #376]\n\t" "ldr r9, [%[a], #376]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -17388,7 +17064,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, "str r14, [%[a], #4]\n\t" : [ca] "+r" (ca), [a] "+r" (a) : [m] "r" (m), [mp] "r" (mp) - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12", "r11" ); sp_3072_cond_sub_96(a - 96, a, m, (sp_digit)0 - ca); @@ -17403,8 +17079,8 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_mul_96(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_3072_mont_mul_96(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_3072_mul_96(r, a, b); sp_3072_mont_reduce_96(r, m, mp); @@ -17417,8 +17093,8 @@ static void sp_3072_mont_mul_96(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_sqr_96(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_3072_mont_sqr_96(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_3072_sqr_96(r, a); sp_3072_mont_reduce_96(r, m, mp); @@ -18756,7 +18432,8 @@ static int sp_3072_mod_exp_96(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -18822,34 +18499,34 @@ static int sp_3072_mod_exp_96(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 96); for (; i>=0 || c>=4; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 28); + y = (byte)(n >> 28); n <<= 4; c = 28; } else if (c < 4) { - y = (int)(n >> 28); + y = (byte)(n >> 28); n = e[i--]; c = 4 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 28) & 0xf); + y = (byte)((n >> 28) & 0xf); n <<= 4; c -= 4; } @@ -18901,7 +18578,8 @@ static int sp_3072_mod_exp_96(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -18983,34 +18661,34 @@ static int sp_3072_mod_exp_96(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 96); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -19055,11 +18733,13 @@ static int sp_3072_mod_exp_96(sp_digit* r, const sp_digit* a, const sp_digit* e, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPublic_3072(const byte* in, word32 inLen, const mp_int* em, + const mp_int* mm, byte* out, word32* outLen) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_digit a[192], m[96], r[192]; + sp_digit a[192]; + sp_digit m[96]; + sp_digit r[192]; #else sp_digit* d = NULL; sp_digit* a = NULL; @@ -19482,9 +19162,9 @@ static sp_digit sp_3072_cond_add_48(sp_digit* r, const sp_digit* a, const sp_dig * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_3072(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM) sp_digit* a = NULL; @@ -19548,8 +19228,11 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, #else #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit a[96 * 2]; - sp_digit p[48], q[48], dp[48]; - sp_digit tmpa[96], tmpb[96]; + sp_digit p[48]; + sp_digit q[48]; + sp_digit dp[48]; + sp_digit tmpa[96]; + sp_digit tmpb[96]; #else sp_digit* t = NULL; sp_digit* a = NULL; @@ -19646,7 +19329,7 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, XMEMSET(q, 0, sizeof(q)); XMEMSET(dp, 0, sizeof(dp)); #endif -#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */ +#endif /* SP_RSA_PRIVATE_EXP_D | RSA_LOW_MEM */ return err; } #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -19669,17 +19352,19 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->used = 96; mp_clamp(r); #elif DIGIT_BIT < 32 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 96; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -19692,14 +19377,16 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 96; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 32 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -19726,10 +19413,13 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_3072(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[192], e[96], m[96]; + sp_digit b[192]; + sp_digit e[96]; + sp_digit m[96]; sp_digit* r = b; int expBits = mp_count_bits(exp); @@ -20372,10 +20062,12 @@ static int sp_3072_mod_exp_2_96(sp_digit* r, const sp_digit* e, int bits, sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -20410,34 +20102,34 @@ static int sp_3072_mod_exp_2_96(sp_digit* r, const sp_digit* e, int bits, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } - sp_3072_lshift_96(r, norm, (byte)y); + sp_3072_lshift_96(r, norm, y); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -20448,7 +20140,7 @@ static int sp_3072_mod_exp_2_96(sp_digit* r, const sp_digit* e, int bits, sp_3072_mont_sqr_96(r, r, m, mp); sp_3072_mont_sqr_96(r, r, m, mp); - sp_3072_lshift_96(r, r, (byte)y); + sp_3072_lshift_96(r, r, y); sp_3072_mul_d_96(tmp, norm, r[96]); r[96] = 0; o = sp_3072_add_96(r, r, tmp); @@ -20484,11 +20176,13 @@ static int sp_3072_mod_exp_2_96(sp_digit* r, const sp_digit* e, int bits, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, - mp_int* mod, byte* out, word32* outLen) +int sp_DhExp_3072(const mp_int* base, const byte* exp, word32 expLen, + const mp_int* mod, byte* out, word32* outLen) { int err = MP_OKAY; - sp_digit b[192], e[96], m[96]; + sp_digit b[192]; + sp_digit e[96]; + sp_digit m[96]; sp_digit* r = b; word32 i; @@ -20523,6 +20217,7 @@ int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, sp_3072_to_bin(r, out); *outLen = 384; for (i=0; i<384 && out[i] == 0; i++) { + /* Search for first non-zero. */ } *outLen -= i; XMEMMOVE(out, out + i, *outLen); @@ -20544,10 +20239,13 @@ int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_1536(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[96], e[48], m[48]; + sp_digit b[96]; + sp_digit e[48]; + sp_digit m[48]; sp_digit* r = b; int expBits = mp_count_bits(exp); @@ -20584,7 +20282,7 @@ int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) return err; } -#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */ +#endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */ #endif /* !WOLFSSL_SP_NO_3072 */ @@ -20598,7 +20296,8 @@ int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) */ static void sp_4096_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -20640,7 +20339,8 @@ static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 32 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -20674,7 +20374,9 @@ static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -20713,7 +20415,10 @@ static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a) */ static void sp_4096_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; j = 4096 / 8 - 1; a[j] = 0; @@ -21822,7 +21527,9 @@ SP_NOINLINE static void sp_4096_mul_128(sp_digit* r, const sp_digit* a, sp_digit a1[64]; sp_digit b1[64]; sp_digit z2[128]; - sp_digit u, ca, cb; + sp_digit u; + sp_digit ca; + sp_digit cb; ca = sp_2048_add_64(a1, a, &a[64]); cb = sp_2048_add_64(b1, b, &b[64]); @@ -22101,7 +21808,8 @@ static void sp_4096_sqr_128(sp_digit* r, const sp_digit* a) */ static void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho) { - sp_digit x, b; + sp_digit x; + sp_digit b; b = a[0]; x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ @@ -22110,7 +21818,7 @@ static void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho) x *= 2 - b * x; /* here x*a==1 mod 2**32 */ /* rho = -1/m mod b */ - *rho = -x; + *rho = (sp_digit)0 - x; } /* Mul a by digit b into r. (r = a * b) @@ -22160,1011 +21868,885 @@ static void sp_4096_mul_d_128(sp_digit* r, const sp_digit* a, "str r3, [%[r]]\n\t" "# A[1] * B\n\t" "ldr r8, [%[a], #4]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #4]\n\t" "# A[2] * B\n\t" "ldr r8, [%[a], #8]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #8]\n\t" "# A[3] * B\n\t" "ldr r8, [%[a], #12]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #12]\n\t" "# A[4] * B\n\t" "ldr r8, [%[a], #16]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #16]\n\t" "# A[5] * B\n\t" "ldr r8, [%[a], #20]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #20]\n\t" "# A[6] * B\n\t" "ldr r8, [%[a], #24]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #24]\n\t" "# A[7] * B\n\t" "ldr r8, [%[a], #28]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #28]\n\t" "# A[8] * B\n\t" "ldr r8, [%[a], #32]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #32]\n\t" "# A[9] * B\n\t" "ldr r8, [%[a], #36]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #36]\n\t" "# A[10] * B\n\t" "ldr r8, [%[a], #40]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #40]\n\t" "# A[11] * B\n\t" "ldr r8, [%[a], #44]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #44]\n\t" "# A[12] * B\n\t" "ldr r8, [%[a], #48]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #48]\n\t" "# A[13] * B\n\t" "ldr r8, [%[a], #52]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #52]\n\t" "# A[14] * B\n\t" "ldr r8, [%[a], #56]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #56]\n\t" "# A[15] * B\n\t" "ldr r8, [%[a], #60]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #60]\n\t" "# A[16] * B\n\t" "ldr r8, [%[a], #64]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #64]\n\t" "# A[17] * B\n\t" "ldr r8, [%[a], #68]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #68]\n\t" "# A[18] * B\n\t" "ldr r8, [%[a], #72]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #72]\n\t" "# A[19] * B\n\t" "ldr r8, [%[a], #76]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #76]\n\t" "# A[20] * B\n\t" "ldr r8, [%[a], #80]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #80]\n\t" "# A[21] * B\n\t" "ldr r8, [%[a], #84]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #84]\n\t" "# A[22] * B\n\t" "ldr r8, [%[a], #88]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #88]\n\t" "# A[23] * B\n\t" "ldr r8, [%[a], #92]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #92]\n\t" "# A[24] * B\n\t" "ldr r8, [%[a], #96]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #96]\n\t" "# A[25] * B\n\t" "ldr r8, [%[a], #100]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #100]\n\t" "# A[26] * B\n\t" "ldr r8, [%[a], #104]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #104]\n\t" "# A[27] * B\n\t" "ldr r8, [%[a], #108]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #108]\n\t" "# A[28] * B\n\t" "ldr r8, [%[a], #112]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #112]\n\t" "# A[29] * B\n\t" "ldr r8, [%[a], #116]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #116]\n\t" "# A[30] * B\n\t" "ldr r8, [%[a], #120]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #120]\n\t" "# A[31] * B\n\t" "ldr r8, [%[a], #124]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #124]\n\t" "# A[32] * B\n\t" "ldr r8, [%[a], #128]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #128]\n\t" "# A[33] * B\n\t" "ldr r8, [%[a], #132]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #132]\n\t" "# A[34] * B\n\t" "ldr r8, [%[a], #136]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #136]\n\t" "# A[35] * B\n\t" "ldr r8, [%[a], #140]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #140]\n\t" "# A[36] * B\n\t" "ldr r8, [%[a], #144]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #144]\n\t" "# A[37] * B\n\t" "ldr r8, [%[a], #148]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #148]\n\t" "# A[38] * B\n\t" "ldr r8, [%[a], #152]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #152]\n\t" "# A[39] * B\n\t" "ldr r8, [%[a], #156]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #156]\n\t" "# A[40] * B\n\t" "ldr r8, [%[a], #160]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #160]\n\t" "# A[41] * B\n\t" "ldr r8, [%[a], #164]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #164]\n\t" "# A[42] * B\n\t" "ldr r8, [%[a], #168]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #168]\n\t" "# A[43] * B\n\t" "ldr r8, [%[a], #172]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #172]\n\t" "# A[44] * B\n\t" "ldr r8, [%[a], #176]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #176]\n\t" "# A[45] * B\n\t" "ldr r8, [%[a], #180]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #180]\n\t" "# A[46] * B\n\t" "ldr r8, [%[a], #184]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #184]\n\t" "# A[47] * B\n\t" "ldr r8, [%[a], #188]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #188]\n\t" "# A[48] * B\n\t" "ldr r8, [%[a], #192]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #192]\n\t" "# A[49] * B\n\t" "ldr r8, [%[a], #196]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #196]\n\t" "# A[50] * B\n\t" "ldr r8, [%[a], #200]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #200]\n\t" "# A[51] * B\n\t" "ldr r8, [%[a], #204]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #204]\n\t" "# A[52] * B\n\t" "ldr r8, [%[a], #208]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #208]\n\t" "# A[53] * B\n\t" "ldr r8, [%[a], #212]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #212]\n\t" "# A[54] * B\n\t" "ldr r8, [%[a], #216]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #216]\n\t" "# A[55] * B\n\t" "ldr r8, [%[a], #220]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #220]\n\t" "# A[56] * B\n\t" "ldr r8, [%[a], #224]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #224]\n\t" "# A[57] * B\n\t" "ldr r8, [%[a], #228]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #228]\n\t" "# A[58] * B\n\t" "ldr r8, [%[a], #232]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #232]\n\t" "# A[59] * B\n\t" "ldr r8, [%[a], #236]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #236]\n\t" "# A[60] * B\n\t" "ldr r8, [%[a], #240]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #240]\n\t" "# A[61] * B\n\t" "ldr r8, [%[a], #244]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #244]\n\t" "# A[62] * B\n\t" "ldr r8, [%[a], #248]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #248]\n\t" "# A[63] * B\n\t" "ldr r8, [%[a], #252]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #252]\n\t" "# A[64] * B\n\t" "ldr r8, [%[a], #256]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #256]\n\t" "# A[65] * B\n\t" "ldr r8, [%[a], #260]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #260]\n\t" "# A[66] * B\n\t" "ldr r8, [%[a], #264]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #264]\n\t" "# A[67] * B\n\t" "ldr r8, [%[a], #268]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #268]\n\t" "# A[68] * B\n\t" "ldr r8, [%[a], #272]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #272]\n\t" "# A[69] * B\n\t" "ldr r8, [%[a], #276]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #276]\n\t" "# A[70] * B\n\t" "ldr r8, [%[a], #280]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #280]\n\t" "# A[71] * B\n\t" "ldr r8, [%[a], #284]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #284]\n\t" "# A[72] * B\n\t" "ldr r8, [%[a], #288]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #288]\n\t" "# A[73] * B\n\t" "ldr r8, [%[a], #292]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #292]\n\t" "# A[74] * B\n\t" "ldr r8, [%[a], #296]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #296]\n\t" "# A[75] * B\n\t" "ldr r8, [%[a], #300]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #300]\n\t" "# A[76] * B\n\t" "ldr r8, [%[a], #304]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #304]\n\t" "# A[77] * B\n\t" "ldr r8, [%[a], #308]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #308]\n\t" "# A[78] * B\n\t" "ldr r8, [%[a], #312]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #312]\n\t" "# A[79] * B\n\t" "ldr r8, [%[a], #316]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #316]\n\t" "# A[80] * B\n\t" "ldr r8, [%[a], #320]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #320]\n\t" "# A[81] * B\n\t" "ldr r8, [%[a], #324]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #324]\n\t" "# A[82] * B\n\t" "ldr r8, [%[a], #328]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #328]\n\t" "# A[83] * B\n\t" "ldr r8, [%[a], #332]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #332]\n\t" "# A[84] * B\n\t" "ldr r8, [%[a], #336]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #336]\n\t" "# A[85] * B\n\t" "ldr r8, [%[a], #340]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #340]\n\t" "# A[86] * B\n\t" "ldr r8, [%[a], #344]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #344]\n\t" "# A[87] * B\n\t" "ldr r8, [%[a], #348]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #348]\n\t" "# A[88] * B\n\t" "ldr r8, [%[a], #352]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #352]\n\t" "# A[89] * B\n\t" "ldr r8, [%[a], #356]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #356]\n\t" "# A[90] * B\n\t" "ldr r8, [%[a], #360]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #360]\n\t" "# A[91] * B\n\t" "ldr r8, [%[a], #364]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #364]\n\t" "# A[92] * B\n\t" "ldr r8, [%[a], #368]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #368]\n\t" "# A[93] * B\n\t" "ldr r8, [%[a], #372]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #372]\n\t" "# A[94] * B\n\t" "ldr r8, [%[a], #376]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #376]\n\t" "# A[95] * B\n\t" "ldr r8, [%[a], #380]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #380]\n\t" "# A[96] * B\n\t" "ldr r8, [%[a], #384]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #384]\n\t" "# A[97] * B\n\t" "ldr r8, [%[a], #388]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #388]\n\t" "# A[98] * B\n\t" "ldr r8, [%[a], #392]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #392]\n\t" "# A[99] * B\n\t" "ldr r8, [%[a], #396]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #396]\n\t" "# A[100] * B\n\t" "ldr r8, [%[a], #400]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #400]\n\t" "# A[101] * B\n\t" "ldr r8, [%[a], #404]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #404]\n\t" "# A[102] * B\n\t" "ldr r8, [%[a], #408]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #408]\n\t" "# A[103] * B\n\t" "ldr r8, [%[a], #412]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #412]\n\t" "# A[104] * B\n\t" "ldr r8, [%[a], #416]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #416]\n\t" "# A[105] * B\n\t" "ldr r8, [%[a], #420]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #420]\n\t" "# A[106] * B\n\t" "ldr r8, [%[a], #424]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #424]\n\t" "# A[107] * B\n\t" "ldr r8, [%[a], #428]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #428]\n\t" "# A[108] * B\n\t" "ldr r8, [%[a], #432]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #432]\n\t" "# A[109] * B\n\t" "ldr r8, [%[a], #436]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #436]\n\t" "# A[110] * B\n\t" "ldr r8, [%[a], #440]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #440]\n\t" "# A[111] * B\n\t" "ldr r8, [%[a], #444]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #444]\n\t" "# A[112] * B\n\t" "ldr r8, [%[a], #448]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #448]\n\t" "# A[113] * B\n\t" "ldr r8, [%[a], #452]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #452]\n\t" "# A[114] * B\n\t" "ldr r8, [%[a], #456]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #456]\n\t" "# A[115] * B\n\t" "ldr r8, [%[a], #460]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #460]\n\t" "# A[116] * B\n\t" "ldr r8, [%[a], #464]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #464]\n\t" "# A[117] * B\n\t" "ldr r8, [%[a], #468]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #468]\n\t" "# A[118] * B\n\t" "ldr r8, [%[a], #472]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #472]\n\t" "# A[119] * B\n\t" "ldr r8, [%[a], #476]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #476]\n\t" "# A[120] * B\n\t" "ldr r8, [%[a], #480]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #480]\n\t" "# A[121] * B\n\t" "ldr r8, [%[a], #484]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #484]\n\t" "# A[122] * B\n\t" "ldr r8, [%[a], #488]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #488]\n\t" "# A[123] * B\n\t" "ldr r8, [%[a], #492]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #492]\n\t" "# A[124] * B\n\t" "ldr r8, [%[a], #496]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #496]\n\t" "# A[125] * B\n\t" "ldr r8, [%[a], #500]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #500]\n\t" "# A[126] * B\n\t" "ldr r8, [%[a], #504]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #504]\n\t" "# A[127] * B\n\t" "ldr r8, [%[a], #508]\n\t" @@ -23195,7 +22777,7 @@ static void sp_4096_mont_norm_128(sp_digit* r, const sp_digit* m) sp_4096_sub_in_place_128(r, m); } -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */ /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -23894,6 +23476,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, sp_digit ca = 0; __asm__ __volatile__ ( + "ldr r11, [%[m], #0]\n\t" "# i = 0\n\t" "mov r12, #0\n\t" "ldr r10, [%[a], #0]\n\t" @@ -23902,13 +23485,12 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "# mu = a[i] * mp\n\t" "mul r8, %[mp], r10\n\t" "# a[i+0] += m[0] * mu\n\t" - "ldr r7, [%[m], #0]\n\t" "ldr r9, [%[a], #0]\n\t" - "umull r6, r7, r8, r7\n\t" + "umull r6, r7, r8, r11\n\t" "adds r10, r10, r6\n\t" "adc r5, r7, #0\n\t" "# a[i+1] += m[1] * mu\n\t" - "ldr r7, [%[m], #4]\n\t" + "ldr r7, [%[m], #4]\n\t" "ldr r9, [%[a], #4]\n\t" "umull r6, r7, r8, r7\n\t" "adds r10, r14, r6\n\t" @@ -23916,7 +23498,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "adds r10, r10, r5\n\t" "adc r4, r4, #0\n\t" "# a[i+2] += m[2] * mu\n\t" - "ldr r7, [%[m], #8]\n\t" + "ldr r7, [%[m], #8]\n\t" "ldr r14, [%[a], #8]\n\t" "umull r6, r7, r8, r7\n\t" "adds r14, r14, r6\n\t" @@ -23924,7 +23506,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "adds r14, r14, r4\n\t" "adc r5, r5, #0\n\t" "# a[i+3] += m[3] * mu\n\t" - "ldr r7, [%[m], #12]\n\t" + "ldr r7, [%[m], #12]\n\t" "ldr r9, [%[a], #12]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -23933,7 +23515,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #12]\n\t" "adc r4, r4, #0\n\t" "# a[i+4] += m[4] * mu\n\t" - "ldr r7, [%[m], #16]\n\t" + "ldr r7, [%[m], #16]\n\t" "ldr r9, [%[a], #16]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -23942,7 +23524,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #16]\n\t" "adc r5, r5, #0\n\t" "# a[i+5] += m[5] * mu\n\t" - "ldr r7, [%[m], #20]\n\t" + "ldr r7, [%[m], #20]\n\t" "ldr r9, [%[a], #20]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -23951,7 +23533,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #20]\n\t" "adc r4, r4, #0\n\t" "# a[i+6] += m[6] * mu\n\t" - "ldr r7, [%[m], #24]\n\t" + "ldr r7, [%[m], #24]\n\t" "ldr r9, [%[a], #24]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -23960,7 +23542,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #24]\n\t" "adc r5, r5, #0\n\t" "# a[i+7] += m[7] * mu\n\t" - "ldr r7, [%[m], #28]\n\t" + "ldr r7, [%[m], #28]\n\t" "ldr r9, [%[a], #28]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -23969,7 +23551,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #28]\n\t" "adc r4, r4, #0\n\t" "# a[i+8] += m[8] * mu\n\t" - "ldr r7, [%[m], #32]\n\t" + "ldr r7, [%[m], #32]\n\t" "ldr r9, [%[a], #32]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -23978,7 +23560,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #32]\n\t" "adc r5, r5, #0\n\t" "# a[i+9] += m[9] * mu\n\t" - "ldr r7, [%[m], #36]\n\t" + "ldr r7, [%[m], #36]\n\t" "ldr r9, [%[a], #36]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -23987,7 +23569,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #36]\n\t" "adc r4, r4, #0\n\t" "# a[i+10] += m[10] * mu\n\t" - "ldr r7, [%[m], #40]\n\t" + "ldr r7, [%[m], #40]\n\t" "ldr r9, [%[a], #40]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -23996,7 +23578,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #40]\n\t" "adc r5, r5, #0\n\t" "# a[i+11] += m[11] * mu\n\t" - "ldr r7, [%[m], #44]\n\t" + "ldr r7, [%[m], #44]\n\t" "ldr r9, [%[a], #44]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24005,7 +23587,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #44]\n\t" "adc r4, r4, #0\n\t" "# a[i+12] += m[12] * mu\n\t" - "ldr r7, [%[m], #48]\n\t" + "ldr r7, [%[m], #48]\n\t" "ldr r9, [%[a], #48]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24014,7 +23596,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #48]\n\t" "adc r5, r5, #0\n\t" "# a[i+13] += m[13] * mu\n\t" - "ldr r7, [%[m], #52]\n\t" + "ldr r7, [%[m], #52]\n\t" "ldr r9, [%[a], #52]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24023,7 +23605,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #52]\n\t" "adc r4, r4, #0\n\t" "# a[i+14] += m[14] * mu\n\t" - "ldr r7, [%[m], #56]\n\t" + "ldr r7, [%[m], #56]\n\t" "ldr r9, [%[a], #56]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24032,7 +23614,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #56]\n\t" "adc r5, r5, #0\n\t" "# a[i+15] += m[15] * mu\n\t" - "ldr r7, [%[m], #60]\n\t" + "ldr r7, [%[m], #60]\n\t" "ldr r9, [%[a], #60]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24041,7 +23623,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #60]\n\t" "adc r4, r4, #0\n\t" "# a[i+16] += m[16] * mu\n\t" - "ldr r7, [%[m], #64]\n\t" + "ldr r7, [%[m], #64]\n\t" "ldr r9, [%[a], #64]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24050,7 +23632,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #64]\n\t" "adc r5, r5, #0\n\t" "# a[i+17] += m[17] * mu\n\t" - "ldr r7, [%[m], #68]\n\t" + "ldr r7, [%[m], #68]\n\t" "ldr r9, [%[a], #68]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24059,7 +23641,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #68]\n\t" "adc r4, r4, #0\n\t" "# a[i+18] += m[18] * mu\n\t" - "ldr r7, [%[m], #72]\n\t" + "ldr r7, [%[m], #72]\n\t" "ldr r9, [%[a], #72]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24068,7 +23650,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #72]\n\t" "adc r5, r5, #0\n\t" "# a[i+19] += m[19] * mu\n\t" - "ldr r7, [%[m], #76]\n\t" + "ldr r7, [%[m], #76]\n\t" "ldr r9, [%[a], #76]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24077,7 +23659,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #76]\n\t" "adc r4, r4, #0\n\t" "# a[i+20] += m[20] * mu\n\t" - "ldr r7, [%[m], #80]\n\t" + "ldr r7, [%[m], #80]\n\t" "ldr r9, [%[a], #80]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24086,7 +23668,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #80]\n\t" "adc r5, r5, #0\n\t" "# a[i+21] += m[21] * mu\n\t" - "ldr r7, [%[m], #84]\n\t" + "ldr r7, [%[m], #84]\n\t" "ldr r9, [%[a], #84]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24095,7 +23677,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #84]\n\t" "adc r4, r4, #0\n\t" "# a[i+22] += m[22] * mu\n\t" - "ldr r7, [%[m], #88]\n\t" + "ldr r7, [%[m], #88]\n\t" "ldr r9, [%[a], #88]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24104,7 +23686,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #88]\n\t" "adc r5, r5, #0\n\t" "# a[i+23] += m[23] * mu\n\t" - "ldr r7, [%[m], #92]\n\t" + "ldr r7, [%[m], #92]\n\t" "ldr r9, [%[a], #92]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24113,7 +23695,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #92]\n\t" "adc r4, r4, #0\n\t" "# a[i+24] += m[24] * mu\n\t" - "ldr r7, [%[m], #96]\n\t" + "ldr r7, [%[m], #96]\n\t" "ldr r9, [%[a], #96]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24122,7 +23704,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #96]\n\t" "adc r5, r5, #0\n\t" "# a[i+25] += m[25] * mu\n\t" - "ldr r7, [%[m], #100]\n\t" + "ldr r7, [%[m], #100]\n\t" "ldr r9, [%[a], #100]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24131,7 +23713,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #100]\n\t" "adc r4, r4, #0\n\t" "# a[i+26] += m[26] * mu\n\t" - "ldr r7, [%[m], #104]\n\t" + "ldr r7, [%[m], #104]\n\t" "ldr r9, [%[a], #104]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24140,7 +23722,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #104]\n\t" "adc r5, r5, #0\n\t" "# a[i+27] += m[27] * mu\n\t" - "ldr r7, [%[m], #108]\n\t" + "ldr r7, [%[m], #108]\n\t" "ldr r9, [%[a], #108]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24149,7 +23731,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #108]\n\t" "adc r4, r4, #0\n\t" "# a[i+28] += m[28] * mu\n\t" - "ldr r7, [%[m], #112]\n\t" + "ldr r7, [%[m], #112]\n\t" "ldr r9, [%[a], #112]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24158,7 +23740,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #112]\n\t" "adc r5, r5, #0\n\t" "# a[i+29] += m[29] * mu\n\t" - "ldr r7, [%[m], #116]\n\t" + "ldr r7, [%[m], #116]\n\t" "ldr r9, [%[a], #116]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24167,7 +23749,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #116]\n\t" "adc r4, r4, #0\n\t" "# a[i+30] += m[30] * mu\n\t" - "ldr r7, [%[m], #120]\n\t" + "ldr r7, [%[m], #120]\n\t" "ldr r9, [%[a], #120]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24176,7 +23758,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #120]\n\t" "adc r5, r5, #0\n\t" "# a[i+31] += m[31] * mu\n\t" - "ldr r7, [%[m], #124]\n\t" + "ldr r7, [%[m], #124]\n\t" "ldr r9, [%[a], #124]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24185,7 +23767,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #124]\n\t" "adc r4, r4, #0\n\t" "# a[i+32] += m[32] * mu\n\t" - "ldr r7, [%[m], #128]\n\t" + "ldr r7, [%[m], #128]\n\t" "ldr r9, [%[a], #128]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24194,7 +23776,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #128]\n\t" "adc r5, r5, #0\n\t" "# a[i+33] += m[33] * mu\n\t" - "ldr r7, [%[m], #132]\n\t" + "ldr r7, [%[m], #132]\n\t" "ldr r9, [%[a], #132]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24203,7 +23785,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #132]\n\t" "adc r4, r4, #0\n\t" "# a[i+34] += m[34] * mu\n\t" - "ldr r7, [%[m], #136]\n\t" + "ldr r7, [%[m], #136]\n\t" "ldr r9, [%[a], #136]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24212,7 +23794,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #136]\n\t" "adc r5, r5, #0\n\t" "# a[i+35] += m[35] * mu\n\t" - "ldr r7, [%[m], #140]\n\t" + "ldr r7, [%[m], #140]\n\t" "ldr r9, [%[a], #140]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24221,7 +23803,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #140]\n\t" "adc r4, r4, #0\n\t" "# a[i+36] += m[36] * mu\n\t" - "ldr r7, [%[m], #144]\n\t" + "ldr r7, [%[m], #144]\n\t" "ldr r9, [%[a], #144]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24230,7 +23812,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #144]\n\t" "adc r5, r5, #0\n\t" "# a[i+37] += m[37] * mu\n\t" - "ldr r7, [%[m], #148]\n\t" + "ldr r7, [%[m], #148]\n\t" "ldr r9, [%[a], #148]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24239,7 +23821,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #148]\n\t" "adc r4, r4, #0\n\t" "# a[i+38] += m[38] * mu\n\t" - "ldr r7, [%[m], #152]\n\t" + "ldr r7, [%[m], #152]\n\t" "ldr r9, [%[a], #152]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24248,7 +23830,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #152]\n\t" "adc r5, r5, #0\n\t" "# a[i+39] += m[39] * mu\n\t" - "ldr r7, [%[m], #156]\n\t" + "ldr r7, [%[m], #156]\n\t" "ldr r9, [%[a], #156]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24257,7 +23839,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #156]\n\t" "adc r4, r4, #0\n\t" "# a[i+40] += m[40] * mu\n\t" - "ldr r7, [%[m], #160]\n\t" + "ldr r7, [%[m], #160]\n\t" "ldr r9, [%[a], #160]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24266,7 +23848,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #160]\n\t" "adc r5, r5, #0\n\t" "# a[i+41] += m[41] * mu\n\t" - "ldr r7, [%[m], #164]\n\t" + "ldr r7, [%[m], #164]\n\t" "ldr r9, [%[a], #164]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24275,7 +23857,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #164]\n\t" "adc r4, r4, #0\n\t" "# a[i+42] += m[42] * mu\n\t" - "ldr r7, [%[m], #168]\n\t" + "ldr r7, [%[m], #168]\n\t" "ldr r9, [%[a], #168]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24284,7 +23866,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #168]\n\t" "adc r5, r5, #0\n\t" "# a[i+43] += m[43] * mu\n\t" - "ldr r7, [%[m], #172]\n\t" + "ldr r7, [%[m], #172]\n\t" "ldr r9, [%[a], #172]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24293,7 +23875,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #172]\n\t" "adc r4, r4, #0\n\t" "# a[i+44] += m[44] * mu\n\t" - "ldr r7, [%[m], #176]\n\t" + "ldr r7, [%[m], #176]\n\t" "ldr r9, [%[a], #176]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24302,7 +23884,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #176]\n\t" "adc r5, r5, #0\n\t" "# a[i+45] += m[45] * mu\n\t" - "ldr r7, [%[m], #180]\n\t" + "ldr r7, [%[m], #180]\n\t" "ldr r9, [%[a], #180]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24311,7 +23893,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #180]\n\t" "adc r4, r4, #0\n\t" "# a[i+46] += m[46] * mu\n\t" - "ldr r7, [%[m], #184]\n\t" + "ldr r7, [%[m], #184]\n\t" "ldr r9, [%[a], #184]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24320,7 +23902,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #184]\n\t" "adc r5, r5, #0\n\t" "# a[i+47] += m[47] * mu\n\t" - "ldr r7, [%[m], #188]\n\t" + "ldr r7, [%[m], #188]\n\t" "ldr r9, [%[a], #188]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24329,7 +23911,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #188]\n\t" "adc r4, r4, #0\n\t" "# a[i+48] += m[48] * mu\n\t" - "ldr r7, [%[m], #192]\n\t" + "ldr r7, [%[m], #192]\n\t" "ldr r9, [%[a], #192]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24338,7 +23920,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #192]\n\t" "adc r5, r5, #0\n\t" "# a[i+49] += m[49] * mu\n\t" - "ldr r7, [%[m], #196]\n\t" + "ldr r7, [%[m], #196]\n\t" "ldr r9, [%[a], #196]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24347,7 +23929,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #196]\n\t" "adc r4, r4, #0\n\t" "# a[i+50] += m[50] * mu\n\t" - "ldr r7, [%[m], #200]\n\t" + "ldr r7, [%[m], #200]\n\t" "ldr r9, [%[a], #200]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24356,7 +23938,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #200]\n\t" "adc r5, r5, #0\n\t" "# a[i+51] += m[51] * mu\n\t" - "ldr r7, [%[m], #204]\n\t" + "ldr r7, [%[m], #204]\n\t" "ldr r9, [%[a], #204]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24365,7 +23947,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #204]\n\t" "adc r4, r4, #0\n\t" "# a[i+52] += m[52] * mu\n\t" - "ldr r7, [%[m], #208]\n\t" + "ldr r7, [%[m], #208]\n\t" "ldr r9, [%[a], #208]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24374,7 +23956,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #208]\n\t" "adc r5, r5, #0\n\t" "# a[i+53] += m[53] * mu\n\t" - "ldr r7, [%[m], #212]\n\t" + "ldr r7, [%[m], #212]\n\t" "ldr r9, [%[a], #212]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24383,7 +23965,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #212]\n\t" "adc r4, r4, #0\n\t" "# a[i+54] += m[54] * mu\n\t" - "ldr r7, [%[m], #216]\n\t" + "ldr r7, [%[m], #216]\n\t" "ldr r9, [%[a], #216]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24392,7 +23974,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #216]\n\t" "adc r5, r5, #0\n\t" "# a[i+55] += m[55] * mu\n\t" - "ldr r7, [%[m], #220]\n\t" + "ldr r7, [%[m], #220]\n\t" "ldr r9, [%[a], #220]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24401,7 +23983,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #220]\n\t" "adc r4, r4, #0\n\t" "# a[i+56] += m[56] * mu\n\t" - "ldr r7, [%[m], #224]\n\t" + "ldr r7, [%[m], #224]\n\t" "ldr r9, [%[a], #224]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24410,7 +23992,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #224]\n\t" "adc r5, r5, #0\n\t" "# a[i+57] += m[57] * mu\n\t" - "ldr r7, [%[m], #228]\n\t" + "ldr r7, [%[m], #228]\n\t" "ldr r9, [%[a], #228]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24419,7 +24001,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #228]\n\t" "adc r4, r4, #0\n\t" "# a[i+58] += m[58] * mu\n\t" - "ldr r7, [%[m], #232]\n\t" + "ldr r7, [%[m], #232]\n\t" "ldr r9, [%[a], #232]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24428,7 +24010,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #232]\n\t" "adc r5, r5, #0\n\t" "# a[i+59] += m[59] * mu\n\t" - "ldr r7, [%[m], #236]\n\t" + "ldr r7, [%[m], #236]\n\t" "ldr r9, [%[a], #236]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24437,7 +24019,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #236]\n\t" "adc r4, r4, #0\n\t" "# a[i+60] += m[60] * mu\n\t" - "ldr r7, [%[m], #240]\n\t" + "ldr r7, [%[m], #240]\n\t" "ldr r9, [%[a], #240]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24446,7 +24028,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #240]\n\t" "adc r5, r5, #0\n\t" "# a[i+61] += m[61] * mu\n\t" - "ldr r7, [%[m], #244]\n\t" + "ldr r7, [%[m], #244]\n\t" "ldr r9, [%[a], #244]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24455,7 +24037,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #244]\n\t" "adc r4, r4, #0\n\t" "# a[i+62] += m[62] * mu\n\t" - "ldr r7, [%[m], #248]\n\t" + "ldr r7, [%[m], #248]\n\t" "ldr r9, [%[a], #248]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24464,7 +24046,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #248]\n\t" "adc r5, r5, #0\n\t" "# a[i+63] += m[63] * mu\n\t" - "ldr r7, [%[m], #252]\n\t" + "ldr r7, [%[m], #252]\n\t" "ldr r9, [%[a], #252]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24473,7 +24055,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #252]\n\t" "adc r4, r4, #0\n\t" "# a[i+64] += m[64] * mu\n\t" - "ldr r7, [%[m], #256]\n\t" + "ldr r7, [%[m], #256]\n\t" "ldr r9, [%[a], #256]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24482,7 +24064,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #256]\n\t" "adc r5, r5, #0\n\t" "# a[i+65] += m[65] * mu\n\t" - "ldr r7, [%[m], #260]\n\t" + "ldr r7, [%[m], #260]\n\t" "ldr r9, [%[a], #260]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24491,7 +24073,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #260]\n\t" "adc r4, r4, #0\n\t" "# a[i+66] += m[66] * mu\n\t" - "ldr r7, [%[m], #264]\n\t" + "ldr r7, [%[m], #264]\n\t" "ldr r9, [%[a], #264]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24500,7 +24082,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #264]\n\t" "adc r5, r5, #0\n\t" "# a[i+67] += m[67] * mu\n\t" - "ldr r7, [%[m], #268]\n\t" + "ldr r7, [%[m], #268]\n\t" "ldr r9, [%[a], #268]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24509,7 +24091,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #268]\n\t" "adc r4, r4, #0\n\t" "# a[i+68] += m[68] * mu\n\t" - "ldr r7, [%[m], #272]\n\t" + "ldr r7, [%[m], #272]\n\t" "ldr r9, [%[a], #272]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24518,7 +24100,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #272]\n\t" "adc r5, r5, #0\n\t" "# a[i+69] += m[69] * mu\n\t" - "ldr r7, [%[m], #276]\n\t" + "ldr r7, [%[m], #276]\n\t" "ldr r9, [%[a], #276]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24527,7 +24109,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #276]\n\t" "adc r4, r4, #0\n\t" "# a[i+70] += m[70] * mu\n\t" - "ldr r7, [%[m], #280]\n\t" + "ldr r7, [%[m], #280]\n\t" "ldr r9, [%[a], #280]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24536,7 +24118,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #280]\n\t" "adc r5, r5, #0\n\t" "# a[i+71] += m[71] * mu\n\t" - "ldr r7, [%[m], #284]\n\t" + "ldr r7, [%[m], #284]\n\t" "ldr r9, [%[a], #284]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24545,7 +24127,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #284]\n\t" "adc r4, r4, #0\n\t" "# a[i+72] += m[72] * mu\n\t" - "ldr r7, [%[m], #288]\n\t" + "ldr r7, [%[m], #288]\n\t" "ldr r9, [%[a], #288]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24554,7 +24136,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #288]\n\t" "adc r5, r5, #0\n\t" "# a[i+73] += m[73] * mu\n\t" - "ldr r7, [%[m], #292]\n\t" + "ldr r7, [%[m], #292]\n\t" "ldr r9, [%[a], #292]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24563,7 +24145,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #292]\n\t" "adc r4, r4, #0\n\t" "# a[i+74] += m[74] * mu\n\t" - "ldr r7, [%[m], #296]\n\t" + "ldr r7, [%[m], #296]\n\t" "ldr r9, [%[a], #296]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24572,7 +24154,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #296]\n\t" "adc r5, r5, #0\n\t" "# a[i+75] += m[75] * mu\n\t" - "ldr r7, [%[m], #300]\n\t" + "ldr r7, [%[m], #300]\n\t" "ldr r9, [%[a], #300]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24581,7 +24163,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #300]\n\t" "adc r4, r4, #0\n\t" "# a[i+76] += m[76] * mu\n\t" - "ldr r7, [%[m], #304]\n\t" + "ldr r7, [%[m], #304]\n\t" "ldr r9, [%[a], #304]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24590,7 +24172,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #304]\n\t" "adc r5, r5, #0\n\t" "# a[i+77] += m[77] * mu\n\t" - "ldr r7, [%[m], #308]\n\t" + "ldr r7, [%[m], #308]\n\t" "ldr r9, [%[a], #308]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24599,7 +24181,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #308]\n\t" "adc r4, r4, #0\n\t" "# a[i+78] += m[78] * mu\n\t" - "ldr r7, [%[m], #312]\n\t" + "ldr r7, [%[m], #312]\n\t" "ldr r9, [%[a], #312]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24608,7 +24190,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #312]\n\t" "adc r5, r5, #0\n\t" "# a[i+79] += m[79] * mu\n\t" - "ldr r7, [%[m], #316]\n\t" + "ldr r7, [%[m], #316]\n\t" "ldr r9, [%[a], #316]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24617,7 +24199,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #316]\n\t" "adc r4, r4, #0\n\t" "# a[i+80] += m[80] * mu\n\t" - "ldr r7, [%[m], #320]\n\t" + "ldr r7, [%[m], #320]\n\t" "ldr r9, [%[a], #320]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24626,7 +24208,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #320]\n\t" "adc r5, r5, #0\n\t" "# a[i+81] += m[81] * mu\n\t" - "ldr r7, [%[m], #324]\n\t" + "ldr r7, [%[m], #324]\n\t" "ldr r9, [%[a], #324]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24635,7 +24217,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #324]\n\t" "adc r4, r4, #0\n\t" "# a[i+82] += m[82] * mu\n\t" - "ldr r7, [%[m], #328]\n\t" + "ldr r7, [%[m], #328]\n\t" "ldr r9, [%[a], #328]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24644,7 +24226,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #328]\n\t" "adc r5, r5, #0\n\t" "# a[i+83] += m[83] * mu\n\t" - "ldr r7, [%[m], #332]\n\t" + "ldr r7, [%[m], #332]\n\t" "ldr r9, [%[a], #332]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24653,7 +24235,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #332]\n\t" "adc r4, r4, #0\n\t" "# a[i+84] += m[84] * mu\n\t" - "ldr r7, [%[m], #336]\n\t" + "ldr r7, [%[m], #336]\n\t" "ldr r9, [%[a], #336]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24662,7 +24244,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #336]\n\t" "adc r5, r5, #0\n\t" "# a[i+85] += m[85] * mu\n\t" - "ldr r7, [%[m], #340]\n\t" + "ldr r7, [%[m], #340]\n\t" "ldr r9, [%[a], #340]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24671,7 +24253,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #340]\n\t" "adc r4, r4, #0\n\t" "# a[i+86] += m[86] * mu\n\t" - "ldr r7, [%[m], #344]\n\t" + "ldr r7, [%[m], #344]\n\t" "ldr r9, [%[a], #344]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24680,7 +24262,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #344]\n\t" "adc r5, r5, #0\n\t" "# a[i+87] += m[87] * mu\n\t" - "ldr r7, [%[m], #348]\n\t" + "ldr r7, [%[m], #348]\n\t" "ldr r9, [%[a], #348]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24689,7 +24271,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #348]\n\t" "adc r4, r4, #0\n\t" "# a[i+88] += m[88] * mu\n\t" - "ldr r7, [%[m], #352]\n\t" + "ldr r7, [%[m], #352]\n\t" "ldr r9, [%[a], #352]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24698,7 +24280,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #352]\n\t" "adc r5, r5, #0\n\t" "# a[i+89] += m[89] * mu\n\t" - "ldr r7, [%[m], #356]\n\t" + "ldr r7, [%[m], #356]\n\t" "ldr r9, [%[a], #356]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24707,7 +24289,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #356]\n\t" "adc r4, r4, #0\n\t" "# a[i+90] += m[90] * mu\n\t" - "ldr r7, [%[m], #360]\n\t" + "ldr r7, [%[m], #360]\n\t" "ldr r9, [%[a], #360]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24716,7 +24298,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #360]\n\t" "adc r5, r5, #0\n\t" "# a[i+91] += m[91] * mu\n\t" - "ldr r7, [%[m], #364]\n\t" + "ldr r7, [%[m], #364]\n\t" "ldr r9, [%[a], #364]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24725,7 +24307,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #364]\n\t" "adc r4, r4, #0\n\t" "# a[i+92] += m[92] * mu\n\t" - "ldr r7, [%[m], #368]\n\t" + "ldr r7, [%[m], #368]\n\t" "ldr r9, [%[a], #368]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24734,7 +24316,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #368]\n\t" "adc r5, r5, #0\n\t" "# a[i+93] += m[93] * mu\n\t" - "ldr r7, [%[m], #372]\n\t" + "ldr r7, [%[m], #372]\n\t" "ldr r9, [%[a], #372]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24743,7 +24325,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #372]\n\t" "adc r4, r4, #0\n\t" "# a[i+94] += m[94] * mu\n\t" - "ldr r7, [%[m], #376]\n\t" + "ldr r7, [%[m], #376]\n\t" "ldr r9, [%[a], #376]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24752,7 +24334,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #376]\n\t" "adc r5, r5, #0\n\t" "# a[i+95] += m[95] * mu\n\t" - "ldr r7, [%[m], #380]\n\t" + "ldr r7, [%[m], #380]\n\t" "ldr r9, [%[a], #380]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24761,7 +24343,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #380]\n\t" "adc r4, r4, #0\n\t" "# a[i+96] += m[96] * mu\n\t" - "ldr r7, [%[m], #384]\n\t" + "ldr r7, [%[m], #384]\n\t" "ldr r9, [%[a], #384]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24770,7 +24352,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #384]\n\t" "adc r5, r5, #0\n\t" "# a[i+97] += m[97] * mu\n\t" - "ldr r7, [%[m], #388]\n\t" + "ldr r7, [%[m], #388]\n\t" "ldr r9, [%[a], #388]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24779,7 +24361,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #388]\n\t" "adc r4, r4, #0\n\t" "# a[i+98] += m[98] * mu\n\t" - "ldr r7, [%[m], #392]\n\t" + "ldr r7, [%[m], #392]\n\t" "ldr r9, [%[a], #392]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24788,7 +24370,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #392]\n\t" "adc r5, r5, #0\n\t" "# a[i+99] += m[99] * mu\n\t" - "ldr r7, [%[m], #396]\n\t" + "ldr r7, [%[m], #396]\n\t" "ldr r9, [%[a], #396]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24797,7 +24379,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #396]\n\t" "adc r4, r4, #0\n\t" "# a[i+100] += m[100] * mu\n\t" - "ldr r7, [%[m], #400]\n\t" + "ldr r7, [%[m], #400]\n\t" "ldr r9, [%[a], #400]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24806,7 +24388,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #400]\n\t" "adc r5, r5, #0\n\t" "# a[i+101] += m[101] * mu\n\t" - "ldr r7, [%[m], #404]\n\t" + "ldr r7, [%[m], #404]\n\t" "ldr r9, [%[a], #404]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24815,7 +24397,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #404]\n\t" "adc r4, r4, #0\n\t" "# a[i+102] += m[102] * mu\n\t" - "ldr r7, [%[m], #408]\n\t" + "ldr r7, [%[m], #408]\n\t" "ldr r9, [%[a], #408]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24824,7 +24406,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #408]\n\t" "adc r5, r5, #0\n\t" "# a[i+103] += m[103] * mu\n\t" - "ldr r7, [%[m], #412]\n\t" + "ldr r7, [%[m], #412]\n\t" "ldr r9, [%[a], #412]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24833,7 +24415,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #412]\n\t" "adc r4, r4, #0\n\t" "# a[i+104] += m[104] * mu\n\t" - "ldr r7, [%[m], #416]\n\t" + "ldr r7, [%[m], #416]\n\t" "ldr r9, [%[a], #416]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24842,7 +24424,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #416]\n\t" "adc r5, r5, #0\n\t" "# a[i+105] += m[105] * mu\n\t" - "ldr r7, [%[m], #420]\n\t" + "ldr r7, [%[m], #420]\n\t" "ldr r9, [%[a], #420]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24851,7 +24433,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #420]\n\t" "adc r4, r4, #0\n\t" "# a[i+106] += m[106] * mu\n\t" - "ldr r7, [%[m], #424]\n\t" + "ldr r7, [%[m], #424]\n\t" "ldr r9, [%[a], #424]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24860,7 +24442,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #424]\n\t" "adc r5, r5, #0\n\t" "# a[i+107] += m[107] * mu\n\t" - "ldr r7, [%[m], #428]\n\t" + "ldr r7, [%[m], #428]\n\t" "ldr r9, [%[a], #428]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24869,7 +24451,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #428]\n\t" "adc r4, r4, #0\n\t" "# a[i+108] += m[108] * mu\n\t" - "ldr r7, [%[m], #432]\n\t" + "ldr r7, [%[m], #432]\n\t" "ldr r9, [%[a], #432]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24878,7 +24460,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #432]\n\t" "adc r5, r5, #0\n\t" "# a[i+109] += m[109] * mu\n\t" - "ldr r7, [%[m], #436]\n\t" + "ldr r7, [%[m], #436]\n\t" "ldr r9, [%[a], #436]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24887,7 +24469,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #436]\n\t" "adc r4, r4, #0\n\t" "# a[i+110] += m[110] * mu\n\t" - "ldr r7, [%[m], #440]\n\t" + "ldr r7, [%[m], #440]\n\t" "ldr r9, [%[a], #440]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24896,7 +24478,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #440]\n\t" "adc r5, r5, #0\n\t" "# a[i+111] += m[111] * mu\n\t" - "ldr r7, [%[m], #444]\n\t" + "ldr r7, [%[m], #444]\n\t" "ldr r9, [%[a], #444]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24905,7 +24487,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #444]\n\t" "adc r4, r4, #0\n\t" "# a[i+112] += m[112] * mu\n\t" - "ldr r7, [%[m], #448]\n\t" + "ldr r7, [%[m], #448]\n\t" "ldr r9, [%[a], #448]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24914,7 +24496,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #448]\n\t" "adc r5, r5, #0\n\t" "# a[i+113] += m[113] * mu\n\t" - "ldr r7, [%[m], #452]\n\t" + "ldr r7, [%[m], #452]\n\t" "ldr r9, [%[a], #452]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24923,7 +24505,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #452]\n\t" "adc r4, r4, #0\n\t" "# a[i+114] += m[114] * mu\n\t" - "ldr r7, [%[m], #456]\n\t" + "ldr r7, [%[m], #456]\n\t" "ldr r9, [%[a], #456]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24932,7 +24514,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #456]\n\t" "adc r5, r5, #0\n\t" "# a[i+115] += m[115] * mu\n\t" - "ldr r7, [%[m], #460]\n\t" + "ldr r7, [%[m], #460]\n\t" "ldr r9, [%[a], #460]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24941,7 +24523,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #460]\n\t" "adc r4, r4, #0\n\t" "# a[i+116] += m[116] * mu\n\t" - "ldr r7, [%[m], #464]\n\t" + "ldr r7, [%[m], #464]\n\t" "ldr r9, [%[a], #464]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24950,7 +24532,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #464]\n\t" "adc r5, r5, #0\n\t" "# a[i+117] += m[117] * mu\n\t" - "ldr r7, [%[m], #468]\n\t" + "ldr r7, [%[m], #468]\n\t" "ldr r9, [%[a], #468]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24959,7 +24541,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #468]\n\t" "adc r4, r4, #0\n\t" "# a[i+118] += m[118] * mu\n\t" - "ldr r7, [%[m], #472]\n\t" + "ldr r7, [%[m], #472]\n\t" "ldr r9, [%[a], #472]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24968,7 +24550,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #472]\n\t" "adc r5, r5, #0\n\t" "# a[i+119] += m[119] * mu\n\t" - "ldr r7, [%[m], #476]\n\t" + "ldr r7, [%[m], #476]\n\t" "ldr r9, [%[a], #476]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24977,7 +24559,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #476]\n\t" "adc r4, r4, #0\n\t" "# a[i+120] += m[120] * mu\n\t" - "ldr r7, [%[m], #480]\n\t" + "ldr r7, [%[m], #480]\n\t" "ldr r9, [%[a], #480]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24986,7 +24568,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #480]\n\t" "adc r5, r5, #0\n\t" "# a[i+121] += m[121] * mu\n\t" - "ldr r7, [%[m], #484]\n\t" + "ldr r7, [%[m], #484]\n\t" "ldr r9, [%[a], #484]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -24995,7 +24577,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #484]\n\t" "adc r4, r4, #0\n\t" "# a[i+122] += m[122] * mu\n\t" - "ldr r7, [%[m], #488]\n\t" + "ldr r7, [%[m], #488]\n\t" "ldr r9, [%[a], #488]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -25004,7 +24586,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #488]\n\t" "adc r5, r5, #0\n\t" "# a[i+123] += m[123] * mu\n\t" - "ldr r7, [%[m], #492]\n\t" + "ldr r7, [%[m], #492]\n\t" "ldr r9, [%[a], #492]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -25013,7 +24595,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #492]\n\t" "adc r4, r4, #0\n\t" "# a[i+124] += m[124] * mu\n\t" - "ldr r7, [%[m], #496]\n\t" + "ldr r7, [%[m], #496]\n\t" "ldr r9, [%[a], #496]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -25022,7 +24604,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #496]\n\t" "adc r5, r5, #0\n\t" "# a[i+125] += m[125] * mu\n\t" - "ldr r7, [%[m], #500]\n\t" + "ldr r7, [%[m], #500]\n\t" "ldr r9, [%[a], #500]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -25031,7 +24613,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r9, [%[a], #500]\n\t" "adc r4, r4, #0\n\t" "# a[i+126] += m[126] * mu\n\t" - "ldr r7, [%[m], #504]\n\t" + "ldr r7, [%[m], #504]\n\t" "ldr r9, [%[a], #504]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -25062,7 +24644,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "str r14, [%[a], #4]\n\t" : [ca] "+r" (ca), [a] "+r" (a) : [m] "r" (m), [mp] "r" (mp) - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12", "r11" ); sp_4096_cond_sub_128(a - 128, a, m, (sp_digit)0 - ca); @@ -25077,8 +24659,8 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_4096_mont_mul_128(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_4096_mont_mul_128(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_4096_mul_128(r, a, b); sp_4096_mont_reduce_128(r, m, mp); @@ -25091,8 +24673,8 @@ static void sp_4096_mont_mul_128(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_4096_mont_sqr_128(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_4096_mont_sqr_128(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_4096_sqr_128(r, a); sp_4096_mont_reduce_128(r, m, mp); @@ -26782,7 +26364,8 @@ static int sp_4096_mod_exp_128(sp_digit* r, const sp_digit* a, const sp_digit* e sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -26848,34 +26431,34 @@ static int sp_4096_mod_exp_128(sp_digit* r, const sp_digit* a, const sp_digit* e if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 128); for (; i>=0 || c>=4; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 28); + y = (byte)(n >> 28); n <<= 4; c = 28; } else if (c < 4) { - y = (int)(n >> 28); + y = (byte)(n >> 28); n = e[i--]; c = 4 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 28) & 0xf); + y = (byte)((n >> 28) & 0xf); n <<= 4; c -= 4; } @@ -26927,7 +26510,8 @@ static int sp_4096_mod_exp_128(sp_digit* r, const sp_digit* a, const sp_digit* e sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -27009,34 +26593,34 @@ static int sp_4096_mod_exp_128(sp_digit* r, const sp_digit* a, const sp_digit* e if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 128); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -27081,11 +26665,13 @@ static int sp_4096_mod_exp_128(sp_digit* r, const sp_digit* a, const sp_digit* e * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPublic_4096(const byte* in, word32 inLen, const mp_int* em, + const mp_int* mm, byte* out, word32* outLen) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_digit a[256], m[128], r[256]; + sp_digit a[256]; + sp_digit m[128]; + sp_digit r[256]; #else sp_digit* d = NULL; sp_digit* a = NULL; @@ -27588,9 +27174,9 @@ static sp_digit sp_4096_cond_add_64(sp_digit* r, const sp_digit* a, const sp_dig * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_4096(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM) sp_digit* a = NULL; @@ -27654,8 +27240,11 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, #else #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit a[128 * 2]; - sp_digit p[64], q[64], dp[64]; - sp_digit tmpa[128], tmpb[128]; + sp_digit p[64]; + sp_digit q[64]; + sp_digit dp[64]; + sp_digit tmpa[128]; + sp_digit tmpb[128]; #else sp_digit* t = NULL; sp_digit* a = NULL; @@ -27752,7 +27341,7 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, XMEMSET(q, 0, sizeof(q)); XMEMSET(dp, 0, sizeof(dp)); #endif -#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */ +#endif /* SP_RSA_PRIVATE_EXP_D | RSA_LOW_MEM */ return err; } #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -27775,17 +27364,19 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->used = 128; mp_clamp(r); #elif DIGIT_BIT < 32 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 128; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -27798,14 +27389,16 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 128; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 32 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -27832,10 +27425,13 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_4096(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[256], e[128], m[128]; + sp_digit b[256]; + sp_digit e[128]; + sp_digit m[128]; sp_digit* r = b; int expBits = mp_count_bits(exp); @@ -28670,10 +28266,12 @@ static int sp_4096_mod_exp_2_128(sp_digit* r, const sp_digit* e, int bits, sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -28708,34 +28306,34 @@ static int sp_4096_mod_exp_2_128(sp_digit* r, const sp_digit* e, int bits, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } - sp_4096_lshift_128(r, norm, (byte)y); + sp_4096_lshift_128(r, norm, y); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -28746,7 +28344,7 @@ static int sp_4096_mod_exp_2_128(sp_digit* r, const sp_digit* e, int bits, sp_4096_mont_sqr_128(r, r, m, mp); sp_4096_mont_sqr_128(r, r, m, mp); - sp_4096_lshift_128(r, r, (byte)y); + sp_4096_lshift_128(r, r, y); sp_4096_mul_d_128(tmp, norm, r[128]); r[128] = 0; o = sp_4096_add_128(r, r, tmp); @@ -28782,11 +28380,13 @@ static int sp_4096_mod_exp_2_128(sp_digit* r, const sp_digit* e, int bits, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, - mp_int* mod, byte* out, word32* outLen) +int sp_DhExp_4096(const mp_int* base, const byte* exp, word32 expLen, + const mp_int* mod, byte* out, word32* outLen) { int err = MP_OKAY; - sp_digit b[256], e[128], m[128]; + sp_digit b[256]; + sp_digit e[128]; + sp_digit m[128]; sp_digit* r = b; word32 i; @@ -28821,6 +28421,7 @@ int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, sp_4096_to_bin(r, out); *outLen = 512; for (i=0; i<512 && out[i] == 0; i++) { + /* Search for first non-zero. */ } *outLen -= i; XMEMMOVE(out, out + i, *outLen); @@ -28833,19 +28434,23 @@ int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, } #endif /* WOLFSSL_HAVE_SP_DH */ -#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */ +#endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */ #endif /* WOLFSSL_SP_4096 */ -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */ #ifdef WOLFSSL_HAVE_SP_ECC #ifndef WOLFSSL_SP_NO_256 /* Point structure to use. */ typedef struct sp_point_256 { + /* X ordinate of point. */ sp_digit x[2 * 8]; + /* Y ordinate of point. */ sp_digit y[2 * 8]; + /* Z ordinate of point. */ sp_digit z[2 * 8]; + /* Indicates point is at infinity. */ int infinity; } sp_point_256; @@ -28915,7 +28520,1143 @@ static const sp_digit p256_b[8] = { }; #endif -static int sp_256_point_new_ex_8(void* heap, sp_point_256* sp, sp_point_256** p) +#ifdef WOLFSSL_SP_SMALL +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static void sp_256_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) +{ + __asm__ __volatile__ ( + "sub sp, sp, #64\n\t" + "mov r5, #0\n\t" + "mov r6, #0\n\t" + "mov r7, #0\n\t" + "mov r8, #0\n\t" + "\n1:\n\t" + "subs r3, r5, #28\n\t" + "it cc\n\t" + "movcc r3, #0\n\t" + "sub r4, r5, r3\n\t" + "\n2:\n\t" + "ldr r14, [%[a], r3]\n\t" + "ldr r12, [%[b], r4]\n\t" + "umull r9, r10, r14, r12\n\t" + "adds r6, r6, r9\n\t" + "adcs r7, r7, r10\n\t" + "adc r8, r8, #0\n\t" + "add r3, r3, #4\n\t" + "sub r4, r4, #4\n\t" + "cmp r3, #32\n\t" + "beq 3f\n\t" + "cmp r3, r5\n\t" + "ble 2b\n\t" + "\n3:\n\t" + "str r6, [sp, r5]\n\t" + "mov r6, r7\n\t" + "mov r7, r8\n\t" + "mov r8, #0\n\t" + "add r5, r5, #4\n\t" + "cmp r5, #56\n\t" + "ble 1b\n\t" + "str r6, [sp, r5]\n\t" + "\n4:\n\t" + "ldr r6, [sp, #0]\n\t" + "ldr r7, [sp, #4]\n\t" + "ldr r8, [sp, #8]\n\t" + "ldr r3, [sp, #12]\n\t" + "str r6, [%[r], #0]\n\t" + "str r7, [%[r], #4]\n\t" + "str r8, [%[r], #8]\n\t" + "str r3, [%[r], #12]\n\t" + "add sp, sp, #16\n\t" + "add %[r], %[r], #16\n\t" + "subs r5, r5, #16\n\t" + "bgt 4b\n\t" + : [r] "+r" (r) + : [a] "r" (a), [b] "r" (b) + : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + ); +} + +#else +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static void sp_256_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) +{ + __asm__ __volatile__ ( + "sub sp, sp, #32\n\t" + "mov r10, #0\n\t" + "# A[0] * B[0]\n\t" + "ldr r11, [%[a], #0]\n\t" + "ldr r12, [%[b], #0]\n\t" + "umull r3, r4, r11, r12\n\t" + "mov r5, #0\n\t" + "str r3, [sp]\n\t" + "# A[0] * B[1]\n\t" + "ldr r9, [%[b], #4]\n\t" + "umull r6, r7, r11, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "# A[1] * B[0]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "str r4, [sp, #4]\n\t" + "# A[2] * B[0]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "# A[1] * B[1]\n\t" + "ldr r11, [%[a], #4]\n\t" + "ldr r12, [%[b], #4]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[0] * B[2]\n\t" + "ldr r8, [%[a], #0]\n\t" + "ldr r9, [%[b], #8]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "str r5, [sp, #8]\n\t" + "# A[0] * B[3]\n\t" + "ldr r9, [%[b], #12]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "# A[1] * B[2]\n\t" + "ldr r9, [%[b], #8]\n\t" + "umull r6, r7, r11, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[2] * B[1]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[3] * B[0]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #0]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "str r3, [sp, #12]\n\t" + "# A[4] * B[0]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "# A[3] * B[1]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[2] * B[2]\n\t" + "ldr r11, [%[a], #8]\n\t" + "ldr r12, [%[b], #8]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[1] * B[3]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #12]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[0] * B[4]\n\t" + "ldr r8, [%[a], #0]\n\t" + "ldr r9, [%[b], #16]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "str r4, [sp, #16]\n\t" + "# A[0] * B[5]\n\t" + "ldr r9, [%[b], #20]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "# A[1] * B[4]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #16]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[2] * B[3]\n\t" + "ldr r9, [%[b], #12]\n\t" + "umull r6, r7, r11, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[3] * B[2]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[4] * B[1]\n\t" + "ldr r8, [%[a], #16]\n\t" + "ldr r9, [%[b], #4]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[5] * B[0]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #0]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "str r5, [sp, #20]\n\t" + "# A[6] * B[0]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "# A[5] * B[1]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #4]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[4] * B[2]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[3] * B[3]\n\t" + "ldr r11, [%[a], #12]\n\t" + "ldr r12, [%[b], #12]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[2] * B[4]\n\t" + "ldr r8, [%[a], #8]\n\t" + "ldr r9, [%[b], #16]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[1] * B[5]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #20]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[0] * B[6]\n\t" + "ldr r8, [%[a], #0]\n\t" + "ldr r9, [%[b], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "str r3, [sp, #24]\n\t" + "# A[0] * B[7]\n\t" + "ldr r9, [%[b], #28]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "# A[1] * B[6]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[2] * B[5]\n\t" + "ldr r8, [%[a], #8]\n\t" + "ldr r9, [%[b], #20]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[3] * B[4]\n\t" + "ldr r9, [%[b], #16]\n\t" + "umull r6, r7, r11, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[4] * B[3]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[5] * B[2]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #8]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[6] * B[1]\n\t" + "ldr r8, [%[a], #24]\n\t" + "ldr r9, [%[b], #4]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[7] * B[0]\n\t" + "ldr r8, [%[a], #28]\n\t" + "ldr r9, [%[b], #0]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "str r4, [sp, #28]\n\t" + "# A[7] * B[1]\n\t" + "ldr r9, [%[b], #4]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "# A[6] * B[2]\n\t" + "ldr r8, [%[a], #24]\n\t" + "ldr r9, [%[b], #8]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[5] * B[3]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[4] * B[4]\n\t" + "ldr r11, [%[a], #16]\n\t" + "ldr r12, [%[b], #16]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[3] * B[5]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #20]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[2] * B[6]\n\t" + "ldr r8, [%[a], #8]\n\t" + "ldr r9, [%[b], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[1] * B[7]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #28]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "str r5, [%[r], #32]\n\t" + "# A[2] * B[7]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "# A[3] * B[6]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[4] * B[5]\n\t" + "ldr r9, [%[b], #20]\n\t" + "umull r6, r7, r11, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[5] * B[4]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[6] * B[3]\n\t" + "ldr r8, [%[a], #24]\n\t" + "ldr r9, [%[b], #12]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[7] * B[2]\n\t" + "ldr r8, [%[a], #28]\n\t" + "ldr r9, [%[b], #8]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "str r3, [%[r], #36]\n\t" + "# A[7] * B[3]\n\t" + "ldr r9, [%[b], #12]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "# A[6] * B[4]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[5] * B[5]\n\t" + "ldr r11, [%[a], #20]\n\t" + "ldr r12, [%[b], #20]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[4] * B[6]\n\t" + "ldr r8, [%[a], #16]\n\t" + "ldr r9, [%[b], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[3] * B[7]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #28]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "str r4, [%[r], #40]\n\t" + "# A[4] * B[7]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "# A[5] * B[6]\n\t" + "ldr r9, [%[b], #24]\n\t" + "umull r6, r7, r11, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[6] * B[5]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[7] * B[4]\n\t" + "ldr r8, [%[a], #28]\n\t" + "ldr r9, [%[b], #16]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "str r5, [%[r], #44]\n\t" + "# A[7] * B[5]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "# A[6] * B[6]\n\t" + "ldr r11, [%[a], #24]\n\t" + "ldr r12, [%[b], #24]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[5] * B[7]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #28]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "str r3, [%[r], #48]\n\t" + "# A[6] * B[7]\n\t" + "umull r6, r7, r11, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "# A[7] * B[6]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "str r4, [%[r], #52]\n\t" + "# A[7] * B[7]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adc r3, r3, r7\n\t" + "str r5, [%[r], #56]\n\t" + "str r3, [%[r], #60]\n\t" + "ldm sp!, {r3, r4, r5, r6}\n\t" + "stm %[r]!, {r3, r4, r5, r6}\n\t" + "ldm sp!, {r3, r4, r5, r6}\n\t" + "stm %[r]!, {r3, r4, r5, r6}\n\t" + "sub %[r], %[r], #32\n\t" + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) + : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" + ); +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +static void sp_256_sqr_8(sp_digit* r, const sp_digit* a) +{ + __asm__ __volatile__ ( + "sub sp, sp, #64\n\t" + "mov r12, #0\n\t" + "mov r6, #0\n\t" + "mov r7, #0\n\t" + "mov r8, #0\n\t" + "mov r5, #0\n\t" + "\n1:\n\t" + "subs r3, r5, #28\n\t" + "it cc\n\t" + "movcc r3, r12\n\t" + "sub r4, r5, r3\n\t" + "\n2:\n\t" + "cmp r4, r3\n\t" + "beq 4f\n\t" + "ldr r14, [%[a], r3]\n\t" + "ldr r9, [%[a], r4]\n\t" + "umull r9, r10, r14, r9\n\t" + "adds r6, r6, r9\n\t" + "adcs r7, r7, r10\n\t" + "adc r8, r8, r12\n\t" + "adds r6, r6, r9\n\t" + "adcs r7, r7, r10\n\t" + "adc r8, r8, r12\n\t" + "bal 5f\n\t" + "\n4:\n\t" + "ldr r14, [%[a], r3]\n\t" + "umull r9, r10, r14, r14\n\t" + "adds r6, r6, r9\n\t" + "adcs r7, r7, r10\n\t" + "adc r8, r8, r12\n\t" + "\n5:\n\t" + "add r3, r3, #4\n\t" + "sub r4, r4, #4\n\t" + "cmp r3, #32\n\t" + "beq 3f\n\t" + "cmp r3, r4\n\t" + "bgt 3f\n\t" + "cmp r3, r5\n\t" + "ble 2b\n\t" + "\n3:\n\t" + "str r6, [sp, r5]\n\t" + "mov r6, r7\n\t" + "mov r7, r8\n\t" + "mov r8, #0\n\t" + "add r5, r5, #4\n\t" + "cmp r5, #56\n\t" + "ble 1b\n\t" + "str r6, [sp, r5]\n\t" + "\n4:\n\t" + "ldr r6, [sp, #0]\n\t" + "ldr r7, [sp, #4]\n\t" + "ldr r8, [sp, #8]\n\t" + "ldr r3, [sp, #12]\n\t" + "str r6, [%[r], #0]\n\t" + "str r7, [%[r], #4]\n\t" + "str r8, [%[r], #8]\n\t" + "str r3, [%[r], #12]\n\t" + "add sp, sp, #16\n\t" + "add %[r], %[r], #16\n\t" + "subs r5, r5, #16\n\t" + "bgt 4b\n\t" + : [r] "+r" (r) + : [a] "r" (a) + : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r9", "r12" + ); +} + +#else +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +static void sp_256_sqr_8(sp_digit* r, const sp_digit* a) +{ + __asm__ __volatile__ ( + "sub sp, sp, #32\n\t" + "mov r12, #0\n\t" + "# A[0] * A[0]\n\t" + "ldr r10, [%[a], #0]\n\t" + "umull r8, r3, r10, r10\n\t" + "mov r4, #0\n\t" + "str r8, [sp]\n\t" + "# A[0] * A[1]\n\t" + "ldr r10, [%[a], #4]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r12, r12\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "str r3, [sp, #4]\n\t" + "# A[0] * A[2]\n\t" + "ldr r10, [%[a], #8]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r4, r4, r8\n\t" + "adcs r2, r2, r9\n\t" + "adc r3, r12, r12\n\t" + "adds r4, r4, r8\n\t" + "adcs r2, r2, r9\n\t" + "adc r3, r3, r12\n\t" + "# A[1] * A[1]\n\t" + "ldr r10, [%[a], #4]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r4, r4, r8\n\t" + "adcs r2, r2, r9\n\t" + "adc r3, r3, r12\n\t" + "str r4, [sp, #8]\n\t" + "# A[0] * A[3]\n\t" + "ldr r10, [%[a], #12]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r12, r12\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r4, r12\n\t" + "# A[1] * A[2]\n\t" + "ldr r10, [%[a], #8]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r4, r12\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r4, r12\n\t" + "str r2, [sp, #12]\n\t" + "# A[0] * A[4]\n\t" + "ldr r10, [%[a], #16]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r12, r12\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "# A[1] * A[3]\n\t" + "ldr r10, [%[a], #12]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "# A[2] * A[2]\n\t" + "ldr r10, [%[a], #8]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "str r3, [sp, #16]\n\t" + "# A[0] * A[5]\n\t" + "ldr r10, [%[a], #20]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r3, #0\n\t" + "mov r7, #0\n\t" + "# A[1] * A[4]\n\t" + "ldr r10, [%[a], #16]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[2] * A[3]\n\t" + "ldr r10, [%[a], #12]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r4, r4, r5\n\t" + "adcs r2, r2, r6\n\t" + "adc r3, r3, r7\n\t" + "str r4, [sp, #20]\n\t" + "# A[0] * A[6]\n\t" + "ldr r10, [%[a], #24]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r4, #0\n\t" + "mov r7, #0\n\t" + "# A[1] * A[5]\n\t" + "ldr r10, [%[a], #20]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[2] * A[4]\n\t" + "ldr r10, [%[a], #16]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[3] * A[3]\n\t" + "ldr r10, [%[a], #12]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r2, r2, r5\n\t" + "adcs r3, r3, r6\n\t" + "adc r4, r4, r7\n\t" + "str r2, [sp, #24]\n\t" + "# A[0] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r2, #0\n\t" + "mov r7, #0\n\t" + "# A[1] * A[6]\n\t" + "ldr r10, [%[a], #24]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[2] * A[5]\n\t" + "ldr r10, [%[a], #20]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[3] * A[4]\n\t" + "ldr r10, [%[a], #16]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r3, r3, r5\n\t" + "adcs r4, r4, r6\n\t" + "adc r2, r2, r7\n\t" + "str r3, [sp, #28]\n\t" + "# A[1] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r3, #0\n\t" + "mov r7, #0\n\t" + "# A[2] * A[6]\n\t" + "ldr r10, [%[a], #24]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[3] * A[5]\n\t" + "ldr r10, [%[a], #20]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[4] * A[4]\n\t" + "ldr r10, [%[a], #16]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r4, r4, r5\n\t" + "adcs r2, r2, r6\n\t" + "adc r3, r3, r7\n\t" + "str r4, [%[r], #32]\n\t" + "# A[2] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r4, #0\n\t" + "mov r7, #0\n\t" + "# A[3] * A[6]\n\t" + "ldr r10, [%[a], #24]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[4] * A[5]\n\t" + "ldr r10, [%[a], #20]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r2, r2, r5\n\t" + "adcs r3, r3, r6\n\t" + "adc r4, r4, r7\n\t" + "str r2, [%[r], #36]\n\t" + "# A[3] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r12, r12\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "# A[4] * A[6]\n\t" + "ldr r10, [%[a], #24]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "# A[5] * A[5]\n\t" + "ldr r10, [%[a], #20]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "str r3, [%[r], #40]\n\t" + "# A[4] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r4, r4, r8\n\t" + "adcs r2, r2, r9\n\t" + "adc r3, r12, r12\n\t" + "adds r4, r4, r8\n\t" + "adcs r2, r2, r9\n\t" + "adc r3, r3, r12\n\t" + "# A[5] * A[6]\n\t" + "ldr r10, [%[a], #24]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r4, r4, r8\n\t" + "adcs r2, r2, r9\n\t" + "adc r3, r3, r12\n\t" + "adds r4, r4, r8\n\t" + "adcs r2, r2, r9\n\t" + "adc r3, r3, r12\n\t" + "str r4, [%[r], #44]\n\t" + "# A[5] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r12, r12\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r4, r12\n\t" + "# A[6] * A[6]\n\t" + "ldr r10, [%[a], #24]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r4, r12\n\t" + "str r2, [%[r], #48]\n\t" + "# A[6] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r12, r12\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "str r3, [%[r], #52]\n\t" + "# A[7] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r4, r4, r8\n\t" + "adc r2, r2, r9\n\t" + "str r4, [%[r], #56]\n\t" + "str r2, [%[r], #60]\n\t" + "ldm sp!, {r2, r3, r4, r8}\n\t" + "stm %[r]!, {r2, r3, r4, r8}\n\t" + "ldm sp!, {r2, r3, r4, r8}\n\t" + "stm %[r]!, {r2, r3, r4, r8}\n\t" + "sub %[r], %[r], #32\n\t" + : + : [r] "r" (r), [a] "r" (a) + : "memory", "r2", "r3", "r4", "r8", "r9", "r10", "r8", "r5", "r6", "r7", "r12" + ); +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "add r12, %[a], #32\n\t" + "\n1:\n\t" + "adds %[c], %[c], #-1\n\t" + "ldr r4, [%[a]], #4\n\t" + "ldr r5, [%[a]], #4\n\t" + "ldr r6, [%[a]], #4\n\t" + "ldr r7, [%[a]], #4\n\t" + "ldr r8, [%[b]], #4\n\t" + "ldr r9, [%[b]], #4\n\t" + "ldr r10, [%[b]], #4\n\t" + "ldr r14, [%[b]], #4\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "str r4, [%[r]], #4\n\t" + "str r5, [%[r]], #4\n\t" + "str r6, [%[r]], #4\n\t" + "str r7, [%[r]], #4\n\t" + "mov r4, #0\n\t" + "adc %[c], r4, #0\n\t" + "cmp %[a], r12\n\t" + "bne 1b\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + ); + + return c; +} + +#else +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r12, #0\n\t" + "ldr r4, [%[a], #0]\n\t" + "ldr r5, [%[a], #4]\n\t" + "ldr r6, [%[a], #8]\n\t" + "ldr r7, [%[a], #12]\n\t" + "ldr r8, [%[b], #0]\n\t" + "ldr r9, [%[b], #4]\n\t" + "ldr r10, [%[b], #8]\n\t" + "ldr r14, [%[b], #12]\n\t" + "adds r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "str r4, [%[r], #0]\n\t" + "str r5, [%[r], #4]\n\t" + "str r6, [%[r], #8]\n\t" + "str r7, [%[r], #12]\n\t" + "ldr r4, [%[a], #16]\n\t" + "ldr r5, [%[a], #20]\n\t" + "ldr r6, [%[a], #24]\n\t" + "ldr r7, [%[a], #28]\n\t" + "ldr r8, [%[b], #16]\n\t" + "ldr r9, [%[b], #20]\n\t" + "ldr r10, [%[b], #24]\n\t" + "ldr r14, [%[b], #28]\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "str r4, [%[r], #16]\n\t" + "str r5, [%[r], #20]\n\t" + "str r6, [%[r], #24]\n\t" + "str r7, [%[r], #28]\n\t" + "adc %[c], r12, r12\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b) + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + ); + + return c; +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "add r12, %[a], #32\n\t" + "\n1:\n\t" + "rsbs %[c], %[c], #0\n\t" + "ldr r4, [%[a]], #4\n\t" + "ldr r5, [%[a]], #4\n\t" + "ldr r6, [%[a]], #4\n\t" + "ldr r7, [%[a]], #4\n\t" + "ldr r8, [%[b]], #4\n\t" + "ldr r9, [%[b]], #4\n\t" + "ldr r10, [%[b]], #4\n\t" + "ldr r14, [%[b]], #4\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "str r4, [%[r]], #4\n\t" + "str r5, [%[r]], #4\n\t" + "str r6, [%[r]], #4\n\t" + "str r7, [%[r]], #4\n\t" + "sbc %[c], r4, r4\n\t" + "cmp %[a], r12\n\t" + "bne 1b\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + ); + + return c; +} + +#else +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldr r3, [%[a], #0]\n\t" + "ldr r4, [%[a], #4]\n\t" + "ldr r5, [%[a], #8]\n\t" + "ldr r6, [%[a], #12]\n\t" + "ldr r7, [%[b], #0]\n\t" + "ldr r8, [%[b], #4]\n\t" + "ldr r9, [%[b], #8]\n\t" + "ldr r10, [%[b], #12]\n\t" + "subs r3, r3, r7\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "str r3, [%[r], #0]\n\t" + "str r4, [%[r], #4]\n\t" + "str r5, [%[r], #8]\n\t" + "str r6, [%[r], #12]\n\t" + "ldr r3, [%[a], #16]\n\t" + "ldr r4, [%[a], #20]\n\t" + "ldr r5, [%[a], #24]\n\t" + "ldr r6, [%[a], #28]\n\t" + "ldr r7, [%[b], #16]\n\t" + "ldr r8, [%[b], #20]\n\t" + "ldr r9, [%[b], #24]\n\t" + "ldr r10, [%[b], #28]\n\t" + "sbcs r3, r3, r7\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "str r3, [%[r], #16]\n\t" + "str r4, [%[r], #20]\n\t" + "str r5, [%[r], #24]\n\t" + "str r6, [%[r], #28]\n\t" + "sbc %[c], %[c], #0\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b) + : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" + ); + + return c; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Create a new point. + * + * heap [in] Buffer to allocate dynamic memory from. + * sp [in] Data for point - only if not allocating. + * p [out] New point. + * returns MEMORY_E when dynamic memory allocation fails and 0 otherwise. + */ +static int sp_256_point_new_ex_8(void* heap, sp_point_256* sp, + sp_point_256** p) { int ret = MP_OKAY; (void)heap; @@ -28940,6 +29681,12 @@ static int sp_256_point_new_ex_8(void* heap, sp_point_256* sp, sp_point_256** p) #endif +/* Free the point. + * + * p [in,out] Point to free. + * clear [in] Indicates whether to zeroize point. + * heap [in] Buffer from which dynamic memory was allocate from. + */ static void sp_256_point_free_8(sp_point_256* p, int clear, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -28952,7 +29699,7 @@ static void sp_256_point_free_8(sp_point_256* p, int clear, void* heap) } #else /* Clear point data if requested. */ - if (clear != 0) { + if ((p != NULL) && (clear != 0)) { XMEMSET(p, 0, sizeof(*p)); } #endif @@ -29211,7 +29958,8 @@ static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 32 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -29245,7 +29993,9 @@ static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -29281,7 +30031,8 @@ static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) * p Point of type sp_point_256 (result). * pm Point of type ecc_point. */ -static void sp_256_point_from_ecc_point_8(sp_point_256* p, const ecc_point* pm) +static void sp_256_point_from_ecc_point_8(sp_point_256* p, + const ecc_point* pm) { XMEMSET(p->x, 0, sizeof(p->x)); XMEMSET(p->y, 0, sizeof(p->y)); @@ -29308,17 +30059,19 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) r->used = 8; mp_clamp(r); #elif DIGIT_BIT < 32 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 8; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -29331,14 +30084,16 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 8; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 32 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -30571,7 +31326,7 @@ static void sp_256_mont_sqr_n_8(sp_digit* r, const sp_digit* a, int n, } } -#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */ +#endif /* !WOLFSSL_SP_SMALL | HAVE_COMP_KEY */ #ifdef WOLFSSL_SP_SMALL /* Mod-2 for the P256 curve. */ static const uint32_t p256_mod_minus_2[8] = { @@ -30894,6 +31649,7 @@ SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, sp_digit ca = 0; __asm__ __volatile__ ( + "ldr r11, [%[m], #0]\n\t" "# i = 0\n\t" "mov r12, #0\n\t" "ldr r10, [%[a], #0]\n\t" @@ -30902,13 +31658,12 @@ SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, "# mu = a[i] * mp\n\t" "mul r8, %[mp], r10\n\t" "# a[i+0] += m[0] * mu\n\t" - "ldr r7, [%[m], #0]\n\t" "ldr r9, [%[a], #0]\n\t" - "umull r6, r7, r8, r7\n\t" + "umull r6, r7, r8, r11\n\t" "adds r10, r10, r6\n\t" "adc r5, r7, #0\n\t" "# a[i+1] += m[1] * mu\n\t" - "ldr r7, [%[m], #4]\n\t" + "ldr r7, [%[m], #4]\n\t" "ldr r9, [%[a], #4]\n\t" "umull r6, r7, r8, r7\n\t" "adds r10, r14, r6\n\t" @@ -30916,7 +31671,7 @@ SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, "adds r10, r10, r5\n\t" "adc r4, r4, #0\n\t" "# a[i+2] += m[2] * mu\n\t" - "ldr r7, [%[m], #8]\n\t" + "ldr r7, [%[m], #8]\n\t" "ldr r14, [%[a], #8]\n\t" "umull r6, r7, r8, r7\n\t" "adds r14, r14, r6\n\t" @@ -30924,7 +31679,7 @@ SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, "adds r14, r14, r4\n\t" "adc r5, r5, #0\n\t" "# a[i+3] += m[3] * mu\n\t" - "ldr r7, [%[m], #12]\n\t" + "ldr r7, [%[m], #12]\n\t" "ldr r9, [%[a], #12]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -30933,7 +31688,7 @@ SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, "str r9, [%[a], #12]\n\t" "adc r4, r4, #0\n\t" "# a[i+4] += m[4] * mu\n\t" - "ldr r7, [%[m], #16]\n\t" + "ldr r7, [%[m], #16]\n\t" "ldr r9, [%[a], #16]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -30942,7 +31697,7 @@ SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, "str r9, [%[a], #16]\n\t" "adc r5, r5, #0\n\t" "# a[i+5] += m[5] * mu\n\t" - "ldr r7, [%[m], #20]\n\t" + "ldr r7, [%[m], #20]\n\t" "ldr r9, [%[a], #20]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -30951,7 +31706,7 @@ SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, "str r9, [%[a], #20]\n\t" "adc r4, r4, #0\n\t" "# a[i+6] += m[6] * mu\n\t" - "ldr r7, [%[m], #24]\n\t" + "ldr r7, [%[m], #24]\n\t" "ldr r9, [%[a], #24]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -30982,7 +31737,7 @@ SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, "str r14, [%[a], #4]\n\t" : [ca] "+r" (ca), [a] "+r" (a) : [m] "r" (m), [mp] "r" (mp) - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12", "r11" ); sp_256_cond_sub_8(a - 8, a, m, (sp_digit)0 - ca); @@ -30994,7 +31749,8 @@ SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, * p Montgomery form projective coordinate point. * t Temporary ordinate data. */ -static void sp_256_map_8(sp_point_256* r, const sp_point_256* p, sp_digit* t) +static void sp_256_map_8(sp_point_256* r, const sp_point_256* p, + sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2*8; @@ -31030,106 +31786,6 @@ static void sp_256_map_8(sp_point_256* r, const sp_point_256* p, sp_digit* t) } -#ifdef WOLFSSL_SP_SMALL -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "add r12, %[a], #32\n\t" - "\n1:\n\t" - "adds %[c], %[c], #-1\n\t" - "ldr r4, [%[a]], #4\n\t" - "ldr r5, [%[a]], #4\n\t" - "ldr r6, [%[a]], #4\n\t" - "ldr r7, [%[a]], #4\n\t" - "ldr r8, [%[b]], #4\n\t" - "ldr r9, [%[b]], #4\n\t" - "ldr r10, [%[b]], #4\n\t" - "ldr r14, [%[b]], #4\n\t" - "adcs r4, r4, r8\n\t" - "adcs r5, r5, r9\n\t" - "adcs r6, r6, r10\n\t" - "adcs r7, r7, r14\n\t" - "str r4, [%[r]], #4\n\t" - "str r5, [%[r]], #4\n\t" - "str r6, [%[r]], #4\n\t" - "str r7, [%[r]], #4\n\t" - "mov r4, #0\n\t" - "adc %[c], r4, #0\n\t" - "cmp %[a], r12\n\t" - "bne 1b\n\t" - : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) - : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" - ); - - return c; -} - -#else -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "mov r12, #0\n\t" - "ldr r4, [%[a], #0]\n\t" - "ldr r5, [%[a], #4]\n\t" - "ldr r6, [%[a], #8]\n\t" - "ldr r7, [%[a], #12]\n\t" - "ldr r8, [%[b], #0]\n\t" - "ldr r9, [%[b], #4]\n\t" - "ldr r10, [%[b], #8]\n\t" - "ldr r14, [%[b], #12]\n\t" - "adds r4, r4, r8\n\t" - "adcs r5, r5, r9\n\t" - "adcs r6, r6, r10\n\t" - "adcs r7, r7, r14\n\t" - "str r4, [%[r], #0]\n\t" - "str r5, [%[r], #4]\n\t" - "str r6, [%[r], #8]\n\t" - "str r7, [%[r], #12]\n\t" - "ldr r4, [%[a], #16]\n\t" - "ldr r5, [%[a], #20]\n\t" - "ldr r6, [%[a], #24]\n\t" - "ldr r7, [%[a], #28]\n\t" - "ldr r8, [%[b], #16]\n\t" - "ldr r9, [%[b], #20]\n\t" - "ldr r10, [%[b], #24]\n\t" - "ldr r14, [%[b], #28]\n\t" - "adcs r4, r4, r8\n\t" - "adcs r5, r5, r9\n\t" - "adcs r6, r6, r10\n\t" - "adcs r7, r7, r14\n\t" - "str r4, [%[r], #16]\n\t" - "str r5, [%[r], #20]\n\t" - "str r6, [%[r], #24]\n\t" - "str r7, [%[r], #28]\n\t" - "adc %[c], r12, r12\n\t" - : [c] "+r" (c) - : [r] "r" (r), [a] "r" (a), [b] "r" (b) - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" - ); - - return c; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Add two Montgomery form numbers (r = a + b % m). * * r Result of addition. @@ -31687,104 +32343,6 @@ static void sp_256_proj_point_dbl_8(sp_point_256* r, const sp_point_256* p, sp_d sp_256_mont_sub_8(y, y, t2, p256_mod); } -#ifdef WOLFSSL_SP_SMALL -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "add r12, %[a], #32\n\t" - "\n1:\n\t" - "rsbs %[c], %[c], #0\n\t" - "ldr r4, [%[a]], #4\n\t" - "ldr r5, [%[a]], #4\n\t" - "ldr r6, [%[a]], #4\n\t" - "ldr r7, [%[a]], #4\n\t" - "ldr r8, [%[b]], #4\n\t" - "ldr r9, [%[b]], #4\n\t" - "ldr r10, [%[b]], #4\n\t" - "ldr r14, [%[b]], #4\n\t" - "sbcs r4, r4, r8\n\t" - "sbcs r5, r5, r9\n\t" - "sbcs r6, r6, r10\n\t" - "sbcs r7, r7, r14\n\t" - "str r4, [%[r]], #4\n\t" - "str r5, [%[r]], #4\n\t" - "str r6, [%[r]], #4\n\t" - "str r7, [%[r]], #4\n\t" - "sbc %[c], r4, r4\n\t" - "cmp %[a], r12\n\t" - "bne 1b\n\t" - : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) - : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" - ); - - return c; -} - -#else -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "ldr r3, [%[a], #0]\n\t" - "ldr r4, [%[a], #4]\n\t" - "ldr r5, [%[a], #8]\n\t" - "ldr r6, [%[a], #12]\n\t" - "ldr r7, [%[b], #0]\n\t" - "ldr r8, [%[b], #4]\n\t" - "ldr r9, [%[b], #8]\n\t" - "ldr r10, [%[b], #12]\n\t" - "subs r3, r3, r7\n\t" - "sbcs r4, r4, r8\n\t" - "sbcs r5, r5, r9\n\t" - "sbcs r6, r6, r10\n\t" - "str r3, [%[r], #0]\n\t" - "str r4, [%[r], #4]\n\t" - "str r5, [%[r], #8]\n\t" - "str r6, [%[r], #12]\n\t" - "ldr r3, [%[a], #16]\n\t" - "ldr r4, [%[a], #20]\n\t" - "ldr r5, [%[a], #24]\n\t" - "ldr r6, [%[a], #28]\n\t" - "ldr r7, [%[b], #16]\n\t" - "ldr r8, [%[b], #20]\n\t" - "ldr r9, [%[b], #24]\n\t" - "ldr r10, [%[b], #28]\n\t" - "sbcs r3, r3, r7\n\t" - "sbcs r4, r4, r8\n\t" - "sbcs r5, r5, r9\n\t" - "sbcs r6, r6, r10\n\t" - "str r3, [%[r], #16]\n\t" - "str r4, [%[r], #20]\n\t" - "str r5, [%[r], #24]\n\t" - "str r6, [%[r], #28]\n\t" - "sbc %[c], %[c], #0\n\t" - : [c] "+r" (c) - : [r] "r" (r), [a] "r" (a), [b] "r" (b) - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" - ); - - return c; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Compare two numbers to determine if they are equal. * Constant time implementation. * @@ -32008,8 +32566,8 @@ static int sp_256_proj_point_add_8_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r, } #endif /* WOLFSSL_SP_NONBLOCK */ -static void sp_256_proj_point_add_8(sp_point_256* r, const sp_point_256* p, const sp_point_256* q, - sp_digit* t) +static void sp_256_proj_point_add_8(sp_point_256* r, + const sp_point_256* p, const sp_point_256* q, sp_digit* t) { const sp_point_256* ap[2]; sp_point_256* rp[2]; @@ -32164,9 +32722,11 @@ static void sp_256_get_point_16_8(sp_point_256* r, const sp_point_256* table, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Simple, smaller code size and memory size, of windowing. - * Calculate uindow of 4 bits. - * Only add points from table. + * Fast implementation that generates a pre-computation table. + * 4 bits of window (no sliding!). + * Uses add and double for calculating table. + * 256 doubles. + * 76 adds. * * r Resulting point. * g Point to multiply. @@ -32195,7 +32755,8 @@ static int sp_256_ecc_mulmod_fast_8(sp_point_256* r, const sp_point_256* g, cons sp_digit* tmp; sp_digit n; int i; - int c, y; + int c; + int y; int err; /* Constant time used for cache attack resistance implementation. */ @@ -32268,7 +32829,7 @@ static int sp_256_ecc_mulmod_fast_8(sp_point_256* r, const sp_point_256* g, cons i = 6; n = k[i+1] << 0; c = 28; - y = n >> 28; + y = (int)(n >> 28); #ifndef WC_NO_CACHE_RESISTANT if (ct) { sp_256_get_point_16_8(rt, t, y); @@ -32333,12 +32894,6 @@ static int sp_256_ecc_mulmod_fast_8(sp_point_256* r, const sp_point_256* g, cons return err; } -/* A table entry for pre-computed points. */ -typedef struct sp_table_entry_256 { - sp_digit x[8]; - sp_digit y[8]; -} sp_table_entry_256; - #ifdef FP_ECC /* Double the Montgomery form projective point p a number of times. * @@ -32347,7 +32902,8 @@ typedef struct sp_table_entry_256 { * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_8(sp_point_256* p, int n, sp_digit* t) +static void sp_256_proj_point_dbl_n_8(sp_point_256* p, int n, + sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*8; @@ -32428,6 +32984,36 @@ static void sp_256_proj_point_dbl_n_8(sp_point_256* p, int n, sp_digit* t) sp_256_div2_8(y, y, p256_mod); } +/* Convert the projective point to affine. + * Ordinates are in Montgomery form. + * + * a Point to convert. + * t Temporary data. + */ +static void sp_256_proj_to_affine_8(sp_point_256* a, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 8; + sp_digit* tmp = t + 4 * 8; + + sp_256_mont_inv_8(t1, a->z, tmp); + + sp_256_mont_sqr_8(t2, t1, p256_mod, p256_mp_mod); + sp_256_mont_mul_8(t1, t2, t1, p256_mod, p256_mp_mod); + + sp_256_mont_mul_8(a->x, a->x, t2, p256_mod, p256_mp_mod); + sp_256_mont_mul_8(a->y, a->y, t1, p256_mod, p256_mp_mod); + XMEMCPY(a->z, p256_norm_mod, sizeof(p256_norm_mod)); +} + +#endif /* FP_ECC */ +/* A table entry for pre-computed points. */ +typedef struct sp_table_entry_256 { + sp_digit x[8]; + sp_digit y[8]; +} sp_table_entry_256; + +#ifdef FP_ECC #endif /* FP_ECC */ /* Add two Montgomery form projective points. The second point has a q value of * one. @@ -32513,29 +33099,11 @@ static void sp_256_proj_point_add_qz1_8(sp_point_256* r, const sp_point_256* p, #ifdef WOLFSSL_SP_SMALL #ifdef FP_ECC -/* Convert the projective point to affine. - * Ordinates are in Montgomery form. - * - * a Point to convert. - * t Temporary data. - */ -static void sp_256_proj_to_affine_8(sp_point_256* a, sp_digit* t) -{ - sp_digit* t1 = t; - sp_digit* t2 = t + 2 * 8; - sp_digit* tmp = t + 4 * 8; - - sp_256_mont_inv_8(t1, a->z, tmp); - - sp_256_mont_sqr_8(t2, t1, p256_mod, p256_mp_mod); - sp_256_mont_mul_8(t1, t2, t1, p256_mod, p256_mp_mod); - - sp_256_mont_mul_8(a->x, a->x, t2, p256_mod, p256_mp_mod); - sp_256_mont_mul_8(a->y, a->y, t1, p256_mod, p256_mp_mod); - XMEMCPY(a->z, p256_norm_mod, sizeof(p256_norm_mod)); -} - /* Generate the pre-computed table of points for the base point. + * + * width = 4 + * 16 entries + * 64 bits between * * a The base point. * table Place to store generated point data. @@ -32546,12 +33114,15 @@ static int sp_256_gen_stripe_table_8(const sp_point_256* a, sp_table_entry_256* table, sp_digit* tmp, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_point_256 td, s1d, s2d; + sp_point_256 td; + sp_point_256 s1d; + sp_point_256 s2d; #endif sp_point_256* t; sp_point_256* s1 = NULL; sp_point_256* s2 = NULL; - int i, j; + int i; + int j; int err; (void)heap; @@ -32670,8 +33241,10 @@ static void sp_256_get_entry_16_8(sp_point_256* r, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Implementation uses striping of bits. - * Choose bits 4 bits apart. + * Stripe implementation. + * Pre-generated: 2^0, 2^64, ... + * Pre-generated: products of all combinations of above. + * 4 doubles and adds (with qz=1) * * r Resulting point. * k Scalar to multiply by. @@ -32693,8 +33266,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, sp_point_256* rt; sp_point_256* p = NULL; sp_digit* t; - int i, j; - int y, x; + int i; + int j; + int y; + int x; int err; (void)g; @@ -32722,8 +33297,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod)); y = 0; - for (j=0,x=63; j<4; j++,x+=64) { + x = 63; + for (j=0; j<4; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 64; } #ifndef WC_NO_CACHE_RESISTANT if (ct) { @@ -32737,8 +33314,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, rt->infinity = !y; for (i=62; i>=0; i--) { y = 0; - for (j=0,x=i; j<4; j++,x+=64) { + x = i; + for (j=0; j<4; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 64; } sp_256_proj_point_dbl_8(rt, rt, t); @@ -32780,16 +33359,25 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, #define FP_ENTRIES 16 #endif +/* Cache entry - holds precomputation tables for a point. */ typedef struct sp_cache_256_t { + /* X ordinate of point that table was generated from. */ sp_digit x[8]; + /* Y ordinate of point that table was generated from. */ sp_digit y[8]; + /* Precomputation table for point. */ sp_table_entry_256 table[16]; + /* Count of entries in table. */ uint32_t cnt; + /* Point and table set in entry. */ int set; } sp_cache_256_t; +/* Cache of tables. */ static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES]; +/* Index of last entry in cache. */ static THREAD_LS_T int sp_cache_256_last = -1; +/* Cache has been initialized. */ static THREAD_LS_T int sp_cache_256_inited = 0; #ifndef HAVE_THREAD_LS @@ -32797,9 +33385,15 @@ static THREAD_LS_T int sp_cache_256_inited = 0; static wolfSSL_Mutex sp_cache_256_lock; #endif +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache) { - int i, j; + int i; + int j; uint32_t least; if (sp_cache_256_inited == 0) { @@ -32908,6 +33502,10 @@ static int sp_256_ecc_mulmod_8(sp_point_256* r, const sp_point_256* g, const sp_ #else #ifdef FP_ECC /* Generate the pre-computed table of points for the base point. + * + * width = 8 + * 256 entries + * 32 bits between * * a The base point. * table Place to store generated point data. @@ -32918,12 +33516,15 @@ static int sp_256_gen_stripe_table_8(const sp_point_256* a, sp_table_entry_256* table, sp_digit* tmp, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_point_256 td, s1d, s2d; + sp_point_256 td; + sp_point_256 s1d; + sp_point_256 s2d; #endif sp_point_256* t; sp_point_256* s1 = NULL; sp_point_256* s2 = NULL; - int i, j; + int i; + int j; int err; (void)heap; @@ -33042,8 +33643,10 @@ static void sp_256_get_entry_256_8(sp_point_256* r, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Implementation uses striping of bits. - * Choose bits 8 bits apart. + * Stripe implementation. + * Pre-generated: 2^0, 2^32, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) * * r Resulting point. * k Scalar to multiply by. @@ -33065,8 +33668,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, sp_point_256* rt; sp_point_256* p = NULL; sp_digit* t; - int i, j; - int y, x; + int i; + int j; + int y; + int x; int err; (void)g; @@ -33094,8 +33699,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod)); y = 0; - for (j=0,x=31; j<8; j++,x+=32) { + x = 31; + for (j=0; j<8; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 32; } #ifndef WC_NO_CACHE_RESISTANT if (ct) { @@ -33109,8 +33716,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, rt->infinity = !y; for (i=30; i>=0; i--) { y = 0; - for (j=0,x=i; j<8; j++,x+=32) { + x = i; + for (j=0; j<8; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 32; } sp_256_proj_point_dbl_8(rt, rt, t); @@ -33152,16 +33761,25 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, #define FP_ENTRIES 16 #endif +/* Cache entry - holds precomputation tables for a point. */ typedef struct sp_cache_256_t { + /* X ordinate of point that table was generated from. */ sp_digit x[8]; + /* Y ordinate of point that table was generated from. */ sp_digit y[8]; + /* Precomputation table for point. */ sp_table_entry_256 table[256]; + /* Count of entries in table. */ uint32_t cnt; + /* Point and table set in entry. */ int set; } sp_cache_256_t; +/* Cache of tables. */ static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES]; +/* Index of last entry in cache. */ static THREAD_LS_T int sp_cache_256_last = -1; +/* Cache has been initialized. */ static THREAD_LS_T int sp_cache_256_inited = 0; #ifndef HAVE_THREAD_LS @@ -33169,9 +33787,15 @@ static THREAD_LS_T int sp_cache_256_inited = 0; static wolfSSL_Mutex sp_cache_256_lock; #endif +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache) { - int i, j; + int i; + int j; uint32_t least; if (sp_cache_256_inited == 0) { @@ -33288,8 +33912,8 @@ static int sp_256_ecc_mulmod_8(sp_point_256* r, const sp_point_256* g, const sp_ * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, - void* heap) +int sp_ecc_mulmod_256(const mp_int* km, const ecc_point* gm, ecc_point* r, + int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_256 p; @@ -33330,7 +33954,94 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, return err; } +/* Multiply the point by the scalar, add point a and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * p Point to multiply. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_add_256(const mp_int* km, const ecc_point* gm, + const ecc_point* am, int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_256 p; + sp_point_256 a; + sp_digit kd[8]; + sp_digit t[8 * 2 * 5]; +#endif + sp_point_256* point; + sp_point_256* addP = NULL; + sp_digit* k = NULL; + sp_digit* tmp = NULL; + int err = MP_OKAY; + + err = sp_256_point_new_8(heap, p, point); + if (err == MP_OKAY) { + err = sp_256_point_new_8(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (8 + 8 * 2 * 5), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 8; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_256_from_mp(k, 8, km); + sp_256_point_from_ecc_point_8(point, gm); + sp_256_point_from_ecc_point_8(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_8(addP->x, addP->x, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_8(addP->y, addP->y, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_8(addP->z, addP->z, p256_mod); + } + if (err == MP_OKAY) { + err = sp_256_ecc_mulmod_8(point, point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_256_proj_point_add_8(point, point, addP, tmp); + + if (map) { + sp_256_map_8(point, point, tmp); + } + + err = sp_256_point_to_ecc_point_8(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_256_point_free_8(addP, 0, heap); + sp_256_point_free_8(point, 0, heap); + + return err; +} + #ifdef WOLFSSL_SP_SMALL +/* Striping precomputation table. + * 4 points combined into a table of 16 points. + * Distance of 64 between points. + */ static const sp_table_entry_256 p256_table[16] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -33415,6 +34126,11 @@ static const sp_table_entry_256 p256_table[16] = { /* Multiply the base point of P256 by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Stripe implementation. + * Pre-generated: 2^0, 2^64, ... + * Pre-generated: products of all combinations of above. + * 4 doubles and adds (with qz=1) + * * r Resulting point. * k Scalar to multiply by. * map Indicates whether to convert result to affine. @@ -33430,6 +34146,10 @@ static int sp_256_ecc_mulmod_base_8(sp_point_256* r, const sp_digit* k, } #else +/* Striping precomputation table. + * 8 points combined into a table of 256 points. + * Distance of 32 between points. + */ static const sp_table_entry_256 p256_table[256] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -34714,6 +35434,11 @@ static const sp_table_entry_256 p256_table[256] = { /* Multiply the base point of P256 by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Stripe implementation. + * Pre-generated: 2^0, 2^32, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * * r Resulting point. * k Scalar to multiply by. * map Indicates whether to convert result to affine. @@ -34739,7 +35464,7 @@ static int sp_256_ecc_mulmod_base_8(sp_point_256* r, const sp_digit* k, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) +int sp_ecc_mulmod_base_256(const mp_int* km, ecc_point* r, int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_256 p; @@ -34780,6 +35505,87 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) return err; } +/* Multiply the base point of P256 by the scalar, add point a and return + * the result. If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_add_256(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_256 p; + sp_point_256 a; + sp_digit kd[8]; + sp_digit t[8 * 2 * 5]; +#endif + sp_point_256* point; + sp_point_256* addP = NULL; + sp_digit* tmp = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_256_point_new_8(heap, p, point); + if (err == MP_OKAY) { + err = sp_256_point_new_8(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (8 + 8 * 2 * 5), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 8; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_256_from_mp(k, 8, km); + sp_256_point_from_ecc_point_8(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_8(addP->x, addP->x, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_8(addP->y, addP->y, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_8(addP->z, addP->z, p256_mod); + } + if (err == MP_OKAY) { + err = sp_256_ecc_mulmod_base_8(point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_256_proj_point_add_8(point, point, addP, tmp); + + if (map) { + sp_256_map_8(point, point, tmp); + } + + err = sp_256_point_to_ecc_point_8(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_256_point_free_8(addP, 0, heap); + sp_256_point_free_8(point, 0, heap); + + return err; +} + #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \ defined(HAVE_ECC_VERIFY) /* Returns 1 if the number of zero. @@ -34793,7 +35599,7 @@ static int sp_256_iszero_8(const sp_digit* a) return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6] | a[7]) == 0; } -#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN | HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ /* Add 1 to a. (a = a + 1) * * a A single precision integer. @@ -34840,7 +35646,8 @@ static void sp_256_add_one_8(sp_digit* a) */ static void sp_256_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -34984,7 +35791,10 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) */ static void sp_256_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; j = 256 / 8 - 1; a[j] = 0; @@ -35025,7 +35835,7 @@ static void sp_256_to_bin(sp_digit* r, byte* a) * returns BUFFER_E if the buffer is to small for output size, * MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, +int sp_ecc_secret_gen_256(const mp_int* priv, const ecc_point* pub, byte* out, word32* outLen, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) @@ -35076,564 +35886,6 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, #endif /* HAVE_ECC_DHE */ #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) -#ifdef WOLFSSL_SP_SMALL -/* Multiply a and b into r. (r = a * b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -static void sp_256_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) -{ - __asm__ __volatile__ ( - "sub sp, sp, #64\n\t" - "mov r5, #0\n\t" - "mov r6, #0\n\t" - "mov r7, #0\n\t" - "mov r8, #0\n\t" - "\n1:\n\t" - "subs r3, r5, #28\n\t" - "it cc\n\t" - "movcc r3, #0\n\t" - "sub r4, r5, r3\n\t" - "\n2:\n\t" - "ldr r14, [%[a], r3]\n\t" - "ldr r12, [%[b], r4]\n\t" - "umull r9, r10, r14, r12\n\t" - "adds r6, r6, r9\n\t" - "adcs r7, r7, r10\n\t" - "adc r8, r8, #0\n\t" - "add r3, r3, #4\n\t" - "sub r4, r4, #4\n\t" - "cmp r3, #32\n\t" - "beq 3f\n\t" - "cmp r3, r5\n\t" - "ble 2b\n\t" - "\n3:\n\t" - "str r6, [sp, r5]\n\t" - "mov r6, r7\n\t" - "mov r7, r8\n\t" - "mov r8, #0\n\t" - "add r5, r5, #4\n\t" - "cmp r5, #56\n\t" - "ble 1b\n\t" - "str r6, [sp, r5]\n\t" - "\n4:\n\t" - "ldr r6, [sp, #0]\n\t" - "ldr r7, [sp, #4]\n\t" - "ldr r8, [sp, #8]\n\t" - "ldr r3, [sp, #12]\n\t" - "str r6, [%[r], #0]\n\t" - "str r7, [%[r], #4]\n\t" - "str r8, [%[r], #8]\n\t" - "str r3, [%[r], #12]\n\t" - "add sp, sp, #16\n\t" - "add %[r], %[r], #16\n\t" - "subs r5, r5, #16\n\t" - "bgt 4b\n\t" - : [r] "+r" (r) - : [a] "r" (a), [b] "r" (b) - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" - ); -} - -#else -/* Multiply a and b into r. (r = a * b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -static void sp_256_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) -{ - __asm__ __volatile__ ( - "sub sp, sp, #32\n\t" - "mov r10, #0\n\t" - "# A[0] * B[0]\n\t" - "ldr r8, [%[a], #0]\n\t" - "ldr r9, [%[b], #0]\n\t" - "umull r3, r4, r8, r9\n\t" - "mov r5, #0\n\t" - "str r3, [sp]\n\t" - "# A[0] * B[1]\n\t" - "ldr r8, [%[a], #0]\n\t" - "ldr r9, [%[b], #4]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r10, r10\n\t" - "# A[1] * B[0]\n\t" - "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #0]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "str r4, [sp, #4]\n\t" - "# A[0] * B[2]\n\t" - "ldr r8, [%[a], #0]\n\t" - "ldr r9, [%[b], #8]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r10, r10\n\t" - "# A[1] * B[1]\n\t" - "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #4]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[2] * B[0]\n\t" - "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #0]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "str r5, [sp, #8]\n\t" - "# A[0] * B[3]\n\t" - "ldr r8, [%[a], #0]\n\t" - "ldr r9, [%[b], #12]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r10, r10\n\t" - "# A[1] * B[2]\n\t" - "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #8]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[2] * B[1]\n\t" - "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #4]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[3] * B[0]\n\t" - "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #0]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "str r3, [sp, #12]\n\t" - "# A[0] * B[4]\n\t" - "ldr r8, [%[a], #0]\n\t" - "ldr r9, [%[b], #16]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r10, r10\n\t" - "# A[1] * B[3]\n\t" - "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #12]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[2] * B[2]\n\t" - "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #8]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[3] * B[1]\n\t" - "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #4]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[4] * B[0]\n\t" - "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #0]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "str r4, [sp, #16]\n\t" - "# A[0] * B[5]\n\t" - "ldr r8, [%[a], #0]\n\t" - "ldr r9, [%[b], #20]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r10, r10\n\t" - "# A[1] * B[4]\n\t" - "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #16]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[2] * B[3]\n\t" - "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #12]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[3] * B[2]\n\t" - "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #8]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[4] * B[1]\n\t" - "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #4]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[5] * B[0]\n\t" - "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #0]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "str r5, [sp, #20]\n\t" - "# A[0] * B[6]\n\t" - "ldr r8, [%[a], #0]\n\t" - "ldr r9, [%[b], #24]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r10, r10\n\t" - "# A[1] * B[5]\n\t" - "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #20]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[2] * B[4]\n\t" - "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #16]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[3] * B[3]\n\t" - "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #12]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[4] * B[2]\n\t" - "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #8]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[5] * B[1]\n\t" - "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #4]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[6] * B[0]\n\t" - "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #0]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "str r3, [sp, #24]\n\t" - "# A[0] * B[7]\n\t" - "ldr r8, [%[a], #0]\n\t" - "ldr r9, [%[b], #28]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r10, r10\n\t" - "# A[1] * B[6]\n\t" - "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #24]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[2] * B[5]\n\t" - "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #20]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[3] * B[4]\n\t" - "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #16]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[4] * B[3]\n\t" - "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #12]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[5] * B[2]\n\t" - "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #8]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[6] * B[1]\n\t" - "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #4]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[7] * B[0]\n\t" - "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #0]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "str r4, [sp, #28]\n\t" - "# A[1] * B[7]\n\t" - "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #28]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r10, r10\n\t" - "# A[2] * B[6]\n\t" - "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #24]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[3] * B[5]\n\t" - "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #20]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[4] * B[4]\n\t" - "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #16]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[5] * B[3]\n\t" - "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #12]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[6] * B[2]\n\t" - "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #8]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[7] * B[1]\n\t" - "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #4]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "str r5, [%[r], #32]\n\t" - "# A[2] * B[7]\n\t" - "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #28]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r10, r10\n\t" - "# A[3] * B[6]\n\t" - "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #24]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[4] * B[5]\n\t" - "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #20]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[5] * B[4]\n\t" - "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #16]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[6] * B[3]\n\t" - "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #12]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[7] * B[2]\n\t" - "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #8]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "str r3, [%[r], #36]\n\t" - "# A[3] * B[7]\n\t" - "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #28]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r10, r10\n\t" - "# A[4] * B[6]\n\t" - "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #24]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[5] * B[5]\n\t" - "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #20]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[6] * B[4]\n\t" - "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #16]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[7] * B[3]\n\t" - "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #12]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "str r4, [%[r], #40]\n\t" - "# A[4] * B[7]\n\t" - "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #28]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r10, r10\n\t" - "# A[5] * B[6]\n\t" - "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #24]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[6] * B[5]\n\t" - "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #20]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[7] * B[4]\n\t" - "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #16]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "str r5, [%[r], #44]\n\t" - "# A[5] * B[7]\n\t" - "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #28]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r10, r10\n\t" - "# A[6] * B[6]\n\t" - "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #24]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[7] * B[5]\n\t" - "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #20]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "str r3, [%[r], #48]\n\t" - "# A[6] * B[7]\n\t" - "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #28]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r10, r10\n\t" - "# A[7] * B[6]\n\t" - "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #24]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "str r4, [%[r], #52]\n\t" - "# A[7] * B[7]\n\t" - "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #28]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adc r3, r3, r7\n\t" - "str r5, [%[r], #56]\n\t" - "str r3, [%[r], #60]\n\t" - "ldr r3, [sp, #0]\n\t" - "ldr r4, [sp, #4]\n\t" - "ldr r5, [sp, #8]\n\t" - "ldr r6, [sp, #12]\n\t" - "str r3, [%[r], #0]\n\t" - "str r4, [%[r], #4]\n\t" - "str r5, [%[r], #8]\n\t" - "str r6, [%[r], #12]\n\t" - "ldr r3, [sp, #16]\n\t" - "ldr r4, [sp, #20]\n\t" - "ldr r5, [sp, #24]\n\t" - "ldr r6, [sp, #28]\n\t" - "str r3, [%[r], #16]\n\t" - "str r4, [%[r], #20]\n\t" - "str r5, [%[r], #24]\n\t" - "str r6, [%[r], #28]\n\t" - "add sp, sp, #32\n\t" - : - : [r] "r" (r), [a] "r" (a), [b] "r" (b) - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" - ); -} - -#endif /* WOLFSSL_SP_SMALL */ #endif #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) #ifdef WOLFSSL_SP_SMALL @@ -35778,51 +36030,45 @@ static void sp_256_mul_d_8(sp_digit* r, const sp_digit* a, "str r3, [%[r]]\n\t" "# A[1] * B\n\t" "ldr r8, [%[a], #4]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #4]\n\t" "# A[2] * B\n\t" "ldr r8, [%[a], #8]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #8]\n\t" "# A[3] * B\n\t" "ldr r8, [%[a], #12]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #12]\n\t" "# A[4] * B\n\t" "ldr r8, [%[a], #16]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #16]\n\t" "# A[5] * B\n\t" "ldr r8, [%[a], #20]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #20]\n\t" "# A[6] * B\n\t" "ldr r8, [%[a], #24]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #24]\n\t" "# A[7] * B\n\t" "ldr r8, [%[a], #28]\n\t" @@ -35981,435 +36227,6 @@ static WC_INLINE int sp_256_mod_8(sp_digit* r, const sp_digit* a, const sp_digit #endif #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) #ifdef WOLFSSL_SP_SMALL -/* Square a and put result in r. (r = a * a) - * - * r A single precision integer. - * a A single precision integer. - */ -static void sp_256_sqr_8(sp_digit* r, const sp_digit* a) -{ - __asm__ __volatile__ ( - "sub sp, sp, #64\n\t" - "mov r12, #0\n\t" - "mov r6, #0\n\t" - "mov r7, #0\n\t" - "mov r8, #0\n\t" - "mov r5, #0\n\t" - "\n1:\n\t" - "subs r3, r5, #28\n\t" - "it cc\n\t" - "movcc r3, r12\n\t" - "sub r4, r5, r3\n\t" - "\n2:\n\t" - "cmp r4, r3\n\t" - "beq 4f\n\t" - "ldr r14, [%[a], r3]\n\t" - "ldr r9, [%[a], r4]\n\t" - "umull r9, r10, r14, r9\n\t" - "adds r6, r6, r9\n\t" - "adcs r7, r7, r10\n\t" - "adc r8, r8, r12\n\t" - "adds r6, r6, r9\n\t" - "adcs r7, r7, r10\n\t" - "adc r8, r8, r12\n\t" - "bal 5f\n\t" - "\n4:\n\t" - "ldr r14, [%[a], r3]\n\t" - "umull r9, r10, r14, r14\n\t" - "adds r6, r6, r9\n\t" - "adcs r7, r7, r10\n\t" - "adc r8, r8, r12\n\t" - "\n5:\n\t" - "add r3, r3, #4\n\t" - "sub r4, r4, #4\n\t" - "cmp r3, #32\n\t" - "beq 3f\n\t" - "cmp r3, r4\n\t" - "bgt 3f\n\t" - "cmp r3, r5\n\t" - "ble 2b\n\t" - "\n3:\n\t" - "str r6, [sp, r5]\n\t" - "mov r6, r7\n\t" - "mov r7, r8\n\t" - "mov r8, #0\n\t" - "add r5, r5, #4\n\t" - "cmp r5, #56\n\t" - "ble 1b\n\t" - "str r6, [sp, r5]\n\t" - "\n4:\n\t" - "ldr r6, [sp, #0]\n\t" - "ldr r7, [sp, #4]\n\t" - "ldr r8, [sp, #8]\n\t" - "ldr r3, [sp, #12]\n\t" - "str r6, [%[r], #0]\n\t" - "str r7, [%[r], #4]\n\t" - "str r8, [%[r], #8]\n\t" - "str r3, [%[r], #12]\n\t" - "add sp, sp, #16\n\t" - "add %[r], %[r], #16\n\t" - "subs r5, r5, #16\n\t" - "bgt 4b\n\t" - : [r] "+r" (r) - : [a] "r" (a) - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r9", "r12" - ); -} - -#else -/* Square a and put result in r. (r = a * a) - * - * r A single precision integer. - * a A single precision integer. - */ -static void sp_256_sqr_8(sp_digit* r, const sp_digit* a) -{ - __asm__ __volatile__ ( - "sub sp, sp, #32\n\t" - "mov r14, #0\n\t" - "# A[0] * A[0]\n\t" - "ldr r10, [%[a], #0]\n\t" - "umull r8, r3, r10, r10\n\t" - "mov r4, #0\n\t" - "str r8, [sp]\n\t" - "# A[0] * A[1]\n\t" - "ldr r10, [%[a], #4]\n\t" - "ldr r8, [%[a], #0]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r14, r14\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" - "str r3, [sp, #4]\n\t" - "# A[0] * A[2]\n\t" - "ldr r10, [%[a], #8]\n\t" - "ldr r8, [%[a], #0]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r4, r4, r8\n\t" - "adcs r2, r2, r9\n\t" - "adc r3, r14, r14\n\t" - "adds r4, r4, r8\n\t" - "adcs r2, r2, r9\n\t" - "adc r3, r3, r14\n\t" - "# A[1] * A[1]\n\t" - "ldr r10, [%[a], #4]\n\t" - "umull r8, r9, r10, r10\n\t" - "adds r4, r4, r8\n\t" - "adcs r2, r2, r9\n\t" - "adc r3, r3, r14\n\t" - "str r4, [sp, #8]\n\t" - "# A[0] * A[3]\n\t" - "ldr r10, [%[a], #12]\n\t" - "ldr r8, [%[a], #0]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r2, r2, r8\n\t" - "adcs r3, r3, r9\n\t" - "adc r4, r14, r14\n\t" - "adds r2, r2, r8\n\t" - "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" - "# A[1] * A[2]\n\t" - "ldr r10, [%[a], #8]\n\t" - "ldr r8, [%[a], #4]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r2, r2, r8\n\t" - "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" - "adds r2, r2, r8\n\t" - "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" - "str r2, [sp, #12]\n\t" - "# A[0] * A[4]\n\t" - "ldr r10, [%[a], #16]\n\t" - "ldr r8, [%[a], #0]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r14, r14\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" - "# A[1] * A[3]\n\t" - "ldr r10, [%[a], #12]\n\t" - "ldr r8, [%[a], #4]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" - "# A[2] * A[2]\n\t" - "ldr r10, [%[a], #8]\n\t" - "umull r8, r9, r10, r10\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" - "str r3, [sp, #16]\n\t" - "# A[0] * A[5]\n\t" - "ldr r10, [%[a], #20]\n\t" - "ldr r8, [%[a], #0]\n\t" - "umull r5, r6, r10, r8\n\t" - "mov r3, #0\n\t" - "mov r7, #0\n\t" - "# A[1] * A[4]\n\t" - "ldr r10, [%[a], #16]\n\t" - "ldr r8, [%[a], #4]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[2] * A[3]\n\t" - "ldr r10, [%[a], #12]\n\t" - "ldr r8, [%[a], #8]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "adds r5, r5, r5\n\t" - "adcs r6, r6, r6\n\t" - "adc r7, r7, r7\n\t" - "adds r4, r4, r5\n\t" - "adcs r2, r2, r6\n\t" - "adc r3, r3, r7\n\t" - "str r4, [sp, #20]\n\t" - "# A[0] * A[6]\n\t" - "ldr r10, [%[a], #24]\n\t" - "ldr r8, [%[a], #0]\n\t" - "umull r5, r6, r10, r8\n\t" - "mov r4, #0\n\t" - "mov r7, #0\n\t" - "# A[1] * A[5]\n\t" - "ldr r10, [%[a], #20]\n\t" - "ldr r8, [%[a], #4]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[2] * A[4]\n\t" - "ldr r10, [%[a], #16]\n\t" - "ldr r8, [%[a], #8]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[3] * A[3]\n\t" - "ldr r10, [%[a], #12]\n\t" - "umull r8, r9, r10, r10\n\t" - "adds r5, r5, r5\n\t" - "adcs r6, r6, r6\n\t" - "adc r7, r7, r7\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "adds r2, r2, r5\n\t" - "adcs r3, r3, r6\n\t" - "adc r4, r4, r7\n\t" - "str r2, [sp, #24]\n\t" - "# A[0] * A[7]\n\t" - "ldr r10, [%[a], #28]\n\t" - "ldr r8, [%[a], #0]\n\t" - "umull r5, r6, r10, r8\n\t" - "mov r2, #0\n\t" - "mov r7, #0\n\t" - "# A[1] * A[6]\n\t" - "ldr r10, [%[a], #24]\n\t" - "ldr r8, [%[a], #4]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[2] * A[5]\n\t" - "ldr r10, [%[a], #20]\n\t" - "ldr r8, [%[a], #8]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[3] * A[4]\n\t" - "ldr r10, [%[a], #16]\n\t" - "ldr r8, [%[a], #12]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "adds r5, r5, r5\n\t" - "adcs r6, r6, r6\n\t" - "adc r7, r7, r7\n\t" - "adds r3, r3, r5\n\t" - "adcs r4, r4, r6\n\t" - "adc r2, r2, r7\n\t" - "str r3, [sp, #28]\n\t" - "# A[1] * A[7]\n\t" - "ldr r10, [%[a], #28]\n\t" - "ldr r8, [%[a], #4]\n\t" - "umull r5, r6, r10, r8\n\t" - "mov r3, #0\n\t" - "mov r7, #0\n\t" - "# A[2] * A[6]\n\t" - "ldr r10, [%[a], #24]\n\t" - "ldr r8, [%[a], #8]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[3] * A[5]\n\t" - "ldr r10, [%[a], #20]\n\t" - "ldr r8, [%[a], #12]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[4] * A[4]\n\t" - "ldr r10, [%[a], #16]\n\t" - "umull r8, r9, r10, r10\n\t" - "adds r5, r5, r5\n\t" - "adcs r6, r6, r6\n\t" - "adc r7, r7, r7\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "adds r4, r4, r5\n\t" - "adcs r2, r2, r6\n\t" - "adc r3, r3, r7\n\t" - "str r4, [%[r], #32]\n\t" - "# A[2] * A[7]\n\t" - "ldr r10, [%[a], #28]\n\t" - "ldr r8, [%[a], #8]\n\t" - "umull r5, r6, r10, r8\n\t" - "mov r4, #0\n\t" - "mov r7, #0\n\t" - "# A[3] * A[6]\n\t" - "ldr r10, [%[a], #24]\n\t" - "ldr r8, [%[a], #12]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[4] * A[5]\n\t" - "ldr r10, [%[a], #20]\n\t" - "ldr r8, [%[a], #16]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "adds r5, r5, r5\n\t" - "adcs r6, r6, r6\n\t" - "adc r7, r7, r7\n\t" - "adds r2, r2, r5\n\t" - "adcs r3, r3, r6\n\t" - "adc r4, r4, r7\n\t" - "str r2, [%[r], #36]\n\t" - "# A[3] * A[7]\n\t" - "ldr r10, [%[a], #28]\n\t" - "ldr r8, [%[a], #12]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r14, r14\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" - "# A[4] * A[6]\n\t" - "ldr r10, [%[a], #24]\n\t" - "ldr r8, [%[a], #16]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" - "# A[5] * A[5]\n\t" - "ldr r10, [%[a], #20]\n\t" - "umull r8, r9, r10, r10\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" - "str r3, [%[r], #40]\n\t" - "# A[4] * A[7]\n\t" - "ldr r10, [%[a], #28]\n\t" - "ldr r8, [%[a], #16]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r4, r4, r8\n\t" - "adcs r2, r2, r9\n\t" - "adc r3, r14, r14\n\t" - "adds r4, r4, r8\n\t" - "adcs r2, r2, r9\n\t" - "adc r3, r3, r14\n\t" - "# A[5] * A[6]\n\t" - "ldr r10, [%[a], #24]\n\t" - "ldr r8, [%[a], #20]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r4, r4, r8\n\t" - "adcs r2, r2, r9\n\t" - "adc r3, r3, r14\n\t" - "adds r4, r4, r8\n\t" - "adcs r2, r2, r9\n\t" - "adc r3, r3, r14\n\t" - "str r4, [%[r], #44]\n\t" - "# A[5] * A[7]\n\t" - "ldr r10, [%[a], #28]\n\t" - "ldr r8, [%[a], #20]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r2, r2, r8\n\t" - "adcs r3, r3, r9\n\t" - "adc r4, r14, r14\n\t" - "adds r2, r2, r8\n\t" - "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" - "# A[6] * A[6]\n\t" - "ldr r10, [%[a], #24]\n\t" - "umull r8, r9, r10, r10\n\t" - "adds r2, r2, r8\n\t" - "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" - "str r2, [%[r], #48]\n\t" - "# A[6] * A[7]\n\t" - "ldr r10, [%[a], #28]\n\t" - "ldr r8, [%[a], #24]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r14, r14\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" - "str r3, [%[r], #52]\n\t" - "# A[7] * A[7]\n\t" - "ldr r10, [%[a], #28]\n\t" - "umull r8, r9, r10, r10\n\t" - "adds r4, r4, r8\n\t" - "adc r2, r2, r9\n\t" - "str r4, [%[r], #56]\n\t" - "str r2, [%[r], #60]\n\t" - "ldr r2, [sp, #0]\n\t" - "ldr r3, [sp, #4]\n\t" - "ldr r4, [sp, #8]\n\t" - "ldr r8, [sp, #12]\n\t" - "str r2, [%[r], #0]\n\t" - "str r3, [%[r], #4]\n\t" - "str r4, [%[r], #8]\n\t" - "str r8, [%[r], #12]\n\t" - "ldr r2, [sp, #16]\n\t" - "ldr r3, [sp, #20]\n\t" - "ldr r4, [sp, #24]\n\t" - "ldr r8, [sp, #28]\n\t" - "str r2, [%[r], #16]\n\t" - "str r3, [%[r], #20]\n\t" - "str r4, [%[r], #24]\n\t" - "str r8, [%[r], #28]\n\t" - "add sp, sp, #32\n\t" - : - : [r] "r" (r), [a] "r" (a) - : "memory", "r2", "r3", "r4", "r8", "r9", "r10", "r8", "r5", "r6", "r7", "r14" - ); -} - -#endif /* WOLFSSL_SP_SMALL */ -#ifdef WOLFSSL_SP_SMALL /* Order-2 for the P256 curve. */ static const uint32_t p256_order_minus_2[8] = { 0xfc63254fU,0xf3b9cac2U,0xa7179e84U,0xbce6faadU,0xffffffffU,0xffffffffU, @@ -36417,7 +36234,7 @@ static const uint32_t p256_order_minus_2[8] = { }; #else /* The low half of the order-2 of the P256 curve. */ -static const uint32_t p256_order_low[4] = { +static const sp_int_digit p256_order_low[4] = { 0xfc63254fU,0xf3b9cac2U,0xa7179e84U,0xbce6faadU }; #endif /* WOLFSSL_SP_SMALL */ @@ -36563,7 +36380,7 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6 */ for (i=127; i>=112; i--) { sp_256_mont_sqr_order_8(t2, t2); - if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_256_mont_mul_order_8(t2, t2, a); } } @@ -36573,7 +36390,7 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84 */ for (i=107; i>=64; i--) { sp_256_mont_sqr_order_8(t2, t2); - if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_256_mont_mul_order_8(t2, t2, a); } } @@ -36583,7 +36400,7 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2 */ for (i=59; i>=32; i--) { sp_256_mont_sqr_order_8(t2, t2); - if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_256_mont_mul_order_8(t2, t2, a); } } @@ -36593,7 +36410,7 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254 */ for (i=27; i>=0; i--) { sp_256_mont_sqr_order_8(t2, t2); - if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_256_mont_mul_order_8(t2, t2, a); } } @@ -36604,12 +36421,63 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a, #endif /* WOLFSSL_SP_SMALL */ } -#endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ #ifdef HAVE_ECC_SIGN #ifndef SP_ECC_MAX_SIG_GEN #define SP_ECC_MAX_SIG_GEN 64 #endif +/* Calculate second signature value S from R, k and private value. + * + * s = (r * x + e) / k + * + * s Signature value. + * r First signature value. + * k Ephemeral private key. + * x Private key as a number. + * e Hash of message as a number. + * tmp Temporary storage for intermediate numbers. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_256_calc_s_8(sp_digit* s, const sp_digit* r, sp_digit* k, + sp_digit* x, const sp_digit* e, sp_digit* tmp) +{ + int err; + sp_digit carry; + int32_t c; + sp_digit* kInv = k; + + /* Conv k to Montgomery form (mod order) */ + sp_256_mul_8(k, k, p256_norm_order); + err = sp_256_mod_8(k, k, p256_order); + if (err == MP_OKAY) { + sp_256_norm_8(k); + + /* kInv = 1/k mod order */ + sp_256_mont_inv_order_8(kInv, k, tmp); + sp_256_norm_8(kInv); + + /* s = r * x + e */ + sp_256_mul_8(x, x, r); + err = sp_256_mod_8(x, x, p256_order); + } + if (err == MP_OKAY) { + sp_256_norm_8(x); + carry = sp_256_add_8(s, e, x); + sp_256_cond_sub_8(s, s, p256_order, 0 - carry); + sp_256_norm_8(s); + c = sp_256_cmp_8(s, p256_order); + sp_256_cond_sub_8(s, s, p256_order, 0L - (sp_digit)(c >= 0)); + sp_256_norm_8(s); + + /* s = s * k^-1 mod order */ + sp_256_mont_mul_order_8(s, s, kInv); + sp_256_norm_8(s); + } + + return err; +} + /* Sign the hash using the private key. * e = [hash, 256 bits] from binary * r = (k.G)->x mod order @@ -36644,8 +36512,8 @@ typedef struct sp_ecc_sign_256_ctx { int i; } sp_ecc_sign_256_ctx; -int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, + mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_sign_256_ctx* ctx = (sp_ecc_sign_256_ctx*)sp_ctx->data; @@ -36785,8 +36653,8 @@ int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, W } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, + const mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -36804,11 +36672,9 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit* r = NULL; sp_digit* tmp = NULL; sp_point_256* point = NULL; - sp_digit carry; sp_digit* s = NULL; - sp_digit* kInv = NULL; - int err = MP_OKAY; int32_t c; + int err = MP_OKAY; int i; (void)heap; @@ -36839,7 +36705,6 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, tmp = td; #endif s = e; - kInv = k; if (hashLen > 32U) { hashLen = 32U; @@ -36847,8 +36712,6 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, } for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) { - sp_256_from_mp(x, 8, priv); - /* New random point. */ if (km == NULL || mp_iszero(km)) { err = sp_256_ecc_gen_k_8(rng, k); @@ -36858,7 +36721,7 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, mp_zero(km); } if (err == MP_OKAY) { - err = sp_256_ecc_mulmod_base_8(point, k, 1, 1, NULL); + err = sp_256_ecc_mulmod_base_8(point, k, 1, 1, heap); } if (err == MP_OKAY) { @@ -36869,38 +36732,15 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_256_cond_sub_8(r, r, p256_order, 0L - (sp_digit)(c >= 0)); sp_256_norm_8(r); - /* Conv k to Montgomery form (mod order) */ - sp_256_mul_8(k, k, p256_norm_order); - err = sp_256_mod_8(k, k, p256_order); - } - if (err == MP_OKAY) { - sp_256_norm_8(k); - /* kInv = 1/k mod order */ - sp_256_mont_inv_order_8(kInv, k, tmp); - sp_256_norm_8(kInv); - - /* s = r * x + e */ - sp_256_mul_8(x, x, r); - err = sp_256_mod_8(x, x, p256_order); - } - if (err == MP_OKAY) { - sp_256_norm_8(x); + sp_256_from_mp(x, 8, priv); sp_256_from_bin(e, 8, hash, (int)hashLen); - carry = sp_256_add_8(s, e, x); - sp_256_cond_sub_8(s, s, p256_order, 0 - carry); - sp_256_norm_8(s); - c = sp_256_cmp_8(s, p256_order); - sp_256_cond_sub_8(s, s, p256_order, 0L - (sp_digit)(c >= 0)); - sp_256_norm_8(s); - /* s = s * k^-1 mod order */ - sp_256_mont_mul_order_8(s, s, kInv); - sp_256_norm_8(s); + err = sp_256_calc_s_8(s, r, k, x, e, tmp); + } - /* Check that signature is usable. */ - if (sp_256_iszero_8(s) == 0) { - break; - } + /* Check that signature is usable. */ + if ((err == MP_OKAY) && (sp_256_iszero_8(s) == 0)) { + break; } #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP i = 1; @@ -36928,7 +36768,6 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, XMEMSET(x, 0, sizeof(sp_digit) * 2U * 8U); XMEMSET(k, 0, sizeof(sp_digit) * 2U * 8U); XMEMSET(r, 0, sizeof(sp_digit) * 2U * 8U); - XMEMSET(r, 0, sizeof(sp_digit) * 2U * 8U); XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 8U); #endif sp_256_point_free_8(point, 1, heap); @@ -37224,6 +37063,96 @@ static int sp_256_mod_inv_8(sp_digit* r, const sp_digit* a, const sp_digit* m) } #endif /* WOLFSSL_SP_SMALL */ + +/* Add point p1 into point p2. Handles p1 == p2 and result at infinity. + * + * p1 First point to add and holds result. + * p2 Second point to add. + * tmp Temporary storage for intermediate numbers. + */ +static void sp_256_add_points_8(sp_point_256* p1, const sp_point_256* p2, + sp_digit* tmp) +{ + + sp_256_proj_point_add_8(p1, p1, p2, tmp); + if (sp_256_iszero_8(p1->z)) { + if (sp_256_iszero_8(p1->x) && sp_256_iszero_8(p1->y)) { + sp_256_proj_point_dbl_8(p1, p2, tmp); + } + else { + /* Y ordinate is not used from here - don't set. */ + p1->x[0] = 0; + p1->x[1] = 0; + p1->x[2] = 0; + p1->x[3] = 0; + p1->x[4] = 0; + p1->x[5] = 0; + p1->x[6] = 0; + p1->x[7] = 0; + XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod)); + } + } +} + +/* Calculate the verification point: [e/s]G + [r/s]Q + * + * p1 Calculated point. + * p2 Public point and temporary. + * s Second part of signature as a number. + * u1 Temporary number. + * u2 Temproray number. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_256_calc_vfy_point_8(sp_point_256* p1, sp_point_256* p2, + sp_digit* s, sp_digit* u1, sp_digit* u2, sp_digit* tmp, void* heap) +{ + int err; + +#ifndef WOLFSSL_SP_SMALL + { + sp_256_mod_inv_8(s, s, p256_order); + } +#endif /* !WOLFSSL_SP_SMALL */ + { + sp_256_mul_8(s, s, p256_norm_order); + } + err = sp_256_mod_8(s, s, p256_order); + if (err == MP_OKAY) { + sp_256_norm_8(s); +#ifdef WOLFSSL_SP_SMALL + { + sp_256_mont_inv_order_8(s, s, tmp); + sp_256_mont_mul_order_8(u1, u1, s); + sp_256_mont_mul_order_8(u2, u2, s); + } + +#else + { + sp_256_mont_mul_order_8(u1, u1, s); + sp_256_mont_mul_order_8(u2, u2, s); + } + +#endif /* WOLFSSL_SP_SMALL */ + err = sp_256_ecc_mulmod_base_8(p1, u1, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_256_iszero_8(p1->z)) { + p1->infinity = 1; + } + if (err == MP_OKAY) { + err = sp_256_ecc_mulmod_8(p2, p2, u2, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_256_iszero_8(p2->z)) { + p2->infinity = 1; + } + + if (err == MP_OKAY) { + sp_256_add_points_8(p1, p2, tmp); + } + + return err; +} + #ifdef HAVE_ECC_VERIFY /* Verify the signature values with the hash and public key. * e = Truncate(hash, 256) @@ -37242,8 +37171,7 @@ static int sp_256_mod_inv_8(sp_digit* r, const sp_digit* a, const sp_digit* m) * rm First part of result as an mp_int. * sm Sirst part of result as an mp_int. * heap Heap to use for allocation. - * returns RNG failures, MEMORY_E when memory allocation fails and - * MP_OKAY on success. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ #ifdef WOLFSSL_SP_NONBLOCK typedef struct sp_ecc_verify_256_ctx { @@ -37262,8 +37190,9 @@ typedef struct sp_ecc_verify_256_ctx { sp_point_256 p2; } sp_ecc_verify_256_ctx; -int sp_ecc_verify_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, + word32 hashLen, const mp_int* pX, const mp_int* pY, const mp_int* pZ, + const mp_int* r, const mp_int* sm, int* res, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_verify_256_ctx* ctx = (sp_ecc_verify_256_ctx*)sp_ctx->data; @@ -37417,8 +37346,9 @@ int sp_ecc_verify_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_256(const byte* hash, word32 hashLen, const mp_int* pX, + const mp_int* pY, const mp_int* pZ, const mp_int* r, const mp_int* sm, + int* res, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -37437,7 +37367,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_point_256* p1; sp_point_256* p2 = NULL; sp_digit carry; - int32_t c; + int32_t c = 0; int err; err = sp_256_point_new_8(heap, p1d, p1); @@ -37478,66 +37408,9 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_256_from_mp(p2->y, 8, pY); sp_256_from_mp(p2->z, 8, pZ); -#ifndef WOLFSSL_SP_SMALL - { - sp_256_mod_inv_8(s, s, p256_order); - } -#endif /* !WOLFSSL_SP_SMALL */ - { - sp_256_mul_8(s, s, p256_norm_order); - } - err = sp_256_mod_8(s, s, p256_order); + err = sp_256_calc_vfy_point_8(p1, p2, s, u1, u2, tmp, heap); } if (err == MP_OKAY) { - sp_256_norm_8(s); -#ifdef WOLFSSL_SP_SMALL - { - sp_256_mont_inv_order_8(s, s, tmp); - sp_256_mont_mul_order_8(u1, u1, s); - sp_256_mont_mul_order_8(u2, u2, s); - } - -#else - { - sp_256_mont_mul_order_8(u1, u1, s); - sp_256_mont_mul_order_8(u2, u2, s); - } - -#endif /* WOLFSSL_SP_SMALL */ - err = sp_256_ecc_mulmod_base_8(p1, u1, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_256_iszero_8(p1->z)) { - p1->infinity = 1; - } - if (err == MP_OKAY) { - err = sp_256_ecc_mulmod_8(p2, p2, u2, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_256_iszero_8(p2->z)) { - p2->infinity = 1; - } - - if (err == MP_OKAY) { - { - sp_256_proj_point_add_8(p1, p1, p2, tmp); - if (sp_256_iszero_8(p1->z)) { - if (sp_256_iszero_8(p1->x) && sp_256_iszero_8(p1->y)) { - sp_256_proj_point_dbl_8(p1, p2, tmp); - } - else { - /* Y ordinate is not used from here - don't set. */ - p1->x[0] = 0; - p1->x[1] = 0; - p1->x[2] = 0; - p1->x[3] = 0; - p1->x[4] = 0; - p1->x[5] = 0; - p1->x[6] = 0; - p1->x[7] = 0; - XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod)); - } - } - } - /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */ /* Reload r and convert to Montgomery form. */ sp_256_from_mp(u2, 8, r); @@ -37559,16 +37432,16 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, /* Compare with mod and if greater or equal then not valid. */ c = sp_256_cmp_8(u2, p256_mod); - if (c < 0) { - /* Convert to Montogomery form */ - err = sp_256_mod_mul_norm_8(u2, u2, p256_mod); - if (err == MP_OKAY) { - /* u1 = (r + 1*order).z'.z' mod prime */ - sp_256_mont_mul_8(u1, u2, p1->z, p256_mod, - p256_mp_mod); - *res = (int)(sp_256_cmp_8(p1->x, u1) == 0); - } - } + } + } + if ((*res == 0) && (c < 0)) { + /* Convert to Montogomery form */ + err = sp_256_mod_mul_norm_8(u2, u2, p256_mod); + if (err == MP_OKAY) { + /* u1 = (r + 1*order).z'.z' mod prime */ + sp_256_mont_mul_8(u1, u2, p1->z, p256_mod, + p256_mp_mod); + *res = (sp_256_cmp_8(p1->x, u1) == 0); } } } @@ -37592,7 +37465,8 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -static int sp_256_ecc_is_point_8(sp_point_256* point, void* heap) +static int sp_256_ecc_is_point_8(const sp_point_256* point, + void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -37655,7 +37529,7 @@ static int sp_256_ecc_is_point_8(sp_point_256* point, void* heap) * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) +int sp_ecc_is_point_256(const mp_int* pX, const mp_int* pY) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_256 pubd; @@ -37689,7 +37563,8 @@ int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and * MP_OKAY otherwise. */ -int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) +int sp_ecc_check_key_256(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit privd[8]; @@ -37743,12 +37618,11 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) } } - if (err == MP_OKAY) { - /* Check range of X and Y */ - if (sp_256_cmp_8(pub->x, p256_mod) >= 0 || - sp_256_cmp_8(pub->y, p256_mod) >= 0) { - err = ECC_OUT_OF_RANGE_E; - } + /* Check range of X and Y */ + if ((err == MP_OKAY) && + ((sp_256_cmp_8(pub->x, p256_mod) >= 0) || + (sp_256_cmp_8(pub->y, p256_mod) >= 0))) { + err = ECC_OUT_OF_RANGE_E; } if (err == MP_OKAY) { @@ -37760,12 +37634,10 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Point * order = infinity */ err = sp_256_ecc_mulmod_8(p, pub, p256_order, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is infinity */ - if ((sp_256_iszero_8(p->x) == 0) || - (sp_256_iszero_8(p->y) == 0)) { - err = ECC_INF_E; - } + /* Check result is infinity */ + if ((err == MP_OKAY) && ((sp_256_iszero_8(p->x) == 0) || + (sp_256_iszero_8(p->y) == 0))) { + err = ECC_INF_E; } if (privm) { @@ -37773,12 +37645,11 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Base * private = point */ err = sp_256_ecc_mulmod_base_8(p, priv, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is public key */ - if (sp_256_cmp_8(p->x, pub->x) != 0 || - sp_256_cmp_8(p->y, pub->y) != 0) { - err = ECC_PRIV_KEY_E; - } + /* Check result is public key */ + if ((err == MP_OKAY) && + ((sp_256_cmp_8(p->x, pub->x) != 0) || + (sp_256_cmp_8(p->y, pub->y) != 0))) { + err = ECC_PRIV_KEY_E; } } @@ -37968,7 +37839,7 @@ int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ) sp_256_from_mp(p->y, 8, pY); sp_256_from_mp(p->z, 8, pZ); - sp_256_map_8(p, p, tmp); + sp_256_map_8(p, p, tmp); } if (err == MP_OKAY) { @@ -38148,9 +38019,13 @@ int sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym) /* Point structure to use. */ typedef struct sp_point_384 { + /* X ordinate of point. */ sp_digit x[2 * 12]; + /* Y ordinate of point. */ sp_digit y[2 * 12]; + /* Z ordinate of point. */ sp_digit z[2 * 12]; + /* Indicates point is at infinity. */ int infinity; } sp_point_384; @@ -38220,336 +38095,6 @@ static const sp_digit p384_b[12] = { }; #endif -static int sp_384_point_new_ex_12(void* heap, sp_point_384* sp, sp_point_384** p) -{ - int ret = MP_OKAY; - (void)heap; -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - (void)sp; - *p = (sp_point_384*)XMALLOC(sizeof(sp_point_384), heap, DYNAMIC_TYPE_ECC); -#else - *p = sp; -#endif - if (*p == NULL) { - ret = MEMORY_E; - } - return ret; -} - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) -/* Allocate memory for point and return error. */ -#define sp_384_point_new_12(heap, sp, p) sp_384_point_new_ex_12((heap), NULL, &(p)) -#else -/* Set pointer to data and return no error. */ -#define sp_384_point_new_12(heap, sp, p) sp_384_point_new_ex_12((heap), &(sp), &(p)) -#endif - - -static void sp_384_point_free_12(sp_point_384* p, int clear, void* heap) -{ -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) -/* If valid pointer then clear point data if requested and free data. */ - if (p != NULL) { - if (clear != 0) { - XMEMSET(p, 0, sizeof(*p)); - } - XFREE(p, heap, DYNAMIC_TYPE_ECC); - } -#else -/* Clear point data if requested. */ - if (clear != 0) { - XMEMSET(p, 0, sizeof(*p)); - } -#endif - (void)heap; -} - -/* Multiply a number by Montogmery normalizer mod modulus (prime). - * - * r The resulting Montgomery form number. - * a The number to convert. - * m The modulus (prime). - * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. - */ -static int sp_384_mod_mul_norm_12(sp_digit* r, const sp_digit* a, const sp_digit* m) -{ -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - int64_t* t; -#else - int64_t t[12]; -#endif - int64_t o; - int err = MP_OKAY; - - (void)m; - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - t = (int64_t*)XMALLOC(sizeof(int64_t) * 12, NULL, DYNAMIC_TYPE_ECC); - if (t == NULL) { - err = MEMORY_E; - } -#endif - - if (err == MP_OKAY) { - /* 1 0 0 0 0 0 0 0 1 1 0 -1 */ - t[0] = 0 + (uint64_t)a[0] + (uint64_t)a[8] + (uint64_t)a[9] - (uint64_t)a[11]; - /* -1 1 0 0 0 0 0 0 -1 0 1 1 */ - t[1] = 0 - (uint64_t)a[0] + (uint64_t)a[1] - (uint64_t)a[8] + (uint64_t)a[10] + (uint64_t)a[11]; - /* 0 -1 1 0 0 0 0 0 0 -1 0 1 */ - t[2] = 0 - (uint64_t)a[1] + (uint64_t)a[2] - (uint64_t)a[9] + (uint64_t)a[11]; - /* 1 0 -1 1 0 0 0 0 1 1 -1 -1 */ - t[3] = 0 + (uint64_t)a[0] - (uint64_t)a[2] + (uint64_t)a[3] + (uint64_t)a[8] + (uint64_t)a[9] - (uint64_t)a[10] - (uint64_t)a[11]; - /* 1 1 0 -1 1 0 0 0 1 2 1 -2 */ - t[4] = 0 + (uint64_t)a[0] + (uint64_t)a[1] - (uint64_t)a[3] + (uint64_t)a[4] + (uint64_t)a[8] + 2 * (uint64_t)a[9] + (uint64_t)a[10] - 2 * (uint64_t)a[11]; - /* 0 1 1 0 -1 1 0 0 0 1 2 1 */ - t[5] = 0 + (uint64_t)a[1] + (uint64_t)a[2] - (uint64_t)a[4] + (uint64_t)a[5] + (uint64_t)a[9] + 2 * (uint64_t)a[10] + (uint64_t)a[11]; - /* 0 0 1 1 0 -1 1 0 0 0 1 2 */ - t[6] = 0 + (uint64_t)a[2] + (uint64_t)a[3] - (uint64_t)a[5] + (uint64_t)a[6] + (uint64_t)a[10] + 2 * (uint64_t)a[11]; - /* 0 0 0 1 1 0 -1 1 0 0 0 1 */ - t[7] = 0 + (uint64_t)a[3] + (uint64_t)a[4] - (uint64_t)a[6] + (uint64_t)a[7] + (uint64_t)a[11]; - /* 0 0 0 0 1 1 0 -1 1 0 0 0 */ - t[8] = 0 + (uint64_t)a[4] + (uint64_t)a[5] - (uint64_t)a[7] + (uint64_t)a[8]; - /* 0 0 0 0 0 1 1 0 -1 1 0 0 */ - t[9] = 0 + (uint64_t)a[5] + (uint64_t)a[6] - (uint64_t)a[8] + (uint64_t)a[9]; - /* 0 0 0 0 0 0 1 1 0 -1 1 0 */ - t[10] = 0 + (uint64_t)a[6] + (uint64_t)a[7] - (uint64_t)a[9] + (uint64_t)a[10]; - /* 0 0 0 0 0 0 0 1 1 0 -1 1 */ - t[11] = 0 + (uint64_t)a[7] + (uint64_t)a[8] - (uint64_t)a[10] + (uint64_t)a[11]; - - t[1] += t[0] >> 32; t[0] &= 0xffffffff; - t[2] += t[1] >> 32; t[1] &= 0xffffffff; - t[3] += t[2] >> 32; t[2] &= 0xffffffff; - t[4] += t[3] >> 32; t[3] &= 0xffffffff; - t[5] += t[4] >> 32; t[4] &= 0xffffffff; - t[6] += t[5] >> 32; t[5] &= 0xffffffff; - t[7] += t[6] >> 32; t[6] &= 0xffffffff; - t[8] += t[7] >> 32; t[7] &= 0xffffffff; - t[9] += t[8] >> 32; t[8] &= 0xffffffff; - t[10] += t[9] >> 32; t[9] &= 0xffffffff; - t[11] += t[10] >> 32; t[10] &= 0xffffffff; - o = t[11] >> 32; t[11] &= 0xffffffff; - t[0] += o; - t[1] -= o; - t[3] += o; - t[4] += o; - t[1] += t[0] >> 32; t[0] &= 0xffffffff; - t[2] += t[1] >> 32; t[1] &= 0xffffffff; - t[3] += t[2] >> 32; t[2] &= 0xffffffff; - t[4] += t[3] >> 32; t[3] &= 0xffffffff; - t[5] += t[4] >> 32; t[4] &= 0xffffffff; - t[6] += t[5] >> 32; t[5] &= 0xffffffff; - t[7] += t[6] >> 32; t[6] &= 0xffffffff; - t[8] += t[7] >> 32; t[7] &= 0xffffffff; - t[9] += t[8] >> 32; t[8] &= 0xffffffff; - t[10] += t[9] >> 32; t[9] &= 0xffffffff; - t[11] += t[10] >> 32; t[10] &= 0xffffffff; - - r[0] = t[0]; - r[1] = t[1]; - r[2] = t[2]; - r[3] = t[3]; - r[4] = t[4]; - r[5] = t[5]; - r[6] = t[6]; - r[7] = t[7]; - r[8] = t[8]; - r[9] = t[9]; - r[10] = t[10]; - r[11] = t[11]; - } - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - if (t != NULL) - XFREE(t, NULL, DYNAMIC_TYPE_ECC); -#endif - - return err; -} - -/* Convert an mp_int to an array of sp_digit. - * - * r A single precision integer. - * size Maximum number of bytes to convert - * a A multi-precision integer. - */ -static void sp_384_from_mp(sp_digit* r, int size, const mp_int* a) -{ -#if DIGIT_BIT == 32 - int j; - - XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); - - for (j = a->used; j < size; j++) { - r[j] = 0; - } -#elif DIGIT_BIT > 32 - int i, j = 0; - word32 s = 0; - - r[0] = 0; - for (i = 0; i < a->used && j < size; i++) { - r[j] |= ((sp_digit)a->dp[i] << s); - r[j] &= 0xffffffff; - s = 32U - s; - if (j + 1 >= size) { - break; - } - /* lint allow cast of mismatch word32 and mp_digit */ - r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ - while ((s + 32U) <= (word32)DIGIT_BIT) { - s += 32U; - r[j] &= 0xffffffff; - if (j + 1 >= size) { - break; - } - if (s < (word32)DIGIT_BIT) { - /* lint allow cast of mismatch word32 and mp_digit */ - r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ - } - else { - r[++j] = 0L; - } - } - s = (word32)DIGIT_BIT - s; - } - - for (j++; j < size; j++) { - r[j] = 0; - } -#else - int i, j = 0, s = 0; - - r[0] = 0; - for (i = 0; i < a->used && j < size; i++) { - r[j] |= ((sp_digit)a->dp[i]) << s; - if (s + DIGIT_BIT >= 32) { - r[j] &= 0xffffffff; - if (j + 1 >= size) { - break; - } - s = 32 - s; - if (s == DIGIT_BIT) { - r[++j] = 0; - s = 0; - } - else { - r[++j] = a->dp[i] >> s; - s = DIGIT_BIT - s; - } - } - else { - s += DIGIT_BIT; - } - } - - for (j++; j < size; j++) { - r[j] = 0; - } -#endif -} - -/* Convert a point of type ecc_point to type sp_point_384. - * - * p Point of type sp_point_384 (result). - * pm Point of type ecc_point. - */ -static void sp_384_point_from_ecc_point_12(sp_point_384* p, const ecc_point* pm) -{ - XMEMSET(p->x, 0, sizeof(p->x)); - XMEMSET(p->y, 0, sizeof(p->y)); - XMEMSET(p->z, 0, sizeof(p->z)); - sp_384_from_mp(p->x, 12, pm->x); - sp_384_from_mp(p->y, 12, pm->y); - sp_384_from_mp(p->z, 12, pm->z); - p->infinity = 0; -} - -/* Convert an array of sp_digit to an mp_int. - * - * a A single precision integer. - * r A multi-precision integer. - */ -static int sp_384_to_mp(const sp_digit* a, mp_int* r) -{ - int err; - - err = mp_grow(r, (384 + DIGIT_BIT - 1) / DIGIT_BIT); - if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ -#if DIGIT_BIT == 32 - XMEMCPY(r->dp, a, sizeof(sp_digit) * 12); - r->used = 12; - mp_clamp(r); -#elif DIGIT_BIT < 32 - int i, j = 0, s = 0; - - r->dp[0] = 0; - for (i = 0; i < 12; i++) { - r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; - s = DIGIT_BIT - s; - r->dp[++j] = (mp_digit)(a[i] >> s); - while (s + DIGIT_BIT <= 32) { - s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; - if (s == SP_WORD_SIZE) { - r->dp[j] = 0; - } - else { - r->dp[j] = (mp_digit)(a[i] >> s); - } - } - s = 32 - s; - } - r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; - mp_clamp(r); -#else - int i, j = 0, s = 0; - - r->dp[0] = 0; - for (i = 0; i < 12; i++) { - r->dp[j] |= ((mp_digit)a[i]) << s; - if (s + 32 >= DIGIT_BIT) { - #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; - #endif - s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; - s = 32 - s; - } - else { - s += 32; - } - } - r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; - mp_clamp(r); -#endif - } - - return err; -} - -/* Convert a point of type sp_point_384 to type ecc_point. - * - * p Point of type sp_point_384. - * pm Point of type ecc_point (result). - * returns MEMORY_E when allocation of memory in ecc_point fails otherwise - * MP_OKAY. - */ -static int sp_384_point_to_ecc_point_12(const sp_point_384* p, ecc_point* pm) -{ - int err; - - err = sp_384_to_mp(p->x, pm->x); - if (err == MP_OKAY) { - err = sp_384_to_mp(p->y, pm->y); - } - if (err == MP_OKAY) { - err = sp_384_to_mp(p->z, pm->z); - } - - return err; -} - #ifdef WOLFSSL_SP_SMALL /* Multiply a and b into r. (r = a * b) * @@ -38624,66 +38169,60 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "sub sp, sp, #48\n\t" "mov r10, #0\n\t" "# A[0] * B[0]\n\t" - "ldr r8, [%[a], #0]\n\t" - "ldr r9, [%[b], #0]\n\t" - "umull r3, r4, r8, r9\n\t" + "ldr r11, [%[a], #0]\n\t" + "ldr r12, [%[b], #0]\n\t" + "umull r3, r4, r11, r12\n\t" "mov r5, #0\n\t" "str r3, [sp]\n\t" "# A[0] * B[1]\n\t" - "ldr r8, [%[a], #0]\n\t" "ldr r9, [%[b], #4]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r10, r10\n\t" "# A[1] * B[0]\n\t" "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #0]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "str r4, [sp, #4]\n\t" + "# A[2] * B[0]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "# A[1] * B[1]\n\t" + "ldr r11, [%[a], #4]\n\t" + "ldr r12, [%[b], #4]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" "# A[0] * B[2]\n\t" "ldr r8, [%[a], #0]\n\t" "ldr r9, [%[b], #8]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r10, r10\n\t" - "# A[1] * B[1]\n\t" - "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #4]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[2] * B[0]\n\t" - "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #0]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "str r5, [sp, #8]\n\t" "# A[0] * B[3]\n\t" - "ldr r8, [%[a], #0]\n\t" "ldr r9, [%[b], #12]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r10, r10\n\t" "# A[1] * B[2]\n\t" - "ldr r8, [%[a], #4]\n\t" "ldr r9, [%[b], #8]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "# A[2] * B[1]\n\t" "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #4]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" @@ -38695,13 +38234,25 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "str r3, [sp, #12]\n\t" - "# A[0] * B[4]\n\t" - "ldr r8, [%[a], #0]\n\t" - "ldr r9, [%[b], #16]\n\t" + "# A[4] * B[0]\n\t" + "ldr r8, [%[a], #16]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r10, r10\n\t" + "# A[3] * B[1]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[2] * B[2]\n\t" + "ldr r11, [%[a], #8]\n\t" + "ldr r12, [%[b], #8]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" "# A[1] * B[3]\n\t" "ldr r8, [%[a], #4]\n\t" "ldr r9, [%[b], #12]\n\t" @@ -38709,30 +38260,15 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" - "# A[2] * B[2]\n\t" - "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #8]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[3] * B[1]\n\t" - "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #4]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[4] * B[0]\n\t" - "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #0]\n\t" + "# A[0] * B[4]\n\t" + "ldr r8, [%[a], #0]\n\t" + "ldr r9, [%[b], #16]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "str r4, [sp, #16]\n\t" "# A[0] * B[5]\n\t" - "ldr r8, [%[a], #0]\n\t" "ldr r9, [%[b], #20]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" @@ -38746,16 +38282,14 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "# A[2] * B[3]\n\t" - "ldr r8, [%[a], #8]\n\t" "ldr r9, [%[b], #12]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "# A[3] * B[2]\n\t" "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #8]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" @@ -38774,20 +38308,32 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "str r5, [sp, #20]\n\t" - "# A[0] * B[6]\n\t" - "ldr r8, [%[a], #0]\n\t" - "ldr r9, [%[b], #24]\n\t" + "# A[6] * B[0]\n\t" + "ldr r8, [%[a], #24]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r10, r10\n\t" - "# A[1] * B[5]\n\t" - "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #20]\n\t" + "# A[5] * B[1]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #4]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" + "# A[4] * B[2]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[3] * B[3]\n\t" + "ldr r11, [%[a], #12]\n\t" + "ldr r12, [%[b], #12]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" "# A[2] * B[4]\n\t" "ldr r8, [%[a], #8]\n\t" "ldr r9, [%[b], #16]\n\t" @@ -38795,37 +38341,22 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" - "# A[3] * B[3]\n\t" - "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #12]\n\t" + "# A[1] * B[5]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #20]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" - "# A[4] * B[2]\n\t" - "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #8]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[5] * B[1]\n\t" - "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #4]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[6] * B[0]\n\t" - "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #0]\n\t" + "# A[0] * B[6]\n\t" + "ldr r8, [%[a], #0]\n\t" + "ldr r9, [%[b], #24]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "str r3, [sp, #24]\n\t" "# A[0] * B[7]\n\t" - "ldr r8, [%[a], #0]\n\t" "ldr r9, [%[b], #28]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" @@ -38846,16 +38377,14 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "# A[3] * B[4]\n\t" - "ldr r8, [%[a], #12]\n\t" "ldr r9, [%[b], #16]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "# A[4] * B[3]\n\t" "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #12]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" @@ -38881,44 +38410,15 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "str r4, [sp, #28]\n\t" - "# A[0] * B[8]\n\t" - "ldr r8, [%[a], #0]\n\t" - "ldr r9, [%[b], #32]\n\t" + "# A[8] * B[0]\n\t" + "ldr r8, [%[a], #32]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r10, r10\n\t" - "# A[1] * B[7]\n\t" - "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #28]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[2] * B[6]\n\t" - "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #24]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[3] * B[5]\n\t" - "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #20]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[4] * B[4]\n\t" - "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #16]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[5] * B[3]\n\t" - "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #12]\n\t" + "# A[7] * B[1]\n\t" + "ldr r8, [%[a], #28]\n\t" + "ldr r9, [%[b], #4]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" @@ -38930,23 +38430,49 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" - "# A[7] * B[1]\n\t" - "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #4]\n\t" + "# A[5] * B[3]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[4] * B[4]\n\t" + "ldr r11, [%[a], #16]\n\t" + "ldr r12, [%[b], #16]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[3] * B[5]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #20]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" - "# A[8] * B[0]\n\t" - "ldr r8, [%[a], #32]\n\t" - "ldr r9, [%[b], #0]\n\t" + "# A[2] * B[6]\n\t" + "ldr r8, [%[a], #8]\n\t" + "ldr r9, [%[b], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[1] * B[7]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #28]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[0] * B[8]\n\t" + "ldr r8, [%[a], #0]\n\t" + "ldr r9, [%[b], #32]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "str r5, [sp, #32]\n\t" "# A[0] * B[9]\n\t" - "ldr r8, [%[a], #0]\n\t" "ldr r9, [%[b], #36]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" @@ -38974,16 +38500,14 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "# A[4] * B[5]\n\t" - "ldr r8, [%[a], #16]\n\t" "ldr r9, [%[b], #20]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "# A[5] * B[4]\n\t" "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #16]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" @@ -39016,58 +38540,15 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "str r3, [sp, #36]\n\t" - "# A[0] * B[10]\n\t" - "ldr r8, [%[a], #0]\n\t" - "ldr r9, [%[b], #40]\n\t" + "# A[10] * B[0]\n\t" + "ldr r8, [%[a], #40]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r10, r10\n\t" - "# A[1] * B[9]\n\t" - "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #36]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[2] * B[8]\n\t" - "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #32]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[3] * B[7]\n\t" - "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #28]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[4] * B[6]\n\t" - "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #24]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[5] * B[5]\n\t" - "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #20]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[6] * B[4]\n\t" - "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #16]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[7] * B[3]\n\t" - "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #12]\n\t" + "# A[9] * B[1]\n\t" + "ldr r8, [%[a], #36]\n\t" + "ldr r9, [%[b], #4]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" @@ -39079,23 +38560,63 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" - "# A[9] * B[1]\n\t" - "ldr r8, [%[a], #36]\n\t" - "ldr r9, [%[b], #4]\n\t" + "# A[7] * B[3]\n\t" + "ldr r8, [%[a], #28]\n\t" + "ldr r9, [%[b], #12]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" - "# A[10] * B[0]\n\t" - "ldr r8, [%[a], #40]\n\t" - "ldr r9, [%[b], #0]\n\t" + "# A[6] * B[4]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[5] * B[5]\n\t" + "ldr r11, [%[a], #20]\n\t" + "ldr r12, [%[b], #20]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[4] * B[6]\n\t" + "ldr r8, [%[a], #16]\n\t" + "ldr r9, [%[b], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[3] * B[7]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #28]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[2] * B[8]\n\t" + "ldr r8, [%[a], #8]\n\t" + "ldr r9, [%[b], #32]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[1] * B[9]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #36]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[0] * B[10]\n\t" + "ldr r8, [%[a], #0]\n\t" + "ldr r9, [%[b], #40]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "str r4, [sp, #40]\n\t" "# A[0] * B[11]\n\t" - "ldr r8, [%[a], #0]\n\t" "ldr r9, [%[b], #44]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" @@ -39130,16 +38651,14 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "# A[5] * B[6]\n\t" - "ldr r8, [%[a], #20]\n\t" "ldr r9, [%[b], #24]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "# A[6] * B[5]\n\t" "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #20]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" @@ -39179,58 +38698,15 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "str r5, [sp, #44]\n\t" - "# A[1] * B[11]\n\t" - "ldr r8, [%[a], #4]\n\t" - "ldr r9, [%[b], #44]\n\t" + "# A[11] * B[1]\n\t" + "ldr r9, [%[b], #4]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r10, r10\n\t" - "# A[2] * B[10]\n\t" - "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #40]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[3] * B[9]\n\t" - "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #36]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[4] * B[8]\n\t" - "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #32]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[5] * B[7]\n\t" - "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #28]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[6] * B[6]\n\t" - "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #24]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[7] * B[5]\n\t" - "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #20]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[8] * B[4]\n\t" - "ldr r8, [%[a], #32]\n\t" - "ldr r9, [%[b], #16]\n\t" + "# A[10] * B[2]\n\t" + "ldr r8, [%[a], #40]\n\t" + "ldr r9, [%[b], #8]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" @@ -39242,16 +38718,57 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" - "# A[10] * B[2]\n\t" - "ldr r8, [%[a], #40]\n\t" - "ldr r9, [%[b], #8]\n\t" + "# A[8] * B[4]\n\t" + "ldr r8, [%[a], #32]\n\t" + "ldr r9, [%[b], #16]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" - "# A[11] * B[1]\n\t" - "ldr r8, [%[a], #44]\n\t" - "ldr r9, [%[b], #4]\n\t" + "# A[7] * B[5]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[6] * B[6]\n\t" + "ldr r11, [%[a], #24]\n\t" + "ldr r12, [%[b], #24]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[5] * B[7]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #28]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[4] * B[8]\n\t" + "ldr r8, [%[a], #16]\n\t" + "ldr r9, [%[b], #32]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[3] * B[9]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #36]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[2] * B[10]\n\t" + "ldr r8, [%[a], #8]\n\t" + "ldr r9, [%[b], #40]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[1] * B[11]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #44]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" @@ -39259,7 +38776,6 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "str r3, [%[r], #48]\n\t" "# A[2] * B[11]\n\t" "ldr r8, [%[a], #8]\n\t" - "ldr r9, [%[b], #44]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" @@ -39286,16 +38802,14 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "# A[6] * B[7]\n\t" - "ldr r8, [%[a], #24]\n\t" "ldr r9, [%[b], #28]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "# A[7] * B[6]\n\t" "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #24]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" @@ -39328,44 +38842,15 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "str r4, [%[r], #52]\n\t" - "# A[3] * B[11]\n\t" - "ldr r8, [%[a], #12]\n\t" - "ldr r9, [%[b], #44]\n\t" + "# A[11] * B[3]\n\t" + "ldr r9, [%[b], #12]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r10, r10\n\t" - "# A[4] * B[10]\n\t" - "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #40]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[5] * B[9]\n\t" - "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #36]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[6] * B[8]\n\t" - "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #32]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[7] * B[7]\n\t" - "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #28]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[8] * B[6]\n\t" - "ldr r8, [%[a], #32]\n\t" - "ldr r9, [%[b], #24]\n\t" + "# A[10] * B[4]\n\t" + "ldr r8, [%[a], #40]\n\t" + "ldr r9, [%[b], #16]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" @@ -39377,16 +38862,43 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" - "# A[10] * B[4]\n\t" - "ldr r8, [%[a], #40]\n\t" - "ldr r9, [%[b], #16]\n\t" + "# A[8] * B[6]\n\t" + "ldr r8, [%[a], #32]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[7] * B[7]\n\t" + "ldr r11, [%[a], #28]\n\t" + "ldr r12, [%[b], #28]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[6] * B[8]\n\t" + "ldr r8, [%[a], #24]\n\t" + "ldr r9, [%[b], #32]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" - "# A[11] * B[3]\n\t" - "ldr r8, [%[a], #44]\n\t" - "ldr r9, [%[b], #12]\n\t" + "# A[5] * B[9]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #36]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[4] * B[10]\n\t" + "ldr r8, [%[a], #16]\n\t" + "ldr r9, [%[b], #40]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[3] * B[11]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #44]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" @@ -39394,7 +38906,6 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "str r5, [%[r], #56]\n\t" "# A[4] * B[11]\n\t" "ldr r8, [%[a], #16]\n\t" - "ldr r9, [%[b], #44]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" @@ -39414,16 +38925,14 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "# A[7] * B[8]\n\t" - "ldr r8, [%[a], #28]\n\t" "ldr r9, [%[b], #32]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "# A[8] * B[7]\n\t" "ldr r8, [%[a], #32]\n\t" - "ldr r9, [%[b], #28]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" @@ -39449,20 +38958,32 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "str r3, [%[r], #60]\n\t" - "# A[5] * B[11]\n\t" - "ldr r8, [%[a], #20]\n\t" - "ldr r9, [%[b], #44]\n\t" + "# A[11] * B[5]\n\t" + "ldr r9, [%[b], #20]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r10, r10\n\t" - "# A[6] * B[10]\n\t" - "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #40]\n\t" + "# A[10] * B[6]\n\t" + "ldr r8, [%[a], #40]\n\t" + "ldr r9, [%[b], #24]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" + "# A[9] * B[7]\n\t" + "ldr r8, [%[a], #36]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[8] * B[8]\n\t" + "ldr r11, [%[a], #32]\n\t" + "ldr r12, [%[b], #32]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" "# A[7] * B[9]\n\t" "ldr r8, [%[a], #28]\n\t" "ldr r9, [%[b], #36]\n\t" @@ -39470,30 +38991,16 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" - "# A[8] * B[8]\n\t" - "ldr r8, [%[a], #32]\n\t" - "ldr r9, [%[b], #32]\n\t" + "# A[6] * B[10]\n\t" + "ldr r8, [%[a], #24]\n\t" + "ldr r9, [%[b], #40]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" - "# A[9] * B[7]\n\t" - "ldr r8, [%[a], #36]\n\t" - "ldr r9, [%[b], #28]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[10] * B[6]\n\t" - "ldr r8, [%[a], #40]\n\t" - "ldr r9, [%[b], #24]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" - "# A[11] * B[5]\n\t" - "ldr r8, [%[a], #44]\n\t" - "ldr r9, [%[b], #20]\n\t" + "# A[5] * B[11]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #44]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" @@ -39501,7 +39008,6 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "str r4, [%[r], #64]\n\t" "# A[6] * B[11]\n\t" "ldr r8, [%[a], #24]\n\t" - "ldr r9, [%[b], #44]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" @@ -39514,16 +39020,14 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "# A[8] * B[9]\n\t" - "ldr r8, [%[a], #32]\n\t" "ldr r9, [%[b], #36]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "# A[9] * B[8]\n\t" "ldr r8, [%[a], #36]\n\t" - "ldr r9, [%[b], #32]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" @@ -39542,13 +39046,25 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "str r5, [%[r], #68]\n\t" - "# A[7] * B[11]\n\t" - "ldr r8, [%[a], #28]\n\t" - "ldr r9, [%[b], #44]\n\t" + "# A[11] * B[7]\n\t" + "ldr r9, [%[b], #28]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r10, r10\n\t" + "# A[10] * B[8]\n\t" + "ldr r8, [%[a], #40]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[9] * B[9]\n\t" + "ldr r11, [%[a], #36]\n\t" + "ldr r12, [%[b], #36]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" "# A[8] * B[10]\n\t" "ldr r8, [%[a], #32]\n\t" "ldr r9, [%[b], #40]\n\t" @@ -39556,23 +39072,9 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" - "# A[9] * B[9]\n\t" - "ldr r8, [%[a], #36]\n\t" - "ldr r9, [%[b], #36]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[10] * B[8]\n\t" - "ldr r8, [%[a], #40]\n\t" - "ldr r9, [%[b], #32]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" - "# A[11] * B[7]\n\t" - "ldr r8, [%[a], #44]\n\t" - "ldr r9, [%[b], #28]\n\t" + "# A[7] * B[11]\n\t" + "ldr r8, [%[a], #28]\n\t" + "ldr r9, [%[b], #44]\n\t" "umull r6, r7, r8, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" @@ -39580,22 +39082,19 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "str r3, [%[r], #72]\n\t" "# A[8] * B[11]\n\t" "ldr r8, [%[a], #32]\n\t" - "ldr r9, [%[b], #44]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r10, r10\n\t" "# A[9] * B[10]\n\t" - "ldr r8, [%[a], #36]\n\t" "ldr r9, [%[b], #40]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "# A[10] * B[9]\n\t" "ldr r8, [%[a], #40]\n\t" - "ldr r9, [%[b], #36]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" @@ -39607,83 +39106,1397 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "adcs r5, r5, r7\n\t" "adc r3, r3, r10\n\t" "str r4, [%[r], #76]\n\t" + "# A[11] * B[9]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "# A[10] * B[10]\n\t" + "ldr r11, [%[a], #40]\n\t" + "ldr r12, [%[b], #40]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" "# A[9] * B[11]\n\t" "ldr r8, [%[a], #36]\n\t" "ldr r9, [%[b], #44]\n\t" "umull r6, r7, r8, r9\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r10, r10\n\t" - "# A[10] * B[10]\n\t" - "ldr r8, [%[a], #40]\n\t" - "ldr r9, [%[b], #40]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" - "# A[11] * B[9]\n\t" - "ldr r8, [%[a], #44]\n\t" - "ldr r9, [%[b], #36]\n\t" - "umull r6, r7, r8, r9\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r7\n\t" "adc r4, r4, r10\n\t" "str r5, [%[r], #80]\n\t" "# A[10] * B[11]\n\t" - "ldr r8, [%[a], #40]\n\t" - "ldr r9, [%[b], #44]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r11, r9\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r10, r10\n\t" "# A[11] * B[10]\n\t" "ldr r8, [%[a], #44]\n\t" - "ldr r9, [%[b], #40]\n\t" - "umull r6, r7, r8, r9\n\t" + "umull r6, r7, r8, r12\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" "adc r5, r5, r10\n\t" "str r3, [%[r], #84]\n\t" "# A[11] * B[11]\n\t" - "ldr r8, [%[a], #44]\n\t" - "ldr r9, [%[b], #44]\n\t" "umull r6, r7, r8, r9\n\t" "adds r4, r4, r6\n\t" "adc r5, r5, r7\n\t" "str r4, [%[r], #88]\n\t" "str r5, [%[r], #92]\n\t" - "ldr r3, [sp, #0]\n\t" - "ldr r4, [sp, #4]\n\t" - "ldr r5, [sp, #8]\n\t" - "ldr r6, [sp, #12]\n\t" - "str r3, [%[r], #0]\n\t" - "str r4, [%[r], #4]\n\t" - "str r5, [%[r], #8]\n\t" - "str r6, [%[r], #12]\n\t" - "ldr r3, [sp, #16]\n\t" - "ldr r4, [sp, #20]\n\t" - "ldr r5, [sp, #24]\n\t" - "ldr r6, [sp, #28]\n\t" - "str r3, [%[r], #16]\n\t" - "str r4, [%[r], #20]\n\t" - "str r5, [%[r], #24]\n\t" - "str r6, [%[r], #28]\n\t" - "ldr r3, [sp, #32]\n\t" - "ldr r4, [sp, #36]\n\t" - "ldr r5, [sp, #40]\n\t" - "ldr r6, [sp, #44]\n\t" - "str r3, [%[r], #32]\n\t" - "str r4, [%[r], #36]\n\t" - "str r5, [%[r], #40]\n\t" - "str r6, [%[r], #44]\n\t" - "add sp, sp, #48\n\t" + "ldm sp!, {r3, r4, r5, r6}\n\t" + "stm %[r]!, {r3, r4, r5, r6}\n\t" + "ldm sp!, {r3, r4, r5, r6}\n\t" + "stm %[r]!, {r3, r4, r5, r6}\n\t" + "ldm sp!, {r3, r4, r5, r6}\n\t" + "stm %[r]!, {r3, r4, r5, r6}\n\t" + "sub %[r], %[r], #48\n\t" : : [r] "r" (r), [a] "r" (a), [b] "r" (b) - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" + : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); } #endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +static void sp_384_sqr_12(sp_digit* r, const sp_digit* a) +{ + __asm__ __volatile__ ( + "sub sp, sp, #96\n\t" + "mov r12, #0\n\t" + "mov r6, #0\n\t" + "mov r7, #0\n\t" + "mov r8, #0\n\t" + "mov r5, #0\n\t" + "\n1:\n\t" + "subs r3, r5, #44\n\t" + "it cc\n\t" + "movcc r3, r12\n\t" + "sub r4, r5, r3\n\t" + "\n2:\n\t" + "cmp r4, r3\n\t" + "beq 4f\n\t" + "ldr r14, [%[a], r3]\n\t" + "ldr r9, [%[a], r4]\n\t" + "umull r9, r10, r14, r9\n\t" + "adds r6, r6, r9\n\t" + "adcs r7, r7, r10\n\t" + "adc r8, r8, r12\n\t" + "adds r6, r6, r9\n\t" + "adcs r7, r7, r10\n\t" + "adc r8, r8, r12\n\t" + "bal 5f\n\t" + "\n4:\n\t" + "ldr r14, [%[a], r3]\n\t" + "umull r9, r10, r14, r14\n\t" + "adds r6, r6, r9\n\t" + "adcs r7, r7, r10\n\t" + "adc r8, r8, r12\n\t" + "\n5:\n\t" + "add r3, r3, #4\n\t" + "sub r4, r4, #4\n\t" + "cmp r3, #48\n\t" + "beq 3f\n\t" + "cmp r3, r4\n\t" + "bgt 3f\n\t" + "cmp r3, r5\n\t" + "ble 2b\n\t" + "\n3:\n\t" + "str r6, [sp, r5]\n\t" + "mov r6, r7\n\t" + "mov r7, r8\n\t" + "mov r8, #0\n\t" + "add r5, r5, #4\n\t" + "cmp r5, #88\n\t" + "ble 1b\n\t" + "str r6, [sp, r5]\n\t" + "\n4:\n\t" + "ldr r6, [sp, #0]\n\t" + "ldr r7, [sp, #4]\n\t" + "ldr r8, [sp, #8]\n\t" + "ldr r3, [sp, #12]\n\t" + "str r6, [%[r], #0]\n\t" + "str r7, [%[r], #4]\n\t" + "str r8, [%[r], #8]\n\t" + "str r3, [%[r], #12]\n\t" + "add sp, sp, #16\n\t" + "add %[r], %[r], #16\n\t" + "subs r5, r5, #16\n\t" + "bgt 4b\n\t" + : [r] "+r" (r) + : [a] "r" (a) + : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r9", "r12" + ); +} + +#else +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +static void sp_384_sqr_12(sp_digit* r, const sp_digit* a) +{ + __asm__ __volatile__ ( + "sub sp, sp, #48\n\t" + "mov r12, #0\n\t" + "# A[0] * A[0]\n\t" + "ldr r10, [%[a], #0]\n\t" + "umull r8, r3, r10, r10\n\t" + "mov r4, #0\n\t" + "str r8, [sp]\n\t" + "# A[0] * A[1]\n\t" + "ldr r10, [%[a], #4]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r12, r12\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "str r3, [sp, #4]\n\t" + "# A[0] * A[2]\n\t" + "ldr r10, [%[a], #8]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r4, r4, r8\n\t" + "adcs r2, r2, r9\n\t" + "adc r3, r12, r12\n\t" + "adds r4, r4, r8\n\t" + "adcs r2, r2, r9\n\t" + "adc r3, r3, r12\n\t" + "# A[1] * A[1]\n\t" + "ldr r10, [%[a], #4]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r4, r4, r8\n\t" + "adcs r2, r2, r9\n\t" + "adc r3, r3, r12\n\t" + "str r4, [sp, #8]\n\t" + "# A[0] * A[3]\n\t" + "ldr r10, [%[a], #12]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r12, r12\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r4, r12\n\t" + "# A[1] * A[2]\n\t" + "ldr r10, [%[a], #8]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r4, r12\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r4, r12\n\t" + "str r2, [sp, #12]\n\t" + "# A[0] * A[4]\n\t" + "ldr r10, [%[a], #16]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r12, r12\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "# A[1] * A[3]\n\t" + "ldr r10, [%[a], #12]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "# A[2] * A[2]\n\t" + "ldr r10, [%[a], #8]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "str r3, [sp, #16]\n\t" + "# A[0] * A[5]\n\t" + "ldr r10, [%[a], #20]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r3, #0\n\t" + "mov r7, #0\n\t" + "# A[1] * A[4]\n\t" + "ldr r10, [%[a], #16]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[2] * A[3]\n\t" + "ldr r10, [%[a], #12]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r4, r4, r5\n\t" + "adcs r2, r2, r6\n\t" + "adc r3, r3, r7\n\t" + "str r4, [sp, #20]\n\t" + "# A[0] * A[6]\n\t" + "ldr r10, [%[a], #24]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r4, #0\n\t" + "mov r7, #0\n\t" + "# A[1] * A[5]\n\t" + "ldr r10, [%[a], #20]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[2] * A[4]\n\t" + "ldr r10, [%[a], #16]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[3] * A[3]\n\t" + "ldr r10, [%[a], #12]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r2, r2, r5\n\t" + "adcs r3, r3, r6\n\t" + "adc r4, r4, r7\n\t" + "str r2, [sp, #24]\n\t" + "# A[0] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r2, #0\n\t" + "mov r7, #0\n\t" + "# A[1] * A[6]\n\t" + "ldr r10, [%[a], #24]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[2] * A[5]\n\t" + "ldr r10, [%[a], #20]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[3] * A[4]\n\t" + "ldr r10, [%[a], #16]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r3, r3, r5\n\t" + "adcs r4, r4, r6\n\t" + "adc r2, r2, r7\n\t" + "str r3, [sp, #28]\n\t" + "# A[0] * A[8]\n\t" + "ldr r10, [%[a], #32]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r3, #0\n\t" + "mov r7, #0\n\t" + "# A[1] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[2] * A[6]\n\t" + "ldr r10, [%[a], #24]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[3] * A[5]\n\t" + "ldr r10, [%[a], #20]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[4] * A[4]\n\t" + "ldr r10, [%[a], #16]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r4, r4, r5\n\t" + "adcs r2, r2, r6\n\t" + "adc r3, r3, r7\n\t" + "str r4, [sp, #32]\n\t" + "# A[0] * A[9]\n\t" + "ldr r10, [%[a], #36]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r4, #0\n\t" + "mov r7, #0\n\t" + "# A[1] * A[8]\n\t" + "ldr r10, [%[a], #32]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[2] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[3] * A[6]\n\t" + "ldr r10, [%[a], #24]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[4] * A[5]\n\t" + "ldr r10, [%[a], #20]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r2, r2, r5\n\t" + "adcs r3, r3, r6\n\t" + "adc r4, r4, r7\n\t" + "str r2, [sp, #36]\n\t" + "# A[0] * A[10]\n\t" + "ldr r10, [%[a], #40]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r2, #0\n\t" + "mov r7, #0\n\t" + "# A[1] * A[9]\n\t" + "ldr r10, [%[a], #36]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[2] * A[8]\n\t" + "ldr r10, [%[a], #32]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[3] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[4] * A[6]\n\t" + "ldr r10, [%[a], #24]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[5] * A[5]\n\t" + "ldr r10, [%[a], #20]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r3, r3, r5\n\t" + "adcs r4, r4, r6\n\t" + "adc r2, r2, r7\n\t" + "str r3, [sp, #40]\n\t" + "# A[0] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r3, #0\n\t" + "mov r7, #0\n\t" + "# A[1] * A[10]\n\t" + "ldr r10, [%[a], #40]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[2] * A[9]\n\t" + "ldr r10, [%[a], #36]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[3] * A[8]\n\t" + "ldr r10, [%[a], #32]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[4] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[5] * A[6]\n\t" + "ldr r10, [%[a], #24]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r4, r4, r5\n\t" + "adcs r2, r2, r6\n\t" + "adc r3, r3, r7\n\t" + "str r4, [sp, #44]\n\t" + "# A[1] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r4, #0\n\t" + "mov r7, #0\n\t" + "# A[2] * A[10]\n\t" + "ldr r10, [%[a], #40]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[3] * A[9]\n\t" + "ldr r10, [%[a], #36]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[4] * A[8]\n\t" + "ldr r10, [%[a], #32]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[5] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[6] * A[6]\n\t" + "ldr r10, [%[a], #24]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r2, r2, r5\n\t" + "adcs r3, r3, r6\n\t" + "adc r4, r4, r7\n\t" + "str r2, [%[r], #48]\n\t" + "# A[2] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r2, #0\n\t" + "mov r7, #0\n\t" + "# A[3] * A[10]\n\t" + "ldr r10, [%[a], #40]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[4] * A[9]\n\t" + "ldr r10, [%[a], #36]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[5] * A[8]\n\t" + "ldr r10, [%[a], #32]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[6] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r3, r3, r5\n\t" + "adcs r4, r4, r6\n\t" + "adc r2, r2, r7\n\t" + "str r3, [%[r], #52]\n\t" + "# A[3] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r3, #0\n\t" + "mov r7, #0\n\t" + "# A[4] * A[10]\n\t" + "ldr r10, [%[a], #40]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[5] * A[9]\n\t" + "ldr r10, [%[a], #36]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[6] * A[8]\n\t" + "ldr r10, [%[a], #32]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[7] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r4, r4, r5\n\t" + "adcs r2, r2, r6\n\t" + "adc r3, r3, r7\n\t" + "str r4, [%[r], #56]\n\t" + "# A[4] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r4, #0\n\t" + "mov r7, #0\n\t" + "# A[5] * A[10]\n\t" + "ldr r10, [%[a], #40]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[6] * A[9]\n\t" + "ldr r10, [%[a], #36]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[7] * A[8]\n\t" + "ldr r10, [%[a], #32]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r2, r2, r5\n\t" + "adcs r3, r3, r6\n\t" + "adc r4, r4, r7\n\t" + "str r2, [%[r], #60]\n\t" + "# A[5] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r2, #0\n\t" + "mov r7, #0\n\t" + "# A[6] * A[10]\n\t" + "ldr r10, [%[a], #40]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[7] * A[9]\n\t" + "ldr r10, [%[a], #36]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[8] * A[8]\n\t" + "ldr r10, [%[a], #32]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r3, r3, r5\n\t" + "adcs r4, r4, r6\n\t" + "adc r2, r2, r7\n\t" + "str r3, [%[r], #64]\n\t" + "# A[6] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r3, #0\n\t" + "mov r7, #0\n\t" + "# A[7] * A[10]\n\t" + "ldr r10, [%[a], #40]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[8] * A[9]\n\t" + "ldr r10, [%[a], #36]\n\t" + "ldr r8, [%[a], #32]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r4, r4, r5\n\t" + "adcs r2, r2, r6\n\t" + "adc r3, r3, r7\n\t" + "str r4, [%[r], #68]\n\t" + "# A[7] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r12, r12\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r4, r12\n\t" + "# A[8] * A[10]\n\t" + "ldr r10, [%[a], #40]\n\t" + "ldr r8, [%[a], #32]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r4, r12\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r4, r12\n\t" + "# A[9] * A[9]\n\t" + "ldr r10, [%[a], #36]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r4, r12\n\t" + "str r2, [%[r], #72]\n\t" + "# A[8] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "ldr r8, [%[a], #32]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r12, r12\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "# A[9] * A[10]\n\t" + "ldr r10, [%[a], #40]\n\t" + "ldr r8, [%[a], #36]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "str r3, [%[r], #76]\n\t" + "# A[9] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "ldr r8, [%[a], #36]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r4, r4, r8\n\t" + "adcs r2, r2, r9\n\t" + "adc r3, r12, r12\n\t" + "adds r4, r4, r8\n\t" + "adcs r2, r2, r9\n\t" + "adc r3, r3, r12\n\t" + "# A[10] * A[10]\n\t" + "ldr r10, [%[a], #40]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r4, r4, r8\n\t" + "adcs r2, r2, r9\n\t" + "adc r3, r3, r12\n\t" + "str r4, [%[r], #80]\n\t" + "# A[10] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "ldr r8, [%[a], #40]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r12, r12\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r4, r12\n\t" + "str r2, [%[r], #84]\n\t" + "# A[11] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r3, r3, r8\n\t" + "adc r4, r4, r9\n\t" + "str r3, [%[r], #88]\n\t" + "str r4, [%[r], #92]\n\t" + "ldm sp!, {r2, r3, r4, r8}\n\t" + "stm %[r]!, {r2, r3, r4, r8}\n\t" + "ldm sp!, {r2, r3, r4, r8}\n\t" + "stm %[r]!, {r2, r3, r4, r8}\n\t" + "ldm sp!, {r2, r3, r4, r8}\n\t" + "stm %[r]!, {r2, r3, r4, r8}\n\t" + "sub %[r], %[r], #48\n\t" + : + : [r] "r" (r), [a] "r" (a) + : "memory", "r2", "r3", "r4", "r8", "r9", "r10", "r8", "r5", "r6", "r7", "r12" + ); +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_384_add_12(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "add r12, %[a], #48\n\t" + "\n1:\n\t" + "adds %[c], %[c], #-1\n\t" + "ldr r4, [%[a]], #4\n\t" + "ldr r5, [%[a]], #4\n\t" + "ldr r6, [%[a]], #4\n\t" + "ldr r7, [%[a]], #4\n\t" + "ldr r8, [%[b]], #4\n\t" + "ldr r9, [%[b]], #4\n\t" + "ldr r10, [%[b]], #4\n\t" + "ldr r14, [%[b]], #4\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "str r4, [%[r]], #4\n\t" + "str r5, [%[r]], #4\n\t" + "str r6, [%[r]], #4\n\t" + "str r7, [%[r]], #4\n\t" + "mov r4, #0\n\t" + "adc %[c], r4, #0\n\t" + "cmp %[a], r12\n\t" + "bne 1b\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + ); + + return c; +} + +#else +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_384_add_12(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r12, #0\n\t" + "ldr r4, [%[a], #0]\n\t" + "ldr r5, [%[a], #4]\n\t" + "ldr r6, [%[a], #8]\n\t" + "ldr r7, [%[a], #12]\n\t" + "ldr r8, [%[b], #0]\n\t" + "ldr r9, [%[b], #4]\n\t" + "ldr r10, [%[b], #8]\n\t" + "ldr r14, [%[b], #12]\n\t" + "adds r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "str r4, [%[r], #0]\n\t" + "str r5, [%[r], #4]\n\t" + "str r6, [%[r], #8]\n\t" + "str r7, [%[r], #12]\n\t" + "ldr r4, [%[a], #16]\n\t" + "ldr r5, [%[a], #20]\n\t" + "ldr r6, [%[a], #24]\n\t" + "ldr r7, [%[a], #28]\n\t" + "ldr r8, [%[b], #16]\n\t" + "ldr r9, [%[b], #20]\n\t" + "ldr r10, [%[b], #24]\n\t" + "ldr r14, [%[b], #28]\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "str r4, [%[r], #16]\n\t" + "str r5, [%[r], #20]\n\t" + "str r6, [%[r], #24]\n\t" + "str r7, [%[r], #28]\n\t" + "ldr r4, [%[a], #32]\n\t" + "ldr r5, [%[a], #36]\n\t" + "ldr r6, [%[a], #40]\n\t" + "ldr r7, [%[a], #44]\n\t" + "ldr r8, [%[b], #32]\n\t" + "ldr r9, [%[b], #36]\n\t" + "ldr r10, [%[b], #40]\n\t" + "ldr r14, [%[b], #44]\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "str r4, [%[r], #32]\n\t" + "str r5, [%[r], #36]\n\t" + "str r6, [%[r], #40]\n\t" + "str r7, [%[r], #44]\n\t" + "adc %[c], r12, r12\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b) + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + ); + + return c; +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_384_sub_12(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "add r12, %[a], #48\n\t" + "\n1:\n\t" + "rsbs %[c], %[c], #0\n\t" + "ldr r4, [%[a]], #4\n\t" + "ldr r5, [%[a]], #4\n\t" + "ldr r6, [%[a]], #4\n\t" + "ldr r7, [%[a]], #4\n\t" + "ldr r8, [%[b]], #4\n\t" + "ldr r9, [%[b]], #4\n\t" + "ldr r10, [%[b]], #4\n\t" + "ldr r14, [%[b]], #4\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "str r4, [%[r]], #4\n\t" + "str r5, [%[r]], #4\n\t" + "str r6, [%[r]], #4\n\t" + "str r7, [%[r]], #4\n\t" + "sbc %[c], r4, r4\n\t" + "cmp %[a], r12\n\t" + "bne 1b\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + ); + + return c; +} + +#else +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_384_sub_12(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldr r3, [%[a], #0]\n\t" + "ldr r4, [%[a], #4]\n\t" + "ldr r5, [%[a], #8]\n\t" + "ldr r6, [%[a], #12]\n\t" + "ldr r7, [%[b], #0]\n\t" + "ldr r8, [%[b], #4]\n\t" + "ldr r9, [%[b], #8]\n\t" + "ldr r10, [%[b], #12]\n\t" + "subs r3, r3, r7\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "str r3, [%[r], #0]\n\t" + "str r4, [%[r], #4]\n\t" + "str r5, [%[r], #8]\n\t" + "str r6, [%[r], #12]\n\t" + "ldr r3, [%[a], #16]\n\t" + "ldr r4, [%[a], #20]\n\t" + "ldr r5, [%[a], #24]\n\t" + "ldr r6, [%[a], #28]\n\t" + "ldr r7, [%[b], #16]\n\t" + "ldr r8, [%[b], #20]\n\t" + "ldr r9, [%[b], #24]\n\t" + "ldr r10, [%[b], #28]\n\t" + "sbcs r3, r3, r7\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "str r3, [%[r], #16]\n\t" + "str r4, [%[r], #20]\n\t" + "str r5, [%[r], #24]\n\t" + "str r6, [%[r], #28]\n\t" + "ldr r3, [%[a], #32]\n\t" + "ldr r4, [%[a], #36]\n\t" + "ldr r5, [%[a], #40]\n\t" + "ldr r6, [%[a], #44]\n\t" + "ldr r7, [%[b], #32]\n\t" + "ldr r8, [%[b], #36]\n\t" + "ldr r9, [%[b], #40]\n\t" + "ldr r10, [%[b], #44]\n\t" + "sbcs r3, r3, r7\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "str r3, [%[r], #32]\n\t" + "str r4, [%[r], #36]\n\t" + "str r5, [%[r], #40]\n\t" + "str r6, [%[r], #44]\n\t" + "sbc %[c], %[c], #0\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b) + : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" + ); + + return c; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Create a new point. + * + * heap [in] Buffer to allocate dynamic memory from. + * sp [in] Data for point - only if not allocating. + * p [out] New point. + * returns MEMORY_E when dynamic memory allocation fails and 0 otherwise. + */ +static int sp_384_point_new_ex_12(void* heap, sp_point_384* sp, + sp_point_384** p) +{ + int ret = MP_OKAY; + (void)heap; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + (void)sp; + *p = (sp_point_384*)XMALLOC(sizeof(sp_point_384), heap, DYNAMIC_TYPE_ECC); +#else + *p = sp; +#endif + if (*p == NULL) { + ret = MEMORY_E; + } + return ret; +} + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* Allocate memory for point and return error. */ +#define sp_384_point_new_12(heap, sp, p) sp_384_point_new_ex_12((heap), NULL, &(p)) +#else +/* Set pointer to data and return no error. */ +#define sp_384_point_new_12(heap, sp, p) sp_384_point_new_ex_12((heap), &(sp), &(p)) +#endif + + +/* Free the point. + * + * p [in,out] Point to free. + * clear [in] Indicates whether to zeroize point. + * heap [in] Buffer from which dynamic memory was allocate from. + */ +static void sp_384_point_free_12(sp_point_384* p, int clear, void* heap) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* If valid pointer then clear point data if requested and free data. */ + if (p != NULL) { + if (clear != 0) { + XMEMSET(p, 0, sizeof(*p)); + } + XFREE(p, heap, DYNAMIC_TYPE_ECC); + } +#else +/* Clear point data if requested. */ + if ((p != NULL) && (clear != 0)) { + XMEMSET(p, 0, sizeof(*p)); + } +#endif + (void)heap; +} + +/* Multiply a number by Montogmery normalizer mod modulus (prime). + * + * r The resulting Montgomery form number. + * a The number to convert. + * m The modulus (prime). + * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. + */ +static int sp_384_mod_mul_norm_12(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + int64_t* t; +#else + int64_t t[12]; +#endif + int64_t o; + int err = MP_OKAY; + + (void)m; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = (int64_t*)XMALLOC(sizeof(int64_t) * 12, NULL, DYNAMIC_TYPE_ECC); + if (t == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { + /* 1 0 0 0 0 0 0 0 1 1 0 -1 */ + t[0] = 0 + (int64_t)a[0] + (int64_t)a[8] + (int64_t)a[9] - (int64_t)a[11]; + /* -1 1 0 0 0 0 0 0 -1 0 1 1 */ + t[1] = 0 - (int64_t)a[0] + (int64_t)a[1] - (int64_t)a[8] + (int64_t)a[10] + (int64_t)a[11]; + /* 0 -1 1 0 0 0 0 0 0 -1 0 1 */ + t[2] = 0 - (int64_t)a[1] + (int64_t)a[2] - (int64_t)a[9] + (int64_t)a[11]; + /* 1 0 -1 1 0 0 0 0 1 1 -1 -1 */ + t[3] = 0 + (int64_t)a[0] - (int64_t)a[2] + (int64_t)a[3] + (int64_t)a[8] + (int64_t)a[9] - (int64_t)a[10] - (int64_t)a[11]; + /* 1 1 0 -1 1 0 0 0 1 2 1 -2 */ + t[4] = 0 + (int64_t)a[0] + (int64_t)a[1] - (int64_t)a[3] + (int64_t)a[4] + (int64_t)a[8] + 2 * (int64_t)a[9] + (int64_t)a[10] - 2 * (int64_t)a[11]; + /* 0 1 1 0 -1 1 0 0 0 1 2 1 */ + t[5] = 0 + (int64_t)a[1] + (int64_t)a[2] - (int64_t)a[4] + (int64_t)a[5] + (int64_t)a[9] + 2 * (int64_t)a[10] + (int64_t)a[11]; + /* 0 0 1 1 0 -1 1 0 0 0 1 2 */ + t[6] = 0 + (int64_t)a[2] + (int64_t)a[3] - (int64_t)a[5] + (int64_t)a[6] + (int64_t)a[10] + 2 * (int64_t)a[11]; + /* 0 0 0 1 1 0 -1 1 0 0 0 1 */ + t[7] = 0 + (int64_t)a[3] + (int64_t)a[4] - (int64_t)a[6] + (int64_t)a[7] + (int64_t)a[11]; + /* 0 0 0 0 1 1 0 -1 1 0 0 0 */ + t[8] = 0 + (int64_t)a[4] + (int64_t)a[5] - (int64_t)a[7] + (int64_t)a[8]; + /* 0 0 0 0 0 1 1 0 -1 1 0 0 */ + t[9] = 0 + (int64_t)a[5] + (int64_t)a[6] - (int64_t)a[8] + (int64_t)a[9]; + /* 0 0 0 0 0 0 1 1 0 -1 1 0 */ + t[10] = 0 + (int64_t)a[6] + (int64_t)a[7] - (int64_t)a[9] + (int64_t)a[10]; + /* 0 0 0 0 0 0 0 1 1 0 -1 1 */ + t[11] = 0 + (int64_t)a[7] + (int64_t)a[8] - (int64_t)a[10] + (int64_t)a[11]; + + t[1] += t[0] >> 32; t[0] &= 0xffffffff; + t[2] += t[1] >> 32; t[1] &= 0xffffffff; + t[3] += t[2] >> 32; t[2] &= 0xffffffff; + t[4] += t[3] >> 32; t[3] &= 0xffffffff; + t[5] += t[4] >> 32; t[4] &= 0xffffffff; + t[6] += t[5] >> 32; t[5] &= 0xffffffff; + t[7] += t[6] >> 32; t[6] &= 0xffffffff; + t[8] += t[7] >> 32; t[7] &= 0xffffffff; + t[9] += t[8] >> 32; t[8] &= 0xffffffff; + t[10] += t[9] >> 32; t[9] &= 0xffffffff; + t[11] += t[10] >> 32; t[10] &= 0xffffffff; + o = t[11] >> 32; t[11] &= 0xffffffff; + t[0] += o; + t[1] -= o; + t[3] += o; + t[4] += o; + t[1] += t[0] >> 32; t[0] &= 0xffffffff; + t[2] += t[1] >> 32; t[1] &= 0xffffffff; + t[3] += t[2] >> 32; t[2] &= 0xffffffff; + t[4] += t[3] >> 32; t[3] &= 0xffffffff; + t[5] += t[4] >> 32; t[4] &= 0xffffffff; + t[6] += t[5] >> 32; t[5] &= 0xffffffff; + t[7] += t[6] >> 32; t[6] &= 0xffffffff; + t[8] += t[7] >> 32; t[7] &= 0xffffffff; + t[9] += t[8] >> 32; t[8] &= 0xffffffff; + t[10] += t[9] >> 32; t[9] &= 0xffffffff; + t[11] += t[10] >> 32; t[10] &= 0xffffffff; + + r[0] = t[0]; + r[1] = t[1]; + r[2] = t[2]; + r[3] = t[3]; + r[4] = t[4]; + r[5] = t[5]; + r[6] = t[6]; + r[7] = t[7]; + r[8] = t[8]; + r[9] = t[9]; + r[10] = t[10]; + r[11] = t[11]; + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (t != NULL) + XFREE(t, NULL, DYNAMIC_TYPE_ECC); +#endif + + return err; +} + +/* Convert an mp_int to an array of sp_digit. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a A multi-precision integer. + */ +static void sp_384_from_mp(sp_digit* r, int size, const mp_int* a) +{ +#if DIGIT_BIT == 32 + int j; + + XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); + + for (j = a->used; j < size; j++) { + r[j] = 0; + } +#elif DIGIT_BIT > 32 + int i; + int j = 0; + word32 s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i] << s); + r[j] &= 0xffffffff; + s = 32U - s; + if (j + 1 >= size) { + break; + } + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + while ((s + 32U) <= (word32)DIGIT_BIT) { + s += 32U; + r[j] &= 0xffffffff; + if (j + 1 >= size) { + break; + } + if (s < (word32)DIGIT_BIT) { + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + } + else { + r[++j] = 0L; + } + } + s = (word32)DIGIT_BIT - s; + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#else + int i; + int j = 0; + int s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i]) << s; + if (s + DIGIT_BIT >= 32) { + r[j] &= 0xffffffff; + if (j + 1 >= size) { + break; + } + s = 32 - s; + if (s == DIGIT_BIT) { + r[++j] = 0; + s = 0; + } + else { + r[++j] = a->dp[i] >> s; + s = DIGIT_BIT - s; + } + } + else { + s += DIGIT_BIT; + } + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#endif +} + +/* Convert a point of type ecc_point to type sp_point_384. + * + * p Point of type sp_point_384 (result). + * pm Point of type ecc_point. + */ +static void sp_384_point_from_ecc_point_12(sp_point_384* p, + const ecc_point* pm) +{ + XMEMSET(p->x, 0, sizeof(p->x)); + XMEMSET(p->y, 0, sizeof(p->y)); + XMEMSET(p->z, 0, sizeof(p->z)); + sp_384_from_mp(p->x, 12, pm->x); + sp_384_from_mp(p->y, 12, pm->y); + sp_384_from_mp(p->z, 12, pm->z); + p->infinity = 0; +} + +/* Convert an array of sp_digit to an mp_int. + * + * a A single precision integer. + * r A multi-precision integer. + */ +static int sp_384_to_mp(const sp_digit* a, mp_int* r) +{ + int err; + + err = mp_grow(r, (384 + DIGIT_BIT - 1) / DIGIT_BIT); + if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ +#if DIGIT_BIT == 32 + XMEMCPY(r->dp, a, sizeof(sp_digit) * 12); + r->used = 12; + mp_clamp(r); +#elif DIGIT_BIT < 32 + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 12; i++) { + r->dp[j] |= (mp_digit)(a[i] << s); + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + s = DIGIT_BIT - s; + r->dp[++j] = (mp_digit)(a[i] >> s); + while (s + DIGIT_BIT <= 32) { + s += DIGIT_BIT; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; + if (s == SP_WORD_SIZE) { + r->dp[j] = 0; + } + else { + r->dp[j] = (mp_digit)(a[i] >> s); + } + } + s = 32 - s; + } + r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#else + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 12; i++) { + r->dp[j] |= ((mp_digit)a[i]) << s; + if (s + 32 >= DIGIT_BIT) { + #if DIGIT_BIT != 32 && DIGIT_BIT != 64 + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + #endif + s = DIGIT_BIT - s; + r->dp[++j] = a[i] >> s; + s = 32 - s; + } + else { + s += 32; + } + } + r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#endif + } + + return err; +} + +/* Convert a point of type sp_point_384 to type ecc_point. + * + * p Point of type sp_point_384. + * pm Point of type ecc_point (result). + * returns MEMORY_E when allocation of memory in ecc_point fails otherwise + * MP_OKAY. + */ +static int sp_384_point_to_ecc_point_12(const sp_point_384* p, ecc_point* pm) +{ + int err; + + err = sp_384_to_mp(p->x, pm->x); + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, pm->y); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, pm->z); + } + + return err; +} + /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -39804,6 +40617,7 @@ SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, sp_digit ca = 0; __asm__ __volatile__ ( + "ldr r11, [%[m], #0]\n\t" "# i = 0\n\t" "mov r12, #0\n\t" "ldr r10, [%[a], #0]\n\t" @@ -39812,13 +40626,12 @@ SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, "# mu = a[i] * mp\n\t" "mul r8, %[mp], r10\n\t" "# a[i+0] += m[0] * mu\n\t" - "ldr r7, [%[m], #0]\n\t" "ldr r9, [%[a], #0]\n\t" - "umull r6, r7, r8, r7\n\t" + "umull r6, r7, r8, r11\n\t" "adds r10, r10, r6\n\t" "adc r5, r7, #0\n\t" "# a[i+1] += m[1] * mu\n\t" - "ldr r7, [%[m], #4]\n\t" + "ldr r7, [%[m], #4]\n\t" "ldr r9, [%[a], #4]\n\t" "umull r6, r7, r8, r7\n\t" "adds r10, r14, r6\n\t" @@ -39826,7 +40639,7 @@ SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, "adds r10, r10, r5\n\t" "adc r4, r4, #0\n\t" "# a[i+2] += m[2] * mu\n\t" - "ldr r7, [%[m], #8]\n\t" + "ldr r7, [%[m], #8]\n\t" "ldr r14, [%[a], #8]\n\t" "umull r6, r7, r8, r7\n\t" "adds r14, r14, r6\n\t" @@ -39834,7 +40647,7 @@ SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, "adds r14, r14, r4\n\t" "adc r5, r5, #0\n\t" "# a[i+3] += m[3] * mu\n\t" - "ldr r7, [%[m], #12]\n\t" + "ldr r7, [%[m], #12]\n\t" "ldr r9, [%[a], #12]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -39843,7 +40656,7 @@ SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, "str r9, [%[a], #12]\n\t" "adc r4, r4, #0\n\t" "# a[i+4] += m[4] * mu\n\t" - "ldr r7, [%[m], #16]\n\t" + "ldr r7, [%[m], #16]\n\t" "ldr r9, [%[a], #16]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -39852,7 +40665,7 @@ SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, "str r9, [%[a], #16]\n\t" "adc r5, r5, #0\n\t" "# a[i+5] += m[5] * mu\n\t" - "ldr r7, [%[m], #20]\n\t" + "ldr r7, [%[m], #20]\n\t" "ldr r9, [%[a], #20]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -39861,7 +40674,7 @@ SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, "str r9, [%[a], #20]\n\t" "adc r4, r4, #0\n\t" "# a[i+6] += m[6] * mu\n\t" - "ldr r7, [%[m], #24]\n\t" + "ldr r7, [%[m], #24]\n\t" "ldr r9, [%[a], #24]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -39870,7 +40683,7 @@ SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, "str r9, [%[a], #24]\n\t" "adc r5, r5, #0\n\t" "# a[i+7] += m[7] * mu\n\t" - "ldr r7, [%[m], #28]\n\t" + "ldr r7, [%[m], #28]\n\t" "ldr r9, [%[a], #28]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -39879,7 +40692,7 @@ SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, "str r9, [%[a], #28]\n\t" "adc r4, r4, #0\n\t" "# a[i+8] += m[8] * mu\n\t" - "ldr r7, [%[m], #32]\n\t" + "ldr r7, [%[m], #32]\n\t" "ldr r9, [%[a], #32]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -39888,7 +40701,7 @@ SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, "str r9, [%[a], #32]\n\t" "adc r5, r5, #0\n\t" "# a[i+9] += m[9] * mu\n\t" - "ldr r7, [%[m], #36]\n\t" + "ldr r7, [%[m], #36]\n\t" "ldr r9, [%[a], #36]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -39897,7 +40710,7 @@ SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, "str r9, [%[a], #36]\n\t" "adc r4, r4, #0\n\t" "# a[i+10] += m[10] * mu\n\t" - "ldr r7, [%[m], #40]\n\t" + "ldr r7, [%[m], #40]\n\t" "ldr r9, [%[a], #40]\n\t" "umull r6, r7, r8, r7\n\t" "adds r9, r9, r6\n\t" @@ -39928,7 +40741,7 @@ SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, "str r14, [%[a], #4]\n\t" : [ca] "+r" (ca), [a] "+r" (a) : [m] "r" (m), [mp] "r" (mp) - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12", "r11" ); sp_384_cond_sub_12(a - 12, a, m, (sp_digit)0 - ca); @@ -39943,788 +40756,13 @@ SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_384_mont_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_384_mont_mul_12(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_384_mul_12(r, a, b); sp_384_mont_reduce_12(r, m, mp); } -#ifdef WOLFSSL_SP_SMALL -/* Square a and put result in r. (r = a * a) - * - * r A single precision integer. - * a A single precision integer. - */ -static void sp_384_sqr_12(sp_digit* r, const sp_digit* a) -{ - __asm__ __volatile__ ( - "sub sp, sp, #96\n\t" - "mov r12, #0\n\t" - "mov r6, #0\n\t" - "mov r7, #0\n\t" - "mov r8, #0\n\t" - "mov r5, #0\n\t" - "\n1:\n\t" - "subs r3, r5, #44\n\t" - "it cc\n\t" - "movcc r3, r12\n\t" - "sub r4, r5, r3\n\t" - "\n2:\n\t" - "cmp r4, r3\n\t" - "beq 4f\n\t" - "ldr r14, [%[a], r3]\n\t" - "ldr r9, [%[a], r4]\n\t" - "umull r9, r10, r14, r9\n\t" - "adds r6, r6, r9\n\t" - "adcs r7, r7, r10\n\t" - "adc r8, r8, r12\n\t" - "adds r6, r6, r9\n\t" - "adcs r7, r7, r10\n\t" - "adc r8, r8, r12\n\t" - "bal 5f\n\t" - "\n4:\n\t" - "ldr r14, [%[a], r3]\n\t" - "umull r9, r10, r14, r14\n\t" - "adds r6, r6, r9\n\t" - "adcs r7, r7, r10\n\t" - "adc r8, r8, r12\n\t" - "\n5:\n\t" - "add r3, r3, #4\n\t" - "sub r4, r4, #4\n\t" - "cmp r3, #48\n\t" - "beq 3f\n\t" - "cmp r3, r4\n\t" - "bgt 3f\n\t" - "cmp r3, r5\n\t" - "ble 2b\n\t" - "\n3:\n\t" - "str r6, [sp, r5]\n\t" - "mov r6, r7\n\t" - "mov r7, r8\n\t" - "mov r8, #0\n\t" - "add r5, r5, #4\n\t" - "cmp r5, #88\n\t" - "ble 1b\n\t" - "str r6, [sp, r5]\n\t" - "\n4:\n\t" - "ldr r6, [sp, #0]\n\t" - "ldr r7, [sp, #4]\n\t" - "ldr r8, [sp, #8]\n\t" - "ldr r3, [sp, #12]\n\t" - "str r6, [%[r], #0]\n\t" - "str r7, [%[r], #4]\n\t" - "str r8, [%[r], #8]\n\t" - "str r3, [%[r], #12]\n\t" - "add sp, sp, #16\n\t" - "add %[r], %[r], #16\n\t" - "subs r5, r5, #16\n\t" - "bgt 4b\n\t" - : [r] "+r" (r) - : [a] "r" (a) - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r9", "r12" - ); -} - -#else -/* Square a and put result in r. (r = a * a) - * - * r A single precision integer. - * a A single precision integer. - */ -static void sp_384_sqr_12(sp_digit* r, const sp_digit* a) -{ - __asm__ __volatile__ ( - "sub sp, sp, #48\n\t" - "mov r14, #0\n\t" - "# A[0] * A[0]\n\t" - "ldr r10, [%[a], #0]\n\t" - "umull r8, r3, r10, r10\n\t" - "mov r4, #0\n\t" - "str r8, [sp]\n\t" - "# A[0] * A[1]\n\t" - "ldr r10, [%[a], #4]\n\t" - "ldr r8, [%[a], #0]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r14, r14\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" - "str r3, [sp, #4]\n\t" - "# A[0] * A[2]\n\t" - "ldr r10, [%[a], #8]\n\t" - "ldr r8, [%[a], #0]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r4, r4, r8\n\t" - "adcs r2, r2, r9\n\t" - "adc r3, r14, r14\n\t" - "adds r4, r4, r8\n\t" - "adcs r2, r2, r9\n\t" - "adc r3, r3, r14\n\t" - "# A[1] * A[1]\n\t" - "ldr r10, [%[a], #4]\n\t" - "umull r8, r9, r10, r10\n\t" - "adds r4, r4, r8\n\t" - "adcs r2, r2, r9\n\t" - "adc r3, r3, r14\n\t" - "str r4, [sp, #8]\n\t" - "# A[0] * A[3]\n\t" - "ldr r10, [%[a], #12]\n\t" - "ldr r8, [%[a], #0]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r2, r2, r8\n\t" - "adcs r3, r3, r9\n\t" - "adc r4, r14, r14\n\t" - "adds r2, r2, r8\n\t" - "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" - "# A[1] * A[2]\n\t" - "ldr r10, [%[a], #8]\n\t" - "ldr r8, [%[a], #4]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r2, r2, r8\n\t" - "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" - "adds r2, r2, r8\n\t" - "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" - "str r2, [sp, #12]\n\t" - "# A[0] * A[4]\n\t" - "ldr r10, [%[a], #16]\n\t" - "ldr r8, [%[a], #0]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r14, r14\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" - "# A[1] * A[3]\n\t" - "ldr r10, [%[a], #12]\n\t" - "ldr r8, [%[a], #4]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" - "# A[2] * A[2]\n\t" - "ldr r10, [%[a], #8]\n\t" - "umull r8, r9, r10, r10\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" - "str r3, [sp, #16]\n\t" - "# A[0] * A[5]\n\t" - "ldr r10, [%[a], #20]\n\t" - "ldr r8, [%[a], #0]\n\t" - "umull r5, r6, r10, r8\n\t" - "mov r3, #0\n\t" - "mov r7, #0\n\t" - "# A[1] * A[4]\n\t" - "ldr r10, [%[a], #16]\n\t" - "ldr r8, [%[a], #4]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[2] * A[3]\n\t" - "ldr r10, [%[a], #12]\n\t" - "ldr r8, [%[a], #8]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "adds r5, r5, r5\n\t" - "adcs r6, r6, r6\n\t" - "adc r7, r7, r7\n\t" - "adds r4, r4, r5\n\t" - "adcs r2, r2, r6\n\t" - "adc r3, r3, r7\n\t" - "str r4, [sp, #20]\n\t" - "# A[0] * A[6]\n\t" - "ldr r10, [%[a], #24]\n\t" - "ldr r8, [%[a], #0]\n\t" - "umull r5, r6, r10, r8\n\t" - "mov r4, #0\n\t" - "mov r7, #0\n\t" - "# A[1] * A[5]\n\t" - "ldr r10, [%[a], #20]\n\t" - "ldr r8, [%[a], #4]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[2] * A[4]\n\t" - "ldr r10, [%[a], #16]\n\t" - "ldr r8, [%[a], #8]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[3] * A[3]\n\t" - "ldr r10, [%[a], #12]\n\t" - "umull r8, r9, r10, r10\n\t" - "adds r5, r5, r5\n\t" - "adcs r6, r6, r6\n\t" - "adc r7, r7, r7\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "adds r2, r2, r5\n\t" - "adcs r3, r3, r6\n\t" - "adc r4, r4, r7\n\t" - "str r2, [sp, #24]\n\t" - "# A[0] * A[7]\n\t" - "ldr r10, [%[a], #28]\n\t" - "ldr r8, [%[a], #0]\n\t" - "umull r5, r6, r10, r8\n\t" - "mov r2, #0\n\t" - "mov r7, #0\n\t" - "# A[1] * A[6]\n\t" - "ldr r10, [%[a], #24]\n\t" - "ldr r8, [%[a], #4]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[2] * A[5]\n\t" - "ldr r10, [%[a], #20]\n\t" - "ldr r8, [%[a], #8]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[3] * A[4]\n\t" - "ldr r10, [%[a], #16]\n\t" - "ldr r8, [%[a], #12]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "adds r5, r5, r5\n\t" - "adcs r6, r6, r6\n\t" - "adc r7, r7, r7\n\t" - "adds r3, r3, r5\n\t" - "adcs r4, r4, r6\n\t" - "adc r2, r2, r7\n\t" - "str r3, [sp, #28]\n\t" - "# A[0] * A[8]\n\t" - "ldr r10, [%[a], #32]\n\t" - "ldr r8, [%[a], #0]\n\t" - "umull r5, r6, r10, r8\n\t" - "mov r3, #0\n\t" - "mov r7, #0\n\t" - "# A[1] * A[7]\n\t" - "ldr r10, [%[a], #28]\n\t" - "ldr r8, [%[a], #4]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[2] * A[6]\n\t" - "ldr r10, [%[a], #24]\n\t" - "ldr r8, [%[a], #8]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[3] * A[5]\n\t" - "ldr r10, [%[a], #20]\n\t" - "ldr r8, [%[a], #12]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[4] * A[4]\n\t" - "ldr r10, [%[a], #16]\n\t" - "umull r8, r9, r10, r10\n\t" - "adds r5, r5, r5\n\t" - "adcs r6, r6, r6\n\t" - "adc r7, r7, r7\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "adds r4, r4, r5\n\t" - "adcs r2, r2, r6\n\t" - "adc r3, r3, r7\n\t" - "str r4, [sp, #32]\n\t" - "# A[0] * A[9]\n\t" - "ldr r10, [%[a], #36]\n\t" - "ldr r8, [%[a], #0]\n\t" - "umull r5, r6, r10, r8\n\t" - "mov r4, #0\n\t" - "mov r7, #0\n\t" - "# A[1] * A[8]\n\t" - "ldr r10, [%[a], #32]\n\t" - "ldr r8, [%[a], #4]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[2] * A[7]\n\t" - "ldr r10, [%[a], #28]\n\t" - "ldr r8, [%[a], #8]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[3] * A[6]\n\t" - "ldr r10, [%[a], #24]\n\t" - "ldr r8, [%[a], #12]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[4] * A[5]\n\t" - "ldr r10, [%[a], #20]\n\t" - "ldr r8, [%[a], #16]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "adds r5, r5, r5\n\t" - "adcs r6, r6, r6\n\t" - "adc r7, r7, r7\n\t" - "adds r2, r2, r5\n\t" - "adcs r3, r3, r6\n\t" - "adc r4, r4, r7\n\t" - "str r2, [sp, #36]\n\t" - "# A[0] * A[10]\n\t" - "ldr r10, [%[a], #40]\n\t" - "ldr r8, [%[a], #0]\n\t" - "umull r5, r6, r10, r8\n\t" - "mov r2, #0\n\t" - "mov r7, #0\n\t" - "# A[1] * A[9]\n\t" - "ldr r10, [%[a], #36]\n\t" - "ldr r8, [%[a], #4]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[2] * A[8]\n\t" - "ldr r10, [%[a], #32]\n\t" - "ldr r8, [%[a], #8]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[3] * A[7]\n\t" - "ldr r10, [%[a], #28]\n\t" - "ldr r8, [%[a], #12]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[4] * A[6]\n\t" - "ldr r10, [%[a], #24]\n\t" - "ldr r8, [%[a], #16]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[5] * A[5]\n\t" - "ldr r10, [%[a], #20]\n\t" - "umull r8, r9, r10, r10\n\t" - "adds r5, r5, r5\n\t" - "adcs r6, r6, r6\n\t" - "adc r7, r7, r7\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "adds r3, r3, r5\n\t" - "adcs r4, r4, r6\n\t" - "adc r2, r2, r7\n\t" - "str r3, [sp, #40]\n\t" - "# A[0] * A[11]\n\t" - "ldr r10, [%[a], #44]\n\t" - "ldr r8, [%[a], #0]\n\t" - "umull r5, r6, r10, r8\n\t" - "mov r3, #0\n\t" - "mov r7, #0\n\t" - "# A[1] * A[10]\n\t" - "ldr r10, [%[a], #40]\n\t" - "ldr r8, [%[a], #4]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[2] * A[9]\n\t" - "ldr r10, [%[a], #36]\n\t" - "ldr r8, [%[a], #8]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[3] * A[8]\n\t" - "ldr r10, [%[a], #32]\n\t" - "ldr r8, [%[a], #12]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[4] * A[7]\n\t" - "ldr r10, [%[a], #28]\n\t" - "ldr r8, [%[a], #16]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[5] * A[6]\n\t" - "ldr r10, [%[a], #24]\n\t" - "ldr r8, [%[a], #20]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "adds r5, r5, r5\n\t" - "adcs r6, r6, r6\n\t" - "adc r7, r7, r7\n\t" - "adds r4, r4, r5\n\t" - "adcs r2, r2, r6\n\t" - "adc r3, r3, r7\n\t" - "str r4, [sp, #44]\n\t" - "# A[1] * A[11]\n\t" - "ldr r10, [%[a], #44]\n\t" - "ldr r8, [%[a], #4]\n\t" - "umull r5, r6, r10, r8\n\t" - "mov r4, #0\n\t" - "mov r7, #0\n\t" - "# A[2] * A[10]\n\t" - "ldr r10, [%[a], #40]\n\t" - "ldr r8, [%[a], #8]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[3] * A[9]\n\t" - "ldr r10, [%[a], #36]\n\t" - "ldr r8, [%[a], #12]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[4] * A[8]\n\t" - "ldr r10, [%[a], #32]\n\t" - "ldr r8, [%[a], #16]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[5] * A[7]\n\t" - "ldr r10, [%[a], #28]\n\t" - "ldr r8, [%[a], #20]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[6] * A[6]\n\t" - "ldr r10, [%[a], #24]\n\t" - "umull r8, r9, r10, r10\n\t" - "adds r5, r5, r5\n\t" - "adcs r6, r6, r6\n\t" - "adc r7, r7, r7\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "adds r2, r2, r5\n\t" - "adcs r3, r3, r6\n\t" - "adc r4, r4, r7\n\t" - "str r2, [%[r], #48]\n\t" - "# A[2] * A[11]\n\t" - "ldr r10, [%[a], #44]\n\t" - "ldr r8, [%[a], #8]\n\t" - "umull r5, r6, r10, r8\n\t" - "mov r2, #0\n\t" - "mov r7, #0\n\t" - "# A[3] * A[10]\n\t" - "ldr r10, [%[a], #40]\n\t" - "ldr r8, [%[a], #12]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[4] * A[9]\n\t" - "ldr r10, [%[a], #36]\n\t" - "ldr r8, [%[a], #16]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[5] * A[8]\n\t" - "ldr r10, [%[a], #32]\n\t" - "ldr r8, [%[a], #20]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[6] * A[7]\n\t" - "ldr r10, [%[a], #28]\n\t" - "ldr r8, [%[a], #24]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "adds r5, r5, r5\n\t" - "adcs r6, r6, r6\n\t" - "adc r7, r7, r7\n\t" - "adds r3, r3, r5\n\t" - "adcs r4, r4, r6\n\t" - "adc r2, r2, r7\n\t" - "str r3, [%[r], #52]\n\t" - "# A[3] * A[11]\n\t" - "ldr r10, [%[a], #44]\n\t" - "ldr r8, [%[a], #12]\n\t" - "umull r5, r6, r10, r8\n\t" - "mov r3, #0\n\t" - "mov r7, #0\n\t" - "# A[4] * A[10]\n\t" - "ldr r10, [%[a], #40]\n\t" - "ldr r8, [%[a], #16]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[5] * A[9]\n\t" - "ldr r10, [%[a], #36]\n\t" - "ldr r8, [%[a], #20]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[6] * A[8]\n\t" - "ldr r10, [%[a], #32]\n\t" - "ldr r8, [%[a], #24]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[7] * A[7]\n\t" - "ldr r10, [%[a], #28]\n\t" - "umull r8, r9, r10, r10\n\t" - "adds r5, r5, r5\n\t" - "adcs r6, r6, r6\n\t" - "adc r7, r7, r7\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "adds r4, r4, r5\n\t" - "adcs r2, r2, r6\n\t" - "adc r3, r3, r7\n\t" - "str r4, [%[r], #56]\n\t" - "# A[4] * A[11]\n\t" - "ldr r10, [%[a], #44]\n\t" - "ldr r8, [%[a], #16]\n\t" - "umull r5, r6, r10, r8\n\t" - "mov r4, #0\n\t" - "mov r7, #0\n\t" - "# A[5] * A[10]\n\t" - "ldr r10, [%[a], #40]\n\t" - "ldr r8, [%[a], #20]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[6] * A[9]\n\t" - "ldr r10, [%[a], #36]\n\t" - "ldr r8, [%[a], #24]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[7] * A[8]\n\t" - "ldr r10, [%[a], #32]\n\t" - "ldr r8, [%[a], #28]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "adds r5, r5, r5\n\t" - "adcs r6, r6, r6\n\t" - "adc r7, r7, r7\n\t" - "adds r2, r2, r5\n\t" - "adcs r3, r3, r6\n\t" - "adc r4, r4, r7\n\t" - "str r2, [%[r], #60]\n\t" - "# A[5] * A[11]\n\t" - "ldr r10, [%[a], #44]\n\t" - "ldr r8, [%[a], #20]\n\t" - "umull r5, r6, r10, r8\n\t" - "mov r2, #0\n\t" - "mov r7, #0\n\t" - "# A[6] * A[10]\n\t" - "ldr r10, [%[a], #40]\n\t" - "ldr r8, [%[a], #24]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[7] * A[9]\n\t" - "ldr r10, [%[a], #36]\n\t" - "ldr r8, [%[a], #28]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[8] * A[8]\n\t" - "ldr r10, [%[a], #32]\n\t" - "umull r8, r9, r10, r10\n\t" - "adds r5, r5, r5\n\t" - "adcs r6, r6, r6\n\t" - "adc r7, r7, r7\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "adds r3, r3, r5\n\t" - "adcs r4, r4, r6\n\t" - "adc r2, r2, r7\n\t" - "str r3, [%[r], #64]\n\t" - "# A[6] * A[11]\n\t" - "ldr r10, [%[a], #44]\n\t" - "ldr r8, [%[a], #24]\n\t" - "umull r5, r6, r10, r8\n\t" - "mov r3, #0\n\t" - "mov r7, #0\n\t" - "# A[7] * A[10]\n\t" - "ldr r10, [%[a], #40]\n\t" - "ldr r8, [%[a], #28]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "# A[8] * A[9]\n\t" - "ldr r10, [%[a], #36]\n\t" - "ldr r8, [%[a], #32]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r5, r5, r8\n\t" - "adcs r6, r6, r9\n\t" - "adc r7, r7, r14\n\t" - "adds r5, r5, r5\n\t" - "adcs r6, r6, r6\n\t" - "adc r7, r7, r7\n\t" - "adds r4, r4, r5\n\t" - "adcs r2, r2, r6\n\t" - "adc r3, r3, r7\n\t" - "str r4, [%[r], #68]\n\t" - "# A[7] * A[11]\n\t" - "ldr r10, [%[a], #44]\n\t" - "ldr r8, [%[a], #28]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r2, r2, r8\n\t" - "adcs r3, r3, r9\n\t" - "adc r4, r14, r14\n\t" - "adds r2, r2, r8\n\t" - "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" - "# A[8] * A[10]\n\t" - "ldr r10, [%[a], #40]\n\t" - "ldr r8, [%[a], #32]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r2, r2, r8\n\t" - "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" - "adds r2, r2, r8\n\t" - "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" - "# A[9] * A[9]\n\t" - "ldr r10, [%[a], #36]\n\t" - "umull r8, r9, r10, r10\n\t" - "adds r2, r2, r8\n\t" - "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" - "str r2, [%[r], #72]\n\t" - "# A[8] * A[11]\n\t" - "ldr r10, [%[a], #44]\n\t" - "ldr r8, [%[a], #32]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r14, r14\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" - "# A[9] * A[10]\n\t" - "ldr r10, [%[a], #40]\n\t" - "ldr r8, [%[a], #36]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" - "adds r3, r3, r8\n\t" - "adcs r4, r4, r9\n\t" - "adc r2, r2, r14\n\t" - "str r3, [%[r], #76]\n\t" - "# A[9] * A[11]\n\t" - "ldr r10, [%[a], #44]\n\t" - "ldr r8, [%[a], #36]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r4, r4, r8\n\t" - "adcs r2, r2, r9\n\t" - "adc r3, r14, r14\n\t" - "adds r4, r4, r8\n\t" - "adcs r2, r2, r9\n\t" - "adc r3, r3, r14\n\t" - "# A[10] * A[10]\n\t" - "ldr r10, [%[a], #40]\n\t" - "umull r8, r9, r10, r10\n\t" - "adds r4, r4, r8\n\t" - "adcs r2, r2, r9\n\t" - "adc r3, r3, r14\n\t" - "str r4, [%[r], #80]\n\t" - "# A[10] * A[11]\n\t" - "ldr r10, [%[a], #44]\n\t" - "ldr r8, [%[a], #40]\n\t" - "umull r8, r9, r10, r8\n\t" - "adds r2, r2, r8\n\t" - "adcs r3, r3, r9\n\t" - "adc r4, r14, r14\n\t" - "adds r2, r2, r8\n\t" - "adcs r3, r3, r9\n\t" - "adc r4, r4, r14\n\t" - "str r2, [%[r], #84]\n\t" - "# A[11] * A[11]\n\t" - "ldr r10, [%[a], #44]\n\t" - "umull r8, r9, r10, r10\n\t" - "adds r3, r3, r8\n\t" - "adc r4, r4, r9\n\t" - "str r3, [%[r], #88]\n\t" - "str r4, [%[r], #92]\n\t" - "ldr r2, [sp, #0]\n\t" - "ldr r3, [sp, #4]\n\t" - "ldr r4, [sp, #8]\n\t" - "ldr r8, [sp, #12]\n\t" - "str r2, [%[r], #0]\n\t" - "str r3, [%[r], #4]\n\t" - "str r4, [%[r], #8]\n\t" - "str r8, [%[r], #12]\n\t" - "ldr r2, [sp, #16]\n\t" - "ldr r3, [sp, #20]\n\t" - "ldr r4, [sp, #24]\n\t" - "ldr r8, [sp, #28]\n\t" - "str r2, [%[r], #16]\n\t" - "str r3, [%[r], #20]\n\t" - "str r4, [%[r], #24]\n\t" - "str r8, [%[r], #28]\n\t" - "ldr r2, [sp, #32]\n\t" - "ldr r3, [sp, #36]\n\t" - "ldr r4, [sp, #40]\n\t" - "ldr r8, [sp, #44]\n\t" - "str r2, [%[r], #32]\n\t" - "str r3, [%[r], #36]\n\t" - "str r4, [%[r], #40]\n\t" - "str r8, [%[r], #44]\n\t" - "add sp, sp, #48\n\t" - : - : [r] "r" (r), [a] "r" (a) - : "memory", "r2", "r3", "r4", "r8", "r9", "r10", "r8", "r5", "r6", "r7", "r14" - ); -} - -#endif /* WOLFSSL_SP_SMALL */ /* Square the Montgomery form number. (r = a * a mod m) * * r Result of squaring. @@ -40732,8 +40770,8 @@ static void sp_384_sqr_12(sp_digit* r, const sp_digit* a) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_384_mont_sqr_12(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_384_mont_sqr_12(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_384_sqr_12(r, a); sp_384_mont_reduce_12(r, m, mp); @@ -40757,7 +40795,7 @@ static void sp_384_mont_sqr_n_12(sp_digit* r, const sp_digit* a, int n, } } -#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */ +#endif /* !WOLFSSL_SP_SMALL | HAVE_COMP_KEY */ #ifdef WOLFSSL_SP_SMALL /* Mod-2 for the P384 curve. */ static const uint32_t p384_mod_minus_2[12] = { @@ -41046,7 +41084,8 @@ static int32_t sp_384_cmp_12(const sp_digit* a, const sp_digit* b) * p Montgomery form projective coordinate point. * t Temporary ordinate data. */ -static void sp_384_map_12(sp_point_384* r, const sp_point_384* p, sp_digit* t) +static void sp_384_map_12(sp_point_384* r, const sp_point_384* p, + sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2*12; @@ -41082,122 +41121,6 @@ static void sp_384_map_12(sp_point_384* r, const sp_point_384* p, sp_digit* t) } -#ifdef WOLFSSL_SP_SMALL -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -static sp_digit sp_384_add_12(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "add r12, %[a], #48\n\t" - "\n1:\n\t" - "adds %[c], %[c], #-1\n\t" - "ldr r4, [%[a]], #4\n\t" - "ldr r5, [%[a]], #4\n\t" - "ldr r6, [%[a]], #4\n\t" - "ldr r7, [%[a]], #4\n\t" - "ldr r8, [%[b]], #4\n\t" - "ldr r9, [%[b]], #4\n\t" - "ldr r10, [%[b]], #4\n\t" - "ldr r14, [%[b]], #4\n\t" - "adcs r4, r4, r8\n\t" - "adcs r5, r5, r9\n\t" - "adcs r6, r6, r10\n\t" - "adcs r7, r7, r14\n\t" - "str r4, [%[r]], #4\n\t" - "str r5, [%[r]], #4\n\t" - "str r6, [%[r]], #4\n\t" - "str r7, [%[r]], #4\n\t" - "mov r4, #0\n\t" - "adc %[c], r4, #0\n\t" - "cmp %[a], r12\n\t" - "bne 1b\n\t" - : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) - : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" - ); - - return c; -} - -#else -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -static sp_digit sp_384_add_12(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "mov r12, #0\n\t" - "ldr r4, [%[a], #0]\n\t" - "ldr r5, [%[a], #4]\n\t" - "ldr r6, [%[a], #8]\n\t" - "ldr r7, [%[a], #12]\n\t" - "ldr r8, [%[b], #0]\n\t" - "ldr r9, [%[b], #4]\n\t" - "ldr r10, [%[b], #8]\n\t" - "ldr r14, [%[b], #12]\n\t" - "adds r4, r4, r8\n\t" - "adcs r5, r5, r9\n\t" - "adcs r6, r6, r10\n\t" - "adcs r7, r7, r14\n\t" - "str r4, [%[r], #0]\n\t" - "str r5, [%[r], #4]\n\t" - "str r6, [%[r], #8]\n\t" - "str r7, [%[r], #12]\n\t" - "ldr r4, [%[a], #16]\n\t" - "ldr r5, [%[a], #20]\n\t" - "ldr r6, [%[a], #24]\n\t" - "ldr r7, [%[a], #28]\n\t" - "ldr r8, [%[b], #16]\n\t" - "ldr r9, [%[b], #20]\n\t" - "ldr r10, [%[b], #24]\n\t" - "ldr r14, [%[b], #28]\n\t" - "adcs r4, r4, r8\n\t" - "adcs r5, r5, r9\n\t" - "adcs r6, r6, r10\n\t" - "adcs r7, r7, r14\n\t" - "str r4, [%[r], #16]\n\t" - "str r5, [%[r], #20]\n\t" - "str r6, [%[r], #24]\n\t" - "str r7, [%[r], #28]\n\t" - "ldr r4, [%[a], #32]\n\t" - "ldr r5, [%[a], #36]\n\t" - "ldr r6, [%[a], #40]\n\t" - "ldr r7, [%[a], #44]\n\t" - "ldr r8, [%[b], #32]\n\t" - "ldr r9, [%[b], #36]\n\t" - "ldr r10, [%[b], #40]\n\t" - "ldr r14, [%[b], #44]\n\t" - "adcs r4, r4, r8\n\t" - "adcs r5, r5, r9\n\t" - "adcs r6, r6, r10\n\t" - "adcs r7, r7, r14\n\t" - "str r4, [%[r], #32]\n\t" - "str r5, [%[r], #36]\n\t" - "str r6, [%[r], #40]\n\t" - "str r7, [%[r], #44]\n\t" - "adc %[c], r12, r12\n\t" - : [c] "+r" (c) - : [r] "r" (r), [a] "r" (a), [b] "r" (b) - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" - ); - - return c; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Add two Montgomery form numbers (r = a + b % m). * * r Result of addition. @@ -41244,120 +41167,6 @@ static void sp_384_mont_tpl_12(sp_digit* r, const sp_digit* a, const sp_digit* m sp_384_cond_sub_12(r, r, m, 0 - o); } -#ifdef WOLFSSL_SP_SMALL -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -static sp_digit sp_384_sub_12(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "add r12, %[a], #48\n\t" - "\n1:\n\t" - "rsbs %[c], %[c], #0\n\t" - "ldr r4, [%[a]], #4\n\t" - "ldr r5, [%[a]], #4\n\t" - "ldr r6, [%[a]], #4\n\t" - "ldr r7, [%[a]], #4\n\t" - "ldr r8, [%[b]], #4\n\t" - "ldr r9, [%[b]], #4\n\t" - "ldr r10, [%[b]], #4\n\t" - "ldr r14, [%[b]], #4\n\t" - "sbcs r4, r4, r8\n\t" - "sbcs r5, r5, r9\n\t" - "sbcs r6, r6, r10\n\t" - "sbcs r7, r7, r14\n\t" - "str r4, [%[r]], #4\n\t" - "str r5, [%[r]], #4\n\t" - "str r6, [%[r]], #4\n\t" - "str r7, [%[r]], #4\n\t" - "sbc %[c], r4, r4\n\t" - "cmp %[a], r12\n\t" - "bne 1b\n\t" - : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) - : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" - ); - - return c; -} - -#else -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -static sp_digit sp_384_sub_12(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "ldr r3, [%[a], #0]\n\t" - "ldr r4, [%[a], #4]\n\t" - "ldr r5, [%[a], #8]\n\t" - "ldr r6, [%[a], #12]\n\t" - "ldr r7, [%[b], #0]\n\t" - "ldr r8, [%[b], #4]\n\t" - "ldr r9, [%[b], #8]\n\t" - "ldr r10, [%[b], #12]\n\t" - "subs r3, r3, r7\n\t" - "sbcs r4, r4, r8\n\t" - "sbcs r5, r5, r9\n\t" - "sbcs r6, r6, r10\n\t" - "str r3, [%[r], #0]\n\t" - "str r4, [%[r], #4]\n\t" - "str r5, [%[r], #8]\n\t" - "str r6, [%[r], #12]\n\t" - "ldr r3, [%[a], #16]\n\t" - "ldr r4, [%[a], #20]\n\t" - "ldr r5, [%[a], #24]\n\t" - "ldr r6, [%[a], #28]\n\t" - "ldr r7, [%[b], #16]\n\t" - "ldr r8, [%[b], #20]\n\t" - "ldr r9, [%[b], #24]\n\t" - "ldr r10, [%[b], #28]\n\t" - "sbcs r3, r3, r7\n\t" - "sbcs r4, r4, r8\n\t" - "sbcs r5, r5, r9\n\t" - "sbcs r6, r6, r10\n\t" - "str r3, [%[r], #16]\n\t" - "str r4, [%[r], #20]\n\t" - "str r5, [%[r], #24]\n\t" - "str r6, [%[r], #28]\n\t" - "ldr r3, [%[a], #32]\n\t" - "ldr r4, [%[a], #36]\n\t" - "ldr r5, [%[a], #40]\n\t" - "ldr r6, [%[a], #44]\n\t" - "ldr r7, [%[b], #32]\n\t" - "ldr r8, [%[b], #36]\n\t" - "ldr r9, [%[b], #40]\n\t" - "ldr r10, [%[b], #44]\n\t" - "sbcs r3, r3, r7\n\t" - "sbcs r4, r4, r8\n\t" - "sbcs r5, r5, r9\n\t" - "sbcs r6, r6, r10\n\t" - "str r3, [%[r], #32]\n\t" - "str r4, [%[r], #36]\n\t" - "str r5, [%[r], #40]\n\t" - "str r6, [%[r], #44]\n\t" - "sbc %[c], %[c], #0\n\t" - : [c] "+r" (c) - : [r] "r" (r), [a] "r" (a), [b] "r" (b) - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" - ); - - return c; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Conditionally add a and b using the mask m. * m is -1 to add and 0 when not. * @@ -41970,8 +41779,8 @@ static int sp_384_proj_point_add_12_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r, } #endif /* WOLFSSL_SP_NONBLOCK */ -static void sp_384_proj_point_add_12(sp_point_384* r, const sp_point_384* p, const sp_point_384* q, - sp_digit* t) +static void sp_384_proj_point_add_12(sp_point_384* r, + const sp_point_384* p, const sp_point_384* q, sp_digit* t) { const sp_point_384* ap[2]; sp_point_384* rp[2]; @@ -42150,9 +41959,11 @@ static void sp_384_get_point_16_12(sp_point_384* r, const sp_point_384* table, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Simple, smaller code size and memory size, of windowing. - * Calculate uindow of 4 bits. - * Only add points from table. + * Fast implementation that generates a pre-computation table. + * 4 bits of window (no sliding!). + * Uses add and double for calculating table. + * 384 doubles. + * 108 adds. * * r Resulting point. * g Point to multiply. @@ -42181,7 +41992,8 @@ static int sp_384_ecc_mulmod_fast_12(sp_point_384* r, const sp_point_384* g, con sp_digit* tmp; sp_digit n; int i; - int c, y; + int c; + int y; int err; /* Constant time used for cache attack resistance implementation. */ @@ -42254,7 +42066,7 @@ static int sp_384_ecc_mulmod_fast_12(sp_point_384* r, const sp_point_384* g, con i = 10; n = k[i+1] << 0; c = 28; - y = n >> 28; + y = (int)(n >> 28); #ifndef WC_NO_CACHE_RESISTANT if (ct) { sp_384_get_point_16_12(rt, t, y); @@ -42319,12 +42131,6 @@ static int sp_384_ecc_mulmod_fast_12(sp_point_384* r, const sp_point_384* g, con return err; } -/* A table entry for pre-computed points. */ -typedef struct sp_table_entry_384 { - sp_digit x[12]; - sp_digit y[12]; -} sp_table_entry_384; - #ifdef FP_ECC /* Double the Montgomery form projective point p a number of times. * @@ -42333,7 +42139,8 @@ typedef struct sp_table_entry_384 { * n Number of times to double * t Temporary ordinate data. */ -static void sp_384_proj_point_dbl_n_12(sp_point_384* p, int n, sp_digit* t) +static void sp_384_proj_point_dbl_n_12(sp_point_384* p, int n, + sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*12; @@ -42414,6 +42221,36 @@ static void sp_384_proj_point_dbl_n_12(sp_point_384* p, int n, sp_digit* t) sp_384_div2_12(y, y, p384_mod); } +/* Convert the projective point to affine. + * Ordinates are in Montgomery form. + * + * a Point to convert. + * t Temporary data. + */ +static void sp_384_proj_to_affine_12(sp_point_384* a, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 12; + sp_digit* tmp = t + 4 * 12; + + sp_384_mont_inv_12(t1, a->z, tmp); + + sp_384_mont_sqr_12(t2, t1, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t1, t2, t1, p384_mod, p384_mp_mod); + + sp_384_mont_mul_12(a->x, a->x, t2, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(a->y, a->y, t1, p384_mod, p384_mp_mod); + XMEMCPY(a->z, p384_norm_mod, sizeof(p384_norm_mod)); +} + +#endif /* FP_ECC */ +/* A table entry for pre-computed points. */ +typedef struct sp_table_entry_384 { + sp_digit x[12]; + sp_digit y[12]; +} sp_table_entry_384; + +#ifdef FP_ECC #endif /* FP_ECC */ /* Add two Montgomery form projective points. The second point has a q value of * one. @@ -42499,29 +42336,11 @@ static void sp_384_proj_point_add_qz1_12(sp_point_384* r, const sp_point_384* p, #ifdef WOLFSSL_SP_SMALL #ifdef FP_ECC -/* Convert the projective point to affine. - * Ordinates are in Montgomery form. - * - * a Point to convert. - * t Temporary data. - */ -static void sp_384_proj_to_affine_12(sp_point_384* a, sp_digit* t) -{ - sp_digit* t1 = t; - sp_digit* t2 = t + 2 * 12; - sp_digit* tmp = t + 4 * 12; - - sp_384_mont_inv_12(t1, a->z, tmp); - - sp_384_mont_sqr_12(t2, t1, p384_mod, p384_mp_mod); - sp_384_mont_mul_12(t1, t2, t1, p384_mod, p384_mp_mod); - - sp_384_mont_mul_12(a->x, a->x, t2, p384_mod, p384_mp_mod); - sp_384_mont_mul_12(a->y, a->y, t1, p384_mod, p384_mp_mod); - XMEMCPY(a->z, p384_norm_mod, sizeof(p384_norm_mod)); -} - /* Generate the pre-computed table of points for the base point. + * + * width = 4 + * 16 entries + * 96 bits between * * a The base point. * table Place to store generated point data. @@ -42532,12 +42351,15 @@ static int sp_384_gen_stripe_table_12(const sp_point_384* a, sp_table_entry_384* table, sp_digit* tmp, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_point_384 td, s1d, s2d; + sp_point_384 td; + sp_point_384 s1d; + sp_point_384 s2d; #endif sp_point_384* t; sp_point_384* s1 = NULL; sp_point_384* s2 = NULL; - int i, j; + int i; + int j; int err; (void)heap; @@ -42672,8 +42494,10 @@ static void sp_384_get_entry_16_12(sp_point_384* r, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Implementation uses striping of bits. - * Choose bits 4 bits apart. + * Stripe implementation. + * Pre-generated: 2^0, 2^96, ... + * Pre-generated: products of all combinations of above. + * 4 doubles and adds (with qz=1) * * r Resulting point. * k Scalar to multiply by. @@ -42695,8 +42519,10 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, sp_point_384* rt; sp_point_384* p = NULL; sp_digit* t; - int i, j; - int y, x; + int i; + int j; + int y; + int x; int err; (void)g; @@ -42724,8 +42550,10 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, XMEMCPY(rt->z, p384_norm_mod, sizeof(p384_norm_mod)); y = 0; - for (j=0,x=95; j<4; j++,x+=96) { + x = 95; + for (j=0; j<4; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 96; } #ifndef WC_NO_CACHE_RESISTANT if (ct) { @@ -42739,8 +42567,10 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, rt->infinity = !y; for (i=94; i>=0; i--) { y = 0; - for (j=0,x=i; j<4; j++,x+=96) { + x = i; + for (j=0; j<4; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 96; } sp_384_proj_point_dbl_12(rt, rt, t); @@ -42782,16 +42612,25 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, #define FP_ENTRIES 16 #endif +/* Cache entry - holds precomputation tables for a point. */ typedef struct sp_cache_384_t { + /* X ordinate of point that table was generated from. */ sp_digit x[12]; + /* Y ordinate of point that table was generated from. */ sp_digit y[12]; + /* Precomputation table for point. */ sp_table_entry_384 table[16]; + /* Count of entries in table. */ uint32_t cnt; + /* Point and table set in entry. */ int set; } sp_cache_384_t; +/* Cache of tables. */ static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES]; +/* Index of last entry in cache. */ static THREAD_LS_T int sp_cache_384_last = -1; +/* Cache has been initialized. */ static THREAD_LS_T int sp_cache_384_inited = 0; #ifndef HAVE_THREAD_LS @@ -42799,9 +42638,15 @@ static THREAD_LS_T int sp_cache_384_inited = 0; static wolfSSL_Mutex sp_cache_384_lock; #endif +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache) { - int i, j; + int i; + int j; uint32_t least; if (sp_cache_384_inited == 0) { @@ -42910,6 +42755,10 @@ static int sp_384_ecc_mulmod_12(sp_point_384* r, const sp_point_384* g, const sp #else #ifdef FP_ECC /* Generate the pre-computed table of points for the base point. + * + * width = 8 + * 256 entries + * 48 bits between * * a The base point. * table Place to store generated point data. @@ -42920,12 +42769,15 @@ static int sp_384_gen_stripe_table_12(const sp_point_384* a, sp_table_entry_384* table, sp_digit* tmp, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_point_384 td, s1d, s2d; + sp_point_384 td; + sp_point_384 s1d; + sp_point_384 s2d; #endif sp_point_384* t; sp_point_384* s1 = NULL; sp_point_384* s2 = NULL; - int i, j; + int i; + int j; int err; (void)heap; @@ -43060,8 +42912,10 @@ static void sp_384_get_entry_256_12(sp_point_384* r, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Implementation uses striping of bits. - * Choose bits 8 bits apart. + * Stripe implementation. + * Pre-generated: 2^0, 2^48, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) * * r Resulting point. * k Scalar to multiply by. @@ -43083,8 +42937,10 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, sp_point_384* rt; sp_point_384* p = NULL; sp_digit* t; - int i, j; - int y, x; + int i; + int j; + int y; + int x; int err; (void)g; @@ -43112,8 +42968,10 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, XMEMCPY(rt->z, p384_norm_mod, sizeof(p384_norm_mod)); y = 0; - for (j=0,x=47; j<8; j++,x+=48) { + x = 47; + for (j=0; j<8; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 48; } #ifndef WC_NO_CACHE_RESISTANT if (ct) { @@ -43127,8 +42985,10 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, rt->infinity = !y; for (i=46; i>=0; i--) { y = 0; - for (j=0,x=i; j<8; j++,x+=48) { + x = i; + for (j=0; j<8; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 48; } sp_384_proj_point_dbl_12(rt, rt, t); @@ -43170,16 +43030,25 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, #define FP_ENTRIES 16 #endif +/* Cache entry - holds precomputation tables for a point. */ typedef struct sp_cache_384_t { + /* X ordinate of point that table was generated from. */ sp_digit x[12]; + /* Y ordinate of point that table was generated from. */ sp_digit y[12]; + /* Precomputation table for point. */ sp_table_entry_384 table[256]; + /* Count of entries in table. */ uint32_t cnt; + /* Point and table set in entry. */ int set; } sp_cache_384_t; +/* Cache of tables. */ static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES]; +/* Index of last entry in cache. */ static THREAD_LS_T int sp_cache_384_last = -1; +/* Cache has been initialized. */ static THREAD_LS_T int sp_cache_384_inited = 0; #ifndef HAVE_THREAD_LS @@ -43187,9 +43056,15 @@ static THREAD_LS_T int sp_cache_384_inited = 0; static wolfSSL_Mutex sp_cache_384_lock; #endif +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache) { - int i, j; + int i; + int j; uint32_t least; if (sp_cache_384_inited == 0) { @@ -43306,8 +43181,8 @@ static int sp_384_ecc_mulmod_12(sp_point_384* r, const sp_point_384* g, const sp * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_384(mp_int* km, ecc_point* gm, ecc_point* r, int map, - void* heap) +int sp_ecc_mulmod_384(const mp_int* km, const ecc_point* gm, ecc_point* r, + int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_384 p; @@ -43348,7 +43223,94 @@ int sp_ecc_mulmod_384(mp_int* km, ecc_point* gm, ecc_point* r, int map, return err; } +/* Multiply the point by the scalar, add point a and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * p Point to multiply. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_add_384(const mp_int* km, const ecc_point* gm, + const ecc_point* am, int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_384 p; + sp_point_384 a; + sp_digit kd[12]; + sp_digit t[12 * 2 * 6]; +#endif + sp_point_384* point; + sp_point_384* addP = NULL; + sp_digit* k = NULL; + sp_digit* tmp = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_12(heap, p, point); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (12 + 12 * 2 * 6), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 12; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 12, km); + sp_384_point_from_ecc_point_12(point, gm); + sp_384_point_from_ecc_point_12(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_12(addP->x, addP->x, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_12(addP->y, addP->y, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_12(addP->z, addP->z, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_12(point, point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_384_proj_point_add_12(point, point, addP, tmp); + + if (map) { + sp_384_map_12(point, point, tmp); + } + + err = sp_384_point_to_ecc_point_12(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(addP, 0, heap); + sp_384_point_free_12(point, 0, heap); + + return err; +} + #ifdef WOLFSSL_SP_SMALL +/* Striping precomputation table. + * 4 points combined into a table of 16 points. + * Distance of 96 between points. + */ static const sp_table_entry_384 p384_table[16] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -43433,6 +43395,11 @@ static const sp_table_entry_384 p384_table[16] = { /* Multiply the base point of P384 by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Stripe implementation. + * Pre-generated: 2^0, 2^96, ... + * Pre-generated: products of all combinations of above. + * 4 doubles and adds (with qz=1) + * * r Resulting point. * k Scalar to multiply by. * map Indicates whether to convert result to affine. @@ -43448,6 +43415,10 @@ static int sp_384_ecc_mulmod_base_12(sp_point_384* r, const sp_digit* k, } #else +/* Striping precomputation table. + * 8 points combined into a table of 256 points. + * Distance of 48 between points. + */ static const sp_table_entry_384 p384_table[256] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -44732,6 +44703,11 @@ static const sp_table_entry_384 p384_table[256] = { /* Multiply the base point of P384 by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Stripe implementation. + * Pre-generated: 2^0, 2^48, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * * r Resulting point. * k Scalar to multiply by. * map Indicates whether to convert result to affine. @@ -44757,7 +44733,7 @@ static int sp_384_ecc_mulmod_base_12(sp_point_384* r, const sp_digit* k, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_base_384(mp_int* km, ecc_point* r, int map, void* heap) +int sp_ecc_mulmod_base_384(const mp_int* km, ecc_point* r, int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_384 p; @@ -44798,6 +44774,87 @@ int sp_ecc_mulmod_base_384(mp_int* km, ecc_point* r, int map, void* heap) return err; } +/* Multiply the base point of P384 by the scalar, add point a and return + * the result. If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_add_384(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_384 p; + sp_point_384 a; + sp_digit kd[12]; + sp_digit t[12 * 2 * 6]; +#endif + sp_point_384* point; + sp_point_384* addP = NULL; + sp_digit* tmp = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_12(heap, p, point); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (12 + 12 * 2 * 6), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 12; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 12, km); + sp_384_point_from_ecc_point_12(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_12(addP->x, addP->x, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_12(addP->y, addP->y, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_12(addP->z, addP->z, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_base_12(point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_384_proj_point_add_12(point, point, addP, tmp); + + if (map) { + sp_384_map_12(point, point, tmp); + } + + err = sp_384_point_to_ecc_point_12(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(addP, 0, heap); + sp_384_point_free_12(point, 0, heap); + + return err; +} + #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \ defined(HAVE_ECC_VERIFY) /* Returns 1 if the number of zero. @@ -44812,7 +44869,7 @@ static int sp_384_iszero_12(const sp_digit* a) a[8] | a[9] | a[10] | a[11]) == 0; } -#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN | HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ /* Add 1 to a. (a = a + 1) * * a A single precision integer. @@ -44871,7 +44928,8 @@ static void sp_384_add_one_12(sp_digit* a) */ static void sp_384_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -45015,7 +45073,10 @@ int sp_ecc_make_key_384(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) */ static void sp_384_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; j = 384 / 8 - 1; a[j] = 0; @@ -45056,7 +45117,7 @@ static void sp_384_to_bin(sp_digit* r, byte* a) * returns BUFFER_E if the buffer is to small for output size, * MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_secret_gen_384(mp_int* priv, ecc_point* pub, byte* out, +int sp_ecc_secret_gen_384(const mp_int* priv, const ecc_point* pub, byte* out, word32* outLen, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) @@ -45267,83 +45328,73 @@ static void sp_384_mul_d_12(sp_digit* r, const sp_digit* a, "str r3, [%[r]]\n\t" "# A[1] * B\n\t" "ldr r8, [%[a], #4]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #4]\n\t" "# A[2] * B\n\t" "ldr r8, [%[a], #8]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #8]\n\t" "# A[3] * B\n\t" "ldr r8, [%[a], #12]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #12]\n\t" "# A[4] * B\n\t" "ldr r8, [%[a], #16]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #16]\n\t" "# A[5] * B\n\t" "ldr r8, [%[a], #20]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #20]\n\t" "# A[6] * B\n\t" "ldr r8, [%[a], #24]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #24]\n\t" "# A[7] * B\n\t" "ldr r8, [%[a], #28]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #28]\n\t" "# A[8] * B\n\t" "ldr r8, [%[a], #32]\n\t" - "mov r4, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r5, r5, r6\n\t" "adcs r3, r3, r7\n\t" - "adc r4, r4, r10\n\t" + "adc r4, r10, r10\n\t" "str r5, [%[r], #32]\n\t" "# A[9] * B\n\t" "ldr r8, [%[a], #36]\n\t" - "mov r5, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r3, r3, r6\n\t" "adcs r4, r4, r7\n\t" - "adc r5, r5, r10\n\t" + "adc r5, r10, r10\n\t" "str r3, [%[r], #36]\n\t" "# A[10] * B\n\t" "ldr r8, [%[a], #40]\n\t" - "mov r3, #0\n\t" "umull r6, r7, %[b], r8\n\t" "adds r4, r4, r6\n\t" "adcs r5, r5, r7\n\t" - "adc r3, r3, r10\n\t" + "adc r3, r10, r10\n\t" "str r4, [%[r], #40]\n\t" "# A[11] * B\n\t" "ldr r8, [%[a], #44]\n\t" @@ -45515,7 +45566,6 @@ static const uint32_t p384_order_minus_2[12] = { /* The low half of the order-2 of the P384 curve. */ static const uint32_t p384_order_low[6] = { 0xccc52971U,0xecec196aU,0x48b0a77aU,0x581a0db2U,0xf4372ddfU,0xc7634d81U - }; #endif /* WOLFSSL_SP_SMALL */ @@ -45663,7 +45713,7 @@ static void sp_384_mont_inv_order_12(sp_digit* r, const sp_digit* a, sp_384_mont_mul_order_12(t2, t2, t); for (i=191; i>=1; i--) { sp_384_mont_sqr_order_12(t2, t2); - if (((sp_digit)p384_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p384_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_384_mont_mul_order_12(t2, t2, a); } } @@ -45672,12 +45722,63 @@ static void sp_384_mont_inv_order_12(sp_digit* r, const sp_digit* a, #endif /* WOLFSSL_SP_SMALL */ } -#endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ #ifdef HAVE_ECC_SIGN #ifndef SP_ECC_MAX_SIG_GEN #define SP_ECC_MAX_SIG_GEN 64 #endif +/* Calculate second signature value S from R, k and private value. + * + * s = (r * x + e) / k + * + * s Signature value. + * r First signature value. + * k Ephemeral private key. + * x Private key as a number. + * e Hash of message as a number. + * tmp Temporary storage for intermediate numbers. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_calc_s_12(sp_digit* s, const sp_digit* r, sp_digit* k, + sp_digit* x, const sp_digit* e, sp_digit* tmp) +{ + int err; + sp_digit carry; + int32_t c; + sp_digit* kInv = k; + + /* Conv k to Montgomery form (mod order) */ + sp_384_mul_12(k, k, p384_norm_order); + err = sp_384_mod_12(k, k, p384_order); + if (err == MP_OKAY) { + sp_384_norm_12(k); + + /* kInv = 1/k mod order */ + sp_384_mont_inv_order_12(kInv, k, tmp); + sp_384_norm_12(kInv); + + /* s = r * x + e */ + sp_384_mul_12(x, x, r); + err = sp_384_mod_12(x, x, p384_order); + } + if (err == MP_OKAY) { + sp_384_norm_12(x); + carry = sp_384_add_12(s, e, x); + sp_384_cond_sub_12(s, s, p384_order, 0 - carry); + sp_384_norm_12(s); + c = sp_384_cmp_12(s, p384_order); + sp_384_cond_sub_12(s, s, p384_order, 0L - (sp_digit)(c >= 0)); + sp_384_norm_12(s); + + /* s = s * k^-1 mod order */ + sp_384_mont_mul_order_12(s, s, kInv); + sp_384_norm_12(s); + } + + return err; +} + /* Sign the hash using the private key. * e = [hash, 384 bits] from binary * r = (k.G)->x mod order @@ -45712,8 +45813,8 @@ typedef struct sp_ecc_sign_384_ctx { int i; } sp_ecc_sign_384_ctx; -int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, + mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_sign_384_ctx* ctx = (sp_ecc_sign_384_ctx*)sp_ctx->data; @@ -45853,8 +45954,8 @@ int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, W } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, + const mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -45872,11 +45973,9 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit* r = NULL; sp_digit* tmp = NULL; sp_point_384* point = NULL; - sp_digit carry; sp_digit* s = NULL; - sp_digit* kInv = NULL; - int err = MP_OKAY; int32_t c; + int err = MP_OKAY; int i; (void)heap; @@ -45907,7 +46006,6 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, tmp = td; #endif s = e; - kInv = k; if (hashLen > 48U) { hashLen = 48U; @@ -45915,8 +46013,6 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, } for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) { - sp_384_from_mp(x, 12, priv); - /* New random point. */ if (km == NULL || mp_iszero(km)) { err = sp_384_ecc_gen_k_12(rng, k); @@ -45926,7 +46022,7 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, mp_zero(km); } if (err == MP_OKAY) { - err = sp_384_ecc_mulmod_base_12(point, k, 1, 1, NULL); + err = sp_384_ecc_mulmod_base_12(point, k, 1, 1, heap); } if (err == MP_OKAY) { @@ -45937,38 +46033,15 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_384_cond_sub_12(r, r, p384_order, 0L - (sp_digit)(c >= 0)); sp_384_norm_12(r); - /* Conv k to Montgomery form (mod order) */ - sp_384_mul_12(k, k, p384_norm_order); - err = sp_384_mod_12(k, k, p384_order); - } - if (err == MP_OKAY) { - sp_384_norm_12(k); - /* kInv = 1/k mod order */ - sp_384_mont_inv_order_12(kInv, k, tmp); - sp_384_norm_12(kInv); - - /* s = r * x + e */ - sp_384_mul_12(x, x, r); - err = sp_384_mod_12(x, x, p384_order); - } - if (err == MP_OKAY) { - sp_384_norm_12(x); + sp_384_from_mp(x, 12, priv); sp_384_from_bin(e, 12, hash, (int)hashLen); - carry = sp_384_add_12(s, e, x); - sp_384_cond_sub_12(s, s, p384_order, 0 - carry); - sp_384_norm_12(s); - c = sp_384_cmp_12(s, p384_order); - sp_384_cond_sub_12(s, s, p384_order, 0L - (sp_digit)(c >= 0)); - sp_384_norm_12(s); - /* s = s * k^-1 mod order */ - sp_384_mont_mul_order_12(s, s, kInv); - sp_384_norm_12(s); + err = sp_384_calc_s_12(s, r, k, x, e, tmp); + } - /* Check that signature is usable. */ - if (sp_384_iszero_12(s) == 0) { - break; - } + /* Check that signature is usable. */ + if ((err == MP_OKAY) && (sp_384_iszero_12(s) == 0)) { + break; } #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP i = 1; @@ -45996,7 +46069,6 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, XMEMSET(x, 0, sizeof(sp_digit) * 2U * 12U); XMEMSET(k, 0, sizeof(sp_digit) * 2U * 12U); XMEMSET(r, 0, sizeof(sp_digit) * 2U * 12U); - XMEMSET(r, 0, sizeof(sp_digit) * 2U * 12U); XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 12U); #endif sp_384_point_free_12(point, 1, heap); @@ -46335,6 +46407,100 @@ static int sp_384_mod_inv_12(sp_digit* r, const sp_digit* a, const sp_digit* m) } #endif /* WOLFSSL_SP_SMALL */ + +/* Add point p1 into point p2. Handles p1 == p2 and result at infinity. + * + * p1 First point to add and holds result. + * p2 Second point to add. + * tmp Temporary storage for intermediate numbers. + */ +static void sp_384_add_points_12(sp_point_384* p1, const sp_point_384* p2, + sp_digit* tmp) +{ + + sp_384_proj_point_add_12(p1, p1, p2, tmp); + if (sp_384_iszero_12(p1->z)) { + if (sp_384_iszero_12(p1->x) && sp_384_iszero_12(p1->y)) { + sp_384_proj_point_dbl_12(p1, p2, tmp); + } + else { + /* Y ordinate is not used from here - don't set. */ + p1->x[0] = 0; + p1->x[1] = 0; + p1->x[2] = 0; + p1->x[3] = 0; + p1->x[4] = 0; + p1->x[5] = 0; + p1->x[6] = 0; + p1->x[7] = 0; + p1->x[8] = 0; + p1->x[9] = 0; + p1->x[10] = 0; + p1->x[11] = 0; + XMEMCPY(p1->z, p384_norm_mod, sizeof(p384_norm_mod)); + } + } +} + +/* Calculate the verification point: [e/s]G + [r/s]Q + * + * p1 Calculated point. + * p2 Public point and temporary. + * s Second part of signature as a number. + * u1 Temporary number. + * u2 Temproray number. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_calc_vfy_point_12(sp_point_384* p1, sp_point_384* p2, + sp_digit* s, sp_digit* u1, sp_digit* u2, sp_digit* tmp, void* heap) +{ + int err; + +#ifndef WOLFSSL_SP_SMALL + { + sp_384_mod_inv_12(s, s, p384_order); + } +#endif /* !WOLFSSL_SP_SMALL */ + { + sp_384_mul_12(s, s, p384_norm_order); + } + err = sp_384_mod_12(s, s, p384_order); + if (err == MP_OKAY) { + sp_384_norm_12(s); +#ifdef WOLFSSL_SP_SMALL + { + sp_384_mont_inv_order_12(s, s, tmp); + sp_384_mont_mul_order_12(u1, u1, s); + sp_384_mont_mul_order_12(u2, u2, s); + } + +#else + { + sp_384_mont_mul_order_12(u1, u1, s); + sp_384_mont_mul_order_12(u2, u2, s); + } + +#endif /* WOLFSSL_SP_SMALL */ + err = sp_384_ecc_mulmod_base_12(p1, u1, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_384_iszero_12(p1->z)) { + p1->infinity = 1; + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_12(p2, p2, u2, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_384_iszero_12(p2->z)) { + p2->infinity = 1; + } + + if (err == MP_OKAY) { + sp_384_add_points_12(p1, p2, tmp); + } + + return err; +} + #ifdef HAVE_ECC_VERIFY /* Verify the signature values with the hash and public key. * e = Truncate(hash, 384) @@ -46353,8 +46519,7 @@ static int sp_384_mod_inv_12(sp_digit* r, const sp_digit* a, const sp_digit* m) * rm First part of result as an mp_int. * sm Sirst part of result as an mp_int. * heap Heap to use for allocation. - * returns RNG failures, MEMORY_E when memory allocation fails and - * MP_OKAY on success. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ #ifdef WOLFSSL_SP_NONBLOCK typedef struct sp_ecc_verify_384_ctx { @@ -46373,8 +46538,9 @@ typedef struct sp_ecc_verify_384_ctx { sp_point_384 p2; } sp_ecc_verify_384_ctx; -int sp_ecc_verify_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, + word32 hashLen, const mp_int* pX, const mp_int* pY, const mp_int* pZ, + const mp_int* r, const mp_int* sm, int* res, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_verify_384_ctx* ctx = (sp_ecc_verify_384_ctx*)sp_ctx->data; @@ -46528,8 +46694,9 @@ int sp_ecc_verify_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_384(const byte* hash, word32 hashLen, const mp_int* pX, + const mp_int* pY, const mp_int* pZ, const mp_int* r, const mp_int* sm, + int* res, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -46548,7 +46715,7 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, sp_point_384* p1; sp_point_384* p2 = NULL; sp_digit carry; - int32_t c; + int32_t c = 0; int err; err = sp_384_point_new_12(heap, p1d, p1); @@ -46589,70 +46756,9 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, sp_384_from_mp(p2->y, 12, pY); sp_384_from_mp(p2->z, 12, pZ); -#ifndef WOLFSSL_SP_SMALL - { - sp_384_mod_inv_12(s, s, p384_order); - } -#endif /* !WOLFSSL_SP_SMALL */ - { - sp_384_mul_12(s, s, p384_norm_order); - } - err = sp_384_mod_12(s, s, p384_order); + err = sp_384_calc_vfy_point_12(p1, p2, s, u1, u2, tmp, heap); } if (err == MP_OKAY) { - sp_384_norm_12(s); -#ifdef WOLFSSL_SP_SMALL - { - sp_384_mont_inv_order_12(s, s, tmp); - sp_384_mont_mul_order_12(u1, u1, s); - sp_384_mont_mul_order_12(u2, u2, s); - } - -#else - { - sp_384_mont_mul_order_12(u1, u1, s); - sp_384_mont_mul_order_12(u2, u2, s); - } - -#endif /* WOLFSSL_SP_SMALL */ - err = sp_384_ecc_mulmod_base_12(p1, u1, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_384_iszero_12(p1->z)) { - p1->infinity = 1; - } - if (err == MP_OKAY) { - err = sp_384_ecc_mulmod_12(p2, p2, u2, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_384_iszero_12(p2->z)) { - p2->infinity = 1; - } - - if (err == MP_OKAY) { - { - sp_384_proj_point_add_12(p1, p1, p2, tmp); - if (sp_384_iszero_12(p1->z)) { - if (sp_384_iszero_12(p1->x) && sp_384_iszero_12(p1->y)) { - sp_384_proj_point_dbl_12(p1, p2, tmp); - } - else { - /* Y ordinate is not used from here - don't set. */ - p1->x[0] = 0; - p1->x[1] = 0; - p1->x[2] = 0; - p1->x[3] = 0; - p1->x[4] = 0; - p1->x[5] = 0; - p1->x[6] = 0; - p1->x[7] = 0; - p1->x[8] = 0; - p1->x[9] = 0; - p1->x[10] = 0; - p1->x[11] = 0; - XMEMCPY(p1->z, p384_norm_mod, sizeof(p384_norm_mod)); - } - } - } - /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */ /* Reload r and convert to Montgomery form. */ sp_384_from_mp(u2, 12, r); @@ -46674,16 +46780,16 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, /* Compare with mod and if greater or equal then not valid. */ c = sp_384_cmp_12(u2, p384_mod); - if (c < 0) { - /* Convert to Montogomery form */ - err = sp_384_mod_mul_norm_12(u2, u2, p384_mod); - if (err == MP_OKAY) { - /* u1 = (r + 1*order).z'.z' mod prime */ - sp_384_mont_mul_12(u1, u2, p1->z, p384_mod, - p384_mp_mod); - *res = (int)(sp_384_cmp_12(p1->x, u1) == 0); - } - } + } + } + if ((*res == 0) && (c < 0)) { + /* Convert to Montogomery form */ + err = sp_384_mod_mul_norm_12(u2, u2, p384_mod); + if (err == MP_OKAY) { + /* u1 = (r + 1*order).z'.z' mod prime */ + sp_384_mont_mul_12(u1, u2, p1->z, p384_mod, + p384_mp_mod); + *res = (sp_384_cmp_12(p1->x, u1) == 0); } } } @@ -46707,7 +46813,8 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -static int sp_384_ecc_is_point_12(sp_point_384* point, void* heap) +static int sp_384_ecc_is_point_12(const sp_point_384* point, + void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -46770,7 +46877,7 @@ static int sp_384_ecc_is_point_12(sp_point_384* point, void* heap) * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -int sp_ecc_is_point_384(mp_int* pX, mp_int* pY) +int sp_ecc_is_point_384(const mp_int* pX, const mp_int* pY) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_384 pubd; @@ -46804,7 +46911,8 @@ int sp_ecc_is_point_384(mp_int* pX, mp_int* pY) * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and * MP_OKAY otherwise. */ -int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) +int sp_ecc_check_key_384(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit privd[12]; @@ -46858,12 +46966,11 @@ int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) } } - if (err == MP_OKAY) { - /* Check range of X and Y */ - if (sp_384_cmp_12(pub->x, p384_mod) >= 0 || - sp_384_cmp_12(pub->y, p384_mod) >= 0) { - err = ECC_OUT_OF_RANGE_E; - } + /* Check range of X and Y */ + if ((err == MP_OKAY) && + ((sp_384_cmp_12(pub->x, p384_mod) >= 0) || + (sp_384_cmp_12(pub->y, p384_mod) >= 0))) { + err = ECC_OUT_OF_RANGE_E; } if (err == MP_OKAY) { @@ -46875,12 +46982,10 @@ int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Point * order = infinity */ err = sp_384_ecc_mulmod_12(p, pub, p384_order, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is infinity */ - if ((sp_384_iszero_12(p->x) == 0) || - (sp_384_iszero_12(p->y) == 0)) { - err = ECC_INF_E; - } + /* Check result is infinity */ + if ((err == MP_OKAY) && ((sp_384_iszero_12(p->x) == 0) || + (sp_384_iszero_12(p->y) == 0))) { + err = ECC_INF_E; } if (privm) { @@ -46888,12 +46993,11 @@ int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Base * private = point */ err = sp_384_ecc_mulmod_base_12(p, priv, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is public key */ - if (sp_384_cmp_12(p->x, pub->x) != 0 || - sp_384_cmp_12(p->y, pub->y) != 0) { - err = ECC_PRIV_KEY_E; - } + /* Check result is public key */ + if ((err == MP_OKAY) && + ((sp_384_cmp_12(p->x, pub->x) != 0) || + (sp_384_cmp_12(p->y, pub->y) != 0))) { + err = ECC_PRIV_KEY_E; } } @@ -47083,7 +47187,7 @@ int sp_ecc_map_384(mp_int* pX, mp_int* pY, mp_int* pZ) sp_384_from_mp(p->y, 12, pY); sp_384_from_mp(p->z, 12, pZ); - sp_384_map_12(p, p, tmp); + sp_384_map_12(p, p, tmp); } if (err == MP_OKAY) { @@ -47296,6 +47400,15869 @@ int sp_ecc_uncompress_384(mp_int* xm, int odd, mp_int* ym) } #endif #endif /* WOLFSSL_SP_384 */ +#ifdef WOLFSSL_SP_1024 + +/* Point structure to use. */ +typedef struct sp_point_1024 { + /* X ordinate of point. */ + sp_digit x[2 * 32]; + /* Y ordinate of point. */ + sp_digit y[2 * 32]; + /* Z ordinate of point. */ + sp_digit z[2 * 32]; + /* Indicates point is at infinity. */ + int infinity; +} sp_point_1024; + +#ifndef WOLFSSL_SP_SMALL +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static void sp_1024_mul_16(sp_digit* r, const sp_digit* a, const sp_digit* b) +{ + __asm__ __volatile__ ( + "sub sp, sp, #64\n\t" + "mov r10, #0\n\t" + "# A[0] * B[0]\n\t" + "ldr r11, [%[a], #0]\n\t" + "ldr r12, [%[b], #0]\n\t" + "umull r3, r4, r11, r12\n\t" + "mov r5, #0\n\t" + "str r3, [sp]\n\t" + "# A[0] * B[1]\n\t" + "ldr r9, [%[b], #4]\n\t" + "umull r6, r7, r11, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "# A[1] * B[0]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "str r4, [sp, #4]\n\t" + "# A[2] * B[0]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "# A[1] * B[1]\n\t" + "ldr r11, [%[a], #4]\n\t" + "ldr r12, [%[b], #4]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[0] * B[2]\n\t" + "ldr r8, [%[a], #0]\n\t" + "ldr r9, [%[b], #8]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "str r5, [sp, #8]\n\t" + "# A[0] * B[3]\n\t" + "ldr r9, [%[b], #12]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "# A[1] * B[2]\n\t" + "ldr r9, [%[b], #8]\n\t" + "umull r6, r7, r11, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[2] * B[1]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[3] * B[0]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #0]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "str r3, [sp, #12]\n\t" + "# A[4] * B[0]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "# A[3] * B[1]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[2] * B[2]\n\t" + "ldr r11, [%[a], #8]\n\t" + "ldr r12, [%[b], #8]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[1] * B[3]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #12]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[0] * B[4]\n\t" + "ldr r8, [%[a], #0]\n\t" + "ldr r9, [%[b], #16]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "str r4, [sp, #16]\n\t" + "# A[0] * B[5]\n\t" + "ldr r9, [%[b], #20]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "# A[1] * B[4]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #16]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[2] * B[3]\n\t" + "ldr r9, [%[b], #12]\n\t" + "umull r6, r7, r11, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[3] * B[2]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[4] * B[1]\n\t" + "ldr r8, [%[a], #16]\n\t" + "ldr r9, [%[b], #4]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[5] * B[0]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #0]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "str r5, [sp, #20]\n\t" + "# A[6] * B[0]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "# A[5] * B[1]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #4]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[4] * B[2]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[3] * B[3]\n\t" + "ldr r11, [%[a], #12]\n\t" + "ldr r12, [%[b], #12]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[2] * B[4]\n\t" + "ldr r8, [%[a], #8]\n\t" + "ldr r9, [%[b], #16]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[1] * B[5]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #20]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[0] * B[6]\n\t" + "ldr r8, [%[a], #0]\n\t" + "ldr r9, [%[b], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "str r3, [sp, #24]\n\t" + "# A[0] * B[7]\n\t" + "ldr r9, [%[b], #28]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "# A[1] * B[6]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[2] * B[5]\n\t" + "ldr r8, [%[a], #8]\n\t" + "ldr r9, [%[b], #20]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[3] * B[4]\n\t" + "ldr r9, [%[b], #16]\n\t" + "umull r6, r7, r11, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[4] * B[3]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[5] * B[2]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #8]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[6] * B[1]\n\t" + "ldr r8, [%[a], #24]\n\t" + "ldr r9, [%[b], #4]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[7] * B[0]\n\t" + "ldr r8, [%[a], #28]\n\t" + "ldr r9, [%[b], #0]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "str r4, [sp, #28]\n\t" + "# A[8] * B[0]\n\t" + "ldr r8, [%[a], #32]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "# A[7] * B[1]\n\t" + "ldr r8, [%[a], #28]\n\t" + "ldr r9, [%[b], #4]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[6] * B[2]\n\t" + "ldr r8, [%[a], #24]\n\t" + "ldr r9, [%[b], #8]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[5] * B[3]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[4] * B[4]\n\t" + "ldr r11, [%[a], #16]\n\t" + "ldr r12, [%[b], #16]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[3] * B[5]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #20]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[2] * B[6]\n\t" + "ldr r8, [%[a], #8]\n\t" + "ldr r9, [%[b], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[1] * B[7]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #28]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[0] * B[8]\n\t" + "ldr r8, [%[a], #0]\n\t" + "ldr r9, [%[b], #32]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "str r5, [sp, #32]\n\t" + "# A[0] * B[9]\n\t" + "ldr r9, [%[b], #36]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "# A[1] * B[8]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #32]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[2] * B[7]\n\t" + "ldr r8, [%[a], #8]\n\t" + "ldr r9, [%[b], #28]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[3] * B[6]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[4] * B[5]\n\t" + "ldr r9, [%[b], #20]\n\t" + "umull r6, r7, r11, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[5] * B[4]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[6] * B[3]\n\t" + "ldr r8, [%[a], #24]\n\t" + "ldr r9, [%[b], #12]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[7] * B[2]\n\t" + "ldr r8, [%[a], #28]\n\t" + "ldr r9, [%[b], #8]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[8] * B[1]\n\t" + "ldr r8, [%[a], #32]\n\t" + "ldr r9, [%[b], #4]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[9] * B[0]\n\t" + "ldr r8, [%[a], #36]\n\t" + "ldr r9, [%[b], #0]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "str r3, [sp, #36]\n\t" + "# A[10] * B[0]\n\t" + "ldr r8, [%[a], #40]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "# A[9] * B[1]\n\t" + "ldr r8, [%[a], #36]\n\t" + "ldr r9, [%[b], #4]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[8] * B[2]\n\t" + "ldr r8, [%[a], #32]\n\t" + "ldr r9, [%[b], #8]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[7] * B[3]\n\t" + "ldr r8, [%[a], #28]\n\t" + "ldr r9, [%[b], #12]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[6] * B[4]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[5] * B[5]\n\t" + "ldr r11, [%[a], #20]\n\t" + "ldr r12, [%[b], #20]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[4] * B[6]\n\t" + "ldr r8, [%[a], #16]\n\t" + "ldr r9, [%[b], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[3] * B[7]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #28]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[2] * B[8]\n\t" + "ldr r8, [%[a], #8]\n\t" + "ldr r9, [%[b], #32]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[1] * B[9]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #36]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[0] * B[10]\n\t" + "ldr r8, [%[a], #0]\n\t" + "ldr r9, [%[b], #40]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "str r4, [sp, #40]\n\t" + "# A[0] * B[11]\n\t" + "ldr r9, [%[b], #44]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "# A[1] * B[10]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #40]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[2] * B[9]\n\t" + "ldr r8, [%[a], #8]\n\t" + "ldr r9, [%[b], #36]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[3] * B[8]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #32]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[4] * B[7]\n\t" + "ldr r8, [%[a], #16]\n\t" + "ldr r9, [%[b], #28]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[5] * B[6]\n\t" + "ldr r9, [%[b], #24]\n\t" + "umull r6, r7, r11, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[6] * B[5]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[7] * B[4]\n\t" + "ldr r8, [%[a], #28]\n\t" + "ldr r9, [%[b], #16]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[8] * B[3]\n\t" + "ldr r8, [%[a], #32]\n\t" + "ldr r9, [%[b], #12]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[9] * B[2]\n\t" + "ldr r8, [%[a], #36]\n\t" + "ldr r9, [%[b], #8]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[10] * B[1]\n\t" + "ldr r8, [%[a], #40]\n\t" + "ldr r9, [%[b], #4]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[11] * B[0]\n\t" + "ldr r8, [%[a], #44]\n\t" + "ldr r9, [%[b], #0]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "str r5, [sp, #44]\n\t" + "# A[12] * B[0]\n\t" + "ldr r8, [%[a], #48]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "# A[11] * B[1]\n\t" + "ldr r8, [%[a], #44]\n\t" + "ldr r9, [%[b], #4]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[10] * B[2]\n\t" + "ldr r8, [%[a], #40]\n\t" + "ldr r9, [%[b], #8]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[9] * B[3]\n\t" + "ldr r8, [%[a], #36]\n\t" + "ldr r9, [%[b], #12]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[8] * B[4]\n\t" + "ldr r8, [%[a], #32]\n\t" + "ldr r9, [%[b], #16]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[7] * B[5]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[6] * B[6]\n\t" + "ldr r11, [%[a], #24]\n\t" + "ldr r12, [%[b], #24]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[5] * B[7]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #28]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[4] * B[8]\n\t" + "ldr r8, [%[a], #16]\n\t" + "ldr r9, [%[b], #32]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[3] * B[9]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #36]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[2] * B[10]\n\t" + "ldr r8, [%[a], #8]\n\t" + "ldr r9, [%[b], #40]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[1] * B[11]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #44]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[0] * B[12]\n\t" + "ldr r8, [%[a], #0]\n\t" + "ldr r9, [%[b], #48]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "str r3, [sp, #48]\n\t" + "# A[0] * B[13]\n\t" + "ldr r9, [%[b], #52]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "# A[1] * B[12]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #48]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[2] * B[11]\n\t" + "ldr r8, [%[a], #8]\n\t" + "ldr r9, [%[b], #44]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[3] * B[10]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #40]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[4] * B[9]\n\t" + "ldr r8, [%[a], #16]\n\t" + "ldr r9, [%[b], #36]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[5] * B[8]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #32]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[6] * B[7]\n\t" + "ldr r9, [%[b], #28]\n\t" + "umull r6, r7, r11, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[7] * B[6]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[8] * B[5]\n\t" + "ldr r8, [%[a], #32]\n\t" + "ldr r9, [%[b], #20]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[9] * B[4]\n\t" + "ldr r8, [%[a], #36]\n\t" + "ldr r9, [%[b], #16]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[10] * B[3]\n\t" + "ldr r8, [%[a], #40]\n\t" + "ldr r9, [%[b], #12]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[11] * B[2]\n\t" + "ldr r8, [%[a], #44]\n\t" + "ldr r9, [%[b], #8]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[12] * B[1]\n\t" + "ldr r8, [%[a], #48]\n\t" + "ldr r9, [%[b], #4]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[13] * B[0]\n\t" + "ldr r8, [%[a], #52]\n\t" + "ldr r9, [%[b], #0]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "str r4, [sp, #52]\n\t" + "# A[14] * B[0]\n\t" + "ldr r8, [%[a], #56]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "# A[13] * B[1]\n\t" + "ldr r8, [%[a], #52]\n\t" + "ldr r9, [%[b], #4]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[12] * B[2]\n\t" + "ldr r8, [%[a], #48]\n\t" + "ldr r9, [%[b], #8]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[11] * B[3]\n\t" + "ldr r8, [%[a], #44]\n\t" + "ldr r9, [%[b], #12]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[10] * B[4]\n\t" + "ldr r8, [%[a], #40]\n\t" + "ldr r9, [%[b], #16]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[9] * B[5]\n\t" + "ldr r8, [%[a], #36]\n\t" + "ldr r9, [%[b], #20]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[8] * B[6]\n\t" + "ldr r8, [%[a], #32]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[7] * B[7]\n\t" + "ldr r11, [%[a], #28]\n\t" + "ldr r12, [%[b], #28]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[6] * B[8]\n\t" + "ldr r8, [%[a], #24]\n\t" + "ldr r9, [%[b], #32]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[5] * B[9]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #36]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[4] * B[10]\n\t" + "ldr r8, [%[a], #16]\n\t" + "ldr r9, [%[b], #40]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[3] * B[11]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #44]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[2] * B[12]\n\t" + "ldr r8, [%[a], #8]\n\t" + "ldr r9, [%[b], #48]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[1] * B[13]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #52]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[0] * B[14]\n\t" + "ldr r8, [%[a], #0]\n\t" + "ldr r9, [%[b], #56]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "str r5, [sp, #56]\n\t" + "# A[0] * B[15]\n\t" + "ldr r9, [%[b], #60]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "# A[1] * B[14]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #56]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[2] * B[13]\n\t" + "ldr r8, [%[a], #8]\n\t" + "ldr r9, [%[b], #52]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[3] * B[12]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #48]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[4] * B[11]\n\t" + "ldr r8, [%[a], #16]\n\t" + "ldr r9, [%[b], #44]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[5] * B[10]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #40]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[6] * B[9]\n\t" + "ldr r8, [%[a], #24]\n\t" + "ldr r9, [%[b], #36]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[7] * B[8]\n\t" + "ldr r9, [%[b], #32]\n\t" + "umull r6, r7, r11, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[8] * B[7]\n\t" + "ldr r8, [%[a], #32]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[9] * B[6]\n\t" + "ldr r8, [%[a], #36]\n\t" + "ldr r9, [%[b], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[10] * B[5]\n\t" + "ldr r8, [%[a], #40]\n\t" + "ldr r9, [%[b], #20]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[11] * B[4]\n\t" + "ldr r8, [%[a], #44]\n\t" + "ldr r9, [%[b], #16]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[12] * B[3]\n\t" + "ldr r8, [%[a], #48]\n\t" + "ldr r9, [%[b], #12]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[13] * B[2]\n\t" + "ldr r8, [%[a], #52]\n\t" + "ldr r9, [%[b], #8]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[14] * B[1]\n\t" + "ldr r8, [%[a], #56]\n\t" + "ldr r9, [%[b], #4]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[15] * B[0]\n\t" + "ldr r8, [%[a], #60]\n\t" + "ldr r9, [%[b], #0]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "str r3, [sp, #60]\n\t" + "# A[15] * B[1]\n\t" + "ldr r9, [%[b], #4]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "# A[14] * B[2]\n\t" + "ldr r8, [%[a], #56]\n\t" + "ldr r9, [%[b], #8]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[13] * B[3]\n\t" + "ldr r8, [%[a], #52]\n\t" + "ldr r9, [%[b], #12]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[12] * B[4]\n\t" + "ldr r8, [%[a], #48]\n\t" + "ldr r9, [%[b], #16]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[11] * B[5]\n\t" + "ldr r8, [%[a], #44]\n\t" + "ldr r9, [%[b], #20]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[10] * B[6]\n\t" + "ldr r8, [%[a], #40]\n\t" + "ldr r9, [%[b], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[9] * B[7]\n\t" + "ldr r8, [%[a], #36]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[8] * B[8]\n\t" + "ldr r11, [%[a], #32]\n\t" + "ldr r12, [%[b], #32]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[7] * B[9]\n\t" + "ldr r8, [%[a], #28]\n\t" + "ldr r9, [%[b], #36]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[6] * B[10]\n\t" + "ldr r8, [%[a], #24]\n\t" + "ldr r9, [%[b], #40]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[5] * B[11]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #44]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[4] * B[12]\n\t" + "ldr r8, [%[a], #16]\n\t" + "ldr r9, [%[b], #48]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[3] * B[13]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #52]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[2] * B[14]\n\t" + "ldr r8, [%[a], #8]\n\t" + "ldr r9, [%[b], #56]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[1] * B[15]\n\t" + "ldr r8, [%[a], #4]\n\t" + "ldr r9, [%[b], #60]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "str r4, [%[r], #64]\n\t" + "# A[2] * B[15]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "# A[3] * B[14]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #56]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[4] * B[13]\n\t" + "ldr r8, [%[a], #16]\n\t" + "ldr r9, [%[b], #52]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[5] * B[12]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #48]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[6] * B[11]\n\t" + "ldr r8, [%[a], #24]\n\t" + "ldr r9, [%[b], #44]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[7] * B[10]\n\t" + "ldr r8, [%[a], #28]\n\t" + "ldr r9, [%[b], #40]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[8] * B[9]\n\t" + "ldr r9, [%[b], #36]\n\t" + "umull r6, r7, r11, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[9] * B[8]\n\t" + "ldr r8, [%[a], #36]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[10] * B[7]\n\t" + "ldr r8, [%[a], #40]\n\t" + "ldr r9, [%[b], #28]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[11] * B[6]\n\t" + "ldr r8, [%[a], #44]\n\t" + "ldr r9, [%[b], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[12] * B[5]\n\t" + "ldr r8, [%[a], #48]\n\t" + "ldr r9, [%[b], #20]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[13] * B[4]\n\t" + "ldr r8, [%[a], #52]\n\t" + "ldr r9, [%[b], #16]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[14] * B[3]\n\t" + "ldr r8, [%[a], #56]\n\t" + "ldr r9, [%[b], #12]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[15] * B[2]\n\t" + "ldr r8, [%[a], #60]\n\t" + "ldr r9, [%[b], #8]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "str r5, [%[r], #68]\n\t" + "# A[15] * B[3]\n\t" + "ldr r9, [%[b], #12]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "# A[14] * B[4]\n\t" + "ldr r8, [%[a], #56]\n\t" + "ldr r9, [%[b], #16]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[13] * B[5]\n\t" + "ldr r8, [%[a], #52]\n\t" + "ldr r9, [%[b], #20]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[12] * B[6]\n\t" + "ldr r8, [%[a], #48]\n\t" + "ldr r9, [%[b], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[11] * B[7]\n\t" + "ldr r8, [%[a], #44]\n\t" + "ldr r9, [%[b], #28]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[10] * B[8]\n\t" + "ldr r8, [%[a], #40]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[9] * B[9]\n\t" + "ldr r11, [%[a], #36]\n\t" + "ldr r12, [%[b], #36]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[8] * B[10]\n\t" + "ldr r8, [%[a], #32]\n\t" + "ldr r9, [%[b], #40]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[7] * B[11]\n\t" + "ldr r8, [%[a], #28]\n\t" + "ldr r9, [%[b], #44]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[6] * B[12]\n\t" + "ldr r8, [%[a], #24]\n\t" + "ldr r9, [%[b], #48]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[5] * B[13]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #52]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[4] * B[14]\n\t" + "ldr r8, [%[a], #16]\n\t" + "ldr r9, [%[b], #56]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[3] * B[15]\n\t" + "ldr r8, [%[a], #12]\n\t" + "ldr r9, [%[b], #60]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "str r3, [%[r], #72]\n\t" + "# A[4] * B[15]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "# A[5] * B[14]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #56]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[6] * B[13]\n\t" + "ldr r8, [%[a], #24]\n\t" + "ldr r9, [%[b], #52]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[7] * B[12]\n\t" + "ldr r8, [%[a], #28]\n\t" + "ldr r9, [%[b], #48]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[8] * B[11]\n\t" + "ldr r8, [%[a], #32]\n\t" + "ldr r9, [%[b], #44]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[9] * B[10]\n\t" + "ldr r9, [%[b], #40]\n\t" + "umull r6, r7, r11, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[10] * B[9]\n\t" + "ldr r8, [%[a], #40]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[11] * B[8]\n\t" + "ldr r8, [%[a], #44]\n\t" + "ldr r9, [%[b], #32]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[12] * B[7]\n\t" + "ldr r8, [%[a], #48]\n\t" + "ldr r9, [%[b], #28]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[13] * B[6]\n\t" + "ldr r8, [%[a], #52]\n\t" + "ldr r9, [%[b], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[14] * B[5]\n\t" + "ldr r8, [%[a], #56]\n\t" + "ldr r9, [%[b], #20]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[15] * B[4]\n\t" + "ldr r8, [%[a], #60]\n\t" + "ldr r9, [%[b], #16]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "str r4, [%[r], #76]\n\t" + "# A[15] * B[5]\n\t" + "ldr r9, [%[b], #20]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "# A[14] * B[6]\n\t" + "ldr r8, [%[a], #56]\n\t" + "ldr r9, [%[b], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[13] * B[7]\n\t" + "ldr r8, [%[a], #52]\n\t" + "ldr r9, [%[b], #28]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[12] * B[8]\n\t" + "ldr r8, [%[a], #48]\n\t" + "ldr r9, [%[b], #32]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[11] * B[9]\n\t" + "ldr r8, [%[a], #44]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[10] * B[10]\n\t" + "ldr r11, [%[a], #40]\n\t" + "ldr r12, [%[b], #40]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[9] * B[11]\n\t" + "ldr r8, [%[a], #36]\n\t" + "ldr r9, [%[b], #44]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[8] * B[12]\n\t" + "ldr r8, [%[a], #32]\n\t" + "ldr r9, [%[b], #48]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[7] * B[13]\n\t" + "ldr r8, [%[a], #28]\n\t" + "ldr r9, [%[b], #52]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[6] * B[14]\n\t" + "ldr r8, [%[a], #24]\n\t" + "ldr r9, [%[b], #56]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[5] * B[15]\n\t" + "ldr r8, [%[a], #20]\n\t" + "ldr r9, [%[b], #60]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "str r5, [%[r], #80]\n\t" + "# A[6] * B[15]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "# A[7] * B[14]\n\t" + "ldr r8, [%[a], #28]\n\t" + "ldr r9, [%[b], #56]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[8] * B[13]\n\t" + "ldr r8, [%[a], #32]\n\t" + "ldr r9, [%[b], #52]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[9] * B[12]\n\t" + "ldr r8, [%[a], #36]\n\t" + "ldr r9, [%[b], #48]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[10] * B[11]\n\t" + "ldr r9, [%[b], #44]\n\t" + "umull r6, r7, r11, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[11] * B[10]\n\t" + "ldr r8, [%[a], #44]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[12] * B[9]\n\t" + "ldr r8, [%[a], #48]\n\t" + "ldr r9, [%[b], #36]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[13] * B[8]\n\t" + "ldr r8, [%[a], #52]\n\t" + "ldr r9, [%[b], #32]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[14] * B[7]\n\t" + "ldr r8, [%[a], #56]\n\t" + "ldr r9, [%[b], #28]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[15] * B[6]\n\t" + "ldr r8, [%[a], #60]\n\t" + "ldr r9, [%[b], #24]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "str r3, [%[r], #84]\n\t" + "# A[15] * B[7]\n\t" + "ldr r9, [%[b], #28]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "# A[14] * B[8]\n\t" + "ldr r8, [%[a], #56]\n\t" + "ldr r9, [%[b], #32]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[13] * B[9]\n\t" + "ldr r8, [%[a], #52]\n\t" + "ldr r9, [%[b], #36]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[12] * B[10]\n\t" + "ldr r8, [%[a], #48]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[11] * B[11]\n\t" + "ldr r11, [%[a], #44]\n\t" + "ldr r12, [%[b], #44]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[10] * B[12]\n\t" + "ldr r8, [%[a], #40]\n\t" + "ldr r9, [%[b], #48]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[9] * B[13]\n\t" + "ldr r8, [%[a], #36]\n\t" + "ldr r9, [%[b], #52]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[8] * B[14]\n\t" + "ldr r8, [%[a], #32]\n\t" + "ldr r9, [%[b], #56]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[7] * B[15]\n\t" + "ldr r8, [%[a], #28]\n\t" + "ldr r9, [%[b], #60]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "str r4, [%[r], #88]\n\t" + "# A[8] * B[15]\n\t" + "ldr r8, [%[a], #32]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "# A[9] * B[14]\n\t" + "ldr r8, [%[a], #36]\n\t" + "ldr r9, [%[b], #56]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[10] * B[13]\n\t" + "ldr r8, [%[a], #40]\n\t" + "ldr r9, [%[b], #52]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[11] * B[12]\n\t" + "ldr r9, [%[b], #48]\n\t" + "umull r6, r7, r11, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[12] * B[11]\n\t" + "ldr r8, [%[a], #48]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[13] * B[10]\n\t" + "ldr r8, [%[a], #52]\n\t" + "ldr r9, [%[b], #40]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[14] * B[9]\n\t" + "ldr r8, [%[a], #56]\n\t" + "ldr r9, [%[b], #36]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[15] * B[8]\n\t" + "ldr r8, [%[a], #60]\n\t" + "ldr r9, [%[b], #32]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "str r5, [%[r], #92]\n\t" + "# A[15] * B[9]\n\t" + "ldr r9, [%[b], #36]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "# A[14] * B[10]\n\t" + "ldr r8, [%[a], #56]\n\t" + "ldr r9, [%[b], #40]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[13] * B[11]\n\t" + "ldr r8, [%[a], #52]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[12] * B[12]\n\t" + "ldr r11, [%[a], #48]\n\t" + "ldr r12, [%[b], #48]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[11] * B[13]\n\t" + "ldr r8, [%[a], #44]\n\t" + "ldr r9, [%[b], #52]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[10] * B[14]\n\t" + "ldr r8, [%[a], #40]\n\t" + "ldr r9, [%[b], #56]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[9] * B[15]\n\t" + "ldr r8, [%[a], #36]\n\t" + "ldr r9, [%[b], #60]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "str r3, [%[r], #96]\n\t" + "# A[10] * B[15]\n\t" + "ldr r8, [%[a], #40]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "# A[11] * B[14]\n\t" + "ldr r8, [%[a], #44]\n\t" + "ldr r9, [%[b], #56]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[12] * B[13]\n\t" + "ldr r9, [%[b], #52]\n\t" + "umull r6, r7, r11, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[13] * B[12]\n\t" + "ldr r8, [%[a], #52]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[14] * B[11]\n\t" + "ldr r8, [%[a], #56]\n\t" + "ldr r9, [%[b], #44]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[15] * B[10]\n\t" + "ldr r8, [%[a], #60]\n\t" + "ldr r9, [%[b], #40]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "str r4, [%[r], #100]\n\t" + "# A[15] * B[11]\n\t" + "ldr r9, [%[b], #44]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "# A[14] * B[12]\n\t" + "ldr r8, [%[a], #56]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[13] * B[13]\n\t" + "ldr r11, [%[a], #52]\n\t" + "ldr r12, [%[b], #52]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[12] * B[14]\n\t" + "ldr r8, [%[a], #48]\n\t" + "ldr r9, [%[b], #56]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "# A[11] * B[15]\n\t" + "ldr r8, [%[a], #44]\n\t" + "ldr r9, [%[b], #60]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "str r5, [%[r], #104]\n\t" + "# A[12] * B[15]\n\t" + "ldr r8, [%[a], #48]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "# A[13] * B[14]\n\t" + "ldr r9, [%[b], #56]\n\t" + "umull r6, r7, r11, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[14] * B[13]\n\t" + "ldr r8, [%[a], #56]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "# A[15] * B[12]\n\t" + "ldr r8, [%[a], #60]\n\t" + "ldr r9, [%[b], #48]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "str r3, [%[r], #108]\n\t" + "# A[15] * B[13]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "# A[14] * B[14]\n\t" + "ldr r11, [%[a], #56]\n\t" + "ldr r12, [%[b], #56]\n\t" + "umull r6, r7, r11, r12\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "# A[13] * B[15]\n\t" + "ldr r8, [%[a], #52]\n\t" + "ldr r9, [%[b], #60]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r3, r10\n\t" + "str r4, [%[r], #112]\n\t" + "# A[14] * B[15]\n\t" + "umull r6, r7, r11, r9\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "# A[15] * B[14]\n\t" + "ldr r8, [%[a], #60]\n\t" + "umull r6, r7, r8, r12\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r4, r10\n\t" + "str r5, [%[r], #116]\n\t" + "# A[15] * B[15]\n\t" + "umull r6, r7, r8, r9\n\t" + "adds r3, r3, r6\n\t" + "adc r4, r4, r7\n\t" + "str r3, [%[r], #120]\n\t" + "str r4, [%[r], #124]\n\t" + "ldm sp!, {r3, r4, r5, r6}\n\t" + "stm %[r]!, {r3, r4, r5, r6}\n\t" + "ldm sp!, {r3, r4, r5, r6}\n\t" + "stm %[r]!, {r3, r4, r5, r6}\n\t" + "ldm sp!, {r3, r4, r5, r6}\n\t" + "stm %[r]!, {r3, r4, r5, r6}\n\t" + "ldm sp!, {r3, r4, r5, r6}\n\t" + "stm %[r]!, {r3, r4, r5, r6}\n\t" + "sub %[r], %[r], #64\n\t" + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) + : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" + ); +} + +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +static void sp_1024_sqr_16(sp_digit* r, const sp_digit* a) +{ + __asm__ __volatile__ ( + "sub sp, sp, #64\n\t" + "mov r12, #0\n\t" + "# A[0] * A[0]\n\t" + "ldr r10, [%[a], #0]\n\t" + "umull r8, r3, r10, r10\n\t" + "mov r4, #0\n\t" + "str r8, [sp]\n\t" + "# A[0] * A[1]\n\t" + "ldr r10, [%[a], #4]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r12, r12\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "str r3, [sp, #4]\n\t" + "# A[0] * A[2]\n\t" + "ldr r10, [%[a], #8]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r4, r4, r8\n\t" + "adcs r2, r2, r9\n\t" + "adc r3, r12, r12\n\t" + "adds r4, r4, r8\n\t" + "adcs r2, r2, r9\n\t" + "adc r3, r3, r12\n\t" + "# A[1] * A[1]\n\t" + "ldr r10, [%[a], #4]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r4, r4, r8\n\t" + "adcs r2, r2, r9\n\t" + "adc r3, r3, r12\n\t" + "str r4, [sp, #8]\n\t" + "# A[0] * A[3]\n\t" + "ldr r10, [%[a], #12]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r12, r12\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r4, r12\n\t" + "# A[1] * A[2]\n\t" + "ldr r10, [%[a], #8]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r4, r12\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r4, r12\n\t" + "str r2, [sp, #12]\n\t" + "# A[0] * A[4]\n\t" + "ldr r10, [%[a], #16]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r12, r12\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "# A[1] * A[3]\n\t" + "ldr r10, [%[a], #12]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "# A[2] * A[2]\n\t" + "ldr r10, [%[a], #8]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "str r3, [sp, #16]\n\t" + "# A[0] * A[5]\n\t" + "ldr r10, [%[a], #20]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r3, #0\n\t" + "mov r7, #0\n\t" + "# A[1] * A[4]\n\t" + "ldr r10, [%[a], #16]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[2] * A[3]\n\t" + "ldr r10, [%[a], #12]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r4, r4, r5\n\t" + "adcs r2, r2, r6\n\t" + "adc r3, r3, r7\n\t" + "str r4, [sp, #20]\n\t" + "# A[0] * A[6]\n\t" + "ldr r10, [%[a], #24]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r4, #0\n\t" + "mov r7, #0\n\t" + "# A[1] * A[5]\n\t" + "ldr r10, [%[a], #20]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[2] * A[4]\n\t" + "ldr r10, [%[a], #16]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[3] * A[3]\n\t" + "ldr r10, [%[a], #12]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r2, r2, r5\n\t" + "adcs r3, r3, r6\n\t" + "adc r4, r4, r7\n\t" + "str r2, [sp, #24]\n\t" + "# A[0] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r2, #0\n\t" + "mov r7, #0\n\t" + "# A[1] * A[6]\n\t" + "ldr r10, [%[a], #24]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[2] * A[5]\n\t" + "ldr r10, [%[a], #20]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[3] * A[4]\n\t" + "ldr r10, [%[a], #16]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r3, r3, r5\n\t" + "adcs r4, r4, r6\n\t" + "adc r2, r2, r7\n\t" + "str r3, [sp, #28]\n\t" + "# A[0] * A[8]\n\t" + "ldr r10, [%[a], #32]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r3, #0\n\t" + "mov r7, #0\n\t" + "# A[1] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[2] * A[6]\n\t" + "ldr r10, [%[a], #24]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[3] * A[5]\n\t" + "ldr r10, [%[a], #20]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[4] * A[4]\n\t" + "ldr r10, [%[a], #16]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r4, r4, r5\n\t" + "adcs r2, r2, r6\n\t" + "adc r3, r3, r7\n\t" + "str r4, [sp, #32]\n\t" + "# A[0] * A[9]\n\t" + "ldr r10, [%[a], #36]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r4, #0\n\t" + "mov r7, #0\n\t" + "# A[1] * A[8]\n\t" + "ldr r10, [%[a], #32]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[2] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[3] * A[6]\n\t" + "ldr r10, [%[a], #24]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[4] * A[5]\n\t" + "ldr r10, [%[a], #20]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r2, r2, r5\n\t" + "adcs r3, r3, r6\n\t" + "adc r4, r4, r7\n\t" + "str r2, [sp, #36]\n\t" + "# A[0] * A[10]\n\t" + "ldr r10, [%[a], #40]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r2, #0\n\t" + "mov r7, #0\n\t" + "# A[1] * A[9]\n\t" + "ldr r10, [%[a], #36]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[2] * A[8]\n\t" + "ldr r10, [%[a], #32]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[3] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[4] * A[6]\n\t" + "ldr r10, [%[a], #24]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[5] * A[5]\n\t" + "ldr r10, [%[a], #20]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r3, r3, r5\n\t" + "adcs r4, r4, r6\n\t" + "adc r2, r2, r7\n\t" + "str r3, [sp, #40]\n\t" + "# A[0] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r3, #0\n\t" + "mov r7, #0\n\t" + "# A[1] * A[10]\n\t" + "ldr r10, [%[a], #40]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[2] * A[9]\n\t" + "ldr r10, [%[a], #36]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[3] * A[8]\n\t" + "ldr r10, [%[a], #32]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[4] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[5] * A[6]\n\t" + "ldr r10, [%[a], #24]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r4, r4, r5\n\t" + "adcs r2, r2, r6\n\t" + "adc r3, r3, r7\n\t" + "str r4, [sp, #44]\n\t" + "# A[0] * A[12]\n\t" + "ldr r10, [%[a], #48]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r4, #0\n\t" + "mov r7, #0\n\t" + "# A[1] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[2] * A[10]\n\t" + "ldr r10, [%[a], #40]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[3] * A[9]\n\t" + "ldr r10, [%[a], #36]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[4] * A[8]\n\t" + "ldr r10, [%[a], #32]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[5] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[6] * A[6]\n\t" + "ldr r10, [%[a], #24]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r2, r2, r5\n\t" + "adcs r3, r3, r6\n\t" + "adc r4, r4, r7\n\t" + "str r2, [sp, #48]\n\t" + "# A[0] * A[13]\n\t" + "ldr r10, [%[a], #52]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r2, #0\n\t" + "mov r7, #0\n\t" + "# A[1] * A[12]\n\t" + "ldr r10, [%[a], #48]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[2] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[3] * A[10]\n\t" + "ldr r10, [%[a], #40]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[4] * A[9]\n\t" + "ldr r10, [%[a], #36]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[5] * A[8]\n\t" + "ldr r10, [%[a], #32]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[6] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r3, r3, r5\n\t" + "adcs r4, r4, r6\n\t" + "adc r2, r2, r7\n\t" + "str r3, [sp, #52]\n\t" + "# A[0] * A[14]\n\t" + "ldr r10, [%[a], #56]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r3, #0\n\t" + "mov r7, #0\n\t" + "# A[1] * A[13]\n\t" + "ldr r10, [%[a], #52]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[2] * A[12]\n\t" + "ldr r10, [%[a], #48]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[3] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[4] * A[10]\n\t" + "ldr r10, [%[a], #40]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[5] * A[9]\n\t" + "ldr r10, [%[a], #36]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[6] * A[8]\n\t" + "ldr r10, [%[a], #32]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[7] * A[7]\n\t" + "ldr r10, [%[a], #28]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r4, r4, r5\n\t" + "adcs r2, r2, r6\n\t" + "adc r3, r3, r7\n\t" + "str r4, [sp, #56]\n\t" + "# A[0] * A[15]\n\t" + "ldr r10, [%[a], #60]\n\t" + "ldr r8, [%[a], #0]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r4, #0\n\t" + "mov r7, #0\n\t" + "# A[1] * A[14]\n\t" + "ldr r10, [%[a], #56]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[2] * A[13]\n\t" + "ldr r10, [%[a], #52]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[3] * A[12]\n\t" + "ldr r10, [%[a], #48]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[4] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[5] * A[10]\n\t" + "ldr r10, [%[a], #40]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[6] * A[9]\n\t" + "ldr r10, [%[a], #36]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[7] * A[8]\n\t" + "ldr r10, [%[a], #32]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r2, r2, r5\n\t" + "adcs r3, r3, r6\n\t" + "adc r4, r4, r7\n\t" + "str r2, [sp, #60]\n\t" + "# A[1] * A[15]\n\t" + "ldr r10, [%[a], #60]\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r2, #0\n\t" + "mov r7, #0\n\t" + "# A[2] * A[14]\n\t" + "ldr r10, [%[a], #56]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[3] * A[13]\n\t" + "ldr r10, [%[a], #52]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[4] * A[12]\n\t" + "ldr r10, [%[a], #48]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[5] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[6] * A[10]\n\t" + "ldr r10, [%[a], #40]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[7] * A[9]\n\t" + "ldr r10, [%[a], #36]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[8] * A[8]\n\t" + "ldr r10, [%[a], #32]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r3, r3, r5\n\t" + "adcs r4, r4, r6\n\t" + "adc r2, r2, r7\n\t" + "str r3, [%[r], #64]\n\t" + "# A[2] * A[15]\n\t" + "ldr r10, [%[a], #60]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r3, #0\n\t" + "mov r7, #0\n\t" + "# A[3] * A[14]\n\t" + "ldr r10, [%[a], #56]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[4] * A[13]\n\t" + "ldr r10, [%[a], #52]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[5] * A[12]\n\t" + "ldr r10, [%[a], #48]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[6] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[7] * A[10]\n\t" + "ldr r10, [%[a], #40]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[8] * A[9]\n\t" + "ldr r10, [%[a], #36]\n\t" + "ldr r8, [%[a], #32]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r4, r4, r5\n\t" + "adcs r2, r2, r6\n\t" + "adc r3, r3, r7\n\t" + "str r4, [%[r], #68]\n\t" + "# A[3] * A[15]\n\t" + "ldr r10, [%[a], #60]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r4, #0\n\t" + "mov r7, #0\n\t" + "# A[4] * A[14]\n\t" + "ldr r10, [%[a], #56]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[5] * A[13]\n\t" + "ldr r10, [%[a], #52]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[6] * A[12]\n\t" + "ldr r10, [%[a], #48]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[7] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[8] * A[10]\n\t" + "ldr r10, [%[a], #40]\n\t" + "ldr r8, [%[a], #32]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[9] * A[9]\n\t" + "ldr r10, [%[a], #36]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r2, r2, r5\n\t" + "adcs r3, r3, r6\n\t" + "adc r4, r4, r7\n\t" + "str r2, [%[r], #72]\n\t" + "# A[4] * A[15]\n\t" + "ldr r10, [%[a], #60]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r2, #0\n\t" + "mov r7, #0\n\t" + "# A[5] * A[14]\n\t" + "ldr r10, [%[a], #56]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[6] * A[13]\n\t" + "ldr r10, [%[a], #52]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[7] * A[12]\n\t" + "ldr r10, [%[a], #48]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[8] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "ldr r8, [%[a], #32]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[9] * A[10]\n\t" + "ldr r10, [%[a], #40]\n\t" + "ldr r8, [%[a], #36]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r3, r3, r5\n\t" + "adcs r4, r4, r6\n\t" + "adc r2, r2, r7\n\t" + "str r3, [%[r], #76]\n\t" + "# A[5] * A[15]\n\t" + "ldr r10, [%[a], #60]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r3, #0\n\t" + "mov r7, #0\n\t" + "# A[6] * A[14]\n\t" + "ldr r10, [%[a], #56]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[7] * A[13]\n\t" + "ldr r10, [%[a], #52]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[8] * A[12]\n\t" + "ldr r10, [%[a], #48]\n\t" + "ldr r8, [%[a], #32]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[9] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "ldr r8, [%[a], #36]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[10] * A[10]\n\t" + "ldr r10, [%[a], #40]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r4, r4, r5\n\t" + "adcs r2, r2, r6\n\t" + "adc r3, r3, r7\n\t" + "str r4, [%[r], #80]\n\t" + "# A[6] * A[15]\n\t" + "ldr r10, [%[a], #60]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r4, #0\n\t" + "mov r7, #0\n\t" + "# A[7] * A[14]\n\t" + "ldr r10, [%[a], #56]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[8] * A[13]\n\t" + "ldr r10, [%[a], #52]\n\t" + "ldr r8, [%[a], #32]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[9] * A[12]\n\t" + "ldr r10, [%[a], #48]\n\t" + "ldr r8, [%[a], #36]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[10] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "ldr r8, [%[a], #40]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r2, r2, r5\n\t" + "adcs r3, r3, r6\n\t" + "adc r4, r4, r7\n\t" + "str r2, [%[r], #84]\n\t" + "# A[7] * A[15]\n\t" + "ldr r10, [%[a], #60]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r2, #0\n\t" + "mov r7, #0\n\t" + "# A[8] * A[14]\n\t" + "ldr r10, [%[a], #56]\n\t" + "ldr r8, [%[a], #32]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[9] * A[13]\n\t" + "ldr r10, [%[a], #52]\n\t" + "ldr r8, [%[a], #36]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[10] * A[12]\n\t" + "ldr r10, [%[a], #48]\n\t" + "ldr r8, [%[a], #40]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[11] * A[11]\n\t" + "ldr r10, [%[a], #44]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r3, r3, r5\n\t" + "adcs r4, r4, r6\n\t" + "adc r2, r2, r7\n\t" + "str r3, [%[r], #88]\n\t" + "# A[8] * A[15]\n\t" + "ldr r10, [%[a], #60]\n\t" + "ldr r8, [%[a], #32]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r3, #0\n\t" + "mov r7, #0\n\t" + "# A[9] * A[14]\n\t" + "ldr r10, [%[a], #56]\n\t" + "ldr r8, [%[a], #36]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[10] * A[13]\n\t" + "ldr r10, [%[a], #52]\n\t" + "ldr r8, [%[a], #40]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[11] * A[12]\n\t" + "ldr r10, [%[a], #48]\n\t" + "ldr r8, [%[a], #44]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r4, r4, r5\n\t" + "adcs r2, r2, r6\n\t" + "adc r3, r3, r7\n\t" + "str r4, [%[r], #92]\n\t" + "# A[9] * A[15]\n\t" + "ldr r10, [%[a], #60]\n\t" + "ldr r8, [%[a], #36]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r4, #0\n\t" + "mov r7, #0\n\t" + "# A[10] * A[14]\n\t" + "ldr r10, [%[a], #56]\n\t" + "ldr r8, [%[a], #40]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[11] * A[13]\n\t" + "ldr r10, [%[a], #52]\n\t" + "ldr r8, [%[a], #44]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[12] * A[12]\n\t" + "ldr r10, [%[a], #48]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r2, r2, r5\n\t" + "adcs r3, r3, r6\n\t" + "adc r4, r4, r7\n\t" + "str r2, [%[r], #96]\n\t" + "# A[10] * A[15]\n\t" + "ldr r10, [%[a], #60]\n\t" + "ldr r8, [%[a], #40]\n\t" + "umull r5, r6, r10, r8\n\t" + "mov r2, #0\n\t" + "mov r7, #0\n\t" + "# A[11] * A[14]\n\t" + "ldr r10, [%[a], #56]\n\t" + "ldr r8, [%[a], #44]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "# A[12] * A[13]\n\t" + "ldr r10, [%[a], #52]\n\t" + "ldr r8, [%[a], #48]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r5, r5, r8\n\t" + "adcs r6, r6, r9\n\t" + "adc r7, r7, r12\n\t" + "adds r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adc r7, r7, r7\n\t" + "adds r3, r3, r5\n\t" + "adcs r4, r4, r6\n\t" + "adc r2, r2, r7\n\t" + "str r3, [%[r], #100]\n\t" + "# A[11] * A[15]\n\t" + "ldr r10, [%[a], #60]\n\t" + "ldr r8, [%[a], #44]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r4, r4, r8\n\t" + "adcs r2, r2, r9\n\t" + "adc r3, r12, r12\n\t" + "adds r4, r4, r8\n\t" + "adcs r2, r2, r9\n\t" + "adc r3, r3, r12\n\t" + "# A[12] * A[14]\n\t" + "ldr r10, [%[a], #56]\n\t" + "ldr r8, [%[a], #48]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r4, r4, r8\n\t" + "adcs r2, r2, r9\n\t" + "adc r3, r3, r12\n\t" + "adds r4, r4, r8\n\t" + "adcs r2, r2, r9\n\t" + "adc r3, r3, r12\n\t" + "# A[13] * A[13]\n\t" + "ldr r10, [%[a], #52]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r4, r4, r8\n\t" + "adcs r2, r2, r9\n\t" + "adc r3, r3, r12\n\t" + "str r4, [%[r], #104]\n\t" + "# A[12] * A[15]\n\t" + "ldr r10, [%[a], #60]\n\t" + "ldr r8, [%[a], #48]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r12, r12\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r4, r12\n\t" + "# A[13] * A[14]\n\t" + "ldr r10, [%[a], #56]\n\t" + "ldr r8, [%[a], #52]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r4, r12\n\t" + "adds r2, r2, r8\n\t" + "adcs r3, r3, r9\n\t" + "adc r4, r4, r12\n\t" + "str r2, [%[r], #108]\n\t" + "# A[13] * A[15]\n\t" + "ldr r10, [%[a], #60]\n\t" + "ldr r8, [%[a], #52]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r12, r12\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "# A[14] * A[14]\n\t" + "ldr r10, [%[a], #56]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r3, r3, r8\n\t" + "adcs r4, r4, r9\n\t" + "adc r2, r2, r12\n\t" + "str r3, [%[r], #112]\n\t" + "# A[14] * A[15]\n\t" + "ldr r10, [%[a], #60]\n\t" + "ldr r8, [%[a], #56]\n\t" + "umull r8, r9, r10, r8\n\t" + "adds r4, r4, r8\n\t" + "adcs r2, r2, r9\n\t" + "adc r3, r12, r12\n\t" + "adds r4, r4, r8\n\t" + "adcs r2, r2, r9\n\t" + "adc r3, r3, r12\n\t" + "str r4, [%[r], #116]\n\t" + "# A[15] * A[15]\n\t" + "ldr r10, [%[a], #60]\n\t" + "umull r8, r9, r10, r10\n\t" + "adds r2, r2, r8\n\t" + "adc r3, r3, r9\n\t" + "str r2, [%[r], #120]\n\t" + "str r3, [%[r], #124]\n\t" + "ldm sp!, {r2, r3, r4, r8}\n\t" + "stm %[r]!, {r2, r3, r4, r8}\n\t" + "ldm sp!, {r2, r3, r4, r8}\n\t" + "stm %[r]!, {r2, r3, r4, r8}\n\t" + "ldm sp!, {r2, r3, r4, r8}\n\t" + "stm %[r]!, {r2, r3, r4, r8}\n\t" + "ldm sp!, {r2, r3, r4, r8}\n\t" + "stm %[r]!, {r2, r3, r4, r8}\n\t" + "sub %[r], %[r], #64\n\t" + : + : [r] "r" (r), [a] "r" (a) + : "memory", "r2", "r3", "r4", "r8", "r9", "r10", "r8", "r5", "r6", "r7", "r12" + ); +} + +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_1024_add_16(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r12, #0\n\t" + "ldr r4, [%[a], #0]\n\t" + "ldr r5, [%[a], #4]\n\t" + "ldr r6, [%[a], #8]\n\t" + "ldr r7, [%[a], #12]\n\t" + "ldr r8, [%[b], #0]\n\t" + "ldr r9, [%[b], #4]\n\t" + "ldr r10, [%[b], #8]\n\t" + "ldr r14, [%[b], #12]\n\t" + "adds r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "str r4, [%[r], #0]\n\t" + "str r5, [%[r], #4]\n\t" + "str r6, [%[r], #8]\n\t" + "str r7, [%[r], #12]\n\t" + "ldr r4, [%[a], #16]\n\t" + "ldr r5, [%[a], #20]\n\t" + "ldr r6, [%[a], #24]\n\t" + "ldr r7, [%[a], #28]\n\t" + "ldr r8, [%[b], #16]\n\t" + "ldr r9, [%[b], #20]\n\t" + "ldr r10, [%[b], #24]\n\t" + "ldr r14, [%[b], #28]\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "str r4, [%[r], #16]\n\t" + "str r5, [%[r], #20]\n\t" + "str r6, [%[r], #24]\n\t" + "str r7, [%[r], #28]\n\t" + "ldr r4, [%[a], #32]\n\t" + "ldr r5, [%[a], #36]\n\t" + "ldr r6, [%[a], #40]\n\t" + "ldr r7, [%[a], #44]\n\t" + "ldr r8, [%[b], #32]\n\t" + "ldr r9, [%[b], #36]\n\t" + "ldr r10, [%[b], #40]\n\t" + "ldr r14, [%[b], #44]\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "str r4, [%[r], #32]\n\t" + "str r5, [%[r], #36]\n\t" + "str r6, [%[r], #40]\n\t" + "str r7, [%[r], #44]\n\t" + "ldr r4, [%[a], #48]\n\t" + "ldr r5, [%[a], #52]\n\t" + "ldr r6, [%[a], #56]\n\t" + "ldr r7, [%[a], #60]\n\t" + "ldr r8, [%[b], #48]\n\t" + "ldr r9, [%[b], #52]\n\t" + "ldr r10, [%[b], #56]\n\t" + "ldr r14, [%[b], #60]\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "str r4, [%[r], #48]\n\t" + "str r5, [%[r], #52]\n\t" + "str r6, [%[r], #56]\n\t" + "str r7, [%[r], #60]\n\t" + "adc %[c], r12, r12\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b) + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + ); + + return c; +} + +/* Sub b from a into a. (a -= b) + * + * a A single precision integer and result. + * b A single precision integer. + */ +static sp_digit sp_1024_sub_in_place_32(sp_digit* a, const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldr r2, [%[a], #0]\n\t" + "ldr r3, [%[a], #4]\n\t" + "ldr r4, [%[a], #8]\n\t" + "ldr r5, [%[a], #12]\n\t" + "ldr r6, [%[b], #0]\n\t" + "ldr r7, [%[b], #4]\n\t" + "ldr r8, [%[b], #8]\n\t" + "ldr r9, [%[b], #12]\n\t" + "subs r2, r2, r6\n\t" + "sbcs r3, r3, r7\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "str r2, [%[a], #0]\n\t" + "str r3, [%[a], #4]\n\t" + "str r4, [%[a], #8]\n\t" + "str r5, [%[a], #12]\n\t" + "ldr r2, [%[a], #16]\n\t" + "ldr r3, [%[a], #20]\n\t" + "ldr r4, [%[a], #24]\n\t" + "ldr r5, [%[a], #28]\n\t" + "ldr r6, [%[b], #16]\n\t" + "ldr r7, [%[b], #20]\n\t" + "ldr r8, [%[b], #24]\n\t" + "ldr r9, [%[b], #28]\n\t" + "sbcs r2, r2, r6\n\t" + "sbcs r3, r3, r7\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "str r2, [%[a], #16]\n\t" + "str r3, [%[a], #20]\n\t" + "str r4, [%[a], #24]\n\t" + "str r5, [%[a], #28]\n\t" + "ldr r2, [%[a], #32]\n\t" + "ldr r3, [%[a], #36]\n\t" + "ldr r4, [%[a], #40]\n\t" + "ldr r5, [%[a], #44]\n\t" + "ldr r6, [%[b], #32]\n\t" + "ldr r7, [%[b], #36]\n\t" + "ldr r8, [%[b], #40]\n\t" + "ldr r9, [%[b], #44]\n\t" + "sbcs r2, r2, r6\n\t" + "sbcs r3, r3, r7\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "str r2, [%[a], #32]\n\t" + "str r3, [%[a], #36]\n\t" + "str r4, [%[a], #40]\n\t" + "str r5, [%[a], #44]\n\t" + "ldr r2, [%[a], #48]\n\t" + "ldr r3, [%[a], #52]\n\t" + "ldr r4, [%[a], #56]\n\t" + "ldr r5, [%[a], #60]\n\t" + "ldr r6, [%[b], #48]\n\t" + "ldr r7, [%[b], #52]\n\t" + "ldr r8, [%[b], #56]\n\t" + "ldr r9, [%[b], #60]\n\t" + "sbcs r2, r2, r6\n\t" + "sbcs r3, r3, r7\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "str r2, [%[a], #48]\n\t" + "str r3, [%[a], #52]\n\t" + "str r4, [%[a], #56]\n\t" + "str r5, [%[a], #60]\n\t" + "ldr r2, [%[a], #64]\n\t" + "ldr r3, [%[a], #68]\n\t" + "ldr r4, [%[a], #72]\n\t" + "ldr r5, [%[a], #76]\n\t" + "ldr r6, [%[b], #64]\n\t" + "ldr r7, [%[b], #68]\n\t" + "ldr r8, [%[b], #72]\n\t" + "ldr r9, [%[b], #76]\n\t" + "sbcs r2, r2, r6\n\t" + "sbcs r3, r3, r7\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "str r2, [%[a], #64]\n\t" + "str r3, [%[a], #68]\n\t" + "str r4, [%[a], #72]\n\t" + "str r5, [%[a], #76]\n\t" + "ldr r2, [%[a], #80]\n\t" + "ldr r3, [%[a], #84]\n\t" + "ldr r4, [%[a], #88]\n\t" + "ldr r5, [%[a], #92]\n\t" + "ldr r6, [%[b], #80]\n\t" + "ldr r7, [%[b], #84]\n\t" + "ldr r8, [%[b], #88]\n\t" + "ldr r9, [%[b], #92]\n\t" + "sbcs r2, r2, r6\n\t" + "sbcs r3, r3, r7\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "str r2, [%[a], #80]\n\t" + "str r3, [%[a], #84]\n\t" + "str r4, [%[a], #88]\n\t" + "str r5, [%[a], #92]\n\t" + "ldr r2, [%[a], #96]\n\t" + "ldr r3, [%[a], #100]\n\t" + "ldr r4, [%[a], #104]\n\t" + "ldr r5, [%[a], #108]\n\t" + "ldr r6, [%[b], #96]\n\t" + "ldr r7, [%[b], #100]\n\t" + "ldr r8, [%[b], #104]\n\t" + "ldr r9, [%[b], #108]\n\t" + "sbcs r2, r2, r6\n\t" + "sbcs r3, r3, r7\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "str r2, [%[a], #96]\n\t" + "str r3, [%[a], #100]\n\t" + "str r4, [%[a], #104]\n\t" + "str r5, [%[a], #108]\n\t" + "ldr r2, [%[a], #112]\n\t" + "ldr r3, [%[a], #116]\n\t" + "ldr r4, [%[a], #120]\n\t" + "ldr r5, [%[a], #124]\n\t" + "ldr r6, [%[b], #112]\n\t" + "ldr r7, [%[b], #116]\n\t" + "ldr r8, [%[b], #120]\n\t" + "ldr r9, [%[b], #124]\n\t" + "sbcs r2, r2, r6\n\t" + "sbcs r3, r3, r7\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "str r2, [%[a], #112]\n\t" + "str r3, [%[a], #116]\n\t" + "str r4, [%[a], #120]\n\t" + "str r5, [%[a], #124]\n\t" + "sbc %[c], r9, r9\n\t" + : [c] "+r" (c) + : [a] "r" (a), [b] "r" (b) + : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" + ); + + return c; +} + +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_1024_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r12, #0\n\t" + "ldr r4, [%[a], #0]\n\t" + "ldr r5, [%[a], #4]\n\t" + "ldr r6, [%[a], #8]\n\t" + "ldr r7, [%[a], #12]\n\t" + "ldr r8, [%[b], #0]\n\t" + "ldr r9, [%[b], #4]\n\t" + "ldr r10, [%[b], #8]\n\t" + "ldr r14, [%[b], #12]\n\t" + "adds r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "str r4, [%[r], #0]\n\t" + "str r5, [%[r], #4]\n\t" + "str r6, [%[r], #8]\n\t" + "str r7, [%[r], #12]\n\t" + "ldr r4, [%[a], #16]\n\t" + "ldr r5, [%[a], #20]\n\t" + "ldr r6, [%[a], #24]\n\t" + "ldr r7, [%[a], #28]\n\t" + "ldr r8, [%[b], #16]\n\t" + "ldr r9, [%[b], #20]\n\t" + "ldr r10, [%[b], #24]\n\t" + "ldr r14, [%[b], #28]\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "str r4, [%[r], #16]\n\t" + "str r5, [%[r], #20]\n\t" + "str r6, [%[r], #24]\n\t" + "str r7, [%[r], #28]\n\t" + "ldr r4, [%[a], #32]\n\t" + "ldr r5, [%[a], #36]\n\t" + "ldr r6, [%[a], #40]\n\t" + "ldr r7, [%[a], #44]\n\t" + "ldr r8, [%[b], #32]\n\t" + "ldr r9, [%[b], #36]\n\t" + "ldr r10, [%[b], #40]\n\t" + "ldr r14, [%[b], #44]\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "str r4, [%[r], #32]\n\t" + "str r5, [%[r], #36]\n\t" + "str r6, [%[r], #40]\n\t" + "str r7, [%[r], #44]\n\t" + "ldr r4, [%[a], #48]\n\t" + "ldr r5, [%[a], #52]\n\t" + "ldr r6, [%[a], #56]\n\t" + "ldr r7, [%[a], #60]\n\t" + "ldr r8, [%[b], #48]\n\t" + "ldr r9, [%[b], #52]\n\t" + "ldr r10, [%[b], #56]\n\t" + "ldr r14, [%[b], #60]\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "str r4, [%[r], #48]\n\t" + "str r5, [%[r], #52]\n\t" + "str r6, [%[r], #56]\n\t" + "str r7, [%[r], #60]\n\t" + "ldr r4, [%[a], #64]\n\t" + "ldr r5, [%[a], #68]\n\t" + "ldr r6, [%[a], #72]\n\t" + "ldr r7, [%[a], #76]\n\t" + "ldr r8, [%[b], #64]\n\t" + "ldr r9, [%[b], #68]\n\t" + "ldr r10, [%[b], #72]\n\t" + "ldr r14, [%[b], #76]\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "str r4, [%[r], #64]\n\t" + "str r5, [%[r], #68]\n\t" + "str r6, [%[r], #72]\n\t" + "str r7, [%[r], #76]\n\t" + "ldr r4, [%[a], #80]\n\t" + "ldr r5, [%[a], #84]\n\t" + "ldr r6, [%[a], #88]\n\t" + "ldr r7, [%[a], #92]\n\t" + "ldr r8, [%[b], #80]\n\t" + "ldr r9, [%[b], #84]\n\t" + "ldr r10, [%[b], #88]\n\t" + "ldr r14, [%[b], #92]\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "str r4, [%[r], #80]\n\t" + "str r5, [%[r], #84]\n\t" + "str r6, [%[r], #88]\n\t" + "str r7, [%[r], #92]\n\t" + "ldr r4, [%[a], #96]\n\t" + "ldr r5, [%[a], #100]\n\t" + "ldr r6, [%[a], #104]\n\t" + "ldr r7, [%[a], #108]\n\t" + "ldr r8, [%[b], #96]\n\t" + "ldr r9, [%[b], #100]\n\t" + "ldr r10, [%[b], #104]\n\t" + "ldr r14, [%[b], #108]\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "str r4, [%[r], #96]\n\t" + "str r5, [%[r], #100]\n\t" + "str r6, [%[r], #104]\n\t" + "str r7, [%[r], #108]\n\t" + "ldr r4, [%[a], #112]\n\t" + "ldr r5, [%[a], #116]\n\t" + "ldr r6, [%[a], #120]\n\t" + "ldr r7, [%[a], #124]\n\t" + "ldr r8, [%[b], #112]\n\t" + "ldr r9, [%[b], #116]\n\t" + "ldr r10, [%[b], #120]\n\t" + "ldr r14, [%[b], #124]\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "str r4, [%[r], #112]\n\t" + "str r5, [%[r], #116]\n\t" + "str r6, [%[r], #120]\n\t" + "str r7, [%[r], #124]\n\t" + "adc %[c], r12, r12\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b) + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + ); + + return c; +} + +/* AND m into each word of a and store in r. + * + * r A single precision integer. + * a A single precision integer. + * m Mask to AND against each digit. + */ +static void sp_1024_mask_16(sp_digit* r, const sp_digit* a, sp_digit m) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i=0; i<16; i++) { + r[i] = a[i] & m; + } +#else + int i; + + for (i = 0; i < 16; i += 8) { + r[i+0] = a[i+0] & m; + r[i+1] = a[i+1] & m; + r[i+2] = a[i+2] & m; + r[i+3] = a[i+3] & m; + r[i+4] = a[i+4] & m; + r[i+5] = a[i+5] & m; + r[i+6] = a[i+6] & m; + r[i+7] = a[i+7] & m; + } +#endif +} + +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static void sp_1024_mul_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit* z0 = r; + sp_digit z1[32]; + sp_digit a1[16]; + sp_digit b1[16]; + sp_digit z2[32]; + sp_digit u; + sp_digit ca; + sp_digit cb; + + ca = sp_1024_add_16(a1, a, &a[16]); + cb = sp_1024_add_16(b1, b, &b[16]); + u = ca & cb; + sp_1024_mul_16(z1, a1, b1); + sp_1024_mul_16(z2, &a[16], &b[16]); + sp_1024_mul_16(z0, a, b); + sp_1024_mask_16(r + 32, a1, 0 - cb); + sp_1024_mask_16(b1, b1, 0 - ca); + u += sp_1024_add_16(r + 32, r + 32, b1); + u += sp_1024_sub_in_place_32(z1, z2); + u += sp_1024_sub_in_place_32(z1, z0); + u += sp_1024_add_32(r + 16, r + 16, z1); + r[48] = u; + XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1)); + (void)sp_1024_add_32(r + 32, r + 32, z2); +} + +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_1024_sqr_32(sp_digit* r, const sp_digit* a) +{ + sp_digit* z0 = r; + sp_digit z2[32]; + sp_digit z1[32]; + sp_digit a1[16]; + sp_digit u; + + u = sp_1024_add_16(a1, a, &a[16]); + sp_1024_sqr_16(z1, a1); + sp_1024_sqr_16(z2, &a[16]); + sp_1024_sqr_16(z0, a); + sp_1024_mask_16(r + 32, a1, 0 - u); + u += sp_1024_add_16(r + 32, r + 32, r + 32); + u += sp_1024_sub_in_place_32(z1, z2); + u += sp_1024_sub_in_place_32(z1, z0); + u += sp_1024_add_32(r + 16, r + 16, z1); + r[48] = u; + XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1)); + (void)sp_1024_add_32(r + 32, r + 32, z2); +} + +#else +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static void sp_1024_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* b) +{ + __asm__ __volatile__ ( + "sub sp, sp, #256\n\t" + "mov r5, #0\n\t" + "mov r6, #0\n\t" + "mov r7, #0\n\t" + "mov r8, #0\n\t" + "\n1:\n\t" + "subs r3, r5, #124\n\t" + "it cc\n\t" + "movcc r3, #0\n\t" + "sub r4, r5, r3\n\t" + "\n2:\n\t" + "ldr r14, [%[a], r3]\n\t" + "ldr r12, [%[b], r4]\n\t" + "umull r9, r10, r14, r12\n\t" + "adds r6, r6, r9\n\t" + "adcs r7, r7, r10\n\t" + "adc r8, r8, #0\n\t" + "add r3, r3, #4\n\t" + "sub r4, r4, #4\n\t" + "cmp r3, #128\n\t" + "beq 3f\n\t" + "cmp r3, r5\n\t" + "ble 2b\n\t" + "\n3:\n\t" + "str r6, [sp, r5]\n\t" + "mov r6, r7\n\t" + "mov r7, r8\n\t" + "mov r8, #0\n\t" + "add r5, r5, #4\n\t" + "cmp r5, #248\n\t" + "ble 1b\n\t" + "str r6, [sp, r5]\n\t" + "\n4:\n\t" + "ldr r6, [sp, #0]\n\t" + "ldr r7, [sp, #4]\n\t" + "ldr r8, [sp, #8]\n\t" + "ldr r3, [sp, #12]\n\t" + "str r6, [%[r], #0]\n\t" + "str r7, [%[r], #4]\n\t" + "str r8, [%[r], #8]\n\t" + "str r3, [%[r], #12]\n\t" + "add sp, sp, #16\n\t" + "add %[r], %[r], #16\n\t" + "subs r5, r5, #16\n\t" + "bgt 4b\n\t" + : [r] "+r" (r) + : [a] "r" (a), [b] "r" (b) + : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + ); +} + +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +static void sp_1024_sqr_32(sp_digit* r, const sp_digit* a) +{ + __asm__ __volatile__ ( + "sub sp, sp, #256\n\t" + "mov r12, #0\n\t" + "mov r6, #0\n\t" + "mov r7, #0\n\t" + "mov r8, #0\n\t" + "mov r5, #0\n\t" + "\n1:\n\t" + "subs r3, r5, #124\n\t" + "it cc\n\t" + "movcc r3, r12\n\t" + "sub r4, r5, r3\n\t" + "\n2:\n\t" + "cmp r4, r3\n\t" + "beq 4f\n\t" + "ldr r14, [%[a], r3]\n\t" + "ldr r9, [%[a], r4]\n\t" + "umull r9, r10, r14, r9\n\t" + "adds r6, r6, r9\n\t" + "adcs r7, r7, r10\n\t" + "adc r8, r8, r12\n\t" + "adds r6, r6, r9\n\t" + "adcs r7, r7, r10\n\t" + "adc r8, r8, r12\n\t" + "bal 5f\n\t" + "\n4:\n\t" + "ldr r14, [%[a], r3]\n\t" + "umull r9, r10, r14, r14\n\t" + "adds r6, r6, r9\n\t" + "adcs r7, r7, r10\n\t" + "adc r8, r8, r12\n\t" + "\n5:\n\t" + "add r3, r3, #4\n\t" + "sub r4, r4, #4\n\t" + "cmp r3, #128\n\t" + "beq 3f\n\t" + "cmp r3, r4\n\t" + "bgt 3f\n\t" + "cmp r3, r5\n\t" + "ble 2b\n\t" + "\n3:\n\t" + "str r6, [sp, r5]\n\t" + "mov r6, r7\n\t" + "mov r7, r8\n\t" + "mov r8, #0\n\t" + "add r5, r5, #4\n\t" + "cmp r5, #248\n\t" + "ble 1b\n\t" + "str r6, [sp, r5]\n\t" + "\n4:\n\t" + "ldr r6, [sp, #0]\n\t" + "ldr r7, [sp, #4]\n\t" + "ldr r8, [sp, #8]\n\t" + "ldr r3, [sp, #12]\n\t" + "str r6, [%[r], #0]\n\t" + "str r7, [%[r], #4]\n\t" + "str r8, [%[r], #8]\n\t" + "str r3, [%[r], #12]\n\t" + "add sp, sp, #16\n\t" + "add %[r], %[r], #16\n\t" + "subs r5, r5, #16\n\t" + "bgt 4b\n\t" + : [r] "+r" (r) + : [a] "r" (a) + : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r9", "r12" + ); +} + +#endif /* !WOLFSSL_SP_SMALL */ +/* The modulus (prime) of the curve P1024. */ +static const sp_digit p1024_mod[32] = { + 0xfea85feb,0x666d807a,0xac7ace87,0x80c5df10,0x89857db0,0xfce3e823, + 0x56971f1f,0x9f94d6af,0x1c3c09aa,0xa7cf3c52,0x31852a82,0xb6aff4a8, + 0x65681ce1,0x512ac5cd,0x326b4cd4,0xe26c6487,0xa666a6d0,0x356d27f4, + 0xf7c88a19,0xe791b39f,0x31a59cb0,0x228730d5,0xe2fc0f1b,0xf40aab27, + 0xb3e01a2e,0xbe9ae358,0x9cb48261,0x416c0ce1,0xdad0657a,0x65c61198, + 0x0a563fda,0x997abb1f +}; +/* The Montogmery normalizer for modulus of the curve P1024. */ +static const sp_digit p1024_norm_mod[32] = { + 0x0157a015,0x99927f85,0x53853178,0x7f3a20ef,0x767a824f,0x031c17dc, + 0xa968e0e0,0x606b2950,0xe3c3f655,0x5830c3ad,0xce7ad57d,0x49500b57, + 0x9a97e31e,0xaed53a32,0xcd94b32b,0x1d939b78,0x5999592f,0xca92d80b, + 0x083775e6,0x186e4c60,0xce5a634f,0xdd78cf2a,0x1d03f0e4,0x0bf554d8, + 0x4c1fe5d1,0x41651ca7,0x634b7d9e,0xbe93f31e,0x252f9a85,0x9a39ee67, + 0xf5a9c025,0x668544e0 +}; +/* The Montogmery multiplier for modulus of the curve P1024. */ +static sp_digit p1024_mp_mod = 0x7c8f2f3d; +#if defined(WOLFSSL_SP_SMALL) || defined(HAVE_ECC_CHECK_KEY) +/* The order of the curve P1024. */ +static const sp_digit p1024_order[32] = { + 0xbfaa17fb,0xd99b601e,0x2b1eb3a1,0x203177c4,0xe2615f6c,0xff38fa08, + 0xd5a5c7c7,0xa7e535ab,0x870f026a,0xa9f3cf14,0x0c614aa0,0x6dabfd2a, + 0x595a0738,0x144ab173,0xcc9ad335,0x389b1921,0x2999a9b4,0x4d5b49fd, + 0xfdf22286,0x39e46ce7,0x4c69672c,0xc8a1cc35,0xf8bf03c6,0xbd02aac9, + 0x2cf8068b,0x6fa6b8d6,0x672d2098,0x905b0338,0x36b4195e,0x99718466, + 0xc2958ff6,0x265eaec7 +}; +#endif +/* The base point of curve P1024. */ +static const sp_point_1024 p1024_base = { + /* X ordinate */ + { + 0xeae63895,0x880dc8ab,0x967e0979,0x80ec46c4,0xb63f73ec,0xee9163a5, + 0x80728d87,0xd5cfb4cc,0xba66910d,0xa7c1514d,0x7a60de74,0xa702c339, + 0x8b72f2e1,0x337c8654,0x5dd5bccb,0x9760af76,0x406ce890,0x718bd9e7, + 0xdb9dfa55,0x43d5f22c,0x30b09e10,0xab10db90,0xf6ce2308,0xb5edb6c0, + 0xb6ff7cbf,0x98b2f204,0x0aec69c6,0x2b1a2fd6,0x3ed9b52a,0x0a799005, + 0x332c29ad,0x53fc09ee, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* Y ordinate */ + { + 0x1bef16d7,0x75573fd7,0x6a67dcde,0xadb9b570,0xd5bb4636,0x80bdad5a, + 0xe9cb99a9,0x13515ad7,0xc5a4d5f2,0x492d979f,0x164aa989,0xac6f1e80, + 0xb7652fe0,0xcad696b5,0xad547c6c,0x70dae117,0xa9e032b9,0x416cff0c, + 0x9a140b2e,0x6b598ccf,0xf0de55f6,0xe7f7f5e5,0x654ec2b9,0xf5ea69f4, + 0x1e141178,0x3d778d82,0x02990696,0xd3e82016,0x3634a135,0xf9f1f053, + 0x3f6009f1,0x0a824906, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* Z ordinate */ + { + 0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* infinity */ + 0 +}; + +#ifdef WOLFSSL_SP_SMALL +/* Sub b from a into a. (a -= b) + * + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_1024_sub_in_place_32(sp_digit* a, const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r14, #0\n\t" + "add r12, %[a], #128\n\t" + "\n1:\n\t" + "subs %[c], r14, %[c]\n\t" + "ldr r3, [%[a]]\n\t" + "ldr r4, [%[a], #4]\n\t" + "ldr r5, [%[a], #8]\n\t" + "ldr r6, [%[a], #12]\n\t" + "ldr r7, [%[b]], #4\n\t" + "ldr r8, [%[b]], #4\n\t" + "ldr r9, [%[b]], #4\n\t" + "ldr r10, [%[b]], #4\n\t" + "sbcs r3, r3, r7\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "str r3, [%[a]], #4\n\t" + "str r4, [%[a]], #4\n\t" + "str r5, [%[a]], #4\n\t" + "str r6, [%[a]], #4\n\t" + "sbc %[c], r14, r14\n\t" + "cmp %[a], r12\n\t" + "bne 1b\n\t" + : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r12", "r14" + ); + + return c; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Conditionally subtract b from a using the mask m. + * m is -1 to subtract and 0 when not copying. + * + * r A single precision number representing condition subtract result. + * a A single precision number to subtract from. + * b A single precision number to subtract. + * m Mask value to apply. + */ +static sp_digit sp_1024_cond_sub_32(sp_digit* r, const sp_digit* a, const sp_digit* b, + sp_digit m) +{ + sp_digit c = 0; + +#ifdef WOLFSSL_SP_SMALL + __asm__ __volatile__ ( + "mov r9, #0\n\t" + "mov r8, #0\n\t" + "1:\n\t" + "subs %[c], r9, %[c]\n\t" + "ldr r4, [%[a], r8]\n\t" + "ldr r5, [%[b], r8]\n\t" + "and r5, r5, %[m]\n\t" + "sbcs r4, r4, r5\n\t" + "sbc %[c], r9, r9\n\t" + "str r4, [%[r], r8]\n\t" + "add r8, r8, #4\n\t" + "cmp r8, #128\n\t" + "blt 1b\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "r4", "r6", "r5", "r7", "r8", "r9" + ); +#else + __asm__ __volatile__ ( + + "mov r9, #0\n\t" + "ldr r4, [%[a], #0]\n\t" + "ldr r6, [%[a], #4]\n\t" + "ldr r5, [%[b], #0]\n\t" + "ldr r7, [%[b], #4]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "subs r4, r4, r5\n\t" + "sbcs r6, r6, r7\n\t" + "str r4, [%[r], #0]\n\t" + "str r6, [%[r], #4]\n\t" + "ldr r4, [%[a], #8]\n\t" + "ldr r6, [%[a], #12]\n\t" + "ldr r5, [%[b], #8]\n\t" + "ldr r7, [%[b], #12]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "sbcs r4, r4, r5\n\t" + "sbcs r6, r6, r7\n\t" + "str r4, [%[r], #8]\n\t" + "str r6, [%[r], #12]\n\t" + "ldr r4, [%[a], #16]\n\t" + "ldr r6, [%[a], #20]\n\t" + "ldr r5, [%[b], #16]\n\t" + "ldr r7, [%[b], #20]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "sbcs r4, r4, r5\n\t" + "sbcs r6, r6, r7\n\t" + "str r4, [%[r], #16]\n\t" + "str r6, [%[r], #20]\n\t" + "ldr r4, [%[a], #24]\n\t" + "ldr r6, [%[a], #28]\n\t" + "ldr r5, [%[b], #24]\n\t" + "ldr r7, [%[b], #28]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "sbcs r4, r4, r5\n\t" + "sbcs r6, r6, r7\n\t" + "str r4, [%[r], #24]\n\t" + "str r6, [%[r], #28]\n\t" + "ldr r4, [%[a], #32]\n\t" + "ldr r6, [%[a], #36]\n\t" + "ldr r5, [%[b], #32]\n\t" + "ldr r7, [%[b], #36]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "sbcs r4, r4, r5\n\t" + "sbcs r6, r6, r7\n\t" + "str r4, [%[r], #32]\n\t" + "str r6, [%[r], #36]\n\t" + "ldr r4, [%[a], #40]\n\t" + "ldr r6, [%[a], #44]\n\t" + "ldr r5, [%[b], #40]\n\t" + "ldr r7, [%[b], #44]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "sbcs r4, r4, r5\n\t" + "sbcs r6, r6, r7\n\t" + "str r4, [%[r], #40]\n\t" + "str r6, [%[r], #44]\n\t" + "ldr r4, [%[a], #48]\n\t" + "ldr r6, [%[a], #52]\n\t" + "ldr r5, [%[b], #48]\n\t" + "ldr r7, [%[b], #52]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "sbcs r4, r4, r5\n\t" + "sbcs r6, r6, r7\n\t" + "str r4, [%[r], #48]\n\t" + "str r6, [%[r], #52]\n\t" + "ldr r4, [%[a], #56]\n\t" + "ldr r6, [%[a], #60]\n\t" + "ldr r5, [%[b], #56]\n\t" + "ldr r7, [%[b], #60]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "sbcs r4, r4, r5\n\t" + "sbcs r6, r6, r7\n\t" + "str r4, [%[r], #56]\n\t" + "str r6, [%[r], #60]\n\t" + "ldr r4, [%[a], #64]\n\t" + "ldr r6, [%[a], #68]\n\t" + "ldr r5, [%[b], #64]\n\t" + "ldr r7, [%[b], #68]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "sbcs r4, r4, r5\n\t" + "sbcs r6, r6, r7\n\t" + "str r4, [%[r], #64]\n\t" + "str r6, [%[r], #68]\n\t" + "ldr r4, [%[a], #72]\n\t" + "ldr r6, [%[a], #76]\n\t" + "ldr r5, [%[b], #72]\n\t" + "ldr r7, [%[b], #76]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "sbcs r4, r4, r5\n\t" + "sbcs r6, r6, r7\n\t" + "str r4, [%[r], #72]\n\t" + "str r6, [%[r], #76]\n\t" + "ldr r4, [%[a], #80]\n\t" + "ldr r6, [%[a], #84]\n\t" + "ldr r5, [%[b], #80]\n\t" + "ldr r7, [%[b], #84]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "sbcs r4, r4, r5\n\t" + "sbcs r6, r6, r7\n\t" + "str r4, [%[r], #80]\n\t" + "str r6, [%[r], #84]\n\t" + "ldr r4, [%[a], #88]\n\t" + "ldr r6, [%[a], #92]\n\t" + "ldr r5, [%[b], #88]\n\t" + "ldr r7, [%[b], #92]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "sbcs r4, r4, r5\n\t" + "sbcs r6, r6, r7\n\t" + "str r4, [%[r], #88]\n\t" + "str r6, [%[r], #92]\n\t" + "ldr r4, [%[a], #96]\n\t" + "ldr r6, [%[a], #100]\n\t" + "ldr r5, [%[b], #96]\n\t" + "ldr r7, [%[b], #100]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "sbcs r4, r4, r5\n\t" + "sbcs r6, r6, r7\n\t" + "str r4, [%[r], #96]\n\t" + "str r6, [%[r], #100]\n\t" + "ldr r4, [%[a], #104]\n\t" + "ldr r6, [%[a], #108]\n\t" + "ldr r5, [%[b], #104]\n\t" + "ldr r7, [%[b], #108]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "sbcs r4, r4, r5\n\t" + "sbcs r6, r6, r7\n\t" + "str r4, [%[r], #104]\n\t" + "str r6, [%[r], #108]\n\t" + "ldr r4, [%[a], #112]\n\t" + "ldr r6, [%[a], #116]\n\t" + "ldr r5, [%[b], #112]\n\t" + "ldr r7, [%[b], #116]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "sbcs r4, r4, r5\n\t" + "sbcs r6, r6, r7\n\t" + "str r4, [%[r], #112]\n\t" + "str r6, [%[r], #116]\n\t" + "ldr r4, [%[a], #120]\n\t" + "ldr r6, [%[a], #124]\n\t" + "ldr r5, [%[b], #120]\n\t" + "ldr r7, [%[b], #124]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "sbcs r4, r4, r5\n\t" + "sbcs r6, r6, r7\n\t" + "str r4, [%[r], #120]\n\t" + "str r6, [%[r], #124]\n\t" + "sbc %[c], r9, r9\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "r4", "r6", "r5", "r7", "r8", "r9" + ); +#endif /* WOLFSSL_SP_SMALL */ + + return c; +} + +#ifdef WOLFSSL_SP_SMALL +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_1024_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "add r12, %[a], #128\n\t" + "\n1:\n\t" + "adds %[c], %[c], #-1\n\t" + "ldr r4, [%[a]], #4\n\t" + "ldr r5, [%[a]], #4\n\t" + "ldr r6, [%[a]], #4\n\t" + "ldr r7, [%[a]], #4\n\t" + "ldr r8, [%[b]], #4\n\t" + "ldr r9, [%[b]], #4\n\t" + "ldr r10, [%[b]], #4\n\t" + "ldr r14, [%[b]], #4\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "str r4, [%[r]], #4\n\t" + "str r5, [%[r]], #4\n\t" + "str r6, [%[r]], #4\n\t" + "str r7, [%[r]], #4\n\t" + "mov r4, #0\n\t" + "adc %[c], r4, #0\n\t" + "cmp %[a], r12\n\t" + "bne 1b\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + ); + + return c; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Mul a by digit b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision digit. + */ +static void sp_1024_mul_d_32(sp_digit* r, const sp_digit* a, + sp_digit b) +{ +#ifdef WOLFSSL_SP_SMALL + __asm__ __volatile__ ( + "mov r10, #0\n\t" + "# A[0] * B\n\t" + "ldr r8, [%[a]]\n\t" + "umull r5, r3, %[b], r8\n\t" + "mov r4, #0\n\t" + "str r5, [%[r]]\n\t" + "mov r5, #0\n\t" + "mov r9, #4\n\t" + "1:\n\t" + "ldr r8, [%[a], r9]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r5, r10\n\t" + "str r3, [%[r], r9]\n\t" + "mov r3, r4\n\t" + "mov r4, r5\n\t" + "mov r5, #0\n\t" + "add r9, r9, #4\n\t" + "cmp r9, #128\n\t" + "blt 1b\n\t" + "str r3, [%[r], #128]\n\t" + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) + : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" + ); +#else + __asm__ __volatile__ ( + "mov r10, #0\n\t" + "# A[0] * B\n\t" + "ldr r8, [%[a]]\n\t" + "umull r3, r4, %[b], r8\n\t" + "mov r5, #0\n\t" + "str r3, [%[r]]\n\t" + "# A[1] * B\n\t" + "ldr r8, [%[a], #4]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "str r4, [%[r], #4]\n\t" + "# A[2] * B\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "str r5, [%[r], #8]\n\t" + "# A[3] * B\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "str r3, [%[r], #12]\n\t" + "# A[4] * B\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "str r4, [%[r], #16]\n\t" + "# A[5] * B\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "str r5, [%[r], #20]\n\t" + "# A[6] * B\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "str r3, [%[r], #24]\n\t" + "# A[7] * B\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "str r4, [%[r], #28]\n\t" + "# A[8] * B\n\t" + "ldr r8, [%[a], #32]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "str r5, [%[r], #32]\n\t" + "# A[9] * B\n\t" + "ldr r8, [%[a], #36]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "str r3, [%[r], #36]\n\t" + "# A[10] * B\n\t" + "ldr r8, [%[a], #40]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "str r4, [%[r], #40]\n\t" + "# A[11] * B\n\t" + "ldr r8, [%[a], #44]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "str r5, [%[r], #44]\n\t" + "# A[12] * B\n\t" + "ldr r8, [%[a], #48]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "str r3, [%[r], #48]\n\t" + "# A[13] * B\n\t" + "ldr r8, [%[a], #52]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "str r4, [%[r], #52]\n\t" + "# A[14] * B\n\t" + "ldr r8, [%[a], #56]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "str r5, [%[r], #56]\n\t" + "# A[15] * B\n\t" + "ldr r8, [%[a], #60]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "str r3, [%[r], #60]\n\t" + "# A[16] * B\n\t" + "ldr r8, [%[a], #64]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "str r4, [%[r], #64]\n\t" + "# A[17] * B\n\t" + "ldr r8, [%[a], #68]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "str r5, [%[r], #68]\n\t" + "# A[18] * B\n\t" + "ldr r8, [%[a], #72]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "str r3, [%[r], #72]\n\t" + "# A[19] * B\n\t" + "ldr r8, [%[a], #76]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "str r4, [%[r], #76]\n\t" + "# A[20] * B\n\t" + "ldr r8, [%[a], #80]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "str r5, [%[r], #80]\n\t" + "# A[21] * B\n\t" + "ldr r8, [%[a], #84]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "str r3, [%[r], #84]\n\t" + "# A[22] * B\n\t" + "ldr r8, [%[a], #88]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "str r4, [%[r], #88]\n\t" + "# A[23] * B\n\t" + "ldr r8, [%[a], #92]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "str r5, [%[r], #92]\n\t" + "# A[24] * B\n\t" + "ldr r8, [%[a], #96]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "str r3, [%[r], #96]\n\t" + "# A[25] * B\n\t" + "ldr r8, [%[a], #100]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "str r4, [%[r], #100]\n\t" + "# A[26] * B\n\t" + "ldr r8, [%[a], #104]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "str r5, [%[r], #104]\n\t" + "# A[27] * B\n\t" + "ldr r8, [%[a], #108]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "str r3, [%[r], #108]\n\t" + "# A[28] * B\n\t" + "ldr r8, [%[a], #112]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r7\n\t" + "adc r3, r10, r10\n\t" + "str r4, [%[r], #112]\n\t" + "# A[29] * B\n\t" + "ldr r8, [%[a], #116]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r7\n\t" + "adc r4, r10, r10\n\t" + "str r5, [%[r], #116]\n\t" + "# A[30] * B\n\t" + "ldr r8, [%[a], #120]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r7\n\t" + "adc r5, r10, r10\n\t" + "str r3, [%[r], #120]\n\t" + "# A[31] * B\n\t" + "ldr r8, [%[a], #124]\n\t" + "umull r6, r7, %[b], r8\n\t" + "adds r4, r4, r6\n\t" + "adc r5, r5, r7\n\t" + "str r4, [%[r], #124]\n\t" + "str r5, [%[r], #128]\n\t" + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) + : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" + ); +#endif +} + +/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) + * + * d1 The high order half of the number to divide. + * d0 The low order half of the number to divide. + * div The dividend. + * returns the result of the division. + * + * Note that this is an approximate div. It may give an answer 1 larger. + */ +static sp_digit div_1024_word_32(sp_digit d1, sp_digit d0, sp_digit div) +{ + sp_digit r = 0; + + __asm__ __volatile__ ( + "lsr r5, %[div], #1\n\t" + "add r5, r5, #1\n\t" + "mov r6, %[d0]\n\t" + "mov r7, %[d1]\n\t" + "# Do top 32\n\t" + "subs r8, r5, r7\n\t" + "sbc r8, r8, r8\n\t" + "add %[r], %[r], %[r]\n\t" + "sub %[r], %[r], r8\n\t" + "and r8, r8, r5\n\t" + "subs r7, r7, r8\n\t" + "# Next 30 bits\n\t" + "mov r4, #29\n\t" + "1:\n\t" + "movs r6, r6, lsl #1\n\t" + "adc r7, r7, r7\n\t" + "subs r8, r5, r7\n\t" + "sbc r8, r8, r8\n\t" + "add %[r], %[r], %[r]\n\t" + "sub %[r], %[r], r8\n\t" + "and r8, r8, r5\n\t" + "subs r7, r7, r8\n\t" + "subs r4, r4, #1\n\t" + "bpl 1b\n\t" + "add %[r], %[r], %[r]\n\t" + "add %[r], %[r], #1\n\t" + "umull r4, r5, %[r], %[div]\n\t" + "subs r4, %[d0], r4\n\t" + "sbc r5, %[d1], r5\n\t" + "add %[r], %[r], r5\n\t" + "umull r4, r5, %[r], %[div]\n\t" + "subs r4, %[d0], r4\n\t" + "sbc r5, %[d1], r5\n\t" + "add %[r], %[r], r5\n\t" + "umull r4, r5, %[r], %[div]\n\t" + "subs r4, %[d0], r4\n\t" + "sbc r5, %[d1], r5\n\t" + "add %[r], %[r], r5\n\t" + "subs r8, %[div], r4\n\t" + "sbc r8, r8, r8\n\t" + "sub %[r], %[r], r8\n\t" + : [r] "+r" (r) + : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div) + : "r4", "r5", "r6", "r7", "r8" + ); + return r; +} + +/* AND m into each word of a and store in r. + * + * r A single precision integer. + * a A single precision integer. + * m Mask to AND against each digit. + */ +static void sp_1024_mask_32(sp_digit* r, const sp_digit* a, sp_digit m) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i=0; i<32; i++) { + r[i] = a[i] & m; + } +#else + int i; + + for (i = 0; i < 32; i += 8) { + r[i+0] = a[i+0] & m; + r[i+1] = a[i+1] & m; + r[i+2] = a[i+2] & m; + r[i+3] = a[i+3] & m; + r[i+4] = a[i+4] & m; + r[i+5] = a[i+5] & m; + r[i+6] = a[i+6] & m; + r[i+7] = a[i+7] & m; + } +#endif +} + +/* Compare a with b in constant time. + * + * a A single precision integer. + * b A single precision integer. + * return -ve, 0 or +ve if a is less than, equal to or greater than b + * respectively. + */ +static int32_t sp_1024_cmp_32(const sp_digit* a, const sp_digit* b) +{ + sp_digit r = -1; + sp_digit one = 1; + + +#ifdef WOLFSSL_SP_SMALL + __asm__ __volatile__ ( + "mov r7, #0\n\t" + "mov r3, #-1\n\t" + "mov r6, #124\n\t" + "1:\n\t" + "ldr r4, [%[a], r6]\n\t" + "ldr r5, [%[b], r6]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "subs r6, r6, #4\n\t" + "bcs 1b\n\t" + "eor %[r], %[r], r3\n\t" + : [r] "+r" (r) + : [a] "r" (a), [b] "r" (b), [one] "r" (one) + : "r3", "r4", "r5", "r6", "r7" + ); +#else + __asm__ __volatile__ ( + "mov r7, #0\n\t" + "mov r3, #-1\n\t" + "ldr r4, [%[a], #124]\n\t" + "ldr r5, [%[b], #124]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #120]\n\t" + "ldr r5, [%[b], #120]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #116]\n\t" + "ldr r5, [%[b], #116]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #112]\n\t" + "ldr r5, [%[b], #112]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #108]\n\t" + "ldr r5, [%[b], #108]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #104]\n\t" + "ldr r5, [%[b], #104]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #100]\n\t" + "ldr r5, [%[b], #100]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #96]\n\t" + "ldr r5, [%[b], #96]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #92]\n\t" + "ldr r5, [%[b], #92]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #88]\n\t" + "ldr r5, [%[b], #88]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #84]\n\t" + "ldr r5, [%[b], #84]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #80]\n\t" + "ldr r5, [%[b], #80]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #76]\n\t" + "ldr r5, [%[b], #76]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #72]\n\t" + "ldr r5, [%[b], #72]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #68]\n\t" + "ldr r5, [%[b], #68]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #64]\n\t" + "ldr r5, [%[b], #64]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #60]\n\t" + "ldr r5, [%[b], #60]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #56]\n\t" + "ldr r5, [%[b], #56]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #52]\n\t" + "ldr r5, [%[b], #52]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #48]\n\t" + "ldr r5, [%[b], #48]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #44]\n\t" + "ldr r5, [%[b], #44]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #40]\n\t" + "ldr r5, [%[b], #40]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #36]\n\t" + "ldr r5, [%[b], #36]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #32]\n\t" + "ldr r5, [%[b], #32]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #28]\n\t" + "ldr r5, [%[b], #28]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #24]\n\t" + "ldr r5, [%[b], #24]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #20]\n\t" + "ldr r5, [%[b], #20]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #16]\n\t" + "ldr r5, [%[b], #16]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #12]\n\t" + "ldr r5, [%[b], #12]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #8]\n\t" + "ldr r5, [%[b], #8]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #4]\n\t" + "ldr r5, [%[b], #4]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "ldr r4, [%[a], #0]\n\t" + "ldr r5, [%[b], #0]\n\t" + "and r4, r4, r3\n\t" + "and r5, r5, r3\n\t" + "subs r4, r4, r5\n\t" + "it hi\n\t" + "movhi %[r], %[one]\n\t" + "it lo\n\t" + "movlo %[r], r3\n\t" + "it ne\n\t" + "movne r3, r7\n\t" + "eor %[r], %[r], r3\n\t" + : [r] "+r" (r) + : [a] "r" (a), [b] "r" (b), [one] "r" (one) + : "r3", "r4", "r5", "r6", "r7" + ); +#endif + + return r; +} + +/* Divide d in a and put remainder into r (m*d + r = a) + * m is not calculated as it is not needed at this time. + * + * a Number to be divided. + * d Number to divide with. + * m Multiplier result. + * r Remainder from the division. + * returns MP_OKAY indicating success. + */ +static WC_INLINE int sp_1024_div_32(const sp_digit* a, const sp_digit* d, sp_digit* m, + sp_digit* r) +{ + sp_digit t1[64], t2[33]; + sp_digit div, r1; + int i; + + (void)m; + + + div = d[31]; + XMEMCPY(t1, a, sizeof(*t1) * 2 * 32); + for (i=31; i>=0; i--) { + sp_digit hi = t1[32 + i] - (t1[32 + i] == div); + r1 = div_1024_word_32(hi, t1[32 + i - 1], div); + + sp_1024_mul_d_32(t2, d, r1); + t1[32 + i] += sp_1024_sub_in_place_32(&t1[i], t2); + t1[32 + i] -= t2[32]; + sp_1024_mask_32(t2, d, t1[32 + i]); + t1[32 + i] += sp_1024_add_32(&t1[i], &t1[i], t2); + sp_1024_mask_32(t2, d, t1[32 + i]); + t1[32 + i] += sp_1024_add_32(&t1[i], &t1[i], t2); + } + + r1 = sp_1024_cmp_32(t1, d) >= 0; + sp_1024_cond_sub_32(r, t1, d, (sp_digit)0 - r1); + + return MP_OKAY; +} + +/* Reduce a modulo m into r. (r = a mod m) + * + * r A single precision number that is the reduced result. + * a A single precision number that is to be reduced. + * m A single precision number that is the modulus to reduce with. + * returns MP_OKAY indicating success. + */ +static WC_INLINE int sp_1024_mod_32(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + return sp_1024_div_32(a, m, NULL, r); +} + +/* Multiply a number by Montogmery normalizer mod modulus (prime). + * + * r The resulting Montgomery form number. + * a The number to convert. + * m The modulus (prime). + * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. + */ +static int sp_1024_mod_mul_norm_32(sp_digit* r, const sp_digit* a, + const sp_digit* m) +{ + sp_1024_mul_32(r, a, p1024_norm_mod); + return sp_1024_mod_32(r, r, m); +} + +/* Create a new point. + * + * heap [in] Buffer to allocate dynamic memory from. + * sp [in] Data for point - only if not allocating. + * p [out] New point. + * returns MEMORY_E when dynamic memory allocation fails and 0 otherwise. + */ +static int sp_1024_point_new_ex_32(void* heap, sp_point_1024* sp, + sp_point_1024** p) +{ + int ret = MP_OKAY; + (void)heap; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + (void)sp; + *p = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024), heap, DYNAMIC_TYPE_ECC); +#else + *p = sp; +#endif + if (*p == NULL) { + ret = MEMORY_E; + } + return ret; +} + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* Allocate memory for point and return error. */ +#define sp_1024_point_new_32(heap, sp, p) sp_1024_point_new_ex_32((heap), NULL, &(p)) +#else +/* Set pointer to data and return no error. */ +#define sp_1024_point_new_32(heap, sp, p) sp_1024_point_new_ex_32((heap), &(sp), &(p)) +#endif + + +/* Free the point. + * + * p [in,out] Point to free. + * clear [in] Indicates whether to zeroize point. + * heap [in] Buffer from which dynamic memory was allocate from. + */ +static void sp_1024_point_free_32(sp_point_1024* p, int clear, void* heap) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* If valid pointer then clear point data if requested and free data. */ + if (p != NULL) { + if (clear != 0) { + XMEMSET(p, 0, sizeof(*p)); + } + XFREE(p, heap, DYNAMIC_TYPE_ECC); + } +#else +/* Clear point data if requested. */ + if ((p != NULL) && (clear != 0)) { + XMEMSET(p, 0, sizeof(*p)); + } +#endif + (void)heap; +} + +/* Convert an mp_int to an array of sp_digit. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a A multi-precision integer. + */ +static void sp_1024_from_mp(sp_digit* r, int size, const mp_int* a) +{ +#if DIGIT_BIT == 32 + int j; + + XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); + + for (j = a->used; j < size; j++) { + r[j] = 0; + } +#elif DIGIT_BIT > 32 + int i; + int j = 0; + word32 s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i] << s); + r[j] &= 0xffffffff; + s = 32U - s; + if (j + 1 >= size) { + break; + } + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + while ((s + 32U) <= (word32)DIGIT_BIT) { + s += 32U; + r[j] &= 0xffffffff; + if (j + 1 >= size) { + break; + } + if (s < (word32)DIGIT_BIT) { + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + } + else { + r[++j] = 0L; + } + } + s = (word32)DIGIT_BIT - s; + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#else + int i; + int j = 0; + int s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i]) << s; + if (s + DIGIT_BIT >= 32) { + r[j] &= 0xffffffff; + if (j + 1 >= size) { + break; + } + s = 32 - s; + if (s == DIGIT_BIT) { + r[++j] = 0; + s = 0; + } + else { + r[++j] = a->dp[i] >> s; + s = DIGIT_BIT - s; + } + } + else { + s += DIGIT_BIT; + } + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#endif +} + +/* Convert a point of type ecc_point to type sp_point_1024. + * + * p Point of type sp_point_1024 (result). + * pm Point of type ecc_point. + */ +static void sp_1024_point_from_ecc_point_32(sp_point_1024* p, + const ecc_point* pm) +{ + XMEMSET(p->x, 0, sizeof(p->x)); + XMEMSET(p->y, 0, sizeof(p->y)); + XMEMSET(p->z, 0, sizeof(p->z)); + sp_1024_from_mp(p->x, 32, pm->x); + sp_1024_from_mp(p->y, 32, pm->y); + sp_1024_from_mp(p->z, 32, pm->z); + p->infinity = 0; +} + +/* Convert an array of sp_digit to an mp_int. + * + * a A single precision integer. + * r A multi-precision integer. + */ +static int sp_1024_to_mp(const sp_digit* a, mp_int* r) +{ + int err; + + err = mp_grow(r, (1024 + DIGIT_BIT - 1) / DIGIT_BIT); + if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ +#if DIGIT_BIT == 32 + XMEMCPY(r->dp, a, sizeof(sp_digit) * 32); + r->used = 32; + mp_clamp(r); +#elif DIGIT_BIT < 32 + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 32; i++) { + r->dp[j] |= (mp_digit)(a[i] << s); + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + s = DIGIT_BIT - s; + r->dp[++j] = (mp_digit)(a[i] >> s); + while (s + DIGIT_BIT <= 32) { + s += DIGIT_BIT; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; + if (s == SP_WORD_SIZE) { + r->dp[j] = 0; + } + else { + r->dp[j] = (mp_digit)(a[i] >> s); + } + } + s = 32 - s; + } + r->used = (1024 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#else + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 32; i++) { + r->dp[j] |= ((mp_digit)a[i]) << s; + if (s + 32 >= DIGIT_BIT) { + #if DIGIT_BIT != 32 && DIGIT_BIT != 64 + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + #endif + s = DIGIT_BIT - s; + r->dp[++j] = a[i] >> s; + s = 32 - s; + } + else { + s += 32; + } + } + r->used = (1024 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#endif + } + + return err; +} + +/* Convert a point of type sp_point_1024 to type ecc_point. + * + * p Point of type sp_point_1024. + * pm Point of type ecc_point (result). + * returns MEMORY_E when allocation of memory in ecc_point fails otherwise + * MP_OKAY. + */ +static int sp_1024_point_to_ecc_point_32(const sp_point_1024* p, ecc_point* pm) +{ + int err; + + err = sp_1024_to_mp(p->x, pm->x); + if (err == MP_OKAY) { + err = sp_1024_to_mp(p->y, pm->y); + } + if (err == MP_OKAY) { + err = sp_1024_to_mp(p->z, pm->z); + } + + return err; +} + +/* Reduce the number back to 1024 bits using Montgomery reduction. + * + * a A single precision number to reduce in place. + * m The single precision number representing the modulus. + * mp The digit representing the negative inverse of m mod 2^n. + */ +SP_NOINLINE static void sp_1024_mont_reduce_32(sp_digit* a, const sp_digit* m, + sp_digit mp) +{ + sp_digit ca = 0; + + __asm__ __volatile__ ( + "ldr r11, [%[m], #0]\n\t" + "# i = 0\n\t" + "mov r12, #0\n\t" + "ldr r10, [%[a], #0]\n\t" + "ldr r14, [%[a], #4]\n\t" + "\n1:\n\t" + "# mu = a[i] * mp\n\t" + "mul r8, %[mp], r10\n\t" + "# a[i+0] += m[0] * mu\n\t" + "ldr r9, [%[a], #0]\n\t" + "umull r6, r7, r8, r11\n\t" + "adds r10, r10, r6\n\t" + "adc r5, r7, #0\n\t" + "# a[i+1] += m[1] * mu\n\t" + "ldr r7, [%[m], #4]\n\t" + "ldr r9, [%[a], #4]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r10, r14, r6\n\t" + "adc r4, r7, #0\n\t" + "adds r10, r10, r5\n\t" + "adc r4, r4, #0\n\t" + "# a[i+2] += m[2] * mu\n\t" + "ldr r7, [%[m], #8]\n\t" + "ldr r14, [%[a], #8]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r14, r14, r6\n\t" + "adc r5, r7, #0\n\t" + "adds r14, r14, r4\n\t" + "adc r5, r5, #0\n\t" + "# a[i+3] += m[3] * mu\n\t" + "ldr r7, [%[m], #12]\n\t" + "ldr r9, [%[a], #12]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r4, r7, #0\n\t" + "adds r9, r9, r5\n\t" + "str r9, [%[a], #12]\n\t" + "adc r4, r4, #0\n\t" + "# a[i+4] += m[4] * mu\n\t" + "ldr r7, [%[m], #16]\n\t" + "ldr r9, [%[a], #16]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r5, r7, #0\n\t" + "adds r9, r9, r4\n\t" + "str r9, [%[a], #16]\n\t" + "adc r5, r5, #0\n\t" + "# a[i+5] += m[5] * mu\n\t" + "ldr r7, [%[m], #20]\n\t" + "ldr r9, [%[a], #20]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r4, r7, #0\n\t" + "adds r9, r9, r5\n\t" + "str r9, [%[a], #20]\n\t" + "adc r4, r4, #0\n\t" + "# a[i+6] += m[6] * mu\n\t" + "ldr r7, [%[m], #24]\n\t" + "ldr r9, [%[a], #24]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r5, r7, #0\n\t" + "adds r9, r9, r4\n\t" + "str r9, [%[a], #24]\n\t" + "adc r5, r5, #0\n\t" + "# a[i+7] += m[7] * mu\n\t" + "ldr r7, [%[m], #28]\n\t" + "ldr r9, [%[a], #28]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r4, r7, #0\n\t" + "adds r9, r9, r5\n\t" + "str r9, [%[a], #28]\n\t" + "adc r4, r4, #0\n\t" + "# a[i+8] += m[8] * mu\n\t" + "ldr r7, [%[m], #32]\n\t" + "ldr r9, [%[a], #32]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r5, r7, #0\n\t" + "adds r9, r9, r4\n\t" + "str r9, [%[a], #32]\n\t" + "adc r5, r5, #0\n\t" + "# a[i+9] += m[9] * mu\n\t" + "ldr r7, [%[m], #36]\n\t" + "ldr r9, [%[a], #36]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r4, r7, #0\n\t" + "adds r9, r9, r5\n\t" + "str r9, [%[a], #36]\n\t" + "adc r4, r4, #0\n\t" + "# a[i+10] += m[10] * mu\n\t" + "ldr r7, [%[m], #40]\n\t" + "ldr r9, [%[a], #40]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r5, r7, #0\n\t" + "adds r9, r9, r4\n\t" + "str r9, [%[a], #40]\n\t" + "adc r5, r5, #0\n\t" + "# a[i+11] += m[11] * mu\n\t" + "ldr r7, [%[m], #44]\n\t" + "ldr r9, [%[a], #44]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r4, r7, #0\n\t" + "adds r9, r9, r5\n\t" + "str r9, [%[a], #44]\n\t" + "adc r4, r4, #0\n\t" + "# a[i+12] += m[12] * mu\n\t" + "ldr r7, [%[m], #48]\n\t" + "ldr r9, [%[a], #48]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r5, r7, #0\n\t" + "adds r9, r9, r4\n\t" + "str r9, [%[a], #48]\n\t" + "adc r5, r5, #0\n\t" + "# a[i+13] += m[13] * mu\n\t" + "ldr r7, [%[m], #52]\n\t" + "ldr r9, [%[a], #52]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r4, r7, #0\n\t" + "adds r9, r9, r5\n\t" + "str r9, [%[a], #52]\n\t" + "adc r4, r4, #0\n\t" + "# a[i+14] += m[14] * mu\n\t" + "ldr r7, [%[m], #56]\n\t" + "ldr r9, [%[a], #56]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r5, r7, #0\n\t" + "adds r9, r9, r4\n\t" + "str r9, [%[a], #56]\n\t" + "adc r5, r5, #0\n\t" + "# a[i+15] += m[15] * mu\n\t" + "ldr r7, [%[m], #60]\n\t" + "ldr r9, [%[a], #60]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r4, r7, #0\n\t" + "adds r9, r9, r5\n\t" + "str r9, [%[a], #60]\n\t" + "adc r4, r4, #0\n\t" + "# a[i+16] += m[16] * mu\n\t" + "ldr r7, [%[m], #64]\n\t" + "ldr r9, [%[a], #64]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r5, r7, #0\n\t" + "adds r9, r9, r4\n\t" + "str r9, [%[a], #64]\n\t" + "adc r5, r5, #0\n\t" + "# a[i+17] += m[17] * mu\n\t" + "ldr r7, [%[m], #68]\n\t" + "ldr r9, [%[a], #68]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r4, r7, #0\n\t" + "adds r9, r9, r5\n\t" + "str r9, [%[a], #68]\n\t" + "adc r4, r4, #0\n\t" + "# a[i+18] += m[18] * mu\n\t" + "ldr r7, [%[m], #72]\n\t" + "ldr r9, [%[a], #72]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r5, r7, #0\n\t" + "adds r9, r9, r4\n\t" + "str r9, [%[a], #72]\n\t" + "adc r5, r5, #0\n\t" + "# a[i+19] += m[19] * mu\n\t" + "ldr r7, [%[m], #76]\n\t" + "ldr r9, [%[a], #76]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r4, r7, #0\n\t" + "adds r9, r9, r5\n\t" + "str r9, [%[a], #76]\n\t" + "adc r4, r4, #0\n\t" + "# a[i+20] += m[20] * mu\n\t" + "ldr r7, [%[m], #80]\n\t" + "ldr r9, [%[a], #80]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r5, r7, #0\n\t" + "adds r9, r9, r4\n\t" + "str r9, [%[a], #80]\n\t" + "adc r5, r5, #0\n\t" + "# a[i+21] += m[21] * mu\n\t" + "ldr r7, [%[m], #84]\n\t" + "ldr r9, [%[a], #84]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r4, r7, #0\n\t" + "adds r9, r9, r5\n\t" + "str r9, [%[a], #84]\n\t" + "adc r4, r4, #0\n\t" + "# a[i+22] += m[22] * mu\n\t" + "ldr r7, [%[m], #88]\n\t" + "ldr r9, [%[a], #88]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r5, r7, #0\n\t" + "adds r9, r9, r4\n\t" + "str r9, [%[a], #88]\n\t" + "adc r5, r5, #0\n\t" + "# a[i+23] += m[23] * mu\n\t" + "ldr r7, [%[m], #92]\n\t" + "ldr r9, [%[a], #92]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r4, r7, #0\n\t" + "adds r9, r9, r5\n\t" + "str r9, [%[a], #92]\n\t" + "adc r4, r4, #0\n\t" + "# a[i+24] += m[24] * mu\n\t" + "ldr r7, [%[m], #96]\n\t" + "ldr r9, [%[a], #96]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r5, r7, #0\n\t" + "adds r9, r9, r4\n\t" + "str r9, [%[a], #96]\n\t" + "adc r5, r5, #0\n\t" + "# a[i+25] += m[25] * mu\n\t" + "ldr r7, [%[m], #100]\n\t" + "ldr r9, [%[a], #100]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r4, r7, #0\n\t" + "adds r9, r9, r5\n\t" + "str r9, [%[a], #100]\n\t" + "adc r4, r4, #0\n\t" + "# a[i+26] += m[26] * mu\n\t" + "ldr r7, [%[m], #104]\n\t" + "ldr r9, [%[a], #104]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r5, r7, #0\n\t" + "adds r9, r9, r4\n\t" + "str r9, [%[a], #104]\n\t" + "adc r5, r5, #0\n\t" + "# a[i+27] += m[27] * mu\n\t" + "ldr r7, [%[m], #108]\n\t" + "ldr r9, [%[a], #108]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r4, r7, #0\n\t" + "adds r9, r9, r5\n\t" + "str r9, [%[a], #108]\n\t" + "adc r4, r4, #0\n\t" + "# a[i+28] += m[28] * mu\n\t" + "ldr r7, [%[m], #112]\n\t" + "ldr r9, [%[a], #112]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r5, r7, #0\n\t" + "adds r9, r9, r4\n\t" + "str r9, [%[a], #112]\n\t" + "adc r5, r5, #0\n\t" + "# a[i+29] += m[29] * mu\n\t" + "ldr r7, [%[m], #116]\n\t" + "ldr r9, [%[a], #116]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r4, r7, #0\n\t" + "adds r9, r9, r5\n\t" + "str r9, [%[a], #116]\n\t" + "adc r4, r4, #0\n\t" + "# a[i+30] += m[30] * mu\n\t" + "ldr r7, [%[m], #120]\n\t" + "ldr r9, [%[a], #120]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r9, r9, r6\n\t" + "adc r5, r7, #0\n\t" + "adds r9, r9, r4\n\t" + "str r9, [%[a], #120]\n\t" + "adc r5, r5, #0\n\t" + "# a[i+31] += m[31] * mu\n\t" + "ldr r7, [%[m], #124]\n\t" + "ldr r9, [%[a], #124]\n\t" + "umull r6, r7, r8, r7\n\t" + "adds r5, r5, r6\n\t" + "adcs r7, r7, %[ca]\n\t" + "mov %[ca], #0\n\t" + "adc %[ca], %[ca], %[ca]\n\t" + "adds r9, r9, r5\n\t" + "str r9, [%[a], #124]\n\t" + "ldr r9, [%[a], #128]\n\t" + "adcs r9, r9, r7\n\t" + "str r9, [%[a], #128]\n\t" + "adc %[ca], %[ca], #0\n\t" + "# i += 1\n\t" + "add %[a], %[a], #4\n\t" + "add r12, r12, #4\n\t" + "cmp r12, #128\n\t" + "blt 1b\n\t" + "str r10, [%[a], #0]\n\t" + "str r14, [%[a], #4]\n\t" + "ldr r6, [%[m], #124]\n\t" + "subs r9, r6, r9\n\t" + "neg %[ca], %[ca]\n\t" + "sbc r9, r9, r9\n\t" + "orr %[ca], %[ca], r9\n\t" + : [ca] "+r" (ca), [a] "+r" (a) + : [m] "r" (m), [mp] "r" (mp) + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12", "r11" + ); + + sp_1024_cond_sub_32(a - 32, a, m, ca); +} + +/* Multiply two Montogmery form numbers mod the modulus (prime). + * (r = a * b mod m) + * + * r Result of multiplication. + * a First number to multiply in Montogmery form. + * b Second number to multiply in Montogmery form. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_1024_mont_mul_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) +{ + sp_1024_mul_32(r, a, b); + sp_1024_mont_reduce_32(r, m, mp); +} + +/* Square the Montgomery form number. (r = a * a mod m) + * + * r Result of squaring. + * a Number to square in Montogmery form. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_1024_mont_sqr_32(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) +{ + sp_1024_sqr_32(r, a); + sp_1024_mont_reduce_32(r, m, mp); +} + +/* Mod-2 for the P1024 curve. */ +static const uint8_t p1024_mod_minus_2[] = { + 6,0x06, 7,0x0f, 7,0x0b, 6,0x0c, 7,0x1e, 9,0x09, 7,0x0c, 7,0x1f, + 6,0x16, 6,0x06, 7,0x0e, 8,0x10, 6,0x03, 8,0x11, 6,0x0d, 7,0x14, + 9,0x12, 6,0x0f, 7,0x04, 9,0x0d, 6,0x00, 7,0x13, 6,0x01, 6,0x07, + 8,0x0d, 8,0x00, 6,0x06, 9,0x17, 6,0x14, 6,0x15, 6,0x11, 6,0x0b, + 9,0x0c, 6,0x1e, 13,0x14, 7,0x0e, 6,0x1d, 12,0x0a, 6,0x0b, 8,0x07, + 6,0x18, 6,0x0f, 6,0x10, 8,0x1c, 7,0x16, 7,0x02, 6,0x01, 6,0x13, + 10,0x15, 7,0x06, 8,0x14, 6,0x0c, 6,0x19, 7,0x10, 6,0x19, 6,0x19, + 9,0x16, 7,0x19, 6,0x1f, 6,0x17, 6,0x12, 8,0x02, 6,0x01, 6,0x04, + 6,0x15, 7,0x16, 6,0x04, 6,0x1f, 6,0x09, 7,0x06, 7,0x13, 7,0x09, + 6,0x0d, 10,0x18, 6,0x06, 6,0x11, 6,0x04, 6,0x01, 6,0x13, 8,0x06, + 6,0x0d, 8,0x13, 7,0x08, 6,0x08, 6,0x05, 7,0x0c, 7,0x0e, 7,0x15, + 6,0x05, 7,0x14, 10,0x19, 6,0x10, 6,0x16, 6,0x15, 7,0x1f, 6,0x14, + 6,0x0a, 10,0x11, 6,0x01, 7,0x05, 7,0x08, 8,0x0a, 7,0x1e, 7,0x1c, + 6,0x1c, 7,0x09, 10,0x18, 7,0x1c, 10,0x06, 6,0x0a, 6,0x07, 6,0x19, + 7,0x06, 6,0x0d, 7,0x0f, 7,0x0b, 7,0x05, 6,0x11, 6,0x1c, 7,0x1f, + 6,0x1e, 7,0x18, 6,0x1e, 6,0x00, 6,0x03, 6,0x02, 7,0x10, 6,0x0b, + 6,0x1b, 7,0x10, 6,0x00, 8,0x11, 7,0x1b, 6,0x18, 6,0x01, 7,0x0c, + 7,0x1d, 7,0x13, 6,0x08, 7,0x1b, 8,0x13, 7,0x16, 13,0x1d, 7,0x1f, + 6,0x0a, 6,0x01, 7,0x1f, 6,0x14, 1,0x01 +}; + +/* Invert the number, in Montgomery form, modulo the modulus (prime) of the + * P1024 curve. (r = 1 / a mod m) + * + * r Inverse result. + * a Number to invert. + * td Temporary data. + */ +static void sp_1024_mont_inv_32(sp_digit* r, const sp_digit* a, + sp_digit* td) +{ + sp_digit* t = td; + int i; + int j; + sp_digit table[32][2 * 32]; + + XMEMCPY(table[0], a, sizeof(sp_digit) * 32); + for (i = 1; i < 6; i++) { + sp_1024_mont_sqr_32(table[0], table[0], p1024_mod, p1024_mp_mod); + } + for (i = 1; i < 32; i++) { + sp_1024_mont_mul_32(table[i], table[i-1], a, p1024_mod, p1024_mp_mod); + } + + XMEMCPY(t, table[p1024_mod_minus_2[1]], sizeof(sp_digit) * 32); + for (i = 2; i < (int)sizeof(p1024_mod_minus_2) - 2; i += 2) { + for (j = 0; j < p1024_mod_minus_2[i]; j++) { + sp_1024_mont_sqr_32(t, t, p1024_mod, p1024_mp_mod); + } + sp_1024_mont_mul_32(t, t, table[p1024_mod_minus_2[i+1]], p1024_mod, + p1024_mp_mod); + } + sp_1024_mont_sqr_32(t, t, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(r, t, a, p1024_mod, p1024_mp_mod); +} + +/* Normalize the values in each word to 32. + * + * a Array of sp_digit to normalize. + */ +#define sp_1024_norm_32(a) + +/* Map the Montgomery form projective coordinate point to an affine point. + * + * r Resulting affine coordinate point. + * p Montgomery form projective coordinate point. + * t Temporary ordinate data. + */ +static void sp_1024_map_32(sp_point_1024* r, const sp_point_1024* p, + sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*32; + int32_t n; + + sp_1024_mont_inv_32(t1, p->z, t + 2*32); + + sp_1024_mont_sqr_32(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t1, t2, t1, p1024_mod, p1024_mp_mod); + + /* x /= z^2 */ + sp_1024_mont_mul_32(r->x, p->x, t2, p1024_mod, p1024_mp_mod); + XMEMSET(r->x + 32, 0, sizeof(r->x) / 2U); + sp_1024_mont_reduce_32(r->x, p1024_mod, p1024_mp_mod); + /* Reduce x to less than modulus */ + n = sp_1024_cmp_32(r->x, p1024_mod); + sp_1024_cond_sub_32(r->x, r->x, p1024_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_32(r->x); + + /* y /= z^3 */ + sp_1024_mont_mul_32(r->y, p->y, t1, p1024_mod, p1024_mp_mod); + XMEMSET(r->y + 32, 0, sizeof(r->y) / 2U); + sp_1024_mont_reduce_32(r->y, p1024_mod, p1024_mp_mod); + /* Reduce y to less than modulus */ + n = sp_1024_cmp_32(r->y, p1024_mod); + sp_1024_cond_sub_32(r->y, r->y, p1024_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_32(r->y); + + XMEMSET(r->z, 0, sizeof(r->z)); + r->z[0] = 1; + +} + +/* Add two Montgomery form numbers (r = a + b % m). + * + * r Result of addition. + * a First number to add in Montogmery form. + * b Second number to add in Montogmery form. + * m Modulus (prime). + */ +static void sp_1024_mont_add_32(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + __asm__ __volatile__ ( + "mov r12, #0\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "adds r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldr r14, [%[m], #124]\n\t" + "adc r12, r12, #0\n\t" + "subs r14, r14, r7\n\t" + "neg r12, r12\n\t" + "sbc r14, r14, r14\n\t" + "sub %[r], %[r], #128\n\t" + "orr r12, r14\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "subs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbc r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "sub %[r], %[r], #128\n\t" + : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) + : + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + ); +} + +/* Double a Montgomery form number (r = a + a % m). + * + * r Result of doubling. + * a Number to double in Montogmery form. + * m Modulus (prime). + */ +static void sp_1024_mont_dbl_32(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + __asm__ __volatile__ ( + "mov r12, #0\n\t" + "ldm %[a]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "adds r4, r4, r4\n\t" + "adcs r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adcs r7, r7, r7\n\t" + "adcs r8, r8, r8\n\t" + "adcs r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adcs r14, r14, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "adcs r4, r4, r4\n\t" + "adcs r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adcs r7, r7, r7\n\t" + "adcs r8, r8, r8\n\t" + "adcs r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adcs r14, r14, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "adcs r4, r4, r4\n\t" + "adcs r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adcs r7, r7, r7\n\t" + "adcs r8, r8, r8\n\t" + "adcs r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adcs r14, r14, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "adcs r4, r4, r4\n\t" + "adcs r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adcs r7, r7, r7\n\t" + "adcs r8, r8, r8\n\t" + "adcs r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adcs r14, r14, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "ldr r4, [%[m], #124]\n\t" + "adc r12, r12, #0\n\t" + "subs r4, r4, r14\n\t" + "neg r12, r12\n\t" + "sbc r4, r4, r4\n\t" + "sub %[r], %[r], #128\n\t" + "orr r12, r4\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "subs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbc r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "sub %[r], %[r], #128\n\t" + : [r] "+r" (r), [a] "+r" (a), [m] "+r" (m) + : + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + ); +} + +/* Triple a Montgomery form number (r = a + a + a % m). + * + * r Result of Tripling. + * a Number to triple in Montogmery form. + * m Modulus (prime). + */ +static void sp_1024_mont_tpl_32(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + __asm__ __volatile__ ( + "mov r12, #0\n\t" + "ldm %[a]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "adds r4, r4, r4\n\t" + "adcs r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adcs r7, r7, r7\n\t" + "adcs r8, r8, r8\n\t" + "adcs r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adcs r14, r14, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "adcs r4, r4, r4\n\t" + "adcs r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adcs r7, r7, r7\n\t" + "adcs r8, r8, r8\n\t" + "adcs r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adcs r14, r14, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "adcs r4, r4, r4\n\t" + "adcs r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adcs r7, r7, r7\n\t" + "adcs r8, r8, r8\n\t" + "adcs r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adcs r14, r14, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "adcs r4, r4, r4\n\t" + "adcs r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adcs r7, r7, r7\n\t" + "adcs r8, r8, r8\n\t" + "adcs r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adcs r14, r14, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "ldr r4, [%[m], #124]\n\t" + "adc r12, r12, #0\n\t" + "subs r4, r4, r14\n\t" + "neg r12, r12\n\t" + "sbc r4, r4, r4\n\t" + "sub %[r], %[r], #128\n\t" + "orr r12, r4\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "subs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbc r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "sub %[r], %[r], #128\n\t" + "sub %[m], %[m], #128\n\t" + "sub %[a], %[a], #128\n\t" + "mov r12, #0\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "adds r8, r8, r4\n\t" + "adcs r9, r9, r5\n\t" + "adcs r10, r10, r6\n\t" + "adcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "adcs r8, r8, r4\n\t" + "adcs r9, r9, r5\n\t" + "adcs r10, r10, r6\n\t" + "adcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "adcs r8, r8, r4\n\t" + "adcs r9, r9, r5\n\t" + "adcs r10, r10, r6\n\t" + "adcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "adcs r8, r8, r4\n\t" + "adcs r9, r9, r5\n\t" + "adcs r10, r10, r6\n\t" + "adcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "adcs r8, r8, r4\n\t" + "adcs r9, r9, r5\n\t" + "adcs r10, r10, r6\n\t" + "adcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "adcs r8, r8, r4\n\t" + "adcs r9, r9, r5\n\t" + "adcs r10, r10, r6\n\t" + "adcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "adcs r8, r8, r4\n\t" + "adcs r9, r9, r5\n\t" + "adcs r10, r10, r6\n\t" + "adcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "adcs r8, r8, r4\n\t" + "adcs r9, r9, r5\n\t" + "adcs r10, r10, r6\n\t" + "adcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldr r7, [%[m], #124]\n\t" + "adc r12, r12, #0\n\t" + "subs r7, r7, r14\n\t" + "neg r12, r12\n\t" + "sbc r7, r7, r7\n\t" + "sub %[r], %[r], #128\n\t" + "orr r12, r7\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "ldm %[m]!, {r4, r5, r6, r7}\n\t" + "and r4, r4, r12\n\t" + "and r5, r5, r12\n\t" + "and r6, r6, r12\n\t" + "and r7, r7, r12\n\t" + "subs r8, r8, r4\n\t" + "sbcs r9, r9, r5\n\t" + "sbcs r10, r10, r6\n\t" + "sbcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "ldm %[m]!, {r4, r5, r6, r7}\n\t" + "and r4, r4, r12\n\t" + "and r5, r5, r12\n\t" + "and r6, r6, r12\n\t" + "and r7, r7, r12\n\t" + "sbcs r8, r8, r4\n\t" + "sbcs r9, r9, r5\n\t" + "sbcs r10, r10, r6\n\t" + "sbcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "ldm %[m]!, {r4, r5, r6, r7}\n\t" + "and r4, r4, r12\n\t" + "and r5, r5, r12\n\t" + "and r6, r6, r12\n\t" + "and r7, r7, r12\n\t" + "sbcs r8, r8, r4\n\t" + "sbcs r9, r9, r5\n\t" + "sbcs r10, r10, r6\n\t" + "sbcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "ldm %[m]!, {r4, r5, r6, r7}\n\t" + "and r4, r4, r12\n\t" + "and r5, r5, r12\n\t" + "and r6, r6, r12\n\t" + "and r7, r7, r12\n\t" + "sbcs r8, r8, r4\n\t" + "sbcs r9, r9, r5\n\t" + "sbcs r10, r10, r6\n\t" + "sbcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "ldm %[m]!, {r4, r5, r6, r7}\n\t" + "and r4, r4, r12\n\t" + "and r5, r5, r12\n\t" + "and r6, r6, r12\n\t" + "and r7, r7, r12\n\t" + "sbcs r8, r8, r4\n\t" + "sbcs r9, r9, r5\n\t" + "sbcs r10, r10, r6\n\t" + "sbcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "ldm %[m]!, {r4, r5, r6, r7}\n\t" + "and r4, r4, r12\n\t" + "and r5, r5, r12\n\t" + "and r6, r6, r12\n\t" + "and r7, r7, r12\n\t" + "sbcs r8, r8, r4\n\t" + "sbcs r9, r9, r5\n\t" + "sbcs r10, r10, r6\n\t" + "sbcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "ldm %[m]!, {r4, r5, r6, r7}\n\t" + "and r4, r4, r12\n\t" + "and r5, r5, r12\n\t" + "and r6, r6, r12\n\t" + "and r7, r7, r12\n\t" + "sbcs r8, r8, r4\n\t" + "sbcs r9, r9, r5\n\t" + "sbcs r10, r10, r6\n\t" + "sbcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "ldm %[m]!, {r4, r5, r6, r7}\n\t" + "and r4, r4, r12\n\t" + "and r5, r5, r12\n\t" + "and r6, r6, r12\n\t" + "and r7, r7, r12\n\t" + "sbcs r8, r8, r4\n\t" + "sbcs r9, r9, r5\n\t" + "sbcs r10, r10, r6\n\t" + "sbc r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "sub %[r], %[r], #128\n\t" + : [r] "+r" (r), [a] "+r" (a), [m] "+r" (m) + : + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + ); +} + +/* Subtract two Montgomery form numbers (r = a - b % m). + * + * r Result of subtration. + * a Number to subtract from in Montogmery form. + * b Number to subtract with in Montogmery form. + * m Modulus (prime). + */ +static void sp_1024_mont_sub_32(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + __asm__ __volatile__ ( + "mov r12, #0\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "subs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "sbc r12, r12, r12\n\t" + "sub %[r], %[r], #128\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "adds r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adc r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "sub %[r], %[r], #128\n\t" + : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) + : + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + ); +} + +/* Conditionally add a and b using the mask m. + * m is -1 to add and 0 when not. + * + * r A single precision number representing conditional add result. + * a A single precision number to add with. + * b A single precision number to add. + * m Mask value to apply. + */ +static sp_digit sp_1024_cond_add_32(sp_digit* r, const sp_digit* a, const sp_digit* b, + sp_digit m) +{ + sp_digit c = 0; + +#ifdef WOLFSSL_SP_SMALL + __asm__ __volatile__ ( + "mov r9, #0\n\t" + "mov r8, #0\n\t" + "1:\n\t" + "adds %[c], %[c], #-1\n\t" + "ldr r4, [%[a], r8]\n\t" + "ldr r5, [%[b], r8]\n\t" + "and r5, r5, %[m]\n\t" + "adcs r4, r4, r5\n\t" + "adc %[c], r9, r9\n\t" + "str r4, [%[r], r8]\n\t" + "add r8, r8, #4\n\t" + "cmp r8, #128\n\t" + "blt 1b\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "r4", "r6", "r5", "r7", "r8", "r9" + ); +#else + __asm__ __volatile__ ( + + "mov r9, #0\n\t" + "ldr r4, [%[a], #0]\n\t" + "ldr r6, [%[a], #4]\n\t" + "ldr r5, [%[b], #0]\n\t" + "ldr r7, [%[b], #4]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "adds r4, r4, r5\n\t" + "adcs r6, r6, r7\n\t" + "str r4, [%[r], #0]\n\t" + "str r6, [%[r], #4]\n\t" + "ldr r4, [%[a], #8]\n\t" + "ldr r6, [%[a], #12]\n\t" + "ldr r5, [%[b], #8]\n\t" + "ldr r7, [%[b], #12]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "adcs r4, r4, r5\n\t" + "adcs r6, r6, r7\n\t" + "str r4, [%[r], #8]\n\t" + "str r6, [%[r], #12]\n\t" + "ldr r4, [%[a], #16]\n\t" + "ldr r6, [%[a], #20]\n\t" + "ldr r5, [%[b], #16]\n\t" + "ldr r7, [%[b], #20]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "adcs r4, r4, r5\n\t" + "adcs r6, r6, r7\n\t" + "str r4, [%[r], #16]\n\t" + "str r6, [%[r], #20]\n\t" + "ldr r4, [%[a], #24]\n\t" + "ldr r6, [%[a], #28]\n\t" + "ldr r5, [%[b], #24]\n\t" + "ldr r7, [%[b], #28]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "adcs r4, r4, r5\n\t" + "adcs r6, r6, r7\n\t" + "str r4, [%[r], #24]\n\t" + "str r6, [%[r], #28]\n\t" + "ldr r4, [%[a], #32]\n\t" + "ldr r6, [%[a], #36]\n\t" + "ldr r5, [%[b], #32]\n\t" + "ldr r7, [%[b], #36]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "adcs r4, r4, r5\n\t" + "adcs r6, r6, r7\n\t" + "str r4, [%[r], #32]\n\t" + "str r6, [%[r], #36]\n\t" + "ldr r4, [%[a], #40]\n\t" + "ldr r6, [%[a], #44]\n\t" + "ldr r5, [%[b], #40]\n\t" + "ldr r7, [%[b], #44]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "adcs r4, r4, r5\n\t" + "adcs r6, r6, r7\n\t" + "str r4, [%[r], #40]\n\t" + "str r6, [%[r], #44]\n\t" + "ldr r4, [%[a], #48]\n\t" + "ldr r6, [%[a], #52]\n\t" + "ldr r5, [%[b], #48]\n\t" + "ldr r7, [%[b], #52]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "adcs r4, r4, r5\n\t" + "adcs r6, r6, r7\n\t" + "str r4, [%[r], #48]\n\t" + "str r6, [%[r], #52]\n\t" + "ldr r4, [%[a], #56]\n\t" + "ldr r6, [%[a], #60]\n\t" + "ldr r5, [%[b], #56]\n\t" + "ldr r7, [%[b], #60]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "adcs r4, r4, r5\n\t" + "adcs r6, r6, r7\n\t" + "str r4, [%[r], #56]\n\t" + "str r6, [%[r], #60]\n\t" + "ldr r4, [%[a], #64]\n\t" + "ldr r6, [%[a], #68]\n\t" + "ldr r5, [%[b], #64]\n\t" + "ldr r7, [%[b], #68]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "adcs r4, r4, r5\n\t" + "adcs r6, r6, r7\n\t" + "str r4, [%[r], #64]\n\t" + "str r6, [%[r], #68]\n\t" + "ldr r4, [%[a], #72]\n\t" + "ldr r6, [%[a], #76]\n\t" + "ldr r5, [%[b], #72]\n\t" + "ldr r7, [%[b], #76]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "adcs r4, r4, r5\n\t" + "adcs r6, r6, r7\n\t" + "str r4, [%[r], #72]\n\t" + "str r6, [%[r], #76]\n\t" + "ldr r4, [%[a], #80]\n\t" + "ldr r6, [%[a], #84]\n\t" + "ldr r5, [%[b], #80]\n\t" + "ldr r7, [%[b], #84]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "adcs r4, r4, r5\n\t" + "adcs r6, r6, r7\n\t" + "str r4, [%[r], #80]\n\t" + "str r6, [%[r], #84]\n\t" + "ldr r4, [%[a], #88]\n\t" + "ldr r6, [%[a], #92]\n\t" + "ldr r5, [%[b], #88]\n\t" + "ldr r7, [%[b], #92]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "adcs r4, r4, r5\n\t" + "adcs r6, r6, r7\n\t" + "str r4, [%[r], #88]\n\t" + "str r6, [%[r], #92]\n\t" + "ldr r4, [%[a], #96]\n\t" + "ldr r6, [%[a], #100]\n\t" + "ldr r5, [%[b], #96]\n\t" + "ldr r7, [%[b], #100]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "adcs r4, r4, r5\n\t" + "adcs r6, r6, r7\n\t" + "str r4, [%[r], #96]\n\t" + "str r6, [%[r], #100]\n\t" + "ldr r4, [%[a], #104]\n\t" + "ldr r6, [%[a], #108]\n\t" + "ldr r5, [%[b], #104]\n\t" + "ldr r7, [%[b], #108]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "adcs r4, r4, r5\n\t" + "adcs r6, r6, r7\n\t" + "str r4, [%[r], #104]\n\t" + "str r6, [%[r], #108]\n\t" + "ldr r4, [%[a], #112]\n\t" + "ldr r6, [%[a], #116]\n\t" + "ldr r5, [%[b], #112]\n\t" + "ldr r7, [%[b], #116]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "adcs r4, r4, r5\n\t" + "adcs r6, r6, r7\n\t" + "str r4, [%[r], #112]\n\t" + "str r6, [%[r], #116]\n\t" + "ldr r4, [%[a], #120]\n\t" + "ldr r6, [%[a], #124]\n\t" + "ldr r5, [%[b], #120]\n\t" + "ldr r7, [%[b], #124]\n\t" + "and r5, r5, %[m]\n\t" + "and r7, r7, %[m]\n\t" + "adcs r4, r4, r5\n\t" + "adcs r6, r6, r7\n\t" + "str r4, [%[r], #120]\n\t" + "str r6, [%[r], #124]\n\t" + "adc %[c], r9, r9\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "r4", "r6", "r5", "r7", "r8", "r9" + ); +#endif /* WOLFSSL_SP_SMALL */ + + return c; +} + +static void sp_1024_rshift1_32(sp_digit* r, sp_digit* a) +{ + __asm__ __volatile__ ( + "ldr r2, [%[a]]\n\t" + "ldr r3, [%[a], #4]\n\t" + "lsr r2, r2, #1\n\t" + "orr r2, r2, r3, lsl #31\n\t" + "lsr r3, r3, #1\n\t" + "ldr r4, [%[a], #8]\n\t" + "str r2, [%[r], #0]\n\t" + "orr r3, r3, r4, lsl #31\n\t" + "lsr r4, r4, #1\n\t" + "ldr r2, [%[a], #12]\n\t" + "str r3, [%[r], #4]\n\t" + "orr r4, r4, r2, lsl #31\n\t" + "lsr r2, r2, #1\n\t" + "ldr r3, [%[a], #16]\n\t" + "str r4, [%[r], #8]\n\t" + "orr r2, r2, r3, lsl #31\n\t" + "lsr r3, r3, #1\n\t" + "ldr r4, [%[a], #20]\n\t" + "str r2, [%[r], #12]\n\t" + "orr r3, r3, r4, lsl #31\n\t" + "lsr r4, r4, #1\n\t" + "ldr r2, [%[a], #24]\n\t" + "str r3, [%[r], #16]\n\t" + "orr r4, r4, r2, lsl #31\n\t" + "lsr r2, r2, #1\n\t" + "ldr r3, [%[a], #28]\n\t" + "str r4, [%[r], #20]\n\t" + "orr r2, r2, r3, lsl #31\n\t" + "lsr r3, r3, #1\n\t" + "ldr r4, [%[a], #32]\n\t" + "str r2, [%[r], #24]\n\t" + "orr r3, r3, r4, lsl #31\n\t" + "lsr r4, r4, #1\n\t" + "ldr r2, [%[a], #36]\n\t" + "str r3, [%[r], #28]\n\t" + "orr r4, r4, r2, lsl #31\n\t" + "lsr r2, r2, #1\n\t" + "ldr r3, [%[a], #40]\n\t" + "str r4, [%[r], #32]\n\t" + "orr r2, r2, r3, lsl #31\n\t" + "lsr r3, r3, #1\n\t" + "ldr r4, [%[a], #44]\n\t" + "str r2, [%[r], #36]\n\t" + "orr r3, r3, r4, lsl #31\n\t" + "lsr r4, r4, #1\n\t" + "ldr r2, [%[a], #48]\n\t" + "str r3, [%[r], #40]\n\t" + "orr r4, r4, r2, lsl #31\n\t" + "lsr r2, r2, #1\n\t" + "ldr r3, [%[a], #52]\n\t" + "str r4, [%[r], #44]\n\t" + "orr r2, r2, r3, lsl #31\n\t" + "lsr r3, r3, #1\n\t" + "ldr r4, [%[a], #56]\n\t" + "str r2, [%[r], #48]\n\t" + "orr r3, r3, r4, lsl #31\n\t" + "lsr r4, r4, #1\n\t" + "ldr r2, [%[a], #60]\n\t" + "str r3, [%[r], #52]\n\t" + "orr r4, r4, r2, lsl #31\n\t" + "lsr r2, r2, #1\n\t" + "ldr r3, [%[a], #64]\n\t" + "str r4, [%[r], #56]\n\t" + "orr r2, r2, r3, lsl #31\n\t" + "lsr r3, r3, #1\n\t" + "ldr r4, [%[a], #68]\n\t" + "str r2, [%[r], #60]\n\t" + "orr r3, r3, r4, lsl #31\n\t" + "lsr r4, r4, #1\n\t" + "ldr r2, [%[a], #72]\n\t" + "str r3, [%[r], #64]\n\t" + "orr r4, r4, r2, lsl #31\n\t" + "lsr r2, r2, #1\n\t" + "ldr r3, [%[a], #76]\n\t" + "str r4, [%[r], #68]\n\t" + "orr r2, r2, r3, lsl #31\n\t" + "lsr r3, r3, #1\n\t" + "ldr r4, [%[a], #80]\n\t" + "str r2, [%[r], #72]\n\t" + "orr r3, r3, r4, lsl #31\n\t" + "lsr r4, r4, #1\n\t" + "ldr r2, [%[a], #84]\n\t" + "str r3, [%[r], #76]\n\t" + "orr r4, r4, r2, lsl #31\n\t" + "lsr r2, r2, #1\n\t" + "ldr r3, [%[a], #88]\n\t" + "str r4, [%[r], #80]\n\t" + "orr r2, r2, r3, lsl #31\n\t" + "lsr r3, r3, #1\n\t" + "ldr r4, [%[a], #92]\n\t" + "str r2, [%[r], #84]\n\t" + "orr r3, r3, r4, lsl #31\n\t" + "lsr r4, r4, #1\n\t" + "ldr r2, [%[a], #96]\n\t" + "str r3, [%[r], #88]\n\t" + "orr r4, r4, r2, lsl #31\n\t" + "lsr r2, r2, #1\n\t" + "ldr r3, [%[a], #100]\n\t" + "str r4, [%[r], #92]\n\t" + "orr r2, r2, r3, lsl #31\n\t" + "lsr r3, r3, #1\n\t" + "ldr r4, [%[a], #104]\n\t" + "str r2, [%[r], #96]\n\t" + "orr r3, r3, r4, lsl #31\n\t" + "lsr r4, r4, #1\n\t" + "ldr r2, [%[a], #108]\n\t" + "str r3, [%[r], #100]\n\t" + "orr r4, r4, r2, lsl #31\n\t" + "lsr r2, r2, #1\n\t" + "ldr r3, [%[a], #112]\n\t" + "str r4, [%[r], #104]\n\t" + "orr r2, r2, r3, lsl #31\n\t" + "lsr r3, r3, #1\n\t" + "ldr r4, [%[a], #116]\n\t" + "str r2, [%[r], #108]\n\t" + "orr r3, r3, r4, lsl #31\n\t" + "lsr r4, r4, #1\n\t" + "ldr r2, [%[a], #120]\n\t" + "str r3, [%[r], #112]\n\t" + "orr r4, r4, r2, lsl #31\n\t" + "lsr r2, r2, #1\n\t" + "ldr r3, [%[a], #124]\n\t" + "str r4, [%[r], #116]\n\t" + "orr r2, r2, r3, lsl #31\n\t" + "lsr r3, r3, #1\n\t" + "str r2, [%[r], #120]\n\t" + "str r3, [%[r], #124]\n\t" + : + : [r] "r" (r), [a] "r" (a) + : "memory", "r2", "r3", "r4" + ); +} + +/* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m) + * + * r Result of division by 2. + * a Number to divide. + * m Modulus (prime). + */ +static void sp_1024_div2_32(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_digit o; + + o = sp_1024_cond_add_32(r, a, m, 0 - (a[0] & 1)); + sp_1024_rshift1_32(r, r); + r[31] |= o << 31; +} + +/* Double the Montgomery form projective point p. + * + * r Result of doubling point. + * p Point to double. + * t Temporary ordinate data. + */ +#ifdef WOLFSSL_SP_NONBLOCK +typedef struct sp_1024_proj_point_dbl_32_ctx { + int state; + sp_digit* t1; + sp_digit* t2; + sp_digit* x; + sp_digit* y; + sp_digit* z; +} sp_1024_proj_point_dbl_32_ctx; + +static int sp_1024_proj_point_dbl_32_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r, const sp_point_1024* p, sp_digit* t) +{ + int err = FP_WOULDBLOCK; + sp_1024_proj_point_dbl_32_ctx* ctx = (sp_1024_proj_point_dbl_32_ctx*)sp_ctx->data; + + typedef char ctx_size_test[sizeof(sp_1024_proj_point_dbl_32_ctx) >= sizeof(*sp_ctx) ? -1 : 1]; + (void)sizeof(ctx_size_test); + + switch (ctx->state) { + case 0: + ctx->t1 = t; + ctx->t2 = t + 2*32; + ctx->x = r->x; + ctx->y = r->y; + ctx->z = r->z; + + /* Put infinity into result. */ + if (r != p) { + r->infinity = p->infinity; + } + ctx->state = 1; + break; + case 1: + /* T1 = Z * Z */ + sp_1024_mont_sqr_32(ctx->t1, p->z, p1024_mod, p1024_mp_mod); + ctx->state = 2; + break; + case 2: + /* Z = Y * Z */ + sp_1024_mont_mul_32(ctx->z, p->y, p->z, p1024_mod, p1024_mp_mod); + ctx->state = 3; + break; + case 3: + /* Z = 2Z */ + sp_1024_mont_dbl_32(ctx->z, ctx->z, p1024_mod); + ctx->state = 4; + break; + case 4: + /* T2 = X - T1 */ + sp_1024_mont_sub_32(ctx->t2, p->x, ctx->t1, p1024_mod); + ctx->state = 5; + break; + case 5: + /* T1 = X + T1 */ + sp_1024_mont_add_32(ctx->t1, p->x, ctx->t1, p1024_mod); + ctx->state = 6; + break; + case 6: + /* T2 = T1 * T2 */ + sp_1024_mont_mul_32(ctx->t2, ctx->t1, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 7; + break; + case 7: + /* T1 = 3T2 */ + sp_1024_mont_tpl_32(ctx->t1, ctx->t2, p1024_mod); + ctx->state = 8; + break; + case 8: + /* Y = 2Y */ + sp_1024_mont_dbl_32(ctx->y, p->y, p1024_mod); + ctx->state = 9; + break; + case 9: + /* Y = Y * Y */ + sp_1024_mont_sqr_32(ctx->y, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 10; + break; + case 10: + /* T2 = Y * Y */ + sp_1024_mont_sqr_32(ctx->t2, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 11; + break; + case 11: + /* T2 = T2/2 */ + sp_1024_div2_32(ctx->t2, ctx->t2, p1024_mod); + ctx->state = 12; + break; + case 12: + /* Y = Y * X */ + sp_1024_mont_mul_32(ctx->y, ctx->y, p->x, p1024_mod, p1024_mp_mod); + ctx->state = 13; + break; + case 13: + /* X = T1 * T1 */ + sp_1024_mont_sqr_32(ctx->x, ctx->t1, p1024_mod, p1024_mp_mod); + ctx->state = 14; + break; + case 14: + /* X = X - Y */ + sp_1024_mont_sub_32(ctx->x, ctx->x, ctx->y, p1024_mod); + ctx->state = 15; + break; + case 15: + /* X = X - Y */ + sp_1024_mont_sub_32(ctx->x, ctx->x, ctx->y, p1024_mod); + ctx->state = 16; + break; + case 16: + /* Y = Y - X */ + sp_1024_mont_sub_32(ctx->y, ctx->y, ctx->x, p1024_mod); + ctx->state = 17; + break; + case 17: + /* Y = Y * T1 */ + sp_1024_mont_mul_32(ctx->y, ctx->y, ctx->t1, p1024_mod, p1024_mp_mod); + ctx->state = 18; + break; + case 18: + /* Y = Y - T2 */ + sp_1024_mont_sub_32(ctx->y, ctx->y, ctx->t2, p1024_mod); + ctx->state = 19; + /* fall-through */ + case 19: + err = MP_OKAY; + break; + } + + if (err == MP_OKAY && ctx->state != 19) { + err = FP_WOULDBLOCK; + } + + return err; +} +#endif /* WOLFSSL_SP_NONBLOCK */ + +static void sp_1024_proj_point_dbl_32(sp_point_1024* r, const sp_point_1024* p, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*32; + sp_digit* x; + sp_digit* y; + sp_digit* z; + + x = r->x; + y = r->y; + z = r->z; + /* Put infinity into result. */ + if (r != p) { + r->infinity = p->infinity; + } + + /* T1 = Z * Z */ + sp_1024_mont_sqr_32(t1, p->z, p1024_mod, p1024_mp_mod); + /* Z = Y * Z */ + sp_1024_mont_mul_32(z, p->y, p->z, p1024_mod, p1024_mp_mod); + /* Z = 2Z */ + sp_1024_mont_dbl_32(z, z, p1024_mod); + /* T2 = X - T1 */ + sp_1024_mont_sub_32(t2, p->x, t1, p1024_mod); + /* T1 = X + T1 */ + sp_1024_mont_add_32(t1, p->x, t1, p1024_mod); + /* T2 = T1 * T2 */ + sp_1024_mont_mul_32(t2, t1, t2, p1024_mod, p1024_mp_mod); + /* T1 = 3T2 */ + sp_1024_mont_tpl_32(t1, t2, p1024_mod); + /* Y = 2Y */ + sp_1024_mont_dbl_32(y, p->y, p1024_mod); + /* Y = Y * Y */ + sp_1024_mont_sqr_32(y, y, p1024_mod, p1024_mp_mod); + /* T2 = Y * Y */ + sp_1024_mont_sqr_32(t2, y, p1024_mod, p1024_mp_mod); + /* T2 = T2/2 */ + sp_1024_div2_32(t2, t2, p1024_mod); + /* Y = Y * X */ + sp_1024_mont_mul_32(y, y, p->x, p1024_mod, p1024_mp_mod); + /* X = T1 * T1 */ + sp_1024_mont_sqr_32(x, t1, p1024_mod, p1024_mp_mod); + /* X = X - Y */ + sp_1024_mont_sub_32(x, x, y, p1024_mod); + /* X = X - Y */ + sp_1024_mont_sub_32(x, x, y, p1024_mod); + /* Y = Y - X */ + sp_1024_mont_sub_32(y, y, x, p1024_mod); + /* Y = Y * T1 */ + sp_1024_mont_mul_32(y, y, t1, p1024_mod, p1024_mp_mod); + /* Y = Y - T2 */ + sp_1024_mont_sub_32(y, y, t2, p1024_mod); +} + +#ifdef WOLFSSL_SP_SMALL +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_1024_sub_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "add r12, %[a], #128\n\t" + "\n1:\n\t" + "rsbs %[c], %[c], #0\n\t" + "ldr r4, [%[a]], #4\n\t" + "ldr r5, [%[a]], #4\n\t" + "ldr r6, [%[a]], #4\n\t" + "ldr r7, [%[a]], #4\n\t" + "ldr r8, [%[b]], #4\n\t" + "ldr r9, [%[b]], #4\n\t" + "ldr r10, [%[b]], #4\n\t" + "ldr r14, [%[b]], #4\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "str r4, [%[r]], #4\n\t" + "str r5, [%[r]], #4\n\t" + "str r6, [%[r]], #4\n\t" + "str r7, [%[r]], #4\n\t" + "sbc %[c], r4, r4\n\t" + "cmp %[a], r12\n\t" + "bne 1b\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + ); + + return c; +} + +#else +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_1024_sub_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldr r3, [%[a], #0]\n\t" + "ldr r4, [%[a], #4]\n\t" + "ldr r5, [%[a], #8]\n\t" + "ldr r6, [%[a], #12]\n\t" + "ldr r7, [%[b], #0]\n\t" + "ldr r8, [%[b], #4]\n\t" + "ldr r9, [%[b], #8]\n\t" + "ldr r10, [%[b], #12]\n\t" + "subs r3, r3, r7\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "str r3, [%[r], #0]\n\t" + "str r4, [%[r], #4]\n\t" + "str r5, [%[r], #8]\n\t" + "str r6, [%[r], #12]\n\t" + "ldr r3, [%[a], #16]\n\t" + "ldr r4, [%[a], #20]\n\t" + "ldr r5, [%[a], #24]\n\t" + "ldr r6, [%[a], #28]\n\t" + "ldr r7, [%[b], #16]\n\t" + "ldr r8, [%[b], #20]\n\t" + "ldr r9, [%[b], #24]\n\t" + "ldr r10, [%[b], #28]\n\t" + "sbcs r3, r3, r7\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "str r3, [%[r], #16]\n\t" + "str r4, [%[r], #20]\n\t" + "str r5, [%[r], #24]\n\t" + "str r6, [%[r], #28]\n\t" + "ldr r3, [%[a], #32]\n\t" + "ldr r4, [%[a], #36]\n\t" + "ldr r5, [%[a], #40]\n\t" + "ldr r6, [%[a], #44]\n\t" + "ldr r7, [%[b], #32]\n\t" + "ldr r8, [%[b], #36]\n\t" + "ldr r9, [%[b], #40]\n\t" + "ldr r10, [%[b], #44]\n\t" + "sbcs r3, r3, r7\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "str r3, [%[r], #32]\n\t" + "str r4, [%[r], #36]\n\t" + "str r5, [%[r], #40]\n\t" + "str r6, [%[r], #44]\n\t" + "ldr r3, [%[a], #48]\n\t" + "ldr r4, [%[a], #52]\n\t" + "ldr r5, [%[a], #56]\n\t" + "ldr r6, [%[a], #60]\n\t" + "ldr r7, [%[b], #48]\n\t" + "ldr r8, [%[b], #52]\n\t" + "ldr r9, [%[b], #56]\n\t" + "ldr r10, [%[b], #60]\n\t" + "sbcs r3, r3, r7\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "str r3, [%[r], #48]\n\t" + "str r4, [%[r], #52]\n\t" + "str r5, [%[r], #56]\n\t" + "str r6, [%[r], #60]\n\t" + "ldr r3, [%[a], #64]\n\t" + "ldr r4, [%[a], #68]\n\t" + "ldr r5, [%[a], #72]\n\t" + "ldr r6, [%[a], #76]\n\t" + "ldr r7, [%[b], #64]\n\t" + "ldr r8, [%[b], #68]\n\t" + "ldr r9, [%[b], #72]\n\t" + "ldr r10, [%[b], #76]\n\t" + "sbcs r3, r3, r7\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "str r3, [%[r], #64]\n\t" + "str r4, [%[r], #68]\n\t" + "str r5, [%[r], #72]\n\t" + "str r6, [%[r], #76]\n\t" + "ldr r3, [%[a], #80]\n\t" + "ldr r4, [%[a], #84]\n\t" + "ldr r5, [%[a], #88]\n\t" + "ldr r6, [%[a], #92]\n\t" + "ldr r7, [%[b], #80]\n\t" + "ldr r8, [%[b], #84]\n\t" + "ldr r9, [%[b], #88]\n\t" + "ldr r10, [%[b], #92]\n\t" + "sbcs r3, r3, r7\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "str r3, [%[r], #80]\n\t" + "str r4, [%[r], #84]\n\t" + "str r5, [%[r], #88]\n\t" + "str r6, [%[r], #92]\n\t" + "ldr r3, [%[a], #96]\n\t" + "ldr r4, [%[a], #100]\n\t" + "ldr r5, [%[a], #104]\n\t" + "ldr r6, [%[a], #108]\n\t" + "ldr r7, [%[b], #96]\n\t" + "ldr r8, [%[b], #100]\n\t" + "ldr r9, [%[b], #104]\n\t" + "ldr r10, [%[b], #108]\n\t" + "sbcs r3, r3, r7\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "str r3, [%[r], #96]\n\t" + "str r4, [%[r], #100]\n\t" + "str r5, [%[r], #104]\n\t" + "str r6, [%[r], #108]\n\t" + "ldr r3, [%[a], #112]\n\t" + "ldr r4, [%[a], #116]\n\t" + "ldr r5, [%[a], #120]\n\t" + "ldr r6, [%[a], #124]\n\t" + "ldr r7, [%[b], #112]\n\t" + "ldr r8, [%[b], #116]\n\t" + "ldr r9, [%[b], #120]\n\t" + "ldr r10, [%[b], #124]\n\t" + "sbcs r3, r3, r7\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "str r3, [%[r], #112]\n\t" + "str r4, [%[r], #116]\n\t" + "str r5, [%[r], #120]\n\t" + "str r6, [%[r], #124]\n\t" + "sbc %[c], %[c], #0\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b) + : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" + ); + + return c; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Compare two numbers to determine if they are equal. + * Constant time implementation. + * + * a First number to compare. + * b Second number to compare. + * returns 1 when equal and 0 otherwise. + */ +static int sp_1024_cmp_equal_32(const sp_digit* a, const sp_digit* b) +{ + return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) | (a[3] ^ b[3]) | + (a[4] ^ b[4]) | (a[5] ^ b[5]) | (a[6] ^ b[6]) | (a[7] ^ b[7]) | + (a[8] ^ b[8]) | (a[9] ^ b[9]) | (a[10] ^ b[10]) | (a[11] ^ b[11]) | + (a[12] ^ b[12]) | (a[13] ^ b[13]) | (a[14] ^ b[14]) | (a[15] ^ b[15]) | + (a[16] ^ b[16]) | (a[17] ^ b[17]) | (a[18] ^ b[18]) | (a[19] ^ b[19]) | + (a[20] ^ b[20]) | (a[21] ^ b[21]) | (a[22] ^ b[22]) | (a[23] ^ b[23]) | + (a[24] ^ b[24]) | (a[25] ^ b[25]) | (a[26] ^ b[26]) | (a[27] ^ b[27]) | + (a[28] ^ b[28]) | (a[29] ^ b[29]) | (a[30] ^ b[30]) | (a[31] ^ b[31])) == 0; +} + +/* Add two Montgomery form projective points. + * + * r Result of addition. + * p First point to add. + * q Second point to add. + * t Temporary ordinate data. + */ + +#ifdef WOLFSSL_SP_NONBLOCK +typedef struct sp_1024_proj_point_add_32_ctx { + int state; + sp_1024_proj_point_dbl_32_ctx dbl_ctx; + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1; + sp_digit* t2; + sp_digit* t3; + sp_digit* t4; + sp_digit* t5; + sp_digit* x; + sp_digit* y; + sp_digit* z; +} sp_1024_proj_point_add_32_ctx; + +static int sp_1024_proj_point_add_32_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r, + const sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + int err = FP_WOULDBLOCK; + sp_1024_proj_point_add_32_ctx* ctx = (sp_1024_proj_point_add_32_ctx*)sp_ctx->data; + + /* Ensure only the first point is the same as the result. */ + if (q == r) { + const sp_point_1024* a = p; + p = q; + q = a; + } + + typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_32_ctx) >= sizeof(*sp_ctx) ? -1 : 1]; + (void)sizeof(ctx_size_test); + + switch (ctx->state) { + case 0: /* INIT */ + ctx->t1 = t; + ctx->t2 = t + 2*32; + ctx->t3 = t + 4*32; + ctx->t4 = t + 6*32; + ctx->t5 = t + 8*32; + + ctx->state = 1; + break; + case 1: + /* Check double */ + (void)sp_1024_sub_32(ctx->t1, p1024_mod, q->y); + sp_1024_norm_32(ctx->t1); + if ((sp_1024_cmp_equal_32(p->x, q->x) & sp_1024_cmp_equal_32(p->z, q->z) & + (sp_1024_cmp_equal_32(p->y, q->y) | sp_1024_cmp_equal_32(p->y, ctx->t1))) != 0) + { + XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx)); + ctx->state = 2; + } + else { + ctx->state = 3; + } + break; + case 2: + err = sp_1024_proj_point_dbl_32_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, r, p, t); + if (err == MP_OKAY) + ctx->state = 27; /* done */ + break; + case 3: + { + int i; + ctx->rp[0] = r; + + /*lint allow cast to different type of pointer*/ + ctx->rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(ctx->rp[1], 0, sizeof(sp_point_1024)); + ctx->x = ctx->rp[p->infinity | q->infinity]->x; + ctx->y = ctx->rp[p->infinity | q->infinity]->y; + ctx->z = ctx->rp[p->infinity | q->infinity]->z; + + ctx->ap[0] = p; + ctx->ap[1] = q; + for (i=0; i<32; i++) { + r->x[i] = ctx->ap[p->infinity]->x[i]; + } + for (i=0; i<32; i++) { + r->y[i] = ctx->ap[p->infinity]->y[i]; + } + for (i=0; i<32; i++) { + r->z[i] = ctx->ap[p->infinity]->z[i]; + } + r->infinity = ctx->ap[p->infinity]->infinity; + + ctx->state = 4; + break; + } + case 4: + /* U1 = X1*Z2^2 */ + sp_1024_mont_sqr_32(ctx->t1, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 5; + break; + case 5: + sp_1024_mont_mul_32(ctx->t3, ctx->t1, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 6; + break; + case 6: + sp_1024_mont_mul_32(ctx->t1, ctx->t1, ctx->x, p1024_mod, p1024_mp_mod); + ctx->state = 7; + break; + case 7: + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_32(ctx->t2, ctx->z, p1024_mod, p1024_mp_mod); + ctx->state = 8; + break; + case 8: + sp_1024_mont_mul_32(ctx->t4, ctx->t2, ctx->z, p1024_mod, p1024_mp_mod); + ctx->state = 9; + break; + case 9: + sp_1024_mont_mul_32(ctx->t2, ctx->t2, q->x, p1024_mod, p1024_mp_mod); + ctx->state = 10; + break; + case 10: + /* S1 = Y1*Z2^3 */ + sp_1024_mont_mul_32(ctx->t3, ctx->t3, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 11; + break; + case 11: + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_32(ctx->t4, ctx->t4, q->y, p1024_mod, p1024_mp_mod); + ctx->state = 12; + break; + case 12: + /* H = U2 - U1 */ + sp_1024_mont_sub_32(ctx->t2, ctx->t2, ctx->t1, p1024_mod); + ctx->state = 13; + break; + case 13: + /* R = S2 - S1 */ + sp_1024_mont_sub_32(ctx->t4, ctx->t4, ctx->t3, p1024_mod); + ctx->state = 14; + break; + case 14: + /* Z3 = H*Z1*Z2 */ + sp_1024_mont_mul_32(ctx->z, ctx->z, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 15; + break; + case 15: + sp_1024_mont_mul_32(ctx->z, ctx->z, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 16; + break; + case 16: + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_1024_mont_sqr_32(ctx->x, ctx->t4, p1024_mod, p1024_mp_mod); + ctx->state = 17; + break; + case 17: + sp_1024_mont_sqr_32(ctx->t5, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 18; + break; + case 18: + sp_1024_mont_mul_32(ctx->y, ctx->t1, ctx->t5, p1024_mod, p1024_mp_mod); + ctx->state = 19; + break; + case 19: + sp_1024_mont_mul_32(ctx->t5, ctx->t5, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 20; + break; + case 20: + sp_1024_mont_sub_32(ctx->x, ctx->x, ctx->t5, p1024_mod); + ctx->state = 21; + break; + case 21: + sp_1024_mont_dbl_32(ctx->t1, ctx->y, p1024_mod); + ctx->state = 22; + break; + case 22: + sp_1024_mont_sub_32(ctx->x, ctx->x, ctx->t1, p1024_mod); + ctx->state = 23; + break; + case 23: + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_1024_mont_sub_32(ctx->y, ctx->y, ctx->x, p1024_mod); + ctx->state = 24; + break; + case 24: + sp_1024_mont_mul_32(ctx->y, ctx->y, ctx->t4, p1024_mod, p1024_mp_mod); + ctx->state = 25; + break; + case 25: + sp_1024_mont_mul_32(ctx->t5, ctx->t5, ctx->t3, p1024_mod, p1024_mp_mod); + ctx->state = 26; + break; + case 26: + sp_1024_mont_sub_32(ctx->y, ctx->y, ctx->t5, p1024_mod); + ctx->state = 27; + /* fall-through */ + case 27: + err = MP_OKAY; + break; + } + + if (err == MP_OKAY && ctx->state != 27) { + err = FP_WOULDBLOCK; + } + return err; +} +#endif /* WOLFSSL_SP_NONBLOCK */ + +static void sp_1024_proj_point_add_32(sp_point_1024* r, + const sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*32; + sp_digit* t3 = t + 4*32; + sp_digit* t4 = t + 6*32; + sp_digit* t5 = t + 8*32; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Ensure only the first point is the same as the result. */ + if (q == r) { + const sp_point_1024* a = p; + p = q; + q = a; + } + + /* Check double */ + (void)sp_1024_mont_sub_32(t1, p1024_mod, q->y, p1024_mod); + sp_1024_norm_32(t1); + if ((sp_1024_cmp_equal_32(p->x, q->x) & sp_1024_cmp_equal_32(p->z, q->z) & + (sp_1024_cmp_equal_32(p->y, q->y) | sp_1024_cmp_equal_32(p->y, t1))) != 0) { + sp_1024_proj_point_dbl_32(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_1024)); + x = rp[p->infinity | q->infinity]->x; + y = rp[p->infinity | q->infinity]->y; + z = rp[p->infinity | q->infinity]->z; + + ap[0] = p; + ap[1] = q; + for (i=0; i<32; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<32; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<32; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U1 = X1*Z2^2 */ + sp_1024_mont_sqr_32(t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t3, t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t1, t1, x, p1024_mod, p1024_mp_mod); + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_32(t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t4, t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t2, t2, q->x, p1024_mod, p1024_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_1024_mont_mul_32(t3, t3, y, p1024_mod, p1024_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_32(t4, t4, q->y, p1024_mod, p1024_mp_mod); + /* H = U2 - U1 */ + sp_1024_mont_sub_32(t2, t2, t1, p1024_mod); + /* R = S2 - S1 */ + sp_1024_mont_sub_32(t4, t4, t3, p1024_mod); + /* Z3 = H*Z1*Z2 */ + sp_1024_mont_mul_32(z, z, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(z, z, t2, p1024_mod, p1024_mp_mod); + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_1024_mont_sqr_32(x, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_32(t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(y, t1, t5, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t5, t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_32(x, x, t5, p1024_mod); + sp_1024_mont_dbl_32(t1, y, p1024_mod); + sp_1024_mont_sub_32(x, x, t1, p1024_mod); + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_1024_mont_sub_32(y, y, x, p1024_mod); + sp_1024_mont_mul_32(y, y, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t5, t5, t3, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_32(y, y, t5, p1024_mod); + } +} + +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Fast implementation that generates a pre-computation table. + * 4 bits of window (no sliding!). + * Uses add and double for calculating table. + * 1024 doubles. + * 268 adds. + * + * r Resulting point. + * g Point to multiply. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_fast_32(sp_point_1024* r, const sp_point_1024* g, const sp_digit* k, + int map, int ct, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 td[16]; + sp_point_1024 rtd; + sp_digit tmpd[2 * 32 * 5]; +#endif + sp_point_1024* t; + sp_point_1024* rt; + sp_digit* tmp; + sp_digit n; + int i; + int c; + int y; + int err; + + /* Constant time used for cache attack resistance implementation. */ + (void)ct; + (void)heap; + + err = sp_1024_point_new_32(heap, rtd, rt); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +#ifndef WC_NO_CACHE_RESISTANT + t = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) * 17, heap, DYNAMIC_TYPE_ECC); +#else + t = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) * 16, heap, DYNAMIC_TYPE_ECC); +#endif + if (t == NULL) + err = MEMORY_E; + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 32 * 5, heap, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) + err = MEMORY_E; +#else + t = td; + tmp = tmpd; +#endif + + if (err == MP_OKAY) { + /* t[0] = {0, 0, 1} * norm */ + XMEMSET(&t[0], 0, sizeof(t[0])); + t[0].infinity = 1; + /* t[1] = {g->x, g->y, g->z} * norm */ + (void)sp_1024_mod_mul_norm_32(t[1].x, g->x, p1024_mod); + (void)sp_1024_mod_mul_norm_32(t[1].y, g->y, p1024_mod); + (void)sp_1024_mod_mul_norm_32(t[1].z, g->z, p1024_mod); + t[1].infinity = 0; + sp_1024_proj_point_dbl_32(&t[ 2], &t[ 1], tmp); + t[ 2].infinity = 0; + sp_1024_proj_point_add_32(&t[ 3], &t[ 2], &t[ 1], tmp); + t[ 3].infinity = 0; + sp_1024_proj_point_dbl_32(&t[ 4], &t[ 2], tmp); + t[ 4].infinity = 0; + sp_1024_proj_point_add_32(&t[ 5], &t[ 3], &t[ 2], tmp); + t[ 5].infinity = 0; + sp_1024_proj_point_dbl_32(&t[ 6], &t[ 3], tmp); + t[ 6].infinity = 0; + sp_1024_proj_point_add_32(&t[ 7], &t[ 4], &t[ 3], tmp); + t[ 7].infinity = 0; + sp_1024_proj_point_dbl_32(&t[ 8], &t[ 4], tmp); + t[ 8].infinity = 0; + sp_1024_proj_point_add_32(&t[ 9], &t[ 5], &t[ 4], tmp); + t[ 9].infinity = 0; + sp_1024_proj_point_dbl_32(&t[10], &t[ 5], tmp); + t[10].infinity = 0; + sp_1024_proj_point_add_32(&t[11], &t[ 6], &t[ 5], tmp); + t[11].infinity = 0; + sp_1024_proj_point_dbl_32(&t[12], &t[ 6], tmp); + t[12].infinity = 0; + sp_1024_proj_point_add_32(&t[13], &t[ 7], &t[ 6], tmp); + t[13].infinity = 0; + sp_1024_proj_point_dbl_32(&t[14], &t[ 7], tmp); + t[14].infinity = 0; + sp_1024_proj_point_add_32(&t[15], &t[ 8], &t[ 7], tmp); + t[15].infinity = 0; + + i = 30; + n = k[i+1] << 0; + c = 28; + y = (int)(n >> 28); + XMEMCPY(rt, &t[y], sizeof(sp_point_1024)); + n <<= 4; + for (; i>=0 || c>=4; ) { + if (c < 4) { + n |= k[i--]; + c += 32; + } + y = (n >> 28) & 0xf; + n <<= 4; + c -= 4; + + sp_1024_proj_point_dbl_32(rt, rt, tmp); + sp_1024_proj_point_dbl_32(rt, rt, tmp); + sp_1024_proj_point_dbl_32(rt, rt, tmp); + sp_1024_proj_point_dbl_32(rt, rt, tmp); + sp_1024_proj_point_add_32(rt, rt, &t[y], tmp); + } + + if (map != 0) { + sp_1024_map_32(r, rt, tmp); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_1024)); + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (tmp != NULL) { + XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 32 * 5); + XFREE(tmp, heap, DYNAMIC_TYPE_ECC); + } + if (t != NULL) { + XMEMSET(t, 0, sizeof(sp_point_1024) * 16); + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#else + ForceZero(tmpd, sizeof(tmpd)); + ForceZero(td, sizeof(td)); +#endif + sp_1024_point_free_32(rt, 1, heap); + + return err; +} + +#if defined(FP_ECC) || !defined(WOLFSSL_SP_SMALL) +/* Double the Montgomery form projective point p a number of times. + * + * r Result of repeated doubling of point. + * p Point to double. + * n Number of times to double + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_dbl_n_32(sp_point_1024* p, int n, + sp_digit* t) +{ + sp_digit* w = t; + sp_digit* a = t + 2*32; + sp_digit* b = t + 4*32; + sp_digit* t1 = t + 6*32; + sp_digit* t2 = t + 8*32; + sp_digit* x; + sp_digit* y; + sp_digit* z; + + x = p->x; + y = p->y; + z = p->z; + + /* Y = 2*Y */ + sp_1024_mont_dbl_32(y, y, p1024_mod); + /* W = Z^4 */ + sp_1024_mont_sqr_32(w, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_32(w, w, p1024_mod, p1024_mp_mod); + +#ifndef WOLFSSL_SP_SMALL + while (--n > 0) +#else + while (--n >= 0) +#endif + { + /* A = 3*(X^2 - W) */ + sp_1024_mont_sqr_32(t1, x, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_32(t1, t1, w, p1024_mod); + sp_1024_mont_tpl_32(a, t1, p1024_mod); + /* B = X*Y^2 */ + sp_1024_mont_sqr_32(t1, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(b, t1, x, p1024_mod, p1024_mp_mod); + /* X = A^2 - 2B */ + sp_1024_mont_sqr_32(x, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_32(t2, b, p1024_mod); + sp_1024_mont_sub_32(x, x, t2, p1024_mod); + /* Z = Z*Y */ + sp_1024_mont_mul_32(z, z, y, p1024_mod, p1024_mp_mod); + /* t2 = Y^4 */ + sp_1024_mont_sqr_32(t1, t1, p1024_mod, p1024_mp_mod); +#ifdef WOLFSSL_SP_SMALL + if (n != 0) +#endif + { + /* W = W*Y^4 */ + sp_1024_mont_mul_32(w, w, t1, p1024_mod, p1024_mp_mod); + } + /* y = 2*A*(B - X) - Y^4 */ + sp_1024_mont_sub_32(y, b, x, p1024_mod); + sp_1024_mont_mul_32(y, y, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_32(y, y, p1024_mod); + sp_1024_mont_sub_32(y, y, t1, p1024_mod); + } +#ifndef WOLFSSL_SP_SMALL + /* A = 3*(X^2 - W) */ + sp_1024_mont_sqr_32(t1, x, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_32(t1, t1, w, p1024_mod); + sp_1024_mont_tpl_32(a, t1, p1024_mod); + /* B = X*Y^2 */ + sp_1024_mont_sqr_32(t1, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(b, t1, x, p1024_mod, p1024_mp_mod); + /* X = A^2 - 2B */ + sp_1024_mont_sqr_32(x, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_32(t2, b, p1024_mod); + sp_1024_mont_sub_32(x, x, t2, p1024_mod); + /* Z = Z*Y */ + sp_1024_mont_mul_32(z, z, y, p1024_mod, p1024_mp_mod); + /* t2 = Y^4 */ + sp_1024_mont_sqr_32(t1, t1, p1024_mod, p1024_mp_mod); + /* y = 2*A*(B - X) - Y^4 */ + sp_1024_mont_sub_32(y, b, x, p1024_mod); + sp_1024_mont_mul_32(y, y, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_32(y, y, p1024_mod); + sp_1024_mont_sub_32(y, y, t1, p1024_mod); +#endif + /* Y = Y/2 */ + sp_1024_div2_32(y, y, p1024_mod); +} + +/* Convert the projective point to affine. + * Ordinates are in Montgomery form. + * + * a Point to convert. + * t Temporary data. + */ +static void sp_1024_proj_to_affine_32(sp_point_1024* a, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 32; + sp_digit* tmp = t + 4 * 32; + + sp_1024_mont_inv_32(t1, a->z, tmp); + + sp_1024_mont_sqr_32(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t1, t2, t1, p1024_mod, p1024_mp_mod); + + sp_1024_mont_mul_32(a->x, a->x, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(a->y, a->y, t1, p1024_mod, p1024_mp_mod); + XMEMCPY(a->z, p1024_norm_mod, sizeof(p1024_norm_mod)); +} + +#endif /* FP_ECC || !WOLFSSL_SP_SMALL */ +/* A table entry for pre-computed points. */ +typedef struct sp_table_entry_1024 { + sp_digit x[32]; + sp_digit y[32]; +} sp_table_entry_1024; + +#ifdef FP_ECC +#endif /* FP_ECC */ +/* Add two Montgomery form projective points. The second point has a q value of + * one. + * Only the first point can be the same pointer as the result point. + * + * r Result of addition. + * p First point to add. + * q Second point to add. + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_add_qz1_32(sp_point_1024* r, const sp_point_1024* p, + const sp_point_1024* q, sp_digit* t) +{ + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*32; + sp_digit* t3 = t + 4*32; + sp_digit* t4 = t + 6*32; + sp_digit* t5 = t + 8*32; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Check double */ + (void)sp_1024_mont_sub_32(t1, p1024_mod, q->y, p1024_mod); + sp_1024_norm_32(t1); + if ((sp_1024_cmp_equal_32(p->x, q->x) & sp_1024_cmp_equal_32(p->z, q->z) & + (sp_1024_cmp_equal_32(p->y, q->y) | sp_1024_cmp_equal_32(p->y, t1))) != 0) { + sp_1024_proj_point_dbl_32(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_1024)); + x = rp[p->infinity | q->infinity]->x; + y = rp[p->infinity | q->infinity]->y; + z = rp[p->infinity | q->infinity]->z; + + ap[0] = p; + ap[1] = q; + for (i=0; i<32; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<32; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<32; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_32(t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t4, t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t2, t2, q->x, p1024_mod, p1024_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_32(t4, t4, q->y, p1024_mod, p1024_mp_mod); + /* H = U2 - X1 */ + sp_1024_mont_sub_32(t2, t2, x, p1024_mod); + /* R = S2 - Y1 */ + sp_1024_mont_sub_32(t4, t4, y, p1024_mod); + /* Z3 = H*Z1 */ + sp_1024_mont_mul_32(z, z, t2, p1024_mod, p1024_mp_mod); + /* X3 = R^2 - H^3 - 2*X1*H^2 */ + sp_1024_mont_sqr_32(t1, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_32(t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t3, x, t5, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t5, t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_32(x, t1, t5, p1024_mod); + sp_1024_mont_dbl_32(t1, t3, p1024_mod); + sp_1024_mont_sub_32(x, x, t1, p1024_mod); + /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */ + sp_1024_mont_sub_32(t3, t3, x, p1024_mod); + sp_1024_mont_mul_32(t3, t3, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t5, t5, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_32(y, t3, t5, p1024_mod); + } +} + +#ifdef WOLFSSL_SP_SMALL +#if defined(FP_ECC) || !defined(WOLFSSL_SP_SMALL) +/* Generate the pre-computed table of points for the base point. + * + * width = 4 + * 16 entries + * 256 bits between + * + * a The base point. + * table Place to store generated point data. + * tmp Temporary data. + * heap Heap to use for allocation. + */ +static int sp_1024_gen_stripe_table_32(const sp_point_1024* a, + sp_table_entry_1024* table, sp_digit* tmp, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 td; + sp_point_1024 s1d; + sp_point_1024 s2d; +#endif + sp_point_1024* t; + sp_point_1024* s1 = NULL; + sp_point_1024* s2 = NULL; + int i; + int j; + int err; + + (void)heap; + + err = sp_1024_point_new_32(heap, td, t); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, s1d, s1); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, s2d, s2); + } + + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(t->x, a->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(t->y, a->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(t->z, a->z, p1024_mod); + } + if (err == MP_OKAY) { + t->infinity = 0; + sp_1024_proj_to_affine_32(t, tmp); + + XMEMCPY(s1->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + s1->infinity = 0; + XMEMCPY(s2->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + s2->infinity = 0; + + /* table[0] = {0, 0, infinity} */ + XMEMSET(&table[0], 0, sizeof(sp_table_entry_1024)); + /* table[1] = Affine version of 'a' in Montgomery form */ + XMEMCPY(table[1].x, t->x, sizeof(table->x)); + XMEMCPY(table[1].y, t->y, sizeof(table->y)); + + for (i=1; i<4; i++) { + sp_1024_proj_point_dbl_n_32(t, 256, tmp); + sp_1024_proj_to_affine_32(t, tmp); + XMEMCPY(table[1<x, sizeof(table->x)); + XMEMCPY(table[1<y, sizeof(table->y)); + } + + for (i=1; i<4; i++) { + XMEMCPY(s1->x, table[1<x)); + XMEMCPY(s1->y, table[1<y)); + for (j=(1<x, table[j-(1<x)); + XMEMCPY(s2->y, table[j-(1<y)); + sp_1024_proj_point_add_qz1_32(t, s1, s2, tmp); + sp_1024_proj_to_affine_32(t, tmp); + XMEMCPY(table[j].x, t->x, sizeof(table->x)); + XMEMCPY(table[j].y, t->y, sizeof(table->y)); + } + } + } + + sp_1024_point_free_32(s2, 0, heap); + sp_1024_point_free_32(s1, 0, heap); + sp_1024_point_free_32( t, 0, heap); + + return err; +} + +#endif /* FP_ECC || !WOLFSSL_SP_SMALL */ +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^256, ... + * Pre-generated: products of all combinations of above. + * 4 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * table Pre-computed table. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_stripe_32(sp_point_1024* r, const sp_point_1024* g, + const sp_table_entry_1024* table, const sp_digit* k, int map, + int ct, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 rtd; + sp_point_1024 pd; + sp_digit td[2 * 32 * 5]; +#endif + sp_point_1024* rt; + sp_point_1024* p = NULL; + sp_digit* t; + int i; + int j; + int y; + int x; + int err; + + (void)g; + /* Constant time used for cache attack resistance implementation. */ + (void)ct; + (void)heap; + + + err = sp_1024_point_new_32(heap, rtd, rt); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, pd, p); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 32 * 5, heap, + DYNAMIC_TYPE_ECC); + if (t == NULL) { + err = MEMORY_E; + } +#else + t = td; +#endif + + if (err == MP_OKAY) { + XMEMCPY(p->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + XMEMCPY(rt->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + + y = 0; + x = 255; + for (j=0; j<4; j++) { + y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 256; + } + XMEMCPY(rt->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(rt->y, table[y].y, sizeof(table[y].y)); + rt->infinity = !y; + for (i=254; i>=0; i--) { + y = 0; + x = i; + for (j=0; j<4; j++) { + y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 256; + } + + sp_1024_proj_point_dbl_32(rt, rt, t); + XMEMCPY(p->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(p->y, table[y].y, sizeof(table[y].y)); + p->infinity = !y; + sp_1024_proj_point_add_qz1_32(rt, rt, p, t); + } + + if (map != 0) { + sp_1024_map_32(r, rt, t); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_1024)); + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (t != NULL) { + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_32(p, 0, heap); + sp_1024_point_free_32(rt, 0, heap); + + return err; +} + +#ifdef FP_ECC +#ifndef FP_ENTRIES + #define FP_ENTRIES 16 +#endif + +/* Cache entry - holds precomputation tables for a point. */ +typedef struct sp_cache_1024_t { + /* X ordinate of point that table was generated from. */ + sp_digit x[32]; + /* Y ordinate of point that table was generated from. */ + sp_digit y[32]; + /* Precomputation table for point. */ + sp_table_entry_1024 table[16]; + /* Count of entries in table. */ + uint32_t cnt; + /* Point and table set in entry. */ + int set; +} sp_cache_1024_t; + +/* Cache of tables. */ +static THREAD_LS_T sp_cache_1024_t sp_cache_1024[FP_ENTRIES]; +/* Index of last entry in cache. */ +static THREAD_LS_T int sp_cache_1024_last = -1; +/* Cache has been initialized. */ +static THREAD_LS_T int sp_cache_1024_inited = 0; + +#ifndef HAVE_THREAD_LS + static volatile int initCacheMutex_1024 = 0; + static wolfSSL_Mutex sp_cache_1024_lock; +#endif + +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ +static void sp_ecc_get_cache_1024(const sp_point_1024* g, sp_cache_1024_t** cache) +{ + int i; + int j; + uint32_t least; + + if (sp_cache_1024_inited == 0) { + for (i=0; ix, sp_cache_1024[i].x) & + sp_1024_cmp_equal_32(g->y, sp_cache_1024[i].y)) { + sp_cache_1024[i].cnt++; + break; + } + } + + /* No match. */ + if (i == FP_ENTRIES) { + /* Find empty entry. */ + i = (sp_cache_1024_last + 1) % FP_ENTRIES; + for (; i != sp_cache_1024_last; i=(i+1)%FP_ENTRIES) { + if (!sp_cache_1024[i].set) { + break; + } + } + + /* Evict least used. */ + if (i == sp_cache_1024_last) { + least = sp_cache_1024[0].cnt; + for (j=1; jx, sizeof(sp_cache_1024[i].x)); + XMEMCPY(sp_cache_1024[i].y, g->y, sizeof(sp_cache_1024[i].y)); + sp_cache_1024[i].set = 1; + sp_cache_1024[i].cnt = 1; + } + + *cache = &sp_cache_1024[i]; + sp_cache_1024_last = i; +} +#endif /* FP_ECC */ + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * r Resulting point. + * g Point to multiply. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_32(sp_point_1024* r, const sp_point_1024* g, const sp_digit* k, + int map, int ct, void* heap) +{ +#ifndef FP_ECC + return sp_1024_ecc_mulmod_fast_32(r, g, k, map, ct, heap); +#else + sp_digit tmp[2 * 32 * 5]; + sp_cache_1024_t* cache; + int err = MP_OKAY; + +#ifndef HAVE_THREAD_LS + if (initCacheMutex_1024 == 0) { + wc_InitMutex(&sp_cache_1024_lock); + initCacheMutex_1024 = 1; + } + if (wc_LockMutex(&sp_cache_1024_lock) != 0) + err = BAD_MUTEX_E; +#endif /* HAVE_THREAD_LS */ + + if (err == MP_OKAY) { + sp_ecc_get_cache_1024(g, &cache); + if (cache->cnt == 2) + sp_1024_gen_stripe_table_32(g, cache->table, tmp, heap); + +#ifndef HAVE_THREAD_LS + wc_UnLockMutex(&sp_cache_1024_lock); +#endif /* HAVE_THREAD_LS */ + + if (cache->cnt < 2) { + err = sp_1024_ecc_mulmod_fast_32(r, g, k, map, ct, heap); + } + else { + err = sp_1024_ecc_mulmod_stripe_32(r, g, cache->table, k, + map, ct, heap); + } + } + + return err; +#endif +} + +#else +#if defined(FP_ECC) || !defined(WOLFSSL_SP_SMALL) +/* Generate the pre-computed table of points for the base point. + * + * width = 8 + * 256 entries + * 128 bits between + * + * a The base point. + * table Place to store generated point data. + * tmp Temporary data. + * heap Heap to use for allocation. + */ +static int sp_1024_gen_stripe_table_32(const sp_point_1024* a, + sp_table_entry_1024* table, sp_digit* tmp, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 td; + sp_point_1024 s1d; + sp_point_1024 s2d; +#endif + sp_point_1024* t; + sp_point_1024* s1 = NULL; + sp_point_1024* s2 = NULL; + int i; + int j; + int err; + + (void)heap; + + err = sp_1024_point_new_32(heap, td, t); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, s1d, s1); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, s2d, s2); + } + + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(t->x, a->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(t->y, a->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(t->z, a->z, p1024_mod); + } + if (err == MP_OKAY) { + t->infinity = 0; + sp_1024_proj_to_affine_32(t, tmp); + + XMEMCPY(s1->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + s1->infinity = 0; + XMEMCPY(s2->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + s2->infinity = 0; + + /* table[0] = {0, 0, infinity} */ + XMEMSET(&table[0], 0, sizeof(sp_table_entry_1024)); + /* table[1] = Affine version of 'a' in Montgomery form */ + XMEMCPY(table[1].x, t->x, sizeof(table->x)); + XMEMCPY(table[1].y, t->y, sizeof(table->y)); + + for (i=1; i<8; i++) { + sp_1024_proj_point_dbl_n_32(t, 128, tmp); + sp_1024_proj_to_affine_32(t, tmp); + XMEMCPY(table[1<x, sizeof(table->x)); + XMEMCPY(table[1<y, sizeof(table->y)); + } + + for (i=1; i<8; i++) { + XMEMCPY(s1->x, table[1<x)); + XMEMCPY(s1->y, table[1<y)); + for (j=(1<x, table[j-(1<x)); + XMEMCPY(s2->y, table[j-(1<y)); + sp_1024_proj_point_add_qz1_32(t, s1, s2, tmp); + sp_1024_proj_to_affine_32(t, tmp); + XMEMCPY(table[j].x, t->x, sizeof(table->x)); + XMEMCPY(table[j].y, t->y, sizeof(table->y)); + } + } + } + + sp_1024_point_free_32(s2, 0, heap); + sp_1024_point_free_32(s1, 0, heap); + sp_1024_point_free_32( t, 0, heap); + + return err; +} + +#endif /* FP_ECC || !WOLFSSL_SP_SMALL */ +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^128, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * table Pre-computed table. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_stripe_32(sp_point_1024* r, const sp_point_1024* g, + const sp_table_entry_1024* table, const sp_digit* k, int map, + int ct, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 rtd; + sp_point_1024 pd; + sp_digit td[2 * 32 * 5]; +#endif + sp_point_1024* rt; + sp_point_1024* p = NULL; + sp_digit* t; + int i; + int j; + int y; + int x; + int err; + + (void)g; + /* Constant time used for cache attack resistance implementation. */ + (void)ct; + (void)heap; + + + err = sp_1024_point_new_32(heap, rtd, rt); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, pd, p); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 32 * 5, heap, + DYNAMIC_TYPE_ECC); + if (t == NULL) { + err = MEMORY_E; + } +#else + t = td; +#endif + + if (err == MP_OKAY) { + XMEMCPY(p->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + XMEMCPY(rt->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + + y = 0; + x = 127; + for (j=0; j<8; j++) { + y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 128; + } + XMEMCPY(rt->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(rt->y, table[y].y, sizeof(table[y].y)); + rt->infinity = !y; + for (i=126; i>=0; i--) { + y = 0; + x = i; + for (j=0; j<8; j++) { + y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 128; + } + + sp_1024_proj_point_dbl_32(rt, rt, t); + XMEMCPY(p->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(p->y, table[y].y, sizeof(table[y].y)); + p->infinity = !y; + sp_1024_proj_point_add_qz1_32(rt, rt, p, t); + } + + if (map != 0) { + sp_1024_map_32(r, rt, t); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_1024)); + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (t != NULL) { + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_32(p, 0, heap); + sp_1024_point_free_32(rt, 0, heap); + + return err; +} + +#ifdef FP_ECC +#ifndef FP_ENTRIES + #define FP_ENTRIES 16 +#endif + +/* Cache entry - holds precomputation tables for a point. */ +typedef struct sp_cache_1024_t { + /* X ordinate of point that table was generated from. */ + sp_digit x[32]; + /* Y ordinate of point that table was generated from. */ + sp_digit y[32]; + /* Precomputation table for point. */ + sp_table_entry_1024 table[256]; + /* Count of entries in table. */ + uint32_t cnt; + /* Point and table set in entry. */ + int set; +} sp_cache_1024_t; + +/* Cache of tables. */ +static THREAD_LS_T sp_cache_1024_t sp_cache_1024[FP_ENTRIES]; +/* Index of last entry in cache. */ +static THREAD_LS_T int sp_cache_1024_last = -1; +/* Cache has been initialized. */ +static THREAD_LS_T int sp_cache_1024_inited = 0; + +#ifndef HAVE_THREAD_LS + static volatile int initCacheMutex_1024 = 0; + static wolfSSL_Mutex sp_cache_1024_lock; +#endif + +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ +static void sp_ecc_get_cache_1024(const sp_point_1024* g, sp_cache_1024_t** cache) +{ + int i; + int j; + uint32_t least; + + if (sp_cache_1024_inited == 0) { + for (i=0; ix, sp_cache_1024[i].x) & + sp_1024_cmp_equal_32(g->y, sp_cache_1024[i].y)) { + sp_cache_1024[i].cnt++; + break; + } + } + + /* No match. */ + if (i == FP_ENTRIES) { + /* Find empty entry. */ + i = (sp_cache_1024_last + 1) % FP_ENTRIES; + for (; i != sp_cache_1024_last; i=(i+1)%FP_ENTRIES) { + if (!sp_cache_1024[i].set) { + break; + } + } + + /* Evict least used. */ + if (i == sp_cache_1024_last) { + least = sp_cache_1024[0].cnt; + for (j=1; jx, sizeof(sp_cache_1024[i].x)); + XMEMCPY(sp_cache_1024[i].y, g->y, sizeof(sp_cache_1024[i].y)); + sp_cache_1024[i].set = 1; + sp_cache_1024[i].cnt = 1; + } + + *cache = &sp_cache_1024[i]; + sp_cache_1024_last = i; +} +#endif /* FP_ECC */ + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * r Resulting point. + * g Point to multiply. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_32(sp_point_1024* r, const sp_point_1024* g, const sp_digit* k, + int map, int ct, void* heap) +{ +#ifndef FP_ECC + return sp_1024_ecc_mulmod_fast_32(r, g, k, map, ct, heap); +#else + sp_digit tmp[2 * 32 * 5]; + sp_cache_1024_t* cache; + int err = MP_OKAY; + +#ifndef HAVE_THREAD_LS + if (initCacheMutex_1024 == 0) { + wc_InitMutex(&sp_cache_1024_lock); + initCacheMutex_1024 = 1; + } + if (wc_LockMutex(&sp_cache_1024_lock) != 0) + err = BAD_MUTEX_E; +#endif /* HAVE_THREAD_LS */ + + if (err == MP_OKAY) { + sp_ecc_get_cache_1024(g, &cache); + if (cache->cnt == 2) + sp_1024_gen_stripe_table_32(g, cache->table, tmp, heap); + +#ifndef HAVE_THREAD_LS + wc_UnLockMutex(&sp_cache_1024_lock); +#endif /* HAVE_THREAD_LS */ + + if (cache->cnt < 2) { + err = sp_1024_ecc_mulmod_fast_32(r, g, k, map, ct, heap); + } + else { + err = sp_1024_ecc_mulmod_stripe_32(r, g, cache->table, k, + map, ct, heap); + } + } + + return err; +#endif +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * p Point to multiply. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_1024(const mp_int* km, const ecc_point* gm, ecc_point* r, + int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_digit kd[32]; +#endif + sp_point_1024* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_32(heap, p, point); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 32, km); + sp_1024_point_from_ecc_point_32(point, gm); + + err = sp_1024_ecc_mulmod_32(point, point, k, map, 1, heap); + } + if (err == MP_OKAY) { + err = sp_1024_point_to_ecc_point_32(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_32(point, 0, heap); + + return err; +} + +#ifdef WOLFSSL_SP_SMALL +/* Striping precomputation table. + * 4 points combined into a table of 16 points. + * Distance of 256 between points. + */ +static const sp_table_entry_1024 p1024_table[16] = { + /* 0 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 */ + { { 0xe0162bc2,0xbf9c7ec6,0x10a89289,0xddecc6e3,0x9e499d81,0x5d599df0, + 0x6d358218,0x9a96ea28,0x70c5f8db,0x01aec7d3,0x8cf5d066,0xe72e4995, + 0x3e91d7f8,0xc2e7297d,0xda9f2f5a,0x8621db92,0x5a5679ed,0x4b26c867, + 0x2c56aac1,0x233385df,0xc6a13f99,0xb88e74d4,0xffa8ec11,0x1214b173, + 0x1f3f9fef,0xa0386a27,0xc0e7b44e,0xbd9b1b4e,0xeecd3496,0xafe528dc, + 0x1c49f80b,0x8dfff96a }, + { 0xc03c0c83,0xb4a4753a,0xabcdcd75,0x68e69d18,0xf775b649,0xe3839b88, + 0xbf58f352,0x803f949a,0xbd0bc15c,0x5f702679,0x8ff298c2,0x85bf5d16, + 0xc6c7976e,0x3f6ebd98,0x45e3e1b4,0x20618af4,0x54e64093,0x67d5598e, + 0x504fed9e,0xb047283b,0x70d87517,0x450cabfd,0x3f5addbe,0x47d628bf, + 0x78cb4cca,0x0037ef30,0x6b1c4908,0x4e148d3c,0x4fcfd837,0xe256d329, + 0xde3c01f3,0x2aa1207b } }, + /* 2 */ + { { 0x755c2a27,0xcf3e0bb2,0x59585c44,0xd38e42f9,0x19285e60,0x46b13e0f, + 0x76273d0f,0xc3ecd0c0,0x193c569a,0x7800f085,0x4351818a,0xf04e74ab, + 0x8496363b,0x9258aa38,0xb8c894fe,0x8456617c,0x2af969a0,0x8bc62aaa, + 0x5a4668d9,0x66c2280b,0xa992f4fa,0xbc9df58e,0x3f401e99,0x5db0b7d9, + 0xc4c38c0e,0xe0614fe1,0x2ccdf6b3,0xd531151c,0xe143b618,0x1c7575ec, + 0xdf9398a4,0x40247985 }, + { 0x8f055746,0xfba25178,0x0ab1e6e0,0xc5ba0040,0xac292697,0xe1b194fb, + 0x5b4f4740,0x77152119,0x9bb7ba54,0x250091d0,0xb9a139a4,0x7a674861, + 0xf353aa7e,0xba8413b3,0x2443ceee,0xafe77192,0x3847bbd0,0x14468d36, + 0x3da4942d,0x61f79ff6,0xd425b456,0x1563a1c1,0x75ff4630,0x3c270fcd, + 0xeb2802c9,0x42072090,0xc85c7004,0x68f0cdcb,0xfa032e74,0xca4372fb, + 0xc8b79d80,0x1a6fd1e6 } }, + /* 3 */ + { { 0x8d5116a3,0x967a901a,0xb2f5f47f,0x0b844394,0x60ebaf3b,0xe39ad452, + 0x60ccfc0c,0x1e1be617,0xcc3f53f2,0xac07e3d2,0x1ed11bb6,0xdd838e0e, + 0x1c15b0c2,0x45475307,0x920fe5b8,0x70dd4748,0xe471896d,0x1a20be2d, + 0x59276c7c,0x3c3fad8a,0xc886ee07,0x026a1cc3,0x6e831ac4,0x9fdb6f37, + 0xac501d65,0x26a35d1a,0x40da8574,0x0ae98905,0xabd734e5,0x65dde0a4, + 0x15614750,0x29b7d4dc }, + { 0xcbf4e20b,0x44b3c2cb,0x58cc44c5,0x1c3f548f,0x5b0cac1f,0x39809b54, + 0x00f80621,0x0c0f02b5,0x066905e0,0xe612b890,0x8350188c,0x8f158ed7, + 0x3f5576b2,0xc01dc458,0xa45492e0,0x29803272,0x0ff92443,0x77a5623a, + 0x29d0dc41,0xd12a2b00,0x2780e87a,0xb4125459,0x0d53f272,0x1ebcf903, + 0x24301e8d,0xbae6ea40,0xa37d0798,0x1e5f3f2f,0x22b4126c,0x9342c310, + 0x5382497e,0x5d092802 } }, + /* 4 */ + { { 0x4b59213a,0xf5b495d0,0x8d70200e,0xca672039,0x2b6771c1,0x4bcb09a6, + 0x2b9eb0cb,0x26adeed4,0x8cdba212,0xeb544754,0xf08890d1,0x0e1abfcd, + 0x698e46b4,0x52509963,0x82e9c138,0xe1bff0b0,0x51099a71,0xa189e4cd, + 0xc9b91cc7,0x2360c9bc,0x137ec4be,0x9bd4d7dc,0xd1519f6e,0xd0356521, + 0xcf832503,0xbf5f6d78,0x8deea2b4,0xe4301031,0xef4c319c,0xc3132494, + 0x0f1fa7d7,0x2ab3bd47 }, + { 0x922c9fbb,0x5753b680,0x0f16c6d1,0x869e7dc8,0xbac16efc,0x83445135, + 0x846d1d9b,0x4326a3b4,0xb2d62c21,0xb517fee3,0x0b292ad5,0x6905afa2, + 0x2cadac13,0x2a57131a,0xebdbca8d,0xcd904d8f,0x3f365fb2,0xdfeda86f, + 0xdc7eaa1c,0x7097b208,0xa45e77c0,0x89a35a84,0xcf5d118e,0x417a062c, + 0x1f6e99e8,0x3c0c04a8,0xba7a087d,0xc44704b0,0x3ea22ad2,0x6f8a27d1, + 0x4c27d229,0x93a4b416 } }, + /* 5 */ + { { 0x1f1efb7a,0xd4271bc1,0x33fccc0d,0xae4e68e6,0xb11f50a8,0x9d9bc8f1, + 0xaf076089,0x5430398f,0x443d0e03,0x45e242fb,0xf6e3d4c1,0x73ec2519, + 0xba9bad09,0xab70f790,0xf9add10f,0xde612ad5,0x14e942b4,0xb837e54e, + 0xddb8b68a,0x175a56d3,0x1ac2a408,0xe85b233c,0xf0c80f94,0xf8ff6c30, + 0x898db4f9,0x4b7f3fb7,0x45a7dcdd,0xa2c6044f,0xfe3d3895,0xf3abb2f6, + 0x32ee7763,0x342ce0d7 }, + { 0xcf491b1f,0xeb261394,0x1909e395,0xdcaaeed7,0x9fe4dbea,0xdcc4055a, + 0x493d604d,0x17a6611d,0x1ce5ebef,0xba445a3a,0xe3989cb5,0xe82e2858, + 0x83f58406,0xb96f4282,0xa156cf55,0x99877b99,0x4e166a0e,0xaf906a66, + 0xb2976d13,0xcea1d353,0x36c61a01,0xefc16f27,0xb0f55d86,0xdb04c433, + 0x8eb34c01,0x3cb4b269,0x2ae60280,0x38d07f78,0x43be3ec5,0x43ac3bcb, + 0xe156fd20,0x455f4af3 } }, + /* 6 */ + { { 0x95532833,0x2e6fe0a6,0xd626d067,0xabca228e,0x649e73bd,0x22aef3d9, + 0xf03c4c0c,0x2083a87a,0x35169b45,0xe954e75d,0x74506a89,0x577509ee, + 0x2aeacf90,0x49cb276e,0xfa409f91,0x08275d77,0xf0bbd6b9,0x61eb6f3d, + 0xe4132704,0x948202cb,0xb1c498b1,0x35f3fc21,0x361fee59,0x76c68ba8, + 0x50e051f3,0xa18cbbd9,0x318e7042,0x2384a879,0x80dd1e8b,0x292abead, + 0x5c37c334,0x65713c29 }, + { 0xceb77b9a,0xdccca8e9,0x23b69469,0x2f97e727,0xa01d6b28,0xc76abee6, + 0x5abecdfe,0x3925203d,0x29290d70,0x89448082,0xb0314438,0xf9931424, + 0x7cd447c3,0x04209df1,0xc855c827,0x7c6f2059,0x56c0e069,0xd97d7862, + 0x412d94c4,0x5a9db6fe,0x994c41dd,0x19a64591,0xc89e21a3,0x12348aa1, + 0xc6a03f0e,0xd6904b50,0xa616feac,0x55c15156,0x7cc7693b,0x4e36d1b5, + 0x3bae3c38,0x6b0e996c } }, + /* 7 */ + { { 0xcceced00,0x32789fab,0xe5b7aa66,0x3237e71a,0x2ddebcdf,0x87b2e269, + 0xb61dad8f,0xb7245120,0xd35f803c,0xe11e5e48,0x98e50f0d,0xfb4df5d7, + 0xbcd2ab92,0x60ee68b4,0x1ce3363d,0x98ab2f5c,0x7cd42647,0x15ba39da, + 0x83f4fb3f,0x1a6572eb,0xe56f08db,0x0f77de88,0x172562c2,0x1743761e, + 0x8a58f0f4,0xbe349ff8,0x84d1d6e2,0xe04da71b,0x9e9ff3b4,0x368f0342, + 0x678223f8,0x4022a205 }, + { 0x83847375,0x527bbd05,0x3f451af0,0x3ae56b62,0x4b2c7f18,0x6198f24d, + 0x4525b98d,0xee323f5b,0x0e0884b5,0xa9d8d39a,0xfb12c776,0xd005d7f6, + 0x708bc154,0xd71c483e,0x742541bc,0x8ca6fd28,0xf8397ddb,0x0af3dccd, + 0x3eccf243,0xb80d3125,0x58d81b8d,0xc743a108,0x71391f68,0x3f48eb21, + 0x33bb657f,0x493aff88,0x07e47e31,0x1d15ed66,0xe08279f6,0x10159b11, + 0x24a6a956,0x312179cb } }, + /* 8 */ + { { 0xfb99cfe6,0x950323d3,0xc9334178,0x7b09bc26,0x7cbdfb6f,0x64111e41, + 0x89a75760,0x91141744,0x10919cb0,0x4c633df9,0x396bfd2f,0x715fc7c7, + 0x8cab62db,0x8ca19512,0x4db81aac,0x30672473,0xb4c4c54a,0xe67a246b, + 0xbf229646,0xd77ea0fa,0xfa5b5d70,0x5bed15f1,0xc2f192f3,0xa5686da5, + 0x7f6690ad,0xdecac72a,0xcaa50b7d,0x0c4af2a2,0x6049ad2f,0xf44631c1, + 0x04ecf056,0x325d2796 }, + { 0x4848c144,0xee11fb55,0xb6a7af32,0x4e062925,0x369e0f9a,0x125b68e1, + 0xca53b21e,0xad9bdae6,0x2e98ea1b,0xf50d605c,0x9f2fa395,0xbdb9e153, + 0xe91532f5,0x4570e32d,0x46a250d7,0x810698ae,0xad9d9145,0x7fd9546c, + 0x11e97a5e,0xabf67721,0x249f82e9,0xca29f7d5,0x9851df63,0xa9c539a9, + 0x71d0e3e5,0xfd84d54b,0x041d2b56,0xd1e0459c,0xfd80096a,0xceb3eb6e, + 0xe32a79d3,0x19d48546 } }, + /* 9 */ + { { 0xb540f5e5,0xfe19ee8f,0x04e68d17,0x86d2a52f,0xadbdc871,0xd2320db0, + 0xd03a7fc8,0xa83ad5a8,0x08bcb916,0x54bf83c7,0x2e51e840,0x092133ea, + 0xcb52dddf,0xbce38424,0x31063583,0xd5c7be40,0x458e3176,0xc1ebb9df, + 0xbc4dabbf,0xafb19639,0xc05725a8,0x36350fe4,0x84e1cd24,0xac4a0634, + 0xc145b8de,0xadf73154,0xb3483237,0x0aa6dd9e,0xcbff2720,0xa3345c3d, + 0xb4e453b0,0x1b3ace6c }, + { 0x90a8bdc5,0x0343e5e9,0x6306a089,0xa203bf9d,0x8e48520e,0x98489a35, + 0xde7d1d06,0xbd17debe,0x5f795d3f,0x8fafa6d7,0x387b0a3f,0xa4ceb630, + 0xffddeafa,0xe0166b32,0x7e764e02,0xa2fe2054,0xe871f304,0x55ab9824, + 0x952ec45e,0xa2bd36bb,0xa90d20ca,0x7b4c1484,0x75bcfb53,0x5319f387, + 0x6982c4e5,0x34238a4a,0xa102921d,0xa2bb61c7,0xdb3ab17e,0x1e061b64, + 0x192f0a14,0x538ec33e } }, + /* 10 */ + { { 0x576374c2,0xe53c7785,0x84727040,0xe60526d1,0x228ca044,0x8a066dc8, + 0xf1ce1313,0x1fe1c1b2,0xcdeb0c5d,0x2aeec832,0x9cbf826f,0xa7596699, + 0xde77a589,0xcd188e81,0x118d1254,0xe5ce0fe0,0x0790b86a,0xa142a984, + 0x39ac28ce,0xe28f043f,0x87de5804,0x4eef8290,0xf639a8c5,0x83c31b32, + 0x5887794f,0xd70454a7,0x18b1b391,0xca635d50,0x31d9c795,0xcefea076, + 0xb6f8aa25,0x13cbee76 }, + { 0x8d3f34f3,0x79cabe0f,0xa3617fe3,0xbda9c31c,0xdd9426a1,0xb26dee23, + 0xf29c9104,0xe9dd9627,0xe2c6cd3b,0x033eb169,0xfcba2196,0x8a73f492, + 0xb858c83c,0x92e37e0b,0x23b3fbb7,0xe4f2aca6,0x64be00a2,0x8101fb1e, + 0x948f6448,0x91a7826a,0x907260e7,0x414067b4,0xe30bb835,0xf774aa50, + 0xc999c06e,0xf922ca80,0x0ba08511,0x6b8635b9,0x25fa04f0,0xbf936b5c, + 0xe02e8967,0x4e0a1ada } }, + /* 11 */ + { { 0x8ba29c4d,0x00ca6670,0x22988094,0xc08240ce,0x16dda752,0x21c5ca67, + 0xabbbfa34,0x689c0e45,0x3ed28b72,0x1d7545fd,0xd7c56ab4,0x5f221198, + 0x38759d65,0x4b3d8f74,0x8fe50b89,0x93490dfb,0xe80eba16,0xb641f5d7, + 0x79acb537,0x7b0da5eb,0x0c1d5e5e,0xab6b1497,0xa5da429a,0x2338e68d, + 0x2f6d2f25,0xe010c437,0x6530f3a7,0x226f16d2,0xcbef08bc,0xefb0f7b6, + 0x9f99c999,0x733e30d9 }, + { 0xa42a38f9,0xecfe1582,0x4730b500,0xaec2d58e,0xde976b2c,0x2ee2f2a7, + 0xa969c1bb,0xf0539db5,0xfcecdb4a,0x31954168,0xe7a8e902,0xf2f7348a, + 0x3121541f,0x1d58d7cc,0x2202ae52,0x5d25b75c,0xf40835a7,0xdea9965a, + 0x529b4e46,0x3feb6a41,0xbd27ad9b,0x5c97fb6f,0x261f900b,0xd87554c0, + 0x04d5b19e,0xb43031d9,0xcb219b9c,0x33d5e9b8,0x3ee00bcf,0x7a43d492, + 0xb79a5c0c,0x56facb39 } }, + /* 12 */ + { { 0x7c834915,0x667eaed6,0xbc5eb64d,0x9f77aa6a,0x25d62011,0x729ebcb6, + 0x699fd9c2,0x0aee24f2,0x2b8d4f6c,0xe1eb5874,0x14c976d6,0x7f12710c, + 0xf6d9ea65,0x91390335,0x06b50064,0x668b7049,0x0876ee4f,0x65969a0e, + 0x2f9d9360,0xf901bf3f,0xb499e3ce,0xfb1a8651,0xf2dbcaaa,0x80b953fb, + 0x973b06b6,0x312cc566,0x3af36c64,0x3534d9c3,0x10ffd815,0xe4463a52, + 0xf18c2b91,0x57ea2b4b }, + { 0x8aa0f2f2,0x00f5e162,0x0e46bcaa,0x8c7e75c5,0xa4a2c42d,0x97ab479a, + 0x14baa202,0xb4f308ea,0x6943cc2e,0xa901bd14,0xeed58804,0xbb125fee, + 0x9d180f7c,0x6502c8f9,0x1580c61c,0xe5353919,0x27101ee3,0x7e278069, + 0xfaa72717,0x7a0a40a1,0x4c75b153,0x32edce02,0x538f1c22,0xda23660b, + 0xbe307d2e,0x4d511e98,0x9baee0b4,0x24276e40,0x7ff1f307,0xa78c3927, + 0xea7935c9,0x60480b46 } }, + /* 13 */ + { { 0x3872ece3,0x31087d66,0x955b70f8,0x5f29be7d,0x9cf95bb8,0xb50b4fc7, + 0xdbffa621,0xbae3b58d,0xe022ba5d,0x0e61d280,0x4181449c,0x78ae5117, + 0xcf555485,0x0b132840,0xb8ce0b0e,0x800ed1b6,0x78d5de3d,0x35dffdd5, + 0x69a56b47,0xf7e42374,0x8d910ae7,0xd5e32369,0x6313c7c7,0xb6ff52a0, + 0xa92de9e5,0x5a2fe20d,0xd12110bb,0x41b347d3,0x40c16f23,0xc5905edb, + 0x9a8f88cc,0x0774a0d3 }, + { 0xe3b6c106,0x3ae181ab,0x8de150b7,0x4ebe163f,0x6f354836,0xcf75b82f, + 0x3ac7ac16,0xaa0d2063,0x291722af,0x5c680668,0x11545553,0x73941e61, + 0xbf5de3f7,0x17127e38,0x1afb41da,0x32cfdf03,0x87bc8663,0xc6893c91, + 0xa62c9c99,0x75046744,0x962c1947,0x96866e2d,0x378cdf4c,0x489ec8df, + 0x3407fa32,0x3a60709b,0x551290d1,0xd37d2159,0xbab92273,0x9623d303, + 0x2432014b,0x08151954 } }, + /* 14 */ + { { 0xb05f2b26,0x569044f3,0x80b9f76c,0xb35a294a,0x4290f6ae,0x8839fe28, + 0x026a5877,0x761cfb23,0x2e5ff9c3,0x768926b6,0x0b11c576,0xbae6cd20, + 0x72a03efe,0xdc857756,0xe1bad63a,0x0cae074a,0xd709d99c,0x3fe491a1, + 0x6501d9c1,0x76c5ded6,0xc32aeff7,0x1da6eca1,0xc57683e8,0x50849d55, + 0xdf98d847,0x9e392e9c,0x64d9a564,0xfad7982f,0xa37b98b2,0xf7c3bdb7, + 0xf0860497,0x1fe09f94 }, + { 0x7648cc63,0x49a7eaae,0x67cfa714,0x13ea2511,0x653f4559,0xfc8b923c, + 0x81a16e86,0xd957619b,0x3c864674,0x0c7e804b,0x1616599a,0xfc88134a, + 0x0a652328,0x366ea969,0x4bc9029e,0x41532960,0xae2aad2b,0xef9e1994, + 0x7f10bef5,0x9e2a8c52,0xc67bf860,0x73dcb586,0x844cc25d,0xf61a43fa, + 0x74eb3653,0xd74e7eea,0xdd240f02,0xf3356706,0xfd83bcb4,0xeec7694c, + 0xdb62526a,0x4de95786 } }, + /* 15 */ + { { 0x3deac2f7,0x4867d315,0xb61d9a8e,0xa084778a,0x0ab7b2d5,0xf3b76f96, + 0xcfdf4f79,0x00b30056,0x31ab8f4b,0xd0701e15,0x9c779d01,0x07f948d5, + 0x82675371,0x7c994ebc,0x48bad4c0,0x1104d4ee,0xbfc9d058,0x798ce0b5, + 0x309fa80b,0xc7ca898d,0xacb33eaf,0x0244f225,0x5b2f3175,0xd51e8dfc, + 0xa4d7be34,0x3e49ba6b,0xbda02b43,0x1760f4c7,0x4435275a,0x37e36a7e, + 0xe636980c,0x1c94418b }, + { 0x09dc1414,0x43a21313,0x43c93537,0x060765fc,0xdf5f79ce,0x6ff3207a, + 0x85d4cfca,0x6f18b1fa,0x63e995ab,0xf5c4272e,0xa82b3002,0x121a09e4, + 0x97147f16,0x82b65d1b,0x20a7fe26,0x4993c20c,0xe6716726,0x99c9cb98, + 0xfeb440a0,0x5a02d673,0x251b4bc5,0x3f3fa9e1,0xa05338ea,0x75dbc474, + 0x7b09f6cb,0x3cb4044b,0x80434609,0x6767da18,0x098ceac2,0x97851422, + 0xb55235ba,0x611bfbb2 } }, +}; + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^256, ... + * Pre-generated: products of all combinations of above. + * 4 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_base_32(sp_point_1024* r, const sp_digit* k, + int map, int ct, void* heap) +{ + return sp_1024_ecc_mulmod_stripe_32(r, &p1024_base, p1024_table, + k, map, ct, heap); +} + +#else +/* Striping precomputation table. + * 8 points combined into a table of 256 points. + * Distance of 128 between points. + */ +static const sp_table_entry_1024 p1024_table[256] = { + /* 0 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 */ + { { 0xe0162bc2,0xbf9c7ec6,0x10a89289,0xddecc6e3,0x9e499d81,0x5d599df0, + 0x6d358218,0x9a96ea28,0x70c5f8db,0x01aec7d3,0x8cf5d066,0xe72e4995, + 0x3e91d7f8,0xc2e7297d,0xda9f2f5a,0x8621db92,0x5a5679ed,0x4b26c867, + 0x2c56aac1,0x233385df,0xc6a13f99,0xb88e74d4,0xffa8ec11,0x1214b173, + 0x1f3f9fef,0xa0386a27,0xc0e7b44e,0xbd9b1b4e,0xeecd3496,0xafe528dc, + 0x1c49f80b,0x8dfff96a }, + { 0xc03c0c83,0xb4a4753a,0xabcdcd75,0x68e69d18,0xf775b649,0xe3839b88, + 0xbf58f352,0x803f949a,0xbd0bc15c,0x5f702679,0x8ff298c2,0x85bf5d16, + 0xc6c7976e,0x3f6ebd98,0x45e3e1b4,0x20618af4,0x54e64093,0x67d5598e, + 0x504fed9e,0xb047283b,0x70d87517,0x450cabfd,0x3f5addbe,0x47d628bf, + 0x78cb4cca,0x0037ef30,0x6b1c4908,0x4e148d3c,0x4fcfd837,0xe256d329, + 0xde3c01f3,0x2aa1207b } }, + /* 2 */ + { { 0x01900955,0xa95b6dae,0xceb4656d,0xa5dc9cc1,0xe72fe95b,0x50c78907, + 0xa040c334,0xa1ae5447,0x7952ea6e,0x91191370,0x6d097305,0x54ff7343, + 0xbda4d10f,0xa4db0074,0x91644070,0xfd5306f1,0x8b24522c,0x14b9fe73, + 0x7849f762,0x1468dad6,0xb0dcd2e4,0x87b29a18,0x5e1ad492,0xadd7f1a1, + 0xdbba2a1a,0x9ac63a81,0x81223379,0x01379c5b,0xb0e53bc8,0xf402b2f0, + 0x0bf13b61,0x8c3eb27f }, + { 0xe513696f,0x9a4ad3e1,0x18c81ffa,0x0350ba5c,0x3c033d13,0x1e2fc136, + 0x17a531bc,0x53da6e71,0x1aed610d,0x42ec6490,0xe99ff567,0xd33e8df7, + 0x3deed12a,0xe4aad73e,0x180f4deb,0xd983b465,0x502f30b4,0x99365269, + 0xa8918d7f,0x7e2799ab,0x700fc79a,0x0ffe84b6,0x40bfd8c2,0x7b4400d6, + 0x5d2641bd,0xc3a21d21,0xc32621cb,0x79839442,0xb1401e83,0xace6500b, + 0x251c4310,0x7bf4163e } }, + /* 3 */ + { { 0xe3fd589e,0x1c174f88,0xdf974a03,0xdb501790,0x3e70549f,0xd09623e3, + 0x15924f34,0x8d091eff,0xf9b65ac5,0xeef79cad,0x3f69c2cf,0xd2cc4262, + 0x52cd82bc,0x817d9032,0xa5f1dddd,0xacf4f4d9,0x5011b6bd,0xd0612635, + 0x2ed140c9,0x9f74490d,0x4db686d2,0x64092e8c,0x776b0fcc,0x225eef16, + 0xdf16aeb6,0x0e8c01e9,0x84bbd82a,0x62836741,0x8956e337,0x757574e2, + 0x705a7f07,0x9871edc6 }, + { 0x776535f7,0xbd0b76d5,0x2635b3b8,0x5214d602,0x9d216f64,0xc0c25ad9, + 0x5515bf75,0xfd4df3a7,0x5e9f1675,0x24a625bc,0x406873e7,0x3c35efb7, + 0xbb2e5c4a,0xef5c9a33,0x806b198a,0xa971b35e,0xa3c690ed,0x9f5c0ca5, + 0x8e1e2341,0xa8d5dd89,0x955ad9e4,0x4cecbcce,0x248d3416,0x2ecf4407, + 0x45c0af6e,0x1abb3811,0x1c780fff,0x3f4bee82,0xc272ed57,0xd14df768, + 0x371637ad,0x397ed10a } }, + /* 4 */ + { { 0x755c2a27,0xcf3e0bb2,0x59585c44,0xd38e42f9,0x19285e60,0x46b13e0f, + 0x76273d0f,0xc3ecd0c0,0x193c569a,0x7800f085,0x4351818a,0xf04e74ab, + 0x8496363b,0x9258aa38,0xb8c894fe,0x8456617c,0x2af969a0,0x8bc62aaa, + 0x5a4668d9,0x66c2280b,0xa992f4fa,0xbc9df58e,0x3f401e99,0x5db0b7d9, + 0xc4c38c0e,0xe0614fe1,0x2ccdf6b3,0xd531151c,0xe143b618,0x1c7575ec, + 0xdf9398a4,0x40247985 }, + { 0x8f055746,0xfba25178,0x0ab1e6e0,0xc5ba0040,0xac292697,0xe1b194fb, + 0x5b4f4740,0x77152119,0x9bb7ba54,0x250091d0,0xb9a139a4,0x7a674861, + 0xf353aa7e,0xba8413b3,0x2443ceee,0xafe77192,0x3847bbd0,0x14468d36, + 0x3da4942d,0x61f79ff6,0xd425b456,0x1563a1c1,0x75ff4630,0x3c270fcd, + 0xeb2802c9,0x42072090,0xc85c7004,0x68f0cdcb,0xfa032e74,0xca4372fb, + 0xc8b79d80,0x1a6fd1e6 } }, + /* 5 */ + { { 0x8d5116a3,0x967a901a,0xb2f5f47f,0x0b844394,0x60ebaf3b,0xe39ad452, + 0x60ccfc0c,0x1e1be617,0xcc3f53f2,0xac07e3d2,0x1ed11bb6,0xdd838e0e, + 0x1c15b0c2,0x45475307,0x920fe5b8,0x70dd4748,0xe471896d,0x1a20be2d, + 0x59276c7c,0x3c3fad8a,0xc886ee07,0x026a1cc3,0x6e831ac4,0x9fdb6f37, + 0xac501d65,0x26a35d1a,0x40da8574,0x0ae98905,0xabd734e5,0x65dde0a4, + 0x15614750,0x29b7d4dc }, + { 0xcbf4e20b,0x44b3c2cb,0x58cc44c5,0x1c3f548f,0x5b0cac1f,0x39809b54, + 0x00f80621,0x0c0f02b5,0x066905e0,0xe612b890,0x8350188c,0x8f158ed7, + 0x3f5576b2,0xc01dc458,0xa45492e0,0x29803272,0x0ff92443,0x77a5623a, + 0x29d0dc41,0xd12a2b00,0x2780e87a,0xb4125459,0x0d53f272,0x1ebcf903, + 0x24301e8d,0xbae6ea40,0xa37d0798,0x1e5f3f2f,0x22b4126c,0x9342c310, + 0x5382497e,0x5d092802 } }, + /* 6 */ + { { 0xff2f780d,0x583a2b7e,0xd7d76b1d,0x34d26820,0x86f74aec,0xe3c32847, + 0x10823feb,0x0fd42212,0xfb5e7bf4,0x227e417e,0xa568f8cd,0x510d49b6, + 0x1781bbec,0x53bce7d6,0x2f3718b7,0x9cfe3f22,0xd9de6c1f,0x7f44e89f, + 0x3fac9b55,0xf1cc553f,0xe6f300bc,0x9d2d0846,0x9f0ae6b1,0x976c82a2, + 0x24b8bbe0,0xe63dbf5e,0x973a5aa7,0x4cac7f45,0x84dd33c7,0xc6eb6237, + 0x142fee5d,0x0a26e434 }, + { 0xacaa9a08,0x8081339f,0x5246ece1,0x40f31105,0x61393747,0x892c8170, + 0x242f02e1,0x8d8d4103,0x3b5de98a,0x482bfd20,0x5abbe952,0x89ef946b, + 0x37698249,0xb8d218b9,0x66617c7a,0xd5268e89,0x8b7d2b91,0x962e7551, + 0xfe8d67c3,0x2c5c7973,0x2b017c51,0x42e3150a,0xc1a29469,0x6f4e5ebc, + 0x531c7083,0xa39910ce,0xb77b9e50,0xaf4f6eb4,0xda120ad0,0x68cbb175, + 0xb92636ec,0x19497c61 } }, + /* 7 */ + { { 0x417659a8,0x6920b0c6,0x92cb28ff,0xc77ab9c7,0xb687797f,0x55b67180, + 0xe7759363,0x4caf58c1,0x5561b186,0x5155bdb6,0x780f4946,0x2e64e355, + 0x229a8b20,0xeb0ac9b7,0x2571bd60,0x88594d78,0xe3fa78f9,0x5dcc0939, + 0x2ac2d379,0x7b8b4830,0xb90f1444,0x505fbf60,0x3ce4b3c1,0xac610e81, + 0xd59b5c18,0x39a4f27a,0x7cea0222,0x5fa33973,0x8dff1c7b,0xe578730b, + 0x517bf7a6,0x96b91b8b }, + { 0x9aac087c,0xc1a991f4,0x6cfdb28d,0xce62f74e,0x5f7600d6,0x08d6ff9a, + 0xf917f9c9,0xd781cd04,0x3de52dbf,0x7796f5f6,0x2ed72180,0xe7db64e0, + 0x6fa4137d,0x0f0876f6,0x3ca1f716,0x3271ee64,0x7c4ab8a3,0xcb9b2058, + 0x39481047,0xcba17107,0x598c5c37,0xdf9a190d,0x6f20e125,0x0cb6e72a, + 0xf4f2902d,0xa3142204,0x7ce2dcfb,0x42d28cb9,0xa3d3c351,0xdf261b8a, + 0xcffc249d,0x73f3d315 } }, + /* 8 */ + { { 0xe6fd3673,0x5d86855b,0x9d214b7b,0x309b70af,0xdcc46cd3,0x8d332f90, + 0x595510de,0xe553c015,0x38c1251c,0x5746a096,0x85cc1bc9,0xcd7cea5b, + 0x002eba8f,0x4ffa1468,0x22fcd77c,0x10a3cb70,0xc4ea05e3,0xb6999dfb, + 0x4efa756e,0x3375a0d0,0xdced5fd8,0x4d90279e,0x251fd56e,0x48192403, + 0x82a4c5f1,0xe87633a4,0x1b34105b,0x3170d130,0x7247e578,0x93998b0f, + 0x436ba1fa,0x88934f64 }, + { 0x4713eabc,0xf09f43b0,0xaccdc517,0x4ca7dd91,0xef13ca7c,0x27daa63b, + 0x2588184b,0x8b2e5a7a,0xd95dc269,0x0a8cb612,0xe1f2f14c,0x346975a2, + 0xe172935c,0x1f29b8ed,0xd40bc1e3,0xc3cbfd6e,0x132623da,0xd3f46b3f, + 0xfb0b7681,0xc115be6d,0x56da4344,0x5e31c345,0xa8e43d98,0xa7c63f18, + 0x4bddb4ea,0x55cb2083,0x4a54f58c,0xb16a0c38,0x46fd69d9,0x74eacca2, + 0x153548e1,0x0d1898bb } }, + /* 9 */ + { { 0xe35ef043,0x4ea73461,0x3496b564,0x107b67d9,0xd0f83a3c,0xd62c173b, + 0x51d29c35,0xfad4b038,0x71b1c1a4,0x3f42882a,0x54b43b9e,0x5d2bcf66, + 0x2abdf543,0xc77b15aa,0xdabe3dc1,0x5cb38a80,0xa481673b,0x15fda0ae, + 0xe7b90ebe,0x86996b4d,0x2bc8f3d8,0x84f87e25,0x37c4e424,0xaded03d6, + 0xd7a7afd8,0xe5ede666,0xa1ccb93a,0x80dd95a2,0x46fba391,0xa55cfd25, + 0x46f82e60,0x2bdab1dc }, + { 0xfa6fed61,0x7a4de22b,0xcc8dd94e,0xca458aa5,0x071222f5,0x3e372df1, + 0xe5aff377,0x06a4b44f,0x4a738e6d,0xbc2d0ba7,0x5f31f136,0x1a470e1d, + 0xe102a911,0x77ff933a,0x310c7885,0x8b380a50,0x783fc5ac,0x9f3c0228, + 0x44725d06,0xec668925,0x5ac84221,0x878f0e16,0xcfda6e8a,0x9a3af1af, + 0x78cd2aba,0x0183ed37,0x826d0eae,0x32cdbd60,0xcbee6415,0xb3234661, + 0xb9c10120,0x353eb892 } }, + /* 10 */ + { { 0x10b5521e,0xc8fdcad6,0x52e702f0,0x1a11b440,0x8ffda49c,0x6302680d, + 0xcbf36bad,0xcdb9654a,0x4c10a2d7,0x7b58ce11,0xe630e7e0,0x1e5d1f7d, + 0x6760a813,0x8cbe3d7d,0x6480d77f,0xeb35866b,0x7f036219,0x58728cf3, + 0x42a8a757,0xdd5865ed,0x906a2870,0x283f1f1d,0xa51f906b,0x79e23fa4, + 0x543b20a8,0xf2ac6e83,0xb81e7754,0x4f0b6379,0x840016ee,0x57fbc0d4, + 0xe621b67d,0x8da20771 }, + { 0xecce65ec,0x3c855004,0xb748185e,0x76d10d1f,0x78797ad2,0x64be7bca, + 0x77e54aad,0x43444db0,0xbe0df0ff,0x17b6b0c9,0x055086a4,0x8fc4256c, + 0xfd74d5a3,0xf952c43b,0x01c4edb8,0x501e005a,0x4a57e328,0xd5172dfc, + 0x535d6ee3,0xdb40ce4e,0x0c650918,0xbaef1e5c,0x857561fc,0xe85145e7, + 0x34a224c6,0xe468536a,0x0ec0e0a2,0x69a8e227,0x242b03fc,0xb3f52247, + 0xc3bebd5f,0x862f55e2 } }, + /* 11 */ + { { 0x226049fe,0x2d6a390f,0xdcbbc9fb,0xcc92a578,0x97634fb7,0xa52feca4, + 0x3dea5893,0x2b340cb6,0x2a49e916,0xa39f338a,0x949e41f3,0x26b2df3d, + 0x065a7e40,0xc71c7cdb,0x468281a2,0x4a9b84a0,0x731eeeca,0x63eeb503, + 0x76cbb725,0xe6d09134,0xb94a678c,0x0cf979a9,0x808fd9f1,0xb44d8c3b, + 0xe0afc5b9,0xe60da613,0x3ea5be69,0x52dce7de,0xdc1ee74f,0x3a5d6864, + 0x3bc80790,0x71ab2891 }, + { 0x3b5b60ad,0xcf618fc4,0x4a0c3184,0x0afb5e30,0xbc403302,0xd22381cc, + 0xdb1c0c66,0x33cf8953,0xa6112a8d,0x9c994e4d,0xd1967a86,0xd7aae2c3, + 0x5b7acd29,0xc28d5493,0x6c9a57fb,0x8075bd13,0x9c8427f9,0xc9c0373e, + 0x193225f5,0x2cbca18d,0x442c018c,0x73777d13,0xfbb3a727,0xebe5ed47, + 0x1962dc18,0x70437d49,0x2dc08806,0xf39c1e09,0x15fff35c,0x03e9c6f7, + 0x5e360a65,0x8d087bb6 } }, + /* 12 */ + { { 0x3fdc1844,0xbe212302,0x105eac56,0x6eca27ef,0xf168a348,0x2183a606, + 0xe1d7a4cb,0x295f807d,0x7ef5d43e,0x7246a632,0xc77025c7,0xae143205, + 0xf3484e3e,0x4bdfc7ca,0xdf52c075,0xec939895,0xd7a9cac0,0x82e655f6, + 0x8baeddb0,0x985dfe20,0x527de731,0x79c817e4,0x313de1ea,0x30ce0fbc, + 0xcc4f6cbb,0x9df95b89,0xf5bb20cd,0xf2aedf1e,0x1a8cfb01,0xfc1e0a89, + 0x63edb7ec,0x225ed34a }, + { 0xbabb1a85,0x3e13154d,0x1e6a565a,0xd3d8dae7,0xab4b100f,0xd3217d56, + 0xebc78e1a,0xd44d934e,0x48e73d37,0x0215321b,0x201e43cb,0xbbc90bfa, + 0x27500905,0x3c23f1d0,0xc86691a1,0x2a2e5000,0x6065841c,0x08b2bad2, + 0x30026b60,0x15d41caf,0x5276ce61,0x1712c2f4,0x15932ffb,0x01c4c3e7, + 0x6a74caf2,0x7894e13d,0x0c0537a4,0x02d6f5df,0xc2b1c97e,0xa8fb7602, + 0xd0887c7b,0x612b60e5 } }, + /* 13 */ + { { 0xba245d6b,0xefd495cf,0xa2ce3ff6,0x5cf0cbb7,0xdff5feee,0x24da2ac0, + 0xcf28c6a3,0x90c914f8,0x4308a56b,0x72fdb50d,0x13d72034,0x03dbf779, + 0x822ac9e9,0xcfa5ec91,0x3aea3e81,0x0dde73c8,0x66289139,0x545ba962, + 0xca6acbd3,0xa52f648b,0x98a0683a,0xff6f276e,0xa378ed52,0x2536d3ac, + 0x885ac1d9,0x353c2c54,0x00bc84a7,0xcaff52da,0x37684167,0x3971f81c, + 0xd2d7986e,0x0f7334e1 }, + { 0x6596067e,0xafbb5c83,0x38c19806,0x33e54e19,0x39cb0dcc,0x8285d967, + 0x424035f9,0x2b53f43d,0xdfef9095,0x38c531f8,0xdb0f571a,0x90fbe8e4, + 0xa39ca787,0x9a0c1ed2,0x606f2620,0x2fecc1d6,0x72b7cb4a,0x9dc890b1, + 0xccbb7868,0xc33ca6fb,0xfe73ee49,0xd1b11082,0xfcb66c48,0x590b7d17, + 0x86e14573,0x9356b0a6,0x053ead85,0x75d682c4,0xc54d30fb,0xb2ae55fa, + 0xf8aee949,0x67636a72 } }, + /* 14 */ + { { 0xb91d6bea,0x638063bc,0x923ecb96,0xae263a2e,0xc627aca6,0x9d7b0992, + 0x77af9e7e,0xc6ed001a,0x24aafebb,0x9214accf,0x78055a90,0xa3564b96, + 0xe027499d,0x00999b1c,0xe46a06a5,0xe413a4e1,0x2e51efe7,0xa05d13f6, + 0x9ba843be,0x35e87d34,0x3183159e,0x0a633825,0x54601923,0x6023e8ba, + 0xb7fd1cf2,0x9b107721,0xfdf2fd53,0x46b5542b,0x1c18af38,0xb314f4f8, + 0x60ac8965,0x086f9876 }, + { 0x8cbb9850,0x76701954,0xa20d2c8c,0x6210b730,0x5335670c,0x4084d057, + 0x0324baea,0x3ecdc595,0xc76ee9b4,0x607fc5f2,0x440ffa64,0xf393d00f, + 0x2dc1463c,0xe0111796,0x9c7725e7,0xf00b8251,0x5bd1d186,0x35e60736, + 0x2cf72aac,0xf3d8554c,0xefa3497d,0xb4dd0fde,0xf646ad11,0xd712268c, + 0x9f7b8ead,0x07c20afb,0xfc06dfe5,0x630969d4,0x7245549a,0x76b7df1c, + 0xe61ae810,0x681f9403 } }, + /* 15 */ + { { 0xc9a0623b,0x7cad5163,0x67fab8d4,0xdbf82957,0x81af7c7c,0x2ccab0ec, + 0xe966d5c2,0x469e38c8,0xf0d4e41c,0x34430d52,0xa52b359c,0x426075a2, + 0x33bd0127,0x242dd3e3,0x9fed2341,0xcda3f635,0xd7d52ffa,0x4df33730, + 0x7640c3ef,0x5fff56f0,0x1bbde57c,0x4783c21c,0xeb8bb336,0xd8784a2a, + 0xead08405,0x1ec7c533,0xf9b62bd4,0x4b7f1423,0x7075d4af,0x5543145c, + 0xba60590a,0x0c9de94a }, + { 0x95d5682b,0x8ed72735,0x2ec276ed,0x711c4283,0x8b36a0d2,0xd1f4aed5, + 0x8498a88f,0x62ab40c4,0x4480f451,0x58c8fc62,0xb79cffe2,0x8bc8ca4b, + 0x701a359d,0x90ab583c,0x3fd5d15d,0xaee31a73,0xc912333c,0x02a5597b, + 0xb6c3e3c2,0x1019cae4,0x29938088,0xe513042c,0xf47c8199,0x0e00283d, + 0xf2a00e92,0x90d68e58,0xa775ae3b,0x69e2df41,0x871c30b2,0xb8d2eca5, + 0xbb1de396,0x733dca0e } }, + /* 16 */ + { { 0x4b59213a,0xf5b495d0,0x8d70200e,0xca672039,0x2b6771c1,0x4bcb09a6, + 0x2b9eb0cb,0x26adeed4,0x8cdba212,0xeb544754,0xf08890d1,0x0e1abfcd, + 0x698e46b4,0x52509963,0x82e9c138,0xe1bff0b0,0x51099a71,0xa189e4cd, + 0xc9b91cc7,0x2360c9bc,0x137ec4be,0x9bd4d7dc,0xd1519f6e,0xd0356521, + 0xcf832503,0xbf5f6d78,0x8deea2b4,0xe4301031,0xef4c319c,0xc3132494, + 0x0f1fa7d7,0x2ab3bd47 }, + { 0x922c9fbb,0x5753b680,0x0f16c6d1,0x869e7dc8,0xbac16efc,0x83445135, + 0x846d1d9b,0x4326a3b4,0xb2d62c21,0xb517fee3,0x0b292ad5,0x6905afa2, + 0x2cadac13,0x2a57131a,0xebdbca8d,0xcd904d8f,0x3f365fb2,0xdfeda86f, + 0xdc7eaa1c,0x7097b208,0xa45e77c0,0x89a35a84,0xcf5d118e,0x417a062c, + 0x1f6e99e8,0x3c0c04a8,0xba7a087d,0xc44704b0,0x3ea22ad2,0x6f8a27d1, + 0x4c27d229,0x93a4b416 } }, + /* 17 */ + { { 0x1f1efb7a,0xd4271bc1,0x33fccc0d,0xae4e68e6,0xb11f50a8,0x9d9bc8f1, + 0xaf076089,0x5430398f,0x443d0e03,0x45e242fb,0xf6e3d4c1,0x73ec2519, + 0xba9bad09,0xab70f790,0xf9add10f,0xde612ad5,0x14e942b4,0xb837e54e, + 0xddb8b68a,0x175a56d3,0x1ac2a408,0xe85b233c,0xf0c80f94,0xf8ff6c30, + 0x898db4f9,0x4b7f3fb7,0x45a7dcdd,0xa2c6044f,0xfe3d3895,0xf3abb2f6, + 0x32ee7763,0x342ce0d7 }, + { 0xcf491b1f,0xeb261394,0x1909e395,0xdcaaeed7,0x9fe4dbea,0xdcc4055a, + 0x493d604d,0x17a6611d,0x1ce5ebef,0xba445a3a,0xe3989cb5,0xe82e2858, + 0x83f58406,0xb96f4282,0xa156cf55,0x99877b99,0x4e166a0e,0xaf906a66, + 0xb2976d13,0xcea1d353,0x36c61a01,0xefc16f27,0xb0f55d86,0xdb04c433, + 0x8eb34c01,0x3cb4b269,0x2ae60280,0x38d07f78,0x43be3ec5,0x43ac3bcb, + 0xe156fd20,0x455f4af3 } }, + /* 18 */ + { { 0x754ec21c,0xc057f262,0xe3a1ba38,0x3eacd4c9,0x116c1fe9,0x3a0210d1, + 0xeacc8ab6,0xe4ea4e94,0xea6f32ca,0x31c00c9a,0x86b975ce,0x5cb6239d, + 0xa14ea1e9,0x654d5d8c,0x5067fc8b,0x230d31f4,0x6355fecb,0x48bb90cb, + 0xdc172e8e,0x78f81ece,0xcb006737,0x288380a8,0xe162d012,0x19b02e01, + 0xc5af145c,0x0e087a06,0xb72dc354,0xf04dc8b7,0x8de3c066,0xf70ef214, + 0x13009fb7,0x4f148243 }, + { 0x6e2055e2,0x5e004fce,0x86c32067,0x89e247ea,0x5f9daaa2,0x4ebcbd95, + 0xceb7f63b,0xd15f212f,0x863784a0,0x5ecc5c1f,0x75760251,0x53b3800b, + 0x8a6a2954,0xeb9301c3,0xa13cdd19,0x0f16ba18,0x887c2d24,0x8313d251, + 0x9a9413f6,0xf9923585,0xfe3fd7c5,0x423405e6,0x16e0ee05,0x678aeb34, + 0x3fadaab0,0x1f3be7bb,0x82884471,0x7901fa2c,0x4d662ff6,0xc950db30, + 0x3c01170b,0x74d5d2d4 } }, + /* 19 */ + { { 0x2b5bfe11,0xa3002dc0,0x52d321e7,0x0733410d,0x9679ba89,0x15920f65, + 0x685b236e,0x0e248c14,0x346f6040,0x8cfab594,0x40c717f0,0x9f57afb7, + 0x66044576,0x0dbab28c,0x9cdc3247,0x0fa09968,0xc230ed05,0x41e02ae2, + 0xe45bef74,0x0d961554,0xce4d7b6f,0x9688a982,0x5e62d22e,0xfadefac7, + 0xbd2cba28,0xaf1512a6,0xbe7c749f,0x78868e62,0xae9f5a6b,0x88048d81, + 0xc5857a29,0x6b1a5442 }, + { 0x43242066,0x9f5ab9ad,0x2ccca2ae,0x0afef1b5,0x988edc4e,0xb1b43ec7, + 0x0341b0d5,0x0d0c00f1,0xb50aab37,0x4d68b8f7,0xf3a64a99,0x9a8e4e6f, + 0x7f1a684e,0x198338fb,0x351a0f5c,0x8bc0e748,0xdac44515,0x2cacf2cd, + 0x5e9ff76b,0xc14d3999,0x16393055,0x54a01b3f,0x888d8376,0x6ac3eea5, + 0x723277b1,0xb84d9a9a,0xe11dbbbf,0x99132691,0xabb67178,0x597717ae, + 0x8bb14ac8,0x4c213526 } }, + /* 20 */ + { { 0x95532833,0x2e6fe0a6,0xd626d067,0xabca228e,0x649e73bd,0x22aef3d9, + 0xf03c4c0c,0x2083a87a,0x35169b45,0xe954e75d,0x74506a89,0x577509ee, + 0x2aeacf90,0x49cb276e,0xfa409f91,0x08275d77,0xf0bbd6b9,0x61eb6f3d, + 0xe4132704,0x948202cb,0xb1c498b1,0x35f3fc21,0x361fee59,0x76c68ba8, + 0x50e051f3,0xa18cbbd9,0x318e7042,0x2384a879,0x80dd1e8b,0x292abead, + 0x5c37c334,0x65713c29 }, + { 0xceb77b9a,0xdccca8e9,0x23b69469,0x2f97e727,0xa01d6b28,0xc76abee6, + 0x5abecdfe,0x3925203d,0x29290d70,0x89448082,0xb0314438,0xf9931424, + 0x7cd447c3,0x04209df1,0xc855c827,0x7c6f2059,0x56c0e069,0xd97d7862, + 0x412d94c4,0x5a9db6fe,0x994c41dd,0x19a64591,0xc89e21a3,0x12348aa1, + 0xc6a03f0e,0xd6904b50,0xa616feac,0x55c15156,0x7cc7693b,0x4e36d1b5, + 0x3bae3c38,0x6b0e996c } }, + /* 21 */ + { { 0xcceced00,0x32789fab,0xe5b7aa66,0x3237e71a,0x2ddebcdf,0x87b2e269, + 0xb61dad8f,0xb7245120,0xd35f803c,0xe11e5e48,0x98e50f0d,0xfb4df5d7, + 0xbcd2ab92,0x60ee68b4,0x1ce3363d,0x98ab2f5c,0x7cd42647,0x15ba39da, + 0x83f4fb3f,0x1a6572eb,0xe56f08db,0x0f77de88,0x172562c2,0x1743761e, + 0x8a58f0f4,0xbe349ff8,0x84d1d6e2,0xe04da71b,0x9e9ff3b4,0x368f0342, + 0x678223f8,0x4022a205 }, + { 0x83847375,0x527bbd05,0x3f451af0,0x3ae56b62,0x4b2c7f18,0x6198f24d, + 0x4525b98d,0xee323f5b,0x0e0884b5,0xa9d8d39a,0xfb12c776,0xd005d7f6, + 0x708bc154,0xd71c483e,0x742541bc,0x8ca6fd28,0xf8397ddb,0x0af3dccd, + 0x3eccf243,0xb80d3125,0x58d81b8d,0xc743a108,0x71391f68,0x3f48eb21, + 0x33bb657f,0x493aff88,0x07e47e31,0x1d15ed66,0xe08279f6,0x10159b11, + 0x24a6a956,0x312179cb } }, + /* 22 */ + { { 0x07615ac2,0xa94cc3ca,0x121ad581,0x85865e64,0xa7986b79,0xae47616f, + 0x9d5e0f1d,0x395a40eb,0x3d9457ea,0xa9143264,0xfa2865d9,0x8de6d6a3, + 0x1014ae8c,0x0771db96,0x976a87cb,0x77a7cce6,0x143a0f60,0xa7de42e1, + 0xd993d934,0xe203cc09,0x98ec4c3d,0x92018693,0x3a25df4b,0xd77546d8, + 0x62b02d6b,0x0ad9eb47,0xd05a7189,0xfaaaf208,0x431221bb,0x5238181f, + 0x733511ea,0x417d6c78 }, + { 0x0e91e9a8,0x3cbd81b7,0xc370d6b3,0x73340418,0x8eaa2373,0x825db10a, + 0x6c7d6756,0x8f2b09e4,0x94c33ded,0xe288ee9b,0x1695e3fb,0xcd8426bb, + 0xdce9e888,0xa6176c86,0x6165e362,0x3f4c8922,0x6063fb09,0x514e411f, + 0xc8f9e04c,0x6907ac20,0xdfd2ad61,0xcef7469c,0x8452199a,0xba30bae4, + 0x12ac3462,0x30681293,0xc92d482d,0x011be873,0xe8330995,0xff4cbf89, + 0xd1470a0a,0x02189d52 } }, + /* 23 */ + { { 0x92599c69,0x73e419dd,0x7fec32ca,0x5b94221b,0x09bbfbfd,0xb2bf9bd2, + 0x63ed895b,0x61ea97a4,0x3f486f79,0x6609146b,0xfd141a39,0xbd1c7a05, + 0x83d64135,0xc79ec8cf,0x9883507b,0x7f8fd42f,0x17b3d027,0xafcb53b7, + 0x67ca5a21,0x86658dcd,0xcd149786,0xa6a6c0ac,0x34b95067,0x16f3d70e, + 0xdf44958c,0x371208e3,0xec280212,0xd2dd64e6,0x30782c71,0x33b2c4ab, + 0x521176fa,0x7bbf8abd }, + { 0xa78b981a,0xbe9e4aaf,0x304ec828,0x788b4e36,0x3959dea3,0x0c45cf39, + 0x240b39c7,0x70a9bdd3,0x28383b7d,0x499cd7dd,0x307a1026,0x30690b2e, + 0xee92f1b3,0x2262d598,0xb4725a48,0xc62d77de,0x7bc3aa0e,0xa16f25bc, + 0xd15ef7fa,0x62dd8b65,0x0b96d68f,0xd979221d,0xa00f1906,0xb92885c3, + 0xeb74c740,0xfa476b9b,0xc7576222,0x217ddbb5,0x5788504f,0xc2782c30, + 0xf812716b,0x860d096c } }, + /* 24 */ + { { 0x4d79bbf9,0xfebc337d,0x69f74f80,0x5d53eab8,0x33104d53,0xff36a095, + 0x196f8b97,0x2ab820da,0x75ce6909,0x961d3d1f,0x04683754,0xb197ec04, + 0x93a6cb9b,0xa68ce1bf,0xc5f021a3,0x503456ff,0x8940ffdb,0xb50a2db1, + 0xef004209,0x77c50f8f,0x04965875,0xd635d177,0x8bb8770a,0x725766d9, + 0xa078e53e,0x8e19b028,0xf9fc8378,0x364d4cca,0xf0dd39a0,0x1a3df411, + 0x03adf920,0x7e80e442 }, + { 0x539a1ddf,0x4b5f8a57,0xee486562,0xd248e7ae,0x816021e1,0x1c7b491d, + 0xfd36d2c4,0x2e7b871b,0x0aec00d9,0xda38b504,0x6193f1b3,0xf2827612, + 0xfb1f78d6,0x69c3fe86,0xe827ac33,0x56c8b786,0x3487c8f7,0x1687f6c7, + 0x19dee5bc,0xab8f2217,0xff399418,0x04e8473f,0xa9027c80,0xf384c014, + 0xaa1d2e28,0x9967be9a,0xe065eef1,0x869686d3,0xc7bd837c,0x737c6b08, + 0x9e8bd863,0x5dcab5d1 } }, + /* 25 */ + { { 0x9a7d772b,0x0784283a,0xe540959b,0x6b49e525,0x86414ab5,0x546bb008, + 0x9d74b2a9,0xd4448162,0x203b0b1b,0x267890ad,0xc8d3f86b,0x1e7a82bc, + 0xd85a83c7,0x1352bfb5,0xfad07ccf,0xf29f16e3,0x41e0c43f,0xc02a63b8, + 0x6b379fef,0x904f22c5,0xb1244f26,0x19d8a653,0x3a28bdea,0x6635b6df, + 0xf6d455ce,0x18b68851,0x9cff3735,0x74ac2818,0x8b2cbdab,0xad40f9df, + 0xadc9d498,0x08cc2d9e }, + { 0xc170c84b,0x2e6a6866,0x5a49a484,0xbb989e8b,0xd04c8992,0x7b0e00e0, + 0x61b3a423,0x55ad3478,0xb0d01899,0x3c952450,0xe3100cb3,0xe3922155, + 0xf03276d0,0x19265b6e,0x76d42b53,0x0fe8595a,0xfc6353b6,0x0a96dee0, + 0x246f893e,0x761e0dc8,0xf0a74cba,0x4ec902be,0x3fdfad9b,0x61008684, + 0x4fdb6975,0x5d6a60e4,0x7ef7590a,0x3f53aac8,0x12870a37,0xd29e6be0, + 0x55aa55b0,0x991fadc1 } }, + /* 26 */ + { { 0xb4844ffe,0x82bc4b0f,0x60f8b871,0x73922714,0x4ce3f1f3,0x8ac000e2, + 0x163519ec,0xf0d548b4,0x88288b5f,0x7aaf842b,0x2bdc9a70,0x9e8b0c4c, + 0x4ba5fd67,0xa06d5152,0xf93cdec3,0xd0b1afa0,0xdf89f8f0,0x280955ba, + 0xeea32c92,0x86cbe92d,0x3fe05be4,0x0cae3f99,0xfa6919aa,0xf2607095, + 0x6e0f1b8b,0x0f54741e,0x30ecf988,0x2aed1f74,0x734991d7,0x9296f76b, + 0x259f0fe9,0x66cf8d28 }, + { 0x226f5868,0x9b01905b,0x16909e9e,0xc102e88c,0x4a37eb54,0x2bd08916, + 0xc9816323,0xf72253e8,0x86bac53c,0x37f84e9d,0xafeaaaf7,0x2e352454, + 0x2ca0046e,0x67c86f77,0x6663372e,0x86bce50e,0xb6950a04,0xf6a3a960, + 0xfc1aba93,0x61f994d7,0xc1326e6e,0x1957c12b,0x2e56b005,0x9b658fe4, + 0x8592740c,0x9cd297fc,0x177f26a5,0x7654ce9b,0xa79d2ebb,0xaaa699db, + 0x0ecb6448,0x5fca0c5a } }, + /* 27 */ + { { 0x569a6663,0xe26e25f3,0xe6aa4ca7,0x09597ee7,0x8d18b80c,0x25a4cda6, + 0x22926730,0x450602b5,0x07387209,0x9af5f650,0x26733a53,0xfeeedb34, + 0x86572951,0x0f5ce768,0x8398ae9a,0x872a360b,0x2b30f6c3,0x60347a80, + 0x1a162158,0xd2113b23,0xee6c6dec,0x6fd9cf92,0x5cbcf9e6,0x85f0a5a8, + 0x2ba3fe84,0xd7a5a6e4,0x51ecd727,0xaafe6720,0xa2081a10,0xe09c6bb2, + 0xb973b0b4,0x657acbf0 }, + { 0xc274c8d4,0x3130466f,0x30a994d1,0x42765176,0x7079435f,0x217258ca, + 0xeb897a06,0x44850406,0x561ee130,0xf38dfeee,0xaa1778bb,0x11f4facf, + 0xb9abb9e9,0x765c6617,0xd8f10932,0xb135499b,0xa73b9159,0xc0eb6337, + 0x6f7e8b6a,0xf2c1ccf1,0x187def53,0x5b32c03a,0x830b9c62,0x89ad1d49, + 0x2f10e538,0x1735eae3,0x9d5f55bc,0xb1cbd9c2,0xe539db0d,0x42428c47, + 0xc852b3bb,0x3d2da412 } }, + /* 28 */ + { { 0x871f2865,0x97702b6e,0x142920d6,0x56cb639f,0x45b58611,0x328522a0, + 0xf3b13812,0xf3943ad1,0x712206e8,0xe6c2200a,0xa34d59ea,0xc2890e5a, + 0xf6b7f759,0xab52fd40,0x180bf567,0xf522c8de,0xaccee396,0x181e97b2, + 0xc4ea5cbb,0xe0375819,0xab51d3ef,0x0d9985e8,0xbcb50fd8,0xe26c96ca, + 0x97e1c80d,0xfb9d6b13,0xf796357d,0x582b1814,0x07f4c7fb,0x89a78221, + 0xc0357e61,0x02aeef2d }, + { 0x2c7ec9be,0x2ba7926f,0x7258b201,0x292f307e,0xc6fa6b4a,0x74e62a10, + 0xe2bcc5ab,0x80c08549,0x7bb8c073,0xb4160db8,0x329f194d,0xd5ef0529, + 0x6dda4a9c,0x0eb8da14,0x15ea23d1,0x0b5d43d2,0xfc34bfae,0x6cebef02, + 0x848757a7,0xacd364d0,0x2d34cca3,0xc1401368,0x1d2d95e2,0x09ca6742, + 0x786eaa28,0xc3fd1d6e,0xa2965fec,0x9eb1136d,0xc0779203,0x48871baa, + 0x4b15aeb0,0x6b446c01 } }, + /* 29 */ + { { 0x25e8fe80,0xc819eb2e,0x98238a17,0x2b5f7906,0x81e41849,0xd6f1e996, + 0x98ea6d45,0x58ad8ad6,0xbfd02e40,0x5bae5ad4,0xa812416d,0x016dc327, + 0xa3347ca1,0x8b31a985,0x82a65391,0x0b4da610,0xb48c35fb,0x1cb91b2d, + 0xd2aaf8c4,0x9e96817c,0xcdfdcdc0,0x1a630483,0x12b69254,0x70559361, + 0xf8a2a097,0x5fdcd712,0x35cc5281,0x59ab623a,0x932b6095,0x30c8ebe0, + 0xb08e052f,0x8613424b }, + { 0xb2231d8a,0x28902063,0xd9a61667,0xb0f62329,0x071a9f27,0xaafa0fe7, + 0x603f047e,0x6bcd8960,0xfd92a1c3,0x118cca76,0x71d483b6,0x3414e62b, + 0xba705262,0xa123ccdd,0xfd9b5c5a,0x1a576437,0x4c8d0fa3,0xa5301bc2, + 0x102427cd,0x96f0ad44,0xd3aa6c02,0x0e6fb5e0,0x072a3996,0xcd8c4880, + 0x840d3fad,0x4dafca12,0xde91d541,0x29f4ca3d,0x8441734d,0x0037c598, + 0x9ccfe57c,0x86333a99 } }, + /* 30 */ + { { 0xecf53b40,0xd213a751,0x2f78a542,0xcff2c6f2,0xf13ae56d,0x0f59f0e2, + 0x0e61748e,0x91f8ccbf,0xd72c4145,0x0aadecb9,0x4c9cdcb7,0x6b2ed852, + 0x1eaffc70,0x8e00b72c,0xaa728102,0x89b24285,0xb679cafa,0xaa7ea7e0, + 0x4f0a6f6f,0x5d2b8c26,0x0e804397,0x7ed7b173,0xc8573049,0x5a93eb45, + 0x0986e93e,0xc92bf5d4,0x6a20c0af,0x526b5a9c,0xb99dc3af,0x0adf47c9, + 0xba202cc9,0x12b25fe2 }, + { 0x33eea395,0x09b8d78a,0xf633fc5c,0xc7a93618,0x270eceef,0x7e821629, + 0xc628ed0c,0x524779b8,0xa1d68939,0x91db5ca1,0x586edc90,0x8626e18e, + 0xfeb3f3bf,0xfe023e8b,0x0250171c,0x6279fde1,0x55e172de,0xe52ec7dc, + 0xc6d4ca45,0x445e8695,0xbdbc10f1,0x42de3878,0x6fc3835e,0x2b114de8, + 0x7e10b652,0x9faba456,0x390e78fe,0x4111d82a,0xaedf0aca,0x576b61c2, + 0x74accb74,0x216279a9 } }, + /* 31 */ + { { 0x4047f747,0xc14cdabf,0xc1315a1e,0x03ca233d,0x40e5d0a7,0x59e7cbd3, + 0xbb413869,0x1fd0c4e9,0x0f01fbd8,0x189d08b1,0xa76b823d,0x50449c42, + 0x398b00a1,0x81c224a1,0x8e8179e4,0x08084e4f,0x698e41e9,0xfd8af994, + 0x5610bf2e,0x1e30e37c,0xa7d2790f,0x4e6a043f,0xb3195388,0x9d96e60c, + 0x03799dfd,0xe75f986d,0xf8ff902f,0x3b4a8f11,0x7588416e,0xfa945378, + 0x9827535e,0x20683e3f }, + { 0xd0378878,0xcb582e26,0xa7945787,0x9e214c23,0x8f6688b3,0x13d000bf, + 0x40515270,0x7548d4f5,0x40111f5d,0x7113c15d,0xa8bff902,0x3bf5a526, + 0x9b4945cc,0xbda6b010,0xbc2f3a05,0x83dcc74e,0x43efdfa1,0x2aef6284, + 0x565c5bf4,0xd2e60ee9,0x592f243a,0x4f0fa10d,0x1bc3bf51,0x6ae58b32, + 0x60576a74,0x813b0868,0x4d73081a,0x0bc023f8,0x32dcee59,0x9fd03aa0, + 0x27d6c795,0x5e416bf5 } }, + /* 32 */ + { { 0x026cc23c,0x24313760,0xb5b29058,0xf819aaee,0xc5d2ee17,0xa92272f8, + 0xee5cc402,0x8048e7cb,0x77def07d,0xdbc7d6ee,0xf6af821e,0x61d69244, + 0x996cbb89,0x5f7966ed,0x96a155a4,0xf81b17ea,0x03f3ed56,0xb2d9ef70, + 0xe882a5b2,0x5e6e5906,0xae947180,0x86fa1072,0x658c76f4,0x34d9fc51, + 0xcb035aa0,0x9f603dc0,0x75be6481,0xb7b39feb,0xcf04a9ef,0xca87554a, + 0x87b4fde3,0x4ff682ec }, + { 0xd0a10ad5,0x3125627f,0x968e6f45,0x7fd45c72,0x806a1163,0x2981bd6b, + 0xde5033e3,0xb92de1cd,0xbf4f8988,0x3b44b45e,0xdae7e1dc,0xca1b9896, + 0x0778d878,0x52166e5a,0xa5116847,0x82d472be,0xf2895445,0xfbdd382a, + 0x5d6ec4c9,0x22ed1602,0xb6552b02,0x3614eb1c,0xa1e6210f,0x63c5df73, + 0x021a74a7,0xe9160285,0xc65cbd4d,0xa44ca400,0x0f15e299,0x48cb187e, + 0x3402507c,0x51eb818e } }, + /* 33 */ + { { 0xb92100ab,0x1fc1d178,0x9605b839,0xdf2e3d60,0xb71e59d0,0x12a7c255, + 0x14fcbe04,0x3f8b6675,0x59fd06af,0x0e8a3935,0x12020d07,0x56326502, + 0x528e7be5,0x6696fcd1,0x0c7b7654,0x6588514b,0x5912a5b5,0x0cd80f8c, + 0xf324cb7f,0x8bafef04,0xc6da3d75,0x6b53eecf,0x31d1df2f,0xedef48d8, + 0x73812b6d,0xf336b965,0xee626031,0xc82eae4a,0xd244f09b,0x300abd32, + 0x31d9647f,0x8b0af955 }, + { 0x2e603544,0xb770180a,0x221acd9e,0x2b573ac3,0x62407032,0x3a17f665, + 0xb89abc3d,0xad3e74ad,0xd793225a,0x8a3d2e3a,0xef02564b,0x457bba04, + 0xfc2dd2b5,0x8875652f,0xe67143e8,0xd2905d15,0x02e48d70,0x6d884b42, + 0xc7636a57,0x06f99219,0x35e378df,0xa8dc3421,0x10c64a02,0x95c1d73d, + 0xcc157a66,0xcd6a4ece,0x8e24a354,0xbadcc1c8,0x9839329d,0x8024f1b2, + 0x4da48ad0,0x5363e549 } }, + /* 34 */ + { { 0xe23fc641,0x1f5523b7,0x86667063,0xfe54e72f,0x8e009d2f,0x294a15f5, + 0x8c57f5e1,0xf203997f,0xb16d64dc,0xa229724c,0x4baa2ffb,0x697be4fd, + 0x0a6e8ed6,0x3f507e46,0x78508536,0x0afe3a5d,0x95408208,0xeeef6cdd, + 0xf2c4237c,0x701fd889,0x5c385253,0x496d883a,0x72a212f1,0xe25c67ed, + 0x1ff78fcd,0x4b416783,0xc16f4146,0xe9967004,0xc45b0697,0xfa45c3a1, + 0x3fbd30c3,0x63334018 }, + { 0xa2fbbbce,0x39c9a0cc,0xaa0cb744,0x876f6e5c,0x3438ece3,0x9ce6010e, + 0x13802d82,0x0aad148e,0x9cd45a1b,0x9c3e5c60,0x7bcfc1e0,0x875cb859, + 0xd8584dd0,0xb19ff790,0xd81c2a2b,0x2598b81e,0x02be07e3,0x118bdf2f, + 0xb9765ce9,0x074fc8ee,0xb24f95ae,0x125e9d88,0x0c98f09d,0x3bb12cdc, + 0xa0b74b27,0x4a6aee07,0xc08077ce,0x4723d2f9,0xbea8026f,0x959447d6, + 0x16280b73,0x93a7075c } }, + /* 35 */ + { { 0x715b27f9,0x26bbefe2,0x2a280923,0xa935a5e2,0xfd58a26a,0x5ddf23af, + 0x7c138694,0x54c83e16,0x892a2153,0x44799bc9,0x9b8d09f5,0x4e6e4710, + 0xd588ea68,0xc63af616,0x883ab1b6,0x5e896706,0x3d209336,0x3c1393a0, + 0x92c23dda,0xd02f2921,0xdcf6ea43,0xab70cb7a,0x791559e1,0x12434ea8, + 0x6d70ff0b,0x040680db,0x2832ba45,0x1a10fe52,0xe5f0cb8f,0xd69f9c08, + 0x44b141fd,0x1a7422ac }, + { 0x9f40b675,0xc3a9dd2e,0xfcc71f39,0x2a7c6603,0x1948e342,0x18939a61, + 0xed0ab484,0x8f3b6158,0xee31ca6b,0xa3aa7d97,0xf7a8db63,0xbc1e865e, + 0x2c7c62e4,0x315f8c09,0x9f5c6d0f,0xa260788f,0x4b6f3ec5,0xb1833129, + 0x36b4d849,0x73adbcd6,0xbc699a9b,0x66e14890,0x2a1175e7,0xbf3790d8, + 0xfc53ca4f,0x7f43605a,0x87ff6091,0x577f6c47,0x600c82b6,0x827c7552, + 0x9d25599c,0x0944d630 } }, + /* 36 */ + { { 0xe6ab9620,0xcfdeb63e,0x786cd808,0xdff4fa6d,0x456320b3,0x145edd82, + 0xc4943915,0x2ae5f862,0xb73b3f87,0x9508e813,0xe52f97a9,0x3bd805f3, + 0xc9829b62,0xf71b5c28,0x86e0cefc,0xb394c70e,0x23bdb36e,0x534fb1a9, + 0xdbe27e5a,0xd64f5862,0x83ab6169,0xbae23df3,0x27c828cb,0xdd6df1b1, + 0x3a307a8a,0x1901899f,0x811ddf66,0x36cc8659,0x79943b77,0xa3cb7774, + 0x6fd86576,0x7d89f383 }, + { 0xc9f92b2b,0xf8564242,0xc46e32bd,0x700c6a75,0x7f99a5c5,0x93e768b7, + 0x03149568,0xb6efe858,0xc2ce6709,0xbbfe8a19,0xee6ec493,0x721a3b1b, + 0xc371c28d,0x26eeeea9,0x15177e1d,0xd798115e,0xb068a5a5,0xd7bf3bce, + 0x46d2b4b2,0xdf8da220,0x59be9dfc,0x3df0995b,0x77640b79,0xc96897bc, + 0x5a2bd3c5,0xce0cf4c2,0x89afe744,0x16f45d6e,0x3a8509bb,0xb53f3acb, + 0x63f2a6e6,0x449af81f } }, + /* 37 */ + { { 0xa16d9377,0xc2fcf132,0x7e1a2f9e,0x9ab377b3,0x86d19ae5,0x72e1a12e, + 0xd013bbb1,0xd2b12e66,0xcb5f66ba,0x0972e055,0x399eab50,0xd11de1c0, + 0xc65f5ec2,0xc1f314fd,0x8a9ff593,0xfc311841,0xe05246e6,0xdf73c1ec, + 0x1625056d,0xc28d1363,0x6fb25e19,0x30a9dbd7,0x845cd2d7,0x049ed244, + 0xd36e852d,0xc779b83f,0xf68c8a83,0x85a35fc7,0xc95e8033,0x299bf1e1, + 0x20891af5,0x0e8617c3 }, + { 0x67c81b5c,0x53720602,0xe737873c,0x2fa89dcd,0xa8144fd0,0x2a7430b0, + 0x26208c83,0x3006c5a7,0xd8ea40f5,0x4e066660,0x896413a4,0x9dd025f9, + 0x46b9149f,0xbdf380cc,0x0a125cc2,0x80156619,0x52793c37,0x04d6a3b7, + 0x6b7a62f2,0xb6001374,0x585d5978,0xa9cfe268,0x8395fe66,0xdcad0cb8, + 0x46b261f6,0xbab468fc,0x9d9d9218,0xca0ef5ef,0x5e452402,0xc507d4a8, + 0x326cf687,0x6f4404f1 } }, + /* 38 */ + { { 0x4febd3ff,0xa3e1920b,0xfdfd2bba,0xca6234d8,0xe19a9829,0xb7d1af2a, + 0xc6f5bc20,0x23de1610,0xdaa39ca9,0xe204dbf3,0x6d8c70ab,0x2a2de9b8, + 0x7c9d370b,0x272e0c37,0xe565510e,0x80914c06,0x57cbb6b0,0xb611e7a8, + 0xd8266a6e,0x076fc6ef,0x3095801c,0xdfac34ee,0xb9e24063,0x69ff40a2, + 0x787aa5c5,0xa7ba31a9,0x33c70cd2,0x0e4d1fdf,0x6895f074,0x903e3132, + 0x7fb671e2,0x905771f8 }, + { 0xa4062bee,0x5199ba0d,0x94d7d9f9,0x18e7238c,0x1e0922c0,0xf53f29bc, + 0xb12d855f,0xde9b2a81,0x6d68ca29,0x649f3eed,0xc50c097f,0x64adfc34, + 0x9db398a0,0x81964ab9,0x7a587224,0x00d59c47,0x74c5903a,0x09fea396, + 0x15043dd0,0x6aafd8ee,0x5f1ecc20,0xc5721a6e,0x0db9b7b4,0xb6d6a483, + 0x66c8d52a,0x06ffc617,0xacc82a27,0x3de241d6,0x27f2f7a8,0x0605f052, + 0x6404decc,0x6a22953b } }, + /* 39 */ + { { 0x74fce389,0x92452d8f,0x2afa5564,0x059634c0,0xf0ed7825,0x9377ccbb, + 0x37718e0d,0x89f4045b,0x9fa69a4d,0x11074e7d,0x7295b0ba,0x5d70bb07, + 0xf107ede6,0xb22d54ad,0xa1a29c7b,0x5c39a3d8,0xd795e3ab,0x37236c02, + 0x2b589951,0xf7282d00,0x5790bee2,0x5e2265be,0xa8e65ea2,0x91e0ea11, + 0x6001cebd,0x0e71a708,0x2c1c5402,0x16900f5a,0x357f6981,0xc3b2d5c0, + 0x619e3427,0x528c9ea0 }, + { 0x5f26c577,0x1edc86b4,0x9438bd45,0xf8074708,0x792582a7,0x2dfe1013, + 0xde1e569f,0xe08eaca0,0x9a55a356,0x5f952efa,0xe4976216,0xa4d80b53, + 0xcd5d71f2,0xd2b65855,0x66cea3f0,0x246704bf,0x492323ca,0x193f641f, + 0x9adb1325,0xa681855c,0x2d19d652,0x86d522ce,0x5b82ed7b,0x53609f10, + 0x8e150d29,0x3b0f0094,0x0b13e891,0x23ad8bfb,0xf794b449,0xcbb1556c, + 0x738bcf57,0x200f9093 } }, + /* 40 */ + { { 0x8388387f,0xf9b22fc5,0x28e883c5,0xcf26f170,0xd1b7973c,0x447cab90, + 0xf6ec9171,0x8d5d4ea2,0xc30cdbc0,0x2e16f498,0x48623c2b,0xdc92910c, + 0x30dbc545,0xeb1491b0,0x14de21b0,0x631deb2e,0x2fe830f4,0x04a21066, + 0x379c1f3f,0xa4c6979c,0xfb06a795,0x8a732b68,0x1619dfa9,0x3a44327a, + 0x8dbe2c9b,0x91a307d3,0x03989fea,0x939bc8d2,0x0f4a331f,0x3daabaf2, + 0xdd0f55dc,0x5c307e98 }, + { 0x35b233da,0xbbc4e0c4,0x22f6f985,0xe3d29085,0xa8b02468,0x99dd2d21, + 0xa96916e7,0x978f40e9,0x614bcced,0x0327d86c,0xb290762c,0x95e95502, + 0xa879f2ed,0x0ffd2197,0x50e0bd33,0xc4365137,0x0827c4c4,0x26c3148a, + 0x3fcfc0b2,0xc79812a8,0x31928589,0xc3d8d17e,0x8830f42d,0x8b572cfe, + 0x4b07f83f,0x7cd9ff92,0x0a51148f,0x331ca950,0x4c59f9ac,0xd0c53968, + 0xc1434785,0x1df16dfa } }, + /* 41 */ + { { 0x68bcacc3,0xcc7bb4ac,0x430f58cf,0x06ded34f,0xd461855a,0xc59f9f4f, + 0x45c9f0bc,0xf5491994,0x4375c892,0xdc5f7ec6,0x3c85983a,0x1b8708f1, + 0x82fcd087,0xb32a5cc4,0x2d6b4c0f,0xefdcdc35,0x8ac6fb2d,0x4bb24f04, + 0x33906471,0x5982d4f5,0xb83a3ac4,0x162eb52f,0x2337a223,0x7130df28, + 0xcbc3dbd3,0xdce7b802,0x2467ac0e,0x8b395959,0x1b56717e,0x21d3d2e8, + 0x46512617,0x729a7f50 }, + { 0x8420f90a,0x874ed1aa,0x0fe4c855,0x6368e19e,0xb0be74af,0xb62d4aaa, + 0x8ca60ca9,0x76fcc480,0x7645a867,0xf310b5a5,0xddb1b24c,0x131bac9b, + 0x2dea5b44,0xef77d71d,0x72fcc64e,0x4706d210,0x673d77f0,0x29b92691, + 0xe89e0663,0x22e00bf3,0x74077d40,0x472d0cd3,0x829232e2,0x3e21040d, + 0x38dc8533,0x2f916dfb,0x14b8f667,0x48bbb59b,0xd44be19d,0x19de9f4a, + 0x232d9d5c,0x7f6d3649 } }, + /* 42 */ + { { 0x6e794819,0x3bd064de,0xf82ebda1,0x5a6b694e,0xb91e2804,0x1f017fe0, + 0x07a43cd2,0x190d31f3,0x630433e9,0x6c26f226,0x0abfdcb4,0xba488aa7, + 0xa46411c0,0x418d9085,0xbffb5880,0x1b934fe6,0xe200f849,0x75d1e237, + 0xa55413db,0xdf04d63f,0xe23b3f77,0xe216ed75,0x0f91bd30,0xa05866cb, + 0x7729c509,0x84c395d9,0x452ab2d7,0xec97e188,0x0093d686,0x8cb7c1f9, + 0x628f086c,0x2d032395 }, + { 0x4a44b4c5,0xa81c9407,0xcc702c98,0xb9846879,0xceb0dc97,0xcb502287, + 0x6e3aa321,0x30301126,0xe4c256c2,0xc0ac8763,0xe55b4845,0x65034d20, + 0xf240f35b,0xaa96a040,0x7cf7eedc,0x046d26d3,0x3b810656,0x62a5a8e1, + 0x83d70c2b,0x86044b97,0x59e4da8f,0x2fbaff88,0x5457f5d1,0x929d901a, + 0xb531b757,0xd29e1eb2,0x9e4e9739,0x214dabdc,0x4eaa9bd9,0x5bd724fc, + 0x1ef9bb9b,0x734c12b3 } }, + /* 43 */ + { { 0x92f9b086,0x98fe3c2e,0xb3fd4544,0x4641b93e,0x5c02c65c,0x47ce208b, + 0xc4f03242,0x8a52dca1,0x679d29f6,0xb5ec17d9,0x9406f5f4,0x11d2fed0, + 0x0d9ba811,0x260f63dc,0x15472a3f,0xde2b056f,0x007290e6,0x1b170d9f, + 0xb6b5c8f9,0xa2e23e8d,0xcf34c3ee,0x345a2839,0x1b973ee2,0x9bdc5461, + 0xbb24d1c5,0x65bda6c2,0x3c6141a1,0x97d52ba3,0x9d2eb201,0x47bb1612, + 0x21fbe49f,0x7c558a87 }, + { 0x3f350fec,0xb9485a52,0x6a38d4c0,0x016678c5,0x0d5aa64d,0x8ef346a2, + 0xd96da2e4,0xb85daa02,0x4f647b3c,0x845ec4ea,0x0d5e946c,0xc0d1a6ca, + 0x4fa9f4ab,0x41d8d1c1,0x9c8b1303,0x43972cc5,0x434ffbfb,0x67e1f48d, + 0x819d2318,0x350ce93a,0x6ddef23f,0x49f53090,0x200cf12c,0x3c2e6cf9, + 0x640432fc,0x42691cc1,0x72496b52,0xbfff74b4,0x020a97be,0x44527c9f, + 0x7b3c4348,0x34cd7dca } }, + /* 44 */ + { { 0x59e7fe87,0xf031761a,0x0047cd72,0xb1eae31a,0xfae30f62,0x27902e68, + 0xb71db143,0xa666f48d,0x0e0038f4,0x75ee6678,0x02bdd76d,0x3b45ac67, + 0xa0d6cd5c,0x0d2fb828,0x9d8c5b11,0x27ce7f1d,0x120b5e96,0x141fe0e4, + 0xb9267c37,0x95a1b984,0xd60312cd,0x5206e589,0xda549356,0x1867342e, + 0x070c74ac,0x374520b9,0x9557b0b3,0x2703cbb5,0xa6ed8c14,0xf621f59c, + 0xabf7b887,0x7ceb1cc2 }, + { 0xdb7fd65b,0x0647a5bb,0x36c9457c,0xd8d45cc0,0x9e12718a,0xc6da99db, + 0xe93a7fb1,0xed1dbbf4,0xbd1566a1,0x4512c95c,0xdbc0c919,0x4861ba00, + 0x9e7f5269,0x3c6cc298,0x0941aaae,0x67196150,0xc8c538e3,0xbfcf5d0f, + 0xa25a551f,0xad6e9929,0x17ca0f26,0x90710985,0xfa89ef7e,0x743b78ea, + 0x71ab4549,0x39d5ea31,0xe6d1c36d,0x7442f3f3,0x059d568d,0x25a683e0, + 0x227ced5c,0x1f629a99 } }, + /* 45 */ + { { 0xe45a1c3e,0x8925ddac,0x41f7545f,0x72d29365,0x37e7f828,0x45622fcb, + 0x3e4c79d2,0x88234513,0x9c2645d6,0x5dffaf84,0x994802b9,0x3078f4dd, + 0x9d339fa0,0x566927f0,0x9fd91dcc,0x9a500a1e,0x0ab0abd7,0xce008180, + 0x8194e5df,0xd97135a3,0x98adf088,0x9e876307,0x9a45a2a7,0x3baf01b8, + 0x788b4399,0x6fed6154,0xe77a997d,0x980e5722,0x2a378eed,0xaac90ffa, + 0x8bd805a2,0x4a75fda2 }, + { 0x55e74cbc,0xd09a8fbb,0xfab18f25,0x737738ce,0x9764ec3a,0x0fc23ad6, + 0xe7e0ad31,0xc5a7d35b,0xe481cc9b,0xe75e068e,0x3d4aec34,0xf0c2ea99, + 0x0d4a63c4,0xf1324fe8,0x99b0592c,0x5dbb7c16,0xa7e0f46b,0x442d674d, + 0xa300faea,0x5a5d66c7,0x3333ac83,0xe83dc821,0x8c408496,0x70ef812e, + 0x99ef5fc1,0x96e1dcb6,0x1734e862,0x6e2b771b,0x583507d8,0x04629cdc, + 0x23d8179a,0x5819f9ae } }, + /* 46 */ + { { 0x6aa78811,0xd9969121,0x2103e7c3,0xf64ee8f4,0x22b9e698,0xddf01070, + 0x4f582cde,0xe6001f9e,0x2ecfac1a,0x24a608af,0x06393009,0x6ef4c784, + 0xebf72911,0x5262eae6,0x8c4ee5a0,0xddbd0af5,0xecd87bc7,0x875aff90, + 0x6f24f114,0x2fddb34c,0xe865f172,0x48104281,0x886c1b9a,0x95692426, + 0x9ef4231f,0x6f5f3208,0xd0a7e82e,0xaf587acf,0x9ac395c8,0xd6571917, + 0x1364a750,0x7459603c }, + { 0xf41ae519,0x1c2475bf,0x4af8f251,0x34401fb1,0xaefb2c3d,0x70ddfcd2, + 0x51cdaf08,0x9b2d385b,0x8208bb19,0x8531c256,0x4c33f3f6,0x16c89df6, + 0x24571769,0xc23cfa99,0x86d010ba,0x2339b51e,0x22638313,0x08db0e8d, + 0x00fedeb7,0xf769e179,0xa3687ef1,0x3fd96dcb,0x91476475,0xcd046b23, + 0x0c45c8dd,0xf3ff2064,0xb8343d78,0xefd167bd,0x4b77ee90,0x493ccb6d, + 0xb3cf7b45,0x33025513 } }, + /* 47 */ + { { 0x35eaaca1,0x36f00469,0x89119102,0x0c384b75,0xe6d2954c,0xcb375665, + 0xb1e9d6d7,0xcb9199b9,0xc29c2757,0x75852349,0xb8e738d0,0x89cbd1ba, + 0x5923a427,0x9b8dbe90,0x18fe1889,0xa237793e,0xa742e083,0xa4271757, + 0x4eebd613,0x8c4979d2,0xd4f2cf77,0x40325054,0x958705de,0xa3b8a091, + 0x33d999ba,0x1b191bd9,0x3b0fee1e,0xbafefba4,0x3facdf14,0xb3bad184, + 0x4387561c,0x9328adb0 }, + { 0xf906b872,0xabe84e80,0x78262665,0x705523a0,0x3398ccf7,0xd89c6a7e, + 0xf55b5323,0x2fab551d,0x0554dea8,0xa0578eca,0x375589cd,0xef26523d, + 0x864ad750,0xd8fd6242,0x178fe1fe,0x93f27fc5,0x9df87422,0x7b3e6f30, + 0x3750d054,0x2862e49e,0x5dc038a1,0x7d90c6b2,0x84db682b,0xc1a1ae22, + 0x9881930a,0x47f3dab7,0xbaf3e0a4,0x30e6bd52,0xf62d25c5,0x0680025b, + 0xadd0d5e7,0x0aa1f3cf } }, + /* 48 */ + { { 0x22a10453,0xa9822190,0x2a03a10b,0xdd1eb91c,0x96646f3b,0xafbb5d95, + 0xf38b6fc6,0xa58de344,0xb8cfca1d,0xce47c3e5,0x0f70da04,0xfcd8e16d, + 0xda262ed6,0xac44349b,0xc56e2f8e,0x9320d87b,0x19138e58,0x9ce3ea08, + 0xa2b236c0,0xa5862dff,0x8e7efb0d,0x6b0f9a5c,0x16ac78eb,0x4b53432b, + 0x709b51af,0x6ff43105,0x8f519628,0x08e236f8,0xeed403ad,0x1f93f176, + 0x9636545e,0x559337e0 }, + { 0xd8fd807a,0x30ddf738,0xab131222,0xf4e0ec9d,0x625afbc3,0x14a2f4db, + 0x9f12f895,0xd5b70604,0xac3044fd,0xb46f3c23,0xf540148f,0x1b232d1f, + 0x39b4e554,0x61b458f5,0x0dd70b75,0xf694b24a,0x289581d9,0x0fc64299, + 0xee5fe22d,0xc05d49be,0x6a18bf63,0x7af3447f,0x7f1929d6,0xe96a1dc2, + 0xc1551e8c,0x6afe6028,0x2b5d4fa2,0x27dacaf3,0x545c2cb4,0x4a1631bc, + 0xb0c914d3,0x930070f9 } }, + /* 49 */ + { { 0x69a9bc05,0xd2f32c5e,0x589c4b73,0x0a5c19c6,0x94665f9c,0x095c9e5e, + 0xbcfb4c39,0x8ab0f293,0x1ddb7c31,0xb9070877,0x66b38048,0x894e9658, + 0x606bd9bd,0xf19a90cf,0xb6fd2d69,0xcc1d58df,0x461d8a69,0x886dcc4e, + 0xf9ce4831,0xc455c277,0x765f8a82,0x749a5996,0xc3badc8d,0x2ffc668c, + 0x9112cdab,0x38018396,0xb243c7cb,0xa98795c3,0x010a2224,0x8775f310, + 0x587b5e14,0x043a2141 }, + { 0x3a873752,0x7bbe9dbc,0x2f442fee,0xee1493f4,0xc18c2181,0x981ca2c8, + 0xe29769e7,0x00ce3090,0xde768c5f,0xb4626ac8,0x34d7677e,0x33e9ce46, + 0xe0fa94e6,0xf89c2cad,0x41f5b5bf,0x04f5cc11,0x2228c12c,0x2565f736, + 0x0c05cce5,0xf1bf706a,0xbe487c4f,0x5d07ffff,0xa499f1a4,0x3ec43c09, + 0x98d94800,0x4f4e79bb,0x073f12f8,0x8a335a16,0x0f970d6d,0x4bb5eaf7, + 0xf24d0ae8,0x18d0747b } }, + /* 50 */ + { { 0x84601faf,0x58d3c77c,0xaf1c1f72,0xc9465be2,0xd116d806,0xff626798, + 0xd5b0d93c,0x3996c0c6,0x5ec6723a,0x2fa1ad75,0x03ba5349,0x966a8144, + 0x2ac34d8a,0xdc4c9422,0xed675865,0xddf471de,0x953d528f,0xd8aca597, + 0x24ebf67d,0xb2e463b5,0x7e25b4d3,0x25824871,0x43159daa,0x23c5adba, + 0x83357540,0x5458f9c6,0xf938b1a6,0xcf685da7,0xcefed231,0x981a4fda, + 0x08bb5e59,0x711093ed }, + { 0x401f161a,0x12aa3fc6,0x974c5e87,0xf7358560,0x17b5df82,0x4aa252fb, + 0xa48e6299,0xb0b82b07,0x29dd847d,0x00234157,0x4529c5a6,0xf1e54d00, + 0x6d98f538,0xcc1c539e,0x28d3abcb,0x36162b53,0x2a84f0cd,0x75a37938, + 0x4dee7484,0xf717a81b,0x4c23bf1b,0x16cf35fb,0x787e8b3e,0x7fd1c29f, + 0x59b79ab0,0xb7da7e68,0x85f6c60b,0x072100a0,0xe7ed48b5,0x31840159, + 0x4d9c97d4,0x17898bda } }, + /* 51 */ + { { 0xae1b8cf8,0xcd8483d8,0xe9a28856,0x323d4b42,0x204a4bc2,0x7633584f, + 0xca7a69fa,0x4e0b2228,0xf757bab2,0x8afbda8b,0x6cc5f9ca,0x85b24088, + 0xd41a95c3,0x47fb4813,0xc2aabe6b,0x3f1bc53c,0x1ad1599d,0xf22cda3f, + 0xc31ea9b1,0x1b2ec081,0x01614ac1,0x048f304b,0xc6afa7ab,0xce31cee9, + 0x4140dc3d,0x55af7633,0xdce8abba,0x84b7ab37,0xc7cf3efe,0x50de7648, + 0x15356ab2,0x73a88dcf }, + { 0x06e83b39,0x3f868288,0x9f44037d,0x477a4413,0x17dbc841,0xf9058b0f, + 0x54d17549,0x2db64f4f,0xf2307ffe,0xa23cea6a,0x4f126261,0x393efd55, + 0x10f37f26,0x2f4e658a,0xf4ee1e35,0xa4437ce3,0xa93cde8b,0x64ef42a7, + 0x939aa901,0x1debc9f4,0x3d7b5cd4,0x44223d6a,0xf88a3acc,0x789a6a11, + 0x2c608a2d,0x56fb9df8,0xbbf56c06,0xe79db8e3,0x668fa300,0x73c56af2, + 0xae396a1e,0x52f32b17 } }, + /* 52 */ + { { 0xe714f71a,0x56f524c1,0x9add8519,0xc1be1262,0x65cadbe3,0xad9189d8, + 0x5a0fb649,0xd88bf5c8,0x21d192d9,0x9efa6a92,0x6f724b6f,0xe3fe8389, + 0xb250119c,0xec3fae24,0x2ae0d3c0,0x4b6af9f6,0xd619624d,0x8fceba0b, + 0x2fdb6e3a,0x7dc3092b,0x3263cd29,0xc91da376,0xf95c43bd,0x30c0761e, + 0xcdeb44d9,0x89136400,0x43c0d31d,0xfd7dce84,0x9871899f,0x78fec3b1, + 0xefdf58c1,0x79e14d28 }, + { 0x9bb40c55,0xe3822235,0x0ed07a42,0x0a27202d,0x4838c1f4,0x48e6c1a9, + 0xd864a78e,0x2b5f24a7,0x0c6c55c9,0x7e7f140a,0xce12d508,0xe62c104a, + 0xc11b1e10,0x9b0a1a7e,0xafbb3dd5,0xfd8a275f,0x9a3b6b30,0xdff354fe, + 0x46602a01,0x5a105d9e,0x93bb65f7,0x3d371b4d,0x0f82fdeb,0xda5cbf0b, + 0xde468545,0x4601229b,0xc73d517e,0x505e10b9,0x672ff492,0x77cfa541, + 0x99566ce2,0x0d8ec28a } }, + /* 53 */ + { { 0xcbeee995,0x014cf73e,0xd491e80c,0xb2eb88bc,0xd9aba5d4,0x615a6cad, + 0x9304c84d,0x2f7d4633,0x8ab03c9a,0xba0501d2,0x91babb94,0xc8f723de, + 0x50405772,0xc885f977,0xc7fcb094,0xb5e1d2b3,0xdf96c71a,0x61ee7995, + 0x3464499e,0xb8c8daab,0x5f607932,0xdb425ddd,0xb1243587,0x70251ca1, + 0x9fc74340,0x26d7d3be,0xc902ac89,0x8c179310,0x4559a74f,0x72522c15, + 0xc3734afc,0x86001e27 }, + { 0xe7693947,0x13b00ba5,0x012c062b,0x6478641e,0xe85490a8,0xe1a438e0, + 0xd9574d5e,0x5173dbbf,0x9bd3ba61,0x9532eb8c,0x5f3ea075,0x1f41bcb8, + 0x8cbb92b9,0xac1cc247,0x1ef901b4,0x0f34648e,0xd2b3b2ee,0xdd929d1e, + 0xc3d75bfc,0x470f1eab,0x139cf4d2,0x5cdbc6f7,0xf0424953,0xcd86454d, + 0x47fcb383,0x1e079812,0x17df930c,0xb9f209b4,0x114ebc00,0x4225fc31, + 0x347946c1,0x020591cb } }, + /* 54 */ + { { 0x275e0af4,0xe3003721,0xe78a4a4b,0x721141ef,0xd1757485,0x666cfcf6, + 0x168e659e,0x5fa1d737,0x0e2842ee,0x263e3e54,0x948bd5f6,0xadecc3d4, + 0x246b104a,0x019de03d,0xf343d818,0xf8a9e903,0x5b0c0d31,0xcb57ba4a, + 0x51e2765f,0x8246c506,0x6519bf67,0x80c5751f,0xf2119a01,0x5f05c200, + 0x7821d4f4,0x7e6487b8,0x261c3a06,0x262f94aa,0x72146052,0x56cfe489, + 0xa1df05ef,0x5119985f }, + { 0xb18586c0,0x5819497d,0xc6eeaa62,0x004415d6,0x97cda28b,0x7c6a46b6, + 0x7c194594,0x9a149b28,0x4ed3a506,0xb56369fa,0x43c94cb4,0x7092aa66, + 0xa9e9eee2,0x55bce73a,0x77893509,0x34bb2870,0x06eb5326,0x8af95fb0, + 0x9638f485,0x87cd0323,0x5ba75bf8,0x29376268,0x9d42d581,0xf32d6f3d, + 0x65c6d64d,0xa4cad574,0xb2cded41,0x985f50fb,0x9006a067,0xcf34ce0e, + 0x58a57f9a,0x59eaf265 } }, + /* 55 */ + { { 0x6ec3876f,0x7b407efb,0xf0f48648,0x780c6123,0xbf893039,0x2abb56ff, + 0x45a91ab0,0x9592eaa0,0x78811b82,0xce5b84d7,0x1f9f3fc9,0x86a71a34, + 0xf0e7e13b,0xc17fdd86,0x655a0880,0x88ed8297,0x81d5e666,0x75d6dc74, + 0x1d171797,0xeffc9df6,0xe3f79e1f,0x36ad4c8d,0x2046192e,0xdb15317d, + 0x274fda62,0x78c9fa7a,0x82dd9914,0x04ec924f,0x3a64971c,0x059d1e38, + 0x2620bbfb,0x3b4450ea }, + { 0xc776dcdb,0x3db7a955,0x81c8ba47,0x35c4a57c,0x505760fb,0xae285003, + 0xb3aec353,0xe3e80691,0x47117be5,0x380335be,0x056ccf61,0xe1c47e3a, + 0x33977916,0x253cfdeb,0xf5cb7ee1,0x3decdfba,0x7cf4b704,0xf3c9794f, + 0x9ff81462,0x2401680c,0xbe3daa9f,0x4e440e11,0x69f91d8a,0xc5d04377, + 0xcb5e9c5d,0x4106c7a8,0x33b7d24d,0x191909a1,0x3764b4a2,0xe893c838, + 0xc429b614,0x4a7fe30c } }, + /* 56 */ + { { 0x2455c7c5,0xe78f3a70,0x70157754,0x5b7636e8,0x7623262c,0xf32c4524, + 0x1bc780c7,0x2c98b11e,0x915ed877,0xd48eaeac,0x199265f4,0xbb04d3c0, + 0xcfa5200f,0x6b52b19b,0x93ea3fe8,0xc46a0981,0xba758059,0xd82c733d, + 0x1896aacc,0xd324bbd6,0xce8ecd51,0xac09a2fc,0x02fc44b3,0x529918fd, + 0xaaa1784b,0xf0c45e4a,0xfe22085c,0x35626340,0xc50c7d61,0x53cbb676, + 0x65126b23,0x83fa1ea3 }, + { 0x10ccc646,0x60ac86da,0x7b0451e9,0x2ce0637f,0x8a088610,0xbbbcf630, + 0x20349982,0x23c19019,0xfc0bcda0,0x707fc39c,0x1bd4fd7d,0x7f4d1f15, + 0x44713bbb,0xd6a64e74,0xc5ac9e60,0x57bdc676,0x37b61169,0x456c5303, + 0xdcf40a1d,0xd3451396,0x4997d2c7,0xf3edec25,0xc2c4a739,0x534ae9a4, + 0x6a6ad2e2,0x1401397e,0x23e95f81,0x20769d4d,0xde98fabf,0xcee007c6, + 0x931c51e0,0x61409779 } }, + /* 57 */ + { { 0x15156623,0x3ddb32db,0xab7a67c2,0x68137fbc,0x6f19e3c2,0x26011f50, + 0x89924c61,0x34218b02,0xc6804c1c,0x492a0b0f,0xafaae6a7,0xd65be706, + 0x0d01be61,0x3b13d23e,0xf87f4c69,0x44545b47,0x04dc1aa3,0xd42236e2, + 0x3c5161ec,0x6135261d,0xbd88bc07,0x1eb46a63,0x1599d720,0x78c6d836, + 0x69baf0f3,0xf6955fe1,0x17072820,0x467eebd6,0x3e3a340a,0x2f1b8a2a, + 0x2d0b5f88,0x636dac76 }, + { 0xb4c80af3,0x94280db9,0x4e3892ab,0x9a189cd1,0xd1477ddc,0x26e702e0, + 0x68f9f14f,0xe91aee38,0x80baa0b2,0x2864f63a,0x8b714a29,0xacd81f73, + 0xc5fe7cb6,0x30e1b870,0xb10837fd,0x883ea1c3,0x6b20489f,0x2da27953, + 0x58a2da5f,0x3aeb2a68,0x03a8fa14,0xe2330bf2,0xdc70b1c4,0xb5c488b5, + 0x299678f4,0x0a78c4d9,0x25df675c,0x233bd098,0x7b67d368,0x37b5c076, + 0x4d0bef3f,0x2f6dbdfe } }, + /* 58 */ + { { 0x2e4da7c7,0x2f8472fd,0xae677932,0x708cfc91,0x3dc268e2,0x364af08a, + 0x799a2424,0x0f10dfe0,0x71d58bff,0xef912d58,0x988962e6,0x6bf35dfc, + 0x5f47ea0a,0x28b96fa9,0xaad308c1,0x734a79ea,0x9f437bba,0x95730337, + 0x6cf54f75,0x002cbd8e,0xe7632eec,0x47606dcf,0x53193104,0x404b5ecb, + 0x0acf729d,0x0ae0897c,0x3bddf1de,0x89628b86,0xf87d7448,0xeced154e, + 0x458d5d4e,0x5cb6e197 }, + { 0x008c75ed,0x98cef197,0xf6eeaaf8,0x7cf49d3e,0x1875e96d,0x1d6f9e02, + 0xdd9b0d8a,0xfcec2cfe,0xb9576daa,0x38a61cfe,0x36a7dbb8,0x10003f39, + 0x23b814f4,0xb37c3868,0xb80e3153,0x9fb66dcb,0x059847a8,0x9e7e2eba, + 0x35a72770,0xa4ec63fd,0xfc9e0ed0,0x311f3d91,0xd515baa4,0x3c1dc094, + 0xa08cd4e3,0x75a06ebc,0x2ed5eeaa,0xab617238,0xe1f52c1f,0x2e82bbb0, + 0x5175d6e5,0x2149d630 } }, + /* 59 */ + { { 0x5f9311f6,0xee1a8e6f,0xbabc1f85,0xc97e3c9f,0xb494209a,0x4fa7c52e, + 0x19774fe1,0x04c2f51c,0x8555844f,0x5cefd122,0xb5873ab3,0xb53862a3, + 0xcbed19fc,0x768efdd6,0xee58469a,0xcdc12479,0x3d80c09c,0x11237e31, + 0xc044c28c,0xdd74a290,0xbd47e287,0x9ee6517a,0xad0ffeef,0xc2421228, + 0x818d281f,0x4273088f,0x43ec0de1,0xebc744bc,0xb415bd73,0x5b26eccf, + 0xcb07c26c,0x14e2f350 }, + { 0x4216946b,0x548d2a10,0x7a4bd92d,0x6e801f07,0x43695160,0x5996d0a3, + 0x63a197c9,0x0f1b5c2f,0x061f77c9,0x79da3c4f,0x93ff7b22,0x1c1cd634, + 0xa234123f,0x5e61b650,0xf284033c,0x826b34c5,0xc2f34214,0x718b90e8, + 0xae806ec5,0xa5f35620,0xe324a9b4,0xa2fae345,0x8b53cb51,0x8c0bb95e, + 0xf9965778,0xc94f6ac2,0x6b9def32,0x07ec607d,0xd0ed8f27,0x63bf1dba, + 0xdcb61e4f,0x58537e02 } }, + /* 60 */ + { { 0x64f80ba2,0x1f64b064,0x0559a45b,0xe8e055e7,0xf1f4b634,0xc3262b34, + 0xde8c8482,0xef4f7d5f,0xc30c780a,0x9d55dea0,0xcfa1e693,0x1740afb9, + 0x7460c34b,0x2cfe6a66,0x1187c1ee,0xf6695941,0x5f974d94,0x1382f277, + 0x004549eb,0x1ca0ace4,0xbabded02,0xf8244b3f,0x4e3653ea,0xc36f4d06, + 0xc55c5f83,0xeab9f0dc,0xacebce90,0xd93b9cef,0x19061425,0x16658e72, + 0x82d7970d,0x4857835f }, + { 0xd2576210,0xdcd525bc,0xd51b5443,0x9f378aa7,0x1bd83994,0xfe97bf17, + 0xf38ac621,0x930d0f63,0x818408cc,0xaf8f2c17,0x260f53f6,0x2692c87e, + 0xdb0a75e4,0x0ee45407,0xffdb1b37,0x0ec47ae5,0x7aa6a44b,0x769129dc, + 0x2e40b75d,0xb6f932b2,0x95ef3b77,0xe06764d0,0x68bc63e8,0x28fd47f5, + 0x9c0014c0,0xd1810494,0xd7995d8e,0x90e2d3fd,0x6c2a85af,0xeb39a05d, + 0xa21f3128,0x6c0277bd } }, + /* 61 */ + { { 0xb509e7ef,0xe41b7086,0x3d7f9f91,0x8842ec7b,0x5526b88b,0xcd285f94, + 0x051dd0ab,0x6e44e064,0x774f1ceb,0x90198c10,0x123e661b,0x6ecabe98, + 0x32f647d9,0x44811136,0x26c52aee,0x1dd82b45,0x939dc9d5,0xd650907f, + 0xfcd455bf,0xbd5eeef2,0x8d2e5d7c,0x7815a4dd,0x88bc9f2a,0x5ad4ec92, + 0x57a3b322,0xc6f10d0b,0x20b9cbdb,0xe8d0c1e7,0x9b774ee8,0x5a0b071a, + 0xf22fcf8f,0x3067bc9a }, + { 0xb7ca9326,0xe0e589f2,0xb1224f63,0x17a106fd,0x747a57bd,0xb2354521, + 0x62b0882e,0x2614982d,0x4391ffcf,0x7f3af544,0xa84e440d,0x1aaa337b, + 0x941bb071,0x28ea37b0,0x2e4a7f54,0xa957dcb4,0x1a6ad5fb,0xe7ab662c, + 0xf7c36a20,0xd135e381,0x9baa0b6b,0x42e7980c,0x94e4671f,0x4237030c, + 0x8b0922e3,0x24cc63ff,0x445a589f,0xd10d5279,0xa870ff6c,0xbb99d316, + 0xa996c195,0x390c83ca } }, + /* 62 */ + { { 0xffc4a73f,0x50d3fa82,0x3bd53303,0x2665d635,0x264bb77d,0x80a06f8a, + 0x22d73d84,0x81c04a6e,0x0323b8aa,0x2409cff5,0x8c4c4d5a,0x31dce217, + 0x0c0f9c19,0x374aa80e,0x00186bb8,0x0b25a387,0xaaf1487f,0xd0b77a10, + 0xab498de1,0x15f39ad5,0x1aa0c116,0x92e32da6,0x96e25ce8,0x228e3dbd, + 0x5e8646d1,0xb57c88dc,0x267b1c68,0x672b1164,0x600bdec5,0x5d0d807f, + 0x223e573a,0x3ea4007d }, + { 0xa595d0a3,0xd76debd0,0xaff0b3b4,0xa6bd76cb,0x9b1bdb97,0xbf2c154f, + 0x4c714c71,0x62b19ab4,0x221af663,0xc9bf33b9,0x8c941ef6,0x23d87c49, + 0xd79f0f6d,0x255804c3,0x2a7acbc1,0x6f1a1005,0x550528af,0x5dab79d9, + 0xc8d16213,0xfd77a6f0,0xde5e1029,0x40508b6d,0xf95da12b,0xd95ac0f2, + 0x758a8ba1,0x8860af71,0x7160c8fb,0x0b194c83,0xce004d34,0xa40e6c80, + 0x6b14aaa0,0x09f82a17 } }, + /* 63 */ + { { 0xc21366dc,0x60abe588,0xaf75daf9,0x729c0a4f,0xacb93ed4,0x70501fd9, + 0x87a16d70,0xb97e744e,0x98e7361b,0xa42e0a7a,0x28b54cf3,0x1acdaff2, + 0xb7bd9078,0xf087ccbb,0x663250e7,0xda6f3983,0xbaf07c09,0x66d693ee, + 0x8cbaf157,0x79baf4c3,0xdfca99d0,0x5a984e07,0xf26d8dab,0xab4d3247, + 0x7eba36f9,0x4d0be701,0x0e8dd216,0x37bb9e65,0x531c4f03,0x72aa4e24, + 0xb753d85a,0x77d1e984 }, + { 0xd8e62367,0xd9373239,0xb9820cf1,0x3361848b,0x5a9c97c4,0x00c7e344, + 0x14f960fc,0x9a0ec9ae,0x740474b5,0xcf41f0cf,0xece065d5,0xa5eede8f, + 0x9e808610,0xb1de5a4e,0xae0cf75d,0x17c44ae4,0x6b148d0b,0x2fa56323, + 0xd29ff2dc,0x64fa740f,0x88cb212e,0xc605eb8a,0x6a863016,0xf2c771ad, + 0x607b4c17,0x6d6112e7,0x40d49785,0xfe90ec07,0xe256e0e5,0x599be18b, + 0xca54adb0,0x4e6eabec } }, + /* 64 */ + { { 0xfb99cfe6,0x950323d3,0xc9334178,0x7b09bc26,0x7cbdfb6f,0x64111e41, + 0x89a75760,0x91141744,0x10919cb0,0x4c633df9,0x396bfd2f,0x715fc7c7, + 0x8cab62db,0x8ca19512,0x4db81aac,0x30672473,0xb4c4c54a,0xe67a246b, + 0xbf229646,0xd77ea0fa,0xfa5b5d70,0x5bed15f1,0xc2f192f3,0xa5686da5, + 0x7f6690ad,0xdecac72a,0xcaa50b7d,0x0c4af2a2,0x6049ad2f,0xf44631c1, + 0x04ecf056,0x325d2796 }, + { 0x4848c144,0xee11fb55,0xb6a7af32,0x4e062925,0x369e0f9a,0x125b68e1, + 0xca53b21e,0xad9bdae6,0x2e98ea1b,0xf50d605c,0x9f2fa395,0xbdb9e153, + 0xe91532f5,0x4570e32d,0x46a250d7,0x810698ae,0xad9d9145,0x7fd9546c, + 0x11e97a5e,0xabf67721,0x249f82e9,0xca29f7d5,0x9851df63,0xa9c539a9, + 0x71d0e3e5,0xfd84d54b,0x041d2b56,0xd1e0459c,0xfd80096a,0xceb3eb6e, + 0xe32a79d3,0x19d48546 } }, + /* 65 */ + { { 0xb540f5e5,0xfe19ee8f,0x04e68d17,0x86d2a52f,0xadbdc871,0xd2320db0, + 0xd03a7fc8,0xa83ad5a8,0x08bcb916,0x54bf83c7,0x2e51e840,0x092133ea, + 0xcb52dddf,0xbce38424,0x31063583,0xd5c7be40,0x458e3176,0xc1ebb9df, + 0xbc4dabbf,0xafb19639,0xc05725a8,0x36350fe4,0x84e1cd24,0xac4a0634, + 0xc145b8de,0xadf73154,0xb3483237,0x0aa6dd9e,0xcbff2720,0xa3345c3d, + 0xb4e453b0,0x1b3ace6c }, + { 0x90a8bdc5,0x0343e5e9,0x6306a089,0xa203bf9d,0x8e48520e,0x98489a35, + 0xde7d1d06,0xbd17debe,0x5f795d3f,0x8fafa6d7,0x387b0a3f,0xa4ceb630, + 0xffddeafa,0xe0166b32,0x7e764e02,0xa2fe2054,0xe871f304,0x55ab9824, + 0x952ec45e,0xa2bd36bb,0xa90d20ca,0x7b4c1484,0x75bcfb53,0x5319f387, + 0x6982c4e5,0x34238a4a,0xa102921d,0xa2bb61c7,0xdb3ab17e,0x1e061b64, + 0x192f0a14,0x538ec33e } }, + /* 66 */ + { { 0xa19b56cf,0x193496fe,0x7bb99acd,0x663d77f4,0x57d0a881,0x8f04afa8, + 0x082835fd,0xcced3da2,0x5d82cec7,0x7e21faed,0xf8009c85,0x6e175b99, + 0x2d05a307,0xd9c6e31b,0x81487d82,0x96948d4a,0xd46f6655,0x86ebd3f2, + 0x773ccc49,0x86851aa8,0x8b1640a6,0x3e220f22,0x41a20b75,0x9f06e3a8, + 0x90ac0a6f,0x2cfffe5e,0x8ebeb3fb,0xf5a9b1da,0x6e08e2c9,0x2587d997, + 0x03e9f401,0x6fd60298 }, + { 0x8eb7516a,0x54709f8d,0xbdc598ab,0x83058a74,0x87e801ce,0xd234dd98, + 0xd17b8a96,0xfd0f9d90,0x6e90f6ab,0xaa1e549f,0x5a7ed55b,0x2496ff80, + 0x6c254c19,0x0d9f657a,0xb8962575,0x3cdea49c,0x2dff27de,0xb685a3f0, + 0xdb8bc04b,0x3c50e7fd,0x987236b0,0x904ff0ff,0xbb0d5055,0x494298fd, + 0xe14be8d0,0x34b3386d,0x7c3d30d6,0x7ad34e9c,0xe159fdd9,0x1f2b32bd, + 0xc761e5c0,0x84cfa23c } }, + /* 67 */ + { { 0x8b99b964,0x13bc11eb,0x58e2fc47,0x8e280c0a,0xd4c9a54b,0x870fbc49, + 0xbf6e20fa,0x37a334a2,0xd7c88cfa,0xee583d0d,0xef4af1da,0x05e029a8, + 0x0c2ef8a6,0x6d55e234,0x209e9b62,0x61b6fdfe,0xbb8e080f,0x3b1dad26, + 0x9392fc1a,0x5adbc162,0x0aae3f4e,0x02ac0fe6,0xc2bf4d5b,0x8d99801a, + 0xc282fed2,0x2333f93f,0xb52db33f,0x16dcb10c,0xc55752e7,0x09f90f84, + 0xc84a0d8e,0x287d4c51 }, + { 0x0e9867da,0x5fa58201,0x1a874cda,0x614589b3,0xfbdee22e,0x005e27c5, + 0xe612bda8,0xe357fef5,0x2d3635f9,0x4e0dbedf,0x6f125a86,0x62be70e4, + 0x0d94a2e5,0xa09b9884,0x28b5e5d1,0x7eb99a15,0x751028b5,0x21b9416e, + 0xe06d2cc4,0x1b137fd7,0xfea09845,0x6fa1f517,0xffcecbd7,0x3ba1e966, + 0x832f453e,0xd4c89a4a,0xeca68fa1,0x07b1e2af,0x4bd395a3,0xd0fb4453, + 0xd8ef9e13,0x0132a3dc } }, + /* 68 */ + { { 0x576374c2,0xe53c7785,0x84727040,0xe60526d1,0x228ca044,0x8a066dc8, + 0xf1ce1313,0x1fe1c1b2,0xcdeb0c5d,0x2aeec832,0x9cbf826f,0xa7596699, + 0xde77a589,0xcd188e81,0x118d1254,0xe5ce0fe0,0x0790b86a,0xa142a984, + 0x39ac28ce,0xe28f043f,0x87de5804,0x4eef8290,0xf639a8c5,0x83c31b32, + 0x5887794f,0xd70454a7,0x18b1b391,0xca635d50,0x31d9c795,0xcefea076, + 0xb6f8aa25,0x13cbee76 }, + { 0x8d3f34f3,0x79cabe0f,0xa3617fe3,0xbda9c31c,0xdd9426a1,0xb26dee23, + 0xf29c9104,0xe9dd9627,0xe2c6cd3b,0x033eb169,0xfcba2196,0x8a73f492, + 0xb858c83c,0x92e37e0b,0x23b3fbb7,0xe4f2aca6,0x64be00a2,0x8101fb1e, + 0x948f6448,0x91a7826a,0x907260e7,0x414067b4,0xe30bb835,0xf774aa50, + 0xc999c06e,0xf922ca80,0x0ba08511,0x6b8635b9,0x25fa04f0,0xbf936b5c, + 0xe02e8967,0x4e0a1ada } }, + /* 69 */ + { { 0x8ba29c4d,0x00ca6670,0x22988094,0xc08240ce,0x16dda752,0x21c5ca67, + 0xabbbfa34,0x689c0e45,0x3ed28b72,0x1d7545fd,0xd7c56ab4,0x5f221198, + 0x38759d65,0x4b3d8f74,0x8fe50b89,0x93490dfb,0xe80eba16,0xb641f5d7, + 0x79acb537,0x7b0da5eb,0x0c1d5e5e,0xab6b1497,0xa5da429a,0x2338e68d, + 0x2f6d2f25,0xe010c437,0x6530f3a7,0x226f16d2,0xcbef08bc,0xefb0f7b6, + 0x9f99c999,0x733e30d9 }, + { 0xa42a38f9,0xecfe1582,0x4730b500,0xaec2d58e,0xde976b2c,0x2ee2f2a7, + 0xa969c1bb,0xf0539db5,0xfcecdb4a,0x31954168,0xe7a8e902,0xf2f7348a, + 0x3121541f,0x1d58d7cc,0x2202ae52,0x5d25b75c,0xf40835a7,0xdea9965a, + 0x529b4e46,0x3feb6a41,0xbd27ad9b,0x5c97fb6f,0x261f900b,0xd87554c0, + 0x04d5b19e,0xb43031d9,0xcb219b9c,0x33d5e9b8,0x3ee00bcf,0x7a43d492, + 0xb79a5c0c,0x56facb39 } }, + /* 70 */ + { { 0xa3018bfa,0x019165a2,0x9ffad984,0x100c6b24,0x55341a9b,0xbbf1b1f6, + 0x25dc4cc9,0xe6bd1d97,0x2bfffe60,0x52850ed5,0x7e5509ab,0x24e992cc, + 0x4ceb59f1,0xff6c502e,0x1aa7d148,0x2f0b3573,0xe7e3aa46,0xe90c1ddd, + 0xd1142880,0xbaec9f45,0x65be5dd5,0x475cfd26,0x1febce13,0x83abb14e, + 0x80942d30,0x6aba4829,0x297e82c8,0x1e1b235d,0x50d8218d,0xb771cdbe, + 0xd94d6cbb,0x88599266 }, + { 0x155ccaf2,0x08847290,0x7c5b773e,0x8679ebc7,0xb2dd08ed,0xa88b2dd1, + 0x87d475db,0x960a180e,0x6694d02a,0x80fdb6b7,0x3f3f9e96,0x3e8758c9, + 0x4ad836c4,0xbda3f6fa,0x32fb387d,0x9400c581,0x2550200f,0x25a78542, + 0x776ecf18,0x2a97c351,0x566db59a,0x03ebf46e,0x26545eda,0x4743a280, + 0xcf74ab44,0xed169d84,0x88cb3f69,0xbaab931d,0xd8257196,0x70ae932c, + 0xa0c09719,0x797224a6 } }, + /* 71 */ + { { 0x441f3567,0x632923f8,0x2e24bf1d,0xc11c3168,0xb7671fff,0x4b97726b, + 0x7a5e1a22,0x601746a7,0x3addb417,0x53dddea0,0x7f59b846,0x57867a3c, + 0x56cd7ff7,0xb012a987,0xf19ba9a8,0x1bd5fec9,0xf8306748,0x750379a2, + 0xab8c05d1,0x7763445d,0x7903f42a,0x5d7f441b,0xa903e46d,0xc011674d, + 0xadd126c1,0x1b1d3c4d,0x61455b40,0xa2752aac,0x555c356e,0x4da42a68, + 0xd820852c,0x3ff09c15 }, + { 0xf9cb7784,0x4c0a1bce,0x2422f305,0xaec539bc,0x0c414aa7,0x5f40f9fd, + 0xffd42bc4,0xd3aa316c,0x2f358e15,0x42f5a4c3,0xd6e27682,0x00bdcd9e, + 0xf8a5ecee,0x069f789f,0x05e14f5d,0x8078018e,0x8b40c741,0x2bb3e493, + 0x7917f72d,0x5dbc8c1d,0xcc57150c,0xe0eea664,0xc3fa8920,0xa25ecc5a, + 0x1c797164,0x3c21b0f5,0x634ad16b,0x8f09a2f2,0x58391d9a,0x8e730fc5, + 0x4fdfae4c,0x47ef1805 } }, + /* 72 */ + { { 0x3da285e4,0x9965f3d1,0x3a01e3f4,0xba7d4dba,0x61214ad0,0x4738413a, + 0x22397549,0xd3b7d535,0x5a730b92,0xa53dbdcf,0x332d165d,0x3130d92b, + 0x82f97ef4,0x44a28541,0x44dce1b6,0xbf62221c,0x7e2a0ec9,0xbba13858, + 0xcbfad998,0x33f32c8d,0xb5fed44b,0x409e5f3f,0xc66217bb,0x5c328c65, + 0xfcdf71a9,0xb00db69f,0xb8920788,0xa23c2a21,0x3ae6464b,0xf8ab28e6, + 0xb8de0861,0x1a6b6e9c }, + { 0x06af77aa,0xaf6ec2b6,0xa887f065,0x2e60f5cd,0x9f498c56,0x87d21400, + 0xfcbaaf4b,0xdb595b59,0x271ab855,0x0fb592a1,0xd4349b0c,0xa0ce10e5, + 0x887d8c9c,0x9d6187d8,0x154bd6db,0x03ee95f9,0x5d06c999,0x8fe53213, + 0xfb6a64d0,0xf4a7bc30,0x66a4cb60,0x3d22af0d,0x5d37367c,0x16952cef, + 0x997d8e55,0x6f0ea734,0x731732d0,0xb447c70f,0xa9cb3942,0x00ab3034, + 0x28510fd0,0x79dd0180 } }, + /* 73 */ + { { 0x3ac7424e,0x04e0033a,0x60fda4d0,0xdb06b688,0xbcb772fb,0x236a9766, + 0xf297cda4,0x294a8e2b,0xdb013c6e,0x4b0aab85,0x8723a3ad,0x3d2aec98, + 0x13c84a6b,0x0cae32cd,0x70ec169e,0x21888f5e,0x42a88262,0x739633bd, + 0x7b60d9b8,0x68ac792e,0x10769fe1,0x89f2b722,0xd24bed34,0x8f3fcfe6, + 0xa3eb24aa,0xd35efb88,0x484c706b,0xddecfa3f,0x929ece0d,0x7cc119a9, + 0x8d405436,0x87e5ad45 }, + { 0x7d1000a7,0xba99aa9d,0xae823833,0x8b94affc,0xdfb83dc5,0xc8229628, + 0x845a418d,0x2f59fe11,0x5d417054,0xa8b970f8,0x72b71581,0x8918c265, + 0xc0d1dd17,0xe4ef477d,0x3afad7c0,0xb50b4cf3,0x01870a5b,0x21baea79, + 0xbb3a2868,0xc77087f9,0x124a59cd,0x7857531e,0x57f43239,0xed74c26f, + 0x0164c94a,0xd5f5ae25,0xf094bf74,0x6608b7e2,0xfdceea32,0xf4cdb5ba, + 0x990cc045,0x0b712519 } }, + /* 74 */ + { { 0x88d5c64d,0x5a290ca1,0xa7492534,0x0596d749,0x2a00e925,0xa04b0d3d, + 0xcaf7b66b,0x082cd02c,0xecdded83,0x912b50c2,0xff31646e,0x813ce9de, + 0xc75fff95,0x62ae70c7,0x7e2a4615,0x6f6852e0,0x03804fd1,0x320fd7d0, + 0x8218e8d9,0xb1a2a4dd,0xafc645d7,0x4918a6fb,0xe8d9fdbe,0xfb080fa1, + 0x4470b6ee,0x33d4d08a,0x6d974ef7,0xd2ba2077,0x69dae5d2,0x8ecb95a7, + 0x7d69596d,0x7a3f423a }, + { 0x9a929387,0x362d2ca6,0xcb1c1fff,0xabdb7581,0x7e51b6cb,0xd892ec9f, + 0x3a4e131f,0xee8d8632,0x5bd87561,0x4680e3f1,0xd4e7e732,0xe3a597e1, + 0x5581fefe,0x3cc72b7c,0xca8cae0b,0xf3e77f8a,0x5e2fd4af,0xfcc7d7dc, + 0x21355b79,0xdd3a4552,0xa2c07177,0x546b24f2,0x0689621f,0x415b532d, + 0x3f78163e,0x2be9af51,0x33d7ed21,0x27d63b9b,0x96802943,0xab019ef2, + 0x1623faf4,0x2da5fc55 } }, + /* 75 */ + { { 0xc8a5c600,0x62429cf3,0x3fe33e7c,0xa7a80c22,0x0a57ddcb,0x9ffda740, + 0x925b0c74,0xd1ae156d,0x6b100eb0,0x097a43f9,0xef943c81,0x169e945c, + 0x1128cf24,0xa1f734e5,0x419f0133,0x04387c4a,0x01044024,0xc007868b, + 0x90359cf2,0xe5416abf,0x478d54e3,0xf9c76fee,0x42a2173e,0x66219da6, + 0x9fe30141,0x61e03156,0x93ef247e,0xa0ff5ce3,0x072b6592,0x811792ba, + 0x70c854d3,0x855f0219 }, + { 0x847314c4,0x61fbfb6c,0xeb45b96a,0x97906155,0x6ba2afac,0x7102e146, + 0xab949781,0xed51f975,0xc110c4fe,0x9d2f5b17,0xaff57667,0x7ac8ce70, + 0x6eb244e7,0xe7366a21,0x551c65c7,0xdd1bbcec,0xe1a859de,0xb525060a, + 0x8ba7d2e7,0x7a048174,0xab8ea8c4,0xe1a2c541,0x6fdff078,0x6e7824c3, + 0x14874b04,0x79b49fc7,0x06b1f733,0x22ae337f,0x6f8fe6cf,0x1c352192, + 0x525d0797,0x292236cf } }, + /* 76 */ + { { 0x7d8b29dc,0xcdb8d80a,0x08ea648a,0xd17a2024,0xae92be91,0x7db12c5e, + 0xfda72fbc,0x1f347d18,0x9e760c6f,0x11374b40,0xd8e38d91,0x7361e8f1, + 0x739ac1f4,0x7714be9d,0xb4df5c4e,0xc1f9701c,0x6f72cae1,0xd9138ed8, + 0x6ad180c4,0x1c7fe1f7,0x9e2dbf9c,0xf8c185be,0x7c70c44d,0x835db269, + 0xb0d15b5f,0xf997cfea,0x61e6545e,0x5101445a,0x25184e5e,0x16b06884, + 0x7521e7aa,0x7cfac359 }, + { 0x3c0bc53a,0x81182167,0x7e751367,0x84b5ede3,0xa3657a18,0x3ca255fd, + 0xba1fdd98,0x096abbf4,0xc5da77d8,0x9ce8369f,0xaab342c5,0xf27b9ae7, + 0x972059f1,0x06c91bd6,0x914ecfe9,0xee0dab30,0x93f53f12,0xbb647fbb, + 0xffa57e0e,0x30c38a7a,0x9f2ad607,0x517d06ef,0xbb99dcc9,0x49728d87, + 0x446080a1,0xb0034af1,0x12b9c17d,0xcc810c3f,0x772a22a0,0x7225f14f, + 0x1ddf82bd,0x6ce3dc7f } }, + /* 77 */ + { { 0xa4397830,0xc07cd835,0xf4733306,0x4dd9290c,0x29989e8c,0xdd35d3a8, + 0x563d8152,0x79902559,0xe87de61b,0xf278d911,0x1024e35c,0x9c7340c7, + 0x4a0d0e59,0x2d444461,0xf32626a1,0x63e7608f,0xc4c9baa9,0x627a37e9, + 0x76fffd25,0x0c56dc51,0xcef2a1cd,0xcb6defc8,0xefc559d9,0xcbcc0d56, + 0x041cb692,0xe45f3fc5,0xe5161e09,0xcd05c239,0x5c3b559c,0x2a731ee9, + 0xa3d0a16d,0x85151122 }, + { 0x86ff19e2,0x782d0335,0x1da28603,0xc2c60daa,0x557c7eed,0xb2e78cfe, + 0x1bc4e8b0,0xa8f6f984,0x3df35c67,0xcc1f9b4b,0x4764462a,0x96e13603, + 0x7c7ae0b0,0xbf910b97,0x51435956,0x27c7f305,0xf631eae5,0xc14db15c, + 0x7e69b34c,0xa51d6142,0x5fc12ff2,0xdec82851,0xfb887162,0xfcceae13, + 0xde1488bd,0xda332ac1,0x2ee3e74c,0xa20374e2,0xf0ae069c,0x597ea1a1, + 0x77bdec04,0x8b1159f2 } }, + /* 78 */ + { { 0x2f961d30,0x4af71a44,0x7ac7248f,0xbdf968a8,0xb1a906cd,0xd32df87c, + 0x04abf925,0x00c10e26,0xb9f04d4c,0xb8711759,0x939705da,0x00d54e60, + 0xc9f80849,0xf7587433,0x6a7a2375,0x2e9abade,0x94ac17ac,0x5676d478, + 0xc202d99c,0x4ca0525b,0xabfae73d,0x95b8bcad,0x3405991b,0x2371ed38, + 0x458a99c3,0x2b69e47a,0x2b78c866,0x7cac0b18,0xe0232c7c,0x6ceaa79b, + 0x588f7459,0x0bd86433 }, + { 0x7e734189,0xdea1a8b4,0xcfe5fa17,0x52c5ac88,0x11437664,0x444a4d4e, + 0xaf9e9750,0xc2522308,0xd30c6b3b,0x78b1d0c3,0x4c6df477,0x2edae5f0, + 0x2ee88dd7,0x53131d9a,0xacc93e34,0xc4e380ee,0xa8db0e8e,0xd499b1ac, + 0x7f5d49d7,0x77348c16,0x1556ccd7,0xc9663257,0x2611d13d,0x65ce0e8c, + 0xb5a2fdcc,0x2c95fe66,0x8658faa1,0x26698832,0x31c32c98,0xda87d1f4, + 0xfcd91907,0x46650598 } }, + /* 79 */ + { { 0x6b4a5efa,0x4c6c13cc,0x1d07b265,0xc481989b,0x8bdc69c0,0x10b966ce, + 0x2c2531d4,0xf54cfaa2,0xcad0a100,0xcb5f1808,0xee5da449,0xbeb52538, + 0xbedd83cc,0xa6240085,0xd6255c78,0xe792dacf,0x2062058f,0x88371906, + 0xed1658c1,0x96615e83,0x7d28d542,0x4b549b27,0x83b75df3,0xeaf127db, + 0x17fbb942,0x4f60df6d,0xf6f7c930,0xd08631db,0x6018789f,0x17c38f98, + 0xb9a9280c,0x0c43574a }, + { 0x1d20cad0,0x76eb324c,0x8c61108a,0x90decb09,0x6f06d36d,0xa6e9d39c, + 0xbc0da197,0x6cd978ba,0x507ac5ce,0x5948b1c0,0xc5497eb5,0x2bd47164, + 0x4d5914e3,0x2a9c4c0f,0xa759f03c,0x772c5046,0x69ac847e,0xe7d7328a, + 0x3048b330,0xa8d57d0c,0x40f7bace,0xe60034e0,0xa85f1790,0x823d9193, + 0x5c859736,0xa6e9b66c,0x679e1022,0x22ca2c7a,0x09023fa4,0x00e7a19c, + 0x2726d5b9,0x324999f1 } }, + /* 80 */ + { { 0x7c834915,0x667eaed6,0xbc5eb64d,0x9f77aa6a,0x25d62011,0x729ebcb6, + 0x699fd9c2,0x0aee24f2,0x2b8d4f6c,0xe1eb5874,0x14c976d6,0x7f12710c, + 0xf6d9ea65,0x91390335,0x06b50064,0x668b7049,0x0876ee4f,0x65969a0e, + 0x2f9d9360,0xf901bf3f,0xb499e3ce,0xfb1a8651,0xf2dbcaaa,0x80b953fb, + 0x973b06b6,0x312cc566,0x3af36c64,0x3534d9c3,0x10ffd815,0xe4463a52, + 0xf18c2b91,0x57ea2b4b }, + { 0x8aa0f2f2,0x00f5e162,0x0e46bcaa,0x8c7e75c5,0xa4a2c42d,0x97ab479a, + 0x14baa202,0xb4f308ea,0x6943cc2e,0xa901bd14,0xeed58804,0xbb125fee, + 0x9d180f7c,0x6502c8f9,0x1580c61c,0xe5353919,0x27101ee3,0x7e278069, + 0xfaa72717,0x7a0a40a1,0x4c75b153,0x32edce02,0x538f1c22,0xda23660b, + 0xbe307d2e,0x4d511e98,0x9baee0b4,0x24276e40,0x7ff1f307,0xa78c3927, + 0xea7935c9,0x60480b46 } }, + /* 81 */ + { { 0x3872ece3,0x31087d66,0x955b70f8,0x5f29be7d,0x9cf95bb8,0xb50b4fc7, + 0xdbffa621,0xbae3b58d,0xe022ba5d,0x0e61d280,0x4181449c,0x78ae5117, + 0xcf555485,0x0b132840,0xb8ce0b0e,0x800ed1b6,0x78d5de3d,0x35dffdd5, + 0x69a56b47,0xf7e42374,0x8d910ae7,0xd5e32369,0x6313c7c7,0xb6ff52a0, + 0xa92de9e5,0x5a2fe20d,0xd12110bb,0x41b347d3,0x40c16f23,0xc5905edb, + 0x9a8f88cc,0x0774a0d3 }, + { 0xe3b6c106,0x3ae181ab,0x8de150b7,0x4ebe163f,0x6f354836,0xcf75b82f, + 0x3ac7ac16,0xaa0d2063,0x291722af,0x5c680668,0x11545553,0x73941e61, + 0xbf5de3f7,0x17127e38,0x1afb41da,0x32cfdf03,0x87bc8663,0xc6893c91, + 0xa62c9c99,0x75046744,0x962c1947,0x96866e2d,0x378cdf4c,0x489ec8df, + 0x3407fa32,0x3a60709b,0x551290d1,0xd37d2159,0xbab92273,0x9623d303, + 0x2432014b,0x08151954 } }, + /* 82 */ + { { 0xfb7b2108,0xf9236d89,0xad75f9aa,0x3ecc83cc,0xb4e1da11,0xf7c72b15, + 0x0315c362,0x552aeaef,0xf272fe3f,0x11e140ed,0x87843ee8,0x99d79bf6, + 0x1d9bb25b,0xce6b54fd,0x5b1bad74,0xb20b0e21,0x5b84c90d,0x54a0214f, + 0xfca6cec9,0x459bbf52,0x9e4df76f,0xe363c48d,0xd64cf17e,0x3045f84e, + 0xf62ada48,0x8402a167,0x6a74ca01,0x2c9e1bf3,0xf691c42d,0xe8cf9d41, + 0xc2c4b874,0x5abf2178 }, + { 0xf3b3bccd,0x4777966b,0xbe3e0caa,0x0047e0f0,0x8c7d5043,0xcb8383b3, + 0x946fd5fc,0xe77e3baf,0xe9ec0e87,0x79baa785,0xc8a18d25,0xd83c557c, + 0x25befcfe,0x9b96e5af,0x98c71b61,0x4f05d15e,0x77e62da1,0x081f991a, + 0xcbaa3821,0x1c6ec781,0xe54d9bfb,0x7522f65d,0x44ed1430,0xf5d05573, + 0x95cafdda,0x3035b31f,0x6378f5bf,0x47e67f43,0x5270b9d9,0x029f7cad, + 0x4d916a48,0x15ad1587 } }, + /* 83 */ + { { 0xaa588ae4,0x00de2ece,0xa371a232,0x552ebc58,0x71230444,0xd00ea934, + 0xe4b1832d,0xafbfa67d,0xb689e843,0x29216341,0x61f4e2e8,0x1f96bbbd, + 0x04c29dc5,0x95420684,0x42317fd1,0xc7fe3827,0x63483162,0xe0a0aec6, + 0x0700184f,0xfc2b94d1,0xfe1fbd85,0x07219973,0xfb074352,0x648b6ab1, + 0xc46e5392,0x23bbdaad,0x00fa56ff,0x0db8dd1f,0x866725f6,0x104815eb, + 0x52e81963,0x3f9c4cca }, + { 0x32ce637e,0xff36b297,0xf5d25cdd,0x81a15f2d,0x8b02ad97,0x1a1d052d, + 0xcfbab3e9,0x2e5f3bbc,0x614eeb75,0x60d2cbd7,0xcd5a793a,0xd4491843, + 0xcdba2144,0x2242cf75,0x88b99766,0xa20705e7,0xec77e132,0x64e12cc0, + 0xb61a9b05,0xb1c14df6,0x74825b5a,0x8fd97f04,0x3da31223,0x95604821, + 0x4d30c70d,0xde486727,0x1c12ee69,0xbcab8f15,0x668d893d,0x5dc638b4, + 0x223f574b,0x6479dad6 } }, + /* 84 */ + { { 0xb05f2b26,0x569044f3,0x80b9f76c,0xb35a294a,0x4290f6ae,0x8839fe28, + 0x026a5877,0x761cfb23,0x2e5ff9c3,0x768926b6,0x0b11c576,0xbae6cd20, + 0x72a03efe,0xdc857756,0xe1bad63a,0x0cae074a,0xd709d99c,0x3fe491a1, + 0x6501d9c1,0x76c5ded6,0xc32aeff7,0x1da6eca1,0xc57683e8,0x50849d55, + 0xdf98d847,0x9e392e9c,0x64d9a564,0xfad7982f,0xa37b98b2,0xf7c3bdb7, + 0xf0860497,0x1fe09f94 }, + { 0x7648cc63,0x49a7eaae,0x67cfa714,0x13ea2511,0x653f4559,0xfc8b923c, + 0x81a16e86,0xd957619b,0x3c864674,0x0c7e804b,0x1616599a,0xfc88134a, + 0x0a652328,0x366ea969,0x4bc9029e,0x41532960,0xae2aad2b,0xef9e1994, + 0x7f10bef5,0x9e2a8c52,0xc67bf860,0x73dcb586,0x844cc25d,0xf61a43fa, + 0x74eb3653,0xd74e7eea,0xdd240f02,0xf3356706,0xfd83bcb4,0xeec7694c, + 0xdb62526a,0x4de95786 } }, + /* 85 */ + { { 0x3deac2f7,0x4867d315,0xb61d9a8e,0xa084778a,0x0ab7b2d5,0xf3b76f96, + 0xcfdf4f79,0x00b30056,0x31ab8f4b,0xd0701e15,0x9c779d01,0x07f948d5, + 0x82675371,0x7c994ebc,0x48bad4c0,0x1104d4ee,0xbfc9d058,0x798ce0b5, + 0x309fa80b,0xc7ca898d,0xacb33eaf,0x0244f225,0x5b2f3175,0xd51e8dfc, + 0xa4d7be34,0x3e49ba6b,0xbda02b43,0x1760f4c7,0x4435275a,0x37e36a7e, + 0xe636980c,0x1c94418b }, + { 0x09dc1414,0x43a21313,0x43c93537,0x060765fc,0xdf5f79ce,0x6ff3207a, + 0x85d4cfca,0x6f18b1fa,0x63e995ab,0xf5c4272e,0xa82b3002,0x121a09e4, + 0x97147f16,0x82b65d1b,0x20a7fe26,0x4993c20c,0xe6716726,0x99c9cb98, + 0xfeb440a0,0x5a02d673,0x251b4bc5,0x3f3fa9e1,0xa05338ea,0x75dbc474, + 0x7b09f6cb,0x3cb4044b,0x80434609,0x6767da18,0x098ceac2,0x97851422, + 0xb55235ba,0x611bfbb2 } }, + /* 86 */ + { { 0xf00ad2a1,0xbdbaa55e,0x14a290d7,0x29efa85e,0xe92b1694,0x3b4a4768, + 0x11ec8130,0x67111bcd,0x88bd27b2,0x0e425702,0xd9a03c06,0xf28cf2a3, + 0xf318884a,0xbb7c8d2d,0xe3aaeb20,0xe2ea1462,0x43b85d77,0x33535804, + 0x554ee9bd,0x81ee4482,0xe6aa198f,0xeb2eee9e,0xc26c5944,0x7a5aa804, + 0x82ab167c,0xa0ef2da5,0x02fe21a5,0x5a2ab476,0x3370298e,0x169cb3b8, + 0x0eb3aa8d,0x86e6c544 }, + { 0x0b793d9b,0xede03321,0x1ddb5ece,0xf79fade1,0x68930b64,0xf73fda92, + 0xfe4fd1b2,0x06aad97d,0x92a4dc88,0x073a5b1d,0xbc976d75,0x8af8cbd8, + 0x63ce26c0,0x60b4abb1,0xdcb1fb06,0x9c8300a9,0xda95b3d3,0x335a594c, + 0xb37eac87,0x1f97d7d4,0x20eefaab,0xa3d2eba2,0xf3e828c8,0x3258c906, + 0x85ab7781,0xc832616f,0x8c28b617,0x72597192,0x3233b82d,0xcd7196bc, + 0x19fa126d,0x83867eb9 } }, + /* 87 */ + { { 0x22474edb,0x774fe73e,0x1a84e1ae,0x2a766394,0x9c6dd6e3,0x270329ad, + 0x14f8bf5d,0x00c4a415,0xd2267b90,0x3ce2ea37,0x11d24fae,0x12753015, + 0x263a1b78,0x7c14d854,0x1ae0b206,0x20c8401b,0x081f49fc,0xf32a011b, + 0x959c6df8,0x1e8123fb,0x800e1d06,0xa328dc7c,0x24259a9a,0x5876a378, + 0xb7ef6c37,0x23ada8b5,0xa93d4c9f,0x023f6b6e,0xffb6389f,0x89f5414d, + 0xe628b39e,0x4b26bba2 }, + { 0x5d318454,0xd30b1cb4,0xd7436cb6,0x123b749f,0x568a7461,0x3110c726, + 0x1c84fd1e,0xc85de123,0x08403d55,0xa5f8d6e6,0x9b1fabf8,0x395b6e13, + 0x3cfedce0,0xfe6d68c3,0x94b91110,0x1d90381f,0x2dcc6eb7,0xf0a8ea81, + 0x7e90ca2b,0x59e80413,0xc8a25c5a,0xbeb5fc07,0x5d84663c,0x009c253a, + 0x910b6a7c,0x00b15073,0x4108f8d5,0x8607da4c,0xcb901e65,0x02c3d9c3, + 0x2c9615c6,0x4d697bc5 } }, + /* 88 */ + { { 0xefa8fb40,0xe0db1ef0,0x5ba3989c,0x29021c5b,0x809d19df,0xa8d6fb15, + 0x4c1219e1,0x6b787b73,0x14ef05e2,0x6417e168,0x8f9796e2,0x449342db, + 0xbf84421b,0x2f878a5e,0xe94a4536,0xe71916d7,0xae119693,0x9818bba3, + 0x5768804e,0xec674be9,0xf8424f8a,0x0a26074c,0x466ce6ab,0xdbc93b9d, + 0xc920078b,0xb3f15a98,0x3870f1a3,0x9d10fd0d,0xe4e785a7,0xa61241d9, + 0xe6c8cd80,0x76ca87a1 }, + { 0xe02e48b7,0x4357fb56,0xcc09e9c6,0xfbd14b13,0x24069cf0,0xdb5f2435, + 0x2c3b01a9,0xf878165c,0xe6956dad,0xe549e7c4,0xbbd60b68,0xf2fe9538, + 0x059dc653,0x952f856b,0xb377fe9b,0xd3f60225,0xbfe908c4,0x6a0c7328, + 0xbc8f5f2d,0xce6aa2d3,0x24425050,0xf7213443,0x3d3b3ce5,0x17e1266a, + 0xc1677512,0x75b5e43f,0x37fb894a,0x15927062,0x2be3e375,0x15260753, + 0x6da3b7be,0x27e7f2c6 } }, + /* 89 */ + { { 0xe6a15883,0x638f65ad,0x66afdb33,0xd4a7e68c,0xd3f12de5,0x6207b6ab, + 0x37b87810,0x1c6ff950,0x64acf6d3,0xc0d44cb2,0xf2be78c2,0x163ac601, + 0x1636980e,0x1c63cc5a,0x95c9349b,0x3e92cfe8,0x41ec7220,0x7738e0d8, + 0x2d5fa961,0x6169d764,0xc3e028e9,0x2aa776c1,0xb16d5409,0x93dc5646, + 0x706df4d9,0xa0b27fb5,0xce9c6b97,0x9e991170,0x53c85f40,0xea8e42be, + 0x83246528,0x02e96437 }, + { 0xae78ea1f,0x91540add,0x7b670e96,0x51a1b74d,0xf7006826,0xf9936441, + 0x7d7520c7,0x8f97d6ea,0x69ce12e1,0x0faa6a02,0x79208342,0x2590aca8, + 0x75614436,0x7a483863,0xf381408f,0x07c6149e,0xd7853406,0x733bf584, + 0x9abbb6f7,0x8761b010,0xf528a09a,0xe4eb249f,0x2e00ae3c,0x08781ed8, + 0x2178effa,0x864c1b25,0x9d513a7e,0xcc1e62a2,0x1919062f,0xedb8b94e, + 0x4f16527d,0x739f53da } }, + /* 90 */ + { { 0x924adc5f,0x7a5f4a88,0xa818f56d,0x95646c16,0x7795f954,0x0ec49129, + 0xd19c5400,0x2b48753d,0x205912b4,0x16fa236b,0xe87a4946,0x6b3d65f3, + 0x045fd066,0xa7174a01,0x12a5e140,0xb6350313,0xa96b8623,0xa79c4b44, + 0x9ab003d5,0x7a339d65,0x3826f31a,0xc72f30c6,0x6f7090cd,0xb4e7390c, + 0x906ebe24,0x59ac6c36,0xbba4505a,0x39a7f06d,0xc58c413a,0x839991e1, + 0xa20e0e84,0x020c23ff }, + { 0xafc74661,0x120e4ada,0x277fc065,0x37bbcf63,0xb6dce799,0x41049cf6, + 0x7b161ba1,0x5b8d6b53,0xa9610fb2,0x22218431,0xdfdde769,0xde9ec9d1, + 0x42d80630,0xd32bfa4d,0x6244df4b,0x3885702a,0x45592dfb,0xcdedd1ed, + 0xfb4e01b8,0x0e1df45b,0x86e215b0,0x8f4bded2,0x6a937e6a,0x80935487, + 0x8130f723,0x415278ba,0x38a821f8,0xc6dc4692,0xfd8b4f8a,0x2207b119, + 0xf9269cef,0x76e7bf53 } }, + /* 91 */ + { { 0x27ebd187,0x5f128428,0xb65aadbb,0x8d3320ab,0x72258695,0xb042765a, + 0x8f0986ab,0xda3f33f9,0xaebff503,0x411807a7,0x825f71a5,0x25c776ca, + 0xff7df24b,0xc0de7bed,0x165f1fb4,0xda8b0f42,0x731f3ae3,0x5f3ff737, + 0x193e0a52,0x4cd1d7e7,0xb6b3ba46,0x8df84aa3,0xaa1f3782,0xba84b897, + 0xe7733ac7,0x6e7960cc,0x50981a21,0x4d46d6ab,0x7cbb80ed,0x1ec12c25, + 0x2b96ef09,0x79e7ad27 }, + { 0x8f30caae,0x3cd970dc,0x0a6ebef4,0x85cabcf1,0xc714616d,0x63c1863e, + 0x519e3a98,0x1c50db0b,0x64cb13d6,0xf39b8963,0x22547b69,0xdf67d81f, + 0xd67db0cc,0x7157abb9,0x889491b7,0xccca25ba,0x7a27e0dc,0xf689207c, + 0x0fd43281,0x34ae8fbe,0x5720ec09,0xa5d91f73,0xcdfd7bed,0xb2f61909, + 0x4a039e32,0x1ec10232,0xdb0d8fdc,0xd3c3d65e,0x4fe5005d,0x32c916c8, + 0x4c0bea94,0x7f8c37ac } }, + /* 92 */ + { { 0x43ac05e5,0x33ec1e54,0xcd8d3825,0xda4a4da4,0x88bf9e2b,0x86d88c0b, + 0xb53811dc,0x34d71dd0,0xa3c3aba4,0x655040d2,0xb61611be,0x2bc40949, + 0x279a4fa0,0x1c2d426e,0x3b065ac3,0x535a5aa2,0xc52ea890,0xdaa8a32f, + 0x9fddad22,0x5a5deca7,0x2ab3b26f,0x911f05fd,0xf37cd81e,0x5dace7db, + 0x90d16b8c,0x0e0e44e7,0xe4f5894e,0x15e68aed,0xfc92a74f,0xafe04999, + 0x970e7c2f,0x1d7703aa }, + { 0x3f0062a9,0xa8a4c81d,0xd96a20ba,0xe31eb2b8,0x864bd101,0x66dd98df, + 0x4413b614,0xba05f592,0xe9a555f8,0x51a67a0d,0x2e4b52d1,0xacc2f097, + 0x7184ab23,0xab5daaec,0x7c7f691b,0xce08b43e,0x76c427f4,0x520e530b, + 0xe423ebdc,0x7d352069,0x34df14ce,0x6b5e39e8,0x446305ac,0x3dcbf295, + 0xfe34cdc1,0x682cb2e1,0x111f5afb,0xd4ac45d1,0x47f296f9,0xc5ef63cd, + 0x93c20871,0x0a2c40ec } }, + /* 93 */ + { { 0xaf5747db,0x09bc384f,0xc06ab86b,0x3bad6086,0x9e7c1547,0xa406882e, + 0x55977abf,0x2d5326d1,0xda81deb0,0x063a9a05,0x524b6111,0x9a86e4a7, + 0x4ab2eb90,0x1402f87a,0xd5c600ba,0x7d0721d4,0xf289fdbf,0x1a2fd9a9, + 0xecde6f07,0xf5dce66d,0xdab9fa73,0x62171277,0x6c474bab,0x6d2dc49f, + 0x76eed033,0xdc017e1f,0x4da825d3,0xb97175c0,0x54b05e43,0x6c297e3d, + 0x56c9c87e,0x2efb4546 }, + { 0x8b21c064,0xa4712b00,0x4a70629e,0xd186fe42,0x9b74f0af,0x6435b340, + 0x7ec9e629,0x6965aa43,0xc4c60d08,0xdda14673,0xbf3057aa,0x0b656670, + 0x3ce86f60,0x7f05e840,0x04401a16,0xc05073a9,0x294e607e,0x16b1e638, + 0x69cf7046,0x20783252,0xe8ce7d3a,0x2941141b,0x7577053d,0xd38ad8d3, + 0xcaa6630d,0xdba68fb3,0xe9504350,0xecbeaff1,0x1d2d760b,0x9f5166d5, + 0x462891e4,0x337532ce } }, + /* 94 */ + { { 0x3a00bb9b,0x3f111853,0x45f66685,0x2d2ffbae,0xd4aee24d,0x9ae11a85, + 0x0341856e,0x18ba1e1b,0x2731349f,0xa9ac8178,0x545715b5,0xc13dfd4a, + 0x5daad2ea,0xa5f7423c,0x535b76a7,0x30a483b9,0xff873e9b,0x92e9ada4, + 0x723a1055,0x15662d84,0x8edac4e0,0xb935497b,0x39d8fa70,0x61b6441a, + 0x40d1589f,0x1541d756,0xf0a05f0a,0x62994237,0x6bb28908,0xfd8b0034, + 0xd4cd32bf,0x192a2b5d }, + { 0x365ced07,0x63576628,0x05de1d1f,0x029f32fb,0xbf40a7aa,0x6d17b9bc, + 0x9bb50a47,0x1b1b2a08,0x795a6278,0x9389abbb,0xb34fc19b,0x52cff60f, + 0x387d8739,0xf3ab9492,0x6920ccd6,0xa8f053e6,0x63a9b4f0,0x3ef2dd4b, + 0x51e82129,0x9ab0ede1,0x0838bfa1,0xafba0c0b,0x9ffc11be,0x2bd5a7ac, + 0x95cc0878,0x058bfd95,0xf8c2f0c6,0x686d48a3,0x1d9b31ba,0xc33abaaf, + 0x3bc0c268,0x632e2289 } }, + /* 95 */ + { { 0x15a1ccca,0x1c851d20,0x7e522bc3,0x4efe290c,0x18eab053,0x0b741d55, + 0xbc85e217,0xae656197,0x01cf8b29,0xae13141e,0x66948478,0x2e2cb593, + 0xc31bd8ae,0xeb57bb0f,0xc264e788,0xdecef5d6,0x9cb96d86,0x6fa856cc, + 0x279183da,0x2db16813,0x383d796a,0xf03f3820,0x1d0c6fed,0x58a456ff, + 0x8a6abd9b,0x25589805,0x83f96f19,0x339f52c5,0xda7e9ea7,0xcf6ded8f, + 0x5d1ccd45,0x68c3d9c1 }, + { 0xe6b392b7,0x67e26265,0x775d9509,0xcec1d9bf,0xd76514f7,0xe16abcd4, + 0x0de72e1c,0xd86f59b2,0x1adfb033,0xa66e43cd,0x05e457cc,0xdb344340, + 0x5681daa2,0xb67a7916,0xf0114731,0xc32e7bab,0xd3b1e961,0x066fe16e, + 0xf63d26e6,0x924e298e,0x541add6d,0x9bea0dd8,0x9982f971,0xef9500df, + 0xc5f076ac,0x5c876e63,0xb23d396b,0x55e12ae5,0x2ec6747a,0x09efbb36, + 0x233286a5,0x8f2055ee } }, + /* 96 */ + { { 0xb82c1af0,0x4a4ab9e3,0xf2cae264,0xfc65e9e7,0x60187d46,0x4feaac0a, + 0xe393b363,0x27d3f335,0x819bacce,0x9c9f7c00,0xb8aa6611,0x3f7418b5, + 0x372aae95,0xffa94557,0x8db38589,0x937d7804,0x6f1fbc1c,0xd10c86df, + 0xa2f0a0ce,0x48aebd89,0x367439eb,0xae5d5fa2,0x3f17d2d8,0x103a6a0b, + 0x411d9894,0xf233f68a,0x218b67a2,0x7fece8b3,0x2319bf06,0x0422540f, + 0x340d322e,0x1292c8c9 }, + { 0x0386463d,0xf5eb5587,0x0371d97f,0xd4bbc2b2,0x0b819c5a,0x1b364571, + 0xcf04ad41,0x0cbb42d6,0x66939ec1,0x5d819c76,0xa01847e7,0x8745ac13, + 0x1c7232e4,0x4f704b02,0xacb05780,0x2c9e58a0,0xb561e295,0x9523b8b3, + 0x79f9ba35,0x3384df00,0x1eaa9628,0x78231fc2,0x8aea2b90,0xa2eac54f, + 0x30d1c263,0x8075ed77,0xfb339000,0xacb44ed5,0xf011293a,0x92546ac2, + 0xeb821764,0x7c78762b } }, + /* 97 */ + { { 0x067902b6,0xb8f7d6fb,0xd1735980,0xb2823a43,0x59741ddd,0x062cfb12, + 0x4033f95c,0x6e391b07,0x68589b8c,0x3831d0a3,0x522290f2,0xe3474d49, + 0x222e1f3a,0x4dab14d6,0x53f08d39,0x8f00fcde,0x707f28f5,0x559917ae, + 0x068e607c,0x166aa0ba,0xd7e1f824,0x602713e7,0x4d6a328f,0x7c255540, + 0x9890cd2a,0x0d2e3264,0xeca0b20a,0xf2207944,0x52f4e09c,0x5c98dc07, + 0xd84de81d,0x69403504 }, + { 0xe5407206,0xf8b7b366,0x0d88fa8c,0x1ecf54cf,0xf7272e6f,0x6fefe548, + 0x81ab4468,0xd6531372,0x4e474408,0x52cb5f0e,0x6490737f,0x9e426b3a, + 0x4980d071,0x2576c19b,0x0f272caf,0x91f34628,0x468f31c9,0x78e60a4f, + 0x90844d89,0x8776a329,0xb951582b,0x8a55700c,0x14b1adbf,0xab1af365, + 0xfbd343ef,0x22ebff92,0xb7d81f34,0x32f9fb01,0xba6b30e1,0xad850e06, + 0xbc5f9546,0x6da9e027 } }, + /* 98 */ + { { 0x5c9490ce,0x21eee4c2,0x0df68381,0xa96ec4a3,0xa4a9368e,0xe6c607e0, + 0x4bc262f3,0xd8b0492a,0x460c34ff,0x0846a210,0x28df33cd,0xf7ff7a64, + 0x21827612,0x10c55044,0x149bcd01,0x9d25fce9,0xcfc613dc,0x725611cd, + 0x97f51ce5,0x159f7e88,0x4e8c08b5,0x3fa3bf31,0x75e7538f,0xea156115, + 0x91c84020,0xd1e0a951,0xcf02ad0a,0x0d2268ba,0x058b8e5f,0xa04c6ac4, + 0xb3515912,0x773b40b9 }, + { 0x3631cfd2,0x00ff2cdc,0x807737bc,0x14c4c2d3,0x338a5270,0xd600616a, + 0xb32cabde,0xd0e3306d,0xa70b17ca,0x336738ea,0x79f353ee,0xf2f4aa8d, + 0x576f3ad3,0x712f6ad9,0x89b2bce0,0xe4279852,0xda92ca30,0x05d8f94d, + 0xd8492dd9,0x9891d475,0x4d15e4bd,0x3e06a5ca,0x254eabbd,0x4725d4eb, + 0xc0ed513c,0x31394ace,0xbbfaae6c,0x7e0f9859,0x833fd137,0xdc125546, + 0xc56c4f75,0x12b46385 } }, + /* 99 */ + { { 0x932951de,0x810dbebd,0x5aa69c94,0x96959d42,0xecb2f08d,0x5fc49c04, + 0x2250b82c,0xac74f0cc,0x3aec4e1d,0x96a439a5,0x90499acd,0xc33cab9a, + 0x54d9b3af,0x2fccde66,0x3863ae8b,0xf4af285c,0x46febf88,0x2373373e, + 0x3c9ab7ed,0x751d672c,0xfe12020c,0xc1c51130,0x52f3e56e,0xad82402f, + 0xa4a64a81,0x3489ab7a,0xd9f163f2,0x0a1fb661,0x0e553317,0x17c69be1, + 0x7d88d417,0x61c1935e }, + { 0x3492ae43,0x2e722d9b,0x0538f05a,0x1ef89d95,0x200aab63,0xae77e588, + 0xeba4b117,0x2872c120,0x3a461cb8,0x5c2432c8,0xcb938f26,0x315b3434, + 0x8c4c7dc0,0x05bf2ac5,0x596b378d,0xd2e501dd,0xcb890c30,0xa8506c9f, + 0x7c361f0c,0x3d0af461,0x5a35cbae,0x21f7b718,0xf3fc0138,0xbd1035f1, + 0x8b248edf,0x74628af5,0x48c9cae0,0x8d6421d0,0x2ca18773,0x75e3da39, + 0x71d3db94,0x27ad0df2 } }, + /* 100 */ + { { 0x305b5aed,0x9e3bda79,0x5998d6a7,0x2c67d4a4,0x0f7eb700,0xc855e1d3, + 0x147d1c44,0xc18a7e9e,0xc89540ed,0x3ea99618,0x7e6bfd20,0xa53be20a, + 0xecc14437,0xc9487e64,0x34ef85c6,0x72979207,0xd5e1ebd5,0xfa0d4e71, + 0x4d48d6b6,0xfda2b1e6,0x66e200d4,0x782a1e05,0x5a5366a1,0x2a3c70da, + 0x1a473738,0xfe3fbd2b,0x7fe020e8,0xd7ef8c06,0xeacfb665,0xec686fde, + 0x6dd1542f,0x5d9b5e27 }, + { 0xcb3e472e,0x3637c5a5,0x30a1405e,0x2153d927,0xb4498558,0x009992e5, + 0xf39a0851,0x18f00ccd,0xb5c6c560,0x26237c11,0x1343540e,0x418ed408, + 0x7e7f3184,0xfef7cbf0,0xbf48576b,0xecd92366,0xbc94c91a,0x1b75be1a, + 0x4a162276,0x8e1778de,0xc5c6bcb8,0xc52e57d3,0x5ab71858,0x5cc382c7, + 0x3f6e39f9,0xe12c2c28,0xd62735fc,0x4c7e0ef2,0x835a5996,0xe071deb1, + 0xcbb8c766,0x24f891cd } }, + /* 101 */ + { { 0x6778c1e2,0x24ef60bf,0x00d5be5c,0xff49c03d,0x2f01a09f,0xec11986e, + 0xae096e58,0x59a728a4,0x7077984c,0xaabbcedb,0x870ca5a5,0xfb473bd2, + 0x4de30e3d,0x8c928c61,0x4f67abca,0x3fae7f9a,0xec21a9cf,0x83c2b2eb, + 0x9cd9b5de,0xafa70d62,0xc60b18df,0xadeaea59,0x4049b54c,0xd5fef7be, + 0x6dd310e3,0xfceebc76,0x8f6321cc,0x7748efe3,0x18ee8af5,0xfe9c32b1, + 0xd42df612,0x863ac3cf }, + { 0xb85a2fe2,0x0a36fca7,0xee429dc6,0xf3e70d08,0x141c3944,0x8c9ba209, + 0x67272a0a,0x306a8106,0xf968bd06,0xe69a1555,0x153c603d,0xb86f7e47, + 0xef56e4fa,0x9706614a,0x98780b4c,0xc0dc36b8,0x3a1d3263,0x43657fe2, + 0x435522c9,0x01f97a86,0xedfef679,0xd91897f6,0x6daa17a0,0xebbe31d4, + 0x85accfbd,0x6f179100,0x8f9fc1de,0xe0da6e32,0xe1e7142c,0x1c9d53db, + 0x8b86725a,0x3e3f1b1e } }, + /* 102 */ + { { 0x7b7fbf05,0xb7ea15c0,0x1f1a3882,0x992f11b6,0xd1dcd1bc,0xc9ddd95a, + 0xad0f7e8b,0x31f5b7fa,0xfca7ab79,0x2936e5eb,0x19a55be6,0x30f417dc, + 0x43cde554,0x1f6f4e43,0x82f044bf,0x971f5e65,0x4288c408,0x73c3b8e4, + 0xb807f575,0x61aac59f,0x818b58f0,0xa64ee2dd,0x97a3b0d3,0x6f7a0a60, + 0x0394b058,0x8b85ecc8,0xbfb3517d,0x9a059474,0xa79c3f06,0x89ad5977, + 0x700a8025,0x81208ed8 }, + { 0x14c4ce37,0x10935099,0xa1aa48a6,0xf34bb843,0x580d58e8,0x86007024, + 0xb375b8ba,0x6db42c49,0xed3bde83,0xac365524,0x649233b6,0x5521e1b4, + 0x64dd946f,0xbc7cc5d5,0xbfb5b6ae,0x9c14b035,0x0146c1a3,0x7f22ba18, + 0x872214f5,0x0b62fbbc,0xb4921764,0x3acfd7f7,0xcb4d6df1,0x5ff10da1, + 0x62600a91,0x660e2620,0x81d9167f,0x7ac7da9d,0xb6e7a199,0x6e8e260c, + 0x80deb3c2,0x44383fb8 } }, + /* 103 */ + { { 0xe44f9af6,0xe107f01d,0x8cb1fa1c,0x36381a4d,0xfb7dd493,0xe65be3ec, + 0x26a8839f,0xd0b8435a,0x3ec789d8,0xee60f915,0x2bcc5e1f,0xe25fea50, + 0x7e44a81c,0x0477c0c5,0x230ba5b8,0x349e9f83,0xde180dd9,0xdd42f32f, + 0x64a3d11c,0x8b039eaf,0xbeb7083a,0x80ef884e,0xf12742cb,0x288e60c4, + 0x720a0262,0x44156cc5,0x7253b77f,0xcd547de6,0xa6013a59,0x9829a6ec, + 0x0d548445,0x8aee708f }, + { 0x32c54409,0x18f22d9c,0x75ebaac4,0xa9ebfa46,0x86284981,0x90e2e928, + 0x6b3a8e0c,0xd0201f6f,0xbd77641e,0xc973016c,0x70170575,0xf926f2f0, + 0xfec0ce01,0x4984048f,0xf319d304,0xbf696211,0xc91a88c4,0x74b5c844, + 0xe0030a82,0x4c40fbce,0xe4f6d521,0xbed67525,0x29d67d1e,0xaf7e47cc, + 0xc21d3536,0xfa307db8,0xbbb29405,0x56b6c46a,0x033e805f,0xf059a7e3, + 0x6096a5a0,0x970f61fe } }, + /* 104 */ + { { 0x1bec8e4a,0x1bc53d23,0x35a6034c,0x8809ac14,0x509e464d,0x4ee081da, + 0x8a488235,0x496ae1fd,0x325864b6,0xa1ae9863,0x74cd069f,0xbaca13e9, + 0xb1d8a6b4,0x3738cc58,0xe76b9da4,0x5fa71f58,0xc7eb16fb,0xc919be88, + 0xad4e429d,0xf5c8f13f,0x2499f9ed,0x4583b671,0xa10d8bd7,0xbce20115, + 0x5790bb7e,0xf66d7605,0x482b78dd,0x9316aede,0x75f855fa,0xe0d8fb2d, + 0x5a7dcca7,0x404b5b94 }, + { 0x517a15c7,0xf9ee682a,0xef880202,0xaae4cfbc,0x5106a354,0xcee2c139, + 0x170febe7,0x5de60192,0x73d0c54b,0x589e39fd,0x8c9092b7,0x195c7135, + 0x0a7bfe5f,0xcb7ed53f,0xf61cc979,0x2bd9242a,0x5395f7d9,0x8d2ef16c, + 0x70b32f09,0x0d4ac1ca,0x52d185c1,0xa587526d,0x942d6195,0x2932b04a, + 0xa500b0ac,0xfe25a979,0x562fd230,0x5fa1f4ae,0x20da253c,0x60f55af2, + 0x83146002,0x7faa11b5 } }, + /* 105 */ + { { 0x6e402149,0xb0ba4f0c,0x963cc119,0x3584cc1d,0xa6527476,0x7740dc1a, + 0xc95715f2,0x3f77ff75,0x3f89fb0e,0xb2f234ad,0xef9be3ff,0x55159032, + 0x04237e82,0xfc9fb21d,0xa153ed93,0xeb2eff38,0x10041d13,0x89d53ae0, + 0x7f1bd828,0xcf2e545b,0x43953ea5,0xdd4a27ce,0xd85e75c8,0x00d2e5d4, + 0x241be1c3,0xeb93ed62,0x0242032d,0x1e53f25f,0xc3a4e701,0xb9957636, + 0xed98febf,0x14b63a52 }, + { 0x71c43336,0x7610b553,0x23a4824b,0x19dfd4a6,0x0286051b,0x7b97a2e0, + 0x8f5f1edb,0x86abbb9c,0x9b67daad,0x67a57d77,0xcd5ffafb,0x8ace506d, + 0x89ac3c63,0x85da9f95,0x75a3d150,0x081cbaa8,0xe9346ed2,0x03353d8f, + 0xa1f9a02d,0xb2ab61f1,0x3a659c71,0xb0cb0937,0x4f5df8a1,0xb7e0e30b, + 0xeb7d5a1d,0x77c4c741,0x728e5cf0,0x8f046c9c,0xf7c171ac,0x32dd0bc7, + 0x836d2655,0x02485873 } }, + /* 106 */ + { { 0x75a4cd8d,0xcd40dd23,0x97bcba78,0x132ca433,0x258d61f5,0x30c5cd84, + 0xda1e8e68,0x0a7ec059,0x1d65d40a,0x07a8f171,0xf4350d76,0x869e655e, + 0x5983ae42,0xb98ce6f0,0x9d8bebd0,0x7b61391d,0xb1ba5d49,0x3a529e25, + 0x1f6b2cf6,0x46f732e9,0x3fa3b629,0xbd66ec6a,0xc3ef0ed2,0x397950ec, + 0x5f08b476,0xee9008cb,0x965a0e2e,0xfd6be425,0x1177bc87,0x78ed513c, + 0xfe512dae,0x6798cedf }, + { 0x1b97c5c6,0x49e3f8fd,0x78c3b33f,0x39fbab3e,0x40f595ba,0x44274412, + 0x5d7d4376,0x174225b9,0x79c44777,0x880b3fcc,0x3296b245,0xdc3aca83, + 0x1734e184,0x55913df7,0x9c934472,0xa4db23d3,0xd1420a11,0xcebb3733, + 0xf3608bdc,0xb9d20cf9,0x30cfe13f,0xa618acf6,0x5f30874c,0x75f06b31, + 0x9f0005a5,0x506efe7f,0x01bfc9db,0x8aaea78c,0xf78e7c41,0xf9179255, + 0x52e96395,0x3ea7aed2 } }, + /* 107 */ + { { 0x5b06ae25,0x98617e04,0xcb5750ef,0xbcac148d,0x604c2ba2,0x91ea2f0e, + 0x76b78975,0x00c19f6b,0x651da181,0x79b9b6d0,0xc945705b,0xf3225beb, + 0x5c005bf1,0x30b435f3,0xbc24d86d,0x440b4482,0xd6373777,0x2b8f0996, + 0x1c44b4dc,0x65fd6c56,0x30906999,0xe9405ee6,0x08aa1ec1,0x19ff0924, + 0x3d2f2895,0xeef3246a,0xbc746797,0x016c3765,0xd0705f7e,0x62d2569f, + 0x05250044,0x6a8ad39c }, + { 0x46be7282,0xe45f020d,0x21380f12,0x9405afed,0xd5da6ad0,0x4cdca5bd, + 0x7f8be61e,0xc2d6f184,0x596b8178,0x20132953,0x7a8df954,0x8d3b1e7b, + 0x39572b4d,0x757c61bb,0x80cc3b56,0xd749b57b,0x37b3ffec,0x9590ff93, + 0x145dc94d,0x39bbb653,0x2335e573,0x70c1c606,0xf763feba,0x9c2e72d7, + 0xcc61b732,0x4768e424,0xaa73f2ca,0x777d2fa6,0xc5cb58cd,0xdee4dbaa, + 0x9cfae1aa,0x1a181179 } }, + /* 108 */ + { { 0x77575ed0,0x6f6ff62f,0x7d1da99b,0x18f14fa9,0x69efd7f6,0x2e72aefb, + 0xddc28633,0xc45ab4cb,0x586c5834,0xb0e20d48,0x39775dd8,0xd397011a, + 0xf4134498,0x0130c808,0xf5115ed8,0x2d408eba,0x0260ded9,0xc506a05c, + 0x19cab911,0x9e5b7362,0xe8693a86,0x4cf508c6,0xcc773617,0x4e71245f, + 0x95d89ca3,0x2f71aa1f,0x607bbc98,0x4bba7c6a,0x212b7fd2,0xf3a515e7, + 0x9230f5a8,0x7d2ddc75 }, + { 0x4ed2cae8,0x3d05816d,0xb9c00377,0x4cf6bc7d,0x646b08d4,0xc23e98e6, + 0x4b9c0180,0xf9ee6c61,0xef9179c1,0xe11c9a13,0x8ed9688a,0xa5b6147e, + 0xd06670a7,0x7afeb648,0x17685275,0xd670333c,0x75f9e8f2,0xa89dd969, + 0x37a68ade,0xbb57228d,0x454cb186,0x21a05d5e,0x063dd550,0x4810158f, + 0x4cb6caf3,0x92dd4f08,0x7854abe7,0x70c4d852,0x6e729d76,0x845969dc, + 0xb1bf40ba,0x5a52f87a } }, + /* 109 */ + { { 0x09ecacbd,0xed019e91,0x7b89bdea,0x6544023d,0x5707371e,0x7cc51f0b, + 0x16c8e217,0x14832b04,0x81259ab5,0xb1aa6682,0x23e361d4,0x6e100f92, + 0xe3a95c2a,0xe593eee9,0x16c10e26,0x699b6bbd,0x9473a13f,0xad487873, + 0xb274987c,0xf1c14dc5,0x2559e2e9,0x57dc0075,0xc3d47ad2,0x8449849d, + 0xdd527793,0x83df278a,0xeefd5b99,0x770e3ec8,0x76bd02a0,0x2ae58446, + 0x3e705ffe,0x17f02764 }, + { 0x29abea1f,0xdda4010d,0x2407ac4c,0x636b9695,0x0433218b,0x96a60129, + 0x163d534a,0xf221fc3b,0xccc20565,0x05ba15be,0x96285577,0x1238e54d, + 0x878804d3,0x1b144257,0xa89a9fe4,0x96fbf304,0x4be642b1,0xc8a7f06c, + 0x6e2b085e,0xdd1a20e8,0xff4a591d,0x8f7f27c2,0xa4a343b8,0xc17b0753, + 0xbb173d4d,0x684b1e88,0x3dc07bbe,0x3accea44,0x4c441d77,0xdb15c88d, + 0x53e5957e,0x0ef0309a } }, + /* 110 */ + { { 0xfa8e5b60,0x4fc25721,0x691c0bb2,0x646938ad,0x0b0a2248,0xe46d4b76, + 0x7de16877,0x863f9ac2,0x2721c630,0x503bb6ef,0x0b67fb02,0xf8c199df, + 0xe07abd39,0x78c1ed72,0xb32f0dda,0xcf9deb7b,0x6c3c89f3,0xaff726f0, + 0x1972225a,0xb7008b2d,0x4f145f5c,0x8f5a6117,0x457c4f37,0x4e0e6f8c, + 0x1c453c64,0x8bbdaa44,0xa6e92c80,0x57be326d,0x5d773561,0xa9bc3fd9, + 0xbb37b72a,0x3d3b6cc6 }, + { 0x9722c880,0x6e6f12cc,0x286b6889,0x3a1b6ae7,0xad2fafec,0xba1cc09b, + 0x43bb8bef,0xad64ad7a,0x97c3f4c3,0xa5af6a00,0xc353a91b,0x2afcb0d9, + 0x69ccbf6b,0xca13fcab,0xf2abc190,0x699a1391,0x23a247e5,0x2dbd5542, + 0x95488d9a,0xe206180f,0x1244cc3c,0xba9e7bff,0x87d3a365,0x29297abe, + 0xfa4ca5e2,0x4054fa38,0x67be1b6c,0xb390623d,0x78f41a44,0x1fa67c57, + 0xc7b544e7,0x2e946e43 } }, + /* 111 */ + { { 0xc60934ae,0x2980fddf,0x164206d1,0x2c3e7eff,0x416ed75a,0xf75e7f96, + 0x5cd0b2dc,0xfac60cf3,0x1faad87b,0xddc4bece,0x9849e5dd,0x753fa87c, + 0x2c1bf1ae,0xc5d516a3,0x14732b4b,0x565dbea8,0xce48696b,0x007ebe3a, + 0xcdb97694,0x40ca74d6,0x65e4e7be,0x3f5cd270,0x3aac4ebc,0x74847c01, + 0x43d6c3a1,0x6762e034,0x467a076a,0x690d8c95,0x1eda677d,0x768d78d6, + 0x0181d8c2,0x0997ce55 }, + { 0x965a0b81,0x9297746c,0xe5e12dfa,0x48b58be6,0x715f437f,0x5573b3c4, + 0xb565c459,0xe425e907,0x1582797c,0x4f43f512,0x8ea5474f,0xe5dafa6f, + 0x13de04ac,0x2aeb8fbe,0xe8a07c83,0xed7f95f0,0x662c09fe,0x3e012a6e, + 0xc742cf17,0xbf96e9b8,0xe28a1c45,0x8ea5759a,0x5cf4e2f3,0x475941b4, + 0xf901a019,0x7dd3c02d,0x70916b2e,0xe7a4deea,0x2fa9b988,0x50b272b5, + 0xd0917fe6,0x96f9f09f } }, + /* 112 */ + { { 0x2c310a96,0x78e8aac4,0xf7a2a734,0x32a98303,0x23962207,0xc46ca83d, + 0xd9541280,0xad131e6e,0x2cabe911,0x5791fc5e,0x841b6c68,0x50cb77eb, + 0x3d3c8878,0xaff93dea,0xf1007bce,0x06541f1d,0x55cdf1fd,0x4ee729c2, + 0x323e3972,0xe0f71317,0xad4d08c1,0xa2de7a41,0xa35e22bf,0xa9912abf, + 0x89b03325,0xa050122b,0x06514d4e,0x8b9e51f4,0x79d3e0ab,0x423c7aad, + 0x40b8fea5,0x71998e26 }, + { 0xceb6ed78,0x40140fcd,0x18534516,0x653cf377,0xe8d60dcc,0x0450b65a, + 0x9dac55f8,0xce6c1a76,0xae05686c,0x8a96a92d,0x12712562,0x2fe44762, + 0xa4f39425,0x747bcb50,0xfc531fc2,0xf0ec6ff2,0x10fe9ff0,0xc97c3447, + 0x9c792cff,0xfb488783,0x026fb019,0x552c5248,0xd804c290,0x4001a29c, + 0x35c8ca73,0x742b5ad8,0x6ee5dfa0,0xc3781f17,0x3dfa4ab1,0xca6b85f0, + 0x0b0d32ac,0x8389941a } }, + /* 113 */ + { { 0xde067dff,0xc0f062a2,0xbcb80162,0xd4f32690,0x0707a2bd,0x98cd990d, + 0xfae4a391,0x5afc63b8,0xb32ad814,0x684f1b7b,0xf199dfb1,0xb0a2dce2, + 0x48f25848,0x2260e17f,0xc2d5e862,0x7393db00,0x338cf171,0x9e88f854, + 0x02acf522,0x00679429,0x6835af3d,0x19157cb8,0xb8a2614c,0x2faa6f92, + 0x134ec46c,0x04ff95f5,0xfb7a8135,0xcf00626e,0xb37a4704,0x454b3d05, + 0x2694ec25,0x1fbfda31 }, + { 0xc8f69c77,0xfdebb657,0xa3df88fa,0x92a8278b,0xc1fb78b4,0x463b5571, + 0x11c71a33,0xd2066a1a,0x089958b0,0x10c88143,0xcf9d67a6,0xb975c7e0, + 0x73037b8f,0xdaa5d208,0x40bf5861,0x5ee5005d,0x7dba69a9,0x300e6ce7, + 0xc962cc74,0x893c3cb3,0x4cf84055,0x0ac98629,0x225c9d70,0x0a7ef63a, + 0xb91e47e8,0xfe184869,0x8c2f84be,0x1b9d7deb,0xc0e278bf,0x67788915, + 0xc426f19e,0x4f9488ca } }, + /* 114 */ + { { 0xdd51b8ce,0x610dfcd4,0x36230e80,0x08579278,0x36599562,0xedc7ff1c, + 0xe2cae877,0x905ead4b,0xe7967608,0xa1c325d9,0xbd38926c,0x3e39eddd, + 0x5f6f0a4e,0xda92c868,0xf47a0fa4,0xe16f800a,0xe5f60aab,0x50b4db5b, + 0x983853d3,0x3665412f,0x9b79789c,0x64b62250,0x4e0e72b2,0xea560058, + 0xe555c2bb,0xabbd4901,0x17292e11,0x378419a7,0xe174218f,0x6e0b5aaa, + 0x8f796b92,0x688e0684 }, + { 0x313b8f64,0xcdfef641,0x942c7462,0xaef11b7b,0x5c0d8abd,0x067cfb77, + 0xaf4041a9,0x608ea5f0,0x6935210f,0x23d5bd82,0x27917a08,0x5ab904fc, + 0x45d22d21,0x85dbb1fe,0x4d36159f,0xc3d5e509,0x1d39b8f2,0xaebb528e, + 0xf44acef0,0xdd5ca828,0x20c57a54,0x24209adf,0x78f95f44,0x5742b433, + 0xa9337d37,0xd11fa7d9,0xc64cfdb7,0xd66a0c09,0x9bb817ec,0x56e55b8f, + 0xe4c41265,0x1723c7e3 } }, + /* 115 */ + { { 0xdc8b43f3,0x9a6486d8,0x26409e68,0xfc3e0e61,0xd9b46003,0x1889c437, + 0x6284ec7b,0x3a850335,0x6a9dbaea,0x5a3665c4,0xe978933c,0x7bf6941d, + 0x69341490,0x1ed5a510,0x8cb8002d,0x664a7b7a,0x60ed0a59,0x603f76e4, + 0x1f4ebf27,0xc3e06ba3,0xf2c38a7f,0x296ced41,0xcf1db08a,0x2ac18f79, + 0xcde7a3b6,0xc919e882,0xdbf68b06,0x15e77d29,0x4e947cb5,0x21978baa, + 0x7630993a,0x84bf542b }, + { 0xe364f21e,0xc1decda9,0x012e557e,0x0d6cf345,0x588f90e1,0xba246848, + 0xe3b104b8,0x9f6dda4b,0xe3aef57a,0x6bf7a346,0xe8327ea9,0x210299fe, + 0xda95e6c7,0xaa99f487,0xd2cdf645,0x24ff813e,0x8bd414b8,0xd1dbb2d2, + 0xcafa1a61,0x065101af,0x9cdebda4,0x7d9f4b9a,0xe41039e4,0xaf41b395, + 0xc50adf42,0xe3e9e6ba,0x341e9e49,0x4f2133ae,0xcb157f23,0x4968c0f3, + 0xda068153,0x383f827b } }, + /* 116 */ + { { 0x6583ff4c,0x2ec46a21,0x4ad709e7,0x4e645a29,0xc04ca12a,0xdc66e9cf, + 0x9160a7e5,0x82f128f4,0x569c762e,0xbfb227b1,0xc2edb8e7,0xf80c7963, + 0x49a0f688,0xa7dafe06,0x2d14b8cc,0xb7e41754,0x86de40be,0x3a0c5c53, + 0x1db79331,0xf0d05286,0xfbfe071b,0xb902ce69,0x210e9903,0x61e46956, + 0xf703ebb8,0xfaef874e,0xdd5f78b6,0xf668947e,0x5af5ea3a,0x6fe86547, + 0x43f94625,0x3b121f15 }, + { 0x659275e9,0x5b26e847,0x6d0fce50,0x47581cfd,0x8aa3f1ef,0x55f5cbfd, + 0xe484e60e,0x1e7be315,0xfe9698e4,0xd8f1a20f,0x7ab04784,0x25d46da9, + 0x834cdb3e,0xa526db75,0x8d08a009,0x1fd408d9,0x5b5ca816,0xfc004b20, + 0x65e4bbe8,0x5b3e3bb3,0x759bb6ef,0xf50cc125,0xc2fac737,0xf05fa817, + 0xd273951a,0x9ee102d2,0xfecb3367,0x2a8e540b,0x2a6a515f,0x673446fb, + 0x37290c83,0x5505e1d1 } }, + /* 117 */ + { { 0xd15e68a6,0x0c3014a1,0x64dd35e5,0x6f9f0b26,0x03ad67f9,0x18c3742d, + 0xd2c14484,0x74818c0e,0x0d41a3cb,0xc5181169,0xc49f3e9e,0x65c8c83f, + 0x2c279386,0x9b260c61,0xced04e9c,0xf6086fae,0xfd7c4758,0xa7b2cceb, + 0x90297fd8,0x4b3c3133,0x09701ac8,0xca8264e8,0x508b3762,0x9f976a87, + 0x983a8dfe,0x5d582714,0xd9d598e9,0x350d2669,0x0f6fd348,0x85cb89cb, + 0xa574317c,0x617d80d4 }, + { 0x70022b67,0x4cef267e,0x3768b94a,0x80536bb5,0xd2784462,0x3153a566, + 0x38243919,0x49054d44,0x5df78c4a,0x8d11e172,0xd5a1e35a,0x9b252a71, + 0x8171e31d,0x07866c80,0x1b38a00e,0x0a8501db,0xce770236,0x2ed932b8, + 0x8edaf7d0,0xa2d77609,0xb93006e9,0x3aee5dab,0xbbfeb036,0xfaffc8c4, + 0x4e21b38b,0x077b9678,0xdca8e069,0x491fc59f,0x0e938471,0x3f624f55, + 0x7cd1780b,0x5156f508 } }, + /* 118 */ + { { 0x0206e8d0,0x58234e22,0x7f15af32,0xf5f6f5d4,0xd638950f,0xafab7289, + 0x7d4495f4,0x66ec4d09,0x68da80a9,0xad890c5d,0x64f8a36b,0xe4aa0920, + 0x0f4d5c5f,0x799e257e,0x24495e31,0x44c677ae,0xa5b8e352,0x720387b3, + 0x75a287b9,0x703790f4,0xc3c1f2f7,0x54895cc5,0x41a7fa41,0xb8680f9b, + 0xb00b008b,0xfcd47458,0xba6473cb,0x149cc838,0xac9be19a,0x78ed5f7a, + 0xb33765ba,0x5254599c }, + { 0xa21b54c4,0x08739679,0xb6497d9d,0x029ece2a,0xc8488640,0xf14f1a92, + 0xe9fa79d9,0xae48dcff,0x46c208db,0x14b911c2,0xdae3f69e,0x5ab0fbf2, + 0xd1edb838,0x180ac87e,0x188586bb,0x146fd718,0x5467cbd0,0x210eb654, + 0x1667cfee,0xaa239408,0xb73d1a60,0xdb125c1a,0x881c1cbe,0xde685300, + 0x37c30232,0xfe34c713,0x6f3c8d18,0xc6c6070e,0xb4af4e83,0x07e365ba, + 0xdcf82b45,0x22f0a7ed } }, + /* 119 */ + { { 0xea7f1b7f,0xe262791f,0xdcff09d4,0x9c3d8c5d,0x39c7dc58,0x86c2a9c3, + 0x4276e8c0,0x4dad4017,0xe9fe1d56,0x0a918f59,0x2aa810c9,0xb8d79670, + 0x4aa5cdc4,0xeb7a8836,0xe7afa72e,0xfc4c23bb,0x4ac86908,0x4dbb5c9e, + 0x6a0c7e6f,0x37e39013,0x49c218d2,0x855d7001,0x94b324a2,0xe475bc67, + 0x6287a071,0xc98a8dc6,0x5fb4323c,0x395a299b,0x0c0389e9,0xe186c3ee, + 0x16734c46,0x79f81e6f }, + { 0x364f3c4e,0x83f2c1f3,0x1367e14b,0x536b2ac5,0x5933e43d,0x44a6dcfc, + 0x10d961fe,0x34e59475,0x7e3f2aae,0x08234ece,0xbdea7f25,0xcb92e00a, + 0xa791a124,0x1efba4f0,0x1192d53a,0xc2086fd2,0xb51c8af6,0xfec0d0fc, + 0xdc0f1b5f,0x48d1b2ca,0x812dbe19,0xb07a388f,0xdedbdd45,0x40873a6a, + 0xd702589a,0xbc2a1268,0x17e27b64,0xbbf6e3a8,0x6d386e85,0x73ee5663, + 0x9de7c000,0x442ecd37 } }, + /* 120 */ + { { 0x8a2f90a6,0xb4cd1ae6,0x6f5ad0cc,0xf277d41d,0x401d4b8e,0x6a3828c4, + 0xd8376631,0xe817a134,0xf5e1124b,0x142b758d,0xfd6b95e4,0x25fbc69d, + 0xd74a9e3e,0xa30c9f5f,0xd89663ce,0x5ac0f163,0x0ce6386d,0x32a9eef7, + 0xd8ed5544,0x7a690ea5,0x9889427a,0x5de23ff0,0xeaaced58,0x75ad36a5, + 0xd3e18465,0x3514a6c1,0x7f093910,0x3d9162c3,0xe33d56e8,0x5c10add9, + 0x06aa691e,0x85176b73 }, + { 0x28a21e38,0xa32110fa,0x5773d538,0x97b6379d,0x2d020dc4,0xd3697bbf, + 0x961833cd,0x59177593,0xe5fa8516,0x6d7045fa,0x786ab5d2,0x3390f29a, + 0xdc4f5b70,0xac0bda30,0xdcc615c6,0xcca0240a,0xc5146d91,0x8e1f1702, + 0xa72cef87,0xceb472d0,0x0b669ba1,0x84840708,0x7e61aa0a,0x79b08f9d, + 0x4669560b,0x388160be,0x948eb71e,0x23935c2d,0x9431590c,0xd7fd83c0, + 0x6e5768b3,0x8ab154bb } }, + /* 121 */ + { { 0x353c4a96,0x28686003,0x905cd835,0x4e5c60e8,0x8f66f8cc,0xbd591364, + 0x9faccf9e,0xb6b80b98,0xe32639e5,0xbc1c1fae,0x278aadeb,0x2f6396d2, + 0x1898202d,0x00a796d0,0x3a474835,0x18ab548f,0xb31b0e3e,0xacd056c3, + 0x0164512d,0x15ba68dd,0x4b03f3bc,0x203836d9,0xd8f206c5,0xd64eca6b, + 0x9f1779b6,0x931a361e,0x52ab34a8,0xd82690fc,0x92922e22,0x342bb8e0, + 0xe00b02a9,0x1bfcdd84 }, + { 0x75a365d9,0x310b9a43,0x08d8fb03,0xd4ade15e,0xd742df83,0x9c9753d7, + 0xde318742,0xcf7309d4,0x3360ace0,0x1228e212,0xf7669643,0x1043d238, + 0xf90f5a53,0xfc2adbed,0x7b5f9397,0x41d64cb7,0xc446d010,0x5200b30a, + 0x231720fe,0xc3c8642d,0xb9aa2075,0xfcc0122d,0x041eae47,0x856e3b12, + 0x68c876a4,0x45864455,0x233606b1,0x1a1c7842,0x227757bf,0x9b766d1f, + 0xf7b9d4f1,0x25b78a3b } }, + /* 122 */ + { { 0x156707ce,0x90835718,0x4314f90a,0x9bdc2398,0x8be57dbd,0x017c885a, + 0xad63a4b8,0xd4bba225,0x15aacffd,0x5ce71b86,0x72954722,0x5f266475, + 0x4f0ad3dd,0x0a80f1f7,0xfc352ed7,0x010538a3,0x4203c6ca,0xf8a64045, + 0x330c73b4,0x2b2c7a88,0x02dcac1b,0xb3433ee6,0xed2b17c7,0x2e0499cf, + 0xbd6329c7,0x9f8681a4,0x36fadc37,0x38979946,0x92b7895b,0xdc5650c8, + 0x65a51cf0,0x70ab9570 }, + { 0x7b585d93,0x46778ec4,0xa633fe4e,0xca6d3610,0x4ea0311a,0x21da154e, + 0xbd64002f,0xaf22190b,0xd91cb7a9,0x9e633ac7,0xee6837d7,0xed13c31f, + 0x1616ee8a,0xda4a07d7,0x3afcd616,0xd78a2732,0xba14d694,0xc06696e5, + 0x4df58420,0x733754d7,0x2778e3c9,0xe85e504e,0x55b5a5c2,0x3055aa0c, + 0x8a3acb5c,0x313df538,0x2a088eda,0x5896acb5,0x84c85dde,0xfc8842a0, + 0x51dde6be,0x5fec9f79 } }, + /* 123 */ + { { 0xfe519f99,0x5ebc2c7c,0xe5410353,0xe396bd80,0x8a3988f3,0xaded9402, + 0xd601bda1,0x1c03b735,0x14ce64ac,0xfd302036,0x01240290,0x5837ebe9, + 0xa554097d,0xcaaea1a3,0xb0b88139,0xdce73d25,0xecb090b9,0x35ed412b, + 0xd63dab3c,0x99029ff7,0x062db071,0x555437d9,0x42a4c11d,0x277d2f56, + 0x24fc9109,0x477fa645,0x2799254d,0x7b12e9b7,0xd84c618c,0x7ad2ae22, + 0xce8ed195,0x0a8d5663 }, + { 0x0a21fde1,0x43ac5163,0x6903d849,0xcfcf5dd6,0x5fdd6281,0x6d2499ee, + 0x77a49a34,0x4dedc6f0,0x2875c06f,0x46bda2c0,0x347b8046,0xd0e0e0f6, + 0x5e67836f,0x1058169b,0xde8a8042,0xc961912a,0xa93b3d32,0xdf3fea0a, + 0x0c576bc5,0x9f138edb,0xd8d37e47,0x7971ad6e,0xcce5e7cb,0xeab85739, + 0x1d202b40,0x88a4b434,0xe3a1fd26,0x5d842557,0xb3a86f91,0x872fabd5, + 0x6aa4629f,0x95b93493 } }, + /* 124 */ + { { 0x99f951de,0x9998a701,0xf058db45,0x8fade596,0xf3d03dd3,0x4d479c1e, + 0x33b141d3,0x6e928d5d,0xacfe8a40,0x9a465800,0xc1cefa3d,0xd108ad2f, + 0xe013726e,0x64b96921,0x8e83bb9f,0xb9b6a6b6,0x1242e544,0x29f1e6dc, + 0x2f65966b,0xd3f8f676,0x5e105b41,0xa34dd096,0x16011e1c,0xd4e9139a, + 0x2515541b,0xeea4dc68,0xc822166d,0x6f8030ac,0x31d16124,0xbdc7ae1d, + 0x621afa7d,0x2e25ef51 }, + { 0xdd8e7357,0x2533cf8f,0xeaceddb8,0x333ba218,0x0784d2ac,0x68e3e31d, + 0xf2804ae2,0x1c927f36,0x77e7ad7e,0x01433d22,0x587f78a0,0x0b401cf0, + 0xaa0027ae,0x9dfcf036,0x1d9a46b5,0xc9e46c8b,0x1f288d32,0xaa6de486, + 0x1b8a043d,0xdd56da2f,0xf2d0bb56,0x346230e5,0x19defb56,0x19f0b6e4, + 0x21d2c874,0x55ec37cd,0xb70e45b3,0x3dbf0397,0xac7ce852,0xf0862a8d, + 0xe141f3d6,0x87979ea7 } }, + /* 125 */ + { { 0x7f1c747f,0x9b7e7b3f,0xc6e63369,0x151a4c1d,0xb372dba0,0x4273ff70, + 0xd3ee54fe,0xca6d2234,0xd33cae0f,0x12fc8e0c,0x5dd6f10c,0x27328538, + 0xf01a9cf9,0xc86f3fbd,0xe36cae91,0x5322677f,0x2fefea44,0x39a70033, + 0xce8af217,0x2c9ca328,0xf6a731f4,0xc0256776,0x66a96813,0xc687b3df, + 0x8db2eda8,0x194aab12,0xeec4febd,0xde30dc5a,0x979241b2,0xc052236a, + 0xc23d4c16,0x3ec98802 }, + { 0x4072f74d,0x0f9e760c,0xab594059,0xe78eb0de,0xc9b009c2,0xdb3dea40, + 0x38b59ae5,0x47e875f0,0x2b4daa06,0xf40eb436,0x090f3788,0x9a6a4f92, + 0xedbfaf8b,0xefebe9af,0x9867e256,0xf87f96a5,0x75ab6aeb,0x1e6fed23, + 0x3fdb13cb,0x17f2782a,0x70fa2621,0x5102c71e,0xfd4c0dbe,0x5d2b06ec, + 0x30347297,0x537cc268,0x2b67e780,0x8dbf5e2b,0xba25da32,0x2f633f3a, + 0xefaec914,0x3e9315e8 } }, + /* 126 */ + { { 0x239a9ea9,0x9255cfa5,0x0be33a62,0x20f3c690,0x9cb642bd,0x759eeb4b, + 0x00bae718,0x3316c546,0xf3410f84,0x874a76d5,0x90f129b6,0x123b502e, + 0x12851f1c,0xadc8f9a8,0x1b62408c,0xf57b764a,0x1a80777b,0x116ec01f, + 0x1f0ddc5c,0x746ecef2,0xe5a6a5a7,0x3c49d47c,0x06e955ba,0x1e15dbe7, + 0xb45d79b0,0x629c0c79,0x778d1087,0x11278308,0x8c6a22d7,0x22585dc7, + 0x0a682791,0x2ed02a0d }, + { 0x4daa2682,0x53043416,0x01359625,0x0e26d32b,0xbd867097,0x449c834a, + 0xee77ae2e,0x11a19d2b,0x3af6c169,0x39bd529a,0x5cd61054,0x36cca5c0, + 0xdc6c0fe1,0x6370a59b,0xb93d5135,0xca420d27,0x554c451a,0xd8730d45, + 0x96cdebf2,0xebd258c9,0xa50f9a05,0x0cb1b990,0x7b0f0151,0x69a8c97a, + 0x11d217e1,0x2cc36d34,0x752f75e8,0xf117688a,0xa09b2a61,0x1db01394, + 0xa9efd7dd,0x14627844 } }, + /* 127 */ + { { 0x232803cf,0x6bca3aed,0x9a96ff34,0xc1e4398b,0x74ab788b,0xcaf6757f, + 0x7e68c04d,0xc3a53e00,0x5cb7cd20,0x5f969c19,0xdc068bca,0xf28b65a6, + 0x1d863032,0xe3ca01d3,0x87808e14,0x9b733b81,0xefe618be,0xb5d704d9, + 0xb01b946d,0x276f3542,0xfbedddbf,0xe057e19e,0x903275ce,0x7d182f2b, + 0x880f7bc6,0x3cdc5f77,0x78476c14,0xd6f03d3f,0xa9ba5072,0x035f5557, + 0xb4029628,0x7acb57b6 }, + { 0x44e6b07c,0xd2413569,0xe1c7345d,0x451c4cc9,0xe273b9fb,0x407444d8, + 0xb88e34fc,0xfe496079,0xf152776d,0x77d184cf,0xc742299c,0x6d1033b9, + 0x77bf2897,0x29a0a684,0xee8f0420,0x59ffdf10,0x44bb56d6,0x4e17146c, + 0xfb9ae855,0x831d06c2,0xd93e7cd5,0xb2cb82db,0x3c96b607,0x83381c46, + 0x7549e2a8,0x06aed251,0x774a21d4,0xef97891c,0x8675fbdd,0xae9807c7, + 0x6363516c,0x6a5a05b9 } }, + /* 128 */ + { { 0x6a8f4f33,0x92e71ea6,0x4dea8f4a,0xf2fc6fc6,0xfee88461,0xd356252c, + 0x08954d08,0x59b0a83e,0x468ab766,0x5bd68c23,0x900f8d04,0x40281357, + 0x52b867ae,0x181c19c0,0x18764c41,0x986a5169,0x13575d24,0xcb01dfae, + 0x593677b7,0x17269ae5,0x46dc9b19,0xf6d17025,0xc40097c8,0x8de68499, + 0x259c407b,0x76df0032,0x17d29d8b,0x4091aad9,0x4a7ab5f6,0xa7f46d21, + 0x70ece48c,0x688054b4 }, + { 0x51a5b86c,0xf0d168aa,0x95777247,0x2437e4d8,0xf1720329,0xae844076, + 0x9647a54e,0x0a7ac87d,0x0405622c,0x1e597a4b,0xf0a79f2f,0xedefe5c6, + 0x4d55156d,0xaf3ef0c2,0xef047cf6,0x917fb04e,0x54b62137,0x3792799f, + 0x314be0b8,0x875ea32f,0x0c466b0c,0xe157c65b,0x7e218978,0xd28c90ce, + 0xcde587af,0xb90fc3ba,0x8b877bed,0xdd32d71c,0xca8e10cd,0x3b432200, + 0xd94f6e53,0x0021f419 } }, + /* 129 */ + { { 0x43519d26,0x2191122c,0x40a51845,0xbdafac1d,0x548bb89f,0xcc6f71e9, + 0x16844bf9,0x9ef3375c,0x178e8d55,0xe7789f79,0x1f8be1c5,0x04f599b6, + 0x2cbbde40,0x8088c99a,0x893206c9,0x8939a260,0xfcd30851,0xa1ae4bff, + 0xe08feafe,0x664cb3fe,0xff14aabc,0x61f38099,0x2a841ef9,0x0d8394cc, + 0x17f01db6,0x75fad8ad,0x6debb773,0x6fc34576,0xa4252512,0x1e716b05, + 0x29e1ed9f,0x79855880 }, + { 0x95106473,0xa2cb3aaa,0x5a61da04,0x95fafa41,0x539563c0,0xfd3c9362, + 0x95312b87,0xbaa48091,0xbf885c76,0x6c7e7582,0x230c78d5,0x70f6dab6, + 0x7747440d,0x8ce3051c,0xffdb6186,0x6dbebd14,0x190e4096,0xb0e041fa, + 0x6ee62e2a,0xba10c466,0x74f333d6,0x93d57e2a,0xfe7b9b66,0x006aadc4, + 0x06d2837d,0xfaf72f6c,0x910741ea,0x318cc5e6,0x65692477,0x9c502609, + 0x1d0fb08d,0x95d823c3 } }, + /* 130 */ + { { 0x140528a5,0x6aeebd86,0x53979bc8,0xf268c2ba,0x4ec144ab,0xb1bc9b8a, + 0x82a7d7ed,0x1efabb0d,0x4e0118d8,0xf12c70d1,0xa1c1558e,0x31607168, + 0xe4b7e73e,0x33e428b7,0x83aec9dd,0x63176637,0xe12ac35c,0x5172ffbe, + 0xbc17b2a4,0x37df0bfb,0x741f812a,0x4212f870,0xe2888f9c,0x3dcecbdb, + 0x756ca55d,0xa9dc15aa,0xb9028e41,0xf31918ec,0x6aeadb03,0x7ede0285, + 0x78654f54,0x0e2708d5 }, + { 0xcde20f88,0x2270cc53,0x5f5b1039,0x9338272c,0x5dcb1dbf,0x5042e19e, + 0xb72d74c1,0x4b3de219,0x2aaaaa55,0x16c49a8b,0xbba86ba6,0x008443e5, + 0x20cf1695,0xee6bcd72,0xa89abd11,0x59ffac6b,0xf115639d,0x2831217b, + 0xf34cba52,0xe4d28af2,0x0727a906,0xf27f03e7,0x69017766,0x6842c79f, + 0x7a81123e,0xcb3469bd,0xa42973b8,0x48c0f346,0x23990dbd,0xfc5784a6, + 0xfb299678,0x0d3dab3b } }, + /* 131 */ + { { 0xce29c3cc,0x8f8376e6,0xf016cbc6,0xcb0507ec,0x5e394ce1,0xdebff996, + 0x73c50d41,0x24fc526f,0x2d16ce3d,0x4edd5a54,0x91c13141,0xbb37bdd9, + 0xe33a8606,0xe3442ef2,0xc0629da8,0x2ae90337,0x592ab331,0x57faec64, + 0xd82b857b,0x1a938997,0xa3373176,0xad6c8cb9,0x9086751f,0x82595de2, + 0x18c17196,0xa81e97fb,0xbf697357,0xe4f48a13,0x5cb89f69,0xa1387c2e, + 0x5874b426,0x530b4eeb }, + { 0xbab7b5ae,0xe9f275a1,0x03a57bf4,0xbb69dc4d,0xa45c505b,0xc974dc4a, + 0x416ac402,0x726369f3,0xaed985dc,0x735e4e78,0xcdd446a1,0x0548d879, + 0x9e16b02a,0x84ceb069,0x789b11a6,0xf73f6fa4,0xb2a4e784,0x6aa0c41f, + 0x93a9b697,0xb1f76902,0xf03a8ab2,0x814cce00,0x844d66c1,0x64cb255b, + 0x30952201,0xb794e7d6,0x3da32271,0xe052d4e4,0x08b6a4d9,0x5278b2e7, + 0x80c6577f,0x90942552 } }, + /* 132 */ + { { 0x0d5b4c2f,0xd269a14d,0x5c8a649c,0x2b8fc59b,0xb0e37d4a,0x95becb3a, + 0x9111037e,0xfda1a768,0x94e35322,0x5810e05a,0xa178fafc,0xa24dcc12, + 0x8e3dce62,0x5c2c63b2,0x9452c444,0x995c3f17,0x42d45161,0x35330ec3, + 0xb4ef8129,0xa025a60a,0x8bae9c13,0x85493252,0xe2e3caf8,0x25d1a606, + 0x3649bf47,0xd44091ab,0x704ec5f1,0xc7d0afbf,0xbd8b3333,0x27bd1d62, + 0xcfe616f5,0x50570111 }, + { 0xf534356b,0xd0084ace,0x4b4b0fbc,0x9df1de05,0xcee04dc1,0x021afe05, + 0x361b78e1,0x64bde688,0xef78d38b,0xa324fcc7,0xeb0a5e4e,0xfeb372ce, + 0x65811996,0xef04fcb3,0x5eb0ab4e,0x7dce5d50,0x238c586e,0x1e29b588, + 0xbcd80037,0xde5e3197,0x4806b9cf,0x8bf5e451,0xd18e67ab,0x4330968b, + 0xf9f63fad,0x26a7d04e,0xb5c18bb4,0xa1c7f123,0x25dce22c,0x485b8482, + 0xd540e79f,0x8ff0b36f } }, + /* 133 */ + { { 0x3ff42cff,0x99f2e2f4,0x1c35317c,0xa3c19f9d,0xaba1b545,0xdb749392, + 0x4afa9a32,0x84232b05,0xd7dcd436,0x0b855d46,0x45cf9915,0x8ac35e20, + 0xf001a218,0xd7cf22c7,0xed408305,0x057d35ae,0x553ccfcd,0x25a4a519, + 0x93e2b939,0x5e565793,0x3422ec27,0xa20332b0,0x3ac53958,0x9b09005e, + 0x79e9b163,0x628051a3,0xfc6618d6,0xb4a0dc09,0x6748e7af,0x9e0e857f, + 0xc577d63e,0x71b28eee }, + { 0x99726bf8,0x4942b0cd,0x1c208f3c,0x1290a3b9,0xb0598eaa,0xfd7290e7, + 0xa25a9128,0xc6a7791f,0xc037d7da,0x2d33db24,0x70e2837b,0xc21efeb0, + 0xe3dae2a0,0xbf70d96e,0x85076027,0x43ed8191,0x4d4ad7e3,0x4aeb0aa8, + 0xe8c5b74c,0xbc75101f,0xad26ebdd,0xdbfb2a6e,0x6b78aa4e,0xba812068, + 0xe1159848,0xc94aa8f2,0x3eba5c4e,0x0d10d9db,0x6318295a,0xce7fec47, + 0x330d925a,0x7294711a } }, + /* 134 */ + { { 0x32bbd495,0xfce45904,0xbe54973f,0x330f4dd1,0x5d9c3f4e,0x006bee1d, + 0x59ba7204,0x40ee6078,0x42c2c768,0xc194fd3f,0xe9fe88be,0xa0e76b12, + 0xec2b0210,0x17cddddb,0x00811ec7,0x689d436b,0x284be9e4,0xa6a6ba37, + 0x007d4114,0xabc395b2,0x0f11e744,0xf8cdf9f3,0xe9396402,0xc5febec8, + 0xeeb46285,0x8a751743,0xc6e0d137,0x99bf8782,0xbeb292e3,0x3965e170, + 0x5801fd5f,0x001c39d8 }, + { 0xda4a0912,0xf4805cb9,0x4410bca4,0xd27cb76a,0xec71d65b,0xef3dcb8e, + 0x4816849a,0x780fbb2b,0xa8b24635,0xef6a7026,0x12c44e68,0x15625c88, + 0x4d7a74a8,0x624c232c,0x4b1631e4,0x81a77037,0xdb917c2e,0x04e4f7f1, + 0x1f61ed95,0x1d0465fd,0xcbde6e3d,0xb1048049,0xd7131fcf,0x637ce0c1, + 0x8ada4715,0x22e4dbc2,0xace99726,0xf7530c5c,0xee287450,0xa0160dcc, + 0xbb91af13,0x9132e670 } }, + /* 135 */ + { { 0x7996099d,0x8057efe2,0xa06e608c,0xb72344db,0xd0958588,0xeb4a8740, + 0x79e5aee9,0xe53daf06,0x908a2fad,0xc9560a9a,0x107e706a,0x7f4be131, + 0x2830246a,0x6d5f3d9b,0x27cca3e6,0xa5f8e8da,0x4c28f292,0xeb51dca6, + 0xf31dfd78,0x4cfa310e,0x2ca073e5,0x92e0c7c2,0xa40da683,0x102f1694, + 0x750d38fc,0x16bb07cc,0xbadae035,0x703e83e2,0xb4d3c9dd,0xea93c066, + 0x79940ed1,0x7d0b03e5 }, + { 0x4dd94c63,0x5fe7ea30,0x738b0b3a,0x57ef01c5,0xa14e6b4b,0x9534a78c, + 0xa5353276,0x07622cde,0x7c22d006,0xaf696a07,0x7d46b209,0x733c1886, + 0x626c2b4a,0x9654ccbb,0xa84f3c4c,0xa098d3a1,0x2d734b74,0x3596f9ed, + 0x5d551c90,0xdfd3021a,0x1ec5123f,0xe2ba7d2f,0xb2c1aa39,0xf9726925, + 0xf8eb2927,0xd2e75d0e,0x19192a6f,0xfaba712e,0x9b83e50e,0xa606b43a, + 0xdab5de60,0x31b1782f } }, + /* 136 */ + { { 0x4034db92,0x878dba45,0x8f34dc4d,0xa3977901,0xdf754c33,0x8d004f2e, + 0xcd563a88,0xeaa5954a,0xbb5ffad1,0xa29d6c89,0xb0d8bdb8,0xa8adf655, + 0x8cdbdb47,0xf7fb842d,0x80d3205b,0xb72e3a03,0x7cac7ca9,0xc335b0b2, + 0xd8a5475d,0xffc60bcb,0xeba4d25f,0x736f7719,0x0c50fca6,0x3d901c38, + 0x80c01900,0x1fdacf7b,0x5681f84d,0x75cf658f,0x5cefbbc1,0x57a7e634, + 0x3e07ed1f,0x6fc0fbe5 }, + { 0xb81b0e5f,0x496d116b,0x2ac853b8,0xd82dd2a5,0x327387f0,0x357e22d4, + 0xba912c59,0x3e332a84,0x49d5dcc1,0x8b71c643,0x438d85d3,0x0c982ee9, + 0xbf7fcd4e,0x90b9553c,0x38fed5e3,0x2cb39bbc,0x5ac42903,0xa2c67c9c, + 0xbf07da55,0xebf21217,0xa0b9e4ee,0x55ac05ad,0x8ee9e0c6,0x10bb12c2, + 0x48bb6e3f,0x5cf3aee5,0x8b046e91,0x4ae7269c,0xaa0e553f,0xcb266012, + 0xa94c8fc8,0x701935a1 } }, + /* 137 */ + { { 0xa4626dea,0xde58d41d,0x15b9039f,0x25ef66ca,0x3164e65b,0x99a810a4, + 0x748cfccf,0x9fe6daad,0x2f142fa9,0x7ab9a6bd,0x5d471796,0xa4cba168, + 0x6bc3a39b,0x12d30b36,0x8bf45076,0x1f46a5dc,0x1421ac0e,0xb868e529, + 0x59bba1c4,0x7a686206,0xda698b90,0x2b4b552e,0xe5453707,0x5039dcd4, + 0x9e90165f,0x42a07a9e,0xd7d45dfc,0xa838fff3,0x3b5ceb30,0x41991e5a, + 0x969ca600,0x6c961ec8 }, + { 0xc4e7eb46,0x703bdc1b,0x596c7b48,0xd6bac557,0x66afd74d,0x4f9917cd, + 0x656ce6f3,0x56355105,0x32497175,0x3d1fb50c,0x63effb2d,0xfda6783e, + 0xeefaa2bd,0xbd79f1f3,0x17af9ef7,0xa4efbe54,0x5a55b7a4,0x6cef6462, + 0x1a713304,0x116f3238,0xb95625a3,0xdb2a2a7f,0x0b027e96,0x6a0aa43a, + 0x4832b3bc,0x458fe5d2,0x5adfaac0,0x523418df,0xc49e7f9a,0xc05a89cb, + 0x69e24b53,0x830883d8 } }, + /* 138 */ + { { 0x02557389,0x959b1c62,0xadefc0bc,0x5fe5ce97,0x8330f383,0x893bbe7f, + 0x16cfb81e,0x27e0c6af,0xd04428fd,0x6f64e65b,0xb79e6182,0x53de9245, + 0x487e11ca,0x08a313c1,0x445bce93,0x65cec3b9,0xd67ed49e,0x33bc0314, + 0x30782352,0x69f36b24,0x93ad31d2,0xd78e5daf,0xc780890c,0xf2682b70, + 0x9e45efe9,0x7015c34f,0xe6cbafea,0x135d4ba4,0x7e3fcc6c,0x43a378a4, + 0x96638f8c,0x2376f97f }, + { 0xae575b99,0x0a6e1ec0,0x81b970dc,0x7e14cb4f,0xd3a73947,0xf00a3824, + 0xfb235a9d,0x0b4b9c81,0x5bf62944,0x8d15115f,0x1e165d7a,0xcfd35b43, + 0xb2ee3e3b,0x5d12fea2,0xf5182e7b,0x629984a6,0xc365d08e,0x4e43e2f3, + 0x30f36e72,0x99327091,0xfd345401,0x698b4a00,0xbaf96dce,0x23c4fd0e, + 0x23675554,0xa60ba0ae,0xb0325784,0x51bdac2d,0x215464a1,0x8ab4190a, + 0x6bf10296,0x8c461661 } }, + /* 139 */ + { { 0x2d1f36a5,0xeffca258,0x894c5f2d,0x0eded2b2,0x43ced84f,0x35a5cdb8, + 0xdb0e3b9b,0x290f8982,0x0719a112,0xcce0eaf0,0x39a362d6,0xd0e657e4, + 0x62697e47,0x5516a55d,0x8e636514,0x269e1f77,0xd50269bc,0x5e3dedcb, + 0x441c57c5,0xecec2300,0xc705578d,0xdb83f31c,0x1e489eab,0x1bdefb73, + 0x395fcdb4,0x20b678cf,0xff9db001,0x908cf91c,0x55f52cc8,0xcbebc6f4, + 0xb4c61162,0x155ea622 }, + { 0x876fa42e,0x94be2f1f,0x7fadeee7,0xab5e8749,0x38c865af,0x692e70f5, + 0xdf8059b0,0x16e99b84,0x8b5a7ac9,0x0ceb606e,0x2d463d2b,0xced23357, + 0x2a9a09a0,0x2d0f2623,0x3861fbdf,0x2529998c,0xc1be310b,0x711888a7, + 0x0d8aade3,0x9b1229c5,0x3b13533d,0xdbcf9b78,0xff029708,0x3ca746f8, + 0xda83ef88,0xa5a013a1,0x4ab28444,0x8e904d18,0xbcbd4aba,0x2fe84b3d, + 0x259058c3,0x8f570f24 } }, + /* 140 */ + { { 0x2ca9c508,0xdeb66c8a,0x69d6b780,0x2dc5bec2,0x88ead600,0x16d61266, + 0x49d72614,0x61841b97,0xce472e6f,0x41e40e6c,0x1fa7a876,0xada24264, + 0xcc3997a0,0x45b9fd33,0x7c15dcf4,0xb25e8fa9,0x12e9629d,0x0124ceb2, + 0x7db3d956,0x3a8c72c6,0x7c1a7844,0x8e2ded2b,0x6dd027ff,0x94ab09c6, + 0x7e7a2bc6,0xf89a057d,0xcf70c763,0xad8bf226,0xc8a26212,0x4cb268e7, + 0xb2c44c1d,0x3d171e87 }, + { 0x8ce49820,0x382ac16e,0xc0c44dc9,0x24ee45e2,0x73e858c4,0x0ec67912, + 0x46327cf9,0x918cb25c,0xc6159c1f,0x43e3876b,0x37545cb3,0xb6b6e0e0, + 0x5d12347e,0x64b839ab,0xa300d541,0x72e09274,0x881c1169,0x26ab28e6, + 0xeb75a843,0x4a580fff,0x359120df,0x0a5802ca,0x3209f4a3,0x7fee82d0, + 0x8e6a9380,0xb518016b,0xc2ee11ca,0xb99c6c70,0xab9d4ec7,0x16105af1, + 0x34cd9004,0x234e98f8 } }, + /* 141 */ + { { 0x14db9cda,0xff435208,0x96adec90,0x99cfdc47,0xaf458b6d,0x843aaa6f, + 0x743eaa31,0x3f1f7415,0x61735d81,0x915e192e,0x0ac595d5,0x3441a22d, + 0xc044bc8d,0x704bbf67,0xbe23a236,0x2f960471,0x15d1d557,0xcc326388, + 0x76b1dd94,0x9410230b,0x0c1c8a67,0xf2e5439f,0x833c910d,0x56b141ac, + 0x865b84df,0x467c999f,0x21f02b7b,0x1b0251fa,0x96216950,0xde5b5260, + 0xce3a1e93,0x6a2130e3 }, + { 0x4b3ca1a7,0xd21b67a0,0x00c0ce80,0xaf42ed53,0x932cf07a,0x22ccd368, + 0x5c25c35a,0x36523a81,0x8dd04d06,0xecdd3958,0xb2f93a3b,0x73da3502, + 0xd5e5b530,0x4c5e0c3c,0x13268777,0xef9f5486,0x1e742292,0xed87fefc, + 0xa24e5ede,0x6d9ac29e,0x33849f1a,0x08abc9f0,0x40f23905,0xb09b2292, + 0x7f934353,0x6791072c,0xe6aeb550,0x102a6381,0x96feb870,0x3ee07409, + 0x9c4d2830,0x34f06faa } }, + /* 142 */ + { { 0x2348f005,0x869dc79f,0xdf4920b1,0x9b5c5d71,0x6dee64a4,0xfd1b57ca, + 0xe82a4fb4,0x21b7f734,0xb9578366,0x637cb834,0x7d287d96,0xc934101b, + 0x0392ecab,0x1590f8ac,0x7f75f4e3,0x280dc373,0x6a61ac62,0x8b36f50f, + 0xa65568da,0x74f58304,0xd930870a,0x80d792a9,0xfc8895cc,0x6d17b192, + 0x4914939f,0x498392fa,0xd41d5b9e,0xaf36027d,0x5caa82b5,0x452d79e2, + 0xf4115d1a,0x764d47b1 }, + { 0xa2ee8b9c,0x5df22303,0x85dfcd48,0x1b9f72d3,0x10813a37,0x6b42b983, + 0x3de741f5,0xe28c523b,0xf303bb5b,0x0857625a,0xac9bf9af,0x926f299a, + 0x0d445b34,0x21beac08,0xd6ba2c0e,0x6a523a02,0x7fce2864,0xe302a1b1, + 0xe300c1ea,0x4516a235,0x7b4a9311,0x4543736a,0xc0cc89f7,0xd3c0b9e8, + 0x40ed88de,0x0481904f,0x3cb7fc70,0x4f269b56,0x321b9738,0x09a1d53a, + 0x230a3810,0x1c0dd9c3 } }, + /* 143 */ + { { 0xc46a7d9a,0xffaa1f67,0xbedf91cc,0x64743334,0x47a42f2e,0x45833a74, + 0x241ffaa9,0x67980051,0x335efe6b,0x70979a84,0xf08b2403,0x5f0613f5, + 0x64f211dc,0x6bb22fcd,0xa0572cfc,0xe1b8b2a3,0x7950a14a,0x19e0eb41, + 0x3eb6cd4c,0xe634bb29,0x470a25ff,0x31a04b25,0xa3d15a0a,0xa41f7ac9, + 0xbf2fede9,0xefed85ec,0x81b94a00,0x1f581f5f,0x9ef4a15c,0xaa3996b0, + 0xb06041bc,0x52d8be39 }, + { 0xfd631a2f,0xbd1536f6,0xb351a8dc,0x91fae7f0,0x9b126212,0xd1a590c7, + 0x2bd0f435,0x52d4875f,0x92b0ea70,0x9aedb6d3,0xb83ab89e,0x0bd0abdc, + 0x89fe192c,0x827a1062,0x102a0bda,0x6566a960,0xce036814,0xda083037, + 0x58639405,0x30bed79f,0xdbca8df9,0x972019b6,0xefdaa3f5,0x89201286, + 0x5236b892,0xb337b996,0x28fc2e73,0x11d3e38e,0x880e8da3,0x70787f41, + 0xdae4a45d,0x6cff6367 } }, + /* 144 */ + { { 0xf89a8bb4,0xbd3d0433,0x93b98f71,0x42144c33,0x03470a2d,0x82b616c8, + 0xe5da089e,0x98fcc757,0x7bf5fda6,0x542354ef,0x9ebd34cc,0x1885c253, + 0xbec5dd0d,0x2e20b285,0x782a1bca,0xe71bbbe1,0x9b854ef0,0x959ded30, + 0x8997fa6a,0x17249979,0xd81f3c45,0x50cf8fa8,0x60c11152,0xa9a3b517, + 0xecf845ea,0xc9b0ef7d,0xb9fed11b,0xc9339e23,0x28256080,0xc93e9c5c, + 0x613ec1e7,0x1d2c8217 }, + { 0x987cfc93,0x7381347d,0xf187f810,0x047603bb,0x1250ca31,0x3fa6bc9d, + 0xbb055bf3,0x480091e0,0x3a3af87c,0xbdf95f1a,0x140540ab,0xe2687770, + 0xd7fe045b,0x998df730,0xb723bc2d,0xb398135f,0x15ebec46,0xac230f8c, + 0x5f5561c0,0xe08e1830,0xda60a47f,0x7c0fbf4c,0xe16d4bfc,0x06e95c24, + 0x74617e92,0x74163495,0x4ae0c20e,0x39719869,0x2131e2b6,0xfe269312, + 0x0a537722,0x25486e36 } }, + /* 145 */ + { { 0x53572806,0x618795ca,0x656968e1,0xb2c89449,0x3fb323ae,0x149c2c97, + 0x409bc7d6,0xfb15de26,0xc79121b3,0xa90cda72,0x204cabbb,0x6d2fa14e, + 0x91604125,0xcbcda6f7,0xb435f947,0x25086261,0xc282eb10,0xdb686c38, + 0xf1a791cb,0x51016d62,0x61a2266c,0x6b1c7ed1,0x271d74a6,0x26780666, + 0x824287a4,0xb5ffeda1,0xbbe4f0f3,0xcbe503ff,0xb9482a74,0xd7f7f0be, + 0x088493f1,0x751b2358 }, + { 0xe9c9be68,0xd597b9d6,0x67d10c6c,0x1794b5c4,0x7762b2f4,0xa88cdc3d, + 0xa1b44e11,0x6d94a63a,0xaaa8eca8,0xfb0bbbb9,0xc963d87f,0xf4b0f2d0, + 0x5dc7075d,0xb753062c,0x49933989,0xfed726ac,0x57f9ccde,0x5da60638, + 0x75f8c766,0x221c392a,0x5dc672ca,0xcd264d95,0xb66ecc8d,0x7004ff22, + 0x18a458ba,0xfb1aa9ae,0x8babd653,0xea9644df,0x2ba0de7c,0xa9378e80, + 0xca2c6c75,0x144cc12d } }, + /* 146 */ + { { 0x2989aa3a,0x593a0a1d,0x59e6e64d,0xd83f2283,0xd32e732e,0xe938b0cb, + 0x3c3cb249,0xf4c464c5,0xf89ea6ac,0x9750a5f8,0x346cfc32,0x467e5bbf, + 0x37b2b809,0xc9bfab9d,0x3b339c6d,0xf8eb7453,0x3b766dee,0x3fe01fbe, + 0xef6aea27,0xb3154254,0x7be61b10,0x555c3df2,0xdd818488,0x70fb6d81, + 0xbbe714f9,0xda1af3a4,0x9d18f693,0x575f2017,0x2465b839,0xdc08fc6b, + 0x6b84a951,0x874ecf33 }, + { 0xbbb3f6be,0x624af83e,0x08bb423d,0xf578fbb9,0xd7873527,0x5623b0ba, + 0xa62e0442,0xc3659bd8,0xfe236f79,0x2903b167,0xe53f26a6,0x55a430c6, + 0x3ad712cf,0x222547ae,0x76eb272b,0xb73890d7,0x3d628df9,0x95b4f70b, + 0x53eae4ac,0x9f0e13b0,0xe7f2174e,0x5b4f5138,0x98dbae17,0x75482cf9, + 0x44518480,0x2b69bbde,0xcafef15c,0x4f279652,0xb6bcaf19,0xa0a3ef2b, + 0xce4c634f,0x31fb8581 } }, + /* 147 */ + { { 0x615cd607,0x398306d1,0xaa32c3a6,0x680c9faa,0x7779131d,0xe87a705b, + 0x36708b00,0x1031013a,0x9445297f,0x814fa0e1,0xa6a79b56,0x70c5583a, + 0x4b16bed4,0x03039cbf,0xaaaaf8d3,0x18a7ca8d,0x5cdb68a5,0xf33159e7, + 0xd23814fa,0xdea0e738,0x8d0f4f9f,0xeb352718,0xdcdff032,0xb0b76609, + 0x3d48338b,0x65ba8ea9,0x55dd507a,0x18044d82,0x4a4a50b4,0x844a223e, + 0x18e19e54,0x98323000 }, + { 0x57f3d5a6,0x28a21027,0x6e8cadcd,0xffce5648,0x02551f3b,0x9590381b, + 0x935ebdf1,0xb26cc64f,0xc083aa6e,0x60611291,0x88e4cf41,0xcd988a66, + 0xdd53b1b5,0x581c3f73,0x77fc621d,0x78c804a9,0xfadca2fa,0x31874330, + 0xc83ccf02,0xf7008da4,0xa79a4707,0xc4122a1d,0x4a915eb5,0x9a8e0d3f, + 0xd0123660,0xa2de157d,0x65ead2a0,0x45ef43b2,0x188db285,0xd0a22ade, + 0x922e0caa,0x8abbe39e } }, + /* 148 */ + { { 0x3a2d2f01,0xb4446905,0x5dc6685c,0xd27c3193,0x1d74a027,0x6a908bbf, + 0x5b50ec1d,0x01da350f,0x3f3c2e26,0x1d3dd45e,0xb836ee92,0xf66e11d0, + 0x474b979c,0x7e03908f,0x98b87834,0x19e7c5b9,0xbd3d1de9,0xa741d3fe, + 0x1ef6059b,0x63c68e8d,0x3674e247,0x9b9ff939,0x3e7e67f6,0x1d7d53e7, + 0xaee9e248,0x698dc326,0xb3bd984c,0x52f23eda,0x6f8fe8a7,0xf95e31b0, + 0xc3d0ba95,0x0f15b4d0 }, + { 0x790a8d85,0x8f2f6635,0xe2595af1,0x51bffbae,0x24b51287,0xd15b7ec6, + 0x3234715d,0x7639b6ab,0x2bc5441d,0x0cdd5299,0xf6d05833,0x54800ea4, + 0xf6d6e360,0x21efd752,0x19290613,0xc0b7ffe5,0xeea898cd,0xb68a5825, + 0x22982266,0xecedba92,0xbbd06bb2,0x678a91b0,0x4bb6b0cb,0xb2436dc0, + 0xcaf8ea98,0xcf7a99e7,0x71aa05bb,0xb92d0e6e,0xf5993eb1,0xbf8d0471, + 0x20385ddb,0x515db378 } }, + /* 149 */ + { { 0x6f5bef22,0xee43eaaa,0x20348712,0x952d2698,0x7a3af6c6,0x1e4c484e, + 0x9a8c9403,0x18d434c6,0x5001899a,0x63e5d741,0xfe8ea40c,0x5238dbbc, + 0x96798721,0xca6cc8d2,0x04acbde8,0x73db6aee,0xb7f993ce,0xbf69328d, + 0xad45e334,0xa3f79bbf,0x7c1f1630,0x8c51ec93,0x9b00a6de,0x4907325f, + 0x12d82bc3,0x49e6acb4,0x0ec59fc9,0x5901b36d,0x9cf34e3b,0xcb09b710, + 0x1abf4c02,0x2de0487e }, + { 0x8dd9d484,0x18b722f3,0x7c77bacc,0x83349393,0x93d92b8a,0x58dbb8f1, + 0x8e3fac25,0x80d78d50,0x745f4a7d,0xf0500981,0x877cc29d,0xd072bfed, + 0xc30a89f8,0x67abf8f2,0x9a0820d7,0x92c567ea,0x8a3a5738,0x425ab12e, + 0xf055521b,0xc162faeb,0xb94ea5e9,0xee1c4f26,0x3d71e546,0x1e414994, + 0x43e8be1d,0x258183b8,0xef9eae0b,0x44917c82,0x73874a30,0x6813a457, + 0xcc42f86e,0x6f6ac071 } }, + /* 150 */ + { { 0x4dd6e3b1,0xd38822ad,0xad620869,0xfc78e1cc,0x2cacde80,0xe7843845, + 0xa8469fe3,0x121cc14a,0xe67e8ef2,0x8e8f3da7,0x4d347448,0xdb83d16e, + 0x798631f4,0x3ba1dd98,0x0a4c4c17,0xdfab5977,0x3edc701f,0x1f0a1306, + 0x6cd8ff28,0x4649d601,0xbcc55bc9,0x2267230b,0x5760412a,0x02a19c60, + 0x328faef6,0xc719d5f1,0xf67eaad9,0x27cb969e,0x719bafb5,0xf342530e, + 0xff5a82cb,0x6e2c24cc }, + { 0xadaf8793,0x6313024b,0x035c948e,0x944bccf1,0x953500bf,0xe9a066b7, + 0x1d116765,0x7991a946,0x9fd93c78,0x95addb2e,0xe92e5495,0x05d2c037, + 0x9f03e5cf,0xcb145b18,0x95aa1f72,0x81ae48ca,0x135a6e4f,0x203f2702, + 0x49b2a7d5,0x2bcef5a2,0x02d7f2a3,0x0687a900,0x6c6745b0,0x2f7d3228, + 0x86507305,0x3da8a875,0x2e8dc58f,0xbe38b884,0xdbf11185,0x6b48bf34, + 0x97c08f91,0x5af7fd0d } }, + /* 151 */ + { { 0xf4a224a5,0x55f9b950,0xcc50273a,0x41904574,0x643f1fd5,0x34f81330, + 0x0e50f783,0x996801bb,0x89581712,0x866d7403,0xa4091d36,0xdb9a405d, + 0x16a46fe7,0xf1e379df,0x83bf9168,0x8d04a93f,0x32b20bca,0xae4c8335, + 0xf72a1c10,0x99d334b1,0xd8195db4,0x8fbc9977,0xfba14b5d,0xcaeb3dff, + 0x76daf476,0x60fef022,0xdb5b72f4,0x4b948dfe,0xb6dfb062,0x5185c925, + 0x9609d4ae,0x27a9c381 }, + { 0xf12a93af,0x73c37346,0x5536634d,0x028b707c,0x498193d1,0x8efa58d5, + 0xef21b69d,0x4f83a5cc,0xa788a0e2,0x05cbb0a3,0x65b13c98,0x01031781, + 0x2b73784c,0xfea20e58,0xe50361f2,0xdf9713a0,0xd0cc22d9,0x31449a0f, + 0x7c5e2e1b,0x183752e7,0xb67044cf,0x6e44d6bd,0x733e177a,0x012dde95, + 0x08ee2c23,0x68b49669,0x1f5f1949,0xd9bb0541,0x6acd886f,0x95182c71, + 0xfbde9244,0x1c690694 } }, + /* 152 */ + { { 0x3a880026,0x5db67d17,0x125d95f2,0x89c4f0a0,0x3f6cb7a4,0x29050551, + 0x5cbbdca5,0x3eb231d1,0x972bcbd3,0xf8cffc99,0xad55a03a,0xcb4ef4d4, + 0x22867c2f,0x944d47ca,0x0ead1aa5,0x96d88548,0xcbc8b045,0x76a57cf8, + 0x005e55a0,0xdfe5844b,0x1d18a097,0x5e9e7e19,0x52923c74,0x957a26e8, + 0x7f5db339,0xd0867b79,0x63bed0c8,0x2553408e,0x689ad23c,0x1596e5d5, + 0xa504c339,0x7b8c13d6 }, + { 0x52fb6901,0x2fc43aad,0x16ca253b,0x1c0313f9,0x515aadc6,0x1475830a, + 0x7f577dc2,0xc93d1926,0xf723c0dd,0x26e52e8e,0x3eb9f6da,0x2f1e0eb8, + 0xf180376d,0x9979de82,0xb0834939,0x43e28ecb,0xa39c38e7,0x9a2d51dc, + 0xa8e3f6b5,0x6e6063a9,0x4b9b3270,0x4cf1da3a,0xd2f8915d,0x6e5348a2, + 0x50507912,0x5e75e3e0,0x20d383fa,0xaeffce57,0x8fd2fb29,0x1d6d53cc, + 0x696f4cd0,0x0e3c3ef6 } }, + /* 153 */ + { { 0x21ee1d83,0x3bc337c1,0x787b7788,0x97e08f6d,0x138fa4ce,0xbf709fcc, + 0xa0348e58,0xbaf77647,0xa55e672d,0x04f8babc,0x7d5ec5dd,0x0ed2919d, + 0x33e99218,0x8ce64bff,0x24b059af,0xac09fc57,0xdc5e32ba,0x506831f9, + 0x465af6a9,0x26a22677,0xc97f1ff8,0x3c5efe66,0xbc6087fd,0x1515e0d6, + 0xaa8edc6b,0xb1a39c5e,0x0e79ed29,0x3dd816bb,0xbc3788b8,0x6cc13769, + 0xc092a51c,0x463098e3 }, + { 0xc8bd0fa7,0x3a6408c7,0xce6bde49,0xd1764311,0x283ef7be,0xe315e108, + 0x99b5d938,0x8213cc77,0x45a49a6b,0xaf7f1581,0xe529e4d1,0xd00fdb0f, + 0xce66c9d6,0x55d38f77,0x1bd4b952,0xb4f7ccc0,0xaf71f986,0x8d975b49, + 0xcd64d00a,0x12b59fcb,0xa5a3bad7,0x1860e504,0x2b5c89f1,0x6d976044, + 0x7a3e231f,0xfed0c659,0x178cba92,0x58114c33,0x6698e11e,0xe2e74c06, + 0xa348b85a,0x7f8fd093 } }, + /* 154 */ + { { 0xc19428af,0xf24592ca,0x3a308665,0x192a1c81,0xe30bbd7f,0x42589812, + 0x836c6bb9,0x10db0723,0x598e4987,0x9c7a41e9,0x6ead6f4b,0x8aff179e, + 0x75862c44,0x70f8f9b9,0x6f21983e,0x6b3b0237,0x98e65152,0x25d83e9b, + 0xd751218a,0x3b2d26a8,0x9d6f1da6,0x9508281a,0xa5a81f74,0x8df78d05, + 0xe4687471,0xd79ee559,0x6787d8cc,0x2060ca57,0xa8476c95,0x427a84ff, + 0xe6435131,0x87b64c51 }, + { 0x4b30d3c4,0x87f46f65,0x23b4ef14,0xcdec4c5c,0x63ca4d68,0xb3b74766, + 0xcf3fb56d,0x1df34269,0x0fd7d46a,0xd4f139c4,0x6a69a8bd,0xa3b7c7c7, + 0xcbadd7d2,0xee56b4c9,0xac942334,0xb28ff342,0x786f1da3,0x0046fdfa, + 0xb700c82e,0xce5d149c,0x50966597,0xca30ef81,0xfcff4bdd,0x44a20609, + 0x44925268,0x0f2f65e7,0xd4021f38,0xe5b6552c,0x042dbbd0,0x77ea9c2a, + 0xd9c062f5,0x8c95267c } }, + /* 155 */ + { { 0x5fc1abb1,0x6655032e,0x12fe4743,0x2215af54,0x29f05ef5,0xfd657560, + 0xdc191be9,0xb0e73325,0xc08639b0,0x7ab3c65e,0x1c3e6673,0x67507f51, + 0xc8615555,0x638befc3,0x42f0c4ad,0x5d0188cf,0xd896186d,0x843a301c, + 0xb2c6741e,0x045603f7,0xfa3cd1d0,0xf7545c0c,0x4a40672e,0xf612affd, + 0x45b9e8dd,0x56197c9f,0x87922d74,0xb453237d,0x4b2d59bf,0xbf132e3a, + 0xb84a6a16,0x8afa1b73 }, + { 0xe793ac70,0x6b3596ea,0xeef6dd10,0x4c94ef8e,0x70422e40,0x926b4fa2, + 0xe9e5d763,0xc8c71dce,0xf512aadf,0x352fcb70,0xa883975f,0x1b7ba138, + 0x058c3b13,0x57991390,0x97740fd1,0x9692092a,0x160b0697,0x19ad945b, + 0x10837ab2,0xbc634388,0xf174bb71,0x76ee11c4,0xab1b80eb,0x6111bfc1, + 0x70ec458a,0xbc82bac8,0x312d3325,0xeee60127,0xb240adc8,0xb4118b1a, + 0x2b5a093c,0x67211191 } }, + /* 156 */ + { { 0xf55cf9bf,0x91e99306,0xa46b96d9,0x9b045308,0x9e7a65df,0xae3c1e1d, + 0xc731bcbb,0x453cb151,0xa4d58a61,0x14be5227,0x97c74cc2,0x39dac922, + 0x822e00d6,0x4d0f7a45,0xc62b03df,0xafeb1d51,0xbaa18b2d,0xbb1dc3a4, + 0xdf2b74f0,0x7f3c7178,0x896b6a33,0xfcd328a6,0x1dce055f,0xe95ed454, + 0x6a4e2b87,0x97fbc76b,0xfa59dce9,0xe5ec67f1,0xcc0367c1,0x052368ac, + 0x54e4a3fe,0x7c863916 }, + { 0xca7388cf,0x55e94b5e,0xc0335d38,0x17cc0a60,0x616f85ba,0x9b69b78b, + 0x10122980,0x705d02ef,0x1cfd0a79,0x565a6e80,0x7d1ee352,0xeb74a96d, + 0x427b9dad,0x5c8832ed,0xe6d5330f,0x96ea8528,0x18d24ee8,0x30d8862b, + 0x9ff939f7,0x9cd38ed5,0x01060252,0x690fc9a2,0x2303b3ff,0xc62d88b8, + 0xdd52b469,0xfc42d7a4,0x8cad2d93,0x06f8dfa2,0x60920438,0x50236090, + 0xfce855ad,0x32582758 } }, + /* 157 */ + { { 0x359e8c60,0xeb20e45f,0x364ca186,0xc71bb8a5,0xdff8e110,0x02b15071, + 0x4c93e578,0x074e91d3,0xb829d0d8,0xc0326e00,0x626a83fa,0x3c192258, + 0xfb29a09e,0x387a64d5,0xe5ac5c82,0xcaaa3d34,0xada2da29,0x8ed685e5, + 0xeb29650e,0x92720267,0x763802f3,0xf7184b19,0xdf6b1aea,0x23f5dd0e, + 0x25e6125d,0xbe1fa347,0x0c872a1a,0xd6287f9d,0xac57c3af,0x49aa93d2, + 0x5bda7656,0x1a4e6a71 }, + { 0x554d1267,0x1a126ede,0x1cd02b48,0x37f94533,0xce31fb1d,0xd70af04c, + 0x097dc012,0xcf410b0b,0x36c7b6c5,0x930e1d17,0xc6891085,0x902fee41, + 0x79fb638f,0x349ba4a7,0xacd6f8df,0xa16c5821,0x2e076ace,0xfb3b83c1, + 0xe501d14d,0x6b8d033b,0x20f2d2da,0x0593d452,0x99df1880,0x3752526d, + 0x9feb33a6,0xca32351c,0x1f6ef456,0xd91343bc,0x35b9dc8a,0xc74857db, + 0x85b4e832,0x856a7c93 } }, + /* 158 */ + { { 0x0d0a5583,0xa007d002,0xeda4658a,0x2f1301dd,0x34d939be,0x91c07964, + 0xa70c0836,0xa0cb6780,0xbe81e540,0xc0b4df95,0x5d4ac8b8,0x6cbbcd34, + 0x54756239,0x57c52ed0,0x1805ceb6,0xcac2dca4,0x79344255,0x915ee6ab, + 0x24c9a2a6,0x366def31,0x8c12c674,0xbd3b962f,0x7dbb7c3b,0xaab64f1b, + 0xe22bb95b,0x3c0e4553,0xc4c63b74,0x2408feba,0x2a4da631,0x3ca77312, + 0xc636da40,0x62889084 }, + { 0x8cb8d208,0xa457fd53,0x543f06d4,0x7a8f8009,0xf2eff2ab,0xb66de154, + 0xf72517e7,0xfddb28eb,0xf9389d2c,0x0149fe66,0xd85b88ce,0x79e8773f, + 0x0ba543f7,0x452e090b,0xb0b03fc0,0xdeb9b5cf,0x6c5ed77b,0x3113448a, + 0x8ffc0372,0x3609f3cf,0x5c1b4c4a,0x2bc9c46d,0x8fa59be9,0xe66f3bf3, + 0xcdb02691,0x1396bf5f,0x009f88f9,0xf1ec59d4,0x2ad9dfe3,0xc2903456, + 0x5ada4d58,0x79d8122c } }, + /* 159 */ + { { 0xaa529507,0x14d4e4ce,0x74655d00,0x056a0814,0x4f0fc474,0xc0d30a38, + 0x3443cb8e,0x8a8203ea,0x97f1728d,0x33c62fb0,0xb520ef52,0x8a38dcfd, + 0x7cac9d3e,0xa0f90d5d,0x873cea50,0x28a7b0bf,0x6c6c41cb,0xd115ae3a, + 0xa13812c1,0xa35171da,0x624d507e,0x25d4bba5,0x7e98f42f,0x91dad289, + 0x96a41371,0xffd6b1e9,0xb69e5b77,0xd46c2125,0x20c4f707,0xc7d2b424, + 0x8142557a,0x2ab3af95 }, + { 0x6a5372a6,0x86ca074c,0x56292ba7,0x728fb83e,0x77741cf5,0x745596dc, + 0x520ef49d,0x70b4cea1,0x61e46472,0x1472fe34,0x3fb8ac5d,0xf4d6bd66, + 0xc10bc071,0x46e52cc9,0x371a3461,0x28794efe,0x276fe877,0xa4850718, + 0x9bef5ab4,0xedad5773,0x3f15c815,0x24c2d9ff,0x8f8395c3,0x188950e5, + 0x80b6a855,0xbae40996,0x8a8803e1,0x4f53e22c,0x039d25ee,0xaf233f61, + 0x250409ca,0x07db2c35 } }, + /* 160 */ + { { 0x037d4703,0xc7f3b8db,0xc5f488b9,0xe83708df,0x8471d402,0x1fba830f, + 0x5a2faae9,0xa55ee8d2,0x5404fc1e,0xc2e5bf10,0xaa2d5651,0x647d5027, + 0x7ebaf5f9,0x37a53c0c,0x95b30abf,0x7adf0bb2,0xd64c93ba,0x5a62e1fe, + 0xe2ef4a78,0x7ffc18c0,0x4d2cd04f,0x139dd9d9,0x5ea0af02,0x253fbab7, + 0x0fef9acf,0x7c8100ea,0xc8615aa7,0x74c5384d,0x9fe52069,0xcb28682d, + 0xcf7dd759,0x08b6ca8f }, + { 0x036c3b5a,0xe04e5bea,0x7f9f2b4b,0x38726102,0x29797c0f,0xa9fca570, + 0x82879ea3,0x1656180b,0x607f0ddf,0x153389bb,0x67b0e087,0x99a1223c, + 0x9d897fc7,0x0d1808ec,0x916edf19,0x9470711a,0x07217118,0xf8f52f2b, + 0xd18888b6,0x5d8b29ff,0x4cc6f900,0xef1e22c5,0xeb24877f,0xc4036165, + 0x35479525,0xfda95233,0x6861468a,0xd622a421,0x74faba08,0x5d043b07, + 0x0d31a7d2,0x2c337b02 } }, + /* 161 */ + { { 0xea22fa65,0x7b2305bc,0xd159f63a,0xbe183ef4,0x3f35923f,0x3473d87d, + 0xc11d7753,0xb27fb306,0x2a054cff,0x702e7e6b,0xaf185619,0x3ce9f97c, + 0x4e7d51c5,0x83550243,0xf356ac5b,0xa63e3d82,0xd7645131,0x867b7caa, + 0xa671fc9d,0xee85e6af,0x2b07cd77,0x3b985ede,0xffda5193,0x07d598b0, + 0xa942dc36,0xb10eca39,0x506218a9,0x17f3dcee,0x06b7d5ca,0x3d94e8d1, + 0xed8831c9,0x509b2634 }, + { 0x48caed54,0xb1b9414e,0xcbf51e97,0x77a78c6c,0x4de9b258,0xa4688c8d, + 0x91ee3d78,0x0024137c,0xe30ee64c,0xa68f9234,0x88190d78,0x573255bc, + 0xba80690b,0x41e8e05f,0xec354f4c,0x50038d84,0xdfa52816,0xb18f02d6, + 0xccb63fda,0xc47f9007,0xe98ae455,0x29d480fb,0x5d0e319d,0x4ac45d22, + 0x026db719,0xd06f3575,0x2c3587b9,0x733b9e20,0x2c317727,0x22483992, + 0x54bb8752,0x1592d5a7 } }, + /* 162 */ + { { 0xcf7453f0,0x5778d9a2,0xed83c1f0,0xaffb899a,0xe0a82ba7,0xae6506d3, + 0xea3d5081,0x32c84e1a,0x810aa38b,0x9ad528c0,0xbd37d041,0xb1fdb020, + 0xd06ce41f,0x78d6cbe1,0x2e74b7f6,0xd287f0f0,0xc43bb022,0xf5cd2575, + 0xf81a71b3,0x6d28f2f3,0xc633e7f4,0xe65bb1f5,0xc4fc580e,0x32e5fc1c, + 0xbb7b07a5,0xcd55539f,0xc3caaf3a,0xb5a94471,0x4cc22d2d,0xb958bdf4, + 0x77a2777c,0x1614bdbd }, + { 0xed0ab04d,0x4c1f0230,0x6e2082ea,0xae347b00,0xc42c5b5f,0x9f10bc63, + 0xde019935,0xb0539e6f,0x65dd0825,0xd89bd4e7,0xbbceda16,0x92260fef, + 0xe62aca32,0x8aaa755c,0x5ec82c5f,0xed762fa9,0x18650768,0x99e64c01, + 0xc92e348c,0x57dd6245,0x31ea6d68,0x0db88a77,0x07b44736,0xef0012ab, + 0x171d70fe,0xb9356b94,0x03f891b0,0xe68b0628,0xb79c20a2,0x3a54a53a, + 0xb00b0728,0x489656c7 } }, + /* 163 */ + { { 0x71353c25,0xe43649ba,0x13f67e24,0x517f27a1,0x1c1eb9e3,0x10bd333a, + 0x78e29bf9,0x94e1c05c,0x4743f15d,0x84fe7d97,0x90da2df0,0x9c874908, + 0x53673be1,0x82403fa7,0x1baea1b1,0x7ebf5db4,0x24180ead,0xcfe0ae35, + 0xc2f50c3f,0x1d15873f,0x70661cd9,0x16851ad6,0xa51e8c2c,0x802968d9, + 0xe0161099,0xe7d1a9cd,0xa8a7ea56,0x2b153c89,0x06e3c498,0x6d41b789, + 0xd6769dcb,0x082bb2e9 }, + { 0xc4d6615f,0x6180ef46,0x01b9829c,0xfc629dc1,0x0fb264ca,0xde222ec0, + 0x10ecc2c4,0xc5457e06,0x1eea2c4d,0x95ce599f,0x8f9c5b2c,0x0433fa72, + 0xcd6310f9,0xee035462,0xce2e2253,0x84c57c3b,0x96d87e44,0x6c8ec31a, + 0xa452c5a7,0x30bfe393,0xa047b235,0xc592b140,0xc018545e,0x7bd8be18, + 0x5c178c46,0x794e0107,0x2e23005b,0x48471946,0x622a54f3,0x2665e237, + 0x901c9042,0x36451a46 } }, + /* 164 */ + { { 0x19893e71,0x17802d18,0x539a2082,0xa1765d8b,0x2302ecfc,0xfc6aea01, + 0x365bf59d,0x8d4cf51b,0x0d232a80,0x87741d72,0x18e80427,0xac343eb3, + 0xe74739ec,0x553ecb2f,0x1a8b07ca,0xaeca79a8,0x56f4ab3a,0x089ff322, + 0x3fa1d1f7,0x5e95d729,0xf62a9a16,0x260569ae,0xaa08ddc2,0x5e776232, + 0x1b7bb54a,0x93fabec3,0x743d56e7,0x48a20956,0xeb0ebeff,0x749cdb12, + 0x69b8fcf1,0x705307a4 }, + { 0xe488310b,0x7a8e4c04,0x5325cd7b,0x12726e32,0x4983efac,0x5d0fd8b0, + 0x02ddb913,0x796e552c,0x77b9685c,0x0eeca3f7,0xb15f24a3,0x9b766e89, + 0x48efc979,0x7c2736d6,0xa8021c6c,0x3d619685,0xa0b2f1ea,0xfe33e278, + 0xb676d6b0,0x95c69879,0x1af4e0be,0xa0747319,0x36c4ee55,0xa2fab5f1, + 0x59e5f3b9,0x6938b8ff,0x39cafe6e,0x1e114da4,0x6a6ad120,0xc9595ec3, + 0x57e62aec,0x80f79bd0 } }, + /* 165 */ + { { 0x60af09b3,0x3cef42a7,0x933dfe14,0x3c016ebd,0xed85eaa8,0x720cf1e0, + 0xceaa3bc9,0xd4f5e99f,0xb7106f97,0x7216b9d2,0xc9668ad2,0x65f34c36, + 0x5b0c651f,0xa8fb82bc,0xf2fda4de,0x20f42f1c,0xd21f659e,0xeb31ab2c, + 0xa13d1618,0xb7a776c7,0x38662be5,0xec441022,0xcad08e0b,0xc825da70, + 0x022c0180,0x99299079,0x2aef9ffd,0x7623bda0,0xf5c58b50,0xde84f4f3, + 0xd824ff19,0x5f5a5da4 }, + { 0x7e8311dc,0x5737257e,0x466cf136,0xdef94f51,0xb05ca21a,0xa73e1645, + 0x02e4ab37,0x38ea9b3c,0x8579165b,0x7760eac9,0xc24b01a4,0xdffdd047, + 0x3fb95584,0x188d4fd1,0x25548bda,0xfaac38b8,0x59e9dcac,0x1a79a6f0, + 0x09a2700f,0x983f720f,0xfb8a7e48,0x8cbba554,0x47a1fad5,0x38a19968, + 0x5abd6b5e,0x11856547,0xf3716ec2,0x75113d31,0x4212907b,0x1391e781, + 0x0dc15889,0x5319c801 } }, + /* 166 */ + { { 0x6b61c3af,0x2320136e,0x07b4bb68,0x1d40f2de,0x380c97f0,0x651dee7f, + 0x6a8c313a,0xa978ba70,0x2011ca10,0x22c587d6,0xab1f445b,0x48bba218, + 0xe50444e6,0x8c5eaf07,0x442fccf9,0x5549f02a,0x3d80493d,0x2564746f, + 0x79c04591,0x42d24f61,0xabdc8887,0x1600fa18,0xded38f8f,0x5cb8600a, + 0x923aeb46,0xa4bf9b90,0x1e1c578a,0xd63fee35,0xebb9ea14,0xf3c9c5ac, + 0xf11a4ff0,0x3d13314d }, + { 0xb4513d1e,0xe5cc662d,0xd55952bd,0xde78a8c5,0xe7f86d0a,0xe8a37a3f, + 0x7a04f0c5,0xca2d12a4,0x2e25d06c,0x4c6696e4,0xb2136071,0x52614698, + 0x89f6e1cb,0xf4d2701b,0x80efd95e,0xaafd6177,0xc5bb6907,0xe6d73ac4, + 0x420db35a,0x49e874ac,0xf2751fa0,0x11631de4,0xa1fa2edd,0xb29f7336, + 0xb7fd794d,0x4c406864,0xe22f92a6,0x73cb21d3,0x2043cc76,0xeae904e6, + 0xb322c6ad,0x67f28a9f } }, + /* 167 */ + { { 0xca148ab5,0x7c17b258,0xb3c60051,0xb9a1976f,0xc8f28df9,0xea260698, + 0xe8d45017,0x87b2cc74,0x0578a422,0x37257329,0x17bec732,0x81d5ee25, + 0x1d48bbc4,0xd7411fcf,0x487f5cfe,0x46217e6b,0x41eb8e1b,0xcb007ac5, + 0xe05a00c8,0xc41c57a6,0xd2f9fa99,0x1f954d2b,0x40941cad,0x370bd5db, + 0x3829509d,0xe487879c,0x5ceca5ee,0x4c137552,0xfd3efb9e,0xe8ef7fa4, + 0x1bd1bdb2,0x5ff09174 }, + { 0x579c6632,0x791912a4,0xb8a20815,0xbb19a44f,0x535639d3,0xf4f97b84, + 0xbc3c9bce,0xe57e2bcb,0xf19e6410,0x122b3f2b,0x1357d9ad,0x1f0189da, + 0x79e5ff66,0x675573bb,0xef2f3c4c,0x444e5c98,0x04d10731,0xd6f61e20, + 0xac75d635,0x0dfa366f,0x2c854f23,0x9fc47c86,0x0ad0850b,0xc04ae43e, + 0x2f720c32,0x5ce94f64,0xa753bc9d,0x67efae65,0xb0373a63,0xc27d30d3, + 0x29721646,0x6681013a } }, + /* 168 */ + { { 0xe84509df,0x1385d913,0xcf339376,0xe978bedd,0x3423a148,0x2df425d3, + 0xee8cb579,0x43fa0ae3,0x31c4553c,0xf015369d,0xdfbf1d48,0x05cf08bb, + 0x9444244a,0xadff4be6,0xa35dda33,0x01635f81,0xe76fab7c,0x085c8949, + 0x16737783,0x4bd7fcde,0xa254f8d2,0xfd8cb52c,0x413ec985,0x62168a66, + 0x7a9026cc,0xf2db9741,0x50e1e1b7,0x3962ee56,0xd3beffde,0xbee0a346, + 0x0bdfab1f,0x3b35b72f }, + { 0x535c3749,0xbff8de9f,0x8add9c48,0x23c1f20f,0xc8f8f663,0xa975b37b, + 0xe8f3ae49,0x2529e475,0x1d5e2628,0xc32f10d5,0x67862f1d,0x5ac0d297, + 0x854cbe36,0x13c79338,0x4b67e462,0x48f004ef,0xe5d10ee1,0xfa37a150, + 0xd28288a0,0x4974778d,0xcfb73f4d,0x96830a66,0x07804952,0x9f444013, + 0x9760b694,0x8233c709,0x25b75c99,0x8340cca5,0xc771f99c,0x3f62e40b, + 0xcd95c685,0x47d0a1eb } }, + /* 169 */ + { { 0x652811f1,0x266f4fff,0x62ef3002,0xeaacaa93,0x50cba0ca,0x6c387a55, + 0x007f5467,0xa350142a,0x202f2673,0xc7fd102a,0x33dc6e65,0x5daee570, + 0x064a63d9,0x60682ec3,0x462b251e,0x46cf0bb0,0x5da936e7,0x0e030ca5, + 0x434265b5,0xc87a60f2,0x69b4e8f5,0x9637b2bb,0x7ad7770a,0x601fb58c, + 0xed3a15a6,0x1f2147f6,0x2995e961,0x05b47d5e,0x83213a16,0xcb0ca9b3, + 0x4995a85c,0x8f4b614a }, + { 0x4b4eb3c1,0x5aa8ec19,0x20323a70,0x8c549ac4,0x4f6cc6aa,0x00d49322, + 0x45f9a5a3,0x0e53b9bb,0x0897abbb,0xe46ef110,0xd7acd7d0,0xfe873e57, + 0x0f7cb588,0x7cfccfe5,0xc85557d1,0x0ea53d65,0x7288f2e2,0xfdd9eb44, + 0xc0eb68a8,0xab2dedfa,0x08603a0c,0x58221470,0x00feb06c,0x69464689, + 0x25e5caac,0x804cf5bf,0x9fc91ae9,0xd8559858,0x73c45eae,0xed9378b1, + 0x524c9801,0x8f942d02 } }, + /* 170 */ + { { 0x8e845808,0x1f1ec302,0xb77abfc5,0xc302bffa,0xf8d97dc7,0x26afd4b9, + 0x3aac594b,0x3d3a83c4,0x674d94dc,0xe3b74bd1,0xcaa5911c,0x4464b737, + 0x871c2cd2,0x62925773,0x3b4440fe,0x419f2485,0xe052ad7d,0xdda6a0f3, + 0x846c86c0,0x645280d6,0xf8324f42,0xa25689fa,0x07cf117a,0xc74ad1e8, + 0x8ddc9db7,0x5626dea0,0x966fc85d,0x52620373,0xf3b1eb53,0xe0ad57c3, + 0x949c1acb,0x38300252 }, + { 0x5e744723,0xa0ef5a40,0x1ae08481,0xdb5bcf75,0xfec1f76f,0xabfad8cc, + 0xfab37fc6,0xfba5d831,0xc8fedb78,0xbe39e248,0xad93f310,0xa5cfad5f, + 0x913d5c24,0x747fdb1e,0x4518b7f5,0x052a47c9,0x7cfb4327,0x9e208d6c, + 0x70e538be,0xb135cb9c,0x5bb17916,0x36352759,0x5b3106c7,0xa2c07880, + 0xc209bb06,0xd2d42a06,0xd3c504ad,0xb525b471,0x822ce034,0xc9f4b368, + 0xeb4185a5,0x15f18796 } }, + /* 171 */ + { { 0x0aee4684,0x094dea06,0x7cdbdbc8,0x42b21f06,0xb1931319,0xa439e149, + 0x81a7dba6,0xea4bdd41,0x3c2ae80f,0xc6213706,0x12823dc2,0xb58b0967, + 0x832611b1,0x7443d515,0x13c20384,0x2e16f831,0x2bd992d2,0x0ce204d6, + 0xf419388b,0x499dbcd6,0x1d3778c7,0x492ded1d,0xc5ddae73,0x9d5bd74f, + 0x994b6259,0xd4813d52,0x0e86ca68,0x191d9cf6,0xf3e9c2ac,0x562179ea, + 0x9fee1238,0x6146f1f3 }, + { 0x078e2aa6,0xbd06d33e,0x9dee9265,0x693af7f7,0xdaa40e84,0xd56e0f81, + 0x9b9a407e,0x05fbbb88,0xede99519,0xdcf44adc,0x092dba39,0x7f71f8d3, + 0x4231774b,0x675b5da5,0xa5f605eb,0x7456a251,0x87a39a9e,0x9031d4af, + 0x05b474bd,0xdb430006,0xb665aa91,0xbda5dbf2,0x6631eeb4,0x5d1a3df5, + 0x62377c58,0x028149ef,0x685d0bff,0x2e1af4e9,0x82a465de,0xe0ea0875, + 0x06bd0050,0x95543f9e } }, + /* 172 */ + { { 0x85d7c6ef,0xf7cbc6f4,0x63b1bc24,0xcad8084d,0xbf8cba62,0xdf90ce88, + 0xb455c192,0x98e4b686,0x774fc6ed,0x6146b8d5,0x7ae20077,0x70e2389e, + 0x61c22529,0x5241c479,0x3884e5f5,0x7d221510,0x17e28273,0xd6d20ce2, + 0x4f2674f8,0xe3119f51,0x70c011db,0x85459055,0xfcfb760e,0xdfab75d9, + 0x9e8c2a19,0x9546362a,0x4a7d4b27,0x4b6d3f8a,0xee5d698c,0xa5c87104, + 0x2ba296ff,0x6db43478 }, + { 0x5c3f0d95,0x06486493,0x4e748895,0x8917db82,0x6b2f3e44,0xf73fdf62, + 0x2b7f574b,0xc60edc54,0xaf732723,0xbe1c09a2,0x7cad114c,0x7d34669d, + 0x321aaff9,0x9646600a,0xed0cd61c,0xb94e2bba,0xdec4750e,0x866e1a41, + 0xb1a89f58,0xa1be990d,0xf2759693,0xc39e4d6c,0xc0e0dddf,0x11cfb780, + 0xd99c8a41,0xf0afcd7f,0x6e1c3050,0xcebffadb,0x96d2c6e4,0x4f3981b0, + 0x2ae27a94,0x07a791e7 } }, + /* 173 */ + { { 0x1e9f0300,0xe70e9047,0xbccdf904,0xe0253ad9,0xff053078,0x51c0289d, + 0xae893462,0xf1ef092e,0xa4846845,0x2c90a91a,0xf1dad4b4,0x1946eda0, + 0x33df67b2,0xf07650f3,0x0b15a014,0xc6e988db,0xb542f0f9,0x72e0c66e, + 0xe0c0378f,0x5d4b6311,0xae86950d,0x548badaa,0xb35f1c8f,0x6801638d, + 0x944d1ad4,0x129e3216,0x40471d32,0x9951bac8,0x85e94dde,0x03cc29f3, + 0x4543ecac,0x6d6acc2e }, + { 0x57b2d299,0xeb999e95,0xe3d721cd,0x3a2bcd9b,0xbb4cb444,0x2e60384f, + 0xdc060faa,0xae177709,0x8c987cde,0x74f0e6d3,0x1076fbed,0x9a237cf8, + 0x7983fbff,0x69af1513,0x323f9584,0x6c3f7a1d,0x6db64398,0x3e21cacf, + 0x96703d92,0x7cd8134f,0xb8393f76,0x0755898f,0x2e825222,0x1b5b28bc, + 0x7924aa7c,0xb78799c1,0x81427a8a,0x1db378f2,0xff289492,0xd5a451b1, + 0x3d3c46ee,0x79d18212 } }, + /* 174 */ + { { 0x109d5589,0x1a3edff9,0x029b4499,0xded52eb4,0xb4b54adf,0x13eb9d30, + 0xa27bff67,0x4f9214c1,0x67f0f460,0x4c817ee7,0xc3a50e28,0xbadf8d83, + 0x94026237,0xc5dc03c9,0x966647c1,0x5f29581b,0x8a0687f3,0x10b6a089, + 0x31634517,0xae787cec,0x62e75188,0x2001dba5,0x45e2c3fb,0x55d4e1a7, + 0xb67d3395,0xbfcacdeb,0xbc6842ee,0xa1a0af9c,0x3e88580b,0x50590a2b, + 0xa784cdc8,0x73104491 }, + { 0x2648d676,0x44ca2cdf,0x4f1b12b1,0x9a85eca5,0x2980e1eb,0x1b9dac94, + 0x1ac8aa89,0xf30d3709,0xc719e195,0x73072ab7,0x2f703797,0xba518c82, + 0xac0067f6,0xac090e14,0x8dcd2927,0x0e6cfc70,0x21e7da63,0x4f5889e2, + 0x8371c7c6,0xb4aaa40b,0x8f7878c9,0x1f9dabe2,0xd84caf3f,0xf78aed6b, + 0x9e0e1d92,0x3c39dd07,0x122424dc,0x680be5fb,0x0bdc0099,0xf41b214d, + 0x5180c54f,0x6a8f8fc9 } }, + /* 175 */ + { { 0x53235132,0x62a1ed63,0x59dba88b,0x1db233f1,0x291efdd8,0x85625452, + 0xb25111ae,0xc7505297,0x1d701bd8,0xb5921af9,0x9774f45d,0xb4d05d72, + 0xf18e73ff,0x6e3d4c5e,0x899b3038,0x897d985f,0xc89b1558,0x8a9c30fb, + 0x4d13181c,0x3c92d1a3,0x2223320e,0x292e86ba,0x01ceed02,0xcf2454c2, + 0x583f309f,0x27a45f74,0xad0fd1a3,0x75a6102c,0xcb9c7538,0xdb4f45d2, + 0xdb283fd7,0x4752d8c1 }, + { 0xd5dff4d5,0x514d6cea,0x45a827f4,0x74cd5fdb,0x4fc7135e,0x1070a60c, + 0x1be5778e,0xdec0bb78,0x58dc6b08,0x271e12cd,0x54bc2496,0xb765089b, + 0x619098ac,0x6ddf2c63,0x67528832,0xfd6ebac6,0xc2508af1,0xeaa2d025, + 0x4dcfc1f0,0x13c2cda8,0x45510be0,0x1c7836a8,0x1a886801,0x3904688d, + 0xafaf2545,0x643132aa,0x2830a88d,0x49685577,0x8744b470,0x569491ca, + 0x75fb8552,0x3a6518f3 } }, + /* 176 */ + { { 0x224042a0,0xaaa8ed50,0x2452f1e6,0x6cb4e3b0,0x768211d8,0xedca5f4c, + 0xef4d5d3f,0x4e0fe3f9,0x522d46e5,0x33a8e2a4,0xf1446775,0x5998e21f, + 0xf592d01b,0x1496c50e,0x83a67739,0x69104c2f,0x472bbf00,0x28670bcb, + 0x503177bd,0x8ea883b2,0x7d2712a2,0xc5d8bc05,0xb439c994,0x41ef9317, + 0xdcda1aff,0x9801d3a8,0x7038f6fb,0xd686eeb5,0xfbfbf820,0xe80c5cd0, + 0xedc25817,0x540ac363 }, + { 0xfe7f43df,0xa71969a9,0x2c1b9e4c,0xe6653808,0x859c2917,0xad9677d8, + 0x96aa4404,0xbaca9545,0xff1297da,0x0e9d855f,0x22aea7de,0x1f61897b, + 0x36f13f8e,0x96edccfd,0x16e200df,0x627d3070,0xc98988a4,0x729f0736, + 0x97f231d2,0x95e25e60,0xf6048752,0xaf7f221b,0x4019b299,0xd6682609, + 0x26b4b1d9,0x1d99de09,0x1acdd7a3,0xec47cf66,0x6ebe15e9,0x4de9f2b3, + 0xfa16974f,0x17db32ec } }, + /* 177 */ + { { 0x6cf40599,0x75ef6919,0x00c020ea,0x7ea10dfb,0xfcaaf679,0x3da5ae7b, + 0x88ddd678,0x0d663ca3,0x255bcfcd,0x5a21f8fe,0xe344bc7e,0xe9c3f538, + 0x548e0632,0x35f62b1d,0x43c6e64d,0x654f2425,0x26993627,0xc755a7a6, + 0xb0f41324,0xa3b7c5f7,0x3a2180f3,0x05697f79,0x1e81675b,0x6cf85fb1, + 0xe53428f5,0x6d3cdb35,0x52d28b02,0xe3aa1591,0xf7a3fb78,0xa8470255, + 0xa194445d,0x460bd01b }, + { 0xc24d8077,0xbc34dc23,0x4c720d2c,0x82f4b580,0x6f5d1ffe,0xa29da911, + 0x92783ce2,0x578af520,0xb5904af3,0xe29f51ab,0xf7aa1190,0x46c570d7, + 0x571bddf0,0x4a522fba,0xae89bb51,0xbf4e2a06,0x59f3444d,0x799b35cc, + 0x26cc2557,0xc3028367,0xafcec177,0x94a4e985,0x7c36cbd0,0xadaf7dcb, + 0x75d39077,0xed31b787,0x2d3e24bc,0x52d6904f,0x1f95421b,0xc5ca2669, + 0x1734878d,0x7d342c3c } }, + /* 178 */ + { { 0x11fd127f,0xe5cf2c0a,0x119e4c5e,0x66d36bb8,0x6ef56ac3,0x621ab252, + 0xe5430675,0x30cfeaee,0xac3e9619,0x2ede27d2,0xf8fce671,0x6413513a, + 0x075f4c3d,0x6159c61b,0x59069d98,0xd447efe9,0xea76aea9,0xaf8d6f68, + 0x0f5bd164,0xac5dc61b,0x1e88bb98,0xdbab446e,0x1ba92320,0x618b8b16, + 0x78989865,0xa0eafb3c,0xc08b7e82,0x0c7abcc2,0x20d160bb,0x10f09b6e, + 0x8e4c63a7,0x5be0afa6 }, + { 0x1bbbf49c,0x82ab6d38,0x8c0703fe,0x3e09ce49,0xe10f4263,0xeca58b5d, + 0xda5a4532,0xd9cc6581,0xf618f7b7,0x07e18876,0x250f7fe7,0x0419a5e3, + 0xde6b86be,0xbb1a9e90,0x37359169,0x584a7deb,0x5149db2c,0x38eb3489, + 0xb0ebabb8,0x14546a33,0xc2f88a92,0x0067f0b0,0x0a2db019,0xbde0dfe7, + 0xc63e6f3e,0xba51b06c,0xe9206fad,0xa19127b9,0xfe80dc0a,0xe4eb5e87, + 0xd4de30ae,0x1e6fccf5 } }, + /* 179 */ + { { 0xaa8ac924,0xb57dff66,0xc298b3e8,0x06e9ad31,0x65fb080c,0xd140e329, + 0x1d95c93f,0x7dab211d,0x8a180caa,0x6d68d842,0xa20ded69,0x1a929408, + 0x38df461f,0xa8151753,0x60eae932,0xff5604ae,0x7dae4c0b,0x901b9e49, + 0xde262e89,0x4573a97f,0xf1084983,0xed69d9a4,0x64724f1d,0x8ffa022f, + 0xea85a15f,0xd5f1c2e4,0x01453794,0x4c626ce9,0xbf0907dd,0x80440cd6, + 0x5ddaa837,0x4522d461 }, + { 0xebfbe7c5,0x8895f079,0x84ef3446,0x30ea1ded,0xd4a1ab96,0x716a9eb6, + 0x50a30c68,0x1a4a5d22,0x0043bbaa,0x5a16631c,0x5010e5f5,0xbd107502, + 0x3d8c0556,0xbffe3e9d,0x07772419,0x31b30b18,0x84b82297,0x90ff7ef0, + 0xf21a18c3,0x00c37d75,0x565bb8f8,0x18d0a635,0x45e3bceb,0xbac1da2a, + 0x23f0b08d,0x1c38e90c,0x5fbc5ac5,0xf1ba1aa2,0xdda71fc6,0x09d5256b, + 0x6d7e40ba,0x346501a9 } }, + /* 180 */ + { { 0xcc2b0f1d,0x86be448c,0xac4c3703,0xe3eb45c9,0x9fc96bbf,0x5387f65d, + 0x5ae27fda,0xcef3c4e9,0x1bc18089,0xa008f776,0x22ca18a1,0xf374a084, + 0x53b73371,0xee882842,0x7cc09354,0xcb6fc6d8,0x61496d6b,0x8489ec1b, + 0x49e325c4,0xa92c29b9,0x7bdec166,0x15c6ca52,0xdcea2813,0x95444eee, + 0x3a21154f,0x34683eb3,0xd39061cf,0x8fb26f98,0x06c940bb,0xc3b08aa8, + 0xe554c96d,0x7c1d42cf }, + { 0xdc110aa7,0x766e703f,0xf362e378,0xab7b79d7,0x5aadca3c,0xd259c75d, + 0x60be3373,0x2a6eca79,0x06c4e8ff,0xf4744a4b,0xf3b705bf,0xb2842cce, + 0xae304b53,0x1a3af5aa,0x1b2d31b8,0x7bbfa201,0x4bee88d9,0xc4ba6eba, + 0x565cb839,0x2d3565ce,0xdaf7ece8,0x24808696,0xe6959745,0x2c7ccce7, + 0xe94f9837,0xefd6eb3c,0x3811a326,0x0a33b4cf,0xfffa93a6,0x14203f43, + 0x73c31d90,0x031e9828 } }, + /* 181 */ + { { 0x765a17ff,0x4fefecfc,0xd1290a65,0xa09f3888,0x938da038,0xbf265c46, + 0xa169ad46,0x4bb6145d,0x23a62fe8,0x33cf8214,0xabc860a5,0x562df571, + 0x815c38c4,0xbf2a90fa,0x17eda875,0x45ba1d6e,0x946fa5e1,0x799d881a, + 0xb90f5a3b,0x6c1be784,0xb10ff52a,0x0910a37c,0xa4f4fd36,0xc38c1fe4, + 0x8e2d3ba0,0xc3180fc5,0xb17a6187,0x3e2ff050,0x943a35c2,0x3a00059b, + 0xa28cc51c,0x494d3645 }, + { 0x4ba021f8,0x398426b6,0x796deb6c,0xd14c9083,0x7e36c762,0x6d2e5395, + 0x751cf216,0x8f556eca,0x19b24a19,0xdaca1e00,0x4b20c2ae,0x47887da4, + 0xff41a733,0x93ed4ccd,0x5c7c0cd7,0x8d717c44,0x91bf7009,0xcc48634a, + 0x3b59bbaf,0xa1f146f9,0xe5624f15,0xdd38bb39,0x303f8443,0x96d41aad, + 0x4bf104fc,0x6b670f03,0x29706582,0x0503f9ed,0xb34200f5,0x768e1f47, + 0xbbd4c6f3,0x3cfdcc5e } }, + /* 182 */ + { { 0xb523e13d,0x536c2a86,0x2920d0a0,0x1014a458,0xe7571296,0x3d52b478, + 0x7eb51bea,0x05746066,0x87b0e919,0x709f7861,0x686888e8,0x028aed88, + 0xd94afcd4,0x79a809d7,0xe2129af3,0x50c6032f,0x983c4082,0x75e4be72, + 0x7ab3be8e,0x98331bbb,0xb618c728,0xd31a032c,0x3f59c4a4,0x36dd85a1, + 0xed4f61e2,0xdbece345,0x1e571715,0xba7aaccd,0x64a1ebd7,0x138c58da, + 0x3d1aeea1,0x89296d0f }, + { 0xcca82c97,0xb165288f,0x1427e8dc,0x26c6c12d,0x4c3edda9,0x66a94f07, + 0xeaa01ebe,0x94600e1e,0x30f5e86d,0x14abce7c,0xcb456a31,0x741d7020, + 0x279f42c2,0xab05aa13,0xd4238468,0x70b60faf,0x318d39e6,0xa18efec1, + 0x8920b318,0xeb07f1ac,0xd8399e03,0x01e3cba8,0x3c81a301,0x65f8932e, + 0xccc667d8,0xae8bca7d,0xa268607c,0xcee1ae79,0xcac0a12c,0x3182e64c, + 0x2b1a4c54,0x9233a2f7 } }, + /* 183 */ + { { 0x0acbee17,0x717e8df6,0x5c24fcdc,0x0f0959c2,0xe54ffcb0,0x46f09887, + 0xd285116b,0xb993deca,0xbba1fa51,0x0bfaa4f8,0xd0f2183e,0x9c9249ef, + 0x96847779,0xf93cb358,0x2322d421,0x284bfb7f,0xd42af009,0x40cc709a, + 0x9bb1d615,0xc69f2274,0x717c3c6a,0x76f50b3a,0xbb9c5eeb,0x8b21e985, + 0xa4783b5f,0x58fb19ae,0x52e1c3e7,0x04c86b9b,0xf2971ac8,0xaca59092, + 0x21ed8291,0x2bb26a69 }, + { 0x15f81416,0x98a34435,0xaaff5bb4,0x086e72e7,0x0317261c,0x3d1f64de, + 0x5c0a1cfe,0x31c0786c,0xb3683401,0x542ea4d8,0x1a39b4cd,0x2f77273a, + 0xcbef27f1,0x14fe7ee1,0x16bb27dc,0xee7fc09e,0x410e5dc7,0xc0dccc17, + 0x1943b3dd,0xa3466742,0x3f31c1b7,0x92934b60,0xc22c1070,0x0186ded9, + 0x799f966b,0xa37ee8ba,0x249b0893,0x0f3bfcb4,0x2e92d4de,0xbae61447, + 0xe196eb08,0x937cb3f8 } }, + /* 184 */ + { { 0x16fbfdce,0x57c0e77c,0xc98d4cc0,0xea034cc9,0x42572d20,0xe7606d72, + 0x0019a83c,0x9861b55c,0xf1597162,0x80ba2803,0x05a0fd7b,0x0f4141dd, + 0x4b0daaa2,0x8865913b,0xaa3848ec,0xe6685746,0x3e0485d2,0x16d15a5a, + 0x3b6905dd,0x81c0c774,0x818af2ba,0xcec31b7d,0xd2b74b78,0x80d8f194, + 0x543e2f28,0xca659db2,0x9fb07c1c,0x31b83a7d,0x1f1048c0,0x86537fdc, + 0x78586a11,0x4d57bb07 }, + { 0x53b396b6,0xbc4b768a,0x93b51dac,0xbc8b24c4,0xa30ae1b3,0x33e511eb, + 0x945147c5,0x893bbd95,0x179fe3ce,0x6cc86031,0x3f920bd4,0x34b0a167, + 0x6b256160,0xb32912eb,0x9d168d83,0xbc69a2a4,0xef0dd128,0xb4949e7a, + 0x872699e1,0x2613419a,0xbf21376b,0x06c58477,0xa4f97147,0xe55b1909, + 0x7b9b745f,0x63d6eb75,0x08df3c85,0xb5365b29,0x55fcfae3,0x0e257e43, + 0x979f2aa8,0x1067c118 } }, + /* 185 */ + { { 0x32bf8883,0xc8455084,0x6fd06667,0x4755286a,0x77c2335d,0xd70b0f8f, + 0x2f4a2c94,0x678e60da,0xd118acf5,0xa468d8ac,0xbf5b90d9,0xce93830b, + 0xed4e9104,0xea4b1c74,0x27776ea4,0xac67316d,0x361bab12,0xb98ad75c, + 0x99122451,0xc323d482,0x530a43ae,0x26440220,0x3292d5a5,0x3a44532e, + 0x5fecf1bc,0xdb48694b,0xc667b8b8,0xe4e0516e,0xa4306ade,0xb3aa595f, + 0xf34e9725,0x7e4f7091 }, + { 0xb7f70919,0x3f3816e9,0x16b003f5,0x765216ed,0x778c99e5,0x46c6cff4, + 0x30a51810,0xe6a5abe8,0x45e728db,0xef6f49e6,0xcaccefd6,0x6fdd73ea, + 0x8c37f3f7,0xec394e6f,0xb6407fc3,0x73320802,0x96625cbd,0x988e8f7a, + 0x7cabfb00,0x83292363,0x407f359a,0x258ba9df,0xccbfae50,0xff01aee5, + 0xfe251813,0xfbeaeace,0x83f1cba1,0x9c69f161,0x9eadcdb5,0x512c58ad, + 0x6ccce8bd,0x2ae49cd4 } }, + /* 186 */ + { { 0xc40849f2,0x1239b0e3,0xa441098c,0x5136a4cd,0xe547f649,0x61535a99, + 0x7a9bbac6,0x92e4bdc4,0x53547af6,0x195a1646,0x8b47a74a,0x85ecb319, + 0x9de6a2b2,0x278553fc,0x0e2ba52d,0x471c038a,0x35bcba93,0x12ba1b88, + 0x6f31eca2,0xd4bf50da,0x802b32c6,0xd146e3f6,0x3c64c8c4,0x0c9c0131, + 0xeed21297,0xad30f12d,0x9c68530f,0x9b75bffb,0x8918de51,0x23c0ad3e, + 0xa73771b7,0x180e9d52 }, + { 0x29ab77b0,0xc316542f,0xf7aee628,0xdd411d9c,0x353c2f40,0x044c0685, + 0x4b0ae4cf,0x638dc7e4,0x95fc266f,0xa0924185,0xfd2feb7d,0x639da671, + 0x5ea39798,0x56858ed5,0x58f3832a,0x7a694f31,0xd316d831,0xa94233c6, + 0x30a35a7b,0x2fcacb26,0xf1ff713b,0xfef8f7dd,0x59eee2f3,0x8b9b4525, + 0x156d064a,0xd1b4f91b,0x2f5cfcfc,0x177866c2,0x3777eb41,0x12bc2566, + 0xd8ab85b4,0x21ca6f3c } }, + /* 187 */ + { { 0xa3e66635,0x0e162b13,0x2a9f76af,0x1ef20a2b,0x46db3356,0xab473a30, + 0x7802bb8d,0x0840bd77,0xa699b44c,0x5b6baf5e,0x1b2207f1,0xc6e11900, + 0x790b0105,0xe5de16a9,0xdb67f004,0x22b12f15,0x8a025d25,0x185fad45, + 0xdf0a1142,0xbccf6953,0xf45034c0,0x4c42129b,0x1c277bff,0x0f740400, + 0x280a9e18,0x6e440b4c,0x842aa2b4,0x767de8f5,0x05e8d94f,0x3de20ab8, + 0x20227635,0x5aff5859 }, + { 0xa8458e40,0x805acd20,0x149732bd,0x5a5557d8,0x5f1ca72d,0xc7074131, + 0x952b5323,0x7f2e269c,0x6494fadf,0x5c592556,0x1a7d2666,0x153b7acd, + 0x86fe2865,0xa6df063d,0x57d53b6b,0x1e91db13,0xe93ead01,0x9195bb89, + 0x2963bfe6,0x3d71e1af,0x88278886,0xfab2b9c2,0x3b859b6f,0x77836692, + 0xf7029dd1,0x6e695174,0x7b984561,0xc7987876,0x5907d849,0x64fb4f1d, + 0x88d8a977,0x3eab7e1c } }, + /* 188 */ + { { 0x52e5718b,0xc73a94b6,0xf4cee1e9,0xe3aefa54,0x553eedea,0x654e9e63, + 0x5f3aca1a,0xf2541e1b,0x0d083316,0xd7129489,0xfb7f950e,0x7965af63, + 0xc74e3e4a,0xd8fc9e0d,0xeaf79ebc,0xb4ee48d2,0x8b7787e6,0xa458a86a, + 0xf7cceaf0,0xd8c7621f,0xdf67980d,0x8228eeff,0xf9106727,0x210d4742, + 0xb07e3629,0x91f63501,0x7971e29d,0x441761c6,0x03a3b8a5,0xc0ccc65f, + 0x38e09544,0x3491da4f }, + { 0xcb062eae,0x6706d046,0x5d08776d,0xee7db735,0x292315d2,0x80de8052, + 0xc402bbdb,0x40785662,0x26ed3337,0x5f93525c,0x7d568ed3,0x6cea14d6, + 0x66888b1e,0x916a1189,0x5dc71675,0x0fbd5205,0xe4575df2,0x833d1077, + 0xec092335,0x4e93100a,0x6cd85389,0x2f9e1d01,0x43226368,0xeebd3725, + 0x1ba4cfd7,0x401d172b,0x574c5838,0x377dab9d,0x80d517de,0xaeaa6958, + 0x6ad15a18,0x0c843dfd } }, + /* 189 */ + { { 0xc9373300,0x455811ff,0x99fdc300,0x1c39332a,0x353cb655,0xe19bb81c, + 0x96a83d27,0x774b924a,0xb2ee3f1a,0xcbfc8fcb,0x010d56c7,0xaf278ec4, + 0xe0abaf79,0x6fde682f,0x7339aebf,0x7566d072,0x71205db6,0xbd35ad5d, + 0x7051c9d0,0xb5bbe694,0xd3a3067c,0x577db480,0x572d7530,0x2c70ff54, + 0xe06d853d,0xe8615aec,0x05abfb5d,0x71999ccb,0xea0a8ed7,0xeeefc96b, + 0x35f6df69,0x2dcc469d }, + { 0xc65f0e77,0xcca6cd06,0xbd71b14a,0xddcc7980,0x3c93cc00,0xb6221f8b, + 0xae8cbf57,0xddfcd5b3,0x76f8e63f,0xbc92973f,0x06e132b7,0xe9848a34, + 0xd51ec9e2,0x4cc59a03,0x3a33081a,0x9c9d32bb,0x80e8466b,0x00121052, + 0x1bbe7295,0xc2b0032a,0x24938448,0xdbfc6572,0xb6bba0ff,0xe972a0ce, + 0xc0a94802,0xf60c0a4f,0x599d8bc7,0xf62c41cc,0x312da0b8,0x820c96ee, + 0xcdbdf9fc,0x5a1a65db } }, + /* 190 */ + { { 0x42485684,0xbfba691a,0x29c470c9,0x613116b9,0xe62a0519,0xb4b01971, + 0x5ff499da,0xf3245aa6,0xa5238eff,0xc2ef87f4,0xcc9d5515,0xc16dc6ba, + 0x2dbdacac,0x5a7f227e,0xa9bbaecb,0x8dedaac4,0x2e7c9885,0xff308a6d, + 0xe6895593,0x4c6f2fc2,0x177e0611,0x3655f285,0x300b1bee,0xa63e8d06, + 0x13c17b54,0xbed0ce79,0xc4974262,0xca4abe35,0xbc4e4037,0xf4b44a17, + 0xefe5fbd9,0x5ae95099 }, + { 0x804f7455,0x122e5ee7,0x22066682,0x341a4997,0x7795e333,0x97d24c31, + 0xe48efced,0x12f4123c,0x19fbc21c,0xe8738d92,0x0663a3ae,0xbb3bdc61, + 0x8593a6db,0x3603d8c2,0xe3c1ac75,0x926227f2,0x5eaae519,0xfea92ac0, + 0xfd6812ac,0x5b596f0b,0xfc2a82dc,0x3ce7e844,0x63522b27,0x3840481a, + 0x52867895,0x836088b1,0x26588688,0x21ffb7cc,0x2f4a7cac,0x0ca33161, + 0xa3edd298,0x4110667e } }, + /* 191 */ + { { 0xc2d04b63,0x81830357,0xf4929a18,0x3fc5a34d,0x22d195df,0xc73bf6da, + 0xcb432473,0x14df2f89,0xe997f138,0x345afe5c,0x8b9604f4,0xd8e3f5f9, + 0x50c10ae5,0xad7942e9,0xeed25ff3,0xcefd5447,0x0e73c0cc,0xbf68e51e, + 0xab54fa4c,0x5b1ad591,0x12b61c8c,0x8bbc1105,0xb5abf760,0xbb932913, + 0x01e79649,0xdb1231be,0x040ccbe7,0xd0a83e91,0x90a96db9,0x3dde426f, + 0x34df11ea,0x1cceb645 }, + { 0x0c6d0f55,0x2d210c4f,0x9c673c9d,0x6cadf61b,0xa9ce3fbb,0xdd7f9919, + 0x93b063e4,0x135f494c,0x145a93be,0x580bdb3c,0x0f52ef7c,0x4d872332, + 0x8814bb6a,0x74d876e8,0xc7a97dee,0x4f6f723a,0x3e3cd833,0x7de2b8f0, + 0xae720270,0x6162f082,0xddfa486e,0xe88ec2d4,0x8d3a17c6,0xd965c859, + 0x3980171a,0x62e59e54,0xbbef6b22,0x0ab6285d,0x4d48b203,0x3cf45195, + 0x4ea25ea3,0x1f175233 } }, + /* 192 */ + { { 0x3467ea91,0x808a765b,0xfd2d9c45,0x3f4632ee,0x9cf2bc6f,0x7b75dc6d, + 0x359813ae,0xefc8d240,0xe44cbd8d,0x23ecb209,0x21525622,0x59ba10e3, + 0x3f1ee19a,0xfa14d934,0xfb0c48f7,0xdf97c21b,0xea30d437,0xc4e62890, + 0x651475c2,0xb286e2a4,0x126672a5,0x291f01e4,0x31aab3b8,0x9c6fda5c, + 0xe17d22ec,0xb7277a5a,0x914f0bad,0xbd88ed83,0x6a2392e1,0xd0b05d1b, + 0x65893c2b,0x4cb8af90 }, + { 0xbb4b1953,0xa2b02057,0xf597f6ee,0x4ce08b44,0x5e6412c8,0x854f5d9b, + 0xb3cd4919,0x1913262d,0x6e42bb5d,0x902762e4,0xd78e7f60,0x8355c8e6, + 0x38b6c16c,0x8efaa824,0xe550f618,0xd0173790,0xe57d778e,0x118af462, + 0x715b4714,0xa16ad5e8,0x41dea4f9,0x900596c3,0x280ca610,0x2a957c32, + 0x374c65a1,0x2faee800,0x50080414,0xdb105127,0xff080fa1,0x8c1db931, + 0xd79878fc,0x486a5c25 } }, + /* 193 */ + { { 0x941b4f36,0x0521e213,0xf803b4f9,0xbaacfb14,0x52a54ba8,0xfdf1e22e, + 0x8fe4796c,0xacfabbba,0x58dbacb6,0xae0788db,0xc19dfa51,0xdf98d736, + 0x35a716ee,0x155c286a,0x9c86461b,0xbe7d4676,0x63a64a5e,0x50b6380f, + 0x9f609262,0x14b41914,0xa2dfc5b3,0x0919a7d0,0xcef466ac,0xc454da55, + 0x6986aaec,0x93fa4a24,0x71a49ced,0x5090b171,0xc1fa75ad,0x602f1d6c, + 0x78e4c054,0x5d269f89 }, + { 0x14920419,0x3a74030c,0x90968739,0x0845d868,0xeeb70fa6,0x81b994c4, + 0xd9fc5bcb,0xabcaa06d,0xf58f8f2d,0x06539427,0xb1dc52aa,0x35c85f67, + 0x2c911baa,0x5a7d8d72,0xaec2d834,0x4041005c,0x7a8e5347,0xb5868a44, + 0x8de512c3,0x04ee180b,0x211168eb,0x4daa66e5,0x2317cd8a,0xc0bd5dab, + 0x61164df6,0xa1d4185d,0x1dbad7c9,0xacedca26,0x09b02683,0x0fe4b5ac, + 0x26d9550f,0x8ac9995a } }, + /* 194 */ + { { 0x2640a39d,0xb2c8dc9b,0xede0c9f9,0x21ff0b38,0xa1ecba0a,0x74f469bd, + 0x080d0417,0x8a902ccd,0xf4994604,0xe956fa32,0x9776ab15,0x348f85cf, + 0x0066f492,0xc21fc6ee,0xfeeef367,0x35b1ebfe,0x4613e5ed,0x7804581c, + 0xea6ba071,0xcbdfe8e6,0x950d73ed,0xddfcaa32,0x1da48889,0xc9747936, + 0xdbaffbd1,0xce867c8c,0x1cbaeae7,0xd267431f,0x897912c8,0x68255045, + 0xd7ea1e4d,0x0c7c1ddc }, + { 0x1ce963a7,0x53aa30cc,0xc4c5fade,0x7352f64c,0x2828afbf,0x2b9aa2f8, + 0xca212107,0x64273c56,0x85a576dc,0xaadd7654,0x90b5c77c,0x6196ac3e, + 0xd1aaf39b,0x20d43e9f,0xcd05cbc4,0xfc392062,0x4c0ff2fd,0x14163872, + 0x2ae821e6,0xcf32b8d8,0x3fa7a3f0,0x5f58f943,0xf644ca92,0xaebf1d2d, + 0x1918a75f,0x0c061563,0x6b876118,0x7989b5ed,0xad412441,0xbf342445, + 0x1df633ab,0x24ffc9ae } }, + /* 195 */ + { { 0x93c7cb2b,0x89fcdc05,0x590053fb,0xc1243b95,0x6182343c,0x601debcf, + 0x66c18a63,0x364546ef,0xec913287,0xa5290701,0xf9788c31,0xc35b8026, + 0x92d1f7d7,0x852b862a,0x0aa79728,0x1809cb05,0xa3cb2005,0x897d467c, + 0x9ef5b946,0xf20c77c0,0xf2241984,0xc3372c42,0xf35bb206,0xda053e0d, + 0xa9c140b5,0xbc26c6d0,0xcb56fb33,0x61cfcc0c,0x299b3968,0x1c3cf9ef, + 0x40621ba4,0x89e4d3d1 }, + { 0xa45a9be3,0xd35e80e7,0x07356fbd,0xc4daa578,0xb967bc2f,0x0186d62e, + 0x47cd16e3,0xa702679e,0x5f30ce9b,0xca2f1c02,0x1f864f50,0xf1205b46, + 0x85061d66,0x7fd6d797,0x8a08809e,0x47edc4f6,0x9a4d3ae2,0x5dac0449, + 0x6d1f9da8,0xf844664a,0xd7a83a71,0x9f30ce84,0xeaac33f1,0xe9382bac, + 0x948622ab,0x1f033831,0xf7681eb2,0xb037a4ba,0x99a1b5c7,0xd156a908, + 0xe6f1d0fb,0x675d3e6f } }, + /* 196 */ + { { 0x707193e5,0xd9767ffd,0x810358e5,0xe478aa91,0x328d8ef7,0x5634f9ff, + 0x6dbbd9a7,0x913a0ee8,0x7e215686,0x379b2968,0x89d9da38,0x903f410a, + 0x1b1334d2,0xd9f8d7b9,0xbd82efb5,0x9fe74229,0x3803c778,0xdb568b62, + 0xd3d25344,0x93e9a350,0x724497e8,0x559c35b0,0xa169e23b,0xc472d436, + 0xcc5b4c69,0x09864632,0x83c7f531,0x9f6d759d,0x1e497888,0xa91cf1db, + 0x60af1a4b,0x5f7f92fe }, + { 0x0545167e,0xf18a1cc6,0xaffa88e0,0x55ee2e02,0x432a7bcf,0x24cdff51, + 0xa7510866,0x7382da42,0x40511af7,0xe894c11f,0x2aaf1423,0xaa4e4e31, + 0xf63dd2ae,0x8c3d36f0,0xd7660635,0xfc5c9550,0x37ea7eab,0x01253731, + 0x39b950f6,0x2a5cd598,0x40e63442,0x95a0f601,0xf2ac7045,0x905e238e, + 0x446b0f73,0x44bacc0e,0xc448578a,0x4cd4206e,0xa5bd7803,0x367b1aaa, + 0x0a2b458d,0x25beced9 } }, + /* 197 */ + { { 0x0c33a8fb,0x079a7382,0x0f25dc1d,0xcfbf6cd1,0xc6d482b6,0x4ffc73f8, + 0x07bf844a,0x3e51f18c,0x599162f0,0xa7651236,0x14013811,0xac59a74e, + 0xe55018a0,0x957a6865,0xe3ca09b1,0xe1ec51bd,0xa960253f,0xbc0c7eb3, + 0x7de03f84,0xe83bfd14,0x52fbdb09,0xc0540ed1,0xcea15ec1,0x6ba52edd, + 0x4b261307,0xf3d30ed5,0xe8397206,0x9bd7bae8,0x096373aa,0xf20d8692, + 0xc3b0bf63,0x0a616a4b }, + { 0x6e1339c9,0x2075f3ed,0xbf8b00a6,0x7afaa072,0xbccd9b47,0xdfafec82, + 0x00ca54c7,0x4713158f,0x38bc31ae,0x449102f1,0x310dfc8a,0xaf98f158, + 0x59e954d4,0xc9ef2075,0xc527a0c4,0xe8021af9,0x7a192023,0x6e801277, + 0x7fb02377,0x635f538c,0xe8c9e951,0x5df1974f,0x15cc9097,0x0287faed, + 0xf7a5115c,0xfa0728f0,0x0fac623d,0x90dbfbe6,0x0311ba09,0xa8d40fd4, + 0x07c6464c,0x876d154e } }, + /* 198 */ + { { 0xc2d3ea8a,0xd3a4d6d2,0xa842600e,0x36be681b,0xe4070672,0xc53f100d, + 0x6a7d7a7b,0xe3e5b6fe,0x5d5e1a83,0x6e6994f9,0x76097c2a,0x07cacd22, + 0xa6791011,0x12d98dba,0x102e0e24,0xddfc4461,0xd493272a,0x4815dbc2, + 0xa9436696,0x7e38e64b,0x32b2bf90,0x4960eb1a,0xd928e28b,0xda457525, + 0x2a077c9e,0x72f75b39,0x7fd61d00,0x27760cbb,0x0f4b1456,0xaf235d1b, + 0xe76d1700,0x3040c23b }, + { 0x4efa9a70,0xb10dc55b,0x53e86610,0xd4de414f,0x09f8a27f,0x3d95c113, + 0x06661d3c,0x505109a5,0x60eb513e,0xcaa2994a,0x1e7d338b,0x3ee41537, + 0x4651e71f,0x4fd145fc,0xcbc313b4,0x51bbf838,0x1eb92150,0xb039e078, + 0x14bf5ac7,0xe8696b44,0x8be0d48c,0x2d667188,0xdd8f2b6f,0xbe93b2f5, + 0xeb8a7f8a,0xc1dfd1e7,0x90f751c5,0x862b3dd9,0xa32a74be,0x1eb1ad58, + 0x1ebbc9a2,0x5486d79a } }, + /* 199 */ + { { 0xa1359e13,0xcb2e34ff,0x28196051,0x202d8dbf,0x23564b5e,0xe95e023d, + 0x42f6ac12,0xfb1340b6,0xb653725d,0x543ba852,0x8d2466ad,0x81aedcd6, + 0x547c728b,0xbf780224,0x9569fb65,0x559f8a11,0xdfb22ec9,0x505b7a62, + 0x9eed5e52,0x07107540,0x299f6f11,0x9c899288,0x3db6f8c7,0xa7d69261, + 0xb3ca79a9,0x30eb7fb3,0xfb2160b0,0xcab99bb8,0xd28b409a,0xd2012568, + 0x5ac45f8b,0x380f1b0f }, + { 0xe6a0068f,0xc0b99e6b,0xc8a73753,0x4b67cf2a,0xb2faeb7c,0xa6c9a548, + 0x340260c3,0x7f417f99,0xcc0f739e,0x8ee56855,0x780949da,0xf08b510f, + 0x8d5c6eff,0xb1770fc2,0xfd96a7bb,0xb4f5abee,0xf2665a2a,0xa07b1136, + 0xb601dcf9,0x2fb380a4,0x162becc6,0xcc803614,0xee6b83b3,0x3498fb96, + 0xa8c17eeb,0xea9b0fd6,0xa177efc2,0x5834b5ba,0x5b110b3e,0x929044f5, + 0xebd7285e,0x4abedded } }, + /* 200 */ + { { 0x700ef376,0x3355e1b9,0x66cdabff,0xd56e5d9a,0x47e87646,0xb3dc2575, + 0x00f79369,0x28f44b8a,0xa0c52e29,0x08c32b1e,0x3729b392,0x5a78de12, + 0xb26d239d,0x4184519a,0xe0ce4a6b,0x23f6b4b7,0xacb2a9f9,0x235f6f8a, + 0xe2064a59,0xbb8bc454,0x1bf3062e,0x37efd034,0x94dff6f9,0x6bac683b, + 0x8aa7fa06,0xc3364b1e,0xce0b3745,0x0616772a,0xd1e3fb0f,0x46f08d08, + 0x18e132d3,0x6a20abb3 }, + { 0x6a85cbc7,0xea831016,0x934f9aa7,0xd0990946,0xe778f1b3,0xc2211088, + 0x2247b799,0x7ea4ff8f,0x454484ce,0xb3171d71,0x4f98c364,0x29403949, + 0x97df1458,0x5da911f3,0x09439116,0xa6b58093,0x174238bc,0x75f9509a, + 0x8209758d,0xfeb51821,0xa47925d0,0xae0c6021,0xaf8a315e,0x0e946694, + 0x6bad04b7,0xae7af8a3,0xf072447d,0x44c15e7f,0xa5456ffe,0x5184668a, + 0xbf36b977,0x45e353a7 } }, + /* 201 */ + { { 0x93092f71,0x76056764,0xf5b92d71,0xeb66b6c2,0xe2c8b6c5,0x9db3149b, + 0x20c0363e,0xf62f583a,0x03cd7097,0x688acd33,0xebb916ac,0x85d0c0f8, + 0x84c19b0e,0x1bf7462c,0x7c4a6ad1,0xc76ed5f9,0xd119f369,0xec8b88ba, + 0xebe50b83,0x59b8371b,0x866706a6,0x0cc69508,0xf8373d2c,0x531c75a3, + 0x2a5a02fb,0x4e1cd3a3,0xda39a1d0,0xe8274778,0x75da333e,0xedfc5bbb, + 0xca79bd36,0x15941f24 }, + { 0xa77dd512,0x42e8c0f8,0x1dc365f6,0xa91b59a7,0x08753862,0xe80d14cd, + 0xd272faca,0x1624230d,0x4027cb5a,0xeea3ec16,0xc1ef9f03,0xc1700b59, + 0x0da3148d,0xd411c127,0xc4181af1,0x801ee448,0x9e3a900b,0xedf28559, + 0x0d09affd,0x5d67b0bd,0x8b370024,0xd839df96,0xe6f836b8,0x3b6307e0, + 0xbd3201c9,0x5382e588,0x7a1d02bb,0x636d8a6b,0x968641e9,0x70b7db76, + 0x118fad03,0x6d17c34a } }, + /* 202 */ + { { 0xc181c99b,0xcf608841,0xc87bdcaf,0xb65dc901,0x3720dabe,0xb460b447, + 0x5377515b,0x4c79c396,0x0a96c277,0xd447f22e,0x2ac0f440,0x0d952130, + 0xc90583ad,0x8330b26b,0x928904a0,0xe25e977a,0x85c50b18,0x1deaffd9, + 0xa5ad5f6a,0xcf4dbcb7,0xc8a37ed5,0xcbcd0019,0x1e9850b6,0x7846dd90, + 0xb0b8e605,0x1ac8194a,0x34132f90,0xb9728571,0xf56ee28b,0x4ce9f149, + 0x3e9e1d4e,0x1ab9b5a4 }, + { 0x314fa7a3,0x206dab92,0x478ff963,0xcc4af0f0,0x904d9fdb,0x4cce1713, + 0x12c045fe,0xac20a2eb,0xfd8f6d7d,0x44fc5478,0xca7b6ffa,0x886e72c5, + 0x6fd6f758,0x7fa4529b,0x92a820d5,0x4df1d1b1,0x2789f149,0x3d812f9f, + 0xaabb53d2,0x9842f083,0x2a03ab32,0x2648539b,0xb1512502,0x631ce090, + 0x731f6bd5,0xe1294d15,0x9436e634,0xb229361d,0x3ca966af,0x8c4281c4, + 0xc21ab3ed,0x24b34956 } }, + /* 203 */ + { { 0x659824e2,0x49bdcb86,0x4e13e74c,0x6dc4ce48,0x6bbe1eea,0xa4c01a26, + 0x1e3ec457,0x47b2b8e7,0x2f5a8e4b,0x7e8b15e0,0xe333530d,0xe81eb6e6, + 0x17a45202,0xacba369e,0xd70e4c9f,0x81241431,0x3e12beb8,0xc190af4b, + 0x11f486fd,0x53270523,0x29fb2bce,0x9f6c41e1,0xb70f6c08,0xbe6287eb, + 0x3feb4477,0x1479850a,0x9bcf18bb,0xfcfdfb11,0xda80d040,0x925c292f, + 0x7e3c5bf9,0x212d65e5 }, + { 0xca15cf08,0x23adb386,0x81e172eb,0x4dfa4ac4,0x4d42d0c0,0x9d1dbf93, + 0x74404dc7,0xd9cf6073,0xe932bfcd,0x60508441,0x1c682a98,0x9ae910ca, + 0x41ac1cc0,0x9528fc18,0xdbbed630,0xe6a120ae,0x30ccf250,0x94e0e1ec, + 0xe58bbf2f,0xfe84ba54,0x9faa4415,0xc66d0b4f,0xecee7ce5,0x0c58f1e7, + 0x6fa6873a,0x7a1d43eb,0x399f1348,0x96c6c5a0,0xe6727ab7,0xe6ef9aaa, + 0x9a5c2447,0x66afa554 } }, + /* 204 */ + { { 0xc980e91d,0xda5aaba8,0x6ac98efa,0xa93cf509,0x8da32662,0xb0990e0a, + 0x0081453e,0x01d21530,0x3d71de84,0x2bb0d33e,0x3e19a012,0x465f6d80, + 0x78a838e7,0x5902ff4c,0x1931348c,0x74e2afb7,0x9cfb057b,0xa4932757, + 0x3ad03f8f,0x761ea642,0x58ffa40a,0xb7d4c245,0x77a87e30,0xb5e9c0d9, + 0xc9c84d26,0xd1c5edba,0x3d1963a0,0xeca8839a,0xebf6bf0d,0xbc6f2f35, + 0x0d58abdf,0x01ef0631 }, + { 0x3ecdcbb0,0x2bf90316,0x27c1c955,0x19e2d728,0x9575c930,0x9e527030, + 0x96983930,0x0dc1c5a9,0x7cd082df,0xef9f80ff,0xdf97e051,0xcd915075, + 0x9cc61b55,0xf286fffe,0x80f24cc4,0x352db38f,0x36523ae3,0xed9b99ec, + 0x10b104a9,0x109a8ca8,0x305203ad,0xc2700fe7,0x769400f5,0x2a2ee24e, + 0xee0c452c,0xd595d399,0xf7f02a41,0x0ab75d6a,0x0db730b7,0x34108099, + 0x5e8d1202,0x0e4f5ffd } }, + /* 205 */ + { { 0x0ff14c38,0xbd1c6444,0xaece11f2,0x9a5b59fa,0x22af6330,0xaa4605a7, + 0x82af24ee,0xddc9f65a,0xeb9a1159,0xf4ee4bfe,0x74e84eaf,0x2463d076, + 0x0e0baace,0x88cbe1e0,0xd5fabdcb,0x7ca568ea,0xc57eb99d,0xbd80d524, + 0xe9be9873,0x9c46572c,0x7300b85e,0x918a1dcd,0x40f54176,0x49221312, + 0xb5b14236,0xf7e324ff,0x2434f16a,0x40dda501,0xa133d97c,0x08833421, + 0x0876f020,0x33d41161 }, + { 0x9878e5ec,0x7531a36b,0x46918232,0x5de3e321,0xd0a30464,0xd15f9a33, + 0xaa173659,0x734c1b87,0xf925d4fe,0xac2094a2,0xc262b0f4,0x43c965a1, + 0x447d5cbc,0x759c903e,0x05239300,0x92af215e,0x1f593f34,0xfffb6d5f, + 0xc3cddb5f,0x65943b4b,0xbfdd5408,0x9d03a29c,0x198d76c0,0x8f7cda6b, + 0xc0f27b59,0xc0790a22,0x8cb58ccf,0xba557a84,0x76c54fdc,0x5922052d, + 0x47b6b466,0x2d3de7aa } }, + /* 206 */ + { { 0x65add3b7,0xaade7462,0xabf24c2a,0xe5888f35,0xe1a57d93,0xd41549ca, + 0x2c76f7bf,0x0e22e18e,0xbe3202b3,0x67f288ea,0x1d1d0f0a,0xb79a66ba, + 0x2881ad18,0x0e0ab749,0xc7adb0e9,0x7d424086,0x2842132f,0x870c32c5, + 0x58f9a09e,0x858477f1,0xec025589,0x422a9372,0xa5098777,0xbe428c5c, + 0x57660058,0x45b79564,0x957f37cf,0x6c7fc631,0xd6316289,0x8b7023dd, + 0x5b1c12a6,0x47003bb6 }, + { 0xc91c1c96,0xd99401c1,0x27a12970,0xaa5dcdf9,0xc3c29107,0x3ab92e17, + 0xa3fe4710,0x26fce8f7,0x4ee998ee,0xb0d09d5e,0x8e3a41f8,0xafa62204, + 0xa26ca506,0xb1c012a5,0x99b57252,0x2c6f734c,0x512f7fe1,0x1093d79f, + 0xacee19a6,0x2f30906e,0x056d1ea6,0x6bff8381,0xeff35f21,0x61c75856, + 0xc1ad2224,0x6e07e978,0x6b20fde8,0x2cca6ca1,0x633fe81b,0xab4d6d2d, + 0xb06a2ce6,0x73dff504 } }, + /* 207 */ + { { 0xd8e20fb8,0x8b615805,0x82b533f0,0x7c6873e4,0x56a854ca,0x5205f001, + 0xcb369211,0x87fec6ac,0xc7f092b7,0x1fa3c0ec,0xe845fe4c,0x5b36647e, + 0xf8b1f112,0xd4781e85,0x8b0f1a6f,0xc6526839,0xdcb8eb92,0xceeb8c6c, + 0x8e5f6d52,0x133f0ead,0xc8d934dc,0x31883e23,0x428ac45a,0x214ed5bd, + 0xdbbfca85,0xf77ca492,0x07e5ae13,0xdf4113fe,0x72ab05fb,0x63e4a0d2, + 0x7148f535,0x7544d0b7 }, + { 0x80797ace,0x4fe8d134,0xaf86d97e,0x216d6aa0,0xef5a68fc,0xdbf0a688, + 0x9f9b2684,0x18b26f45,0x8999d2fc,0x52fefcfa,0x62423955,0xd5af8d82, + 0xf63a3780,0x8f123469,0xdcd4feaf,0x2933454f,0xa73b5d09,0xba8018b7, + 0xe5552c18,0x9af1f276,0xff26bb1c,0xc5d4773d,0x06dd4f44,0x9ef49410, + 0x5f39ba49,0xad8f12f9,0xf66ca4f2,0x5767f6dc,0x7922f59a,0xba8773f1, + 0xc1e42d49,0x220081ea } }, + /* 208 */ + { { 0xba37a0ba,0x3043d573,0xdd176df6,0x05a431bc,0xc42070f7,0x03322cfc, + 0x67c2d109,0x5cabd30e,0xcbf8bcfa,0x362c95de,0x7787b10b,0xd767d277, + 0x6ec05e64,0x612c915e,0xce69c30e,0x9e669631,0x682e2635,0x27c9dd8f, + 0x95ffcc38,0x79021f12,0x8a2adca2,0x06a8ee79,0x4b5d500a,0x8e00e784, + 0x8d80d6c5,0x87746fc7,0x915f10cc,0x246053be,0x219f6fd8,0x844e328b, + 0x11bd3733,0x620541ac }, + { 0x509e5a29,0x0f7fd382,0xb432531e,0x8748d7d0,0xcd3883b9,0x8f749354, + 0x8bfbb17a,0xc6b8ac74,0x05f2d2c5,0xa4616a66,0x1bcb1b83,0xb3d96625, + 0x2fee265a,0xcf753104,0xdb225058,0xc70d73fb,0xf0c2d556,0x1211d434, + 0x54b259b3,0x862061d8,0xc42b3f7d,0xffe4606d,0xe86a4949,0x4c5c8585, + 0x160eedac,0x04ddcc8b,0x568e2420,0x1804ce67,0x42141656,0x91f3855a, + 0xf932be97,0x7f378198 } }, + /* 209 */ + { { 0xdfa6639a,0x9a374bda,0x02ab7391,0x0cbd48d4,0x47031e2d,0x5c5ef236, + 0xd0599d1f,0xb49ee2bc,0xe0d38443,0xd285eb60,0x269392e8,0xdbbea92f, + 0xb8bc538f,0x91455fbf,0xe469b768,0xae259ff1,0x41de5682,0xc1cecb1f, + 0x9952d1ae,0xc876f071,0xe7bf7446,0x1ce25181,0x282ad2f1,0xcb93ad86, + 0x6ba4ef67,0x8fa3cd31,0xe507aa3e,0xfce68a04,0xa61bb608,0xced74170, + 0xf6ac10d0,0x6de716b3 }, + { 0x172d6dc5,0xd4e58d04,0x6397c65c,0xbed2cde6,0x0c9eb4e8,0x7ae77e18, + 0x75fa2edb,0x56275468,0xa91e6738,0x4b30324e,0x235c8b2e,0x6023a856, + 0xa8f92887,0x9df6d6c2,0xf6f5e8b5,0xec2c185f,0x3ad5748a,0x7892e12b, + 0xd54aefbc,0x7aebb4f2,0xee868821,0x14915448,0xb1d9bd5b,0xa26c5f71, + 0x2ff00df7,0xe5ccd166,0xb95b1dee,0xebc99f17,0x3fe1f774,0x90983616, + 0xbb3d25b0,0x51f90830 } }, + /* 210 */ + { { 0xf2922461,0x49376fa1,0x1650d0d1,0xdbb1b1c3,0x0dd8608d,0x92b91c33, + 0x36b89906,0x3e612c4b,0xdf560052,0xe1977b0b,0x636a2545,0xf8afff70, + 0x11723d8e,0xcda7d278,0x81bde7ba,0x0b0bc4bb,0xed2a578e,0x3cb080b2, + 0x171b2e02,0x5bda0d0d,0x941bb9ae,0xf6df38cf,0xc14a65c5,0x85dd81db, + 0xc19dd98e,0x7f98c82d,0x52206f93,0xc613747f,0x5f5bbe78,0x9e13a2c2, + 0x0aa34be7,0x5eed218e }, + { 0x01d4dc0b,0xe1565754,0xf566bb07,0xa1ae5f27,0xb82225d5,0xe985ebeb, + 0x1189ec6b,0x5f3ad21c,0xecce4d9d,0x17da518c,0xd6b65b59,0xc84a2d3e, + 0x8ffa771c,0x7f988175,0x2ac69a7a,0x50d6ae12,0xc6e6846d,0xcb7f30b1, + 0x5bd0bb13,0x8c023a60,0xd73f2407,0x9a10fecd,0xe5f0a996,0x8c5158cc, + 0xbd8f5806,0xd26bf615,0x915a46e1,0xaf32ea87,0x0287d308,0xeaf74e81, + 0xa6264254,0x8c14ba06 } }, + /* 211 */ + { { 0xb17ee201,0x0c877895,0x88e57a77,0xc05aa471,0x97822456,0x19c3e763, + 0xc9c3ba1d,0x0be6f8c0,0xb4389ebe,0xfe85f4ff,0x0ce7fbb6,0x538bccce, + 0x65266c64,0x876eab2a,0xcf9a3842,0x5c9ac690,0xccc8f981,0x9f5cf3b1, + 0x9cf687de,0xfa17be6a,0x83835c15,0xfcfc10fc,0x150ef2eb,0x086b0fdb, + 0x884a52e6,0x9f97ecd9,0xb0cd1eb8,0x416e6fa2,0x3ecc03ba,0xe2bd1599, + 0xeabb165e,0x645c0a5d }, + { 0x50aa7e31,0xd94c4205,0x2f851da5,0xaec8df0c,0x3c726e6a,0x99646909, + 0x2619bf9a,0x72dbdc36,0xe253fbd5,0x1b4260e0,0x8c709e06,0x97c259fb, + 0xcddaec5b,0xfabf7cbb,0xe4b703e9,0xb4d5e8b1,0x0734efdd,0x1b06e56e, + 0x1f55f8a5,0x02d4a4f9,0x3f565c8d,0x7f8608ba,0x816d1d94,0x822f47d2, + 0x5ce7b136,0x0cc36156,0x31d04242,0xe46ee5ef,0x683567f6,0xb2a65f70, + 0xd2fa6c91,0x27e9ff40 } }, + /* 212 */ + { { 0xd7e952e7,0x75251893,0xc735bf18,0x15b30583,0x96fe0491,0x732b5992, + 0x806d2fca,0x27451858,0x1b885ed9,0x71ab76a0,0x6d9f55ec,0xbdce9d97, + 0x48f2ba9c,0x3da60b20,0x592b132b,0x6977c086,0x099051d7,0xb6dca9cb, + 0xd188ae25,0xd9c2ab23,0xe20aaf3d,0x9f469f3f,0x5aad74d0,0xdbd1f7cf, + 0x22a9eb3b,0x3d5efe5c,0x137010c4,0x8c5edfa2,0x57870260,0xada2217b, + 0x3dac9776,0x4feee567 }, + { 0xb5d3d780,0x30e18d52,0x07166744,0x4dadb5d3,0x5a742156,0x320d386e, + 0x8d6bbb86,0x5d8c290e,0x2d263dd1,0x981a4323,0x98984636,0x33d0e7ca, + 0xa519acb1,0x5138784d,0xdddc81ff,0x832e3fab,0x3199a43a,0xfc278594, + 0x32743163,0x5b4cabcf,0x74f94fa7,0x9fa010bd,0x5694a627,0xc28a743d, + 0xcb657a24,0xc1d2a888,0xe86a25ea,0x7eef2503,0x04c561ff,0xed11a5d3, + 0x9c9ede0e,0x4fe818e7 } }, + /* 213 */ + { { 0x7fc1c7ff,0x00252c9d,0x9fa89ad1,0xa9bd419d,0x4064e9cc,0xc93a124a, + 0x43942ecc,0x384cbcb8,0x8749695b,0x004c21fd,0x421165bf,0x69c81d9f, + 0xdde01102,0xe2325628,0x5a9b004d,0xec937457,0xf6dcfc21,0xfb3346bf, + 0x4d372c7d,0xac4da64b,0xf20494e2,0xcecb7ad3,0xe867c150,0x562c41b5, + 0xc2b723d8,0x299395ce,0x7ee53231,0xc91adfc5,0xf10b6597,0xe06f1161, + 0xb74d3ffc,0x81915529 }, + { 0x6ed9d4ee,0x8ec12431,0x689aff01,0x3dffa154,0x2a89a3f4,0x4aba349f, + 0xd467efb2,0x2db1e8e2,0x039102e2,0x18dea354,0xe52f082b,0x422ab853, + 0xed36dd47,0x7130a2c1,0x0295d1ee,0xca60e86d,0x7c7f5ad3,0xe6ac6808, + 0xde864658,0x0f83cecf,0x461d1265,0x72e66c21,0xbd385099,0xfeef4150, + 0xa6632289,0x0f183f3a,0x792dc795,0x275454be,0x11367702,0x2744c11b, + 0xe8ea6ef3,0x7d06bcc7 } }, + /* 214 */ + { { 0x7090212f,0x89285942,0x5521e844,0x691b7d4c,0xbe2dbb92,0x4c038422, + 0xbd81f880,0x317721ed,0xac89bc36,0xc136cbee,0x7b8f004d,0x4f71b60b, + 0x4e218ab8,0x269132d0,0xe6cc814d,0xb0e2496e,0x75fadc15,0x0b2ce317, + 0x66d223c5,0x82e3c084,0x4c612f8b,0x9721caa6,0xa4b65355,0x59a751eb, + 0xc7d3d9d1,0x3433aad5,0xe80d4246,0x1e61b9d2,0xfc673caa,0x149f655f, + 0xd0f9cb92,0x48b52b99 }, + { 0xefdc05be,0xa3915399,0x13e095e9,0xde70db18,0xcddb3fda,0x447862e9, + 0x1a009451,0xa2b03162,0x23920ea3,0x4b27980c,0xa23b8feb,0xac5394f1, + 0x3e5616d4,0x163f7256,0xb714219a,0xaa0ff93f,0x93d62474,0xd26f96d2, + 0x7dcfe276,0xdd212ea8,0x47038d15,0xab27bf2f,0xf418168e,0xe58c8325, + 0xb32a989a,0xe3704222,0xbfc9f13b,0xa3694390,0x0d0684ad,0xf16e2606, + 0x9d8c76ec,0x17c0de87 } }, + /* 215 */ + { { 0xdcc01958,0xbca5f453,0x1ce88393,0x7d945954,0x561f5b6d,0x5e6350a1, + 0x7e2d36bc,0x291c3c86,0xa5ac3a6c,0xf6c7ed84,0xd98006cd,0x7913c40b, + 0x5671ec3b,0xf78bb087,0xb43e89a9,0x1c928f6e,0xae1ea1ed,0xfdf28df3, + 0xb924b2b5,0x62bba5b1,0x1a116e05,0x491d2705,0x167ed3e3,0x08ec02b7, + 0x5bc0b046,0xe291cf7b,0x8c5d7f59,0x30e50169,0xf5c799b7,0x0c7c350d, + 0x0ac6e1d7,0x6862b9e2 }, + { 0x9ffa1f64,0x56c6f4e7,0xa1e24349,0xfed6a91a,0xcdb75232,0xe9a0ee0c, + 0x0322d607,0xbfc90b37,0x462fef87,0x29480ad2,0xc2bfcf34,0xfc214969, + 0xa539e38f,0x6e5211e0,0x12a5149c,0x2a59ec26,0xd706b532,0x195fe212, + 0xe99c8429,0xf77fb108,0x5dc80482,0x74ceaea3,0xbd92d298,0xa5a6030b, + 0xaaea15ee,0xad42dca5,0x4987109c,0xd6ac3bc7,0x290af649,0xc64e1c40, + 0x51f8de6c,0x5093fa2d } }, + /* 216 */ + { { 0x4c2d553b,0xc4cf3280,0x3b966c29,0xdc1abe22,0x2296914a,0x556a549c, + 0x999976c9,0xd8c9f8b5,0x776e83f3,0xc22c57bd,0x7c85ec57,0x4f2942ab, + 0x6e2c61f5,0xef3407e5,0xf213db48,0xf005e8ca,0xf32698c7,0x470c853d, + 0xcac0a54b,0xe6f488d7,0x60b7501e,0xb6bd6bed,0x714a4bd9,0xf0103106, + 0x6e098894,0x5285bc3b,0xf5f92a00,0xec06741a,0xef7ef24a,0x32f16426, + 0x6c77a438,0x12f9c44d }, + { 0x83313a1c,0x1951e964,0x33c58b37,0x98edd3da,0xc7ac4044,0x4edbbf52, + 0x0dcb5ee8,0x866ca6f7,0x6dd422f8,0xec0ae8f5,0x0661ec2e,0x1077bc54, + 0xd422523c,0x6d39913a,0x58e7cb3e,0xd105e1e8,0xc979bb45,0x47c9397f, + 0x0997b592,0x3221d4a9,0xe8952fe7,0x0ef628a3,0x4e946241,0xd08d5827, + 0x59780f40,0x64cbed0f,0x08e110ec,0x13d7c227,0x7679b1a3,0xd186d866, + 0x26ae1d18,0x02f75e4e } }, + /* 217 */ + { { 0x47f307d7,0x1b637ebf,0xd0141477,0x6b644a6a,0x2e05a80c,0x82a33d65, + 0xfed07b31,0xc8f1a0f3,0x3696e597,0xc09ee7f9,0xc7ffc01e,0xcdaa7ec3, + 0xf8f373b9,0x549f88fe,0xc3bb8989,0xc88d1961,0xdfcaa7b7,0xd92a4fe9, + 0x3ae4ab20,0x12ff9ee2,0xf5ecb1a5,0xf5aea641,0xe32fb47d,0xe769237f, + 0x25d085c0,0x96a5c420,0x26c755a2,0xdc912558,0x9bce9723,0x580b985f, + 0x63961941,0x72b1b566 }, + { 0x790e5558,0x9d708a08,0x0689af80,0x98536041,0x42313b5f,0xe85e7b8a, + 0x55a49d1a,0xe6ba1292,0xac371b0b,0x5e76c4b0,0x938e6e19,0x58504f39, + 0x60ae9a21,0x8dd41422,0x968485ce,0xd8b04e9b,0x887efe43,0xf94c4ba5, + 0xf11c5e73,0x11268e67,0xcf6b99c4,0x92623e28,0x7a0a9662,0xf2d0aaa8, + 0x4ca02ed3,0xb266772a,0x2d63b551,0x68ee8e4e,0x2e78b5b5,0xcdebb299, + 0xe17225ad,0x5df19216 } }, + /* 218 */ + { { 0x8df2e7e3,0x20027e1e,0xd8da07de,0xb183cc68,0x4b4ae694,0xce35ba69, + 0x3ca62e88,0x896d97df,0x52efed2c,0x3de4713b,0x26bd084f,0xd006c40e, + 0xfc81923b,0x1e9b71bb,0x1aacc6b0,0x9991c7b6,0x8f656840,0x650c9364, + 0x87f47524,0x138561d1,0xbffd3ca2,0x610f2b11,0xfa191418,0x96915faf, + 0x955e5309,0x8f1236de,0xa1872d79,0x613cbeea,0x66a2a48b,0x7f7b44ea, + 0xe0a89c32,0x452265c2 }, + { 0x25430010,0x4ad5ec79,0xebd090c0,0xcac786ff,0x20a9d3f5,0xa5f9f4ff, + 0xa3edc65f,0xfcbf4112,0x0cf3eb11,0x8824839c,0x8aa5b700,0xb8dd6d4e, + 0xb7568ab8,0xe2271dfd,0xb744560e,0xe43ec373,0x1cf75296,0x78eaf926, + 0x3fa96d9b,0x1809ae0e,0xdc25dfd5,0x0b312d2d,0x6bab7711,0x6b8f78b4, + 0xb5ecf1e4,0x069efc8d,0x609fecaa,0xc1952bae,0x5f4dbde1,0x43e302ed, + 0x1e078555,0x14b02bf9 } }, + /* 219 */ + { { 0xb87e5b57,0x2c71c768,0xf531a557,0x0bcc78f7,0xf7597dc8,0x4ff93f8b, + 0x139e175f,0xb28e026d,0xcb94ca6c,0x6b83b727,0x0079f7fc,0x2eafe3b2, + 0xcf3bd170,0x2aca54de,0x6af0dc6c,0x17c4133c,0xccf5e35e,0xbea1e665, + 0x345505c6,0xa6691a48,0xe6100b89,0x2633abd0,0xc17d0388,0x966c6706, + 0x1a0cf90c,0x7aefffbe,0xd0add64c,0x4d847be7,0xaea2aa46,0xd49bcdfb, + 0x2cc7d0a5,0x85e07e74 }, + { 0x0bc25bca,0x23aae0a6,0xe44f64ec,0x6e8e55f1,0xb607b773,0xe1e696d8, + 0xd3005909,0xaa90a746,0x2cbc4990,0x072b1ccd,0xc68e2f5d,0x0d0fe6c6, + 0x53e28ec9,0x920ec5f0,0xf0040cc1,0x79b21fb4,0xfcc4a2c7,0xa7375bd3, + 0xe1bac7dd,0xf5f5def9,0x35c0f8d3,0xdc315d79,0x2cacd318,0x7117c170, + 0xe926f71c,0x6f2823c4,0xed02f39a,0x38db58bb,0x7db69323,0xe5b49231, + 0x8d49f430,0x0964039f } }, + /* 220 */ + { { 0x56999eba,0x21774f16,0xb1de6305,0x3d8ee287,0xde0b2669,0xd81af726, + 0x3f8942a1,0x37446939,0xea03e13c,0xbcf6b615,0x94e273cf,0xd30c0c35, + 0xc6725c56,0x4fd33a56,0xa8be97a2,0xa57534ad,0x7c22a251,0x799242a6, + 0x9d0c5c49,0x4e51bdb5,0xc6a42768,0xd7cd76cc,0xd426bf59,0x914097ac, + 0x66e9beb2,0x59404a2c,0x5c96e3e9,0x4738fe98,0xaad666d0,0xbcbb3e0e, + 0x63bc5e56,0x626b0fd2 }, + { 0xe1a1ec42,0x47217dba,0xab5acc50,0xaa6ae7db,0x865331d1,0xb7e1ab1e, + 0x3d30126f,0xb8453070,0xdee61851,0x280649e0,0xea689544,0x8806f4a3, + 0xcb56f632,0x4bbe43ad,0xbcaff94f,0x036b9bda,0xbd0637be,0x0d941e65, + 0x686f3abb,0x82179d44,0xaad6afd6,0x1486912c,0xff7e1534,0x9a3b891e, + 0xeb86fd96,0x88c426ce,0x117928c3,0xb56e6a81,0x96399e00,0x933e7135, + 0xa17b6ac1,0x09bbddd9 } }, + /* 221 */ + { { 0xe4fd3673,0x75e39c1d,0xa65c8e07,0xf880d9d1,0x7289c7fe,0x4725c1dc, + 0x3529d200,0x5b6735ee,0x3c747af3,0xc1f8f2ed,0x912efdf5,0x5cf3998f, + 0x49859c39,0xed722618,0x0e69795d,0x23793a2f,0x86b1d2a7,0x8a6ab8d6, + 0x22a882e4,0x00c815de,0xf9db8d7e,0xbe77d6fc,0x02267547,0x0886fb32, + 0x49c10edc,0xb62687d4,0x7c83ed4c,0x9f1c3e17,0x5af366ea,0xe6d5d7f0, + 0xd1efad24,0x2eaa01b8 }, + { 0x1f357c74,0x5e47fb70,0xa9e3b794,0x93085c4a,0x6e85a905,0x4f098733, + 0xbe0244c9,0xf53808ff,0xa3b5660d,0x91dddf93,0xf3b95ed6,0x8b76377b, + 0xbb3920d4,0x91b911b7,0x86a13cf3,0x7ccf08bf,0xea018e58,0x53ed8f97, + 0x78c55194,0xb1ea4343,0xe0d2d5a6,0x8e6adde9,0x9b96259a,0xfc2b248f, + 0xeef17ddd,0x96ebceae,0x557f9c85,0xf694b443,0x07d5bba8,0x48cd150f, + 0xb4c1986b,0x02d31de9 } }, + /* 222 */ + { { 0xde79499d,0xa6bb9e1e,0xfd0fc2ad,0xf6ca8ff8,0x1a7d9356,0xbec0f8e8, + 0xe8f06327,0xbc3d1c9f,0x3b300beb,0x805c7217,0x413c181b,0x00420a08, + 0xf0ca9d01,0x9e9a167e,0x1aeeddd6,0x076c909d,0x8e3a8a72,0x64a1997f, + 0xa77b429e,0x3ce7f7a7,0x5c94d3e9,0xaac0fbf4,0xe6d48407,0xf37694a7, + 0xa91921e7,0xf56679e2,0xee1dbbd6,0xf23fe0f3,0xcbf9fa99,0xc7917566, + 0xe0f4d765,0x965860f2 }, + { 0x7fa5f79c,0xe734702b,0x5af2d26d,0x930bd426,0x6c73e0ce,0x45bd8b98, + 0x4ee44a2d,0x7dbe7bed,0x956c8a1a,0xc129e024,0x77cdf80e,0x6fdc05ac, + 0x589ca59b,0x70a6ba2b,0x999825af,0xfc484021,0x7a23f0b6,0x1d284b54, + 0x28a0a8af,0xb1da10a4,0x2b2af6d8,0xb1eb1b31,0x33935ee3,0xf051443a, + 0x8effa6ec,0x7a07eb26,0xd662654c,0x16ee4086,0x4549ee4c,0x7a7bc501, + 0x1fa98a52,0x65081032 } }, + /* 223 */ + { { 0xb67ed9b2,0x49f0e460,0xc36d93d2,0x0cda0fd0,0x88c75e1c,0xbb5963e9, + 0x614bc0c9,0x757bbe93,0x9a768605,0x9a9b8801,0x48edc544,0xa8b7e2af, + 0xb51a5985,0x9e77ed9e,0xebbf024c,0xdd025274,0x1545c636,0x598b6288, + 0x4800dba0,0x39bdaed0,0x81e2a23a,0x7fc20139,0x550cb4f2,0xdc66fd5c, + 0xb52068c7,0xad27032f,0x8169fa15,0xc9a0bcae,0x3a7ca8a2,0x60606f21, + 0x9862652f,0x98295046 }, + { 0x2e11c128,0x3e374600,0x0e6dca7e,0x80dfae5d,0xd9552264,0xe44016e2, + 0x880b7143,0xf65f88f2,0x526b881c,0xca3d28d4,0xdfb86afe,0xf9c59dd1, + 0x4c74f958,0x548860c2,0x9cb69f4f,0xd06ea43c,0x7334ecec,0x5343c9ae, + 0x35329713,0x5cc2ccd6,0x5f3a6c0c,0xa95ff403,0xb372653b,0x2e01a1cc, + 0xa250523d,0x31510fdf,0xa6227eb2,0xeee538e2,0xca23cd10,0xeadfc8a0, + 0x3e78f54b,0x4b7e6e1b } }, + /* 224 */ + { { 0xdb5f928b,0x79c9076f,0xb7347cec,0xe6250bb6,0xac00ec41,0x54b67798, + 0x9d9619c7,0x900d20ba,0x59e4343f,0xed42c0d0,0x451935d7,0x3df39e85, + 0x64f701ce,0x26391182,0xe1f87aac,0xce8f2554,0x65f91aaa,0xfddd6789, + 0xa324539f,0x96cd163f,0x4bace995,0x5c815f2c,0xa94f9ea5,0xd78c8c2a, + 0xef24e455,0x7ab2aff4,0x1cddc26a,0xf0ed6409,0x00ca2822,0x954a420b, + 0xd3297658,0x0611c4c5 }, + { 0xa9e81829,0xf192001c,0x08a282cc,0xded33320,0x8f9ded9b,0x0bfd7de1, + 0xb7889003,0x6793ac0d,0x3577a5dd,0xbb00d91d,0x802d3c2b,0xe17a23a7, + 0xfb549014,0xff95f88c,0xc71b6e07,0x7cd1bf4b,0x23588c8b,0x2e3b24a0, + 0xa4112076,0x9b5335b8,0xc4056d30,0x2481c05e,0xe916a1b5,0x55c7410c, + 0x850179f4,0xbbe03271,0xb3cd1208,0x15e6c177,0x90cbfe50,0x509a24c0, + 0x1c108566,0x82079529 } }, + /* 225 */ + { { 0x1c7d353e,0x5d2d3cff,0x7de0ce3b,0xd5e7eccd,0x6ca87635,0xb4b1075f, + 0x25f9ad3e,0xda8404e0,0x205cb5ae,0x6b963e89,0x09f221a1,0x9e5ee0d8, + 0xea41aca4,0xd64c85d9,0x34442a34,0x6a46c4e9,0x3cf655a4,0xac6ff97e, + 0xe5417d7c,0x76565c1e,0xeebf9c4c,0x681009a9,0x88da6388,0x95b61d39, + 0xf6b472c6,0x6402b46a,0x0b7f1171,0x1fde5165,0xbe0c05e3,0x94f8f273, + 0xa88344a7,0x7487b036 }, + { 0x9c3e2370,0xa860e575,0xf8048719,0x19d58193,0xa6e2f9aa,0x3a0dbf3c, + 0x6144719b,0xb6c7e959,0xdeffec21,0xa9049c74,0x3f50cebf,0x8ba064b2, + 0x49a1de15,0xb12822c0,0xb1d527f2,0xb654b7d9,0x0ffd0430,0xc470859d, + 0x4f05446b,0x37c74a67,0xa3add995,0xe553251b,0xe33533b5,0x4a3ed6cb, + 0x27e419ce,0x2f2f44d0,0xa5d1b979,0x2d84ee82,0xdb6fa69f,0xcc76b123, + 0x21fa3bdd,0x834f85c5 } }, + /* 226 */ + { { 0x2ce9b31a,0x329347c1,0xfe3fb3b7,0x1d88522a,0x52ff90fd,0x4bcefb4d, + 0x2b1a081d,0x53b17386,0x2a411f08,0x538c11ba,0x141b603a,0x7895b93c, + 0xb10bd741,0x2993b9aa,0x09912986,0xccbbd046,0xeea0aba5,0x669fafb0, + 0x35661897,0xd4844622,0x367ffa54,0x4a63b89c,0x1c3478da,0xcbad5d1d, + 0xaa6034f7,0xc5339227,0xe61b1391,0x0e6d705f,0xf74ff515,0xdd14b660, + 0x5332b54c,0x639d8b0a }, + { 0x162217cd,0xfa423162,0x811c28e6,0x2e0e4a2a,0x21766dc0,0x68d9ce18, + 0x046a06ef,0x51263739,0xdde92101,0x44eea231,0x114298d3,0x0607c8f2, + 0x63d957e9,0x27f272ba,0xa5e8cae1,0xe7ce80cc,0x24f7a63f,0x5816ebe2, + 0x89673e34,0x4dece5a7,0x536babd4,0x13756a22,0xe3bf77af,0x644d61ae, + 0x2bcf98bc,0x60b2bf6e,0x29fa962c,0x3b0b59f3,0xabb50023,0xb0769a1a, + 0x0c75402c,0x40903136 } }, + /* 227 */ + { { 0x1670433f,0x84d2873a,0x25493dfc,0xc9394df6,0x80fcf89e,0xeb05a19a, + 0xdb297616,0xe39e4310,0xd9e63046,0x50742dc9,0x1de9ca9e,0xf31ad8c8, + 0xfb7b1d0d,0x86aabf94,0x1b3c82d1,0x36cda27a,0x39702d84,0xfb1a2ef4, + 0x46081299,0x280bfddc,0xd2396238,0xe4b2b48d,0x7b3c9353,0x2db2c2f3, + 0x12fb8a69,0xd5b5b317,0x08180474,0xf9b87a3b,0x1e952578,0xd8590986, + 0xf37a2bc8,0x80668eed }, + { 0xb39a0249,0xe2edcd35,0xb2f8aeae,0xaf230cd4,0x7223df05,0x295b15e4, + 0xe0e937f4,0xbb66982a,0x8cbc9162,0x019d2b72,0xcf49dca1,0x5c512ae9, + 0x630f07b4,0x11b491a7,0xa03874e9,0x48d4f34c,0x44cb7433,0xc1fd0ea6, + 0xf95b30c3,0x13f79ae1,0xed8b60ac,0x40362d4d,0x61ead81c,0x9e8314ff, + 0x498c3d28,0xed600dd4,0xc2521702,0x5fcb1c19,0x3a9c1f33,0x592329fc, + 0x1bde6ce9,0x04677548 } }, + /* 228 */ + { { 0x39233c96,0xee3de56e,0x80737eaf,0x868c409c,0x201abc68,0xacae11bd, + 0x2b486205,0x0f2cea9b,0x6f19056c,0xe32387e1,0xa5dc2a41,0xea75365a, + 0x12b4be86,0x76c29acc,0x8d63294d,0xa01fcab7,0x0cab9f24,0x81dbe88b, + 0xf414c054,0x76646e5b,0xcb96b7aa,0xfe111893,0x7664e097,0xb649f5b1, + 0x53fcf5a9,0xa196422e,0x0b7ff634,0x5978c9bd,0x3c229895,0xb5feb38e, + 0x0833c456,0x038a49fb }, + { 0x13e93257,0x35e3818c,0xa612741b,0x14cebc9d,0x7caac06b,0x4f6e9249, + 0x3daa1116,0x82278e33,0x4de2034a,0xe7cc565e,0x0a1ba630,0xbb7dc95f, + 0x66956fbd,0x81dd9f23,0xbb132dd6,0xc63e6319,0xfc241337,0x6e22b022, + 0x7e8beb1c,0x23848193,0xd8c938ac,0x83b1994d,0xa6bb5644,0xb54cfaca, + 0x06f91807,0x1a7cd44e,0xa8f8d9f3,0x1dd439bb,0x7f74a8e6,0x660c2a78, + 0x121b5660,0x4bb76e22 } }, + /* 229 */ + { { 0xe6354817,0x7a151e8a,0xf038b438,0x33d494ea,0x85958986,0x4c86c688, + 0x1dcbac12,0x72153827,0xc0edad06,0xf487af8c,0xe500e5d6,0xad33051f, + 0xd6e47f55,0x0a711b1b,0x8c746ad5,0xa68709a7,0x6402f35e,0x27f17262, + 0xfb30c130,0xc6d08efa,0xc06c7497,0x9ef1c041,0xdcc3e2da,0xd0c74ece, + 0x092e1073,0x30c5f96e,0x2aa12b74,0x0f1393cf,0x2107eb02,0x24584016, + 0x7b76f98b,0x8843d25f }, + { 0xedb2a83e,0x4e1501dc,0x2bb8d724,0xbcfe8fb0,0xd925df62,0x09020659, + 0x42ab6fc3,0x3c715dcf,0xa0f09dfd,0x73c05055,0xe3590aea,0x126745d8, + 0x76ff749e,0x5382f4d8,0xa920c663,0xfc69feef,0x9fd711ca,0xde160211, + 0x9075c4d5,0x4219c3bd,0x3ded6bf2,0x3800cbd1,0x6263a116,0x8c7ea0eb, + 0x7d264c37,0x35bd7958,0x7159c98c,0x56e22e45,0xfa7373b5,0x71bf2a2d, + 0x8935c949,0x0503f939 } }, + /* 230 */ + { { 0x71dad4f6,0x65addc66,0x024bea1b,0x238e4889,0xf605d3dd,0xfb76c8e2, + 0xb0d96b89,0x13d5f5de,0x6601b2cb,0xe0b5ba35,0x83e3d254,0xe37d491d, + 0x240c8ea7,0xe8860423,0xe91c99ba,0x374182f3,0xa87ad919,0x26c2caf9, + 0xf574f295,0x4b13040a,0x944000a3,0x5b9bced1,0x06df42e7,0x4ccc57be, + 0x4bd1089d,0x22e8ec50,0xdddbb500,0x0c53177a,0x9ecfeadb,0x690d31d2, + 0x176668f9,0x735778fe }, + { 0x843c1137,0x0f86ee3e,0x3f0b73cd,0x3c1c42fa,0x8ab20e3a,0x0e75679d, + 0x16242fae,0x6f95f1f4,0x39b092e4,0x7b88e11c,0x4c236ac0,0x1629403e, + 0x2dac02e6,0x66105f41,0x862e0632,0x74dc28a7,0xf3b23c8d,0x2118ffb2, + 0x0745ffbf,0x1182417c,0x4c05711e,0x49b55a04,0xcefbe4de,0x2c665b74, + 0x97bf7107,0x1cc4c01d,0xc54f0676,0xb2ca06da,0x7450d0f8,0xfc599daa, + 0x1a3182a1,0x52e637a6 } }, + /* 231 */ + { { 0x6bebc6db,0x481700f1,0xf9503d92,0x4a6b45db,0x5d153919,0xc715cd3c, + 0xe5ad2abc,0x942a1c05,0xab7b466f,0x36a82433,0xba13918b,0xba413bed, + 0x90f4e6ce,0x698a5624,0xf3f1f3ca,0xbb720da6,0x63471ab3,0x2116d41d, + 0x303d3609,0xe00d2227,0x463ba69e,0x7fd4cc00,0x62845fd1,0xac609e4d, + 0x80adc9c7,0x63603b2c,0x45fafbca,0xbf16fc9a,0xc4bc94ab,0x41007f7f, + 0xa74b1698,0x7c916b4f }, + { 0x78bac2d4,0xc1026f91,0x2601a875,0x8a2e8098,0x0073d640,0xad2f276e, + 0xfcc1fb88,0x443610c4,0xca6b291f,0x5727b822,0x88ec60fc,0x0645532c, + 0xed9ad48b,0x51e48899,0xf543f103,0x841b48b5,0xd591ceeb,0xa6ccb1be, + 0x9dcf5a8b,0xfc4adf0f,0xb347ddb4,0x3a7ca020,0xcb44c521,0xaa1accc2, + 0x0527c0c4,0x773b6828,0x7023cf50,0xaa374c10,0x6b74c926,0x733d1000, + 0x77a8d07c,0x1ff3916f } }, + /* 232 */ + { { 0xf997939d,0xaa218fe4,0x791583b3,0x3d4dfbbb,0x87f7560b,0xb3a7b5da, + 0x5da92c98,0xa9c02801,0x46666f4a,0xe1eb4aad,0x14ce9dd7,0x2eb17a51, + 0xef8f3076,0xf46a66a4,0x810e546e,0x900b45c6,0x4baf04dd,0xf7af2258, + 0x5c84d42f,0x3cc1c872,0x8e4c83de,0x3093f225,0x170d88b2,0x62fade41, + 0xac076e44,0xe19612e4,0x32dd141b,0xf48d7346,0x925e34da,0xc1b1f759, + 0x072b90c9,0x19ed1a56 }, + { 0x6c735473,0x9cf7fcde,0x6003bc3e,0xaab88e67,0xfb199bb8,0x12187cbc, + 0x9accccbd,0xbb730441,0xb0f65459,0x214aff3c,0x6f926282,0x6aec81a3, + 0x9f9d20b8,0xaa82cb32,0x5773cc90,0x82f3f90f,0xf62257e1,0x4af60e6b, + 0xbd4762df,0xf18b44bf,0xdb970753,0x3948b129,0x7c22c18e,0xc6e920e9, + 0x57be97ad,0x393d6208,0x46b637f9,0xe8d7382c,0xf1fed1d5,0xf6625ccb, + 0x68681599,0x6f31e0f9 } }, + /* 233 */ + { { 0x82b8f204,0xc45afe55,0xd358b54a,0xac0441b6,0xacd5f5ed,0x7213e7bf, + 0x139bcd93,0x1914c70b,0x96dbcbb0,0x714b4581,0x1ed35d21,0xe9297d35, + 0x6a3e1f20,0x8f640837,0x2f3cd705,0x150a8a9d,0xdcdd9f6d,0xfb36e801, + 0x5cf56d82,0x5a54eb65,0x92aa5a21,0x7610500c,0x3b089f03,0xd10d0ae2, + 0xc42b66e8,0x491b2079,0x0eee8d48,0x4af1ae3d,0x41556f45,0x137e4c28, + 0x63d8a7e6,0x875e3308 }, + { 0xaf6c0acc,0xdc80fddc,0xbb1e7c08,0xd5ad1e66,0x828585ad,0xdc717ae1, + 0x275c7da6,0xbdc54340,0xd26b9e15,0xf4b4c852,0x6a05fa50,0x5f0a1fbf, + 0x817bcb32,0xc6f81e47,0x70ff2e1d,0x2cbd4328,0x67c7f7fc,0x8a249016, + 0xb585a6c4,0xd045acb7,0x4666c057,0x2e972ad4,0xe6d7d63d,0xc74d87cf, + 0x0e274144,0xf7067d87,0x8b2584ae,0xb2ca157a,0x75f0fdeb,0x495c5bfb, + 0xf386e009,0x5abb0581 } }, + /* 234 */ + { { 0xf0c97f57,0x8be62d2b,0x962f28c7,0x0fe04871,0x47b50abb,0xc548a467, + 0x44fa09ed,0xf6b26e03,0xab05a96e,0xfd44c6e3,0x70e6ae82,0xedb0032c, + 0xd7e4899d,0x28bd402b,0x9b7c11c2,0x43f2e963,0xce913716,0x0ec3fc0e, + 0x02fd0f8c,0x769b8bc9,0x7cabc3ac,0x9d9cb3aa,0x06924cc9,0xe88a8892, + 0x42609014,0xa51461aa,0x962e79e0,0xc7f4aa8b,0x8b1b3e80,0x4ef0210a, + 0x1bfee4bc,0x70544680 }, + { 0x121901c1,0xfab3d713,0xfead54aa,0xe90a2627,0xbc08ba23,0x64f6d285, + 0x36ec227e,0x8d993015,0x06c191ab,0x99a16ab9,0xf649ce2c,0x86b1cf5b, + 0x66be3a80,0x59206759,0xccba2cf0,0x18836279,0xeff53486,0x2c157b87, + 0x4b223af2,0xbfac9896,0x0aae7a57,0xcd0fd4f0,0x63218a80,0xdaddb940, + 0xdf88f14e,0x3844bb79,0xb71ed9fd,0xc1b3e3d4,0xd6205036,0x6c634a13, + 0xb8680a6b,0x6f56aecf } }, + /* 235 */ + { { 0xd9205c5d,0xb01dc803,0x67123929,0x68955f7d,0x9d9b6565,0x3debbffd, + 0xd3b1acfe,0xb844395e,0x6094eeff,0x04328b21,0x22991feb,0x6631ffa8, + 0x190dd075,0x0dde66e6,0xe8577c05,0x75b03c55,0x91722407,0x6c91ce5f, + 0x8ebb3a3f,0x9a288a40,0x058a1396,0x1d376f8a,0x9a6e0676,0xf3a59457, + 0x7b71d288,0x103029c5,0xb44c30c0,0x0843f428,0x730e0b9c,0xd8e6aff8, + 0x4ed644ad,0x7b6be811 }, + { 0x3d3aa54e,0x3ec38e4a,0xd83d509a,0x10233943,0x243955e2,0xf84aa621, + 0xf51d3d44,0x29104717,0x7eca4e37,0x62d2442c,0x85fa55de,0x8c5a523d, + 0x851da1b5,0xc6f5ccda,0x20001468,0x044bcaa8,0xe01702e0,0xf7501e68, + 0xe6a0acec,0xf0819359,0xac0ef0b2,0x33dda6ad,0xfd964f01,0x97aeedc8, + 0x530b90d8,0x48dacd0e,0xb84122eb,0x4c5fad6f,0xd700a1de,0x2284ec1e, + 0xdbca5474,0x86f9a835 } }, + /* 236 */ + { { 0x450cc69f,0x0e1d9055,0xc9edf98f,0x50eb14bc,0xee7eba01,0x1bb94e77, + 0x998f8e53,0x5f7a6737,0x1b16eef0,0x588384e3,0xd85c5e15,0xbb928723, + 0xcbd952aa,0xfe51e345,0x7e241674,0xc5d0ee28,0x100182f0,0xfdc146ef, + 0xe7f5be2c,0x0f739e92,0xb656bd3e,0x501ab3af,0x5168e289,0xb1552dde, + 0xb8ee104a,0x940dfe31,0xc4304475,0x42923603,0xc460a913,0x9306f114, + 0x03b51f86,0x5bfa9faf }, + { 0x107b258e,0x2a23f52c,0xd66341dc,0x989e82bb,0x823cff1a,0x54a3ced8, + 0x719b491f,0xf45b7794,0x2433dfb8,0x898c2218,0xc49250ee,0x0f9dd91c, + 0x4fa17655,0x50c2a2ae,0x2c327f45,0xf7aa1ce4,0x583b1e41,0x13a15ad6, + 0xa1bfad9e,0x9aa0d5a5,0x8e1fbdcd,0x9b1caa28,0x915f7f87,0xaf9283b6, + 0x87e81a1e,0xc10e4e0c,0x1080d296,0x04fdca56,0x12755bd8,0x6acc9616, + 0x828feeda,0x1b1266aa } }, + /* 237 */ + { { 0x774ee49c,0x4ebc0a00,0xcb6237d7,0x776f6852,0x5df938a3,0xfc0544ac, + 0xb6fbfbbd,0xc3388ec8,0x745f2eae,0x84ac8bcd,0xb1ece937,0xa9c56609, + 0x7de8fa13,0x656fb6ac,0xa532b871,0x5f8ded74,0xaa889f09,0xab0d428b, + 0x10b7aec2,0x43b27f28,0xfeecb34c,0x26426e1e,0x9e89c2db,0x44431b6b, + 0x39211090,0xaac4bc5d,0x4fd81058,0x926f7368,0x471ef60e,0x452fa691, + 0x218d7a23,0x33517fdb }, + { 0x593c4a36,0xa9c33f46,0x36b1a9ee,0xac69d718,0x4277beec,0x55a20c1d, + 0x7e4f179c,0x3e8ca24e,0xd46d88a2,0x57373369,0x730702f8,0x71ceb1cc, + 0x35eed574,0x8b184d97,0x0704cec2,0x7f4517a2,0xd7062a53,0x7f129d18, + 0xb1d77e1c,0x07a4571b,0x8350d8b2,0x774ac309,0x61fab8ef,0x27b2919f, + 0xb5dd801b,0xa7c4cc13,0x1434591f,0xe7e6255b,0x5a3592b3,0x349937b8, + 0x30c77549,0x31fac63d } }, + /* 238 */ + { { 0x04913fb6,0x2ee8cf1b,0x1769a6b3,0x7e401350,0x783e61f0,0x790ebb71, + 0xe27f2ffe,0x1e5107f9,0xedaf89bf,0x124ba67f,0xe58de68d,0x189200e1, + 0x6df5abee,0x962732a3,0xacbeb4aa,0x72cc37cf,0xe93c5a76,0xb0c5fa96, + 0xde63393b,0x4c2a317c,0x830b2d6c,0x97f65e67,0x1be5b96a,0x4afc3504, + 0x730ce66d,0x0bf40a60,0x9340d84f,0x96a1ba79,0x07626b08,0x3ee18254, + 0x7ab0cbf5,0x01db35db }, + { 0xac0efee2,0x6e0fbc2d,0xd71dbb45,0x8406ebcd,0x19b69abe,0xe72bde3e, + 0x37e01822,0x49cb7e61,0x11458b4c,0xcbb8c01c,0x687c5d63,0x420b4847, + 0x454c6776,0x1847dfa1,0xd1839d18,0xbede911d,0x278df046,0x1b9dc9c9, + 0x881a336c,0x294bd62b,0x93e77adc,0x7f096879,0x43ce3ba7,0x7ac90665, + 0x7764eefc,0x148695fd,0x9ac465cf,0xe0c20f0b,0xa6e2cdb1,0x636e8d28, + 0xd755341d,0x7b6ba98c } }, + /* 239 */ + { { 0xc1881ab4,0xcb1d9e03,0xb3168c88,0x19c25d55,0x282364ce,0xa82d3d47, + 0xf161aa24,0x95994390,0xe1ebb2c9,0x7838bc00,0xbdec7a75,0x8fd5dfcc, + 0x4ff7220a,0x4dd203c2,0x0efeff48,0x5ec173b3,0x16428b35,0x99f1d2b3, + 0x056e813f,0xc06bd9e5,0xc0b319f1,0x929172ba,0xfd223b15,0x6ae0e384, + 0x98d091ed,0xbd01059e,0xa654648e,0x6b3168e4,0x3375e798,0x2211447f, + 0x71eb4508,0x47e81019 }, + { 0xbc8c290d,0x7045d45a,0x810fb33a,0xa33d1355,0x46fbbf2f,0x2baf0092, + 0x385c7cd9,0xacff3f1b,0xe161985c,0xc5b150ec,0x2a888748,0xc6ee0a7f, + 0x5e88dcc8,0x9d888c8e,0xccb86443,0x4dd735f2,0x3c40f6f2,0xcc1e13b7, + 0xf3fed691,0xfc3a25ff,0x257ee5c7,0x4cb43b17,0xf32db135,0xaa654f93, + 0x02dff2d3,0x44f58d0a,0xa8ca6394,0x78e3f188,0xf3e86697,0x39646cce, + 0xe0dce87b,0x785b1902 } }, + /* 240 */ + { { 0xa92f9a20,0xfcce2361,0x9d64540e,0xb7bdca87,0x1d00d7c5,0xd4739a85, + 0x2e97c926,0x067ac8dc,0x78da6a8b,0x2aea3ffe,0x63c51b69,0x6828bf54, + 0x7155141a,0x76f1c479,0x3977d810,0xf4bcbef6,0x541bce7a,0x75bc4949, + 0xd17041a5,0xe01f4066,0x87755eaf,0xd282d5bd,0x59e7ae80,0x6e2107dd, + 0x382ab36f,0xaa56e166,0xb9d1d634,0x65ee8ef6,0xce4ed844,0x99a2160a, + 0xb7712c27,0x6557c367 }, + { 0xd75b6e52,0x561b0268,0x118d0e89,0xb0813640,0x6a2eb1ae,0xcff53330, + 0x6d090894,0x4e462226,0xb5fc1d48,0xbb351227,0x57a3062d,0x9365ea07, + 0xd66e2dc5,0x4caca37b,0xb9095887,0x220d7d23,0x8c4473bf,0x9c0fd393, + 0x6787da4f,0xadff370a,0xd057f4b8,0xef0aebcc,0x1173f33a,0x205e744c, + 0x925a26b4,0xb8d1f0a5,0x722fbbfd,0xa9364f49,0x8227d284,0xc891ae77, + 0xa0e08ab4,0x15c40d04 } }, + /* 241 */ + { { 0x2a0e18d1,0x9baf169a,0x4c0327c2,0x9971c017,0x7bc262ce,0xd81a323f, + 0x818ff379,0x2099db8d,0x4cd3c330,0x663f663d,0x011a0553,0xef5325c3, + 0xf980a470,0x9cd70bdc,0x1c9ed070,0xe64452d1,0xac676e13,0xafbf43f4, + 0xae85c2a5,0x97bec0a6,0x470490c4,0x2faae550,0x491e6ba9,0x0ab97a87, + 0xaafa9914,0x4055f537,0x36726557,0xfc95adbb,0xd119d6bf,0x646343b9, + 0x9d341e37,0x788e94a0 }, + { 0x9c53461a,0x053a6fe5,0x08e3b6ed,0x75ec897e,0x0768d939,0xa8f5d2f3, + 0xcc213d4f,0x9bd6bff6,0x05b0147c,0x590c7b41,0x7c7b8169,0x20a3628b, + 0x5bce78e9,0xc66a086e,0x4dec1d8f,0x3dd4d282,0xc19dcce9,0x890acf44, + 0xd8435a7e,0x6632d875,0xea6381b2,0x590167c1,0xf0dcc128,0xb2259797, + 0x46f8d463,0x91a612b4,0xc15efa39,0x42185d78,0x119f6788,0xdf55ec37, + 0x780dea93,0x91b19cc6 } }, + /* 242 */ + { { 0xcb5d8b80,0xebf2709d,0xfc35660e,0x03b96182,0x055ef969,0xb873d991, + 0xe47c4342,0xd1ea4b4d,0xd54f8867,0xcc4b9244,0xfd8d77ef,0x93b1a2ca, + 0xe8c1f563,0x068d24e7,0x49973056,0x5f5fabb6,0x0542374f,0x83248c50, + 0x3f38e913,0xc36de2b5,0x7bb680be,0xed07e8eb,0xd8f313b5,0x964813d7, + 0xafd2d392,0x7bb6a069,0x0848a31a,0xc06d848e,0xe4f0c325,0x6867fb2f, + 0x067343af,0x3c2ba834 }, + { 0x9d3ad63b,0xab62d775,0x59e0eb1f,0x3f9cab97,0x3885e117,0x70332a63, + 0xe20b2f9e,0xf22cafce,0x49eca947,0xb529ba7e,0x6228d88d,0x24954216, + 0x39239561,0x80ea23ec,0xd4370644,0x1b8907e7,0x563e4e44,0x4b7fa455, + 0xb2a4b0fa,0xcca9829e,0x48060792,0xd0a720a4,0x246991ce,0x8ccdda0c, + 0x348d086b,0x37a2325b,0xf60aee13,0x566ed509,0x147f253f,0x3d30e091, + 0xc1073bd8,0x1fa627a5 } }, + /* 243 */ + { { 0x42478fd4,0xa11222a2,0x670b2000,0xacf4c6f1,0x8359c6de,0xf71bb04f, + 0x7b93cdbc,0x618e2829,0x230db60b,0x96e1bae3,0x965b3b29,0xf17fd3b4, + 0xbc7055dd,0xa58639c6,0x4b817d7f,0xc3ea92ed,0xd23b08a4,0x9082b2a6, + 0xdc17010e,0x8471228a,0x20e89d97,0x753b9e46,0x03ff77c9,0xcf7e4f97, + 0x2bbe60e5,0x6c3f8245,0xb80e017d,0x9e432cbc,0xc0a45edb,0x150a5acd, + 0x4798743e,0x67b8bd05 }, + { 0xf4797cf7,0xe66079b4,0xd03fde02,0xe31c998a,0x54caaef1,0x5aa3763a, + 0xf7649711,0x64d9a1fe,0xaf29b1a7,0x7ce0dc73,0xfb66ca93,0x6661b083, + 0x32fb6a78,0xbf4d74fe,0xdf00a561,0x25f6ef09,0x831d1159,0x2bc4383f, + 0x536bde37,0x6d5cc10c,0x882cc65b,0xd4945f9f,0x451a99b8,0x81f48f13, + 0x6bac11a4,0x140161cd,0xf18a4a0a,0x9d94d4ed,0xa467a824,0x65363165, + 0xa4c9aedf,0x74297aa9 } }, + /* 244 */ + { { 0xe21124ba,0xc49758a4,0xa87ffbd2,0x99bd8198,0x3d6638a8,0x45fbcdd1, + 0x15f7bf76,0x94645ff8,0xc4e6d57e,0x5fa6736f,0x92e61db9,0x1eae6475, + 0xcbdf944a,0x79575c0c,0x25b31d74,0xa3d13047,0x4cab5ae6,0x7881df22, + 0x1a2887f2,0x8dbfd299,0xa26ac459,0x23d07590,0xd8661d4a,0x2e589852, + 0x8a0140f7,0x37b5c13b,0x3fb3782a,0x0f94199e,0x1bc14e90,0x722aa059, + 0xd55bbb12,0x89aab7ba }, + { 0xd656bdc7,0x8b345a96,0xe176cd3b,0x43bdc8af,0x32d64c43,0xd69518b6, + 0x79b82b41,0xfcf364a7,0xffb0cf82,0x907b344e,0x5101287b,0xf3d0c83c, + 0x34cd90ef,0xe9f26a59,0x07082b5c,0xe5f5aaf2,0xece7c165,0x4eb72c75, + 0xbe986cd6,0xe9590a81,0xff1536aa,0xfeef498f,0xa8263d5e,0x04560243, + 0x54ae872b,0x940be14f,0xe3207686,0xbee7bcc9,0xc1bc4d7a,0xd496a27d, + 0x5940ab46,0x002dc297 } }, + /* 245 */ + { { 0xb69d60c3,0xee533937,0xfe972755,0x260be552,0xc0c725a6,0xb11fb78d, + 0xcab2e7c2,0x6982c27e,0xee2322cb,0x4bceedd9,0x122704f7,0x952b19ed, + 0x854a6165,0x2df4c285,0x7b192485,0xba40b5bf,0x0119f52a,0xfcbca950, + 0xe5add86f,0x7467d1cb,0xd9d0f2c1,0x9bf536fb,0xb8d4ebc9,0x3c296e34, + 0x05a81317,0x0495f8f4,0x73335f76,0x8c59e8d6,0xe0542122,0x0b53d324, + 0x3c3bda73,0x4d564535 }, + { 0x7e5c0877,0x7322f800,0x0ca9a764,0x481b43e6,0xa2c12716,0x231f4f4b, + 0xed3136c2,0x09596857,0x38db30de,0xae826322,0x99908ebc,0x652fad40, + 0xaf0d231e,0x0b8d1814,0x09cbc349,0x2680c54b,0x4bf3bf8e,0xfd4562f3, + 0x092b595f,0x2985090b,0x5e15fc34,0xe6f39ca4,0xbc378168,0x70175191, + 0x845a4a87,0x906944b3,0x82a1541a,0xacc6d74a,0xb155c8b4,0xadc9bab3, + 0x77306c62,0x1f2f89ce } }, + /* 246 */ + { { 0x9affefdf,0x8253ef41,0x4cf9256b,0x05d7ece5,0xb444e483,0x377002f2, + 0xcba5471f,0xb189755f,0xd5cbe015,0xc88483cb,0x6a0b8429,0x254f7c69, + 0x61f3f61d,0x18850bd4,0x0a247157,0x7ba21089,0xd92eeb0d,0x35abbc2e, + 0x965dec89,0xfb56cabe,0xbc55684a,0x9da23724,0x6a7a7492,0xd8ba396f, + 0x2ef4ba46,0xfcb90db7,0x9909b27a,0xdd234fe0,0x76f4366e,0xbdf3c164, + 0x17e50d47,0x09c8097f }, + { 0x60050c07,0x6a04b140,0x43a8e37e,0xc29e8318,0xbb55e41f,0xcb9429b2, + 0x2ce60e3a,0xed2fea5a,0xdb9d82f4,0xdc7b1ff3,0x687d37fa,0x48ebecc3, + 0xecb07539,0x79153e32,0x57075692,0x6a60054f,0x800759ba,0x3871cd0c, + 0x30922df1,0x17a7386f,0x83357b7c,0x4e9fc59e,0x39415186,0x1d26b3a9, + 0xd34db889,0x912a0222,0x59fcdb71,0x6672fcf4,0x44ff3036,0x5a3f268d, + 0x6911e16c,0x6f113ed3 } }, + /* 247 */ + { { 0x1836f1c9,0x52a9df59,0x4232307d,0xfa6519f5,0x5ded285a,0x8406c701, + 0xaf627f75,0x0a1545ca,0xace0417d,0xae1111ee,0xa6113443,0xfb28bdf6, + 0x52dbcbcb,0xde9ef0ab,0x7813e658,0xe9dc181b,0x99127225,0x0b1dabdb, + 0x22814c59,0x5f0598e3,0xd934ee7e,0x5c3b966e,0xb99ba4bf,0x4eb84eda, + 0x3c1b55e7,0xb2919a34,0x94aa860f,0xa9addb49,0xf6811ff6,0x1b7220df, + 0xd1a183e2,0x6636a23b }, + { 0x20587283,0xdf5d5a2d,0xef07fc5d,0x0b3822c9,0x0ef6de38,0x1786bd55, + 0x25d1671d,0x163cf907,0x1cdb1def,0x74bf971f,0x0842fc4a,0x5749e830, + 0x27f854f7,0x0e2edbc7,0xbce24acb,0xbb27bbda,0x05bed08d,0xc1b19cec, + 0xf7c904bc,0xaada123e,0xd89982db,0x02429f1b,0x65f6e632,0x49d3616e, + 0xee59fd32,0xa3789fa8,0xfe9f29f5,0x160ba3ba,0xaf5378a0,0x0f2d3b61, + 0x73c2a6f8,0x7aeecc76 } }, + /* 248 */ + { { 0xdc43b0db,0xf3a4757c,0x98119cad,0x3d8a4e85,0x4616c156,0xf8095bf6, + 0x4f533e97,0x3e2a07bc,0x39cfc5ad,0xa9824367,0xcd68052c,0x18a6ba3a, + 0x8a1cec66,0xbd60e590,0x02b1b695,0xae3841a5,0x190a195b,0x986dff12, + 0xad31fd9b,0x2df2beac,0xcc728f7b,0x7d893224,0x0cf0a992,0xc38ea738, + 0x586a44ea,0xa8439a80,0x1615f03c,0xede7f7f0,0x27a1f885,0x48249908, + 0xb78a7645,0x28ec4006 }, + { 0xa2fe0009,0xe1820c2e,0xf13874e9,0xe11ba5d2,0xc524db52,0x97522454, + 0x7fede529,0x4d477426,0x9b2500d4,0x01d3419a,0x1869244b,0xce08a492, + 0xdd1be1b9,0xba169023,0x32a301e0,0x242c3e54,0x70906788,0x9b56f7ba, + 0xc74a8cc4,0xf0ad2a09,0xd76f9439,0x99cd1841,0x621fb60e,0xeddafe0b, + 0xbc397634,0x056bee54,0xff7f0a84,0x4653f860,0x2011c0af,0x6bd4876f, + 0x0c9525c3,0x134f4cc7 } }, + /* 249 */ + { { 0xe938dff4,0x9621a3ec,0x486a79a3,0x7d101a7b,0xde950537,0xf2c4ef97, + 0xe65d87db,0xf3184099,0x373b8cfa,0xb89c7ffb,0xe842916e,0x68baa505, + 0x4ebea764,0xa790fd09,0xe592892b,0x679df6d4,0xfcfed741,0x2023331c, + 0x9880ff21,0x0bf4efd2,0xd0344501,0x7ca78ddd,0x342858c8,0x2cb09ecb, + 0x2575487a,0x9e5eb6dc,0xebcb0491,0x50675a15,0x7381d471,0x09d2e74f, + 0x83d3d6f4,0x6ea37829 }, + { 0x4e5cc40a,0xc65c094b,0x1af37dfb,0x7a2e3f6a,0xf9026e44,0xef677e9d, + 0x93880f53,0xb7878c95,0x7f644aa9,0x4aa30b07,0x2f208c3c,0xa0c51683, + 0x658d663b,0x7c0277ae,0xae1d9130,0xef0b3c38,0x695c3ea4,0x302f37a7, + 0x6a0c5e0d,0xe004c1c5,0x20cbcf9f,0x9fd495c4,0x568a0e7c,0x706d5b9d, + 0x59286454,0x8b225dff,0x8d9a709c,0x527d4465,0x87c08d68,0x47c558da, + 0xbb4ef07d,0x606ee6e6 } }, + /* 250 */ + { { 0x57c621f6,0x02d99fc7,0x7fe83d48,0x292e40c1,0x9ef199b0,0x1bdfc7a1, + 0xe62c7666,0x78a04102,0xe6738753,0x16cda370,0x1e3a65af,0xbc81974d, + 0xf78fe209,0x19742048,0xbf5981c6,0xc83a058a,0x9c89702d,0xf26b2434, + 0x9d1a678a,0x988b2f1e,0xff29ae29,0x472bf9b0,0x1d7cf5ec,0xa143e398, + 0xb268ddd8,0x9c9d7e45,0x5fc4ff76,0x166cda55,0xa4aa7673,0x6044cdf0, + 0xe9148707,0x49dba6f7 }, + { 0xa758e37a,0x20e47fb2,0x2d8eaf66,0xaf6b31d7,0x6f9c2210,0x352ad5f9, + 0x90efc32b,0x0093f727,0x41e4b264,0x435c99dc,0x05b15795,0xbfa878e0, + 0x0e673575,0x99c520a4,0x87eea759,0xca682594,0xf12a348b,0x029f7b81, + 0x2aa2ce35,0xa547cc18,0xead5e2c5,0xa11d874b,0x55682cdf,0x9af0349b, + 0x8bbe8e66,0xf86ebfea,0xf55394ab,0x3dab8782,0xebc8eb8f,0x458bf797, + 0x9b7de78c,0x4890a7a4 } }, + /* 251 */ + { { 0x8da995f6,0xd7299689,0xec6156ef,0xd39eaae7,0x356a82d5,0x6959040c, + 0xc135bcfe,0xb2046b21,0x0f595c78,0xea720b64,0xe7c5fb40,0x02824efa, + 0x0edb3bfc,0x97d8fd4c,0x79f24ebe,0x12f02905,0x187ea6b9,0x16fc47cf, + 0x789d5c23,0xc219fd27,0x89263ecc,0x233a6b6c,0x8b6d30a6,0x823634b2, + 0xc9b33680,0xca352e25,0x40c77456,0x9388d6ca,0x3c92065b,0xf8e55b0b, + 0x02439a76,0x5c17474b }, + { 0x8aaccab5,0xd888e7c2,0xaaced05b,0x18027836,0xccec0f65,0x185b877d, + 0x125c2882,0x93cadc1c,0x67fdc54c,0x45df540a,0xc2788a33,0x4f3c86e2, + 0xe3a0fa2c,0x3e874469,0x273983cf,0xc59daa47,0x4a96d8a5,0x3063c48b, + 0xc2e58915,0xc38d2bcf,0x84e428c3,0x90e78b87,0xf0c4fd53,0x900a292c, + 0x941e6005,0xb7f92db7,0x6ca53a1c,0x95679241,0xb1ab0fa7,0x35f6f31d, + 0x7b58408c,0x5d675eb4 } }, + /* 252 */ + { { 0x870c6025,0xaeee1a77,0x91a2dfca,0xfc4a23b7,0x386b64c4,0x7b0e60c4, + 0xe5ae72b1,0xd5d5b17d,0x9eefa212,0x6dfc88ac,0xd4038b96,0x4feaefbe, + 0x8e2d2ecc,0x099ac356,0x012af207,0x548ea612,0x89c31218,0x4ffed9db, + 0xe0e67331,0x1c1e91c4,0xaf8300e0,0x009bb64f,0x6773c3be,0x8780501c, + 0xc08219fa,0xe0cd6ede,0xf81b06ff,0x7c055e07,0xe080b36f,0x82b63f9c, + 0x0a9feca3,0x02fccbaf }, + { 0xb47cac61,0x9991d4d1,0xab86e12c,0x2e9d1687,0x2b94f042,0x8c6855ec, + 0x48e648e5,0xca400519,0xef89ac57,0x9ba91fb2,0x1be792cd,0x4f419206, + 0xbd0f1e15,0x82d221cb,0xfc444019,0x062eb13b,0x99790fdc,0xf3a97c32, + 0x6067a64b,0x4e796d94,0x6d23775a,0xc46dd300,0xed7f0f23,0x8672c4d5, + 0x3b4f63d7,0x821851dc,0xd26273f2,0x50a3ae0c,0xeac60f6f,0x800e58fc, + 0x13845545,0x56f1e456 } }, + /* 253 */ + { { 0x32c24f3b,0x01ccb3f6,0x06d817e6,0x99eb1c7f,0x6aa26776,0x8dc640bb, + 0x0845d5e0,0x7838affe,0xf81a79a8,0xf34fecb1,0x3e6819b0,0x6a2e282d, + 0x8237a4b8,0xc4b977ce,0x87636439,0x0f46b3db,0x97970497,0xa465f540, + 0x8791be43,0xd7e08762,0x34198ec6,0x00220b6c,0x093d94bb,0x57b38637, + 0x29d690b2,0x84012e16,0x20aad1a4,0x02ec9db5,0x85dc34e3,0xafee2fc6, + 0x25500cf8,0x911d1936 }, + { 0xf5e5af5b,0x13b1bd58,0x7b6a22a7,0xa7ca263b,0xf3af2adc,0xab6bec4d, + 0xa04420bd,0x16651e59,0x4ba36c11,0x3b448b3b,0xff424310,0x3c62bfcd, + 0xf1a96cbb,0xde15c4a5,0xe4d1f980,0xbe0ad8a1,0x36673a3a,0x812bd14e, + 0x9212acdd,0x40303af6,0x576095ce,0x8f6dab9c,0x107f5ca5,0x7df1882a, + 0x8896a3b0,0xb903e63c,0xd863b3f0,0xf5048544,0xc09887de,0x5e5019b9, + 0xa0f53865,0x2be744fe } }, + /* 254 */ + { { 0x5b50f324,0x054cd05f,0x1ea3c7a2,0xb9b1eb24,0x7ff8e6b7,0x4a858a5c, + 0xec040882,0xd83902fe,0xd0cba9bd,0x72b26494,0xb29c9e1e,0xd0176f90, + 0xcebadb81,0x05d4eb02,0x372b8bfc,0x874405b1,0x79ead190,0x5c412881, + 0xec2b48cd,0xd44a3dd3,0x3f4d5033,0x84499a77,0x564c3a09,0xb37b38cd, + 0xf42e803b,0x80e99497,0xb8f518b2,0xc07b47a0,0x3568fde4,0xc710e3c5, + 0xcead0e7a,0x735f542f }, + { 0x38380039,0xcaa9a171,0xf74d19c8,0xadfafe17,0xccbc1a8b,0x92d4393e, + 0xfe029705,0x3c5dbf39,0x930e9b36,0x4552b5ab,0x2afd494a,0x7ee63032, + 0x3f02ac43,0x826a9ad7,0x99356298,0x98c53562,0x7342bb39,0x0c869f87, + 0xe4f9b79a,0xd7510020,0xd34789a9,0x6361d1a4,0xcfa85637,0xf0ded5ba, + 0x88ac07e4,0x407ee73f,0x09ef1cbd,0xfac7d03f,0x4d475bad,0x25d697cb, + 0x14bd399e,0x1e984c9d } }, + /* 255 */ + { { 0x4850c817,0xc76d0561,0x3489812d,0xb08a5b19,0x5e58cbbe,0x7273d154, + 0x4be61e5a,0x8900b5fa,0xd7aeb8e1,0xaa088691,0xd35a3d4b,0xe66666af, + 0x57ec7d3d,0x38a2c199,0x668d6f5c,0xa0648e8f,0x7adc1746,0x1f9fc92c, + 0x843065c3,0x23a116c0,0x61e6ae69,0x36370a20,0x2aa47e73,0x626c3736, + 0xdeff6d84,0x540c25f2,0xcdbed2d4,0x9804824c,0x039a9492,0x4b5bfce0, + 0x76942e01,0x6c474a56 }, + { 0x7d88e3a1,0x3aeb9a41,0xc484742a,0x105d3c88,0x3fe61131,0xe59de8d1, + 0x1a869e8b,0x148f5b6b,0xaa75d90a,0x7a8abc59,0x62146013,0x2f0c9bc7, + 0xc3824cd9,0x43faa747,0x6a5d0b92,0x81763a18,0x9bcbaebc,0xbbc341bc, + 0xf745d1dd,0xe1813160,0xb75ce5f4,0xa53ce52d,0xd50de4c2,0x15eae66c, + 0x75d7656d,0x5ed8996c,0xc4ca552a,0xe4ff5711,0x3c5305b4,0x215e985a, + 0xfa1ba2ce,0x6b258954 } }, +}; + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^128, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_base_32(sp_point_1024* r, const sp_digit* k, + int map, int ct, void* heap) +{ + return sp_1024_ecc_mulmod_stripe_32(r, &p1024_base, p1024_table, + k, map, ct, heap); +} + +#endif + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_1024(const mp_int* km, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_digit kd[32]; +#endif + sp_point_1024* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_32(heap, p, point); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 32, km); + + err = sp_1024_ecc_mulmod_base_32(point, k, map, 1, heap); + } + if (err == MP_OKAY) { + err = sp_1024_point_to_ecc_point_32(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_32(point, 0, heap); + + return err; +} + +/* Multiply the base point of P1024 by the scalar, add point a and return + * the result. If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_add_1024(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_point_1024 a; + sp_digit kd[32]; + sp_digit t[32 * 2 * 5]; +#endif + sp_point_1024* point; + sp_point_1024* addP = NULL; + sp_digit* tmp = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_32(heap, p, point); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (32 + 32 * 2 * 5), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 32; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 32, km); + sp_1024_point_from_ecc_point_32(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_1024_mod_mul_norm_32(addP->x, addP->x, p1024_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_1024_mod_mul_norm_32(addP->y, addP->y, p1024_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_1024_mod_mul_norm_32(addP->z, addP->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_ecc_mulmod_base_32(point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_1024_proj_point_add_32(point, point, addP, tmp); + + if (map) { + sp_1024_map_32(point, point, tmp); + } + + err = sp_1024_point_to_ecc_point_32(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_32(addP, 0, heap); + sp_1024_point_free_32(point, 0, heap); + + return err; +} + +#ifndef WOLFSSL_SP_SMALL +/* Generate a pre-computation table for the point. + * + * gm Point to generate table for. + * table Buffer to hold pre-computed points table. + * len Length of table. + * heap Heap to use for allocation. + * returns BAD_FUNC_ARG when gm or len is NULL, LENGTH_ONLY_E when table is + * NULL and length is returned, BUFFER_E if length is too small and 0 otherwise. + */ +int sp_ecc_gen_table_1024(const ecc_point* gm, byte* table, word32* len, + void* heap) +{ + int err = 0; +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; +#endif + sp_point_1024* point = NULL; + sp_digit t[5 * 2 * 32]; + + if ((gm == NULL) || (len == NULL)) { + err = BAD_FUNC_ARG; + } + + if ((err == 0) && (table == NULL)) { + *len = sizeof(sp_table_entry_1024) * 256; + err = LENGTH_ONLY_E; + } + if ((err == 0) && (*len < (int)(sizeof(sp_table_entry_1024) * 256))) { + err = BUFFER_E; + } + + if (err == 0) { + err = sp_1024_point_new_32(heap, p, point); + } + if (err == 0) { + sp_1024_point_from_ecc_point_32(point, gm); + err = sp_1024_gen_stripe_table_32(point, + (sp_table_entry_1024*)table, t, heap); + } + if (err == 0) { + *len = sizeof(sp_table_entry_1024) * 256; + } + + sp_1024_point_free_32(point, 0, heap); + + return err; +} +#else +/* Generate a pre-computation table for the point. + * + * gm Point to generate table for. + * table Buffer to hold pre-computed points table. + * len Length of table. + * heap Heap to use for allocation. + * returns BAD_FUNC_ARG when gm or len is NULL, LENGTH_ONLY_E when table is + * NULL and length is returned, BUFFER_E if length is too small and 0 otherwise. + */ +int sp_ecc_gen_table_1024(const ecc_point* gm, byte* table, word32* len, + void* heap) +{ + int err = 0; + + if ((gm == NULL) || (len == NULL)) { + err = BAD_FUNC_ARG; + } + + if ((err == 0) && (table == NULL)) { + *len = 0; + err = LENGTH_ONLY_E; + } + if ((err == 0) && (*len != 0)) { + err = BUFFER_E; + } + if (err == 0) { + *len = 0; + } + + (void)heap; + + return err; +} +#endif +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * gm Point to multiply. + * table Pre-computed points. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_table_1024(const mp_int* km, const ecc_point* gm, byte* table, + ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_digit kd[32]; +#endif + sp_point_1024* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_32(heap, p, point); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32, heap, DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 32, km); + sp_1024_point_from_ecc_point_32(point, gm); + +#ifndef WOLFSSL_SP_SMALL + err = sp_1024_ecc_mulmod_stripe_32(point, point, + (const sp_table_entry_1024*)table, k, map, 0, heap); +#else + (void)table; + err = sp_1024_ecc_mulmod_32(point, point, k, map, 0, heap); +#endif + } + if (err == MP_OKAY) { + err = sp_1024_point_to_ecc_point_32(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_32(point, 0, heap); + + return err; +} + +/* Multiply p* in projective co-ordinates by q*. + * + * r.x = p.x - (p.y * q.y) + * r.y = (p.x * q.y) + p.y + * + * px [in,out] A single precision integer - X ordinate of number to multiply. + * py [in,out] A single precision integer - Y ordinate of number to multiply. + * q [in] A single precision integer - multiplier. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_mul_qx1_32(sp_digit* px, sp_digit* py, + const sp_digit* q, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 32; + + /* t1 = p.x * q.y */ + sp_1024_mont_mul_32(t1, px, q, p1024_mod, p1024_mp_mod); + /* t2 = p.y * q.y */ + sp_1024_mont_mul_32(t2, py, q, p1024_mod, p1024_mp_mod); + /* r.x = p.x - (p.y * q.y) */ + sp_1024_mont_sub_32(px, px, t2, p1024_mod); + /* r.y = (p.x * q.y) + p.y */ + sp_1024_mont_add_32(py, t1, py, p1024_mod); +} + +/* Square p* in projective co-ordinates. + * + * px' = (p.x + p.y) * (p.x - p.y) = p.x^2 - p.y^2 + * py' = 2 * p.x * p.y + * + * px [in,out] A single precision integer - X ordinate of number to square. + * py [in,out] A single precision integer - Y ordinate of number to square. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_sqr_32(sp_digit* px, sp_digit* py, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 32; + + /* t1 = p.x + p.y */ + sp_1024_mont_add_32(t1, px, py, p1024_mod); + /* t2 = p.x - p.y */ + sp_1024_mont_sub_32(t2, px, py, p1024_mod); + /* r.y = p.x * p.y */ + sp_1024_mont_mul_32(py, px, py, p1024_mod, p1024_mp_mod); + /* r.x = (p.x + p.y) * (p.x - p.y) */ + sp_1024_mont_mul_32(px, t1, t2, p1024_mod, p1024_mp_mod); + /* r.y = (p.x * p.y) * 2 */ + sp_1024_mont_dbl_32(py, py, p1024_mod); +} + +#ifdef WOLFSSL_SP_SMALL +/* Perform the modular exponentiation in Fp* for SAKKE. + * + * Simple square and multiply when expontent bit is one algorithm. + * Square and multiply performed in Fp*. + * + * base [in] Base. MP integer. + * exp [in] Exponent. MP integer. + * res [out] Result. MP integer. + * returns 0 on success and MEMORY_E if memory allocation fails. + */ +int sp_ModExp_Fp_star_1024(const mp_int* base, mp_int* exp, mp_int* res) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td; + sp_digit* t; + sp_digit* tx; + sp_digit* ty; + sp_digit* b; + sp_digit* e; +#else + sp_digit t[4 * 2 * 32]; + sp_digit tx[2 * 32]; + sp_digit ty[2 * 32]; + sp_digit b[2 * 32]; + sp_digit e[2 * 32]; +#endif + sp_digit* r; + int err = MP_OKAY; + int bits; + int i; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8 * 32 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + tx = td + 4 * 32 * 2; + ty = td + 5 * 32 * 2; + b = td + 6 * 32 * 2; + e = td + 7 * 32 * 2; +#endif + r = ty; + + bits = mp_count_bits(exp); + sp_1024_from_mp(b, 32, base); + sp_1024_from_mp(e, 32, exp); + + XMEMCPY(tx, p1024_norm_mod, sizeof(sp_digit) * 32); + sp_1024_mul_32(b, b, p1024_norm_mod); + err = sp_1024_mod_32(b, b, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(ty, b, sizeof(sp_digit) * 32); + + for (i = bits - 2; i >= 0; i--) { + sp_1024_proj_sqr_32(tx, ty, t); + if ((e[i / 32] >> (i % 32)) & 1) { + sp_1024_proj_mul_qx1_32(tx, ty, b, t); + } + } + } + + if (err == MP_OKAY) { + sp_1024_mont_inv_32(tx, tx, t); + + XMEMSET(tx + 32, 0, sizeof(sp_digit) * 32); + sp_1024_mont_reduce_32(tx, p1024_mod, p1024_mp_mod); + XMEMSET(ty + 32, 0, sizeof(sp_digit) * 32); + sp_1024_mont_reduce_32(ty, p1024_mod, p1024_mp_mod); + + sp_1024_mul_32(r, tx, ty); + err = sp_1024_mod_32(r, r, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + return err; +} + +#else +/* Pre-computed table for exponentiating g. + * Striping: 8 points at a distance of (128 combined for + * a total of 256 points. + */ +static const sp_digit sp_1024_g_table[256][32] = { + { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000 }, + { 0x335c1685, 0x170a46d2, 0xe1007a58, 0xeac9e971, 0x43ca4a73, + 0x40e8f3df, 0x82642475, 0x2646f815, 0xb36576d1, 0x3af49bb4, + 0x72bf1afb, 0xd89e2d14, 0x2fd151e6, 0x27be882c, 0x8f88717c, + 0xaddedc85, 0x16ac6c6f, 0xd6d859bf, 0x2d8eae58, 0x0e741a1b, + 0x61c1f30d, 0x6faf7a00, 0x9b67e096, 0x66dbd09a, 0x7d3b4f7d, + 0x21f11c06, 0xc727c98e, 0x6152ba02, 0xe86cb221, 0xafd58891, + 0x6bd3baf4, 0x59e93c6a }, + { 0x71dd4594, 0xe54dd36f, 0x00aef1e6, 0xbbc9cc9f, 0xa19f6530, + 0x9ea5a44e, 0x3f520928, 0x8588aa99, 0x8f5c1418, 0x9753794c, + 0xc11399fa, 0x118bd792, 0xf5cb6ab5, 0xb9bd3afd, 0x2ecb9652, + 0x813d1cb2, 0x40389813, 0xfd456267, 0x4ac8431c, 0x51f7119b, + 0x0a180eb6, 0xdd9f6a91, 0x9f7bfa2e, 0x13946d17, 0x50a9d0d9, + 0x16f18631, 0x6f8373d3, 0x5f19c20d, 0x9b6a52b9, 0xbe85ac6a, + 0x74f62e03, 0x63ef187b }, + { 0x016f45e7, 0x7c376b7f, 0x2bec82f8, 0x1c1bdb57, 0xce429b60, + 0x7392f741, 0xc7afd81d, 0x6fdbf0a2, 0x7241098b, 0xbda41b1f, + 0xbb60f8cf, 0x5b407474, 0xb330bc4d, 0x933e0d41, 0x733fa3be, + 0xae182830, 0x0f5c6cd1, 0xa0ed299b, 0x3f9860c8, 0x7ff3354e, + 0x15559c41, 0xb1360986, 0x129f85cb, 0xab0cb63c, 0x47685fbe, + 0x682ecc49, 0xeb199633, 0x505e8ec2, 0xddac2cda, 0x90dcc794, + 0xf192da23, 0x4fe6791c }, + { 0x05e8733c, 0x94a423d5, 0x1d5717c1, 0xcc845e65, 0xe961b322, + 0x237c7e88, 0xdb4181cc, 0x0c4471c6, 0x713bd721, 0x00c875e2, + 0xb2c17b09, 0x9dfde9ed, 0xe88ceaf6, 0x430a6de5, 0x7b81cea6, + 0xaaa7a61a, 0x233f98d5, 0xea52d026, 0x60689a9a, 0xb55efdd0, + 0x5cac4aab, 0x30cfa7ce, 0x8e950761, 0xfa4db114, 0x4e9a1e52, + 0x309570c4, 0x1a040170, 0x18c21f61, 0xbe78d9d2, 0x555d1ffe, + 0x561db297, 0x04482a18 }, + { 0x73d486d8, 0xe7758ac2, 0x61cdc1e7, 0x8169f946, 0x2188ab4f, + 0x723c99fc, 0xf3373630, 0xa0e54f02, 0xbd8c2260, 0x560bee25, + 0x4531bc60, 0x28fc307c, 0x7e44feb5, 0xd6f21f1a, 0x57128d37, + 0xc8e4499c, 0xd7b2ea45, 0x963b053e, 0x32a3d222, 0x40c27a04, + 0x35459668, 0x5b51854d, 0xd73557e9, 0x66e1a49f, 0x8692077a, + 0x0d267fd9, 0xe7342702, 0xfa1350d3, 0x68ccdb44, 0x1a9c3f25, + 0xdedbf89f, 0x833a0ff8 }, + { 0xab376b76, 0xa8c419c7, 0x27d0f0cc, 0x3b7294f3, 0xa90c514d, + 0xe56bb9e2, 0xa62575a6, 0x931ba51e, 0x098c0a88, 0x56fee07b, + 0xb4c16a2a, 0x04be5aee, 0xe6eb260b, 0xe513350b, 0xa1d5c270, + 0x339edad6, 0xe9dbadd1, 0xf366ed59, 0x2dd06ec0, 0x4213be88, + 0xcb1187db, 0x22d639c8, 0xd8a1058a, 0x1fec95e1, 0xa2b744f1, + 0x03f73ea6, 0xf4f05c0c, 0x741fd51a, 0x85f811a0, 0x2e2df95a, + 0xeb24965f, 0x692b3ce3 }, + { 0xd2a127b4, 0x0ce6cb72, 0x8f92816f, 0x66a46ea5, 0x47a37616, + 0x43ecf463, 0xe0ab96ee, 0x163d9a01, 0xb2edbe8c, 0xc8145c6d, + 0x4de4e665, 0x2f426cae, 0x74e252f9, 0x174d0b40, 0x7d2af831, + 0x54c240d7, 0x3d652936, 0x581fa397, 0xa09d4695, 0x05b9491c, + 0x5452643c, 0x8c4e8533, 0xd4128327, 0x32d64331, 0x70361f25, + 0x64479038, 0x89ef09f2, 0x774191b1, 0x81de5fe0, 0xc0cf0aaf, + 0xf40042d6, 0x333e430a }, + { 0xcf26d3b7, 0x5df04de4, 0xb53f79be, 0x57a77306, 0x1808b664, + 0xa4013c5f, 0x85037360, 0xef291ea4, 0x0b061037, 0x1ffc9d7d, + 0x65c913bb, 0xd9d04dd9, 0xf13b8587, 0x948a37af, 0xfe3ee755, + 0xb5443483, 0x04631386, 0x3fc21e74, 0xcddeb58c, 0xb3a104e5, + 0x6572cd52, 0x94fe1862, 0x15aaa408, 0xeb9a71a1, 0x459ea462, + 0x8adc6fe5, 0x4aeb02a3, 0xbb18d175, 0x2f7791d1, 0xae127636, + 0xd6bbd708, 0x10e8b31d }, + { 0x3ed9f1af, 0xb87f03e5, 0x56676166, 0x03ad2477, 0x74ce15b8, + 0x38dcd630, 0x26b1e85b, 0x1877e2b0, 0x1af99c15, 0xb1654d17, + 0x9382547a, 0x9782e9e4, 0x26d55ef5, 0x6dc7fc7c, 0x2fbeb54c, + 0x9038f95d, 0x036c0357, 0xfe590dfe, 0x4fdc3f7f, 0xcfcb6eae, + 0xf35e1a88, 0xcb1fbc54, 0xda0a5568, 0x3c8e1db2, 0x5b6f5557, + 0x9a87393f, 0xe7ac0a06, 0x38646b32, 0x2a8495ab, 0xfd261c83, + 0x0cdcc4bc, 0x6485524c }, + { 0xc4a6ff2a, 0x1abfb3e2, 0x35a6428a, 0x2aa03fba, 0x89aff742, + 0x884227f0, 0xba5dbd93, 0x2337883a, 0xd2a182cb, 0x38186ae9, + 0x49a01f05, 0xb9f0764d, 0x917b1e7a, 0x92411feb, 0x570cbb5b, + 0x700b1903, 0xb914be7c, 0x5d5181d5, 0x1981182d, 0x135c4437, + 0x574b9997, 0x32758d24, 0x632d28b2, 0xa650a8f5, 0xfa383f09, + 0x24078bac, 0x00a33d80, 0x6546a60c, 0x2df8b449, 0xa4061c7a, + 0xf234563c, 0x1f76f3f2 }, + { 0x44c436b0, 0x9aa2c143, 0x1f69c87a, 0x79070556, 0x5f6db2df, + 0x35f3117b, 0xed56ba82, 0x85761f41, 0x7d0afa48, 0xf831464f, + 0x3adce71e, 0xa99f2915, 0x116b7488, 0xb27bf693, 0x9bb9443a, + 0xa98a5a8c, 0x2ee5fde8, 0x7f878026, 0x1812acb7, 0x3a6f93dd, + 0xdc84bc92, 0xaf92a4cc, 0xf1d4995a, 0x3c2562af, 0x04ed899d, + 0xfd9fc33c, 0x4ed2a538, 0xc028ca94, 0x049ea726, 0xd0f367bb, + 0x3d108e05, 0x04924ffb }, + { 0xc673562f, 0x06548e3d, 0xe2eae48c, 0xd3b33025, 0x5e1c6977, + 0xe61fd32b, 0x6ebe557b, 0x424e2064, 0x41d6e18e, 0x767391c0, + 0x14d7e95b, 0x4b8ebb8e, 0x20991b8c, 0x4ae8b7d4, 0xe01290d3, + 0xf8a0df66, 0x925e5f4e, 0xc97e24a3, 0x1508272a, 0x79a7b2cb, + 0x25072661, 0xb40b072e, 0x9062fa49, 0xdad9e182, 0xf3c53bce, + 0x8780a784, 0x9f142799, 0x58a82b76, 0xc1468426, 0x08cd849c, + 0xc380ae35, 0x4dfce809 }, + { 0xd527b780, 0x45069cb2, 0x977930dd, 0xd52da015, 0xe27d0263, + 0x10cc600b, 0xbb2d1b2b, 0x34102c26, 0x554adf3c, 0x4c652623, + 0x45f0ff47, 0xd6891382, 0xca916e7c, 0x83fa8cc5, 0xd15c8d8a, + 0x1e10f139, 0x81dc56b3, 0xf173dc2e, 0x5c4ed9ba, 0x7fcecb04, + 0x47d01228, 0x307fd7d8, 0x9f3a532f, 0x24a57153, 0xe2153c22, + 0x59e9e81d, 0xe428a408, 0xc562595d, 0x9339bd23, 0xdc7daff8, + 0xb8a06802, 0x0d075908 }, + { 0xde085f2a, 0x870af2a7, 0xbe99b2e5, 0x88fcd24f, 0x59ca413b, + 0x88c0d261, 0x8559f851, 0x1f02a2e4, 0xf622da0d, 0x83b96021, + 0x6dca3615, 0x5c05c2f5, 0x7910c682, 0x0148cf1c, 0x272695be, + 0x392f2896, 0xa8d64ef6, 0x883d0bb5, 0x1cfcbc52, 0xef0d2244, + 0x526117e5, 0xf5dafcec, 0xf04928e9, 0xb68612b9, 0x393f2e2a, + 0x283f744d, 0x700c1151, 0xfbeed7ed, 0xa4360dfe, 0xf2cde215, + 0x2f08535a, 0x24fa961c }, + { 0x616df7f6, 0x0767db3f, 0xfbd90326, 0x643057d8, 0x6e82d544, + 0x174daa90, 0x689643db, 0x2284f345, 0xcc89a060, 0x18b191df, + 0xd6c27d12, 0xbab46af4, 0xc9895145, 0x5a57f486, 0xcc942f9e, + 0xc03214e9, 0x41950158, 0x273e1c8f, 0x39ad43ab, 0x8ceb759f, + 0xe50ee173, 0x5e1b8b7f, 0x8f4d7d4e, 0xf635b1fc, 0x755603f3, + 0x8eff77e3, 0x7752fa60, 0x201f61d1, 0x4a6fb6e1, 0x94d7a03d, + 0xfc4f0114, 0x371cc23d }, + { 0xda90c351, 0x289b115d, 0x364d9c06, 0x6d196ebf, 0xf650b31b, + 0x77a89202, 0x6f57642f, 0xcc28c164, 0x08100127, 0xdc4f7e36, + 0xdc4c807b, 0x8836cd08, 0xe00240f2, 0x1280f156, 0x99cb3953, + 0x3f9a6d78, 0x3a802038, 0x40a494d3, 0xe87d3474, 0x45697e91, + 0x26dde24a, 0x70d97d07, 0x7640c30e, 0x06f6a58d, 0x5ba6e6c6, + 0x03c2c0e8, 0xf1bc13e8, 0x330f6a7a, 0xc9f4d78f, 0x3e602e4f, + 0x0c80fb7f, 0x92b6bca0 }, + { 0x5f00822e, 0x2e3d5c83, 0xb8b16f12, 0x0e825712, 0x92b0a330, + 0x81c329c4, 0xa7cc1954, 0x6b4e32ad, 0x1bb1413f, 0x0bee9cee, + 0x4a92ca27, 0xedfb7baa, 0xea3b9153, 0xcd472afa, 0x00f0c0f9, + 0xe8f09e7e, 0x5cdebb70, 0xa4e1d872, 0x4a9b63b6, 0xfe2bae08, + 0x3fd58f65, 0xf40141b8, 0xa3b62759, 0xd7ec5eda, 0x790e3088, + 0x9aaf6e67, 0x1f277e31, 0x215ad830, 0xcf33871c, 0xe7db4b98, + 0x4f02f89d, 0x71ff62c9 }, + { 0x2a4a84d9, 0xaa4c7102, 0x5ebc71e6, 0xe2ee4acd, 0xf1cd6578, + 0x3b11a8a5, 0xfff120a5, 0x83f5ef9f, 0x09e65033, 0xa4c598e1, + 0xca044180, 0xe1e9f990, 0xf59828c1, 0x8b832d46, 0x33af536b, + 0x753f28a0, 0xb6d4f68a, 0x92edc4b1, 0x72ccd1f0, 0xedde692a, + 0xd2226432, 0xd3aa0f7d, 0xa3d2661c, 0x38dbb63e, 0xfdc37dda, + 0xf1e19fc6, 0x84ef6b4c, 0x6c18b350, 0xdf1bba69, 0xe6a83fe9, + 0x5f958273, 0x40fd47e7 }, + { 0x267140a4, 0x5b88b746, 0xeab6f2fb, 0x6dbbfc1e, 0x69862548, + 0xdd9ec88e, 0x2eb6efc2, 0x69beeba1, 0x8ac8ff88, 0xcfc2214a, + 0xb5a21950, 0x95d5c96e, 0x4171fb69, 0x93389c05, 0x1b468337, + 0x2d85d452, 0x4113425c, 0x14d68a08, 0xec6c2174, 0xe52c0139, + 0xf730084d, 0x20cf0b97, 0x1f578aa3, 0x1ac16a26, 0xf9b6ae43, + 0x18b9fab3, 0xd854a695, 0x68d82111, 0xdffbe286, 0x0b334d98, + 0xe639338c, 0x5b1c1157 }, + { 0x72b6bb8f, 0x90edaab1, 0x02fc92c2, 0x8dc64ed2, 0xfe694c73, + 0xf42ba3c5, 0xcb54dce4, 0x316dc65f, 0x632420dc, 0xcb2d66a3, + 0x056dcf94, 0x16e706e7, 0xa4f32c9d, 0x2809c764, 0xea6edca8, + 0xab18d830, 0x81c65f57, 0x4fd1ace6, 0x7da12c10, 0x1f91651c, + 0xc7791a48, 0x0ac3bd66, 0x785e67a3, 0xb6ad1cf4, 0xda0fd591, + 0xe4d3fc44, 0x6e1c6344, 0xce164801, 0x33e50ab3, 0x84de9cb8, + 0xa756eef4, 0x963ab83a }, + { 0xdf4ea5a3, 0x944b47d8, 0x5cfe45fe, 0x96568815, 0x8a3c3564, + 0xd16e7d58, 0xe7c99e15, 0x84e55b3e, 0xf55071bc, 0x3fee204d, + 0x04057dce, 0x71006f29, 0xbba75570, 0xfe8c390d, 0x3319adac, + 0x3645bcb6, 0x7c20bfd8, 0x8189e8b0, 0x7d7d9578, 0x8e550969, + 0xb99f4e3b, 0x037d1321, 0xa60cfb6a, 0x011b2521, 0x837382da, + 0x66594aaa, 0x83c1dc07, 0xc89b91fd, 0x076b9884, 0x6b82b899, + 0xbe45c558, 0x443480fc }, + { 0x9114221a, 0xf8ffffb4, 0x3e857a7a, 0x4aec4f2e, 0x0fa54787, + 0x42e2d0e4, 0xd6f96152, 0xef3e6b31, 0xfbfe9b77, 0xb2296537, + 0xfb43a86a, 0xc2a9d0f2, 0x24572ac6, 0x241284ed, 0xe721ba7b, + 0xa3868917, 0xc117a78d, 0xdbef7c00, 0xd31605ac, 0x38149071, + 0x065a8ee9, 0xc2dada9e, 0xc442be82, 0xd5b138d8, 0xf6d72b58, + 0x9b6c224b, 0x8eb03e6d, 0xb9d355cf, 0xa1700371, 0xab6d1eb0, + 0xcffaa7eb, 0x97118a88 }, + { 0xcdecb5d8, 0xbf9c59a2, 0xa93a6866, 0x8083c81b, 0x04774fbf, + 0x24e0dd81, 0xa02070b4, 0xe779a3ca, 0x0fbfb781, 0x9d352fbb, + 0x3ef2a1c4, 0xa8b0d820, 0x14b3e501, 0xb858637b, 0x8a882ff2, + 0x5ba70a49, 0x3b06efa5, 0xa2730083, 0x102fee2a, 0xa42c02f4, + 0x8a0223a5, 0xe4e76299, 0x85c3fc72, 0xdba2ba26, 0xfe52eae7, + 0x554fe763, 0x270f45f6, 0x30b5405a, 0xa573387c, 0xd56a177a, + 0x4b71fa82, 0x17c0778d }, + { 0x2735e37b, 0x0e6dff1d, 0x656ec572, 0xc9884e56, 0x9ebba978, + 0xa2f5ac9d, 0xba09f3c4, 0x40fa4518, 0xf5b04377, 0x8c3fa177, + 0x967a2eca, 0xa1a1decd, 0x0528bd40, 0x768bca70, 0x18691c4a, + 0xf224952b, 0xe86d5fd5, 0x16e12c45, 0x37859a6a, 0x7a0d9157, + 0xa0ffce0e, 0x723f4309, 0xa96cc9a3, 0x5a8db79b, 0x1ad23a38, + 0x6dd12ae0, 0xe2bf5d84, 0x9ffec3a1, 0xa452ed66, 0xd6ce84e1, + 0x571fe4c6, 0x1219d5c8 }, + { 0x262969eb, 0x43eaa67f, 0x2f03e773, 0x3a3ab39d, 0x57bb0909, + 0xe6127e51, 0x8d150274, 0x0f82b0ed, 0xe580bdbd, 0xffffcad8, + 0xa9743e6b, 0x51d3d075, 0x8bac11d6, 0x1484bdb1, 0xeb24c388, + 0x95cd9990, 0x7fac67c6, 0x216a61d0, 0xa04e6b87, 0x4308f762, + 0xcba57cc8, 0x2865dd61, 0xd234a07a, 0x3c296b0d, 0x3a0793f9, + 0x76f92839, 0x0be29ece, 0x70b57e1f, 0x7e626f42, 0x1314a82f, + 0xd657f230, 0x2c8d7ab2 }, + { 0x0825e4d6, 0x67cf5892, 0x6ef83b44, 0xdf51eaa5, 0x1310108d, + 0x63e665d8, 0x8dd0963f, 0x229f89f5, 0x9df6436a, 0x8c4b14dd, + 0xd45ebba7, 0x99dae469, 0x5a4df381, 0x118aab77, 0x29e37feb, + 0xda8978bd, 0xaca2d7ef, 0x69ced5aa, 0xc67d6a8a, 0x6c98d05d, + 0x77f84a34, 0x7474bf0d, 0xed8cd59a, 0xd4428b2e, 0xd1d398fb, + 0xb0fd1cd5, 0x94a20b11, 0x596013db, 0x1b404c44, 0x96eb705a, + 0x4b09d958, 0x2299d277 }, + { 0xc64397e6, 0x5b9cd58d, 0xbf6dd31e, 0xac198f1e, 0x3e9f1db2, + 0x5866d8e1, 0x8fcdc68c, 0x405ae287, 0xe53c01fd, 0xa4b280cd, + 0x411db5f6, 0xdc963f2d, 0xbec4f8a0, 0xed5d5189, 0x916ee98b, + 0x336fd13d, 0x042df48e, 0x6925b1b3, 0xace0074e, 0x0cf56291, + 0x25317e95, 0xe8d38b48, 0x821c446b, 0xc7ad1d2b, 0xf0b65934, + 0x71c44135, 0x52ca0d50, 0x971b736f, 0x27b46c26, 0xaf9ffa57, + 0x1936618e, 0x21ac6779 }, + { 0x2d7fbcd2, 0xab420e3f, 0x97bdfc18, 0x12722473, 0x4df5d4b4, + 0x492033f8, 0x3807b7d3, 0x6fcd4236, 0xb33c3625, 0xdfc19b09, + 0xa0f22814, 0x13d6f375, 0x037c19b8, 0x70978a59, 0x0ff27b9c, + 0x4f398997, 0x615a4389, 0xfc0e1a45, 0x3e602f74, 0xffa3496a, + 0xb261ca1c, 0xc3f1c431, 0xee0164cd, 0x612211db, 0xe7f7be9f, + 0x30463ee4, 0x92c2e1bb, 0x015f7e78, 0x24483a56, 0x663d88d6, + 0x0e62d9d8, 0x0e8ec1e7 }, + { 0x8a0878dd, 0xa88ccc29, 0x6640071a, 0x99ac175d, 0xa5173617, + 0x90344820, 0xdd58a315, 0x316d023e, 0x88d221a1, 0x30785bd4, + 0x959c48e3, 0xb74b3de7, 0x4c67a771, 0x42ee0382, 0xe0b91453, + 0x59ef6cdd, 0x9b237e91, 0x7830ae28, 0x495d8325, 0xe1847a4c, + 0xd0773666, 0x67b1217e, 0xa294a325, 0x58192c86, 0x864d8326, + 0x76aa0f56, 0xf4b13e5b, 0xe2a2bd12, 0x1b6b73fd, 0xd850c1c0, + 0x5d103635, 0x653a795f }, + { 0x50dcb199, 0xcfe28985, 0x7fa02b60, 0xb35b8e5e, 0xc97603d0, + 0xbca7d7c3, 0x27f131b5, 0xb0e5288d, 0xe2b12d52, 0x3aa704de, + 0x1db725c7, 0xe206b1d8, 0xc5d1b113, 0x0b12839a, 0xdb45d763, + 0x14f970cb, 0xb2125e8e, 0xc997f93e, 0xee7daa26, 0xbd75739c, + 0x1fef20e9, 0x46ecbd3f, 0x7c6a42b1, 0xf994a114, 0x27fb0fd1, + 0xd289eb4f, 0x9a40da4b, 0x11186d31, 0xfb9d7976, 0x083f65a5, + 0xd444675e, 0x30dfc47b }, + { 0x9eaadfe8, 0xbcfc5ae2, 0xb4d4e812, 0x25027e54, 0x8b533561, + 0xab0702df, 0x56a6a214, 0xa2b9c204, 0x3059068e, 0xb1a3df7a, + 0x9883110f, 0xa3514b21, 0xc4b78e1c, 0xb7be2336, 0x3e2f6984, + 0x17073ce6, 0x2ddf7ac6, 0x86e114a6, 0x07d7c3c8, 0x276192bf, + 0xeb1ae289, 0x5da69e0b, 0x25184939, 0x983af175, 0x407a3aa0, + 0x9ac52a4d, 0xae0fe218, 0x1535c7da, 0x397f2501, 0xe16fe872, + 0x54c212cf, 0x572a591f }, + { 0x09a5553a, 0x49668419, 0x327733bc, 0x3f054318, 0x3eefd690, + 0xf9ceb4b2, 0xf22126d4, 0xbd3cbf9b, 0x2fed9578, 0x6d9671c0, + 0xca0306d8, 0xbba597ce, 0x3d674fe5, 0xb705ed61, 0x67f33f76, + 0xf1d3622b, 0x11cb8c31, 0x15bcf3c6, 0xe53d1aa9, 0xa38467dc, + 0xf908ab43, 0x902fe929, 0x8d15767a, 0x6e3e499d, 0x90afd07b, + 0x8142db5c, 0x6c8b190e, 0x120c6fbc, 0x24919a4e, 0x80c86553, + 0xd8c82c3c, 0x65c2cbe1 }, + { 0xa660bb63, 0x684cda20, 0x86e86245, 0x27dc3b0a, 0x6ba0eed7, + 0x76472cf6, 0x679dd158, 0x79c162e5, 0x08452d44, 0xb6884277, + 0x413f579e, 0x829bc6b3, 0x95011770, 0x92ea15ec, 0x47738183, + 0x5e34e300, 0x73e1d2f1, 0x8c3ca349, 0x229bd3de, 0xa5c4f1dc, + 0x94ef7ed3, 0x783eff1b, 0xdfae7a1a, 0x46db738d, 0x1a099852, + 0x4353d72e, 0xa0dcf4ab, 0x2533ad58, 0x0e7888b9, 0xd8055016, + 0x3ba77f66, 0x831440d5 }, + { 0xf611b2da, 0xf43e2e32, 0xd0fa46ac, 0x5d066e29, 0x820b3c0d, + 0xe897f3e8, 0x1d3e44f0, 0xc45c28e6, 0xdfd27a66, 0x929d7f66, + 0x101e8517, 0x735b860a, 0x3de078dd, 0xea3fce98, 0x638ce11a, + 0xc9977db5, 0x48536b3b, 0x0488382f, 0x64cadfc6, 0x7e0c7a3c, + 0x82147b71, 0x3cd17f7f, 0x1b411e3e, 0xe95663cc, 0x985fb46d, + 0x5739ac8f, 0xbcf119ca, 0x385399cd, 0xe15a2815, 0x4a985a70, + 0x6d5f4566, 0x504c3a8a }, + { 0xb8fa53c7, 0x00b55283, 0x509474e3, 0x985cff38, 0x437ce25f, + 0x234d241c, 0xe5a129ed, 0x29832430, 0xaabcc674, 0x6ad38956, + 0x7ee81ee1, 0xa2dc001d, 0x670b2702, 0x4c23c6b6, 0xa6e8a3bb, + 0xb35e567e, 0xa69673ea, 0xbc70b3ce, 0xe6e28eac, 0x85a7a9c3, + 0x5537b7da, 0x2ae684de, 0x6de937dc, 0x5ecac3e5, 0xf8430422, + 0xbf2ea6c9, 0x77fdc520, 0x38caf7d0, 0x69f56add, 0xc27af0b1, + 0xc71d21d2, 0x496e4699 }, + { 0x9fa93467, 0xba14fc82, 0x0eb2a614, 0xc2e37684, 0x4833e09b, + 0x659bcfaf, 0x3686bdcc, 0xbc859752, 0x81f3216a, 0x40bfd080, + 0x17c081b8, 0xc463bda6, 0xbb04793b, 0xbd01fa86, 0x2cd640c5, + 0x5a21ece6, 0x2203d5c4, 0x97bf6a54, 0x951167b7, 0xceb40edc, + 0x765ba268, 0xd67aacaf, 0xaeab51f9, 0x8ba0d9e9, 0xb0d6863a, + 0xc14b215e, 0xe5f06952, 0x354cdcdb, 0xcb3744b5, 0x4f2b5ccf, + 0x13037fe8, 0x13389173 }, + { 0x45003cd1, 0xee680640, 0x44ae2ac6, 0xfdac17bc, 0xde8e5314, + 0x4bcd419f, 0xc7cea95c, 0x81e34eb9, 0x38f37e01, 0xbb57762d, + 0x260990c8, 0xecc4cfb0, 0x50a34a7b, 0x0bc493f9, 0x543304ef, + 0x68074172, 0x6bc8aa2a, 0xaec0fcb2, 0x3b45fea5, 0x9e7a9b46, + 0x55fbdbac, 0x4bb2952e, 0x0485dff4, 0x50f0c0a6, 0x4dea4796, + 0x02c5104d, 0x695e3a02, 0xd2cefa09, 0x6da1f345, 0x4c8102b4, + 0xf3833fbd, 0x422eb573 }, + { 0xa6ad3f47, 0xac592eb6, 0x9714ba0e, 0xb0861f6d, 0x07281459, + 0x57c1e919, 0x64ea5803, 0xcf7c94e2, 0x54b12723, 0x725376ac, + 0xdafb736a, 0xf2a6ba41, 0xcba03cdc, 0xc89e8920, 0x5b0fd3ad, + 0xf2e20cb4, 0xd66059fe, 0x26ea5a54, 0x889df8bc, 0xee63fa8b, + 0x66a3f2bf, 0x40f1c7e1, 0x747312e1, 0x09febc9c, 0x727999ff, + 0x7d19b9c2, 0xb7fd2b05, 0xa9fbbb4c, 0xa0da2dc6, 0xcfba27d7, + 0x2c252582, 0x368541cf }, + { 0x22799d37, 0x510d3c9e, 0xacfa333a, 0x1b677de5, 0x080f795b, + 0x4e6ae18f, 0xafc8dfc2, 0x69b53c2a, 0x0e842dc2, 0x797541b6, + 0xac067fe8, 0xd5a6f2af, 0xbd07d877, 0xd0208a03, 0x654be2f2, + 0x34b473f0, 0xf515e23e, 0xe67c102a, 0x2ac1af48, 0xb00dbf9d, + 0xb6a13d00, 0xe264fa41, 0x97e94c11, 0x1669786a, 0x86a586f4, + 0x09d8cf2d, 0xc7f927e9, 0x073bf869, 0x2241a566, 0xb8977880, + 0x22261334, 0x59a5bf59 }, + { 0x81347191, 0xe9d1c91e, 0xeb969972, 0x186c1abc, 0xa9d46a7f, + 0x07888767, 0xdaa7d397, 0xda93cfcc, 0xd91b9aa0, 0x08bee9f1, + 0xf8dd3c6c, 0x8267fd78, 0x94228100, 0xf93860d0, 0xdadb47fb, + 0x6a6a71aa, 0xa6156f8a, 0x9caa06b7, 0x39848bc9, 0xaa1b05e0, + 0x2aaa9135, 0x36ddc237, 0xb13f3bd1, 0x77e7e079, 0x4acc5f4d, + 0x8d0b5cbe, 0x984cfd36, 0x04da45f8, 0xd3d3e0f8, 0xf14ef618, + 0x43eb799c, 0x467564c1 }, + { 0xb6fff5d7, 0x8d725904, 0x92dc4752, 0x037f33af, 0x6d20b8aa, + 0x9095d575, 0x43baec39, 0x32235fc1, 0x68a2b9b0, 0xa2feb4af, + 0x94d35c61, 0x61c50318, 0xea877486, 0xac92b6a2, 0x011bc6f3, + 0x8eb48b15, 0xc79edcb2, 0xa28fe128, 0xa5d2a006, 0x9f71bc0c, + 0x2f15b850, 0xf3167732, 0x7a036218, 0xfe8d728c, 0x4f81e09e, + 0x068f39cb, 0x7b7c50d9, 0x1773f016, 0xed6a1e03, 0x0d0f7adb, + 0x4ee984d5, 0x8a0dee16 }, + { 0x47366e6f, 0x504991bf, 0xe86c3005, 0xb8084d9f, 0xa40cce36, + 0x14c4c751, 0x3f1961e2, 0xbbb46aa6, 0x40445e43, 0x56a785f9, + 0xc91e215f, 0xdb8d1b57, 0xc7ee808d, 0x6a8e453e, 0xbbaa1e8c, + 0xc0367ef8, 0xe3e18109, 0x310d91f1, 0x7e20a2c3, 0xf97cfd0e, + 0x554cc277, 0xf1e80c84, 0x7b628403, 0xe89bbc1d, 0x3fe0a17c, + 0x7778a966, 0xc1f00073, 0x9e9db19f, 0xb6f6bed2, 0x2ce7fe7d, + 0xee97ce23, 0x7b04b5d2 }, + { 0x82c5faf8, 0x5b546bc7, 0x8eb81097, 0x1a734c5e, 0xe77851e0, + 0x3d566861, 0xe956d51f, 0x833a1013, 0xc3c3c37c, 0xc7351731, + 0xe0c148ec, 0x607738fb, 0xe1bbef41, 0x2ec6f0bb, 0xcfa51857, + 0x0aa2ac6e, 0x66e3adf0, 0x072902d7, 0xc622d6e3, 0xcd4d5089, + 0xa6dd802f, 0x3ae21b23, 0x33886372, 0xe5465a55, 0xa8d81822, + 0xd85119a0, 0x3786977a, 0x4f14d032, 0x9c7b272c, 0x515b081c, + 0xc99be31c, 0x1c6a95a4 }, + { 0xc2821363, 0xa6b14ad5, 0x4d17de1c, 0x829c1823, 0xccade848, + 0xaef5d2c4, 0x82489e27, 0xf412ab39, 0xf081d927, 0x92c9c098, + 0x75cbad1f, 0x6f87bdf4, 0x1a1d9fb1, 0xf4aadab8, 0xb75f3b76, + 0x475a7923, 0xdbbba8fe, 0x99dd0ad6, 0x4b70ab45, 0x836f6164, + 0x34bd9af1, 0x2a464881, 0xba9abda3, 0x5c91226e, 0xe65625fb, + 0x4cec8709, 0x0818e4be, 0xd4b3919e, 0x14f6879c, 0xa5c09c84, + 0x30a864c9, 0x72708a02 }, + { 0xf34a466c, 0x4f33c0b1, 0x7f9d45ba, 0xa1bae09c, 0x0e28785c, + 0xd70f0fee, 0x90880881, 0x824c7146, 0xbb043da3, 0xe2416c2a, + 0xcec6f432, 0x733da713, 0xc9793e1c, 0x2b590649, 0xb35c9365, + 0xdb62d5b0, 0x3e5c1b2a, 0x355eb6e2, 0xbb16b515, 0xcfe8b5ce, + 0xf709691c, 0x9e081869, 0x61a85bd5, 0xc865f9fb, 0xfae103f7, + 0xf169d3cc, 0x73467e9d, 0x9525c473, 0x43695113, 0x7db55c0b, + 0x73265d21, 0x7491c74c }, + { 0x80d2b94d, 0x312ed5bf, 0xba4b260b, 0x1b8ac633, 0xd62219a1, + 0xac86c58c, 0xaeb82c8e, 0x317ccf6b, 0x59ef9ced, 0x2dfb29ee, + 0xe42bcd5a, 0xdaa7d898, 0x5974b201, 0x93e295c8, 0xd9fc5adc, + 0x69e75784, 0x012aa3ba, 0xd6c4709f, 0xc85d3cb9, 0x1fda9f37, + 0xd3dd4abd, 0xe5487e25, 0x0b3ba22e, 0x00fd4b01, 0xc6e8dcbb, + 0xcb591493, 0xbce68664, 0xb7329fab, 0x68906b76, 0x6829d1c2, + 0x74176841, 0x8bcfd3e5 }, + { 0xd3c8c314, 0x06882734, 0x11870833, 0x95f0b2f1, 0xc068ba16, + 0xb937f7c3, 0x77924787, 0x5365e0d8, 0x1f992227, 0x15527e5e, + 0x27dffd4f, 0x0a069648, 0x2f586389, 0xd58b3df2, 0x6af20ead, + 0x83446b89, 0x50746257, 0x09d7970b, 0x4022a691, 0xd9e8d206, + 0x671ec379, 0xd1e5f8af, 0x057fe91e, 0x6f542509, 0x52890418, + 0xf14dda81, 0x1db932ad, 0xbd78010e, 0x905a9378, 0x3e18d1e4, + 0xbd37ab49, 0x53cadcf7 }, + { 0x5e53d0ff, 0x1bb5edf7, 0x888abf67, 0xd886606c, 0x12206d15, + 0x6491b0f8, 0xe22b6a33, 0xb3018345, 0xb173b317, 0xaba6794b, + 0x7dc9e595, 0x8c1e5867, 0x239624d1, 0x4e106482, 0xda55dd53, + 0x61752e59, 0x9e42879c, 0x018b4eab, 0x491f2bed, 0xcaf6784b, + 0x1e79429e, 0x3dcdb9d2, 0x10f26224, 0x36941485, 0xa650ec5c, + 0x106f190a, 0xb69a9760, 0x7542a5ae, 0xc32d1046, 0x69bd75e9, + 0xbf8c62b1, 0x90849964 }, + { 0x5a93c661, 0xb1390cf6, 0x9db5f056, 0x18486264, 0xa51a1788, + 0x92a93a9d, 0x6772de9a, 0x1b0cbb8f, 0x7c71487c, 0x6e67febd, + 0x4e62423e, 0xf9b4382d, 0xbb5a42f8, 0x96fda50e, 0x6089a4f2, + 0xc921b337, 0x875ec516, 0x49d32d7b, 0xc410124b, 0xbd86d2ca, + 0xc421fb7a, 0xf6862209, 0xf6b7de33, 0x3e1949ab, 0xe93c9268, + 0xcdee18f0, 0x08dc4cc0, 0xd4edbd5e, 0x73580d22, 0xc2b75be4, + 0x468cd7e8, 0x3d7f6ffa }, + { 0xdffbd5d1, 0xea7b290c, 0x970338df, 0x9d759da6, 0x90feedc9, + 0x56680b08, 0x42dce68e, 0xbc690af5, 0xb2ae4d82, 0x8519df2b, + 0x7f195b60, 0x5612467f, 0xd83c21f4, 0x659a342c, 0x55651633, + 0x55771bf5, 0x548ba562, 0x5fc68935, 0x9492f23a, 0xb5419203, + 0x9c9c6017, 0x567528e3, 0x511e6019, 0x3f064ed4, 0x1d16a555, + 0x303f9eb9, 0x2254abee, 0x3e18c4fd, 0xfd434e7c, 0x40994d6f, + 0x6dde74e6, 0x8fb12d3f }, + { 0x293cb7a4, 0x6c6381a2, 0xb87b7e4d, 0x453e09f0, 0x078ac3ef, + 0x4f212823, 0x578cae91, 0xe89ffad0, 0x716ba4dd, 0x4a2b696a, + 0xf6f580a0, 0x14681a14, 0x4c2f1307, 0x1358f97b, 0x2932fb89, + 0x87896996, 0x268a5af7, 0x29dd850a, 0xfe239f83, 0xaf771f6d, + 0x4f47499d, 0x5f20fd2e, 0x867ca0e9, 0x9b643e77, 0x375981ec, + 0xe7858ecd, 0x19ab1c97, 0xbe946a59, 0x06ff3453, 0x4f9303a2, + 0x75d237b1, 0x3fcc6731 }, + { 0xdf21f920, 0x509debd5, 0xc1401b90, 0xfaf70e1f, 0x95a64aaf, + 0x2429cbfd, 0x2c37a122, 0xf2120855, 0x7deb926b, 0x1d4c93f4, + 0x9fb3f1dc, 0x12f3e4c0, 0x5b51bc46, 0x56085a59, 0xf10fdbd2, + 0x2a2f5d62, 0xdf0cb3c2, 0x60dd62cf, 0x6b0f254b, 0x154424a3, + 0x564612b7, 0xc3a5a05d, 0xa1f5249c, 0xbebe30cf, 0x7e62a188, + 0x24ec6903, 0xaf429939, 0x75f0fbac, 0xb3fa8685, 0xd41345dc, + 0xc7151c34, 0x645146fd }, + { 0xba1924f9, 0xecec633a, 0x006326e1, 0xbba6f136, 0x7e50fc17, + 0x203757ac, 0xef3d8e00, 0xca531919, 0x51dc5a74, 0x9545a6aa, + 0xd31412b8, 0x6e21d58f, 0x7bb1d000, 0x01bc3005, 0x6ed1a9c3, + 0xf1789c69, 0x9858fa48, 0x7af2d35f, 0x8197be85, 0x434d09b9, + 0x29aa265d, 0x1dc07755, 0xc058fa80, 0xcad03be7, 0x54ba14ce, + 0x92d70a9f, 0x6c050a74, 0x6dc78505, 0x4d005dda, 0x2a7ca4a9, + 0xabfb9f2e, 0x448d3d72 }, + { 0x29b33989, 0xdc56f145, 0xa9ae815a, 0x868351bc, 0x4b074414, + 0xb3f45613, 0x3cd9f33b, 0x955ce42a, 0x5ff6e4a3, 0x13ade4ec, + 0xa50eaa91, 0xd3aac715, 0x5666efdf, 0x0c61ec99, 0xf6a4470a, + 0x108a28b8, 0xe54844c9, 0x402ef584, 0xd0e2f337, 0xb825b162, + 0xb46f7cbc, 0x3dcd131f, 0x96f2fd89, 0x208178ec, 0x25928c78, + 0x4d8c5d67, 0x9963c459, 0x285a33df, 0xd92a309f, 0x72497175, + 0xcb7019a5, 0x76881479 }, + { 0x91767eed, 0xba43a114, 0x92bf65db, 0x5e11b9ad, 0x03a5e21a, + 0xe8a22ce0, 0x2a335415, 0x63604421, 0x4a9ead62, 0xc2c563b4, + 0xa0b2aee5, 0x4bc06264, 0x8bf2e1d7, 0x75b8d575, 0xd08a265d, + 0x1cff0ee7, 0xb0b712a7, 0x17914e1d, 0x4b18692d, 0xc35925d0, + 0x56cce815, 0xde253f4c, 0x9fff0e3a, 0xa479241c, 0xddabed19, + 0x50b9d06e, 0x59fae506, 0x67135260, 0x532ce180, 0xf37600fb, + 0x5e5a8626, 0x670eb01c }, + { 0x73cdbb43, 0xdf73c0af, 0x7f2431ad, 0xcf08ecc5, 0x2a1a3845, + 0x91780541, 0x9224ddf1, 0x69a104f2, 0xbeac7eff, 0x4352f38d, + 0x7c2d1322, 0xfc3b3b4e, 0xb5e4b476, 0xa69e9430, 0x975a46f0, + 0x7d932340, 0x5d64eece, 0x8093899e, 0xdb2345e9, 0x7b821250, + 0x7f4b796b, 0x23552932, 0x4bb90b1f, 0x2ee9cc15, 0x9112f7d6, + 0x1fa9c8f5, 0x1cbaae32, 0x2d0f2f98, 0x0075166a, 0xb77f0366, + 0x635dff27, 0x504852e7 }, + { 0xa2f392fa, 0x2f0f3ce5, 0xec6c9078, 0x326c076a, 0x84baaaf6, + 0xad01de92, 0xcbe8e993, 0xb01b16d3, 0x2d950908, 0x71305c24, + 0x3853af38, 0xc66fd617, 0xd3c429a0, 0x7735140e, 0x1fabf027, + 0x8a31b12a, 0x058b3177, 0xa0530002, 0xa9c7deb9, 0xabffd9fc, + 0xe8667d30, 0xd05ef69b, 0xe9a9e13f, 0x2f3a7308, 0xb91eae9c, + 0x3f4c9a19, 0x618ce6c4, 0x50d0cee7, 0x5240f8b0, 0xfb24dc40, + 0xf7e90cc4, 0x992fe151 }, + { 0x38f197aa, 0x4454db31, 0x87872f98, 0xa4ded69d, 0x44f0a828, + 0x97b427b0, 0xa31e48c6, 0x9821e1ae, 0xdd98efec, 0xe38cb09f, + 0x480cb3ae, 0x20b84fa8, 0x47475573, 0xba5bb4a8, 0xcd50e96b, + 0xa9be080a, 0xef103550, 0xc4451e9c, 0xc441325c, 0x626ee75f, + 0x38a5e33d, 0x6eea5e98, 0xa2b0abd2, 0x7321beb9, 0x9b6082a9, + 0xca92e484, 0x992bcc2a, 0x1dc8168a, 0x9c8eb9fb, 0x134ecf4b, + 0x4c5b71e0, 0x5a68bfa8 }, + { 0xff0a2bfb, 0xb4ff3b45, 0x5502f8b0, 0xd105fff9, 0x5b1c0c26, + 0x14de5885, 0x0d3b9d04, 0xed16865b, 0x026d3917, 0x2f5a2453, + 0xf4db3c0e, 0x6a22f493, 0xe2418f2e, 0x4871548a, 0x509bef61, + 0x6ab363a8, 0xb8cbbbec, 0x91ca1e3a, 0x4011a396, 0x71e0dc98, + 0x0d5ca577, 0xff982e0a, 0x81897bc1, 0xeb40b045, 0x085ad5e7, + 0x4bc24a46, 0xa6337b7c, 0xd15c8fa0, 0xbef1628f, 0x56ce6ef7, + 0x9f5ef439, 0x78acfdf9 }, + { 0xf8520189, 0x45bf7f15, 0xc77f61c4, 0x954202a0, 0xdfa22e1b, + 0x39edc6b9, 0x1f4a3487, 0xd2d60267, 0x4814cc52, 0xcd933929, + 0x05e9f123, 0xde76a124, 0xae36b6f7, 0xe2306ea0, 0xb83a58e0, + 0x53815218, 0xa041231a, 0x9862bb76, 0xbf31be71, 0xe8da253c, + 0x37de861f, 0x2dfc5332, 0x90ae4890, 0xf25c93f6, 0x8baa6ed2, + 0x66bcb8f0, 0x908b4a29, 0x6f10ae0f, 0xb061c949, 0x8cb4b48c, + 0xd075a366, 0x0ad92d73 }, + { 0xc2ca548a, 0xbfb95fed, 0x80cd89ab, 0x4778c620, 0x3466c280, + 0xbe99154b, 0xd4be8902, 0xea3be093, 0x13e681ed, 0x847b7995, + 0x02f40161, 0xf22a8f4b, 0x4aeb7fe8, 0x3ef2cb4d, 0xb3aed5f6, + 0x9adc5151, 0x98c31163, 0xec1ccfd1, 0xa3d7d88f, 0xdc2ac17b, + 0x46421097, 0x08fa64d3, 0x94b90bcf, 0x5ebf80b7, 0x0b50a9eb, + 0x1b78b4ba, 0x279aa66b, 0x1a4fe934, 0x075b3ced, 0x8ef4dcaf, + 0x70a6e9ae, 0x95bbd8a0 }, + { 0xe614bbd0, 0x59f92495, 0xb823e363, 0x7567a887, 0xfc1bd6a7, + 0xe247c9ec, 0x8e835c42, 0x2bfaaf47, 0xaade066a, 0x314ef4e0, + 0x5c16d336, 0x072baa63, 0xe2f0e389, 0xfa429c71, 0xbd07d90f, + 0xcac1e5d0, 0x514f5c04, 0x69ff35ea, 0xc0554ec1, 0x893053fc, + 0x2a35947f, 0xab1d86b7, 0x2aebe487, 0xe29fb060, 0xdfb9cf21, + 0xa0a10d6d, 0xf20dfcf5, 0xad147059, 0xb8867a2a, 0x480dc66f, + 0xc125a919, 0x375a884f }, + { 0x1217f7ea, 0x178cbe2e, 0x875c6dab, 0x1a161e2a, 0x1bdb1a54, + 0xf7707ec0, 0xe4fd73ca, 0x678864a0, 0xd13a0d86, 0xbaebc664, + 0xc8d30668, 0x40325f99, 0x2f1c5950, 0xb93ed9c9, 0x541e0667, + 0xfdf36763, 0xb91a6763, 0xfd97fbb0, 0x6079c9a0, 0x26aa69ea, + 0x1eaa8c47, 0xc7303c80, 0xafa63c55, 0xdec75c81, 0x4fd12adb, + 0x01cdcde2, 0x1968838a, 0x9fe0dda7, 0x38415379, 0x66bb093b, + 0x08cb84ec, 0x268d818b }, + { 0x41580555, 0x73dae358, 0x473d103b, 0x4fc32e67, 0xbeccc1ab, + 0x240c1013, 0xb24ee9de, 0xda4099f2, 0x9fa8e066, 0x37b0cb5b, + 0x6438d7ee, 0xb5ae04e4, 0x2b720140, 0x7f7d3164, 0x339e4a78, + 0x86ef4edb, 0x3a7d8375, 0xa5e77eed, 0xbd707c2e, 0x883fad37, + 0x0f979189, 0x816b633a, 0x2e7a208e, 0xe24c028a, 0x4435516a, + 0x1171fe3c, 0x4f5f2bf5, 0x3eb93b33, 0x01b53a56, 0x8419ed4b, + 0x056ca44b, 0x8b02735c }, + { 0xe1019195, 0xb89bb464, 0xf3fc28c1, 0x1de4c026, 0x2bfc3b21, + 0xac120e6e, 0x91bdf92f, 0xec71bc5a, 0x0d995bc9, 0x485d7ab4, + 0xe6491ffe, 0x97c6768e, 0xafbce265, 0xd9552d19, 0x8e1b76c2, + 0xbae6c7fe, 0xd7e3ad1b, 0x167d8281, 0x5e989734, 0x3e149af9, + 0x8a0c8182, 0xd1f0024c, 0xc3006c0d, 0xf571ffdb, 0x58773d4c, + 0xb32ecf7e, 0xfd3540d8, 0x5822a782, 0x04365042, 0x5ab45c3f, + 0x4b4d85fe, 0x400e3aa0 }, + { 0x5e46e4a2, 0x47321649, 0x24136074, 0x37a2ed64, 0xc60ec77d, + 0x659223b1, 0xe5e0ac2e, 0x5e13aac3, 0xc5107ab7, 0xda17c41b, + 0x73c253db, 0x65b22ec9, 0xa5012296, 0xff3867b8, 0x0621a99b, + 0xfed660d5, 0xc89fc3f5, 0xa3c28506, 0xf16451a7, 0x3ed350b9, + 0x67cb586f, 0x27c3e032, 0x967185b1, 0xc807c779, 0x4a13009b, + 0x09c157d4, 0xadaf1f4d, 0x362f7647, 0xf3a6a198, 0x4a42b9ac, + 0x8da6e039, 0x131c3da2 }, + { 0xa7da83ba, 0x4a785ff1, 0xd04f4436, 0xf415b425, 0xec03f812, + 0x7c0899bd, 0x80f5f4a2, 0xc58d411a, 0xfda251b9, 0x3d32d610, + 0xcd3b2f32, 0x99bb4504, 0xf4c2083c, 0x198c444b, 0x730e83fd, + 0x60c261af, 0xcb02db90, 0x060ca4df, 0x9df1e7c8, 0x0ff7838b, + 0xc4c690c9, 0x6b79cf97, 0x5d75f154, 0x131514d7, 0x1cb0e8ff, + 0xa7c074f1, 0xb2c17615, 0xb920aac1, 0x44aa0ff0, 0xde8098ad, + 0x34545ce9, 0x71d1a46a }, + { 0xfa1b382e, 0x76178f76, 0x772dda0d, 0xa0d8ecc3, 0xc5d4d130, + 0xaa5aab2a, 0x8d72622c, 0x27d38ba4, 0xca3bed06, 0xc5410db6, + 0x793ceccf, 0xf637a588, 0x6e65e3d7, 0x1f65dafd, 0x60a45641, + 0xc3b44a85, 0x4f78540b, 0x0f47b3a8, 0x5e4d60f6, 0x824fdadd, + 0x17d3b6d5, 0xd8ccf90c, 0x325fc13a, 0x008eabdf, 0x3648fab9, + 0x3e90d716, 0x24c52d4b, 0x3964ff3a, 0x533d0acb, 0xb95cc416, + 0x1167f521, 0x6cd2699f }, + { 0x12f4f3ac, 0x2d8c0b3b, 0x99d1bdfb, 0xb03dcfe2, 0x30f37326, + 0x540034f8, 0x7c5a8c82, 0x22dd6893, 0xcd8f1442, 0xeb7093d0, + 0x585742f2, 0x892795a7, 0x087adadd, 0xe15f282c, 0x16ab7b5e, + 0x7bbdc749, 0xa58acbb4, 0xd30fe40b, 0xe2bac39b, 0x0de417eb, + 0xc61a04bc, 0x4b4b19a6, 0xf2735569, 0x9338c34d, 0x30ab196f, + 0xe8f03742, 0x6c88c965, 0xfa2efcb8, 0xc7eeb826, 0x19eee274, + 0xda345dc2, 0x327c063f }, + { 0x5b47cd53, 0xab399eff, 0x1943aefe, 0xbbe9869d, 0x1402a866, + 0xe64ecc7b, 0xb1c25a16, 0xc3e7c2aa, 0x022de271, 0xc4216b79, + 0x366d6a5f, 0xe58dfcc8, 0xda813336, 0xd159509e, 0x130bfb7c, + 0x370400f2, 0x93b48780, 0x1be4e059, 0x39f3cd22, 0x0623a1fe, + 0xeecb4f87, 0x72aa22b2, 0x6c27b83b, 0x1af4c496, 0xda5fa5bf, + 0x7a42a94b, 0x48b01af2, 0x9afba822, 0x3670112c, 0xeb6b9d2a, + 0xc0df6856, 0x020f19d1 }, + { 0xa4dbba20, 0x37051a86, 0xdb1de5c5, 0xb618ebc6, 0xe6525840, + 0x9a780a19, 0xd2bccc4d, 0x9440302d, 0x10285a24, 0xe9ff023d, + 0x3a486268, 0x3b937ee3, 0x4cd61147, 0xe37ee2f2, 0xa3d057cf, + 0x79fbbfd3, 0xccddefce, 0x5fba16d3, 0x5b231727, 0x916058ec, + 0x720c3adb, 0x47699ebe, 0x8b4f6bba, 0x26274386, 0xf18a0770, + 0x54b0092a, 0xacca1160, 0x99d090eb, 0x0c888f60, 0xf757e1ff, + 0xb0050544, 0x79e72720 }, + { 0x2820a239, 0x632acf25, 0xaae6b310, 0xb1a3974e, 0x48c0a1df, + 0xd61fd6ba, 0x5a3ee7aa, 0xd2453c39, 0xb980446d, 0x548455a0, + 0xde16676f, 0x9f29d97b, 0x789375a1, 0xf252ca0c, 0x7743a985, + 0xe961af3e, 0x66cdbd8d, 0x70c79c56, 0xcbc538f9, 0x14a3854e, + 0xa126851c, 0x58daa73a, 0x2a9f558c, 0xe9b5bb45, 0xfbd15e05, + 0x37af7f83, 0x38a1939d, 0xa4487927, 0x9511a056, 0xe428b2b5, + 0x7015846d, 0x001d3ce3 }, + { 0xe145b1d7, 0xd6be36b9, 0x009c5664, 0xf3e3938a, 0xe7c0f6db, + 0x2e562e7d, 0xc343f539, 0x951044e6, 0xd90897b1, 0xa5ab62b8, + 0x512f797c, 0xb1a1f70b, 0x750f28e4, 0x91cdd754, 0xffb8165d, + 0xb4c80e2f, 0x594d02b3, 0x65ed39c7, 0x56833edc, 0xcc12a49d, + 0xf3693a18, 0xe73694bc, 0xfcd2c404, 0x34cc134a, 0x11d40194, + 0x071bd5fc, 0xfc585e46, 0x05759047, 0x790b7a04, 0xb3280360, + 0x40afc684, 0x4bb8c6fc }, + { 0xfd0f8796, 0x3120e2dd, 0xb133c9de, 0x6968a40d, 0xa9369c6e, + 0xfea366c0, 0x6007273b, 0x37e5b6d6, 0x8cb81439, 0x39e4ecf0, + 0x9febc005, 0x487fe9cd, 0x0199b53c, 0xeb8af444, 0x293519eb, + 0x2f124e3b, 0xc82c9c16, 0x860c218a, 0x709dc590, 0xacd1d6f2, + 0x36d50529, 0x5696d545, 0x59120bfc, 0xc03f5df9, 0x10ffa690, + 0x99a3e88d, 0x6c432827, 0xd4f9cfa5, 0x9a135d89, 0x2e8fea9e, + 0xb6a77e78, 0x3699a881 }, + { 0x1eb1c64d, 0x5bca3372, 0xf1d28154, 0xe9cf3a2d, 0x6537106f, + 0xb7e2e9b3, 0x4f7cbf4d, 0x06c17151, 0x2058b37f, 0xcbde416e, + 0x8834e9c5, 0x82c53a7e, 0xe9ac3a75, 0x94dbdfe2, 0xc5e67c02, + 0x795ec6cb, 0x1426a80d, 0x8c23c25f, 0x6a8d4f9f, 0xee2cd20d, + 0xd3b7c235, 0x838daa54, 0x3d7a4d52, 0xb9e08ec0, 0x781cb473, + 0xca9475e9, 0x5ec31caa, 0x7271f39e, 0x82535187, 0x1df08e9f, + 0x208aff8b, 0x4f3a4b03 }, + { 0x1ed095f8, 0x0f7b8107, 0xda226d4e, 0x23e37fa6, 0xafb36d1d, + 0x8b0f9852, 0x07d8e311, 0xb114634e, 0xe3e0f16e, 0xb9634a97, + 0x421eec37, 0x2454bb9c, 0xd72b21c1, 0xb4ecd5db, 0x6df20d7c, + 0xf9603868, 0xdf86e0a2, 0x9f5359fd, 0x5ac488aa, 0xc43d54fa, + 0xd1049df4, 0x56d714ab, 0xb020607a, 0x13152b3e, 0x7a02325e, + 0x49be1c18, 0x52ae84db, 0x44f24f4a, 0x0b5a7b80, 0x9e525c03, + 0xa6d179fd, 0x6d874446 }, + { 0xbe9a42f5, 0xd29d07aa, 0x3781ccc8, 0x1fd5316c, 0x9dc69ea1, + 0x71a75a6d, 0x88fee91a, 0x4e19e0df, 0xf8d44f12, 0x99c2b4dc, + 0x31ae94e4, 0x05f6df92, 0xcf28ccc2, 0x27fba876, 0xf57f7ceb, + 0x6e1a0f01, 0xf3fd3b74, 0xe03f1f34, 0x42c1d213, 0xa0edc4a7, + 0x7deb8580, 0x5caac270, 0xaf0848bc, 0x0f5d791f, 0x07ac759d, + 0x17f514ad, 0x904fc531, 0x95a39734, 0x7bb70f3d, 0x95a4aca9, + 0xff9c5609, 0x3cf384c9 }, + { 0xce1fc9e3, 0x700506ba, 0x676b0399, 0x49721742, 0xe72bf7b3, + 0x2b4a1b8d, 0x79b209f7, 0xca8602a8, 0xce26a8e1, 0x90580b90, + 0xfe24f39a, 0x1ef339b7, 0x629362e1, 0xb6c5d991, 0x577b24f4, + 0x51174e1a, 0x05e451e9, 0xf380fcb5, 0x148321bd, 0xf4d97afb, + 0x747e5d2a, 0x099806bb, 0xbe99a608, 0x85525d65, 0xd455e820, + 0x264828d9, 0xd8560a65, 0x8c8c5405, 0x71030770, 0x3c67e73c, + 0xee73df26, 0x2b248850 }, + { 0x8541159f, 0x2173cde6, 0x4fb410b2, 0x78224c18, 0x1f2ca1c7, + 0x07a28619, 0xa8b23e40, 0x52c207d6, 0xa6b2344a, 0x071a0210, + 0xb5ed2945, 0xdb0e587c, 0x810fcc6c, 0x6c56b8ef, 0x62d843b9, + 0x1248c58f, 0x74c66975, 0x4b90363d, 0xe66c66f6, 0x6348f7f2, + 0xc126bcbe, 0xb2f9d441, 0x73ce49e8, 0xac07f2a3, 0xe81b0df0, + 0x52486758, 0x1d4621d1, 0xa108b54d, 0x74414a1c, 0x17261ece, + 0x6a3ac215, 0x938b3bcc }, + { 0xe4ded340, 0xa9e4a16b, 0x80e88036, 0x8e65fb2a, 0xdcd73acb, + 0x97089606, 0xaaa657a9, 0x1c3a0434, 0x49101b06, 0xf304fc58, + 0xda0bb64c, 0xe60fb61a, 0xf5542df5, 0x818c2aec, 0x56f76d5f, + 0x74020576, 0x92533d97, 0xb566b790, 0x74d6eb5f, 0xae4655e5, + 0xa55b44b7, 0x60f7a1b5, 0x93747ea5, 0x7970179b, 0xf2dace56, + 0x8ae7e0e8, 0x84e83c06, 0x98474607, 0x15307341, 0x24e8c9ed, + 0xd9e89d6b, 0x6cff58a5 }, + { 0x03e51f68, 0x508c01b0, 0x1d2fe7d6, 0xe1d1f225, 0x09bd8805, + 0xf7998d0b, 0x03e415b7, 0x255e907a, 0x607d9798, 0xd148467d, + 0x9b453896, 0x055c3b1e, 0x809f50f4, 0x35001013, 0xd0233fdc, + 0xfbbb2fa6, 0xff1820b8, 0x0b680b0a, 0x38d317e0, 0xb1d404dc, + 0xccc8c7df, 0x133d5444, 0x6ec13f84, 0x7fa847e6, 0x046e2e48, + 0xc33f83d8, 0x4863b3ac, 0x3c627fc5, 0xeb936af7, 0x5f67f8aa, + 0x31b79327, 0x5fe4ac8f }, + { 0x8b6f401e, 0x581aa4bf, 0xad5c7ed4, 0x05db12a3, 0x6fb07b4a, + 0x7b018726, 0x9c22bcd4, 0xfdd11f04, 0x69371c95, 0x5454a7d4, + 0x99a46eaf, 0x066c55fb, 0x7fef96d0, 0x18637c7c, 0x6b83e95c, + 0xbafc1d34, 0x00bb42dc, 0x55c38593, 0x34e7e712, 0xdd8dec2b, + 0xb184cee8, 0x69c9cfb0, 0x49a27864, 0x8dcc0c42, 0x2010f2e7, + 0x290d95f2, 0x6977a420, 0x86e254c9, 0xeb2abdad, 0x20931c89, + 0x121c0548, 0x81377164 }, + { 0x9c5a8edf, 0x6266b25e, 0x1078a7ad, 0x6e1388c2, 0x4876eedf, + 0x5f02737d, 0x62744617, 0x242fa7f9, 0xb385382a, 0x3e2cfbd9, + 0x02f71bef, 0xbadad7b1, 0x677d0a92, 0x562abcfa, 0x51fdff34, + 0x573ebd17, 0x7c250c78, 0xd7f65852, 0xc47ca896, 0xe0cf16ee, + 0x67622c9e, 0x8ccd79b0, 0xf8f2c075, 0x31fc5882, 0xa6008515, + 0x9232b37e, 0x82e8c5ba, 0x4d7bb361, 0xd2f146fe, 0xbf24735c, + 0x9cd2db98, 0x79c280ee }, + { 0xf2b48122, 0xbdcc8203, 0xb04ac48e, 0xa8c04916, 0x9fc4885e, + 0xacf064dc, 0x82c1001c, 0xab838997, 0x676de250, 0x7339e721, + 0x8e1ab820, 0x17aa5aea, 0x6bc14b2e, 0x24d28ca0, 0x816b6230, + 0x570c5bb7, 0xcee6b606, 0x6c51235c, 0x183eae42, 0x1b2bf89f, + 0x9c66274b, 0x3e3af3c6, 0xb51e38bc, 0xe0b04426, 0x73e40e3b, + 0x26dbc58e, 0xb5be5be4, 0x3f9dd578, 0x52c8f408, 0x9fd9f791, + 0xa9e3ff4f, 0x758073a4 }, + { 0x8691ca22, 0x7d27b057, 0x13a2a1b6, 0xf206bfd6, 0xac795413, + 0xe84bd385, 0x75536607, 0xc5d18a2a, 0xc8a0e24c, 0x2e166de7, + 0x3c474dbd, 0x56d5750c, 0x1366843a, 0xdef444c1, 0xcf4b8432, + 0x14646e53, 0xa9fd9783, 0x4bc0d030, 0x297ee203, 0xbda4c824, + 0xfd7be6c7, 0x3d0b10bf, 0x08c7f3ff, 0x2d216476, 0xb4fd4c45, + 0x06e52599, 0x49e9e104, 0xfbab9fa1, 0x8661d32d, 0x9342a7fa, + 0xfaf66aa8, 0x3f3e3458 }, + { 0x951597aa, 0x51ec35af, 0x49df64eb, 0xb677d4ac, 0x9bf4eff5, + 0x0276cd9c, 0x515a2935, 0x423eca49, 0xfd9bb9c3, 0x8a696553, + 0xede1f09c, 0xf99ee9df, 0x199e5f98, 0xb8fa2956, 0x35292c32, + 0xb7638758, 0xfc40e81b, 0x8734eddc, 0x65457d95, 0xd82d5e9f, + 0x30c78d2b, 0xc8ee323e, 0xc1433d67, 0xe77b2e4c, 0x3c8314ae, + 0x56d9f807, 0x2a0e2f63, 0x441eede2, 0x6c48295e, 0x1e9e17ed, + 0x34c294ef, 0x640d20c4 }, + { 0x3284d513, 0x4e9a0b8e, 0xf315053a, 0x074c3545, 0x45acd52a, + 0xb36e7407, 0x1de50db7, 0xd80bdcfc, 0x2549fc46, 0x8d9d47dc, + 0x303f07a8, 0x29b6ef13, 0x6d4ad4c2, 0x4e461aca, 0xfc9f1b73, + 0xca8e351d, 0x57460e65, 0x8bc4094d, 0x0f32d367, 0xb6302b33, + 0x285742e8, 0x69a074b6, 0x876c29c3, 0xdfe52b11, 0x912bd17a, + 0xf39e4609, 0x349aa639, 0x8ee40d66, 0xc72e05c1, 0xb968902a, + 0xc0d92816, 0x0f9c1ca8 }, + { 0x67433df3, 0x1ebbaab3, 0x15d3628c, 0xb6aa5347, 0x97f0c5cc, + 0x13a320d8, 0x65e408f9, 0x72c918cb, 0xd5373451, 0x4b638854, + 0x0b4dca09, 0x731399a3, 0x0a3b1326, 0xcf256730, 0x6608b388, + 0x5ea60dfa, 0x7b290dfd, 0x58ad74b0, 0xd7694f9b, 0x83202789, + 0xb6630fb1, 0x48593db8, 0xc65e3eaf, 0x3db47f70, 0x3e7263f8, + 0x63949c91, 0xe6e6ff33, 0x9b9acec6, 0x098a8240, 0x34bd9ba7, + 0x45d36ec5, 0x7e31c12f }, + { 0x0dfd2dd7, 0xbe281d68, 0x24ab61d8, 0x1efacb00, 0x94431f97, + 0xb9c3005f, 0x959cb3bc, 0x660c8dfa, 0xcffbb406, 0xfdd5fc30, + 0x7969a10d, 0x7a4631be, 0xde13fd1b, 0x336e309e, 0xfc947076, + 0x76b3bfad, 0xdcc72223, 0xfa91925d, 0x156c4ee1, 0x741f0d73, + 0x0e2b3747, 0x4f64ee41, 0xefc4d93c, 0x86be92d3, 0xfc4fbb2e, + 0xc53b7e03, 0x337ca1bb, 0xac196cf5, 0x7e23ba60, 0x4de41a30, + 0x326d5357, 0x1a219c45 }, + { 0xaa4db0bc, 0xfdcf7ef8, 0x7b6c9963, 0x2e231806, 0x3d8a192f, + 0xc2639067, 0xffdc7771, 0xc0cec2e2, 0xa2fc0edb, 0x997c8e35, + 0x82cc6043, 0x78e10ec1, 0x2b0c8120, 0xfd0de2cb, 0x69e57f8e, + 0x4d6c457f, 0x5b53f1c3, 0x953e69b2, 0xc4f89cb8, 0x422a330a, + 0x95566be6, 0x92ff2329, 0x437442d1, 0x73cd502d, 0xbea69403, + 0xf04ce590, 0xf8030662, 0x6ac1537e, 0xb6d0bf93, 0xe02bcf77, + 0xbc90192f, 0x17aaa999 }, + { 0x8e55db2e, 0x0d3d5643, 0x3b946851, 0x835dee43, 0x5b88462f, + 0x1a1440e5, 0xea17e27c, 0xa6ff3b35, 0xdd95f7a9, 0x23f99c36, + 0xbdd672cf, 0x7217fdd9, 0xdd2045c0, 0xf400ac1e, 0x4ff06b25, + 0x94b55c87, 0x0e4a49be, 0x0a44a0e5, 0xb43b6813, 0xe8925e91, + 0x214f96c5, 0x78bedde1, 0x0f97fa97, 0x0f456a4c, 0xa5bfd267, + 0xa28fd86b, 0xbe7608ef, 0x3b4b2d8f, 0x226474bc, 0xfbd5ff8c, + 0xa5f3b24a, 0x6b282af0 }, + { 0x6341a595, 0x78fc025f, 0xa445e28c, 0x591c38d6, 0xeb446842, + 0x72bd6e3d, 0x75547833, 0x3f9466d3, 0x083e16c4, 0x911414d3, + 0x95a7acb4, 0x145d9466, 0x8fd2fb64, 0x102ddf09, 0x0bfd87b1, + 0x2a2b2d2d, 0x59455088, 0x69e9be5c, 0xa80245de, 0xee378bf4, + 0xb2306b0e, 0x80b0bd68, 0xc2be9f3d, 0x76a545c6, 0x4802c245, + 0x429d167b, 0x2b412dfb, 0x13e64427, 0xee8d9762, 0xb664f529, + 0x54706ebf, 0x6d4f5d23 }, + { 0x00ba9f88, 0x35c8f2b6, 0x7bb6d0bf, 0xfdc807e0, 0xb3b81e5b, + 0x0a126d42, 0xa7ac781e, 0x335ce6ce, 0xf37dcba6, 0x3e308e6f, + 0x63c96487, 0x028dca62, 0x8818434d, 0x72eba57e, 0x79b78a26, + 0xa9e3d59f, 0x2f07aea3, 0xd2f0a7dd, 0x24d05f74, 0xe0fe4678, + 0x0116deb6, 0xb2085170, 0x58f37580, 0x9c2a5e92, 0x74070bb3, + 0xe78bd7a5, 0xb9977d90, 0x551fc872, 0x40db81b4, 0x6eda93c4, + 0xd65d34ad, 0x4aaf0b4f }, + { 0x3514c7af, 0x9bef2506, 0xbc181ead, 0xb09e7dad, 0x8fa3ec58, + 0xef3cae87, 0x173b8685, 0xd8dbfab5, 0x921d32dd, 0xb2490fc0, + 0x8bd9c466, 0x4eef386b, 0xa061dbdb, 0xc1cdd52f, 0x25bc04db, + 0x64de989a, 0x85728636, 0x06f9836b, 0x8be44aa0, 0x11a5a804, + 0x097018c7, 0x16dede4e, 0xb2c11fb1, 0x72aec577, 0xa721ecd9, + 0x144dade1, 0xd6ebf3a9, 0xf99c526b, 0x1c2e14d7, 0xa1d4165b, + 0x82bc6337, 0x8b2cbd39 }, + { 0x8a52e991, 0x28ec1bf2, 0xcf9d42ec, 0x0ba202f6, 0xc634ea45, + 0x8307d130, 0xc5762b9c, 0x3fc257b3, 0x487c2a2d, 0xbd3298d1, + 0xa319488a, 0xca14f1a7, 0x06ba06d2, 0xc70ca93b, 0xee405e89, + 0x9aa3f4b3, 0x35deeae7, 0xcc64eeb3, 0x03bf1d4c, 0xd155f578, + 0x45616bfd, 0x041ec0b5, 0x086e33f6, 0x23df80e6, 0xf0243cf5, + 0x399a79c8, 0x874ccd58, 0x86c2824e, 0x8fc5c831, 0x220eeaec, + 0x7dbe3670, 0x57e28304 }, + { 0xfbcdf666, 0x6e60b698, 0x8bebb1d2, 0xbdd06a99, 0x80498436, + 0x4044adba, 0x522bc88d, 0xd76bf75e, 0x28423b20, 0x655c4b9b, + 0x53398a72, 0x65c0f492, 0x0ca37601, 0x76d4f2b7, 0x2030fa5a, + 0x46989925, 0xb6054705, 0x96b37e87, 0x53de1b2f, 0xef96f731, + 0xad54ef05, 0x5ecbbc8c, 0xa93617b0, 0xeb289d0a, 0x7cba217d, + 0x3ac0fbd5, 0x19d4a2d7, 0xd0d3cb56, 0xc91d6063, 0xe8bee9d4, + 0x696ffda6, 0x4f12e037 }, + { 0x15f1a610, 0x4ccfa422, 0x3786519a, 0x804a5c55, 0x73838134, + 0x1246a454, 0x4b284e2a, 0xfa15b484, 0x146d1320, 0x36464c65, + 0x70a8a0fa, 0xfb6ba88c, 0x93c4804e, 0x74e7cee7, 0xb95ae16a, + 0x8c34d22c, 0xf9c1d4dd, 0x9d9ed89f, 0x32025371, 0x61a0866d, + 0x9bd6444a, 0x45b232b2, 0xf277bab1, 0xf888e92c, 0xa9448b02, + 0x73e69c6e, 0x5b521ecb, 0x1a496ea9, 0x5858afb2, 0xa8f78ea7, + 0xb1266f91, 0x83d2333e }, + { 0x67b478d7, 0x1c633288, 0x50a2fc9c, 0xa1ee1ae1, 0x18d2241b, + 0x05b6ab30, 0x893cd696, 0x69f1f288, 0xa8117a87, 0x159d6660, + 0x70e73d77, 0xe8120119, 0x93f55f0a, 0x528fef00, 0xd854dfb2, + 0xb3978db8, 0xf45d9fbb, 0xd6b43ef6, 0xd5bee397, 0x17de4bfe, + 0x6bf76dad, 0xa01e0f59, 0x3d40754c, 0x28b2280e, 0xf8e86ef3, + 0x8edb6122, 0xb7d1e586, 0x8226b6af, 0x2f40a55b, 0x46353215, + 0xc5a31621, 0x7362f13e }, + { 0x73c0c430, 0x792eb27c, 0xa51c3657, 0x8cc0a65f, 0xd2194f1b, + 0x50a5cece, 0x814b4947, 0x18945688, 0x4b6fbbf4, 0xbbf0a81a, + 0xf0aa8608, 0x376f4f58, 0x3987795e, 0xd9361d68, 0xe3a8d0d5, + 0xb6510cd8, 0xb6c1a455, 0x63e2fdbf, 0xaec891f9, 0x2c91154e, + 0xff568f64, 0x0eb1e715, 0x2f2b399e, 0xe7af9cd7, 0x89f0bf0b, + 0x1fc39bac, 0x90983695, 0xf0861d92, 0xda0a20a8, 0xd9b16f02, + 0xa38c0ead, 0x2f10693f }, + { 0x0c06ded2, 0x07a6ce91, 0x2fd9087b, 0xf974842f, 0xa9f635a6, + 0xe468bfd6, 0x1ed60626, 0x04b61891, 0x369ee548, 0x1fb2f89f, + 0xdc96a201, 0x9cbd1113, 0x10d633ac, 0x6759acfe, 0x8faa629e, + 0x64ba66fc, 0x47f38283, 0xa686ae49, 0xd59cda99, 0x828c3a05, + 0x08ea2f6e, 0x7c7afb14, 0xaf3953c8, 0x2551c8e4, 0x9daa9e4f, + 0x5b53d279, 0xad6f1940, 0x1eff68d4, 0x96437cdb, 0x2775dbdd, + 0x4fe7a043, 0x985f83e4 }, + { 0xeaf45294, 0x89603c16, 0xc24b5751, 0x70131160, 0x39d6b52d, + 0x4c112018, 0xed943340, 0x7079cf02, 0x74f41b68, 0x0c5b028b, + 0x9c8ac1e1, 0x3dc3f076, 0xf8b24f0e, 0x5ac5eea3, 0xe34c5c22, + 0xee6684ba, 0x9abc452a, 0xa5259e63, 0xe9df45cc, 0xb07d2cd1, + 0x1a443cfa, 0x07019c93, 0x92c003b3, 0x68fddaa9, 0x0d8cbc2e, + 0x2d9f179c, 0x1e781ca7, 0xbbf15a6f, 0x50dcc799, 0x54d779d5, + 0x0fe962f1, 0x0c88e540 }, + { 0xe8f44357, 0x84f71a6a, 0x3a3cab6a, 0xf75b4bf6, 0x5aebc680, + 0x334c9d9e, 0x8a753ef2, 0xcecaf084, 0x075e3c8e, 0xe28014c1, + 0xf74f8d3a, 0xbb9d5a38, 0xb80e32ae, 0x75988464, 0xf2bc3792, + 0x7b328e6f, 0xeed0e197, 0xebbb1faf, 0x5a33065a, 0x674eac95, + 0x922dbce8, 0x8c19fd8f, 0x987b907a, 0x8c17ae85, 0x3b3a2cd7, + 0x89f33627, 0xfa87772f, 0xebaea019, 0x3a25ced6, 0x4e5de499, + 0xaf110715, 0x8e2560b8 }, + { 0x3141aba6, 0x56d3746c, 0xbab2cf9e, 0x45a1079f, 0x9cdd27c7, + 0xb6382831, 0x9dfd950e, 0x22237632, 0x3a9408ff, 0x1e0b15cd, + 0xb1160118, 0x49a80200, 0xa383bba7, 0x2719db5d, 0x651046d5, + 0x6078340a, 0x97523b1f, 0x8929d4de, 0x8e0a28ab, 0x4040345c, + 0x0adf09c7, 0x61275ac2, 0x2331d611, 0xb41ab265, 0x5391ca50, + 0x230cc77c, 0x8f922315, 0x88be0c92, 0x92fd9a29, 0xfef3d92b, + 0x8324f2e5, 0x59005f22 }, + { 0x3c4c1c74, 0x6bb1750c, 0xe966fb79, 0xbe73aac0, 0x66c5973f, + 0x85a75d92, 0x3a8656b6, 0x8c97f932, 0x50446cde, 0x2b7043b1, + 0x3ff3897f, 0x548916f7, 0xb18b72b2, 0x913dd01c, 0x488c0de6, + 0xd0a751f1, 0x8558ca58, 0x19175714, 0x44a663da, 0x97714301, + 0xb0e08618, 0x2df190ac, 0xf39ead9c, 0x0080fc0c, 0x17382da1, + 0x0085ac6e, 0x3262a338, 0xe9791851, 0xb43bae8d, 0xe4495936, + 0xd783df6e, 0x57a78e26 }, + { 0x40dbddd8, 0x161b346f, 0x9410c3ac, 0x2b49a927, 0x1886cf3b, + 0x8c542783, 0x33b93deb, 0x72df3232, 0x40df579d, 0x9c8d59f5, + 0xc20ef500, 0xe5d7a67d, 0x67f08643, 0xc46b3918, 0xad96adc3, + 0xecfa2445, 0x0c4544d0, 0x658f589b, 0xe08417d7, 0xe6ec9301, + 0xc454e288, 0x6ca5ef6a, 0xac0f462d, 0x4191048f, 0x08d8a036, + 0x852407d8, 0xf6d35b7e, 0xb4c533a7, 0x8f6ada87, 0x3251e412, + 0x81c472e8, 0x1ca370c5 }, + { 0xa801b68a, 0x94bd5171, 0xfd1998b3, 0x7312879c, 0x41163202, + 0x4905aabf, 0xf5b01fdb, 0xb5fe87f4, 0x9cda128b, 0x78de523a, + 0xc7bd31f7, 0x0bf161a1, 0x23904c35, 0xb5decfd0, 0xe188f12d, + 0x224b2882, 0xf99dae74, 0x0dd2801d, 0x08cd1cd2, 0xcad467b5, + 0xc0867e39, 0x6c311c3d, 0x2b425072, 0x71a11720, 0x2efd9003, + 0x83bf464e, 0x1dbd3b03, 0x53d0448a, 0xe6265baa, 0x32db52f4, + 0x4c33ac79, 0x2584b34c }, + { 0x2aeec688, 0x3cb86389, 0x45fbe523, 0xa5e740ba, 0xfd60b5f8, + 0x422e71f7, 0x4874913d, 0x455d185c, 0xfa17d80d, 0x04c2bb36, + 0xac054524, 0x3f271854, 0xa8b9a657, 0x76dd3045, 0x62ee7cc8, + 0x2e42c3e1, 0x4df6c7d0, 0x00266706, 0xdc7cb488, 0x5927dd51, + 0x187897e0, 0x6b3faabe, 0xf2d5737c, 0xfe6ad22e, 0xff51a9ff, + 0xafb60269, 0x69807baa, 0xe1c83545, 0x951ca49a, 0xacddb6ff, + 0x3f9ab085, 0x7e811374 }, + { 0x830a88b1, 0xad722a8b, 0xce1117e1, 0x91918ea8, 0x0409b47d, + 0x3e02d0b8, 0x6c46d1d3, 0xb53812d3, 0xe589669c, 0x2fd09db0, + 0x15b0cd5e, 0x9845cd06, 0x2386c453, 0x0c1c155a, 0xf5ff43cb, + 0xda774de5, 0xe391c0cd, 0xbb076b98, 0x5004f286, 0x97d71eff, + 0xaeec0bfe, 0x23e0b46c, 0x32a1ad94, 0xe4538667, 0x396da422, + 0xfe0c9f81, 0x63db2bfe, 0x6376c1a2, 0xba56fa91, 0x001c7918, + 0xdf8485a6, 0x436b8c64 }, + { 0x8ab764bc, 0x88117e9d, 0xa077df84, 0xdfa61e94, 0x0c18eebd, + 0x5a7765d3, 0xfc9451dc, 0x548916af, 0x071a347a, 0x01a52e33, + 0xb23b41df, 0x633b95de, 0x43c8c286, 0xdd7d68c9, 0x18d97068, + 0xe4f9d41e, 0x8c92799d, 0x79908b90, 0xd47394a3, 0xe614148e, + 0xcd51e53f, 0xe5018517, 0x0243dcb6, 0x5060075e, 0x17954405, + 0xe5dcde62, 0x537da5ff, 0x6f7c90e1, 0x0768cb66, 0x1df7aae4, + 0x6dbe95e1, 0x5266ca9e }, + { 0x1386b3db, 0x84ddee6d, 0x7c38e540, 0xf9e4af5a, 0xeb04f49d, + 0xb3418440, 0xfde5a4fd, 0x2138a1e8, 0x30257cfc, 0x3e6e6924, + 0x19fd70c1, 0x3519c6e3, 0x86c31ff0, 0x8f34e174, 0x940ce1e8, + 0xf1e298fd, 0x14960d7c, 0x6fb8cb1d, 0x2b2f3bff, 0x207c1347, + 0x146ef8ff, 0x899a20b4, 0x7bd3e220, 0x7dec362b, 0x626bea27, + 0xa975044e, 0x4fb4cb67, 0x0f32b449, 0x1fc6703a, 0xc17a0920, + 0x9cd84a2b, 0x41f325b9 }, + { 0xce2843a4, 0x312ed513, 0x00728afc, 0xe748498e, 0x4d864ce5, + 0xa8ef2822, 0xa620083b, 0x34064704, 0x4bed338d, 0x5905e1d9, + 0x063e7b38, 0x2a578cb5, 0x289e7bb9, 0x98276d96, 0xf17b7341, + 0xdfe2dc47, 0x1dac8944, 0x5923521f, 0x23400aa7, 0x3db6d28d, + 0xa761ba43, 0xc647705e, 0x9bfd07dd, 0x8947ba6d, 0x242ca8fd, + 0x00f2e3ac, 0xeb8c3468, 0x49ef4670, 0xd9aa18fd, 0x7db3d37b, + 0xe58cea9e, 0x56b30fb6 }, + { 0xcd80a428, 0x07ecdcaa, 0x8732c891, 0x7af922dc, 0x3ada441f, + 0x20d88798, 0x924b008a, 0x3bed9a44, 0xb2e81c3a, 0x2123533c, + 0x65f807d3, 0xc34e4075, 0x1f2faecb, 0x0bfaefa5, 0xade8a88d, + 0x78b634a5, 0x94392a91, 0xc4e0b7f8, 0x90bb1cd8, 0x30922377, + 0xf87204ae, 0xdea9b4fa, 0x85d3cd83, 0x3edf81f5, 0xc6523a79, + 0x58f88c51, 0x17c0d969, 0xe472fb8b, 0xdccf7f07, 0x899081e5, + 0x58bdd146, 0x1353cc57 }, + { 0x39bf6e18, 0x28a56497, 0x649b89c7, 0x59e8b5a2, 0xdce8b8e7, + 0x8d9434a0, 0x2047040c, 0xd935bf51, 0x6a7b8e82, 0x2ab3a164, + 0x27f81294, 0xf1583ed6, 0x72d67297, 0x8416a7e0, 0xcd39e42b, + 0x49685d86, 0x958ddbad, 0x8a797fc7, 0x155ce6de, 0xa558f928, + 0xf8a36235, 0x75f4e570, 0x52877ae5, 0xbc69cfc0, 0xa6b16ebd, + 0x8f4193a9, 0xbb1cc1f1, 0x8d1df43c, 0x5a21e789, 0x723a830e, + 0xf451df58, 0x3ec2185d }, + { 0x1f0bc2d7, 0xb9d4c7d7, 0x6e51d412, 0x6982c6cc, 0xa09f80f6, + 0x92e02d93, 0x047ae09c, 0xb7dd2d25, 0x37f351f9, 0x3503149f, + 0xc77850be, 0x69d49ce1, 0x12f0d2c8, 0x60242acb, 0x7bc28b9d, + 0xba188c56, 0x06bc0550, 0x8e406121, 0x8d7d4329, 0xb0d84b1f, + 0xd38951e0, 0xb4a67ae7, 0x8bc97607, 0xb527c57b, 0x5497aa72, + 0xbc93c5f3, 0x39bdd666, 0x5f1de8cc, 0xe9d447a3, 0x3087dc5c, + 0xa211abe5, 0x89b356b6 }, + { 0xdfdcc837, 0xed6db0af, 0xa871b7a9, 0x0fb80baa, 0x1c1d4b72, + 0x413abfc9, 0xadac9e5c, 0xf5b56bf7, 0x8b8657a3, 0x5664a2da, + 0x0e41d94e, 0x11b04f72, 0x37433658, 0x63e11d26, 0xf426daea, + 0xee628ece, 0xcb162dc2, 0x011619c9, 0x87648643, 0x9cf5817f, + 0x5584bc86, 0xe1bb9702, 0x00bf7928, 0x2cc27cef, 0xdc60eee5, + 0x4ef3a80e, 0x87adc2f9, 0x7e1202be, 0x8a0d4f52, 0x656f18e0, + 0x57c5d126, 0x39c4f10d }, + { 0xe88aecd3, 0xb3a9b68c, 0xa518aa9d, 0x555b0918, 0x4bd4ee54, + 0xedc1cdad, 0x02068d84, 0x79b68b67, 0x811ac72d, 0x7dac80d0, + 0xa81a0a78, 0x6d1e6d35, 0x3bd16283, 0xc841e9ea, 0x894c4444, + 0xa7bc1775, 0xf1aa1202, 0xf2b63725, 0xc7d4c556, 0xbec7767e, + 0xd46ff51b, 0x2817ebb3, 0x73f7e339, 0xfde5be8d, 0x5aed24c4, + 0x44c6c977, 0xb6e579cf, 0x0b9a1707, 0x9069fbcc, 0xcff16478, + 0x49152b00, 0x414b542d }, + { 0x606e173b, 0x33c31e58, 0x90e6713a, 0x5b7f4e1b, 0xdebb20af, + 0x425fb512, 0x05120e70, 0xc788c617, 0x9013e4ec, 0x3ef05602, + 0x81c6e6d7, 0x9f9d35ac, 0x9450690a, 0xe131e88f, 0x44af082e, + 0x708f9b32, 0x1ba2aea9, 0xb2e4d66c, 0x740db29c, 0xaf1f4a6e, + 0xd1843007, 0x74ab9248, 0xed556a6c, 0x13338ef8, 0x270d17a6, + 0xf48e623e, 0x9608f5bf, 0x3c7362fa, 0x444e8515, 0x43977874, + 0xe00b8b2a, 0x52678d6a }, + { 0xdf36aeb4, 0x5dff1c59, 0xa92bc0ab, 0x52d6653c, 0x927a5f81, + 0x0e03f496, 0x2dfd491f, 0x8509d414, 0xa571f89b, 0x258c2c52, + 0x93334485, 0x2bd61804, 0x3f7d9e09, 0x1a33e94f, 0x2c1bf906, + 0xfab418d3, 0x5aa5695c, 0xf39c490e, 0xf6d2d7ff, 0x0e41196e, + 0x0f7948a9, 0x3ecd4075, 0xd3053b4f, 0x4b58f9b2, 0x5d9974c9, + 0xb8ee842a, 0xbf22f682, 0x23a59c1d, 0xc8efcea6, 0x045ac614, + 0xc10ceedd, 0x7040ba5b }, + { 0x515a1a96, 0x2c364f81, 0x184327e0, 0x31a63503, 0x1ad93d4f, + 0x0a096650, 0x273b6173, 0x9d7694f1, 0xd2cda9d2, 0x8886d876, + 0x2814c177, 0x1e01a742, 0x8667696b, 0x3492276b, 0x5b25f006, + 0x2fd4f0c6, 0xfb294c4a, 0x6527349f, 0xde1d336f, 0xc1fe0d8a, + 0xe7e3860e, 0xaf9a23e8, 0xb774c31e, 0x97d2b721, 0x4365784a, + 0xfac3e582, 0x70f4eaa3, 0xff2dff4e, 0xfe873248, 0x3d281e1a, + 0x0bd1c9c1, 0x9043a6d6 }, + { 0x766c7937, 0x1511a0fe, 0xabbc3be3, 0x1b2ded5c, 0xe00888ac, + 0x2ac160cc, 0x616200f3, 0x928754bd, 0x34a2ea06, 0xb801c83d, + 0x9cbe106f, 0x8ad7a03a, 0xcedfcd94, 0x996b0822, 0xe4069880, + 0xc3c3463a, 0xf597f663, 0xfb12ea4d, 0x40c92af9, 0x2c8d3834, + 0x4e8da154, 0x79bc85c6, 0xdb4e801a, 0x95771fa2, 0x1e3579b2, + 0x7bd2c138, 0xffaad078, 0xe45c75df, 0xb73eac46, 0xb0760a3c, + 0x3a125f35, 0x26362b48 }, + { 0xeefc3e89, 0x25c68d28, 0x69e9ee71, 0x2d0ee877, 0xaf5e4b75, + 0x8b07bb86, 0xcb86b333, 0xdb709072, 0xff552bac, 0xfd3d20ea, + 0x4c0da1e9, 0xa5eeb2b1, 0x44f97145, 0x391f688a, 0x1e06d485, + 0x21fbd310, 0xbea9cd49, 0x45e4f2a5, 0xa7bf21da, 0x7b60d464, + 0x054d5471, 0x193f88c8, 0xbee0f2e9, 0x5ace53d1, 0xc1439273, + 0x92c26563, 0x96c6b5ee, 0x9c86e0b2, 0x09ff59ba, 0x452fe231, + 0x555c935e, 0x2e952b20 }, + { 0xd75f886e, 0x2a846bca, 0xd43dfc58, 0xe68a5dbe, 0x007b1b86, + 0x103e45b6, 0x355ff2b5, 0x580e2ec9, 0xa263ecc9, 0xbc702f26, + 0x181e5e33, 0x2835b386, 0x6c122076, 0x025113ec, 0x7fbd856d, + 0xa5c26e3a, 0x9d6ebcb1, 0x8ef83fb3, 0xa44d2fa8, 0x7aaa53f2, + 0x53b1fa97, 0x7c14ef33, 0x17559a30, 0xff604a11, 0xb09377e0, + 0x2bcd96b0, 0xdb2f0273, 0xa5c14896, 0xeb53ef06, 0x1c0a84c9, + 0x30378e4b, 0x1236d017 }, + { 0xc084373b, 0xd7481c8f, 0x646097ae, 0x29ae4768, 0x613bc34b, + 0x1300dfa0, 0x934bc2b0, 0x3712714c, 0x0e2be7e2, 0x86524629, + 0xed010800, 0x554fbb9f, 0x42314576, 0xf0ec0b38, 0x330a3282, + 0x65baf594, 0x706ef817, 0x3bdde1a8, 0xba7530e9, 0x7d2c727d, + 0x74cc95cb, 0xbb0c5d66, 0x2438906d, 0xb3fcd365, 0xd14658f3, + 0x19881941, 0x6c97f0e9, 0xe616f555, 0x4b9ec7ea, 0x353c2d85, + 0x620cb56e, 0x02a48014 }, + { 0x506ccd38, 0x11d6d23d, 0x9059baa6, 0x229a1c54, 0x69d011c5, + 0x717c9c27, 0xd828937d, 0xe87e1b46, 0x83835083, 0xf5d63bbb, + 0xaadac258, 0xf0a7b427, 0x9f154d1f, 0x99ab26bd, 0x8ec955fd, + 0xdec0ffbf, 0x49fcb880, 0xee957c67, 0x1e0114de, 0x32395dee, + 0x369f46c7, 0x192a64b7, 0x91eb2599, 0x43044660, 0xa2e8c3da, + 0xbe2da887, 0xc3556d18, 0xa44e2c25, 0xb55f75f3, 0x31390414, + 0x8f217fe0, 0x1d8bde6f }, + { 0xa2028924, 0x03cd39f8, 0xb06ecb9f, 0x6e54f19c, 0xd6f05846, + 0x862bbcb7, 0x5a060776, 0xdbe06716, 0xb10fec10, 0x9397c97a, + 0x6f1bb65c, 0xf4213826, 0xa672ba38, 0x414deccb, 0xf88b05e6, + 0x594d4d43, 0xac94d4d1, 0x7993f57a, 0xbfb17638, 0x74fc2a6a, + 0xb6fc655a, 0xd8196b5b, 0xee8d2139, 0xdc375c84, 0x360d3a26, + 0xb9b00a02, 0xdeb93b87, 0xb36ed35c, 0xcc83209e, 0xf565b28b, + 0xc61013c1, 0x349c6943 }, + { 0x4de6c88a, 0xd1b39444, 0x4700207e, 0xd5c2c471, 0x21c2b780, + 0xb6f458a2, 0x0850993e, 0x749f7564, 0xbaef0c18, 0x400ba579, + 0x737c70f0, 0x2d742938, 0x21467ebf, 0xc5a8e2ec, 0x5337f453, + 0x243a666e, 0xed0bd50a, 0xc991f1c7, 0xf4bd1f91, 0x3a7f3e90, + 0x5f0e129b, 0x96089e8a, 0x07389635, 0xd0d3a177, 0x27182ac9, + 0x9cf842d5, 0x0817c5c2, 0x21195299, 0x87255769, 0xa32f327e, + 0x89c2d8fa, 0x056587ab }, + { 0x1ce4733d, 0x008562ed, 0x98e51444, 0x5faff7cb, 0xa9ab46b9, + 0x5f03021f, 0xb61a8c13, 0x89494c5e, 0x36b35976, 0x57c95036, + 0x2ac2d2f6, 0x6be84c8f, 0x9bd2703e, 0x0e5b34d8, 0x7e872abb, + 0xc4ad918f, 0xc4052ee1, 0xc2a89e9f, 0x3190b51e, 0xc2caee3f, + 0x6fff254f, 0x58fd1437, 0x883e0972, 0x6f3c0d68, 0x0fb15438, + 0x63d0a0e9, 0xf6caae00, 0xc438764b, 0x3f1d0f6c, 0x815f1565, + 0xb86cdbde, 0x1b87f2ed }, + { 0x2b0b15b1, 0x35792bbb, 0xce6ba779, 0xa3e4b5a7, 0xdd8f3779, + 0xfbacffd9, 0xc298d1ef, 0x005450bd, 0xc47031c6, 0x0e3f5556, + 0x95d68066, 0x0770f07a, 0x2d1052c2, 0xce3e84e0, 0x7aa8cc54, + 0xb050791e, 0xba3223a3, 0x4d621e73, 0x39632990, 0x87b9b94d, + 0x7eb8056d, 0x8df9cb47, 0xedfca0cc, 0xe2430de8, 0x9712a0ca, + 0x374bf416, 0x88848a99, 0xbe3f3c77, 0xc4a3e59e, 0xb22b87b1, + 0x3e95bc23, 0x8e0227c4 }, + { 0x3210964d, 0x000e22a8, 0xff056eeb, 0xdccd5df5, 0xdaf1ead7, + 0x02173a1f, 0x67cdcae3, 0xd02833e0, 0x8bdcc90c, 0x1cc574cb, + 0x3224b4f5, 0x86eca714, 0xbb3f8298, 0xd00e603a, 0x0c1a8deb, + 0xb98ece1b, 0x378c261d, 0x228a46e4, 0xa6165e5d, 0xc6f9dd0d, + 0x4b7ef0e2, 0xb3ae3899, 0xbda9f306, 0x3a3c16b3, 0x38a084db, + 0x5e9a26d3, 0x5394e950, 0x528e5993, 0x4ea206bc, 0x848ecb11, + 0x40545d6e, 0x14b15ab5 }, + { 0x664c59a2, 0x0f6d86c9, 0x60fd7aa5, 0x3dfe2be1, 0x9072cb8e, + 0x33f9b569, 0x8176a7e0, 0x5f2325d9, 0x4587080b, 0x79a0d4e7, + 0x0d5d4e05, 0xa4ee0def, 0xc87b28e1, 0xc0ad9ffa, 0x3f09b4ee, + 0xd6f18d2f, 0x292e9d87, 0xcc896ae7, 0x6094763c, 0xca88953d, + 0x18fbf9fa, 0xdbee97a8, 0x4b63d701, 0xdf20e0e9, 0x47ea722f, + 0xcbba6e30, 0x612b571f, 0xce57e1ca, 0x009a55f5, 0x1e16ac76, + 0xc4389e2e, 0x742bbed8 }, + { 0xc1dc2c73, 0x23ea86dc, 0xc1643abf, 0x4bbbfd5b, 0x24d8ca1f, + 0x07f8fa1f, 0x8cb5cac7, 0xde68a6e0, 0x54e66a7d, 0x7d54c64b, + 0xa9b7ad78, 0x789dba22, 0xe364ab94, 0x4d88d540, 0x1f72e011, + 0xc8c2e02d, 0x46e2a278, 0x4c826057, 0x4b187c7d, 0xe6c35bb3, + 0xeb8fe0c9, 0xed8b3dfe, 0x7d11e415, 0xb6bc34e8, 0xb865c7f9, + 0xb3908bbf, 0xe1ecc17c, 0x717d1ce6, 0xf7cdd69b, 0x151e3308, + 0xb5c94124, 0x97bd5a14 }, + { 0x81e82861, 0xe01c62fe, 0xdd42c40e, 0x703d4b6d, 0xe65e91e5, + 0x7e52e55b, 0x5abbbfdd, 0xb8b49374, 0xc72a45f4, 0xb4f15f52, + 0x550f29d8, 0xce8435a8, 0x582de75f, 0x9df76b9b, 0xa20c8b96, + 0x52e84c5f, 0x0a8a0af4, 0xaf77d2d1, 0xca6013c3, 0x0389bbd8, + 0x26f8305f, 0xb0d9b9ba, 0x0cec8b9a, 0xf053e848, 0xffabda18, + 0x4d63367a, 0xa6424c2a, 0x50f53be4, 0x864fba2e, 0xf892c58c, + 0x48cc5469, 0x317c6d31 }, + { 0x2cb7d42b, 0x0c3525b0, 0x310facae, 0x55240bc9, 0xff20408f, + 0x8d5d2022, 0xe0c10ea0, 0x6b01402f, 0x718eb23d, 0x7fbef68a, + 0x41252a19, 0xa0146b5a, 0x110e0d6e, 0x59afce48, 0x022de181, + 0xe9a1d27f, 0xdc3f49da, 0x6db96d16, 0xefbe4008, 0xfc1ae3f5, + 0xeccbc11c, 0xf9d70641, 0x525f8636, 0x49022279, 0xc2763c30, + 0x3769796a, 0x1d90630b, 0x9cc3483c, 0xee3d3f17, 0x451651f0, + 0x9da0b8fd, 0x6ae59739 }, + { 0xbff4d2ee, 0x57b13bc7, 0x30b173d8, 0x20754229, 0x0794936c, + 0xb6254bd5, 0x5efd55be, 0x1d5f232a, 0x4e0c3389, 0xc06f4a85, + 0x8e61f944, 0xcf2c5b59, 0xfd5f87b7, 0xc564861f, 0x5a2afa4c, + 0xee261fb1, 0x2d97a774, 0xb0ff7226, 0xd6cf007a, 0x1a89ae22, + 0xd346f214, 0x28880534, 0x97b6497e, 0x8fe73bff, 0xfa2afffc, + 0x8a8595b2, 0xf151a726, 0x9ef9cf3e, 0xe744b82b, 0xa84ee5f1, + 0xbc63fe72, 0x6649048d }, + { 0x1e8b760d, 0x91b7bb78, 0x25aadaa0, 0xd47b0bd8, 0xfab5226f, + 0x81493d9f, 0xbffc148e, 0x4a6dd226, 0xa29be3db, 0x5a032f8a, + 0x34b0ab0b, 0x318dbc70, 0x7d654868, 0xdcccbfb5, 0x9c581e46, + 0x8506ab37, 0x2830ece2, 0x09136a6e, 0xcf6c80c7, 0x48b79356, + 0xef6b1e86, 0xfa176377, 0x83f0f1c9, 0x2c9c1cc1, 0x16abeddd, + 0x96f0526d, 0xa93b0de4, 0x3e0e98e2, 0x0f13873a, 0x6f2d7ada, + 0xf3fa49ec, 0x4eb93b5c }, + { 0xe11fae32, 0xbd89f7e5, 0xc4023f51, 0xd13d74f5, 0x491c3f6f, + 0x1b0014df, 0x555279b7, 0x1d849a57, 0x05ba0068, 0xbb9e8897, + 0xc13ca2ca, 0x82222419, 0xfd33676f, 0xafbbb685, 0x75878a2a, + 0x931c3f52, 0xef3d5173, 0x12aeefef, 0xbd8a6878, 0x189a5cc8, + 0xd99f0c16, 0x82cffdb3, 0xa19d48b6, 0xbf565406, 0xe9c6c4e0, + 0x5605e223, 0x86804172, 0x53e781de, 0xc7001cc8, 0xcdf5c90b, + 0x7c043f68, 0x2b582d93 }, + { 0x81abc2ae, 0xa1165c82, 0xe2b69eca, 0xa73380f5, 0x07fff66f, + 0xc097b3d2, 0x54776506, 0x5d603826, 0xb57fa21c, 0xdcbac9f3, + 0xc98dbdd5, 0x78750db4, 0xd9eff32a, 0x85e21103, 0x2f11c41c, + 0xceed172c, 0x9e348c09, 0xa8e39264, 0x831eddfb, 0x71cb936b, + 0xf50864a3, 0x915c3d06, 0xe93acfcd, 0xfe8e33cd, 0xb3f2f7aa, + 0x4bee10d7, 0xeb7cee9a, 0xc1d8eb48, 0xfa574afd, 0x4fa49ce3, + 0x862db4c0, 0x78615109 }, + { 0x7ae72c21, 0x3fe3f480, 0xfd0f0da5, 0x631aa144, 0xf8c3a454, + 0xc76ee1e8, 0x51b4f1ab, 0x379ae094, 0xd7cdbb24, 0x2a3a4397, + 0x82bd5fcd, 0x7a14cffe, 0xf427ef5a, 0xbbe4ed12, 0x284d3ccf, + 0x9b0a43ee, 0x8eec6e1e, 0x57b78b93, 0x67b8e87b, 0x18d404e4, + 0x34374c20, 0x0c8adc05, 0x5428deb5, 0x64373605, 0xc3afa2cf, + 0xb4d80ec0, 0x3aa956f9, 0x6d51f93c, 0x84161c68, 0x9f9a28ab, + 0x6bc9c025, 0x540b6bb7 }, + { 0x321d315d, 0x04e1734c, 0xd86e05d0, 0x4ef56612, 0xbba8cd81, + 0xeafae145, 0xacdc789a, 0x1fb07a49, 0x5877570f, 0x6a21e9ad, + 0xb9bc53de, 0x2e4a837e, 0x1d6298eb, 0x436db293, 0xea362f45, + 0x43afbc78, 0xaabf6585, 0x2a973d97, 0x0c924d60, 0xdce7dabe, + 0x7cadf0e9, 0xf69d98f0, 0x75020538, 0xe0b505a1, 0x4461cd29, + 0x3db7d1a3, 0x5e20e818, 0xe1c28776, 0x52dd50f6, 0x2ca25867, + 0x92e0388c, 0x897cab14 }, + { 0x0d8bab8a, 0x59ed3813, 0xa438200a, 0xc11d364c, 0x40581415, + 0x0687bf2c, 0x7ac89674, 0x86ad0d3a, 0xb97411a0, 0x44928105, + 0xf383371c, 0x74984b11, 0x0d1a831e, 0x70d2ed84, 0x6c912fe0, + 0xd883628b, 0x14fa88d2, 0x44f8f7fb, 0xcf0ac93e, 0x564f2a4d, + 0xa6c24fa6, 0x82f629aa, 0xbf6cd949, 0xab906ba3, 0x20a5182d, + 0x2c822e67, 0x30eb93a5, 0x2ff47dac, 0xfff673aa, 0xdc62c4a4, + 0x476b0ec5, 0x64b00763 }, + { 0xb3c9a404, 0x1e3f533e, 0xb7ef9952, 0xb1db7f73, 0x6c253693, + 0xc7f13e29, 0x0738eed4, 0x7ce7f4c4, 0xce26cad0, 0xccfd3b33, + 0x01ec5cf1, 0xd8784935, 0xdc084e01, 0x3f8fc09d, 0xc39b5acf, + 0x217cab32, 0x9ef5551c, 0x42daf0bb, 0xe1217a95, 0xfbc76f56, + 0xc237002a, 0x80178b12, 0xb070a293, 0x0b52c39f, 0x576ca964, + 0xe3925153, 0x19d68e36, 0x25559424, 0x09e50e84, 0x291fb82c, + 0x6618ed8c, 0x7dd22ea6 }, + { 0x49cbb3bf, 0x7ffe844b, 0x5562fb25, 0xde0cc704, 0x9f5a845a, + 0x1e6ee537, 0xe51277fc, 0x956d7f26, 0x30635718, 0x2c75d4b9, + 0x96957f34, 0x39a14892, 0x82e5742b, 0x8cf4eb32, 0x83247b72, + 0x6b0d3ddd, 0x201a4237, 0x67a9f633, 0x1414a485, 0x416403c1, + 0xb6f6a916, 0x60afd447, 0xdac6f790, 0x95f94930, 0xbd3b9d82, + 0x685ff94b, 0x51cadf0f, 0x5c8f98fc, 0xb13b7489, 0x9559c88a, + 0x5f18fcc8, 0x31377c66 }, + { 0x7dcfb35f, 0x35c5de09, 0x01cc36f8, 0x2dccca9f, 0x7576cb63, + 0x7e93e85d, 0xf7b4b375, 0x0c2dd48a, 0xb09a19b5, 0x9d95cd4f, + 0x71bfe607, 0x752ed159, 0x2596dad2, 0x439880cf, 0x69e90a6f, + 0xe52efb53, 0x03d3e60a, 0x44097663, 0xa95070e0, 0xfcf364fa, + 0x05624dd2, 0xd8f993b6, 0x00d5e467, 0xb35a9824, 0x0c8f4524, + 0xe289d024, 0x648a0179, 0xef45423c, 0x587edabd, 0x3a5fd695, + 0xa11e5271, 0x3dacc50c }, + { 0x6499ae4c, 0xcb3e4f94, 0x7053c527, 0xa46dcbe1, 0xbe782e8a, + 0x807f5ce9, 0xd8481e45, 0xb6c64d28, 0xaa286fd0, 0xf35e4518, + 0xdf1cdb49, 0xf7b7b9ba, 0xaec23eaf, 0xf3fb6210, 0xb9bfd2fb, + 0x0a9ba385, 0x8807f3a0, 0xe51a0d53, 0xb17b2842, 0x7ab24404, + 0xf9dd9f0a, 0x6fd57687, 0xf3e9df64, 0xcd1efdb4, 0x60df194d, + 0x5dd2df7a, 0xe069df05, 0xbed3f2c3, 0x23248a31, 0x469b7561, + 0x694744f7, 0x866949e1 }, + { 0x3f4ab07a, 0x3a9a0da5, 0xf54a6fbf, 0x2cd6f333, 0xb23cf290, + 0x0c92e921, 0x848e3d58, 0xc9581c3e, 0xd3b218ab, 0x93af1fbd, + 0x066cb4d7, 0x38598ea1, 0x990c03a0, 0x5001394e, 0x7d0877b5, + 0x3b664b1e, 0xd74c7091, 0xd79db1bb, 0x4e2d5dd0, 0x852d4435, + 0x3329db82, 0x0d2b841b, 0x7b96d480, 0xfa844eb0, 0xc295dc46, + 0x37a50569, 0x94f7ec4e, 0xc2d38373, 0x5b083177, 0xdc3884ff, + 0x8b1fa598, 0x574352b8 }, + { 0x0d5d7ce9, 0xed2193f7, 0x0b487eaf, 0x3c19fd26, 0x7be65fd0, + 0x7c44ab59, 0x78270d56, 0xdd9da860, 0xbaa70198, 0x8a84ec00, + 0x285985df, 0x2ec27e49, 0xde2028d8, 0x996ccaf0, 0x61c2201d, + 0x4e7648c7, 0x091c19eb, 0xa96335bc, 0xf0d6782b, 0x253a3a69, + 0xd2946493, 0x3f204340, 0x099f6873, 0x444521a1, 0x6996011a, + 0x5fcbcc09, 0xf853a94e, 0x3884d5d8, 0xd3b6a3a1, 0x2418c624, + 0x06ae3c4f, 0x3e431af2 }, + { 0x83d381f1, 0xf967d939, 0xd0c033c3, 0x36501aae, 0x54410768, + 0xbf3af4d0, 0x5093a6d3, 0xa86d1598, 0xd92f2900, 0x43ae0741, + 0x36f0b755, 0xfeb2afa6, 0xaa456d6f, 0xd090a6a3, 0xaefdb646, + 0x336a4fda, 0x1a942f7d, 0xfd1bfe44, 0x851ee41e, 0x7fc2a3ed, + 0x11e935c5, 0x4f1c9686, 0x53bbb343, 0xcd577666, 0xad896c2a, + 0xf26931ba, 0x86bbfa41, 0x8a0fbbd1, 0xa203cef1, 0x1c3d7d82, + 0xe2664d35, 0x6dad3f15 }, + { 0x12ec35a1, 0xd1940b7d, 0xe7dfb128, 0x6219c5b6, 0xf13321d5, + 0x2cc278c6, 0x33c58eb6, 0x5e76904a, 0xd9903c43, 0x15090f55, + 0xc3d96a19, 0x061bc926, 0x8c0acba7, 0x974a9f03, 0x7198b21b, + 0x7a414021, 0xf8958c6f, 0xb069599d, 0xbebd0129, 0x517f2f1d, + 0xdf3a8dc3, 0x1109a613, 0x672375c5, 0x08e58448, 0x9383d2d3, + 0x56590ba4, 0x0bff837c, 0xfc3ee7c6, 0x27d2d55f, 0xc87a5390, + 0x5f517a3f, 0x2438e9d4 }, + { 0x8815af3c, 0xc4a45308, 0xf3c9bed5, 0xe55f1a32, 0x97b65ddf, + 0xaef1cdc9, 0x12e51eb5, 0x61c61d94, 0xe63f2490, 0xbd0dac54, + 0xd0b3e231, 0x6f14429c, 0xf1da6010, 0xf737c3c2, 0x6bbc4fb1, + 0x7150e04b, 0x1be281cb, 0x205b4c89, 0xd7701f5b, 0xf1b4633c, + 0x2a513490, 0x8b33ef46, 0x68f1f7f2, 0xddb47c73, 0xbd416b67, + 0xf4ada511, 0xff795bb3, 0x9d2a97cd, 0x96200e67, 0x00a8b7b2, + 0xafe30e01, 0x13f39011 }, + { 0x7bd0c827, 0x3dd296ef, 0x4a29ff46, 0x506110f3, 0x1c9a515a, + 0xf8793068, 0x268bca77, 0xde8d8045, 0x998045df, 0xcbb83024, + 0x68c0e584, 0x3f90d710, 0x263b6062, 0x2a838ca8, 0x535c5d0b, + 0x293bb5e7, 0x56415110, 0xceea99d5, 0x1bbda005, 0xfe311ad0, + 0xa4d8d018, 0x2497e0bf, 0x1cf2b866, 0x33dd77a0, 0xd8c4ba8b, + 0xbc075b73, 0x722b7bc9, 0x298466d4, 0xcbda1b0b, 0x17a7ce24, + 0x680703b6, 0x458d4b6b }, + { 0x4d54d8b2, 0x8a26a20e, 0x4d320a0d, 0x05a5696e, 0xf994f700, + 0x698b5858, 0x2f6549a8, 0x7a4adc3c, 0x3694d00d, 0x1812e819, + 0x730402bd, 0x46b9b000, 0xa1b36410, 0xe10a1449, 0x99230220, + 0xeae95ea5, 0x1b4820c3, 0x3efc2e9b, 0x85c9eb8a, 0xfe5b5cb5, + 0x97847064, 0x21ae0319, 0x8f27d49f, 0x68ef0b70, 0x2f72556b, + 0x3259ef18, 0x624db01a, 0x00ae0457, 0x5668f95c, 0x628e3b06, + 0xb6fbbf91, 0x5f13f5fa }, + { 0x3a9b0dc6, 0x7c6ed9ae, 0x6f883ec8, 0xaea1bde9, 0xea8b3677, + 0xea66bf88, 0x9a66e3ab, 0xdefa6abc, 0x68217ffd, 0xc4d3317b, + 0x290df05c, 0xf741c8f2, 0x7d11674e, 0x1f0fdf17, 0xc35989ca, + 0xfdf0ece7, 0x6b9c482d, 0x0eed92df, 0x55bf1ca7, 0x73713e66, + 0x25cec99c, 0x90acb290, 0xe803e69c, 0x37c9e3a2, 0x17713a1a, + 0x7c0a3c53, 0x6f5a174d, 0x350dc565, 0x05f802f6, 0x11625a44, + 0xa37ba4a2, 0x2196495d }, + { 0x13142680, 0x00cb2fd3, 0x65d14cf4, 0xab9e91d7, 0xdfe2669e, + 0xc6a0ceab, 0x0ae22bc5, 0xbeefce58, 0xcb6ec250, 0x3c2b7986, + 0xd738f1ff, 0x84adb1a2, 0x516ec8ec, 0x9709bc28, 0x8e8f7db5, + 0xf3693129, 0x95b197f9, 0xc48efc6b, 0x9aaaa404, 0x9ff10952, + 0x144154b0, 0x2c3c8cbd, 0x427f3435, 0x33ef7bc3, 0xd21897c1, + 0x04a17940, 0x6ce548a0, 0x5aa0c47d, 0x3d56fa62, 0x2971cea7, + 0x04475f08, 0x93ad0eb0 }, + { 0x988a9963, 0x7a0b6967, 0x6515e8dd, 0x61e477f7, 0x3b6b50f2, + 0x6274e386, 0xd33922de, 0x63a9b8d5, 0x687a5b3d, 0x3c38d3fb, + 0x1302e323, 0x18f6f09c, 0xe02fcccf, 0x254c05c3, 0x26e662f7, + 0xc04ed0b7, 0x143fe079, 0x1d5646b8, 0xc9016c8c, 0xef8a9448, + 0xf823d797, 0xe5674c4b, 0xbccde451, 0x0586f72f, 0x4417eade, + 0xc5fc88d5, 0x576e588d, 0x2b952209, 0x5844d1f9, 0x4408dd42, + 0xea41c034, 0x73f8c3f0 }, + { 0x5df763dd, 0x89534fc8, 0x3ac71836, 0x3b1427f3, 0x6e8f15a0, + 0x0db5be17, 0xcb20888e, 0x1d390944, 0x857caea6, 0x7804c9ad, + 0x519f7bf3, 0xaa584428, 0x293aa8cf, 0x626eecf1, 0xea36a015, + 0x749e0d98, 0x3321edcd, 0xefff6dae, 0x28b791cc, 0x963deea6, + 0x2d16e361, 0xa14e0552, 0xb15ae206, 0xa2e058fc, 0xfca325e4, + 0x0f268745, 0x21341a8a, 0x7cf9d407, 0x7caa51b8, 0xdfed25d9, + 0xadbedd75, 0x0108ae39 }, + { 0xa9e88f63, 0x54d178f3, 0xab0c7325, 0xaa05b11e, 0xe261d8a6, + 0x773a53e6, 0x8d0b91c8, 0x24db7dae, 0xe9bb004d, 0xde10b073, + 0x54e3090b, 0xfc8befe7, 0x0cc69c89, 0x16af0599, 0x9d59511a, + 0xddc83803, 0x46c5dafc, 0xc3f65b99, 0x1ee0a599, 0xfbbe4be8, + 0xfb3a9b17, 0x88891e36, 0x445dad00, 0x0c9aad75, 0xd5097e1f, + 0xdffc46ab, 0xac85a4e1, 0x8848089b, 0xa0c45233, 0x348bb42f, + 0xeb13c1df, 0x807c06d8 }, + { 0x98ee0ef6, 0x00a969ec, 0x8bb7b7af, 0xba9d5483, 0xa02f8fdb, + 0x24484c92, 0x8b70557c, 0x7bdb201a, 0x60ad1af2, 0xe59343e4, + 0x998c95fb, 0x53a9a942, 0xda861d3b, 0x974db3de, 0xed399c0e, + 0xce1525c9, 0xf72109bd, 0x89b56881, 0x998211a4, 0x08ff7d15, + 0xef0f275a, 0x5df76b3a, 0xfa2f358b, 0x93f180f7, 0xc39b0634, + 0xaac4ffcf, 0x17583b53, 0x2692c626, 0xb55399fc, 0xb2fdfa36, + 0x99607a61, 0x16424c6c }, + { 0xdd2744a9, 0x5dd65c55, 0xfe3af418, 0x2544c1c2, 0xefe8b089, + 0x32c82e99, 0xa9df691a, 0x30b7ab25, 0x9be99674, 0x98384550, + 0xcaf2d122, 0xbcecd258, 0xbcc77272, 0x88ae4098, 0x4b8efa0c, + 0xd4396141, 0xed64d12c, 0x44ff67b9, 0x2e7f3404, 0xa9e655e4, + 0x45b0e9eb, 0x3d16fc45, 0xf03ded28, 0x474a3e14, 0xacccb85c, + 0xa3c9adff, 0x7253a51b, 0x3dfe6bc1, 0xfb5831b1, 0xdddaf4b9, + 0xa4f4478a, 0x5544e602 }, + { 0xbaa80b4f, 0x897c5313, 0x63bdc8ef, 0x0122716f, 0x7b42c5a8, + 0xae2742db, 0x0883308c, 0xe9d9e1e9, 0x2d341ab1, 0x352c8c3f, + 0xed945870, 0x163d0500, 0xc290d9d8, 0x8349dd73, 0x1f6c7d29, + 0x2053c5e0, 0xcb42033c, 0x83107446, 0x09d09af1, 0x76c88bd2, + 0xb2794681, 0xd0f70e6e, 0x19b1b540, 0x720b59de, 0x22994b43, + 0x80b7ecdc, 0x2dec53cf, 0xc1a4cdce, 0x1ed60f42, 0xdd7d3edd, + 0xe241d261, 0x5735995c }, + { 0xa0237056, 0xdc4ba3fb, 0x33ab3388, 0x6856c164, 0x271ec612, + 0xc01eebbd, 0xe3031bec, 0xabdeb033, 0x6118a1f5, 0x4eee4419, + 0x5b600f33, 0xec497421, 0x08868773, 0x1b7185cf, 0x7c1b7dfd, + 0x7b0c46cd, 0x4a4c5e89, 0xd143b2da, 0xbb1ff94d, 0xdb9a5984, + 0xc9cf3465, 0xac3904e4, 0xeace64c9, 0xf8729bc0, 0x768ad99a, + 0x5cc22821, 0x8a9540c2, 0xbbd3b081, 0x049a6917, 0xe468ed5f, + 0x3ec45ef0, 0x885486df }, + { 0x4bdff464, 0x6a942c93, 0x25a7b451, 0x3db2719f, 0x325be324, + 0xccb0070b, 0x19fe3339, 0x2055a31b, 0x241ee8ff, 0xaca69ae8, + 0x55ef8def, 0x7607dd08, 0x1a1b73c6, 0x9e24960f, 0x71d36810, + 0xbcb0e8a2, 0x6885e6b9, 0x29e11aa2, 0x185eae19, 0x98b5d0ab, + 0x0f81f91c, 0x1a0b96e4, 0x994fc503, 0x4d0e8bcf, 0xf119d6e0, + 0x33d81697, 0xaaa4ce0c, 0x29083287, 0xc91ff9d7, 0xc5dd4d3e, + 0xd4ab962d, 0x31cecfe8 }, + { 0xfc8b21e8, 0x437bfd9a, 0xb19436df, 0xe5dd32b3, 0x921c36a0, + 0xfe5902d4, 0xa3d0fa90, 0x8e9de84d, 0x5bb523bd, 0x9663e6ad, + 0xaecd6975, 0x9800a23f, 0xb4fbb59c, 0x1009c0d9, 0xc9d20ff1, + 0x839aa7bd, 0xecd6fa3d, 0xf502f66d, 0xc5516ca9, 0x480ed4fb, + 0x6c742ac4, 0x65ffa5f6, 0xff3252f8, 0x2b7c7945, 0x75d9cb3d, + 0x72fefc05, 0xd6d6f1d2, 0x11b0863b, 0x9a6a4ec3, 0x5d8f3cf0, + 0xda2547b3, 0x6961b46a }, + { 0xcb35e2ac, 0xd07b587e, 0x57af14d9, 0x1ed5546b, 0xdb28a04c, + 0xeca17a5b, 0x709d54f0, 0xa1f91d44, 0x9c6f400e, 0xa6e719fd, + 0xfb8ce190, 0x4e4b88ed, 0x246e3fd2, 0xf9781edd, 0xb655af5d, + 0xd67120e6, 0x93413ca7, 0xda782d1d, 0x9707fa21, 0x697e20a2, + 0x54e84123, 0x1eb51f32, 0x36051f9f, 0x2e254d9e, 0x73ce5be9, + 0xddaec42b, 0xcd3f794f, 0x89a9a32e, 0x0781aad9, 0x1964e22f, + 0x53755212, 0x6a63a90c }, + { 0x3d7acbbb, 0x76554e00, 0xb74f6108, 0x2c01668a, 0x388c519b, + 0xe4a29672, 0x3eb94d4f, 0x01667714, 0x0cd6d2f6, 0x086a3cdf, + 0x7b370f7f, 0xf8658021, 0x5a4d3e7c, 0x658880c1, 0x5ba3f4a1, + 0xd6ed5816, 0x5ca471dd, 0xabcc7813, 0xe844a576, 0x809bf074, + 0x6ea502ea, 0xa53a81b3, 0x0e021ed3, 0xc20b9307, 0x8617f165, + 0x8c27f892, 0x8235cd0b, 0xa5476446, 0x82552961, 0xffc89ffd, + 0xd151d90e, 0x51ed4a22 }, + { 0x449701b4, 0x37d6963a, 0xbb27caf2, 0xea8d91a3, 0xb572965f, + 0x3ef9be15, 0xdb50bf7d, 0x75a7a055, 0xce643b9b, 0xfd67480e, + 0x6ceb5d5e, 0xf2a60d2d, 0x5ed7c897, 0x68fc320c, 0x28ce685f, + 0x41c53cf6, 0x7106615e, 0x0e29711f, 0x23500ecc, 0x7a872138, + 0x6c29fe48, 0xaf0a9260, 0xe1ef9712, 0x93df3f2a, 0xd2d169bf, + 0x0d5f6fb1, 0x74a9793c, 0xeb7afe26, 0xe9f49256, 0x4173d94a, + 0x2b8b5ce5, 0x2d6951bc }, + { 0x904e222e, 0xdd007d9f, 0x86f4e109, 0x333f248f, 0x8f429eee, + 0xd4994e8b, 0xcfc77518, 0x29573415, 0x0b0f42f1, 0x6e7fea3a, + 0xc2743519, 0xc795cb7d, 0x711e71a0, 0x820a8f66, 0x2b874f55, + 0x83d95d9c, 0xe70e1627, 0xd4b64d78, 0x8b92a742, 0x924353f5, + 0x447b5e6d, 0x322048b1, 0xbcf931a0, 0x0bad730c, 0xa7af2268, + 0x75c4d089, 0xb83b93f9, 0x464904c1, 0x165b3aee, 0xa24eba02, + 0xe08cc5f0, 0x65c48e78 }, + { 0xde222c22, 0x1a1c73ce, 0xfcea23b4, 0x5683d8cd, 0xb2143b06, + 0x0301cb14, 0x59fcec77, 0x284adf8f, 0x31204cef, 0xfb1c581c, + 0x94735107, 0xf54d3eee, 0x4d3188c0, 0xdbf67f0b, 0x10f18d12, + 0x76a3f2d1, 0x07d3e013, 0x3809fa28, 0x25e7ece0, 0xf06f0a46, + 0xb2895d2e, 0xd82867ed, 0x08b0553a, 0xe106f489, 0xef245445, + 0xe2280fa6, 0xa8d9a3cb, 0x402d5785, 0xd438ba2d, 0xf63dd9ff, + 0x7a6b226f, 0x36b5cd2c }, + { 0x545679a7, 0x87ff4e20, 0x4520c750, 0x64d80b41, 0x9b459cd8, + 0x90a357fa, 0xc85af1a3, 0xa19eaf39, 0x8d935a5e, 0x0d475d79, + 0x781a678a, 0x74501983, 0x0cc2e810, 0x74839779, 0x2f412244, + 0xc6a21d11, 0x36a51a37, 0x8d0e85f9, 0xeaa74df8, 0xff50151e, + 0x93cf99c4, 0x14e182a7, 0x376a9ab6, 0x45593df1, 0x522389ff, + 0x18f73caf, 0xf7445e8a, 0xd27cc960, 0x39a51dc8, 0x0692f4c5, + 0xdb39bfd8, 0x08d7c144 }, + { 0x3ecca773, 0x809c0d96, 0xd48c2156, 0x87ea9192, 0xdb6bd641, + 0xf0eccd74, 0x2a678cdf, 0x77312374, 0xd1587b7e, 0x7a966d8b, + 0x6130a4c6, 0xf3c1a101, 0x5fce17bd, 0x7cc6e838, 0xa8de7aa4, + 0x95e95bb8, 0x898308e3, 0x3fe1e8b5, 0xe347694a, 0x0197243e, + 0xbb0cd2bf, 0xf3fe9c42, 0x0f9b2b49, 0xb5905264, 0xc7367d1f, + 0x4c385e8b, 0xb5ee147b, 0x1d3050ae, 0x04004ad9, 0x8e2c3879, + 0xbab70202, 0x5f2aa8ee }, + { 0x1266524b, 0xe208d464, 0xd0a19f66, 0xb7bf3880, 0xda106ebf, + 0xa5aa685e, 0xe642dd46, 0x0a69e8d3, 0xc682e4d6, 0xef349c61, + 0x0fcb534c, 0x26f6ee3b, 0x05eb67b8, 0x7daba127, 0x18be05f6, + 0x2babb27e, 0x8e2d85d1, 0x959afcba, 0xe2d9d386, 0xedcf2d1a, + 0x1ea6f06e, 0x59dc52e6, 0x866e5ae8, 0xc28278b4, 0x02bcd3c7, + 0xd9ff0340, 0x784be82f, 0xe884ac76, 0x83c9f224, 0xa3164980, + 0xb46ff949, 0x62501a98 }, + { 0xad264086, 0x563f7d9a, 0xa5e0e4bd, 0xca6a33db, 0x8c8d3d67, + 0xe8253002, 0x46e64b19, 0xa288dac8, 0x20aa4536, 0xfa3c9197, + 0xed553eac, 0x8130c9b0, 0x2ea8abd3, 0x622806e0, 0xceccfe77, + 0x52fbf54d, 0x4f0d1b70, 0xbd9a8e31, 0xd59b1741, 0x519d2133, + 0x9a6fea8a, 0xfd74101c, 0xb5c4eb10, 0xd1acf7a0, 0x91f9da5e, + 0x78499b73, 0xc0dea586, 0xabaa4c49, 0xa1f3531a, 0xcc9c5f73, + 0xfd3fc665, 0x497b15fe }, + { 0xf45568e9, 0x8a56cbaa, 0xc7192a6f, 0xf491a0fe, 0x9ab2539a, + 0xdbb03dd3, 0x4ac37da9, 0xc86522f8, 0x02a0f5b4, 0x8c8cdba2, + 0xa29c539f, 0x8109fc75, 0xca90f02e, 0x9cd06d31, 0x3e216dbf, + 0x8f31f044, 0xba3ebd91, 0x99aa68ac, 0x42c007f4, 0x2a80d0d2, + 0x86a9b7ce, 0xdd8dffbf, 0xd6308edc, 0x405d3e84, 0x068012ca, + 0xdafa33fe, 0xedea1071, 0xc2eebd13, 0x2ff637e6, 0xb7ae7e5c, + 0x9e514cb7, 0x18d46a6c }, + { 0xa78b7802, 0x868cbb22, 0x497cbaf4, 0x0745ddb2, 0x42ae8add, + 0xc4eb2f3e, 0xb4ceb4e4, 0xac0abcda, 0xa325fd40, 0x2e0d8325, + 0x13ac7345, 0x6cfe0571, 0xb14171b9, 0x7407a788, 0x6da7a52b, + 0x70eb0603, 0xd85176ac, 0xab0b36f9, 0x7c2954f3, 0x14109d29, + 0xdcd705ad, 0x370de9c8, 0x7bb5e751, 0x3f0db5cd, 0xa06e708c, + 0x45f93d41, 0x7e93050d, 0x10d54f8a, 0x5a38fef9, 0x69e6f8e4, + 0xd3f62e40, 0x55044601 }, + { 0x06cb9cc9, 0xd1c5c910, 0x41d00014, 0x542074d7, 0x11236fb8, + 0x7cd8663e, 0x29ad5f82, 0x39721ffe, 0x2951fc83, 0x1d21fbfa, + 0x400d144f, 0x1cde06e7, 0x91792e6b, 0x9042596b, 0x29ad5166, + 0x3365c8e5, 0x9aeefe98, 0xe2220e85, 0x70c2aee3, 0xbcb53189, + 0x9ff100bc, 0x477ca3db, 0xf532973f, 0x27074176, 0x9a2bd01b, + 0xa12118ac, 0x3dd79f93, 0xf3425209, 0xc6f5d7db, 0x563a8ff7, + 0xd7b0ec4f, 0x0da313fc }, + { 0x15aa2557, 0x37125a8c, 0x00893e9c, 0xca21d70c, 0x67b8a823, + 0x48713994, 0x7cb0042a, 0x0d3e9a74, 0xc9e2ce18, 0x2d2bf4ff, + 0x049aeac2, 0xd5531a0d, 0xf03d0660, 0x4d29a616, 0x1f1b7f00, + 0x473d50d6, 0xca3de50c, 0x3af0ecbb, 0x09c28f27, 0xe2959bea, + 0xf8704664, 0x6d7c2ea0, 0x731083ef, 0xadfae4e1, 0x941c2554, + 0x50940c26, 0xa1162d03, 0x44167410, 0x1e82290e, 0x620230d8, + 0xdb414acc, 0x63630be8 }, + { 0x8a7d2e41, 0xbf8d5222, 0xeb62f879, 0x49e75823, 0x6c402d89, + 0x1b4d33dd, 0xde2c59ad, 0x883e04d6, 0x49b9dc38, 0xbf3f38f4, + 0xb4b70c4c, 0x9d997d18, 0x13cea045, 0x1f69b20c, 0x58e2606d, + 0xca3d7025, 0x261d1b79, 0x3d4fd977, 0x5a1436fa, 0x56aeafa8, + 0xbb443c07, 0x369b3e98, 0xe558f6be, 0xfce5186c, 0xf8ac8f89, + 0xeb0cd478, 0xd5e5aa72, 0x68074f37, 0x68544eb0, 0x295845c0, + 0xf16688ed, 0x306a9871 }, + { 0x634ec136, 0xbc451e9d, 0x0e6f658f, 0x1edf27ca, 0xc0db4120, + 0xa9be0152, 0xc5bfee67, 0x87b6ef20, 0x9a2d6023, 0x35283238, + 0xc7afb899, 0x60e564d8, 0x0ac9c2de, 0x4af22bc0, 0x82a9d22b, + 0x28e6f631, 0xf532701b, 0xc075c701, 0x82075f91, 0xf6d418f8, + 0x1beaa511, 0xf9fa628d, 0x6e72a13d, 0x551e7a17, 0x77f4c01c, + 0x9306215b, 0x93c9d588, 0x71aba731, 0x58e57cd4, 0x6443ebe0, + 0xe8103e37, 0x2833ac41 }, + { 0x8da5ec5c, 0x7e564b86, 0x1c08db24, 0xac3d9da8, 0x8c57a728, + 0x9d7c1f0b, 0x9d343dc2, 0x3512afe7, 0xfdc60339, 0xb438e4cf, + 0xdcfa1941, 0x7d5a2700, 0x27320449, 0xd5f323f8, 0x1393c6e6, + 0x1b87a58e, 0x04baa431, 0xecb68bd1, 0x4722b4d7, 0xc09c1c5a, + 0x206b5faa, 0xf42faa97, 0x9976327e, 0xe1dcbcd6, 0x087787d9, + 0x655ba9e4, 0xde5c0191, 0xbd59c757, 0x0bcf3538, 0x673020ed, + 0xa49d6303, 0x120cd454 }, + { 0xcab0f9ee, 0xebfdb8f4, 0x2cce58ee, 0xbc003ef0, 0x5a8d0665, + 0x9b6a6841, 0x9b957774, 0x642ed3a6, 0x4721ab5c, 0x3de487f0, + 0x21a4f0d3, 0xef2ff380, 0x29dbddcd, 0xbd16f558, 0x0e93dff2, + 0x2ef05b4b, 0x0bc9aec1, 0xde1faa12, 0xd467fa92, 0x66dae2c2, + 0x5eb33e34, 0x758daf64, 0x8f0103cb, 0xa67ad9f6, 0x9be02430, + 0x151f693a, 0xeb4054bc, 0xd5698496, 0x7019336e, 0x8ef1677e, + 0x7fdeea3e, 0x021cfd16 }, + { 0xdf5c36f3, 0x5c73715f, 0xd64ad254, 0x703bde37, 0xf2cf7713, + 0x55368d10, 0x0f3993c8, 0x1e5ec7b7, 0x304ae4ca, 0xfdb16776, + 0x3d3bb18b, 0x0d8f717e, 0x66343d5a, 0x5267073f, 0x156008b5, + 0xfaeb52ef, 0x224a470f, 0xb97ad5f9, 0xed2ab51a, 0xaf86e391, + 0x9974302c, 0xdc0c7e57, 0xfd0ae28a, 0xc88fa817, 0xbf8ed59c, + 0x807c22df, 0xeb128bb6, 0x5dedc231, 0xa20595a3, 0x71edcd9c, + 0xc73cf78e, 0x07265b46 }, + { 0xbd66232f, 0x73dd99f0, 0xc4027716, 0xc59aaf89, 0x5b860fc4, + 0xaf826dfa, 0x7a943f3b, 0x239ea8aa, 0x523c428d, 0x0e0e1b1a, + 0x6973b95a, 0x55ea0e3a, 0x2557753b, 0xea399caa, 0x06957b1f, + 0xf8adf72f, 0x3bd34302, 0x0389f341, 0xf8a43a97, 0x333f27d0, + 0xadaf796f, 0xcd9c0c08, 0x49c12aa2, 0x6dcca49b, 0x7a0ac6e9, + 0xdd88deee, 0x0644080e, 0x8f47575d, 0x0cc2f4bd, 0x6e9d667d, + 0x31d1496c, 0x36c5754b }, + { 0xf323d84b, 0x9120046e, 0x7e789c4f, 0xa6991122, 0x921b8055, + 0x4b0eaf4e, 0x8079974e, 0x6339844a, 0x740f8c79, 0xc905466a, + 0xcd6def49, 0x1c18d0f7, 0x4b23e4ba, 0x5297da6b, 0xc41800c5, + 0x1c09dff3, 0x37ef6777, 0x6c49075b, 0x50513ded, 0xa94c3a40, + 0x6b0b1705, 0x3d6742e9, 0xc48af5ae, 0xc0784494, 0xc95822de, + 0x40c01532, 0xc164d94f, 0xa2ddade5, 0xa2975eb5, 0xfc8a8ac9, + 0x1946944e, 0x06fbf861 }, + { 0x3f45aa97, 0x2d65338e, 0x1d040feb, 0xd83b58c8, 0x0fdef8b9, + 0x05fef59b, 0xe4d7417c, 0x7beb071a, 0xb30a1a23, 0x982b61f5, + 0xfb65bd03, 0x4c5f2a2a, 0x5cbf6bf3, 0xe40abc9d, 0xf06612a5, + 0x422c326d, 0x9571ae28, 0xc921e69d, 0x23d3434e, 0x7c88b10b, + 0x9da07933, 0x96d2e957, 0x3619cf4d, 0x833d46a1, 0xd95eefa1, + 0xd9d19653, 0xa03e8f0e, 0x2a7d8411, 0x04bb5ab1, 0x5e642953, + 0x1f0fa9ea, 0x5e9ca0fd }, + { 0x197c5dc4, 0x5bd54571, 0xe78a95a2, 0xe2da40bf, 0xffdb0eb2, + 0x65fb9efc, 0x0d17467c, 0xe952dc2c, 0xc758c6a3, 0xc1fc9c7b, + 0xd4034a9a, 0xfc79562c, 0x61f64b56, 0x26e36fbe, 0x1e84728b, + 0x6adc4b9e, 0xa8f9ac8a, 0x7f165fd3, 0x03e3e013, 0x7bc93a45, + 0x656478e3, 0xeacc5513, 0x064ddc77, 0xd3391717, 0x76936914, + 0x75b318dc, 0x362424a6, 0x69b1f1c7, 0x49955f34, 0x8cc2045b, + 0xc6836af8, 0x940622b3 }, + { 0x0d997973, 0x4710ccb7, 0xd3f8f115, 0x3b29625d, 0x5b97abd5, + 0x8cf0c4d5, 0x673e14a5, 0xc6321e0a, 0x3d262246, 0x0541af9d, + 0x6fc83b11, 0xde6d8754, 0xf01652a4, 0x47e97da8, 0xad9802b6, + 0x0f82b3a6, 0xae9c44b2, 0x69aa4075, 0xced2bf77, 0xaf3f5de2, + 0x497a40da, 0x1ef1ea8a, 0x3c23ba9c, 0x2e0f8608, 0xf190a2c8, + 0xd8a998a4, 0xcfde3368, 0xe2b49c8c, 0xbde6bd71, 0xb9f49824, + 0x785bedb6, 0x80bb1664 }, + { 0xfd145cb5, 0x05e575fe, 0xac5e6883, 0x155ee561, 0x8793b273, + 0x461e70cf, 0x133b2338, 0x9f1553de, 0xa2a7ba07, 0x2fb9e0c3, + 0x3e7086fa, 0xc3bfd6a8, 0x8bb4cb93, 0xb6ba8500, 0x76f82dbd, + 0x0b66d789, 0x54eb49ff, 0x7d5a6ff6, 0x1f20b322, 0xcd65d237, + 0x54e29cdc, 0x79ea49c2, 0xcb118ff9, 0x64975963, 0xcc58000b, + 0x969598dd, 0x110c779c, 0x95107918, 0x63b85a35, 0xedfc1548, + 0x41212350, 0x077ba5ea }, + { 0xcdd86f61, 0x0b3a38d3, 0x0502a0ab, 0x43121445, 0x806d0272, + 0x1912edc5, 0x8a32f10f, 0x01dc1f98, 0x0e80c760, 0xbb1d31d1, + 0xf464e8b3, 0xd46ec7e5, 0x9abf49ee, 0xd569af36, 0x2cdade77, + 0x9d286ea7, 0x45ad5920, 0x2be7020d, 0x6299ae7f, 0xabe5236e, + 0xd3f55c07, 0xc93179bd, 0x52350e80, 0x8138995a, 0xaff07586, + 0x0901265c, 0xf4739653, 0x5b3c81b2, 0x9bc77d21, 0xbaf7581d, + 0x4591a2e2, 0x6b2006df }, + { 0x965b1bc1, 0xb2fe50a8, 0x962bb4fd, 0x931f536a, 0x000e7f99, + 0xd5718d33, 0x53d5125e, 0x84728f25, 0xd2125caf, 0x4f8a6184, + 0x357f679e, 0x54f1a701, 0x1531c05a, 0x70a9f40c, 0x6fa8b775, + 0x10d0cb97, 0x9dc12ce9, 0xb476f41e, 0x2755f894, 0x5c8d7a75, + 0x625741a4, 0xd6c12e10, 0xc917b16c, 0x262a6fb8, 0x38d6b0a0, + 0x24d116e6, 0x32c38e83, 0x849540c0, 0x66868afc, 0x855b911c, + 0xbd26b550, 0x53217ea6 }, + { 0x259f52b4, 0xfc840473, 0xe621146c, 0x968da9cb, 0xcacbd26e, + 0x964eb85e, 0xe4a54344, 0xab7daa2d, 0x381a4ff7, 0x6dc3b848, + 0x41c815ef, 0xa07a96b3, 0xc3d4b1e1, 0xc4fae9e8, 0x42ce9ea8, + 0x0f938d1e, 0x35cc052f, 0xa727dacc, 0xe9a06f07, 0xc81e01c9, + 0x4a6d65a1, 0xa9e08dcb, 0x6044a9a6, 0xf8e2d173, 0xf2bd295b, + 0x99893dd0, 0xf9781b12, 0xa08d3379, 0x61830ac2, 0x64bd6001, + 0xd9adbeef, 0x0386931e }, + { 0xd09885a5, 0xd0d7abb3, 0xe355bb07, 0xed9d2b67, 0x536ebaed, + 0x3bc238cf, 0x699ce4d6, 0x61ca2e78, 0x111594cd, 0x354ff447, + 0x03316ad2, 0x55cbe709, 0x49fff5c4, 0x418679fd, 0x0f9c6c40, + 0x75bacd75, 0x2972721a, 0x677edc88, 0xe5ef502f, 0x82596887, + 0xbf320e0e, 0x459e9367, 0x8bbdccb2, 0x81ce36ef, 0xb766863d, + 0x1ba097fc, 0xd58c6db8, 0xcd3a21d6, 0xb4a8748b, 0x0e4967cd, + 0x15041c20, 0x2caaf749 }, + { 0x6ed20424, 0x44f98006, 0x22471545, 0xb3e4ea23, 0x781a8c86, + 0x268ed1a5, 0x7ae5b70b, 0x48d0ab75, 0x356d3982, 0x6ca8b320, + 0x2df31fa4, 0x9ce8e681, 0xd925dcf2, 0xb909d232, 0xf56723de, + 0x302c8f78, 0xabac96f9, 0x11725d69, 0x57d1a170, 0x656a47ca, + 0xc18a2be7, 0x6bb5d511, 0xad50d9d9, 0xb56e45f1, 0x70b05518, + 0x36e886e2, 0x09d8ff91, 0xc7c71f3d, 0x9350361e, 0x65a1bbe2, + 0x45fe3bd8, 0x86d7f532 }, + { 0xb0bf719a, 0x99f16eb6, 0x8bc3d913, 0xb6975098, 0x26cd01b4, + 0xfae50e52, 0x90898d1c, 0xd3e3ac54, 0x887ec666, 0x4da3b9db, + 0xfbea45b8, 0x58300644, 0x8355b058, 0x369f3bd9, 0x579bcc13, + 0x0fb239a8, 0x6e2bd811, 0x4f5b4539, 0x24198fd2, 0x007f3baf, + 0x8837d51d, 0x68a676db, 0xeae75b16, 0x68eeea62, 0x3db6083c, + 0x5ffe5f94, 0x7d836c5a, 0x52c94d0f, 0xcbc1ff85, 0x5a4c3c6f, + 0x86c0b4dd, 0x682a55e3 }, + { 0x587495aa, 0xc8f235a4, 0x34c7245d, 0x2276026c, 0xb75a46e3, + 0xd6ae0cc5, 0xecc3e5e7, 0x890d3965, 0x14296629, 0x1b13342f, + 0x8a877227, 0xc89927e6, 0x2324a68b, 0x1543f27e, 0x49cdc21a, + 0x6c447684, 0x1452d0ac, 0x9bc7fd4f, 0xff4b045c, 0x2cc30a31, + 0x852f7611, 0x415d46a0, 0xc6fdd7a6, 0xad737052, 0x7b4c7c91, + 0xdcecc3ab, 0x7688d70c, 0xd2cdf01b, 0xe40d3905, 0x054f2542, + 0xfefe4dcd, 0x02227fa6 }, + { 0xb751948b, 0x1805efd9, 0xfdfd225d, 0x8efeed46, 0x4f2c8b22, + 0xcb128e09, 0x96f7c5e5, 0x9d1090bf, 0xb4cbeca0, 0x0959d044, + 0x8e08cb04, 0x21c955f9, 0x68fa4fce, 0xbc1f279d, 0x0710ae9a, + 0xb021e14e, 0x881167f4, 0x64d16e9f, 0xbbc9f1a5, 0xf5a5c22e, + 0xe3420eea, 0x5f3716df, 0xd5c4e843, 0x971eb915, 0x28ffba81, + 0x64fc55fc, 0x7dd37578, 0x3427e54d, 0x15ebc7d0, 0x446e6a62, + 0x29269778, 0x547e249a }, + { 0xa1ffda27, 0x4706868a, 0x7955cf50, 0xb4e6cdcc, 0x0a63f3d8, + 0xf65151e1, 0x9de5e70a, 0x5b4127ea, 0xf9342823, 0x3d2c09ba, + 0xaa2f7d51, 0x18c99d83, 0xddeec025, 0xa0c5bb1d, 0x03dcf1ce, + 0x7ffddf84, 0x616fdeda, 0xe57e4d29, 0x7932a1f0, 0xd2456569, + 0x3191d4e3, 0x7475e0e8, 0xc220218b, 0x3479bea1, 0x8bcb2505, + 0xfceb5c90, 0x3c6132e6, 0x1c685cea, 0xbfe6c1eb, 0xc42dc745, + 0xd2b08eea, 0x45a41cc0 }, + { 0x4dbbf0e1, 0x3ea9b2c7, 0xa17cf70e, 0x41ff962f, 0x5eeb4c66, + 0xdc1ea758, 0xa9beb17e, 0x4f5412d2, 0xa285741a, 0x2c9e4f52, + 0x984fd11f, 0x93df7da4, 0x0df3184e, 0xb2afbddc, 0x2421e375, + 0x96323d25, 0x49df781e, 0xc87be1e4, 0x3d589bea, 0x145601ed, + 0x28fff6dd, 0x0f0bd9bd, 0x8a0f298c, 0x2d3259d4, 0xd88e6944, + 0x362d7a77, 0xb6ac2af6, 0xa84c06b6, 0xd087da02, 0xba850ac9, + 0x42ee40c8, 0x128763c9 }, + { 0xacbac178, 0x29a80f07, 0x34b08f6e, 0x7cc20044, 0x70feded2, + 0xe9631d14, 0x86615767, 0xb2115da3, 0xcb088548, 0x7c75f5c4, + 0x9a2e8e03, 0x5b29d213, 0x8b881752, 0xfe9fda66, 0xc1de7ebc, + 0x3f1d8d88, 0x03218123, 0xb476565e, 0xb1c995f3, 0x07365561, + 0xb13eb71b, 0x2160cb18, 0x99b3a0eb, 0x7e8da513, 0xb20fcd74, + 0x5e8ca1f9, 0xb4126d72, 0x6a7e0067, 0x68bb637f, 0x1e8204b7, + 0xfc4f74d2, 0x75e96bcc }, + { 0x0d19716e, 0x189d1fdc, 0x7c384525, 0xdf585058, 0xea987d2a, + 0x64a846d1, 0x6c07150f, 0x12b6bf83, 0x4d6fd5b7, 0x91d85d46, + 0x4f53f55f, 0xa9788836, 0x81509129, 0x60083bd8, 0xea876f48, + 0xa7672683, 0xc15b2489, 0xe80b2e7a, 0x42d1d992, 0x985ef8d2, + 0xcf3de492, 0x9c57b029, 0xb1487627, 0xfe02f83c, 0x8ae5b687, + 0xaeba4fe4, 0x5d6b8196, 0x8a86f09b, 0xa16e523d, 0xd88f566b, + 0xba268949, 0x309a6e9a }, + { 0xbdfbe97a, 0xef27ee50, 0xb8c50c4d, 0x1a5fe70f, 0x7fe09f5c, + 0xcc7beb01, 0xbed36cc5, 0x8fa15a85, 0x7550ed3a, 0xc0c3acdb, + 0xeb908681, 0xc581ef87, 0xc49d5ccb, 0xa15b3362, 0x1fa264e8, + 0x0fbb1714, 0x8e1eee88, 0x267f8d8f, 0x21c2b63d, 0xd31ccfd6, + 0x53be7efd, 0x924dbe7d, 0xdb2a358a, 0xd42e877f, 0x75d68ac1, + 0xcf9673c7, 0x714fea55, 0xe35978fd, 0x5769b202, 0xeeb36653, + 0xd7593789, 0x0458258a }, + { 0xa042dbdf, 0x5df71a74, 0x5779dfa2, 0x2d405857, 0x0d2e6657, + 0x0e66cba7, 0xca2e892e, 0x285d6745, 0x0f0e6b5f, 0xf56a8def, + 0xa30767c3, 0xe0ee851d, 0x43346b9c, 0x98c05658, 0xd6b3c742, + 0xb35fce26, 0x39777e00, 0xc0895bff, 0xe7b6d886, 0x83c8f6a6, + 0x4f02904b, 0xbee14843, 0x2e84ec34, 0x7f74915b, 0x96d10991, + 0xbaaf663c, 0xe41facc0, 0x004b8757, 0x6f86c029, 0xa2b880e5, + 0x95b77358, 0x53f4a3e0 }, + { 0x89fc48e7, 0x11bb08ce, 0xafab5aeb, 0xba60c577, 0xa0c1cb5a, + 0xf06bcbf8, 0x79757cb6, 0x7d2efaea, 0x76319160, 0xe26d90b1, + 0x2b77b7a9, 0x42aa1ab6, 0x285df2bf, 0x38eec0cd, 0xf3a8f7f0, + 0xd35947f5, 0xfc1cb5b5, 0x97c8dc0e, 0xc45845cf, 0xfeb8cca0, + 0x249e26f2, 0x16e8d989, 0x483ed89a, 0x7c264e6d, 0x51d91073, + 0x13a3f145, 0x305e99f0, 0x8501562e, 0x6908d563, 0xaaf98d74, + 0xd723d236, 0x0a99e653 }, + { 0xabbc0559, 0x23536f46, 0x9aa1a160, 0xc163067b, 0x0c1681b5, + 0x229fd229, 0x1378e907, 0x61254be1, 0xab793a2d, 0xc60ff57a, + 0x466552db, 0xa6f2df8b, 0x8c170a36, 0x9ad31893, 0x29b74d9a, + 0xc5cd9abe, 0xf7848523, 0xcf747273, 0x0d0e3063, 0xc126a93a, + 0x4248e3d8, 0xfe2021e3, 0x8323ddfa, 0xd97343ee, 0x332639e7, + 0x9f768775, 0x75325548, 0x9650fc31, 0x3eebf7ea, 0xb595dbd1, + 0x010fcbc0, 0x3a95cb45 }, + { 0x39d7ff2e, 0x954e68cb, 0xc1d5c48f, 0x8dd1cb4b, 0x7169438a, + 0x02a92c77, 0x91cad8ce, 0x7965c0b0, 0x32cd08d2, 0x0c5798ab, + 0xa6902bda, 0x1a5bc3c3, 0x5186d218, 0x545d0925, 0xd27e64db, + 0xf0077cdb, 0x8cd092da, 0x0157caa4, 0x24532ab3, 0x2a2fa3a0, + 0x41ccaba3, 0xa5fb639b, 0x4744aee6, 0x01702dc1, 0xcdba93da, + 0x485bb436, 0x329784f1, 0x93597f66, 0xdad672c3, 0x5d713c1d, + 0x030b7245, 0x366d222e }, + { 0x573ea5b2, 0xd50b4875, 0xa90da44d, 0x0fce401b, 0x7a1a0310, + 0x7b53fa65, 0xcf114460, 0x722a80a5, 0xa538bf49, 0x0b8ebf05, + 0xd32acd21, 0xae141147, 0x7b5ad07d, 0x6692712c, 0x3f48ca07, + 0x6dc5fee7, 0x2b8a78d8, 0x98ed1499, 0xdd2f1759, 0x4e8b3145, + 0x5f971b8e, 0x43408de1, 0xadf1b368, 0x055ea6dd, 0xe5932b7e, + 0x4bb76e73, 0xd30893fd, 0x44287153, 0x0661bfda, 0x173dccd2, + 0x79defd25, 0x9072ba99 }, + { 0x9620ea39, 0x474de4dd, 0xc831cee8, 0xfbf1649f, 0xcd3a9c43, + 0x0b0e8bb1, 0x3f3df1d5, 0x6a38286f, 0x8f0ec9b3, 0x4ed072b3, + 0x729c09e3, 0xa6e4c987, 0x8ad12242, 0xea3e8ac6, 0xfbdfa5ba, + 0x6ae0e22b, 0xb0a0f592, 0x56171ecf, 0x6b871f8d, 0x33b2886d, + 0x35e11bda, 0x6b19bea9, 0x7f0f153f, 0x4d815a40, 0x7d6c02ee, + 0x7e608d97, 0xb6a88f46, 0x7e8f23d9, 0x439d1654, 0x26ac9652, + 0x35546c29, 0x8d92c6bd }, + { 0xabeb0ff7, 0xb3e0d7ce, 0x3e0e42f8, 0xfbe35254, 0xde808499, + 0x57d1b226, 0x1cd44bc3, 0x9ece2e1f, 0x435cfee1, 0x1245adbc, + 0xf93f581c, 0x874ee840, 0xbda0b947, 0x916a779c, 0xfa57ae0a, + 0xabcc815a, 0xf0a621b0, 0x97adec2d, 0x81f90bdc, 0xbe6a502b, + 0x53bde63d, 0x54bf9de1, 0x78884c25, 0xa88fdabf, 0xcbbb5470, + 0x30aa52b1, 0x29053ef5, 0xf805396c, 0x8dd827ea, 0x8d43d898, + 0x5c1ae5c0, 0x4e4bec17 }, + { 0xfcc09676, 0xbf8483a2, 0x19ea9a94, 0x457c4a3f, 0xd702a5dd, + 0xa6852ef3, 0x843fe7d8, 0xe7915fd2, 0x16e35158, 0x644bba98, + 0x9ed746f0, 0x8d1b95d0, 0xb90af0b5, 0x47704581, 0xd4fd135e, + 0x0bd4bc6b, 0xb4e833a5, 0xa6dce067, 0xff56a9a1, 0x2c0e8f30, + 0xec2c63fe, 0xa9c80800, 0x98f508a8, 0x449c20a5, 0x3292813a, + 0x02b94cb3, 0xec7e81a2, 0x647e3d28, 0xb4877677, 0x72e67d1a, + 0x6f9ded24, 0x7a4aa3f5 }, + { 0xe27a0045, 0x559ef1ba, 0xb242cb50, 0xdc812d4f, 0x39cf8d24, + 0x23a478e4, 0x9b3f9c54, 0x97544fc5, 0xaffa1fcf, 0x5ac68132, + 0x34a2c83b, 0x74f8fee0, 0xcd3f4bb7, 0x96cc640f, 0xb0512ea6, + 0x775dce9d, 0xcdce381e, 0x67dca19d, 0xa9d3fe55, 0xc1eeb3f3, + 0x1a19274f, 0x38e0bf42, 0x28d69b12, 0x15992fb4, 0x9fd09df8, + 0x48fcebde, 0xb41ab5df, 0xdc9dfa4f, 0xc0a269c5, 0x0cbd7dc8, + 0xf7f0ade1, 0x60282a7b }, + { 0xdceea2e7, 0x7c07e538, 0x3c42061d, 0x38a322c8, 0x4f1f6516, + 0x676828f9, 0xc7776a10, 0xf21b69fb, 0xb5e6b405, 0xc63a3417, + 0x91a7b642, 0x4c99f258, 0x2cad1440, 0x38692ca8, 0x00869bcd, + 0xf1e82ffe, 0x16fe466a, 0xc30b714e, 0x19019138, 0x5fb742f9, + 0x0fa516ae, 0xe90166d0, 0xd8c73a43, 0x5550f7ac, 0xfbc5c372, + 0x2d6a407d, 0x68cc39ed, 0xe47a7539, 0x4a5fbe70, 0x3fd286d9, + 0x23c6b942, 0x5f4ae9c7 }, + { 0x53f4d561, 0xd96a2dda, 0x16da1992, 0x286d45d0, 0xfdd4b051, + 0x449a01fb, 0x9f2195ea, 0x25488a0d, 0xa37661b3, 0xc4151b0a, + 0xf9e5ee02, 0xb98c471e, 0xa8658817, 0xa4bca86e, 0x7a68fc0a, + 0xbbcadb87, 0x6b7366a9, 0x88b34649, 0x15661c2d, 0x32ee98d4, + 0xc901420c, 0xf5b3b4c6, 0x2f2752af, 0xa2352735, 0x510e4d9c, + 0x2f64ce73, 0xaca4aa80, 0x939a7f26, 0x401aa503, 0x9cd3e291, + 0xdc46afd2, 0x92a01423 }, + { 0x1c2f7dbd, 0xe9f24be1, 0xb7d527fa, 0xda8c900f, 0x8648f128, + 0x963e25bb, 0x48141941, 0x9ab713e2, 0x7a6756fb, 0xe87f7d01, + 0x058d90bd, 0x274dd85e, 0x82566abd, 0x823fee7a, 0x74240195, + 0x9f6230d7, 0xacb5e46e, 0x04579f2c, 0x16a4c87e, 0x2a226263, + 0xd99b0857, 0x9ca19a43, 0xe488789e, 0x86dc2ba3, 0x9406c3bd, + 0xf960b5b9, 0x8960957e, 0x6f2c428b, 0x161c515b, 0x90748706, + 0xaa88cb9b, 0x0fc8fe1e }, + { 0xfeb90f2d, 0x68ae1bed, 0xa48b1559, 0xf393bb3c, 0xf64e9635, + 0x2be62f9c, 0xf8be75c2, 0x354c2410, 0x5e6f7529, 0xbd7ea703, + 0x162cab31, 0xc264868e, 0xc860f3ff, 0xb1391e70, 0x1d89837e, + 0xdf367c75, 0x2bf32941, 0xe150b6b4, 0x78c1318f, 0x95e8f46e, + 0xa2c4b160, 0x2b3f1dab, 0x701afbf3, 0xc6ccf5ce, 0x5e8874c5, + 0x3ad27530, 0x5dc6dcbe, 0x39285e51, 0xd99892dd, 0x3c954d86, + 0xdfd3789f, 0x2d0ba862 }, + { 0xb472e1af, 0xeacd8ee8, 0xb76abbcc, 0xeb354eae, 0xd0d93fbd, + 0x9b520bf8, 0xfe6fc706, 0xfccd60d7, 0xa4ee2f39, 0xa9353dde, + 0x9a81e51e, 0x5eb0925e, 0xd1366777, 0xee334da1, 0xd5354d69, + 0xc1d28c9f, 0x92a5ed54, 0xb9771755, 0xb7f70d81, 0x5d3e367f, + 0xa933ae7a, 0x7be7eeca, 0xe23cfbb7, 0x264cf1f9, 0x89497681, + 0x0d129f4a, 0x09b6235b, 0x705375a4, 0x48a376da, 0xccf64c75, + 0x4d41dbfc, 0x963c8712 }, + { 0xde36a814, 0xbae290cb, 0x733b12b5, 0x9bdb0195, 0xf77fe0e1, + 0x0ebad867, 0x29720cea, 0x0a7d19fd, 0x9029ec72, 0x434d7651, + 0xbb51911e, 0x856aff17, 0xd80a7f60, 0xd0a25d9a, 0xf848c106, + 0xffca86af, 0x43ad749c, 0x53e8bdf9, 0xe3e696bb, 0xfb9e0284, + 0xeeee4215, 0x3eb6630a, 0x2ecf3c63, 0x9d8fbb9e, 0x4e00c0c0, + 0x71da4ffa, 0x5d57beac, 0xb296be59, 0xa8cec7ef, 0x1751fbad, + 0xff55d7bd, 0x2d03eb3c }, + { 0x04f2ec1d, 0xeb16925f, 0x0d147ee2, 0xa878f276, 0xaad9d9e0, + 0x442df604, 0x3f71035b, 0x891df44b, 0x8cb95d5b, 0xc28272b3, + 0x5ee8ed23, 0x6f14efb5, 0x13b0f3e3, 0xf3c4460f, 0x6bd7335e, + 0x889f9bd7, 0xf755ba6e, 0x889ee771, 0xed219b6c, 0x626984fe, + 0xec2ee411, 0x2d44c737, 0x63efcd37, 0xb94385a2, 0x6637826b, + 0xd909321b, 0x3ee6b7a7, 0xc24f8a79, 0xa7cf61b7, 0xa3ca8d24, + 0xc54bacd9, 0x842e40c1 }, + { 0xa661d843, 0x5a268ed6, 0x4f5b30cd, 0x02328cca, 0x1311e177, + 0x16e6fed1, 0xc6695967, 0x690decb4, 0x57b2e280, 0xbdac5bf6, + 0x1efe42d0, 0x827f82ca, 0xca5fca2f, 0xc554ec0a, 0xdde45506, + 0xac5276c1, 0xe3077513, 0xb7f4cb08, 0xcc8797cc, 0x8caf6d9a, + 0x0d9332d2, 0xd5964814, 0x285a409f, 0xcc6ae297, 0x6223d093, + 0x7773c2a5, 0x5128fc09, 0x2d5266ac, 0xbc31fe6c, 0xa596b7cb, + 0xcac91328, 0x0e63319a }, + { 0xf0360ac2, 0xb5cd2fad, 0x285e605a, 0x86b660de, 0xe25b9b14, + 0x82c6cf10, 0xaa9ac554, 0x9d5fa38d, 0x526c070e, 0x3dfcf1b8, + 0x3fccc52d, 0x0379a96b, 0x0bfcc7f5, 0xe3659c29, 0x69d3e6a1, + 0x5b1a3db5, 0x9b7b42d5, 0xb41528b5, 0x9c22a006, 0x934defa4, + 0x9b4ce3b6, 0x90f38018, 0xb3abaf32, 0xb073bc04, 0xff8389e2, + 0x27a5a222, 0xffa5a35b, 0x0b7a9d51, 0x28e1a7c2, 0x4939ecef, + 0x1872705a, 0x88839da2 }, + { 0x701ce29a, 0x56b66c30, 0x58981d50, 0x3acaf126, 0x105f9f21, + 0xd4dafc0c, 0x373e3d13, 0xfee571e6, 0xfa2ee3ca, 0xe7269c86, + 0xdd20385a, 0xf5cca64a, 0x3000e9ac, 0x217f2757, 0x0e7273ef, + 0xc934db47, 0x355b6776, 0x4294f4f7, 0x6fc05180, 0x1faa36b9, + 0xb052190b, 0x8f88b1db, 0xe9eaef52, 0x35791b90, 0xdb681b90, + 0xf37fb2eb, 0x4415c369, 0x39d0a51d, 0x1d2e21c9, 0xfc59cca7, + 0xa1f50c26, 0x64128cfe }, + { 0xe8f5b0b5, 0xf03678a2, 0xd340f059, 0x5c7e249c, 0x93ca7cec, + 0x41440441, 0xbc83af98, 0x075ca346, 0xfaa8bbb0, 0xf39f0033, + 0xf38230f7, 0x3d18f0ed, 0xd448f345, 0x78dff00c, 0xd51aa475, + 0x849228c0, 0x30c928d1, 0xdd4e2708, 0x8f12cfd3, 0xc66ba686, + 0x88b3a206, 0x091049db, 0x016dae01, 0xd865d059, 0xe253e37d, + 0x4599e905, 0x7ce9871b, 0x322cf0c2, 0x174a132e, 0x014f54da, + 0xbdabcbda, 0x93634a09 }, + { 0xa9a2e304, 0x62826b27, 0xc1a4c124, 0xc57e1866, 0x22381710, + 0x913ab832, 0xa9847cfe, 0x7e9b6b85, 0x2b5f46fd, 0x29655cf1, + 0x8038e66d, 0x7295572b, 0x6fa95eab, 0xe4cba601, 0xb9deda81, + 0xbbc11071, 0x3f1cf61e, 0x97f0009a, 0x373e0cfb, 0x5372777b, + 0xd139d63b, 0x302f909c, 0x4f87d78e, 0x1ed672da, 0xb4048763, + 0x362077a3, 0x9dcc22b2, 0xc408c32d, 0x26deeee7, 0x4b4c5bf2, + 0xbc06357e, 0x266cb467 }, + { 0xb56363e8, 0x6faa4154, 0x3c1aa4db, 0x4b4fd078, 0x2b9e6597, + 0x14358dde, 0xfa004b84, 0x5b34ae3e, 0xf19911a6, 0xcf44b2ec, + 0xa536bf78, 0x55caa833, 0x8870dc95, 0x606e1eb9, 0x09f3511d, + 0xe3c3287d, 0x9d5cf364, 0x68b2f4eb, 0x63ab8c9e, 0xc154e892, + 0xc36ab611, 0x1548828e, 0xa1b7d120, 0x0932bfcb, 0x5315b8d7, + 0x7ee7b5bc, 0xf7473ac1, 0x782fd0d1, 0x3c8f2af3, 0xbcb029a8, + 0x52454ee1, 0x4b1d5a1b }, + { 0x63d52c0c, 0x12fe5174, 0x188c099d, 0x3735525e, 0x360e3956, + 0x5c621563, 0xacfa5a43, 0x88b3f1ca, 0x797e8107, 0x90123a0a, + 0xb15e080a, 0xba31f6b5, 0xfca3dada, 0xd7de5e12, 0x0df511c8, + 0x3287361b, 0x65757d4e, 0x7cc800d4, 0x5207ec91, 0x10810f3d, + 0x30eea0e3, 0x0d4e56f1, 0x3ea5a2ec, 0xbbf7ee13, 0xbe6abbd0, + 0x6fc07762, 0x120bf619, 0xc831fdce, 0xb622d42a, 0xe07439fa, + 0x508e4b27, 0x8186b93f }, + { 0x09312867, 0xc619d154, 0xbfaf7db4, 0x7e042c05, 0x1f5f5dda, + 0xc1cf1668, 0xa4fc3d82, 0x50aa5057, 0xce68b8fe, 0xed30ed65, + 0xbeb4d644, 0xecb01c0b, 0x831c0497, 0x7b5dc444, 0x9b7d9b1c, + 0x351e6a00, 0xd9477c91, 0x4bb863b9, 0x05d4110a, 0xaba65891, + 0x43580b7a, 0x30086cf4, 0x90be357e, 0xb139c076, 0x27b5214e, + 0x12bfff1a, 0x22c3ab57, 0x79cfc6d7, 0xf34a9bfa, 0x4743de57, + 0xc9ee2b2a, 0x0bf97e97 }, + { 0xdda19e96, 0x96ec4ec8, 0x6c306e8b, 0x54ce18ea, 0x65f6918a, + 0x7e83612b, 0x0d9a0d99, 0x1ac6f68b, 0x62fdcc09, 0x98a697a4, + 0x95bc3e13, 0x65ce25f1, 0xb3939730, 0x1896ecda, 0x32f12806, + 0x9eb81a0f, 0x1d2dc7df, 0xd3d7416e, 0xad473599, 0xe22c7976, + 0x9f5ef439, 0x3de37a9a, 0x9e69d94e, 0x6b7ac0ab, 0x0a9d0bc8, + 0xe6bfa9e0, 0x5676f120, 0x576a870d, 0xfeaac23f, 0x3bd91bb4, + 0x3e40aabb, 0x8fe5482c }, + { 0xce9a4d1e, 0x85ae67c2, 0x4f1d2038, 0x4c3eb803, 0x25d06192, + 0x5c6c8f3a, 0x308fb41c, 0x803de0ad, 0xe71c294e, 0x9961f5bc, + 0xf02eb0da, 0xdc62078d, 0xb64ae8b6, 0xc87ef515, 0x50b4d18f, + 0x69679f1e, 0x52199f43, 0xc5c009a1, 0x0f640a5f, 0xa7d484be, + 0x23dab566, 0x4c918bb1, 0x64275d2c, 0xa67c114c, 0xcad2ded6, + 0x95a913b9, 0x6b4b5c8d, 0x189ed18b, 0xb42d3bf6, 0x4aeb6206, + 0xbbc8bc3f, 0x3928c669 }, + { 0xdacb4b64, 0xde4bea4a, 0xf26179a1, 0x03f62a44, 0x7a9112a4, + 0xf3aac94e, 0xd36f331e, 0x90448fbd, 0x407b85c4, 0x426042bc, + 0x2121b77b, 0x5ad8a596, 0x67cee984, 0x31674a4f, 0x4e3b2f0d, + 0x7fae8bbe, 0xa7c930eb, 0x681df6dd, 0xc259d0d4, 0xadeefa98, + 0xbea1c1fd, 0x1b14d9e6, 0x21d405d1, 0x3baadc8b, 0x73892754, + 0xf01dff93, 0xf071cde4, 0x81c35b3e, 0x9150d0d9, 0x1704d2e1, + 0x355134f6, 0x6ccc888f }, + { 0x7ad7504c, 0xf8d36f0e, 0xf7959ddd, 0xbca3265f, 0xfede67aa, + 0x0dcd1ede, 0xbaebf32f, 0x1276f4ce, 0x014edcfc, 0x6825a6e6, + 0x99ad8eb7, 0x0b8c1a82, 0x09b8ce1e, 0x312024a9, 0x9cbd351a, + 0xcb8fd98b, 0xfab1e8be, 0xa4841378, 0x3973cacf, 0x17ed0f5d, + 0x259d5254, 0xa17e1484, 0x74b91393, 0x53d5b843, 0x1aca3ce9, + 0x8f792b21, 0xc8c0f815, 0x035ff110, 0xad4ed7bd, 0x6afa6357, + 0xb26faef9, 0x2f151980 }, + { 0x29d2d439, 0x0c8631da, 0xbc039955, 0x121fbbc2, 0x6c05b75b, + 0x3e5a9792, 0xb6ce47ec, 0x6d6cf4c0, 0x9d88c658, 0xbaaa1767, + 0xf3355a17, 0x031db9e7, 0x0aef5a85, 0x8381e3d8, 0x15a31bdf, + 0xc71db290, 0x9498fd7d, 0x638f6b74, 0x13beeef6, 0x44edf3f9, + 0xf4ab67b3, 0xe6173271, 0xfd22df11, 0x3a202c70, 0x205c4e92, + 0xf7be0389, 0xa8eb9920, 0x1c219085, 0xbeb54aaa, 0x6c805ce8, + 0x0ac58d65, 0x354b05b7 }, + { 0x7a9170e9, 0x7171e236, 0x4cad50cd, 0x01eec42d, 0x3cddccfb, + 0xffbe824f, 0xa66cae1a, 0xa73e8ce3, 0x965c7d01, 0xb7138a7f, + 0x5c3d971e, 0x00058e3f, 0x2ff0a72b, 0x52591ac3, 0xbbbce76f, + 0xa32fb5bc, 0xa9f81a18, 0xf3241ab8, 0xeca68630, 0xf31d3332, + 0x4482f13b, 0x847af9fc, 0xa4681be2, 0x6196e217, 0xe55efcf9, + 0x9938f932, 0x70acc705, 0x3e7dacb8, 0xcf09fac2, 0xd41be893, + 0xae3523a1, 0x48dc55c4 }, + { 0xa5092193, 0x8e623826, 0x6898970c, 0xe46ec362, 0x25c9eb41, + 0x2f1356af, 0x83c7d245, 0x41780640, 0x97d00e38, 0x982def67, + 0xa512151c, 0x382eb6e7, 0x8af58869, 0x154e1077, 0x8a51cf02, + 0x18707075, 0x71313c58, 0xcdeba9f7, 0xba155904, 0x5d67b973, + 0x1d0d7b3a, 0x851c9f4b, 0x8b8af2cd, 0x19f29d71, 0x986b8d62, + 0xcb94ccff, 0xb93b9c33, 0x8725e24b, 0x66e38c68, 0x405ce4c5, + 0x0b6dc021, 0x5f6a8edd }, + { 0x8f9a8690, 0x83704ca5, 0x2f76a407, 0x3f369766, 0x69201028, + 0xfbc12d8c, 0xbce3a4cf, 0x4cd58f16, 0x04aab26d, 0x7804664a, + 0x4ea457a8, 0x005cfbba, 0xb8a59794, 0x537951b3, 0x4fe1f739, + 0x4ca2b9e4, 0xdf325797, 0xe4428acd, 0x0ea243db, 0x648da342, + 0xf43ce01e, 0xcce6562b, 0xf27db490, 0x840f0421, 0x8bfb7cf0, + 0x156ccb70, 0x5a8797d3, 0x9b33480d, 0x9eb814bb, 0x2e12e07a, + 0xca7f87ac, 0x1ca65072 }, + { 0x2b9d25a0, 0xfbb321cf, 0x40a746db, 0x66affdca, 0x59e368b5, + 0xc1c1530e, 0x7d80068f, 0x56ed1ea4, 0x5647dd68, 0x9b74d8fe, + 0x89b78da8, 0x1d96b507, 0x8bbe3391, 0x39b75243, 0x0d858c5f, + 0xef8d443e, 0x9646aa34, 0x4dd2db49, 0xe667543c, 0x7fad3bd1, + 0x68980985, 0xd0d710c0, 0x49facaba, 0x9f7aff32, 0x14f9a192, + 0x055dec1c, 0x1fb307a1, 0xaca66399, 0x35ffff64, 0xac44fd91, + 0xcbad3cee, 0x462cafb6 }, + { 0xde3237dd, 0x1660a647, 0x82b87404, 0x95f735cc, 0xddfa55f8, + 0xf7879f59, 0x726b914a, 0x15ef043e, 0x1c93e298, 0x1875393d, + 0x6ef18331, 0xa1a2be74, 0x25a9a12b, 0x4e7e8dfc, 0xa9c3917f, + 0xdfefc97d, 0x0a2ebe41, 0xbc875d03, 0xa732d1cc, 0x0f75d235, + 0xd9baa6d3, 0x06fee7fe, 0x65f48576, 0xaa784fab, 0x513f83c0, + 0x23155e22, 0x3e8f9d13, 0xd2fb7718, 0xb546eafd, 0x2a291503, + 0x6cd93608, 0x1293c98c }, + { 0x49d53b77, 0x72781251, 0x96eafac7, 0xa6ab403d, 0x4a36b711, + 0xb7d7c7db, 0x87e771c1, 0x8238c708, 0x33b37522, 0x495f6abf, + 0x8c87530d, 0xb0b0289c, 0xe77b111a, 0xca83cb86, 0xa1bd189e, + 0xbe1c0fb8, 0x1ae9d7c7, 0x58cfb2fb, 0x4940c3e8, 0xd05c23c5, + 0x74ad9107, 0x16e79e41, 0x064e7142, 0xa0a47f05, 0xfdfd614f, + 0xc6929cd4, 0x3946988b, 0xedb2584c, 0xe46f8fb1, 0x73e4b5f3, + 0x68ea94ba, 0x53b79aa1 }, + { 0x44bbb6a1, 0x216fafce, 0x67821728, 0xd3a5bba0, 0xa9dd939a, + 0xef1e4b30, 0xf19efafe, 0x022eaf3d, 0x7b4ec014, 0xfed5abce, + 0x512c6738, 0x64968ee6, 0x29fe89a2, 0x23119869, 0x47397c05, + 0x0d539d8d, 0x234596c4, 0x6400bc54, 0x5346611d, 0xb9287f58, + 0xc9d5da0f, 0x04099903, 0xc83af2a8, 0xe5ef4997, 0x328151e1, + 0xc89dc01b, 0x58401104, 0x150fb4a9, 0xf3872c9d, 0x40a6f7d5, + 0x56c2e833, 0x8290d6d1 }, + { 0xd8546946, 0xf84637c6, 0x69ec57fa, 0xda134a39, 0xd789007e, + 0xd42359a4, 0x0dc7b809, 0xb42557fe, 0x2d6784a9, 0xe62ae52d, + 0x0bcadb5f, 0xa2714ca6, 0x33aafca5, 0xcc208de6, 0xed967811, + 0x2380ed5c, 0xdb321660, 0x6e6b55e9, 0xa675235a, 0x1bead02c, + 0xb33fa0e1, 0x51cc6ef9, 0xf06a2a08, 0xfd223e26, 0xec47b3cf, + 0x00f332e1, 0xa0aa984e, 0x459f297b, 0xee952e14, 0x6fa1d969, + 0x304fabb0, 0x506ef1ab }, + { 0x35bff163, 0x11b4eb27, 0xea9fa984, 0x7130b96f, 0x9deb27ce, + 0x66aceb3f, 0x9dd1c3d5, 0xa2daf1a5, 0xa73075aa, 0xf5090a7e, + 0xe3071b58, 0x36a6af39, 0xdf73ad9c, 0xa28d633d, 0xbdc89a16, + 0xdd354cac, 0xd4dcbc3c, 0xdfea3423, 0x379d92d1, 0x6eec74d2, + 0x8eed6765, 0xe14a456f, 0xfa8feb1f, 0xfabe7743, 0xb98fcbc7, + 0x1404ccf8, 0xf71a706e, 0x6ccd2fbf, 0x4d85c678, 0xdaaf3fdb, + 0x15200344, 0x415b7dbf }, + { 0x7d8377a7, 0x97010586, 0xcb803272, 0x068a3d68, 0xf03a4c32, + 0xfd67d289, 0x93c8f290, 0x4bc7095d, 0xe9e5a2b8, 0x712fa13c, + 0x0feb9f3b, 0xfc6ac6c6, 0x6e0e54c2, 0x0cda36d9, 0x86320a01, + 0x45499751, 0x97f00f11, 0xf9318c91, 0xe6936508, 0x01dc4c3f, + 0x85f068aa, 0x769a2ef9, 0xa2b5511c, 0x3522cef0, 0xb4122e05, + 0x006965ed, 0xc175d43f, 0xfce0fafc, 0xec831d59, 0x525dc9bd, + 0xaf58879d, 0x1ec314f1 }, + { 0x2c8310c2, 0x0663feef, 0x457e3f74, 0xaa7e14da, 0xe5346887, + 0x392b10fc, 0x637ec2c5, 0xcde4a38f, 0xb542f8df, 0x50773320, + 0xf7de1711, 0x341302f9, 0xae4b9bc6, 0x018b1c63, 0xdd2f9e6f, + 0xf001c46e, 0x26eccfa0, 0xd3bb0a97, 0x7746e0c7, 0xa931b99d, + 0xf5875aec, 0xe0c8b6f7, 0x96939c82, 0xbb32f17c, 0x3de5a664, + 0x765135d2, 0x52abfa6b, 0x71936cb4, 0x2dc105de, 0xad5cc08f, + 0x7fff5788, 0x17e91d12 }, + { 0xb7e051ca, 0xbe92ced3, 0x19c776d4, 0xc644d4fd, 0x0086784b, + 0xc8ab4b52, 0xce9d6b31, 0x3ea66227, 0xd289e9c7, 0x395249a3, + 0xd12a19ee, 0x54509e65, 0x8c365aec, 0xa7bd4692, 0x77963e0e, + 0x354997e4, 0xb599732d, 0x0d765957, 0x91d4a3b6, 0x99584aeb, + 0x1deb3e28, 0x6e653ea4, 0x572571df, 0xca7c98ed, 0xb18ae1f9, + 0xf301a38f, 0x63f7b97e, 0x1629f7c2, 0xafc4a0d5, 0xdf242282, + 0x3ddd0c01, 0x118f3b4b }, + { 0x7ad4762b, 0x74a0a0a8, 0x8c58d175, 0x1aef84da, 0x4cf76d86, + 0x16ff4960, 0x7e60d98b, 0xc0be8786, 0x3ecc1dba, 0x83637ffb, + 0x5dd6147a, 0xc244a609, 0x5b0846e5, 0xa3e17834, 0xe77a4c05, + 0x735eb686, 0xdf758695, 0x5bc18b4f, 0x1bdfe52f, 0x15618d0b, + 0x00715ba1, 0x878ecc0d, 0xc2dd617f, 0x1dbdbd1a, 0x21b61710, + 0x21d2b631, 0x44f593c2, 0x22ce8a79, 0x44f17024, 0x3b9b536a, + 0x8d03e727, 0x01d0a67c }, + { 0x1e46533c, 0x7b964236, 0xfb88c2ae, 0xe9477990, 0xa42c4a18, + 0x019b5d16, 0xd83c7a45, 0x7135e81d, 0x4cb663e3, 0x74a69bdd, + 0xe76c0d63, 0x7b67ecdb, 0x11e68da6, 0x03d54521, 0xd2e8650a, + 0x596cceb5, 0x2af03b37, 0xcd572dfd, 0xfabd5952, 0x52364ba1, + 0xb4ed8569, 0x7f47d456, 0xc950d5d4, 0x5ad8b572, 0x486e2f84, + 0xcadd2dfa, 0xc56bb044, 0xdd527b43, 0x997c08e6, 0xc9adba24, + 0x7da6320f, 0x1b625b06 }, + { 0x4fd8446d, 0x44dfaa7b, 0xaf6febeb, 0xc01b2f01, 0xfe8838b5, + 0xbf444388, 0xbba9758b, 0xf33c434f, 0x87156bc9, 0x2b971cba, + 0x1f49098b, 0x6b245e5c, 0x2b41c5dd, 0x87dcb534, 0x34d852d7, + 0xdb1f80c6, 0x2433da34, 0x6d6e3258, 0x3f7df0c2, 0xf6682065, + 0x360cb365, 0xc4ca567c, 0x9826656a, 0x321faac2, 0xbf069768, + 0x13f5ca6f, 0xa7076639, 0x15397921, 0x8400736e, 0xbdf14328, + 0x19fc948d, 0x333eca96 }, + { 0xac775d81, 0x23337948, 0xd41dbbca, 0x38c2518f, 0xbcfce948, + 0x623c7a4f, 0x54703fe7, 0xaad36236, 0x13fb3b5b, 0x2b3a13a4, + 0x7f5c01f0, 0x5db3565a, 0x52359661, 0xd72408dc, 0x1d616e91, + 0x5a17f8e5, 0xcb25b999, 0x90c16eeb, 0x3393743e, 0xf35e8cf1, + 0xe54b64a7, 0x987da74a, 0x65cd449d, 0x557b322a, 0x37e7b15d, + 0x765082a5, 0xf2cd134f, 0x4d25c742, 0x4ccf0746, 0xae9d9c07, + 0x8728d135, 0x72fc2110 }, + { 0xf96004c8, 0xa906b203, 0x458055ff, 0xd83f95cf, 0x55f35909, + 0xd77d5867, 0xe550c8ee, 0x4a9ea6fb, 0x55a06081, 0x91c8cca9, + 0xbce82062, 0x4a1fee78, 0x9a3df85e, 0xeb9ade06, 0x7d3de666, + 0xfbbdcf0c, 0x5d336d51, 0x228a391b, 0x5c2ffc3c, 0x760f8d28, + 0x2f7b165b, 0x1ee48de3, 0x56177040, 0x03803d84, 0x9deff9a0, + 0xe573f648, 0xa17e35a4, 0xe1a2738e, 0x8840a6c6, 0x238ef17c, + 0xb11ed92d, 0x480946f8 }, + { 0xfd71f119, 0x84c747a8, 0x53eb3695, 0x19e65c5e, 0x6298587a, + 0x0e2f6786, 0xab18d6f4, 0x48a48899, 0xc630b8c0, 0xa1a99024, + 0x2caaf892, 0x84975096, 0xe20fd624, 0xc8869aba, 0x6c2b7dd4, + 0x3b72b04d, 0x0992f7d0, 0xe2775eb6, 0x7d06e684, 0x0089c06e, + 0xe4bbd007, 0xcb3b4361, 0x4ba846e4, 0xa1ae666b, 0x46464d9e, + 0xc01c2eb2, 0xc1f8539f, 0xf86f2be6, 0xcf68afc7, 0x16e8e8ae, + 0xc7386902, 0x8dab61fd }, + { 0xd54d1d45, 0x42a5c903, 0xff4f9ba2, 0xacd4297e, 0x34d478b4, + 0x2d88b520, 0x08c4621a, 0x35b2ba2b, 0x34865402, 0xd3d239bb, + 0x911f32e6, 0x1de76aed, 0x3f06fdc2, 0x877f8bcf, 0x9ec51502, + 0x802714c1, 0xa590700d, 0xa10444eb, 0x31dcc957, 0x8694229f, + 0xb8169fed, 0x5ece77ab, 0x2caf080e, 0x55be8a15, 0xcbd7cef1, + 0x3eb21b14, 0x67b97ee1, 0x9def7ad1, 0x118f690c, 0xe03ca879, + 0xf99b29e7, 0x6f77e62d }, + { 0xe40bbf59, 0xa271bded, 0x6401aad6, 0x177ba453, 0x73541cd1, + 0x1755e035, 0x4b71b02f, 0x3465b466, 0xa813359f, 0x22eb7113, + 0x6f38eac7, 0x9792a8fd, 0xff3bf3b5, 0x11aa012f, 0xf85c3fbf, + 0x99aafabf, 0x06c0cc42, 0x91e0a2ef, 0x773b7b3a, 0x314d5d57, + 0xd669840a, 0xae5e2e76, 0x2e5a8be6, 0x86136073, 0xc1cf5580, + 0xee6d7578, 0x68bed102, 0x2344e00f, 0x8184f0eb, 0x799d7886, + 0xc3d2cf80, 0x63819c91 }, + { 0x7884b073, 0xca5392e1, 0xeb1267ea, 0x9ec3a1fc, 0x907038a7, + 0x3d07f5f0, 0xe4c47b70, 0xcb2ac07c, 0x1bf96b91, 0xf96664ee, + 0x2aea4fbf, 0xebf57589, 0xfade6500, 0x5aabf391, 0x171d1204, + 0xc5b3376f, 0xa0d3d81a, 0x1ff60c51, 0x976a844b, 0x10b2cfe7, + 0xbda6125a, 0xe131cc9a, 0x4ebd453e, 0xe0fc16d3, 0x504b6bc1, + 0xc0d0319a, 0x0a2f8cab, 0xe43a0be7, 0x55e49b47, 0xc80afeec, + 0x8265d7ee, 0x67d48d12 }, + { 0xea2d56d6, 0x068d59a7, 0x27480a63, 0xd71abd0e, 0xae7366cd, + 0x6bd11db0, 0x07204ebc, 0xfbb639ca, 0xf77e6293, 0x89a242e7, + 0x75ba8c3d, 0xdee7ca2b, 0x64a2f9a8, 0x472ddc3d, 0x7561a010, + 0x84229df4, 0xc5b649d4, 0x95f62c85, 0x4dc927cd, 0xfdd56b1b, + 0x5ee60596, 0xfe8bb120, 0xabf29401, 0x3efcaa50, 0x10d1c184, + 0xd4900d0f, 0x28b01df5, 0x2cf113a9, 0x1f0e43f5, 0xa3d7ebc3, + 0xe8384dc7, 0x27950e38 }, + { 0xe1d0fa79, 0xeab21ff0, 0x048b5de9, 0x4b9fd033, 0x2fe374cb, + 0x4c934689, 0x4eb21f6b, 0xbb4827fa, 0xa925e7e7, 0x46716f79, + 0x7dd4c531, 0x1442bf36, 0xd2e96ddf, 0x2073954c, 0x8502aa89, + 0x4e0141ae, 0x8eef6cc9, 0x8ee00e1a, 0x5880cdaf, 0x55ce8491, + 0x69628046, 0xff3aba5c, 0x5d15dfbf, 0x335cc4f8, 0x9f684f25, + 0xa7f0440c, 0xbb1e5bd8, 0xae80453f, 0xff2225ab, 0xa1c99813, + 0x79b25d71, 0x54ff7884 }, + { 0xde40b068, 0x27c6ee30, 0xe6f3a51e, 0x9226465b, 0xfa3b21f6, + 0xe24a4604, 0xc0418115, 0x50a5a5ad, 0x8df90d2b, 0xe3285441, + 0xdcb0c00f, 0xbb74e58f, 0x4a2c08e3, 0xc68f1b3b, 0x0ccd9ec9, + 0x339df081, 0xb786ea9f, 0x915362dc, 0xc955aead, 0x28945e31, + 0x8b6a6c6b, 0xd6a2c01d, 0x3678a427, 0x069e82dc, 0x28c9302c, + 0x17875500, 0x9fa101e6, 0x8acda965, 0xee30b286, 0x4e4e4573, + 0x3f1830fe, 0x8adbad85 }, + { 0x0969d524, 0x060ae11f, 0xf39bcc79, 0xf42fdaf7, 0x7cc1fcc2, + 0x3cec6766, 0xe2336d4f, 0x456b9cf2, 0x8e1c0f7f, 0x6aa1f5de, + 0x0984fb0e, 0xcdbc2ad2, 0x1b464b28, 0x4090cfa6, 0x1243f3ef, + 0x40d86f30, 0xcd5e87e7, 0x95b16ccc, 0x3026cd41, 0x403f168c, + 0x816c0730, 0xdbe386cb, 0x58407a1d, 0x14eb86f3, 0x1717e1af, + 0xf588b4f8, 0x66cbc96c, 0xb75c41a6, 0x027e71c1, 0xf342c1aa, + 0xc0945e5f, 0x73930036 }, + { 0x22cdaf42, 0x954f757d, 0xf4181aab, 0x788b591d, 0xf5514f25, + 0x8b986819, 0xf18fd5bc, 0x69642e08, 0x022ceb91, 0x92b305d1, + 0x6a4f6985, 0x1715903e, 0x61179cae, 0x4bd7d69d, 0xd29c01aa, + 0xdacdfd5d, 0xd91108cc, 0x705ddd5a, 0x64ac8f15, 0x434ac7b1, + 0xb524632f, 0x61a514e1, 0x731fc447, 0x45b9e61b, 0xe0961b31, + 0xcf561348, 0x73eaf223, 0x9c28a967, 0xaa7c99d3, 0x5bd10182, + 0xe42965e2, 0x8bc6ec4a }, + { 0xe7f2a32b, 0xd096e5c0, 0x09388a30, 0xff54800c, 0x401e360c, + 0x06fe437c, 0xbb6054a6, 0x6655fc9c, 0x8457aa6e, 0x510e1860, + 0x2b29b2b7, 0xa0acfca2, 0x51b7da61, 0x732483e3, 0x6be6c8ca, + 0xe31471ee, 0x8b65c9a1, 0xe565431c, 0x48d65cbb, 0xfc9ac3b9, + 0xae9b2aa8, 0xd308fc21, 0xaa60aa6a, 0xd6a7df0d, 0x982fc0d4, + 0x2844d96a, 0x5847a4d7, 0xab012c2c, 0xdceb8955, 0x2b3c8f71, + 0xbe9c7e15, 0x8e85437d }, +}; + +/* Perform the modular exponentiation in Fp* for SAKKE. + * + * Base is fixed to be the g parameter - a precomputed table is used. + * + * Striping: 128 points at a distance of 8 combined. + * Total of 256 points in table. + * Square and multiply performed in Fp*. + * + * base [in] Base. MP integer. + * exp [in] Exponent. MP integer. + * res [out] Result. MP integer. + * returns 0 on success, MP_READ_E if there are too many bytes in an array + * and MEMORY_E if memory allocation fails. + */ +int sp_ModExp_Fp_star_1024(const mp_int* base, mp_int* exp, mp_int* res) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td; + sp_digit* t; + sp_digit* tx; + sp_digit* ty; +#else + sp_digit t[4 * 2 * 32]; + sp_digit tx[2 * 32]; + sp_digit ty[2 * 32]; +#endif + sp_digit* r = NULL; + unsigned char e[128]; + int err = MP_OKAY; + int i; + int y; + + (void)base; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6 * 32 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + tx = td + 4 * 32 * 2; + ty = td + 5 * 32 * 2; +#endif + r = ty; + + (void)mp_to_unsigned_bin_len(exp, e, 128); + + XMEMCPY(tx, p1024_norm_mod, sizeof(sp_digit) * 32); + y = e[112] >> 7; + y |= (e[96] >> 7) << 1; + y |= (e[80] >> 7) << 2; + y |= (e[64] >> 7) << 3; + y |= (e[48] >> 7) << 4; + y |= (e[32] >> 7) << 5; + y |= (e[16] >> 7) << 6; + y |= (e[0] >> 7) << 7; + XMEMCPY(ty, sp_1024_g_table[y], sizeof(sp_digit) * 32); + for (i = 126; i >= 0; i--) { + y = (e[127 - (i / 8)] >> (i & 0x7)) & 1; + y |= ((e[111 - (i / 8)] >> (i & 0x7)) & 1) << 1; + y |= ((e[95 - (i / 8)] >> (i & 0x7)) & 1) << 2; + y |= ((e[79 - (i / 8)] >> (i & 0x7)) & 1) << 3; + y |= ((e[63 - (i / 8)] >> (i & 0x7)) & 1) << 4; + y |= ((e[47 - (i / 8)] >> (i & 0x7)) & 1) << 5; + y |= ((e[31 - (i / 8)] >> (i & 0x7)) & 1) << 6; + y |= ((e[15 - (i / 8)] >> (i & 0x7)) & 1) << 7; + + sp_1024_proj_sqr_32(tx, ty, t); + sp_1024_proj_mul_qx1_32(tx, ty, sp_1024_g_table[y], t); + } + } + + if (err == MP_OKAY) { + sp_1024_mont_inv_32(tx, tx, t); + sp_1024_mont_mul_32(r, tx, ty, p1024_mod, p1024_mp_mod); + XMEMSET(r + 32, 0, sizeof(sp_digit) * 32); + sp_1024_mont_reduce_32(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Multiply p* by q* in projective co-ordinates. + * + * p.x' = (p.x * q.x) - (p.y * q.y) + * p.y' = (p.x * q.y) + (p.y * q.x) + * But applying Karatsuba: + * v0 = p.x * q.x + * v1 = p.y * q.y + * p.x' = v0 - v1 + * p.y' = (px + py) * (qx + qy) - v0 - v1 + * + * px [in,out] A single precision integer - X ordinate of number to multiply. + * py [in,out] A single precision integer - Y ordinate of number to multiply. + * qx [in] A single precision integer - X ordinate of number of + * multiplier. + * qy [in] A single precision integer - Y ordinate of number of + * multiplier. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_mul_32(sp_digit* px, sp_digit* py, + const sp_digit* qx, const sp_digit* qy, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 32; + + /* t1 = px + py */ + sp_1024_mont_add_32(t1, px, py, p1024_mod); + /* t2 = qx + qy */ + sp_1024_mont_add_32(t2, qx, qy, p1024_mod); + /* t2 = (px + py) * (qx + qy) */ + sp_1024_mont_mul_32(t2, t1, t2, p1024_mod, p1024_mp_mod); + /* t1 = py * qy */ + sp_1024_mont_mul_32(t1, py, qy, p1024_mod, p1024_mp_mod); + /* t2 = (px + py) * (qx + qy) - (py * qy) */ + sp_1024_mont_sub_32(t2, t2, t1, p1024_mod); + /* px = px * qx */ + sp_1024_mont_mul_32(px, px, qx, p1024_mod, p1024_mp_mod); + /* py = (px + py) * (qx + qy) - (py * qy) - (px * qx) */ + sp_1024_mont_sub_32(py, t2, px, p1024_mod); + /* px = (px * qx) - (py * qy)*/ + sp_1024_mont_sub_32(px, px, t1, p1024_mod); +} + +#ifndef WOLFSSL_SP_SMALL +/* + * Convert point from projective to affine but keep in Montgomery form. + * + * p [in,out] Point to convert. + * t [in] Temporary numbers: 2. + */ +static void sp_1024_mont_map_32(sp_point_1024* p, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 32; + + sp_1024_mont_inv_32(t1, p->z, t2); + sp_1024_mont_sqr_32(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t1, t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(p->x, p->x, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(p->y, p->y, t1, p1024_mod, p1024_mp_mod); + XMEMCPY(p->z, p1024_norm_mod, sizeof(sp_digit) * 32); +} + +#endif /* WOLFSSL_SP_SMALL */ +/* + * Calculate gradient of line through P, P and [-2]P, accumulate line and + * double P. + * + * Calculations: + * l = 3 * (p.x^2 - p.z^4) = 3 * (p.x - p.z^2) * (p.x + p.z^2) + * r.x = l * (p.x + q.x * p.z^2) - 2 * p.y^2 + * r.y = 2 * p.y * p.z^3 * q.y (= p'.z * p.z^2 * q.y) + * v* = v*^2 * r* + * p'.x = l^2 - 8 * p.y^2 * p.x + * p'.y = (4 * p.y^2 * p.x - p'.x) * l - 8 * p.y^4 + * p'.z = 2 * p.y * p.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] p ECC point - point on E(F_p^2) to double. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_dbl_32(sp_digit* vx, sp_digit* vy, + sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 32; + sp_digit* pz2 = t + 2 * 32; + sp_digit* rx = t + 4 * 32; + sp_digit* ry = t + 6 * 32; + sp_digit* l = t + 8 * 32; + sp_digit* ty = t + 10 * 32; + + /* v = v^2 */ + sp_1024_proj_sqr_32(vx, vy, t); + /* pz2 = p.z^2 */ + sp_1024_mont_sqr_32(pz2, p->z, p1024_mod, p1024_mp_mod); + /* t1 = p.x + p.z^2 */ + sp_1024_mont_add_32(ty, p->x, pz2, p1024_mod); + /* l = p.x - p.z^2 */ + sp_1024_mont_sub_32(l, p->x, pz2, p1024_mod); + /* t1 = (p.x + p.z^2) * (p.x - p.z^2) = p.x^2 - p.z^4 */ + sp_1024_mont_mul_32(t1, l, ty, p1024_mod, p1024_mp_mod); + /* l = 3 * (p.x^2 - p.z^4) */ + sp_1024_mont_tpl_32(l, t1, p1024_mod); + /* t1 = q.x * p.z^2 */ + sp_1024_mont_mul_32(t1, q->x, pz2, p1024_mod, p1024_mp_mod); + /* t1 = p.x + q.x * p.z^2 */ + sp_1024_mont_add_32(t1, p->x, t1, p1024_mod); + /* r.x = l * (p.x + q.x * p.z^2) */ + sp_1024_mont_mul_32(rx, l, t1, p1024_mod, p1024_mp_mod); + /* r.y = 2 * p.y */ + sp_1024_mont_dbl_32(ry, p->y, p1024_mod); + /* ty = 4 * p.y ^ 2 */ + sp_1024_mont_sqr_32(ty, ry, p1024_mod, p1024_mp_mod); + /* t1 = 2 * p.y ^ 2 */ + sp_1024_div2_32(t1, ty, p1024_mod); + /* r.x -= 2 * (p.y ^ 2) */ + sp_1024_mont_sub_32(rx, rx, t1, p1024_mod); + /* p'.z = p.y * 2 * p.z */ + sp_1024_mont_mul_32(p->z, p->z, ry, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 */ + sp_1024_mont_mul_32(t1, p->z, pz2, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 * q.y */ + sp_1024_mont_mul_32(ry, t1, q->y, p1024_mod, p1024_mp_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_32(vx, vy, rx, ry, t); + + /* Double point using previously calculated values + * l = 3 * (p.x - p.z^2).(p.x + p.z^2) + * ty = 4 * p.y^2 + * p'.z = 2 * p.y * p.z + */ + /* t1 = (4 * p.y^2) ^ 2 = 16 * p.y^4 */ + sp_1024_mont_sqr_32(t1, ty, p1024_mod, p1024_mp_mod); + /* t1 = 16 * p.y^4 / 2 = 8 * p.y^4 */ + sp_1024_div2_32(t1, t1, p1024_mod); + /* p'.y = 4 * p.y^2 * p.x */ + sp_1024_mont_mul_32(p->y, ty, p->x, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 */ + sp_1024_mont_sqr_32(p->x, l, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 - 4 * p.y^2 * p.x */ + sp_1024_mont_sub_32(p->x, p->x, p->y, p1024_mod); + /* p'.x = l^2 - 8 * p.y^2 * p.x */ + sp_1024_mont_sub_32(p->x, p->x, p->y, p1024_mod); + /* p'.y = 4 * p.y^2 * p.x - p.x' */ + sp_1024_mont_sub_32(ty, p->y, p->x, p1024_mod); + /* p'.y = (4 * p.y^2 * p.x - p'.x) * l */ + sp_1024_mont_mul_32(p->y, ty, l, p1024_mod, p1024_mp_mod); + /* p'.y = (4 * p.y^2 * p.x - p'.x) * l - 8 * p.y^4 */ + sp_1024_mont_sub_32(p->y, p->y, t1, p1024_mod); +} + +#ifdef WOLFSSL_SP_SMALL +/* + * Calculate gradient of line through C, P and -C-P, accumulate line and + * add P to C. + * + * Calculations: + * r.x = (q.x + p.x) * c.y - (q.x * c.z^2 + c.x) * p.y * c.z + * r.y = (c.x - p.x * c.z^2) * q.y * c.z + * v* = v* * r* + * r = p.y * c.z^3 - c.y + * c'.x = r^2 + h^3 - 2 * c.x * h^2 + * c'.y = r * (c'.x - c.x * h^2) - c.y * h^3 + * c'.z = (c.x - p.x * c.z^2) * c.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] c ECC point - current point on E(F_p^2) to be added + * to. + * @param [in] p ECC point - point on E(F_p^2) to add. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] qx_px SP that is a constant value across adds. + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_add_one_32(sp_digit* vx, sp_digit* vy, + sp_point_1024* c, sp_point_1024* p, sp_point_1024* q, sp_digit* qx_px, + sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 32; + sp_digit* rx = t + 4 * 32; + sp_digit* ry = t + 6 * 32; + sp_digit* h = t + 8 * 32; + sp_digit* r = t + 10 * 32; + + /* r.x = (q.x + p.x) * c.y */ + sp_1024_mont_mul_32(rx, qx_px, c->y, p1024_mod, p1024_mp_mod); + /* t2 = c.z^2 */ + sp_1024_mont_sqr_32(t2, c->z, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 */ + sp_1024_mont_mul_32(t1, q->x, t2, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 + c.x */ + sp_1024_mont_add_32(h, t1, c->x, p1024_mod); + /* r = p.y * c.z */ + sp_1024_mont_mul_32(ry, p->y, c->z, p1024_mod, p1024_mp_mod); + /* t1 = (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_mul_32(t1, h, ry, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z * c.z^2 = p.y * c.z^3 */ + sp_1024_mont_mul_32(r, ry, t2, p1024_mod, p1024_mp_mod); + /* r.x -= (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_sub_32(rx, rx, t1, p1024_mod); + /* t1 = p.x * c.z^2 */ + sp_1024_mont_mul_32(t1, p->x, t2, p1024_mod, p1024_mp_mod); + /* h = c.x - p.x * c.z^2 */ + sp_1024_mont_sub_32(h, c->x, t1, p1024_mod); + /* c'.z = (c.x - p.x * c.z^2) * c.z */ + sp_1024_mont_mul_32(c->z, h, c->z, p1024_mod, p1024_mp_mod); + /* r.y = (c.x - p.x * c.z^2) * c.z * q.y */ + sp_1024_mont_mul_32(ry, c->z, q->y, p1024_mod, p1024_mp_mod); + /* v = v * r */ + sp_1024_proj_mul_32(vx, vy, rx, ry, t); + + /* Add p to c using previously calculated values. + * h = c.x - p.x * c.z^2 + * r = p.y * c.z^3 + * c'.z = (c.x - p.x * c.z^2) * c.z + */ + + /* r = p.y * c.z^3 - c.y */ + sp_1024_mont_sub_32(r, r, c->y, p1024_mod); + /* t1 = r^2 */ + sp_1024_mont_sqr_32(t1, r, p1024_mod, p1024_mp_mod); + /* t2 = h^2 */ + sp_1024_mont_sqr_32(rx, h, p1024_mod, p1024_mp_mod); + /* ry = c.x * h^2 */ + sp_1024_mont_mul_32(ry, c->x, rx, p1024_mod, p1024_mp_mod); + /* t2 = h^3 */ + sp_1024_mont_mul_32(t2, rx, h, p1024_mod, p1024_mp_mod); + /* c->x = r^2 + h^3 */ + sp_1024_mont_add_32(c->x, t1, t2, p1024_mod); + /* t1 = 2 * c.x * h^2 */ + sp_1024_mont_dbl_32(t1, ry, p1024_mod); + /* c'.x = r^2 + h^3 - 2 * c.x * h^2 */ + sp_1024_mont_sub_32(c->x, c->x, t1, p1024_mod); + /* ry = c'.x - c.x * h^2 */ + sp_1024_mont_sub_32(t1, c->x, ry, p1024_mod); + /* ry = r * (c'.x - c.x * h^2) */ + sp_1024_mont_mul_32(ry, t1, r, p1024_mod, p1024_mp_mod); + /* t2 = c.y * h^3 */ + sp_1024_mont_mul_32(t1, t2, c->y, p1024_mod, p1024_mp_mod); + /* c'.y = r * (c'.x - c.x * h^2) - c.y * h^3 */ + sp_1024_mont_sub_32(c->y, ry, t1, p1024_mod); +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * @param [in] key SAKKE key. + * @param [in] p First point on E(F_p)[q]. + * @param [in] q Second point on E(F_p)[q]. + * @param [in] r Result of calculation. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +int sp_Pairing_1024(const ecc_point* pm, const ecc_point* qm, mp_int* res) +{ + int err = MP_OKAY; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit* qx_px; +#else + sp_digit t[6 * 2 * 32]; + sp_digit vx[2 * 32]; + sp_digit vy[2 * 32]; + sp_digit qx_px[2 * 32]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + + err = sp_1024_point_new_32(NULL, pd, p); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 9 * 32 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 32 * 2; + vy = td + 7 * 32 * 2; + qx_px = td + 8 * 32 * 2; +#endif + r = vy; + + sp_1024_point_from_ecc_point_32(p, pm); + sp_1024_point_from_ecc_point_32(q, qm); + + err = sp_1024_mod_mul_norm_32(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 32); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 32); + + sp_1024_mont_add_32(qx_px, q->x, p->x, p1024_mod); + + for (i = 1020; i >= 0; i--) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_dbl_32(vx, vy, c, q, t); + + if ((i > 0) && ((p1024_order[i / 32] >> (i % 32)) & 1)) { + /* Accumulate line into v and add P into C. */ + sp_1024_accumulate_line_add_one_32(vx, vy, c, p, q, qx_px, t); + } + } + + /* Final exponentiation */ + sp_1024_proj_sqr_32(vx, vy, t); + sp_1024_proj_sqr_32(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_32(vx, vx, t); + sp_1024_mont_mul_32(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 32, 0, sizeof(sp_digit) * 32); + sp_1024_mont_reduce_32(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_32(c, 1, NULL); + sp_1024_point_free_32(q, 1, NULL); + sp_1024_point_free_32(p, 1, NULL); + return err; +} + +#else +/* + * Calculate gradient of line through C, P and -C-P, accumulate line and + * add P to C. + * + * Both C and P have z ordinates to use in the calculation. + * + * Calculations: + * r.x = (q.x * c.z^2 + c.x) * p.y * c.z - (q.x * p.z^2 + p.x) * c.y * p.z + * r.y = (p.x * c.z^2 - c.x * p.z^2) * q.y * p.z * c.z + * v* = v* * r* + * h = p.x * c.z^2 - c.x * p.z^2 + * r = p.y * c.z^3 - c.y * p.z^3 + * c'.x = r^2 - h^3 - 2 * c.x * p.z^2 * h^2 + * c'.y = r * (c.x * p.z^2 * h^2 - c'.x) - c.y * p.z^3 * h^3 + * c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] c ECC point - current point on E(F_p^2) to be added + * to. + * @param [in,out] p ECC point - point on E(F_p^2) to add. + * @param [in,out] q ECC point - second point on E(F_P^2). + * @param [in,out] t SP temporaries (6 used). + * @param [in,out] neg Indicates to use negative P. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static void sp_1024_accumulate_line_add_n_32(sp_digit* vx, sp_digit* vy, + const sp_point_1024* p, const sp_point_1024* q, + sp_point_1024* c, sp_digit* t, int neg) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 32; + sp_digit* rx = t + 4 * 32; + sp_digit* ry = t + 6 * 32; + sp_digit* h = t + 8 * 32; + sp_digit* r = t + 10 * 32; + + /* h = p.z^2 */ + sp_1024_mont_sqr_32(h, p->z, p1024_mod, p1024_mp_mod); + /* rx = q.x * p.z^2 */ + sp_1024_mont_mul_32(rx, q->x, h, p1024_mod, p1024_mp_mod); + /* rx = q.x * p.z^2 + p.x */ + sp_1024_mont_add_32(t2, rx, p->x, p1024_mod); + /* c.y = c.y * p.z */ + sp_1024_mont_mul_32(t1, c->y, p->z, p1024_mod, p1024_mp_mod); + /* r.x = (q.x * p.z^2 + p.x) * c.y * p.z */ + sp_1024_mont_mul_32(rx, t2, t1, p1024_mod, p1024_mp_mod); + /* c.y = c.y * p.z^3 */ + sp_1024_mont_mul_32(c->y, t1, h, p1024_mod, p1024_mp_mod); + /* t2 = c.z^2 */ + sp_1024_mont_sqr_32(t2, c->z, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 */ + sp_1024_mont_mul_32(t1, q->x, t2, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 + c.x */ + sp_1024_mont_add_32(t1, t1, c->x, p1024_mod); + /* c.x = c.x * p.z^2 */ + sp_1024_mont_mul_32(c->x, c->x, h, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z */ + sp_1024_mont_mul_32(r, p->y, c->z, p1024_mod, p1024_mp_mod); + if (neg) { + /* r = -p.y * c.z */ + sp_1024_mont_sub_32(r, p1024_mod, r, p1024_mod); + } + /* t1 = (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_mul_32(ry, t1, r, p1024_mod, p1024_mp_mod); + /* r.x -= (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_sub_32(rx, ry, rx, p1024_mod); + /* t1 = p.x * c.z^2 */ + sp_1024_mont_mul_32(t1, p->x, t2, p1024_mod, p1024_mp_mod); + /* h = p.x * c.z^2 - c.x * p.z^2 */ + sp_1024_mont_sub_32(h, t1, c->x, p1024_mod); + /* c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z */ + sp_1024_mont_mul_32(t1, h, c->z, p1024_mod, p1024_mp_mod); + /* c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z * p.z */ + sp_1024_mont_mul_32(c->z, t1, p->z, p1024_mod, p1024_mp_mod); + /* r.y = (p.x * c.z^2 - c.x * p.z^2) * c.z * p.z * q.y */ + sp_1024_mont_mul_32(ry, c->z, q->y, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z^3 */ + sp_1024_mont_mul_32(t1, r, t2, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z^3 - c.y * p.z^3 */ + sp_1024_mont_sub_32(r, t1, c->y, p1024_mod); + /* v = v * r */ + sp_1024_proj_mul_32(vx, vy, rx, ry, t); + + /* Add p to c using previously calculated values. + * h = p.x * c.z^2 - c.x * p.z^2 + * r = p.y * c.z^3 - c.y * p.z^3 + * c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z + */ + + /* t1 = r^2 */ + sp_1024_mont_sqr_32(t1, r, p1024_mod, p1024_mp_mod); + /* t2 = h^2 */ + sp_1024_mont_sqr_32(rx, h, p1024_mod, p1024_mp_mod); + /* ry = c.x * p.z^2 * h^2 */ + sp_1024_mont_mul_32(ry, rx, c->x, p1024_mod, p1024_mp_mod); + /* t2 = h^3 */ + sp_1024_mont_mul_32(t2, rx, h, p1024_mod, p1024_mp_mod); + /* c'.x = r^2 - h^3 */ + sp_1024_mont_sub_32(c->x, t1, t2, p1024_mod); + /* t1 = 2 * c.x * p.z^2 * h^2 */ + sp_1024_mont_dbl_32(t1, ry, p1024_mod); + /* c'.x = r^2 - h^3 - 2 * c.x * p.z^2 * h^2 */ + sp_1024_mont_sub_32(c->x, c->x, t1, p1024_mod); + /* ry = c.x * p.z^2 * h^2 - c'.x */ + sp_1024_mont_sub_32(t1, ry, c->x, p1024_mod); + /* ry = r * (c.x * p.z^2 * h^2 - c'.x) */ + sp_1024_mont_mul_32(ry, t1, r, p1024_mod, p1024_mp_mod); + /* t2 = c.y * p.z^3 * h^3 */ + sp_1024_mont_mul_32(t1, t2, c->y, p1024_mod, p1024_mp_mod); + /* c'.y = r * (c.x * p.z^2 * h^2 - c'.x) - c.y * p.z^3 * h^3 */ + sp_1024_mont_sub_32(c->y, ry, t1, p1024_mod); +} + +/* + * Perform n accumulate doubles and doubles of P. + * + * py = 2 * p.y + * + * For each double: + * Calculate gradient of line through P, P and [-2]P, accumulate line and + * double P. + * + * Calculations: + * l = 3 * (p.x^2 - p.z^4) = 3 * (p.x - p.z^2) * (p.x + p.z^2) + * r.x = l * (p.x + q.x * p.z^2) - py^2 / 2 + * r.y = py * p.z^3 * q.y (= p'.z * p.z^2 * q.y) + * v* = v*^2 * r* + * p'.x = l^2 - 2 * py^2 * p.x + * py' = (py^2 * p.x - p'.x) * l - py^4 (= 2 * p'.y) + * p'.z = py * p.z + * + * Finally: + * p'.y = py' / 2 + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] p ECC point - point on E(F_p^2) to double. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] n Number of times to double. + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_dbl_n_32(sp_digit* vx, sp_digit* vy, + sp_point_1024* p, const sp_point_1024* q, int n, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 32; + sp_digit* pz2 = t + 2 * 32; + sp_digit* rx = t + 4 * 32; + sp_digit* ry = t + 6 * 32; + sp_digit* l = t + 8 * 32; + sp_digit* ty = t + 10 * 32; + int i; + + /* py = 2 * p.y */ + sp_1024_mont_dbl_32(p->y, p->y, p1024_mod); + + for (i = 0; i < n; i++) { + /* v = v^2 */ + sp_1024_proj_sqr_32(vx, vy, t); + /* pz2 = p.z^2 */ + sp_1024_mont_sqr_32(pz2, p->z, p1024_mod, p1024_mp_mod); + /* t1 = p.x + p.z^2 */ + sp_1024_mont_add_32(t1, p->x, pz2, p1024_mod); + /* l = p.x - p.z^2 */ + sp_1024_mont_sub_32(l, p->x, pz2, p1024_mod); + /* t1 = (p.x + p.z^2) * (p.x - p.z^2) = p.x^2 - p.z^4 */ + sp_1024_mont_mul_32(ty, l, t1, p1024_mod, p1024_mp_mod); + /* l = 3 * (p.x^2 - p.z^4) */ + sp_1024_mont_tpl_32(l, ty, p1024_mod); + /* t1 = q.x * p.z^2 */ + sp_1024_mont_mul_32(t1, q->x, pz2, p1024_mod, p1024_mp_mod); + /* t1 = p.x + q.x * p.z^2 */ + sp_1024_mont_add_32(t1, p->x, t1, p1024_mod); + /* r.x = l * (p.x + q.x * p.z^2) */ + sp_1024_mont_mul_32(rx, l, t1, p1024_mod, p1024_mp_mod); + /* ty = py ^ 2 */ + sp_1024_mont_sqr_32(ty, p->y, p1024_mod, p1024_mp_mod); + /* t1 = py ^ 2 / 2 */ + sp_1024_div2_32(t1, ty, p1024_mod); + /* r.x -= py ^ 2 / 2 */ + sp_1024_mont_sub_32(rx, rx, t1, p1024_mod); + /* p'.z = py * pz */ + sp_1024_mont_mul_32(p->z, p->z, p->y, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 */ + sp_1024_mont_mul_32(t1, p->z, pz2, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 * q.y */ + sp_1024_mont_mul_32(ry, t1, q->y, p1024_mod, p1024_mp_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_32(vx, vy, rx, ry, t); + + /* Double point using previously calculated values + * l = 3 * (p.x - p.z^2).(p.x + p.z^2) + * ty = py^2 + * p'.z = py * p.z + */ + /* t1 = py^2 ^ 2 = py^4 */ + sp_1024_mont_sqr_32(t1, ty, p1024_mod, p1024_mp_mod); + /* py' = py^2 * p. x */ + sp_1024_mont_mul_32(p->y, ty, p->x, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 */ + sp_1024_mont_sqr_32(p->x, l, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 - py^2 * p.x */ + sp_1024_mont_sub_32(p->x, p->x, p->y, p1024_mod); + /* p'.x = l^2 - 2 * p.y^2 * p.x */ + sp_1024_mont_sub_32(p->x, p->x, p->y, p1024_mod); + /* py' = py^2 * p.x - p.x' */ + sp_1024_mont_sub_32(ty, p->y, p->x, p1024_mod); + /* py' = (p.y^2 * p.x - p'.x) * l */ + sp_1024_mont_mul_32(p->y, ty, l, p1024_mod, p1024_mp_mod); + /* py' = (p.y^2 * p.x - p'.x) * l * 2 */ + sp_1024_mont_dbl_32(p->y, p->y, p1024_mod); + /* py' = (p.y^2 * p.x - p'.x) * l * 2 - p.y^4 */ + sp_1024_mont_sub_32(p->y, p->y, t1, p1024_mod); + } + + /* p'.y = py' / 2 */ + sp_1024_div2_32(p->y, p->y, p1024_mod); +} + +/* Operations to perform based on order - 1. + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * Pairs: #dbls, add/subtract window value + */ +static const signed char sp_1024_order_op[] = { + 5, 6, -13, 9, -21, 6, -5, 8, 31, 6, 3, 6, -27, 6, 25, 9, + -1, 6, -11, 6, -13, 6, -7, 6, -15, 6, -29, 7, 25, 6, -9, 6, + -19, 7, 3, 6, 11, 9, -23, 6, 1, 6, 27, 6, 1, 7, -25, 8, + 13, 7, -13, 7, -23, 10, 19, 7, 7, 7, -3, 7, 27, 6, -7, 7, + -21, 7, 11, 7, 31, 8, 1, 7, -23, 6, -17, 6, -3, 10, 11, 6, + -21, 7, -27, 11, -29, 6, -1, 10, 15, 8, 27, 7, 17, 6, 17, 7, + -13, 8, 13, 6, 21, 7, -29, 6, 19, 7, -25, 6, 11, 9, 29, 7, + -7, 8, 27, 7, 29, 10, -1, 8, -7, 8, 17, 6, 17, 7, -27, 7, + -21, 6, -9, 6, -27, 12, -23, 6, 19, 6, 13, 6, -11, 7, 27, 6, + 17, 6, -7, 6, -25, 7, -29, 6, 9, 7, 7, 6, 13, 6, -25, 6, + -19, 6, 13, 6, -11, 6, 5, 8, 19, 6, -21, 8, 23, 7, 27, 6, + -13, 6, -19, 11, 29, 7, -15, 6, -9, 7, -21, 10, -3, 7, 21, 10, + 25, 6, -15, 6, -23, 6, 21, 6, 1, 6, 21, 7, -3, 6, -3, 7, + -7, 6, -23, 7, 7, 8, 15, 9, 5, 6, -11, 6, 21, 11, -27, 7, + 27, 6, -11, 6, 31, 6, -21, 6, 19, 6, -7, 8, -7, 13, -3, 6, + -7, 7, -3, 6, 1, 6, 7, 8, 19, 8, 11, 9, -9, 7, -31, 12, + 25, 6, -17, 9, -15, 7, 5, 6, 25, 7, -5, 7, -25, 6, 17, 8, + -19, 6, -13, 6, 27, 8, 1, 7, -5, 7, -1, 6, 21, 6, 3, 10, + -3, 1, +}; +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int sp_Pairing_1024(const ecc_point* pm, const ecc_point* qm, mp_int* res) +{ + int err; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit (*pre_vx)[64]; + sp_digit (*pre_vy)[64]; + sp_digit (*pre_nvy)[64]; + sp_point_1024* pre_p; +#else + sp_digit t[6 * 2 * 32]; + sp_digit vx[2 * 32]; + sp_digit vy[2 * 32]; + sp_digit pre_vx[16][64]; + sp_digit pre_vy[16][64]; + sp_digit pre_nvy[16][64]; + sp_point_1024 pre_p[16]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + int j; + + err = sp_1024_point_new_32(NULL, pd, p); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 56 * 32 * 2 + 16 * sizeof(sp_point_1024), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 32 * 2; + vy = td + 7 * 32 * 2; + pre_vx = (sp_digit(*)[64])(td + 8 * 32 * 2); + pre_vy = (sp_digit(*)[64])(td + 24 * 32 * 2); + pre_nvy = (sp_digit(*)[64])(td + 40 * 32 * 2); + pre_p = (sp_point_1024*)(td + 56 * 32 * 2); +#endif + r = vy; + + sp_1024_point_from_ecc_point_32(p, pm); + sp_1024_point_from_ecc_point_32(q, qm); + + err = sp_1024_mod_mul_norm_32(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMCPY(&pre_p[0], p, sizeof(sp_point_1024)); + XMEMSET(pre_vx[0], 0, sizeof(sp_digit) * 2 * 32); + pre_vx[0][0] = 1; + XMEMSET(pre_vy[0], 0, sizeof(sp_digit) * 2 * 32); + sp_1024_mont_sub_32(pre_nvy[0], p1024_mod, pre_vy[0], p1024_mod); + + /* [2]P for adding */ + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 32); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 32); + sp_1024_accumulate_line_dbl_32(vx, vy, c, q, t); + + /* 3, 5, ... */ + for (i = 1; i < 16; i++) { + XMEMCPY(&pre_p[i], &pre_p[i-1], sizeof(sp_point_1024)); + XMEMCPY(pre_vx[i], pre_vx[i-1], sizeof(sp_digit) * 2 * 32); + XMEMCPY(pre_vy[i], pre_vy[i-1], sizeof(sp_digit) * 2 * 32); + sp_1024_proj_mul_32(pre_vx[i], pre_vy[i], vx, vy, t); + sp_1024_accumulate_line_add_n_32(pre_vx[i], pre_vy[i], c, + q, &pre_p[i], t, 0); + sp_1024_mont_sub_32(pre_nvy[i], p1024_mod, pre_vy[i], p1024_mod); + } + + j = sp_1024_order_op[0] / 2; + XMEMCPY(c, &pre_p[j], sizeof(sp_point_1024)); + XMEMCPY(vx, pre_vx[j], sizeof(sp_digit) * 2 * 32); + XMEMCPY(vy, pre_vy[j], sizeof(sp_digit) * 2 * 32); + + /* Accumulate line into v and double point n times. */ + sp_1024_accumulate_line_dbl_n_32(vx, vy, c, q, + sp_1024_order_op[1], t); + + for (i = 2; i < 290; i += 2) { + j = sp_1024_order_op[i]; + if (j > 0) { + j /= 2; + /* Accumulate line into v and add P into C. */ + sp_1024_proj_mul_32(vx, vy, pre_vx[j], pre_vy[j], t); + sp_1024_accumulate_line_add_n_32(vx, vy, &pre_p[j], q, c, + t, 0); + } + else { + j = -j / 2; + /* Accumulate line into v and add P into C. */ + sp_1024_proj_mul_32(vx, vy, pre_vx[j], pre_nvy[j], t); + sp_1024_accumulate_line_add_n_32(vx, vy, &pre_p[j], q, c, + t, 1); + } + + /* Accumulate line into v and double point n times. */ + sp_1024_accumulate_line_dbl_n_32(vx, vy, c, q, + sp_1024_order_op[i + 1], t); + } + + /* Final exponentiation */ + sp_1024_proj_sqr_32(vx, vy, t); + sp_1024_proj_sqr_32(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_32(vx, vx, t); + sp_1024_mont_mul_32(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 32, 0, sizeof(sp_digit) * 32); + sp_1024_mont_reduce_32(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_32(c, 1, NULL); + sp_1024_point_free_32(q, 1, NULL); + sp_1024_point_free_32(p, 1, NULL); + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* + * Generate table for pairing. + * + * Small implementation does not use a table - returns 0 length. + * + * pm [in] Point to generate table for. + * table [in] Generated table. + * len [in,out] On in, the size of the buffer. + * On out, length of table generated. + * @return 0 on success. + * LENGTH_ONLY_E when table is NULL and only length returned. + * BUFFER_E when len is too small. + */ +int sp_Pairing_gen_precomp_1024(const ecc_point* pm, byte* table, + word32* len) +{ + int err = 0; + + if (table == NULL) { + *len = 0; + err = LENGTH_ONLY_E; + } + else if (*len != 0) { + err = BUFFER_E; + } + + (void)*pm; + + return err; +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Small implementation does not use a table - use the normal implementation. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @param [in] table Precomputed table of values. + * @param [in] len Length of precomputed table of values in bytes. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int sp_Pairing_precomp_1024(const ecc_point* pm, const ecc_point* qm, + mp_int* res, const byte* table, word32 len) +{ + (void)table; + (void)len; + return sp_Pairing_1024(pm, qm, res); +} + +#else +/* + * Calc l and c for the point when doubling p. + * + * l = 3 * (p.x^2 - 1) / (2 * p.y) + * c = l * p.x - p.y + * + * @param [out] lr Gradient result - table entry. + * @param [out] cr Constant result - table entry. + * @param [in] px X-ordinate of point to double. + * @param [in] py Y-ordinate of point to double. + * @param [in] t SP temporaries (3 used). + */ +static void sp_1024_accum_dbl_calc_lc_32(sp_digit* lr, sp_digit* cr, + const sp_digit* px, const sp_digit* py, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 2 * 32; + sp_digit* t2 = t + 2 * 2 * 32; + sp_digit* l = t + 4 * 2 * 32; + + + /* l = 1 / 2 * p.y */ + sp_1024_mont_dbl_32(l, py, p1024_mod); + sp_1024_mont_inv_32(l, l, t); + + /* t1 = p.x^2 */ + sp_1024_mont_sqr_32(t1, px, p1024_mod, p1024_mp_mod); + /* t1 = p.x - 1 */ + sp_1024_mont_sub_32(t1, t1, p1024_norm_mod, p1024_mod); + /* t1 = 3 * (p.x^2 - 1) */ + sp_1024_mont_dbl_32(t2, t1, p1024_mod); + sp_1024_mont_add_32(t1, t1, t2, p1024_mod); + /* t1 = 3 * (p.x^2 - 1) / (2 * p.y) */ + sp_1024_mont_mul_32(l, l, t1, p1024_mod, p1024_mp_mod); + /* t2 = l * p.x */ + sp_1024_mont_mul_32(t2, l, px, p1024_mod, p1024_mp_mod); + /* c = t2 = l * p.x - p.y */ + sp_1024_mont_sub_32(t2, t2, py, p1024_mod); + + XMEMCPY(lr, l, sizeof(sp_digit) * 32); + XMEMCPY(cr, t2, sizeof(sp_digit) * 32); +} + +/* + * Calc l and c when adding p and c. + * + * l = (c.y - p.y) / (c.x - p.x) + * c = (p.x * c.y - cx * p.y) / (cx - p.x) + * + * @param [out] lr Gradient result - table entry. + * @param [out] cr Constant result - table entry. + * @param [in] px X-ordinate of point to add. + * @param [in] py Y-ordinate of point to add. + * @param [in] cx X-ordinate of current point. + * @param [in] cy Y-ordinate of current point. + * @param [in] t SP temporaries (3 used). + */ +static void sp_1024_accum_add_calc_lc_32(sp_digit* lr, sp_digit* cr, + const sp_digit* px, const sp_digit* py, const sp_digit* cx, + const sp_digit* cy, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 2 * 32; + sp_digit* c = t + 2 * 2 * 32; + sp_digit* l = t + 4 * 2 * 32; + + + /* l = 1 / (c.x - p.x) */ + sp_1024_mont_sub_32(l, cx, px, p1024_mod); + sp_1024_mont_inv_32(l, l, t); + + /* c = p.x * c.y */ + sp_1024_mont_mul_32(c, px, cy, p1024_mod, p1024_mp_mod); + /* t1 = c.x * p.y */ + sp_1024_mont_mul_32(t1, cx, py, p1024_mod, p1024_mp_mod); + /* c = (p.x * c.y) - (c.x * p.y) */ + sp_1024_mont_sub_32(c, c, t1, p1024_mod); + /* c = ((p.x * c.y) - (c.x * p.y)) / (c.x - p.x) */ + sp_1024_mont_mul_32(c, c, l, p1024_mod, p1024_mp_mod); + /* t1 = c.y - p.y */ + sp_1024_mont_sub_32(t1, cy, py, p1024_mod); + /* l = (c.y - p.y) / (c.x - p.x) */ + sp_1024_mont_mul_32(l, t1, l, p1024_mod, p1024_mp_mod); + + XMEMCPY(lr, l, sizeof(sp_digit) * 32); + XMEMCPY(cr, c, sizeof(sp_digit) * 32); +} + +/* + * Calculate vx and vy given gradient l and constant c and point q. + * + * l is a the gradient and is multiplied by q->x. + * c is a the constant that is added to the multiplicative result. + * q->y is the y-ordinate in result to multiply. + * + * if dbl + * v* = v*^2 + * r.x = l * q.x + c + * r.y = q->y + * v* = v* * r* + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in] l Gradient to multiply with. + * @param [in] c Constant to add with. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] t SP temporaries (3 used). + * @param [in] dbl Indicates whether this is for doubling. Otherwise + * adding. + */ +static void sp_1024_accumulate_line_lc_32(sp_digit* vx, sp_digit* vy, + const sp_digit* l, const sp_digit* c, const sp_point_1024* q, + sp_digit* t, int dbl) +{ + sp_digit* rx = t + 4 * 2 * 32; + + /* v = v^2 */ + if (dbl) { + sp_1024_proj_sqr_32(vx, vy, t); + } + /* rx = l * q.x + c */ + sp_1024_mont_mul_32(rx, l, q->x, p1024_mod, p1024_mp_mod); + sp_1024_mont_add_32(rx, rx, c, p1024_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_32(vx, vy, rx, q->y, t); +} + +/* Operations to perform based on order - 1. + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * Pairs: #dbls, add/subtract window value + */ +static const signed char sp_1024_order_op_pre[] = { + 5, 6, -13, 9, -21, 6, -5, 8, 31, 6, 3, 6, -27, 6, 25, 9, + -1, 6, -11, 6, -13, 6, -7, 6, -15, 6, -29, 7, 25, 6, -9, 6, + -19, 7, 3, 6, 11, 9, -23, 6, 1, 6, 27, 6, 1, 7, -25, 8, + 13, 7, -13, 7, -23, 10, 19, 7, 7, 7, -3, 7, 27, 6, -7, 7, + -21, 7, 11, 7, 31, 8, 1, 7, -23, 6, -17, 6, -3, 10, 11, 6, + -21, 7, -27, 11, -29, 6, -1, 10, 15, 8, 27, 7, 17, 6, 17, 7, + -13, 8, 13, 6, 21, 7, -29, 6, 19, 7, -25, 6, 11, 9, 29, 7, + -7, 8, 27, 7, 29, 10, -1, 8, -7, 8, 17, 6, 17, 7, -27, 7, + -21, 6, -9, 6, -27, 12, -23, 6, 19, 6, 13, 6, -11, 7, 27, 6, + 17, 6, -7, 6, -25, 7, -29, 6, 9, 7, 7, 6, 13, 6, -25, 6, + -19, 6, 13, 6, -11, 6, 5, 8, 19, 6, -21, 8, 23, 7, 27, 6, + -13, 6, -19, 11, 29, 7, -15, 6, -9, 7, -21, 10, -3, 7, 21, 10, + 25, 6, -15, 6, -23, 6, 21, 6, 1, 6, 21, 7, -3, 6, -3, 7, + -7, 6, -23, 7, 7, 8, 15, 9, 5, 6, -11, 6, 21, 11, -27, 7, + 27, 6, -11, 6, 31, 6, -21, 6, 19, 6, -7, 8, -7, 13, -3, 6, + -7, 7, -3, 6, 1, 6, 7, 8, 19, 8, 11, 9, -9, 7, -31, 12, + 25, 6, -17, 9, -15, 7, 5, 6, 25, 7, -5, 7, -25, 6, 17, 8, + -19, 6, -13, 6, 27, 8, 1, 7, -5, 7, -1, 6, 21, 6, 3, 10, + -3, 1, +}; + +/* + * Generate table for pairing. + * + * Calculate the graident (l) and constant (c) at each step of the way. + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * + * pm [in] Point to generate table for. + * table [in] Generated table. + * len [in,out] On in, the size of the buffer. + * On out, length of table generated. + * @return 0 on success. + * LENGTH_ONLY_E when table is NULL and only length returned. + * BUFFER_E when len is too small. + * MEMORY_E when dynamic memory allocation fauls. + */ +int sp_Pairing_gen_precomp_1024(const ecc_point* pm, byte* table, + word32* len) +{ + int err = 0; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_point_1024* pre_p; +#else + sp_digit t[6 * 2 * 32]; + sp_point_1024 pre_p[16]; + sp_point_1024 pd; + sp_point_1024 cd; + sp_point_1024 negd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* c = NULL; + sp_point_1024* neg = NULL; + int i; + int j; + int k; + sp_table_entry_1024* precomp = (sp_table_entry_1024*)table; + + if (table == NULL) { + *len = sizeof(sp_table_entry_1024) * 1167; + err = LENGTH_ONLY_E; + } + + if ((err == MP_OKAY) && + (*len < (int)(sizeof(sp_table_entry_1024) * 1167))) { + err = BUFFER_E; + } + + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, pd, p); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, cd, c); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, negd, neg); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6 * 32 * 2 + 16 * sizeof(sp_point_1024), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + pre_p = (sp_point_1024*)(td + 6 * 32 * 2); +#endif + + sp_1024_point_from_ecc_point_32(p, pm); + + err = sp_1024_mod_mul_norm_32(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(p->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + neg->infinity = 0; + c->infinity = 0; + + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMCPY(&pre_p[0], p, sizeof(sp_point_1024)); + /* [2]P for adding */ + sp_1024_proj_point_dbl_32(c, p, t); + + /* 1, 3, ... */ + for (i = 1; i < 16; i++) { + sp_1024_proj_point_add_32(&pre_p[i], &pre_p[i-1], c, t); + sp_1024_mont_map_32(&pre_p[i], t); + } + + k = 0; + j = sp_1024_order_op_pre[0] / 2; + XMEMCPY(c, &pre_p[j], sizeof(sp_point_1024)); + + for (j = 0; j < sp_1024_order_op_pre[1]; j++) { + sp_1024_accum_dbl_calc_lc_32(precomp[k].x, precomp[k].y, c->x, c->y, t); + k++; + sp_1024_proj_point_dbl_32(c, c, t); + sp_1024_mont_map_32(c, t); + } + + for (i = 2; i < 290; i += 2) { + j = sp_1024_order_op_pre[i]; + if (j > 0) { + sp_1024_accum_add_calc_lc_32(precomp[k].x, precomp[k].y, + pre_p[j/2].x, pre_p[j/2].y, c->x, c->y, t); + k++; + sp_1024_proj_point_add_32(c, c, &pre_p[j/2], t); + sp_1024_mont_map_32(c, t); + } + else { + XMEMCPY(neg->x, pre_p[-j / 2].x, sizeof(pre_p->x)); + sp_1024_mont_sub_32(neg->y, p1024_mod, pre_p[-j / 2].y, + p1024_mod); + XMEMCPY(neg->z, pre_p[-j / 2].z, sizeof(pre_p->z)); + + sp_1024_accum_add_calc_lc_32(precomp[k].x, precomp[k].y, + neg->x, neg->y, c->x, c->y, t); + k++; + sp_1024_proj_point_add_32(c, c, neg, t); + sp_1024_mont_map_32(c, t); + } + + for (j = 0; j < sp_1024_order_op_pre[i + 1]; j++) { + sp_1024_accum_dbl_calc_lc_32(precomp[k].x, precomp[k].y, c->x, c->y, t); + k++; + sp_1024_proj_point_dbl_32(c, c, t); + sp_1024_mont_map_32(c, t); + } + } + + *len = sizeof(sp_table_entry_1024) * 1167; + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_32(neg, 1, NULL); + sp_1024_point_free_32(c, 1, NULL); + sp_1024_point_free_32(p, 1, NULL); + return err; +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * Pre-generate values in window (1, 3, ...) - only V. + * Table contains all gradient l and a constant for each point on the path. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @param [in] table Precomputed table of values. + * @param [in] len Length of precomputed table of values in bytes. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int sp_Pairing_precomp_1024(const ecc_point* pm, const ecc_point* qm, + mp_int* res, const byte* table, word32 len) +{ + int err = 0; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit (*pre_vx)[64]; + sp_digit (*pre_vy)[64]; + sp_digit (*pre_nvy)[64]; +#else + sp_digit t[6 * 2 * 32]; + sp_digit vx[2 * 32]; + sp_digit vy[2 * 32]; + sp_digit pre_vx[16][64]; + sp_digit pre_vy[16][64]; + sp_digit pre_nvy[16][64]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + int j; + int k; + const sp_table_entry_1024* precomp = (const sp_table_entry_1024*)table; + + if (len < (int)(sizeof(sp_table_entry_1024) * 1167)) { + err = BUFFER_E; + } + + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, pd, p); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 56 * 32 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 32 * 2; + vy = td + 7 * 32 * 2; + pre_vx = (sp_digit(*)[64])(td + 8 * 32 * 2); + pre_vy = (sp_digit(*)[64])(td + 24 * 32 * 2); + pre_nvy = (sp_digit(*)[64])(td + 40 * 32 * 2); +#endif + r = vy; + + sp_1024_point_from_ecc_point_32(p, pm); + sp_1024_point_from_ecc_point_32(q, qm); + + err = sp_1024_mod_mul_norm_32(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMSET(pre_vx[0], 0, sizeof(sp_digit) * 2 * 32); + pre_vx[0][0] = 1; + XMEMSET(pre_vy[0], 0, sizeof(sp_digit) * 2 * 32); + sp_1024_mont_sub_32(pre_nvy[0], p1024_mod, pre_vy[0], p1024_mod); + + /* [2]P for adding */ + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 32); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 32); + sp_1024_accumulate_line_dbl_32(vx, vy, c, q, t); + + /* 3, 5, ... */ + for (i = 1; i < 16; i++) { + XMEMCPY(pre_vx[i], pre_vx[i-1], sizeof(sp_digit) * 2 * 32); + XMEMCPY(pre_vy[i], pre_vy[i-1], sizeof(sp_digit) * 2 * 32); + sp_1024_proj_mul_32(pre_vx[i], pre_vy[i], vx, vy, t); + sp_1024_accumulate_line_add_n_32(pre_vx[i], pre_vy[i], c, + q, p, t, 0); + sp_1024_mont_sub_32(pre_nvy[i], p1024_mod, pre_vy[i], + p1024_mod); + } + + XMEMCPY(c->z, p1024_norm_mod, sizeof(sp_digit) * 32); + c->infinity = 0; + j = sp_1024_order_op_pre[0] / 2; + XMEMCPY(vx, pre_vx[j], sizeof(sp_digit) * 2 * 32); + XMEMCPY(vy, pre_vy[j], sizeof(sp_digit) * 2 * 32); + + k = 0; + for (j = 0; j < sp_1024_order_op_pre[1]; j++) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_lc_32(vx, vy, precomp[k].x, + precomp[k].y, q, t, 1); + k++; + } + + for (i = 2; i < 290; i += 2) { + sp_1024_accumulate_line_lc_32(vx, vy, precomp[k].x, + precomp[k].y, q, t, 0); + k++; + + j = sp_1024_order_op_pre[i]; + if (j > 0) { + j /= 2; + /* Accumulate line into v. */ + sp_1024_proj_mul_32(vx, vy, pre_vx[j], pre_vy[j], t); + } + else { + j = -j / 2; + /* Accumulate line into v. */ + sp_1024_proj_mul_32(vx, vy, pre_vx[j], pre_nvy[j], t); + } + + for (j = 0; j < sp_1024_order_op_pre[i + 1]; j++) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_lc_32(vx, vy, precomp[k].x, + precomp[k].y, q, t, 1); + k++; + } + } + + /* Final exponentiation */ + sp_1024_proj_sqr_32(vx, vy, t); + sp_1024_proj_sqr_32(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_32(vx, vx, t); + sp_1024_mont_mul_32(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 32, 0, sizeof(sp_digit) * 32); + sp_1024_mont_reduce_32(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_32(c, 1, NULL); + sp_1024_point_free_32(q, 1, NULL); + sp_1024_point_free_32(p, 1, NULL); + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Returns 1 if the number of zero. + * Implementation is constant time. + * + * a Number to check. + * returns 1 if the number is zero and 0 otherwise. + */ +static int sp_1024_iszero_32(const sp_digit* a) +{ + return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6] | a[7] | + a[8] | a[9] | a[10] | a[11] | a[12] | a[13] | a[14] | a[15] | + a[16] | a[17] | a[18] | a[19] | a[20] | a[21] | a[22] | a[23] | + a[24] | a[25] | a[26] | a[27] | a[28] | a[29] | a[30] | a[31]) == 0; +} + +#ifdef HAVE_ECC_CHECK_KEY +/* Read big endian unsigned byte array into r. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a Byte array. + * n Number of bytes in array to read. + */ +static void sp_1024_from_bin(sp_digit* r, int size, const byte* a, int n) +{ + int i; + int j = 0; + word32 s = 0; + + r[0] = 0; + for (i = n-1; i >= 0; i--) { + r[j] |= (((sp_digit)a[i]) << s); + if (s >= 24U) { + r[j] &= 0xffffffff; + s = 32U - s; + if (j + 1 >= size) { + break; + } + r[++j] = (sp_digit)a[i] >> s; + s = 8U - s; + } + else { + s += 8U; + } + } + + for (j++; j < size; j++) { + r[j] = 0; + } +} + +/* Check that the x and y oridinates are a valid point on the curve. + * + * point EC point. + * heap Heap to use if dynamically allocating. + * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is + * not on the curve and MP_OKAY otherwise. + */ +static int sp_1024_ecc_is_point_32(const sp_point_1024* point, + void* heap) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* d = NULL; +#else + sp_digit t1d[2*32]; + sp_digit t2d[2*32]; +#endif + sp_digit* t1; + sp_digit* t2; + int32_t n; + int err = MP_OKAY; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 4, heap, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + (void)heap; + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t1 = d + 0 * 32; + t2 = d + 2 * 32; +#else + t1 = t1d; + t2 = t2d; +#endif + + sp_1024_sqr_32(t1, point->y); + (void)sp_1024_mod_32(t1, t1, p1024_mod); + sp_1024_sqr_32(t2, point->x); + (void)sp_1024_mod_32(t2, t2, p1024_mod); + sp_1024_mul_32(t2, t2, point->x); + (void)sp_1024_mod_32(t2, t2, p1024_mod); + (void)sp_1024_sub_32(t2, p1024_mod, t2); + sp_1024_mont_add_32(t1, t1, t2, p1024_mod); + + sp_1024_mont_add_32(t1, t1, point->x, p1024_mod); + sp_1024_mont_add_32(t1, t1, point->x, p1024_mod); + sp_1024_mont_add_32(t1, t1, point->x, p1024_mod); + + n = sp_1024_cmp_32(t1, p1024_mod); + sp_1024_cond_sub_32(t1, t1, p1024_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_32(t1); + if (!sp_1024_iszero_32(t1)) { + err = MP_VAL; + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (d != NULL) { + XFREE(d, heap, DYNAMIC_TYPE_ECC); + } +#endif + + return err; +} + +/* Check that the x and y oridinates are a valid point on the curve. + * + * pX X ordinate of EC point. + * pY Y ordinate of EC point. + * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is + * not on the curve and MP_OKAY otherwise. + */ +int sp_ecc_is_point_1024(const mp_int* pX, const mp_int* pY) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 pubd; +#endif + sp_point_1024* pub; + byte one[1] = { 1 }; + int err; + + err = sp_1024_point_new_32(NULL, pubd, pub); + if (err == MP_OKAY) { + sp_1024_from_mp(pub->x, 32, pX); + sp_1024_from_mp(pub->y, 32, pY); + sp_1024_from_bin(pub->z, 32, one, (int)sizeof(one)); + + err = sp_1024_ecc_is_point_32(pub, NULL); + } + + sp_1024_point_free_32(pub, 0, NULL); + + return err; +} + +/* Check that the private scalar generates the EC point (px, py), the point is + * on the curve and the point has the correct order. + * + * pX X ordinate of EC point. + * pY Y ordinate of EC point. + * privm Private scalar that generates EC point. + * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is + * not on the curve, ECC_INF_E if the point does not have the correct order, + * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and + * MP_OKAY otherwise. + */ +int sp_ecc_check_key_1024(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_digit privd[32]; + sp_point_1024 pubd; + sp_point_1024 pd; +#endif + sp_digit* priv = NULL; + sp_point_1024* pub; + sp_point_1024* p = NULL; + byte one[1] = { 1 }; + int err; + + err = sp_1024_point_new_32(heap, pubd, pub); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, pd, p); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY && privm) { + priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32, heap, + DYNAMIC_TYPE_ECC); + if (priv == NULL) { + err = MEMORY_E; + } + } +#endif + + /* Quick check the lengs of public key ordinates and private key are in + * range. Proper check later. + */ + if ((err == MP_OKAY) && ((mp_count_bits(pX) > 1024) || + (mp_count_bits(pY) > 1024) || + ((privm != NULL) && (mp_count_bits(privm) > 1024)))) { + err = ECC_OUT_OF_RANGE_E; + } + + if (err == MP_OKAY) { +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + priv = privd; +#endif + + sp_1024_from_mp(pub->x, 32, pX); + sp_1024_from_mp(pub->y, 32, pY); + sp_1024_from_bin(pub->z, 32, one, (int)sizeof(one)); + if (privm) + sp_1024_from_mp(priv, 32, privm); + + /* Check point at infinitiy. */ + if ((sp_1024_iszero_32(pub->x) != 0) && + (sp_1024_iszero_32(pub->y) != 0)) { + err = ECC_INF_E; + } + } + + /* Check range of X and Y */ + if ((err == MP_OKAY) && + ((sp_1024_cmp_32(pub->x, p1024_mod) >= 0) || + (sp_1024_cmp_32(pub->y, p1024_mod) >= 0))) { + err = ECC_OUT_OF_RANGE_E; + } + + if (err == MP_OKAY) { + /* Check point is on curve */ + err = sp_1024_ecc_is_point_32(pub, heap); + } + + if (err == MP_OKAY) { + /* Point * order = infinity */ + err = sp_1024_ecc_mulmod_32(p, pub, p1024_order, 1, 1, heap); + } + /* Check result is infinity */ + if ((err == MP_OKAY) && ((sp_1024_iszero_32(p->x) == 0) || + (sp_1024_iszero_32(p->y) == 0))) { + err = ECC_INF_E; + } + + if (privm) { + if (err == MP_OKAY) { + /* Base * private = point */ + err = sp_1024_ecc_mulmod_base_32(p, priv, 1, 1, heap); + } + /* Check result is public key */ + if ((err == MP_OKAY) && + ((sp_1024_cmp_32(p->x, pub->x) != 0) || + (sp_1024_cmp_32(p->y, pub->y) != 0))) { + err = ECC_PRIV_KEY_E; + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (priv != NULL) { + XFREE(priv, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_32(p, 0, heap); + sp_1024_point_free_32(pub, 0, heap); + + return err; +} +#endif +#endif /* WOLFSSL_SP_1024 */ #endif /* WOLFSSL_HAVE_SP_ECC */ #endif /* WOLFSSL_SP_ARM32_ASM */ -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH || WOLFSSL_HAVE_SP_ECC */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH | WOLFSSL_HAVE_SP_ECC */ diff --git a/wolfcrypt/src/sp_arm64.c b/wolfcrypt/src/sp_arm64.c index 7e29ce1bc..546ea4ac5 100644 --- a/wolfcrypt/src/sp_arm64.c +++ b/wolfcrypt/src/sp_arm64.c @@ -1,6 +1,6 @@ /* sp.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -58,7 +58,8 @@ */ static void sp_2048_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j; + int i; + int j; byte* d; for (i = n - 1,j = 0; i >= 7; i -= 8) { @@ -111,7 +112,8 @@ static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 64 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -145,7 +147,9 @@ static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -184,7 +188,8 @@ static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a) */ static void sp_2048_to_bin(sp_digit* r, byte* a) { - int i, j; + int i; + int j; for (i = 31, j = 0; i >= 0; i--) { a[j++] = r[i] >> 56; @@ -207,422 +212,412 @@ static void sp_2048_to_bin(sp_digit* r, byte* a) */ static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) { - sp_digit tmp[8]; - __asm__ __volatile__ ( - "ldp x9, x10, [%[a], 0]\n\t" - "ldp x11, x12, [%[a], 16]\n\t" - "ldp x13, x14, [%[a], 32]\n\t" - "ldp x15, x16, [%[a], 48]\n\t" - "ldp x17, x19, [%[b], 0]\n\t" - "ldp x20, x21, [%[b], 16]\n\t" - "ldp x22, x23, [%[b], 32]\n\t" - "ldp x24, x25, [%[b], 48]\n\t" + "ldp x8, x9, [%[a], 0]\n\t" + "ldp x10, x11, [%[a], 16]\n\t" + "ldp x12, x13, [%[a], 32]\n\t" + "ldp x14, x15, [%[a], 48]\n\t" + "ldp x16, x17, [%[b], 0]\n\t" + "ldp x19, x20, [%[b], 16]\n\t" + "ldp x21, x22, [%[b], 32]\n\t" + "ldp x23, x24, [%[b], 48]\n\t" "# A[0] * B[0]\n\t" - "mul x4, x9, x17\n\t" - "umulh x5, x9, x17\n\t" - "str x4, [%[tmp]]\n\t" + "mul x3, x8, x16\n\t" + "umulh x4, x8, x16\n\t" + "str x3, [%[r]]\n\t" "# A[0] * B[1]\n\t" - "mul x7, x9, x19\n\t" - "umulh x8, x9, x19\n\t" - "adds x5, x5, x7\n\t" + "mul x6, x8, x17\n\t" + "umulh x7, x8, x17\n\t" + "adds x4, x4, x6\n\t" "# A[1] * B[0]\n\t" - "mul x7, x10, x17\n\t" - "adc x6, xzr, x8\n\t" - "umulh x8, x10, x17\n\t" - "adds x5, x5, x7\n\t" - "adcs x6, x6, x8\n\t" - "str x5, [%[tmp], 8]\n\t" - "adc x4, xzr, xzr\n\t" + "mul x6, x9, x16\n\t" + "adc x5, xzr, x7\n\t" + "umulh x7, x9, x16\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "str x4, [%[r], 8]\n\t" + "adc x3, xzr, xzr\n\t" "# A[0] * B[2]\n\t" - "mul x7, x9, x20\n\t" - "umulh x8, x9, x20\n\t" - "adds x6, x6, x7\n\t" + "mul x6, x8, x19\n\t" + "umulh x7, x8, x19\n\t" + "adds x5, x5, x6\n\t" "# A[1] * B[1]\n\t" - "mul x7, x10, x19\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x10, x19\n\t" - "adc x5, xzr, xzr\n\t" - "adds x6, x6, x7\n\t" + "mul x6, x9, x17\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x9, x17\n\t" + "adc x4, xzr, xzr\n\t" + "adds x5, x5, x6\n\t" "# A[2] * B[0]\n\t" - "mul x7, x11, x17\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x11, x17\n\t" - "adc x5, x5, xzr\n\t" - "adds x6, x6, x7\n\t" - "adcs x4, x4, x8\n\t" - "str x6, [%[tmp], 16]\n\t" - "adc x5, x5, xzr\n\t" + "mul x6, x10, x16\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x10, x16\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" + "adcs x3, x3, x7\n\t" + "str x5, [%[r], 16]\n\t" + "adc x4, x4, xzr\n\t" "# A[0] * B[3]\n\t" - "mul x7, x9, x21\n\t" - "umulh x8, x9, x21\n\t" - "adds x4, x4, x7\n\t" + "mul x6, x8, x20\n\t" + "umulh x7, x8, x20\n\t" + "adds x3, x3, x6\n\t" "# A[1] * B[2]\n\t" - "mul x7, x10, x20\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x10, x20\n\t" - "adc x6, xzr, xzr\n\t" - "adds x4, x4, x7\n\t" + "mul x6, x9, x19\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x9, x19\n\t" + "adc x5, xzr, xzr\n\t" + "adds x3, x3, x6\n\t" "# A[2] * B[1]\n\t" - "mul x7, x11, x19\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x11, x19\n\t" - "adc x6, x6, xzr\n\t" - "adds x4, x4, x7\n\t" + "mul x6, x10, x17\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x10, x17\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" "# A[3] * B[0]\n\t" - "mul x7, x12, x17\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x12, x17\n\t" - "adc x6, x6, xzr\n\t" - "adds x4, x4, x7\n\t" - "adcs x5, x5, x8\n\t" - "str x4, [%[tmp], 24]\n\t" - "adc x6, x6, xzr\n\t" + "mul x6, x11, x16\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x11, x16\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" + "adcs x4, x4, x7\n\t" + "str x3, [%[r], 24]\n\t" + "adc x5, x5, xzr\n\t" "# A[0] * B[4]\n\t" - "mul x7, x9, x22\n\t" - "umulh x8, x9, x22\n\t" - "adds x5, x5, x7\n\t" + "mul x6, x8, x21\n\t" + "umulh x7, x8, x21\n\t" + "adds x4, x4, x6\n\t" "# A[1] * B[3]\n\t" - "mul x7, x10, x21\n\t" - "adcs x6, x6, x8\n\t" - "umulh x8, x10, x21\n\t" - "adc x4, xzr, xzr\n\t" - "adds x5, x5, x7\n\t" + "mul x6, x9, x20\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x9, x20\n\t" + "adc x3, xzr, xzr\n\t" + "adds x4, x4, x6\n\t" "# A[2] * B[2]\n\t" - "mul x7, x11, x20\n\t" - "adcs x6, x6, x8\n\t" - "umulh x8, x11, x20\n\t" - "adc x4, x4, xzr\n\t" - "adds x5, x5, x7\n\t" + "mul x6, x10, x19\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x10, x19\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" "# A[3] * B[1]\n\t" - "mul x7, x12, x19\n\t" - "adcs x6, x6, x8\n\t" - "umulh x8, x12, x19\n\t" - "adc x4, x4, xzr\n\t" - "adds x5, x5, x7\n\t" + "mul x6, x11, x17\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x11, x17\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" "# A[4] * B[0]\n\t" - "mul x7, x13, x17\n\t" - "adcs x6, x6, x8\n\t" - "umulh x8, x13, x17\n\t" - "adc x4, x4, xzr\n\t" - "adds x5, x5, x7\n\t" - "adcs x6, x6, x8\n\t" - "str x5, [%[tmp], 32]\n\t" - "adc x4, x4, xzr\n\t" + "mul x6, x12, x16\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x12, x16\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "str x4, [%[r], 32]\n\t" + "adc x3, x3, xzr\n\t" "# A[0] * B[5]\n\t" - "mul x7, x9, x23\n\t" - "umulh x8, x9, x23\n\t" - "adds x6, x6, x7\n\t" + "mul x6, x8, x22\n\t" + "umulh x7, x8, x22\n\t" + "adds x5, x5, x6\n\t" "# A[1] * B[4]\n\t" - "mul x7, x10, x22\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x10, x22\n\t" - "adc x5, xzr, xzr\n\t" - "adds x6, x6, x7\n\t" + "mul x6, x9, x21\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x9, x21\n\t" + "adc x4, xzr, xzr\n\t" + "adds x5, x5, x6\n\t" "# A[2] * B[3]\n\t" - "mul x7, x11, x21\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x11, x21\n\t" - "adc x5, x5, xzr\n\t" - "adds x6, x6, x7\n\t" + "mul x6, x10, x20\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x10, x20\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" "# A[3] * B[2]\n\t" - "mul x7, x12, x20\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x12, x20\n\t" - "adc x5, x5, xzr\n\t" - "adds x6, x6, x7\n\t" + "mul x6, x11, x19\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x11, x19\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" "# A[4] * B[1]\n\t" - "mul x7, x13, x19\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x13, x19\n\t" - "adc x5, x5, xzr\n\t" - "adds x6, x6, x7\n\t" + "mul x6, x12, x17\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x12, x17\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" "# A[5] * B[0]\n\t" - "mul x7, x14, x17\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x14, x17\n\t" - "adc x5, x5, xzr\n\t" - "adds x6, x6, x7\n\t" - "adcs x4, x4, x8\n\t" - "str x6, [%[tmp], 40]\n\t" - "adc x5, x5, xzr\n\t" + "mul x6, x13, x16\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x13, x16\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" + "adcs x3, x3, x7\n\t" + "str x5, [%[r], 40]\n\t" + "adc x4, x4, xzr\n\t" "# A[0] * B[6]\n\t" - "mul x7, x9, x24\n\t" - "umulh x8, x9, x24\n\t" - "adds x4, x4, x7\n\t" + "mul x6, x8, x23\n\t" + "umulh x7, x8, x23\n\t" + "adds x3, x3, x6\n\t" "# A[1] * B[5]\n\t" - "mul x7, x10, x23\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x10, x23\n\t" - "adc x6, xzr, xzr\n\t" - "adds x4, x4, x7\n\t" + "mul x6, x9, x22\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x9, x22\n\t" + "adc x5, xzr, xzr\n\t" + "adds x3, x3, x6\n\t" "# A[2] * B[4]\n\t" - "mul x7, x11, x22\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x11, x22\n\t" - "adc x6, x6, xzr\n\t" - "adds x4, x4, x7\n\t" + "mul x6, x10, x21\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x10, x21\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" "# A[3] * B[3]\n\t" - "mul x7, x12, x21\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x12, x21\n\t" - "adc x6, x6, xzr\n\t" - "adds x4, x4, x7\n\t" + "mul x6, x11, x20\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x11, x20\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" "# A[4] * B[2]\n\t" - "mul x7, x13, x20\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x13, x20\n\t" - "adc x6, x6, xzr\n\t" - "adds x4, x4, x7\n\t" + "mul x6, x12, x19\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x12, x19\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" "# A[5] * B[1]\n\t" - "mul x7, x14, x19\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x14, x19\n\t" - "adc x6, x6, xzr\n\t" - "adds x4, x4, x7\n\t" + "mul x6, x13, x17\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x13, x17\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" "# A[6] * B[0]\n\t" - "mul x7, x15, x17\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x15, x17\n\t" - "adc x6, x6, xzr\n\t" - "adds x4, x4, x7\n\t" - "adcs x5, x5, x8\n\t" - "str x4, [%[tmp], 48]\n\t" - "adc x6, x6, xzr\n\t" + "mul x6, x14, x16\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x14, x16\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" + "adcs x4, x4, x7\n\t" + "str x3, [%[r], 48]\n\t" + "adc x5, x5, xzr\n\t" "# A[0] * B[7]\n\t" - "mul x7, x9, x25\n\t" - "umulh x8, x9, x25\n\t" - "adds x5, x5, x7\n\t" + "mul x6, x8, x24\n\t" + "umulh x7, x8, x24\n\t" + "adds x4, x4, x6\n\t" "# A[1] * B[6]\n\t" - "mul x7, x10, x24\n\t" - "adcs x6, x6, x8\n\t" - "umulh x8, x10, x24\n\t" - "adc x4, xzr, xzr\n\t" - "adds x5, x5, x7\n\t" + "mul x6, x9, x23\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x9, x23\n\t" + "adc x3, xzr, xzr\n\t" + "adds x4, x4, x6\n\t" "# A[2] * B[5]\n\t" - "mul x7, x11, x23\n\t" - "adcs x6, x6, x8\n\t" - "umulh x8, x11, x23\n\t" - "adc x4, x4, xzr\n\t" - "adds x5, x5, x7\n\t" + "mul x6, x10, x22\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x10, x22\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" "# A[3] * B[4]\n\t" - "mul x7, x12, x22\n\t" - "adcs x6, x6, x8\n\t" - "umulh x8, x12, x22\n\t" - "adc x4, x4, xzr\n\t" - "adds x5, x5, x7\n\t" + "mul x6, x11, x21\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x11, x21\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" "# A[4] * B[3]\n\t" - "mul x7, x13, x21\n\t" - "adcs x6, x6, x8\n\t" - "umulh x8, x13, x21\n\t" - "adc x4, x4, xzr\n\t" - "adds x5, x5, x7\n\t" + "mul x6, x12, x20\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x12, x20\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" "# A[5] * B[2]\n\t" - "mul x7, x14, x20\n\t" - "adcs x6, x6, x8\n\t" - "umulh x8, x14, x20\n\t" - "adc x4, x4, xzr\n\t" - "adds x5, x5, x7\n\t" + "mul x6, x13, x19\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x13, x19\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" "# A[6] * B[1]\n\t" - "mul x7, x15, x19\n\t" - "adcs x6, x6, x8\n\t" - "umulh x8, x15, x19\n\t" - "adc x4, x4, xzr\n\t" - "adds x5, x5, x7\n\t" + "mul x6, x14, x17\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x14, x17\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" "# A[7] * B[0]\n\t" - "mul x7, x16, x17\n\t" - "adcs x6, x6, x8\n\t" - "umulh x8, x16, x17\n\t" - "adc x4, x4, xzr\n\t" - "adds x5, x5, x7\n\t" - "adcs x6, x6, x8\n\t" - "str x5, [%[tmp], 56]\n\t" - "adc x4, x4, xzr\n\t" + "mul x6, x15, x16\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x15, x16\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "str x4, [%[r], 56]\n\t" + "adc x3, x3, xzr\n\t" "# A[1] * B[7]\n\t" - "mul x7, x10, x25\n\t" - "umulh x8, x10, x25\n\t" - "adds x6, x6, x7\n\t" + "mul x6, x9, x24\n\t" + "umulh x7, x9, x24\n\t" + "adds x5, x5, x6\n\t" "# A[2] * B[6]\n\t" - "mul x7, x11, x24\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x11, x24\n\t" - "adc x5, xzr, xzr\n\t" - "adds x6, x6, x7\n\t" + "mul x6, x10, x23\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x10, x23\n\t" + "adc x4, xzr, xzr\n\t" + "adds x5, x5, x6\n\t" "# A[3] * B[5]\n\t" - "mul x7, x12, x23\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x12, x23\n\t" - "adc x5, x5, xzr\n\t" - "adds x6, x6, x7\n\t" + "mul x6, x11, x22\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x11, x22\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" "# A[4] * B[4]\n\t" - "mul x7, x13, x22\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x13, x22\n\t" - "adc x5, x5, xzr\n\t" - "adds x6, x6, x7\n\t" + "mul x6, x12, x21\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x12, x21\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" "# A[5] * B[3]\n\t" - "mul x7, x14, x21\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x14, x21\n\t" - "adc x5, x5, xzr\n\t" - "adds x6, x6, x7\n\t" + "mul x6, x13, x20\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x13, x20\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" "# A[6] * B[2]\n\t" - "mul x7, x15, x20\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x15, x20\n\t" - "adc x5, x5, xzr\n\t" - "adds x6, x6, x7\n\t" + "mul x6, x14, x19\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x14, x19\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" "# A[7] * B[1]\n\t" - "mul x7, x16, x19\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x16, x19\n\t" - "adc x5, x5, xzr\n\t" - "adds x6, x6, x7\n\t" - "adcs x4, x4, x8\n\t" - "str x6, [%[r], 64]\n\t" - "adc x5, x5, xzr\n\t" + "mul x6, x15, x17\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x15, x17\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" + "adcs x3, x3, x7\n\t" + "str x5, [%[r], 64]\n\t" + "adc x4, x4, xzr\n\t" "# A[2] * B[7]\n\t" - "mul x7, x11, x25\n\t" - "umulh x8, x11, x25\n\t" - "adds x4, x4, x7\n\t" + "mul x6, x10, x24\n\t" + "umulh x7, x10, x24\n\t" + "adds x3, x3, x6\n\t" "# A[3] * B[6]\n\t" - "mul x7, x12, x24\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x12, x24\n\t" - "adc x6, xzr, xzr\n\t" - "adds x4, x4, x7\n\t" - "# A[4] * B[5]\n\t" - "mul x7, x13, x23\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x13, x23\n\t" - "adc x6, x6, xzr\n\t" - "adds x4, x4, x7\n\t" - "# A[5] * B[4]\n\t" - "mul x7, x14, x22\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x14, x22\n\t" - "adc x6, x6, xzr\n\t" - "adds x4, x4, x7\n\t" - "# A[6] * B[3]\n\t" - "mul x7, x15, x21\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x15, x21\n\t" - "adc x6, x6, xzr\n\t" - "adds x4, x4, x7\n\t" - "# A[7] * B[2]\n\t" - "mul x7, x16, x20\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x16, x20\n\t" - "adc x6, x6, xzr\n\t" - "adds x4, x4, x7\n\t" - "adcs x5, x5, x8\n\t" - "str x4, [%[r], 72]\n\t" - "adc x6, x6, xzr\n\t" - "# A[3] * B[7]\n\t" - "mul x7, x12, x25\n\t" - "umulh x8, x12, x25\n\t" - "adds x5, x5, x7\n\t" - "# A[4] * B[6]\n\t" - "mul x7, x13, x24\n\t" - "adcs x6, x6, x8\n\t" - "umulh x8, x13, x24\n\t" - "adc x4, xzr, xzr\n\t" - "adds x5, x5, x7\n\t" - "# A[5] * B[5]\n\t" - "mul x7, x14, x23\n\t" - "adcs x6, x6, x8\n\t" - "umulh x8, x14, x23\n\t" - "adc x4, x4, xzr\n\t" - "adds x5, x5, x7\n\t" - "# A[6] * B[4]\n\t" - "mul x7, x15, x22\n\t" - "adcs x6, x6, x8\n\t" - "umulh x8, x15, x22\n\t" - "adc x4, x4, xzr\n\t" - "adds x5, x5, x7\n\t" - "# A[7] * B[3]\n\t" - "mul x7, x16, x21\n\t" - "adcs x6, x6, x8\n\t" - "umulh x8, x16, x21\n\t" - "adc x4, x4, xzr\n\t" - "adds x5, x5, x7\n\t" - "adcs x6, x6, x8\n\t" - "str x5, [%[r], 80]\n\t" - "adc x4, x4, xzr\n\t" - "# A[4] * B[7]\n\t" - "mul x7, x13, x25\n\t" - "umulh x8, x13, x25\n\t" - "adds x6, x6, x7\n\t" - "# A[5] * B[6]\n\t" - "mul x7, x14, x24\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x14, x24\n\t" + "mul x6, x11, x23\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x11, x23\n\t" "adc x5, xzr, xzr\n\t" - "adds x6, x6, x7\n\t" - "# A[6] * B[5]\n\t" - "mul x7, x15, x23\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x15, x23\n\t" + "adds x3, x3, x6\n\t" + "# A[4] * B[5]\n\t" + "mul x6, x12, x22\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x12, x22\n\t" "adc x5, x5, xzr\n\t" - "adds x6, x6, x7\n\t" - "# A[7] * B[4]\n\t" - "mul x7, x16, x22\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x16, x22\n\t" + "adds x3, x3, x6\n\t" + "# A[5] * B[4]\n\t" + "mul x6, x13, x21\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x13, x21\n\t" "adc x5, x5, xzr\n\t" - "adds x6, x6, x7\n\t" - "adcs x4, x4, x8\n\t" - "str x6, [%[r], 88]\n\t" + "adds x3, x3, x6\n\t" + "# A[6] * B[3]\n\t" + "mul x6, x14, x20\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x14, x20\n\t" "adc x5, x5, xzr\n\t" - "# A[5] * B[7]\n\t" - "mul x7, x14, x25\n\t" - "umulh x8, x14, x25\n\t" - "adds x4, x4, x7\n\t" - "# A[6] * B[6]\n\t" - "mul x7, x15, x24\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x15, x24\n\t" - "adc x6, xzr, xzr\n\t" - "adds x4, x4, x7\n\t" - "# A[7] * B[5]\n\t" - "mul x7, x16, x23\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x16, x23\n\t" - "adc x6, x6, xzr\n\t" - "adds x4, x4, x7\n\t" - "adcs x5, x5, x8\n\t" - "str x4, [%[r], 96]\n\t" - "adc x6, x6, xzr\n\t" - "# A[6] * B[7]\n\t" - "mul x7, x15, x25\n\t" - "umulh x8, x15, x25\n\t" - "adds x5, x5, x7\n\t" - "# A[7] * B[6]\n\t" - "mul x7, x16, x24\n\t" - "adcs x6, x6, x8\n\t" - "umulh x8, x16, x24\n\t" + "adds x3, x3, x6\n\t" + "# A[7] * B[2]\n\t" + "mul x6, x15, x19\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x15, x19\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" + "adcs x4, x4, x7\n\t" + "str x3, [%[r], 72]\n\t" + "adc x5, x5, xzr\n\t" + "# A[3] * B[7]\n\t" + "mul x6, x11, x24\n\t" + "umulh x7, x11, x24\n\t" + "adds x4, x4, x6\n\t" + "# A[4] * B[6]\n\t" + "mul x6, x12, x23\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x12, x23\n\t" + "adc x3, xzr, xzr\n\t" + "adds x4, x4, x6\n\t" + "# A[5] * B[5]\n\t" + "mul x6, x13, x22\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x13, x22\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" + "# A[6] * B[4]\n\t" + "mul x6, x14, x21\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x14, x21\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" + "# A[7] * B[3]\n\t" + "mul x6, x15, x20\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x15, x20\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "str x4, [%[r], 80]\n\t" + "adc x3, x3, xzr\n\t" + "# A[4] * B[7]\n\t" + "mul x6, x12, x24\n\t" + "umulh x7, x12, x24\n\t" + "adds x5, x5, x6\n\t" + "# A[5] * B[6]\n\t" + "mul x6, x13, x23\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x13, x23\n\t" "adc x4, xzr, xzr\n\t" - "adds x5, x5, x7\n\t" - "adcs x6, x6, x8\n\t" - "str x5, [%[r], 104]\n\t" + "adds x5, x5, x6\n\t" + "# A[6] * B[5]\n\t" + "mul x6, x14, x22\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x14, x22\n\t" "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" + "# A[7] * B[4]\n\t" + "mul x6, x15, x21\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x15, x21\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" + "adcs x3, x3, x7\n\t" + "str x5, [%[r], 88]\n\t" + "adc x4, x4, xzr\n\t" + "# A[5] * B[7]\n\t" + "mul x6, x13, x24\n\t" + "umulh x7, x13, x24\n\t" + "adds x3, x3, x6\n\t" + "# A[6] * B[6]\n\t" + "mul x6, x14, x23\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x14, x23\n\t" + "adc x5, xzr, xzr\n\t" + "adds x3, x3, x6\n\t" + "# A[7] * B[5]\n\t" + "mul x6, x15, x22\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x15, x22\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" + "adcs x4, x4, x7\n\t" + "str x3, [%[r], 96]\n\t" + "adc x5, x5, xzr\n\t" + "# A[6] * B[7]\n\t" + "mul x6, x14, x24\n\t" + "umulh x7, x14, x24\n\t" + "adds x4, x4, x6\n\t" + "# A[7] * B[6]\n\t" + "mul x6, x15, x23\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x15, x23\n\t" + "adc x3, xzr, xzr\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "str x4, [%[r], 104]\n\t" + "adc x3, x3, xzr\n\t" "# A[7] * B[7]\n\t" - "mul x7, x16, x25\n\t" - "umulh x8, x16, x25\n\t" - "adds x6, x6, x7\n\t" - "adc x4, x4, x8\n\t" - "stp x6, x4, [%[r], 112]\n\t" - "ldp x9, x10, [%[tmp], 0]\n\t" - "ldp x11, x12, [%[tmp], 16]\n\t" - "ldp x13, x14, [%[tmp], 32]\n\t" - "ldp x15, x16, [%[tmp], 48]\n\t" - "stp x9, x10, [%[r], 0]\n\t" - "stp x11, x12, [%[r], 16]\n\t" - "stp x13, x14, [%[r], 32]\n\t" - "stp x15, x16, [%[r], 48]\n\t" + "mul x6, x15, x24\n\t" + "umulh x7, x15, x24\n\t" + "adds x5, x5, x6\n\t" + "adc x3, x3, x7\n\t" + "stp x5, x3, [%[r], 112]\n\t" : - : [r] "r" (r), [a] "r" (a), [b] "r" (b), [tmp] "r" (tmp) - : "memory", "x4", "x5", "x6", "x7", "x8", "x9", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24", "x25" + : [r] "r" (r), [a] "r" (a), [b] "r" (b) + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24" ); } @@ -1208,7 +1203,6 @@ SP_NOINLINE static void sp_2048_sqr_16(sp_digit* r, const sp_digit* a) u += sp_2048_add_16(r + 8, r + 8, z1); u += sp_2048_add_8(r + 16, r + 16, z2); sp_2048_add_zero_8(r + 24, z2 + 8, u); - } /* Sub b from a into a. (a -= b) @@ -1629,7 +1623,6 @@ SP_NOINLINE static void sp_2048_sqr_32(sp_digit* r, const sp_digit* a) u += sp_2048_add_32(r + 16, r + 16, z1); u += sp_2048_add_16(r + 32, r + 32, z2); sp_2048_add_zero_16(r + 48, z2 + 16, u); - } #endif /* !WOLFSSL_SP_SMALL */ @@ -2033,7 +2026,7 @@ static void sp_2048_sqr_16(sp_digit* r, const sp_digit* a) } #endif /* WOLFSSL_SP_SMALL */ -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ /* Caclulate the bottom digit of -1/a mod 2^n. * @@ -2042,7 +2035,8 @@ static void sp_2048_sqr_16(sp_digit* r, const sp_digit* a) */ static void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho) { - sp_digit x, b; + sp_digit x; + sp_digit b; b = a[0]; x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ @@ -2052,7 +2046,7 @@ static void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho) x *= 2 - b * x; /* here x*a==1 mod 2**64 */ /* rho = -1/m mod b */ - *rho = -x; + *rho = (sp_digit)0 - x; } /* Mul a by digit b into r. (r = a * b) @@ -2495,7 +2489,6 @@ static sp_digit sp_2048_cond_sub_16(sp_digit* r, const sp_digit* a, const sp_dig SP_NOINLINE static void sp_2048_mont_reduce_16(sp_digit* a, const sp_digit* m, sp_digit mp) { - sp_digit ca = 0; __asm__ __volatile__ ( "ldp x14, x15, [%[m], 0]\n\t" @@ -2505,6 +2498,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_16(sp_digit* a, const sp_digit* m, "ldp x23, x24, [%[m], 64]\n\t" "ldp x25, x26, [%[m], 80]\n\t" "ldp x27, x28, [%[m], 96]\n\t" + "mov x3, xzr\n\t" "# i = 16\n\t" "mov x4, 16\n\t" "ldp x12, x13, [%[a], 0]\n\t" @@ -2645,25 +2639,78 @@ SP_NOINLINE static void sp_2048_mont_reduce_16(sp_digit* a, const sp_digit* m, "adc x6, x6, xzr\n\t" "umulh x8, x8, x9\n\t" "adds x6, x6, x7\n\t" - "adcs x8, x8, %[ca]\n\t" + "adcs x8, x8, x3\n\t" "str x11, [%[a], 112]\n\t" - "cset %[ca], cs\n\t" + "cset x3, cs\n\t" "adds x10, x10, x6\n\t" "ldr x11, [%[a], 128]\n\t" "str x10, [%[a], 120]\n\t" "adcs x11, x11, x8\n\t" "str x11, [%[a], 128]\n\t" - "adc %[ca], %[ca], xzr\n\t" + "adc x3, x3, xzr\n\t" "subs x4, x4, 1\n\t" "add %[a], %[a], 8\n\t" "bne 1b\n\t" - "stp x12, x13, [%[a], 0]\n\t" - : [ca] "+r" (ca), [a] "+r" (a) + "# x12 and x13 hold a[0] and a[1]\n\t" + "# Create mask\n\t" + "neg x3, x3\n\t" + "mov x9, %[a]\n\t" + "sub %[a], %[a], 128\n\t" + "# Subtract masked modulus\n\t" + "# x12 and x13 hold a[0] and a[1]\n\t" + "and x14, x14, x3\n\t" + "ldp x11, x10, [x9, 16]\n\t" + "and x15, x15, x3\n\t" + "subs x12, x12, x14\n\t" + "and x16, x16, x3\n\t" + "sbcs x13, x13, x15\n\t" + "and x17, x17, x3\n\t" + "sbcs x11, x11, x16\n\t" + "stp x12, x13, [%[a], 0]\n\t" + "sbcs x10, x10, x17\n\t" + "stp x11, x10, [%[a], 16]\n\t" + "ldp x12, x13, [x9, 32]\n\t" + "and x19, x19, x3\n\t" + "ldp x11, x10, [x9, 48]\n\t" + "and x20, x20, x3\n\t" + "sbcs x12, x12, x19\n\t" + "and x21, x21, x3\n\t" + "sbcs x13, x13, x20\n\t" + "and x22, x22, x3\n\t" + "sbcs x11, x11, x21\n\t" + "stp x12, x13, [%[a], 32]\n\t" + "sbcs x10, x10, x22\n\t" + "stp x11, x10, [%[a], 48]\n\t" + "ldp x12, x13, [x9, 64]\n\t" + "and x23, x23, x3\n\t" + "ldp x11, x10, [x9, 80]\n\t" + "and x24, x24, x3\n\t" + "sbcs x12, x12, x23\n\t" + "and x25, x25, x3\n\t" + "sbcs x13, x13, x24\n\t" + "and x26, x26, x3\n\t" + "sbcs x11, x11, x25\n\t" + "stp x12, x13, [%[a], 64]\n\t" + "sbcs x10, x10, x26\n\t" + "stp x11, x10, [%[a], 80]\n\t" + "ldp x7, x8, [%[m], 112]\n\t" + "ldp x12, x13, [x9, 96]\n\t" + "and x27, x27, x3\n\t" + "ldp x11, x10, [x9, 112]\n\t" + "and x28, x28, x3\n\t" + "sbcs x12, x12, x27\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x28\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 96]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 112]\n\t" + : [a] "+r" (a) : [m] "r" (m), [mp] "r" (mp) : "memory", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28" ); - sp_2048_cond_sub_16(a - 16, a, m, (sp_digit)0 - ca); } /* Multiply two Montogmery form numbers mod the modulus (prime). @@ -2675,8 +2722,8 @@ SP_NOINLINE static void sp_2048_mont_reduce_16(sp_digit* a, const sp_digit* m, * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_mul_16(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_2048_mont_mul_16(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_2048_mul_16(r, a, b); sp_2048_mont_reduce_16(r, m, mp); @@ -2689,8 +2736,8 @@ static void sp_2048_mont_mul_16(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_sqr_16(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_2048_mont_sqr_16(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_2048_sqr_16(r, a); sp_2048_mont_reduce_16(r, m, mp); @@ -3166,7 +3213,8 @@ static int sp_2048_mod_exp_16(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -3232,34 +3280,34 @@ static int sp_2048_mod_exp_16(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 16); for (; i>=0 || c>=4; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 60); + y = (byte)(n >> 60); n <<= 4; c = 60; } else if (c < 4) { - y = (int)(n >> 60); + y = (byte)(n >> 60); n = e[i--]; c = 4 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)((n >> 60) & 0xf); + y = (byte)((n >> 60) & 0xf); n <<= 4; c -= 4; } @@ -3311,7 +3359,8 @@ static int sp_2048_mod_exp_16(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -3393,34 +3442,34 @@ static int sp_2048_mod_exp_16(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 16); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 59); + y = (byte)(n >> 59); n <<= 5; c = 59; } else if (c < 5) { - y = (int)(n >> 59); + y = (byte)(n >> 59); n = e[i--]; c = 5 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)((n >> 59) & 0x1f); + y = (byte)((n >> 59) & 0x1f); n <<= 5; c -= 5; } @@ -3451,7 +3500,7 @@ static int sp_2048_mod_exp_16(sp_digit* r, const sp_digit* a, const sp_digit* e, } #endif /* WOLFSSL_SP_SMALL */ -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) /* r = 2^n mod m where n is the number of bits to reduce by. @@ -3468,7 +3517,7 @@ static void sp_2048_mont_norm_32(sp_digit* r, const sp_digit* m) sp_2048_sub_in_place_32(r, m); } -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */ /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -3636,7 +3685,6 @@ static sp_digit sp_2048_cond_sub_32(sp_digit* r, const sp_digit* a, const sp_dig SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, sp_digit mp) { - sp_digit ca = 0; __asm__ __volatile__ ( "ldp x14, x15, [%[m], 0]\n\t" @@ -3646,6 +3694,7 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "ldp x23, x24, [%[m], 64]\n\t" "ldp x25, x26, [%[m], 80]\n\t" "ldp x27, x28, [%[m], 96]\n\t" + "mov x3, xzr\n\t" "# i = 32\n\t" "mov x4, 32\n\t" "ldp x12, x13, [%[a], 0]\n\t" @@ -3946,25 +3995,134 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, "adc x6, x6, xzr\n\t" "umulh x8, x8, x9\n\t" "adds x6, x6, x7\n\t" - "adcs x8, x8, %[ca]\n\t" + "adcs x8, x8, x3\n\t" "str x11, [%[a], 240]\n\t" - "cset %[ca], cs\n\t" + "cset x3, cs\n\t" "adds x10, x10, x6\n\t" "ldr x11, [%[a], 256]\n\t" "str x10, [%[a], 248]\n\t" "adcs x11, x11, x8\n\t" "str x11, [%[a], 256]\n\t" - "adc %[ca], %[ca], xzr\n\t" + "adc x3, x3, xzr\n\t" "subs x4, x4, 1\n\t" "add %[a], %[a], 8\n\t" "bne 1b\n\t" - "stp x12, x13, [%[a], 0]\n\t" - : [ca] "+r" (ca), [a] "+r" (a) + "# x12 and x13 hold a[0] and a[1]\n\t" + "# Create mask\n\t" + "neg x3, x3\n\t" + "mov x9, %[a]\n\t" + "sub %[a], %[a], 256\n\t" + "# Subtract masked modulus\n\t" + "# x12 and x13 hold a[0] and a[1]\n\t" + "and x14, x14, x3\n\t" + "ldp x11, x10, [x9, 16]\n\t" + "and x15, x15, x3\n\t" + "subs x12, x12, x14\n\t" + "and x16, x16, x3\n\t" + "sbcs x13, x13, x15\n\t" + "and x17, x17, x3\n\t" + "sbcs x11, x11, x16\n\t" + "stp x12, x13, [%[a], 0]\n\t" + "sbcs x10, x10, x17\n\t" + "stp x11, x10, [%[a], 16]\n\t" + "ldp x12, x13, [x9, 32]\n\t" + "and x19, x19, x3\n\t" + "ldp x11, x10, [x9, 48]\n\t" + "and x20, x20, x3\n\t" + "sbcs x12, x12, x19\n\t" + "and x21, x21, x3\n\t" + "sbcs x13, x13, x20\n\t" + "and x22, x22, x3\n\t" + "sbcs x11, x11, x21\n\t" + "stp x12, x13, [%[a], 32]\n\t" + "sbcs x10, x10, x22\n\t" + "stp x11, x10, [%[a], 48]\n\t" + "ldp x12, x13, [x9, 64]\n\t" + "and x23, x23, x3\n\t" + "ldp x11, x10, [x9, 80]\n\t" + "and x24, x24, x3\n\t" + "sbcs x12, x12, x23\n\t" + "and x25, x25, x3\n\t" + "sbcs x13, x13, x24\n\t" + "and x26, x26, x3\n\t" + "sbcs x11, x11, x25\n\t" + "stp x12, x13, [%[a], 64]\n\t" + "sbcs x10, x10, x26\n\t" + "stp x11, x10, [%[a], 80]\n\t" + "ldp x7, x8, [%[m], 112]\n\t" + "ldp x12, x13, [x9, 96]\n\t" + "and x27, x27, x3\n\t" + "ldp x11, x10, [x9, 112]\n\t" + "and x28, x28, x3\n\t" + "sbcs x12, x12, x27\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x28\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 96]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 112]\n\t" + "ldp x5, x6, [%[m], 128]\n\t" + "ldp x7, x8, [%[m], 144]\n\t" + "ldp x12, x13, [x9, 128]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 144]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 128]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 144]\n\t" + "ldp x5, x6, [%[m], 160]\n\t" + "ldp x7, x8, [%[m], 176]\n\t" + "ldp x12, x13, [x9, 160]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 176]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 160]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 176]\n\t" + "ldp x5, x6, [%[m], 192]\n\t" + "ldp x7, x8, [%[m], 208]\n\t" + "ldp x12, x13, [x9, 192]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 208]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 192]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 208]\n\t" + "ldp x5, x6, [%[m], 224]\n\t" + "ldp x7, x8, [%[m], 240]\n\t" + "ldp x12, x13, [x9, 224]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 240]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 224]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 240]\n\t" + : [a] "+r" (a) : [m] "r" (m), [mp] "r" (mp) : "memory", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28" ); - sp_2048_cond_sub_32(a - 32, a, m, (sp_digit)0 - ca); } /* Multiply two Montogmery form numbers mod the modulus (prime). @@ -3976,8 +4134,8 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_2048_mont_mul_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_2048_mul_32(r, a, b); sp_2048_mont_reduce_32(r, m, mp); @@ -3990,8 +4148,8 @@ static void sp_2048_mont_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_sqr_32(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_2048_mont_sqr_32(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_2048_sqr_32(r, a); sp_2048_mont_reduce_32(r, m, mp); @@ -4631,7 +4789,8 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -4697,34 +4856,34 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 32); for (; i>=0 || c>=4; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 60); + y = (byte)(n >> 60); n <<= 4; c = 60; } else if (c < 4) { - y = (int)(n >> 60); + y = (byte)(n >> 60); n = e[i--]; c = 4 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)((n >> 60) & 0xf); + y = (byte)((n >> 60) & 0xf); n <<= 4; c -= 4; } @@ -4776,7 +4935,8 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -4858,34 +5018,34 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 32); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 59); + y = (byte)(n >> 59); n <<= 5; c = 59; } else if (c < 5) { - y = (int)(n >> 59); + y = (byte)(n >> 59); n = e[i--]; c = 5 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)((n >> 59) & 0x1f); + y = (byte)((n >> 59) & 0x1f); n <<= 5; c -= 5; } @@ -4930,11 +5090,13 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPublic_2048(const byte* in, word32 inLen, const mp_int* em, + const mp_int* mm, byte* out, word32* outLen) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_digit a[64], m[32], r[64]; + sp_digit a[64]; + sp_digit m[32]; + sp_digit r[64]; #else sp_digit* d = NULL; sp_digit* a = NULL; @@ -5173,9 +5335,9 @@ static sp_digit sp_2048_cond_add_16(sp_digit* r, const sp_digit* a, const sp_dig * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_2048(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM) sp_digit* a = NULL; @@ -5239,8 +5401,11 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, #else #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit a[32 * 2]; - sp_digit p[16], q[16], dp[16]; - sp_digit tmpa[32], tmpb[32]; + sp_digit p[16]; + sp_digit q[16]; + sp_digit dp[16]; + sp_digit tmpa[32]; + sp_digit tmpb[32]; #else sp_digit* t = NULL; sp_digit* a = NULL; @@ -5337,7 +5502,7 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, XMEMSET(q, 0, sizeof(q)); XMEMSET(dp, 0, sizeof(dp)); #endif -#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */ +#endif /* SP_RSA_PRIVATE_EXP_D | RSA_LOW_MEM */ return err; } #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -5360,17 +5525,19 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->used = 32; mp_clamp(r); #elif DIGIT_BIT < 64 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 32; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 64) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -5383,14 +5550,16 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 32; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 64 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -5417,10 +5586,13 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_2048(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[64], e[32], m[32]; + sp_digit b[64]; + sp_digit e[32]; + sp_digit m[32]; sp_digit* r = b; int expBits = mp_count_bits(exp); @@ -5680,10 +5852,12 @@ static int sp_2048_mod_exp_2_32(sp_digit* r, const sp_digit* e, int bits, sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -5718,34 +5892,34 @@ static int sp_2048_mod_exp_2_32(sp_digit* r, const sp_digit* e, int bits, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } - sp_2048_lshift_32(r, norm, (byte)y); + sp_2048_lshift_32(r, norm, y); for (; i>=0 || c>=6; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 58); + y = (byte)(n >> 58); n <<= 6; c = 58; } else if (c < 6) { - y = (int)(n >> 58); + y = (byte)(n >> 58); n = e[i--]; c = 6 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)((n >> 58) & 0x3f); + y = (byte)((n >> 58) & 0x3f); n <<= 6; c -= 6; } @@ -5757,7 +5931,7 @@ static int sp_2048_mod_exp_2_32(sp_digit* r, const sp_digit* e, int bits, sp_2048_mont_sqr_32(r, r, m, mp); sp_2048_mont_sqr_32(r, r, m, mp); - sp_2048_lshift_32(r, r, (byte)y); + sp_2048_lshift_32(r, r, y); sp_2048_mul_d_32(tmp, norm, r[32]); r[32] = 0; o = sp_2048_add_32(r, r, tmp); @@ -5793,11 +5967,13 @@ static int sp_2048_mod_exp_2_32(sp_digit* r, const sp_digit* e, int bits, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, - mp_int* mod, byte* out, word32* outLen) +int sp_DhExp_2048(const mp_int* base, const byte* exp, word32 expLen, + const mp_int* mod, byte* out, word32* outLen) { int err = MP_OKAY; - sp_digit b[64], e[32], m[32]; + sp_digit b[64]; + sp_digit e[32]; + sp_digit m[32]; sp_digit* r = b; word32 i; @@ -5832,6 +6008,7 @@ int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, sp_2048_to_bin(r, out); *outLen = 256; for (i=0; i<256 && out[i] == 0; i++) { + /* Search for first non-zero. */ } *outLen -= i; XMEMMOVE(out, out + i, *outLen); @@ -5853,10 +6030,13 @@ int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_1024(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[32], e[16], m[16]; + sp_digit b[32]; + sp_digit e[16]; + sp_digit m[16]; sp_digit* r = b; int expBits = mp_count_bits(exp); @@ -5893,7 +6073,7 @@ int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) return err; } -#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */ +#endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */ #endif /* !WOLFSSL_SP_NO_2048 */ @@ -5907,7 +6087,8 @@ int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) */ static void sp_3072_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j; + int i; + int j; byte* d; for (i = n - 1,j = 0; i >= 7; i -= 8) { @@ -5960,7 +6141,8 @@ static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 64 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -5994,7 +6176,9 @@ static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -6033,7 +6217,8 @@ static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a) */ static void sp_3072_to_bin(sp_digit* r, byte* a) { - int i, j; + int i; + int j; for (i = 47, j = 0; i >= 0; i--) { a[j++] = r[i] >> 56; @@ -8130,7 +8315,6 @@ SP_NOINLINE static void sp_3072_sqr_24(sp_digit* r, const sp_digit* a) u += sp_3072_add_24(r + 12, r + 12, z1); u += sp_3072_add_12(r + 24, r + 24, z2); sp_3072_add_zero_12(r + 36, z2 + 12, u); - } /* Sub b from a into a. (a -= b) @@ -8665,7 +8849,6 @@ SP_NOINLINE static void sp_3072_sqr_48(sp_digit* r, const sp_digit* a) u += sp_3072_add_48(r + 24, r + 24, z1); u += sp_3072_add_24(r + 48, r + 48, z2); sp_3072_add_zero_24(r + 72, z2 + 24, u); - } #endif /* !WOLFSSL_SP_SMALL */ @@ -9069,7 +9252,7 @@ static void sp_3072_sqr_24(sp_digit* r, const sp_digit* a) } #endif /* WOLFSSL_SP_SMALL */ -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ /* Caclulate the bottom digit of -1/a mod 2^n. * @@ -9078,7 +9261,8 @@ static void sp_3072_sqr_24(sp_digit* r, const sp_digit* a) */ static void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho) { - sp_digit x, b; + sp_digit x; + sp_digit b; b = a[0]; x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ @@ -9088,7 +9272,7 @@ static void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho) x *= 2 - b * x; /* here x*a==1 mod 2**64 */ /* rho = -1/m mod b */ - *rho = -x; + *rho = (sp_digit)0 - x; } /* Mul a by digit b into r. (r = a * b) @@ -9695,7 +9879,6 @@ static sp_digit sp_3072_cond_sub_24(sp_digit* r, const sp_digit* a, const sp_dig SP_NOINLINE static void sp_3072_mont_reduce_24(sp_digit* a, const sp_digit* m, sp_digit mp) { - sp_digit ca = 0; __asm__ __volatile__ ( "ldp x14, x15, [%[m], 0]\n\t" @@ -9705,6 +9888,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_24(sp_digit* a, const sp_digit* m, "ldp x23, x24, [%[m], 64]\n\t" "ldp x25, x26, [%[m], 80]\n\t" "ldp x27, x28, [%[m], 96]\n\t" + "mov x3, xzr\n\t" "# i = 24\n\t" "mov x4, 24\n\t" "ldp x12, x13, [%[a], 0]\n\t" @@ -9925,25 +10109,106 @@ SP_NOINLINE static void sp_3072_mont_reduce_24(sp_digit* a, const sp_digit* m, "adc x6, x6, xzr\n\t" "umulh x8, x8, x9\n\t" "adds x6, x6, x7\n\t" - "adcs x8, x8, %[ca]\n\t" + "adcs x8, x8, x3\n\t" "str x11, [%[a], 176]\n\t" - "cset %[ca], cs\n\t" + "cset x3, cs\n\t" "adds x10, x10, x6\n\t" "ldr x11, [%[a], 192]\n\t" "str x10, [%[a], 184]\n\t" "adcs x11, x11, x8\n\t" "str x11, [%[a], 192]\n\t" - "adc %[ca], %[ca], xzr\n\t" + "adc x3, x3, xzr\n\t" "subs x4, x4, 1\n\t" "add %[a], %[a], 8\n\t" "bne 1b\n\t" - "stp x12, x13, [%[a], 0]\n\t" - : [ca] "+r" (ca), [a] "+r" (a) + "# x12 and x13 hold a[0] and a[1]\n\t" + "# Create mask\n\t" + "neg x3, x3\n\t" + "mov x9, %[a]\n\t" + "sub %[a], %[a], 192\n\t" + "# Subtract masked modulus\n\t" + "# x12 and x13 hold a[0] and a[1]\n\t" + "and x14, x14, x3\n\t" + "ldp x11, x10, [x9, 16]\n\t" + "and x15, x15, x3\n\t" + "subs x12, x12, x14\n\t" + "and x16, x16, x3\n\t" + "sbcs x13, x13, x15\n\t" + "and x17, x17, x3\n\t" + "sbcs x11, x11, x16\n\t" + "stp x12, x13, [%[a], 0]\n\t" + "sbcs x10, x10, x17\n\t" + "stp x11, x10, [%[a], 16]\n\t" + "ldp x12, x13, [x9, 32]\n\t" + "and x19, x19, x3\n\t" + "ldp x11, x10, [x9, 48]\n\t" + "and x20, x20, x3\n\t" + "sbcs x12, x12, x19\n\t" + "and x21, x21, x3\n\t" + "sbcs x13, x13, x20\n\t" + "and x22, x22, x3\n\t" + "sbcs x11, x11, x21\n\t" + "stp x12, x13, [%[a], 32]\n\t" + "sbcs x10, x10, x22\n\t" + "stp x11, x10, [%[a], 48]\n\t" + "ldp x12, x13, [x9, 64]\n\t" + "and x23, x23, x3\n\t" + "ldp x11, x10, [x9, 80]\n\t" + "and x24, x24, x3\n\t" + "sbcs x12, x12, x23\n\t" + "and x25, x25, x3\n\t" + "sbcs x13, x13, x24\n\t" + "and x26, x26, x3\n\t" + "sbcs x11, x11, x25\n\t" + "stp x12, x13, [%[a], 64]\n\t" + "sbcs x10, x10, x26\n\t" + "stp x11, x10, [%[a], 80]\n\t" + "ldp x7, x8, [%[m], 112]\n\t" + "ldp x12, x13, [x9, 96]\n\t" + "and x27, x27, x3\n\t" + "ldp x11, x10, [x9, 112]\n\t" + "and x28, x28, x3\n\t" + "sbcs x12, x12, x27\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x28\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 96]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 112]\n\t" + "ldp x5, x6, [%[m], 128]\n\t" + "ldp x7, x8, [%[m], 144]\n\t" + "ldp x12, x13, [x9, 128]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 144]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 128]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 144]\n\t" + "ldp x5, x6, [%[m], 160]\n\t" + "ldp x7, x8, [%[m], 176]\n\t" + "ldp x12, x13, [x9, 160]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 176]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 160]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 176]\n\t" + : [a] "+r" (a) : [m] "r" (m), [mp] "r" (mp) : "memory", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28" ); - sp_3072_cond_sub_24(a - 24, a, m, (sp_digit)0 - ca); } /* Multiply two Montogmery form numbers mod the modulus (prime). @@ -9955,8 +10220,8 @@ SP_NOINLINE static void sp_3072_mont_reduce_24(sp_digit* a, const sp_digit* m, * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_mul_24(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_3072_mont_mul_24(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_3072_mul_24(r, a, b); sp_3072_mont_reduce_24(r, m, mp); @@ -9969,8 +10234,8 @@ static void sp_3072_mont_mul_24(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_sqr_24(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_3072_mont_sqr_24(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_3072_sqr_24(r, a); sp_3072_mont_reduce_24(r, m, mp); @@ -10570,7 +10835,8 @@ static int sp_3072_mod_exp_24(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -10636,34 +10902,34 @@ static int sp_3072_mod_exp_24(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 24); for (; i>=0 || c>=4; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 60); + y = (byte)(n >> 60); n <<= 4; c = 60; } else if (c < 4) { - y = (int)(n >> 60); + y = (byte)(n >> 60); n = e[i--]; c = 4 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)((n >> 60) & 0xf); + y = (byte)((n >> 60) & 0xf); n <<= 4; c -= 4; } @@ -10715,7 +10981,8 @@ static int sp_3072_mod_exp_24(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -10797,34 +11064,34 @@ static int sp_3072_mod_exp_24(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 24); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 59); + y = (byte)(n >> 59); n <<= 5; c = 59; } else if (c < 5) { - y = (int)(n >> 59); + y = (byte)(n >> 59); n = e[i--]; c = 5 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)((n >> 59) & 0x1f); + y = (byte)((n >> 59) & 0x1f); n <<= 5; c -= 5; } @@ -10855,7 +11122,7 @@ static int sp_3072_mod_exp_24(sp_digit* r, const sp_digit* a, const sp_digit* e, } #endif /* WOLFSSL_SP_SMALL */ -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) /* r = 2^n mod m where n is the number of bits to reduce by. @@ -10872,7 +11139,7 @@ static void sp_3072_mont_norm_48(sp_digit* r, const sp_digit* m) sp_3072_sub_in_place_48(r, m); } -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */ /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -11096,7 +11363,6 @@ static sp_digit sp_3072_cond_sub_48(sp_digit* r, const sp_digit* a, const sp_dig SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, sp_digit mp) { - sp_digit ca = 0; __asm__ __volatile__ ( "ldp x14, x15, [%[m], 0]\n\t" @@ -11106,6 +11372,7 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "ldp x23, x24, [%[m], 64]\n\t" "ldp x25, x26, [%[m], 80]\n\t" "ldp x27, x28, [%[m], 96]\n\t" + "mov x3, xzr\n\t" "# i = 48\n\t" "mov x4, 48\n\t" "ldp x12, x13, [%[a], 0]\n\t" @@ -11566,25 +11833,190 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, "adc x6, x6, xzr\n\t" "umulh x8, x8, x9\n\t" "adds x6, x6, x7\n\t" - "adcs x8, x8, %[ca]\n\t" + "adcs x8, x8, x3\n\t" "str x11, [%[a], 368]\n\t" - "cset %[ca], cs\n\t" + "cset x3, cs\n\t" "adds x10, x10, x6\n\t" "ldr x11, [%[a], 384]\n\t" "str x10, [%[a], 376]\n\t" "adcs x11, x11, x8\n\t" "str x11, [%[a], 384]\n\t" - "adc %[ca], %[ca], xzr\n\t" + "adc x3, x3, xzr\n\t" "subs x4, x4, 1\n\t" "add %[a], %[a], 8\n\t" "bne 1b\n\t" - "stp x12, x13, [%[a], 0]\n\t" - : [ca] "+r" (ca), [a] "+r" (a) + "# x12 and x13 hold a[0] and a[1]\n\t" + "# Create mask\n\t" + "neg x3, x3\n\t" + "mov x9, %[a]\n\t" + "sub %[a], %[a], 384\n\t" + "# Subtract masked modulus\n\t" + "# x12 and x13 hold a[0] and a[1]\n\t" + "and x14, x14, x3\n\t" + "ldp x11, x10, [x9, 16]\n\t" + "and x15, x15, x3\n\t" + "subs x12, x12, x14\n\t" + "and x16, x16, x3\n\t" + "sbcs x13, x13, x15\n\t" + "and x17, x17, x3\n\t" + "sbcs x11, x11, x16\n\t" + "stp x12, x13, [%[a], 0]\n\t" + "sbcs x10, x10, x17\n\t" + "stp x11, x10, [%[a], 16]\n\t" + "ldp x12, x13, [x9, 32]\n\t" + "and x19, x19, x3\n\t" + "ldp x11, x10, [x9, 48]\n\t" + "and x20, x20, x3\n\t" + "sbcs x12, x12, x19\n\t" + "and x21, x21, x3\n\t" + "sbcs x13, x13, x20\n\t" + "and x22, x22, x3\n\t" + "sbcs x11, x11, x21\n\t" + "stp x12, x13, [%[a], 32]\n\t" + "sbcs x10, x10, x22\n\t" + "stp x11, x10, [%[a], 48]\n\t" + "ldp x12, x13, [x9, 64]\n\t" + "and x23, x23, x3\n\t" + "ldp x11, x10, [x9, 80]\n\t" + "and x24, x24, x3\n\t" + "sbcs x12, x12, x23\n\t" + "and x25, x25, x3\n\t" + "sbcs x13, x13, x24\n\t" + "and x26, x26, x3\n\t" + "sbcs x11, x11, x25\n\t" + "stp x12, x13, [%[a], 64]\n\t" + "sbcs x10, x10, x26\n\t" + "stp x11, x10, [%[a], 80]\n\t" + "ldp x7, x8, [%[m], 112]\n\t" + "ldp x12, x13, [x9, 96]\n\t" + "and x27, x27, x3\n\t" + "ldp x11, x10, [x9, 112]\n\t" + "and x28, x28, x3\n\t" + "sbcs x12, x12, x27\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x28\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 96]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 112]\n\t" + "ldp x5, x6, [%[m], 128]\n\t" + "ldp x7, x8, [%[m], 144]\n\t" + "ldp x12, x13, [x9, 128]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 144]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 128]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 144]\n\t" + "ldp x5, x6, [%[m], 160]\n\t" + "ldp x7, x8, [%[m], 176]\n\t" + "ldp x12, x13, [x9, 160]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 176]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 160]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 176]\n\t" + "ldp x5, x6, [%[m], 192]\n\t" + "ldp x7, x8, [%[m], 208]\n\t" + "ldp x12, x13, [x9, 192]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 208]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 192]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 208]\n\t" + "ldp x5, x6, [%[m], 224]\n\t" + "ldp x7, x8, [%[m], 240]\n\t" + "ldp x12, x13, [x9, 224]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 240]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 224]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 240]\n\t" + "ldp x5, x6, [%[m], 256]\n\t" + "ldp x7, x8, [%[m], 272]\n\t" + "ldp x12, x13, [x9, 256]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 272]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 256]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 272]\n\t" + "ldp x5, x6, [%[m], 288]\n\t" + "ldp x7, x8, [%[m], 304]\n\t" + "ldp x12, x13, [x9, 288]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 304]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 288]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 304]\n\t" + "ldp x5, x6, [%[m], 320]\n\t" + "ldp x7, x8, [%[m], 336]\n\t" + "ldp x12, x13, [x9, 320]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 336]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 320]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 336]\n\t" + "ldp x5, x6, [%[m], 352]\n\t" + "ldp x7, x8, [%[m], 368]\n\t" + "ldp x12, x13, [x9, 352]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 368]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 352]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 368]\n\t" + : [a] "+r" (a) : [m] "r" (m), [mp] "r" (mp) : "memory", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28" ); - sp_3072_cond_sub_48(a - 48, a, m, (sp_digit)0 - ca); } /* Multiply two Montogmery form numbers mod the modulus (prime). @@ -11596,8 +12028,8 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_mul_48(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_3072_mont_mul_48(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_3072_mul_48(r, a, b); sp_3072_mont_reduce_48(r, m, mp); @@ -11610,8 +12042,8 @@ static void sp_3072_mont_mul_48(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_sqr_48(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_3072_mont_sqr_48(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_3072_sqr_48(r, a); sp_3072_mont_reduce_48(r, m, mp); @@ -12403,7 +12835,8 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -12469,34 +12902,34 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 48); for (; i>=0 || c>=4; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 60); + y = (byte)(n >> 60); n <<= 4; c = 60; } else if (c < 4) { - y = (int)(n >> 60); + y = (byte)(n >> 60); n = e[i--]; c = 4 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)((n >> 60) & 0xf); + y = (byte)((n >> 60) & 0xf); n <<= 4; c -= 4; } @@ -12548,7 +12981,8 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -12630,34 +13064,34 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 48); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 59); + y = (byte)(n >> 59); n <<= 5; c = 59; } else if (c < 5) { - y = (int)(n >> 59); + y = (byte)(n >> 59); n = e[i--]; c = 5 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)((n >> 59) & 0x1f); + y = (byte)((n >> 59) & 0x1f); n <<= 5; c -= 5; } @@ -12702,11 +13136,13 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPublic_3072(const byte* in, word32 inLen, const mp_int* em, + const mp_int* mm, byte* out, word32* outLen) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_digit a[96], m[48], r[96]; + sp_digit a[96]; + sp_digit m[48]; + sp_digit r[96]; #else sp_digit* d = NULL; sp_digit* a = NULL; @@ -12973,9 +13409,9 @@ static sp_digit sp_3072_cond_add_24(sp_digit* r, const sp_digit* a, const sp_dig * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_3072(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM) sp_digit* a = NULL; @@ -13039,8 +13475,11 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, #else #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit a[48 * 2]; - sp_digit p[24], q[24], dp[24]; - sp_digit tmpa[48], tmpb[48]; + sp_digit p[24]; + sp_digit q[24]; + sp_digit dp[24]; + sp_digit tmpa[48]; + sp_digit tmpb[48]; #else sp_digit* t = NULL; sp_digit* a = NULL; @@ -13137,7 +13576,7 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, XMEMSET(q, 0, sizeof(q)); XMEMSET(dp, 0, sizeof(dp)); #endif -#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */ +#endif /* SP_RSA_PRIVATE_EXP_D | RSA_LOW_MEM */ return err; } #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -13160,17 +13599,19 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->used = 48; mp_clamp(r); #elif DIGIT_BIT < 64 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 48; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 64) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -13183,14 +13624,16 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 48; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 64 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -13217,10 +13660,13 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_3072(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[96], e[48], m[48]; + sp_digit b[96]; + sp_digit e[48]; + sp_digit m[48]; sp_digit* r = b; int expBits = mp_count_bits(exp); @@ -13576,10 +14022,12 @@ static int sp_3072_mod_exp_2_48(sp_digit* r, const sp_digit* e, int bits, sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -13614,34 +14062,34 @@ static int sp_3072_mod_exp_2_48(sp_digit* r, const sp_digit* e, int bits, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } - sp_3072_lshift_48(r, norm, (byte)y); + sp_3072_lshift_48(r, norm, y); for (; i>=0 || c>=6; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 58); + y = (byte)(n >> 58); n <<= 6; c = 58; } else if (c < 6) { - y = (int)(n >> 58); + y = (byte)(n >> 58); n = e[i--]; c = 6 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)((n >> 58) & 0x3f); + y = (byte)((n >> 58) & 0x3f); n <<= 6; c -= 6; } @@ -13653,7 +14101,7 @@ static int sp_3072_mod_exp_2_48(sp_digit* r, const sp_digit* e, int bits, sp_3072_mont_sqr_48(r, r, m, mp); sp_3072_mont_sqr_48(r, r, m, mp); - sp_3072_lshift_48(r, r, (byte)y); + sp_3072_lshift_48(r, r, y); sp_3072_mul_d_48(tmp, norm, r[48]); r[48] = 0; o = sp_3072_add_48(r, r, tmp); @@ -13689,11 +14137,13 @@ static int sp_3072_mod_exp_2_48(sp_digit* r, const sp_digit* e, int bits, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, - mp_int* mod, byte* out, word32* outLen) +int sp_DhExp_3072(const mp_int* base, const byte* exp, word32 expLen, + const mp_int* mod, byte* out, word32* outLen) { int err = MP_OKAY; - sp_digit b[96], e[48], m[48]; + sp_digit b[96]; + sp_digit e[48]; + sp_digit m[48]; sp_digit* r = b; word32 i; @@ -13728,6 +14178,7 @@ int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, sp_3072_to_bin(r, out); *outLen = 384; for (i=0; i<384 && out[i] == 0; i++) { + /* Search for first non-zero. */ } *outLen -= i; XMEMMOVE(out, out + i, *outLen); @@ -13749,10 +14200,13 @@ int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_1536(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[48], e[24], m[24]; + sp_digit b[48]; + sp_digit e[24]; + sp_digit m[24]; sp_digit* r = b; int expBits = mp_count_bits(exp); @@ -13789,7 +14243,7 @@ int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) return err; } -#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */ +#endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */ #endif /* !WOLFSSL_SP_NO_3072 */ @@ -13803,7 +14257,8 @@ int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) */ static void sp_4096_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j; + int i; + int j; byte* d; for (i = n - 1,j = 0; i >= 7; i -= 8) { @@ -13856,7 +14311,8 @@ static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 64 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -13890,7 +14346,9 @@ static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -13929,7 +14387,8 @@ static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a) */ static void sp_4096_to_bin(sp_digit* r, byte* a) { - int i, j; + int i; + int j; for (i = 63, j = 0; i >= 0; i--) { a[j++] = r[i] >> 56; @@ -14659,7 +15118,6 @@ SP_NOINLINE static void sp_4096_sqr_64(sp_digit* r, const sp_digit* a) u += sp_4096_add_64(r + 32, r + 32, z1); u += sp_4096_add_32(r + 64, r + 64, z2); sp_4096_add_zero_32(r + 96, z2 + 32, u); - } #endif /* !WOLFSSL_SP_SMALL */ @@ -14861,7 +15319,8 @@ static void sp_4096_sqr_64(sp_digit* r, const sp_digit* a) */ static void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho) { - sp_digit x, b; + sp_digit x; + sp_digit b; b = a[0]; x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ @@ -14871,7 +15330,7 @@ static void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho) x *= 2 - b * x; /* here x*a==1 mod 2**64 */ /* rho = -1/m mod b */ - *rho = -x; + *rho = (sp_digit)0 - x; } /* Mul a by digit b into r. (r = a * b) @@ -15475,7 +15934,7 @@ static void sp_4096_mont_norm_64(sp_digit* r, const sp_digit* m) sp_4096_sub_in_place_64(r, m); } -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */ /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -15755,7 +16214,6 @@ static sp_digit sp_4096_cond_sub_64(sp_digit* r, const sp_digit* a, const sp_dig SP_NOINLINE static void sp_4096_mont_reduce_64(sp_digit* a, const sp_digit* m, sp_digit mp) { - sp_digit ca = 0; __asm__ __volatile__ ( "ldp x14, x15, [%[m], 0]\n\t" @@ -15765,6 +16223,7 @@ SP_NOINLINE static void sp_4096_mont_reduce_64(sp_digit* a, const sp_digit* m, "ldp x23, x24, [%[m], 64]\n\t" "ldp x25, x26, [%[m], 80]\n\t" "ldp x27, x28, [%[m], 96]\n\t" + "mov x3, xzr\n\t" "# i = 64\n\t" "mov x4, 64\n\t" "ldp x12, x13, [%[a], 0]\n\t" @@ -16385,25 +16844,246 @@ SP_NOINLINE static void sp_4096_mont_reduce_64(sp_digit* a, const sp_digit* m, "adc x6, x6, xzr\n\t" "umulh x8, x8, x9\n\t" "adds x6, x6, x7\n\t" - "adcs x8, x8, %[ca]\n\t" + "adcs x8, x8, x3\n\t" "str x11, [%[a], 496]\n\t" - "cset %[ca], cs\n\t" + "cset x3, cs\n\t" "adds x10, x10, x6\n\t" "ldr x11, [%[a], 512]\n\t" "str x10, [%[a], 504]\n\t" "adcs x11, x11, x8\n\t" "str x11, [%[a], 512]\n\t" - "adc %[ca], %[ca], xzr\n\t" + "adc x3, x3, xzr\n\t" "subs x4, x4, 1\n\t" "add %[a], %[a], 8\n\t" "bne 1b\n\t" - "stp x12, x13, [%[a], 0]\n\t" - : [ca] "+r" (ca), [a] "+r" (a) + "# x12 and x13 hold a[0] and a[1]\n\t" + "# Create mask\n\t" + "neg x3, x3\n\t" + "mov x9, %[a]\n\t" + "sub %[a], %[a], 512\n\t" + "# Subtract masked modulus\n\t" + "# x12 and x13 hold a[0] and a[1]\n\t" + "and x14, x14, x3\n\t" + "ldp x11, x10, [x9, 16]\n\t" + "and x15, x15, x3\n\t" + "subs x12, x12, x14\n\t" + "and x16, x16, x3\n\t" + "sbcs x13, x13, x15\n\t" + "and x17, x17, x3\n\t" + "sbcs x11, x11, x16\n\t" + "stp x12, x13, [%[a], 0]\n\t" + "sbcs x10, x10, x17\n\t" + "stp x11, x10, [%[a], 16]\n\t" + "ldp x12, x13, [x9, 32]\n\t" + "and x19, x19, x3\n\t" + "ldp x11, x10, [x9, 48]\n\t" + "and x20, x20, x3\n\t" + "sbcs x12, x12, x19\n\t" + "and x21, x21, x3\n\t" + "sbcs x13, x13, x20\n\t" + "and x22, x22, x3\n\t" + "sbcs x11, x11, x21\n\t" + "stp x12, x13, [%[a], 32]\n\t" + "sbcs x10, x10, x22\n\t" + "stp x11, x10, [%[a], 48]\n\t" + "ldp x12, x13, [x9, 64]\n\t" + "and x23, x23, x3\n\t" + "ldp x11, x10, [x9, 80]\n\t" + "and x24, x24, x3\n\t" + "sbcs x12, x12, x23\n\t" + "and x25, x25, x3\n\t" + "sbcs x13, x13, x24\n\t" + "and x26, x26, x3\n\t" + "sbcs x11, x11, x25\n\t" + "stp x12, x13, [%[a], 64]\n\t" + "sbcs x10, x10, x26\n\t" + "stp x11, x10, [%[a], 80]\n\t" + "ldp x7, x8, [%[m], 112]\n\t" + "ldp x12, x13, [x9, 96]\n\t" + "and x27, x27, x3\n\t" + "ldp x11, x10, [x9, 112]\n\t" + "and x28, x28, x3\n\t" + "sbcs x12, x12, x27\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x28\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 96]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 112]\n\t" + "ldp x5, x6, [%[m], 128]\n\t" + "ldp x7, x8, [%[m], 144]\n\t" + "ldp x12, x13, [x9, 128]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 144]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 128]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 144]\n\t" + "ldp x5, x6, [%[m], 160]\n\t" + "ldp x7, x8, [%[m], 176]\n\t" + "ldp x12, x13, [x9, 160]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 176]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 160]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 176]\n\t" + "ldp x5, x6, [%[m], 192]\n\t" + "ldp x7, x8, [%[m], 208]\n\t" + "ldp x12, x13, [x9, 192]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 208]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 192]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 208]\n\t" + "ldp x5, x6, [%[m], 224]\n\t" + "ldp x7, x8, [%[m], 240]\n\t" + "ldp x12, x13, [x9, 224]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 240]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 224]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 240]\n\t" + "ldp x5, x6, [%[m], 256]\n\t" + "ldp x7, x8, [%[m], 272]\n\t" + "ldp x12, x13, [x9, 256]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 272]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 256]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 272]\n\t" + "ldp x5, x6, [%[m], 288]\n\t" + "ldp x7, x8, [%[m], 304]\n\t" + "ldp x12, x13, [x9, 288]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 304]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 288]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 304]\n\t" + "ldp x5, x6, [%[m], 320]\n\t" + "ldp x7, x8, [%[m], 336]\n\t" + "ldp x12, x13, [x9, 320]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 336]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 320]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 336]\n\t" + "ldp x5, x6, [%[m], 352]\n\t" + "ldp x7, x8, [%[m], 368]\n\t" + "ldp x12, x13, [x9, 352]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 368]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 352]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 368]\n\t" + "ldp x5, x6, [%[m], 384]\n\t" + "ldp x7, x8, [%[m], 400]\n\t" + "ldp x12, x13, [x9, 384]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 400]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 384]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 400]\n\t" + "ldp x5, x6, [%[m], 416]\n\t" + "ldp x7, x8, [%[m], 432]\n\t" + "ldp x12, x13, [x9, 416]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 432]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 416]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 432]\n\t" + "ldp x5, x6, [%[m], 448]\n\t" + "ldp x7, x8, [%[m], 464]\n\t" + "ldp x12, x13, [x9, 448]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 464]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 448]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 464]\n\t" + "ldp x5, x6, [%[m], 480]\n\t" + "ldp x7, x8, [%[m], 496]\n\t" + "ldp x12, x13, [x9, 480]\n\t" + "and x5, x5, x3\n\t" + "ldp x11, x10, [x9, 496]\n\t" + "and x6, x6, x3\n\t" + "sbcs x12, x12, x5\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x6\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 480]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 496]\n\t" + : [a] "+r" (a) : [m] "r" (m), [mp] "r" (mp) : "memory", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28" ); - sp_4096_cond_sub_64(a - 64, a, m, (sp_digit)0 - ca); } /* Multiply two Montogmery form numbers mod the modulus (prime). @@ -16415,8 +17095,8 @@ SP_NOINLINE static void sp_4096_mont_reduce_64(sp_digit* a, const sp_digit* m, * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_4096_mont_mul_64(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_4096_mont_mul_64(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_4096_mul_64(r, a, b); sp_4096_mont_reduce_64(r, m, mp); @@ -16429,8 +17109,8 @@ static void sp_4096_mont_mul_64(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_4096_mont_sqr_64(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_4096_mont_sqr_64(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_4096_sqr_64(r, a); sp_4096_mont_reduce_64(r, m, mp); @@ -17374,7 +18054,8 @@ static int sp_4096_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -17440,34 +18121,34 @@ static int sp_4096_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 64); for (; i>=0 || c>=4; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 60); + y = (byte)(n >> 60); n <<= 4; c = 60; } else if (c < 4) { - y = (int)(n >> 60); + y = (byte)(n >> 60); n = e[i--]; c = 4 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)((n >> 60) & 0xf); + y = (byte)((n >> 60) & 0xf); n <<= 4; c -= 4; } @@ -17519,7 +18200,8 @@ static int sp_4096_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -17601,34 +18283,34 @@ static int sp_4096_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 64); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 59); + y = (byte)(n >> 59); n <<= 5; c = 59; } else if (c < 5) { - y = (int)(n >> 59); + y = (byte)(n >> 59); n = e[i--]; c = 5 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)((n >> 59) & 0x1f); + y = (byte)((n >> 59) & 0x1f); n <<= 5; c -= 5; } @@ -17673,11 +18355,13 @@ static int sp_4096_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPublic_4096(const byte* in, word32 inLen, const mp_int* em, + const mp_int* mm, byte* out, word32* outLen) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_digit a[128], m[64], r[128]; + sp_digit a[128]; + sp_digit m[64]; + sp_digit r[128]; #else sp_digit* d = NULL; sp_digit* a = NULL; @@ -17972,9 +18656,9 @@ static sp_digit sp_4096_cond_add_32(sp_digit* r, const sp_digit* a, const sp_dig * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_4096(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM) sp_digit* a = NULL; @@ -18038,8 +18722,11 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, #else #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit a[64 * 2]; - sp_digit p[32], q[32], dp[32]; - sp_digit tmpa[64], tmpb[64]; + sp_digit p[32]; + sp_digit q[32]; + sp_digit dp[32]; + sp_digit tmpa[64]; + sp_digit tmpb[64]; #else sp_digit* t = NULL; sp_digit* a = NULL; @@ -18136,7 +18823,7 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, XMEMSET(q, 0, sizeof(q)); XMEMSET(dp, 0, sizeof(dp)); #endif -#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */ +#endif /* SP_RSA_PRIVATE_EXP_D | RSA_LOW_MEM */ return err; } #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -18159,17 +18846,19 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->used = 64; mp_clamp(r); #elif DIGIT_BIT < 64 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 64; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 64) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -18182,14 +18871,16 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 64; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 64 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -18216,10 +18907,13 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_4096(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[128], e[64], m[64]; + sp_digit b[128]; + sp_digit e[64]; + sp_digit m[64]; sp_digit* r = b; int expBits = mp_count_bits(exp); @@ -18671,10 +19365,12 @@ static int sp_4096_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits, sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -18709,34 +19405,34 @@ static int sp_4096_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } - sp_4096_lshift_64(r, norm, (byte)y); + sp_4096_lshift_64(r, norm, y); for (; i>=0 || c>=6; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 58); + y = (byte)(n >> 58); n <<= 6; c = 58; } else if (c < 6) { - y = (int)(n >> 58); + y = (byte)(n >> 58); n = e[i--]; c = 6 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)((n >> 58) & 0x3f); + y = (byte)((n >> 58) & 0x3f); n <<= 6; c -= 6; } @@ -18748,7 +19444,7 @@ static int sp_4096_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits, sp_4096_mont_sqr_64(r, r, m, mp); sp_4096_mont_sqr_64(r, r, m, mp); - sp_4096_lshift_64(r, r, (byte)y); + sp_4096_lshift_64(r, r, y); sp_4096_mul_d_64(tmp, norm, r[64]); r[64] = 0; o = sp_4096_add_64(r, r, tmp); @@ -18784,11 +19480,13 @@ static int sp_4096_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, - mp_int* mod, byte* out, word32* outLen) +int sp_DhExp_4096(const mp_int* base, const byte* exp, word32 expLen, + const mp_int* mod, byte* out, word32* outLen) { int err = MP_OKAY; - sp_digit b[128], e[64], m[64]; + sp_digit b[128]; + sp_digit e[64]; + sp_digit m[64]; sp_digit* r = b; word32 i; @@ -18823,6 +19521,7 @@ int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, sp_4096_to_bin(r, out); *outLen = 512; for (i=0; i<512 && out[i] == 0; i++) { + /* Search for first non-zero. */ } *outLen -= i; XMEMMOVE(out, out + i, *outLen); @@ -18835,19 +19534,23 @@ int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, } #endif /* WOLFSSL_HAVE_SP_DH */ -#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */ +#endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */ #endif /* WOLFSSL_SP_4096 */ -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */ #ifdef WOLFSSL_HAVE_SP_ECC #ifndef WOLFSSL_SP_NO_256 /* Point structure to use. */ typedef struct sp_point_256 { + /* X ordinate of point. */ sp_digit x[2 * 4]; + /* Y ordinate of point. */ sp_digit y[2 * 4]; + /* Z ordinate of point. */ sp_digit z[2 * 4]; + /* Indicates point is at infinity. */ int infinity; } sp_point_256; @@ -18919,7 +19622,320 @@ static const sp_digit p256_b[4] = { }; #endif -static int sp_256_point_new_ex_4(void* heap, sp_point_256* sp, sp_point_256** p) +#ifdef WOLFSSL_SP_SMALL +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static void sp_256_mul_4(sp_digit* r, const sp_digit* a, const sp_digit* b) +{ + sp_digit tmp[8]; + + __asm__ __volatile__ ( + "mov x5, 0\n\t" + "mov x6, 0\n\t" + "mov x7, 0\n\t" + "mov x8, 0\n\t" + "\n1:\n\t" + "subs x3, x5, 24\n\t" + "csel x3, xzr, x3, cc\n\t" + "sub x4, x5, x3\n\t" + "\n2:\n\t" + "ldr x10, [%[a], x3]\n\t" + "ldr x11, [%[b], x4]\n\t" + "mul x9, x10, x11\n\t" + "umulh x10, x10, x11\n\t" + "adds x6, x6, x9\n\t" + "adcs x7, x7, x10\n\t" + "adc x8, x8, xzr\n\t" + "add x3, x3, #8\n\t" + "sub x4, x4, #8\n\t" + "cmp x3, 32\n\t" + "b.eq 3f\n\t" + "cmp x3, x5\n\t" + "b.le 2b\n\t" + "\n3:\n\t" + "str x6, [%[r], x5]\n\t" + "mov x6, x7\n\t" + "mov x7, x8\n\t" + "mov x8, #0\n\t" + "add x5, x5, #8\n\t" + "cmp x5, 48\n\t" + "b.le 1b\n\t" + "str x6, [%[r], x5]\n\t" + : + : [r] "r" (tmp), [a] "r" (a), [b] "r" (b) + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11" + ); + + XMEMCPY(r, tmp, sizeof(tmp)); +} + +#else +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static void sp_256_mul_4(sp_digit* r, const sp_digit* a, const sp_digit* b) +{ + sp_digit tmp[4]; + + __asm__ __volatile__ ( + "ldp x16, x17, [%[a], 0]\n\t" + "ldp x21, x22, [%[b], 0]\n\t" + "# A[0] * B[0]\n\t" + "mul x8, x16, x21\n\t" + "ldr x19, [%[a], 16]\n\t" + "umulh x9, x16, x21\n\t" + "ldr x23, [%[b], 16]\n\t" + "# A[0] * B[1]\n\t" + "mul x4, x16, x22\n\t" + "ldr x20, [%[a], 24]\n\t" + "umulh x5, x16, x22\n\t" + "ldr x24, [%[b], 24]\n\t" + "adds x9, x9, x4\n\t" + "# A[1] * B[0]\n\t" + "mul x4, x17, x21\n\t" + "adc x10, xzr, x5\n\t" + "umulh x5, x17, x21\n\t" + "adds x9, x9, x4\n\t" + "# A[0] * B[2]\n\t" + "mul x4, x16, x23\n\t" + "adcs x10, x10, x5\n\t" + "umulh x5, x16, x23\n\t" + "adc x11, xzr, xzr\n\t" + "adds x10, x10, x4\n\t" + "# A[1] * B[1]\n\t" + "mul x4, x17, x22\n\t" + "adc x11, x11, x5\n\t" + "umulh x5, x17, x22\n\t" + "adds x10, x10, x4\n\t" + "# A[2] * B[0]\n\t" + "mul x4, x19, x21\n\t" + "adcs x11, x11, x5\n\t" + "umulh x5, x19, x21\n\t" + "adc x12, xzr, xzr\n\t" + "adds x10, x10, x4\n\t" + "# A[0] * B[3]\n\t" + "mul x4, x16, x24\n\t" + "adcs x11, x11, x5\n\t" + "umulh x5, x16, x24\n\t" + "adc x12, x12, xzr\n\t" + "adds x11, x11, x4\n\t" + "# A[1] * B[2]\n\t" + "mul x4, x17, x23\n\t" + "adcs x12, x12, x5\n\t" + "umulh x5, x17, x23\n\t" + "adc x13, xzr, xzr\n\t" + "adds x11, x11, x4\n\t" + "# A[2] * B[1]\n\t" + "mul x4, x19, x22\n\t" + "adcs x12, x12, x5\n\t" + "umulh x5, x19, x22\n\t" + "adc x13, x13, xzr\n\t" + "adds x11, x11, x4\n\t" + "# A[3] * B[0]\n\t" + "mul x4, x20, x21\n\t" + "adcs x12, x12, x5\n\t" + "umulh x5, x20, x21\n\t" + "adc x13, x13, xzr\n\t" + "adds x11, x11, x4\n\t" + "# A[1] * B[3]\n\t" + "mul x4, x17, x24\n\t" + "adcs x12, x12, x5\n\t" + "umulh x5, x17, x24\n\t" + "adc x13, x13, xzr\n\t" + "adds x12, x12, x4\n\t" + "# A[2] * B[2]\n\t" + "mul x4, x19, x23\n\t" + "adcs x13, x13, x5\n\t" + "umulh x5, x19, x23\n\t" + "adc x14, xzr, xzr\n\t" + "adds x12, x12, x4\n\t" + "# A[3] * B[1]\n\t" + "mul x4, x20, x22\n\t" + "adcs x13, x13, x5\n\t" + "umulh x5, x20, x22\n\t" + "adc x14, x14, xzr\n\t" + "adds x12, x12, x4\n\t" + "# A[2] * B[3]\n\t" + "mul x4, x19, x24\n\t" + "adcs x13, x13, x5\n\t" + "umulh x5, x19, x24\n\t" + "adc x14, x14, xzr\n\t" + "adds x13, x13, x4\n\t" + "# A[3] * B[2]\n\t" + "mul x4, x20, x23\n\t" + "adcs x14, x14, x5\n\t" + "umulh x5, x20, x23\n\t" + "adc x15, xzr, xzr\n\t" + "adds x13, x13, x4\n\t" + "# A[3] * B[3]\n\t" + "mul x4, x20, x24\n\t" + "adcs x14, x14, x5\n\t" + "umulh x5, x20, x24\n\t" + "adc x15, x15, xzr\n\t" + "adds x14, x14, x4\n\t" + "adc x15, x15, x5\n\t" + "stp x8, x9, [%[r], 0]\n\t" + "stp x10, x11, [%[r], 16]\n\t" + "stp x12, x13, [%[r], 32]\n\t" + "stp x14, x15, [%[r], 48]\n\t" + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [tmp] "r" (tmp) + : "memory", "x4", "x5", "x6", "x7", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15" + ); +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +static void sp_256_sqr_4(sp_digit* r, const sp_digit* a) +{ + __asm__ __volatile__ ( + "ldp x16, x17, [%[a], 0]\n\t" + "# A[0] * A[1]\n\t" + "mul x9, x16, x17\n\t" + "ldr x19, [%[a], 16]\n\t" + "umulh x10, x16, x17\n\t" + "ldr x20, [%[a], 24]\n\t" + "# A[0] * A[2]\n\t" + "mul x4, x16, x19\n\t" + "umulh x5, x16, x19\n\t" + "adds x10, x10, x4\n\t" + "# A[0] * A[3]\n\t" + "mul x4, x16, x20\n\t" + "adc x11, xzr, x5\n\t" + "umulh x5, x16, x20\n\t" + "adds x11, x11, x4\n\t" + "# A[1] * A[2]\n\t" + "mul x4, x17, x19\n\t" + "adc x12, xzr, x5\n\t" + "umulh x5, x17, x19\n\t" + "adds x11, x11, x4\n\t" + "# A[1] * A[3]\n\t" + "mul x4, x17, x20\n\t" + "adcs x12, x12, x5\n\t" + "umulh x5, x17, x20\n\t" + "adc x13, xzr, xzr\n\t" + "adds x12, x12, x4\n\t" + "# A[2] * A[3]\n\t" + "mul x4, x19, x20\n\t" + "adc x13, x13, x5\n\t" + "umulh x5, x19, x20\n\t" + "adds x13, x13, x4\n\t" + "adc x14, xzr, x5\n\t" + "# Double\n\t" + "adds x9, x9, x9\n\t" + "adcs x10, x10, x10\n\t" + "adcs x11, x11, x11\n\t" + "adcs x12, x12, x12\n\t" + "adcs x13, x13, x13\n\t" + "# A[0] * A[0]\n\t" + "mul x8, x16, x16\n\t" + "adcs x14, x14, x14\n\t" + "umulh x3, x16, x16\n\t" + "cset x15, cs\n\t" + "# A[1] * A[1]\n\t" + "mul x4, x17, x17\n\t" + "adds x9, x9, x3\n\t" + "umulh x5, x17, x17\n\t" + "adcs x10, x10, x4\n\t" + "# A[2] * A[2]\n\t" + "mul x6, x19, x19\n\t" + "adcs x11, x11, x5\n\t" + "umulh x7, x19, x19\n\t" + "adcs x12, x12, x6\n\t" + "# A[3] * A[3]\n\t" + "mul x16, x20, x20\n\t" + "adcs x13, x13, x7\n\t" + "umulh x17, x20, x20\n\t" + "adcs x14, x14, x16\n\t" + "adc x15, x15, x17\n\t" + "stp x8, x9, [%[r], 0]\n\t" + "stp x10, x11, [%[r], 16]\n\t" + "stp x12, x13, [%[r], 32]\n\t" + "stp x14, x15, [%[r], 48]\n\t" + : + : [r] "r" (r), [a] "r" (a) + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20" + ); +} + +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_256_add_4(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + __asm__ __volatile__ ( + "ldp x3, x4, [%[a], 0]\n\t" + "ldp x7, x8, [%[b], 0]\n\t" + "adds x3, x3, x7\n\t" + "ldp x5, x6, [%[a], 16]\n\t" + "adcs x4, x4, x8\n\t" + "ldp x9, x10, [%[b], 16]\n\t" + "adcs x5, x5, x9\n\t" + "stp x3, x4, [%[r], 0]\n\t" + "adcs x6, x6, x10\n\t" + "stp x5, x6, [%[r], 16]\n\t" + "cset %[r], cs\n\t" + : [r] "+r" (r) + : [a] "r" (a), [b] "r" (b) + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10" + ); + + return (sp_digit)r; +} + +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_256_sub_4(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + __asm__ __volatile__ ( + "ldp x3, x4, [%[a], 0]\n\t" + "ldp x7, x8, [%[b], 0]\n\t" + "subs x3, x3, x7\n\t" + "ldp x5, x6, [%[a], 16]\n\t" + "sbcs x4, x4, x8\n\t" + "ldp x9, x10, [%[b], 16]\n\t" + "sbcs x5, x5, x9\n\t" + "stp x3, x4, [%[r], 0]\n\t" + "sbcs x6, x6, x10\n\t" + "stp x5, x6, [%[r], 16]\n\t" + "csetm %[r], cc\n\t" + : [r] "+r" (r) + : [a] "r" (a), [b] "r" (b) + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10" + ); + + return (sp_digit)r; +} + +/* Create a new point. + * + * heap [in] Buffer to allocate dynamic memory from. + * sp [in] Data for point - only if not allocating. + * p [out] New point. + * returns MEMORY_E when dynamic memory allocation fails and 0 otherwise. + */ +static int sp_256_point_new_ex_4(void* heap, sp_point_256* sp, + sp_point_256** p) { int ret = MP_OKAY; (void)heap; @@ -18944,6 +19960,12 @@ static int sp_256_point_new_ex_4(void* heap, sp_point_256* sp, sp_point_256** p) #endif +/* Free the point. + * + * p [in,out] Point to free. + * clear [in] Indicates whether to zeroize point. + * heap [in] Buffer from which dynamic memory was allocate from. + */ static void sp_256_point_free_4(sp_point_256* p, int clear, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -18956,7 +19978,7 @@ static void sp_256_point_free_4(sp_point_256* p, int clear, void* heap) } #else /* Clear point data if requested. */ - if (clear != 0) { + if ((p != NULL) && (clear != 0)) { XMEMSET(p, 0, sizeof(*p)); } #endif @@ -19047,7 +20069,8 @@ static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 64 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -19081,7 +20104,9 @@ static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -19117,7 +20142,8 @@ static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) * p Point of type sp_point_256 (result). * pm Point of type ecc_point. */ -static void sp_256_point_from_ecc_point_4(sp_point_256* p, const ecc_point* pm) +static void sp_256_point_from_ecc_point_4(sp_point_256* p, + const ecc_point* pm) { XMEMSET(p->x, 0, sizeof(p->x)); XMEMSET(p->y, 0, sizeof(p->y)); @@ -19144,17 +20170,19 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) r->used = 4; mp_clamp(r); #elif DIGIT_BIT < 64 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 4; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 64) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -19167,14 +20195,16 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 4; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 64 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -19609,7 +20639,7 @@ static void sp_256_mont_sqr_n_4(sp_digit* r, const sp_digit* a, int n, } } -#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */ +#endif /* !WOLFSSL_SP_SMALL | HAVE_COMP_KEY */ #ifdef WOLFSSL_SP_SMALL /* Mod-2 for the P256 curve. */ static const uint64_t p256_mod_minus_2[4] = { @@ -19803,35 +20833,6 @@ static sp_digit sp_256_cond_sub_4(sp_digit* r, const sp_digit* a, const sp_digit return (sp_digit)r; } -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -static sp_digit sp_256_sub_4(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - __asm__ __volatile__ ( - "ldp x3, x4, [%[a], 0]\n\t" - "ldp x7, x8, [%[b], 0]\n\t" - "subs x3, x3, x7\n\t" - "ldp x5, x6, [%[a], 16]\n\t" - "sbcs x4, x4, x8\n\t" - "ldp x9, x10, [%[b], 16]\n\t" - "sbcs x5, x5, x9\n\t" - "stp x3, x4, [%[r], 0]\n\t" - "sbcs x6, x6, x10\n\t" - "stp x5, x6, [%[r], 16]\n\t" - "csetm %[r], cc\n\t" - : [r] "+r" (r) - : [a] "r" (a), [b] "r" (b) - : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10" - ); - - return (sp_digit)r; -} - #define sp_256_mont_reduce_order_4 sp_256_mont_reduce_4 /* Reduce the number back to 256 bits using Montgomery reduction. @@ -19996,7 +20997,8 @@ SP_NOINLINE static void sp_256_mont_reduce_4(sp_digit* a, const sp_digit* m, * p Montgomery form projective coordinate point. * t Temporary ordinate data. */ -static void sp_256_map_4(sp_point_256* r, const sp_point_256* p, sp_digit* t) +static void sp_256_map_4(sp_point_256* r, const sp_point_256* p, + sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2*4; @@ -20514,7 +21516,8 @@ static void sp_256_mont_dbl_sub_4(sp_digit* r, const sp_digit* a, const sp_digit * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_4(sp_point_256* p, int n, sp_digit* t) +static void sp_256_proj_point_dbl_n_4(sp_point_256* p, int n, + sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*4; @@ -20812,8 +21815,8 @@ static int sp_256_proj_point_add_4_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r, } #endif /* WOLFSSL_SP_NONBLOCK */ -static void sp_256_proj_point_add_4(sp_point_256* r, const sp_point_256* p, const sp_point_256* q, - sp_digit* t) +static void sp_256_proj_point_add_4(sp_point_256* r, + const sp_point_256* p, const sp_point_256* q, sp_digit* t) { const sp_point_256* ap[2]; sp_point_256* rp[2]; @@ -20906,8 +21909,8 @@ static void sp_256_proj_point_add_4(sp_point_256* r, const sp_point_256* p, cons * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_store_4(sp_point_256* r, const sp_point_256* p, - int n, int m, sp_digit* t) +static void sp_256_proj_point_dbl_n_store_4(sp_point_256* r, + const sp_point_256* p, int n, int m, sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*4; @@ -20918,6 +21921,7 @@ static void sp_256_proj_point_dbl_n_store_4(sp_point_256* r, const sp_point_256* sp_digit* y = r[(1<x[i]; @@ -20934,7 +21938,10 @@ static void sp_256_proj_point_dbl_n_store_4(sp_point_256* r, const sp_point_256* /* W = Z^4 */ sp_256_mont_sqr_4(w, z, p256_mod, p256_mp_mod); sp_256_mont_sqr_4(w, w, p256_mod, p256_mp_mod); + j = m; for (i=1; i<=n; i++) { + j *= 2; + /* A = 3*(X^2 - W) */ sp_256_mont_sqr_4(t1, x, p256_mod, p256_mp_mod); sp_256_mont_sub_4(t1, t1, w, p256_mod); @@ -20942,14 +21949,14 @@ static void sp_256_proj_point_dbl_n_store_4(sp_point_256* r, const sp_point_256* /* B = X*Y^2 */ sp_256_mont_sqr_4(t2, y, p256_mod, p256_mp_mod); sp_256_mont_mul_4(b, t2, x, p256_mod, p256_mp_mod); - x = r[(1<y); + sp_256_norm_4(negy); sp_256_cond_copy_4(p->y, negy, (sp_digit)0 - v[i].neg); sp_256_proj_point_add_4(rt, rt, p, tmp); } @@ -21305,12 +22316,15 @@ static int sp_256_ecc_mulmod_win_add_sub_4(sp_point_256* r, const sp_point_256* return err; } +#ifndef WC_NO_CACHE_RESISTANT /* A table entry for pre-computed points. */ typedef struct sp_table_entry_256 { sp_digit x[4]; sp_digit y[4]; } sp_table_entry_256; +#if defined(FP_ECC) || defined(WOLFSSL_SP_SMALL) +#endif /* FP_ECC | WOLFSSL_SP_SMALL */ /* Add two Montgomery form projective points. The second point has a q value of * one. * Only the first point can be the same pointer as the result point. @@ -21416,12 +22430,11 @@ static void sp_256_proj_to_affine_4(sp_point_256* a, sp_digit* t) XMEMCPY(a->z, p256_norm_mod, sizeof(p256_norm_mod)); } -#endif /* FP_ECC */ -#ifndef WC_NO_CACHE_RESISTANT -#if defined(FP_ECC) || defined(WOLFSSL_SP_SMALL) -#endif /* FP_ECC || WOLFSSL_SP_SMALL */ -#ifdef FP_ECC /* Generate the pre-computed table of points for the base point. + * + * width = 6 + * 64 entries + * 42 bits between * * a The base point. * table Place to store generated point data. @@ -21432,12 +22445,15 @@ static int sp_256_gen_stripe_table_4(const sp_point_256* a, sp_table_entry_256* table, sp_digit* tmp, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_point_256 td, s1d, s2d; + sp_point_256 td; + sp_point_256 s1d; + sp_point_256 s2d; #endif sp_point_256* t; sp_point_256* s1 = NULL; sp_point_256* s2 = NULL; - int i, j; + int i; + int j; int err; (void)heap; @@ -21541,8 +22557,10 @@ static void sp_256_get_entry_64_4(sp_point_256* r, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Implementation uses striping of bits. - * Choose bits 6 bits apart. + * Stripe implementation. + * Pre-generated: 2^0, 2^42, ... + * Pre-generated: products of all combinations of above. + * 6 doubles and adds (with qz=1) * * r Resulting point. * k Scalar to multiply by. @@ -21564,8 +22582,10 @@ static int sp_256_ecc_mulmod_stripe_4(sp_point_256* r, const sp_point_256* g, sp_point_256* rt; sp_point_256* p = NULL; sp_digit* t; - int i, j; - int y, x; + int i; + int j; + int y; + int x; int err; (void)g; @@ -21593,8 +22613,10 @@ static int sp_256_ecc_mulmod_stripe_4(sp_point_256* r, const sp_point_256* g, XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod)); y = 0; - for (j=0,x=42; j<6 && x<256; j++,x+=43) { + x = 42; + for (j=0; j<6 && x<256; j++) { y |= (int)(((k[x / 64] >> (x % 64)) & 1) << j); + x += 43; } #ifndef WC_NO_CACHE_RESISTANT if (ct) { @@ -21608,8 +22630,10 @@ static int sp_256_ecc_mulmod_stripe_4(sp_point_256* r, const sp_point_256* g, rt->infinity = !y; for (i=41; i>=0; i--) { y = 0; - for (j=0,x=i; j<6 && x<256; j++,x+=43) { + x = i; + for (j=0; j<6 && x<256; j++) { y |= (int)(((k[x / 64] >> (x % 64)) & 1) << j); + x += 43; } sp_256_proj_point_dbl_4(rt, rt, t); @@ -21646,22 +22670,31 @@ static int sp_256_ecc_mulmod_stripe_4(sp_point_256* r, const sp_point_256* g, return err; } -#endif /* FP_ECC || WOLFSSL_SP_SMALL */ +#endif /* FP_ECC | WOLFSSL_SP_SMALL */ #ifdef FP_ECC #ifndef FP_ENTRIES #define FP_ENTRIES 16 #endif +/* Cache entry - holds precomputation tables for a point. */ typedef struct sp_cache_256_t { + /* X ordinate of point that table was generated from. */ sp_digit x[4]; + /* Y ordinate of point that table was generated from. */ sp_digit y[4]; + /* Precomputation table for point. */ sp_table_entry_256 table[64]; + /* Count of entries in table. */ uint32_t cnt; + /* Point and table set in entry. */ int set; } sp_cache_256_t; +/* Cache of tables. */ static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES]; +/* Index of last entry in cache. */ static THREAD_LS_T int sp_cache_256_last = -1; +/* Cache has been initialized. */ static THREAD_LS_T int sp_cache_256_inited = 0; #ifndef HAVE_THREAD_LS @@ -21669,9 +22702,15 @@ static THREAD_LS_T int sp_cache_256_inited = 0; static wolfSSL_Mutex sp_cache_256_lock; #endif +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache) { - int i, j; + int i; + int j; uint32_t least; if (sp_cache_256_inited == 0) { @@ -21779,9 +22818,13 @@ static int sp_256_ecc_mulmod_4(sp_point_256* r, const sp_point_256* g, const sp_ #else #if defined(FP_ECC) || defined(WOLFSSL_SP_SMALL) -#endif /* FP_ECC || WOLFSSL_SP_SMALL */ +#endif /* FP_ECC | WOLFSSL_SP_SMALL */ #ifdef FP_ECC /* Generate the pre-computed table of points for the base point. + * + * width = 8 + * 256 entries + * 32 bits between * * a The base point. * table Place to store generated point data. @@ -21792,12 +22835,15 @@ static int sp_256_gen_stripe_table_4(const sp_point_256* a, sp_table_entry_256* table, sp_digit* tmp, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_point_256 td, s1d, s2d; + sp_point_256 td; + sp_point_256 s1d; + sp_point_256 s2d; #endif sp_point_256* t; sp_point_256* s1 = NULL; sp_point_256* s2 = NULL; - int i, j; + int i; + int j; int err; (void)heap; @@ -21901,8 +22947,10 @@ static void sp_256_get_entry_256_4(sp_point_256* r, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Implementation uses striping of bits. - * Choose bits 8 bits apart. + * Stripe implementation. + * Pre-generated: 2^0, 2^32, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) * * r Resulting point. * k Scalar to multiply by. @@ -21924,8 +22972,10 @@ static int sp_256_ecc_mulmod_stripe_4(sp_point_256* r, const sp_point_256* g, sp_point_256* rt; sp_point_256* p = NULL; sp_digit* t; - int i, j; - int y, x; + int i; + int j; + int y; + int x; int err; (void)g; @@ -21953,8 +23003,10 @@ static int sp_256_ecc_mulmod_stripe_4(sp_point_256* r, const sp_point_256* g, XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod)); y = 0; - for (j=0,x=31; j<8; j++,x+=32) { + x = 31; + for (j=0; j<8; j++) { y |= (int)(((k[x / 64] >> (x % 64)) & 1) << j); + x += 32; } #ifndef WC_NO_CACHE_RESISTANT if (ct) { @@ -21968,8 +23020,10 @@ static int sp_256_ecc_mulmod_stripe_4(sp_point_256* r, const sp_point_256* g, rt->infinity = !y; for (i=30; i>=0; i--) { y = 0; - for (j=0,x=i; j<8; j++,x+=32) { + x = i; + for (j=0; j<8; j++) { y |= (int)(((k[x / 64] >> (x % 64)) & 1) << j); + x += 32; } sp_256_proj_point_dbl_4(rt, rt, t); @@ -22006,22 +23060,31 @@ static int sp_256_ecc_mulmod_stripe_4(sp_point_256* r, const sp_point_256* g, return err; } -#endif /* FP_ECC || WOLFSSL_SP_SMALL */ +#endif /* FP_ECC | WOLFSSL_SP_SMALL */ #ifdef FP_ECC #ifndef FP_ENTRIES #define FP_ENTRIES 16 #endif +/* Cache entry - holds precomputation tables for a point. */ typedef struct sp_cache_256_t { + /* X ordinate of point that table was generated from. */ sp_digit x[4]; + /* Y ordinate of point that table was generated from. */ sp_digit y[4]; + /* Precomputation table for point. */ sp_table_entry_256 table[256]; + /* Count of entries in table. */ uint32_t cnt; + /* Point and table set in entry. */ int set; } sp_cache_256_t; +/* Cache of tables. */ static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES]; +/* Index of last entry in cache. */ static THREAD_LS_T int sp_cache_256_last = -1; +/* Cache has been initialized. */ static THREAD_LS_T int sp_cache_256_inited = 0; #ifndef HAVE_THREAD_LS @@ -22029,9 +23092,15 @@ static THREAD_LS_T int sp_cache_256_inited = 0; static wolfSSL_Mutex sp_cache_256_lock; #endif +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache) { - int i, j; + int i; + int j; uint32_t least; if (sp_cache_256_inited == 0) { @@ -22148,8 +23217,8 @@ static int sp_256_ecc_mulmod_4(sp_point_256* r, const sp_point_256* g, const sp_ * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, - void* heap) +int sp_ecc_mulmod_256(const mp_int* km, const ecc_point* gm, ecc_point* r, + int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_256 p; @@ -22190,8 +23259,95 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, return err; } +/* Multiply the point by the scalar, add point a and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * p Point to multiply. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_add_256(const mp_int* km, const ecc_point* gm, + const ecc_point* am, int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_256 p; + sp_point_256 a; + sp_digit kd[4]; + sp_digit t[4 * 2 * 5]; +#endif + sp_point_256* point; + sp_point_256* addP = NULL; + sp_digit* k = NULL; + sp_digit* tmp = NULL; + int err = MP_OKAY; + + err = sp_256_point_new_4(heap, p, point); + if (err == MP_OKAY) { + err = sp_256_point_new_4(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 + 4 * 2 * 5), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 4; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_256_from_mp(k, 4, km); + sp_256_point_from_ecc_point_4(point, gm); + sp_256_point_from_ecc_point_4(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_4(addP->x, addP->x, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_4(addP->y, addP->y, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_4(addP->z, addP->z, p256_mod); + } + if (err == MP_OKAY) { + err = sp_256_ecc_mulmod_4(point, point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_256_proj_point_add_4(point, point, addP, tmp); + + if (map) { + sp_256_map_4(point, point, tmp); + } + + err = sp_256_point_to_ecc_point_4(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_256_point_free_4(addP, 0, heap); + sp_256_point_free_4(point, 0, heap); + + return err; +} + #ifdef WOLFSSL_SP_SMALL #ifndef WC_NO_CACHE_RESISTANT +/* Striping precomputation table. + * 6 points combined into a table of 64 points. + * Distance of 43 between points. + */ static const sp_table_entry_256 p256_table[64] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00 }, @@ -22516,6 +23672,11 @@ static const sp_table_entry_256 p256_table[64] = { /* Multiply the base point of P256 by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Stripe implementation. + * Pre-generated: 2^0, 2^42, ... + * Pre-generated: products of all combinations of above. + * 6 doubles and adds (with qz=1) + * * r Resulting point. * k Scalar to multiply by. * map Indicates whether to convert result to affine. @@ -22531,6 +23692,10 @@ static int sp_256_ecc_mulmod_base_4(sp_point_256* r, const sp_digit* k, } #else +/* Striping precomputation table. + * 8 points combined into a table of 256 points. + * Distance of 32 between points. + */ static const sp_table_entry_256 p256_table[256] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00 }, @@ -23815,6 +24980,11 @@ static const sp_table_entry_256 p256_table[256] = { /* Multiply the base point of P256 by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Stripe implementation. + * Pre-generated: 2^0, 2^32, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * * r Resulting point. * k Scalar to multiply by. * map Indicates whether to convert result to affine. @@ -23865,7 +25035,8 @@ static const uint8_t recode_neg_4_7[130] = { */ static void sp_256_ecc_recode_7_4(const sp_digit* k, ecc_recode_256* v) { - int i, j; + int i; + int j; uint8_t y; int carry = 0; int o; @@ -35970,6 +37141,7 @@ static int sp_256_ecc_mulmod_add_only_4(sp_point_256* r, const sp_point_256* g, } p->infinity = !v[i].i; sp_256_sub_4(negy, p256_mod, p->y); + sp_256_norm_4(negy); sp_256_cond_copy_4(p->y, negy, 0 - v[i].neg); sp_256_proj_point_add_qz1_4(rt, rt, p, tmp); } @@ -36022,7 +37194,7 @@ static int sp_256_ecc_mulmod_base_4(sp_point_256* r, const sp_digit* k, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) +int sp_ecc_mulmod_base_256(const mp_int* km, ecc_point* r, int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_256 p; @@ -36063,6 +37235,87 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) return err; } +/* Multiply the base point of P256 by the scalar, add point a and return + * the result. If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_add_256(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_256 p; + sp_point_256 a; + sp_digit kd[4]; + sp_digit t[4 * 2 * 5]; +#endif + sp_point_256* point; + sp_point_256* addP = NULL; + sp_digit* tmp = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_256_point_new_4(heap, p, point); + if (err == MP_OKAY) { + err = sp_256_point_new_4(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 + 4 * 2 * 5), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 4; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_256_from_mp(k, 4, km); + sp_256_point_from_ecc_point_4(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_4(addP->x, addP->x, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_4(addP->y, addP->y, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_4(addP->z, addP->z, p256_mod); + } + if (err == MP_OKAY) { + err = sp_256_ecc_mulmod_base_4(point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_256_proj_point_add_4(point, point, addP, tmp); + + if (map) { + sp_256_map_4(point, point, tmp); + } + + err = sp_256_point_to_ecc_point_4(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_256_point_free_4(addP, 0, heap); + sp_256_point_free_4(point, 0, heap); + + return err; +} + #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \ defined(HAVE_ECC_VERIFY) /* Returns 1 if the number of zero. @@ -36076,7 +37329,7 @@ static int sp_256_iszero_4(const sp_digit* a) return (a[0] | a[1] | a[2] | a[3]) == 0; } -#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN | HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ /* Add 1 to a. (a = a + 1) * * a A single precision integer. @@ -36108,7 +37361,8 @@ static void sp_256_add_one_4(sp_digit* a) */ static void sp_256_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j; + int i; + int j; byte* d; for (i = n - 1,j = 0; i >= 7; i -= 8) { @@ -36263,7 +37517,8 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) */ static void sp_256_to_bin(sp_digit* r, byte* a) { - int i, j; + int i; + int j; for (i = 3, j = 0; i >= 0; i--) { a[j++] = r[i] >> 56; @@ -36289,7 +37544,7 @@ static void sp_256_to_bin(sp_digit* r, byte* a) * returns BUFFER_E if the buffer is to small for output size, * MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, +int sp_ecc_secret_gen_256(const mp_int* priv, const ecc_point* pub, byte* out, word32* outLen, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) @@ -36340,207 +37595,6 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, #endif /* HAVE_ECC_DHE */ #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -static sp_digit sp_256_add_4(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - __asm__ __volatile__ ( - "ldp x3, x4, [%[a], 0]\n\t" - "ldp x7, x8, [%[b], 0]\n\t" - "adds x3, x3, x7\n\t" - "ldp x5, x6, [%[a], 16]\n\t" - "adcs x4, x4, x8\n\t" - "ldp x9, x10, [%[b], 16]\n\t" - "adcs x5, x5, x9\n\t" - "stp x3, x4, [%[r], 0]\n\t" - "adcs x6, x6, x10\n\t" - "stp x5, x6, [%[r], 16]\n\t" - "cset %[r], cs\n\t" - : [r] "+r" (r) - : [a] "r" (a), [b] "r" (b) - : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10" - ); - - return (sp_digit)r; -} - -#endif -#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) -#ifdef WOLFSSL_SP_SMALL -/* Multiply a and b into r. (r = a * b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -static void sp_256_mul_4(sp_digit* r, const sp_digit* a, const sp_digit* b) -{ - sp_digit tmp[8]; - - __asm__ __volatile__ ( - "mov x5, 0\n\t" - "mov x6, 0\n\t" - "mov x7, 0\n\t" - "mov x8, 0\n\t" - "\n1:\n\t" - "subs x3, x5, 24\n\t" - "csel x3, xzr, x3, cc\n\t" - "sub x4, x5, x3\n\t" - "\n2:\n\t" - "ldr x10, [%[a], x3]\n\t" - "ldr x11, [%[b], x4]\n\t" - "mul x9, x10, x11\n\t" - "umulh x10, x10, x11\n\t" - "adds x6, x6, x9\n\t" - "adcs x7, x7, x10\n\t" - "adc x8, x8, xzr\n\t" - "add x3, x3, #8\n\t" - "sub x4, x4, #8\n\t" - "cmp x3, 32\n\t" - "b.eq 3f\n\t" - "cmp x3, x5\n\t" - "b.le 2b\n\t" - "\n3:\n\t" - "str x6, [%[r], x5]\n\t" - "mov x6, x7\n\t" - "mov x7, x8\n\t" - "mov x8, #0\n\t" - "add x5, x5, #8\n\t" - "cmp x5, 48\n\t" - "b.le 1b\n\t" - "str x6, [%[r], x5]\n\t" - : - : [r] "r" (tmp), [a] "r" (a), [b] "r" (b) - : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11" - ); - - XMEMCPY(r, tmp, sizeof(tmp)); -} - -#else -/* Multiply a and b into r. (r = a * b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -static void sp_256_mul_4(sp_digit* r, const sp_digit* a, const sp_digit* b) -{ - sp_digit tmp[4]; - - __asm__ __volatile__ ( - "ldp x16, x17, [%[a], 0]\n\t" - "ldp x21, x22, [%[b], 0]\n\t" - "# A[0] * B[0]\n\t" - "mul x8, x16, x21\n\t" - "ldr x19, [%[a], 16]\n\t" - "umulh x9, x16, x21\n\t" - "ldr x23, [%[b], 16]\n\t" - "# A[0] * B[1]\n\t" - "mul x4, x16, x22\n\t" - "ldr x20, [%[a], 24]\n\t" - "umulh x5, x16, x22\n\t" - "ldr x24, [%[b], 24]\n\t" - "adds x9, x9, x4\n\t" - "# A[1] * B[0]\n\t" - "mul x4, x17, x21\n\t" - "adc x10, xzr, x5\n\t" - "umulh x5, x17, x21\n\t" - "adds x9, x9, x4\n\t" - "# A[0] * B[2]\n\t" - "mul x4, x16, x23\n\t" - "adcs x10, x10, x5\n\t" - "umulh x5, x16, x23\n\t" - "adc x11, xzr, xzr\n\t" - "adds x10, x10, x4\n\t" - "# A[1] * B[1]\n\t" - "mul x4, x17, x22\n\t" - "adc x11, x11, x5\n\t" - "umulh x5, x17, x22\n\t" - "adds x10, x10, x4\n\t" - "# A[2] * B[0]\n\t" - "mul x4, x19, x21\n\t" - "adcs x11, x11, x5\n\t" - "umulh x5, x19, x21\n\t" - "adc x12, xzr, xzr\n\t" - "adds x10, x10, x4\n\t" - "# A[0] * B[3]\n\t" - "mul x4, x16, x24\n\t" - "adcs x11, x11, x5\n\t" - "umulh x5, x16, x24\n\t" - "adc x12, x12, xzr\n\t" - "adds x11, x11, x4\n\t" - "# A[1] * B[2]\n\t" - "mul x4, x17, x23\n\t" - "adcs x12, x12, x5\n\t" - "umulh x5, x17, x23\n\t" - "adc x13, xzr, xzr\n\t" - "adds x11, x11, x4\n\t" - "# A[2] * B[1]\n\t" - "mul x4, x19, x22\n\t" - "adcs x12, x12, x5\n\t" - "umulh x5, x19, x22\n\t" - "adc x13, x13, xzr\n\t" - "adds x11, x11, x4\n\t" - "# A[3] * B[0]\n\t" - "mul x4, x20, x21\n\t" - "adcs x12, x12, x5\n\t" - "umulh x5, x20, x21\n\t" - "adc x13, x13, xzr\n\t" - "adds x11, x11, x4\n\t" - "# A[1] * B[3]\n\t" - "mul x4, x17, x24\n\t" - "adcs x12, x12, x5\n\t" - "umulh x5, x17, x24\n\t" - "adc x13, x13, xzr\n\t" - "adds x12, x12, x4\n\t" - "# A[2] * B[2]\n\t" - "mul x4, x19, x23\n\t" - "adcs x13, x13, x5\n\t" - "umulh x5, x19, x23\n\t" - "adc x14, xzr, xzr\n\t" - "adds x12, x12, x4\n\t" - "# A[3] * B[1]\n\t" - "mul x4, x20, x22\n\t" - "adcs x13, x13, x5\n\t" - "umulh x5, x20, x22\n\t" - "adc x14, x14, xzr\n\t" - "adds x12, x12, x4\n\t" - "# A[2] * B[3]\n\t" - "mul x4, x19, x24\n\t" - "adcs x13, x13, x5\n\t" - "umulh x5, x19, x24\n\t" - "adc x14, x14, xzr\n\t" - "adds x13, x13, x4\n\t" - "# A[3] * B[2]\n\t" - "mul x4, x20, x23\n\t" - "adcs x14, x14, x5\n\t" - "umulh x5, x20, x23\n\t" - "adc x15, xzr, xzr\n\t" - "adds x13, x13, x4\n\t" - "# A[3] * B[3]\n\t" - "mul x4, x20, x24\n\t" - "adcs x14, x14, x5\n\t" - "umulh x5, x20, x24\n\t" - "adc x15, x15, xzr\n\t" - "adds x14, x14, x4\n\t" - "adc x15, x15, x5\n\t" - "stp x8, x9, [%[r], 0]\n\t" - "stp x10, x11, [%[r], 16]\n\t" - "stp x12, x13, [%[r], 32]\n\t" - "stp x14, x15, [%[r], 48]\n\t" - : - : [r] "r" (r), [a] "r" (a), [b] "r" (b), [tmp] "r" (tmp) - : "memory", "x4", "x5", "x6", "x7", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15" - ); -} - -#endif /* WOLFSSL_SP_SMALL */ #endif #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) /* Sub b from a into a. (a -= b) @@ -36743,83 +37797,6 @@ static WC_INLINE int sp_256_mod_4(sp_digit* r, const sp_digit* a, const sp_digit #endif #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) -/* Square a and put result in r. (r = a * a) - * - * r A single precision integer. - * a A single precision integer. - */ -static void sp_256_sqr_4(sp_digit* r, const sp_digit* a) -{ - __asm__ __volatile__ ( - "ldp x16, x17, [%[a], 0]\n\t" - "# A[0] * A[1]\n\t" - "mul x9, x16, x17\n\t" - "ldr x19, [%[a], 16]\n\t" - "umulh x10, x16, x17\n\t" - "ldr x20, [%[a], 24]\n\t" - "# A[0] * A[2]\n\t" - "mul x4, x16, x19\n\t" - "umulh x5, x16, x19\n\t" - "adds x10, x10, x4\n\t" - "# A[0] * A[3]\n\t" - "mul x4, x16, x20\n\t" - "adc x11, xzr, x5\n\t" - "umulh x5, x16, x20\n\t" - "adds x11, x11, x4\n\t" - "# A[1] * A[2]\n\t" - "mul x4, x17, x19\n\t" - "adc x12, xzr, x5\n\t" - "umulh x5, x17, x19\n\t" - "adds x11, x11, x4\n\t" - "# A[1] * A[3]\n\t" - "mul x4, x17, x20\n\t" - "adcs x12, x12, x5\n\t" - "umulh x5, x17, x20\n\t" - "adc x13, xzr, xzr\n\t" - "adds x12, x12, x4\n\t" - "# A[2] * A[3]\n\t" - "mul x4, x19, x20\n\t" - "adc x13, x13, x5\n\t" - "umulh x5, x19, x20\n\t" - "adds x13, x13, x4\n\t" - "adc x14, xzr, x5\n\t" - "# Double\n\t" - "adds x9, x9, x9\n\t" - "adcs x10, x10, x10\n\t" - "adcs x11, x11, x11\n\t" - "adcs x12, x12, x12\n\t" - "adcs x13, x13, x13\n\t" - "# A[0] * A[0]\n\t" - "mul x8, x16, x16\n\t" - "adcs x14, x14, x14\n\t" - "umulh x3, x16, x16\n\t" - "cset x15, cs\n\t" - "# A[1] * A[1]\n\t" - "mul x4, x17, x17\n\t" - "adds x9, x9, x3\n\t" - "umulh x5, x17, x17\n\t" - "adcs x10, x10, x4\n\t" - "# A[2] * A[2]\n\t" - "mul x6, x19, x19\n\t" - "adcs x11, x11, x5\n\t" - "umulh x7, x19, x19\n\t" - "adcs x12, x12, x6\n\t" - "# A[3] * A[3]\n\t" - "mul x16, x20, x20\n\t" - "adcs x13, x13, x7\n\t" - "umulh x17, x20, x20\n\t" - "adcs x14, x14, x16\n\t" - "adc x15, x15, x17\n\t" - "stp x8, x9, [%[r], 0]\n\t" - "stp x10, x11, [%[r], 16]\n\t" - "stp x12, x13, [%[r], 32]\n\t" - "stp x14, x15, [%[r], 48]\n\t" - : - : [r] "r" (r), [a] "r" (a) - : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20" - ); -} - #ifdef WOLFSSL_SP_SMALL /* Order-2 for the P256 curve. */ static const uint64_t p256_order_minus_2[4] = { @@ -36828,7 +37805,7 @@ static const uint64_t p256_order_minus_2[4] = { }; #else /* The low half of the order-2 of the P256 curve. */ -static const uint64_t p256_order_low[2] = { +static const sp_int_digit p256_order_low[2] = { 0xf3b9cac2fc63254fU,0xbce6faada7179e84U }; #endif /* WOLFSSL_SP_SMALL */ @@ -36974,7 +37951,7 @@ static void sp_256_mont_inv_order_4(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6 */ for (i=127; i>=112; i--) { sp_256_mont_sqr_order_4(t2, t2); - if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { + if ((p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { sp_256_mont_mul_order_4(t2, t2, a); } } @@ -36984,7 +37961,7 @@ static void sp_256_mont_inv_order_4(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84 */ for (i=107; i>=64; i--) { sp_256_mont_sqr_order_4(t2, t2); - if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { + if ((p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { sp_256_mont_mul_order_4(t2, t2, a); } } @@ -36994,7 +37971,7 @@ static void sp_256_mont_inv_order_4(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2 */ for (i=59; i>=32; i--) { sp_256_mont_sqr_order_4(t2, t2); - if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { + if ((p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { sp_256_mont_mul_order_4(t2, t2, a); } } @@ -37004,7 +37981,7 @@ static void sp_256_mont_inv_order_4(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254 */ for (i=27; i>=0; i--) { sp_256_mont_sqr_order_4(t2, t2); - if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { + if ((p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { sp_256_mont_mul_order_4(t2, t2, a); } } @@ -37015,12 +37992,63 @@ static void sp_256_mont_inv_order_4(sp_digit* r, const sp_digit* a, #endif /* WOLFSSL_SP_SMALL */ } -#endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ #ifdef HAVE_ECC_SIGN #ifndef SP_ECC_MAX_SIG_GEN #define SP_ECC_MAX_SIG_GEN 64 #endif +/* Calculate second signature value S from R, k and private value. + * + * s = (r * x + e) / k + * + * s Signature value. + * r First signature value. + * k Ephemeral private key. + * x Private key as a number. + * e Hash of message as a number. + * tmp Temporary storage for intermediate numbers. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_256_calc_s_4(sp_digit* s, const sp_digit* r, sp_digit* k, + sp_digit* x, const sp_digit* e, sp_digit* tmp) +{ + int err; + sp_digit carry; + int64_t c; + sp_digit* kInv = k; + + /* Conv k to Montgomery form (mod order) */ + sp_256_mul_4(k, k, p256_norm_order); + err = sp_256_mod_4(k, k, p256_order); + if (err == MP_OKAY) { + sp_256_norm_4(k); + + /* kInv = 1/k mod order */ + sp_256_mont_inv_order_4(kInv, k, tmp); + sp_256_norm_4(kInv); + + /* s = r * x + e */ + sp_256_mul_4(x, x, r); + err = sp_256_mod_4(x, x, p256_order); + } + if (err == MP_OKAY) { + sp_256_norm_4(x); + carry = sp_256_add_4(s, e, x); + sp_256_cond_sub_4(s, s, p256_order, 0 - carry); + sp_256_norm_4(s); + c = sp_256_cmp_4(s, p256_order); + sp_256_cond_sub_4(s, s, p256_order, 0L - (sp_digit)(c >= 0)); + sp_256_norm_4(s); + + /* s = s * k^-1 mod order */ + sp_256_mont_mul_order_4(s, s, kInv); + sp_256_norm_4(s); + } + + return err; +} + /* Sign the hash using the private key. * e = [hash, 256 bits] from binary * r = (k.G)->x mod order @@ -37055,8 +38083,8 @@ typedef struct sp_ecc_sign_256_ctx { int i; } sp_ecc_sign_256_ctx; -int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, + mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_sign_256_ctx* ctx = (sp_ecc_sign_256_ctx*)sp_ctx->data; @@ -37196,8 +38224,8 @@ int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, W } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, + const mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -37215,11 +38243,9 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit* r = NULL; sp_digit* tmp = NULL; sp_point_256* point = NULL; - sp_digit carry; sp_digit* s = NULL; - sp_digit* kInv = NULL; - int err = MP_OKAY; int64_t c; + int err = MP_OKAY; int i; (void)heap; @@ -37250,7 +38276,6 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, tmp = td; #endif s = e; - kInv = k; if (hashLen > 32U) { hashLen = 32U; @@ -37258,8 +38283,6 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, } for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) { - sp_256_from_mp(x, 4, priv); - /* New random point. */ if (km == NULL || mp_iszero(km)) { err = sp_256_ecc_gen_k_4(rng, k); @@ -37269,7 +38292,7 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, mp_zero(km); } if (err == MP_OKAY) { - err = sp_256_ecc_mulmod_base_4(point, k, 1, 1, NULL); + err = sp_256_ecc_mulmod_base_4(point, k, 1, 1, heap); } if (err == MP_OKAY) { @@ -37280,38 +38303,15 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_256_cond_sub_4(r, r, p256_order, 0L - (sp_digit)(c >= 0)); sp_256_norm_4(r); - /* Conv k to Montgomery form (mod order) */ - sp_256_mul_4(k, k, p256_norm_order); - err = sp_256_mod_4(k, k, p256_order); - } - if (err == MP_OKAY) { - sp_256_norm_4(k); - /* kInv = 1/k mod order */ - sp_256_mont_inv_order_4(kInv, k, tmp); - sp_256_norm_4(kInv); - - /* s = r * x + e */ - sp_256_mul_4(x, x, r); - err = sp_256_mod_4(x, x, p256_order); - } - if (err == MP_OKAY) { - sp_256_norm_4(x); + sp_256_from_mp(x, 4, priv); sp_256_from_bin(e, 4, hash, (int)hashLen); - carry = sp_256_add_4(s, e, x); - sp_256_cond_sub_4(s, s, p256_order, 0 - carry); - sp_256_norm_4(s); - c = sp_256_cmp_4(s, p256_order); - sp_256_cond_sub_4(s, s, p256_order, 0L - (sp_digit)(c >= 0)); - sp_256_norm_4(s); - /* s = s * k^-1 mod order */ - sp_256_mont_mul_order_4(s, s, kInv); - sp_256_norm_4(s); + err = sp_256_calc_s_4(s, r, k, x, e, tmp); + } - /* Check that signature is usable. */ - if (sp_256_iszero_4(s) == 0) { - break; - } + /* Check that signature is usable. */ + if ((err == MP_OKAY) && (sp_256_iszero_4(s) == 0)) { + break; } #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP i = 1; @@ -37339,7 +38339,6 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, XMEMSET(x, 0, sizeof(sp_digit) * 2U * 4U); XMEMSET(k, 0, sizeof(sp_digit) * 2U * 4U); XMEMSET(r, 0, sizeof(sp_digit) * 2U * 4U); - XMEMSET(r, 0, sizeof(sp_digit) * 2U * 4U); XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 4U); #endif sp_256_point_free_4(point, 1, heap); @@ -37635,6 +38634,92 @@ static int sp_256_mod_inv_4(sp_digit* r, const sp_digit* a, } #endif /* WOLFSSL_SP_SMALL */ + +/* Add point p1 into point p2. Handles p1 == p2 and result at infinity. + * + * p1 First point to add and holds result. + * p2 Second point to add. + * tmp Temporary storage for intermediate numbers. + */ +static void sp_256_add_points_4(sp_point_256* p1, const sp_point_256* p2, + sp_digit* tmp) +{ + + sp_256_proj_point_add_4(p1, p1, p2, tmp); + if (sp_256_iszero_4(p1->z)) { + if (sp_256_iszero_4(p1->x) && sp_256_iszero_4(p1->y)) { + sp_256_proj_point_dbl_4(p1, p2, tmp); + } + else { + /* Y ordinate is not used from here - don't set. */ + p1->x[0] = 0; + p1->x[1] = 0; + p1->x[2] = 0; + p1->x[3] = 0; + XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod)); + } + } +} + +/* Calculate the verification point: [e/s]G + [r/s]Q + * + * p1 Calculated point. + * p2 Public point and temporary. + * s Second part of signature as a number. + * u1 Temporary number. + * u2 Temproray number. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_256_calc_vfy_point_4(sp_point_256* p1, sp_point_256* p2, + sp_digit* s, sp_digit* u1, sp_digit* u2, sp_digit* tmp, void* heap) +{ + int err; + +#ifndef WOLFSSL_SP_SMALL + { + sp_256_mod_inv_4(s, s, p256_order); + } +#endif /* !WOLFSSL_SP_SMALL */ + { + sp_256_mul_4(s, s, p256_norm_order); + } + err = sp_256_mod_4(s, s, p256_order); + if (err == MP_OKAY) { + sp_256_norm_4(s); +#ifdef WOLFSSL_SP_SMALL + { + sp_256_mont_inv_order_4(s, s, tmp); + sp_256_mont_mul_order_4(u1, u1, s); + sp_256_mont_mul_order_4(u2, u2, s); + } + +#else + { + sp_256_mont_mul_order_4(u1, u1, s); + sp_256_mont_mul_order_4(u2, u2, s); + } + +#endif /* WOLFSSL_SP_SMALL */ + err = sp_256_ecc_mulmod_base_4(p1, u1, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_256_iszero_4(p1->z)) { + p1->infinity = 1; + } + if (err == MP_OKAY) { + err = sp_256_ecc_mulmod_4(p2, p2, u2, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_256_iszero_4(p2->z)) { + p2->infinity = 1; + } + + if (err == MP_OKAY) { + sp_256_add_points_4(p1, p2, tmp); + } + + return err; +} + #ifdef HAVE_ECC_VERIFY /* Verify the signature values with the hash and public key. * e = Truncate(hash, 256) @@ -37653,8 +38738,7 @@ static int sp_256_mod_inv_4(sp_digit* r, const sp_digit* a, * rm First part of result as an mp_int. * sm Sirst part of result as an mp_int. * heap Heap to use for allocation. - * returns RNG failures, MEMORY_E when memory allocation fails and - * MP_OKAY on success. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ #ifdef WOLFSSL_SP_NONBLOCK typedef struct sp_ecc_verify_256_ctx { @@ -37673,8 +38757,9 @@ typedef struct sp_ecc_verify_256_ctx { sp_point_256 p2; } sp_ecc_verify_256_ctx; -int sp_ecc_verify_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, + word32 hashLen, const mp_int* pX, const mp_int* pY, const mp_int* pZ, + const mp_int* r, const mp_int* sm, int* res, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_verify_256_ctx* ctx = (sp_ecc_verify_256_ctx*)sp_ctx->data; @@ -37828,8 +38913,9 @@ int sp_ecc_verify_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_256(const byte* hash, word32 hashLen, const mp_int* pX, + const mp_int* pY, const mp_int* pZ, const mp_int* r, const mp_int* sm, + int* res, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -37848,7 +38934,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_point_256* p1; sp_point_256* p2 = NULL; sp_digit carry; - int64_t c; + int64_t c = 0; int err; err = sp_256_point_new_4(heap, p1d, p1); @@ -37889,62 +38975,9 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_256_from_mp(p2->y, 4, pY); sp_256_from_mp(p2->z, 4, pZ); -#ifndef WOLFSSL_SP_SMALL - { - sp_256_mod_inv_4(s, s, p256_order); - } -#endif /* !WOLFSSL_SP_SMALL */ - { - sp_256_mul_4(s, s, p256_norm_order); - } - err = sp_256_mod_4(s, s, p256_order); + err = sp_256_calc_vfy_point_4(p1, p2, s, u1, u2, tmp, heap); } if (err == MP_OKAY) { - sp_256_norm_4(s); -#ifdef WOLFSSL_SP_SMALL - { - sp_256_mont_inv_order_4(s, s, tmp); - sp_256_mont_mul_order_4(u1, u1, s); - sp_256_mont_mul_order_4(u2, u2, s); - } - -#else - { - sp_256_mont_mul_order_4(u1, u1, s); - sp_256_mont_mul_order_4(u2, u2, s); - } - -#endif /* WOLFSSL_SP_SMALL */ - err = sp_256_ecc_mulmod_base_4(p1, u1, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_256_iszero_4(p1->z)) { - p1->infinity = 1; - } - if (err == MP_OKAY) { - err = sp_256_ecc_mulmod_4(p2, p2, u2, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_256_iszero_4(p2->z)) { - p2->infinity = 1; - } - - if (err == MP_OKAY) { - { - sp_256_proj_point_add_4(p1, p1, p2, tmp); - if (sp_256_iszero_4(p1->z)) { - if (sp_256_iszero_4(p1->x) && sp_256_iszero_4(p1->y)) { - sp_256_proj_point_dbl_4(p1, p2, tmp); - } - else { - /* Y ordinate is not used from here - don't set. */ - p1->x[0] = 0; - p1->x[1] = 0; - p1->x[2] = 0; - p1->x[3] = 0; - XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod)); - } - } - } - /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */ /* Reload r and convert to Montgomery form. */ sp_256_from_mp(u2, 4, r); @@ -37966,16 +38999,16 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, /* Compare with mod and if greater or equal then not valid. */ c = sp_256_cmp_4(u2, p256_mod); - if (c < 0) { - /* Convert to Montogomery form */ - err = sp_256_mod_mul_norm_4(u2, u2, p256_mod); - if (err == MP_OKAY) { - /* u1 = (r + 1*order).z'.z' mod prime */ - sp_256_mont_mul_4(u1, u2, p1->z, p256_mod, - p256_mp_mod); - *res = (int)(sp_256_cmp_4(p1->x, u1) == 0); - } - } + } + } + if ((*res == 0) && (c < 0)) { + /* Convert to Montogomery form */ + err = sp_256_mod_mul_norm_4(u2, u2, p256_mod); + if (err == MP_OKAY) { + /* u1 = (r + 1*order).z'.z' mod prime */ + sp_256_mont_mul_4(u1, u2, p1->z, p256_mod, + p256_mp_mod); + *res = (sp_256_cmp_4(p1->x, u1) == 0); } } } @@ -37999,7 +39032,8 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -static int sp_256_ecc_is_point_4(sp_point_256* point, void* heap) +static int sp_256_ecc_is_point_4(const sp_point_256* point, + void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -38062,7 +39096,7 @@ static int sp_256_ecc_is_point_4(sp_point_256* point, void* heap) * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) +int sp_ecc_is_point_256(const mp_int* pX, const mp_int* pY) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_256 pubd; @@ -38096,7 +39130,8 @@ int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and * MP_OKAY otherwise. */ -int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) +int sp_ecc_check_key_256(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit privd[4]; @@ -38150,12 +39185,11 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) } } - if (err == MP_OKAY) { - /* Check range of X and Y */ - if (sp_256_cmp_4(pub->x, p256_mod) >= 0 || - sp_256_cmp_4(pub->y, p256_mod) >= 0) { - err = ECC_OUT_OF_RANGE_E; - } + /* Check range of X and Y */ + if ((err == MP_OKAY) && + ((sp_256_cmp_4(pub->x, p256_mod) >= 0) || + (sp_256_cmp_4(pub->y, p256_mod) >= 0))) { + err = ECC_OUT_OF_RANGE_E; } if (err == MP_OKAY) { @@ -38167,12 +39201,10 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Point * order = infinity */ err = sp_256_ecc_mulmod_4(p, pub, p256_order, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is infinity */ - if ((sp_256_iszero_4(p->x) == 0) || - (sp_256_iszero_4(p->y) == 0)) { - err = ECC_INF_E; - } + /* Check result is infinity */ + if ((err == MP_OKAY) && ((sp_256_iszero_4(p->x) == 0) || + (sp_256_iszero_4(p->y) == 0))) { + err = ECC_INF_E; } if (privm) { @@ -38180,12 +39212,11 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Base * private = point */ err = sp_256_ecc_mulmod_base_4(p, priv, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is public key */ - if (sp_256_cmp_4(p->x, pub->x) != 0 || - sp_256_cmp_4(p->y, pub->y) != 0) { - err = ECC_PRIV_KEY_E; - } + /* Check result is public key */ + if ((err == MP_OKAY) && + ((sp_256_cmp_4(p->x, pub->x) != 0) || + (sp_256_cmp_4(p->y, pub->y) != 0))) { + err = ECC_PRIV_KEY_E; } } @@ -38375,7 +39406,7 @@ int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ) sp_256_from_mp(p->y, 4, pY); sp_256_from_mp(p->z, 4, pZ); - sp_256_map_4(p, p, tmp); + sp_256_map_4(p, p, tmp); } if (err == MP_OKAY) { @@ -38555,9 +39586,13 @@ int sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym) /* Point structure to use. */ typedef struct sp_point_384 { + /* X ordinate of point. */ sp_digit x[2 * 6]; + /* Y ordinate of point. */ sp_digit y[2 * 6]; + /* Z ordinate of point. */ sp_digit z[2 * 6]; + /* Indicates point is at infinity. */ int infinity; } sp_point_384; @@ -38595,8 +39630,9 @@ static const sp_digit p384_norm_order[6] = { #endif #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) /* The Montogmery multiplier for order of the curve P384. */ -static sp_digit p384_mp_order = 0x6ed46089e88fdc45l; +static sp_digit p384_mp_order = 0x6ed46089e88fdc45L; #endif +#ifdef WOLFSSL_SP_SMALL /* The base point of curve P384. */ static const sp_point_384 p384_base = { /* X ordinate */ @@ -38620,6 +39656,7 @@ static const sp_point_384 p384_base = { /* infinity */ 0 }; +#endif /* WOLFSSL_SP_SMALL */ #if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY) static const sp_digit p384_b[6] = { 0x2a85c8edd3ec2aefL,0xc656398d8a2ed19dL,0x0314088f5013875aL, @@ -38627,397 +39664,6 @@ static const sp_digit p384_b[6] = { }; #endif -static int sp_384_point_new_ex_6(void* heap, sp_point_384* sp, sp_point_384** p) -{ - int ret = MP_OKAY; - (void)heap; -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - (void)sp; - *p = (sp_point_384*)XMALLOC(sizeof(sp_point_384), heap, DYNAMIC_TYPE_ECC); -#else - *p = sp; -#endif - if (*p == NULL) { - ret = MEMORY_E; - } - return ret; -} - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) -/* Allocate memory for point and return error. */ -#define sp_384_point_new_6(heap, sp, p) sp_384_point_new_ex_6((heap), NULL, &(p)) -#else -/* Set pointer to data and return no error. */ -#define sp_384_point_new_6(heap, sp, p) sp_384_point_new_ex_6((heap), &(sp), &(p)) -#endif - - -static void sp_384_point_free_6(sp_point_384* p, int clear, void* heap) -{ -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) -/* If valid pointer then clear point data if requested and free data. */ - if (p != NULL) { - if (clear != 0) { - XMEMSET(p, 0, sizeof(*p)); - } - XFREE(p, heap, DYNAMIC_TYPE_ECC); - } -#else -/* Clear point data if requested. */ - if (clear != 0) { - XMEMSET(p, 0, sizeof(*p)); - } -#endif - (void)heap; -} - -/* Multiply a number by Montogmery normalizer mod modulus (prime). - * - * r The resulting Montgomery form number. - * a The number to convert. - * m The modulus (prime). - * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. - */ -static int sp_384_mod_mul_norm_6(sp_digit* r, const sp_digit* a, const sp_digit* m) -{ -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - int64_t* td; -#else - int64_t td[12]; - int64_t a32d[12]; -#endif - int64_t* t; - int64_t* a32; - int64_t o; - int err = MP_OKAY; - - (void)m; - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - td = (int64_t*)XMALLOC(sizeof(int64_t) * 2 * 12, NULL, DYNAMIC_TYPE_ECC); - if (td == NULL) { - err = MEMORY_E; - } -#endif - - if (err == MP_OKAY) { -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - t = td; - a32 = td + 12; -#else - t = td; - a32 = a32d; -#endif - - a32[0] = a[0] & 0xffffffff; - a32[1] = a[0] >> 32; - a32[2] = a[1] & 0xffffffff; - a32[3] = a[1] >> 32; - a32[4] = a[2] & 0xffffffff; - a32[5] = a[2] >> 32; - a32[6] = a[3] & 0xffffffff; - a32[7] = a[3] >> 32; - a32[8] = a[4] & 0xffffffff; - a32[9] = a[4] >> 32; - a32[10] = a[5] & 0xffffffff; - a32[11] = a[5] >> 32; - - /* 1 0 0 0 0 0 0 0 1 1 0 -1 */ - t[0] = 0 + a32[0] + a32[8] + a32[9] - a32[11]; - /* -1 1 0 0 0 0 0 0 -1 0 1 1 */ - t[1] = 0 - a32[0] + a32[1] - a32[8] + a32[10] + a32[11]; - /* 0 -1 1 0 0 0 0 0 0 -1 0 1 */ - t[2] = 0 - a32[1] + a32[2] - a32[9] + a32[11]; - /* 1 0 -1 1 0 0 0 0 1 1 -1 -1 */ - t[3] = 0 + a32[0] - a32[2] + a32[3] + a32[8] + a32[9] - a32[10] - a32[11]; - /* 1 1 0 -1 1 0 0 0 1 2 1 -2 */ - t[4] = 0 + a32[0] + a32[1] - a32[3] + a32[4] + a32[8] + 2 * a32[9] + a32[10] - 2 * a32[11]; - /* 0 1 1 0 -1 1 0 0 0 1 2 1 */ - t[5] = 0 + a32[1] + a32[2] - a32[4] + a32[5] + a32[9] + 2 * a32[10] + a32[11]; - /* 0 0 1 1 0 -1 1 0 0 0 1 2 */ - t[6] = 0 + a32[2] + a32[3] - a32[5] + a32[6] + a32[10] + 2 * a32[11]; - /* 0 0 0 1 1 0 -1 1 0 0 0 1 */ - t[7] = 0 + a32[3] + a32[4] - a32[6] + a32[7] + a32[11]; - /* 0 0 0 0 1 1 0 -1 1 0 0 0 */ - t[8] = 0 + a32[4] + a32[5] - a32[7] + a32[8]; - /* 0 0 0 0 0 1 1 0 -1 1 0 0 */ - t[9] = 0 + a32[5] + a32[6] - a32[8] + a32[9]; - /* 0 0 0 0 0 0 1 1 0 -1 1 0 */ - t[10] = 0 + a32[6] + a32[7] - a32[9] + a32[10]; - /* 0 0 0 0 0 0 0 1 1 0 -1 1 */ - t[11] = 0 + a32[7] + a32[8] - a32[10] + a32[11]; - - t[1] += t[0] >> 32; t[0] &= 0xffffffff; - t[2] += t[1] >> 32; t[1] &= 0xffffffff; - t[3] += t[2] >> 32; t[2] &= 0xffffffff; - t[4] += t[3] >> 32; t[3] &= 0xffffffff; - t[5] += t[4] >> 32; t[4] &= 0xffffffff; - t[6] += t[5] >> 32; t[5] &= 0xffffffff; - t[7] += t[6] >> 32; t[6] &= 0xffffffff; - t[8] += t[7] >> 32; t[7] &= 0xffffffff; - t[9] += t[8] >> 32; t[8] &= 0xffffffff; - t[10] += t[9] >> 32; t[9] &= 0xffffffff; - t[11] += t[10] >> 32; t[10] &= 0xffffffff; - o = t[11] >> 32; t[11] &= 0xffffffff; - t[0] += o; - t[1] -= o; - t[3] += o; - t[4] += o; - t[1] += t[0] >> 32; t[0] &= 0xffffffff; - t[2] += t[1] >> 32; t[1] &= 0xffffffff; - t[3] += t[2] >> 32; t[2] &= 0xffffffff; - t[4] += t[3] >> 32; t[3] &= 0xffffffff; - t[5] += t[4] >> 32; t[4] &= 0xffffffff; - t[6] += t[5] >> 32; t[5] &= 0xffffffff; - t[7] += t[6] >> 32; t[6] &= 0xffffffff; - t[8] += t[7] >> 32; t[7] &= 0xffffffff; - t[9] += t[8] >> 32; t[8] &= 0xffffffff; - t[10] += t[9] >> 32; t[9] &= 0xffffffff; - t[11] += t[10] >> 32; t[10] &= 0xffffffff; - - r[0] = (t[1] << 32) | t[0]; - r[1] = (t[3] << 32) | t[2]; - r[2] = (t[5] << 32) | t[4]; - r[3] = (t[7] << 32) | t[6]; - r[4] = (t[9] << 32) | t[8]; - r[5] = (t[11] << 32) | t[10]; - } - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - if (td != NULL) - XFREE(td, NULL, DYNAMIC_TYPE_ECC); -#endif - - return err; -} - -/* Convert an mp_int to an array of sp_digit. - * - * r A single precision integer. - * size Maximum number of bytes to convert - * a A multi-precision integer. - */ -static void sp_384_from_mp(sp_digit* r, int size, const mp_int* a) -{ -#if DIGIT_BIT == 64 - int j; - - XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); - - for (j = a->used; j < size; j++) { - r[j] = 0; - } -#elif DIGIT_BIT > 64 - int i, j = 0; - word32 s = 0; - - r[0] = 0; - for (i = 0; i < a->used && j < size; i++) { - r[j] |= ((sp_digit)a->dp[i] << s); - r[j] &= 0xffffffffffffffffl; - s = 64U - s; - if (j + 1 >= size) { - break; - } - /* lint allow cast of mismatch word32 and mp_digit */ - r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ - while ((s + 64U) <= (word32)DIGIT_BIT) { - s += 64U; - r[j] &= 0xffffffffffffffffl; - if (j + 1 >= size) { - break; - } - if (s < (word32)DIGIT_BIT) { - /* lint allow cast of mismatch word32 and mp_digit */ - r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ - } - else { - r[++j] = 0L; - } - } - s = (word32)DIGIT_BIT - s; - } - - for (j++; j < size; j++) { - r[j] = 0; - } -#else - int i, j = 0, s = 0; - - r[0] = 0; - for (i = 0; i < a->used && j < size; i++) { - r[j] |= ((sp_digit)a->dp[i]) << s; - if (s + DIGIT_BIT >= 64) { - r[j] &= 0xffffffffffffffffl; - if (j + 1 >= size) { - break; - } - s = 64 - s; - if (s == DIGIT_BIT) { - r[++j] = 0; - s = 0; - } - else { - r[++j] = a->dp[i] >> s; - s = DIGIT_BIT - s; - } - } - else { - s += DIGIT_BIT; - } - } - - for (j++; j < size; j++) { - r[j] = 0; - } -#endif -} - -/* Convert a point of type ecc_point to type sp_point_384. - * - * p Point of type sp_point_384 (result). - * pm Point of type ecc_point. - */ -static void sp_384_point_from_ecc_point_6(sp_point_384* p, const ecc_point* pm) -{ - XMEMSET(p->x, 0, sizeof(p->x)); - XMEMSET(p->y, 0, sizeof(p->y)); - XMEMSET(p->z, 0, sizeof(p->z)); - sp_384_from_mp(p->x, 6, pm->x); - sp_384_from_mp(p->y, 6, pm->y); - sp_384_from_mp(p->z, 6, pm->z); - p->infinity = 0; -} - -/* Convert an array of sp_digit to an mp_int. - * - * a A single precision integer. - * r A multi-precision integer. - */ -static int sp_384_to_mp(const sp_digit* a, mp_int* r) -{ - int err; - - err = mp_grow(r, (384 + DIGIT_BIT - 1) / DIGIT_BIT); - if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ -#if DIGIT_BIT == 64 - XMEMCPY(r->dp, a, sizeof(sp_digit) * 6); - r->used = 6; - mp_clamp(r); -#elif DIGIT_BIT < 64 - int i, j = 0, s = 0; - - r->dp[0] = 0; - for (i = 0; i < 6; i++) { - r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; - s = DIGIT_BIT - s; - r->dp[++j] = (mp_digit)(a[i] >> s); - while (s + DIGIT_BIT <= 64) { - s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; - if (s == SP_WORD_SIZE) { - r->dp[j] = 0; - } - else { - r->dp[j] = (mp_digit)(a[i] >> s); - } - } - s = 64 - s; - } - r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; - mp_clamp(r); -#else - int i, j = 0, s = 0; - - r->dp[0] = 0; - for (i = 0; i < 6; i++) { - r->dp[j] |= ((mp_digit)a[i]) << s; - if (s + 64 >= DIGIT_BIT) { - #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; - #endif - s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; - s = 64 - s; - } - else { - s += 64; - } - } - r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; - mp_clamp(r); -#endif - } - - return err; -} - -/* Convert a point of type sp_point_384 to type ecc_point. - * - * p Point of type sp_point_384. - * pm Point of type ecc_point (result). - * returns MEMORY_E when allocation of memory in ecc_point fails otherwise - * MP_OKAY. - */ -static int sp_384_point_to_ecc_point_6(const sp_point_384* p, ecc_point* pm) -{ - int err; - - err = sp_384_to_mp(p->x, pm->x); - if (err == MP_OKAY) { - err = sp_384_to_mp(p->y, pm->y); - } - if (err == MP_OKAY) { - err = sp_384_to_mp(p->z, pm->z); - } - - return err; -} - -/* Conditionally copy a into r using the mask m. - * m is -1 to copy and 0 when not. - * - * r A single precision number to copy over. - * a A single precision number to copy. - * m Mask value to apply. - */ -static void sp_384_cond_copy_6(sp_digit* r, const sp_digit* a, sp_digit m) -{ - __asm__ __volatile__ ( - "ldp x3, x4, [%[r], 0]\n\t" - "ldp x5, x6, [%[r], 16]\n\t" - "ldp x7, x8, [%[r], 32]\n\t" - "ldp x9, x10, [%[a], 0]\n\t" - "ldp x11, x12, [%[a], 16]\n\t" - "ldp x13, x14, [%[a], 32]\n\t" - "eor x9, x9, x3\n\t" - "eor x10, x10, x4\n\t" - "eor x11, x11, x5\n\t" - "eor x12, x12, x6\n\t" - "eor x13, x13, x7\n\t" - "eor x14, x14, x8\n\t" - "and x9, x9, %[m]\n\t" - "and x10, x10, %[m]\n\t" - "and x11, x11, %[m]\n\t" - "and x12, x12, %[m]\n\t" - "and x13, x13, %[m]\n\t" - "and x14, x14, %[m]\n\t" - "eor x3, x3, x9\n\t" - "eor x4, x4, x10\n\t" - "eor x5, x5, x11\n\t" - "eor x6, x6, x12\n\t" - "eor x7, x7, x13\n\t" - "eor x8, x8, x14\n\t" - "stp x3, x4, [%[r], 0]\n\t" - "stp x5, x6, [%[r], 16]\n\t" - "stp x7, x8, [%[r], 32]\n\t" - : - : [r] "r" (r), [a] "r" (a), [m] "r" (m) - : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14" - ); -} - #ifdef WOLFSSL_SP_SMALL /* Multiply a and b into r. (r = a * b) * @@ -39078,395 +39724,242 @@ static void sp_384_mul_6(sp_digit* r, const sp_digit* a, const sp_digit* b) */ static void sp_384_mul_6(sp_digit* r, const sp_digit* a, const sp_digit* b) { - sp_digit tmp[6]; - __asm__ __volatile__ ( - "ldp x9, x10, [%[a], 0]\n\t" - "ldp x11, x12, [%[a], 16]\n\t" - "ldp x13, x14, [%[a], 32]\n\t" - "ldp x15, x16, [%[b], 0]\n\t" - "ldp x17, x19, [%[b], 16]\n\t" - "ldp x20, x21, [%[b], 32]\n\t" + "ldp x8, x9, [%[a], 0]\n\t" + "ldp x10, x11, [%[a], 16]\n\t" + "ldp x12, x13, [%[a], 32]\n\t" + "ldp x14, x15, [%[b], 0]\n\t" + "ldp x16, x17, [%[b], 16]\n\t" + "ldp x19, x20, [%[b], 32]\n\t" "# A[0] * B[0]\n\t" - "mul x4, x9, x15\n\t" - "umulh x5, x9, x15\n\t" - "str x4, [%[tmp]]\n\t" + "mul x3, x8, x14\n\t" + "umulh x4, x8, x14\n\t" + "str x3, [%[r]]\n\t" "# A[0] * B[1]\n\t" - "mul x7, x9, x16\n\t" - "umulh x8, x9, x16\n\t" - "adds x5, x5, x7\n\t" + "mul x6, x8, x15\n\t" + "umulh x7, x8, x15\n\t" + "adds x4, x4, x6\n\t" "# A[1] * B[0]\n\t" - "mul x7, x10, x15\n\t" - "adc x6, xzr, x8\n\t" - "umulh x8, x10, x15\n\t" - "adds x5, x5, x7\n\t" - "adcs x6, x6, x8\n\t" - "str x5, [%[tmp], 8]\n\t" - "adc x4, xzr, xzr\n\t" + "mul x6, x9, x14\n\t" + "adc x5, xzr, x7\n\t" + "umulh x7, x9, x14\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "str x4, [%[r], 8]\n\t" + "adc x3, xzr, xzr\n\t" "# A[0] * B[2]\n\t" - "mul x7, x9, x17\n\t" - "umulh x8, x9, x17\n\t" - "adds x6, x6, x7\n\t" + "mul x6, x8, x16\n\t" + "umulh x7, x8, x16\n\t" + "adds x5, x5, x6\n\t" "# A[1] * B[1]\n\t" - "mul x7, x10, x16\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x10, x16\n\t" - "adc x5, xzr, xzr\n\t" - "adds x6, x6, x7\n\t" + "mul x6, x9, x15\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x9, x15\n\t" + "adc x4, xzr, xzr\n\t" + "adds x5, x5, x6\n\t" "# A[2] * B[0]\n\t" - "mul x7, x11, x15\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x11, x15\n\t" - "adc x5, x5, xzr\n\t" - "adds x6, x6, x7\n\t" - "adcs x4, x4, x8\n\t" - "str x6, [%[tmp], 16]\n\t" - "adc x5, x5, xzr\n\t" + "mul x6, x10, x14\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x10, x14\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" + "adcs x3, x3, x7\n\t" + "str x5, [%[r], 16]\n\t" + "adc x4, x4, xzr\n\t" "# A[0] * B[3]\n\t" - "mul x7, x9, x19\n\t" - "umulh x8, x9, x19\n\t" - "adds x4, x4, x7\n\t" + "mul x6, x8, x17\n\t" + "umulh x7, x8, x17\n\t" + "adds x3, x3, x6\n\t" "# A[1] * B[2]\n\t" - "mul x7, x10, x17\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x10, x17\n\t" - "adc x6, xzr, xzr\n\t" - "adds x4, x4, x7\n\t" + "mul x6, x9, x16\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x9, x16\n\t" + "adc x5, xzr, xzr\n\t" + "adds x3, x3, x6\n\t" "# A[2] * B[1]\n\t" - "mul x7, x11, x16\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x11, x16\n\t" - "adc x6, x6, xzr\n\t" - "adds x4, x4, x7\n\t" + "mul x6, x10, x15\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x10, x15\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" "# A[3] * B[0]\n\t" - "mul x7, x12, x15\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x12, x15\n\t" - "adc x6, x6, xzr\n\t" - "adds x4, x4, x7\n\t" - "adcs x5, x5, x8\n\t" - "str x4, [%[tmp], 24]\n\t" - "adc x6, x6, xzr\n\t" + "mul x6, x11, x14\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x11, x14\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" + "adcs x4, x4, x7\n\t" + "str x3, [%[r], 24]\n\t" + "adc x5, x5, xzr\n\t" "# A[0] * B[4]\n\t" - "mul x7, x9, x20\n\t" - "umulh x8, x9, x20\n\t" - "adds x5, x5, x7\n\t" + "mul x6, x8, x19\n\t" + "umulh x7, x8, x19\n\t" + "adds x4, x4, x6\n\t" "# A[1] * B[3]\n\t" - "mul x7, x10, x19\n\t" - "adcs x6, x6, x8\n\t" - "umulh x8, x10, x19\n\t" - "adc x4, xzr, xzr\n\t" - "adds x5, x5, x7\n\t" + "mul x6, x9, x17\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x9, x17\n\t" + "adc x3, xzr, xzr\n\t" + "adds x4, x4, x6\n\t" "# A[2] * B[2]\n\t" - "mul x7, x11, x17\n\t" - "adcs x6, x6, x8\n\t" - "umulh x8, x11, x17\n\t" - "adc x4, x4, xzr\n\t" - "adds x5, x5, x7\n\t" + "mul x6, x10, x16\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x10, x16\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" "# A[3] * B[1]\n\t" - "mul x7, x12, x16\n\t" - "adcs x6, x6, x8\n\t" - "umulh x8, x12, x16\n\t" - "adc x4, x4, xzr\n\t" - "adds x5, x5, x7\n\t" + "mul x6, x11, x15\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x11, x15\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" "# A[4] * B[0]\n\t" - "mul x7, x13, x15\n\t" - "adcs x6, x6, x8\n\t" - "umulh x8, x13, x15\n\t" - "adc x4, x4, xzr\n\t" - "adds x5, x5, x7\n\t" - "adcs x6, x6, x8\n\t" - "str x5, [%[tmp], 32]\n\t" - "adc x4, x4, xzr\n\t" + "mul x6, x12, x14\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x12, x14\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "str x4, [%[r], 32]\n\t" + "adc x3, x3, xzr\n\t" "# A[0] * B[5]\n\t" - "mul x7, x9, x21\n\t" - "umulh x8, x9, x21\n\t" - "adds x6, x6, x7\n\t" + "mul x6, x8, x20\n\t" + "umulh x7, x8, x20\n\t" + "adds x5, x5, x6\n\t" "# A[1] * B[4]\n\t" - "mul x7, x10, x20\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x10, x20\n\t" - "adc x5, xzr, xzr\n\t" - "adds x6, x6, x7\n\t" - "# A[2] * B[3]\n\t" - "mul x7, x11, x19\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x11, x19\n\t" - "adc x5, x5, xzr\n\t" - "adds x6, x6, x7\n\t" - "# A[3] * B[2]\n\t" - "mul x7, x12, x17\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x12, x17\n\t" - "adc x5, x5, xzr\n\t" - "adds x6, x6, x7\n\t" - "# A[4] * B[1]\n\t" - "mul x7, x13, x16\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x13, x16\n\t" - "adc x5, x5, xzr\n\t" - "adds x6, x6, x7\n\t" - "# A[5] * B[0]\n\t" - "mul x7, x14, x15\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x14, x15\n\t" - "adc x5, x5, xzr\n\t" - "adds x6, x6, x7\n\t" - "adcs x4, x4, x8\n\t" - "str x6, [%[tmp], 40]\n\t" - "adc x5, x5, xzr\n\t" - "# A[1] * B[5]\n\t" - "mul x7, x10, x21\n\t" - "umulh x8, x10, x21\n\t" - "adds x4, x4, x7\n\t" - "# A[2] * B[4]\n\t" - "mul x7, x11, x20\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x11, x20\n\t" - "adc x6, xzr, xzr\n\t" - "adds x4, x4, x7\n\t" - "# A[3] * B[3]\n\t" - "mul x7, x12, x19\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x12, x19\n\t" - "adc x6, x6, xzr\n\t" - "adds x4, x4, x7\n\t" - "# A[4] * B[2]\n\t" - "mul x7, x13, x17\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x13, x17\n\t" - "adc x6, x6, xzr\n\t" - "adds x4, x4, x7\n\t" - "# A[5] * B[1]\n\t" - "mul x7, x14, x16\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x14, x16\n\t" - "adc x6, x6, xzr\n\t" - "adds x4, x4, x7\n\t" - "adcs x5, x5, x8\n\t" - "str x4, [%[r], 48]\n\t" - "adc x6, x6, xzr\n\t" - "# A[2] * B[5]\n\t" - "mul x7, x11, x21\n\t" - "umulh x8, x11, x21\n\t" - "adds x5, x5, x7\n\t" - "# A[3] * B[4]\n\t" - "mul x7, x12, x20\n\t" - "adcs x6, x6, x8\n\t" - "umulh x8, x12, x20\n\t" + "mul x6, x9, x19\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x9, x19\n\t" "adc x4, xzr, xzr\n\t" - "adds x5, x5, x7\n\t" - "# A[4] * B[3]\n\t" - "mul x7, x13, x19\n\t" - "adcs x6, x6, x8\n\t" - "umulh x8, x13, x19\n\t" + "adds x5, x5, x6\n\t" + "# A[2] * B[3]\n\t" + "mul x6, x10, x17\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x10, x17\n\t" "adc x4, x4, xzr\n\t" - "adds x5, x5, x7\n\t" - "# A[5] * B[2]\n\t" - "mul x7, x14, x17\n\t" - "adcs x6, x6, x8\n\t" - "umulh x8, x14, x17\n\t" + "adds x5, x5, x6\n\t" + "# A[3] * B[2]\n\t" + "mul x6, x11, x16\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x11, x16\n\t" "adc x4, x4, xzr\n\t" - "adds x5, x5, x7\n\t" - "adcs x6, x6, x8\n\t" - "str x5, [%[r], 56]\n\t" + "adds x5, x5, x6\n\t" + "# A[4] * B[1]\n\t" + "mul x6, x12, x15\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x12, x15\n\t" "adc x4, x4, xzr\n\t" - "# A[3] * B[5]\n\t" - "mul x7, x12, x21\n\t" - "umulh x8, x12, x21\n\t" - "adds x6, x6, x7\n\t" - "# A[4] * B[4]\n\t" - "mul x7, x13, x20\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x13, x20\n\t" + "adds x5, x5, x6\n\t" + "# A[5] * B[0]\n\t" + "mul x6, x13, x14\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x13, x14\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" + "adcs x3, x3, x7\n\t" + "str x5, [%[r], 40]\n\t" + "adc x4, x4, xzr\n\t" + "# A[1] * B[5]\n\t" + "mul x6, x9, x20\n\t" + "umulh x7, x9, x20\n\t" + "adds x3, x3, x6\n\t" + "# A[2] * B[4]\n\t" + "mul x6, x10, x19\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x10, x19\n\t" "adc x5, xzr, xzr\n\t" - "adds x6, x6, x7\n\t" + "adds x3, x3, x6\n\t" + "# A[3] * B[3]\n\t" + "mul x6, x11, x17\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x11, x17\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" + "# A[4] * B[2]\n\t" + "mul x6, x12, x16\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x12, x16\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" + "# A[5] * B[1]\n\t" + "mul x6, x13, x15\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x13, x15\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" + "adcs x4, x4, x7\n\t" + "str x3, [%[r], 48]\n\t" + "adc x5, x5, xzr\n\t" + "# A[2] * B[5]\n\t" + "mul x6, x10, x20\n\t" + "umulh x7, x10, x20\n\t" + "adds x4, x4, x6\n\t" + "# A[3] * B[4]\n\t" + "mul x6, x11, x19\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x11, x19\n\t" + "adc x3, xzr, xzr\n\t" + "adds x4, x4, x6\n\t" + "# A[4] * B[3]\n\t" + "mul x6, x12, x17\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x12, x17\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" + "# A[5] * B[2]\n\t" + "mul x6, x13, x16\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x13, x16\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "str x4, [%[r], 56]\n\t" + "adc x3, x3, xzr\n\t" + "# A[3] * B[5]\n\t" + "mul x6, x11, x20\n\t" + "umulh x7, x11, x20\n\t" + "adds x5, x5, x6\n\t" + "# A[4] * B[4]\n\t" + "mul x6, x12, x19\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x12, x19\n\t" + "adc x4, xzr, xzr\n\t" + "adds x5, x5, x6\n\t" "# A[5] * B[3]\n\t" - "mul x7, x14, x19\n\t" - "adcs x4, x4, x8\n\t" - "umulh x8, x14, x19\n\t" - "adc x5, x5, xzr\n\t" - "adds x6, x6, x7\n\t" - "adcs x4, x4, x8\n\t" - "str x6, [%[r], 64]\n\t" - "adc x5, x5, xzr\n\t" + "mul x6, x13, x17\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x13, x17\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" + "adcs x3, x3, x7\n\t" + "str x5, [%[r], 64]\n\t" + "adc x4, x4, xzr\n\t" "# A[4] * B[5]\n\t" - "mul x7, x13, x21\n\t" - "umulh x8, x13, x21\n\t" - "adds x4, x4, x7\n\t" + "mul x6, x12, x20\n\t" + "umulh x7, x12, x20\n\t" + "adds x3, x3, x6\n\t" "# A[5] * B[4]\n\t" - "mul x7, x14, x20\n\t" - "adcs x5, x5, x8\n\t" - "umulh x8, x14, x20\n\t" - "adc x6, xzr, xzr\n\t" - "adds x4, x4, x7\n\t" - "adcs x5, x5, x8\n\t" - "str x4, [%[r], 72]\n\t" - "adc x6, x6, xzr\n\t" + "mul x6, x13, x19\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x13, x19\n\t" + "adc x5, xzr, xzr\n\t" + "adds x3, x3, x6\n\t" + "adcs x4, x4, x7\n\t" + "str x3, [%[r], 72]\n\t" + "adc x5, x5, xzr\n\t" "# A[5] * B[5]\n\t" - "mul x7, x14, x21\n\t" - "umulh x8, x14, x21\n\t" - "adds x5, x5, x7\n\t" - "adc x6, x6, x8\n\t" - "stp x5, x6, [%[r], 80]\n\t" - "ldp x9, x10, [%[tmp], 0]\n\t" - "ldp x11, x12, [%[tmp], 16]\n\t" - "ldp x13, x14, [%[tmp], 32]\n\t" - "stp x9, x10, [%[r], 0]\n\t" - "stp x11, x12, [%[r], 16]\n\t" - "stp x13, x14, [%[r], 32]\n\t" + "mul x6, x13, x20\n\t" + "umulh x7, x13, x20\n\t" + "adds x4, x4, x6\n\t" + "adc x5, x5, x7\n\t" + "stp x4, x5, [%[r], 80]\n\t" : - : [r] "r" (r), [a] "r" (a), [b] "r" (b), [tmp] "r" (tmp) - : "memory", "x4", "x5", "x6", "x7", "x8", "x9", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21" + : [r] "r" (r), [a] "r" (a), [b] "r" (b) + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20" ); } #endif /* WOLFSSL_SP_SMALL */ -/* Conditionally subtract b from a using the mask m. - * m is -1 to subtract and 0 when not copying. - * - * r A single precision number representing condition subtract result. - * a A single precision number to subtract from. - * b A single precision number to subtract. - * m Mask value to apply. - */ -static sp_digit sp_384_cond_sub_6(sp_digit* r, const sp_digit* a, const sp_digit* b, - sp_digit m) -{ - __asm__ __volatile__ ( - - "ldp x5, x7, [%[b], 0]\n\t" - "ldp x11, x12, [%[b], 16]\n\t" - "ldp x4, x6, [%[a], 0]\n\t" - "and x5, x5, %[m]\n\t" - "ldp x9, x10, [%[a], 16]\n\t" - "and x7, x7, %[m]\n\t" - "subs x4, x4, x5\n\t" - "and x11, x11, %[m]\n\t" - "sbcs x6, x6, x7\n\t" - "and x12, x12, %[m]\n\t" - "sbcs x9, x9, x11\n\t" - "stp x4, x6, [%[r], 0]\n\t" - "sbcs x10, x10, x12\n\t" - "stp x9, x10, [%[r], 16]\n\t" - "ldp x5, x7, [%[b], 32]\n\t" - "ldp x4, x6, [%[a], 32]\n\t" - "and x5, x5, %[m]\n\t" - "and x7, x7, %[m]\n\t" - "sbcs x4, x4, x5\n\t" - "sbcs x6, x6, x7\n\t" - "stp x4, x6, [%[r], 32]\n\t" - "csetm %[r], cc\n\t" - : [r] "+r" (r) - : [a] "r" (a), [b] "r" (b), [m] "r" (m) - : "memory", "x4", "x6", "x5", "x7", "x8", "x9", "x10", "x11", "x12" - ); - - return (sp_digit)r; -} - -#define sp_384_mont_reduce_order_6 sp_384_mont_reduce_6 - -/* Reduce the number back to 384 bits using Montgomery reduction. - * - * a A single precision number to reduce in place. - * m The single precision number representing the modulus. - * mp The digit representing the negative inverse of m mod 2^n. - */ -SP_NOINLINE static void sp_384_mont_reduce_6(sp_digit* a, const sp_digit* m, - sp_digit mp) -{ - sp_digit ca = 0; - - __asm__ __volatile__ ( - "ldp x14, x15, [%[m], 0]\n\t" - "ldp x16, x17, [%[m], 16]\n\t" - "ldp x19, x20, [%[m], 32]\n\t" - "# i = 6\n\t" - "mov x4, 6\n\t" - "ldp x12, x13, [%[a], 0]\n\t" - "\n1:\n\t" - "# mu = a[i] * mp\n\t" - "mul x9, %[mp], x12\n\t" - "# a[i+0] += m[0] * mu\n\t" - "mul x7, x14, x9\n\t" - "umulh x8, x14, x9\n\t" - "adds x12, x12, x7\n\t" - "# a[i+1] += m[1] * mu\n\t" - "mul x7, x15, x9\n\t" - "adc x6, x8, xzr\n\t" - "umulh x8, x15, x9\n\t" - "adds x12, x13, x7\n\t" - "# a[i+2] += m[2] * mu\n\t" - "ldr x13, [%[a], 16]\n\t" - "adc x5, x8, xzr\n\t" - "mul x7, x16, x9\n\t" - "adds x12, x12, x6\n\t" - "umulh x8, x16, x9\n\t" - "adc x5, x5, xzr\n\t" - "adds x13, x13, x7\n\t" - "# a[i+3] += m[3] * mu\n\t" - "ldr x10, [%[a], 24]\n\t" - "adc x6, x8, xzr\n\t" - "mul x7, x17, x9\n\t" - "adds x13, x13, x5\n\t" - "umulh x8, x17, x9\n\t" - "adc x6, x6, xzr\n\t" - "adds x10, x10, x7\n\t" - "# a[i+4] += m[4] * mu\n\t" - "ldr x11, [%[a], 32]\n\t" - "adc x5, x8, xzr\n\t" - "adds x10, x10, x6\n\t" - "mul x7, x19, x9\n\t" - "adc x5, x5, xzr\n\t" - "umulh x8, x19, x9\n\t" - "str x10, [%[a], 24]\n\t" - "adds x11, x11, x7\n\t" - "# a[i+5] += m[5] * mu\n\t" - "ldr x10, [%[a], 40]\n\t" - "adc x6, x8, xzr\n\t" - "adds x11, x11, x5\n\t" - "mul x7, x20, x9\n\t" - "adc x6, x6, xzr\n\t" - "umulh x8, x20, x9\n\t" - "adds x6, x6, x7\n\t" - "adcs x8, x8, %[ca]\n\t" - "str x11, [%[a], 32]\n\t" - "cset %[ca], cs\n\t" - "adds x10, x10, x6\n\t" - "ldr x11, [%[a], 48]\n\t" - "str x10, [%[a], 40]\n\t" - "adcs x11, x11, x8\n\t" - "str x11, [%[a], 48]\n\t" - "adc %[ca], %[ca], xzr\n\t" - "subs x4, x4, 1\n\t" - "add %[a], %[a], 8\n\t" - "bne 1b\n\t" - "stp x12, x13, [%[a], 0]\n\t" - : [ca] "+r" (ca), [a] "+r" (a) - : [m] "r" (m), [mp] "r" (mp) - : "memory", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20" - ); - - sp_384_cond_sub_6(a - 6, a, m, (sp_digit)0 - ca); -} - -/* Multiply two Montogmery form numbers mod the modulus (prime). - * (r = a * b mod m) - * - * r Result of multiplication. - * a First number to multiply in Montogmery form. - * b Second number to multiply in Montogmery form. - * m Modulus (prime). - * mp Montogmery mulitplier. - */ -static void sp_384_mont_mul_6(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) -{ - sp_384_mul_6(r, a, b); - sp_384_mont_reduce_6(r, m, mp); -} - #ifdef WOLFSSL_SP_SMALL /* Square a and put result in r. (r = a * a) * @@ -39683,6 +40176,660 @@ static void sp_384_sqr_6(sp_digit* r, const sp_digit* a) } #endif /* WOLFSSL_SP_SMALL */ +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_384_add_6(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + __asm__ __volatile__ ( + "ldp x3, x4, [%[a], 0]\n\t" + "ldp x7, x8, [%[b], 0]\n\t" + "adds x3, x3, x7\n\t" + "ldp x5, x6, [%[a], 16]\n\t" + "adcs x4, x4, x8\n\t" + "ldp x9, x10, [%[b], 16]\n\t" + "adcs x5, x5, x9\n\t" + "stp x3, x4, [%[r], 0]\n\t" + "adcs x6, x6, x10\n\t" + "stp x5, x6, [%[r], 16]\n\t" + "ldr x3, [%[a], 32]\n\t" + "ldr x4, [%[a], 40]\n\t" + "ldr x7, [%[b], 32]\n\t" + "ldr x8, [%[b], 40]\n\t" + "adcs x3, x3, x7\n\t" + "adcs x4, x4, x8\n\t" + "str x3, [%[r], 32]\n\t" + "str x4, [%[r], 40]\n\t" + "cset %[r], cs\n\t" + : [r] "+r" (r) + : [a] "r" (a), [b] "r" (b) + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10" + ); + + return (sp_digit)r; +} + +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_384_sub_6(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + __asm__ __volatile__ ( + "ldp x3, x4, [%[a], 0]\n\t" + "ldp x7, x8, [%[b], 0]\n\t" + "subs x3, x3, x7\n\t" + "ldp x5, x6, [%[a], 16]\n\t" + "sbcs x4, x4, x8\n\t" + "ldp x9, x10, [%[b], 16]\n\t" + "sbcs x5, x5, x9\n\t" + "stp x3, x4, [%[r], 0]\n\t" + "sbcs x6, x6, x10\n\t" + "stp x5, x6, [%[r], 16]\n\t" + "ldr x3, [%[a], 32]\n\t" + "ldr x4, [%[a], 40]\n\t" + "ldr x7, [%[b], 32]\n\t" + "ldr x8, [%[b], 40]\n\t" + "sbcs x3, x3, x7\n\t" + "sbcs x4, x4, x8\n\t" + "str x3, [%[r], 32]\n\t" + "str x4, [%[r], 40]\n\t" + "csetm %[r], cc\n\t" + : [r] "+r" (r) + : [a] "r" (a), [b] "r" (b) + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10" + ); + + return (sp_digit)r; +} + +/* Create a new point. + * + * heap [in] Buffer to allocate dynamic memory from. + * sp [in] Data for point - only if not allocating. + * p [out] New point. + * returns MEMORY_E when dynamic memory allocation fails and 0 otherwise. + */ +static int sp_384_point_new_ex_6(void* heap, sp_point_384* sp, + sp_point_384** p) +{ + int ret = MP_OKAY; + (void)heap; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + (void)sp; + *p = (sp_point_384*)XMALLOC(sizeof(sp_point_384), heap, DYNAMIC_TYPE_ECC); +#else + *p = sp; +#endif + if (*p == NULL) { + ret = MEMORY_E; + } + return ret; +} + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* Allocate memory for point and return error. */ +#define sp_384_point_new_6(heap, sp, p) sp_384_point_new_ex_6((heap), NULL, &(p)) +#else +/* Set pointer to data and return no error. */ +#define sp_384_point_new_6(heap, sp, p) sp_384_point_new_ex_6((heap), &(sp), &(p)) +#endif + + +/* Free the point. + * + * p [in,out] Point to free. + * clear [in] Indicates whether to zeroize point. + * heap [in] Buffer from which dynamic memory was allocate from. + */ +static void sp_384_point_free_6(sp_point_384* p, int clear, void* heap) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* If valid pointer then clear point data if requested and free data. */ + if (p != NULL) { + if (clear != 0) { + XMEMSET(p, 0, sizeof(*p)); + } + XFREE(p, heap, DYNAMIC_TYPE_ECC); + } +#else +/* Clear point data if requested. */ + if ((p != NULL) && (clear != 0)) { + XMEMSET(p, 0, sizeof(*p)); + } +#endif + (void)heap; +} + +/* Multiply a number by Montogmery normalizer mod modulus (prime). + * + * r The resulting Montgomery form number. + * a The number to convert. + * m The modulus (prime). + * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. + */ +static int sp_384_mod_mul_norm_6(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + int64_t* td; +#else + int64_t td[12]; + int64_t a32d[12]; +#endif + int64_t* t; + int64_t* a32; + int64_t o; + int err = MP_OKAY; + + (void)m; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + td = (int64_t*)XMALLOC(sizeof(int64_t) * 2 * 12, NULL, DYNAMIC_TYPE_ECC); + if (td == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + a32 = td + 12; +#else + t = td; + a32 = a32d; +#endif + + a32[0] = a[0] & 0xffffffff; + a32[1] = a[0] >> 32; + a32[2] = a[1] & 0xffffffff; + a32[3] = a[1] >> 32; + a32[4] = a[2] & 0xffffffff; + a32[5] = a[2] >> 32; + a32[6] = a[3] & 0xffffffff; + a32[7] = a[3] >> 32; + a32[8] = a[4] & 0xffffffff; + a32[9] = a[4] >> 32; + a32[10] = a[5] & 0xffffffff; + a32[11] = a[5] >> 32; + + /* 1 0 0 0 0 0 0 0 1 1 0 -1 */ + t[0] = 0 + a32[0] + a32[8] + a32[9] - a32[11]; + /* -1 1 0 0 0 0 0 0 -1 0 1 1 */ + t[1] = 0 - a32[0] + a32[1] - a32[8] + a32[10] + a32[11]; + /* 0 -1 1 0 0 0 0 0 0 -1 0 1 */ + t[2] = 0 - a32[1] + a32[2] - a32[9] + a32[11]; + /* 1 0 -1 1 0 0 0 0 1 1 -1 -1 */ + t[3] = 0 + a32[0] - a32[2] + a32[3] + a32[8] + a32[9] - a32[10] - a32[11]; + /* 1 1 0 -1 1 0 0 0 1 2 1 -2 */ + t[4] = 0 + a32[0] + a32[1] - a32[3] + a32[4] + a32[8] + 2 * a32[9] + a32[10] - 2 * a32[11]; + /* 0 1 1 0 -1 1 0 0 0 1 2 1 */ + t[5] = 0 + a32[1] + a32[2] - a32[4] + a32[5] + a32[9] + 2 * a32[10] + a32[11]; + /* 0 0 1 1 0 -1 1 0 0 0 1 2 */ + t[6] = 0 + a32[2] + a32[3] - a32[5] + a32[6] + a32[10] + 2 * a32[11]; + /* 0 0 0 1 1 0 -1 1 0 0 0 1 */ + t[7] = 0 + a32[3] + a32[4] - a32[6] + a32[7] + a32[11]; + /* 0 0 0 0 1 1 0 -1 1 0 0 0 */ + t[8] = 0 + a32[4] + a32[5] - a32[7] + a32[8]; + /* 0 0 0 0 0 1 1 0 -1 1 0 0 */ + t[9] = 0 + a32[5] + a32[6] - a32[8] + a32[9]; + /* 0 0 0 0 0 0 1 1 0 -1 1 0 */ + t[10] = 0 + a32[6] + a32[7] - a32[9] + a32[10]; + /* 0 0 0 0 0 0 0 1 1 0 -1 1 */ + t[11] = 0 + a32[7] + a32[8] - a32[10] + a32[11]; + + t[1] += t[0] >> 32; t[0] &= 0xffffffff; + t[2] += t[1] >> 32; t[1] &= 0xffffffff; + t[3] += t[2] >> 32; t[2] &= 0xffffffff; + t[4] += t[3] >> 32; t[3] &= 0xffffffff; + t[5] += t[4] >> 32; t[4] &= 0xffffffff; + t[6] += t[5] >> 32; t[5] &= 0xffffffff; + t[7] += t[6] >> 32; t[6] &= 0xffffffff; + t[8] += t[7] >> 32; t[7] &= 0xffffffff; + t[9] += t[8] >> 32; t[8] &= 0xffffffff; + t[10] += t[9] >> 32; t[9] &= 0xffffffff; + t[11] += t[10] >> 32; t[10] &= 0xffffffff; + o = t[11] >> 32; t[11] &= 0xffffffff; + t[0] += o; + t[1] -= o; + t[3] += o; + t[4] += o; + t[1] += t[0] >> 32; t[0] &= 0xffffffff; + t[2] += t[1] >> 32; t[1] &= 0xffffffff; + t[3] += t[2] >> 32; t[2] &= 0xffffffff; + t[4] += t[3] >> 32; t[3] &= 0xffffffff; + t[5] += t[4] >> 32; t[4] &= 0xffffffff; + t[6] += t[5] >> 32; t[5] &= 0xffffffff; + t[7] += t[6] >> 32; t[6] &= 0xffffffff; + t[8] += t[7] >> 32; t[7] &= 0xffffffff; + t[9] += t[8] >> 32; t[8] &= 0xffffffff; + t[10] += t[9] >> 32; t[9] &= 0xffffffff; + t[11] += t[10] >> 32; t[10] &= 0xffffffff; + + r[0] = (t[1] << 32) | t[0]; + r[1] = (t[3] << 32) | t[2]; + r[2] = (t[5] << 32) | t[4]; + r[3] = (t[7] << 32) | t[6]; + r[4] = (t[9] << 32) | t[8]; + r[5] = (t[11] << 32) | t[10]; + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) + XFREE(td, NULL, DYNAMIC_TYPE_ECC); +#endif + + return err; +} + +/* Convert an mp_int to an array of sp_digit. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a A multi-precision integer. + */ +static void sp_384_from_mp(sp_digit* r, int size, const mp_int* a) +{ +#if DIGIT_BIT == 64 + int j; + + XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); + + for (j = a->used; j < size; j++) { + r[j] = 0; + } +#elif DIGIT_BIT > 64 + int i; + int j = 0; + word32 s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i] << s); + r[j] &= 0xffffffffffffffffl; + s = 64U - s; + if (j + 1 >= size) { + break; + } + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + while ((s + 64U) <= (word32)DIGIT_BIT) { + s += 64U; + r[j] &= 0xffffffffffffffffl; + if (j + 1 >= size) { + break; + } + if (s < (word32)DIGIT_BIT) { + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + } + else { + r[++j] = 0L; + } + } + s = (word32)DIGIT_BIT - s; + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#else + int i; + int j = 0; + int s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i]) << s; + if (s + DIGIT_BIT >= 64) { + r[j] &= 0xffffffffffffffffl; + if (j + 1 >= size) { + break; + } + s = 64 - s; + if (s == DIGIT_BIT) { + r[++j] = 0; + s = 0; + } + else { + r[++j] = a->dp[i] >> s; + s = DIGIT_BIT - s; + } + } + else { + s += DIGIT_BIT; + } + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#endif +} + +/* Convert a point of type ecc_point to type sp_point_384. + * + * p Point of type sp_point_384 (result). + * pm Point of type ecc_point. + */ +static void sp_384_point_from_ecc_point_6(sp_point_384* p, + const ecc_point* pm) +{ + XMEMSET(p->x, 0, sizeof(p->x)); + XMEMSET(p->y, 0, sizeof(p->y)); + XMEMSET(p->z, 0, sizeof(p->z)); + sp_384_from_mp(p->x, 6, pm->x); + sp_384_from_mp(p->y, 6, pm->y); + sp_384_from_mp(p->z, 6, pm->z); + p->infinity = 0; +} + +/* Convert an array of sp_digit to an mp_int. + * + * a A single precision integer. + * r A multi-precision integer. + */ +static int sp_384_to_mp(const sp_digit* a, mp_int* r) +{ + int err; + + err = mp_grow(r, (384 + DIGIT_BIT - 1) / DIGIT_BIT); + if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ +#if DIGIT_BIT == 64 + XMEMCPY(r->dp, a, sizeof(sp_digit) * 6); + r->used = 6; + mp_clamp(r); +#elif DIGIT_BIT < 64 + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 6; i++) { + r->dp[j] |= (mp_digit)(a[i] << s); + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + s = DIGIT_BIT - s; + r->dp[++j] = (mp_digit)(a[i] >> s); + while (s + DIGIT_BIT <= 64) { + s += DIGIT_BIT; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; + if (s == SP_WORD_SIZE) { + r->dp[j] = 0; + } + else { + r->dp[j] = (mp_digit)(a[i] >> s); + } + } + s = 64 - s; + } + r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#else + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 6; i++) { + r->dp[j] |= ((mp_digit)a[i]) << s; + if (s + 64 >= DIGIT_BIT) { + #if DIGIT_BIT != 32 && DIGIT_BIT != 64 + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + #endif + s = DIGIT_BIT - s; + r->dp[++j] = a[i] >> s; + s = 64 - s; + } + else { + s += 64; + } + } + r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#endif + } + + return err; +} + +/* Convert a point of type sp_point_384 to type ecc_point. + * + * p Point of type sp_point_384. + * pm Point of type ecc_point (result). + * returns MEMORY_E when allocation of memory in ecc_point fails otherwise + * MP_OKAY. + */ +static int sp_384_point_to_ecc_point_6(const sp_point_384* p, ecc_point* pm) +{ + int err; + + err = sp_384_to_mp(p->x, pm->x); + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, pm->y); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, pm->z); + } + + return err; +} + +/* Conditionally copy a into r using the mask m. + * m is -1 to copy and 0 when not. + * + * r A single precision number to copy over. + * a A single precision number to copy. + * m Mask value to apply. + */ +static void sp_384_cond_copy_6(sp_digit* r, const sp_digit* a, sp_digit m) +{ + __asm__ __volatile__ ( + "ldp x3, x4, [%[r], 0]\n\t" + "ldp x5, x6, [%[r], 16]\n\t" + "ldp x7, x8, [%[r], 32]\n\t" + "ldp x9, x10, [%[a], 0]\n\t" + "ldp x11, x12, [%[a], 16]\n\t" + "ldp x13, x14, [%[a], 32]\n\t" + "eor x9, x9, x3\n\t" + "eor x10, x10, x4\n\t" + "eor x11, x11, x5\n\t" + "eor x12, x12, x6\n\t" + "eor x13, x13, x7\n\t" + "eor x14, x14, x8\n\t" + "and x9, x9, %[m]\n\t" + "and x10, x10, %[m]\n\t" + "and x11, x11, %[m]\n\t" + "and x12, x12, %[m]\n\t" + "and x13, x13, %[m]\n\t" + "and x14, x14, %[m]\n\t" + "eor x3, x3, x9\n\t" + "eor x4, x4, x10\n\t" + "eor x5, x5, x11\n\t" + "eor x6, x6, x12\n\t" + "eor x7, x7, x13\n\t" + "eor x8, x8, x14\n\t" + "stp x3, x4, [%[r], 0]\n\t" + "stp x5, x6, [%[r], 16]\n\t" + "stp x7, x8, [%[r], 32]\n\t" + : + : [r] "r" (r), [a] "r" (a), [m] "r" (m) + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14" + ); +} + +/* Conditionally subtract b from a using the mask m. + * m is -1 to subtract and 0 when not copying. + * + * r A single precision number representing condition subtract result. + * a A single precision number to subtract from. + * b A single precision number to subtract. + * m Mask value to apply. + */ +static sp_digit sp_384_cond_sub_6(sp_digit* r, const sp_digit* a, const sp_digit* b, + sp_digit m) +{ + __asm__ __volatile__ ( + + "ldp x5, x7, [%[b], 0]\n\t" + "ldp x11, x12, [%[b], 16]\n\t" + "ldp x4, x6, [%[a], 0]\n\t" + "and x5, x5, %[m]\n\t" + "ldp x9, x10, [%[a], 16]\n\t" + "and x7, x7, %[m]\n\t" + "subs x4, x4, x5\n\t" + "and x11, x11, %[m]\n\t" + "sbcs x6, x6, x7\n\t" + "and x12, x12, %[m]\n\t" + "sbcs x9, x9, x11\n\t" + "stp x4, x6, [%[r], 0]\n\t" + "sbcs x10, x10, x12\n\t" + "stp x9, x10, [%[r], 16]\n\t" + "ldp x5, x7, [%[b], 32]\n\t" + "ldp x4, x6, [%[a], 32]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "sbcs x4, x4, x5\n\t" + "sbcs x6, x6, x7\n\t" + "stp x4, x6, [%[r], 32]\n\t" + "csetm %[r], cc\n\t" + : [r] "+r" (r) + : [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "x4", "x6", "x5", "x7", "x8", "x9", "x10", "x11", "x12" + ); + + return (sp_digit)r; +} + +#define sp_384_mont_reduce_order_6 sp_384_mont_reduce_6 + +/* Reduce the number back to 384 bits using Montgomery reduction. + * + * a A single precision number to reduce in place. + * m The single precision number representing the modulus. + * mp The digit representing the negative inverse of m mod 2^n. + */ +SP_NOINLINE static void sp_384_mont_reduce_6(sp_digit* a, const sp_digit* m, + sp_digit mp) +{ + + __asm__ __volatile__ ( + "ldp x14, x15, [%[m], 0]\n\t" + "ldp x16, x17, [%[m], 16]\n\t" + "ldp x19, x20, [%[m], 32]\n\t" + "mov x3, xzr\n\t" + "# i = 6\n\t" + "mov x4, 6\n\t" + "ldp x12, x13, [%[a], 0]\n\t" + "\n1:\n\t" + "# mu = a[i] * mp\n\t" + "mul x9, %[mp], x12\n\t" + "# a[i+0] += m[0] * mu\n\t" + "mul x7, x14, x9\n\t" + "umulh x8, x14, x9\n\t" + "adds x12, x12, x7\n\t" + "# a[i+1] += m[1] * mu\n\t" + "mul x7, x15, x9\n\t" + "adc x6, x8, xzr\n\t" + "umulh x8, x15, x9\n\t" + "adds x12, x13, x7\n\t" + "# a[i+2] += m[2] * mu\n\t" + "ldr x13, [%[a], 16]\n\t" + "adc x5, x8, xzr\n\t" + "mul x7, x16, x9\n\t" + "adds x12, x12, x6\n\t" + "umulh x8, x16, x9\n\t" + "adc x5, x5, xzr\n\t" + "adds x13, x13, x7\n\t" + "# a[i+3] += m[3] * mu\n\t" + "ldr x10, [%[a], 24]\n\t" + "adc x6, x8, xzr\n\t" + "mul x7, x17, x9\n\t" + "adds x13, x13, x5\n\t" + "umulh x8, x17, x9\n\t" + "adc x6, x6, xzr\n\t" + "adds x10, x10, x7\n\t" + "# a[i+4] += m[4] * mu\n\t" + "ldr x11, [%[a], 32]\n\t" + "adc x5, x8, xzr\n\t" + "adds x10, x10, x6\n\t" + "mul x7, x19, x9\n\t" + "adc x5, x5, xzr\n\t" + "umulh x8, x19, x9\n\t" + "str x10, [%[a], 24]\n\t" + "adds x11, x11, x7\n\t" + "# a[i+5] += m[5] * mu\n\t" + "ldr x10, [%[a], 40]\n\t" + "adc x6, x8, xzr\n\t" + "adds x11, x11, x5\n\t" + "mul x7, x20, x9\n\t" + "adc x6, x6, xzr\n\t" + "umulh x8, x20, x9\n\t" + "adds x6, x6, x7\n\t" + "adcs x8, x8, x3\n\t" + "str x11, [%[a], 32]\n\t" + "cset x3, cs\n\t" + "adds x10, x10, x6\n\t" + "ldr x11, [%[a], 48]\n\t" + "str x10, [%[a], 40]\n\t" + "adcs x11, x11, x8\n\t" + "str x11, [%[a], 48]\n\t" + "adc x3, x3, xzr\n\t" + "subs x4, x4, 1\n\t" + "add %[a], %[a], 8\n\t" + "bne 1b\n\t" + "# x12 and x13 hold a[0] and a[1]\n\t" + "# Create mask\n\t" + "neg x3, x3\n\t" + "mov x9, %[a]\n\t" + "sub %[a], %[a], 48\n\t" + "# Subtract masked modulus\n\t" + "# x12 and x13 hold a[0] and a[1]\n\t" + "and x14, x14, x3\n\t" + "ldp x11, x10, [x9, 16]\n\t" + "and x15, x15, x3\n\t" + "subs x12, x12, x14\n\t" + "and x16, x16, x3\n\t" + "sbcs x13, x13, x15\n\t" + "and x17, x17, x3\n\t" + "sbcs x11, x11, x16\n\t" + "stp x12, x13, [%[a], 0]\n\t" + "sbcs x10, x10, x17\n\t" + "stp x11, x10, [%[a], 16]\n\t" + "ldp x12, x13, [x9, 32]\n\t" + "and x19, x19, x3\n\t" + "and x20, x20, x3\n\t" + "sbcs x12, x12, x19\n\t" + "sbcs x13, x13, x20\n\t" + "stp x12, x13, [%[a], 32]\n\t" + : [a] "+r" (a) + : [m] "r" (m), [mp] "r" (mp) + : "memory", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20" + ); + +} + +/* Multiply two Montogmery form numbers mod the modulus (prime). + * (r = a * b mod m) + * + * r Result of multiplication. + * a First number to multiply in Montogmery form. + * b Second number to multiply in Montogmery form. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_384_mont_mul_6(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) +{ + sp_384_mul_6(r, a, b); + sp_384_mont_reduce_6(r, m, mp); +} + /* Square the Montgomery form number. (r = a * a mod m) * * r Result of squaring. @@ -39690,8 +40837,8 @@ static void sp_384_sqr_6(sp_digit* r, const sp_digit* a) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_384_mont_sqr_6(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_384_mont_sqr_6(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_384_sqr_6(r, a); sp_384_mont_reduce_6(r, m, mp); @@ -39715,7 +40862,7 @@ static void sp_384_mont_sqr_n_6(sp_digit* r, const sp_digit* a, int n, } } -#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */ +#endif /* !WOLFSSL_SP_SMALL | HAVE_COMP_KEY */ #ifdef WOLFSSL_SP_SMALL /* Mod-2 for the P384 curve. */ static const uint64_t p384_mod_minus_2[6] = { @@ -39909,7 +41056,8 @@ static int64_t sp_384_cmp_6(const sp_digit* a, const sp_digit* b) * p Montgomery form projective coordinate point. * t Temporary ordinate data. */ -static void sp_384_map_6(sp_point_384* r, const sp_point_384* p, sp_digit* t) +static void sp_384_map_6(sp_point_384* r, const sp_point_384* p, + sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2*6; @@ -39945,43 +41093,6 @@ static void sp_384_map_6(sp_point_384* r, const sp_point_384* p, sp_digit* t) } -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -static sp_digit sp_384_add_6(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - __asm__ __volatile__ ( - "ldp x3, x4, [%[a], 0]\n\t" - "ldp x7, x8, [%[b], 0]\n\t" - "adds x3, x3, x7\n\t" - "ldp x5, x6, [%[a], 16]\n\t" - "adcs x4, x4, x8\n\t" - "ldp x9, x10, [%[b], 16]\n\t" - "adcs x5, x5, x9\n\t" - "stp x3, x4, [%[r], 0]\n\t" - "adcs x6, x6, x10\n\t" - "stp x5, x6, [%[r], 16]\n\t" - "ldr x3, [%[a], 32]\n\t" - "ldr x4, [%[a], 40]\n\t" - "ldr x7, [%[b], 32]\n\t" - "ldr x8, [%[b], 40]\n\t" - "adcs x3, x3, x7\n\t" - "adcs x4, x4, x8\n\t" - "str x3, [%[r], 32]\n\t" - "str x4, [%[r], 40]\n\t" - "cset %[r], cs\n\t" - : [r] "+r" (r) - : [a] "r" (a), [b] "r" (b) - : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10" - ); - - return (sp_digit)r; -} - /* Add two Montgomery form numbers (r = a + b % m). * * r Result of addition. @@ -40028,43 +41139,6 @@ static void sp_384_mont_tpl_6(sp_digit* r, const sp_digit* a, const sp_digit* m) sp_384_cond_sub_6(r, r, m, 0 - o); } -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -static sp_digit sp_384_sub_6(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - __asm__ __volatile__ ( - "ldp x3, x4, [%[a], 0]\n\t" - "ldp x7, x8, [%[b], 0]\n\t" - "subs x3, x3, x7\n\t" - "ldp x5, x6, [%[a], 16]\n\t" - "sbcs x4, x4, x8\n\t" - "ldp x9, x10, [%[b], 16]\n\t" - "sbcs x5, x5, x9\n\t" - "stp x3, x4, [%[r], 0]\n\t" - "sbcs x6, x6, x10\n\t" - "stp x5, x6, [%[r], 16]\n\t" - "ldr x3, [%[a], 32]\n\t" - "ldr x4, [%[a], 40]\n\t" - "ldr x7, [%[b], 32]\n\t" - "ldr x8, [%[b], 40]\n\t" - "sbcs x3, x3, x7\n\t" - "sbcs x4, x4, x8\n\t" - "str x3, [%[r], 32]\n\t" - "str x4, [%[r], 40]\n\t" - "csetm %[r], cc\n\t" - : [r] "+r" (r) - : [a] "r" (a), [b] "r" (b) - : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10" - ); - - return (sp_digit)r; -} - /* Conditionally add a and b using the mask m. * m is -1 to add and 0 when not. * @@ -40391,7 +41465,8 @@ static void sp_384_proj_point_dbl_6(sp_point_384* r, const sp_point_384* p, sp_d * n Number of times to double * t Temporary ordinate data. */ -static void sp_384_proj_point_dbl_n_6(sp_point_384* p, int n, sp_digit* t) +static void sp_384_proj_point_dbl_n_6(sp_point_384* p, int n, + sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*6; @@ -40695,8 +41770,8 @@ static int sp_384_proj_point_add_6_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r, } #endif /* WOLFSSL_SP_NONBLOCK */ -static void sp_384_proj_point_add_6(sp_point_384* r, const sp_point_384* p, const sp_point_384* q, - sp_digit* t) +static void sp_384_proj_point_add_6(sp_point_384* r, + const sp_point_384* p, const sp_point_384* q, sp_digit* t) { const sp_point_384* ap[2]; sp_point_384* rp[2]; @@ -40789,8 +41864,8 @@ static void sp_384_proj_point_add_6(sp_point_384* r, const sp_point_384* p, cons * n Number of times to double * t Temporary ordinate data. */ -static void sp_384_proj_point_dbl_n_store_6(sp_point_384* r, const sp_point_384* p, - int n, int m, sp_digit* t) +static void sp_384_proj_point_dbl_n_store_6(sp_point_384* r, + const sp_point_384* p, int n, int m, sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*6; @@ -40801,6 +41876,7 @@ static void sp_384_proj_point_dbl_n_store_6(sp_point_384* r, const sp_point_384* sp_digit* y = r[(1<x[i]; @@ -40817,7 +41893,10 @@ static void sp_384_proj_point_dbl_n_store_6(sp_point_384* r, const sp_point_384* /* W = Z^4 */ sp_384_mont_sqr_6(w, z, p384_mod, p384_mp_mod); sp_384_mont_sqr_6(w, w, p384_mod, p384_mp_mod); + j = m; for (i=1; i<=n; i++) { + j *= 2; + /* A = 3*(X^2 - W) */ sp_384_mont_sqr_6(t1, x, p384_mod, p384_mp_mod); sp_384_mont_sub_6(t1, t1, w, p384_mod); @@ -40825,14 +41904,14 @@ static void sp_384_proj_point_dbl_n_store_6(sp_point_384* r, const sp_point_384* /* B = X*Y^2 */ sp_384_mont_sqr_6(t2, y, p384_mod, p384_mp_mod); sp_384_mont_mul_6(b, t2, x, p384_mod, p384_mp_mod); - x = r[(1<y); + sp_384_norm_6(negy); sp_384_cond_copy_6(p->y, negy, (sp_digit)0 - v[i].neg); sp_384_proj_point_add_6(rt, rt, p, tmp); } @@ -41200,14 +42283,15 @@ static int sp_384_ecc_mulmod_win_add_sub_6(sp_point_384* r, const sp_point_384* return err; } +#ifndef WC_NO_CACHE_RESISTANT /* A table entry for pre-computed points. */ typedef struct sp_table_entry_384 { sp_digit x[6]; sp_digit y[6]; } sp_table_entry_384; -#ifdef FP_ECC -#endif /* FP_ECC */ +#if defined(FP_ECC) || defined(WOLFSSL_SP_SMALL) +#endif /* FP_ECC | WOLFSSL_SP_SMALL */ /* Add two Montgomery form projective points. The second point has a q value of * one. * Only the first point can be the same pointer as the result point. @@ -41314,6 +42398,10 @@ static void sp_384_proj_to_affine_6(sp_point_384* a, sp_digit* t) } /* Generate the pre-computed table of points for the base point. + * + * width = 6 + * 64 entries + * 64 bits between * * a The base point. * table Place to store generated point data. @@ -41324,12 +42412,15 @@ static int sp_384_gen_stripe_table_6(const sp_point_384* a, sp_table_entry_384* table, sp_digit* tmp, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_point_384 td, s1d, s2d; + sp_point_384 td; + sp_point_384 s1d; + sp_point_384 s2d; #endif sp_point_384* t; sp_point_384* s1 = NULL; sp_point_384* s2 = NULL; - int i, j; + int i; + int j; int err; (void)heap; @@ -41366,14 +42457,14 @@ static int sp_384_gen_stripe_table_6(const sp_point_384* a, XMEMCPY(table[1].x, t->x, sizeof(table->x)); XMEMCPY(table[1].y, t->y, sizeof(table->y)); - for (i=1; i<8; i++) { - sp_384_proj_point_dbl_n_6(t, 48, tmp); + for (i=1; i<6; i++) { + sp_384_proj_point_dbl_n_6(t, 64, tmp); sp_384_proj_to_affine_6(t, tmp); XMEMCPY(table[1<x, sizeof(table->x)); XMEMCPY(table[1<y, sizeof(table->y)); } - for (i=1; i<8; i++) { + for (i=1; i<6; i++) { XMEMCPY(s1->x, table[1<x)); XMEMCPY(s1->y, table[1<y)); for (j=(1<y[3] = 0; r->y[4] = 0; r->y[5] = 0; - for (i = 1; i < 256; i++) { + for (i = 1; i < 64; i++) { mask = 0 - (i == idx); r->x[0] |= mask & table[i].x[0]; r->x[1] |= mask & table[i].x[1]; @@ -41440,8 +42532,10 @@ static void sp_384_get_entry_256_6(sp_point_384* r, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Implementation uses striping of bits. - * Choose bits 8 bits apart. + * Stripe implementation. + * Pre-generated: 2^0, 2^64, ... + * Pre-generated: products of all combinations of above. + * 6 doubles and adds (with qz=1) * * r Resulting point. * k Scalar to multiply by. @@ -41463,8 +42557,10 @@ static int sp_384_ecc_mulmod_stripe_6(sp_point_384* r, const sp_point_384* g, sp_point_384* rt; sp_point_384* p = NULL; sp_digit* t; - int i, j; - int y, x; + int i; + int j; + int y; + int x; int err; (void)g; @@ -41492,12 +42588,14 @@ static int sp_384_ecc_mulmod_stripe_6(sp_point_384* r, const sp_point_384* g, XMEMCPY(rt->z, p384_norm_mod, sizeof(p384_norm_mod)); y = 0; - for (j=0,x=47; j<8; j++,x+=48) { + x = 63; + for (j=0; j<6; j++) { y |= (int)(((k[x / 64] >> (x % 64)) & 1) << j); + x += 64; } #ifndef WC_NO_CACHE_RESISTANT if (ct) { - sp_384_get_entry_256_6(rt, table, y); + sp_384_get_entry_64_6(rt, table, y); } else #endif { @@ -41505,16 +42603,18 @@ static int sp_384_ecc_mulmod_stripe_6(sp_point_384* r, const sp_point_384* g, XMEMCPY(rt->y, table[y].y, sizeof(table[y].y)); } rt->infinity = !y; - for (i=46; i>=0; i--) { + for (i=62; i>=0; i--) { y = 0; - for (j=0,x=i; j<8; j++,x+=48) { + x = i; + for (j=0; j<6; j++) { y |= (int)(((k[x / 64] >> (x % 64)) & 1) << j); + x += 64; } sp_384_proj_point_dbl_6(rt, rt, t); #ifndef WC_NO_CACHE_RESISTANT if (ct) { - sp_384_get_entry_256_6(p, table, y); + sp_384_get_entry_64_6(p, table, y); } else #endif @@ -41545,21 +42645,31 @@ static int sp_384_ecc_mulmod_stripe_6(sp_point_384* r, const sp_point_384* g, return err; } +#endif /* FP_ECC | WOLFSSL_SP_SMALL */ #ifdef FP_ECC #ifndef FP_ENTRIES #define FP_ENTRIES 16 #endif +/* Cache entry - holds precomputation tables for a point. */ typedef struct sp_cache_384_t { + /* X ordinate of point that table was generated from. */ sp_digit x[6]; + /* Y ordinate of point that table was generated from. */ sp_digit y[6]; - sp_table_entry_384 table[256]; + /* Precomputation table for point. */ + sp_table_entry_384 table[64]; + /* Count of entries in table. */ uint32_t cnt; + /* Point and table set in entry. */ int set; } sp_cache_384_t; +/* Cache of tables. */ static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES]; +/* Index of last entry in cache. */ static THREAD_LS_T int sp_cache_384_last = -1; +/* Cache has been initialized. */ static THREAD_LS_T int sp_cache_384_inited = 0; #ifndef HAVE_THREAD_LS @@ -41567,9 +42677,15 @@ static THREAD_LS_T int sp_cache_384_inited = 0; static wolfSSL_Mutex sp_cache_384_lock; #endif +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache) { - int i, j; + int i; + int j; uint32_t least; if (sp_cache_384_inited == 0) { @@ -41675,6 +42791,405 @@ static int sp_384_ecc_mulmod_6(sp_point_384* r, const sp_point_384* g, const sp_ #endif } +#else +#if defined(FP_ECC) || defined(WOLFSSL_SP_SMALL) +#endif /* FP_ECC | WOLFSSL_SP_SMALL */ +#ifdef FP_ECC +/* Generate the pre-computed table of points for the base point. + * + * width = 8 + * 256 entries + * 48 bits between + * + * a The base point. + * table Place to store generated point data. + * tmp Temporary data. + * heap Heap to use for allocation. + */ +static int sp_384_gen_stripe_table_6(const sp_point_384* a, + sp_table_entry_384* table, sp_digit* tmp, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_384 td; + sp_point_384 s1d; + sp_point_384 s2d; +#endif + sp_point_384* t; + sp_point_384* s1 = NULL; + sp_point_384* s2 = NULL; + int i; + int j; + int err; + + (void)heap; + + err = sp_384_point_new_6(heap, td, t); + if (err == MP_OKAY) { + err = sp_384_point_new_6(heap, s1d, s1); + } + if (err == MP_OKAY) { + err = sp_384_point_new_6(heap, s2d, s2); + } + + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_6(t->x, a->x, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_6(t->y, a->y, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_6(t->z, a->z, p384_mod); + } + if (err == MP_OKAY) { + t->infinity = 0; + sp_384_proj_to_affine_6(t, tmp); + + XMEMCPY(s1->z, p384_norm_mod, sizeof(p384_norm_mod)); + s1->infinity = 0; + XMEMCPY(s2->z, p384_norm_mod, sizeof(p384_norm_mod)); + s2->infinity = 0; + + /* table[0] = {0, 0, infinity} */ + XMEMSET(&table[0], 0, sizeof(sp_table_entry_384)); + /* table[1] = Affine version of 'a' in Montgomery form */ + XMEMCPY(table[1].x, t->x, sizeof(table->x)); + XMEMCPY(table[1].y, t->y, sizeof(table->y)); + + for (i=1; i<8; i++) { + sp_384_proj_point_dbl_n_6(t, 48, tmp); + sp_384_proj_to_affine_6(t, tmp); + XMEMCPY(table[1<x, sizeof(table->x)); + XMEMCPY(table[1<y, sizeof(table->y)); + } + + for (i=1; i<8; i++) { + XMEMCPY(s1->x, table[1<x)); + XMEMCPY(s1->y, table[1<y)); + for (j=(1<x, table[j-(1<x)); + XMEMCPY(s2->y, table[j-(1<y)); + sp_384_proj_point_add_qz1_6(t, s1, s2, tmp); + sp_384_proj_to_affine_6(t, tmp); + XMEMCPY(table[j].x, t->x, sizeof(table->x)); + XMEMCPY(table[j].y, t->y, sizeof(table->y)); + } + } + } + + sp_384_point_free_6(s2, 0, heap); + sp_384_point_free_6(s1, 0, heap); + sp_384_point_free_6( t, 0, heap); + + return err; +} + +#endif /* FP_ECC */ +#if defined(FP_ECC) || defined(WOLFSSL_SP_SMALL) +#ifndef WC_NO_CACHE_RESISTANT +/* Touch each possible entry that could be being copied. + * + * r Point to copy into. + * table Table - start of the entires to access + * idx Index of entry to retrieve. + */ +static void sp_384_get_entry_256_6(sp_point_384* r, + const sp_table_entry_384* table, int idx) +{ + int i; + sp_digit mask; + + r->x[0] = 0; + r->x[1] = 0; + r->x[2] = 0; + r->x[3] = 0; + r->x[4] = 0; + r->x[5] = 0; + r->y[0] = 0; + r->y[1] = 0; + r->y[2] = 0; + r->y[3] = 0; + r->y[4] = 0; + r->y[5] = 0; + for (i = 1; i < 256; i++) { + mask = 0 - (i == idx); + r->x[0] |= mask & table[i].x[0]; + r->x[1] |= mask & table[i].x[1]; + r->x[2] |= mask & table[i].x[2]; + r->x[3] |= mask & table[i].x[3]; + r->x[4] |= mask & table[i].x[4]; + r->x[5] |= mask & table[i].x[5]; + r->y[0] |= mask & table[i].y[0]; + r->y[1] |= mask & table[i].y[1]; + r->y[2] |= mask & table[i].y[2]; + r->y[3] |= mask & table[i].y[3]; + r->y[4] |= mask & table[i].y[4]; + r->y[5] |= mask & table[i].y[5]; + } +} +#endif /* !WC_NO_CACHE_RESISTANT */ +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^48, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * table Pre-computed table. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_stripe_6(sp_point_384* r, const sp_point_384* g, + const sp_table_entry_384* table, const sp_digit* k, int map, + int ct, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_384 rtd; + sp_point_384 pd; + sp_digit td[2 * 6 * 6]; +#endif + sp_point_384* rt; + sp_point_384* p = NULL; + sp_digit* t; + int i; + int j; + int y; + int x; + int err; + + (void)g; + /* Constant time used for cache attack resistance implementation. */ + (void)ct; + (void)heap; + + + err = sp_384_point_new_6(heap, rtd, rt); + if (err == MP_OKAY) { + err = sp_384_point_new_6(heap, pd, p); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 6 * 6, heap, + DYNAMIC_TYPE_ECC); + if (t == NULL) { + err = MEMORY_E; + } +#else + t = td; +#endif + + if (err == MP_OKAY) { + XMEMCPY(p->z, p384_norm_mod, sizeof(p384_norm_mod)); + XMEMCPY(rt->z, p384_norm_mod, sizeof(p384_norm_mod)); + + y = 0; + x = 47; + for (j=0; j<8; j++) { + y |= (int)(((k[x / 64] >> (x % 64)) & 1) << j); + x += 48; + } + #ifndef WC_NO_CACHE_RESISTANT + if (ct) { + sp_384_get_entry_256_6(rt, table, y); + } else + #endif + { + XMEMCPY(rt->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(rt->y, table[y].y, sizeof(table[y].y)); + } + rt->infinity = !y; + for (i=46; i>=0; i--) { + y = 0; + x = i; + for (j=0; j<8; j++) { + y |= (int)(((k[x / 64] >> (x % 64)) & 1) << j); + x += 48; + } + + sp_384_proj_point_dbl_6(rt, rt, t); + #ifndef WC_NO_CACHE_RESISTANT + if (ct) { + sp_384_get_entry_256_6(p, table, y); + } + else + #endif + { + XMEMCPY(p->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(p->y, table[y].y, sizeof(table[y].y)); + } + p->infinity = !y; + sp_384_proj_point_add_qz1_6(rt, rt, p, t); + } + + if (map != 0) { + sp_384_map_6(r, rt, t); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_384)); + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (t != NULL) { + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_6(p, 0, heap); + sp_384_point_free_6(rt, 0, heap); + + return err; +} + +#endif /* FP_ECC | WOLFSSL_SP_SMALL */ +#ifdef FP_ECC +#ifndef FP_ENTRIES + #define FP_ENTRIES 16 +#endif + +/* Cache entry - holds precomputation tables for a point. */ +typedef struct sp_cache_384_t { + /* X ordinate of point that table was generated from. */ + sp_digit x[6]; + /* Y ordinate of point that table was generated from. */ + sp_digit y[6]; + /* Precomputation table for point. */ + sp_table_entry_384 table[256]; + /* Count of entries in table. */ + uint32_t cnt; + /* Point and table set in entry. */ + int set; +} sp_cache_384_t; + +/* Cache of tables. */ +static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES]; +/* Index of last entry in cache. */ +static THREAD_LS_T int sp_cache_384_last = -1; +/* Cache has been initialized. */ +static THREAD_LS_T int sp_cache_384_inited = 0; + +#ifndef HAVE_THREAD_LS + static volatile int initCacheMutex_384 = 0; + static wolfSSL_Mutex sp_cache_384_lock; +#endif + +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ +static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache) +{ + int i; + int j; + uint32_t least; + + if (sp_cache_384_inited == 0) { + for (i=0; ix, sp_cache_384[i].x) & + sp_384_cmp_equal_6(g->y, sp_cache_384[i].y)) { + sp_cache_384[i].cnt++; + break; + } + } + + /* No match. */ + if (i == FP_ENTRIES) { + /* Find empty entry. */ + i = (sp_cache_384_last + 1) % FP_ENTRIES; + for (; i != sp_cache_384_last; i=(i+1)%FP_ENTRIES) { + if (!sp_cache_384[i].set) { + break; + } + } + + /* Evict least used. */ + if (i == sp_cache_384_last) { + least = sp_cache_384[0].cnt; + for (j=1; jx, sizeof(sp_cache_384[i].x)); + XMEMCPY(sp_cache_384[i].y, g->y, sizeof(sp_cache_384[i].y)); + sp_cache_384[i].set = 1; + sp_cache_384[i].cnt = 1; + } + + *cache = &sp_cache_384[i]; + sp_cache_384_last = i; +} +#endif /* FP_ECC */ + +/* Multiply the base point of P384 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * r Resulting point. + * g Point to multiply. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_6(sp_point_384* r, const sp_point_384* g, const sp_digit* k, + int map, int ct, void* heap) +{ +#ifndef FP_ECC + return sp_384_ecc_mulmod_win_add_sub_6(r, g, k, map, ct, heap); +#else + sp_digit tmp[2 * 6 * 7]; + sp_cache_384_t* cache; + int err = MP_OKAY; + +#ifndef HAVE_THREAD_LS + if (initCacheMutex_384 == 0) { + wc_InitMutex(&sp_cache_384_lock); + initCacheMutex_384 = 1; + } + if (wc_LockMutex(&sp_cache_384_lock) != 0) + err = BAD_MUTEX_E; +#endif /* HAVE_THREAD_LS */ + + if (err == MP_OKAY) { + sp_ecc_get_cache_384(g, &cache); + if (cache->cnt == 2) + sp_384_gen_stripe_table_6(g, cache->table, tmp, heap); + +#ifndef HAVE_THREAD_LS + wc_UnLockMutex(&sp_cache_384_lock); +#endif /* HAVE_THREAD_LS */ + + if (cache->cnt < 2) { + err = sp_384_ecc_mulmod_win_add_sub_6(r, g, k, map, ct, heap); + } + else { + err = sp_384_ecc_mulmod_stripe_6(r, g, cache->table, k, + map, ct, heap); + } + } + + return err; +#endif +} + +#endif /* !WC_NO_CACHE_RESISTANT */ /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * @@ -41685,8 +43200,8 @@ static int sp_384_ecc_mulmod_6(sp_point_384* r, const sp_point_384* g, const sp_ * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_384(mp_int* km, ecc_point* gm, ecc_point* r, int map, - void* heap) +int sp_ecc_mulmod_384(const mp_int* km, const ecc_point* gm, ecc_point* r, + int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_384 p; @@ -41727,6 +43242,443 @@ int sp_ecc_mulmod_384(mp_int* km, ecc_point* gm, ecc_point* r, int map, return err; } +/* Multiply the point by the scalar, add point a and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * p Point to multiply. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_add_384(const mp_int* km, const ecc_point* gm, + const ecc_point* am, int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_384 p; + sp_point_384 a; + sp_digit kd[6]; + sp_digit t[6 * 2 * 6]; +#endif + sp_point_384* point; + sp_point_384* addP = NULL; + sp_digit* k = NULL; + sp_digit* tmp = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_6(heap, p, point); + if (err == MP_OKAY) { + err = sp_384_point_new_6(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (6 + 6 * 2 * 6), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 6; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 6, km); + sp_384_point_from_ecc_point_6(point, gm); + sp_384_point_from_ecc_point_6(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_6(addP->x, addP->x, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_6(addP->y, addP->y, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_6(addP->z, addP->z, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_6(point, point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_384_proj_point_add_6(point, point, addP, tmp); + + if (map) { + sp_384_map_6(point, point, tmp); + } + + err = sp_384_point_to_ecc_point_6(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_6(addP, 0, heap); + sp_384_point_free_6(point, 0, heap); + + return err; +} + +#ifdef WOLFSSL_SP_SMALL +#ifndef WC_NO_CACHE_RESISTANT +/* Striping precomputation table. + * 6 points combined into a table of 64 points. + * Distance of 64 between points. + */ +static const sp_table_entry_384 p384_table[64] = { + /* 0 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 */ + { { 0x3dd0756649c0b528L,0x20e378e2a0d6ce38L,0x879c3afc541b4d6eL, + 0x6454868459a30effL,0x812ff723614ede2bL,0x4d3aadc2299e1513L }, + { 0x23043dad4b03a4feL,0xa1bfa8bf7bb4a9acL,0x8bade7562e83b050L, + 0xc6c3521968f4ffd9L,0xdd8002263969a840L,0x2b78abc25a15c5e9L } }, + /* 2 */ + { { 0xa54768dab1b43eefL,0x13e41f47e14fda22L,0x774df203faef6863L, + 0xf795a034bd7471b3L,0xf0958718b47de2e9L,0xc92f7888e1160cffL }, + { 0x86ded97b0146c790L,0x015918f5480a4b7bL,0x05588920424e8459L, + 0x37455914eecf8b2bL,0xe7d3df1fb968a6faL,0x07a0ffd6bad0719fL } }, + /* 3 */ + { { 0xda37cd535c54db6fL,0x0e37890a91f06c5cL,0x1730ef7be7ae7db5L, + 0x2b3dcd51ff045f54L,0xf5db3c3c72cc8451L,0x3165d6efcf0c185cL }, + { 0x177c4f6bf5958d78L,0xcb29d22f8d676a9fL,0x3bcf0068792ac96dL, + 0x60d1c6b719df5641L,0x426e412a68a099f8L,0xf9ca0c5c9f74d52bL } }, + /* 4 */ + { { 0xf186d6bcc88d568aL,0x872bc4c7528535ddL,0xc9e7432edfe64dc3L, + 0xd9fc4832d795ea57L,0xf4ffdb81c845af2bL,0x66d7e7882b670517L }, + { 0xa7c1be04d7b7a1c6L,0xbed88479d5b2a249L,0x62ff8aba03f2ef6dL, + 0x60ecaac420dc701dL,0x9f4b559f4ff10119L,0x0582c9313cd54fd0L } }, + /* 5 */ + { { 0x394fb84de86e3f64L,0xfe4a36e7ff13314eL,0xa1e44b14dc261ec2L, + 0x3924e50a7420408fL,0x637e330242ed7626L,0xeb657b10fd711ba4L }, + { 0xc16d01c5340949bbL,0x30e043267f1f42c7L,0xe7465819b056d872L, + 0x3386f1c6886fb3dbL,0x5be463a5be56f774L,0xa96fd3b74694e15aL } }, + /* 6 */ + { { 0x95dd5ee5a98b4254L,0xea328205aa845e67L,0x98640fb5a1e36348L, + 0xd1bc5c251add5ee7L,0xc3158a423d11b799L,0x5feb68ed47c83d54L }, + { 0x7c5a1204963a207bL,0x2f2b2c7eee4671f8L,0xb63d291cd42867a6L, + 0x0b073620139530f4L,0xbe149492abb05b99L,0x21417da455accd2aL } }, + /* 7 */ + { { 0x9408555e9e5eba15L,0x416250137b7572c5L,0xfa53ee50bfff6ea7L, + 0x3d682de1e7b178c3L,0xb3e8769dec329f53L,0x1ab8c82e9eb524f4L }, + { 0x5bbd538dde2f1eb9L,0x1d1b0bea2b19c51eL,0xf785f9b98cb06eeeL, + 0x5cff29c6f58f21d5L,0x44aaa52245cbaef3L,0xd60c19427de40246L } }, + /* 8 */ + { { 0x378205de2f9fbe67L,0xc4afcb837f728e44L,0xdbcec06c682e00f1L, + 0xf2a145c3114d5423L,0xa01d98747a52463eL,0xfc0935b17d717b0aL }, + { 0x9653bc4fd4d01f95L,0x9aa83ea89560ad34L,0xf77943dcaf8e3f3fL, + 0x70774a10e86fe16eL,0x6b62e6f1bf9ffdcfL,0x8a72f39e588745c9L } }, + /* 9 */ + { { 0x73ade4da2341c342L,0xdd326e54ea704422L,0x336c7d983741cef3L, + 0x1eafa00d59e61549L,0xcd3ed892bd9a3efdL,0x03faf26cc5c6c7e4L }, + { 0x087e2fcf3045f8acL,0x14a65532174f1e73L,0x2cf84f28fe0af9a7L, + 0xddfd7a842cdc935bL,0x4c0f117b6929c895L,0x356572d64c8bcfccL } }, + /* 10 */ + { { 0x984a6aed6420bc66L,0x6d90e0e0896a24a6L,0xe0adb93a18713003L, + 0xf00d424c1a8369fcL,0x636ebf14712ae802L,0xee39ff8ebe9d739aL }, + { 0xb330dd3e94f6d1dcL,0x6ba6780eb7731cf8L,0x4e569408198be5a2L, + 0x6639523b0193a22cL,0x6978cc9d91aa1455L,0x62062d8f329f9763L } }, + /* 11 */ + { { 0x7159107d80efff78L,0xf8ed5f8e8e4c39d5L,0x64a2265cc15e679cL, + 0xfc514e17a6d96c81L,0x59c86545f093e0a8L,0x804b0a588b5a336aL }, + { 0x94c32118cb9dcbcaL,0x2deb0e385d45251dL,0xd1092b0986869572L, + 0x073bf838fb2e9f97L,0x76b6d7d6de700fcbL,0xd2a6d110f2ddce5fL } }, + /* 12 */ + { { 0x6da7ccd0229de19eL,0x5050d45df0aa039dL,0xf9f01d68d9e7a861L, + 0x6d8b9f2000aa05f2L,0xae3d9698742cd4d9L,0x43e477abd560c394L }, + { 0x73d594991cb6dd81L,0x689162b2fac3f62eL,0xd6187ca864d1d0d5L, + 0xe8421a0d2f067457L,0x9b266acbea7c3a8dL,0x707e0e6e44df5cb3L } }, + /* 13 */ + { { 0x604b2a1a026511a0L,0xd4f6cf16256f4076L,0x7d823347b315a642L, + 0x8f805833786aa438L,0x9883df85f04bb4b3L,0x02bc10305bba6d84L }, + { 0xfe39a024a72c03acL,0xa980db635f2dbfd0L,0xcd53149f4f259ec6L, + 0xe969079b43f53f97L,0xd3849fdb42f9f27cL,0xd2cfd3f842653dc9L } }, + /* 14 */ + { { 0xbf69fe6a6abe7d80L,0x4932288192bb50e2L,0xc9e2f7fb61e8b18dL, + 0x24c74788f6c82421L,0xe79e5e3011c0b244L,0xd6612c70e0484571L }, + { 0x7863ff927ef82d17L,0x692790feb0a1b01cL,0xa2d6ffb5afe51546L, + 0xacdb43f26cf550c6L,0x3b3243dfaecfaf8fL,0x9557335ac233bcd9L } }, + /* 15 */ + { { 0x25e08c8faff5b387L,0x112c11e2d06208ceL,0x61031c1765234214L, + 0xba06f5550514764dL,0xfaacf6f39bd197d0L,0xe4b032321464a57fL }, + { 0x00c19adfe35dcd69L,0x81b75730a1c2646cL,0x47baa4fee0c50e32L, + 0xe9297832bcaddb3bL,0x1768d2f9d712c6cfL,0xfcef29fdb82e9eeaL } }, + /* 16 */ + { { 0xdbe04c3044ce3ad8L,0x995fbb1b4ce8aad5L,0xdbf8b54670911457L, + 0x9e683b5b3f7a1757L,0x7b89a08a9c7bd62cL,0x448865a40b3fc97eL }, + { 0x0ac9abfc3bb01e94L,0xa07760421e756124L,0x0aa6c335d9deed97L, + 0xe270580f72603e08L,0x70857a946c783bb2L,0xa0047774caa929aeL } }, + /* 17 */ + { { 0x56211190a353e889L,0x052917c3190eb198L,0xadfd85b03eee3d12L, + 0xde1d761779fd9c91L,0x05be51b7bf500159L,0x271f07178fcb87f1L }, + { 0x02673e273a75ac71L,0xb1b7246eda12da8dL,0xb25647928f5fb8c0L, + 0x0a22cbe1063b1d7fL,0xb0d7a7365649976eL,0x8f8e6e289e96b15dL } }, + /* 18 */ + { { 0x8fc113f98312351cL,0xe837b9e0c5eff002L,0x7cb9ef074dad72fcL, + 0x18a8d43eb5eb7ee3L,0x2cf3ae844925efdbL,0x376e9e857756ec6aL }, + { 0xf77a79c8a3e3705fL,0x2d590b7d6c5fbab3L,0xa59713e27a4766c3L, + 0xb5da6a6861544174L,0xadb04a8adab1fe76L,0x03b6138d375143b4L } }, + /* 19 */ + { { 0x20d88a80c1bfa043L,0x88806999672583ceL,0x195a89eaaea9b605L, + 0x0b9b4e8532bac07bL,0x8279965683868df6L,0x83c58afab52711a9L }, + { 0xb895c13d1c869283L,0x00f98d046206dde6L,0x76caaa22884bf311L, + 0x22b2137f995b29a5L,0x7f645809b098b07bL,0xa540c8a6050e2552L } }, + /* 20 */ + { { 0x47980509e562d904L,0xe736f89d031e112cL,0xbc6bfb0765d8ae25L, + 0xe9ed4cc4ca459646L,0xf540e90e2fff67ffL,0x836280eb1a314e11L }, + { 0xa710b25041610627L,0xefc22b1573a9f9a2L,0x60f20789456498c0L, + 0x417920438052f4e7L,0x5c850903d5c0e80dL,0x52df5275bf1d8815L } }, + /* 21 */ + { { 0x25539de98ece218dL,0xb36574a8dca420baL,0x9d1812680e0d07feL, + 0xea79a5f5ad3ed34fL,0x8b739ad57c9277cfL,0xd88659886ee9a930L }, + { 0xaf07bfb621591a3eL,0xe0138c6508f3524fL,0xd3128f1297ee315eL, + 0x67f8641e21045f63L,0x3e1a96b140c73a2dL,0x8976b70305f51122L } }, + /* 22 */ + { { 0xdeaf635731960db4L,0x680b054e5948d7f7L,0x0841e40fd272bb5cL, + 0x94d37db26e36117dL,0xaf2d001547f63ec8L,0x82665cdc47493309L }, + { 0xfe90e844abbe3851L,0x8357709afb79bc0cL,0x811a64d2b6bcc044L, + 0x1937c988882b3415L,0xe8b28724e267b271L,0x84d1eed0af89ed33L } }, + /* 23 */ + { { 0x52b8234f54c894a7L,0xfe54146fa2d11b70L,0x6412b5eb0aab6097L, + 0xa62499906a13a9daL,0xd2b1eb50adc448caL,0xe7ab51f9b115ab92L }, + { 0x4638ee62e76551d8L,0x74c3c1e1afe9c98dL,0x59000ad060d77322L, + 0x0a4b105ba06adc9aL,0xcdaeb4a496a6f616L,0x8c79c4a1864b49dcL } }, + /* 24 */ + { { 0xc09c32d1c0b1bf15L,0x005d510f88d74e44L,0x031f9a9afc2c089eL, + 0x08aac7294ba183f0L,0xf227a7ceaf2245ebL,0xb4ec33cbb3a864ffL }, + { 0xdb76decd570a24f3L,0xea59387a12283a9eL,0x81b7c569341ef9a4L, + 0xad7c98bd8d77833aL,0x2182133b49ca80ffL,0x1de1d456085802b7L } }, + /* 25 */ + { { 0xeead25b2e1c02860L,0xb2ae43694ff42d2eL,0x4b39a2ddfd61c1b0L, + 0x29c826ea968718a5L,0x877fdf15d9751a0aL,0x00b321dfb54affdfL }, + { 0x3c7c0778d4d5dbf7L,0x858a0fdccfc47423L,0xbd8e6544185b3063L, + 0xa22c3ef62da46a04L,0x5c2d84016a6c0ce1L,0x260246eddd6329aeL } }, + /* 26 */ + { { 0x71753fc00c6463f6L,0x7ec14c015c6c9e33L,0x28b9ab9441ce6153L, + 0x3a1ac251a6702c8dL,0x2b124bc49ed6cb1fL,0x7a11c4be4fc7383fL }, + { 0x1414913509fac991L,0xf7c188d3cb1ee336L,0x754bc47391c3f406L, + 0x71d34587cad39500L,0x213dd1a7dd0399a1L,0x8457a8f671d05899L } }, + /* 27 */ + { { 0xa921ca662e9c06d3L,0x1d8974e89ba6521fL,0xbb465c775f79f791L, + 0x8f983f083a3954c8L,0x8492f8398b3935dcL,0x2b87d9c290c04426L }, + { 0xcec76ea403e60a28L,0x648e9830aa631308L,0x7b542f791eb86b73L, + 0xfc8cc9a3150d854dL,0x2be86940bfcc83feL,0x2e58a13ac88c7585L } }, + /* 28 */ + { { 0x19249a8fd1bc237fL,0xdec1c6a563505555L,0xc8256977bad2a93bL, + 0x78533659fc598170L,0x888a6578ee7e53cbL,0x28783b0e33766db3L }, + { 0xcf791e56e42c28f2L,0xfbf8dde8f9c37f4cL,0xf0ffaf1712c05395L, + 0xd27d21e9daf2f012L,0xf90432da9a7be009L,0xa459c036a8012f28L } }, + /* 29 */ + { { 0x4d99a7cac8b1c6d4L,0x8088818825c899c0L,0xbd27e9be2ebdeb3dL, + 0x73c3e0aa054e77c1L,0x180c848498534ce5L,0x750d52f754ffa9cdL }, + { 0x5f26eeb16f702f4cL,0x427fc6e4cc76d8f4L,0x93126b8d026b631dL, + 0x5356b93917e145a7L,0xc79ca872c0be7c84L,0x3fca7cad4b615fb7L } }, + /* 30 */ + { { 0xed48fe78d0241021L,0x252b14a0142f7f8eL,0x19ab85c6db573a09L, + 0x546c3960f3df906fL,0xc688f4b22c810ea8L,0xbccf0cca5ff9e108L }, + { 0x34f4609e3f2cc69bL,0xf3b1efe414afe4f4L,0x5d809cef37a8ef74L, + 0xa8d1978a176ba328L,0x75dde11fdf59ecb9L,0x34eeeaffa9916ee2L } }, + /* 31 */ + { { 0xe7f603f248e83c85L,0xa94a539cfa581815L,0x5a61a596dba360b7L, + 0x6cc51dd16a77ef79L,0x4ff36ae0fdbceb9dL,0xfcff65323e8a9c07L }, + { 0x0ba0ce5436d4d0b8L,0x98087a452464efc2L,0xd456843bcc1a2ba7L, + 0x677384a53853e04cL,0x625d32d56c7971deL,0x86882509f724b331L } }, + /* 32 */ + { { 0xc20fb9111a42e5e7L,0x075a678b81d12863L,0x12bcbc6a5cc0aa89L, + 0x5279c6ab4fb9f01eL,0xbc8e178911ae1b89L,0xae74a706c290003cL }, + { 0x9949d6ec79df3f45L,0xba18e26296c8d37fL,0x68de6ee2dd2275bfL, + 0xa9e4fff8c419f1d5L,0xbc759ca4a52b5a40L,0xff18cbd863b0996dL } }, + /* 33 */ + { { 0x684a681892a5eeeaL,0x1f5b193242a09264L,0x30bd8695d98a2f34L, + 0x6e775e019a8601fcL,0x8126bdc24ca956f8L,0x149e73d9e5595daaL }, + { 0x876428401f851e83L,0x4b8863dbd3a7c4a0L,0xe1e43b3d8c95d7d9L, + 0x7f1e307ea60fd528L,0xbf2fa5d134341610L,0x11ad4a8181c502d3L } }, + /* 34 */ + { { 0xc7df022e782dd401L,0xd15aa9a9a7bcc543L,0x6aa42774b94df1d0L, + 0xab2660c30592a13eL,0xaf4e40809ffc40c7L,0x01152c8d9cd52b10L }, + { 0x649de1d99034a33aL,0x2b9d0ef0d758abfcL,0xdddd0bc2d458adddL, + 0xe5366ac9c09837f8L,0xa003abbb7b1ae35fL,0x880062887ab1fddeL } }, + /* 35 */ + { { 0x6b6c8f055288f1b4L,0xba05407c033738b4L,0x26cac3a941a955e3L, + 0x28f1692f8e0e0601L,0x2032cb36842c4887L,0x6adeba457d76b20fL }, + { 0xd282c2ce654c6f5cL,0x30584ca5be9ba4f1L,0x45d766a01b2c528bL, + 0xe918bad7c0c6f8ccL,0x1e050b2a0560f070L,0x4fc95de12d6dd010L } }, + /* 36 */ + { { 0x2bb26072150191d5L,0xea2617618108dcf6L,0x4dfa1303e6083c63L, + 0xfa4e0709e2876fb8L,0xf901fed0b1668763L,0xf01c53aeb82c967aL }, + { 0xb43e59d39ed827e8L,0xb58e157e57774eefL,0x57ee54e31b83dceeL, + 0x3d896f32613aa922L,0x69d40667b5c7bfc5L,0xd402b5cb77a2c0d8L } }, + /* 37 */ + { { 0xabeb70127d3c9923L,0x412ada8dd7ecb93aL,0xeb64dc910b71ae2fL, + 0x52ef537aa9ab061aL,0x0863970fc1b55faeL,0xfaff5fb9b1182dbdL }, + { 0x5551d6fed0abaa17L,0x7bb3e02072d641f6L,0x939d7793aa9d288cL, + 0x1450f8bf9078e2c2L,0x24ccd102a086b6aeL,0x57d1796f6a3f8a5fL } }, + /* 38 */ + { { 0x1023120683ce1f76L,0xd16d4b9f03ee406fL,0x9d39c39883caa4b7L, + 0x875732f5ce299b93L,0x1e6a425d2f121f4aL,0x4b1f1d835d8c3279L }, + { 0xe655f58856dd6a6cL,0x23f106475843fd34L,0x932b7d942bad6ce2L, + 0x70a0580e6772a52eL,0x3240118ac88537afL,0x9ccb2ca9d2407224L } }, + /* 39 */ + { { 0xa6a40db8710f2324L,0xb3567518c2a8a09aL,0x8816442841b5650aL, + 0x2a352ed27570ba50L,0x23ee46b94c85d77eL,0x643aceffd858a8c3L }, + { 0xe067908de3f02e82L,0x8d5869f2ffb8cf81L,0x4713f0820bc8ad7eL, + 0xe1ee44c780057c40L,0xb34395087d2cf34eL,0x4307b0e10336a207L } }, + /* 40 */ + { { 0xe9c1e45746e4d003L,0xa23978c394332057L,0x0e2f300829575db6L, + 0x50a51ff490441e9eL,0x38ce3ed0508d4a07L,0x6a997411cfd7224eL }, + { 0x4d147c31da6b1e1dL,0xedf604b2da8a3547L,0x7a1b8cf0d5e9ceedL, + 0xd74e501213544e6aL,0xcc49f8da4ad968f9L,0xfb87e604cc69ada9L } }, + /* 41 */ + { { 0xde79409bdf166882L,0xd645b836d46cc527L,0xda4a02f3b6c3eb28L, + 0x845e3c5900e7cf86L,0x733bdc9b604c6d80L,0xe3a1244b847acd97L }, + { 0x421312d6d128842cL,0x81f71feaa1c598efL,0xc619465545eaf796L, + 0x1ffb85121f338b6cL,0xe7aed7106632f064L,0xf8d1ffb7f5b6e510L } }, + /* 42 */ + { { 0x7d3f031f3eace851L,0xef43ab7025923624L,0xbae811881af6cdecL, + 0xb7e93b49ea862112L,0xe35a4fc6af23aba2L,0xc52e1fc0aecc593eL }, + { 0xbffa292428148b99L,0xd08040fc89e3d795L,0x7da320032db47b3aL, + 0xe78b44e5a0eb7aa3L,0xd1648ec8f0ec090bL,0x4048dba7740fe871L } }, + /* 43 */ + { { 0x6fddb89fa00a14acL,0x844f991508aa06e7L,0x6d5ac4a9f76aca7dL, + 0xfba1ba85e9fa4d51L,0x159633bbb2ea0fc7L,0xa2eb0e4b76ba2854L }, + { 0x8a858155c11f5398L,0x30a96e535e8ea044L,0x696210c197e05a47L, + 0x86e55f9415036f4bL,0x0c93ea9c6a96d9d7L,0xb7ba506179eba3daL } }, + /* 44 */ + { { 0xd305c733cd94d7b2L,0x9ea33e363e7955b2L,0x78a98855bc73812fL, + 0xfb1b791d48a3a9a0L,0x6e5107ee04014aafL,0x0412b2c00ea07de0L }, + { 0xdd3a2408ddcaca68L,0x5d18e69ae3344f29L,0x3ce65481f9017408L, + 0x50abb4568cbd64fbL,0x442fa5098916a9ebL,0x16b3ddc7c538c410L } }, + /* 45 */ + { { 0x6757dbfd25e331abL,0x0efde50ba3eaafbcL,0x1cd46222d531d29cL, + 0x1b713ca93561cb2bL,0x7d07334bfb5bc99dL,0x95dba43e885a417dL }, + { 0x1c9c3f3f77823a59L,0x43533ba83220cb7fL,0x1b918bc182e3e401L, + 0x66a039aacd3fec87L,0x1d39dbb02dad36d5L,0x554025959dc04be4L } }, + /* 46 */ + { { 0xdf39920847744933L,0x4264f7ea82524dd6L,0xdb57ec08e5182c6dL, + 0x2d6778e705c5e7bfL,0x3f37793f96f53ea2L,0x6472cbae05c47e48L }, + { 0x9e6dd60fbf78067cL,0xa2817ec2cef34088L,0xde4715b8168edde9L, + 0x6c57105146bf31e1L,0x98113fbbc4272bc0L,0x03bb7922cc3b90c3L } }, + /* 47 */ + { { 0xe0f23be157d88fefL,0x4125c55b0ca27a01L,0xeadf527e14a71262L, + 0x1f2e803ccc4e9a04L,0x32e07b47d68c4fcfL,0x1577fab79db5070bL }, + { 0xd786d6e57831990aL,0xf64ff4b154fbde40L,0x4bac5b034f9450aeL, + 0x06ae25e055116af9L,0x33d84ea2d7b4fcfcL,0x44a92e73569c3b9eL } }, + /* 48 */ + { { 0xf5bdccbabad0cb7fL,0x370f43ca958edd05L,0x3dd8232b04904a26L, + 0x3f8106682f4458e8L,0xdfcb67b99b3ace7eL,0x54e42f2d3e1241fcL }, + { 0xe30f3fb0db889300L,0x4ca0184b483e51fcL,0x5a32d097a638dac6L, + 0x567a2b5ec62a1db0L,0x2a756ba3c446456cL,0x6919026dd9f8d5c0L } }, + /* 49 */ + { { 0x7f6493fc4fec874aL,0x8bb8a674d47a0770L,0x90bad2a652bd4f0cL, + 0x16badbe2f5733b07L,0x93be07cf93a1f802L,0x1e37a01541c395f7L }, + { 0xfe2c0fd6216582b3L,0xdcd98bc81627180dL,0x41e037268e8c9f1eL, + 0x93dbc22cfe8f45afL,0x5728c8a6ff45e059L,0x4f2f15cfca4a98cdL } }, + /* 50 */ + { { 0xdbe2ec5d656e7d76L,0x84ad1b4bae2757bbL,0xc9297e7a0d4fec75L, + 0xfcc673eecad3ba87L,0xb0f77621dfd1671aL,0x5c386e449704a8c7L }, + { 0xce78f03f3e29256dL,0x0b185938c3a6ed2fL,0x7b1e2fae7824819bL, + 0x5a85d7f1f2d9313cL,0x238bd27973595b0fL,0x5fbf6b675c1cd2dcL } }, + /* 51 */ + { { 0x84d1ffb88a3e2412L,0xf01605926515f2feL,0x0e26ea9889905340L, + 0xbfd7a1b7203bd3d4L,0x5301273a88ea0bdaL,0x2f424475b28dd43eL }, + { 0x31014a2b33c28afaL,0xffbdea0c01e220eaL,0x681c64e8460b81d5L, + 0xdbe6f7286a91e1d5L,0x068bf36332619ad5L,0x4946291f27976c74L } }, + /* 52 */ + { { 0xa081a9462068e4b0L,0x1a8f5df609bfdad0L,0x5fbba5bcef28dd35L, + 0xa3e60d4f031ff71eL,0x2d47689b702ca18eL,0xd283f247c9b8e66bL }, + { 0x63e65dd7859ea140L,0x123da61f42aacdc3L,0xa8a9e893336f680cL, + 0x1cc4e12ac23d43acL,0x421e80d586a1fff8L,0x833d60d543deecc9L } }, + /* 53 */ + { { 0x3c25b57c29014f8fL,0xa19fcb1e35d8e122L,0x916c0e3ceda32ac8L, + 0x9a23d289f36b6096L,0x5099038439a39871L,0xdc5b77b661c64196L }, + { 0x5a7d9917942bf2b6L,0xd21853934f41cf6dL,0x90ff1016fcc45c2fL, + 0x9891093deb8938aaL,0xe3c49b1baac4e6e9L,0x0f21a1d1d7a8e91eL } }, + /* 54 */ + { { 0x3a808e336f364b7eL,0x6a96d1b8bfa17359L,0x3387ec8552b36545L, + 0x2fde350af712180cL,0x9219d6f4703a2183L,0x8ba27e0086457946L }, + { 0x7446bca0ed80a9afL,0xbaf78b6f7203637aL,0x0304129d497c9d0fL, + 0x6df1e0356a883b68L,0x93ea2bb5e8018c47L,0xc86fd77cdb46443cL } }, + /* 55 */ + { { 0x8de865d255dc2427L,0x74f7f83d6f72d126L,0xee1111786c7e665aL, + 0x272a8b3dddf44f12L,0xad3546449164eb4fL,0x2ffbdb586859d68fL }, + { 0xbefd36c509701865L,0x63c256162c983d01L,0x15a7ba0b2eb68703L, + 0x3318a82b5bb0fafcL,0x8e930fa9a0804f38L,0xb7459eb6be60ed1dL } }, + /* 56 */ + { { 0xace01c514260b948L,0x04a6080f49210f78L,0x0d1eef6b2241b00dL, + 0x85a25069ef63912aL,0xcc96c4ec13dd8bc2L,0x90f14d1140d7e234L }, + { 0xae33f18ca69c8dc3L,0x76921f2a9adfa431L,0x18158ccf048c9f49L, + 0x90bcf7fbfb8fb345L,0x0d50b4dc38b3ff5dL,0x3914ea0b59ef84a8L } }, + /* 57 */ + { { 0x4929d3f9d4e37cf3L,0x622183d1b24c24c0L,0x65cec0675f904d34L, + 0x65f9931a8a6f76faL,0xeed975b0e73282f2L,0xa045552a5e1625fdL }, + { 0xfd6b3e02f8fe8e42L,0x5f9f40256203907cL,0x8307eedb42b2c264L, + 0x2fb3ee719f757e92L,0x4502f2ecdc157ea8L,0xd976e7755d1cc0d5L } }, + /* 58 */ + { { 0xe46fb9a28fe1946eL,0xe91df3ed63bdde6eL,0x2e995306e9c28432L, + 0x7b3a6fe10988235bL,0xc55199f077f92a71L,0x47dd034853cb7950L }, + { 0xead52de2b727a6d1L,0xb87c9f75eea9c8daL,0xf3e2f3280d944f21L, + 0xce82734edd751eddL,0xfb83225ce616cedcL,0x15850e4b4a31eb49L } }, + /* 59 */ + { { 0x92c4b6d50196ad3aL,0x0205ea484e1205e4L,0x8e08a97c0afc5affL, + 0xda8687c6727827ebL,0x2eace83106e398aaL,0x3a086c0f6d69e4e8L }, + { 0x5ff9b7aaf286e62aL,0xc428503962aae55eL,0x4ebd4258d9530a3fL, + 0x57ea313a8afc7fcbL,0x6d30a67522c18879L,0xd3c00cc994afb659L } }, + /* 60 */ + { { 0x53ee47c5dee0d48bL,0xbd9e84ad9dfa2397L,0x2d581e12f81ba5e2L, + 0x26269f4f132cd325L,0x9e6224df58860a5fL,0x9306c607ff55522aL }, + { 0xb48af6d4146950e5L,0x09920ed00436805eL,0x3a1bc276cdce7eaeL, + 0x55ba728ac39a425eL,0x6a04d4e6d961d03eL,0x13891c66736e684aL } }, + /* 61 */ + { { 0x7c75175a04cd04d6L,0xb76f9bd909c27a17L,0xa0cff6d408e5fe36L, + 0xc9097695dcd5ef90L,0x26bea24585e28054L,0x658e03c61580f068L }, + { 0x0da9f75e811eed27L,0x086e5e04aca0d2eeL,0xd4c157faa53a6787L, + 0x2e9266d2b40a595cL,0x8f1cb52698fa0820L,0x32a74240a1aef514L } }, + /* 62 */ + { { 0xeb42e3d91ae86e7cL,0xd6956c8ce04a5026L,0x4c0b8b980f4302ebL, + 0xde43c938b37211fdL,0x9fa6a158e7090f80L,0x5f3c9afc73c47fb6L }, + { 0x2dc4f109f850a4d0L,0x56e63a4b6fd49d6aL,0x8e80a0694cbff048L, + 0x18d8b8cf2284afb0L,0x61dd086dc89363a1L,0x034c2202c37342a4L } }, + /* 63 */ + { { 0x1ae0c4e11c718580L,0x303f48a6bf99a0bfL,0xa5551e4491ae219fL, + 0xdc41d9bd55a05287L,0xd5aa73e36872b123L,0x6fd94b0ce6395bf6L }, + { 0xbb95fdbac00afbc1L,0x9cd96208497cac10L,0x8adbd8c1ca51afeaL, + 0x94fedafbf3bc5f5fL,0x29c0217bdf9f5371L,0x5c13eb4bd9024634L } }, +}; + +/* Multiply the base point of P384 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^64, ... + * Pre-generated: products of all combinations of above. + * 6 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_base_6(sp_point_384* r, const sp_digit* k, + int map, int ct, void* heap) +{ + return sp_384_ecc_mulmod_stripe_6(r, &p384_base, p384_table, + k, map, ct, heap); +} + +#else +/* Striping precomputation table. + * 8 points combined into a table of 256 points. + * Distance of 48 between points. + */ static const sp_table_entry_384 p384_table[256] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -43011,6 +44963,11 @@ static const sp_table_entry_384 p384_table[256] = { /* Multiply the base point of P384 by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Stripe implementation. + * Pre-generated: 2^0, 2^48, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * * r Resulting point. * k Scalar to multiply by. * map Indicates whether to convert result to affine. @@ -43025,6 +44982,18014 @@ static int sp_384_ecc_mulmod_base_6(sp_point_384* r, const sp_digit* k, k, map, ct, heap); } +#endif /* WC_NO_CACHE_RESISTANT */ +#else +/* The index into pre-computation table to use. */ +static const uint8_t recode_index_6_7[130] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, + 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, + 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, + 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, + 0, 1, +}; + +/* Whether to negate y-ordinate. */ +static const uint8_t recode_neg_6_7[130] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, +}; + +/* Recode the scalar for multiplication using pre-computed values and + * subtraction. + * + * k Scalar to multiply by. + * v Vector of operations to perform. + */ +static void sp_384_ecc_recode_7_6(const sp_digit* k, ecc_recode_384* v) +{ + int i; + int j; + uint8_t y; + int carry = 0; + int o; + sp_digit n; + + j = 0; + n = k[j]; + o = 0; + for (i=0; i<55; i++) { + y = (int8_t)n; + if (o + 7 < 64) { + y &= 0x7f; + n >>= 7; + o += 7; + } + else if (o + 7 == 64) { + n >>= 7; + if (++j < 6) + n = k[j]; + o = 0; + } + else if (++j < 6) { + n = k[j]; + y |= (uint8_t)((n << (64 - o)) & 0x7f); + o -= 57; + n >>= o; + } + + y += (uint8_t)carry; + v[i].i = recode_index_6_7[y]; + v[i].neg = recode_neg_6_7[y]; + carry = (y >> 7) + v[i].neg; + } +} + +#ifndef WC_NO_CACHE_RESISTANT +/* Touch each possible entry that could be being copied. + * + * r Point to copy into. + * table Table - start of the entires to access + * idx Index of entry to retrieve. + */ +static void sp_384_get_entry_65_6(sp_point_384* r, + const sp_table_entry_384* table, int idx) +{ + int i; + sp_digit mask; + + r->x[0] = 0; + r->x[1] = 0; + r->x[2] = 0; + r->x[3] = 0; + r->x[4] = 0; + r->x[5] = 0; + r->y[0] = 0; + r->y[1] = 0; + r->y[2] = 0; + r->y[3] = 0; + r->y[4] = 0; + r->y[5] = 0; + for (i = 1; i < 65; i++) { + mask = 0 - (i == idx); + r->x[0] |= mask & table[i].x[0]; + r->x[1] |= mask & table[i].x[1]; + r->x[2] |= mask & table[i].x[2]; + r->x[3] |= mask & table[i].x[3]; + r->x[4] |= mask & table[i].x[4]; + r->x[5] |= mask & table[i].x[5]; + r->y[0] |= mask & table[i].y[0]; + r->y[1] |= mask & table[i].y[1]; + r->y[2] |= mask & table[i].y[2]; + r->y[3] |= mask & table[i].y[3]; + r->y[4] |= mask & table[i].y[4]; + r->y[5] |= mask & table[i].y[5]; + } +} +#endif /* !WC_NO_CACHE_RESISTANT */ +static const sp_table_entry_384 p384_table[3575] = { + /* 0 << 0 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 0 */ + { { 0x3dd0756649c0b528L,0x20e378e2a0d6ce38L,0x879c3afc541b4d6eL, + 0x6454868459a30effL,0x812ff723614ede2bL,0x4d3aadc2299e1513L }, + { 0x23043dad4b03a4feL,0xa1bfa8bf7bb4a9acL,0x8bade7562e83b050L, + 0xc6c3521968f4ffd9L,0xdd8002263969a840L,0x2b78abc25a15c5e9L } }, + /* 2 << 0 */ + { { 0xc8229e55783dde91L,0x8e6c8f2e022b53f0L,0x3504e6f0ff9d48a1L, + 0xda821495f0687f50L,0x9c90a4fd2de4b506L,0xdb93b776427460c3L }, + { 0x42ea84633140bfdaL,0xe8e8e4a8c2aaccd8L,0x15e4f18bdc588258L, + 0x09f1fe415172bad9L,0x070d430900b0e684L,0xe34947f7123df0c2L } }, + /* 3 << 0 */ + { { 0x05e4dbe6c1dc4073L,0xc54ea9fff04f779cL,0x6b2034e9a170ccf0L, + 0x3a48d732d51c6c3eL,0xe36f7e2d263aa470L,0xd283fe68e7c1c3acL }, + { 0x7e284821c04ee157L,0x92d789a77ae0e36dL,0x132663c04ef67446L, + 0x68012d5ad2e1d0b4L,0xf6db68b15102b339L,0x465465fc983292afL } }, + /* 4 << 0 */ + { { 0x0aae8477ebb68f2cL,0x30594ccbee0421e3L,0x2e4f153b0aecac46L, + 0x078358d4736400adL,0xfb40f647d685d979L,0xcfeee6dd34179228L }, + { 0x54f3e8e79b3a03b2L,0xe74bb7f17bfec97eL,0x8e3e61a34c542ad1L, + 0x147162d30418c693L,0xe607b9e33820017dL,0x50946875303df319L } }, + /* 5 << 0 */ + { { 0xbb595eba68f1f0dfL,0xc185c0cbcc873466L,0x7f1eb1b5293c703bL, + 0x60db2cf5aacc05e6L,0xc676b987e2e8e4c6L,0xe1bb26b11d178ffbL }, + { 0x2b694ba07073fa21L,0x22c16e2e72f34566L,0x80b61b3101c35b99L, + 0x4b237faf982c0411L,0xe6c5944024de236dL,0x4db1c9d6e209e4a3L } }, + /* 6 << 0 */ + { { 0x7eb5c9317d56dad8L,0xcb2454b339d3413aL,0xec52930f580d57f2L, + 0x2a33f6661bdf6015L,0x4f0f6a962b02d33bL,0xc482e189f0430c40L }, + { 0x3f62b16ea7b08203L,0x739ac69d5b3d4dceL,0x8bd4bffcb79e33b0L, + 0x93c9e5f61b546f05L,0x586d8ededf21559aL,0xc9962152af2a9ebaL } }, + /* 7 << 0 */ + { { 0xdf13b9d17d69222bL,0x4ce6415f874774b1L,0x731edcf8211faa95L, + 0x5f4215d1659753edL,0xf893db589db2df55L,0x932c9f811c89025bL }, + { 0x0996b2207706a61eL,0x135349d5a8641c79L,0x65aad76f50130844L, + 0x0ff37c0401fff780L,0xf57f238e693b0706L,0xd90a16b6af6c9b3eL } }, + /* 8 << 0 */ + { { 0x23f60a05dd9bcbbaL,0x9e336de5ae9b587aL,0x1c5c2e7193d7e30fL, + 0x1d9aebd64f3ddb37L,0x1c7b5fe116b66423L,0x5db4f184349cd9b1L }, + { 0x0d2cfe83e6655a44L,0x836dbb36b7e55e87L,0x701754bf7d8686e4L, + 0xe9923263a42dbba2L,0x7008d943c48ecf0eL,0x3c0c6dd70d27ef61L } }, + /* 9 << 0 */ + { { 0x2f5d200e2353b92fL,0xe35d87293fd7e4f9L,0x26094833a96d745dL, + 0xdc351dc13cbfff3fL,0x26d464c6dad54d6aL,0x5cab1d1d53636c6aL }, + { 0xf2813072b18ec0b0L,0x3777e270d742aa2fL,0x27f061c7033ca7c2L, + 0xa6ecaccc68ead0d8L,0x7d9429f4ee69a754L,0xe770633431e8f5c6L } }, + /* 10 << 0 */ + { { 0x845539d3c8d99c02L,0x2a15a9a6e58d6787L,0xe9f6368eab225fa3L, + 0x54a612d7eb32cabeL,0xc2f646025c4845ecL,0xa91a5280db1c212eL }, + { 0xbb971f78e67b5fceL,0x03a530eb13b9e85cL,0x592ac0ba794eabfdL, + 0x81961b8ccfd7fd1dL,0x3e03370a47a9b8aaL,0x6eb995bec80174e8L } }, + /* 11 << 0 */ + { { 0xc7708b19b68b8c7dL,0x4532077c44377abaL,0x0dcc67706cdad64fL, + 0x01b8bf56147b6602L,0xf8d89885f0561d79L,0x9c19e9fc7ba9c437L }, + { 0x764eb146bdc4ba25L,0x604fe46bac144b83L,0x3ce813298a77e780L, + 0x2e070f36fe9e682eL,0x41821d0c3a53287aL,0x9aa62f9f3533f918L } }, + /* 12 << 0 */ + { { 0x3db8477270313de0L,0xd4258cc55d970420L,0x03aced26c8edfee1L, + 0xf67eb42235d77d83L,0x523c40dbcf9ab45cL,0x627b415f9c35b26dL }, + { 0xfacc45e48be55ed8L,0x80d60af627aa651aL,0x8c79848fd0e102acL, + 0x40c64a4e66bed5afL,0x0329eab1f7942f0eL,0x0c6e430ef9c4af3dL } }, + /* 13 << 0 */ + { { 0x9b7aeb7e75ccbdfbL,0xb25e28c5f6749a95L,0x8a7a8e4633b7d4aeL, + 0xdb5203a8d9c1bd56L,0xd2657265ed22df97L,0xb51c56e18cf23c94L }, + { 0xf4d394596c3d812dL,0xd8e88f1a87cae0c2L,0x789a2a48cf4d0fe3L, + 0xb7feac2dfec38d60L,0x81fdbd1c3b490ec3L,0x4617adb7cc6979e1L } }, + /* 14 << 0 */ + { { 0x5865e5018f75244cL,0xd02225fb01ec909fL,0xca6b1af8b1f85c2aL, + 0x44ce05ff88957166L,0x8058994c5710c0c9L,0x46d227c432f6b1baL }, + { 0xbe4b4a9003cb68e5L,0x540b8b82730a99d1L,0x1ecc8585e11dbbbfL, + 0x72445345d9c3b691L,0x647d24db13690a74L,0x4429839ddefbadf5L } }, + /* 15 << 0 */ + { { 0x446ad8884709f4a9L,0x2b7210e2ec3dabd8L,0x83ccf19550e07b34L, + 0x59500917789b3075L,0x0fc01fd4eb085993L,0xfb62d26f4903026bL }, + { 0x2309cc9d6fe989bbL,0x61609cbd144bd586L,0x4b23d3a0de06610cL, + 0xdddc2866d898f470L,0x8733fc41400c5797L,0x5a68c6fed0bc2716L } }, + /* 16 << 0 */ + { { 0xda6e8a7f7c33ed91L,0x992afb5b0ecdd2d8L,0x37cf65517917652aL, + 0x317b63ea2887d5ffL,0x37065f5313bdc3faL,0xa10896aa435abaa1L }, + { 0x9b21615fefabca26L,0xeb07ddea230cf00dL,0x914871dc154d410fL, + 0xb333bdfbc88ee148L,0x51c305c6a72d1967L,0x659db48181ef2513L } }, + /* 17 << 0 */ + { { 0x8903e1304b4a3cd0L,0x3ea4ea4c8ff1f43eL,0xe6fc3f2af655a10dL, + 0x7be3737d524ffefcL,0x9f6928555330455eL,0x524f166ee475ce70L }, + { 0x3fcc69cd6c12f055L,0x4e23b6ffd5b9c0daL,0x49ce6993336bf183L, + 0xf87d6d854a54504aL,0x25eb5df1b3c2677aL,0xac37986f55b164c9L } }, + /* 18 << 0 */ + { { 0x5dfee73ce5b82700L,0x198fd3f0f38f6662L,0x3bd1c8f62edb0dbdL, + 0x55a96a6879909f08L,0x68a2324355671693L,0x57505d8d67497030L }, + { 0x8a60717f75c64513L,0x54b867b7f78aa7deL,0xc266eb8441129858L, + 0x6ffcfc7ca4cfd9bbL,0x9bdd6a092945a757L,0x91700b247eb1be63L } }, + /* 19 << 0 */ + { { 0x82a2ed4abaa84c08L,0x22c4cc5f41a8c912L,0xca109c3b154aad5eL, + 0x23891298fc38538eL,0xb3b6639c539802aeL,0xfa0f1f450390d706L }, + { 0x46b78e5db0dc21d0L,0xa8c72d3cc3da2eacL,0x9170b3786ff2f643L, + 0x3f5a799bb67f30c3L,0x15d1dc778264b672L,0xa1d47b23e9577764L } }, + /* 20 << 0 */ + { { 0xad610a2d94a70ec1L,0xcd96f20591e71d16L,0x713466708cbaffc7L, + 0xf78cff0cd467f03aL,0x98ca8dd42d96c936L,0x1d1cdf7b5f223465L }, + { 0xe27a189460d4db60L,0x25f546ab321828ffL,0x9933fb25dccd4df3L, + 0x422da643ffe6132bL,0x5e01b72b4718bbc7L,0xab9dd81052ebfb01L } }, + /* 21 << 0 */ + { { 0x08265e510422ce2fL,0x88e0d496dd2f9e21L,0x30128aa06177f75dL, + 0x2e59ab62bd9ebe69L,0x1b1a0f6c5df0e537L,0xab16c626dac012b5L }, + { 0x8014214b008c5de7L,0xaa740a9e38f17beaL,0x262ebb498a149098L, + 0xb454111e8527cd59L,0x266ad15aacea5817L,0x21824f411353ccbaL } }, + /* 22 << 0 */ + { { 0x4f595351262bb775L,0x981b788d16f325b8L,0xccd57831927ed783L, + 0xc382472ebe0e1fdbL,0xfd7a8b13f0681fcaL,0xe082882d69059095L }, + { 0x4d1c3049faa71fdcL,0xf9d62fd9c9576c69L,0x7b1ab489cbf837b7L, + 0xc764edf840d0fcf7L,0x50fc847215809cddL,0x671d69c98fcd8418L } }, + /* 23 << 0 */ + { { 0xd1b4e74d12e3683bL,0x990ed20b569b8ef6L,0xb9d3dd25429c0a18L, + 0x1c75b8ab2a351783L,0x61e4ca2b905432f0L,0x80826a69eea8f224L }, + { 0x7fc33a6bec52abadL,0x0bcca3f0a65e4813L,0x7ad8a132a527cebeL, + 0xf0138950eaf22c7eL,0x282d2437566718c1L,0x9dfccb0de2212559L } }, + /* 24 << 0 */ + { { 0x259f272cfab816a7L,0x20c1b8e0d809afcdL,0x540c045a409c930bL, + 0x563361909bd5c2f7L,0x38076e8fca77d74fL,0x4f13f901fc55723fL }, + { 0x890932d7bd3d10c3L,0x98d82ad1da247ec8L,0xdf5579fa4bea82ddL, + 0xe8277439a0f9ad3aL,0x1395a87966a4e904L,0x150808e625a302c9L } }, + /* 25 << 0 */ + { { 0x1e93722758ce3b83L,0xbb280dfa3cb3fb36L,0x57d0f3d2e2be174aL, + 0x9bd51b99208abe1eL,0x3809ab50de248024L,0xc29c6e2ca5bb7331L }, + { 0x9944fd2e61124f05L,0x83ccbc4e9009e391L,0x01628f059424a3ccL, + 0xd6a2f51dea8e4344L,0xda3e1a3d4cebc96eL,0x1fe6fb42e97809dcL } }, + /* 26 << 0 */ + { { 0x6423197d2afd473dL,0xb0391b37897b93f5L,0x6efedb8023bf0b90L, + 0x808497b7b0bba4a7L,0xf14b309f03fa90f2L,0x37a45bdb091cbb80L }, + { 0xedda4ae48a8f5dcbL,0xdb3f422d95e16d6eL,0x25c7b9146f5f24c7L, + 0x5d512df99d42a727L,0xbf2c0862697c08fdL,0x47d98a9df092241cL } }, + /* 27 << 0 */ + { { 0xa04482d2467d66e4L,0xcf1912934d78291dL,0x8e0d4168482396f9L, + 0x7228e2d5d18f14d0L,0x2f7e8d509c6a58feL,0xe8ca780e373e5aecL }, + { 0x42aad1d61b68e9f8L,0x58a6d7f569e2f8f4L,0xd779adfe31da1beaL, + 0x7d26540638c85a85L,0x67e67195d44d3cdfL,0x17820a0bc5134ed7L } }, + /* 28 << 0 */ + { { 0xc76afaa373b64643L,0x4169b4117b3c1220L,0x550e0bee8ff22c6fL, + 0x8fb0c597a4da3e15L,0xd8232f8b4e492aa8L,0x55be5764d37da1a2L }, + { 0xf1bc89b628e77f9eL,0x9ff769c4875fee0fL,0x184bd4733ad6983aL, + 0xc48ee6f3b033c112L,0x792377fbf8eb8319L,0x05cdca3fe7988176L } }, + /* 29 << 0 */ + { { 0x019d6ac5d3021470L,0x25846b66780443d6L,0xce3c15ed55c97647L, + 0x3dc22d490e3feb0fL,0x2065b7cba7df26e4L,0xc8b00ae8187cea1fL }, + { 0x1a5284a0865dded3L,0x293c164920c83de2L,0xab178d26cce851b3L, + 0x8e6db10b404505fbL,0xf6f57e7190c82033L,0x1d2a1c015977f16cL } }, + /* 30 << 0 */ + { { 0x6a7a3464d0cbcea0L,0x76aad8b813126388L,0x519b9fd50a183232L, + 0x15f9abe1feb6b100L,0x7002990485ba4143L,0x92cea8f4c4360dd8L }, + { 0xdc6c5d1dc12748a1L,0x1846eefcdd3eb156L,0x3117dd04d47a41dcL, + 0x96c21b29f6a167f2L,0xf569446a27555692L,0x941292e500f88cb2L } }, + /* 31 << 0 */ + { { 0xa39c89317c8906a4L,0xb6e7ecdd9e821ee6L,0x2ecf8340f0df4fe6L, + 0xd42f7dc953c14965L,0x1afb51a3e3ba8285L,0x6c07c4040a3305d1L }, + { 0xdab83288127fc1daL,0xbc0a699b374c4b08L,0x402a9bab42eb20ddL, + 0xd7dd464f045a7a1cL,0x5b3d0d6d36beecc4L,0x475a3e756398a19dL } }, + /* 32 << 0 */ + { { 0xad852b878c0a64a4L,0x0d784cf208f779d5L,0x1896b9fcc651b1ddL, + 0xba8953d612e8dc87L,0x3a9865baa631cfb0L,0x5dd2a4a0626b3d79L }, + { 0x1148bc72687c20bbL,0xa372dfc2f2a52bfdL,0x77315f9e9448fd08L, + 0x4bcb06f00a2377b6L,0x73b42725b35b4ff0L,0xc510ad93aabca99fL } }, + /* 33 << 0 */ + { { 0x61333a382fb3ba63L,0xdf330d9d5b943c86L,0xbbc7c7ee955ef3afL, + 0xda631fc160f09efbL,0x68af622641d5c400L,0xcc9e97a46c833e9dL }, + { 0x7fd73e8e3a625e76L,0x13bf6124c209e55eL,0x08467cea48b90b91L, + 0x8a416eb9bb6f0abaL,0x6fcc93a1b8c31072L,0xa7fd2b619057dad7L } }, + /* 34 << 0 */ + { { 0x80b309dd2ada5bf4L,0x0648c2cd2d668c41L,0x45700722abb9102fL, + 0x9d6ac102b4e25201L,0x7ec2bc1cd50b3e6dL,0xcdb55e6ba07b7caeL }, + { 0xebcbda0786da3943L,0x470ddc68f8a57f48L,0x9e1418a4554557c3L, + 0x02d00cfb8a76b2d6L,0x03c050a061520726L,0xa964eefbfdadd24eL } }, + /* 35 << 0 */ + { { 0x58a5b5433720ec9bL,0xbb3800d52d7c2fb4L,0x4a508620dde6bd0aL, + 0x65f16273a02583fdL,0x832bd8e34fc78523L,0xd6149f75e9417bc6L }, + { 0xfeb026e93deeb52aL,0x0ce18088a55e0956L,0x50018998988092a2L, + 0x22f19fab28f35eeeL,0xac8a877f52ccd35cL,0xb13a8ad830e23f26L } }, + /* 36 << 0 */ + { { 0xf216aa2531238ed0L,0x4a13260770b1b757L,0xa39180d45c2c7ce1L, + 0x9f82b7fbab52606cL,0x6f01faee26946e78L,0x1608643883061d37L }, + { 0x597edf370fb077bcL,0x1d11bc5ed6e28138L,0x10209418c167fd20L, + 0x6a3258ec33f55675L,0xdf33eed7b73401b1L,0xf699887b806085b7L } }, + /* 37 << 0 */ + { { 0x0202d57de44f61a3L,0x4027704bb5630ef2L,0xa129e2dff5b54a5dL, + 0xacb60a7597482b86L,0x9261ede87ef27114L,0x1eba28f3defc58b5L }, + { 0x6c91c0c98be5589eL,0x2f1643d514594beeL,0x2ea912435d2ca034L, + 0xb50649a894047d1fL,0x284fcbb5638ca337L,0xfa0e07b7fe85bf85L } }, + /* 38 << 0 */ + { { 0x4703cd85891f8ffeL,0x018843c01c0d7702L,0xf3d752f5ad6cbeacL, + 0x479ecf018173fb32L,0x6b464412bc9a48c7L,0x47ba96091da7b147L }, + { 0x91af26eaabc13488L,0x87c183c3e1a0e06cL,0xdae2479844956b93L, + 0xf300e1c648347f9aL,0x129be314974320a4L,0x1f466694520618f2L } }, + /* 39 << 0 */ + { { 0x7d894f80506e0e42L,0xd984244a8e3d2c46L,0x6d7edf642b7f006fL, + 0x36a1cd6dde9b6230L,0xc9985040b76c0665L,0x587df4d6b89b1fc2L }, + { 0x4c0638476a71ae7aL,0x7b2b0ab3e8294747L,0x345c553ab53153b8L, + 0xb646e453436d9fe2L,0x1a95355f1cd60340L,0x2d7bc128074968fbL } }, + /* 40 << 0 */ + { { 0x6048c6949399c38aL,0x43a53ff21beb359eL,0x86fcfe4760be3ebcL, + 0xae78bc3a3134216cL,0x3b021cf316d7a9adL,0x51c4b1b36a4d6e81L }, + { 0x54b9cd8db593d816L,0x1df8cc84a69ea3a3L,0x98ff87f7370eb744L, + 0x63a00a0a60e0aa2aL,0xdbb22c9ddeb46e6cL,0xdfd92b6da914bb01L } }, + /* 41 << 0 */ + { { 0xad148e87bca6d14cL,0x41dfd24d456a201eL,0x73a82933a80d68f3L, + 0x89746c8d852ca035L,0xe3bc778895fd71aeL,0x8764cd2cda92245dL }, + { 0xa2fe2c4782eb23e2L,0x5ac762e00f3c9d6eL,0x57860ce121646f31L, + 0xbdc9d6c34f9f589aL,0x679952c7d193272eL,0x82ea702eeb18f1c5L } }, + /* 42 << 0 */ + { { 0x18ef56cd5d76b881L,0x31b22efc5df46c66L,0x4b21c4f3eb6c7e62L, + 0x3fd72a308f234c86L,0xe983e169ffff96c7L,0x7438b4933c1e593cL }, + { 0x863a23a3a553e8e3L,0x0d959ba9796d9129L,0x25d0caaeda1eadf4L, + 0xe739fb61eaa67763L,0x50029568472a7175L,0xdb6829c2f002bb6eL } }, + /* 43 << 0 */ + { { 0x37fa935500846d44L,0x09112fc50578bc8cL,0xdad9f5b239c4943dL, + 0x7314f5f0416dbd86L,0x5cf095a901fefb56L,0x35178bad22dab393L }, + { 0xcf79fc1b36baf1a7L,0x1b7ee42d749e5498L,0xbce78aa9ede314bbL, + 0xaaf8e0f6bd0628dfL,0xa974b09415cbf948L,0x8f3f1f63c9632b78L } }, + /* 44 << 0 */ + { { 0x1c5f0e5b36a400d3L,0xae97af8bf240b30aL,0x767b4ad7f8f99b51L, + 0xd50a288981ea36c2L,0x04ce2a21986c5ce6L,0x9c7e7754a320d352L }, + { 0xc3336331bbad8346L,0x7cc82a4df1698fb2L,0xc680176505c7ad6cL, + 0x47678afb27dda8e5L,0xade6096d02e543aeL,0x5fb28e322a1dd73bL } }, + /* 45 << 0 */ + { { 0xd4c411564fddda5bL,0xd4af65c673ad9112L,0xffe8e0bb39eb8f59L, + 0xb0040c0e8d6fcf13L,0x99e1c0c61f2bb599L,0x9c94c858b2ac3405L }, + { 0x8f8878d76eeed85dL,0x62b2f54351fcca3fL,0xeb3b44a9e5b56918L, + 0x16f96676b7234e93L,0x17477722bd2af19eL,0x42eb2979db83a485L } }, + /* 46 << 0 */ + { { 0xa618d7479fc4f435L,0x9f24fba649ddd10eL,0x60976b01b472d789L, + 0x9266634957719f54L,0xd9c79db800541257L,0x374aa9069481ed0dL }, + { 0x60efb1147fdc2d7aL,0xa1590c30ecf58643L,0xd7a198a4185a849cL, + 0x19ab802314eb4ab9L,0xc82d5998ec090d06L,0xfc539eb3e259c7dbL } }, + /* 47 << 0 */ + { { 0x6f888f7df0c668caL,0x65c788785f0dc66cL,0xbfb185125f5b07a0L, + 0x780abff7d878acd0L,0x504f21b1570cf950L,0xea5b37c5da233371L }, + { 0x487ae8bd22437ed1L,0x9c701758249cf9b7L,0xf86562a898fb34ffL, + 0xdfeea1a265e0fc91L,0xeef006912e20fc23L,0xac9dfec7dfa72a8bL } }, + /* 48 << 0 */ + { { 0x3ccf806ab35bf6cfL,0x2d368d48e7f30c2bL,0x4f504e06ea52bef9L, + 0x40d01ff53a7d2f3cL,0x62e5c5d3e73a1bc9L,0x66e4794bae7d7400L }, + { 0x3d30625e5ffef312L,0x4580609da766ddf1L,0x5c3ca10d04bab985L, + 0x2605ca009da2a2caL,0x48eab00eb5c9462cL,0x271e42a12624a583L } }, + /* 49 << 0 */ + { { 0xfa5c3aef697136c6L,0x8ea5af63a5ea6fb8L,0xa669156542e365a4L, + 0x47c56c115b6e3386L,0x1197832bcea03f56L,0x0b470bb250e4ea9eL }, + { 0x3113c74313b25712L,0x8d6c174ed2497d48L,0xfc4486ee49c9ebe8L, + 0x2487edd57f82bdd3L,0x771e64415b57be2fL,0x2d1cc518e28b2bdbL } }, + /* 50 << 0 */ + { { 0xa96763d2fba32d1fL,0x172cfe4ecb5af900L,0x510bd675cb2ec3f1L, + 0xbeabb91ac3c90051L,0x9cbf755b46f97ac7L,0xa820e8303a5d50d1L }, + { 0x83a9f17e308c4545L,0xdf7dc7053048461aL,0x6124642f0f32b151L, + 0xc1b444139333e405L,0x6f7bfa7e13a4f7d6L,0x6f58fa8b7181c2a1L } }, + /* 51 << 0 */ + { { 0x2c4ccac72070ac8dL,0x1947c0caec4a22b8L,0xa5e0fb598c5a78d9L, + 0x464ae8d241a84de7L,0x3dba16e9daaabc27L,0x16634a504f35cb3cL }, + { 0xadc18bf9b16ec84fL,0x324d067e7359dd35L,0xdaeac0c3570543f0L, + 0x0b2240003c887d36L,0xc69489e2373f1a0dL,0x518b047dcbaa0d97L } }, + /* 52 << 0 */ + { { 0x8f6468656f9201b9L,0x8a944b316b326232L,0x5687d1dca6ccfd35L, + 0x0bedaa85e5377c00L,0x252b48f5cd8d7d77L,0x4b820d9b31d83660L }, + { 0xa9e5af3ccae07f15L,0x0a8930fc1208b9faL,0x6d0a166ced3c3b7aL, + 0x90e2aead7f78aaf8L,0x222465866e5ede76L,0xc5cc339dcba1fd4bL } }, + /* 53 << 0 */ + { { 0x3b1bddc6fbde49efL,0xdaed7c268a0915ccL,0x0b0110610f0422a2L, + 0xcf485c74a7c54b16L,0x642ec4e615c3aae2L,0xa8ba8f10e0f383eaL }, + { 0x2a2054b495618501L,0xebec6442089efa8bL,0x5786a19a4e2fa83eL, + 0xd2c71ad139069963L,0xadc93d9a481765e2L,0xedf2e3eb7ecc9485L } }, + /* 54 << 0 */ + { { 0x11853add834e6c54L,0xab2f15202175fbf4L,0xcff00bd23c9b5a41L, + 0x075134ebabd64a6aL,0x48c075daaadd6150L,0x4576a6497cb89442L }, + { 0x340a767034adeda3L,0x8dbb571c77fcd1f4L,0x0bf879d693b44ea6L, + 0x1ae1dd97d13444bbL,0x6e9e86bb7b1eb77aL,0x420eb673906a2949L } }, + /* 55 << 0 */ + { { 0xbcab5f60069f3367L,0xfd6622bc1718ec3cL,0xa4fb7867e3a142d6L, + 0x6078d8bf085faeb3L,0xfa5cbfda60f4554fL,0xb3fcd5d1690cd408L }, + { 0x4ebdee7d281f7884L,0x82af23aa180a63a7L,0x8de3107c3d079f61L, + 0x17c6b5cbbe2334f8L,0x6a91e73997d0fa06L,0x7460257314ceeed4L } }, + /* 56 << 0 */ + { { 0x483350a5ebb8cdadL,0xd4215b4fc7a8baa1L,0x8b6fc785e692fdd2L, + 0x2629ba4fd1deca25L,0xe9981ea6820da79fL,0x7772a913e6436cc1L }, + { 0xd141235c553fb41dL,0x28179e6cc852f64bL,0xb623a1aeeb8cc21cL, + 0x05826192490bb572L,0x56fefff326f349ceL,0x31ff648e0f88b82dL } }, + /* 57 << 0 */ + { { 0xb14ba61cf97f865cL,0x73bae4c1694b8b0dL,0xa14967dfac4bbf62L, + 0x1e9dd1509bf446e0L,0xc052f3eb1c99ceefL,0x814d7fa07a78c189L }, + { 0xa101a483ab74b05dL,0x7788c258a1737b65L,0x0d60bab7e809a13cL, + 0x8f427bc473c81d5bL,0xd2e130552952c1fcL,0x0a823b9a4b26df63L } }, + /* 58 << 0 */ + { { 0x941c5c257d0be180L,0x341cf9d9c46785afL,0xdab9dc0015b0fa13L, + 0xa58db4ea4f96af4fL,0x9e9520bf57acc87aL,0x104cec0666ac72e0L }, + { 0x9f3f7baa1929e675L,0xb8b4ac9ffa80380aL,0xb5f157aa569b57d8L, + 0xe11699e909fa58a1L,0xc08595e35548fbeaL,0x2b51995f794da901L } }, + /* 59 << 0 */ + { { 0xaf467ce227bf64c9L,0xdfca6897f929974cL,0x64473b595c322738L, + 0x96a917cf1ed0e315L,0x3703435b0de64db9L,0x9ba039679267b646L }, + { 0xdf0c2aae3a522fbeL,0x41bdb741b335eff0L,0xaccf2edd7b059703L, + 0x6fb34b3028463cceL,0x96d9ba0bd9e3ca19L,0xff336f12504655c1L } }, + /* 60 << 0 */ + { { 0xc711d5d1c425543eL,0xa61fada6fb4f60e8L,0x0402d5c4eb809f85L, + 0x84b7c2fed74cccd4L,0x61bba736a55b5277L,0x95bb80cece47968cL }, + { 0x09f92adc16eb7b95L,0xf0e0f4f7e682aa29L,0xacd70b86ad2a20fcL, + 0xbb45a51f948a8375L,0x29fc3b284892e676L,0x8dd21bf0b4ea4f51L } }, + /* 61 << 0 */ + { { 0x48da1fd3fc60a6e0L,0x54fb5a34222241e8L,0x6035e34f772ae080L, + 0x5ff77ff2332982d0L,0x2366467300fe51fdL,0xc93ea049ef6ba006L }, + { 0x6640f1177d381266L,0x394d32cd6ae9f4acL,0xe6a7885370d303ebL, + 0x0dda19ffe5275767L,0xb0a6c77201466d23L,0xc4cc11451fc69829L } }, + /* 62 << 0 */ + { { 0x49a04dc0f5acf772L,0x1e659730c1fb476eL,0x0c7d749907dbb9afL, + 0x03b9f1cebfec21daL,0xd194b7054b14d117L,0xcb4c0a54561fedf2L }, + { 0xaf623d3f21da4d42L,0x5f5e9b1fd630c145L,0x65609e59d9ff0abaL, + 0x3d2508922ba9239bL,0xcac324ec82c4faa7L,0x0902cc23149446b8L } }, + /* 63 << 0 */ + { { 0xc5c0e6d7aaed89c0L,0x6ce8ead6149a1896L,0x7a50f7458c949f8fL, + 0xcd7e35f76e2b71aaL,0xf6159e519a049f7aL,0x1c9bf0b0f1e52d1eL }, + { 0x3bb6c1f518202c80L,0x8d3a5f621ecd7b1aL,0x3bb034e888d17f19L, + 0xdc89bd4997d4048dL,0xf5af7b8e3735df22L,0x52bb3712a0a689e8L } }, + /* 64 << 0 */ + { { 0xed4de4f88e89b258L,0x957c980f297a9a37L,0xe04b3d30f8a0580dL, + 0xa309199dca57b7bdL,0xfc8e87cf3be44d56L,0x4f5d5ab6d1b30e5cL }, + { 0xb213c6a030a9325bL,0x0fd1c52df091bc01L,0xfe51bbbf1090fedeL, + 0x6d97cabc301fe259L,0x3ee127895ecd3fe8L,0x888b708b9404ca51L } }, + /* 0 << 7 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 7 */ + { { 0xe484fd9f8258030fL,0x0f4fa5eff21af80aL,0xc0dd449e7c1c3984L, + 0xf313389118eb5195L,0x0336aab8777a16d2L,0xa6661cc4c241720aL }, + { 0x678db970a7efacd0L,0x228968656461e382L,0x5d85a0e4a022c7a4L, + 0xb01f1e0434a02a6bL,0x2657eedda5791ce3L,0x239dcab2a277ac5bL } }, + /* 2 << 7 */ + { { 0x9a7a5b426ae54da1L,0xcfcadaab7040b022L,0x7539438e3d9f0e61L, + 0x013c6719e328c2e2L,0x7f4a706ccccbf891L,0xa335ab82735a2d28L }, + { 0x46694ef03d984124L,0x0e0bdfabc166b337L,0x9d54ed8b423d47e4L, + 0x8075a8cbf44c9180L,0xd4f5b184abe9b384L,0x424dd00b41abdc75L } }, + /* 3 << 7 */ + { { 0x99a710b1400f1d87L,0xec3ca386ee47be8bL,0x3a00dcad37168feeL, + 0x1a69d6741765a0dfL,0x85233afe917c4909L,0xa3aa97a4e9bd6210L }, + { 0x01010526310885f3L,0x21c5de3fb5007b08L,0x5df0c6efee8ddabdL, + 0x5d17d45a0f6dfdefL,0xb73d831a251c9f79L,0x397779e6cb1df19dL } }, + /* 4 << 7 */ + { { 0x5e2cb07fd7801edfL,0xf9fa2c0b3adc065aL,0xa296c53fd4de1f25L, + 0xd408060c838f7169L,0x68e19d7b2e8a6ce7L,0x2cc6e06c94b58671L }, + { 0x93d02a07c1cb6151L,0xa10fb4cf35003126L,0x6aa069f51aa3bc4eL, + 0x0e44fbf0dd09b142L,0xe264f343832e5945L,0x5dca2adc1fc166acL } }, + /* 5 << 7 */ + { { 0x5f63e391d7afb4c6L,0x85208bcd2bcb4a76L,0x10022d53c3da8fd7L, + 0x607538c007e50047L,0xdbdb0e7212793242L,0x8e6b9f6135eb668fL }, + { 0xbe5632887e1da455L,0x5e73e1a06e544e82L,0x0c28a5d29a2da4deL, + 0x62b30a8822326300L,0x470764f16013086eL,0xcbe2c34cd3ef5fbbL } }, + /* 6 << 7 */ + { { 0x9ee4f522b0f6c604L,0x5b8a689d52736e58L,0x0d5f396db7edb07cL, + 0x09b3457c2e829063L,0xf1d28188f83495daL,0xba2511e6cce559b8L }, + { 0x17cbaf57d8f90669L,0x3ba19a1c514eacf0L,0x298208995145b8fdL, + 0x92cb5da81a33b1a7L,0xca49fe334c5149e9L,0x5c499b661772b4c0L } }, + /* 7 << 7 */ + { { 0xb98266b132508180L,0xf5008b926719d49dL,0x50c513f98069ffe6L, + 0x99ceb828a7c6f38eL,0x375b8a8225e2a436L,0xb8197f6c416c073dL }, + { 0x01663a25eadf09ddL,0xfa2ca1571d7ff230L,0xf3b65b2545284aa4L, + 0x144dbefe648bd565L,0x6095ed8ab4c24e35L,0xe1f1fa3696ff2020L } }, + /* 8 << 7 */ + { { 0x56ad7582a0eb176aL,0x085b5a366e19aa00L,0x85f2c6ffe2c8b036L, + 0x55c6d357fcd7336bL,0xb1ecc56d22a46acdL,0x8e0f976736277ac7L }, + { 0xa4ed11e901878921L,0xd38355667f4fb650L,0x5fdaba45266158aaL, + 0x6f0b27fd89e0dff0L,0x32ef7ae2eb6b02d0L,0x2f145871cc1b46e1L } }, + /* 9 << 7 */ + { { 0xc7698dfd4b449cfeL,0x78aacb7bd1517720L,0xaf0f6ef574cd5f32L, + 0x026f1826f17954e3L,0x33ef67ab2453185bL,0x82f0fcc90a420c0fL }, + { 0x5b444b3645f154b1L,0xb27c4ece70d17f90L,0x6417e0d039282194L, + 0xebfb5fa001aa4f4fL,0x9cc5d0b573932754L,0xe8b56699704ffd85L } }, + /* 10 << 7 */ + { { 0xc112733b9d4075dcL,0x349281c187737549L,0xbb7d8e0181009785L, + 0x7640a3e2bfe16c4fL,0x4e34813ec1d9f810L,0x61985fbc8d2605d7L }, + { 0x2a544cd8e3f66442L,0x48879af56a7c9e94L,0x9e6157bacec18a7eL, + 0xa555fc9511b882d6L,0x4305a4dd04f86563L,0xc58ed7631d0fd96eL } }, + /* 11 << 7 */ + { { 0xaaeec0f9b726e2edL,0x243ba6614493d146L,0xd799c3408980a9fbL, + 0x886e4f44ed060f57L,0x52126b82c1f83f6eL,0x8b4978441df301ceL }, + { 0xeb2a98abcdc4e434L,0x87dec119474e2c77L,0xcbbc613092eb1528L, + 0xb0b0bcf7c454f37eL,0x404d97a7e1a919d3L,0x26d1baa825e62c30L } }, + /* 12 << 7 */ + { { 0xf04145e82d2696b3L,0xaffb66acf4fb2928L,0x9ffcba4e12aa299fL, + 0xcc5ec24991b3b517L,0x9edcd4616f81c747L,0x0a96090a77a883ebL }, + { 0x9b0bab58a2aa4badL,0x76359a5e8f9b84e7L,0xfe8cd81e438a9d43L, + 0xf40e2b5e25ca8b3cL,0x4254030067bc720cL,0x883002a46b2446a3L } }, + /* 13 << 7 */ + { { 0x4b43bd3206c3aa7bL,0x83ca2db60a470b08L,0x07c1036c06f22f37L, + 0x312e04d7bbb46ed2L,0x6a1d70a40193e5f6L,0xc69720e8ba8a3f38L }, + { 0x2c003429468a04b1L,0x885c43bfbc83fe25L,0x65a65259393e00e8L, + 0x7154c7ac2af17741L,0x682224d331dda744L,0x6183dd8bc80b57f5L } }, + /* 14 << 7 */ + { { 0x80e1cd16c496089aL,0x7a59f4c06ec2000fL,0x67a019d509ddce06L, + 0x52573e3e70c4b032L,0x16d253e14d3ba57eL,0xa43c6d42162504f7L }, + { 0xa237bbf952ff95e4L,0x81187e659acb7273L,0x4b13531a1f384daeL, + 0x39067f3398125165L,0xe98fb141672dccc1L,0x594baca0a75e27b5L } }, + /* 15 << 7 */ + { { 0x85e12293c205465bL,0x57bbcfb1b71cbe44L,0x201ed45c1bc85881L, + 0xccbc39d5ccbe7dacL,0xc509b77f9277f310L,0x171b603aca1b70efL }, + { 0x9b99605504d2dbbeL,0x986d6323451c918dL,0x75ad922f63c6fb03L, + 0x69e2cca49630182fL,0x1389a2b7f7b34d1fL,0xa66a80323d4f7c7fL } }, + /* 16 << 7 */ + { { 0xe65245cef6e9f82cL,0x9e234dfff6da7b5aL,0x5677c121bad2c806L, + 0xc52dec32060fcf24L,0x78d070675d78cccaL,0x630002ea1bc8b6fbL }, + { 0xc5cb86beeb2e99aeL,0xf13981e78551d16fL,0xfbb7cdf2c92a70d7L, + 0x5a9ff1f1f53cd2a1L,0xfdbe6b7a984f1139L,0x4403d046a470a9f1L } }, + /* 17 << 7 */ + { { 0xdf8c9325efcc63faL,0xe0d35cd966563147L,0x140b9a8bc144d7b9L, + 0x492bfbd70c17c75fL,0x3cbc2b644c5c4d8bL,0xfecfaf47ff8a3328L }, + { 0xaf341aa179b8c3d5L,0x5e72713ff04f29e6L,0x652219fb9f5b6fb6L, + 0x9deeba3f0764460fL,0xb8c2bfa5fa069d0fL,0x5d3e6fefe57be3e2L } }, + /* 18 << 7 */ + { { 0x52c9b94decd84cacL,0x34c2d0ad446dc59bL,0x5563701d951878ceL, + 0x92e2fc1c843c9b1cL,0x2309a5f13dfc7a98L,0xdaf117dc0c57a156L }, + { 0x5739190d359fb843L,0xd433e9bb4b88e3a8L,0x4d6bb0e2c47a1f45L, + 0x511eaa33d7b59627L,0x42ef82c5e389e532L,0x641a0bdcd75f4c08L } }, + /* 19 << 7 */ + { { 0x3ae32dbdc7e30cc3L,0x0c970135af5d0ea3L,0x8fc38e50bd9a0528L, + 0xdb0506791bfa634aL,0xf3514fbd245cb0dcL,0x3a3c8c6982319ddeL }, + { 0x92136baf6426632fL,0xabc3e24aabdd5641L,0x8ccae1429cc004baL, + 0x6c9834d8b3ee0d66L,0xa807ab63e1f7e8d7L,0xb4598e2a220aea7cL } }, + /* 20 << 7 */ + { { 0x19821469d678d1a3L,0xf9fa42e60df2f58dL,0x1177daf49f284ba0L, + 0x6dd2ad3d2a201dafL,0x667b0e383d427075L,0x39b76d1d4212b65aL }, + { 0xc6720ae0bf3612fcL,0x72559d98775f8137L,0x466e8e4476c48a09L, + 0xa05f8eb07fb5428aL,0x7fa1fbce5e36b7d3L,0x13bab84f8d1fdcd1L } }, + /* 21 << 7 */ + { { 0xf1876140ed6f3524L,0x47171ee5cb94b2adL,0x56d836abcb8de844L, + 0x346e80890d3b4271L,0x0110df1fdabf6a02L,0x6850fba1f571cb92L }, + { 0x490cd9af6209f064L,0x41f32d5f1cf5636cL,0x558bb7ddc328f9dcL, + 0x44abd0b9d32e3e4dL,0x2c42a5607fc2ff0eL,0x8b1dc5e12c9931f5L } }, + /* 22 << 7 */ + { { 0x6a35f6efdca1ce69L,0x04216d3184de3658L,0x3c3010df732f31b1L, + 0xe4421a872c1444b8L,0x17c987a3c59c1ccbL,0xd67159dba297df1bL }, + { 0xd13aa7a0bc96041dL,0x686d7b77f44c3d8fL,0x6c2e505f09b2b933L, + 0x8c04eb8256161b34L,0x61785cb4b344bec6L,0x60b4d06cbf8b0b45L } }, + /* 23 << 7 */ + { { 0xe5b055481883c1bcL,0xd5bc37684597b8afL,0xa71ae49adb2fae11L, + 0xc1ac1b3e050327f0L,0xd990b2a668f3cb1aL,0x566e5175b74a3228L }, + { 0x348d382957909fe3L,0xe849dd8dd03c2374L,0x4f31a278150fb5b4L, + 0xbfe265cf168c0798L,0x2737c156ce6a34beL,0x4478d6ae4aa6b73fL } }, + /* 24 << 7 */ + { { 0xb5b16cd48d040c69L,0xfdaba315f95a2dc4L,0xc9fef34961ce4704L, + 0x5fe87a0ddbb53ed6L,0x3f0ccc7973d70f93L,0x4601d1bc46724a1aL }, + { 0x5c4a15ae24f08565L,0x5eda1e8aaa577320L,0xe31ebb35bb32d307L, + 0xcdc6f13bdc770a0eL,0xbe3ae514c434c2f8L,0x57c7fdf63a0ef0d1L } }, + /* 25 << 7 */ + { { 0x85165ea2d71c01a5L,0x3935171c99a29e59L,0x2aa1b5837d326190L, + 0xb1d702f8e79f3959L,0x94100c65c6ddffd0L,0xd1d56d626a9c54c6L }, + { 0x5c93b4cf7ce12b66L,0xfc28574bb32a90caL,0xcd654a96e755969cL, + 0xa06f436cd1bec664L,0x9b27c110ffb6f3e6L,0x529b77d317b476c4L } }, + /* 26 << 7 */ + { { 0x04c3d9e162ccecd4L,0x6050bc1221cb59a1L,0xb33847543cbb7e07L, + 0xef2201ac4cf1be50L,0x99c3dda42d2ac886L,0xad19cb0ab776eff3L }, + { 0xd326dd7f5a3d9036L,0x9fe56af2e5b27667L,0x3d849fc072cea4d1L, + 0x262a0cbcd6aa9e3cL,0x8286211885401b09L,0x8ec71d4b98fe8047L } }, + /* 27 << 7 */ + { { 0x9b769cc43c6b2de7L,0x433d4c26acb13b6dL,0x52878f517530ef4fL, + 0xd0e7ce94b0c5354aL,0x5b094d461d92dbc1L,0x75f681449e4ffb31L }, + { 0xb9b9e97351b9d1e1L,0xc147ba4698661569L,0x2a06f4cb7a239309L, + 0xd5cb5ad420928958L,0xbde0283bd5bdf5c6L,0xb91664a082e43c18L } }, + /* 28 << 7 */ + { { 0x8fc0cfa6e51d078aL,0x431d9dd5744ca779L,0x37a4f3120e96e887L, + 0x9c3624fa03ea5144L,0x47d5ecda0b1127f4L,0x018ad424807cf96dL }, + { 0x58ba530f586b16b9L,0xec7271ed72f47883L,0x8d2918da0281ac88L, + 0x6d0f14ef002330c9L,0x1a90a01591dc35caL,0xeb8e71e9c81607dcL } }, + /* 29 << 7 */ + { { 0x2eab9c5ee6d01fd3L,0xe030e6d23fa77f57L,0xff41311877edc0e9L, + 0x7817766bb47ca351L,0x70c987e36cb15abaL,0xc3c867ace19c5aa4L }, + { 0xc24ec23ea05c3810L,0x3965a165c4f0f350L,0x52af99cf7c0d8e5bL, + 0x2d95d23c106e0b12L,0x27507b297f6d44d3L,0x33da846858b191f9L } }, + /* 30 << 7 */ + { { 0x8e5785629aa664e0L,0xf3a1cfc329a97c9bL,0x91ce3b404037bd09L, + 0x34c447b07f9f2482L,0xebe360164010c2a6L,0x7b8b9b3afdc0a861L }, + { 0x0e60c49199c4ff9fL,0xf1cf53b1053e703bL,0xabeae550dd974a16L, + 0x28ac5a34994ea50eL,0x9384617d27329793L,0xd04db83ddad0aec7L } }, + /* 31 << 7 */ + { { 0xcb0ec2bd4b1537bcL,0xd0de683cbac6569bL,0x0688dbee5c96afb7L, + 0x7c7d192f3324ab6fL,0x1455b1e6165fe655L,0x32d135a1ccfe9e1cL }, + { 0x05a80a2af9e1a86fL,0xdc946c70479c71f1L,0xf8b9ad985aaa0ff3L, + 0x78cf198ef195bbceL,0xadbc082dfcee6b59L,0xe6e1fa844cd19e25L } }, + /* 32 << 7 */ + { { 0xeb06571c0f547ebaL,0xf292c38d6246c0dcL,0xa185966726eed224L, + 0x8d9e56e46100e387L,0x470506b9dc6298d1L,0xb19e084cf3350ad0L }, + { 0x83eb62a812abd898L,0x70f152cc2222342cL,0xb089e880e1bd4a82L, + 0xd4d1e70fcaf3b3fcL,0xd0b1ec6395ffd65cL,0x79f27f3a9b184ebbL } }, + /* 33 << 7 */ + { { 0xb4a7435231a3e816L,0xba8a0af2fd4ada3aL,0x1622289dd8fed2e4L, + 0xb71e579e31d3745cL,0xb090650704a50576L,0xc98b5f20123f900fL }, + { 0x3799ee82d3587b21L,0xafdd6dc79d9abe55L,0x4053ee2aba64b9d7L, + 0xa816246657b3f258L,0xd9b5c4c4690b1169L,0x32c1d3afd091d158L } }, + /* 34 << 7 */ + { { 0xff5a9c58de97d0d7L,0xec086138feede4acL,0x55b14035ebf47cecL, + 0xc0b3e061c619fe18L,0x5644c092ead4ebe9L,0xa1a4f7a41e5e0a61L }, + { 0x8698da06d179219cL,0x86f560bc3f88f732L,0x6ad10b3f1e34a23dL, + 0xd4326bb71307ede6L,0xc93cd2a19b3045adL,0x5a0b733dd8a5160aL } }, + /* 35 << 7 */ + { { 0x68ef87cdeaedf10dL,0x5ce97a07bed10cb6L,0x9b8dbd896ed762c1L, + 0x1a72b05333c1dcd8L,0x6718eff90f97cfa6L,0x02f886e57dda698bL }, + { 0x9db378a8c724f4c7L,0x5b55b8383fa6548aL,0x9935a70ecb24bdf9L, + 0xf5da6936e9de8ae0L,0x3b3a10a79b0c4bcfL,0xe4e6a6e86361c492L } }, + /* 36 << 7 */ + { { 0xb37fc581c634a8f8L,0x06f06c93de1d01acL,0x0f2dac8452fed4ccL, + 0x1673c81bda53f81fL,0x963e500e61e11c94L,0xe86ff87e2144d55fL }, + { 0x343ddf389bbaec76L,0x16a13527806df1edL,0x1361b5ac0a9edd65L, + 0xf20507fe33c0124fL,0xdf64ec1e4e8e0d18L,0x3f6a42e27860a8f2L } }, + /* 37 << 7 */ + { { 0xe6db1c43d38266a7L,0x55bee1a3adec0d4dL,0xe41c403ed56d2f9dL, + 0x5fb703f24d3cd93cL,0x4d7ae8c53d2a7ccaL,0x65c8ac50ffa5fff2L }, + { 0x128814ec264dfa80L,0x08d1372ea642513fL,0xfc5ea1615343a57bL, + 0xc70a6f2f9a2f3f3cL,0xfe61c499df4963f1L,0x2b711eee5cea1508L } }, + /* 38 << 7 */ + { { 0xfc3e9fb252f9a4f3L,0x8bbeeff32180cd36L,0x274312dbd6438c99L, + 0xbd30984a55612a57L,0x344006d609381db3L,0xd9b696f62bcac509L }, + { 0x481e4ea3bef646d0L,0x213033d430561b68L,0xf46bf9a05453f623L, + 0x2af3c4a46d848d97L,0xc35e55a543efa02eL,0x8da254342462874dL } }, + /* 39 << 7 */ + { { 0x1f7fda656a12b927L,0xf628cfac876b9303L,0x1904a0b5d0d0d0b2L, + 0x46d486f6f2894b1dL,0xd35cb5610d243bfeL,0xe759579b851a568eL }, + { 0xb99572e2c1aeda5cL,0x872e16fb1c54cd1eL,0xf5ec9e42a60fdc40L, + 0x59b03a6201a4b019L,0x9c5e7f87e272e064L,0x6240282f24c918a2L } }, + /* 40 << 7 */ + { { 0xc2467f9ab92a9a13L,0x0c3ee8eb6add349aL,0x59250eda45e99644L, + 0x22ce0635c8a2df27L,0xec7b643e312e8698L,0x334ccf2eaebd1587L }, + { 0x0c1c68736bca2900L,0x00beb4c209826cb1L,0x12dbb586cde6b725L, + 0x8d7cee6c66dfed41L,0xc38deba2014de4c8L,0xa3ba6ec76248442dL } }, + /* 41 << 7 */ + { { 0x870be3ebef38abf3L,0x6e0cf541f74dc605L,0x499976bcda4bc168L, + 0x5513c6122548b3b8L,0x5b9a054c3f647360L,0xa47f9f8bde929154L }, + { 0xa2ae9ccbb8ec35b4L,0x934c5c0a4d9857e3L,0xc9dd66cc4b4f01ffL, + 0x42a1afa2e5b5e147L,0xc284e464f3d9b380L,0x67845404e21bbe63L } }, + /* 42 << 7 */ + { { 0x9ec1ed3342ec772dL,0xa77e1ecf5501609bL,0xb059e214a02906f8L, + 0x35b2ebceb28e4d14L,0xb8453ec22cf036eaL,0xe621234b2518fe75L }, + { 0x079d7d11f03cd158L,0x357492f91b2f011aL,0x3c2186da0661992aL, + 0x7adc1c0fe5df978aL,0x88d329db5300cdccL,0xd915c2444c0d644dL } }, + /* 43 << 7 */ + { { 0x1b9797a8f0ff03f6L,0x00dafe43f41c9284L,0x1e565c33f2bdc817L, + 0x63b77ad9784b1a5dL,0x3304540e74aa6079L,0x630524f3d7181d2bL }, + { 0xb4fe5fcca2804658L,0x1e48e50b9e393a6eL,0xb5bccd49397a94a5L, + 0x95394743eef17accL,0x4d67ba5226dd1687L,0x80965c3432349d9fL } }, + /* 44 << 7 */ + { { 0x1d70669e49f1216eL,0x8645472fa5fca474L,0x9242e8ddfc400357L, + 0xe7ac31548623996fL,0x37b9e68ce61aecb5L,0x7d2e10fdb997e4c9L }, + { 0xc0cb59a6c2086dc9L,0xb38e2032d7952172L,0x78eaecf6eebac939L, + 0xece490b42f5dbaaeL,0xdb17501dcdc32565L,0x59bd392ab133bf99L } }, + /* 45 << 7 */ + { { 0x71554fae07de21a7L,0x3dd66b8bcc42db25L,0x9da85c0f0636e9a4L, + 0x61fef273904930d8L,0xcc8f527b73369e81L,0x4207dfab7caeacd8L }, + { 0x99e5d1404fc763d7L,0x5cc6a3739f4e8947L,0x9ef14ec1cde33eaeL, + 0x25eb3aa8095872d2L,0x0db8268d7d9e6dd9L,0x38846510c2ccfe92L } }, + /* 46 << 7 */ + { { 0xce6197e822d0a502L,0x69df7f8e09d45970L,0x0274f48b7eb4718dL, + 0x47461334a8c22b75L,0x89cebf17bf25b9abL,0x57c042f6fdfea412L }, + { 0xb19c338644346b96L,0xdba17de06ba014c4L,0x6697687a5f844d69L, + 0xf16dee4c1a66c6faL,0x7f916e47fdafd0d7L,0x1c3842d2340f158cL } }, + /* 47 << 7 */ + { { 0x417c9ab760efab2aL,0x1745d5c2f0065f75L,0x1a7d86f2ed71b350L, + 0x6d4d504feee5c850L,0x4ae7ee0da657b859L,0x1f72ded53c302a3fL }, + { 0x08779fdae7b22e51L,0xb04c1c0446d90bfdL,0x4dc97219712f96d0L, + 0xb15e8c0041a6be82L,0x384a02cca3804090L,0xcea45861babd1ee5L } }, + /* 48 << 7 */ + { { 0x3c686079d42aeb95L,0xc162e5e985e3ea0fL,0x34cf58611bbb2455L, + 0x7650de1d8773b064L,0x3b7562c6d2bab35dL,0x83191b4433d0741bL }, + { 0x4b604db03a6bd9cfL,0x87cd84db074aed21L,0x02a042d2d4f91f9cL, + 0x5a5d52e5e42c2a67L,0x31291acd1d5f216aL,0x9c3971bccd6203c8L } }, + /* 49 << 7 */ + { { 0xec931d6599e9ec3fL,0xe9d780c64bd554d9L,0xa580534502eca45cL, + 0x84701f1ac1276ca3L,0xcb7ba786d5f9438bL,0xf3a27508c85f663aL }, + { 0x044df512118c9421L,0x1109fd431039871bL,0x7865443de2378386L, + 0x7a5e2d49e70297abL,0x112763ca6824d2b3L,0x8a05f2c90e84bba5L } }, + /* 50 << 7 */ + { { 0xde3bfdebff044924L,0xd7f2a5181a0458f9L,0xc03df0c00139d557L, + 0x7a958c60cd3ad0d4L,0xec9f2f9759a43584L,0x5e0fbba950d8b4b6L }, + { 0x5fbc5e3888245837L,0x17235805a267a54aL,0xdc24a508db55d65bL, + 0x431e4d5623c704d1L,0xb1f85b2277585f9cL,0xb288f25ed0b1c374L } }, + /* 51 << 7 */ + { { 0xd8fd5b405a37c029L,0x5c9d827fe4d37effL,0xe024d7952e046275L, + 0x0661277f913c55c6L,0x21ee10eb904b3679L,0x32c582e066778adfL }, + { 0xc353ab1fba8d17daL,0x1d4ab06b5658ea17L,0xb908cb88a2d70bb4L, + 0xfc215909a98daaebL,0x7aea6c8777000e24L,0x19e0acbe38446e20L } }, + /* 52 << 7 */ + { { 0x1bc3803e2f98532bL,0x39d0c3258754d142L,0xa7b035c5d739eaefL, + 0xd36ddeb8fbfdea2dL,0x7df72a94bdf64f2aL,0xab4ad6b880bc3c47L }, + { 0xdf386df3877fa482L,0x4b94260470519bc3L,0xa3399d91d20e1e04L, + 0x7f5208b797cf58ccL,0x528f6a2814424c00L,0x83d74730bd900d10L } }, + /* 53 << 7 */ + { { 0x501c657f34ded7f1L,0x9071027e12fa53bbL,0x395e16aedff079ccL, + 0xea95dc84770ac4b2L,0x4d2aa60a41355974L,0xe04effa507f12473L }, + { 0x38ca98385cd1c738L,0x3c067a0b683c0dbaL,0x55ad2dec67589842L, + 0xe51550f7dfdae3c8L,0x21a56717214d51aeL,0x75b6a4a012a0fdcdL } }, + /* 54 << 7 */ + { { 0xd63605266a4ea95bL,0x180f72d403e67090L,0x7faf4529751c8c9fL, + 0x1ab7b50d00e4252aL,0xc0e69adf34811274L,0x5c4c83495e99c6ccL }, + { 0xcc9467f29a9e02a9L,0x5402c2da5c4fc719L,0x1dff8c5d3f6d5bddL, + 0x88a7d27a2c653c3cL,0x067f31183a050dc7L,0xca0f7dafc4f0236eL } }, + /* 55 << 7 */ + { { 0xa09306e9ca177c3bL,0xea84f03ed0552a4dL,0x7ae9024f3c00d359L, + 0xe189ebc33aa619faL,0x4adeefac8354579bL,0x90168ef9699db1ebL }, + { 0x75319141ad87490aL,0x7b48fe7629c1bf84L,0x00ae82c7a2235f2aL, + 0x6292c9cf68562b59L,0x0b6500943935ca20L,0x39f22cb027f33addL } }, + /* 56 << 7 */ + { { 0x92e4c851aa1ef488L,0x4f91fc22846528a9L,0xaa2f5d2d5dc13a84L, + 0xba06aa68f1072d4dL,0xf4f3b17c5e3a2ba9L,0xff36a5355e4dde77L }, + { 0xe8ef143aae17dddcL,0xcc82631ba1fcd4ecL,0x97db807ec7d3963bL, + 0xe4aff04521d85ce2L,0x2d6480e674667392L,0xc8ce97f3a55d0b3fL } }, + /* 57 << 7 */ + { { 0x1a32b8457962a675L,0xd78efd71723d217dL,0x9b03d6573b41a2c5L, + 0x1116f33589a380b1L,0x2c0359af931ee15bL,0x8a53744f239ba4c4L }, + { 0x4801397dc78cdc83L,0xc43b9f0434ae4453L,0x9cc8f6cec356a35bL, + 0xd5a74c2a648b39e6L,0xa54d668c0d5e78fbL,0x36257047cfcb8f6aL } }, + /* 58 << 7 */ + { { 0xabeef3461549c215L,0xfec59db2ce4aee45L,0xa1743a0f5305df83L, + 0x9d598abdf211bacfL,0xd14609dd52a513fdL,0xd3dc446be00d4ad0L }, + { 0xbd8883e9b272211aL,0xe991e57757879fd6L,0x5a093d372b732171L, + 0xdd901071f55f18dbL,0x87f04c0034fecfd1L,0x2c07df27c94f6a5bL } }, + /* 59 << 7 */ + { { 0x518e3ced1c17df0cL,0xf8971149ff5dbc4eL,0x5fec8bfe0ac9d27cL, + 0x41d68852489eed7dL,0xf48ef4bf3c3c4725L,0x3b8d9eee7681eceaL }, + { 0x7743ededdaae4bdcL,0xb9665ef5d1bcf697L,0x9d77f535471bb958L, + 0xb5db5b96d752b2ddL,0x2cd3c919c368982dL,0xf8297660e9cff6d7L } }, + /* 60 << 7 */ + { { 0x39e7da1028946a2eL,0x4e628a96c3a76f7cL,0x43b8b808e9f6000aL, + 0x86cbd25ca48bbb79L,0x5ce825e273092951L,0x43a6031df0cbee32L }, + { 0x6d685a594923485dL,0x8d4483ed81a17f47L,0xf61d329bbc379719L, + 0x9deef7d0f6596ee8L,0x0314a572541b1222L,0xe2b34d387ea7d376L } }, + /* 61 << 7 */ + { { 0x05ff6faa31f43d37L,0xfb83f23211b801f6L,0x238792d519b223a4L, + 0x28edadcce004f601L,0xf77747b3bdeb7597L,0x2178dbe21e6575d4L }, + { 0xd48ec49842870ba2L,0x7733661d15dca6dfL,0x08212e2f83393416L, + 0xffa1bfe2614c545cL,0xfaf4ab8494254145L,0xd8f9eb48000d250cL } }, + /* 62 << 7 */ + { { 0x9ff4f289a66132a2L,0xc54fb8001e098994L,0x09d3cd6624cc2471L, + 0x6d0f74167838e14bL,0x7438cd2dc540cbdaL,0x193b16817d6fa8b4L }, + { 0x487a7dedab33c6f3L,0x625eb8cf02f5aa09L,0xd8039682501323bdL, + 0x9de122e38e216951L,0x40a8fbde0711c51aL,0xf192b5c283a474c3L } }, + /* 63 << 7 */ + { { 0x3782cbda57e04e9cL,0xec639886e41b30dfL,0x4cd14afd12d2f686L, + 0x0aa093ee8b768113L,0x6cfc12cdad598f9dL,0xe4a62f1194bcce0fL }, + { 0xd5035fab150ad4f2L,0xb3cd4871ae2e8da4L,0x49c9e78271ad9c3dL, + 0xdcafeb34825690cdL,0xc05fb7a38c246f85L,0xefe16be3a82cc013L } }, + /* 64 << 7 */ + { { 0xd42777314c14ee0eL,0xda8146d15e881c3fL,0x6b0746b099f1867cL, + 0x1ec73d72602dd4ccL,0x27fae51538081120L,0x6a677bdc2f8b2f2dL }, + { 0xb924af64d60544e9L,0x1439e183dcfc6b16L,0x4e88e9ae068565acL, + 0x8a3dbd25a9a4f146L,0xdb4a3e483f93f734L,0xb1971c058f1d33bcL } }, + /* 0 << 14 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 14 */ + { { 0x721bb8363a7f43c3L,0xab5b3108c12dca0fL,0x9cc9a78934853870L, + 0x78b604a7af598c4fL,0xd370375e476f27c8L,0x9f0415b80b15cba5L }, + { 0x2bcfd9a4d400dc1fL,0x2a6fe03b4bc62dddL,0xb05a6464a211b19fL, + 0xce059d419990b504L,0x011c5f87d94951d3L,0x13cec08900d9c7b0L } }, + /* 2 << 14 */ + { { 0xf365419f9b280fd9L,0x13e3b12746365672L,0x8a91c165c41880aaL, + 0x3eb27a97f9712fbdL,0xa6587aec76c55678L,0x7c3a04b702cd79cfL }, + { 0xfc878f9cda712eb8L,0x076e61170fca3e02L,0x09a184d8caf6df5eL, + 0xd32bf232aabcde75L,0xf601d0de03de597aL,0x85d2b5fcc5da2858L } }, + /* 3 << 14 */ + { { 0x3075a7636c888df8L,0x6305c20472e21527L,0x6b1d683e8798aad9L, + 0x0d09624680706369L,0x91db5e7f7b854739L,0x0e63cc6e02d72332L }, + { 0xe929e3ea1f7ff6ccL,0xd53a18a145595925L,0x867916cb93af8be1L, + 0x757e9f56c5c305eeL,0x3f9071c75c83063cL,0xccc0f92d7f6d5bb7L } }, + /* 4 << 14 */ + { { 0xb6029961ae899afaL,0x8eedd66e681b6e1bL,0x82db693b4df3e5b1L, + 0xb5131488a0c3e357L,0xbfb01ff3ccb2f577L,0x28ea947027a72cc3L }, + { 0x26170928e39e325eL,0x42d4876b84f80188L,0x0bec6a634c872d76L, + 0xa0a7cc90b14d9c9fL,0x8a32d2c44f6c7778L,0xe7cd346e3b889a4cL } }, + /* 5 << 14 */ + { { 0xab35a14f5a4a3753L,0x1d0d5a142bbbd563L,0x54cfffc5998d4514L, + 0x1c02f381a77ed59bL,0xe4a7a6ab21c9c190L,0x50059df54a9adb60L }, + { 0x2d0383ba34bd7008L,0x894889bedf1a4f41L,0xe541c62612ac407dL, + 0xcc0e417964c3b62bL,0xdb8ca1f33a0978b2L,0x4ef45a2d287e8c6cL } }, + /* 6 << 14 */ + { { 0xea95b5c9437f2efbL,0x67d3e9b58e52ce8eL,0xfb33102488ff5455L, + 0x883ec9fcc3101dedL,0x056218e20ca5f1f9L,0x4c9b2483bccc65d8L }, + { 0x13199b26123db2ecL,0xbc1d82479aff90dbL,0xc4a9311d367516f6L, + 0x3b40c867cb6e90d6L,0xff674ff84034415cL,0x2787db45a1821e7eL } }, + /* 7 << 14 */ + { { 0xacc263fcadeb8508L,0xb52ebcd719854c90L,0x3d54e7805f2ce0aaL, + 0x2fc056a97e02e760L,0x47e7173e32da5f93L,0x1d468de3fa893134L }, + { 0x9adc877dd73396b5L,0x430826afeeb00c82L,0xfde2c3da96a673caL, + 0x467575ad33e43f9cL,0xc3b2c3a1ec1df2f0L,0xf0348e6f2252a8a6L } }, + /* 8 << 14 */ + { { 0x860ef794609683acL,0xf0631ad39af1c522L,0x322c83662ee7f522L, + 0x58ccd95f54122af0L,0x7454880c2bbb2d80L,0xea173d8286d8d577L }, + { 0xd5a3057cea1cc801L,0xfd08d482bbb2a189L,0x26aac99ec3c512f8L, + 0xc3eac036556d891eL,0x866c3aa7bf9f6112L,0x7c4c8fb9c144f7e9L } }, + /* 9 << 14 */ + { { 0x989eef73a9109d83L,0xbe43bd378edd17dfL,0x14a63abd1b17029bL, + 0xfd14ae365ff76860L,0x689dd0a6b8730632L,0x01eb37f147342f9aL }, + { 0x619bab45e6c446a3L,0x93d26fc97abddba4L,0xda6c120486ffa4cdL, + 0xc608937548758279L,0xaf074ea3034a7230L,0xf220244b82ce176dL } }, + /* 10 << 14 */ + { { 0xc0c1eb0f8343f5ddL,0xa205e66a0126fa2dL,0x37530a3244fd8be4L, + 0x3c7af6f696ab64cfL,0x1f04305076657202L,0x2c59d31c828f3fb1L }, + { 0xa61cba51e7f5926eL,0xb2de427391ebeb81L,0x976f2c34bb855476L, + 0x0c6c02c3269e4f86L,0xc69bed8fe2e01fffL,0x19aa421c480bf7b4L } }, + /* 11 << 14 */ + { { 0xb32e8e229affa929L,0x69ebb533bb7db327L,0x10ac3360a8a8d088L, + 0x066cffa7c485517fL,0x2393e74c12b8eebaL,0xb3a8825a596c8412L }, + { 0xe2b99fc3bc8b6b92L,0xd7716da085ca802dL,0x92f6693f4de5101fL, + 0xe8b0442304be34eaL,0x05b44ef648324966L,0xa89d9499413df57fL } }, + /* 12 << 14 */ + { { 0xad0d24c7b617206bL,0xb8be483f9dd13f59L,0xa55134ff7655aa29L, + 0xa3d103857a5e217eL,0xfbb9eeb53a21b295L,0x1de71555c84a136dL }, + { 0x7579398e0b7487b3L,0xc6ca9575a14dce87L,0x99b32e1e46452257L, + 0x99d54955479d8f2cL,0xc2a8a6a1930b80efL,0x58d9db81656c850bL } }, + /* 13 << 14 */ + { { 0x0c8fe2e04d89b43aL,0xe4d923e77a04e492L,0x49ecb701617df01cL, + 0x6d80f249bff9a819L,0xf01e604acb7f86c1L,0xd6d3a6664b7f1455L }, + { 0x657801c19188fb17L,0x339d79450dc92875L,0xca798cf57ec0b757L, + 0xc0808852a62301c2L,0x2dda13558266c908L,0x22bcde8f5e55da21L } }, + /* 14 << 14 */ + { { 0x6c85a0eda682508cL,0x8350b515edcce6c8L,0xa84a67656f95898dL, + 0x55b0ae971e419847L,0x11115c6edd6a885dL,0x6f0beaf64fb174a4L }, + { 0xaaae44b2815af3afL,0xcf0697b9927a2c1cL,0x37639d62d7d645eeL, + 0x157b7eda2effec37L,0xb55e50759b9c66e6L,0x33a66a1f85f597ecL } }, + /* 15 << 14 */ + { { 0x8260c5339b49bb46L,0x3f3df9d6437cac27L,0xd0723229d972d2a8L, + 0xe544a216d0dd92abL,0xeea4a0f5a03588f6L,0x54006166b218dec0L }, + { 0x0fae2be85778113bL,0xbb9618d68d570227L,0x3ba87360297a47aaL, + 0x9483a8399a76dd6eL,0xa803edaf6eb061b7L,0x6790050cf8067cf4L } }, + /* 16 << 14 */ + { { 0x171898aa8f7782b6L,0x8b7a706b499b3a81L,0xbc0e835ffdb2c1baL, + 0x4ee30281591f5aafL,0xfd71de3bcc272c6aL,0x532800c46e93f68aL }, + { 0x35ee08048365c576L,0x6c2bcc94cd4c0221L,0x49f37ff5957b2ff6L, + 0x315d8e7e5ec029c0L,0x33230602ef324c12L,0xf5847f9b966b2578L } }, + /* 17 << 14 */ + { { 0xed88aa550bf098d0L,0xbc9888fd75f90180L,0x9040919207713428L, + 0x38922bbc1a1f71ddL,0xa430fb65bfbf0f55L,0xa258b9ba867c1998L }, + { 0xa7f69b03b7294c58L,0x2ec0c5de84dbc1e5L,0x41c9e5207dba8d62L, + 0x545573f1795d8285L,0x1c24a375d3075041L,0x687e1cc8fb6b88dcL } }, + /* 18 << 14 */ + { { 0xc29b123e1453b1e1L,0xefb0778820059b44L,0x15554ade9291671eL, + 0xeb5a1980429dea37L,0xf96dacbb6c4b867dL,0x4f5563d6abab4d68L }, + { 0xb5b0ecffcbe76297L,0x5a22996a51d6bd43L,0x0088ec95b7e5cfc6L, + 0x4863a5a1fe373e05L,0x42b7925bc244d93dL,0x85bad13540117113L } }, + /* 19 << 14 */ + { { 0x01725fbe8201fae2L,0xee4d7d382dc34bbbL,0xaddf878afd7c35bdL, + 0x56522d5865536719L,0x595c3dd8f772d4cfL,0xd87c5b6045af30b9L }, + { 0x9cc20b9de7992d5dL,0xdfd53d58d56f1964L,0xaf2947bdc7d42a68L, + 0x9322b73dd19e8ad3L,0xa73a9e843243a6d7L,0x9c7dc57992c203d3L } }, + /* 20 << 14 */ + { { 0x86283e21f9daa551L,0x47fd23f81f696f1bL,0x7d029b1bb9784a9aL, + 0x7c7798bea0c0acb5L,0x41241c716d7c682bL,0x11c6c1131d33c2b0L }, + { 0x5d469ca23565cf32L,0xa949f022bad4bdbfL,0x3d054cc2a13cf4cdL, + 0x13bd21669e3ce279L,0x01bc70e68a4beafcL,0xb39e351d8aba087eL } }, + /* 21 << 14 */ + { { 0x92efa2ebfa6cb068L,0x934209b29235050bL,0xc446ee28d5000c05L, + 0xd4e51912862fb7ecL,0xa53940f111193db0L,0x5f2ef2aa82a7fc57L }, + { 0x1a6b30ecb0210f49L,0x4ab1dac73899548aL,0xb116cc3186737a03L, + 0x56cb33809ebfa5b6L,0x8ac3b61fdfd918b2L,0x65867e3ca102e1feL } }, + /* 22 << 14 */ + { { 0x26072a5d82357232L,0x3762764e9f0fd2f1L,0x9c5813f60c16733eL, + 0xea2e0e03718951d4L,0xae195bd469e63818L,0x241a4afcfa2f9a6eL }, + { 0x0e97519f9165d59aL,0x416bd37358e5af1bL,0xc4e811288197b7ecL, + 0x4145be2c9c6ba0d0L,0xc82cb2a17d40b98aL,0xc3c28487bccfa8b8L } }, + /* 23 << 14 */ + { { 0x920949a810476d2fL,0x5b387bbe2502c026L,0xd1d61a9acd7f026bL, + 0x81003d7ceea9a3f8L,0x6191c15fba5b78aaL,0xacbed41e30ad7befL }, + { 0x1427f1fd6740f72cL,0xb4b5e7c93c475735L,0x6a374d1773029d5dL, + 0xc1e4bfdacd622400L,0x670b9e36c2686dccL,0x1bb236e08dd4085dL } }, + /* 24 << 14 */ + { { 0x84aa863ea4ee10a1L,0x24d805a687919ccdL,0x553f3206b5c399b2L, + 0x775b92173cc109bdL,0x25c01263fe384088L,0xa3c4418bd5f743cfL }, + { 0x3d69705ddf91f1f0L,0x547d46269ebddad1L,0x0198ab1a2626cebdL, + 0xaf8320f285b1afe8L,0xb9c0968ce17e6efdL,0xfedc75c290215bb6L } }, + /* 25 << 14 */ + { { 0x1d375f7dcee34c76L,0x2295f8dbaa486096L,0xd18577928285cb84L, + 0x53fe6bd5e8c46c3bL,0x6f6cb6c068ba071dL,0x654ab4e8964e0f1bL }, + { 0xc70857a9edf6aa40L,0xc313c7852fd26360L,0xd705a86a995998d9L, + 0x413d35efd6989c8dL,0xddc0b2070df131bbL,0x21f64be59c7d70f8L } }, + /* 26 << 14 */ + { { 0x8061d340143ff74dL,0x59e94fc6a23aa7b3L,0xf7c79a0b914c3b81L, + 0x5a836211702c6ae7L,0x2570d63c718123c3L,0x7e86d11ec9f5ce3cL }, + { 0x80f03f9717bcce3bL,0x073975b1465a7446L,0x29f66de7cb357aceL, + 0xe87bd12c04894fb0L,0xfc501a2651a0b5aeL,0x20a3170c02207a3bL } }, + /* 27 << 14 */ + { { 0xaab1f0fa2785a18eL,0xa50192fdb37c657aL,0xe7073b27f0c8a908L, + 0xf3e0451b2c82fce1L,0x8237e128c290240fL,0xc1c631621bbf66cdL }, + { 0x9bbcc2afb6639b7cL,0x07643d299bf0e0c6L,0xf7f070c7671c5be5L, + 0xb09a423a9870ac6aL,0x324503506656cda2L,0x4f404be80584abc2L } }, + /* 28 << 14 */ + { { 0x3ee52d8f5fe63bd4L,0x09f8405c7a7da77cL,0x35ce95c61881a757L, + 0x0a8cf9d9c13e3707L,0xe71258d548d2d3f6L,0xcf4fd6910bbe7c0dL }, + { 0xbd6496e1fb9479f1L,0x711c669aab8cb3a2L,0xcbe8501358cfdfb4L, + 0x655c902b59275b4aL,0x7e0ff05b20f722baL,0xcb00031d42b17aadL } }, + /* 29 << 14 */ + { { 0xc568cee0cef0ae1dL,0x1b3422ca7a55aae0L,0x8dcce5058bb536b8L, + 0x12df74bee92759c9L,0x029abaf02ef962c4L,0x5d30b4359bb1240fL }, + { 0xc62fe8e7d03a850eL,0x67da35b5b08dcab6L,0x6f4d4e75e8ca1131L, + 0x53d6fbf81bd5bf97L,0x596d850ceaa0b2c6L,0x32e918240e8d39b5L } }, + /* 30 << 14 */ + { { 0x3360ff11d54bf1a4L,0xbab994cb5c79494bL,0x953ad553757d7771L, + 0xf17f14f068b58ed5L,0x223615317523c422L,0xf0f05f965ebf0d49L }, + { 0x3386676549182267L,0xf87eccc1ad71c3ebL,0xd7708e18913d8dcaL, + 0x27fe27e1b193eef9L,0x33376365cc45e65dL,0x599b4778d700ac20L } }, + /* 31 << 14 */ + { { 0xb118f73509ebb3c5L,0x7299c7844d0d36efL,0x409ef9cde10b249fL, + 0x040f91d0156401b9L,0x6b9fa5b107467a49L,0x2ede334334415300L }, + { 0x0b3abc9c0edc8055L,0x58f850958ca04aa2L,0xeb0d3202e568b6a6L, + 0x5e57bb1a159dce4cL,0x8d3780e03b68641eL,0x78eb21a0d9f50517L } }, + /* 32 << 14 */ + { { 0xda643272ed068028L,0x86b52135a91fb87fL,0x23865a7c35b43943L, + 0x6ac015884606bbf2L,0x9660ab721559fb9aL,0x1fcb09e73ce2f1a5L }, + { 0x62af29ab793d2f0cL,0xad5aaef53aee7efcL,0xee9f29b744c11037L, + 0xb2a19cf1d36c2571L,0xb87d88e265b552b7L,0xd8b4f172beb253d4L } }, + /* 33 << 14 */ + { { 0x6776241470c50124L,0x157c591f57d0eb9bL,0x99e1e2d769b4bcc2L, + 0x81c2b923a9d94ed3L,0xbdd9294fecbf3becL,0x3825c29a4c4fb135L }, + { 0x431d9f26e915cc2eL,0xc4fb48afec1a4835L,0x97f426c09ada831dL, + 0x0be0cf81d5c48eddL,0x166ee4243d02771fL,0x810bb518b09de508L } }, + /* 34 << 14 */ + { { 0x9f4dd8185038ba67L,0x5ff1572801111ed1L,0x900d44f163de4d57L, + 0xa36c1a67d5db5e67L,0x2f01142e2bf5cea7L,0x1519ae1f59aefbf4L }, + { 0x7b963d1f6d989fcaL,0xa5bb3cb85fce44e1L,0x61087c9672fd3285L, + 0xfb2fc6c1c597ef26L,0x5548e25c81e70a6aL,0xa6c53d67a229d7bbL } }, + /* 35 << 14 */ + { { 0x9d11a26ab9678e36L,0x8142106fbe07b082L,0x3c31548b322fda75L, + 0xa87215ceb7299565L,0xb5229b119ea80113L,0x7221a40f43ae700eL }, + { 0x1ad48de8cc00aef7L,0xc4573660d266daa8L,0x1cb020a65761657bL, + 0x9e799be24588c895L,0x3d209df968561484L,0xa0fb323295fec6d8L } }, + /* 36 << 14 */ + { { 0x9292138a3acde05fL,0x7b23f51a50f9e7f0L,0x6ad891a1af59b585L, + 0xbd394db79654da39L,0xcb8c47315f7c6edbL,0x367bbb5d6d2d6e5aL }, + { 0x8df2c759f51dd55eL,0xce0924d8e6c3517dL,0x49c46188097a8072L, + 0x47169f40980170a7L,0x56198937b96df7ebL,0x09572534531fb3b6L } }, + /* 37 << 14 */ + { { 0x04c18873d2eef240L,0x5752cce75106879cL,0x4b7fbe6bd9736e37L, + 0x7c7f1de4c85990afL,0x0cda6f07a2324ca7L,0x0894eafa4d80c28eL }, + { 0x24bd95890ae7e6d9L,0x050d526aaba494a3L,0x4b05455ee583fb5dL, + 0x3b5fb27c6049bb23L,0xc7c9da6ecb5b411eL,0xc1f2528ebc38336dL } }, + /* 38 << 14 */ + { { 0x8b177119d62ff4b1L,0xb0c02e2783150269L,0xdbeee1f8428f9e51L, + 0x2a55661225ff00dbL,0xb4ebcf98cd0d526aL,0xc69f721fc0efa6abL }, + { 0x0ceeceb516e29d31L,0x0bf4510127d1c530L,0xad942f1f42a7383dL, + 0x2cf389eb03b8fa98L,0x1aa647651ec6acf0L,0xf7ac647c202433b9L } }, + /* 39 << 14 */ + { { 0x880bfb2caa7fcbf4L,0x18c2b739731cd693L,0xd093ada3ae39b46eL, + 0xd48a288796c6fb7cL,0xed7c405daf96bbfcL,0x6b63b9ee256335e4L }, + { 0xfd4795ec7ee8e89cL,0x4f3fa1ccb07320d6L,0xe16c594206b0078dL, + 0xb8c95b563a0b2914L,0x2b5b5ab42b337970L,0xcf612b4cb9f75ea9L } }, + /* 40 << 14 */ + { { 0xbfe63081596eecd6L,0x20eb6fb0a3a194fbL,0x4497ec2b8751a73eL, + 0xf90e9e4cf88ba0e5L,0xd5a9c5d55974eca2L,0x9fc120ade4f3e171L }, + { 0x9ae058a633330640L,0xbda3227855bc8aaaL,0x7851cdbc1c9688a9L, + 0xf68d7d9e1d950edfL,0xc89c645074e06425L,0x62406f3b6116d386L } }, + /* 41 << 14 */ + { { 0x1094390070e509fdL,0x0a8e3db09af61ad1L,0xa487a61538d7aa57L, + 0xa9d56bc5ed020b3bL,0x7ed2294f638b35f8L,0x53d6870dc95fb42eL }, + { 0x85e828494c2207d7L,0xf88831baf0556be9L,0x64a547979fe416c3L, + 0xd61b652e779bebaeL,0xd3f43e2f2c0ccce6L,0xd5119f341f680ab7L } }, + /* 42 << 14 */ + { { 0x466f42a1191938bdL,0x95ec31c036f1dae5L,0xa7f350d2feaa8b55L, + 0x66434577555c505cL,0x0c668e73f55d1ca4L,0xd6af5ba4a7bd7449L }, + { 0x581e14ac1a79d8c9L,0x9761d9763054e915L,0x928e7415d69220a6L, + 0xc5bf4bb405bc4a22L,0xad033b7c45d52313L,0x4e67962c75d66dc7L } }, + /* 43 << 14 */ + { { 0xc60e17b2e2300049L,0x731c2fa54107f308L,0x848f6db7cc2982b3L, + 0xf251c21085275d38L,0xf5cac5b2128c8a96L,0x3c012933405b27f0L }, + { 0x9b0a61520b8b15b7L,0xb1c32dc691fa4548L,0xbe7b7654f366d677L, + 0x7e1f33277147a660L,0x11e31a0eeae310bcL,0x3edef63c1b86b525L } }, + /* 44 << 14 */ + { { 0x6f7e7259c6334c8cL,0xe34cba49b4f2333bL,0x157bf099211d08c5L, + 0x9e39c5442988a4daL,0x796ed9f17a998311L,0x3f4da896d8d349e6L }, + { 0x8ab75656fab28acaL,0x3e215d5342d14b21L,0x50008fd7bec23301L, + 0xd6ee4853446e2c56L,0x203ff1c880da14bcL,0x27a4bfbbc333ba74L } }, + /* 45 << 14 */ + { { 0x745e69dfb3d54e52L,0x1ab2a03e7c405cbfL,0xda71141e0bc431b5L, + 0xb3a47e71aafa7c19L,0x5329594fa88a4905L,0x489b5928973aba07L }, + { 0xbe31a4d37350ad6dL,0x177e5285478a42a4L,0x45a101bf848eba6aL, + 0x4287dfd949936d31L,0xbc4c491dc82823c9L,0x87c816aaeb8b8055L } }, + /* 46 << 14 */ + { { 0x66f5337cf309ced6L,0x897cbcb9eb5ed3cbL,0xeffb601762c35fd5L, + 0xb4b702f081fd31f3L,0xd5203833f66f6120L,0x1d2d5ef318a84d91L }, + { 0x22f9fae70edb3857L,0x034197b3cef00765L,0x16d8c6b493643908L, + 0x90ac59e16c51708bL,0xbed18da32edffd9dL,0xc90ac893e750df1eL } }, + /* 47 << 14 */ + { { 0x4a0af827bdb07e48L,0x5588631e131f46ebL,0xda550ce1e503169dL, + 0x0e16b540f2cf2f14L,0xea19a70dc79930abL,0x5654aa5fa8925651L }, + { 0x2f1a14906104f9c7L,0x98420d6c654cf319L,0xf967467f3ca96df3L, + 0x6abe4e32dee1fc07L,0x913bdf2bbd07d17cL,0xf96f70eda8ef9068L } }, + /* 48 << 14 */ + { { 0xa0096d10b7f8286aL,0x493e88563015be8dL,0xa221d57c17f70125L, + 0x4f932f4fe425eb77L,0xf0fa00df78ddfe95L,0x68165f257866f01fL }, + { 0x01345af4b1693425L,0x3fc8d3a6bad5603fL,0x4269006f0bf46cf5L, + 0x96e3b6b77e340ce9L,0x2a4bda69df7c68b7L,0x9649d8b91b6574c2L } }, + /* 49 << 14 */ + { { 0x98f55e59112ef290L,0xa5516c3568909cdaL,0x40407393235165f1L, + 0x6eeeae510991970cL,0xae79ce1faaa6d26fL,0x8bc719b441d43f67L }, + { 0x4a7af92a39cc89a3L,0xf6d14f9a85c8ab12L,0xb9bfca97eb8d4851L, + 0x926b8155cd52b2f3L,0xdd17dbd48fa94f9fL,0xaf68726447cac5cbL } }, + /* 50 << 14 */ + { { 0x39d7c1729517c2c0L,0x6f795181166e2f50L,0x9f6ecb5dc0ad8b54L, + 0xb480afac8e75ce4bL,0xf51569203dd5ad07L,0x87c855e73799b80dL }, + { 0xea8c34d9538ebc9eL,0x67bebb6a957b303aL,0xc6511b7b4dfc6d7bL, + 0x9a40cf5885b02ee1L,0xf4fffbbdecc59a6fL,0xe85a7c115cebfbcaL } }, + /* 51 << 14 */ + { { 0xffa0118c4a33265cL,0x4c4051d583e0bb83L,0xcde22f8d7007d078L, + 0xae9ebbc2932cba29L,0x297c2252f7a82223L,0x662814f41a09fbdaL }, + { 0x3bfd965640be805aL,0xe49901e592acce09L,0x4e201930bbb6bb43L, + 0xfe94eb4dcc018aa2L,0x454d8c611dcf97a5L,0x11d8e3a230f1011dL } }, + /* 52 << 14 */ + { { 0xe745ee2c36cc8b1bL,0xb40c94e6e328c813L,0x4144aecd8bd107b9L, + 0xc35567890ea88fd2L,0x017460e30492a810L,0x0c63cd4410b8bea1L }, + { 0x9123e9a3c890f74cL,0x940fe6590cea499cL,0xbe306232c82e1bdeL, + 0x40544f6bc041d7ecL,0x46de1f3b477a7dafL,0x336551f6951f1295L } }, + /* 53 << 14 */ + { { 0x2a61217a09b3b9a1L,0x0736704635b71125L,0xfddbf1933df24d57L, + 0x33ddabcb4592d748L,0x2fa9ff8a25309e3aL,0xdca2dd2892a0e76aL }, + { 0x706350255dfbd02cL,0xe01c2553b6306b8dL,0xb14132905e91ddecL, + 0xf45221866f6de6fbL,0x2d48d001b440319aL,0x926e9b64fe67f843L } }, + /* 54 << 14 */ + { { 0x5580401264e2c160L,0xe154925a9a6c256bL,0xce2df32922260b79L, + 0x74824410c546d756L,0x2a1d0a5f79887083L,0xa2c040c5da3f7d48L }, + { 0x74058ecbc14f96b8L,0xe69c09d73415e476L,0xe5a93bb47a443fc0L, + 0xe1bb24800c31d7b0L,0x4701d669f4ab0610L,0x0ad815841eeb23e9L } }, + /* 55 << 14 */ + { { 0x823cd737d72b5925L,0xee09efb9fa38cb06L,0x6828dced4a21e81eL, + 0xab67b37bf365e481L,0x3995edd2b5a7c630L,0x4c24ac8806930b7cL }, + { 0xfd7264d36dedce0eL,0xdcab1e333e76fe1aL,0x6b40889a89a94f97L, + 0x7a1fd432b2a3b0e3L,0x121efaea3ffe933eL,0xa81f6c6f843c3553L } }, + /* 56 << 14 */ + { { 0x26301455e5488aceL,0xdf39099881a20dc7L,0xac7d6049ee06c7f3L, + 0x547e8df33f248fe7L,0x5fc4b74213743dceL,0xa97721bc4c398630L }, + { 0x6b7877cc258aea47L,0x1cedce562d5c28d6L,0x7e930e419428d66eL, + 0x42c80757b97faf54L,0x091fe5ab3812e632L,0x2c29fd42e2e359bbL } }, + /* 57 << 14 */ + { { 0x2d9e65a61d7b990aL,0x8a9ab4bee2a8a6a9L,0x8658c36985e3eea6L, + 0xf352787df0de0b23L,0x872db1de1161aa92L,0xf2648c972190acbfL }, + { 0x9a34f1d09de72e41L,0x13860f846c086516L,0x2e9211b824127c21L, + 0x4e1623bba3697c37L,0x41d71f1df579c733L,0x33f0ebf7ca9f68aeL } }, + /* 58 << 14 */ + { { 0x9b51f4ca9f5a40c2L,0x38b59573682e2132L,0x5765e89dc556998cL, + 0x102fe894698a4a8cL,0x0bbcae977c6964d6L,0x8548f2c6dd7bb12cL }, + { 0x32c11ed9e49848d9L,0x1ee1b525135aefc2L,0xade5d14e812a5e4bL, + 0x0e122e7e15bb167bL,0x321594d4ec5c3594L,0xbcea8723a7c02afeL } }, + /* 59 << 14 */ + { { 0xdbf91edcaf87c75aL,0x9710003266582706L,0xb10cb32b1133a7b3L, + 0x70f5d71767e068daL,0x8d937e56b8e0c9a2L,0xd8a2652ee2a9afd7L }, + { 0x94d6cae9cc90c6ccL,0x3512f3abe94f68ffL,0x931ea6f09331ad40L, + 0x71621013daa3d4f1L,0x591c40bfb668a992L,0x5494cc174c6868e5L } }, + /* 60 << 14 */ + { { 0x7981826070ececc7L,0x8cc0b6e071cfc0e1L,0x998df6590276a6bcL, + 0xffb5bec11a43be05L,0xb93b1543f2beb640L,0x337703d456f3719bL }, + { 0xce74c17cd40a7375L,0x6aef79cab1aece94L,0xc5bdfb388876d218L, + 0xf71ce9cccea91445L,0x471cdbd1ed6e5f5dL,0xe0cc79cf10e56c08L } }, + /* 61 << 14 */ + { { 0x2b17e181794ebe48L,0x6111c897f28cdd32L,0x4d59199062dfeee5L, + 0x7b9d070241b14904L,0xa1ad534d5fea4804L,0xc08915d953b16c22L }, + { 0xa57c883e8ac9ddedL,0x589474dcda1d1bf0L,0x31cbf32ce9aa8e7dL, + 0x2abe9b60f0930d84L,0x604731b0cbdd031aL,0xbc35b1e4e9e1b3c1L } }, + /* 62 << 14 */ + { { 0x39300d55efeff954L,0xa9cf57f34fe9cffdL,0xe3315321b15aebbdL, + 0x26354c57b840b080L,0x2c690488476abf35L,0xa7303fe6d480cf33L }, + { 0xa50865295706c3b1L,0x4c26034eed0b2342L,0xf08d67be9ae9c452L, + 0xd4dbb9f5046c7d0dL,0x4435f1a3f9e5393bL,0xf47aae68cd4d5de8L } }, + /* 63 << 14 */ + { { 0xce9e5ddc06d5f48bL,0x22c1cd3e0ef642baL,0x2ad48eb9e9b8a960L, + 0x330074883ce26679L,0x495e62428d2de642L,0xcba5bf37e03b1a77L }, + { 0x9382c92de716624dL,0x410d212350a33e4fL,0xe55ee116e953e7edL, + 0x27e9a0584b840616L,0x560a5e4939473bd8L,0xbc1e795b382f3a95L } }, + /* 64 << 14 */ + { { 0x31bdb48372876ae8L,0xe3325d98961ed1bfL,0x18c042469b6fc64dL, + 0x0dcc15fa15786b8cL,0x81acdb068e63da4aL,0xd3a4b643dada70fbL }, + { 0x46361afedea424ebL,0xdc2d2cae89b92970L,0xf389b61b615694e6L, + 0x7036def1872951d2L,0x40fd3bdad93badc7L,0x45ab6321380a68d3L } }, + /* 0 << 21 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 21 */ + { { 0xc5cf8997ce0b5b72L,0x350adde19d7154baL,0x8139681e307b254aL, + 0xcc87fb5775cd94d7L,0x90e7027478684954L,0xc4fdf4c095ceb991L }, + { 0x91bbc0ab8762c84cL,0x5e09e226ce09e8adL,0x1cb83d704b93d45fL, + 0xe2299024f541da1fL,0x3eef7ce14b7ffd10L,0x53ee63bbb3fc1b9aL } }, + /* 2 << 21 */ + { { 0xe5004e8003682f59L,0xccdb9cb7f642ac0fL,0x405f50d1bd869f77L, + 0xecffa54de7ebea2cL,0x3354dc22d87620baL,0x01bb2988b1c01ff4L }, + { 0xd9370076e16477fdL,0x45303d2a2e71ba4bL,0xc0de76273291e5c5L, + 0x5cfebd87f0a7ca55L,0xde1162809e592a30L,0xdd26e577a78ebce4L } }, + /* 3 << 21 */ + { { 0x1e9b23b9ff1735a8L,0xc3bf3d5b2b0e4b7bL,0xd4cc00fe59b7721cL, + 0xd5c36f9c9e2f4cebL,0xdeca06bac90af70eL,0x42676f12416ee799L }, + { 0x0d7afe1b6f748c6fL,0x0b7a6de539c39d55L,0x11e43d6ee6eaed18L, + 0x5baf8602496087e0L,0xf833634fb1a3a66eL,0x25098c8a79398677L } }, + /* 4 << 21 */ + { { 0xe141e763d4720770L,0xb9739e70ddb3b450L,0x46e6cde496131446L, + 0x0458a5d5cb6c2ef7L,0xb7747634532f9fd8L,0xf62d372116544457L }, + { 0xbfacb4ded3100854L,0x70788a31b39d3f62L,0x9b543220f22d92e4L, + 0xaa4590f655723258L,0xc7b6730e01ddb8bcL,0xae252cf869e1e7bdL } }, + /* 5 << 21 */ + { { 0xc618cf0ddd4b8d8dL,0x471cda8640dcfbfbL,0xba0dd7ac08882ce6L, + 0x58e5d2f56cd336e7L,0xcdda8301af096540L,0xf6d268463cf31600L }, + { 0x6150cd982197efd5L,0x4440fbfa55fb0877L,0xca31871c90757f1dL, + 0xc4a1faacbdd756c8L,0xc9d4ac1bcbb8421eL,0x3c0c2914b17c43beL } }, + /* 6 << 21 */ + { { 0x46fdb65caa6fe9eaL,0xe0d48e5e05494cd9L,0x5adef5704afbf837L, + 0xc96ba4b91c9e2cadL,0x1e8158f7054a158cL,0x47be73209e38b88dL }, + { 0x9b99971e6d2993ecL,0xac9b0bfadf980eccL,0x9da09642d96ca391L, + 0xd67105369bf4305cL,0x40cc1adfa0dfafaeL,0xe27e32f8a209699bL } }, + /* 7 << 21 */ + { { 0xeaaddeb836e87d82L,0xc12587a71ffd7210L,0xf93d2f5c731f6838L, + 0xb96594e8f7097a65L,0x08d6717ab016e8d3L,0x9c378de81984d825L }, + { 0x627d41e7cb2a0c26L,0x1f447501c697ceb1L,0x8dc40831c760550bL, + 0x70ad48707fac97b0L,0x5ac7f22e7021c170L,0xa6f730e4929d5931L } }, + /* 8 << 21 */ + { { 0x7d27d71fd186cb09L,0x67cb7f4e3bc213c7L,0x418cafeb6075b2cfL, + 0xc0d691e6d93a06f7L,0xc16a95259dd001b9L,0xa0583230026f17b9L }, + { 0x4c1041b07845900bL,0x2874079147a22aaeL,0x8d08efd62c1758e9L, + 0x9cc6f207e6c3229aL,0xec69e902082d8924L,0x9cfa1deaf331dfe7L } }, + /* 9 << 21 */ + { { 0x7b5ab2afbce81cd9L,0xd25fa34b12028b49L,0xf9d65e6b63a659beL, + 0x6f88f1ddfffb943cL,0x38eb0d02b871cd5fL,0x732afedc558ad949L }, + { 0x4093ab05367d424eL,0xf73b23ad29de1be7L,0xce1c0093e7a50181L, + 0x6d05cbbe1e412cb9L,0xd3c1148b773a394cL,0xe04b5fdd38e50316L } }, + /* 10 << 21 */ + { { 0x1793535b8d0ce0f4L,0xe9b054b1ab73f7daL,0xd82a3ac1ee7bc6e2L, + 0xb28ad846b847f39eL,0x40975fa2fc10c012L,0x8de998619aafe68eL }, + { 0xa73f442584878534L,0xbe3118cb7a36a0d7L,0x3763a49e8fa37fc9L, + 0xf3f8ef82361f32b9L,0xea66f9978c1aebc4L,0x88600d648d9d024cL } }, + /* 11 << 21 */ + { { 0x11f842ca150a3325L,0xbae115c3185a385fL,0xddf9643637561bb0L, + 0xecea0cd9a4115fe4L,0x297720665893a694L,0x837e6880df408cfbL }, + { 0xfeb8f511e0a7fb68L,0xd21869dfa062b60fL,0xe2b60f46ca6a5e72L, + 0x64bbec184931d188L,0xfb09c90fe3ef3378L,0x67cbeffacd767337L } }, + /* 12 << 21 */ + { { 0xd35832381b289f6eL,0x10dac54a0aeb3bcaL,0x4df1c08d6692339aL, + 0x2968edec20054647L,0x34072618d74235a4L,0x00b4a7ae71d6064aL }, + { 0x23a8900e25c23f8fL,0xda0cb7fad7d0f1b5L,0x266211c56c8ecdbbL, + 0x0a4351b97bc27e4dL,0x98d54c97fc234258L,0x5ba534071e1a4dfaL } }, + /* 13 << 21 */ + { { 0xf07cfcdd77f083bdL,0x89bcae29d46712c6L,0x2089c3ab0f09bb8bL, + 0x3ede5a2a6b9a4028L,0x27ee18fe013066deL,0xc2bebbb416fcdda3L }, + { 0x6b3926af3a87cd68L,0xf52f0ef9f9a7b831L,0x4a39660a1ffc01b2L, + 0xe98f718d91aa6719L,0x8b0626f111d48e8dL,0x4a6a2e5b2bd93db3L } }, + /* 14 << 21 */ + { { 0xc3ddb6123ef24470L,0x98b66569bb3f99edL,0xccc537153a97a015L, + 0x0d9a6b4d04937b8cL,0x854d081ad9a575f7L,0x347bf0c0127fbd90L }, + { 0x6baa47a5c30987f1L,0x164b390dbfd0b503L,0x6672d1afe6a1f565L, + 0x9a50ee5828d5bb14L,0x2e23ab480d0226fcL,0x33eb052365cdbdbaL } }, + /* 15 << 21 */ + { { 0xa32d1a27d904eb73L,0x6fcad8d0c43c978dL,0x8cf1e7a19c0842f5L, + 0x2a6fa6d800328ae2L,0xa5905f67a1e3b06dL,0x458c8badaa8df96aL }, + { 0xee5b20c0b0d4b89bL,0x352ae0c4815c1af8L,0x546a7d7e6dd73b70L, + 0xa99882225f753229L,0xa38eb5d7efde47e2L,0x8290aaed92635ab1L } }, + /* 16 << 21 */ + { { 0x8ec4335fabe7c60eL,0x01f198c10a6a9fb5L,0x3ff96de001141ab6L, + 0xb21acc2c2eca98a1L,0x6154849010fdf648L,0x2c01a99cd1403e8bL }, + { 0xf1a35f306fa509d7L,0xf7715fe3e3f08e9fL,0x89c26c077fc9a752L, + 0x8d2535fe420d48a0L,0x80ec5ddd52fe2e73L,0x041b8df071704f39L } }, + /* 17 << 21 */ + { { 0x96882074659a0a12L,0xdb0d63032a6bb752L,0x2a1fb2d740c2194dL, + 0xeb6b45ba2c184444L,0x10ee44368c179d33L,0x906d0e509391917fL }, + { 0x11bead88ca3bcba2L,0x25914dae4253fb99L,0x0445b31013c25404L, + 0x2a2eac6d515f53baL,0xa746a1d662bf0a11L,0xc7576a4c6573c4f1L } }, + /* 18 << 21 */ + { { 0xec159ed060c5bee9L,0x80282ff007746414L,0x8d53f05f40a97a54L, + 0xc92d8789f5d4eedeL,0x1edd798132344c09L,0x3bb9a444a92c7b36L }, + { 0xbf130f5cdd6c8903L,0xd270e7cf676fcab9L,0xac49744bdc5ae6f9L, + 0xbd0ccfcb40e39281L,0x222efa16a981b3f7L,0x92bcd2d700aeeadfL } }, + /* 19 << 21 */ + { { 0xecfdb91489c73e10L,0x83a5168becffe79cL,0x6a0d57c123e97ffbL, + 0x774121ca4b130cc3L,0x8556fdc5486967a6L,0x1249448d5fe4a7f5L }, + { 0x8c2c14440e93c114L,0xcde258573bc68985L,0x697ba7b0952758a2L, + 0x0d962b377aee19e3L,0xdb31fe8582c4c640L,0x6ecfaf36c89b4b85L } }, + /* 20 << 21 */ + { { 0xf1e8c5a0e06b40eeL,0xa55909fe59836af3L,0x77a13be8a3a4ed95L, + 0x47408650bbbcde0aL,0x95b455c2b4fba7b7L,0x4983f5ca4321117aL }, + { 0x37bab5d1e18d304fL,0x0edf3733f1d29206L,0xe23e4db4dab91670L, + 0x602a5265923ab7c4L,0x53ee98c6eb920a03L,0x1b592b626f25489cL } }, + /* 21 << 21 */ + { { 0x66c981d9d3543689L,0x20500cd7bb8f53bdL,0x807d43605179af77L, + 0x7280a7b27c286404L,0x75a74e630976a65fL,0x2ba9ad9df11c3bdfL }, + { 0x23f38f950ec6c760L,0xcad599102b858cc1L,0x4d9adb7efec23c19L, + 0xbabb6e45095e85c5L,0xfab66a97e5dac2e4L,0xcde4b15a08baf1f4L } }, + /* 22 << 21 */ + { { 0x148aad3207089d6aL,0x3ab5b0790303c267L,0x7d13995bc3153026L, + 0xeba27c192287f305L,0x5faa453367ae45bdL,0xbbb561db2f4e9488L }, + { 0x254d8977c8493163L,0x60d468fc5c544164L,0x0b6309a3a2758037L, + 0x8480e16b1f9add24L,0xf1d99fd2902ec661L,0xd32df254cb6dd6f4L } }, + /* 23 << 21 */ + { { 0x9a17f5c3610178b9L,0x75dded80bada5aadL,0x158249c23dbeb289L, + 0x1d0671cac300cf49L,0xa1649bd0886902f2L,0x79b0d6ed7d13be62L }, + { 0x78253e7549e2327aL,0x5629cc509af110ecL,0x4373a20059f8765cL, + 0x739f33289d9c5f3aL,0x3c7d5cfe9a5f997eL,0xf044d90d0559357eL } }, + /* 24 << 21 */ + { { 0x20aa15d97ab838e6L,0x6cefdd5a0c827ed1L,0xe2f205caef579e8fL, + 0xad27e38b325981bfL,0x087b8284c3438be8L,0x2095dfcf422360d9L }, + { 0x87cdf5ad76d096bfL,0xf1b97ce1e022adc3L,0xa71240c189104665L, + 0xeb5a175c9c1578e8L,0xbd66910ad150ffa2L,0xac277af811459a28L } }, + /* 25 << 21 */ + { { 0x7db4df62417fb54dL,0xf6c1e7f04dfb7c05L,0xfdcbd3777aa8ceb5L, + 0x0364b3bd89c24333L,0x8a721718fdd3dcafL,0x9a6015dcec2848f1L }, + { 0xd6571930d35ad1a9L,0x154a929199369196L,0xf3be7e228e514732L, + 0xfa3eef28b7fd3aacL,0x0bc3b2a69f60d298L,0xf6327920febfca58L } }, + /* 26 << 21 */ + { { 0x3b9de1baf8dc6030L,0xacc4224a2107fd1eL,0xa7d32fe86dcef0d2L, + 0x353d5e88dd83fb28L,0xd552c3ce50bfb0b2L,0x69bc0e686cc8ee7dL }, + { 0x965c0ca21d9c74d9L,0x5cd163a406ac3ecdL,0x57910a828e98b581L, + 0x1d0fa7523d992afbL,0x862d3184e7d12701L,0xab6a288c6c7d161aL } }, + /* 27 << 21 */ + { { 0x04caa9caf4f2b3e9L,0xcdb896141af43dd4L,0xb09444fd4e74ee8bL, + 0x9428849fec05d35cL,0xe29bb0e94765c0e5L,0x138c45f176d25d2eL }, + { 0xbf041131a0184d83L,0xaf321573991ddc4cL,0x058760a8ef31df7dL, + 0xe0b94b57f80dcf5fL,0x75572221850a4a6eL,0xc735580c104a4a1fL } }, + /* 28 << 21 */ + { { 0x9ba102f1a6b735daL,0xe073232edfbe7d06L,0xa8ac24ba57266a16L, + 0x07458ea42d5c4bb0L,0xfbdd0f0574868e1bL,0x73fa612a3921fe7aL }, + { 0x26f6714b0b32d8e2L,0x7a3cb2b48bceb95eL,0x756a68c6290f204aL, + 0x148fbb787fdf2b7eL,0x639ece6c57fe0da0L,0x315aee1e9a92b7e7L } }, + /* 29 << 21 */ + { { 0x22dc170769d10661L,0x8d89cd1c71fd40f7L,0xa22f11bfa2545040L, + 0x1247d019d44c2446L,0x8d17daaba08235c7L,0x7e6863b9fae7874dL }, + { 0x6d57431c0490d338L,0xc1459e61809d1f9aL,0x4eb14dce95b64852L, + 0x8d3a04e6a7b5a861L,0xfed631ee7bfa24a7L,0xf8f86f27af11723bL } }, + /* 30 << 21 */ + { { 0xb43b14146e63c833L,0x497a5f98c1ec160aL,0x112223de83eb3709L, + 0x293964a88d100b9bL,0x6db1d1931e3b2db3L,0x264bc83d71eced39L }, + { 0x8418eb43aa89c967L,0x51d41bff76f8620aL,0xa4017ee5cc416467L, + 0x1cc527231e216e36L,0x76ba536ce8069a6fL,0xa239b54acb77b981L } }, + /* 31 << 21 */ + { { 0xa05f2dbc37544476L,0xf18dbcd71b797f65L,0xc78131376d50cd5eL, + 0x2b509a4d6dee11daL,0xfc0f0584beba1b6aL,0x3282624a9d53bd6bL }, + { 0xa0944e5c16b7187bL,0x468a79b8aa2f99e9L,0x32e4644b38bc4ed9L, + 0x5bc375d7e7cf71feL,0xe18e3c0956617861L,0xbce9ccbce69255bfL } }, + /* 32 << 21 */ + { { 0x498808edc65fafceL,0x3676a7cc4e806bc3L,0x796e25f176c6b964L, + 0x1aced64bac474261L,0xa62470fc29a460c1L,0x77501dce5e751e48L }, + { 0xcc00053b6d9e3641L,0x2b5bc4ae9a3f5a0bL,0xddaccc2e3f9ca178L, + 0xad33f34a0b80d1b0L,0x6a76df9364642225L,0xc145f36f778e761bL } }, + /* 33 << 21 */ + { { 0x377fc5ac575e74f6L,0xfefeb2327736739fL,0x62ba076a9fc2d5c5L, + 0x6f3c6084baf0269aL,0xce2917688fa7c145L,0xa60bb8905b3f2333L }, + { 0xa811055dd900095aL,0x92d95e7b385bd4f2L,0xba54f444d33c2a43L, + 0xc1b131327d12754fL,0xdcdb54821556f5e3L,0x55377fc539ca4b94L } }, + /* 34 << 21 */ + { { 0x455f65d1a0cbee78L,0x554eccb566225edbL,0x306400b47a4e014fL, + 0xef3e02eb7b67025aL,0x7d4efbaa997a633aL,0xd43c6eb8672c90b2L }, + { 0x0ed2d88d7519da07L,0x864377854b9d51e8L,0xd5900a2e2e3ab57cL, + 0xc02f046b69bb0a39L,0x06d825a6bff12faaL,0xa12e5b0d5d3ac267L } }, + /* 35 << 21 */ + { { 0x1716be5ba10508b4L,0x8706acbe7e37fbebL,0x3881f54e44e3d127L, + 0x54e20622a864d77dL,0x26a194616b83325eL,0x0d57be814c15a8f4L }, + { 0xb10c0cd07b53b476L,0x3d016ea097d39c64L,0x4d7df7c15315bdadL, + 0x6fe5a1acf060cf4dL,0xd5e3d05396846b79L,0xebc878f79e3c8028L } }, + /* 36 << 21 */ + { { 0x5b849ed8d0d193acL,0xe983abf773950501L,0x5ca162770854a569L, + 0xb0b284d26904bdceL,0x9c769d269d4fadecL,0x98e5e9b912677284L }, + { 0xd9246836b557f2cfL,0xbd47433069d46374L,0xbce8b27b9b063a22L, + 0x08da2eca37c5ba26L,0x9e742de8d4b26479L,0x643b752c102aa36cL } }, + /* 37 << 21 */ + { { 0xb72fae566fad22d5L,0x1e921426cf2fd62bL,0x9f31293d4c225102L, + 0x78d43a621975afbbL,0xce2787303cfee30eL,0xb88590d77a82613eL }, + { 0x42f86567560b932aL,0xc2d98915a7c9ed68L,0xe70e41fb349a9750L, + 0x7e7fdd2c79f9582bL,0xf3d6ab07da737c0bL,0xba247c0b9f3cf823L } }, + /* 38 << 21 */ + { { 0x4bebaf153dffdbd3L,0xc37d4a04fcc967a6L,0xeabab9aca0435a65L, + 0xf23d1d58f9ae9c52L,0xce229a798cc8f7b6L,0x4a61e6ebf5e11e61L }, + { 0x770e1dc6b20f2d8bL,0x199d20e8cfb9e820L,0x9fd709c4c381a22bL, + 0x6f53a358b1d52a98L,0x4b1a018c66f511faL,0xc7d2d49375d3a666L } }, + /* 39 << 21 */ + { { 0x3b2db5e5550791d3L,0x034ed5665bbb686eL,0xf019f161e033e3eeL, + 0x33198653acd2f0b5L,0x368d89e41ee8273cL,0xa7ac3b507f26daffL }, + { 0x73d8d7df006c0037L,0x98b5937de73cf271L,0xc3bc340be917247dL, + 0x799ea890e45f37afL,0x27be0f5a25e8dd2fL,0xd70ec41c3bb16923L } }, + /* 40 << 21 */ + { { 0xd30302352679072fL,0x73dfdc0f95dad4c8L,0x53649b575c4630f1L, + 0x60197fc08d098d74L,0x9c295d54647f5cbcL,0xfa5f1bc6c0813efcL }, + { 0xf6e08007d2e49417L,0x4f7d4b3dab579569L,0x7af3e08e11d9b388L, + 0x073ec38a5db61c65L,0x9b480cb89db4dc4dL,0x9be2ce7e372fa82aL } }, + /* 41 << 21 */ + { { 0xd87c0b55ed1b6d83L,0x3b47443adfae29cdL,0x16c5b0e52147bfdeL, + 0x98812fd0663cbdbcL,0xe3cea04955ffe911L,0xfc1e9d9cc5df31caL }, + { 0x7ffa90f9902c4ab1L,0x2cf973c3669a857fL,0x89243cfc94b109adL, + 0x222d6fdb536ee544L,0xa48b1b15fd488c22L,0x7120e3f0f318ba27L } }, + /* 42 << 21 */ + { { 0xfbb8a3cd47813054L,0xa2d7255d462ac3f3L,0x341bc10babdfa7adL, + 0x01efa884ceb9ea50L,0x30fa0f903f5bd09cL,0x8aa309453abd108aL }, + { 0x0ab7fe23f9ecab6fL,0x0585f72a5ec032bcL,0x686a7d71cf9f4fcdL, + 0x096bbf04f769be8dL,0xa309931250b64584L,0x67be53402e216060L } }, + /* 43 << 21 */ + { { 0x4e14fa6eef252e90L,0x2ca968579b7db6f2L,0xf80772e3653f1662L, + 0x4f89e666cd28bb05L,0x7fa800cc77eef62eL,0xa3f6ef5963b2f3e2L }, + { 0x438d564bc81e600aL,0x8978912de14c1434L,0x33732892ea695891L, + 0xaf6aef0b1dc8caceL,0xcbf9580b7c509cb1L,0x2db9fbc11ed6fbdfL } }, + /* 44 << 21 */ + { { 0x408805a1fa7052bdL,0xe4eb27f75f825c13L,0x0a0cc8fa37ee34a7L, + 0x737b99a40c59156fL,0x78c2a5d8e1b55c30L,0x89d70b62bcbb2196L }, + { 0x07ad36911e862a0fL,0xaa1c9118c41cc693L,0x7e6f544c4e1f7359L, + 0xa5f4f5891bf9474fL,0xa711efd9ef56df82L,0x0428edb7e3de91fcL } }, + /* 45 << 21 */ + { { 0x67f403610905be0fL,0xffe68b80c12178bcL,0x41bef79ec6a673aeL, + 0x347e8ba81bc77376L,0xd49956d60e589da2L,0xadd54508fed84dabL }, + { 0x18868a4a462749f4L,0x2048cd88ed323e71L,0x7b27932aa28d1f02L, + 0x3cf6107412e4ddccL,0x0f6198631360ecc5L,0x40e5e08b1330d33bL } }, + /* 46 << 21 */ + { { 0x79b68071e3ad573bL,0xcb070412723966f5L,0xf4610fd1964b453fL, + 0xfdc9dbbc8bcee838L,0x3e191f3bb5ca4f20L,0x90d85084c02e0af0L }, + { 0x4e3f57a70ee64025L,0x63f339acdea07a5cL,0xf255b5045eb4081aL, + 0xe42bd241b4cbb0bbL,0xafa58985ff68c5c3L,0xd36cf7175b55e6e5L } }, + /* 47 << 21 */ + { { 0xf2b06f4b95d37e50L,0x7da1d2af3747c79eL,0x18a37dad6ad0092cL, + 0x9f4a6f081a8f207bL,0xeb1fd3f2cf0fed15L,0xfb9911e4384eb46bL }, + { 0x5f07c680b87cb035L,0xc49935d189e1531aL,0x718f6bd09ea02056L, + 0xadafb67b18a4ca31L,0x26cb0f368477f396L,0xec7775df62ec2172L } }, + /* 48 << 21 */ + { { 0xdffb03aec10b43aeL,0x39b1266e9433a54bL,0x4c262521b19fe0dbL, + 0x0ec1e54f3d5c7feeL,0x2856510b05e68e1eL,0x49382c1edc80b8a6L }, + { 0x80a509312471bdd5L,0xe8cde18581974aa9L,0xca6112ee28235c52L, + 0xd28a0eb8301f9653L,0x22b11e26e11fcdf8L,0x97e6fc5de4d735f3L } }, + /* 49 << 21 */ + { { 0x7fc264d35b253506L,0x1a11dd9cdfe2be8fL,0x2cbcf79c711185a3L, + 0x2208200a46806ddcL,0xf2764b6524e75d8aL,0x71a71bcdfcb43c25L }, + { 0xddd0cd3586a895caL,0x5ec28b469e2caf5dL,0xeb749df9f6614957L, + 0xdae1dd77eddd371fL,0x7ce493b556dde554L,0xc1627c06d6e5653cL } }, + /* 50 << 21 */ + { { 0x7926553cdea7472aL,0xe1e9480d3ba7f351L,0x242a641b1b6a2fe5L, + 0xf4af10091f790122L,0x5a2e2f95967810a0L,0xf1eaec6e2ed57598L }, + { 0x34a32da96b9f2421L,0xdc32daa8dd820372L,0x8b2539fc37a067ecL, + 0x2a495112820969ffL,0xea7c1829a699c283L,0xb4a1083dc2c58cbbL } }, + /* 51 << 21 */ + { { 0x1bcc30812e59d7a4L,0x557be0b2fac34690L,0x5b2868db673254faL, + 0x62e150a49e1302c3L,0xe29e9b445772138eL,0xc76bf4fd7ccb31daL }, + { 0x8d687bbb34c905c9L,0xf4f207030786eeb2L,0xe56a494c38deb469L, + 0x759e75e2cc6bbfa8L,0xb11903aaa59eb766L,0x3f6928c5c68b3bf8L } }, + /* 52 << 21 */ + { { 0x27fa09ebcdded185L,0x763b655c36d090e3L,0xbc586674dd864c93L, + 0xa1f84ff34c7074b8L,0xdf5261d17cf08435L,0xc57860f6fbdaff3fL }, + { 0xfa49af22252d7f08L,0x2367bf8c8db5f89fL,0xad6443ce6dade92dL, + 0xdc5265138d1af3f1L,0x62a282ecc720ce46L,0x1769b74c9808b416L } }, + /* 53 << 21 */ + { { 0x4ee11333ec598f02L,0x4613ba038c7eaad5L,0x48e0bfe61b1ccd1dL, + 0x6e115b6b507b705aL,0xc4d38e4992874d89L,0x30460a066dc59fc4L }, + { 0x75de8dcba0f7ea87L,0xba96718125101367L,0x9d7b03314a742660L, + 0xb4ca381d8c304133L,0xb87b896d65846055L,0x8dd96f0513d381dfL } }, + /* 54 << 21 */ + { { 0x43716f0c3e25b7b3L,0x00caad210aeb5d75L,0xbfee232559a6cb66L, + 0x06c1d812ad059aaaL,0x42d0af57c8bcc046L,0x37968ef70e409a85L }, + { 0xc5c3812ee3be328eL,0xaaa74bf166547ad7L,0xb292af92a15a0db1L, + 0xc0645385e5d5cdbcL,0x2dcf4ca937ec2c28L,0x3f75d089f0cb1694L } }, + /* 55 << 21 */ + { { 0x7e71fba26c0204d3L,0x6191ad249a40b4aeL,0xe2c7ab6bdda24cecL, + 0x5a8fc77e95b26a2dL,0xa6d8b2e43f1c7e44L,0x42d485e4e0a0e08bL }, + { 0x8697386ed7e3b896L,0x5b960d76ee7e58caL,0xda950e9a3fce610cL, + 0xb85c7842803c67dbL,0xed8a53535e62ff2aL,0xfe6b0e2c4d674e7fL } }, + /* 56 << 21 */ + { { 0x46a2a08be26d822eL,0x63537bc689d6d6deL,0x28c556a2b3df9fbcL, + 0x81d3161eb121d512L,0x4e27ce0b123bc86cL,0x1ebadb85bfb240d1L }, + { 0x86edb71a1156314dL,0xf8ac56fd113961bdL,0x2f6bc6d8067f586fL, + 0xf558b8833fe8e532L,0xe9433e2321a7997fL,0xb86f039c87e53b9bL } }, + /* 57 << 21 */ + { { 0xc022a16d78329681L,0xc3da7bf76b1226d5L,0x47ef18daa85c69e3L, + 0x4614f0ee45cecdbaL,0x9126fc2640f19d1eL,0xcdecb2693f5ca09aL }, + { 0xb62a831257a020e3L,0x5f9a8ddc8330d472L,0x37e58ab3eb208a24L, + 0xe64ed285ee4b8687L,0x752fa22a74a82625L,0xa67e24609b25fbafL } }, + /* 58 << 21 */ + { { 0x89e3d770e6b94044L,0x50f50d1675a1a8c9L,0xe73c51d95344c139L, + 0x97a8dd8411723e9bL,0xba0663c57de5dcf2L,0xf26eee6c3a6b588fL }, + { 0x6275b2a9211b989eL,0x32ab4b311608f16eL,0x9e47b2943fdde5b5L, + 0x63c50a50614bae9eL,0xffe4ef05e31c05e7L,0x2fea9142b7db4ba7L } }, + /* 59 << 21 */ + { { 0x27f286db0874c6f6L,0x26de6376e6ec0054L,0x56458a082ca84fc7L, + 0x07bcd4011fccf1b2L,0xb8548e74bae6f486L,0x0ea5857a0de2964fL }, + { 0x8e8df866e50fd2a4L,0x3b07d1a8710fc74aL,0x3e4cc4f5a1fe92b9L, + 0x7380d0836e52d244L,0x4d75e1c12796278bL,0x9eb279258d33f4d5L } }, + /* 60 << 21 */ + { { 0xce7abd1ba225f084L,0x696e1eaff803ee75L,0x66f2789989415775L, + 0x14df21a29eb4991eL,0x012a6413fe2a0769L,0x022cf1c8626f421cL }, + { 0xd4644d0460ab4299L,0xa43cc1732a8d453fL,0x7c4ab8c20ed14031L, + 0xd5854b98e14605f7L,0xd9a98c51fa7ff2cdL,0x7dbe8cbc46baf2c0L } }, + /* 61 << 21 */ + { { 0xf26574593c42ae9eL,0x7c3e5c13bbc289fcL,0xb815fe3fe096e7bfL, + 0x3eb67095da54264eL,0xbf5ca7c4ff3f8128L,0x8fc4a3f865db4dd4L }, + { 0x3af47b17ee382cfdL,0x8854132fd95520f4L,0x3387b11d33c5588eL, + 0x5d7eb66c0c662f93L,0xcad581933b18885eL,0x8d1c069a6f23c209L } }, + /* 62 << 21 */ + { { 0xa9498fb5212ee678L,0xa8824b696ade4a39L,0x422c074e0a406cc2L, + 0x7d38de650a2beef0L,0x482d16f81eed5bbfL,0x1c882006f18380a1L }, + { 0xf90f6c2bb98445e2L,0x36aa980b2c738d70L,0x4caff65b6785ad58L, + 0x1c282becf95863f8L,0x59ad267c5350b79fL,0x53ea042721cedec9L } }, + /* 63 << 21 */ + { { 0x5cc362909fa3481cL,0x1321acdd7292ac86L,0xcc30550378f4d6abL, + 0xf7917237e7d9154eL,0x591e5ba81fb39377L,0x0a387e4f7c541c76L }, + { 0x99685212a38570cfL,0x5cce35c8624cd61bL,0x375c68133aed79d0L, + 0xf72d4b068197e487L,0xcd672f7d129775c5L,0x944ef37f1cd768f6L } }, + /* 64 << 21 */ + { { 0x9c66a32becc5f6daL,0xe4ff40431719ba2cL,0x8c6cfab721e716efL, + 0x32c8fccb96ed74e6L,0x475890dd0b110c83L,0xdfada95f5cb4eefeL }, + { 0x9d7b89a693240fe1L,0x6afdb2d0210b776fL,0xc3f0b55bca7a7d52L, + 0xa6e56a0655d04585L,0x818e221c4257acc5L,0x05207b63fcb8d39eL } }, + /* 0 << 28 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 28 */ + { { 0x0a74da82d8ada6ccL,0xc6b98a3cbea55457L,0x896c26bb57c2f5acL, + 0x981e2f72845d45e4L,0xca152b877e9a7d36L,0x49666d457b582e8fL }, + { 0xea3b9bda49fc20b9L,0x5bcbc84a7c71f153L,0xd346fc5d5748a654L, + 0x7ac2f217622665eeL,0xbb5efe7fb6f16e27L,0xb1810a70644c9dc8L } }, + /* 2 << 28 */ + { { 0x98d089819bc5917bL,0x9f90885d187fac5dL,0x651b18287cfc13dbL, + 0x2d606e4c8655a658L,0xba64d3c563c91b71L,0x36c7d7d8b82a5090L }, + { 0x2d1dff02cab1d598L,0xa95788d7be78f90dL,0x1ac2ee6b0ea1fe01L, + 0xc100b60cd5c1273cL,0x4496084ceae603e7L,0x7fcaaf5f77c2fdfbL } }, + /* 3 << 28 */ + { { 0xa93fec0861b06e05L,0x0bebc26b7dfe6802L,0xc00b45a5cce5662fL, + 0x2e8a0a7f83a9a4a9L,0x6e0cdebbc0bbeb63L,0xc56a20fe63ccd80fL }, + { 0xfc10fa08b51f1f89L,0x4848392020ad9243L,0xfda69cc66bf53af8L, + 0x474b7440f10bb6c9L,0xcda9db3b1e7625e1L,0xe2f62c1e1dc7f3cbL } }, + /* 4 << 28 */ + { { 0xe8e3225a6abdd842L,0x8c85f18f3b367b02L,0xf147a4219f42edb9L, + 0x6d4bc00d0d411d4dL,0xa1a13a2770014bb4L,0xb896d97bfa10166fL }, + { 0xb2a1dfa70c302c6dL,0x0a24bd5d808a63a4L,0x8409a3a2f88c7359L, + 0x071f3838347726a0L,0xd18a551c27507bb9L,0xe0c4cc34b359b167L } }, + /* 5 << 28 */ + { { 0xeaaaf4602a44610fL,0x94d330b10392ac47L,0x989b9b673fe123f1L, + 0xe2ca56ddd8fd0129L,0x77d6d0cd624982a4L,0x55d4b2c371e1fec7L }, + { 0x3e9a04a0360e013cL,0x1d227ea9c9cde585L,0xac2b08e24fed8f86L, + 0xa1d1357ce199e8dbL,0x7cf06ec8e99cc964L,0xd9bc3a7fd85ec63bL } }, + /* 6 << 28 */ + { { 0x7d111c67017c633cL,0xadd9e9bd7d128a9cL,0x4cd8730c6db857e9L, + 0x3c9c03e9f4b46d12L,0xd42f0242a78472dcL,0x3fc0bcb2260841bbL }, + { 0x6332b11a8783f828L,0x65229d2af7be37ddL,0x402f28eee7e8944aL, + 0x3d1bab505ab28372L,0x6944e82cad5e1ff3L,0x65a94c0de8c75729L } }, + /* 7 << 28 */ + { { 0xa151dcbc2f7f3633L,0x4305312a98969226L,0x947afc00604d46e1L, + 0xc3c9d57572f3e28cL,0xce4c1cbd14b1cd1dL,0x8fe9a81df80dea45L }, + { 0x50920f3a9685f603L,0x51d380f00b80d89eL,0x19978ba13f798e32L, + 0x1294aaa6c5edde47L,0x280002c2be714a1eL,0xd998669ef212603cL } }, + /* 8 << 28 */ + { { 0xa44f6ef880e9d9f3L,0xaa7621e91d14d618L,0xcb0e4ed80eaf6671L, + 0x2bf485f8181514a2L,0x74670e180a2927eaL,0xe1b5461612c14645L }, + { 0x4068c0742a67ed61L,0xd10c7a57739063caL,0x391b651d698b2816L, + 0xf310d1696da14fa8L,0xa089be6bd8a578b1L,0xa314b3a844389ad7L } }, + /* 9 << 28 */ + { { 0x688ce85068fd73ecL,0x2cfb41040db1f500L,0x5d943b8d5b9bbc41L, + 0x861867f5403f3973L,0xc331110a2c766363L,0xb28a6bc153aaceeeL }, + { 0x2ab6e7aaadbee7a4L,0x316ca45c2f2b9569L,0xcac646e561d2428aL, + 0x6fd28dadc7cb6291L,0x2e28f68741e20ff4L,0x8cfe90eebd189d34L } }, + /* 10 << 28 */ + { { 0x09b8ed53339da6adL,0xe40727af26f54b8eL,0xc4a105979990fdb2L, + 0xb808656b5108236aL,0xb4411363aa4bd584L,0x19e90149288a0328L }, + { 0x5795d8a8fb0592f8L,0x313c68833213c929L,0x62eecb5b48f79d47L, + 0x3afcfdbab29ca224L,0x0072847d40075b08L,0x078eef3dd1fe0c8fL } }, + /* 11 << 28 */ + { { 0x719b51f20ca20aaeL,0x01ad630824b47b92L,0xd32460c2d3c807deL, + 0x8497786b0a1785f5L,0x8bd521355d714ee5L,0xc267724ed00f741eL }, + { 0xe5578dca9c266820L,0x97ff60085b62d484L,0x84c70e92e3bd1869L, + 0x412759e34dfa679fL,0x6bccc33fce497e18L,0xfb92405669056198L } }, + /* 12 << 28 */ + { { 0x664ff05368ed0760L,0xc3cdc99138fae9feL,0x3fe057aaf1f30a86L, + 0xbae990222d08c72aL,0x4f5faf3f6f09e13fL,0x44461a4413d26b29L }, + { 0xc2504c1bf95418edL,0x12766ea7db3ff26cL,0x2f956e9507a22399L, + 0x2716e70f5a00cdd3L,0x80c020140e9fba99L,0xbe587ac30519875dL } }, + /* 13 << 28 */ + { { 0x5e4bb6b83b23d2a1L,0x819a7c7705c9888cL,0x59e4c48ad0fec7f7L, + 0x4b212b21d6bb71abL,0x370cb90bcbf213f2L,0xf1ea07e0817549b0L }, + { 0x20e3115351a37b92L,0x30f9e70158d444c0L,0x7ac3a37b0b791ab7L, + 0xe456fd475265e4cfL,0x3e3f27ca29580ae8L,0x5d68a40daa2a1654L } }, + /* 14 << 28 */ + { { 0x14203d8720cbb917L,0x284e0c9db2a7424eL,0x99eb2911cefe7139L, + 0xa709c50f42925411L,0xa5a7543e5c79a13aL,0xe262025c6f45f023L }, + { 0x3966fd18828b9f40L,0xc660846913693115L,0xd7dfbcf644373027L, + 0x8e73fe6bbade7645L,0x88267c7b1de0dbd8L,0x1231ac99ce4e8c9eL } }, + /* 15 << 28 */ + { { 0xfd928bd90ba99806L,0x799ac97d1a864172L,0x5436a8cd129682b9L, + 0x4bcacda54e96fecbL,0x453af995c5db1451L,0x8fd382e07073b98fL }, + { 0x17165b8a644a7bbdL,0xd17d2d80b6118620L,0x2a4bf1b2c8cd1bcfL, + 0xdc7aad959ccc119aL,0x6d34084c3bcdbeadL,0xcbc5c5557e0663c8L } }, + /* 16 << 28 */ + { { 0xba86aec170128295L,0x83a09b65c12f35ceL,0x8978ff0789df2f80L, + 0x85750cfd97a773d5L,0x806bb730fc3f35f6L,0x04503422fed868c9L }, + { 0xdc0fcde086ffdbaeL,0x8f4297e11860f43bL,0xfefb7d028d3ad6cdL, + 0x5c652b5997293550L,0x32e12942ed5cfbbaL,0x06192aaf98800d22L } }, + /* 17 << 28 */ + { { 0x9bb8cf660002f389L,0x217219af51505913L,0xfea1388999ef8797L, + 0xad1b2383235597c4L,0x85ffabb70a3e3536L,0xd8235d9da00c725aL }, + { 0xfa9b0f4ba704dac0L,0x99d76ddc2f57fb9aL,0x5ed3683b18428507L, + 0x9e42bc54435307f2L,0x3167de67b4f36896L,0x8a0f99a0d539d713L } }, + /* 18 << 28 */ + { { 0xf0b92b8a4642d9b2L,0xce97828a3f50c883L,0xa33d62936f0b1194L, + 0x23417e0f3692f5b5L,0xc79b9491fb0b95bdL,0x5410e8c95e836b2aL }, + { 0x2b84078d29798fc7L,0xa8732e78d6628695L,0x39da93f898c766aaL, + 0x0797832d305e464bL,0x246069ab163f9f4bL,0xb867dcef53fb6170L } }, + /* 19 << 28 */ + { { 0x949c63730ced5c37L,0x6f8cd6e4fdb6464eL,0xbea902ae2e056dd4L, + 0x43871371fa0d560cL,0x162128e9e9ec2208L,0x84deda5c25060c6aL }, + { 0xa8a8a27c14160ed1L,0xf24bf3dda33b53cdL,0xd12038a976a6d272L, + 0xe64d6384ee8f2b15L,0xc404d580d3e91d69L,0x62cdb886a4888d17L } }, + /* 20 << 28 */ + { { 0xccf0fb423c9eb0caL,0x8703c6694aa03b40L,0x44c735a74001af07L, + 0x9616dd932e874ed1L,0x5c2e8520474ba621L,0xddf13cd3fa93d8b4L }, + { 0xd68c9b4575df1b67L,0x4cd242288f80d389L,0x0f1a16bcc09f47fcL, + 0xc414dc6a9cd4842aL,0xbb0fa94f1f353c6dL,0x405124551950d073L } }, + /* 21 << 28 */ + { { 0xbfe176f2dfb520a6L,0xf51917bced96d0abL,0x8131985078b11135L, + 0x6397f1288f006a55L,0x9877f30e576b5132L,0xe0cd103bec781571L }, + { 0xb4bf74e5bcfd5046L,0x04333aa4be9cc561L,0xc6dd1dbc1e066ca1L, + 0x03c926e1d3718e62L,0x13bf83d404309072L,0x79649ba0ba28ac51L } }, + /* 22 << 28 */ + { { 0xcb1a73c55abfe8a1L,0xe9e2e220deae1d92L,0x2d953d00514befaeL, + 0x74024df9b7940bcaL,0x9a2cad0cd13f4a3aL,0x8790b699360795fcL }, + { 0x63957f3b5e9982eaL,0x491bf3155b7d256eL,0x5708bd4dd23324e7L, + 0x9f11ddd397c4c8c2L,0x1823762f5b7f5162L,0xc45a3976cbfc9dd2L } }, + /* 23 << 28 */ + { { 0x806134cd30731f5cL,0x04522c23487c778cL,0x99b6e6a1651640a5L, + 0xe2d20ed87e9898d1L,0xcad25762069e56d9L,0xd4184f6e29ddfc7bL }, + { 0x1017badcc1aeaa34L,0x7d3700e7f3c62e08L,0x203dcf8d5e42399bL, + 0x05986c66b72795c7L,0x0b56ad9cc0925f02L,0x1f0e895bfe0e3bd3L } }, + /* 24 << 28 */ + { { 0x935b9e244d2edd5fL,0xfeb46fb5efb287b8L,0xa51700a3f5018b92L, + 0xc328beba23864e2aL,0x113b5c9a995f70c1L,0xc0b11c22da1b5d51L }, + { 0x9b99b907f4a360cbL,0xf4ee9995adf0b094L,0xf67c7cf2f94b3f0eL, + 0x664a51a1dcaf10ccL,0xa3709ccce937a669L,0xea97bace4862f098L } }, + /* 25 << 28 */ + { { 0x62c7dd9ed537ed6bL,0x8a82ae7ccc168feeL,0x96fcf8d19d00a4a9L, + 0xfeef6ec205096874L,0xc828c68969f4485fL,0xdc4903a6322563f0L }, + { 0x5339cad7d3280a32L,0x42ae434909ff15cfL,0x94cdb7790bbb6af4L, + 0x480f8a5515721529L,0xc2f9c4dc0ff28eb2L,0x9d2a405e1ff6e3d5L } }, + /* 26 << 28 */ + { { 0xfeebe7d29309e729L,0xd322c38aa30a4eb9L,0x18cb0ce12f4f5c8eL, + 0x08a073a04262105eL,0x6ca92585933f888aL,0xf4a080c903ca1489L }, + { 0x5e678c7949c8daf0L,0xcd6ef6ba5abfcf82L,0x61faba612a4fc564L, + 0x7cacb3dcee0b306eL,0x9fcfafadb5aae2a9L,0x193e841c4b8fb04bL } }, + /* 27 << 28 */ + { { 0x4db6f5f07ed99ce4L,0x1257bd9c2456059bL,0x546c764b43d3590eL, + 0x6d5062adebba72d6L,0x6858f04e2e8d99fcL,0x46554047b4eeee5fL }, + { 0xff433f63535f2da3L,0xd76777542b76d2e8L,0xeb6be9c88e838a3fL, + 0xb7a2d2c1145f8bf4L,0xf3ba128703bb278aL,0xd88cd51530c4a1a4L } }, + /* 28 << 28 */ + { { 0x51758334c942a3f5L,0x7cc01e8832182ba6L,0x772af25774de4fe6L, + 0xb1b3c448e9667bf8L,0x71cb27388079caf6L,0x48890c641d823a40L }, + { 0x47a5887b0e9edbdaL,0x916dfb0cbe089e5aL,0x3185090e1eb42ddfL, + 0x3c7eaa13b7f3af26L,0x940ed8c79e9963b2L,0xd85e77db3426ac10L } }, + /* 29 << 28 */ + { { 0xf21b47bfd7bbbfa1L,0xf757cb309ea0ea77L,0x6df7f53783b2a6dbL, + 0xb0808cf99eb8ed81L,0xc526bb6b64edb3b6L,0x24f1612068f72d82L }, + { 0x3e2e6af8f01cee94L,0xd2e01f947847ca60L,0x079dac3539e68ac2L, + 0xc30720b270cedeaaL,0x2f97f968fa6bf057L,0x2dba403babf6a743L } }, + /* 30 << 28 */ + { { 0xed99932452c802f1L,0x99f6864c5cb78b2eL,0x8f8a0a709b9c3693L, + 0x0b931016e2f598bbL,0x7edbb1b3a614fc15L,0xa0321b50e79f74c2L }, + { 0x834f3ee994bfa457L,0x5ffa9613006907b4L,0xa37e9b83d779b46cL, + 0x7a21743cf33b791eL,0x6646b89dcc28a011L,0x9b975ef8e2ba76f8L } }, + /* 31 << 28 */ + { { 0x166c7151ec72cbfcL,0x3d1f2450c9e519ceL,0xfdcc648e7efc0fa1L, + 0x3f5f90cf6db6d516L,0x8a5dd3df145830f8L,0x4d9938da4e5858e6L }, + { 0xe598f9d4dede1584L,0x2de5a26cf5c8f4e4L,0x495b750f364e20f6L, + 0x29291c445b718188L,0xe560d9ee3733ce27L,0x99b9d27d5b9d206cL } }, + /* 32 << 28 */ + { { 0x162cdf342efffd95L,0x92111fdad59086e8L,0x4478d114454eb977L, + 0x8ce403d8dea38a67L,0xd459633b7435728aL,0x3a7be4e3a63b0504L }, + { 0x0c74066b335dba3eL,0x4e8fb1d7c6ea6ee5L,0x3398b588a99690edL, + 0x4949517c3ad77562L,0xf9824f09cbbb60eeL,0x9fdcafdf85660becL } }, + /* 33 << 28 */ + { { 0x368bea127aa62889L,0x6096730506e1046fL,0xe69be05e564f219cL, + 0x064b9d7c01eab75cL,0xf16ccc9e0152981dL,0x708827acb178a3deL }, + { 0x320f6a8a93248b89L,0x532acc568084908eL,0xe494cd1f6ab586d3L, + 0x59c74cacabbdcde3L,0x3ccf84a62259abeeL,0x6657d1fad96bd141L } }, + /* 34 << 28 */ + { { 0x5d3a8252aa0a9dcdL,0x540e037af97fe26aL,0x4cbb768ca3f68f56L, + 0xf9608732652d7058L,0x5fae0f9f72cea8b9L,0x1a7edfd97d980da5L }, + { 0x9f00ee611791c34dL,0x6c95404c2bc25810L,0xabb1089e043a9faeL, + 0xe36fe9e1a7881ae0L,0xf163dc460fc04e9dL,0xb6955f2f129c7940L } }, + /* 35 << 28 */ + { { 0xa22ebfc7c23bcd94L,0xa653b119684fe9f2L,0xe469e28646b59d70L, + 0x0720daf3dad96b47L,0x5066df7871288c07L,0x7648d7d82905b5a2L }, + { 0xc6ab9c5c0a30a65aL,0xa00539f34930712aL,0x6a64738c7e894bdeL, + 0xd7f3a7459e8eafdfL,0x652a58ff8ce9f7b2L,0x7c9d02e4cb3782bdL } }, + /* 36 << 28 */ + { { 0xf26bd8618875d9e8L,0x22e2380dbea9c273L,0x5f15183791995508L, + 0xb97f40a6648aa1c6L,0x7478f5f83977d848L,0x21e876ae35b57de6L }, + { 0xf620b180a93fc7f6L,0xf49bd07e1b148996L,0xfb0857261c4f60e1L, + 0x6a6653af7ad6b84dL,0x913a2d022e05b686L,0x94746629407dda9aL } }, + /* 37 << 28 */ + { { 0xc662b0f68a97c714L,0x69fbf7d1b8fbbb02L,0xf3bb5a9c5cdff85dL, + 0xfade6eb036ee44f3L,0x6eb4b8266d0905c8L,0x6ab3e4a4391a34d6L }, + { 0xf490046478e7bdb1L,0x8bcd4bf23272c400L,0xdf9a81b78d2c9573L, + 0xb9a0ea166af43695L,0x3298a5d071fe768aL,0x53eeeb4333e87bd2L } }, + /* 38 << 28 */ + { { 0x87cdbfe6bb531d08L,0x384bcd0357957992L,0xc654e2c942008cffL, + 0xd12b50285002e06aL,0x41a34286a67db410L,0x31a109d99d6b2c01L }, + { 0x14d642da2ed35f38L,0xa06a846048ffd04fL,0x8291190cbdbeef68L, + 0xc8106239e43bb0c9L,0x4d7aa992c4bea448L,0x107b86efba3dd9b5L } }, + /* 39 << 28 */ + { { 0x3d870c3144fc1cd3L,0x34409eec0085e7b3L,0x67d5c1340d0395e6L, + 0x9c30dedae3f36689L,0x988ac951d268cc91L,0xdb05825bd2c9dfdfL }, + { 0x30ccc3b75d349fd5L,0x63383c0f60c3a79bL,0x4f45c81732c71964L, + 0x456679642fef028cL,0x82454c12cf4053f0L,0x7c1310fbed8077f0L } }, + /* 40 << 28 */ + { { 0xb8465d16da684157L,0xdadde1abb238faaeL,0xe2cd45e7c6b9bea8L, + 0x7251d4a15cf413d5L,0x615cea8baae1765bL,0x75aa831813f36885L }, + { 0x7d5b0bf7b8767cc1L,0xec38a8ff8022968cL,0x034805b62a07faebL, + 0x916f9eb033b7321eL,0x34963633c0c577ceL,0x8ee07efdabb8d3ceL } }, + /* 41 << 28 */ + { { 0x498606fc2d15a409L,0x2398e109d5fdcb60L,0x8ed8fcbc36540c3cL, + 0x94404e2bc1db3193L,0xe62b808b28db1c38L,0x545b60871ad1d686L }, + { 0xe8bf6489740f4264L,0x7ee76fe71809505cL,0xaa95b8c86f45a011L, + 0x9bd6111b55c715c3L,0xc5c736bc33165913L,0xf1e8cdf282f6c7a9L } }, + /* 42 << 28 */ + { { 0xeb09e7fa949d05b5L,0x49394c1b8d014014L,0x644874d73eb7abd7L, + 0x89c666e5679d2a01L,0x6ea98cbbd315bc8eL,0xd919142a37fa5a26L }, + { 0x042fbac56d0239b6L,0xbff2b086837c510fL,0x21e4d279d9883ed7L, + 0x6416e0239713c2b2L,0x3742c6d14ea05144L,0xff591d8fd5b00fb2L } }, + /* 43 << 28 */ + { { 0x0ae21b83c138ed42L,0xf1b0895a2ff30df8L,0x4d5d634d9559c6e1L, + 0xfd02f3a3098e5c4aL,0x7bc6b63152bb211dL,0x498a68fffb69f0ecL }, + { 0xd6fd5f443e69b479L,0x5ea1877d8c740d2eL,0xfaaff5f0ca605f02L, + 0xb3022f9839a03f5bL,0x3feb7c13aa253725L,0x119097a89dc33a73L } }, + /* 44 << 28 */ + { { 0xa0bd6c0da8a29345L,0xc676b6c55d7f5ef9L,0x303b6d7c20ad7259L, + 0x06542a19d8fe09a7L,0x5a06653ca959014aL,0xf45fd79a5bcfe0cbL }, + { 0x29058d984e583468L,0xf1bd25e60cd7afc0L,0x2a88246ef7dbe54cL, + 0x680eaff835e0ef3dL,0x5942c97f726e59b9L,0x43e971398d5c0825L } }, + /* 45 << 28 */ + { { 0x6656b318f7378bf8L,0xf9a838df182f1a29L,0x0d62dc5ede475756L, + 0x97564544585bcab5L,0x3e99f44c857a13cfL,0x8c3a0a940cbdde00L }, + { 0xa7be375833dd2d24L,0x629040f1bbb1c7eeL,0x0bb2ced27f0eab7aL, + 0xb86f1e1e9f474277L,0x60539a544a14ac4eL,0x9860f986aa90977fL } }, + /* 46 << 28 */ + { { 0x143fdef1fe944aacL,0xfd6700fdd24f606cL,0x5dad2e41737404a9L, + 0xb16c5d42953abdccL,0x132b5cd995be01c9L,0x2bf605d86fd01c6bL }, + { 0xed62526c8803881dL,0x3429579201788c26L,0x553f8e0f8d62ab25L, + 0x3b2df9cf9850ff9bL,0xb320ec40acb513b3L,0x86d61c988875dfe7L } }, + /* 47 << 28 */ + { { 0xe5fbda4daab3cc32L,0x556fcd2535d469a0L,0x414673d91c02fb7bL, + 0xc14ee9fd8bfe6a4cL,0x8ba0959d1133d9f3L,0x086a7c94e94338ddL }, + { 0x92c2f484cdd5a1b9L,0x97bb21f6ea0e0f9eL,0x99756b285411da59L, + 0x4b79c4663be739b3L,0x73502d3e706078fdL,0x6bb794100da7aea4L } }, + /* 48 << 28 */ + { { 0x2daddb11a406d4d7L,0xb02b5da5a2a33d81L,0xb73ce82721a6aa89L, + 0x10919587467506deL,0x0927724c428d8daaL,0x0ede991f7c17adfdL }, + { 0x8518dab1bf7ddb3dL,0x04b091c42a54e1b8L,0x5943c37f89e7a398L, + 0x8e63f5e8e273f6f3L,0xc6d0352b83143d22L,0x30e43182ebd1628eL } }, + /* 49 << 28 */ + { { 0x9bc5af5aedf58e50L,0x31a3beeeb0d51722L,0x5789fcf98cd467aaL, + 0x85d974897793faafL,0xcf09224ecc18f367L,0x4f293783ec7957b4L }, + { 0xb044c854c0be350cL,0x027caaf72a63996cL,0x5341b3f3cb85de2fL, + 0x0d261d80b106359aL,0xf63bfe7a8456af12L,0xa954c4400174c82cL } }, + /* 50 << 28 */ + { { 0xaf752854b02aceb3L,0x000c5c4222c194b3L,0x7e953b78ebd2e61aL, + 0x44dd61b4b9d68960L,0x282ef4216d454ed1L,0xffed862aa402ca61L }, + { 0x5fffddeed3e189e2L,0xf36379990daffe3dL,0x1b09a625857a8a00L, + 0x3e64ff63c1ced62aL,0x9acc484d10b63647L,0x5a470aef3afc8675L } }, + /* 51 << 28 */ + { { 0xe21acfec09ebdbaeL,0x512c66a729b064faL,0x15c08e1191835db7L, + 0x78fff5d665203a4aL,0x99259d961c73615cL,0x85b444b9f36024bbL }, + { 0x4909772df16932deL,0xcc4a526899a3863bL,0xe54557bd2ebff8faL, + 0x1a9b05b709bee4c1L,0x0d2ce396bdb2b785L,0xbd15bcec8ce7ef40L } }, + /* 52 << 28 */ + { { 0x606658a99991167eL,0xb8773e1572c4b43dL,0x6cb364cde025abceL, + 0xafa58e9b0c5a653eL,0xa7e35a54134a68bfL,0xcb831d42ba4d9db6L }, + { 0xae37348ede83ef97L,0x4ac64a6a62ddd553L,0x5feb5e0d715bb6b4L, + 0xf876efae043424b2L,0x7b56a291ad91a9efL,0x817c7053356f3adeL } }, + /* 53 << 28 */ + { { 0x0dbd99249e88115fL,0xecb57472bc568c61L,0xfa4f4a47c1058746L, + 0xb19006014d92c079L,0xe693577091026a8cL,0xebde8e65eefe8740L }, + { 0xe8bc6b3480a93b35L,0xc1c8fc0635518beeL,0xf7f4b448a47cdd36L, + 0xe4d040e0db4f3e42L,0x025fbdfb88345042L,0xfe6cc10f3fbe045dL } }, + /* 54 << 28 */ + { { 0x63ba344a1c20cb4fL,0x55f11c207e8cccf6L,0xe66e1641b5b1046cL, + 0x51cf6dbe758a460bL,0xe786a81e91bb5101L,0x6f4a976209cd4365L }, + { 0xe88b4d03fc565022L,0x46006d0ebfdf8ec6L,0x10a3e85781f4e635L, + 0x28ea91360a4a2e82L,0xf890ea9e757b38dcL,0x89c6789261312e2aL } }, + /* 55 << 28 */ + { { 0x8ce54e2a65d9fc54L,0x4776c1f13bfc0c09L,0x5d15fced99476b22L, + 0x2c5399bc1142dc7bL,0x6faef9d96c6ad87bL,0x4f238e48ca5126cbL }, + { 0xbc7136d607849dc2L,0xc840ccb1e30377a8L,0x30e0f0373a371bafL, + 0x5b8eef9bdfce4735L,0x1662184e514bb217L,0x010ebb8579e0918dL } }, + /* 56 << 28 */ + { { 0x3d6e8d6d8dff7dffL,0x6b6c194ad5be4ad1L,0x57b93f2db6fcd08bL, + 0x99f09948f3761f23L,0x4062f3d6ac8b018fL,0x4b58ac05a27af72cL }, + { 0x4abcc81504d0cdfdL,0xa50043e0bda4b02fL,0xe11297e527a9c083L, + 0x2b2d8d529779c5b3L,0x3de3d330dfdecfedL,0xfe2487caae7fc522L } }, + /* 57 << 28 */ + { { 0xc510bb0b7e7a66ceL,0x54a3e0111332f2c3L,0x6331badedc885f5cL, + 0x1a73c8aedc47d8b2L,0xc657edbb95d4e933L,0x30994aa335dc3ccdL }, + { 0x832d586fafe5be42L,0x3392b07ad44de522L,0x1bcea9a62982450cL, + 0x8237bf2b3709f75bL,0xfa4f2501ea9d03f0L,0xcf492df7bdacd276L } }, + /* 58 << 28 */ + { { 0x2d0f7f28af4ecf83L,0xc2863ae4d48229efL,0xc989ff3d7001268dL, + 0x7f07adb6ba225adeL,0x1564c1db450a15ddL,0x3bfea98c6524d417L }, + { 0xee3cd3ef2cc20833L,0x055c569dba767b1aL,0xef2eaf51351b1279L, + 0x4e02b1d163b809d2L,0xf0e943d00a14c115L,0x2bb3bc3f32f55210L } }, + /* 59 << 28 */ + { { 0x8f577dd79ed385ffL,0xdbcf0548a1fdcac6L,0x38555497c2352ff2L, + 0x33e2ed85eb9edab2L,0xbe4bd6db9e649ecbL,0xea3668f72c6e7488L }, + { 0x841627b8f4b91b7bL,0x2d61a0f7d487c7a7L,0x1932b198142d1dc2L, + 0x06dbb39a1a792783L,0x5be16e570bede1faL,0x4d3b197bdffceb55L } }, + /* 60 << 28 */ + { { 0x1c2fc5088f7a83e5L,0xa7c56233b9970c92L,0x949c71738bafa66fL, + 0x1e299b2d5bbb0490L,0xb9a79e7c18fcb9e8L,0xe6372ce69cb5cc50L }, + { 0x114fc628f465c6aaL,0xc55395208cb797f6L,0x7df94ed7a73ad211L, + 0x41eb8e1f8e0cd008L,0xb028725a004cbb0dL,0x1340186d372c1656L } }, + /* 61 << 28 */ + { { 0x5162886c203a829aL,0x60dbd8d464416392L,0x60589a51b5a10685L, + 0xa79ca259113476a8L,0xbf4f71100d7b37dcL,0x1a1b3fdf78bbb029L }, + { 0x2954d3454799a0bdL,0x7459eac788c256efL,0x61ac72653800707cL, + 0xd861f7764cc84f7dL,0x29f4e5bf84faae3aL,0x7975c9555aa1236cL } }, + /* 62 << 28 */ + { { 0x65f28419238c3c84L,0xf07d83ed90f1ecd1L,0x10307e1bf6567704L, + 0xa94dddb389d17845L,0xaa56f72788f39175L,0x01cf57e2a7aa55f7L }, + { 0x98f4340e77f21e8cL,0x8cd3e0a2adb036c0L,0x5c49ebf4af6b46ddL, + 0x312a2c32455f6897L,0x52fb4f488b517f06L,0xb0f373d442beff4bL } }, + /* 63 << 28 */ + { { 0xd9694bd9af44f9ceL,0xaf2cfbbc1ee29f43L,0xaf352b1c880f80ddL, + 0x3fdabd2142297787L,0xf5a2acc21c7916b3L,0x6154b3f2cc0d85f0L }, + { 0xb9ff2bea0bc58e86L,0x359eb0750561c3d1L,0xbb5a318fb93be593L, + 0x34af9320bff0b3b3L,0x3cbe89341d967c37L,0xd08e5f46a8e9a750L } }, + /* 64 << 28 */ + { { 0x4074ee27978029bbL,0xa9394bdabae0d0c0L,0xaa01d53972cecb4bL, + 0x4b0cf1279a7dd9c4L,0x3e3e3f165bc787cfL,0xdf48f7e1942de53fL }, + { 0x0cc69719567b9d0eL,0x631e33158d0d2750L,0x9fedc1e292314a09L, + 0x7547d22614a1adcbL,0x405561a48662b86aL,0x149fa2b1f5480b7dL } }, + /* 0 << 35 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 35 */ + { { 0x923d0b44bda4aaa7L,0xced14ce4fee29f7bL,0x1656be009cf5b87dL, + 0x13a37d0d1d61103dL,0x1d705880fb652393L,0x870a31bbed712ed8L }, + { 0x15ad02e6ad7c21e3L,0xf004e447c36c2831L,0x56aa376cba2b3ffdL, + 0xc3be2b2f9745443cL,0x47c8a870eb903660L,0x976c303e6c6c192dL } }, + /* 2 << 35 */ + { { 0x148bd39cf4fb80d4L,0x469b208cfff04e65L,0xf397fbe2ce548415L, + 0x441e5c2c87fdde9fL,0x6366b49ffee9c179L,0x38d02bd32938dc71L }, + { 0x26d450fac49c5444L,0x4569f95d2b23d3d7L,0x5f68bf4d298fd876L, + 0xe86df047544768b6L,0x40b69a32f8491267L,0xcbf3adf9f917c71aL } }, + /* 3 << 35 */ + { { 0x32498d4d8125489cL,0x965e8d07a5a46ae0L,0x6cea5e47e96a7e29L, + 0xf78293a4668039ffL,0x62548a96f63edd32L,0xe8e6af95a83e8256L }, + { 0x76e60c3b0db6263bL,0xa1ee4b0621b3d668L,0xa17dbf8b9e49b0b5L, + 0x4b29ba127eb366fdL,0x5e0ed781d29b565fL,0x8cb50d53199b36f9L } }, + /* 4 << 35 */ + { { 0xa66c703529aa3150L,0xd038a5ab479e61fcL,0xdee33e96b5ab5410L, + 0xd068929c7c57d123L,0x0839a208f1d6ad37L,0x8f523dab123f8178L }, + { 0xb3e5e524a67d3840L,0x88bda75e52eb59dfL,0x513a0ab7389f2dd3L, + 0x3197a145890bba6fL,0x61add75b6f66bf09L,0x5c9dfc154eef1722L } }, + /* 5 << 35 */ + { { 0x66dc285007769b1bL,0xe07fb7414d71fac4L,0x5ae688a6c2abbe60L, + 0x08ae92fadcbfd296L,0xbc291256b43044d1L,0x0e1d71ed9fcdf213L }, + { 0xf0c5b28102485685L,0x5d3f9302e3f68f42L,0xbbbfac50ffe4f036L, + 0xb5b5f26174fdba44L,0x4ebe1d070d746760L,0xbb0f7812c37f04b7L } }, + /* 6 << 35 */ + { { 0x810b6ab36df1199dL,0xc229308bb4f293b7L,0x3cf838dd89897750L, + 0x3e391e4e7a336c9aL,0x70148337176f89c0L,0x54b15bacbc4f1e22L }, + { 0x32b104f92c0f2885L,0x2c39cefa67034f2aL,0xb8310437bf178ac1L, + 0x722299f5c99370d5L,0x0a493cf0332b93a8L,0x00e0ab41a420f719L } }, + /* 7 << 35 */ + { { 0xf25925434cab24daL,0x52be9bbce7c3b9c5L,0xaab7a8b64660d1a0L, + 0x09738b819a9600f4L,0x58f0c86637de9e3cL,0x0aea5cc15db31f4fL }, + { 0xe480406f499868beL,0x0d8fc7f0f6913a44L,0x7282364435f2e14eL, + 0xb147b31045e37a93L,0xb1e7aa5bf15c1af7L,0xa8685068b03e7713L } }, + /* 8 << 35 */ + { { 0x21feb7fc21c34c2bL,0xab6a553addb0140eL,0x03a6557624b04e6fL, + 0x2531f186342cb0adL,0x088c4d54a24f6426L,0x9a0ee15c06a873eaL }, + { 0xdbe0253fd33bc748L,0xdad3339f5db8ac9eL,0xeaaf368173e65901L, + 0x71f1fab2ccbfa504L,0xb7b845224b0e163eL,0xe0fca8373c779f3bL } }, + /* 9 << 35 */ + { { 0x710988eb46baf373L,0x8cceb935b57d5018L,0x1864603fa45fdf17L, + 0x3dcaae73ef48e6d0L,0xadd9420b590322c5L,0x947783e39b135f67L }, + { 0xfde763688bf5049fL,0xf00e4c182caa4023L,0x4d3b0f23d355b3d6L, + 0x181fabcc20d5799dL,0x29499b40ab2ad0afL,0xf6e66328f9a938aaL } }, + /* 10 << 35 */ + { { 0xcd7b3c42bcbe922dL,0x2fe02b3b95dd1a5cL,0xeb66bcbd24ef5c38L, + 0x7edcc21ce579c309L,0x7b19d49116f6c900L,0x36019ecdb6317c2cL }, + { 0x554ba55391d9001cL,0xa5e30b9814f31e44L,0x3d1fe33bffda4032L, + 0x5dfec4782306675cL,0xbe59305e000c91e7L,0x3c4e52a325a6b879L } }, + /* 11 << 35 */ + { { 0x02fcc14ec5ea88acL,0xca29bb6d56d093b6L,0x876aeda90e6fe94dL, + 0xfa11a142d7225a9dL,0xfea3ca053d03fed8L,0x435854c6c54d5962L }, + { 0xd770737454a6dfd5L,0xb8960017a3e55d02L,0xd4015a0c04d65c3eL, + 0x397f93d1e98a1204L,0xb0efa2e55f3ed850L,0x18f244698a3ec67bL } }, + /* 12 << 35 */ + { { 0xa35802f5d62cd9f9L,0x0ca9c15d4148436eL,0x261a991d472b9d21L, + 0xd81a1ed6a2f8e875L,0x942f213a699b6d63L,0x041a12fc0ae57758L }, + { 0x61191c82bd70aabbL,0x3776eb8bee4c23b3L,0xabe23e8652511222L, + 0x66dd967d30dabb91L,0x77650c597ed27424L,0x08ea2ebdab25a050L } }, + /* 13 << 35 */ + { { 0xa410ba3ab6cb5a02L,0x6eb40d15d07c5c6bL,0x0de81e9107dcc811L, + 0x996f46eb2631b7afL,0x5a350ba75b7a22f3L,0xf42b24e7634159afL }, + { 0x07bae0abc30952fdL,0x3488cda2d644e0b0L,0x23ae40d0e2111e12L, + 0x650af54ec80cdb56L,0x0f33a30b7d4aa2a8L,0x4e8d3e98442a00e8L } }, + /* 14 << 35 */ + { { 0xa624ab3759a8bc95L,0x4b7e3fa61c971228L,0xe8229c4273aa694bL, + 0x0cc31029779288abL,0xf8eff30f57575e0eL,0xee5e01947d52803eL }, + { 0x32d87e558a78f632L,0x48a06031e454904eL,0xaa2cb8dd16c6e626L, + 0xadd098ac2c140452L,0xd25f285d2d3031b1L,0xfb5fbbe175b59543L } }, + /* 15 << 35 */ + { { 0x2297041fd7a21503L,0xfe7738c2657f03f0L,0x994a8deb168fa34aL, + 0x0c772e02a53c4fdbL,0x67f835d150124cd3L,0x0e0d26356993cbbeL }, + { 0x9857ed845257f11dL,0xdc23a728ac556942L,0xf0e1bb29deb32a7fL, + 0xb8c3c43fee0d70f4L,0xc294b0efc60ad214L,0xa4d438dc679067caL } }, + /* 16 << 35 */ + { { 0x520b0bb905c755e4L,0xa2c2c59bf89f0048L,0x85c1c73a73c23975L, + 0x6e4dec49783aabbaL,0x69f0c69bb0463155L,0x61a42b949c97b17bL }, + { 0x55af24a945d331a3L,0x4b0e63f8f5fe81fdL,0x4034283d708671c4L, + 0x200ddab35fd9001aL,0xe45f28e4342eaf3bL,0x3e8375b41ba936c4L } }, + /* 17 << 35 */ + { { 0xcde014bbc613b1faL,0x5ad97babcdf992c2L,0x9fe05b9fea13e2d8L, + 0x93b553e290c4031fL,0xd62bc0818c727bebL,0x284fb61f888306caL }, + { 0xa63f8dcd1101abd6L,0xfe02dc120e962b27L,0xab169958115301e7L, + 0x8822f954462209baL,0xb3ba3e721198428aL,0x9a73ed38d74c88f8L } }, + /* 18 << 35 */ + { { 0x7db497e17da2f887L,0x0995648b683f3507L,0x50e3ff74f5935bd2L, + 0xdec083e2708c88dcL,0xbcc3bc3125129bccL,0x7a3fd7a80a407b41L }, + { 0x46ab826c25e0ab93L,0x28e891ec54944cfcL,0x637be168f55c6cbfL, + 0xfa34e9942a65216eL,0xd23e99afe3a43c84L,0x6d09d189e6fd958bL } }, + /* 19 << 35 */ + { { 0x8aa6ca1381bbd283L,0x3a0633f4ee167a15L,0x7f297c8b9e3b18e6L, + 0xbead8a50c71fea64L,0xa11b2fdd457aebbfL,0xd7fc286f85bc7bd2L }, + { 0x2922ae5bad1c9d9dL,0xa07741c2ef9ac174L,0x24dab2d457fa8f9fL, + 0xd7078d946116a870L,0x4b45107834117a37L,0x19a4dd21c73c857dL } }, + /* 20 << 35 */ + { { 0xa2f9b4e4bac5d14bL,0x9f904a3eb8699164L,0x63585978fec79b4fL, + 0xbcc9b60ebff45cd8L,0x2e515592a5d63de5L,0xc47a048c3bcc637aL }, + { 0x0523810643aba777L,0xf6818e4c77e67aacL,0x9d5827d238f962b3L, + 0x28a904c6a003988dL,0xc06bc833551f4575L,0x61f6bcc2221cffefL } }, + /* 21 << 35 */ + { { 0xf7cfbbe5055a5623L,0x1f8af775e66d2a5bL,0x0cac440268831d8cL, + 0xd25185890d0e6f2fL,0xf17838a3182f90f1L,0xefdf6f20737f163dL }, + { 0xc3198af0542242e9L,0xf77c3d28209efb0bL,0x1df6d0da8de7be08L, + 0x22ef7367901a6590L,0xfa9b4af44b776d27L,0xdc49102c88ace4f6L } }, + /* 22 << 35 */ + { { 0x60c7d148bafa9cc9L,0x0afc5fe2516b87fbL,0x02e20acff795ff60L, + 0xd1ba069151f32975L,0x8547e7f757be2399L,0x4bdf6abfa0d1b33eL }, + { 0xc793832fa06077f9L,0xad55cccb2d874993L,0x5e217b27314387d8L, + 0x744d7b06e7f2ec4cL,0x761aa86d24fa58b1L,0x41400d9657dd313dL } }, + /* 23 << 35 */ + { { 0xd17f68da759d20f0L,0xc141ca6827b7eaa7L,0x3796db8bdaff5c66L, + 0x067119dca1e5220bL,0x174f11777158ddbbL,0xa80365d8cf8bf75eL }, + { 0x0a79f74933567f05L,0x8c2826123c99bb4fL,0xe448c2bdcd6ae726L, + 0x1ae05aac2ad4b0e0L,0xf90dddcb16442420L,0x37465a1ea75c28e3L } }, + /* 24 << 35 */ + { { 0xf58e05c53178468fL,0xa17c8b868328a2efL,0x1bb22cb44ce0c2f8L, + 0x1ab807b51aab9089L,0x2aafa8c91e76fafdL,0x58cdf95fb4801546L }, + { 0x2c1e4ef8d5d699f1L,0x1583a2aa4cd433bdL,0x571dcaec7f4f9b10L, + 0xf62b696b27156c5eL,0x77d2443448820bb9L,0x94e4cfcc11dd3e55L } }, + /* 25 << 35 */ + { { 0xc3fd1feac00e6c7fL,0xf4e42ddabd322507L,0x1ce3e0da023469ebL, + 0xf81769d2d788b1c2L,0x505cec4c62353342L,0xd4049907ba759922L }, + { 0x9ff98f06618ee939L,0xfa63b3606bd55f31L,0x3fcce488cc4d2515L, + 0xeb6e92e91d629e19L,0xcae4190bff892af7L,0x3e7b780dca80cb44L } }, + /* 26 << 35 */ + { { 0xbc923fdfaf54b58bL,0x2aef31d88767acdeL,0xfbebb8f07f28a3d4L, + 0xce5feafe694fe977L,0x606afb0ac9da1ee5L,0x559866a0b74f7c42L }, + { 0xd935191fdc85f22cL,0x5c3002d7c8ce3240L,0xecd278c198452214L, + 0x665b3176821a3606L,0xce05a914baf26fb7L,0xa178860b60e4e8b8L } }, + /* 27 << 35 */ + { { 0x135c82b55000cc19L,0x34537edf8b2c55b4L,0xfcb6aac2b37acc8cL, + 0xa882e25e8ce8d7f5L,0x531756e98c7ff1eeL,0xdcdaced9ad6312b0L }, + { 0x309a469b7f3aef9dL,0xf306e32588d8772fL,0xe7e6f3abd4dc0d90L, + 0x816b01ae49878940L,0x1cb084e84ba5e2c8L,0x395af25b005d08b3L } }, + /* 28 << 35 */ + { { 0x3832cfd59093efcaL,0x3fda8380ed8b34d7L,0x874ec122e2bd4004L, + 0x3761e9c44270b9ccL,0x6eb2fb1166e640d5L,0x2a45ad23e6dfd0fdL }, + { 0xdcb3272bf8dd082cL,0x7d84341f17486485L,0x0f46b1fda4ca2644L, + 0x81a1ab1e82baf37dL,0xbb1d72713b322f65L,0x1571e326f4038252L } }, + /* 29 << 35 */ + { { 0x4e00aa41d9acdec7L,0xb2b701bf9f80dff4L,0xc366ce97d5e71e0eL, + 0x28c2b4e9ed09255bL,0xef54a1a535086ba6L,0xee2e43f2a1c8b39eL }, + { 0x346f22f5d9143a78L,0x71fc5c06f1053377L,0x1789f7644737b5bfL, + 0xc9f83ee8b0df2648L,0xf91a29e9073ee793L,0x18eb801e3ab450a1L } }, + /* 30 << 35 */ + { { 0x1c3df0914085f0b6L,0xc60c47f5cede211bL,0x7bdead8650b6e857L, + 0xc68645be2cf9aad6L,0x8d970a94d01540f6L,0x9346f253782ec6a1L }, + { 0x3da31263c1b23981L,0x53076158dbabfb68L,0x22947b9f743dfba4L, + 0x872e60061c56f47aL,0xe973d81c2b3b8417L,0xb98216184b1fed56L } }, + /* 31 << 35 */ + { { 0x29fa699b8873de48L,0x64f9e1124932447fL,0x4fb0e009e4c20d43L, + 0x748a0cdf78016262L,0x4891badb7bd23ea8L,0xf1300a437f56368cL }, + { 0x178efa9de8f1f8bbL,0xc31cdb4098a31dd6L,0xc2d5bfbad2c43f9cL, + 0xf377e2cc8678d990L,0xd42d274808d19833L,0x2d72fd4de5ad5e63L } }, + /* 32 << 35 */ + { { 0xb083ba6aec074aeaL,0x46fac5ef7f0b505bL,0x95367a21fc82dc03L, + 0x227be26a9d3679d8L,0xc70f6d6c7e9724c0L,0xcd68c757f9ebec0fL }, + { 0x29dde03e8ff321b2L,0xf84ad7bb031939dcL,0xdaf590c90f602f4bL, + 0x17c5288849722bc4L,0xa8df99f0089b22b6L,0xc21bc5d4e59b9b90L } }, + /* 33 << 35 */ + { { 0x44e6089f006e422dL,0xb4a99bc45b029c6eL,0xd14bd00e6f289edcL, + 0x8ebbedfa25c50773L,0x5bdad80851d3ade5L,0xe4e70c3094727960L }, + { 0x29b759e863ab2622L,0xe20ad36b134d5982L,0x27c8387f4070e06eL, + 0x9fae222556593896L,0x299a0f0c3b199172L,0x476fe70977a39ca4L } }, + /* 34 << 35 */ + { { 0xc91a3d2ef4d0d8a4L,0x450193a819e05a78L,0x0e59e0b89eec69eeL, + 0x2ba20f00138fbf46L,0x5c9fea780e8ae694L,0x62c81c8cc6b73372L }, + { 0x2a1df446ff0997a2L,0x929364ab692bb930L,0x4c4a956436cb618cL, + 0xc55020a0526be5dbL,0x151f18a02c64c026L,0x2ec5becd61724143L } }, + /* 35 << 35 */ + { { 0x139c7d788713439bL,0x46f7bd4b1e19b1caL,0x74259a28b47977d7L, + 0x89a912cb8ab1817aL,0x4428e45f06419142L,0x11b9c4836b34a2d5L }, + { 0xb613563a29487118L,0x81f4502ab6249a60L,0xe28685843d4ddecfL, + 0x138c97297bd250dfL,0x733f2201aaac4593L,0xee6b85ad5d061887L } }, + /* 36 << 35 */ + { { 0xbff288ed74006fd8L,0x388c5a34ded657eeL,0x47d400a2d61a2995L, + 0x54c684af1eba1f65L,0xd1ba6975b1b4452bL,0xb23dda26f2f8283aL }, + { 0x6bff7acf86803147L,0x839571e5e8ea5923L,0xc89e1048dbc4ccc5L, + 0x1fa0221120102232L,0xbf7b8f902d4e4406L,0x14c5de43576aba0eL } }, + /* 37 << 35 */ + { { 0x6c55807bfd2f9b11L,0xb01d9f7239e338efL,0x94f6531135628879L, + 0xae51cf0b0ec6f5b4L,0x387223cfd36b9719L,0xeeb02cc6f2fb192cL }, + { 0x867611ec43c9e89cL,0x5b15785f97930887L,0xb792b88b57ab078bL, + 0x0c54de110bdc03cdL,0x5785811a30d0eee3L,0xb73bb98436b88b00L } }, + /* 38 << 35 */ + { { 0x0d0ba3c06fba6f94L,0x7f7e0f5cf29713c2L,0xa8cce53ba6b94d6cL, + 0xbea99382df40fd27L,0xb3ff1c56bcd4f8b2L,0x19124644418f108fL }, + { 0x6fc5260727c26f18L,0xbc5e23d682c7c8f9L,0x12aa5e8e099b8cb3L, + 0x9d94d88614c579f9L,0x5c629d7a47395f32L,0x9cd280633efbbea0L } }, + /* 39 << 35 */ + { { 0xf0bbf8e88edb7b56L,0x9a76ad71adeb43ccL,0xd99a92528643e982L, + 0x6468ff05cf17f5b5L,0xe6589476d56b985eL,0xdca4273cbe446b3dL }, + { 0xd430e3a47b9dbac1L,0xe075c00f4cfe735dL,0x3ba43fef12395845L, + 0x6895f0c3dcb49ce9L,0xd868006aa92843dbL,0x968a8ceec0d5bc9eL } }, + /* 40 << 35 */ + { { 0xc0387b57f440fe92L,0xce8bad38e291c443L,0x022052e5f9e88be0L, + 0x6f949fe261615c9cL,0xf4874e2d84725fc1L,0x06fb244b73a394ebL }, + { 0xb70553c678208bd8L,0xab1829c028704d28L,0x1453ee1a807b160bL, + 0xa1da80c34649d33aL,0x072e02e056c32ee1L,0x79baa98f3f590646L } }, + /* 41 << 35 */ + { { 0x1613a710b0fef3f2L,0x9ae438012edeec54L,0x07824d08579c3130L, + 0xc2beaf806ba2b1fbL,0x7df3c459fc9e85e5L,0x8debf613dbd63acbL }, + { 0x2774ab78f04f3526L,0x36e7ff55a5285219L,0xf2adccaf4ab04c77L, + 0x14add3d8aa43fbfeL,0x387e4965e3026ac4L,0x154801a1c77391ddL } }, + /* 42 << 35 */ + { { 0x28687291933bc404L,0x6a13b0cc9ba35fa8L,0xd3d1746931c5d126L, + 0x1c81ce5df9727cfbL,0x14f66be860b464eaL,0x0bbdefb8c10ea9f6L }, + { 0x5679a0e5e8d06c95L,0x380161d83dbfd6e3L,0x6cdd31f20523e6d1L, + 0x2ff419e0c4b4c439L,0xc7439153e217782cL,0xb1b74383f6dc5d95L } }, + /* 43 << 35 */ + { { 0xcf0d1d2d03746e38L,0x8476c982916e077eL,0x93de41516dfdc6d3L, + 0x15010d26b78cf13fL,0xbab5a5de97cb08c0L,0x37f0673014a31939L }, + { 0x777c709f6819b0f4L,0xe3c2d2f7114a32e7L,0xf0227e19ec047092L, + 0xe1416f34b817e1e1L,0x4d7db41419c6c3f6L,0xf12a13a9d01aecb1L } }, + /* 44 << 35 */ + { { 0xa09e68e61f023abeL,0xbc432449aae2d6c8L,0x61e22f727cb683dfL, + 0x0b5bbc0fd81a0e89L,0x18ea4e774581f128L,0x28df9961cd70a12aL }, + { 0xb0d3b19f8b8bc10bL,0x0805d1439844e7f8L,0xe3ed3d40675ab6a9L, + 0x026d1200f75e2859L,0x1802457b8bb10969L,0xf94c62b3eadab8caL } }, + /* 45 << 35 */ + { { 0x518e9c4220d03ce7L,0x6c44676187811010L,0x07ff38f99d9be611L, + 0x5c2bac105cf0cfd2L,0x4e5cc677d5881c2dL,0x02dc395f08e39281L }, + { 0xc3ef99142044f4e9L,0x0203508c20c8c831L,0xd1276c030e0524c9L, + 0x5525c0af5402f999L,0x5c9a43aa49c2371bL,0x6d7b6700d28cbb59L } }, + /* 46 << 35 */ + { { 0xdec3ab0f7bae55e1L,0x6bae4baf56152625L,0x1d597c0c839b5d6aL, + 0x243692a966b3b169L,0x37f2ca8eb01c6d34L,0x5baa355aae5c05baL }, + { 0xe0b84c28af384b13L,0x6a2c9386667cd513L,0xc361a75d78319608L, + 0x0c317ac596ca528dL,0xe243aa8672f0a5e0L,0xedcf9f5fa1d1677eL } }, + /* 47 << 35 */ + { { 0x88e5cf3f74a0a7d2L,0xa25a3883cac23d4fL,0x7be2fc2ba6eb3d72L, + 0x188be28d391326cdL,0xeca6aa726f3db24fL,0x237cd6f70b9a11a1L }, + { 0xafeca5436fecffeaL,0xa32291510e6d18f3L,0x46699e2500dd8b76L, + 0x5edb4b1a331eaa12L,0xecf6d8a472ce0658L,0xd91af8da6b80e9e2L } }, + /* 48 << 35 */ + { { 0x7af5da7b63ec62d4L,0x74dc387261dbdee2L,0x7d08dbd360b519a4L, + 0x4e785f79459ef257L,0xe3e7d5a485fa9e7fL,0xea60c815e9b5665fL }, + { 0x2e570d18c209caf9L,0x7bae108371818d1eL,0x5db42a0a398d749aL, + 0x149740ff4f555604L,0x72e4f06bbcee0abdL,0x0ecc0cb581ad0830L } }, + /* 49 << 35 */ + { { 0x43550eea0a34451dL,0x8b0b97e9c3aa33e3L,0xdd974528da22dbdeL, + 0x0337c64dabff3ed2L,0xb50da9e9230cc211L,0x931f891c004d17d0L }, + { 0x8b7f9ccbff366019L,0x5483938033d76a4bL,0x52fceec1950ef740L, + 0x5b19b50cd18125d1L,0xbbb661f55b9011c7L,0xfbf0ec747beda7fdL } }, + /* 50 << 35 */ + { { 0xebca6bbec047276bL,0xcda078e05c3018c5L,0x4620dedda223af10L, + 0x962f389ad02fd60cL,0x901fab93baab3894L,0x5ecbbd7506eab11eL }, + { 0x865dc95e62203b9cL,0x04a599844acf85edL,0x877e94647607236eL, + 0x09592a5684609563L,0x6535176ace76d699L,0x44f2d997ce8812e9L } }, + /* 51 << 35 */ + { { 0xa09c9ab62285b330L,0x6058d94a9b145627L,0x7b4b4141da3c3571L, + 0xc9347a16033b665cL,0x95e9b4f01a33d052L,0x35520f3cd46c67b1L }, + { 0x24938cb136042a9aL,0x5eeaec9de73b7354L,0xed47914931f08616L, + 0xb0187b2b713a2114L,0x03c49947e3b76d73L,0x79b5778a2e94fc7eL } }, + /* 52 << 35 */ + { { 0x6bb19d2162de1ccfL,0x3810bdb3339162c2L,0xeb56c72b6aa09df6L, + 0xac66c58d1d415050L,0x922cd7e74ad9cc85L,0x09e3585f91168090L }, + { 0xffc9a98d31b918a6L,0xc273e186c73c7513L,0xd506753f12a77342L, + 0xe288a471e5edd613L,0x0f358d310cacf05eL,0xfbadfa2d9a63fcfcL } }, + /* 53 << 35 */ + { { 0x020e282989cf155bL,0xa1fa6eaac7f481edL,0xba422e09c5c89724L, + 0x43da4df7cad8186eL,0x1bea459cba3ca738L,0xe9f0afdd0c64bc9bL }, + { 0x4c3b3b8e3592686eL,0x7e6938a7b43ea3f7L,0x8e01a54e7ba7dad8L, + 0x33ecd36ea9c68839L,0x1abd6e125e7e993bL,0x29947e126531feb6L } }, + /* 54 << 35 */ + { { 0xb0fe9b7912a193a0L,0xfa19ad4be4bbd264L,0xd5bf0e5409918851L, + 0xd07d8e5729cf45b0L,0x228e67cc7744259dL,0x786ea24843ed0fc4L }, + { 0x7f700231873cd08dL,0x394db4a70ef49109L,0x699047c06a8197f7L, + 0xf5b168443021ff8fL,0x4c8bb55026621cabL,0x6f28b013065208f1L } }, + /* 55 << 35 */ + { { 0x2fb3a7601f809545L,0x8006902ae93849c6L,0x37cc848c9bd9e1bcL, + 0xf4cd31559d0f6340L,0x357772ac4baef442L,0x0f46d0f77d533f1bL }, + { 0x4121411fd9c12bd0L,0x304083dedb70e364L,0xff6b7a1ccecbeb3dL, + 0xb444b5972aadc899L,0x29ec79bfdb8b3731L,0x864d8d917fbd8982L } }, + /* 56 << 35 */ + { { 0xa79feacac241c5bfL,0xc86df4c017861e6dL,0xaecd1722a699282eL, + 0xcce5e345a0464190L,0x0a79c23deca4f6d4L,0x64603ff16a6e7967L }, + { 0x02e24234aa7312c2L,0xa9e1fc7791a1b587L,0x1daef29f94526a4bL, + 0xa7db710a62ead861L,0xb387fec78869446bL,0xee2171015db19f08L } }, + /* 57 << 35 */ + { { 0x79a0feabe64fb245L,0x5799eea096a4e94cL,0x2592e7a333b063a6L, + 0x2cac3c2ef1063574L,0xb9cea04a7f4755d4L,0xb8e40abaa0bf858dL }, + { 0xe1723d963ffa32a3L,0x6547b4402701eb1eL,0x16ec552a4da9b337L, + 0x75f7f4a8fe0555eeL,0xf97e465014f1c2b2L,0x5495fce3d9ccf8a2L } }, + /* 58 << 35 */ + { { 0xffd160fb62c1b457L,0x62efe01fc4d91f7fL,0xc54f75b5208dd413L, + 0x089514d3e78124d0L,0x752a9ae8c2945054L,0x466636fbdbffa78bL }, + { 0x32936281a265949eL,0xd657c0f084b4d11fL,0x199d8641af455a47L, + 0x1eb24cc7dbd9852aL,0xd2ce80f856bfbbafL,0x1b31b23ceb862890L } }, + /* 59 << 35 */ + { { 0xc866d2a5fcd5aaf4L,0x4ac2b7f57e21250eL,0xa78cd3cbc50b4a92L, + 0x2485c3435a5c541bL,0x555db4dc7ef371eeL,0xcd9d6d9c1304f782L }, + { 0xae86a22974b4d57aL,0x68c93bc8dd4cdd8fL,0x7b95411098b9fd49L, + 0x0dd480b9399d8d4bL,0x0e27be29f2665c52L,0xce8a1ef9d920a5c8L } }, + /* 60 << 35 */ + { { 0x10a6bd0cfc0395b9L,0xe30bf6d06a5e8107L,0xc8aa2483167930d4L, + 0xee75885006e7e1c2L,0x4ee64cfcedcb7788L,0x9498e9bbf2f1d7ecL }, + { 0x084d2350ae0fcdb4L,0x4398ee677f4d25ccL,0xc1ddca395db85bfaL, + 0xefd4819747961197L,0xbd16037f2265195cL,0x1c61a6fc56daae6dL } }, + /* 61 << 35 */ + { { 0x640cf6b17f7c8c50L,0xdffddf2209d44051L,0x837275314e3c038eL, + 0x3164d1875aa8d8a1L,0xb37590bcfceb1066L,0x5e4fab4200d489f6L }, + { 0xc1e5dca3f8105ea2L,0xfdd1b0751c7f8679L,0x571d7dd14f14ac54L, + 0x84cc453155cfb741L,0x49d0b1be48823448L,0x8365f1f3f798b5d9L } }, + /* 62 << 35 */ + { { 0x9f2409cb6a564a3cL,0x9266799ae5134e54L,0x39aa3697fac47921L, + 0xdf3db1f32c0b4dbdL,0xfa37a085f096ec03L,0xb99cfe05afaa0f3fL }, + { 0xc9e00e43df458860L,0xbeb7e60ace2bb0b0L,0xdfe2be57cac8d7e0L, + 0x6ec03d799162b2ffL,0xdfe3a6225d1122dcL,0x9f04dcc8b6014310L } }, + /* 63 << 35 */ + { { 0x30471bf9b42ba5c0L,0x19073fd0c9d26763L,0x92817e8059c1017cL, + 0x29248f743da195b3L,0x029d7e7be928767bL,0xf1a3a08a049a0080L }, + { 0x8ec4f3e6e20c1d68L,0xae815a11f3ad30feL,0xdd0a6083f76f43afL, + 0x197d29fe49465bebL,0xf1a40ae996316f4bL,0xec47d65e59bafbc0L } }, + /* 64 << 35 */ + { { 0x6f57752951c2bb65L,0x4a0c1c284b874bdbL,0x19a1842778b96c6dL, + 0xa674f9922f593505L,0x5abeeec46b7209d6L,0x42d15d0147cf5fffL }, + { 0xe24509b7b49e3b4eL,0x81be939c639ee6e8L,0x7f7daf595761e8e3L, + 0xed5cfcb8d420a288L,0x365b29eb7a0ff696L,0x7d14680599a1ac8fL } }, + /* 0 << 42 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 42 */ + { { 0x9ee1ec3aadcdaa68L,0xd98c498fdcbb6548L,0x32b9737588102ac0L, + 0xdd296cf9c08527f4L,0xb74f8145fae3dfbeL,0x84131eb96cd7cc4fL }, + { 0xa0f2fe7a927ff15bL,0x6b0ade4deee1a4b4L,0x6e7df2d40eeb90a7L, + 0xe2f46e20be4de684L,0xcd28feba3fdd06bcL,0x8e4205aee6d6d9f6L } }, + /* 2 << 42 */ + { { 0x35d47426f78d33efL,0x4af25db28440c42cL,0xbd6a15e22e91bf5eL, + 0xe366a84cc08b6b1aL,0x759c122f55b97de8L,0xecec558f08a03f29L }, + { 0xdcc9fca2ea9d2060L,0xb3e49b8e9f361fe1L,0xdeae39029b59cd04L, + 0xf532ede06f5e5bd4L,0x84fbeeb936099f4dL,0x73576b1f088d2052L } }, + /* 3 << 42 */ + { { 0xee43828c6b512bc6L,0xf73dc9f550b91e60L,0x68f23f30f5dbde6bL, + 0xaf2fe9e3ddd15e00L,0xfbf34dae86578d49L,0x689796556c130010L }, + { 0x137a5fc309942897L,0xff1f0bfe9959f06dL,0x2dd0a04abd7ee14bL, + 0x59c46072e54e2161L,0xf470bdaeea7518adL,0xce556e4340c471cdL } }, + /* 4 << 42 */ + { { 0x2ba8c79022b25f2eL,0xf4670a511af0f4a8L,0x6842f36a2fc2451eL, + 0xfc5c9558bb91e1e3L,0x035d1dfcc3ead762L,0x3d0721cb031e5556L }, + { 0x3af0cc813af18a2eL,0x7888cee2bd11a363L,0x80c3de0a6ade1d12L, + 0xe8c3a5bd93b2dcb5L,0xe3adbd7c90a2214dL,0xfe8646d51192948dL } }, + /* 5 << 42 */ + { { 0x9214cd4bf1c7ed94L,0x4887c7c63738f386L,0xa72ba72bf623e542L, + 0x3c52a464f67d6004L,0xcdb6171d09b9a4ffL,0xe5eb77d160aba627L }, + { 0x7aa9836f39d6afdcL,0xa3fa3a520e0a1e18L,0xe90bd925dee3a4c4L, + 0x47e8eeafd9a94dcfL,0x34302a4921e16feaL,0xe32a62eb8ae23949L } }, + /* 6 << 42 */ + { { 0xd1d70db31df1d1f2L,0x22ebc9bd9fec1f42L,0xde5ac585d11d3205L, + 0x0e4584ab282d4d6eL,0xc87607928f78b85bL,0x48a85682af1fbb6dL }, + { 0x64d012ceae0947bfL,0xab792bbf25e22366L,0x250d40d4a3a030deL, + 0xe9b49f0877e26b9cL,0xe7d30c828c0f2249L,0x2b77b40b97c676a2L } }, + /* 7 << 42 */ + { { 0xa89144b89efc8fe2L,0x23625c36e13b79c9L,0x4fdea1d3a047ad35L, + 0xd0b0ee0d4ae78e01L,0xc224b3f3eac4e606L,0x4360e8acfa41bd81L }, + { 0xb2c69238062437e7L,0x86ce8de0decd1245L,0x2ce4be3dfa9d07bdL, + 0xfd09aa853d268d06L,0x4cd874264a162aafL,0x1b28f72e9d45e849L } }, + /* 8 << 42 */ + { { 0x65026297ba958101L,0xbeb4adf98eef151dL,0x623763a460c8bbf7L, + 0xfa8f5ad78b2a7120L,0xfd744bdf085497e7L,0xf9b6f97e2ba35618L }, + { 0x0cebfe9df8a15e86L,0x47a6d01329576088L,0x655817a3fcf19627L, + 0x30ab44f7c2f11261L,0xbb001c9dddf2c850L,0xb45c7eff073260c3L } }, + /* 9 << 42 */ + { { 0x609a02d031716f88L,0xdff6246c45421ce4L,0x544f3162142838d9L, + 0x8842dcbe36b57d38L,0x2818919c57f561e2L,0x87f5acca318373aeL }, + { 0x42773fb72edf1501L,0xff92c38648e9d8a3L,0x21a81668ccd5a860L, + 0xbac5cf837328cee1L,0x7441f749ddc53a05L,0x987d3a1cb5abe243L } }, + /* 10 << 42 */ + { { 0x3b7c44f8fb90e50fL,0xeafeda047cc384fbL,0x9a33e377de65e34eL, + 0x303f568095094a58L,0x4c0f2e932292809cL,0x920c9c12160b30f2L }, + { 0x31d14e1414b268d4L,0x9964173f1eadb1dcL,0x8e22b362eccb0f39L, + 0x81dccdf83bf9ece1L,0x8e2fda43a40503b1L,0xdb647ac13e112199L } }, + /* 11 << 42 */ + { { 0x9c23216f096c21adL,0xae259a6d41fa37f2L,0xefe0a8c9efe96f6aL, + 0x5631701dd6a27744L,0xed8d0219b3017563L,0xbe2723bca0867a0cL }, + { 0xe02bcb56687b62cfL,0xf26c0f77b96f66a9L,0x43e46251fd16fa3bL, + 0x206a180a44033302L,0xcfa96b556121888eL,0x50567a7789dabe7fL } }, + /* 12 << 42 */ + { { 0xb08fb1175cf3e702L,0x7379b1978023df0aL,0x73aefc7b6f954966L, + 0xc0fb886f76bd243cL,0x871eacc5ce09d5a8L,0x9f55b0a4e773f049L }, + { 0x92945c84415d725dL,0xcd57391f0112ad84L,0x4762bc1d0509d73fL, + 0x15cf97f10f1af175L,0x1f855695328c160fL,0x32cb87263b439f0cL } }, + /* 13 << 42 */ + { { 0xb27e344ae6361abdL,0xa53690eb474027a8L,0x500db02d683a8ef4L, + 0x547ecd17819df66cL,0xc35cd4cc91360e21L,0x6ea003a16026dfedL }, + { 0x45e77cda22395207L,0x1e8e103f91264683L,0x130f2d2b3bd6328eL, + 0x6ae25c819af8973dL,0x6b0f90a0d32d7134L,0x0280a95755c62195L } }, + /* 14 << 42 */ + { { 0x23781958cd8bb5aeL,0xe3d30c5417dd827aL,0xf974e0076bedf762L, + 0xd8154b6273264accL,0xf10fd9bb167b9396L,0x967c5acbe9652a0cL }, + { 0x46775025a28fa76cL,0x17ac7cb32ece9d3cL,0x5fd8968ce04a833eL, + 0x96ed5b49fcd20a43L,0x1d209e85289f9c68L,0x4d7473518ce51950L } }, + /* 15 << 42 */ + { { 0x6f5c8f3475214c1eL,0x3d5560bae192d11eL,0xd8a63ff0d7af2e6fL, + 0x5fb858be9069fe09L,0x83956dcd8cc663f9L,0x52d30c3b838bce30L }, + { 0xf354f6d75569122aL,0xfcef54d1fa68f566L,0xc75b01e79020dfe9L, + 0xaac66895774b952bL,0xb2a58a299468cebeL,0xa994a3b487c81a42L } }, + /* 16 << 42 */ + { { 0xfa7d1236e2319f38L,0x9ba1a1c0a551d3feL,0x9ea27288beb1282bL, + 0x1c069efa07fee8a9L,0x5749c7b55870fee9L,0xbedca76fafcec6faL }, + { 0xa3f8f1b14c63c5e2L,0xaa1bb15694758ac3L,0x753329a9b59dc06eL, + 0xfa8e5f5b98a92c38L,0x6b6f46fd3c2b4662L,0x716f41a1ec04c6c6L } }, + /* 17 << 42 */ + { { 0xa882aa6389201dffL,0x3441fde55bfcde3fL,0x220cca60cb543f54L, + 0x2af1cb29d764d74bL,0x47ae56d0517617c6L,0x05b98dee0342bf55L }, + { 0x214f4b11b4e28cfaL,0xa6ebcdf5093691ffL,0xe49ca185f61d29acL, + 0xd304ac40fd8c9018L,0x196161a0f889b7c7L,0x3b704d52dcfc6c91L } }, + /* 18 << 42 */ + { { 0xb405aff88886500aL,0xd88008bebeeabe24L,0x9457cdf30bc931b2L, + 0x8e5fd378f4c5aac1L,0xdec408107bc2bb98L,0xf86424c598b16f6eL }, + { 0xb6af27b634df75d8L,0x1bd3082125943a31L,0x51176cfcec993c24L, + 0xcfc1433accbd192dL,0x324a5e1e2993be83L,0x34169fc1d06215adL } }, + /* 19 << 42 */ + { { 0x41aa181ad260133aL,0x627dbe0346e236d2L,0x717fba9cfb8cc72bL, + 0x6e21d03d69bbc9e7L,0xd903e845241abdecL,0xd17879fa3c20cb6eL }, + { 0xe6141bd463a360b8L,0xa784a651e86cdcb9L,0x80fe8dd11f9147fdL, + 0x641241c6de155420L,0x1caef32ba71f3546L,0x28c3a51a79fdf82aL } }, + /* 20 << 42 */ + { { 0xaa16c27a84a3d033L,0xc207a4990c11c9caL,0x7ae2d193aae87c9cL, + 0x125ab459916d634eL,0x02ded714cfa65b4bL,0x6efe84944e212e22L }, + { 0x97c48a1888766168L,0x663ccc9dd9c85b9aL,0x6fe8b77b2652f501L, + 0x1daa602d078efd38L,0x35885364dbcb8299L,0x25bd1826b8240626L } }, + /* 21 << 42 */ + { { 0x6621d504af748cb6L,0x3940e5e08dacbf89L,0x9fdd8eeaf546daffL, + 0x18fc70d4b42f9507L,0x09bc4af9a3fcc42cL,0x9199b08f4165304cL }, + { 0x039d45bed3d0e9eaL,0x0963ede2a6464c2bL,0x77f47a62b5215830L, + 0x3a0ce54c3e540cdeL,0x34cf6031b2be8f77L,0xeb143e60201083efL } }, + /* 22 << 42 */ + { { 0x21404da5442467a1L,0xe73047597f7023e0L,0x836439a8213ff492L, + 0x105fe0e37ca0fc37L,0x73835ac85b303c34L,0xe29d830e0057ac8cL }, + { 0x457d083e3b5f41bdL,0x228b26c357341890L,0x8e8f194c4109bf9dL, + 0xd032cf2b6e4a39e3L,0x012e9515d88f9292L,0xd1a4cd32e957e163L } }, + /* 23 << 42 */ + { { 0xec56b72f4ab23680L,0x7cb58e727f22217eL,0x6e98647bd045d18dL, + 0x2b7c9caa9a73b956L,0xc414eabef120122aL,0x45d9036bb6e1b134L }, + { 0xe963c88388abd93fL,0x257f3b619180cb9aL,0x915fee5cb6ca7abdL, + 0x2166402cdb7b1bb1L,0x636f85f6541614e4L,0x81f91a1849d9e527L } }, + /* 24 << 42 */ + { { 0x0430af7759b11c7aL,0xf71cc5b1d4f47acaL,0xe1a7905f12e9190fL, + 0x1c689b7012db9e14L,0x6bdd3dc90abaeeacL,0x97f1c244504f0319L }, + { 0x874afd61a7a54b51L,0xd4604ecbe3d979b8L,0x0d33eee1ebf4aab1L, + 0xa3631cac1aa49fe6L,0x0d8340fbf2217cfdL,0xf6373284423b7e77L } }, + /* 25 << 42 */ + { { 0xc6cdb5ba6f7972d7L,0x7ac7d438907d281eL,0x9160a8f5c01044ddL, + 0x3d74d7eac19ba8f9L,0xf7c7f93f112433e5L,0x2ab355a2012236d3L }, + { 0x1168ce913009447eL,0xbefde8dba26e3458L,0x6f9837db49ec8169L, + 0xb4d1e35c86782931L,0x41440a76d711e5f4L,0x8fc7a5aeacb5cd89L } }, + /* 26 << 42 */ + { { 0x73719fe8286e8aa5L,0xff8663419982a4a4L,0x684511702fb2db95L, + 0x4f1c0eab01d80ea1L,0x2bc50da5530af14eL,0x00d1d5b506071a95L }, + { 0xdb618990a6b374b1L,0x06ad90084e79ebe5L,0x281d01a424a63b70L, + 0x87dbd6d5348625fbL,0xdc90f0bef576b1a9L,0x1a9ef270987747a3L } }, + /* 27 << 42 */ + { { 0x135e416ed651b9b0L,0xe55f7f104a5e7979L,0xe55df2550f0729d2L, + 0x666f2744e33ada22L,0x4968bb982cbcb4a8L,0x7ad4e7811028dd81L }, + { 0x0e59f0dcd7ca8b60L,0xd71628cdd2a600b2L,0x7eaf6d308b0af99cL, + 0x6224b6452900105cL,0xe0513f4388650f12L,0x2a63822a6f6c5234L } }, + /* 28 << 42 */ + { { 0xf8c07373078a045eL,0x998b2d52a81724d2L,0x2b97faf1a6305a28L, + 0x5bc61f67f3e0f93dL,0x7238583cd7aeb8c1L,0x851ecc4b39f5f24bL }, + { 0x1cc8b4689992c20cL,0x73168a863c8553dbL,0x1b9a5f95ba2641adL, + 0x87a0c362ce9d565bL,0x07fb51b2e1eedc62L,0xdb300ac6a973903dL } }, + /* 29 << 42 */ + { { 0x789ca390f33e8516L,0x6a7f594cdee7f1caL,0xb4b6b9ca988005a6L, + 0x14f7b4806cad024bL,0x682a86285a576b68L,0xf188c74e40e1984dL }, + { 0x3584b5e6bf6f19c6L,0xa350b1d2b7467bf3L,0x3b3bb966aa3d1266L, + 0xebbd2c782804d8a3L,0x91a272d36a9caf4eL,0x553ada4158fa7041L } }, + /* 30 << 42 */ + { { 0xb564a0d9807e30a8L,0xaba07b1534a637ccL,0x010e76c5840d8e37L, + 0xb6dcb9ac95f6765eL,0x2f5f8fe103b3ec08L,0x10c5a24fb48363efL }, + { 0x5ddacb2709c4dc1eL,0x8e2884b1e03bafc5L,0x84d56df3cfc2d599L, + 0xc8e2da84ab78ec0dL,0xace4663f900084c6L,0x98d9a1df5d49f42eL } }, + /* 31 << 42 */ + { { 0xb10ca6eea690d9c8L,0x0b8b39efd5e0d490L,0x2685d320e63807d4L, + 0xca40d0ee83116ce2L,0xe1e1434fca51b48dL,0x178a91afeddde4a9L }, + { 0x64f59e3fd0dace59L,0x57b33c26278b1820L,0x2ca13b041550875aL, + 0xb21f675a4e0db4aaL,0x2bbb3edb0216d3c8L,0x7f39955b96ec8017L } }, + /* 32 << 42 */ + { { 0x78a53b5a9563e3bbL,0x19c75eb286af355cL,0x3520f427019a6f8eL, + 0xde6fcad6dc3ad0baL,0xfec96e4f79745b7cL,0x5e566bbdb133f2dcL }, + { 0x50088a2b26561be7L,0x16275b4cc5fddfc7L,0xf21332ff23ae4b9dL, + 0x8cbc659e85246712L,0x27fa9c8df50b515eL,0x25ecf745494ac8b7L } }, + /* 33 << 42 */ + { { 0x7cb130e0837ab43fL,0x8a1f00127b9f6c17L,0xbf827f6d17fa5e12L, + 0xc181b1264914a231L,0x8ce70fb6986288a8L,0x9832863fcd1c276eL }, + { 0x738e99819622ecd1L,0xdfc1b43cb73807abL,0x7254b4cf1b673290L, + 0x2d689f38fb20f902L,0x86460de83c34960eL,0x8453896aed8f62e0L } }, + /* 34 << 42 */ + { { 0x9f74efc606f4904cL,0xa280e4c26d3bc556L,0x974f9bdb75975ee2L, + 0x1bc0e7fb6dacde9fL,0x2a110d4c49649375L,0x045432c09090d834L }, + { 0x84295a20195083cbL,0x92ea17cac7dcf71bL,0x3acced0be70be8c7L, + 0x3703dfc007e28816L,0x37fbf2d1e869fb8eL,0x8c6b0bbef9c35ff8L } }, + /* 35 << 42 */ + { { 0x04a991812f1d2778L,0x0d78573685b91ae0L,0x8c32d6046a5252a0L, + 0x12b043131a0df85eL,0x40c4db631ee669b6L,0x0f499408f18f5f9cL }, + { 0x0dcdefabbfe9a187L,0xbd371c45ca650d7dL,0x33819eb00a36748bL, + 0x82d1af1f29034844L,0x301f906d96257b2fL,0x862728ea9395c666L } }, + /* 36 << 42 */ + { { 0x33a2194f40175152L,0x0f7ddc1dbb13f08bL,0x7c08860850b54274L, + 0x7ebb2c11e41f0795L,0xf915683fbe20d37fL,0xcbcc14889daacec5L }, + { 0xfb02c20fea459050L,0xe964d76ad5815aa3L,0x0e009be9496bbf2dL, + 0x8233690eb42d0f7fL,0x98ee83d49168eb0eL,0x34c3b6f3621fa292L } }, + /* 37 << 42 */ + { { 0x29555d79b0221994L,0x1dd689dd4c9e8f29L,0xcb83ed2c853f5261L, + 0x04b1475e0d9b0670L,0xa28b15e7df2ec34eL,0x094409b5e60a168eL }, + { 0xe4b9fd0e16ed42fdL,0x02f97e84a138f2f6L,0x91dc216ce13520dfL, + 0x59564eda7a245e5dL,0x825278be8478befaL,0x69daadd20328c4d1L } }, + /* 38 << 42 */ + { { 0x6ffade389995db43L,0x88974055790f4b92L,0x082e5add525d19e1L, + 0x002c414897bd9931L,0x3f093b3b5461cff7L,0xafc95b0042b8d3f2L }, + { 0x0a8f7687a993155dL,0x1edfdf616c2bb58aL,0xb5be2d4fc44049e4L, + 0x6fd505bb8dfdf4e7L,0x5386f02a41af5871L,0x8178817569121027L } }, + /* 39 << 42 */ + { { 0x1deada722706171eL,0x1baf4c9aee773c6cL,0x458efac06977d673L, + 0x1f2c2f38646e29b5L,0x36ece91a53323300L,0xab51a49bc4d598e8L }, + { 0x7802760ed8e41d8aL,0x2996f790587425a5L,0x227165b73ca21bedL, + 0x0d9e5c5283536ec3L,0x6232f2e089701806L,0xc55e80a2894e2577L } }, + /* 40 << 42 */ + { { 0x437b7224641e3bd1L,0x84e39f7980a58460L,0x68e5292709759523L, + 0x0176a3ace77f5904L,0xde92fb15e151e242L,0x79965c9aeb1438d4L }, + { 0x318a810a596700b9L,0xa8a6ec57c2198cbeL,0xd7709aaabf030fd2L, + 0xb432023472f5d326L,0xc9945214b03bce50L,0x0bc06d9bd4ecba09L } }, + /* 41 << 42 */ + { { 0x30630eefaadf21b4L,0x94896f68042fb57aL,0xe678fc3eb312e7daL, + 0x325cd2bc5c94c991L,0xd4eece20bea4e518L,0x9d9d65e925eab2abL }, + { 0x5439c348676454e8L,0x9eb68953be1e48ccL,0xbeea9da27b625a31L, + 0xbd82c6ee48cc200eL,0xba9fc94444b9dc77L,0xb31bdebe1eb9283aL } }, + /* 42 << 42 */ + { { 0x1ac1a09d07abf58bL,0x7372e532b5770f9dL,0xe1716687c12fe180L, + 0xd91f4d36c715009eL,0x5d8885cfd6fe1cd3L,0xc0ab5a13aea65e52L }, + { 0xa5fe05a0838e5e05L,0x590cc325971fb33fL,0x3bd8234a4653bf57L, + 0xb83300373708c1aaL,0x27453d3b0e84e8fdL,0x9dd3f05399cf918fL } }, + /* 43 << 42 */ + { { 0xaf6f26c3a36468a3L,0xcab875f28d9fc8deL,0x0209b1ad52f4479dL, + 0xc9941cb5459542cdL,0x91603260a0212b68L,0x98018317345673edL }, + { 0x2b02a35ef98b810fL,0x15953f78b714fb32L,0xf9f9c61eb71a4b4aL, + 0x959b1473a8505b7aL,0x331d32cb4c6ec97cL,0xb1d2dd44e49f189aL } }, + /* 44 << 42 */ + { { 0xdfb0508345c0a2acL,0xd13790035eacfb2fL,0xe9872d766a2e126cL, + 0xd2a89cbd39a02d27L,0xf45baf72d754b7c2L,0x37985ef8c6c61bafL }, + { 0xbbcd3ef2da1c46b1L,0x5af5dda43a355d83L,0x9f7ce4281d67a984L, + 0xf19526926fa33654L,0x2abccb55567b3b71L,0x1b3704f3300cf29fL } }, + /* 45 << 42 */ + { { 0x9dcfaf21712af69cL,0x26de8fb05291cd70L,0xc778294742072171L, + 0x889b9fbc8c617e24L,0x5971e60cc2926862L,0xdd8e70bddc022533L }, + { 0xc783e1e30a369db0L,0x37f562ab07b2bb92L,0x5043f3d40c060f44L, + 0xa9650f47a3e17ac4L,0x3b8cd7ad18010ceaL,0xeed5de39969849e7L } }, + /* 46 << 42 */ + { { 0xf93c3ccb6044ade6L,0xd14a13f8fd376746L,0x1fc20e6fd718a98eL, + 0x9f63c6673e31573eL,0xe99b7693a8e0c66cL,0xdad4615c1e5b5f5dL }, + { 0xcbdb7200ac98f5a3L,0x31414469668ab045L,0x82e92df9bacf0ac7L, + 0xa61f4e8371bfdf94L,0xce8cb699d1bc5deeL,0x42da8ac72f2f837cL } }, + /* 47 << 42 */ + { { 0x0b6252fc32a4e8a0L,0xac1e457dd7170402L,0x76faaffeb121e40fL, + 0xd2dc3cb84ddebd9aL,0x303e47cf362348a1L,0xe37e824a829d9806L }, + { 0x419cc2cc7c2ec135L,0x3eab37024cecfdceL,0xf0c9f19088403d18L, + 0x73c8984daf61b6a3L,0xa2d44d9e00c232a1L,0x61fdf4883cf1cecdL } }, + /* 48 << 42 */ + { { 0xa1972c2196fffb94L,0xbe04093099d7633bL,0xb116ff407e23d66eL, + 0xcb12b2bb949a19f1L,0x75df10ee79e49e91L,0xa3bf90764890bcf4L }, + { 0xcbaa76a609a30252L,0x17c224a90ee5728eL,0xcbc56e5cf4f3f4cbL, + 0x8a07110f4fe868a5L,0x23289f2125e110a2L,0x0289c12bd7693c45L } }, + /* 49 << 42 */ + { { 0x4a9c6f8bea96a0f4L,0x78262a3499e3aaa3L,0x513a8e2028b2634bL, + 0x5ba40287d85d74b0L,0x5702d11d440fcbbfL,0x1933c88a0df91fbdL }, + { 0x642247909a0aff2aL,0x85dc2ca13734398cL,0x1009884fd7aa787aL, + 0xc666a62a0e73f4f5L,0x491bb941cce66210L,0xda8e896bcd173443L } }, + /* 50 << 42 */ + { { 0xdc9b37a7c6e32022L,0x158cd4bb342a148aL,0xd62d371cf06287a0L, + 0xba027eb6e9fe0a01L,0x8e7c6f5372017d09L,0x13c5d6ce9381d9c7L }, + { 0xbd0bc2d46e32f045L,0x52cf0f2554ab7f2aL,0x2e674e50085643f2L, + 0x77bc15aef1662819L,0x57f9e3c4f2ebe66eL,0x839aaebadd284956L } }, + /* 51 << 42 */ + { { 0x752bc171ed9d735cL,0x76d96d3419ad5c26L,0x9549ad3e25c1d83aL, + 0x8f6fed53cd460d20L,0x04504f7c7b619b69L,0x68265559c566f393L }, + { 0x5e39e108804598edL,0xace859b01f4538edL,0x4b8503070c85e5daL, + 0x9f087821abcd4ecaL,0x126d3850c8d0def4L,0x66971fe5263457b2L } }, + /* 52 << 42 */ + { { 0xa82ac9983a4bc15bL,0x28697435c930e4f1L,0x191ebdb6b0c9cef3L, + 0xff05f8e875748872L,0x5b86940237343b20L,0xa7bce94beedfe44fL }, + { 0xfc271e2778f4e1fdL,0x652c5a187734db66L,0x108f61c87efc9a9cL, + 0x01db328970ed1dc1L,0x2bc509afd249f61cL,0x0d2e6b4cfeed393dL } }, + /* 53 << 42 */ + { { 0x691199d77a477295L,0x1f0679a661746b75L,0xf3a51493c9f936d7L, + 0x1fcb336a445af5f6L,0x9880cdebb94ce08fL,0x784fa04a22a6b57aL }, + { 0xc85fe18caa97c3bbL,0x27294a3baabe9b50L,0x9418a5b7b673c915L, + 0x686cd97a15dceed5L,0x6d1c9dc70f22ae6aL,0xed88e02dc02212d3L } }, + /* 54 << 42 */ + { { 0xa62c358dcf616234L,0x85402ffad40aae7cL,0x315ce9f151a7614aL, + 0x6f7e796f5d0c7d7dL,0x73bf57faf3444d22L,0xb5e71e7a224b77c0L }, + { 0x94c40681541ee741L,0x40c97253d6837e1bL,0x1058fe7bb1f1c742L, + 0x3206256f9b24d65cL,0x0abb12a78169ba8dL,0x01fcdb7beae85db9L } }, + /* 55 << 42 */ + { { 0x868f294309fdbd8aL,0xd9c11e7ebdd6c274L,0x3be4d8e7fdcb4fb7L, + 0xcd8c40ad17305d10L,0xf12c97642abde5eaL,0xc9e16d8256776e80L }, + { 0x279c0248df05235cL,0x4bdd8b136d8e4b89L,0xab8bbe8d7c47d2c5L, + 0x12ba8b9e255c665cL,0xd585ce64d140a518L,0x55947e69eb4d353dL } }, + /* 56 << 42 */ + { { 0x06ba6db1f184c91fL,0x3c0a348a45fd0382L,0x0d535b6e4434b527L, + 0x7bbfa2c8692bae0bL,0x5c59a08ebe7fe51cL,0xbaa7d2be36e80cb8L }, + { 0x8a42d8d1bed3cae8L,0xd9e0bc0d15ff4962L,0xe51fce93644c75ffL, + 0x40222561b9392d63L,0x8ab1d286023b4787L,0xfa85c220a1b3190dL } }, + /* 57 << 42 */ + { { 0x294845c28ed1d81eL,0xc0402af2dbe7fdbaL,0xbb56d86d67abe6a1L, + 0x2e61f65b2ed330e4L,0x2893eaebffdf0fd1L,0x06cff97a75fb77dcL }, + { 0x2911ebac1c90fe64L,0xd9c40d77e5ee3458L,0xf5b8b1d4b355f191L, + 0x5be71a4ef365bc6bL,0xe2db432f5277b244L,0x3272a28327235b87L } }, + /* 58 << 42 */ + { { 0xe5105755e6b16cbfL,0xba9fb47b536a49f0L,0x03ac0c10c75ad751L, + 0x9090bc328a2d65a0L,0xcecc7202852b3d23L,0xd214f70128f67958L }, + { 0x379899b1f3695cabL,0x8f3d02e9bd3342c2L,0x9870a7f9e24e7bc1L, + 0x7277e115f723893eL,0x6932ceef0f6f1936L,0xd0bf06dde171306dL } }, + /* 59 << 42 */ + { { 0x815cabeb17832ce7L,0x65afc856a2a4864cL,0x9fe4ae1aa4939a4dL, + 0x7005cbd90729a3c0L,0x887f0cca791e8ad6L,0x55cad97a85aca45aL }, + { 0x3e89d294493c7dcfL,0xf4ae5277ae8ed154L,0x507a3fd0a08fbcdbL, + 0x4df3c552f86677fdL,0x6529f9ace3a82131L,0x09efe1fba53a7c67L } }, + /* 60 << 42 */ + { { 0xbbcfa42d21fe8f67L,0x82983012de2be980L,0x88bb9704aa8e17a0L, + 0x100ad5e784772203L,0x2867168965479d29L,0x0334f9c5c2d9d5d3L }, + { 0x49032c1a83a6cf83L,0xc257b0901dad479aL,0xf64177dea7e3636cL, + 0xb2b5747874a315abL,0x210b11cda170ccbcL,0x80509b7480d80177L } }, + /* 61 << 42 */ + { { 0xe98ad30696993a74L,0xa7dc8330f0484940L,0xc30319fdd61b83d0L, + 0x76e2755809873771L,0x33f4f43ecaedda98L,0x68d5ffe3639c8d3eL }, + { 0xe3cf3b850059b2d9L,0x7f3ecb2f6a3d057eL,0xb569c24b9b8b7466L, + 0xeed92f2ac38ccd58L,0xc16a4e8ce765a2f7L,0xa3a7b6552de9cb38L } }, + /* 62 << 42 */ + { { 0x496de6fa0640df83L,0xa4e500a36c77c97dL,0x45609036947aed3cL, + 0x0edb9422423fc5d8L,0xd0c01b2e68f70746L,0xae44ae0e6d77f3a3L }, + { 0x7cc7e90635adba9cL,0x107a3b46a8413303L,0x9e3eeab98916817eL, + 0x1a99dab86fb74601L,0xb4e8466c1064b039L,0x249149146fcbadeeL } }, + /* 63 << 42 */ + { { 0x89643fa624798452L,0x179b3bd76ee52833L,0x343096e54430c6b3L, + 0x589dba3323461536L,0x59073225c3433575L,0x540f9ce317d80d42L }, + { 0xcd04b14d3aea6c82L,0x9be179b0efc9f455L,0x0ad6fb0791e57cbaL, + 0x33894fa262706b10L,0x2cbc270886bf6926L,0x2cf067e64ea48c6bL } }, + /* 64 << 42 */ + { { 0x298647532b0c535bL,0x90dd695370506296L,0x038cd6b4216ab9acL, + 0x3df9b7b7be12d76aL,0x13f4d9785f347bdbL,0x222c5c9c13e94489L }, + { 0x5f8e796f2680dc64L,0x120e7cb758352417L,0x254b5d8ad10740b8L, + 0xc38b8efb5337dee6L,0xf688c2e194f02247L,0x7b5c75f36c25bc4cL } }, + /* 0 << 49 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 49 */ + { { 0x36c9dbbefda8520eL,0x573507ce6ae3ea98L,0x1ab38db696a8f9f1L, + 0xe031d2356b01e6bcL,0x10466ae68afc4adaL,0x3b35df41ed9c44e4L }, + { 0x61272c12c7bd99e8L,0x6a4ae7b4805afd79L,0xf4c47a910ecc49ebL, + 0xeb95dfeccbe84d5cL,0x43f3b71c8ee497d7L,0x2547af524c6fece4L } }, + /* 2 << 49 */ + { { 0xe323ed0cced45039L,0x04ce0b67a90aa713L,0x9c092f06e8d68e4eL, + 0xd8f5555ad0742e5dL,0xe2d175bf00d3df92L,0x8ca55f154f71aeabL }, + { 0xd1762d72642d391dL,0x0dfdd3c2aec466bdL,0x2caacb4c6281f2a7L, + 0x635ba4703603e53aL,0x94a9811d49fecf29L,0x3a42cf09466bf361L } }, + /* 3 << 49 */ + { { 0xe63fbb10b5356889L,0x5995a0a92e73aba2L,0x5cea30677afd4bf7L, + 0x4494e39dfd37120dL,0x8c572c7249d718a7L,0xfe159c275fa305fbL }, + { 0x751c217fc276c40fL,0x44d0643c45e40857L,0x9a996e6efe7a6486L, + 0x1a4f6d10f53b0e47L,0x651390ecd15fd593L,0xe0c1181d739ee9eeL } }, + /* 4 << 49 */ + { { 0x0f05710b11bccf2fL,0x7113085a7aec1bc6L,0x137da67a46b8d0e2L, + 0x454b89fc698b78ccL,0xf2a6e1de258a9393L,0x5f1804e716488e69L }, + { 0x7c6c550215b3bf35L,0x3b0e09a5b05c2ec1L,0x4b9de30e92f15247L, + 0x09d4ca9327e70a0aL,0x9c8b16340d149363L,0x54a8287cce642137L } }, + /* 5 << 49 */ + { { 0x3a05e7d5ca2af43fL,0x068953f975009801L,0xd6c8a76c06740141L, + 0x7e1df1038a831fa9L,0xfe06e2bae39046f3L,0xda5264a0e1807c29L }, + { 0x1be4ffedff5d4808L,0x299d6537c52be83cL,0x1b38adba11834a9cL, + 0x6074a60b1248fd42L,0xd9a0bd2e041b5430L,0xf222ba84a7b76b03L } }, + /* 6 << 49 */ + { { 0x49ecd6f3346a764eL,0xe46847f14105e657L,0xce9cb2b57550f608L, + 0x45f1a1f7f4cf062eL,0xcdb19a112c27d38aL,0x36d375b284e50b19L }, + { 0xf43691540dba6405L,0x4c9dc863040354dcL,0x7229e70ea24d09cfL, + 0xe72aa86c7cf6831bL,0x487fb68425392838L,0xe88bed04430b9b47L } }, + /* 7 << 49 */ + { { 0x9f77b8c5d1164788L,0x45bcd4c1d7b5c5dcL,0xed22ecf3d88c2357L, + 0x330272ad07de1cf8L,0xd9749f7f4ca13a48L,0x4964ce5d1383ce08L }, + { 0xc033d516b0d0dbb3L,0x056ae73bf51943c3L,0x495cf7e057105e88L, + 0x08ced52e56462560L,0xe9578aa713ca1a7dL,0xe9b045c5a9717f7eL } }, + /* 8 << 49 */ + { { 0xf8a8499b666fa8a8L,0xd0f9401571bba84aL,0xb85e1b1d515e1328L, + 0x88a2636ba941e788L,0xa045241d2b5dd8d8L,0x161be476332f0350L }, + { 0x96c4b205a18fac6bL,0x5cbe8d5e73fc5337L,0x6fc33fc6d00b6029L, + 0x07a914ee89aa3b79L,0x35353eb7a4d4dd00L,0xc026bdc0673e8956L } }, + /* 9 << 49 */ + { { 0x1e551f9bce0b6f8cL,0x1fe7ea4618495e1dL,0x3f6f28742dc0e878L, + 0xb778c12844c43f20L,0xbddc28eb8a250230L,0xd8571a4aac6c3d17L }, + { 0xb9dcaec9730c8a1eL,0x512cee9993fbcf87L,0x0df3a1379bafe001L, + 0x8530e501e2a2b9bbL,0x6d38ba8995ebf91fL,0x704b81a7792cef7aL } }, + /* 10 << 49 */ + { { 0xccda372167103852L,0xf78d22470c54de53L,0xebd16036afa44aa5L, + 0x7b88024864a24ab9L,0x86b38e961c2bc78eL,0xd0aa0d058d63b295L }, + { 0x24912955c62fcbf1L,0x77a68156b9ac435cL,0x432401c71b360b26L, + 0x091f19f34c58ef8cL,0x3a4a61f483d46c9dL,0xad0e5c72e8d616cdL } }, + /* 11 << 49 */ + { { 0x668d598ad1666826L,0x6ffed334fba0ba63L,0xe71e3359d7cddc30L, + 0xa9c15c2d9fb9998eL,0x6966d350612230b9L,0xbca3ed23ae4fe0edL }, + { 0x537cac1b3caa3edfL,0x4f4a737ef33c180cL,0xf8d8f796f8807a7bL, + 0x5c7cf072d1aab3e2L,0x7f0ccb9dfff736e4L,0x71bf0732ef11266aL } }, + /* 12 << 49 */ + { { 0x33b029bccdaa6831L,0x2548552d4c1f9cedL,0x35f1a002dece1c8cL, + 0xc6b87fd7acc23aa5L,0x0b8bb275bab029a4L,0xf07bc06730bfb42dL }, + { 0x1688ff5d1f69ce9dL,0xeedb7b5edb10585eL,0xb7a88cf0d432c197L, + 0x20731bdd015a350aL,0x5fa1835463223f5cL,0xe392e1318024693fL } }, + /* 13 << 49 */ + { { 0x61ada737c3449cb3L,0x071062504ca876ffL,0xcd98a39001d1403eL, + 0x197c845096ded881L,0xd060160568cacebbL,0x7e1b37d1dc3ddff4L }, + { 0xfdc1bcb5d1725e92L,0x11cbe941bf0856d2L,0x63fd35d050199657L, + 0x208a1047b9790d10L,0x52790ce61af4301dL,0x75e6d83beff28b69L } }, + /* 14 << 49 */ + { { 0xdfaeea0a0154731eL,0x9e53419de15a0388L,0x2ad6a83c25a992c8L, + 0xa2ba020fe125501aL,0x894ebaf8d4dd04dcL,0xd48cb95850765559L }, + { 0xf9b58d0980dec92bL,0x2a0e11659da299d7L,0x3c081853efe9cb11L, + 0xb9f3b702a511c5e0L,0xa8f7a25f70486180L,0xc0358b25591b3e2fL } }, + /* 15 << 49 */ + { { 0x00333fa6fa806947L,0x7e4dcfb3504b3e19L,0x8326b0acad4a5dfdL, + 0x9ffc65eac7b12e49L,0xed3b7c0258d16eeeL,0x79fccfb434a4222eL }, + { 0x4a8070a0e556357fL,0x554fe2c9ec97769eL,0xcc405a57da691714L, + 0x12927897856f590eL,0xd4805b93ba198dcbL,0x2649be2e4b18444bL } }, + /* 16 << 49 */ + { { 0xf36e8398eaddf274L,0xe41553a16a5e4ddbL,0x36ab07464efc5b0cL, + 0xb211e59ad316c434L,0x2515ec9f16ccf839L,0x6ecb746503dc6a07L }, + { 0x842b7275c65c1b07L,0xf7ceeec535750ab6L,0x967d711ccef5255dL, + 0xcd3bfb075108cb92L,0xe50c0d8aec1b9740L,0x9e8d56611a9e6308L } }, + /* 17 << 49 */ + { { 0xfcb12ba3aae18c46L,0xb55e959c6e21d463L,0xf720d19f4a4f6f21L, + 0x1c2ff60ed4320c5fL,0x4ce5e1ac1a1b40b8L,0xfdebfb81ff6fb9a0L }, + { 0xd6c37d8a9c67c07eL,0x55167952012fc09fL,0x5dc722b52c306c4dL, + 0x1efad8d2bc1f65e1L,0xa1478f3da52556ecL,0x54cbfb884a795dd5L } }, + /* 18 << 49 */ + { { 0x84f8ea13ccb8a36aL,0x5f7aeeffa05709a2L,0x4942d04e60574f37L, + 0x855b13e9e048b400L,0x747e4067a6b59c09L,0xc349fb05074d3990L }, + { 0x398e6afaec2c7e03L,0xce361865ec2d5a4cL,0xfc04bf8eb6f57d22L, + 0xf0e0b84c759ce6c6L,0xb65141235ee7e528L,0x8ca144bdf5c0f9b9L } }, + /* 19 << 49 */ + { { 0x5868449bc6e0124eL,0xdd65ffc1e68ad5eaL,0xe126665f4f577466L, + 0x8ade5cee2defe8deL,0x7c1cf7f07beddf87L,0x0e0e066a362c5956L }, + { 0xac2aff4e15563b47L,0xa28ab875620d1299L,0x91f67b3fd8caa497L, + 0x91bef53394fc08a3L,0x0fa27d9cd99918f5L,0x205b6c1f60b67bd9L } }, + /* 20 << 49 */ + { { 0xc1370daef6a58536L,0x6f2e5b37c56b0ae9L,0x5511d68292f6b6a3L, + 0x2e9e5034ae575249L,0x3e5a32f81d14bed7L,0xa346a86f75efd17aL }, + { 0x4f2510a60309fd7aL,0x689ecd74d0b1425eL,0x9e9bebe19f771e24L, + 0x20188045adc5b48cL,0xe49811b6b845230bL,0x420855ec5a8687f8L } }, + /* 21 << 49 */ + { { 0x705a9ab30aa1a423L,0xcb01466fb49830c4L,0x1db1768581a75897L, + 0xcaacb855e341f157L,0x9b13cd497a0d3c38L,0x119b4d47e177fcb3L }, + { 0x0d8f7c2639788712L,0xbda0f3180642bd4aL,0xdd4bd88bd4616239L, + 0x9a3ecf978df1b895L,0xd0d54caf4a6dc07fL,0xa7ed6bfb31810203L } }, + /* 22 << 49 */ + { { 0xe650e49abae1b94dL,0xb6b162e6e3199794L,0xdc706859b4ec0480L, + 0x28b618c24b1a06caL,0x0929a001403acdc2L,0x796dfd972da3aefdL }, + { 0x16389072ef4c1673L,0x600d8bd7fc94a4f5L,0xf003214de5f386a9L, + 0xa7af0499e62cbb48L,0x750a3b00de82bad5L,0x6c615b838e7dc8eeL } }, + /* 23 << 49 */ + { { 0xe1916cb4eae432e5L,0x81f3e48acc193889L,0x54d58685ba922a4fL, + 0xeffcc528bf11b76bL,0x2f70d38f8171c971L,0x547ce8ccb3a5669aL }, + { 0x3acd91b878e6d0beL,0x372dbf2c689c2913L,0x9fceb5bbd0aae543L, + 0xc601f9622830a977L,0xd55e74509f874dffL,0x77ff8ab4822878caL } }, + /* 24 << 49 */ + { { 0x283eec26d71543a6L,0x98fa08bea7627841L,0x269a83b827ad302dL, + 0x225f2f12bde3fdd0L,0x046fcf380130b3a6L,0xea733c1ac3ed9043L }, + { 0xf870f14d70aa08d1L,0x643d18b834391e0bL,0xf3e1d5f4847be772L, + 0xa9498223d0ed73a0L,0x6933ccf014b3babbL,0xc2439ae437f08f70L } }, + /* 25 << 49 */ + { { 0x503414d0f2cb5475L,0x51b9497cb24cbf9eL,0x57359dee2f4c7746L, + 0xee7125c3f3118a94L,0x2f0db706e4ea33d6L,0x885e8c3eddff7f63L }, + { 0x752f594b628432f0L,0xcfadea7779852e2bL,0x4f733b8ba2ba4b7fL, + 0x163c8c2e530f763eL,0xf95a7b57ff05a7e9L,0xd4768d242d7be01fL } }, + /* 26 << 49 */ + { { 0xb643f4e0f88d049bL,0x5e0ac1fb12682fcfL,0xeaf7874d9f981c8fL, + 0x9c2adfd2b1af779dL,0x9a7abeaddaa8c275L,0x09ad552124cacec4L }, + { 0x069cd5c40ead1646L,0x5186bf190a6157d1L,0xcc222a9396503506L, + 0xfeaa7bdebd29686eL,0xb0d65b0da7257c8dL,0xc31c0a8898aa227fL } }, + /* 27 << 49 */ + { { 0x5495f21c9fe88a48L,0x01f580ac590c1966L,0x1ad433ba39810166L, + 0xecbc67003a5187f6L,0x38d36c3bd4216887L,0x49653585e27b615cL }, + { 0x2a70a1d9e773db7eL,0xe36d967a63c1c048L,0x51cba60d26d15862L, + 0xb633839fd5a6b746L,0xa6a756a2ec1fc364L,0x37fef8d24cfccb6fL } }, + /* 28 << 49 */ + { { 0xb4b7651f5be1d45bL,0x0425200a7f0cf680L,0x200d12b48960be95L, + 0x02fdd1a14945b193L,0xedd70e3e27d046d8L,0xc1cc086a83f14e12L }, + { 0x1580e72b2629396eL,0xc87439dbf9ed73c1L,0x5debdf30a90c5128L, + 0x0b6c020e9fbe14efL,0x168da56a0149a0b0L,0xc66a4dbd79c58ac6L } }, + /* 29 << 49 */ + { { 0x6ecd9c41596b8890L,0xd25172fe210d9613L,0x1ce8abf872b97aa5L, + 0x355899d610faa675L,0x003b69adf4ddf011L,0x6736cd40ec2d1af9L }, + { 0x8069a0ad4f85ac72L,0x5c31d68b5836cfd3L,0x8e9486eaa5ec1473L, + 0x8e175c4a1468cebdL,0x58b3d2b1ffaf2f77L,0x4fd21681a17a3e00L } }, + /* 30 << 49 */ + { { 0x800aec84330b8e2eL,0x1a2c033e335837bfL,0xf1a91551fe6f6dd9L, + 0x326c42b21de7360aL,0x300e740b7b66f9d5L,0x53bcc70068ce95d4L }, + { 0xc9e225ac3d80f228L,0x64b2ad4e6977dfdbL,0xac863b0801f23221L, + 0x0517a648df11e5f7L,0xbf7aedcb68d11050L,0x2607e33777b3029cL } }, + /* 31 << 49 */ + { { 0xcb1955e44f4706b2L,0x0821d4663acaed1fL,0xbe822db07f8b43deL, + 0x3d11573f9b1c83a1L,0x6c052118201eab83L,0x294c5060dfe340d7L }, + { 0x994a4bde0644005bL,0xf1519f3258fa0552L,0x9077bf5bd4d0d39bL, + 0xebde1ff0e6204ea0L,0x58a68e09829130a7L,0xda64eb8596961bb6L } }, + /* 32 << 49 */ + { { 0x1afa6aa6206add5dL,0x66cfbbae150ea4c9L,0x07fb920b5d36da4fL, + 0x144d51f9291e774fL,0x26c2c134f40d87a8L,0xc8cf3524a932f1a0L }, + { 0x35bb2a425aeb0bdeL,0x5cfcc1dac4be960aL,0x5c40cabfaa1838edL, + 0xea0c05ffe2855f1fL,0x931ebb02fd525934L,0x31a7b78f16246fd4L } }, + /* 33 << 49 */ + { { 0xbe055fead42b36aeL,0x733a05ed819ddf8eL,0xa00fa0a15c9a6102L, + 0x0ed363273c0af634L,0x5b5a62b4d5970a32L,0x9d7557dfca954cd8L }, + { 0x30314f0c6daf871bL,0xaa7c42a96267b2abL,0xc5d1f0d6132bc62dL, + 0x77ac94df7ed26084L,0x0d256fdada34e1f6L,0xf0259d1caa4b4dd6L } }, + /* 34 << 49 */ + { { 0xf576c69e86ccb00bL,0xc870c07f5781803eL,0x91d4c0c6b1869e56L, + 0x9c2729397d940416L,0xdad33f73c4d0269bL,0xe2baf5b8838c9198L }, + { 0xd8bb9613218414e4L,0x5e9f7b67c980ca07L,0x1e2d4e63165079fbL, + 0x6ae5b17f983b3fadL,0x1e66b8380c24e22dL,0x80cdaec2136e0be8L } }, + /* 35 << 49 */ + { { 0x98cb12d93fc277f4L,0x81def3ee160b8743L,0xa1f07ebb11711fb6L, + 0xba17dd15a95b3ba0L,0xb25f1c78bc158f33L,0x1bb83cf27841e8bcL }, + { 0x57ad928abf49233cL,0xc94fd746bdad3f2aL,0xf7c716ae4a4c6600L, + 0xdd0e3117060a78b4L,0x85e8851a860764b0L,0x3342d974bce0d787L } }, + /* 36 << 49 */ + { { 0x2bc4e37a719793feL,0x1543af2aa68ceea3L,0xc99cb391aabdea45L, + 0xc890e546f0b8eea7L,0x8b75b91feb4173d7L,0x9d52d04bef46f637L }, + { 0x0929f25d878ff734L,0x7377235fb6c43342L,0x657835cf6eca900cL, + 0x7b752665098bb5e2L,0x320d09b6b8a61442L,0xec4f8182cf5b8023L } }, + /* 37 << 49 */ + { { 0xfc5f8feffc788160L,0x7d552625f73f48a3L,0x4eea435145c02498L, + 0xb5f5de5bf8f8af26L,0x78f1c499067b1610L,0x6e0d1b14eac18a29L }, + { 0xf8be2f6c052af916L,0xd8cee5668876af81L,0x99a27ec31577bd90L, + 0x3ac529d242919f4fL,0x1215428c7fc05dd4L,0x99ef01e450f67e87L } }, + /* 38 << 49 */ + { { 0x145902629d671094L,0x7fef49c166ce858bL,0x2a7ea540c2f21eadL, + 0x1226b04fc1d5a636L,0x4fb54e4e535efb9bL,0x6c51cdb91d72bed3L }, + { 0x94162e44938efaf6L,0x166013cfaf6f5697L,0xfa9495bddf95f9c6L, + 0xc05441cb0d7f8406L,0x7e5c89763a233ca6L,0xbc75dc6493fe8e42L } }, + /* 39 << 49 */ + { { 0xe1885cf128ed669eL,0x6e9f40dfb428b3cdL,0x412388a61626f8d0L, + 0xb8201f047cbcd192L,0x642ecfad70ba644bL,0xd43be1cb43c76bb7L }, + { 0xafafffc388f4bd51L,0x8c40e2787052eea6L,0xc1a84e866a4c8776L, + 0xf0201f292fe7075dL,0x132f80e4576af421L,0xe0831b7f4731dddbL } }, + /* 40 << 49 */ + { { 0xecfabd2742dbb68aL,0xad43a2c43eb546d1L,0xcf4e64ccfe2691c9L, + 0xe3889e258347566aL,0x48da354885b8c733L,0xcb7fe0679d9c9f57L }, + { 0x8c26a8d668223280L,0xc1e8ff623065705aL,0x181ca70a3f8db9f8L, + 0x25aa6450e758213eL,0xa4898f9169b2653eL,0x5e5c9fb4ccd8303aL } }, + /* 41 << 49 */ + { { 0x640b6946b03aa213L,0x6b99e84d00c068f7L,0xed4f1d2d99c5c461L, + 0xcec88724b20eaffaL,0xdf2b79a95dbbc32cL,0x2f7397054f3a1c5bL }, + { 0x1594a54946eb52edL,0x55f11aad39c4c43eL,0x0fcdb331f46500f2L, + 0x0d66be885ceb8dbfL,0x4d977349886dbbf1L,0x238f4617797d1b41L } }, + /* 42 << 49 */ + { { 0xfc8c7320721034d4L,0x48b389db60264280L,0xac246988649cbd88L, + 0xb7f52891a50bb658L,0xc0a812e50a7f279dL,0x6593175967fb2cffL }, + { 0xd31a77c6661ab439L,0xabadcea00ceb4aceL,0x201d98f6a3702dddL, + 0xcec1e83e7c9463aeL,0xc64e44fbc55e6856L,0x421f3e3148aa0d81L } }, + /* 43 << 49 */ + { { 0x4f0b251871a07c6dL,0xbfe652edaf3a2fbdL,0x5f68dc667bc2053fL, + 0x445df84f6040a7cdL,0xbdda2132180dc0a9L,0xd8627401d6c7a92fL }, + { 0xba350cb190cd2c73L,0xaf4c1e5929886ab4L,0xee8fdff2d677399cL, + 0x3ce35c6edaecf83fL,0x44df0a300f114062L,0x1b633b4647f29868L } }, + /* 44 << 49 */ + { { 0x48483f6af58ae2c1L,0x70ba34635e1cce49L,0x5f7a1c6d33907532L, + 0xa0fab701875a5f3fL,0xf2e8b0ff85d387e1L,0x0076aa68ff349689L }, + { 0x6e392b02747e2fffL,0x5e1ea320e788d577L,0xba705bd7713a0b03L, + 0x04ef192f2dc2cbc5L,0xa5a14eed38aef8a2L,0xf9682bbe30a268faL } }, + /* 45 << 49 */ + { { 0xc04f2cf540244a00L,0x00c90c3bb8dc0ad2L,0xac5b1060601d76f6L, + 0xad97c5c1a7ff84ecL,0x7919a06dd2328101L,0x62d5b7a4ca8a69c5L }, + { 0x75607148de5a2cc9L,0x1afff7f79a75fd24L,0xe62efc8083a22367L, + 0xad08258a10e05e36L,0x22666e06c0e4b549L,0x15f62c613f4c48c2L } }, + /* 46 << 49 */ + { { 0x751affadc7b8da09L,0xc052109dbd8e45d5L,0x7d11aaad87c14560L, + 0xa0410b2a6b690121L,0xcabad9853e10a103L,0x4d19bd3e785f1bfeL }, + { 0x8f32c6b84b6167a4L,0xb21d4ec297b4f546L,0x2e26df99c008f7c7L, + 0x63825597eb347720L,0x6a05b375afe39fc8L,0x19790b92131201a3L } }, + /* 47 << 49 */ + { { 0x149347ff7780729eL,0x076b4edc62e2dd48L,0xbf0de9d7cdcec866L, + 0x9d75deab8fa1e18cL,0x10931716eecb1f4fL,0xa8765dd3a385eb7fL }, + { 0xfd26f39c4d70651cL,0xc501caf48834c723L,0x1d263a83a65e5093L, + 0x57ee2fb96f709deaL,0xdae3dcc645091321L,0xba0665a906a60a48L } }, + /* 48 << 49 */ + { { 0x517d13b1784d0621L,0x2db4ef27d77b84beL,0x6e2e26866d752aaaL, + 0x95da9fa1cab02667L,0xbe8d91ad423163c3L,0x8f3d59dba69953c9L }, + { 0xf728b1d2d6e635aeL,0x5c4c177deeea663eL,0x97a900a82e75d9c2L, + 0x136c6b1e3ad09defL,0x4bab14a6dd8a2be8L,0xa4ee903025cf1447L } }, + /* 49 << 49 */ + { { 0x05f93697a5235c12L,0x434f91026943a0d0L,0x92696b701a4d3169L, + 0x0a9da44b8c3b1ee5L,0x327f9f79d295521bL,0xf605cb83afd8aa40L }, + { 0xe3bd4ab5d365fb37L,0x6c6a470ce984ea2dL,0x7ad01e6b392af60dL, + 0xbef2dffd5ff8ee6bL,0x4e56deb722efc2ebL,0x1b90570ae14ff270L } }, + /* 50 << 49 */ + { { 0x70718d8e333cd9e2L,0x858c880c6b03a371L,0x5b7f69a5926a3dd4L, + 0xedbed135572f420fL,0x740a21e6332aaa09L,0x665aff63fecf1e3dL }, + { 0xd884a3c1214490e9L,0xed70c29a63cdab1fL,0xc92dfa58786e274bL, + 0xa5395591d7fd529dL,0xacdf81ac3b95b61fL,0x07f801df40cb45a0L } }, + /* 51 << 49 */ + { { 0x4f863ad59230d44fL,0xd176d2764a099825L,0x4a6868745a43a7d8L, + 0xbcab3548fff3e8dfL,0x15028cfccab2c7e6L,0xad077a8874a91fb2L }, + { 0x015700d39eee3e32L,0x524ef9c7386e489aL,0x3be1771b60285f8bL, + 0xe4a5353cf9c33beeL,0x0aa0f2ab244ad683L,0x04e846f98a4c0ed6L } }, + /* 52 << 49 */ + { { 0x326a204790f55f13L,0x194d24db53017b29L,0xa26db785cd4368c3L, + 0xd58943e8238d7518L,0x8e06f8cc3527387eL,0xebc6dc9e071846d4L }, + { 0xbfc08dccc541e098L,0x3dcf0713e4fbc9a4L,0x44e9ba7869fedb43L, + 0xd867cf784fa012a0L,0xc618b2b88733ddf2L,0x4149fd48a737fd5cL } }, + /* 53 << 49 */ + { { 0x5c4c2183179b1928L,0xc54d315d0439876cL,0x07d22792f7495bceL, + 0xd378185e3bc32c4aL,0x8539aab65b31c5c9L,0xc72b1ac640dffb35L }, + { 0x46bb918a2e8d6ae2L,0x102c49f9e8a1d7a1L,0x7c622793cd2764d3L, + 0x5bbc6f023c7aafcaL,0xa41f383bcff71b4dL,0xc8a0e1a9aa99bf83L } }, + /* 54 << 49 */ + { { 0x323aad4991d6b8f3L,0x91b678c0f3d9154eL,0xc141e2424ce74f67L, + 0xb7c38aef65659ca0L,0x5b5f89b174a937e1L,0x739fad71abc55012L }, + { 0x315ed44ccee5f4fbL,0xb0731455360a61eaL,0x39235ff0ee93ce5aL, + 0x6352556fd203baf9L,0x3c22dc6a0ea06b93L,0x195638cb591bbfa0L } }, + /* 55 << 49 */ + { { 0x8bd5a15359ad0688L,0x827e82d8a7323070L,0x9ea55b3af70686e5L, + 0x511c8c3f34c2d054L,0x9364d28aa14a3c61L,0xc4dff9c461374139L }, + { 0x947c3ec9a39c01c0L,0xead11d42108440bbL,0xcc6d893569677f79L, + 0xb1d632710b9b4823L,0x2cec325e63b154e0L,0x45e97c3814a85b9cL } }, + /* 56 << 49 */ + { { 0x11b59f3e92acd14cL,0x188c1bb1d7aea098L,0x5cadf0a19365958fL, + 0x8fef04fcca0b1b0eL,0xbcb4d9fb0c274a5eL,0xe97eb41cba78427eL }, + { 0xc49f0bc55cf06378L,0x2681f12a281b669dL,0x200e9e583f796b81L, + 0x5bbea92b17964262L,0x86b3c15756db0039L,0xe4477c5eead482baL } }, + /* 57 << 49 */ + { { 0x1340e22c050fc1faL,0xd5cc5445bd062615L,0x03ad31601f494b03L, + 0x612919142af1b95eL,0xdb31a06d53705ac5L,0xf590433ad07ae464L }, + { 0xed52363421bbbd72L,0x1f032ad2f1cc7842L,0x212b1d5536a7164aL, + 0xc2cedab7dd973183L,0x29aeeee05e74ada3L,0x579984d8bb666836L } }, + /* 58 << 49 */ + { { 0xbbe5db83e13d34d3L,0xbae5ae959a8a3344L,0x55d2f0ac797d6e35L, + 0x75e78c017cd0abb0L,0xb757f72cbad96294L,0xe52493895d556f25L }, + { 0xc02293538e7675dbL,0xc363c5255c8beec5L,0x7ac23c0b7c87ee00L, + 0x9c5f22b4a7de93f8L,0xc6f0ea64d9644b5fL,0x3fa718d4d161f87eL } }, + /* 59 << 49 */ + { { 0xe8496c463f356cf8L,0x25b5b8742da1b81cL,0xa35ec06330efa9c9L, + 0x7497d85ffdaeb348L,0x312ad677e83f49d7L,0xcb5c346cfe8aece3L }, + { 0x19d7332d61cd4ebcL,0xb03dece0d0967141L,0x47dcb81af5455addL, + 0xbef0e70389ca68d4L,0xf7abbeb9c987400fL,0xbda81c65a1521da1L } }, + /* 60 << 49 */ + { { 0x535f3e4b86882341L,0x5af1c6322e22600fL,0x0403b6e0584a13abL, + 0xa64de86661f59ce9L,0xd22106f738501b92L,0x2932f808ab6ffd04L }, + { 0x8da4cc6e232967f2L,0x4b8fdd9ef3644670L,0xe8cb6ef31e0c51bcL, + 0x20b7b734230c6897L,0x5009176453d9339aL,0x5f5c8c67ca637277L } }, + /* 61 << 49 */ + { { 0x23e333d467232358L,0x3c2807bdea037380L,0x9439cc4626f1dc2fL, + 0x8c87dde53ac29173L,0x601b7245766897a1L,0x9e0b1a4559350e3cL }, + { 0x0818b6cb301db407L,0xbdc4584676b6fbf3L,0xeeca553431bdd954L, + 0x1dfabc033f9be3bfL,0xdf0415dc68851bd8L,0x33be32a67aa9dfa8L } }, + /* 62 << 49 */ + { { 0x8c9017dd4b4e4b5eL,0x02f435dd7b892b2eL,0xe9af9efd292e0f2dL, + 0xa32124c75c4d315dL,0x5c6fde76b31a390dL,0xf1fdcefaa6e46d3eL }, + { 0x5f39dbfe9e9e84b6L,0x574d647d19aab6b7L,0xd5a234cdad1a2987L, + 0xeab841c7dab59c81L,0x5155898db3137b90L,0xc52e9ddd06db2fd0L } }, + /* 63 << 49 */ + { { 0x8617f0d490660ff7L,0x00d73d108b35743eL,0x433e42d68a6ca67eL, + 0x575ecb9beab5cff6L,0x4c64bcddf258960aL,0xb8ffb7f32c23405dL }, + { 0xa98c06691261b0c7L,0xf2701f4a6b9bf7c6L,0x3abe44c41c68efc3L, + 0xdb5ac9cbf12c7a25L,0xf5b4616651120981L,0xf8058f7074d518f3L } }, + /* 64 << 49 */ + { { 0xcd92906c6d6ae962L,0x628356159807d881L,0x0d6929781fdc1915L, + 0x45d01a8c269d611eL,0xe7bd1e709665b00aL,0x086385349bcaa388L }, + { 0x8f189e882dd24299L,0x5f643392b82fb270L,0xca65bf16c633b111L, + 0xc6adc9c9d6f1dac8L,0x0df2c293a3c3381dL,0xdd6ae97d8388cd12L } }, + /* 0 << 56 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 56 */ + { { 0xffdbd0eb3863db02L,0x8b8256832f57e10fL,0xc11acead35e7a3a2L, + 0x4998cf8c67833028L,0x8f3a346b844c7976L,0x0a9d872cdb9b1a1cL }, + { 0x8735dabcb98d445dL,0x93790d80305fa0a9L,0x7c0add49d267a01aL, + 0x2b46c913ffa20d11L,0xf2acef26d8ab2d4aL,0x71b701b93d926080L } }, + /* 2 << 56 */ + { { 0xe9d2a98a5133de8eL,0x37083b60b81b8b00L,0xf399325dceaf86aeL, + 0x03b17c888f161525L,0xd8ac35c984211b9dL,0x220837849050ca48L }, + { 0xa818c44bc9fab832L,0x8882bccee5aea7daL,0x633aaf35f8715b04L, + 0x5463e1b99d8829a9L,0xb18df52d84a820f1L,0x9d5ef891d096675dL } }, + /* 3 << 56 */ + { { 0xd54e2c7cac60496dL,0xc06d5e5d04cd50a4L,0xcb4105e8e60f7f59L, + 0x705db308427483adL,0xf73ba98bf2bff383L,0xa945611a0220e6e9L }, + { 0xc01c46b8d957e12bL,0x458897b7acb1f371L,0xf738dc0bfa3403e6L, + 0x098bc687d2202896L,0xec0c217a5f882e5eL,0x8f25af77a1f4eb13L } }, + /* 4 << 56 */ + { { 0x2615c78259ee4124L,0x4dc2824c76532b4bL,0x9c3b1d771c84a04bL, + 0xb6fc203fcb9f9e34L,0xbed65464c64f7846L,0x04f520a2eb004248L }, + { 0x5c0177274a58fd22L,0x25958482c10d9472L,0xb78c6666aceb0e3aL, + 0x18d3c188fc046f0aL,0x7f3e2f301baa9595L,0xa574f8cd8a2844e8L } }, + /* 5 << 56 */ + { { 0xc899eba381c2d81fL,0xb27267d6f3f0a431L,0x607c8629da55568eL, + 0x6b5472282b1dc1d9L,0x23232311c9c001ffL,0x207a2eb2488f8b85L }, + { 0x3867ac9adac37a28L,0xa36d14d32584a5f0L,0x7398c647a74488ffL, + 0xf6ed920fbe087640L,0x72beddc76319a571L,0x55c2cd826a244aebL } }, + /* 6 << 56 */ + { { 0xb7da79c625f8a53bL,0x6b950bdfd331ad8eL,0x3481b7b54aa36d18L, + 0x6efeaf88ed0e3091L,0xeb017bddc993074cL,0x8431a6d6529dd654L }, + { 0xf5177231bd069585L,0x6d753b103ce85096L,0x194d82d34ca26741L, + 0xeaeffe15adcd1650L,0x4dcec3d9af7758b7L,0xf5fdf6664cc2c819L } }, + /* 7 << 56 */ + { { 0x94bdc7f4a9810744L,0x464195daf045d859L,0x27e2dab0d654cb57L, + 0x1d4e1e537a491956L,0xa1ef570c31d5d099L,0x01cd21ee295f3de7L }, + { 0x8681b00db8249038L,0x17c31bce93781b71L,0x4324e90c6a1b5748L, + 0x44f9324c1222e554L,0xe30ba10fffd53dd0L,0x2e5817a8b48eeef0L } }, + /* 8 << 56 */ + { { 0xa349bb66c8fccaa9L,0x7888755f31a53ee7L,0xa6e1d891c18d3750L, + 0x9985aa4dae8d2bfbL,0x8baec9ae31b33078L,0xee68295a98750e94L }, + { 0x0d834bf8d6ddf305L,0xab33dff39762126cL,0x0c22faaa0c51d098L, + 0x32404042b887a10fL,0x31f6a614248bed32L,0x311f86301ce0d662L } }, + /* 9 << 56 */ + { { 0x5c95cf080d844b0dL,0xe09a8352c98650c9L,0xc1b106c5d089058eL, + 0x2b3cf101eb0c6107L,0x1993fdba3ce6ee18L,0x7234eb6425fc4d24L }, + { 0x8345acfe05f46dfeL,0x07fccf68a2d87d38L,0x14494cea85da7852L, + 0x8737500acecdd9f1L,0x72b1490ca39068ffL,0xce28271acfa4469aL } }, + /* 10 << 56 */ + { { 0xc872326f55c6c00aL,0x6a5f0fa3f912decaL,0xf4ef0ca5a7d1bdb1L, + 0x1dee685b37dc6bebL,0xdad4cf52f1b09b88L,0xc7199f0277f1db84L }, + { 0x7099ef00a3f00491L,0xd8fbbbfa6d8804e3L,0x2a00b8e50ae1e360L, + 0x8a8c9d03fe9be5dfL,0x06e0585b8b1faf6fL,0x19542ee7ae29c502L } }, + /* 11 << 56 */ + { { 0x36cad867e2aa1c5eL,0x7ef21e51317f9078L,0x68efbb84c82e925fL, + 0x973b36769fe751e0L,0x09c4e0c1177d36a7L,0x9c0b7e048a753c5eL }, + { 0x8414cdab15ccad5cL,0xeea2134ed50c1678L,0xd9c1dae8f6585d5fL, + 0x82fd04ab4e5c3d96L,0x868cddf7da3812d3L,0x32a65aeafda07e68L } }, + /* 12 << 56 */ + { { 0x73292e6a60720858L,0xe046a79953160855L,0xf74d56c9ed3b94c1L, + 0x0e371167c67863e1L,0x19b3a9f43f6636cfL,0xe624798d898a25b0L }, + { 0x2ed1fc4dfde2cd6eL,0xd9a7ab519fd15ee5L,0xb6b8d551c487b1cdL, + 0x9fec705ae8936c54L,0x4b779dde1a50e094L,0xfb5100c2c3a4ef5bL } }, + /* 13 << 56 */ + { { 0xb35a7b102704c525L,0x8a77fa5b44276cbcL,0xb4a9cd235ff1a12cL, + 0xc74a017c88a37997L,0x84e26eea9af37476L,0x8a6b8c0e7bbf737bL }, + { 0x90ab7c948f05bd3eL,0x31749075464f3a2cL,0x32f7873c1dcfbd25L, + 0xc0af73d343bc2054L,0x556c4798171d825eL,0x2c84b5b6081542f8L } }, + /* 14 << 56 */ + { { 0xa5907e5c59ab2507L,0x12b86e04cf7df60eL,0x0a14bed18af4bc50L, + 0x462863b20c11bac5L,0x98dde284126958dcL,0x8877e7695625eb29L }, + { 0x869f7214f4fe19e5L,0x29867e51ec0f8c1aL,0xbf498bc078b85f03L, + 0x9dda400e8973a94eL,0x8d8b998ae6e51b1aL,0xedb0957c557ac00eL } }, + /* 15 << 56 */ + { { 0x84b6d5143b7d43f2L,0xcb84c823afb7a2b9L,0x892e8c4c56d2b161L, + 0x52ea7426214fdc0aL,0x07f3d57679763557L,0x9f95fd585a828bb3L }, + { 0x2c7f03d550e14019L,0xab723de7d7eae7b3L,0x4c08189317f4ea6eL, + 0x64cc5bc0ec367246L,0x73077b5ddf11c3b7L,0xfa34b540e08eb4bbL } }, + /* 16 << 56 */ + { { 0xac6dbdf6edc9ce62L,0xa58f5b440f9c006eL,0x16694de3dc28e1b0L, + 0x2d039cf2a6647711L,0xa13bbe6fc5b08b4bL,0xe44da93010ebd8ceL }, + { 0xcd47208719649a16L,0xe18f4e44683e5df1L,0xb3f66303929bfa28L, + 0x7c378e43818249bfL,0x76068c80847f7cd9L,0xee3db6d1987eba16L } }, + /* 17 << 56 */ + { { 0x254ed267050f46f1L,0x36786ff864daa83cL,0xb4a89efc802a3ae6L, + 0xe0027b3486b77d59L,0xb7147905f48d0de6L,0x00733ca710cf7c60L }, + { 0x87efbe387b3ab776L,0x3db10898de9730f4L,0x61f21e1386b7a40dL, + 0x5541873648455b6aL,0x0de378f9a88587deL,0x42dead7a766d18f1L } }, + /* 18 << 56 */ + { { 0x42b8ef51e15ad876L,0x498886e5082e110aL,0x3144e8c964edbd73L, + 0x4b08cf86f79e6724L,0x42d06d53ddfdb6a5L,0x4c9dce336d8b1f33L }, + { 0xbb8913ae4be29e97L,0xe944c922166fdcc4L,0x83913b963c494e9bL, + 0x529d57ac633a0018L,0x632a7cfd242e7d9cL,0xf0e2434dd9b51d08L } }, + /* 19 << 56 */ + { { 0x74768ab044ff52cdL,0xa590ac7eead09902L,0xdc408c53f52c0f5fL, + 0x614a22d6f853efbfL,0x61f391c425126427L,0xb61adcfcbf462fbbL }, + { 0x7b753aaaaffdbe78L,0xce12b2247bea939dL,0xca21f73e95baf09bL, + 0x2a82915e43ca9ebeL,0x67ba04f57936a38cL,0x1c1964f1616b0b87L } }, + /* 20 << 56 */ + { { 0x4dc628c67cb2ec48L,0xc896f99c0cb1e9d2L,0x399ac2e85cc6134bL, + 0x5ac36de184ba73d0L,0x66a334a3e1803832L,0x394af7ea59b770c1L }, + { 0x3df19e55b46f793eL,0x97aaec84bf770a95L,0xf52068b8f8c54408L, + 0xb6f7649f49e05f0fL,0x54d8db0583360826L,0x24748fdf71af722fL } }, + /* 21 << 56 */ + { { 0x68f4dd4956c29111L,0x391ac9910dac9352L,0xb0a8a54206dc9d58L, + 0xb5058ed8fbe70330L,0x8b5e9d4076b593bfL,0x769fb99cd7f2b261L }, + { 0xcdcbb60ec67cce8aL,0xe01a5d5d75da36dfL,0x7e831d0ef7c6e5cbL, + 0x0f6bf54bccdeef00L,0xed49ad3998ba4d8dL,0x8d512c83614d70c2L } }, + /* 22 << 56 */ + { { 0xc1910b2545b4f6e5L,0x54c6ee8489fb712dL,0x80b6fd47f5747ba2L, + 0x3d81e7efd6d4f856L,0x8b9e87418031f1bdL,0xc591d451f2327316L }, + { 0x4830d9971e0f1c1fL,0xeabe29bd86e92024L,0x2f2053a1b8c68d7eL, + 0xff4eb9e879d00ad6L,0xa0c93249f4b4cd89L,0xe127d9d3cb9e0761L } }, + /* 23 << 56 */ + { { 0xeb947df3492d73ebL,0x5474817b0d32c2ddL,0xeb01bef7a9440e93L, + 0xf604581d8085d1f8L,0xf69daa189f69ec8aL,0xc79ac48e71748716L }, + { 0x5141c75ad4beef28L,0xf7dfaf89901c44a6L,0x7bcbe4812e81ed85L, + 0x57ed0e6f0c5a4423L,0x7cf189651cec85a5L,0x8ddfe8a5beef12b0L } }, + /* 24 << 56 */ + { { 0x60ee08b46bc0b979L,0xa31cfd961aba7f4eL,0x66c05a6358bedf51L, + 0x2ae6ec3854df9266L,0xe7dbda332771b08aL,0x44455d312a09fb28L }, + { 0xaaba39171cec98a5L,0x9b2b12258cb543d0L,0xf47a9cd16af6495aL, + 0xe207f3aac6cd8a16L,0xf98952878ae828b6L,0x37e2475725844053L } }, + /* 25 << 56 */ + { { 0x7c8137d8f93723a2L,0x78fa2e03cf552846L,0x3becd2627d11977eL, + 0xdbc8e9b34e9a700eL,0xb2c7798d20decdccL,0xecae57179523bb6dL }, + { 0xc0fec0677fa2f633L,0xe270b10702aab6a8L,0xda280b374dcc797bL, + 0x50a163b86c42945dL,0x4a3fd6bd363e44ceL,0x0aa7e33d38bca4e6L } }, + /* 26 << 56 */ + { { 0x19c7f098a693d0aaL,0xb79d84244bd22a29L,0x19d91d12a9b3c2ebL, + 0x2ae96bfdde735665L,0x2f9c9a773d8a85bcL,0xa74bdd46cbab80f5L }, + { 0x25a2486cdd9f70f0L,0xada155c9754513d5L,0x8aecd7db4c3e9494L, + 0x9c3951ad2cf6665eL,0xd35780d44a9ec29eL,0x064983964cfd7821L } }, + /* 27 << 56 */ + { { 0x23407aac0834f890L,0xad7b7b5599bb065fL,0x3254aa7e4ba2b4ccL, + 0x37f37fd1663f9213L,0x0c72c3111c5a51d4L,0x6e6df84b9989820bL }, + { 0x576a320e1ae2f321L,0xa5fc617c3c62888eL,0xc4f1be4df6c40362L, + 0x01b21892dbfaa5b3L,0x6fc0442390b9a5e3L,0x22a70c8791495c30L } }, + /* 28 << 56 */ + { { 0x365e1382183aee81L,0xe9f2245275d289c8L,0x543cb5c7b70962e2L, + 0x853971711cea2e37L,0x8b31cf530adfc82cL,0xf9a458bf3b67c705L }, + { 0x13b1cb3334a9b3a8L,0xa4325b403732f6b5L,0x39e997ba04e9df8eL, + 0x24c0d6ebf1d542f8L,0x9cb3f1abd82901bbL,0xbbaef37a4cb34763L } }, + /* 29 << 56 */ + { { 0xc4881080b08dd648L,0x21869be8f1fe4e15L,0x63e158b112501ea3L, + 0x48a909ce32408693L,0x77fd2cf062b24495L,0xf7d1e134db9322a5L }, + { 0x4c02c8bcbdb19eedL,0xe03cd00e8a20b335L,0xe04271c530632562L, + 0x549e5dba603e1681L,0xf01b38f95503b61fL,0x244c81920b3fb785L } }, + /* 30 << 56 */ + { { 0xb423030c4b0c7247L,0x242d409f149f8cbcL,0x6094885e9c1f518eL, + 0x6d299dffe04d97ebL,0x152d05bb09903069L,0xf5656895fe235dddL }, + { 0x801e7f736b22ac0eL,0x73aa6df46ba6dc97L,0xba498bc0d66e5d8cL, + 0x8054e17d36b8c78eL,0x241bd2e21137fdf1L,0x8e79a943b97dec15L } }, + /* 31 << 56 */ + { { 0x94e617abeb64269eL,0x39aef936b410ae02L,0xdbb744c325fcc976L, + 0x5072bfab38a5b366L,0x3998aefea3f5d715L,0x0bdbf555a74e281dL }, + { 0x50d2feece24dd239L,0x835925ef46324c5cL,0x53c4eece7a4dad08L, + 0x340fef207c358d83L,0x9e2189da30f04396L,0x2bc748d727e322cfL } }, + /* 32 << 56 */ + { { 0x1238e097ae658422L,0xb4631ddb568df55fL,0x451254e7f74c5c50L, + 0x238b16d28805813bL,0x23987b28925e7a6eL,0x93b72e2d2a1a10bcL }, + { 0x944c784d05e44b7fL,0x7d70fd098c8e3120L,0x6bf1ab2aead45716L, + 0xd5f8f0e631c04205L,0xac062526a10b8881L,0xa1a83cf0fe5505a8L } }, + /* 33 << 56 */ + { { 0xe1e05ff89ea47326L,0x88219a1ffbfc7f61L,0x9cbd0b387dcd3008L, + 0x751d03847671a68eL,0xd73ed70d28e0387fL,0xf66f9cfea9485256L }, + { 0xac68aae1ae153e0cL,0x92eb6542e81b1282L,0x9617d45464541adfL, + 0x81b4d94a9d489e95L,0xafd5cd4620f31ba0L,0x35700392e5a38941L } }, + /* 34 << 56 */ + { { 0x52296be3b71ea9c4L,0x82b05a43424cadf9L,0xb6d329e8842699e3L, + 0x9dfb91bf9370f2c1L,0x0188b738994ecc71L,0xa9a7b03b5ce8b100L }, + { 0x99198b2a25c33035L,0x772795a7e21895d5L,0x37dafa4c42173e01L, + 0xd37f03933ab27d91L,0xf3500a7d2afad1f3L,0xa433b5fd87eac06eL } }, + /* 35 << 56 */ + { { 0xdc193cb5243a97bfL,0xe367f27ff5715184L,0xc4bb95c6fd9120c6L, + 0xd2bd176bbc5f7ba2L,0xf2c0f86de966c1deL,0xc69ab26e811e70cfL }, + { 0x95756460e87c55f0L,0x6b62ab136a59c832L,0x6e971c6c128448a0L, + 0xca72482e91ea44a3L,0x2602d4795dca0f8bL,0x8dadd3e25519433bL } }, + /* 36 << 56 */ + { { 0xfe0553be23246f68L,0xccc1d774d8ad4128L,0xbec668d8cc155edaL, + 0x7a80e9b44231506cL,0x579cb5f42aa1740aL,0x3a61b84fd8b35a2bL }, + { 0x0478c05ba3b519f8L,0xf518ac09acfe39aeL,0xabc15e9076c956e6L, + 0xff35db67dd55d268L,0xbe066679bdbba89fL,0xf7385df12062b845L } }, + /* 37 << 56 */ + { { 0x279d7ffdfc12078dL,0xeb14155eb8f302e9L,0x5f1b11e165b3c14dL, + 0x08510b461bd36b3fL,0xa7f5b2ffc9d73b4fL,0xe5e831557aa09e40L }, + { 0xbed67135cc3d88d8L,0x7b2775f7017a43d2L,0x9ce22ff24c58cb64L, + 0xab88d04849ede1eeL,0xcac13762da63daa8L,0x70662331b1dbfc4eL } }, + /* 38 << 56 */ + { { 0xe4f7022200a8a9adL,0x8d1bbab7d42fffcbL,0xe024970e368ad5edL, + 0x231ef631b4c0c9f8L,0xb47ca0386760b411L,0xe1f297ff179e6d44L }, + { 0x2e5ec77d3e071736L,0x90e20be915b29c93L,0x33961b6dbb7e7237L, + 0xa854df5b42176851L,0x67d223e4a8f4bac8L,0x5464a46f0dee39fcL } }, + /* 39 << 56 */ + { { 0x525a553b32230b65L,0x7bbde6b816bb6a4eL,0x2f5bc6d229f12292L, + 0x5d86858045fbcff9L,0x6ce4fb249f932964L,0xd7cd175098e05ef6L }, + { 0x794b0248e1366d8eL,0xa37afa66332098a0L,0x2dcc1888d9aac70cL, + 0xa01ba83ec15b9fb8L,0xd34ddf851df4b59cL,0x92289e954f829510L } }, + /* 40 << 56 */ + { { 0xdec879d51c9d09f1L,0xdfa9e7d61b371576L,0x8c705c7937fb3410L, + 0xd770153e1f2a02bfL,0x208fc8f18043ba69L,0x58aebe6e25aa3453L }, + { 0x191b69e512941f03L,0x27dbb050d7966e0eL,0xa5196bb7d16bc20bL, + 0x5b6bae47f22b30b2L,0xbddcabda8ce7b419L,0x6e3cfd373b9f5a39L } }, + /* 41 << 56 */ + { { 0x605d4b83330c07f8L,0x4dbe47646a0ed45fL,0x1e715823d7e4163dL, + 0xe337a67dcea3306dL,0x55abf0684f18a604L,0xaaf69d5ea9f57370L }, + { 0xddd09e8129784840L,0x17fd42b9a4fff5e9L,0xe99859e55acee616L, + 0x41d691203b927ed5L,0x35cc99675168f505L,0xfc311c24431d7d60L } }, + /* 42 << 56 */ + { { 0x415f7f0da581c54dL,0x67c678244509f31fL,0x36fb92eb988f449dL, + 0x22d41b1a94181fe4L,0xacc68410df896026L,0x4a10e46f9ccc4df6L }, + { 0xf805a1191969cf2dL,0x7230a26b32ad355cL,0x9d200562e9abd845L, + 0x2db90c3b5cb55349L,0x80b59daa29bcc42cL,0x81272ebc53d32149L } }, + /* 43 << 56 */ + { { 0x6aaf15f27756bcffL,0x5391bc009b645589L,0x46cc4480a6fc61a0L, + 0x6fde9d53293d676dL,0xd6c35628d7618399L,0xdda13a0853daac23L }, + { 0xb6e6c20c0fe7995dL,0x32eb3468d8d41d55L,0x8927d508c19c5995L, + 0x3907eeed3c229e66L,0x509af79f27972057L,0x8a7f44f750e2f170L } }, + /* 44 << 56 */ + { { 0xb91ffd21c87b3fe1L,0x0fe8389b34fe2825L,0xe22d45d74bf4c8cdL, + 0xb575ae4cd6d8308aL,0xa7fa552e82994ba8L,0xfb67a86fecb08870L }, + { 0xc3bebdf8e6dabcb1L,0xef18b357b5bcf114L,0xed518499a4b8eca5L, + 0x0fec83c5df16ed99L,0x5d353a5856b5649eL,0xc858c1d1cec900e0L } }, + /* 45 << 56 */ + { { 0x7a65d2660d85e627L,0x96170bb90bc010a3L,0xaa6e0055da030ad9L, + 0xa75ab280ff4e4a8fL,0xec14e68c0be864a3L,0x05424b9cc17723b6L }, + { 0x9ed54bb218ca85d6L,0x035edc14b78b34bbL,0xc116914929617416L, + 0x0a00e0086cb0d801L,0xba40f1207d4a638fL,0x54b1e8cc9d8bd0e9L } }, + /* 46 << 56 */ + { { 0xbbab4ab54c88db57L,0x68dbee6f9ee9558aL,0x31b988e140da802fL, + 0x9d117c37e90b2221L,0x443ae099025b66c7L,0x8568bd6f2538a654L }, + { 0xf806d8636720df01L,0xe390adf2b649ad8fL,0x7851f8e039d1c315L, + 0x8185ae1a5e650f1bL,0x3dccfc4c9b562532L,0xae99ae835f427c40L } }, + /* 47 << 56 */ + { { 0x99542ca7564c7ad5L,0x682eace49a96f25dL,0x2d01b2488d933a6cL, + 0xf96916ddb8604277L,0xad3259d12e4d7419L,0x9085251fc26981e5L }, + { 0x848219363d2ec970L,0x723ea6a5392351c7L,0x3fae69a55e5448c8L, + 0xf6eee650dfb03d49L,0xe2e1df1ef8c58715L,0xc603b61f1a369206L } }, + /* 48 << 56 */ + { { 0xcbbd8576c42a2f52L,0x9acc6f709d2b06bbL,0xe5cb56202e6b72a4L, + 0x5738ea0e7c024443L,0x8ed06170b55368f3L,0xe54c99bb1aeed44fL }, + { 0x3d90a6b2e2e0d8b2L,0x21718977cf7b2856L,0x089093dcc5612aecL, + 0xc272ef6f99c1baccL,0x47db3b43dc43eaadL,0x730f30e40832d891L } }, + /* 49 << 56 */ + { { 0x7f3a3e5f4447ed08L,0xa6302f7bf94d49d0L,0x94fd2ad33b2abc46L, + 0x98ffc01fe4249c1dL,0x6f3a53bf8db4549fL,0xfbae12df25566cceL }, + { 0x63fc92d3c2e84d15L,0xc355b46c4f5abdebL,0xb50b43a05678d0cfL, + 0xf4d4b0b15681d628L,0xc9f11d63fb3bac7dL,0x444b748cda461eb1L } }, + /* 50 << 56 */ + { { 0xafe9adafc9845a07L,0x484a9eb9df6a1305L,0xec32f0bdb0f111dbL, + 0x742b41cddc7b100cL,0x5a7ea89d23c5f849L,0x1ea8801fa298aa82L }, + { 0x183e1750cb001f26L,0x66ec5daa49da5bbbL,0x8071ff322d05ab57L, + 0xaea9e694e1944e0eL,0xc993754437b85438L,0x2c2467b4faaf4f22L } }, + /* 51 << 56 */ + { { 0x38f87acce602c278L,0x72c79590515854dfL,0x9d466a765e7e2f6dL, + 0xe5f6704772081935L,0xb4b56288ad958812L,0x7f4d9e1395b08242L }, + { 0xb38d0ddb962f0f6bL,0x969d4327e5f76463L,0xf7c7c799f6ac01f8L, + 0x494066673e6ff230L,0xa81fa10dc7e9c1b6L,0x2fcf26bf8093c2d3L } }, + /* 52 << 56 */ + { { 0xcca6e9cfa754256bL,0xfdd79280347723f7L,0x8179d6f52d69c6bdL, + 0x156a53fa94cc8567L,0xb819d70324655f28L,0xf86872e2ebfb198bL }, + { 0xb158e73939ccd668L,0x655db8248de67826L,0x54399a79c621cf3aL, + 0xc55900d498a09c9dL,0x5423edbf20278b3aL,0x06a625b280ba89cbL } }, + /* 53 << 56 */ + { { 0x0f152d69869c4f68L,0x0ed4205a9f0068fcL,0xda68af4f25d4490eL, + 0x715fcc60745c00afL,0x70ab559aad63dff1L,0x7d0a7b6a9b8a37ebL }, + { 0x82ab7a068bca8498L,0x4f012fb4297d954aL,0x8b139e6ed5f6a4b7L, + 0x597316e4b856ac26L,0xeb64b5894387367aL,0xcc92eeabbacb7e74L } }, + /* 54 << 56 */ + { { 0xb53560e968fdcf87L,0x4ed638bd3cbd0887L,0x57f3f38f6080d1cdL, + 0x50370e0c1e4e3ae8L,0x14c87fad184a1ecfL,0x3d06f78d0af7b2ceL }, + { 0xd9370e24fd595621L,0x1e462483c9fbb559L,0x1ee5d81ca0aa5c0aL, + 0xdb2524557419564dL,0x782ba91b57585be7L,0xb2d14bcc5c431c72L } }, + /* 55 << 56 */ + { { 0x9cb9de6fd62ebed6L,0xb7f23b1916c6d571L,0x69b4a8dfa8b307b5L, + 0x78a7f74e19dc7e39L,0x423405152f47c94bL,0xf1c2a5bc31ff2d82L }, + { 0x98c1c3f7b145387eL,0xdd9d24d885e635ccL,0xeaaececa07397bc4L, + 0x6bf6a8469b0cd4c6L,0x68052950680dbd05L,0x81a071b60ce07df9L } }, + /* 56 << 56 */ + { { 0xf3fa8bec0c61d5a5L,0x98f772fc0dedaa77L,0x45a382161146d42bL, + 0xebef5d4a58821ebdL,0x21498af30c1f0e6aL,0x3d8699144758014aL }, + { 0x6f2276ecb625c7e0L,0x68d6a144fb55d708L,0x0bc836e0ad56b494L, + 0x72b6d8850f58ef70L,0x0e0be2887bd7c1d1L,0x70549a879c277d39L } }, + /* 57 << 56 */ + { { 0x39a445d2dbb2bb75L,0xda2a211b1ac42cd1L,0x934bee9a8e4cf8f9L, + 0x5d0dde6a24801bc1L,0xb2d4261d23da4ea7L,0x5fa9059a7187cde8L }, + { 0x49298bb651f05f9aL,0xff0c4a0422a7bee4L,0xf466232da6a29be3L, + 0xff2e157a995c1904L,0x3a4ee4537b31bdffL,0xb4a736d7e41f6eeaL } }, + /* 58 << 56 */ + { { 0xaed55c123fa96c0eL,0x8f90803f6e08adf2L,0x349e5807015b7cb4L, + 0xdb3f05e314656b3cL,0x9289bbecde8b2d9aL,0x3cad12e0c7f28356L }, + { 0x7a68fa54959fe89aL,0x2e7135d0a77f956fL,0xa0285cbabbe35884L, + 0xc547ffe7131ab269L,0x82a902bebe33b425L,0x5a793a790c71b02aL } }, + /* 59 << 56 */ + { { 0x2bb2a929c645c6eeL,0xfc6cbd471e651728L,0x4ec3f630c07af98fL, + 0x118231588e4a8ad5L,0x99a2b5de1303f68aL,0xcc280b182ec9b8f7L }, + { 0x3d7b406ad7298d55L,0x63941bceb9f83957L,0xfeeb132c463a64c6L, + 0x243a2e2bf76a6c8bL,0xae72bf2fdad18d64L,0x774423431987a4caL } }, + /* 60 << 56 */ + { { 0x06de549d78dc1526L,0xa27fc0c1f52c5766L,0xee5ff3d8e9485b1eL, + 0x7af2fbc64bc530dbL,0xa266d6c810f9dc58L,0x866abeed8bfa4d74L }, + { 0x50356d7fcb7c7018L,0x4ae502e07c962af2L,0xb98b449cf011990cL, + 0xfcc8446b59e8535fL,0x25964ab0088776ebL,0x3848aba2ab6cfe8eL } }, + /* 61 << 56 */ + { { 0x9f2c62cbe14a2c5dL,0xcd182e386b113f03L,0x2275ad4f525a15aaL, + 0xd5b7d1d9eb373133L,0xd3c47b9b07929822L,0x60b043cd8fa8e8e0L }, + { 0x603a3403d3958f57L,0xefa36ad67b79c263L,0xfe33dd9f3742ac39L, + 0x30f40b3bb249f9bbL,0x9d2902d20a3b2e7fL,0x173f7d1a899684f0L } }, + /* 62 << 56 */ + { { 0xdcbeff5bf33bdff0L,0x963ae65ee9684a3bL,0xe03586882bcd272bL, + 0x756695068942f107L,0x14319d19262e422fL,0x5c0ef45a2265b294L }, + { 0xeb897bd8a9f64203L,0xa3b259d742b1640bL,0xdc34ee2dce66355cL, + 0x2fab125eb4e13438L,0x1b93a820443420b7L,0x79c46f97b4ba8382L } }, + /* 63 << 56 */ + { { 0xafd8cb2006e55b9cL,0xc88f38ea2530a11aL,0x628d10bfe4efe221L, + 0x00df0da42a8d983fL,0xed45860508a2fce0L,0xcd7882b86a01efecL }, + { 0x93ebd86c7efcbf7bL,0x578f9fe7e3db504aL,0x3c584008aa5e83e8L, + 0x5bf38b4ca8368754L,0xcb4a9cf905c05ca7L,0xf77ab684c634f28fL } }, + /* 64 << 56 */ + { { 0xac92ee1537d83369L,0xc968c187fecec65cL,0x29a7ca876e7a3265L, + 0x0f2b7e7a8456c9afL,0x7471824e9754326fL,0x498687bf364d2ec8L }, + { 0x86d8aacd3c6ee351L,0x01ee6823f6f41e85L,0x9805fc881d79f7ebL, + 0x377ac3a40040547dL,0xd39215d461b4e90bL,0x2547416e4c5fd81bL } }, + /* 0 << 63 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 63 */ + { { 0xa10292b907a6fbf8L,0x292c1a203fa6235bL,0x7a36f18f73ad7a1fL, + 0x8b2c7b0c5897b11fL,0xf7b9a272cb664c61L,0xb6d366af8f81e22cL }, + { 0x3b99b2118e342bbaL,0x03ce158bb06ced2bL,0x3af1175d001db74bL, + 0x526f08467159cb8aL,0x6a3c6e1febde4601L,0xfad5963b8c232eacL } }, + /* 2 << 63 */ + { { 0xa54768dab1b43eefL,0x13e41f47e14fda22L,0x774df203faef6863L, + 0xf795a034bd7471b3L,0xf0958718b47de2e9L,0xc92f7888e1160cffL }, + { 0x86ded97b0146c790L,0x015918f5480a4b7bL,0x05588920424e8459L, + 0x37455914eecf8b2bL,0xe7d3df1fb968a6faL,0x07a0ffd6bad0719fL } }, + /* 3 << 63 */ + { { 0xf13f55e619f6ebccL,0x63720df2a266b368L,0xdbcc937f3bf1a890L, + 0xd3faff625f326fa4L,0x8b33bae9019730d0L,0x7879782af9961795L }, + { 0xec7e75bc93735e44L,0xfbbf6d225d5702d0L,0x26b6e1d53bc2ddc5L, + 0x00345bf714941d10L,0xdd719676a745c77cL,0x2869b11881c523dbL } }, + /* 4 << 63 */ + { { 0x2566021f98d23f6fL,0xfb883e1234ca97caL,0x34e047a5d9f51b69L, + 0x0b50d91df8efa646L,0xc2bbcbb2971f584fL,0x4136f0e40907c91cL }, + { 0xa7ebeb0de735cc48L,0xa7d1bedce113c8faL,0xc04d9a073f5c962aL, + 0x95c155e53ff74a2fL,0x923c65a53df0749dL,0x10d5f81227ae35d0L } }, + /* 5 << 63 */ + { { 0xc08cf7a1a128747dL,0xeb34a1c02eca6776L,0xff6e7cdfb596491aL, + 0x17024305eddd8bbcL,0xab92b54cf3c46414L,0x2a995b7759134eb8L }, + { 0x97525904e48cb259L,0xeac065ed1e1da01aL,0x16cab74a14c5bf38L, + 0xcd3e2516c14eda8fL,0x3ff38094a8de7a9eL,0xb7340214359d653eL } }, + /* 6 << 63 */ + { { 0x4d37c2663e7a369aL,0x092dc32c3ae62c55L,0x566da2e928ca9d67L, + 0xa9771c1a79beb236L,0xaf6b97a976f801e7L,0x3afd62e771259358L }, + { 0xc23a5e32cd541e77L,0xae4c90a301660ff9L,0x3f3a233b1911ccf2L, + 0x93e4664cfa3b3aceL,0x4bdc14832d4c5f5cL,0xfe03d3c36abf13c0L } }, + /* 7 << 63 */ + { { 0x9649468631b26990L,0x55222e9fe3fd62f4L,0xc8eaba742ee74b8eL, + 0xfa43617834d198efL,0x475b688e892748f5L,0xc6eb426541b9822dL }, + { 0x535695bebdae951fL,0x45e69033e909cce4L,0x40354e72b1829154L, + 0x1005ee6d5c56c3cfL,0x61b36a754a3fec51L,0xae644f3872f2f56eL } }, + /* 8 << 63 */ + { { 0xd5469c7becee6e87L,0x056180bc33a4c917L,0xf881ca21a16caa7aL, + 0x221de182e6cc7f39L,0x10d61ab531378723L,0xfb763bd9520c9660L }, + { 0x145214cd0d6b1541L,0xd9f7ff2dd70223e7L,0x9fce59e30cb1fe69L, + 0x2e6e77fa3e299fe7L,0x3a0cf652d5af78cfL,0x50cc42c53e852159L } }, + /* 9 << 63 */ + { { 0xd2536452b8da85a2L,0x5c15dabe331197daL,0xf5a89366aecccec9L, + 0x8f998baf2d8352fdL,0xb10e6c80f56159d2L,0xf61ceff379eb9affL }, + { 0x05bcb93d1c4283a2L,0x4e1abc521d8cd941L,0x898c9a49b46b343dL, + 0xcf352f3c6e423ae6L,0xb1db207f6fd42c89L,0x08f36a1edab295b4L } }, + /* 10 << 63 */ + { { 0xebbe18b7ed31fabaL,0x046e248dd74971d3L,0x3ddf5a2a0b24f97bL, + 0xf9a400c262fc6124L,0x9ad9b0bc6b03b73aL,0x9fa97c56153c8fdeL }, + { 0x1b6477da00b73ea7L,0xec59f64a21b2f3f3L,0x4428712895306955L, + 0x4b5db01db9e77579L,0x237edf0bde05e0d1L,0xac904b01855332f5L } }, + /* 11 << 63 */ + { { 0x6a37fc505cf708c5L,0x8de4dd7c30497ceaL,0x6978648161b8bf39L, + 0x3cb303375d7362eeL,0x0e24d09237ed25e6L,0xd474f3dc2f69ce20L }, + { 0xe15d98a0edb40541L,0x5e4a87c91466f464L,0xc3cefc9eb68923cbL, + 0x66f10920f22c9de2L,0x3c18f9ea9a51b3f2L,0x706237bef40e6204L } }, + /* 12 << 63 */ + { { 0x0791dfa1df764716L,0x31bf68768c66da07L,0x49f25b77ccedf4f3L, + 0x05170ccd5d965c05L,0x37d9521bd49e6727L,0x1548251286a00176L }, + { 0xdab444936c00eb48L,0x102c6b95e00c5c5dL,0x43660c3e4c2506baL, + 0xb2fb26165ec6f132L,0xccc4221a99ac7691L,0x05b29758a576deb5L } }, + /* 13 << 63 */ + { { 0xee84fe05a5731e27L,0x3251ded005713149L,0xbfeeaf3c7c5e7260L, + 0x3db0b6b2f048907aL,0x38728debb4a6b923L,0x853997d9d1142e10L }, + { 0xc636e3874b641cd1L,0x69b10f43c629f4f7L,0x6f10a95c7deddd0fL, + 0x85b5a7a317f56374L,0x28cd59435c329333L,0xb37621f7d1e476a1L } }, + /* 14 << 63 */ + { { 0x3a17f86d48341ba2L,0x558ef6e8ba6375bcL,0xa86ea3f0927935e2L, + 0x2f43742ac04d4fb0L,0x32a30bce38769421L,0x5a6d6a62d8d3912fL }, + { 0x34154b19c20e3fd9L,0xe95d3843fc85f907L,0x26cfbe0f9f7a13c0L, + 0x50d50b3a531736e5L,0x81849773b2cfa2c2L,0xc81523e63ba8ae5fL } }, + /* 15 << 63 */ + { { 0xac9b0573c2f899caL,0xd9c4fc1ff747ef78L,0xbc205571c7714e62L, + 0x726bbf311919f8c8L,0xfff68adaaedc0450L,0x9f4bc0b9f4001089L }, + { 0x5d10a660fc5dcfeeL,0x1ea644fbaa9f25adL,0x4f5cf102e5a144d4L, + 0x4275b6021521f249L,0x9c62750522d8bcdeL,0x3ebbfc5bb7df57afL } }, + /* 16 << 63 */ + { { 0x4a873076ad8c49b7L,0x891598ce7146575fL,0xc1d3042f427ea198L, + 0xdc592111ed259219L,0x0abdbd16234850caL,0x26b9412643b6fe8dL }, + { 0xd3c79d1736a1cfe9L,0x576386219a2b3bafL,0xa736535d5a98bf65L, + 0xacb3b7ddab2cdb2bL,0x37d3743adaaf89eeL,0xf19d9aba0b348532L } }, + /* 17 << 63 */ + { { 0x013b49753e09dc4bL,0xe548f7bc2d034deaL,0x65ffcd710b861c72L, + 0x80f4d7a2e07dac01L,0xd1889dcf56c1a8b1L,0x14ad62d4789b133bL }, + { 0x082e3c082e80532bL,0x0562a7d80b9d17e2L,0x4f8613095d57e2a7L, + 0x79f21d7255f93514L,0x22c4f68c595c0f33L,0x91d9bd5ba22c0c33L } }, + /* 18 << 63 */ + { { 0x30539655b29eff74L,0x7ba206ebe723167cL,0xe20c3ce488110a02L, + 0x52b406b97c124481L,0x050111c68c74a728L,0x3d594a6bc57cd9feL }, + { 0xd4b2a271e5f952d9L,0x7e52d63b080da0c9L,0xa6463d65f53a6cffL, + 0x9ebcffcfcc678e26L,0xa657f27b2f2b9424L,0x850bd2b871da5c9aL } }, + /* 19 << 63 */ + { { 0x9f3c395b7d4e1a14L,0x2f99aa23bd7301efL,0x50eee34e3017f166L, + 0x88c951ff4c9cbb4dL,0x90c0422ad8dda2f4L,0xe8361775d49cae19L }, + { 0x654db0d250da6138L,0xe4ada30ee03c34a3L,0xde0d3787832ccf4bL, + 0xd1bf435641b94c86L,0x347531c37db87eb5L,0x6942e7e30fb51863L } }, + /* 20 << 63 */ + { { 0xafad01a0d93c54b2L,0x659bff9695536c49L,0x7b91aac2b9734c15L, + 0x55c7f08224e02f59L,0xebcb71e73a26e551L,0x5b7225f76c6343ebL }, + { 0x021c48fb17d5e775L,0x57536a42bd859c87L,0x24852cc0ae2b63e9L, + 0x21515020c0ce0ef1L,0x2ac7336c8fed825eL,0x4bc87feea0152819L } }, + /* 21 << 63 */ + { { 0x7f9813e94b82bbd5L,0xc01f14624e697d08L,0xf02d9eb293de010eL, + 0x290c503c50db5ea8L,0x339341f033edb639L,0x962abf5f7cd7f6c1L }, + { 0xbb1041ae95fb9e8cL,0xb8c9f9d6dbd8525fL,0x8658a54f0f5244b2L, + 0xe9326e455b84eea8L,0x9ebdfe4f54f11de8L,0x3c90b0cedc740440L } }, + /* 22 << 63 */ + { { 0xde6973e22683ad60L,0x35fe4650eebceb58L,0xbcdbbabf7c719a33L, + 0x8bce8111c076ca95L,0x8f7176deeb6bd711L,0xd04e9769d240a56fL }, + { 0xdef7d8fac8e218daL,0x04cff5976df28152L,0x2a1af6e24bd1cca2L, + 0x9397014edcb911e2L,0xa251339038677b96L,0x0dc48a8fb61b462dL } }, + /* 23 << 63 */ + { { 0x42eab6610197a8d2L,0xdc4a557ade082468L,0x4cf68d6090495f66L, + 0x6dba8de79032929eL,0x304b38cc827b5d7bL,0x8e57275cf32f5063L }, + { 0x4b555a0337280c95L,0x49c1e532ef8ddd18L,0xa2d8eed45459adc1L, + 0x2b353217bba3cf41L,0x11f3c90cefe8f005L,0xb3367fa0d55916c4L } }, + /* 24 << 63 */ + { { 0xe7c396d64654712cL,0x1fa5ea507a26e994L,0xaa98768709012b83L, + 0xf1ef9792e9b17e98L,0x2c22bcb06dc2db10L,0xae42ddf6ed4be80eL }, + { 0x672080f62e743405L,0xa15a7f975b7821d1L,0x0cd912f247adbf07L, + 0x6919c0dcb6c4ae8fL,0x62b13edd14c6253cL,0x66f35919f8032287L } }, + /* 25 << 63 */ + { { 0xc992f6fe05f3b31fL,0xcdcf59b56a3d4522L,0x69901b3815df24b8L, + 0x4b9874029f6153b3L,0xeb09cbc1bca86176L,0xbe78cd7d446289c4L }, + { 0xd4aced42b933fd58L,0xe0dc6f306a326de3L,0x4bef32960542a5f8L, + 0x3eb8d14106f537c3L,0xbb45a994b6f0d0a9L,0x340c025d3f4a01b8L } }, + /* 26 << 63 */ + { { 0xdfcb3255fa371ffbL,0x3fb4a22c92bb6b01L,0xd96efc1605396353L, + 0x2ce2228ce5d2bc25L,0x59483843212c7eecL,0xdca7173882996047L }, + { 0x44dad56d8de87b1dL,0x622f88910b6222d5L,0x1abbc501d5d3a9ccL, + 0xdbed73a5ebe52e80L,0xa7f785b1c98c56efL,0xa32471d3d343aeacL } }, + /* 27 << 63 */ + { { 0x65d39f8ae510cee9L,0xcc60cd118dc5e825L,0x3b6ac6627ed7198aL, + 0x5d7fc001f33edc87L,0x0218ffc453e978eaL,0xecb762e57bdfcf16L }, + { 0x8e7122047966b202L,0x1c502404e6b99602L,0x0acb73f1131cc36dL, + 0x81d1132ed4369a1eL,0xbca89fe8377271a4L,0x1353a883262a2e18L } }, + /* 28 << 63 */ + { { 0x2713b58c9d628e1dL,0x3729960afaa8ba1eL,0xc3438130ab53bc93L, + 0xcef9eda5e9c165e7L,0x9bacd1c3fd02650bL,0xbb300334540ece72L }, + { 0x21f5a5d3d9c4f0edL,0x1ba32e4ff7c19269L,0x8f073beb2cf320fbL, + 0xb49766c45599646fL,0x68180d6649e4f200L,0x8203d8aeeaeddb36L } }, + /* 29 << 63 */ + { { 0x7b19780fdbbbf57eL,0xc094d6d9c2207635L,0x241898ac6bb652d6L, + 0xb61b25724923ce29L,0x26ecd97508000048L,0xd08c54e5f5f96b8fL }, + { 0x19019968c1604cc5L,0xa9940e9edc3f31b9L,0xbad2d245c3614a9aL, + 0x7d3cdb2d411e63b3L,0x88d842c3223638ffL,0xbc5427d0cfba2b48L } }, + /* 30 << 63 */ + { { 0xe6d78b7f60085b20L,0x0aa1d62bf318d226L,0xaaa4391df6461e64L, + 0xb15ee4a7213c949bL,0x183f043be4bd3dbbL,0xa1a87996ca49f456L }, + { 0x6030ed2ef6ed22bbL,0xa2002784fab7f7a2L,0xfc40914dd850cdbaL, + 0xe63edc4c7df80ba3L,0x8fa35ab57b27ddfbL,0x3bdaec795096ea04L } }, + /* 31 << 63 */ + { { 0xf33cc5ee452881ddL,0x89c144a38966d47fL,0xbfa8395149156a93L, + 0x0069bff358707b05L,0x2caf814cca12a0b5L,0x1ea71ce71794450aL }, + { 0x08fd2b1c63d22a26L,0xdb08594eb3876737L,0xf459049a57b3669bL, + 0xf64ecaeefee0d4ccL,0x9da2177c63f233a4L,0x042fcca84e54f053L } }, + /* 32 << 63 */ + { { 0xa68295da2caf088bL,0x23d6439a5c8709feL,0x8deba0cffe0c3df0L, + 0x5b4d037b3cd00a1aL,0xe9edc429aa0f9088L,0x6f5827e35847def7L }, + { 0x9739d03d306ad966L,0x7c6b18afaed51d04L,0xdc3d34ff1759060aL, + 0x029e9aa9a7e94dbbL,0x2a3cdfa0f7e8b7f3L,0x42f87bf0bbd8f6f4L } }, + /* 33 << 63 */ + { { 0xe36941004ef8cf5dL,0xcb4dbddf4d8bb768L,0x0610858e828c717eL, + 0xb4cf22cb2bf53239L,0x938e49f16a3e7a71L,0x1dbbb837e73c7a10L }, + { 0x26ea3108db1b58d0L,0x1ca340abad2929faL,0x1d4601938ecb1f6aL, + 0x060543510424fd93L,0xdbfc403f0303dc50L,0x142ad48dfc0f4007L } }, + /* 34 << 63 */ + { { 0x8a8258eee6a52970L,0xf2d13a33a3882954L,0xd312768c38d48e32L, + 0x78a70e03e9369eb8L,0x02ba8d2b69228d48L,0x7f957a33b3bfeb28L }, + { 0xafb22cd20ab2d0bfL,0x335304ccf8cd44d9L,0x0587a6f256009a3dL, + 0xc0bc7278023b2530L,0xe85f2ec5f37c6727L,0x045f156003f5a081L } }, + /* 35 << 63 */ + { { 0x6d71a45274ec55c2L,0x0d064bdfed33da75L,0x1aa4d77ab503afc6L, + 0xec08340c5cb136e7L,0xf096fed6ed11d9faL,0xf232d1b82f81e148L }, + { 0x71cc9b78ae9b3374L,0xd80ce28668bcc1baL,0xe8f4bd170274926cL, + 0xa7ac120f100da329L,0x9f071c6352a482f2L,0x76d85a8e842d6ef1L } }, + /* 36 << 63 */ + { { 0x516f138bed210253L,0x5ec2fa324433461aL,0x0dbe2c66cdaf1280L, + 0x086b91e59fbf3318L,0xfb0223ee399a1ca6L,0xd6f86d9b0db5b20fL }, + { 0xec02bca25752d618L,0x952fafcaaf69f3f1L,0xf304cb7533c4d294L, + 0x78085727dac65608L,0x22f302ef840a4466L,0x33fb889dc371c31fL } }, + /* 37 << 63 */ + { { 0x4aa2f1c36abdcdf4L,0x80963f8251da8d8cL,0x5647a356ac008cf0L, + 0x40a78c45fc10452fL,0x2a3b9da1ca2d6a31L,0xa4d177760f0db94fL }, + { 0xcfd600d9939941acL,0x256e44c142c3fd25L,0x85bccd42ab3f9d41L, + 0x83e93e44d018298cL,0x569f54d474a5fb37L,0xad2c613af2ffcf8dL } }, + /* 38 << 63 */ + { { 0xc63e6f7c22d515abL,0x3fabfef42ad30174L,0xf13a0126b1c65411L, + 0xe269e956dce87183L,0x44136834a83e0249L,0x554e731831958850L }, + { 0xd287755696569aeeL,0x5af275e9274bf4dfL,0x7056f958197dbfdfL, + 0x699f5a672169811cL,0xd9a857d92c1c7c3aL,0x62cf7431843bdac1L } }, + /* 39 << 63 */ + { { 0x974fcf5529d0c948L,0x104d7df0693c5379L,0x4f851c397dadfb28L, + 0xcd5bc87c233c02c8L,0xf7fa16e82c8c1c04L,0xed42de484dc18a19L }, + { 0x213db3a5b4366736L,0xf6eb5c9517da3d1dL,0x4d04ef1213b304ecL, + 0xba7bd9afaf74e164L,0x956a5f7bab319f50L,0xe733891ce2a4932dL } }, + /* 40 << 63 */ + { { 0xaa4711f54f890542L,0x862421d9eba822c4L,0x2f667179848280fcL, + 0x4de16d87c201ed75L,0xd20e1399c5e61b5dL,0x3f7114b49ed67ec7L }, + { 0x561fd4979b5a88f9L,0xb202eb86d84db2c1L,0x67d8fb90c8637d3dL, + 0x3d1d78a1032b1853L,0xe07bf775ef1af9acL,0x691e1deea57d6adaL } }, + /* 41 << 63 */ + { { 0xe236e42b2a6045fcL,0x4a6b7be7613f1c5eL,0x14136ccbf57b1aefL, + 0xc3a8a6b9c7b34813L,0x63b0998c5f5cee69L,0x311bfe2c3481a229L }, + { 0x4dd2325ff0aba408L,0x1b8a3f739a2fdff6L,0x4845cde0dbafe0d2L, + 0xd092bb22cd37b02dL,0x35436f9d600fe0efL,0x63c580cb065f379eL } }, + /* 42 << 63 */ + { { 0x38f98360f48948b5L,0x1a1d67a97ae3ad67L,0x79966318ab91b44aL, + 0xb69a75b8dfea0b1eL,0xbb18e5fa05d4d71dL,0x80a14dfe03b1280aL }, + { 0xe549c8f14c17cf7fL,0x91da31098969b5c4L,0x1e3e8f08ccfc1732L, + 0xf1cfb3ad0c85444eL,0x6854b52a628bebbeL,0x8a5e2d85075f04d3L } }, + /* 43 << 63 */ + { { 0xd428f75c5aaa1da4L,0xf192162dd224691bL,0xc30f5ccfd3a50718L, + 0x82e2b585e9e0f738L,0xc7fb4dc15cf3fd23L,0x8a52eb37e4e2b37dL }, + { 0xd5bb892bf1702cd4L,0x64b8ccd056b92a51L,0x98ab053f8988e2e6L, + 0xd56b34022f104643L,0xf09017be073886d7L,0x0283e9eebf6eaea0L } }, + /* 44 << 63 */ + { { 0x834701da3801c65dL,0x5bb35c48955aa27dL,0x0ef0f375db7ad387L, + 0xd25e337f06cd1d53L,0x757a1f9d90cd91deL,0x1604f153d61bbd60L }, + { 0x6a01e8cf8bb95dc4L,0x34b7be6275bbdb13L,0x0a96b3a121e9b029L, + 0x25615c3b2946df44L,0x5eda7d1919d04842L,0x08317975fba84668L } }, + /* 45 << 63 */ + { { 0x4a4dd7bf2bb5fba0L,0x0ebc07f3c84c2304L,0x054f2e448daa5099L, + 0xbf8949da3ec362f1L,0x2e4a677c1d7d73f5L,0x405e3ad24dc70fbeL }, + { 0x2958e956c7e46fb3L,0x34e0d7f1b2522e5dL,0xc44b95e25e371e3dL, + 0x62e348a4d91baea4L,0x8d9e89e24c09e110L,0x8cb886f6b1c1e356L } }, + /* 46 << 63 */ + { { 0x66b16f6033e8683dL,0x3435ab2560b41c5eL,0xd5b89f51d452e049L, + 0x4b5253a73aac0092L,0x01cae436f9d2e2c2L,0x789de14637e8ce97L }, + { 0x8f50541701a1c2e8L,0x8c77dbdd798a8404L,0x5a264906b6e91e68L, + 0x36761ccc3c6aafe2L,0x5809baa37e50f9e7L,0x0b50904e28fac969L } }, + /* 47 << 63 */ + { { 0xb6360372308785eeL,0x0c9913a68cf10e55L,0xe82b0f470e67c99aL, + 0x0bf2d24825399082L,0x7aa3edfca86fe16eL,0xf534ec4e731a4956L }, + { 0xb71d5d4eff26e993L,0x320eb7ac7bd58ef3L,0xe5e4c5f30cafd658L, + 0xeb6b8e0a21a06cedL,0x037d0faf6f76acb1L,0x39c76a6ed6f13f81L } }, + /* 48 << 63 */ + { { 0x12474bd8a55a3a4dL,0xe326aaf19e471af4L,0xf201a9308caadaa6L, + 0x546821f835304341L,0x7fe452c3088353e1L,0x8f1ff628fc82566aL }, + { 0x49526f46d99f8967L,0xb19c80c0a4009690L,0xeccf97591cbc0716L, + 0x2e13ae2caf4cbc8bL,0x12b0df13f32e29adL,0xa2005d6e0b1565f0L } }, + /* 49 << 63 */ + { { 0x9260321bde788968L,0x4aaf1752886ccc74L,0xf94ae636c06b1d9bL, + 0xf0c858854954ae43L,0xaaa735866c42a104L,0xcab59d914e782db7L }, + { 0xfd12f9ee01ff3a1fL,0x35eb6104b546d3c5L,0x97d839e075ca1425L, + 0xa77712f452428003L,0xf5dda4e8bd9f30e2L,0x0c3ab97091d6f540L } }, + /* 50 << 63 */ + { { 0x58734b3ca68716ccL,0xacdcfdd2acfb5719L,0x97074bac7084cf23L, + 0xf8d4f285d0c81b66L,0x5ea926e2ef541e44L,0x65a8e25da2c04e0fL }, + { 0x67e2380f06258485L,0xdc00f2ed9691a57dL,0xd37b23fd6b80274eL, + 0x57f1604f2fe10aecL,0xcc21a4aeffb33ceaL,0xf33a344bf75eaa02L } }, + /* 51 << 63 */ + { { 0x24ca6fc56969f55cL,0x6fe18be29a7a9753L,0x5e9a7ed36af8da90L, + 0xf6c261b7ed493388L,0xbe9ac24beef2b77fL,0x0357ab559f244e49L }, + { 0x5f7953375f1b5b9bL,0x27dfdecaa9bc503dL,0x0b2091b55c0e3ee9L, + 0x1f4f7866d68cb87fL,0x336c2c127a442a9cL,0x88267fd1d3f2ab78L } }, + /* 52 << 63 */ + { { 0xdb891eedd06014e0L,0x69685d6103e9970aL,0x3a612db402838113L, + 0xc1cd7b3adcdef0b0L,0x612b299da41d6c1eL,0x982161ed0ed386a0L }, + { 0xb36bbe2f3ea1bf1eL,0x0d8c3752ceb2a5ecL,0xc02cd7f6ec03bdddL, + 0xa87977c152631d9eL,0x7b546cc37e398d7eL,0x5b1218a804845671L } }, + /* 53 << 63 */ + { { 0x52cd86c68a62f0a0L,0xc437c2af4d29c896L,0x722a337a45aebfe3L, + 0x03b13844d8a9de8bL,0x41a005bb8510aae9L,0xf42399ffc63af92cL }, + { 0x004d29cfcd93390eL,0x472de98741dcfa34L,0x2c71ae744e7cdcc4L, + 0x11a5c2f8409816ccL,0x320ca246a96cef60L,0x72de4287f3d57621L } }, + /* 54 << 63 */ + { { 0xe3e7a3eb3771a0aeL,0x781156e9b6dd5304L,0xbaee3a8323e31e6aL, + 0x66d1569a08985bf0L,0x56161e202d75cba3L,0xf9c23c102a944de4L }, + { 0x27ac8f454e129ea5L,0x8b991ba788050aaaL,0x600c96ffa5d052f6L, + 0x0fbe944df244984bL,0x3801026fa204c36aL,0xc4bfa1994d55a584L } }, + /* 55 << 63 */ + { { 0x11b200c6a32f5c81L,0xc4ab4cf43eabe341L,0xa21468f06f339f5aL, + 0xf20c2c5a729438aeL,0x3e68031e3a067c3dL,0x3962a92f062c8371L }, + { 0x389b22835b000f3dL,0x98f3b679250b8666L,0xe283c2b4eea91464L, + 0xd35b14de1e1f4c08L,0x9ae72567d79d8683L,0x2c37b162a3b2a840L } }, + /* 56 << 63 */ + { { 0xfa3e43e56cb173d1L,0x2502258d4591b5a5L,0xae8c4b558ca9682aL, + 0x8cb1ffb4ec81a288L,0xd11ae888bfc84fd1L,0xa3b083a0d774577cL }, + { 0x119b41c11da9afc5L,0x44bc77622934e22bL,0xa04694f37c639d6cL, + 0xd5e1ce5732c5b8eaL,0xd507c39b9749e8b6L,0x16cc0b5755255b63L } }, + /* 57 << 63 */ + { { 0x66fe7a39c4955e7aL,0x25b0b3e5bb11a1baL,0xb82c2cdefc573bf3L, + 0xed33c0e8281a3927L,0xd068c8901ad799d4L,0x052801ec9cbc73edL }, + { 0x614e4aba0faf5c5dL,0x50d7b0a89f66d391L,0x7bdfbf5fc18e88a8L, + 0x1fc93e1f4380d2a2L,0x8241dd5f27d952d0L,0x44944d9c3a3f79d5L } }, + /* 58 << 63 */ + { { 0x808e2693c0edcf36L,0x4725b5aa87c254c0L,0xd1e464644d317973L, + 0x3e59efc2393049d2L,0xa4c9f340d3e0d17dL,0x69b40727abdf3022L }, + { 0xa1d85395317058c8L,0x2cec2a040cfa7c13L,0xe3c16f7634236cd1L, + 0x566b403a3e52fe3eL,0xfd6065bdd6923cb6L,0xe769a89a5019f94eL } }, + /* 59 << 63 */ + { { 0x9b1f6e9042a1cce9L,0xc6c870270511f865L,0xc924caa72a3c29f6L, + 0xcb674fb068e604f8L,0xe997b0b8330c2dedL,0xf5b315a04ddab219L }, + { 0x6fa1dde6575d3ac3L,0x32ad27f735e65e56L,0xfe723ec2e81b1ce4L, + 0x149983f8985d7286L,0xa1d350a0492ecc9aL,0x12a51f8c36a0707aL } }, + /* 60 << 63 */ + { { 0x71e5df78614f6f37L,0x5cf0e08da0b80beeL,0x1f8dae171e32051fL, + 0x54ae365d83bc233bL,0x97ea005b1b84aaa6L,0xf4766d9264c75139L }, + { 0x9b93bbf241215701L,0xb18f042d8cf8a865L,0x5dfb96dd0867556fL, + 0xe9fafbb8597fd6a1L,0x729b2f50fe48bbc6L,0x2cf85f6b7f37ff9bL } }, + /* 61 << 63 */ + { { 0x3e7c871024d197f2L,0xb635595bafe9c29cL,0x302f4fff194e084cL, + 0xd497ce7c18edf332L,0x4081c7aa062672a4L,0xe886a5b28afa97daL }, + { 0xa7e922b5786e1bfeL,0xabd9a18bbd7ffb7aL,0x1f4f5b9356341b58L, + 0x1726484344969ab1L,0xc4a0b557e668a479L,0x5ad1c062bf4f3343L } }, + /* 62 << 63 */ + { { 0x4ff86eb693d2b958L,0x4513fe1b784f628bL,0x45f4712573b5bb80L, + 0x25aa3d36c987bb15L,0x12b1e65bb48163f0L,0x9d0cb4aa9801592bL }, + { 0x02c0c2aa3718bc98L,0x79b03df99c306353L,0x097d8d8daee5144cL, + 0xebed60774621d7abL,0xa8edf06e4b52e72cL,0x40c86f181dbca7d2L } }, + /* 63 << 63 */ + { { 0x65c7144a5e84482aL,0xba6f92644d4f7553L,0xf4dfe807d9c2524eL, + 0x1333dd7c054403b1L,0x44557e880156451fL,0x5dbda4d80824c813L }, + { 0x59e204959857fec6L,0x42f4068f1b1eeb99L,0x067c3aa21d59bde9L, + 0xa9c4c3eeef27419aL,0x99fc994b2ec87652L,0x4f1607581578a996L } }, + /* 64 << 63 */ + { { 0xcd8c2ec9378ef62bL,0x7f4a3c5491a7c4b9L,0xe12386d4db83e1abL, + 0x9a792032bb549bb5L,0xaf81cba62807c0f1L,0xd4ad7d87abf2008eL }, + { 0x9d7a72307e9ad6cdL,0xb30636b08b517b2aL,0x47c324daec900516L, + 0x408cd0d37193eb30L,0x8f0bcce2d315c655L,0x540ad4e0869d6c22L } }, + /* 0 << 70 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 70 */ + { { 0x4b5e753ddae0ff8bL,0xe55c83e4da3d97b5L,0x4034d75f42fa905bL, + 0x89b85edac33e462bL,0x31f413c3058de3bbL,0x66c01c806ba75391L }, + { 0x3f500202373e28deL,0x5090b33b4b9be739L,0x7297aa10efa2adddL, + 0x3e8ccdbe1a6566aaL,0x4dfda07fd7b4f214L,0xa659bd1e7cb1cae7L } }, + /* 2 << 70 */ + { { 0x31796c2387d11691L,0x02991ea2a9de506cL,0x4ff0cb716cb0c301L, + 0xdd0cdbd7d1702ca9L,0x470a26c8e1a02a90L,0xb705b7bad7054625L }, + { 0xfadc2e86d4a1a268L,0x0fd9764668e9f923L,0x042b5ebb2951a8feL, + 0xe4af9d0364197a76L,0xdd2c6bb3249c1b5dL,0x60af89bdf01932b1L } }, + /* 3 << 70 */ + { { 0x4374145d41afcd64L,0x98b72d6049d21198L,0xc0ff394bdfde8a41L, + 0xed1112e5ee1ff7a5L,0x87a920e8cb5036fcL,0x437123f62deb225eL }, + { 0x37e527afb9ad8c58L,0x3e3c9998abfaef38L,0xb656bcc550b2b4e2L, + 0xfacc8a193bf5699dL,0x98cec74fe616307aL,0x34af333dd3ef8babL } }, + /* 4 << 70 */ + { { 0x9ded9b0d744ec273L,0x5bdfe5472e79e4d5L,0x94f3aaf539393728L, + 0x22136862a438413eL,0x449286da373c7de3L,0xa709d85d29aa1540L }, + { 0x1bd13e410284a4f6L,0x37b54d69f0799c8bL,0xd43b558f6bcd0cb2L, + 0xf5757c0e9e610369L,0x15c80b23c16e0651L,0xacb2cf64001820aaL } }, + /* 5 << 70 */ + { { 0x0629e4ddeec37f48L,0x3f7556a2da7de716L,0xcacd8f27661662bcL, + 0x65d8bc2ceaf01690L,0x83ac66477c39c893L,0x353f60dbf59440e1L }, + { 0x2597b0d6852c575aL,0x410885f73a40c2b3L,0x953ab3472fcc2488L, + 0x9f753e5eef4cc6d8L,0xfc32bb4d97f69e63L,0x461c1b0c87e8c264L } }, + /* 6 << 70 */ + { { 0x2bea7e75ac4b62f5L,0xcf255dcdc6297871L,0xdd88db8781b25c72L, + 0x77ad90b3b617dc04L,0x65ee13820ed4a7d6L,0x4c08df9cd9644c8fL }, + { 0x072d3784525a023fL,0x1aef69cefce399fbL,0xb07fd78ed7f29044L, + 0xa3754e1443043fa7L,0x97bdae92ff9fe4d9L,0xad63ba6a700fe6b8L } }, + /* 7 << 70 */ + { { 0xa571929ba1ca17dbL,0xce7a12f545e146b8L,0x39df1446d9eb426dL, + 0x1e48b3f8dc27f268L,0xa2d7dfa1ff548455L,0x750068b86ef1cc82L }, + { 0x4d699306667fce62L,0x98540b9d131c5412L,0xf8a62cd347c580b0L, + 0x2b55460f73795005L,0x3206c0257b8db337L,0x2280934bd0dda5a2L } }, + /* 8 << 70 */ + { { 0x10a8aabd2352478cL,0x599d9dfa1364c40fL,0xa009df1a076945a2L, + 0xf869152c03861f02L,0xc405226e9f866a3cL,0x93bd737d8b41ecbbL }, + { 0xb5c9ed1033901eedL,0x90e4ce8f99312b80L,0x1a9ef22e57589279L, + 0x83ef607d7fe2d6aaL,0xf2da84543473dbfaL,0x14f36d3a57879066L } }, + /* 9 << 70 */ + { { 0x2c780f220ea3ce34L,0x240a211e4b8aac72L,0x7a266e5dc2625a99L, + 0x1cb15d3e3b30c878L,0x8cd8ccab0e1b21d3L,0x53c64279adc1a6b3L }, + { 0xe60d15b960bf708dL,0x6e431c1b0cb5ad4bL,0xec874c3e82033111L, + 0x88054a1d9141eae5L,0x98438a5addf53a28L,0x168f0b0ffa12c657L } }, + /* 10 << 70 */ + { { 0xd621ce26629d7a57L,0xbf571de7cc1f8af1L,0x2c5cfaf9304adaa3L, + 0x950addbd3f283b49L,0x622dc27cee6d1cd1L,0x26d920041f0863fbL }, + { 0xe243b2a2a41ec585L,0x0dbd9adf2bea6235L,0xcb083c4d6f0820f5L, + 0x809ecbafd5493931L,0x9647067414b7ffa8L,0x2cdfe22e53fc2224L } }, + /* 11 << 70 */ + { { 0xc8b1333c7cd74a06L,0x7d5ac4dc271006bfL,0xe9377d9fc14e0e56L, + 0xaa8651db7a92ab1fL,0x77cee8145fc11fb5L,0x1e7c5ca027870b14L }, + { 0xdeef4b3f6f959698L,0x7c59f26e5daa9bdaL,0x4d0d5aecfd312368L, + 0x5247a6f3b738de68L,0x1c4e8ba990c04807L,0x0554b41bcce126caL } }, + /* 12 << 70 */ + { { 0x3df98ea9a81cc26aL,0x982ed56883b2c6f3L,0xc9cbd1b5ea6d6976L, + 0x3f9f23197e25ffbcL,0xbca8e0567da6280eL,0x7abd316635cda713L }, + { 0x46ef321d740ae011L,0xb17f6c75db214a33L,0x37b73b4b51de4044L, + 0x5bccf3ccccd9ba8dL,0xa2ca080dd0f7045bL,0x79caf90668cf4dccL } }, + /* 13 << 70 */ + { { 0xcc3605a9a7b07d22L,0x4370eb18b4ebe4e7L,0xbe393039248867c1L, + 0xc8e4851ecb1a75ffL,0x215f3fbe39cb6da4L,0x6f2102eee41f9a34L }, + { 0x61d484abdfae7c27L,0xf5143bd26f1260fcL,0xa70b6c067514bcccL, + 0xe71ca833d23506f5L,0xe2f50ba8eae03a8eL,0x2ac3b50883c33359L } }, + /* 14 << 70 */ + { { 0xe94b930f3655cabdL,0x6ef6aac4a342443cL,0x2feb8005bae255daL, + 0x4625a15cac6e2095L,0x75c6311d0ec76c1eL,0x896a07409b81c6f2L }, + { 0xbad3e2f9073378bbL,0x2984a10629266ec0L,0xa68a5351a788010aL, + 0x321aa113017cd052L,0xecfb61752f34db5cL,0xfe080cedca2b51dfL } }, + /* 15 << 70 */ + { { 0xba29690803360c88L,0x3fb087c036311812L,0xec5fb10ad9ff6a48L, + 0x52f7077f207dd8e1L,0x8e65cfb844c02fbcL,0x4f4fcde2fbf4bfd5L }, + { 0xd1ff54156cc74320L,0xf989d544f68b036aL,0xafedc2db973bd9beL, + 0x7bdc35694785e26aL,0x0df36796751ae9baL,0xfebde691ccdabd95L } }, + /* 16 << 70 */ + { { 0x3499b44bc77488ccL,0xde000e01aa8f3c10L,0x30140406c1f517d7L, + 0xd4b3c8eb82a174e8L,0xc8835b13af2c9b3aL,0x2cd7626e443716f4L }, + { 0x336c4f4b9c22de71L,0x9dd2b277f2529f60L,0x6ffba2dc828c34d3L, + 0x257a345c34d0d1f7L,0xbc1eff056ca4fbceL,0x05b335620768349fL } }, + /* 17 << 70 */ + { { 0xb142febb692e076aL,0x10cfaa6b9a654721L,0x5b7ba30c8d4917c1L, + 0x44be3089dfe4056bL,0xb7530ae6ae6307f4L,0x47c519c45b5f381fL }, + { 0xa80648d8c3078009L,0xfde72e30dcb021b4L,0x8a89a51bdc2659e8L, + 0xb9e0efa6306adefcL,0xc671c060c754a7bfL,0x703c698e18f14248L } }, + /* 18 << 70 */ + { { 0x25c86ad43c47783aL,0xb1f94a9650f85a4dL,0xb9472e3ac023a02fL, + 0x91033d1b26f0fcdfL,0x95d775c1ab7b4ee3L,0xbe17daffdf3a5cb7L }, + { 0xaeaecd2ce78395f6L,0x0e3abb0953b5da8cL,0x5f729f858ee774afL, + 0x1acccfb3aeca7a6eL,0xd066fccb37e4af11L,0x24c832ab84fc3259L } }, + /* 19 << 70 */ + { { 0xca547b680ca4864eL,0xea40fe17c7d49f27L,0xb5e68bab87227475L, + 0x6ba2bfaf8ce485f7L,0x4d2747acb72684f4L,0x5fabffc670aa6087L }, + { 0x2d4ded5679c67c9dL,0xaf3b4eedc8a4f22fL,0xbef6128ebfa6ca86L, + 0x7ce412bbd4381632L,0x518e6ecfe670d99fL,0xaba6518dfa5f426bL } }, + /* 20 << 70 */ + { { 0x5ebdc79cd41b2401L,0xf0cd8598c498e0f1L,0x93f6efe79c8b7f7dL, + 0xb2f1e40ac469aa57L,0x882f0e943433c455L,0x0add72adaea0712aL }, + { 0xb13578c399af96d0L,0x43c28dc621177663L,0x83aca2d854e09133L, + 0xae03943cc6ad8532L,0xce0a61917104f75cL,0x7dec8786f9838c37L } }, + /* 21 << 70 */ + { { 0xb0b41b8ec5abaef9L,0x43f59aee8ff5d1f2L,0xe58f78c9234d3d34L, + 0x0e1948d029a7f49eL,0x722f8e54c6cd8941L,0x75a4ebcfbaf24424L }, + { 0xec8954982d7dc6d9L,0x8df2feee5261e4e2L,0xdf2820b825dfb96eL, + 0x4b89c4dcff651949L,0x27c871a527bacbe1L,0xfdc70cf7329a52bcL } }, + /* 22 << 70 */ + { { 0x37d58766fdb3f3fbL,0x49d9a762ad64fa66L,0xf80423918cfdbbc2L, + 0x22e60ca36400f7eeL,0xfab8ea7568210629L,0x91267753963e5b6fL }, + { 0x5988d7f56b8e7ec9L,0xe43e762a5899e718L,0x842dbdcc40ae8b99L, + 0xa7ced3f19869739fL,0x1ccc1e8a6d54b9f5L,0xaa3a91adbd32e710L } }, + /* 23 << 70 */ + { { 0x306d662c6d4c255fL,0xf32aa48101fa367cL,0x29a71e02f16b3197L, + 0x653f7d88513a6079L,0xde93d6e74541b4adL,0x4d284acd8c54d3b1L }, + { 0xfc9d462be106ed07L,0x6e3818d07e355468L,0x2ad523859400c515L, + 0x287af41d5ecd3b52L,0x1162162351e1fb02L,0xd696d01f17bd4584L } }, + /* 24 << 70 */ + { { 0x9db114e3715aa8daL,0x596c2dc25c2fee22L,0x04df016bd2f3080eL, + 0x0cb3f7cfb9b72037L,0xadb877c7814fe2abL,0xb2d5ec5c37761ec1L }, + { 0xb5d6068e55d45831L,0x5fab1dffb7c52c04L,0x39b4aa5457d36d41L, + 0xec1de467423cc8cbL,0x280e02dafda6566dL,0xc70c3c383ca55f55L } }, + /* 25 << 70 */ + { { 0x27a866e7c6b03391L,0x980b0a42bfa32fc0L,0xd27856910c105df7L, + 0xf3def8c77103a2b3L,0x6c4ff04bdffea913L,0x57b1003e121140ddL }, + { 0xf47bb2826d0e3170L,0xa44d6ab1e6abdfedL,0x67114b8a2a4b69d1L, + 0x7605714d52d7c65cL,0x3734795ef60b81deL,0x277f9816ebf91959L } }, + /* 26 << 70 */ + { { 0xe57c2ed902b3b70bL,0xcec67da99dbc076aL,0xcaf66725b0644881L, + 0xdea4f6608a3a3f96L,0x5215f097609df5ceL,0x6d828267010193e3L }, + { 0x5971ff31a156565bL,0x44f7e4037b64e465L,0x2145ea9ab5486d75L, + 0x47b04066758e7ec5L,0xc181833a9c93cbe9L,0xcac07a9fe8443292L } }, + /* 27 << 70 */ + { { 0xead7cd3d041326e8L,0x721785f26092e605L,0x760864024ba91a6fL, + 0xb7b9b9fa335e8522L,0x6ba9c85387bb3ea9L,0x9c9f1f6f89b2ae0fL }, + { 0x952bb995aae2014dL,0xf8e74d80c538cfa1L,0xb21ca840b55b7e72L, + 0x22565ec4ad982191L,0xf9547aa1f569c537L,0x8d3cb14648596bcaL } }, + /* 28 << 70 */ + { { 0x340d77c2f3b6cbc6L,0xe09ae22c80f4f690L,0x3e915b028b74d32cL, + 0xae7101ca3cc1117eL,0x3c36152b526c5939L,0xdad8aedbd3ec0caaL }, + { 0x34de058e351bde13L,0x2fa75fd4582726d1L,0x27c030efc214ac0eL, + 0x2a216d1cc7100acbL,0x3b730043309097b7L,0x162ada747afd8aafL } }, + /* 29 << 70 */ + { { 0x43893d328c216eacL,0x475a3466349d7334L,0xf9f259866114fbc4L, + 0x96a22d2f0410b54eL,0xc60b69a53f3d951aL,0x152416e7fb400ddeL }, + { 0x3904dd2e8f682dbfL,0x5459272368383eeaL,0x0092554ee8c998faL, + 0xc80f28512c602ce9L,0xab2f8533b197386fL,0x8c302dbc91094b32L } }, + /* 30 << 70 */ + { { 0x853d994eea2026d9L,0x18734b04a1b927d7L,0xd4815747ce88d009L, + 0x0265742f01b856bfL,0x05fd8b1e205d4e15L,0x0f4c8be0f1da4808L }, + { 0x2652b76c456d62abL,0x0d3d1a29cbb8d818L,0xf350487453048509L, + 0xe393ef54e89ae4a5L,0x19ed8f0cc4b1306cL,0xfd72388da1aabd6dL } }, + /* 31 << 70 */ + { { 0x8a7e1494289e6aa7L,0xc69223e65c955385L,0x2bcbad5c087b8c7aL, + 0xc08008a531fed020L,0x9d38f5b2dc117c3bL,0xd84158bee4ad6b36L }, + { 0x2c2583eb92fe5b21L,0xebc847bf557ce949L,0x4c1b54ff4fc0fd57L, + 0xe437eba325ff2f8cL,0x79a4c3cb383caa3dL,0x38a34856e08356edL } }, + /* 32 << 70 */ + { { 0x5d7afe9a10fa53ceL,0xe2415b501ff49021L,0xe39a067dc6523492L, + 0x3458527527557f5dL,0x756b8d86930e9f9dL,0x88df6219040d52d8L }, + { 0x606eb60b5362b045L,0xd179818c9e383cbeL,0xa6215748e068d293L, + 0x73fbdca22fce158dL,0x9cfee07dcb183c8fL,0xc0bf2beba5e03c98L } }, + /* 33 << 70 */ + { { 0x36702d091bf9acc2L,0x1efceaebc9c9dddfL,0x31f9f5599b9afc1aL, + 0x359d4ff33e61a0e4L,0x33b3a707f3772327L,0xd990af318ac1c7ceL }, + { 0x5ee060b7e736ad45L,0x83dbe8b2f653ac2aL,0x30a1e38b407f054bL, + 0x0ec6c70bd9326ac9L,0xeb37ad09d7358ab4L,0xaf36143030551ef3L } }, + /* 34 << 70 */ + { { 0x7b05d8e56edd5c74L,0x268edfac5443acbdL,0x73e0d693ce1ee52cL, + 0x67c67914120a1270L,0x54a897cb6f1c5007L,0xe817914a8d540dbaL }, + { 0x85c1fa1958fc091bL,0x4f4989f4cf2698feL,0xbb2d5091168c08b4L, + 0xa6143388768cdd46L,0x69ec7a265e62ddc5L,0xc08749ae2654f4b2L } }, + /* 35 << 70 */ + { { 0x0a9882b37409bdbeL,0xfad3899cf8b6543eL,0x01c183f9f7e9893fL, + 0xe6438cf708ac9a25L,0xec22dc81aa0f2794L,0x3b641c02aa277a09L }, + { 0x686b1fbd0975c891L,0x4f7e1b680070ce2bL,0xdc343dd7487e3f1dL, + 0x8825d9c230f35abaL,0xda5a77a413b91384L,0xf09d958459e405faL } }, + /* 36 << 70 */ + { { 0x76b242b31cf2ab8eL,0xceb190e697edb12bL,0xd39b41b7089fc439L, + 0x6ee54e750892be51L,0x128fbcfcde414849L,0x4462539007fce5faL }, + { 0x9d12e04513709b9bL,0xc2c49737d95b22a3L,0x0bcd670be4b34d6cL, + 0x78d7b8cd768d7c8aL,0x7cf9382e16a0f402L,0x9b84311d17238fa2L } }, + /* 37 << 70 */ + { { 0x6b7faaf8c19b849bL,0x24aa5d54a5bec317L,0x991aeb14e7c06172L, + 0x52dc7da883e65aebL,0xda8998497696dd56L,0x3844a54e94cea131L }, + { 0xc9fb72ac55f69169L,0xe2f7bfc821893ab6L,0x44220c2edc4057f9L, + 0x9f4f0c3812d5fedeL,0x5725b2b05c913be6L,0xfa08c56c02d8668fL } }, + /* 38 << 70 */ + { { 0x9aff9f0c009b3e1dL,0xed7936d97a3c8c8fL,0x0bc8e46fdefbd340L, + 0x7b508ef231540ba4L,0x9bcd9108005388f2L,0xa25cfa07c089f35dL }, + { 0x9ec7cf81733bccfcL,0xf8a1993a249006d6L,0x1e68981a96d81923L, + 0x27b6199adce834d6L,0x2ddccfcfacffb035L,0xf62d7a534fe0126cL } }, + /* 39 << 70 */ + { { 0xc800c1d5af76895bL,0xc86db45c43f2a94eL,0xf77322fbdbb144cbL, + 0xb2607dc8f7da8df6L,0xaf666055b6cc1047L,0xf1db6416375619d4L }, + { 0xf6103c8c4b0fbd9eL,0xea8e979fb4f5b85aL,0xb0307d41fd16f61eL, + 0x26bf96c58cadf61eL,0xb56c53a3bd348a61L,0xd1a5aa4f8a01388dL } }, + /* 40 << 70 */ + { { 0xa29d231edda802baL,0xde8d0d510ec3c1e2L,0x0ee56eae117033bdL, + 0x4dc9491998bf860cL,0xa08919cd775cd56fL,0x609a30dc1332bfc2L }, + { 0x2c337f181a41db0dL,0x27fb0072c974824bL,0x34292c1bfaf28976L, + 0x242fcd73ef8c4fccL,0x553723b27473c603L,0xb2191ee9a06a0bc1L } }, + /* 41 << 70 */ + { { 0xd10b7b7c10bf3427L,0x16f9ebc505321572L,0x057692f6db5fde44L, + 0xf45d4d268f047704L,0xe3f8784e25584db0L,0x753764cb9f548980L }, + { 0x4239bd4858f5360dL,0x9dc993da98296063L,0x0fbb0c419ffd05b9L, + 0xa6a87d50610c3493L,0x99f5669df10f18abL,0x5a03f02ba4224a18L } }, + /* 42 << 70 */ + { { 0x3c6839e5bf733207L,0xc2f380899c6d106bL,0x43155630e39a7559L, + 0x28d6cb546f2b8d34L,0x19738cdf09183c75L,0xa71ec595dcee5a08L }, + { 0x8e9c1cc3c70db659L,0x1333d7b38beff6a6L,0xb263d91e036a5aa8L, + 0x72728714ee4f858bL,0xd65fcffbb885ceecL,0x08193f585aaaac96L } }, + /* 43 << 70 */ + { { 0x264006e1b53b4c8dL,0xd3748c0bdea2f9ceL,0x019408d34e580011L, + 0x381bcc70b1342807L,0xb904a17191eb1a0aL,0x13ddf3af6151a1cdL }, + { 0x13827129bc228909L,0x3378b4834cdbebd9L,0x25806f7ed56635c1L, + 0xd1a3fb1c54327e55L,0xb2b8895c69d94817L,0x0779752d7150c16cL } }, + /* 44 << 70 */ + { { 0x228437506ce71a1fL,0x39c6fd9abf0956a5L,0xd34a4be8c8d29ce5L, + 0x41dc15356fbf8fb0L,0xdce277034c950de0L,0x1ad7192f90c75c28L }, + { 0x5b3df71e27766767L,0xba85ec629ca80b5fL,0xfadae6e5095938d8L, + 0x5ce3ffc24d286159L,0x60f771fdc7b977e5L,0x7a764991b38c0c70L } }, + /* 45 << 70 */ + { { 0x3e4440b7469f6406L,0xdba02dea247657bcL,0xa551a570a46227e5L, + 0x278bd5a06e58b15cL,0xbbc5f8edc53eb694L,0x50e6bf5b855a2c7cL }, + { 0xa80af271d231f3b9L,0x6c22008bc139b010L,0x04e9a337ba1e27e1L, + 0xcfb75909677a28ccL,0x95c59b55f967af35L,0x70d24fe88d3c6ddbL } }, + /* 46 << 70 */ + { { 0x0117cabbaedcb5a3L,0xb70a95d52e7bc67aL,0xdc2e07d1ad7e7cffL, + 0xf507941825b9a6b4L,0xf953a962bc8b2f61L,0x390a630d181fda94L }, + { 0xc833598d1fbdd233L,0x0213e633ac4763dfL,0xe822febbcabd2713L, + 0x522864e71d2a409eL,0x49d778a81f904f3aL,0x0dd980e15912be0aL } }, + /* 47 << 70 */ + { { 0x97f993f46621ff1cL,0x3bdcc1ea7d30ef87L,0x931c624585386384L, + 0xd17a7b6a8cb593e3L,0x1b25176da0912f55L,0x323cf7ac2faa4d72L }, + { 0xababa6c58683a7f8L,0xa99ebbda4a71606cL,0xb5375f6b0cd8fd0cL, + 0xce43e2e08ae372b7L,0x957af3cb9e69c105L,0x167c4fca772d0c74L } }, + /* 48 << 70 */ + { { 0x0934812574503f05L,0xcd6a64b217bf8ab4L,0x791e72fa1fd4057dL, + 0x033abed8f0697964L,0x1085ac930d58690cL,0x8acd49d69c8874cfL }, + { 0x929e4c39ff1a5286L,0x9704e80ff28395abL,0xfa69fce54c3d9f8dL, + 0xdeb56555fc83a6c4L,0xd375fa037dc04c5eL,0xab2f12f156a58cdcL } }, + /* 49 << 70 */ + { { 0x381d144f8119fa7dL,0xda3aa4a73c6cf64eL,0x3db4cf0a74cc1520L, + 0xe8148941c1cf3514L,0xbc6c7398a22977daL,0x75e26d4982bbdc63L }, + { 0x17a626a4c9594c3cL,0x766fc21a60d71273L,0x547331241c7653a3L, + 0xdbe3a9f1502617a8L,0xe41acd19a33d622dL,0x4d24cbd5e15d69d6L } }, + /* 50 << 70 */ + { { 0xdde0a062dbbb9d08L,0xb5676d14153211e7L,0x747247f6f97b1468L, + 0x93a6de79b2ada501L,0xf9d4e652518ce913L,0xefb0de76702b82fcL }, + { 0x2c54ffd9d68961fbL,0xa6a2d1a384f04f81L,0x88167488d74b91adL, + 0xf20bba56a7d73a78L,0x9af1df5ae1afc672L,0xd79ded4543c26afeL } }, + /* 51 << 70 */ + { { 0x24011535a223c19bL,0x38b55f0a19c719f3L,0x369f86b4d343ce98L, + 0x6516fca318288db7L,0xad32d4699e4aa0a4L,0xb6c80dd50480429cL }, + { 0x890d73f3b659b787L,0x2d1f888be15362aeL,0xd26a84bf7a9d8c3bL, + 0xd79b764460bc6435L,0xecd0272f07b0abadL,0x3ab2390382d7c63cL } }, + /* 52 << 70 */ + { { 0x3ec1874496d87afbL,0xb02425b5aeea74b1L,0x47cfacea954bb89eL, + 0xd8d6ff40cd26918aL,0xf2dbcbb19fd4dea6L,0xc481a4fe370fea30L }, + { 0x60df9f99a334a5a1L,0xeacebd61e6fbc823L,0x21932e6ba0140a5cL, + 0x6504deb051206cceL,0xaa4b43a350560eecL,0xaf965e7b6535123bL } }, + /* 53 << 70 */ + { { 0x25ce17e7be01690fL,0x82bd07fc216f7549L,0x26f98cddac6e021cL, + 0x815367ff3403972eL,0x01b1cf87cd89d71dL,0xe777db14ae24f544L }, + { 0x8081a692f628a076L,0x663adf4498b98423L,0x4a31e0bfbfb25b73L, + 0x5b42f193427be5b2L,0x24b1369118ae7408L,0xf13654a6e9998e84L } }, + /* 54 << 70 */ + { { 0xf8ec0a9e1b64a70aL,0xa1042bbb45fc54dcL,0x3ac4a936b7cbec0bL, + 0x0c2db54708eb7d93L,0x3f16e7c961ae36d2L,0xde25381b4611083aL }, + { 0xc1680ae3cf5edeb7L,0x7c86d74ce2b3398eL,0xa3ec4cde9945710dL, + 0x303d28ce864e3b4fL,0xd5b9730012956ac7L,0x9ad973be3c0763b2L } }, + /* 55 << 70 */ + { { 0x526c03ba1979515aL,0xe6492299cde06e58L,0x2215e3fb93ec91d0L, + 0xa086161bf783b7caL,0x89e39ff44ef0015eL,0x42c6ccc595e90587L }, + { 0x7577d689a81ec775L,0x272e4578daf4d896L,0x6d43c717cf01d7aaL, + 0x583814cffd5253d6L,0xee692f0666f7a3b9L,0x54048fe4e99bc633L } }, + /* 56 << 70 */ + { { 0x2afba531c0b9171aL,0x687dbe4cf2d75c55L,0x7c1c73f7fa17ba3dL, + 0x7886dd45063787eaL,0x14f59a18abd0a109L,0x1819df3c873bb66cL }, + { 0x76c969dfe01183f5L,0x486a120b1a78b6bcL,0xdfd702fac5686aa4L, + 0x2f74157bf3457569L,0x66c8c73e01964800L,0x0a2f6114def25ca0L } }, + /* 57 << 70 */ + { { 0x841838a8227220dfL,0x39eb77e2cd45ff3bL,0x7140aa47f5a060cdL, + 0x9fae5937b55bc3a6L,0x243390ea09b711c4L,0x69db2ace867a3eedL }, + { 0x14ee853a152860b0L,0xe3389c4edae0dae9L,0x4fa55ed1248a496aL, + 0xda6803e00ef304bbL,0xd19f48bcd04c2823L,0xe76b8d82a61773d1L } }, + /* 58 << 70 */ + { { 0x2e3a6332f7ae9a8aL,0x89f1576f78a12a00L,0x9597b2b245ab254dL, + 0x2017d6306309a625L,0x0385c02719adbe9fL,0x26c84f2014606336L }, + { 0x3808a31a3584dd47L,0x0fd2bd1b4e1da791L,0x70c2827fb894be27L, + 0xac97e84547d1faecL,0xa63c56fe9b01c835L,0x19c3b18067ca7507L } }, + /* 59 << 70 */ + { { 0x975dbe423a07930bL,0xf03fc9da8f7975f3L,0x94209a2522662e65L, + 0xf5b20e6b9619dcdbL,0xa95e2188ed5ee020L,0x2301e35abe7fb828L }, + { 0x4216b05b9caa0bceL,0x0534eef625cdec7bL,0x81f5c5f8613aa24bL, + 0x8705662951451a5fL,0xffafb623df15645dL,0xe19276fe79c497c5L } }, + /* 60 << 70 */ + { { 0x461bb6e1d118ef5cL,0x277e378d1f4bf653L,0x3b4138849ccaab1cL, + 0xa5979a3ecea9c61fL,0xdc2a23c09dbfe67dL,0x5f7e32f5335cb2d7L }, + { 0xeefe71a87accbd69L,0x65d961341df58e12L,0x17bafa56538145d8L, + 0x2a723472695df807L,0x132b5320394ec082L,0x96219e617d0ed426L } }, + /* 61 << 70 */ + { { 0xf08ee7071ec12e08L,0xb9a51fc40c4917aaL,0x1aa9b778aa085b77L, + 0x3b3e40d72e62193aL,0x3700217fdc211bb4L,0xed03eaf4fbea2fdcL }, + { 0x82e00364c55111e0L,0x3be15019e3cbc07cL,0xf142d230055b597bL, + 0xf68837b1a063deb9L,0xf1368df622e72e40L,0xfc712c67ab522f37L } }, + /* 62 << 70 */ + { { 0x02ca4c0dc3c8ee2fL,0x1962366a0d75f552L,0x6354ab90a43c43e7L, + 0x9f46429f7668d14eL,0x70ffaa6d0ca59472L,0x231fdb485a95ad7eL }, + { 0x82ae5f0acb2ebd5dL,0x2dc8417ce51b1d3bL,0x5052133a2fb456dfL, + 0xad3b4cf2bad61a16L,0x59f283a48d76344dL,0x5f15465772b18fdcL } }, + /* 63 << 70 */ + { { 0xe0ef0c3cc73a7131L,0x8a4e0cdd43ea81fdL,0xceb5fcb8d6d6ce6eL, + 0x941179893535781dL,0x20f5e952b37d4531L,0x5e77f33364c25699L }, + { 0xb6645e8fa6d3ff57L,0x6dac30cb5b9bfdc0L,0xb29648e73ebb655aL, + 0xe1bf3f4005ebc1d1L,0x1b12288514025fdcL,0xe15fab026c5adaabL } }, + /* 64 << 70 */ + { { 0x86230934f14a99d9L,0x1cf9c66e97c1c092L,0x01e186ba6f595ed3L, + 0xd3291c3de2284a58L,0x03dee2311b9e5e25L,0xf2e9b4ad15cc9f53L }, + { 0x4fba15679770c29dL,0xbf7d673650c4ae2fL,0x86901eb92532d015L, + 0x4396fd784e7455deL,0x2fbcea8fbcf811c9L,0x3981ad15ae952b37L } }, + /* 0 << 77 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 77 */ + { { 0x6bd2c54d4cb89afaL,0xe78c8bfa36527751L,0x27f52654e3eee747L, + 0x56f205839598d907L,0x5f91c2d027cb3712L,0xc501819fa3e33c5bL }, + { 0x248490aa4eded738L,0xde7ac94427789065L,0x20138b3d74f7d38bL, + 0xae791f602fb60214L,0x6b4fb300bd033d4eL,0xc69c25d9bdfd1f17L } }, + /* 2 << 77 */ + { { 0x0c3d2056be21a890L,0x1c1ffbfb8fcfba99L,0x1b68a98b1fbf56caL, + 0x56fd85ff396e31cdL,0xd2ca58444382c03bL,0xc442030a7d3ef917L }, + { 0x4129a731426afafaL,0xacff17ff5eaae9c6L,0x9e854180653f3b23L, + 0xe65a1a149ee066bdL,0x3420084e362ea5feL,0x6fe58801c7911e2eL } }, + /* 3 << 77 */ + { { 0x43f0ae676c4be6a0L,0xabc6a17a504bffebL,0xd5be6c25dbb4492eL, + 0x7efc9ee884bff97fL,0x54fbd9d7062da2e2L,0x1befeb61c6d2ac32L }, + { 0x14cf6dc0cbafef5bL,0x8e640e4771d12192L,0xd0566543d9a16800L, + 0x9cc2ade9beb1e28dL,0xcbfeb45038e65833L,0x3852eaacd0f5acb2L } }, + /* 4 << 77 */ + { { 0x5e930d65c4650b85L,0xbe96b2ae6350da54L,0xcfac4f7efa08bd49L, + 0x277e8456a6e10f64L,0x41be3067407ac162L,0xcfd1d03252a9b68bL }, + { 0x8d8d216a9c337e0bL,0xace044dc4e1b9cf5L,0xad9a4102c60d54c3L, + 0xb09420f028815187L,0x881179c60b3b8e59L,0x872685ed5b09aba1L } }, + /* 5 << 77 */ + { { 0x26d43085ee64924eL,0x5eb54d1c4bd6a77fL,0x69a69ccfd1ca022fL, + 0xaad92723a3342720L,0x51e27b54421d836cL,0x15e83917fc72a1adL }, + { 0x183e75d14ddea73eL,0x73fe3b9fbafcecfeL,0x0197e0925daefd64L, + 0x2fa89f60f85b8249L,0x95411aafd23cd465L,0xb7dbe7485d9a459eL } }, + /* 6 << 77 */ + { { 0xab146c207dfc66eeL,0xa7250dcebb6869efL,0xaeba44439d7ad5f8L, + 0x919f877ec48059f0L,0x780ecd232c6b5c11L,0x586daa8e38625f8dL }, + { 0x46a46c789911c031L,0xf56f74fc65303d34L,0x825bb06d4f384eabL, + 0xd147719ad6aa2bc2L,0x745fd7460750e1acL,0x2ef411494b3ec757L } }, + /* 7 << 77 */ + { { 0xdb24cd1af10ea702L,0xf393de57461f8ebdL,0xf56f414e5cfaefecL, + 0x758c8d854690230cL,0x6740c974433d2594L,0x69d92a620aa6bb20L }, + { 0x17be342e9b0bb191L,0xc1cd309fdbf5c97bL,0x089134df8998140aL, + 0x33809a7e82afcb85L,0x409d2a481db47b21L,0x1d54e86ccdb1bccfL } }, + /* 8 << 77 */ + { { 0x22313dee5852b59bL,0x6f56c8e8b6a0b37fL,0x43d6eeaea76ec380L, + 0xa16551360275ad36L,0xe5c1b65adf095bdaL,0xbd1ffa8d367c44b0L }, + { 0xe2b419c26b48af2bL,0x57bbbd973da194c8L,0xb5fbe51fa2baff05L, + 0xa0594d706269b5d0L,0x0b07b70523e8d667L,0xae1976b563e016e7L } }, + /* 9 << 77 */ + { { 0x47de66da62a200a6L,0x67b0ce0d65186fb7L,0x8e8f0248238d23a2L, + 0x5a44a886c1114a6eL,0x36383e5be8ec166bL,0xd36077d8ca7d2e43L }, + { 0x332f98267c45e8c6L,0xcec2ba1355d968faL,0xdca664a84a56f7abL, + 0x954652467b03621aL,0x471f66259b6e55d4L,0x401a6a5efb0714e4L } }, + /* 10 << 77 */ + { { 0x2fee0c6d6046896eL,0xde64c4e0466a90efL,0xb0c9755a55395f3aL, + 0xdfe2dfd6ae3879d6L,0x979853c2d656c53dL,0x58bb6121757f381fL }, + { 0xdfae5707980db8b8L,0x6d4c7cd7d7752f7fL,0xdfb77382c5dacfccL, + 0xd0fca93104177fbbL,0x9ef6d3e4b67891ffL,0xb599dfcb26024609L } }, + /* 11 << 77 */ + { { 0x79bf86761cc06935L,0x6bbc2d3fd44fe6bdL,0x092678c486f9f728L, + 0x05631aaf54c3fe18L,0x217adbbe95eec92fL,0xdcdbfdfb955bcba3L }, + { 0xf938779c01bafb04L,0x67f599e73ab755e0L,0x793b591fb00c1315L, + 0x7ea2dbae3f2d0909L,0x05436dce46614955L,0x02b988888060d145L } }, + /* 12 << 77 */ + { { 0x795df21ba1ebf7c0L,0xa98f2466681b5da4L,0xea18a2ab413b507dL, + 0x9243326688324aa8L,0x2b91dcc2f74d83edL,0x95054b471f411a13L }, + { 0x50869778e3c621f2L,0xb950f3a9427faf54L,0x8949bf7dae29f080L, + 0x7c16cd020ef3a3c8L,0x7883c719b122cd0aL,0xa2cad71fc03bd749L } }, + /* 13 << 77 */ + { { 0x60c794125b3ad53bL,0x91c62ac783981a98L,0xa6f30f473dcd7196L, + 0x55417e7598b4c589L,0x2ce067cb345b89bbL,0x4787f0db71936e38L }, + { 0x208cb360331d7de3L,0x4b0347aa15022254L,0xc66e58865e8af235L, + 0xdefed4c591a68080L,0x0b8dbd336eeb47a1L,0xb6d44d36f732c8d2L } }, + /* 14 << 77 */ + { { 0xce0b1700d3aa7741L,0x13cc58a90df0cefcL,0xa96149c7da3a1816L, + 0xd387d361561277fbL,0x2294f77cf2c363c6L,0xc8d19d51355a8a93L }, + { 0x926dd80092affccbL,0x70c59253686afd1eL,0xe4826f2370c4d8b5L, + 0x948d43dba2226c34L,0x6ffed99e2a097aaeL,0x80e7a99a2ce18037L } }, + /* 15 << 77 */ + { { 0x070c3f39b7f01551L,0x21b249434512844eL,0x46e33e16e2e2a68cL, + 0xd79daf0ca549dcb0L,0x634fa53966a7b9bfL,0xe856d0a8702990f4L }, + { 0x246e5858e466abdbL,0x3f3ad441edfc851eL,0x9ab3db2c2e397554L, + 0x6c5b1a39b5cabd32L,0x695649b2427c5cefL,0x6179fa0f82ab4f68L } }, + /* 16 << 77 */ + { { 0x022aa09d236b71dcL,0xb1ce6a0ea65a7640L,0x317344c5b38b417aL, + 0x29a74cdb436451ecL,0xd898eb6ca8b1c876L,0xf0134f99b74eeffdL }, + { 0x0d9eab64225d71f7L,0x9679b453ceb3cc2dL,0x37c894ce14dbff2fL, + 0x3704d34927065280L,0x9ee435d8ba29a0cdL,0x675bea1409c11c4fL } }, + /* 17 << 77 */ + { { 0xa8454e2b63263ee1L,0xf4c8a384cc42ffc3L,0xb260754916bf086cL, + 0x610d299cfa46a481L,0x21777897ce41a4d1L,0xdfc04bb321573cdeL }, + { 0xac7d9433ced06177L,0xfdce0356a281b9ceL,0x22abd67970d48fc7L, + 0x1e4ebf7750514178L,0x7f0869ef21a255c8L,0x80ae565c29bf477cL } }, + /* 18 << 77 */ + { { 0x607cfaa1a38a18a2L,0xb29ae9c760bd3f91L,0x4991432d76a4c22dL, + 0x4fe8dcd380e75452L,0x7aeea8150925ed79L,0xa0cc6823b7abca08L }, + { 0x647b164fb0a555dbL,0x60545cd3d6076f3bL,0x7e801133807a2045L, + 0x74b2200743ac7e22L,0xdfb58fd1716d3e5dL,0x369ad09947772c45L } }, + /* 19 << 77 */ + { { 0xb6c5dc0635ba2007L,0x6543c6307921115fL,0xa7e5a662eb6c493cL, + 0x728159f54a0b8d6dL,0x8cb07ef1b943fa72L,0x4a2c5cc923c46a98L }, + { 0xea078b478c26221eL,0x68ef5015ce2be601L,0x3048b5de5239f8d2L, + 0x00a98cd419bbe0e5L,0x0a34161caa94a375L,0x879a9a7aac8a411aL } }, + /* 20 << 77 */ + { { 0x2d968968e3f6217fL,0x60b781ad1fb91fc9L,0x44ce23514a84e6ecL, + 0xe8f5627d00a3d089L,0x45211a094a980480L,0x11029b7263274860L }, + { 0x44601cfcae0477aaL,0xa05a67df269ca043L,0x9dc3938fb758fbd0L, + 0x43d5d89abaa35f8cL,0xa38dfa1f2ab3436aL,0xa29653bc529b7061L } }, + /* 21 << 77 */ + { { 0x6ab2e32b982cd162L,0xdd690ed7794d6da0L,0x8fee0b461862f33eL, + 0xbf9aeee210d244fdL,0xe485aac27dbb57d7L,0x7f7ee4bc0ff23849L }, + { 0xfb3c6255171ba49eL,0x089b9986133e45deL,0xb6c033106d04b924L, + 0x216af9223ea88efcL,0xe646a49b5fd52347L,0xbb495d2ee404b86bL } }, + /* 22 << 77 */ + { { 0xe24934ba07fd5fcfL,0x4840e1a6a1027598L,0x4c2294d245eead89L, + 0x7717bb604fda652dL,0xe809c21878370655L,0x417853499151e578L }, + { 0x8bfe121cede554c7L,0x96037a33952c153cL,0x80458ed86a5b30f0L, + 0xba331cf9ca28472aL,0x31b5f463e6c177aaL,0x68c5dc9183ec14fcL } }, + /* 23 << 77 */ + { { 0x8b78d2bff13dc6a5L,0xacd7e0902285c2a2L,0x6aa7866cb47e9427L, + 0x7c2483474d9fa3f2L,0x2e668396f0661aafL,0xf491cd6d08cacae4L }, + { 0x772a131158f9a617L,0xf372dcd6b2011823L,0x790a5ae54e6bd2a9L, + 0x035ff238fee0c8c9L,0xcbbe828cb0b8c53dL,0x9edba1a40af83ca1L } }, + /* 24 << 77 */ + { { 0x2fde4893fbecaaaeL,0x444346de30332229L,0x157b8a5b09456ed5L, + 0x73606a7925797c6cL,0xa9d0f47c33c14c06L,0x7bc8962cfaf971caL }, + { 0x6e763c5165909dfdL,0x1bbbe41b14a9bf42L,0xd95b7ecbc49e9efcL, + 0x0c317927b38f2b59L,0x97912b53b3c397dbL,0xcb3879aa45c7abc7L } }, + /* 25 << 77 */ + { { 0x62ecc0cc429bdc1fL,0x6a8000add447c01bL,0xc2dd42354f23e5d2L, + 0xe6c1790a01b4a0dcL,0x2497e53c24393079L,0x0a113afeb2a00faaL }, + { 0x96c1bd5011151480L,0xded805425aad86dbL,0x639f24cb76720e92L, + 0xf17703b7d825eb92L,0x10f8924e82d2657eL,0x6edc843c627c5236L } }, + /* 26 << 77 */ + { { 0x472226adf80911c2L,0xfb50c3a5e087a3d8L,0xb194551441848a6fL, + 0x61f4fbba9f17504bL,0x8c59b2c48e33924bL,0xa7641127ac7a8608L }, + { 0x79feb7fc164a2330L,0x9e0fd67253a44e7aL,0x9c5c973081953c30L, + 0x25d6932c3f6342f8L,0x29e8b7664b574a69L,0x02f90a46a5de3639L } }, + /* 27 << 77 */ + { { 0xe2d1e2a3465ab77bL,0x2ca0f6a3cf45823cL,0xa1b12306dbdce9d8L, + 0x820470e7b4b39ca0L,0xe48956c76e847681L,0xc8ed8fc8fbf6970dL }, + { 0x52cb109419ba40aaL,0x08136d091efbaaa2L,0x99dd1ad27d71e1c4L, + 0x10001f97a3a59a3bL,0x79d229e460e4cad9L,0x6d443d8756732312L } }, + /* 28 << 77 */ + { { 0x8d6b28b4d7cfe9f0L,0x6ee5407a4dce4904L,0x7acee5e7ba0b67f6L, + 0xd4cf6bd2abf447aeL,0xc085e8e2e7330268L,0x23edbd5a145689d8L }, + { 0xd2ae9bd21d7b0e7bL,0x3196410ec4fe6ecbL,0x964bef26ec2cd59dL, + 0x09c6d07dd5e0bf03L,0x379f131ea65b646bL,0x0439c37964849830L } }, + /* 29 << 77 */ + { { 0x8afc9a5eae562537L,0xde81bbaab2d4172aL,0xa272c6d53db07247L, + 0x08b903ffd86ec6f8L,0x3373041f835aa84aL,0x02e8ecfdc8f18f48L }, + { 0xed6b2784ccc11e64L,0x03e45e15842a8292L,0xfcfcc54b653b86efL, + 0x9678fe7ed9ea2f91L,0xee5bf4584efceafdL,0x188e49d59fcc4be9L } }, + /* 30 << 77 */ + { { 0xeb0098cf67a224f8L,0x14e486c90991108dL,0x0dad68314b397687L, + 0xf2a4f6cb9d089000L,0x3fcc8803509f7376L,0xdbdf06dddb5d6f8fL }, + { 0x2cbf342806ef3e46L,0x4a4bd5eee432ca41L,0xdcb8bdb70e2d391dL, + 0x941b9a4ec1710ac3L,0x25cea4333d62c34aL,0x9136e5cd881a70b7L } }, + /* 31 << 77 */ + { { 0x9bfdb9b310c3ed1eL,0xc9a225ec0cd146c3L,0x1fec4316573c4414L, + 0xe11a408f2fa8323cL,0x198c760ac3e988bcL,0x3f8a5a1caf0fda3cL }, + { 0x91e89f11f6e78264L,0x3cee0165264eebfdL,0xf9412b049898eaa0L, + 0x3c67991a382e46e3L,0x8d833d7a80acd219L,0x746a696c9d233f20L } }, + /* 32 << 77 */ + { { 0x8b3269a2714a10e8L,0x64cef040a4a2727eL,0xbc5ac714e428865cL, + 0x531dd17ffdaba094L,0x86d2405718d657f2L,0xe807b0d92f99dbbfL }, + { 0xc428a80f6848ef88L,0xb3ef0709d0b73ce5L,0xa752691922a5d255L, + 0xbfe6392318a18586L,0x28a0c772fcf633b3L,0xad22b4ec3f3c5298L } }, + /* 33 << 77 */ + { { 0x8b6a2f1ae6c40f85L,0xf0f44c54f44cf3f0L,0xda635b687b25d4b6L, + 0xee59c00f8cdc9d5dL,0x36509f58cc4876afL,0xe37564484e2c550cL }, + { 0x20f965b565974809L,0x26481694e3fe3a63L,0x6778b20becd272eeL, + 0x9b6bbf39c9072853L,0x4f61f192b0436bdeL,0x98bf7dafd0221263L } }, + /* 34 << 77 */ + { { 0xa06a4b56e0442513L,0x6537e117dd513547L,0x89e38ccd2a654224L, + 0x2fe734bd005ee292L,0x54d6933498cfece0L,0x85de5c9d85a79bf2L }, + { 0x21e072bdcd3da6a9L,0x7a5d707b8c16b8a1L,0x43654d0142d04cd4L, + 0x07d589b94a88c151L,0x5bfe9ea2df726b52L,0x877c46ffcf728e4eL } }, + /* 35 << 77 */ + { { 0xe338f606fa009c33L,0xce596aafa351fe32L,0x8ae0e06123968387L, + 0xcdaaaa9465c98e2dL,0xec6b8a818acb9355L,0xc2c67e7facbee162L }, + { 0x7068df85517df4beL,0xc34a6ecb7c5c076aL,0xf4193aab6250f0baL, + 0xe0cd2f3fa6c9ea47L,0x23a57ccc6488135aL,0x044d73e6c12b842eL } }, + /* 36 << 77 */ + { { 0x9d8a78808078c8bdL,0x6ea07982076d44f1L,0xc58fc94eeb3bfda0L, + 0x0b9e72200dd11b13L,0x8bd58e3aa74a005dL,0x7a30aeda115b7d33L }, + { 0xeb0037e6ef2491ffL,0x0fa2d1a7fb39ecbcL,0xb75aac645ac598f7L, + 0x2c3c103341f61b42L,0x5a330bf01f7eb885L,0x1c96124d33d5e27bL } }, + /* 37 << 77 */ + { { 0x3f157ea1b28d1640L,0xa41c98f2c96806ecL,0xef261c3bb099566bL, + 0x11d88be30aa23f1eL,0x9a721a2c47ed1540L,0x214cb5b0e4431563L }, + { 0x36a95c20250f6b19L,0x6b44f01d30eb0249L,0x141777dc5c67e2beL, + 0x6926b32ebbe7bb63L,0xb72fd3bf756cbae7L,0x226661a279dfb835L } }, + /* 38 << 77 */ + { { 0xc25a44e3300b8f91L,0x08aa9d5691ad1a78L,0x130c561ffdd2a064L, + 0x36f0b4608c05f94eL,0x748166e158a351b3L,0xe408976147d40ed6L }, + { 0xa0ba5e5d1b2e3400L,0x94aea3b6687f6492L,0xf4975167ea262235L, + 0x8014e81143e800d6L,0x635a3c516e5df6dcL,0x71207caf2eb20366L } }, + /* 39 << 77 */ + { { 0xc00364013638e940L,0x24baf83bbb70e3cfL,0xc08a99b865dca079L, + 0xc070152e0d40622bL,0x44880b191697468aL,0xcf95519bfebc1644L }, + { 0x7bdc41d7911a74efL,0xb88180314ad83219L,0x53c523185ad49f95L, + 0x4e59a29f6d112b66L,0xb2707b9c7515de9eL,0x8322492c150c9bdbL } }, + /* 40 << 77 */ + { { 0xcd81bdcf24359b81L,0x6fd326e2db4c321cL,0x4cb0228bf8ebe39cL, + 0x496a9dceb2cdd852L,0x0f115a1ad0e9b3afL,0xaa08bf36d8eeef8aL }, + { 0x5232a51506e5e739L,0x21fae9d58407a551L,0x289d18b08994b4e8L, + 0xb4e346a809097a52L,0xc641510f324621d0L,0xc567fd4a95a41ab8L } }, + /* 41 << 77 */ + { { 0x966f961d46ff607bL,0x7e52ad9bb29278c3L,0x5b9b84b9bc6835b8L, + 0x00e4a35ad834701fL,0x53aa139866b8f484L,0xc397f087de063112L }, + { 0xb811a9a24e81b980L,0x8d9c38ef8d680c4eL,0x0a7e66ef1c8db33aL, + 0x1c7e636bf4e17483L,0x25c0a690ae9acf11L,0x5b0a435985966d63L } }, + /* 42 << 77 */ + { { 0x3d4a4ee0a3bb186fL,0x84de7765082c283bL,0x499bf10a8fc8baddL, + 0x85191faa2db59e7bL,0xc5964c20ccc587a2L,0xfa59313b9cf52cfeL }, + { 0xe614ce878da8cf4eL,0x7d8aa381d60e91b6L,0x054dfc4a0d5c0a8dL, + 0xbcd89aef28a15c79L,0x2af1121efecbc916L,0x6aa49bcb44f30755L } }, + /* 43 << 77 */ + { { 0x7953c7ec7b7dc4cdL,0xb709542edbdd99baL,0x7a2afc3eb30b5c70L, + 0x7669020fcd0cc804L,0xb57c1d949fade8f7L,0x5ae7d78cb2eef81bL }, + { 0xdd5457edca354c1bL,0xa531d85c8f5ac058L,0x5fdca829009e0aabL, + 0x8df732f6f2bced0fL,0x3ee658627faf57d5L,0xf7a265735c2f3bc2L } }, + /* 44 << 77 */ + { { 0xe1ce7f3725a64849L,0x760847744da790f0L,0x4638f287cf5f319fL, + 0xe36f3c5308c3786fL,0x07042ce1985513cbL,0xfb955cbf73d9cf3aL }, + { 0x3e68a2cacde0774bL,0x321f49b76dc2c816L,0x9bfed81fd76c4d3bL, + 0x985b34fefd49fa62L,0x2a3de945ebb8fa9fL,0xcaa616f0405da5afL } }, + /* 45 << 77 */ + { { 0xf3fa1924bc6d86f1L,0xbcf9d3cbb41dde67L,0xf96431168057ef19L, + 0x09315fc52177ef64L,0x1ae99958fcf594a7L,0x7c4baeefaa4dd788L }, + { 0xff1ed168a2bb1bf3L,0x9c697d19b4a651c5L,0x5fe29bcc0df8c999L, + 0x16446aa446c45428L,0x3a51398061700e83L,0xf34133593f034bc9L } }, + /* 46 << 77 */ + { { 0x9cc126b8cbf28cbfL,0xf3f8aa7c1e6d63ffL,0x533e48d2b7f80225L, + 0x8fea0d204749d781L,0xd8ea614b326f8185L,0x9cf3e07753c541abL }, + { 0x09040b60d95c9367L,0xc1b19940f5eabd9dL,0x80b0793cd8f8bd1eL, + 0x95fafd6fadff120cL,0x071b1841ce155f8bL,0xa85dfc8cd29d9d9aL } }, + /* 47 << 77 */ + { { 0xf38e0fdea761048aL,0xd9d5a22c88a93773L,0xbd58470841a99bddL, + 0xa31ef1edebb412e0L,0xd5c4fd5a0274ea16L,0xaaf215f380c1f0f8L }, + { 0xe842a4537d3dfd08L,0xb5c877ae5a904548L,0x3dadd2eb9c6ddbebL, + 0x7f97c541e84e54d9L,0x6183b6ce1b8d8829L,0x2a20c212f50534a5L } }, + /* 48 << 77 */ + { { 0xc8c9b0ae7176dd90L,0xa95604542917d487L,0xb03b7946e62c508eL, + 0x60425926e9fe2321L,0x73b10bba80c1d136L,0xc30a847d9d218c9cL }, + { 0x6ed0c8ef2073859fL,0xa176eabf432dd97fL,0x3078096ab9e96167L, + 0xb28f0e6cc473e377L,0xb44e4995683a3bc8L,0x483512eed3523796L } }, + /* 49 << 77 */ + { { 0x7ff5827f22adab31L,0xa7e859ad43ee005aL,0xfc2387f402c9629eL, + 0x6f39e84add12b107L,0xd1378037c097d3daL,0xc677b554d70d107fL }, + { 0xec15469fe4943084L,0x1f0b13b19d412b76L,0x3b3b49b48a265a31L, + 0x45f28cc7dbe97ff2L,0x33f0e31f4efa0f0aL,0x6b22b99e37a5591bL } }, + /* 50 << 77 */ + { { 0x0a751d3eae0538e1L,0xd51b039af14135e9L,0x92eae0f6e8bdf562L, + 0xf253bd5c66557b17L,0xc1ff9054ef26b81bL,0x9d586d39eafd711eL }, + { 0xd2b05d3d4f431502L,0x847d727f5823cfe5L,0x2c4e236a8e99840dL, + 0xa407e2d87c5981c6L,0x989dd28c69ca34b5L,0x2e8ec6b09fe586e7L } }, + /* 51 << 77 */ + { { 0x43161b5c40bda312L,0x8fd476b8a10fbb2fL,0x84cbf7579e5d9a4bL, + 0x19bb5926a9a31956L,0x66ed993aea9db48aL,0xd7897780ffb0361eL }, + { 0xb031e035adfa3661L,0x1be83caf2296b4d8L,0x8802c98b0024cc48L, + 0x73adb0c0bac1aa5eL,0x17df92e1bef75b41L,0xd753e99903d800bbL } }, + /* 52 << 77 */ + { { 0x24940b868733c1c1L,0xf5dd77ce2ac072e1L,0xc248ad6bf7bdb8d2L, + 0x423e0cc9d9a8b926L,0x4318d600e6da05dcL,0x3e557e08ca27dfc9L }, + { 0x8dc551cdc5dc822bL,0x160da94cbc8fb392L,0x4ffebd2aa6d4d363L, + 0x8190c17db1ce15a6L,0x1abcd1361e9dc500L,0xae3a477c9ee52a47L } }, + /* 53 << 77 */ + { { 0x67ab01575ed80bdfL,0xc77067b69aeb4a86L,0xe6e26abdf7880a93L, + 0x782248db1e43049cL,0xa902c41016d78616L,0xc6fa899fbf309f15L }, + { 0x81e1532d672d951bL,0x84280ba386556a0dL,0x83190bfb55199078L, + 0xbc11e8c25a1c4691L,0x8ac60c7f21152509L,0x4211923ec775dcd0L } }, + /* 54 << 77 */ + { { 0xa63b33f6746418acL,0x62085e0eb7359443L,0x3b43ea7b5fb598dbL, + 0xf4a0f4442b365528L,0x7f4d2ff3eb55a5ddL,0x012cd591f189eadeL }, + { 0x3fbdad99f58c8f84L,0x71dc1b0093bf34dfL,0xfb63f09ce062a588L, + 0xd5f0f0ad6f24b66fL,0x940e23c91813cd9dL,0xeff8580b55f241dcL } }, + /* 55 << 77 */ + { { 0xb30719d8b7fb5f3aL,0x8f74305b43275030L,0x2fdb613bf23628bbL, + 0x75d9868ad945ccdcL,0xbfae46f4f0b73348L,0x48ad8bafe26679b3L }, + { 0x3aeb4743d0b389bdL,0xd2463ca37916297eL,0x3a6f37c820f52fd1L, + 0x7bfade4495ffa348L,0x1e3f6282a25cb79cL,0xac3320d5229bd2a3L } }, + /* 56 << 77 */ + { { 0x261578c7d57c8de9L,0xb9bc491f3836c5c8L,0x993266b414c8038fL, + 0xbacad755faa7cc39L,0x418c4defd69b7e27L,0x53fdc5cdae751533L }, + { 0x6f3bd329c3eea63aL,0xa7a22091e53dd29eL,0xb7164f73dc4c54ecL, + 0xca66290d44d3d74eL,0xf77c62424c9ea511L,0x34337f551f714c49L } }, + /* 57 << 77 */ + { { 0xd1f879197700d61cL,0x21728fe49a89dc22L,0xdd3a475be6d93642L, + 0x3f8554d6e095363fL,0x4b8b712463e1bb11L,0x75db57e6c6da541dL }, + { 0xfdeb9e46ac8342fdL,0x8ab4875114905993L,0x48150a06b2efd023L, + 0x9f5f513df415bff5L,0x39b1234eee9d7915L,0x735570a7dda66da5L } }, + /* 58 << 77 */ + { { 0x3a79a1756e3d4ec1L,0xde0ee6c79936b689L,0x37a7d9ec7fb84ee0L, + 0xe82810d38fe1f44fL,0xbe433c7253049e9eL,0xe72ef4f5fb49e274L }, + { 0x525b72094b4ad28dL,0x37bfb857164f5f0cL,0x60327e31ac68d566L, + 0xdb027619bb71f137L,0x8abc8026abb6e829L,0x99702ff15e838117L } }, + /* 59 << 77 */ + { { 0x974be1d30696f1a5L,0xf884616dd3832430L,0x6997c37ce9dce1acL, + 0xf4bad00e2e5cfbc4L,0x7727adf8e327a9a4L,0x15315bf16aeeb305L }, + { 0xe697c0af09fbffceL,0xe4291f7589f86a5fL,0x765f1904487b12f9L, + 0x752c58a5b7f8ca88L,0x9f9563d473716bf7L,0x48803cdbfd032783L } }, + /* 60 << 77 */ + { { 0xa0d935ce9050c5cdL,0xc1e062d03e9b902aL,0x212d0e5dc3054c00L, + 0xdc9c3f2de70ad96bL,0xa2182ffbc2742144L,0x4680d472a716993fL }, + { 0x9852bb00677f3756L,0x2bb3d78435e6213fL,0xadfdbfe07377fdc7L, + 0x41db795d708afddfL,0x6848cef57727ed86L,0xb24e416aa6c1dd1aL } }, + /* 61 << 77 */ + { { 0x36d76f2f2edc95c2L,0xbdf2a67810b0670fL,0x49fc8c43b63877a1L, + 0x23182ed3a87c8615L,0x94c21da96c011a44L,0x3bc0b86860d3c162L }, + { 0xca6a158244815192L,0x4bd1ce04fd97b78bL,0x1d0074cddc750023L, + 0x40cf8233cdfb0c7cL,0xe4e28aa8bbbfbf3dL,0x72656155b6eec7d2L } }, + /* 62 << 77 */ + { { 0x5b1be65b912b364dL,0xe6369ca1e0335426L,0x249740d58420e7daL, + 0xff13a26f1ac1acf4L,0x0ecee744b9634fb2L,0xbaa77d57d664ceb1L }, + { 0xadfa7625914f3f7eL,0x17c75e99bbcffe16L,0xcf557911d64aedb0L, + 0x8a4b7b49c3644ba0L,0x115240401eb7bb97L,0xb823c21a70fc7b5eL } }, + /* 63 << 77 */ + { { 0x45db2c038727c0fcL,0xf5aeeb7bbae2c896L,0xfad1cc32eed15b82L, + 0x65d4440a8609b00eL,0x35698d956b4dbd25L,0x861615bd0f6cda68L }, + { 0x578efdaa8aec1e99L,0x87ddae76fcf67480L,0x5ff5a1304669ccb0L, + 0x5fd2f31a0b98ee60L,0xccad491a3cc4c003L,0x6dcf25bbccbc46e0L } }, + /* 64 << 77 */ + { { 0x93a62e7cfa43699cL,0xdad738901bc422d9L,0x265e3cbb10cc9544L, + 0x28cceb062f37154cL,0x6b79b0713bf2e08bL,0x88e025df3ab39091L }, + { 0x50a8d04d126522bdL,0xeabbc1b7b779bacfL,0x3db4336ac21cc62eL, + 0x4747f0a36fc00450L,0x067cbf1c544b2d95L,0x2480b7d8fd2be7a7L } }, + /* 0 << 84 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 84 */ + { { 0x0233e423d52eb122L,0xc28483521154b0c9L,0x2ca09cef6349e35bL, + 0x3b70afc3ded2ec54L,0xc813474d52dded3dL,0x2d3f21bf12f00ee0L }, + { 0xa0908f7692f215c6L,0xb97d60e94e9c0440L,0x84ad10c134b6a8e0L, + 0x6f37fd956e7c163eL,0x7caae8c8d057e0c3L,0x534f52c2553721a2L } }, + /* 2 << 84 */ + { { 0xa354c1de72a041b2L,0xe83df25929d1330aL,0x676610999d532bbdL, + 0xb7c2f4cf52011751L,0x6945d34ff659e35eL,0x6217d20ba1303b7bL }, + { 0xa200ddba25751badL,0xa74a729001d3566dL,0x3018445faa82b46fL, + 0xc3e6a3acfccedc1bL,0xe86ae8703353e29fL,0x1c8085bbfd7e8547L } }, + /* 3 << 84 */ + { { 0x728c8e145d1a678fL,0xf944da572ac89a2dL,0x3016c2da4796df72L, + 0xf6d79e4e00a55efcL,0x4fced269526b1cb8L,0x4a93e47791f165a9L }, + { 0x528b8572f84f90d3L,0x3b30376e5e725561L,0x4f903520e07bb990L, + 0x07ddb97f4ea8ae6bL,0x29c01e70b3b735bbL,0x825c7f6e5000dd4aL } }, + /* 4 << 84 */ + { { 0x306b63e3b4dcea78L,0x4b10209213636935L,0x36bb68898bdeddeaL, + 0x9331655d67a329acL,0x14c7fe26ba92ccceL,0x4e7d6929be0519b4L }, + { 0x0dc39dbd164d50e2L,0xd4c430a0b1679cc5L,0xc7f78818fa8682baL, + 0x43396eadb60aad97L,0x751784d7ff2c64ccL,0xd37928be866af43eL } }, + /* 5 << 84 */ + { { 0x3742b61e0475f547L,0x48b2a2c2477722acL,0xf52c6787abce3401L, + 0x4749711ea4cb41b4L,0x7ce0dfb03fca817eL,0x1c1e3bf996e85048L }, + { 0xcd65250e40faa8e9L,0xa8edce7017d9b93aL,0x73523cb2b4dd5619L, + 0x15ba773abb5379f5L,0xcc5e62d6c0a847baL,0x7efe5c7c04d852deL } }, + /* 6 << 84 */ + { { 0xf0a69e685a91c9aaL,0x0304d20105c13197L,0x773a3ab7cd14af1dL, + 0xc0b88edd558d555dL,0xeb12d197d2e63dd6L,0x4a8e849fbcd9cdb3L }, + { 0x06432985965eaa14L,0x453d93861a5a6f43L,0xbd28f6164171b9bcL, + 0x37781639bbfcf90aL,0x1f93898f3a36084dL,0x1fefd8b7dd00ca75L } }, + /* 7 << 84 */ + { { 0x3b8d8e495e456124L,0x967ed511967c17b7L,0x1d72430c2aad8c67L, + 0xe8c5d506b82c1673L,0x989978868a0fb41dL,0xa9d478f70f81234fL }, + { 0xa0c941cf44cc0614L,0xc033c99024ad30f5L,0xaa7de296101f89aeL, + 0x4cadd8e3ca6a3227L,0x3b4db51f2764ec0cL,0xcbfe70fc09256db4L } }, + /* 8 << 84 */ + { { 0xb9207dbc2b2f1bccL,0x6afd6871a3e83ef7L,0x49924e5534ba150bL, + 0x2935ebf1dfec9972L,0x34bf5e94b76f870dL,0x22d0f32b4c20385cL }, + { 0xc78ac1728ccc8e72L,0x7b45b8220ccecb0aL,0x76c67ee4cfb4b8baL, + 0xecfaefb2cd8724b6L,0xe9bc3d67340bc1efL,0xed40b2b9ca5541b5L } }, + /* 9 << 84 */ + { { 0x5d1bd16518f8e17dL,0x754986b7405f822bL,0x420b1b24d8753fafL, + 0xab038e0608ff680cL,0x33621a0fa3649f49L,0xe24b84db78918eb6L }, + { 0x0e669672c8bf4168L,0xcb7fab33171eab20L,0xa097d2cc4808be42L, + 0x4f4e395f5842b80bL,0xddcb1e51a579145cL,0xa635d0cdf330ae0cL } }, + /* 10 << 84 */ + { { 0x9b8a3eb3069e6432L,0x43aaa7fc721397f7L,0x46e23c6ca7e83a71L, + 0x71b261d593fa3c25L,0x4a47a1050f523a72L,0x31919e898dcad752L }, + { 0x4c8b06e70c5dd2adL,0x677ec5f38bdc55e7L,0x4372d55dcb1b5828L, + 0x7bf054c1f04dd321L,0x4e8c1a992e44584eL,0x6807803751d35d78L } }, + /* 11 << 84 */ + { { 0xa6d78a3d754377feL,0xcc17c26ac72ae5e6L,0x2f0ab93b1c05fc24L, + 0x1645c369d64c9d40L,0x7c37b12c563e7e9bL,0xb70d292d58b477cbL }, + { 0xc283aca993a2d5a6L,0x759e9118354c183fL,0x8a031f6fdd8f4125L, + 0xfa8b17ad56edbe3aL,0x6e0f96eb63c651ffL,0x40361942b5085541L } }, + /* 12 << 84 */ + { { 0x25ae349981d311b3L,0x8640f52a3b16037bL,0xac0839941d947065L, + 0x3723c75ee2e693d2L,0x65040a51b66f429eL,0x7f582b0b035a3a53L }, + { 0x20eca9e10a166da6L,0x45b37e202c4cc565L,0xeab882957a8a96e3L, + 0x99e771dab60a1a1bL,0x2cdd778c23b03965L,0x8d4d7a7291052478L } }, + /* 13 << 84 */ + { { 0xb57b345e4ff33506L,0xc1a3092a31d23fc3L,0xc16b501e905e1f58L, + 0xa36a3b1f29067b85L,0x7cfabd23c214dd5aL,0xbd5f7ab726ad949eL }, + { 0x8f64595987363816L,0x49c1a3e679d12d59L,0xcc8f3e2c32d771abL, + 0x008d900e6bde16d1L,0x60428a0f60165966L,0xd4f8d9eda7383ab9L } }, + /* 14 << 84 */ + { { 0xa52d3c2d7e8f73b5L,0x86d8063351842657L,0x58f01253b3949ebaL, + 0x97689f15e79367d0L,0x918bf9a30d820328L,0x2d4bc99441c959dfL }, + { 0x37392f6e8c16ee54L,0x9f726d58e6f0849bL,0x497de1e4b8208f08L, + 0x60c51233d51a29b3L,0x0f61fb03c9e1d465L,0x09494bd0fbe2613cL } }, + /* 15 << 84 */ + { { 0x100ef5d0a2bd7bd4L,0x89efecf5f45e2a66L,0x63bc210b653786bbL, + 0xc7748dba0a0e47c4L,0xaf8122ae110d1ba0L,0x6695bfbf797c78bfL }, + { 0x9b0e6fb1d7dbff69L,0x106799703f53040eL,0x22d9ed52fcaf4ed1L, + 0x1e27bafdcc1b2d4cL,0x839f9c019f1c88e6L,0x1112fe541321ad66L } }, + /* 16 << 84 */ + { { 0x4f293478154d0f99L,0x1b82320dd07a24b3L,0x1bf7c94f64d55f6fL, + 0x4489b57d725c5125L,0x3aa4d43ab1b6a091L,0x054842bdcf7a60faL }, + { 0xaa918a4d2aeb4cb6L,0xcbdaff99ac7d317bL,0xed0e00a16812a03cL, + 0xb09acf270b0a1e4bL,0xc73a41f7ac28386bL,0x43134dbdf4cd1321L } }, + /* 17 << 84 */ + { { 0xe5f746af6e001a20L,0xdc975b02d6a9925fL,0x6d13e266e57f9100L, + 0xe013661396a9c4c9L,0xb483162850a66d45L,0xe3b0f96d4ee8439aL }, + { 0xf2a2c08d3e074501L,0x987b2b6b2be498e4L,0x605aad24a15b815aL, + 0x5bf2186f8529ad68L,0x1413b3d7885ad25dL,0x3de23959807efaabL } }, + /* 18 << 84 */ + { { 0x08336ffed8c33924L,0x15b56cbf5140b253L,0x38dcd310306caedbL, + 0x04ecd49647944afdL,0x1280d23f68a48f95L,0xf414220434363c6eL }, + { 0xd0a397eacaa8717fL,0xb51a1669c3994b80L,0xa02eed916c56808bL, + 0xc3ab55c583545c3cL,0x8b835820fd26114aL,0xe0cfa4a6ffff324cL } }, + /* 19 << 84 */ + { { 0x4db4bfb788b45f19L,0x130252bbe0d5fd16L,0xe44c97b22808bff6L, + 0x885e4555b03405caL,0x3b7ce036be9af81eL,0xebe17cf58c552276L }, + { 0x6eb946c977f4158fL,0x36c23a9c74a5e642L,0x466ff55f2e70a453L, + 0x327fd5fd28ea7af7L,0xc96bfbec6e658256L,0xaf194fe8c0a3b932L } }, + /* 20 << 84 */ + { { 0xcf63d27951c0d95eL,0x3b170a0bac86a014L,0xc21eaaa9881095e1L, + 0xed2fda116069a3ebL,0x536264b9bd2f1c5aL,0x819e1cffde312c2cL }, + { 0x6c30f983dfd6ce38L,0x2f32cc4c980b439eL,0x9fab10b63b9c03b2L, + 0xdfebe34e011ab74aL,0x587360e3b80963f6L,0x3db1f6108692e352L } }, + /* 21 << 84 */ + { { 0xf262f2379765908aL,0x76f8d0017d03cdcbL,0xdbcadfb22f35de21L, + 0x88d5bf592a73815aL,0xc4f4e3b02b1bab82L,0xf5cce885b9635dcbL }, + { 0x110a785875a416dbL,0xfe7e6c360adb01feL,0xa02642c01374d779L, + 0x9010758753bb5898L,0x0c764ed2a363fcf2L,0x24a2a5541700e551L } }, + /* 22 << 84 */ + { { 0x63a094c5fe3d070bL,0xf769b91988515eb1L,0xafe86e1450d1131dL, + 0x6bf277886774d3d4L,0x7231d699ffd805d0L,0x05132e5b6304116eL }, + { 0x3d5e255be34ce5bcL,0xfd9c3bd0c95e3089L,0x22a24023b83cbac9L, + 0xfb6d2b6fb0b3b98aL,0x74af1115f7e36fcdL,0xcfe15eaff9da3bf0L } }, + /* 23 << 84 */ + { { 0xb242ffd61da39f60L,0xd0ed946320cac1b3L,0x9ebd5e46e25f809fL, + 0xc7df7e5a07f5aa4eL,0x5eea38d791a5f85dL,0x6240f01d6080442fL }, + { 0x72ec0a5e251d866fL,0xd3e4acbebf2c0037L,0x0d4f47c90fd962d7L, + 0xece7c047b8de2dfbL,0x841050b96df17f0fL,0x567c3df7e933a4d5L } }, + /* 24 << 84 */ + { { 0x266d2c1cbb2fcdaeL,0xb538d4a252be93f2L,0x774c88ba73bd0094L, + 0x65283a9b81a7e042L,0xe1438bbfd0381625L,0x450e1f644d0db206L }, + { 0xb38ae9ef4e60fc4aL,0x14ce87e112719817L,0x831d41ec570303f0L, + 0x7172917028850444L,0x2077ea32ccd609f5L,0x091d1166cd273fdcL } }, + /* 25 << 84 */ + { { 0xaf5916f49412edcbL,0x9ccc0dc08f01b2d9L,0xbed1fdd42dd737c8L, + 0x29d26cab95a21501L,0xff38bf18c70f1364L,0x0bdb055876879b06L }, + { 0x706031e2a14164d8L,0xe229fce1fc39648bL,0x5ebc640878e97c8bL, + 0x26039bda822de18fL,0xab992da4b9f090d7L,0xf409432d53eb438eL } }, + /* 26 << 84 */ + { { 0xdf216dd84b2ca517L,0xb3eec4b9c6b74c4dL,0xf564e6c81c14e77bL, + 0xcde25f1c2c2c9395L,0x7e31f7a5049fcc83L,0x6913707b9284c753L }, + { 0xb92a6f2458e6eb5fL,0x85b0cab595148292L,0xeaad036d7449be92L, + 0x2f6a2888eb94a702L,0xd7d8773d47d59fb0L,0x612d257303c0bf25L } }, + /* 27 << 84 */ + { { 0x805ece910ea742f6L,0x54486a6ffb5dba94L,0xaceb0eebbae52f76L, + 0x2200fd85e98794f0L,0x44bd993ef305af19L,0x28f256738eb8baceL }, + { 0x5d3fabbadc5f9c18L,0x4338f79c1b003ed1L,0xaf4b0566bc20c65aL, + 0xded9407c3045d1bbL,0xe8713d7506391eb2L,0x557d62c971307365L } }, + /* 28 << 84 */ + { { 0xb872a10584d2c3bbL,0x44bca57139196026L,0x857327d84e352e5dL, + 0xa6c6004ad925f99fL,0x48aaf266bab79eadL,0x213ad923adab2a3fL }, + { 0x3be29b6df371cc48L,0xe732b9062385c9f4L,0x562e0be123f0a84eL, + 0xbb6b017228c4b0dbL,0x71a93ae5f4c6d8beL,0x76b8bb16551f1fe9L } }, + /* 29 << 84 */ + { { 0xd028d9b5242002c2L,0xea105054823783caL,0x01cf8a491d45c34fL, + 0x1035835e42457869L,0x0a95049661cc1e05L,0x9dce5bd3b439afc2L }, + { 0x8552f02003b18e4fL,0x4973e3bde6144805L,0x29fb98d8d8514c4eL, + 0x0ce0e8d83ca27b39L,0x7aaf3f5284bbc6caL,0x0572bf40d78c7c5bL } }, + /* 30 << 84 */ + { { 0xbbfaaa94c39926a8L,0xb9a59fdb60a138aaL,0x217a1aa2947e30e9L, + 0xcac988c9c52c9fffL,0x5676473a3bae3c39L,0x7d84b353857f04c9L }, + { 0xdeded30cdd324e24L,0xf07c678a9c242899L,0x956d05538cb64f3bL, + 0x9d34e2f5502cb2b0L,0x99e1054a51dd03b3L,0x86b8bfa54d60a593L } }, + /* 31 << 84 */ + { { 0x3dcd2df9c8870c4eL,0x7cfdd05f1699cd0fL,0x19e9ccf027e79e0fL, + 0x56e997027b85d75eL,0x407b5b74ccadcf9cL,0xc961a336297dda7aL }, + { 0x350c34d56d12d17bL,0xe37de9a93bc6afe9L,0xd2c7339e0d641d3fL, + 0x2700f39cf7dfa063L,0x2916f9ad8ddef077L,0xffec6230547cdbebL } }, + /* 32 << 84 */ + { { 0x10a53b90754d15e9L,0x6cde9a0c5f4c7218L,0x740d513fabef2b96L, + 0xff6cc47cd3f802fdL,0x1be6825beb0627afL,0xdb21ede55886c2dcL }, + { 0xb6cfb2c6f5daaed7L,0x68b61aa8fae29a9cL,0x7a1e16f53a5a485bL, + 0x16b60b92e7b2223eL,0x332f33d836a13a9bL,0x4567c313876cd1a2L } }, + /* 33 << 84 */ + { { 0x7663402de62014a2L,0xbffe1e7fc4efd224L,0x2080eb02c38f766dL, + 0x6c95529ba9641db9L,0x24dc13a5c68de8e5L,0xca219b3fbbc3016bL }, + { 0xb83450e310b634e0L,0x8cd26d775b097a34L,0xb912c34564c9884fL, + 0x3d1f28be5bd75f1eL,0xdcba2b479466ea59L,0x4077e017ca9948e3L } }, + /* 34 << 84 */ + { { 0xb4b2c65df91c7972L,0xabe915496b689013L,0x4eb7afa8d506333bL, + 0xc2f2ac1d648e7c0aL,0xc6bc96b1213cc243L,0x0b827c2189e44025L }, + { 0x2e866601cadee87dL,0x8ee85356b4719ce3L,0xefda7427b4fc0081L, + 0x0d5c33c4c802c92dL,0x4c8635ab58515f01L,0x9d7ed87edd0ab04fL } }, + /* 35 << 84 */ + { { 0x9a660794cda4cadfL,0x70784fff2484a3b3L,0x8ed664ad2de7de13L, + 0xbaff5937030d906eL,0x884407034ab43a4fL,0x86dfdd53ee09795bL }, + { 0xcffa6852fb0e889cL,0xd94373e1e8c9fb95L,0xecc0ea249b0e3ac1L, + 0xe88eda6eaa89e492L,0xbb049803da19207cL,0xfbb0c3874bbb5be6L } }, + /* 36 << 84 */ + { { 0x3e2bdd9b5a5f6b4dL,0x30cf4762ab005a55L,0x8736f5188bacd78cL, + 0x8a5a647b09dc21fdL,0xfba40c38ca06c1fcL,0x63d53fb64a4e1524L }, + { 0xe77d07a19a2bd706L,0x54144ea7bbe30e86L,0x8eb606220bd955a4L, + 0xf689cc80b3c26cafL,0xc70fe95c9fefcbbfL,0x67f9e8e2495b5bdeL } }, + /* 37 << 84 */ + { { 0x04361e6b2e4d2cf9L,0xdbd3cc13ade11ba7L,0x93dc1d1df47d8ae0L, + 0x7d46bba6fbb2d65dL,0x797ea0df92e97abdL,0x09eb3975a712e8cdL }, + { 0x9ab3a54e0380cf8fL,0xcd1a9574c96710b1L,0x6abcd1a1dc13dbfaL, + 0x1be0db71c2ee67f9L,0xee8ec8d0c2ac89a5L,0xbc363f407da201f5L } }, + /* 38 << 84 */ + { { 0xc86c049bbbef377cL,0x43df6f3703de56a7L,0x01eced2b558e516fL, + 0x18fca0bdb43c1cc0L,0xd8c6f7ff62121c68L,0xb2f1f1ac36f90713L }, + { 0x5f876328ea1bbd95L,0x9f22dd535ac4ce8cL,0x7e052acc7df88002L, + 0xedf21fb7068d46a4L,0x349130a21d7d0220L,0xcccc79beaaa68eebL } }, + /* 39 << 84 */ + { { 0x9c955b5eb4100632L,0x8d6dd2d3ccd99a0eL,0x700f827c265dd397L, + 0x5540bc0cfc85a2c1L,0x6d4b8e7adfb81661L,0xfbfe1ebe1d5c1485L }, + { 0x322c2883c9dc1b6cL,0xc7c897cdfd7e0f34L,0xe70b0586030e41aeL, + 0x4263e06e26a728b7L,0x0ee2b93392387542L,0xae708ccaf6220511L } }, + /* 40 << 84 */ + { { 0x05ff8b9cbc15ae37L,0x94dc2e85d06d62edL,0xea1d1c8b4b02607dL, + 0x1fc202a224da757cL,0xbd5180bb35440e69L,0x0263dd51698ee7a5L }, + { 0xbe93f27654013d74L,0xa7c041c464e81695L,0xbb170ac13ba5336fL, + 0x1aadf302af84dfa1L,0xeda58747c960788fL,0xb456070e5eefc35eL } }, + /* 41 << 84 */ + { { 0xa905d421800ed69aL,0xdb8a643813622898L,0xd003affbdaab0769L, + 0x467bc051f0aed9d3L,0xed1e6951b11085d3L,0x7a1d1152d3f54fc5L }, + { 0x8cb243b6dc8dd008L,0xf9c690d1f409210dL,0x9a3195399461aee0L, + 0xf580724dbc2e4de0L,0x52f648e4e759556fL,0x235a79f2697885d6L } }, + /* 42 << 84 */ + { { 0xb293d3fe8220ceb2L,0xace20e7e049a33a9L,0xa584ad52af4198d6L, + 0x49c5cde64aa0a5c6L,0xc4f7877ecee2e664L,0xe1557968bb98ed87L }, + { 0x69b0cd713066000dL,0x1af188cbc7399f29L,0x5b88b85c306188a3L, + 0xcffa28eb4097182dL,0xdb01149ec80d0aa9L,0x9f8e6d59402bc397L } }, + /* 43 << 84 */ + { { 0xa646077bd5b97d37L,0x618df84461cfbd95L,0x3a9fe2f447c62894L, + 0x7f2760eb4e0f1612L,0x50c08fdb36e5acf1L,0xac799584675d2aabL }, + { 0x3eba6f54917dd606L,0xf585fa5075119ed9L,0xb047abfca32016bcL, + 0x61c03e51aca118f0L,0xef9fcc526dc13766L,0xd849eca5e8a3fb72L } }, + /* 44 << 84 */ + { { 0x11ac1ff4147faf46L,0x5dd8913882b818f4L,0xe439f66fb15fe5a2L, + 0xadf913a5fe8fb45aL,0x3dc708404a6bbdb0L,0xe8e1204da4af4ac5L }, + { 0x4be549318ba70502L,0x945d9a765883b39bL,0x99cb1c721a76198bL, + 0x96fbed479a7949e2L,0x30ee96ebf0299bc4L,0xb7dc5e76d3dd160cL } }, + /* 45 << 84 */ + { { 0x85eca39b0c88d5feL,0x96000863af9e0158L,0xbb13f99c4509590eL, + 0x50033c18034e2499L,0x1e9346f87b86cb33L,0x917d88b4aca548e0L }, + { 0x0c422c2e9e2a7e15L,0x6751c95c5e37fb06L,0x631361b8c40d21b7L, + 0xe231858ec9958deeL,0xae86abc54d9936e3L,0x60c78d1137bf9213L } }, + /* 46 << 84 */ + { { 0xa0bcb7c6283190a9L,0x36c884ffc53fe76eL,0x071d4acab23f0865L, + 0xd44e3c20e14a82f5L,0x704dadd8968d28bbL,0xb40d2b948e88ad61L }, + { 0x4a29142ff3de62f8L,0xdd071910bd7292a8L,0x5b12c32d5b3571c9L, + 0xe9886262943c6aecL,0xc49b7506cb1e0a33L,0x87f6c2d3de95886cL } }, + /* 47 << 84 */ + { { 0x44ba232e010f465cL,0xb82486c69ac91d38L,0xcd1a6bf75de743f5L, + 0xe050232838acbc4bL,0x8de9c29631fb87b5L,0x9c8029250450c4efL }, + { 0x19ee1607635e64a6L,0xeff5478c69ed7f8eL,0x311201a027001c21L, + 0xfc0382a78beb55ecL,0x494b623ce9dea7f8L,0x926a3f756767f769L } }, + /* 48 << 84 */ + { { 0x802f495cee46f99bL,0x0f3ad0ee43b91cbbL,0xeaf3b294e9b3f0f6L, + 0x82cc760033cbdcd1L,0x1a5642278e83fce5L,0xcf1b2edaffa0e4ccL }, + { 0x7d93e9769b1f5706L,0xe4eb843cf873d68eL,0xcb53dd79eafe5f35L, + 0xcbbed8f0fcaafabbL,0x570472705f053efeL,0x2c71a95f1ebfeb7aL } }, + /* 49 << 84 */ + { { 0x02d4717ddd7a5499L,0x3bc8bdcb9966236bL,0x13f08015fd27be15L, + 0xe05236f6baaff392L,0xf73bab3f7b4cc522L,0x8ad26d4552ccc027L }, + { 0x79f8e79e9e9ccd7fL,0x8011b92aab2f22d9L,0x6aef576e729662e5L, + 0x7d5194d05e568f55L,0x2947d63a1a40860bL,0xe9890f1440305b54L } }, + /* 50 << 84 */ + { { 0x8085614c0fa9602eL,0x9ee1b9b26651c4ffL,0x65dd9c94ec048f1bL, + 0x10b4a62f6d6c0fd7L,0x61469fb7d391dcd2L,0xdf751399edc3d431L }, + { 0xe3901315c913acbbL,0x31581d7a90976644L,0xf20809634aee5cecL, + 0xaa716eafe5408c5dL,0x9e356989b9a60ad7L,0x2d6e7733a6a3c977L } }, + /* 51 << 84 */ + { { 0xd6d99f54f19b8464L,0x3322a0b8a0be5c3bL,0x6cff730557e98725L, + 0x786709c7953a357dL,0x3864d278a1013652L,0xf7471f111738f6e6L }, + { 0x0377a923984c465aL,0x4a24b9e14ba970e2L,0xe53dd9f21c01d248L, + 0xf422b754fbffc0d5L,0xae25dc0ec6a956b0L,0x3c3fef96ce806445L } }, + /* 52 << 84 */ + { { 0x6a69d207b5906d71L,0xf3c757ed8964e1b1L,0xdae255af5f98821fL, + 0x6c801ed4db1af96aL,0xd12430343d109b86L,0x4b2aa65fa091f98dL }, + { 0xd9bb4c2132dcb5f9L,0xe5a5979bf190a1e0L,0x0861e5de40117a91L, + 0x8753c9adc39120e4L,0xfdcb09f4aeb4a18fL,0xdbda38746bd1fd08L } }, + /* 53 << 84 */ + { { 0x1bd8e8c0304f7045L,0x8ffcf24eedbd2dd0L,0x13c9441de6ae4dadL, + 0x5efb70aab418c02dL,0x9d0fede1b8cf6949L,0x613545cf41f5aec0L }, + { 0x4e3342244b98bddeL,0x7d0c11110fd8aaf9L,0x30c2bedcdfb8643cL, + 0x875d386aa83e493fL,0x85b32632d6cd0825L,0x9f1ef3a01445507dL } }, + /* 54 << 84 */ + { { 0x2b70440e54f6b8d9L,0x355e692430eddda5L,0x354e7cfbc9199910L, + 0x7e8933bfdc7de946L,0xc5692fa981b9eaabL,0x2eb58fff98cf5f21L }, + { 0xd0d8f9bb96b19d59L,0x779aad414d1a6285L,0x0cee1a9b5eb87c49L, + 0x676e36ff786c4c81L,0x6618c8f112d34964L,0x2061186dd03e9562L } }, + /* 55 << 84 */ + { { 0xa5ae40977da39b54L,0x98e4d1d9f1d40635L,0x40d97af126154fc6L, + 0xf18041d4e9ae28c3L,0xdca9487555978c61L,0x4aaddec43638b9b6L }, + { 0x1e615a2eab925f91L,0x5cfbbe9ded8a50faL,0x0f26d3ffb2034aa1L, + 0xb2f9cee2c4813646L,0x2195af47957b6709L,0xa55dac537e7fc45fL } }, + /* 56 << 84 */ + { { 0xe44a8ed7630816b2L,0x5fb9b643cca34310L,0x07826148a3b5d2e2L, + 0x0f890db16e65c2efL,0xe9feebe288283844L,0x8e56c6760368a9f4L }, + { 0x8f0cc9c93e4ce874L,0x646ede9b09f1beffL,0xe92d6bda014e3d19L, + 0x27e620c5520c921fL,0xfd9b2ae1eed78555L,0x68684615816a603eL } }, + /* 57 << 84 */ + { { 0xcf54e9e89ded00c7L,0x8dff0130abbf7765L,0xf12773fb10c5f8d0L, + 0x7435ac767382e4eaL,0x93092b16f61d443fL,0xc1554fa846eb45cdL }, + { 0x0896852c30957ca5L,0xc0d91e3effe60944L,0xce8aee57a1b7c75eL, + 0x4d24f07007cd1a9eL,0x3d8e381094456b11L,0xed6fba6b9dbc9d0dL } }, + /* 58 << 84 */ + { { 0x1b1de3ed8b5b8f82L,0xf542399d64252363L,0x23f34cccd206f26fL, + 0x54c48d9fbd941d6fL,0x3859eb56202e757bL,0xedcb4729ae0eaf7aL }, + { 0xf08753c512360fceL,0xf37ece765f697cd4L,0x073cae01c98a7c8bL, + 0x6e298559df664bdaL,0xe8cefd27194b103cL,0x56301e2a811f6a71L } }, + /* 59 << 84 */ + { { 0x8103c6053d3fe586L,0x472885b3999bb4caL,0x3759d2d492a2834aL, + 0xaa4eb3acd46cca1bL,0xcb99aaba633e579dL,0xf9369b033d6dc569L }, + { 0x55fdb1fe8398c067L,0xd7aab8b47e6826ceL,0x7f5497bd8b525561L, + 0x2e0e1e9c2cd0e3beL,0x3142a6e2c47caf5aL,0xe78cb1840f4b802fL } }, + /* 60 << 84 */ + { { 0x0a1577baf455f6bcL,0xaeeea79094df32b3L,0x1af3ba0f6bbb15ceL, + 0xaab92a74e8522659L,0x84087a8f7efa0a4fL,0x83c6991b84596065L }, + { 0x11f7829d29fbb626L,0x32b04b2f86031974L,0xf3a5b8722c1291deL, + 0x2ffcc97e8bd2be43L,0x575400d10a206f7cL,0xbb4583de0befbce6L } }, + /* 61 << 84 */ + { { 0xd448eafaab983fd7L,0x2622336c7a18a7e0L,0x36632e221c274b3cL, + 0xe64e8f89bf086fcfL,0x1dced08fef72ebd9L,0x61249c25ea295d31L }, + { 0x7433743d3755632aL,0x9d766243ff32ed08L,0xc36e816a977b1d9aL, + 0x1069fc0820ccec81L,0xbd4af7bef65a0cd8L,0xd04127fc92e31836L } }, + /* 62 << 84 */ + { { 0x39560937ea57ca46L,0xe1f2b7198229d346L,0x462b28d4dd02dcbfL, + 0x510fce98a333d609L,0x795fbd38fefa05beL,0xd6e34c231bcb029dL }, + { 0xf33291fc838f7ec3L,0x2a01a1f5f16e7247L,0xf9737722c0bcb3cdL, + 0xc53ef57ecc8a6c77L,0x219372afc750f1a7L,0x3e6a97c3d14e60bcL } }, + /* 63 << 84 */ + { { 0x87278f062db3d752L,0x64c65f5cd106b7a8L,0x04ccc14d41ee7aebL, + 0x72d1189e71952b60L,0x2e88f851080e9ea8L,0x625a6d32913e8df4L }, + { 0xd943de73900ee95dL,0x6c12b3b3ecb8b3a0L,0x6209daf2c9b141e8L, + 0x81c02f71412da959L,0x222d17b747278f65L,0xaa338805789138e1L } }, + /* 64 << 84 */ + { { 0xa896d28e4aea3fa2L,0xc6137a456db06ee9L,0x1bbafe8c06fb15ccL, + 0x2daab2961cdffdadL,0x984defc8e1119b3aL,0x9cd44c3cde2a25a3L }, + { 0xa7f54ece54ed6d73L,0xd283017f50907054L,0x69130efc6a3b9442L, + 0x5d17f1276785163bL,0xc019911b172b1d0aL,0xa19c745f7e3e093cL } }, + /* 0 << 91 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 91 */ + { { 0xe185bdc2ab83d932L,0x0a75845dd7c4e754L,0x1f6f3397c3fe5695L, + 0x6c9f3a5f61f6a04fL,0x3c0f9d4bb390a92bL,0x9e3336b74793b454L }, + { 0x91ad0c341472f06bL,0x4110047a892cbdd7L,0xfa24d90565d53c83L, + 0xd63e58334176007dL,0x741089fd2cd1623cL,0x6b3d92022685d345L } }, + /* 2 << 91 */ + { { 0x1d510157c9cb7f6dL,0x532a077346ab7372L,0x2ea07e2fc6dde9e2L, + 0xceed9ad937d5bb1fL,0x3121994b98cc6e28L,0x67d2fbb567ad8fc4L }, + { 0x34707fb3dc9f195dL,0x6a601f481fd5a013L,0xfe939b8d81ef6cb5L, + 0x5c51e8ab1223a9a1L,0x8f6d7993db74cf37L,0x0b81c5b7972808e1L } }, + /* 3 << 91 */ + { { 0xcb4e85123bf921afL,0x28fc6332532e81d3L,0x682d8637f69f907dL, + 0xbd9fa8f45f759a16L,0x091ea9fa51f03716L,0xd685a14132c630e9L }, + { 0x7600c9ac3d249cf4L,0x687e2022002cd2b5L,0x7ec205ab55334058L, + 0x9d0d86b13ecf1368L,0xb3fc17a7fc7baf6dL,0x57939961361c91cdL } }, + /* 4 << 91 */ + { { 0x0db33228010c0754L,0x10635ffa8eca7c59L,0x6efd85380e8a38faL, + 0xc1812ea5769360d8L,0x505723dc76f27ef5L,0xd0358e02f35af2e8L }, + { 0x9f7bb7fed99419eeL,0x87c66e83430a0e2dL,0x01187549773eaf7fL, + 0x05bbbba489d51bdaL,0x52cabb06640ccde6L,0x0d5cb557e7ff387dL } }, + /* 5 << 91 */ + { { 0x709d61ca10e06f1aL,0xaa1e9fc578eba75cL,0xf85d062f914b2cfcL, + 0xe73b3baf9089d85cL,0x4ac05feac4a284b9L,0x92c78a433acb7268L }, + { 0x7b5586f8ee45bb4dL,0xc39a0d0e6ac0a9e7L,0xe4bbe3d54d6f9ab8L, + 0x1489463f1fd46a08L,0x3ba3182529dba364L,0x94f000d68138511bL } }, + /* 6 << 91 */ + { { 0x70187dfbc39c1cefL,0xa785216e0c50c71eL,0x30188b816a6c0d60L, + 0xeaeda67d6a27e97bL,0x4a5192826ba389aaL,0xb96c7c7ea2bf1273L }, + { 0x8ff10657267fe714L,0xdff4a271996d91b7L,0xe34ba3e11dc7aed4L, + 0xc457048b38853d61L,0xe89825db1ccbf658L,0x68c7b4556b255eddL } }, + /* 7 << 91 */ + { { 0xdc14cb2a74871e18L,0x017b1340fcb8974aL,0xea5cb0546e93c20fL, + 0xa7c078ada9e2ad1fL,0xa37207d4beb26838L,0xcd8b3b25de7ee8eeL }, + { 0xdca6606a2801a7ffL,0xad2fedcf0f8af3faL,0xf27d30b49b530c05L, + 0x071fc1c36b2a4613L,0x363aaa99b72cea9fL,0x7a33ed8f3d350374L } }, + /* 8 << 91 */ + { { 0xc377b373bb20fabfL,0x68d3aa52f986b847L,0xd9c2f2adf39b6894L, + 0x1bbff106bd6da22eL,0x3f7e5b8e7e09678eL,0xad6a87897ed3ee78L }, + { 0x689e6b31af9807b9L,0xeca87778bd1f6ef2L,0x17d3277edda78c54L, + 0xe686caccefb65cb7L,0x758aa1ab19a30f0cL,0xb40df97fb11f071eL } }, + /* 9 << 91 */ + { { 0x43b379f71a54cd32L,0xd61fe6c948817fa8L,0x6d7b0acc49ab7a6cL, + 0xee23b4a0eb6bb45fL,0x340da1f1a2bda931L,0xfdff68411750ea8dL }, + { 0x890346b8a96c7df8L,0x551993aed4fafc31L,0x2830b98890de711fL, + 0x4d23863cfb5b5286L,0x327161a0d636d67cL,0xf99dded9733e1725L } }, + /* 10 << 91 */ + { { 0x0bef2d2517da64c9L,0xb94dfc85470bbc15L,0x2c2417cedd4af7aeL, + 0x52b5b3bbc8e88ca4L,0xc00328c44f20d154L,0x024290f730af5d4bL }, + { 0xe8bacbebeefc7350L,0x89eed6ebb72abd15L,0xb67d1da61d9e7030L, + 0x2ddefcbc0e70a331L,0x7d09bc6d61e32577L,0xc2073cc95b52e979L } }, + /* 11 << 91 */ + { { 0x585939298b806bfaL,0x608ddfbfbce6a08aL,0x674545a08eb27b54L, + 0x4b57a947c8fba762L,0xcf960113cbd8c683L,0x7b5a479a4fef1937L }, + { 0xe26eb960450e97f1L,0xf04b36b9d8605a37L,0xb208c832ee5af2b3L, + 0x3578d3a71fa337e3L,0x22547fca93509939L,0xd93dcb50e848508aL } }, + /* 12 << 91 */ + { { 0xd40f36e6276f2576L,0xd37455c46405cfe4L,0xe34094d7cc51dbaeL, + 0x20f93f0f0edf8bf9L,0x534b75aa23b5e165L,0x438e4dd1dc1b73a8L }, + { 0x9dd48c413bddb435L,0xc49867a0996b4932L,0x4212f8a2a9ffa0daL, + 0x8d5236c4d94ed9bdL,0x81bec489f169cb19L,0x71cc1d7e6104edfcL } }, + /* 13 << 91 */ + { { 0x31a94a7f22771941L,0xa277284b39867dc3L,0xc66bd88b1a52f0f1L, + 0xd2e2707b1aa21ee8L,0x78e4f280248d61e2L,0x33df48c7596a31f9L }, + { 0xb9bf2baab1bb1e89L,0xe1bbcdb4038f10e2L,0x81f674a877b89305L, + 0x8b2ec6ee16f08a86L,0xa07239c29db97ceaL,0x9f4ae6647ef8ecbcL } }, + /* 14 << 91 */ + { { 0x9cb21b57012eaba3L,0xcfce54821347a83aL,0xe3f3a67100d7b34bL, + 0xd4bcb3d1a6c1b0c3L,0x6ebd26fb9f3c3e31L,0xd01746532dc79be8L }, + { 0xe7cf9a0ad4156cfdL,0x2757cb0416face21L,0x8b0e320e69e1f08bL, + 0x2a8caf9b946f83d7L,0x6daff0ba98a399adL,0xb4dfea0938ed6086L } }, + /* 15 << 91 */ + { { 0x90ed8b41e2bcf8ceL,0xa464972be8dcc1a6L,0x5a3d0b80ba496081L, + 0xb636435569f85ac8L,0x0a2765b1a25bdd8aL,0x87a6c18f0d1516bcL }, + { 0x9344081ae3b01522L,0xcef8e12e608f0145L,0x6f3566a52155e7deL, + 0xcfc1be9c4d033a3eL,0xfc836eeaab97bf98L,0xbdf53718ba7dd059L } }, + /* 16 << 91 */ + { { 0x16f3708b953b9223L,0x0d3780f8770e7cf3L,0x97a615b227bb71a8L, + 0xa8b9a864162f8b55L,0x80ee8362d91e3fb9L,0xb2009a09f83a4ff6L }, + { 0x07a7873ac1696281L,0x17ff00c223095ddcL,0x427f683d860d60baL, + 0xea9959271f87d32aL,0xb2ac69faa050319dL,0x30c362b9d2d0b9ceL } }, + /* 17 << 91 */ + { { 0xe05c6a88783508b6L,0xa5569c8ee1779a78L,0xa1e0ca30cc1e84ceL, + 0x12ecb540337cca76L,0xafb5e2fb344d729fL,0x558db4e132c8f80bL }, + { 0x5aa3c39523128383L,0x9f04757cee1ee2fbL,0x41132bd215356deaL, + 0x4e9af313ae07ca78L,0xdfc14c0100c6b589L,0x54fdb4f3dc16a1f1L } }, + /* 18 << 91 */ + { { 0x71e663c234938279L,0x9a8f5ccdb05630f4L,0xd91ead12aad70096L, + 0x2b19b27e9e46cf72L,0x93348c7038e3932dL,0xeab6c03a5c7617b4L }, + { 0x57c13a97538eab27L,0x2624d17b2f5872f7L,0x77b63d9104b00f8eL, + 0x2e0582473c89db0fL,0x5d367277937d0d8aL,0x28c19068df60c252L } }, + /* 19 << 91 */ + { { 0x9867bc3d38cd6020L,0x5f341d8c5986f76cL,0x108a3c0d0dab2e32L, + 0xd127a7f989ab3654L,0x9d5018f468505cecL,0x51204da0a8fc94a4L }, + { 0x1751f30cf6da9840L,0xafe6a8d955ed1f74L,0x270a5d1180165ac5L, + 0x739f63e05de1e17bL,0xaa95f30735d2b566L,0xf20dd093650236a9L } }, + /* 20 << 91 */ + { { 0xd648dd79ee45d4b1L,0x0ceeaa64c2bc2f0aL,0x695f3a3f491a2862L, + 0x4c07e2e0ce497e3dL,0x5c53879969c766c2L,0x3f856a2e4c4a7c14L }, + { 0xbf8a6d81038032a9L,0xbeaadd7f45b7c960L,0x78b22e85d50b9d26L, + 0xac1c56fa7eaefe26L,0x21fbce54fc69f13dL,0x37be1b47512a3708L } }, + /* 21 << 91 */ + { { 0x12845d55689429afL,0x7e20f0f9082c8ac8L,0xe1615340249773b6L, + 0xf66c39638d0f35afL,0x4a20ce6d67d27093L,0x1d462f08e55802caL }, + { 0x66f209849ff4dd67L,0x6b86f8d8271c57b3L,0x8701a5cde766b85bL, + 0x50737ac2eea5fbfaL,0xb46ebb42a702f3d6L,0xf853091d999258bcL } }, + /* 22 << 91 */ + { { 0x0ce992198c9e7869L,0x653006be525c4adaL,0x783620e4330c402dL, + 0x185a6ac833b728b5L,0xa297c4a99d390886L,0x547d1db5db4b8123L }, + { 0xccf12f071acdb039L,0xe89c5866078ddc28L,0x3460cbb1e52c383fL, + 0x7a4d1beaad25b82cL,0x21e243fdb429be1bL,0x5aa85c25bdc0d798L } }, + /* 23 << 91 */ + { { 0x76cf73b9c0db9d16L,0x45e57cdc1970ace6L,0x3c6f5314c54a109aL, + 0xe32306f7da47cbfbL,0xb3787bdf93e76516L,0x68aa80084c6d4e22L }, + { 0xd9246ddcb3d37be7L,0x6de2bb4d7000f1abL,0xda02568b67e4751dL, + 0x3ed7a5615c7f88f4L,0x5f05c828ca5116caL,0x139cc5772a2ebb9aL } }, + /* 24 << 91 */ + { { 0xc983afb64cb8d897L,0x7f05e954b14cc152L,0x587fe71e0f4d02f5L, + 0xaaa43167531b0cd8L,0xf69452727a26def9L,0x7ecf1e563bab50e2L }, + { 0x04b6f5c94c6f20abL,0xbc6cec2b893b497bL,0x79e89567c9dc548aL, + 0xa39a0a567a40b749L,0xf1531e2644bd4efaL,0x14cdd759057c7c70L } }, + /* 25 << 91 */ + { { 0x30c49847d6d51bbbL,0x70b744feecdc6aeaL,0x38cdf36fe8671744L, + 0x5834286b8cf6461fL,0xf3414f7b2c09d632L,0x58425e4d5debb923L }, + { 0x8bd79117a6b96c6bL,0xecf9802680f56fa8L,0x5ae917d7e6dcbbf8L, + 0xf2d80fb169240a4bL,0x005ac47596e3aa3aL,0xe5196a3463536aa9L } }, + /* 26 << 91 */ + { { 0x5fb02929811d42bdL,0xd7d1b956289929b4L,0xfd3546947e531627L, + 0xa37c9b1e58c2b2e2L,0xf30ed0f902bf499bL,0x3fe80d240eb6df36L }, + { 0xf96270e57b148672L,0x47362483647f48d8L,0xc279ece6c29bc59cL, + 0xc05c1d9ffdd7e628L,0xef8fc92e17568a7eL,0xd65fe5a9ec0e7f00L } }, + /* 27 << 91 */ + { { 0x0ad31de68c93f010L,0x151b1405945ec54cL,0x325d132c3db6997cL, + 0xbed9cb3a335531e7L,0xa83932c34a578610L,0xd905abbf6f721147L }, + { 0x6dd45af086d1d919L,0x2b2ee3090195e91bL,0x3dc30d5edb70d257L, + 0xfb04b014481bde1aL,0xc2ac3ec82de2debeL,0xc9f161e090db691eL } }, + /* 28 << 91 */ + { { 0x8041f112afefdee1L,0x8cab3c86b891f668L,0x1f18774e2b61e754L, + 0xf0d81b2459df567cL,0x2cc25da41c95e1ecL,0x315b1b1ac735d39eL }, + { 0xd0a9b9fb010734cfL,0xeefc0398c79386daL,0x49ce859b11fb1917L, + 0x3d66fd6baf167239L,0x2522b0ef1fea6175L,0x1a27657d3ec4a52dL } }, + /* 29 << 91 */ + { { 0x89ec003abb2ca05dL,0x2290b5f403195ec6L,0x9989bd925f6b95b5L, + 0x1d6e6b2fad409cd9L,0x41f9b9ce3bfe7364L,0xb240f89570ec096cL }, + { 0xf8725a58b8d5a5d6L,0x3bfec6f1c581930dL,0xc93e290356235c98L, + 0x82af4269c7cdcb5cL,0xeb13fa40eea6fe91L,0x9247050097c80acdL } }, + /* 30 << 91 */ + { { 0x48dc23534ded5b58L,0x1b69590756e707caL,0xbbcb73927ec7794fL, + 0x3714dfa6e50dbcc8L,0x4f8083c8f27ec5d7L,0x6358d2273bc8c3e4L }, + { 0xe0c2a0e7656cf184L,0x3996e0a24244d801L,0xa46767b54e543c01L, + 0xbf55776d965f1e2fL,0xeb66845e6bc872eeL,0x6a73fef1b441895cL } }, + /* 31 << 91 */ + { { 0x21602e432b26bbf2L,0x6092d570d1bfd7e2L,0x2b48d74a30b38d1fL, + 0x4aab113c67c53791L,0xa6acbd3df57be611L,0x53b6509ebd3aae7eL }, + { 0x047e5ab4d8751f49L,0x978ed11b0cf25652L,0x763553d2153619c7L, + 0xc7e85e93d824d943L,0xb82cc9781048a7ebL,0x7beb9166e39cc777L } }, + /* 32 << 91 */ + { { 0x24480c57f26feef9L,0xc31a26943a0e1240L,0x735002c3273e2bc7L, + 0x8c42e9c53ef1ed4cL,0x028babf67f4948e8L,0x6a502f438a978632L }, + { 0xf5f13a46b74536feL,0x1d218babd8a9f0ebL,0x30f36bcc37232768L, + 0xc5317b31576e8c18L,0xef1d57a69bbcb766L,0x917c4930b3e3d4dcL } }, + /* 33 << 91 */ + { { 0xf6625ac0b9a038e8L,0x954056eb2a921e56L,0x7135295aeac07bc6L, + 0xedde9c39f1ba0ea8L,0x628324026b592655L,0x4603177aefb8aa66L }, + { 0x63e5ea16406a6c28L,0x5897fdee1c758382L,0x515e49fd415533c9L, + 0x0a0dd627d6701b21L,0xd7c06db1c93a312eL,0x4fe95e3da33d8df7L } }, + /* 34 << 91 */ + { { 0xf113d92c3336edc5L,0x0a201f3e8ce47278L,0x57492feb5c52562fL, + 0x18b73800f29da837L,0x2262089f649a1ee8L,0x076b07657c99bf48L }, + { 0xa95050bc09bfad20L,0x5aeaa9088c7e713cL,0x264283ed3cda06ccL, + 0x5d574b116079b43dL,0x0071495cced10a84L,0x97441fb0570d3063L } }, + /* 35 << 91 */ + { { 0x340831072b228335L,0x84ea0aba50fbd43dL,0xafde6098b3ec91e4L, + 0x4fd293ca1091ad93L,0xee085e23552a785bL,0x437d799ed7057200L }, + { 0x41f735628a611ff4L,0x707a7cb5d2ef6254L,0xa9a8f00092a30686L, + 0x901cc8e60cea8d1dL,0x1fbc9ca6d6da2ddcL,0x61bcee2176489604L } }, + /* 36 << 91 */ + { { 0x5f6ef134781a7f53L,0xbac4cf47b10a9d16L,0x48148ba110e69f4eL, + 0x40594360a9c615f0L,0x3141817ddfb3fc58L,0xb9579a9263c38d83L }, + { 0x0544b1bb6373b9aeL,0x718a5fb7007c8185L,0x48d4a4f77cfa392aL, + 0x9c16cb825d44ba38L,0xc83d2df42a8fa83fL,0x835aacccc08fef0cL } }, + /* 37 << 91 */ + { { 0x09ce1818af09fefdL,0xd1d2f95f5dd9d687L,0x94ed08b5495c4eaaL, + 0xd1afff464a0b95d2L,0xd51ba2b455347a75L,0x413126295e3866edL }, + { 0xeef2d7e3cdd37660L,0x50e6fbdfec2fe50dL,0x9d071e18a664e2eeL, + 0xe70e1d9ed6a8f467L,0x576d0cc4e13afc19L,0x67ced86da0efc220L } }, + /* 38 << 91 */ + { { 0xa26968cb26a963daL,0x461d1ab5cecbd96bL,0x8eaa1834b3e38516L, + 0x1e92730f05d2cd2bL,0x91112026b07cbf92L,0x26eb815062374314L }, + { 0xa904f1d08ab1b9d1L,0x52006594692b1905L,0xc9cc90ca6ba4717dL, + 0x4bd7300aaad1c74fL,0x67ba07a4c21c5832L,0xdebfd810fa56a1a8L } }, + /* 39 << 91 */ + { { 0x3bc5aaf484539b6bL,0x6ca9ac0c0d1249aeL,0xb59da22db4ee30c8L, + 0x6e62553e57149c9cL,0x46db0089786333cdL,0xe1e2ae523e4c12ceL }, + { 0xf828d2b537b3fd82L,0x31844a9d03af654cL,0x85dd8daaea5a4677L, + 0x0db99b8f3432e82fL,0x99383b874866e1b6L,0x52310054e325b0c2L } }, + /* 40 << 91 */ + { { 0x737cd387044854f9L,0x488b2fd667eb29c2L,0xe71d9bb7258c5a80L, + 0x21afb486ac71048eL,0x0252b540d4d39296L,0xe3e52cb87839d8fdL }, + { 0x5cb1100667ea0afbL,0x207637d1de82b12bL,0x77920933e93bcfcdL, + 0x65197f5df32f636dL,0x82179527b6c41411L,0x7696a479f410c989L } }, + /* 41 << 91 */ + { { 0x78307cd80e8d576cL,0x10d3b950fd9d6044L,0x2c2f9e2bf4b20445L, + 0x961343c72c5c7ea7L,0x931c52a0af640e61L,0x45557391470d420bL }, + { 0x4096a997317f4d26L,0x15210801cceb9be5L,0x228102195ff0759dL, + 0xc388a2d21d265932L,0xceb79d01e86dd99bL,0x23e8fc7b3311dcb3L } }, + /* 42 << 91 */ + { { 0x1a7d0e091d7743eeL,0x18720797d53e4a8dL,0x78465f1ea04dbaa1L, + 0xd4f064da9ce65723L,0xc0e7c035b496e8d4L,0x25657d2e6bb2f9ebL }, + { 0x45576ab49f4b6cb5L,0x83983c70ba33d6dfL,0xf699e84d1eca62a4L, + 0x35528636a13f5c31L,0x6a1b56b01f6b1739L,0x7906eccc6ea87942L } }, + /* 43 << 91 */ + { { 0x4e584a4fec1204a5L,0xd96b00e845a5b311L,0xea11fb03030badccL, + 0x9b2141b2a825a89aL,0x18bbc30bf8b2450dL,0x87bd93916513b2cdL }, + { 0xb3dbde552f0b304dL,0x762f3dd7c3c4817bL,0xe51e1733edd3fdd8L, + 0xddad4c515d8219a2L,0xf5a8c0b8796b6877L,0x34563a8989bf65c8L } }, + /* 44 << 91 */ + { { 0x93e2e3a2881c106eL,0xa227cc49fe82afd8L,0x6fee74a4748e81f3L, + 0xb212e8eaa5dd966cL,0x68d270efdc7d8883L,0xef2f3966fe757e9eL }, + { 0x0340098b7466881eL,0x7ab98a0575884bbfL,0x24783467a472f62fL, + 0xc73cb49f988637d9L,0x2b5e9d27dfb710c9L,0x503f9a2f788fcb18L } }, + /* 45 << 91 */ + { { 0xcba6f4631a52b729L,0x8874582cc8be34cfL,0x98a08e246a9a1eaaL, + 0x77094319d5693f71L,0x575a0938a8504e5cL,0x3f59910c226f888eL }, + { 0x5c3587990aeeb1f1L,0x7c32821d3613bbc5L,0x66f288e7cc17db95L, + 0x6f3221998724ac94L,0x4e3fa38981db3751L,0xa6e798c8420403baL } }, + /* 46 << 91 */ + { { 0x56672f2e2cbea2e8L,0xd1a02df9128bd636L,0xff6a3bc6d47a0025L, + 0x24124f30d38d0b42L,0x89ac3b8dda63df29L,0xf26d72994d0b6458L }, + { 0xfff0445f7d6880bcL,0xface90f52be76351L,0xbf10c6b8ebffb74fL, + 0x0e53c533a1fba003L,0x037baf09112f4980L,0xb8ae6312be960954L } }, + /* 47 << 91 */ + { { 0x8397b60917270d4aL,0xb4d0c38700e4caeaL,0x69c52bb3f4c58f86L, + 0x06e0e01157b1fd41L,0xc5dc2f25627873a2L,0x9af848ca0ae53974L }, + { 0xb5c957c06ad18335L,0x93b564154ef09e7bL,0xb5ba282450e2c5ccL, + 0x63f003a567d7b68bL,0x0bcb0dc820bcbca3L,0x8803b1ffe3d4296aL } }, + /* 48 << 91 */ + { { 0xff41d51faae4bfd4L,0xcf50b14117c44facL,0x078b808e657a1ea4L, + 0xc5aac1a893c00c55L,0xcb99cfd0cc4d1c0fL,0x1d1048933fa123a6L }, + { 0x49646059023ca92fL,0x5833e326f3982134L,0x2e0d4bc9c5781cddL, + 0x5f7f84ed8d5e75f5L,0xb6655f1fe1e8a383L,0xcc18514c296e4943L } }, + /* 49 << 91 */ + { { 0x5d3e5f8d8a407ff0L,0x9c713c8c7b42b11cL,0x7433a9921e387806L, + 0x5272b92a98cb43acL,0x6261dfc1b1018149L,0x229d2ba5d3b4adf4L }, + { 0x1f52e72989f0905fL,0x965e062925d4c79cL,0x42edaeeb33e6c016L, + 0x5ec492e8af1709adL,0xaad39616c5763619L,0x85a659098c666860L } }, + /* 50 << 91 */ + { { 0xec8fe7dc86009df6L,0x42dd3c37871b20a6L,0xe4388c920db643e4L, + 0xcc5dfdd481e06dbdL,0x3f1a3c6458ca7500L,0x987d7caa22c04e9dL }, + { 0xd0c91072bc5717e2L,0x3f605fd2e77e5509L,0xa1cc1404c0c3e95eL, + 0x4afaa9fdc6d0edd0L,0x2f3aba4e0d7d882dL,0x3f1f0349796c5ac0L } }, + /* 51 << 91 */ + { { 0x5dac93982eeb82e8L,0x2fe5ffb57536ce1eL,0x2bb120ac6926cfceL, + 0xe54ff20f2236dbf0L,0xaaf0d31edf8c5a87L,0x5262fb9fc8f5df7aL }, + { 0x0f833760467092bcL,0x50fa223d0a8dc0afL,0xd6a4847d35406966L, + 0xd17d6ce003b7f56bL,0x8067d8e2ee2d64bdL,0xe33e51bb9fa4fe9bL } }, + /* 52 << 91 */ + { { 0x52aa210770248e4eL,0x30cf7e773b6bf709L,0x36961c7b788e1836L, + 0xbe49de5f7595af2bL,0x86b49b619cbcba78L,0x1947db3790cf1117L }, + { 0x7d3f599de14b4287L,0x14546993f0ca62ebL,0x0f6c8872d0abde7aL, + 0x1531ceeaafe2260fL,0x36449624ae5ecf96L,0x6cfa12a5840bdc19L } }, + /* 53 << 91 */ + { { 0xb092ad68c1d612b5L,0x9f6052507af5c37dL,0xf48aa7c6c702b673L, + 0x380144215cd29c3bL,0x7b09e407121867ecL,0xf71443d391e59047L }, + { 0xea51e1a6b6d16a51L,0x041fa7650f33e2ccL,0x3a6d50c73750dce3L, + 0xeebf5c2e97cb7a7dL,0x2530de228f39e771L,0x9af217c18f37f863L } }, + /* 54 << 91 */ + { { 0x38793fd0c683085cL,0x49cc5934dc436d16L,0x94c708e4175e770eL, + 0x41bfb65d059c2682L,0xf6b83eb75f004ddeL,0xe1881929f6864410L }, + { 0xfaa77fe0b438f937L,0x97a856069997e90dL,0x78366a9108de889aL, + 0x6c28ef64553229cdL,0xfce82c2fe9381854L,0xae98117146f70bb1L } }, + /* 55 << 91 */ + { { 0x3f77410e9aacedd8L,0x0e34bd7d453813e4L,0xc5818436825d6b0dL, + 0x0e30f037b4d0ac73L,0x70f6bc9b69b559c5L,0x68d3d71eaed15484L }, + { 0xd0254e5414fbae1eL,0x6ddaad42ae0d3df6L,0xefb91a545a6e98d0L, + 0xde3fcefc854ee5fdL,0xb2f0f3a1dfa2a8a0L,0xb656f97ad00ded3aL } }, + /* 56 << 91 */ + { { 0x01acfa7e0a90e37fL,0xf47e5946366d0ba0L,0x8e37db7b54c11845L, + 0x5742d8bd50a62064L,0x27dc9a33ed6d096cL,0x2246d73016deb724L }, + { 0x203c08da2c8f1a85L,0x210cda3a56fea379L,0xea6b1bbf2bf9ed67L, + 0xe5a1e5552395cc4bL,0x458a7e19de2d6b2fL,0xa7199a86734942a3L } }, + /* 57 << 91 */ + { { 0x53684c23d44cad85L,0xd23613f8940779a5L,0xf485c7a3940bd34cL, + 0x64c66a1f3f673b5eL,0xec29c76f1d6dd63cL,0xe10f56272f191435L }, + { 0xc054f9a7325d5759L,0xe6740d3f974edaf5L,0x2723ac6103f3b640L, + 0x0a2315a4576e0bbeL,0xf8156e1e4a3ec903L,0xa307bc249bbc8c52L } }, + /* 58 << 91 */ + { { 0x78579ca212a1687aL,0x208b7494268a02a2L,0x61708a002c1c5243L, + 0xca366915a760461eL,0x0e9038fe3ca1e167L,0x2cfd6fe3a58e2c57L }, + { 0x97c16e34fe79a49cL,0x1575244ef08e4037L,0xc1407fa08e2283edL, + 0x38ae77621b057919L,0xcec574a5e68a366dL,0xafdfdce03eff00d4L } }, + /* 59 << 91 */ + { { 0xdad0dca9162d80c6L,0x554141f8b888ea0fL,0x1e471b24d4036218L, + 0xafca22cfb36102d0L,0x437c51bff280dfa8L,0xc2c8bc8b50c9c30cL }, + { 0xe7bacc372a9fdf6dL,0xd01dc65cf0472f2dL,0xaca59cf983d7be3eL, + 0xf7c935425d9ec484L,0xc22046c6015a08a1L,0xa71b3c64cecdf816L } }, + /* 60 << 91 */ + { { 0x4b7d0b277abe7856L,0xe566f4567acdb39cL,0x70c6cdf20047ae7dL, + 0xd27f831233ed0392L,0x498f0ad0358a429dL,0xed97c4668e6ee95dL }, + { 0x3d11cd69f3018515L,0xedd460344c1b367bL,0xd75660e3b3ac8ec6L, + 0xc80dfc0fa541e6e1L,0x80026f005c091a6eL,0x62b86784c426f2bbL } }, + /* 61 << 91 */ + { { 0x417408e529ee8eb4L,0xe92f18c2917f9951L,0x1f471f0eb38b6210L, + 0x53cb14264df240f3L,0xeaf7fc0067c29b25L,0xbbf46fd3d99cb613L }, + { 0x05cd552eb465b50dL,0x136b8e675e136733L,0xd7d50f61ccf61776L, + 0x90187ec5a32b01f4L,0x21548ec523ba232aL,0x6c8266c0748e558aL } }, + /* 62 << 91 */ + { { 0x762f413d7650470dL,0x9b4af5d018c9ad5dL,0x85fe90460ea625a0L, + 0x4af4511b2200cadbL,0x4c16980defec2921L,0x42ae5d5d60dbe1a0L }, + { 0x0785260bbb2ceb1bL,0xd181ea3242f1fb7bL,0xc34f02b13a47672bL, + 0xb0bc79f770e58634L,0x6e7967098a8509aaL,0x05870e6f3c3e6d44L } }, + /* 63 << 91 */ + { { 0x46d4fef752f7c595L,0x5f35083a8a07819cL,0xbba477ca591233ddL, + 0x4e66309358e307deL,0x65c3e2b9ef827537L,0xcf7b7adb09ee9adaL }, + { 0x00a82d4b5f5e1434L,0xd6aecb8032e50afcL,0xffdce7ce6b034271L, + 0xa95d96ae036d5058L,0x61582ae24cb7d60bL,0x6a10577474139c1bL } }, + /* 64 << 91 */ + { { 0x53ebbaaeb475d8f3L,0x3d6ea31cff76bedaL,0x3c15f25d340986b4L, + 0xc5925d2e3365312aL,0xc35d3ee251641f96L,0x11eb2f75984128e4L }, + { 0xb41a21a83d04bc99L,0xf2d286006436c3d0L,0x4ffcf4c0faf5663cL, + 0x889d285a0a62c9dcL,0x0908665acb2d60c5L,0xe2f19c590a131be5L } }, + /* 0 << 98 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 98 */ + { { 0xc0de60f5091354ffL,0xd7cc38bba1bd1975L,0xf4122aa8e734e2dfL, + 0x08f40f63ef773db6L,0x0a7e9484ce2d71c5L,0xcc79173378a3f825L }, + { 0x0cac7a5bb47beec9L,0x1cbea0e4a3f7b5b6L,0xecf19a90d3e18145L, + 0x0d1b062a0aadf689L,0x42299f1ff3f0acf7L,0x63a645395ac252b9L } }, + /* 2 << 98 */ + { { 0x44bfd1665c1d4586L,0x46434e198d1d86d6L,0xe50fcf81c3936683L, + 0xc9b4eb068b08680fL,0xf90882c52832aab0L,0x42823cefecbf5ddaL }, + { 0xfd4d51c744ae08f0L,0xb54a08f1bbd21c1cL,0xb72953dbfb187c34L, + 0x166f7f26f8ed037fL,0xd2b1077a097bad45L,0x47794cdc790dd808L } }, + /* 3 << 98 */ + { { 0xfadb2ac4bac8b691L,0xf0c5a0361579c4d1L,0xa192474f79019224L, + 0x8c7a64574117a323L,0xe58122dd84d970a9L,0xc475893c0bf77208L }, + { 0x9518412f1bd45c95L,0x75bd0a72283f7a3bL,0xa9e871605fb7e6f1L, + 0x14d3c944df67acedL,0xbceea947d0348c22L,0x5331c192d021aba4L } }, + /* 4 << 98 */ + { { 0xa05c751cd1d1b007L,0x016c213b0213e478L,0x9c56e26cf4c98feeL, + 0x6084f8b9e7b3a7c7L,0xa0b042f6decc1646L,0x4a6f3c1afbf3a0bcL }, + { 0x94524c2c51c9f909L,0xf3b3ad403a6d3748L,0x18792d6e7ce1f9f5L, + 0x8ebc2fd7fc0c34faL,0x032a9f41780a1693L,0x34f9801e56a60019L } }, + /* 5 << 98 */ + { { 0x35df68ae1a504405L,0xe41d69508fc755b9L,0x420dc1cda6297243L, + 0x3011646b913fb68fL,0xc4b630465e141a27L,0x943b3b3bbd91fe5fL }, + { 0x3ca17d6b50c31708L,0xce88b5e74ffa8c71L,0x8b60038f4dacd2bcL, + 0xdf654d723c13cf9bL,0xb5353e281d871b40L,0xc2d27919226663d3L } }, + /* 6 << 98 */ + { { 0xa028d2fa9b87715fL,0x7cdd9b4a453625bdL,0xc8afb1890be3dacfL, + 0x40289a3a274c4e2eL,0x7f5f9f7677c6bbadL,0x577c0935bdfeaccaL }, + { 0x5f838f0404281989L,0x8650a974ebfa410dL,0x414fab6dcd56dea6L, + 0x6995cae292eed440L,0x3b474d27ab146e15L,0xe24262b2e9938f84L } }, + /* 7 << 98 */ + { { 0x649e18fba34fb18bL,0xa4883af898cc69d3L,0xff46285f3fd56e37L, + 0x2e28ccc4557c0c04L,0x8388dee821a9b46bL,0x0fd4fb807ba3a6deL }, + { 0x1d8e9da7c62bb315L,0xfa7bd70d06e44230L,0x2840122063320438L, + 0xeefabd47d06c0654L,0xf4387b08d4c8c10fL,0x8f2694624ff2142cL } }, + /* 8 << 98 */ + { { 0xa4b957d262c36887L,0xaf15a485fc24cff8L,0x11575e80a271d9e0L, + 0x0fff68d44b9367e5L,0xf55ba6732279779fL,0x9d72cca6d4d68f68L }, + { 0x01474ab1590ffe4cL,0xd20f44e1074d634bL,0x63903a8336111d25L, + 0x37342a5fab531cefL,0xd3c93fe7702ed867L,0x05d143696279f7e1L } }, + /* 9 << 98 */ + { { 0xcddf64873e942b27L,0x9e29835a2bc21472L,0x924c2bfb2d2195e3L, + 0xdf4a3cd38eca6d9bL,0x7fe6acd1c5be60c3L,0xa3abee9cfc38025fL }, + { 0x014f0d992f449934L,0x8d72657a78860127L,0x92514cb948d84cfcL, + 0x8bd4ac503aadd70cL,0x3c96ee00136620d7L,0xa0caeeb54efc5e57L } }, + /* 10 << 98 */ + { { 0x7a65cdf5bd200ed6L,0x72dc1b5f0e4b1c68L,0x9c09576a6ddf540bL, + 0x358dcd122b169da2L,0x6466f0e81639b734L,0xa1429a6ef14c6eb6L }, + { 0x4b3d781943221168L,0xfe3d2fdaf3b74fceL,0xb22bcec2ae26014bL, + 0xa8900e7ace7e789cL,0x9db9af67220bce88L,0x1f86d2e4fb8ee34dL } }, + /* 11 << 98 */ + { { 0x6f8e1c0bf8c65293L,0x66f44ea04d7a5dfbL,0x2c3cacac741fdc1fL, + 0x72e58aae239f5f16L,0x50dbaf192f72d8c8L,0x24ee526628c97b95L }, + { 0xdb5f7827ab3ecb17L,0x2c567337669b05c5L,0x78c97eb8ff76ccdcL, + 0x1de1b4a3f8d2c990L,0x5b183974e6138df5L,0x61b74177aa1a1019L } }, + /* 12 << 98 */ + { { 0xb398290cf0db3751L,0x01170580ba42c976L,0x3e71aa2956560b89L, + 0x80817aac50e6647bL,0x35c833ada0be42daL,0xfa3c6148f1baba4eL }, + { 0xc57be645cd8f6253L,0x77cee46bc657ad0dL,0x830077310defd908L, + 0x92fe9bce899cba56L,0x48450ec4bceffb5aL,0xe615148df2f5f4bfL } }, + /* 13 << 98 */ + { { 0xcc14267f6be1860dL,0x3de7f48b4ffedea1L,0x8252694e5b776b87L, + 0x478c877890dd427fL,0x913e19a675a21357L,0x882f2d5ac078bd79L }, + { 0xf442752184c565dcL,0xd772147e3ac3ed26L,0xf21abc752fa216b6L, + 0xab1804ad305ff0dfL,0x10d89a07920c977bL,0x0a2240dc4fda6075L } }, + /* 14 << 98 */ + { { 0x7068e6b98653bfadL,0x16b0da9b8f4397e8L,0x77b953b4946bb9c6L, + 0x08366ad749b036f5L,0xd219117b26a3913dL,0xbe3607949a5460d2L }, + { 0x1a4acf6dfadd462eL,0x1f7de879c32f3550L,0x11117132669c9b2eL, + 0x1deea7d1c87ca216L,0xa88c90c748a058d2L,0x0d8e6afff403ef36L } }, + /* 15 << 98 */ + { { 0x21f6c96c1ad77f33L,0xb5da9d34992e7807L,0x17fc994ba7192adfL, + 0x59f204fcbcc3f8b2L,0x3f4a970f10bd22f5L,0x42936bfcbaa1188dL }, + { 0x6239fea5eb985837L,0x5fde15e0b33d1158L,0xe0bbe9b800cf90b2L, + 0xf2c6d8b16b2b68a8L,0x58c331cd0f3a2341L,0xe951c48910dab1a4L } }, + /* 16 << 98 */ + { { 0xdccf68bccbaf4685L,0xb333e464270a2bccL,0xe43ae199254dd3e3L, + 0xe8526e26ddce5c84L,0x52bad815ea0b4258L,0x67c12c1b094574c4L }, + { 0xa5362fcb861545b7L,0x3e904c35c2b2eb62L,0x0f9312b5eeffc2cdL, + 0x5475657b14de4e5bL,0x746e67d4f0233fa5L,0xb5157d7f35471ec2L } }, + /* 17 << 98 */ + { { 0xcbaf92265315e83aL,0xcc6e9a972f15ff37L,0xcac446dde8c87fb1L, + 0x5fa37a5c672d7f92L,0xe66efc07b1380425L,0x2d8ed2e32c8e59ebL }, + { 0x8e3ab80461743725L,0xe59a87f825493349L,0xf6995fe16062fe7eL, + 0x5d7f8a646e8de27cL,0x4a5ecbbbebe084f2L,0x99fc5ea93f863156L } }, + /* 18 << 98 */ + { { 0x1ddede1b495fdc2eL,0x3dfcf56b039d6339L,0x54c423806a56c492L, + 0xe6bfd184def6446fL,0xfaa2fa123ac841beL,0x503e319a4f9330a4L }, + { 0xd9305d4654ad427eL,0x68d23497d95dfcc8L,0x2d935aad1e9602f5L, + 0xd7e74bf2e33174a9L,0xc8e4a0b17225e2b5L,0x5db7187cbcda5221L } }, + /* 19 << 98 */ + { { 0x9a0e0908b0ec0b27L,0x28894b2edd759131L,0x0107bb592b9d6f02L, + 0x318921deeea022f7L,0xa1a00f5882c73390L,0x877833129551b381L }, + { 0xff866039a3a9dd22L,0xa59235ffdf0fc09eL,0x530c2fe61ca647f4L, + 0x77b1ea2860f9428bL,0xeef2a9e6bba4bbabL,0xdbdbe037204f5ea3L } }, + /* 20 << 98 */ + { { 0xf55edabb90b86166L,0x27f7d784075430a2L,0xf53e822b9bf17161L, + 0x4a5b3b93afe808dcL,0x590bbbded7272f55L,0x233d63faeaea79a1L }, + { 0xd7042beafe1eba07L,0xd2b9aea010750d7eL,0xd8d1e69031078aa5L, + 0x9e837f187e37bc8bL,0x9558ff4f85008975L,0x93edb837421fe867L } }, + /* 21 << 98 */ + { { 0xf87a92375b2e5fa6L,0x88571e4452a3a605L,0xf85e9a330c8f5f55L, + 0xf99886c599dc2c97L,0x5866329d065261daL,0x9011f13912dd434cL }, + { 0x0cc67d535284c555L,0xf8f715274a4032caL,0x4b002683a9524bcaL, + 0x3c3c12910f63a7baL,0xd19e173e9124eb8cL,0x3431c51c54b7d85aL } }, + /* 22 << 98 */ + { { 0x7103ab4ae11cc85bL,0x2064ca41789cf87eL,0x592850ead5f13a08L, + 0x56b9ff066212e096L,0xa106455d6efa7445L,0x3e62aac92343c5efL }, + { 0x7edbf70dcb8ddf7dL,0x27f00a4a5f2687e4L,0x7d4ce32e44a08d11L, + 0xe97f0910890a57f1L,0x792597fb912cb027L,0x1fa7a1d2ad3492dfL } }, + /* 23 << 98 */ + { { 0xbf4e161c3cfad317L,0xda4e6bffa1998bc8L,0x6534ef622e890b99L, + 0xd10a3b24d272cc42L,0x3f81b0e5f1194dabL,0x8919caefec549c5cL }, + { 0x847ef47f68f5633dL,0x01cd59975468f4afL,0xc38bce29b6727408L, + 0x56a1cd1ea4c84268L,0x31a493f406b81088L,0x4461ce8531b37e73L } }, + /* 24 << 98 */ + { { 0x3503d9371f23a0d8L,0x64c598a8c321dde0L,0x67f101ef5b52e0f0L, + 0xb6b5b4c2f955b5faL,0xb5f03d53880e0569L,0x121c3ac1c99393efL }, + { 0x90755bd657330666L,0x70ae5793d4d71d3dL,0x326ffd519e9ce792L, + 0x1b772d7396ccfa14L,0x652710f4874a22deL,0x72768469db210342L } }, + /* 25 << 98 */ + { { 0xb2d85722b3413d7fL,0x4e41362092e55ea5L,0xad1a20c7ff7b3409L, + 0x743b31c0c6f98cbeL,0x1b5b0b5adab3810aL,0x628d9b212cea0428L }, + { 0xa3e24294b0335ba0L,0xa9c0e139487530a7L,0x54199640072e70eeL, + 0x0977586e64c0d563L,0x393878451c5cce35L,0x57acd85631ce1eeeL } }, + /* 26 << 98 */ + { { 0x63081bcf9b8d9f3aL,0xb09fe52b6f94e3e9L,0xc232e5d1e39c092bL, + 0xd61ddcccf5f072e4L,0xcdb3b4189a26a93cL,0x0c010c048de6f5c9L }, + { 0xad2473a5d238e823L,0x4120ab3632029ca0L,0xd6632edb639bb8ddL, + 0x3383f077a8b32fe4L,0x8afcbce5eacfbe80L,0xe28236212d2fff74L } }, + /* 27 << 98 */ + { { 0xccf2a24a0eb3829bL,0xdd8fe4421eae0751L,0xb685b073c9598d91L, + 0x025214ce8b308785L,0x11c3fb11d6433acdL,0xe40cf39c81794024L }, + { 0xa167651b1c0b1f54L,0x350cf3eb0bbde983L,0x69c93dd0b2a88c48L, + 0xf13afc37bee80b26L,0x0be7d05d776345e2L,0x1ccbc8ba7645b02bL } }, + /* 28 << 98 */ + { { 0xaa6489df83d55b5aL,0xea092e4986bf27f7L,0x4d8943a95fa2efecL, + 0xc9baae53720e1a8cL,0xc055444b95a4f8a3L,0x93bd01e8a7c1206bL }, + { 0xd97765b6714a27dfL,0xd622d954193f1b16L,0x115cc35af1503b15L, + 0x1dd5359fa9fa21f8L,0x197c32996dfed1f1L,0xdee8b7c9f77f2679L } }, + /* 29 << 98 */ + { { 0x2aa349975442c668L,0x4c5137130cd74444L,0x4f87be0f449300ecL, + 0x13e07b552bae04fdL,0x6aa575d11f75acf6L,0x4502e9e9852848a9L }, + { 0x3c246d38889666fcL,0xb6c0292b7c100867L,0x618f234aa2a280e0L, + 0xf983c834669afe62L,0xc51a15105d900a1fL,0x7d7ce31bc952f419L } }, + /* 30 << 98 */ + { { 0xe3dbb7483c3388dfL,0xc26a7d042c32f139L,0xc1b48180ed938dcdL, + 0x785b964d42e4c01cL,0x507cd16aa1f75e28L,0xfaabff8d1f323caaL }, + { 0xc6bc47ceadd5b649L,0x997dc0ee3c0aed28L,0xcef0c89bf3666cfeL, + 0xd8d7dfb426482ea7L,0x5f00e432d2348484L,0x09549b5a1dc66aa6L } }, + /* 31 << 98 */ + { { 0x702e450ef8464b1eL,0x52d20765a061c4c6L,0xe1c930b26519bfc6L, + 0xa9c0c8c6d17ea02dL,0x52bfc60ddac62461L,0xc325568f7c5f9a55L }, + { 0xe7413df9eb44b9d7L,0x461682265837e0d1L,0xfcb9628c15aa0c89L, + 0x83d6d0eebb57c6a3L,0x17bb82a56829c9fbL,0x342fe91c496861e0L } }, + /* 32 << 98 */ + { { 0x58d6998e171c1439L,0xfd4a98f401feedecL,0x420b2a0165739fceL, + 0x5c5db30822f7a073L,0x016c547805042f00L,0x5fc73ce2a12413d9L }, + { 0x8ceb2d70e932aa17L,0xb4d66b670537afafL,0x2638d012339c146bL, + 0x02fbb7b628ac0555L,0x7fcb0c8162d46e63L,0xeaa9ff4f066d088eL } }, + /* 33 << 98 */ + { { 0x45f53090b8b22c29L,0x155b8f8111e70d5aL,0x5ec118b25d3a7d83L, + 0xfe4c7eb39c4ddd1aL,0x8cdfb753f226d869L,0x20bb870779fc646bL }, + { 0x3c8c1d7a25d1308cL,0x5a976ae47116f347L,0x6af949a60faf9690L, + 0x7e6718fc07f3472fL,0x16ec7b45267b17cbL,0x80744641cebe1bd7L } }, + /* 34 << 98 */ + { { 0x45eded7ab2a5c8e3L,0x4308485969a0681bL,0x89b7510d90910e8bL, + 0x1c622d04d2066d92L,0xdc3b434bcd2f0d7cL,0x98bcb83b476ea5a3L }, + { 0x9195431d3dbf2be5L,0xfec7efd969275ac5L,0x6a4364f556a7da4dL, + 0xaf701bc579c177ccL,0xb77ef33e9ffc2a47L,0x2bc59331cc23c4e4L } }, + /* 35 << 98 */ + { { 0xedf4a85b9d43c51fL,0xc0afbcb6b59a7244L,0x3ede2f25626e0ca8L, + 0x45836582270f674dL,0x83c47048bf06d267L,0xbb1e994f3c68314eL }, + { 0x50d79cb4f2fe6c8fL,0x1a1d8aecdf7600f5L,0x216f5d2bef4e4857L, + 0x41361a90bdffb9e9L,0x8040f5c173d2f9caL,0xe6665f0dd1e9be4dL } }, + /* 36 << 98 */ + { { 0x5405179f394fd855L,0xc9d6e24449fdfb33L,0x70ebcab4bd903393L, + 0x0d3a3899a2c56780L,0x012c7256683d1a0aL,0xc688fc8880a48f3bL }, + { 0x180957546f7df527L,0x9e339b4b71315d16L,0x90560c28a956bb12L, + 0x2becea60d42eee8dL,0x82aeb9a750632653L,0xed34353edfa5cd6aL } }, + /* 37 << 98 */ + { { 0xb112fd7b36386e2dL,0x358e974a6a634bd7L,0x509814737faf640aL, + 0x1036bdacef39b3aeL,0x410c6448db5aceb0L,0x914671305bbebe92L }, + { 0x83fabd54e9e009e4L,0xb2da8eea9994d16cL,0x9d73da6356997acdL, + 0xea9158b97ec1b844L,0x8e6a6e3129714795L,0x23e98f57131243f9L } }, + /* 38 << 98 */ + { { 0x7105f727552664dcL,0x97cbfb6c5c589c8cL,0x1a7b110a70fc59b3L, + 0x46c39f2cc754c69dL,0xcda0e2c067b1f17cL,0x35fe45fab7ede210L }, + { 0x6b3ecb7d82e78b40L,0xa90eed4fdbc07241L,0xa73797895aacd533L, + 0x28120ba5f4fa89a2L,0x9c1fc09ee3055006L,0x71e665efc51653a4L } }, + /* 39 << 98 */ + { { 0xcf782247d28b5059L,0x15bef4cb1b89eb06L,0xbc182ed6bcb4afeaL, + 0xcf5b6dfde0e32b77L,0xeb61aff9d9446052L,0x5846f171c4bfc0abL }, + { 0x61d5ae1c6fc68422L,0xa282c56846e870afL,0xdb4859d16bca8fbdL, + 0xd4cd416e97caf135L,0x11217fa9c3debd59L,0x27702da6370758ddL } }, + /* 40 << 98 */ + { { 0x8273db992d189057L,0x4d1b05fce1b5f8ccL,0x5fec7c830a7c32d1L, + 0x28ddaf28ea9b4d45L,0xb6bb62aca2fc58beL,0xfc65b7aa4a41852dL }, + { 0x6e7651941c9e6045L,0x3acabf28fc116257L,0xc9d5e8054b5a4ba8L, + 0x9a072259cbdcf1ebL,0xc67cf643439fc8fcL,0x917ef6f8b4333aa8L } }, + /* 41 << 98 */ + { { 0xee6123cca6411227L,0x91372d080ee882bcL,0x2c30a840a638a4faL, + 0x1867421321e83d4fL,0xc6afa4cfc3fb9925L,0x19aec276e4fdc73fL }, + { 0x1ffec4510cf4e610L,0xac57292ede22d429L,0x62844d78e6cacbc1L, + 0x0eafcc554d2e497cL,0x39f1acc8e780f600L,0xfcf8d914fcff8c6aL } }, + /* 42 << 98 */ + { { 0x0734ab43ff2152d0L,0xe52c5dee930fea54L,0x9cac7efe940bddbfL, + 0x30d2610ddbd43391L,0x4beeb865921c124dL,0xa19fe6a4fca219fcL }, + { 0x588395628755cc47L,0xa7f301241324f2d1L,0x4fe38ee3b1ec5aacL, + 0x3583542eb16413ceL,0xfa92e2191733b7eeL,0xc0f30ba32b2001a4L } }, + /* 43 << 98 */ + { { 0x706b02c3febc7968L,0x6e45dc90c96a6b64L,0x34e5f890f95aa4c7L, + 0x8ae64d487683b855L,0x0fbb9c4a62e03ebaL,0xb32a965ce2cab115L }, + { 0x4a7084a8b33102b4L,0xe7fd9db3ebd1bd6aL,0x2fcb233cc7f32b61L, + 0x365896d5f2549734L,0xa3f18bfd25c7a1c4L,0x382950ef212b8daeL } }, + /* 44 << 98 */ + { { 0x82154d2c91aecce4L,0x312c60705041887fL,0xecf589f3fb9fbd71L, + 0x67660a7db524bde4L,0xe99b029d724acf23L,0xdf06e4af6d1cd891L }, + { 0x07806cb580ee304dL,0x0c70bb9f7443a8f8L,0x01ec341408b0830aL, + 0xfd7b63c35a81510bL,0xe90a0a39453b5f93L,0xab700f8f9bc71725L } }, + /* 45 << 98 */ + { { 0xee2b773e4ed17990L,0x499e83623faab7feL,0xa3925e2f71abb9efL, + 0xfee50406ce3b4a69L,0x71a15070bc10f803L,0x5b01e4a2c7bab10aL }, + { 0x806c590d99e51e36L,0x34adbaf6a7f88d5aL,0xd4a93ce9f6b30ac3L, + 0x39d2cf40dc33fdfbL,0x13e676f1d5e4e7ddL,0xbaa72ab9199690fbL } }, + /* 46 << 98 */ + { { 0x85017690e51b47daL,0x25919b58a2b476ceL,0x6f692de103ec5d55L, + 0xd6cf8ee5d022dcebL,0xaf3225238ba7076eL,0x917b373728c902d5L }, + { 0xac75fddc3fdf8590L,0xe83d9bbb64fc304cL,0x13550de2971f659aL, + 0x70bee07ee12b7bebL,0x9989d2fa0a855646L,0x8b6043aca576b3a1L } }, + /* 47 << 98 */ + { { 0x1bfd4f92fadf9017L,0x1e4509aa737bc67cL,0x88278c3699af1ffaL, + 0xbc47536f4678e22bL,0x69914cdb1b07c823L,0x56fc28ab97277358L }, + { 0x092d28efe752d2f7L,0x6a8286a691da62c5L,0x86b702778033c632L, + 0x57ef284e7672f41fL,0x9101ed302e54007bL,0x53e94cfed25d8d19L } }, + /* 48 << 98 */ + { { 0x311ebba2fc37efedL,0x8a6a42d660cfd6bcL,0xb4051b3af2a4871eL, + 0x66ce77b8c2f0ebf0L,0x84abc9480ad28477L,0xc82e5c6263d9d11aL }, + { 0x99ffc70c007dcf93L,0x5e974edfd964c822L,0x0fee3572513085e3L, + 0xbe67a88046ce8444L,0x136ceeb806d17129L,0x0da512ae662d86fdL } }, + /* 49 << 98 */ + { { 0xeae827d989e687ddL,0xb025f0723bdbdd9dL,0xfbddcecec3a575aaL, + 0x3fab33c1f80d12cbL,0xd0232142b32f0381L,0xf00e74bd3b6c3132L }, + { 0xb7c1311e0e44deffL,0xf3d790ae29b04d6bL,0x3d3744b846f72957L, + 0xc0890fb6ab2f13e6L,0xa669a34324461f0cL,0x35c9677ddd72fcb7L } }, + /* 50 << 98 */ + { { 0xc257ed518060a28fL,0x3a9d7e1cc72fafebL,0xa304a5e8332f435aL, + 0x96969bc234ccf343L,0x2aae4d8e7702ba84L,0x37f15631f203a7eaL }, + { 0xc0000f24c9666405L,0xa98eb834a537fb89L,0x8c0564cf7e36dd1aL, + 0xb5ca507b4e89615cL,0x9bfa209a9d80ef92L,0xe2ec1879a83f02e8L } }, + /* 51 << 98 */ + { { 0x73b4573c11dfdea9L,0xe5f208ee5c8cc81fL,0x5c240d3c769adf12L, + 0xbd3f8f33550c53acL,0x98171d16bb4f43acL,0xaf19d5fe84db9e13L }, + { 0xc589be0d2e53345eL,0x3184b540f114f6f3L,0xa35ed77e4946090fL, + 0x427b860afd3108fcL,0x7d0848c3867df76bL,0x353539e2a32ec485L } }, + /* 52 << 98 */ + { { 0x9401aec2b9f00793L,0x064ec4f4b997f0bfL,0xdc0cc1fd849240c8L, + 0x39a75f37b6e92d72L,0xaa43ca5d0224a4abL,0x9c4d632554614c47L }, + { 0x1767366fc6709da3L,0xa6b482d123479232L,0x54dc6ddc84d63e85L, + 0x0accb5adc99d3b9eL,0x211716bbe8aa3abfL,0xd0fe25ad69ec6406L } }, + /* 53 << 98 */ + { { 0xee174af2df740edcL,0x1bd8382c09233f0aL,0x34a7450e7d343006L, + 0x92259ddd3d463e61L,0xcd0bfe6fedbc3af2L,0x39627c4cfc8770f4L }, + { 0x7b7c688ddbabdf2bL,0xf459f0e64bef3558L,0xfa0e87becc88f7c8L, + 0x67beabac5fcc80feL,0xbdae52bfadeba16fL,0x4751724c5af5c9bbL } }, + /* 54 << 98 */ + { { 0x5627e0d016332364L,0x33839376fc57f01bL,0xe7fc2c489528e434L, + 0xa0ee39acb52b3757L,0xe49e383ee42e4832L,0xabfefdbb31359afbL }, + { 0x5dedb6f3b99ee196L,0x38abe58bc16aac17L,0xa300a1333ec06a07L, + 0x00e68eadc90d4659L,0x60412e8a8000a773L,0x6099b6a6a5830c94L } }, + /* 55 << 98 */ + { { 0x85364bd10d340c80L,0x14b89462be64bc9fL,0x16429134b542faa0L, + 0x0d4cf3ce73683e2bL,0xf9a3e443cb73ab7bL,0xa4c2d0afbb156b0dL }, + { 0x826123921bc77675L,0xaf2aad4a5f26c238L,0x6f6f5d9aef4656bdL, + 0x0e20425f90901f3eL,0x0e30bfef9943a673L,0x6cefc62847415a28L } }, + /* 56 << 98 */ + { { 0xe7acaa8457e0105dL,0x3c06d3bd3851fd57L,0x23cf3c612a9c631bL, + 0x13888aaa33863bf8L,0xf2396355717783eeL,0xf21e1a4836b300e1L }, + { 0xa734cb3b9d27b4cbL,0x0a7effed796e34b6L,0xfc5864773615cc7aL, + 0x1f98ed7788844a21L,0xd6e289407ad4c7bdL,0xa00d64ebe9331c7eL } }, + /* 57 << 98 */ + { { 0xcc6ce7dee1c1e159L,0x77982e4f03df6b56L,0xbd8307d1b82b5ebfL, + 0x43e25358ed881b82L,0xddba4f418e0eb034L,0xbe326c36f919800cL }, + { 0x97d03da7af52dfaeL,0x153bb17af4bf81c5L,0x29bbb9bed7ff322cL, + 0x7a7bd8c7232cca47L,0x7474c199c2830f03L,0x9f464a06f0065fc4L } }, + /* 58 << 98 */ + { { 0xca505cb553b876bfL,0x6fc27f553662cb5fL,0x891cbef432cb1636L, + 0x339743f16e27e2d9L,0xde76538f21dc4837L,0x9cea05020efe241cL }, + { 0x97b8deb65888d9acL,0x4d3c28cba4b6cc56L,0x88ca828f840910b3L, + 0x2e5727cfbfde6793L,0x05a4138302bbae6cL,0x2e72fd653fa8e23bL } }, + /* 59 << 98 */ + { { 0x5b88c5ae6d17fe02L,0xc9b14810d6dbe104L,0x170b8659873be863L, + 0xdc5946a6ae9111b4L,0x4cfa5f022819a4cdL,0x7653d06ae213bb7dL }, + { 0x324c41baabd7ee74L,0x4219968cdd1608f1L,0xa5e104704adc1561L, + 0x964a53ea5e16d818L,0x00ebd1d4980f4bd2L,0x23cbb80d3518144dL } }, + /* 60 << 98 */ + { { 0x0d5c1769df85c705L,0x7086c93da409dcd1L,0x9710839d0e8d75d8L, + 0x17b7db75ebdd4177L,0xaf69eb58f649a809L,0x6ef19ea28a84e220L }, + { 0x36eb5c6665c278b2L,0xd2a1512881ea9d65L,0x4fcba840769300adL, + 0xc2052ccdc8e536e5L,0x9caee014ac263b8fL,0x56f7ed7af9239663L } }, + /* 61 << 98 */ + { { 0xe6ece4b5dae76820L,0xd428354e95feec03L,0x43517722f8871f7bL, + 0x313fde11e84d0b7cL,0x7f02824b1cae0a45L,0xf9f560c1d6646bc4L }, + { 0x124d88bc903a0608L,0x950e8320370c7ff2L,0x29e6da714090a72dL, + 0xbc5a108c54547d89L,0x809330cd3e484deaL,0x1b04a8088bb00f0cL } }, + /* 62 << 98 */ + { { 0x2425c59c03e0a528L,0x49de96f425c2be3aL,0x30b52686fff4b610L, + 0x2ce573b0f2e5f7b1L,0x4ec05f07b606f0e6L,0xf2040886366ecbf4L }, + { 0xc7fd993460d404d3L,0x8a064992fc12227dL,0x9c6d64ec215492b1L, + 0x2793bd0903463ec1L,0x49523ebab7376e80L,0xb138dfbd35b14fd6L } }, + /* 63 << 98 */ + { { 0x5ed097b0df7363adL,0x21319edba5696d91L,0x17c46519c5d5313dL, + 0x341d46576c6cccedL,0x60d80713692bc704L,0x9477b6e907fb8e13L }, + { 0x2965720b532e0c6dL,0x2767b4ee87831d79L,0x3e2e67abd4b5ef14L, + 0x45ee89b5d2598521L,0xfc8f1e3ee6441648L,0x75c4db57567ed090L } }, + /* 64 << 98 */ + { { 0x17e3d0b8713b8541L,0xf372b048c6b5e839L,0xf8ef0261d0bb1848L, + 0x9b804ceec71a3bbeL,0x00b7d171542a88aeL,0xf2b8ed10e9097b9eL }, + { 0xdbad9f122c0a009aL,0x245fc1e9205fb1bfL,0xa8a4834fb83debf5L, + 0xc3ee226d637e449bL,0xe3070d93cab82664L,0x24b8094db37320e8L } }, + /* 0 << 105 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 105 */ + { { 0xb506b7b925059699L,0x349fd83f01ab02e5L,0x64b729ad3789281eL, + 0x69ae8f81f9af4561L,0x007befe156f91860L,0xb578c566edc250fbL }, + { 0x1c16d75a67ae4801L,0x04c35a7ea1d3f592L,0x5dc97da936881f89L, + 0xaddb603103a5b1eaL,0x7eb515b13e153a0fL,0xdc3a92192b4a1ee2L } }, + /* 2 << 105 */ + { { 0xe7365f9e512cc92aL,0x9efdcf8b5172a654L,0xbfb389ac8e611fc3L, + 0xce778fd5699c227dL,0xdc1f47b63ff2ef17L,0x2ae0f68302672ed4L }, + { 0x51c63806a8e879cbL,0xd3dfecf03909f526L,0x375b3d13e00e12a2L, + 0x91f9f750bf8df325L,0xf1ea0e421df5f21aL,0xaed73e7f32c60584L } }, + /* 3 << 105 */ + { { 0x03b07fb5e0728e6dL,0x9e0469201012234eL,0x272e644935637644L, + 0x2b6ad1c2a55bcadfL,0x86c527765c71c6afL,0xa25bd60bc1678806L }, + { 0x0cae829476bb32f8L,0x389ce4e633e03cb2L,0x504df8337513dfb6L, + 0x4260ee8e1b351ddaL,0xa473c5d9dbaf7cd0L,0x22cb7cb471e390fdL } }, + /* 4 << 105 */ + { { 0x1d9aa9fa26caebd8L,0x6b64686926b7a673L,0x7ebed6a17f167b47L, + 0x324c13f85bd9153dL,0xe9ea5b734c682ba6L,0x2961da7d7e3ff6e2L }, + { 0x1ed2b05001a83dadL,0xb232951dc4a2f60aL,0xafcea5d3d68b8ec6L, + 0x21dc058d1c6ce0d2L,0x0043de75e719410cL,0x4edd792ce15cf534L } }, + /* 5 << 105 */ + { { 0x0f45245f3babe09eL,0x0959326fa9f2fac5L,0x7629e7fb5cc136e5L, + 0x208bd5a6e48b7eb0L,0x637891d6b75a85cbL,0xf0ad9d8d9f27b57eL }, + { 0x437b6944e0454b05L,0x022c51d702ed3592L,0x0f79e2bd0dc0a769L, + 0x54ace1fdd9b81f9bL,0x38611d66f95ea8dcL,0x52443ca8f0e6147bL } }, + /* 6 << 105 */ + { { 0x857d68558bc272d0L,0x4583eeeeb5be2485L,0xb83586dafe0152ecL, + 0x8b0eb223e830294aL,0x757582b6a5b0e880L,0x5140c0169cca7fffL }, + { 0x07a00782e9228f12L,0xb96e2b5dd4973080L,0x3cceb9a6e88efbe6L, + 0x9955b63073fcdd25L,0x04f26ab02805d470L,0x90b38299424da086L } }, + /* 7 << 105 */ + { { 0x73f1ae48f4f6c5b4L,0xee5af13d4a477f01L,0x274614a2ddb93d52L, + 0x90b0c563c320aaf5L,0xee2303c8ef990b0bL,0x00d028e73061f140L }, + { 0xff705011cb3d8eafL,0xae1d990862594f4cL,0x22a27cecdafea438L, + 0xa78e12d5c5962ea9L,0x5bbe9d878e65f9cfL,0xa222580cf47cefa6L } }, + /* 8 << 105 */ + { { 0xf7aaa732959abb9eL,0x1222ad0a2ebf80b9L,0xa1a417372e0c286eL, + 0x3b6685025da3472dL,0xbc0d116b7576f2a2L,0xfdbcad95a36a27d4L }, + { 0xcdb3f4749d54f7eeL,0xe2e0f5f98a5643a3L,0xc70d11b969d4f171L, + 0xdf96d1366cca4ef7L,0x570693db2fc6afdfL,0x5059e67b567504daL } }, + /* 9 << 105 */ + { { 0x2c8107d47fe632a2L,0xfc46c745ede7bff8L,0x2d3b12864650025bL, + 0x815ef3cbe74cd65fL,0x5431b01ba256f01cL,0xe832ff1139915cfaL }, + { 0x2c106de607d7af84L,0x67303b786d4753e7L,0x5f886ffa6d75c8deL, + 0x932a6c20967131cfL,0x5bc94a9170aebbb0L,0xa85b3044fd56e06dL } }, + /* 10 << 105 */ + { { 0xc904558ae7eba799L,0x46b6031bb2fa7331L,0x6620e2b50653675cL, + 0xd1373a357d2218f7L,0x0f4b3ca3af55a5e7L,0x50774160714e70c2L }, + { 0xacc63d1469188455L,0x89a795fe043b8b30L,0xac2fd66ce1e4b9cfL, + 0xac7927021bf67f26L,0xb9513f0d1143d437L,0x02198050811f2931L } }, + /* 11 << 105 */ + { { 0x6d4acdba7b480776L,0x8b518cd466dffeb5L,0x8826c99451918859L, + 0xd2b6a7a038fad835L,0xd315417a6929a870L,0x05d85252c5a769e1L }, + { 0x2fa06335ec0d091eL,0xb0cc337287768c88L,0xacbda5ba58a2eb9dL, + 0x2a404fc976b7b057L,0x073abb71838c6135L,0xbdf89b135cfc4f3cL } }, + /* 12 << 105 */ + { { 0xd00eb9c53508675fL,0x92ec76a4a117dc95L,0xf58d6f85334ca15cL, + 0xeeb522169cee0544L,0x3eb9847ff21457c2L,0x547908bc5524c60dL }, + { 0xb5b49d225198709bL,0x718abce6324abc67L,0xdab8ff2f4abd54baL, + 0x98be59e67184d444L,0x45b74b54babeb4b0L,0xd8d8bb30ff71a5acL } }, + /* 13 << 105 */ + { { 0x8aedf7e28ec13e6fL,0x8b952620d950792dL,0x36e9dac204918f59L, + 0x5e49a5a2d3dd47edL,0xb17455bee863c2bdL,0x8caac6a9326a0d66L }, + { 0xb6c3f5e427bb72e1L,0x17566c9dee5fe09bL,0xfd6bbcc25e3db64dL, + 0xd437d07a3189319cL,0xad00dfc4cd3166a5L,0xab75927b0bd63003L } }, + /* 14 << 105 */ + { { 0xa7672a39afc43be8L,0xefc49015c72f97aaL,0x81c63c050e48f2edL, + 0x62f39f32833a22ccL,0xf7a3480172c0c0c4L,0x4711cd41a4158538L }, + { 0xa3c99a4d1d15f2f3L,0x4b82c1c17bee1b47L,0xc7d60b489d199f10L, + 0xd1d1f03d5f16fa95L,0x96c780c932fbeaf2L,0x0662e250376ff106L } }, + /* 15 << 105 */ + { { 0x728e334678571c8fL,0xd0a886b56cb339d3L,0xf4ea33380a5671baL, + 0x43823401a64850a4L,0xa7729cd533117b9dL,0x4dd457602b78cffbL }, + { 0xbe0571115a67d812L,0x7ec6cf925105a3fcL,0x5dbcb4bc0ccafeecL, + 0xa7587f15803092f8L,0x67ee61d5a884efadL,0xd4ced554ca47d9caL } }, + /* 16 << 105 */ + { { 0x02c6b6083b03dcbcL,0x2b20149e3b9d868aL,0xaf5ab01d4f57eb0cL, + 0x59935b94d750e515L,0x32721b408f89ad68L,0x673bd755a7e3ceffL }, + { 0xbd462fd8ef3b3393L,0x991422640e59a120L,0x4162da619263fa61L, + 0x2ed1f2deb6488eb3L,0xb0bd37a8725680c4L,0x17218bf029ec27b0L } }, + /* 17 << 105 */ + { { 0x444071ff84ff1ebcL,0x4b4171e87f789cbdL,0x4a832cca2db4e8daL, + 0xe229ffb6dc209c05L,0x9efbfd7eb5f0b3f4L,0x65e07fe774fbbe6bL }, + { 0x2892c8ac627b9d41L,0x01a20eb94297e7a9L,0x2f54e88646f29860L, + 0xc425accc188798ecL,0x6137251c85c80580L,0x6cc0f9c4f386581eL } }, + /* 18 << 105 */ + { { 0xf677bdd11cb61a7bL,0xfca1faf8932d6113L,0x1d5bbf97a531bbe2L, + 0x3d5e4860c849fc47L,0x388943cd95fe4da2L,0xffb7d5e073add43fL }, + { 0xc3166ae828fcc058L,0x89dc7faae0d6f6e4L,0xe6daf1a6f527ca01L, + 0x500a703a56ef1d8dL,0x3573d0a3fc914df4L,0xd780e745ef8dc2a4L } }, + /* 19 << 105 */ + { { 0x90a8f3380500afbcL,0x8c303270838ccf6fL,0x82cbdc98458254c6L, + 0xc2f24d03b367ddbcL,0x5d3daa0d6c882354L,0x824d313d376599d0L }, + { 0x6e5075df7b9dd1b6L,0x6871a3d4d69c9828L,0x8b3762f59cffa148L, + 0xf2184f67eef8c656L,0x437630c296a1537eL,0x92a0667c4cbf8249L } }, + /* 20 << 105 */ + { { 0x6e929912ef619478L,0xe7ddaf255ffc5939L,0xb71133cf96dbbca5L, + 0xee8bd53f17da5104L,0x7601ce6adc49be68L,0xa1ca3b3cc63f2a87L }, + { 0xebf388c2a0de1668L,0xa0f6c38dd0ec6bd7L,0xc8e0875ddac451ddL, + 0x179fbbe5a5afce85L,0x0727095673bfb06bL,0x992afcd047622925L } }, + /* 21 << 105 */ + { { 0xe3b0122624f262c3L,0xaa7a0925dae30b22L,0x36104c95a96a18f9L, + 0xdc6090f5539b6740L,0xd70270ba11040a88L,0x53997b57ea3342feL }, + { 0xaaf1d47d63393e4fL,0x9db8aa3fe8a99625L,0xed571a32c3926e1cL, + 0xd6e898526e565346L,0xb3984bbd873b2589L,0xaeb7bf3f3f5f68e1L } }, + /* 22 << 105 */ + { { 0x75a4a19a79ded4a8L,0x1368e269f688177dL,0xa24d67118581e23aL, + 0xae63d5a6746b3830L,0x0c68d3e314017304L,0x521a5e7de4d45dc9L }, + { 0x69d9adfaf77ca616L,0x1f8d37f4bfda67f3L,0xa2833ba1027e771dL, + 0xae49b00367141a63L,0x04e6f282ed6f1968L,0x65d7d88f060f9157L } }, + /* 23 << 105 */ + { { 0x5dc3137b512e4026L,0x43e189595d6ac980L,0xdb7dfef39eac06a4L, + 0xa8f3e2aea09b0650L,0x80a8594c575e047aL,0x9eba41bcf0c58bf3L }, + { 0xdc04cc7679812341L,0x716050eaeed1be66L,0xe559782099b77be8L, + 0xe543aef055183ad5L,0xbbddfb814c08a959L,0x6e54d86eb5368e8bL } }, + /* 24 << 105 */ + { { 0x170f8a74e7aba263L,0x6b4e1d7b986b151aL,0x5f65bd224b08921aL, + 0x1017ae3de6caca3aL,0x613f36b626cb9d5bL,0x8a1e2f2ded19d99bL }, + { 0x52c915a5c3c519c2L,0x3c9a33305902fa08L,0x2cd7f7c206a51a12L, + 0xfed60db66e0197ceL,0x4e5b2bb7d971b04cL,0xebebeebf2f45ab13L } }, + /* 25 << 105 */ + { { 0x43b10a0673220e06L,0xdf93af67777cf022L,0x830195efbeea9ed4L, + 0x0a36b71812353c9bL,0x520e2e8d1ec8c488L,0xdc985ffaadac5e16L }, + { 0x0ebac566f3f58ed7L,0xc7747562a2cd13a2L,0x6a5b4cbce3901864L, + 0x66634acaa374b634L,0x45e000877f4680dcL,0xb783d01f9fdbe92aL } }, + /* 26 << 105 */ + { { 0xcf6d51be36e1c05bL,0xf59b6665e1da0ad8L,0xaa8bfb9d727a701bL, + 0xb1680942e26e268bL,0x09d41407e518661bL,0x8b0dfbfb3757a993L }, + { 0x34ecb09f6cb33380L,0xfcd77efede342bf6L,0x9f8fa6c6e476c5eaL, + 0xde30410fb6257416L,0x416ea101bbd47b91L,0x86ebd19e4aeede80L } }, + /* 27 << 105 */ + { { 0xfe7562e00818226bL,0x922d8fe662b46275L,0x6216698b491adc2eL, + 0x5bdf7a59f6a38f2eL,0xc0640bf937710dfcL,0x06ad30a9df687f48L }, + { 0xc561dc7d3eb66e6dL,0x7444ac83d08616c3L,0xebfcccee84984618L, + 0x35a03bafbb15eb51L,0x7c907f9fc17a5de2L,0x2e48ddb5814634dfL } }, + /* 28 << 105 */ + { { 0xe466d7a7ea51a37aL,0x5203e990cdf97186L,0xf700953096c84ba0L, + 0x4e32fbe65f89d1adL,0xe530349aa9be221eL,0x0f7f9c2e50b31508L }, + { 0xa6796f5c3af5a574L,0xe220f6daa2a2df89L,0x99ec4811d8b65510L, + 0x4dfdac69ed373b27L,0x663f46b1bb55114cL,0x44236350d167e032L } }, + /* 29 << 105 */ + { { 0x1382e90ba65f6a57L,0x3557ab88e5c903e1L,0xcc0cc77f032067beL, + 0xdd8da09f67797328L,0xeb2979d45114c09bL,0xaaca95bcc4eb598eL }, + { 0x651a7ce5a2b776fbL,0xc20fe9315312ffc1L,0x842957357dcf479fL, + 0x022ba6e2ee5cc0a7L,0x6d27e37185b0ba5cL,0xe6f212bdbcd5f2c1L } }, + /* 30 << 105 */ + { { 0xb0c2ce87a9088f95L,0x47ec07e0acb11d2fL,0xfe84fba0d30ad231L, + 0xaa98e35f18a08eb1L,0x36adc3f2f6a27510L,0x622d202751fac4fcL }, + { 0x4be765cabb9b6ffcL,0x934193571cbfcbeaL,0x83542d9cbef14402L, + 0xf27504954612b4b4L,0x91aff597bb988ba6L,0x229031e51d61f6f9L } }, + /* 31 << 105 */ + { { 0x6b04a446ea29e65cL,0x9b6247a696c48a99L,0x95aa162f60c83930L, + 0xe387f544e30821eaL,0xbe1cdab306c51b7eL,0x40175d151fc7b8f8L }, + { 0x89df5ff36384d331L,0x02eb9aa4fe1aaf5eL,0xf24155f789675704L, + 0xbd2e8cdd87f72f4cL,0x2856b3c46de30f01L,0x2356f0a3ecf8af25L } }, + /* 32 << 105 */ + { { 0xfb09e7564bd044efL,0xdbc9fcdfbb964fb3L,0x451c5b01cdb1f4f5L, + 0xb02f9068f1dd1cf0L,0xd4765e7c0c687e41L,0x89b64981d1967bd3L }, + { 0x06a0e4ecf0439d65L,0x564c387da5abbcecL,0xc1e9d01ac651d806L, + 0x5e6ebd830618a96cL,0x9ce1aacec54ad8ceL,0xe5248a089953f90fL } }, + /* 33 << 105 */ + { { 0xd65f3b909b6ab239L,0xbc259a6d9ea8bf80L,0xc10d5c235944f964L, + 0xbd6b3f6f61eeac6fL,0xc4ef2d8383e92858L,0xb80d5ab0a3736bfeL }, + { 0x27bebd1176695c40L,0x4de92348ea4f5720L,0xd70d93e6070b892aL, + 0xfce03d0be626d5abL,0x2525e8ea81014bedL,0x6fa3df16a70e2799L } }, + /* 34 << 105 */ + { { 0x42b8350a7bbc41caL,0xd7861ad49af59bc9L,0x2453d07c5644d328L, + 0x2b92643ad7c8ec43L,0x7c14d3c7cd5f1fd2L,0xcee050463d373c7fL }, + { 0x17ff60bd0ab2b35bL,0x473925e0dbb7f655L,0xdbaa015aff3ee023L, + 0xbc1ff6d6087ecfbfL,0xc44e1c8c5fc66ca2L,0xc60a193850d6b257L } }, + /* 35 << 105 */ + { { 0x5ff44f3ed8f0983cL,0x9de50da0bb82cc15L,0x504f82ec94757c44L, + 0x72a4fc9dc8a07028L,0xd4d6e4cec3d5e64cL,0xc6148fe780008568L }, + { 0x71ba3fc525ef66d6L,0x969cc8694f6589f6L,0x5016c8c2d934ab25L, + 0xa78382f6959e8881L,0x28bcb8bea20eee18L,0x055ba80b37edd7c8L } }, + /* 36 << 105 */ + { { 0xbe389fef9c98ca3cL,0xdc3ab23b910370e5L,0x866cb37d5e8eb20dL, + 0x2f951ca9c1e32fc8L,0x54ef6ab15fe24e6cL,0x6038b5efcfcb8cfbL }, + { 0x362e076b6eec196dL,0x47bb3aefd398b505L,0x9f3128eb343711ccL, + 0x8dda2fa8d28e3269L,0x908c52c7eda48846L,0x65fb3a05d53b0917L } }, + /* 37 << 105 */ + { { 0xeae35c02ed711239L,0x16ab943fa97db2d7L,0x9770bb578f3b0599L, + 0xa88ffb95956d04f3L,0x3b937af5f4dcf6ffL,0x311ef2cc0bc41f56L }, + { 0x00e9214a2860ea2aL,0x2a64b18a7bd12d8fL,0x20a5b9da6a2b9dbcL, + 0x5c16a412fe1b8edaL,0x6fc306af7b9db98bL,0x964c35de25dc9363L } }, + /* 38 << 105 */ + { { 0x81f4739e6df16589L,0x2ea2fff11f8b8ac4L,0x3baff03d33e02c36L, + 0x7f07526874d77660L,0xa442d7fa758eed7dL,0x584cbe9866625864L }, + { 0xeed35d579d167ff6L,0x56627c2e3c7bf84fL,0x908df5aedd011153L, + 0x2694e54d242fc055L,0x25beed9a2f2d60c3L,0x29d3f22fe2ee5293L } }, + /* 39 << 105 */ + { { 0x14940dbc178f9859L,0x6e6e35b7329ec4a2L,0xd1f198096707db4aL, + 0x6eb310b79fe4233aL,0x8f92556eb41e1d8cL,0x2ab28e231d7ce522L }, + { 0xc5d0f5dfdd5c4d68L,0x3f5146d825101083L,0x3a04aa53de9ee4cfL, + 0xcf36f1e3d9357f64L,0x05a1896444889f68L,0x1096c87aa96a4137L } }, + /* 40 << 105 */ + { { 0xfa4b6697a8352657L,0xf5696452cad6ec30L,0x10aaba60986c84ffL, + 0x49bdfff4dae014e1L,0xe2a810bd0abc0e46L,0x1dc5b81462d1dd5fL }, + { 0x15d2f2c723bb4561L,0x5ac7b6421818e30cL,0x40c6b6f94c545f5bL, + 0x5875b6b2f99241e8L,0xfa3e88a9d6708293L,0x1c936920ad6d9344L } }, + /* 41 << 105 */ + { { 0x6516f6210e18ec42L,0xb967eb43df8c26bdL,0x624ee27e69addc2aL, + 0x34019d6339063252L,0xb317fdd3dcd99d7aL,0xc3d566825d314caaL }, + { 0x04992df3367506b8L,0x13e4ab2e547262b7L,0x35f130352e287d3eL, + 0x92e0a276211304d9L,0x94e7129417133d22L,0xb35302275fd71a28L } }, + /* 42 << 105 */ + { { 0xe1d9273c9ae60111L,0xe86aeac3d01243ecL,0xc7257b27fa5989f5L, + 0x57737dc89807d3ccL,0xe1ef78526937551aL,0x74ab9edb15dd2d58L }, + { 0xbc47b23cc59962fbL,0x376ff30fd3bba76dL,0xaf0035872788ab98L, + 0x1e475c68619b472cL,0xd79984c89c6a9835L,0x5ceafba510219a94L } }, + /* 43 << 105 */ + { { 0xc25ae81155d238d9L,0xf2a21fce4ba4456fL,0x4ebe44d0bd1a440cL, + 0xe821687f83d958beL,0xb4ce63423ba09f9dL,0xf271435d139048bcL }, + { 0x2a3db37c99c6412eL,0x50cba09ccb36dbd0L,0x9e5231aef6e65cf8L, + 0x48e9105d90118a6bL,0x2d58d372368144cbL,0x48702d59928575baL } }, + /* 44 << 105 */ + { { 0xc71ce040d1c9204cL,0x8ad09d7373f7686eL,0xbcc6d88dc6fcf31dL, + 0x22a0b71aaf428ad3L,0x7767944847721255L,0x2b720c7e316b808fL }, + { 0x3128a7cc5ed45b8bL,0x9744c6c0f79fa1c7L,0x738e94efd22728d7L, + 0x8a652496fff8f874L,0x0e4a5ade566c9751L,0xfcde62db64e3199bL } }, + /* 45 << 105 */ + { { 0xb068ec91aa63f5fcL,0x547e7e471a29ddfbL,0xe3e5de42b17b8e5dL, + 0xb5c84f27264d1361L,0xa68d10a426432715L,0x4f31e81c23e48e1dL }, + { 0xe32bea6116dbe185L,0xfaeab7256d1d34feL,0x0ee437cef3a8ca7bL, + 0x2b8657a2f458446bL,0x8779a3d4c52e3dcaL,0x243d7d0e71654165L } }, + /* 46 << 105 */ + { { 0xc4a346b2de23afe2L,0xf8e00f790fac7ba4L,0x22393604ab76b7d8L, + 0x109233d7a06efba8L,0x5bf89334c7bf56a4L,0x27ed4a28135d4cabL }, + { 0x07851ad2e32ca02fL,0x41b7ffa630c97f29L,0x383b3716e4457ccdL, + 0x6ce8645b0b43a50fL,0x73c82018fc5b907bL,0x79a1467381bbcf0dL } }, + /* 47 << 105 */ + { { 0xcf5331d35e092e41L,0x7e0b9fdeb43e3c15L,0x842a971182841f82L, + 0x2d837c810cb9d1ecL,0x6aff6d6873095ddeL,0x2a7f6f40c9478ef3L }, + { 0xb6e8ac80a9976e39L,0x3853fa5474e40024L,0x664b159a6d87c1d9L, + 0xaaedf4b4b20b5d11L,0x8a1ac277c5819de1L,0xf10276dc6450b97eL } }, + /* 48 << 105 */ + { { 0xa8d7901c7c16c09bL,0x628ff3be42e1948bL,0xb905d7c504e4bce1L, + 0xdfbf9c4e5ab0696fL,0x0f4e6e2ab6db9cd5L,0x4857e570482e40feL }, + { 0x5ccd9b421c3beed4L,0x171b085fae51a947L,0xcebe0dbe59065754L, + 0x4d052d3a461c1620L,0x396bac422fe541a7L,0x8e714cdb70bf32d8L } }, + /* 49 << 105 */ + { { 0xed82f15e6ca1cdcbL,0xc5ae5cde51b9a9cbL,0x3b2f78cec70c475eL, + 0x0f22d10b4243c675L,0x1db96885facac4c6L,0x2fb7884817df2f2cL }, + { 0x25fb9f4e990f3104L,0x1416733ecefa14f7L,0x3a33828384a5dc24L, + 0x6d75d3d02564288cL,0xf7bea8b69b93e62aL,0xa5ea8695349f1740L } }, + /* 50 << 105 */ + { { 0x38feea7115e711b8L,0x129aea564accd3eaL,0xc53e54c412b23539L, + 0xb15bf11a2b280c59L,0x5ea76f5782d44df5L,0xea79f833d4ac1af8L }, + { 0xe547deba08330c6dL,0xbaa89422663ef402L,0x17263762d215a5f5L, + 0xb9509a19c02b5f9eL,0x9bb99fcb025caaccL,0x43f4494b25f24089L } }, + /* 51 << 105 */ + { { 0xe55e592c98563c70L,0x4e62ace5d013c82aL,0xb6025ac16fcf7380L, + 0xac4a8157cfdff8b9L,0x1fa181344497acf6L,0xdcdf05c0ef09d3e9L }, + { 0x7a65490d83d8e716L,0x2aee0b35e98c46feL,0xe62381dc7d6d4035L, + 0xc7162b78203975c0L,0x1079d8b6aad2c021L,0xe3e1cb4370c98838L } }, + /* 52 << 105 */ + { { 0x3ca01799f04dd97aL,0xd6d1d41d3f9e03f3L,0xac2713eda55fa375L, + 0x2bd440556a89a5e5L,0x8582d98458f5c269L,0x7f9b3527fb31fc27L }, + { 0x23f91951d810580dL,0x99303919360a3debL,0xfaf10326b5e1eea8L, + 0xf96feb4838ba5ac8L,0x1508b1002a639622L,0x0766a1019dc93c78L } }, + /* 53 << 105 */ + { { 0x0c79d40679a0290cL,0xc09bca0c57eb7a00L,0xf7274ffc163c1dcdL, + 0xd64ec461bb2c83c4L,0xff3b83efe9ee350bL,0xa490157d01882c72L }, + { 0x626e1f3d3312310bL,0xd2097e03cdd5d62cL,0x705c3fcadbf659c5L, + 0x2dc1d7cc810fa413L,0x6313192ad67d58a8L,0x6e1e5bc3597f63a6L } }, + /* 54 << 105 */ + { { 0x6100535ea0d42639L,0xb126e939d921369dL,0x2d4c826e4999e42cL, + 0x159063c6f62f77e7L,0x063c42914e632555L,0x8d3ee387b35d8220L }, + { 0xbd951cff9b2bac3eL,0xd9b943f1bc248755L,0xeee7017ad3a6074cL, + 0xbcb9e0e6b0872a21L,0x26d80e0949dff656L,0x2ad7d4e335fbf620L } }, + /* 55 << 105 */ + { { 0x6ce5840df7f9503fL,0xb96f82996abf4f6bL,0xf71f33853ab55fcdL, + 0xe347e891e83a8109L,0x12c5dcdeeb48f0faL,0xb0f02553cd7183a9L }, + { 0xa7d74862c414f01fL,0xbea40c5cae369360L,0xbe9785e5022d5192L, + 0x1a3224a50d318251L,0x4d7200093fcbceebL,0x1fd71167c2976f6dL } }, + /* 56 << 105 */ + { { 0x03c88a8566d2ee47L,0xee8e5c34455ee428L,0xd90a3d393870d90eL, + 0x2fd78d14f2fdb976L,0x9472a6066a312a30L,0xea68e2283484af2fL }, + { 0x7cf25951ac9e5cf2L,0x024f07ee37a28e95L,0x5d479379e563a2bdL, + 0xe87b50a4b46e93d8L,0x9128fc11f137285cL,0xe46efdf77c67d7e6L } }, + /* 57 << 105 */ + { { 0x4050036c7cb0b9a1L,0x8560750c1161d7fdL,0x4d293a521b247ba9L, + 0x4b25e54c8f1b9d31L,0x91c89139c5baa0aaL,0xa2f75f9f2202b7e2L }, + { 0x6c0915dd4d2d1388L,0x575d90f703717fd7L,0xd90c059b03e0626dL, + 0x7004305ba4239e8cL,0x39fb4e2e989775e6L,0x20c31fc8d8a239c6L } }, + /* 58 << 105 */ + { { 0x4de318054ab51b84L,0x4a68443c6aa00707L,0x2c3637f05b317f3bL, + 0xb8ea6f87c0fc14a7L,0xcd0cb4fca2cc6af8L,0x6b5fc899317083fbL }, + { 0x1b8f160956e6dfa1L,0x698299ed92b77d20L,0xdb84ab7f14fc3fc1L, + 0x944666a35d5fe625L,0xe9a3448d7e064ab0L,0x53f62fa01abe1440L } }, + /* 59 << 105 */ + { { 0x04bc8a2bc8c676b8L,0x502a73144a577562L,0x494d01f11ff01f9dL, + 0xfe648df164d98f70L,0x80bed0d849719dd3L,0xb77a8f09c231e190L }, + { 0xc8aa8daecc011818L,0xf313be4f5918814eL,0xf28fcb74488b5bfeL, + 0x71e23b19b3345c98L,0x1cfb7c0596eba9beL,0xa88e73b941c61971L } }, + /* 60 << 105 */ + { { 0xdc7050459cfd4295L,0x1cc9648eedeea59eL,0x88f4af1c0e9ca92dL, + 0x45d0b53f69689317L,0xa122a6dd41c04186L,0x9df54c3a277fba1aL }, + { 0x1efc55a5017eb9ccL,0xb253f7b661d1ecd4L,0xd03f8ec6acfb7854L, + 0xf641e5f49f338dbaL,0x6b6a680a3a3addbcL,0xe80babb5b5cd058eL } }, + /* 61 << 105 */ + { { 0xb48da67307873319L,0x53309cdf3bf5db9bL,0x1bc510e64ee9dd11L, + 0xbb8e529a7388950aL,0xc9c0ce3c7f6e6175L,0xd75753f88a290784L }, + { 0xfebdd94ba80acc08L,0x942cdfebdc846b30L,0xbb64799f6ca7099fL, + 0x40f03362d1326fa8L,0x95b2d9db97b62e9eL,0x5ad9ce165301d9aaL } }, + /* 62 << 105 */ + { { 0xaa5fead9dfc59ef1L,0xc1348e98b2cc1e9aL,0x83dd617e77bda968L, + 0x0fdcc0837c8997dfL,0x9206ae234cc62b01L,0x88aec92f417678dfL }, + { 0x9d399af791fb8920L,0x399eebd13e8a22a0L,0x32f3bba735bebdf3L, + 0x354c1c5004c2f32aL,0xc2d6b5514052c926L,0x16a1f71f656a7eebL } }, + /* 63 << 105 */ + { { 0xd7a755bc14a8c57bL,0xa97b901341ebec55L,0x88b88459143a1a9bL, + 0x7aa178cc7e19e3e0L,0xb8359634635dfb65L,0x63fd26c7c169e28aL }, + { 0x89d9090d953272f5L,0x63e571196383845aL,0x0e26c0cf886a1f1fL, + 0xda56332db7057a29L,0x6b5d303f7a459c6fL,0x3c351b771bb704c3L } }, + /* 64 << 105 */ + { { 0xda2b0725bb296c27L,0x1f22ffa4d341171bL,0xc721e35a5b132756L, + 0xe5695e84fadb6907L,0xbc5a3bf4c283f546L,0x9182cb3edde128aeL }, + { 0x179c7fa66592e05eL,0x1e604790f38e8586L,0xaf7e83bea16bad55L, + 0x6f41231e9137ecd8L,0xac87543d8f30d1abL,0x630a9d87b1ee0ee8L } }, + /* 0 << 112 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 112 */ + { { 0x359cbfa05e4f1914L,0x6992cd48d922176aL,0x2fd5e90f630cbcb5L, + 0x2b0f61306ddbf238L,0x5070970a3af753e6L,0x433d009441727016L }, + { 0x2eb15b3b9dca97e2L,0x3a7379cd00d96875L,0x0d4374aee930a75cL, + 0x3cd36046849e7727L,0x9ac3117e336a19ffL,0x2d1373c9433ddc04L } }, + /* 2 << 112 */ + { { 0x985dcb43e4362d67L,0xecb860c2a939bea4L,0x40597f3055fbf1d5L, + 0xb6d166bf43fcd98aL,0x5932570915ec99caL,0xe05ae3b9c5bdd370L }, + { 0xc18f78270c7b943bL,0x84bde9c64dd572ccL,0x5d50a89df478e56bL, + 0x242c2f4864d29053L,0xcda12c6161cf7e0eL,0xf8b6890eac8d1d40L } }, + /* 3 << 112 */ + { { 0x7a9a9dd7b6b11af8L,0xac4c50dd16a42f8fL,0x1550267b6726c324L, + 0x12cfb2fd7f841afbL,0xa41b19052f046430L,0x8f5f5373b7d786cbL }, + { 0x7b61b39c729e09fbL,0x07a5415f2626da4cL,0x65d6efb84a348905L, + 0xf377862cf2e864b9L,0x3c94000dab96cdb2L,0x2176321a8efef0f6L } }, + /* 4 << 112 */ + { { 0x8c558000c1c1bc68L,0x9e48a67a83fd6ca6L,0xacf0d75ceb7a35cbL, + 0x0fbdce4cf0a93110L,0x82b2d13a9cc50c85L,0x696fd259cef70d6fL }, + { 0x1cc9be2e457b88c2L,0x0d58b34b1f04c0bcL,0x52bd479f195a532bL, + 0x769fe6ca1ab3605cL,0xba6a63e48a24c1e0L,0x86dea46299da5d7aL } }, + /* 5 << 112 */ + { { 0xdf2a6cecd24790f3L,0x37bfbba7b87ca06dL,0x7c8a7e4c0de8a6aaL, + 0x5c806b94be7b8f5dL,0xccca1c714fda3e7eL,0x3c1cbaf9cff788e5L }, + { 0x17a081a9565d0464L,0xc4eb995713ed1b82L,0x0d7c90549e4cfac7L, + 0x6fb74c629d53a200L,0x65b9ed6d5f977a8bL,0xe2279cec0ba2e7c4L } }, + /* 6 << 112 */ + { { 0x8435e2962d4412dcL,0xa36cbfef972350d8L,0xe2fe6e6fece5cb15L, + 0x6f249b095336f7ffL,0x5801feb9908ee267L,0x7649a837fc8f217bL }, + { 0xfc1adc3ea0ebc808L,0x1ef06bec94f08075L,0x4afb5404cc1d9b72L, + 0x75cabd61a1f2c5a4L,0x2bd797e1cd08f195L,0x4f1b5cdecbea0f49L } }, + /* 7 << 112 */ + { { 0xe9759aa9e7aa87e2L,0x2d54a5fbe5909f55L,0xe49a59aa2c80bb61L, + 0xdb89e21230c9b328L,0xf42b9adb004ebffcL,0x4471b983479678e4L }, + { 0x0dde5b0e97709e2dL,0x2f35c653a12bdb85L,0x9f8d7a5cd8c8285cL, + 0xd7cde5971d156206L,0xdbe765d7a8e126bcL,0x2e645b6de3f4e60bL } }, + /* 8 << 112 */ + { { 0x509abccb65682820L,0xfbfa1d094ff86137L,0x1ae371bd640bc2f6L, + 0xa155c2978f546c68L,0x8858cadcc08b8cbfL,0xafac5b0a1d96948bL }, + { 0x919cb22682e25016L,0xd147df4ab064ffc3L,0x25dd0f1ab4abe560L, + 0xc6bbe6369cb75bd1L,0xbb367cf947a778e4L,0x5714aa4dbde524b3L } }, + /* 9 << 112 */ + { { 0xce3c8218e61b1439L,0x8be5a9cb67f79d28L,0xb1bd1386d5164b35L, + 0x0bc24d96b9adbac7L,0xbcee4f0ec7482414L,0xac15b5b66ca5d49dL }, + { 0x79caa999f20f9a50L,0x89bfd652a911308cL,0x972fe26d15245a7dL, + 0xd44d0f6e1d0d2939L,0x6749beaedd439057L,0x02627a6ad4b6f416L } }, + /* 10 << 112 */ + { { 0x7e882e8cb437b791L,0x9afde25afbe334cfL,0x60184381da52f9fbL, + 0x935d33a1001df73cL,0x38f303df080682e5L,0xd9cf2c1f4e9a29b2L }, + { 0x889d265e00d9208eL,0xfc1cc2221fd8e817L,0xdd14f1a2ec71428aL, + 0xe81cc4f9d9e973aaL,0x26a154963696468cL,0x0620fe6409d546acL } }, + /* 11 << 112 */ + { { 0x06ed3e64166be92fL,0xe1da6e27c51ea53eL,0x784f2514acb2b245L, + 0xc544e50f8e24077fL,0xad449938c5c01787L,0x5d9ef8d527d41dd7L }, + { 0x37114064e15d4a96L,0x7f0c92aa1dd45321L,0xc1f11d56b9c72ee5L, + 0x91f3b3f7a78e6d3aL,0x0cf440b0c9488cf7L,0x14d3defd93df403aL } }, + /* 12 << 112 */ + { { 0x3fa4ea0225aa1d44L,0x22c68e17f74a6a3aL,0x351bcb80f489e72dL, + 0xdabdf118be0268edL,0xa3bf9e1984d2cd16L,0x318506a2d67393a4L }, + { 0xb0c6b2d8615ed517L,0x42ac507c3dcba0f9L,0x60570dfb51235e30L, + 0xc677628dedb033e4L,0x0290c22766e61f76L,0x1d8450d09888943fL } }, + /* 13 << 112 */ + { { 0x1b8f5ed7155a3daeL,0xc9d2433aa46ed72bL,0xe99c7fe38ca361fbL, + 0x606b08c19626fe7bL,0xe6447257c0ea792aL,0x5839e2c62e1156f3L }, + { 0xb73135dd5eab6d41L,0x200f2e488ef63584L,0x4c73885ddda1c49eL, + 0x8d606a75b5428ee9L,0x2a73cc7aa62699dcL,0x484a58941c6c8de5L } }, + /* 14 << 112 */ + { { 0x2365b4150decae0cL,0x9c8567ece8583741L,0x35d6cfae6d8842a7L, + 0x4e6c98e6dd0db8e4L,0x584524e767b34d02L,0x786ea52f554c6117L }, + { 0x8952ce169320725fL,0x8eb7f91854c4c8f2L,0xdd34f77afc799251L, + 0x76b8c3173e05d37fL,0x664cbddcebb4d365L,0x31ba98b90dfa1a98L } }, + /* 15 << 112 */ + { { 0xf113a7bd651c186fL,0x417bd7373737a50aL,0xddb40d201b858249L, + 0x62a60745345f5b45L,0xf0a03f5c2d4e221eL,0xcafde67cc64621a2L }, + { 0xbbbfaebcbc3c06c3L,0xadaf9a16b8383dc0L,0xcd21aa308f343ea2L, + 0x64cefec0d890128dL,0x2ed9b8f763b44054L,0xc0a49e2917c0ffcfL } }, + /* 16 << 112 */ + { { 0xc6307399166915dfL,0xb35545bc5da8a26eL,0x8e0126aae3a99321L, + 0x0fbfdf76da9308d1L,0x2163ed6b6168e505L,0x71f3d0087500d8bdL }, + { 0xf57159605ac13f65L,0xc1cd9a6755172d5bL,0x6b225f7e53d84c65L, + 0x9c031269025029daL,0x54c1edfa17d89aedL,0x5b0238786b435150L } }, + /* 17 << 112 */ + { { 0x96d69db1146abf28L,0xc924454924d221dbL,0x7881951c137bdfe1L, + 0xde2d490dda51f789L,0x6033c2c34b0a1e0aL,0xbe214d8c08dac13eL }, + { 0x3d5abfa9a5a1d055L,0x3433060f6fe02a62L,0x88608c7ba37f2833L, + 0xfd2da6f0e74dd6c1L,0x27c22c17fe000000L,0x04a1f15bcfbde005L } }, + /* 18 << 112 */ + { { 0x01204485f340b522L,0x588a9e1c9367a099L,0xb3d1a4b466005913L, + 0x522ac504d55cc36fL,0xa6c80e511b72eabaL,0x15025a7acaaa89b5L }, + { 0xc9166912bec1a986L,0xe78e9642f19044cfL,0x230d51ab4756908aL, + 0x6795942aac04cb90L,0xcd2cc9eca2a92818L,0xfccead967cf52961L } }, + /* 19 << 112 */ + { { 0x32fa291d52ccf481L,0xbb137ef901ac0eafL,0x13ce2183011746abL, + 0x7e64248677bfea0aL,0x67cbba0e5e7e5032L,0xc900998a1f2b69fbL }, + { 0x62ddd91aab3256afL,0x1f0f216911d7996fL,0xab2f2d540e4dd4feL, + 0x05b577a92ec64ec3L,0x8071e88708ef233aL,0x9be1f8d60e649a5cL } }, + /* 20 << 112 */ + { { 0x5f78334137732664L,0x625b85dc840b6f8eL,0x7dcb3d256cdf0959L, + 0x87a5ae19d4ce1845L,0x43bf0721b0dc016aL,0x6569ad52f6a5f6f3L }, + { 0xa2697f15560ab87aL,0x4c6fd1a0060dcd57L,0x652a7732c3167f56L, + 0xe355fef05294a5e0L,0xf7b3177dcc59c562L,0x511c96dddccf4b1fL } }, + /* 21 << 112 */ + { { 0xec768f587622c0b9L,0x7c9eb5490416afe7L,0x3c3d87f55795433eL, + 0x74eff3cba4611446L,0xb2c79249dc7037d3L,0x70062ebd8bb1fc42L }, + { 0xbd0d3532a4ad91c8L,0x42411c139f5ee0c3L,0x11c4ee91132470cbL, + 0x496438979fb2a135L,0x4c1df7e0ce2ec891L,0x689cda57e16f7413L } }, + /* 22 << 112 */ + { { 0x3b42838a2a0030a1L,0x3f37587ae05ba56eL,0x6382a86f44c16650L, + 0x6c1bc67da6f9f136L,0x7d152d907ada0f41L,0x9115319d5c40c0f5L }, + { 0x1143028632f58e3aL,0x5dcf7ec7eda5c5a2L,0xf04404a9f334a0b2L, + 0x75e0b4a84ec2cbd5L,0x86e89728d079dbf0L,0x796700799a99c605L } }, + /* 23 << 112 */ + { { 0x98456a79b1d2a3fdL,0x4e8ba91e6dd789e9L,0x8e0bfa33a435226eL, + 0x42bea2f48cfea5ccL,0x5ca5fb0321b14602L,0x73faac5826877b13L }, + { 0x0ddb6ea203905ebbL,0x67bc35f1698cd7abL,0x24da47d85d9af735L, + 0x1a2a7c1dd786000eL,0xb35fb29e23ccaceaL,0x1c063466bf1f51a7L } }, + /* 24 << 112 */ + { { 0x1e7ae1601e94d949L,0x177dc53ee78e6221L,0x8af29d8f7aeb9882L, + 0x2d9a60fd9e3f3906L,0x6979fcd6df962156L,0xdd2fe5887e1e54b8L }, + { 0x9cccf31076643453L,0x94ece1a84e0643d0L,0x745449cbc111d8cfL, + 0x872afa4ae6cfbd97L,0x5c27b7ca10dfb34eL,0x505e62bc533480feL } }, + /* 25 << 112 */ + { { 0x6dd2007363141676L,0xdb099810c5c4c657L,0x2bbbcbaf8c369f32L, + 0x339e3ded08794178L,0xcc362a32315c4cd7L,0x5d288ff37dbce794L }, + { 0xafd05d104d0cb6c6L,0x3a6dcee9d386c7dfL,0xa207dc17e311ee74L, + 0xc5794286abdc751cL,0xf45136e5d889b985L,0xb25e84638d8f32a3L } }, + /* 26 << 112 */ + { { 0x8711ebfd1dc32f77L,0xfc0e851f3933d758L,0x90b679fd64a859f3L, + 0x0914a975ef37a81eL,0xcef80495d675c502L,0x862d3b65be18c403L }, + { 0x0d53f957305b4aa2L,0xe404f2570e5bcb47L,0x833a8644854b6b63L, + 0x5709f53b99f8d3d9L,0xc400dc1f13893effL,0x75ca01714c65086eL } }, + /* 27 << 112 */ + { { 0xdaaf8e76eeceb904L,0xbce9ca54b9e31f92L,0x4442d0c88d06a58fL, + 0x5966e1e5eda0ee34L,0x043125f058edc555L,0x44d0311749cf0931L }, + { 0x292aea12a99ae5c2L,0x1e9be1702a2bade4L,0x003ec2826b21b444L, + 0xc158f3cffc41d601L,0x25a839f4c4b3f4c7L,0x4a36bec399e64264L } }, + /* 28 << 112 */ + { { 0x829bbe7e04e6bda7L,0xc52b64ded3e667dbL,0x98aa40ecaa2fc128L, + 0x2c6997d011fbef94L,0x70ca76aa97c8167eL,0x558f8ce7b1083886L }, + { 0x5c621e35d250f064L,0x757710f8f535b2c7L,0x5d118d8faa69ee95L, + 0x02ffe667b27cd9deL,0x65711ac7d13e51fcL,0xdbbf16278cb1a1c7L } }, + /* 29 << 112 */ + { { 0x3c2fcbceeab0bb77L,0x569d6c7e4e1b17adL,0x22e06899b0518730L, + 0xf8466d9d19f809e9L,0x372e254288359d10L,0x8074483532d5bb82L }, + { 0xc88727d566060945L,0x08e9246572a0d38fL,0x84ca145c9f84a861L, + 0x8363463c1c004212L,0x9debab72bd3ad87eL,0xce68c150a988e65dL } }, + /* 30 << 112 */ + { { 0x1c172e5ea71dbae0L,0xf7794eb19b80bf40L,0x3007c5705d7d2829L, + 0xa8d44d6fcc97cf00L,0x093a9784f6abea6bL,0x2ac4a67564cca46fL }, + { 0x14fcc56350d8fc8bL,0x53133983a11ccd07L,0x7cf09bf68e6b8f26L, + 0x49f864d57b06e3adL,0xd526a765c373fc6dL,0x7af297c6151305d5L } }, + /* 31 << 112 */ + { { 0x18f941bfcf7c1eb5L,0xda10720a130163b7L,0x3c4894f46bd9bb34L, + 0x7575087bc8ca64f1L,0x68c424852c8f3798L,0x986214eecf0e5839L }, + { 0x3723b713df2b0b90L,0xd81560d5d229bf8aL,0x0204ae5ff993078eL, + 0x55206d9186a14833L,0x8c7d09181557fc96L,0xe2cd5dcdddba9705L } }, + /* 32 << 112 */ + { { 0x009ef80aae238fa1L,0xb41d9b24486af6b5L,0xab4455ed685add95L, + 0x18f323f672c7dac8L,0xe7009790e372f168L,0x4d5bcba6067bea99L }, + { 0xf15bdbcc51a2a9a9L,0xde7e4f742fac9169L,0x2fd62c304bdbec36L, + 0x8b3ea93d1b3ac6c7L,0xce1c8e5c9c293889L,0x19664dda11564f8bL } }, + /* 33 << 112 */ + { { 0x207a738245406afaL,0x7c1c398d1675bc91L,0x2ae99d8ba1bb7a43L, + 0x63f134e8c5e176e5L,0x4a624a1c48364268L,0x471974f1de65c5deL }, + { 0x44932063ea90b0cfL,0x13ba5019d8fd7e30L,0x6281f71348510422L, + 0xdaba3f14bc1a523aL,0x333e5eff924cc5cdL,0x861ab150e9113d1dL } }, + /* 34 << 112 */ + { { 0x332d308dd9b9461cL,0x3e9b4a95b7014261L,0xc557f608c2beeb5cL, + 0x9ee927187c8531d6L,0x55ff3dfcc0002ff0L,0xed96119eccd9b325L }, + { 0xd779ba03fb92416bL,0x63b75d351416be79L,0x793cb1fbfc9ad27fL, + 0xcc762a5b87f1bc59L,0x6e7a23389bbb07d8L,0x99b6e278aa7bfa44L } }, + /* 35 << 112 */ + { { 0xeb142de02bcce03eL,0xcac04711577565e2L,0xa949c7350ab07328L, + 0x8f15874cd7d347ebL,0xade8c67a696dc9f3L,0x039e6b7c66a7bcadL }, + { 0x1260bd4acb8cb9d2L,0xdbf05496d4801bcfL,0x6b37a4d30ffb845eL, + 0xc3968fe150b50889L,0x261e82f4525c6a7dL,0x539f634912aad50bL } }, + /* 36 << 112 */ + { { 0xcb1a9d2ceae4d774L,0xfdec2ca998a0775cL,0xa538acbd0eab9e25L, + 0x6901ebfd04dd34b0L,0x998ab679ed4c6409L,0x69b1d7ee0235b865L }, + { 0x4f2e6e5723ac3be6L,0x2b2072aed4a00479L,0x5c12fcdc2ce2f059L, + 0xfc688c45ac329db8L,0x16d377a51f539427L,0xebe4e2cfa08ed9aeL } }, + /* 37 << 112 */ + { { 0xb394214715d60238L,0x60d8909bbe9d4febL,0x013827b78654e16cL, + 0x465b3078824fc55aL,0x361e6523e3fcd6c0L,0x2ef44d80ef88b307L }, + { 0xdca7809fbeb2db77L,0xe649d591da97468aL,0xad6079b77c28ff0aL, + 0x6a21ce1ac4897775L,0xde876f7b5a592fd5L,0xced421a585a1dd36L } }, + /* 38 << 112 */ + { { 0x9793bdf6a045a442L,0xdb3c60472713ed37L,0x9929d32261344a0bL, + 0xfb48c2dc831af45cL,0x730226df53a8a077L,0x3a5baf8a18876559L }, + { 0x99736e7d8e11f9edL,0x3e7663dd0c09dddfL,0x368a29ed89b8a23dL, + 0x5443d7f5d3a68663L,0x0b84b464c6302455L,0x235c6eb5cf088847L } }, + /* 39 << 112 */ + { { 0x13307013b8de0a3aL,0xfb10e919f592fd9eL,0xd09e5b2571401ec7L, + 0x6e8091c11d94cf0aL,0xb7d79fc74193b129L,0xb842a3695f2c05e5L }, + { 0xcf6fc6cbccdc7614L,0x77d6408180102a3aL,0xde4b9304f30c3488L, + 0x4fd9f8d89bd08e48L,0x58ac01245963b063L,0x1f11335c747fac66L } }, + /* 40 << 112 */ + { { 0x5f266f13175418b2L,0x6bd7a86903a626f9L,0xc7b532304a6f11caL, + 0xa216b056bfc8ccedL,0xa274d5d8b288cb7cL,0x6fc4a35d924897adL }, + { 0x1ea532eb81fc6940L,0x2fcd817e2acbbc45L,0x45eee93f67814fa3L, + 0x3b3da48c1229e035L,0xd049a976efd8e3d7L,0x8087dff7bf81f314L } }, + /* 41 << 112 */ + { { 0x9ccd802fbddea807L,0x08a64e86d93b97f6L,0x422c0f5602f04e3cL, + 0x25aecab133900990L,0xcdb2c5c15d4b4d2fL,0x849a6b1f5f43e42eL }, + { 0x4689b815446e7361L,0x49abaf6ca681fba0L,0x304d84b18289a564L, + 0xa6529d430b779df3L,0xca926da67b51b195L,0x3640dde5c829ae84L } }, + /* 42 << 112 */ + { { 0x747235495424e1d0L,0x3861ae65c85af64fL,0xc56ff12baab902c2L, + 0x9aeb9e154fbf264eL,0x14e3c13942ca40d2L,0x6c26da41c1ba0250L }, + { 0x97a6031df51a0967L,0x88fea7710e623393L,0xcafae4c778574eefL, + 0x2c4c281198119f28L,0xd190fc749276d971L,0x843f4baf9273f01cL } }, + /* 43 << 112 */ + { { 0x1b2d643de50ad79dL,0x1ceaee7ed3075486L,0x13a003f3ec287aabL, + 0x09a4a825e8c7aeddL,0x93babe5ad1d4c05cL,0x8115bfec95ab084cL }, + { 0x629e8e0a289ebb8aL,0x923167a9bd992f77L,0x440edf75ae16ce72L, + 0xa67dd37b0a0019d4L,0x174b341978b0df8dL,0x010746a5ad6e4c60L } }, + /* 44 << 112 */ + { { 0xed05e4bf8342da4aL,0x36d881f3b565f0f2L,0x3fbd04e1411e627fL, + 0x40ac13cb0411889aL,0x9f6006cab5b25fd6L,0x0e79d377e31404ccL }, + { 0x9fd6474a5af3ea01L,0x89d7ddcb2a27d905L,0x2c1beebada12e71dL, + 0x3ecb11e1833eb7deL,0xa348b2f6600eb1faL,0xc227192183f2657fL } }, + /* 45 << 112 */ + { { 0x2cfaf519e32ba792L,0xa99113d7f929b512L,0xd347f7d18f554e19L, + 0x18f0374f098a2ad8L,0x073855acc174e0b9L,0xf155c6c009324c23L }, + { 0x3388c39605d1e427L,0x144356a9d39221d1L,0xe3d4ffed492a84adL, + 0x519c65e6d1e53c29L,0x334f470a2813c717L,0x69aa0a1de0a400e7L } }, + /* 46 << 112 */ + { { 0xd8689c9c39e70b62L,0x2b87157e6cd86fe6L,0x53d55de887c0f35dL, + 0xb2d7141de09aa44bL,0x3499553084fe7c21L,0x4550096c16b19be0L }, + { 0xb0a8ce05b856dac0L,0x570223450e211887L,0x8d4a7431aca17401L, + 0x96bf439857400a0eL,0x1e849d365ffd5f34L,0x7e70f6253a6d23acL } }, + /* 47 << 112 */ + { { 0x511ad0024b4ecd64L,0xd2287a28f37bf796L,0x801d2c2dcbc1f22dL, + 0xf0d3a6944df568c8L,0xa7fec550af6836b0L,0xa27dd6e887a426c7L }, + { 0x2f730e5b59c6b695L,0x9df438ee93ee2b36L,0xc4def9eaf2cfc4c6L, + 0x82ddcca0a209814bL,0xb2e1de4f6dc916d3L,0xc6798e7453f81a55L } }, + /* 48 << 112 */ + { { 0x77faac22bd366155L,0x13cc4038282f11b5L,0x31ad1dd45fbd35abL, + 0x7e0de9da45d6d40eL,0xa16c5f1939749ef6L,0x761cd6cf85691cf2L }, + { 0x156536ad4d59b802L,0xee98dc4187c4b11dL,0x165a1eacd35088fcL, + 0xce8a733538fb995cL,0x34d0d3313293b3a5L,0xfcf548ca8b570e79L } }, + /* 49 << 112 */ + { { 0x4c4bddca99e8cb05L,0x2b900ed017c5be91L,0x0ba0201b40adbfc1L, + 0xb5098cf8534595ecL,0x356e23ff80f56f69L,0x8b3fa12e748555a0L }, + { 0x9063437677b8ebdbL,0xe3eb33fdf040b6a8L,0xcc5b699539b611ceL, + 0x20171523c693be7eL,0x5c4364d760849cf0L,0x30f3376372c4d303L } }, + /* 50 << 112 */ + { { 0x0757295022a8c8e0L,0x6e05715866ca81ecL,0x7e8e36890f804bc9L, + 0xcba813a191b99207L,0x3f11f7abe50ab65fL,0xaefe5479b6d05954L }, + { 0x48dd59a1eff5cf18L,0xa623b738bda11ecdL,0x586e755818870f08L, + 0xb2c471a50e38ba1aL,0x5b21c42c69ce8032L,0xaf040e6c7943d78eL } }, + /* 51 << 112 */ + { { 0x6364714c4852f979L,0x7ed7aa310700cd35L,0x9021e46d9376733cL, + 0xf2b65ed3b6de8d03L,0x0e3d00c16652346cL,0x6630fcb75d27e2d0L }, + { 0x69cc20ded79a1c20L,0xa6d77163be3745e6L,0xab36946379aacf14L, + 0x8bdffbf1b935a1daL,0xda8eb343b63096f6L,0xf61988f13c966345L } }, + /* 52 << 112 */ + { { 0x06f684ffd31f390eL,0xa1467be560ec98a8L,0x7cbdd03eaa80fddeL, + 0x0ae4d114e204ded1L,0xb8ebeb29a004c3e2L,0xd93cd70726009581L }, + { 0x3ff2ee49f1b9d3ccL,0x0e69e5ac753526ccL,0x8cb2243e8b13f47bL, + 0xe2c5ae8d7fbfc5aeL,0x8e9af723394a45d8L,0x0b1114dbd92ab8d0L } }, + /* 53 << 112 */ + { { 0x937d9d2a73f9ff5bL,0x07c8c147de0fd740L,0x3880ead73639b680L, + 0x879d6f836558cc89L,0xf32e14b975bc8c84L,0x278ea5e4bcf6f8cdL }, + { 0xd9f25ea94baca6cbL,0x676e4bdd44d0ceb2L,0x98042ac190868974L, + 0xdf227f370711b658L,0xcd6d29b46ef0e4f8L,0xd04f5bf88f817e92L } }, + /* 54 << 112 */ + { { 0xc7d62be78354f4ffL,0xd6fd9d590ac4d9b6L,0x13fbed772b50ab82L, + 0xc4c5be374362b766L,0x5d67bfdd6c59d059L,0x10c93cceac02f34cL }, + { 0x3bec1f3b72e35ca4L,0xb1cfade159f4820bL,0x679edbcf80fae051L, + 0x6762f5ba6671737cL,0x28b425db3fe77970L,0x4bd6d2ebe778aaaeL } }, + /* 55 << 112 */ + { { 0xdcbe0018aecd5ae8L,0x7f178b7aedb2a7b0L,0xedb5c805b427179cL, + 0x25fb6a084ba080fbL,0xeb6365165f1b263dL,0x814c520092acb04aL }, + { 0x936f97a988d94b88L,0x6d54f1768b45e4b7L,0x6321e3bdb0cc515cL, + 0x9118d0318eb5be13L,0x5be9188a8c574e96L,0xcdad43f3f281f19dL } }, + /* 56 << 112 */ + { { 0x7be5946ea85af34aL,0x420593c9da6fb0e0L,0x40b83c00987f9246L, + 0xac35f4e9a15d192bL,0x1979bd33776a678cL,0x0a7d973e8f6068d3L }, + { 0x71d322e87e6298feL,0xbb23a29936af9b65L,0x14e2b9706644c50cL, + 0x5f7f207373570bd3L,0x40215c569055538bL,0x91372e64365500c9L } }, + /* 57 << 112 */ + { { 0x2763961a303ef488L,0xc357c32fbf865ec3L,0x32ca1a943663e409L, + 0x9d9040217de506a9L,0x1f56e144249028bcL,0xd76402e61c5c7cecL }, + { 0x98dcac65b0dd9d4fL,0x887f6e97532facf6L,0xc0d5d2a123c2cfbeL, + 0x0566bd59d18d8b1aL,0x67404eb1297a071eL,0x10f24d9b26529285L } }, + /* 58 << 112 */ + { { 0x34808f5ca479ef4eL,0x60effdea9ff10abfL,0x471a077cdae34e0eL, + 0xf34df9562f9d1408L,0x4f8bbffbe46961b7L,0x6a80b0276336a6f4L }, + { 0x28e57309ca92e5dbL,0x27fbb139ce31cb10L,0xcea87ae28d24334bL, + 0x3781f438de6db765L,0x3328fc09edaf054bL,0xa8acdbcfa94396f8L } }, + /* 59 << 112 */ + { { 0xa05b72aa83a79820L,0x3210863ccdeeaedcL,0x192d5fdcb76fdabbL, + 0x25ec4568f10c17a7L,0xbd51e31fca556920L,0x8ab534f26a7e40f7L }, + { 0x2ecb28c041145d5bL,0x4e95843df9038557L,0x65605d17d783699cL, + 0xf728cb1178bddf7aL,0x2d823ae8bee2a60cL,0x02030edb8eb48325L } }, + /* 60 << 112 */ + { { 0xfe517758aa04facfL,0xa5216df44c421615L,0x4d87767d4f133b52L, + 0xdae81b7699757264L,0x53c1a0e3e3ad4323L,0x2c565bbd53b401bcL }, + { 0x94d2354fcd54a0e1L,0xf43d0f053f1a02a7L,0x52e7ee4af660b949L, + 0x563ec009bc208df4L,0x58c0b975bf21c4b1L,0x29a8e5adeb029e52L } }, + /* 61 << 112 */ + { { 0x4c07b3e4283bdd75L,0xcd94d2a385dd6177L,0xc1ab8a5cab097530L, + 0x90301468a5fd9ff7L,0x2a3e5b4064d0932dL,0x77e3b67e435e1c0fL }, + { 0x3b5d261c14f7bb4dL,0x1d67a760bab7bfc9L,0x507aad46d799621bL, + 0xf44567b5f4f3c3b9L,0xfaa97a3eae2bb6b2L,0x7d373b163594e2c9L } }, + /* 62 << 112 */ + { { 0x29ef2da9a15e6ea0L,0xf411e20dcd168689L,0x34944975049a4b24L, + 0x0effc2dfe035cd24L,0x5d77178b0a954cf7L,0x3504bc357ab2d8c0L }, + { 0xc3405000ec32219cL,0x00442630421a5a3cL,0x0548505c7f49819aL, + 0x6bdb281fc805d0e8L,0x03cb57ac97484e09L,0xcf0926da58a14cc1L } }, + /* 63 << 112 */ + { { 0x0715055cc85610a7L,0xd2642935fa6ca505L,0x87ef95128c361749L, + 0x89cd669a8c8156d2L,0x5cdcd266ed60d7ceL,0x99ccc96df59fb53fL }, + { 0x82400f4655df7f73L,0x2b6aa1d9af34f742L,0xa6cbca79c398aa8eL, + 0x7697bdea02b7325eL,0x1cb036b94fde4a79L,0xfe11ff96307fb964L } }, + /* 64 << 112 */ + { { 0x6a3a23279af0a75cL,0xf832a8159f1f250dL,0x17030c3322a82d3fL, + 0x24bf18ea14cbc835L,0x319dc4cab2da2727L,0x481df3606d020d4aL }, + { 0xaeebdd8a7fc22ba5L,0xbd0515c6a91e28abL,0xfc8a2978595f361dL, + 0xe60dd96c1ae8fa3cL,0x19c2109aa5341575L,0xfd6e92bb06a0ee48L } }, + /* 0 << 119 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 119 */ + { { 0x2e32f896cde5e785L,0xcd55ae7ab9db8f31L,0x278db1ad8f832885L, + 0x271d9078adcbd933L,0x2208fae34a64f863L,0x974046e039c89365L }, + { 0xcb46f272b3cd0cd3L,0x31f34e1a74e59edcL,0x3421d316edd50418L, + 0xb1d8a064cabe36edL,0xdb13e560362efcdaL,0x567c2b6cc71eb3eeL } }, + /* 2 << 119 */ + { { 0x2af8ed8170d4d7bcL,0xabc3e15fb632435cL,0x4c0e726f78219356L, + 0x8c1962a1b87254c4L,0x30796a71c9e7691aL,0xd453ef19a75a12eeL }, + { 0x535f42c213ae4964L,0x86831c3c0da9586aL,0xb7f1ef35e39a7a58L, + 0xa2789ae2d459b91aL,0xeadbca7f02fd429dL,0x94f215d465290f57L } }, + /* 3 << 119 */ + { { 0x94c3938b4c9324feL,0x0dea07003fe78a0eL,0x57ab9daa019e7dc6L, + 0xb0d7b14a9925b79fL,0x3c9a638b937a5daaL,0x3b14fd0de62943adL }, + { 0xbaafb635ed3ae4b5L,0x3060a090b2bcfaa2L,0x389d9e7f7aa8f217L, + 0xd7f987c6e9310a65L,0xec0927f993b69c0aL,0x9335e9102381a247L } }, + /* 4 << 119 */ + { { 0xc08550024b950889L,0xee99dbfe8ce24da0L,0xdda71d964318e860L, + 0x01d3d39604fe9b85L,0xda4bc065e25e7e20L,0xd3a50b87e076c81cL }, + { 0x5b9f821931e5f494L,0x6a140527a6a1b821L,0xf52683e4d8dd159bL, + 0xca9c888720b18043L,0x73c040fa08a0d8f5L,0x92e482e8179525c4L } }, + /* 5 << 119 */ + { { 0x8b9f650f3e776590L,0x41ba807f47703a5dL,0x8cc1a550fe907078L, + 0xd70cb76c8f00b84bL,0xcaee21566f3e6780L,0xfd6a51f595c2d03eL }, + { 0x2c897c5556ffa08fL,0x08589a6563d13d54L,0x6a1eed4287bbacf7L, + 0x66aed4f5ee709d78L,0x67c925bf1178ecabL,0x6870f4c8a29cf747L } }, + /* 6 << 119 */ + { { 0x37ed2be51cfb79acL,0x801946f3e7af84c3L,0xb061ad8ae77c2f00L, + 0xe87e1a9a44de16a8L,0xdf4f57c87ee490ffL,0x4e793b49005993edL }, + { 0xe1036387bccb593fL,0xf174941195e09b80L,0x59cb20d15ab42f91L, + 0xa738a18dac0ff033L,0xda501a2e2ac1e7f4L,0x1b67eda084d8a6e0L } }, + /* 7 << 119 */ + { { 0xe3a67b2d5e12e708L,0x3a4772e2ce48f234L,0x78f9dbc334794271L, + 0x9880053a3e6a61e7L,0x031c30b87c0f6e59L,0x8113df6cf7b972f8L }, + { 0x3625bdce18ee148cL,0x72c2b8efdb885158L,0x4c73c80c9a7f0df3L, + 0xbc2dd8a507b92470L,0x5a33e4dfdb005677L,0xc699cf5ea5ca9dd3L } }, + /* 8 << 119 */ + { { 0x3a828904a4d2313eL,0xbf4946b192e66888L,0xc574898ae5fa19d2L, + 0x0b13dbb65e1c5fa4L,0xf11343ba7c390fc2L,0x35b1418fd7d32187L }, + { 0xc92cb1bb83e7fe7bL,0x0b969455d78365c4L,0xda69dfe5672f2af7L, + 0x9c62d7b430932441L,0x165672ad94af02d6L,0xd2cc734dcde81c22L } }, + /* 9 << 119 */ + { { 0x6353420218d07dd6L,0xc7c0c8f128a3cb4eL,0xa41d4c55d7929131L, + 0xf1aaab3445d21f63L,0xd69a59545ec3e9feL,0x209732c1b8ddea2fL }, + { 0x368b9c59e1936916L,0xb011c662ab1f8585L,0xcce30a25474e57b4L, + 0xb79c76df7049c61dL,0x984739950ccf165bL,0x7c6f4ab40ce897baL } }, + /* 10 << 119 */ + { { 0x1d27efce1080e90bL,0xa28152463fd01dc6L,0x99a3fb83caa26d18L, + 0xd27e6133b82babbeL,0x61030dfdd783dd60L,0x295a291373c78cb8L }, + { 0x8707a2cf68be6a92L,0xc9c2fb98eeb3474aL,0x7c3fd412a2b176b8L, + 0xd5b52e2fc7202101L,0x24a63030f0a6d536L,0x05842de304648ec0L } }, + /* 11 << 119 */ + { { 0x907d88035a8432bdL,0x89232a5a2638fe30L,0xa120eecbe2089014L, + 0x3a5208cb5a2c9e97L,0xe163d29a3449eb4eL,0x3df984530eaba88fL }, + { 0x55d3b9afa1547443L,0x316aae18f2a60ceeL,0x64d0fd30d6e11a5aL, + 0x65de345808ef6002L,0xcede56fab4a3d1deL,0xa5bfa8d9a4bc1588L } }, + /* 12 << 119 */ + { { 0xd45e350133f4d416L,0xbb40233a4bf9131eL,0x1532a088e302483aL, + 0x3475e8b82c2485c0L,0x08f9ea56969cdbe6L,0x31928645253cd738L }, + { 0x1cf323a4ac9836beL,0xdf647ccf02b6e4deL,0x9a31e84fc06f3d09L, + 0xd326b86e39efe6d9L,0x77e3e1df14ac4decL,0xf2d5917af3e0c582L } }, + /* 13 << 119 */ + { { 0xf88238f1376216b2L,0x8c7522db7d15f653L,0x50aa7a74a21f74d8L, + 0xf7a964c8bc9e1a0cL,0x33ea64251387ca6bL,0xda84fe74e7be16a6L }, + { 0xdf0462d727867aaaL,0xeb7f0ab8ae6be1b3L,0x21abe5a5d9bdec8bL, + 0xdbb99199ac4bed1bL,0xf65c19d935d13c0dL,0xf966e22e4df74056L } }, + /* 14 << 119 */ + { { 0x67477cdc30577ac9L,0x51dd9775244f92a8L,0x31fd60b9917eec66L, + 0xacd95bd4d66c5c1dL,0x2e0551f3bf9508baL,0x121168e1688cb243L }, + { 0x8c0397404540d230L,0xc4ed3cf6009ecdf9L,0x191825e144db62afL, + 0x3ee8acabc4a030daL,0x8ab154a894081504L,0x1fe09e4b486c9cd0L } }, + /* 15 << 119 */ + { { 0x7b4e65ebae4219adL,0x2e424c441184a0d3L,0x10eeb898d32e179bL, + 0xadf05e2d8afa9a6dL,0xecd6c18bbeccd5f1L,0xe592115c39ac53e8L }, + { 0x9ccf231ac8c7b9b6L,0x1848b4fe678774bcL,0x2050856386782b91L, + 0xb7caf7cc74dc6018L,0xe80805485cf9273aL,0x9609897b246b4851L } }, + /* 16 << 119 */ + { { 0xe92b56c002cf37fdL,0xa75bbcb0f71b34deL,0x7754d0ef50f5c482L, + 0x850a9ef611fa89feL,0x97d74b1bba4ea7d8L,0xfc757c25aab7ba2eL }, + { 0x06f30ab0f2a67fddL,0xb10aba1412e72af8L,0x47580bca7a2e053dL, + 0x85795598dcf0e14cL,0xc3596781d6f55310L,0x8ab251b74c9b7e18L } }, + /* 17 << 119 */ + { { 0xdc56cff85279e5cfL,0xa33a6765fdbdf1adL,0xc122c0eee5077a4bL, + 0x44c3b190a98ab643L,0x334a6868b991d197L,0x598bbf185d6a0488L }, + { 0xd028bfdc5a0e6f96L,0xfd1a37f5e11c57b6L,0xe1240a3003f82183L, + 0x6afae98c390d8536L,0x554a42dcc244b181L,0xa3d422d75f4cb4b6L } }, + /* 18 << 119 */ + { { 0x512f82f9d113450bL,0x5878c9012dbc9197L,0xdb87412be13f355bL, + 0x0a0a4a9b935b8a5eL,0x818587bdf25a5351L,0xe807931031e3d9c7L }, + { 0x8b1d47c7611bc1b1L,0x51722b5872a823f2L,0x6f97ee8a53b36b3eL, + 0x6e085aac946dd453L,0x2ec5057de65e6533L,0xf82d9d714bb18801L } }, + /* 19 << 119 */ + { { 0xf113abe17d48bfe7L,0x51d77fa5213facecL,0x27bb373f21269089L, + 0x31e9850e7b188989L,0xd20a15f41d50a1c6L,0xb4887ed9d9746367L }, + { 0x8920a7e2325f19c5L,0x691352358ad74492L,0x713d1471d19a76a2L, + 0x952cb9e5873ab310L,0x5b359d1ffa8eb8cfL,0x55aab5ad8b9c9e7cL } }, + /* 20 << 119 */ + { { 0x4ab138504dbb8798L,0x0e7980d772d04cd2L,0x1755c5660b3271c6L, + 0x8414efb09d9d1468L,0x61a586301795ce66L,0xb6a8b393232924a1L }, + { 0xa992f0ceae031bd6L,0x6747fb5f2915acc1L,0x03daa26693e9c0d2L, + 0xc18fa3645400d554L,0xaf04ff8d9497e895L,0x86c3cfc250b6b339L } }, + /* 21 << 119 */ + { { 0xdf26f6605b26122cL,0xeb6c188c4d6b80ccL,0xae2efe59ccec172bL, + 0x5cdcd958f3f7d693L,0xa2ac2594c5f993f0L,0xb96ad8cf3f7cb591L }, + { 0x7e2f88f8446abbabL,0x3d1a5eb6f6051f2bL,0x7d882e82ad6f49daL, + 0xe32918e3c4e7bbffL,0x442a32789be81150L,0xa1d34da1bd14557eL } }, + /* 22 << 119 */ + { { 0xad81fa938ba5aa8eL,0x723e628e8f7aa69eL,0x0ba7c2deef35937cL, + 0x83a43ec56decfb40L,0xf520f849e60c4f2dL,0x8260e8ae457e3b5eL }, + { 0x7ce874f0bf1d9ed7L,0x5fde35537f1a5466L,0x5a63777c0c162dbbL, + 0x0fd04f8cdad87289L,0xca2d9e0e640761d5L,0x4615cff838501adbL } }, + /* 23 << 119 */ + { { 0x60c7e16cdf66a95cL,0x25b1078d5d0bd644L,0x77f8d872bd933e31L, + 0x5c4c382de2e1536cL,0x5b3b37c09295ee0dL,0xf94698d4ecce42b6L }, + { 0x947ef80c4db8f2c7L,0x34661f7dc70dd82fL,0x17b288a7f2311006L, + 0x1f1171a66815e1caL,0x0f71f66ce80d6235L,0x858c665a87fa5a59L } }, + /* 24 << 119 */ + { { 0x376b2a7f04e1e6e3L,0xea0dcb70a31774b4L,0xfc7fe4cc5cbdec2eL, + 0x8568499df03f459eL,0xe9fd8fb28b78900eL,0xd33c6e30e431bf97L }, + { 0xd904b8f5c896e766L,0xa8f577cf82748cefL,0x93dd921b87e044b3L, + 0x23d79837f76eebe9L,0x5e0a7493e569feebL,0xd0797549414dddb6L } }, + /* 25 << 119 */ + { { 0x9bf04f567781556aL,0x30be1e8953ebf7c6L,0x6f4899cf713fe432L, + 0x4f641fb7c9ef741fL,0x03560819002cc010L,0xfa51f8f7b4bbd339L }, + { 0xe09c5ef77f1dea5cL,0x39cb20d97255fec5L,0x407746862ea38859L, + 0x68ca598ecd7a29f3L,0xb8025dd67a9db4d9L,0x4feaeeaed9dfe491L } }, + /* 26 << 119 */ + { { 0x9422789b110b4a25L,0x5c26779f70ad8cc1L,0x4ee6a748ec4f1e14L, + 0xfb584a0d5c7ab5e0L,0xed1dcb0bfb21ee66L,0xdbed1f0011c6863cL }, + { 0xd2969269b1b1d187L,0xf7d0c3f2afe964e6L,0xe05ee93f12bb865eL, + 0x1afb7beeed79118eL,0x220af1380f0fe453L,0x1463aa1a52782ab9L } }, + /* 27 << 119 */ + { { 0x8cf42aa26b99ca6aL,0x696850242f091dbaL,0x9d887e6ad7d3270aL, + 0x627754fd5c9b735eL,0x3b8735a811d95df6L,0x74debd8b52443251L }, + { 0x1f8dd5b66181583eL,0xbd0ca92c8b570a9cL,0xc373a61a71ae3274L, + 0xf4b2c88d1c4c16cdL,0xd3e6ec3baf33efabL,0x8c54d2721bf6f0d0L } }, + /* 28 << 119 */ + { { 0xfd9e3542bfe5b1a7L,0xb42d2a4175938ceaL,0x74688a153befb760L, + 0x8daeeaa22e33dbe7L,0xc9c1ea083e677801L,0x68ecf4e434effe1eL }, + { 0x927700ccd294c321L,0x9e2e723de940afc5L,0xbcfac07a7cf6cd43L, + 0xa009ef94d1006bc3L,0xa02016b0373d13e3L,0x4e097adbabae5822L } }, + /* 29 << 119 */ + { { 0x7535175d48752720L,0xf51086ee850bdf07L,0xce322c33cb4c3f4dL, + 0xd863f7edb28965fbL,0xfe46a4e9885e4afaL,0x58b5c871136d7ddaL }, + { 0x126eddaf6ed07824L,0x084ce962844fcbb8L,0x9ac0787157dfb4c5L, + 0x97451fcc4d6b5910L,0x9f14b1ce0843c9c6L,0xf737f6c0a0e18596L } }, + /* 30 << 119 */ + { { 0x7c139d56d7dbe5f9L,0xfc16e6110b83685bL,0xfa723c029018463cL, + 0xc472458c840bf5d7L,0x4d8093590af07591L,0x418d88303308dfd9L }, + { 0x9b381e040c365ae3L,0x3780bf33f8190fd1L,0x45397418dd03e854L, + 0xa95d030f4e51e491L,0x87c8c686e3286ceaL,0x01c773bf900b5f83L } }, + /* 31 << 119 */ + { { 0x0028dcae855a0b90L,0x74c1e36026f0d718L,0x34f80e3ca059f144L, + 0x85b5d8e3f2bfe1b4L,0xe124601f453de099L,0x8b164ad6221b3efdL }, + { 0x636f45ebbe004ab0L,0xa23093e99f231a8aL,0x48e05e8e2287b992L, + 0xefec5e5b4477cb8bL,0x45a65afa8ba0231bL,0x92d38bd88b1af6baL } }, + /* 32 << 119 */ + { { 0x8db8b78cc898b8bcL,0x686896da502940cdL,0x67e50f022dde2e3cL, + 0x2e2461f38cbf406cL,0x32182781e1f7ff60L,0x26934b05e30e2688L }, + { 0x95adc204fc4494f6L,0x4c7f30c5161b7499L,0xd5caf060b7341737L, + 0xed93187fd128d46cL,0x3f2819cb20fc1e04L,0x48c4086f2b7f70a1L } }, + /* 33 << 119 */ + { { 0x45693c00a92ca9faL,0x046b218d63bd525dL,0x40f1d6cc6b1d6a68L, + 0xfc5807c5c54dc1f0L,0x2875d4d98b5690f6L,0x7a753543d0f72a83L }, + { 0x01f2c35ae28b5309L,0x38fb5f121bcef323L,0xd6ea6896256a9bffL, + 0x4380fb2c44d65badL,0xb587d641c3556fb6L,0x74c5ec1905167f32L } }, + /* 34 << 119 */ + { { 0xdabe347578673b02L,0x4f0f25cef6e7395eL,0x3117abb9d181ad45L, + 0x4b559f88aa13de0bL,0xfd8efe78ea7c9745L,0x080600475dd21682L }, + { 0xc0f5de4bd4c86ffcL,0x4bb14b1ef21ab6a2L,0xacb53a6cf50c1d12L, + 0x46aac4505cc9162eL,0x049c51e02de240b6L,0xbb2dc016e383c3b0L } }, + /* 35 << 119 */ + { { 0xa1e3cb2255b7f121L,0xc9183b13dd01db7dL,0xfe26aa801469dae6L, + 0x7318df7fd9ecfe2bL,0xade0a24d56dd4acfL,0x6e521c2222d1ba14L }, + { 0xa039800a40afa1deL,0x9c7da49d5c6af72aL,0xf7ae921cd3fcc7c6L, + 0x76af2407dcab63e2L,0xdc1618dbb6dd49ceL,0xebc65c4d362cc88bL } }, + /* 36 << 119 */ + { { 0xd847939132202bd3L,0x1dacde87d6631ac1L,0x99d2e71f905a94f4L, + 0xd3c21f5a7e67dd7fL,0x3605c28e3c43cf23L,0xb6cd5ac74d3b3070L }, + { 0x8bf748ba246298d7L,0x9e939fbd0f053664L,0x3bb3e7b8cc303783L, + 0x359bd3e56189c417L,0x299d0ce1f609ae34L,0xd7221cc7b9ca801dL } }, + /* 37 << 119 */ + { { 0xb7c823506b73c5a6L,0x7fea0d95fefee640L,0x6d5dd775f68b6be6L, + 0x4a5576147cbfa333L,0x6cad79c2fcd9b17dL,0x49aec3d405c4dd35L }, + { 0x3b1f3754c3792470L,0x351ef2ccbe00cffcL,0x44a248916a71f45eL, + 0x1e7a6013b8640d08L,0xf0f476154efcd556L,0xc82171444fe15dd3L } }, + /* 38 << 119 */ + { { 0xa3c56ad28e438c92L,0x7c43f98fb2ceaf1aL,0x397c44f7e2150778L, + 0x48d17ab771a24131L,0xcc5138631e2acda9L,0x2c76a55ef0c9bac9L }, + { 0x4d74cdce7ea4bb7bL,0x834bd5bfb1b3c2baL,0x46e2911eccc310a4L, + 0xd3de84aa0fc1bf13L,0x27f2892f80a03ad3L,0x85b476203bd2f08bL } }, + /* 39 << 119 */ + { { 0x85f9b301218642acL,0xb3f3b36f8728ef66L,0x4a833bea2ebb8181L, + 0x7d3bca9d8541a662L,0xd3be6d0ac5a0ecffL,0xaf52a2a9528da950L }, + { 0x4b431910131f72caL,0xe2708d36933d5550L,0x195340a469abf146L, + 0x84ca66e4e4e2e131L,0xd9402ca7e16c39bfL,0x5beedce343ca6041L } }, + /* 40 << 119 */ + { { 0x87c5915395523a22L,0x56686f525ac5146eL,0x9ec69ec718ccf766L, + 0x13f36d4ff6e21a4aL,0xa0841e94098691f4L,0xbd9d52d2bd91dd2eL }, + { 0xa8765981b3fa43eaL,0xb0cd17cd600b9761L,0x02dd9d71b5abe842L, + 0x63df33a63689a53bL,0xab4b85bb9d9baad7L,0xce2d31c1eb74e549L } }, + /* 41 << 119 */ + { { 0x8d69a654f2472426L,0x91a4b6a3ff7aeff0L,0x51dd8e76fdcc7cb4L, + 0x5f7d42a273731cd7L,0xc127401aa99c9d9aL,0x8ede9330c92561d7L }, + { 0x86057a56784c3cf2L,0x8afcf32cb5a7755eL,0xa0a5b561c71cd3d9L, + 0x0a5d805e36d3f5a4L,0x25a39acd7432a384L,0xd574a6b7b226e9ecL } }, + /* 42 << 119 */ + { { 0xab1cb818567af533L,0x273b4537bac2705aL,0x133066c422c84ab6L, + 0xc3590de64830bfc1L,0xea2978695e4742d0L,0xf6d8c6944f3164c0L }, + { 0x09e85f3dc1249588L,0x6c2bb05d4ec64df7L,0xd267115e8b78000fL, + 0x07c5d7aec7e4a316L,0xcb1187ba4619e5bdL,0x57b1d4efa43f7eeeL } }, + /* 43 << 119 */ + { { 0x886e3f30b29f5916L,0xa419d2c6625f29a0L,0xb4f89fc49bf07dc4L, + 0x86c137a1a165ed88L,0x6fa241a9e5d6280dL,0x08be9b0cd11576f2L }, + { 0x5735aeb7e376b03dL,0xf4639e6d182ce9b9L,0xb6948499cc688f57L, + 0xfde146636552009eL,0x3eeeae350a2e8553L,0x50447f1b659dfe2eL } }, + /* 44 << 119 */ + { { 0xefccd67ed15c33c0L,0x33393846146d5e96L,0x015e97da9ca7354eL, + 0x729b69bac143e795L,0xd4440ecfd4c5d0e2L,0x78c042bb697a80e7L }, + { 0x9361ad1d08602f75L,0xaa354166af489794L,0xe60e5a274966d3cdL, + 0x8346995e2394f9f3L,0x2de33256590f6a15L,0xb14427bb43298ac1L } }, + /* 45 << 119 */ + { { 0x38fee83a74680d2cL,0xd8019e5c0e700c8dL,0xcfaf5614475da1b8L, + 0x11893fc58f0159e3L,0x4c101127553813c2L,0xd273055208f82a6aL }, + { 0x8728834c74a3ce9aL,0x66b939a891906488L,0x42ac7c07b88d36bcL, + 0x663d7411d989bb72L,0x650e5d6eb284c066L,0x052b7f6710d8f124L } }, + /* 46 << 119 */ + { { 0x3618891fc8176a96L,0x62c4b084e5808b97L,0xde5585464dd95d6eL, + 0x27a8133e730b2ea4L,0xe07ceec36af318a0L,0x0acc1286ce24fd2cL }, + { 0x8a48fe4add4d307cL,0x71a9ba9c18cde0daL,0x655e2b66d5d79747L, + 0x409fe856a79aedc7L,0xc5a9f244d287e5cfL,0xcce103844e82ec39L } }, + /* 47 << 119 */ + { { 0x2a8cb0a56ad833c5L,0xe8fab8b844962dd6L,0x31166fd63ee1dfefL, + 0x3aba85a1e1230449L,0xf9f8da66bd1f502eL,0xe4a72d82e3c17ccaL }, + { 0xfa3d661d6070d587L,0x51d10b73c33ed08aL,0x3b0f515cb29f2d0bL, + 0xd82a11d7e1986e91L,0xcf24f81a2201f05bL,0xa94ec1e0d25f8417L } }, + /* 48 << 119 */ + { { 0xc7807daa081ed51dL,0xb7dfabf0e5d2d963L,0x3f78ae2e80d386d0L, + 0xd66275254bbfd04bL,0x238c8eb76d074f92L,0xfe51ec8a5bc5f9b5L }, + { 0x6ba47430cc03177bL,0xe72efda6400b29e0L,0xb905701becbffe88L, + 0x5c61bdb47cf89933L,0xf1eb3084c914aa6aL,0xa3ead71e8245998bL } }, + /* 49 << 119 */ + { { 0xc58ee3013c7eb5a9L,0x02c177220a1172baL,0x8620118394c7c5b3L, + 0x66292bc4e1668debL,0xf51b48f4caf39937L,0x9cca60f43eaea578L }, + { 0xf8e8004a5c2adccaL,0xce7ceeb1ebf49ac7L,0x36346357371d1c54L, + 0x8799e408d99ff07dL,0x3226181d8c3b2cbfL,0x3b4ff42ba437c2c6L } }, + /* 50 << 119 */ + { { 0x00675ba7f25d364cL,0x7a7f162968d36bdfL,0x35ec468aa9e23f29L, + 0xf797ac502d926e6cL,0x639ba4534b4f4376L,0xd71b430f51ff9519L }, + { 0xb8c439ec2cf5635cL,0x0ce4c8d181980393L,0x4c5362a964123b15L, + 0x6e0421e0ffdcf096L,0x624a855f10d1f914L,0x7d8f3ab7614dcd29L } }, + /* 51 << 119 */ + { { 0x235ba8b565868390L,0x853c9346ea936e81L,0x967ff132700bb25aL, + 0xb26d9778561a136cL,0x8b775c4fe3f7e41dL,0xae8f6b2ebd390b2cL }, + { 0x80959adc4fc7224dL,0xd9c913c12eaccf8cL,0xa9a278c79e96f769L, + 0xbc6be3038f26856dL,0xb039caf295d04cdeL,0x42ba0510a91bf5dcL } }, + /* 52 << 119 */ + { { 0x77870665cfbe0653L,0xab84c4b3523d814dL,0x72839d8897cd2bc0L, + 0xb966e521d25b1476L,0x4255d18451fd86a0L,0xadaf9b76dd54be7aL }, + { 0xada6ff627f285e0bL,0xb76e26f46d42400bL,0x1d9fe676958bee25L, + 0xfcd7be9edb59965cL,0x897a90834bcf6e75L,0x64b26f02aabd21e8L } }, + /* 53 << 119 */ + { { 0xee46626beb1a8ce6L,0x2de20371b672fc49L,0xa0fb11b8bd2d9256L, + 0x5b49f70ac2a8dcd4L,0x98935fc9e5dc0ee3L,0xaddbae423bc00993L }, + { 0xbd0bd9e19207f0e9L,0xe86c5365b393bcdcL,0x32184c832d0a9282L, + 0x8fe996d1df34532eL,0x3b33f151c6f45172L,0xd9def9a7b84545e4L } }, + /* 54 << 119 */ + { { 0xd9219adab3493ce0L,0x971b243a52f09ae5L,0xc16c9bf8e24e3674L, + 0x026d408dce68c7cdL,0xf9b33dd9358209e3L,0x02d0595df3b2a206L }, + { 0xbf99427160d15640L,0x6da7a04e15b5466aL,0x03aa4ed81cadb50dL, + 0x1548f029129a4253L,0x41741f7eb842865aL,0x859fe0a4a3f88c98L } }, + /* 55 << 119 */ + { { 0x66bb66f5f56b17ccL,0xdce0bf2cba8958f8L,0xd814318f9ff85781L, + 0x41dce823edd1ad96L,0x71bb754bb59c6580L,0x9c5efb70de594c3bL }, + { 0xf7b4ce5eb0053788L,0x9c26b0342770b6deL,0xe6967b1c8d131e8fL, + 0xfda0efdccf21bf28L,0x2366d47e09cbeeacL,0x62e9ee556629680eL } }, + /* 56 << 119 */ + { { 0xdaff980ff8e06359L,0xb4e0c9e2ead8a883L,0xe3e262023da6e94fL, + 0x37410ed03303c9d6L,0xc044d77b91fb5d82L,0x3559d9ac9ea34d26L }, + { 0xf51a120be21beda5L,0xdd2eef8a3f7befa4L,0x46a26ccd8c79fca1L, + 0x3fb21a682a046572L,0x3624a47adad7c7c9L,0xb9b77ffd4b4174f5L } }, + /* 57 << 119 */ + { { 0xae19a097c9f8c462L,0x477be49917a9d8a9L,0x4a0c41c9d2154c45L, + 0x39313aba1b0d985bL,0x3a70f65cc051b643L,0x0725dabf2d0be160L }, + { 0x29eefc94a69867d4L,0x6acc4cd49d02bce2L,0x0606ab725d4dca50L, + 0xcce81133bfecdcbaL,0x604df3def23b2239L,0xa644b430d20a7529L } }, + /* 58 << 119 */ + { { 0x80de085a05fd7553L,0x4a4ab91eb897566bL,0x33bcd4752f1c173fL, + 0x4e238896c100c013L,0x1c88500dd614b34bL,0x0401c5f6c3ba9e23L }, + { 0x8e8003c4d0af0de5L,0x19b1dfb59d0dcbb9L,0x4a3640a9ebef7ab6L, + 0xedafd65b959b15f6L,0x8092ef7f7fb95821L,0xab8dd52ece2e45d1L } }, + /* 59 << 119 */ + { { 0x43f9a415259ac609L,0xcd6c7aaa0ff5722cL,0xb4689e75b29973caL, + 0x78a43571b690c0acL,0x90dc4ac0a6d3ba1fL,0x38af00a2b773932aL }, + { 0xc13aebdda5e2c9edL,0xfab3a128cf3fed2dL,0xb3b7d29d32eb8ccfL, + 0x9ae1430b6986db5cL,0x35d18edf5365c21eL,0x88f8356e038471ccL } }, + /* 60 << 119 */ + { { 0x45587a7c0794dad2L,0x660833899e9c1cdcL,0x60e7ae4ad242a6b9L, + 0xb5f96b521009df3cL,0xc2d405092e30445aL,0xfa53ba4ec250a29eL }, + { 0xf6a247855d98c6ceL,0xf873653c207dd110L,0x2aebc3c6c634cbd0L, + 0x84b8016ce5cdbafeL,0xbda81fcace00b206L,0x837dc69484b55f2cL } }, + /* 61 << 119 */ + { { 0x61bdc5cab308f1f0L,0x7763c97d8898d3c2L,0xc02324e60434de23L, + 0x7f5c565e4ba696e9L,0x06f27a3e66914b66L,0x64a975ee05052cf5L }, + { 0x98b2f703bb38b14eL,0xbacbd113371e495cL,0xe54451acdd14cc9dL, + 0x8575cfdf87d141b3L,0xbd183a03d0996091L,0x947555579360264cL } }, + /* 62 << 119 */ + { { 0xd1f2d6b8b9cfe6bfL,0x6358810b00073f6fL,0x5fce5993d712106eL, + 0x5ee6b2711c024c91L,0xd0248ff5453db663L,0xd6d81cb2adb835e8L }, + { 0x8696cfecfdfcb4c7L,0x696b7fcb53bc9045L,0xab4d3807dda56981L, + 0x2f9980521e4b943bL,0x8aa76adb166b7f18L,0x6393430152a2d7edL } }, + /* 63 << 119 */ + { { 0xc89db4eb4595ca55L,0x48921c735f1a73a2L,0xfc513c904afe7cbaL, + 0x6d3f988bff8322eeL,0x17d0d4f0e59b7cdcL,0x292f4757f4bb5588L }, + { 0x3037e11151c14623L,0x3e113343dce98277L,0x0be229341e20dc8fL, + 0x0ebd1fbfcd6ff82aL,0x304bd69ed01fa90fL,0x402a457577f1862fL } }, + /* 64 << 119 */ + { { 0xd74d09c10ece13aeL,0x5e59d9e057a6bd95L,0xdb1ccfdce132b940L, + 0xa0e5309c843d3c66L,0x1fbd03a5f9cb3ef4L,0xcdc9ef0a00ea5177L }, + { 0x1ebf5a15cb784a6bL,0xa67382af8a0d109aL,0x3256c37aa0d34d15L, + 0xee40efa50fca43afL,0xc299bbd4b9841bdeL,0x6df68f603bef4a0bL } }, + /* 0 << 126 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 126 */ + { { 0xe01295fdd9d7c50aL,0xaf31b4ea67f8ef0dL,0x2ec9689f9eaf8eb7L, + 0x327b96c5c622acc5L,0xae918f81b2757f2aL,0x74927d684fd6606eL }, + { 0x09bb7fce18574215L,0xfea383bce8e68b72L,0xdf2a6f125fb47511L, + 0xbe88faa18e399520L,0x0166d57e3fb1c3a2L,0x5907ef2fe525f81fL } }, + /* 2 << 126 */ + { { 0xdefe3a7b8a37f660L,0x7898db8c858f5765L,0x7366c26a73d1f9b4L, + 0x35d5d718237ae8b7L,0x3efb20feb4478259L,0xccd0fed7aa545ee3L }, + { 0x750edd05ed22d152L,0x4f8020f9ee20d4c6L,0x16e60f370a9e29dcL, + 0x9cf0a136bfbec7f6L,0xb430a34b2e47e143L,0x2e2560bbc6cdd1a9L } }, + /* 3 << 126 */ + { { 0x799352dae4161a65L,0xe5cf7ad856253ce6L,0xf606bf796de32775L, + 0xddc0f3a357fce8dbL,0x1075fc2316cf4a47L,0x078f0e04b27c5ad8L }, + { 0x9fc477953f7100aaL,0x3ac489254673ffa2L,0xb8263f42f9cd8348L, + 0x5bdfde3068cc92d5L,0x2250927b1ac37f9cL,0x26ec8328b33da359L } }, + /* 4 << 126 */ + { { 0xf186d6bcc88d568aL,0x872bc4c7528535ddL,0xc9e7432edfe64dc3L, + 0xd9fc4832d795ea57L,0xf4ffdb81c845af2bL,0x66d7e7882b670517L }, + { 0xa7c1be04d7b7a1c6L,0xbed88479d5b2a249L,0x62ff8aba03f2ef6dL, + 0x60ecaac420dc701dL,0x9f4b559f4ff10119L,0x0582c9313cd54fd0L } }, + /* 5 << 126 */ + { { 0xea9da8f012bbaeb6L,0x3fba06b18c9f8360L,0xc11bd7abb28c0ac3L, + 0x1e05af2faa8a01bdL,0xae1e99c5f000b1c3L,0x93ee806453d79930L }, + { 0x5728089e4c4f5513L,0x755351f3b1f70b76L,0x187ac651675f77efL, + 0x5cf7bfb553067d84L,0x629290838174b5c0L,0x720e20798d5be74dL } }, + /* 6 << 126 */ + { { 0xab8cc09ff5eb9ad1L,0x97a4de76132edbfeL,0xa2e11c548baf6347L, + 0xcee54229683cfcf6L,0xe1e993b8dcfc6555L,0x333bf16abe9df066L }, + { 0x5207e093060d62dfL,0xfa32324d69b0f5faL,0xef16fbcfd3243d2dL, + 0x540a2e59f04f8e45L,0xb5e70f9c48317bbaL,0x00dbe9b25b35baa1L } }, + /* 7 << 126 */ + { { 0x0eaed675ebb512eeL,0x347e0756058efbd5L,0xadf792ca296d3d47L, + 0x57f00c0a4654d012L,0xa1e08a04bccc5803L,0x610677f05b2f11d1L }, + { 0x0d9393d7b81acfd2L,0xb258e1570587c219L,0x372a1857b4ceba47L, + 0xe1ce8bb53ecc1c5dL,0x7efdf301922cecd0L,0xcab8cb170d8aa653L } }, + /* 8 << 126 */ + { { 0x31954a5679d05497L,0xc12520b6fe76d4d8L,0x8c433ec5e37ef1d2L, + 0xcd0f203575bc3b66L,0x3723f145249cd98bL,0x1356e0d2ea3b42a3L }, + { 0xf607fee0f174c7b5L,0x318afc5e0127be39L,0xd47b5d74cea5417fL, + 0x6891940a10fca22bL,0x5cea41332b635e8bL,0x93db2ed6b5934fefL } }, + /* 9 << 126 */ + { { 0xf87cfaaac8972b7dL,0x2b8f9874e090800fL,0xdb88cd4f52efde36L, + 0x7b977f6e80776de8L,0xd047fc8ffb4b19c4L,0x33f3e43578b8135fL }, + { 0xb4cdb352da33eff8L,0x217f9e2deb89d325L,0x1bb5a004c99feec5L, + 0x98ce5a7fdb45c845L,0x458904681d87e964L,0xb9253873d151ad80L } }, + /* 10 << 126 */ + { { 0x5d7c767de39edca9L,0xe4a700e7a7f8de0cL,0x5816e1f93c9eec33L, + 0xa975c933d32fe465L,0x979beff968466a5eL,0xe308c135cc067721L }, + { 0xe0e733b41839b88dL,0xda3e3e6c298dc2ebL,0x414c3f0e8fb70e3eL, + 0x5ebaefa7ed7ca91cL,0x5c283310ae3b0f3eL,0x20353d5df3b1d44eL } }, + /* 11 << 126 */ + { { 0xd50767a9790325feL,0xe2ceddb9358c50eeL,0x60be64bdbbf03ae5L, + 0xe70c7e90f053328fL,0x6ba6af9e51543f0aL,0x470941f3b413e069L }, + { 0x0b569fd4ddf63d13L,0xf94b22634a2125d6L,0xaa45ab62a5c1acedL, + 0x2b797175defa5a30L,0x3eb30067ead1d440L,0xcadb54e90b691af2L } }, + /* 12 << 126 */ + { { 0x365a4a431630b133L,0x9ecef631068d7863L,0xa330c8b4b7205a6fL, + 0x4858eab357df815cL,0x6e522afaf1a92674L,0xa7cff3d9f41365d7L }, + { 0x00dd34615a0e4626L,0xa695feff48f9d094L,0xf427103f7c082301L, + 0x14a2a1876b092b71L,0x210f632130037a33L,0x21cca09639340e14L } }, + /* 13 << 126 */ + { { 0x58355ba0f60ad6c1L,0xc63fbcff56022afaL,0xa6a770d54e7ef19fL, + 0xf42b2024a09e9378L,0x153aa3200330f774L,0x268aaee55dc02c97L }, + { 0xa7e13b42828f7ab7L,0xc0ccce09c303bfcaL,0x23169daae3ccb6ddL, + 0xf7f763fd786774e9L,0xb15a5ef150021488L,0x52f408fd5f3ea885L } }, + /* 14 << 126 */ + { { 0x53e84021177346c2L,0x4ee451dde20af475L,0xd7642453c14f393eL, + 0x7eaa215331662516L,0x1217a1b4c1d486c9L,0x7d32427569860f20L }, + { 0x3813c95f14c2837eL,0xb8f0713d4e0c056aL,0x398c218cf6dec37bL, + 0x5bfa2eefa4ad1eedL,0x53cb0fd29f97a05dL,0x59fa132f6a9f492bL } }, + /* 15 << 126 */ + { { 0x6d5dff381fc2c16aL,0x5dec7ae2b1fe149eL,0xa9eed62c85088ceaL, + 0x5878fdf7996174baL,0x2cf65bb935517a73L,0x80844bcacff96d13L }, + { 0x0f55c8bfed53f49dL,0x35815fb0fbd8cec6L,0x23e7d5c53b6fa7d9L, + 0x3ee04c0146ce1733L,0x180e25553f5c4a27L,0x61263ea7280e6363L } }, + /* 16 << 126 */ + { { 0xb1f4fead41b959b5L,0x6edb53a9e71890c0L,0x48b47efe2e28aa2aL, + 0x70dad2e9b3151d67L,0x87a8178b436a3460L,0x0f86f9f5801f7af7L }, + { 0xfab462e3a982fc14L,0xe29126bacb03e978L,0xb4696b3fe6681282L, + 0x3bd9910a6a3fdc1dL,0x4409128449e37dacL,0x3b4bfabccf605fb3L } }, + /* 17 << 126 */ + { { 0x605fae7ece9d1372L,0xb2623a79f9b7e06eL,0xfab9b2742d37357eL, + 0xffdf9246461417f3L,0xc04b15d7bdd0e922L,0x767bcee54b2dbc0eL }, + { 0x74c4ea4ed45efc88L,0x32d3d85491a534a8L,0x88967078554b2691L, + 0xe8256015e336a410L,0x166469624b9f978bL,0xb433f06ca104f01fL } }, + /* 18 << 126 */ + { { 0x8906d815457e1e82L,0x96abb1aa4c8a2c68L,0x2e63f37927ab2fb1L, + 0xe092e15f5446dfaaL,0xa3a3f0926615c65cL,0x8b31116747c3f259L }, + { 0xfe2038782e5c658cL,0x38903cf526215773L,0x0039fca7237f1bd4L, + 0x75dbcc016058ff17L,0x67ee6226a65aeb9eL,0x96999fa75cedcba5L } }, + /* 19 << 126 */ + { { 0x04c6fd475ac4d191L,0x0067e474c825a897L,0x4a37c931404810c5L, + 0x072d30e5c4a56380L,0xbaf3428dc897ba23L,0x9899935b53724382L }, + { 0xda5cc13ff4d41a62L,0x063047a0c6271baaL,0x49790bdc5cf48302L, + 0xd8c34e5384c5a9abL,0x6cf28e83db5bc36aL,0x430dbb1497da9d42L } }, + /* 20 << 126 */ + { { 0x59470e49c37acc2eL,0xc9e0f73611b85596L,0x47613c1e0fb30eccL, + 0x1fbeffa3b62892f1L,0xddfeef49f8eefa16L,0x6f82acd9daeff719L }, + { 0xff1872cdacb41007L,0x06fe556c82d64c6dL,0x52a63a387695218aL, + 0xa0d413a720802b88L,0x233f1f3118f4a473L,0x22ef7d6fc9d7da4aL } }, + /* 21 << 126 */ + { { 0xeba1db6910dad9abL,0xddb62dacde3a5a42L,0x209c472cfdf5ad86L, + 0x14a7ee4b37214540L,0xcaf70ce08339c9dfL,0xa95744554eb9189bL }, + { 0x90d7f241e9b39189L,0xf5edfd09af7f3eddL,0xc9a3444deb7ed52aL, + 0x30d9e2f80085d9d1L,0xeb412daa4dc24fefL,0x55c0000b27786649L } }, + /* 22 << 126 */ + { { 0xa9f34fa9518118e5L,0x430db0a51a22e790L,0x64b443a5d5a16ca1L, + 0xaa3b64f4d8adbe45L,0xb49435fae0f0873aL,0xb8d67ce4a635d1e3L }, + { 0xad843f8a8a612b29L,0xa416ec7fd84a210aL,0x8b4dc6930984b23fL, + 0x29a1b71b24640dcfL,0x8f2d7507911892adL,0x0ce384105bd4d518L } }, + /* 23 << 126 */ + { { 0x1e1bef926c42e1bcL,0x91259dd60e04d449L,0xc029961e8875d346L, + 0xfde51012a9e38f43L,0xdeaa1dc18892643aL,0x67e3b913217e08d8L }, + { 0x889a28c269b92b7eL,0x004c0f87b7446c21L,0xea812f67a2f98e77L, + 0x42fc7bbe22c40b8cL,0x5e7f5f5a8722e381L,0xf8f209d932099e41L } }, + /* 24 << 126 */ + { { 0x867379134a2965f5L,0x34724dcde67b3546L,0x2efe185ee92c712dL, + 0x8b908f86c201e327L,0x3ab5528894f6b078L,0xb9b2b784ce0a5bf3L }, + { 0x5eab37ac879f6a41L,0x74271f672f2360f3L,0xf3a3edff304f1cf9L, + 0x8992ecd8f6fd3e90L,0xff24d7c69f16e5edL,0x0844ab25def9a5c4L } }, + /* 25 << 126 */ + { { 0x35cbf2191e14f235L,0x9ef33f3c4cdc1b46L,0xfd5cedd0299f7f13L, + 0xf57b9bbf99379e17L,0xae25d3e3cd3d59a8L,0x72f9fc84f58cb31eL }, + { 0x87950fd84c94b63bL,0x15b52b4f7a4560a8L,0x382d36ec943e44baL, + 0x567ce2e9337b0f11L,0x8136e9ce2fa44901L,0x7e43a7289b15eeaeL } }, + /* 26 << 126 */ + { { 0xd1c8ed8814fb95f4L,0xc302e0aa29602659L,0x67abcce005cd67baL, + 0x7a234cc022f8ae25L,0x7074face39f44e4fL,0x84a08afc7a9d3fb2L }, + { 0xfd149c88f56c1f32L,0x5b12cc15219e494aL,0x242fc50c9ea3c0e3L, + 0x196cdba555b23034L,0xfd8cfa5e87b75206L,0x915e706488d55f47L } }, + /* 27 << 126 */ + { { 0xb59480ba876145beL,0xd8f8fbbe8e1075ddL,0x0ba10292b5d9baf0L, + 0x3a4b7f65e39a8754L,0x1b3a044c0f3c6520L,0x6b8b3397b1dff4f8L }, + { 0x40cef2285c182eb3L,0xbef82aec1b1cb92fL,0x5c4d2bfc2a97c5dfL, + 0x41d2a046536ad077L,0x94ef34a8c497505dL,0x14e9aef48e0b35ffL } }, + /* 28 << 126 */ + { { 0x2edaaaaaacaf1f3fL,0x9e3af72c80ebcc10L,0x3542fc42bcb1618fL, + 0x6c04ec246709d851L,0x5fe9768ea9af4ce0L,0xe739d50eeb6ebe2eL }, + { 0x7b7da4ac876586e0L,0xb0869f1d64f5f956L,0x7f691c51fd563c80L, + 0xea990d6926c775e1L,0x2cd96f1321b58889L,0xbc8074720f1aac2cL } }, + /* 29 << 126 */ + { { 0x8e1fa5f8eb3283cdL,0x0107a3ba20e69342L,0xf99a511cb045b8dfL, + 0x172d0c8933b51876L,0xb11efc2b9636d0f9L,0x16b2197c41570483L }, + { 0x49df27edacfdfd1aL,0xd9d2cedc366b9b28L,0x0289a75cab028c0fL, + 0x522f567a4879464fL,0x3313728225f64030L,0xfa28cb1558d6753fL } }, + /* 30 << 126 */ + { { 0xe5252210c6cd33f0L,0x6ba7f51f3f085202L,0xd2a87fb38f52e312L, + 0xa5e082cff25f35efL,0x786a93c2b9df2f20L,0x68c7e1299a19bf27L }, + { 0x13a971ab8d710915L,0x3ca4f8c6939443c6L,0x8554699c70522446L, + 0xdf42b7768e14e6bcL,0xc7969fa5f7f3dadeL,0x135b6b77350ded88L } }, + /* 31 << 126 */ + { { 0x39e54aa472546076L,0xc0003f7f13e312beL,0x71106a4ffea91274L, + 0x3868f957819851cfL,0x713b96e75c85bbc6L,0xfda8c2df610403a8L }, + { 0x0ea806c3a008cf78L,0x0ef9708353c0d1bdL,0x536950211e592838L, + 0xea3773d5e9023982L,0x6eee3c0d4195754cL,0x95df7b568c4bead3L } }, + /* 32 << 126 */ + { { 0x57edf71edf9a9f18L,0xbf834240627a0b79L,0xb37aba1aa6934160L, + 0xd45b3d2c5e639a54L,0x62c6b9ad70bce957L,0x16bc35a75d7e87f3L }, + { 0xb021698266b4a982L,0xb56050dd0e51c9bcL,0x15aa692b478e4b91L, + 0xdd67cf29be3fe25aL,0xf1ef75b006bdd4a8L,0xf71a285b41df627aL } }, + /* 33 << 126 */ + { { 0xba6be58993032120L,0xea6dd691db99740eL,0xad8679463154648dL, + 0xd1a36f4c28c0668cL,0x09a28c234dd76e88L,0x93fef0c7dc665bb7L }, + { 0xa78dfeb4860a0016L,0x06d2f868e21a9e02L,0x333a25a38486ade7L, + 0x12aa13130e398a80L,0x04a44a5848d5b3e3L,0xe59293d47a7ec12eL } }, + /* 34 << 126 */ + { { 0x6cdfb5faea2c1632L,0x6799cfcd7865f931L,0x4e1e5d25bf420a7cL, + 0x7d4597db05d22ddaL,0x7548db12fceda1e1L,0xb4523ccdcb473578L }, + { 0x3d8dbad0ff889f03L,0xc591bb1118a9a222L,0xfac2b914a2cfcc57L, + 0xbb67601abec9d9bfL,0x18dff42ceb55218dL,0xb36ef9ba7d2b6320L } }, + /* 35 << 126 */ + { { 0x5b007ad1f3edf67dL,0xfaee9cada25fcfafL,0x18fc784a4d62e5c2L, + 0x98deda878acb5f8eL,0xe9cfd10a6f888d8fL,0xbb0d729b053db2efL }, + { 0x7b09fa4f2aecece4L,0x3f72187cd4c44cc3L,0xf646aba05b8175a5L, + 0xf213caeba5686ca7L,0xf5ce777badc5d40dL,0x15ff85d660eb9357L } }, + /* 36 << 126 */ + { { 0xcdd18aee24e6df19L,0xa08ab968bbb3303eL,0xd5eb039cbab4f1a3L, + 0x040d03a8fa7a48d1L,0x767c0ed23d66628bL,0x0c6bd388b1a6809aL }, + { 0x793aff3f029eeb91L,0x6db32d13bca798a8L,0x6aef5c1cc3816cf7L, + 0xcfb25ea45fd2cd2aL,0x0715a7899f8e3312L,0x4a9ad4782a6b1a6bL } }, + /* 37 << 126 */ + { { 0xa9f360a5d134c919L,0x10dba223dcfd0715L,0x7444b191dc9b4394L, + 0x9a16a971e2f288e0L,0x0d05c511f6a49999L,0xca34eae26b65e956L }, + { 0x692febc418a83b76L,0xf3468c7b0b5f3511L,0xd8d3ce48b8e1ed80L, + 0xbe8c5c302a6de231L,0x9c0468b74e680d8bL,0x773ebb63f57b88d3L } }, + /* 38 << 126 */ + { { 0x9c2c33a5b726729dL,0xa86ab4ea5db2af56L,0xe987c5e3b0a36ffeL, + 0xa6dba84da5fe8bdaL,0xe1fefa4b8ff617a5L,0x561cdb88a91ad714L }, + { 0xeb58f7fce145ddc0L,0x7b0e560a29c5ad50L,0xf8d6626593da0e76L, + 0x7769b479db39fb92L,0x9149f1e3a3c49033L,0xb706057f3ac49c35L } }, + /* 39 << 126 */ + { { 0xa678ba3fa527d157L,0x922aab268856a8b2L,0x936d3e85690b4771L, + 0xed78dccee114e472L,0x9694ccb1d315fbc1L,0x8b1cf4482822d968L }, + { 0x336e670c4aca5441L,0xece24fb58f0e2824L,0x28d1578d05b758adL, + 0x0a1be96a40c3f019L,0xed1586e30b659cd6L,0xdef180009f860dd6L } }, + /* 40 << 126 */ + { { 0xc2885af90fe0f372L,0x2c756bef5fa6b808L,0x52b7f7b6068926bfL, + 0xc9399c1ddb143b68L,0x0e77c689e4c61211L,0x7d01e37f15ad7fa0L }, + { 0x712fc61f188b2a01L,0x103685ec55a4100eL,0x721f9c02e5fdce96L, + 0x61c8a0c5e784397bL,0x34d478351c686ed2L,0xc697c89cd155bbe9L } }, + /* 41 << 126 */ + { { 0xc26dbc34f06a2cffL,0x4f10297631a80712L,0x758e33eda7c54effL, + 0x44b5e4ff3682d103L,0xef05034722a05e6cL,0x9170365c48ff372fL }, + { 0xee49b61d66a15a71L,0xb5fd487995c2045dL,0x5940487160ad67caL, + 0xdcd2d5f586388c40L,0x0b41a8e54cbd1f71L,0x8152c17040236ae0L } }, + /* 42 << 126 */ + { { 0xf05b99d0995e9809L,0x036248a70295fceaL,0x7b70cf8f558e6ec4L, + 0xe882639c7c48ce34L,0x4cc86feaf4f47d38L,0x976799cf6d81aef1L }, + { 0xdb202bfe8043cb43L,0x4c761cc5cef4f017L,0xe124bbc161f0c89eL, + 0x77d1cbf55b5a3d20L,0x26e549fcff346940L,0xc6040a4c2325466bL } }, + /* 43 << 126 */ + { { 0x1ed4d238e940e32aL,0x29d99c20139efcd6L,0x4cb7ef50c172b412L, + 0x8a9c438931957225L,0x5d8872af60be4612L,0x7bffbb1be7e79e0eL }, + { 0x75bd89c1fc7d4e66L,0x723f9ae86bcc0379L,0x88f673b599c1b827L, + 0x8d45d139ecf5148fL,0xf12e605ff97ad1e0L,0x567dec052f09c370L } }, + /* 44 << 126 */ + { { 0xfb33b987b0be5055L,0x9864f903bcce94dbL,0x99b8da36aea9d09bL, + 0x19e326113b622d3dL,0x6abde501dc38f903L,0xb1fe3f1867cb2161L }, + { 0xb053ec831e08cd7cL,0xba503b563298d32fL,0x220e98c8c2a79e86L, + 0x66ac99511e1cba68L,0xf9520e1e644ab527L,0x3f222b9b4eb8abf3L } }, + /* 45 << 126 */ + { { 0xae0cf2ff705cfc45L,0xf9d5dfb65a0449b1L,0xd0300b2cd4697fe0L, + 0x4ac80d7e4dc665b0L,0x84fbd38d72c1677cL,0xea8306f08e683a0cL }, + { 0xe2381e65a469e337L,0x36b565d0b3ec173fL,0xc67689c700f3007aL, + 0x9f0108992abcc81fL,0x867a5f8dbb9bf584L,0xef789cdd5a436b38L } }, + /* 46 << 126 */ + { { 0xf8cdc9ecee11fa1bL,0xa78c73ed4c90edb9L,0xf6703453bbbddb82L, + 0xd268b4e23020e294L,0x214cdd54958eb8cdL,0x2acbd31d4d7214e5L }, + { 0xf7c60c89cc733351L,0xb8c5cc642fa201fdL,0xaae1ca7f4c2acb10L, + 0xf7e33be56d7f598fL,0x982c012fd920c3c8L,0xaa98a69b86751ef1L } }, + /* 47 << 126 */ + { { 0xf5f548eb915ed5cdL,0x657ca09ce30f448bL,0x8750c4a44a30850dL, + 0x1b329c4108edb075L,0x8c261df8ccbcdaeeL,0xa81720bbedd44638L }, + { 0x602fc21f0b91ee05L,0x6241265db7e8bc28L,0x1daefe5b106ac444L, + 0x93fe5bd42c9deae2L,0xedc229e17f1ba35cL,0xd99244977e0da1f9L } }, + /* 48 << 126 */ + { { 0x3176a43ab7a3ce87L,0x9fa09e975f130e73L,0x971cc37b9368e156L, + 0x2cabf535b8981792L,0xaec2862e4d0f0bc0L,0xa1a48c183ce8c100L }, + { 0x288f4e694af2eae9L,0x778845f21f9339bdL,0x1ef5fdfd17dfaa6aL, + 0xc784117e3483a6fcL,0xe8c82f05f3c5c19eL,0xf39b3c1d1da87ab6L } }, + /* 49 << 126 */ + { { 0xa2539d4cc4ac73e9L,0x0308f91891488ba1L,0xa3e72f4459fae934L, + 0xb6bbcc37f8c9c402L,0x345a2debc6edee3eL,0x0352f023b0df87b5L }, + { 0x67c9e7b8818c4f8dL,0x3a8714cc70f44977L,0x37b96e1295066bfaL, + 0x617d9737c95d7f70L,0x60bb06ef759a360aL,0x97689b3f34f59fe1L } }, + /* 50 << 126 */ + { { 0x17d0667fb2dd1febL,0xbfb92fe48862b2ccL,0xcfa0c8e9d5438a69L, + 0x7bdbd4b1d9cf9ef5L,0x7616acddf373c87eL,0x0603d2b0cf8fd5b6L }, + { 0x6a80f25d46e31aacL,0xea8c0ad0fd424755L,0x9e2e5a5b3ffd5a2fL, + 0x8882d271f3b143caL,0xe6fc9ad7904e1740L,0x98d1620af428ad20L } }, + /* 51 << 126 */ + { { 0xc8c991a63292054aL,0xc90b11618ce93455L,0xdfa32238e200d1c6L, + 0xa9c578d5303004b3L,0x9dd2c3881609e5f8L,0x068ec35d24b69108L }, + { 0x47e8183b2d1a3b7fL,0x6200d70efe3db580L,0x76012f3fafc089b0L, + 0xba06dbf4bddea8a2L,0xd83b4af5da01a49bL,0xa3d4334ce16e87e6L } }, + /* 52 << 126 */ + { { 0xb2fff4035b43e58fL,0xe80bd5740727be41L,0x048a59cbf9b52541L, + 0xb79084e7f38d0b47L,0x763b0c95938935d7L,0x7cfc6180336b8735L }, + { 0x118d2a6f929b0200L,0x7e5789775a31948cL,0x9085999326009509L, + 0x330533a33ad633c6L,0x28bdb910733f4c3eL,0x82c88f148fdca27cL } }, + /* 53 << 126 */ + { { 0x1c346bb04ef444e7L,0x40a50060e6c22e57L,0x5eb02aa6c7a773b4L, + 0xd748a0a0d23b190eL,0xb6ff7f02cfedb7dfL,0x3f8fb35b30f8bb4aL }, + { 0x245b1c232dc31174L,0xa1e156579af25f59L,0x1ad1a2315e2393daL, + 0x9430ed2dfd7c7073L,0xc4161d4f580fbc0fL,0xa2bebd3fa0f1dadcL } }, + /* 54 << 126 */ + { { 0xace743b6baff35ebL,0x84ac3ce8ac6f38f8L,0x81d41297106b44f5L, + 0x33f6bbbbaed20aa3L,0xae4dd66ceb420ee5L,0x87553aac994f0777L }, + { 0x26275ebff1e3647dL,0x3b574c4fd9eeb474L,0x58fe2a16929721c5L, + 0x748480df932030d0L,0x3a30032641bb5f68L,0x0797fad92c06d1adL } }, + /* 55 << 126 */ + { { 0x65356242c7caa811L,0x780fe23f4506bbd7L,0xa741a51042407c02L, + 0xb8ccd27f5ef9eac3L,0x137f4a573ecf5766L,0xd495be0d15936fdbL }, + { 0x5a419656109c93f3L,0xd2f7b65dcb12affdL,0x2305a070ff830421L, + 0x6d00f1e9684d5a6fL,0x3de9d1de91aa391fL,0x0b5148c10acb6de9L } }, + /* 56 << 126 */ + { { 0x209fa6e68ca7ec95L,0x17808b0c107a1047L,0x99bbeb5edfd270cbL, + 0xe3d57c1dc25e2d6eL,0xb90b0c107ba1237aL,0xa7e1b8dc4a0d6856L }, + { 0x97d5b46136a9a07eL,0x931251e9125ea29cL,0x4177fd10fc8868a8L, + 0x1d3538b7b7cdcdf4L,0x889008c8ed3ff9dfL,0x30573ad2229b9413L } }, + /* 57 << 126 */ + { { 0x11596662924d413fL,0xe797d0a70e5d7bf1L,0xaa05dcd28452ee62L, + 0x6e10e77f5d5ddf1cL,0x46b72cda5fbd184aL,0x3adc1edb5b25c0c6L }, + { 0x640de5b05c732e3aL,0xa7d4f0f5c6739747L,0xbc11978d1426527cL, + 0x979276eccbee0053L,0xc44347a7304e8811L,0x016c01e11f5ececdL } }, + /* 58 << 126 */ + { { 0x78b2f1a15ee57666L,0x28060d1576a2c09eL,0xaf0cb38df632a5deL, + 0x93ce93eea284cd43L,0xe3670d0af35dc1f5L,0x3b8deea527971072L }, + { 0x3b88b1158eea4303L,0x43ff3b22aabde038L,0x8d69e180c813d623L, + 0x218f5b853aa7a08eL,0x6ee1544adf74f239L,0x0d7abf20fb8772f7L } }, + /* 59 << 126 */ + { { 0x1d881d4eb7716840L,0xdf83a03b86bdef07L,0xd534c4e4dc7ee69bL, + 0x1169f1cc6e264c79L,0x85c812d1b7690d17L,0xcc3164adec5f2ed1L }, + { 0xb91a14180674e87eL,0x5dfaa279969188fbL,0x434acad5e242b969L, + 0xa51b5c63751c4e51L,0xaa9089b7874f9aa2L,0x8758f9e51b8397e5L } }, + /* 60 << 126 */ + { { 0x422ad88e57fd35feL,0xd4564b96b99a11cbL,0x78939992238baebbL, + 0xe66ddcaf4b30a709L,0x00873d5f7812ea50L,0x7317f9dc6784aabcL }, + { 0xf94afbdbe0608ba4L,0xfff893618896d745L,0xa3348af5cad62808L, + 0x13ed4507f349f51bL,0xa73d4bec1186324eL,0xf0b48189a20022d2L } }, + /* 61 << 126 */ + { { 0x87d117858b8efa4cL,0x724439d6e9c2ee6aL,0x33ab2a03606fa0c8L, + 0x6ede5b55f9779d87L,0x858b7dd0759445cdL,0x33683c817a5ef23aL }, + { 0x0f093175221c3443L,0xedcf2aaf889195a5L,0x9f189ebc814abec7L, + 0x6a64999c40235b9eL,0xf98dc212984438ebL,0x97e2d102ba86e7caL } }, + /* 62 << 126 */ + { { 0x337b9cbce3db0718L,0x1f2f55833d1796feL,0xa522b76f68c2a69dL, + 0x4c1da7cf5375cb22L,0x690a2e7f50bb0d7fL,0xa734d4756689b6eaL }, + { 0x918592d5867ca0a3L,0x64d1c147c4d15e28L,0x4d8c3e22656f8219L, + 0x5e028bb2170f59c3L,0x41e8b84449875858L,0x1d928cc90c599178L } }, + /* 63 << 126 */ + { { 0x736dee2cf44db09cL,0xfb5035c07257b4e5L,0x3e3a7bf6bf0b702aL, + 0x4910a0165f257c0fL,0xd80b891d98437b4eL,0xf9e55d55076d8587L }, + { 0x4e4ed7a79b4fcf4cL,0xaaf417f5581acfe3L,0xb1ae2a7ca3b3f920L, + 0xa666bb6263ee4781L,0x2fba297e63684f04L,0xd6e662658d83bd6bL } }, + /* 64 << 126 */ + { { 0xa58a27c58a541be6L,0xaf66949954fd7683L,0x2431826600079a25L, + 0x113f6fcf2606caf5L,0xf6ff2be316cb28c8L,0x8f7fc60e3c17caa6L }, + { 0x8ea577e07d35e26cL,0xc3e744c0f0628903L,0x4b28eff4592a57eeL, + 0x76e1f87c5e3f67b2L,0x40d7a676fb008902L,0x68a9dc764b6e6b7eL } }, + /* 0 << 133 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 133 */ + { { 0x76e2751a12575913L,0x2c6059914a5f8c4aL,0x58322dfb71fba662L, + 0x228aec085e0886afL,0x8d83b6276aee544cL,0x338f5fb6e29f9639L }, + { 0x1ba4cfe0bf5e19faL,0x2eea84c5b9e4f8f6L,0x7e0eed58cee95d92L, + 0x2d29282abe535540L,0x866638b607a9a1f4L,0x915999776ab8dc82L } }, + /* 2 << 133 */ + { { 0xa16c79cfaf4d260bL,0xfe853f6cfab3c3c8L,0xb8bd6aa0c2f47e68L, + 0x277d590f2c9b4914L,0xb6d1c810097242a8L,0xcf2f3d8e45f75512L }, + { 0x2176162b74a20c3bL,0xeee8bcb82b2bcddaL,0xfcf8c0d1a503aee7L, + 0x5d1f94a57af4dd78L,0x8f0bc1a62ab43be4L,0xd22dbf16ba9e071bL } }, + /* 3 << 133 */ + { { 0xbf87f30e3790b47cL,0xd3d3f1e25ab52ae8L,0xd5fd32bd50ec0ba3L, + 0x7de8fe0ae60d1e72L,0x52d77fe0e14ff2d3L,0x9b6937db55ca47e4L }, + { 0x39e3d19f53e94fa3L,0x8d962a4fbd7827e4L,0x3bd70c7afe92c6cfL, + 0xa3fbc06869a82904L,0xe263f00ed96d1d9eL,0xe6c9781f75c0c24bL } }, + /* 4 << 133 */ + { { 0x705bfe37b4e814b3L,0x22f0de61702013c6L,0x811e77a9bc456797L, + 0x4f52c4e617081a2fL,0x87405d819fe1640eL,0x53fa82b7707711d7L }, + { 0xdc6fff830ee4aea6L,0x8413e22ffd60373dL,0x0ecb66bea9cf3eadL, + 0x7418372e87139b8bL,0x6aaccf295e42b4d7L,0xb6dc592531fc932eL } }, + /* 5 << 133 */ + { { 0xf1c8d00de460fe00L,0x5692bfee528da7c6L,0x9e4dd700ac8620dfL, + 0xcc43e73d9d6fe740L,0xc94060d3e76dcba2L,0xfcdf8ba6d398914fL }, + { 0x540942e7502f8587L,0x5def85040de058fbL,0x63e0c7855292b0c8L, + 0xe90405282e558983L,0xe25727a16baf4a31L,0xb9bf28f0acf64d7cL } }, + /* 6 << 133 */ + { { 0xc7c8364f09d26382L,0xe16988737bf32d9fL,0x97bac2feb726391cL, + 0x521426364a7c0b57L,0xe3e596482cdec222L,0x4ee7238cf44e0a98L }, + { 0xa6d05a21f61cfea8L,0xa1059fb7efe6a26fL,0x482a65b342416fa4L, + 0xdc5727e1c71e7a94L,0xe6b0fb6ec4767f1eL,0x3d0d626d6510599eL } }, + /* 7 << 133 */ + { { 0x59f5df1b2a8f9f78L,0x6bb161d992257e60L,0x2cf060beb7b2eb14L, + 0x98e72799aec169b0L,0xdde683927045fdb9L,0xee5e0aaf461b27e8L }, + { 0x80250c744c0ee047L,0xdd3881f597f0677bL,0x0ea56921a4459b6cL, + 0xf7793cee26df8d7dL,0x33bfa09be42d1913L,0x9f0636f74ccf5139L } }, + /* 8 << 133 */ + { { 0xfa3b4c8eb88ee8f9L,0x1f288e60b521ab57L,0x06aa39562e8c4d8cL, + 0x4981c3e5cf89935bL,0xbdbd0c4745fa071eL,0xa78f831c496073beL }, + { 0x09a72986a4e5c001L,0xac527731709cb728L,0x9a64b5b3988f2781L, + 0x6ac9440d73b1719dL,0x58ad54c7e3d2e807L,0x1c1574488f06742bL } }, + /* 9 << 133 */ + { { 0x3220a099a5e437e6L,0x11a1b1734dc5bdaeL,0x1ad9e736b64c9b8bL, + 0x82b6a3d4ce40acadL,0x54e1eef8915aaa8aL,0xff19be481f3a1f54L }, + { 0xadc4c5250b64a2b6L,0x6637bc8e12caf63dL,0x970d08b01206a661L, + 0x97c9b9bde57cf6c2L,0x228ee4712b89b7b7L,0xfeed19ca837cb79fL } }, + /* 10 << 133 */ + { { 0xcd36c981a816f4d4L,0xc99316c27712a72bL,0xd32cb20339e671aeL, + 0x79ff1889f67f6215L,0xf9fe7448cd08e91eL,0xdc9b277776f3e605L }, + { 0x8af30c2e7c1609a6L,0xed3224a3e54cdd0bL,0xe73f56ded1dea6acL, + 0xb836eb783e37a390L,0x9f0dcdb2c78a0510L,0xc37e67a39e6109f0L } }, + /* 11 << 133 */ + { { 0xab419eb852e0d552L,0x86c76ef8ae3d06ebL,0x219662b4f7c6342fL, + 0x2820299e548f6717L,0xc4d0d47a8a2aeebaL,0x4c98069895536593L }, + { 0x3644e55ff42cd505L,0xe109b64ae47e0b0bL,0x91f520a6c89788aeL, + 0x35f6dc577699087aL,0x3484f5b6b77deb8dL,0xc22a63a47f3c09e6L } }, + /* 12 << 133 */ + { { 0x6b5b7b2a75c953b2L,0x927ed77ca7f1cd5bL,0x2e8c53994cba0e5eL, + 0x03aeb14a3f4a941bL,0xedbad9a0a1385c8aL,0x925a49c167fd2258L }, + { 0xe7e368ee3365ffedL,0xcc4aad2dd106eb87L,0x4ce908daa980b53bL, + 0xd3f4954016929ac8L,0x613c804dd5c05c32L,0xa42290ccd7973344L } }, + /* 13 << 133 */ + { { 0xe7437974c464c24fL,0x70c04156d36bdfecL,0xd94c80fcb2d5d96fL, + 0x4a1fcf19d2cfea9cL,0x443478592f6df796L,0x0c908d0159743bd2L }, + { 0x78949087d165a62bL,0x6c3f9021632f4e1cL,0x3917b925a94bb004L, + 0xe153ef092b3f87e3L,0x6aee1027ea706338L,0x953ab2959733bd02L } }, + /* 14 << 133 */ + { { 0xad49cad49855d008L,0x23442cf94b273d85L,0x3a3c8752e3dd8f65L, + 0x0ca5d24bedf84ed0L,0x3d0580938b4f8f96L,0x1cea59acf9b9ae03L }, + { 0xf17cbbe23a06567eL,0x49cf5294f090338fL,0xcf8cbe0da93562c1L, + 0x66683f21b986b71cL,0x3c96750cc87c9e10L,0x38e62db63dcf2f32L } }, + /* 15 << 133 */ + { { 0x807a519047f99946L,0x49e03dcf01615a37L,0xe813287c99590bf6L, + 0xc9caf30ddb62835cL,0x0733c49d4df78781L,0x4fde30fd4815d3adL }, + { 0x2809b853f9a2610dL,0xf2b139b9dc050142L,0x52a40a413c23a4edL, + 0x9333086b0a104df2L,0x04a90c11e2a65950L,0x4c6a15c4dc24341aL } }, + /* 16 << 133 */ + { { 0x33952177a98cf218L,0x841d9e1f579ee53aL,0x1084d61e0a285bd5L, + 0x3935a84e71171b1cL,0x8ac2433cf29b29f9L,0x5dd868b56dd1e9bdL }, + { 0x88da04788d102390L,0x1140735a657400d1L,0xa792a25f9d5b19e1L, + 0x9ee015cb6a27fa79L,0xea3bf8b57ba16a8eL,0xc5f0cc26c15fde67L } }, + /* 17 << 133 */ + { { 0x033708d2e02e9feaL,0x2b588d1e222f437dL,0x998442d6c6b47013L, + 0x4033d62fb8ac1fc6L,0x9b8fd348877c726cL,0x1a2125fa5bea5a49L }, + { 0x04a2c1d680b8afd9L,0x3d52c9d2a40195c1L,0x56b204e6655c0b30L, + 0x55ee14ef520b3464L,0x23fc52e6b5bdd96bL,0x445cfd7a56f4b269L } }, + /* 18 << 133 */ + { { 0xc8985c2c5fee6426L,0x8be749496bb7bb8dL,0x12967576659363b4L, + 0xd1b6ded9b969b221L,0x586f28929819fc04L,0xec6b03e5addd6307L }, + { 0x3f0e96cad4da6627L,0xc866c95c14860d00L,0xb038867c9725f9a8L, + 0x60cd3afa1caf2547L,0x6f2cc04411dddfafL,0x49551f249d0af0faL } }, + /* 19 << 133 */ + { { 0x04a68337177e2e7cL,0xe20b21c0adb79464L,0x9b30d3437e42ae4dL, + 0xac7a01d7f86c5767L,0x3ea34e385381db5cL,0x3005a0c39235f5bcL }, + { 0x853eb43167b4a5c5L,0x92f26a35584e4b8aL,0xa3d25e5879bb470fL, + 0x7963d90a5eacbb13L,0x08ca7969212e3aefL,0xb5ec6582df92bfffL } }, + /* 20 << 133 */ + { { 0x2e152d95ee2c3290L,0x8437df2e4a9ceda4L,0x4151754e3c7ebfd1L, + 0x556c59a888f80aeaL,0x8d099c5d8de44dbcL,0x9ecce7fc77abeeccL }, + { 0x5e0a0f383aa311cfL,0x99ff1eecb8f2bff5L,0x5ae0b483b5dcf488L, + 0x11212c4591483a02L,0x99fe0738312134a1L,0x3b855db0a72745efL } }, + /* 21 << 133 */ + { { 0xb70bf73230261470L,0x8c9b7c4bc74a180fL,0x4c648aef88a9d9acL, + 0x3d9f7540a10f98bfL,0x8ec2a3a3120d55f5L,0x1707c1b0baa5a600L }, + { 0xacba8da9103f2f0bL,0x96926dc0c7194236L,0x00358df7584499dcL, + 0x74c27d0e538c0a15L,0xc675d079de960a77L,0x575b042e89f41f6bL } }, + /* 22 << 133 */ + { { 0xd17d99529703d919L,0xb25ecc411477faebL,0xa5c66a58a9aea2fcL, + 0x83754d683accb00cL,0x6a9ae76a25901044L,0xe437981b2565e035L }, + { 0x441ec0d96f45fa01L,0x35e40d126a697636L,0xba2fbab59bb3c2fcL, + 0xc038be03e94b245fL,0x366b4bcc0c1672eeL,0xa14a2c10f1ce6d55L } }, + /* 23 << 133 */ + { { 0xef32d94febe1dfe2L,0xdbf53d4271494ea6L,0x72dc5fad24cf0c2dL, + 0xa9247adc66dbc21bL,0xe31ff66ab130da59L,0x8cb97c09e86ab63aL }, + { 0x204020e2f59ebb80L,0x56f6d8b7cfd0f965L,0x7522a692b1518dadL, + 0x8e7c999f5f231e2eL,0x2eff5904b4406177L,0x8440cee87bfe2363L } }, + /* 24 << 133 */ + { { 0x37f50e43892c8eecL,0xf06a2f047d85a7e2L,0x3916af85e1d11150L, + 0xf56e852f6785ae1cL,0xbf8c72adae6ada8cL,0x1fcd53e3e13285b2L }, + { 0x5327920cbd56d348L,0x82a394fb445658a8L,0xa71328573caf3792L, + 0xb15ab34b550ffe1cL,0x818980666a5d4e4fL,0x0bda153b2f854f9dL } }, + /* 25 << 133 */ + { { 0xf664f44407aa3d00L,0xcf8901664704e2d6L,0x1802f662f8c2fc8dL, + 0xd52496b8a47f0da6L,0x37f71d8c75001c8eL,0x7ad8e8c29cad3ba7L }, + { 0x666afc25825515f7L,0x3a871c76a729e498L,0x5dc21f1108479e3eL, + 0x78ff145966c4331eL,0x8d01e2352dd3deb2L,0xc68445e9dbc91fc3L } }, + /* 26 << 133 */ + { { 0x8f2d9aae98ea13f6L,0x3e75ba40ab97bfb0L,0x14dd24e635e1fe35L, + 0x14abb0735f88d9b9L,0x74b2c6a801d4fcd6L,0x4905dfe7744a09bbL }, + { 0x349348c077cd538aL,0xdec247f5f7b6d035L,0x737e248dc455d417L, + 0x608a5529b6fe5d92L,0xce0ba0bccd7dca64L,0x022bcb18c21175c6L } }, + /* 27 << 133 */ + { { 0x79fe5372881b120aL,0x4878428aae98aeeaL,0x5c6a7f7d09511acbL, + 0xb7be08de3b046481L,0xfb91990b8b35f13bL,0xab734f604ebdd374L }, + { 0x3d4955f1197690e1L,0xfc82767c7b376dc4L,0x7cf3db85b8c659c7L, + 0x4cfb6f4b03202723L,0x8b79311746141d27L,0x94c6ee67867292c4L } }, + /* 28 << 133 */ + { { 0x77a31009722730feL,0x93707ac4d5cdd297L,0xa290be39d3811e8cL, + 0x831a9b9592a5cdb7L,0xc74cda84e7342270L,0x964661903f48affcL }, + { 0xb0496cca5520b0f0L,0xc8742cd9bae930ffL,0x3a30737aeaea703aL, + 0x0a8e6fb7fb758854L,0x9ab9523e6796f4d1L,0x36e6c05dfdf7140fL } }, + /* 29 << 133 */ + { { 0x4c8ec1a3ccedff1fL,0x8fc58987ca74bd5fL,0x70a6b71cf768abcdL, + 0xb9971cf5ed60a02dL,0xbb2aedc8af2f9a41L,0x4ebf90c76032c98aL }, + { 0x8e69b4c4d3752262L,0x350f201474ba8e8aL,0x7a164f6724d0052dL, + 0x5aeb80db61d7eee0L,0x626a6c9da63583bdL,0x6246637fc3f2196dL } }, + /* 30 << 133 */ + { { 0x2077dfa1817d444bL,0xdda9c7fcdf855b15L,0x577603be04b31d38L, + 0xc6beacae7a140cabL,0x8cd9dc019ecbed91L,0x6ea8591295ae114eL }, + { 0x6fb29a33fd47f1b5L,0x6203bca6223cb96aL,0x2459d85a7c1a3580L, + 0xbab5922d6410a3c0L,0x543be274cc7750f8L,0x1a653e1c42baea3aL } }, + /* 31 << 133 */ + { { 0x616abd271dbeeea7L,0x0684c14fe2189d8aL,0x0d2bf3687354d862L, + 0x8b0cfc06a8bdcb0bL,0x187147b49661e548L,0x07509bc358edde6dL }, + { 0x7b2a33bca78c2782L,0x5f41b8379ec5fa24L,0xa6df5de574539201L, + 0x3510f650093f8f7eL,0xe4d1c06ed14aaa71L,0x4d1b1ca2b0470581L } }, + /* 32 << 133 */ + { { 0x3b62315064ef6a95L,0x97645381aaa5b792L,0x4bc2c31c56471100L, + 0x4a0e73bb1bae8d2aL,0xbfc0770a8df1f76aL,0x5089916fa7bb16caL }, + { 0x2afe5b1cf31fe82eL,0x0b06831df0119977L,0x97caa333a1af2a82L, + 0x93cb92c5dafed6cdL,0x09553e7e92c3b2e3L,0x3d9c4b7d61af2956L } }, + /* 33 << 133 */ + { { 0xe56c89b06910185fL,0x1cd06d19ac47667cL,0xb35e6ae5fe41a4ffL, + 0xdc2fbaf959e8be08L,0xa9e6df08f8cec40bL,0xcab91f8ffe63ad2cL }, + { 0x1e3bd193ca2cc678L,0xe1830cae06bb40f2L,0x3b8b33d6d69985abL, + 0xb6b7e8433895d8a8L,0xec3882909fbf6b31L,0x012bec2ac37d64cfL } }, + /* 34 << 133 */ + { { 0xff2e88fd33941b4bL,0xa2d9730a8d85cccaL,0xa23f8cfa16f7d7a1L, + 0x82013193d39a250eL,0x3b119882ca0fd8a8L,0xcff642ac1a438706L }, + { 0xe4a3a95f65e5688cL,0xb2a6c836c31243d2L,0x1b7ec5d2194d1f42L, + 0x51ab34f814e4f7a2L,0xa3e3f135d3583ca0L,0xbca6ecbade9b91f2L } }, + /* 35 << 133 */ + { { 0xc85820c3002f07caL,0x090365320e00dca7L,0x0f3b3166f4e4d8c2L, + 0xe694eb4479460f00L,0x50d0ed14c15e04ecL,0x8c9998abcc86e3bcL }, + { 0xb82581624aefa561L,0x6351aca610050c0eL,0x4e60399acc8d2342L, + 0x96da3af7f633dc88L,0x1af763ec09202348L,0x76b0e49d3f0d5f76L } }, + /* 36 << 133 */ + { { 0xd83f574a08f84746L,0x48fc9715ca07f5f8L,0xb3d5d0d2dcc51638L, + 0xc2a5e3356153bdcdL,0x8242cd9a8aa4ef74L,0xe71ba25b0bdaa0d0L }, + { 0x4342d4bba4ff172dL,0x81db10dffc1341a2L,0xdd93dd877dacb140L, + 0x6f8a4e81d12d347fL,0x0d4e7e461bc369beL,0x3ce10a771fafd0c5L } }, + /* 37 << 133 */ + { { 0x2fdaa3bb8cb896a3L,0x2fb82dfd913bb303L,0x5d814a50ba9ca09aL, + 0xc3de6aa426112215L,0xd0d5c98b25a0c9fdL,0x54004b3e0eaae4a8L }, + { 0x410e2cc209358663L,0xf7e3d08a501c4ef5L,0x3d86434dd334aa19L, + 0xf70ea577772fc0cdL,0xa0eded5aa607c4f2L,0xba0bf1bc36222b2dL } }, + /* 38 << 133 */ + { { 0x8d901e759632c4d6L,0x0ed9a7ebbbd94698L,0xfd2169dbbf7bcbc1L, + 0x2b4d168d5b302c66L,0xd42f9dd73e65f24dL,0x73e0c22c0eed0022L }, + { 0xf9091588f5d2dcfbL,0x81c7c01eb8715b78L,0x2be06165dde6a9d6L, + 0x64b5902dcacd6ca2L,0xdcd510d70159d3bcL,0x5b71995b42b5e30aL } }, + /* 39 << 133 */ + { { 0xa9c474eae7a211edL,0xc7bcdd20d8170f76L,0xd9aa8d9734a15487L, + 0x26235292933c16b6L,0x289d47d5d8238fc0L,0x39f10fb3ae27ca16L }, + { 0x822e187f1c016ae1L,0x8e93b15f2be46859L,0xe2ba61a60b0a055bL, + 0xd8f33ddecb8de893L,0x016652d6379657efL,0xf4eb08f9e7d9eab8L } }, + /* 40 << 133 */ + { { 0x5559dd31e67145b6L,0xf2d905b45b2427e7L,0x0d840fabcaf57d0cL, + 0x9625866578742ab6L,0xc85482ad409c1c8eL,0xdca2a058adaa6167L }, + { 0xec26ad9a0c8885fdL,0x1b93b8a22a600cb2L,0x340aa7fc2539986bL, + 0xd7674876a23dee41L,0xa948a9292e1a9837L,0x9ae67d2a71438da9L } }, + /* 41 << 133 */ + { { 0xe753114a8d6a98f5L,0xb2d7d1e1f6ad93e4L,0xfbcfe0cf1935714dL, + 0x9dc2d293e859e729L,0x674c170889a703f2L,0x87744b0252063099L }, + { 0xa1721de04b25966bL,0x059292573a285fcaL,0x5b02ca39e8ce75e0L, + 0xbfdf0fb939e57da4L,0x554378cd6388a964L,0xc53fc5c8f853d7faL } }, + /* 42 << 133 */ + { { 0xcd3b60e352f51554L,0x6292fafab44ad7eeL,0x670561c79513741fL, + 0x95defdf3b9ba16a7L,0x6c0beac1adae36cdL,0xef05c24a3e8aabd6L }, + { 0x74208a02b23efc25L,0x71930e02c22172d1L,0xbdb1f1c6f5ccbffbL, + 0x358b483c504d9cb3L,0x48b5887a9a48a4baL,0x289256b4e48f09e7L } }, + /* 43 << 133 */ + { { 0x671bf1eebc2f256aL,0x530faa653984ca7eL,0x0a6d18955c05da6eL, + 0x219de918118fe96cL,0x289b9645bb7eded4L,0xe905c4729588f006L }, + { 0x56d0cd9ac9d61133L,0x8879550079a4f743L,0xd05e910199c2aff3L, + 0x7e91f7c985e52c8bL,0x7fd02f83b5c5d473L,0x4b43b6453c59330aL } }, + /* 44 << 133 */ + { { 0xeac6f447d56bdf1fL,0xb22e8425c2b502ffL,0xe1cc9d3dfca5a501L, + 0x8192bc29b64baf39L,0xeb2c901a52ce849eL,0x7f5f38b11dd506f1L }, + { 0xfb3684b10f0a1d68L,0x16c4aacde9240ff8L,0xffa682435a4d8995L, + 0x27264ab554e4c95dL,0x9aa40cdc4f34ffaaL,0xcb8a30a35fd818eeL } }, + /* 45 << 133 */ + { { 0x912f0a7dfa88792fL,0x2ad9249f5090716eL,0x4b828a6fb96e6e31L, + 0xe805f0588d7f2095L,0x72e95cb956e00978L,0xc95354667651815fL }, + { 0xc877181a08df5b53L,0xae055dd8779c3302L,0x3f9e6dd90b4e68d2L, + 0xdeb15f1308fbb2f8L,0x5f129c1cc5802a96L,0x7482e4af3cc51022L } }, + /* 46 << 133 */ + { { 0x98904777ab695f56L,0x6dc472c18989e518L,0x6749d25c82031d40L, + 0x5c465922c36202f1L,0xb3b5b9aff31fe542L,0x855263bdf98bc09dL }, + { 0x40ee01747eb4789fL,0xd64ae0d4de4e92bcL,0xbaea76a38995e69fL, + 0x3f22b2e3d972751eL,0x5a197daa2461f1b4L,0xbd15682a5097b93eL } }, + /* 47 << 133 */ + { { 0x7f251143534f8547L,0x213baf14222a161aL,0xae993737ad1e6005L, + 0xdc70867ff8b1cc7eL,0x41e880f3bb22e11bL,0xe36f54cbd2d6bc45L }, + { 0xa42e819d4d65ae97L,0xdc57be4de8592604L,0x8a89777fabe73b50L, + 0x435fedec72e26f5bL,0xe8d3cd8251ec79f0L,0x9574d6ea67f407b0L } }, + /* 48 << 133 */ + { { 0x39038863f7f35053L,0x421a17f3328787d2L,0x38aa682ef3d8310fL, + 0xb52d41e8f4123153L,0x4fbef3dd7026310bL,0x0c6bd7adf6ff5692L }, + { 0x3831c6b2a9be5d0cL,0xb5c9ae85e8d328b8L,0x76d26abc6516bba4L, + 0xc237f9a5446d35a8L,0xb2b16c0ff012a8d0L,0xddf2b7fe0ee0315bL } }, + /* 49 << 133 */ + { { 0xf401366a7dd4243fL,0x7db92881f434ba76L,0x5b5bacd737ffc502L, + 0xa53fe0e802cb994eL,0xf6db539ffb00cb96L,0x0bb288b379878966L }, + { 0x275c108c0c3d4b7fL,0xe57222d267236ba2L,0xc754d31890683aa1L, + 0x883a41ef2345460fL,0x8e6b7ce8b572fd14L,0x7649c29237d21925L } }, + /* 50 << 133 */ + { { 0x46302515c4af281fL,0xe2a9633c3513ea87L,0x1175276fb3e96864L, + 0xda377e32f4ed1228L,0xacf223a1fa6be904L,0xf442c41abc01057bL }, + { 0x83d766c38a69db33L,0x933dd0974cef397cL,0x094b21b575fe43cdL, + 0xf16ee57ab3141dd5L,0x4a8d0d6cb981d196L,0x6bd246c3730075deL } }, + /* 51 << 133 */ + { { 0xd9ae9faa91eab3f7L,0x8520bebba2bcdfc1L,0xc681d5a0ee94353aL, + 0x980871dd316ee7acL,0x7d70b82bcb401c4eL,0x150706c1bc6885efL }, + { 0x11709bbed3d8663aL,0xad69df943ace1806L,0xf889daef1a36f12cL, + 0x6ba376b2560bb749L,0x5342cd7a0d95f8b9L,0x5d14201273b4554aL } }, + /* 52 << 133 */ + { { 0xbb85b640056ad6c2L,0x7c51ef96ac074372L,0x1c7ce31cf10b43fcL, + 0x08e4101b26f4d3a4L,0xd18511c43968459fL,0x00e20c3fd6d07839L }, + { 0xd5bcd598e4fcdc11L,0x99e9a4d0c877f6a2L,0x9c5dd9d0bd491646L, + 0x83918f609bfd7a1aL,0x4bc130cd7e2b95a3L,0x668825fbfbc31c83L } }, + /* 53 << 133 */ + { { 0x7e8947bd5568b75cL,0x43419ecbdab8f822L,0xeb52a83a7b8fa996L, + 0xbc674ff32d1a32c6L,0xdc086f84ce405eeaL,0xebe3e087f8918ddfL }, + { 0x476099ecdb152bc4L,0x0cb491c52d3718c3L,0xa7c49cd69da8517fL, + 0xc736fcf51ab8fbadL,0xa00b403ba24fe115L,0x01f6e5bfd976f549L } }, + /* 54 << 133 */ + { { 0xef8e12edf15ad86eL,0x216be9828c20441dL,0x10ccd4f85c45e821L, + 0x8a12f6037c9745e9L,0x56212b09da6f1b2fL,0x5a81d69338115f05L }, + { 0x5aead3330a4405a8L,0x7024a76c03221eddL,0x9c101d0250e6a610L, + 0x6bcb22ffc1b6d54aL,0xf96cef62cf787e89L,0x9c9bde7b79341d83L } }, + /* 55 << 133 */ + { { 0xe9c61fa744058dc9L,0x59efcc8f1581d690L,0x1ea73467513aba4bL, + 0xf0fda8a69d03d72aL,0xcc1f3f22c6f30a01L,0xb632daa3ddf8dea8L }, + { 0x58563188fe8e2f89L,0xf053b9f67b45cf5eL,0x1ab51b07f9bda4b1L, + 0x37850e9789dc0050L,0x1bf5e41e8f6a1daaL,0x4abb4f82d94c0fd8L } }, + /* 56 << 133 */ + { { 0x817d77b106a9ad54L,0x3a999d7d89a25ecaL,0xd3ac4107da68b768L, + 0x6904bcddbebc4c4dL,0xb0d2103ca53d39e9L,0xdba86bd230a5e950L }, + { 0xb09256804f52208eL,0x37c3156a28495b2cL,0x2389ab34c15855aeL, + 0xc14dfd963017194fL,0x420e07191146b838L,0x1a9f909b8fb4b6fcL } }, + /* 57 << 133 */ + { { 0x73af3d1fa24985f4L,0x4fa27db444a1f9a8L,0x6deb02455cfbfa45L, + 0x4803e0342813c996L,0x24715fe80e4116ddL,0xa2e8258d38d8e902L }, + { 0x3321e112dd7d8ebfL,0xab8d5b2b272ee6a4L,0x2994fac34eb10fd9L, + 0xe007d0a4a9c611ccL,0x29db5aa974d194e3L,0x9e76e3ddcf7409b9L } }, + /* 58 << 133 */ + { { 0xf12a3eeab577f6b9L,0xe666e002b6db2206L,0x95aa0d03375229b4L, + 0xebd05140ef0772beL,0x9d5b5e9e48580b17L,0x960906b3a77ceceeL }, + { 0xca869663e50422f8L,0x150e844199d481b2L,0xadd97d7c3418b00dL, + 0x9908a23e68244f02L,0x5357ea61d3eac131L,0x0af5423d9778902dL } }, + /* 59 << 133 */ + { { 0x11aa3582d8e62251L,0x108ec170aa1560a5L,0x8423663e2b5b6ea9L, + 0x3f4ad292d8718329L,0xf8e3e7bd04f8daadL,0xed310c3a11b81211L }, + { 0x718db302edac9282L,0x7866f1c1e434544bL,0x1052133c568b195aL, + 0x8ca61965c0e37cbbL,0xdd28fbd32cfac1c2L,0xf4062b33dce29660L } }, + /* 60 << 133 */ + { { 0x2926ef17dd63404dL,0x0e89c4d41399cc68L,0x6507fedef7ec20b8L, + 0x1ac084ff88c751d6L,0x31bc08bedefe29e6L,0xd42199714f0692c5L }, + { 0x4d6ee74236069bc0L,0x3868ef6aff80f3d7L,0x6df02d7c5a9c6f4bL, + 0x2c3096bb101abf69L,0x0c2b01ec8eaacaebL,0x65914c20eb2e687aL } }, + /* 61 << 133 */ + { { 0x78d5ab7b34a8173eL,0xa34b72ac9230c3b2L,0x379453e13538b39dL, + 0x1764c4420f3789b0L,0x5b4bbe77a3f2ba4eL,0x3bd35b796f86338dL }, + { 0xf2fcdf04f02fa7e3L,0x6b4522f420d23feaL,0x966fb8fa01be16a5L, + 0xf2a56e96e0d705feL,0x494aa4553872e429L,0x68432d9181921587L } }, + /* 62 << 133 */ + { { 0x0ae47d1e3dba277aL,0x54607ac99832d90cL,0xd4cec32eecbcdeacL, + 0xe54b3033b9ccdfa9L,0x5b3a8a56fb920449L,0x831ec8f955eefd3aL }, + { 0x59ba32a3a02dca96L,0xb421e4b01decf837L,0x52e70a88a88636d2L, + 0x3b75ed073086667eL,0x7a4a46b3b877cd6bL,0x3825c80b59c99207L } }, + /* 63 << 133 */ + { { 0x3bc3f0e069bdc53fL,0x7e0bd730d9d7def4L,0x71a577e6844ede6bL, + 0x06d47f4981705712L,0x83bdb1a6ef108ea6L,0x853a3ce0c8a8ff41L }, + { 0xa6f114b8f408ec44L,0xe0ce4267e2d72d33L,0x405f6ddda2a0b613L, + 0x22ce3daa8d253ad3L,0x2fd738094aa1de25L,0x28a2001b27363597L } }, + /* 64 << 133 */ + { { 0x13722ab079ed523aL,0x33b29bec249d5624L,0xd3d0f467f76fdaf7L, + 0x7ce072f912ddfd9aL,0xce918a5747bdefd3L,0x14d38ab4750e5315L }, + { 0x08bbb20e3346f647L,0x428b917f05b26894L,0xc8fb5c21ca865ba6L, + 0xee6e41e02e6e8e6fL,0xd00ae6214c608b60L,0x659756396ff685cdL } }, + /* 0 << 140 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 140 */ + { { 0xbbccce39a368eff6L,0xd8caabdf8ceb5c43L,0x9eae35a5d2252fdaL, + 0xa8f4f20954e7dd49L,0xa56d72a6295100fdL,0x20fc1fe856767727L }, + { 0xbf60b2480bbaa5abL,0xa4f3ce5a313911f2L,0xc2a67ad4b93dab9cL, + 0x18cd0ed022d71f39L,0x04380c425f304db2L,0x26420cbb6729c821L } }, + /* 2 << 140 */ + { { 0xca07923c0eb008c8L,0xab79402d9985912eL,0x41e379e83cb02510L, + 0xfabac005beb383efL,0x24d12d9a1076dd0dL,0x95afd46fb208f127L }, + { 0x9cc38a60b1031e46L,0x93e21e977009f6bcL,0x6f6360d98ac219efL, + 0x1edaab3faf284c80L,0x9c3b5281019e366aL,0x6475c579bc9e9726L } }, + /* 3 << 140 */ + { { 0x26bd07d6bdfbcae8L,0x10b5173fdf01a80aL,0xd831c5466798b96cL, + 0x1d6b41081d3f3859L,0x501d38ec991b9ec7L,0x26319283d78431a9L }, + { 0x8b85baf7118b343cL,0x4696cddd58def7d0L,0xefc7c1107acdcf58L, + 0xd9af415c848d5842L,0x6b5a06bc0ac7fdacL,0x7d623e0da344319bL } }, + /* 4 << 140 */ + { { 0x8410d8298d85a25aL,0x48ee01354af81a14L,0xae460d0d18c25348L, + 0x5d0279a07eb035a3L,0x87e7c1289a114414L,0x17c08a8ec0744f79L }, + { 0xb7b2b4f1025cdbe3L,0x9a74f15d82d1af60L,0x124a7395b51ee685L, + 0xf2937c4bf6122422L,0xb4ec133207f1a7ffL,0xad801112f886032eL } }, + /* 5 << 140 */ + { { 0x4c0d78060c9d3547L,0x993f048dcf2aed47L,0x5217c453e4b57e22L, + 0xb4669e35f4172b28L,0x509a3cd049f999f8L,0xd19f863287c69d41L }, + { 0xe14d01e84c8fded0L,0x342880fdeafd9e1cL,0x0e17bff270dc2bf0L, + 0x46560b7bc0186400L,0xe28c7b9c49a4dd34L,0x182119160f325d06L } }, + /* 6 << 140 */ + { { 0xdd4eb3d07bb5346eL,0x9a46ad01382e7db7L,0x1200285ddc1973c7L, + 0xfd342beaa0046b98L,0xd19173491219a7fcL,0x5383d319b7caffe5L }, + { 0xea5a0c4e2e0fa118L,0x1cc2de3ca5457b28L,0x5b2a16dc6046eeeaL, + 0x1755e1fecc8e64b1L,0x51e4946e9e7faddaL,0xf805422ffcbf4ec2L } }, + /* 7 << 140 */ + { { 0x46d70888d7e02e18L,0x7c806954d9f11fd9L,0xe4948fca4fbea271L, + 0x7d6c7765bd80a9dfL,0x1b470ea6f3871c71L,0xd62de2448330a570L }, + { 0xdaecddc1c659c3a7L,0x8621e513077f7afcL,0x56c7cd84caeeef13L, + 0xc60c910fc685a356L,0xe68bc5c59dd93ddcL,0xd904e89ffeb64895L } }, + /* 8 << 140 */ + { { 0xf877e8c6bd08ffafL,0x24718fefaf23012fL,0x19ff269f2b004cfeL, + 0x8adc5d7795450f8bL,0x688ce8bce2a7d458L,0x74d7445b97bd7fdcL }, + { 0x1b9f4ad641e6abadL,0x6652ed05f00e4bf5L,0xabee1f7e71d83d86L, + 0xe693c76d25ffc219L,0x1c9a84afc873f553L,0x84d2718766d77a55L } }, + /* 9 << 140 */ + { { 0x75d874fb8ba7917aL,0x18fa7f53fd043bd4L,0x212a0ad71fc3979eL, + 0x5703a7d95d6eac0eL,0x222f7188017dead5L,0x1ec687b70f6c1817L }, + { 0x23412fc3238bacb6L,0xb85d70e954ced154L,0xd4e06722bda674d0L, + 0x3ea5f17836f5a0c2L,0x7e7d79cff5c6d2caL,0x1fff94643dbb3c73L } }, + /* 10 << 140 */ + { { 0xe566dc057e5f7121L,0xccac74e22ed07bc3L,0xaabfdfcdc70401b4L, + 0xac9fc4496254e0dbL,0x358d885f11c7de05L,0xb8e6a4a9d60772b4L }, + { 0x884272a5cfe917ceL,0xdfbe98689a3d347aL,0x06b90848c9d1baccL, + 0xc4ccedb6db8c6288L,0x892878b979e5683eL,0x1b521829243273e3L } }, + /* 11 << 140 */ + { { 0x916e19d0f163e4a8L,0x1e6740e71489df17L,0x1eaf9723339f3a47L, + 0x22f0ed1a124b8dadL,0x39c9166c49c3dd04L,0x628e7fd4ce1e9accL }, + { 0x124ddf2740031676L,0x002569391eddb9beL,0xd39e25e7d360b0daL, + 0x6e3015a84aa6c4c9L,0xc6a2f643623eda09L,0xbeff2d1250aa99fbL } }, + /* 12 << 140 */ + { { 0x099369c4bf0c6fbeL,0x976f78b2fe7d5727L,0x32feb503d18267a9L, + 0x162c41501a7dd0feL,0x3141e37726b8e969L,0x50497a643b53a94aL }, + { 0x96159f41607b4cfcL,0x1999b7042f111babL,0x3254987c760f2eaeL, + 0x5308075b841014faL,0xc634127e4e7adad8L,0x32a70a6059ffbfe6L } }, + /* 13 << 140 */ + { { 0x1feef7ce93ee8089L,0xc6b180bc252dd7bdL,0xa16fb20b1788f051L, + 0xd86fd392e046ed39L,0xda0a36119378ce1dL,0x121ef3e7a5f7a61dL }, + { 0x94d2206192d13caeL,0x5076046a77c72e08L,0xf18bc2337d2308b9L, + 0x004db3c517f977b1L,0xd05ae3990471c11dL,0x86a2a55785cd1726L } }, + /* 14 << 140 */ + { { 0x7279c369a1f857e6L,0x029d30ef27fb373aL,0xe82cbc806827358bL, + 0x2bfe09aaa18f57abL,0x63bf3145e5503492L,0x7ea15beafb28ee43L }, + { 0x8e6d428f5eec91b8L,0x215e03e9611b1799L,0xb995737161d476deL, + 0x2320c764e76726a5L,0xc5de88178e5e26f5L,0x24aae0699161e0b7L } }, + /* 15 << 140 */ + { { 0xb8d9b28672107804L,0xb5a7c4133303b79bL,0x927eef785fa37dedL, + 0xa1c5cf1ead67dabaL,0xaa5e3fb27360e7c7L,0x8354e61a0a0c0993L }, + { 0x2ec73af97f5458ccL,0xde4cb48848474325L,0x2dd134c77209bc69L, + 0xb70c5567451a2abeL,0x2cd1b2008e293018L,0x15f8da7ad33c0d72L } }, + /* 16 << 140 */ + { { 0x5584cbb3893b9a2dL,0x820c660b00850c5dL,0x4126d8267df2d43dL, + 0xdd5bbbf00109e801L,0x85b92ee338172f1cL,0x609d4f93f31430d9L }, + { 0x1e059a07eadaf9d6L,0x70e6536c0f125fb0L,0xd6220751560f20e7L, + 0xa59489ae7aaf3a9aL,0x7b70e2f664bae14eL,0x0dd0370176d08249L } }, + /* 17 << 140 */ + { { 0x5dc386d0a8790657L,0xa4fdf676bc4d88bbL,0x1b21f38f48bc6c49L, + 0xcdcc7faa543a7003L,0xea97e7aa8c9cf72cL,0xa6b883f450d938a8L }, + { 0x51936f3aa3a10f27L,0x0170785fdecc76bfL,0x7539ece1908c578aL, + 0x5d9c8a8e0f3e8c25L,0x8681b43b9e4717a7L,0x94f42507a9d83e39L } }, + /* 18 << 140 */ + { { 0xaeac64c96f089b59L,0xecfdc92b65f9d762L,0xddde5024f750daffL, + 0x82c01c1c0f707e73L,0xc70aa9d4ee20adb5L,0x27f6799dbeb0e60fL }, + { 0x918ad262520aa514L,0x2bb1362f8d13eae0L,0x21b60b46a9d1d43bL, + 0xf449e2d4767ab86eL,0xf42b09948a5a496eL,0x3b26006b853f2a3bL } }, + /* 19 << 140 */ + { { 0xbbe11ca8a55adde7L,0x39e6f5cf3bc0896bL,0x1447314e1d2d8d94L, + 0x45b481255b012f8aL,0x41ad23fa08ad5283L,0x837243e241d13774L }, + { 0x1fc0bd9dbadcaa46L,0x8df164ed26e84caeL,0x8ff70ec041017176L, + 0x23ad4bce5c848ba7L,0x89246fde97a19cbbL,0xa5ef987b78397991L } }, + /* 20 << 140 */ + { { 0x364d5dfda6140b89L,0x30e4a48efdc9105dL,0x13f6276018a47151L, + 0x18ad84cfa17a2853L,0x5f315c93988cb37bL,0x90f9cb701af64ce3L }, + { 0x020c67db029b6ffdL,0x8989ccc62ce3528dL,0x9bb4f9844d00ee63L, + 0x0b052413a70b4ca9L,0x7dee36dcc96b4a07L,0x226db70ea7888508L } }, + /* 21 << 140 */ + { { 0x111af1b74757964dL,0x1d25d351ddbbf258L,0x4161e7767d2b06d6L, + 0x6efd26911cac0c5bL,0x633b95db211bfaebL,0x9bedfa5ae2bdf701L }, + { 0xadac2b0b73e099c8L,0x436f0023bfb16bffL,0xb91b100230f55854L, + 0xaf6a2097f4c6c8b7L,0x3ff65ced3ad7b3d9L,0x6fa2626f330e56dfL } }, + /* 22 << 140 */ + { { 0xcd9b76b6a92f4e61L,0xa464f5225a00d902L,0xb64774e68a583f92L, + 0xc7dc2030bee842a8L,0x594743ea5d2f27ddL,0x4c0ed28ef3c54609L }, + { 0xd763346d4b1dfb93L,0x8ea291dde1bed2eeL,0xf26d4adbd6d34ae1L, + 0x74b8d24e54ea3529L,0xe20490e150062077L,0xf67b7a9092d6c19cL } }, + /* 23 << 140 */ + { { 0x3d28bf2dffccfd07L,0x0514f6ffd989603bL,0xb95196295514787aL, + 0xa1848121c3db4e9cL,0x47fe2e392a3d4595L,0x506f5d8211b73ed4L }, + { 0xa2257ae7a600d8bbL,0xd659dbd10f9f122cL,0xdb0fdc6764df160fL, + 0xff3793397cb19690L,0xdf4366b898e72ec1L,0x97e72becdf437eb8L } }, + /* 24 << 140 */ + { { 0x67bf4c98e11df408L,0x8e105c66d299b156L,0xfde3922e901b63c7L, + 0x7fd57218c184ac91L,0x6dd2ea5cebcdc105L,0x1c4956c0aef7653fL }, + { 0xd6fac6429c1c11a1L,0xeda44f663d230d5dL,0xecca2241e6902ccbL, + 0x85962a1f2700870fL,0xc5ca32c97864a291L,0xe55e974af6c8d3d9L } }, + /* 25 << 140 */ + { { 0x81dcea271c81e5d9L,0x7e1b6cda6717fc49L,0xaa36b3b511eae80dL, + 0x1306687c3cd7cbb3L,0xed670235c4e89064L,0x9d3b000958a94760L }, + { 0x5a64e158e6a6333cL,0x1a8b4a3649453203L,0xf1cad7241f77cc21L, + 0x693ebb4b70518ef7L,0xfb47bd810f39c91aL,0xcfe63da2fa4bc64bL } }, + /* 26 << 140 */ + { { 0x0af51a2025f7b355L,0x35fc45d58d8081bfL,0x0cf3036d0ab30d16L, + 0x2bd47f919109cf76L,0x8be09360ec7f12beL,0x99fc291be8dcdca9L }, + { 0x385b89868135b12fL,0x272ac288f4ec52dcL,0xe7ca370cce09b043L, + 0x94655816251f4c4eL,0x5c1dea972d40a755L,0xe8977234a4b10406L } }, + /* 27 << 140 */ + { { 0x82c1c684eaa66108L,0xe32262184cfe79fcL,0x3f28b72b849c720eL, + 0x137fb3558fee1ca8L,0x4d18a9cde4f90c4eL,0xc0344227cc3e46faL }, + { 0x4fd5c08e79cda392L,0x65db20db8adc87b5L,0x86f95d5b916c1b84L, + 0x7eda387117bb2b7cL,0x18ccf7e7669a533bL,0x5e92421cecad0e06L } }, + /* 28 << 140 */ + { { 0x240fde37b21b2632L,0x6b878ae68ca0f16fL,0x072d9ded0bc32ebeL, + 0x8c2552bc29840743L,0xb58327b003b34f8aL,0xa51598ea71dabbfdL }, + { 0x337361f7d4f461c6L,0xae88972dda1de4b2L,0x9ec86d7ade7e8c2eL, + 0x607de383f23f19e0L,0x0cb144c27d234103L,0x00878a228f0c3411L } }, + /* 29 << 140 */ + { { 0x26063e124174b08bL,0xe621d9be70de8e4dL,0xaea0fd0f5ecdf350L, + 0x0d9f69e49c20e5c9L,0xd3dadeb90bbe2918L,0xd7b9b5db58aa2f71L }, + { 0x7a971dd73364caf8L,0x702616a3c25d4be4L,0xa30f0fa1a9e30071L, + 0x98ab24385573bc69L,0xcbc63cdf6fec2e22L,0x965f90edcc901b9bL } }, + /* 30 << 140 */ + { { 0x265f7236e22b29caL,0xe36c3c3daa62691aL,0x73410e6ed2e1bad1L, + 0xa182a579a5743cecL,0x2ca67274c22b0453L,0xc698fe35546e52e6L }, + { 0x60b3a519890e9155L,0x24312c3c2b91dbc3L,0xa6d45050282911d9L, + 0x3781933efd249e1eL,0x2e0cbb93e26d023aL,0xfb479267bf27687aL } }, + /* 31 << 140 */ + { { 0xd53b592d71e15bb3L,0x1f03c0e98820e0d0L,0xce93947d3cccb726L, + 0x2790fee01d547590L,0x4401d847c59cdd7aL,0x72d69120a926dd9dL }, + { 0x38b8f21d4229f289L,0x9f412e407fe978afL,0xae07901bcdb59af1L, + 0x1e6be5ebd1d4715eL,0x3715bd8b18c96befL,0x4b71f6e6e11b3798L } }, + /* 32 << 140 */ + { { 0xaff4782231cb94c9L,0xf1b5a0b7803c1af4L,0xbeb85f8d2ef696a9L, + 0x8ce5baab4fa94fcaL,0x0a32f96200d41a43L,0x0f69ad5774f6e772L }, + { 0xbe0221af6ccb5157L,0xcb83969a2a4f91ffL,0x78ff85d6a7e49f39L, + 0x63006589cb5d3c63L,0xe8e4383596eb65f5L,0x79f59da9ff8adbdfL } }, + /* 33 << 140 */ + { { 0x3cc0df125df9b6ecL,0x3c18f44e286d6ef1L,0x55a3939e517d0f7dL, + 0x42626a32607e97bbL,0x6168e7b2e26ad78aL,0xdcf8e74b9145583aL }, + { 0xa7c541a52db84a71L,0x680532c7119210a6L,0x3252035d0a3315e5L, + 0x06dc2d5befe7c8b6L,0x940175894e720570L,0xb16e635f2f6a3ec6L } }, + /* 34 << 140 */ + { { 0x0bd0ed3803e13ce1L,0x44a148bb5868069cL,0x2a79ab57aa5095e6L, + 0x943416faffffcf22L,0x98434e8756a1365cL,0x2493315d196dc354L }, + { 0x1f89d911b79a3a1eL,0x937140a841dfdd23L,0x05ad36e43b220b8bL, + 0xff5e810333594e3aL,0x3119775f893edb80L,0x1fad811627eee584L } }, + /* 35 << 140 */ + { { 0x55c4377e204f30b9L,0x63550549a1ebd2bdL,0xdd86ee0c5e44f5f1L, + 0x8b9d1d9b5d84d999L,0x9ea95a58dda7a075L,0xa465b4a50977e81fL }, + { 0xcb491e5558421fadL,0x4617f31c280709d6L,0x5e2751c382e0195dL, + 0x698155856f8eefd1L,0x6702166cd16dc160L,0xfc14545c84c85b2fL } }, + /* 36 << 140 */ + { { 0x27c961f6e8fc35abL,0x1e0c26923a596fe7L,0xc75c7cb804351be8L, + 0xfb92bfeb1c425d80L,0xb01d1c909f0bde61L,0x273d1f0c512f7817L }, + { 0x4375000df0d71796L,0xc1655874cf53d529L,0xe157b358abddc21cL, + 0xb0f91e3e40cedc30L,0x48e26c7272260452L,0x9794a6bf0713f667L } }, + /* 37 << 140 */ + { { 0x78befaede72c6f0dL,0xc80584210bb2a3ceL,0xcee67a5d52748e21L, + 0x08d4a9e8de8ed124L,0xc0393271b5fb9514L,0x39b1df6b20942000L }, + { 0x831fd8cfc3d961afL,0x1bb097e3e752daceL,0x279b3924cf2c8143L, + 0xa9f8a939b8f5cad9L,0x2b566813bfb8009cL,0xab37ee1df58f0927L } }, + /* 38 << 140 */ + { { 0xc17f21f5134d8bd8L,0xc75fc638a90a9a1aL,0x032a6f382a22527bL, + 0x3c77a72bd20fefb2L,0x559d8a52196e2921L,0x760a3a2c9afcb6caL }, + { 0xa3bf5802f162d871L,0xb6b367a5c594d2adL,0x4d440c523daa48dbL, + 0xb2a8acafd5b2c18aL,0x50d85d6adc349ddaL,0x3c2e67718a707475L } }, + /* 39 << 140 */ + { { 0x8254a39d5e1656cdL,0xff457dcaa595e153L,0xf0ddc1936bf62398L, + 0x45e1f91a558f9337L,0x8a424d9d91480b33L,0x019f0a412bf61189L }, + { 0x66badaa6d49e7b98L,0xb0674512dad636faL,0xc767eceff4c49695L, + 0xbe16e6b5ddc80ea0L,0x2bd0bb87febd1ba6L,0x69c9f485fe60eb32L } }, + /* 40 << 140 */ + { { 0x08cf7d82bff4b684L,0x6abbf429ac4a9329L,0x2454c15ab0c8e0ffL, + 0x4782035a70bdb03dL,0x89ff6a41448199cdL,0x07969c9ffd0bf1e5L }, + { 0x19d1cc6a83406dc9L,0x4054cab9b4980267L,0xf0f5594e1887d258L, + 0x039249e4e09dd987L,0x2b0cd4f9857ddb1eL,0x54ceb29fd8418075L } }, + /* 41 << 140 */ + { { 0x562693d30843729fL,0xd703202122648488L,0xd7c40e82ec6d0799L, + 0x8eacb2496eb6fb6bL,0xddf7074885a5ec47L,0xd70524bf891d5de5L }, + { 0x4d17c237c4d01055L,0x4793c6e4b4203cc0L,0xf247d0df1d1bf37aL, + 0x406994fa93b007feL,0x4062c29902940092L,0xedc0d949f558c1e8L } }, + /* 42 << 140 */ + { { 0x9fb3630606ab1fc5L,0x2726c1acc0de4e26L,0x8b2fb5130ec7b070L, + 0xf3581a6907bacd4aL,0x97db622c164bf5a5L,0x8103517962327e3eL }, + { 0xad3637b0b1d635c2L,0xb894adf949832ec3L,0x0ab5381725685b12L, + 0x73ceb46069720ce8L,0xdbd1b68ef5e445dfL,0x57659059c8961eb8L } }, + /* 43 << 140 */ + { { 0xbd1272a5f73a7cfcL,0x30d3c078de0828e1L,0x5dc0244e1a8f36a1L, + 0x87c80cdf585ec2acL,0x46c88d277944584cL,0x588d14d8b2dbe1a9L }, + { 0xb42327a7afe7d55aL,0x58add8f98775409eL,0xa45db2fd10590c68L, + 0xb98e10bca972b84dL,0xbf5c0ee0a737aeb6L,0x26424f3def199fa1L } }, + /* 44 << 140 */ + { { 0xb7bb774603c4cd27L,0x5bfe638ad9723678L,0x47d8b4c24a04d064L, + 0xdba309383faa45d7L,0xb0fb4308b39dd043L,0x5eeaa33f23ebfa1dL }, + { 0xaa5a0ce0ba100837L,0xae025cf6d7667d17L,0x610baf5df480cf99L, + 0x8ba0039ead025771L,0x0ff4f75174785f24L,0x910736ef8b7c30b7L } }, + /* 45 << 140 */ + { { 0x0496b77ac04b7e7fL,0x6f7ea5bbdf8163a1L,0x87a8e8f18f415876L, + 0x6e5b6f2e3ee22085L,0x5ae860ca6f529471L,0xc54c8667eb624447L }, + { 0xdd06be3de1c7766aL,0x8a8e48ecd2189d23L,0xa4076d3564245444L, + 0xc4973a5deb651a4bL,0x3b3e2fd52c4f2747L,0xe9a16a24abde2ecbL } }, + /* 46 << 140 */ + { { 0xb7f146b890973714L,0x2277873f288ed67fL,0xe6da9d9ee5182317L, + 0xa446f9d3562475b3L,0xc5291f9756755d91L,0xe762c5f3c104c2b6L }, + { 0x542f90b3dde83d53L,0x758aaddddace5f42L,0x1c8b9775e673f002L, + 0x8899c11f74ec42bdL,0xfd9e300a2dbc0dedL,0x6de1c8e4d281f6adL } }, + /* 47 << 140 */ + { { 0x5ddafb1b2a2f98cbL,0x8dc2bdc429ec504fL,0x27c51b3cc9f43826L, + 0xcfd609fccacf5becL,0x642ff85c30dd9f71L,0xcab498e5b6b00ffdL }, + { 0x9c7ef286652ca743L,0xda291ae0ab95d7aeL,0xe6f4d2badfbff466L, + 0x34afffef9835d482L,0x41a2cfc050db295cL,0x51a08859e6ee400eL } }, + /* 48 << 140 */ + { { 0xf6fd26cc487925bdL,0xd9b751eef5ef44e9L,0x694a788be372817eL, + 0x85f3dc1ae8c90c31L,0x8c90c6bf15aa0ce5L,0xb52a5d83f01bb223L }, + { 0xbdae01dddf9c3315L,0x941fa6b663ddfc56L,0x50ddff4ec2548f24L, + 0x54a49868d12802a7L,0xcd922fb6404d9240L,0x88d7f41f957f6d1aL } }, + /* 49 << 140 */ + { { 0xbfd0a17e4c4c87cdL,0xc6c76ebb10b614bfL,0x721d8b4fd1c594a9L, + 0x1ff70b2daff65d09L,0x2698f57ce50ad026L,0xf4ac3f5627a92e38L }, + { 0x1114d3392c143ba0L,0x7fafa6b97f8e9b0bL,0x506f11edd82a2500L, + 0x4df1087fe0ad9ca2L,0x85509ad9fdfecaa2L,0x733c4f8293bd022dL } }, + /* 50 << 140 */ + { { 0x3b9de3494233d6cdL,0x9a360917a8f55d63L,0xbe79cdfd90662136L, + 0xbb3d8fd7cbf3f02aL,0x5d0d4eb81d61e485L,0x85b485215484cd65L }, + { 0x77580c810fc5cbb1L,0x4b36441bd8e70ff2L,0x50ccdec1b2107a8bL, + 0x6b7f97c945a45893L,0xb818859b9572a173L,0x864dc632d94bd9beL } }, + /* 51 << 140 */ + { { 0x13bb6b113fee0074L,0x4c02520ed1059617L,0x5beb793ccf71f07aL, + 0x15a8d28d46d4c54bL,0x9889a8948b89fab6L,0xd00fdcb492623b75L }, + { 0x1c7963572939a84cL,0x4b85d94d6221a244L,0xcc66b5bad1fd506dL, + 0x866271042a06ca91L,0x4295fc6a49bb18c1L,0x05a81eea341d93e4L } }, + /* 52 << 140 */ + { { 0x895dbf20df8111ccL,0xec8297be2906fb2aL,0x4ddd6f22b94c3f53L, + 0xec55cc738ecbd552L,0x549d3145ef343a0bL,0x9b19220c3b4858d8L }, + { 0xd5bbf954bd0c2f11L,0x9cacae0cce8c221fL,0x87e6cbc1f6a3dbc5L, + 0x7ce5c9b6e37ebcb2L,0x654339ef50eb3c8fL,0xeac7f343f3674f55L } }, + /* 53 << 140 */ + { { 0x723969a3dd8d5580L,0x4f6dd5c4a30edd79L,0x5b29f3f5a4d7ed53L, + 0xe17a12bd11869af9L,0x63d01e02dc4c4c1cL,0xb43b904466a691e9L }, + { 0xab58d45ad1bbbcbeL,0x1e9b166322e8a57bL,0x88b6d3bb6684cdd9L, + 0xb944dee1ddaf3976L,0x70a4a121c347c41fL,0x7e93fa26fd1c217fL } }, + /* 54 << 140 */ + { { 0x5df68a1b584da350L,0xf378c367d72cd093L,0x5908ac0033dc31a6L, + 0x89bb976b7ca65b9cL,0xefdadfe237dcf670L,0xce22b5ba0011f3e7L }, + { 0x94d2c115b7d27bc7L,0x2e6763498761afbfL,0x3c0477829eb8185fL, + 0x634c8c5531f7635fL,0xf8fb5494d4d0fc53L,0x5a905615530ee2c3L } }, + /* 55 << 140 */ + { { 0xd28e59a0940c9809L,0xc208ae4f01b9f39fL,0xae1cb420b3630002L, + 0x739950501289d72bL,0xec24392805fcbd8eL,0x5b592df51f843891L }, + { 0x0d7602303f59f374L,0x32b6e643cae9f3ecL,0x94a25696e3dcc436L, + 0x657ae6aa8a059dadL,0x0df91017edd1505eL,0xfb1ae06f7b518d81L } }, + /* 56 << 140 */ + { { 0xf5bd119ad84c8a53L,0x36c5410f26928a6dL,0xf340f2bc0eb42b83L, + 0x8d93a66cffeffe84L,0xff59141d64310b9eL,0x2d509d7aaf69e00fL }, + { 0xf0f034ae1390628dL,0xf9089c720c38b563L,0x7462988e4e8df0daL, + 0xe6041dcaa7985905L,0x86295326d3b7274cL,0x5c8bf249075aa31aL } }, + /* 57 << 140 */ + { { 0xb08d098b9e423b93L,0x8ae94622029d192bL,0x05335f68fd67f1c4L, + 0xf3cb831f6e8c1e57L,0xf84a7a54a50a776bL,0x99930a48dc49c28bL }, + { 0xdac2ef8f1b833418L,0x87a4ca7829fda2f2L,0xf47f23079c0e9e7bL, + 0xebc1c2de46aeb3c7L,0x544f76836408bfc4L,0xa01b094b86c6cd44L } }, + /* 58 << 140 */ + { { 0x8e81bd1c06841f10L,0x3fc24a346c045063L,0xbb2be2dc85bc7ebfL, + 0x32523efbc341fe12L,0x1ac9f6b116508a41L,0xb6b7fa1df6ac4426L }, + { 0x2614c995fb685157L,0xe452b94dace46bbcL,0xccda1adabc453b4aL, + 0x32d32574fb4fac48L,0x7e43920c9d7d90fdL,0x9d6e959417a08456L } }, + /* 59 << 140 */ + { { 0x2c90f95bdb1f005dL,0x801089a2e16444a3L,0x2f2944ed7a724ad8L, + 0x0dfdd065de135e95L,0x510ab3eaafed3817L,0xdba075380855fbb5L }, + { 0x905f78bda10dde49L,0x63786348956a4057L,0x3d420ff0441530aeL, + 0x7a9968bfd1488ff0L,0x97479bfbca4dce2eL,0xf371985356f76255L } }, + /* 60 << 140 */ + { { 0x8102fa85bbda55a7L,0x6cbafe0de96c5eb3L,0x517720eb26aa52c7L, + 0x0ee110a98c030e47L,0x5a058569d4afe2c1L,0x29965b44262bbc0dL }, + { 0xda017ec04996daf5L,0x1781e7b84dfb810cL,0xdbe148350c8a5cf6L, + 0xd151055dd92ff62eL,0x5e4f48ba2932a708L,0x77e163d95f28bb43L } }, + /* 61 << 140 */ + { { 0xf6c5998c48bc9bc9L,0xb25ae99e2db132d7L,0x17f29131fb934e7dL, + 0x31b96a79d7fb5430L,0x3fad00391971cabaL,0x7f809e56cf3d5e33L }, + { 0x1a4f705a9ede6055L,0x3cab6c6149c2d054L,0xb616adc47945b589L, + 0x842b8652f342ee03L,0xa22fc6a67bc36a4eL,0xffdfee262c89a4fbL } }, + /* 62 << 140 */ + { { 0xac6b2727dab13b10L,0x8b4fa7807351ac35L,0x48243c245692808aL, + 0x724897f01fbc5d24L,0xb635fe5e2c69bd93L,0xab26453338d5d5b2L }, + { 0x368b2c07bc578c97L,0x94e02c9226fecf25L,0x768de4d41f473908L, + 0x58feaadee445d405L,0x1f1380d6e42a2218L,0x2904b4542154dd5eL } }, + /* 63 << 140 */ + { { 0x4e28b938ca2ec0f3L,0xd4af48d795b1c113L,0x33ffb9c222f2275aL, + 0x2a734af97b57b2e0L,0x1555ba38d08a45d3L,0xd0cae6c57a05837cL }, + { 0xed04c869c4e78884L,0xa7ba74726f3d56d3L,0xdb7b831ef6d68485L, + 0x225798677e7d0a4dL,0xd2d702a94c3eef8cL,0xdaba503869a83e29L } }, + /* 64 << 140 */ + { { 0x082ea61d10eeed24L,0x7c9d5ade143fd59dL,0x7d33df962e54f5cfL, + 0x340b0d36e39dc6abL,0xd97a8b848d179b13L,0x88184bb0288d388cL }, + { 0x2237e507e116ae6dL,0x3e97b063211b2cf0L,0x645f8bcb42be7459L, + 0xce2b0f54de2176b6L,0xaf570a09d1e2f09cL,0x110adf5657fdc001L } }, + /* 0 << 147 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 147 */ + { { 0x158bfe27bcb6db29L,0x967212410054d963L,0xf07b153b8e71aca1L, + 0x5e67698171b11643L,0x77b7dd7dd04e2f90L,0x07814aa6f0dcf109L }, + { 0xd3bab2a4fe1d0b1eL,0x50abba31be69e691L,0x54fe99afc6f53cd9L, + 0x071f2a4f628039e4L,0xf1f44181b183aa16L,0xdf0138e05010f6f9L } }, + /* 2 << 147 */ + { { 0xb1e365019c77ca60L,0xfe084a2301018e14L,0xbf451d2ca4bfdcecL, + 0xd210892fb29cdcfeL,0x5b12bcd894514871L,0xd03ca18c1809b1e3L }, + { 0x09b243115858e4eaL,0x37b30d50e57524b4L,0xcef0a16b5de334b5L, + 0xfe0bd1e20b116076L,0x54e4b48289ae2bf4L,0xfbcc5e1a68c8a937L } }, + /* 3 << 147 */ + { { 0xa5023e1364be0f56L,0x6a7310e00046f45cL,0xe0af09aeec8700d3L, + 0xdea5fb7ceb2d38f0L,0xc038eae6859852e6L,0xd515fb4c8c34f04cL }, + { 0x546b778e1488c207L,0x8cf4f1146258d8baL,0x474e60d85182c96cL, + 0xcd0387303dbde757L,0x387232f876ab01ffL,0x277614f628231392L } }, + /* 4 << 147 */ + { { 0x309b1eb33ef5a413L,0xa7607981a81f43fbL,0x87c2b81ebf8a894cL, + 0x27a40bce0d293293L,0x7f4c315be4bf3714L,0x03fdc14e01236895L }, + { 0x319c88f8dff053feL,0x146bb448ea3fa121L,0xfcc2a05df0dd1380L, + 0xc8d55b024acba9faL,0x871358de5927313eL,0xfd1d81d317ce294aL } }, + /* 5 << 147 */ + { { 0xa135970c7361138aL,0xd67eddb5b7d50260L,0x313c6e9bc4d5311bL, + 0x4f503bf28423e5b4L,0x17dc4b6f44f3fe83L,0x15b7bdb9ccf1bbcdL }, + { 0x0ce4d64ea11b9896L,0x050b0edebbb6b0eaL,0x85531293bf5db990L, + 0x9db3b964520d095eL,0xb45ec235bd2d4e88L,0xf88a9e6215ee5ba1L } }, + /* 6 << 147 */ + { { 0x10777189c1a21254L,0x7d8d3966ca593a6cL,0x261ab515120380e6L, + 0x453c858fe13577d1L,0xb1f6bb58f3862db1L,0xf8ff48b8b9529e1cL }, + { 0x03f63a417b60b400L,0xdc248d96bba66b3bL,0x8423048b756e5af2L, + 0x4d978ed31c984befL,0xa06242995ba00f3eL,0x0bed7b454f4d19e7L } }, + /* 7 << 147 */ + { { 0x9ef52e3d6524f389L,0xc5b157c5f6ac19eeL,0xdca7a72ab5d42f7aL, + 0x2d2e8d72fa0051dbL,0x3a6ff9243f4a4f60L,0x0ae997af340e7977L }, + { 0x33dd395e269db4e9L,0xf95c3683616b9dc3L,0xb86a066122d516a7L, + 0xd50c582cad913df8L,0xac8b8efef550afbfL,0xf34fcab01d88728cL } }, + /* 8 << 147 */ + { { 0xd3797831ff63ae69L,0xa753de02ce4c7eafL,0x2ff7a6a611a4e339L, + 0x904f86f05328043aL,0xe29d31c012e9f7ddL,0x8825a639c0a51904L }, + { 0x070c2696ebfc2cc7L,0xc03ce643c5f7a943L,0x5b970d0c12c8a1f5L, + 0x572aaaa1ab352a83L,0x63df45a90c5eb0c7L,0x95c951e1d4977599L } }, + /* 9 << 147 */ + { { 0xf5aefd5572ba3741L,0x7ab81965f5fe816dL,0x597d15d546752cefL, + 0xaa79a0822a3c142bL,0x038ddfdd3af5dfe9L,0x9f4dc166755c9e07L }, + { 0xf34224dfb9165297L,0x96e7ff6e4e3fd907L,0x5d7f3c821727beb6L, + 0x7098493dd6af73ceL,0x6b9358fbe00dfa4dL,0xefb2634a96e74870L } }, + /* 10 << 147 */ + { { 0xe35daffe2e4c6299L,0x1f9e33935915cd16L,0x93f05a40f009a48aL, + 0xa4a801fd308a81c6L,0x75e5dc467e885426L,0xf0bc7d5d4629ff05L }, + { 0x356b879bdbd812c2L,0xdb5eb60001629849L,0x11c9856eec2dd55aL, + 0x20f0443880f0c804L,0xc0b5e3e21801b217L,0x7ceba67d6ea097b8L } }, + /* 11 << 147 */ + { { 0x7a1bc5d85d08d3f0L,0x9ecce2a8385ef3a8L,0xae93d42b3c1b2927L, + 0x81a3a60719ce9447L,0x8d6b2d3d0eda597cL,0x5baabad60eea6dc5L }, + { 0x2cb372642741608aL,0x3b1148d6f0202a01L,0x6e85272f52931f5dL, + 0x49bf47596a2e601aL,0x5ec0418443279ddcL,0x7d052cac6ec080ddL } }, + /* 12 << 147 */ + { { 0x01c2df8d3bb02d0eL,0x874e43afe26f388dL,0xe198341c8360fa6aL, + 0xe67f8092c52bb2d6L,0xf944dc63a02efba5L,0x9a9c02d92c12332aL }, + { 0x39684f6ca8cb6bd5L,0xbcc1828e26bc9535L,0xb7fb8eb646594725L, + 0xbb4f5f05793c32ddL,0x3ef3c33845f94b55L,0x228e0e7d09eac277L } }, + /* 13 << 147 */ + { { 0x80d9bd388aeae732L,0x2be676dccbeb6443L,0xef4d056bded9ad31L, + 0xc4fea44f349e5d0eL,0xb66c35d28d95db86L,0x210c3d4aae9f5d3aL }, + { 0x5c0c5b9c1582982bL,0x50a529be93aed9a4L,0x88f769a384c77818L, + 0xc0970b4269776a3eL,0xbf3e5ee022a1cad4L,0x705c0b29b80187eeL } }, + /* 14 << 147 */ + { { 0xefd26dca727cacdeL,0x6290fedb5fcdb147L,0x9f108a89e1830a96L, + 0x7e8e36813e039a02L,0x1747b3e9256fbb3bL,0x5aa0ebffabb3b2f1L }, + { 0xcac5818c9fbb9b49L,0x037d66114a94b74eL,0x4081fd4d7a548536L, + 0xfe2d8e79aa364507L,0xe86ce00ea81a5f81L,0x77b95e9477a9bdb4L } }, + /* 15 << 147 */ + { { 0x3eadfde5bf06a49eL,0xca88828b33787c62L,0xde6f765022070f63L, + 0xcb4e54dc438f649aL,0x24957c77169727d0L,0xa2e7781cdd2a92a3L }, + { 0x17a1d7ddc38885f4L,0xb75716717605c408L,0xfdbbcffc8a2323f5L, + 0x11666bd2c955456cL,0xf8b94fa2517f27f5L,0xe101927fee002499L } }, + /* 16 << 147 */ + { { 0x2c5b0e42bca07a42L,0xbe57f3597a0dffa1L,0xace485959aa90727L, + 0x32be886af658699bL,0xce75d6c6da3b18e6L,0x9d563e4f69caf667L }, + { 0xc17c66cf065eb772L,0xfbe123814df9f6efL,0xceb80041623db4efL, + 0xe75615b2c74762e1L,0xade8a5438671c52fL,0xb713c401cacaf2ecL } }, + /* 17 << 147 */ + { { 0xc740669ab01b20dcL,0xd873f3f1abecc3f3L,0x0d8290402db73d1cL, + 0x147aaafb99198d33L,0xca66e755d4e7d7e4L,0x8747298cb2cb752bL }, + { 0xd9d58d29c43762aaL,0xa3801a4a15e45d57L,0xa747fa3f454eaf2aL, + 0x26c79cdd0c067c77L,0xf15404cea24fe6b4L,0xe2add5ec77fec1c9L } }, + /* 18 << 147 */ + { { 0xc45064dbd71a7744L,0x1900bb8f04a6f3cbL,0xd592585a76c2dd6cL, + 0xabbbd6d862b95d26L,0xb0db482b1d2e180aL,0xf459430184c9dea5L }, + { 0xd30b162a6e5ec460L,0x90838e57e4b35476L,0xab4b7c80f9356687L, + 0x72c2c009719f347aL,0xd5d01fcf920d187dL,0x47426f1e0afe06abL } }, + /* 19 << 147 */ + { { 0xe6473aeaafb2f584L,0xd5395475c44ab7a2L,0xcba2c240bc27e864L, + 0x201735cc742c1c9bL,0x8cb4886951263febL,0xb52706ba4fd2cd5bL }, + { 0x028445755a2dec94L,0x978e79d6a4be7b6dL,0x5a68d8103c4742f8L, + 0x9c917f48b301ad64L,0xa6a7d5bd684a6ea6L,0x251d61327c978749L } }, + /* 20 << 147 */ + { { 0xdc7e39ee0ae2a7caL,0xcdd3c235e6b7dee9L,0xf9624c299368c8a3L, + 0x2086bc904b21951fL,0xf7990a1f57e0e6a3L,0xf170dd75e686da8cL }, + { 0x4a82719a06da9714L,0x3a78e35e24274685L,0x1c3965e1c67712f8L, + 0xc6c26eb62f164e3aL,0x1129a467381fb91fL,0x896022108443ffddL } }, + /* 21 << 147 */ + { { 0x25e561bd808c4ff9L,0x08c9f2758c0cf1c7L,0x9af6165b59599115L, + 0x59f06a4bb4b415f7L,0x3a9d8ca5236e2650L,0xc8fa3bc61b48ebdfL }, + { 0x5e1896193404846eL,0x6d1d803b378a5a46L,0x672fe2bab812d5dfL, + 0x3ec27a7f04c6ddc1L,0x9c5ff08c0cee3357L,0x9f465babae8d37d3L } }, + /* 22 << 147 */ + { { 0x0057f60756a0b6bbL,0x46a6e9949c1e24daL,0x1c283f859baaf618L, + 0xd75e731be878a354L,0xf9db13388bf2ca71L,0x0f14adeea9022f59L }, + { 0x309f04aa6c14666fL,0xe6cec2aa552d2da7L,0x9f27eaba218d8659L, + 0x9b3165d3c268561eL,0xc7e3afcb90ae19efL,0xb840170bcb329e68L } }, + /* 23 << 147 */ + { { 0xf6b9a32fab95aa95L,0x1a1e06c387e1c3c5L,0xcfb7ecc5317f1c2bL, + 0x12953ce7999d2bcdL,0xcaf5f0229e3c5a01L,0x0c9db571305ac94cL }, + { 0xa423d26cafbc860aL,0x82fbbd3dfe98409dL,0x455aa9926652ac17L, + 0x6916e7d6f9428029L,0xdcfbd65099822714L,0x5de152a13f3c72d2L } }, + /* 24 << 147 */ + { { 0xe6d039ef467eb167L,0xa7e0959d74696cf9L,0xf3a19b9d7078d8a0L, + 0x5d4ec99c07cdc6f6L,0x4842d0f98386eed8L,0x48f5ab80545fc0d5L }, + { 0x8906fc626d39c2f7L,0x1c050d691bf5366aL,0xac506c579f54d0d6L, + 0x9a356a6ef9e4b94cL,0x62632c5108a75e61L,0xfc1b9fa5c6951dc2L } }, + /* 25 << 147 */ + { { 0x84ba4069d034ec62L,0xd55b42f6f169349eL,0x78dce88d17de2b22L, + 0xdadae679204ec730L,0xfad5ec6b5357f5e5L,0x330bba18ccc0d0afL }, + { 0x8419755c4a566c71L,0x29c56c5fbfe57083L,0xe42a7c52598cad77L, + 0x9d81623f5fcf1dc0L,0x978eb12864615869L,0xc837262a9c2a6f35L } }, + /* 26 << 147 */ + { { 0x917747f99ee0628bL,0x5d711303566cf048L,0x206d53f15b77f58dL, + 0xe104bc12667a86ddL,0x158f8d253505380fL,0xf5b32ad4616e821eL }, + { 0xdb67191a3cdfe797L,0x61b58589147e1756L,0xb7927e12625d0efcL, + 0x48d999d008bca937L,0x335c6f5b7b02689bL,0x4f0994a9d8149b7eL } }, + /* 27 << 147 */ + { { 0xe7ba0870df6ae3beL,0x661373f0166cd7d9L,0x369d361d8627f3fcL, + 0xca06d544cf6ceb36L,0xc819e0ea34b5d425L,0x80c1ab716ffd2827L }, + { 0x3fb8c0b520b4161cL,0x3647e67b3734b87eL,0x9c3a14b203e6c9cbL, + 0x320ed1c1c3620486L,0x6d77d46b5286a22fL,0xbd6036c1bc74a266L } }, + /* 28 << 147 */ + { { 0x125951a52e6d5433L,0x7d672aee6a6013d4L,0x6ed23f2560831997L, + 0xb0e219ae438c75c3L,0x6851dd4bace91d00L,0x84704f7d30f19991L }, + { 0xd744cb32d0107170L,0x15f51a63b0cb6796L,0xe14712cf5a5807d8L, + 0xff89f0c5dbfd612cL,0x0c314718bd021483L,0xf9ccd3b11b4b76d5L } }, + /* 29 << 147 */ + { { 0x36121d0909b6398fL,0xd9ad591369069016L,0xd3a08c8469cdcfebL, + 0xd92ae9b2b03e1e4cL,0x1620c549e9b6284bL,0x5860431227ab9432L }, + { 0x4e1d3134aa314da8L,0x89207aad70910cbcL,0xacee236badff9190L, + 0xe6390f7cf6eb6df2L,0x0dfc5a5cffa91d75L,0x3474104aa0e7f48dL } }, + /* 30 << 147 */ + { { 0x00b75b851871749cL,0x063b748ea00faa20L,0xa516e09f90257503L, + 0x9ffc43981c800098L,0x49f011f871b00fa1L,0x6fc80517443268bfL }, + { 0x2802e2bf24a24acaL,0x96fdc71edde88ab9L,0xe3eff1f997e661a4L, + 0xae5c34e13cb321f8L,0xf863263e301c8ba0L,0x3c3eeb7b093e186cL } }, + /* 31 << 147 */ + { { 0xc0f51229e7aa3325L,0x3abde561fa93ec80L,0xd7e5317f4e6df2b2L, + 0x4eefcc76bc832652L,0x9dce52905d054a1dL,0xee2939da2a6f52e2L }, + { 0x8faa1d3e092b5422L,0x77f55f7f9ca6338cL,0x6dadad8f6546d37aL, + 0x0ef4922ef3bf7cb1L,0xfcf41c23200ccc57L,0x591e208362aa0372L } }, + /* 32 << 147 */ + { { 0xa933aaf7a4886619L,0x9ec1915f4af13c7fL,0x25a9dff8854de496L, + 0xa8b31d9b247bec15L,0x468a25c84661e58dL,0x8989c046786a0707L }, + { 0x282db8cabb66922eL,0x73bf240d45ca29ffL,0xa2c40faaeaeda06eL, + 0x69632929add94b47L,0xc72354f6b0069076L,0x8d197fbf7878e92cL } }, + /* 33 << 147 */ + { { 0x7bd8195662267b63L,0x9352be73894a4ed8L,0x62568211d0bfdfdbL, + 0x7974999285698b05L,0x897ccd584412ea21L,0xe4cc4ddcb2f25225L }, + { 0x808539bdb4a1d924L,0x619fee34bdebf750L,0x47ed5b3473aea42aL, + 0x91e07a9b94ba376aL,0x218f6885edb27e08L,0x4feb09e6c4214344L } }, + /* 34 << 147 */ + { { 0x24bf9fbbf3e4bc93L,0x8973b72471151bfcL,0x8e33b753a85eb707L, + 0x13eba76e50adc461L,0xe445e8e144dd9d2fL,0x8729ec22b1592a0fL }, + { 0x9a13bf315ec24808L,0xe6ae840c2e95cabbL,0x634f3416e28cdf4aL, + 0x34d3349b9278cd7bL,0xd74990c542b912b5L,0xaf94b104b2430c71L } }, + /* 35 << 147 */ + { { 0x6d26cd01580b15a5L,0x5af25c06dcd849aaL,0x05b00800ffef39f8L, + 0x8cc59e06f9e0208bL,0x920f69540bc19bf9L,0xc06c4df97faa5ddeL }, + { 0x9a26a3f4770351d4L,0xda015bd3443f40d9L,0x1afd829c740f1942L, + 0xb108a8a6566e6158L,0x118e50a9a35e5d37L,0x94cac90eab72a3b3L } }, + /* 36 << 147 */ + { { 0x01f7968e60cb465cL,0x4efeffb796e0af3aL,0x6f9016e7066ad6aaL, + 0xa8ae30e88743aa97L,0x7b77d3e0b7d55766L,0xe1773661c6b3fadeL }, + { 0xa52fa7bc88f5270bL,0x4de08cb39f7f811cL,0x6021536f9bc34254L, + 0x47bd18cf4068e3d2L,0xc91bc312ce16889dL,0x468659ea929b71f5L } }, + /* 37 << 147 */ + { { 0xa5a2a3b3225b532aL,0x5ed77864167f7874L,0x2b5d475037ae42d7L, + 0x9bd62f14433b243fL,0xe8dca1b2eea90992L,0x1ce44e53ef5e0624L }, + { 0xd92c7bf61d3d7173L,0x83c1e65424c19a94L,0x59dce036eafe8941L, + 0x23478c50d81014b0L,0xb89214bbe65a18e9L,0xf9fd325ea05d9fb6L } }, + /* 38 << 147 */ + { { 0x2c4bbee73965ed81L,0x58b6a8766c1a47beL,0x7c8d94f71a67dfabL, + 0x865c9e42ac6ae9e4L,0xa63a0e42a3114c18L,0x7432c6c92bcf8169L }, + { 0x1927723c7532bd7aL,0x20b75c7201e5781eL,0x1963e16919d57f9cL, + 0x05427a3cb10e3798L,0x31bbc661cebc82a9L,0xdd88383ac3862997L } }, + /* 39 << 147 */ + { { 0xa0ef513d4adce457L,0x942aea7df9f906d8L,0xe52a2bb5fe22c5a3L, + 0xfd9fff1f8dec9ca1L,0x19b0e7a27913f99aL,0x58c45dd205660e97L }, + { 0x6722c47ff06d3c2dL,0xe4927a002a4d127fL,0xdc647c1ef40f46a1L, + 0x538c8cda7ab7a21bL,0x90227d6cc8015ae8L,0xe62f52dc2d4ec8a5L } }, + /* 40 << 147 */ + { { 0x69a9ebd8a83bbb88L,0xcbab0b5a29f98875L,0x325e487e4e7611f0L, + 0x90aa24b1d955cc3bL,0x840e70a13c264d53L,0x15bcf88bad7f4f81L }, + { 0xe47552cc2cf0df0aL,0xcb99973379205ea9L,0x25dc58bd10d5ca45L, + 0x0947d7151228b978L,0x9a0204da4f2c7c4aL,0x4377ea4a4690052cL } }, + /* 41 << 147 */ + { { 0x35da16d16bc7d7afL,0x098c4b0271de4ac2L,0xdaa2407c3655dd94L, + 0x5136884c90380d70L,0x3f47052e762f61abL,0xf715107a8dcd6ddfL }, + { 0x862a4a6e5d76615aL,0x2b546e1b2128a6f9L,0x5297a3cf40490672L, + 0xef2cbdf1b9c765a6L,0x52e71cb4426562baL,0x34d0e3237a84f9b1L } }, + /* 42 << 147 */ + { { 0x6cd4098d74e7c67bL,0x3bf4193123d2b418L,0x598710ad682135ccL, + 0x26ccbfe0172d648cL,0x0c4918c5d84dc9afL,0x346e8b6385065417L }, + { 0xcbc7f2efd353219fL,0x93637eea3c4e4863L,0xb18fc69c2dbbd39bL, + 0x20614dd45a4b5b0cL,0xcdac0383547adce3L,0xedcdd64842ac8be3L } }, + /* 43 << 147 */ + { { 0x76ac6c94b4559439L,0x09090af620319667L,0xef433d73a742e3beL, + 0xb7ec99eb7cbd7090L,0xcde2579dcb782be1L,0x2a2fb807e75552fcL }, + { 0x083f9e982f1eee15L,0xe20f65c167779c98L,0x73c044ff5f23e998L, + 0x5fce594269488208L,0x3e4ca86ccace7ba3L,0x5e3f43b8f32c1acaL } }, + /* 44 << 147 */ + { { 0x3ab171a237b42b60L,0x6501afcc4f20e50dL,0x4f9e22413e3a4298L, + 0x3c5834d9be3b3d3cL,0x9607b8cb9be25af0L,0xcc5f6b6f81c723a5L }, + { 0x11b9b5d199227bacL,0x2bc5dd9f322cc499L,0x0c3884a0cdbc3a55L, + 0x018a8ebefd4f004aL,0xa858ee7ce08741d9L,0xb5bbfa2b5d69b3ffL } }, + /* 45 << 147 */ + { { 0x57069b4a1b0611b3L,0x24b5421c89da55d7L,0x6433c29dcf9b2fb2L, + 0xda9382c67869a1cdL,0x67fbb7a343514903L,0xb3429e35e8b224f8L }, + { 0x4058ef1e7ac51191L,0x56283b0cfd4e6114L,0x4eff0caca16fadd1L, + 0xe6088db7b6ee634eL,0x94e68bd0ca7bd1b7L,0x0e98796b965ff86eL } }, + /* 46 << 147 */ + { { 0xf3176014bbd74a95L,0x5dfe36b51bc6c763L,0x4c463aa27d3d0366L, + 0xcbd7106cff3b113bL,0x2d660f5a0b6edee3L,0x92d79c864db04c30L }, + { 0xfd1067cfd2236e55L,0x1ae21f2d90925a83L,0x8419072ca952c451L, + 0x2f268b473d946980L,0x04831991b709ab5aL,0x0d622a70bf72efd6L } }, + /* 47 << 147 */ + { { 0xec468aecf0440b85L,0xaae6041369cea78eL,0x5a88145d12a30f40L, + 0x438c6e3f37a52bfcL,0x41bf603894749b6eL,0x3d38b86267edc2d1L }, + { 0xe379125a020a32abL,0x68a6b13a198c3944L,0xed1fb3258be252d2L, + 0x76dc8df6e15c37cfL,0x5a6592cb6453b542L,0x372b1998b3347c65L } }, + /* 48 << 147 */ + { { 0x015c325eb8e79179L,0xf4fc61335b57dce6L,0x27a51e5d78d6858fL, + 0x13babcab4dd5f180L,0xfaa19cb1847e499eL,0xe2688ae608aaea61L }, + { 0xe20d7edce86100d5L,0xa9b0d46bed2fedacL,0x5e99cc0c1d357dedL, + 0x4c1263ab723cac89L,0xad5f3e6ff15e22f4L,0xf25f3950d77dae65L } }, + /* 49 << 147 */ + { { 0xf3814fdba1c6fb06L,0xbfde395d8d71559aL,0x6e4b2b1c07e00f72L, + 0xac0d1aef1e12b111L,0xa4041ea0387dc52cL,0x8004ef4893c80d7dL }, + { 0xb311b5c29a770d6eL,0xd4a340bbaf41a540L,0xe96d1dbd9a5391ccL, + 0xcd4b19fb45ebf6ffL,0x142556a5dcb6dbe8L,0xf68968ff092f898aL } }, + /* 50 << 147 */ + { { 0x540a2e35c854356eL,0x6d0eab45f5002153L,0xb8f542bd9a6c488cL, + 0xd572d282c6201f12L,0x260bc62781a3eedaL,0x508621af06eaa5beL }, + { 0x754eeb205eadc8d5L,0xfe33248f42d4b0dbL,0xf44a1c7ac5529222L, + 0x9079ccb574396eeeL,0x6c4bc87db9cbdc41L,0x1ee8982431ee3f18L } }, + /* 51 << 147 */ + { { 0xb64fc90ed811f25aL,0x310214a2c82c8f68L,0xee559209b5052420L, + 0x6055c5b45c1bf95eL,0x414f7c8dedce3bc7L,0xd3438b8a66d3cfb4L }, + { 0x687b9f70d3935eeeL,0x553b15ddd3e179f1L,0xccc9961e21ff232bL, + 0x3729ac207d322041L,0xf1537630094907c9L,0x3e87f4f903153dccL } }, + /* 52 << 147 */ + { { 0x2c21e48c7dae4b17L,0xe842930a07ca1575L,0x3a3d6d361cc47ab4L, + 0x749dba405fcd07bcL,0x55a538a6f306a498L,0xe85c60be633d42bcL }, + { 0x777595f2dafa94a7L,0x1c690529a0400ef6L,0x41485f886bfa23bbL, + 0xdead14a1256d9204L,0x74f1a820bbda2f9fL,0xc86554f65fe54284L } }, + /* 53 << 147 */ + { { 0x03ee764b978ad2dbL,0xec253b0f01c9282dL,0x028e7873fb26c425L, + 0x3e1da0436504ba10L,0x68369881531961f1L,0x0365ea56ee435146L }, + { 0xf5505ae80c00a6b4L,0xc1ac097403f34fe3L,0x7327b391b5922f68L, + 0xe561cedd1845ef9bL,0xaa82258c6a44b29dL,0x23e39cedc4d56159L } }, + /* 54 << 147 */ + { { 0xf5a07dedd14a3ce3L,0xeda454ec9c47615fL,0x01d6b1562775730fL, + 0x3ec02f95fe4d93f4L,0x335806e4dcbd0ceaL,0x3f498d1b51a19d96L }, + { 0x9949c853374b7210L,0xb255d34b25980320L,0x3b681db4307b513eL, + 0x4137053add10a78aL,0xd9c0f2728dcaae0cL,0xcbeb6b7216031955L } }, + /* 55 << 147 */ + { { 0xd1b13e72c709af4cL,0xb4b99796c12f27fcL,0x9e56569a05e2c06eL, + 0xd8c880631212ba12L,0x8da1a6704e7f8fe4L,0x3bbb314f875bb39eL }, + { 0xc56ef7088fbc8a3fL,0x39b3cef2300d21bbL,0x5e755398458e347eL, + 0x9f7b84b16c1b2162L,0x278ffd26b08d0c52L,0x7c8a442a9ec7febfL } }, + /* 56 << 147 */ + { { 0x3c0e2b9737e8e6b2L,0xa2037913575da8b7L,0xeedf0a75b925cbb2L, + 0x4f28ec1bc561b405L,0x368fb2742901931cL,0x52b54eee2f26221fL }, + { 0x381845b6247812a9L,0xf9bcc9619115a0dfL,0xef127dfecb84d25bL, + 0x4256afe5fa10e0a7L,0x0c08a532353a15ebL,0xbbd15b176a91e61eL } }, + /* 57 << 147 */ + { { 0x3c573b2655574ae4L,0xd3f12e8f2c0be823L,0x5954b69fde9ce60eL, + 0xc433991bcedfd1eaL,0x35696716718e950bL,0xce4318664e9cc107L }, + { 0xee16b6347359991cL,0x8f05851b1818a113L,0x257a228c3b494b59L, + 0x4239f98e156f91f6L,0x2382157c72efdcc4L,0xc82b652cff7b7ac1L } }, + /* 58 << 147 */ + { { 0x072eee036b7a9a38L,0x42a680cbaef9b327L,0x67311eb8b56fb35eL, + 0xf320acf3c7de3776L,0x09c89cc3ed15e895L,0x368501713232345cL }, + { 0x5a5fe1104822f90eL,0x64f7ef18c6077b89L,0xbbc5748c8bdfb971L, + 0xdf5488334b6209deL,0x02268bf676e7f595L,0x1c7971b447779e75L } }, + /* 59 << 147 */ + { { 0x90d308b495c9497fL,0x277535b782c903f6L,0x443cd37fc5d7b4c3L, + 0x48ebf0acfcaff8a7L,0x8ee8c79e579f25f6L,0xb825ccd8360ffd90L }, + { 0x6327be1599fe4be2L,0xc94c68cf59ec2909L,0x0dbf8d4456660ce7L, + 0xbb31989b5d510edaL,0x43c8c365c4a2e601L,0x100de78314dcf793L } }, + /* 60 << 147 */ + { { 0x635ee0f3d33ac52aL,0x609c328dd1970e1aL,0xf28ddf0a09426902L, + 0x2a94d4decbbcbbe8L,0x15890cf4ab7ecf5cL,0xb14a405df2dd4135L }, + { 0x64659a4fa6d01554L,0x1d1b2c43cc966f9bL,0xb02ee871df0e48b3L, + 0x0bd13e47f4dc3ebaL,0xb4763547bb4fc529L,0x868650044068ab72L } }, + /* 61 << 147 */ + { { 0xe3d60dfac22bda56L,0x021411ba6be2f502L,0xc1dd4d55b35e750fL, + 0x708b62cd4d5e1648L,0x234a80c6347b8b8dL,0x53b6fa80f3ba912dL }, + { 0x4041b8007b92c92bL,0x636c12524b6dbceaL,0x4ea250d08a1aa141L, + 0x9ffa7e35a2ae7be0L,0x765c809cd2844e61L,0x5bcabd922d56de12L } }, + /* 62 << 147 */ + { { 0x48d594e522205fbdL,0x79c78f1c0862eb11L,0x02a3becdf7798099L, + 0xbfe574a8b1ef2ae5L,0x1bfb7779c4781f34L,0x7211dfcf044da23cL }, + { 0xe4c3fd7dc3686ef9L,0x14c6e5b5e74210f7L,0xc40a0a0275ab746fL, + 0xd2033594621f6369L,0x6bdbbe3d66241d44L,0x014b089ee47f00e9L } }, + /* 63 << 147 */ + { { 0x93e3a89108e65849L,0xf90a376ba1a712fcL,0x6555d6dff1a48fcdL, + 0x984ec5c86a763e90L,0x7a7fe565e55d6b14L,0x12550fe809b2e8b7L }, + { 0x21736c048e41210eL,0x72ae44d448ce08f6L,0x02755a2871fecc50L, + 0x379da24beb485ee5L,0x394cb7ba66d7b659L,0x49fc9d60ab638c33L } }, + /* 64 << 147 */ + { { 0x854b05846150771aL,0x35fdd9b4d9ca9868L,0xec8293894c32fc71L, + 0x882fad4c9ec8f90dL,0x2d39990dc6c7b9c0L,0x7fbc201bd71a25e5L }, + { 0x6b852e655166da7dL,0xc6bde23a3d8c6e36L,0x370011545857f048L, + 0x746621fc1ccb9bc8L,0x97e44e63612bb853L,0xabc3b450758da4edL } }, + /* 0 << 154 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 154 */ + { { 0xd25f650804926a41L,0x7236b475514045daL,0x0b36031108b9b08bL, + 0x16477aff3fe92e91L,0x6e5f6cb103189ddcL,0x81ff008ec698a38fL }, + { 0x02a09218c93adb23L,0x71fcecd3445d8faeL,0x55a15eac8fd6b76cL, + 0x1e37ec3611ef96b4L,0xd1b3b3fc30e433b5L,0x4951873351d174c3L } }, + /* 2 << 154 */ + { { 0x7914213db8c9f82eL,0x7a3e4e38fc038e90L,0x6edae5a126a34238L, + 0xe566bf50701ce8c7L,0x3562e87555656e02L,0x48325ebfb4e8efbfL }, + { 0x5f10a50466505ec3L,0xd8b9834b8da78aecL,0x49d1fc25cc2f2e40L, + 0xe973bb1caf5718c1L,0x9b8825dad2d6b890L,0x7de7885ee2f00f12L } }, + /* 3 << 154 */ + { { 0xfb0fa0e6494fe64fL,0x4ea468b59a907f37L,0x9bb6d672cbabb7ccL, + 0x523c7c6ea5be2b38L,0x4065adbb361c2e41L,0xffa1299925c13172L }, + { 0x0eb29793f80d5e2dL,0x862fe1ae8e4efeffL,0xd485483e948895c4L, + 0x513977300d80d5bfL,0xb4731ffc348782f2L,0x42543c76e1a7f6aaL } }, + /* 4 << 154 */ + { { 0xe37211be7ef79898L,0xa810387721344d16L,0xfdcd7e26a1b9f8b4L, + 0x5641e45d7d7f72d5L,0x5377c1bec449c920L,0xd3edcb0cefc7b2a1L }, + { 0xc657a9ffe14b42fcL,0xc8f858c800831b07L,0x6bfcd1bcd020eaa8L, + 0x17534b0a3f6860c7L,0x8ce5722284c7c806L,0xa1d40eaf2bd7456bL } }, + /* 5 << 154 */ + { { 0x28b88cbb1a7093caL,0x09275152080a85ebL,0x0bee7d979c1dcc32L, + 0x43698f5f5ed033a5L,0x4f142867b0f0acc1L,0x6e6202ecf62960deL }, + { 0xe95a607ff005b671L,0xfeee8ea060cae478L,0x456bb6e90e8ec6e5L, + 0xc1c0319a9d088a59L,0x29c6898bbe3d2379L,0xd7049b2af8a8628fL } }, + /* 6 << 154 */ + { { 0xe0c93007c9aa57eeL,0xebb2d47b8895a604L,0xb8aebc49c4fd6ffeL, + 0x2c06e1e573f300b6L,0xa019070d81628b8bL,0x2db1690bbaf8c1eaL }, + { 0xb3fce6c8cc94ccd2L,0xf301463885bcdf4fL,0xb1e62616e2f82c32L, + 0x85581e2468295a54L,0x0f2e2ff5bf51f8faL,0x940716f1155c1f6fL } }, + /* 7 << 154 */ + { { 0x15b2dd270c6bd5f1L,0x07b5bd91eb086d0eL,0xe701742e97c5f5caL, + 0x3ce5f3f6eea06ea6L,0x51a81a6aa9cee784L,0x2bd404c1c7182fa7L }, + { 0x27deca74d5b8bde4L,0x2c1931c595385e4aL,0x04fcb34e3a79d65fL, + 0xdf3357edad1babceL,0x8bc628ffa31af476L,0x42ce1d91e5cc9e78L } }, + /* 8 << 154 */ + { { 0xaed02b6b4e623856L,0x7a6d2bef3e1d74cbL,0x82226ec4654e7c30L, + 0x008ac003e7034bfdL,0xe343c5407fd6b555L,0xca1b29071b429d44L }, + { 0xe0702a339c3ceea2L,0x48079aa9732694c3L,0x7e6d72f6d4652401L, + 0xd92655ed35f60043L,0xa0dbaac6273e8cc4L,0x0bb8f0f93c3ffb40L } }, + /* 9 << 154 */ + { { 0xc3134781a91940b2L,0x37579fc9e9b90620L,0xa506227a08acd6f1L, + 0x603ecce0270da73cL,0x8a53b67d7fdd70cfL,0xe29b7df299640bd6L }, + { 0x7bb4fa877569105dL,0x6ee80ae8567bb5e9L,0xf394bd02baccabefL, + 0xe854b3a6309c944fL,0x1271a131f06246e9L,0xbc1c205531580147L } }, + /* 10 << 154 */ + { { 0xb41b87b6c95cd23bL,0xb99714ba55e371a4L,0xb138ee8f6f571cebL, + 0x09c42be480146ec7L,0x275ee21eee9aa125L,0x0cef4d6f3a878b59L }, + { 0xd436eb1ca801068dL,0xe2c5448c762b8a80L,0x243beee1f3640ecaL, + 0xf979458b32bbba7aL,0x6bc26cfea63407d3L,0xd3b6e132392dd1d3L } }, + /* 11 << 154 */ + { { 0x123ae65005d0072fL,0x9f101624f0656bbeL,0x762bd4f4344e283fL, + 0xd1f70d5161b6863bL,0xcd99382592ef9a38L,0x53aaa0c3ac2bf9bbL }, + { 0x13904fb521ef9a43L,0x0470a8ba2beb8f44L,0xf3733943fcfe9ecdL, + 0x10b8881a79d776dcL,0x89b94c67b82b7139L,0x7af5147aeb962922L } }, + /* 12 << 154 */ + { { 0xbc06ecab3de4ba2eL,0xf51ca0639e491bcdL,0xa6fc6fa0453c94beL, + 0x5460f943ed1a6731L,0xeb11656a4ec3f1fbL,0x2fcb2cabff1e7d4eL }, + { 0x595264678fea2286L,0x838117a34e0bee38L,0x7bdf588824fd2ce5L, + 0x13df0c839f2c2925L,0x1bf621e6dee97f30L,0xb43b2558ebea6641L } }, + /* 13 << 154 */ + { { 0xf49a97d80a33b97cL,0x4e68d71512ab9bcaL,0xc0d361c04bdb65a3L, + 0x5fba9fb86cfb0cafL,0x222e12ca2a716589L,0xaea01502731f5099L }, + { 0xf322ddf7e97b37f1L,0x050e82a5e55c844dL,0x01ef972ba11d664bL, + 0xab30502882c737b6L,0x43aa811185e39769L,0x766a9350937c1456L } }, + /* 14 << 154 */ + { { 0x246c86608e729329L,0x39fcc41dd693dac8L,0x48a65b54c062a6c0L, + 0x368a57706a5a3101L,0xd143600f47ed1988L,0x48466d92a764ce3dL }, + { 0xb05006135a22cb6bL,0xf1d77247edea070cL,0xb1ddd151617f2464L, + 0x7905069828b83fd9L,0x021abb26d70bf93eL,0x590b3c42ab5a5e1eL } }, + /* 15 << 154 */ + { { 0xe86c737b728b8438L,0x21f45a22acf1dd66L,0x6f29f2d7abd4de3cL, + 0xa223154576d4435eL,0xad902927f5fcafadL,0x272cceeb04f30557L }, + { 0xc2e4e0017ebbb2d6L,0x73954580bb873ec3L,0xadf5ec7ac7fa9088L, + 0xc036da0464006dd7L,0x9c3545b5e8274f69L,0x6e153c2552325f50L } }, + /* 16 << 154 */ + { { 0x5906a35c1cfb991fL,0xb62a4f80740a7744L,0x65c8ac9136f84763L, + 0xf73b3debbe0f1dd3L,0x40358868a2d26c21L,0xd907e90a76792ae7L }, + { 0x3ecea167668c3d5fL,0x731068f26754b49cL,0x6db891090e006243L, + 0xd29106e6dd94681bL,0xb40b8694a85a3de2L,0xc80c7bf1936b86ccL } }, + /* 17 << 154 */ + { { 0xd735de6b91f7c76aL,0xd89aa1d4b054837aL,0x47c1a397271e94c4L, + 0x8d91f3f9dcb7c071L,0x4cf9be2db4cc209dL,0x4fb6842ec08190d4L }, + { 0x926423a1d7b2aaedL,0x5bbfc08957a1cb44L,0x44438c56021defb3L, + 0x8b9a2b1ba09863cfL,0xc9d5c170e37e339fL,0xa8994d5dabb18c7aL } }, + /* 18 << 154 */ + { { 0x003d45d011913575L,0x866cb2dd87e1186bL,0x692f630146b69a22L, + 0xd296a55c8174c1d1L,0x77ef6fbe9f17af00L,0x6b588be93aa922e1L }, + { 0x99ecb44f033e6dd7L,0x32edea2c1d22b7cdL,0x3122b027ba7006f3L, + 0x8950054bbb6ebc5cL,0x4f6d606182dab805L,0xc12055181bae5f1bL } }, + /* 19 << 154 */ + { { 0xeca71515ad7edd2dL,0x3f9c330e9bf56567L,0xd0b62d6749104bb1L, + 0xde92596410cc8d89L,0xc7a083f4287fc898L,0x8ba176e712d15d2bL }, + { 0x2cee62f7b4c8c4c1L,0xc15966c2ef79aeb2L,0x9b449522427c11a6L, + 0xcc850028eb49b2fcL,0x0966a06d3a22720dL,0xfd511944a1e78c8dL } }, + /* 20 << 154 */ + { { 0x28d33e79e08c180fL,0x768c7794f6aec9ceL,0x5a749f3bce683c5bL, + 0x717629d98371fe75L,0x5e828fc057712c1dL,0xb46c6ed17e4c61aaL }, + { 0x5d927bad5bccf95cL,0x55d6fc80d72f68ecL,0x560a99a398591dc2L, + 0xc885fe8a4836664cL,0xd18acd4226d79298L,0x05e4cd17185df1d7L } }, + /* 21 << 154 */ + { { 0x9c1e5db3ab34fbbeL,0x0d4b1e742f7eaa94L,0x106b0b5c86de1289L, + 0xd2c6c1aab691a830L,0x2e55cff9b9717593L,0x4522b37d075e5e95L }, + { 0xc6ee67ea3abfeb96L,0x35844bbd890b04eaL,0x0246545a55d6f65bL, + 0xc66bad2b13594e25L,0xaff4c6b35d6aa7d1L,0xebb7d2b5a3f42a84L } }, + /* 22 << 154 */ + { { 0xebc60e21fcc83355L,0xc94dbc02d9119b77L,0xceb05a312f18ae9aL, + 0xa8462962b8f69016L,0x58dde5a48f67b5f4L,0xb8bdf9c9af3c234dL }, + { 0xe95c069f80e85df8L,0x9d525e1bab3aa0e5L,0x73c8a92f76276d8bL, + 0x7feb4abd163530efL,0x8ca949b35ef5ad73L,0xe129431e2e3d057bL } }, + /* 23 << 154 */ + { { 0xa263d726c129d188L,0x89da948e9d526adbL,0xc7319a5a6b8a9149L, + 0xd85d382d8816f421L,0xfad69eb1844032eaL,0xf668901a4233122fL }, + { 0x246cc0de210ddea0L,0x26d8ccb70bc07dbaL,0xfc1b558470e6708cL, + 0x853802b775fa0b44L,0x215ccb88bb75a5b2L,0xff50f0cf24e60054L } }, + /* 24 << 154 */ + { { 0x9d8a925b60dec308L,0xb72e3efa6b3ea363L,0x4f53ca6ddfb534b8L, + 0x4e64874c6dd78a32L,0x336e5b46c2a146d5L,0x07c76d6398395201L }, + { 0xa4c095228fe3e815L,0x887e659d3221cc26L,0x0ff92f64c36286ecL, + 0x57b1b903c3ebb08cL,0xc6bdc9b665f00c30L,0x826242269a46d36eL } }, + /* 25 << 154 */ + { { 0xe054597768bbf4f6L,0x17bb77edb6e2cc19L,0x0cc551d89ae950f7L, + 0x3490778d761763a4L,0x1c36044a32647ceeL,0xa6e083223f9d2938L }, + { 0xea392a153a656a51L,0x4d51161ba083cb54L,0x15c01e792c690757L, + 0xc7bf5d7c5cc62636L,0x1b00cddab2ccd76aL,0x68f49fa995313f8cL } }, + /* 26 << 154 */ + { { 0xc782c16c1a0b619aL,0x8643d42bbe316086L,0x49d2966bc0daa421L, + 0x080b1cafb7b487e0L,0x1d33bb53144de273L,0x8bafce2d6faf7ed9L }, + { 0xdafbe3cf408d4636L,0xf10527df7ee8835bL,0xe1123f3ee2e75522L, + 0xb388c64bebe27d60L,0x2cb38dc1e3f1f55eL,0x57ff8e43e34524d8L } }, + /* 27 << 154 */ + { { 0x557dc1cbea28398bL,0x34d5709a208996b9L,0x94470993e97a3306L, + 0x0343320772b117f3L,0x66c4e442f056525fL,0x27753c526d11dd35L }, + { 0xf0aa7658b26a70d7L,0x95608b19543cd7ebL,0x618b2e17bac19156L, + 0xe7e42948cae64ba1L,0x2016a9d59657ec93L,0xa38f67e03d7ea46cL } }, + /* 28 << 154 */ + { { 0xd67dc92b85653dc8L,0x8e0970af0bc93ab9L,0xb6f09baa8b87c0afL, + 0x5a8a903052760ef4L,0x2e2ae7561047bf85L,0xd049078f85bd4e74L }, + { 0xced11ff83729f708L,0xdd21cbebd91068a6L,0x83d488ff24b3e911L, + 0x6e166fda1afd2196L,0x66a912114f0d2128L,0xd11078ed05c9f39cL } }, + /* 29 << 154 */ + { { 0x69aef6f919c64bddL,0xe7d4f909598ab592L,0x48952e280e55124fL, + 0x637693f6290b558bL,0x3afb2e7b421e60e9L,0x00d1dbac79aac8a9L }, + { 0x45156c5cc08563d5L,0x8cc201be4519c881L,0x2e36c0d7bd616581L, + 0x595fe0164ee16dffL,0xeebec40ae4889c65L,0x23b6dfd7d35b94e7L } }, + /* 30 << 154 */ + { { 0xd87003d3bdbdf0cfL,0xe9750b5b56c298f1L,0xc256c3a2b73ad05dL, + 0xe0779a192ee94279L,0x31d8b3c6279626a3L,0x469056bb90163bc8L }, + { 0xe6aeabc623755853L,0x9fffdfe2896a6f4cL,0x15c1ce78a36cf41bL, + 0xd4c8c025eee41941L,0xf7a917ee7653be9dL,0xfa3cba9659d52222L } }, + /* 31 << 154 */ + { { 0xa02f08586d8c610fL,0x9819c563ad4af3cfL,0x085d4439b95d17eaL, + 0x9df256ea616f532aL,0x5e9c5419cebd249cL,0xdd5ffbf451062a22L }, + { 0xb8910ea5c8b33577L,0x5e8b7ff7ff8e63d7L,0x5e4f3926b24e230dL, + 0x163eb51eacd851d7L,0x9bda95f2ea2aef8eL,0x3d6887755aefa290L } }, + /* 32 << 154 */ + { { 0x913f92075f8ab132L,0xd5b6792c5c14080fL,0xefab4e2c787c3594L, + 0xa55d465fe7b7b7ddL,0x921aaad834e28e6aL,0xc4f3a35e12d6a7bcL }, + { 0x109803c46115a5aeL,0xc023098ce709f9a1L,0x1a8c8bdb99c5bb66L, + 0x1cd1c2b6bc7c2da7L,0x50189c975f927eefL,0x493823d1229f9410L } }, + /* 33 << 154 */ + { { 0x34ec4dc840dedfb0L,0x1109ddb93aa89063L,0x93d9db278c218bb9L, + 0x07131b6e0b6007ddL,0xf90570ddcc4690f0L,0xa6a9a634afa26a59L }, + { 0xbd0c25194292e2b7L,0x92b99706a6d44b7eL,0x89481adf4942c03bL, + 0xff5e56b98a0c30d5L,0xdfd8939591c80fafL,0xed9d140840663594L } }, + /* 34 << 154 */ + { { 0xcc22db55c41e42fcL,0xc90ec77e4c9f2411L,0x419b9f46e4c02557L, + 0x156ed30ccee45c60L,0xf2c1340a72e4a938L,0x4a9cda8a204775a8L }, + { 0x900fd58713952b75L,0xa82ec2b812461145L,0x9f1875d41db68028L, + 0xaaa6af31308475acL,0xa11f379442d4b884L,0x1f1fcbe3d087882aL } }, + /* 35 << 154 */ + { { 0xa32d5a80a292fbecL,0xe0b10099d7091eabL,0xcb99bf7b4bfe6956L, + 0xfd806d4c61955461L,0x7124b1bf931066fdL,0x29fad019649ccbf7L }, + { 0xd1fe7911049609e7L,0xb568e167592f93c1L,0xabe7d10398ba066cL, + 0x0cd22c9668d7ac2cL,0x0ccd0c21427522d3L,0x97ba199ba503b4a4L } }, + /* 36 << 154 */ + { { 0xa0f2da0c78a2cbf7L,0xd1611acbd163d80dL,0x1af6ee1bf2cd3795L, + 0xc4993e08307d6105L,0x84c3b8f8560b5f12L,0x4f52c56347869733L }, + { 0x8fd9e3f728d28bc6L,0xdbf34576e5d44bd9L,0xf7e3a6da10d14cb5L, + 0xb93870990fe051ffL,0xf6363a48f15d43d5L,0x4bc358fcf434d1acL } }, + /* 37 << 154 */ + { { 0x35bac9471eae6dacL,0x4244697e39d6fe97L,0x16ec7f64fe017230L, + 0x393856d10493823cL,0x0782fbb55b7cbbfeL,0x4c399e3f5820f9f9L }, + { 0x86311cd9c08fe816L,0x057d4cbbc3ac958bL,0x63f09d484bdb0531L, + 0xab0b582b0b89ea02L,0x19c52243beb30331L,0xafa64f25ca87ff6dL } }, + /* 38 << 154 */ + { { 0x0d28a67859b1f4aaL,0x79b04589c52d40f4L,0x443b7fa5219303d9L, + 0x5be78d9663972eceL,0x0ccb969e7d984869L,0x7d8738077f81916fL }, + { 0x3502b3e426d9f292L,0xda1de7a82c90b612L,0x5605f5dc434f27c0L, + 0xa50d3328df89c616L,0x5a80cf84e7082731L,0x2c89e4b6f7ce953aL } }, + /* 39 << 154 */ + { { 0x7a46cd0d01fdf1e6L,0x86868e74e8690fbeL,0xf038771d8a8fc3b2L, + 0x30135b3084303d90L,0xa7ecb9ded562d20bL,0x7a6d1f37884cd233L }, + { 0xa30ca0bb07dfad3bL,0x1690d6018e09fa7fL,0xe582449f6c744551L, + 0x0b0030a21b935d17L,0x6b46681272bdb78cL,0xe40d4e5f56d4f328L } }, + /* 40 << 154 */ + { { 0xa29978fc62a8b8b4L,0x4cc216310fa130a9L,0xe4b51c6bf15e04c8L, + 0x453cf4d23f815420L,0x1257c751c6282b9dL,0xcd15b03c8af1af36L }, + { 0xe3596240514ef6e8L,0x72a6691708ab83d9L,0xca0a62d710e44b2dL, + 0xcde068128a9b8a8dL,0xd492b261ba470875L,0x5c7ea67cc6d7aeb8L } }, + /* 41 << 154 */ + { { 0x6acd945fc0995487L,0x06d5b2e47abac4fbL,0x42cddd75aaf3d12bL, + 0xca7d2363de1b9632L,0xbb1a1990dfbbb30fL,0xb0beb43139fd7bd4L }, + { 0x9ceb36884fa796e7L,0xb4d2bc4ba3266ab8L,0x79bda9d6e02df012L, + 0x414636bbf6faf7c4L,0x0a6603b9d1ab23f9L,0x2bc60c848db14f7bL } }, + /* 42 << 154 */ + { { 0x1b36ef27007ff90fL,0x394fe8095111399dL,0xaf4f246cb758e748L, + 0x794e4b151a7139a2L,0x40869a49eb527db3L,0xf2e15106f46d1b34L }, + { 0x46619f0352ac96e6L,0x40f556de49caf0c4L,0xa36b11d693072befL, + 0x871919b4ab2dad50L,0xf44b8084792dcefdL,0xe051823dbc31b021L } }, + /* 43 << 154 */ + { { 0x56293d8dcfd7432bL,0xdedf8dfd1d5f72c4L,0x743f4a71ae604fb4L, + 0xfb35ab43730caf7fL,0xcaacce6b20fc2167L,0x21ec3a0daa8ac71aL }, + { 0x4fdf5890c21ac9baL,0xbdc41ecfd6149328L,0xb1ac4d519b381c55L, + 0xc4cc08fd63f10a98L,0x2b9f0d3a4913a671L,0x9ce9949cbc36a952L } }, + /* 44 << 154 */ + { { 0x5049a7d3f758b1b2L,0x60beb74f14ab97b8L,0xdfc47828a9ff8ad3L, + 0x303a0cde8bb99766L,0x53f4b45a43b9a7a6L,0xe467aec8ca6e8c43L }, + { 0xb8e7db7b3f573855L,0x5fee5a5481e760f1L,0xe928b23385b0fed4L, + 0x72f02728ebae0b7cL,0xe32abf70bb5897d3L,0x103e8b859c572995L } }, + /* 45 << 154 */ + { { 0xf321278c2dc1a02cL,0x06ca03865dd09f91L,0x3c28640b7bac9e7aL, + 0xe3a7f9b527b1a011L,0x9137ad0407ccedd3L,0x3a2976a8cb6b447aL }, + { 0xab1c39248225c1ecL,0x30703f108f9022a8L,0x212f0f1bb0b2a64bL, + 0x76ad924b3e73862fL,0x47253a5c84842ac8L,0x33a03a17755af95eL } }, + /* 46 << 154 */ + { { 0x97c371fc5a274b61L,0xc7362cdbb14c680bL,0xa8cdd929efbd49afL, + 0xdfb2d5f075325f06L,0xf62d10e2b905531bL,0xbdfbfd8462ed0c3aL }, + { 0x252061599d07d2daL,0x1376775152491224L,0x165637057413313cL, + 0x642a7911a2b88eb1L,0x42d9dc6806ffe363L,0xe81d3403017bcc9fL } }, + /* 47 << 154 */ + { { 0xa68ce9db93d57f06L,0x4d1fa86a31dba07dL,0xf11603178c4822abL, + 0xc2243680633c26f5L,0x6b4e91cd10f1da80L,0x4358155734827d78L }, + { 0xbf54e87400c19817L,0xf52b94c4f2bad957L,0xcc85de8144e71756L, + 0x4f7d8ca365b7a8c2L,0xff76efa579d7c36eL,0x50a444025952932aL } }, + /* 48 << 154 */ + { { 0x87c0ef84172784bdL,0x023128267a5f2d07L,0xeae5c0cec9901fa3L, + 0x6ea74133a11144e5L,0x740c3d2ed8e89beeL,0x88e06131f9bb1801L }, + { 0x47f253754356fd51L,0x8e2ca6ce38e45ea1L,0xf0afe990c2ef8066L, + 0x91b7263d8ea03d0fL,0x37b01664880ca591L,0x61306f09790c8ed7L } }, + /* 49 << 154 */ + { { 0x084c4f92b24a5736L,0xf3d01da90a3c3859L,0xd37c47ed7468b812L, + 0xeb539a939567c798L,0xd852f502acfdc072L,0xd8e5454996245975L }, + { 0x42ec3948db5e323dL,0xdbebd1c7002d3fadL,0x9cc5db55d7c62d0aL, + 0x22af02388afa4c07L,0xbdcb68fc6979eb74L,0x33763dd544dc11baL } }, + /* 50 << 154 */ + { { 0x4734465f87c2e496L,0xbafe4fb4eb7d82c4L,0x940b168521837f17L, + 0x790d7041345a66c3L,0xe9973cfd65ea596cL,0x45fc95df058b3350L }, + { 0xc63bf91405d08638L,0x36e6af6476465a92L,0x7fe09193f1eb3701L, + 0x364f64f06468e2aaL,0x83108431f7129cc9L,0x3ac117205606bf94L } }, + /* 51 << 154 */ + { { 0xe6a85c7d34dcecd9L,0xc14437fe338cdc1aL,0xa5eeb471b3a9233eL, + 0xf230947c71349a62L,0xe704a95686308ebbL,0x0ef4d4da4a362a8dL }, + { 0xae9be4394b634c67L,0xf736c07c569f0039L,0x7356f3010f5f07d9L, + 0xc86c4000823c9cecL,0xc43b3489951ab5faL,0xa7a3b3a6b46bb659L } }, + /* 52 << 154 */ + { { 0xb1d6cb737337af87L,0x09a59a6908638c3cL,0x4ecc3fd25d94c727L, + 0xa7b57269e274ba87L,0x909cd824a61a0590L,0xcbe63cfe3c11751dL }, + { 0x9574de8347c46efaL,0xee334cda539b7e03L,0x245bc6a2e3ef3599L, + 0x13a570fee88d0da7L,0x88ede26d90ef4a21L,0xa0c5953b01fccebcL } }, + /* 53 << 154 */ + { { 0x855ff0f7657121c2L,0x18754814f94c7402L,0x720f1e3c32ce8340L, + 0x7ecd080ee8e49d3dL,0x2838e642f0bee412L,0x69cad618209f8e60L }, + { 0x5730f2dba983a4cbL,0x74957697f43896a1L,0x68de04373dc55d4aL, + 0xa2fbb915628698bbL,0xc8279c975cace19dL,0x7df557465fd52bc0L } }, + /* 54 << 154 */ + { { 0x1cb1c2f378c3f521L,0xa425f99b63116c7dL,0xc86b48c36f7c0e71L, + 0x9e92e82dc76a73ddL,0x8c0414657e7d6df8L,0x99e7884d38c02d8eL }, + { 0x6c53c0cfb78a7e50L,0xcbcb5114481d60ebL,0x1eed68ed035b4441L, + 0xdc95269f755f18efL,0x3ad7f32a3fe51f12L,0x981782d017296245L } }, + /* 55 << 154 */ + { { 0x7743ef2655fcd15eL,0xa73944a4d07f3cc0L,0x3161d6a32438cf14L, + 0xad193a9b14e8938aL,0xe1de190e872dac01L,0xb165da2fc4795b10L }, + { 0x1eb89d519e155bfeL,0xc8b97d94c9c552d5L,0xea7d3edb108c4c82L, + 0xafb60b29c10acbb5L,0x331b316b82c7b642L,0xa53c4b3d719fa342L } }, + /* 56 << 154 */ + { { 0xc8dc34f36b3bcbdfL,0x952d337b24d72806L,0x28b8ec817e56e8c8L, + 0x98e78abdbe861aebL,0x521773ddcf3bd040L,0x582ffcb2b7ca45d2L }, + { 0x70962c0a04202ac8L,0x31b6ac909f29381fL,0x3b4cd403355715a7L, + 0xffbbd1a7399a071cL,0xac669b08e50f02d7L,0x0f568c89b2cf0565L } }, + /* 57 << 154 */ + { { 0x2d2afc2daae7e637L,0x840e47c782a818efL,0xfe26a67c879f2451L, + 0xd41d289810f54247L,0x36040f4877119f14L,0x741859a983f240ccL }, + { 0x15f9607a8fa720c8L,0x8eb70f6df7b8e32dL,0x755394229b98d670L, + 0x80a4a127750c4e62L,0xbe88d03195ca3a50L,0xfadeb53dc6411eb6L } }, + /* 58 << 154 */ + { { 0x19f29da06b824028L,0xa5cfd12b7bd354a7L,0x1cb5d74caeb59b3aL, + 0xec9a8ccc47211999L,0xd7f2a1c17852f167L,0x134629209a1859cdL }, + { 0xdd65f7ac9e3a339fL,0xccaa968075437831L,0x25772f9b7f502bb0L, + 0xa64cd12f6fa0aa66L,0xd2f46ac62af2c3d4L,0x58433d963f262a2fL } }, + /* 59 << 154 */ + { { 0x747757c6715ba7e6L,0xc01b73c1f9cbefd2L,0xf1d96de501bbc017L, + 0xad554e91a1087f55L,0xd9b74be65a6cc716L,0xad2f2c0320317019L }, + { 0x42ef19c207893532L,0x7f3624c40858fdc1L,0xc104bde7078936c6L, + 0x99af706682b5f95eL,0xa40e02625a13a9a0L,0x6c0251c40a318574L } }, + /* 60 << 154 */ + { { 0xedb3abb1fe36eed2L,0xbb2cc1e6a038298aL,0xfa0ac06fe5adc3beL, + 0x7cbcef3eae73ebe1L,0x41596590cd676b87L,0x6cc8c0ae214391d7L }, + { 0x826e2e16fcb3f244L,0x1ed7837e1be22058L,0x83052d0d1a9912b3L, + 0xa2cb410c8ac3dbf5L,0x279d555a7faa6bc7L,0x870e7132f52b439cL } }, + /* 61 << 154 */ + { { 0x5957428e385308d3L,0x49ba20b3bfdae187L,0x4e1281c3adb44defL, + 0xebe93dc4e75c6cf9L,0x81d1d1cff675fc6eL,0xbe01bcecfe0e371cL }, + { 0x713f294d336bc7caL,0x1beb1508e26a1903L,0xbb5feab4b6819961L, + 0x28bede2741bfc7efL,0xb0a5108bb3365719L,0x81a8c9255ccd21a3L } }, + /* 62 << 154 */ + { { 0x4f3d90af2bea6870L,0xfebb0de2ca26ca46L,0x109d96e5d58bd9d2L, + 0x4b42928cd9882c8aL,0x5238cb7a8c73adcaL,0x9d79d72a4adfc913L }, + { 0xba58929d1f0bf201L,0x0b7790a505f52baeL,0x361949aae45fda0bL, + 0x21b2d006af3f732cL,0x1ed05dc33aa84bf8L,0x2322b7f72405980cL } }, + /* 63 << 154 */ + { { 0x4a38b5b2c7151e42L,0x1d5dd94894550168L,0xf2adeb5b7b3d1d93L, + 0xe15c42fa36661a89L,0x7d55a3f27a3aee90L,0xbe1b5c39d9d350a4L }, + { 0x9c4d6fa2610f16b8L,0x7b96051da60fb18eL,0x539762fa496c018bL, + 0x048ffa39168a8f22L,0x33486ccada1c0a58L,0xe216d6be9fd687a1L } }, + /* 64 << 154 */ + { { 0x11a8fde5f0ce2df4L,0xbc70ca3efa8d26dfL,0x6818c275c74dfe82L, + 0x2b0294ac38373a50L,0x584c4061e8e5f88fL,0x1c05c1ca7342383aL }, + { 0x263895b3911430ecL,0xef9b0032a5171453L,0x144359da84da7f0cL, + 0x76e3095a924a09f2L,0x612986e3d69ad835L,0x70e03ada392122afL } }, + /* 0 << 161 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 161 */ + { { 0x3ee0a31c6754f492L,0x02636c6b96769ff5L,0x90a64f4ff0fbfa96L, + 0x513f054efafea65aL,0x796ba7479cf4b9f9L,0x3198c068932a9590L }, + { 0x93af8a65549ee095L,0xb8b6f72ca212760fL,0x23bc71e9c1a46c8fL, + 0x000643af4c9bca72L,0xb6d967c7848cea30L,0xe06b6b4e73312ec2L } }, + /* 2 << 161 */ + { { 0x52ec99561d85a725L,0x0f9be000f3208012L,0xe881337c6dcc7816L, + 0xe4e7b6d9791f7cf1L,0xfaa717aa59885a42L,0xb1bbb5c7f9c01e41L }, + { 0xcf208d58a0361880L,0x24426e4020afa350L,0x7261871b264ce04aL, + 0x66be4a86cd42026aL,0xc5397b77829f99feL,0xffe4a6bc24578e2bL } }, + /* 3 << 161 */ + { { 0x0733667af822d5f9L,0xd7f81b9e18339700L,0x7ca29b27a7bc265fL, + 0x9fefa698eb4f0c7aL,0x7b6f351301f27630L,0x72f0f152fcfb1133L }, + { 0x9928d9d05c81eb14L,0xa16ac36bed8ff6cbL,0x7fbd1acbe041bef3L, + 0x7d25159af8d99854L,0x2ec3a7d8db5a0dc5L,0xd86fc4cc87e3e933L } }, + /* 4 << 161 */ + { { 0xba8418f34c20e15fL,0x7eed2494fb54404eL,0x4e6438d7bce1e82dL, + 0x9e489b3eb397915bL,0xa9baea9ffb4cf659L,0x8bc5b2ba42ef4affL }, + { 0xae3fb5337e62a188L,0xcd648493496e8e35L,0x89728e28defe047bL, + 0x63a8c679d24e60feL,0xadacbf92470f710cL,0xd470aeb95e198d3cL } }, + /* 5 << 161 */ + { { 0x8e3807dd7a3e874aL,0xc4edb45b89ac3a99L,0x9ba9cdaf4bfd77d2L, + 0x31d33f59b540fffcL,0x404c87790c60028bL,0x7f89da7189688c81L }, + { 0xdd3390e5504b862bL,0xdf1e721be937efe3L,0x5833d0df63e6036fL, + 0x7712527a385fbab4L,0x6347236bd210c0d4L,0x12d7733c8d238e2dL } }, + /* 6 << 161 */ + { { 0x0ecb0723302e943fL,0xd180ca1e4a443e78L,0x39e7891123dd2c9eL, + 0xfa2a440401fe50bbL,0x4678e7ed154d39d1L,0x64ddaee1af513e01L }, + { 0x6d4c615a634904daL,0x937c6326ba5c900cL,0x70658f5feb6c8582L, + 0x2a04fd51f3d65166L,0xcefe7472b676eb47L,0xd3565a71f597d887L } }, + /* 7 << 161 */ + { { 0x299520f4e5dcba80L,0x522ad4b52b758045L,0x54eabe27193b36d4L, + 0xda4d3bff45e9e442L,0x44cb9252637311f3L,0x4cd620a971338ebfL }, + { 0xec908157cc9524fbL,0x2731a11ba8c955d7L,0x72a5e0545cb94009L, + 0x7eee8f3b9126cfe8L,0xc71e29203dd5d5ceL,0xe886f91a22069494L } }, + /* 8 << 161 */ + { { 0x294d29550db962c0L,0xd6994ef46d523ab0L,0xfa1a7f9158f95037L, + 0xb137981164420c94L,0x2b686e1e093caea8L,0xdef10944f9e1c340L }, + { 0xcd1beecf611d9bf5L,0x34696c50a1b5267bL,0xcecbc7192dfc2b16L, + 0x2cdb955dcee7e854L,0x9fefc321f2635cc8L,0x276d2e4f2936f7d3L } }, + /* 9 << 161 */ + { { 0xa9de8b87d38e86b2L,0xe0c2f232780d2fb9L,0x742d7fe9449e78b1L, + 0xc6946b7ef29efe3bL,0xbd59bcf985de7456L,0xb070ebfadb492e64L }, + { 0x5cda7ac8a0ff7c15L,0x6e0c0062c4f435c9L,0x4d8e5395974d4be8L, + 0xa0a0c5984e6d1681L,0x5debadbea14cbda0L,0xe176a772ae30b167L } }, + /* 10 << 161 */ + { { 0x25df81bce7b19019L,0x3058081aa6f45519L,0xccafbccabb3de1d7L, + 0x2b794710c515b1b0L,0x74b81bf87168d9ddL,0x92d5e462ec00571eL }, + { 0x865e29efdc670943L,0x2350537c7f6299c0L,0x9fdf787ea947c6f8L, + 0x9601cb21cabe0f8bL,0x2899d5f49313b000L,0x4873bc9f66a9e8e2L } }, + /* 11 << 161 */ + { { 0x2829add72f163a26L,0xf96dd91156909488L,0xc16d185f769ccb59L, + 0x13c4b566e9c6da4fL,0xfd68110bc423ac34L,0x64911819cfaa9fb6L }, + { 0xad7c7d2b12dd07e5L,0xbf7eea90abc19a50L,0x1db70ed108d6c57aL, + 0x01da2b41446deeabL,0x163a5a5fa4f6a367L,0xca9f4bcca10c8a53L } }, + /* 12 << 161 */ + { { 0x2132c32e68206a00L,0x20bc1bb483bab6d9L,0x99fa3be2bc4ef156L, + 0xe515cd05ebbd6c33L,0x9c06d7670d2c8ebcL,0x2fa7f3b68a79c884L }, + { 0xa4dad16a9137df25L,0xc4da20f833598c21L,0x32f5d9e3867cb117L, + 0x8f00fb54da7cf533L,0x428cf9e3870ef3b4L,0xa8b6c754521b8428L } }, + /* 13 << 161 */ + { { 0xe9b297be7be5e610L,0xd09f63c304b49303L,0x9110a9b381ebb814L, + 0xc32af8986bf19586L,0x5c4939571da2280fL,0x89e85cb41becc5f5L }, + { 0x1068cb528f1a396eL,0x49dde483440a6144L,0x51280400b5d6aaf0L, + 0x0e8ac4a53e8ea21aL,0x32f4a91d92582420L,0x5eb09649bc35e408L } }, + /* 14 << 161 */ + { { 0xea3a2f0c32f235f8L,0x8281bfe5bf4a8256L,0xf44e1319577b9e1fL, + 0x31732d1bab2d9ac7L,0x6e7682eff375c5cdL,0x7069fbaf0913ed09L }, + { 0x693257dcf690cb94L,0x576a85b2dfa6e07bL,0x72e00515447fe4e4L, + 0x00af617509a2cd8bL,0x05a61365902ae75fL,0x8310b16db5ecb690L } }, + /* 15 << 161 */ + { { 0x4d22c79cb00fd8f5L,0x432b09844c9ed8b2L,0x43da93b2a85b3f0aL, + 0x0522df2ac4163655L,0x2ea7210b77214019L,0x8280099b7051a9a3L }, + { 0xcd0a829bb11b9e80L,0x9bda76c7246ee656L,0x1ece801bad70a0faL, + 0x4f8162f096721d79L,0x341faae58e7c3b0aL,0x6914420b12e57cf4L } }, + /* 16 << 161 */ + { { 0x4962c02167141724L,0x5f81eabeabe7762fL,0x78549a79dd189c3fL, + 0x47675cdd6ce517a7L,0x5102294e32d6bb97L,0xb19500c66ed1a029L }, + { 0x3efb54e8b16a206cL,0x7dbdcc250dc135b8L,0x955bc2948967fb04L, + 0x373615c9be04e909L,0xf1fcf820111efad6L,0x8530f97d6fd2e97aL } }, + /* 17 << 161 */ + { { 0xdfff3aceb3b513d3L,0x569f9d42fdaed4c5L,0x8615a9cf71cdec34L, + 0x2e700c34ceeedc56L,0x9047d770a48d0682L,0x3fc845780ee5893fL }, + { 0xaaaf3d90ab5b432bL,0xc846365184cb412cL,0xd215030d928ec9bdL, + 0x237a710045b97accL,0x0f533045ff791353L,0x093a0d21a1899bf6L } }, + /* 18 << 161 */ + { { 0x5da20568b4bcee44L,0x878025840f5bd27dL,0xc76b965c1c06dbccL, + 0x89ea2cceb1492616L,0xaefc8746b460c4bdL,0x679e6edb994d1756L }, + { 0x4ff93a4a271f3218L,0xae496faf3b970a74L,0x062df3a7ba6c44f2L, + 0x1ede93021990ede1L,0xa797899af9a1e2adL,0x9b1bcf6d82599120L } }, + /* 19 << 161 */ + { { 0x63a38a51bd04f6ffL,0x2ddc958bffafb91aL,0x198895cdb19b2b08L, + 0x1bb494246f65b797L,0xf75df140f157b79eL,0xa188dc873d599990L }, + { 0x8b926eecaeac83c2L,0x55fe56f03b82900fL,0x10eb6dd33b11d061L, + 0x8b44c14c3aec5877L,0x294b83e8b486e651L,0x469e552f79524b3fL } }, + /* 20 << 161 */ + { { 0x69386f451a746ed1L,0x4319649bcc14bac3L,0x006292b3b647cefcL, + 0xc771b7cda20e2a37L,0x838714d2396bf329L,0xf263e66759c0823dL }, + { 0x7ee258f0725e3ecbL,0x37638f9934218254L,0x4d57db246fc6d0f6L, + 0x8c85ad7322c2dd47L,0x2300a9129c59cf13L,0x63971b0bee08c1bcL } }, + /* 21 << 161 */ + { { 0x180032d98c2e7698L,0x07d4d364a851f2faL,0x0070bbdeb50b5986L, + 0xba05ee28274eee7dL,0x28843675b0f482e5L,0xdcc9c09ff82b2229L }, + { 0xae0273e7f061df73L,0xa3856b6644e3a740L,0x4b13b141527b80ceL, + 0xfd83b7f0e1b7dabdL,0xa3b5a2f1536c04c3L,0xfd09c77bb29e2bf3L } }, + /* 22 << 161 */ + { { 0x05fe64c5436e7c2dL,0x5b9f0b83ebb1ee26L,0x13dcbfed2977d6f5L, + 0xbd16c6b7db552375L,0xaaeacc2342da342dL,0xe427d2ee0cfec89dL }, + { 0x3097ac7b038b280cL,0xa2b79d623aab3c43L,0x9771fff4a40f585aL, + 0xf50974e0b15aa16cL,0x114e51137a847284L,0x574ba8efb4fbe083L } }, + /* 23 << 161 */ + { { 0x3c8dfa3b05e37e4aL,0xeaf691b47408352aL,0x2e1ce9863c9a8610L, + 0x8d024a814acfb35fL,0x3766aa2184ba6baaL,0xc336f82eb91f5a27L }, + { 0xe2d46985412ab7b4L,0x397f0411ded6de53L,0x067241c3544768fdL, + 0x9206d3839b71e023L,0x8571fe1e3f51c3c9L,0x0abdb52e3ba345abL } }, + /* 24 << 161 */ + { { 0x85e1e4abd5281f9bL,0xc7e517ddc653b0c8L,0xc0b84da1a717e034L, + 0xf1a63b280f1bf3dfL,0x47b74201aba6fd41L,0x9cf3da633518fcabL }, + { 0xe12511fb23bb6e77L,0x13b2cb4438679d79L,0x20e0fb10db5665c0L, + 0xb5448a33b99f4d5aL,0xcb1847ad46b7dbceL,0x41f156b8fdcadb87L } }, + /* 25 << 161 */ + { { 0xd09b746793c8b2a8L,0x36c760204357f251L,0xa965d1771ac04cf1L, + 0xca49d59427740f18L,0xbba973ed76c53b33L,0x7f8c2d264c17d867L }, + { 0x389afbbb00966b80L,0x92f2097a55988387L,0x316a85393a47c746L, + 0x259ae094ac3a3a30L,0x337f1d3f0d61ee3cL,0x02d5a60ca9d928ebL } }, + /* 26 << 161 */ + { { 0xd9f370e42af77d78L,0xf9cb8d588bfa692fL,0xdc8a4c24fc9203d5L, + 0x499b6fda3b8138f4L,0x051a61f19118d3b8L,0x89207fa2cb251fb6L }, + { 0x32247676bbb0e12dL,0xaa1c59822900bce2L,0xe7beff9c7df4f6c1L, + 0x595fd551757c1449L,0x2fe91299650e8961L,0x2db30033f480bf30L } }, + /* 27 << 161 */ + { { 0xe796c05d110c4d7fL,0x12f87395d4af6817L,0x849cd9e6b5512cb8L, + 0x23b8d0a4adb71290L,0x28cc808bee64339fL,0x3072d46fcc27fd1cL }, + { 0x8d9183af47f675d2L,0x9959aa9102c84561L,0xdff7591708216e03L, + 0x868c237abd01b2f0L,0x4c00c229a53e639fL,0x2c0667fb07d69862L } }, + /* 28 << 161 */ + { { 0xb4d2324f9470e571L,0x3af515979ca353e5L,0x479a3a796ae5778bL, + 0x387958a7fb1d9c91L,0x4e606558cf91edc6L,0x428384ca495a3b00L }, + { 0xa49f67da10f7146fL,0xbda553e08e25f80fL,0x21b034c4cb919bc6L, + 0x1fb454bfa7930462L,0x1fb2ac9b255d7fd8L,0x491cceff8b197e6aL } }, + /* 29 << 161 */ + { { 0x0a0e0cd91f5a179fL,0x699d872713841e78L,0xfa93f774fc47f9cfL, + 0x8fd0019c02933131L,0x128efed95aa46834L,0xe20226fdf080cb8dL }, + { 0xf7b05fc3000445dcL,0xcc818da1f52f5ddbL,0x0fa803d07299267aL, + 0x99cf0ab4f9f172a0L,0xb5dd3c36b08d03a3L,0xfafa550ea1c2f73dL } }, + /* 30 << 161 */ + { { 0xdda52c89d2da4e36L,0x0348948d5c333386L,0xe3a5be8b37917590L, + 0x42488ae238e4aaacL,0xa6ecb5be7a44eb6aL,0x3bfd640ea9b27b56L }, + { 0x23b8d107bd05946aL,0x01018c45bb8034bdL,0x1ffc958cd2e058fbL, + 0xeadc93953fd43516L,0x0659b83ea0491dbcL,0xc36115008cdee521L } }, + /* 31 << 161 */ + { { 0xc0f3761c034b0a6eL,0x2c4ce5481fb66b85L,0x7a5d3143410698abL, + 0x4bc07a795d59e8c5L,0x176a10eb4d19ba85L,0xa8a68c5526dae045L }, + { 0x7eed57fb21625985L,0x33ef04ae16c62e63L,0x78d0acd4562454bcL, + 0x5878d7f2a44a1608L,0xa51a423a0cf11971L,0x1934e3f2f21fd6ecL } }, + /* 32 << 161 */ + { { 0x3f2b5bd4b4805410L,0x201ca7a9f96c5ee7L,0x532ef2db94256fe1L, + 0xacbfc459318ddb03L,0x2375f9fd5f24c8e1L,0xd27c479b370783dbL }, + { 0x1bd461e856541ae6L,0x78f054a77f7ea49aL,0xc9f8777d8845f315L, + 0x81aed29697fc92c7L,0x9f2f8d7949929540L,0x7531e78bff5ebfe0L } }, + /* 33 << 161 */ + { { 0xd4710d5a16ba6a11L,0xb172d8a0e056d27aL,0x01879d2b8301e5c0L, + 0x100c3e706f6a3396L,0x4a33d4a4e4e1cab1L,0x48016f0f08017d74L }, + { 0xbde9e0f18cec4fb8L,0xd8604899eb15c26dL,0x17ac5d884a21f615L, + 0xb8f1e7060cb0cddfL,0x0ead85644a0d51c2L,0x7bff69bdfd6bafa5L } }, + /* 34 << 161 */ + { { 0x028acd1cb6b73820L,0xc931f4bc815047a8L,0x22c6159f1ede2c60L, + 0x571dd40c99a4820fL,0xbaf08be0b450f472L,0x6475536aeb5bb639L }, + { 0x033568e4d984d0c7L,0x2ab7dd4885e910d4L,0xb0d76698d0c632ebL, + 0x954d00f3e3c34a46L,0x53e8772de651bc5eL,0x4910b07b6e3564f6L } }, + /* 35 << 161 */ + { { 0xe1550b37e758fcf6L,0xfea2446f763120abL,0x5db50b38124f80e6L, + 0x5cc28a7830c3301aL,0xa935846fd950d5b9L,0xae3e87f2ce43ebe3L }, + { 0xf033b25b7d0776a5L,0x941d186e882c5916L,0x0430c4503d6d4f7dL, + 0x4e0641c0726f30ccL,0xdfcdbd1626c66c27L,0x43c4590ceb00e495L } }, + /* 36 << 161 */ + { { 0xd8cbdd8b70435ca2L,0xede7fb3675af3a63L,0x6c1fa971090b36bcL, + 0xdd2292eb85455ed2L,0xf9c3889c7fbe5041L,0x2ec87c15506d605fL }, + { 0x2691b0a28b099c25L,0x27961c8b89944e21L,0x8e9e18a5147f5304L, + 0x6a82e35baf7dce25L,0x6745339c32a4bbc4L,0xe0bf0e0ee026676aL } }, + /* 37 << 161 */ + { { 0x3c6fd1ab352a43fbL,0xe57e7f8cbd68dbffL,0xa4a5b74e9ea30f41L, + 0xacea695d2d5a3a34L,0x183be19adc8fe4d3L,0x22fce6281b9f9d1cL }, + { 0x8b1ae75da5d35bc9L,0x213face52c673f82L,0xa879851d6568d549L, + 0x327c59937f8d8112L,0x56b982e2a7869b71L,0xc77afa6110bb8086L } }, + /* 38 << 161 */ + { { 0x1dcd57541ccadbe8L,0xd2d8c36512b37773L,0xc1a7a5b7d50e8680L, + 0xab1a00b3e19d155eL,0x58f4bcce7a9776b8L,0x1c02df3320d9d7aaL }, + { 0x24f00d31db8cea6fL,0x2680b029d4aa0785L,0xf3db2889c48587f5L, + 0x1811dd2521a7fabaL,0x5836964bbf820746L,0x3b118bab97aca83eL } }, + /* 39 << 161 */ + { { 0x14babe6321d76845L,0xf7b4c662c60f5934L,0xbf212c4434de5b23L, + 0x57c478a35bdf0a35L,0xddecc21535dc8714L,0x1609b7401571e91aL }, + { 0x41998697ba45b40aL,0x6ef382d468cf383aL,0x77a24c1488c0ec9cL, + 0x0a5e245297b377a4L,0x2b9d72bf18f9804bL,0xa4c21326f51ddaacL } }, + /* 40 << 161 */ + { { 0x397049f4c785c7baL,0xa87db27da1decf9dL,0xce6d5ec1e7862c0cL, + 0x17a98db834350bf1L,0x6ceccd8030ec8d74L,0x4790cc07bcab4aa8L }, + { 0x4378b1feb4f771a8L,0x3c54588b404dfcbbL,0xbddf0faa8d60f86dL, + 0x987583da3573271aL,0xb0afe4ec4b8f8032L,0xb5c44605b69d03f6L } }, + /* 41 << 161 */ + { { 0x7f69e8bfed7d4230L,0xfe54dca7d8ee8cbeL,0x6ec2b75f71b72d99L, + 0x97e2b30f8dd8338fL,0x9916dcdbbc75bf05L,0x22f4291aad5c114cL }, + { 0xb6af2e86f9ba5c98L,0xdd7d738dfd6fc5d8L,0xce7af7d544649034L, + 0x2979be5cd163b098L,0x5acd51858db8d84cL,0x82b0e4a5ca64d1c0L } }, + /* 42 << 161 */ + { { 0xf27f5f4f480ef46dL,0x2f49f44fcba811f7L,0xef40508d43961b6cL, + 0x0f6778e8df9fb37fL,0x97aff7e8446864b5L,0x29aeb86d4d264e1eL }, + { 0x48baa1984901daacL,0x91ade9db02b483cdL,0x00952a61cdb6abc4L, + 0xa1a51250de7f22c9L,0xe6adfaacc19ec8d5L,0xa7d2f066fc39838dL } }, + /* 43 << 161 */ + { { 0xfbe20a8e270bcf2fL,0x9882e7a0c35c60f9L,0x74d8e63f560e716aL, + 0xdc689649bae281e2L,0xd454571036d9b680L,0x0a0f1c681740ca0bL }, + { 0x228dd692dadf3782L,0x6ab0bede632d6e56L,0xae2f5535e1b7add3L, + 0x2ce1c6fece308fa6L,0x7a11b255db881355L,0x903007107bee5bb7L } }, + /* 44 << 161 */ + { { 0xdd55c21a9f1a57d6L,0xc9e1dcf9f6043ee3L,0x0385e3f36747e2baL, + 0x6511555a932e55b5L,0x7f4053b3700e73f6L,0x23adf65d992916a2L }, + { 0x4664bf231bfc40a3L,0x8400e8f27974d63fL,0xb70f104dcff08198L, + 0x4c44382f4d1710afL,0x5593a751374ec807L,0x6af17e84462c6112L } }, + /* 45 << 161 */ + { { 0xc1ad3eb7b8f1f38dL,0x74bb37c88d462e67L,0xd127b6e6246b0388L, + 0x3054aaf0824defffL,0x4e981d2e487809aeL,0xba76b7b805ead528L }, + { 0x0a167834a7a32c6dL,0x3451ee930268c370L,0xab4da0971b625d09L, + 0xdb94f9aa304e60b4L,0xf3bea685ab50c663L,0x8d929a0142d4c11eL } }, + /* 46 << 161 */ + { { 0xfce03e6eaa911497L,0x32cba5cf546ab5ecL,0x631123d0b1a71e10L, + 0x49f3a80906bcdeafL,0x783373bcfc538ca5L,0x3590890ee4b47edaL }, + { 0xb5c84fff39ab2df0L,0xf681be9ac737b24fL,0xf37bbc68b2b0052cL, + 0xd9f03cf6fde04d93L,0x23171bc2e43803e3L,0xeda51460040de801L } }, + /* 47 << 161 */ + { { 0x0e09a74d0bccf0d7L,0xfb429a675b58037aL,0x1f2660d2200b89ccL, + 0x489b332e04efc617L,0xb53d4f65f38ceeb4L,0xeaaf759546c4aa4aL }, + { 0xc6cff1fa714b9f97L,0x6a647072ec0dd5b7L,0xcbf59eb1637384bcL, + 0x043003cd2240993cL,0x134cab640497f9afL,0xcdb44a4ca9fcc655L } }, + /* 48 << 161 */ + { { 0xbd9a66d6543b3e41L,0x2948c0a62ae73774L,0xa75151dfef38e9b3L, + 0xa3348ae5754fb3fbL,0x1218fa8f13069b72L,0x532bb0510835dfafL }, + { 0x2121a98edf2be3c6L,0x85980de69e5199bcL,0x1b23a4be1a1eb6eeL, + 0xb5c48b92adeb3ae5L,0xeebd305dedea2b45L,0x20543f04c37198eaL } }, + /* 49 << 161 */ + { { 0x9eb2d599fa727a5dL,0x27cce415105643ccL,0x2face9e8c06035deL, + 0x967f70e4c5d916cfL,0x477224ece7cdc451L,0x70a3de4ea9a34198L }, + { 0x84ebd23a62628f21L,0x517cbb6097f55e75L,0xa4dc8d8ccbfaa795L, + 0x821d53c1a9c17b12L,0x04e94aea5124d5a4L,0xc72432c083efbc58L } }, + /* 50 << 161 */ + { { 0xb7a2090999f73a42L,0x019bf3a630db0901L,0xcf0c2a7281cfde4fL, + 0xf656a2117b0b04f8L,0x88cedc1896043e90L,0x4482c3786ae4c551L }, + { 0x169f25d3dc70c774L,0x0f8cc86cb552fbe4L,0x17d0556b88d2f3eeL, + 0xf5af9d6ff864ba64L,0xcd509d82f93dbf7fL,0xf00c76f51b98df35L } }, + /* 51 << 161 */ + { { 0x19fbeb37856e35a3L,0x1788055c88f36390L,0x9da657f165361c9fL, + 0xc9f327b7e35a36b1L,0xdc388bcb04b9174fL,0xa79bf7d3349a87c8L }, + { 0x865958b202289b24L,0x4096845ecebc4686L,0x1127085b42ce096dL, + 0x56f31d12735241bfL,0xe2239ab543b89a15L,0x477cc5b3a6a1f0f2L } }, + /* 52 << 161 */ + { { 0xc44c81525d54607fL,0xe742a6f35c9ab491L,0x50df96d9be8c2ed5L, + 0x3aa8c9b4e7f5cc4fL,0x577d534c3f12e8b5L,0x03f9573da33a57b1L }, + { 0x9172e1aec5c0c895L,0x64fa9822a2e19442L,0x17db2388178a10d5L, + 0xe75a6bdc2755ed55L,0x6a6d9dc3f9188333L,0xdd93a3b83eda0c41L } }, + /* 53 << 161 */ + { { 0x353d1f4bad0d960fL,0x6fbf4355846e07dcL,0x2156ae3c3a1bb429L, + 0xfa95a260442e6e21L,0x659a856ac2b31d7dL,0x9b56cd6563ecb2d0L }, + { 0xac9ec96823a787b7L,0x4102d82e320742deL,0x470ee0ea50a422a2L, + 0xd3ca8414af386491L,0x28d8994b1a0d8192L,0xe601e4e2b3f117dfL } }, + /* 54 << 161 */ + { { 0x906c071c4e9ab844L,0xeb1a5806f085a058L,0x2f14c3ac176e2f59L, + 0xfc1a3020bd19f909L,0x5e67d789ac060e45L,0x75dd23a7b707084eL }, + { 0xb9dec51a07e89974L,0x50c9cd0b38f97f3dL,0x368b0f53e14cd6fcL, + 0xea4c7f8b81ab93b2L,0x774ca31d1b7aeb66L,0x94c14607288f51a9L } }, + /* 55 << 161 */ + { { 0x18c41b62fe32b90aL,0x2e11c7e6be96e1aaL,0x72832e8c428b9d81L, + 0x93f63cc0058ca451L,0x603f18af7cc827f1L,0x31c8b8fee038eb26L }, + { 0x21158b24411cb335L,0x48dbbed70d9e953dL,0x445e244e4d62615cL, + 0x2f5309ac28ef4922L,0x12ee44c60d4dc305L,0x7dc0363f56f7677aL } }, + /* 56 << 161 */ + { { 0xf73471b5ef349ec5L,0x014dae75565aa6c7L,0x57cb497dae082cefL, + 0xdfcbf2b5c3e563bcL,0x22149c0fd1125f95L,0x529f419b425bc019L }, + { 0x049476deaee2094cL,0x3490c0490cbbb583L,0x56c5c62d1256424fL, + 0x0a118ee541bc66faL,0x0d8e9ff8296ada14L,0x34356e8b0134f8c5L } }, + /* 57 << 161 */ + { { 0x5e41ebd6eb28f97cL,0xe054a055d6a393f8L,0xc0a19e38db6555e3L, + 0x1b40c80fbabf4f9bL,0xfca17ae2780d5107L,0x89ae096f379701feL }, + { 0xd79be295b53ebb0cL,0x3112d3a5942b2247L,0x6c1f44d30de10f30L, + 0x2a17fffb0041f800L,0x13082de044552d55L,0x319aa9c0cd11c85aL } }, + /* 58 << 161 */ + { { 0x63ea1a6ae760373bL,0x00f2addd11742d8cL,0x46b17c9cafdd38eaL, + 0xf4121c5a4c7e78d7L,0xbeb70ef90048e4f0L,0x0b60c2b6bf7f7348L }, + { 0x4bbadf7632969689L,0xcb6a8a20e12708e4L,0xc43ad55b5638eb7aL, + 0x4a72b02b3d27bf7aL,0xecc95d92e5a54c30L,0xae52514bacc45d53L } }, + /* 59 << 161 */ + { { 0xbf5a2b5132d1f651L,0x6a2a74116e438838L,0xfa6353dd6c067d61L, + 0xf6918622b96ba12fL,0xf0fa254d45f595f3L,0xa0f0cb4b92f680a0L }, + { 0xf13ba734463e3f27L,0x7e3d4eb1a32d7f9aL,0x348baaf26f6502dfL, + 0x8021a9977b830e5eL,0x503f38ca55caf601L,0x27dde9e8f4bb74b6L } }, + /* 60 << 161 */ + { { 0xfd5a49310eb63b3cL,0xdb9f1a1510175713L,0x044d42c23e11c321L, + 0x5561f2e9b7961e8fL,0x70b3f7557ec7c597L,0x5dd9671235aed561L }, + { 0xc6cdc78ee1bcc2b1L,0xebcf6f87f1117aa5L,0xef470e0ae3669f78L, + 0x87b13e0fd38e0fe8L,0x01bff01439c755c7L,0xa66f2521c37529f8L } }, + /* 61 << 161 */ + { { 0xac56a8b223f78e49L,0x908c4be58708f0b5L,0xa63aa4191536f6b0L, + 0x8c08578fe5a95771L,0x5d2d1d6b9c2ae8daL,0xf3e4ef12f1527cc4L }, + { 0x46c1ac13920a90bcL,0xc0bc661d28ba758fL,0x9114e016585ef450L, + 0x8ab6a1f6e899a032L,0x57d4089606b658baL,0x2ef87621eb83235fL } }, + /* 62 << 161 */ + { { 0x033a4d4c4ebdc925L,0xff239a3efe1b346cL,0xd7ab2fb388d03949L, + 0x56ce2e41bd6e8e4dL,0x3826aff0e55da68dL,0xc9c7ba7451267f98L }, + { 0x5264a48ae6710c7cL,0x3635f1d4e7605975L,0x53a1849a94be903cL, + 0xe4fc3617128d5859L,0x7686804d7e4dd785L,0x6f04942d2dbcfe4fL } }, + /* 63 << 161 */ + { { 0xe80b7f5562927d6eL,0x92b98c350c0cc89fL,0x9522896d15117facL, + 0x7a224db5fdd3ffcdL,0x9502ecd8fbfc8908L,0x4e1dc71ac593105eL }, + { 0x052aade62f0536dfL,0x0c7cc371f324268aL,0xe7c62f2ccd843bb4L, + 0x77d48fa36df2c231L,0xb2c29803cb8f68c4L,0xad7ccf519bb9fddeL } }, + /* 64 << 161 */ + { { 0xd0960bd80fab968cL,0x6899e4faae028db0L,0x975ccc77a9850916L, + 0xb41bd531e5f81554L,0xbdf8ab57c8cff2c8L,0xea306a01f5822be3L }, + { 0x1f0ac0e7befbdbbeL,0x72f4b0e960519f87L,0x22bd8b82e3cc86abL, + 0xc43bde8d2b2beaeeL,0x8168781e412617ffL,0xc5610627b7ee7096L } }, + /* 0 << 168 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 168 */ + { { 0x0869457a01a8eb44L,0x522239857a7bedd7L,0x2c04b0c600057505L, + 0x468be6e80b09adebL,0x2f3bf32b6f81474fL,0xf54f949da712ccceL }, + { 0x292cee424cdd8f2aL,0x3d9fdf6b9c221be1L,0xe54da66156f47b2aL, + 0x2ca76835840b5d1bL,0xb52adb6a8a6e8cf6L,0x8b416a6bdade153eL } }, + /* 2 << 168 */ + { { 0x65f7d2c18565afc9L,0x764c897170fa7b82L,0xe268634c986436f2L, + 0x6334d8d133356165L,0xf17164269ec7957dL,0xae834331b8093983L }, + { 0xedb1fe5cd2dfcce7L,0x6195b86368463e5cL,0x746e5f4da691b665L, + 0x61171291e1e2727eL,0xbb4aa8f16f27b029L,0x1037657d7f42c197L } }, + /* 3 << 168 */ + { { 0x2af8bdfa970f96adL,0x19d09a6dd0c86e6dL,0xd57fd5ced7046d2eL, + 0x5ea025f7d545fd33L,0xe2ccb6f43161ffd7L,0x3ca5286209406242L }, + { 0xf3536d60b5c90905L,0xd086e3b9d5b290f6L,0xfd15b06a5cc55444L, + 0x61b0febf9a9e2a66L,0xdc3c0576653dfd02L,0x357774230a8ab51fL } }, + /* 4 << 168 */ + { { 0xfe19901b0d5b855aL,0x5facb9552f745022L,0x92fd012556c4ce5cL, + 0x23172d65938c89abL,0xa71f8a33aaa587b1L,0x511a3745b55c9c50L }, + { 0xec005f6a7185086eL,0x6dfc2761f894c6abL,0x98a4d67f9e26361fL, + 0x7f0a2b2321389c25L,0xd158820795ffbceeL,0x4d6b29ab9f36a888L } }, + /* 5 << 168 */ + { { 0x5ffec1d78c04bc6eL,0x35f052d16ca0dde2L,0xfbe3844c649c850bL, + 0x450263e610fa337dL,0x44f7c8f40280773dL,0x27de5d3ce896966cL }, + { 0x2587f47598d0378dL,0xbd49c97f4e4f6e49L,0x9e902f667071543aL, + 0x03398aae06577b74L,0x030926d6910bee13L,0x5576575bffa92cecL } }, + /* 6 << 168 */ + { { 0xe4ee33460562cd7eL,0xd1d385a3f01ba45eL,0xd817ca667ce11848L, + 0xda222cddcb69c7eaL,0x74ac74709d680afeL,0x3770357cd9596ca8L }, + { 0xdff57da7f7759bd6L,0x090426be20d5c726L,0x71c0ba28b7fbc1b0L, + 0x60faab1c13d4ed0fL,0x6fbe3567ea3a2ef2L,0x0dd3835c4e577dffL } }, + /* 7 << 168 */ + { { 0x9b758b512ce27e38L,0xe4148475a39855e3L,0x4669b3c39ee88a77L, + 0x3f36a671105e1ec0L,0xd0f30e5d9e88ea13L,0x6346df15baecbaadL }, + { 0xec65be65cf4c6510L,0x843efca194e1989fL,0xf7195d29942ce52bL, + 0x12201877d3ce28d4L,0x9c962aa1a97fc904L,0xc4fedb3465c5a55eL } }, + /* 8 << 168 */ + { { 0xeccb421ed0a701a5L,0xad4cb9a5b60cd286L,0xd344da9e05a53972L, + 0x3a8035e07bc99feaL,0xe0214485c0f77bf5L,0x50ada30ee54df78aL }, + { 0xdef45af64ec2d576L,0xa05d61845f9a8678L,0xa9b17db1c337e017L, + 0x026a4f66b84671d5L,0x606142343b7d696dL,0x71ed9aaf81cfd22aL } }, + /* 9 << 168 */ + { { 0x62805305695a3f30L,0x6ce27626e28e8fe0L,0x507386af6a54f410L, + 0xf8c5f738cd5c7effL,0x3ab2db9e347e85d7L,0xf5b635b0b2161b68L }, + { 0x99009791be2e80caL,0x6dff3030c13910ddL,0x2beeca057ee8700aL, + 0x12616fb11ac7e09dL,0x38c9ef9f9037c2e4L,0x39181fbf9c140344L } }, + /* 10 << 168 */ + { { 0xcdd6aee47aa54433L,0xf5ecb432b80336f5L,0x690bb949a1380829L, + 0x219d659ca9c9d720L,0x74abf2dd7e5a3260L,0x405ee136025c55d1L }, + { 0xc5c592cb1cc878a8L,0x119a38be88b31ecfL,0x4fb00f82e94e39e7L, + 0x66bf72e59412c068L,0x9337c8f30821142aL,0x477216340c24ab67L } }, + /* 11 << 168 */ + { { 0xa6c7953457fe953eL,0xd70d3d2f3c76ae58L,0xe1e047b52c531c84L, + 0xc71f3a9973735602L,0xd70bdb0f7ba0628eL,0x280fdd4e0e3e3c0cL }, + { 0xb5a3f5823e414e26L,0x55b2eda8f44dee7eL,0x8e1d024b2f5dd828L, + 0x21f054eb3b1bfdf9L,0x3d3ae74cc554e1cfL,0xa0a5863ffc42ec16L } }, + /* 12 << 168 */ + { { 0x1b76a3c5439ada39L,0x818829cf89236ae5L,0x2277cb7a750f8129L, + 0x44aa462a4d46502bL,0x7a12e1e164f06dc8L,0xb9a3300dba5630cfL }, + { 0xd2cc8d9c55b05f4bL,0x6d0b0b88a700be7aL,0xa7be99699617500cL, + 0x2b5b8deac03f8a50L,0x712f703e785b3dfdL,0x96a5a60accf93950L } }, + /* 13 << 168 */ + { { 0x9838155fbf9f72c6L,0x3ab3cb602c10e57dL,0x7ac228ef14bcd75eL, + 0x2c167e15027923fcL,0x678869d1267471c7L,0xeba35e857ec3582cL }, + { 0x22d290a9a3478eb3L,0x542092ca1309aa14L,0x8bb5c69be2e5d3acL, + 0xf83c5a0a81652736L,0x9cc576227280cd6dL,0x6653436f3b0f49a1L } }, + /* 14 << 168 */ + { { 0x7ad1f1bab497d900L,0x9d0512236c9dd5d7L,0x0ed27e5bffed3df8L, + 0x659028a775d2fa72L,0x69bd68154581f377L,0x142c2088e2faf671L }, + { 0xf9c1b8a499b000ffL,0xf31d01b18f408d3aL,0xa7aa142f42b9d35bL, + 0xeb8aa74ba0495da2L,0x824cc32a59a1da45L,0x3f1fbe0ff5173374L } }, + /* 15 << 168 */ + { { 0xec9071a634238c30L,0x6dd6c38b88a0f423L,0x3adace72992e7977L, + 0xc90b941b1ae5166eL,0x052aa3e9e3e43a68L,0xe9b1976da733a950L }, + { 0x0e1ca28e5ff6c9dbL,0xd1bd4350387409a2L,0x5943cc7089155117L, + 0x8e85794f5feae20cL,0x0d118fd669768ccbL,0xc647179d53120895L } }, + /* 16 << 168 */ + { { 0xfeb984b3ee828fbaL,0x8273f830e2bd188cL,0x177ef97e3ca0a99fL, + 0x76d4796dacc000acL,0xbad0fa6eb140f51aL,0xb275656706ebc810L }, + { 0xf89eb78fa18cb32fL,0xcfc37eaea65285b0L,0xe2b29cfbb25e9d1bL, + 0x9388ea8fb4e7aef3L,0xee606c12e267e845L,0x6b103c549f5806d7L } }, + /* 17 << 168 */ + { { 0xb9a40e78e31fd643L,0x648cc34a97950a34L,0x85c5ca405900be55L, + 0x2e519cf12abb843bL,0x6f9d0a7f27436edcL,0x2f569c9d6694f363L }, + { 0xf6d1b325f6f1bd24L,0x01103c0d4044b353L,0x2d3ce56f3138b549L, + 0x5379bcf71c28bc5bL,0x6768220d08ac00d1L,0x973f92ff0152746cL } }, + /* 18 << 168 */ + { { 0x5e992944b37b0486L,0x0a334b92001fa124L,0x6653cded9c9ab466L, + 0xd512612fabac4da9L,0x636bf431c502b860L,0xfca1c0c2c3d20db2L }, + { 0x7073f293f85c40c3L,0xfaabc77acfba9eddL,0x58842eb97f9b570dL, + 0xe8cd4f53702aec24L,0x8975f4e6e08113a1L,0xcc0d7f17767bedd6L } }, + /* 19 << 168 */ + { { 0x5163bb51ae315a65L,0xf82ec4cdbe405348L,0xffd381a46b1801a4L, + 0x33f9b8ad2f6ba570L,0xd88c58a58ecc0000L,0xc0b9a639cfdad25eL }, + { 0xc78cb70fe3bd808aL,0xf54b86e573ce5eadL,0x111208ed5610a761L, + 0xba3579b0e3c8e27aL,0xbadd918c63b85bb7L,0x9e10da0b71bcd972L } }, + /* 20 << 168 */ + { { 0xf418e3f63766f2aeL,0x4a3ad3c8053ef1c1L,0xd01e5b5b560db262L, + 0xa583edc7c02bf4c3L,0x7c9f706052f318d3L,0x0852556f1f5e1ffeL }, + { 0xe1c70aa7feb0e63cL,0x59f0a3f989a8c058L,0x4aa4cf021ffc0adeL, + 0xbb880e4138a78632L,0x35b0f7596f28f096L,0xf9c4fe17d5757d7dL } }, + /* 21 << 168 */ + { { 0x160303ded896adf7L,0x19a46b6c6beb8930L,0x33dfd962f010f74bL, + 0x03b699cc00e5610fL,0x17487b7595078dfeL,0x63bc614253f3479cL }, + { 0x43f3d994858d5b8bL,0x383349349483c0ffL,0x47c917a67977142bL, + 0xdc50fb80df7eead4L,0x4e3a1d3fb5b82be1L,0x091af8796d7317b7L } }, + /* 22 << 168 */ + { { 0x783e5066af151a9aL,0xec0a9c175466df17L,0xdecd12310174b0adL, + 0x654af66a3b2aaa45L,0x849d64e5b1fcdd11L,0x7e8e2ae6d05af56cL }, + { 0x12e887b7318a6184L,0x42d1445554ed59d8L,0x2eafeb48ee54ddc5L, + 0xd1f9e6b980c94a8eL,0x5ea691e3263696c0L,0x7f42f3796e03eed3L } }, + /* 23 << 168 */ + { { 0xeeb8accfd69b82b9L,0xb4c4988ae0b61d73L,0xb78becf19df9b59eL, + 0x13274f6236440c93L,0x33d287f5697d5a77L,0x391fe6129af4053eL }, + { 0x986c42b21c16e858L,0x23f5d1dffe04125aL,0x2f57ccb3af9541ffL, + 0xe5b4eec70f1a8bafL,0xaad23ce7646c1b6fL,0x69495ee5a6ff96abL } }, + /* 24 << 168 */ + { { 0x78b8879cfd6376ebL,0x22a76461c01e1edbL,0x6a44be39369cf0c4L, + 0x6653670d5ae54539L,0x257bd7516fb43ad0L,0xb3ac371512baffddL }, + { 0x48659d617548eabbL,0xd8f931f80cd468cbL,0x98f0241549e3b531L, + 0x90b0d71670df011fL,0x26d73c54ab98f066L,0x06591ec988475d5eL } }, + /* 25 << 168 */ + { { 0x6fa72e3518f18e71L,0x6c04fe2d8123ff14L,0xc48cb53a197481a9L, + 0xf059db349860e48cL,0x35e8341ace46ca7dL,0x880f4ea4b0400f7dL }, + { 0xb4c5ea9acc9cc40aL,0x6522c768e2555fa3L,0x95207f39ea2c32e6L, + 0x7b6fc09fa8be60e1L,0x772b829f29902652L,0xb7936b90af6a48dcL } }, + /* 26 << 168 */ + { { 0x409e3b1109758457L,0x59dd0a8c1dea73d9L,0x528906a58fb18a01L, + 0x6fa55967a17ffb33L,0x9523cc3d50edbcb2L,0x35600b3e44d43541L }, + { 0xc3a7d22c8f87dbc0L,0x5514c967c1b225abL,0x78e5701988304a74L, + 0xe9b417ba35f3b54dL,0xb72a243c48eea230L,0x4e173eaf291ee52dL } }, + /* 27 << 168 */ + { { 0x79b854ca2127c795L,0xd9457d8f86657844L,0xf8c9e6ef186668e8L, + 0x84c8855df913c2f6L,0xf207d36ad641cc12L,0x7be9b5736105ce0aL }, + { 0xe72cce1974ec078dL,0xc4f47413d09950c3L,0x640bf6eb3974554eL, + 0xf880dcfb844497baL,0x3744626999bbcfacL,0xcf1712f4316f4d64L } }, + /* 28 << 168 */ + { { 0x627f6328412b84c3L,0xd427e977a04545d2L,0x5b0145bc104f25c2L, + 0xa6931c4f2ac7ad62L,0x407611431f8d42f5L,0xfda5a76be7f8a0b3L }, + { 0x4f1ca5cffe0946b9L,0x6def7b9fbeb2d427L,0x984bd4bbc9a0d136L, + 0xb9a778235b3af1c1L,0x04ee66ae38ac2087L,0x63374ed926d9dbb9L } }, + /* 29 << 168 */ + { { 0x68088e9c3983deb9L,0x2c95ecaa2ed99988L,0x371af002917f200dL, + 0xff33aa5dbb4ff0dcL,0x1dd5fcf2e47bbd6eL,0x1624b973e75f73ecL }, + { 0xf6ce0e9db9722af3L,0x8bde5b8818226fcbL,0x243753fc5b5da478L, + 0x3b53e0e3bdf88daeL,0x59f8c86f325cedb2L,0xabd4076d70fb9681L } }, + /* 30 << 168 */ + { { 0x1996761db8759af1L,0xfb85cdd8e4a705f5L,0x2ea7aa0b35111725L, + 0x23245d4157a17f4bL,0xcbdb650e0d00eb9dL,0xb40823d9e23a4a3cL }, + { 0x041bfb67229163f8L,0x020ad3c16d47b83dL,0x3bc8975d344c8ebfL, + 0x287efd06d91ff408L,0x1ca5d75a2059106bL,0x4ff27af3b90c5d66L } }, + /* 31 << 168 */ + { { 0x416b7c61ded914e8L,0x1aeee7d007ad4237L,0x59d5852476c2b7a4L, + 0x427a102c98665f29L,0x8504aa8d2a1aefe4L,0xef2dbeadc183a736L }, + { 0x5cb5f222f533358cL,0xf2ebb47d36b0d678L,0x1de4a0e7f2c2cf99L, + 0x62613994ea95a161L,0x68a86f4012d66ed4L,0xeb12fe75b2af52f3L } }, + /* 32 << 168 */ + { { 0xcf947c0644ba39e6L,0xf5d5216cedfe78d7L,0xd00115c05f1835c9L, + 0xdf084152d8c79d90L,0xc0c3a6846db5f791L,0x40514451749b18cdL }, + { 0xd314b7d5734df3f1L,0xbccdd3f07f541415L,0x97ed5af06855a942L, + 0xea84ae9ee9d02ab9L,0xb87e90343238a5d0L,0xd12d25c3650a0eabL } }, + /* 33 << 168 */ + { { 0xc3747c584f9d2c34L,0x493a0adc95429c92L,0xf9b5916238a679ebL, + 0x04d500a16bac07f7L,0x8938f4f96a809676L,0x44ecbbf0c5b25a4dL }, + { 0x3b68705504768400L,0x6a432e14b4db3907L,0xff82fb56ad375d2bL, + 0x87f59f97944210c2L,0x2b680b2051445242L,0x1e0986466cd75962L } }, + /* 34 << 168 */ + { { 0xdd2eea82672e5a4cL,0xb05ef9ebccc68d94L,0x626ce368a3fa4215L, + 0x6e376f67fe46bd46L,0xaed7a0bc33c4f169L,0x4a92c6093af5c4fdL }, + { 0x6615245fa690fb49L,0x571d2d870d64f04dL,0x6a45df34641ce79bL, + 0x045ddbd02655d316L,0x2b6c574db4fbc42aL,0x41545fbc5b2dbbb8L } }, + /* 35 << 168 */ + { { 0x484996b97d8f1eb7L,0xf72f3a8110bd1585L,0x418e00e7b67eb27fL, + 0x354e56c97877c18fL,0x7f11f5040a8b37f9L,0x66591146ff58764dL }, + { 0x816ac849ed0bfc38L,0x85eaa6350a50a99eL,0x7fa62d9c5bf4995aL, + 0x77840d5003413385L,0xe4f023bde83f9fa1L,0x2c5f8e1d9cfa7578L } }, + /* 36 << 168 */ + { { 0x1473b55b86a515a9L,0xa9e3230a3b337c64L,0x7e8bf9049db668f1L, + 0x1db2c25ef27f9fc9L,0x0c1086072d9e467eL,0x4505579aa3f00d52L }, + { 0xe2ad661b240400a7L,0x8022294c11af4874L,0x29e9037078bba8e8L, + 0xbf0fbf08f6baca04L,0x2e46d2b74101fab0L,0x66065490c61089e6L } }, + /* 37 << 168 */ + { { 0x18b01aa935dde51dL,0xa7496997a7d044b8L,0xcd9c467f44c23d2dL, + 0x96211b86659e4a5bL,0xa2a9000f3e17b717L,0x7af9c312dd90459aL }, + { 0xf0d6c24394547203L,0xa76a23dbd77cc691L,0xe1b7fce10ef364deL, + 0xe08c1d0bb689c810L,0xb75bfacb0a43ca02L,0x1b7afea5408ac99aL } }, + /* 38 << 168 */ + { { 0x3b1abdb85a4a8a23L,0x8f52060c4d68bcf2L,0x7408306a00ab3146L, + 0x652ae3064b86b775L,0x276a14a0b0695b00L,0xcf8af11f1b771254L }, + { 0x3fafcc63b91118b3L,0x6c49000a73bacebcL,0x53852d084e3f3d6eL, + 0x78977e91fdfccca1L,0xe843cbca6ae9ea5eL,0xa99831896bb8271bL } }, + /* 39 << 168 */ + { { 0xf77b0a7387534a6cL,0xfff419f2f5b0c6dfL,0xde3c3b33357205eeL, + 0x867eb3a23c8ec9d6L,0xd28bed3263a99b18L,0xf5fc17e4c1573146L }, + { 0x30cf41e5821641feL,0x84b1970e225ab57fL,0x6bf707325a1e8ba0L, + 0x7bfb3bbce3cf38d6L,0x9f362787a661e876L,0x6d9137c86c0a16fdL } }, + /* 40 << 168 */ + { { 0x2131ce5b09f8a1cbL,0x7b373ed28ab129e2L,0x463cc8d677c1292aL, + 0xa9b7cf6594ffe9c5L,0x129125ceb99bfc4fL,0x819b42849820d323L }, + { 0x3f70976376541a41L,0xfd679ae5e32c7a7bL,0xc39a208df65b6b3cL, + 0x1c22ebc050002745L,0x268f19dde2bcd202L,0xfeac809c9c3d4266L } }, + /* 41 << 168 */ + { { 0xc5ad8903af14f8a1L,0xdfcd207c3993c99cL,0xf65f8260c7c1fd57L, + 0xa1573b3d41be66fdL,0xeeeb9ea476690f79L,0x6a6338437129849dL }, + { 0x22eeb38623a7bfcfL,0x258fc0743393e894L,0x008efb477ce9602aL, + 0x4bf127b699c7b279L,0x150da482fa1bfd7fL,0x7b84744d293754dbL } }, + /* 42 << 168 */ + { { 0x3af9919db2183277L,0x7f5990fb4f6182ccL,0x17603db034f716d2L, + 0x6b79f6538f135ad5L,0xad9189e68092d128L,0xa5f3ab8efc6628c1L }, + { 0xa36b978e84b6d30fL,0xf2a7e1c64c001f26L,0x2acbdfd676e79beeL, + 0x71b5faec86f6d6c6L,0x23d9b7c849b0e5d7L,0x36ea518212fd4cccL } }, + /* 43 << 168 */ + { { 0x14a4af0f59df1cf9L,0x37f8641dfd7cd2b4L,0xfb6aa5d0244434b2L, + 0xb85f8c8b5d5bbd63L,0x833e76baedb92f97L,0xbcd9d7b50d7a2dc2L }, + { 0xb233f07ff0e0f06cL,0x453f10c4fcc06efcL,0xa4e8f306128a167dL, + 0xbd6df4690d0c09cbL,0x2b5db66b7168ecc6L,0x7ec02c77f29bcecfL } }, + /* 44 << 168 */ + { { 0x0746783787dcdbdbL,0x4cce33be320493d8L,0x9ab08cbe713c7746L, + 0xd6f0c1de9c6dc5cbL,0x194005382ac03761L,0x3fc11f38d0547be5L }, + { 0x66b378ce819fe3fdL,0x6a590acc3700fe7eL,0x4c976a728924b396L, + 0xa5006d8d70b9b250L,0x2fdce1b212b85f9cL,0x5858f7ce495f8f1cL } }, + /* 45 << 168 */ + { { 0x3f2b5e295de2948eL,0x84554eaae1a4a962L,0xb4e55f1293db9addL, + 0x9260e3eb61b22484L,0x22a898997b1a6d10L,0x571bcd3af58d1ce3L }, + { 0xd62db0edecc88a76L,0x88352f634af2cf53L,0x8d279316b61c73adL, + 0x7f898e09ec74d6abL,0x39b2b0c05412a81bL,0x623a5ea30644b6a4L } }, + /* 46 << 168 */ + { { 0xe876b53bdb0f6565L,0xd0dc323c4650204bL,0x0e4af31b0201643fL, + 0x486173207e8a0e6cL,0xe09183d457643a1cL,0x3c55bcb5ae8359b1L }, + { 0xa06078cb7b467835L,0x4d3a35d901b6bb3cL,0xd4f1d8233963fd31L, + 0x9c1b06093d4cce05L,0x55e368d5da550340L,0x50c3feee12c4b7b3L } }, + /* 47 << 168 */ + { { 0x6de0fcdaf0f97e84L,0x1f225d818dfbc0ebL,0xe27a42efcd2c51d9L, + 0xeff56879c0cb033cL,0xe700cb87c82e38d4L,0xc89a02d589d244caL }, + { 0x0b464846ad9c718bL,0xf8d5ee1f8de96d61L,0x2cc33c3dfbfd0960L, + 0x3ef549f0e199b6fbL,0x29f83f686c1597b3L,0x54ca37a3731712ffL } }, + /* 48 << 168 */ + { { 0x357540ab903ff177L,0x225280b8276af514L,0x33d273ac14d7fed3L, + 0xfef6b9ffd186ee3dL,0xa94c207101a7b1d9L,0x4ea3627450bc8bc2L }, + { 0xc68959c9fa98a918L,0x8f5ecceec7bdc262L,0x7a73a4fce6861310L, + 0x19bcac90c828330fL,0x73e3b66f7ef74fdbL,0x60f7698352d8f2f4L } }, + /* 49 << 168 */ + { { 0xda57f1a65645cb9bL,0x3d5d3190f0840240L,0x6a0c6ab101bce275L, + 0x38993676ad23128aL,0x54f7b5d7ea0da248L,0xfee930b38b04ccb8L }, + { 0xadb9034e2cf3bf1aL,0x0488b71ae9b608daL,0xa3e51e303bd1172cL, + 0x56dffa5844993c1bL,0x6b3211fa4cdcaf10L,0x223b2a43834d4e17L } }, + /* 50 << 168 */ + { { 0xb31f934134e43ed1L,0x895c99973c6b7f58L,0x360021084c465126L, + 0x7eb0bf6b095df89fL,0xde3b2fa3ac534af6L,0xd9dd9f55c22477caL }, + { 0xf52cfffc2092e355L,0x4ba071ac8d8bffc6L,0xafb61137abefe750L, + 0x2887d0e4cb62210bL,0x0eb2be515f4fc157L,0x8c993039438fa2f7L } }, + /* 51 << 168 */ + { { 0xfd2a61093efae008L,0x60fa269552f57cafL,0x3591e64f481c36c1L, + 0xdc2b9993c908a87aL,0x76bd4dea5bffb50dL,0x913a0458f70fb0f5L }, + { 0x45ea6c4c097bbfc3L,0x3ebe29d3fa9e90c1L,0xc69532426479c087L, + 0xdd1d24509abc7a4eL,0xa497b072d0fc7791L,0x477d71f9388ab90cL } }, + /* 52 << 168 */ + { { 0xab3578047e03a14eL,0x0f4f28688caf673fL,0x919e661e66530425L, + 0x28da445c91ba47c5L,0xd6d0537566c394feL,0xfe1864a302e8ae91L }, + { 0xd34baca2a753aec4L,0x43b7ffe7a2c8d292L,0x496659eb04efb8f1L, + 0x310ec2a9e0252dfdL,0x98173d2f9168a80eL,0xa3e018d631497255L } }, + /* 53 << 168 */ + { { 0x39ee6439ddfa0ffcL,0xaea6f882c1d1d54dL,0x688feff654a65059L, + 0x17ee5aaa37f25ebaL,0x6c9b4f2932b345f2L,0xb883c0c75b4d62ebL }, + { 0xaf33e4ae3135aa7eL,0x28a7572c924146a2L,0x67dc5dd37e77ae8bL, + 0xe11cd9c5ff39b601L,0xa86f090b5e6f364aL,0x76f7517500b84247L } }, + /* 54 << 168 */ + { { 0x26d3a3e3fbae20ddL,0x5e9b73cee1dd2b25L,0x7008aefb0235d5b0L, + 0xa92af4ed2aaf208dL,0xab786c9bb1132040L,0x43250e6c9a91269dL }, + { 0x00a15294c9be00ceL,0x2d5782df1698dd42L,0x3f980bbe76e3d6e3L, + 0x5b602647496650fbL,0x461edc3271aca61bL,0x2516ab6c9805a01bL } }, + /* 55 << 168 */ + { { 0xb468fcf2967e2216L,0x97b840679ae47d05L,0xfcafaebc5cc15209L, + 0xaf7f6c8ccc83c3d4L,0xa74d4cd5cfa47e0fL,0xd8a51615474cb8b1L }, + { 0x4815ef52591462a6L,0x9c5b2cf74deb41ddL,0x39cb450b7e99d620L, + 0xfe8cacbaa7772019L,0x98b98210577dc69dL,0x5e02b90072423a96L } }, + /* 56 << 168 */ + { { 0x3266c887d9d9284aL,0x690f818b73646ab7L,0x67315ec6af7fc33bL, + 0x181e61abc30b1ccbL,0x1b81e6cd105a9e1cL,0x62a15daf5078b9bbL }, + { 0x74f9840f6fa8cc65L,0x356b777443388573L,0xba0f7d0506b3fd46L, + 0xb0ac864c92b4fdadL,0xcdeac253ef192cdeL,0x0c24810bc313b4a7L } }, + /* 57 << 168 */ + { { 0xfbcd4f77e748de9bL,0xb7d28cdfc25dcc94L,0x32f937a92e033c43L, + 0xb6289636d9da1f7aL,0xd774e97dd287865fL,0x8d013739e6243bf8L }, + { 0xee7ec1f856b9601dL,0x429017666afc90caL,0xc42d960ad2bef9afL, + 0x654ece7f5b430bf6L,0x02878c7f221440f4L,0xe575aa6474a4e1a5L } }, + /* 58 << 168 */ + { { 0xc96e763e71a449f9L,0xdeda66311a349fb0L,0x6f896aef3c4e8f44L, + 0x71ffe2d2e9eb36a3L,0xcbee21ab8f908a29L,0xaeb695f85be98708L }, + { 0xb6023803de61e1a9L,0x59f1ec96065ecca3L,0x2a1229f3637d0741L, + 0x5a9bca2c69441afeL,0xfc6daedbbbeaeed6L,0x950034954e2e31e0L } }, + /* 59 << 168 */ + { { 0xe59a827339859da4L,0x8720429fa7431a84L,0xfcab26e17ee3457cL, + 0xc13c1125da3b7833L,0x0bb1043fbc0b0da1L,0xdc2726ea84b526e8L }, + { 0x34049278a213a188L,0x400bb4a00a1a2553L,0x00e3eb25c92df398L, + 0xc0b7113f9c36a6ddL,0x719d185001e274bdL,0x86f08f2dcde338aaL } }, + /* 60 << 168 */ + { { 0xef8c40bf1adb09b7L,0x2efeb49c0b74992aL,0x3f0f8a412b79957fL, + 0x08927bfe87a06873L,0x1f63a4109288cb9aL,0x8c66fb70df2b373aL }, + { 0x98da4712980facaeL,0x15ce5b17d819d026L,0x097571a5749a671aL, + 0x85a40804894dd269L,0x3e89c13c34cb6797L,0x2d19d5e4d07119a4L } }, + /* 61 << 168 */ + { { 0x903eee85d90da9a7L,0x67723582de5ddbf9L,0xacf6898ad394eeeeL, + 0xa700fb8fabdb94f3L,0x1bcc4f947ac5624fL,0xee5cccff7e3b8ec5L }, + { 0x87d64d4d98e5a1baL,0x78727fc1ad9c4409L,0x55b4159b82310db7L, + 0xaff4eecea58d10efL,0x6d2ec94c11c958afL,0xf129bd1043db33faL } }, + /* 62 << 168 */ + { { 0xe1f6d71ed42eebf8L,0x46f825b9541ac0b2L,0xb01031b693ae2ab1L, + 0xfa4e1c357c589556L,0x65fb2504d273d1bbL,0x589d735447642bddL }, + { 0x7a5776adcf5e2d53L,0xab5c3544e5feda7eL,0x48e8442d32dea96cL, + 0x5f3e9c9e64d293daL,0x3f2df6a16b972a00L,0xfba58f5fa273832fL } }, + /* 63 << 168 */ + { { 0x5c9fe89240e9ce34L,0xfd9fb296633495d7L,0x0ae3c18a8c76cd7aL, + 0xb5ede1e3a6b77012L,0x5ac7a9d5a285822dL,0xe41de7da71ffe07bL }, + { 0x585f7e101b1bb4c5L,0x482794be74153077L,0x66f1c9d5a3e2a34bL, + 0x491d48f7c749830fL,0x3c0f3bcd5416d2bdL,0xaa3baada90b04986L } }, + /* 64 << 168 */ + { { 0x58225208ecbafb80L,0x4f212035aa73d6deL,0x1224e45562fe86dbL, + 0xa8c8a4782dc5b2f1L,0x8a957b8dc3096555L,0x6a3248b0b1591452L }, + { 0x1e563c58cb604c18L,0x32808cb59bf1045eL,0xf8f62de99462e7a2L, + 0x6b3dfe91c2489214L,0x6c1d8fc42174639cL,0xdfca11b8ef88d4b5L } }, + /* 0 << 175 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 175 */ + { { 0x5a4a5ce418690ad0L,0xd0f788e0fe27f51aL,0xd459388e4efe9a30L, + 0x3a45c11aef9d074bL,0xf68ab50b93ab9cb0L,0x62fbc397ecd9a566L }, + { 0xbfb79b7fcc587a7eL,0xfcf4d66f92870baeL,0x4f31aa21877390f0L, + 0x2de0c645e314cfb5L,0x56d904f6238eab12L,0x4d104a42ccb4d4f6L } }, + /* 2 << 175 */ + { { 0x3eb83a8729358cd3L,0xad741295b9c6d430L,0x57b8c77a53abe4e9L, + 0x0a14673ebb9feb82L,0xc0a6cbf7f26f922eL,0x213de299a32e526cL }, + { 0xca417e677b6ca858L,0x8d6ae0f7fc2e0900L,0x2bae0e7a62e135ddL, + 0x962bdcaea7ee82c7L,0x573d7f6ae5776c74L,0x9c4de6496ffbefebL } }, + /* 3 << 175 */ + { { 0x8c962fc809335d38L,0x26d1bc81eb38d176L,0xe1aeb295c47711edL, + 0x0812b9926cbe3e4eL,0xeecacaf90ab9805dL,0x82fefbaa3521a0adL }, + { 0x3a6948c0e2c31b9dL,0xb7d3905be82daf2bL,0xbd3ac90e25a34c37L, + 0x55afd99b61453063L,0x56d87cd190b99303L,0xc9bf82dd97ddb0a3L } }, + /* 4 << 175 */ + { { 0xcbc0bb1968916917L,0x0bbb9f921094bf88L,0xf62cb350d3806442L, + 0xe4d2f1cc397a7602L,0xa54bd48e43987d82L,0x77b6f8314f0a19faL }, + { 0xfa0c9a456e766443L,0x995ae0fff51ba70bL,0x8e242c5b9cbd8d33L, + 0x1671eb0813d97956L,0xccae388f40da55faL,0x97cc48faf376dce5L } }, + /* 5 << 175 */ + { { 0x1c2919bbe8c91718L,0x9dbb727a5097bde3L,0x23f87ae7f8ea2fb2L, + 0xe1bfffdcba310121L,0x5938c50c75329669L,0x716c63e00549855cL }, + { 0xe091b0c9654814f0L,0xa20535d10e43daeeL,0x16ce68b2593ddd04L, + 0x7813a49af59900bdL,0xef0d3eecd3e5d232L,0xe7d12cc40ee3fd4dL } }, + /* 6 << 175 */ + { { 0xe54d92cdef01fc5fL,0xc46c2ab8dda2e25aL,0x7c907fd2849f6142L, + 0xbb11dd2dacd0202dL,0xa4913a701d92d19aL,0xe9a26ae0cf610677L }, + { 0xfff1e1d5538943c5L,0x5943dcc4a47b2204L,0xcafcf33a92cabf71L, + 0xd571e13ce329d1adL,0x7626ad237a9a0e4cL,0xf0aa0d9f130d7f86L } }, + /* 7 << 175 */ + { { 0x09df3a4419e6aa7eL,0xe27ad0475841b1cdL,0x02d2a69fbde75934L, + 0xb0e05e53fd9ba435L,0x4732d88ae008c16eL,0xdebc4777ea72110dL }, + { 0xccb7d9932e3143adL,0x674f3753ea8cd06aL,0x56012a7a051562cfL, + 0x961df68425f74cd6L,0x26630e71214d8a95L,0x584e8d6365d92f84L } }, + /* 8 << 175 */ + { { 0x8a89daefebc5557cL,0x7ca71403275e1649L,0x48d923775b80bb4aL, + 0x0a587c52a45b3626L,0xdaff503cc75bfe91L,0xd845d3e6116d07d7L }, + { 0x6b5a4715a51eeca2L,0x34ac02bd74481991L,0x8f076cfc595abf8dL, + 0xc9de4ce9ed0391ceL,0xaaaad03ae1fcabd3L,0x8d48ec0087b199edL } }, + /* 9 << 175 */ + { { 0xbd0f2653ae5dd482L,0x59f968dd060032dcL,0x6bea33e067283310L, + 0xccce88cc012aa50cL,0xbb6d7f2f66838f46L,0xb764c95f05ec9bcbL }, + { 0xd097b60451477ccaL,0xc2fbda7b82b20a85L,0x75fe07a424e9ca8dL, + 0xfc4fa8240cc40d01L,0x0b17d5f90c0e95f7L,0x285e6e8a6e1e46dcL } }, + /* 10 << 175 */ + { { 0xb0641d09bc9b2654L,0xf9fcc2e68aa8fa35L,0xd12a5b4b00d5ec6eL, + 0x9be1a1115569d89aL,0x9c0566deffac7208L,0x7a9fd4ff7034edf1L }, + { 0x636aeb6b9571c375L,0x60d05aec55cdf187L,0xf4e2f898734e9d2fL, + 0xdaf742195ccdc6bcL,0x9d39249f608a4f28L,0xb5f1bb5e8820e2c3L } }, + /* 11 << 175 */ + { { 0xd02e9936d9589548L,0x8f1bf5755341402fL,0x1535a443057300aaL, + 0x3062478e65d29324L,0x4203351fc656a3f3L,0xbeb21b516569c4ffL }, + { 0x8113ce70e1f0f263L,0x59d1293903f9320cL,0x95061255d08f8936L, + 0x8be3c0f997d4b705L,0x0259742e827837c2L,0xf55ea28d95c65cdaL } }, + /* 12 << 175 */ + { { 0x62024812603dc3dcL,0x25dc5337efd67b57L,0x86b3eb38d7f033fdL, + 0xee3226b232646d6fL,0x8c4825f6f1dae596L,0xd2303055a5bcb8e5L }, + { 0x904a53493c0baa76L,0xe60f6125e08646a7L,0xaf6a329f21d45f89L, + 0xf20ad88a06605546L,0xcf7a0e9619a93d14L,0xf1eabcc891c97174L } }, + /* 13 << 175 */ + { { 0x72b76e9e8f02af51L,0xac94cbf1d580f95aL,0x2e9cd74801d854a4L, + 0x4ed4e9061f08a1bcL,0x0a2b28419d2bd936L,0xbf86350051c89ddaL }, + { 0x9407b0e7e3f00bf5L,0x6b1f71ff28b57ac1L,0xc1dfe03fcd28801fL, + 0xf3d83d64afa55309L,0x47aafba28af8f76fL,0x54eed45f6604b2e9L } }, + /* 14 << 175 */ + { { 0x59edd2640f3e541fL,0x318674b582b76ba8L,0xbf4a0d304e7f0716L, + 0x36fc0e4119b88200L,0x91db560240da801eL,0x638371ad2c72c2c7L }, + { 0xfe960c25d5822da7L,0x7a7571d14a7415e1L,0x5a6480febccc1576L, + 0x72f4e5e5c3c88f47L,0x224e7e749a7bd8ecL,0x3ebbf52c7631455eL } }, + /* 15 << 175 */ + { { 0xae3c2bc08608ab37L,0x35e3da8c39f336b6L,0x7413664281f44511L, + 0x21ce7c511d8506e7L,0x9b6718b3846165f1L,0x9e455007f5cabf6aL }, + { 0xec582a0e02611073L,0x269aa18d83bf042eL,0x7c54fb7c86306757L, + 0x453336021b948fafL,0xd3a5c508b7025d73L,0xcd6e555b428471e4L } }, + /* 16 << 175 */ + { { 0x42c9fad511a224e6L,0x6b6aeb8b69b2ac26L,0x0cf4c7fdb149854bL, + 0x4a7d90002fc359ebL,0x9ff0c3ea29ec8603L,0x157ae7859b24ee14L }, + { 0x638c809a8979e9bbL,0x347dfb2e7869d8c5L,0x2fb1e0f8a07ea547L, + 0x1e580d32aecdec3fL,0xbbf895730f74025bL,0xeb94d71bdd529164L } }, + /* 17 << 175 */ + { { 0x8670812a35d03250L,0x2f68343f1984cd59L,0x5fe890caf1ff97ecL, + 0xd47fff536f764b2aL,0x70fa44a4f8f7077bL,0x7b287efcb2c7fe02L }, + { 0x0718e70806dedcdeL,0x37193c827172c0f6L,0x47ad55f67b7f28a5L, + 0xaf83c4fe9c71a96fL,0x2d6075587c490626L,0xe647de1b933e9033L } }, + /* 18 << 175 */ + { { 0xdc5909e3f1687d4cL,0x4fe3be46d431c5a7L,0x28c41a035f9807beL, + 0x2c4203fd12f1f8daL,0x13f12da450a19620L,0xc32f881eae2e9835L }, + { 0x56328ef7622587d0L,0xcf785f038f209f66L,0xb562ea70a2697748L, + 0xa762289055598769L,0x9842bfa8fbf41fd3L,0x304c3057fa401ba0L } }, + /* 19 << 175 */ + { { 0xb8d685d1c56bc716L,0x1eceb18f1fccc358L,0xf94bedc82034cabdL, + 0xa9acaf11ad003472L,0x6fea0a55ad0786c6L,0x60f7f9a9581f6f52L }, + { 0xc4736494400bcca5L,0x221d8f8a3606b047L,0x533756fb6339c7fdL, + 0x1e068e987510c1a4L,0x9bf9abb6ededfa09L,0x96895ce548d54775L } }, + /* 20 << 175 */ + { { 0xc995b0171552c477L,0x6f92a95252351781L,0xa9d4bb6c4da25dafL, + 0x2b02828e3cf6aab7L,0x5f4febed11fa4d0bL,0x42f0e61ea12d9d37L }, + { 0x1ceef875d24610d0L,0xa7c85c485d4eeceeL,0x33fcfa3b79340a49L, + 0x3671e563b00b3491L,0x871f74e493eade0fL,0x1ed095182c546f3eL } }, + /* 21 << 175 */ + { { 0xc003b709a9a5c68eL,0x9441e7b26c84310aL,0x7ec3b652dd90f7c5L, + 0x17e601685b526324L,0xc5f77fee479573aeL,0xe89beed18453fe7eL }, + { 0x259a2b0364540cadL,0x8c2f13322b9a8053L,0x1db53ab7304940edL, + 0xcf780c5d1612763dL,0x2edd7285e19b62f9L,0x20ddc9874abdd7a5L } }, + /* 22 << 175 */ + { { 0xa70aa6781250954bL,0xe4a2f7cf2930f3edL,0x3e3dd26666fd719aL, + 0x500166cf792ff463L,0xeccd32cd75cf00a6L,0xb65f46a5c4526e56L }, + { 0xfc3a99c360aa8cd7L,0xe04a18b31290b20fL,0x957139a218cb9326L, + 0xf6b352ce11fc04a5L,0x9314b80778534e64L,0xd4a265c52d8f5015L } }, + /* 23 << 175 */ + { { 0x7078b4820dca1fd5L,0xec3192daeed504baL,0x144183332d06a63eL, + 0xaff9f7bd69c01ac1L,0xc5fb50475b74308fL,0x37846eeaa67e7ef4L }, + { 0x0fcea663976b931bL,0xd3407d42bb345b71L,0x925afc36a2deb11bL, + 0x12c271092207db49L,0x237500002e1c8fbeL,0x41427e0763f771cfL } }, + /* 24 << 175 */ + { { 0x9dafbe96491ddae9L,0x92c60b897741da5fL,0x1185b001b866ab14L, + 0x7a43b9cfca7f2f81L,0xaaeb5efc6ee8fdfcL,0x1f7cc70022beba9dL }, + { 0xa212724722e3e7cfL,0xb98dde1e9e723477L,0x87832183ac89706bL, + 0xdfb92ac1ff72f1d5L,0x5877fe6daade3804L,0x7ddde4a79170b9acL } }, + /* 25 << 175 */ + { { 0xdb147da0b7df600fL,0xbef5374660a8b100L,0xb4c7e404a1330d14L, + 0x152c6ae754f96693L,0x08884fecb25fd94dL,0x8ec186048ba59001L }, + { 0xdc245c0c9f8e77fcL,0x2be5aaebc0f0a83dL,0xd15bdecd1fd13525L, + 0x46b603f0821c9224L,0x6b335a7daf6dc128L,0x4cead4f94dc6b5bbL } }, + /* 26 << 175 */ + { { 0x239cccd8179fac91L,0xffa076063829d42eL,0x75b8589cbd42a0ecL, + 0x012f5e80d7f2292cL,0xdcee7efd99c14665L,0x4925256d23650737L }, + { 0x847c86ecf3cc64afL,0xdd34a75feabc04fcL,0xc2f73b3ac6a1f710L, + 0xe16e317565cbf6fcL,0x9cccffee351461d9L,0xe3d635543b4fe4b9L } }, + /* 27 << 175 */ + { { 0x6e27de1176ece8f1L,0x3ca873a79d5a3cb7L,0x7d65cdff7e424482L, + 0x023e5bcf69372216L,0xae601c2f2ffeb5a6L,0x8c8888cbde130b33L }, + { 0xcb8309485700ecc4L,0x5a1902ef9dfe1891L,0xe01f5fc558198380L, + 0x9d5d1c476c59f973L,0xacc64c98e34cc41fL,0x057d81f03065d870L } }, + /* 28 << 175 */ + { { 0xf3a1a9797aeefd73L,0x3fb166a09537abf7L,0x39e8c469d4c37607L, + 0x3efc85650e3f034eL,0xc955c2dff9c25655L,0xd6ce96ec260fa449L }, + { 0x5383a8b831d8e6d4L,0x3aed2e761a3595dbL,0xbd269c39e22a0f45L, + 0x4c82238694a7a83cL,0x362f08055731bd0cL,0x7dc1e7ee0527be95L } }, + /* 29 << 175 */ + { { 0x606ffedfd41ce228L,0xb87608d0ceb21740L,0x6fa23c0794a4354aL, + 0x587a7c54d5061d84L,0x75678bdb16b823ccL,0x2d2163c94ec818afL }, + { 0xa80b1e4e22c6fcaeL,0xc07cebee4d2a4b65L,0x64f303c7a895e2c9L, + 0x750079f5a768a2e6L,0x0665502c2d423133L,0xaf33176715135cdcL } }, + /* 30 << 175 */ + { { 0xda8f7878c715abf4L,0xc62292a5a5830c4dL,0xfcd30f7e4b46acb9L, + 0xb931f1ee39a73db2L,0xf838a5c84ee1afb0L,0x15609b57c202a921L }, + { 0x2e21871620bbba58L,0xe1d2fa14ae2615cdL,0x0a4dcf3543946185L, + 0x2e80d804730d2490L,0x5e43dc17794246b6L,0x7b3588c8dcb3be9bL } }, + /* 31 << 175 */ + { { 0x3e74f09c1bb8e6e2L,0xac587847584dba0dL,0x926415593f843324L, + 0x0033257729f3ed18L,0x4b7164e5d0089537L,0xc50542793e54c9a0L }, + { 0xbae7ff9808e58162L,0xc0707d03c1aa2fd9L,0x43524f717714dca8L, + 0xa202a0707255b169L,0x0a7867ab4249b2e0L,0x03f748656d6ec5e9L } }, + /* 32 << 175 */ + { { 0xfa2db51a8d688e31L,0x225b696ca09c88d4L,0x9f88af1d6059171fL, + 0x1c5fea5e782a0993L,0xe0fb15884ec710d3L,0xfaf372e5d32ce365L }, + { 0xd9f896ab26506f45L,0x8d3503388373c724L,0x1b76992dca6e7342L, + 0x76338fca6fd0c08bL,0xc3ea4c65a00f5c23L,0xdfab29b3b316b35bL } }, + /* 33 << 175 */ + { { 0xd2437a52eddd4b72L,0xe2cec2abf051b831L,0x845af98e482a4ea4L, + 0x75758ccfa43cae82L,0xa76733429260ea35L,0x77845b02b1dd602aL }, + { 0xb78bc4c047d5c450L,0xcb1f444550ad371bL,0x6bc01293d71cc417L, + 0x8538f638c1fcb367L,0x5d01d35919b313f3L,0xcd6b55bfcf67f6acL } }, + /* 34 << 175 */ + { { 0xc28000d6e3b03290L,0x4dd5064a5f2ddbcdL,0x4916f830338a1414L, + 0x3ffb8381aca74c22L,0xec073ee8e680f548L,0xa34e0693a0430cc3L }, + { 0xc6baf20dca03e6e7L,0x2a30df6e835fb88dL,0xbf3c9e9cc2092d6bL, + 0x391cb25c17bc2433L,0x9b7de7126c205c0aL,0xf25e1494cd2a5e62L } }, + /* 35 << 175 */ + { { 0x05ae44e9d21fdc9aL,0xc520657fce40ebbaL,0x6b8e25431270cb59L, + 0x24e6f9bff7f096d0L,0xc6ded76a3ed81f52L,0x729d05e75f7df798L }, + { 0x99e2636fe5468eb1L,0x6f3abd4c00419facL,0xfc61117a9cc41e09L, + 0xb16f106baa399a51L,0x05603bc845e52713L,0x612658aca5c36107L } }, + /* 36 << 175 */ + { { 0x107573b96defe8f4L,0x9a9edf0570545313L,0x5df43df0e54e8272L, + 0xac91bae8eeb4ae90L,0x241d54bd26006ab1L,0x0ba118a6c031de7dL }, + { 0x376214671f500d4fL,0xbbd6b318bc3596e4L,0x4b5532c85992277aL, + 0xb15165da16a4728bL,0xbd7986d45140abdfL,0xf4fe16df7386f38aL } }, + /* 37 << 175 */ + { { 0x8c5d305696aeee65L,0xe52e500ea79991dcL,0x3af4a3ef343fdde9L, + 0xc6d0389b248ad10cL,0xc3dbdb3f5014de53L,0x606b1352310a0cd8L }, + { 0x65af3f8479bde08fL,0xa6c7d968d82ab682L,0x7262c07d202a6508L, + 0xd0231bb64cd75fe0L,0x58a34ca5dcb1f7fbL,0xcc8b21b21b8cf7a1L } }, + /* 38 << 175 */ + { { 0x4cd6e61be824653dL,0xfa02c0c9f253dd65L,0xab198e41b1e84cedL, + 0x89ce6aff1928be7cL,0xf2a83f4895afb956L,0x5b5f195ddc73f3a5L }, + { 0x44220ff79328317bL,0x03d62cb7f5239616L,0x0e908d34b5d49415L, + 0x050b7651c1f7e665L,0x3610167089e1a98bL,0x564abb3418eb7644L } }, + /* 39 << 175 */ + { { 0x400b363b2eecacf6L,0xe2ae5bee1ed9fb9aL,0x23374b11831e99c6L, + 0x0a8382d82cb9de95L,0xf95b8e052dc02291L,0x63b05a0d2f752257L }, + { 0x9ec16f84b60d9df4L,0x6ed683ac3bda5171L,0x7206450813acca39L, + 0x6024af3cf8871ba1L,0xbf88040e2f9a4d56L,0x001054149fb100e5L } }, + /* 40 << 175 */ + { { 0xd52c606375ccd2e3L,0x4fa8e4df56ce654aL,0xcd905c9bce581d23L, + 0x51ce0eab24ff75eaL,0x1c1c0831432c6e5fL,0xb83307aec02f0e86L }, + { 0x0b7a0274fe2ee821L,0xae7dd7729c3d69faL,0x54745da5931ed75fL, + 0xc276d96f18caba13L,0x142571dd26dd9792L,0xc522dac16c0e3167L } }, + /* 41 << 175 */ + { { 0xa86fa630197b5b97L,0x749ea479fa21c176L,0x520c0e4871ce7101L, + 0x5c53d9ebe30a0b0aL,0xdc71b629ceb570feL,0xa30fc3d11fa3699eL }, + { 0x741321b579cbbfa4L,0x205ea0aae8d18119L,0x94556e92fc62e0eeL, + 0x5ba78d4e042b9c3cL,0x14de84103fa24a56L,0x6e57a9fbd6557bceL } }, + /* 42 << 175 */ + { { 0x2a5e716ff103d9c9L,0xda2f7e5cb9cd27ecL,0x317f74b8e047e5cbL, + 0xf1f496d33a4413feL,0x1a480a9cb8cc9fdeL,0x502b52d7575208d4L }, + { 0xf14fe00cd19c49a3L,0xf5c2367b269be5a9L,0x966a524f12d42690L, + 0x2786ff714dd03b95L,0x6fa1f891d69bf68dL,0x0f3d77579f67b3bfL } }, + /* 43 << 175 */ + { { 0x230c8d00c966c638L,0xde5c9e8e54673305L,0x618b0dd561bc99faL, + 0x669618048f3cb5c0L,0x7c653ca507141ba5L,0x454d54ff32ba155aL }, + { 0x82665a307df3e39fL,0x15eb1a65ca19cbb7L,0x4e7632a617330ab3L, + 0xc69235295a3221b4L,0xe23ee9382eb58e9dL,0xb320aa8e23bcf88cL } }, + /* 44 << 175 */ + { { 0x6ba15fe607a7ecf8L,0x93127926f831cc91L,0xfde2dbf41ff6264fL, + 0xdf7f22018413fdb2L,0xdd81d11487f66260L,0x87907f0e4a87133dL }, + { 0xeac1032cb1d47e23L,0xe2603119125a0918L,0xba680392f2259208L, + 0xb7c7f8ebf9bf06b7L,0x875a380fa56ba57cL,0x05a88a97460c939cL } }, + /* 45 << 175 */ + { { 0xfb2871b7d0dc771eL,0xd12b21fcbaf358c9L,0x30dbd412df616c16L, + 0x291bd90f9345e16bL,0x92f7534b8ee6bb6dL,0x7ebc5b0eb1c901a0L }, + { 0xc9e9c76151e1881aL,0x5ca52152756bfecbL,0xb0a9f5cb6affd506L, + 0x4c12f965669feb3eL,0x01d84b9ea6f1c529L,0x3870fa27e8433c92L } }, + /* 46 << 175 */ + { { 0xe4e9e72495bb5db0L,0x86babe3ffd616958L,0xc1520c280f93c1cbL, + 0xe393ded539cab777L,0x031a2af3e86a6ca3L,0xb26a19101e8466eeL }, + { 0xb16b746dbb64fd81L,0x4e96f0b65a97d50eL,0x7a12a611a793fac2L, + 0x8d729847db6482aeL,0xdd050ce812e72ce5L,0x915041366c54299aL } }, + /* 47 << 175 */ + { { 0x9e8018c06b63c4beL,0x49dde0c8fce47904L,0x1668de9c9bae36cdL, + 0x8dfb0d5f80ed18aeL,0xfd6739a791e1949dL,0x80353c9f8053d7d6L }, + { 0xa611699bdea54710L,0x5eacf16e6c6c1f5bL,0x5212fbd3c920323eL, + 0xaf75db75848d085fL,0xb58564b1babb45b8L,0xefa1958938bc491dL } }, + /* 48 << 175 */ + { { 0x0a43a76c2f95a081L,0x27eaf2bc38b1c395L,0x6ba3222c63da1d80L, + 0xd95ae17e6a78ce09L,0xa72d9812508f03b3L,0x9f36d02efa8ed359L }, + { 0x1716d1dcd5118f96L,0xd116339f489bbc53L,0x272153ef6f7e1d3dL, + 0xcb4a9e739e308d22L,0xcfa9d88b615a3646L,0x8b69bd6cde454569L } }, + /* 49 << 175 */ + { { 0x33ae0fec2b8f41feL,0xc45aac500762c46bL,0xa03bc6ddf228ec44L, + 0x82cb78cfea3d48c2L,0xbe7a02ed27126795L,0x1a44d1f830b3e3ddL }, + { 0xb414edc73be7b58cL,0xb3e6c7ce331bcbc9L,0x9f6fd0f2903b3508L, + 0x260c8b5736cc2930L,0x8581a05d0d59278dL,0xfac1817b189b3005L } }, + /* 50 << 175 */ + { { 0xbf4d4640cc9a69c3L,0x07b39b5d67d262dfL,0xcd4a6a4579526d6cL, + 0x4a04c430538143caL,0x6c3341b86639e3b0L,0xd490cab5ab7216d4L }, + { 0xedda2b64a2a93161L,0x04e309de644a06f3L,0x7cad728a8c4495fbL, + 0xe1744f3871dd61f4L,0x39cbd782e3201618L,0xbd66e1850ca18ab4L } }, + /* 51 << 175 */ + { { 0x69d8237f87dcb8beL,0x3f9a485b090e0237L,0x535371e1f117a1c5L, + 0x0d5ef52675430c29L,0xcb9c150898fdd18dL,0xc7c1a7b4108d9383L }, + { 0x6ba9fb4d98064eedL,0x07d205a9a3df31c8L,0x7a0be62e9be5da37L, + 0x03b21b1255a9e2c2L,0x3f4792263de80449L,0xb0160ee1ae3bf31cL } }, + /* 52 << 175 */ + { { 0xa22c084a7a3f8c5eL,0xeb7fe23f3ef30511L,0x161ca862819fa38aL, + 0xe5f014156d45762aL,0x37da6bb95718b789L,0xfcb682bbd837f453L }, + { 0xc49c7397275e5974L,0xbe908df5a1ed0925L,0x3dcd694615a13ea0L, + 0xdbe652e32596fa76L,0x6a3bcc93c55d376cL,0xa2f7611933a0f02bL } }, + /* 53 << 175 */ + { { 0xdfff9b9c6ed061ffL,0xa36aef2dec32b16cL,0x9f3b7ab6da61572dL, + 0x96e72a027ac2dac9L,0xb0e36e023aaf4fcdL,0x5f32a620503004cfL }, + { 0x6c91dacbadcd649aL,0xb25deea21ac02a32L,0x211a421ffb914c2cL, + 0x1ddbd60e149fde1dL,0x91c4cc0d7ce86ad3L,0x8be6f031b9ed909cL } }, + /* 54 << 175 */ + { { 0x62e773c4a0cb50ffL,0xe54fdbdd2e903681L,0xed2bce9e21c12ca9L, + 0x13aa4748c072bae6L,0xb290c0ad475f290eL,0xcbbc3f9b56698a85L }, + { 0xfb37611b1b7fff76L,0xe62a842260bc2e36L,0xb6a36c783bb20fd4L, + 0xdec045418dd69509L,0x67648b7798a1ad2aL,0x4fa2005d078fdea3L } }, + /* 55 << 175 */ + { { 0x757f249416307553L,0x865af9d0de6bcb49L,0x3943031a07b0104cL, + 0xe5fdb46168da2d33L,0x4937d614b5432b48L,0xb3fbbf2c0a29a5e5L }, + { 0xe7d3b12b8de89887L,0xc1a43c24e41258c3L,0x91ac7eabf7d9efe4L, + 0xfd90de0088385cb3L,0xead102e37674c39fL,0x7b9a2cc4fff118c5L } }, + /* 56 << 175 */ + { { 0x11f92678a1e598f5L,0xde8052491fbb882aL,0x3730b3261154d0aaL, + 0x0e279827da521670L,0xa03c8c702336f8c0L,0xae50e64ff0bd66d6L }, + { 0xfbfd665f7af4f681L,0x237a4f4e5c8d5680L,0x6527611ba409064fL, + 0x1f4eff6a99db9a94L,0x4a55d96ae53ba177L,0xd9dec234f002368aL } }, + /* 57 << 175 */ + { { 0xbb837d0ad193ebc0L,0xab1e3eccd09b24caL,0x229f36d81d848777L, + 0xee895edf0ab68c98L,0x67fc65f4dce31b92L,0x777ebe585db96c26L }, + { 0xca0893ae6047d0d6L,0x71a2ca0b550d6905L,0x35426866eac4c2e3L, + 0xb4d7e78e0c1b8eb0L,0x03cb0a9a84b384e4L,0xd8a99a5c7f7115b6L } }, + /* 58 << 175 */ + { { 0x07db8bfa5f25a74eL,0x97dd568a3dd8e706L,0xcf4c02a32fb59efaL, + 0xe2ae502616b291e4L,0x5499f3b20f9c10cfL,0x59abdcf5a7297ec7L }, + { 0xcec282671f4a3646L,0xc10ae0971e065cb1L,0x172f886319dbbaebL, + 0xb0c27f7d73dd068aL,0x764d185495086ceaL,0xb89923c732de9a97L } }, + /* 59 << 175 */ + { { 0xacd499ca093345e2L,0xfbdb3895f3c23800L,0x2584f8ca02f0fadbL, + 0x9f5dc96ec2f35eddL,0x4dd102ca1ba0266dL,0x13ee9c8aa9f26fabL }, + { 0x9e7467fa2a1e61daL,0x999764b6850191c5L,0xd053a575b70dd8dcL, + 0x697b856fd7065eb7L,0x9d5bb6aa695b4914L,0xc5cdd170e65001f1L } }, + /* 60 << 175 */ + { { 0xe87cf622e93495f0L,0x347b09c6bb43a802L,0x2a38f3b7a4e3ac34L, + 0x13353b959751c1c4L,0x753ec3ecb3947985L,0x3bf856dc12d3fa90L }, + { 0xbf4f6fa5ec35dbe0L,0xd099a15bf3b4fcf2L,0xb348462fbfe7245bL, + 0x508324b352a2d4f4L,0xec4bae05feee1315L,0x468fa9e404496618L } }, + /* 61 << 175 */ + { { 0xc57673257d5e7a94L,0x40c05da604cefc01L,0xba1fd6c6b921c681L, + 0x0d3e09f9c104cedfL,0x4b7cd83cc6586416L,0xb747d7f9adfa7bfaL }, + { 0x833f8e24a42be782L,0xd5f0421d06b2471fL,0xac87b17c22e4b84eL, + 0x85af6b063a10c7bbL,0x4e557cbf66e88e2aL,0xaff21b66d3751e40L } }, + /* 62 << 175 */ + { { 0xdbab25f4c4464538L,0x3c36560ba93d7f74L,0x8b9b15d39f86f410L, + 0x1237e35b0a1db237L,0xc9dad97994f49677L,0x390a3d8f15dff99eL }, + { 0x0a74dfaef82c19edL,0x3f8e958589c2dc55L,0x763448ce94a8e729L, + 0xc6349398625f0517L,0x1ca5f9e7523dd700L,0x45aa25317fe638dbL } }, + /* 63 << 175 */ + { { 0xe91af601aad04ed7L,0x6f86f323e897df2eL,0xf8c259564c7a0ab8L, + 0x6e793f3633845d15L,0x08937ef5e583d043L,0x92dafa5824d1fd96L }, + { 0x6458ae2a86c9aedbL,0x271823a026a4252fL,0xb119fe4c5a57ef16L, + 0xf41e13943a507289L,0x0cbf1da6bd1aa499L,0xa177ac9dc2465a51L } }, + /* 64 << 175 */ + { { 0x14f962e404a8313dL,0xc6e3e7c45f1f5a26L,0x2c0e11c079e777beL, + 0xa1705efb4657c31bL,0x02688fd23c494de3L,0x75664a84412a8718L }, + { 0x878fc7ad7a422f8aL,0xe5d581df7419bd0aL,0x7c813c4c704b70c0L, + 0x98553da87323c008L,0x4f63cec663089f1aL,0x9626d6fa9655d291L } }, + /* 0 << 182 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 182 */ + { { 0x10586ea7507f8b27L,0x1510deb9a261f7d7L,0xa42fc4d7dfbfa352L, + 0xbf38c3821e1c2291L,0x46e40ef60e11760aL,0xc24f6061dcb974d7L }, + { 0x755b105ba7619027L,0x8004bf09b8ffa759L,0xa630d0b00945db60L, + 0xa160ac9cf2809e1cL,0x38fc1113dc6c95c5L,0x01f540985d52574fL } }, + /* 2 << 182 */ + { { 0xcda68a7e698ee21cL,0xc7414d196a5e725eL,0x483be2dadce20b91L, + 0x7de1601cfc69dca6L,0x4bec17aaac4f9891L,0xe8741dd18d479a56L }, + { 0xc623cb8dac23a286L,0xe20a96b5166133f0L,0xda9bb7c030dcde61L, + 0xf84ea3273a1733fdL,0xd7afb6c3e82fac31L,0x37ea7d35d3897449L } }, + /* 3 << 182 */ + { { 0x120649b20370327bL,0x0e76555acd48cdc6L,0x4ed54decca01db03L, + 0x7be21319ac601d22L,0xf711661901b6576eL,0x7839fa064e73537fL }, + { 0x169d43ace46e860aL,0xde6d658c3078eed9L,0x8df731395032142bL, + 0x6be199b09b3c76c7L,0xc2f385f6f8bbffe5L,0x848df7f3d5ffd28cL } }, + /* 4 << 182 */ + { { 0xa189f30fc6a6d6d1L,0xdd674d3669665ab8L,0x307c9ec37d8da76dL, + 0xb3e1d006c1ea7c10L,0xc15e20b3b88c62d4L,0xb0000ec50bff3b3aL }, + { 0x9e330eb19ff9aa5cL,0x8663f9fddf578877L,0x157d3cb002e1eb2aL, + 0x638f297bf525e4d4L,0xa20f833234a3dff1L,0x748ea86b45a9c051L } }, + /* 5 << 182 */ + { { 0x978ed3abe664c066L,0x3f4a8e0d668361eaL,0x0ba610c753a25231L, + 0xa8b5b864189143c6L,0x0d7ccefca2841fc2L,0xa80dd8f3f8fea1e1L }, + { 0x2c24af232e19028cL,0x0e332b77919decaeL,0x44eae977f6089c76L, + 0x25e04dae53722e9aL,0xdd6f8b1f71ac4db0L,0x7c5b6ffd075e7bc4L } }, + /* 6 << 182 */ + { { 0x4c6299a7a1de1cc7L,0x362d293c02d9445bL,0x08f24df0399a9494L, + 0x33307792e37a1851L,0x1cc5e448760f680dL,0x70a6a8164a2efbefL }, + { 0xee939681246fc671L,0xfa7a26d1f70a9c14L,0xfae5ca89b826aab5L, + 0x6b8932c7e48176f9L,0x379f89bd9841c8e1L,0x46141d2fdb674190L } }, + /* 7 << 182 */ + { { 0xf4408485b4619d3aL,0x34b4f18160b4f44eL,0x369edc1b3532caf0L, + 0x2d0471ec6771abc2L,0xca4129311013266dL,0x02e636af617e2024L }, + { 0x1f93d60d3c69696cL,0x6aba7f2a1b99a172L,0x896873e1bf435ce6L, + 0x9649f08215b71e40L,0x730bedcfa02b024fL,0xb17e9cbd8df60bfbL } }, + /* 8 << 182 */ + { { 0xfe9fdde8bc266ee3L,0x91668688ba18e6c7L,0xa65349acddde6f6eL, + 0xc53c29c97e54356cL,0xee15ad945709f73cL,0x033b3940e5429277L }, + { 0xf52035cdd0c3475aL,0x9c5bef4d93f1f1f0L,0x26e0b0ceca319bd4L, + 0x4e7eb67b6951fd8dL,0xac3a6f4395c34d6fL,0x1f2769e600f60b59L } }, + /* 9 << 182 */ + { { 0x95188c136c4d0bedL,0x377a04901b5271e7L,0x60db30226a540165L, + 0x4be61fda3310c5b9L,0xbbb4fbe93f8bbf16L,0x5232fb46ac12f77fL }, + { 0x8d6f75ab255b569cL,0x09cc854d3bd39650L,0xec17a6e74b557c3eL, + 0xd6949f9d5c3d149fL,0x9a17a440494b18b2L,0xc10cb9d5d4a024acL } }, + /* 10 << 182 */ + { { 0x4520be6b8eddc97bL,0xeb8f2c317391f948L,0x18fcbbd772369418L, + 0xb8950ee217246882L,0x6b1e4b7a382e82c2L,0x9e2bb1eb7ea4c447L }, + { 0x5202d913c3c5bc54L,0x53ea78cd21352716L,0x7bd53ffb36e6b4ecL, + 0x8325bdf817387196L,0x33b2cd8af94d6a73L,0x206bdec5e13db4bcL } }, + /* 11 << 182 */ + { { 0x6e27ce2609c98c86L,0x8f87ec4c958002c2L,0x00b6897064ab26edL, + 0xd2b4037282e5e129L,0xbeae654c78c48327L,0xc0632b4341a54107L }, + { 0x7b1fc7f001562313L,0x01cd1b5c1fd6a56cL,0xa199a69835e71626L, + 0xb02b2692635fbcffL,0x1c0c4200a0632386L,0x637164f8d6c670e7L } }, + /* 12 << 182 */ + { { 0x2c47010d18e30ee3L,0xb7d4b1dbfdd5f040L,0x5c8abe509d930f6dL, + 0x6bcf875d5f56cf04L,0x1f6456c0062f1fc1L,0xc79597805304d710L }, + { 0xd76452e4db85dcecL,0xd531f73fa0cbf90cL,0xb5ae9fc89021bde6L, + 0x505c6b9f4babfae0L,0x99d943c17ea61fd6L,0x6ef4766159bf125aL } }, + /* 13 << 182 */ + { { 0x3a48020daa0b0a5dL,0x4a32d4d658bad0dfL,0xe013dbde2e4340ecL, + 0x99efac69a5fc51f3L,0x26acf7a669ee64c6L,0x36672d6566fdc9f2L }, + { 0x77426caedcb879feL,0x0166194676e3be96L,0xb6fe4709b2dac331L, + 0x1f3d8a63678ff3ebL,0x711c0ea447bd5865L,0x5fbe38e87c080adeL } }, + /* 14 << 182 */ + { { 0xd0891b2df4e61379L,0xea2c7ceb9941c391L,0x1441a2d099677e8aL, + 0xc29d88c8abcb3669L,0xecb1a21a06ce9bd9L,0x0663fa7cf5b11fc6L }, + { 0x440a5a1c0c44c2c8L,0x08d71bc39fdded3cL,0x62b53ca512d33d2eL, + 0x3fb8640e005e8adfL,0x2a9acaefaa2673a5L,0x356ae6f6695f8448L } }, + /* 15 << 182 */ + { { 0xcf3c9b318496d935L,0x7e849aff8ceefc78L,0xfc06a46e7a5d692dL, + 0x87248699e89463afL,0x4dc55e5e8e17af3cL,0x3378832fe41ec54cL }, + { 0x7578d6192816f87dL,0x505845612806d3cdL,0x7354f1022754c3d7L, + 0x61ca6cac08d64863L,0xecde4969eb9954ecL,0xe0c211b4a1a5dae0L } }, + /* 16 << 182 */ + { { 0xbd10b8bffb787270L,0x4f0b1566e43aaab6L,0x9a18be5ec0c90781L, + 0x3677f4c71ad167ceL,0xccb254e2a68c1c56L,0x392493e6e2c4d275L }, + { 0x44958cb1d5b63617L,0x178f141a4caa4e7cL,0x7445a767a2ffdbd5L, + 0x0e789c99b0b6c22dL,0x3ff8b6565dc92b2eL,0x1623e5c3eca98782L } }, + /* 17 << 182 */ + { { 0xcb013ff62c5c50daL,0x5e5550b70b256dd6L,0x38249ee1bfd47036L, + 0x984daee275379fbfL,0xfb35304588c6bc7fL,0x32379c955f9683aeL }, + { 0xbcb4ac531b5a8626L,0x1057d2a3bbaa0deaL,0x114ef8a7ffa8efb7L, + 0x553a34566da90cbaL,0xa2ced0b21a365fe6L,0xcec4d64bb1ccdb57L } }, + /* 18 << 182 */ + { { 0xe0312b66b81fe0eeL,0x11e0493b892c7b21L,0xb6a1d76e624ce73bL, + 0x38768ec0cd75cb6aL,0x425b091f2032c271L,0xa88d39f55b5d8338L }, + { 0x1496b9ed1916be43L,0x14468e3054549f3cL,0xd429c2c47248e206L, + 0x21a1c212fc9e892aL,0x0feb5822640c984dL,0x0cabfb472b7c0c66L } }, + /* 19 << 182 */ + { { 0xcda1c4cd1cc5a20fL,0x33d66a893f67814bL,0xbba50d5360ce82edL, + 0x9d34dc4d70553a53L,0xc926f498a8a1442fL,0x9dfe3cbccbb43feaL }, + { 0xd25887434fd3e4efL,0x7443a9a9a371d894L,0xb53e6afaa22bb4f9L, + 0xcef3fa347dfc9da4L,0xd079ded047403836L,0xc6c97c36d39aa93bL } }, + /* 20 << 182 */ + { { 0x6618fcae534f6370L,0x1635580da1a864a2L,0x90ad39947d7ce552L, + 0xbf8c45895257f24bL,0x5a9499202098768cL,0xec1eb621bb6d8830L }, + { 0xfae8f161f1f9ac16L,0xfc9184ca35704c99L,0xa72b1ea9139ea04fL, + 0x82229a912e39e1d8L,0x4153bf3e479c7bc2L,0x83325be4c5541825L } }, + /* 21 << 182 */ + { { 0x358a91badbea81d1L,0x4d1947d7c669c7a9L,0x4ca6d8f18eedbfcaL, + 0xf9eda237069b3b93L,0x9e1217e5a35ea963L,0xb7e16f08ab960c77L }, + { 0xf440d825fb313db7L,0x804c5262101c5424L,0xd236a0edab3c4f7aL, + 0xf8bdb2b1c2682459L,0xfaa7aacaf46c4d70L,0xcf6ce4adae83dd7cL } }, + /* 22 << 182 */ + { { 0x2c7756bcbd452842L,0x2c47593cd1783fd8L,0xa4f41583a7527697L, + 0x2fddafbbd1049934L,0xc087f3db6c71063fL,0x8f5a85c4c9b3ef6cL }, + { 0xbe178bc966a975d0L,0x2e2d825b94066514L,0x061dd919e0d42ba4L, + 0x964fdcfb227ca011L,0xcb915b2973d7ba7aL,0xaa7f2fa72af8338aL } }, + /* 23 << 182 */ + { { 0xbdbb3440734e8984L,0x8b9b7acb3d6f547aL,0xfc4f48ea0e76a07cL, + 0x49758a9f97da0c23L,0x13f4254a26958261L,0xdf1fdca2adb3ef57L }, + { 0xfafba40d699460e6L,0x71b2de39cd5c94c4L,0x52d76b76c21cdf0eL, + 0xbe75960760f3dfa3L,0x519d4fcb7078f5e0L,0x4bd8ca7f5191e1b3L } }, + /* 24 << 182 */ + { { 0xfadf9be978207cefL,0x97d5ba569cb5718eL,0xcbad24ec2f995393L, + 0x6236a26861203303L,0xe4bafc336589a4beL,0x6cba77185e23fa82L }, + { 0x8ccbc5774583e65aL,0xe5d88bca4bc2f415L,0xe6bc2d5841df8dd1L, + 0xec24e1d914d31fcdL,0xacaaf13efc26010bL,0x7e1da447e01b92f3L } }, + /* 25 << 182 */ + { { 0x2b3477ec1a29de39L,0x30a5c2190a8720eaL,0xf593ec729775bad0L, + 0xaaf607792af7dbbeL,0xaace90d4c7cc7b59L,0x6eadf21d40509cf4L }, + { 0xb9a5f138096d00fcL,0x3896d42625b206a0L,0x0f28f0f09dcaa5dcL, + 0x2ef6f9f9a8186106L,0xd212710fe25b4d04L,0x0cc6d2878b9847b2L } }, + /* 26 << 182 */ + { { 0xe7407327cdfb2baeL,0x06745198510c3039L,0x8a913ba74da758e9L, + 0xc882e7bb1a4797abL,0x0f0d8eb5dd7b375dL,0x90ac5223dcff3f3fL }, + { 0x8443b7cabbe341a3L,0xa7cba7f22f173bbcL,0x04669ff830e5c327L, + 0x0edd0eac09b777fcL,0x2a70898bd71e0cb2L,0x881c48929bd983bfL } }, + /* 27 << 182 */ + { { 0xe4847c654e7603f4L,0x826cd33c0bbea366L,0x95727caf2c4ced28L, + 0x580313dedb8ac1e8L,0x6745673701363cb0L,0x540c35ec0ff13cc9L }, + { 0x878c86fe3c4fc263L,0x4d81f8aed14e7c78L,0x6f7cf97e8355ef22L, + 0xa2aadbc848a0aef8L,0xe0200ecf4fc3c61bL,0x7e58e6e0c8094ab1L } }, + /* 28 << 182 */ + { { 0xc52789bbf2d3bdc6L,0xd38673fc3b23d7a0L,0x8b6df95aacafbbfaL, + 0x37afdcbdc7f6eb6dL,0x57775bdd6cb4c9d7L,0xc34e5a2711007453L }, + { 0x903e5ba1b5faf98eL,0x811e142a9d4a8a45L,0x046d18932d7ac9e4L, + 0xe2fe9d1543ce66a8L,0x44b5beb4d4956410L,0x7c5f1b9ebb147f72L } }, + /* 29 << 182 */ + { { 0xd51033f48312b074L,0xc98fe29456f898d7L,0xa8d6433be8eeebbaL, + 0x50bf170976fdbb84L,0xdd95f89d43c14baeL,0x13f9c7366307bca5L }, + { 0x3cd12e2855e7bc8fL,0xe2d7482c3a52581cL,0x12a2c6c7b59eeb8cL, + 0xf98f79124ae87ffcL,0x41eb808e80d7bf65L,0x589970f2015e20adL } }, + /* 30 << 182 */ + { { 0x200a764a6333b070L,0xa0acd8ecdf0d20d7L,0xbc1c589953269941L, + 0xed7c9192b439eca8L,0x057c50eeb789f0cdL,0x31dc2d36a9c794a3L }, + { 0xe3f2d38dd58ef984L,0xdb250da69235b084L,0xc2ff1b49da05b500L, + 0xf2ea6cc50387c539L,0x8250353a3d1004cfL,0x69103201aed0bf97L } }, + /* 31 << 182 */ + { { 0x495cd7fc878e97f8L,0x6397fa8b61120b1dL,0x20b9afddc8708907L, + 0x84f55bb97be2ee80L,0x996fcb9d8d075b5dL,0x2e94d95ead858627L }, + { 0xf786143e77113ebaL,0x6fec684f7b3fdb28L,0x4be44fb211d10d07L, + 0x4b3478e2372f16b6L,0xec8d61614697ca58L,0x097d241c3a45f335L } }, + /* 32 << 182 */ + { { 0x6f6a6104899ef333L,0x95496f6d39067165L,0x42fd9a6ab51989e5L, + 0x1b60ce0f68f5b168L,0x97324d8756f7fe67L,0x443812f7676815a8L }, + { 0x265ee994685a7260L,0x342c7b2f6c6515f0L,0xe909232334b4adb0L, + 0xddcd233e1e5a8d18L,0x3dc5b27c5f4f6456L,0x9664533a7f421d9bL } }, + /* 33 << 182 */ + { { 0xa55e8ab09a35f4aeL,0xf908fb35ebbadf5dL,0xf885d61b35fee31aL, + 0xb8047f4f82728fdbL,0xa6fe454d33c5bc34L,0xdc5266332ef52e54L }, + { 0xb2f524a931581251L,0xb9eeec91aba760f4L,0xa95d396624a9b423L, + 0xfd52f4d29d3d75acL,0x82719e78834d4c33L,0xeeca71fb3840ca62L } }, + /* 34 << 182 */ + { { 0x984658940f4c60e0L,0x3929d4c645ce7c0cL,0x7846d6c19c4f9b89L, + 0x2c38a9b20fbc695bL,0xeeb4799ad73d4bb2L,0x7c16e5ba4e3b5520L }, + { 0x11ce92e51cf310d2L,0x0910dcc91e037725L,0x159fcef85fc5af9fL, + 0x4944f8ee1dcb3ca5L,0xf5d9f8c0b9a4516fL,0x452f0fa2f1cfa6e0L } }, + /* 35 << 182 */ + { { 0x59b15b61c634aab2L,0xcca0742a620df0b6L,0x791d95720d345276L, + 0xb775b790cd3854baL,0x944e591a256c26fbL,0xc5fda2d0b8fe17d9L }, + { 0x7dba5830c0aff69dL,0x46f7164b0f7c6d60L,0xd767cd58549eeb83L, + 0x4498b4f51ff2da7cL,0xeef2caf8fc594b0eL,0x88dc39ec5f0a95b1L } }, + /* 36 << 182 */ + { { 0x1a57d3e1b3fe597eL,0x1a3ad06d18d1b6f0L,0xf70f27b32e4a4617L, + 0x55e8a0479a75b4adL,0x0b24d5beede15d86L,0x2b3c41d0fb2f56b5L }, + { 0xf6cf36aab1d36456L,0x418a72fe1d8ff434L,0x64149a0d156746bbL, + 0xae65897c4e3a26d6L,0xb75e87d21e68eefdL,0x5b81e0b01cb27c91L } }, + /* 37 << 182 */ + { { 0x2c3fa19b34b90671L,0x369c9e9aa7c9aae3L,0xd89dc03f3d236ad0L, + 0x280c47b9588ace95L,0x0ad071be57f25a96L,0x36ce641d8296279cL }, + { 0x321778128595511dL,0x51878842b52cb227L,0x720df7ab4156b413L, + 0xccc71e10fed25819L,0xc878554e3fde679bL,0x9c50ecbe3b565d48L } }, + /* 38 << 182 */ + { { 0xb2d66f1ffe23ba35L,0x82339e2914b273a4L,0x454a5f0b58c2be97L, + 0x0ebadaa68488ac1fL,0x3c635442517e9af1L,0xa87044c3a5b9fe2bL }, + { 0xb8214dbdb505ae0bL,0x05a9bfad60bf4393L,0xb7b64b42428a49ceL, + 0xcad71866bd2283f1L,0x5bcfe7fce33a3a22L,0x018a2121fd6c73c3L } }, + /* 39 << 182 */ + { { 0xc4471fb02510a1c7L,0x542e73bd2c1c35c1L,0x0bc8bcc4f028a46aL, + 0xdf87cd2bb5610f25L,0x0845e4d1df42b41fL,0xc0523e3593aba84dL }, + { 0xc9161e8ed14887b0L,0xa96f9b3aa68c235dL,0xba1427a46f94d5b5L, + 0x6a5fdbbc858e00f3L,0x8170bad6abfaf661L,0xb4b9dc0ec9f4abedL } }, + /* 40 << 182 */ + { { 0xc48bc829ff7543c0L,0xc0bda14c4d72bfaaL,0x2f470ec703be0af1L, + 0xc70f1e8e92d37eb4L,0x08abdd98418f410fL,0xe38c74ab35386176L }, + { 0x9c07cfdd8c00426cL,0xba74c310a998f1adL,0x76b45140b7d2dda8L, + 0xa52b5e584948330eL,0x9b7332348d8efb26L,0x5d1763735d19a312L } }, + /* 41 << 182 */ + { { 0x46950a441d38ade1L,0x377fdf593058c7a2L,0x5e2fa1681aa129f6L, + 0x2eae63dbc5fe1745L,0x9616fee275545475L,0x4073a79c8627b2cbL }, + { 0xf1ec69ea9a5198e4L,0xe9a906aebd2821d5L,0x193a9387bc22625bL, + 0xca468d717b6c67ccL,0xb4d11cb360f17a73L,0xcd801a0e3df1cabbL } }, + /* 42 << 182 */ + { { 0x1b80b9c386cf5a12L,0xa5bcd3a016349cfdL,0xcee36e8f00d1edb5L, + 0x9566e10a5b7bf29bL,0xd0db98cfd4ff0a0cL,0xb516605e7fe427d0L }, + { 0x099066c18e614e25L,0x63537fbbabe78647L,0x5601a8b420117e1aL, + 0xfd125e2f06df05acL,0xa7fcbd420948daeaL,0x55ad4ee28ff03220L } }, + /* 43 << 182 */ + { { 0x18d71671da2c6332L,0xb38bf94f98ee4e23L,0x9b90bf72ecc579e8L, + 0x5af93aab1bf6b8c5L,0xdad6e7909342613eL,0x5a1d49dc710ad0ccL }, + { 0x2013ed8801468036L,0xb8bd31cf2f0f6f9fL,0xf025eb2aaac961a6L, + 0x1e201f659e1adb43L,0x2755f3aeac7e5132L,0x72d8e1d0f5205d31L } }, + /* 44 << 182 */ + { { 0x80bba9170319fec4L,0x4ba44600aaef6debL,0x83285b613594f325L, + 0x8879183753b5765aL,0x651b4c6adaf1b02dL,0xccc17578825f609aL }, + { 0x0b4076b39fddc6ffL,0x286e2daddf2fa874L,0x46c45233c413b648L, + 0x4fa46969b7cfe0abL,0x835786f3e04f5e5bL,0x526292a90ce3f707L } }, + /* 45 << 182 */ + { { 0x9928e9eb83f17723L,0xc38d5de26c2306aaL,0x3dd3f371558b3989L, + 0xfa4b194877154d39L,0x89f437e4b89f5448L,0xd5531444a6437c9bL }, + { 0x65a6874092537cd4L,0x5f6d72281246fb09L,0x0db0b3be58539e37L, + 0x1f0dd43df50f4143L,0x1aa12daec215aab3L,0xf82820fb7fe7b225L } }, + /* 46 << 182 */ + { { 0x32c6bf5e56cb520dL,0x74dc46c41569fa1aL,0xcbee46391ba52541L, + 0x5e2f511a50ec4575L,0x90165e35032b6f53L,0x2b8f1f8a5544c780L }, + { 0x95baef65c6b50147L,0x4e9db41946b7fde6L,0xe2463226f7afa6feL, + 0x4d70932235409eb4L,0x8faad8937c20aa0aL,0xc8c95a85abc1ab65L } }, + /* 47 << 182 */ + { { 0xd5f54ce676d1f996L,0x55957500e595a0eaL,0x9b62e1fd92c72af4L, + 0xb4803bc3069bf052L,0xb7cdf59c686ebd16L,0x2d1fa780655ac6d2L }, + { 0x6c306d3edca404f5L,0x24e9d7a9a7b5fa9aL,0xe4c080ddc533c701L, + 0x71d16b63425e29e3L,0x81c00db32d993e49L,0xb59f87f577902ecaL } }, + /* 48 << 182 */ + { { 0x43b58def987cf64aL,0xc95b16c63d4bcd4eL,0x5d1b1373bcd9b923L, + 0xaf560542522e052bL,0xc2ff8f7583800352L,0x11723aa17fe2a4eaL }, + { 0x28de7668e94bd9bdL,0x0ce80e0f874018a5L,0x0fe3755d8d43e726L, + 0xa78296acf9b075c5L,0x76d58d9882207423L,0x5c5bc6971db99205L } }, + /* 49 << 182 */ + { { 0x9cbecc969e2aea70L,0x1a3fd38d7e4f2a84L,0xdc35e3c84b95e560L, + 0xd5e912a5aa21d2e2L,0x037866628d8cd601L,0x4b726855f2bb35e6L }, + { 0xa45a827a0d763ea2L,0x17d6e5ea057bceecL,0xdab2381d09a2a2a0L, + 0xf1880617e9aa76dbL,0xb86444dbb184c5ecL,0x23a0e4b767da7c23L } }, + /* 50 << 182 */ + { { 0x2d94a6f030df736bL,0xd1ce20050b3be2bdL,0x201352b55e288cc1L, + 0xdbd3dc57779644a7L,0x9f258b16d191db2bL,0xd83c827fd1c123efL }, + { 0x74c5126e17f04f0aL,0x06008f14966e620fL,0xa4406ba80aaa9e37L, + 0x27323f797faf87eeL,0x43380a672b1206a1L,0xab1ed1cfaf15ebedL } }, + /* 51 << 182 */ + { { 0xa3d2bad9bb22cc74L,0xfe6591a80e2b9221L,0x8c94c974d3cb4eefL, + 0x772694266beb6451L,0x2942737a010986e4L,0x920c9dda59c1ace3L }, + { 0xd31af336da61e1d3L,0x973997a118021018L,0x50a6c8425710575dL, + 0xd61d47c9ade9d8a0L,0x90abe8f8a85f458fL,0x23cc28a3ac4d474bL } }, + /* 52 << 182 */ + { { 0x283d5bb63e052e69L,0x149ac3d01bd300e4L,0xb4c7b96ce0582ccaL, + 0x66102883428cb7d7L,0xd3eea16b500958dfL,0xe1b6a74f74674893L }, + { 0xe3b284be3fb0522bL,0x74b0fe2dea983a60L,0xd4328e5c81e465d8L, + 0xecb534c7403173b3L,0x1721e22774144d34L,0xb7273c6aa88a5141L } }, + /* 53 << 182 */ + { { 0x0ea24ac64018877dL,0x265cbfe42acf249aL,0x811c17e61837d63aL, + 0xff453f5d6b3adf1aL,0x7add0621a3031529L,0x62105dc838af1d27L }, + { 0x2cd31a899b56ec62L,0x5f524be5ede7bbceL,0xc485b2ff66a044f5L, + 0xae28f5dc87a7b274L,0xd41989a93415b6c5L,0x3051ca44c9c43ad1L } }, + /* 54 << 182 */ + { { 0xc22046bcfb50bf2eL,0xee22fb7b78f7c548L,0x5c41c6bc2b5b4563L, + 0x56da674a8bf9259cL,0x3732f77433d8d4c7L,0xa90bf0472741046aL }, + { 0x5ee7f4396288c2e0L,0xa7a1fec99ae621c6L,0x523c0569b76e955cL, + 0xda0c2b378d1e8601L,0x9010bc349559b56dL,0x8d2fab0917b8d9b8L } }, + /* 55 << 182 */ + { { 0xb2caf938281b021cL,0xc61f3abf1404b0abL,0x24203e1cea26d902L, + 0xc84f07e10d34906fL,0x8ba3d589f0cf7520L,0x86b54f6d9a2a90caL }, + { 0x9f87234f3d77a667L,0x328941966e3fa8d0L,0x0921b4a6e994d49aL, + 0xe77e9f8b8b3495cbL,0x9e5b74798da1fe56L,0xcbc09ce7b070591eL } }, + /* 56 << 182 */ + { { 0x583ee7dfe3b7e746L,0x0b6659e4a4fab3a8L,0x34ee02751946db5dL, + 0x5ae3c0ba1a12eecaL,0x36756ed44ccb83e7L,0x973b0861a80eaf3aL }, + { 0x969e38f46982ca90L,0x9a9bcd10018d01fcL,0xb540e9533272476aL, + 0xcf91dd0a75ab7002L,0x2c7d363f39ceb983L,0x4369c221974747c7L } }, + /* 57 << 182 */ + { { 0x32c5b289642be172L,0xe5cc452e697e6a30L,0x344935e10aa6841fL, + 0x9eb2dc4faad907a7L,0xaf77d029e121d0c0L,0x2bcddeb08bb073b8L }, + { 0x3584dee5e40653fdL,0xe853b6337605f214L,0x4723f0add4bab900L, + 0x16dddd27fbf91322L,0x1f96d7e610c525b2L,0xdfba535200c998abL } }, + /* 58 << 182 */ + { { 0x701e8ab819df9ed7L,0x1a6d74c13e2159d1L,0xe82127e0fc61a470L, + 0xaa2e5f33dd15316fL,0x92b6ea927c42c081L,0xfd470a298522aef4L }, + { 0x0c54a067e5ccf152L,0x60c113eda1a079b5L,0xdd501a8389d6e6b9L, + 0x3dbf20d219792456L,0x633cd2b710bf70edL,0xace5327a0aa8e5e8L } }, + /* 59 << 182 */ + { { 0xed79a2de3b2a8a4aL,0x02851125cbf095c4L,0x6817ecd1880fd3bbL, + 0x72acb6ff066adfe0L,0x04fd696d66ce8257L,0xb644f098dc81958fL }, + { 0xcab55d1525218005L,0x1184b0a64de70465L,0x6248e1157aa96b53L, + 0xe30958630516ac32L,0x19f80cc0d07084ceL,0xfdf7ca2efde86c28L } }, + /* 60 << 182 */ + { { 0x9a8857568bc1783eL,0xb373e5a0a7cf2ee3L,0xdeb162fde46cc503L, + 0xd5d334601074ef35L,0x0030f98eea159a90L,0xc5ffbdde64e50d98L }, + { 0x85a6486a48195b26L,0xdbf56597b1b9f2d6L,0x5df2352ab8613aebL, + 0xc425807ebd0189a9L,0xcf5a34d4fa1f4f7bL,0x233e26c7628fd2ceL } }, + /* 61 << 182 */ + { { 0x6c4dd28313a1e482L,0x24bfc23bf803f1ceL,0xb8e795b2f426832fL, + 0x636d2d63b13fcb5fL,0x2dbca0b214a508ecL,0x1948c957c1ff2b70L }, + { 0xc9d7cd4ae3135c7aL,0x1bf41de75d7cfe18L,0xfff9428f2f6cd5fbL, + 0xa25d3e8294d640edL,0xecdea1583e4fec66L,0xff3b2b1555530798L } }, + /* 62 << 182 */ + { { 0x483565313178cbc6L,0x085a31143f3a1ff0L,0xee2a58b11dc7054eL, + 0xa9ce7c113287d5e6L,0xd283d22c8fa263a1L,0x9160bb8be77ff147L }, + { 0x21dabddf918caf34L,0x6921e987ad1a9f13L,0x47e45c7d3ba0ad41L, + 0xeaac63192bd18585L,0xb88881060818034aL,0x2d8e9c1b60be0a45L } }, + /* 63 << 182 */ + { { 0xad3e46af32f4625aL,0x5c2f95dd88371d5fL,0xfc7a9adef2415ac6L, + 0x77a23c424ad85440L,0xce7c63712f4dd730L,0xd65bdc45a5c9f380L }, + { 0x763d3990cf11ee6eL,0x7b2a927a9ffc522aL,0x65ccf351deead5c5L, + 0xef1fa99cce4d076bL,0xdb6f5cca6708ba8fL,0x361525a0f3bac7ffL } }, + /* 64 << 182 */ + { { 0xbfc40c30f893a2caL,0xdf96980e0623bad1L,0x4fd7b54dc027511cL, + 0xf4799284cf3484ceL,0x655ab811069beea5L,0x52588bc87392e280L }, + { 0x522e7b404f0c17cbL,0xc0d88acac705e9b2L,0x9cf1b95877f3913fL, + 0x3e06b9267dd52514L,0x992e920e2908cbcaL,0x13baced26d6ed529L } }, + /* 0 << 189 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 189 */ + { { 0x8a46c911bfc6c637L,0x8dc3d699e4fa4fe6L,0xd4ba64f15cf8e4c9L, + 0x01b3908a01cb3488L,0x69b1fa5d38bd7dedL,0x92ad483818b2eae1L }, + { 0x619324beb33955b6L,0xc7f373355c8a6df7L,0xa397f42e925b3f69L, + 0x32169a495f7e4d11L,0xc0fa9a548d0d9f01L,0xf52a1f2289d8f2e5L } }, + /* 2 << 189 */ + { { 0x9c0d5231ba8e0a52L,0x94d0509e93e465d7L,0x67df90dd98515454L, + 0x223e8b9c8dbfb46aL,0xf39529a36d757ce3L,0xffec9175b4648296L }, + { 0x330749e8f78aae7bL,0x19e5549645f93cc3L,0x8c320b3494083aa8L, + 0x1161f5a321e321c6L,0x0980deedde3e7892L,0x605aa9196ad76cccL } }, + /* 3 << 189 */ + { { 0x71191262062312e3L,0x84c82a94691f46faL,0xad4b344bdda57f44L, + 0x674b758ac4f0cfd2L,0x3bc058a077543efdL,0x3d7c765756618d06L }, + { 0x95107c744dba9e44L,0xe59c3180cfdf1923L,0x5dbeaf35e3f1d63cL, + 0x012029c643ab8726L,0x4f588a4ea256c6fdL,0x14a01b7a3e5d2e30L } }, + /* 4 << 189 */ + { { 0x73fa3508180660f7L,0x4cae013e2d24936fL,0xf64a549f58493d98L, + 0xd9ceae0adc79f602L,0x6569e37bd1512b84L,0x11e4c022151c9151L }, + { 0x075678c2b55c5813L,0xb26cdb5809d3cb16L,0x6334dca3a57fb969L, + 0x0ed90820223dc3ceL,0x74f9c3aebd11e277L,0xaeefed3679c0b8e2L } }, + /* 5 << 189 */ + { { 0x22195e48e57ac6a0L,0xba77c58214bd1913L,0x265f96b4323349b5L, + 0xc183196ea124d497L,0x99f1f78d2466d82eL,0x185a18bfc6263afcL }, + { 0x29a3d5b686cf8908L,0x81f3bc00f680511dL,0x5f6ffc81661d015aL, + 0x31c2ff64cd5eb082L,0xc3c37ad672776042L,0x49438769d9c6ac75L } }, + /* 6 << 189 */ + { { 0x0e2fc74c2a24c385L,0x836a474034679278L,0x25518f16817e2c41L, + 0x8b573a8eb4b7d3c1L,0x012797f94ab56adfL,0x9e0e56d0fa2ab690L }, + { 0x009ba1ee1c9f6f08L,0x8ebf4aac2f412e9eL,0xb143122a1cfb4e02L, + 0x988cf0eccbf2b783L,0x44a7ed9657f5be97L,0xbdcad87251804147L } }, + /* 7 << 189 */ + { { 0x969fcd982f60d1a0L,0xf0f4c9b2ef06b3ebL,0x8c6438cb49ec8f92L, + 0x746107773f1653daL,0xf7cbc899b574576aL,0x758de9008494795cL }, + { 0x73045065ab22cf9fL,0x9893653c9ff13e98L,0x6e8860264a58d64dL, + 0x387d6cc34e3bf554L,0x82a49da4a42b0008L,0xb28bd9b71b0b1c47L } }, + /* 8 << 189 */ + { { 0x378205de2f9fbe67L,0xc4afcb837f728e44L,0xdbcec06c682e00f1L, + 0xf2a145c3114d5423L,0xa01d98747a52463eL,0xfc0935b17d717b0aL }, + { 0x9653bc4fd4d01f95L,0x9aa83ea89560ad34L,0xf77943dcaf8e3f3fL, + 0x70774a10e86fe16eL,0x6b62e6f1bf9ffdcfL,0x8a72f39e588745c9L } }, + /* 9 << 189 */ + { { 0x97e6400574103b65L,0xdad518d6db50ac66L,0xaf96065961077d1bL, + 0x1335de0a5baab1f5L,0xd404db749e444a1cL,0xd3124c5027d5fe2fL }, + { 0x1f20c68a0bd49e9dL,0x44405e6aad6a1654L,0x287d565193c362a9L, + 0x301ec6a2e76661bfL,0x4900f9b54c6f9927L,0xca3dbc3464bf3909L } }, + /* 10 << 189 */ + { { 0xa96955b9b1bafbc4L,0x8dcb55a7646ece39L,0x2b62784feb00e541L, + 0x462f9d7d2693249bL,0x8b264697794c189dL,0xded6ff5563354e69L }, + { 0x7c8ea441eed1089fL,0xe355f75c1462f461L,0x87b691f61210fd5bL, + 0x7291bffb6983cb27L,0x9ed83afc92800095L,0x307a3dc81f24d923L } }, + /* 11 << 189 */ + { { 0x9f79814a45faaa0cL,0xc64a7ac93bb1b07eL,0xaad6ff897f2ad506L, + 0x43da948300b83699L,0x6a702b8d6617956dL,0xfcb1035a7981052bL }, + { 0x094acd48cb230926L,0x3c3249d05da96800L,0x934088079d7208c8L, + 0xe4f04014d738a48dL,0x49bc5f0bf18b06c2L,0xf854285f596b9befL } }, + /* 12 << 189 */ + { { 0x7cec60ead7804b2fL,0x0064464345c11441L,0x3c6de88b769cd685L, + 0x34709186c7f01232L,0xd9eef41eedd2bd0dL,0x3bafcccde427faa9L }, + { 0x33e5350ec07e701aL,0x9cb2eb47a87c1fd1L,0x9fa9a7790d5f5b28L, + 0xa2e7076b07ea2e53L,0x72f4da325c169cf4L,0xb7f192947e751588L } }, + /* 13 << 189 */ + { { 0x1a3b217d2f6d700dL,0xcbbe9349ed335d55L,0x428adbfb53ff169aL, + 0xbd74385214793b47L,0x2224e2569d9460a2L,0x8408600809982ac0L }, + { 0xae6c6f9934447242L,0x63c78b2b9b51fb67L,0x381c948a389593d4L, + 0xf4cdd09f6e79ee72L,0xc658428ba185a0b6L,0xcd7562a786fe4c6fL } }, + /* 14 << 189 */ + { { 0x47eb133532dd7a30L,0x9d058169a9db654dL,0x375c59df6e7a2b1aL, + 0x55d37c677a35f29fL,0xc78a3678493c4cdeL,0xe5f0e2d68d83e31bL }, + { 0xf7927002e9777bf9L,0xdd559324a5afdfc7L,0x077c6c48b81c08ccL, + 0xba1c98ccaa2ef694L,0x06c6c9544c02dd46L,0x211e50f37dd3145eL } }, + /* 15 << 189 */ + { { 0x7f985fa8a96aea53L,0x811f94dc480b38d4L,0x91fdd510f3d40c68L, + 0xc156312ccd763693L,0x24b544c3640057dbL,0xd7d5d4f5ad3b5a1bL }, + { 0x5e235a1e26cda8a4L,0x0cf7b7cd1d2c6f17L,0x17b1ccf0908d3107L, + 0xf32f2a06f555eb5cL,0x274f7c2cb3c278c6L,0xcf1eaf296af1b44dL } }, + /* 16 << 189 */ + { { 0x2a5f8ecf06616d0dL,0xca9b1cb8c7deb373L,0x9de31cedc59c4301L, + 0x1e0f40b10111d998L,0xd29d229f960d5b95L,0x10563249d1dabab8L }, + { 0x7b225cc9a05ecac9L,0xb02e689678f3b8a0L,0x009b52a1f5fb06b2L, + 0x8a575d3f842b9081L,0xfddb48afe9272512L,0xd39b8f1d0b452cb7L } }, + /* 17 << 189 */ + { { 0xb6efc7e167ba9cd3L,0x5a642c288e4f62a6L,0x214a63da364378edL, + 0x582c59944121c53cL,0x840277facc9a728fL,0xc6db3529f8f72d39L }, + { 0x9c5cc2760aca9955L,0x8558a58db8b6dcd6L,0x709226acf0701f24L, + 0x6ce95b21ed248b40L,0x32ea565b5487934aL,0xa75a688496f9ddd1L } }, + /* 18 << 189 */ + { { 0x0d6b9c7c67e09987L,0x261a564d0761ad52L,0xec4621749f60925bL, + 0x83ee0c1218529b03L,0x72972467fbcfff74L,0x37fc074c6abc4bfbL }, + { 0x8b6015bd54e65e89L,0xde8583eb991583cbL,0x379548e1b4d2c62aL, + 0x88024a9a9b24a5e5L,0x633aa869fc03abfcL,0xa27657b98fa35283L } }, + /* 19 << 189 */ + { { 0xb340993c5727e344L,0x2379f51d4f3295d5L,0xa5de3efce2929734L, + 0x7d2e2c82d8717e3eL,0x8f24abb67180db1fL,0xa5060d648a4ed876L }, + { 0x8d39e3a2761110d6L,0x38d30c93a3bb5b66L,0x07774ac3c12fb741L, + 0x7d4ae5a55f4425beL,0xb9848a2afa704922L,0xed9ab68c4cd00812L } }, + /* 20 << 189 */ + { { 0xde9703b461d9e770L,0x02d4091def4653efL,0xefd229aa576eb5e1L, + 0xc0b0b243f77eb987L,0xb11309b2eefe8f71L,0xfeeacf2f68478044L }, + { 0x8dfd8e8643ac3dd7L,0xc0a24181b07f95c3L,0x551ca09624be161cL, + 0x6cb2c1d4b098cdc3L,0xbfc74e9be74f84f8L,0xe58e14d9067e3388L } }, + /* 21 << 189 */ + { { 0xda121aae0ef98506L,0x435f28c6328e636eL,0x64b2170a720d40a3L, + 0x3ddb0e61cd24a844L,0x111442478797c7adL,0x624e7f73d589dd37L }, + { 0x3e7e0ed0a8efdd25L,0x8de031f116509a5aL,0x1330cff5873488c2L, + 0xa80c60b3342ecf75L,0x9d3742c8e62550ceL,0x8ec9b229e46475f9L } }, + /* 22 << 189 */ + { { 0x9eca6f94f025baa6L,0xb2db0741bcf9c741L,0xf8e2aab590bb8f56L, + 0x4772903208762829L,0x067a0c5ae2a266c8L,0x22b104c771b7d7d0L }, + { 0x4a48cd6953e406dbL,0xb85e44d524f0070bL,0x6168262fe10133ffL, + 0xdfc02315e4874e8fL,0x20dba2d7ca317e3bL,0x441c56d2e1d2c0c3L } }, + /* 23 << 189 */ + { { 0x9ebd10d6c444a2fcL,0xda7683e3f18ac11aL,0xdd42ed990fe8e59fL, + 0x9c867debee068909L,0x32df043fccc77aa3L,0x377423ce4aaa45acL }, + { 0x960940524a90c535L,0x48bfe83347d1799cL,0xe8cd1a55ccabd174L, + 0x2ee0a276682145c3L,0x4249297e8d606c00L,0x22021ce2fd7af6d3L } }, + /* 24 << 189 */ + { { 0xae10069e808dc4b1L,0x64df30e18fb3ba73L,0xbbe4caf27ebaad0bL, + 0x5907bf373dd6119cL,0x0a723dff9dfceefeL,0x59bff4ddf7cffc7eL }, + { 0x7bc95fa26a6f43c2L,0x9001d1d53ca0e2b3L,0x316a7ecd27b3335bL, + 0xbf08e6727b8d7d49L,0x4b209f93c619058fL,0x4c0ca01e59d8f9eaL } }, + /* 25 << 189 */ + { { 0x3c1e7f45bad772b1L,0x20f6f1732544af67L,0x14f491f9a7d6544dL, + 0x1451cc8e6acea162L,0x20c8ffa5d234ab89L,0x4b59bce1f5cd1002L }, + { 0x99da4c0ee63027acL,0x6290cb963fc1f75eL,0x3a51774524c4d85cL, + 0x3bf9929c1fd144e7L,0x9bcb97467068294bL,0xcb0b3e5d2e61a022L } }, + /* 26 << 189 */ + { { 0x18c452c4cae69c3bL,0xf45690acef0f00faL,0x3b363aa04f66a5ccL, + 0x9dd41c0a47718c52L,0xfa219d7e7e5cd370L,0x5d384db7b2196dfbL }, + { 0x5e14749b90b4d46bL,0x55796656d9db9481L,0x3bf13d0ac8cf353eL, + 0xb89a28a6a95c485aL,0x568fa3d05da29783L,0x4aa008eed182b1a4L } }, + /* 27 << 189 */ + { { 0x4f38667a179639e1L,0xca492d50ba7c7a16L,0x191e4a3478fe9dcdL, + 0xa3cddb2f03fc70b8L,0x57d90a90a751ec9fL,0xcf88357457a50cd6L }, + { 0x69abd86d7cc58687L,0xc73a00408466bc6cL,0xfbb99c755c495208L, + 0xdd5f1ab9c13347b8L,0x9ae6fb92060b93efL,0xd6bb56a3588e5369L } }, + /* 28 << 189 */ + { { 0xf7e1ed3bb09fa8f3L,0xbb4fe6f71da5be9eL,0xcbab0e01f4d1ba21L, + 0xb732741076a5f326L,0xd94d2349206092afL,0x739f3cd0728e0e4dL }, + { 0x568644aaf81fd823L,0x510cff6b6110e2f6L,0xef4cf1ac566c3598L, + 0x2c26f17162aae69bL,0x1e4360468964a2a5L,0x83c0bbf63e472c50L } }, + /* 29 << 189 */ + { { 0xc198c07064b2955aL,0xc32d41e1d8d43284L,0xfb6f0e2c9f4fc13eL, + 0xf4d5b60b41c61889L,0x5c79f500beb36946L,0x328b22408ca4beabL }, + { 0x64058e916697617eL,0x6bdf7409f43f7390L,0xf2afd208f5bd8512L, + 0xc0000aa0bd1ad6d6L,0x38b8e03bd9f6c1c2L,0x0a34680d665a2d06L } }, + /* 30 << 189 */ + { { 0x79c04804aabd965aL,0x9581aab443d0b660L,0x59bff0035ba71d23L, + 0x212ecd58b6a0cd80L,0x29bdcd33bf1ea5d6L,0x59fd2ff477a002e1L }, + { 0x3c9d21308d9cd247L,0x790e9dbcb1786da3L,0x967ee5e714464d04L, + 0xd6f7ebbd2b5373afL,0x1c0b22d539768d40L,0xdfb54983913f6cc3L } }, + /* 31 << 189 */ + { { 0x5c9808b78a42e002L,0x5cdb2b070f732854L,0xdc92b1676d6d4579L, + 0x789dbb8ebcc22c54L,0xd76b2d40716eb28fL,0x5cbaadea004affd8L }, + { 0x5d4d84dd08fcfe12L,0xd0f1d7ee20d4b893L,0xc98d77dfbbb90db6L, + 0xbce9a5a2b1e29a22L,0x71a6835d0b54e100L,0x0199594a55b1ac68L } }, + /* 32 << 189 */ + { { 0x167ec88a51b3f1ceL,0x19756ee0420024c8L,0x10f2e2443877e634L, + 0x6321bf2603462cb3L,0x1dbd10ee9d3afceeL,0x0726f5f22ca17dcdL }, + { 0x094652660bacf018L,0xc92a9f2de1feb969L,0x0043b0f95e1c5912L, + 0xa09b94d1757d3a63L,0x533956529fdef1e0L,0x9826886cd4fedd41L } }, + /* 33 << 189 */ + { { 0xd22bcbee51964ceeL,0x3ed80af3b0eea46eL,0x263cfa026b854aafL, + 0xfa4ad481b9ca3b51L,0xf8c569a0b4451297L,0xeafb78f8f48059a3L }, + { 0x86a9e3c037093acbL,0xcfb3bb63275ef52eL,0xc4672d3c7c924f03L, + 0xa87350871691be3bL,0xf124f3a52be289b7L,0xf45052dc6b80b6c1L } }, + /* 34 << 189 */ + { { 0x79c99f99a010db6dL,0xe83088a74ee93fc2L,0x76e8376d836b1a7dL, + 0x8cab091c4e24e127L,0x5c98a00f7283cd21L,0x1beaf4a084997647L }, + { 0x2cfb55b8d934088dL,0xca24052cee724d5fL,0x5d6e9db5bba84289L, + 0x133414b26fb26d72L,0x3e844eb9cb12a503L,0x5eac12dab53d6496L } }, + /* 35 << 189 */ + { { 0x79a098812cc6698bL,0x6d44e7577f383e02L,0x1969f93785b5f732L, + 0x3061f62792acecccL,0xa9428d60cc2a4752L,0x69a472af2cf58626L }, + { 0x63fde53cabd347d7L,0x138b5b6a1aed4fd3L,0xd93fce1f2bd48519L, + 0x957fe302e49cc436L,0x9b51657a2e21ad5fL,0x3b5c4cb6acbd3af6L } }, + /* 36 << 189 */ + { { 0xdcfa78b096dda000L,0x5b60dfe5be2303bdL,0x7a6bbd34c7c6ad6fL, + 0xd45c9cb57012b97dL,0x9a049e36812e1662L,0x723bc0b66a5483aeL }, + { 0x7fc03b6ad1c82e81L,0x02ddd6d2b23f6818L,0xe8914b2d30dae39aL, + 0xf4f0ae392f692056L,0x198a31bd45f1390eL,0x917ce4f4f542565eL } }, + /* 37 << 189 */ + { { 0xde39a4e6ca447864L,0x95a028f9f0b131ccL,0xba77ac314a39c4f7L, + 0x0c24d09614857939L,0xdeea56edfbfaa0fbL,0x79aa342f4c920bf1L }, + { 0x50228f48c7e9dc62L,0x0fd9d1dee0f0fba3L,0x3fc03993cd703f6bL, + 0x229a3bf4c5ff39fcL,0xa7456aa484f9cb20L,0xb01bb5a7d12fd7d9L } }, + /* 38 << 189 */ + { { 0xfb390be4539519d7L,0xbaa98a2a6ad44d22L,0xafd19a75ef89de1fL, + 0x1afaef2971e27781L,0x18b297d79887739fL,0x8fcff6048e6da42eL }, + { 0x17bfc1717e861a36L,0x1467800537a8843bL,0x2bc47afdeb16065dL, + 0xcc038e2fbab7b4fdL,0x9d8fc42a3eb9be7cL,0xfc2f0b295928da63L } }, + /* 39 << 189 */ + { { 0xa4e33ca261c14fbdL,0xebafe73fc0a87f99L,0x22fdf1d1f5abf7f4L, + 0xfc1da26549a6b956L,0xfd8c48e5be25dd72L,0x9fd6520ad31a25aaL }, + { 0xe0167d4ffd14dbbaL,0x8838d2ba7370153cL,0xe5f7d69b133fdda1L, + 0x31acbf8de1749b60L,0xc14ec9e2107558dbL,0xb06d0252b99553acL } }, + /* 40 << 189 */ + { { 0x34590975ed424438L,0x7c03ce744d11a200L,0xcc939a286ec406eeL, + 0x8d214276fee5454dL,0x66a0e1a56b257f70L,0x93761a8a006fb85eL }, + { 0xc44f9df2aa70b65aL,0x1dac524f91d9e2e8L,0x5894a8224fca1a81L, + 0x8586e418f3ed85bfL,0xd494dfb202899b5bL,0x7ea9f222ecb8e371L } }, + /* 41 << 189 */ + { { 0xd93ee716b0958516L,0xa91f39db3eb86888L,0xb472c1e2ac92105eL, + 0x4d88a307429ca094L,0xd3fd88027a8e87e1L,0x40c4cd50126a2cf2L }, + { 0x046ce3bf11cf2046L,0x412678ee05691999L,0xea0c78168d3a2921L, + 0xd24ae89924f3c66eL,0x2c4457f00bd144e9L,0x82005b4fd7a52270L } }, + /* 42 << 189 */ + { { 0xf1b3ec32924340e0L,0xe5430ea3b33a05abL,0xbf43b031807629b7L, + 0x53c9407d57014039L,0x6e67b52f2f195ce2L,0xc8cc645f1e48d8c1L }, + { 0xf2234275c08f2122L,0x9cfe3c74c2f233e0L,0x235e6b349c4e0af9L, + 0xb4e8ef5770de39d8L,0xba573a727f73d0a9L,0xe12c506a18587ed2L } }, + /* 43 << 189 */ + { { 0x6b9669c59cf3e4f6L,0xa472d5dbff677559L,0xde845b0c877e5590L, + 0x9f7ef5802d0e2350L,0x87ea99d4e78c1096L,0x213243e9abb68028L }, + { 0x0172c81595e71abaL,0xc2592a762ca34c65L,0x50749aee9dc286dcL, + 0xe37d10884055de3eL,0x3e5a93bb90d652baL,0x0cbb7a08c32aa3e6L } }, + /* 44 << 189 */ + { { 0xe0bf3d8a026c43cfL,0x091956cfeb702508L,0xfcd486c9a6b3203aL, + 0x94a6d52f365460ceL,0xefeb5400563bec77L,0xbe6baa9619b2659cL }, + { 0x116f71c34bf21a00L,0x83d1c99a86d21871L,0xff1ba96aca0bd547L, + 0x5eb0acf741b94afbL,0x1be5d66fb1aaad14L,0xb8ececc5e6cd6d4fL } }, + /* 45 << 189 */ + { { 0x65f6e29dec7d4de8L,0x082fa0560e938c79L,0x4cda3fc925a02f04L, + 0x77dbcf0d3bac5cadL,0x625f9bd859145bdbL,0x98b7fd64553a11f3L }, + { 0x621bfbe387dd8a45L,0x6519421d1c35176bL,0x89eabac6d5ead4c7L, + 0x45c68bfe54acfbd5L,0x87cd244a84f30b68L,0x83b5f6b27b39275cL } }, + /* 46 << 189 */ + { { 0xd43b1d3c0ed0ade8L,0xd60b1ae7640e7d37L,0x965489e6f88e06e5L, + 0x35398ac89653417dL,0xed1e89ac02cfcfc5L,0xd127f68dbb6f2bfeL }, + { 0xa569c59fe22bb079L,0x7933f14e4ca8e9deL,0x68b4964a30033c3eL, + 0xab438cf88f069045L,0xa64f3a1516163059L,0xf40499c14576fe42L } }, + /* 47 << 189 */ + { { 0x361c28da052567f7L,0x8a2c6aafe0db84b6L,0xa79eb10cabbc87d3L, + 0xeaf7bfff4141b3acL,0x90bba4a953aacaf8L,0xda577661c35f9564L }, + { 0xb2550d0dd4487a5fL,0x69d43c5199638269L,0x6d16973f7a1f8ac6L, + 0x3dfb2253c71e4a4aL,0xafd836aefa36168cL,0xba72fd1faae6dacdL } }, + /* 48 << 189 */ + { { 0x690c0cfeb449d1e2L,0x4a5e150b1b8e1577L,0x22508042204d98a6L, + 0xc87a97f5bad2eb08L,0xd307c59ed25823eeL,0x6ed083580df8b3f6L }, + { 0x280ae344314e7016L,0x6a55be876ef4e889L,0xea930e5a24d04e38L, + 0x0269d9a7309830fcL,0x41dc8f0ae4afeebcL,0xfd1bc660f14ee02dL } }, + /* 49 << 189 */ + { { 0xf81cc943631da366L,0x2e821eb85ab1a2caL,0x339e9e4765433883L, + 0x3dc14370e1f60c71L,0xbd6c79bebc25b506L,0x2bd3ad51a8a639f0L }, + { 0x7c168f13c700a293L,0x64fef4fc28b4ce88L,0x3ccdc3080c329c6aL, + 0xbfd78932b76a9452L,0xf0c123fbc684f4b5L,0x8bfad06432305ed6L } }, + /* 50 << 189 */ + { { 0x208a668feea1a9ddL,0x8af75caeab903f09L,0x356208b449265292L, + 0x57b24ebe53faced4L,0x9c8aaa7303694920L,0x1c06ef5ad2f90179L }, + { 0x794ead99df92de87L,0xad900c4e7a73fe9aL,0xdb66b9ae715d9f66L, + 0xd19dc46db1bc2950L,0xb0a5af5c24c82c0aL,0x7d83f950371d0ec7L } }, + /* 51 << 189 */ + { { 0x716071e3abd37656L,0xaa22858be6cab564L,0x6793a66f5aec00ccL, + 0xe2ea5401e025da6dL,0x3998ea5d2eb0059cL,0x4ff6f442e39abb77L }, + { 0x703eabdabdb6e0f9L,0xa33e6deb38522433L,0xe23c13f6ca83c2acL, + 0xcfb8e57c0cac836fL,0xd0f84bde7692714cL,0xb4fc3b01f3f41d29L } }, + /* 52 << 189 */ + { { 0x67842ab4d8f358a5L,0x70cab57540e2fb69L,0xdebc3046e5c458e4L, + 0xc3574cf47eb004d5L,0xbac261a1c86f20f9L,0xc1bcb661deccf7fcL }, + { 0x5b3b96dec5574e9dL,0x07b878b3e151fb0fL,0x2f2d126cd38bd5f2L, + 0x06c951e8319597c9L,0x5529be4424ed0027L,0x82dcacc2ba8d7acbL } }, + /* 53 << 189 */ + { { 0xc37eef0149311e82L,0x3d07aaad401d010cL,0x934e039e53417831L, + 0x70775653da895ec3L,0x206b80af625cbe49L,0x9e2a4ee1e53ccb36L }, + { 0xebeace45c8ca6ff7L,0xadb19bd9925302deL,0x951bfcc497dee154L, + 0xd09882da79b60e1fL,0xb1e9cf0cda5f2516L,0xc2b697295e4def97L } }, + /* 54 << 189 */ + { { 0x74ce542d04f860e6L,0xdc8adf8fa3c48075L,0xe19852232063f76fL, + 0xf651c9fd5cd9ff61L,0xd4cbea69bab39ea0L,0xb6d4749b28fe3443L }, + { 0xaa7747ec65e960ebL,0x1a1b7b65e132a213L,0xfa52901f402a50d4L, + 0x3e4d2da68d43700fL,0xbfc7322937d45181L,0x68a812f9008bb845L } }, + /* 55 << 189 */ + { { 0x226d4d233e4cbf5dL,0x36359f52576243e8L,0x032af38a39a1999eL, + 0x9b59120a687eb228L,0x85c56b78e68e1498L,0xa7a14bd4849d03d1L }, + { 0x9e7177b345c4c3f1L,0xad7e4975183bd846L,0x42418d9a42f69dc2L, + 0x218e8f8e4f52cac6L,0xafafa7649f1f3214L,0x32f6f72b747f7592L } }, + /* 56 << 189 */ + { { 0xefca7f7ba6c53c1bL,0xcb4bb33c524457a0L,0xc9eab87fe57d08dfL, + 0x48c01c2a7d9a1967L,0x11c97ed97dc27492L,0xd8c644861cf1f639L }, + { 0x541f8c0d8156576cL,0xdf5c8dff2384e299L,0x9806935ba6be190dL, + 0xec6c5de764494b4eL,0xf04e2d4cb83c00b6L,0x379af438c0b84f15L } }, + /* 57 << 189 */ + { { 0x64e6289d92bbc1f8L,0xe88b78c5a0620121L,0xd01bac79a0fbc373L, + 0xa2e7986af098f07cL,0xfcac4dbcc5911218L,0x2e2bf56db337ed26L }, + { 0x878d9819e89a73c6L,0xa7df4f5768df46d2L,0x74bf7e2f4b3c9568L, + 0x2f2b187aebcce535L,0x544f18139a4c2be3L,0x3a5fe300a5938f0eL } }, + /* 58 << 189 */ + { { 0x901a14cd70aa91aaL,0xf0b6e1ec7f0b0a70L,0x6fd1ee0156a8bf9cL, + 0xe7e53c6693fbdadbL,0x18ebae68e17de706L,0xf4107457ebecf636L }, + { 0x77a85ea4a9f6c696L,0x3ea193e17dd9e3adL,0x9497e0a9f151c8abL, + 0xcc9237497a1dbf14L,0x2e36740e8f9be59fL,0x1b1c7d7c4a249e51L } }, + /* 59 << 189 */ + { { 0x7a45af2242cdcc53L,0x3061d91b8682832dL,0x85e080f6c375030fL, + 0x3ea6dcd1418440c7L,0xe0559870d14b6537L,0x36619215d178b45eL }, + { 0x48a4b452dcb85a34L,0x79cf4529bd5504bdL,0x506215e9e9c34c8eL, + 0x961f74b6dbd00e2fL,0x473d1397cbc84ddbL,0x6c64f870a8d67cb5L } }, + /* 60 << 189 */ + { { 0x519a6edb91a9b99eL,0xc0ea29e0f19221eeL,0xde83e0f77dc193b2L, + 0xa7b33b6044be16f6L,0x7edcb49406c8e8d7L,0x9f9dbb86392c0ef6L }, + { 0x09aefe035726bd5eL,0x782d8350c4e80b7cL,0x14e41a49186b80e9L, + 0x9af13703499ef97fL,0x5752877f2cbcc336L,0xdd0f8583d2df624dL } }, + /* 61 << 189 */ + { { 0x1cd2be3f32f6b0a4L,0xfd5da4a90114bca5L,0xc322a6a198a39a66L, + 0xca411eeb10d64384L,0x7c5d3ed0c72d8b6eL,0xf20c76697481309fL }, + { 0xaa4e45dca155872dL,0x66e41d54b87c1e51L,0xbe2fe5e6a6bfe6b6L, + 0xf60ca33a08a4d3e7L,0x45c1ec8c7211b48cL,0xdf44d3b573b78f7bL } }, + /* 62 << 189 */ + { { 0x21eda67429a1e6acL,0x33118990422ce5aaL,0x236aa9ec27326810L, + 0xc42dff9e3be7b318L,0xbe4601281690755fL,0xa395509d8c1c60c6L }, + { 0xa36de79d05b991d2L,0x55f516a3632882d4L,0x4c8c5a4296d1d493L, + 0x56199648533cda6dL,0xf9c6897a603bbfeeL,0xae835160f9857cc4L } }, + /* 63 << 189 */ + { { 0x700bad58d6aa9618L,0x2ad7069c05d54c73L,0x7f3ff5992f6a8495L, + 0x39de751ee26e6720L,0x39126d97d4cecf54L,0x353e00e21523aca4L }, + { 0xee905af017a33178L,0xa30173d31daf2642L,0x24cbbcc728f9169dL, + 0x4e65bb13a7039e69L,0x004a11859121e44eL,0xd4efa5b91c1e60beL } }, + /* 64 << 189 */ + { { 0x2e75a26eec65b53eL,0xfeb630b270552fb3L,0x53dfd057ee7d8e4aL, + 0xb959110d8994f449L,0xb4a16596bb538367L,0xa70917bdef82f29cL }, + { 0x5a76430043bba6aeL,0xee207476cfbc194aL,0xc7eab23803a4184bL, + 0x60c67ef20f7fcd62L,0x41e05799dfa8a0c6L,0x5d7d05e604d352b0L } }, + /* 0 << 196 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 196 */ + { { 0xc97c01eb436b59f5L,0x1d15aca7ef1848abL,0xdba1ce807fa7d3c2L, + 0x69e6f96e81060874L,0x6e3e0df74d7eeeadL,0x8a3b5e85b0c87f3dL }, + { 0xc55ae3dbc8a23914L,0x5cdc2a92bf6d27d9L,0xa6008c591de7860aL, + 0x8202f8b66e546731L,0x652f2d07aa1e45d4L,0x146f214f6df5415aL } }, + /* 2 << 196 */ + { { 0x041c706cce5fb4d9L,0xddc78cb3b22a79a7L,0x7dc4cd27839e9d5aL, + 0xdfc9db83bf3c4c06L,0x85b8094138b7bd22L,0x1007dea2d0f4c2daL }, + { 0xd7b34006c633fba0L,0xa8880acf4476e55fL,0xa340b2c275236685L, + 0x5ddd05510113a85fL,0x7dfc7ab29cb32704L,0x9a334a33dabf22ffL } }, + /* 3 << 196 */ + { { 0x2fbce9bed7d1146bL,0xcec9e5d8b3980bd2L,0x48ea45939f4cbaf0L, + 0x56c540092574a3bdL,0x84a39630e792c39aL,0xe5c690f8eef81343L }, + { 0xf996760f17655bc9L,0x6009c2156c0c191cL,0xa0ca12e6966d7027L, + 0x92a6d5d52e6f7c63L,0x46809d269bd13eadL,0x3c11fa7967aac681L } }, + /* 4 << 196 */ + { { 0x3fc9b3cfabe2cc87L,0xfd8d64e3514e77feL,0x2003a58afe1ad535L, + 0xcec4be38cb39149fL,0x4d578c99bdedf470L,0xcd35d7a33a356519L }, + { 0x7a762f278b078d6bL,0x3b6891ed31ae2701L,0xdc0e817f270c508eL, + 0x5a7be2049fdb29c8L,0xfa1a0be3cb2711d3L,0x5865f55f3786a0c2L } }, + /* 5 << 196 */ + { { 0x1d0af6b52f641cffL,0xa932adeb3648c4a0L,0x67641951b1ea8fc4L, + 0xc0b90064b1fae482L,0x7012642f6623477bL,0x1cddc0245bf019ceL }, + { 0xca1f4675c2c32737L,0x11525a5e97d6b18cL,0x9c034ef2d3868de9L, + 0x0533d921044e0c18L,0xba6cf14ecb5e38c3L,0x438309f3509d7053L } }, + /* 6 << 196 */ + { { 0xe164268ec4ff9f0bL,0x6c8e9349e6c36e63L,0x734f979478ab17f3L, + 0x46d468de0179ed0eL,0x7e68f006dfa26867L,0xe4d4a85de3d0485dL }, + { 0x0913a1d7f84c0f8fL,0x4095c8c025a9c9cdL,0xeeb1a79e49eadd08L, + 0x433f5e417dd8f954L,0x70a6281430bb26d0L,0xad94d8f6ff5e8e29L } }, + /* 7 << 196 */ + { { 0x6a352b579e32c0a4L,0x5274a08277ec7a40L,0xee1f7c7a240e6dc5L, + 0x85d5be62d313b4a9L,0x1522c5d25c01a405L,0xcfa08aab960afd5aL }, + { 0xa3cb77f38e8a93dcL,0xaacb16766d1c98c7L,0x84090c7d3b93fa9dL, + 0xc77f1ee13c0383adL,0x461c93b776f7a220L,0x66d63a1d04ac0bfcL } }, + /* 8 << 196 */ + { { 0x3c7d6b644751207fL,0x65e1f96ae440c1a2L,0x8ed15d20aa0eaa1eL, + 0xe944ad2fc0eab490L,0x71525aa1f6d9f260L,0x5cd14c8816146ba3L }, + { 0xf940190814a41275L,0x3bb7ea742288618dL,0x6a4e1c37cab1060aL, + 0x357fe4d0c8cac96fL,0x97a8b8ab6a2466ecL,0xb6e83fdb9c01be70L } }, + /* 9 << 196 */ + { { 0xa55a7142cb09a69cL,0x0a39fa12896a9c24L,0xa7131a001f6c9c82L, + 0xdacbfae97509c912L,0x3793d4ef4232eb57L,0xb63d9fc0da02ac15L }, + { 0xf1ce48a09ab37492L,0xa388dbb5cf9ddedbL,0x7224ef47fd7b2aa4L, + 0xdfe18be82fd35ae0L,0x2286ae7b90a2e98dL,0xd06cfd71e0d3c2daL } }, + /* 10 << 196 */ + { { 0x7825df5c948663a4L,0xc8c093adeb4ec9ddL,0x677c51ebc1505989L, + 0x8c28421524041f43L,0x0f63f15ac9ef610bL,0xcb98841d257678c5L }, + { 0xc0560066c52c64acL,0xaf7417db954180e4L,0x935c08876fe1f0e7L, + 0x8fe556ba46d03a88L,0xec44271484a0c4a7L,0x431f8e8395be9544L } }, + /* 11 << 196 */ + { { 0xc1fc18cb3101ce6cL,0xff753902048e52fcL,0x768299554e58e21eL, + 0xac990acc32856d44L,0xaac4d5dc9f8a9da8L,0xca1740fdd4be9e8aL }, + { 0x59250846892d8bdaL,0x45f45cad19c97c71L,0xf29e2724e6ba5c87L, + 0xe441134473f6a778L,0x9f4f9027a0f278faL,0x11bb7ce02bdcef71L } }, + /* 12 << 196 */ + { { 0x0cc553bb9b3fd7ceL,0x2e0ff43ce103b562L,0x96c01f0328222a3fL, + 0x7dcc5593c10171c0L,0xc677366a4b3e5858L,0x872d4396bde4eebdL }, + { 0x5d0c5f3a7f83c0b6L,0xbf4274dcf7ba33d9L,0x1df6e4811a635f83L, + 0x24e2e8347d807292L,0x792203a8eee1e676L,0x20475f907ef4e8a4L } }, + /* 13 << 196 */ + { { 0x1b4db0579e37cd0dL,0x61b95bc9ebccdf79L,0x7d98d8537a57d7adL, + 0x58a3d639709b0194L,0x45fbd4417ce5bc31L,0x7684b71b5b3c856aL }, + { 0xb311f8f85bb6bd1aL,0xaeb8e44711eda59bL,0x1ad5b35fbf269cffL, + 0xc69651b4a0e2a640L,0x3713803bd83ad8b2L,0x613ca3af0e4b353cL } }, + /* 14 << 196 */ + { { 0x3ac59b1fff8cf495L,0x3f3726866b04c4dcL,0x2cdddf90da325f0cL, + 0x3ae79666444cabe5L,0x8222f6d6c7484b1fL,0x61fb08929ae328b9L }, + { 0x279aae392c575c0eL,0xac694019948508bfL,0x4931cc55b84056f1L, + 0x75927a688b50ad1dL,0x47ba72e945584371L,0xbea7e62ea79fe5e5L } }, + /* 15 << 196 */ + { { 0x990a6767faddc25dL,0xcd7650eb114eaf17L,0xf9d1d6409a44cda3L, + 0x70996b6871fb091aL,0x630ae9754ff80816L,0x59a9dc2f987b20e7L }, + { 0x9a39588ef65fbbc7L,0x71f4c8e598e7c78cL,0xad2f5a0138cd40acL, + 0x3c68fe575a837332L,0x7af44087155e6b4aL,0xd66f4cf8e99e31f2L } }, + /* 16 << 196 */ + { { 0x5b0b5d692a7aecedL,0x4c03450c01dc545fL,0x72ad0a4a404a3458L, + 0x1de8e2559f467b60L,0xa4b3570590634809L,0x76f30205706f0178L }, + { 0x588d21ab4454f0e5L,0xd22df54964134928L,0xf4e7e73d241bcd90L, + 0xb8d8a1d22facc7ccL,0x483c35a71d25d2a0L,0x7f8d25451ef9f608L } }, + /* 17 << 196 */ + { { 0x81e304c903b37e31L,0x21781e57925a6491L,0x4ecbad144b9250d9L, + 0xb395914345cae8feL,0xb894a39dbf775d4fL,0x8a2c1090d307e272L }, + { 0x49dfcee9408bf3cdL,0x08f0f33195b573dfL,0x23eb8a0b214bcd3bL, + 0x425e1cde7ccc4d82L,0x53f64095ac113d2bL,0x377a6cb3d88e0761L } }, + /* 18 << 196 */ + { { 0x9cd08431d360ae16L,0xbf5a73d211281e82L,0xfe25aadfcc34ff33L, + 0x8874984b84e3af16L,0x8dd38b596a65a2a7L,0x6c91112c68a26926L }, + { 0xb765168637554f46L,0x79558f04c78bf29bL,0x8bb14b1f03012b9dL, + 0xed7d03f9a0886ba3L,0x9a436ec3c2a93baaL,0x601babb740db0c78L } }, + /* 19 << 196 */ + { { 0xa7395eef391821d0L,0xb299378fc8b7b1e2L,0x53a37e3b7f3a58d4L, + 0x7d06fa4e3188c5adL,0xe65a94c063dd7462L,0x4daf74f39cfde2b0L }, + { 0x98f986b4fbe7198dL,0x8e96b1ee88176bffL,0x5f309f64eb91641eL, + 0x46bfe3352ffdca19L,0x1ea1bbe7ac8fbc08L,0xde8ca618b00f88eeL } }, + /* 20 << 196 */ + { { 0x0757ee852005631fL,0x60f484ea9d70cc3bL,0xaf131d246b011041L, + 0xe40711a1062e2e17L,0x05ccf1b94c27e2c2L,0x29e9910e43d43758L }, + { 0x54daa550ed000e45L,0xf00a312295d3674cL,0xdb006fe743ec424eL, + 0xbddf5473536162d2L,0x7b8a24b579d433bdL,0x3127a46f282297d3L } }, + /* 21 << 196 */ + { { 0xcd964573cd0585a7L,0x9c2fd35605b684aeL,0x7f600f4de4a47ec5L, + 0xcb4bcdf085fdd4feL,0x5b292292b4dcf5d1L,0x923c4331df33a2b8L }, + { 0x0fe13edfd6c1e73aL,0x0b35adc6c370821bL,0xa70061b08d405282L, + 0x98efb3fc6457af81L,0x8806ee7136e1041dL,0x8b56657faaaf0731L } }, + /* 22 << 196 */ + { { 0xe68b669189cb38d1L,0x250f59233456ed5dL,0x8928f1fe16188290L, + 0x8b24b1f734a837d4L,0x268c8c57d945d0b1L,0xa4190ceae002b3abL }, + { 0x4596e76e56dd74b1L,0x647c17871c307789L,0x0b945c7243b13a6cL, + 0x4904669552a58ee2L,0x7547a6b46e25b7e4L,0x8bc26f49e2b1b140L } }, + /* 23 << 196 */ + { { 0x95b3f4e75196d614L,0xc075bcfd5ea18aadL,0x15dc9dd41ae71f42L, + 0x75a769f289543f86L,0x06032d9ec392b4c4L,0xd6cc5c717d4df83bL }, + { 0x111fc63427ad6680L,0x770dfe7f781bda48L,0xabacb082fc0afb5cL, + 0xe3a463e771dca197L,0x390f21a89635b275L,0x3d3474b24ae094a6L } }, + /* 24 << 196 */ + { { 0x48f5588853666241L,0xb9fee3d39e6a068dL,0x8c50e3af0275e82dL, + 0xd490cf2dcab34005L,0x20b11f86bf0584c8L,0xd49714c18179e559L }, + { 0x89647b178ded6686L,0x6c4bac8cf16c93d4L,0x5401e4f8076ff71bL, + 0x577e73acb1ef9b0cL,0xa1b87e0ea46e7880L,0xab8d8bbb54fd28a7L } }, + /* 25 << 196 */ + { { 0x220161f0741396fcL,0xae14ce5817da16ecL,0x766e415bb828b19aL, + 0x1b3b239e610c7aabL,0xf1c7df4992d53419L,0x57e4cee59442c6cbL }, + { 0x546f73b5f85d33d3L,0x195116c74e041703L,0x5a71a96a5d668df5L, + 0x0adb7b16fe56c658L,0xf6be923deb563532L,0xa65ed113f2d45f4dL } }, + /* 26 << 196 */ + { { 0x8c6742e5bccd3be6L,0x5f0f7fdd378de702L,0x41236fec334aabb8L, + 0x4b15815b7e9d8aa9L,0xbb816e46e1c235bbL,0x8591cc45176c2fe0L }, + { 0xef00e3981d7104b1L,0x761d2c244012398bL,0xe4984f4ae81af247L, + 0xf923bb80c144dc64L,0xd51f27dd83988de3L,0x0ad5438d995dbbddL } }, + /* 27 << 196 */ + { { 0x0532790bd148314dL,0xb4862d9d5b6b4ad1L,0xab65bfc45beb3ac6L, + 0x72eac92d99331822L,0x2e09a69a6127632cL,0xaa1eaf0791ef9141L }, + { 0x79b923fe754ff12aL,0x19395a97f9a467ffL,0x7dcc91d49ef5cc4eL, + 0xb9019ff198a84090L,0x62616ed6d5bfd083L,0x95cbf9442b328615L } }, + /* 28 << 196 */ + { { 0x22ef6f606374afbeL,0x70e19fad26348f5cL,0x8bcd51a845f98ac6L, + 0xeeef7f7026b7ba04L,0x33aa0644544edcb9L,0x22d89a1244974c71L }, + { 0xecd08f5d0f8d90a5L,0x495a0403cf03513bL,0xe924feea27953ba9L, + 0xdfbe1f93eb5e7975L,0xd3c105a1285865dfL,0x87b8b6360886fc87L } }, + /* 29 << 196 */ + { { 0xc2da6d7a219d44f8L,0xe66364c555a9d970L,0xfb0936258611738aL, + 0x916fbfa844f7f35dL,0x7a4e0451774b1e2bL,0x7adaab9e80375e65L }, + { 0x2272b95c8ffdfda9L,0x41644b619ad42b25L,0x157026817f0c98fdL, + 0x25d4a00fffba1d85L,0x52e684c6c6c5545aL,0xba85bf2adabb7df5L } }, + /* 30 << 196 */ + { { 0x89a5b69dd282b12fL,0x63864e7ba7d28277L,0x36ac74d08c21f920L, + 0x7cfd291713a2f8d3L,0x50b63122c2ef5022L,0x23d454328ed33339L }, + { 0xf8696b2dc4880048L,0xb9605bd5792dcb6cL,0x4cdb5fc26fdeeb9bL, + 0x58ee2837f1a7f35eL,0x8956359ae2985ccfL,0x0cc6c4ab2c94cb32L } }, + /* 31 << 196 */ + { { 0x2fcac7d161a8254aL,0xc396583a05389aceL,0xc6f069cc3872ee52L, + 0x76f0e5b407180f5fL,0xc8b23b7a2dee0d6fL,0xc77b242613bf8fb2L }, + { 0xa8c625e66d5ae411L,0xc0c40a75b0723adfL,0xdee0ba8f380d9c67L, + 0x38b86a3b19920f24L,0xff2191b7d910e9cdL,0x8d01786734181894L } }, + /* 32 << 196 */ + { { 0xa704016022ec7eddL,0x19124972cc9c8ee8L,0x697f301f2ccb9417L, + 0x3ee877646f00d8aaL,0x2b5afaf88138a017L,0xf152b14c832d7543L }, + { 0x27c27ce2383052f9L,0x4746c5b5e1dae11bL,0x92dc5ac75b752008L, + 0xcf382e01e84fe5f1L,0x90e034197d5929ceL,0xafee3abb15ca3ffaL } }, + /* 33 << 196 */ + { { 0x299e0c5507f0e3a7L,0x75dac5c46cdebb44L,0x340b5479183c7e42L, + 0xfb1b03dd702672d4L,0x68f7222ec07cf89dL,0x67a471e422e7a8a4L }, + { 0x79dd4627b9ada93aL,0x774c53771c8ecca5L,0x95191e1a59db2e65L, + 0x3f6947f270abeeceL,0xb4934fe0885e4e00L,0xd082e49901728c2aL } }, + /* 34 << 196 */ + { { 0x86cd8083aaa82329L,0x74f0c5786e579dfcL,0xc2b68c4e3b436545L, + 0x8e66c648469d4a81L,0x4c5b05c5bef62bb0L,0xe558ff020bb6f865L }, + { 0x9f8ccb16f356a124L,0x1bb28d7c1279f8f4L,0x9b885f0ca8fc4e08L, + 0x2ec4cf69859d90eeL,0x9bef3c4d86d3b9d1L,0x5a98ce73eaad8d53L } }, + /* 35 << 196 */ + { { 0x6c716b179711b5d2L,0x396a4a4cb386c1d0L,0x5845f6861c157c12L, + 0xdcad516262c15d4eL,0xb6e0a6a02dadb218L,0xe4f6d5e5a342e785L }, + { 0x1eeea548c78980e9L,0x363c31be00a32adaL,0x01481fb7e660b445L, + 0xcbb61552999c1f5cL,0x20a73942f361d12aL,0x67fb89a11b8b4b3eL } }, + /* 36 << 196 */ + { { 0x1d57d639eb00e26fL,0xbeb198906985c10bL,0x38cd95a337b9b76aL, + 0x3b1d12e30304c87dL,0xdf42dc6f4734e191L,0x1ed1d9e397841989L }, + { 0xfb60e333859b577bL,0xfb026d16ed3db987L,0xa216b0e46f7855c8L, + 0x9501bae3539ebdf6L,0xd95a4a32dc8a1f6fL,0x76cb0b6b45307deaL } }, + /* 37 << 196 */ + { { 0x5607ab62a844b579L,0x8d3ed3db94f67d9fL,0x95390de8a9929b04L, + 0x4a6f6f7cc85397f3L,0xec5b73eff26eab04L,0x2543190b045699f9L }, + { 0x9a4896138cdbb723L,0x0e081e5b7a1c638bL,0x20f292c6596a7b1dL, + 0xa14d849794477dd3L,0xeeeca98064b0de1dL,0x75fdbae92c5135dcL } }, + /* 38 << 196 */ + { { 0x1202b5752b076f5bL,0x5ca1247edbd6c420L,0xb45ff9bfd8ccc5c6L, + 0x680fcfb28e061baaL,0x5a6e6342122a4212L,0x0ad12abc312fea8aL }, + { 0xd1dd8ae5665dc7b1L,0x30494dfdd9a22454L,0xc8aa9bc9da55ed09L, + 0x6ec643031b74b119L,0xf54574716b604639L,0xe2a214e59f8d83ceL } }, + /* 39 << 196 */ + { { 0xca698de5f5c96e8aL,0x352c89a3fd941919L,0x0e3de0a909812f23L, + 0xa74ba91667702fefL,0x6acfaa5a3863d479L,0x28d8932bb6bb15cbL }, + { 0xc62155704ba9718dL,0xc67a3eafa1edd692L,0xc86eeedaab31aa74L, + 0x2064ea632deb79c3L,0x813b84f51ff01adbL,0x994b9437458a1835L } }, + /* 40 << 196 */ + { { 0x1013c4f4fde3f7ccL,0xbad5415a838699b6L,0x2a8b4eac64cacc78L, + 0x3d10f949bf75d233L,0x5a9f7782fc84e55eL,0x209a18345ea7b274L }, + { 0xa66cb6d4f9e8d374L,0xf898d9479a20080eL,0xe7e4b91b1272df4cL, + 0x5b8507cc5dd136bbL,0xbe4b5262372a8e05L,0xa0cb170c2aa4a47bL } }, + /* 41 << 196 */ + { { 0x469180a38378217fL,0xd960bdde85ef6d61L,0xcc4e737d6654aa84L, + 0x28d440016ae51d69L,0xf13a0d9ac6187196L,0xe60851b392160f65L }, + { 0x41d98cf61cac48d1L,0xf37f003d1b57f2cbL,0x4829c60bce272603L, + 0x45991d4adcbdddc1L,0x17e591fe74601bf3L,0xf8a36b4fb3fe856cL } }, + /* 42 << 196 */ + { { 0x4410b773fe480323L,0x42ae32e3ea2f8b57L,0x6578a64b2886b9d9L, + 0xafcfa5fe4241ec91L,0xa7fa5afc16b4ef24L,0x4a6594bbbc16b610L }, + { 0xcb5845515e264fb6L,0x4b89955e2b9c3c70L,0x530426be21e11c1eL, + 0xb707abe9c9dab34dL,0xb5aab0bf5931cd78L,0xab6a2585f0ccfcdaL } }, + /* 43 << 196 */ + { { 0xe75761f716afd216L,0x8ff1cea3b8a4f008L,0x04b8b65e69889d77L, + 0x679bf7a586ad9fb5L,0xbe49be0b4c22b86bL,0xcc8905a16c026c1dL }, + { 0x17464e7e59ec1983L,0x50cb62832a03afe0L,0x8dadaf456ce4df91L, + 0x26cf59d1e0df6fddL,0x6ecc66119adaec45L,0x1be42e744ef67dacL } }, + /* 44 << 196 */ + { { 0xa01cb3bacb1957b9L,0x053693ccf50694c9L,0xf8a887ad527f3aedL, + 0x2f1a80ece9bf06f0L,0x74baeaa57d0eec9fL,0xce8e8b9ab0641cabL }, + { 0x91d1e84d128a1804L,0xbdcfcaec2d5fa43cL,0xfc5cff124106fa6dL, + 0x2ae3ffab01588ac1L,0xe9dcc9b44c067052L,0xd8e3d74bafa7d4c3L } }, + /* 45 << 196 */ + { { 0x64a134296d7b277bL,0x487080d8e9a50637L,0x02e5fe901c6c061bL, + 0x8fdaafc8ecabeb11L,0xb1e3960110720b13L,0xe7304bf77081f41eL }, + { 0x78a10af8c26f5cf8L,0xf52cbc155c032c15L,0x95a3c4558c0c2091L, + 0x1797b407abba6f79L,0x87c0cd05a96a3062L,0xdf75e2805f04a7e2L } }, + /* 46 << 196 */ + { { 0x47161e1f82779cd6L,0xa95afa08c8158458L,0x2cbefdbc40a80742L, + 0xd86e0bfaca420c9fL,0x08f5f8c29c79427eL,0xe8f88361da4d0d9eL }, + { 0x2195174d3eb78d14L,0x889b32c9ed6caecfL,0x1e679749c3c83ed3L, + 0xc27a8c84eddf8a29L,0x4a21af3af8e09f40L,0xf4b9797f1eb3b9b3L } }, + /* 47 << 196 */ + { { 0x58c2405baa44f11dL,0x86ffaa37ac0f7257L,0x373623cc4070f6e3L, + 0x142e62f9a36c73b3L,0x43bab2dd36a143fbL,0x4fbeb0b7aa50375cL }, + { 0xf9cc2e7b1f862294L,0x95a9be3c0abdcaa8L,0x70f050225cda074eL, + 0x152659db43e6bc89L,0x1790148727c6e01aL,0x544069354e083c21L } }, + /* 48 << 196 */ + { { 0xcb51f03954ebc926L,0xe235d356b8d4a7bbL,0x93c8fafab41fe1a6L, + 0x6297701da719f254L,0x6e9165bc644f5cdeL,0x6506329d0c11c542L }, + { 0xa2564809a92b4250L,0x0e9ac173889c2e3eL,0x286a592622b1d1beL, + 0x86a3d7526ecdd041L,0x4b867e0a649f9524L,0x1fe7d95a0629cb0fL } }, + /* 49 << 196 */ + { { 0x028bc25096c54946L,0xace5e7ad0f5fb7eeL,0xc820d7513350ab02L, + 0x4ae1f6d99c8d7635L,0x03d1f83a98e1ed80L,0xf014d45d5ad14550L }, + { 0xeb8f2c328cd6d0b6L,0x090a8f71770f586fL,0x1a8219f93eb7d3b7L, + 0x0d610d9febfc26dcL,0xfdb49980aa330297L,0x6396f218d81b3fbbL } }, + /* 50 << 196 */ + { { 0xb4ea3102eacb7b9bL,0x4aefb43d72af1d6eL,0x9a1a912d249a51d6L, + 0xddd0a5744d5e3a1fL,0xe252114708aa1f69L,0x4b235efe9de89d5dL }, + { 0x6fae47420d7f1aa7L,0x0434ae2ff200e13aL,0x75143dc192508b57L, + 0xc441a768055e177aL,0x84cd7adf2f142b2dL,0x56484f4161d9ad5aL } }, + /* 51 << 196 */ + { { 0xe3e9d0881beecd14L,0x4bd12b179093ab18L,0xa6908ddbc925d5dbL, + 0xfdc5f740832d1474L,0x1a35623696f831afL,0x0e39086808cde8c9L }, + { 0xab1c7cbda2206b32L,0x84d299c8b93ccf1fL,0x380fa432dabb6542L, + 0x59f01b5177c2cb3dL,0x9785c47b6e56c4bbL,0x047acc813a3f2b1aL } }, + /* 52 << 196 */ + { { 0x724210e61e42b4a7L,0xa8d536afe2dd968cL,0xc69936e683582c60L, + 0xd031f1abdd5d7f68L,0x7d31dcae8c4180d4L,0x117985f622bca188L }, + { 0x3b0a982537e38dc2L,0x1663fdc5896fe4b4L,0x55d18cc7fd707372L, + 0xfac2d7a40d2d8470L,0x994763391b04b1f6L,0x87cfbb5ee0bd72e4L } }, + /* 53 << 196 */ + { { 0xeac6a72ad5dd2841L,0xf1aa32524277e152L,0xe6c44e9b6ef7e947L, + 0xd03309fc54095378L,0x6fc5fb9ccdd06947L,0x10ed0e76d1e9a968L }, + { 0x42d5ab02dfb77b17L,0x4c54c381a53de8ccL,0x5fb4c256f2b1b5d8L, + 0x17d5ab28e12ed054L,0xd7c96ce1139da42aL,0xb32f63859919f459L } }, + /* 54 << 196 */ + { { 0x4bf5788312f4b0b3L,0xcd69d82ef46735faL,0xc397c8f9a1baa0efL, + 0xfce184c0fd1be398L,0x15021775fa54580eL,0x10bc85468f54397cL }, + { 0x6009a691eaa9d711L,0xc9c6a42fb7846417L,0xe9c305685627817dL, + 0xa1be66ff92abd5daL,0x9317838fcdea11c0L,0xace94ddcc85e7aa5L } }, + /* 55 << 196 */ + { { 0x3ef37821d4079bf4L,0xff78abebfcbdc3d0L,0x117414bc4733ea34L, + 0x7f181a3b9f50d0feL,0x9ea5f94eda897ea7L,0x01a996ceee8314ceL }, + { 0x0cac3c8b420e988dL,0x7ad66ac4bed3294aL,0x6bbf6dd800b62445L, + 0x590a57017a2fb4fdL,0xbf3b4e529ac11d81L,0x1bd453020d60c710L } }, + /* 56 << 196 */ + { { 0x8a43bba0902c32d8L,0xd8c69b74a3955e42L,0x413bf25d79c64afbL, + 0x3c39837584ac94cdL,0xfbfa9c53a08ccf5aL,0x9d8ac945e9d791d4L }, + { 0xfb9bb89e5e7a2553L,0x1442612bb039dd24L,0x8250ffe0a2e2344aL, + 0x5eae8b396426b985L,0xa1657768484741deL,0x05e52d4ac73cdf8cL } }, + /* 57 << 196 */ + { { 0x61c2417995c5e767L,0x7456380c3bdfef62L,0x62763f43d206cbb1L, + 0x1996e2c657871e44L,0xd0dbd290f220c06dL,0x6778e1e5d87743eaL }, + { 0x40e54caf16b8f046L,0xe834a1cb6bed77daL,0x7240befa3e9457c4L, + 0xd1b638dbac96cedcL,0xd1d7e814c9c0cd8cL,0xc73beaf14d38258eL } }, + /* 58 << 196 */ + { { 0xf1a6d776c05f40feL,0xb98c19b1c21ce471L,0x700b0bab7f9689eaL, + 0x861513a56f1d2e6eL,0xb7558b2292fe4456L,0x2d8f860704c66a25L }, + { 0x10ba7d6a7998347dL,0x72bf56093983b98dL,0x8d873c4f89238292L, + 0x5db0dca9a5e3c944L,0xf81fe37e0925aef0L,0xed6a13a4e4daae25L } }, + /* 59 << 196 */ + { { 0x49e2372711c3a930L,0xbf2ede34f5293b8eL,0x0abeeb3ca8e1cc9aL, + 0xb1db299440205cbcL,0x3252d29e52fb01d4L,0xa0b080c57dc91095L }, + { 0xb56fdae622a9ceb9L,0x6c3c3463b31f6f27L,0xcb510ec2ae3bd22aL, + 0x1efcd77b0b3db475L,0x1094bcc5ca766f9cL,0x688e940dfea48297L } }, + /* 60 << 196 */ + { { 0x3d95d26a99cde27aL,0xed608a89b99344f4L,0x7a70a8f09c0ab25cL, + 0x7740953c496552d8L,0x4da4ca0f4a366adcL,0xbf475c1b33274d4fL }, + { 0x5ac1d8288811b869L,0xed62e7b4d23446d4L,0x67d78571a0eab287L, + 0xa74ae3e98b0acc4dL,0xa63f91d64077c236L,0xe2c3f82a818a6889L } }, + /* 61 << 196 */ + { { 0x2bde7037b1d5fbeeL,0x477a4b51a80b92f2L,0x195ae0e06606b504L, + 0x7aaf3de57497785aL,0xb5581ee9290c5ef9L,0xcb303c30360c8ec2L }, + { 0xfb056f901b1fb602L,0xa38bc9f59931b7ceL,0xb0b74aeab2f453a8L, + 0x9a0e2ebf668cd68aL,0x8b7e0d73d7db7842L,0x21f29b74d1fa5433L } }, + /* 62 << 196 */ + { { 0x38321d7c4e11f824L,0x04dcd3a3e4a816e9L,0x382968ed07e09612L, + 0x6f7b2dbfa370e1d1L,0x5a8472348675d730L,0x88d974b0e59e984fL }, + { 0x89f7e2bce3f9e429L,0xd478eacfe3aebac2L,0x8df9f281ebef3488L, + 0xcbcb9fbeab5543b3L,0x2c8d19b0203f59e2L,0xbb98e4495287b0fcL } }, + /* 63 << 196 */ + { { 0x16c45f709aab81d7L,0x0f1310851795a4b7L,0x3c63d43af0ecd732L, + 0x22e2d1988628b683L,0x7d7482bab641d6d4L,0x6baef4a2ab69891aL }, + { 0x10989097e63c00d2L,0xbfd42ab0d93794ccL,0x9a1935f3e4165a41L, + 0x359701b35b600ca7L,0xbe7d69f983d1b54bL,0x99b0f35e3729bd4aL } }, + /* 64 << 196 */ + { { 0x11dd860e1c6d03b0L,0x30c1700809eec660L,0xd4f8aff635c0192fL, + 0x96a727b1e3a4a900L,0x1426daffde78c8baL,0xfacaa9bd8d1527c4L }, + { 0x0c0d5234cd072989L,0x1936c20d918550b5L,0x4828bee43d914fb3L, + 0x8324ea38f3ba26a6L,0x027590f3a94eb26fL,0xfd354295acd957bfL } }, + /* 0 << 203 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 203 */ + { { 0x3ede2484da756624L,0xb22da2ab73b13062L,0x56069e93962a667bL, + 0xc931266b130f2ceaL,0x4bd6a6fca7366a66L,0x23f30563aa5ac3b1L }, + { 0xa025d0efd7c2b26fL,0x597ce7d862129bc7L,0x4809927f2b3057f2L, + 0xb001c10a1499f884L,0x309d141c30b9a653L,0xadddce7dbf659d05L } }, + /* 2 << 203 */ + { { 0xa6c32900af2825c1L,0xb37c46c1d223a04eL,0x691e7d39063de7eaL, + 0x998df4e710daf9bdL,0xc7085b9e718b5d7aL,0xd41abcc816b3d4b8L }, + { 0x4dfce693f9bc4041L,0x383677ed659ec7a8L,0x2c1904bf4491fb34L, + 0x7c1bf1114552451cL,0x6562cc2c3c5e5e40L,0x1ecaa2a1fe0e4372L } }, + /* 3 << 203 */ + { { 0x9657d08ca9cb9ecbL,0xf69662363b75be69L,0x396a9344a31c2b8cL, + 0x1c50b1269767bc1fL,0x597223d0d1417e03L,0xe165ed5a12137153L }, + { 0x8bce29f926a24098L,0xc428a1fbe99e7bf8L,0x6fd4c906eea7f1d9L, + 0x94275713fceb2e05L,0x3555448b741dbd94L,0xc50e85459faffd4dL } }, + /* 4 << 203 */ + { { 0x84c3630bf3087bc8L,0x152691e674be6e26L,0x5abd125ff61af001L, + 0x69bca56fbfea3525L,0x384af19900e0cb6eL,0xb0b13cfed00475a6L }, + { 0xedafde495e394049L,0xd988b558daf2add6L,0xf14cf97a6c8ffcc9L, + 0x4d6cec23e5a9cc5cL,0xb0d678f88a104e05L,0x80a7fcba9fb527c1L } }, + /* 5 << 203 */ + { { 0x9ae12b902af1ffceL,0x082f30b95a30521dL,0x974099bdc304014bL, + 0xab1e27e444ccb6e5L,0x72db8f42290387a1L,0x3d1a461040f3ce18L }, + { 0xe939a3f2634ba10fL,0xe70a9cf517254c56L,0xd0f8692fa08ec3c5L, + 0x77edefcc7a7cbdf8L,0x04c4b18ebdf90f0bL,0xa890436a8aa36a59L } }, + /* 6 << 203 */ + { { 0x8618ffa79e30f8a0L,0x9961390cd12699bbL,0x5b1b0d744f61edfeL, + 0x33df67d9eb7a476fL,0x7f1a767ea92ee99bL,0xfab400e32223a2ccL }, + { 0x16f376f2f534dc3dL,0x6f36eaefcec17905L,0x8dc1516ca58765deL, + 0x893408262260ed6bL,0x060eb0afcf4b29baL,0x9cd0a9f11d252bbaL } }, + /* 7 << 203 */ + { { 0xd3c2a6a8ca413693L,0xcc56a8e932d5714cL,0xc72b73683c0da165L, + 0x5d236660db44e616L,0xa83b2ecce5c73667L,0x9d292f298aea900cL }, + { 0x67121215aaa2a7eaL,0x57dae96abf889191L,0x63bf7a81d296ae68L, + 0x9bf518758fd496c4L,0x5b4382fbc2f7308cL,0xf1215dfc9632aad7L } }, + /* 8 << 203 */ + { { 0x0d6cadbfc22137d2L,0xb5db59d3628a3298L,0x3b433c734ab19507L, + 0x4fc53405660086b3L,0x770ae903a1eb0f43L,0x31b5857ef6b5b58dL }, + { 0xe206e141d392868eL,0x8be6956f4b31de04L,0xcfbfca2f47449e07L, + 0xebaef25639fef8e1L,0x959e37b8c16fc80cL,0x8bb4bdd2e911d61bL } }, + /* 9 << 203 */ + { { 0xecfb851380fc41f3L,0xb0dc8823931843c4L,0x59decd6c1b93df03L, + 0x954103b72511e252L,0xe372f86a0f759de1L,0x04f5afd38f6f9ef3L }, + { 0xbd8e60affcba2e7cL,0x9b1cb1ed092315b0L,0x5f9e20a03fd05e36L, + 0xfcdcc44ded95f25eL,0x6baf401b6ac79cb5L,0xfe1a5a856894f651L } }, + /* 10 << 203 */ + { { 0x014a0907e51c6673L,0x28118ccd3e6e6a91L,0xdbbb7c4dc999acc0L, + 0x01b771075e7ab1e3L,0xa33fefbfcd8fb11eL,0x1df5b61fc0b8a5c2L }, + { 0x774dc2674478c5c6L,0xbfe1add422fb91a1L,0x5ac4dc694d9c8461L, + 0xbf6e002a1e772c5fL,0x4922120e0b83fe91L,0xa7747f4b3efbadceL } }, + /* 11 << 203 */ + { { 0x4b955beaddaf2e82L,0x3775ecde90fdc68aL,0x579c34f91713e763L, + 0x6c27f504fa509d74L,0xef6df04a3f8dbf4bL,0xc39f2e28b3ad7104L }, + { 0xe54042b3a5973cffL,0x4e594427f111f3d9L,0x53c7a2ba155fce57L, + 0x7b3c1c60e6e1d21fL,0x5e12db8d308ddf4dL,0x2c3c5e77a00e8976L } }, + /* 12 << 203 */ + { { 0xc483d4b24343bbf8L,0x42aca2e18a0fc95eL,0x5165df6fcbab1fb0L, + 0xeb284370f6cdfc0cL,0xab565c00994320fcL,0xc0d157fd62133e80L }, + { 0x7850cda55b69644aL,0xe37ae76a806ec8b8L,0xd14b805cc2c82eddL, + 0xcb5468b6cf244539L,0x97d43ee825dbe92dL,0x1442243689fb8f1eL } }, + /* 13 << 203 */ + { { 0xcfc8a945f361dc08L,0x383a5336491dc3abL,0x77580587c35cd376L, + 0x6604248ae2426904L,0x47c56025ffeb9d26L,0xc301edd8bae5d983L }, + { 0x7c6511a9e2e5cf33L,0xdc52c1dd221d41acL,0xdbdc8acada47503bL, + 0x01b406864bcedbbaL,0xca9cb9fd2d5496d5L,0x5768e0edb17e8400L } }, + /* 14 << 203 */ + { { 0x421afbe0431cb760L,0x9ae9ff985203e69bL,0x56cacf4db1a2705aL, + 0x6a3a4136d128bcd5L,0x2411c4b866191ad8L,0x39f26e1a15b45d24L }, + { 0x4cc82459c64ed153L,0x5c7a0dd58195b452L,0x9c88bb1c69f6298dL, + 0xfe567b031933fdb5L,0x8a6aea71881308c3L,0xc1268b55a2f0adfaL } }, + /* 15 << 203 */ + { { 0x312b777c1231c557L,0x3984f71be9971115L,0x0266b58294cc2d4bL, + 0xc3058419cdf5e5c1L,0xab3a1ae477bbf0d8L,0x7c2173a6d21603daL }, + { 0x61cca8cc747b092bL,0x70f77a53e376506aL,0x742c20692f1ccc85L, + 0xb1f2ceca2dc8844bL,0x5a73cff83a096c10L,0x28acb67d5c19cd11L } }, + /* 16 << 203 */ + { { 0xd7bf2ac6a0a85236L,0x2921b55c7194c46dL,0x162fabaa9afa9762L, + 0x7b7f1664b62b36abL,0x77b9f797296a84e9L,0xfcc1ad657dbd843dL }, + { 0xc6e9c1e1cd77b7f6L,0x9cf0e272917067c9L,0xfa7fa93d3bfa90bfL, + 0x55846fe9d050e46aL,0x473b9a0d35c56256L,0xadd29e332b656a65L } }, + /* 17 << 203 */ + { { 0x4698137f46fb8ae3L,0xb11a595f7b1c062dL,0x4a043b99ff023ef7L, + 0x2836d64d8ef0fa4dL,0x4067dbee8ea44a98L,0x9d1739c9f00ff4e1L }, + { 0xcbcf12fe133d2703L,0xd2923424016037cfL,0xda7543d68be5f666L, + 0x587d1920ac5e1847L,0x14662476f79e3462L,0x0120a1d8c810a1f3L } }, + /* 18 << 203 */ + { { 0xa4fc828ab18f9bb1L,0x06de4c9da27a787aL,0xfbb7c7d7b1b3a12bL, + 0xa7052b94b8583128L,0x173ec2d2e7b02fd8L,0x4b724682c776c664L }, + { 0x46ed9be5673183e5L,0x312191e83bd17c60L,0xe3ed6326efd56a9eL, + 0xb3ebc44c943a2278L,0x7ef62ba9ec9cf589L,0x754be6d389832cd7L } }, + /* 19 << 203 */ + { { 0xccb4b369dc992b32L,0x0ef84cc0922cee22L,0xda0058f1fc56e9e1L, + 0x208c57943f23632bL,0x3589a7338f77a82bL,0xee6cfa2c76ee99bdL }, + { 0x88cffafc418f7993L,0x0dde3f05f4be56d6L,0x5d088382a0472bf5L, + 0x872ca5aabd58d05dL,0x9c467c62e8f91f17L,0x38ab1b348c6b91ffL } }, + /* 20 << 203 */ + { { 0x926c2552ebc69b0bL,0x953a850fd4c7432eL,0x0ee85e14b9359035L, + 0x8b10b01abde090a5L,0xb2878dcaec423943L,0x2571a178f70bde20L }, + { 0x24ed159af5ebeee5L,0x60c202af043f6539L,0xdaaa76f4c8d4ffc3L, + 0x2fc1f1ba06eda10fL,0xddf159ee88ded556L,0xcfa71782e67b1ec4L } }, + /* 21 << 203 */ + { { 0x2596ee7409d3ed60L,0xd42551f474a46e37L,0x2e46a92e21061c90L, + 0x236299fa73ad22eaL,0xacdccd5214393ac2L,0x9a572130b56b4d5bL }, + { 0xddfc31781835e70bL,0x5dac0671d542048dL,0x2b0768d7a6dce17cL, + 0x6d447d4206c55342L,0x6b55b21525548478L,0x24e6483518d5310dL } }, + /* 22 << 203 */ + { { 0x3c58c5ea9b037c66L,0x08d0648e0d5c6ec5L,0x1bf90c53a4fa3f5aL, + 0x660cf61740381205L,0x63fd03081d44af3fL,0xe22b9c1a77175de7L }, + { 0x0b6044fc3556fc9dL,0xaefb6804fb55318eL,0x77045bce5c46e1ebL, + 0x29c4a3bc76e8f93aL,0xdf8aec699d697f5dL,0x5bd9552845a89080L } }, + /* 23 << 203 */ + { { 0x1bd61fbdc5756910L,0xcfcc6d5adeaca40dL,0x292867885dd80ac1L, + 0x7effe328d621c0a6L,0xc64ebb91ab22a2b5L,0x8954ab330c44a456L }, + { 0x7552a0b460e26218L,0x2e81d3a94136adbaL,0x96dc2451610d665eL, + 0x30859c62ab04e03fL,0xdb3726fd4c31fa3fL,0xbf4954d1d962a7c4L } }, + /* 24 << 203 */ + { { 0x31521f66d5d826b0L,0x0a63695240787844L,0xc0a3bd059c8f934eL, + 0x12c57dd42f0ce835L,0x847f6a9967064213L,0x1c9e1a7aa88bd71aL }, + { 0xc4060eb2171e8407L,0xdf78d8dfed106780L,0xa3d28ceb0d704729L, + 0x4f8e523246ca3912L,0x09e9f852017791f4L,0x594006631e6ea97dL } }, + /* 25 << 203 */ + { { 0xdd26fb79444827feL,0xbf78e076d3f5fa6bL,0x46d486e81a5475b5L, + 0x43e325a5faabc3f8L,0x1fef6b6ba6795d0cL,0x40e040666644d631L }, + { 0x16207bb9676c3322L,0x677c1c235811706bL,0xb686252e994e2a95L, + 0xa359e2a51b6f6a3eL,0x6d8f06cfb124f019L,0x3bcf778246266c42L } }, + /* 26 << 203 */ + { { 0xeaa3426b8eb929aaL,0x090924f2327bb35dL,0x4d23ba1276da394fL, + 0x05d98e56adecd43fL,0x83c7169f6b4af795L,0xc22560a7c8f26ae8L }, + { 0xb43aecc2d01ab5d8L,0xe7bcdc1f7257d7d1L,0x6f32d77650de3318L, + 0x6d736b279bf02c0aL,0x9534fa5865319235L,0x5a6a38493cfbeb3cL } }, + /* 27 << 203 */ + { { 0x3ddcb65828c50956L,0xb335f336bf1bdb4cL,0x7c18d2d0ac3b6194L, + 0x8748654bca324d11L,0x7c9c58dac2e85f94L,0xf1930a56d4f4f957L }, + { 0x9cacbdbbe410fee8L,0x0e292c2178e1312aL,0x6845b293906a6270L, + 0x842ded0f00c5401eL,0x747cd08f35e3ff9bL,0x8405540af48227feL } }, + /* 28 << 203 */ + { { 0x547b0d9583939224L,0x3a0823ff1e026769L,0x6016671525bd43acL, + 0xb6cf475e18ba5f64L,0xa22f9c92c8b6d09dL,0x730553683ccf50abL }, + { 0xa6de248eee6deefeL,0x32aaf8b2acc3ca20L,0x0e254c5bad44e674L, + 0x8aa73e6535f95f98L,0xe622600160a2dc1eL,0xdf9482109109020aL } }, + /* 29 << 203 */ + { { 0x7b24d7b056190aafL,0x0115cbdd0563b377L,0x5688526ca7ba4975L, + 0xd2971e28aee3100dL,0x57a6ff8a6fa24f61L,0x9cb571c4d8603be7L }, + { 0x09c01564a2cce6d5L,0x14f0902b89884939L,0xd71a5ff8a072ffecL, + 0xee7848b8fefeab69L,0x7b52a9577e40895aL,0xd1576be7e8c61be2L } }, + /* 30 << 203 */ + { { 0x4c4d454849d77b8eL,0x431f942f6a4c982dL,0xc8633d051cb39ce8L, + 0x23421f8caf516f9bL,0xc9db25d2aac876fbL,0x9f2669c5d882760eL }, + { 0x59dc4bf4c47d4bfaL,0x99ed0024c475f93cL,0x269d1ca4ebe07d37L, + 0x49ce3bdbbf88b1faL,0x515044053361e4ccL,0x207f0048735b3c96L } }, + /* 31 << 203 */ + { { 0x835fe90b5a516e82L,0x26f1f2a7abfcb383L,0x3dae65a8609c4ac0L, + 0x70b01d6e91f4054eL,0x22da015b581e3159L,0x2ad34f99329d1ebfL }, + { 0x7385aad60d09b845L,0x4cbafb0b0adf42f7L,0xd8727d26c02398cdL, + 0x58c261f590549db5L,0xd49b12e48ea70310L,0xb31eea047ef89773L } }, + /* 32 << 203 */ + { { 0x372798f02893f2f7L,0x4f62bfac9e5030caL,0x5e64f9a98a1e2567L, + 0x5870254ce70391c8L,0x2def81a341f02458L,0x25d4e4dc1d087bedL }, + { 0x3557d07d4fe24a13L,0x6da49186dc3112bcL,0x08c8c5675f73ba50L, + 0x5309050b9c7c6706L,0x2ab67da3bd985072L,0x9bafa8b1e5df4e96L } }, + /* 33 << 203 */ + { { 0x5acdcd216f77738eL,0x340710746cb67a3eL,0xd68c55cf4bf76bf7L, + 0x64c159200b4deda8L,0x1021d38ae242b1e0L,0x615f1f033bd3d95bL }, + { 0x2ae0245cc300c9c5L,0x3549605ba88d63e2L,0xfe0dd65ad5038849L, + 0xe67abfec63c6e4aeL,0xccd08ba528153bdfL,0x9be9f5bced4d76bbL } }, + /* 34 << 203 */ + { { 0x30fe00bb6e8423deL,0xe16ce94784e4d005L,0xaf0f8c283fed764cL, + 0x05ef9bf67d92b1efL,0xbf6570d4eb481da7L,0x39349e30468494ebL }, + { 0xe32b99a63fb36907L,0xd92386da2d35e71bL,0x74af8b79166a973dL, + 0xa0a177f94f72de6bL,0xfff3e19d5dd6c660L,0x15310d4d4b0d54f0L } }, + /* 35 << 203 */ + { { 0x692a561f15c15a11L,0x25abe85f26ca3ddbL,0x50fef4444caffa5fL, + 0x58472cfbed3f4aadL,0x7e9178f0092d2b83L,0x3afd364ff8dfaaa7L }, + { 0x4686ee5cbbf813a8L,0x6a62687d937cbae4L,0x56f22558a9b7b6c9L, + 0x9af1beae9c189e25L,0xfac4ad9f4d41f79eL,0xdecb57431f9c7a40L } }, + /* 36 << 203 */ + { { 0x3ac662895c02f173L,0x6a110e3876d566e5L,0xd9cc14e2b9577e26L, + 0x6f3d5df9fdfe617eL,0x8fac740f352bb2caL,0x50bc8a0cc28e6310L }, + { 0x6e572fc477ac93f7L,0x56277377605bb8e9L,0xad6d0637402b8c55L, + 0xdab377914509eda7L,0xae770abc0854e91bL,0x523bd278742b3de8L } }, + /* 37 << 203 */ + { { 0x8ede0eea2aa0da2eL,0x7015ee6e90cfeb90L,0xef33f3efd6b3227aL, + 0x6e332f1712ef9f4bL,0xcaa089898e7f9fe9L,0x001482ef8fa71529L }, + { 0x2522637907a5019aL,0x807faf01bed40fc9L,0x426002ab56710e12L, + 0xcdfffbc18d3949e6L,0xcc03f27861284379L,0xcd7dc2026d5edc82L } }, + /* 38 << 203 */ + { { 0x94f84d57cff31148L,0x9c567c7f6bf2a313L,0xc82e62353149ad8fL, + 0x81f69703c2a5d513L,0xb54e6fc756eea9acL,0x6799c7957c3aae62L }, + { 0x78e89c1edb280515L,0x3c5693066ac42925L,0xd984c86dab063cc4L, + 0x61754b5151d44ae3L,0x23af8ec0cebeef0fL,0xff67170bc618fe8aL } }, + /* 39 << 203 */ + { { 0x123b567195b58447L,0x7397316ad43aabd2L,0xcb65d69d9ddc7979L, + 0xf98be7bd91150e08L,0xa5388c79fc0ae5c7L,0xb115690215ed9074L }, + { 0xc2d01b9227e9afdeL,0x80d705ec2095a6ebL,0xbea901c7fab23079L, + 0xced8b2772346d712L,0xad5c45a92542a0ffL,0x87b2e4ac0455e90fL } }, + /* 40 << 203 */ + { { 0xc2cbd64417fecb90L,0x61616eb3b32dffdbL,0xdc4485a29f5d2095L, + 0xf78911246553371bL,0x4f06ba18bf9b20afL,0x136d4f291a2c4df1L }, + { 0xc04aca34fb8b685fL,0xeec83c20f2b657bbL,0x4da5d70a5925a36aL, + 0x8060874172ff2965L,0x2e0dd9ff9f352620L,0x5f0afa6746d1a7a8L } }, + /* 41 << 203 */ + { { 0xb76c722762c1e582L,0xbce1eb164ffefd05L,0xa574a9fe169e53fbL, + 0x77bf92b0c001628eL,0xd998172c04d60440L,0x62f35199ceae6bf7L }, + { 0xd81a563e93f1ff84L,0x5a7a0b4211598ad0L,0x884f2ca5ff11f3f8L, + 0x99f5aac2f3ac66cbL,0x58497c01f489c5afL,0x11277bc39566521cL } }, + /* 42 << 203 */ + { { 0xfb9670c26a770385L,0x5da887e1e9682174L,0x31fa9d6bedf922f3L, + 0x8de8814cf7a98d1eL,0x3935b9b27a019f08L,0x1f59d6f3ea6173caL }, + { 0x8732f39d5c638a66L,0x981a1b7a3d48d3e5L,0xea451b381ee0ab37L, + 0x31a8e9abf2708356L,0xa491944ee86cbfc1L,0xd747a885a97ddfcaL } }, + /* 43 << 203 */ + { { 0xa3460236aefd304aL,0xaac80f43c58719a0L,0x7d635c17d3ca5b1aL, + 0x986ac0a62119976aL,0x0d8a6e39f2538d36L,0x6a02af2f31849d5dL }, + { 0xecb6ef8f6719d4deL,0x6dd71ab674ff8880L,0x0d40ec0e9d225d93L, + 0x304cd88adf381d24L,0x2d6787380c5571fbL,0x03c23f547c03af94L } }, + /* 44 << 203 */ + { { 0xa995a95bf46aace5L,0x44ede5379eaa630aL,0x421f3b3500336e3bL, + 0xbf897478cf47c9edL,0xf360ae32259e0827L,0x04e0e3e82e6a9f6bL }, + { 0xb26eae5fa9136702L,0xd6cb15a1853674b4L,0xf81276e2748bcbc9L, + 0x7fc02e220a4ca1d7L,0xf650f48ecd82f330L,0xf4ea7c1dabaa8859L } }, + /* 45 << 203 */ + { { 0xe9f090b935caae35L,0xe04dff188dcf1e6bL,0x81b7de5eb8032e04L, + 0xba0d0b4e4b1e8070L,0xaa82dc8ad1a2aeb3L,0x5855ed1ded26f229L }, + { 0x8bce967ed1955233L,0xe6ed07f356ac7532L,0x4227c7fdbf0eff2dL, + 0xb1f4785fa5e213e4L,0xeedad0733ac30f4bL,0x503619889cf1e686L } }, + /* 46 << 203 */ + { { 0xeb252116ba5da79eL,0x51cc937edb691345L,0x1d5fec14077458c1L, + 0xaa304f7ba0808e6fL,0x4bed89f5abec4c09L,0xc67293cbd1a3b798L }, + { 0x0905f7d342122672L,0x83675b2da0d3a277L,0x7f422b7024bf5bcaL, + 0xe2144c6910495acfL,0xdac1c357a6a6ab5eL,0xd1a3b951c8b1d472L } }, + /* 47 << 203 */ + { { 0x0821017d60c0c248L,0xa17ce97a8540bdc8L,0xe0576ea986e6f45eL, + 0x1453268bf152c6eeL,0x1ea1937138edbed5L,0x970ad9c002343c23L }, + { 0x3a08a859af8a97afL,0x20caf7cab570d738L,0x6d82d863e2a89455L, + 0x30eb8d0724c76844L,0xb31d58c8d32b79f1L,0xe5df7cb9fe63e93cL } }, + /* 48 << 203 */ + { { 0x1ccd44ff95c746ecL,0xe18914b510405763L,0x50ed644321a3a927L, + 0x4f96a1b143ef8e8fL,0x7f5645e577952bf8L,0x4bc5c7ab66dbdf15L }, + { 0xacc1612623930a08L,0xbf5ed482504cf9b6L,0xdeb7a798d71ecbd7L, + 0xf62e63b14a4dd859L,0x668809a7daf714d9L,0xdd836382f3a4329eL } }, + /* 49 << 203 */ + { { 0xac0ef2cf383e038bL,0x848e3c1f91135098L,0x19e5a3ee3f15b241L, + 0x2d01f1a2dbea2ad2L,0x44ec32a799cb0bdfL,0x3e66fed4eab4d856L }, + { 0x3162a75af45c8656L,0x53ab74245a37ca4fL,0x1b81f1dc360bb395L, + 0xa7eb222e2b8a5267L,0x163bb0c804b0bcaaL,0x1cac5bc0ef5c417dL } }, + /* 50 << 203 */ + { { 0xb95e2d85e81d9e43L,0x8a92acdd1418f6d8L,0x5429140110ee43d7L, + 0x32a2933c625838dfL,0x801d57dd3d485868L,0x33bba67258af765dL }, + { 0x545fe2583f520eecL,0x900ed51a32d71974L,0xf21fefe6df3ed77cL, + 0x2f0df28c9deb2d81L,0x90898dd780856fb7L,0xeba82159bbba4771L } }, + /* 51 << 203 */ + { { 0x83ecc8f374df3780L,0x432e9807d3a89728L,0x3461c5297b5cb6e0L, + 0xee307c19030c25cbL,0xd72b60c7391ee616L,0x0c07bf462e9b4384L }, + { 0x9d791b0bd44acd49L,0xf3b3411c9f3b33caL,0x1bf55cb97f9b455fL, + 0x77e01607600f0a91L,0xdab95bf26bb7e977L,0x30d0f591fe4633e5L } }, + /* 52 << 203 */ + { { 0x894bdbd9c48f3ad5L,0x687ff8de09e167f6L,0xf06104a930371c43L, + 0x82fd34b7ce84dd10L,0xae122deb66ce5abdL,0x31f041d2fc4a90b2L }, + { 0x2589535c9a01c607L,0x231bcc85695bd7abL,0xc67c306262e3a31dL, + 0x31be44757af3e186L,0x1a2077a388efa7f1L,0xffe53e22815fad1aL } }, + /* 53 << 203 */ + { { 0x4ce41f69a3ee310bL,0x38fb07d09bf311ddL,0x5fd284d660985bd4L, + 0x2fe99a19e04d3dffL,0x21a352520b3ad853L,0xb0808a89012aa69cL }, + { 0x98219cf718c7c301L,0x429e08fc91254db8L,0xface2e53c41d54d0L, + 0x180651242decb2d7L,0xa9f65e3f26a9191cL,0x1dadd3deed42831cL } }, + /* 54 << 203 */ + { { 0x81ce91dd6327460aL,0x4cc880a0e2f22af0L,0x81aa9bb46a6d36f3L, + 0x8ad516741dd10657L,0x212267854253b30aL,0x530d1f6a8f161dd6L }, + { 0xe7eeb4c7e9ab63aeL,0x84f225bfb72d250eL,0xc81cb984458a8dc7L, + 0x39fbbe3bda68c1afL,0x8c6c99b3083cafd9L,0x4700ba37eb07d40bL } }, + /* 55 << 203 */ + { { 0x8980dd7cd8dcc7b4L,0x0179e9bc7ad18f8dL,0xa9e4fa6a08c60f0aL, + 0x4f0d76fa3cc7dd36L,0x53339e4c51a0e67eL,0x1acdaf24cebd80cbL }, + { 0x5aaebffcb5264b96L,0x3ebebb22858df87aL,0xb2f4c1cb092a95a1L, + 0x34932d51841b1a63L,0xe0631aab49074a2fL,0x71525c4fe3b7fd61L } }, + /* 56 << 203 */ + { { 0xdd15591366229776L,0x84093730f7882064L,0x6dddcb14e50ee337L, + 0xa8e6ec597a1f7e81L,0x8467f998f3738a6aL,0x70fcc6bcad3f1840L }, + { 0xf82eb4be723b3f4bL,0xf0f3935406beec1bL,0x1b181ea37ddcb539L, + 0x9c82c4faad6a81b9L,0xcc5ea5435c612c2bL,0x63ce7571bb258d6fL } }, + /* 57 << 203 */ + { { 0xc6c110ecd3b9416aL,0x254403ea024f63e5L,0x92d2965b68aa4a66L, + 0xa08bfaafbaed92aaL,0xe2194cd701ad3eb4L,0x7ba66e1da7552847L }, + { 0xf68c90ee44eb9bbbL,0xabe38c5c5f6438daL,0xe16d4aa68c38a6a1L, + 0xc2f8691bf6294db4L,0x9248492fba64da6fL,0x850c6a6865a3d6b7L } }, + /* 58 << 203 */ + { { 0xa794308d2599a1f7L,0x06bbefce3e72b328L,0x24f2c6f5420f6ae1L, + 0xedf67defaae894c0L,0xf66396eb2e8e9821L,0x21fbf5f7a701c8ceL }, + { 0x7fbb192401732f26L,0x3d0063a944f57696L,0xd6bcb1c3513dd8f7L, + 0x1fbb11b2c9f8c033L,0x122f94b17b57b3eaL,0x08edce19d24626c0L } }, + /* 59 << 203 */ + { { 0x06aa75398c3a1e9cL,0x3512ec3c1a08c7caL,0xfad0dddac5a92e6aL, + 0xa98059ee3b9022fdL,0xd67b6723103fbda5L,0xc1df32904762c170L }, + { 0xfd99ee58c734f81dL,0xa8de2a4b478b8a4fL,0x9e3ed58fb4b557c6L, + 0x14d353c571abd10cL,0x10ea798fe3fd4475L,0x157e16f97627f4d5L } }, + /* 60 << 203 */ + { { 0x1b5888550b96547fL,0x4539c9c065d1a59dL,0xd6c95fea26e15084L, + 0xf84ad9e286b96242L,0x92f57d6d451a5486L,0x0215cfcb06a9e87eL }, + { 0xe05b10eaf66e46f3L,0xe7b0e72f655a0642L,0x035032677b117f43L, + 0xf5b78105779ea4a1L,0x28ee00faa4adac77L,0x1ea67d716a93a2b1L } }, + /* 61 << 203 */ + { { 0x4b68a01cd6b3387eL,0xc79582a9e7c4c99aL,0xa4ad6429029fc3bcL, + 0xf260ad946b83c7adL,0x81360618b09c3b8eL,0xf66e00ccc661ba2bL }, + { 0xd064537de29a69e7L,0xe2764d389bb4095bL,0xa3f57eb0f2efdea7L, + 0x72c214f27ed3ac00L,0xf8cfa59de392e32bL,0xa5d995124ad99928L } }, + /* 62 << 203 */ + { { 0xd069a9971dec038dL,0x64401a3fd0b59bf0L,0x33eff74ce7ec5e85L, + 0xfef5a1c50d35b207L,0x731cfc17e766bc43L,0xf994c0d01328b6cbL }, + { 0x4f2a5eaa2d3cc024L,0x7f83c57036a6fa14L,0x915a126d65f71dbdL, + 0x588fdd68acfb54ebL,0x7de9d37b7f57b2afL,0xca52d27170e071ebL } }, + /* 63 << 203 */ + { { 0x9b9211ada283322cL,0x30c6fa27b7124c9fL,0xda8f88a7474cbf5fL, + 0xc2414ee338203749L,0xe5c65cc26b767731L,0x8bdb52952753781cL }, + { 0xc8fe770be051cd30L,0x6370ecc4f046aa97L,0x03c83c1cfa287e66L, + 0x935bd2052bccef4dL,0x87b2a49646012036L,0xbce6a91de3e6d6aeL } }, + /* 64 << 203 */ + { { 0x7be81fb126882c6cL,0xe2d5a251ecd25498L,0xbb3d40e27a8d1678L, + 0x1806c67ad520811eL,0xadd4bb6686f65d23L,0x3a62b1b3e20e23d7L }, + { 0x208b47006548b3ebL,0x0497f09ab7ec2809L,0xbd3964f8121c37e2L, + 0xd35ef301a598efbbL,0xbd76a276c5eef966L,0x64700a7f0af64e46L } }, + /* 0 << 210 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 210 */ + { { 0x169474a2d3812087L,0x9de300da6698ca7aL,0x8589de922ede425bL, + 0x50e03fea6df8a890L,0x0d8a5c1c4ba8b8e3L,0xf273aa673fffb91aL }, + { 0x21cf054475fc8236L,0x6ceafacf9799c242L,0xc3237eaed0962c81L, + 0x43d6ac34213f6004L,0x45e619b2d4148b6bL,0xfafa18b5ea5fb80aL } }, + /* 2 << 210 */ + { { 0x9a8580aa2f063b51L,0xa83c8ff71c216613L,0xb4da0970be07f781L, + 0x0ac2a260712f7b7cL,0xc9b8ee84436a7b97L,0xd758c20d11fb2f62L }, + { 0x5daabed9f170b799L,0x018d2fddc46bc387L,0x82d6b5b7d96cfb8eL, + 0x4d7d0d9344d9e843L,0xfa2a9ea991e7da3cL,0x8230c1a3d531b253L } }, + /* 3 << 210 */ + { { 0x82412f525ec31754L,0x42f462c89d32e890L,0x1e7b58cece897ff2L, + 0xcfef785241164628L,0x34ee0422d8bb22efL,0x6e0d44ac7d32f01bL }, + { 0x968251655a3cc196L,0xa26724dc99eb23d3L,0xdb575fafa75f7252L, + 0x778e333062a3e5b1L,0x8689884e84cccc80L,0x9883cd19b645502dL } }, + /* 4 << 210 */ + { { 0x4cc41f2834220e26L,0xb5937c6da49749c4L,0x705366640fa1ca24L, + 0xeeb40f3b91e5edafL,0xcdf98235f1d3de14L,0xa65e5b7eff018c43L }, + { 0xaa3228e7acee3a6eL,0xb63a6289e08f4ff1L,0x90e90425650b2daaL, + 0xe4a8cad26d875f17L,0xc212029c9ce8a46eL,0xce0512835ed7cfb5L } }, + /* 5 << 210 */ + { { 0xb0df226159b79436L,0x82bd0dafa195be26L,0xbc99a94b3398c317L, + 0xbeb44c903c96ee31L,0x3c39ad81664d2e46L,0x081787520a3e0585L }, + { 0x9a054b6b413e269aL,0xbe58891d98c3b62eL,0xe7fa4c4de5734974L, + 0x8ac535f4d0a846a8L,0xea0f95f1a651339cL,0xa255274fd96aa239L } }, + /* 6 << 210 */ + { { 0xe23b7b229534047eL,0xbd70aea83a3bd625L,0xf44b05fe238db60bL, + 0x9c46fb140293abcfL,0x12cab5d3bfd8875bL,0x1f38d4aa12dd0c65L }, + { 0x4bed41572adf9805L,0x3f87da928a56609dL,0x10b93363da02c903L, + 0x7ecc726621ce4786L,0x8ae366851e3da5bfL,0x196040ffd3edee12L } }, + /* 7 << 210 */ + { { 0x4805841fe81508e8L,0xe2a578d3a4808642L,0x6bbf10accd0b2555L, + 0xc5071effaf5cde28L,0x665e75439a7124a9L,0x157c11edc1437981L }, + { 0x2019367d7aeddd8bL,0x74a1e104386e3b8aL,0xe72d429bfbe09a42L, + 0xaca96fd9061b862eL,0xbb2d2bc8122595f8L,0xc90c6503c509d644L } }, + /* 8 << 210 */ + { { 0xadb5966fcff05adaL,0x8ed26c025c57284eL,0xa76e73e244693a95L, + 0x14da74355982bbd3L,0x46e982cd5d2ca132L,0x8f39074024938e76L }, + { 0x749206b30a89b09aL,0x429653c793b4a1e5L,0xbee3d1567025bb7cL, + 0xe23f0e1e19555c9eL,0x0dec3837751639baL,0xb36cb84405d43bd0L } }, + /* 9 << 210 */ + { { 0xae76a96e74f90b6eL,0x5fa8e94824c6789cL,0x2b3584bb03abbb81L, + 0xe19ce47c5c451f72L,0x35792fbad619ac7aL,0xfa0282a250059bf4L }, + { 0x562bfd14dabe692fL,0x1aaf542c47eeb6c2L,0x392d5bba045d0360L, + 0x4e7bb31bd80fe998L,0x08f62ef31111e14dL,0x4de917b04e9ee1b8L } }, + /* 10 << 210 */ + { { 0x8b9d2d5867166271L,0x658db4ea142bab7cL,0xdf84932fa4ad2849L, + 0x04b113355f6f86a7L,0x2de6b29c50cfcea7L,0x46d8f68a9be6a3a3L }, + { 0xfb88cda7af0204afL,0x3ece449126029d72L,0x69fef1e23f946dfdL, + 0x708532fb01ef7bb5L,0x78d5053deb3795a2L,0x819a63206b36d57bL } }, + /* 11 << 210 */ + { { 0xca07e0c1e509d19eL,0x6c7e42c39f6281b1L,0x0e2ff43977b66728L, + 0x1d740e7880e76251L,0x6bfae4c631a0eb23L,0xd78ca917aa9b0b3bL }, + { 0xe140c662991e1781L,0x6e396b5f0dd3cfeeL,0xf0a1d1976ce7f6c7L, + 0xbe10f8efd5b01564L,0x865cbd54101a5194L,0xf665885266861dedL } }, + /* 12 << 210 */ + { { 0xe4e52e865b28f7daL,0xeb43a6809a58683fL,0x73b951bfb49f2b38L, + 0x7b6cb7db3f8097cfL,0x9dfb8d0b328fbf05L,0x491635a5ebce6211L }, + { 0xa31a152390fdd577L,0x334120df1cd2f39cL,0x1d22834e6b563876L, + 0xfd91b30d10ee5a28L,0x3d7a282d59aee4eaL,0x36814c6b73300a76L } }, + /* 13 << 210 */ + { { 0x7b584add6621c251L,0x98da669d4233aba3L,0x4d652b7933aa2065L, + 0x901bcfb8df7b4ed4L,0xb2ce587948012f81L,0xc18e2cd63cb71b88L }, + { 0xadb0f2bdff86279dL,0x46d9e5d65bd15866L,0x11b1fb3ec635a4c0L, + 0x8bcd0ad201b1006aL,0x0f6f7502cbab210bL,0xd6cc3e560d6b3995L } }, + /* 14 << 210 */ + { { 0xa54a6420137264c5L,0xa6ef0e78f9c2e45eL,0xba8b5a73d58d850cL, + 0xc0209ed86ef6fc3eL,0xe39dd0f391f7518aL,0x74697b8942b3eda6L }, + { 0x2dccac36abfc9150L,0x80e4fba298b2f5a5L,0xe0e56fd2771018d5L, + 0xa31fd1684c22bb94L,0x8b0998f71a66ef21L,0xed483e55b5a53ddbL } }, + /* 15 << 210 */ + { { 0x95db1c0ef23978ebL,0x80ad1612f04011f4L,0xe76bd1824d7ae83dL, + 0x841d6e668fc3bd60L,0xb68e80796875e2d0L,0xe3965efcd5d9dee7L }, + { 0xc488bb7e58930931L,0x52f4de19a907aa24L,0x39aebbdd321cc197L, + 0xd2f5b1f967de5c66L,0x60f1a8c28efe3e76L,0xf40604a0af988831L } }, + /* 16 << 210 */ + { { 0x78b5c14c0acb5935L,0xd9ec715c4311d3beL,0xffa22ab209e1759eL, + 0x5a86263db4b2f68cL,0x71e77c516b5be7f4L,0xfb5bea3a19844f6dL }, + { 0x2519d0060890ffabL,0x426a03f0f0329ef0L,0x2c6d74a685b3c2a9L, + 0x9306f68fc294f449L,0x552e77c22c69fb46L,0x7c7337ad10bb9886L } }, + /* 17 << 210 */ + { { 0x61f8a505d2b9f25bL,0x1d33aafe4c8645ffL,0x26f3fab7bcd333e5L, + 0x8ff4fc51be95e40fL,0x11cd52c6b55bdd5aL,0xf2b4782a22d43de8L }, + { 0xfe66e399a4c0e1c4L,0x26c6d7fc17954032L,0x44c700f97f20d2caL, + 0xdf67c3927187cdc7L,0xe11a98f9da36414cL,0x0bc5763a04052276L } }, + /* 18 << 210 */ + { { 0xe75b564bcf95451bL,0xd5ed760cc01aac32L,0xccf14dc5980d2c06L, + 0x235b5034ce2a5c0cL,0x64dc86aa05fa6780L,0x1d2ea4877385590dL }, + { 0xb18696f636c3174eL,0xf530487b608215b4L,0xa073d0750a123172L, + 0x8ca24b5afde8666aL,0xd6dd589a9b716dc1L,0xcab7ea504a721d4aL } }, + /* 19 << 210 */ + { { 0x34dee42c1592ebceL,0x5b0eba2e417636d3L,0xba178703a97d7356L, + 0x16f6119f4123e8cfL,0xd2906a53ef179fa6L,0xac5530606b7ed572L }, + { 0x82a25857b600f5c8L,0xb1dc1309973d516aL,0x6d53a967245c6e34L, + 0x7ce90bf4f670b879L,0x727ad4129732b6ebL,0xf00fb0054411dfd5L } }, + /* 20 << 210 */ + { { 0xeba7daad2b14da6fL,0x8274d1a8cee90515L,0x985c18f885bdbc82L, + 0x86555ff094d43909L,0xb0b1b2b6539e108bL,0xa4f32c66c0bf1313L }, + { 0xbd4777c162080e0bL,0x73039da8dadfb23dL,0x85bc57374a27f1ddL, + 0x9a8ae24eeaaa58abL,0x161cb2f5e876fac2L,0x54d457e46636e377L } }, + /* 21 << 210 */ + { { 0x409b17487bece8c3L,0xee36a1d3b49f5c90L,0x8ed9eb2a619ecefcL, + 0xc50a917798ab7bb1L,0x1eb247cceee2ccffL,0x07a9566f084a0f69L }, + { 0x59bda805a7cbee61L,0xf588124ca4e7ecd7L,0x0f7d8c3dde5eed54L, + 0xd98894ddefcb791fL,0x2fd80439ab309d7dL,0x0c8bf15d3e6cf756L } }, + /* 22 << 210 */ + { { 0x076a19c70e68a69dL,0x4d01c94b24b3854fL,0x9f38c5eeea8a85b8L, + 0xea80422d9a56f9c3L,0x10d9ceec9ad36735L,0x42194df742261173L }, + { 0xc7332e70c285d22dL,0xf3a3d4be592ff9b0L,0x2fe712f7f59846abL, + 0xd6de5201e4362677L,0x16ce8f1d4f30006bL,0x1f3c324d11dba5edL } }, + /* 23 << 210 */ + { { 0xa5af9e1c0cb4335cL,0x00a46bc0f3d0dbe5L,0x852a18c99d734817L, + 0xc12d54a9986c0102L,0x184b407063ffe60dL,0xe05182437d99d723L }, + { 0x8d3886cb20ef7647L,0x7e9c618017b1ce8fL,0x194baf260f176141L, + 0x978015d3b4694945L,0x2603be2f1c135e8eL,0xbc0f5e72ba074e0aL } }, + /* 24 << 210 */ + { { 0x1674b959cfe7bcebL,0x62e1279fe7b66a28L,0x3962a32dc67c3648L, + 0x4949617368d720a6L,0x4e81df85a957a5b2L,0x28b5c45753123c0fL }, + { 0x5091dd347e239c67L,0x10b9c3f6160ef925L,0x5e7720f52c119dbeL, + 0xd584ae76c94d609aL,0x476c63ba86dccd1fL,0x70103a1a32508c6eL } }, + /* 25 << 210 */ + { { 0x64f4f4ee90a17a16L,0x31165bee7cb22fb7L,0x31da800b924825b0L, + 0xc2c169db0551e47cL,0xf9ca5e0e0d583789L,0x5e4fbdb53cd42f2cL }, + { 0x6ade1fce1d81000bL,0xa105df391d6603e5L,0xd659094da3139f95L, + 0x363a882851d01444L,0x13cd7cbb2dece086L,0xaeea2aa96ab9020aL } }, + /* 26 << 210 */ + { { 0xdcb31a931081405fL,0x200090dcf1326ecbL,0x773fe49cde99f0ddL, + 0xf6a7cb67fac2c511L,0x95c93429b40b014dL,0x967708d4198dd723L }, + { 0x74591cc184b90062L,0x2539ef20691d2550L,0x7d7290765a5d86c7L, + 0xa81f085475c6fdacL,0x103186d1c0f0d5cfL,0x5ae582e07eb3b8d9L } }, + /* 27 << 210 */ + { { 0x7df39eb2f9f3456cL,0x1e7ad4587be12020L,0xaee54df11fedfb79L, + 0x98f3a0879bf1dfe6L,0xdf958d371d13fb71L,0xa745249717dc809dL }, + { 0x9f2ec9dd02d4eb90L,0x9db5686e48b0c7a0L,0x7d064cbf72532eb0L, + 0xe204d56593a71a9cL,0x0c912346f1aecdecL,0x894224a3d25d243dL } }, + /* 28 << 210 */ + { { 0x6bbf77cb5a508291L,0x2af81442d35db82cL,0x357feb1a2b9febf8L, + 0x74240a81a25330ceL,0x7a9ab575b4917998L,0xa60288d5eda3ef5cL }, + { 0x360410d30aea9569L,0xef66acb5b9bf8c16L,0x7baeb466cc381b57L, + 0x024a98b8247a4904L,0x6e70b4c3e3c58130L,0x276e2420ae8a56d2L } }, + /* 29 << 210 */ + { { 0x3b4a25222c57f1f3L,0xf43d352ba8d1f53bL,0x169fb3cce198b03cL, + 0x92172ca923235a6eL,0x90b5953683f996e5L,0x32b1a34cb5ab11a0L }, + { 0xb944e4b7b9001351L,0x1084de3d28ab5cb2L,0x60f1dc93c70ec63dL, + 0x790e1d496cfa10f9L,0x79bcc2277c3cd865L,0x95007ac24fd31fd0L } }, + /* 30 << 210 */ + { { 0x6b5d8db5f75e17b5L,0xc5ab42961b45a230L,0x586f097b7486832aL, + 0x1ec456c14f289757L,0xd11773bb57b04a20L,0xc84dfacd0821d3dfL }, + { 0x580da8cd586e399cL,0x58c1355ae3bbec57L,0x0a476934d594a2e5L, + 0x0490ffd537e99427L,0xd41348386a4d8c4eL,0xd62cccb3c83d6e28L } }, + /* 31 << 210 */ + { { 0xe6071a3d57c9e219L,0x88728c47a93f38dbL,0x0426848b50eb1a01L, + 0x9df36972cada9a09L,0xf2ad4a2d4f494ec4L,0xae26577de1f34993L }, + { 0x72ec08cde3618d7aL,0xd1fb89013ea90c46L,0x915936173b94f996L, + 0x8703357705387745L,0xf1961ff818fd5199L,0x7f0b58d34c2aeed1L } }, + /* 32 << 210 */ + { { 0x3313a9d544b133d9L,0xdb85c25d2da910ddL,0xc0fdef915e4dd5cdL, + 0x902a2a93c565dd67L,0xd8eba4dc7fed05acL,0xd453995ce157dae9L }, + { 0xd655d0b3f250cb55L,0x4194a09e86119222L,0x5b7e525a0652872bL, + 0xaf7968efe68c0ddbL,0x2ec02930f51cb31cL,0x237f3ae4f2be071eL } }, + /* 33 << 210 */ + { { 0x696d84910dc943a1L,0x1f24fd7d9fe1d7d5L,0xea38c9e349413ad7L, + 0xe223996607c1cecaL,0x62094496ea7bd8dcL,0x9aba5bc7236dd525L }, + { 0xa138ed5851631b6fL,0xed724f20902f109aL,0x3ab594cccb28f1e8L, + 0x3424213b5916dae7L,0x07e5a6df18479651L,0x4c51f2e1c5b48e29L } }, + /* 34 << 210 */ + { { 0x6306564b6591a811L,0x734b2619fd463a13L,0xa795d0569d8019d8L, + 0x103d85004ffe5858L,0xe1962c31adab8484L,0x326b3351b2015dccL }, + { 0x2ad52b852ff36c73L,0x5874652308682fcaL,0xf544e162ea37824eL, + 0xd4a6b45ec208ce7cL,0x52d09045d2559ef2L,0xde1dfbbe57ebca65L } }, + /* 35 << 210 */ + { { 0x3a94aec3bb793f9aL,0xd0af44d4b5352511L,0x1d3f1c130b8930cdL, + 0x016cab225a729e0cL,0x092a7c11e31b549aL,0x80c462ed90ebfea4L }, + { 0x3dcb9606e5e4ae09L,0xad150903ab59a450L,0x1b58210c6c944727L, + 0x26599f6024572a80L,0xfce0ad40c0445075L,0xedca1ada54c4037dL } }, + /* 36 << 210 */ + { { 0x794593303801b021L,0xb19bb405c9a4cde4L,0xe20091667f9cdee9L, + 0x762c684f7636d30eL,0xbf2b29f20c215831L,0x4c0d1b651853fe90L }, + { 0x196ccb3157defc94L,0x9f3d66b7f6b9cc44L,0xb2328a0eea439deeL, + 0x82b3808d7b140e5bL,0x986210dd88e4a35cL,0x9b171fc838a2b7a7L } }, + /* 37 << 210 */ + { { 0xdc80e3ae91517233L,0xa219f65dc6f20d29L,0xd348a3d8be093f56L, + 0x63c233774d33113bL,0x587fd56257f2ce9bL,0x82cf3e3a4e9061c0L }, + { 0x0e41f59bee8dd928L,0x7a5641be8aaef52dL,0xa852a171984ff476L, + 0x3c37fd1c047457b6L,0x7f00d665972d4793L,0x29dab0fd97b27966L } }, + /* 38 << 210 */ + { { 0xb1d119c91e9d07c0L,0x2f973a09432c86afL,0x3505b6f05ded5546L, + 0x21814b958687f973L,0xc104d7fad3794ae9L,0x81614d707ea91311L }, + { 0xb7f3e6b600677961L,0x53fceb8bc0e6a90dL,0xa3a7485699ed4fb6L, + 0x07ad488421d4807bL,0x527b1ae6004e0c03L,0x437f306215146393L } }, + /* 39 << 210 */ + { { 0x917b4cf463e12603L,0x79e0b7363f838ecdL,0x57de4b3328b4f37eL, + 0x3085e4887f58fcfaL,0xb9301c4e958a3bc6L,0xef8d10578b044eddL }, + { 0x2123d284d6391459L,0xdfcc2be5e196d765L,0xb58216268184b993L, + 0x13e21d03937c6048L,0x39eb3d38460d11fdL,0xf8ef123e5bb23c30L } }, + /* 40 << 210 */ + { { 0xa6f8b354666eb2f0L,0x7fbf6d91f9c7b16eL,0x9b360814161b5e0bL, + 0x13726fbd921511a4L,0x37aa1b8013833a11L,0x53f01183407b9889L }, + { 0x8a83ea3fd147da9fL,0x25279241db0ad0b1L,0x78353bccd1a8d9aeL, + 0x1e33c10e271f7f0eL,0x136d9e7e9e67adc5L,0x11dcef95cc56ff8dL } }, + /* 41 << 210 */ + { { 0xae530580d84ba919L,0xac2e43ceb6d3ecd5L,0xf97b1afda4bc6a2dL, + 0x180d66d5bdfa96a0L,0x935b8a7d1ca12bf5L,0x1d4409a79e678225L }, + { 0xdd85bf4b19a2163cL,0xe34197bcddeeb22bL,0x1e33fc3e1210cde9L, + 0xc96212a98b9b5d0aL,0xa3ae81f303e4a12bL,0x531a7148ea262807L } }, + /* 42 << 210 */ + { { 0xf11ac5fd4ace8006L,0x898a388133c499a5L,0xcf27ab9f1d3368ffL, + 0xfb6019606cbd6e54L,0x5373c2a901fb58b6L,0x1489f5037cd1b888L }, + { 0xb3f0e0b85a238131L,0xd0e11e6e670858bdL,0x897f1584b65768f8L, + 0x9252aa72013b1f2dL,0x185842af0a1a5f8bL,0x49a978373d681a70L } }, + /* 43 << 210 */ + { { 0x8b65c6d23396eaf3L,0x2191764e50b9392fL,0x7a2363b72dcf6d0aL, + 0xa6a52402f0591553L,0xfaba81cd5ff7a071L,0xd6be926ae43e37aeL }, + { 0x7b34c578ccaacef2L,0x2bc5d248d5eec9b1L,0x9447aab3014c0048L, + 0x767309a3c02d54d0L,0x408c6eee1f92297dL,0xf7ad95f40072a2d4L } }, + /* 44 << 210 */ + { { 0xd0051ab940ee5098L,0x4861b2461d8311deL,0x6b7796e0f31e860fL, + 0xde8b243acfd543e3L,0xef9d0957a0161843L,0x70fd43ecefefcbaeL }, + { 0xd47392541931a5a6L,0x42e253300342623aL,0x90b33edd52ffbf5fL, + 0x0affda4ca015a550L,0x8716376b77e59672L,0x39d84b33fc0e9448L } }, + /* 45 << 210 */ + { { 0x71b55e7ea0415173L,0x5d0b5e01b10f3cd5L,0x0c35a1b63e3f9d84L, + 0x3c68cb5db794ba37L,0xa73356f0dfd6c999L,0xc59ed0650e5e221aL }, + { 0xc59443a90cd7d577L,0xa354296e283015a8L,0x202aee3ba7477107L, + 0x59f361392ee80330L,0xc52bdfaae875a886L,0x8ca39d9d07637e97L } }, + /* 46 << 210 */ + { { 0x95be10b8f3a1611dL,0x6db370f0d1f992c1L,0xb964029de8124b40L, + 0x618b26aadfc90473L,0xac65c9916f6d5553L,0x10d5b0f0a0a6fde8L }, + { 0x4bff23122d164911L,0x876db39d1f7293b1L,0xa2d3cd549de47789L, + 0xd8ca4f6eabc9a28eL,0x0bb3145fca7b5467L,0x4dce66338b37bf62L } }, + /* 47 << 210 */ + { { 0xcdd8ec4dec1b8d36L,0xf76258d888003e0cL,0x35a114e7262723f9L, + 0x12933142abb34bcaL,0xf55b84514c188a3bL,0xa0cfdb2c0ada78b6L }, + { 0xaf0b62f6ed36781cL,0x0c619486ea7e1ca1L,0x11fae38689162fc3L, + 0xe9bd7ae694828e92L,0x081c3acda84cedb9L,0xb34ceca8787a67e0L } }, + /* 48 << 210 */ + { { 0xd1b2af2f2bca651bL,0x2211e4f97404bc78L,0x787b1cc8fc5068f2L, + 0x73d6da299fcbb3f5L,0x6867fb7707d2142fL,0x36f277ae116ad6bdL }, + { 0x81c86073a7534943L,0x67188488c4033c7aL,0x13a8415ccc568123L, + 0xbc01db07f3f475deL,0x90b8af2e3aaeee1aL,0x320c4880175fa55bL } }, + /* 49 << 210 */ + { { 0x263afd7d2fcafc9aL,0x9b0c30ebcc9405d6L,0x713fdd27d6720896L, + 0xb07f8ec5f7df4a02L,0x05d62e5147ddd4e1L,0x6278227b8ae3b80aL }, + { 0x2ef5c81b0d4ab658L,0xe6ad5925016a434bL,0x6c0e30a2b85d8037L, + 0x254830037a9cd869L,0x78da543b2cc48c8aL,0x3a65b54e3edca4dbL } }, + /* 50 << 210 */ + { { 0xaf2a06c3d54b0072L,0x81621ebfaf0310c5L,0x6bd1fe41a8a7a9ecL, + 0x942cf6ba03e74289L,0x2a25f0f59f9822e8L,0x16654b13062edd3eL }, + { 0x2345a0b19de373cdL,0x425a59f80c0744acL,0xc6738fe96f0d620aL, + 0xaa479ef8ed67c1a9L,0x52540af87765b194L,0x17a3bd3bf2b96455L } }, + /* 51 << 210 */ + { { 0x5b1a1f075f01e608L,0x3c696f4e87b821c5L,0x4358a5243129700fL, + 0xfc9816a14be9d001L,0x905de48166744b96L,0x2ca5f8d8eeda3945L }, + { 0xb30eeb1aad207f4eL,0xbd113b2dbc66e6f7L,0x1b6c5c6cebaef81dL, + 0x6b3863998bfaf32bL,0x5f9f2a2432a83dffL,0xe8cc190e26ea39d1L } }, + /* 52 << 210 */ + { { 0x51e05f7d450535fbL,0xa5f5181effbe389fL,0xdf178fffaa2d5514L, + 0x89358810e51da035L,0x206e324f664d399cL,0xc148ae74c4477d4eL }, + { 0xe0c8d4377d6f38d5L,0x327aad6d8c8133e9L,0xa685a889d21cac4dL, + 0x1217c68d0ceb5770L,0xa4a09612d21f1d50L,0xab64b4dd889676afL } }, + /* 53 << 210 */ + { { 0xf263062aee202007L,0x95e90bbda2359019L,0x57740eb39f34e691L, + 0xa5f4fd0f355bef37L,0x484b97fb439f091dL,0x642776fe53ac871dL }, + { 0x5c8f9b1e494e0eddL,0xbc62c971ae25a6d7L,0x01981994a7d90290L, + 0x3cec43524602cdc1L,0x4bd29f5a14403ae2L,0xafaef08b921328d2L } }, + /* 54 << 210 */ + { { 0xd33e754a53ef149dL,0x82243def548034e6L,0x99c29a9b23ea2dcfL, + 0x724e4b5d214848afL,0xe43d4438dcf85b9aL,0xaf7241ea9d7b20dfL }, + { 0x60a10c30069edb1bL,0x1aaddd5e9874f484L,0xfc784ac073085538L, + 0xc998afe54d69703aL,0xb71f6fd7bf52139fL,0x28f994c46a45b089L } }, + /* 55 << 210 */ + { { 0x85084ec2eebd9e0bL,0x73e489c6cb9f1929L,0x91e47fd7ebe10e55L, + 0xeed6a3a1486a2704L,0xf63deae7e124d6e2L,0xca958204b48b3834L }, + { 0xe69cb5bb13185b44L,0x56be0e05868d97d0L,0xc48cb1e50181e64dL, + 0xfaa012ddfc7827cdL,0xf535b1c83488352fL,0xd1cce04e9fbf42d4L } }, + /* 56 << 210 */ + { { 0xa54436b6ba3403ffL,0x1fe4b1ecdcbc4822L,0xb3b351004c6846e2L, + 0x360278048d1cac7cL,0x9eff87327e86d5d1L,0x7f435326ba21993aL }, + { 0xb51a9da5adc24224L,0x111c19fcc8c14a71L,0x05aa2c86ab77e011L, + 0x81edc338ce72744dL,0x20fa8f528d882bc3L,0xc61c3e639d1696f3L } }, + /* 57 << 210 */ + { { 0xa66674ca0f41637cL,0xa01d08ac418487daL,0x2ce4258b6b593194L, + 0xd755220645024db4L,0xffb3366f626732ceL,0x802878f370ba2f1aL }, + { 0x80a3f41659b77372L,0xfbb411631a04b19cL,0x7d575112a346d265L, + 0x6c30421ffff87d4fL,0x1b62b93fdcb05f02L,0x98ba4397b72649e3L } }, + /* 58 << 210 */ + { { 0xcca45c1d135a7eb5L,0x2623e629b048126bL,0xada7326e926980f0L, + 0x64f334c276bf796eL,0xf0751596b4a562a8L,0x0baa14486f9d0079L }, + { 0x6c394aa32205ea70L,0x635b9d2d556172e9L,0xf418fe0cfd37b53bL, + 0xcf5fe2ac56b9791cL,0x9d855e67911c68ddL,0x9e40f75f734b57d8L } }, + /* 59 << 210 */ + { { 0x32c42482b5b8f846L,0xdefec599b61cc3cfL,0x4c3460996506a9b5L, + 0x0d9475a0263a6142L,0x1753cd92c80a6713L,0xc015412f420cf67eL }, + { 0x1c33f01b6a88d12bL,0xa49f038ef522f7d0L,0x232343decd25f260L, + 0x479bc742d6a833c3L,0x2f2ab294cee07b83L,0x02e69a143dec38b3L } }, + /* 60 << 210 */ + { { 0xbf7fea3aee1fee16L,0x31fb342ce0cde85bL,0x9a232ea51575924bL, + 0xc3132e6cbcc4cf26L,0xbc5b7a7102499a58L,0x3064a3b904d99836L }, + { 0x6f17475ff8b3bad1L,0xaeeb90c429271790L,0x7f442a13f8eca53dL, + 0x6d641eea08882274L,0x8dff43bf88ffaebaL,0xaa92827f5840b198L } }, + /* 61 << 210 */ + { { 0xf5ce3fca26d803acL,0x6927ddd9d4e1b6b5L,0xb509b5c609f48bc0L, + 0x2bc5d1749e35975aL,0xfba3024af570c98bL,0xeba15980aa27d6b0L }, + { 0x95abc07290abd2daL,0xd0e30e99232035cfL,0x3dc4e1bcd3f0ecb1L, + 0xa5a8c6e556de9d17L,0x878c7403ab73bd18L,0x5cce39260c474b0aL } }, + /* 62 << 210 */ + { { 0x86a3f001e93b6ee6L,0xa28984474fb3203aL,0xbca0d71e9b3550adL, + 0xc225759d0396d796L,0x208b9a02cbd949d8L,0x15b21ec9a550d2ddL }, + { 0x64aaed6a2a7dcffaL,0xb8cc7575ed5b6b47L,0x2b4a3aff022dbce3L, + 0xe85d690b86f51861L,0xe26a6c3d578f4d5fL,0x706d770a70e7ae76L } }, + /* 63 << 210 */ + { { 0x822467eb579c91a6L,0xe98a471531599272L,0x7baf0e9f1078d497L, + 0xd13f270e25fe439cL,0xae9d58adc0d95395L,0xc3beb60827693037L }, + { 0x4d9c4cf397f797e5L,0x4e26167db26d2e9dL,0x06092d5e86a167efL, + 0x9827a21128dceb29L,0x30423344552a55ccL,0xae07b37f3fa437afL } }, + /* 64 << 210 */ + { { 0x9b23ab4e94d0864fL,0x46356266009c9fc1L,0xdbe99e51e798edf9L, + 0x38547449307675c7L,0x23ffaf55628c0fb6L,0x56ccd2a31698c372L }, + { 0x39f45a578347ce95L,0xe0aaec744f2c6118L,0x2a89079e4af138fcL, + 0xb86371ea2ee4ecc0L,0x076d256a06bbf92fL,0x9073adb8ae3c4c51L } }, + /* 0 << 217 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 217 */ + { { 0xba2e9543743c15d9L,0x7d5812db1c99c984L,0xf94db95145bdc19eL, + 0x951d00ae382e77bdL,0x9940a5fbb220b29aL,0x6908d50e58fc91f1L }, + { 0x682e42eadd0940feL,0x2124e23aa1d32009L,0xbe15810016294d05L, + 0xaea13fe32e326d68L,0xc0dfe1ef15e64fceL,0x32dbc0b5b8237a8aL } }, + /* 2 << 217 */ + { { 0x6ee65a08c36d3f25L,0x7b6c811fe393e4d4L,0xc4a2cc382876e523L, + 0xab7aba26d3bf53aaL,0x5bf00871db7f290cL,0x3cb1cd131ee6d5bdL }, + { 0x4cafb218de998adaL,0xa1ecf36af6319101L,0xa1fe785520b281ccL, + 0xe457198e64d9c65eL,0xa3d1a6d0c5a0e67bL,0x69ddbc3290cc468aL } }, + /* 3 << 217 */ + { { 0xd4ee3f7f6dadc46fL,0xa1f3dc925d7febd6L,0x4c0bee1363ebab5bL, + 0x70e32d77005ec237L,0x302fc73dc52fb006L,0x1af84c0a8f159899L }, + { 0x42a5478f0686232aL,0xb4fc56348a308687L,0x042c4970c8378f0dL, + 0x70c195758e2c86c5L,0x61a95e6884c7c767L,0xd96a8216d6fb43a8L } }, + /* 4 << 217 */ + { { 0x0c62fd2d543c1255L,0x71ea9c6fef361a27L,0x76b0933dcef3f9e3L, + 0x51b1ec2d9889ffa2L,0x9e84b2ba9a3c88d2L,0xc8996b961913e52fL }, + { 0xbafc5e94cee43e36L,0xd9898d2470c658b7L,0x4e9bcc41bed17108L, + 0x0db5b7336c7a41c8L,0xd4be07a7795369cdL,0xb899f92f7bd3a934L } }, + /* 5 << 217 */ + { { 0x1fffcbc010e15fafL,0x8447bdb8910245acL,0x857d521e86476901L, + 0xcd1d5f87369ccfe9L,0x560b3277b3f1dbf1L,0x4ac02a1a47ea4266L }, + { 0x29ac98b6a8a929eeL,0x020ec6db5e5e70c0L,0xb0be38ba21291be6L, + 0xcbe9d362bdba40deL,0xc585450571535a89L,0xc21839de3d7a3235L } }, + /* 6 << 217 */ + { { 0x831541b39805497aL,0x2ceb5ac879c414cbL,0x86601fa616d2eb82L, + 0x373d19079338ce8eL,0x98151a90c1f5c87aL,0x966ebde6048a538cL }, + { 0x5c4a8c5ae180ff7cL,0x6d9065dff996d994L,0x4e0dd86e2460ab91L, + 0xfbe8b3ff309a8f5eL,0x33d7cb35856f7218L,0x62b2200a1ac59f2aL } }, + /* 7 << 217 */ + { { 0xb36ad750a460e53fL,0x727006d60df0f7b0L,0x6ca3ac348ee96a11L, + 0xb04f6ae930e75d1bL,0x9957738a3a24e9eeL,0xc0117a7d16521e18L }, + { 0x79fcea8872ad7e27L,0xcbe2c2d37281e3b5L,0x31915f1cc391fc60L, + 0x1c1c0082a13a92e1L,0x362663cc7ddca7acL,0x8021aad689689d35L } }, + /* 8 << 217 */ + { { 0x3f2eff53de1e4e55L,0x6b749943e4d3ecc4L,0xaf10b18a0dde190dL, + 0xf491b98da26b0409L,0x66080782a2b1d944L,0x59277dc697e8c541L }, + { 0xfdbfc5f6006f18aaL,0x435d165bfadd8be1L,0x8e5d263857645ef4L, + 0x31bcfda6a0258363L,0xf5330ab8d35d2503L,0xb71369f0c7cab285L } }, + /* 9 << 217 */ + { { 0xc19db6f05890e1cbL,0xc21587edfcac8d05L,0xa9e88798d86730edL, + 0xee3e6ee2c27441cfL,0xadb2c63ea23af57fL,0xb524b7da29ff5977L }, + { 0xab1ed847d3e4739dL,0x6592a0131cbfb581L,0x1f519c6ea1798195L, + 0xfe837a814c324a4dL,0x74fec4a85c813abcL,0x7b3b5351dce539b0L } }, + /* 10 << 217 */ + { { 0xb886a0c50c99e321L,0x4063d19576e924e9L,0xc03cca041a659dcbL, + 0x1e01abbc1bd3dab0L,0x9d7cf04fe9141cd8L,0x5f87dfa73ef58d85L }, + { 0xa579e76388d764b8L,0x381dec6a74b9e5b3L,0x354221f99a4c9a67L, + 0x8c2556d33f529346L,0xced3642bb4349eb7L,0x1527cec7fef5c92cL } }, + /* 11 << 217 */ + { { 0xf2e42ef7785ecd51L,0xca3438cf33d9c0d2L,0xeef9ec08c1c097f3L, + 0x9e438fa746682aa7L,0x53d0144531a7eefbL,0x04431241e6998a0bL }, + { 0x2c1bb2bd55bc7febL,0xed99e7afb44d4943L,0x7f37bc4a3c77d21eL, + 0x866c0978398e3997L,0xed7462305bde12b8L,0x24796f7c7194fd1fL } }, + /* 12 << 217 */ + { { 0x7e4450cd5e83d570L,0x0113cab242b394e7L,0xdf4062a08ee24413L, + 0xf8a0fd4931227510L,0x06b798f4b80f0d23L,0x33f17673b72bffa8L }, + { 0x4638602b5de9f490L,0xbe3a65834d905654L,0x446e0afaf406772cL, + 0xef68dfd7b4ec908aL,0xa6be004966ab5ebfL,0x56049360ff376531L } }, + /* 13 << 217 */ + { { 0xb47202b760b6ce82L,0x8129c1befe05e9faL,0xcb70cbdde861de07L, + 0xcf35fbc5af16b6d9L,0x60071beec9916116L,0x3aaa496ed057e63cL }, + { 0x1cb0bb12c356f065L,0x12dccccef4de0d26L,0xe3f59cf67ccc0d48L, + 0xd66f10b3d9569e26L,0x95f4d7e79d1853ccL,0x10313dfdbf651d5aL } }, + /* 14 << 217 */ + { { 0x779b55062a3d9774L,0x3785db08e0554291L,0x9b3a4eb8546c69dcL, + 0xfe36824dd22d8fc8L,0x037d9ac9471132a1L,0xc895e332a01e1c28L }, + { 0xe535ede71b5e2845L,0xdc90cd7c568743deL,0x3292b40b4691d367L, + 0x911fad21b4f16a4bL,0xb3c5f0eb455d018dL,0x2eb2def669033748L } }, + /* 15 << 217 */ + { { 0xfd1297a4307aa8fbL,0x021f242177952146L,0x17cc2d6f0ba72feeL, + 0xa265095d01a3a733L,0x2e12c2e7a07d5f8bL,0x27bb60341202224cL }, + { 0xb58b3fab8185dc12L,0x83467b977700f166L,0x98242e227ff9e1ccL, + 0x96b2a4d9f4b28f1dL,0x64113c3865ed82eaL,0x7dc9ab732ee160e8L } }, + /* 16 << 217 */ + { { 0xf16938f514c5969bL,0xde2e3cf0944b2271L,0x2d5095530b6490d6L, + 0x8432fef1a28a296aL,0x6f254dd08d26415cL,0x3780eeadd50c2865L }, + { 0x4f5bc455665b8794L,0xef31fb9e56cb7018L,0xbab8dd6e65e59340L, + 0x676baca2a56dc2eaL,0x38eea06beaa90e05L,0x26e64224174bada0L } }, + /* 17 << 217 */ + { { 0x309e9fbe109cdb79L,0xc2ed3566977d0e4eL,0x2891f30be6b944aeL, + 0x514bd4cf5022e070L,0xae9a22a98726a661L,0x1114a0c8c1916b06L }, + { 0xe1b4f8339795adecL,0xcc0f3824ed4dbf8cL,0x432c93c878096a66L, + 0xb9450e9da7d2ad83L,0x294b0c192c1e35ebL,0x791427038be5a953L } }, + /* 18 << 217 */ + { { 0x4d215132881faf35L,0x52171a5ceec736a8L,0x4788813e1ba561d5L, + 0x9ca022a7d35e399cL,0xbfcaab926c4b8d7eL,0xde62b2c007c7ec40L }, + { 0x7b46c2d96bb54e10L,0x2ce02e5a7d31e85aL,0xb757b699cd776c12L, + 0x08f122552c81b71bL,0xaca91e058aa6b02aL,0x35cf7bd37209279dL } }, + /* 19 << 217 */ + { { 0x24b5bc7086a04b9aL,0xd4d4c640612e0fbcL,0xb19ea7fcf732589aL, + 0xa18b6f4081fc63cbL,0xddd7211d84d88fe2L,0x7e8db6f72963130cL }, + { 0x8772908c500c491fL,0xa3bf747783fd8a41L,0xca54d0d34e3e9fe9L, + 0x9969471866b030d5L,0xc2f5fb98b1fd6736L,0x58d5a851d103fa45L } }, + /* 20 << 217 */ + { { 0xe4c16fcda97a5decL,0xcc4333092f1dd4b8L,0x8cac9da985d334dcL, + 0xb4deff204cda5a0cL,0x59eea4c9be70b1b9L,0x161e73a2ec5b7b58L }, + { 0x584c5e098b7fb4a6L,0x697fb795a3f7dd08L,0xc9e15f754bd4ba2cL, + 0x66d04f47c83df783L,0x0c03c2452efedf63L,0xa76a08c94a87dbb4L } }, + /* 21 << 217 */ + { { 0xde4e18c2da669a50L,0x0629350a480fb520L,0x84b3e68b7cac0748L, + 0xab718a12da3e1e9eL,0x3f5c5489cc26aed3L,0x81c6b6d42a57ab3bL }, + { 0xc4ded8ce15d23825L,0x2d753e6a20c6eb43L,0xbaa120ec555f3a83L, + 0xc72f9d3877e93abaL,0x4ce297d0373317cfL,0xf42b3e954845bc1fL } }, + /* 22 << 217 */ + { { 0xbf162c19d7480e46L,0xa7f45ea76403bf0fL,0x250e936c6c51cef8L, + 0x97ba086f1cd24b64L,0x271a22364cfb2889L,0x2685c98804dc4b48L }, + { 0x843bb75ac877f6a1L,0xe10cd5c799d5c7bcL,0xbe65eea1db60606aL, + 0x9019a9a7a10d0d74L,0x5614c0b987c62e5eL,0xaab2308d38240d05L } }, + /* 23 << 217 */ + { { 0xc908c6929a772e03L,0x73441df703928ce9L,0x36141b5bcf111c12L, + 0xf6b9e2f16c7c3e5dL,0x1f245a77722c5b57L,0x07e3f364635f65e0L }, + { 0x1aab7abf272597d8L,0x03954428d4fe8e71L,0x7dd58036ecae1b5cL, + 0x9b97c2f28c85b0f0L,0x68ed3dc6ace011e9L,0x8e4ab5ca1744a774L } }, + /* 24 << 217 */ + { { 0xe6a19dcc40acc5a8L,0x1c3a1ff1dbc6dbf8L,0xb4d89b9fc6455613L, + 0x6cb0fe44a7390d0eL,0xade197a459ea135aL,0xda6aa86520680982L }, + { 0x03db9be95a442c1bL,0x221a2d732bfb93f2L,0x44dee8d4753c196cL, + 0x59adcc700b7c6ff5L,0xc6260ec24ca1b142L,0x4c3cb5c646cbd4f2L } }, + /* 25 << 217 */ + { { 0x37daf7fd5a96d915L,0x1bba82e6d16a1332L,0x7558b642ce1135d0L, + 0xc9fcd6ce3abc5915L,0xc3762a20b93ad4d3L,0xef0cdb45e4e74f82L }, + { 0x809b91dcd26fbab6L,0x1264f72ea9b53697L,0x264699ffd7c827f1L, + 0x16d4f094d8c4976fL,0x244c90cd997df2caL,0x58eb3b1c76f77b3cL } }, + /* 26 << 217 */ + { { 0xb99e2dde1ed04268L,0x94247d202497b83fL,0x0c6c21d1fb833507L, + 0xa01e682fafab9c39L,0x4938108f4d84c3d5L,0x70b68c75347652d1L }, + { 0x458e814740e17747L,0xca752a14c3f8bb03L,0xaa537b4d8598d044L, + 0xeec3febb7ff102e0L,0x10ef3cad247fe4baL,0xe4de5b1b5673ac39L } }, + /* 27 << 217 */ + { { 0xbca2931378d0bb1aL,0xfcc237068e5c3fe4L,0x0f9d6b11dd0d67a3L, + 0x9aec22faae14bbd8L,0x75f8d86e5bda7184L,0x6bcad95759aeb4c1L }, + { 0xbb1224a5990a9309L,0x00edc04ef7193f45L,0x870c1647c17cbff7L, + 0x9855513c65031caeL,0xe5a2e2ded852b607L,0x540a4141e5671e25L } }, + /* 28 << 217 */ + { { 0xfb0e2f2e4d5efff4L,0xbf3b96e73a143fd6L,0xa18a037f18579946L, + 0xae02fd4ce48c8a51L,0x1cb139288745c177L,0x4991594a28c47832L }, + { 0xdce3b1d2fd51c1a2L,0x4e707213314cb09dL,0x5312de95ee323449L, + 0x4925c4e789389866L,0x2438fd9e28ca17acL,0x58fd2aad872dc0acL } }, + /* 29 << 217 */ + { { 0x75bcf0ef54ddedaeL,0x3cc75fc6f9077493L,0xc91b78df60f6b874L, + 0x7687a1d0622634c1L,0x57fdef4f82cabf32L,0x544819218e2671e5L }, + { 0x526cbb27a3c37afbL,0xe0db88340d1aec76L,0xa034badb73cdef1cL, + 0x165cdfad6281f26bL,0x5c90d4d1ce24a71aL,0xc404af1125f297a7L } }, + /* 30 << 217 */ + { { 0x6b21a0ea2fd5df44L,0x2da8dc6cb36e5b1dL,0xa683e08ac3688655L, + 0xfc5fbad3454bf878L,0x9d2fb9f12f73b749L,0x4612cf42f920b37dL }, + { 0x23da6b697035794dL,0x2763828adff7c198L,0xd320660522dd7eedL, + 0x6829994cd1316e68L,0xd732bc8f62831ed9L,0x69c6972c9303d789L } }, + /* 31 << 217 */ + { { 0xf5901854b0dcc28aL,0x81c92c1fcd18e579L,0x91a412ebc4b8e1cdL, + 0x35f00725891d6ab8L,0x10d6bad8ad7aa63dL,0x8cda809d09df2b47L }, + { 0xe856cfbfa489c233L,0x7ea921addf1ecf5aL,0x884cc717fd724c37L, + 0xe278f2457377136bL,0x240b142d9f3dc9ecL,0x80a384961139a645L } }, + /* 32 << 217 */ + { { 0xa35e411c2cb40964L,0xdd7d4f4cc331a3d6L,0x7c7c859e89a66f2bL, + 0x9908c37e0def8ecdL,0x8274124e344947b7L,0x0d279f7b568b0ce8L }, + { 0xe5291961866091ecL,0xb056e3bf3a08acc7L,0x60fb39e156bd3a7dL, + 0xe56a34d6268f8562L,0xb3a1fe1613fd8293L,0x6a41e1a967537fcbL } }, + /* 33 << 217 */ + { { 0x95c2bbfe021fc932L,0xc7e3399db2af7e0cL,0x1224bf06122670f7L, + 0xc9e4513ffcc1fe85L,0x8c82371ddb50fa7eL,0x017c5498bb76e4b5L }, + { 0x5467926c7fa89f61L,0xa4a65606f3a1204cL,0x22133acfa64b2e59L, + 0xab7896bce1247662L,0x75d35fb661780c9eL,0x99199644a91b33faL } }, + /* 34 << 217 */ + { { 0xf799c4638471104eL,0x43c122dd8b91c351L,0x9db6498616dc06f7L, + 0xf7e534410ebcf250L,0xa702c0f18373f9bbL,0x6ed8d39a1024e14eL }, + { 0x92913e436cabd9c4L,0xba906ef40dde6283L,0x06835e914a3972d8L, + 0xfbba3c7dfd99c4feL,0xf843e6f1b950909aL,0x7ec9866df5160b4eL } }, + /* 35 << 217 */ + { { 0x68f75bab06722bd4L,0xdeca718813066eeeL,0x4d658fa11152b8c6L, + 0xfae01e657257c9e2L,0x999445f923e4189cL,0x2cbe272cef6f0b1aL }, + { 0x5f60d9d735fff303L,0x4ca7a54696235360L,0xf506201598758f1fL, + 0xba81e7ad1dbaecbfL,0xd326e063c687425dL,0x8c46fa4b193484c5L } }, + /* 36 << 217 */ + { { 0xa97149cf3c1f5f12L,0x17b04a3d143d72b6L,0x174195ff17449a22L, + 0x851803960b136adfL,0x8d87d21f9a7adb22L,0xf9c9fc85a8f46d49L }, + { 0x7839f453a7ed1b7dL,0xe19d80ace9067ba5L,0xc387a6a0e41b8d6eL, + 0xd11611e1241d287aL,0x2561ed02636240beL,0x3bd8c57df0fba033L } }, + /* 37 << 217 */ + { { 0x7b5caacd3ea8ec1cL,0x221770e944624802L,0xafb1a4df5a32468aL, + 0xdec20eb62e295525L,0xe1cd4fb9e309c92dL,0x0331b9c0e7256005L }, + { 0x987d4c55246f2fddL,0xa392d27367f70f8fL,0xccba11994e214e5fL, + 0x789f0e4c9943562cL,0xf502ec237235c86bL,0x67403523987746d6L } }, + /* 38 << 217 */ + { { 0xdd02ced216c97e7cL,0x578d6912dc3347baL,0x760260da2134e993L, + 0xf96643dff34fb26aL,0xec214b767ea3285dL,0x19b135d4117733d1L }, + { 0x29a0e0636b037168L,0xb5df2bb95d1285eaL,0x5a2d3297796f0cc4L, + 0xfcee639f2090e0b9L,0xba11e8a4d93c091dL,0x5b6fc501492250e5L } }, + /* 39 << 217 */ + { { 0x6019d207263929d8L,0x9821d6e81f164aa2L,0x8f1b33f8d4924236L, + 0x389e482fb72de1b1L,0x398785a862554c10L,0xed31cf8408469265L }, + { 0xf9b99e158a09f334L,0x9ddfd4eba83df391L,0x28a5cdf4caa4f7d5L, + 0x32b9e3c68f68fd49L,0xbce64b93b6f52209L,0x72649c6fea7c4bdfL } }, + /* 40 << 217 */ + { { 0x8a15d6fea417111fL,0xfe4a16bd71d93fccL,0x7a7ee38c55bbe732L, + 0xeff146a51ff94a9dL,0xe572d13edd585ab5L,0xd879790e06491a5dL }, + { 0x9c84e1c52a58cb2eL,0xd79d13746c938630L,0xdb12cd9b385f06c7L, + 0x0c93eb977a7759c3L,0xf1f5b0fe683bd706L,0x541e4f7285ec3d50L } }, + /* 41 << 217 */ + { { 0x73bc200cfdd5504eL,0x73322fbf3825b0c3L,0xbf8bf1edd35c24d2L, + 0x54eba9f52e2bc29eL,0x80ffb5fff3aa841bL,0xbc676f62cc188be9L }, + { 0x2e2f79290383f0dcL,0x886c647e0d42059bL,0x673f0ea113eb7019L, + 0x630da63f3f9cd771L,0x2597592b3a0a42b2L,0xfd21fb21b83b8673L } }, + /* 42 << 217 */ + { { 0xd39ebb9fd2b34df5L,0x622bd0c3db873666L,0x546cc7f77b52738fL, + 0x0323cdd1c156c52eL,0x78b00818b5950f19L,0x8065a86a562bec17L }, + { 0x0b42eb1427ca5a49L,0x1791eaf1a457ac04L,0x3a2c93a6b2631402L, + 0x28b9cd6fcacec5dcL,0x6a0a8826d4535a3dL,0xeb08a884a83fcdcbL } }, + /* 43 << 217 */ + { { 0x16bae8925a940b6dL,0xfec394c1789562f0L,0x54349605ea412ea1L, + 0xccd57783cd18e2cbL,0x394bea1a1c813e61L,0xf11c566ff249dd67L }, + { 0x2cd679c112207f37L,0x7780918e83d16012L,0xe8bdbef4646c9987L, + 0x6e1882e5082dbbffL,0x811dd74777abe4acL,0x5bbbb740668380adL } }, + /* 44 << 217 */ + { { 0x0969263a7321c39dL,0xbd13b28bab7aefcaL,0x10e431f205377165L, + 0xbbb2a7d009442c57L,0xf935bc2d9cd156b7L,0x66c3d55e42406686L }, + { 0x4c529b76d20bdc50L,0x112e0f004d1c9f24L,0x414f1c65ed38dbc3L, + 0x63ade49c4eea65caL,0xbefd8af5fab697e8L,0x727bd3b45cc3b209L } }, + /* 45 << 217 */ + { { 0xb89d450a957925f4L,0xcb39b69c6e1e60f3L,0x55396e61ae3fffa3L, + 0xe89d97962986fdceL,0x5521d6b787fcd037L,0x6c20b2b0ec718024L }, + { 0xb1e0964bad6529c9L,0xe1bdaba3bc38493bL,0x6a9cf9d6f19b4690L, + 0xa2d035f7054466dcL,0x37df7fc07fa65c9fL,0x045b0b36106ef822L } }, + /* 46 << 217 */ + { { 0xe4fc833eda5c9577L,0x22afb5addfbbca7cL,0x215de02eb902e8d9L, + 0x215e4c900f1a6cb5L,0xf6d7e4a9d59e146cL,0xcd0c6c6e4912eb8cL }, + { 0xe0616976eae22897L,0xe2279d9f5d809d19L,0x2da1b7b3e282b2e5L, + 0x19327068ebf058b7L,0x9b23df0f5934492eL,0xabeb464fb1752d68L } }, + /* 47 << 217 */ + { { 0x6e754efc00d03f9bL,0x64aed0bd38b94393L,0x9d084ba16df2f6dfL, + 0xfe383a56c6abe8f3L,0xd23c6ca2bc7bac13L,0xde8ef161e326b691L }, + { 0xbb4e853342f96925L,0x1391974f6601dc73L,0x3a545ffb700480cdL, + 0x4d379c538884e214L,0x0fe40f66f713e900L,0xc7f202cbfff783ffL } }, + /* 48 << 217 */ + { { 0x89e48d8bc6bb5e5fL,0x0880ede01ea95a10L,0x60f033d7302c0daaL, + 0x15e4578a048eefe3L,0xfd6dec89b0a72244L,0x1f7cd75e309489cdL }, + { 0x7cdcc2a0e9aba7fdL,0xd18dc5c7f28ba00fL,0xa6300a455812b55fL, + 0x8fa5c4152ca31d8cL,0x36aa3c234f3a5b5aL,0xd128739ec86cf4e0L } }, + /* 49 << 217 */ + { { 0x7ac4712f660598aaL,0xe3f00c28aaba6261L,0xb71ac42e1a9b639bL, + 0x19674c28f69958d0L,0x3983abfec4e5c60fL,0x67f4583a5de58f9fL }, + { 0x83e0bbbaf7278c06L,0xd1883aaa19c5f96bL,0x8ec0f2848b3128afL, + 0xc88e07f49166e04cL,0xa515a9e44e3995c9L,0x0680a306b757ec2bL } }, + /* 50 << 217 */ + { { 0x5673b61e6d6f3aedL,0xcd1275e29524fd2dL,0xa8844f08cde12134L, + 0xeca3eb27b8366e0cL,0x5ce49d498bbe04b4L,0x0b7ab7a02882b056L }, + { 0x12fddcb840fee142L,0x99b7920b2895df5fL,0x35dd8d5a5829bb19L, + 0x271c6a4c46ee8dfbL,0xae09ba7536b594e4L,0x45502d0e1ae12c22L } }, + /* 51 << 217 */ + { { 0xa9e1b19ad95e0110L,0x6a419f8b2383280dL,0x6c35e8e16eb602a6L, + 0x966e0f44d71beeeeL,0xfc5cbdc0c8915585L,0xdce1c36583133b89L }, + { 0x3fbdd24289e6a35cL,0x8cd24d1760ff9dc3L,0xb9708c2729dd493fL, + 0xabbf39803cf807caL,0x62689ffe5410c80aL,0xf133928be8b31d13L } }, + /* 52 << 217 */ + { { 0x3645a1910d4bfc83L,0xa564ac85f2114b63L,0xf0647034cc6d9314L, + 0xb58e96d331d80285L,0x8b8222d9e269c964L,0xdee12adcd204b214L }, + { 0x82d2bfbae1d0a6e6L,0x4fd69d2e9da964eaL,0x1605d9e3200b3ac0L, + 0x5ab2886266d133eeL,0x938411c9f72f5353L,0x9fcdcb3a7d40dee7L } }, + /* 53 << 217 */ + { { 0xd65c1d6c501eb835L,0x37374dd14a0e5861L,0xa13f1070505f1fdeL, + 0xedd76943d1351805L,0x0f9501953673091dL,0x0dec24e308aa62f2L }, + { 0xec4962e7f50efefeL,0x0acccbdc9d227293L,0xc6c95d29d84fd828L, + 0xa4b214c540578ca4L,0x06963d3ba4d41991L,0xeb8c14c2fde0034cL } }, + /* 54 << 217 */ + { { 0x3d46a2317460e00fL,0xedce1c7dacce513cL,0x3d7b6f388cfdce74L, + 0x870082baacfa61deL,0xa86efef862ff847dL,0xc146218368c11d11L }, + { 0xb296eede9d21be2aL,0x9dc54e9e761451cfL,0xed1bb1fd53107f7bL, + 0x41f9efdb676bfbe4L,0xcdf43b904feb9a1eL,0xe81fcb6409d98782L } }, + /* 55 << 217 */ + { { 0x00639fa8642789c3L,0xf8e893a03c101e43L,0xc55439302730e33bL, + 0xe2967d30460970e2L,0xb33f1976ceacc128L,0x9bb0f896235e8c4cL }, + { 0x523f7bbb2fbbbc97L,0x127728a5dab215c1L,0x95dd23ca7ed6ab74L, + 0x69f1219feacf4ba8L,0x5ed12355e875dd6fL,0x7aa732dc95565bdeL } }, + /* 56 << 217 */ + { { 0x9a0e153581833608L,0x5cce871e6e2833acL,0xc17059eafb29777cL, + 0x7e40e5fae354cafdL,0x9cf594054d07c371L,0x64ce36b2a71c3945L }, + { 0x69309e9656caf487L,0x3d719e9f1ae3454bL,0xf2164070e25823b6L, + 0xead851bd0bc27359L,0x3d21bfe8b0925094L,0xa783b1e934a97f4eL } }, + /* 57 << 217 */ + { { 0x0a700190a5e41f7bL,0x2173e68dae9045b6L,0x28e9ac53f1669974L, + 0xcb00ff99d4b9fd98L,0x09c7b907ebe90d1bL,0xbf401f20385744c1L }, + { 0x0bb7ea7ae1292c18L,0x82aa43120b58f171L,0x5aa97bb2e3102d77L, + 0x1a71e7c570178b35L,0x9bbb9ade6ab76f59L,0x32da60c9dea7bcacL } }, + /* 58 << 217 */ + { { 0x3c3f113ab3726680L,0x27be1c406f5b5ab2L,0x5f51f684f6864a39L, + 0xfaf84229a60c4f39L,0xa788612d01df18c9L,0x65c9fd14951d5ea3L }, + { 0x4b2153cdaeeaf44fL,0x6b9e977ba567781fL,0x4dbca3609dbf3e39L, + 0x1ad43ad4fc65d7ddL,0x70a7a5e13d8dcf0cL,0xc11b1f4688b91e4dL } }, + /* 59 << 217 */ + { { 0x1ef5695b0868ad28L,0x09c9c06c2e3a9176L,0x2f2c19672c358e86L, + 0x4ff1af54da22d7e7L,0x5ea6716840fa2270L,0xd164b6874d31a3e9L }, + { 0xec036bb4345103d9L,0x6c6a130f26e17156L,0x2c491063d872b0d6L, + 0xa66be18c4123d04cL,0x8593de34a33fa919L,0x620d2970f025b880L } }, + /* 60 << 217 */ + { { 0xc194cc1664baf040L,0x8038f31fcc01f35cL,0xfcc82fa0ed2079c7L, + 0x1eb7571190d39b9cL,0xf1a89043c108e069L,0x10633334c020880fL }, + { 0x492a494086e262f8L,0xaa0208173383f1a7L,0xfbb4e5ba6d99cc07L, + 0xd6ccdc5cbde40478L,0x9e0b9d5867ee92c7L,0x5204bab7653eb14bL } }, + /* 61 << 217 */ + { { 0x721f44f0ef90c9bcL,0x6ebbecd8d55e653bL,0x9af325df6ccc5d5dL, + 0x265f0f6d827bd1aaL,0xb82453213487ea4bL,0x1642be42af6ba8d0L }, + { 0xb8c4168d4140e5f8L,0xdf5e32c13545d107L,0xf1301b9c2db68318L, + 0xb22e20472bf3c067L,0xf40af49ee56ba514L,0xf4090e795575f363L } }, + /* 62 << 217 */ + { { 0x980de58b1746f6bdL,0xa9e1f0089eb9511cL,0x8f53c6fd1bbdba34L, + 0xe6a867a6a1a41706L,0xd4cc48a5d2e48256L,0xd580559e05cb19d6L }, + { 0xc8983311e6466ae0L,0xeab62080174df01dL,0x710ebd184a0441d1L, + 0x0af69d9a9f653d0eL,0xef3a2510d789c932L,0xb5959cb992fbd39aL } }, + /* 63 << 217 */ + { { 0xdbbdd5fdccb1cc9bL,0x660110b98a26d874L,0xfa80d8b60fb9ff2cL, + 0xfeb5cd6b95040da7L,0xb526ae0c7366cf25L,0xf49d85fce3566146L }, + { 0x3b4107e699f505e5L,0x3c2d618f4302bbaeL,0xdaa09d150b199866L, + 0x3b65cb88c395abf5L,0xd2af1dedbd5ac4eaL,0x0586f5a5276533d1L } }, + /* 64 << 217 */ + { { 0xd927283013575004L,0x01a330d620b2275eL,0x58b9207f450db713L, + 0xae95338423e16d95L,0x4f10c6d4e60e349cL,0x541d03ecfeb122bcL }, + { 0x22548cd22c648211L,0x5c2dc84cd01354f5L,0xa1c6f912b6167b3cL, + 0x6967bab27902d2baL,0xebbe0b0836de34baL,0x6985b33a4b79625eL } }, + /* 0 << 224 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 224 */ + { { 0x9e857f33771560abL,0x4ae1ba22250f109dL,0xf8538d68ff4f6566L, + 0x35380f15ac339148L,0xfef0bfdd5ddfc12fL,0xf706c6bf1387d93eL }, + { 0x618ce77d5357e131L,0xf0921744236478c4L,0x24eaf06e00dc0da5L, + 0x049113be07603cc7L,0x5cf489088f6963c7L,0xbe5eb9e6ede4a300L } }, + /* 2 << 224 */ + { { 0x77e486f85d066c15L,0x0c05b6c24ed5307dL,0x322b28ab7df36628L, + 0x2d14d1316704dcd6L,0xd359977af29a3567L,0xc29bb132ec96d3b6L }, + { 0xfd6e400ae6bfa701L,0x03db99244c7e5101L,0x62d81c7d9b8533afL, + 0xefa638c28de66eb8L,0x7405a9d7e86784eeL,0xafaa74efa6c22223L } }, + /* 3 << 224 */ + { { 0x6909994f0572e536L,0x9d22f9157fed8954L,0x1505ca05884aaca9L, + 0xe4b6530996995a98L,0x30e00a5ed02c000eL,0xb9032350236e7b09L }, + { 0xe696f09e14f6c7bfL,0x2126b6277dc18d06L,0xa9ada7b401e1e2a4L, + 0x9630acb69d2d025aL,0x9fab2c6ed84ffeb1L,0xc1d0db26ab7584f6L } }, + /* 4 << 224 */ + { { 0xf9b2dba4b9d36e91L,0x5fb4f6cefda9b2c4L,0x7692a4f33b8104eeL, + 0x5da885b0e4e1896eL,0xc2a30fec73d2aa36L,0x7d06e6af86f60bcaL }, + { 0xbc8bf16d87287887L,0x6c3dd86a3d701becL,0x8e79e2f37e35610aL, + 0x981139f482f9d71cL,0xf8997ec424e62733L,0x330d989aa3518061L } }, + /* 5 << 224 */ + { { 0x6cf0e6ef9b7e3cc9L,0xb465be6b0320acbdL,0x02777783856111dcL, + 0x3a1d36f0c0e9f2b0L,0xfcf4f6365e7fe507L,0x36bf41827fa7c8f1L }, + { 0x09a02de8b0f4ce56L,0xa0bbf65ca9cdb353L,0x7211a9654b7f4e35L, + 0xa6b2ba79805b58bdL,0x418302c20957860cL,0x3c17ec02f99f9d58L } }, + /* 6 << 224 */ + { { 0x4e6ef410ca89fbadL,0xe0fc53ba53933b78L,0xa4f03403fd41d143L, + 0x3a507177e0774c37L,0x078e8c568ec7484aL,0xfb73c6b6fbb3f66bL }, + { 0x169c94753bfbdff6L,0x44d286060a232243L,0x3e8e968508303114L, + 0x7a9797b8fad0def2L,0x0ad14404efc1c8daL,0x6daae4e921ced721L } }, + /* 7 << 224 */ + { { 0xfde0d1b4cbfd18abL,0xa3c9917595850f83L,0x16d3ad79c9eb9de3L, + 0x2707ec8b0ffbcdacL,0xd7e6750fa220287cL,0xe51baf059c2e155aL }, + { 0x3018c309871e10faL,0x074f08e3f23221c2L,0x1aa323aecf15a4afL, + 0xf085d69cc1b8cca0L,0x47a3eaccb143a969L,0x56a04522f3a98430L } }, + /* 8 << 224 */ + { { 0xc7e9ddef88dd2dc2L,0x2c21a99819a0c0b5L,0x6bc0746db239bb82L, + 0xc811a8eb28ea1341L,0x5f714ca71d1309b0L,0x79eabd20d4eb9b34L }, + { 0xe0e5afdcdf0fb30fL,0x1b01a16d8c0814c6L,0x670e1e7b84334366L, + 0xc8c38f9a0eed1116L,0xf914fae2619bbd50L,0x1ed062cb51c1995aL } }, + /* 9 << 224 */ + { { 0xce64d065b711b4e9L,0x32760c2eefc4d25eL,0x9e5916caa6292c7bL, + 0xa90d40bff2a47deeL,0x90dc6681604933d2L,0x707270c60115cf42L }, + { 0x55b601ff6fe583abL,0xdd2fe842a039dafeL,0x602d8de34c2d3357L, + 0x7cc979bca7ab9014L,0x4b8dcf7e60118797L,0x7f1f2a04cbfaad32L } }, + /* 10 << 224 */ + { { 0xd4e60e15cb583422L,0xc6b1ef90320f296fL,0x0714bad0d9bfc834L, + 0x5ee2ca8c9050e2c2L,0x074a8ca824f7cf1dL,0xb975024910df8516L }, + { 0xecee8ab7c2636d2cL,0x308e5af13b4b7bbdL,0xfed4f27eee2ae021L, + 0x7cd4bb192065253bL,0x6b21a3f84de525b4L,0x0f10e7bdac27fddbL } }, + /* 11 << 224 */ + { { 0xb4f02d9dbb3bf37aL,0x69590395978aacc1L,0xdf99b1309c3def3fL, + 0x5c66391e12be0bceL,0x30ab382cb5eaf100L,0x9b84b2b4e0352249L }, + { 0x0c22e4e1af14e85aL,0xc29d3c592286ea0cL,0x6c7f8b6a40758aebL, + 0x7a91adccde68fd0bL,0x4d8554fec8e8fd4aL,0x9fa863d5bb5621e5L } }, + /* 12 << 224 */ + { { 0xd5068487870e29cbL,0xf9420b85fc52d5cbL,0x50c3265a496d000dL, + 0xe605414a166bd6b4L,0x4de8d724c62b2a6cL,0x16af06f2a1a11048L }, + { 0x5406bde945f43c4cL,0x5e15bf6c751ad18eL,0xa846e665b6a59587L, + 0xcdb28a7d1816ac55L,0x899b3551819b73f8L,0x2d46297bbc848d08L } }, + /* 13 << 224 */ + { { 0x76f5aedd44af60a1L,0xf7bd3b4651d1efd8L,0xdfbf3c6439a9721eL, + 0xf927fbf0ee9d2ab3L,0x628e9258c7e0779dL,0x062cb2fe4cf1dccfL }, + { 0xb2ff57dde2278f00L,0x3f0e140a2d199ca3L,0xe7161304342c0a9cL, + 0xe7ca734f0bdbe131L,0x7d070270870057d8L,0xf6f1a65daaa55860L } }, + /* 14 << 224 */ + { { 0xdc4cc720299127beL,0x5b34e762faab8165L,0x2289b2f7b39c120dL, + 0x687a78d06e52b913L,0xd2a091dd2a3ea6a5L,0xc61eced638eab329L }, + { 0x652231ea7887ff2bL,0x77a568750479db4eL,0x1ef471c8d43c5722L, + 0xf82bf436f3764c34L,0x962af4050445cafeL,0xed8b227f5ff47259L } }, + /* 15 << 224 */ + { { 0x30e045f4a73c3da0L,0x13d2527df36c6346L,0x3dffe56d3836fb9bL, + 0x9518276617c5d2bfL,0xa0ef38724dd0b240L,0xb45e19ebc39c675aL }, + { 0x65202bc603e95445L,0x41e2f0d19a2ec9dcL,0x51c719cf2a0d762bL, + 0x3bfb9729ecc6b9f8L,0xda8271705a261640L,0x65c2bbbcaeee5f3fL } }, + /* 16 << 224 */ + { { 0xde849cd1d89594abL,0x00e2d2b10ec4fb3aL,0x3fbd9e3dabe92fbaL, + 0x785414d43324900aL,0xdaead1abde20904eL,0xb493e121aa5f1ba8L }, + { 0xd60a4f2d6eaea0dcL,0x394746b56fca8596L,0x163dc78934efa243L, + 0x3067dccf216a8d8cL,0x116b6534a901617bL,0x8c4bd099bbabe51eL } }, + /* 17 << 224 */ + { { 0xbb9eb22a97ebad53L,0x791d4f90666f1428L,0xa3a896e06c5d5569L, + 0x322d566fdefbc26cL,0xaa581a083c039c26L,0x82d899be62790f0bL }, + { 0xeff4bb9a43a0c2f7L,0x60515c10a01df2c4L,0xdd1455a849312160L, + 0xc8a15052c4292265L,0xdb2970f97f68d081L,0x29c825b892594c4dL } }, + /* 18 << 224 */ + { { 0xc8c2df45ac3a082cL,0xc353d074c8d4c40eL,0xb214f9c05a3c2de7L, + 0x504bc42cf86b0214L,0xc82df5cbd1922a58L,0x40887948a5bc3267L }, + { 0x04bcd21788ba8bb2L,0xe21b3e7f046fd401L,0x8419c338616af5cfL, + 0x7f24760baedfce9dL,0xded8035bddbd519aL,0x1f1fb0d71693faabL } }, + /* 19 << 224 */ + { { 0x7a88376766117f71L,0x8d4e37815d261599L,0xc900e6dff770b193L, + 0xb7d1c06b12e9dda7L,0xa86d173a717cb0faL,0xa138b7ba51dfbeacL }, + { 0xe84468c57360a27cL,0x4acf8b412e9b82a2L,0x85fa386cb121d6faL, + 0xc794d9f283e6169cL,0x7b4cd3fc8c9293acL,0x3096ad868d082719L } }, + /* 20 << 224 */ + { { 0xbb067b49d02ffcf6L,0x7cedf8f93e657299L,0xc3829961406bbfe3L, + 0xefe4b5aa37c12472L,0x7dc01cf9fec7dee8L,0x70a9db2389472f50L }, + { 0x29c269f8b31bf737L,0xa26deac3ae3fa7dbL,0x0046e91233caca41L, + 0x3bf4bc8ab6e78b55L,0xca83bc6cd9eb5ef1L,0x73f25c62c0c5deffL } }, + /* 21 << 224 */ + { { 0x117bb83d3ff7d803L,0xe91098c539c56c0aL,0x7bf72fe91e347fa0L, + 0xa66201a31e174941L,0x1d069d4d6846a06bL,0x721cdbbdcda59bcfL }, + { 0x17d6683a17652893L,0xee1b28f505be2530L,0x2e70558697a69062L, + 0xd4b5798682b56c36L,0x1ccc5be09082e781L,0x42e0e429d6b05e30L } }, + /* 22 << 224 */ + { { 0x697dc47d44b4aae8L,0xb3525cc0782c331cL,0xff71cca40bd7c78cL, + 0x5f3d776610c0ab69L,0xbdc10267e2ba07e3L,0xc656f75ce6373f6eL }, + { 0x9e2938b4b5607b62L,0xa65017d410b0a0f7L,0x8dad31195cc6ac25L, + 0x00f8f2d18ba5d1e6L,0x608137bc43305aefL,0xddad34bbdcb81cb1L } }, + /* 23 << 224 */ + { { 0x9e46b17c20c78a64L,0x28db365d5c48e678L,0xbe4c3b8eac6ba470L, + 0xee737236b6617b28L,0x81c5b94a4f3422bcL,0x4d44c33076faa922L }, + { 0xd7a09a719be38835L,0x99d024e1410b382dL,0x103b67c36b15012eL, + 0x02b6e094d9808da4L,0x4f5d938a0a7f2fcdL,0xa43058b7e4c5073bL } }, + /* 24 << 224 */ + { { 0xe133d941b1f82ca5L,0x2af8b98bfdf115bfL,0xdc6179c857aaa6f3L, + 0xabaa83e9130ade06L,0x7836b6fb0e8bffd1L,0xc479751ffa103703L }, + { 0x0ff3c1299c89963bL,0xe64072560b84c24fL,0xa92a4ea2f34f6bc9L, + 0xba45b3053197989bL,0xd12b5a0199243aabL,0x3015772c442af625L } }, + /* 25 << 224 */ + { { 0x5362ac737e0a5c36L,0xc731132a8c4fbc07L,0x0ef7468d7ca0d4d0L, + 0xc43afef835d25de0L,0x096bde6a3fa1209bL,0x21f57eb566846236L }, + { 0x878b585cf04d23d7L,0x737f7e527315ed56L,0xb716462c811afdd1L, + 0x4d223734a571a3cbL,0x56460e2fa7db2c60L,0x0684d72c61f97485L } }, + /* 26 << 224 */ + { { 0xd95fca81e6f065c5L,0x45e886d5fc8655deL,0x3580957727cff79eL, + 0x92a39a34625877d9L,0xdda02684dfee17eeL,0x6354f871986f635bL }, + { 0xb3a6e9edd409c182L,0xf0b1c8d9c4fbbb3aL,0x28721c019b77adedL, + 0x3c356df1bf94f028L,0xff221bd229a81f1aL,0x20edf2e856b20b0dL } }, + /* 27 << 224 */ + { { 0xb8c636db31ac60c2L,0xf3830e72bd987402L,0xfe63957c30e6b969L, + 0x3508e67989eb2bc4L,0xc0837f8c9a987e3bL,0xd1d0ce7b3f9b2ef4L }, + { 0x08d8f99441fe62baL,0xe73f79d7e17669d4L,0x8801fabaee6d68feL, + 0x4ef814891a508a88L,0xcc851bb71fbc4512L,0x69f728704680b88aL } }, + /* 28 << 224 */ + { { 0x97fff124835fda9eL,0xa79ceb2f0bc68512L,0x70ba93d1a2fc3995L, + 0x62bd28ab9e51c5eeL,0xb95fa624d5bbbaa9L,0x0654dc458c1f571eL }, + { 0xb9a4edc665a45ed6L,0xbf5ed1bc21ad0612L,0x74adc1a1b1a3551bL, + 0x3dfa3dc8dbbd6cefL,0xce5dd40b2fa3afd2L,0x14894e0f30a746caL } }, + /* 29 << 224 */ + { { 0xe4544006ada9bf7dL,0x9e123b709b75770dL,0x903628d557cea95aL, + 0x6429e00c9e8cef6bL,0xafa2cce77b1adaa2L,0xf2f5771e15e488daL }, + { 0xda44962269820874L,0x5b20ef1b6e0fef81L,0x3150a8699507b4faL, + 0x901897add191de20L,0xf459da31c41dbb2dL,0xc2516dd077146754L } }, + /* 30 << 224 */ + { { 0x7e729c58b8ca2a2cL,0x0f32ea1ecaac04afL,0x47267f13bdd549e3L, + 0x35b9440690be3b50L,0xad0f2bb14b27f670L,0xd7e5874e92341803L }, + { 0x7dc841cf1f9ec462L,0xebeff994512b2a42L,0x22998a7f320dc858L, + 0xf08eb5c719946f59L,0x228c8dcda68ea75eL,0x40dc6dc37b20dee5L } }, + /* 31 << 224 */ + { { 0x23f40e331dd722adL,0x0a441bf4c54fc48fL,0xed6c026548b75f84L, + 0xc2d3972f3e0fff2bL,0x889b44c4db09b7d9L,0xeb6ccc6541a6a562L }, + { 0x5ef1162e8f04e03aL,0x25e2ea895d8102c5L,0x37b71631154644d5L, + 0xa9a1a8320446b1bbL,0xe3f58daefb342b20L,0xc6d19decb6d292c3L } }, + /* 32 << 224 */ + { { 0x929454f6b3952db4L,0x412142ec4d3f69f5L,0xf5b0a7c5ee25c0b0L, + 0x7d3372ff2e752295L,0xd6dadc7d6eacac68L,0x5f0076cca96a8e3cL }, + { 0xea831db671725b3aL,0x4a286c89c29ab454L,0x5ff817e572e3c00cL, + 0xb022e25d2a5fb6baL,0xb611c5bcbb392476L,0x062c14dc190485a0L } }, + /* 33 << 224 */ + { { 0x44730047ffdc9a7eL,0x44949bdcf078d5bbL,0x8c1a3e4bc486e2b1L, + 0x53088ba20801402cL,0x6e20a7cfeac83daeL,0x4407ea8436ec5443L }, + { 0x564fb733853f79d8L,0x59ea819afe809670L,0x1ac62174f1ec7e91L, + 0x0d7e065566a0b8c9L,0x0c4d072482958221L,0x80db0297a60f984eL } }, + /* 34 << 224 */ + { { 0x380823e7f3359d47L,0x8a60fb05f5efd39cL,0x78a940669425487dL, + 0x1da6abc3f199c67cL,0x7df00b2165f0a6b1L,0xdc0dea58017b1231L }, + { 0x9c529db079f4f22fL,0xc7043be3e5dd92b5L,0x10153ffb43661331L, + 0x51c459bf6ff02e8fL,0x451483bfa43aa005L,0x3313f903199cd1baL } }, + /* 35 << 224 */ + { { 0x2f66587e62e1ef1bL,0x942d4c739e3ae33fL,0x4a27ead5c0ab9c1eL, + 0x368d8dd89ca91b06L,0xb3f0cf92c4b6ed34L,0x28cc332673e62557L }, + { 0x2649e5527910986bL,0x635dcf9cdda049abL,0xbbde12f625d3f201L, + 0x5200c3d0a9384443L,0xd996573d51eb3c10L,0xb093c1792b8cd7e5L } }, + /* 36 << 224 */ + { { 0x15cd1d1cc3fe6fa4L,0xf260a739e2c3c686L,0xf7c2270eb08c65dbL, + 0x9ada2cb6ff69d971L,0x65fbbcac212bff0cL,0x40157d075646a735L }, + { 0x101d2b7d55de9e45L,0x0db580e83118b763L,0x3203baca8322a9cdL, + 0x2a3137ef22cac14dL,0xcc9092e291a14128L,0xbb269f6d98cc368fL } }, + /* 37 << 224 */ + { { 0x7c8946002ad7f66fL,0x6a8328bb99b438a7L,0x86d06fbbdb440d86L, + 0xb74ffe2d20ac5a42L,0xc3a6f01d91b1c82bL,0x606f8ce71d5efbddL }, + { 0x8c49c43a6338c99fL,0x50657f7216da7cb7L,0x7f204c8b84f22d9bL, + 0xa2612d80ca76978dL,0x80080d868a3e8e96L,0xd8841a1ac0bff9afL } }, + /* 38 << 224 */ + { { 0xc2a734cb962fa060L,0x2baa26c580a17874L,0xe27b21110b44efe6L, + 0xdc1244e531d2154cL,0xfcd86d4116c7742bL,0xf45230df32503138L }, + { 0x94a790f4812cf0afL,0x0ab2df23da3f24d7L,0x0c764df181571d54L, + 0x989ff71c68d68f74L,0x9896fe62cda535b3L,0xfe0502e05f4fa41bL } }, + /* 39 << 224 */ + { { 0xf1ffe852c2f58cf6L,0x2ec46d2546d64576L,0x95bfec93d602c51aL, + 0x349c58bf3907b766L,0x59cb12bb9b94bdfbL,0xfa95da9515dfcd87L }, + { 0x731a8535e1543bfbL,0x14844aeeca14187cL,0x0d73e58aba1f4928L, + 0xbb71009fc6bb67f2L,0x5e7c0e988b4142b9L,0x4866b5095f08f58bL } }, + /* 40 << 224 */ + { { 0xc8295c2fa234de87L,0x1cd7f3fd878e77dbL,0x309c1fefa2155b6cL, + 0x2a9bcfd9484afddeL,0x87ef7a56cc999775L,0x34336cb1970aa188L }, + { 0xd45eb83cc3e16ba1L,0xf9d72c72b9c1695bL,0xff117458cb980742L, + 0x438a7fcb67af836aL,0x5ffad086eb9a6c40L,0xdbd3e518513922a3L } }, + /* 41 << 224 */ + { { 0xde241983e42021b7L,0xaa70e834542873c1L,0x99c9d35f9daf2b99L, + 0x0bf712d549b40780L,0x202d9969d9ab6e97L,0x7f3382dac4932106L }, + { 0x1eb5f5d40849e319L,0xc1bdd1179f659546L,0x628ddd3d2329f977L, + 0x5944611d363ee601L,0x7b7a631463d5bd4dL,0xaf6c51a5631d21ecL } }, + /* 42 << 224 */ + { { 0x2d8f9e1db4100182L,0xa08ae2fe4f3d2c03L,0x7548c430589e99f8L, + 0x0f5ccee2aede8af9L,0xa21ace3343b34b25L,0xb120c569dee102e6L }, + { 0x1cb103ed36f13699L,0xf71ff0dfc91e8cb4L,0x88f141079b22460dL, + 0x050af75af509366aL,0xeec8a310fb179bc6L,0x069e7331c26efef6L } }, + /* 43 << 224 */ + { { 0x3e2a9c713be9cdabL,0x8f235d6f73ac08e6L,0x3de28a6b28832dabL, + 0x7d08b9f31ee82d6dL,0x67c3b88f915ddda9L,0xba8f18cc0f7c81a3L }, + { 0x38cebc31ca3c0936L,0x745f71aa7816a6e3L,0x00cb85a91a95fcd3L, + 0xb92742c6577dc22cL,0x1afdaab592029cbeL,0x0bb43c91278d3f7cL } }, + /* 44 << 224 */ + { { 0x3d77059d3ba02d27L,0x58e28671440b2d3dL,0xe2d4235726636fbcL, + 0xcc448a52c54605d5L,0x73c2902efc0269a6L,0x28a15ed57ea8c26bL }, + { 0xf666587a0cfc1a34L,0x8374f2cc1ae0377cL,0x5dca6ae828417437L, + 0x15a6d54c94bc87ffL,0x5bf187bbb344796cL,0xc629c14889574b2dL } }, + /* 45 << 224 */ + { { 0x06d43c6d87748b63L,0x2489a957a7f232edL,0x7aa9174afa407c3fL, + 0x8c8b8fd933a762e0L,0xe2e8f1e7adbe94a3L,0xd1e0c8c2bb723045L }, + { 0xcafd8f483df092d8L,0xbc89caebb174025cL,0x97595c5649f20c98L, + 0x6e520a968a77acefL,0xc3dbd3107a52a4e6L,0xf51db5a91284ff27L } }, + /* 46 << 224 */ + { { 0x406465742c74cb2cL,0x44eeb9e546c33df0L,0xd2a9f16ecb4c50b2L, + 0x68f912a01906a6ccL,0x2b81296d95211e94L,0xddb2988ec8575839L }, + { 0xb74d990d33b180c0L,0x290185567d319c48L,0xd3d2e40dac8de56fL, + 0x9ad42a60461f30e6L,0x265e4715292a0faaL,0x56c2626c8ac3b2a5L } }, + /* 47 << 224 */ + { { 0xb7580f2fd468adb8L,0x8e1fbf0388a6a587L,0x1b8c40ed8f4f6cddL, + 0x337414f56817b2b1L,0xd877ebafb744d563L,0x59eed3c6df5e18b2L }, + { 0x365e148dd33afa01L,0x82e70adc665702cdL,0xccd77955a5e390ebL, + 0xd86c343accc90cb2L,0x23bd948d6cd8a33bL,0xb1fc140cdc43a8cbL } }, + /* 48 << 224 */ + { { 0xefda99d9ce11b02eL,0x9017bd4a3f820083L,0x8b9e6cd1ad14ac6fL, + 0x1239ee331f413880L,0xd98e93d993dd7fb9L,0xc280d252894fcb12L }, + { 0x33a9201a5230b5eeL,0xc6aeee256e41de26L,0x845051280d0a320aL, + 0xc20551db4b607b53L,0x6e63c766ea228c2eL,0x883321aeac48f25cL } }, + /* 49 << 224 */ + { { 0xa5173910e15a530aL,0xaa2c88b83ac38ab2L,0xcbfbd31ec6a6ba9eL, + 0x0fa126cb49ed182dL,0xd6b38897cfc53c85L,0x98d5f6bacb9c2f41L }, + { 0x6694e8e5cbd150e9L,0xd470ef226a1fc551L,0x57a63765d5ea1c0aL, + 0x95f5eb4318078139L,0xbeaba00585d3e0dbL,0x6bbf010fd314dec7L } }, + /* 50 << 224 */ + { { 0x5941229729ee46d3L,0x39e5aaa0e66bdfabL,0x9ff1575001c815e1L, + 0x709706211f2de195L,0xaac904a968aa571aL,0x9cbefacd8f7625f9L }, + { 0xadfd215dfce3a501L,0xc04d09ddf20651b4L,0x688c1421d17b25f2L, + 0x3efde5d40073247cL,0x999b7f3a7432c699L,0x33c76487703fea50L } }, + /* 51 << 224 */ + { { 0xc720aeb10af6e1faL,0x1564b8d8e8771dc6L,0x5983eb44673d8ef2L, + 0x5dabb2070679ac65L,0x51a854cdbcdb681eL,0xe2b186a9364a3cb1L }, + { 0xfa189eff7222208bL,0xf7161d86477666f9L,0x0ffcc3e6192d1df5L, + 0x1523508e39cf5a4cL,0xf5e98687c43ecce8L,0xbf17b63261450309L } }, + /* 52 << 224 */ + { { 0x63293cb8adfbde28L,0x5df78fb3c6b18ec4L,0xad10da4ffd27e50dL, + 0x60202b357ade5c9aL,0x67b9d253c6c8c8b5L,0xdbacffefbc2b30bdL }, + { 0x508ff8a67494b1edL,0x87ef48be3769728fL,0x74d4f180ef98d036L, + 0xc5d9ef531799e8a9L,0x726d22206e850162L,0xd86d3414239f6b38L } }, + /* 53 << 224 */ + { { 0xfdde327b3e1f1b96L,0xb6272e94bb58615dL,0x2881350cfc2d8a47L, + 0xfcbe87031142ab9bL,0xaa5fccd0f48c7f97L,0x606be6ed29a74ba0L }, + { 0x545409ba3afc598bL,0x4779f54aa7d23f5dL,0x2811c0829d68e38eL, + 0x5b4646bd3f9c5842L,0xbcd3aa492586219aL,0x7345799313642e3fL } }, + /* 54 << 224 */ + { { 0x9a61f240ab638788L,0x519742162b0a8449L,0x9a5ec31d43b2abfbL, + 0x6f3075740563c9c9L,0xe465f7793ffa198fL,0x8876c5772957418eL }, + { 0x10e3d09c976e5875L,0xd66d334e592c2409L,0x3f0d5727b39b7897L, + 0x17ca7ad1e37fd300L,0x221d8436da530871L,0x4df38e4179d6b350L } }, + /* 55 << 224 */ + { { 0xe805096338b7a2cdL,0x9874cc734b8f05cdL,0xfc0821791b74a790L, + 0xe18a92f3293049a6L,0xabd525694dfdc13aL,0xb928cc300d843466L }, + { 0x12750aec348dc7c0L,0x3c8e205d87f12dbcL,0xa2c71091e0bdbd81L, + 0x895b56a0c1c1871cL,0x68dd7414b4c850f9L,0x45a948ecbe806596L } }, + /* 56 << 224 */ + { { 0xa88dbfe0f4fe35f4L,0x32de3a1c84283011L,0x8a3777bc39caea33L, + 0x673630dee4d49959L,0xf3ef842c59070317L,0x33e4bb031fab88a9L }, + { 0x88e4538e98ce8bc2L,0x870c2eb81a235c6bL,0x71f62c5640df0e92L, + 0xdb43b853f9627486L,0xfde9fcaa95cc473bL,0xe4c5b4bb4b677b11L } }, + /* 57 << 224 */ + { { 0xa6ebd946dd4091f8L,0xf0e11886dcf0741bL,0xd6267674d9533601L, + 0x571926506f74e49cL,0x18269c2f891d6717L,0x350a7869b45ddb53L }, + { 0x79ea6a4ac8f62777L,0xbad33c4cae7edec9L,0x14bed149ad7e5578L, + 0xb2f4190ba91af4fcL,0xbbd6f68be71dfd3bL,0x23fd3dc8f2fb7a21L } }, + /* 58 << 224 */ + { { 0x5e0f89e598fd044dL,0xb77180d97cc30e97L,0x64fbfb747f82a12dL, + 0xbeebb9ca77629636L,0xe164549feba83845L,0xe65a964a7079519dL }, + { 0x8b1bcc08ca88157cL,0x466399c3f7483338L,0x6e2726414b9efdc6L, + 0xff8c7027be922e96L,0x9baebf7d48374f59L,0x2a84a23ac18ee18bL } }, + /* 59 << 224 */ + { { 0x337484e0dca4b3b3L,0x82137cb9f5b27d3fL,0x12ae1d11bbf4c806L, + 0xa1e2873f2880c078L,0x9e6bd909058b9a0fL,0xacc5656d2dba5fb9L }, + { 0x7fe5467853fd2ce3L,0x2aa4af35452439efL,0x329989a5904ffc67L, + 0x007ea4c8520fd31bL,0x58988e2551816b44L,0x644f2469d8f186eaL } }, + /* 60 << 224 */ + { { 0xcd4d1a9e8890722fL,0xfa0b826b74142916L,0xa494dfa817ba8041L, + 0x3fb73e736de2b6c2L,0x156a6cf4344b57a7L,0xb197c8621e205448L }, + { 0xf453e348c214acf7L,0x665d7083e9061a73L,0x5ed59ec5ce9868a3L, + 0x9bab305f6ad777faL,0x752c490b35315de8L,0xabcfa35b5d5aaf26L } }, + /* 61 << 224 */ + { { 0x4059fc2f914d618dL,0x88e55ce6108380fdL,0x0c22b21bee61a4c1L, + 0x435ecbdb04788627L,0x3f8a5ec7a9f72788L,0xa31eff8a732d5d97L }, + { 0x119b6bf9d48d0af9L,0xde6d1de5af70a043L,0xac075ffd3368db4aL, + 0x23a33ec94a58603dL,0xd43ad120fe181a89L,0x386b90ed42f0b006L } }, + /* 62 << 224 */ + { { 0x8096824bf9bf1a24L,0xcdf69abc8260ebd7L,0xaf93b34de9ab190bL, + 0x676351ff841cbba0L,0x3db704d3eb6d6c60L,0x3b1b893fc09aebfdL }, + { 0xc06b9bfdbfc69f15L,0x28b1ffb8e9c688c6L,0x1607bc68d3c16455L, + 0x07d56bcc6d16d937L,0xac28e69f318afd9aL,0x7f4afeb7e77263b6L } }, + /* 63 << 224 */ + { { 0x796a530ab935875aL,0xd6700ec89dd1e51cL,0xc30301df4d9320e4L, + 0xe23090f357157f87L,0xdd3f68a74029113eL,0x566afc6de2709936L }, + { 0x830f952edbff8926L,0xe207eae5c7a39d27L,0x9210b3dfd9494592L, + 0x3be25582d8460831L,0xec2496575d58edd9L,0xebe8426fefd24738L } }, + /* 64 << 224 */ + { { 0x0372678dc419b0aaL,0xf95031d8c13fdf17L,0xebaebca4b79594c3L, + 0xe587850baf3b75cfL,0x534183ac2c1e09c6L,0x3f5b0bfdc08204cdL }, + { 0xdac2cf06e297cc77L,0x5e47d9c6d0487084L,0xf6f509f490b0f6c2L, + 0x3ffc3cd6c2c62207L,0xbb21eb1132ff1887L,0x2116a023e62ccc6fL } }, + /* 0 << 231 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 231 */ + { { 0x406a7e2116960728L,0xd03923f85597d8c4L,0xd4402eff020748eeL, + 0x7827442af39b58dbL,0x77e3f2768d8cfb04L,0xf6eb49c8e45a978fL }, + { 0x9db0829949247f6aL,0xce71a74706669fe5L,0xe434ce47b82775f5L, + 0xe84995ef63910016L,0xa35e8b971e47792fL,0xc779cb3d7c6aaeb9L } }, + /* 2 << 231 */ + { { 0x1fa064cfaf31ea1dL,0x2a9547a848e8d974L,0xda8102a1fa9d9453L, + 0x786aecabdc6bd7eaL,0xcaf91e3bca2f6044L,0x67d86ea78573f208L }, + { 0xd309fce9c505ae24L,0x67ddc5b17f86eb8eL,0x57791ae0f3d53056L, + 0x26b053f00d1fd61eL,0x91c962c0045ebfa6L,0xe95246de076ed979L } }, + /* 3 << 231 */ + { { 0x156eaf570746d174L,0xa2d4a83dcda35250L,0x60a9f48c0290fa02L, + 0x9855d26d5c33b4acL,0x06e379c697eb1c30L,0x4f2e2dbe6e219664L }, + { 0x6b7448f829006065L,0x237a1f31115062a9L,0x5c635a90ad92cb24L, + 0x2e857f8c2eed977eL,0x3d512df7856dc88aL,0xbde85263e597a27bL } }, + /* 4 << 231 */ + { { 0x49f24994e7c03ce4L,0x274a8c132aed9ba3L,0x897b9103d5e91bc0L, + 0x63db1efbcb404f68L,0x70efd9d842f7fc02L,0xd6e02921c6a230afL }, + { 0x8d5b199f11ae0a56L,0xc98287dece33da6aL,0xde583d34504dd889L, + 0x03756001f823686fL,0xf19ab86f95fc73dcL,0x300406c693f12f42L } }, + /* 5 << 231 */ + { { 0x2f73595f7759701cL,0x8dc2069a6fe0e0d9L,0xb7de7114c286a65dL, + 0xfecc429e84c0e487L,0x51061a2c14344c07L,0x4d70972596869e37L }, + { 0x8b02781f2be9403bL,0x6cb6aa02de3ab5d9L,0xb013508eff6bdc9aL, + 0x568d2e84e5438c58L,0x7b35a979e4206c3bL,0x0bb793c0b17a8bc7L } }, + /* 6 << 231 */ + { { 0x3f896ca9fa4dd561L,0x4b9a98abd2de2ecbL,0xd0741632600e4e2aL, + 0x87c7db5f69e702d5L,0x1f5a3b8053e0df2bL,0xe1e24b49f443dfbaL }, + { 0xeb90e2305eef3a1dL,0x8f3fc8a6d38f73fcL,0xfb1e8299a5aa335aL, + 0xd78504cd4197b32aL,0x0e7a79cc6755918eL,0xc7c98ae2883b1c72L } }, + /* 7 << 231 */ + { { 0x1a12727c03d2beccL,0x810a37dfc6741372L,0x44ac483fb7049f39L, + 0xab73e5e7a36fc614L,0x298d453feeff8aebL,0x2127dd167e1b586bL }, + { 0xeadc5c54e07bd60cL,0x67cdae00f5e2d2e2L,0x03fe0446c9d2f10aL, + 0x0784098795e38ed2L,0x5d348a7ce1a6306eL,0x4903f1b6562f5463L } }, + /* 8 << 231 */ + { { 0xbf66baa5b44b1d0cL,0xbbed18eda44f8edaL,0x80bc32abeaaa466cL, + 0x605b7897e5f2733bL,0xe9e7e3a1a2531afaL,0x25d66db33deb8369L }, + { 0x36212ea3b2f25d10L,0x52d6b3f4a08d303eL,0xefa54b31444e9e9fL, + 0x9c2229a169530c1bL,0x68feb9854b79bdd1L,0xd570e84f8b984cc3L } }, + /* 9 << 231 */ + { { 0xe141b86bde0560a3L,0x858bf4cdb2264bd1L,0x526fb104fabe5359L, + 0x95f9c43f185b8a70L,0xf8e3a3eb2d1f75e9L,0x71826067d93bc6b9L }, + { 0xf360e01799692f49L,0x00f4fd16c2dc3dd5L,0xeb7f40498b9454d3L, + 0x5cb0f3c426c3b393L,0xe8ab4e4357bdc4d7L,0x9abe36b00c123d67L } }, + /* 10 << 231 */ + { { 0x1df8d98c57b168fdL,0x042fd731b45da94eL,0xa54d64f91703e143L, + 0xa12198be9de0ab4cL,0x160e06241ddc4e0fL,0x15cae64a6695891fL }, + { 0x808565e70c2b2081L,0x6de4a393cc65040cL,0x6682cd934bac1768L, + 0x62e7ac2ca5be965fL,0xd33f6f8ad7a38e90L,0x9cafc4635b8b516eL } }, + /* 11 << 231 */ + { { 0x0541a391b685c547L,0xe86d35e091765999L,0x65aa03c51db4a2ecL, + 0xba53470e6b1c4784L,0x4f848cc8cceca1faL,0x89d0db0b8b18e350L }, + { 0xd03e452a7840d734L,0x6cebfa790ca24215L,0x288b4569e8f1d9e8L, + 0x18e405af8927ce0cL,0x5aad57e51abfb4c8L,0xbbd99091a197ed1eL } }, + /* 12 << 231 */ + { { 0xf041e421aa44f3e2L,0x47ed9e8eae6fd2b7L,0x4fea93751128ed62L, + 0x041a1c1acec6eae6L,0x1f32359415a65daeL,0x741fea0a0154e8e8L }, + { 0x309e9f289c32e224L,0x457d4ffa902ce57bL,0x7bb54dd5692420c2L, + 0x193a41aec4fa1a6aL,0x35f5f3b43d779e77L,0x31e84371046ebb8cL } }, + /* 13 << 231 */ + { { 0xe75a7c1d9d7e5551L,0xb73c987611635e3bL,0x3b07a071e09d29b3L, + 0x0a3cc0acc623023cL,0x15ec4a7a1e2ceb33L,0x09a01968c70eb27fL }, + { 0x2e5bb53c369d145aL,0x4c93330d9b7fb506L,0xbb10a2f358013308L, + 0x3d9da0c4e0b85fd4L,0x8b39c992ce0dc79bL,0x7e6d18b0bec905faL } }, + /* 14 << 231 */ + { { 0x3a5a366ea1554376L,0x0e1687c052a6ed9dL,0x3e16e4aafe5355beL, + 0x6d8bac03ced67666L,0x403eb33ed9344003L,0xd7b9ec0d333ab20cL }, + { 0x9fce1986d64c272cL,0x9d52d64bb1e23843L,0x8e689611921a58e5L, + 0x8f5f115620d5c61aL,0xb17f612fadc81b4eL,0x36e2db30e562f779L } }, + /* 15 << 231 */ + { { 0x98d0bcead01f8634L,0x6e9ba675bc5f825eL,0xfac2d3aa05e938c1L, + 0x434b712fb9c66adfL,0x81c29163a9a61d36L,0x80eade933be8eea9L }, + { 0x10fc6d75c04c45a8L,0xa2c9aa58fb9e8702L,0x9142afaeb200428bL, + 0x4fa28c8520eccf38L,0x3b5f63308209b3e7L,0xf74206ca8cd74accL } }, + /* 16 << 231 */ + { { 0xd6a4d25c845f26e4L,0x71e554ce1b039dffL,0x942059731cdedfc0L, + 0x0c4e385603d6502fL,0x981a4fc5e15ce8c8L,0x85d1b0f17aca30b7L }, + { 0xf2037ef777bb9e43L,0xc52804f4e87ae187L,0x9c98a23c71f3e4e3L, + 0xa73c8b89f47b504bL,0xb9e33f54023233aaL,0xf2bcfc17f92c9f68L } }, + /* 17 << 231 */ + { { 0xb3c1bc26707fc6ebL,0x0bb585b75ef6dac6L,0x70af297f5f707063L, + 0x3d86a8fa967a0ad8L,0x510dae4d4f956cc6L,0x1dbcb2e883c01ad0L }, + { 0x0e480cd28bfbb5edL,0x76498f813025fca2L,0xc015064ec5446cadL, + 0x4ddfe2af3616f51aL,0x76b0d690e6750b31L,0xc4502c050073f263L } }, + /* 18 << 231 */ + { { 0x9120912bb3081e59L,0x6c73c4a2f908b364L,0x408af8c94de763d6L, + 0x3d9e83084000add2L,0x65d197fddcb5a5a2L,0xbfd29f0b2bd82bb0L }, + { 0xa1243e63bdfe09e7L,0x91d90b54d556188cL,0x977dd4a18bc872fcL, + 0xa8e6e7bef4ea7805L,0x12c53bd80a467365L,0x9d7abca493b7f0a4L } }, + /* 19 << 231 */ + { { 0x5faf453a40eeb93eL,0x6801e0d1f1fe9307L,0xe92505d39ea9b800L, + 0x7e911f8108eb58c8L,0x5da7ffcc098143eeL,0xe023262056876057L }, + { 0x5354045bbfa99a91L,0xee660bbebb346841L,0x1dbf5c7cecb3099fL, + 0xe79c78d6a125d753L,0x2a356f10706fc013L,0xe50c50b725f88ebdL } }, + /* 20 << 231 */ + { { 0x663ca92723ca903aL,0x8a64a4dec7681937L,0xe3ec0966a2baa42fL, + 0x688328d7a2906226L,0xc2821e9c94790fd8L,0x7a295b62157501cdL }, + { 0x032cd57d3675c2f3L,0x91d66a57f42e6f95L,0xd75056961e97dcd0L, + 0x7e8ba3ed7d8b6f52L,0x8ddb72c420b0dccaL,0xe09e53bb6aea2d55L } }, + /* 21 << 231 */ + { { 0x3815b1028a009f19L,0x4f76d609f5418c34L,0x7a35cb332a9eabd9L, + 0x018d6c54ce89e886L,0xe00b99e859c9fab6L,0x4f10a0d9aaf6e7b8L }, + { 0xee51f8f0e722fce1L,0x03e8b63179bccac0L,0x66e540c26f327d2fL, + 0x31df4a35d22377e4L,0xba5b0029d5c71cedL,0x6a3e20553ed6aeeaL } }, + /* 22 << 231 */ + { { 0xe932d1aaaffc47ebL,0x75c9d4d8513f85a3L,0x50886fcdf9419cb0L, + 0x756a7d7d49081e9eL,0xe45fff1fe14aff77L,0x022b4ac339846230L }, + { 0xefc3e8dbe89adc78L,0x921bb1538c09ccecL,0xe4dc6aa17826d461L, + 0xa53aa6cefac8f0f4L,0x5d4e4d53954192c5L,0xda721828c722780fL } }, + /* 23 << 231 */ + { { 0x978609c67e4933daL,0x49fd5c5d2539c807L,0x072a911c6330373fL, + 0x40cfa61838177579L,0xf9a7aa4c81c51596L,0x7ba8e7a5b346724dL }, + { 0x79298c06d26ee66dL,0x243323702a9c2792L,0x585e8b9eb6aab53eL, + 0xa39596c6e14bee4eL,0x89b2758828a76dbfL,0x889fba0aa00dc1adL } }, + /* 24 << 231 */ + { { 0xd55a3eaf0a9a8ba4L,0x13b1406b2a8cd215L,0xcb44589a93943e1aL, + 0x91b5e3493a671a47L,0x488654f8efbe0256L,0x448bee4b392ba5e8L }, + { 0x228f478137e762caL,0xe21a2ca7e71b6c47L,0x0e809fe94900fcefL, + 0xb05e1db2815f6c76L,0x8cdf28815fa6fa0cL,0x2ed55c1c586fec8fL } }, + /* 25 << 231 */ + { { 0x7c3842eba210d4d9L,0xd656154e5f69a69bL,0x9e11c6db1f3a0483L, + 0xb0314a5e5a217444L,0xe17a274e34f4e54fL,0x6e41c20a9f79d6abL }, + { 0xd010d789dffef6dfL,0x704937f17e8915f0L,0x5072bf063d3460fbL, + 0xa30814ed5f08429dL,0xe5faf476207d2708L,0x46e56e14af448339L } }, + /* 26 << 231 */ + { { 0x5a049c8f94af3a35L,0x9ae89160d8b75bbcL,0x8b026d867ff40c5eL, + 0x90e54aa4fbddfd06L,0xc85349e7ee418640L,0xbf71e454beb7801bL }, + { 0x63f5e068ad912e83L,0x6252a4a4ada5341bL,0x25114b87b44529abL, + 0x9b80bea9eadb4f13L,0x7f071c0cfe050052L,0x4c9cd33418612061L } }, + /* 27 << 231 */ + { { 0xc6f50ed03c768ff6L,0x5b994b58b6de126aL,0x807ad19e2a1ac05aL, + 0x012fcb9ddfc66ad7L,0xf8706d5fefeb7d07L,0x132aa6697bfc5337L }, + { 0x56bd874310e28d18L,0x33bc53d96e9f8e26L,0x5885b63b152758edL, + 0xb8b1bd5e757e1471L,0xdbc689458c0d406cL,0xa664de3bfc605a11L } }, + /* 28 << 231 */ + { { 0x04df415ea6d4b6c2L,0xb8e33e71d254d2d4L,0x179df4f48b84c588L, + 0x8a2a0683d435793aL,0x6147a5a911eecec0L,0x0b8389793a0196ccL }, + { 0x855059ce81805693L,0x37babf9f3b27872fL,0xa2ac78b1769be5c3L, + 0x16260f0c0a8d267bL,0x31f48c42388266c1L,0x58fee495ead1f238L } }, + /* 29 << 231 */ + { { 0x5753ee0fc048300dL,0x307dfd57e048abc4L,0xc18bdfeca3ba6c56L, + 0xfb2d8daf10495489L,0xd93aebd4e0fd2d13L,0x4736efaf0518a5faL }, + { 0xa8ee4995eaa9fc77L,0x2620f08e008adc03L,0xf03981839f06991aL, + 0xd47b1eabe25a4f4cL,0x669cf09c79f95484L,0xf30191584a0f8b96L } }, + /* 30 << 231 */ + { { 0x047b0f0124b240a1L,0x959915dd46cecf58L,0xedf2e74b72980ca1L, + 0x6b7b7b4ef2cad32aL,0xf9f01c9d0b9ded1cL,0x009d3a5825e77e0aL }, + { 0x62314ab411a39c1cL,0xb3b0c5b2ad557b74L,0x6dbb75dd961619fcL, + 0xb8f2d198c934e1e0L,0x4401507542eb7fd5L,0x3a8552efea1be435L } }, + /* 31 << 231 */ + { { 0x08e3f0e2217de9abL,0x6bdec27bb6b4f789L,0x5b160334685af8e0L, + 0x31e651cc61738f6fL,0x37224bc4631989c0L,0x2dc8006ad39f9c4dL }, + { 0x2a5d585056c3d84eL,0xb2ef06cc5cc79193L,0x246d92869eaa50e7L, + 0x8cacbf7cea6a7cadL,0x109bddc629465ce6L,0xad2f492fb5744947L } }, + /* 32 << 231 */ + { { 0xba03ba3b7b3b336dL,0xe57ce50928c9c55dL,0xf96b8cfe4f0f60b2L, + 0xb908d77e6fcccd96L,0x7208ef7de79dd17aL,0x739095333ec3d048L }, + { 0x9c5ad2da1163fe78L,0x4e2a8685cd4a15c2L,0xac999449470eb938L, + 0xfaaf27fbee7d772fL,0xfbe402abd0b7ad09L,0x704d4f0e57db00a9L } }, + /* 33 << 231 */ + { { 0x8f2f736c6330607fL,0xaf4acf66c975432bL,0x838fd8cabd1dec99L, + 0x347088aa7c3d0499L,0x28008757e835ea86L,0x43e2fb30c03e1aa1L }, + { 0x06c66dabf0d10da1L,0x25d7aa1867321158L,0x215e483811dc063fL, + 0xd52dee1e288362f2L,0x790989a1fe300a0aL,0xe0452fa5f163e1ccL } }, + /* 34 << 231 */ + { { 0xd3eab3ae25e7c044L,0xa3712d11b6d22325L,0x5e3835999e8237ddL, + 0x2549047c9dc93a5fL,0x24b07617b546a113L,0xa50359ed2e7b82fdL }, + { 0xbbc3eb5889964effL,0x93d490b60d7ae172L,0x68cd6b3f774ac0e6L, + 0xf98f1df035e02fc6L,0xfd2625c560857c16L,0xd68f25e845dd06f6L } }, + /* 35 << 231 */ + { { 0x40dcb41018c1b3d8L,0x8af9a0bf954cc170L,0x9c40a17d5af27d6dL, + 0x6b20fa7d7137d35aL,0x7c46f6aaf07f5adfL,0x7caa6e3cafc2f780L }, + { 0xef03332694dfb637L,0xd8f330b38d0ac73cL,0xacbf571255d40a9fL, + 0x1b4ffafa3f4fde0eL,0xa17488e09fe6b04fL,0xd27808a103957cfcL } }, + /* 36 << 231 */ + { { 0x85e1de1e96569e6dL,0xc9545920d7ae52f9L,0x04ebc797bcd62008L, + 0xe142d0bc04a24db0L,0x5ed44b0d40e9fa80L,0x39fd679a48ddaba3L }, + { 0x91aba967ce7ee095L,0x76de8d3a0e97d0f4L,0x92e7a107a221785fL, + 0xb028f67e734283ffL,0x987f644168af2f42L,0x0ad882369d7f7102L } }, + /* 37 << 231 */ + { { 0xc5289301642f7d3cL,0x53ea584de508c45aL,0x86eb66e949337336L, + 0xa56d59d668fbc13aL,0x44c464ffe9e51562L,0xe5280ecd8200a27fL }, + { 0x92e2a9334cc73f23L,0xf59780325e7b858cL,0x399bd41e90d4b2efL, + 0x4faecb8bd0ead86aL,0x6ead9c530ce48b14L,0x941b4807ef74700cL } }, + /* 38 << 231 */ + { { 0xea281be94d522b69L,0xb6855d45694a08bcL,0x7c47ddc7aa7f4d28L, + 0x2028e22b6c36bba5L,0x206b63430c2dee0aL,0xfeb0b3dae68fdcd8L }, + { 0x6dda02a44603db5cL,0xa705d0defd786a39L,0xd356f6a426aadd38L, + 0xd34acb7d95ef6a00L,0x073ea16e14846402L,0x2cf7a82ab2df8bc5L } }, + /* 39 << 231 */ + { { 0x8fdcd309bffd7240L,0x6843dd76386e459bL,0x222fa67c0dee5740L, + 0xa3801343620d7d83L,0x96dfdbffe21b4af3L,0x017bd3d3dadd04beL }, + { 0x1b6adba2bca18337L,0x191b86f1300ed35aL,0x103a380cd73bbadaL, + 0xc2f3172f36f95dacL,0xa01a10e220767bf4L,0xda882ca6989ad766L } }, + /* 40 << 231 */ + { { 0x5bbc748b9cc47708L,0x16d796054026c772L,0xefc3ce3ea053df6bL, + 0x30ea7eab0713752fL,0x15b491b9dfd524b7L,0xa751d82010bcd34cL }, + { 0xf30c708abbd5da72L,0xf0c55aa86d16bd51L,0x1754060ba6215d84L, + 0x3a48d2cbb863542bL,0x992e8340261d8c45L,0x4096f65be8fd2113L } }, + /* 41 << 231 */ + { { 0x5532411e1045d8cfL,0x2d2f8d6b52bea60fL,0xa850b61825c556c2L, + 0x6547892fe8965d13L,0xa7bd4527184d0cffL,0x0e7f7daec25ba558L }, + { 0xfcfaf7b234343889L,0x9d6a23aeb82ba1d7L,0x2859023b60514faeL, + 0x4d51aeddc82da6b7L,0x6a060dc38273cd00L,0xf2f8923d78478c29L } }, + /* 42 << 231 */ + { { 0x0baa35154f08b278L,0x26baf331e57297c8L,0x3fef65cc04e27c13L, + 0x0f910ee0ca8430b6L,0xa27c5f5c2c445251L,0xc780142dccf3c637L }, + { 0x47dc4192e0f3fbbbL,0xf4d12bd6f2a91a33L,0xc1eb18b206352685L, + 0x111cc07f5b3db096L,0xbce0cddbcb95c815L,0x6b0bae7e14d28563L } }, + /* 43 << 231 */ + { { 0x40d16b7705897177L,0x4772a643953915adL,0xc6cfc1d23cabc7a9L, + 0x0641e96df80536c3L,0x6c297cd6be4c5454L,0x509a837c9c00216aL }, + { 0x17455153c01ce9a5L,0xee76da8a40b825e8L,0x1757a59cd23a37acL, + 0x5adcfbd10958248aL,0x043314525d01549bL,0x831f725ab0c42176L } }, + /* 44 << 231 */ + { { 0x28704bdcdf7d537bL,0xbcae2c15fa88f42cL,0xab32eecd3866ac4fL, + 0x446754a2128c4a7fL,0xc69309c1739ef781L,0x216e9f43bd160d81L }, + { 0xe0efa3ec6fefc0aeL,0xd179225086a604f5L,0xe43e13e260418c0fL, + 0x6f605146f100b9b7L,0x6c39828a6e994093L,0x99558f4706c019e9L } }, + /* 45 << 231 */ + { { 0xf541b3cd28df49eeL,0x0be75ef5cec2660fL,0xe73d18bb620c81f1L, + 0x42e81fef3c775c53L,0xd0a9dcdcbc012ed7L,0x570f5a1b8f292a58L }, + { 0x51f302e74c030819L,0x42e1903f50bb8a5bL,0x6d8105a98536e7d0L, + 0x66e2fdf1c1ca766dL,0xecaf4a316c5927fdL,0x347803cf96a14565L } }, + /* 46 << 231 */ + { { 0x794d90ab425d3a7fL,0xcae9008d93ecbe48L,0x211e38c3bd5f11b3L, + 0x6020ed2a6db1c1d7L,0xaa5695064437f020L,0xb2b93424235f4d6fL }, + { 0xa84a3c1d66ab2a3eL,0x171f9325712a14e0L,0x4a43cd6744d958d0L, + 0x53bea85ee95dc3cbL,0x1fba008769f2009dL,0xf0fbc48f31c13eb4L } }, + /* 47 << 231 */ + { { 0xefa3dea85fb2227aL,0x0160b031e098a97bL,0x92a554e3553377b1L, + 0x7b58c26258ccaac8L,0x666400171c3e0a47L,0x40e45f90ae2d7d8aL }, + { 0x660df3441ee18103L,0x5515cd66e9b64e55L,0xede93c59de059b3aL, + 0x874a0c90ca0e7acaL,0x840188abc8b1daa0L,0x9d49a02601e148a7L } }, + /* 48 << 231 */ + { { 0xe93ee31ae12b4e64L,0x2ab8e378662d17f4L,0x2544bd9969516582L, + 0x7bf80e4b2e1e5485L,0xf30f0b14729d9361L,0xb3ffb5d18268d40fL }, + { 0x34605055ac193a63L,0x9e5ca9a9f8e04d69L,0xcbbeebc1085ecbb2L, + 0xda03b75bf340eac4L,0x3bf9468a84436462L,0xdfa8b4c80f26f20cL } }, + /* 49 << 231 */ + { { 0x2e6520714aa497e2L,0x2b9358fd7ecd223cL,0x96efcbdc4f828e86L, + 0xa0f76679d2f096c9L,0x3887bef70690b78aL,0x2e7d9cae1a01b10dL }, + { 0x8b0cdf0e5656e5d0L,0x0a6ca92d48d3ec2cL,0xdcacbdd3b49e2ab8L, + 0x4d087ee0d7485e87L,0x4987078292cc57a7L,0xa1776bd47bb38b8aL } }, + /* 50 << 231 */ + { { 0x60c113bdb711e087L,0x28694ff4e257e115L,0xf81d5e054c18d716L, + 0xd1c04b67eb0af843L,0x16e6e46e40d8907dL,0xb73c3de91dd34d22L }, + { 0x9d7f282519825f92L,0xdf5d33edba486ce6L,0x288fafac21c223d3L, + 0x21c4df016d05007fL,0xccd9626b197c5badL,0x3a91743902c91b36L } }, + /* 51 << 231 */ + { { 0x6f950922340ebed2L,0x9e796894beddf06bL,0x5a8ea337cd9d7a07L, + 0x1c5dee115bd182ddL,0xba87dd1ae0c79b9dL,0xb16169f3b9002931L }, + { 0x68098da138c62518L,0xea7bf413417fdc6fL,0xa500a320b6fdf768L, + 0x7870c71c4550c202L,0x0874fd9f6121afb2L,0x49f0fd0cab7d0b6fL } }, + /* 52 << 231 */ + { { 0x7af3de47f6b7fedaL,0x19b8a51ba30b2296L,0x16886446150a0af8L, + 0xdada5aeeb2a4ecbbL,0x77105de8e8de3888L,0xc54d352c7d763f77L }, + { 0x754984ae72ff499aL,0x3de4b2785a5a25f4L,0x5df75ece818512a4L, + 0xd4fc8093ca7ccf3dL,0xff9bdf544a49f4fdL,0x45d23e77de0a5840L } }, + /* 53 << 231 */ + { { 0x8ef88682ca85a586L,0x12038785bff64885L,0x99670d8ac98cf695L, + 0xf7dc3dca6c3d5832L,0x1e836a59fd3e64d1L,0x8dbb13addd426c1aL }, + { 0x21867f0690f59314L,0x7adb6f707da5ce5dL,0x662422ae0da28987L, + 0x75a1486466766a41L,0x2d42bede6c8937b6L,0x559e168dff0c474cL } }, + /* 54 << 231 */ + { { 0xa07fdaa25af635feL,0x01d67fb36a0c8fd9L,0xa226f8dac9eb8d8aL, + 0x0795c27ce7fcfd0dL,0x84556c0553578294L,0x92b30a84b3e57574L }, + { 0xc8eb6ac0ca5dc890L,0x061a0a195c8b7d8aL,0x60f3351923177c06L, + 0x780755917d01bf6cL,0x63ec8a4421f48422L,0xddfcb2c0d804c7b0L } }, + /* 55 << 231 */ + { { 0xb186daffdb2e385aL,0x7589c9cd43aac848L,0x9b474a411fb053d7L, + 0x2f79556be1ada6c8L,0x694badc54d7d9ce8L,0x31ac06a84921f546L }, + { 0xacaf91c165666233L,0x6ea97c8ee45b62b3L,0x9c8f3fa66f0096c6L, + 0x2db7da39ac68f8baL,0x0ad2da0f19a3d1b2L,0x08c96b0ff80d426eL } }, + /* 56 << 231 */ + { { 0x07d63f07257d20b5L,0x25475a304e8c62caL,0x2469d661789ac15cL, + 0xd0d2ba1b3aae86a4L,0xc716202a4458dab6L,0xa011ca5ec4d5f90cL }, + { 0x53ce0273ca2430c9L,0x61040ecf96da6946L,0x6847dd034247c99cL, + 0x0c500b4519defda5L,0x263316db365796d4L,0xff9b99e7b982d89cL } }, + /* 57 << 231 */ + { { 0x725fc8f911591738L,0xe6c16db3f4030f65L,0x66c7622d441b6b17L, + 0xad8e4b9c69d93786L,0x732d597473093a4dL,0xa2136d85228f103bL }, + { 0x84f1d9397bcf76e0L,0x971a4c55e2531411L,0x9816371d15920fa7L, + 0x5515cbc594bbc17cL,0x8b8c76e859d52722L,0x3bfe618e9a240652L } }, + /* 58 << 231 */ + { { 0x18981da25cd1f7c3L,0x198a91bb09b22c3eL,0x48d11aafb23d71ebL, + 0xddaa6e071d31782aL,0xca7b812a39125babL,0xd89dcd825d963539L }, + { 0xc7012ed9e5a89eafL,0xbcf0d4c4af0ce61fL,0x6f65a246e6a9f404L, + 0xae6a489d51c1302bL,0xab43a2bcfc5ea651L,0xfdb73470293b1e58L } }, + /* 59 << 231 */ + { { 0x8e860629f5c9d835L,0xf91a0b5d04efe37dL,0xaa2acb55b1956d3dL, + 0xe295b30fb5bb48ddL,0xdfad64a7e8275e6fL,0x1e203bb7d41beeaaL }, + { 0x4aa2fd5836e64f60L,0xfb0b92a706e01818L,0x68e386d60d29ff89L, + 0x617981bc1802840aL,0x6d68ccf7ceb124f5L,0x19193c483b120ddaL } }, + /* 60 << 231 */ + { { 0x4d02098b8b5d9d67L,0xecb580503148dc75L,0x561545107d898600L, + 0x0213ef782d8be728L,0x4123671b1f11d90bL,0x8b9ff1b654c291beL }, + { 0x139ba95e52db185bL,0x83be41d0997b3eb4L,0x4a950c9a41e2e288L, + 0xdca0290c48916145L,0xf1eb9327cd073e77L,0x384ec5ddbd4f4ccbL } }, + /* 61 << 231 */ + { { 0x7e538f9036f4b7b0L,0xeb54e9e4ca25008eL,0x0054a07bf8af6eb2L, + 0xd96b712f5e3f61e9L,0xf01da03e29aa496dL,0xedbbc2d7d00faf95L }, + { 0x178c5bbd104f4dd3L,0x5cbd4783aa11b0d0L,0x4433fe6156eecea2L, + 0xdcc01bdcada7991aL,0x89ca41ba1addfa5bL,0xad64ee097a65ee64L } }, + /* 62 << 231 */ + { { 0x05a8a58d7e276915L,0xee28f77bf1582bf6L,0x6f308349285bd210L, + 0xb8b8ec47ab877186L,0x0436930e0ddb857fL,0x20a9973e5346b800L }, + { 0x756ab9b5848dd5b9L,0x33a220cfa12370ebL,0xdbd87c391f3d0386L, + 0x90c6879075429844L,0x5cc1a9736193f021L,0xf0b80f6543d46e24L } }, + /* 63 << 231 */ + { { 0x45e5f57bf79f5116L,0x14f02b229bcd30ecL,0xd989ee5426a39a1dL, + 0x497ad3c3d5854b85L,0xb61c15e50154364fL,0x5979941f502107d5L }, + { 0x0b99f087195934f6L,0x1f852baa605fbf71L,0x68ec80e47206f65bL, + 0x0392af1cea5bc3c0L,0xcebe56f81cb1d6bdL,0xdc6279d90f80b6b9L } }, + /* 64 << 231 */ + { { 0x10c082a63fc14a85L,0x59389ebc1c0b14c4L,0x785d935b4cb291a7L, + 0xfc2ae15313e9ce08L,0x3146fabf4df6f1c4L,0xa2a4a457c87dd24cL }, + { 0x85fdd8771deb49bbL,0x2b7843709b055934L,0xc81d05013e7e0297L, + 0xb56ddd1fb92df904L,0x4612df9f295ddccbL,0xc24bd4cf0e27cf1dL } }, + /* 0 << 238 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 238 */ + { { 0x7830460fd1944d1bL,0xc56f08e784350af2L,0x73bee2aa307d9c78L, + 0x1b02af1b5aad8b6cL,0x5e31882703848db5L,0x4785958bf230f476L }, + { 0x4ea6535d4f80e25dL,0x9958c9c7d23c7f72L,0x4c197b332fd33cabL, + 0x24c7b0b1c566914fL,0x956ce3c371952d3bL,0x8735694bfabae5f2L } }, + /* 2 << 238 */ + { { 0xca9872e1597bd10eL,0x6725cc9a4aed951fL,0x96b17cb84e05b280L, + 0x97987146fa234d45L,0xba78949ebb35a7d8L,0xb82e9b9f6fc59384L }, + { 0xa303e54a70f165c7L,0xfd6bb0dcb9c2cad9L,0xe57e2de8ee722045L, + 0xa05c106563e27035L,0xaa38e86602d2fe6fL,0x78e02fa8ee2f6aadL } }, + /* 3 << 238 */ + { { 0xd6256e7c62c627c2L,0x5571edfc3cbb10dfL,0xfedec45771cca8f4L, + 0x2e26ac5f8483eed6L,0x8e8c0671173508c2L,0xfd9f25d50f39bf76L }, + { 0x1cb080c3094cc1b1L,0xd367ca8c113e6552L,0x4ae2ca36bedb511cL, + 0x0de0c3e34707eeb6L,0x204cc610239d3097L,0xb235dbf0adb00383L } }, + /* 4 << 238 */ + { { 0xc0426b775e3c647bL,0xbfcbd9398cf05348L,0x31d312e3172c0d3dL, + 0x5f49fde6ee754737L,0x895530f06da7ee61L,0xcf281b0ae8b3a5fbL }, + { 0xfd14973541b8a543L,0x41a625a73080dd30L,0xe2baae07653908cfL, + 0xc3d01436ba02a278L,0xa0d0222e7b21b8f8L,0xfdc270e9d7ec1297L } }, + /* 5 << 238 */ + { { 0x9704cdc6a9c26f4fL,0x96808107908a6756L,0x73be47d40f1def2bL, + 0xd32c11d619215394L,0x1a59b9541842c2f2L,0xd64a70bb52c94807L }, + { 0x32b08c3e9dd262b3L,0x54d2cdc4440315a0L,0x671b3139425ace14L, + 0xd418542f2c7518e4L,0xce5e1712cc1bbdaaL,0xb3268403131f98adL } }, + /* 6 << 238 */ + { { 0xce4b39874e39e87dL,0x8e60a901966f4603L,0x1b95e4fd73c4a679L, + 0xae87f845b004310eL,0xcd50aedf815684c5L,0xa56805d343c77e38L }, + { 0x9a429abcf0588403L,0x77dd1a02009e699dL,0x27ad38fb52a417d6L, + 0x62591579fd8f6d00L,0xccb12126ea58f822L,0x3a009e76760a3ccfL } }, + /* 7 << 238 */ + { { 0x17688d3410023b42L,0x9bc8bd6f7cfadb6eL,0xe4cdf89f460aa255L, + 0xf709740a99eb21f8L,0x1ea8115cbd460bacL,0xbf7bafe8ac7e6629L }, + { 0xf8dc02bb096de741L,0x982f7becd2f6a583L,0xd971589a0f92bfeaL, + 0x662793afc02acbaaL,0x1b0f7d5eb771574eL,0xd9f71c4c66985cdaL } }, + /* 8 << 238 */ + { { 0x4f120aa7e2a07891L,0x9158bab3a25d3225L,0xc96bac5ecfe5f7a8L, + 0xd4e73d59bbf3cec6L,0xed8d233560361cd5L,0x9b1a252c562f444cL }, + { 0xbd37d3cfc70f23c2L,0xf13b3b6ea52ea19eL,0x7e35535a3d2f41edL, + 0x0353b52ee8b1743eL,0x31d89dfd7b5a2765L,0x2b7ac6848d9ea8b8L } }, + /* 9 << 238 */ + { { 0x3613afb361bd36b3L,0x85171aef3e0339eaL,0xdaf0c280c833abe6L, + 0xde566372e4500f09L,0x487dbef84a5bda73L,0x5cc00564e6e3f324L }, + { 0xbdf148cfb96abd01L,0xf8dbeda5ba9306ffL,0x05774d1a5ac0b828L, + 0x73ddc3248cf4a56dL,0xabc5af5232dc6125L,0x15ad6d2573294d7bL } }, + /* 10 << 238 */ + { { 0x7b5bbe51bd6086deL,0x7fbc95303816cee6L,0x60ac14fab3354bf6L, + 0x2b2abe43c9a6e793L,0x6ffae7342e19664bL,0x1d0e38b90064bd95L }, + { 0xc1303ba3fa9f23beL,0x6d5f4ea5d8f0a46cL,0xf8f472517a270649L, + 0x126c13ae723a5a0dL,0xe4d0a19e5e21273eL,0x18076170e83abb8cL } }, + /* 11 << 238 */ + { { 0xc21dc6946b771809L,0x2501f25600f85b8aL,0xb3a21dc347382df8L, + 0x25ede3c239dee18dL,0x39709b9db29b770cL,0x6eb314d510fa9c5aL }, + { 0x79140b1f508f5e59L,0xcce9f7cedeff2816L,0xa153c050400bc8a1L, + 0x052e03c4ff2c127fL,0xf8ffff1f841a03adL,0xc0c2626345896fb5L } }, + /* 12 << 238 */ + { { 0x06a67bd29f101e64L,0xcb6e0ac7e1733a4aL,0xee0b5d5197bc62d2L, + 0x52b1703924c51874L,0xfed1f42382a1a0d5L,0x55d90569db6270acL }, + { 0x36be4a9c5d73d533L,0xbe9266d6976ed4d5L,0xc17436d3b8f8074bL, + 0x3bb4d399718545c6L,0x8e1ea3555c757d21L,0xf7edbc978c474366L } }, + /* 13 << 238 */ + { { 0x905ad4bf3023ec1eL,0x8cc101ca16081c1eL,0xe0d47ec79cb74127L, + 0x1be5f86725da2dd4L,0xcba2ee4507ebac2eL,0xcee26667e22d87d1L }, + { 0xfc339af1c7c409ecL,0x112af9b47b7ef32fL,0xcc3e07898b821999L, + 0x4234433c222b3478L,0x55bcc87ddbce50c0L,0xcb6141cd7816f642L } }, + /* 14 << 238 */ + { { 0x8ae24e6b67f38eecL,0x61adae20ea14bc0dL,0x32737584c480c3fcL, + 0x44f61b79812ee744L,0xc8f607d5fe06d5d2L,0xfeaeb2bcea45267eL }, + { 0xe004522bb92c909eL,0x5171fe360ab3e854L,0x659936fe63ebc481L, + 0xdde6dbbff76649d4L,0xb38c160fe2295d0eL,0xba608b7e1e8f5c1bL } }, + /* 15 << 238 */ + { { 0x55616c4c86c2cb9cL,0xcfa8b484173526faL,0x096a09d90039a4c9L, + 0x6ccb4964f300a73bL,0x42dd78ac66819855L,0xa7c532c10941599cL }, + { 0xd15905f0b630220bL,0x9f4893ca5637e103L,0x768c09bf8a2115abL, + 0x5091f4399c52755bL,0x4ad1c0f6d38e7c50L,0xf6e6b2d054eb4439L } }, + /* 16 << 238 */ + { { 0x73457010c46db855L,0xccb68c43dd579fb8L,0x705b0e8c9c25fe5bL, + 0x40f36ea182dd0485L,0x3d55bc8527ac2805L,0x15177c6fad921b92L }, + { 0x51586cd55ab18cabL,0xf51b5296cbb4488cL,0xbb4e605e84f0abcaL, + 0x354ef8e3772dd0daL,0x7f1a8f795e4e1d41L,0x93461f09de5d8491L } }, + /* 17 << 238 */ + { { 0xe186b0b09cd7d54aL,0x0451cb0dd4303760L,0x90a8b0f84b38f082L, + 0x2357f03700b04fffL,0x8a4669f86d81dbd3L,0x2a5cb6f6bd94842aL }, + { 0xa13d19c4c498a572L,0xb7b8fe10cd937a76L,0xf8df355ed9842244L, + 0x64fc9d62b077c8feL,0xd4b2c3cce9dd337eL,0x7c63799ad3784edaL } }, + /* 18 << 238 */ + { { 0x39fe6673a780fd38L,0x8bc8d026a4b4cfa8L,0xcc339850801c44bcL, + 0xb5d80c4bc2dca07dL,0x745ffb5d91f1408bL,0xb55588f89017d1e7L }, + { 0xafef3cf1c3d76a1eL,0xe3a6e8058e1367ebL,0xd09ea1e2a642d2bbL, + 0xf303c613216e63e5L,0xe699e51cc98908e6L,0x835d4cefafeac3c2L } }, + /* 19 << 238 */ + { { 0xd1cbe55ee5000eceL,0xc1a074b01ff0f474L,0xc6681f48d7ffb89bL, + 0x7c68011d48d0bb4dL,0xf305627bdcef5e07L,0x0f0e0c36323ee3fbL }, + { 0xc5c6b61355f5f185L,0x6e4de5af52d6cc84L,0xa64ea548889fe8bfL, + 0xc4c5e4104d28350eL,0xef944a8f7dd3072dL,0x7ed579fa13356185L } }, + /* 20 << 238 */ + { { 0xec72c6506ea83242L,0xf7de7be51b2d237fL,0x3c5e22001819efb0L, + 0xdf5ab6d68cdde870L,0x75a44e9d92a87aeeL,0xbddc46f4bcf77f19L }, + { 0x8191efbd669b674dL,0x52884df9ed71768fL,0xe62be58265cf242cL, + 0xae99a3b180b1d17bL,0x48cbb44692de59a9L,0xd3c226cf2dcb3ce2L } }, + /* 21 << 238 */ + { { 0xe646281876ba99afL,0x1d53bd27818b5992L,0xc55e135d67e1d81bL, + 0x32b9e37023e211feL,0x91ea63dc130b1176L,0xd7e1cc51a34fbb3cL }, + { 0x5363fd962fee934dL,0xd19c50ba0b8fd289L,0x21257825a11c27b6L, + 0x19159a966792c1ccL,0x0ccc3cac39a08fbaL,0x841cb58a45512d8eL } }, + /* 22 << 238 */ + { { 0xae8532c3224ab492L,0x8bc92c85f6acd0ddL,0xc071ba92b796d21dL, + 0x1290162943797a3bL,0x8f4c5fb5ec950329L,0xfab6f950cf0578e3L }, + { 0xb7b8d211bb6aa75cL,0xb06279dc3d1147f9L,0x060db1a7591820cdL, + 0x0e691a412830f356L,0xac00664224b8bc33L,0x579f9c052f17441eL } }, + /* 23 << 238 */ + { { 0xd8b9dcd50c4cb7edL,0x2f59d64c7619cdf4L,0x7e83d18e284bc6f9L, + 0x49af25123e415166L,0x90388976ccd64d11L,0x4708fffdfe2580b6L }, + { 0x7a8d25ff17dd4d8bL,0xba7785fefd71355bL,0x7cceb111b9789cc6L, + 0xa8fd782ee98d6b78L,0x8d1b7fb66135d4a2L,0x78c2267d35e382beL } }, + /* 24 << 238 */ + { { 0xf38995589311182cL,0x1bee4c4bb657a7b7L,0x0b1c4fd32df8d1a7L, + 0xf16bcc2376d3fbbfL,0xd5888916f4fd52bcL,0x3de6cfb4d5cde1f0L }, + { 0x764ffffdd4a07dfdL,0x5e674426e2642182L,0x34f64762ccd57b85L, + 0x2233a4c329351062L,0xdf076095d9c642f3L,0xac917a2c59f0df34L } }, + /* 25 << 238 */ + { { 0xe588d5a8cf2f7d4dL,0xb45923ee86798c14L,0xffefd323f0623572L, + 0x24dd7019005f605aL,0xb9e833053a6edaecL,0x039ed04949923a44L }, + { 0x0f83a74360789fd2L,0xb4f91a8e9b001515L,0x37b856664261ad9eL, + 0xc291caa68b92b7afL,0xfa0f8a5e67ba28e0L,0x362a6808c5eefb98L } }, + /* 26 << 238 */ + { { 0x8aee939cc64e4ab3L,0x3baac0a844621bb2L,0x9094a09629da9bc3L, + 0xa92dc70806d2314fL,0x45c1cd0e34235918L,0x51aeb007c34021a4L }, + { 0x58267735a3492237L,0xe8d494bd375eb21bL,0x664dacf5a395bf8bL, + 0x2ef1feb612cec40eL,0x90c5f43fa7141e5bL,0x93e80dd03855169fL } }, + /* 27 << 238 */ + { { 0x2e550006211b2fb3L,0x8c82e59d6cab73baL,0x011bb2fb2bd326b9L, + 0xfbd519ff1e0efd69L,0x0fb2f266320cec7fL,0x879e28c03518fac3L }, + { 0xd0887775e01294eaL,0xf6e60efd1df5bb0aL,0xb2a5d3a404d04a96L, + 0x915eaa29a4f3500fL,0xcb6c03f70db6bde4L,0xfee081a405f30cc1L } }, + /* 28 << 238 */ + { { 0x9580cdfb9fd94ec4L,0xed273a6c28631ad9L,0x5d3d5f77c327f3e7L, + 0x05d5339c35353c5fL,0xc56fb5fe5c258eb1L,0xeff8425eedce1f79L }, + { 0xab7aa141cf83cf9cL,0xbd2a690a207d6d4fL,0xe1241491458d9e52L, + 0xdd2448ccaa7f0f31L,0xec58d3c7f0fda7abL,0x7b6e122dc91bba4dL } }, + /* 29 << 238 */ + { { 0x24e2801364ca563dL,0x6f06fde270f8f91eL,0x9abcca1bd2a65c0fL, + 0xc5728ffca5aa1e40L,0x654f0f56eb9d3e45L,0xe04ada2394161a0cL }, + { 0x001b25626ddbc960L,0x253b447aef93504dL,0x895ce21e2d6dc894L, + 0xefb987381c1b63deL,0x6adb6eecde8b806aL,0x9ea3884e0240e7bfL } }, + /* 30 << 238 */ + { { 0xe8387f68411ad563L,0x98a962eacc5f157bL,0x8093a8d296090321L, + 0x240a73083790052dL,0x6cb4a7382e7dcedfL,0xda65bf8481a60e8cL }, + { 0x420ce478c66c70aaL,0x0e7959ec42da3021L,0x44bc9d3c7e35aa20L, + 0x36e49d764e9df39bL,0x7281073a9b286287L,0xd9a068422524b62dL } }, + /* 31 << 238 */ + { { 0x00d6e0312546247eL,0xcc2851020fdaebdaL,0xb8a453f15601006fL, + 0x0afaa3f138be7068L,0xc87acb442c6cd9f1L,0x10dd5d031ffd5fbcL }, + { 0xbae0b62fddacbbd0L,0x1daadc18446bf2e2L,0xaeaf15317ef0facdL, + 0xe7b92b76c941808fL,0xda59af2ae6d0dffeL,0x1c09b783e612b888L } }, + /* 32 << 238 */ + { { 0x3bd258d8775f516fL,0x4bedebd5c715927fL,0x5b432512e3f966a0L, + 0x338bfca7709d0c2dL,0xd142cc1049658259L,0xfabc6138636b8023L }, + { 0xa9ef94014d4ef14dL,0xd5917ac1c54c570cL,0xfd2f63c55cb64487L, + 0xbae949b11cea475bL,0xa45446031e67a25fL,0xa547abc1dc6a7a6aL } }, + /* 33 << 238 */ + { { 0x6c7b4cf344b880b0L,0x29da87760a388eaeL,0xf434d173fe9617c9L, + 0xaf67cc2ea47abf28L,0xe211ad37249d0eb4L,0x88d156e538bce76fL }, + { 0x60320c6dd58fa585L,0x7b352c39ebf09a7bL,0x9305dae8a31ce734L, + 0x70c35be89361cc3bL,0x6b8b71f8bcd14255L,0xd1b7963572a457a7L } }, + /* 34 << 238 */ + { { 0xd8d04787ef8849e1L,0x58adf044148375e5L,0x5b613ac476623232L, + 0xbd274d2f95d7e359L,0xd97acbd271576bb6L,0xd20bb2c34c7fc4b7L }, + { 0xe15465315f837664L,0xddac59b5fb4ce79aL,0x33fef5214fb36e08L, + 0x0467811045108b22L,0x0de6c7766dbe57bfL,0x456d765a25fea77bL } }, + /* 35 << 238 */ + { { 0x4d9838a32922b715L,0x3cd9fc0a6a7bb3a7L,0xb1bf28fc2247e916L, + 0x92dd22006f206a16L,0x8ea87d67b51256caL,0x2c535730b5a4bf17L }, + { 0x34da42505f584954L,0x72326fb8fefca748L,0x40fd9d09da2844a2L, + 0xaadaf71c412da037L,0xa62329a9aa6f884aL,0x1b6165e6726a8f8cL } }, + /* 36 << 238 */ + { { 0x2a2dedafb1b48156L,0xa0a2c63abb93db87L,0xc655907808acd99eL, + 0x03ea42affe4ac331L,0x43d2c14aeb180ed6L,0xc2f293ddb1156a1aL }, + { 0x1fafabf5a9d81249L,0x39addead9a8eee87L,0x21e206f2119e2e92L, + 0xbc5dcc2ed74dceb6L,0x86647fa30a73a358L,0xead8bea42f53f642L } }, + /* 37 << 238 */ + { { 0x39de72e225e62213L,0xd885c406a03a58adL,0xa63964b527e76458L, + 0x93f83239637c0becL,0x8c9e29b4ba556e65L,0x7d746448a6183182L }, + { 0x6dee01aa09a8eb37L,0x97289f2e757ffa96L,0x367ec50fb4785102L, + 0x200f77cdb3d07cd8L,0xadc7c000a581946eL,0xa2dba5e52c0b32aeL } }, + /* 38 << 238 */ + { { 0x95a5a7f0b203f75fL,0x9b574cfcb5df11f0L,0xbf5fe3f2dba4b4e6L, + 0x347a7bd7d0987125L,0x858dea6b09377a2aL,0x87cb1e66eea85d5fL }, + { 0xe7619b666146a0c6L,0x0012585a8a0bc101L,0x738e6589ea0ce92aL, + 0xf23547979a39b3f0L,0x666f3f5d6dc81167L,0xe569cc82fb06b0b3L } }, + /* 39 << 238 */ + { { 0xef0e64399c7677d5L,0x052bf027efc398c2L,0xa5d253cc515e4198L, + 0x7b915f07a71ce047L,0x56880ea2e177dbf6L,0x735dc74f0b5741d9L }, + { 0xa108632f0161a0acL,0x0c68765705e7e09eL,0x694e651e211709e0L, + 0x334e15e51d879a41L,0x6191d34260c2a603L,0x3a8ce0e6224234d7L } }, + /* 40 << 238 */ + { { 0x158d814db12c4bb1L,0xe52f75d22f0cf4faL,0xf106023e6141b59cL, + 0x5eb8b8ebbeb9d941L,0x1dd3972990cf579cL,0xb273252e69ee6efaL }, + { 0xe43a3c593e9947a0L,0xd605124f6c19dd01L,0x8090fdbd05c578b0L, + 0x8e6c535a622ff18cL,0x3600b0c257d12071L,0x6d026e5c78d001d7L } }, + /* 41 << 238 */ + { { 0x6e515f3608e33ad5L,0x3e320c5283512d9bL,0x171ab26a5ca1c452L, + 0xfb3061e874c97139L,0x7944644c9cacf3aaL,0xedc724f03687cfceL }, + { 0x7252d7590db9b5beL,0x625f17ed0eeaf1d4L,0x6b0b4e5e82e3c58bL, + 0xf03d7bcef0f2ecc3L,0x4cbaa878139a7580L,0x982e471672203e07L } }, + /* 42 << 238 */ + { { 0xa533f574e335d60dL,0x102b66fb2aa6855fL,0x7a57420c49946287L, + 0xe3bb702286f393c2L,0x1892642d04a41c49L,0x2c47ba38d44969feL }, + { 0x9068650444388ef1L,0xd94f6f131eaf6b54L,0xf81d8782f0b872e8L, + 0x7ced5924d013f6eaL,0x76ef63d307cd721cL,0x888646b36cba783fL } }, + /* 43 << 238 */ + { { 0xd2c858157ec1660cL,0x6c8988a3ee73763cL,0xd6cc562d5e80aaeaL, + 0x48f399d975768c58L,0x3189bf68af50c1c3L,0xa3f8d2df27dc372fL }, + { 0x99d6b416b8c7c529L,0x531707944406b1e6L,0xafb57933e3ac044fL, + 0x530ad3bab2548505L,0x791a290a977590caL,0xb0d07228646fd1fbL } }, + /* 44 << 238 */ + { { 0x636225f591c09091L,0xccf5070a71bdcfdfL,0x0ef8d625b9668ee2L, + 0x57bdf6cdb5e04e4fL,0xfc6ab0a67c75ea43L,0xeb6b8afbf7fd6ef3L }, + { 0x5b2aeef02a3df404L,0x31fd3b48b9823197L,0x56226db683a7eb23L, + 0x3772c21e5bb1ed2fL,0x3e833624cd1aba6aL,0xbae58ffaac672dadL } }, + /* 45 << 238 */ + { { 0x86d2f71530cf85afL,0x8e1b053cf7e634e0L,0xe79592f43a4e466dL, + 0x26752e8506985331L,0xfd098e83dff73363L,0xaa158e2c505ffbc0L }, + { 0xe45fa1cba0fe759cL,0x6e2f5989bc0d1491L,0x4a804eacae7210a9L, + 0x0e252f758a63f67bL,0x0d7600cf362a7df7L,0x795069bf6d5b2b18L } }, + /* 46 << 238 */ + { { 0x25f9f0fc0649613bL,0x109521f05d3005d9L,0xcce1c5b41feba4c2L, + 0x6a27cfafacda6021L,0x37ff83303ab6382eL,0x53c7ccb715ca79f3L }, + { 0xdffa6c9633611dd4L,0x7555cfd4352d3916L,0x2354bec62cbd44f7L, + 0xaf0044c54b0b500cL,0xe4835df7ce9aade1L,0x14e57f6bcb218644L } }, + /* 47 << 238 */ + { { 0xb5e26899b1c22bd8L,0xde12b0b51aaf3460L,0xc269595c31ee049fL, + 0x8c7513c88a73ed74L,0x8273018450cd009eL,0xb2cd2dec4d130b5fL }, + { 0x1a9015521971a189L,0x6ce23544c6f39bc3L,0xd76133aa9467badeL, + 0xf91173cc071ee7a4L,0xe54d8f44b8267c73L,0x5725e0676dc9aee6L } }, + /* 48 << 238 */ + { { 0x00e0a003daff1807L,0xcb9d155992c94fd0L,0x3c2b5c3dcebbf905L, + 0x9c799ec7d338afa9L,0x60b9908c4e2cfcccL,0x4bfe1a57ae3c6f92L }, + { 0x480d310efb116150L,0xa1ed6c31e3e7888eL,0x841a11d9720b5196L, + 0xcc337d178adff37dL,0x08c668265faa86c5L,0x945c90d49dfcc7adL } }, + /* 49 << 238 */ + { { 0x0fcc0854f2b3622fL,0x3a9e218ab6833f04L,0x209125d4ee8fc062L, + 0x98b2c628a3c3bf2eL,0x7e051fda83ca6a6eL,0x81afd3933d87981cL }, + { 0x8f3beaff4baf556eL,0x0f1b27fdcc7e66c7L,0xbf0b08f59f4a4461L, + 0x8eb739fa141985e5L,0xdb5b46112da43947L,0x63bf81cbe5cabfddL } }, + /* 50 << 238 */ + { { 0x355e40d398ff85afL,0x19f2f3c2b08f836bL,0x0a62d254737cb5f7L, + 0x5d0ef7d9f8c50d82L,0x773a399ebbd70eb7L,0xac357974a70bea8bL }, + { 0x1de5a45cb3b5d794L,0x67c58b52a48b55b7L,0x724f56f4b02ebc8bL, + 0x03dc71e3154ad508L,0x9bcd3939cc84428aL,0x7fdba978158c4a0eL } }, + /* 51 << 238 */ + { { 0xac08e06e65b93d44L,0x2397625a5358c691L,0xfbc9285a8516e31aL, + 0x38ce0d3544ffe25eL,0x13381dd16414072bL,0xf782fddc170ecb4eL }, + { 0x78c71a716f815259L,0xb725870573659a85L,0xd37678008712d968L, + 0x153d8aee3eda5006L,0xda4fd94818f1439eL,0x6384135352dbfdf8L } }, + /* 52 << 238 */ + { { 0xce92224d31ba1705L,0x022c6ed2f0197f63L,0x21f18d99a4dc1113L, + 0x5cd04de803616bf1L,0x6f9006799ff12e08L,0xf59a331548e61ddfL }, + { 0x9474d42cb51bd024L,0x11a0a4139051e49dL,0x79c92705dce70edbL, + 0x113ce27834198426L,0x8978396fea8616d2L,0x9a2a14d0ea894c36L } }, + /* 53 << 238 */ + { { 0x06d57f2920514206L,0x61394b863a2cc1ebL,0x0ffdf49a86c7b2c1L, + 0x65334e9349f58f13L,0x180b10b8c08dfb05L,0xec352adef6c95b7aL }, + { 0xf9801dc0c4bde0faL,0x428c77f0dabf0c66L,0x2a7d1bb0c2eb80d4L, + 0x81774172fdb56fabL,0x7507481f1d965515L,0xee0693bb8ebfadebL } }, + /* 54 << 238 */ + { { 0xf4589418ac56a031L,0x21f3dec6f2718a10L,0x0ed08d9690f28b6fL, + 0x2624bd7a35c3a6a3L,0x1b3f02e8bba795f2L,0xe629b5aa3977fd17L }, + { 0x66c8cd7691e8df1aL,0xf36c4e2c1b2b5542L,0x7f6b742f7dff66a7L, + 0x00bc68b8242e0fc2L,0xdff5c73360119d9bL,0xe726260fb5c4dddfL } }, + /* 55 << 238 */ + { { 0x0242fa358eeaa549L,0x2d081bcf8abc93c6L,0xaa31813c55551d40L, + 0x1cf21c1271db3aecL,0x5a6dede7203880d9L,0x389c63cabe4aaa9aL }, + { 0xff4db7d4bf28086fL,0xd89c039b33146844L,0xc2b32bf06df6f790L, + 0x7f4e836b9f22fecaL,0x3f64d0fa0af51572L,0x681a1f5bc67aa565L } }, + /* 56 << 238 */ + { { 0x9f9ac9608e2941a6L,0x43e7ff902fc4fe1eL,0x5ec413596033e041L, + 0x5ce791c46f6ff0f3L,0x8d134b899d907343L,0x7bd15c7786304df2L }, + { 0x2cd2ebc777c4a913L,0xcd86a39d45f07153L,0xe7e12d2e88bc423bL, + 0x478e814b0b3163f4L,0x78bd9c8abe8ec766L,0x6a5763e87709ce48L } }, + /* 57 << 238 */ + { { 0xb503ac624329d7f4L,0x3a900374488e3ce4L,0x8a11addab0d8dc97L, + 0xbea3ea2c0873bdf8L,0x0f57130115bc7adeL,0xbc98d2070b2b69a0L }, + { 0xaefc4047639d182dL,0x0e6db26feb3c44eeL,0xaf0f8b392a68a48dL, + 0xde65a6b36bf1e593L,0xe48f8fc989dbd38aL,0xad18a43bd8d285b3L } }, + /* 58 << 238 */ + { { 0x249d86007e9d48c8L,0xec6109ba109a54bbL,0x64f688af5ac65ad4L, + 0xb12c85b4be1796baL,0xcc258d31c9940da0L,0x59590853ff2f151bL }, + { 0x9e9edc4d401c5d1dL,0xdd9ad117f230b458L,0xc2c752ac962334b6L, + 0x3fab66ce27327e6cL,0xa363d3643816a47eL,0xa6fc57bec180bbdeL } }, + /* 59 << 238 */ + { { 0xd72dd5893ff345d5L,0xf87c17ae41e1d287L,0xadadbf525964d55fL, + 0xecc7f27af8b07db1L,0xa2dacfce6f2aa320L,0xc7936da72aa3f228L }, + { 0x2e9e6058fa504b87L,0xf2df43279d0f0634L,0x90d5ee22a4b768c5L, + 0x1ea9bf0b5b46ea84L,0x792370f45cc41770L,0xfd17823176c1a3f5L } }, + /* 60 << 238 */ + { { 0x4f1e1254604f6e4aL,0x4513b0880187d585L,0x9022f25719e0f482L, + 0x51fb2a80e2239dbfL,0x49940d9e998ed9d5L,0x0583d2416c932c5dL }, + { 0x1188cec8f25b73f7L,0xa28788cb3b3d06cdL,0xdea194eca083db5aL, + 0xd93a4f7e22df4272L,0x8d84e4bf6a009c49L,0x893d8dd93e3e4a9eL } }, + /* 61 << 238 */ + { { 0x4c124a904190257aL,0x09002f52347e517bL,0x2e9b69a1e5760993L, + 0xbaa49e53e26672bcL,0x9468fc3bf7820190L,0x637bccfe1f955328L }, + { 0x16fd33f26e0aa088L,0x9391550757b2b2adL,0x85e98842e9a0ace2L, + 0x8e2bd52b4fa787afL,0x8a86bd85644aeeacL,0x63490956c2814734L } }, + /* 62 << 238 */ + { { 0x5e902fb3063b3517L,0x0cd006cae5a65212L,0x597bd7804591c4bcL, + 0xd853d81be17c1d3dL,0xbc4bf68156e5d24fL,0xbc801615d26b5ce5L }, + { 0x1ffa5cd5caeecbe7L,0x16ec32a4b0203156L,0xaaad43269a857672L, + 0x0606ebf9189c6f6dL,0xb90730bd57e476f2L,0xed8d82b1d492fb05L } }, + /* 63 << 238 */ + { { 0x69a2a9b6ff824814L,0xe7b716e7c35c5da3L,0xb6781a5e9a5fde1aL, + 0x08bf695dc072e1b5L,0xaadf71462590a817L,0x490297f9c755c83aL }, + { 0xbd9fad6191c29990L,0x87b3abc226b6cb9dL,0x6975d59865fd0b64L, + 0x0fdc5267f4257158L,0x9f3e10585877bbdeL,0xb7f4cfb04297a2d1L } }, + /* 64 << 238 */ + { { 0xd699ea2d8d095606L,0x3cd080c51e0ddd3aL,0x46604bad66a8b35bL, + 0x0c779b624233fccbL,0x578458acbfd3cf0cL,0x6820f66596bf57afL }, + { 0xa9724245bf1f302cL,0xbbde24da277a6c3eL,0x0980a5b8c6be8c14L, + 0x6230e3ec774d62c4L,0xda1467d84fbde24bL,0xd9d68d07cc862204L } }, + /* 0 << 245 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 245 */ + { { 0x67c516347378f90dL,0xbc201a7966647082L,0x77fcc8dc9ee450cfL, + 0x8dd2b318b41a3e2fL,0xdf6a935e93bf0689L,0x75edabf3a92e5464L }, + { 0x49afcd9f604d208aL,0x372f0ea7d465ca48L,0xcdbd8ad2c7ea7810L, + 0xfe61571e550822b2L,0x744a4f9386606adcL,0x6beb3c9cd9d4e110L } }, + /* 2 << 245 */ + { { 0x1fef389ce700b9f2L,0x63029466425bc8abL,0xbd770a1437f04a33L, + 0xc7438e29d0169369L,0x6b265742e2377cc3L,0xdf24bf96c369fa4fL }, + { 0xdfdbcf470ad94e08L,0xd101b8617f75a7dcL,0x5574a0b82a9c483cL, + 0x0563fe942de43228L,0x58ca0e8aead1fabeL,0xdc3d9a8466023966L } }, + /* 3 << 245 */ + { { 0x383bda07c3fd20e5L,0x9619b1df5c29449bL,0x6f3c717d369f39bfL, + 0x1bb593d11a5a3900L,0xd0f07ecc2aec6c2bL,0x9d72eb2a4240b202L }, + { 0x35342f6cc50e4a0cL,0x701b46626b93bf61L,0xfcd6eb09ccb6a888L, + 0xabb7a6f785aa42c5L,0x952f8824aa4e5895L,0x49860db85c406582L } }, + /* 4 << 245 */ + { { 0x3667a7203955812bL,0x0d73483b284d1dacL,0xe084535efc62f791L, + 0x5bc1652b389faf7fL,0x40cf51683a71b7f6L,0x8a4b19fad4f39703L }, + { 0x823e754a2a8eff13L,0xf01b2021bffa5afcL,0x5639ee027225b319L, + 0x7533bc86fc282f16L,0x710009d2c69f61aeL,0xe30c499dbf65e803L } }, + /* 5 << 245 */ + { { 0x0da7ac1b734b4ec3L,0xf47fc1d012a2afbeL,0xbbbc99be87dce4a2L, + 0xf7264b4edd5c6378L,0xe9409305f618ffdcL,0xafadda9bd1846ac1L }, + { 0xe734f9d0a21850d4L,0x199cb44f8722a316L,0xcfe8704b38cae89fL, + 0x2db1e56b6b151b57L,0x116ca5cf69ce7b2cL,0xe9b8625f57de97c8L } }, + /* 6 << 245 */ + { { 0x18811bd5af247c49L,0xbc180793e124dbdaL,0xed978d3a21234fc4L, + 0x516dd9a70616ae15L,0x8f80677774e430b8L,0x9094256906e8fc49L }, + { 0x4ca03fb5a4e61235L,0xb91de709b617f361L,0x0898d82d0ed08bc3L, + 0x2bd712368cb08146L,0x45b92d45e213176dL,0x05894791f2bf5b9cL } }, + /* 7 << 245 */ + { { 0x0d79cb892695ea2bL,0x2cb0f8dfc88e538aL,0xc1b8dc3da80f36feL, + 0xd756fa6684f00cc2L,0xa6f1cdec9cb9efb2L,0x5c3f15a8a6a21818L }, + { 0x9a7ee3516995d09fL,0x88885463d70434bfL,0x18cecc6d4f7d5d33L, + 0x3f0138866b353bd1L,0x53bf798b0d9ad368L,0xeffd465a28dbc3eeL } }, + /* 8 << 245 */ + { { 0xeb29e44cb5d98ac1L,0xe47e57f80e227a4fL,0xd09c04943d2bf688L, + 0x3ab7799a47428dd2L,0xdc558d6be9aafac8L,0xc042c4cd87f9f6e0L }, + { 0x93842bcd89fb4693L,0x62dbc82f7068fbf7L,0x164552687e6d47b5L, + 0xab304b7a4c37eeeeL,0xdbb3d4e13fc412ceL,0x4f65dad0a726a2c8L } }, + /* 9 << 245 */ + { { 0xb25e01b2605cdaeeL,0x74abec55bc57969dL,0x9c57bfabcdd9d41aL, + 0xa3330e3f4a9e32a3L,0x5929a0d8e5792fd8L,0x830b4ea271ea2cdeL }, + { 0x80065ac1fd06d246L,0xa2b416e632e64a25L,0x3950bde7c0c927a9L, + 0x9951f3bd679d9b8cL,0xc235a274651b6855L,0xbfe5e08e5ad97bc1L } }, + /* 10 << 245 */ + { { 0x4409a5b6744ae145L,0x5e83fa0b7f620908L,0xfc489bec2e140aa0L, + 0x5805a462e3cae337L,0xe56e9ff7c2211c21L,0xb722f2b40c955362L }, + { 0xb098a32f41371f33L,0xe6cceceabb4923d6L,0x1cfbe2b3d82a311cL, + 0xcf9428936b98f917L,0xd60dc62492ef848cL,0x34af446e5adb5228L } }, + /* 11 << 245 */ + { { 0x0eb7e743796ce1caL,0x138653e5d851377cL,0x69c7c86f2b11c8e0L, + 0x878ec1decdf2b205L,0x03e6688aae0e8562L,0x20810666935a36a8L }, + { 0xc8ab7c7f26635c50L,0xe75cdb06744a21dbL,0x4e26f32fd720e198L, + 0xa1c6395ad8cded81L,0xb75dc6ea6ce4fc04L,0x71750b33004623b5L } }, + /* 12 << 245 */ + { { 0xbdef84077e60c447L,0x88570f712a65accaL,0xef3d4a400bb6aa79L, + 0x5c9d189060212976L,0x80179ea21d96c43cL,0x3f002e6d53d2948eL }, + { 0x14b2cc9149d78183L,0x7a549c71b496c279L,0xf4beac3f44995f6dL, + 0x5a34239800bc78feL,0xa874dc1b60e42da0L,0x3a984010cf5824d5L } }, + /* 13 << 245 */ + { { 0xe514ee06dfb9760cL,0xb8862d7577b8951fL,0x0144676ef8ee1141L, + 0x49561a3002eb3e82L,0xb3541c154ff9f897L,0x1670edf0a7a99791L }, + { 0xd41d603564aea7f9L,0xf66ffd092b3463b4L,0x0784e015c3b26fb6L, + 0x88edce33ec46f8c8L,0x1b1e25a3b6381011L,0xbfaadc03ff95ab97L } }, + /* 14 << 245 */ + { { 0x727a59fe0c7be4e1L,0x75a7d5e3f58ced15L,0x146fc0d990f569e7L, + 0x94dbccd2b7f1dc54L,0x0df1ef90b75bf232L,0x2943a082a2568190L }, + { 0x75f2f80d67837b06L,0x07e3506f24b44b6eL,0x7c30829ad0d2231bL, + 0x9ce577ca93277abfL,0xa19d1868b17549ecL,0x0ad6ff5525e8c4d7L } }, + /* 15 << 245 */ + { { 0x16b38dfe1c24d075L,0x3acd4c36992959f6L,0xdaf2fe88ac2da7abL, + 0x76e8ff0e89644935L,0xb8547c26e85f7076L,0x9f149faa1cdea7ceL }, + { 0x181a60729e125d84L,0xc4aef9fa18751ce6L,0x451c84660e00f00aL, + 0x662b3e7ac4e3e6b8L,0x57b7114ec6b64507L,0x07aeb1980b37fb70L } }, + /* 16 << 245 */ + { { 0x79d88e004516234aL,0x98dd3cb931f9cedaL,0xb528000fce7d606eL, + 0xc773557e2fa27fd3L,0x55b53dd3e19436afL,0x675084b3e10b64c7L }, + { 0xe583266556d56374L,0xf8f7fd2a307e2e60L,0x7b93bf537af3e3dcL, + 0x94fafa2cf47d298cL,0x94c2ff9a21121369L,0xa41de95f33468ff6L } }, + /* 17 << 245 */ + { { 0xebbafd4720f25aa7L,0xe2becad71ac444bfL,0x323356a092a944b8L, + 0x32feccc0c9a3cec9L,0x15ec3aaf5f9e96c1L,0x852142b5c12c8e62L }, + { 0x098ffcbf2b6865f1L,0xcca470e8733d7741L,0x0f8c0f5271945bf5L, + 0xfb654f6a08068827L,0x3a9e7d742a0e2829L,0xb90742b04b687763L } }, + /* 18 << 245 */ + { { 0x145afb651fdb2a7bL,0x93315b684eff5eadL,0x0cad1d20e40ca999L, + 0xda9b517a379a8173L,0xacb665780ca018cdL,0x1e9d919f481969b4L }, + { 0x5c9a058d68130364L,0x872e26620a62ce5dL,0xca598848acaabe54L, + 0xdabfcee18aa048a0L,0x16198d034ac52a57L,0x72eb5ec632b6d102L } }, + /* 19 << 245 */ + { { 0x13f2e1726a0c96e0L,0x55aed9e02d6b6f05L,0x3c919ba3bdce76c0L, + 0x647a525ffdda39aaL,0x5c0dbecc01a9011fL,0xa537ba8d9fd9dcefL }, + { 0x8472e375cff62467L,0x57672311ed5adf05L,0xd1e178dc6a423de3L, + 0x3ebcfe18d3ad3ca4L,0xb8f341d7ae802c11L,0x3f14c424ecdfdb7bL } }, + /* 20 << 245 */ + { { 0x381e0a136e4d2e42L,0x2f2a4ee183c0d752L,0x50d4647fc8e6532eL, + 0x7e210aeeb4e7495dL,0xfd147710bcd142a6L,0xddddb07b06429213L }, + { 0x63e06fc64548a6b8L,0x05d9b825904f92a6L,0x4b63fdbf9988ee79L, + 0x6cfa412f9b3366bdL,0x0dd5fe3dc8c61f51L,0x3ec77027be8e047eL } }, + /* 21 << 245 */ + { { 0xea7d01cfc7d81791L,0xfa6c0fe6e2264afdL,0x53c7eea363651291L, + 0xe58f8411f2d90f92L,0x4919b4c61faf0e14L,0x0c7dcd07148e98a0L }, + { 0xf9ef44cebc8bd43dL,0x3acfb6686f83cfb4L,0x34130e18f883693cL, + 0xda9ed2ae2d236c3eL,0xf54da64cc75cabdfL,0x1c3df906cc01722bL } }, + /* 22 << 245 */ + { { 0x686796c68d8f2286L,0xe0efaf9334d7cd1aL,0x84f9237c93b23708L, + 0xcb50cc8ee47f5161L,0x498b81e71f597821L,0x3c3f33e1a491079fL }, + { 0xee300c6dc69d1bc8L,0x279760e734778389L,0xe00ac0eb2bb8ed78L, + 0x9bf9a10e765c8b5dL,0xc7e95c0cf8c1e909L,0x3721300ae6e63ea5L } }, + /* 23 << 245 */ + { { 0xc03ad784d8dfd7aaL,0x671384a64b065a2eL,0x9b21e9e7bed74e87L, + 0x153b606cf889f75bL,0x7345c62a2aab6562L,0x270e4f445960cb4cL }, + { 0x515909fb885f0f88L,0xe43ee4f7067a7928L,0x5f906fc8fc182e56L, + 0x297ad5770641d0d1L,0xdcc45aa1d1b188b4L,0x8c817fb2ef062a39L } }, + /* 24 << 245 */ + { { 0x91e8c992044637f0L,0x01f7838827ee8e8fL,0x7c5e3f6dd095f5b9L, + 0xed7522fcddf3cad2L,0x80bb87056c57aacfL,0x495480b00cc5ff51L }, + { 0x964def7f04da2565L,0x8b0d0fe3afa72140L,0xcc75192584de66a1L, + 0x9acaf7fe075f07c5L,0x6505c2f81eeade93L,0xa2f35aa00e3cf58fL } }, + /* 25 << 245 */ + { { 0x1ad38a2d80548b22L,0x4d6120df47a37b3aL,0x6d64ef8c23e33cb7L, + 0xa1b5f51723c14ca6L,0xd2cdd425039a8e83L,0xa0a359ae229dd2dbL }, + { 0xde0788166c2779afL,0xd960453362d2abc2L,0xc5c48b20707c0e4dL, + 0xe452debd691c5407L,0x35c37ca882b0a299L,0x5b263014da3cde7bL } }, + /* 26 << 245 */ + { { 0xde34fa4586330487L,0x8391248153f61e6bL,0xd3f8fe742d04958dL, + 0xdade250f6df77d09L,0x3a3a16175649d9ebL,0xf9b77847a23abc74L }, + { 0x31d45db63b2e2c8aL,0x311ecc24f61a7bf4L,0x206029f9c56eab17L, + 0xb9d9ff35878c672eL,0x0d268c160fbf2d91L,0x2474b527a45f58d0L } }, + /* 27 << 245 */ + { { 0xad8e84be8436beaaL,0x8f07eee4209eb5d3L,0x47cba1d83ee61bddL, + 0xa081f21f72018544L,0x5dffddf493d88d16L,0x539a79efcac3952aL }, + { 0x990af57791bc452eL,0xb139d7d5012f5c6aL,0xf818c9f3fb180417L, + 0xeeb2d08475566152L,0x287571253f5d4ec9L,0x5a26505daa959798L } }, + /* 28 << 245 */ + { { 0x6536834e11b0f7b6L,0xcaa5271aad46c10cL,0xb5b6ead1fab43763L, + 0x25bf402ff7f7d8fdL,0xf33fb223e19374b4L,0x183ae9b75f348172L }, + { 0x1783c235078862a0L,0x9981a6c33cd368fcL,0xf58d2274fd627f9fL, + 0x37ac9c265c5e71cfL,0x167c8d047b0f157eL,0x24f522f8eefc7d85L } }, + /* 29 << 245 */ + { { 0xd25aeab3926cc973L,0xb3e2cffbdfc2cfbeL,0xdd259ed1de742b6cL, + 0x9d77c94e7b98bf81L,0x90f9067cb0ead3d1L,0x148f2a192a93fec1L }, + { 0xbae3c543c2850153L,0x0d330d758910422eL,0x06f80a9efa670474L, + 0xac6cee9f038431a3L,0x4900d17f5c22ee99L,0x62de04aa275a9774L } }, + /* 30 << 245 */ + { { 0xb6eefcc55f87fb35L,0x9766873b4371415aL,0x308337bd16b058bbL, + 0x6d5b1ddae1ac3884L,0x9307aa0835c4630aL,0x22cfcc0c23e91988L }, + { 0xbeb3814c37db0207L,0x19ab212fc4bbaf5bL,0x0801a1cf21abf22dL, + 0x9e6862cb3bd07332L,0xaa12ba0e4319929aL,0x0da45831f540f97dL } }, + /* 31 << 245 */ + { { 0x67d8ac9484bbf927L,0x7dd04e4e4ea01d33L,0x24ea6386f13def66L, + 0xa8a1acbe28f7f5f0L,0x5f578ffecc84c93bL,0xda8fe295f4ad116aL }, + { 0x4b610ae48483347dL,0xcac5c5596255f9e4L,0x19a0e043abcfe47bL, + 0xcd0cc9493966784eL,0xcc59a36743279291L,0xaa504087802961b6L } }, + /* 32 << 245 */ + { { 0xbe45d81a1b270599L,0x50696e7d97d6c603L,0x63c5a516b078ea89L, + 0x9f3efe41b4464764L,0x84580e24101e5232L,0x00850a1ac8ae8220L }, + { 0xbff4077ded55c404L,0xd74de734f2e7bf50L,0x4df4eef207e1c03dL, + 0x4ab3d0396e654d58L,0xb20056cd086f1596L,0xe4d08a278acd7cd5L } }, + /* 33 << 245 */ + { { 0x5510cebfe354510aL,0x48925b9349998c9bL,0xa05fc961e6d707a0L, + 0x85bf38f866ebc93bL,0xea637045254e615dL,0xae25e2e740d8459aL }, + { 0xa98583176efafd1dL,0x863931fd5a51c4b6L,0x3810d732d4221708L, + 0x959a2f70762a30f3L,0x7bdbaff9420ad3acL,0xba41b20bebdfe90eL } }, + /* 34 << 245 */ + { { 0x5e4d3280d3171eb9L,0x3fb715851bc65c5bL,0x6558962a901a899cL, + 0x78b7cd3e7851462bL,0x21228419ca8f6495L,0xfd8d8f9b2d8be765L }, + { 0xe5e90b92bc562144L,0x4f1f7ca1ae3243edL,0xd20178cd0985f4e4L, + 0xe5be263304253cbdL,0x1e34141c0d348fadL,0x0073fa0dad0eef45L } }, + /* 35 << 245 */ + { { 0x922ddb84d403f20fL,0xf7bccbb54681def7L,0x81a1200f6b580442L, + 0x64901025dc2f9884L,0x3746675aabe78edaL,0x3e750369aa6f005aL }, + { 0x140477ceeb00658fL,0xc76a320ccf89be62L,0x00761f21658c127fL, + 0x669186dfb8b6b03cL,0xbcdf1c36dcb26a2aL,0x94a7aba5da876a56L } }, + /* 36 << 245 */ + { { 0x1872f65c26163265L,0x9fbaf44fda52ad9cL,0xbec7addeeda47d38L, + 0x6a04dc3078094f9cL,0x2c73b8f15f4498e1L,0x504909efd4fcfcb4L }, + { 0x747efbc6b6b3a63bL,0x856e276de0dadd96L,0xa22459aaae3be3a4L, + 0x9ef59e732294a854L,0x0717d4e5d0e36205L,0x5a6afa3eb734cdf4L } }, + /* 37 << 245 */ + { { 0x6bd8fd330e938950L,0x8b26d7fa0f20c4f3L,0xd29a1121e0604d4eL, + 0x23d1cae60711c191L,0x460af39d51914cb2L,0x9cd04208547463c1L }, + { 0xeb80d70e493b7a0bL,0x182568869171652bL,0x9f3007ad76ca8b21L, + 0xf9bdeb4664ac10c4L,0xdaddd584284ae80cL,0x5c7ea28a0022abfbL } }, + /* 38 << 245 */ + { { 0xaef75aa7dc3c897eL,0x98bab5852e6432a8L,0x522b383d83fb0ee5L, + 0xe0d8620f056a8589L,0xd63525dd39352633L,0x74362bbfaeb985dbL }, + { 0x11419f4e8c0f17feL,0x3ca918b0494ba972L,0x39f2bc3c6e074e25L, + 0x3bb66618fbbf0d60L,0xee60c8f88579fecbL,0x916f3fe92a9b905fL } }, + /* 39 << 245 */ + { { 0x14ed31b6482b668dL,0x8e3e10db5b65978bL,0x72ff92eee8011bafL, + 0x5183d0bde1143531L,0xdb628188f9c740d1L,0xd23cb9c57570e3d2L }, + { 0x9e893cacd2745832L,0x49762940ef4a2b31L,0x02f6f892324361bfL, + 0x332e089dd7a881bfL,0xe9303153f788f52dL,0xcd6d15564e7f1bd7L } }, + /* 40 << 245 */ + { { 0x8caa623d408b62b7L,0xa58aa0b0c0272b41L,0x089af856ee285bfdL, + 0x77b461f6d0674ecdL,0xbaa9d9b38d6f6612L,0xa8f26e12590669f8L }, + { 0xb164340c5ebb5e28L,0xfdc11f7401ea89a8L,0x73c03b9176e4346eL, + 0x6a678eb17caad5fcL,0x103ff0790a87803dL,0x25d6fd2af7430a94L } }, + /* 41 << 245 */ + { { 0x72cc0aba66116d84L,0x642c88681039c0fcL,0xaeded9e6d96a7423L, + 0x4ff4163ccc5fea03L,0x180e4d3616483ec5L,0xefde910a7f6332c1L }, + { 0x8042696283367060L,0x4edce3e8c28af356L,0x2452e4de965139daL, + 0x15129fd9547477a1L,0x7f628b5ed80998cdL,0x7c56d44541054b54L } }, + /* 42 << 245 */ + { { 0x4c3f81184d3d9da9L,0x332072f9e1e71487L,0x8cbf7284759ef371L, + 0x3d13d85cb98ce007L,0x507b467f980f4fd5L,0x9853b98bc74fdfdaL }, + { 0x94b81534993f5e19L,0x316b761beeca71adL,0x09820a2331c04080L, + 0xc71a9bd4420e3114L,0x569f813822ea67ddL,0xe3ec5d2b3a41b079L } }, + /* 43 << 245 */ + { { 0x6085b24a19bb6f27L,0xc2f18e8f64dcb82dL,0x8ff89ed91fd3888dL, + 0x9fbe31db0e525a5bL,0xd52dfb5df0527573L,0x90288a3f703193c3L }, + { 0x87bb5d30bb1ce380L,0xb6c9a4c9f0dcf59aL,0xcbc52966aeb86e7aL, + 0xd151178a9a1636eeL,0x48342994e4b48c74L,0xe5bced925af80bc2L } }, + /* 44 << 245 */ + { { 0x106882534918179cL,0xdeb69dde08143b36L,0xfb3c527b992363faL, + 0x11d05e93e9393832L,0xe3249558383a0f59L,0x2d0f3e11c234ab5dL }, + { 0xd50a30d95c599ae7L,0x6d7abc6ce9f98316L,0x3d190629060ab6ddL, + 0xfd58473c81d69afcL,0x841193d24b782d62L,0x4f72696da771226bL } }, + /* 45 << 245 */ + { { 0x288895d056e467a5L,0x78166a95e025a5b3L,0x89df640e895835dfL, + 0xdc2b61f483dcbc50L,0xbeaa7363110dd6a0L,0x2346a2a5e7fdbe3fL }, + { 0x379ae5fb6947a9c4L,0x9dcf01956370a372L,0x34c3c6c3d70d9a24L, + 0x98ee14b7fe6a3d0aL,0xdd37708bba8ce5baL,0x785adb86a15c3672L } }, + /* 46 << 245 */ + { { 0x4c93de89c5ff194aL,0x56aef366fdc94109L,0xc8cb2a0c5b0b23d4L, + 0xd73f1cef587ada16L,0x7138315a364b1463L,0x43940ef59f6bd411L }, + { 0xad068e490f4a533fL,0xe8a772a33c7dac91L,0x74b815fc107998b8L, + 0x4b8fa9db92699ee7L,0xfb2de4bf4cbb023dL,0xe5833a390f67c29cL } }, + /* 47 << 245 */ + { { 0xe985acae7fc4fa91L,0x7730e38ec66c4282L,0x4b971449f4bda67dL, + 0x55261be02b001f47L,0xccde0c7126d0d8e6L,0xa7ac56fd701f6febL }, + { 0x2488b28552642a53L,0xeada397c58fcfabbL,0xa3fc0452b679b0e3L, + 0xd0ef09ffec2e921aL,0x9fcfd991575fb70aL,0xf4adcbbb366cb10dL } }, + /* 48 << 245 */ + { { 0x517075af5faa0cb7L,0x400a22c1efaf68f4L,0x320ce9493b86f639L, + 0x511565717f296bf4L,0x0919607a96108276L,0x4fcc39a02f035900L }, + { 0x5d13de7cefb73f3fL,0x19d725c5081c38e3L,0xf1b28089c0f58697L, + 0x2adcd1a30ca7ca20L,0x96c07f42c21e1be5L,0x94d28cacbaa0aba0L } }, + /* 49 << 245 */ + { { 0x0ff4983fd64cfa4bL,0x2c49c4918c55942cL,0x6093eb7f98eb20baL, + 0x1b33296a060497baL,0x32776a53c92d7b47L,0xf367e6b25241de3dL }, + { 0x711119813b65228eL,0x2e5dc541e1394451L,0x940a4a0f98ef33e5L, + 0x1a395be32cd4315dL,0x4d49469f3c2e20e1L,0x5384f4b95c314f95L } }, + /* 50 << 245 */ + { { 0xdda2f3a0a256813fL,0x4363d190ee6cbae0L,0x61f4d607930d0094L, + 0x6767ff4817021739L,0x8450091bd2c5fadbL,0x144d02fe870710a8L }, + { 0x73f45d9035524b7bL,0xccc7856b04615373L,0x0eb5cd436f081dfcL, + 0x9c433cbfe3a70d59L,0x9ee70f509818349aL,0x16de27347241c634L } }, + /* 51 << 245 */ + { { 0x02a24c5cc47f7db6L,0x519242cd33d60e1cL,0x543f39cf7244a636L, + 0x4ae15d698deb181eL,0xbaec81ef44261806L,0xe5cb18bb5fbf13abL }, + { 0x7534787a032158e7L,0x770e1e34da0d9a6aL,0x251bfa7158f9baccL, + 0x12663214c8d39905L,0xb7bfa81b39c3d64aL,0xd6d439ffe3ee296cL } }, + /* 52 << 245 */ + { { 0x192ecf72d0aa048fL,0x23af774063e40c0fL,0xe4d98e41d804d367L, + 0xd868cc885405bfc3L,0x96909a5b6f6ece88L,0x16b05ad2bae60dabL }, + { 0x7382a1dbde621949L,0x569bb6c9c47cf6dcL,0x892da43e1f2d098bL, + 0x6bd959b9bfa25649L,0x90617c419cb48f9eL,0x36059b73f110b22dL } }, + /* 53 << 245 */ + { { 0x1817b140791af82aL,0xf4a44cde042870c5L,0x60b8414ab5c0405aL, + 0x3b00f5ddf4dc4a9cL,0xa61aa0cfea81dd5bL,0xd43c37422554907dL }, + { 0x3fa264a620569ecdL,0x2cc69c2ba5a46190L,0xecd4f6d3dddd072eL, + 0x41083b72dda8de01L,0x4bc047f110d6f156L,0x7164b432cac3203aL } }, + /* 54 << 245 */ + { { 0x7e7e08f401d45bfeL,0x04f9c9ed0e2d17e2L,0x3213556fa55bc148L, + 0xc58983c734449f0eL,0x463217afaf2bb219L,0xe08a51a2f8fba72dL }, + { 0x2f44991e974d51f0L,0x15f2171f3f12af56L,0xbcc919de24cf01f3L, + 0x9ea371f269399bd0L,0xae8a8eca3ccf4574L,0xf0535b83ae499429L } }, + /* 55 << 245 */ + { { 0xe9ad8928f72305e3L,0x4144b6b9fce1295cL,0x672732a0c3487eb9L, + 0xf19d09a6147f70b8L,0xf45f6a11362a7684L,0x84ce4f25adfbbdadL }, + { 0x31e4bb0ac3403b48L,0xefc861b9b478ab38L,0x3323df44a8320c49L, + 0xa2838aa1ed4f14abL,0xc80e30cc63bf7df7L,0xdd2d5ef9f15ec5ffL } }, + /* 56 << 245 */ + { { 0x3027c1698d6f8572L,0x89326850111e64d7L,0xe6eb6cd31b8b0179L, + 0x0d2d27ea6dd5a4a7L,0x41682c0007c82f11L,0x5a01c54c81075022L }, + { 0xf3903f51fe7220d0L,0x75daeaba1f8e66b2L,0x1b625eed470bd3b2L, + 0xa46398a7e85a6293L,0x8ff6ef8c805ad640L,0xb3430f6795bfa3a5L } }, + /* 57 << 245 */ + { { 0x55d31765bc9341b7L,0x6530526ba312d125L,0x57ad29c02e9eb238L, + 0x31658a8282292155L,0x4d3417b169301639L,0xb38d6199e48c3d1bL }, + { 0x4399d5ddcc5202eeL,0x4b1c293a5076cc08L,0xa46e87f5824171b0L, + 0x16f75919e4cb40e9L,0xd086562dac35d85bL,0xc2b41ad532713f5dL } }, + /* 58 << 245 */ + { { 0x2da6d2ca3248f02aL,0xae49d2fc675de73dL,0x4abb1a65cfbfee63L, + 0xc6cea22cf1246350L,0xdd510cf82d3faec5L,0x8b7d1b0865e7460bL }, + { 0xc5b39c802737b182L,0xeee61e0d8963c709L,0x9cf9da61793e7179L, + 0x630637e52a295ba6L,0x18b85c9fa3881ba2L,0xca091a9464a94fe2L } }, + /* 59 << 245 */ + { { 0xcb68739f0bdec121L,0xf4907b3cd3811dabL,0xcf1b079b8c5d7707L, + 0x9ef9002d2fc6a56bL,0xc4c9d069809e8b64L,0xaf86a3db90d0eef4L }, + { 0x30a52f994b24a04aL,0x03bcd7a958574ed0L,0x330ce8a1a5b52b8bL, + 0x632b3c2d5e6a8ed9L,0x7b080a2c18369382L,0x12173e5f65187ce1L } }, + /* 60 << 245 */ + { { 0x027f654feabe8ef1L,0xd9d327e481a51834L,0x9215df61980faa43L, + 0x76b4f8003ba045c1L,0x8f3ce587f400732cL,0x0abe1f34f133a3caL }, + { 0x2ec690526de4f504L,0xa297cee4cb7ff026L,0xa31a76e3cadaefe1L, + 0xb701391e1173a958L,0x0a4279b08c8768f1L,0xd58927c12f8ede03L } }, + /* 61 << 245 */ + { { 0x71ea38454e630b0aL,0x4f696b59119263abL,0x9e7cb293f9cbab69L, + 0xa448d591c60ea8d2L,0x5021d4ef7d89eb52L,0x1a1ea5e3787663b1L }, + { 0xa95af4eb05bedc8eL,0xfe72effcc2fba411L,0xa88b79bb19a2c6bdL, + 0xbed948fac84c78eeL,0x022dcf3d5ee7455eL,0x0c39c3689f56accbL } }, + /* 62 << 245 */ + { { 0xe0e818a8b77c9de2L,0x0dbaea885e07f77fL,0x6ece83b97b1f96f0L, + 0x3c02e59631733a5dL,0x44bcdfcdd14828ffL,0x2791ca54b66f6107L }, + { 0x1a051c5a6198f24dL,0x9cd5f09a17627301L,0x64323392004a0cb1L, + 0x75d6819b3cc13e05L,0xf5cab2874a58768cL,0xbe090e83e3ca9332L } }, + /* 63 << 245 */ + { { 0xd639e0f3ab9b278dL,0x57f3f8cafa2407b4L,0x6720549f6c11f6abL, + 0x6ad1c608e784308bL,0x62c31e4a196babbbL,0x764b4deed1d36447L }, + { 0xf44efcefaf4407bcL,0x7c1f45dbb3ca82a3L,0xf43e4a8773b952b3L, + 0x145cd2d6ff478bbeL,0x11ef2df450c8e708L,0xa2af06f044491734L } }, + /* 64 << 245 */ + { { 0x8cd6c9f7c90b13f5L,0xec0c187d52a9d469L,0x9c0db0f589b8ad2bL, + 0x692a8db70d9c999dL,0xa407fd03c9f84ab4L,0xa5742fd1cc9a906cL }, + { 0x4813a765c8e72867L,0x9c65943de2e9a10fL,0xca6bf2934fa0a23eL, + 0x1dfa3af7cb1f8d7aL,0x28036f5498d10c53L,0x7bfbcaf20e012c13L } }, + /* 0 << 252 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 252 */ + { { 0xa53f1a104ec177f6L,0x4a2ef9aa3faa5ca8L,0x30efed8532976d13L, + 0xcf5ada165ee692d1L,0x3ceda69d259e7cc1L,0x2aae29e99baab472L }, + { 0x7ee5baef737cc8bcL,0x1717af747fe68dedL,0x9e5c8ddacfdaff63L, + 0x575c8db9cec07693L,0x9afc8ae0fdfb509dL,0x27836d3685651697L } }, + /* 2 << 252 */ + { { 0xa7342f9517eb9264L,0x9264a6a00a8a6eefL,0x50e48bf07471c384L, + 0x729e5ab130827f34L,0x17199191ea779c23L,0xd13ab8539fa9fd58L }, + { 0x7d5799373b1d773eL,0x65f8e7c6d196c3dfL,0x253f7d51e8541725L, + 0x107a793dec720355L,0x1c14d0566aa16268L,0x9dc5fca38bbb231bL } }, + /* 3 << 252 */ + { { 0xf5689c5e12b09f53L,0xc1da32e19e87ff7dL,0x1af879d012eaa533L, + 0xdba775e6d9271e94L,0x60f8507310e63c34L,0x445f3e21a686a24bL }, + { 0xed5ca8fa15bc277eL,0x9839198a364ab7abL,0xe2ee39426d90a7d4L, + 0xe5b3e4cbccd37e76L,0x9013bd08f1412e0fL,0x82f5c532ce999048L } }, + /* 4 << 252 */ + { { 0x61d0e01bf3fe3441L,0x674e52332af47609L,0xd4a4e224b362902dL, + 0x45923c129e0a5d16L,0x4fc2bdd495e580e9L,0x6d1d974ca8c3d954L }, + { 0xaeff1135d0bbeaaaL,0x013ab5b31baafc9eL,0x80907d3eab8f9f31L, + 0xaf2c12166d566c15L,0x0082daba952e6fa7L,0xa46710032df9e03aL } }, + /* 5 << 252 */ + { { 0x91b379c63223d561L,0x8cb7b8cce203417cL,0xd0f44208176b3b81L, + 0xd18c2118aaba5cd3L,0x4aed5c9770794f9fL,0xfc540dc4f4c33894L }, + { 0xb8e6798a0153a8a8L,0x6537dcdf43c4b0c0L,0x1b7eef39ab557397L, + 0x175e3934b7103105L,0x943abf4a82ac89e4L,0xeb1a61f957ffcdb8L } }, + /* 6 << 252 */ + { { 0x99c2b4cd66476227L,0x576a4b0662850cd3L,0x067bb66b5a352b7aL, + 0x3c7d6fc43ec757edL,0x2f69291cb9d36adcL,0xc7c0f3257c9143a4L }, + { 0x768c3c400627fee2L,0xc214d81da8fde577L,0xd86e4b025299ea1aL, + 0xbe46b7e91a2d4005L,0xaf865a169317fa60L,0xfbc3268fcdce2fbeL } }, + /* 7 << 252 */ + { { 0x66fcba52d8fbe900L,0x9f16434c861b3e33L,0xa371b97241b4305fL, + 0xb2d858ce25b6af89L,0xbab07d53275f9e8cL,0x3b5951f8d525bef8L }, + { 0xebf79e3ca1755b0aL,0x4e6256e7b467b1c2L,0x7dbd8b66cba1a659L, + 0x88ea40138b1eb8b6L,0x210ac1b38fa6436aL,0xe93e22c23df40e33L } }, + /* 8 << 252 */ + { { 0x5f79f0df1fd64063L,0xd2d39dd381e118ecL,0xd631a68e11571c5bL, + 0x6d072b4e2474faf7L,0x5e043a6d862a924aL,0xcae58bd8b0fc8d7aL }, + { 0xf54bb7f3b1351f28L,0x4588b6280413275eL,0x81459f4c5909ec04L, + 0xd28cda25abd16460L,0xbb676d018db1c69eL,0xc0056e2dac5036f4L } }, + /* 9 << 252 */ + { { 0x1ce187bf323169baL,0x1dfaef8661ab5073L,0x1893dc7b2ae468b5L, + 0x0748ec86123848d4L,0x0d2877b46a96eb12L,0xb6063e75e9322495L }, + { 0x1cb17189d7d1828fL,0xde41f11944d1b318L,0x7ce0f87610f0b74dL, + 0x2c7c91ee7a98f86bL,0xb641418e750f3ea1L,0xae2cd2e280094054L } }, + /* 10 << 252 */ + { { 0x9f6c6ed598d8e086L,0xa9ad63ca2d3fad85L,0x055b8323fe016926L, + 0x039fbe287b3a8d68L,0x544a8bf5fb6b315aL,0x04b122fb647fed85L }, + { 0x1e9807fa98085b1aL,0xb78a36a771c12696L,0x4ccc1a2cdc22f95bL, + 0x6ff4997d54d1e818L,0xecb5bdc2f08c22dcL,0x6e07e2c146a27762L } }, + /* 11 << 252 */ + { { 0x602077aceaaec565L,0x9dacf68224568aeeL,0xa490fc1e9cfcce26L, + 0xb2ac94b3303218baL,0xc0208604ab33f9aeL,0x801663b6e39a6668L }, + { 0x1defbb42961b0927L,0x688b445e83e318b3L,0x34fe2830c11648e8L, + 0xed56e99360066dfaL,0xa5f30f9a07671eccL,0x02c40260a3222e8dL } }, + /* 12 << 252 */ + { { 0xfb2a11b4ea347db9L,0x2360667e03350681L,0x1aa6e720a02a1261L, + 0xac2bd2eba110bb21L,0x8ab2f9063c9b4568L,0x5f46263d5ace1f17L }, + { 0x97067801eae704c8L,0x35d2637ea715d313L,0x24cdc3d0c77573daL, + 0x6f97cd07e2562b2aL,0x27bcd62d5afb29e4L,0xc38ac1c55d29f5d3L } }, + /* 13 << 252 */ + { { 0xd9c38ba47c88f46aL,0xdd07c4d79946ebe4L,0x908731dcce0e5417L, + 0x43088d11e145839bL,0x9d37419d07b61543L,0x440cdbcd2c3c7c4cL }, + { 0xa6a6fed673216db4L,0x15ce171a198cd32bL,0x198c256974e6a085L, + 0x5fec853f3dc2a714L,0x329250bdd5923068L,0x1d82373c9f6195caL } }, + /* 14 << 252 */ + { { 0xa8e17be53777b2aeL,0x534e3a3bcc284224L,0x7f34ce458192cfa1L, + 0x0009a72966d0e03aL,0xc42053ba524ce1fcL,0x834e98fe6d092e58L }, + { 0x400c65a1c8b0f751L,0x268bfe6f107965ebL,0x0f141c0332e0bc69L, + 0x33bc6e64597a2264L,0x039a4ae9454a0d6bL,0x2cb0bf550b07ddaaL } }, + /* 15 << 252 */ + { { 0x69056cbe63769bb3L,0x710a67d385044d35L,0x971ccbdeea855332L, + 0xd655163a0fd0d210L,0x619c3f9adbb8a8b9L,0xd156f73d49a014e2L }, + { 0xd04ea0a5a129a598L,0xc9c04da6fa2f12eaL,0xc0ed654ae98b3187L, + 0xa254eef6a82f9ec4L,0xe537695fa386a72fL,0x170f1ed4a74eb453L } }, + /* 16 << 252 */ + { { 0xdbe04c3044ce3ad8L,0x995fbb1b4ce8aad5L,0xdbf8b54670911457L, + 0x9e683b5b3f7a1757L,0x7b89a08a9c7bd62cL,0x448865a40b3fc97eL }, + { 0x0ac9abfc3bb01e94L,0xa07760421e756124L,0x0aa6c335d9deed97L, + 0xe270580f72603e08L,0x70857a946c783bb2L,0xa0047774caa929aeL } }, + /* 17 << 252 */ + { { 0xf99a63c5e8c4a440L,0xc7fd1d1419d65168L,0xfb6c21d696d5e80bL, + 0xa4a7304944b833beL,0x093728d5127b1599L,0x9046cbe2c89e7195L }, + { 0x21e2863c146a80d3L,0xb1ac7e1bdd559c13L,0xbe5ba65c72c39063L, + 0x7da5feb87722cbc7L,0x122615d0f17c02c5L,0xd44f477179e5fcb6L } }, + /* 18 << 252 */ + { { 0x0d913830e2d28da9L,0x0465920a8a164385L,0x79959ce1b0ad65d5L, + 0x6c94690759a966d6L,0x4ccb0e5e832c24feL,0xa8c5bee5d6af2a10L }, + { 0x264dcc118c5791fdL,0x719f23ac5b58ce85L,0xfbff8a2f8e54b029L, + 0x0c9240be864e959cL,0x8f7c21733c37c665L,0xfda848d9f164d354L } }, + /* 19 << 252 */ + { { 0x203ea731f35d11f6L,0x90610383f9f9001bL,0xb9d3c302ed97e6f2L, + 0x4c529736c9a67e6cL,0x2e440b1781f6597dL,0xcc798f5616aabf20L }, + { 0x490f50642832ffc5L,0x585e462a7a19b125L,0x99d73e391b06d98bL, + 0xb817e97aab696d7bL,0x9df2f65ac28dffeaL,0xa48dad47045fddd7L } }, + /* 20 << 252 */ + { { 0x2878c20d62e5fc09L,0x419ed2ece7f012abL,0x3bbc853fbaa21e7eL, + 0x412bc3c54844c009L,0xc4b150508b012199L,0x9d160f4c310d5fbfL }, + { 0xcb61b69214f60becL,0x436348c064092943L,0xce8c136e3185cde0L, + 0x97b034f68be5dd85L,0x7697adf92701631aL,0x2ddd86361fa6e8a0L } }, + /* 21 << 252 */ + { { 0xde8c2c963e9ff7faL,0xfdf1e25d8b75bbeaL,0x28ba3be59c146264L, + 0xfc1df52e81fcb0c9L,0xf9341c43af3ba66aL,0xe81c22470d72188eL }, + { 0x2ff00f1069c62b9dL,0x1077962e71498d24L,0xdf35b17ecc34ece7L, + 0x3516c33687eab2daL,0xe71cf7ddc72b7911L,0x6c9233d92c286c56L } }, + /* 22 << 252 */ + { { 0x7ce6389d162754d7L,0x8f03eff514e0d8e5L,0x9fd2c896ef402e31L, + 0x4a4bf70a2195b0e6L,0xe6043a383c8d82dcL,0xd86b647e8bed7c65L }, + { 0x21bc56f4a4c87660L,0x8c99d6270c05564cL,0xd6b82e9014050ee2L, + 0x09bf6a3eb6b11f0bL,0x9704b36731dcd6b1L,0x871c85c85e3d44caL } }, + /* 23 << 252 */ + { { 0x93024430e5236badL,0x4c5872728b883d1aL,0xc265b94bba68d3bbL, + 0x7d8fc82a648d9b7eL,0x57086e6e75ac264cL,0x4b8a157102fc9ec8L }, + { 0x83ae238e86849a9bL,0x2eaad9b8a69acccfL,0x2d82c029d44eaa39L, + 0x8f5b9ed833d7a556L,0x05c83328eea8b609L,0x537069efc3c96005L } }, + /* 24 << 252 */ + { { 0x292f8874b25c4d4aL,0x54961fd87e79f526L,0x949a1fae008c6ec9L, + 0x6ae82f0d525524fdL,0xd1f6f4ef2edbcb1aL,0x41617a6d977ddffbL }, + { 0x6ae38fb71baf0668L,0xa79ea228d538ab3cL,0x70babb05fc44e273L, + 0x247384fbbca85910L,0xdc0e069b6a564959L,0x37a9c5521a7438adL } }, + /* 25 << 252 */ + { { 0xaf2c87828a4b7251L,0xcb5ebfd3c1bc7f72L,0x160b77e560579615L, + 0x297412e3c10f067cL,0x5ad0681ef7df86c8L,0x2e8c63529b3e3afbL }, + { 0x32372cc74cfd3266L,0xb7abc8baa820f8b5L,0x857d545519f34baeL, + 0x5c055ce920ed65beL,0x1d8a59ca537ad6b7L,0x1135adcf7ad88633L } }, + /* 26 << 252 */ + { { 0x47e6ed9530034df1L,0x1839f488321bed8dL,0xb6b67d452ac8a9f9L, + 0x2fe1efc6182e4a63L,0x2da34bde0c1185c7L,0x6e5d1621edfdf9aeL }, + { 0x3bae9db77120804cL,0xf094b0676d986ef3L,0x029c9246853e24ceL, + 0x3abacb1b25a82463L,0x58777e1389c5616aL,0xaedd003b5aeed714L } }, + /* 27 << 252 */ + { { 0x7494e4319da5fb0dL,0xc684d74bee3fd6f3L,0x12fc899403a87d91L, + 0xc4c55e692d6e3931L,0x63e1255896336788L,0x36c297a5f78371fdL }, + { 0x4cd3f9c4a63b313eL,0xd2825e17c543e507L,0xd37e36d06a4e64d0L, + 0xab9559ec11872774L,0xaf168b34880a5d00L,0xb0c916a10c0c3f42L } }, + /* 28 << 252 */ + { { 0xd389397c834eaa9fL,0x2271ea0d2a5532aeL,0x5e59a23ae1f92e9eL, + 0x9f179b8c1f7b91f5L,0x2a1c10028de2dc8bL,0x6ac83e58787a276dL }, + { 0x0facd4756d9d1571L,0xcceaae5e4bf118e2L,0x4e8008b7620fbecbL, + 0xff633fef7a1474cbL,0xfbefea80ce377357L,0xebb9a9460feb7724L } }, + /* 29 << 252 */ + { { 0x0bab441ae9803b71L,0x309ef14684e2e21eL,0x17ccd5b6851b6519L, + 0x8b5e7e300126f470L,0x0560cb9d847eca03L,0xc45850bf11ade256L }, + { 0x08603f5c3c33dbbdL,0x21887bc9708ae545L,0x3bd25ad480014ffcL, + 0x5eb0f89fd3a64409L,0xbca2726b4c3dd83dL,0x611afd2fe4259797L } }, + /* 30 << 252 */ + { { 0xd9cb4233c4f4e0e5L,0xcfc0576818e49029L,0x8e9c8360526f05a1L, + 0x8e83037aa56d6c3dL,0x33507065c47e6742L,0x5ca2c8d8788b5da3L }, + { 0xf355cee9cfb0b6feL,0x0e86fd73973ddafdL,0x27fc6c56d44fd889L, + 0xc9ab416ff7d93f3cL,0x778c3f160d063d62L,0x175e5d920b5085ddL } }, + /* 31 << 252 */ + { { 0xd62406873be63d8cL,0xe8c93b93b80059a6L,0x33bba7dfe065854fL, + 0xcb26543f36b34e45L,0xc17ee58dd2d0c3d5L,0x69752f49bae1bcadL }, + { 0x87e31b429b20106aL,0xc520424b06734eb5L,0x993240afa896d17eL, + 0x5238851bc2762a62L,0xce399f9d506d7dbfL,0xa4822d23040cc7d4L } }, + /* 32 << 252 */ + { { 0xf071c9878fa06859L,0x0083e5311a52390bL,0x845eb12a61483bc2L, + 0x17471d801caf6dd6L,0x7b603616ddc21b92L,0xd38fe0f6b992536dL }, + { 0x433f0652297c25a4L,0x03d4d8fcb1c4bf41L,0xdf617386a9adf49bL, + 0x4bfeb3992cb2944fL,0xbf288427b3d9c076L,0x17818c3e965b4576L } }, + /* 33 << 252 */ + { { 0xfbcff79f6df360c9L,0x342f9ded2bd94c22L,0x2dc5f999283f2300L, + 0xbea18d9893cc3330L,0xc197176269a7da4eL,0x72de17ee93ce69a3L }, + { 0x6c354a6184170a91L,0x031ce0debe47ef92L,0xbf256fd418658739L, + 0x0395088a0d037d9aL,0x61179c42c5a05970L,0x0d5a9f7db8b6ab64L } }, + /* 34 << 252 */ + { { 0x18be1d605a44a8dcL,0xb512d945f1d18ee0L,0xd2e1f6623af39ec0L, + 0x440469136c223676L,0xe7a860836a60a4d8L,0xaefcfc2dc7e09d3bL }, + { 0x175817fad685c9b7L,0xe20b6c9e4b9d0557L,0x9212e7bb51fe560dL, + 0x748aafb7608b53c4L,0x86186d4fd9b06850L,0x4cc6041376512c08L } }, + /* 35 << 252 */ + { { 0x2d5be3b00c127e46L,0x8c6f38fad9b04e47L,0x49c444098736f31bL, + 0x5469ae47f53aa908L,0xd84856f3492fd120L,0xd04b1fa20725e199L }, + { 0x50c2e80a8e7056f2L,0x415db04c9ba2e259L,0x8e4c56ae2eb201e0L, + 0x449e4d9e5082ce94L,0xb5ff077a7345459dL,0x96d10f1e07330e72L } }, + /* 36 << 252 */ + { { 0xac77126e3b3094b7L,0x7c1e7673bdcb616fL,0x90491f8176993114L, + 0xf17c08a8cc8da63bL,0x972a3bffaa050364L,0xdef45b7f65a9cd57L }, + { 0x105ec5ba2b9b889eL,0x7066821150f7a61eL,0x11daa9dbb1d63a40L, + 0x6065451007790568L,0xfaa219cebc2b6d2aL,0xb1b8ace93e5163dcL } }, + /* 37 << 252 */ + { { 0xf8042ae2859b0f22L,0xd8a5d3a200d8bb8cL,0xe85c596189faae14L, + 0xb7d636f906611c0aL,0x35b68bbdd2bc8957L,0xc86f5be5b7cf558cL }, + { 0xb602a00369c17e74L,0xc39479cfd8a1fc01L,0x6dca5c81f733237eL, + 0x9c8cefd41b2e2cccL,0x2e32a323caacb4b8L,0xf7406874ad639090L } }, + /* 38 << 252 */ + { { 0xea3a358e24c1bbfdL,0xfd32af33571400aaL,0x2ec3d44da413949aL, + 0xa0d8594a7bd121f8L,0xb32997a1d6b6153fL,0xa0f48d98b9469c6eL }, + { 0x236b7a18fba15481L,0x49dee3bd98ff970fL,0xbc27ac7a7ee97875L, + 0xd1acf2be28ac6279L,0x92e7ef02514c8328L,0xb2d7a8304f48b497L } }, + /* 39 << 252 */ + { { 0xcaad0554d95946a9L,0x992268c973ed1281L,0x6c0b1edf7b1b25e1L, + 0x4de2d9f81d6e73dbL,0xe12a4f1c5a2950a9L,0xe0cdf7af36ac18fdL }, + { 0x16e7332d1abcc9f5L,0x4dccc1505bac1c75L,0x1b48bbc141f8c231L, + 0x3702cc2693692a4aL,0x9e9e53dd311c5dabL,0x27bc006cfe5d9fd3L } }, + /* 40 << 252 */ + { { 0x2bb798ff689f43efL,0x5813e4415f26ec54L,0x51f64c495005c929L, + 0x60e213a54b42e417L,0xc152844262cc3734L,0x6ecd6c3b09d994e1L }, + { 0xa6e72f7183dd047fL,0x3836f663b0019803L,0xbcf1265b257493cbL, + 0x59b15ff09e62d78bL,0xaac5ed5b6cb92ecfL,0x37e6ad7d9662651cL } }, + /* 41 << 252 */ + { { 0x04743bf8b224f6c9L,0xec04b641ae33b1caL,0x6301f51623a76fccL, + 0xf1aa954675e15fe9L,0x878c64ecd95c1972L,0x033df5ee3ba7578aL }, + { 0xe5e9ff7c47f4721fL,0x9b3d93fa03eef7e9L,0xcd0be6ad573deaa6L, + 0xf377570f3bbc8a16L,0xffdc04c161c37393L,0xd9eee46dd26d659dL } }, + /* 42 << 252 */ + { { 0x33f933604d4b7317L,0xee44b3e02fe482ebL,0x5a96870480f1fde5L, + 0xdfd6293b5510952fL,0x2abdc1989cc0af6aL,0xe608e2769ff45aedL }, + { 0xf408670e3247e796L,0x3144153535fe07c4L,0xa941f96e2870053dL, + 0xbe908795ef6383adL,0x82b620a63560fdf0L,0x2c1cc1ae135de5c8L } }, + /* 43 << 252 */ + { { 0xa829397c727e5988L,0x305659bac6239b1bL,0x9b13701200392cb0L, + 0x4eb1ddf376091862L,0x68b64b19202bdd8aL,0x56c427c5228071e4L }, + { 0x354b1beac3375accL,0x94a45b4e54e1194bL,0xf528df0178095edbL, + 0x6fb0867146fb9ec8L,0x977efc84c555bd48L,0x8230d6f7c268a20dL } }, + /* 44 << 252 */ + { { 0x003d4004b8d81c0bL,0xd3d5048f4168a407L,0x7748ecacc6675bd9L, + 0x9dba4539e2612cf4L,0xa5ebbccfd8770b8fL,0x206b4a9aadd90558L }, + { 0xe446ed9c81b5c103L,0xcd2434184d2199dcL,0x0840f6eacb0d70d5L, + 0x6fbbf1b43107367bL,0xde9444f7d29335c8L,0x33ef004c66252eb6L } }, + /* 45 << 252 */ + { { 0x10eac97aa5a6546aL,0x6129392fe231f95cL,0xfd41bda100e2aae3L, + 0x5b1f93299d8c6288L,0xf1d2fc9246b7df40L,0xbc6fbacfc5df62bbL }, + { 0x64885d924b5af011L,0xe4f3ade883461896L,0x644ce7a7a4a62e43L, + 0x74c9d145337b2730L,0x69d714840f83222aL,0xbfbc594ec27c0fdbL } }, + /* 46 << 252 */ + { { 0x3263c0517ed92916L,0xc039b94884e3f519L,0x54aa433ede89de6dL, + 0x92f76292c0971a03L,0x8457b2312550a2e8L,0x46ab1f0f11cfcd9aL }, + { 0xd97b95c1c6d53077L,0xe8db11d159550599L,0x2092c81385ea4b32L, + 0x149b6b2cb7ced408L,0x2ada6fa482b9b22fL,0x53a5576a25877963L } }, + /* 47 << 252 */ + { { 0xa1e2c2a8195ad455L,0x65e90a3de7f61038L,0xb01eaa52ec623680L, + 0xfad0f9f110302efaL,0x9e544b5449274409L,0xfc9037de8c3a0925L }, + { 0xbcf196fcfd139cdaL,0x0a1f747c4f6a2cdcL,0x580a9abab879fe3eL, + 0x08a20f1c5ee74778L,0x7c9be7de464c5271L,0xa4a1972918e85a09L } }, + /* 48 << 252 */ + { { 0xce23a19aa17e560cL,0x6491b95f62550e2bL,0xc72000121d15a005L, + 0x15fde735f4355a1fL,0x3849761f607f7807L,0xcbe322d018204691L }, + { 0x75756e4ea95e8e91L,0x365959fe817a9b8eL,0x631232763d4ce3dcL, + 0xa769d2fef1d66e00L,0x8624ddbac28829e6L,0x03274297d2df06efL } }, + /* 49 << 252 */ + { { 0x2ad21bdadf3b1368L,0xf4f9d5270b3001abL,0x10182c5557ecb528L, + 0xe00db71565372a5bL,0x2018e0ed74f2bd83L,0xa11b47066175efb4L }, + { 0x3172264722d565cfL,0xb20c27ab2f0faac9L,0x4ca2982a6260f995L, + 0x3850ef89b7085c6fL,0x5b4a6e235f0d45a3L,0xde562df9b7523682L } }, + /* 50 << 252 */ + { { 0xb34ecab233bb63f6L,0xe6cd56a202944c4cL,0x2690cc39489a8d88L, + 0xcdfe368a4fe612dbL,0x23069ca5e9e9f7adL,0x7b87105cc07d742bL }, + { 0x5114645a8b58ea8eL,0xd31fb4821829e8aeL,0x5e235d95c4b28520L, + 0x2a1cda885c2292d2L,0x95d77447ee925b6aL,0xeec419a3df18845dL } }, + /* 51 << 252 */ + { { 0xb8903f10be9ffa75L,0x8bf7fc786432dcc3L,0xcf3f7cf15d028549L, + 0x7684baf29846f2d9L,0x4c580edbe9e063deL,0x0ac5c3edf2d70321L }, + { 0xb9ba10e184c5d96dL,0xbb854b39d7aaabafL,0xe29d66964793c87aL, + 0x7b0fe1d448285ae5L,0xa143454df0121733L,0xa286eb043aa5ddc8L } }, + /* 52 << 252 */ + { { 0x8e4dcfc88c93bc5fL,0x9f96d60a1b233295L,0xae5262e91d447dcbL, + 0xafe58396541d46c4L,0x3e733c2636ff8f80L,0xcb36a37748b81037L }, + { 0x9bcbfa9fc406ef17L,0x57a6e28006fb128aL,0xd86b44db9a771eb1L, + 0xc7ce106e62545a4dL,0xec6818a6b254c908L,0x4b8d3fc550feb342L } }, + /* 53 << 252 */ + { { 0x8faa39c8b609ef4cL,0x0209b3a7d8225cceL,0x11254c211feffc0fL, + 0x64930dcdc1e42ad3L,0xf5b058eb1cbb39fcL,0x2f870e3341cb5065L }, + { 0x61b3611cf7663f95L,0x981890b637941996L,0x00c42b0908dd6854L, + 0xac42af5de17da075L,0xaf3a394c282b8d53L,0xb53b3b245d8bab96L } }, + /* 54 << 252 */ + { { 0xe17c9d98d90f0c83L,0xdd4aa8ac6d984408L,0x94b6fc50f71aef46L, + 0x2e6b5d24f0a2009eL,0xcb9d9cd17d8d75e4L,0x5e732a5b962a1708L }, + { 0x9d774f1c7fd01089L,0x56bc35aded95094bL,0x6844220bb9c797d4L, + 0x40021d8e90ace48fL,0xddc769c5701baad0L,0xe23e8f9e333ac2deL } }, + /* 55 << 252 */ + { { 0x6cf6faf6e92e42bdL,0x759dc78b0d1e6a0eL,0x18fd55ff11532759L, + 0x04a306d7e9af0c07L,0xd7febf615ef7f82eL,0xaa04f1dca65cae01L }, + { 0xb084407c16442bc2L,0x17ab4f74f874f10aL,0x236368d40fb6cea7L, + 0x451ea8206f66813dL,0x4a61097b1760e6ecL,0xa8655cfba01bdd2aL } }, + /* 56 << 252 */ + { { 0x52fced3116f01d7bL,0x88c6b172daf046aaL,0x1a189403fe7a338eL, + 0x39741ecd61798b1eL,0x6a47b0712934b879L,0x3b1a5dd1828d1e9dL }, + { 0xd4bd48487f35a7efL,0x71774b5bc1eebaf8L,0xa86471e5d55344baL, + 0xfbf145f17b8a483aL,0x70f9b214aa53802cL,0x995af93010b066e1L } }, + /* 57 << 252 */ + { { 0xd2714b97aadf25ceL,0xb95c54162a7643f1L,0xae7dc619ba2f1939L, + 0x30e5d013b0db537eL,0xfcd1a456753f0813L,0x19f7117cef62925cL }, + { 0x40a22e35423d3c56L,0xb0271e9926a5534dL,0xc19f703cc76c9a1eL, + 0x9b8fe585560bee08L,0x48c7797d3cc772aeL,0xabd2148e10bd6393L } }, + /* 58 << 252 */ + { { 0x046fb36cc34a7ba2L,0xd42e56d42a61a8a6L,0x16b8fd2d3d4b1184L, + 0x6f9e85a26da29888L,0x1ff7324bdd683c49L,0xdb3746db27bb8e2aL }, + { 0xa7e586e684be7f99L,0xfbd0c0ee61740d6bL,0xb80509bab2071320L, + 0xb5bf09fea3f03641L,0xe872cd854971e39fL,0x9bed91c0ce2b2db2L } }, + /* 59 << 252 */ + { { 0x85177e7ca6bad7b2L,0xd5b1f0901425b611L,0x6b5f16223c4bfa24L, + 0xde34a692def66d8aL,0x96c0663ee8a1b7a0L,0x43eb91ed459c8bbbL }, + { 0x6cc7e78b7d3d8b92L,0x3c9da7efe0338ba8L,0x18d7ab00e21360b4L, + 0x0785ca897f9df01aL,0x5bcfb8302220f1efL,0x8c61a3bfa52bbf42L } }, + /* 60 << 252 */ + { { 0x4dcc3b82196c21d2L,0xef0e0e1e61071fd8L,0xa2a28c3b35a013f7L, + 0x7550d3d7f6b58f80L,0x0f1fc9d58101742bL,0x027874f055982d5dL }, + { 0x5a10b98c629bc409L,0xa28a1b2baf494679L,0x84afdbe1b96578d8L, + 0x201a8062d427238bL,0xe321ee2d89fffdb0L,0x0b304de4fb89f171L } }, + /* 61 << 252 */ + { { 0x5d8e16c0d7700dfdL,0x336e30fa24260211L,0x7ba72067ad557ce2L, + 0xcb388c3169621e0dL,0xcf6b7d813dbf7ba3L,0x7bfe43a91cbd216aL }, + { 0x6c40516adcffe0b5L,0xe77507f083b7ea33L,0x5b5cda074ba1fc8eL, + 0x46860dd296c6d2c6L,0x4716114f0eb5013cL,0x05bd136898c3642cL } }, + /* 62 << 252 */ + { { 0x7fac263852ca5d3bL,0x35e5d8d0f5a2a596L,0x4c7129210011a394L, + 0x400168f7a9c417e0L,0x220994b447b77b44L,0x01a7580af548c0adL }, + { 0x59870c2afe292ad7L,0xdda35a1a2abf8e7cL,0xa3082dc4f16d0c7cL, + 0xd4dcd5f38557c9e8L,0x38d45cc6ba7f0f99L,0xdefc0b1da7c18157L } }, + /* 63 << 252 */ + { { 0x5db2ed891c43e426L,0xeed247709adf4a50L,0x0b5e19765c8b90e1L, + 0xe9db695ffa18542dL,0xc16d3bfb8d043dc5L,0x5c5feb44f11d3430L }, + { 0xd44e3d57365593c0L,0x1338f26c8796edb5L,0x789b325e051ca644L, + 0xaa93b75d1579c2bbL,0xa39a8ec57842c0b2L,0x84225134550ddf11L } }, + /* 64 << 252 */ + { { 0x9ec1159727a28f9dL,0x96f2c44bb847cd83L,0xacf794e131fca111L, + 0x438b917896076f45L,0xad71035b51732588L,0x2db32f32a5d910daL }, + { 0xefaad0e8fe1cc184L,0x6f0360b52e00bbedL,0x99402426474ce326L, + 0xd53b687a2aa270daL,0x96c8bb78d78fa6ebL,0xd07f3bba6e699411L } }, + /* 0 << 259 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 259 */ + { { 0xfe1f11ad389283baL,0xc87e20b60cd91b22L,0x99d0015a3c5babf8L, + 0x7e795b4d5929ea0aL,0xc9cf68331dfb7b7eL,0xc1c07346a64992e8L }, + { 0x0b7e0dd89889746dL,0xa89d7b461c43ea4aL,0x64023cf034f02b96L, + 0xf7dd410a5662f0c8L,0xa3bb6088a1058ccaL,0xedb25dc34e7801edL } }, + /* 2 << 259 */ + { { 0x140a0f9fdd93d50aL,0x4799ffde83b7abacL,0x78ff7c2304a1f742L, + 0xc0568f51195ba34eL,0xe97183603b7f78b4L,0x9cfd1ff1f9efaa53L }, + { 0xe924d2c5bb06022eL,0x9987fa86faa2af6dL,0x4b12e73f6ee37e0fL, + 0x1836fdfa5e5a1ddeL,0x7f1b92259dcd6416L,0xcb2c1b4d677544d8L } }, + /* 3 << 259 */ + { { 0xb6f8d615a033cccdL,0x6aabb87cad75e31fL,0x30a03029a4646d1bL, + 0xfad497e6e6547805L,0x4b9d45c3ba291f12L,0x0f74909bca059918L }, + { 0xdece1fb0b5a181b7L,0x973f74413be1f21bL,0xcc919af36b06839aL, + 0x14427886ad57101fL,0xc63a79882bbc8022L,0x04cf807426742ccaL } }, + /* 4 << 259 */ + { { 0x279fd119da1c29abL,0xbd0688022b30d40cL,0xd8f57da4da44105dL, + 0xb1814b7a28223fe1L,0xcf2fd241e06f2d2eL,0x99003a0201dfde06L }, + { 0x876a31affded7e4bL,0x1efaf8272f725094L,0x5117d608493a6a0aL, + 0xdcec8088a88c03e7L,0xeae1d352ea916897L,0x8cdc28106e8b2c57L } }, + /* 5 << 259 */ + { { 0x52fb8e6f7041b903L,0xd7fc4b5b2ad368a3L,0xf16c61d2f890136fL, + 0xeee859dfbb52a90bL,0x1651b16b3f8396cdL,0xfbced93eb6462918L }, + { 0x1cb3126c4b6bfaa0L,0x65dfc76cc7c8fd16L,0x225b9c21bb46a3c9L, + 0x6c3457577f64f9ffL,0x6f65fadd57c297ecL,0x72a630eae5c5bbbdL } }, + /* 6 << 259 */ + { { 0x0254486d9c213d95L,0x68a9db56cb2f6e94L,0xfb5858ba000f5491L, + 0x1315bdd934009fb6L,0xb18a8e0ac42bde30L,0xfdcf93d1f1070358L }, + { 0xbeb1db753022937eL,0x9b9eca7acac20db4L,0x152214d4e4122b20L, + 0xd3e673f2aabccc7bL,0x94c50f64aed07571L,0xd767059ae66b4f17L } }, + /* 7 << 259 */ + { { 0x25cb1f44f4fefeeeL,0xe1a6b6c8bce660c7L,0xd25459a00d2118e4L, + 0x716532dafedf8f98L,0xaeff37d492cfb480L,0x45919f7da1453c41L }, + { 0x5100afe08d8836a6L,0x2ec20fd7b35d4fe0L,0xce8eefd1c00b7d66L, + 0x922d535d6b82c7ccL,0x5eb38f3fddd8d80aL,0x7eae5305213ae465L } }, + /* 8 << 259 */ + { { 0x09f8bb0654e93c1eL,0xb0045884ad81e27cL,0x26ebc7b6076e13ebL, + 0xbda0b5535d5ac07fL,0xbcb8132248ab69e6L,0xd3847d2e1c0f21faL }, + { 0x7a466528c834d740L,0x6c67a79ae0823ff2L,0x85dd11864c1d7cb8L, + 0x096f849f2d081301L,0xb4f503dd8a5ea0f0L,0x71ee0889d1bf69b2L } }, + /* 9 << 259 */ + { { 0xd7a5f9feaa074b9eL,0xbeda44032fd2468bL,0xca3956309c35ffcaL, + 0xb02a1f592de68348L,0x946b0250903b35c7L,0xe9984f24634e9c91L }, + { 0x4f70d22fe7303041L,0xf8a05d7fb68b0051L,0x0ce7af4fab5006afL, + 0x1011d1644a6bb502L,0xdf959199da4ad1a6L,0xc468cddf1e146f24L } }, + /* 10 << 259 */ + { { 0x40336b12dcd6d14bL,0xf6bcff5de3b4919cL,0xc337048d9c841f0cL, + 0x4ce6d0251d617f50L,0x00fef2198117d379L,0x18b7c4e9f95be243L }, + { 0x98de119e38df08ffL,0xdfd803bd8d772d20L,0x94125b720f9678bdL, + 0xfc5b57cd334ace30L,0x09486527b7e86e04L,0xfe9f8bcc6e552039L } }, + /* 11 << 259 */ + { { 0xffd4fd775b5c7501L,0xc43e409ee0600e93L,0xd2a18cba7d522993L, + 0xbc2e14dc17c84d1cL,0xe84deb43c1eee29dL,0xe65326f08d691cbfL }, + { 0x89760cdd77b726afL,0xb91c302a577b30acL,0xc6a742906e145891L, + 0x95bf3e913be85cc7L,0x2ec0285b9815e0edL,0x5b4be6da8aa3ec95L } }, + /* 12 << 259 */ + { { 0x4ab7a22c02a2d1e6L,0x967e19a31371d5a4L,0x20f59f95078de336L, + 0xfd28fa36f7869245L,0x1de42581cbf1d96fL,0x2e0127d7366e1f0fL }, + { 0xbc65fa9d2258c741L,0x1f2f3356dd6d65f8L,0x06384f3a4a0822a9L, + 0x1c81332bfd05a0aaL,0xbfb12361d95ee3ceL,0x180aaf0642016d00L } }, + /* 13 << 259 */ + { { 0x329ff57bf08c171eL,0x6cd8122a543af2a9L,0x5209a3d65b2f8d96L, + 0x0285b128ba90c881L,0xeb5971ef61b43c8fL,0xf1ec473ccfd759b8L }, + { 0xd2a79fb712d58e1eL,0x695f4877fdb6497bL,0x8bf5a4251f1a0f24L, + 0x3e79a0dea5c8a189L,0x9c8ada35908b7ae3L,0xd8b8622c5000f772L } }, + /* 14 << 259 */ + { { 0x3b75c45bd6f5a10eL,0xfd4680f4c1c35f38L,0x5450227df8e0a113L, + 0x5e69f1ae73ddba24L,0x2007b80e57f24645L,0xc63695dc3d159741L }, + { 0xcbe54d294530f623L,0x986ad5732869586bL,0xe19f70594cc39f73L, + 0x80f00ab32b1b8da9L,0xb765aaf973f68d26L,0xbc79a394e993f829L } }, + /* 15 << 259 */ + { { 0xdd01a72b6024f09fL,0x192c8254378d12e1L,0x03ec536bf5d8b8d0L, + 0xb0c4c01873806514L,0x7d3c5f5614d202b6L,0x7c2a7c5c6febb3e2L }, + { 0xf2fa07d4f9f2b562L,0x6f717b003ba2a4faL,0x1ff95d598f452226L, + 0xe4b3f6ba867c1cf1L,0x907a648a5d0944ecL,0x1ed480007f64f9b9L } }, + /* 16 << 259 */ + { { 0x0a159f6295b3287dL,0xb18f875948cecad0L,0x6d1ab8ee1661a23fL, + 0xcae7f40ec95c41b3L,0xbc3d20407c51eb56L,0xa7527283e8754250L }, + { 0x815610561f9e668aL,0xb8aa7296900f5912L,0xabdbc1bf6af2a00cL, + 0xe9a942542d0a56c0L,0x4774a7b77bc8959eL,0x0a837ff019cef2f3L } }, + /* 17 << 259 */ + { { 0xd9c3f4ea3c696c76L,0x3aff88caea5878bbL,0x2b01171b09dda122L, + 0xa61d5ca0f599cad4L,0xba0c19bef49772c7L,0x8ee9acc25001f977L }, + { 0x15fd3a172549a25aL,0x8f1a25d82263bc97L,0x372b88434db4af00L, + 0xa613b31f4f912925L,0x7d83041a0b64efd9L,0x897c521ca7d5f6a8L } }, + /* 18 << 259 */ + { { 0x9c441043f310d2a0L,0x2865ee58dc5eb106L,0x71a959229cb8065cL, + 0x8eb3a733a052af0fL,0x56009f42b09d716eL,0xa7f923c5abcbe6adL }, + { 0x263b7669fa375c01L,0x641c47e521ef27a2L,0xa89b474eb08ffd25L, + 0x5be8ec3ff0a239f3L,0x0e79957a242a6c5aL,0x1dfb26d00c6c75f5L } }, + /* 19 << 259 */ + { { 0x04c6a90ae75c82afL,0xe9183100f2488abdL,0xef4b378b111a46baL, + 0x77ad9ef502eaa62eL,0x61229a6205e81570L,0x06e26a2db474c367L }, + { 0x0bb2ea7e7113f2d4L,0x8ddc6f887f101386L,0x93fe2d7ef4de63abL, + 0xc3d038278f44e271L,0xe9f9f48ea94e641aL,0xb84b817b4962467dL } }, + /* 20 << 259 */ + { { 0x36f3a3d8a084fae6L,0x759835899a9b0d95L,0x70722186cc80fcb6L, + 0xf28ed0c796d84c04L,0x95a32263ffb63f90L,0xdd7d60a098766034L }, + { 0xe193a31f1d5c387cL,0x6c5eca7eb8310f8bL,0xfe61d523c083ff47L, + 0x90c832dbcb2944e9L,0xa9f3f293593334b7L,0xe6cde2e12d7d1c33L } }, + /* 21 << 259 */ + { { 0x5637d16b065096b9L,0xee3a2ad04770d39eL,0xae605cb56aa94587L, + 0xc2d71dae9b600c6eL,0x672ef30d76a87e0aL,0x74d5bebe567e0817L }, + { 0x38f591310eb8ca48L,0x92b74866031e099fL,0x654858ca785f77eeL, + 0x264b6b7b830be443L,0xb167203d57103903L,0xa73d5d545ce2b21aL } }, + /* 22 << 259 */ + { { 0x2fd97b9b9dfbf22aL,0xdec16cc85643532dL,0xdf0e6e3960fee7c3L, + 0xd09ad7b6545860c8L,0xcc16e98473fc3b7cL,0x6ce734c10d4e1555L }, + { 0xc6efe68b4b5f6032L,0x3a64f34c14f54073L,0x25da689cac44dc95L, + 0x990c477e5358ad8aL,0x00e958a5f36da7deL,0x902b7360c9b6f161L } }, + /* 23 << 259 */ + { { 0x5e8eb8f0636a77efL,0xe14290f8970c3a7fL,0xfe6f6acdfa1784c0L, + 0x98671d33de6a46b3L,0xe7fd88722ae5a76eL,0xed971ecbae4f7d60L }, + { 0x1d90dbd88461b895L,0x3f979ab4bfaaac13L,0xe06ccba1dbd3379aL, + 0xb53b04ba108c4487L,0xe42609dd38d2730dL,0x0638fe82e81c4594L } }, + /* 24 << 259 */ + { { 0xbd079cf1f144b6ccL,0x7f86e29bb4f4a764L,0x5b08b290f21f9cbfL, + 0xada0c85b75e3aeb9L,0xd0789f8b6666c2dfL,0xcf5d8a8cd71ec2ecL }, + { 0x6f7780c3e7e4364bL,0xdd9a652985d2eb75L,0x8222f66bd952a38eL, + 0x9dd5f7eb27260a29L,0xce49b34457947178L,0xaa215f82cdda7e39L } }, + /* 25 << 259 */ + { { 0xcb91619d1419a50fL,0x44a22eac65dc4c84L,0xc199f93701a92405L, + 0x3749a33198045324L,0xf1676e8abc57764dL,0x922f9460a00c33eeL }, + { 0xfde98e63d3766db4L,0xae08a82efd5ffb6aL,0x6a9834537c0c6ae7L, + 0x0e9a919a54f34cdbL,0xf37a95e8fd88d765L,0x927427d4228a1affL } }, + /* 26 << 259 */ + { { 0x454ab42c9347b90aL,0xcaebe64aa698b02bL,0x119cdc69fb86fa40L, + 0x2e5cb7adc3109281L,0x67bb1ec5cd0c3d00L,0x5d430bc783f25bbfL }, + { 0x69fd84a85cde0abbL,0x69da263e9816b688L,0xe52d93df0e53cbb8L, + 0x42cf6f25add2d5a7L,0x227ba59dc87ca88fL,0x7a1ca876da738554L } }, + /* 27 << 259 */ + { { 0x277c833f57c7bf99L,0xbbb84d1d0b301f02L,0x11435cb20713a92bL, + 0x8ae509702d02862bL,0x4edc66bdaa7b0660L,0x5bc0d893d6382c91L }, + { 0x7992c5d3b94a6343L,0x1cfee04147b19345L,0x57963034964ed646L, + 0xd7af0cac3de7b0e9L,0x5123dd8d481b940aL,0xe1d23ad8ad7d3567L } }, + /* 28 << 259 */ + { { 0xaa44b2863004db31L,0x86f43d7ad43e4430L,0xdc4874cdb0b0240dL, + 0x79986a23adc45a06L,0xbb275b443cee4631L,0x21daee8a63a217aaL }, + { 0x1e7c5397d7b25c02L,0xe677d3cbc5e668faL,0xc7c84e28ed51b4bfL, + 0x7ca19e99923e5408L,0xc6f8a595c3f832e7L,0x2d0a789c5fb049a3L } }, + /* 29 << 259 */ + { { 0x49702e622b82b466L,0x365d4f6afb8fe508L,0x2f5234e044884733L, + 0xcd527f345dd0a3d5L,0x371b02544bf4033eL,0x7d84ad677e3212e0L }, + { 0xaf48fd79e69d6b81L,0xd126f83a7a44bfc6L,0xbb8d2b57b2cc4e93L, + 0x5f62a3d5eb60ec5fL,0x7b37da33aa76c824L,0x7593d06b89a682dbL } }, + /* 30 << 259 */ + { { 0x3fa5c1051cac82c4L,0x23c760878a78c9beL,0xe98cdad61c5cfa42L, + 0x09c302520a6c0421L,0x149bac7c42fc61b9L,0x3a1c22ac3004a3e2L }, + { 0xde6b0d6e202c7fedL,0xb2457377e7e63052L,0x31725fd43706b3efL, + 0xe16a347d2b1afdbfL,0xbe4850c48c29cf66L,0x8f51cc4d2939f23cL } }, + /* 31 << 259 */ + { { 0xc342ed50dd305573L,0xe3055013de86c6c8L,0x0ae84d9776deedc4L, + 0xe8e70cbfd1274b52L,0x4bb51dce32e87f7fL,0x32de3672f3748177L }, + { 0x528af91681722d55L,0x459af071a5f2ce91L,0xf6883bbdc685a670L, + 0x398657f9eeb836b8L,0xa08a793eb9278bd7L,0xe786426bcc09e408L } }, + /* 32 << 259 */ + { { 0x114a25c844922386L,0xdd084d446d4e8b57L,0xc49b68411e7bd7deL, + 0x5b0359fad6da54dbL,0xa6e6e5f93f0da321L,0xb65ec55cd640a87eL }, + { 0xc1a4f6ceae64020eL,0x91e29cd2088e1337L,0xf44ceb8e3c0a631cL, + 0x0205b11db756445fL,0x04844e845bc8880eL,0xb630ddc0b85e00d3L } }, + /* 33 << 259 */ + { { 0xac512659c6ee46b6L,0x0c92e402ca82b384L,0x81d79049194fba3aL, + 0x9b68376c36b42b32L,0x6dc1c80cf6b410b0L,0x509fbe9196b2b328L }, + { 0x988fedd6fdc783b1L,0x9f34cd87436ed055L,0x29f243648bb8809fL, + 0x6962ca24b8dc8b68L,0x076cb7b931963ff9L,0xb609ad792b915093L } }, + /* 34 << 259 */ + { { 0x169e025b219ae6c1L,0x55ff526f116e1ca1L,0x01b810a3b191f55dL, + 0x2d98127229588a69L,0x53c9377048b92199L,0x8c7dd84e8a85236fL }, + { 0x293d48b6caacf958L,0x1f084acb43572b30L,0x628bfa2dfad91f28L, + 0x8d627b11829386afL,0x3ec1dd00d44a77beL,0x8d3b0d08649ac7f0L } }, + /* 35 << 259 */ + { { 0x4aeb3f870af947c6L,0x9ac9ff2791d090c1L,0xeaaa7e0fcf698277L, + 0x737ccc2ff09d6155L,0xd5d4bde86753cc31L,0x3b9063477146d4a3L }, + { 0x75106d8959e32369L,0x7a8ee281645999b3L,0x9184fb5cfc3f675aL, + 0xaeebd0423ad4e239L,0xcff8f73e12f449d1L,0x2771bec17339eb4bL } }, + /* 36 << 259 */ + { { 0xf783db44e6674091L,0x57d0eed31e12a3b7L,0x62d2762af3474f91L, + 0x3d122edf0562af71L,0xaf78dbf77f4bbcbbL,0x8fbbbd97e55f0654L }, + { 0x77e117b004bac36eL,0xbbf6bd463ec582aeL,0x553acd10017eb463L, + 0xfc521187fdfd820bL,0x73211103089b6829L,0x9d3fe7ad7e01e5c0L } }, + /* 37 << 259 */ + { { 0x12a8b7ac04c6babfL,0x7b23210557d2cf63L,0xe03831868f21ad0dL, + 0xd14c2b95acdc2184L,0xe7bd19fcadc9bae1L,0xe2dbabf2edea5c71L }, + { 0x009a3ab78f3f4266L,0x159691e17f8ff74fL,0x5ae666aa22f40f41L, + 0x72fcdc88512387bbL,0xa74e8fb841516c92L,0xd9cee7833b15bf07L } }, + /* 38 << 259 */ + { { 0x00a93daa177513bfL,0x2ef0b96f42ad79e1L,0x81f5aaf1a07129d9L, + 0xfc04b7ef923f2449L,0x855da79560cdb1b7L,0xb1eb5dabad5d61d4L }, + { 0xd2cef1ae353fd028L,0xc21d54399ee94847L,0x9ed552bb0380c1a8L, + 0xb156fe7a2bac328fL,0xbb7e01967213c6a4L,0x36002a331701ed5bL } }, + /* 39 << 259 */ + { { 0xd76b43661c8bd222L,0x041c2b87b97e5b19L,0x7b80f8d7b47c4282L, + 0xfec3d476d0dbc7d3L,0x84aa69712753a830L,0xe5f336079ec85e26L }, + { 0xa425d60cfe2374b3L,0xf88b90f14d953af2L,0x80370e7857ca6c43L, + 0xe07d07176f4d6d7eL,0xe60639401e61ab85L,0x171a2bf632a4c829L } }, + /* 40 << 259 */ + { { 0x38e4168d4f8b5073L,0xf1ddc53fc521849cL,0xd2bf515bab917df1L, + 0xab76b71a697d45c1L,0x20fdc6c7cb566a9dL,0x3843bf838a031cf4L }, + { 0x9a2d89a58a028b04L,0x52f3cb1922a908cdL,0xb5df9c2b7b8723baL, + 0x5142f51060374a3dL,0x949b719800bd9f30L,0x4b7cda16c9b86959L } }, + /* 41 << 259 */ + { { 0x22a32c50d154fc49L,0xe12242de66357eb7L,0x67571eb89f19ef9fL, + 0x2ed01f28b92b20e1L,0xd4fd6efb6cd439c0L,0xc4036cfc03b057fbL }, + { 0x605fab271cc48da5L,0x3cbd7a071416a3e7L,0x9cfe7161714bf173L, + 0xbd03d786a77eb0f8L,0x1423516678b8f5ccL,0xecc56e02f0523f3fL } }, + /* 42 << 259 */ + { { 0x20b1632addc9ef4dL,0x2a35ff4c272d082bL,0x30d39923f6cc9bd3L, + 0x6d879bc2e65c9d08L,0xce8274e16fa9983cL,0x652371e80eb7424fL }, + { 0x32b77503c5c35282L,0xd7306333c885a931L,0x8a16d71972955aa8L, + 0x5548f1637d51f882L,0xb311dc66baba59efL,0x773d54480db8f627L } }, + /* 43 << 259 */ + { { 0x2be2f1d67d64ddbbL,0x3afc2fad6edd7e04L,0x9a57c16d9e797442L, + 0x1efecfde9c16769bL,0x86523c3571b2940aL,0x1a9b30035825d17cL }, + { 0xa25e99beeefc4d7cL,0x8521b49fb50df9eaL,0x10bd2309bd8f3b06L, + 0x1f892e95ea82e80cL,0xf741621c93585741L,0x95687594f5e5087aL } }, + /* 44 << 259 */ + { { 0xbcdd3a3146f684c5L,0xbc8be436f700b0cdL,0x33005e370de75b7dL, + 0x527a8a2c3bd820caL,0x5e44854446997e4cL,0x40921fd93c3dafb0L }, + { 0xf3873a8ab7390d9bL,0x30999855495ba2fbL,0x005164f0813c8c76L, + 0x05bb04d7fe8da60cL,0xee7c38d503224ad1L,0x172018d615785ce5L } }, + /* 45 << 259 */ + { { 0xaaf786c0f6442534L,0x3f1344c1e56b44a5L,0x31199702ed073a36L, + 0x1f8ba0ec3df17e33L,0xf3e7b63493ceee0aL,0x568bdf39490fc4beL }, + { 0x364bdd11b1e1c439L,0xa1aa317ae5a63c82L,0xb12697034c02ee46L, + 0x0bc6d92e7eb64374L,0x87538fe740ed83f1L,0x862450abda74892aL } }, + /* 46 << 259 */ + { { 0x59b1b1347a62eb3bL,0x0f8ce157cceefb34L,0x3fe842a8a798cb2bL, + 0xd01bc6260bf4161dL,0x55ef6e554d016fdbL,0xcb561503b242b201L }, + { 0x076ebc73af4199c1L,0x39dedcbb697244f7L,0x9d184733040162bcL, + 0x902992c17f6b5fa6L,0xad1de754bb4952b5L,0x7acf1b93a121f6c8L } }, + /* 47 << 259 */ + { { 0x293ff71acc51318fL,0x69437a2e614149cfL,0xb12ea4613b48b348L, + 0x2f58020321f6cf90L,0x2e865f77178b53fbL,0xf4774d29231909a8L }, + { 0x0433e66bc4d8b703L,0x4fb6256b907097cfL,0x44a2a7fe004470f7L, + 0x7d3ebbb46dc5f10aL,0xe9b3af288f5526b4L,0x4bc0d9db1107bd75L } }, + /* 48 << 259 */ + { { 0x4865c0ffc0391d0bL,0x70d31470176740ffL,0xf44ca9a1ed506d00L, + 0xfaac86f6c981153aL,0x713ddaf4e3f86940L,0x64ec27093fc39de9L }, + { 0x04d413acac9a26b5L,0xde2052eebb21664bL,0xa6e04de8957b4f20L, + 0xd185b640d5487618L,0x1668b6a46fed1707L,0xeed37894c435ac3dL } }, + /* 49 << 259 */ + { { 0x1fa08a16f69cdfbbL,0xabba54dd0bf735a1L,0x37848c6a68a5cc20L, + 0x08e23c52a969298bL,0x48240306f965bddeL,0x48492deaf90bcff5L }, + { 0x416b9005bd994e22L,0xa6ce214ce6429f16L,0x5aaeec21f43f86d4L, + 0x202db9b7a0b1979fL,0xb2d97b4fdd7ae6d5L,0x4fedb6b9e12f04a1L } }, + /* 50 << 259 */ + { { 0x7a56867c325c9b9aL,0x1a143999f3dc3d6aL,0xce10959003f5bcb8L, + 0x034e9035d6eee5b7L,0x2afa81c8495df1bcL,0x5eab52dc08924d02L }, + { 0xee6aa014aa181904L,0xe62def09310ad621L,0x6c9792fcc7538a03L, + 0xa89d3e883e41d789L,0xd60fa11c9f94ae83L,0x5e16a8c2e0d6234aL } }, + /* 51 << 259 */ + { { 0x9c8e64869c85df60L,0xa84692a681e26100L,0x0350e1209c739462L, + 0xb6da4ebf99fa1f63L,0x857b534055e2bcd4L,0x7f4001dbdb209cf7L }, + { 0xbfa320378757800cL,0x2d56821fa6a562b5L,0xe56d810b6c3e775cL, + 0xeba244a6ba757f86L,0xb7ca8dbf80a17cb3L,0x8cbff4a22b7db57cL } }, + /* 52 << 259 */ + { { 0x650c31da9dff967dL,0xecd1e0f77ed949dbL,0xa7ff9becb20196fdL, + 0x5085c68d1e6259aaL,0x5759a166871a71e9L,0xba15e24c2b4d3bd2L }, + { 0x22c4f75912c51998L,0x6038fb0a7c8a9400L,0x64827d9c09625dacL, + 0xd8ce10c96ec4fb64L,0xe417ac30095686ccL,0x1e624aa88c723f44L } }, + /* 53 << 259 */ + { { 0x872d3dc953387fbaL,0xaaa0e1b4317ec17bL,0xa12b45519efb728cL, + 0x0b43907d45a3491eL,0xb7fa83befa4a239dL,0xbecdae00b59a4f3cL }, + { 0xe4e4c7c393407d23L,0x8278f336cf1d3cd8L,0x73dc9356610570a3L, + 0x5579653d688d933fL,0x208b96be5881d760L,0x4752a645d12f57bbL } }, + /* 54 << 259 */ + { { 0x87ec053da9242f3bL,0x99544637f0e03545L,0xea0633ff6b7019e9L, + 0x8cb8ae0768dddb5bL,0x892e7c841a811ac7L,0xc7ef19eb73664249L }, + { 0xd1b5819acd1489e3L,0xf9c80fb0de45d24aL,0x045c21a683bb7491L, + 0xa65325be73f7a47dL,0x08d09f0e9c394f0cL,0xe7fb21c6268d4f08L } }, + /* 55 << 259 */ + { { 0xe02aca87d4bba3cbL,0xd40ac486652fb181L,0xa1dcfe7ffaa3f999L, + 0x116323e0e9eded09L,0xaa3a0f0f07629d4fL,0x9f8e49f5e0dc53adL }, + { 0xbae96096742af22bL,0x6d7e24dd518862dbL,0x5c91ba30bb333cd7L, + 0xda8df051e65319b0L,0x2b9305ce9b3e43dbL,0xbf1d0e98fe783571L } }, + /* 56 << 259 */ + { { 0xf629fb233809aa31L,0xb3b66d77650bd2b8L,0xcb643126bd325d57L, + 0x29f46272ed41fa03L,0x374e734f406ef56cL,0xbb9ecd36da7428eeL }, + { 0x069694a61c06325aL,0x852b2912e40b9e8cL,0x6504bc90cc3d9695L, + 0xf1af43587e38707aL,0x552127dc239a0781L,0x0d1b3a6e8fe76173L } }, + /* 57 << 259 */ + { { 0x207e41f31d681018L,0x8883a6e417a7d540L,0xffc48332bc983c31L, + 0x729c4110c6b3de67L,0x5ef4680ad69a2499L,0x4544b58fe7afb2e7L }, + { 0xf5a2fb13480e063dL,0x8797357382054197L,0x5dd38cf7131d2df7L, + 0x635e91b8a9366742L,0xbd87a407e0d703c5L,0x6cc37be247251f16L } }, + /* 58 << 259 */ + { { 0xc4ccab956ca95c18L,0x563ffd56bc42e040L,0xfa3c64d8e701c604L, + 0xc88d4426b0abafeeL,0x1a353e5e8542e4c3L,0x9a2d8b7ced726186L }, + { 0xd61ce19042d097faL,0x6a63e280799a748bL,0x0f48d0633225486bL, + 0x848f8fe142a3c443L,0x2ccde2508493cef4L,0x5450a50845e77e7cL } }, + /* 59 << 259 */ + { { 0xaa129c0ddc428c57L,0xfe619b75aea19047L,0xd6287ecf12ea77aeL, + 0x4e6d070fdf7ce104L,0xd0df6788f097c79cL,0xd1c1f8a6ad8b1d07L }, + { 0x53eceba296519e66L,0x71670de3d6274109L,0xd2f21ea03f7a82b8L, + 0x41efbe939c8e45a5L,0xb5b153436ada3edfL,0x32ba22aca90038f8L } }, + /* 60 << 259 */ + { { 0xe1d195fad0cbe947L,0xd1fe0c4ef2ef1b72L,0x1451a0b206003fffL, + 0xda653fa08239341cL,0x5f834372f2508d75L,0xaeb245f507faeac3L }, + { 0x3eb3285b65fdf4ddL,0xfb335c0e84085970L,0x600ad6cae5efc0deL, + 0xc9c9f8910cf83e82L,0xf880ff84ad8cc14cL,0x54816725a016aae6L } }, + /* 61 << 259 */ + { { 0x22ce565ce1124375L,0x30ff1dc5edd968c9L,0x62d74c54e9148534L, + 0xf003f0d35de42774L,0xaf9448e6e57f8842L,0x55d5c9a3c5ff761bL }, + { 0x7da9398cc4c5edd8L,0x9643424e4ea0e099L,0x497eed480634fcb4L, + 0x09ffe2d07dea57cfL,0x30673ba73530a094L,0xfdbf8f24a251cff3L } }, + /* 62 << 259 */ + { { 0xd0f4e24803112816L,0xfcad9ddbccbe9e16L,0x177999bf5ae01ea0L, + 0xd20c78b9ce832dceL,0x3cc694fb50c8c646L,0x24d75968c93d4887L }, + { 0x9f06366a87bc08afL,0x59fab50e7fd0df2aL,0x5ffcc7f76c4cc234L, + 0x87198dd765f52d86L,0x5b9c94b0a855df04L,0xd8ba6c738a067ad7L } }, + /* 63 << 259 */ + { { 0xf9ae5fcedb877020L,0xd84ad42f703e5d09L,0xa6a5cc1fbfaed17eL, + 0x2099409829362fe9L,0x9f863bb0dd299c2dL,0x82bd3f61fa632197L }, + { 0xd3b14097ebe7ff51L,0x7c9e6ec4c719a6bcL,0xd3b46f3d70a51db6L, + 0xc8fa2f0692eb8243L,0x68e1f56e02155139L,0x0c35d135fd3b893dL } }, + /* 64 << 259 */ + { { 0xe76894c3ae7ce296L,0x87737ee2a6cafc34L,0x566dfcfbe55cd1e6L, + 0x5421a9f23a7ad5b9L,0xa005838a4687a4efL,0x3837219a23a2c423L }, + { 0x4b7800128a82cd1bL,0x401c07bec728b588L,0x2b5f69e937ced8f3L, + 0x306b621d8c1e1eaaL,0x8acbbe71d389cc4dL,0x922fa665f4ab7774L } }, + /* 0 << 266 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 266 */ + { { 0x2df6f242d35c2d80L,0xf65a99a93493ce97L,0x9e80232b372bcc87L, + 0x26ba13b86e428cc5L,0x2526ef1f13a1b763L,0xcef3edcddc97c5f3L }, + { 0x4954867fbde16b73L,0x9817813d368ff6cbL,0x7e39fa69be143027L, + 0x12329463cf54f28bL,0xcf0991dc7597c2daL,0x0cda396952e07099L } }, + /* 2 << 266 */ + { { 0x412f64a3f303955dL,0xe92bdca9bd692593L,0xfbe6cdc2c2e964e0L, + 0xe9a3b1fd0011cb01L,0x6c30762dcf228f23L,0x1270b84abe9199a1L }, + { 0x732711dfe3c9cbb1L,0xa3aabe37d91d9513L,0x8ee08ba0c6eceba7L, + 0xb1711531f3c3d31dL,0x65060b633c716948L,0x046b4ea12ff2caddL } }, + /* 3 << 266 */ + { { 0x25d1124fbab220c6L,0xcd1423c861524e3eL,0x75e4f45f0434fb51L, + 0xb5180a8f5180ab2bL,0x144e214e5b22e388L,0x6b16dad192263054L }, + { 0x3ea7590740863566L,0x372d5abddada3b46L,0xb3ff5a3a893d210fL, + 0x39f8d1ce5e29f3dcL,0x559186ce68200e82L,0xf48764541202cb66L } }, + /* 4 << 266 */ + { { 0x6f178dbf8b540904L,0x0264bccd8720472aL,0xa6e8b4b459b46611L, + 0xafce8267c72b4a58L,0x21142175a45985adL,0xd23401dfe649d733L }, + { 0x6bf42fe085dc7720L,0xc5c8ab9440e3f2f5L,0xb0c8a58acd029197L, + 0xa73ff329215492e1L,0x895c545eb1b5a5f0L,0x6dbc24456fcaf49bL } }, + /* 5 << 266 */ + { { 0x25ef32d60f2d76a3L,0x540650b9af4a7d46L,0x8979a4b8d991d7f4L, + 0xdaa706c299202400L,0x8a729680f19d281dL,0xde25bdc44ec44de2L }, + { 0x0fc50832c2054496L,0xfee72fb60aaf2941L,0xc8263e64b82ed4f0L, + 0x91a8cb736f49055cL,0xb7585458f2bb515cL,0x03d2b23ab855e6c6L } }, + /* 6 << 266 */ + { { 0x09ec1e3dcfd3f182L,0x1f1c30b5adae7af9L,0xf3a33f7c6b454164L, + 0x0318926f94647c4fL,0x8e37bdd787db14ecL,0x811cbd342ab364d3L }, + { 0x1dd1e5077c2b369dL,0x7a57bc46a28056bdL,0xfca5be4b089efe44L, + 0xb3bd84d76dc1290eL,0x40d7af098793e6aeL,0x4e08e11fa3723942L } }, + /* 7 << 266 */ + { { 0xca3709ad899ffebbL,0x1a87377877c00602L,0x5ff40c2aa99b4af0L, + 0x680464e5a80e870cL,0xd2f7f04494e10b1dL,0xee9b206c4e9aa1a7L }, + { 0xb536d67596cbe950L,0x841856899e8305f3L,0xae1b669c369fa255L, + 0x62e260267233e1eaL,0xac05c5136aa60c24L,0xdfc6814fd2691677L } }, + /* 8 << 266 */ + { { 0x8baef5df0a02b0fbL,0x58a2b06bc2b92b02L,0x268558d754c8267aL, + 0xf924f795ccf70393L,0xe3763f30f68ee021L,0xc1e856f05c01ba4bL }, + { 0xcc01a3e9722b6bffL,0xd2be4623ed5b3b02L,0x1ab3512e6c45e33fL, + 0xa978fe484ef433f6L,0x23e2ea018e21f5afL,0x49647d8811524a40L } }, + /* 9 << 266 */ + { { 0xd50abc94f5d3f437L,0xbf2ffcc546b7b738L,0x0bf53571f80edda5L, + 0x167908d4ab90ba5fL,0xad445b102303cf00L,0x9b537d4fb9e59406L }, + { 0xfac5e27cf43049a8L,0x05ccb32ebf9db100L,0xe662eeac4d1b535fL, + 0xbf21d6d78d27ca90L,0xb960bf652a684981L,0xe16bdaee49236475L } }, + /* 10 << 266 */ + { { 0x47a5958f92ad4720L,0x12c33193da3bf809L,0xf16493147da6d32cL, + 0x42eb4e687102deebL,0x0f8c4ce283088c86L,0xedf91c3bd693c9a2L }, + { 0x8a18a4761e8c310cL,0x5e8757c5dc3db0e8L,0xc48b820ef76a0affL, + 0x690d788d5c71e596L,0x2b0a00857cfe770dL,0x440ba06bd46505f0L } }, + /* 11 << 266 */ + { { 0x503f77906087d4d0L,0xc7243aeda1ebfb04L,0x203f0563ad8f14bdL, + 0xc20013b7cad73fcaL,0xbace8b323741a708L,0x0b376ff731bdeb56L }, + { 0x820b7f1282c22e57L,0x0c08133117830562L,0x306d178a8d0d30c2L, + 0x36a6efd1467a1510L,0x558fea1af55b7b97L,0x1e9152b784e546eeL } }, + /* 12 << 266 */ + { { 0x92a7fbcdac3ce531L,0xeb85f7f059498d99L,0x8e45db2d02a8feb5L, + 0x176c0cb2728cecbeL,0x33fcfbb0d1837662L,0x426e192dd6f2882cL }, + { 0x75a0f3450a2c9899L,0xd815dc6066148f9dL,0xf4ea90cefa0453afL, + 0x5108858ff54c96fbL,0x86b46b5731f77afcL,0x59df021f6bf7e2fcL } }, + /* 13 << 266 */ + { { 0x48d67f73dab6c0f4L,0x70cfc26cf0d49ef3L,0x25c95a68a65cce7bL, + 0x29a05632cf6ad228L,0xbcc2fb5a1a8128f5L,0x360d82a48c9defe0L }, + { 0x1c5c5d628d1531d8L,0x58fc4b9a149f6b4cL,0x8097cf56a3b625adL, + 0x8821ead7fd8e0e35L,0xb96c2b880d9e1df0L,0xfbf55ba72a243accL } }, + /* 14 << 266 */ + { { 0xef32e94d70e0d8fcL,0x33ec93dc6d63e65fL,0x134532fb1dc7156fL, + 0x98fb5b0c0e8d85b4L,0x05c28df9b64f7861L,0xa7e73afa4160e1a2L }, + { 0xbfe60a9b785f6e4bL,0xfcf998f12fec9ec5L,0xf673b8d15c12a44aL, + 0x85df3bc736d189a5L,0x4480a189dd83f6e0L,0x3216317ef3d3ab44L } }, + /* 15 << 266 */ + { { 0x221c1b7ffd3d7532L,0x40939c318bb4e719L,0x75182ce602f8f74eL, + 0xf508d6415395f9d8L,0x88fc89ea1fc81977L,0x861d8d0bcc8dc7d3L }, + { 0xd76e4f0cec07b0e2L,0xb0a4e2aa5819b99bL,0xa67bed0366a9c935L, + 0xce7c8241d2781f91L,0xe7c5c22512af0abdL,0xd1067dbcfde7de16L } }, + /* 16 << 266 */ + { { 0xe1d42d94d087b788L,0xfbfb221aba0e176aL,0x5f6698e783686966L, + 0xbb5e159474a30dbfL,0xef86bb5bcfd20230L,0xf055a1c5403b8f8bL }, + { 0xf249aac8d9d85ea7L,0x7318f7bc3d200198L,0x3b80960cefca9a90L, + 0xf28e33888f449c4bL,0x0cdfc61bf0cfe09eL,0x3b169c638b22cd26L } }, + /* 17 << 266 */ + { { 0xf4f13a49b81b45b0L,0xb77a67be3003fe1bL,0x70e648a318d52c97L, + 0x701ba8a1ee17ce93L,0x58a0ce0cf672226aL,0x2fcad147cebc3294L }, + { 0xf5cd118a104e8f68L,0x0015bc0bd15358e6L,0x75f0d28f1c662df4L, + 0xcd54f443a3e038f4L,0xa83507610804c717L,0x5fce0ce3f03bad08L } }, + /* 18 << 266 */ + { { 0x4c2e2bffa180a71cL,0x067f3e3baff551b9L,0x007610f1afa43e12L, + 0xe8a9ae79ef7b9a1cL,0xa558ef6cf9d3b397L,0x8d5229884f172f34L }, + { 0xafa906332d425e05L,0xc62c3914207b0bd8L,0xc84d197c059f7d66L, + 0x6cc1d8ce421a9172L,0x1d44a46929a7ebe3L,0x96ca4d0171c3c8b1L } }, + /* 19 << 266 */ + { { 0x31302e094d369fd6L,0x62fe210cf1b62d27L,0x496ac173bb37578cL, + 0xb4d3d065aa0907e0L,0x02317db27c822875L,0x60a01580f241ebc7L }, + { 0x81a5d5244e4f37d0L,0x5286f7289c3f2555L,0x14c8c7549a73ff08L, + 0xd8236689ff478877L,0xf62d426b08e09f00L,0x2ba1833c67a96517L } }, + /* 20 << 266 */ + { { 0x7013d596831f464aL,0xe57185fdd3cf6ca2L,0xbba7898e35915f51L, + 0x9fbe5f139fd967d4L,0x0aba8344d173558fL,0x4c0dd30dffeb6beaL }, + { 0x928f68cc5110e40fL,0x1589a327a58b6d60L,0x09b5c4e06abb0ac9L, + 0x01ef3f8a68957627L,0x55dbe9f79f4045a4L,0x91976aeeef178ac3L } }, + /* 21 << 266 */ + { { 0xd9c20a69b85e46d9L,0x1bda1163cdbda686L,0x5c0717f6c02427a9L, + 0x2a976c104d2a48afL,0xea276b15921a02e5L,0xf055b980ddb6315cL }, + { 0x0ab85663825f00efL,0x95377fd42053a392L,0xc51c245e23f463e8L, + 0xe1ae1e5da24c981fL,0xd6a0b44d9f5cfdbaL,0x1205754023c16002L } }, + /* 22 << 266 */ + { { 0xfe464ce116ac9150L,0xfd629551173ee9e8L,0xd0623ab1781696cfL, + 0x7a07cedd58529fa9L,0x831b4a9d449c33a0L,0xb7b7b72417b171a8L }, + { 0x0e1ff931f5a9aa41L,0xd43f33dfe356ba47L,0xd2abfc77f003b5d2L, + 0xc2909150882c0313L,0x83823f6c7ee111a6L,0x9d7a2d82f59cb72dL } }, + /* 23 << 266 */ + { { 0x52e712549b33f6fdL,0xd4d9b73f5c414babL,0x9834943177e93a9bL, + 0x848b53c99f283fc9L,0x86e48b6234c787efL,0x8b498e1cb3166045L }, + { 0xb2259559e5e456ddL,0x0316069fa2c2ca8cL,0x9a70e29ef6524ecfL, + 0x2477ffc9bfff600dL,0x80a9a5e081869e1cL,0x84f887e70a78f6a0L } }, + /* 24 << 266 */ + { { 0x7f89c2c40c9f23eaL,0x8fb025d4d6ec2b2aL,0xbe70e48b12d9f811L, + 0x703ac1bdc7a43dd0L,0xa4309a2c2118ca3aL,0x5a95d7b301943012L }, + { 0xd9597d87811f6c73L,0xf82e801596079992L,0xfcf8760df1561aa9L, + 0xe1e0306e2d91ee39L,0x99979031e0bbcb6dL,0x49259e54cfcc8746L } }, + /* 25 << 266 */ + { { 0x0de49373a38fb6dbL,0xda9e9036d6bf0a7dL,0xc99fe05fcba221c4L, + 0x45b51edd4cb730f8L,0x312670a3b064e142L,0x60dd1edecddb9ddeL }, + { 0x94be613b9291d75dL,0xbc49861ca00b9831L,0xccec7a08230320bdL, + 0xd1de7bd80ff967b1L,0x5a1164f105fda7e3L,0x864cfc4ce3004538L } }, + /* 26 << 266 */ + { { 0x06f76165385095a7L,0x3c73ac918514b2e0L,0x8ac1120a04b2dac0L, + 0xed6a74174382d5b3L,0x852a5a7864a32d50L,0x7ef5b84bbdc721acL }, + { 0x73dd18980480d271L,0x755b23e04ab0b11dL,0x2e78238982391e5aL, + 0x4957b5c948923446L,0x4ab9318f6921c1fdL,0x8e455abd3e46607bL } }, + /* 27 << 266 */ + { { 0x5c41aafbaf25d6b6L,0xe351f1df916b63f6L,0xe28e9ba98a6efd65L, + 0xcbca736356afe7b0L,0xa77d6077f7384e6aL,0xcc9ad74a738a90abL }, + { 0xe1071caa2333dc2cL,0x4415691000dfc2cbL,0x0ce43c16afd89eefL, + 0x0cfbb8767b812045L,0xe6da40fa6d916fc7L,0xe404b3436302af21L } }, + /* 28 << 266 */ + { { 0x4073f246d9915433L,0xc0149d5672e06203L,0x0abb06c18fcec6a1L, + 0x3a7d1295d75a73f1L,0x65fd8700f18c9488L,0xc3cc0b27732f7741L }, + { 0xd15d8c8025a261caL,0x518233510dc1fee5L,0x981607c7120e1266L, + 0x0e486b11f42cc9fdL,0xe606c16c01a888cfL,0x079dd0b31ea23249L } }, + /* 29 << 266 */ + { { 0x19c62d3c58624305L,0x44974c41b73eae15L,0x2df48b6dd023231aL, + 0x6a82c197c6fad2d0L,0x55758764c623fdceL,0x29f533fbadcebd90L }, + { 0xcfbe4155cfff7336L,0xb18415c7bfb609fcL,0xc23395ad8d411a6cL, + 0x25aebbcf0c92de60L,0xf4d3b1ebc5ccf268L,0x9646b4a79ac85de3L } }, + /* 30 << 266 */ + { { 0x0f423f3013d6cb61L,0x239b2baa66674aceL,0xa6f2ba39eda69340L, + 0xdbbd20eb43e6918cL,0xe6ce84a3e5e7248cL,0xd9184bb5e04c580cL }, + { 0xe4b76d96a0738aedL,0x98662b6090d480a8L,0xfb14bec72610b6c5L, + 0xdfcb01f6bb65837cL,0xd7f0b6ad4a97fb21L,0xe6d84f4bad59b2ceL } }, + /* 31 << 266 */ + { { 0xa79085eb1f7e921aL,0xe2737a08d0aeb41fL,0xa96d7e8169ead959L, + 0xbed1731b733b7c6aL,0x7768e32df508a48aL,0x6f73a08651ccc97aL }, + { 0xb7f94a4b9122db73L,0x1cd17ca257ec947eL,0x7c83fe278f8445f1L, + 0x661f5d82b520fe34L,0x495354942233d364L,0x0bf7abe663925ca2L } }, + /* 32 << 266 */ + { { 0x923e948c203bb368L,0x58e37a2b231a80e0L,0x345a011a6df27debL, + 0xba6784c1d57f4ca2L,0xf01b3703114196e9L,0x981a63eb1aab426dL }, + { 0x2ffdc97851770c1cL,0xddd19da6efa722fcL,0x5ca1c01216f09c1eL, + 0x612021de5b9cc0b6L,0x910e10e95e150569L,0xacace9dce2ab93eaL } }, + /* 33 << 266 */ + { { 0xf66601a7aae13423L,0x940bcd2882cf3308L,0x55de590974f632bdL, + 0xf677d9d4f183faeaL,0x54026b2828ab364cL,0x2a5353dc743469edL }, + { 0x15f02aadd46871d5L,0x4b3ec89b5a2100d1L,0xca85c3681eb9c381L, + 0x145cc7fd50e78466L,0x75fdac98c4b4cdf3L,0xb7cb9170796136f4L } }, + /* 34 << 266 */ + { { 0x6e89c0df54827957L,0xafb26b6d05805250L,0x0c0dc4ea37343465L, + 0x2d3c8b873daca876L,0x733b23d9554a2cd8L,0xd4f2936a6a04d38dL }, + { 0x0937611686f90d9aL,0xcd854d3211425591L,0xbaf9d4cab55b4bf3L, + 0x47259b95144676c2L,0x765cc4b55d7d2835L,0x36e47a8882b2cbafL } }, + /* 35 << 266 */ + { { 0x2070db373af8c96dL,0x4c2db2623b70e976L,0x7ed4d1e9c01f404aL, + 0x04a52764b39d2e07L,0x06e4a7984ebe3ac3L,0x35c9c1f68d7645a7L }, + { 0x2e0b48c75e9c295dL,0x5d44fafaf78e0717L,0x2fc27eba04213067L, + 0x9f3fb2ff2ab0f0e6L,0x374b32fd0c730af6L,0x06ec846129583945L } }, + /* 36 << 266 */ + { { 0x583a3272230be37eL,0x4d3298951c55f593L,0x3b3a2d8a350f0334L, + 0xec830170b25498abL,0xd65847d9b3a01571L,0x4605e739663f86fcL }, + { 0x971b8e115c4bf502L,0x651d179571a892b0L,0x57930832d2d1a4f9L, + 0xf97010745b09a4c4L,0x76b023e55ec2d1a6L,0x8648b8bcf49e1329L } }, + /* 37 << 266 */ + { { 0xc5a8884d6d5c7411L,0xad32aa97d098e2f2L,0xf99569e945d8ad00L, + 0x35801c1c0a232776L,0xe426fd65fb1a2cb2L,0x874b559ecb26ae10L }, + { 0xfa67c2ddf44461b8L,0xc58f8d229418e17cL,0x5998197169908eddL, + 0x8a4a14b8a1f78300L,0x4814c36e61f7fbc5L,0x0389dcc716a1c7adL } }, + /* 38 << 266 */ + { { 0x777e308fc072cf71L,0x4a2d66928c807ed5L,0xa4fe074124842689L, + 0xa3c2a867151ed7b1L,0x52ef24f24d22ee35L,0xe684ac76499053ddL }, + { 0x0b7c223b0582cb86L,0xa6c18539bb81f713L,0xb472da7f66d2aab9L, + 0x3592ab7b7916d4e5L,0xed651a05770c49a1L,0x7b879da1c0256420L } }, + /* 39 << 266 */ + { { 0x82eeaa1496f83e29L,0x586f3e8de5cae8eaL,0xb671eddbb298eb5aL, + 0x41efea86dd0da080L,0xfe9af019564a382eL,0xb2f370463027693bL }, + { 0x65466e5018789c0fL,0x5b0870ac2ebfe89eL,0x9093f416a59f3a53L, + 0xab0cd17251864c77L,0x8e3aa9864481457bL,0x46cfd207896346a5L } }, + /* 40 << 266 */ + { { 0x473bdac887cb6ae0L,0xbd3001b3f155c32bL,0x109643c20026e8a5L, + 0xc4f5f6cc188a568eL,0x630aecf64d2758e0L,0x4549949955b91872L }, + { 0xb10f19d4b6a09df6L,0xc537a4bb37f26d01L,0xd29f505c4d19a293L, + 0xf388a5d2cbb09b17L,0x462efffc6811a49bL,0x8a1cbc40b2f3aef2L } }, + /* 41 << 266 */ + { { 0xf7d94342b7b42998L,0xcdfd6e43629089abL,0x622e8d3cf7932661L, + 0x4818adca0b14b257L,0xcc1dcd1ccdb486bbL,0x58b6cb7ecce8b358L }, + { 0xca36c0b4e640cebeL,0xcc5598942d25f742L,0xdf4f2a9ed754d3eaL, + 0x072eb5e5f44a8604L,0xfa7b1a03cd5ca1c5L,0x6b6b4967d4779eceL } }, + /* 42 << 266 */ + { { 0x0f0233df8665f6f2L,0x8cd887463bd40f39L,0x23a41596eedf8d3aL, + 0x3f50e3f0b5ef5455L,0x935b24e0a50cd358L,0xfdd0e940d362a9a7L }, + { 0x6b00a6d154371aabL,0x2e707c4e1204bcf8L,0xb4d2d2dc30233f88L, + 0x470c3201783e58efL,0xf53987865ac21a16L,0x278487d626c3513eL } }, + /* 43 << 266 */ + { { 0xab5ac4df7d40427aL,0x0c4fb23b66ebdcedL,0xb02f8632b87df612L, + 0xebbd2e7f1801700cL,0xdd11de725b675e5bL,0x2adfb20662d7210fL }, + { 0xe3ba7c0e28667b70L,0x3e190a438fe31c22L,0x57908f2bc3390733L, + 0xe9e8714ccb6fefbbL,0xabba506dfd51c513L,0xd50f979f6b798860L } }, + /* 44 << 266 */ + { { 0xdf224cea1eed2b0bL,0x10205f438814572bL,0x8b99d85c02eb9b6cL, + 0x7a8a3d146c63a672L,0xc8822c6c96f45695L,0x0530f619c7f532f5L }, + { 0xb981e182310f8355L,0x49318290f201444cL,0xeaa4c406f9b76d19L, + 0x960fa2c7534a91c1L,0xf98966d1522b7d9dL,0x66912542c757dbd6L } }, + /* 45 << 266 */ + { { 0xe265972e1fe73a1aL,0x77e234c2987a1a34L,0x1814bdfe8c5789c0L, + 0x908f55c7df2ca0d7L,0xec207eb2a6a50ceeL,0x63cfeaffee916760L }, + { 0x808a758bf466a1b8L,0x2a48112d8383b0afL,0x5238922ef1a4ca6aL, + 0x5c422786778de666L,0xf5a8c6b5d2f549ecL,0xcac5d0c5242bbc9bL } }, + /* 46 << 266 */ + { { 0x33e0e005b34dbf06L,0x7bbdbe1e1fb341dbL,0x443fde882bab5425L, + 0x9db5bf1a86b57cdfL,0x72c535c309a93848L,0xf7aa9432b5f216ceL }, + { 0xc17dc7ae0242308dL,0xf1cb5dc5db0e4c0cL,0xb9d16d58a2b7112eL, + 0x486cda07ee4494b5L,0xeb46ab545d431adbL,0x3261dc5181ab565aL } }, + /* 47 << 266 */ + { { 0x476a4bfaa2a8a081L,0x43c5f841394f851bL,0x659baa591f5b22ddL, + 0x49a786aa65f680efL,0x091bd21608fcb9d8L,0x13f6953d984fe1f1L }, + { 0x7b5d9f4b6d6d40a3L,0x2f135dcf0d458d54L,0x2da18c3d3a71204aL, + 0x3d93edb97a3486d6L,0x026fec7261846af9L,0xa62197bcd5200dcdL } }, + /* 48 << 266 */ + { { 0x0cdd83725070e0a9L,0x7c5ad562ec550783L,0x9652b8474f3b8d2bL, + 0xfdd60d93e6e98d73L,0xd51cae2ca3479d0bL,0x11b93b6dee05c006L }, + { 0x9d72b82d8a3b40d5L,0xc6e996fea7d24855L,0x420672f7398603deL, + 0xd551b34a9a1af2ceL,0xdeb8c1d913bdce0cL,0x56ca926debbeba7aL } }, + /* 49 << 266 */ + { { 0xf63ec096bb85ca8aL,0xc149664173bc52f2L,0xba792560c02fc808L, + 0x9a6043e3533c6523L,0xa9d78f0aa8564390L,0x7fef67e494614bc7L }, + { 0xb4091b8fd389234dL,0x5913368e82db1d08L,0x178f7df0981cc6caL, + 0x19b1f2be725ec048L,0x852aad85012f9c44L,0xb07cac0dc894e777L } }, + /* 50 << 266 */ + { { 0x1c1709d02c7e0767L,0xec1013234d70b117L,0x95c57e678beb8e05L, + 0xdbf29e2e1133fa4aL,0x917f4a6c5139e020L,0xcf0be5098399735dL }, + { 0x83014c169c878b4aL,0xe0c14d2cf789b84fL,0x222aba39165a4aafL, + 0xe135f2b384441391L,0xb6f1cf7e19c3ee07L,0x2f918da9f810499eL } }, + /* 51 << 266 */ + { { 0x026ee35816bb2bddL,0x8c8953f8566d8470L,0xf0cd746d0fc63932L, + 0xddf3e54f060a07a3L,0x8da877a643b4e92dL,0x7ffd839dfdc9e34aL }, + { 0x5c3527445df04d9aL,0x3c5eb576b69f84e0L,0xf73cae300848d993L, + 0x3438f2bea0fe7fdbL,0xd4e7511f0eaf0168L,0xa7ffd167c768386aL } }, + /* 52 << 266 */ + { { 0xbb91877acfc74bb0L,0xbe742182a060a71eL,0x116e5a626ed7786cL, + 0x0a496b1bea669e56L,0x3a012174b8f02e6eL,0x6add760c106174f4L }, + { 0xaf2606e05e0292cbL,0x7800a495c7b7bad0L,0xca02c9320a1c5954L, + 0x904f23c6b245ad57L,0x28d6cc2172934de5L,0xbb7ed903283752cdL } }, + /* 53 << 266 */ + { { 0xc80288125e58122dL,0x7a5c65f1c4b089caL,0x4ddfd3663b980faaL, + 0xe8129f7f96a909a0L,0xc177aa042221ffacL,0xaf444ef78ff46e81L }, + { 0xa627f3d76b154996L,0x0f06fa7b115e2a5dL,0x2532b85d43fdb775L, + 0xb6d96b32eaacfb58L,0x898766304f834382L,0xfd2ffde9d5636b92L } }, + /* 54 << 266 */ + { { 0x318cf974973757d0L,0x12882d0a94ac73a2L,0x1fb74a53bc250843L, + 0xc612569eccd8d47dL,0x74cff8789d5f7c8cL,0x54e0e475375a7366L }, + { 0xe8322d23d0f57cd4L,0xb6ec5666d95a6e0fL,0xc8374b254a4bd084L, + 0x9459181b349d93ebL,0x7011f0a61368b9a8L,0xed57a19137eb2833L } }, + /* 55 << 266 */ + { { 0xd245d180fa5f79acL,0x44c331f35b41fcb3L,0x13188b6e27ee6c0eL, + 0x54ce984b23fdc742L,0x66d4e1303c81c213L,0x432174030ecb6fd8L }, + { 0xbbeb09fe111ae08bL,0xb22ca6b42e2df05cL,0x0e9d01dd0fec9be9L, + 0x9ac4523dfd2fc4abL,0x3d9e98c8fdc059f5L,0xd52e6dfb2d2cbde7L } }, + /* 56 << 266 */ + { { 0x80d7ef8598100f17L,0xb9795c7112db3f3aL,0x44473659296a7c44L, + 0xa46810f21e5bf539L,0x5621241814ee1e3bL,0xea8284e209931822L }, + { 0x424c613e42ac1e42L,0xe84a80afbccf9466L,0x21a8cdcc45132204L, + 0x9505a4148d58da62L,0x773e09837b3f47aaL,0x0ad0cc91e109bc6dL } }, + /* 57 << 266 */ + { { 0x98e2509bb527b250L,0x2dd30c824a9c762bL,0x54025da4cb2a00a2L, + 0x88ed00ff04d8e0e9L,0x5699890219ab1fadL,0x92fffc41697b0226L }, + { 0xb481d1ee7d08a39bL,0xea773f7f82be0803L,0x967e848a6de8ec6dL, + 0x6ea1e46380293472L,0x941cded72e988de3L,0x85f96b23399da6b5L } }, + /* 58 << 266 */ + { { 0xabd86572f1a62473L,0x9ec25d0bec274738L,0xd27d1a8c2052d4ccL, + 0x1f2a2a9ba95de3f0L,0xe3b8652ea2c91bcaL,0x1a4f6900822175deL }, + { 0xd9405d4662475a44L,0x4ecbe06cfe55c587L,0x30f8d199a4ac2f35L, + 0x2a5defd8d3c12844L,0x6d0fd9d673fe9b7eL,0xb0ae1019adf1a196L } }, + /* 59 << 266 */ + { { 0x6c9a378c30734f5eL,0xdf04359f6aaf7b42L,0x244422fc16f87409L, + 0x81dfb15b08bcd67cL,0x24b7d083a5e4a8e0L,0x557183410431786fL }, + { 0xc8feeb8c33f3ec2eL,0x360098cb2be371a0L,0xf4f3d992bdb874ceL, + 0x47b432ed87af8471L,0x5c4b1dbdf87535deL,0x6bb6d6dd8301f660L } }, + /* 60 << 266 */ + { { 0xafa9338759769f77L,0xe6c710cb49e502b3L,0xe6fd7b8d1514da98L, + 0xb5924c63aedf93caL,0x4cc36795c112b37bL,0x0ee30ce3231def42L }, + { 0xe1f436e7daf8a37eL,0xed54b7f56efa184aL,0x09ad65752c0dfe63L, + 0x5ed9da43ca530b38L,0xea2fa192ae156274L,0xbf096c54a4429edaL } }, + /* 61 << 266 */ + { { 0x41401b98f54490cfL,0x361a24a143b21183L,0xf0176431b6570f0cL, + 0x851bfe9d05c8bd3aL,0xe44f4ba74611e1b9L,0x587677dc28bf2c27L }, + { 0x3e3b67886d85341fL,0xad65a69468aa381bL,0xd269dc711aecf19bL, + 0xb94b64a2d98e6a2cL,0x6004b569a94661a0L,0x81713a8e689181d5L } }, + /* 62 << 266 */ + { { 0x55b1901d3649638eL,0x2e9929c416abaf64L,0x2d2b160ee9cd0090L, + 0xb5ef6525f55f13ccL,0x447aacbe11c3e8a5L,0x2c54e602630cf4c4L }, + { 0x3f6d99fc641d8eb3L,0x35386c1384877912L,0x7195db8973f31b6fL, + 0x63297cb2d3a22085L,0xa627593833fe97cbL,0x2f9a6f0da1eaef0aL } }, + /* 63 << 266 */ + { { 0xb70d7683c63d6dd3L,0x60ea781084acedf1L,0x7646260c40d62cd0L, + 0x687000b456142a6aL,0xce3c4728ccb9177bL,0x45377d059928c509L }, + { 0x75cc40bb1a78af0dL,0x43a1661cc69e59fdL,0xf9bbcbf8044a943cL, + 0x934fd40d7c372080L,0xb6edae96cb2eb940L,0xa02bb5fd6e063cc9L } }, + /* 64 << 266 */ + { { 0xac58c9e09db9ca19L,0xd308ea5d390054d0L,0x32ef4afc2cc42529L, + 0x08bd48b397c2bdf9L,0xac8a7803a849e19aL,0xcd51c0da75c31496L }, + { 0x733dc7def0e2d49fL,0x7c9caad1b44b8cc5L,0x6d9c5b0847be21a8L, + 0xfab0fdc55ebf426fL,0xd60748caf94e9e5bL,0x3072e59269366089L } }, + /* 0 << 273 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 273 */ + { { 0xb06c17a3f0ef77c5L,0xc144e7846df6bf59L,0x2440ae990038aeb2L, + 0x83bf711b58b402caL,0xb8763e00b577732aL,0x509e91eff651a932L }, + { 0xbe02ab9d00ac109eL,0xfbcb426c8dfd78f1L,0x7ed272f64283f80fL, + 0x098cf0572365da5eL,0xd90e6f1805dc6bebL,0x09ef177fcf7b9d72L } }, + /* 2 << 273 */ + { { 0x6f101762eeb791c4L,0x0d942184df261effL,0x2c58e2aaac1dc827L, + 0x51410e89f835a1b6L,0x981333a7629915a4L,0x371891b60c14148dL }, + { 0x4d20b3d3c0904446L,0xdda7ecc8949776d8L,0xa664b68c2a2645f7L, + 0x7a6bc857add082eaL,0xe7467dc63e5ff206L,0x40a6c34004e2dfccL } }, + /* 3 << 273 */ + { { 0x3d0efae3106ba1a1L,0x9c717ca192d7be5aL,0xa5cb5a253f00eeeeL, + 0xc2f9258cd86161ceL,0xd2b0865f5c4a389aL,0x8c06d7689b1f2159L }, + { 0x5a758a612753107fL,0x5ab6449d0a539c19L,0x88655a4949d301c8L, + 0x129647e61c4bb89bL,0x06f0665ec360259cL,0xcdba2f0b066197d1L } }, + /* 4 << 273 */ + { { 0xa235456903744726L,0xd2169e6dd8d275acL,0xab0c247b132c5689L, + 0x129a5c9dcc4760bbL,0x03eba46726ae821bL,0x67a33fda3df1cf83L }, + { 0x010813cfb8421b7aL,0x7b0f507098cd6d76L,0x907320b31fe4b600L, + 0xda3bfeb398dd3239L,0x23f1ed1641abb34cL,0x01b30f29946f85f1L } }, + /* 5 << 273 */ + { { 0x97c5f1c7d3970d9fL,0xd051c518ac8e6227L,0x3f67b3958e87edacL, + 0x3a5cbd287b9e4c17L,0x58c009e65671841dL,0x7bc5bddb518b3b39L }, + { 0xe7a8a6335e74a614L,0xf92e4c226ed89a92L,0xd0d6e80a118e663dL, + 0x33dba4f9dcbb4aecL,0x1d4cb3141f917417L,0xd8b17bfa3b0c5859L } }, + /* 6 << 273 */ + { { 0xc0fa0d21a093c3e0L,0xad34c41439e902a2L,0x81c8cd7599bc928bL, + 0xf7f8be14cdbbe4d8L,0xe46268b5c2339529L,0xcdc54e348283ba7dL }, + { 0x4c5cf62778904fe1L,0x056678c11b45e4d2L,0xb555ad6ad265abc2L, + 0xb8f8ca3f830306efL,0x48c8764681c20e1dL,0x5bb0a529737a7944L } }, + /* 7 << 273 */ + { { 0xbd4c2bfc9cf6fc5fL,0x888885140577af66L,0xb5aa2f05f9e3f7c5L, + 0xbd477bae64de6007L,0x1da5dcc9747e1224L,0xc2293d1732a15f5dL }, + { 0x4dd9daed029d6cbaL,0xf51362d62cf299c7L,0xe1a4b5c4279cd1e1L, + 0x4b129a5ea89acfffL,0x8292228ece1c8744L,0x5a440fa04fd12c86L } }, + /* 8 << 273 */ + { { 0x285248309666f8eaL,0xd579b3dfeff6502bL,0x3a66fa9900e4f78aL, + 0xfd8a65bb54a3f7a3L,0x505d3f631965a79aL,0x9524972c1891469aL }, + { 0x78367cbc3354da3aL,0xbfe1fe3de4941c6eL,0xe41bb3f6f5af173eL, + 0x57cb03ca5ca36597L,0x27f86cb87b99f795L,0x5cae6514ad4dcef1L } }, + /* 9 << 273 */ + { { 0x4b43f0aef1743346L,0x1700581944324c46L,0x86c77197e3603fcaL, + 0x230d516f4a6858aaL,0xee965b4ee7c56f7fL,0x4f4ed301dcefb75aL }, + { 0x610b138c4a740b23L,0xda3996a83ffc3599L,0x930698fcb2d1c304L, + 0xd55bdcd3702bf80dL,0xdf767c419e334726L,0x975352a9d0e819b6L } }, + /* 10 << 273 */ + { { 0xc117353b5e816653L,0x0c87bebe820641d5L,0xee588c6d9ecd29a1L, + 0xacdfe622c70edf9bL,0xe8b8024cebae414bL,0xd0c426dc9bd7ceccL }, + { 0x715cbc2efe735ce7L,0x8376edebc5e7017aL,0xe9b37efc07990dd5L, + 0xc89e384ed8d75238L,0xbc594d218438ffb3L,0xbe77e4d4d3628473L } }, + /* 11 << 273 */ + { { 0xc53720cdd1b4f3baL,0xb8ac3b4fadf2a330L,0xcef037f5fe179e70L, + 0x2743b382589d9147L,0x77a094d624423d58L,0x9e34c2e62a23d372L }, + { 0x641ea760983a5893L,0x2211e6a49a81548eL,0x56578a1a48735310L, + 0xedb91e03a57faa83L,0x4e14d5649b133629L,0x341f3ef957e82ff7L } }, + /* 12 << 273 */ + { { 0x4952a350d87a86c9L,0x08ed7da7034f45f9L,0x1e9ff8272bd716d0L, + 0x2471fd15f1d9331fL,0x0c708362d7370b75L,0xaddedde6fc1a1051L }, + { 0xf4475288db27b186L,0x5be4d46b3760bc11L,0xe44435d906d47ee1L, + 0x865cf7c8d0b7c8a2L,0xdb412be08d31a252L,0x4b90a9322f24d71cL } }, + /* 13 << 273 */ + { { 0x71b84eed8f7a3ab9L,0xf41d7edb2dc18004L,0xe408156dcc4a02cfL, + 0x0be155a25cd906caL,0xbf4b0f6991516399L,0x2ea85d434a7ff94dL }, + { 0xf199b31da26e9974L,0xc584df250b805ae3L,0xd4e7e8597a3634daL, + 0xf553f07770db4be9L,0x1cb1056fbf0dafa3L,0x235281b2a817d6edL } }, + /* 14 << 273 */ + { { 0xc3304e9260d2b80bL,0xab24dac9a38753bdL,0x40373d04cc1ebbf8L, + 0xa5a162d3437e68d2L,0xc8018b1257e8db12L,0x0c99c6de9bb52643L }, + { 0xafef0ff6ee24e63bL,0x329c46264bea9a14L,0x1b17d2e6effae4f9L, + 0xd25b93aaee300afdL,0xe83bfdcba0d62da4L,0x5e919538fd787740L } }, + /* 15 << 273 */ + { { 0xf5bbb4fe196c38e7L,0xe0011deca5c75baaL,0x2e29fe59b835aa49L, + 0xee22e2864230f17fL,0x8774214ff94c1060L,0x35bcca38e6d4c126L }, + { 0x18d984dbb7c9d255L,0xb1d5515c9b63dc4fL,0x425360f12a0cb854L, + 0x038c7f2317a1e286L,0x5e6b12ce951f18b2L,0xabfbde5ea65b1de3L } }, + /* 16 << 273 */ + { { 0x38a49bf555f0ad9fL,0x1a84c6b8f3618639L,0x5f709eca01b2f7c2L, + 0xc479a6505be8359fL,0x6b6a22bfd6646b3fL,0xcce78878cc5b711bL }, + { 0x8e7dbc63b446cc63L,0x231bd027218f800fL,0x2d3a7e04030271ebL, + 0xb08b5978e22fb3c7L,0x860d62789be0d46cL,0x253a31c21d49a915L } }, + /* 17 << 273 */ + { { 0xab4dbdf36ebc28e5L,0x56d5fec527be58b5L,0x6e9375d3cf3fd509L, + 0xfffea897ca4ddf48L,0x0a9542ae6a3757c5L,0xb9069a2e7d93911dL }, + { 0x3e74ac5f3dc967b8L,0x99c38796ea8f5a21L,0x27797b97a6ddea53L, + 0x9501e1c561dfcc1bL,0x568d3abe448e95c5L,0x021f8f4c0e7c186bL } }, + /* 18 << 273 */ + { { 0x98aa1f7a6e44f63dL,0x6451b170cb597ec9L,0xc0f6ee8721e13b78L, + 0x36c3b9c751cfd003L,0xc31718ed2f610040L,0xdddabc6688c48009L }, + { 0x5626f090a8369e4fL,0x0eccb1c06004a968L,0x2f0448035da2f1a4L, + 0x5390b6dd3846a726L,0x5c4caffea24f3083L,0x3c9baac8c4842995L } }, + /* 19 << 273 */ + { { 0x58c5fd1205c7a75dL,0xa98007fd10866935L,0x91369e874acd567eL, + 0xb7e05dc322c6145aL,0x24c949b4d949d8b2L,0xc5c574a590a6a437L }, + { 0x4306f0334798d1d5L,0x82af09f4520e01b3L,0x53fab41b81247f00L, + 0x3096ccf44ea93cbfL,0x9665e039f13ff09eL,0xb623f8b158e036d9L } }, + /* 20 << 273 */ + { { 0xbad6b669376bdc3fL,0xc4a8e7bc23a9ff38L,0x3f54d8c4555fb0a3L, + 0xfb3d5e1d2b23db1bL,0x6379f78af0d7eba9L,0x36004febfa0beffaL }, + { 0xdf0a373c334ff01aL,0x10314749dff12a1cL,0x1d52ddc7f184c1b3L, + 0x79431663ab02d404L,0x1a6488c17f4d3795L,0x3363660f7cca9102L } }, + /* 21 << 273 */ + { { 0x1e4595c6db3e57d9L,0x49e3d3d9bfb94ec5L,0x4c720de1a4f12881L, + 0x91a08340b06c64e6L,0x8e5c72f0ef0857deL,0x2c9b4cbc09bb76fcL }, + { 0xd4262fe4b0bba8bfL,0x64c5fa1439fcd07bL,0x518da4de62904ceeL, + 0x626182ebae4c9717L,0x900fe9f806351622L,0xf74aaa2241f9e4d7L } }, + /* 22 << 273 */ + { { 0x9d2c02839fabb29bL,0xb27ac46e172348cfL,0xddc6fb63de1f64b2L, + 0x532dc953bb097c87L,0xc7f5180cdaa34e27L,0xf96e4ad755438893L }, + { 0xc0b2eba324f54a0bL,0xeba396ce5b50d12eL,0x80b3a7f699772783L, + 0xe2fa82ff3ff7df4aL,0x55375369a2359baaL,0xa28388ed856c05bbL } }, + /* 23 << 273 */ + { { 0x4432fe8495a2d064L,0x4c6380747fec6057L,0xc33705bb33cfb533L, + 0x5e7fb7c976991cfeL,0x73d249bdb3ac1b6eL,0x963964c896aeddccL }, + { 0x8c1abe0e56b71636L,0x6ebb841f38693cd1L,0x00ef6a7b60e7cf67L, + 0x29ecded2c258bcb9L,0xb2d566a5e40fd26aL,0xa2910f4ed512abffL } }, + /* 24 << 273 */ + { { 0x56d6515604dc109cL,0xcd740cc809c1d307L,0xef9e049f10dfaeadL, + 0x19750b3ae30b70b8L,0x11ed860015c6a562L,0x53bdf97e12097026L }, + { 0x79559d056c0d908fL,0x8f1d75bab506d527L,0xd6fd7323ae8fb3c4L, + 0x834639c9a4111f88L,0xfc69a029a310a683L,0xa4467bbb255f2e9aL } }, + /* 25 << 273 */ + { { 0xa809a063e9e3953fL,0x09242dc960dc53fdL,0xa48f52d00080c436L, + 0x762a585dad2eb70dL,0xc6d52f047a3c6aa2L,0x1b6979dcbe60899cL }, + { 0x7a07af246d760794L,0xa5b1f912ef5c1118L,0x36367e4375bb329eL, + 0x594f349029e6bddbL,0x13cdc4aaa4a4f1edL,0xa7c3ff97b687a69dL } }, + /* 26 << 273 */ + { { 0x1e79881146f7c4c0L,0x25730855946abf8eL,0x1741fdeeaac2031eL, + 0xef34715b72ea60b6L,0x378eb680350ddcfbL,0xe72ac880ec237141L }, + { 0xb173251fff125bf8L,0x37ffb0cf4999b6daL,0x9eeb91a8817779f6L, + 0xa9edff0ae93ed1f3L,0x31f2ca241d7772d6L,0xd25c3f3b97f67b92L } }, + /* 27 << 273 */ + { { 0xb6c4144381478e46L,0x7b53d46350cf8795L,0xe96e7cb9ca5bf2d2L, + 0xc8fa39c695ac9ba6L,0x8ab037d12efc83d1L,0x0ccacbcc94bc2536L }, + { 0x45e7c7c774038e13L,0x47d5b7292f5e344eL,0x2e0ffb2cb1eed282L, + 0xfe88d3a88d5d0b37L,0x804b612e2487d971L,0x6f316d66c95d08faL } }, + /* 28 << 273 */ + { { 0x5f0a58a8a3526fecL,0x849c171b02f028c1L,0x34d77ce856a5d3b5L, + 0x9701621754d5a92bL,0x0cce35c12cc5b70bL,0xd9d5a00ae83f1f4aL }, + { 0x064223f826a0368bL,0x328a9f6940e16452L,0x3a6ac093d305ad2cL, + 0x759d9a16beba7c44L,0x86021de7637ce7c8L,0x276bed61cc80c1ccL } }, + /* 29 << 273 */ + { { 0x5d4a529ef9822e60L,0xc6f2702006edd801L,0xb2511d84efa3d8d6L, + 0x38cfba656a4c6598L,0x31a5779765c067a9L,0xcee558f387d2ca0aL }, + { 0xf22345cff844260aL,0x29b6352a63d2ae75L,0x59dad0ab6cc9f2bdL, + 0x615ad3599ae1bcb3L,0x3a29a237f692f42bL,0x543771c40f26163aL } }, + /* 30 << 273 */ + { { 0x427437e7d722576cL,0xc9d7ac7abb548ef5L,0x72f00f28c331a9e0L, + 0x5d9327b564949b48L,0xea75f3b54e2bb808L,0x28acdea068678f8bL }, + { 0xe9e787b20878223fL,0x213f47ff7e7b0a11L,0x5e967d39f277a3f7L, + 0xe6651015d2006de4L,0x49b87e4bc44eb1e0L,0xf461bb76222cd3a2L } }, + /* 31 << 273 */ + { { 0xd6b9341fde60d963L,0xb1a8dd0d5319a930L,0xc4f18dc0aa6b20b5L, + 0x787de2e7f23f4401L,0xc15b38eb28047029L,0x0bffc0b55c99d51aL }, + { 0xf0310f39740b5798L,0xf69ea1064ed8d3bfL,0x545a54d79f6722aaL, + 0xe5a9dee3af4017c2L,0x45efa2ec4a659592L,0xc5d64bedbed4e245L } }, + /* 32 << 273 */ + { { 0x66797f56bbe4bddaL,0xb92a369eda51b1a2L,0x18eef4a531adb034L, + 0xcf1cb5ee5d185cfcL,0xf596a59bbd53c27bL,0x1e1dd6f569002569L }, + { 0xd9433e797687e48aL,0x7d8d24c20cbcb9ceL,0x233cd7ed65d68ecdL, + 0x201bbe09fb2aded8L,0x987f4975ac9b750eL,0x949da385337f7f25L } }, + /* 33 << 273 */ + { { 0x31439e35b95fd11dL,0xf97e8fa4b691fb77L,0xcfdc02956d4ac378L, + 0xd31bc3b0d1a617c8L,0xd857098204bd015bL,0x30cca6efd6198f0dL }, + { 0x6a52650a805964edL,0xb656d7abd060eeb3L,0x5267f37ed38a9218L, + 0x5f28a2ecd3d6a193L,0xb7dc6e916d0d9c9eL,0xa7f84e4b219d45c6L } }, + /* 34 << 273 */ + { { 0x550ef2713398c3dfL,0xfe184954307631a8L,0x02cef50606e5cde4L, + 0x9687a39c10f11703L,0x02c35937acb10b97L,0x835b00fd13e3d219L }, + { 0x5828678b584d1abaL,0xbe55fb9cc9b40568L,0xe5a4a90e8fe19e84L, + 0x91e24c9248989b77L,0x094f9e7ae3d5f4fcL,0xfe9bdfb9759029b5L } }, + /* 35 << 273 */ + { { 0x43b1f8b9c1de72e9L,0xcbc8e0d4a3bdb164L,0x5c45d3dfbcc2e5bdL, + 0xb5137b69247bef53L,0x6d889f5673794e3cL,0x43e2fc9b1e2dfdc1L }, + { 0xda15dc5da995d3adL,0xa0db9f5ec43d86e0L,0xc42a144bcaac3bbfL, + 0x3c855fb174c43eddL,0x0731f33152688272L,0xc1f23e5643d7762aL } }, + /* 36 << 273 */ + { { 0x00c2ee1c9c7de99fL,0x28a7461d15e50391L,0x1bdc0e32a1c77952L, + 0xe98242c4d53d640dL,0x1a4724d2cf153c7dL,0x194e5dccba477d46L }, + { 0x871c8cfe3a0d4ccdL,0x62010af09af451fbL,0x9b354f9e6ddec75cL, + 0xe5db0a5d680e3511L,0x183d1270d247745bL,0x9910867aeecf52dcL } }, + /* 37 << 273 */ + { { 0xa970903e8bc2003aL,0x0f8bcfa4a3cf29bcL,0x7054f69e683a7ddaL, + 0x53928bf1ece30167L,0x2588bdf1ffffea87L,0x01683b5ed7172ad4L }, + { 0xa0ac85379de7e713L,0x217bcdfe9b0442bcL,0xba46b8f64d4adb3eL, + 0x320580990a9f8ecdL,0x0173b7bea504bdc5L,0x15321aeb82b1606fL } }, + /* 38 << 273 */ + { { 0x4f349e5f6e39d625L,0x37cbd935b80760d6L,0xb8657ee14b1e84c2L, + 0x502954064cb84bdeL,0x66d678cce8d23ef5L,0xcba173713ec3b79cL }, + { 0xed7ab3e526e3cee5L,0x34c68c516c44ef0cL,0xd704e724f8fdd226L, + 0x2fa0d2dd3a9b40a7L,0x373c5c70a23be590L,0x0beb611bda9f7f7dL } }, + /* 39 << 273 */ + { { 0xef506531913bc31bL,0x31210c5f8c320074L,0xb42faf19b861acc1L, + 0x26f09b89e041e774L,0x23fec89822f84c93L,0x9f8b9d708ec590bfL }, + { 0x604d7d2952644790L,0xb77e3136a2339c53L,0x17f1d7a920f2fc09L, + 0x8c6435d9e6bb96eaL,0x5cafeb5f3711b8a7L,0x1ec6c4edfa23ca24L } }, + /* 40 << 273 */ + { { 0x6fb6b7bc0410ca0bL,0x0e16eed2b3c13935L,0x98ad89d8316ff531L, + 0x4800ee179894d65fL,0x034ea3c448280170L,0x8126d12dc30be537L }, + { 0x43c2d27e5120e525L,0x96a5d498ee65df90L,0x654540105eaef29aL, + 0x1d8f07a17b678fc7L,0x54bc6f737b301270L,0xe58a8102e9473365L } }, + /* 41 << 273 */ + { { 0x1fa3a458aaaf79f6L,0x1d14ff613a1b7c64L,0x32c7da68f22ddb3cL, + 0x7b2345ac58cff63fL,0x214e6d9dce3c3af9L,0x36fba0b78b6691deL }, + { 0x69fd813cee1a30abL,0x50daffe91adf6215L,0x55b34de692871a84L, + 0x437f1b4b7ff3ea1aL,0xc3258ca580ff1c23L,0xdc220ffbc6d0b822L } }, + /* 42 << 273 */ + { { 0x93e56b47ad910b37L,0x8cbce4815d20d236L,0x25b50cac5872d763L, + 0xb50aa752d8505696L,0x02075e6d6f42b533L,0xf0b34a178f8d8352L }, + { 0x59f2feda5234531bL,0xb23e1da1751127c8L,0xe1f65e08b6759ccdL, + 0x47d8631c352e9500L,0xab10d299c13feb16L,0xf9e916a3e5c6a220L } }, + /* 43 << 273 */ + { { 0x55899ffdc06f1b65L,0x4f9ec6e011899630L,0x0df97edc50a29319L, + 0x5c4a10ea5e66f0adL,0xea7b4497aa3d14e9L,0x484d8f64d22cc470L }, + { 0xd7fd252240a61a0bL,0xebd9f49d42d04a79L,0xf18ba2ec312ddb99L, + 0x687273ec2dce1351L,0x68d8b052d0220e57L,0x2c0ecd6b05a7e3dcL } }, + /* 44 << 273 */ + { { 0x460c29904ac6cf02L,0x01482cfa420a35b7L,0xf793933a34680972L, + 0x2cd1f50017e2367bL,0x2411c3523944f060L,0x3d58b97411c06b05L }, + { 0x4552e369cddebb3bL,0xe1c38aec009aeab9L,0x9d34737c353b6e4fL, + 0xf2c99e2cb16d7b0cL,0x57029fa47bbba6a2L,0x0565d1bcd13ef64dL } }, + /* 45 << 273 */ + { { 0x93a50cc7eb0112a9L,0xa0d4419984a59bdbL,0x04b9538c82d01160L, + 0xdb1d33e163a8d5a3L,0xa710beff08d3effeL,0xc2f37326f9bf02f4L }, + { 0x606b6b5555d26856L,0xf528d22a427fe3d7L,0x31b20fac84fb5086L, + 0x27129aa592f7e7bcL,0xd88f0d4f44171b33L,0x9b045c897915ede1L } }, + /* 46 << 273 */ + { { 0x0b15ebebcbe014d6L,0xa4f1504e68d24086L,0xbcf475c979d7c8b6L, + 0xd61b92a8d00a6890L,0x78e096742ee24533L,0x6fe9fe6099656101L }, + { 0xc9542f53e5e63e28L,0x59ec39e12edf3a80L,0x8fe57ffe24ad9280L, + 0xbae0671bf4b9b024L,0x76e36c14d5816ae9L,0xe53256d4805f8688L } }, + /* 47 << 273 */ + { { 0x006956bfcf9e545bL,0x7829ed13e8fa2ee4L,0x1b108d77d4dd6f85L, + 0xf51217bb17045f1aL,0x48c4802986141bd6L,0x8d59b995f8820213L }, + { 0x8439949ffc298a9eL,0x967fdcb278188d77L,0x5bbdfd296f35c711L, + 0x25b37e5df8e62607L,0x18f5c4251795cccaL,0x260f075af0e35ff5L } }, + /* 48 << 273 */ + { { 0x3561b3fea329deb1L,0xfdca0e34f1c3c3e4L,0x4374831347fb79d6L, + 0xa7f497e1c48002edL,0x86221cce2c44dcb0L,0x65e3f04643785e06L }, + { 0x9ee9061fdf4cf461L,0xc7479e8cf022d27aL,0x1d8de85b76f7f52bL, + 0x39a713c90fd6c65fL,0xf74ca067711f8a39L,0xad1119ad8ebc640aL } }, + /* 49 << 273 */ + { { 0x43d9bcba57ec124eL,0xbce6aed98cc29801L,0x1dbb88c72632e757L, + 0xe88f49e891f550e5L,0x056f67da7b6e1b05L,0xa503271082a027bbL }, + { 0x8471fa55c91844a9L,0x882f25b628479daaL,0x96f606dfa9c23504L, + 0x6a42d307fb7fa83dL,0x531c8a5cea310e34L,0x7e2d20565b2e42f0L } }, + /* 50 << 273 */ + { { 0x547047862e8c467eL,0x26f5efc690e52377L,0x762d8f767f6e71afL, + 0x5fc1bd13917ff587L,0x487f6c63fb696a60L,0x889a1dcc3afd2aebL }, + { 0x7407d0a0adcf4b35L,0x8f6c9aef91024ecfL,0x3384f1c03e5d9da0L, + 0xf87acb00b846d122L,0x6d86aebddceb383aL,0x6a5a90cda8f2d076L } }, + /* 51 << 273 */ + { { 0xddff7aa3feb71de1L,0x431e106be44644a9L,0xafe96f8ed5190b4bL, + 0x31a4dfe40ab42a27L,0x0e2d0cc435762eccL,0x7c928cd91fefb256L }, + { 0x5f33c775daeb94f9L,0xa7a91f8894c239b7L,0x6bf418fb4deda3c9L, + 0x91ad6e99eefd4f99L,0x7aae05559c25448fL,0xfb7ed9df487b4deaL } }, + /* 52 << 273 */ + { { 0x59753bf68ba85dffL,0xec8b82efd1c89bceL,0xd7f1a651b8b6a683L, + 0x9c329bf36f84416dL,0xaecbf4b9e68db225L,0x94ec3b0f5a614d23L }, + { 0xbcb6672593a9543dL,0x90c46c46f19132edL,0x4767c73c950b080fL, + 0x0b9b143e971fd9e5L,0xbce6886f8ec8c68dL,0x167b0f8ad47f512eL } }, + /* 53 << 273 */ + { { 0x51517f9481819dd9L,0x2c2640a0fdd7cef9L,0x59283faabf98b8ffL, + 0x39713768a46ad877L,0x13d9c0e6834dcf0cL,0x38c85473cc7acaddL }, + { 0x7b58c7666971a512L,0xbe46a58c2a38e57eL,0x3d26d0a06972e213L, + 0x2341769b63cd0aabL,0x4a293dd0e86307eeL,0x8d1e338d264c81a1L } }, + /* 54 << 273 */ + { { 0x66eb8beab2d5b430L,0x50b4af4382136220L,0x6644e673e79d0b5bL, + 0xe64cdf10f9fa7610L,0xf1dea591132ff33dL,0x07791ab6b926c725L }, + { 0x6c41b4f383f60e02L,0x54bc9049977519c3L,0x618a6f3c2aef73a4L, + 0x42cfc9d26fa4ca2bL,0x2784db71a39a215dL,0x378071655cc85253L } }, + /* 55 << 273 */ + { { 0x9cc3ada3554a7f23L,0xa822f9f21c3d0003L,0xb1654da7303123f7L, + 0xbe33e388f0d8c4a1L,0xd8919c79be4366e8L,0x5a41c92cfe292117L }, + { 0xc4b02d0678c325c2L,0x89eaf4356d511c4aL,0x726fb6d65fda70a0L, + 0xaf7949a0183abdf1L,0x3410915d26f8f929L,0x36b3aeb281f0f83dL } }, + /* 56 << 273 */ + { { 0x1942c2ffcd74009dL,0x71c4d5f5e9c286a4L,0xf3c152b5771a5972L, + 0x4cfb1e74363c2048L,0xcd2ce8249ddb8da2L,0x5d97c8e0a5ee443dL }, + { 0x6fa84b3d68d7b3d5L,0x97eaa76d9ce14ec3L,0x2e4571368e13869dL, + 0x39ac6a0c96f0f8a1L,0xe24458ac42d93dc0L,0x7eb3689d5f60bec9L } }, + /* 57 << 273 */ + { { 0x75592736bce6ebe3L,0x84001a886777bd90L,0xe82739774a31ca6bL, + 0x6906baf0a8e0dd38L,0x92af56d0848d0c92L,0x7ae700c6501326d0L }, + { 0xce418817470339a9L,0x4354d7928e448dfeL,0xc8f593afa48e3148L, + 0xdd5fee34db1a96b2L,0x5974e81e357960c2L,0x7326bf016306fdabL } }, + /* 58 << 273 */ + { { 0x74183618de017cd9L,0x939c7975dcfe6dbfL,0xcad9f8a108ec41e5L, + 0xd9edb91d391afcddL,0xadf1f18c7c4a3f03L,0x0566d3e8ab477304L }, + { 0x32ae20464c19c62cL,0xfa15fdcb252c8c4eL,0x2ed4767e91de2794L, + 0x622e4f38507f8067L,0xd647242bc68ac330L,0x0650e0a9fc1ccf29L } }, + /* 59 << 273 */ + { { 0x6ecd68a086085cc3L,0xb463f4c165c0cc54L,0x3182cc5c480bc57dL, + 0x8f16f2038e6d9267L,0x8c92e446df0d0ee9L,0x7da6001ba4d09789L }, + { 0x596390ff976ee9d0L,0x12b8f9dee4c0fd5fL,0xad08673f297b10f2L, + 0xc8e9097c7b524a51L,0xd494f0d3009cf47cL,0xf535c07abcdd1b68L } }, + /* 60 << 273 */ + { { 0x29544fe8588360ecL,0xa1aa9b9fffb550eaL,0xe1f6cf994af4d28dL, + 0x723d48b00c6fd477L,0xf51f1b2f5c81b252L,0x88ec11c04f5a33eeL }, + { 0x7747f0432cd72de4L,0xcca69b0ad71c92c1L,0x9455d86e4e8cc763L, + 0xc9e0aa1bc08444e0L,0x93803b68e8fffa63L,0xc296af292d781b7dL } }, + /* 61 << 273 */ + { { 0xb1891a2b17329e31L,0x87c2a49056e36717L,0x8c2a50fafd26d8b3L, + 0x017e4e417e3c5a5fL,0xbeb4fad0506c382eL,0x5d3e8b16fc281ec9L }, + { 0x407f7598890e57a0L,0xda855e8b340cd6d6L,0xb9393129ff388d54L, + 0x41113ffdcf355d9eL,0x31d3bb09b357c28dL,0x975bdf00fd39e481L } }, + /* 62 << 273 */ + { { 0xbfb0c87e10a1b4f2L,0xfaf51153dc2fcc04L,0xd2588e39d6b98d81L, + 0x5de5b0eb4953133dL,0x6b65d8135b959ed6L,0x864511dc02eb45bdL }, + { 0xb1dcb4d3d7ce20bdL,0x917bcd0987587230L,0x0935790f83a79453L, + 0xdc65862e54b35d76L,0x4cd2332ba6d1eeeaL,0x0706fcd030d315b5L } }, + /* 63 << 273 */ + { { 0x7c91adb3adf2d8d1L,0xfe1549c24a212fd3L,0x8a7cc285c33213b3L, + 0x26643cfd3e56d17bL,0xcc007c15684c872fL,0x485643e009e554f3L }, + { 0x7f5e9a6ec6569206L,0x252b5393c2f596d6L,0xf7eef1dbbf9cdea5L, + 0x611ee7334dffab46L,0x8d93802a805e976cL,0xd07c0ac6f85c939cL } }, + /* 64 << 273 */ + { { 0x514cc1dcb08d2d0eL,0x4e6b379e30e93536L,0xf0e422ac2fc9230fL, + 0xaa50a1ad92e23e21L,0x70ac46d8676d1ac0L,0x698b9991f9f54493L }, + { 0x59a6b86a8649519fL,0xc1f11ad6e3511da4L,0xd3d9cff13192968cL, + 0x13e700b40b342dd8L,0xfd5dc7bb3b1da441L,0x02426e7c2c883760L } }, + /* 0 << 280 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 280 */ + { { 0x9e9af3151c4c9d90L,0x8665c5a9d12e0a89L,0x204abd9258286493L, + 0x79959889b2e09205L,0x0c727a3dfe56b101L,0xf366244c8b657f26L }, + { 0xde35d954cca65be2L,0x52ee1230b0fd41ceL,0xfa03261f36019feeL, + 0xafda42d966511d8fL,0xf63211dd821148b9L,0x7b56af7e6f13a3e1L } }, + /* 2 << 280 */ + { { 0x3997900ecc8998d6L,0x8fa564b7baa60da1L,0x71bf5b0a661f3c57L, + 0x44b13388aab1292bL,0xcbe80cb9d4d993f2L,0x0b19b4c92203f966L }, + { 0xbc82a6520080f259L,0x870ebc08ad96dea3L,0xa388c7e7502f0003L, + 0x9c704ef056a38f73L,0x93cde8a73487d9b0L,0x5e9148b0ec11a1f3L } }, + /* 3 << 280 */ + { { 0x47fe47995913e184L,0x5bbe584c82145900L,0xb76cfa8b9a867173L, + 0x9bc87bf0514bf471L,0x37392dce71dcf1fcL,0xec3efae03ad1efa8L }, + { 0xbbea5a3414876451L,0x96e5f5436217090fL,0x5b3d4ecd9b1665a9L, + 0xe7b0df26e329df22L,0x18fb438e0baa808dL,0x90757ebfdd516fafL } }, + /* 4 << 280 */ + { { 0x63f27a25a748b8f5L,0x68c8f3ec2cd246c4L,0x5d317cd965f9ce38L, + 0x162c92e0635ba300L,0x5259f64ffe343662L,0x4a6b2b668e614ac8L }, + { 0x97fb55bb01177c3bL,0xfb586c21a705cb01L,0xa57e732578061824L, + 0x892f6b386c1e6306L,0xf12e4c072367b14cL,0x580d5fe2c83a48c5L } }, + /* 5 << 280 */ + { { 0x1e6f9a95d5a98d68L,0x759ea7df849da828L,0x365d56256e8b4198L, + 0xe1b9c53b7a4a53f9L,0x55dc1d50e32b9b16L,0xa4657ebbbb6d5701L }, + { 0x4c270249eacc76e2L,0xbe49ec75162b1cc7L,0x19a95b610689902bL, + 0xdd5706bfa4cfc5a8L,0xd33bdb7314e5b424L,0x21311bd1e69eba87L } }, + /* 6 << 280 */ + { { 0x6897401cea2bafb3L,0x7b96ecc215c56fe4L,0xe511b32939e2b43bL, + 0x39522861bf809331L,0x815f6c1dc958f8f4L,0x2abbdf6bc213e727L }, + { 0xeb09ae59c39bc01fL,0xffe3b831676b56a5L,0x8f4815a2a20f86c6L, + 0x748a17669aa30807L,0xf1f46a211b758878L,0xbd421fe76f6fc3d7L } }, + /* 7 << 280 */ + { { 0x75ba2f9b72a21accL,0x356688d4a28edb4cL,0x3c339e0b610d080fL, + 0x614ac29333a99c2fL,0xa5e23af2aa580affL,0xa6bcb860e1fdba3aL }, + { 0xaa603365b43f9425L,0xae8d7126f7ee4635L,0xa2b2524456330a32L, + 0xc396b5bb9e025aa3L,0xabbf77faf8a0d5cfL,0xb322ee30ea31c83bL } }, + /* 8 << 280 */ + { { 0x300b04840d6ded89L,0x0b1092cbc3ab55edL,0x17d9c5420cc10a74L, + 0x7f637e84eff9d010L,0xd732aa1e27aa1285L,0xedb97340e2a77114L }, + { 0x62acf1585ef4dfb0L,0x1e94fc6eba1d7b81L,0x88bec5d22e6eb2dbL, + 0xaec272028d18263dL,0x4b687353e4bbd6acL,0x031be3510ff7e4c0L } }, + /* 9 << 280 */ + { { 0x048813847890e234L,0x387f1159672e70c6L,0x1468a6147b307f75L, + 0x56335b52ed85ec96L,0xda1bb60fd45bcae9L,0x4d94f3f0f9faeaddL }, + { 0x6c6a7183fc78d86bL,0xa425b5c73018dec6L,0xb1549c332d877399L, + 0x6c41c50c92b2bc37L,0x3a9f380c83ee0ddbL,0xded5feb6c4599e73L } }, + /* 10 << 280 */ + { { 0x6c00f388f086d06cL,0x17ee45035add0cf4L,0xf96984c707caf89cL, + 0x9d49d667648ed5e9L,0x3ef95015a0164881L,0x39e28e447d9c651fL }, + { 0xb13ad24059f37780L,0x08cee349b9522225L,0x9245ee6f2ba1b214L, + 0x12bedaa9a886d8d2L,0xe139ae08fcb8186fL,0x99203fb6fc2ef864L } }, + /* 11 << 280 */ + { { 0x14d34c210b7f8354L,0x1475a1cd9177ce45L,0x9f5f764a9b926e4bL, + 0x77260d1e05dd21feL,0x3c882480c4b937f7L,0xc92dcd39722372f2L }, + { 0xf636a1beec6f657eL,0xb0e6c3121d30dd35L,0xfe4b0528e4654efeL, + 0x1c4a682021d230d2L,0x615d2e4898fa45abL,0x1f35d6d801fdbabfL } }, + /* 12 << 280 */ + { { 0x3c29284764c9323dL,0x40115a890491f77dL,0xec141ade2d7a05f5L, + 0x0c35e4d9222a5f9fL,0x5ea51791442a3e9bL,0x17e68ecee51b841eL }, + { 0x415c0f6cd6ae9174L,0xe6df85f89ffd7595L,0x65fc694f8dedf59cL, + 0xc609503efee92718L,0x57d2592e97d565aeL,0xb761bf157e20862bL } }, + /* 13 << 280 */ + { { 0xa636eeb83a7b10d1L,0x4e1ae352f4a29e73L,0x01704f5fe6bb1ec7L, + 0x75c04f720ef020aeL,0x448d8cee5a31e6a6L,0xe40a9c29208f994bL }, + { 0x69e09a30fd8f9d5dL,0xe6a5f7eb449bab7eL,0xf25bc18a2aa1768bL, + 0x9449e4043c841234L,0x7a3bf43e016a7befL,0xf25803e82a150b60L } }, + /* 14 << 280 */ + { { 0xd443b26582376117L,0xb91087c11a1beb0dL,0x3fe62a6545cc5951L, + 0x49c754bce6e472d5L,0x7e60bb8177c424ebL,0xbcd4088e830cbb97L }, + { 0x3da5c94eba26df7bL,0x508b4f55f72b4338L,0x409c5c7469ad7784L, + 0x82e5f1b0fdf44d6aL,0x10654a1ceed2766fL,0xef1e65faa6e83f4aL } }, + /* 15 << 280 */ + { { 0xe44a2a57b215f9e0L,0x38b34dce19066f0aL,0x8bb91dad40bb1bfbL, + 0x64c9f775e67735fcL,0xde14241788d613cdL,0xc5014ff51901d88dL }, + { 0xa250341df38116b0L,0xf96b9dd49d6cbcb2L,0x15ec6c7276b3fac2L, + 0x88f1952f8124c1e9L,0x6b72f8ea975be4f5L,0x23d288ff061f7530L } }, + /* 16 << 280 */ + { { 0xa6e19d0a5f56dc3cL,0xe387e2690b88326aL,0xef7380950ee527a4L, + 0x78b7174b7c4278a6L,0xc133d867e70798ffL,0x9d0fef759e9230caL }, + { 0x7431eef01a955ab9L,0x3772e7038868d922L,0xf7a4306a8d6af3f7L, + 0x633bb5a0bbec076aL,0x6d07623e7a257ca3L,0xffb5e16521c00663L } }, + /* 17 << 280 */ + { { 0xebfe3e5fafb96ce3L,0x2275edfbb1979537L,0xc37ab9e8c97ba741L, + 0x446e4b1063d7c626L,0xb73e2dced025eb02L,0x1f952b517669eea7L }, + { 0xabdd00f66069a424L,0x1c0f9d9bdc298bfbL,0x831b1fd3eb757b33L, + 0xd7dbe18359d60b32L,0x663d1f369ef094b3L,0x1bd5732e67f7f11aL } }, + /* 18 << 280 */ + { { 0xfab0ce2bee1ae33dL,0x7bf9f90b4c5692e3L,0x131a4374d776d6caL, + 0x6ba40908a2b135afL,0x5c4ab997e1334bf8L,0x9eb442d07af584e9L }, + { 0xd764c506786391c1L,0x07f24c6bbcf6ab3aL,0xf73c7924fad8e1bbL, + 0x79f624acb7583623L,0x2b032021b44c14d3L,0x7cc0ae8dbf58ff99L } }, + /* 19 << 280 */ + { { 0x3c7fb3f5c75d8892L,0x2cff9a0cba68da69L,0x76455e8b60ec740bL, + 0x4b8d67ff167b88f0L,0xedec0c025a4186b1L,0x127c462dbebf35abL }, + { 0x9159c67e049430fcL,0x86b21dd2e7747320L,0x0e0e01520cf27b89L, + 0x705f28f5cd1316b6L,0x76751691beaea8a8L,0x4c73e282360c5b69L } }, + /* 20 << 280 */ + { { 0xe4d7c8b88929c133L,0xe5f96bef92a813c7L,0xdb8ab0af71c18e09L, + 0x0db6ff287dae63b4L,0x54d1fac49a1eaa73L,0xadbcfdf59180c980L }, + { 0xd3220f300b584314L,0xa24e4d1cca3697c7L,0x4ade8c7fa44f8067L, + 0xbd8bc81aca21ac17L,0x303a2f9fc1d361cfL,0x55648b65c71cf031L } }, + /* 21 << 280 */ + { { 0x46bcc0d5fd7b3d74L,0x6f13c20e0dc4f410L,0x98a1af7d72f11cdfL, + 0x6099fd837928881cL,0x66976356371bb94bL,0x673fba7219b945abL }, + { 0xe4d8fa6eaed00700L,0xea2313ec5c71a9f7L,0xf9ed8268f99d4aeaL, + 0xadd8916442ab59c7L,0xb37eb26f3f3a2d45L,0x0b39bd7aa924841eL } }, + /* 22 << 280 */ + { { 0x6f8135c7ce89e8daL,0x21ac20d9d6b5948eL,0x1dc4d48b31cefd7eL, + 0x3d34bc2a4a347926L,0xadcd11be8f614fd6L,0x77148b08a8ea116aL }, + { 0x7afc75fcfce1d3f5L,0xa9e0557d7d9a8ea3L,0x640cb5850cc864ecL, + 0x5811ba842eb332c7L,0xb6c10b6efdb668c4L,0x24d8b10f99f5f6c7L } }, + /* 23 << 280 */ + { { 0xd811eb32e03cdbbbL,0x12055f1d7cc3610eL,0x6b23a1a0a9046e3fL, + 0x4d7121229dd4a749L,0xb0c2aca1b1bf0ac3L,0x71eff575c1b0432fL }, + { 0x6cd814922b44e285L,0x3088bd9cd87e8d20L,0xace218e5f567e8faL, + 0xb3fa0424cf90cbbbL,0xadbda751770734d3L,0xbcd78bad5ad6569aL } }, + /* 24 << 280 */ + { { 0x391fa3cd8d075ec5L,0x54d45020c84c81e5L,0xdead561a79fad87cL, + 0x0ab3c8544e7ffc48L,0x5967f8ebff02706cL,0x8860de795d31ec98L }, + { 0x7476459c6c8a1c25L,0x8d9c484082f16117L,0x5c1b13b33b413429L, + 0x1962a435601b5906L,0x78b9d382e006929dL,0x1924e979e5897b16L } }, + /* 25 << 280 */ + { { 0xcadb31fa7f39641fL,0x3ef3e295825e5562L,0x4893c633f4094c64L, + 0x52f685f18addf432L,0x9fd887ab7fdc9373L,0x47a9ada0e8680e8bL }, + { 0x579313b7f0cd44f6L,0xac4b8668e188ae2eL,0x648f43698fb145bdL, + 0xe0460ab374629e31L,0xc25f28758ff2b05fL,0x4720c2b62d31eaeaL } }, + /* 26 << 280 */ + { { 0xef1001dfbdb22e61L,0x1626bd9af384bbf5L,0x33f42d385fe8ae07L, + 0x59646c42b7218d21L,0x5e27210e6a016f5dL,0x3e9ecf07094481c3L }, + { 0xf91609c1f50cc2dcL,0x8bf8c05ad0d43633L,0x9d508972e74ab746L, + 0xb625887a33f628b7L,0x557bd493e733952fL,0xd35f450b8981dcfbL } }, + /* 27 << 280 */ + { { 0x4603cdf413d48f80L,0x9adb50e2a49725daL,0x8cd3305065df63f0L, + 0x58d8b3bbcd643003L,0x170a4f4ab739826bL,0x857772b51ead0e17L }, + { 0x01b78152e65320f1L,0xa6b4d845b7503fc0L,0x0f5089b93dd50798L, + 0x488f200f5690b6beL,0x220b4adf9e096f36L,0x474d7c9f8ce5bc7cL } }, + /* 28 << 280 */ + { { 0x531c43cdb63f3d28L,0x01289772429708dfL,0xb0ee772ccdb60078L, + 0x4131f5cd5f1a6e72L,0xd9d0f8c6a0da0112L,0x58efddd204e957b1L }, + { 0x18857c0c32840c31L,0x00825340c4068b2cL,0x0a9217a771ff8800L, + 0x69b19e6415530b80L,0xa28e274ee125e3f2L,0xb471a91bc9bfc846L } }, + /* 29 << 280 */ + { { 0xfed8c058c745f8c9L,0xb683179e291262d1L,0x26abd367d15ee88cL, + 0x29e8eed3f60a6249L,0xed6008bb1e02d6e1L,0xd82ecf4ca6b12b8dL }, + { 0x9929d021aae4fa22L,0xbe4def14336a1ab3L,0x529b7e098c80a312L, + 0xb059188dee0eb0ceL,0x1e42979a16deab7fL,0x2411034984ee9477L } }, + /* 30 << 280 */ + { { 0x01d04fe04ce2d199L,0xf434bcfd0517c7ebL,0x82f3aca4a7659a94L, + 0xf436a7781ff015c9L,0xf5143391d6223e5cL,0xba66c6a2ecb5c340L }, + { 0x080f158a4b23a041L,0xb401094cb699acafL,0x1c57626c677491dbL, + 0xfb39e317d42d86dbL,0x19e2ca804f6b3354L,0xe919c4c3c1d41ef3L } }, + /* 31 << 280 */ + { { 0xd65246852be579ccL,0x849316f1c456fdedL,0xc51b7da42d1b67daL, + 0xc25b539e41bc6d6aL,0xe3b7cca3a9bf8bedL,0x813ef18c045c15e4L }, + { 0x5f3789a1697982c4L,0x4c1253698c435566L,0x00a7ae6edc0a92c6L, + 0x1abc929b2f64a053L,0xf4925c4c38666b44L,0xa81044b00f3de7f6L } }, + /* 32 << 280 */ + { { 0x35ae891bbb71e9b0L,0x1f6ce6ca522b77f0L,0xc2dab3cae63745c4L, + 0x55b8c185f218d139L,0x6ab039c889f3b0e2L,0xd9e25bfdc644c3faL }, + { 0xc8496f203e2ed47bL,0xc395ec028d67e17cL,0x5c67839292114918L, + 0xe962e52fef73f345L,0x3818baf354fcfb22L,0x4d75d65d9d4bc911L } }, + /* 33 << 280 */ + { { 0x10078824eb7ff5fdL,0x50c65328735ef75fL,0xdfc04d53ec980ba2L, + 0x4bfb260f2d519cf5L,0x1f03dff15c854667L,0xd1ad2231badb625cL }, + { 0x986064d0be9f7f03L,0xe5ff93e5c13f7d0dL,0x02682a1896e26a17L, + 0xc421567c817ec3cdL,0xb740652352615c25L,0x6800a8335d135eebL } }, + /* 34 << 280 */ + { { 0xde57575b17d8ec5cL,0x72e2257578aeb9bbL,0xce73fa7731605c27L, + 0x2f286b79ae77436cL,0x5e78fbb77f4e6997L,0xb03c888e474f23a7L }, + { 0x4bb302a3e38927ceL,0x39c6de5f6e1514ceL,0x9daa0ad349b2ddbdL, + 0x98fd2377d683dffdL,0xbefa4ae5933476edL,0x4ad53d01173f49edL } }, + /* 35 << 280 */ + { { 0xdfafc70e44b89837L,0xe0104b9c4935fa88L,0x7625d9d92fd702e2L, + 0x27461e6549af2219L,0x4a279383ad3f36edL,0xd87e246b9204e857L }, + { 0x8d832190ab1727d9L,0x59205cd82182e291L,0xb96a1d15a6513613L, + 0x1c7de3cc49cc8ddcL,0x637ea26af17ab785L,0xc098bb7a09a3ba58L } }, + /* 36 << 280 */ + { { 0xfb5383cc31bd4f68L,0x6fd5aee3d96a1899L,0x4e39d6eb01d5430eL, + 0x12679565ca5a2848L,0xa399e83f062b44fbL,0x3ee2432f3c166682L }, + { 0x57229c841de47708L,0x40a5d0cbba528a61L,0x4bae36be8239e7baL, + 0xddac65a2f8087427L,0xfd516d1a3cc61266L,0xc89542b5bcef98b1L } }, + /* 37 << 280 */ + { { 0x3fc8d1b2d49cc0eaL,0xfc591f7f7bca4d23L,0x5f48e27c41fefdf3L, + 0x5ca1d08a1039419dL,0xd450c1bddc8042ceL,0x6760e23fb436fc4bL }, + { 0xc5642797c06bb34bL,0xb787cd53fde06d4dL,0x2926360ccbf144b0L, + 0xb63756f4dce32421L,0x0878deab774abc4aL,0x2d97c7919a4e142aL } }, + /* 38 << 280 */ + { { 0xf58389ff105c818eL,0xfa29f1eb585fa7f0L,0xb6da09b5917e8924L, + 0x1375c3047e7a3f49L,0x9b4792b289cfa1c0L,0x92094a8535571cc7L }, + { 0xf986ccf6051e5e50L,0x55ea34d601df6babL,0xe65989eed1363333L, + 0xd94bbd918c84e20aL,0x9a4f71dc49e39b8aL,0x6d9fe495927d633eL } }, + /* 39 << 280 */ + { { 0x30b295f01fdc29e2L,0x71415daae2c2fab4L,0x205e957683c312beL, + 0x893c69fefab48afcL,0x8108f3f994ca2fdbL,0x37c860c314f99296L }, + { 0x1009a6d2e990ed34L,0xd5350c36ac26b611L,0xd03161102ce23d91L, + 0x82bb476e62189343L,0xe255965160ef0cbdL,0x6bab3f53cf5d2311L } }, + /* 40 << 280 */ + { { 0xcaa3b7a592fa460fL,0x92bb46b804dff174L,0xcd6949b3cf926a1fL, + 0x01f95e5559d1bb18L,0x21f90c08d4518f3cL,0x325dbfe920ee8bf5L }, + { 0xd0136f3feafb919eL,0x941190cc8e0ebcabL,0x599e91a287b557aaL, + 0x7fac4887dcbde1c7L,0x1dad481905a07040L,0x640493978b03d593L } }, + /* 41 << 280 */ + { { 0x65521bb85ebd3685L,0x16c68e79665d1619L,0xd6ab56bbc52b14c8L, + 0x312f1fb4c6d3067dL,0x5afef4f3d50587c0L,0xa3e79e94ace6e2feL }, + { 0x52c7fa0825f12a1eL,0x9c1c1ea20dec9f3dL,0xc418d4232e87a036L, + 0xa0a19fbb0283752fL,0x52e0a8830b804506L,0xc67fc71b3f7de2a1L } }, + /* 42 << 280 */ + { { 0x4d062d3d7dad8ca9L,0xb78c81581cf59756L,0xaccb38f8c6b5d9fcL, + 0x83436d3f7ddc66eaL,0x37115b6033adcb87L,0x49b74bd45a8b09abL }, + { 0x7b8bdb81675ae43bL,0x5284f5b3f0476428L,0x8f1521e7db38b0c7L, + 0x792ef9dea0c4b2f6L,0xa15880a162159fc6L,0x70b999e372b09b63L } }, + /* 43 << 280 */ + { { 0x6f47787d4e8ffde7L,0x19e9434574495a10L,0x8da6d55784f5be33L, + 0x110844811884e325L,0x621734c5a9f030baL,0x25cd0544d0e63f63L }, + { 0xea6729687e936833L,0x08297af784a34442L,0xb77dc3a342f9ed3eL, + 0x9f8908c8258e8d4fL,0xb8281bfc3299ba4bL,0x1f6412920a09849cL } }, + /* 44 << 280 */ + { { 0xd5d51e60ee9a7708L,0x2e8ab3effd2cfe78L,0x0af5c3bac8e71273L, + 0xbfd1b94091041652L,0x4c7c86ab52ce4582L,0x3ab72feff1d9bc29L }, + { 0xae89c3d51e1974b3L,0xd859c7ef70433caeL,0x762064c77edd1398L, + 0xc0b6a6b6072064a4L,0x3ba43b059bb1b3d0L,0x20f9aa85e47d79bbL } }, + /* 45 << 280 */ + { { 0xd1a45415c2d001cfL,0x40f3f05d848a480fL,0x03708da0ce554d5bL, + 0xd7090557c80f4254L,0x7e57d29907743393L,0x7db8a5e10f2f5903L }, + { 0xd0466a0b14e8ff8bL,0xa3c38f49e0cf88b0L,0xde47262e329f71adL, + 0x56b2a7935da6d0a1L,0x22e1f9b880ef44b0L,0xb9b96c617b2b6d4bL } }, + /* 46 << 280 */ + { { 0x3235bc494c500ee1L,0xce0f0b54da4a4f35L,0x628cb91c337ac7b7L, + 0xd8a6d4cd88a26e9dL,0xdcf40cba96e44349L,0x073a0f75b54e3fa9L }, + { 0xc9b95d29ca44e6e8L,0x42ad9afa2315f4beL,0xdf13a5ddf78617c7L, + 0x40aeb346d196504bL,0x9317d6f33d1fef90L,0xf94d308fe1708a79L } }, + /* 47 << 280 */ + { { 0x45bc768608835815L,0x700d93bc5798c507L,0xae3415b85362a822L, + 0xdbce01b33883d21dL,0xb9df7efbe56fb2aeL,0x5ed57d9427d341c0L }, + { 0xdc26916e7ee4dfa0L,0xcdb06a17147c075fL,0x0198b6a7fa9e7a63L, + 0xc9876c786355b62bL,0x9f4b8f12f565279dL,0xa03aeb619cb6ddb6L } }, + /* 48 << 280 */ + { { 0x3a35938779493f3dL,0x128301a91f06a9c0L,0xfcce0f82899d204cL, + 0x4ca41589158780b5L,0xc28f1bb73c4edd4fL,0xe08e48a87a6aec34L }, + { 0x6d4783dfd447c55eL,0xe7c2ecc857803027L,0xb7b8c2bcdf6d7f91L, + 0xf0a8d4700f356ca3L,0x229894bfdeb8e964L,0x555c9d40d3aa70e1L } }, + /* 49 << 280 */ + { { 0xa899a252e0ace851L,0x74b716c9bb9d8476L,0x2ba0bb00571bb175L, + 0xee01a9bf7ac2b619L,0x74f0b6d3502ee575L,0x7fdd7856cc45f810L }, + { 0x68c0beb1c0ae384dL,0x21955de8fe63d58fL,0x1b98e3951c08bbd2L, + 0x5ddaf7e9638701b3L,0xefc264f1b1242d62L,0xa9b8de5c81292443L } }, + /* 50 << 280 */ + { { 0xf0d713b7131a3bf1L,0x690ae8c147e9f09fL,0x1dc92a5f8cd8bf1eL, + 0xdf98927ad61f5445L,0x729b5469ae795eabL,0x939b391c5265675aL }, + { 0x5d916c6c7bd7e97aL,0x7c2a3de5d514e72bL,0x0660758379e9915fL, + 0x0554d5e543a4d2c7L,0x37eb7f82ca5bca41L,0x90e41b71b640109dL } }, + /* 51 << 280 */ + { { 0xfdd403b0e6f769aeL,0xa67f97f6906a7981L,0xc86c49be6aa83c6dL, + 0x6177820677ab6d8fL,0x60f77c49916933b2L,0xfa33c528fcb3fe39L }, + { 0x102ffca0783cb589L,0x6a37a394a96ce10eL,0xd17bf1f89eb4695fL, + 0x2a7623af2a53116eL,0x10601afe83af2e60L,0xceebada2582a1704L } }, + /* 52 << 280 */ + { { 0xcbfb50fa57004c05L,0x0d545f0ea7bea436L,0xb7e30eb77071e269L, + 0x435b3df73b845896L,0x48ba27f0b246365eL,0x9fbe883341344f12L }, + { 0xb763df280a87ef33L,0x4f9339d70b5288beL,0xc02770d6e722e3beL, + 0x6c69bfd918e32f03L,0x20c5c05e74c2845cL,0x09fa0928d6f9279dL } }, + /* 53 << 280 */ + { { 0x82f43866962fccc1L,0x92bc5f82278c9762L,0xc979a68b39a39a08L, + 0xfcae204b97c5a298L,0x78f55c7908676082L,0x210e036447c7b09dL }, + { 0x24512cef47d87769L,0xb4b0fdd7e4b53f4fL,0xc2a263fff6818efdL, + 0xfa160dc1985bc93fL,0x7b7f82961bf44affL,0xd6c75fb2a6407cdfL } }, + /* 54 << 280 */ + { { 0xea0b6ec35741c57bL,0x9b148c2668ba5fd0L,0x6206025166461969L, + 0x0726919f8cfc618eL,0xf66ac684c1954bcbL,0x160ad0260273adb4L }, + { 0x0ec10cffe6f6aac3L,0x232fc7adb4f64d98L,0x0707cb6e73564063L, + 0x76daa2c5487a29acL,0xe4ffd6e335768176L,0x4ab87262464d126eL } }, + /* 55 << 280 */ + { { 0xdbc1d21c553f05efL,0x16e950d0dc115e4cL,0xa727059a354480a5L, + 0x32df221efd6711f1L,0x06f9bc2e5c8aa9fcL,0x9f2449a67b15522cL }, + { 0xac14774bf498ee00L,0x02b5979f3ec7e0a2L,0xdce96e06e1e00abdL, + 0xd7a1bf5a1e00e8a9L,0x19b30fd3a8f42042L,0x29b08eb7e7c507ebL } }, + /* 56 << 280 */ + { { 0xe91477d3a66b2f3aL,0xf50d3bdfc4deb7f5L,0x19bf2857a1e45e44L, + 0x1c104e3270a2126aL,0x4636b4894357b9f5L,0xf65e5aa0962d684aL }, + { 0xfcc83a5fb7b52893L,0x8451d02b08adbd4dL,0xf0fb410c19f7a896L, + 0x6b90b0faff36caeeL,0x111710d0f5af8966L,0x00a4cfafbd2b8c59L } }, + /* 57 << 280 */ + { { 0xad9f11cb817bd227L,0xe4733a1465d27b5fL,0xeda46e8dbcf76526L, + 0x8db309ecad57a5a9L,0x4a863ec07f1487a8L,0xb0453ed210f1c4c1L }, + { 0x9b4df78af2dbfd76L,0x62af38b21525e18cL,0xe6bd0b0ade2c7f65L, + 0xad62bfb70b27fad4L,0xd21fd4346d6a8a5fL,0x07b606703e401a5eL } }, + /* 58 << 280 */ + { { 0xdd14c891e34b192cL,0x6ddfcc793aed3e36L,0xc89c3e6dc49a92e2L, + 0xa61954fd6fcf1ce9L,0x420c39a9bd297157L,0x57c20a8a406d3f2fL }, + { 0x7ccda02263faf545L,0xb01814a96cca4388L,0x88baf1dce5fb1fd0L, + 0x9e1183cfa0bae755L,0x3fe540badbc243c2L,0xe50d52305aeb26a3L } }, + /* 59 << 280 */ + { { 0x10145b3d52726a98L,0x7236036869e333fcL,0xce9a409323a6f608L, + 0x61c121dcddd11095L,0x3349b30a0d39f1daL,0xd07df9d4e3485e93L }, + { 0xb4c500a561159e84L,0xbc74918100561c03L,0x8f27e9f3904ad807L, + 0x7272786a0108ed01L,0xcf36a5d9c9365dd8L,0xe052fc9d7f859d87L } }, + /* 60 << 280 */ + { { 0x0e6cd863da97e11eL,0x5b058c6852a818a1L,0x7768c5e73de760b3L, + 0x898b7f608dfb4142L,0xd48130977efec180L,0xd7196cd758279538L }, + { 0x67c451fb816858a1L,0xbf0e88912ac699b2L,0x21fa74effcb126a5L, + 0x1f9dc10123b8df5aL,0x38aefff921136ffcL,0x3408874c47cb395aL } }, + /* 61 << 280 */ + { { 0xded9035213054567L,0xc61d0628c58c633dL,0x73ff2589f31143c3L, + 0xc43594ff0871b05cL,0xcf662dd64db0edf2L,0x6bac019d8d1f33b0L }, + { 0xcaa37cd8bb379461L,0x9b077a6934fc0269L,0x421e716788ecedf2L, + 0x2d422f95073284cdL,0x9a353114bbb2409cL,0x99e8c7a0dcbb79e7L } }, + /* 62 << 280 */ + { { 0xfca254cba21c40f0L,0x4945c838e0f4a032L,0x99318ff3fd6cb7fdL, + 0xc631e0644a85e726L,0x2e3ca11d9359e8cfL,0x433a0e5c06acf935L }, + { 0x665c54c996b37ea9L,0xe78865c4c2d52b81L,0x68596f6ffb27850aL, + 0x7e7272221277995eL,0x602b0f5c197344c2L,0x81ff2ad620a9ec11L } }, + /* 63 << 280 */ + { { 0xb2ce6cbe7c4c464fL,0xd7c11ef5741a4b1fL,0xf3f987f621a7eb17L, + 0x6b2812ef79f4e274L,0x3a0117ae38a7d5ddL,0x5d8c75a9cfab6bb5L }, + { 0x3827c04052394166L,0x897eb181e00e621dL,0x6693817f8aa19361L, + 0x67cac329959d81a8L,0x21e7133869a7ca51L,0xa02fd11269a46a87L } }, + /* 64 << 280 */ + { { 0x7f1f985c022ea83aL,0x90a22662a7584e7fL,0xb40a930a5188fcf6L, + 0x3fad79aba3a82904L,0x7bee8d22f3151027L,0x79a1a838c2c3e17bL }, + { 0x1fbe06e933cc3509L,0x629c56aa9abd5ccaL,0xfff290ec2d9cf7a5L, + 0x5d0dedaa9bd062c5L,0x080344abd7d35381L,0x0848373af5cf9edaL } }, + /* 0 << 287 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 287 */ + { { 0x31d31f7a7a0c0bc0L,0x7a37a84ab251d2bfL,0x1793362e52f04d67L, + 0x5808e70921c7b651L,0x33fe9123ed6f47f6L,0xdeb1dde958f71405L }, + { 0x821d3045ae56b472L,0x9f61f761e02043adL,0x932ddb145b2048a9L, + 0x17d989fed7811330L,0x032ae4cb128fd85fL,0x8f1956b47d1ef434L } }, + /* 2 << 287 */ + { { 0x070d34e116973cf4L,0x20aee08b7e4f34f7L,0x269af9b95eb8ad29L, + 0xdde0a036a6a45ddaL,0xa18b528e63df41e0L,0x03cc71b2a260df2aL }, + { 0x24a6770aa06b1dd7L,0x5bfa9c119d2675d3L,0x73c1e2a196844432L, + 0x3660558d131a6cf0L,0xb0289c832ee79454L,0xa6aefb01c6d8ddcdL } }, + /* 3 << 287 */ + { { 0xe5d473dc7521f457L,0xe9ef09bda00be577L,0xf6d0965fb6eaa640L, + 0xeb49486875726560L,0x452116d528817302L,0xf0424fdbfbde3597L }, + { 0xd6096da3bb454915L,0xde48280841422141L,0x7a1351972d19fac0L, + 0xdc9a5ec421393f6fL,0xcabcc1e3eb2c8adaL,0xd436643142d8c4f2L } }, + /* 4 << 287 */ + { { 0x0ed1082f89e4e449L,0xdb1fb471833f2378L,0xa35fef0eece77352L, + 0x76adaa464bf0c426L,0xfbab929aa011b2fbL,0x6f475d5b9d8cc4d3L }, + { 0xbe6d7f2174351480L,0x2d1362d193e4a7aeL,0xc7e2cba5106ceaabL, + 0xfe94528a45258697L,0x7109b17d075945b0L,0xfd395b2ccae17f7aL } }, + /* 5 << 287 */ + { { 0xdf534b80dece6d4dL,0xcfaa60a28737af46L,0x7d76a921b9ba3d56L, + 0x61490bd199338721L,0xc514e950ed25cfbdL,0x5041fbb2dc09b8b1L }, + { 0x2410310d46fbcbf0L,0x2c46bcd14f7e8aa4L,0x08ce31f5d0d5fe1dL, + 0xb11efdbebeac3c97L,0x406e1d05b01633e9L,0xde48cdba766391adL } }, + /* 6 << 287 */ + { { 0x68550299845e12c9L,0x979b5406361d027fL,0xf601d2b4a8e92e70L, + 0xfd02799f0cc9fca9L,0x89f99ca013bc2e96L,0x22a12c0bff9db9b8L }, + { 0x6ae7084a32efcea8L,0x5ddd3ee9a24b9376L,0x394d92a4e0945e8fL, + 0xddab6752ecea36f6L,0x650b74d60d18a069L,0x37f91cebad650860L } }, + /* 7 << 287 */ + { { 0xe3e559bd9d839b3aL,0x50e8d4e9719de3c7L,0xf7bb377cea70b986L, + 0x63753cace1b2707dL,0xeb239a870e585c4aL,0xec40a379b0e32380L }, + { 0x836ebcefc86d6685L,0x703c296a70d18b76L,0x47e2c004b94aa268L, + 0x33ef7d0cbaf14d61L,0x74aa00fcd315c72cL,0xf23c789eccf5d75aL } }, + /* 8 << 287 */ + { { 0xfc1faedc310404a8L,0xea339148d3bcb128L,0xf00485456416defdL, + 0x75de7770c58653e7L,0xdd2dcbebe2f6f99eL,0xa4380ef4d159ac07L }, + { 0x45dd713ce4173608L,0x44919b61446a6789L,0x3f73756b6b962b38L, + 0x3cb9f53bbffd3f0cL,0xd723c40b7f08ebaeL,0x998a9b170c3cddbaL } }, + /* 9 << 287 */ + { { 0x261c9fe6f21ae889L,0xa589147edf3cb243L,0xd09452f71976deecL, + 0xf80ee8bf2497f6b2L,0x0b5f1b19eee697d4L,0xce9b6b680de48ab7L }, + { 0x3ad3bbc4bbf29546L,0x544406a697f51becL,0x51d44dfac2e2e75cL, + 0xcfc8625d3da3f634L,0x0845ace6a1f5995dL,0x11850d8bf3b65c55L } }, + /* 10 << 287 */ + { { 0xa804b2f089ef2489L,0x06a2a805fb22f7d6L,0x31baf4fd353970beL, + 0x3481c8b712854a91L,0xb0424eecf3971398L,0x748ef3820f4ed94aL }, + { 0x92b74ad026722164L,0x23f71d5831b1302fL,0x6741b28070a5f0c9L, + 0x46c12cfb9f5101caL,0xe7014d7901d0f81eL,0x129bd87ad758c288L } }, + /* 11 << 287 */ + { { 0x6c43d8307b00cd09L,0xb794cb012141eb00L,0x95fe13a75cf23ec5L, + 0x3de5ad7b8f2c799eL,0xa378434a025de83bL,0x07f681bba3a14a3cL }, + { 0x8fa0b5d2983ba419L,0xe477bf361781bf08L,0x5b8162845e8ce6bdL, + 0xb36a78ee199ec8eeL,0x444fc01a6062d5d1L,0xc026ab4586ee9ac2L } }, + /* 12 << 287 */ + { { 0x6a565269a3e0c5b3L,0xaab7ec7104c6ae54L,0x0bda11a7d8c6ddb8L, + 0xb7ebfafb2332347bL,0xcf791881e99dff48L,0x81600214dc357c83L }, + { 0x2a264f8931d7495bL,0x8ca430004ec885a7L,0x6d478260bb47d417L, + 0x544de4ec3d817032L,0xac7150a9dc05f901L,0xffef225775c0963cL } }, + /* 13 << 287 */ + { { 0xacb83aadb65296f8L,0x04c96c3e18151422L,0x8913311e7a9f126aL, + 0x3baeaf8010b74e8aL,0x253c9dcbb7410105L,0x30a13e42da2d5437L }, + { 0xde31fd5533a2065eL,0xde2caf1ffe099595L,0x54c762fe795076b5L, + 0x8beb51fe635ed402L,0x369603c1e5c3d2a6L,0xc5083f0700a472b5L } }, + /* 14 << 287 */ + { { 0x58805ca8d2eaf294L,0x910d085ed7d5abb8L,0xf9cbc9a1349cfecfL, + 0x67bc7b417800a980L,0xe7e6dbc0f6847e9dL,0x7a0f22c4af379c48L }, + { 0x80b6fc04b1d2822fL,0xa1cae656d8517a70L,0xd2d11ed14e9dc24bL, + 0x48d74f173fab87e6L,0x1feca5af50c630aeL,0x263e04cc62d0620aL } }, + /* 15 << 287 */ + { { 0x7dd330ca16b2a52aL,0x25133c614157ae5bL,0xe6ee0e4edd606b2fL, + 0x700840423f2b59a7L,0x58d27587d03f54eaL,0x62ebc668d34605e9L }, + { 0xa764392ab3155e07L,0xf0810f3e3c6ae6c8L,0x1b32e5ae94614cd4L, + 0x45b49262b9cbf481L,0x0034db795b3d1184L,0x463237825b1b9ab9L } }, + /* 16 << 287 */ + { { 0xf6377e3bf6ba1469L,0xc334fb6c09c832d3L,0x7f85ac42c21c0cf1L, + 0x7a3e31c9857d8edbL,0x2eb1076327b77ed6L,0x2bfbbdbc38dae10bL }, + { 0xed7c6fb17bae3b4fL,0xc5911d9f36d04e6fL,0x4dc435504569e72fL, + 0xaa82fb97bedae3abL,0x06d37bef4f27e463L,0xd0dbce6df0c35a11L } }, + /* 17 << 287 */ + { { 0x4482c7b704414726L,0x72c9cb5b26d23eabL,0x3747b8cefd5cb171L, + 0xe4ecabc300312ffaL,0x5909f29b9cf10a38L,0x209bc3f4b8d0e5acL }, + { 0xd34c84db60fac147L,0xd64dea89f8938c89L,0xb18285f8b815267cL, + 0x719a7e355a2437d1L,0x45f8d9dab769c5a2L,0x2d0e4281a412cfccL } }, + /* 18 << 287 */ + { { 0x23c14c43d8f6e236L,0xb14be0d28ee39386L,0xd3c55814262dd390L, + 0xa1b40401e1f23d0bL,0x1377b07c61534375L,0xfe4e3eb116f6d95eL }, + { 0x17b1af0040b4386cL,0x2dc657a837ca3851L,0x6862ca92ef976731L, + 0x9f0c380ba4118d3bL,0x23bf793977c1aa94L,0xaadee0612bc27d4bL } }, + /* 19 << 287 */ + { { 0xfa5e4cb6f1847a9aL,0x0e13a60cba6f07f1L,0x68d9db450ac86498L, + 0x44b02de3920ff013L,0x43724c2d84b46078L,0xb3686ee81f951b93L }, + { 0x019b3e77d712fe85L,0x313e7b7497dfb295L,0x7d883ed826d50e37L, + 0x64815565d32562ddL,0x2f9e48bed7b3e2f2L,0xc97cf156dcb93450L } }, + /* 20 << 287 */ + { { 0x0573d9963ab4c707L,0xee5d87691420fdf1L,0x41873aa55e2b9c12L, + 0xe09290456810bf08L,0x4ff4143fccbe4bbfL,0xd0e5a74969328301L }, + { 0xab5912621c4b73beL,0x550ea0633f3edf99L,0x8a77633734c93db1L, + 0x5c51d3f832b21521L,0xcee9f604713feea0L,0x0d6f8a5a7bf4268eL } }, + /* 21 << 287 */ + { { 0xc415d467009a0cffL,0x32dd46ef55960242L,0x4ccc6f676d6a81b0L, + 0xa860bcb6b2571d81L,0x7e74150991f9b6c9L,0x9a96b2f9d3a0592aL }, + { 0xcc3d821071248929L,0x586062daf1cb0f52L,0x18d993483d48b6c1L, + 0x667f17949f4e612aL,0xf1d7a77ffb3a12e9L,0xf7586397f5753220L } }, + /* 22 << 287 */ + { { 0xb87d5ce2722f405fL,0x24d1f993d7c6a322L,0x09d837291e0d8113L, + 0x70b5cdbf89a6cbc3L,0xdfb3ee16fb2c9607L,0xf0acc1163465c7c6L }, + { 0x10cef4b707e6659bL,0xc280c4331fde9940L,0xc8b5e9819a2d3f25L, + 0xc36faa763f7f68c1L,0x17878bfa8d54e281L,0x8fda8b359c42c5a2L } }, + /* 23 << 287 */ + { { 0x2aa1366305d22d7dL,0xee77da6eb0c62a12L,0xff8f99c5bacad876L, + 0xcbe33479f8a0f0baL,0x4c69bd7f4a232c8aL,0x760ce3fd485d3f48L }, + { 0x0b286a59268d7411L,0x2dd746b6589819b9L,0xe017a53060ce76f2L, + 0xe4407828d642a7f0L,0x12761e51b6badaecL,0x4f4f286b78d07257L } }, + /* 24 << 287 */ + { { 0x43c78835661019ecL,0x68e916b124e66d29L,0x02c0f3a224094671L, + 0xab6f1c05d0f17d86L,0x6d3bac72a22d4264L,0xd7b8f152f6e5fafeL }, + { 0x95627c6339447eb3L,0xfd15901879e1ff93L,0x39277c835ad80806L, + 0x758aafc90d7c7b74L,0x605ad8ca4cb8bec9L,0x6a90085c5741828aL } }, + /* 25 << 287 */ + { { 0xbc11d3d559cdebfeL,0x75c31b4531b2796eL,0x8d11e18a07b1055eL, + 0xcf522c1fb2d2986dL,0xc994c377eafcbec6L,0x840d27ebc0c0e2f0L }, + { 0xd4124d17859550d3L,0xeea6047aba21b2b6L,0xbd2a036e335a2854L, + 0xd8703d6b207ac2e5L,0x09d2244a94a34bbbL,0xd6b9481417ec6f44L } }, + /* 26 << 287 */ + { { 0x7d8ddca252aa7ff2L,0x0985e47d6953b9a2L,0xed328993dfff63ccL, + 0xbfeca5327cfa6ee5L,0x7535a871b1e6a010L,0xb0052764303c2ec5L }, + { 0xd39c72102fedb0daL,0x7ee2b384e1001505L,0xb638a1b1c82a7e1cL, + 0x1b94a47b4573fd7dL,0xef2bca7792cb2b88L,0x49ad6e97a75b21efL } }, + /* 27 << 287 */ + { { 0x591bdd0d8f4093abL,0xa2c63f1ba1322343L,0x5e548f71b32a4331L, + 0x9930891c5e7f3c14L,0xb2b2406e54c27043L,0x7ffe3e5ef1281af8L }, + { 0xc31ba363900742d1L,0xf24c8ae1e61ee209L,0x687c56b7beed46f4L, + 0x0b63e47895682562L,0x9117cf4c0c8a45a8L,0x0744a86824c20748L } }, + /* 28 << 287 */ + { { 0x9ac777993acb39ddL,0xd1d3ecddbb7c6a8aL,0xa5271c9e7a75159cL, + 0xa6ffb41f2c276e4dL,0xc526556e0bb9a955L,0xa32e1352233b7774L }, + { 0x103f124bc2cf09aaL,0x1816d1eff10bae5aL,0xc5f9197ee8837629L, + 0x064d5dcb13b1b76bL,0x109c70748d0fe0b1L,0xbb4e9743fce5f6e1L } }, + /* 29 << 287 */ + { { 0x4636f36d3ef05af6L,0x3695267b3e498920L,0xd59830285d773fc8L, + 0x939591245d3cc515L,0xc3f52a9569134370L,0xc9d0db7af8848992L }, + { 0xcd1be9bf15906eeeL,0xa95d25fb916d576fL,0x08de893be152fb62L, + 0x65d743658ab1e35cL,0xd6d97057fef14ac1L,0x67ad47b9574508c7L } }, + /* 30 << 287 */ + { { 0x1b403c4f1470433eL,0x6f8cb19257e53eecL,0x87b5b93df0cce4f5L, + 0xfefaa5008c566f77L,0xf6aa8066db71517bL,0x9f01b036d67f5952L }, + { 0x9524306faaeb40dfL,0x5cb2e8e1421350a6L,0xa57d05ea3d69040cL, + 0xd0ff12a1b9bbdcd8L,0xed64d3259e3e19bbL,0x29509c0fed0a490dL } }, + /* 31 << 287 */ + { { 0xc94191e7a607c050L,0xb918a096b98d3d4eL,0x97413dbce3f253f3L, + 0x8476c03cdc6d8418L,0x50247d1d2402202dL,0x077476225f8097c5L }, + { 0x1457ab609b71c6d6L,0x9ff312c447cf0c94L,0x954dce23ee79d2bcL, + 0x3ba2b1a4a0da6e48L,0x363df36f532be9f6L,0x816642ddc742c7d4L } }, + /* 32 << 287 */ + { { 0x6edf5561ff8b1fbeL,0x614b788ef6eac0c0L,0x7699ae56d8d66d29L, + 0x5f81602ae9d58eb2L,0xd0c04874faf9176dL,0x4b3a0046523153b1L }, + { 0x9690930ff6315883L,0xa81c0b44a60ca92dL,0x2d0e725873bcba90L, + 0x57efe72de902e329L,0x3fcd598676bc27b9L,0x492adf0393940c09L } }, + /* 33 << 287 */ + { { 0xf2ab8e22973a4b6bL,0x6a96f2ef6ad73ce7L,0xad5e22547235e929L, + 0xfab3e4a9bc6c3b76L,0xf69fb2062dc950d0L,0xd863ca9049478ff2L }, + { 0xec669f122749fabbL,0xe1d28bdc71a6d279L,0x766ee6458372942dL, + 0xd118b90480ade5ccL,0xedcfb0a72293740bL,0xa3ee3a67f16b29cbL } }, + /* 34 << 287 */ + { { 0xc29fb53e118a0c7dL,0xea7a1017193b834cL,0x678072a2cec93ecbL, + 0x9054d6b72475dedfL,0x4a7d477342ee616cL,0x05cec7f8680f8a43L }, + { 0x39c491d496915870L,0xe07a2b1d8746edeeL,0x1d8ed3c83566e7fcL, + 0xc7d744e5e002298bL,0x8a0acec99c0e6388L,0xb2daac39ebf48fe3L } }, + /* 35 << 287 */ + { { 0x773ad1cb8e133d97L,0x1e29f5a2872523d3L,0xa2a742293a09c1ffL, + 0x809e6d284369ca06L,0xf22e521a7fe148caL,0xbaaf90c383ef9578L }, + { 0x65aa9b54d633b2d5L,0xe55f2ce29a2994a8L,0x8a0af446e67e0b85L, + 0xb9714de9c1f062c8L,0x1f4047dd2a3aa1d7L,0x39658ea965179222L } }, + /* 36 << 287 */ + { { 0x0322b29a57fbc5cfL,0xf55af7863078be9cL,0xd4b186e6ecb59f79L, + 0x50f5fe746d950733L,0xaf8a1898a9f90d02L,0x483801a742d6d9bfL }, + { 0xf0a0af145ec09c0eL,0x85af0e6188383360L,0x404b295e42592235L, + 0xb3199d63c596493cL,0x7aadacdb194abb80L,0xac84563ec1c845c6L } }, + /* 37 << 287 */ + { { 0xd78d1dae5336e58dL,0xa3f36e0bc5ff354fL,0x8421f95e5d1ed78cL, + 0xff4c16019f360c43L,0xd5efa09f8bb582a1L,0x0ece005aefb39652L }, + { 0xce8bb58036c2c940L,0x11f8f74bcd1ae8ccL,0x923c350b57a2f2b3L, + 0x2438e3213c86faacL,0xe76129503e230776L,0x35c73d415e6158e2L } }, + /* 38 << 287 */ + { { 0x8ffda4643672507aL,0x76301be7dd91327aL,0x42720bb0958860bfL, + 0xedc0b8945ad4f455L,0x2fb553201bfbeb4dL,0x22a425bda1c6494dL }, + { 0xfb927a85de0e7f52L,0xb84a82cf49a4b6a1L,0x8afd0546b640fe0fL, + 0x23b78fbed2fc15cbL,0xeab469c26742a49fL,0x308e453fe277c7cdL } }, + /* 39 << 287 */ + { { 0x60ce0f55af7b14aaL,0xf2577fbe5cf5a2caL,0x7bb9521fabf3bb41L, + 0x68b6409def00287aL,0x700bf423bfaf9391L,0x98e6c3017d637300L }, + { 0x342ed4870ce28aeeL,0xad8b8dc383b059dbL,0x1b8a892b85d0a485L, + 0x553c4fad6b7a7d3aL,0xf5692acc198d0379L,0x6004ebb3ce932f00L } }, + /* 40 << 287 */ + { { 0x6895dbe2f820c195L,0x3787a5003f6c7b40L,0xdc718243ac1e90f3L, + 0x352f8c91ba5d0870L,0xf3d1c53eec0112b5L,0x08a0782f6b84f64aL }, + { 0xd659e6358eedd5d4L,0xfc30df6c29537276L,0xbfb09978a1755ce0L, + 0x227f7b12aa2b4187L,0x828730b9226539d2L,0x9051a37cb2472c95L } }, + /* 41 << 287 */ + { { 0x430c2a45d0a0ddabL,0x916aa68926a6291fL,0x9db5510268dff24fL, + 0xa22121c1850a7aabL,0xd43416194e2d9670L,0x7ef2cb9415cf7636L }, + { 0x2cd6ddf6bf97b27dL,0xac5676b625aba9c0L,0x3ca96f7ec4ee110fL, + 0xc6900abd08e7ebb4L,0xcd3942fbdcb91135L,0x62d6b6f6a8ad56e2L } }, + /* 42 << 287 */ + { { 0x1ec7f2410828d35fL,0xd94c2a926ccae554L,0xdf4227273c36ecedL, + 0x2facd6d89fa6582bL,0xed43247ed349d3beL,0x1d59d55d1db6fcc6L }, + { 0x2b5074b1ee1bea38L,0x025496aac9c21a8fL,0x57dd7fa1d1d817edL, + 0x57b5572aead03124L,0xdc024be87314616dL,0x5bb5b23c10f6e38eL } }, + /* 43 << 287 */ + { { 0x643cb9cd53812134L,0x016a11e8092ff9b5L,0x227f3dfbfcde37bfL, + 0x01b9bcebe8a8fc6dL,0x7009ae45e1da0dd6L,0x193b6f519e2908f3L }, + { 0x28656302230db5feL,0xb0a730c41aaeee73L,0x028320ab387addc8L, + 0x92165d909a92488cL,0xb0b2f8f09066c95cL,0x0fa55db564007634L } }, + /* 44 << 287 */ + { { 0xbff4fe0844284b10L,0xc7e3f8da19c2f775L,0xdcd97e54a45ab746L, + 0xf53158a9540ee8a5L,0xfd19068728c4aa74L,0xa3447e30648fa2e1L }, + { 0xa6794670c374cedcL,0x605629c258204248L,0x1b86f8e6f7d8db3dL, + 0x1e8ffe8bff0f38c9L,0xe4a556b8e274c82bL,0xb31406c94c0076d6L } }, + /* 45 << 287 */ + { { 0x198999821e555a0cL,0x831e923fbc196442L,0x8b294623f682e135L, + 0x79ba90c01743c6e1L,0x74f8dbafeff5ed22L,0xe4c3257d5c010835L }, + { 0x9cf94a208f9ec66bL,0x9fe9da3ddc303c43L,0xa53870be0cb716daL, + 0xc322ffaa2aef881dL,0xb9ff76ff0fcd5580L,0xdcc125d49ebb1d7dL } }, + /* 46 << 287 */ + { { 0x747b6b6ddecaf88eL,0x1a32f8ba368cc7caL,0x52a3a00f60d84fd7L, + 0x60052af507adacf7L,0x8b7bf25650b8de16L,0xb8b2acf8194926baL }, + { 0x4bda72c81d1ef524L,0xe350f73288993f96L,0x63fee4e2e08c5d39L, + 0x1f2cd9cd5db46904L,0xbf11ac311668d3bcL,0x8eaa064371d721aeL } }, + /* 47 << 287 */ + { { 0x33cfdcb3e14210feL,0x4abad5ec4946aa01L,0x14b42417a8cb53b3L, + 0xeebb0d70238d4edfL,0x8c9d87fdb5bdb30bL,0x3cc680f17c928b33L }, + { 0x4b2b2358757c2607L,0x51a70a33c1c8dedfL,0x62a26d776b22d113L, + 0x2f4acd62ef3b4f5eL,0x403e91bf6ed00636L,0x219ba3577bf74d3cL } }, + /* 48 << 287 */ + { { 0x7de743e2b39317b8L,0x9205d4472d372acfL,0x8226fc303eeb0012L, + 0xab2a3e052af74be6L,0xbe4767804af91ac0L,0x98497c710ca36bf4L }, + { 0x74fdf7cd8d6dedb4L,0xb50778eea0fc5919L,0x5d5ec33f2fcd7c63L, + 0x667b81937f33cde0L,0xce48ae4b38364d44L,0xb8578963223ed67eL } }, + /* 49 << 287 */ + { { 0x3e5688e46bfd7adeL,0xb3f1eb051b80bd4bL,0x8626c4cafe3de456L, + 0x8846bc714b7e5444L,0xa54c7cff689e8a67L,0x8c3ea61f43eadcf6L }, + { 0x924f17d6fde15178L,0x45319eb705c08d2dL,0x6d55775d9f85dcbcL, + 0x2aaf9f7405278280L,0x574a13e77b617153L,0xe7fa921ae8b15bebL } }, + /* 50 << 287 */ + { { 0x9dd54056514e343aL,0x8d9116dff12aa25fL,0x5322ec38e3397844L, + 0xe1843921571036a1L,0x2cde0a48650beb19L,0x41ad4a7e4f259728L }, + { 0xf314fceeee6448b2L,0x80006b2aff0e81f5L,0xb5ee5524d51d229aL, + 0xeba6d733128e900bL,0x79278cb8030f391aL,0xb24bcd63a9a5f9fbL } }, + /* 51 << 287 */ + { { 0xed867a7b37d10743L,0xd57d2d8df510023eL,0x4d500e4c737e0a50L, + 0xcfa119900ecbf795L,0x3ac126b89373bdaaL,0xb06324fb735449a1L }, + { 0xfe321df5cd79de70L,0x52d625dbfd07c6d4L,0x88ff505a3d628e51L, + 0x120350fab044d725L,0xf718b20ad02f9515L,0x766698630bbea1b2L } }, + /* 52 << 287 */ + { { 0x6293e0ff50d9bda1L,0xe7259ada433b4dd3L,0x39aee63e821cee67L, + 0x4d707c7144b10739L,0x42b9e0f69bd6efc3L,0x7d71edcc0717a61dL }, + { 0xe7df9e56d1e5a5bcL,0x7895b638ddde509bL,0x6fc597b3d2a6a822L, + 0x022da65d96d2a8abL,0x95541ce7cff45c72L,0xa5bb7799e649800fL } }, + /* 53 << 287 */ + { { 0x7472e4c963676cd5L,0x2836b1d52687f376L,0x1460b664f732a51aL, + 0x7c4541f22a214ae1L,0x743a524d107d6622L,0x9c64e3ff082fc015L }, + { 0x9341f3fc8e0d13bdL,0x9946043e529554edL,0x6fbbbcda5798d6ccL, + 0x3bfad5fb242115c5L,0x1f46bd1945ab793cL,0xd9383bcf3b42f81aL } }, + /* 54 << 287 */ + { { 0xe4ff888f820a13b5L,0x7cd18b3eaf1bfbbbL,0x3fb7f681bd4e4dd5L, + 0xaba364c287d46c40L,0x44e209ab659b3498L,0x5e071a272dde85c1L }, + { 0x8a029b1fb969c790L,0x51bab9f0c6fd1c22L,0x9ee9b047b83eb0c1L, + 0xda0b39439e5b2c35L,0x0cb30625f20ca425L,0x8e4dbd013d25c2c9L } }, + /* 55 << 287 */ + { { 0xe7aa41a96b8f7599L,0xe97ff24a3f556ad5L,0x10e07713dd6a9329L, + 0xaf464b18c4d06a93L,0x9b8e5145a1ccc85fL,0xa256680bd0487ca6L }, + { 0x420b60bf815652f1L,0xeaf09eff5bb45b6fL,0xa31e875f8845a557L, + 0xb035ee09eebe0911L,0x1402d1d86531c356L,0x24aeeaf0b630f75aL } }, + /* 56 << 287 */ + { { 0x4b20d1829567f5f4L,0xde7e814918f02b34L,0xc9a4be7becff9dd7L, + 0xe2f70bbe9812fd3fL,0x471bf90c9c889263L,0xb60d01b53e61f5bfL }, + { 0x258c7f89d22d855bL,0x35ef5c15b75a7d4fL,0x26d8e1dab247f27dL, + 0xcf1361998d0f7757L,0x312447803f8e894dL,0x8d2a20bae1a3d47dL } }, + /* 57 << 287 */ + { { 0x6447cc97f08a0417L,0xd98ea6837afee809L,0x81426d20bf7990aaL, + 0x848bd6223526ad26L,0xb6cdc5b4fe1f3381L,0xe7e10bc7a26189ecL }, + { 0x25a9f7cf57464e6bL,0xf90c1aa12c86ddf0L,0x2126ed530124705fL, + 0xf384e7e5b58e6341L,0xb2dfeb0a12207e57L,0x72875c55e0e23287L } }, + /* 58 << 287 */ + { { 0x37579c3eb954b7a4L,0xf0291f8f3f2ea608L,0xde68104f90a85ed2L, + 0x6a35fea9e1088788L,0xe8d5517470d15d00L,0x0bc72de552467f90L }, + { 0x2ded3293297be2b8L,0x76c53e5761ddc65bL,0xae4b2b5015562d6aL, + 0xfe7cdd329e0aeb79L,0x98ef4c518dd474ecL,0xfca56ffb0076b23aL } }, + /* 59 << 287 */ + { { 0x120adcba6f60309aL,0x41e46edeca8ab2c7L,0xd68aa4c529b79ce0L, + 0x21a21f8d7a3b11fdL,0xea68dc4739d0809fL,0xd4faa71a27973044L }, + { 0x65b42172810be134L,0xb2dafa6c793aee92L,0x951e9f6f1f78f7dcL, + 0x2affc70a17fdba97L,0x4f0f4c51dcaa2789L,0xfde1951c9e703980L } }, + /* 60 << 287 */ + { { 0x80826a196488d9d8L,0xfa452795f3ad867aL,0xdd9bf8f5bd4e6674L, + 0x324386227e8e3ee5L,0x7af4c605dff05c96L,0x79efb6f9541cbbd2L }, + { 0xeb5ff62675e78961L,0x5318c4c30be43d7aL,0x02df456daa4a0562L, + 0x4d6002d88a916a81L,0xf0dbc349f68eced2L,0xfd75d4d5ec8c3fddL } }, + /* 61 << 287 */ + { { 0x6c15d903544378f3L,0x0a9bc9d735ea3c77L,0x9d9066408caa4acbL, + 0x9ba27502402be833L,0x1ed4123f8773fd7bL,0x236364ba190eac92L }, + { 0xd6287f17f8383ee1L,0x75b7b0b5d9739582L,0xeb6cd50d0292806eL, + 0x216f36dc43448409L,0xec136f8cb6c4958aL,0xfa805ab49ef7810eL } }, + /* 62 << 287 */ + { { 0x5c6448f70d00b29aL,0xaa134b87124cd55dL,0xc2c6b269d94b72d9L, + 0x0f0dd472412f76d8L,0xb4cf3c1873f6571aL,0x6aed00218b9218ffL }, + { 0xa55b74eaa0c9dde9L,0x59b952125b4c8fccL,0xbc9873ea4ddc367bL, + 0x26b369ba0fd30421L,0x71763a45e446f4fcL,0x67e800edaff54707L } }, + /* 63 << 287 */ + { { 0x4de97de1126b4919L,0xd631d908883ea109L,0x37c77d729f6ec50cL, + 0x910932e6df718c7dL,0xa798406855028d0fL,0x21b09540a6119a26L }, + { 0xb837cceced4b4962L,0x3c83f4bdba66002aL,0xa067aa3d2ac41124L, + 0xa64bff30d08dc360L,0xa22778a5c108d3abL,0x7f732064aac4dee4L } }, + /* 64 << 287 */ + { { 0xc68b641ec795a2c7L,0x4fe559b15a4d6647L,0xeda98cbad89ce668L, + 0x15f84dc06c269d8eL,0xf0eb685ecbf34023L,0x3668c530c032634aL }, + { 0x2e3d7fffe4531f59L,0xe627030685494d06L,0xf02cabcfa3e050dfL, + 0xccd2da67c001dcd9L,0x50aa3723066d2d52L,0xdb0756507224a41fL } }, + /* 0 << 294 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 294 */ + { { 0x04418b5965b55050L,0xa8a797c3d324aa67L,0x5f87e22c7c65a6d9L, + 0xaac710651dbeffe4L,0xff619d64bd3cc05cL,0x9a29c966e65c92c4L }, + { 0x23af2b21dad7fcbdL,0x4950a767153b817fL,0xc34a7efac6478c55L, + 0x57cde95af6cd140eL,0x64b74575f5a0db2eL,0xd4b5ea5275d7fb76L } }, + /* 2 << 294 */ + { { 0x284050628e72aafbL,0x655bf3538ea8bf00L,0x789d944405547f7bL, + 0x7fa445ed3441e472L,0xfeb198254a44ce87L,0xccb5f12c129aed14L }, + { 0x22b05de3af94fb34L,0x7422a040d3f03199L,0xfba252caa83f7f08L, + 0x0f6ad6e6cefaa757L,0xe1ad18716517d806L,0xd16dc8ed8e9d97adL } }, + /* 3 << 294 */ + { { 0x0208092a0e3dca68L,0x9a49bdccd1a09971L,0xe5194181aefab9c1L, + 0xc1c9690a0076f47cL,0xd7499e95b486c2fbL,0x83a69e43d4b72e00L }, + { 0x75f2838a2d1a6c2bL,0x57a24c69751f6366L,0xd956ee08626cc684L, + 0x434cadd7e6ce3249L,0x3d4eaececfe289bfL,0xbbd53b961b8aafddL } }, + /* 4 << 294 */ + { { 0xcbb99194a3736eb6L,0xdd5161cd36dcf470L,0xd50b24aab6ab6c03L, + 0x419d2810bc41f4b7L,0xe2e88d7a295496cfL,0x350713f2f2457ac0L }, + { 0x838e4a360427e2aeL,0x7631472a4d974e5aL,0x9fa3ab1c7a5c5fdcL, + 0x324798cdde34cb8dL,0xbfa5a9d0889105feL,0xd05dad34fd0df249L } }, + /* 5 << 294 */ + { { 0xb47c1d47d6a3a1baL,0x99bb7e6572f65bd5L,0xf251794578abfda2L, + 0x827f2aba3e3e3420L,0x436ee73250e2de70L,0x5c9ac6dc10eca926L }, + { 0x2ec67465181f5e18L,0x1e8f32fcc6c83d02L,0x9dd3aeaf3953bd81L, + 0xca955f4b07086daaL,0x7b4b6f3fd14eaa88L,0x562e75f1148d826fL } }, + /* 6 << 294 */ + { { 0x536e5657cb419fc3L,0xe8c208bc1d271dd1L,0x6a3713bd22d2b9adL, + 0xa4c761a7471d808dL,0xd93aafb67e6dca35L,0xc46c0ae38f55ca32L }, + { 0x55dc0de7a78bfca0L,0xe9cfb3013407d0caL,0x777e2a60b3256c14L, + 0x32b2238c6d8fee02L,0xe8b3539646e43ee8L,0x310bc1ba247985ddL } }, + /* 7 << 294 */ + { { 0xbb9bce6810168f49L,0x32edc368717445e3L,0xb0b5a04426aa3ff2L, + 0xc671f1fcd166542bL,0x3142864df61d2523L,0x11b2dfc7b0c67410L }, + { 0x2e031a05c99690a5L,0x4782fb749fb7bae8L,0xeac2cd506b7175acL, + 0x2e116782bef2313aL,0x67992027241c4d2dL,0xf8aa0e09a6952d9fL } }, + /* 8 << 294 */ + { { 0x9974759c581f9d3cL,0x9e76a970e5cb1973L,0x8afec58ec64941caL, + 0x2d7c57fa01d05575L,0xc07c74cc5c448db5L,0xa52474ce01bb1440L }, + { 0x93162d9700115bbbL,0x483b6147fd7480f9L,0x4f28c57e6af18dedL, + 0x36faed8f174a3089L,0x702dbd64a3dd6265L,0x86a9c43f6adc0d7bL } }, + /* 9 << 294 */ + { { 0x9d4d4b3c795eb646L,0x727e2aa17485839cL,0xb50018a5aa9250baL, + 0x5a15808d1ba716adL,0xb1748d580ff91cebL,0x0131bcff76144b6dL }, + { 0x23fea4a58dcccffaL,0xe8eddb5ceb64caaeL,0x011a65971c3c5e66L, + 0x7723dfba377a8f6cL,0x00167c71dee2f651L,0x3e89ddf5ee0e4325L } }, + /* 10 << 294 */ + { { 0xa3510710b9de7b63L,0x9f364ad14019c9dfL,0x5b66a5d79b5bdce3L, + 0x2b2f695178b1b385L,0x3e4783d33cfa9f99L,0x1af517506bd6bcf4L }, + { 0xf9c0686a81d8d7efL,0xdc0f22ec37c068d3L,0xe1b8665393545fafL, + 0x37ca8501a8a52881L,0x07ac5c8a5603e359L,0x98fb2bab542cc937L } }, + /* 11 << 294 */ + { { 0x96326ec323da6b81L,0xdb48a5e1f90a6f83L,0xbb141660f640a0fdL, + 0xb51609375b92f5c2L,0xaaabd54c997244e4L,0xbeb8ab2f859bb92cL }, + { 0xcac7c5dda4be476bL,0x7093faea7f58c1b2L,0x3167a2c45c6ad412L, + 0xabd86bc9544fb9a7L,0x571296a72448c363L,0x4da64cd9c6cd4621L } }, + /* 12 << 294 */ + { { 0x4981be690c5bbd3eL,0xb047df0a185fdb55L,0x3168e05074cff00cL, + 0x111150a1b52c7f9cL,0x0db2ed84a51c7986L,0x7d991630e61272adL }, + { 0x7443d93628de14ddL,0xfdf31f41a5daed5fL,0x71e0ef4e866b5e40L, + 0x05c57a45b965a670L,0x85bdb58c70e1aa77L,0xe4d1fe2a9df3ce32L } }, + /* 13 << 294 */ + { { 0x6ff2b1a1772c3796L,0x9b88c1178e186fe8L,0x342ba11f4312af31L, + 0x9a93a4d1a86ae2b6L,0x496d5f219d59e3feL,0xce519a7d6924acdcL }, + { 0x6fdef82327c46e44L,0xab5504c34d31c9bdL,0x6fa52bca71693677L, + 0x31221119033c80f7L,0xdb2cb49dc0a22f91L,0x4962d58f9b4aeb5eL } }, + /* 14 << 294 */ + { { 0x5d4618982f722563L,0x11d22b39567db14cL,0x9a8f004e6779cd40L, + 0x0812ae3d5473ecd5L,0x4ed828624e6c296aL,0x2d9ce40c064ee61fL }, + { 0x4856d586d8a9eb1eL,0x2ddd6b125d1b5e3aL,0x0ab5eec0382fba3cL, + 0x302018dffcf4a9c8L,0x7b4e6fd2ab3cdedbL,0x266c246a8f64cb1dL } }, + /* 15 << 294 */ + { { 0x55bad54bd6dc35e8L,0xa43d72ff38642612L,0xe39a191609bc85ddL, + 0xc9d4bc9b0f85d3baL,0x84cd12b61367a70cL,0xf4ebc0e04937bb2dL }, + { 0xd083145949dc027bL,0x110751601cf29970L,0xa443a29c0b76b4c0L, + 0xee5b8d0ca0de3249L,0x368aa3259002e7d6L,0xeb48afdc6182e2e4L } }, + /* 16 << 294 */ + { { 0xc41e4aedf5c3af59L,0xa0284ad06de9a78aL,0xf5eaab7b8ed812d2L, + 0x7801fbb81afb58b8L,0xbe5cdba671efcc3aL,0xe31a0e3ccd10cb91L }, + { 0x882e821e85dc0bc6L,0xd3ad070fbb32e506L,0x3afede2bd8a0f038L, + 0xe20a117c857fd3a0L,0xebaa2aa43060f767L,0x6524aa0d2b9d1da1L } }, + /* 17 << 294 */ + { { 0x86aeca0ffd81174dL,0x19bc6ee60c6eefc8L,0xc85f7f2ea91f0e19L, + 0x09b9276ad2354dc8L,0xb62adee0542a669aL,0x8354ad1a88097445L }, + { 0xe67d2834df9984a1L,0x2330c8cfa64b2864L,0x309dcdeb39e7b54aL, + 0xbbba4737a18cf5eaL,0x47511b1d92861a8eL,0x99d4bd673286d404L } }, + /* 18 << 294 */ + { { 0x9cc5847c88cffe33L,0xff726b0f6e8eb6c1L,0x9bb2ca161bc45d8eL, + 0xe7903009a6d8a5a6L,0x4f089cc047db2201L,0x4135884de6b5928aL }, + { 0xb1a86a0ae5c017cfL,0xb1d9bf6db0a393dfL,0x33d9c1c628bb3277L, + 0xcb05b67b45b582ceL,0xa72585fcf33792c5L,0x78b7c5e8a7d1ed84L } }, + /* 19 << 294 */ + { { 0xbb83b446b1b4a091L,0x66440b3d9603d875L,0xd1931f33c2b45d1aL, + 0xb8b67f20098d4cccL,0xa3583818790f208aL,0xe01194bec4a3e88fL }, + { 0x29301bb192e8b150L,0x1795cabe9448ee60L,0x377d8f9752500c48L, + 0x474e73d65a457e79L,0xce0a50ef30159027L,0xfe69abaafbb2c214L } }, + /* 20 << 294 */ + { { 0x70e478fb9346df25L,0x01dc0c2eb4a4ada5L,0xaec82b005be36ea7L, + 0x82618b8f6717e06aL,0x2db1f6d4008f1977L,0x4e493f3b16b390d1L }, + { 0xfe86fd4d990a75ebL,0xa1cf7f99783f6076L,0x6cbb23e70c049158L, + 0xd05be7e5ed456235L,0x601374069bd836efL,0x94ec964432e5f604L } }, + /* 21 << 294 */ + { { 0xd96e4d920fc48c7bL,0xa2e29660f66e491cL,0xb92d850601146906L, + 0xa43f4803afe346d6L,0x27885d98700b6bccL,0x90662e9f595d8de2L }, + { 0xefa7f261f70d1007L,0xfe8a8be3fc72531aL,0x3b3f7541f1aa8d93L, + 0xb31bea258215966bL,0x15faa4acf35d2be8L,0x0a5f95e786c9a45fL } }, + /* 22 << 294 */ + { { 0x3361e1ce3d87bfa8L,0x92f235e78dcca4f0L,0xc8084cb4be323fd1L, + 0x3fd481a5c24c6d16L,0x9b1bd9402cea81baL,0xf50911910c5aa59fL }, + { 0x4cd8c9eff81d5e2aL,0x5ad000131550bff4L,0x29d47b9f8cc32e55L, + 0x66e3e6f111694eceL,0xd5edf7017950dd7eL,0x9ccb10960f6350c6L } }, + /* 23 << 294 */ + { { 0xc31e47ff95e784e4L,0x7ad0dfd63fa14241L,0xc91482092dab896eL, + 0xe9a114cccb9bb463L,0xedce9e6f16cb16afL,0x0ee2ce0607508893L }, + { 0x1aedb80ce31c0f54L,0x235d4591512658ccL,0x9029fad2a38583f1L, + 0x95b1e1ddebef898eL,0xeb2f21809efabef3L,0x458c4338b10e9cbbL } }, + /* 24 << 294 */ + { { 0x09db138d18f2470cL,0x63bd2290f613658fL,0x0bb647794feebab9L, + 0xfce4aee17fdb1e71L,0x7d5c0c61a7f1f65dL,0x46405b618d02d6cdL }, + { 0x7cac04856fdcb0d0L,0x85224c4b2f8ec5afL,0xb5879a59db0aa864L, + 0x75f391b8ff94f8b5L,0xa6c994ae49c97f8eL,0x4d968fadd690b232L } }, + /* 25 << 294 */ + { { 0x1e436df6e11a616aL,0x9eb49c76bdb932a8L,0x207d2fe90e6591aeL, + 0x6e05acc8233ac034L,0x464dd321f3d04d32L,0xd4ba4889af43c171L }, + { 0x0808e5207120fab9L,0xb9e4726c3fbac672L,0x5dd1c13b9d7d883bL, + 0x1c091808771f1edbL,0x76988d1c75eac1a5L,0xb0fcd3a893a67be8L } }, + /* 26 << 294 */ + { { 0xf5cd290a67e0b4e7L,0xaa6fa6807c1594b6L,0xebedfbd7b63270beL, + 0x574b410ba369bfeeL,0x431cba5a020ea888L,0xd3a3102f56c71d47L }, + { 0x4894bfe0a90a853aL,0xd78bd98b5f9c4b6bL,0x9b1324f6d900c5c1L, + 0xc65c944d718c2147L,0xf661de6ba987f634L,0x0315e69f172628d8L } }, + /* 27 << 294 */ + { { 0xb12e0ab8aac7ab64L,0x8ce877abb06cf9cfL,0x39b694b40bb11fb4L, + 0x0c2428369b0d8850L,0x6bc9a033ccd50c6eL,0xaa2e77739a1e8fb3L }, + { 0xa7d8be09608e2e9cL,0xeb4cef0542b9f458L,0xa7268c9b985f66fdL, + 0xd60eeab27acf4968L,0x02eb2db3b6e5621eL,0x82fb4abfad8236c4L } }, + /* 28 << 294 */ + { { 0x07c60c7522ea5f1cL,0x35beae34a36bee4fL,0xa8b00a09dcba8997L, + 0xa77f1f3a802ce50cL,0x6c4050df2a2144b0L,0xf79bfa96ab1b10dbL }, + { 0x9025d470433a9b1cL,0xaf3e391790d9eec8L,0xbcad2d629ae2d535L, + 0x7a152829eff0f6a9L,0xe87345cd925fa5a0L,0x6ce007200e84039cL } }, + /* 29 << 294 */ + { { 0xc65acf36c3d095d2L,0x9192c5fe72427e6cL,0xcb84c43c3fa8b90dL, + 0x2f458fe965e15b23L,0xd8bf193731469f11L,0x1ccd8bb93638cc3eL }, + { 0xa067022f78e35577L,0x382e6af730ee676dL,0xf197adc2f6d135bfL, + 0x06360834c9a1cf58L,0x413813f7930371beL,0xf7461d04f5dcaccaL } }, + /* 30 << 294 */ + { { 0xdae449c007f6a05aL,0xbc1b84f55bf26c9eL,0xe3b3f9edb1c13820L, + 0x5442ad5b4090598bL,0x794ef65613749e4dL,0xde809180948b71c5L }, + { 0x4c72dc7de203c5b5L,0x8902b0971b349fc4L,0xa899bedb225a1569L, + 0xeb7da73de6ff3f53L,0x6ee8e1607c0be37bL,0x9ee667d2a31bf943L } }, + /* 31 << 294 */ + { { 0xbc91031108b6fb2bL,0xa5e0ab3e25e06a55L,0x16ff0705360f1698L, + 0x71c0aa7487e72a67L,0xa1f1497b355c75e8L,0x179b67bffa6bbcd7L }, + { 0xc9db6590b6738583L,0xf77660c4d87e72bdL,0x0ee2e7b3f13abc2dL, + 0x0cdf5a37a4d922b6L,0xaa8af2d596c853a4L,0xdc452af4e0092356L } }, + /* 32 << 294 */ + { { 0x5017e145db81146dL,0xc7d2086d45c54db8L,0x2541059dfa98234aL, + 0x4bf344d99985af98L,0x39737ed67b5b7b1cL,0x8e24691987c411adL }, + { 0x2fad8cedb877a75fL,0xe42352df17e60ee2L,0x1a53d856404043f7L, + 0x6c1f07a5863927a1L,0x38d3a4f4b6892121L,0xf4c1092001976c8fL } }, + /* 33 << 294 */ + { { 0x541732a70224214aL,0x61617b515cb2d019L,0xc560c24bcb4fc6b2L, + 0xd0ad737943670d99L,0x08cdd32eb83112a8L,0xbe57493d7e29810fL }, + { 0x7834124899d4523fL,0xae1a5857cc8e5fb7L,0xf8b62a59b8454efaL, + 0x7c63c900ab0f4729L,0xeef9243d72dd0f5fL,0x6b865dfbad766386L } }, + /* 34 << 294 */ + { { 0xd11536eefee626b8L,0x1d2471dd8077b5d4L,0x7db062debdb9a4dbL, + 0xfcc62c0ab9f808ebL,0x619b54c6ef392bc7L,0x81e146fc51b9f5c9L }, + { 0x0343807c7bbd52b3L,0xe024a9f1572125c5L,0xf8b886d86c57cb31L, + 0xcb92aa7d5398a318L,0x4ce0870d2410ef34L,0x1a40c103f8366683L } }, + /* 35 << 294 */ + { { 0x46485baa7bb78552L,0xc0f685f23e6a3f0fL,0xd24970b5fb3cc0ecL, + 0x0d1f380e7bf91feeL,0xf0f7fcafe7624351L,0x27cb99bc697a8055L }, + { 0x55be14685cdc7560L,0xf006927927ba7f93L,0xb0c25c759fdd0e70L, + 0xda82e73785818253L,0x7d40d86946304c51L,0xe06ea6fdcc18ba58L } }, + /* 36 << 294 */ + { { 0x99d37ade6b65e17aL,0x61ca538e38ce217cL,0xd3ea83f68ebb89edL, + 0xce6611eb4b02964eL,0x0ec7cc2f5c0a8e44L,0xa985b0c2974240a4L }, + { 0x7a3abb6c42ee5b0fL,0x55f049a0cb2eddadL,0x69348b027c44a60cL, + 0xcabc65191974a8c7L,0xd9def4bc07b91a35L,0x684a2d71b93b34c3L } }, + /* 37 << 294 */ + { { 0x21c37d21f48f274cL,0x2de96b4da082a098L,0x82520e0ca606b6a6L, + 0xf76c9ec6e1050b81L,0x248c5efbd1ce149dL,0x5a36ae1e9a909790L }, + { 0x8790b09bec8b43afL,0xd592dce560ff709cL,0x726d699724cc8e21L, + 0x61e37bef5e2cb745L,0xd55a68c26eff3ba0L,0xd47f02659ad265c0L } }, + /* 38 << 294 */ + { { 0x3e6351ef3932ef94L,0x65625878db5d64e6L,0x118a688e091ec7b7L, + 0x2a95072abdf60b88L,0x5200703540dc0afeL,0x59c3d90b6fc1cbffL }, + { 0x5622b1b21dfb1a7fL,0xdcb0344834d92243L,0x18fccfa86d7d36c4L, + 0x5d43a14181341761L,0xef375542eaaee79dL,0x4e4667216999d399L } }, + /* 39 << 294 */ + { { 0x1bca97aa9d3c6b9eL,0xb4bb4f95095cb250L,0x4f2c216a996fb52aL, + 0xc4d01916f379790cL,0x510882a4359df53dL,0x6457d76a671d6a8fL }, + { 0x0ded2623061f7d64L,0x3cb4f38f1ce7dcf2L,0x0d86313a224ffa88L, + 0xba8a15012b99aeb3L,0x2fb92183d69f72b5L,0xd3b9d6daf1fdb8f0L } }, + /* 40 << 294 */ + { { 0x5d573a3a0b6320aaL,0xf9ac8ccf289b6700L,0x8bad05cd8f28dd72L, + 0xe2eabd446b62c306L,0x60f70353906ef302L,0x147cdd0c367a768eL }, + { 0xea9d871635a9e846L,0xdd71e80aa8684430L,0xa56a5ccd530768a8L, + 0x59d241270a3e42f6L,0x707cbaf0faa367d1L,0x5419b14f52a0cbd0L } }, + /* 41 << 294 */ + { { 0x625bf4e6d991d842L,0x56b95a56a81daaaeL,0x2101137c9911bdadL, + 0x1141b0a1bbded1c2L,0x85deb889d1df8d43L,0x51e3e17edac3e376L }, + { 0x5d31639381fb19f8L,0xd1cb634b92eed2c4L,0x72a6ed7b943746dfL, + 0xd55f55fb22b85e00L,0x255b025804193aabL,0xd0b94c5d86a78c96L } }, + /* 42 << 294 */ + { { 0x121c15d859c3556aL,0xabe25c21864380dfL,0x2de101832627f78cL, + 0x19988e4b4bcf4a0cL,0x4ed3aad8a2f9cb52L,0x50f8cef5b2b257e1L }, + { 0xab0b000c49f7f596L,0x6cb997471fb9c471L,0x331974b95fefb8f4L, + 0x57cf97578e2e0e5cL,0xa82a8d06174a626cL,0x40ef371b03e80567L } }, + /* 43 << 294 */ + { { 0xfea713e1324cbab8L,0x738885e61897e7baL,0x8234ed08126aaa13L, + 0x4f66467661ed1548L,0x61fdc2aa172c432bL,0x78eade7c9ebf0a29L }, + { 0xd50ae7156aa104a9L,0x977d7a605536df98L,0x024014bdc9eb983cL, + 0x75d53c0585e21649L,0xc181d67098404cffL,0xe00f5f5dfdb3f05aL } }, + /* 44 << 294 */ + { { 0x3cfe2987d10542b1L,0x5935e0dc29f5b006L,0xce5932d6d83344f2L, + 0x67aab7ad9800a6d5L,0x3ef2b0e765073619L,0xc381a99454aa9ccaL }, + { 0xbf069577d4011571L,0x33b70c5d4d1ce997L,0x801ba41c758c9b1bL, + 0x6c2dd5ec36968958L,0x31820ca087921665L,0x0b7f0d337ca55668L } }, + /* 45 << 294 */ + { { 0x0b099a5afce6c55fL,0x91d1caca408dd628L,0x42a5181165449db1L, + 0x540935b040715d49L,0x8feabc5433b00823L,0x7107c06240c2485fL }, + { 0x13f307ac4fea64e4L,0xae4ec4a713a04327L,0x8297be380eff71f5L, + 0x3434286f1ecd0b2eL,0x4d7a5456a3e9d625L,0x657f950b6a0d04e2L } }, + /* 46 << 294 */ + { { 0x2237f78ecebadb15L,0xa1184339da01f9e2L,0x542c3354ef37abd1L, + 0xbec90883de982d70L,0xbacdbb9c457d3024L,0xf1d167c19840ea52L }, + { 0x9ed827d8433bd3cdL,0xf4e5b4231102fdf3L,0x2038c92fb63d6056L, + 0x490cb0188eb9ae35L,0x776331b87c75ffc8L,0xafbe7c6a3fe2e400L } }, + /* 47 << 294 */ + { { 0xf668460c9176a02dL,0xa843a70011d322a2L,0x6424f0e8a8c5d1c8L, + 0x0b45a1ab1bc440e5L,0x3b740cb11c3e391cL,0x5aaa89c4d5850e1bL }, + { 0x77739ee6d632c592L,0x171fd350fffe373cL,0x6a648fcdbd7e83beL, + 0xd98650c6b619f4d5L,0xa4e4ae5438dea07cL,0x10001f5afe0bf5c1L } }, + /* 48 << 294 */ + { { 0x31cb896b57dfc732L,0xc6b74a1edc323e91L,0xd24a41d0f11b04f6L, + 0xb609a26dab8f7159L,0x96d84b372adbec34L,0x154f5307d24ae7f6L }, + { 0x36dd3243e10eb34cL,0x055d3b714f6dbbd3L,0x30b1efde36d0c561L, + 0x3846925ce9bffd15L,0xaf401286aa99ba07L,0x3a191267fd48b839L } }, + /* 49 << 294 */ + { { 0x67145f18e42a26cfL,0x580857fa491122d7L,0xa4e2db8dd03b5071L, + 0x47a39a0d3e379882L,0xb6bfe4b35970766dL,0xe40f4daea8bce767L }, + { 0x38f199a7e812a217L,0x1407f98d97eec7caL,0x25d6f750236a41a0L, + 0x644327340e811ee6L,0x84d5d9c9dddd6e5cL,0xc1b6ef13c44cae4eL } }, + /* 50 << 294 */ + { { 0x79879d4f6714e8daL,0xce409617a17abd07L,0x6f2b14d008a6e685L, + 0x817d467409b5e150L,0xa1181873eb51b966L,0x573ba855da6b9544L }, + { 0x836ec3e5c4a37013L,0xb8da1bbe93fded69L,0xdb5bb6f16edff4c1L, + 0xff30b837f1657d36L,0xa20cf000223270b9L,0x29d60562d44a57cfL } }, + /* 51 << 294 */ + { { 0x0d6f36b9b98b029dL,0xc4cd72d07a371233L,0x23bd419e4f95cd4cL, + 0x2c95b0a2b80d1e13L,0x0f76e62f7edfbef1L,0xd077194dd303a470L }, + { 0xd6e20e7cd1b50934L,0xf4201fca2dfeb806L,0xa57dc150bced28faL, + 0xa84d621be3172301L,0x119768fe9aa14d6dL,0x34f1ae864b363253L } }, + /* 52 << 294 */ + { { 0x2fc83aa3afabd13dL,0x521b745f53c45a27L,0xc6f345a660c18225L, + 0x9609076eb5faa47aL,0x8bdd97fd535388fbL,0x8f5f3bd6e7fd7e87L }, + { 0x6de4454c1c8e1d5aL,0x8d61ca3b2b35e823L,0x93b66fce4672d30eL, + 0xcb9d601721d09ec5L,0xef98137fb1de06eaL,0x45e212758b051877L } }, + /* 53 << 294 */ + { { 0x117b89e9ee6e35f7L,0x2ad205aadd203ed9L,0x3f6c950c0689bd4dL, + 0xaba1e4b342f20742L,0x67464b793e22f0d1L,0x74436dfdbe0ad6c1L }, + { 0xc4a6e964c1470ac7L,0x853ad39b361da35bL,0x261c6fd6a187a6abL, + 0x08d7e89d59fb860eL,0x158e2697e8f88299L,0xf3f1f6f34b04a8ecL } }, + /* 54 << 294 */ + { { 0xbdfb8d006b562705L,0x76dbc217ed9f2aaeL,0x62f713778cfd02ddL, + 0xa05eed177a5d27e1L,0x60082379a006983aL,0x312af914bf7c2c05L }, + { 0x7d163fe76c8500fdL,0x722a35299d4d0dbcL,0x9b4c5c3539f93a78L, + 0xb193734c34c7ec06L,0x457db178cda87a84L,0x088dae087f816e0cL } }, + /* 55 << 294 */ + { { 0x746e73055896ac5dL,0x1d8326c21a7b69f1L,0x695197743132a40dL, + 0x3899f8a03f58720fL,0x2c3070a5df0b7fb2L,0x49bc59f2acb839e3L }, + { 0xf7d5d3f66b8f5a9aL,0x704ed893a4c3b570L,0xbafde26cab591c03L, + 0xc447dac83388a62bL,0xda80991d4416acfeL,0x1625c9151e729d69L } }, + /* 56 << 294 */ + { { 0x3104e59e6b843647L,0x4eccb42720bad138L,0xa575b8e150efd6a9L, + 0x68a6b7055a6e4729L,0x670306798f5b2a22L,0xb2cfcf81df9253bfL }, + { 0x9c3eeb19b8f81c39L,0x082ca86c986b4dfeL,0x1f64eca250250d8eL, + 0xbf26bcfb67f0c713L,0xbc5d0e2a49b609cdL,0x175acb34e6aa3c76L } }, + /* 57 << 294 */ + { { 0x5237d7368c53aae2L,0x2a88098bbdbc0b10L,0x18f1af11cec6db6bL, + 0x12c23392c4e08b3bL,0x23b652bf3eab43f3L,0xb79feb949f3dca0dL }, + { 0xb71e311d2b24e0d9L,0x85e48aede37a0f90L,0x93e8a0e753200b6dL, + 0x5d44b87226bf3a30L,0x466c31d1d0496b98L,0xabec12f7dd39874fL } }, + /* 58 << 294 */ + { { 0x58bc23928ca41326L,0x0744ba8524aa5067L,0x900e7e9baaf80bb2L, + 0x510bd122aff38fe1L,0xf90dd6a1002b277bL,0x829379dc81bf7df2L }, + { 0x5443b8736372d502L,0x124c2abab5b6f9a2L,0x88b237a4d6020c14L, + 0x3542215108f7a498L,0x39e84240e6234eb1L,0x43d721dfcc5827eaL } }, + /* 59 << 294 */ + { { 0x43e7597234658dcbL,0xed936b96bdf3a7caL,0x74acb7f60f1923abL, + 0x6a52b28cc007995bL,0x5abf2909a560fbf4L,0x79d571dd256bf1a8L }, + { 0xa8d51082e4c3281dL,0xc0d6f8aa0b9fdd38L,0xd589f2c57ac30640L, + 0x6abb8faf07635c58L,0x2af1b083d7520b0dL,0x18b9f6c893b951fdL } }, + /* 60 << 294 */ + { { 0x32e678b4c1ba956bL,0x9e8b137248f32982L,0x9b380a118a8f262aL, + 0x5c2d6ce0807f6d1aL,0xe99c2e909f1b3fa2L,0x6a0c9e4a7c4bb836L }, + { 0x30d80329ee8dac83L,0xabcf7b76b60bd5fbL,0xc589a0c8c14d56d4L, + 0x9e40af665de24d43L,0x932f4070230f8331L,0x96bba1c19b87948dL } }, + /* 61 << 294 */ + { { 0x8b83af0c4efaae9aL,0x25e55686770c85cdL,0x0beda54fede0c999L, + 0x6c5749398d249a2eL,0x520ac2ba2f476146L,0x162e482de95b05acL }, + { 0x2d3d19b6c73a32daL,0x945e5e3c33fd2c48L,0x361d9770a36b4ee8L, + 0x8aed760d014cacb3L,0xae66e5de5ae302c7L,0xb5fd5959b5d4d6a4L } }, + /* 62 << 294 */ + { { 0x25df58ff147da470L,0x1b3941ec3f4e3e98L,0x7543b1227aee3587L, + 0xb7bc2b31b4a28218L,0x8628b5400bb3224fL,0xe3e7644d373222e6L }, + { 0xb4e3269299244dc9L,0xe72c679d49781bcdL,0x894d9eb0bb6f0700L, + 0x4a08cdbc443c3639L,0x52c4d04e5baeb02cL,0x53f550ffb5f93552L } }, + /* 63 << 294 */ + { { 0x2b908f693c1f524fL,0x59fd6ae7090970ceL,0x595e15721eb9ec29L, + 0xa55adbd6fbc4f04cL,0x575a2344bcc38bf8L,0x89397944f2b659b7L }, + { 0xc77532a18c87fe8bL,0xa5a75677de4c9eefL,0x2e3d873a0e4a1704L, + 0xe18ff4fcc4d02aa1L,0xd842074275573a79L,0x0fcb532115296dcbL } }, + /* 64 << 294 */ + { { 0xbcc88422c2ec3731L,0x78a3e4d410dc4ec2L,0x745da1ef2571d6b1L, + 0xf01c2921739a956eL,0xeffd8065e4bffc16L,0x6efe62a1f36fe72cL }, + { 0xf49e90d20f4629a4L,0xadd1dcc78ce646f4L,0xcb78b583b7240d91L, + 0x2e1a7c3c03f8387fL,0x16566c223200f2d9L,0x2361b14baaf80a84L } }, + /* 0 << 301 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 301 */ + { { 0x7a1a522b246dc690L,0xb563cbe14b61ab70L,0x41bb4abe3d4ac4abL, + 0xc52950b337f996e8L,0x01d991e679727761L,0x35de93bd978fd7d2L }, + { 0x86bad5e65706d336L,0x10844155e7f26c20L,0x58ffeb7705757453L, + 0xbb1861293939df77L,0xbfdd394a6a78ea0fL,0x907ff0546e33e1d3L } }, + /* 2 << 301 */ + { { 0xa7f295320df93b34L,0x855934f25c14df30L,0xd2f54ce9efae348cL, + 0x5acb931cac52758dL,0x287b3e18d22961a4L,0x42a5516d748f8fe1L }, + { 0x1b62b341877224caL,0xaff58db3d30a4aa7L,0xbad78dadbe8da847L, + 0x85fa710954f18276L,0xe2cc9d287c4bfdadL,0xbb131f762c75f237L } }, + /* 3 << 301 */ + { { 0xcdcdd7d703844670L,0x79ec59afb4a23f91L,0x5923c569c00ce5c3L, + 0x099c17ffc589d0c7L,0x0335eeea89fa6fe6L,0x916bcacaa4e868c4L }, + { 0xb7037325fb687bd5L,0x57d6bca79853b564L,0xdf3132efd5e26d28L, + 0x7ed994b8de919cbeL,0x12df67cd6fbbb18dL,0x516e07c06baff508L } }, + /* 4 << 301 */ + { { 0xf2ec9ef597e833e4L,0x97bdef9734ec7e41L,0x90e2b2387d2ac6e3L, + 0xcf682b120318a3b7L,0x7fe76089ea84a7a0L,0x85c489f916546d05L }, + { 0xf987118f6abdda05L,0x675cf998aa4b95fcL,0x544c7774888a7e8cL, + 0xbd2647ba63ec5831L,0xb479cea3fd2fe985L,0xa042134528d163e8L } }, + /* 5 << 301 */ + { { 0xd93506a4e5947c6fL,0x4340d76a39b81d08L,0x741aee5917930d30L, + 0xfea3d99a18fdb81cL,0x1088ff6b289bcb07L,0xc6b45602b7c082c6L }, + { 0x50e2baab453d8d69L,0xda9bf561e893e183L,0x0af25f86b29a284dL, + 0x0e92e67473e01380L,0xe173a0e32be00e59L,0x402d2f3dada8954aL } }, + /* 6 << 301 */ + { { 0xca9cb3890399721dL,0x03ad9f4aa3291479L,0xd85b5df56dee003dL, + 0xe1fa7b0264a4f83aL,0x01c4cbfdb73f7324L,0x707010d45cf2ddf4L }, + { 0x3c6df430b12e02f8L,0x921a290185531489L,0x302fc77c91d1022cL, + 0xc3733ec0342d8f3fL,0xb83bc75f6195a665L,0x4a14b9e7a79f8027L } }, + /* 7 << 301 */ + { { 0x9f0e5428e2a57359L,0xc690a3c714998c16L,0xd73c3ca2de37e07eL, + 0x2ddf91b8dba0bc0dL,0x69d834b27570ae71L,0x2ac8bed4735195a6L }, + { 0xcd8c51ff3b1fcc5cL,0x7aa8cf4e1ba6863fL,0xebb69e72ae70f428L, + 0xa29409dfaa9e936dL,0x43f6ee805a332b9bL,0x0de49efac2eab0a9L } }, + /* 8 << 301 */ + { { 0x04baa1762310333eL,0xdc75e35f7b9bad46L,0xc4a6031dc6cd6108L, + 0xba2534d030bf87a5L,0x7ebc6e2131e497ccL,0x8a2a82b4851fd665L }, + { 0x9ecae0116d5faf40L,0xfa3a6d7f96956ecbL,0x39e8a9c22fa52782L, + 0x74c93801236d442eL,0x8b21ba23b1c289ceL,0x7f3e221b25c769cfL } }, + /* 9 << 301 */ + { { 0xed800e4d08aa4dfdL,0xf524b107d8105bc7L,0x8c4addc9ab07fc03L, + 0x2b0f038d26a71b4cL,0x5055c471a83d19a7L,0xc6c5ecba27e20a5bL }, + { 0xdbad26b7aaeaa017L,0x4e3abc20d2493554L,0x626310143a0c15bfL, + 0xbafcc06798cec55cL,0x9204e17ce6f87607L,0x8f1c10eed9302c05L } }, + /* 10 << 301 */ + { { 0x53680ce08afe59b9L,0x36a3cec75665022dL,0xb3a5091654490b50L, + 0x803d383f0838f0aeL,0x65531a008005ba2eL,0xb7fa6b4a1241a17dL }, + { 0x9aaec449b17e07bcL,0x19b7d9113d190dd0L,0x79da42457fa5e7feL, + 0x725bd045598ad850L,0x49f96cc45f94ee82L,0x114bbcbf03850eefL } }, + /* 11 << 301 */ + { { 0xf566a287d43a6db8L,0xffb8944b2aeb120cL,0x3e7099427e294c1aL, + 0xce122b126c31214eL,0xe59b280c2a21282dL,0x03916e2ba01a4fc6L }, + { 0x56e65da29f5e409cL,0x374d3dfe7f5c3e11L,0x150684fc13967e2cL, + 0xfbed4f5bdf4bc38eL,0x5973c67182e54b82L,0xcd36c873363f307bL } }, + /* 12 << 301 */ + { { 0xcb42c5617c3805d4L,0x0e74e75c3b43a8b3L,0xfd58f864369f579dL, + 0xf471aa774a3dfe97L,0x2e0dbb51ab37bd2fL,0xc4704487729c887bL }, + { 0xcb7958a9cff32948L,0x3e36de368505e71fL,0x2232fd2dd38ccfbfL, + 0x6f3c502042005175L,0xd1280a3e306fb63bL,0xef7abd792e368ee9L } }, + /* 13 << 301 */ + { { 0x29c5712d56ffcac3L,0x20307670e1a8e0eeL,0x676a23c26356aea0L, + 0xb9c17e3f432f15d5L,0x0008512e287c5705L,0x6ae2704bc5f7ccfeL }, + { 0x6a200db709a13b60L,0x24fb1e9241043271L,0x2e455e9741b766a2L, + 0xa11ff26fbe056684L,0x3cfb8a64ad9178ceL,0x5786978d5d675b79L } }, + /* 14 << 301 */ + { { 0xf4cf2c8e6070a72cL,0x0bd73aecabc3251cL,0x1af44eff17539f67L, + 0xec3ee99e44e8d8f7L,0xba698f6a279afdf7L,0xe871accfb771d4a1L }, + { 0xbf92963d8bb0f264L,0x817b1fcfb10716bdL,0xf57580786b23076dL, + 0x994ff3c535a994cdL,0x05d984e82604847eL,0xd728e292fc9f2e43L } }, + /* 15 << 301 */ + { { 0xa44bf023b900b696L,0x1f82fe54037bb770L,0xa6d12f820717e747L, + 0xf154ac51e3b83029L,0xfbd343128cf3984dL,0x7f734beaa76c72c2L }, + { 0x05c5b443114548b9L,0x4ce414f396af4132L,0x1474c0b79d080a7aL, + 0x865827c6497366a3L,0x34760c457816a0a8L,0x6da2474c15d2a176L } }, + /* 16 << 301 */ + { { 0x761e10e2ca114c4aL,0xe39d121d894301b3L,0xa0870ff43dbc6fcaL, + 0x97651286cbe0ba8aL,0x47d46075c0f1ff6aL,0x18669c843abeb5b6L }, + { 0x1234c80ead8d9309L,0x1ccbe4d51f6f97ffL,0x399a2d41d82ab780L, + 0x8a03afafde426e50L,0xa2bcb109ca6dde77L,0x840e13b00618f5ecL } }, + /* 17 << 301 */ + { { 0x9552a8184929f7eaL,0x514e9ce9acc61766L,0x03159a525a219015L, + 0x5efeebfa14eace54L,0xe8a3736f853da94dL,0x3a0f334ff45e8a32L }, + { 0x71ebab39c9dc65c9L,0x6ef37f49d7c24f39L,0xde3d45f8b24a9383L, + 0x7193bbb80c218869L,0xa1bdfd30c0f7b6beL,0x82b2c4c5c1d9206aL } }, + /* 18 << 301 */ + { { 0xf9d9b678b197099fL,0xfa8548c4c15b2bbeL,0xa36f17fbdd2817beL, + 0xb35597021732d1edL,0xba145100744f3955L,0x7c274633344b43a3L }, + { 0x9b0ee7c8686b65a5L,0x438eaf4823f0e973L,0x79a658a7288c5019L, + 0xf6d938c546d04413L,0xe39bf9a6a6cb9853L,0x880d5b83801b70ddL } }, + /* 19 << 301 */ + { { 0x8f23f00303825482L,0xc4a9f214a6b35023L,0xf0905573794e7de0L, + 0x7ff790144dd68979L,0x8d9c14942959beffL,0xdb34474f82282e48L }, + { 0x423bdfa281fde794L,0xfc31e3e792a8810bL,0x19d316ba8bae4eceL, + 0xddcf30b7159c1386L,0x997968a38e7d69dfL,0xcf67ae9aa6b21be0L } }, + /* 20 << 301 */ + { { 0x877866a3697b4dd0L,0x32a872f4e76481aeL,0x300387bad609cc04L, + 0xc761ae79d74566d4L,0x9fd3e5bff22e2d24L,0x363ef5bf1c46bc0dL }, + { 0x121b25bce299a690L,0x7932471dc2d32b7eL,0x7f89692e94bb4272L, + 0xaf9cc4111a3ce076L,0xaf02ea22ea02e452L,0x43154e581d19dc60L } }, + /* 21 << 301 */ + { { 0xd9389e05e25dbe97L,0x3a8689b162b3afe3L,0x4d5556467014953bL, + 0xd6894c42af5ba9bcL,0x4b233690b3bacaa6L,0x0fc8ad07fc191181L }, + { 0xcd3a1e4df0764f39L,0x18a47233d79567f1L,0xf0f9eb765f921f79L, + 0x7f3d814d19d12a7fL,0x5e48cc36ff33a995L,0x9589679b8960331eL } }, + /* 22 << 301 */ + { { 0xa2ff78bb477d7226L,0x3216fcc085e04a8bL,0x7c594f81e4c3c24aL, + 0x075eefaa029d6ef6L,0x5ae51000493ab006L,0xcdfcc6939ab165efL }, + { 0x50b7eee276073bfaL,0xee52d55b3b60cdb4L,0xc7f7b3af45027275L, + 0x01d5444ac15b2ecbL,0xdf56f8c12a61d1e1L,0xcf032e7e4992e1bcL } }, + /* 23 << 301 */ + { { 0xc8a4dfbf15b6d8d5L,0xcb34e0e4e87ff88dL,0x6dc95befa6ebbff6L, + 0x2a55ca1372ff2cc0L,0x3c4c0f3c6a62588fL,0xa8de444ece156917L }, + { 0xced7c4523e55eba1L,0xa109b7949f05820eL,0xa021717e0e6c318dL, + 0xa0156b8d0b308f5bL,0x3c65ab9daa6634baL,0x1666e650e2839e0eL } }, + /* 24 << 301 */ + { { 0x0d27500f9ebe3c40L,0xeb9ac1022b700fcfL,0xee7578f8610763e3L, + 0x6e56078f47ef08feL,0xa8d03a7f047d04c0L,0x2143606f27cc8aa3L }, + { 0x6b08eb383b004721L,0x1f505c0dc4e36bb6L,0x6f9b869ae3f10ba9L, + 0x3bfb9833e500e846L,0x6d975557b9171b1aL,0x7af9cf4f18fa0045L } }, + /* 25 << 301 */ + { { 0x35bfb51b3b35836dL,0xc834e59003b0fba6L,0xbe6e17d378937ce0L, + 0x2f796f7c4daa9aa8L,0xd7896a0ad310eba9L,0xda258ab05ea4056aL }, + { 0x2d872d2170626628L,0xc9b26d7c2ee433f0L,0xb176220ee72f7491L, + 0x4869adcd895e9b52L,0xd37540e4d3a6d786L,0x024aff303a86b44bL } }, + /* 26 << 301 */ + { { 0x5e78606bd8424b90L,0xc83a5af9ebc9c9fdL,0x8d5b63740b65ada7L, + 0x4d01d6a221fca70fL,0x8ed7787ba1838061L,0x29901318f4a1716eL }, + { 0xc4d260527f25fd2dL,0xa66dc0a98b5147e0L,0x4355e26c269d726fL, + 0x1284fecce3a27644L,0xc9aa6cf7f98e1d0aL,0xa25ac1be3ff560c9L } }, + /* 27 << 301 */ + { { 0x5bbb87ded64d103eL,0xcb53a2f24d20fb37L,0xf8a9c2993a46b892L, + 0xb552910ca793aa9dL,0xd09e5bea51ef0806L,0xb57a0568e0c3817fL }, + { 0x9ca67c5f4e85598fL,0x04f6361fb0336008L,0xf028231b580afa5aL, + 0x8d938c0ef2bba03cL,0xa5984c1f894f37d3L,0x62ead7f4af695ac5L } }, + /* 28 << 301 */ + { { 0xf897de9213a48775L,0x505e21681b0041bbL,0x9f5533aad598ebb7L, + 0xd552ae1e1e87b2fbL,0xbb35a6319b736f5aL,0x391ce7dcc3a4c54aL }, + { 0x4c677d87f90124d6L,0x2ceebe51a9292210L,0x8882ae3133c63951L, + 0x8222c6482d44c9d0L,0xb97511420d607658L,0x3a999028b85f5997L } }, + /* 29 << 301 */ + { { 0x7b23f424eabb3f68L,0xa622a3ba4294750eL,0xb382b118e535b446L, + 0x7dbab9ee5fab292cL,0xcfabbfb037fe2f8eL,0x2283d7606670925bL }, + { 0xd18e90715be9d07fL,0xe191daa7d257745dL,0x86d59808df915e35L, + 0x87f68d5987370b6bL,0x76b9d255f945ac1eL,0xdcf9e8f2dc94ddbdL } }, + /* 30 << 301 */ + { { 0x004f1db65b986506L,0x5da683c32b0d22acL,0xf2afd1d85ee0c71aL, + 0x3b99a78a8f2ad25bL,0x8145d2ffd1c0cb69L,0x4511dc4e4009a536L }, + { 0x5539e8b8a5cb0c13L,0x4f8fd0186aae4603L,0x15dde4476d2365f3L, + 0x7cb887f7380df270L,0x815343a6a741b88aL,0x81a085e4bf99e7e1L } }, + /* 31 << 301 */ + { { 0x37d0460fd647fbd6L,0x2ccc7b01b9541f89L,0xec0e8826877a1b2fL, + 0x54d9e611cd462979L,0x016e8458453dcce6L,0x99b5dbed20ea6a24L }, + { 0x64072ec778550386L,0x279fbd9959d02307L,0x7f2ca27e9183bfebL, + 0xa191d6e8bb5132f5L,0x2b9f6163ba49ee68L,0x5a58a11fa3ee1672L } }, + /* 32 << 301 */ + { { 0x15d47e52ec645a62L,0xabe0ddb38d6d4423L,0x51226a3070cddb11L, + 0x63a253d32b5a8db7L,0xe8be4d1fbef37d65L,0x41e625d9c0920b91L }, + { 0x08b713a8d9d040ecL,0x467fb08dc450cdbaL,0xa8975877917ee393L, + 0x294792e91528cd12L,0x4512dc8c37daf6aaL,0xa83becc9197a99b9L } }, + /* 33 << 301 */ + { { 0x1b7bfdb118815b20L,0x1aa602e8629b81b9L,0x11e6df9d199aa5abL, + 0x1a521728bef9296aL,0xeba3e03b89e127e7L,0x6e69893553dffcf2L }, + { 0x24355785101615e1L,0x126b4c5282e42593L,0xe344ddd85c23144bL, + 0xc73a49b3746c0ca2L,0x1ec2432be6f63f9bL,0x6080ba870243120bL } }, + /* 34 << 301 */ + { { 0x6ab2936a4c3e946aL,0x8de2e0ae3ab052f0L,0xcaf8c35eea109739L, + 0x21d69383032418c8L,0xefab535ae7ee60faL,0x1a3a1be794b44fabL }, + { 0x0842aaa5eb911cbbL,0x789c2b7e0286862dL,0x8bff708715c0b148L, + 0x71100d79d8d7faf7L,0x47caa89a6dfa0c8fL,0x82385cf44b546332L } }, + /* 35 << 301 */ + { { 0x4f5d8c35e4b814fbL,0xe534b7be6a427f92L,0x468fb2819ca1d37aL, + 0x8c1c86347949961cL,0xf9d00305db0f7f19L,0x77534b3a976f7102L }, + { 0x94ecb7933f530710L,0x072f6fc7a916827aL,0x9247acdecc926f8eL, + 0x0d4a8997281d0a50L,0x659712669f353507L,0xd4730a15fde80a6bL } }, + /* 36 << 301 */ + { { 0xde68ca25bd37b630L,0xcfa9d32ca899d623L,0xaaeab905937c9ba8L, + 0xcb261334348ed39dL,0x8d12531fc77e1512L,0xfb7934b6213b63d1L }, + { 0xc6a6fb0096a13f19L,0xe940f3aac8f88d6aL,0x014c7f95c3d2829dL, + 0xc33d87e9fff01f41L,0xbf9c3c23c5cdcb4bL,0x8b8c0afe5d5be5c1L } }, + /* 37 << 301 */ + { { 0xe4f84bf12aac2c23L,0x5bde1744f823f90fL,0x65ffefbc02d5bbe2L, + 0x385aff9332a3b756L,0x3813f2b362abfdacL,0xbbb444cb0a144325L }, + { 0x0cf9d137ec625be1L,0x86b8fcd4c143816bL,0x03f7a9d060ac32d8L, + 0x0428daf9366165b6L,0x6ef94260d2a806d0L,0x94a100a598134bb5L } }, + /* 38 << 301 */ + { { 0x4b68325ca4a34cb5L,0x74f41f7639fada89L,0x34bf397236e593e7L, + 0x0cc75d461c6179c4L,0xe62d5ba577d711e5L,0x7bec1be7876964c7L }, + { 0x768f35d13809fc73L,0xfe55a9a57dcf1703L,0x86405336e69d3390L, + 0x68f5ea2d00bfc544L,0xd4cf822b4834b2d8L,0x77dc1ac22b0d3ad6L } }, + /* 39 << 301 */ + { { 0x45603dfa0337f57aL,0x50623184344b6968L,0x3fb9957ef160d9aaL, + 0x40eef1697c8db44fL,0xa8f394e98bf71121L,0xa55ecf3b86a920f5L }, + { 0x1f3c1f22bb0822e6L,0xb3c2f21357747a3eL,0xfbdb4465bef56f08L, + 0xa9844890a46ac73fL,0x3fd564a5bde3652aL,0x008cc1a97c653c82L } }, + /* 40 << 301 */ + { { 0xcfebe027ca0a98d5L,0x946b0d9aa8914697L,0x00f89d16725ebd08L, + 0x94c6f2b07a584e8dL,0x095ac9cc911cab58L,0xfc9c3b499c4073c8L }, + { 0x265919b0c7233aa8L,0xe6c0c7f474be5217L,0x6db597f1815a70a9L, + 0xdd9e4a101c5fd35aL,0x38b8e35112d52a8bL,0x5d0ed83f2ef20fabL } }, + /* 41 << 301 */ + { { 0x4f47e10a6c96b43eL,0xe406ab39f3d744deL,0x1caf45d83c893b01L, + 0x4f089452a7582ea6L,0xc02f58cd62b5a868L,0xf6532017c2a9aa7bL }, + { 0xf0d8bf6f32b01bf2L,0xfeec5f68a97246f3L,0xb2ead70a1aa7c238L, + 0x1a1d6f77ad83e05aL,0x4b7110533dca7e9aL,0x44a89fb85f96e5adL } }, + /* 42 << 301 */ + { { 0x86a7ebe0f02461f3L,0x6a7a9cc6862282c9L,0x7f8857944a97e48bL, + 0x191244cd20662db2L,0x8d85175183489311L,0xfbcb17b0f934c1fdL }, + { 0x33b4d86e032a7bb3L,0xa99864cb573f5c28L,0x49fe8e799c4f12cbL, + 0xe34c32e32c8bb49cL,0x5888421e962d6d9bL,0xa317c2d1bf1be44dL } }, + /* 43 << 301 */ + { { 0x3454c424cc1dcbbfL,0x67e61434aac98717L,0xfecd8125cc2d3044L, + 0x2032be70df7f8891L,0x04c5a0c81028059cL,0x6563dc8c76ade6b7L }, + { 0x9ff3815192f460aeL,0x8c2c3c632d54785dL,0x1fa99d8e43eabf60L, + 0xd75d9559383be317L,0xc9ef068e3dfc908eL,0x2217c8c1959d3e6cL } }, + /* 44 << 301 */ + { { 0x5828d71bf2e5f345L,0x8b756075929fe375L,0xca625ec12c43a6d1L, + 0x08cd01f53b31e127L,0x56c622619cfc1be2L,0x093ea207b3a6caeaL }, + { 0xdf53b20970b42dc9L,0x2d2dfdf2235f4aa0L,0xcaac3b3598786c94L, + 0x1ce1f893b4998150L,0x40341c41526a98bdL,0xef39e97eedce5288L } }, + /* 45 << 301 */ + { { 0x08cd60d461ea4256L,0x8031748b9461f861L,0x9c96e1f9019c7908L, + 0x7e6e08f4e46bcf7dL,0x8e8408f123ffa986L,0x0bee857ed467288bL }, + { 0x702fa8536e36fcceL,0x3bb25fa905a89edeL,0x642105f4e96866ceL, + 0x6a5207cc16e37536L,0xcb6a96d1372a3e06L,0xb1c7c85a1da6bc6dL } }, + /* 46 << 301 */ + { { 0x0bb97497a97a3316L,0x9416659ce402a800L,0x79656970503a2314L, + 0x0070a7eef8007c50L,0x8093cd4372624892L,0x4c0ee444f9b96830L }, + { 0xc7c10b9fe300c49bL,0x97f5f90a5f7baf99L,0xf04a5a7cfaa064deL, + 0xd5b01fa6b0c111fcL,0x4d12d6fb65d8a2b7L,0x807a381c27770e2fL } }, + /* 47 << 301 */ + { { 0xcd1aeeb43b6a9c22L,0x7fbdc6c19d71dcd0L,0x9bb43b6e6221669eL, + 0x1b76f2bf526f8a00L,0xaeba54302efdf661L,0xe1f623e745537bbdL }, + { 0x340966ae067c5f4aL,0xe2cdb27e4799b2aeL,0x9aeec5989b8458e0L, + 0x1d0588487655b632L,0xa5ffe5897abd70b1L,0x84db43db6721054eL } }, + /* 48 << 301 */ + { { 0x3b21dc1f538d92d8L,0xc80b22b3c005aa86L,0xf536e5d30da87d65L, + 0x4ce10edf0cd999a0L,0x8949181450e08f5dL,0x77fd8f2e526647e6L }, + { 0xcb207ee9250099fdL,0x03c7d1abfd6aa078L,0x7d4940d225e0cf15L, + 0xb688b311067fa052L,0x89308326a98b2e21L,0x3ee4cc2b72311eabL } }, + /* 49 << 301 */ + { { 0xec49fc4e06d255b2L,0xabd0c002fb309d28L,0x97490ff08c601c3cL, + 0xe17102fd58042cd6L,0x861411f11416ebc3L,0xfb31ce455c6c630cL }, + { 0x0a24d561c6cc5e9bL,0x80bec25c9a7c1524L,0x8003494fbe53e50dL, + 0xe89b75e28633c559L,0xafb1f6d6763b3360L,0x0e7e58c52bf70cd3L } }, + /* 50 << 301 */ + { { 0x72322d26aab6c9b5L,0x953e43d0070d7d08L,0xe2dd5444954645c3L, + 0xc5de051cb276ca86L,0x195d454439158c74L,0x26e2cf9fb90a8f97L }, + { 0x774baec15b217a76L,0xdba4bc63f94172baL,0x96ddaa4022e20037L, + 0xfe1ce4aac111af69L,0x6f6d3c428ad6dacaL,0xe59257d8376cdefeL } }, + /* 51 << 301 */ + { { 0xf2cabe73184d44ecL,0x4bf744d60bb08687L,0x10cb9e9209865d58L, + 0x3a63fe414ea221e0L,0x8f595e5892961becL,0x1b8ad036855d186cL }, + { 0x75dd5f70086542abL,0x8b357e087bddbb6bL,0x22de89f06e829a06L, + 0x44ca8b64ecc6cc26L,0xd02fa871a5ddebb6L,0x6adf1d0c6a60a0e3L } }, + /* 52 << 301 */ + { { 0x0102775982e4f5c3L,0xac8eac172c014fc4L,0xa0cd26e85bd843eaL, + 0x9b0431ec056d4b1fL,0x89df7db58eb9c55bL,0xf17f917298fc9b9eL }, + { 0x2cf1e4a78e6b770fL,0x0d6ef9e2b842fe52L,0x40b4ddb76c578172L, + 0x6630657627533b9eL,0xf8d8661eb50ce390L,0x6ceba0aa16577df7L } }, + /* 53 << 301 */ + { { 0x6dff66c19ec8ac93L,0x6261295bfdf6fe7dL,0x9ad1536fcf9fbbb2L, + 0x5cfa30a92a6d6d31L,0xb3bcf1b0296224dcL,0x42e4b410608371daL }, + { 0xd6bad6dac32945fdL,0x0fab7d1dc0c031a1L,0x054df9599b192d32L, + 0x29830094ea78052fL,0x8d73ffce03f2ce45L,0xc14c7012f9d840ebL } }, + /* 54 << 301 */ + { { 0xdf74522e74ce5c21L,0xf864cbac930c4b92L,0xfe0d2358eb0fbe9cL, + 0x10b31736a5cf765aL,0x185bbbe96a9c95c6L,0xcb14d694e5362993L }, + { 0x3f5c921da5332e61L,0x0820b32bd244cc98L,0xdaf09f24d7c32062L, + 0xb2241c9ad5959a1cL,0x16bb89a3226127ddL,0x0b46e3f03723d04dL } }, + /* 55 << 301 */ + { { 0xa38b1a796975230aL,0x25c6db8c3991b5ceL,0x0d89c3fe9c1bf52aL, + 0xe186e293cd8f9f8cL,0x777bb327e6ec37afL,0xa974132a0ae31c7eL }, + { 0xfb9918305c50f089L,0x4a653d6999497954L,0x5055c690774e8a26L, + 0xf94ffbae3815d67aL,0x99d74f5e74ea4481L,0x3b352a327d477151L } }, + /* 56 << 301 */ + { { 0x2a62804172fb61e9L,0xa9bfa73ab13d053fL,0x4a2cdaa3c647fcb9L, + 0xe1a9e91f4952d3a4L,0xbc1b3d8011e2e2c3L,0xe58ef59c18e4340eL }, + { 0xeb8696ff1cf859b8L,0x5b0f5cc4ee918cf4L,0xa471d6ce6c1e905cL, + 0x4e13d6091ed2e8cbL,0x52951509c77c8c91L,0x0926dad8e234884eL } }, + /* 57 << 301 */ + { { 0xb168a6c36e3aa3d7L,0xbd0086ea5ad9142fL,0xbc4da0293c24fe23L, + 0x7ed3b34808b90de6L,0x7a7a2259e33b0df9L,0x483b389c9c3a173dL }, + { 0x02080c626334a061L,0x61944965b020cfbeL,0xece528e9ede88ecfL, + 0xcdf3e2fc99389758L,0xb21470cb7a3fb92fL,0x717cfbe083937e21L } }, + /* 58 << 301 */ + { { 0xfac97f2910e3e93fL,0x1505c7d2f1101b88L,0x7cea978823bc0d11L, + 0x27ead95d45045667L,0x711bc4dcd17ea199L,0xe3f93fb522f3142dL }, + { 0x31b05e6ad7233d64L,0xac28e6c154e7c9d5L,0x892b6366716d273cL, + 0x1622230470da8a48L,0xc85bbe6070d560b3L,0x555e6de987fd38a0L } }, + /* 59 << 301 */ + { { 0xac593f746ed50680L,0x89bdeabbcb01cfd3L,0xfa43158ead35524dL, + 0xb2393726e8d66ca0L,0x248c67c2c36bb495L,0x27d4b0b85c933625L }, + { 0xdbb1364a78c8bb4bL,0xdcf4b1e13486ef0eL,0x554f95cec498b2c9L, + 0x2b76da29811a2329L,0x750c10271a10d941L,0x07045eae375b01b6L } }, + /* 60 << 301 */ + { { 0xd3fb9bef82621500L,0x09b18748f0f647a6L,0x186bed054c357e73L, + 0xd58281f0a85f3174L,0xdcf2e0bb91ded0e9L,0xe77faad126894faaL }, + { 0x6843c160bc3a3c4bL,0x7f8058944c76592dL,0xc53be0883ec05e95L, + 0x318d8ce7cce0c822L,0x6d615f1b4c761dbaL,0x0115824c46ff47e0L } }, + /* 61 << 301 */ + { { 0x1815391cf8d0b74bL,0x903ad8fd797625dfL,0xad1ca24d3983100eL, + 0x0883fd415572ff15L,0x0e9e572cadeb4e56L,0x800bad6f7d0e25c4L }, + { 0x52a394b44c7e2f03L,0x5150c01398f2c416L,0xf4ab35c68ce503c4L, + 0xa0ad209a41b4beeeL,0x050c52c80189706fL,0x86780a924049e913L } }, + /* 62 << 301 */ + { { 0xa398529c74ded2a1L,0x5e7248f52d7ea6e5L,0xbeb250bc28c2225aL, + 0xf7068fc0b40f4843L,0x62098aed839b7290L,0x947087e293ddfec4L }, + { 0x81ba8c8824d71004L,0xa877f443bf4813c2L,0x3cf5f473ca4751bcL, + 0x2533890e633cc635L,0xb358f7781e6d9465L,0x50693deaa7801dc7L } }, + /* 63 << 301 */ + { { 0xaf306f56cbebedf6L,0xdd733be7837acb84L,0xc767237afcff0b9bL, + 0xdf948f12e555bee9L,0x86b85657826dc76dL,0xa4bac032e702b1c0L }, + { 0xdf3544bba81bb117L,0x69c20dff34f4f0aaL,0x846b78577050d98dL, + 0xde0ef0403c70120cL,0x4483872c12c3bd64L,0x870b758550acebacL } }, + /* 64 << 301 */ + { { 0x37be5d3f68d7dfcfL,0x97bdbd49b945e6f2L,0x165a24b59d1569e7L, + 0x254aaf59b4e293abL,0x3c751fbd6fb7c0a4L,0x14eda4ba5018cb18L }, + { 0xacb3b8971b5f6aedL,0x6d10be441e4b6b78L,0x245d7258621df6d7L, + 0x2af0e283185f0e2aL,0x1e7edc818fddbd81L,0xbd1e6c72c538d02aL } }, + /* 0 << 308 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 308 */ + { { 0x6858b674844626a2L,0x610cd40f0cbba6a6L,0x324e674e29d9194dL, + 0x2dc6fdf6dcb30a51L,0x3f3ecb77528aa549L,0x0721f8f923ffaa92L }, + { 0xd8efcbd627a77538L,0xf4e642bfd6162c9cL,0x04f2b0b74cf4a16fL, + 0xbc0bb49fbbf335fdL,0xc6b6e5bd5a928c36L,0x981b01f4d893dd45L } }, + /* 2 << 308 */ + { { 0xfb083c2af810465bL,0xb66a8de902ce0deeL,0x6e4130e747a81b95L, + 0xcd704dc658a98737L,0x842ae329592829c9L,0x99bedc34be20dd63L }, + { 0xabee8e55d53b2df4L,0x6ce657586010b37cL,0x781f39b2467112b9L, + 0x6f06058fbe341038L,0x5effdca512a2f8beL,0xaa9bdad7af34466eL } }, + /* 3 << 308 */ + { { 0x3933b4c1575782aaL,0x610d3ba25c66e501L,0x52fd3c0f0b7e019dL, + 0x7f8e5ddfa48715d6L,0x0879c5defa39be53L,0xe32c886c56f01cdcL }, + { 0x71b2dcbb1726779cL,0x6caaff052c6aa84cL,0x6af94846640b2d74L, + 0x78a10710049a2cbeL,0x41a1ce67ac2ab0f1L,0xd160b7faa76d8438L } }, + /* 4 << 308 */ + { { 0xab86639e9c216137L,0x45a12fb882b18d64L,0xb5734418d763f0bbL, + 0xd2cc332211a9802cL,0xe41d7db881269b8aL,0x91072fc12ecfa355L }, + { 0x59d6912504ce306fL,0x916d9d4da131b86dL,0x84478b6b8a739738L, + 0xe86ad7d91cc83ae3L,0xbc9b2084797ccd97L,0xc1e94af4694944c6L } }, + /* 5 << 308 */ + { { 0xbbb6725b5c82c857L,0x72c66c3f140b561eL,0xab65dd0664bcb2d5L, + 0x755e848a780d5c1bL,0x84e6f686a3a61e6eL,0xd84bf486bd100b4bL }, + { 0xb34fdf846354e899L,0xcbc312da55ec5654L,0x3c2cc881f9a125f0L, + 0xb1fcce564aeadf8eL,0xbdfc54c0c46bf0c2L,0x11d7ea4f09d281beL } }, + /* 6 << 308 */ + { { 0xe1aa844b1601940eL,0xd22221821797e84fL,0x3025aba65ddcb5d1L, + 0xac8cdaba38009c6aL,0xb9ee07b46e261ee5L,0x84069bc106ab8430L }, + { 0x7a36b46278b9b112L,0x2d91ed2c08e77879L,0xae4ef469341275a1L, + 0xf7cb393f1c7cf858L,0x83c00eafd192af3dL,0xa81697a7a1e15176L } }, + /* 7 << 308 */ + { { 0x687d0980f9bfd795L,0x9a7539377ad882bcL,0x641407fabbcde5b3L, + 0x12ec9d216ed103a5L,0xf858c7851fa6ee22L,0x329b61bc818f2c11L }, + { 0x4720d42ad9d48b30L,0x3f61c66082a66766L,0x99aff25533723e4eL, + 0xd6c67ce3d3260b62L,0x63a6fc9d86391c33L,0xc002433a31de2381L } }, + /* 8 << 308 */ + { { 0x585edee3895c0318L,0x775e142f45e8205bL,0x3bd7924fd85ad31fL, + 0x2e7d8f919124bffaL,0x885397c044c62868L,0xc0c2dff47fda9f5dL }, + { 0xd302582ec14e693dL,0x53d6e33a6cec31baL,0xb0216b5b63653c06L, + 0x8f08a1ad9c70dad4L,0xccf014aaffbba93dL,0x900b0d2ca33f12b7L } }, + /* 9 << 308 */ + { { 0x4960ccb6e9824c45L,0x3c5a9b74c7e4cd06L,0x1e78cdfe37cfec62L, + 0x8cd49ca80da56a05L,0x5ba51217dca05707L,0x0d1f6e459d66c960L }, + { 0x7178089467f9c82bL,0x342e4a5b18974c55L,0x16263f18f9b32fdaL, + 0x844b5a02935b3636L,0x9c5abd51c139ea58L,0xf54c69428beef953L } }, + /* 10 << 308 */ + { { 0xbe51552d6d2dedd1L,0x6bc86dc1cd997093L,0xc9b600c4418f03b8L, + 0x4ea4e857e7a9208aL,0x7aac3d96883b639bL,0x4127ed0735d2f4bfL }, + { 0xf5f6310d76bd792aL,0x3da9b6a5fa223d0cL,0xd75f88075a041b79L, + 0xf3261457e4dd58f6L,0x4f0f5b18b0d9a51bL,0xf5aeedc1b8c84f9fL } }, + /* 11 << 308 */ + { { 0x1e08d6a81375620eL,0xed9a4fbae1f62c24L,0x0d3bb90381ab5de2L, + 0x885781f0df1b6a13L,0xc3fb9f97e1c7de7eL,0xf12e4bcf9372b033L }, + { 0x9bc3cf4dd5868448L,0x89465649552016adL,0xeea40cf92a8b2c23L, + 0x57d720ee3af98886L,0x97b14c0b72db853dL,0x65d10f42f23504deL } }, + /* 12 << 308 */ + { { 0x0dd2395e9b8cfa41L,0x50e203abd4f92a44L,0x7280aff16630023bL, + 0xfcce59dc07de820eL,0xa686be05bc8189adL,0xac4b59bfaac70b7eL }, + { 0xd2c0070e7a3c71acL,0x1d550add35ac1c47L,0xd42b6389fb881c1bL, + 0x57ca3fccd0dafd42L,0x909e8284be26ccc9L,0x1abe7595a002235cL } }, + /* 13 << 308 */ + { { 0x02562f1c6b1878daL,0x52a2cd069fce0ee6L,0xf25b35bdeb16199aL, + 0x0320c326a75fb01eL,0x2006d7587de2d46aL,0x6f9d0e256842b459L }, + { 0x70a89562a68b5482L,0x9653726e1ab35865L,0xbda3cebbd8f849adL, + 0xe2f8d9e60b6fc51dL,0x9c3fd51246104400L,0xbbd260c9bab5d34eL } }, + /* 14 << 308 */ + { { 0x1f5094703cbc1df1L,0x9f752a663f962634L,0x98089d2ca2435048L, + 0x05256acb0e755318L,0x91a21f707f3845f4L,0x473ac1e0d68c8fcfL }, + { 0x57ee51417f2ff0c9L,0x959a84f32013c48bL,0xe701f13c4c111ee5L, + 0x70219eee86db5763L,0x385f890cdb0782e5L,0x81fb64b2fea04d2eL } }, + /* 15 << 308 */ + { { 0x61b4bf7eeaa07bd9L,0x49832879afe544c0L,0xf788e97f54eb4d80L, + 0x78351b41338af327L,0x3a631bba77cb8057L,0xeb9a6f23f218e4ceL }, + { 0xbd4a0dcf025b6453L,0x2aad6a467b876222L,0xaee94361215c42cfL, + 0xf8d1fd5de496cddeL,0x3c3af08022d0fe06L,0xb3d5dde0d09cc3f7L } }, + /* 16 << 308 */ + { { 0x1e34781aa6a1913dL,0x9a8f32287d0adc38L,0xfc185ccc28af85baL, + 0xc923d78b3ae9ba11L,0x7d494d7ea7bdb313L,0xf774dfa5af8f8b87L }, + { 0xc178ccc116e863b8L,0x2d472f2aa8899691L,0x608747cc80a50372L, + 0x8147aa90e6f90197L,0x4683d4c978c2f216L,0x8323652c552f3b51L } }, + /* 17 << 308 */ + { { 0x7d6bff984dc9149fL,0x79879e1f499b443dL,0xf4ec65232aff2a1dL, + 0x6cf3c97f27253aa1L,0x95b9471eefe6f72cL,0x3959bd816c8457daL }, + { 0xe2870635cf112073L,0x84e44933ec12174fL,0x67a592deedf434edL, + 0x0c93cdae2897d0e0L,0xe344ecf463c89730L,0x28098b7567a1133fL } }, + /* 18 << 308 */ + { { 0x62e96dc7a12a0cd8L,0x09d7c6f0f02a3d87L,0x9d9fd51233f8929dL, + 0x1231952dab376555L,0x6ef6823c8e3d2d63L,0x7ad2e5405a01c12fL }, + { 0xd1bfaec479af6fc8L,0x4555fedfdad97daeL,0x0e6d3f0155750bdeL, + 0xd37ed9f0056f6128L,0xf1fdf91c65fe6ff7L,0x3ece19ae92d05e43L } }, + /* 19 << 308 */ + { { 0x07d2075e750fc5d0L,0xdc2b03f6a07ca45cL,0x0248d87552efef7fL, + 0x2dfdaf3f744e727eL,0xbef861b8d9b2bcacL,0x5e6363f0baf394c7L }, + { 0xe8f23bbec973934cL,0xb43d619a50ea324dL,0x2bd5e0075842d6cfL, + 0x5c5af62217646e90L,0x5d95d8fd222ec05eL,0xc9adabb45bd67c31L } }, + /* 20 << 308 */ + { { 0xa5c08e8bcc2c9a2aL,0x70e1b4058baaf0fcL,0xf29e1e5c9e36e50cL, + 0xa3d9080080f258c5L,0xc9ceac25ecad4498L,0xcb73130fca32f3feL }, + { 0x2dbe620c48b3863dL,0x8c52727f14ff53bfL,0xb60b22a86b45e9b8L, + 0x81e05bc0f6483c5dL,0x217caa6bcd542972L,0xffab716afa780778L } }, + /* 21 << 308 */ + { { 0xaef1278b0ba5a344L,0x253be7ad2d0c3947L,0xce58bf0fe5408f09L, + 0x867b0d6fe21228f4L,0x815abb5dca61e691L,0x0da28f58f3e94434L }, + { 0x5b0fd178ca4cee2bL,0x8989604240b13224L,0x8e2fe19616c251a7L, + 0x7b3381cb11b17162L,0xc73d96a427ef2c0dL,0x76b7fcf36899c135L } }, + /* 22 << 308 */ + { { 0xcaee3387cad8b585L,0x58446c1ad59d8777L,0xb8755fa540888d8cL, + 0x7868510654428813L,0x7bd21629136e2b59L,0x249903a6998254a3L }, + { 0x2cc73a751f8fd813L,0x4b1a64576d4f3a70L,0xea2aa620b2e7a0fbL, + 0x77c8cb98202f6ddcL,0x68ba9d261e3851cfL,0x936fe8cbfe02e6efL } }, + /* 23 << 308 */ + { { 0x8b84121bda75aba3L,0x4440272d74602c33L,0xb8110b2a1e8a8ab0L, + 0x4de462e9391cf47dL,0x9173d756519b9ab4L,0x3df52d13ba8d5dc7L }, + { 0xd7a822eaa418b01fL,0x58be2b076585f7d8L,0xaa814fde00fb449fL, + 0x6b8260fc7da43c5dL,0xaecbfb442351ba9cL,0x9cbe3d199f8db60aL } }, + /* 24 << 308 */ + { { 0xe5d3e0d80d7410d6L,0xcfa9ed742be432c9L,0x60044434a85a0686L, + 0x93b357166ad6918aL,0x1a3c3e6d051762beL,0x80813589b0ab32d6L }, + { 0x64214b92aad403fdL,0x684befc14d3fb746L,0xaca5a51479515046L, + 0xacdba03472e84485L,0x61aa2834287d9e97L,0x07a515a5cad222e7L } }, + /* 25 << 308 */ + { { 0x8f631b17bc04e9c5L,0x017527212c515161L,0x4358d8e9ee7769a5L, + 0x18f0aed0b59dba1bL,0x035c6bb644973218L,0xa49a4cbcfb3897e6L }, + { 0xd2a0b7505841ab18L,0x8fe952dca6d2d43dL,0x2d30add69a71d0ecL, + 0x0cb84c402c5d440aL,0x33f3cf7c7c47846bL,0x88703c65bc8e8b3dL } }, + /* 26 << 308 */ + { { 0x3c3db9419474059cL,0xcfbf13ad72820ae8L,0x3f84300c51c37d62L, + 0x0f78adc45529d333L,0xa19be46482e34cfcL,0x9ed07ee011c98376L }, + { 0x5113e660b5b6f6beL,0x56f2d2b37a5bc818L,0xd99290c61c2c822cL, + 0x39c026b8b27aafceL,0x8692150b12ef7c76L,0xa55426d1c6de9e16L } }, + /* 27 << 308 */ + { { 0x889aa8ee3465358fL,0x5885ee29afbefa70L,0x05f9dbd290b6ff58L, + 0xc74be0d09b5e02afL,0x4b7da27ea6b29d44L,0x2ad60aefcf68eeddL }, + { 0x2ba942b3388c81c5L,0xda8badcc368e2e62L,0x33e95ac87a9e8511L, + 0x37453bbae72008b3L,0x3e1f181195eceea0L,0x719f550c7b19a417L } }, + /* 28 << 308 */ + { { 0xb03093068af19670L,0xd784125a34c6bf0fL,0x0b425ee0255a8396L, + 0x91076433fb541162L,0xc4d8188586f47a0eL,0x3b767d54fd7bc7c1L }, + { 0x98b405d3bee196e9L,0x4ef9c511edaccf4aL,0x5a6deb6503f4f1a6L, + 0x4a22ca641b4c5104L,0x2cce36679145ce41L,0xd05187523206810dL } }, + /* 29 << 308 */ + { { 0xa5746e07f7e11342L,0xb50e390f2e2ddca0L,0x3847749bcb288bc2L, + 0x6ff43ec646ee679bL,0x343b3fe2c5257b02L,0xc0f57f509b823eb7L }, + { 0x5ce3d2c8aff42c7dL,0x984c9b99c3c76f3fL,0xc8559f58b8823b92L, + 0x883ac8064ce4338cL,0xecf8aac3389d8ebbL,0x9edaec10b40bfb16L } }, + /* 30 << 308 */ + { { 0x0ed8a07cafb04e5eL,0x7e95ed898f6bc911L,0x6a4ed37113dcc222L, + 0x9aa3a43296f07c7dL,0xe819a80b9b338e4dL,0x65fc2778278f53b5L }, + { 0x788408e9024163b3L,0x159de8bb7de54f06L,0xc953e21281239dccL, + 0xacb5ea2c6dd62ce9L,0xf56ac93b753f4ab3L,0x2a1a09b5eacc39a6L } }, + /* 31 << 308 */ + { { 0x89dcbf021c5f4cb9L,0xc0fbe7ce210f98ffL,0x3dc3c743b897cdf2L, + 0x931f9dbb5d02c43fL,0x0ea9f164f74db981L,0x504938874af9f53aL }, + { 0x86bd3ed62531b8aaL,0xcc1fb6dddcfca2a3L,0x24b0cbf2b97abaa9L, + 0xd81ad35c9073f19eL,0x4dde5dc05db7fd5cL,0xce410880e3ac9b63L } }, + /* 32 << 308 */ + { { 0x29d81538037bebadL,0x76e52c73d9e0b78cL,0xaa4ace6e8783d1fdL, + 0x9c14ebddf0e3c126L,0x0eb1c08d6eca4b71L,0xd10c6b961c91df35L }, + { 0xdb8119bbe81bb84aL,0xf784d3c117e3ceefL,0x053c916835436f81L, + 0xeb41ccbb9b18d212L,0x93b3fb43b1bc3497L,0xd85a7c758c1ced81L } }, + /* 33 << 308 */ + { { 0x90b606b2fc9958e6L,0xd39965b6f94234b9L,0xf4a86f1676f4dd03L, + 0xd6a7ba54470f0f7aL,0xa1b85c0ca86fce7fL,0x2b50f14e574c4cfdL }, + { 0x4aff867d80e783bcL,0x031092eb61f78fc4L,0x8ad0d7486fe0af1fL, + 0xb56b1a1a0cdfa574L,0x586c916a56466e12L,0x427e5946d09a9d1bL } }, + /* 34 << 308 */ + { { 0xdd0e3ca276d1b2e5L,0x07dea7e48b4cb3a6L,0x62a63cc7fc4a0f0aL, + 0x048478ef5ea2eccfL,0xa77eae472e34c1a9L,0x7a2120751bfa5dc6L }, + { 0x0c1fbbecabc233ffL,0x6255fd91dee18d7fL,0xd6da39aec38462ebL, + 0xd86bc3194be435f9L,0x23567d64291c606fL,0x6b85038af67051adL } }, + /* 35 << 308 */ + { { 0xbe79e1b1eef4ae7cL,0xa45668dc42fb7357L,0xcdb3b3ee2d497a36L, + 0x6ef724e6c5f8d861L,0x7e8834523802a324L,0x641b3a81aba90442L }, + { 0x13bec555ae4c2544L,0x340d34f927d172ceL,0xfcfd933bd92f558cL, + 0x57d8e300d5a669bdL,0x9f745ce71883049bL,0x19690a31e261f9ceL } }, + /* 36 << 308 */ + { { 0x004105c3811af84aL,0x01307934a7934a0fL,0x179fd49b9b3226a1L, + 0x195d9e5cde6834b4L,0xfbb79dc00e6051bdL,0x354273ed367f4487L }, + { 0x4afa9d4574fb892dL,0x03ae905ea1b7f3bbL,0xea32cd5d592f6122L, + 0xa758eed2f1103301L,0x9dde4238c59d1cc8L,0xe2760bcc51022a42L } }, + /* 37 << 308 */ + { { 0xfed7077b7a7134a8L,0xe65b4eaefe0cf05aL,0x130de76be626841bL, + 0x499934ca300117fcL,0xce74885d4e186b5cL,0xd352d0d2029bee7bL }, + { 0xd86c448c857a38ecL,0x8139eb50a956da9eL,0xa036de4a93ce7131L, + 0x3f9eba375041c9d4L,0x8c24408e548f74fbL,0xa74053fde942bf8fL } }, + /* 38 << 308 */ + { { 0x64cb00f586ff10acL,0xd1eebc4c9cbba8d8L,0x427fad8af3157125L, + 0x9f8eb84cf7523b0bL,0xbdd082bf2e6dc29cL,0xfe40623823d3c315L }, + { 0xad5df7fb546d9dd4L,0x83cadc4b8e42f3c7L,0x7c90502c36876485L, + 0x4f33eccda35bb6d2L,0xdf7571383a79b9baL,0xd250b7d2e6ddafaaL } }, + /* 39 << 308 */ + { { 0xa52a7595504417a1L,0x540f70b014683af9L,0x5f0d1560f27a9620L, + 0xccad06444b2147c9L,0x92223275e52c8eccL,0x30d6b52b7cfedb7bL }, + { 0x2161f8bb9bb5b844L,0x075b9db87033586cL,0x5748d512c8c5189aL, + 0x95d76a950f0aab91L,0x91f85aaed0ce9c56L,0xeab8cd9b8434e695L } }, + /* 40 << 308 */ + { { 0x54f84d70d377d7b0L,0xb745d1903344bc4eL,0x1c693ed08f33aa53L, + 0x990ed45f8bfbee7fL,0xad620c9fe9b258fbL,0x465ccb101a54bf46L }, + { 0x5330a0d3ebc40951L,0x34423e8ca405da61L,0xeef1ce78b83043b6L, + 0x99678f22ac06d182L,0x9213f57d1802f14cL,0xf8549616adf11fdaL } }, + /* 41 << 308 */ + { { 0xc6ca95476c66fa6eL,0xcae41345bdd5b16dL,0xd72a41a4ef022783L, + 0x810f4615b2d5154aL,0xfddc469e6d333af9L,0x3154ccbb02d2bf38L }, + { 0xb33d5c59fc1a0bdfL,0xd8c3f8743c971fb3L,0x5e47ec01114e68b2L, + 0xa440a83fe9baa164L,0x353d01c397c26b35L,0xfaabf5dff03b7672L } }, + /* 42 << 308 */ + { { 0xdc2a97651e22de2eL,0x91eef436b6cd3b6dL,0xff099200f99ac721L, + 0x20faacfed4f89e8aL,0x91bb24373fcfe45cL,0xb7a152897b6d3ff6L }, + { 0xfee966c0ef94332aL,0x944728473c81b942L,0x831d36dfab1a553fL, + 0x244bc8393023cca1L,0x3f4a49d57e7be940L,0x4159aa9d7b71c0e0L } }, + /* 43 << 308 */ + { { 0xfc25fcab5b16ee64L,0x44f807e06841acd2L,0x5f43cfedf59c3f06L, + 0x9279c8110c5b59a7L,0x825df117194b80beL,0xe2c18880d27d6fa7L }, + { 0xc9aab2e66a333721L,0x1665b6f55b034c1cL,0xf28fffd13df9796cL, + 0x23caca87bbefb8a2L,0xfc556d575f7510f0L,0x41990ce8552dafd0L } }, + /* 44 << 308 */ + { { 0xf31796d2b6e392e1L,0x199d624893b3395eL,0xef14c7c212f9b763L, + 0x721ebf2143edb7a5L,0xa40b88945e96f3baL,0x8770608c4cff8394L }, + { 0x990c99ae8d0def0eL,0x292b26dfa15a5649L,0xa98fda2c91ca89d7L, + 0x916cb1b4973e5f5fL,0xa2823f13a72de0bbL,0x415f7bd28cd3219dL } }, + /* 45 << 308 */ + { { 0x5cfde16a9fc0e90fL,0x61bda4caac6c15d3L,0x5935e48e2a79d928L, + 0x31213c7c82f986eaL,0x170dc539bcc4c0dfL,0x2e0d29406f11823cL }, + { 0xd2dbecac80fe659eL,0x98b7f46b8399d8b8L,0x259f975abb204589L, + 0x65f3073cd5c52a46L,0x0f4c007805dc7fc4L,0x16c49d403031a8ffL } }, + /* 46 << 308 */ + { { 0x95705b15359816d5L,0xce0c4379d0641ed7L,0xb3f0d8321e8a448eL, + 0x8bea060873e2d711L,0x5a85fb2f6a040c03L,0x7c19a2185bcebd4aL }, + { 0x2b10a87aa31cffddL,0x4fc728fa9a5814a2L,0xedabb0dc63bdd2ceL, + 0xdb90173f96bdaa40L,0x543c4f01527ff659L,0x5dbff7ad0a33b251L } }, + /* 47 << 308 */ + { { 0xeef30ea55e636f5dL,0x8df2d4040bccc4ddL,0x8b0d6f35ef1afe9fL, + 0xbd288e6ef8f86f6aL,0xbc68817ebda45411L,0x8a6f50070faf9e7bL }, + { 0x6158c57a53d4050cL,0x6d5a3af165b2252cL,0x10f62839f450886aL, + 0x8b9ac19b1df85080L,0xc160c1567553ed58L,0x2195ab29cb449cd9L } }, + /* 48 << 308 */ + { { 0x521f4af73ed03d5fL,0xe3461f66eaf9064cL,0xad099ab7ae03777fL, + 0x541cadcdb65f73ffL,0x53430463a86059b9L,0x8ff88fe5043e9f82L }, + { 0xd515f4c7e42cde45L,0xf7f3dec3f41c3269L,0x7bed53567ef1b8ffL, + 0x8782b45f1295b5feL,0xab54ebaa03917627L,0x8516beb28787ed9fL } }, + /* 49 << 308 */ + { { 0x24b2b95b113940daL,0x8c24d8d3f9c6e6d1L,0x7c584170eddaaf29L, + 0x249267171efd01aeL,0x692cf8f40cd0f2d5L,0x0bf82e142f960244L }, + { 0x6dbcb6162dabe927L,0x76d826d20aa1eed3L,0xe4492fb3be98af99L, + 0xd4f27cbea50dd711L,0xb7796efe2d8085daL,0xf2d42519ec4e8ec2L } }, + /* 50 << 308 */ + { { 0x3fbaf46dccc3c261L,0x773c240c1b646e80L,0x151a711f363b6a5bL, + 0x3c8680b1c53b5b59L,0x8ee6795f9fb234b6L,0xab7840aa2f673211L }, + { 0x0a1a0ff3224a8184L,0xcab87319c71bb575L,0x7a9e9daa8125668fL, + 0xdc607b016c4cff5bL,0xa54cb4c792e5c760L,0x977e4c93d99e4655L } }, + /* 51 << 308 */ + { { 0x87d4ff71ebe95680L,0xa2093915e5adaac7L,0xd5bbbdade32f5d9aL, + 0x5d61056cf328a4e1L,0x61fcdb0f353f565bL,0xb7b8ba004efab5caL }, + { 0xb5bbcfa410f05eabL,0x483ae9221f09a105L,0x17d94ca44bbf4753L, + 0xf734a8cdbbdc9a94L,0xc7f01a4244e81e2dL,0x60c3e777b3ba8033L } }, + /* 52 << 308 */ + { { 0xba7df5a965b68624L,0x30b4d6ed6e7d58bbL,0x67e52341dbb81762L, + 0xd697ab1b0deeac1dL,0x01d15e8e5577ea92L,0xbb12d72498fb38daL }, + { 0x302faa6d4e04908dL,0x66cf6cb909b90a9cL,0xcd665dbd98d96736L, + 0xf7d3c528b86f3af4L,0x4844c7541d8b07f4L,0x2a77d7b91eaf7dc0L } }, + /* 53 << 308 */ + { { 0x8a36c9b57fceaa87L,0x5110912b553c7ad3L,0x4aa51166d5eca67cL, + 0x05740dcf07a5eb58L,0xeaafb3e3396857a4L,0x1ae9571bba8d62d9L }, + { 0x2736975500272434L,0x2c74325c59872fbbL,0xd1d8291709dda11aL, + 0x2a5334eb4683e8a1L,0x22cdd088e3481df0L,0xab1c5f5b4fddc546L } }, + /* 54 << 308 */ + { { 0x1966aa0515f46174L,0x495901bd2a074050L,0xda5b0cdebba902baL, + 0xc47c518a684325bfL,0xa5df133ec4d9d6d9L,0x3771f465fbf7d31aL }, + { 0x0a73718c02b05d1aL,0x1107cd45534237a2L,0x582cfd2980f5d897L, + 0xf51a0a88dab0269eL,0xfdea51cfea1a22faL,0x3c9a0d247a13a324L } }, + /* 55 << 308 */ + { { 0xcc330f58c42f1ce6L,0x8e1fb7df534efc38L,0x2a37208f5fa5a01fL, + 0xc06d8447369bdbb6L,0x0b1ea5161a3e36e7L,0xfb4a48366ff9abbeL }, + { 0x5989c2d524419909L,0xdeaa6136f1d5b1caL,0xac6003b04ba760f1L, + 0x3a6d5422059081beL,0x96c7fa9df797e22dL,0x67c2f77fa9f3addcL } }, + /* 56 << 308 */ + { { 0x53e59f251d70eb73L,0x8aed17afe69d0525L,0x26ddc17864413768L, + 0xa7c8d40f5e48c349L,0x29ad92d187ff01fbL,0x8f4e1b3b965b2de1L }, + { 0xb83cfadf1446eca2L,0x7432bda4e609d416L,0xcf97e8a3f1c7de69L, + 0x45899bd832f55f07L,0x41a6811751175738L,0x89eeb115b8efff21L } }, + /* 57 << 308 */ + { { 0x9dcda4f3723fc25eL,0x710de79fb5d954deL,0x095ffbf1f0b7d129L, + 0x419a2a5e32651179L,0x7b249135827d4268L,0x9dccc98d909fbfb4L }, + { 0xcb4b0cb016554ab5L,0xb2fc635f6d84b255L,0xa7f8f3f553512b87L, + 0xc72633f300ec778bL,0x4e07d91a4f1841a9L,0x2a1adbbdcb4f478cL } }, + /* 58 << 308 */ + { { 0xe31333093bb794fdL,0x34c68bac33b3be44L,0x953fa2c412172b7aL, + 0xa9afc12d4fdde6ffL,0x30b5302ae9c7804cL,0x4a1746c702119e68L }, + { 0xc4d0c7d323e2ec51L,0xbc821f217143d613L,0x8f41251a673e203dL, + 0xfa32c06aac2ca4c3L,0xf4343f2799a7c431L,0x8f7d489e6b96d959L } }, + /* 59 << 308 */ + { { 0x183311763f6278f9L,0x4fcc5b653593cdd5L,0xb09b5880e643f83dL, + 0x0f130a3d2c78466eL,0x926d7c3d2b1c1ebcL,0x7217f875662ed4ecL }, + { 0x2d3be028d81cdad3L,0xb2a04e3507a38019L,0x8da8cddfc9a3097eL, + 0xbaa67f60ddb20228L,0x698fc1c407f04de8L,0x6f0e1d6d7e86db6dL } }, + /* 60 << 308 */ + { { 0x54a01e60936c3ebaL,0xf326fe96ec01b12cL,0xcdfaf00366e4de2eL, + 0xc53dba07392fd0a8L,0x00d9b80f6ec46004L,0x84d59be83ba63f8dL }, + { 0xbac4ea439dea6062L,0xb4b4845badd568caL,0xa6ca3d34d225e2d0L, + 0xce72955db50070a2L,0x56e5c91321c78b68L,0x888eb198999488a3L } }, + /* 61 << 308 */ + { { 0x65bead3c1c2de335L,0x0ecdc057b18a6778L,0x821b836983e57ea8L, + 0x84c80b574a5c11dcL,0x0b6432822ac9ad27L,0x8e09a7f344fe943fL }, + { 0xe510f47daa92dc94L,0x8bb0b5cc6a1666a3L,0x55315bcc24645380L, + 0xe3acbed113dcf7a1L,0xff99c90e3c9a1610L,0xfbe9aa1bc326e1f5L } }, + /* 62 << 308 */ + { { 0x5040bea56827b6e3L,0x1049e004d935eb24L,0xa15f9a07ba9bde68L, + 0xda430c55e6087e70L,0x30ed69af8e84b7c8L,0x8498514eac9d6a72L }, + { 0x69c783d64cb27e79L,0xe55d31a09647a572L,0x0479e8b2fbfb82e8L, + 0x3e845922b52f08c0L,0x252f755f0dbca622L,0x6219778389ddfee8L } }, + /* 63 << 308 */ + { { 0x175264893ca1461fL,0x54c432f92b6476bfL,0x0e0be36a530795f9L, + 0xb9896dacca583429L,0xe4af98239d4e6085L,0xa38b7c4b4a7422ddL }, + { 0x74643ef47163e421L,0x74c28314895ee61aL,0x637c79c20d62b657L, + 0xb232ec619bf2b3afL,0x27bdbfb4b2d5992eL,0xcc6e424c49afb181L } }, + /* 64 << 308 */ + { { 0x5255508c11c92f34L,0x9a346cf3a294d382L,0xd9765eea3095205bL, + 0xfea2ed702c470ef7L,0xf5e8a0fc9c40bf0aL,0xb572390ee4137a16L }, + { 0xb91753712bf2f545L,0x2c2d0f4c58cd9cc7L,0xbea6bce902385486L, + 0x46208408a8bc3a94L,0x64a87a2a3ac45044L,0xe40da33c7df70151L } }, + /* 0 << 315 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 315 */ + { { 0xee9e25d939161b8aL,0x8763f2a2e2eead91L,0xd2fc1157d2d91300L, + 0xe7597e2fffcbe50fL,0x4be3814fe11d376eL,0x1eab3d7edbf14562L }, + { 0x38a107c0c0ad183aL,0x829766267c753bbfL,0x18014e09caebd481L, + 0xb28c331bf9ace60dL,0xe8fba04f211cb8e7L,0x41c4b797e42dc65eL } }, + /* 2 << 315 */ + { { 0x009dc2f4c3e88580L,0x4a405be899db1fb5L,0xc89bfaa2ec5d91feL, + 0x461be9a0f160afcbL,0xfdd084bb7d7566b5L,0x795275e8e48099a2L }, + { 0x1b461fc9fe9815dbL,0x576214cd73627bbcL,0x3246332d9f09a206L, + 0xbde4c0c36941d6efL,0x44ef03fdf387f5f6L,0x99c8ac0157b63400L } }, + /* 3 << 315 */ + { { 0xaa512f202f6e4301L,0xef668a5fbf94a1ccL,0x08713c3015861b88L, + 0x49d47551c99bb2b6L,0x6db5f812e2f0258eL,0x70c9b299998d7435L }, + { 0x46168e1c5d176ae0L,0xec3306e4f730ec30L,0x49439df3ab69c15dL, + 0x1040408bea0143e4L,0xb48ab8eabc549b0aL,0x4aa38bbf10f89223L } }, + /* 4 << 315 */ + { { 0x7e4851599598f49aL,0xbdac3d5e9629305bL,0x20de0dafa6fbabfbL, + 0x04f015838f09fff7L,0x5a0562976a06994fL,0xf51dac8f6e3ccd33L }, + { 0xc087ef9c3af507b8L,0x525ab76e6a5c6663L,0x4fc04814d916ee93L, + 0x3369c978d23d140bL,0xb0fcd70f1662028fL,0x2ca77de2e1e28adbL } }, + /* 5 << 315 */ + { { 0x838acd1bc512bc71L,0xac06d6bddc18afd0L,0xc991c1e39ec45f4bL, + 0x667c5e89cc27c68eL,0x0e059b04ed07f829L,0xceccf1d4cec4b3a7L }, + { 0x3d9c2dc9b953f9a1L,0x4be2f7e72d599b16L,0x1a2054b197256c26L, + 0xcf66fa478b4fdfebL,0x896cc1b38134d7efL,0xa17264cad41dadbcL } }, + /* 6 << 315 */ + { { 0xe3ccfe8e37627e56L,0x00733a867b6b21a6L,0x3f13e2cbb605c427L, + 0x5ee12395b0d80992L,0x4dcaea94b9991381L,0x4cfed7ee8c4c4b6eL }, + { 0xd7aad54b7f7f45dfL,0x2229407fb3809bf8L,0x6eb31eee68048fd9L, + 0x693842dfd57225fcL,0x3e62cd85a88dfd3fL,0xc6307d53d5462cf1L } }, + /* 7 << 315 */ + { { 0x2d15615ef344f5fdL,0xe0ba6a8aa7f23989L,0xbbfc58041c84e3f2L, + 0x22ffeaae6f4ba826L,0x1e9bf27494292682L,0xc768f89146c02af9L }, + { 0x894127d6177cdafaL,0x8d0523da2acdc791L,0x71ada9aedc78c3c4L, + 0xf21dbbb92c532a01L,0x0c797d5eacb20fdaL,0x1ff99d7616cf57b0L } }, + /* 8 << 315 */ + { { 0x99b5f150493c1d64L,0x3422b656fb74075eL,0xe7493900ff19bf24L, + 0xc82e5b80260925edL,0x3398d340c0ea1eafL,0xe7de2ba11287121eL }, + { 0xea6dfb0b87847031L,0x73bed0a1566af2f2L,0xe26678bf12012999L, + 0xb5369e4d32e5cebcL,0x2304eac86d181e32L,0xafdbd9543d364addL } }, + /* 9 << 315 */ + { { 0x5b1a53ca75da4189L,0xa90485802eb4862bL,0x319424092783ad6aL, + 0x15a4c5e11a9e025eL,0x841bc53313837199L,0x6e9d3e14e642954aL }, + { 0xf4a02bbdd436ec5cL,0x62fe177bc6d6ad53L,0xedbf1e4eac86425aL, + 0xff9359c8d9f752f5L,0x79c685d92d7ad656L,0x8d82c0c4fdde9052L } }, + /* 10 << 315 */ + { { 0xf55f868e702f640dL,0xe459aa9b1dedda11L,0xbec0ff9bbb5ba193L, + 0xf7325c4957724703L,0x5ab8f06323e0e4fbL,0xfbf02e91ecb0fd7cL }, + { 0xcc72e8daa2e5fa31L,0x47de252832cb53cfL,0xbfa646e64252763cL, + 0x7a769efeb8d81de3L,0xf5ec70031e772f00L,0x049bea9a2729aa5eL } }, + /* 11 << 315 */ + { { 0xe987ba54759090d6L,0x904d6901619ef08bL,0x9e16d1382024a6fcL, + 0xb6f0459ba9f3b7e4L,0x1f2a530817ee069aL,0x99403b2e2be31049L }, + { 0xba1663c6bfb2f288L,0xf829195cc7a92b41L,0x89b915ee8ae621b1L, + 0x3fbbb1e150f8ea92L,0xb1fe7f978c901ddcL,0x16d1f62cbbc69ca4L } }, + /* 12 << 315 */ + { { 0x51f19bb3fda072dbL,0xa815459fe3f7e0a2L,0x5f7cde2f987112caL, + 0xdc51d948759de2cbL,0x9d05c410ed49bd98L,0xf063ab99364341fdL }, + { 0xd7869d68d1aa0a11L,0xc20291065d862d01L,0x7f258180c2591073L, + 0x7b90fc7a6ebc4ebcL,0x5565390f3dda1d68L,0xae77fca8a44e4493L } }, + /* 13 << 315 */ + { { 0x97564e4847c49ee8L,0xc56bb5a9ab4ebef5L,0x80d969417b4f86bcL, + 0xa594b4e541026cf0L,0xd56c89965a89ece9L,0xbcf609316a0f922bL }, + { 0x702596161103475cL,0xb1224fb58a2a2abbL,0x0a437a03715cd61bL, + 0xcbe2d2b2739921edL,0xf3b1b5e9385541c4L,0x5d0984f4ae010520L } }, + /* 14 << 315 */ + { { 0xb4a2742dcfd9295eL,0x9cd36774ae929cd0L,0xb15fadccdd7fcf4fL, + 0x0b1fa2b337d4fcc6L,0x242c7b26f01c7ab7L,0x2be8131b50574cc9L }, + { 0x6ee50f42bd89a03cL,0xc7f6ff8f005e7765L,0x04d13af18420501bL, + 0xc22e092b1b6e7d2aL,0xa393be7ee9516f80L,0xa2593652b80bb5b5L } }, + /* 15 << 315 */ + { { 0x5caa5da68b23bebbL,0xa1ad33e81fdbbdf4L,0x18dc93cf4e5c1de0L, + 0xc3e6addb5bd9e178L,0xf30d517e7cb8cd03L,0xbb84ce54f1abc417L }, + { 0x0774b64c67699659L,0x228005b9b7d4a401L,0xd8c2ec5b80b2d3d2L, + 0x419c4cd93450ba7fL,0x520ae681789286a6L,0x24b67ea9aa8bcfbbL } }, + /* 16 << 315 */ + { { 0x9e41b9b70f74808fL,0x2d835dae0c061bdbL,0x67e50c8cf272346cL, + 0xc98a5ef5def57493L,0xc2dea8afa02676fcL,0x59508de26ace4659L }, + { 0xc2b707aada6cd733L,0x6c1f226a4be7bfb9L,0x5b580fa2a778c20bL, + 0x272c3a1d57af166bL,0xe47a64a9ca78ce62L,0xd12db7d771d35087L } }, + /* 17 << 315 */ + { { 0x6a37ac5a2ada7e64L,0x664594de04e35dbdL,0x3a82f748ffdbf300L, + 0x4525ddf155975f5dL,0xcfe5a76bbdf2035fL,0x1693a99f0fcbda84L }, + { 0x5bdb76856a297cdeL,0xdb9ad0cef1d1009aL,0x9e9dae1caf902a00L, + 0x7e36f79f271a0a50L,0x688a0f41a2a2f652L,0x33d2178613722e40L } }, + /* 18 << 315 */ + { { 0x2f4abaff356f4ca1L,0xa2e419422d13be2bL,0x58d72e2f3d7db731L, + 0xafc2f505cd455649L,0x8a0794cd1583705cL,0x4a43066288ffe8e7L }, + { 0x2c0c031d135c8e7cL,0x8ecd9ed76b371b41L,0x17cc1ad9563843eaL, + 0x9603987cfc6b810fL,0x6e291ed7f0d9498dL,0x8c69ae62e1a4058dL } }, + /* 19 << 315 */ + { { 0x934666dd40680b5aL,0x37a9c6ac91e762f6L,0xa0a10533e4d26e7eL, + 0xd811d558ade18237L,0x6e2918ed411b121fL,0xbd9352b93c24a52eL }, + { 0xe31569ccb811ec4fL,0x3b5b977553f7d097L,0xa0d9ebfd7198e959L, + 0x63e10ab13f0a942cL,0x65b8b87f8ea55897L,0x935ea3c129aa0212L } }, + /* 20 << 315 */ + { { 0xe14dd3708ba8a3dfL,0x49c1fc3750a645b6L,0x3f0db6a32252ff87L, + 0xea2ac3c4a34ad040L,0x97a37936decf9f0fL,0x810f02326f7f92ffL }, + { 0xd96c2641184e9c88L,0x08c4cd333d5ab12eL,0xa938d8c3eda80fdfL, + 0xf2dded68bfccc054L,0x4b3da61ede36ac9cL,0x2c266df8347ef904L } }, + /* 21 << 315 */ + { { 0x4653cbfbe3443739L,0x53ea14dd8dd85382L,0x2f6d0513f26ba2fbL, + 0x374d9bee51269be1L,0xf976cdb243f1f612L,0x68b47bf7b5f171b8L }, + { 0x726e93dc7095f377L,0xe6f18c57b59fcfb8L,0xffb56a4023d9eb60L, + 0x678c9508447caf79L,0x4cec83e459740ce0L,0x820ab7eff4d7d58cL } }, + /* 22 << 315 */ + { { 0x88eac51c8e376fe4L,0x096e70c49ef465b6L,0xb35265852004969eL, + 0xbd581669d29cc63dL,0x88094298745b6919L,0x317e386c12e7d67fL }, + { 0x33848bb2e3d6f4daL,0xbace887f2a0ca785L,0x83b32feb197e67a7L, + 0x2b58535ade9c851bL,0x3e428b19c38beaa9L,0x784aa3d174f26de1L } }, + /* 23 << 315 */ + { { 0x10c5f1e5b292efd6L,0x47d92b88ddc96103L,0xc8743717e5e802e0L, + 0x47781ba8008dbb2dL,0x7abcd3acf02360fdL,0x673e2b05e9142308L }, + { 0x501db7c76db93818L,0x285ced71f33dbda3L,0x30aa5fb5cdba4b44L, + 0x93d536c2df0445b0L,0x28a77bfa10196091L,0x26b9f668e38c4c7fL } }, + /* 24 << 315 */ + { { 0x98c3a697c0909659L,0x35c3b0f297d847aeL,0x67d9f71273a7a5a8L, + 0x28e83651b47bed08L,0xfca9e849567b3410L,0x5fa9a6ded291fe1fL }, + { 0xd79682421976a995L,0xcff5bb36a0261383L,0x34166ef962e9922bL, + 0xd816b0342d433139L,0x3b62d3589c4b99c3L,0x8521f917104f7cc4L } }, + /* 25 << 315 */ + { { 0xc35a5c7874e09962L,0x1c340269e1690418L,0x2ed61ab4dca0de49L, + 0x2570d29ede2534ffL,0x9077691bc5143c88L,0xaa249a4a346f3ec1L }, + { 0x57e4f1e104de76b3L,0x206859c3f415b99dL,0xdac6f415f9a15eb1L, + 0x2bf456d00a9501bcL,0x1ceb7dc41ef91323L,0x19c1fa8c3cb8afb0L } }, + /* 26 << 315 */ + { { 0x7761d8fc6f7b6eafL,0xdc439bfdcc0575e5L,0x33853d91f1ff4383L, + 0x6da20e4b75dc1254L,0x25a53b581969a1d3L,0xb40df56723311968L }, + { 0xac150a297dd6aaebL,0xfe6865ce2a3ba337L,0xea05d97cf71013feL, + 0x0ab3cf008053c65aL,0x7cd38b647bab4869L,0x788cb867204cc6a5L } }, + /* 27 << 315 */ + { { 0x253a041e36e88e48L,0x1610f836b86297fdL,0x379d3da109334bb9L, + 0x62de4308777fa7a9L,0x604a46bd6dfefd1dL,0x9e4740ae314eed76L }, + { 0x40ec32e12efde5ccL,0xa5b841bdd92c1faeL,0x01852e23dec68e16L, + 0xc76173b88b55b2c2L,0x4609f350377d5e77L,0xe9c4167ffd67c6b2L } }, + /* 28 << 315 */ + { { 0x52732a0a4b0fc112L,0xe654744e9d125dddL,0x9f76cf7e269beee7L, + 0x2fb8bf32ff80a2f0L,0x1bcef16262b7153bL,0xdedc255a43a4201eL }, + { 0xb1b30b91acbd8a37L,0x147fae6f240adc8fL,0x5558702cb39bf39bL, + 0x171e58803e1eb997L,0x095bf301ed7c79b4L,0x29f1dbffeef752f4L } }, + /* 29 << 315 */ + { { 0xcbb2506e7535c370L,0x40ee37ec7ab20106L,0x74f502d4caca3675L, + 0x167e778db57c0364L,0x7726715b13fa3dccL,0x76097791f42e0c3aL }, + { 0xe1d990c3379dd41aL,0x432454d785c8f5e2L,0x1f90c59562ac45e4L, + 0x63e156998ffe0c09L,0xc3bb8c29d42bf0a6L,0x027d5a86ecca4cfcL } }, + /* 30 << 315 */ + { { 0xaf8ca08b20492da0L,0x37b1fa1547508667L,0xc9fc925b96077958L, + 0xb78c83c19ecac8b4L,0xd9d953a17c05a67fL,0x970ee229b9ebcaaaL }, + { 0x689cad7f55dc989eL,0xf02f05bc66c941fcL,0x8d00516281e23d8bL, + 0xfe603ffc8caebcc3L,0x592860bff303153bL,0x9ec1d5ab3344e524L } }, + /* 31 << 315 */ + { { 0x7e374b7b0f922941L,0x44b3f00174466c92L,0xcb3eb28c3c2fe678L, + 0x91079467bb9bf05bL,0x0d268749de2dcbe3L,0xb6383ba4c5204680L }, + { 0xd50269f4951d3c71L,0x9209a2d53ffbf2e0L,0x2f6496258110f811L, + 0x08fc9fbb0b31e275L,0x697960ea1faec287L,0xae95e4a8c5420ad4L } }, + /* 32 << 315 */ + { { 0xc20fb9111a42e5e7L,0x075a678b81d12863L,0x12bcbc6a5cc0aa89L, + 0x5279c6ab4fb9f01eL,0xbc8e178911ae1b89L,0xae74a706c290003cL }, + { 0x9949d6ec79df3f45L,0xba18e26296c8d37fL,0x68de6ee2dd2275bfL, + 0xa9e4fff8c419f1d5L,0xbc759ca4a52b5a40L,0xff18cbd863b0996dL } }, + /* 33 << 315 */ + { { 0x1304bd65ff0e8fbfL,0xa249adb53343deecL,0x20635fa9826e1293L, + 0x6283f098b7bddaadL,0x0d0a7820bc96fed6L,0xcd7605d47de0b9bdL }, + { 0x4f0a9751586f9eb6L,0x2f6dde5556b2521bL,0xb7efccbd76264c6fL, + 0x7df9cd35b2613621L,0xc334c8f924a2ff4fL,0x914f472a0b13b604L } }, + /* 34 << 315 */ + { { 0x89092cbc5f6bb241L,0x8b4dadacca123b83L,0x9ba420eecd2dbaa2L, + 0xf269d1982dd6ef2fL,0x29f68d03809b338dL,0x18cf8675958ae927L }, + { 0xc179d4b2bffac33aL,0x5356ffc1522695e1L,0x453474986d039c90L, + 0xcba0e0fc5a675530L,0xf369b7ab98a0c70cL,0x51f82173d508c254L } }, + /* 35 << 315 */ + { { 0x5f98e5aae8490374L,0xdd84a7506ca52a68L,0xb6904ff8a9244f56L, + 0x4c908c0362a5502fL,0x70ff1e01a8df73b3L,0x573a37f20df382caL }, + { 0x5df73cf8c7dd1209L,0x965ad402abfbcd79L,0x61a633a59e67af24L, + 0x0953c83cc64203f7L,0xe14f58f9a1fd8dcdL,0xb5ea722887a5fadeL } }, + /* 36 << 315 */ + { { 0x55466aa1d896c2f9L,0xd03ade059831fb31L,0xc46711547d968dfbL, + 0x8ade0c97bce2fdb9L,0xb408c7457f6d843eL,0xb1bbe028a709cf63L }, + { 0x1dbd25383ba4fe36L,0x1438d322dc1f2720L,0x1c3c46b9c37694deL, + 0xe57133dc3997e650L,0x754c171e422b95bcL,0x29c47f0da209c7bbL } }, + /* 37 << 315 */ + { { 0xe520480823822d0dL,0x745fe7aae3eab177L,0x6f0f4a7e808500edL, + 0x9383c632200c2bf0L,0x6f3130d7be22d432L,0xed7713d465511061L }, + { 0xff84bc04049067acL,0x33c2be61d56210e1L,0x57d63f885ac04f01L, + 0xc2fbb773284fb49dL,0x46422426e1f349adL,0x3cb627c465863455L } }, + /* 38 << 315 */ + { { 0xea06cbe9a1edcfccL,0xb0438e198aff46ecL,0xa93fb88ba450240dL, + 0xfc4a370021b6b45dL,0x2503aa5d82a21241L,0x7533f1d7f540d3b7L }, + { 0xd7a58a679277538aL,0x466d981a539c347dL,0x46f1682bf26488c2L, + 0xee2b4976318282e4L,0x8fe5e5b85a94409dL,0x40ca43a7b1a4fc28L } }, + /* 39 << 315 */ + { { 0x0ed4414c901e48d7L,0xdcabb46418340890L,0xd50bf12f20998781L, + 0x498a90232a596ffdL,0xcc877212b43f456cL,0x98d9d531f796c4fcL }, + { 0x061e3b31977c11b9L,0xe56bc6f00a00c822L,0x756e62c96887ea43L, + 0x29129d53859ec944L,0x42342589146c1fbeL,0x2f2cd4bdd1884196L } }, + /* 40 << 315 */ + { { 0x3d3815d645d94a24L,0x4cd9fe1139f3e6e2L,0x8c7b8dae8e7eb572L, + 0x7e69faf40f7deecdL,0x0e54b3c0387e97ddL,0xd12e473175a1b6b1L }, + { 0xb7163632c664f92aL,0x86ab4ea88d94e55bL,0x37212aef1133dcbdL, + 0x0c6c7fc6dfc0d47aL,0xacbcb077aa9e1ccaL,0x43cf50a726ef7fb6L } }, + /* 41 << 315 */ + { { 0xc0eb003c54d7bac5L,0x89780aea2b770baeL,0x13a194e8076bb29cL, + 0xb863585046f8aa90L,0x79ebc6066df515f0L,0x25ea422dd1ead000L }, + { 0x16b03b8106c89b71L,0xa964da878ad9fff7L,0x2c96dc6b2e7b9072L, + 0xf71788978c93f6bfL,0x4c7ecef912688648L,0xed7b4a577c663be0L } }, + /* 42 << 315 */ + { { 0x5b7cdd0ad74a20d2L,0x273184f48bcdd2f5L,0x4d8d3b4ce3ac03f7L, + 0x0e2ff518a02cc60cL,0x9c006ad8b6fa606fL,0x401606caccf627a0L }, + { 0xe7429a6f7b967844L,0xe4e5d1c1bc8ac8beL,0xc050f89ff4f46638L, + 0xd23a3eb452f918c9L,0x4528e4e202944b49L,0xeb345a689268719dL } }, + /* 43 << 315 */ + { { 0xf4fbd190ccec4c27L,0x7e042c8722674e8fL,0xbc79835ae8b33439L, + 0xc7923b8fad2124d1L,0x0ece42272c72542aL,0x02d638e2b9264875L }, + { 0xbdf9fba1904e7683L,0xcbbc0e0aac934377L,0xea154d99459ec213L, + 0x87db3f66c3023e2eL,0x7f9262d518de83a8L,0x432fef4f3524400aL } }, + /* 44 << 315 */ + { { 0x3b5566d7938a395bL,0x920dc1111f256c82L,0xcee7f231a059c8f8L, + 0xdc3da434d48b3179L,0xb1e819e913f78de6L,0x94a21bb01f9819deL }, + { 0x8ef14a96f302a94dL,0x9f897e1a079fff9eL,0xff9a4e0e54122af0L, + 0xac6a6cbef0b7f1c7L,0xfd15d9756401df3dL,0x500531a323a0b7b6L } }, + /* 45 << 315 */ + { { 0x12e22a012da0c724L,0xa0a837f3b80cba90L,0x89df9a3e2a9b5434L, + 0xf3299f64925840acL,0x0cc78a3a125b3dc1L,0xa4ea6203c723d647L }, + { 0x5cee8068d369522cL,0x3e479803432d5e87L,0x86e809363ad8126bL, + 0x93e871c9cf89d85dL,0x892e4710286c9010L,0xa075a6d3ec3a1792L } }, + /* 46 << 315 */ + { { 0x095768bc7dfddf6eL,0xc4e331b4e63c4e60L,0x1179808104f28a2aL, + 0x415e33e1bee48983L,0x7fe8050144af7eb7L,0xdf6c423b2f28fbfdL }, + { 0xd10886db007a2b56L,0xea578b286613f26dL,0xd18a9d1c2b90a815L, + 0xd4c6e8b2675c2c8dL,0xff973df5788bf2d6L,0x4fbeb6210d7e611bL } }, + /* 47 << 315 */ + { { 0xcfab317671674fa8L,0x78038a1afef7089eL,0x3109736aa27b5b55L, + 0x1b31325fc0193518L,0x3afd21a8be19b5f0L,0x548196a2d8028eabL }, + { 0x15b0d6d2a94e6be0L,0x1552ffb67afd5dd6L,0x49b1150d89bed9eeL, + 0x2c59b0bfb0d1444cL,0xab265d7eb695a900L,0xa24d0788a1dd1ef4L } }, + /* 48 << 315 */ + { { 0x4e913e1131e325ccL,0xe92f7c8f2a65fe01L,0x8e61a80d5857aae9L, + 0x2c36923d53104397L,0x5b0911d6b36d5379L,0x76eb9b56b1207ae0L }, + { 0xb5cd11646723c4aaL,0xa6bec13b98891a11L,0x09af8be29d806056L, + 0x7da8d29ecc1fc0e6L,0x231cc00e2aa8791dL,0x2ded362c042171c2L } }, + /* 49 << 315 */ + { { 0x26eb2ac96afa51d2L,0x83485eff13c04ce8L,0xdedb48718072d8dcL, + 0x4da1771d8ac3d411L,0x2d8f99ef849c6c0bL,0xea65f6bc2b5882e4L }, + { 0x60a90f58fd671216L,0xb9f3e2058af33bedL,0x29c41ec92bf02916L, + 0xcdf15b1de5ddeae8L,0x67f9ad163109e99dL,0xb9b5585f517d25e1L } }, + /* 50 << 315 */ + { { 0xae016b4811b3e20bL,0x5ccf3cf1e5164179L,0x1281ff8efe9fd47cL, + 0xb85438038e61bdf2L,0x694e42feba5856a0L,0x53f7e09759b32aa1L }, + { 0x5b9848e9c341a531L,0x9a5fb85025952b73L,0x9d5fe0dea6f82c5eL, + 0x9216a8ca44090933L,0x3e986d4bc3272875L,0xc20534f8f3512e42L } }, + /* 51 << 315 */ + { { 0x718124a1033495a6L,0xc4f28a746834851fL,0x91186d80e1baaa77L, + 0xca4e13222a761e95L,0x7b6b8322582ddee2L,0x75d396c6c3c70c6bL }, + { 0x075dcd6b54c75102L,0x3669b97c0b92622cL,0x621154e6f0cd45adL, + 0x7ff0029ff381a6d3L,0x3d37e750a726f84bL,0xc4f79202874de604L } }, + /* 52 << 315 */ + { { 0x215018fdec26297dL,0xaa06fd0bbf35d225L,0xe5fb438cab40bc17L, + 0x6a0ab335acb7f4c5L,0xbe1f4de4187a8e6cL,0x651deba961f7e842L }, + { 0x2b30b0046f629aedL,0x63bdbf8e2218f107L,0x21a21aa5f9ca8bbdL, + 0xa88cd9138304f7e1L,0x23594fc6c5e6f9d4L,0x4d4db41a6682fc06L } }, + /* 53 << 315 */ + { { 0xca2317b0428dcb40L,0x9a7bd387288b5eeeL,0xd62da6d0a060584bL, + 0x601a3d6ce8f10251L,0x65718f0584885319L,0x5a87b1c2a1bc252dL }, + { 0x27ae8015a37b05d5L,0xa624af9c98394605L,0x988220050ba4565dL, + 0xb93395c9da2613deL,0xcef9a880edcaa74eL,0x7b2ef0fe0976687eL } }, + /* 54 << 315 */ + { { 0x094f20588e5c6b80L,0x6e5a5f52846eabebL,0x9eaef2d7370a9345L, + 0x12d6f20687c19719L,0x0d2494ab9c44076cL,0x15ccc737de9309a6L }, + { 0x8eeb8faf94ca6587L,0x7dc9a4fe3fe363f5L,0xf02f6e03b3b08270L, + 0x31adbe77daf15507L,0xc0fb2814343bb4efL,0x724007519bdc1d91L } }, + /* 55 << 315 */ + { { 0xd301525c1677fcb7L,0x11b7141bfb6b0dc1L,0x01f4950eb2163b70L, + 0x34c758c6ed3c0025L,0xd1b1c7573a5196cbL,0x7926f0a42fa19c66L }, + { 0x107e5d32b1c47233L,0x0fe50b00cacbdaa0L,0xf45dd7e8e213397aL, + 0xca6b2de9eaa1db7dL,0xbf234b55dd09c2eeL,0x10db87d1a1db37f3L } }, + /* 56 << 315 */ + { { 0xaff57c87de0572ecL,0xc0745250826246c4L,0x523910fc700ef250L, + 0x8c23aa5793faa067L,0x87f7c7198e7dcf75L,0x45ef4adb46695227L }, + { 0x0ffe09d196ceb1e0L,0xfb72a05790f3383aL,0x62d26e5e07c220d9L, + 0x03e19605766b1e64L,0xa774669458c17fb7L,0x9a851d828e7acfa9L } }, + /* 57 << 315 */ + { { 0x150e936f4baea8efL,0xeb5328d68239dfe4L,0xe064fd95b5f987adL, + 0x13d3803d52e7313dL,0x0e9738f5b215317dL,0xb6dd60a7974be106L }, + { 0x00fa92bd6bac81d0L,0xdee050f9e7cb2338L,0xd7943d4f9075745eL, + 0x07cc4170819cfd9aL,0x21b7e0b04aef1468L,0xd7520b77aef07b1dL } }, + /* 58 << 315 */ + { { 0x126c012681097c49L,0x95339f9475c02669L,0xec3fc15b100115ecL, + 0xea5c8e9c49fb787eL,0x63168108bd3fbc19L,0xdbf2430541573590L }, + { 0xcaa3a69686dbc847L,0x2c464fcb70d76739L,0xdd9e0bcd69e2fd74L, + 0x4ae92cc01652728dL,0xafe3e24812b060cdL,0xf3776c6ff951a38dL } }, + /* 59 << 315 */ + { { 0xe4ab1c417af22e76L,0x35a8addf038840dbL,0x95ba3e3dafd0d7b2L, + 0x2a7bf827f84417a3L,0x0bc177c729bf5a83L,0x29ef7f8bd09905a3L }, + { 0x1df34fb1385e6c69L,0x079bc0fcf99e0d19L,0xcd2dbbc4f30eb5c7L, + 0x2d364701afa7447bL,0x3c7bfa087a791ef9L,0xe21508c8e71166d0L } }, + /* 60 << 315 */ + { { 0x0b204c9ac746ec60L,0xdd5efe2718b93b24L,0x484474e0ce15332eL, + 0x690be23d05a308b7L,0xeea3abfcb0f7081aL,0xaff69f36cd8e8720L }, + { 0x5dadd080d951329cL,0x060c379c8cae67c2L,0x8e284705b20851baL, + 0xacc8d8a0e5df0e85L,0x8c024e789463544dL,0x15a9a3f08003076cL } }, + /* 61 << 315 */ + { { 0x095e284899e0ecb5L,0x61e9d5893415c1bfL,0xb1207d3017f5c585L, + 0x75f73f1d04e97243L,0x868551aa77bd50d8L,0xd530e0cc197f7d84L }, + { 0xdd6ab731ea9fb71bL,0x26e5b52e2cf9510cL,0x4fba03ff11a88911L, + 0x6608b634e921e323L,0x4baf22f836d46a1fL,0xb8bced501bc7ace0L } }, + /* 62 << 315 */ + { { 0xaee397fa327d9bbaL,0x9a45e7a2d832e3dbL,0xccb43a730582ae33L, + 0x457b3271d4093b12L,0x409caea6370bd663L,0xa5019f25657f693aL }, + { 0x5851c78a16478fe7L,0x5e09ace7ddf17dd5L,0x89ca68da0763656cL, + 0xb92d3321e2bad2d0L,0xdd5642098422f6bcL,0x4a6ea69946c04923L } }, + /* 63 << 315 */ + { { 0x7ba1f48579120405L,0x6c136597898be69cL,0x1e75e1586dcacc38L, + 0x3d3cb58b65ee4cbeL,0xbccee7a308db0caeL,0xee8bff34e77edfb7L }, + { 0x123bc3f036f60cf7L,0x3b1dc9e779bb4c78L,0x036a8049fe5f0d85L, + 0xc4de23d318f66f39L,0x593cf51e3c436c16L,0xd4d40e906769584eL } }, + /* 64 << 315 */ + { { 0xf6827150844eefc5L,0x002e82c44515ef68L,0xa46c8f55c51916c4L, + 0x98c3524b61ee081fL,0x5ab7f2c2ad64872aL,0x0b503ff07e555faaL }, + { 0x802e0d23b4c58d29L,0x122890402fd917feL,0xb56d19087af20d26L, + 0x8d619e216be50784L,0x10fdbb721372b851L,0xf2c1673e4935576eL } }, + /* 0 << 322 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 322 */ + { { 0xd97a9b1451a135f6L,0x6d16aaf597b4df14L,0xc57160c254818818L, + 0x4dbdeab61d59be44L,0xb93a9dad81f2b247L,0xe2868cf5ecbcab33L }, + { 0x5e1ce82883a86711L,0x29a9ca2f29c55428L,0xe716273a2d82b0dfL, + 0xb017f5f6ac8ff52fL,0x7563e79970ea7ccdL,0x5fedf0a63f0e674bL } }, + /* 2 << 322 */ + { { 0xa7f8501488d7b3fbL,0x3b5ec513ec78386eL,0xc6586b8a2ad5053dL, + 0x88c09a43fbcebe43L,0xde7f2a4a20054f16L,0x63daba80bbbb147fL }, + { 0x087e48f37d352b55L,0x997e32a08317ab79L,0x8ae802ff7f27cac7L, + 0xb01a131c37b1f6e1L,0x3f0d4c2e9a6d1deaL,0xe06114fce7ceef80L } }, + /* 3 << 322 */ + { { 0x311df84c359590bfL,0xf907d69ddf6ca4b4L,0x876fd36782f22c64L, + 0x64c4d14d9713e68cL,0xd431858d6b07f539L,0x39dfea3384990283L }, + { 0x6afb8cf080cf6498L,0x327056bcde060e9eL,0x5103ce4a49a71086L, + 0xfc94be75cdf853abL,0x2bfb105f8ca579cdL,0x02d19c3a50454b41L } }, + /* 4 << 322 */ + { { 0xaa03b474cde121c7L,0x74a648cb55e52c76L,0xb286ef86f37b57bcL, + 0x95b797eb2a6371d2L,0xa489ef894077ccbdL,0xf46ade048e99ca6dL }, + { 0x5cf9e23723242d03L,0x33c7d32acb708390L,0x329523b6ba7ba477L, + 0xd406ab8757de30bfL,0xaa10e4a21536ca01L,0xdcec94f4dfa7aac5L } }, + /* 5 << 322 */ + { { 0xb5839fa424700097L,0x82fe2251759eb8beL,0xec5f34bd5f104a39L, + 0x7f3da509ed1cf49eL,0x62fe425244621c76L,0x2118b68dc7bba926L }, + { 0xb0ac18009ea4b7e7L,0x33b21ca1fcc83f56L,0x1856161208458096L, + 0xba0e6aa95650f3feL,0x918d427231006f05L,0x955f3951b1066473L } }, + /* 6 << 322 */ + { { 0x0cb41ada3c59ee1fL,0x38b2465861d1633dL,0xde863b47d03e9452L, + 0x2bfab5b41548d45bL,0x580af6272ccb7528L,0x6744c7cb13c04327L }, + { 0x5eca3ab339cc5075L,0x51dbfc7b6d243f62L,0xd64d84b7981ee3ceL, + 0xf639a03db4f2bc63L,0x8a411c36a317a1b6L,0x51edc4c0ed34eb3aL } }, + /* 7 << 322 */ + { { 0x01511b8a9d6fce5eL,0xb5c7b33f89a2875cL,0xa88e720e2fd79b67L, + 0x5337034404229e94L,0x40bb7e7ec94af25cL,0xc11501b99183a7b3L }, + { 0x29a4d81fcec3cc7bL,0x143976fdd75b8febL,0xac8dad2cfa261ad0L, + 0xb14793006a2db8a8L,0xd4981293929c4a12L,0x5703506fb6eef856L } }, + /* 8 << 322 */ + { { 0x762a5eec1f5a9609L,0xfe4f5f6a765b337fL,0x0fd534aeaa4f964aL, + 0xcf46648ed6526f01L,0xbc62a54a18d71d72L,0x48d94f2a4f8488eaL }, + { 0x62c40de7a0c72a86L,0xd73ac51a725dd2efL,0x3a51d7466ab19096L, + 0xf07bea4b2dd1ad3dL,0x2a0ec4672ef88078L,0x92598cb3664e435dL } }, + /* 9 << 322 */ + { { 0xd49f753012fbc44aL,0x769a4fc941c51d91L,0xeb1ed485981fd6a9L, + 0x90a4b3cad7daf430L,0x4bbffd5c75d07405L,0xd998a096da671888L }, + { 0x0514ad4b6e10976cL,0x5d40328aab11d9ecL,0x86de976bfa180702L, + 0x259ca429f6f8a4b7L,0xe08970f05772eb4fL,0xca428fa1b5feb7a7L } }, + /* 10 << 322 */ + { { 0x9f3d76ae35af4a88L,0x0b92f48a242af3e6L,0xd4f8a37b7165d261L, + 0x30e1fa8b2b917832L,0xd26f821f8fdfc06aL,0x75359bcf3669d1a2L }, + { 0x0ba3bcebb638331aL,0x8d02c0996c73b62bL,0x2a8c078d8c4f63a5L, + 0x55458ccaa312c282L,0x901ea0ea5eaaad9dL,0x03665da20e39eba1L } }, + /* 11 << 322 */ + { { 0x79a30b82da9affceL,0xafb188567204a29dL,0x2e64e6105a8ed24aL, + 0x6bf3695a9e44aa24L,0xc22320690c77fa6cL,0x20b3c69531524429L }, + { 0x91e60caad6e0f847L,0xf0fa30c4542d6b57L,0x56a3a66bff98ceffL, + 0xec44f0b72c9507a2L,0x4ef13008c37e17e4L,0xc819ae81cda21355L } }, + /* 12 << 322 */ + { { 0x17c563be1cac0b58L,0x889cfcecb8491347L,0x591d49ac4cd1bfc0L, + 0xd4465510d4e53d3bL,0xca95ccf6ad079a6eL,0xce391389b5ea6eb4L }, + { 0x600ccc9ca48b6447L,0x20d0c7dbc20d56a8L,0x5f27edc569c6c6e7L, + 0xb3fc0f4a586abcdcL,0xdbfdf3f985dbc5b6L,0xfba1cf254ea80fe0L } }, + /* 13 << 322 */ + { { 0x38d6267e427a9075L,0xd1df12006d63ea4cL,0x9887a99881407b57L, + 0x41accae4688e9f0eL,0x33c63c9e10886dc3L,0xf8332ac57574a033L }, + { 0x7d77d41f4c636d00L,0xf6f4ca28add70d4bL,0xbe496330c0ee111dL, + 0xa4de7670b74bc69dL,0x683a93d369e5eabdL,0x4c5461c710963bd5L } }, + /* 14 << 322 */ + { { 0x9bbc99b59310424cL,0x6f4bce534568e290L,0x21373f5bc1572fd6L, + 0xe5ecd5b6a28b4394L,0xd56968f646ef7bacL,0xcbce8614726cc043L }, + { 0xb2fa6101d0a49bd8L,0x65eaa7725a7b41c3L,0x10d7515296e5ae18L, + 0xec8f4639af389838L,0xac660d81bccaff25L,0x3c546ba931734025L } }, + /* 15 << 322 */ + { { 0x81b13d3ee098c584L,0xf8eb4e41fa3460caL,0x1bb889d1f0b905e3L, + 0xd158ebe939a3faafL,0x7ad0f829cf09735eL,0xc89611963aa8b3beL }, + { 0x522327781be516cbL,0x9118d851ee88d911L,0x35ad130f0bf2a62cL, + 0xf35bcf1b39c05087L,0x73b992c3bce42949L,0x93ce50b95b42744dL } }, + /* 16 << 322 */ + { { 0xee6e7006b515fff5L,0xaedf6e3913258ed5L,0x373adf7dfc45111bL, + 0x0c7535b1875c23c8L,0x2a7e04f897039d49L,0xd76787ae9afd1a06L }, + { 0x049dd38591b6dc89L,0x8f0c8ad0932dab78L,0xdce057b9925498c2L, + 0x7b9c9bd2da25daa3L,0x6d0b70a3d4decb7dL,0x099a218303df76efL } }, + /* 17 << 322 */ + { { 0xbfaf4b848c5520a2L,0x36fa343fc6741e50L,0xadcc36dcbd5211c4L, + 0x2cae5a8514bf0578L,0x8fee4d403fe4171eL,0x2acd2756624d0daeL }, + { 0xaf99a323623aa9cbL,0x120cd2038c8191e2L,0x2073e8884068d993L, + 0x144851ac579bbf88L,0x54d458a4ee29fa34L,0xb7704255e5e5d676L } }, + /* 18 << 322 */ + { { 0x02f6e396617dc4bdL,0xbc48c42961497feeL,0xb27487fe0b4d22d7L, + 0x33d6b1161d0b0aabL,0x5e21cebad31278e5L,0xf7119a50dacd8f27L }, + { 0xe47eff2cc8ab54acL,0x7c7ccd3bbbe16c9cL,0xc056d817c584bafcL, + 0x868ead2b97790d9cL,0x8fea6eea1a58126aL,0x67d323640fab2640L } }, + /* 19 << 322 */ + { { 0xee1a958ffa14b58eL,0x900644f9760b54e3L,0x97fa6fa451579d09L, + 0xa7351c3b26e7f95aL,0xc3546595aadfd139L,0x07b7ef48f14f1e6dL }, + { 0xc8d100ec4d139608L,0xf98609b2d8741228L,0xf0890d9d33030d3eL, + 0x893b874fe28ed106L,0x5439b7aff7bb558aL,0xe68a3adba71a2261L } }, + /* 20 << 322 */ + { { 0xff54e8bc8acd597bL,0xdae781e94682b8c6L,0xb2265bc4ed1fae2dL, + 0xa5e23c29ea983db1L,0x4af5f55909851454L,0xffe9538836eb4506L }, + { 0x4c72b2d1c2247b8fL,0xb179573331a67505L,0xb1aa8ad4e19c9c25L, + 0xb9cfea953e8b8004L,0x07782d788ac747fdL,0xe23e547fce9d9e41L } }, + /* 21 << 322 */ + { { 0xbc6b0088fd9e8e72L,0x7e51aa5dc6453462L,0xe8615fb9c8b1725bL, + 0x031f0d2a5a371c9bL,0xb9db0a647441d8aeL,0x0dd0446e9d5783c5L }, + { 0xb3b7be2381720779L,0x49a8ecbb6cc5a610L,0x165c626152cd016cL, + 0x5fcd657da3f6ae6aL,0x30497fbc9f6988dbL,0xd734927936a73fe7L } }, + /* 22 << 322 */ + { { 0xb30ddd0e388562b4L,0xc485506b1f61067fL,0xf0da517684947c84L, + 0x04830cedeb067f33L,0x05084c8262404b76L,0xe7e7efad7996707cL }, + { 0xc2a6a57fc78b9a7eL,0x4e55fd8c7bfbf308L,0x204e7c44d1386117L, + 0x979ecd5a4e56595eL,0x3bfc790853707b85L,0x2c3a41c59fcc5b7aL } }, + /* 23 << 322 */ + { { 0xcdbfd951ed6e2671L,0xb72c42ee135f6b96L,0x38c8d1ca40bbb789L, + 0xf6fa984cda03f270L,0x76dc5a19ed88deb9L,0xa8c88f2a9985bcd7L }, + { 0x2b0d3b66c6628a44L,0xdf679b6a2b311954L,0x30a363c25f851b07L, + 0x78a5d242aecdb9cdL,0x42d7ca82a968b4e6L,0xb188e99af2efb94fL } }, + /* 24 << 322 */ + { { 0x779905b6d8948f95L,0x3c7085b591cd0206L,0xce9af0aa679096dbL, + 0xfdf04f10f558913cL,0x05300cb06f24a2e2L,0xf9d9a2f25d581b35L }, + { 0x855c8de96a713751L,0xc9ac24bc0e0c0dfbL,0x67612a4197740d65L, + 0x7588a52744c9360dL,0x928ac910325cc880L,0xa74abdafacdd3188L } }, + /* 25 << 322 */ + { { 0x98d80359e7c5fbc7L,0x6abc82b7047c61d5L,0x8d8f5fbd58f2fd49L, + 0x321f2426ccb0a4dfL,0x379f10e2e96cac24L,0x34c0444130666763L }, + { 0x8dd3972043632c61L,0xb2bbe2eec19f98eeL,0x00d5a467c464dfa3L, + 0xa44ceb19a85b6fecL,0x88bf80ddc9b1fa77L,0x7e5123c8e6dda98fL } }, + /* 26 << 322 */ + { { 0xf73ad540b75a6b88L,0x57bcf1cc08487cc1L,0x00358de735cd0c27L, + 0x86d469a2573df808L,0x4884cd5684716abfL,0x0157687fa7da61d7L }, + { 0x8efd8acda732c2cfL,0xb6c9bf7198677236L,0x3d1f01826d46c473L, + 0xafa65fd82f497476L,0x535ee757e54f17daL,0x432b5878fe7aaef6L } }, + /* 27 << 322 */ + { { 0xf091c4ff3370e118L,0xabf011ee118d4b8eL,0xb489c4b7a13c7279L, + 0xc2dd44e93bfb19feL,0x10b68e92c5d859dcL,0x57935fc39249205eL }, + { 0xb97e63b06c929bf4L,0x98cb08a739a25097L,0xb13f17c15eeedf15L, + 0x1e27a85c240884feL,0xda1515ad9b601298L,0xe01251fd4ce36c3eL } }, + /* 28 << 322 */ + { { 0x3774af36ba6aca8aL,0x562fcfb1340e6a03L,0xde45205ec1187539L, + 0xf3b114418799c22eL,0xfd53f681e8b0842eL,0x45a0039066d36d64L }, + { 0xa2c3391d353eb1e7L,0xf9d9fcc55840eddaL,0x4df1fa4a6ab8ab4aL, + 0x2b0cd34bd841a623L,0x52441d79b10b189aL,0xfd86d3c2fa025da7L } }, + /* 29 << 322 */ + { { 0xe28f3bab5872204bL,0x6f87cbaf0ba35c66L,0x783e85c03d877c60L, + 0x376e5e2df132df52L,0x213d53a9bc2cd6faL,0x2e2a573008a13174L }, + { 0xc0988fa9ba15290fL,0x51d81b9485456f81L,0xfe371f32a0ef5b80L, + 0x9aca060ff129171bL,0x0b02b39e0e402e65L,0x8e6bce1eae9c209cL } }, + /* 30 << 322 */ + { { 0xb0cb0f0c532f78c8L,0x83113e752d133635L,0x3f64aad5123dc64bL, + 0x4d3201c85aee8c59L,0x265905dbe75e8642L,0x9d1d277805f9a759L }, + { 0x84778aead9e2a07eL,0xc747cc3a9c0aed31L,0x10d1b4e87af2dc61L, + 0xf58a6bd8af0bf23cL,0x83836c2352e1ee75L,0x88c4d1c6d899062dL } }, + /* 31 << 322 */ + { { 0x27eb26a3f3842d98L,0x90f712b69da68159L,0xd11177052676f05bL, + 0xdf603446073bf994L,0x28ad2b498bfcbb7cL,0x6916c6e2e5e1266cL }, + { 0x37d516996e98d62bL,0x155d8ef749634968L,0x0676ea286a1b2222L, + 0x1dc3f8d71566cb3bL,0x95fb3f177dc6aecbL,0x092f4c8120807b13L } }, + /* 32 << 322 */ + { { 0x3c6c5618b9d926c2L,0x7e14c3ae4a9099f9L,0xb3259c90ae2fb830L, + 0xf7cc6e43ec31a504L,0x83bb13c6126230bdL,0x5a1f4313ff1dae3aL }, + { 0x0cc6c1a549b0b65bL,0x67fa836a274a84c2L,0xd454c75fe604a58dL, + 0xceadfd912491f872L,0x6c5575da9ce116a5L,0xfaa4903fb24a4481L } }, + /* 33 << 322 */ + { { 0xc9ade1497c4579f8L,0xdad7eff3be316db0L,0x4ff3abc613fce23dL, + 0x09103a75da708e56L,0x4cf139fa8ab52827L,0x0f82219b8f251a68L }, + { 0xd19719c7dea33388L,0xa482548423085413L,0xbb63cb43f8eb4b18L, + 0xeec33735f3b88079L,0xee79d331de3ddb97L,0x56fc93090e5acf8aL } }, + /* 34 << 322 */ + { { 0x951a780bcef9c5bbL,0xc37d442ddb35bf11L,0x8e2a0e7d64a776b0L, + 0xbf461becc652cf34L,0x3970eb603194f918L,0x2768daedb3bda869L }, + { 0x8e81257557b24bf2L,0xae05e2db38dd69cbL,0x0adab288cee2f522L, + 0xc7a0e1f148234f13L,0x285f6ee36728c9e9L,0xb9ae7b9fc4541e19L } }, + /* 35 << 322 */ + { { 0xfd90c5c1f6422b56L,0xd9fc8cce4dfdb947L,0xf3566dc4d088588eL, + 0x25dd9e27f22682e6L,0xb077392119b0a532L,0x54da228c0d05a9f9L }, + { 0x0f7fda40986f60d4L,0xb6dafff6c9b112feL,0x7eb99e1a4abfdfcaL, + 0xed499eb9389611caL,0xf230d6d6f251477bL,0xc09d328c227ecc92L } }, + /* 36 << 322 */ + { { 0x9b21ef6c16cdcfeaL,0x233be0c3694edecfL,0x110243df7c49c931L, + 0x03a59a2ea3113ed1L,0x6470f721023c9a77L,0x7d1640c88e9ff099L }, + { 0xc21488316f2c7b37L,0x9e1c9e1dac6eebc7L,0x6af65a671109ca9cL, + 0x8379fdd9cc6f80d9L,0x33f74ade7e666a4fL,0x07ac728b7be081a5L } }, + /* 37 << 322 */ + { { 0xa3df31a312354705L,0xffc8fdfc1aec1bd7L,0xd9dd39c112cc342cL, + 0x8077a57e37bf43fcL,0x0f037ce49cb8751eL,0x5740f6b5b805b530L }, + { 0xd26422704e2b5b93L,0x114bb1f02dc158efL,0x71881767a9bec3d1L, + 0x1174386d266d95cfL,0xa373d7ea7cdd4461L,0xaf4f7b40d814a33eL } }, + /* 38 << 322 */ + { { 0x0db94a18f79761beL,0x263e2acb5717b98cL,0x78c28d8182567b0eL, + 0xce1b366b893c35b4L,0x1e20b1bc0d6907a7L,0xd6f123474b973588L }, + { 0xfb945471f717e91bL,0xef85653cb027bd4dL,0x048e9e1df07dc0e1L, + 0xc494aa9cc163b83dL,0xfaec72d3021b4fa5L,0x5c63c30fc9869fe6L } }, + /* 39 << 322 */ + { { 0x2dfa058d510d8d86L,0x772fad416a89aa0cL,0xdf55d15cd586f23dL, + 0x7d96b7a989b604f6L,0x352fe049a38d821bL,0xfc56b8df4fbb5795L }, + { 0x264122b4b3d5dd0bL,0x89317f4a980177d9L,0xc060ab4a13e2aeecL, + 0xc2676725e2cafc87L,0x78863cf45eb1df3cL,0x2e1572dc0ab1a715L } }, + /* 40 << 322 */ + { { 0x7a8a898d5a4703aaL,0xc59933ea1cd6f9d6L,0x703265f5d28124cdL, + 0xe1c1bee10178d1feL,0x9ff31cd4241262e9L,0x9174a939a3c9f80fL }, + { 0x0f7a3d2dbc2a62eeL,0x0454051c62f1b3acL,0x83502c9ea2421254L, + 0xb4fa51fcb684199bL,0x257e9e2bc5e36a44L,0x14efeed597d8647fL } }, + /* 41 << 322 */ + { { 0x09bddbc28f2b12baL,0x8af83a779b7f1c14L,0x88f9b4d3bcc934bbL, + 0x8d8312df8d072340L,0x2ee105bc615989dcL,0x6044fa00de3bab08L }, + { 0x98c499d603cc86ffL,0xf0b48aa7c5068033L,0xdaa536d2c96606d8L, + 0xef905aa2bc6a843eL,0xb6f108ee8ac620ecL,0x0dec7dfbb6dd66f9L } }, + /* 42 << 322 */ + { { 0xb9157d4ab0fe18a8L,0x139bbcbc68cc7a70L,0xd546a06d7dea2914L, + 0x8db142d4a01cc59aL,0x127ce2d9aa09fcdfL,0x3950a5a63bfef8deL }, + { 0xf41ef6d42527522aL,0x4b4e6f107e6fb19cL,0x2a2735d1345788c5L, + 0x87963e1ee72a7ae3L,0xb58d8934fc443360L,0x93552692b16b6f2eL } }, + /* 43 << 322 */ + { { 0x70591a849518f0c7L,0x5c282b6fc67c438fL,0xdbf61b6b100facc1L, + 0x3c5d969f2bf2a5beL,0xe1a0c6cbab980c70L,0x70f4981c680619fdL }, + { 0xc6905d7cc65be256L,0xde3340fbb5c27acdL,0x17be9d182c1b3fbcL, + 0xd584e4f96fb00b1dL,0xac5dc14eb819646fL,0xf5c3279a3242935bL } }, + /* 44 << 322 */ + { { 0xfdb13b31be970ebaL,0x119b1c08b0bfadc2L,0xed62f35e21875542L, + 0x73c8f9b0349a6d12L,0x8c35d8f8bd1622c0L,0x501b9d288b6521a0L }, + { 0x377f8fa1c918b2d5L,0xe2a9580cd0239ef9L,0xee24f4f0371d7bebL, + 0x4cc697a669231b47L,0xa55193c8dc4c5a07L,0xd4e51e1db0ab8507L } }, + /* 45 << 322 */ + { { 0xcb811c27265f267fL,0xb85593aa9e2688f4L,0x57a1969dd76bf364L, + 0xc29946c9014483a2L,0x5bdd72490915bddeL,0xba6d13ff22746ae4L }, + { 0x524121e0d25f6b7bL,0x9011309e0d68a3f9L,0xf25e89ccdb91c66cL, + 0xae79cad781df593aL,0xef8c6bec4f103231L,0x832659c3e038f02eL } }, + /* 46 << 322 */ + { { 0xd58eeece37761959L,0xba6d8ab5b328f084L,0x3911e6ae324a6706L, + 0x299921c8ad139296L,0xb81a3fe4f6b8d9e1L,0x2680c46f5ef06a6cL }, + { 0xab9cdf368611d63cL,0x6c9fa5b3cc0a5da8L,0x712356a3da4d4412L, + 0xc1707a10cd3f550dL,0x5c25b2f3ce468303L,0xe4be20bffa546b6aL } }, + /* 47 << 322 */ + { { 0x797a2919515ee1dfL,0x65dd5991119dc9d3L,0x82e8201b41e4c5ffL, + 0xd27b35130d3dd45aL,0x9ba590c5b13b2dd7L,0x0f15b35282992935L }, + { 0xef39971e227e4e46L,0xb74c524b2786fd6dL,0xe09c28ec71b1579eL, + 0x0d1418e285f6a935L,0x173265448719fbe7L,0xfe3b1d831200b35dL } }, + /* 48 << 322 */ + { { 0x6e96a8195cecb21fL,0x3a58d8b2d8beecaeL,0x93c3cbb0c0c715a8L, + 0xfb06f977541759b7L,0xf25ba095771c3d2cL,0x7560446ea3bfd322L }, + { 0x7cd99f35a015cb4fL,0xa0e541960786f235L,0x0f868f768b8e291aL, + 0xc8260b0b2f95050bL,0xaf38376ef4c0a462L,0x2b3c0f3b98a3395dL } }, + /* 49 << 322 */ + { { 0x99d4529efed6a724L,0xc6f1b084071d8d31L,0x6c48062ba097da1fL, + 0x1dd10493301c1d74L,0x5288f194f554cbccL,0x77b1b81f39dd42c7L }, + { 0xeb1f2d53a007a6d8L,0x43bed54e05648d75L,0x1a85326f29801a1eL, + 0xcb9a91a4f564d78aL,0x4f38fc7893f071deL,0x920117d8aeeeb5adL } }, + /* 50 << 322 */ + { { 0x709b5904b35cba78L,0xef0c321021b11d3dL,0x38f07eec46844b18L, + 0x2e79f99934870a55L,0x9e9df80400d7b924L,0x857a95625cafba4bL }, + { 0xef8ab68f4adfea6fL,0x4a83bfc16ea764e1L,0x21f4c75475e8d874L, + 0xa3597f526ecdf5d1L,0x9d3a4766eff2e1e6L,0x9872db39e5e6ae81L } }, + /* 51 << 322 */ + { { 0x42d9f39e99bb9a10L,0xe617263ce35e4852L,0xb3f8ace1a06b71d0L, + 0x861520de6419d9d1L,0xc2c521cf37b1fe38L,0xd537001b9edf9936L }, + { 0x92614b9f39af94e7L,0xd2003f2e25286664L,0x249d04aeb836d4b1L, + 0x3c6c192ab26df88cL,0x6e0b25442c72ec0eL,0x69d7f6d7497f03dcL } }, + /* 52 << 322 */ + { { 0xbb5a95f6293cc00fL,0xb202a82a65fb729eL,0x819c26aa12e35774L, + 0x70cd5237c2b3f0b2L,0xa752224a89b2c5ccL,0x71c09cbd0ec89df5L }, + { 0xb849e352bab45d24L,0x290f0307d313f461L,0xf083031cee885e9dL, + 0xdf42a973a60bf2faL,0xe39f2118d4842999L,0x8b54cf1d0508febeL } }, + /* 53 << 322 */ + { { 0x8942b4df0d846a3cL,0x18db708662b6605cL,0x6549e019fafa6508L, + 0x85d97fce43ef9443L,0xe9f13da373485de4L,0x5743297bb0f46e8dL }, + { 0xc52781bb70908255L,0xcd88a48a6bc6e666L,0xf857caa5eb4f54d1L, + 0x32dc925320974dfaL,0x6dc79fad965146e6L,0x24e3a8d2edc1f747L } }, + /* 54 << 322 */ + { { 0x1993fa650e81671fL,0xc6acd9f3dd1a1e4fL,0x227edd1a7bf36f1cL, + 0x4ad2478370867ca3L,0xed0254f758b9a7c2L,0x63fe279a7013a5a4L }, + { 0xa65787ee232e6a88L,0x5faceda487161d5cL,0x36e351b603d64c37L, + 0xaa265f1de9e30871L,0xbf3432f521e6f66bL,0x69d68c068621289dL } }, + /* 55 << 322 */ + { { 0xd2bd143ea0807eeaL,0x474ad99582568efeL,0x0fcd6bba7d482c5fL, + 0xf83e6f15e2628f4eL,0x314508252210e41cL,0x8f0a9402f47de776L }, + { 0x7f20bc562ee4d1e0L,0xed4157de791aa7a7L,0xbe443399be2dee9aL, + 0xb461643371625f13L,0x1be21ba8771f55c6L,0x04b3035a300fc187L } }, + /* 56 << 322 */ + { { 0x0952b888b9d0bdf0L,0x3973763c8ce32fb7L,0x221f0ba56dd860c7L, + 0xbb7a27feb16ac501L,0xf113b194bc8fe58fL,0x18f3297a65839ffbL }, + { 0xa2d4eb7c8dc30003L,0x3fb4b4878e334479L,0xa4f32c651a8310e3L, + 0x944cd644f78f46acL,0x14e40c4af96fb91fL,0xc31402bd4ddf6e72L } }, + /* 57 << 322 */ + { { 0x9eb2c9e51ff0ab88L,0x0a29fc0695cc3436L,0x3f4b4ebdbd298127L, + 0xeb8ad8b52ef56848L,0x6159700f5b211ff6L,0x8fb98f2fc3a67bc0L }, + { 0x5c5998ffbd195b66L,0xea99d6767e44a64bL,0x314316e4bafd1471L, + 0xb5f48757cc8c0e77L,0x922a91d15b259ac8L,0x2458279cf9fc4e4eL } }, + /* 58 << 322 */ + { { 0x945c5a3c6aac3e97L,0x5cbdfad9a266ad50L,0xa3e38114fe59f5ceL, + 0x1ca1cfdace3ae206L,0xbe1f15e12a84cfdcL,0x682514726a12ec3fL }, + { 0x48409f871f57341aL,0x632c369e8461bf7fL,0x1c96fc87d8865ed4L, + 0x1727934ae1ffc51aL,0xa60f0ebb6d71f51dL,0xb6c354052e411888L } }, + /* 59 << 322 */ + { { 0xc7b3d3bb72a77726L,0x04b9bdfbbdb03d78L,0xdbdbaa7e2fe88db4L, + 0xc5848e58564710b6L,0x7bbd84863ec55713L,0x1b5aea5670183191L }, + { 0x95d91bb25340d9b7L,0x9a1462e4187a3252L,0x5cee9b8cec352fedL, + 0x7db8350137049284L,0xa1d2822cd3b714f3L,0xe4cf6d53c2e51da6L } }, + /* 60 << 322 */ + { { 0xdb2a2ac9a63f6f62L,0x4c0d2da695f20639L,0xa485a6adb475e177L, + 0xf6dad8b5aa93055fL,0xafcc1e954974bc52L,0x6686940224fcf32fL }, + { 0x10c138bfc103b013L,0xe74ea82bc6faba1bL,0xddb399c581824de5L, + 0xae797b70cdaad079L,0xc648e7ad6ea955e2L,0xd07c5c919be79db6L } }, + /* 61 << 322 */ + { { 0xf4b7a33b39d93befL,0x4be176f9659da9f0L,0xbf57d975f36642cdL, + 0xe10b452d16d5528cL,0x7c062421a6bdd74bL,0xc093e346e7aa1d9eL }, + { 0xb7cc38cc2f5c19ddL,0x9fc7f69b230c8790L,0x9b667acd5e3c5282L, + 0x1cade31144cd22ebL,0x53a0d702bb43a1e4L,0xb25868777906519eL } }, + /* 62 << 322 */ + { { 0x46e2415deb5003acL,0x05aee8855e8a6a0aL,0xbda9f162bbaf343dL, + 0x658b350b21853341L,0xaf6b4948ced47246L,0x1d454740723cd3bfL }, + { 0xc4b7ce3fe1aaef54L,0x619420daa35c9e24L,0x65d455b14eb7a52cL, + 0x2f9b700a4c961515L,0xa5b7b962d3aed448L,0x4e32a6d937851d3fL } }, + /* 63 << 322 */ + { { 0x2c4c1b2ed00f8cb9L,0xbf83ba500fd305aeL,0xb75bcf9f801a8e64L, + 0xd8ab465ccba76b29L,0xf5a2bcd74ea718f4L,0x81501d563b592ae0L }, + { 0x9734e4e26ae6bac5L,0xc4860b0eee304e5eL,0x8bd59b7b1d59f1acL, + 0x7c9497e8e799594dL,0x4bc6634c08292918L,0xc45583aa92619229L } }, + /* 64 << 322 */ + { { 0xc5ad791eb45a8002L,0x4a23fd68ba2d7a40L,0x673b9e4998544bc4L, + 0x934d8f55d273c360L,0x7fb48d0768a75a8cL,0x2e6201055e0fac97L }, + { 0xbe01655ff10ed580L,0xd21d52ae9e96731fL,0x74f830de53325138L, + 0xa7240331de9f3fc5L,0x96b25206a7e01fa5L,0x3fcfedee07eda4b4L } }, + /* 0 << 329 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 329 */ + { { 0x3e6e93818d5c039fL,0x809494228a8d2cc9L,0xf2d7c8b4b843ec06L, + 0x0055d882af8a23f1L,0xe848010ed3792335L,0x9b41a55f55e08e74L }, + { 0x956ea8e95de83059L,0xf159a9973263678eL,0x5f7b9271cca1b548L, + 0xd41d2281f1d0b7f1L,0xb187047b5c9963fbL,0x213ff6af02536cd8L } }, + /* 2 << 329 */ + { { 0xe51a95700d0fa76cL,0x67c7890e4d2e9c8eL,0xc6160fa2f974d2cbL, + 0xe00474f74c6a78deL,0xee916e510ac89d11L,0x1adad97af826f133L }, + { 0x3fc65d3f8d2d77f3L,0xda9420750ba6c300L,0x5237a82e0b9196b1L, + 0x4975e680a572b6f5L,0x41ea8b92b9bed2bcL,0xbe0ad7109826825eL } }, + /* 3 << 329 */ + { { 0x06f721d30a9ec81fL,0xf0359222034f3e78L,0xc5ca6b7a5a44ffd9L, + 0xc53e328915764390L,0x7f16917459747d7dL,0xc3a9981461f79122L }, + { 0x099f4e3a97aa46f7L,0xcb0570c9d70458a6L,0x270a43576b72f327L, + 0x9d6bb26cc33695bdL,0x60f9202126224902L,0x8eb0e108e1b0a51fL } }, + /* 4 << 329 */ + { { 0x8a390dca9fcaba39L,0x3879f0b4278d22b3L,0x77bbea69bc5e82f1L, + 0x71f02e2d4628d6f1L,0x6260790cf968e240L,0x1c7f3df5665270eeL }, + { 0x336395451a87b1c8L,0x2011fd214ffd9fb8L,0x69060f867807ed55L, + 0x1b0ac0119dfa452cL,0xbbdb25fe06d27c0dL,0x5c25d23aa60ef90cL } }, + /* 5 << 329 */ + { { 0xc08dc153d9f75d6bL,0x5c1f07e7a0330237L,0xb3e6fb677d67a5c9L, + 0xca949ed098f9faddL,0x48b16b2dd7720835L,0xfdb1b735fee4d341L }, + { 0x1a6b37b1debf3207L,0x5b3eeb1e3218c63aL,0xc19b57b504c23b30L, + 0x178bd3bb40669e2dL,0x74e57b26fb6b162cL,0xc3626931a0932b58L } }, + /* 6 << 329 */ + { { 0xd3eb69e4734b2e9cL,0x1c2754e2c35ff1b3L,0xa26681e69f3e8c51L, + 0x7892ad11a2cae737L,0x88b1da43cbd8bda6L,0x8a576942419d21c4L }, + { 0x7c124343c90f4545L,0xa5a8d93b26453baeL,0x9a4c08fd76ae72e8L, + 0xa08b82d97b064e94L,0x4f803ba083725330L,0x33672455865235f3L } }, + /* 7 << 329 */ + { { 0xf7a5e2f0a51e695fL,0x3099bf9484adf10bL,0xb2a03c0f22a3ff04L, + 0x30303a910acec674L,0xaccb2f3ca59522f8L,0x00ff4d88f273ba94L }, + { 0xf0056b4210e735ebL,0x3337279a7786e93bL,0xfecc77c44bb3c31dL, + 0x3385bf5be0e26a05L,0xa9454ab85f45fcbfL,0x41a4158346edb553L } }, + /* 8 << 329 */ + { { 0x1877dfd0c8110f1fL,0xea88f59d18db27c2L,0x9d089536c78e295eL, + 0xcbb5d55374a04cc5L,0xe3666006827f75edL,0x8557b81a61e7378cL }, + { 0x74170170ed223f48L,0x84197a6ed86ee829L,0xd75a30f8ac1c4a0fL, + 0xd7e7be0d3cd92824L,0x5ea0abdb1b5e86d4L,0x41146ae1b3b615efL } }, + /* 9 << 329 */ + { { 0x6d340fd3fabd376bL,0xb5066b1ccc169cb3L,0xa4148142d20ef8f1L, + 0x0c5d66fb461544d0L,0x84c7a232d67043d2L,0x4c0e77867e609af4L }, + { 0xb1e83f1af4619e4eL,0x40fca1a0b225d174L,0x39bb3a882e42fa4dL, + 0x04dfe833d2682205L,0x49016d9d685296f8L,0x2da587198b735155L } }, + /* 10 << 329 */ + { { 0x570deceb1ae5e9daL,0x5c079c70b73ead01L,0x522a30a6d2ce6639L, + 0x71dc5c3ff4056ac9L,0xd93c7a2dbaac149fL,0x5c3298b8f1844cebL }, + { 0x282adf408c23c0dcL,0xbe4981899b646f86L,0xe77c1950628da9e5L, + 0x38cc27baa1fd5a18L,0xb5579728aacdca52L,0x8d34fdb4c8e1ecbdL } }, + /* 11 << 329 */ + { { 0x563e0b8a7a7fa597L,0x6697c375bb7dd079L,0x95758ff6c6233951L, + 0xca07993fa2059c40L,0xc3065507ce2aaefcL,0x9faed33c6ea927d5L }, + { 0x0f8b48241207247eL,0x0044f6115eb2263aL,0xd7c9ce7c851596fcL, + 0x54729d523c69d424L,0x42cbdcca45876770L,0xc1e0e6ceeff2adcbL } }, + /* 12 << 329 */ + { { 0x323f2102adea7d6aL,0x035b354eb694b253L,0x66dc4e4a5b8a36c2L, + 0xb609222471795ca4L,0xd8c6d7eed300d80fL,0xf31f258db3b94954L }, + { 0x0f2eb679277ced5bL,0x0b16efa3eba40e3fL,0x400035070dca4f36L, + 0xd34c91cb59a9a3a1L,0x5e8fea3286da6408L,0xf237959f03f31728L } }, + /* 13 << 329 */ + { { 0x1d3173653412e8d3L,0x1d14cd1b09695abbL,0x9044adf2a2cda00cL, + 0x60a6ccd60b7ba011L,0x614b100417284b46L,0xfb3d84b9cf840203L }, + { 0xd65b3566532b068dL,0xc8c03996c2465150L,0xc9035c2df71c35f4L, + 0x350231a752222e21L,0x59440020451935b1L,0xd723a55cccfdd206L } }, + /* 14 << 329 */ + { { 0x1b5bc630bbaaedc6L,0xe7d25088b49cbb3bL,0x5622cbf70deb8cf0L, + 0x3b20803cd309c3baL,0x64c2e7deff45e2fcL,0xfa730ffb9aab84a5L }, + { 0xba83cc514edfb52eL,0xe05c0140748bbd69L,0x27bbb5f52254ec43L, + 0xca740989324c8c40L,0xa21488b1d26491b4L,0xe2753a1f69d8626bL } }, + /* 15 << 329 */ + { { 0xea04908f64dab001L,0x8ea1f127b4debb2eL,0x87adb69534f155a0L, + 0x41595cfcca8afe0bL,0xffef042f8763ba08L,0xb7b4865decd3e667L }, + { 0x2c46c97070c4c8a3L,0x1ab18c080403d206L,0x08b2d3c94b3df379L, + 0xc6a4c268a87a7166L,0x449bc61f5323b1f0L,0x8d4b7ced489ada74L } }, + /* 16 << 329 */ + { { 0x618ca06b8956146cL,0xd51f1e6f552cdecfL,0x981372cca3b6ce7dL, + 0xb44a68ee5f14bb57L,0xfc1167e96373abbbL,0x3d621f8b767d4c0aL }, + { 0xc6dcdfebf6ecc778L,0xddda926282d1fbddL,0x477501aabfcbf2f7L, + 0x0be7228a67aa8277L,0x5de7b8331daab9cdL,0xb88a4f9a262feb4aL } }, + /* 17 << 329 */ + { { 0x203a666c608fea53L,0xbf71f8fde8979c08L,0x3bd58feba22a3d2cL, + 0x596bfcf521f178a1L,0x6f207d89f84beffcL,0x8a7c6dbb18097607L }, + { 0x208f5e64a1c5c927L,0xd7d0e33478dc83c3L,0x5e9397261d4e30f5L, + 0xf3877242fa09a36cL,0x68e4338ae6a7b0feL,0xcf8cd131ac47b369L } }, + /* 18 << 329 */ + { { 0x28f18586936fb33fL,0x9809b2ab381bf7bbL,0xf6e16931eac3c252L, + 0x366d18335e151187L,0xe5b4c2357a3b6460L,0x693a9fa50a68bc91L }, + { 0xa35f104a6a7f8b6eL,0x3e5d6981688676c4L,0xc0c081b10651a609L, + 0x6df5da2dd77057c9L,0x8bb271bbc4602847L,0x322547b3c4bd07d8L } }, + /* 19 << 329 */ + { { 0x9b56b9444deb8158L,0x5f4b15a6da5eb70fL,0x120afa9514cb0126L, + 0x01f6d00d6bdd0d78L,0x73dd7c5c463b1ce6L,0xc770cf35df00a133L }, + { 0xb5db93a1247ff879L,0x1c12f3f0c70ecea1L,0x10168c4e5b59cc9cL, + 0x1e9e0f8a0e19efe5L,0x43987dc1cfd44b62L,0xb1d265c204814e2dL } }, + /* 20 << 329 */ + { { 0x8c283529233d39e4L,0x96300796c6092096L,0x2c549de55dde766cL, + 0x27e0b444b4151002L,0x802e5fc3f2f88f1bL,0x2af579c28ba1956dL }, + { 0x52edd04ed68196c7L,0x2e22e71474a202b0L,0x338948248bf66459L, + 0x8f0d8c259e39df55L,0xee4f109e6c5276d9L,0xc0c893f0c5dc0bf0L } }, + /* 21 << 329 */ + { { 0xa3081bc75b3f17e5L,0x299e7a0222e46b9dL,0x36184c98a9afa278L, + 0xee2043319095a8a1L,0xf5e54622cd5ac080L,0x08d649013fa844a4L }, + { 0xb20ddfc6d7fbb42bL,0x15130bdbd868a81eL,0x25e5fd2f32ff1a03L, + 0x907e3c01ca5288d3L,0x2f2f7496a1f6f96cL,0x831feefd38ab83d9L } }, + /* 22 << 329 */ + { { 0x06054c76f8482849L,0xc24b4a6a5fcca65dL,0x71c27e01a17ebda3L, + 0x1ffce0281be9dfb8L,0x3784c950ebc43854L,0xcf0ecc2dd5086510L }, + { 0x86d0fc3cbe24d8ebL,0x5bad01911f21788eL,0xe2c3bcb9c49b3a12L, + 0x66f82433f7d5992dL,0xf7cc5eb913969246L,0xe52defd48660a6daL } }, + /* 23 << 329 */ + { { 0xd6d6a42b102490deL,0x9e6532acf40d27d7L,0xcd1591cdf2a08bbeL, + 0x973e09f234eb47ccL,0xb3a5915add4fa316L,0xb36ca6ceac38218dL }, + { 0x73d370b3e58a0cafL,0xbc8fd39f07766be2L,0x3d5d9ef7c2ea7997L, + 0x22877500bbfcc1a7L,0xc54d0c6406e0547aL,0xf7bc1d2d564e9ef1L } }, + /* 24 << 329 */ + { { 0x7a9623b653fd1a04L,0x13bd35bf3a3b8500L,0xf8a5dec9e0f8e530L, + 0x88bcbe291d65dcd4L,0x09fe38036739541cL,0xebd04b7fe716a97aL }, + { 0xbd8e34df1e5ef7cbL,0xddfc4243d7c4fd6cL,0x0183d9053519411fL, + 0x63450996f7a3c483L,0x18283cea01355739L,0x8c1d72cf9aaa72f7L } }, + /* 25 << 329 */ + { { 0xffcd4b6f9be9ff57L,0x0bff01bb939327efL,0xde596626b5ed90e3L, + 0xc07464ff4379e17cL,0xefd3e2c470d31340L,0x78b2192f4e7df61bL }, + { 0x7cfe28def3faf2fcL,0xd2d1a994dd642f87L,0xa5d4fb1410b3377eL, + 0x2cb4978ead6fa00aL,0x5b6fe7a765fb3688L,0xc26c1b3336d5acdeL } }, + /* 26 << 329 */ + { { 0x551e1b4e8dc72468L,0x8a926cb2a7b2f1acL,0xb873e83b0fd12fadL, + 0xb6cde14fa4e7fb13L,0x81ae41415befc256L,0xffb0c636b4c7631cL }, + { 0x80f1408f8a2478feL,0xde6d051d44fa7605L,0x5a15b1f84d44a1e4L, + 0x1a0031c5a0daafe3L,0x304338dd597652a7L,0x6830dcc7f257f17aL } }, + /* 27 << 329 */ + { { 0x62fae4072fdc8ea4L,0xff77522fcbe76ee3L,0x5fa03a454fd2bae6L, + 0x774c635e8dc90431L,0x718081b62ddc4376L,0xf4901a2c03e7aec7L }, + { 0x5339a3109eb023d7L,0x15dd4f96366e35f7L,0x1f802d4a0e2d2e95L, + 0x8e5e9cb2fe1b1226L,0x175806f623a0de5cL,0x115a97db068c7bbdL } }, + /* 28 << 329 */ + { { 0x4a67ec76193aabbcL,0x3da6dec6d74761f9L,0x751720c90b35bb70L, + 0xe5e049058d9e0f8bL,0x3cd37c840858f29cL,0x7ff1abfbb881733eL }, + { 0xa0c2698b0c4f7694L,0xc736419296b95e4eL,0xcfa55c5537ece651L, + 0xa2bbd6ae7cb1e9e1L,0xcd2292b9a0eb0e8aL,0x8aba99e18d5030d0L } }, + /* 29 << 329 */ + { { 0xa3f508a498fa3d8cL,0x4d894cbf45bcff40L,0xbcdac17d0c095cc4L, + 0x397caa6f407c2ed8L,0x2195056b5f97b4a9L,0x41eb6e0e97434508L }, + { 0xbb5e4e4a73f211f8L,0x5e8e638f720a451cL,0x8470bc9e4974252dL, + 0xc487aae29f6a9a96L,0xaa66417101165deaL,0xc8af7172b603771bL } }, + /* 30 << 329 */ + { { 0xb7c74c58dc4a1d3eL,0xe3ec30160331ea39L,0x83afb271023c8712L, + 0xc2670d56c9c82680L,0xd426f350feca1061L,0xe8aee692ba6edc01L }, + { 0xc916fbe546e801d9L,0xcb001c377097286eL,0xfcf79d2678ee1328L, + 0xb05b0634b6a4afb3L,0x2ab327bb306da14fL,0xc11a0294ba5ff534L } }, + /* 31 << 329 */ + { { 0xcaa287c30f00dfcaL,0x9ca672930601cc7eL,0x435e883fb105d00fL, + 0xf9cddbf91238536aL,0xda604ccb45f558c3L,0x7e51d9d182f48366L }, + { 0xc1e8d50d7e8396c3L,0x58638b85edbb75e3L,0xe926aabe9b088d2eL, + 0x8103a34a428c41e3L,0x03e5e35d089deeedL,0x64969c6d93bb0b99L } }, + /* 32 << 329 */ + { { 0x7b7da028e19763ddL,0x662f54df8b98ff78L,0xc056d83c51f3dbd9L, + 0xe2f4d46fa91d085aL,0x31759c9ceb35262dL,0x624d0cf20c9dd29eL }, + { 0x108cf9bb1624b02dL,0xa241444e345531d6L,0xf69816b273d372b2L, + 0x126575a7d5415e53L,0x546bb4c1306b8b0eL,0x82bb0c124d54ea5eL } }, + /* 33 << 329 */ + { { 0x85b355304c397362L,0x218a3b0eeda72e19L,0xd8eae54461729c56L, + 0x3d9b4a62735b571dL,0x12f3ee775629e437L,0xa72f9809095e5378L }, + { 0x5420a641bbe6dd1eL,0x8121eb3d02f41fe9L,0x5698eaf945e7acbaL, + 0x8a5e1a89469c2f12L,0x801740e25b434e0fL,0xa4dbe1cc670f58bcL } }, + /* 34 << 329 */ + { { 0x2f1919df5819e9f2L,0x156489e7a62287a9L,0xed038deb20a0c2caL, + 0xf63ac2d5c5ab4fdcL,0xca2b648ce391ec06L,0x8258e3f45b047d2eL }, + { 0xb7dcff56fd17b40aL,0xa8ace11f4bed747eL,0x542d70d175018429L, + 0x6c568967951bb2e2L,0xce420f73bb0e089cL,0xdae9623ed13f8eb5L } }, + /* 35 << 329 */ + { { 0x2d561034009a41d3L,0xf078204f5734d3a1L,0x2b8973ff7408e71fL, + 0x07cb9f95aab9c533L,0x376c1f59d0b35fffL,0x4a756c7fe851b313L }, + { 0xdc690e9874dedeaaL,0x625b082f70cf3f5cL,0x44839b5803dfc301L, + 0x5835a6c3c520f618L,0x695425e3afdb68d5L,0xc04ce4c62db97ee7L } }, + /* 36 << 329 */ + { { 0xc1d9b27ecb5833e7L,0x9911909567a8a669L,0x9317f8c30ab9ee27L, + 0xfad65eb9f34551e6L,0x7725ec2e016504f6L,0xca492cb47ebbdfc1L }, + { 0x6d2a3c962706aa66L,0x53e6d650836d8ee2L,0x109496434bc84bf3L, + 0x8442ee826df7c0f1L,0x7ab2eb9918fe80c5L,0x6a8579b35cd2ea35L } }, + /* 37 << 329 */ + { { 0x96adba7706e80e68L,0xa8839d6a0fe580e1L,0x755227e337a31a9bL, + 0x40b5fc70e27ec051L,0xb900a11b29af222aL,0x8fea2e509dd84811L }, + { 0x4f844c8861b59ab3L,0x26739874560c0948L,0xb39f85ba0cc08828L, + 0xcdce2fca829082edL,0xbd17998eb4555dceL,0x827eae97a3608a9fL } }, + /* 38 << 329 */ + { { 0xa77087f4c98e17c4L,0x9fa12dadbe2985a5L,0xa68cabc94bdce4e2L, + 0x222a6fb6d3500913L,0x15e28fd5a9c0904eL,0xed31c63f7a91f825L }, + { 0x9cd9f3e56f2f35b0L,0xa2b14261923cab8dL,0x71a780516d8ccbeaL, + 0xf1fe532bdfa937b4L,0x6e3d7252539d0a74L,0x27ef2720814cd797L } }, + /* 39 << 329 */ + { { 0x8bd8341e6899b9bfL,0xc2ea111680865aedL,0x0cabb5cf13fed0e6L, + 0xa11e82c1e4ce70c0L,0xefe3d4eb99aba16aL,0xd774db4dd8df10c3L }, + { 0x72ee5c98bae14dbaL,0x9161d0b179b86e02L,0x1ba8b84585e5ba90L, + 0x3830148f17228bdfL,0x222499e2ba89b2a5L,0x5d50922cccd4f87eL } }, + /* 40 << 329 */ + { { 0x81dd074e4398751eL,0x87b11b480a3f3ebcL,0xb5afe1f0352b58f5L, + 0x6d2d94829c390eefL,0xd073f9a0f36a8d23L,0xa7c5abec466ebbe5L }, + { 0x968c04a60539f145L,0x52a3ad0c93f4d3d3L,0x98e196bb15c0970bL, + 0x2af28ea370ab8ddaL,0xb912fbda7a039fa9L,0x3dd8d87acbd02ff6L } }, + /* 41 << 329 */ + { { 0x849b2f0b4ee5ebb7L,0xfd1b015158bea2f9L,0x260a6b5bfbc530f9L, + 0x2b6c198d06776366L,0x6540793f8074c6d2L,0x1c722c259871be11L }, + { 0x8ce5241ce0560ce9L,0x3574db548096df0cL,0x1d9dd078b0fb8c98L, + 0x6049c7f25625a023L,0xd2c0853cb18d0dd0L,0x5e57bd71cd645f78L } }, + /* 42 << 329 */ + { { 0x8da9b831361ce377L,0x6496515b7dc06076L,0x870e7df3b8cba83eL, + 0x315ac0049f8f495bL,0x1a09dee576fe0978L,0xae7af621c18059a2L }, + { 0x2bc9dea404fac2afL,0xc630bd5021b90a79L,0xbded6b8628c0f9a1L, + 0x709d72c7be4fe93cL,0x3d1e2eed74b22303L,0xcdaf6b1d0e81dfcaL } }, + /* 43 << 329 */ + { { 0x42d004f3be8ec138L,0x5379a3063d617cfeL,0xcbbd274ec1a87d06L, + 0xb9967c5284c9df0dL,0x0238d715c421e288L,0x787ee6abd239639fL }, + { 0x746e4071adace009L,0x2e2545db61377666L,0x47cc241cf07deb1fL, + 0x0a0742f1847dee19L,0x50175dd06e59b0acL,0x95ce3065d2333a87L } }, + /* 44 << 329 */ + { { 0x65c33cf4ca5eba6eL,0xbc48b22e12c2f19aL,0x6c5bbde461fbdcb0L, + 0xe086202bbc503a00L,0xa9483799deecbb11L,0x9b2c0216279aff50L }, + { 0xc10fce1069f99456L,0x2b0051d5b7820d55L,0xd2de9cc32129b5a4L, + 0x711166d9e4f565d6L,0x7a8c3dfb88075f30L,0x6914edda224ac45fL } }, + /* 45 << 329 */ + { { 0xca481b6e4e1e3cabL,0xf390ed5f7e12d8b5L,0xcda82616dcd06247L, + 0xf7d791422cec8917L,0x0c2ea9fe2364e5deL,0x471b71ed21f98e3fL }, + { 0xbebd6a753b9aae94L,0xf9914c0b45f5d5a5L,0x07c823ca4b3dd18fL, + 0x0b8c09ab74ad2bafL,0x21048cf7c7376302L,0x080e4a00efb16ac2L } }, + /* 46 << 329 */ + { { 0x1699d711379e6c77L,0x9126d88c7427418eL,0xbb05797d825210acL, + 0xc0b611df315cb277L,0x90f82a9d61f69206L,0x39a79014f517228fL }, + { 0xd9f2def450e8a693L,0x88c1104381e9d71aL,0x28e20b56451f8a9dL, + 0xeaa794763e101231L,0x3f1ba0c56423e8c3L,0x2fe7ce4e3c6c558dL } }, + /* 47 << 329 */ + { { 0xd706ab9cc55b1a3cL,0x99c453663aa386f6L,0x348c8f743617676aL, + 0x5f3c49092b9ef7bcL,0x26969963ff5d4864L,0x1f952e03f5b490ffL }, + { 0x4007914e30cd5518L,0x3b38fd1e0b0e6513L,0xb25e0a81decbba43L, + 0xb7e77345a7d78431L,0xbb7bc23062467d4aL,0x616c1724598ad852L } }, + /* 48 << 329 */ + { { 0x5bcf287864e60ac2L,0xf70e78a455d53345L,0x88685de6707a7138L, + 0xa77646dcfb2041a4L,0x8608695289db3060L,0x08b7c4d8e27a1690L }, + { 0x4148d9373ca7fd81L,0x58c7440bff7698a8L,0x9d722d4db0391d14L, + 0x5683112462b0373fL,0x87b0363be9a9992cL,0x51870cd18853db84L } }, + /* 49 << 329 */ + { { 0x775086f481eb73b1L,0xddf02d0e4db4d236L,0xab3d637445b09e54L, + 0xb7ef92657e883a2eL,0x20e6ae8f7f42b4b3L,0x26a14629bc49d85cL }, + { 0xf0ee4e5ca4ed9ba3L,0x288c5b0793b0b721L,0x9c767a59e9917114L, + 0x3dde322015085ec5L,0x3176507f7ece24dbL,0x71e1995686cc47fcL } }, + /* 50 << 329 */ + { { 0x86dedf2e9b1ab85eL,0xf3330387c2d0593eL,0xf5e6143997e907a5L, + 0x1992569d8cd66e4aL,0x836b215e0869329eL,0x8b5c4891153ff215L }, + { 0xf6c52f1b609dcc15L,0xa3a5258c085722c3L,0x0a4e81501c378dfcL, + 0xa8997ddc739040aeL,0xb1c4417a7180a073L,0x618009bff1dbab34L } }, + /* 51 << 329 */ + { { 0xc276e23733ec753fL,0x196a1ccee112da60L,0xcc049e2b953211efL, + 0xa60e1aa711dcc43cL,0x091ceb49cdfed2ddL,0x8fe1c52e72c69037L }, + { 0xf66eac87a986ba11L,0x4917f822b273d90dL,0xf7ef04cc957befacL, + 0xf8a7ac1320b8aeebL,0x71f0db3dbe6af428L,0xcb0bf8ba566429c8L } }, + /* 52 << 329 */ + { { 0xf617674d2cbb40a8L,0x446ad46b4d11399aL,0x4d4246943076b6b3L, + 0x1b9e7d881c33ea9eL,0x8e1aa6716954589cL,0xf1099b26e221722cL }, + { 0xb18904f94917576eL,0x0512b21bb549058bL,0x12c89a64a209ad3cL, + 0x421f5e575557cc67L,0xb42e17371b5a17edL,0x427c6a621ff3230cL } }, + /* 53 << 329 */ + { { 0x74e75db02bfb49e4L,0x7685588d58cf18dfL,0xfbfe8f56398e27a9L, + 0xd2711ec365666b9fL,0x1df7714d2c59b787L,0x0f2c4b4c486f8fc0L }, + { 0x098ed315f847b688L,0x60c367e332a20ae2L,0x58f48cd6bba6dd13L, + 0xc41e31960616128aL,0x7f90dd69a3205005L,0x8e6ce9d23581c177L } }, + /* 54 << 329 */ + { { 0xcf2da6044a3b3618L,0xcfd27cc6b83f1814L,0x8cb45c0a6b9369a6L, + 0x1f11501633976ef1L,0x2654a1574afc708cL,0xb47f423860970498L }, + { 0x548be9389fd8536bL,0x454fde1673ff1ecfL,0x44657efae96be82dL, + 0xc8e7e96b555df813L,0x2a0b3f4a4fccb822L,0x2e0f36b114b6dfdaL } }, + /* 55 << 329 */ + { { 0x227ba88551cefcb8L,0x81e8f52e00071a19L,0x4afd5a5d170fee3eL, + 0xc8864e274e17ff05L,0x1d8c2083710ffa4dL,0x22529baa9839c46fL }, + { 0xad771341825a0a87L,0x34a3049edad7c56cL,0xf1f14e1712f3625fL, + 0x6103d1fabcd36dfbL,0x9f5ce7a949a7cf78L,0xa5a4e38a333cf634L } }, + /* 56 << 329 */ + { { 0x6c8e5a261d99492cL,0x6e5bab8e77f916a3L,0x9b014aad50ad6f39L, + 0x2a3933c51f107e26L,0x4b04395cc951bf73L,0xf8f683b4b0ef56dfL }, + { 0x28c9fcdd1905c84fL,0xb03604f14141feacL,0xb546f58e53ace23dL, + 0xee5fec4efe688f02L,0xd8b43f6d2e91406dL,0x75e44b21261764d9L } }, + /* 57 << 329 */ + { { 0x56905026e84e6549L,0x1dc1958c5b84b0b7L,0xcb477afba55d3c52L, + 0x6c67cf7bc1434094L,0x739da94d2ecb03edL,0x8c45e5ee778ca2fdL }, + { 0x66084f9712e2fe43L,0xee6a89e66c3289d1L,0x623b73abc5d1a215L, + 0xb0edfa31cbf45830L,0x8024dffbd7de3b1fL,0x2ddf805a27f25caaL } }, + /* 58 << 329 */ + { { 0xb4e5a5d5605d7341L,0xe7a7a4069a1d3465L,0x234783d66c60b1b0L, + 0xdd7ee2fb3b480129L,0xfd183240dbb7032fL,0xba2a97accaedc8c1L }, + { 0x1a1824d3b0185c9bL,0xddc0f82cd36edae3L,0xaf7bbcc03116b17dL, + 0xefc9095985f6e8e4L,0xc6bde428acb9c328L,0x69d80732cbf991a7L } }, + /* 59 << 329 */ + { { 0x455a23a465ecec1dL,0xcf0b2a221d9e9887L,0x0b43131e3fbb1cc9L, + 0xd4ece789bdad49b9L,0x370c2f9aedfa4d17L,0x7f6855be15163f17L }, + { 0x868a16f3735ecbd1L,0xd84527db08897c01L,0xcdbf5b18f2df294aL, + 0x8c500b1f12b99a2fL,0x929c58df2591e3b9L,0x314cb13714eae6cbL } }, + /* 60 << 329 */ + { { 0xd014cc6deda2479bL,0xd2586003f1a85fb5L,0xceb0611153cd207cL, + 0xe8c9fbfa647b3c16L,0x1f53e8e6ab7d6738L,0x06dcceabb060b5f3L }, + { 0x80e023b2ab770ccbL,0x83ca0a5f4cda70d2L,0x19f7f5dfea1caa2cL, + 0x769041414ffe884eL,0xfa4d93a3fca3c05bL,0xd381f527e88e1169L } }, + /* 61 << 329 */ + { { 0xa4553b3534914b85L,0x03968ddddc176f80L,0x095fb9531f258fa3L, + 0xda9d2df7a554bb6dL,0x012a30ed84926864L,0x3fea37b12aa219d2L }, + { 0x730d2c6d81cc6036L,0x96ea83c9ddd81991L,0xfab080dcef1678dfL, + 0x16e25c6bfb2fe230L,0xf083a2b298ef2fb5L,0x0c0d0767581feac0L } }, + /* 62 << 329 */ + { { 0xd464a6525bc81cc8L,0x513353adebfa99d0L,0xd1aa97c0be51245bL, + 0x0d37e590e4d20201L,0x7afc95cbb45c5c19L,0xdbd640cfb6a4ea8cL }, + { 0xffcc3ff2be9c5b78L,0x61cb76ac1b2865d1L,0xb145bb0011352d21L, + 0x69568e5ce550ac6dL,0x454a33043bf7ee0bL,0xa2fcf9b45dad3642L } }, + /* 63 << 329 */ + { { 0x2e2c8fb3f33eaca6L,0xae1c78b265f75366L,0xbdc601092280d2b4L, + 0xed8409b7b6f472f0L,0x69eafa4f439e09afL,0x3b9ca2ecaa2b1531L }, + { 0x59b2e8eb336e484bL,0x93ec3ecac5f0481aL,0xb01e690ad575157bL, + 0x811aebc262e9d767L,0x1b26c0e49a9065eaL,0x5712d2c969a18827L } }, + /* 64 << 329 */ + { { 0xdaa7fcc9f9474bb7L,0x3c82e74bafa5db2aL,0xfbf918c59894edceL, + 0x470c45eda9ac29a7L,0xdfd44f6fbc372f2cL,0x73a4790aa1e38d3fL }, + { 0x23d2400ba9674837L,0x3dad71bc136a92daL,0xc76a488148baa4abL, + 0x73227e4ebc26e6b0L,0xe732edcfe8ef5662L,0xfe96aa5f0c5662bbL } }, + /* 0 << 336 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 336 */ + { { 0x87c7dd7d139b3239L,0x8b57824e4d833baeL,0xbcbc48789fff0015L, + 0x8ffcef8b909eaf1aL,0x9905f4eef1443a78L,0x020dd4a2e15cbfedL }, + { 0xca2969eca306d695L,0xdf940cadb93caf60L,0x67f7fab787ea6e39L, + 0x0d0ee10ff98c4fe5L,0xc646879ac19cb91eL,0x4b4ea50c7d1d7ab4L } }, + /* 2 << 336 */ + { { 0xcfbcbc4a7db62b5aL,0x2919bf514ab45ddeL,0x735de05622322f91L, + 0xd2590bda7662ae23L,0x63d468fed82be7a6L,0xc84d0435695ea172L }, + { 0xc50f494120a6fccdL,0x2d613990620f44f1L,0x680ccd041fd25778L, + 0x25ddac444a3d0808L,0x41d8b738c4684cbaL,0x2611645f53963888L } }, + /* 3 << 336 */ + { { 0xb05cb834b0279be5L,0x2de7d0ebf08c5f93L,0xf023b5aaefa9e4f0L, + 0xb8061e5d9bd075ecL,0x7d2ba50f1aa41bfbL,0x8963f3e390865d96L }, + { 0x7f221a794713ec7aL,0xc83bc5178500b4c3L,0x085feb6af6ab1540L, + 0xfd141024dc87cd93L,0x3e196fdb3239dbf6L,0xb7cf3e16dbcd5364L } }, + /* 4 << 336 */ + { { 0x1466c9f5e03a2fb4L,0xb866c006862a58a2L,0x291e8c75b5865550L, + 0x1ddb7154e65862ccL,0x285153bc2b997167L,0xe2fce0e7954b6c19L }, + { 0x985d450616dc2937L,0xf7f14216ee41d9c3L,0x39e098dafa5fe5e5L, + 0x3fc26046f90f231dL,0xde5d5ced32afd0b5L,0xad688b1d60c09c18L } }, + /* 5 << 336 */ + { { 0x3720b1720f806b59L,0x1f696d47f224597bL,0x03c46e315b54eefcL, + 0x387e466472b0edaaL,0xfc59b03dee77476eL,0x86854e54607a7259L }, + { 0x1478bcee3e9320dcL,0x4aa825a88c9d87e4L,0x71272f72cf272ee0L, + 0x19e3a4a38bd885cdL,0x9af6415b376ba31cL,0x6394b5a7807b2b36L } }, + /* 6 << 336 */ + { { 0xdbfcfa75e572e06dL,0xafa019d08b7d5653L,0xcc6c851d67a19b60L, + 0xace88bf431ae1a67L,0x74554a6193d1e135L,0x51ba2cdd4211890aL }, + { 0x7cb326899e8d1f02L,0x29a6b8258b66ab99L,0x0a672c21766e72f3L, + 0x24bb718a880642e3L,0x425dc41d184d2b36L,0x96a1468e891024abL } }, + /* 7 << 336 */ + { { 0x3180789c26df7050L,0xe375a43e96cdfd31L,0x7951b895e99e922dL, + 0x987ea2503d0bbe80L,0x6d2f49f0e2fe79c0L,0xc9c2c636c2b18d2aL }, + { 0x707798f3d8c8620cL,0xc2d603dad5c6a0eeL,0x46cf1e32bc447940L, + 0x4dfc145938a845f3L,0x210083fe455e5d92L,0x6be989eaa1fedc3fL } }, + /* 8 << 336 */ + { { 0x72fc8198dacc038cL,0x5fdae1d9f1077bbdL,0x369198bbd99e3036L, + 0x6b68390a0efddfcaL,0x8c35f3e4f0914741L,0xd2bc54ecca7d7807L }, + { 0x564d991e3a8695d1L,0x5e1e14c81b0d937dL,0x51f30dab5d635893L, + 0x0427e346f944e49aL,0x1e0bf1b56a233bc0L,0x75b0ee6c617bf93eL } }, + /* 9 << 336 */ + { { 0xcd2db6797b1bbd75L,0x1ce5acecaac388b1L,0x715ab9f634c1fa9cL, + 0xa531e1b8e0815643L,0xa64511c692de769bL,0x8425126b785b8bc0L }, + { 0xc8d9320de72e155bL,0x9cf36dcd5600a04bL,0xbea8b0f4c6e1f7fdL, + 0x6f9af6349767d85bL,0xc3ea9fa4c403ecb8L,0x0af7be1ed60a0e70L } }, + /* 10 << 336 */ + { { 0x180afdcc20928729L,0xec2e90f436bce72bL,0xa8a8c54d8f48e48cL, + 0x9d0c6a355248109bL,0x8bdd819baa6c3ae3L,0x95e221a6dc0bebc1L }, + { 0x83e568eceb113737L,0xaa6d29c8a1a3a0a8L,0x0ebd5015c54fbda4L, + 0x692a84832a5c8b17L,0xa08e384b51836490L,0xf1904bfc37ded786L } }, + /* 11 << 336 */ + { { 0x2093335463919940L,0x34e4f27397ea3359L,0xbe64c5584d4156a5L, + 0x368a6c980497cf92L,0x59931a502288b8cfL,0x67d70ff8c36cf906L }, + { 0x4175562a8886126fL,0x46ecdd1d55114ffeL,0xd12876f94efde702L, + 0xb0c9333fc046d908L,0x8358b04a2cd6c180L,0xcbaf4612336d3c84L } }, + /* 12 << 336 */ + { { 0xd77d9cd4fe8dee55L,0x7a0f60c12e43fc84L,0xecc5cd746d5da126L, + 0xb5ac6fee2382a984L,0xd9db83e26ccd0feeL,0xaa4dbcba350717d4L }, + { 0xb3c0562c812ead77L,0xf7a995eea96cdd07L,0xd5419bf1ffeb4e67L, + 0xba0aa22e1226df29L,0xb8d0d7f4c1e333d1L,0x86fecca60a27388cL } }, + /* 13 << 336 */ + { { 0x9ea1d715dc579084L,0xc1e715dd0b1cf2a4L,0x624fa6e4926bf7d5L, + 0x5034c9d34f7b4e51L,0xc1b0ed7aba3a42a6L,0xd1847c28b73cdb77L }, + { 0xa4794bc36ae49ff0L,0x50b2d908b9144fa5L,0xad112c778f073479L, + 0x040499dd4b98f590L,0xd415d273152b5e30L,0xd3f4ff3f39054cabL } }, + /* 14 << 336 */ + { { 0x1e0318d5fff93451L,0x40b91fa9283e197eL,0xdebc5a28089ac579L, + 0xcf25f527e9d98537L,0x73f7818d4ae08f51L,0x397f2cb6a956c875L }, + { 0xb7d74ac57515436dL,0xc29a2ffd830664abL,0x02e273563cabe01bL, + 0x418417c103c78924L,0xd12994116535005eL,0x53fc391258f66295L } }, + /* 15 << 336 */ + { { 0x6b1fceac4d87dff4L,0xd31aef70f262f722L,0x894361782612da01L, + 0x1d3bdfa9963bc230L,0x9a46505ba7afa565L,0x662c2fc7a31db4ffL }, + { 0x33983a9ae5ef30c0L,0xb8c874ee723f085aL,0xfb5fbc860f279c05L, + 0xcd9cc376ad0a380cL,0xcb19d881fdfad736L,0x1c3d9734585167ddL } }, + /* 16 << 336 */ + { { 0xd23658c8d2e15a8cL,0x23f93df716ba28caL,0x6dab10ec082210f1L, + 0xfb1add91bfc36490L,0xeda8b02f9a4f2d14L,0x9060318c56560443L }, + { 0x6c01479e64711ab2L,0x41446fc7e337eb85L,0x4dcf3c1d71888397L, + 0x87a9c04e13c34fd2L,0xfe0e08ec510c15acL,0xfc0d0413c0f495d2L } }, + /* 17 << 336 */ + { { 0xf791c8196726ae9cL,0xc95c53f13cee0ca7L,0x816b37ae601b0802L, + 0xcf28a2371b854925L,0xdc4f6bc111d5d9f2L,0x222d6102df6862aaL }, + { 0x93d3fcc5c0053ee2L,0x1d30937fdf873eb7L,0x925a2c2527d098b9L, + 0x8564c199001cf28aL,0x87cb85ed748b8479L,0xd12d6b2b184c1020L } }, + /* 18 << 336 */ + { { 0xeaf36b865bddb3c8L,0xa4bab6e0099f18ecL,0xe22839208addee4cL, + 0x485307e053bb454eL,0xf981c80d362db12aL,0x012190355cb4b460L }, + { 0x62824680c78bd110L,0xf3e0b963d87df5f5L,0xd96de5e2758da525L, + 0xc6a810faa60956abL,0x913d5a7b8e3eb6dbL,0x27c581fbbc9e8c3cL } }, + /* 19 << 336 */ + { { 0x5edcd7dcb0c55d75L,0xaeb0b5c727838c23L,0x13d65db758c3fea0L, + 0xe821d853b36f1f15L,0x3435a4bc365e7703L,0xb890e52f3a04d292L }, + { 0x6a96ae92e7a823f3L,0x3960ecb0ca611036L,0x81638aff210cb460L, + 0x5f95793ce6b983d1L,0x0d5029ffa3ae1a8dL,0x54f749b492ca1229L } }, + /* 20 << 336 */ + { { 0xefe0a702537c4a5fL,0x322ff89c151d0e69L,0xcee88b48491b757cL, + 0x8e92cc15b5da77c0L,0x3138b90bf6af039dL,0xeb73edd2f3748d35L }, + { 0xf29f06435b8bb06cL,0x91ea9643560e4966L,0x013c274875acbcc8L, + 0xdb2d1d9703f1d40dL,0xed7aeef1fcac606eL,0x91395dcabff4b849L } }, + /* 21 << 336 */ + { { 0x952e4e21c8967f37L,0xdc9f71994bf85ec3L,0x6b01f3d00c141bd4L, + 0xc6601dec06c9ba55L,0x7d884fc0c4a5945eL,0xcab1de947e19d3baL }, + { 0x9ca6aff02e3c9c5eL,0x01e828a1445e4a8bL,0xf97165ae80d065c1L, + 0xe2195895881978a2L,0x4834501fc6b77acbL,0xbcf7545445d99f5fL } }, + /* 22 << 336 */ + { { 0xbfc9c5071e434ba6L,0x30768f646f2634adL,0xee3a7cec1caf9c0bL, + 0x27c4fd0bc232910fL,0x5c5813ee24ff4510L,0xe5e731af901f2ce6L }, + { 0x440ca2cf68f9aef3L,0x54ff9e837fa17587L,0x4d792db7982acc0bL, + 0x73c3863834846c98L,0x76cff95f8d6243d9L,0x5fa573399d015583L } }, + /* 23 << 336 */ + { { 0xe0419a6fb007e4cdL,0xc44ac4961f613529L,0x3408e15af18f82eaL, + 0x66bebd87d92d3b39L,0x1c563ee4f85d0c1eL,0xb31a8c891f7eb37dL }, + { 0x65c7bf8c458a056dL,0x9d2ba592f25b6f73L,0x1ac4f0bc94eeb39dL, + 0xa008b562d9a9ac29L,0xe7de714589d1c354L,0x420f5cf04c2e45d2L } }, + /* 24 << 336 */ + { { 0xe11cc2e117cc0d20L,0x9b4cc698d406fabfL,0x6f6e9b0cb8567c18L, + 0xa0dcda9c61b22b83L,0x4c8683fa79ee53abL,0x7d46b3f82f11f0c4L }, + { 0x91e74e482740aed8L,0x75afb62a056466e3L,0xc60bb430e8d0c16fL, + 0x36cf252522b4aae9L,0x3713f254aceb6dd2L,0xc2906379eb8c6fd9L } }, + /* 25 << 336 */ + { { 0x440da0369eb8b2deL,0x6c4d1a38462fbb19L,0xfd86930fb050f995L, + 0x2e5f1a8c954823a0L,0xe9122aefcb9f8e9aL,0xc9e923f2794be14eL }, + { 0xdaa5663dbf740c2aL,0xf3a7ecd6df75c915L,0xa047a07efa80015aL, + 0x846b4d27ea4a720bL,0x2389717e295845f4L,0xf56f77f6cbf2eabaL } }, + /* 26 << 336 */ + { { 0xaac4f6a7e67b6dcbL,0x59ccb836d51c5183L,0x78d19f452b7ccb20L, + 0xb32d4ffd5a619a1dL,0x86b11dbe5c4bd17eL,0xd983e839a9b52073L }, + { 0xfe9c0b92993455c1L,0x3a156676ea36006eL,0x578217fea907ca7aL, + 0xaa3c5489440a251fL,0x6760a166d7fdf3fbL,0x4a2fc54b4415c6fbL } }, + /* 27 << 336 */ + { { 0xaedf171dbe18bc16L,0x00febab2b2d026ffL,0x82b6d8890cdcca4aL, + 0x1b1e4c53445bc877L,0xc2174e10ed74285eL,0xced66cc02b243f6bL }, + { 0x73e9ff69c7b9a66eL,0xc4fe5caad5e4d121L,0xaef80d67402c5d1fL, + 0xd3b95a0f2f3dcaf9L,0x00cb6e798ceeea00L,0x1ee2ca8c436f35e1L } }, + /* 28 << 336 */ + { { 0x0b21c764a6db111fL,0x7c36dfde24c5721eL,0x53a0b6db66e2d428L, + 0x6f37bf728169d776L,0x9baf6385a68511c8L,0xeaef9c919b218151L }, + { 0x712cdd5bdd58d201L,0x50bcd0988d3f78c3L,0xfb6427b571fcb05eL, + 0x6245fe7cc4675aebL,0xb5b75b50fb767bdaL,0xc1d8b76ddd7a18fdL } }, + /* 29 << 336 */ + { { 0x6392686cbb52f636L,0xf10df7c41c46a5c1L,0xab7f88acc504a122L, + 0x2a179193fdb6a9d5L,0x2a7c7e4e2901f29cL,0x3ab41b80a2cc726eL }, + { 0x8f577fc31fb5e412L,0x65cba0aeff7c47faL,0xa79191697f45c04dL, + 0x2712fcaeb29a4c06L,0xf2a879e4099f76e3L,0xd333fabd98a22a04L } }, + /* 30 << 336 */ + { { 0x87a905e056ddf14cL,0xd36289cb95a1c633L,0x2fb251aa57f8f0f2L, + 0xbf9c72a9fb7907a4L,0xb4f9b6f3f771333dL,0x7b5ed437469ea10bL }, + { 0xe8cfa847fa5a8f93L,0x456395c945a4c9a9L,0xe20ffc39f7fac5a6L, + 0x8b07c9ff287a3c78L,0x117f306f67e66d0eL,0x97c8a6388b331e09L } }, + /* 31 << 336 */ + { { 0x1b3e04c26a98318fL,0x04d5ed5dd5a63b2bL,0x4098d09f3cebabecL, + 0x226bb70565a14306L,0x5bdce76fd962a94fL,0x47a66e96c40dedbcL }, + { 0xd514ae5bbedcfbb0L,0xa8c0fe40892f07e7L,0xcf78e224c9186f1cL, + 0x2499f68fe94329e0L,0x3ea3fae5ebbe3d2fL,0x681fca8bbc631de3L } }, + /* 32 << 336 */ + { { 0xb097b2c5c4e81268L,0x7ef175521d50ca8cL,0x638266e942099644L, + 0x43d059deff729073L,0xeebb5fe1148c3940L,0xb82e73d1daa8e925L }, + { 0xf43c78d8254380fdL,0x2beabc58fce37fa0L,0xcdd5a7d66b636357L, + 0x8b70a2ebe096a954L,0x011d5419d0afa2fcL,0x3e49eb6704fb095aL } }, + /* 33 << 336 */ + { { 0x5c73f69fb99abd8eL,0x0a7c36aacc1ed636L,0x9d2fe67e7f69a6cdL, + 0x04d015fd48c34b1fL,0xc50f88c17f84915fL,0xeee3e105a706fb24L }, + { 0xbd42861c734d0513L,0x544b6ef495408b60L,0x4526e680d40179beL, + 0x9f984c4140ab740bL,0xbed7baee67a02ab3L,0x09e3446862a9fb2eL } }, + /* 34 << 336 */ + { { 0xdf64ebcf28eedf59L,0x435531be73b5d9f4L,0x1990df01cf35d981L, + 0xa34d4fa9a2cc41b0L,0x9f643bd6b5a10b37L,0x90cae11158a6cd14L }, + { 0x2b0490701943d2f3L,0x2c9f8af4eda3fc20L,0x48c245c5f96e72f3L, + 0xb4505a3a861355deL,0x4dfab1b9be032112L,0x69c1a9195942de24L } }, + /* 35 << 336 */ + { { 0x761c2c356efcc891L,0xd06710d1fa376241L,0xc83a491c8a78b0fcL, + 0x0c0ee8d8af75b3eaL,0xe6d9d92e4532b587L,0xcb3b652d64eba138L }, + { 0x1cc504ca34ff5d2aL,0x207e7443d0eae0baL,0x94ad1676428382b1L, + 0xfcb5909992ec17c5L,0x7f99e1b5ce3b2e48L,0xa8c38c0fac9bc921L } }, + /* 36 << 336 */ + { { 0x5763ff1af4ba4711L,0x6aac1315bfaae662L,0x51b9c30ede4b5505L, + 0x50e63d1891b25d3eL,0x41938349e65ea695L,0x11260360f514dd15L }, + { 0x231f7f574a086eecL,0xa2c3237f55bd9ee1L,0x8afafa043e0705bbL, + 0x44607900e9fc754fL,0x7250929678519ce3L,0xe751c3a74d17708eL } }, + /* 37 << 336 */ + { { 0x0098a3254611d3dbL,0xbee52036dde82f67L,0xec432a62cdd50282L, + 0xae8a144e52f994f2L,0x027e9e60aa5c03fdL,0x1a49ce47821f55f7L }, + { 0x46fbbd6c4d10c0ffL,0xe14c82ff8c461df3L,0x95570f44aef902b8L, + 0xacaa04ec0eb7eb26L,0x3c8c86a8e738570fL,0xb87d47ccb77cc59cL } }, + /* 38 << 336 */ + { { 0x2f4f68377bbf7168L,0xd5b67947f03f7145L,0x2c6ca74d4cecfe22L, + 0x0e559b9f0a7d6fadL,0xdbcd039ff6b37f98L,0xaaf1f6edfa7a3877L }, + { 0x97b779f0f607316fL,0xe2185ccc72b99fd4L,0xd3f696bf2bdfe399L, + 0x20d9baf15e6c403cL,0xe5bbc1cb4c4f1216L,0xd1c0761a428838fcL } }, + /* 39 << 336 */ + { { 0x4f433b8abd08dd65L,0x27849a72773bd3c0L,0x62351b911854502eL, + 0x836580ffca24ce7dL,0xa5c224a39355258aL,0x8d33fb43e65db7f0L }, + { 0xe44d391edf49a825L,0xc28e0d9bd2f5d4bbL,0xf7208342efb61ae9L, + 0x43686b414dbce055L,0x7f7562d01800c062L,0x5031bd7c8b8ace99L } }, + /* 40 << 336 */ + { { 0xc183199375476a4fL,0xa6383a0055fc4367L,0x23a72dea98bf90c4L, + 0x67ee6f451045a947L,0x4e6518836920d0a2L,0x49132c9ac8042a04L }, + { 0xe249e46d5dfa9fc8L,0x6ff9eba1c60d1a11L,0xa4d9362d43490335L, + 0xe8fad79ade504480L,0x519e8d1bac43c951L,0x7e688047952d6f54L } }, + /* 41 << 336 */ + { { 0x135d677342e27f9eL,0xd58b98fb8fcc77e0L,0xf3bb847d7f64928bL, + 0x15ec841663176905L,0x83e75b6a0f755173L,0x4c3eff5c7a24de69L }, + { 0x289e9a45313bf61eL,0x01b15aadeafa2733L,0xae7fafe1d2cf501dL, + 0xd6fba525d5ac0b3eL,0x4bf48be0689bb20aL,0xa591843255bf610eL } }, + /* 42 << 336 */ + { { 0x0f019b64c5f8df0bL,0x112f06a979307310L,0x91dc57276d16102eL, + 0x34070a5be2651248L,0x0b9f35dbd3423044L,0xf29bb4a072b10ed1L }, + { 0x87071a9a07fb6388L,0x4246d532b7dbdb1eL,0x87db3d2285a039c9L, + 0x76620a5d42b030cdL,0xc798e3816a42d8ebL,0xdd97441ac441ef9bL } }, + /* 43 << 336 */ + { { 0xa9b004a0f08592c3L,0x984d17e5d069c54dL,0xc96f2132ccb87e81L, + 0x67fd082f3b1f9eccL,0xcdd0827ac4ff9feeL,0x9d1025070e04b7a6L }, + { 0x4ff3424177c67935L,0x4f2246f58efea5b9L,0x128085b12fbf7615L, + 0x9f111f65174b0575L,0x0b27d8e2f455cba5L,0xda20626b536054eaL } }, + /* 44 << 336 */ + { { 0x4a3df6de3761fa82L,0xb839d6babc56eb6cL,0xe41afc5e13977a26L, + 0x64022937fc0686d5L,0xa5d6dc19e2d681a2L,0x81afab3128f411b0L }, + { 0xc089aff74321a117L,0x32b0ae2657d18f89L,0x650aacd5f66aacd0L, + 0x7b317bf6b8d3f677L,0x2cd5789777ea82dfL,0x935be0f3c74e7509L } }, + /* 45 << 336 */ + { { 0x4387f8f602de9e59L,0x529c06f337589811L,0x6dbaab60bc9f06b4L, + 0x0063bc3db5f181faL,0x7bcb289969b906b3L,0xdca70d1331d1ea3eL }, + { 0xca65e546ee373e94L,0x13cd365c779f415fL,0x4183460e9d71cb08L, + 0x60f312726e35eaf7L,0x3d0c265f14bc5e0eL,0xe7a1b9af39ce618bL } }, + /* 46 << 336 */ + { { 0xc234c892f46aac36L,0x213076ada55983a9L,0x81f96142dcf335a1L, + 0xf21ceb724b22e311L,0xa12d6333dc053e1dL,0xe7808925a930732bL }, + { 0xb5a9eb81b1f1075aL,0xd13739c0f0a3e623L,0xbcd842e9ff2f24d5L, + 0x200cda381b16ff0fL,0x0a85ea521d6a6c54L,0xe1c0dc8756785463L } }, + /* 47 << 336 */ + { { 0x3287c8d39100f769L,0xb349ce8c052e8bcfL,0x5fdb952dd0d3e44bL, + 0x68715110d0639cc4L,0xc9a5fbaac8efc67eL,0x14ebb97da009aec5L }, + { 0xf0684e1ca1423e1eL,0xb282f2f56357fa17L,0xc2e79d3c5af78041L, + 0xe0ca9f4bd7d2ba8bL,0x20629f1e04dd84bfL,0x274ebccc3ee73228L } }, + /* 48 << 336 */ + { { 0xeb05c516156636c2L,0x2f613aba090e93fcL,0xcfd573cd489576f5L, + 0xe6535380535a8d57L,0x13947314671436c4L,0x1172fb0c5f0a122dL }, + { 0xaecc7ec1c12f58f6L,0xfe42f9578e41afd2L,0xdf96f6523d4221aaL, + 0xfef5649f2851996bL,0x46fb9f26d5cfb67eL,0xb047bfc7ef5c4052L } }, + /* 49 << 336 */ + { { 0xeadd123d385f2b36L,0xe3b14829ddf58569L,0xa4fdf0ec47c7e485L, + 0x93c0d8380623ea5fL,0xeb9c0a2c9e2661deL,0x8046fc69e72e0ca6L }, + { 0x6f439e5c7be1c918L,0xcd8fd2f92a9ffcdcL,0x7f134747420e939cL, + 0x8e880ef05ae283f9L,0x502c5c99f780a249L,0x68a529ab94bf9d68L } }, + /* 50 << 336 */ + { { 0x3cf994ed88c9d290L,0x9209f5610bb34d46L,0x8170b567b2bfa21eL, + 0xae87b6f7c62f86d4L,0xac6fc431d71bccebL,0x5f3a62ba83cf2970L }, + { 0x390262d1d943b10aL,0x8fc9a27f28aec573L,0xe59beb203e3069f9L, + 0xf3e7bd365e0812a7L,0xc29c8a433aceffa4L,0x015feecb41c25e2dL } }, + /* 51 << 336 */ + { { 0x5b6a4d6ca8e61f40L,0x35825d762f9a6e70L,0xd48f6d8d346a8b94L, + 0x12bea60889801a40L,0x5182192ad57115f6L,0xb5a8dc6b954c1b47L }, + { 0x084a5c71793b427eL,0xeb66d699f8de2a03L,0x9835b2fb8eb6d905L, + 0xb4229923c79dfe40L,0xa7c8aedddee34c0aL,0x12a00675337b0658L } }, + /* 52 << 336 */ + { { 0x38ca9f61d44aee32L,0xb2cd0f505484905aL,0x23ecb3a4d812e727L, + 0x9be645b874a3ac5dL,0xaa4a1d114bfa93b9L,0x5be5277d147072caL }, + { 0x623a4bd9ba0a6d93L,0x03419661dcf3d9b1L,0x9bffbe8231de1cf4L, + 0xbadfa2ab56a6af06L,0x9103f7256746f09cL,0x0cd5e956344a2688L } }, + /* 53 << 336 */ + { { 0x50a18ab1f40b0edeL,0xf963b76736e01032L,0xba2029b4d4f9a6deL, + 0x8baec9b85a8446b9L,0x7a4107e766fa8a92L,0x06e78bf99f6543d9L }, + { 0xdaa894b3a5043e86L,0x172858a8f4e6fe37L,0xff0265cc0844608dL, + 0x5db1a8f1d5def174L,0xdf9f8a698874fbedL,0xdd2292a977a274d6L } }, + /* 54 << 336 */ + { { 0x46f522196ad8d03dL,0xb63e0eaadaf8b0d3L,0xd667f0a66e29df38L, + 0x6e77432f96ef3b57L,0x78fe0872139ca180L,0x300a0c78d1e4af21L }, + { 0x650f32462148816aL,0x31ef1e883b4301a2L,0xa2222b25f18442fdL, + 0xb26b63066884291fL,0x977b6f7d713d88daL,0x3e8173248cd5f7f7L } }, + /* 55 << 336 */ + { { 0xd5687c9a9684771aL,0x797808e396cf65d4L,0x793d4eb6ea9ee562L, + 0x2359b991fd94defcL,0x4e75cdf03a8959adL,0x7a08566900ce7815L }, + { 0x5c61df5da699fc46L,0x02b62d4868da56d5L,0x8a6972d1eaea27d5L, + 0x727582b3c8e5d04fL,0x0ab2e6c2de87c408L,0xaa9a62e47b9ed157L } }, + /* 56 << 336 */ + { { 0x9c6247d631af03e4L,0xe5a59ad075f9ee90L,0x1da1d64f6ac4b5a6L, + 0xd2fbd169c521ec7dL,0x6d168015dfaa39f7L,0xe9bcf5b59c69d9d7L }, + { 0x3d1d3e6693ae2925L,0xcda60beae4bc73a3L,0xb2456adc954e2f3bL, + 0x5d312fdc02a8fe08L,0x7b37c00e0e497a0cL,0xbd1f3aafc2f8b148L } }, + /* 57 << 336 */ + { { 0x60f3bb27bc00d150L,0x159c5af42448affbL,0x4492b6bd2cfa563dL, + 0x7e58219683c833b8L,0x9f9ebdb20edfafa2L,0x93a7048f31a39a8aL }, + { 0x4172f74d50149d01L,0xff38fceec58b7588L,0x2e71ba9099f25353L, + 0xdf50fb440604e555L,0x7effa7ca8f3b5969L,0x3bbe8d49b836b8bfL } }, + /* 58 << 336 */ + { { 0xc18c375c29d08d49L,0xb04c0c29c1a681bbL,0x0c4acce9e74dd458L, + 0x1d6da95c85c920a1L,0xc67280d285387462L,0xeba99725e7e804adL }, + { 0x08f80e5a8811a138L,0x26f442138f2136e3L,0xf67f157c2d028cc9L, + 0xb436356d14cd7cbaL,0x1c9c610290281895L,0xf67f16ea48598bdbL } }, + /* 59 << 336 */ + { { 0xbf926a077a326266L,0x4045c18bef43cfc6L,0x6fad4cf56ce45553L, + 0x613ad2dc45a9abc8L,0x7b086ace8836eed8L,0x855857c213ad51d7L }, + { 0xa3b19c2d167664adL,0x422c548abbd2c452L,0x8cd3681f85928ef0L, + 0xe969e45c3ed435ecL,0xf76f2cce746c9aacL,0x514df58d1dd90e35L } }, + /* 60 << 336 */ + { { 0x9b66219c4d09cd36L,0x6c6fa570b54f0853L,0x95c268bcf29a8fffL, + 0xc8cf84bf5420c324L,0x5bfc975ebb61617aL,0x935cfe24e78f1bbaL }, + { 0xa6e2afe919d71ea1L,0x8a321e568c9b950eL,0x42dd9e28ec097826L, + 0xf06e600ef391633aL,0x94e5512b46acbe2eL,0xb0bca2cc61cc7a08L } }, + /* 61 << 336 */ + { { 0xcd361103e8b2d41dL,0x2d0d982cab0b5f13L,0x8158129618d55aecL, + 0xf1c28a71579caa03L,0x5ddedfd7e50b83faL,0x932d2c03222105d0L }, + { 0x48fd0ead75ada3f4L,0x29209d988c533a40L,0xc2acc587f2acf0c8L, + 0x05a8703ef689912fL,0x8f28953b9182995aL,0x1cbba2f20fb3eeeaL } }, + /* 62 << 336 */ + { { 0xa1472574180e5eb2L,0xde27569b93fc7b21L,0x3bb956816b9af8aeL, + 0x8a25fc0ee155f89bL,0x8aff018d825126b2L,0x6eda2f31906f0bdcL }, + { 0x19cbbecc4e8fbe4eL,0x04e0a4a40568d248L,0x6de2c002ff07b863L, + 0x6d388447e8d1595dL,0x6a193b70c2cfd10fL,0x00bd826ee6f6bf96L } }, + /* 63 << 336 */ + { { 0x2a0165a40a5b4d1dL,0x49c85ee904f12309L,0xc2d221031ded788dL, + 0x510ccbb3735bd89fL,0x92d2eaebd8eb0e1dL,0x6bda8e346e428c11L }, + { 0x44c01a1d361f7495L,0xddda8e97cc7a95bdL,0x95cbae30524a53baL, + 0x266d7192dacad45bL,0x8a42793f22fa4b99L,0xbb393cb5ed204904L } }, + /* 64 << 336 */ + { { 0x88e7ac8e168d5e60L,0x53abd5696188a98fL,0x3b96d52918be419aL, + 0x7e75e354c057621cL,0xcb1b709f5ce57e59L,0xe78befa2844f2463L }, + { 0x536081993276d4a0L,0x92636ade157f2024L,0x6dd0d348e0411414L, + 0x5b28e9504d73eeaeL,0x08439232690ed85eL,0xdde1a3496da14b58L } }, + /* 0 << 343 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 343 */ + { { 0x6cbd275739ed9ec9L,0x5db68a68fe5d4aa8L,0x177eaa0be4c58c7bL, + 0x603551ef0e488784L,0xc8eba131df916b0fL,0xd0dbceda159732e2L }, + { 0x55acca84b0834afaL,0xdbe98440b59ffbf5L,0x162a2c703bd3b202L, + 0x4c5e5d256ddd8ebaL,0x66e7844a77b1d93dL,0x1292bc0e110b9dcfL } }, + /* 2 << 343 */ + { { 0x1b66faabf9e89beaL,0xc81c5ddc3a441284L,0x1a82f3a0a675f7c8L, + 0x82884a2f30313a71L,0x7ac5d7b058aea9e6L,0x1954f075cd5ff05dL }, + { 0x7c29638d6178d270L,0x6af7f8ba19381929L,0xe85e3c47a17ae3a7L, + 0x91b107c77009e38aL,0xf3b777d8f1f9c52eL,0x5b7b74ff11b688a0L } }, + /* 3 << 343 */ + { { 0xe1e5b76914b87b2aL,0xee187f5d143a4ae1L,0xa9a38728908cb988L, + 0x2027b2ed4443d8daL,0x1c6b4813c0c98675L,0x509ea7d1323bd978L }, + { 0x43b16a587f4dc19eL,0x385f8be812940ae9L,0xa4ed64e57d59acadL, + 0x47e7abed51ca7f14L,0xead594b82bcce6b8L,0xa2bff60cfc03cf06L } }, + /* 4 << 343 */ + { { 0x4ae3d232c0385874L,0x83bda9e6cbf96d2aL,0xba73c769ec62fd6aL, + 0xd586ba7f62a4720cL,0x6497cd140cc1f491L,0x8b012b707b2ac571L }, + { 0xa65eabb6268fd705L,0x8caf100a1431873dL,0x25b31b84231457d7L, + 0xcab62f75901645c5L,0x2377d74db2f7b656L,0x4008277c2d33c95cL } }, + /* 5 << 343 */ + { { 0xa7be70c04bfeb784L,0x4633ddadc222ab44L,0x00e397d30f5924bdL, + 0x5446db3ae25b7b9eL,0x433ea2c4fa1dd048L,0xbb9ae36a1421321aL }, + { 0xf879069dc59fe8f6L,0xe0f2b8b4820bfee2L,0xcc6cf7c49cf239e4L, + 0x0e3545c207dc3122L,0x23b0f48b1d2c737bL,0x1c6b6d9cfc1137d4L } }, + /* 6 << 343 */ + { { 0x10105dfd101d2433L,0x64e009b58ab6d664L,0x122e68324e80fc07L, + 0x3b26e76287dc7da6L,0x7bc183de6d4728cfL,0xebfecf4f8bcdc129L }, + { 0x8b995cec265c66f5L,0x080572d7c4b0e942L,0x612e9e6b4da5b77dL, + 0x8ec048a96caf9161L,0xe3628ee2c7f45eb6L,0x0190b71bd85650e9L } }, + /* 7 << 343 */ + { { 0xccf79a81017fbd3fL,0xa852ca29c875bc66L,0xbb4cd90c0592f8e2L, + 0x2ee786f455b05c79L,0xe1a2b6baf382e6e7L,0xf2d6cf6e6d2e952eL }, + { 0x2f0b534abc9304fcL,0x1d63fd80795629a3L,0x42e70cd9322d8e03L, + 0x8a282cdfb057e36cL,0xd18a0c313ceb177bL,0x270e31569c58b890L } }, + /* 8 << 343 */ + { { 0xaae2f448ed001c43L,0x08ad1d9bcf4be493L,0x3262b2f482c1f372L, + 0x5521febd351a5f7fL,0xf8ec9190916c75a8L,0xf3c258c72728dfb8L }, + { 0x5dd4ff4f8af19574L,0xefddf5795d076b1cL,0x318b5b98ba8b777aL, + 0xd971d426fb7f8409L,0xed1465e8b0fd31dbL,0x80d24d4300f66347L } }, + /* 9 << 343 */ + { { 0xe8263e8012eb6baaL,0xc452c7581dde8c37L,0x5112af2840baa45dL, + 0x949b8a740793703aL,0x8ba78382e60e007eL,0x38cd110412823c99L }, + { 0xdeb0d555f86cf04bL,0xb2f20bfdfd9f6320L,0xff1d399d17c39502L, + 0x1340aedd1bdf0760L,0x36b2b43c88cc0c09L,0x5f3dba7e9ce285edL } }, + /* 10 << 343 */ + { { 0xcea0374a69ca5051L,0x19e060ad5294ae7aL,0xf6ce02361bb01f47L, + 0x2a5b28ba8c328b8bL,0x6991b1d8b253d630L,0x360afd40859455d8L }, + { 0xf5c6e1427c1f5946L,0x1eab83084cc8c391L,0x4eb4032f67e76ecdL, + 0x5bf14aa233898059L,0x0804a7c00e001b76L,0xe3866a93734cd134L } }, + /* 11 << 343 */ + { { 0xbe85177db72e5eadL,0x47c15fad59fd2463L,0x2cf5f07f4bd51f8eL, + 0x82f48288c2898713L,0xdb08aab4c8f753e8L,0x18a1f5c510f58eddL }, + { 0xaeb7bde366d0b94cL,0x04539620079fb6dfL,0x64d1aff2ebe8c4b9L, + 0x08d9ef431a10a101L,0xe326c7ec6c602789L,0xd8b1b3e7f6efc3d1L } }, + /* 12 << 343 */ + { { 0x5ba5288c1ae586a2L,0x044f1fc61b715821L,0xc1a9a997602f3c65L, + 0xc5c7512fe08c0223L,0x48a19c3c367e6f1dL,0xa9f2195dfb241597L }, + { 0x9f674a5fb5ba32a6L,0x275a060f0a312742L,0x5aeb8c4303d6f13eL, + 0x0fed575d917433fbL,0xe4a5ef9a59f53490L,0xa9f86145f315e616L } }, + /* 13 << 343 */ + { { 0x770d01ab2c1deef8L,0xca72f761f61b2a4eL,0xff686a4ceff9ee49L, + 0xd6b338d30d07000aL,0x885b4e8ce1050b10L,0xd6326179b2364b01L }, + { 0xceb2bafc672b298aL,0x7df8941aba628946L,0x9c94004ebc56b115L, + 0xde09cc2d7b12cdd2L,0x9c2dda163833ce43L,0x88da691a6265b59eL } }, + /* 14 << 343 */ + { { 0x7059c58669a03980L,0x91f2dfe4e88e1287L,0x96dcd9318d9633ccL, + 0xb2abc44f37bda148L,0xe31adb3feb8964dcL,0x7b07e015e316876cL }, + { 0x31732880ababd240L,0x5c37a667e95854a1L,0xb5b334c91d6f69adL, + 0xe613e5622c34e118L,0x8bbdbf5c5f5984edL,0x82ecfd95cf4f63a1L } }, + /* 15 << 343 */ + { { 0x813caa72ade4e3bfL,0x29055be8600c93c4L,0xcb346967e6e4ec1bL, + 0x39c1152d50ce992fL,0x4682c20e5ce62852L,0x04e9dcb7f4e45ed4L }, + { 0xda75355d7c0fa5bdL,0xe80f29b078949d91L,0x6214610130fb9e33L, + 0xe70cda8f325eececL,0x49217f74efca3e14L,0xd3c890b36bd7246aL } }, + /* 16 << 343 */ + { { 0x315ad7a47e5a59f4L,0x1c615bfc543c8b00L,0xe12f97a8baa56473L, + 0xf263db4446edcfcbL,0x47cf91d53c1a968eL,0x1a1165b4c15db875L }, + { 0x5d35e53a3479616aL,0x649f87b45c59958fL,0x5d3d11ea246da3d3L, + 0xc1ddfcc653f06820L,0x8169d7116610c00fL,0x15f16ba54bddc8c7L } }, + /* 17 << 343 */ + { { 0x307b040d9977713eL,0xc03f7787dee9e016L,0x761a5d03e12c354fL, + 0x8fa1a4141cc88904L,0x2e079008b7675e71L,0x649c789591d68d60L }, + { 0x63467e93c98f1c9eL,0x81931ac7fcc52703L,0x2060c89538e59af3L, + 0x8c12e002a87024c4L,0xfc881e69b3b8496aL,0x2b4e482e1e827081L } }, + /* 18 << 343 */ + { { 0xf80ed61a30fa7e86L,0xf2e5f324a15ec5d9L,0x139ca085ecba2d64L, + 0xd164ee5ff3f5cfd1L,0x758c0008e5cc3cc5L,0xd180c463ce8fa1f9L }, + { 0xe5dd27054adc6e61L,0x061e0c3c592c39e5L,0xec5a8d4a4e437781L, + 0x9e4c6f461e6d4540L,0x33ab232e2526e6eeL,0x3c551685ea282d9cL } }, + /* 19 << 343 */ + { { 0x59507a2162ce1459L,0x88b465d1c6a2cb30L,0xa5ef8b2b5c8ef7d4L, + 0x73145f4c4dc9a457L,0xabad3390d19186f2L,0x7036b424f9b78a7aL }, + { 0xf76f51bb16e04046L,0xecd1ece92b2b71efL,0xda8d82011900f2b9L, + 0xc2d3291b268d1bfbL,0xa6c1c79a2d176459L,0xb27e5d5885ee1b7bL } }, + /* 20 << 343 */ + { { 0xcf19fb2a1e548ef0L,0x8bb6dfa0cc694171L,0xeb1668ca5c5e390fL, + 0xf5a3485be1975263L,0x4edfc596442cc850L,0x9901f447f9627d74L }, + { 0x3a6b85c984d0413aL,0x1466366167de639cL,0x9fc9fdcf11705bbbL, + 0x6d066e2bbff2cf80L,0x38dedc2fdc3026fdL,0xad533a981b828538L } }, + /* 21 << 343 */ + { { 0xa7d51d862222dcb3L,0x52e2531cd1a6c525L,0x742b1234532126d8L, + 0x226043f24e9e77acL,0x02f270afb3a75b2bL,0x7ede5714d4a8dc0aL }, + { 0x24699e16b34fd97dL,0x4e5d785e8d417ad1L,0x273f5dd1ec307ecdL, + 0x742373863186955aL,0xf46805fde6afd38dL,0xae100ba424562906L } }, + /* 22 << 343 */ + { { 0xed9f434e5216636cL,0x242bd09bc5c1668fL,0x8bb747bd804f3d6eL, + 0xd66d8753c7c83dd2L,0xa71016c2584540b8L,0xd8b16210fdd41a90L }, + { 0x5eb5947e1b65be60L,0x1bf995e7616dbdc2L,0x71b7099abb7dbdd8L, + 0x53650d29079eec24L,0x6bdd1b0e8ebd86c8L,0x0a9658ed9a31624aL } }, + /* 23 << 343 */ + { { 0x3be2ce89b8cf4d55L,0xf9b3c501822cdcd9L,0x0cc8423010e12f3aL, + 0xee09031a3c580ec7L,0xf4c256a812f4b48bL,0x71a8323104018d0cL }, + { 0x69ad6d7babfcf13fL,0xfa79b457af658743L,0x249f32816001af58L, + 0x158430fcea127a64L,0x25a3e4549a9be713L,0x68ba3f0fcc6b5bb5L } }, + /* 24 << 343 */ + { { 0x6c75bc93b7bfa29eL,0xf86f22b218ef6d69L,0x90ce6a1536dcadf2L, + 0xf11f711c7ce50921L,0x0739ceda38a479e3L,0x840b825e6ec3dbc6L }, + { 0x7c36c0a59fa23481L,0xceb61fd170cb186dL,0xac6f7d3c26e4754dL, + 0x4076d3b5f317b385L,0x52f1bd723fd9e9c7L,0x6649d8b6bf316043L } }, + /* 25 << 343 */ + { { 0x5f03dcdcceb1e25cL,0xafff6561d50ff864L,0x17208b6f3a6bb787L, + 0x61d96c978e15abf2L,0xb1beb427991107b1L,0x436328475008aa3fL }, + { 0x8a326eeb3595febdL,0xa8e5a037ec60dc0dL,0x762ebd2a3159f062L, + 0x8ea005adbd1b0bd5L,0xd4d863cf696d4121L,0x2a07a637eacc9b9eL } }, + /* 26 << 343 */ + { { 0xf352e28b54a8ffaaL,0xa8317f089ce68b6eL,0x7deb148770cad820L, + 0x2411b382b2c3579dL,0x20b21ed214d36e66L,0xe7331bec353b9ff5L }, + { 0x5692636840dff0b3L,0x13356f7b646eff07L,0x1e6e6e4508c64091L, + 0x913b83f2ea0b920eL,0xb69e5f839f713aa1L,0x8e59d3794632a60dL } }, + /* 27 << 343 */ + { { 0x3594c0d3cdefc3dfL,0x9d850e2fd21cf9e7L,0x245322944e38263bL, + 0x597964610e43acb7L,0x13fad563bca9408aL,0xe52983dba985390cL }, + { 0x9c5e71e08c000a9dL,0xde6b0b2f800949e2L,0xc58032d131d94108L, + 0x36cd4099b31811e6L,0xa8d9bdeb3981d619L,0x06f644e03d4760c2L } }, + /* 28 << 343 */ + { { 0xdc2870f8243cfbd5L,0x000b71b31ab496f3L,0x53511a3f708f4507L, + 0xbd7bd0381949d835L,0x723a007d938f4db6L,0x5bc8679e2d04e9fdL }, + { 0x51ca5fd176ec7fc4L,0x86c4205c988f354eL,0x9042e76b2a0a4a90L, + 0x368f52a84ad44d2dL,0xddc2cab8912edfb7L,0xde74ccf5cde80199L } }, + /* 29 << 343 */ + { { 0x91b31fcbcaa3f1d2L,0xb8a29af1bcc99f53L,0xc5842b2695662f80L, + 0x13954262a4b4b396L,0xc1fac956a6acfdffL,0xbe37fa4dcf60b88bL }, + { 0xc7715493dffff3deL,0x06dfaceda1274350L,0x9dfcaffd7460fa94L, + 0x5f1d3a351e9c317dL,0x2fbf393d377b84ceL,0xb4d9bc8404b83635L } }, + /* 30 << 343 */ + { { 0x29871ce22855a74eL,0x5418f0dc98696474L,0xd8bc07d6b90d0498L, + 0x391012a79fdc0ea2L,0x271396949b09f60aL,0xa0a43dbf3371f0d7L }, + { 0xab5849422af8d992L,0x64cbd121409eb3faL,0xd36faf01766864fcL, + 0x69189faea2a83417L,0x3c24d85e3733b772L,0x125a915d2ee497adL } }, + /* 31 << 343 */ + { { 0xa8f9eb2abab3fa8cL,0x484584f654ab1e16L,0xee74e5aab21b34edL, + 0x3ce626ff4eb689f0L,0xd757f22b0006e5bcL,0x611505d024a25e65L }, + { 0x212df14c46382659L,0xd17898d78c73da0aL,0x5604a93e51421c2cL, + 0x76147f7603a580a1L,0x325b5c8ae5c34d09L,0x6ff28848db857152L } }, + /* 32 << 343 */ + { { 0x8002f4583e455a61L,0xafbafd375bea205aL,0xa8ced112fb93f735L, + 0x27cb6292196e3084L,0x72395bdd77e8c744L,0x02e018d8ee71f5ffL }, + { 0x7cfc14d9c1337a1dL,0x94e14c0ad7b4d86eL,0x66e50129d213738eL, + 0x7a905d91bc0b5ea3L,0x92cb630afca06700L,0x65e06d5cbf3a0821L } }, + /* 33 << 343 */ + { { 0x769ff9191e1cde66L,0x6ef257d1944a8786L,0x881437da4f75233eL, + 0x15266f3768665eafL,0x21fcccafc1777505L,0xe9513e1ab7fea0ddL }, + { 0x67806e9c53c8a735L,0x24be9a769b11ae2eL,0x928c1455045d2065L, + 0xea0395b53557f62eL,0x910d7cb4c7d3a450L,0xe849c853c634443dL } }, + /* 34 << 343 */ + { { 0x76c6e48d3b476f69L,0x28195cdffe694ee4L,0xa3a9a99e2d3aacc9L, + 0x0f68fe36b7f320d8L,0xca84a6c9889ce762L,0xc1eafac94901907dL }, + { 0xa28b9916208c9770L,0x6846e639f8403e57L,0x12fdf9fa1d179e3eL, + 0xb81e47c843d046dbL,0x700ad19468c14491L,0x136395cebbac51d7L } }, + /* 35 << 343 */ + { { 0x7452dfd4f775003bL,0xb38a2031f1a4765dL,0xef36c513a2888c68L, + 0x2039b168a2339fd3L,0xf74c24be2cc498e9L,0xbeeaca157b622e31L }, + { 0xda72e5a005f2fb8fL,0xab4a98f0568d5811L,0x231aa495fcb15e1eL, + 0xf981bd7f537023f1L,0x29d6eb2db367e5fbL,0x15247194b8cd452dL } }, + /* 36 << 343 */ + { { 0xa81e4a4e55c2369dL,0x394de01b60a0f544L,0x22acfd07a8906e17L, + 0xf59b37a6cc9bc4d0L,0xdd16a22c7ffec12fL,0x07decc2ad5976455L }, + { 0xc5019463abe1d122L,0x2bf0ac0ce318c92cL,0xfa50280ab2bfc47bL, + 0x53354fc5c7cf8bffL,0xaea1d293e20ca341L,0xec25ecda8b626244L } }, + /* 37 << 343 */ + { { 0x05c6f1c99a2f572bL,0xf13f8c7747987918L,0xccb406d74101fdffL, + 0x93cea27bee1abcf4L,0x32703ada8f5adca8L,0xceaecb5f76313a1eL }, + { 0xf1c558980b9620cfL,0x942c28b51046c388L,0xbed4e9dc5a07cf8cL, + 0x423b695a6c734b85L,0x1ce0a2392ac87737L,0x40f126ac4d1cc7d8L } }, + /* 38 << 343 */ + { { 0x63e3bb09ad9e132dL,0xaa2880c5c9e84778L,0x23de89ea06049834L, + 0x442d1df3554e23bbL,0x87214f9f08c5f124L,0x305d967a6beb4996L }, + { 0x01676f804409f827L,0x16992f73a50147f9L,0x77ee56796081b38aL, + 0x8c75d293290afd9bL,0xf9578bca813f0aceL,0x395212dd0e786ed6L } }, + /* 39 << 343 */ + { { 0x63475e65c21b0f48L,0x114f9af5326c2c63L,0xa897bc01310f768aL, + 0xcaf47a8fc1bf3f5aL,0xc023bb3718cb887aL,0x3572f633685652a2L }, + { 0x2dc4ea0d7523287cL,0xafd60b92a121a141L,0xb6b4bf6e085ca490L, + 0xf599f8f2e5351ecbL,0xe38c8eacddba3d60L,0x2540585f5be9e748L } }, + /* 40 << 343 */ + { { 0x313b66cafd8ba33eL,0x10bdb130fabe27ddL,0x1181334c125e2b8cL, + 0x0f4f198fdb6f94baL,0xf7000076ac3f5de9L,0x1a78813d9d6402aeL }, + { 0x3427f75dc8a9e758L,0xcdac8b34b01f791fL,0x922c36d12a9ebaf5L, + 0x195ea05fb0487cc4L,0xe33de901a808baecL,0x15e1d5ac57291d89L } }, + /* 41 << 343 */ + { { 0xfe52cd9cfdc7e2deL,0x3947e578da6dccf1L,0x0548d4b5738751e7L, + 0xc73fc23f4b52a5ffL,0xf38eb8ff1b066accL,0xe9a40d37a27b40f5L }, + { 0x723b0752a264ad77L,0xe5d0c4efdea83bf8L,0xf7301e3fafad27a0L, + 0x336b0d86298d09b3L,0x462766bdb2ef2fb7L,0xa5311241141a7607L } }, + /* 42 << 343 */ + { { 0x10adb987ee1f44a1L,0xd6ebd1c3e51c0152L,0x0cf1303f4dd3b9eaL, + 0xd06351b837a33a3aL,0xb5ce1d941cff1f0fL,0x326b3e055476e2bcL }, + { 0x90f76b5d3426b8ddL,0x77497380648042f1L,0x48684604f9f83902L, + 0x00275191180f197aL,0x36fd84ecde7ce932L,0x52b428e65391a268L } }, + /* 43 << 343 */ + { { 0xd2c1ccb0695c2851L,0xd722b84ff1c78f17L,0xaaa53d26fe52f2a4L, + 0x3057f4ed24742143L,0x951332a4a2aea258L,0xe5e4db6091096878L }, + { 0x71db9e48f0b9ef38L,0x7e4b25c1ac542c26L,0xb7250394dd021df5L, + 0xcdcc6118ee48e711L,0xbc324af1fcdd5db9L,0x71a664ef3e6de57fL } }, + /* 44 << 343 */ + { { 0x4e2a05c1c21cdd1fL,0x8a232097dd46e76aL,0x8b55313cd871b1d6L, + 0x976ce5f6af396bc4L,0xeb91527dafd381b1L,0x6cfd449014455ee2L }, + { 0x8723be9e1f274d1eL,0x1c63fd011999fa9fL,0x5f1726258049b6f8L, + 0xe18a3ecd99a51b4dL,0x329fc2c1b13d4e65L,0x94da252b0f18f300L } }, + /* 45 << 343 */ + { { 0x583adeb8b893316aL,0x69dce1efee5122deL,0xc5cacdf319b77627L, + 0x061fedee5e8aedd8L,0xd53fce220257dce1L,0x0e4124bdc781e069L }, + { 0xf097c697d44ed517L,0x7704e33e9a4e9019L,0xac245dc23e0088dfL, + 0x70e1176bb76102a3L,0x55261ab235e4dcaeL,0xc2ba59230ede3501L } }, + /* 46 << 343 */ + { { 0x6edf35f3af073b6dL,0x7ab4118107376eb0L,0x4ef3e65be7ff1c9aL, + 0x654ea359d2ac6d70L,0x2b41a7f67ffcd91fL,0xe5da0511e0a60e8cL }, + { 0x97fefd9756701b93L,0x7a4a827dd34afe15L,0x8bd6c2299090536cL, + 0x110156f217e510a0L,0xce62a26ec801ca6aL,0xa786e9b05522b64aL } }, + /* 47 << 343 */ + { { 0x3c73c2868f02f70bL,0x744a580d0eeca325L,0x58b7ca1733534669L, + 0xd7d17d77800b0270L,0x864e3509538b116aL,0xc7eda5dce4797818L }, + { 0xd6c00fbaf741f023L,0x718ed11131d022bcL,0x4586baf2f2ce39efL, + 0x1095729dcd9a09f8L,0xf5ff3f2d7652f5ddL,0x29d95a09dbb72722L } }, + /* 48 << 343 */ + { { 0x7b151b98e28fd10dL,0x8fc01ce81dd884cfL,0x1f0ffb5098d56c2cL, + 0xf9df1fa2b084606dL,0xf86232bfdc7d2008L,0xeae5cb8fd8751699L }, + { 0x70f0229883ed54fdL,0xb575283a86087697L,0xad2191350302e2c3L, + 0x1c09a0d6c4b57e01L,0x0f65e1e1c541b9fbL,0x85493d9bf4fe76c0L } }, + /* 49 << 343 */ + { { 0xecf595d6bc19db89L,0x32cdf31bd607e09bL,0xfaf93c636217e9faL, + 0xa9a1619884d37c72L,0xa2688a33bd929e8eL,0x2ce3442e2842b31bL }, + { 0x906ac09ab37184daL,0x93a1a54492587ea0L,0x1acfab1ec5b4ce7eL, + 0xd4788cac7131e80bL,0xb463d67bc8cf0e18L,0xa754ffb81f24067fL } }, + /* 50 << 343 */ + { { 0x634f8d6db04ea518L,0xe8c424b4c60108a7L,0x3553b6d11ef6f4bdL, + 0x1fe850dfbc0a8e1cL,0xa077055473a66e4aL,0x5417bd50da985b55L }, + { 0x3f99edcaed53259aL,0xd243f2d1b3d5ae6cL,0x70f404b8cb49e74eL, + 0xf6893edc51fec8f0L,0x3f3ac23871521335L,0x127c055436e39048L } }, + /* 51 << 343 */ + { { 0x459a96595ab6a5b5L,0x14ec172bb5ac2238L,0xe556f7061642ba57L, + 0xe18d92d2da35bad6L,0xe64f9bcdd5805c1fL,0xabb4e0243b297094L }, + { 0x95429e14b8b876f3L,0x27961a7d9c04bad0L,0x81c74cf57fa32b6aL, + 0xb035259ebb0f1f24L,0x828c42da2e773f8bL,0x06c996366ea73c24L } }, + /* 52 << 343 */ + { { 0x353718ce191c21ccL,0x08e6edf64ad6bd18L,0xc2bb0d6e4dc5b572L, + 0x328e19df88193daaL,0xccc9f6ab7211c958L,0x377d99ef58aae5c5L }, + { 0x40e2ecc91c823442L,0x036d6d528b0d36abL,0x2fe0cd7eda4d0ad3L, + 0xb8fc3c7ffc8af791L,0xdb7e44a42b201b20L,0xa5176004ebcf527dL } }, + /* 53 << 343 */ + { { 0x24d19ca6fed20bb6L,0x0c02db9841d634aeL,0xfb55998930310b8fL, + 0xf9d0818506c00c8bL,0x2b9983fb4742362cL,0x16ae9bfbdce1b6f3L }, + { 0x679057e6a161a419L,0xe1e80fe04db28bbaL,0x2ca0c869f06c9a98L, + 0x7b80c43bc448ffa4L,0x100f205cb7ef73f7L,0x29565a93a938bea7L } }, + /* 54 << 343 */ + { { 0x4d00c613e1e7a831L,0xc90021dc56d9ddf2L,0xbb80b8385286ccccL, + 0x156b05b771f5f09dL,0x120f47f47bc921f7L,0x6ea1715f8a65c50aL }, + { 0xa070c9f695aa8348L,0x96120fe273171f56L,0x10c7d592ebc69e4eL, + 0x73f6ba27c1c7ef52L,0x10f5b9cef8bb536dL,0x8bc82b225ce0220eL } }, + /* 55 << 343 */ + { { 0xac25749af4f3fa3bL,0x2376bcd76f50e4a0L,0x9c68fd1028b2332dL, + 0x130ed4d12130b66bL,0x91842d58038dfc9fL,0x4111e4cbc401a53dL }, + { 0x85532deafb5d9b16L,0x0c5657503025e3b1L,0x1340aa49b6cc0c31L, + 0x1cfdd7d68b7f71a0L,0xee911d7e8b6e548fL,0xcddf07f021456ebdL } }, + /* 56 << 343 */ + { { 0xe19b7576fa5256d2L,0x418d5425db3f8bfdL,0x00424869951a1719L, + 0x2383c7a8533b69b0L,0x166a38e2e67a86fdL,0xa6baa01c5876c435L }, + { 0x574ddc4584a208f5L,0x8cee30b826b18dbbL,0xeced99c1e9f6b30dL, + 0xb638d88da7d34beaL,0xa4836806069adedfL,0x62beb7ee7a07c593L } }, + /* 57 << 343 */ + { { 0xffc89d6de16d63b2L,0x4da3b04f5df40d2fL,0x3437da2ab48706d8L, + 0xc35290a1d677df03L,0xe54fc6567c5b6c8aL,0x84f052ff2c77314eL }, + { 0x59c33a99d968b4eeL,0x2424c5d0facce444L,0x022d7bfbf505307dL, + 0x5372518d00c142ffL,0xcc82d21aeefa787aL,0x3517f3c0473ef630L } }, + /* 58 << 343 */ + { { 0xaf576c307a8a437cL,0x15852131de3f2cc9L,0x96bbff4371759da5L, + 0x106934ec66f5257dL,0x712e7d0ba9cedae6L,0x5b0b876ddabf131bL }, + { 0x1605f3a8b741f94fL,0xe5d961c109305b04L,0x3fb97996346266c6L, + 0xaf4eafc0b3ec7458L,0x0aefa01abcd90b0cL,0x2b7723e3505ea305L } }, + /* 59 << 343 */ + { { 0xe5c6f37b43d12de3L,0xdc34fdad642baf26L,0x89d716d647268e1bL, + 0x50047b391df8d657L,0x40da6352c64470a7L,0x406e3bc97879824eL }, + { 0x9677b4c38b9ecc36L,0xc82bf16fd246788cL,0xbc9fa99cef5dda3dL, + 0x3050febf0e7b676aL,0xfbb1301a53e448afL,0x3239f20267c84d67L } }, + /* 60 << 343 */ + { { 0x5093950b724fb94dL,0x107822718117ff50L,0xdc9e34b59f5961d7L, + 0xfaa2fc012351a33eL,0xb9e0f1d9d5fc462eL,0x276a5b3bdd9c6914L }, + { 0xe6136d1775365ca5L,0x228b77e2a91eed68L,0x5cd6a269411e4770L, + 0xd8857b0e17590390L,0xe7094f3aa0d45fafL,0xe52d11dcf40693e4L } }, + /* 61 << 343 */ + { { 0xc873fdf565a0d2bbL,0x848244dbaa42c6cbL,0xa5d2d766ac50ba78L, + 0xc650cf4343f38ad7L,0x901cf122ea895d06L,0x3ec1b583cbf46321L }, + { 0x863dce6193c3db94L,0x902459202445bb4fL,0xae716052673385dbL, + 0x9266b0bfff830253L,0xd201095844375610L,0x9e008b9712cf8d71L } }, + /* 62 << 343 */ + { { 0x2b1b2a551448e73bL,0xa8486146b5f97da2L,0xcf24d8636c848202L, + 0xa3d6431c5e483407L,0x47a33db852edb78bL,0xb09256a37dad3826L }, + { 0x740222a74dfa2b26L,0x23f43bec2a8ebe04L,0x4081e512a8072f18L, + 0xe53f0d05751ad7e8L,0x100d0a17332361ecL,0x8a2122e9e0c3a152L } }, + /* 63 << 343 */ + { { 0x28be8affe7e6417aL,0x4e18b452d6a30763L,0x73ae410310d0d5f2L, + 0x5151fe80003625caL,0x45ebb636ba7a91ccL,0x50f4b49d994e7e31L }, + { 0x02eaeaa93ebac455L,0x7632c7dac830fb1cL,0x06fe1dde3bb0d765L, + 0x0d2f7623a6789d20L,0xabba46de01a43e9dL,0x2e822e08f27917f9L } }, + /* 64 << 343 */ + { { 0xe96c4aebe5f5b545L,0x10a85a002d4c43b0L,0xf86ad2f632f9151dL, + 0x05daf874302b99e2L,0x4299dbfa14fd3171L,0x27cbedd6812cfc62L }, + { 0x42e61536b8772164L,0x52eecef76a5423efL,0xc34c6c70548fffa3L, + 0x1fbed7777b6db825L,0x850bded44ef2989eL,0x3b8a542c815463eeL } }, + /* 0 << 350 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 350 */ + { { 0x9decf2173079fe2fL,0xc32ec5707c817f6dL,0xd5649ce8aeb36b92L, + 0xab9f77d158fb4dc8L,0x66b11fb6b52d60cfL,0xe217941deaaa4619L }, + { 0xf3522a9a1607c412L,0xea2eba4fc2a3d8c9L,0x267997c625e38722L, + 0xed5047b72d4595eeL,0xaaa41e5f55e5456cL,0x891e3d1278cfc6feL } }, + /* 2 << 350 */ + { { 0xa438634ed7357a51L,0x918f14cd18c04d59L,0x2ab4dedfac40dd56L, + 0x758e95ee4956a5deL,0xfc11e3945113f84dL,0x6d71b6736059f16cL }, + { 0xfd8e2236fb357c3fL,0xd7c8681232dca873L,0x02aeb1538ea13b44L, + 0xde1275d3013d3827L,0x470a7b7e659ca201L,0x862c83c55c77b351L } }, + /* 3 << 350 */ + { { 0xfc9b800f05084cfbL,0x1c4d4510496f23fcL,0xfea0003cc1d08465L, + 0xf0281da09af48a41L,0xa5c0d97144d32eedL,0x2613b73e023a2e31L }, + { 0x455013c87dc8ac1aL,0x581b13195958b3daL,0xd293f2f22290aaeaL, + 0xa068256496f6223bL,0x38fd18fa69410ef6L,0x74eaf35f2b2cf629L } }, + /* 4 << 350 */ + { { 0x281f6e58c7ff5b50L,0xbc67791ecf9cd114L,0xe29fa41afd89abd8L, + 0xfcb0b0b07984feefL,0x0b0928a6d9d20a64L,0x2fd385c46979ccd5L }, + { 0xce9c34c81fbe72e4L,0x69364344aad0135fL,0xd464635250946a5bL, + 0xb09a97c6f39f53b9L,0x1d47bc20dcbc8b64L,0xcda5c7bdd458b0d6L } }, + /* 5 << 350 */ + { { 0xad5b8c2887eff3b3L,0xa8a3917d9937833aL,0xbafdc493200c3b49L, + 0x9e27aac5972c6fbfL,0xfd292bb20518c97dL,0xa62126db33515a63L }, + { 0x9892a8bb1bcfc875L,0x93b066b7e0b674d1L,0xcde9b0087fd3d080L, + 0x1e285a8859401ae8L,0x4679e32982cfea96L,0x52406ea023e615d3L } }, + /* 6 << 350 */ + { { 0x27de61138b6e9462L,0xb8ade1dc473464bfL,0x911ad49394dacc08L, + 0xd036f28e44252cb1L,0x3865abf6d13dc20dL,0xcea487cdd528f0baL }, + { 0x14d77eaf4fc290feL,0x5106533bc5084101L,0x11001dc7cda9eccdL, + 0xb79ad4bc49fc4a78L,0x4f6369f54567f8a9L,0x64050aa2df7ab817L } }, + /* 7 << 350 */ + { { 0xffe057aade07f615L,0xf3f91b55342700bdL,0x294761e127a839f9L, + 0x6411a2b480eafe1cL,0x4900eb120737b80aL,0xa1134d10bb73264cL }, + { 0x0ebfad730ddbf7f1L,0x57bbe692cd1f73ecL,0x675931fca20f8944L, + 0x1950eefffad2ad19L,0x60d304029cdf88a0L,0x121af89e33fd2c6eL } }, + /* 8 << 350 */ + { { 0x763e3664295c4db2L,0x632fd676dbbaa92dL,0x62ab11a8c66b40e9L, + 0x06244698f384b708L,0xe7cdf3bd69197876L,0x9cc79c48064f8837L }, + { 0x95900a229486589eL,0x7953f6e72ff01639L,0x3f65fbbddd3e6e46L, + 0x84f52e06baa2e2a0L,0x1dc462a8e3852824L,0x9be69c3f7e4c032cL } }, + /* 9 << 350 */ + { { 0xa40afc3670977e01L,0x965f110da6c3b289L,0xc4952f87805a8491L, + 0xb36804b80b65e2d3L,0xd3f6f5ace8cf2b2bL,0x0f37a79da4b71938L }, + { 0xb2f810d9489ef671L,0x1feae0262df23cd8L,0x7412eee321a14e4fL, + 0x1458b8ad179d51faL,0x2156a90ee201509cL,0x39f29fca72605867L } }, + /* 10 << 350 */ + { { 0x231f70adb2e066e3L,0xf09db880bb477a19L,0xdfa0e503907e5c63L, + 0x12fe09f4f97022adL,0xdbf06f3620bce7ddL,0x0140e197f1371cbaL }, + { 0x917b6da464b0b4b0L,0x9a6f4d9b20fe3320L,0x0981d60ed66bdf87L, + 0xb430e4e062d3487cL,0xc3440fb934dc4a94L,0xe7972dda09a5e3c9L } }, + /* 11 << 350 */ + { { 0x29d6394093f47052L,0xadf04e70847e5937L,0xa0ef4fee731bab6fL, + 0x21de31956ee7d7bdL,0x99af4a8dbd716777L,0x9e15c983df4c569eL }, + { 0x2ec7bc0ce94401eaL,0xda1835ad85727722L,0x2b5862ce5dad81daL, + 0xb2be508188dddc2eL,0xa02482101414286bL,0xc52c436d8ea33f3fL } }, + /* 12 << 350 */ + { { 0xcc580ea73b24e776L,0x0f3a8b189d721d6eL,0x8665604fb23480cfL, + 0x95787cba34414689L,0x425d7c6f4d10a945L,0xb5ec2626b2f1cc78L }, + { 0x55da88858658de6bL,0xb50919d1e9aba03eL,0xc64881d7d99e417eL, + 0x1eeba5aabf28fba2L,0x20feb7b3504eff80L,0x9f5f9db650debfb7L } }, + /* 13 << 350 */ + { { 0x4eb94584230923dbL,0xba8611287b3a6929L,0x5aa7faa3ab1d6b31L, + 0x95c1e23916ae0966L,0x98674fd3a2fe2297L,0xa8da0ee53c42d488L }, + { 0x103cabace0740db0L,0xf0b860d45bf16882L,0x03cb0cdc289e48ceL, + 0x3c15d3759e52c7d5L,0x524f731998103ca2L,0x828ed65cc609ffebL } }, + /* 14 << 350 */ + { { 0x518f231b83dfb993L,0x4b0987db37c0826cL,0x0c34961cd5177eadL, + 0x9d882d3e452c92daL,0xbfeaf5588765bcedL,0x83957b62b9962295L }, + { 0x2d1d01757bb084cfL,0x04c4cfcde8cffcfcL,0x2f35e33d8d4536c1L, + 0xbebb31cbd83124cfL,0xe342bed2abb29019L,0x2af0fcde2692a0d3L } }, + /* 15 << 350 */ + { { 0xece5d865c7e3b29fL,0xe58106a4622839ddL,0xf5272d43f2969d76L, + 0x90c72c1b2a1a240fL,0x1e2aa0acaf15e14fL,0xfa2f1c7bf1b6b5a0L }, + { 0xfb5d343d880224a5L,0x47b88a84f91881c5L,0x140f5ee9dd142fe7L, + 0x4e76982e24b37c44L,0x6aaf61e9578b482bL,0x01950e22765bc4e2L } }, + /* 16 << 350 */ + { { 0x20ebf79ce8a2e8f0L,0xec040d0daca418a2L,0x016c07e78d630d2aL, + 0x20021d57fa605dcbL,0x6190f3e942d04705L,0x4e000df58974b7e6L }, + { 0x6710da6c5abcedacL,0xf31aa4965f95d37cL,0x192c4b8ba5830899L, + 0x171ab8c4ea7dbcddL,0x715f60818cdf1097L,0x0e0135bf205d10edL } }, + /* 17 << 350 */ + { { 0x070fbbe1687645c4L,0x4dd859c8c7e0261eL,0x749fa1e9fad54b60L, + 0xb35942f483cdc91fL,0xcef26d0018eeb83cL,0x4dddd5787462064fL }, + { 0x0420ed6e703e8740L,0x9087d805c180c7d3L,0x93807412828424f2L, + 0x8bcea69a6dcae236L,0x22aed9a2d1973c78L,0xe3d0f6f83328d690L } }, + /* 18 << 350 */ + { { 0x5ce5bc6da85a13acL,0x868f385c7f1dd71bL,0x15aa63a420c376c6L, + 0x7802fc9e749127dcL,0xfad59f8e67a98935L,0x6bc97b1d60c0fdf3L }, + { 0xd24caa7ebce87ee6L,0x8aa08bc27ba511f8L,0xe5ba94f47ba61c1cL, + 0x9fe9c343364d2d75L,0x8ee0468161273932L,0xab2f0dbe5e8c4861L } }, + /* 19 << 350 */ + { { 0x13239c0a8254ded6L,0x594182e61762f9cdL,0x6326369d480efa21L, + 0x7fee5afd33101382L,0x9e1ea59c4688bc0bL,0x7a3b1b8eae19c17aL }, + { 0xa8f8f8e5777aedf3L,0xe2d018bfc6bbdeacL,0x3625b03b54328db4L, + 0xda7540c8711ab8caL,0x7faa19fc46930a99L,0x61a5d1845b59a973L } }, + /* 20 << 350 */ + { { 0x4a6226f9f7092423L,0xfe6b7a6dec945231L,0xb44e2e60a1193cabL, + 0x2ce6393543dda270L,0x1a9e8a2138d64738L,0x863d151a9d843675L }, + { 0x98a1222ee2b14443L,0xbf8b32712826846fL,0x80475be555508801L, + 0xc39ccd917b38f064L,0xea31304de8e249f5L,0xa3b6891b4d42db74L } }, + /* 21 << 350 */ + { { 0xc0f1627a147e0f32L,0x59fb7f2f5e8822d8L,0x21d8be6371097441L, + 0xa6169f1b855543f5L,0x188c420645102ae3L,0x4c20a136131b674fL }, + { 0x05487c4d15999699L,0x8a82a130e6ba5542L,0x93a2119519ec0de9L, + 0x634d644cc8d0538aL,0xa90c5eeb3b6bbd60L,0xd59105125e4db926L } }, + /* 22 << 350 */ + { { 0x5140a7172119e821L,0xe5a2ca8cbc370a14L,0x0c17ad48a6db3398L, + 0xd7094545ed6fc82aL,0xcf32984dedb976d1L,0xcf04ac16cdf83a9bL }, + { 0x9bbea16b49775502L,0xb4855286452a6f35L,0x45cbc3b7a86f445dL, + 0x5972ec64763f5990L,0x14d0b9c0b780b2f0L,0xb120273456e707feL } }, + /* 23 << 350 */ + { { 0xbf6b76e1e41c43c6L,0x64ea1824db033acdL,0x7fc0399987c9406cL, + 0x9427585a51b371d3L,0x464f3559c9705e0aL,0x6639797ac8cb6ff6L }, + { 0x5104a72e842fbf01L,0x7cabb009fea7af74L,0xe42aa69b19a1db1cL, + 0xca9599a3a6a7ab69L,0xf31e4aaa1a70d770L,0x0fcc7f1b8a5ef098L } }, + /* 24 << 350 */ + { { 0x39a689bc281548baL,0x11aacfca138eabbeL,0xcf33108a8d29457bL, + 0x312612e014ed4b4dL,0xcbb21f345115625fL,0x4e7217de303a363bL }, + { 0xaeb0c8c0d137f67bL,0x4ff84a937bf78dfeL,0x7a022604683b37dcL, + 0xfa4ced77862b0847L,0x5a49bdc136d69390L,0x6d9dff06c0215314L } }, + /* 25 << 350 */ + { { 0xcb116e787b1320bbL,0x6310206258ed15fcL,0x1a7891a082c13108L, + 0x203d73d939eb4c93L,0x0485b8493c78c65aL,0x663897e93c935525L }, + { 0x9b79708088b41afbL,0xbd34d5134f2b649dL,0x0b4c156f62f6b652L, + 0x24125d1d6863dca7L,0x726a8bb2edb6638bL,0x2ec5deaf82aea7a2L } }, + /* 26 << 350 */ + { { 0x9fb22ca52a3706f1L,0x5a265b5279f5203eL,0xc8844f096fcbd426L, + 0x52a165f0ed8a3267L,0xff0b3a00dfdfcac5L,0x80167cf52de9e1c6L }, + { 0x9e9c4391b0b969c7L,0x279440c41e0dabf6L,0xaa535b8f85133e39L, + 0xef61e22234660228L,0x8ea81a41c386528bL,0xd0bb1f6e71a8c66aL } }, + /* 27 << 350 */ + { { 0x75a689bfa67ab0ecL,0x53eaad3e54843363L,0xdb71f81619a3ba98L, + 0x817257fdc244f33dL,0x8181c028c0fb3720L,0xc813c4651cb7bb39L }, + { 0xbc44c1e71b189585L,0xaedef8701eea3a29L,0xcdd828d7ccb5dc90L, + 0xd224f1774fd2e0f1L,0x2a4723b0e78883e6L,0x33bb05473128e260L } }, + /* 28 << 350 */ + { { 0x544874b71477473cL,0x253a455a3907385fL,0xb303afd631411ba1L, + 0x30047aa0466d6415L,0x3a1b676594d4c2deL,0xc265f1912860c7b1L }, + { 0xfe140a73688e7975L,0xf08a652bf37ce7deL,0x6c9f6df9f46f144eL, + 0xf7e7b95bc0defbc4L,0xfbc9a9697824c075L,0x9745d768d7773c39L } }, + /* 29 << 350 */ + { { 0x7170ab4699873dabL,0x765eb89b8952bc0fL,0xbe3fe2c4f78fd020L, + 0xde51f8579f194b70L,0xa625839e7cc68fbbL,0x50e59b49f7105097L }, + { 0x625294f3b82e287dL,0x98daa85288ca9d10L,0xfa0eb790b499d9bfL, + 0xe280de610382dba8L,0x3fd350e0e76a7d70L,0x1e5c2bebece5ba7aL } }, + /* 30 << 350 */ + { { 0x73e187e000ce469bL,0x21dc6268dbd717ceL,0xe9d63224ee564ef2L, + 0xa7553c854c4c444bL,0xdd409398f6a9b713L,0x902c9cff72f94d6fL }, + { 0x944edb33f50a36eaL,0xa48a5ae4cfb65a8aL,0xcb9a83b9ed82fddfL, + 0x9476090c209aa829L,0x66cd0cb1c7e2347bL,0x0f1fe07c86fa005bL } }, + /* 31 << 350 */ + { { 0x7c17a2e0c65e52b9L,0xa987f030615b8325L,0xa39b78aaa3d4dba8L, + 0x738ce26396e96e82L,0x313f7bb7f08f99cdL,0x29571b3cd1a1b7c1L }, + { 0x00c0e66c89ead6e5L,0x231de4ff19b9874dL,0xc9445296a4137755L, + 0x7b95f3ea336ea724L,0x7c0a222c49bfe5a0L,0xa265c41d782f8d4fL } }, + /* 32 << 350 */ + { { 0xd2db4d35c8d2bf7bL,0x52105d0981571d06L,0x447565cc723a57bfL, + 0xd98c3597d8ded62cL,0x0aeac6d9de2f1a9eL,0xd363b0b70a98d3b2L }, + { 0xd9708f0702ad9933L,0x9334677564f5809dL,0x499332cf49cda010L, + 0x546df74a858467e2L,0x8b84a55093748e8eL,0x9e88ef9706f09073L } }, + /* 33 << 350 */ + { { 0x1cdc6b4f673d9c55L,0x4300148a0c11743eL,0x2f924ce4c38b8c99L, + 0x5300ecc925f32459L,0xb9cd815004473c2cL,0xffee15498eebdcabL }, + { 0x42c292d54c537dbcL,0x32f6d8a293a133d0L,0x4da3a50c35dc41a6L, + 0xc16dee6a102f9ea4L,0x69a017a1f00d0bd6L,0x6a95ee1527acbc5eL } }, + /* 34 << 350 */ + { { 0x6c02c17adcb73b47L,0x10073a3454b70b07L,0x417ca218a7fe7a73L, + 0x6f81a38e4ab64b0aL,0x4e25301f8fa7fc44L,0x180f3e1b27d41e1eL }, + { 0x88925649ce1cfbf5L,0xae279fff2eedaeb9L,0xeac9b033eed426cfL, + 0xa8488f8aa1740d49L,0x6f748bc3711b5da7L,0xbb1c46fd23bbe135L } }, + /* 35 << 350 */ + { { 0x6b2f317b9da70c21L,0xebddc2b5c99dc82dL,0xf4a85d4c5c807d1eL, + 0x47a79b298a15ad6eL,0x02afb05befbda553L,0x34f3998e6941a669L }, + { 0xa4a413fb72deac14L,0x2bd9306c1941b899L,0xae023fa5788c1db8L, + 0x38cd6c42e1012bb6L,0x77ae298c13bd860bL,0x6312af9d63bb40cbL } }, + /* 36 << 350 */ + { { 0xbb7742f370fcad48L,0x6dcce7ff57d444acL,0xfc338485b6abc122L, + 0x03c1118caaf9060bL,0x095dc123cb997905L,0x2dfe24453dd9bee4L }, + { 0x9bffbbf9d45cdcdfL,0xc5b50babb4b26fe5L,0xe985754e87d31873L, + 0xb5b007f5a503d2e0L,0xe25c4eb620bb8357L,0xb6f00e50803fa8ddL } }, + /* 37 << 350 */ + { { 0x21cab682b8035f01L,0xec82f6ae301c96c1L,0xf25d6a0c1539a503L, + 0x94180ece1e35b449L,0x13fbc96f1ede3c57L,0xe4a63eac01d8e678L }, + { 0x3d1a745c068c6886L,0x0659d6ff233be378L,0x493d7a6f3244a214L, + 0xfa852b1b772bd953L,0xbf05cc0ce87db547L,0x28f497ccb30aacf9L } }, + /* 38 << 350 */ + { { 0xa92f28b88ea312ecL,0x9c702e953a3b5f1eL,0xf0a2f787583053edL, + 0xf99506f29cb41eceL,0x4c3b00b5c2b5c214L,0x59bb943717b8d5caL }, + { 0x9ccc7869af5e6b94L,0x6eb795a7f340d02cL,0x7fc613c80a09eca5L, + 0xdac14e61d155f16eL,0xda25c7fcccadb39eL,0x160fda8c9c7fe2b3L } }, + /* 39 << 350 */ + { { 0x8aa83310312ee9dcL,0x702ad7bc2af291bfL,0x3940f883ec915c5dL, + 0xdfb7e44f6fe07c64L,0xa7af875c72d09357L,0xb5df04f4f70b766fL }, + { 0x738af1bb96f8b10bL,0xab27b86735563f8eL,0x18fccbec2ebaf570L, + 0x94e9066dc1d7d59dL,0xa1e3518dc63373e4L,0x0722fd0f22d8306fL } }, + /* 40 << 350 */ + { { 0xcd42d2391be93e28L,0x93c11fcae2ea0d1cL,0x8acd0b17345984efL, + 0x3e3feaf350905d0dL,0x4124e89a6f35b49cL,0xafdd8d27a2bae979L }, + { 0xce1e814015ad5661L,0xb0f9296dde281bc6L,0x11e93935c31ea529L, + 0x1c4c3bd7ebb898ffL,0x7cb73fc76ccc32c2L,0x69e5307da3ac9b8bL } }, + /* 41 << 350 */ + { { 0x37bec50c8e5a9a8fL,0x7f0daba5055a1aa3L,0xa56bc577a1c00a74L, + 0x0656b6aeab88258eL,0x2959237fb88f0f0fL,0xffff63bb9ef15ca9L }, + { 0xd9a2909eb94ae6c0L,0x2506a1779b304c76L,0x5658fed3abdf17c8L, + 0x9c95765e0f90cc53L,0x80ffd7b38e74dc97L,0x97e032e6b8c73479L } }, + /* 42 << 350 */ + { { 0x7073ada11780b0c7L,0x6d4ce321f35f07d8L,0x27b26ee589f35e5fL, + 0x5af10ecd324349d4L,0xf9a0a9071b9bd956L,0x5dde968571350ba0L }, + { 0x678158f5b6400a5eL,0x93764a022842e0deL,0x71a17724057c9ff8L, + 0x04c4313c72f58c63L,0x07fdf15cc4e81260L,0xd6c25e82a509f1acL } }, + /* 43 << 350 */ + { { 0x4f8a719ae3cf3138L,0x7aac7f0d9b1a2e30L,0x3fe8dcb88c0c76d0L, + 0x34afed4ade0b5be0L,0x824e043cfdf7c28eL,0x5b700afce708e71bL }, + { 0x6c7fa728eeffc50dL,0x2488eee97ca62450L,0x25490cb59d969f4eL, + 0x8bbbac3d8bd629aeL,0x7e5213b56e75e171L,0x1385bff25324b23bL } }, + /* 44 << 350 */ + { { 0x364e7371c7d996d5L,0x053390bf8cc483aaL,0x69c23cf281e948d1L, + 0x65e45d618e822ec6L,0x9240ee412ed94568L,0xe0f33912510a84cbL }, + { 0xad42eb0f6ecabdadL,0xb35afdb4bc7e39f6L,0x4ee63cb10cb50316L, + 0x7ccfa14a2a27dc3fL,0x584328f0b4141347L,0x361b2614a23cd89fL } }, + /* 45 << 350 */ + { { 0xe70edc42ee93ec36L,0xec773e52bccc99efL,0x9b0367a0ce0816e2L, + 0x43baad458c6757e4L,0x5d25fa821fb7b01aL,0x65913e86bb6bc3fbL }, + { 0xb1f1fcab67fafef2L,0xe5ffd89c9e9261cbL,0x86f7b89ff29bb205L, + 0xa76ed6722db408b5L,0xd6f1ce5cf83f53a5L,0x9cb5cd26c2882d51L } }, + /* 46 << 350 */ + { { 0x03f6ca364b2582d0L,0x70345ae80f8116e4L,0xc2612cbfc562aba3L, + 0x9cdd127789898142L,0xea7f202c02d762ccL,0xa00c15da33662a74L }, + { 0xcb5cc621aa430b63L,0x6dd1482fb1550d67L,0xb27e7df46216f063L, + 0xfffe57408f49403aL,0x9403206cfc2bc9f9L,0x132504014593a578L } }, + /* 47 << 350 */ + { { 0x6b9c67e6076b2d5bL,0x54509f61883d31d1L,0x25905831fe051be5L, + 0xe6633c1be93608f5L,0x284afa7697480e6aL,0xb124e6063a06cc65L }, + { 0xcbcb2c2e2c608edaL,0x07a39d8f813795a2L,0xf27742a8bd108bbeL, + 0x7425519005b4e5b6L,0xa27620b2b0145a3bL,0x6e3d1210c0f42782L } }, + /* 48 << 350 */ + { { 0x0eeb9dc702ed3c24L,0xe7cb624dfb39fc44L,0xded105f581d4cceeL, + 0xaa675d0c46465cc3L,0x313f4fc99af0a81bL,0xd129819f227e6a72L }, + { 0xaa6b690340b16103L,0x3dba75b2fb4c2fdfL,0xc9feeea1e7c79c2aL, + 0x14f503104e024e75L,0x3704aaa8b5729449L,0x39ac6b0c24b86accL } }, + /* 49 << 350 */ + { { 0x7e25860735214575L,0x3baa75cb068c68c2L,0x93b6a33f10be8d33L, + 0xa88f3cc11ba06b10L,0xe70e7ec2a4f8fe72L,0x32fed39fd4835710L }, + { 0x16137edf3e6059b5L,0x57b1bb9fbb064775L,0x68d3f26dac98cfccL, + 0x89339bce7f9fd53fL,0x15b32212825e946fL,0x55b0a89bf92a0ef1L } }, + /* 50 << 350 */ + { { 0xf419d9becd3eed01L,0x851b31659851492fL,0xa9ac81a9c9b0a402L, + 0xf67bdf20122c09acL,0x9b26b131f442a030L,0xf7a548f517e72d1bL }, + { 0x9e0dbf852a7f505eL,0xaa8e7348c7e93ff2L,0x4efa7877134d8017L, + 0x48f476fc13e5fb0eL,0x552d0447154f4040L,0x8d5b166569b18f6aL } }, + /* 51 << 350 */ + { { 0x65ef443e63c90cfcL,0x3a0dfb8194ed3ad4L,0x75570ba710b5547dL, + 0x5e161fa498e84064L,0xf55dc5003c576f89L,0xe46bd28c7f530eabL }, + { 0x367607400109f9c1L,0xde7a997bb15e9598L,0x25386f307593c3d7L, + 0x680e3639def120b7L,0x43fab687aa6e213eL,0xce48861daa99cf3bL } }, + /* 52 << 350 */ + { { 0x93c2cf3e53ead820L,0xfca3b3564f4444e1L,0xeb6d82bfaac7a37dL, + 0x9c0915d4cf49947cL,0x771f9f7cc7edadaaL,0x51418e487b2df679L }, + { 0xad1b249173f28cf8L,0x8fe4fb7baecacd2aL,0x539764bdb20d0b77L, + 0xb0073685a6a4f808L,0x4c6f5602cf909196L,0x1ae89342d45e9e7dL } }, + /* 53 << 350 */ + { { 0xcf8aa4e5f007985eL,0x833ea882c325d2dfL,0xc1cbaaf5f9f326e8L, + 0xe779a4a9bf906c20L,0x29f475bbc923cf15L,0x6598d52a54055b74L }, + { 0x1001a5f1e4fbd4f9L,0xb4933d56cc74cc71L,0x45c04a50fed802baL, + 0xda140558052bd04cL,0x71c127d63dfbd563L,0xef2b85ba42ebaafcL } }, + /* 54 << 350 */ + { { 0x76569e44bc325891L,0x8f8a1487fa2604afL,0x07a8bacdbc90be04L, + 0xeb53b1087b2c9bb7L,0xcfdc78aaad3c7943L,0xd74807da3bfcd779L }, + { 0x642552417189257eL,0x28138e8d23cb9584L,0x0ce0b331476b888dL, + 0x6d9ceaa0f2a9bbe5L,0xb4f1185653b872efL,0xfa9e6fb222d06df6L } }, + /* 55 << 350 */ + { { 0x0d45565ce6eabd52L,0xaca75463f41a4559L,0xc3e4064a846eb291L, + 0x22ac04bc8613d2f2L,0x74cf6fac2364ce2cL,0x61bbaca8be4fce3cL }, + { 0x302e8117b24dc7b4L,0xa72ae24dd89a053fL,0x75b2023967de96e1L, + 0xbe51cfd2a9e6d1bdL,0x807a8e3d07c9259dL,0xcf3cd92e43cf6384L } }, + /* 56 << 350 */ + { { 0xc040412c754b8669L,0xbda7e0cde2c1d3b4L,0x2ac3b3d5ba29b9beL, + 0x98a415e3f63bf3abL,0x25aee93ed1776a16L,0x46db7347ec3bc968L }, + { 0x8e44180a02612d2bL,0x4e3dc4e82db990ffL,0x2050f58f5f7705dfL, + 0x7b41f5892672d845L,0xeb301603c96e4fecL,0x66ecd24e6cb16a6eL } }, + /* 57 << 350 */ + { { 0xd428e7e3d01edc1fL,0xef608062873fadf8L,0x05e7c80d5606965eL, + 0xb818d0c6a979f826L,0xe9b4c5c7c4793537L,0x7ef637225e83bb66L }, + { 0x825d89499fbb3a85L,0x557abf0396e34cabL,0xfc3db05b8040ad0cL, + 0xbdc8e907e305204eL,0xdfc1628d1c1637e1L,0x10841d2a947a78deL } }, + /* 58 << 350 */ + { { 0x99432df309c7b138L,0x288eef14593b1fc1L,0xf47f9fb21b55f0b4L, + 0x5cc20dd46788b9a5L,0x2e87fb4605e43a77L,0x08cf86be849c700aL }, + { 0x467ec61374680ce7L,0x44e5c8d45884aff8L,0x549f2ea86b33a1a9L, + 0x2ebf696a8b4a815dL,0xc1705b152a74323aL,0x930a9fde69745934L } }, + /* 59 << 350 */ + { { 0xbb11fe102d168ee9L,0xba4aea667f39e124L,0x139364b6fca2841fL, + 0x6feef5b13d359df1L,0x4fe89fe19787be92L,0xd4cea92e0f6b6aa9L }, + { 0x794006c0039bd8f5L,0xdce0eb5b0be647abL,0xf4a97f7d4e40c1d3L, + 0x78d19059d5f7254eL,0x464ddc1d0df22d8bL,0x990b0a39e0fc7628L } }, + /* 60 << 350 */ + { { 0x72f5a0f70ad3bb67L,0xabb15e3dce6396d8L,0x2ae94788463efba7L, + 0xe77b53b41fd4c512L,0x09921a1ca88606cdL,0x1b86b75608e980eaL }, + { 0x2def667af3d22731L,0xadebd3a39641b175L,0xc0f35509045da920L, + 0x8fbf85e4952b7ca9L,0x4ee7565023517a65L,0xd31eeea30e75a4a4L } }, + /* 61 << 350 */ + { { 0x6d9a5d3cc4508650L,0xe71fcf32d1a2ac1bL,0x784b9148d62ec2dbL, + 0x9a3d5d572088946aL,0xc488178757848c00L,0x2f50a62e0875c1e9L }, + { 0xbd23d4aedec0f2dfL,0xc9c28dd5188dad0eL,0xf87ef6460977ba29L, + 0x89ce8330ab03e4d7L,0x7dbec90dbcf1a5a9L,0x3ddc39c1f6c2a4d4L } }, + /* 62 << 350 */ + { { 0x8c0518c7618b787eL,0x6f226212b95734feL,0x3e6cab90c66e138bL, + 0x6e56d68037a7c0b8L,0x67a3c7df16f6acbbL,0x43df95107921bb92L }, + { 0x967846f6a0887d25L,0xf717017766908fcbL,0x1a8ec350267430d8L, + 0xebb46f1a25855c90L,0x73eb78cb396c1714L,0xf766957cdc081e43L } }, + /* 63 << 350 */ + { { 0x0700da846de27e73L,0xfac9dcfd78c35563L,0x01af330ccd073b09L, + 0x0bf5c3b1bb784ceeL,0xd3d9a9ff5d465498L,0x4836b065bde8bafbL }, + { 0xf5bf3316329b4cf5L,0x387388fc54a5275fL,0x73e880d8254af26eL, + 0x07ebcddc8d05311dL,0xe8b9965a4f46cec2L,0x4f07a4fa01b06069L } }, + /* 64 << 350 */ + { { 0xc0a40cac52133095L,0xfe1b22fd93c162bbL,0x8625898c34018741L, + 0x69c9f3f636d9e57aL,0x69d9d7f3378aa211L,0x6b03f897e7dca168L }, + { 0x24d49aebf997a48fL,0x1d984c67c149ac40L,0x667c1d01576f533fL, + 0x372eee199ef82eceL,0x577723c0c207c14dL,0x4225907a0eed37f6L } }, + /* 0 << 357 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 357 */ + { { 0xc61db977bc0e0903L,0xbaf6e4da645c32fbL,0xce89b8ca060b1adbL, + 0x41db448188e2c178L,0xba6339f3923bdd3cL,0xff25b818d29db42cL }, + { 0x3521116ee6d6b35dL,0x4e1bd283b22f16acL,0x9357c984bd79fe5dL, + 0x2eda73be9d45eee4L,0x1a50c59f6288e01fL,0x37baf64975018873L } }, + /* 2 << 357 */ + { { 0xc552c6c6097f322fL,0xdf59a3028bc06287L,0xc9ed375c19610b0cL, + 0xf0e7b4ebb051dad5L,0x7267a304c6556643L,0x0044f6d8c96dc1d8L }, + { 0xf0ed5f9af4fc3725L,0xbbaf9f2c9de8e1ffL,0xef5d66f4af5a4b4bL, + 0x0b5bed3d20644cf2L,0xf7e4543a75ae23c0L,0x696f60dc41325b66L } }, + /* 3 << 357 */ + { { 0x9949b33d2c20f868L,0xdb3aa790b5706250L,0x88ce71e788e17f2bL, + 0xd851baf2da9c0881L,0xe869c5ba86d8c9e9L,0x1af68d65a01425b6L }, + { 0xeae8b1c69bbd3963L,0xf34900b1ec087425L,0x14942910c374bb96L, + 0x3e13c45705487483L,0xe0e6fad435bc6ee1L,0xc7c38dc7b54d247bL } }, + /* 4 << 357 */ + { { 0x6d34bdf6ab463fa6L,0x7bb127b60093b9cbL,0x61d051135a3bfdd0L, + 0x4abab575f1296bddL,0x72da68494d2e9a7cL,0x90267bca8d11f03dL }, + { 0x478111223e9b310bL,0x8ffe91d31b1920cdL,0xec293ec67521898eL, + 0xf0cf026996c1da75L,0xb0dbd4c380f2c7b3L,0xe528175534e4baf8L } }, + /* 5 << 357 */ + { { 0x7ce1ce36189e2f1bL,0x36ca8fe3fa84ca41L,0x54cc2c13a6a568e4L, + 0x1967d9ed25a6d223L,0xf8d20c88537252afL,0x5a58936cac3d697cL }, + { 0xa2659671b0084ffeL,0x08a9e041ec25bb0eL,0x6bd405ed4074ccedL, + 0xaeebb470dacb5503L,0x6f18e32bd5448d3eL,0x0412973ba94cd45dL } }, + /* 6 << 357 */ + { { 0xd72fcc3742fb1cd7L,0xadfb8967c49c359dL,0x6dc988a55935bb0dL, + 0x3fb10981e3080802L,0x12c4494f3be161ceL,0x5a0e22d44b649dd0L }, + { 0x5c57cbfd62a85259L,0x7ad55b3c0e5ab7a2L,0xcd53564928de30e7L, + 0xce35e6e76867e6a7L,0x626810562f6716fbL,0xd8b4ff26a88d3bf8L } }, + /* 7 << 357 */ + { { 0x5949ddfa53abe7a9L,0x944a2ae0716f63a6L,0x90961922675d1f43L, + 0x36c41c12f5b55722L,0x85b8250f7782775eL,0x89a3a733748663beL }, + { 0xd4358450475d2d88L,0x4183f45e1beef8adL,0xee3bfe8b06ec8d58L, + 0x2e462b1609cc4d82L,0xf9cc307ec6148e1dL,0x70d3b2f77b1281a3L } }, + /* 8 << 357 */ + { { 0xc32730e8dd14d47eL,0xcdc1fd42c0f01e0fL,0x2bacfdbf3f5cd846L, + 0x45f364167272d4ddL,0xdd813a795eb75776L,0xb57885e450997be2L }, + { 0xda054e2bdb8c9829L,0x4161d820aab5a594L,0x4c428f31026116a3L, + 0x372af9a0dcd85e91L,0xfda6e903673adc2dL,0x4526b8aca8db59e6L } }, + /* 9 << 357 */ + { { 0xf0467111e854f886L,0xe228021d8dc6117fL,0x07ff954cac432e28L, + 0x373be2ef31d9b69bL,0xaa214d016fd61f0aL,0x27bb7932f950b029L }, + { 0x1caa914f967c97f0L,0xfb133ec0d548897dL,0x598514173cfad251L, + 0xd41d1da432d14208L,0x446c79f2cee424ceL,0x8b5272a175e839a5L } }, + /* 10 << 357 */ + { { 0x26b5e85d62f50c12L,0x8418cecf5ff562d5L,0x0d35b4d459be698eL, + 0xd79ca9ee93730d2eL,0x2414d99325627fe5L,0xe31dc5293fc64803L }, + { 0x5c9100d60d027a12L,0x9004ee36f2208db5L,0xe734b13b135d02bdL, + 0xf905c01a7bc09b60L,0x4eb51557b21b68fdL,0xe6e98bea8c583359L } }, + /* 11 << 357 */ + { { 0x14dbcf1a61dae7e6L,0x559a7b52ea0da075L,0x7391545d439d10d6L, + 0x187e00e675e617abL,0x453b546b5142355dL,0x9bdbddbc84bca97aL }, + { 0x742a699591e5035dL,0xcf86d3e1831209ddL,0x6fb66757f5f2a999L, + 0x2e360aeff0e71f2dL,0x6c6f71f2dc97114aL,0xef686b8b17c3a3dcL } }, + /* 12 << 357 */ + { { 0x7d07a61d13b5ea74L,0x7f4b7157c8afecd9L,0xefce9c89820b0298L, + 0xe85c4510e3888d59L,0x9cd3352001234b9cL,0xba2692c0fef767e8L }, + { 0xd2bea3d45b3ca353L,0x9ad478e5b51a704aL,0x1fc9bd0d9426f25bL, + 0x52f930bf864a1ba4L,0x559f36353765ff27L,0x548c7f0dae28479fL } }, + /* 13 << 357 */ + { { 0x6296d54f68b0df62L,0xace420ee9e6afdd4L,0xa20a510dfcd1812fL, + 0x488f113a8cd04a29L,0x1bee07640765cb70L,0x50bb5c446d0f44e5L }, + { 0x5ea842cb7e320ebfL,0xa6e0c1e6e795a7fbL,0x89cd1f765e7e79c9L, + 0x7436ec1e87ce6c5dL,0x1376222de28309f9L,0x9ed7d6fb7f01548aL } }, + /* 14 << 357 */ + { { 0x32e9740ae2fb0467L,0x3a7a32b3ec039d67L,0x630d8d346a425a7cL, + 0xc9af74ae418a7dd0L,0xc903576daf502870L,0x7e02b3b7e98cce5dL }, + { 0x0bfdee7a158f005bL,0x88eff4a363b91d59L,0xf23079728bfe3ed3L, + 0xc75536bce6b1fb4cL,0xf61a82e1a04d46fbL,0x771a8fedfddd52a5L } }, + /* 15 << 357 */ + { { 0xf5efc82065af5b94L,0xd618a9e8ce5535a2L,0x70cfb112cda6249cL, + 0x6986f00f9f217280L,0x41e46ce605faa951L,0x2abb39f3a3ad613cL }, + { 0x3e04b28b07671c94L,0x61d323ac53cdaf80L,0x2389875cbb9580f8L, + 0x64800835febb0b34L,0xdaebba99d0d21027L,0x0f1cebfc23288a7fL } }, + /* 16 << 357 */ + { { 0x51a033a5cecb916fL,0x2ac62f638d7de61cL,0x92eece49a42a266eL, + 0x87e037db82c4d11eL,0x875be1416fbae08aL,0xf348fe26c539478cL }, + { 0x51f8b907ff94c01eL,0xc46cc0e019695a9dL,0x2c74bd666c51b9c2L, + 0x635d3d24ee565de8L,0x6bd656638982c8c3L,0x5c345b79daf6a93cL } }, + /* 17 << 357 */ + { { 0xee7265ee93f081dcL,0xe8f90a6be03493f4L,0x4e8d10275328b0b8L, + 0x13bb82bb96fa0930L,0x764c2915d1f7d5a7L,0x1896c78f73476481L }, + { 0xe9a34ff267873b76L,0x8a9a719cfa0afda4L,0xce93d4cc9ccb715aL, + 0x9ba00f011495d1ffL,0x3131e6666df0e119L,0xe68e1815c902ac6bL } }, + /* 18 << 357 */ + { { 0x0ce4ae1044f4a2dbL,0xa8645e2310bcc5c6L,0x6d9728b5e489762fL, + 0xd365c12a9d46ad88L,0xedf484fee1a527aeL,0xfdf5c519e5be2bb1L }, + { 0x4706cc2870a3d4e3L,0x07c60129065f1506L,0x42e2e16478298553L, + 0xa56a2bd5bae646dbL,0x893bf45c61437e62L,0x97dbf9266c525900L } }, + /* 19 << 357 */ + { { 0x65c56764b52213c3L,0xa171ba9d97aefe9aL,0x5904e8c934336916L, + 0x727209b6ff187f05L,0xaf4e50525cb68a5bL,0xb46a6abadc4319feL }, + { 0xfd48d0d57890cd90L,0x5b0b68c7252942daL,0xc41023352b01887bL, + 0x582251eb5ad09a7dL,0xbd79b557e1312726L,0x9f5ee3788057db5cL } }, + /* 20 << 357 */ + { { 0xa30486a6666fdcc5L,0x5cb7f7ce84056f89L,0x0f8a6b96505636a5L, + 0xfeafdf97c6624ce2L,0x9dade91c55b8a7d6L,0x3d009219ca2b459fL }, + { 0x483549845a969337L,0x37d57cbd323c09adL,0x32a91e91e74b9e74L, + 0xdb4f18ff1c317c24L,0xf9f0daf342418667L,0x735a1eb946946667L } }, + /* 21 << 357 */ + { { 0xb395bfd1c8eaa54bL,0x8181d6262ee25219L,0xf4bf437b38d912f1L, + 0xf9f1161228a8b32eL,0xe359adacc2be5c61L,0x71557ea2971b60c9L }, + { 0xf071404b1b00cf1eL,0xb163c3608da3141fL,0xd9dedc07a8d51d98L, + 0x29e89ac5ac827b74L,0xc38cef633ef35dfbL,0x9abd281097d477f1L } }, + /* 22 << 357 */ + { { 0xb34e560f0e6d9646L,0x4fc05a0dc0ba033fL,0xc9f5e040ddc1bcc8L, + 0xf723b78ab92068cbL,0xd558f5912b5c7030L,0xb16bdec774ed778bL }, + { 0xc12aacc3b32980e0L,0x856e90411daaa32cL,0x34f7a28596429db4L, + 0xcc2c61ea415dcd04L,0xa0e192cb46b7d996L,0x5b7c845d55d87ce9L } }, + /* 23 << 357 */ + { { 0x9ba0a26fc0ee684eL,0x1b871ac353573254L,0x76a094bc5783e706L, + 0xe78bea66dcc01e8fL,0x7e20c5aedfb74e56L,0xbdc5314a8710f0e6L }, + { 0x2bcc7a0085f2233aL,0xc58dd45b8aba1575L,0xdd1c6b78e411b6d8L, + 0xbb8d19529d23d2eaL,0x5293f3cc0066c9cbL,0xb7d0d7b0249c6d93L } }, + /* 24 << 357 */ + { { 0x68fe359de23a8472L,0x43eb12bd4ce3c101L,0x0ec652c3fc704935L, + 0x1eeff1f952e4e22dL,0xba6777cb083e3adaL,0xab52d7dc8befc871L }, + { 0x4ede689f497cbd59L,0xc8ae42b927577dd9L,0xe0f080517ab83c27L, + 0x1f3d5f252c8c1f48L,0x57991607af241aacL,0xc4458b0ab8a337e0L } }, + /* 25 << 357 */ + { { 0x614c4bc273041ddfL,0x4fef1cf6364135aaL,0x2c9ac204ecf0e610L, + 0x75a302a991a6dce1L,0xa5899c96651ec9f9L,0x6c5384f64bcad1a6L }, + { 0xa41012e560f705ebL,0xfcf6512235e85d67L,0x2fdcfc235ced3638L, + 0xf834fac02deac34aL,0xf5a64ec510a8ad80L,0x843855e1a412c4feL } }, + /* 26 << 357 */ + { { 0x440dfebd76ca517aL,0x79924057c577eb59L,0xf1aea290d038a921L, + 0x77afb37fb0c95974L,0x48a5b9a715763d44L,0x713de85155c8683eL }, + { 0x250e8f8239d7e1deL,0xc5f1f61c8a2c846bL,0xf26ea6f9faafd017L, + 0x8ad26055f9d7cd35L,0xc980ba773b2df598L,0xe23b7eabd5e299a3L } }, + /* 27 << 357 */ + { { 0x5d37811464744605L,0xfab096990278c1f0L,0xc4d32b208448c344L, + 0x767a24d2d7d1df17L,0x842de148773ea0fdL,0x73d7dfbdff6e40b4L }, + { 0x3d61439283576d1cL,0x4820c435ec865519L,0xf99e84dd6bfa5e48L, + 0xeb18687a9d0d2adcL,0xc3b7369da7fd75d2L,0x7e332b5739f5f093L } }, + /* 28 << 357 */ + { { 0x0796a8b6ec13d2acL,0x19036c255677347dL,0x2f0d36eef527c827L, + 0x7c8a3d17ca61ed60L,0x3920bc68748cf7c2L,0x61835bdf9018b300L }, + { 0x9cf595c1689d5826L,0xdc547999fb51aea5L,0x11bb04120fc297c6L, + 0x88770df2b2f9fe0eL,0x99e031f5f6856a85L,0xbb59e8c7afe29c50L } }, + /* 29 << 357 */ + { { 0x714e784820dfc5f8L,0x35cde8ae2a2265bcL,0xf6b29ce4bfc32fecL, + 0xbd5e91f1918043a5L,0xd3766f8b60f8c218L,0x273c41935298904cL }, + { 0x0a76492d5d441fb5L,0x99cb3b1d164d9275L,0xb2be87c80ac7935eL, + 0xbd1a1b3f0962981bL,0x8a0c207b96d0df2dL,0x1bb1e505929752d9L } }, + /* 30 << 357 */ + { { 0xa574de94621b2705L,0x0d0ca1b73e3f2227L,0xbdc9ddf2e49bc2d8L, + 0xfbc7254309d314f0L,0xf5900cbb827e0b1dL,0x3994eadd8a7e8164L }, + { 0x2e7949793046f170L,0xde21ddc3c6883cc6L,0x9ea19d34bcd40da7L, + 0xb4334df8f01a9ae5L,0x801496ebce8c53c7L,0xc2a5e8527a4b0601L } }, + /* 31 << 357 */ + { { 0x435a6c512ecf62d2L,0x757cd8f6559a6a0cL,0x47833f815e4c0d40L, + 0x2d0b48047d960c6aL,0xf5474833473d5eb3L,0x70264154bf756b52L }, + { 0xcc46e58d940bfb7cL,0x2e0dd3a69c89d48aL,0x483f3ee19387df66L, + 0xb3097da4585d3600L,0x82d64b4d76411ef9L,0x0df7d95719682e87L } }, + /* 32 << 357 */ + { { 0x179c59cf210c3144L,0xfb613c5733eebbc4L,0xdda75cfdba0cf384L, + 0x94081a5b3a8fbafaL,0xb91de90a33384e0bL,0x7d1f8f4027aa2a45L }, + { 0x0747bcc162031148L,0xd2db8e39f324160bL,0x9c1ce3e9722484f0L, + 0x13a7ee5da62d1ddaL,0x77fd79343a963bceL,0xcd3d871783d2f21bL } }, + /* 33 << 357 */ + { { 0xc7c8eedc93a27196L,0x0832b0dfa8abe585L,0x31fe11e8d8adfb86L, + 0x1091601e9d50e4c7L,0x7931a284ac3d2ca4L,0x0f1464b6f3fc6641L }, + { 0x2ead94f3260f29a7L,0x914b8396d88a7696L,0x950be4bbe73d807dL, + 0x26d0115e5b3ad83dL,0x3de8a73146c22525L,0xe50825dac5fffff1L } }, + /* 34 << 357 */ + { { 0x716378cae4b98aa8L,0xacf8d67b59b746a9L,0x78f0b5eca65ce8ebL, + 0xe5997983523cfa35L,0x85bf5badbeba89e3L,0xc8052bbfcfd73b41L }, + { 0x0b3d77139fb311a3L,0x821a20e2d96f696fL,0x0f087e5744657c9aL, + 0x72031f281ecfea36L,0xd0765f333f32b010L,0x0412c69929c48643L } }, + /* 35 << 357 */ + { { 0x53d361b89f501481L,0x8970937717153c6fL,0xb52280b916bb8d8cL, + 0x5985cdc0b33dabd6L,0x35ba0cd9dca8ae72L,0xf55c6e7301bc4efdL }, + { 0x2106ed2f269577c4L,0x4cc34291bfe765b4L,0x9f4168ea812eb958L, + 0x02869228999ba5cdL,0xff91540d3ab27498L,0x9020e6e158e55a79L } }, + /* 36 << 357 */ + { { 0x1a5b15377f1c7cbdL,0x5b31930b7cc17c56L,0x5b91e1a492cc8cf5L, + 0x970e43deeca08bdeL,0x36424bfe0e2e963bL,0x2e49534968b1a489L }, + { 0xe350ca52d8e85a9aL,0x3cb9f599ae2cdd7cL,0x0ff35a0aa83215ecL, + 0x64cf57b81973a966L,0x128be6cd36b26702L,0x8067afbd5f65f7bdL } }, + /* 37 << 357 */ + { { 0x23d1f49215876c71L,0xafb21c1d41e7495bL,0xdb3ab62c2705885dL, + 0x20ff803f7ba216cdL,0x26cb190699c9ee55L,0x8280dc9c0fb05389L }, + { 0xadf55171df1020dfL,0xc044e9bcbd011b5cL,0xe21aaa60cbed2430L, + 0x5939fe583336df4dL,0xfa306816ff78c665L,0xba92ca8243eb18f2L } }, + /* 38 << 357 */ + { { 0x6f05e6241b7edb64L,0xc280105b6681f48fL,0xd1b94413f993dc9eL, + 0x84f24c01e46de412L,0x092017d54abbf7dbL,0xb73193a56f7b1b08L }, + { 0x22a7c5765195ae46L,0x81dd6b12610c28efL,0x61959874ad7bfcc1L, + 0x3ade0a77d15f8cf9L,0x124cef4d954db624L,0x0733bd7a5c247650L } }, + /* 39 << 357 */ + { { 0x52d7f9ddf1cee098L,0x538b7fa17a6a2ad1L,0x5f2294312911e75aL, + 0x71c337b7e6ef0271L,0x5e278a1267ee72d1L,0x7b348c756f33fea9L }, + { 0x7bb59f1a694bb928L,0x5783e43f292b258aL,0xe3b53ca77181f1d2L, + 0x028ba90e051c7d2eL,0x4bb06f9364789d76L,0xcf97fc4da228a7a7L } }, + /* 40 << 357 */ + { { 0x3dbb3fa651dd1ba9L,0xe53c1c4d545e960bL,0x35ac6574793ce803L, + 0xb2697dc783dbce4fL,0xe35c5bf2e13cf6b0L,0x35034280b0c4a164L }, + { 0xaa490908d9c0d3c1L,0x2cce614dcb4d2e90L,0xf646e96c54d504e4L, + 0xd74e7541b73310a3L,0xead7159618bde5daL,0x96e7f4a8aa09aef7L } }, + /* 41 << 357 */ + { { 0xdf5c2fa79111caacL,0x493ada25b04d2b3aL,0x5c4850bfa39a7872L, + 0xbeae16c067e07e93L,0x63bd7d390178358dL,0x7a7e56a1cfe0bcd0L }, + { 0x9ba7a4500816b666L,0xea6c70c8dae070dfL,0x84013756832c2b35L, + 0xa28e5dd08d3e9fc3L,0xd67665aac653c08fL,0xee54d7b6aa6bdff8L } }, + /* 42 << 357 */ + { { 0x99b870afadbd24baL,0xb34fa9083bee289fL,0x4a20f29bae836fa4L, + 0x4188ed5024b464c3L,0xfb93f48fc6c00297L,0x334b8689736186ecL }, + { 0xbf7f1c424e1016f1L,0xf95e6e59413ca088L,0x5878156c288912d8L, + 0x9e99199704c7ce69L,0x0f0c185d5d6520d1L,0x1ed2ece33fe6f498L } }, + /* 43 << 357 */ + { { 0x319fb249607cfd40L,0x5920056f62b40e28L,0x9ab4528058631ab5L, + 0xb527738f413452d2L,0xb2885e46b296e602L,0xb1dcf41a74824807L }, + { 0xca9d2b06b2ad2fc6L,0x500c5f11ad05eeceL,0xca94160f21f3db6aL, + 0x693adf4e262470d6L,0x1f4c62c5480b0cffL,0xb3ebf11f54c748e4L } }, + /* 44 << 357 */ + { { 0xc8ae4d2bb4ef93b3L,0x4967da7b99758d99L,0xd1483a1fe04db9baL, + 0xf5e657df3033474dL,0xdd9371c89db4b96fL,0xb5f288956044b259L }, + { 0xe8987a43b2ec27bdL,0xaabb1ae68fce67bcL,0x4518fa3eb2b97680L, + 0xa0142a13748591e1L,0xf9148ab96c2db557L,0x65592253e0e4f9e7L } }, + /* 45 << 357 */ + { { 0x21163809bccf41d8L,0x0eafed515b3f09d1L,0x3b5360d9d84b27f6L, + 0xee752fd04411d37aL,0x1cea3b5c6a3f5027L,0xb206e74d9454d9f6L }, + { 0x710715dab52af43dL,0x8175ca136e6c6463L,0xbdb123d39689144dL, + 0x569e6edd4d9c459fL,0x070f09a4f02e5b25L,0x691c23ef3d79a7b9L } }, + /* 46 << 357 */ + { { 0xc0c94165781356cbL,0xcb9fb705876a839bL,0xfe23f07e89db25feL, + 0x710f0fa3a52cec3bL,0xb0ab363073e0f037L,0x3b79a8167c9aa037L }, + { 0xdbc7f83ca1f13fe1L,0x8bd910c63d653a81L,0x2e54ad408c78d003L, + 0x0de02157a3e9ccf0L,0xe9081e8bf7670dfbL,0x6a2ad476c8647bc8L } }, + /* 47 << 357 */ + { { 0xaf58106ebf047836L,0xadc3245e195e5675L,0x75612e175290e051L, + 0x27b81bd869d46bb9L,0x9d4dad5b5417b5faL,0x19850d70fd024259L }, + { 0x987daa604b0a86b5L,0x5d5a5f9c0358a944L,0x9008682f48d2ff67L, + 0xc9db4d4b89e81cf9L,0x133516bc850eaae4L,0x0b5bfdc81da8bd19L } }, + /* 48 << 357 */ + { { 0x609deb162d8bcd6eL,0xe42f23a92591750dL,0x4a9f3132b378305cL, + 0xf101799869275f5eL,0x14be746761b089b5L,0x05f620d20c81b0c5L }, + { 0xca90a9c06cb8412eL,0xfe0f6a8915b1b0d5L,0x1b25ac9620c71988L, + 0xb971b61a390aedd0L,0x995214d779d8cd39L,0xd7fa135b65c6e11aL } }, + /* 49 << 357 */ + { { 0x5aaa98f875330325L,0xc900a7781f3541a6L,0x69bcf864174a3200L, + 0x3abc5ef71c46b3e2L,0xa53c9e4e47851b97L,0xc166a4e22acdc42eL }, + { 0x49e4e6fdb19b4678L,0x4fe02cb162b7da19L,0x575c61a6633153feL, + 0x49578b28a4f83b70L,0xc6840d063737532cL,0x93047d40480f55b9L } }, + /* 50 << 357 */ + { { 0x835be7417d930332L,0xa4d001bb2cd86fc4L,0xef141e30a6e3a24dL, + 0x4047620adc328d2eL,0x5c80a3bc9a5f1f12L,0x6cde5e4ca19b423cL }, + { 0xcdd5d7773ba0fa5cL,0xb96dbe62ea85c28eL,0x963c02245c804896L, + 0xb2a581abe5dd6b98L,0x28a908a2abc8dac4L,0x5834b212985fd18fL } }, + /* 51 << 357 */ + { { 0x02757b1f0fbe0c5dL,0x2d0d05a854ef99e2L,0x2bda526d0377ffa0L, + 0x58ca8b08925985afL,0x1fb7dbe727b69722L,0x322d7db5f1c57fe5L }, + { 0x4049c8bcfdf111f3L,0x0b4712974148b027L,0x34fcb1e58782dab0L, + 0x697dc9431665557cL,0x3ae30e2844659ba2L,0x479dbc2f118e7417L } }, + /* 52 << 357 */ + { { 0x10b10d86227e8607L,0xe83536281d1be36aL,0xe34068f9d952b0e9L, + 0x148eeb38fdb6ea99L,0x82657d605547e7ebL,0x9c35dc82a86155eeL }, + { 0x408f79262060a81aL,0xf2a79205a6282e8aL,0x10dbb58526e70e7cL, + 0xd636f8225df85d6cL,0x03202c027682b922L,0x31323940baf18500L } }, + /* 53 << 357 */ + { { 0x5882374401879796L,0x068943ccd1249281L,0x20dec1c12e1d6effL, + 0x5f4c2c070bdddecdL,0xc56d52b37ee724c3L,0x93bc2c7a559e25ddL }, + { 0x0c95d2e5f98a9940L,0xc570e96ada60a809L,0x94c4a964076233eeL, + 0x843c99627dbbc526L,0xe4075129d4cdc652L,0x0afff70561cb2698L } }, + /* 54 << 357 */ + { { 0x3ec1e3a5f607f893L,0xd476dd24054aaa8cL,0x2cb92280a93488abL, + 0xc8d1207710d1dc68L,0x564839b9bfb494e6L,0x7a13930ceabdfe56L }, + { 0x52f72a9724f9b183L,0x30ae4bc87e9c6fc3L,0x3d7d2765f35b8e6cL, + 0x701f3d89a665ba55L,0x98f2fe85c466111bL,0x338073600c1c0dadL } }, + /* 55 << 357 */ + { { 0x7dd106bab3a48d42L,0x7eac4690ebfc75aeL,0xdbf3547e68ef4ea3L, + 0x3629c438a1a5faa2L,0xac2aa55e653bfd97L,0xae5cc39752c3b8f9L }, + { 0x117380552853b626L,0xd5a955f224a0dfe2L,0xc4356ca25940233eL, + 0x73f7eda97994aedfL,0x2bfa76c693b185d9L,0x091cef91a0327108L } }, + /* 56 << 357 */ + { { 0xa8393a245d6e5f48L,0x2c8d7ea2f9175ce8L,0xd8824e0255a20268L, + 0x9dd9a272a446bcc6L,0xc929cded5351499bL,0xea5ad9eccfe76535L }, + { 0x26f3d7d9dc32d001L,0x51c3be8343eb9689L,0x91fdcc06759e6ddbL, + 0xac2e1904e302b891L,0xad25c645c207e1f7L,0x28a70f0dab3deb4aL } }, + /* 57 << 357 */ + { { 0xf5dafec85f102704L,0x2f3b6b6929f5b946L,0x84472c029d4c9979L, + 0xed49f3e6341f0150L,0x3ee3432eb3bb085fL,0x84c553183cbac42eL }, + { 0xbb358bd9dc4c7ffaL,0x0713917d2db356ccL,0xc73e9fd0670c7139L, + 0x87600c4c3581108eL,0x2ae731d7586af51dL,0x30630ad6614c126eL } }, + /* 58 << 357 */ + { { 0x15f8fba7712c0edfL,0x4a1f93baa2c363ceL,0xfabca37e8f2948a4L, + 0x652922e4dd765560L,0x2da78559220cb98bL,0xb797746a54b940c4L }, + { 0x8535fcfc591bb7faL,0x58857815c25376e3L,0xcd8db789da627557L, + 0x718072ca318512b7L,0x92266469813efd94L,0x3217649aafa85382L } }, + /* 59 << 357 */ + { { 0xd517b39e51c4bf28L,0x6614c16261f583a3L,0x79c72f414739ea59L, + 0x597e1c2ff76e80f8L,0x3a72b05e7b846f3aL,0x1849e5126c0a45a2L }, + { 0x79a6ea5b9d506d83L,0xc48e570219b7f46eL,0xc89c5047c524bb48L, + 0xafc1fdd99cb88cfdL,0xb07eaaa0b82056e6L,0x60f6544f05885df8L } }, + /* 60 << 357 */ + { { 0x9894ef75f39e2738L,0xac585d07b40db6ecL,0x07d9e938c4cfdb92L, + 0xda174933737f1a7fL,0xa4f1fb65484031a6L,0xa96d9f612c21b546L }, + { 0xaf981519d24ccee0L,0x238de6de9d53b571L,0x09afc481fd78c3ffL, + 0x4351715d9ea7f6fbL,0x91a02325b14a7320L,0xcd8958d8bbb6346aL } }, + /* 61 << 357 */ + { { 0x22ef4217452ae6a0L,0x3192309d9ced837aL,0x773585ed2ba43ee9L, + 0xa9b29d94f3379e81L,0x43838b3aa6835e44L,0x1afe27ab0c7b2336L }, + { 0xca1dc61683ecd230L,0xc9e8b95e6d235df5L,0x9667829b2af11adeL, + 0x27254b0fbe532148L,0xb50bc3c86d233f14L,0x30e0e450bb35d985L } }, + /* 62 << 357 */ + { { 0x8b3f79087b95cf32L,0x67c654b06272c619L,0x61160a9d22c0f46eL, + 0x1cce95721d2e36ccL,0x62bd951d3990db3cL,0xcf0005c8d9700d14L }, + { 0x304aff9c70116120L,0x1c919dd2b08d57ceL,0x841b058ec0c0c0b0L, + 0x7cfd4deb7af05aa2L,0x4fbd13c57b11ce5bL,0x03e07dc9f8259bebL } }, + /* 63 << 357 */ + { { 0xe9b37f569d0703e0L,0x7b5e0df5f83c215bL,0x7fbb40f0d3c21efcL, + 0x87a2ff119fb33620L,0x208b062bd1176635L,0x806bc549950d30efL }, + { 0x862de3a4ae2bf355L,0x917b06bacf9ef6e8L,0x55f1ec4cadacc178L, + 0xbcd679fc81d752fbL,0x9404d6ce65a00270L,0x25ce99e6000c6e1fL } }, + /* 64 << 357 */ + { { 0xa13f19b40f3ff12dL,0x57ee08b1019564aaL,0x00ec0c997044a6f4L, + 0xaf5665f8dca1075cL,0xded5ca3f0620ab0cL,0x9b2cb8c7a896deffL }, + { 0x032ab2b307df2345L,0x964d109ef1da3f88L,0x2286b6f725133304L, + 0x0d16d531977a4567L,0x00a66036f1abae4fL,0x5debab1d95f0103bL } }, + /* 0 << 364 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 364 */ + { { 0xf2cdae3196230a58L,0x47cf36b4f304e1eaL,0x9d14f25ad750b29bL, + 0x931b9c65dba15f3eL,0x34db169ebf9fe2ddL,0x8a89e47c52663433L }, + { 0x8859a4f8026ec31fL,0xeeb703eaa913ceeaL,0x74638d6a67ac4db7L, + 0x5c8ea7b2be25d755L,0x8a0f0a8738db10eeL,0x96a26bace890bcd3L } }, + /* 2 << 364 */ + { { 0x883533af64a5e869L,0xaaa778c26973ec23L,0x8f0b5fb546d0fcf3L, + 0x7e6b0a0a4ab05da7L,0xcd91a869c67b6614L,0x7de9f2ff6c6f7cf2L }, + { 0xc072a106d1ec14c3L,0x3f4b960642a128eeL,0x7378192c8f0ce946L, + 0xdf2e7b9fd1149441L,0x4fa17cb614ccf45aL,0x575680e945f03568L } }, + /* 3 << 364 */ + { { 0x0f4ca7803374f910L,0x5948ae98fedc5b5bL,0x4873625b4ef805afL, + 0xbddba22fc015c586L,0x7091b50aa41a8c93L,0x721dd3384c005f42L }, + { 0xf43d37462065f41dL,0xd16bae3e172512b3L,0x3efca10c8277068fL, + 0xd0c25d7b77513f00L,0xc0015cc12dc3af9bL,0xdf11a4ec94c6cadaL } }, + /* 4 << 364 */ + { { 0x8b70e94f8f458c68L,0x292726544160ecc7L,0xe22219ba4d3ef22fL, + 0x7f8a712a1999f948L,0x25575e96abfe7302L,0x21c6ffc6564a1af0L }, + { 0x045e9c667e8500daL,0xef7c3cf704ef8ea6L,0xdd23b825c3db161aL, + 0x05fb173aba33a906L,0x9a8b5ecb870e41f2L,0xf3d9db0bccc30d1dL } }, + /* 5 << 364 */ + { { 0xbed7d94ca1bf2c8cL,0xbb7f437cb8b719ddL,0x65416af6106834bfL, + 0xdade8a144c4f7448L,0x62227a1d881dfc06L,0x37bc7de58dc2b7bcL }, + { 0x4f11541712ce030bL,0x72439d8ac2a9e0d6L,0x98cc53aba0f1b961L, + 0x2f68011d48b0ec8eL,0x4bbc34679c72d034L,0x0320c1469c576e38L } }, + /* 6 << 364 */ + { { 0xd9243926e873ff0fL,0x2e2a5ab6f20b0e49L,0xa1bcfeee0e35f201L, + 0xd25be5f3196f23f3L,0x298c67f2ffc1d068L,0x77dae55c0c3d950bL }, + { 0x5e15ab998822c996L,0x52de2e6d83f60a98L,0xa9f82ec947a7e269L, + 0xf02af9a22ac22e49L,0xdfb3103fa706f090L,0x125599623cf8dcb0L } }, + /* 7 << 364 */ + { { 0x9f5f44fa666e278fL,0x53c88803f5582c78L,0xd7e8f258f9627f9cL, + 0x22499dc938fd51bdL,0xa9d7497c846a4a79L,0x791b8ead026ae250L }, + { 0x84d47d19db15ff63L,0xb58a82c0267b44b5L,0x9b2f138806a52e30L, + 0x3fc8da027f08953fL,0x22d074d292fcac08L,0xb9c7c3db701d73fcL } }, + /* 8 << 364 */ + { { 0xb7b8562588ad12b2L,0x81f5958b1e44b254L,0xb4ebddd5c91b8ffdL, + 0xef815ae155d38511L,0x98587d551b0da525L,0x1d41817734a9ebbdL }, + { 0x844811fb1e6057d7L,0x0c16977176e5976dL,0x4b268bb4f623789bL, + 0xb26ae5be40498058L,0xb47a5ded3c2b435aL,0xe15a684b8fceceb3L } }, + /* 9 << 364 */ + { { 0xd55407583353db48L,0x0e334ccac0c0b5e9L,0x679a935f270c48d3L, + 0x170693e436ef0e90L,0xc72fb12f9de59023L,0xaae13a0e9371697cL }, + { 0xe98ed704d8d56e4dL,0xc6de5384eb71f091L,0xba63adccc6d905a8L, + 0xc84e614d66e40dd4L,0x15dcf1a3fa0f55e3L,0x4e26ee3af157c7a1L } }, + /* 10 << 364 */ + { { 0x122a3eedd09dc3c8L,0x6a19907faefe0819L,0x057aafa1da325339L, + 0x138033bdd42a5345L,0x8ac206af1a065ebeL,0x0a46f5ae25c31ed6L }, + { 0x7fc577a9d7e379dbL,0xc6df694369dcee54L,0x4c167ba2a8336bc1L, + 0x0fbd9708f3a1339cL,0xc6b8c01f226f612fL,0x5d4ed789d51332e1L } }, + /* 11 << 364 */ + { { 0x67ead4e0f6a40814L,0x42fe051ca2ec9ae1L,0xc09f84395eba62cdL, + 0x7bb5ba0c9d8e7305L,0x85962d0db46f81abL,0xc7183752628b18ebL }, + { 0x7a1f023edf58ec0cL,0xf21bfdbaab6535dfL,0x12add590801d2481L, + 0x1fccd1e37a11520aL,0xf83caddd6fa8f8e2L,0x99e7256c24e58433L } }, + /* 12 << 364 */ + { { 0x26aa2c2e5a1abcd8L,0x2b16a12e9609d9d8L,0xe485a551a2bee00cL, + 0xfa28c30bf4f2292eL,0x99abef78b7358f1bL,0xda6b3cdf10a276a1L }, + { 0xbd3858b747c03f71L,0x4f0bf5f0b22d05d1L,0x2d80f5d28250f760L, + 0x060f9b278cd9666cL,0x6a6c40b0b1b014a9L,0x44537af38c440a9eL } }, + /* 13 << 364 */ + { { 0xce1c070a2275263dL,0x2723b3d149cea971L,0xedca02f5817001b6L, + 0x5c160e9349c946e4L,0x273b4952458a5265L,0xc7bcd7c610385173L }, + { 0x22cddfd17fb08b14L,0x959d5dfe10f73d01L,0x900f5f348e387351L, + 0x6d7381dfdadb8695L,0x8dff2b193aeafba6L,0xe4a8d6bd8adadc36L } }, + /* 14 << 364 */ + { { 0xb564cfd676faaca5L,0x8a6e3925920dd223L,0xee59a140a590a383L, + 0x9e29b552a1922ad9L,0x604367de60a0da63L,0xc498aca592c35fd0L }, + { 0x74135082250ed8a0L,0x5d109d1a6c7c3e77L,0xf9e2d84dc63dff94L, + 0xca50f5e4f7aa2b0eL,0x7cba9e87d543d389L,0xaf5fbbefd8fd1292L } }, + /* 15 << 364 */ + { { 0x3163e2e895bcc345L,0x4ceaaf2d80d9a931L,0x4d2dc44b2f621612L, + 0x2a5f60b86cc8ffd0L,0xf49038cf7e8c9434L,0xb580b8c508015b8fL }, + { 0x4283ec01d52af80bL,0xac9dc35f99076245L,0x38785f7bd64c3dd8L, + 0xca19c17623bf8915L,0xd778291370478260L,0xc1e48e6816e34149L } }, + /* 16 << 364 */ + { { 0x707656834fc11c3aL,0x53a9403166aac4d1L,0x2a935ef0a6db6169L, + 0x002927612032d599L,0xb5babb2d3a6f1316L,0x601a7dfadb26af51L }, + { 0x00c340131322d983L,0x45b062ec2bb507c5L,0xa1bbe2ed0f9b3656L, + 0xe17a5d4934031d18L,0xe3661047f8fe1224L,0x0e4f3b3d623c6cf5L } }, + /* 17 << 364 */ + { { 0xb335d83c7c3b8c3cL,0x01eb94f059359a67L,0x3a8359a6aef3ffa0L, + 0xb0270076ecd2d862L,0xc946b1610377e30eL,0x9a5506c282bd6ae1L }, + { 0x737bdad0218512dbL,0x449238633487fb13L,0x36026dd12a8e7907L, + 0xb67bdc80784811eeL,0x9f92cc2405c90646L,0x02c551554c370746L } }, + /* 18 << 364 */ + { { 0xffaac084ca45cccfL,0xaea5cc3d061ffe3cL,0x7c5d7c60b355f387L, + 0x4bbb2a0c99cba92dL,0x6b4ba3ef2f7768d6L,0xc7484ed2cc5f9c40L }, + { 0x5d4e92fc52b57a7eL,0xba9f16c4ca2c200bL,0xebe02a8a3797ccbaL, + 0xb6b3f42138c4133aL,0xad5d85b68153d033L,0x782d6ee85714f269L } }, + /* 19 << 364 */ + { { 0x4654991087f226ccL,0x97894d5fc7bfffcbL,0x94f67786b3cabb83L, + 0xa6abaa960d788dc4L,0x08ae72d61723738dL,0x5003f41d86704dfeL }, + { 0x67687c3d40fb0a3cL,0x6fdc98c9b43320aeL,0x0f22572fdeb08964L, + 0x05bb02a4c8002624L,0x4c5adb7f987c2991L,0x3f1c6dddef4e60cdL } }, + /* 20 << 364 */ + { { 0x7845b6969c0cf752L,0xb82d052b5a732acfL,0x7760564c1262877bL, + 0x29b3c57a8ecc7aa5L,0xb58eccb0df1ebbedL,0x86fc15443c3a3303L }, + { 0x44761ddf13060f0eL,0x5a3dacfd7371a5a8L,0x846f6faaf7cbc2bcL, + 0xf5e098b0368caabfL,0xe23ea10710c08769L,0xbc5df1db1563fcdaL } }, + /* 21 << 364 */ + { { 0x75647f6476638edbL,0xb76ceb04aad6e25bL,0x33c73367d9393a41L, + 0x8396726dc55f0feeL,0xe1cbd48e751b3d43L,0xb779c5bdf47141a3L }, + { 0x122b85434eab6097L,0xeabacf45e08c6fa4L,0xdb32eab7769f49cfL, + 0xf956976a04ac2cb4L,0xf55c6fcb5ea8e71aL,0xd72940dfbad47ea9L } }, + /* 22 << 364 */ + { { 0x65c3a54e142d8955L,0x5c6583cce7814f25L,0xbd5a07d8d924dc7dL, + 0x9f717bd9c28f6e8eL,0xa0c4ec4e3b6540a7L,0x3153bb2b142b3283L }, + { 0x53bf403c9b296946L,0x659a828ab1cdb6d2L,0xe9517d811369af19L, + 0xd8c7a0998990e7a0L,0xbaa9f59de535cd04L,0xbb0cc68e0f269551L } }, + /* 23 << 364 */ + { { 0x2b4a0e69d0cd5fc2L,0xeb8dd25981167a94L,0x356198ae61b73503L, + 0xb159ca12e5289d45L,0x99d71c97991765b5L,0xce3a3b6c198e10b0L }, + { 0xcf6ee0bcafbb512eL,0x4aadd1381e19b49aL,0xcf6a9cf3b4806f0aL, + 0x6aff0386ad688bb4L,0xea487c6e4f2e5065L,0xec200f4b56573b51L } }, + /* 24 << 364 */ + { { 0x3c00ac526a78c6e5L,0x9c61aca6defaa52cL,0x0034128939794a09L, + 0xe08910d141cd7c0aL,0xa58ffbb6a732e3bcL,0x87bf51ab91fe8fd8L }, + { 0xc4f4f2674a59e2beL,0xdeb512c7438071c8L,0xddf82842e9cd290bL, + 0x3e17311d6ae85fe0L,0x6e9236a9b41be881L,0xbb9ddf9853555ebfL } }, + /* 25 << 364 */ + { { 0x07d2df1162bb0e3aL,0xe74ce211ce469affL,0x9629d7d4756b5a83L, + 0x61d2a633aefd449eL,0xd39a6afe491e503bL,0x0f1568d14d2b2ed7L }, + { 0x8216304cd19611bbL,0x6df99bbeb27388daL,0x2b0f60c0b7a3b4beL, + 0xcff84c1c7dadf840L,0x470201e28a9f8a49L,0xcda3693c21afc717L } }, + /* 26 << 364 */ + { { 0xccc163ea09f3f0beL,0x9932b56f6a5b0a63L,0xf89fae919c69668eL, + 0x555f98215ce13021L,0x4b02693f37037aa9L,0xc4afee79bde50f35L }, + { 0x4b0919c202aa6c7aL,0x3166de2a991e15e9L,0x284baa3e7077fb38L, + 0xbb7a6416a116ddecL,0xe8c89547b7636772L,0xff9403620ef92c54L } }, + /* 27 << 364 */ + { { 0xcd183e8bd3ea4c3cL,0xc8ce2f2154b7ac32L,0x75387e04be960826L, + 0xaf878400f2e39f5dL,0x7fcefcd94fa628f7L,0x76eb621c34582cbbL }, + { 0x44e1f848f29d2496L,0x42aa36174ab4eb21L,0x43cead840c08b50aL, + 0xfa4ecf60dd44f7c2L,0x5ac9ffd59f817546L,0xec11567eabcc594dL } }, + /* 28 << 364 */ + { { 0xd5d81275e2ce6008L,0xc45bdf250b3b9d10L,0x15ab5da36cbc83e2L, + 0x85a18cf8c52a66cbL,0x77e202b8b042c047L,0xc4dc3de2e7e7997eL }, + { 0xfe9335b1995fa67aL,0x809e161d75b96a00L,0xfb03c2a5a0c3baeaL, + 0x5c7e0523888c2f77L,0xa8fda1c887ad10e2L,0x90484f78858a3577L } }, + /* 29 << 364 */ + { { 0xefc5aa2681bf26c9L,0xdbe91f606bf105bcL,0x0d70c4d4369dd3aaL, + 0x2b357b847af9bf66L,0x4293e9a01f27f163L,0xc846f67cb3eaeddeL }, + { 0x4556bb787da305dfL,0x4ecebf83a5a26bf9L,0x8e05af924c1bc430L, + 0x4f3bdaba70f80402L,0xccaccfd3cf204577L,0x8fdee135a0c42d1aL } }, + /* 30 << 364 */ + { { 0x49e41f0af9fde126L,0xec9600443613d3c2L,0x2c62a49d10421d3bL, + 0xe24024648131a0d8L,0x8a7ce188bdf794fcL,0x704dea7d4665b1b6L }, + { 0xbdb9c18e4d57c6baL,0x5288a053f669b3c0L,0xbf7d01b878a5e252L, + 0xb26cccf926b9cb7dL,0x14191a3284326c47L,0x460ff74791f8425bL } }, + /* 31 << 364 */ + { { 0xb9958c5397698b9bL,0xe1f74292c27f96ffL,0x172b0d50806da6bfL, + 0xaf3d889ddd38b97eL,0xe7a75ea409c688daL,0x1f0951b85c631b2aL }, + { 0xdad8b2adda1c111eL,0xbacb9cc832813338L,0x30b8336b10582abaL, + 0x0ff3d7549494e71cL,0x8d99be5cd663ed6dL,0x8eb412cf7073a941L } }, + /* 32 << 364 */ + { { 0x59367582bd27be7bL,0x92bf5bbc1ab2c596L,0x5d96351af6a27741L, + 0xeab94db87f929e0dL,0x865ba011043f1afbL,0x43acea125fb631ddL }, + { 0x192e0652b2fd1436L,0x44f22ff17b38d121L,0x7bcc228db7cae5f6L, + 0x02eaeccd6a828b03L,0x7c48a2ea91f301aaL,0x1e090717f5eb1a07L } }, + /* 33 << 364 */ + { { 0x4c7f41b4609c6818L,0x978c2a561c82b3c4L,0x68404f1d7f6ba836L, + 0x91e056d0c863aa7cL,0x0b24599ba2261804L,0x16e9060dcdd7596fL }, + { 0x42aa49434eff004eL,0xb99408690438f1e4L,0x28299e8581775712L, + 0x498998eb83be6877L,0x84273d9e91328a67L,0xb7e9076e9a87bc8cL } }, + /* 34 << 364 */ + { { 0xe8d204865e5aea08L,0xaa946076addc7ba0L,0xc0153a9bb6a5cabdL, + 0x622271bd4fbe43e0L,0x44de159cbd62e5cfL,0xefca41112b9b63f8L }, + { 0x30774d3cf5269928L,0x4fbb7ff84ac0c8b6L,0xe0611f1f8839106aL, + 0x5d4121204ffa4a64L,0x9552c123e86251c0L,0x57d029680efbdb14L } }, + /* 35 << 364 */ + { { 0xdf3f8e06d7aeacd2L,0x725b25fe4d0e7af3L,0x1794f0da5c17392dL, + 0xabc807dac977ff46L,0xd90e6c8f0d5ca66fL,0xaf8eb526c2d26d49L }, + { 0x4661962e8a8efa37L,0x2a2cbeade87ad53aL,0xa57d34b1ce3ff40fL, + 0x1190437dc6aa3067L,0x92c31e779db66b47L,0x86a8ee0f8e8a70d4L } }, + /* 36 << 364 */ + { { 0x7b65bb14de97229eL,0xad6e3fee4c6d35b8L,0xfcbbf6afbee3f5d8L, + 0xb51549ca4a438fe3L,0xe66e615d437d531dL,0x9ee793eabf168624L }, + { 0x796789b0f8878a84L,0x3d38950dd32ec2ecL,0x74c37196a638d45bL, + 0x35d318327aeedaf0L,0x082c44f046a001e5L,0x93fae5cf89886220L } }, + /* 37 << 364 */ + { { 0x8e585fea499b635cL,0x60afcb3566781e83L,0x06594d9267482257L, + 0xb9f6101128773448L,0xba9ef7102817fd2aL,0x494e05b2aad046c8L }, + { 0x65d804fc1614e265L,0x1b0884c6d97fe002L,0xd7d34f60875bcc2dL, + 0xf34725444b440852L,0x49386bfb95591325L,0xe3966f4ccf68a142L } }, + /* 38 << 364 */ + { { 0xa5f3bc6cea06320dL,0x1bf855c637ad6e7eL,0xce7ff06ec58befadL, + 0xcf0d22cf1c2c0478L,0xf53e473e75616621L,0x00539f8700829986L }, + { 0x45398355844866d3L,0xbade46a2d710bc63L,0x6b3da567d4e2641fL, + 0xff70185978fd963cL,0x2eefaabaa5bc18a6L,0x61eeca92eb64cd49L } }, + /* 39 << 364 */ + { { 0xdf7c7c0b4cd4c82fL,0x67a26a97188ab9dcL,0x58c5bd74dd189cebL, + 0x3e1e93a9bb6409f2L,0x0d18a8bca6bb744bL,0xad3eafb45328dcf0L }, + { 0xacd15db5e311dfe8L,0x13a1c10ac1e849bdL,0xfaaa7227e1e73aa5L, + 0xa4cd2400e33d4665L,0xb9be68d9d6d527b4L,0xfe282bc05efbfc40L } }, + /* 40 << 364 */ + { { 0x159b38e17f8fd522L,0xf3ea27b5755e2bd8L,0xfaa52efebf11ac90L, + 0xc2014b892cb9f6dfL,0xa711c179d8baa5d6L,0x5474c1ceb22c2f27L }, + { 0x3cbc74cb031d05d9L,0xddd97ca6c44e469aL,0x21b386a647db83e5L, + 0xd1431c7b7abc0595L,0xbc05d009a416a325L,0x1c29eb709da53e92L } }, + /* 41 << 364 */ + { { 0x7f1aaf98181ce8a0L,0xa890cd3b6caa5b6cL,0x5d78dfaa5fbeac66L, + 0x36c63cef3d3d4594L,0x6f89ac3ec36d117aL,0xce9095640fc90e27L }, + { 0xaa356b1ac127aa76L,0xfa42cc119d181455L,0xbe4622fcd27f5ab7L, + 0x58d924542c3d54f7L,0x78a84f6b07e93c24L,0x5bf7cd278bce9a46L } }, + /* 42 << 364 */ + { { 0x4bde9ce5f810db3bL,0xec4a74b7281552edL,0xf5b4fa5fee085bb0L, + 0xb07a62936192c8b2L,0x163ff0d1fb18d219L,0x8d4b5e1d8e0ce753L }, + { 0xbfa6211baebcbf50L,0x1ed6d4b4fecc19eeL,0xbf6d514b82393e94L, + 0x90b356c1711e7d6fL,0x87b28dc2f975139bL,0xc41900648d8bebe9L } }, + /* 43 << 364 */ + { { 0x3468af53e8d49368L,0xa0a07369ff825262L,0xfad134fd662958f7L, + 0x5be79c00ce900822L,0x4909a56c44bde5abL,0xc2e8c4df4862e335L }, + { 0xd5e9b9386e7e41f5L,0xd3828d424fe474afL,0x058b2723cef44adaL, + 0xc74ac74617eebe66L,0xc3e6e014bca4416cL,0x2e30bc88167c2e86L } }, + /* 44 << 364 */ + { { 0x68211ba4969c2c58L,0x7a34733977f218e4L,0x0237eb3696ea1d64L, + 0xdc97f94b7416f3caL,0x63aa82e476bf9e52L,0x4b88a32d388465baL }, + { 0x7322d9f44adc7579L,0x70c01c7fb24d28f6L,0xdf7f4213c7517ecaL, + 0x42c027f0a8db6d56L,0x2708360eb6c2f8baL,0xf20690d1c2dde09eL } }, + /* 45 << 364 */ + { { 0xf139c3e3bc6158ceL,0x19207b6a4c86b780L,0x55af3eb977c036b1L, + 0xd192686abd563ebdL,0x8bd0afb05550266dL,0xaaa7376d83bf81bfL }, + { 0x26aa74ae4a114541L,0xd92549dfbb6745ecL,0x6ad6a14ec6bbfbd0L, + 0x63fee75b411771f3L,0x111ae3101938e8b5L,0xce3e5e346c363756L } }, + /* 46 << 364 */ + { { 0x2a53c88ae0a45b56L,0x26367466da72228fL,0xdd65516edfdbb135L, + 0x5fe254e82d7e37bfL,0xc0f5cbe433ef39e3L,0x249b7e3ece85effeL }, + { 0x85951a5391ffba8aL,0x41117672c8dd5ec6L,0x7a74538d9dbb0761L, + 0x0b35fba0cfb06ddcL,0x8c36be4d1a0aca2aL,0xbf884a8e45848e1dL } }, + /* 47 << 364 */ + { { 0x191eef31788596c8L,0xa7413be65a2d0ef8L,0x30894fcc5c3c09e1L, + 0x6b0e429b2f72a333L,0xceea52a1e70470e2L,0xfc638b316b682db2L }, + { 0x31af73cd615f7f21L,0xb31663760094996eL,0x7ec37e33dfff756dL, + 0x38c50101d9b63a4cL,0xa517c6df192f18e4L,0xd674c53a841fb337L } }, + /* 48 << 364 */ + { { 0x4dd3bd842446fc6aL,0x4654b82ef25ab510L,0x1ad46998ba066896L, + 0xb7c679acad713bbdL,0xef9389aff7ca4fa5L,0x1b864105d68b6a1cL }, + { 0x3acfff604b6f5ea4L,0x81ef58f7b9e5a475L,0x5e2f6441c66ad734L, + 0x49f144c42fd3eb16L,0xbd7f22082e4e2117L,0x30865994417911a3L } }, + /* 49 << 364 */ + { { 0xc2f25d9e80d2adb5L,0xa0e77dc5242430feL,0x7f30e54b4f504e97L, + 0xdc114db4680ca2cbL,0xf76fae57adec4d89L,0x06f892eff313535fL }, + { 0x50af729a9a266407L,0xb0cbc4f0764dffd1L,0x153ff8f8d20c2e19L, + 0x27fa845a7388d22fL,0x26e08ef5d784e057L,0xccbe49ee53b5dfc0L } }, + /* 50 << 364 */ + { { 0x6fa8e5ff3082ceb5L,0x81f4dd02ef4850ccL,0x626b324456483f9aL, + 0xc0acbd8782e65652L,0xf9bef3117e23f93eL,0xc2474777c2310f6fL }, + { 0x6b4617704379fd64L,0x2f8fc599f18c3b14L,0x2287f1d0bd076aedL, + 0x9f8eac0fef366016L,0x517cd2e371fd845dL,0x0fc2f219a30c371dL } }, + /* 51 << 364 */ + { { 0xfea0464721c56ce8L,0x4f7b055b6a32a26bL,0xf8c8d93e487ed396L, + 0xe620b440855f4df9L,0xa3f6f21dea870c14L,0x0518225207dad127L }, + { 0xbdfb7b12c68ab5f6L,0x5f58bdd7fc68f296L,0x2df9cfc505e4fdc2L, + 0xed12a102379c282cL,0xd388362654d8de77L,0xaefb0f7fb01065afL } }, + /* 52 << 364 */ + { { 0xdc64f8d23d80d738L,0x7ae74ab1d95a1c6dL,0x4dba93a8dd46de0dL, + 0x271aeb870fddbd1dL,0x1bab6546e9e7ed31L,0xe6445d22efec8f37L }, + { 0xd927df1797a718a7L,0x738c2450351b1ceaL,0x3809e595d51a7422L, + 0x4f8d5ea58969456cL,0x74d9168421c9ad95L,0x59a69f8f4f796a11L } }, + /* 53 << 364 */ + { { 0x2542fcf1f07717aaL,0x032abb3f405a7717L,0xc757e6e294cade8cL, + 0xad4776adf2e84dd1L,0xb7e277243d5e397bL,0x173894a605f8921cL }, + { 0x0e3a78531f6afc3fL,0xf33732b8ad62482fL,0xa6b4e0f03e4cb6e9L, + 0x51ba565eda02264aL,0xd0afaa4600f3f376L,0xf5506a1e35252e93L } }, + /* 54 << 364 */ + { { 0x3574783b5ea1c662L,0x675894e514fadc8dL,0x64dd63935ac6ea7fL, + 0xa76c00dc77f16c96L,0xf73ef2c62eb9574cL,0xdd39a89a2e408008L }, + { 0xbef8c8c72bafa10bL,0xa31f030a074733f8L,0x5620dda5445b4b6dL, + 0x4e08fb0173040ab8L,0x0a279f38598ad48aL,0x03e8b55e2d40d775L } }, + /* 55 << 364 */ + { { 0xf49d4d54c20c8610L,0x1b1d70bbc0d62b65L,0x524d3a0c16285ce2L, + 0x0be553b08a0785b4L,0x9b93e5093c84975aL,0xbeac761160769465L }, + { 0xffaaffcb3331dd0aL,0xad0f01542d70fcf1L,0x65aaabab66fe24bcL, + 0x283edb562cab253eL,0x1659deca80383c87L,0x06de45fd83fc6d7cL } }, + /* 56 << 364 */ + { { 0x7bcb055d5f76c311L,0xdb2d05878e293aaaL,0xb15036e7207360b4L, + 0xbc38cc9f163f0ae4L,0x5a942f85a44d0a0eL,0xee8633a23f553a88L }, + { 0xf66b65c5c9bd4ee7L,0x7a4ca96a80b8ceefL,0x7b71cc55f6f08036L, + 0xc0408b198c41be7cL,0x885fd72f80860d93L,0x338a567be7f68b7bL } }, + /* 57 << 364 */ + { { 0xcba302e939d99b60L,0x2557b3d903b8faa0L,0x2a99cd6e9efc4461L, + 0x03ce3e08268f14a3L,0x59226a83b1c68a01L,0x81a18c69fe379976L }, + { 0xfdfc9f148af62557L,0x0cdf327140b2d4ebL,0xf99ff3ded26c6085L, + 0x2c138ffdf9b0273cL,0x393d6de6888dfbd3L,0x75903c68e5cc102bL } }, + /* 58 << 364 */ + { { 0x0c56d477b78a7b91L,0xbedff933c7c3ecf4L,0xe02da64223ead65aL, + 0xf7e7cc19a8162300L,0x3719fb8f2f3dbd03L,0x4f150cb8cff88c59L }, + { 0xa564c5eda7fcb233L,0x9b042870b6a41ca7L,0xf253b65ac1615f1aL, + 0x9ccb49a7b8aaff46L,0x38bbc5f7af0086fdL,0x688f7c2054a6d8a9L } }, + /* 59 << 364 */ + { { 0x3702c5e5d22a0892L,0xf17510a28d510809L,0x5c36dc68bfdab4e7L, + 0xf72c9357623a98e4L,0xc660fc5146624a0cL,0xf0b4983d3e64dd4cL }, + { 0x5cb98cc9a5ecf45eL,0x79759acdf5082a78L,0xfd0daf366e7321dfL, + 0xf61c54f7f1ebcacaL,0x782e5e74b8f665c4L,0xb1d54c2145d78c08L } }, + /* 60 << 364 */ + { { 0xb64f3b9bef1af123L,0xc86dc5ffe1b75401L,0xc3a76d81d928e989L, + 0x075005abff8ca002L,0xca6226325c3cd8b1L,0x017a97b2bd8f772aL }, + { 0x187eb635039c4757L,0x9eb7a9d1e905c6e5L,0xdacb98bfbc251cceL, + 0xe357c60e8704c639L,0x50563b8558fd987aL,0xb2f89c864cea5d4bL } }, + /* 61 << 364 */ + { { 0x3d13c0bfd32233faL,0x997c424145aceb7cL,0x77ff5a75ed2e9df0L, + 0xc4279aa23c91d085L,0x5a11a276ca0392c7L,0x928e06032daae653L }, + { 0x21fe225fc4046f85L,0x591fa82f512dbfb4L,0xb5b01a3f51aa53feL, + 0x900012ef7133befbL,0x24609da17130c15dL,0x3c4a09b33d2549faL } }, + /* 62 << 364 */ + { { 0xcdd3073d3ceabe32L,0x56e155bc5a848977L,0x07f4c7c6da48eef6L, + 0x00a2f9f79e021b38L,0xeb683e17ffc4bd6bL,0xa7d6b87592b7e240L }, + { 0x651d21de7e48836eL,0xf9c9ede775de3c75L,0x72cea748d90f2634L, + 0x29d8022283fc524aL,0x1e412b510dd044faL,0x1b9b332a76a04fdfL } }, + /* 63 << 364 */ + { { 0x4dc8421f06f49d8cL,0x6a3fd9a83f979e4cL,0x50b0e3760b51bd69L, + 0xec22f486a592313eL,0x5e4663ff8e8904d4L,0xde7b9e23f3362548L }, + { 0xa1ad270d1ab757abL,0xb91fd935a3089f6aL,0x1d6b1524a635f996L, + 0x8673f8e29c718c6dL,0x0e04360725932b9fL,0xb5d0447222ac239fL } }, + /* 64 << 364 */ + { { 0xdf0ae8df941948e3L,0x123fee901d010bcdL,0xde3717ca1dd28691L, + 0x0c1db879709b678eL,0x0288959a400acdc6L,0x66c691815ca2d03aL }, + { 0xe52534b3dbbb75deL,0xe914938c3de927cfL,0x1a9a34f873eece30L, + 0x0fb0c7bd642a6799L,0x375cc0cfeaa7e8a8L,0x75fb9eb5d00ec238L } }, + /* 0 << 371 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 371 */ + { { 0x9ca8cc9db72958ebL,0x3c8cd0db1014f562L,0x72115d53059b2bbaL, + 0x8fe7ac30730e5dc3L,0x4e67ef69841d8998L,0xfb6439ffc8ed37a5L }, + { 0x48164b3e26df84c4L,0x37d492ad365bc99eL,0xb7fd4643beed38ceL, + 0x993cfa9fa3e30b3dL,0xdcc5e7af01ddd484L,0x5edf3ac06840175dL } }, + /* 2 << 371 */ + { { 0x79768e9f51d33c11L,0xeec34505a4b24889L,0xc194821bbe0c67d7L, + 0x537a6a4a6909fdfcL,0xae6d705195ccdda7L,0xed4b722292b3926cL }, + { 0x2c5dd6af6b24a3d4L,0x9282ec39e4386095L,0xdd3c7388397a3bd3L, + 0x9d176c6a8baf59c2L,0xd5c6219e380ec958L,0x194fc11654e8e315L } }, + /* 3 << 371 */ + { { 0x0b7576f901ec1432L,0x84b30eecabc5f603L,0xdaaf7ba9f4a84b7aL, + 0x9e3a5daa3bb37a99L,0x56bd964880378cffL,0x2fdeeeb78e6ed856L }, + { 0x079014a73c81ac34L,0xf8de4004b4211c27L,0x0cee3df97fe4391eL, + 0x441aa7fb2fd2fc38L,0xeba7be864d1b575aL,0xca2fb5b7231c2d01L } }, + /* 4 << 371 */ + { { 0x0683349e463a8251L,0x97dc4f475103e72cL,0x47c7181050663b9eL, + 0xf327d1499733dac6L,0x03f55e4a292137c5L,0xccc6232ada59e1c7L }, + { 0xbaa8b4ddadc59cb8L,0x45370d35fe7486e4L,0x99a88c1db0322df9L, + 0x394440a7fd69954fL,0x9060473da5a29889L,0xc8ca43e32f04864aL } }, + /* 5 << 371 */ + { { 0xd5c7241add8b9644L,0x45a5f2d1993116d2L,0xbacacd4a823048dfL, + 0xa278fa042568547aL,0x3a4f2482bff72820L,0x1305d1a713e4314aL }, + { 0x9d84c33334ba28e3L,0x9995b5bb6a32fb41L,0xb0f75f3c520946d8L, + 0xd7c4b8b7de98aa63L,0xee5efcf3ba856b6bL,0x36af33683324ed66L } }, + /* 6 << 371 */ + { { 0x90762c1f5827fe2cL,0x20160f7aeaffda88L,0x7420849f5c47c645L, + 0xb08231956d72e748L,0xaeac683b8ee11773L,0x8c2a0a79fb5c550eL }, + { 0x6d986d696c07cc1eL,0x57269140ba8398b9L,0xd13e136fd94d5223L, + 0x1aa75419ed5b01c6L,0x7c2014b1408fcdccL,0x0680a985cffde5eeL } }, + /* 7 << 371 */ + { { 0x92fc9a3342c5a7eeL,0x8768614af9f0ed71L,0x1ea5f7ed87ebfb66L, + 0x296852ded361069cL,0x1cec6f1a0192498eL,0xbfd4858fa9cca3aaL }, + { 0xfba98c242ef240e8L,0xc8b500e4ab635d9fL,0x9f49c572913a3eddL, + 0xe6181f93d42b2d4dL,0xf96b5db26aa77fa3L,0xdfb2241fe43558d8L } }, + /* 8 << 371 */ + { { 0xc7d0abb2edee15a5L,0x72dc0105228cc4a1L,0xeb67defca80767deL, + 0x6fa174d871820908L,0x3215df485674d19aL,0xf944531a960a081aL }, + { 0x93ed7180ef2cce62L,0xb318edbfc8bcfc0dL,0x0909d56efe787e58L, + 0x5ae74fc98fe8b96fL,0x8fc342c435ab6811L,0x6fc6cc5c0b991e0cL } }, + /* 9 << 371 */ + { { 0xa8eaba6e291f689dL,0xfbfa9a2cdea0cba9L,0x5b1b4a21727bfa11L, + 0x3b69505fac59c8c4L,0xb06290c89368ddb2L,0x4181abc294bcc14aL }, + { 0xa19f65813e29d997L,0xab1ae8408864aac2L,0xb04a24300fcc9ae8L, + 0x3ca2428e1059e4dbL,0xe288731117e1e01dL,0x1f5d4164be56238fL } }, + /* 10 << 371 */ + { { 0xc600dd57354416d9L,0x6f5840991f829d6bL,0x2d7b0a27de43c1d6L, + 0x21bf3a9e616bdb16L,0x33ce767c96297953L,0x99bf97b69e4398b2L }, + { 0x4069cced8d441287L,0x52e0edd6bf01017dL,0x9981bf89c5394236L, + 0x07d9c079acb24e38L,0xd2e5e904a2da4735L,0x4c3c12162f1b6cd9L } }, + /* 11 << 371 */ + { { 0x1f28bd0de6f1c85cL,0x4a49d0864e6f3db6L,0xc9a8e70c4ef7d981L, + 0xde8abcf2682bc68eL,0xd0ef89a4a66cbee3L,0xfa03108432df7f0fL }, + { 0xe361e0f803594856L,0x1f423bafc985c77fL,0x50397b67010ee4acL, + 0x502f4a20c0a48e96L,0x260bed875435539eL,0xdae03cefa0391250L } }, + /* 12 << 371 */ + { { 0xfeecc6e83be5ba68L,0x3293dbda40445158L,0x48454e20e81879caL, + 0xd0ea9cb89c4a2712L,0xba8b6f33540749c3L,0x95e6d6e3e971df93L }, + { 0x4c2a1b13478a2eb5L,0x8b5f9af330b92170L,0xe6c60b5343573986L, + 0xb9f56a6a57040c00L,0x6de6489f6291a7b4L,0xa9a7784653bc3246L } }, + /* 13 << 371 */ + { { 0x0dd4172f9025411fL,0x978e952ac6129de8L,0x9afa974bc7ab7609L, + 0x7bd29a644e42f223L,0xc0232f5f3deb639bL,0xacce69d05f39a264L }, + { 0xdaee07cb3070b24cL,0xe3adc8556b532246L,0xae5935ce1e6ee4f6L, + 0xba9c4329ea018a45L,0xa1a4002e6b97ee9dL,0x98390aab8a9460cbL } }, + /* 14 << 371 */ + { { 0x828a9dbe67154a02L,0x57a3af981866aadfL,0x1558428089faa581L, + 0x2da092202dba2a1dL,0xa225f631df197ae6L,0x0abff5cf8f4ebabbL }, + { 0xbbadc9b3b98e5e4eL,0x7c7cc36e4509f98fL,0x072a6cc2759413f6L, + 0x7b39ea4121dd1222L,0xd6baf9e196ac2c73L,0xee38818c75d46296L } }, + /* 15 << 371 */ + { { 0x19befeacfa37c53fL,0x32c29b361f95c29aL,0x1d282db40d5aeafdL, + 0x8812b6c8f102a97eL,0x1cd4a23c8402f481L,0xbfdf7b6b8eddec81L }, + { 0xc8039ae0616b2654L,0xdc6f38acabd23a57L,0x2431c763f147dd44L, + 0x7c45ed50d795bc37L,0xdbc30ab9842022aeL,0x568f7d4ba1f05a43L } }, + /* 16 << 371 */ + { { 0x55671129542f4e90L,0x43bedccf0623d4cdL,0x7e21207ce99ca16bL, + 0x785fa1057c7a26b9L,0x33c28658c2c3ab00L,0xcce42a48d79cd59fL }, + { 0x9a674db4b8c3bc75L,0xea701d156904e3feL,0x990e722166bf2c6cL, + 0xba29affabd4c3791L,0xd98510cf20696ee1L,0x722ed471f93d26a5L } }, + /* 17 << 371 */ + { { 0x74e6c2624ba40f04L,0xf7ad1f159a63b3c2L,0xa89e8490ef75d482L, + 0xaf8e79b83bb5f5c4L,0xb094f8660c624d8aL,0xb571ce6613c69a60L }, + { 0xcbf9722d53787457L,0x97e24cf5c15d097fL,0xdba98bede99e034bL, + 0x8b6c171a57773590L,0x5d2b441cfe822efbL,0xb8c6dc57fc74ef1aL } }, + /* 18 << 371 */ + { { 0x37c70bdf7db1c03fL,0xd9368612964632abL,0xcf6368d742530338L, + 0xe56beecbb1d9522eL,0xb1caaf16bb6fba3aL,0xb7bd485ac8384d26L }, + { 0x4ba13818528d4372L,0x95c469bab9c5e8f6L,0x4e5cef0c4a370695L, + 0xb87c97ca663f9b07L,0xa9e1b388e5f3b79aL,0xc0416bb84c845a1bL } }, + /* 19 << 371 */ + { { 0x4483db00e4634d8dL,0x4d8d623d0a268bd8L,0x296f179c64e6d10aL, + 0x048f3a1cb6c7ff95L,0x60f8ad62c60c76d1L,0xa0a497610d028845L }, + { 0x10128387aea1b714L,0x81e5c75ca18bd98cL,0xac30d7361dac4200L, + 0xb83c1c12821380f1L,0xc8ca7c6afaaeb726L,0x13fb870dfead4cfbL } }, + /* 20 << 371 */ + { { 0x3921332a6b393648L,0x49ec6df649584f38L,0xa0fc013dce243a6cL, + 0xde5b16b5f8da8a00L,0xabcd0c0471ab1c9aL,0xff6594bc78b83305L }, + { 0x3546004b76c1900bL,0x87428fa236fb3186L,0xd2e464ce59cdeb49L, + 0x1260bd28faf6ec08L,0x1ada2f08d0c9d098L,0xe0b66299dea06396L } }, + /* 21 << 371 */ + { { 0x603d58167c1212e8L,0x95bb823fa4590144L,0xf239058a4bc3ba48L, + 0x21f2aa610db724b3L,0x29c706e8cd6792a2L,0xb143a84a634f01e6L }, + { 0x68f37382626ee80eL,0x56daa0e51fcd8c4aL,0xe01b52b39e5299a5L, + 0x2224513c3accdac7L,0xbb21c7d74acd435fL,0x039bc010bbcb948aL } }, + /* 22 << 371 */ + { { 0x5006c3a00848d6b7L,0x726b8648b28285aeL,0x7162e3c0277c5a87L, + 0x567f7ab02019c20aL,0x490c858fa551d5efL,0x0029a108d134a2bbL }, + { 0xa9e19284ef0aca3cL,0xbc399dc16e414f83L,0x5bdf85f86efa5a8eL, + 0x5291e1a674fe7c5fL,0x249ddf2acd7091dfL,0x71d4cb4c2e29fcf6L } }, + /* 23 << 371 */ + { { 0xc374acf4c1ded13cL,0x300d96132b69132cL,0x909ce34b055622d2L, + 0x26f033f6bad97809L,0x30987ebed1f7a220L,0x23147226db775b8cL }, + { 0x8d45c2c28d05ecfdL,0xeee0c679f0c1b419L,0x9f7df70d8c380da2L, + 0x4d49f3d130212a25L,0xa9602e8c64491ff3L,0x5ab91d223a254c49L } }, + /* 24 << 371 */ + { { 0xedd3291c9dac47a9L,0x02d64634fb5d396dL,0x2ce21bf163264c51L, + 0x0fdcc68e092c4724L,0x653acb286e3e4c2fL,0x2f9c77f12f1fa1edL }, + { 0xd91d4c3aa58afea2L,0x5a91b2ba7b0d8092L,0xd47e0f61f10a15fdL, + 0x01652d86f9c86edeL,0x1cc1b668d6006daeL,0x2763e36d24af68beL } }, + /* 25 << 371 */ + { { 0xaa5f387c2314a1adL,0xb8c00105e2647c74L,0x1f950dd8d6719178L, + 0xb7dae31de79881efL,0xf2d49aa2e45a615eL,0xb22dc098f17352afL }, + { 0xa4c438728ac23ba4L,0xedd6e4092c55e588L,0x1956b199022f5632L, + 0x18adcaa58c11bc50L,0xa0c11f6458b1cbf5L,0xd1204377f961ce1fL } }, + /* 26 << 371 */ + { { 0x35a2685bbb77f5dcL,0x1b5b79bbc08efa67L,0x4ebec6e6ea5f411eL, + 0x1800a21988c57793L,0x8d7397f2cbb13c96L,0xbc13ac35dc0327f4L }, + { 0x53ac05a6fd94b150L,0xd898fa600423e787L,0x802aad2c2a66b97fL, + 0xb604ac0692c62b03L,0x9f395d3a45911e7dL,0x5d38164128ae56b6L } }, + /* 27 << 371 */ + { { 0xa7d5a3afa5fb0decL,0x0d11c0cd5b27e02dL,0x8d854b53366c6cc9L, + 0x87ef4c140ad9a5f5L,0xaf7c2e6b0c5f8acfL,0x81fc22b69f010f1aL }, + { 0xe49e0c7e4e25ddb3L,0xd30bc860ef233d23L,0x0b63afb89fa41205L, + 0xd14b326c702fea93L,0x10ab93662c2a5fc8L,0xab35bab356cfff28L } }, + /* 28 << 371 */ + { { 0xdf0f79524130138bL,0x117e4628934c58afL,0x227be6867b6a4087L, + 0xe73fb2f3b8d298a3L,0xe32e89fda9bacb9dL,0xdd3be6130e9ea7e3L }, + { 0xd3d655ead4da2d1eL,0x153cce647833bb3dL,0x4a32a9f0b36da20cL, + 0x025768e5a69c4b27L,0xb0b5da379cf1fcecL,0xd0ecaba23aa3b99eL } }, + /* 29 << 371 */ + { { 0x9ab6dae0aaf6b398L,0x2d50f46b4f8e270cL,0x46c1e676fd7b7005L, + 0x4b8b203e32cf8be9L,0x0253ec899451bca9L,0xc3a7eab7f512b7a5L }, + { 0xf3bed3fdc5bd61a6L,0x5c0eb52f0a37ef8aL,0xb61aee11140894dfL, + 0x690607f9bec928f6L,0xba2b1db65148b45cL,0xbd309bf56619b652L } }, + /* 30 << 371 */ + { { 0x79d624c7a7b92932L,0xcd086bd7cc75e7a8L,0x3cddc1bbb48eab26L, + 0x10282df1f6791cfdL,0xffedb4fb1048f114L,0x937ed0e7c092d899L }, + { 0x045e4f60b84b6d20L,0xdd67bd36877ed915L,0x9bf8fede97617aa9L, + 0xa7ff9b0789cb8e1aL,0xc49e310e74f4e7d6L,0x12dde0fb3f62eafeL } }, + /* 31 << 371 */ + { { 0xe2e3dc4d50ba6e73L,0x31c19ebce6114f87L,0x8df0ffb01ffa99b5L, + 0x305142f1bfcf7fbdL,0x39931954ab88b782L,0x1952bbab43de3650L }, + { 0xb32ed678aa09e528L,0xa5150011acee68ffL,0x0307716a97b98b23L, + 0xb60c3edd4fc8d2b7L,0x91c81725b2b2f887L,0xf1dfc70ab9fb0288L } }, + /* 32 << 371 */ + { { 0xe7cf5bacbc579793L,0x11db7ddfd73f881cL,0x9c1a531d04fa8473L, + 0x399e84845780efdaL,0x6e9c12be4f62cb5aL,0xf21bdc4994a5df3bL }, + { 0x3c15fe1211da2a4fL,0xdea123bb23e631d1L,0x3ef76da4be294c90L, + 0x5cf21d5aa99b8398L,0x50679cf8751b9f6aL,0x4b3f3b9c54d0b7bfL } }, + /* 33 << 371 */ + { { 0x442dc0fd27174604L,0x5aa056efebc95895L,0xbb8cf9b54c96a2dfL, + 0xf43342d440f8618bL,0x58b0d00a8f89a8bcL,0x74d32dbc81f69f20L }, + { 0x5caf0910ab22a49eL,0xa0e9a677ff372f3cL,0xec90b5aef5c05066L, + 0xe2d98821b663f0e1L,0x388804bf50c7abc2L,0x2fbab16e97ba64d3L } }, + /* 34 << 371 */ + { { 0x09138c6071ed8d4eL,0x994d0fa991ef82b1L,0xe6089dbb931f3193L, + 0xb3b229d0aac23611L,0x52cf03fdacb8affeL,0xf64f9872bd99d6e2L }, + { 0x52ebb8b40186279dL,0x36a2349fb09efd7aL,0xa85b5d802225772aL, + 0xd2dc3c1547522562L,0x659297a666471319L,0x65913b608c8e7b68L } }, + /* 35 << 371 */ + { { 0xd54591f9a713f82eL,0x0ecfcffc6fae64b7L,0x7df9d7ea7287e218L, + 0x8b260162abe71460L,0xf75097efb12d48beL,0x82d5902482581904L }, + { 0xc5c0b5dc400d4288L,0xf6493c78190f768cL,0x1844b5f895bc9fccL, + 0x24afb04ba615bff9L,0x6c9638ee8bf51197L,0x38bce012b9ab9fcaL } }, + /* 36 << 371 */ + { { 0x087a2790494efdc0L,0x0b5f23c9e1645cb8L,0xa6e1d1e8193a99baL, + 0x0d324e67c0e0c026L,0xa86d993820d608b5L,0x48ddfbfd8d6944dfL }, + { 0x6aa07f90d371864eL,0x5cf727eef2060df5L,0x7694e02c9a7cf2d0L, + 0xe091982f6260f63cL,0xd2d481a72cae5da6L,0x045e3685ebcb4172L } }, + /* 37 << 371 */ + { { 0x1765632323c82633L,0x5de90578d590cdd3L,0x5cc5e7b9525caf0aL, + 0xdd9be80dd53e825aL,0x9ed28b29949073f3L,0xd15024156a6ce0bcL }, + { 0xbc34beeabf355f49L,0x73724878d2b210ccL,0xe47b7af911e8122dL, + 0x381a4cccdf53a9eaL,0xaa22c9b229e8a466L,0x7a05e2081a4fa093L } }, + /* 38 << 371 */ + { { 0x3dfb53521830d848L,0xea183d5cd2820590L,0xc83a65bcabbeb376L, + 0x5d9ca4d189bb9ac9L,0xb32217be137c900aL,0xcc40daebb0827afdL }, + { 0xc76130060c58b0afL,0x39f4ed8adf32389dL,0x04a586e2bc1fe9f6L, + 0xcf018c2abb50450eL,0x5072b8f016d55d0dL,0xc3c72e90d59e1dbdL } }, + /* 39 << 371 */ + { { 0xb3291b4e50b4e9f4L,0x79a2e8121b7b9e08L,0x81855db1ddd5f0adL, + 0x91fa12fc884392e5L,0x6373de02291c5694L,0x15c77432a7171428L }, + { 0x6016a06c1132df9eL,0xa4286939a0c21c8fL,0x70c5ebe26dca3f37L, + 0xc5278c510f115497L,0x8f5b07a35ce1953cL,0x4d75c1dc41f6ac0dL } }, + /* 40 << 371 */ + { { 0xfeac8e8ac24002e7L,0xa43892076643fa6aL,0x06e7ed63daa68b52L, + 0x8580bbd5d8c7b952L,0xb17ce22410c8fe9dL,0x40266bd379b88ceaL }, + { 0x32afc840dd63ffa5L,0xb4a3eb27a2280b83L,0x90528bf685897e28L, + 0xe4612391d231f941L,0xa7b3a2ccacb5c909L,0x2606844e5558d57aL } }, + /* 41 << 371 */ + { { 0x49ad52380519dd66L,0xe1b0b03b3c1470f4L,0x15e42792cd3a4852L, + 0x91c954b7388ba040L,0xe9fd8c7f857711f1L,0x8552d3d44b63a36dL }, + { 0xbf867fde230ffab0L,0x362a32a0793f885dL,0x687802cba11e0225L, + 0xd95b073b308c1972L,0x13b104aa6b3e5120L,0x60bef12333673f57L } }, + /* 42 << 371 */ + { { 0x4c4cc5561c8a5d9fL,0x5c6e1fd52b8a42c9L,0x73fd66c44ccfa024L, + 0x73c777563c50d038L,0x26964a68a5076758L,0xb14cdbfa7484d080L }, + { 0x24c499cf3f4b92ccL,0x40c8c0d84682daa1L,0xaa156edf785561beL, + 0x36718fb6de75af0aL,0x4d391cee03f5b180L,0xcf28d08a3100efc8L } }, + /* 43 << 371 */ + { { 0xbf1fc9fdd113a97bL,0x19cee87f5ff5ff3cL,0xfc140acf8f8213a3L, + 0xe70d50d546127d5cL,0x78cd24032faa7ac9L,0x409675f1c1808096L }, + { 0xaa7b6cd91765da93L,0xc0755b924f508d86L,0x09b8fb7640169a6eL, + 0x9ca977e52e7da664L,0xee1aab6c9a9616daL,0x54d740391ca0f4fdL } }, + /* 44 << 371 */ + { { 0xfe011830c37c7fc5L,0x0b2b965b2ee958c7L,0x99fd253588a43cf6L, + 0x6a73d62dbf8dc33aL,0xd53c0241a99247deL,0xb8186dccb4127f94L }, + { 0x86c4c274964cc3d3L,0x2f3f2742cbfa9429L,0x5b4bd23c5391abd3L, + 0x030b211bc5838fe2L,0xd2263dc4ae2e36fbL,0x45583a3ca0bf7280L } }, + /* 45 << 371 */ + { { 0x9ce7f43f1ed3f49aL,0xd8094c4afcdce20cL,0xd8b423d12b37b162L, + 0x332ce47c53d90a7dL,0xc686fc0c94a38ff2L,0xb44938d6c33d842eL }, + { 0x5ed14772cd9b0002L,0xffa5d063e800c655L,0x4511ec79ffcb6120L, + 0xb8c9de3f9da8e70dL,0x4d0759ca952b0ef7L,0x685f7005dfd88f4cL } }, + /* 46 << 371 */ + { { 0xcbdb755f1dbdc85dL,0x63d0d7047961be6aL,0xf65af35d8220a1b3L, + 0x8dcea7df77db51b3L,0x8cb2c5d14bfe8fbeL,0x740579bdee2f03e0L }, + { 0xa7eeea4ed3f0181fL,0xedbdfaa3c12ef399L,0xee3cc40f1c332118L, + 0xdae0995e731ef93fL,0x05165c6c0f24d954L,0xcbcc014219fca63aL } }, + /* 47 << 371 */ + { { 0xff24bcd842c7c110L,0xa5ddfffc56dc10c6L,0xb9937fcdaa1a09c5L, + 0x8e18ed5b852dd22fL,0xf24e43c7826fb5a7L,0x13989a43415c2c63L }, + { 0x71ad7c21d36ffe0bL,0x68b77701129df418L,0x1c5324cd9a8d424aL, + 0x2e2a2b1ba9bf46abL,0x7d0c04d19cd0ea12L,0x8b4186bf2f9869e8L } }, + /* 48 << 371 */ + { { 0x6c8d97e075a46271L,0x0fa0c4cd9dbed39fL,0xfb6da5e2de74ac6cL, + 0x041ce886c17c1ec5L,0xb42941a8d7419105L,0x79768eee002fdfd5L }, + { 0x64849afd88c8111fL,0xf425fe14814192d6L,0xe916e8640448fd7eL, + 0x31e224ad72ed351fL,0x73e6e6ac7c0183c1L,0x375657c621bf7cebL } }, + /* 49 << 371 */ + { { 0x093d8039114fd7b9L,0xb6bed3eb45c5e1c7L,0xb73ab7fe50fdbf14L, + 0x68d95e57af0cd23dL,0x5c260eacc7b750fbL,0x79bb142bb5358c26L }, + { 0x5aa9845158ace251L,0x04b2388637dbfef5L,0x1051172dc0532263L, + 0x686ee9e6294890d9L,0x092617b3bffd1609L,0xb4a50e50ea3836a4L } }, + /* 50 << 371 */ + { { 0x8bdb3886cdf950abL,0xe2bdc8d3d595dbd5L,0xd28211254ecc49f1L, + 0x946566081d3c2f24L,0x8124ad390c87df6dL,0x6020c322d16272baL }, + { 0x2150f7e694af134bL,0x38512401a1a14e33L,0x39a54386b1ff7304L, + 0xfaf1ffea078d8f0fL,0x7739ea99dea995bfL,0x3252e815c020816eL } }, + /* 51 << 371 */ + { { 0x1609832322f1bd8dL,0x6b02533cd4df163fL,0x25108619a8296363L, + 0x373bf9988f8c755cL,0xebfbc5b23b32542dL,0x7ada597688b9d360L }, + { 0x3914406ebd605f01L,0xe245ba48cb3a40b2L,0x11a1dc4ed3171f32L, + 0x4a10d5d26ffb5915L,0x9326b23e997460b6L,0x53ddfee92aa0c77cL } }, + /* 52 << 371 */ + { { 0x44f51dd51104ed7fL,0xfca4773e270f6135L,0xe36c8b266bc757f4L, + 0x2cf0515d6941c7a0L,0xdeab655d5fb16e2aL,0x75c28116cff7be07L }, + { 0xb24ca428abbbca02L,0x6aaeca9b1e7f8116L,0x4252f4c3510f0c81L, + 0x01462d856f3ff7fcL,0x4df702879d1c25e3L,0xddd47a1dbebd1559L } }, + /* 53 << 371 */ + { { 0xdffaef2c6f2e2611L,0xc2c2e6a41f29efa2L,0xa29bc3b75ebb40c9L, + 0x8473594bac31a2c4L,0x100d7d6a8604447aL,0x80318670794bbab9L }, + { 0x78979f72054dfc75L,0x94b4c17e55232511L,0xac44836b78b883c3L, + 0xc1f7e98168422328L,0x34fcdee68266747cL,0x18533b3f0475c011L } }, + /* 54 << 371 */ + { { 0xede6728e3bab17f0L,0xfcd9c96879b94302L,0x6410ae37544a677bL, + 0xeacbf6de1dcd0fdeL,0xdae70841e2f3ac0fL,0xeea2a9b6e41ba13bL }, + { 0x1b06aeae9349cdf0L,0x28571e3d33c0ea87L,0xceaf9dd46043e874L, + 0x32cbcc69fa6fea15L,0x7db75664e135aa11L,0x588d4458f816929aL } }, + /* 55 << 371 */ + { { 0xf70797d02b014160L,0x1ddf312d8d7c3263L,0x3bdd58f3c78beacbL, + 0x8bccd90101c71f77L,0x3c637f58166c1486L,0xb62c0aa45fd1a307L }, + { 0xa68db7b05f2544d4L,0xb9727946f860585aL,0x91565060a068412eL, + 0x1283d6d1ab536c42L,0x86c2a11c79caa387L,0x2687309b62bd7797L } }, + /* 56 << 371 */ + { { 0x525cd8849b711a38L,0xd413d82b8c95bf61L,0x19ecc14a36b82970L, + 0x65190ee6e3416342L,0xde9834c93066fcf7L,0x3b87b15e8302cd85L }, + { 0xec6f67a785268eb2L,0x5ab08b5af95aef07L,0xb5257f70adda86a5L, + 0x53e95ec4b934400aL,0x9611a632c33b870bL,0xd27929522723a3d5L } }, + /* 57 << 371 */ + { { 0xcd203b542c95b469L,0x89b140e768713ca6L,0x451646a165701050L, + 0xb97a582575e54715L,0x070fabaa93bb6a91L,0xe517e07a196421b3L }, + { 0xc8d741235f46e495L,0x920ee94fdf60eb8dL,0x885b86dd19564c3eL, + 0x6c9e973231670005L,0xb52eed1fe4893763L,0xa8f9fbd759157417L } }, + /* 58 << 371 */ + { { 0x0c41f2eb56517cafL,0x47778a92798cf8b0L,0x4232ab390dc60cecL, + 0x5de0b7e39e3eb6f1L,0xa2569d8571562511L,0x37b3c62a1ce1cec9L }, + { 0x312caccd8b3391aeL,0x6b22c9447dcbe533L,0xc890d22f4fefd4edL, + 0xd1504f7df007a64eL,0x117e4e595845d5bcL,0x999386c7723584e1L } }, + /* 59 << 371 */ + { { 0x02c396533bdadbd5L,0xc07325fda1fe704aL,0xf78d7e23350aa0c4L, + 0x9f09cf22ce50784cL,0xcdea9a6a1a6e8abcL,0x245fba06ee5a5e06L }, + { 0xf1fd3b9b4a3d0d7cL,0x24c65a131a4952c4L,0x40ea3ef37236b6f4L, + 0x60aa573d8f7addcfL,0xdd5ec47b0305577dL,0xd92dc5035deacea5L } }, + /* 60 << 371 */ + { { 0xc666f8f3fac2de80L,0xabb2b8aba8fa36a6L,0x1bd0ec8f12202b09L, + 0x88b184be6d17a3c5L,0x00d501fc670a77c1L,0xe1f94f1db3de1c7eL }, + { 0x953179cd2d6de8caL,0xa8873a5bb9263791L,0xd76433098d7ac5d1L, + 0x3d751cab4d2f8224L,0x7417b8262e5458eaL,0xf4eb3c669e454a8cL } }, + /* 61 << 371 */ + { { 0x65b0d7e9ae3284a2L,0x3d4770bb1e3cbb18L,0x217a0cdb808ea164L, + 0x9ed6d0f689810270L,0x62d9cc95f14139e1L,0x4d39eeef6a2c82a0L }, + { 0xecf319f40dcf14afL,0x62c95df6ab0fd145L,0xfe85014d22db0105L, + 0xc37756e6a652168cL,0x6ba9f6b370a67e9dL,0xe453fd0af18d8058L } }, + /* 62 << 371 */ + { { 0x265798acfe3bf4f8L,0xc1603abdc1183f63L,0x14e3952f1063e086L, + 0xdcb106d2910f0a78L,0x27c2aee2f454f625L,0xf16d83e60f463fe9L }, + { 0xaa5547207f5ae172L,0x42ea8fea9a2133eaL,0x9f3b33f6e9253e7eL, + 0x6224ef75d67af0afL,0x06f0ddfbb92d6cc9L,0x12e66e32656e9e9aL } }, + /* 63 << 371 */ + { { 0x1a93be3424ace7f0L,0xb993bcb9a56be2eaL,0x3b054afac33608d7L, + 0x36e782c3aea3d7e9L,0x54f1dda950e9b3adL,0x04dd021f55f51bb4L }, + { 0x9c76f7c0347bb352L,0x3d9a04ee2f1dc5fbL,0xea5e582ae80e06f0L, + 0xe523aab927e1e818L,0xe2f1960252d4904cL,0x1bfa8b03adecc51fL } }, + /* 64 << 371 */ + { { 0xc84f917203bdf6d6L,0xcfc4718769f60e03L,0xcdc4753ba05068eaL, + 0xa177ad14077777efL,0x0b7f54eb7e4cf44aL,0x4ee443f91860144eL }, + { 0x1279ed4d42bb6a93L,0x511137d7436c1b54L,0xebc958fab8cdb6ceL, + 0xbc4f93f4a0c7614aL,0xc5bd6cde7b2c6d8eL,0xecff7dd78d65f38aL } }, + /* 0 << 378 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 378 */ + { { 0xffec6674f65de0f5L,0x4043079cd23ad193L,0x31811365ee61bc95L, + 0x358bbd6e8948b6e2L,0x1cd9c342e31644beL,0xbab3aa8c60a8a7a7L }, + { 0xe065519fa375beb6L,0xf7d0b0414439990cL,0x8957c03b8517ae8aL, + 0xc96a040173750d6eL,0x4eb2e364b2aee6d7L,0x813054feed099114L } }, + /* 2 << 378 */ + { { 0xbb39a17a7c34f095L,0x7be330a822fbbe61L,0x6be6abe3b91f1482L, + 0xf972804fbd39a2bcL,0x06737e54f91d813eL,0xbd6066681a87cd4aL }, + { 0xbf88b2e5f538d56eL,0xb8206a8134afd68fL,0x7a93aedfa58af042L, + 0x8853cdf6ac0511b0L,0x9d7f416d067e2c19L,0x5d0bc923f9671d8aL } }, + /* 3 << 378 */ + { { 0xf3b6fd79dd3532a7L,0xf60262b5dbbb9e4cL,0xbf75bb57da4d6ac4L, + 0xf016adf1c094b38cL,0x9114cdd012def474L,0xdc74d638c785f143L }, + { 0xdea060d6a8d90bbbL,0x1f141878cbcd0d4cL,0x552685b79ddee1f5L, + 0x381dfc0c636ea6b6L,0x8c601615cb08f34fL,0x5b843830271041eeL } }, + /* 4 << 378 */ + { { 0x2e7d0a16204be028L,0x4f1d082ed0e41851L,0x15f1ddc63eb317f9L, + 0xf02750715adf71d7L,0x2ce33c2eee858bc3L,0xa24c76d1da73b71aL }, + { 0x9ef6a70a6c70c483L,0xefcf170505cf9612L,0x9f5bf5a67502de64L, + 0xd11122a1a4701973L,0x82cfaac2a2ea7b24L,0x6cad67cc0a4582e1L } }, + /* 5 << 378 */ + { { 0x139d9fef6bfc08e4L,0x4399615939ffcb3bL,0xaa299008a84ace07L, + 0xfce43e873cbb2b3fL,0x07b3e8b9191a320eL,0x3ec851d706c4d485L }, + { 0x03d8a672a4bb8477L,0xb6a5dcb213c31d5cL,0x58b79d01c439ab23L, + 0xdd6f8b5134f66137L,0xccb178a0b29be48cL,0x4c71b7aa4df8a1b2L } }, + /* 6 << 378 */ + { { 0x92bf8c4508359896L,0x77253434ae2c30f2L,0xf05086ec827e6cf8L, + 0x46d4729f1771c5d3L,0x92587306f37f0bedL,0xb82c99d2e7c30180L }, + { 0xee0141dcb1684841L,0x7fa984be994ddaf5L,0x5c583347165c238cL, + 0x1a1ad3eea5d78204L,0xcfed795f2736bce6L,0xa7a413318961204eL } }, + /* 7 << 378 */ + { { 0x87451ca71400851dL,0x3aace28e3573ecf6L,0x3a5902cee85717c5L, + 0xe4b51dd0c9f57944L,0x33cf684789a9d8aeL,0x2f6fb08031e6e769L }, + { 0x4bf3da323b78dad1L,0x2d73fef4e7809638L,0x84d76151965109abL, + 0xa2c932c9a2098f46L,0xb8c457c3bc17d1fcL,0x5ef2562d0c8012a4L } }, + /* 8 << 378 */ + { { 0x96a1e74f51e4de5eL,0x72913696e37f5006L,0x12449c4fbe35109cL, + 0x1fad8b304521d7e6L,0xc85eb23d57d00293L,0x4ebd334b35f68229L }, + { 0x7c5b86682df5acf1L,0xc2b4da6e5463de2eL,0x067b0456757cd570L, + 0xeaab81be3a1c866bL,0x72a6af75bbba88c0L,0xaed4dbde0ef567dcL } }, + /* 9 << 378 */ + { { 0x085e33cd9273818aL,0x8fb9294a8cf4e306L,0xaed46bbc35052bd1L, + 0x031febb3374661eaL,0x9386a35d4868dbb2L,0x381e5b521d3f2dddL }, + { 0xa938a3a5179617edL,0xb0fc99f49dc95af1L,0xf446dfa92b9dacbcL, + 0xbae262ae490c1969L,0x042707ffa7443354L,0x8dc0511f267d5c14L } }, + /* 10 << 378 */ + { { 0x8f0e1908fac2674dL,0xd86e85a483e43c26L,0x1f719f7036fb5a4eL, + 0x7ad61b8ca57dbcbcL,0xcf6ba7db0f63dc79L,0xb4315ab11afe8540L }, + { 0x0448e852425c4df3L,0xf51969ef8838a51dL,0xce98589b9eab87deL, + 0x55867b5645149689L,0x9b70bc8c60d2a624L,0xc158a2710b6dbd45L } }, + /* 11 << 378 */ + { { 0x0b262f808f1915f2L,0x64ba3bc73d501e01L,0x8ce2db1f4645152cL, + 0xf4a4f3afab047cdbL,0x1a7c4af600d31e7fL,0x0005bca678d1c0ecL }, + { 0xf5ed135f6fe5ebb0L,0xa299b1002ea9abdfL,0x4fa387e5fccb58f5L, + 0x105b9dd2fc657b72L,0x1494c6050dc3c22cL,0xf7468e8a92d281c7L } }, + /* 12 << 378 */ + { { 0x597a26ffb4dc8600L,0x264a09f3f9288555L,0x0b06aff65c27f5f6L, + 0xce5ab665d8d544e6L,0x92f031be99275c32L,0xaf51c5bbf42e0e7cL }, + { 0x5bb28b061e37b36dL,0x583fba6a8473543aL,0xe73fd299f93fb7dcL, + 0xfcd999a86e2ccad9L,0xb8c8a6df334d4f57L,0x5adb28dd9a2acc9bL } }, + /* 13 << 378 */ + { { 0xc760823646dd14f3L,0xc6d97d37e7a97f33L,0x05037f26de2f444aL, + 0x5267ded09aa9a5c0L,0xd1ef46340be2d841L,0x308b37a8d48b9574L }, + { 0x102f7878487bad5bL,0x1d5169d938b7c1efL,0x2d8adde62c39c75aL, + 0x71bfb8bc0b80f3bbL,0x126505999bff252fL,0xf99e952f24f8bd3bL } }, + /* 14 << 378 */ + { { 0x24496a8b7a8a6d47L,0x9fc75c0aec6afe43L,0x4200e00670744f15L, + 0xe2f87d5e2973be1dL,0x0f6c5993c82e2013L,0xe9ecf6ce198c99f0L }, + { 0xcbdf72058b37d828L,0xbef4b8c8325d1d93L,0x8e962ffbd0fbb134L, + 0xe4273a124bcffc61L,0x4f24ba23f3d93d73L,0x8f02df83bcfcb930L } }, + /* 15 << 378 */ + { { 0x985c8f4b0614348aL,0xca4ca7cd5a03c014L,0x5bdd4382a7b62effL, + 0x623d44b9e4a0bb42L,0x1f28862ef23931d5L,0x30568303868326beL }, + { 0x850d2a0d82e76f04L,0xf4dc02330ac4a153L,0x62b74879b1e70a9aL, + 0x7b32249baf3f0dbbL,0x2f50395d155eae92L,0x6d990c16f6f5c9a4L } }, + /* 16 << 378 */ + { { 0x3afdee277d221ab6L,0xecf10abc47bb619eL,0x340c8ee3ba4a3301L, + 0x1a6ea51a2a883b7fL,0x64f27976d5d7412bL,0x7fcf0ecc91251b6eL }, + { 0x5f3f8f41365b18b7L,0x38e48b96e2e13e58L,0xde3b73d6ad61b2cbL, + 0xf08398d5d542676dL,0xd373931e8e7d712bL,0x89325d7a7f96e023L } }, + /* 17 << 378 */ + { { 0xeb2e48c10bf4e94dL,0x00614bf206b7e166L,0x536c999ce295c451L, + 0x951f92186359cf06L,0xe2a938890afc827fL,0x63102e93ff029787L }, + { 0xab297c7d2ac89645L,0x7354df74928742bfL,0xc0934ca6c8604304L, + 0x36b7e9711cc2f3b4L,0x487ce890e10ee837L,0xe6aa9eabae2ae9e3L } }, + /* 18 << 378 */ + { { 0x6e7a578340517347L,0x7db868f3a950dfa2L,0x7fd7fd8eb3c2eff7L, + 0xae7b59c5fbe10a47L,0x5239b5c4109797d6L,0x3838356a53264b8aL }, + { 0x8df8454c320a8c5aL,0x67c86ef46958fa2cL,0xfe1aad846241a50aL, + 0x3df64ef5a06f3cf3L,0xde6af0ff83282fbdL,0x25ca45046cdbe5feL } }, + /* 19 << 378 */ + { { 0xa319340d6e6c0debL,0x101f055acb1b1cd5L,0x4bea31ad623e7e55L, + 0xc0c88af6aec23cd2L,0xca98c4364aaf2f73L,0x1969eca437dd1341L }, + { 0x6b03989f97866dc3L,0xafdc99532eaf5b08L,0x199ec0e93d6ea9c4L, + 0xc3d1069474f262e9L,0xa7e5670079911cf9L,0xc0213ec56844da05L } }, + /* 20 << 378 */ + { { 0x5adf3d9a111792b9L,0x1c77a3054f1e0d09L,0xf9fbce33a82d3736L, + 0xf307823e718c8aa3L,0x860578cf416ccf69L,0xb942add81ef8465bL }, + { 0x9ee0cf97cd9472e1L,0xe6792eefb01528a8L,0xf99b9a8dc09da90bL, + 0x1f521c2dcbf3ccb8L,0x6bf6694891a62632L,0xcc7a9ceb854fe9daL } }, + /* 21 << 378 */ + { { 0xfc9660a3c8808373L,0x84c5d6a71a50c560L,0x13fe0588ba057fe2L, + 0x29b0341dafb73ad1L,0x37b11137f15f0cd2L,0x84422ba89c2d7eb0L }, + { 0x0b595ac52554ef7fL,0xd7a8303f08b37a84L,0x908895a9e02d77fcL, + 0x70cdeb0c9f242a42L,0x535e8540116e2db8L,0xc88f0cf685c54d31L } }, + /* 22 << 378 */ + { { 0xf534f145e2290ebaL,0x3d081c0d7f15c9e3L,0x716574c5e9ae3da0L, + 0xbe6bd7b92c078aa8L,0xab8802bab8da8e68L,0x0c5be4a1ab204fb0L }, + { 0xad25c5ee0d3f12b3L,0x3929d0d78fc9b7a5L,0x9c6e2ce0bb5cd2fdL, + 0x855367c4924ec2d2L,0x6b532891e6550d3cL,0xab2bc89575ba5c99L } }, + /* 23 << 378 */ + { { 0xb56b035e2a0349adL,0xcfa41da6f89ce836L,0x9d86bcac8b5c43fcL, + 0xc77375da47644b07L,0x9e9c222607f4b670L,0x71d663c80482a61bL }, + { 0xb423e739ef237431L,0xf1cedf7e48832b5bL,0x09e0cb2a7ca7548bL, + 0x9b463559631b9850L,0x8a2bd7fed4dd03deL,0x46115292ae0c97d3L } }, + /* 24 << 378 */ + { { 0xe44e3f864b3759cfL,0x90cab0eb9d74e3f6L,0x1004254501c4e171L, + 0xc12df68cce52defbL,0xb1fae2fbf363100aL,0x5016c8533573235fL }, + { 0x8d4deb661d922e9bL,0x8a20d42317f84ef2L,0x324985835a4e118eL, + 0x5abfa961308772e9L,0x41c7611ff54e4876L,0xc1da40d31f5867b2L } }, + /* 25 << 378 */ + { { 0x4df02a7d3088aebcL,0x7dea27ea12487485L,0x2a773270df98069eL, + 0xea435fa0e9ceaf44L,0x08e952e365e5ebabL,0x972877d5c3511480L }, + { 0xef5685f859a04cd0L,0xe50abe68b8c7c796L,0xbbb792e2c3225f20L, + 0x7d9878e811c89153L,0x4b72a1e619354751L,0x7d5f05a3faa1be22L } }, + /* 26 << 378 */ + { { 0x61dd7692f27eed54L,0x8540213ea7a3f2f7L,0xe659cbd6ace07e13L, + 0x3a998cdcc8995cacL,0x0accb4a7922d3b25L,0x762b3406c6577d81L }, + { 0xa09db4f57e043740L,0x7f78e02d8cc9bc5fL,0x080a522673b98cd3L, + 0xb6d72f7ce6490808L,0x36815de2c724284aL,0xc27d13df98b867b5L } }, + /* 27 << 378 */ + { { 0xbfeffd5356adb6e4L,0xb5e8876c499a1455L,0x4771281390833f18L, + 0x5f49ef880115b9a5L,0xb041ec67cf575de5L,0x490753350b7e4afcL }, + { 0xad4dc4a15f0b9f24L,0x9dbb181edafad9a5L,0xa84431a6e6ed5198L, + 0x33ee16e27993eed6L,0xfdf76899c1e4f8b4L,0x868d06baff60e943L } }, + /* 28 << 378 */ + { { 0x46303171491ccb92L,0xa80a8c0d2771235bL,0xd8e497fff172c7cfL, + 0x7f7009d735b193cfL,0x6b9fd3f7f19df4bcL,0xada548c3b46f1e37L }, + { 0x87c6eaa9c7a20270L,0xef2245d6ae78ef99L,0x2a121042539eab95L, + 0x29a6d5d779b8f5ccL,0x33803a10b77840dcL,0xfedd3a7011a6a30fL } }, + /* 29 << 378 */ + { { 0x5d782a0778664144L,0xc1413da46682c779L,0x937a15f52a67b12bL, + 0x8ec00d9fc04d8cd5L,0x3f16d1ed3b5fe8d6L,0x24ad6b0ca28c8067L }, + { 0xdd1eecc532732b19L,0x62c4c2beab2fa785L,0x7d863f5b2ac0c238L, + 0xd686eb7239384e15L,0x3770e54d16bd75b2L,0xdcd9e4e8120b3881L } }, + /* 30 << 378 */ + { { 0xe3052838df5147e1L,0x87bc4d75b1baaa7cL,0x49b13eb95acc5572L, + 0x919081881990c13cL,0x5d43a4a6191cc808L,0x20b358444182aa55L }, + { 0x70d49a4a670b1fd1L,0xc6e6e061722e91e7L,0x8d130b3900c5ae9eL, + 0x5db7d06920f68ec5L,0x85b6c505470fbe13L,0x14101ec7326c4d38L } }, + /* 31 << 378 */ + { { 0xeef03450e10e8018L,0x75921e487576c3ddL,0x6c8e22676e97f5afL, + 0xd7323e01a856ae6bL,0x43a195425fed884fL,0x010865380377ba8fL }, + { 0x7cdbd06ac82a8f67L,0xc6fce58bf0fd4281L,0xae098b7f9e67bed0L, + 0x0c8d328bdd918524L,0xddf723ec0a11fb83L,0x210d6016e25a2073L } }, + /* 32 << 378 */ + { { 0x3c90a59f85adde98L,0x35414174e5269140L,0x9aca885c1a0d58e2L, + 0x77b9b6dd6816b009L,0x8e5c12139ee4718fL,0x60ad991e4e4eac45L }, + { 0xc00c35694d71f624L,0xacbf4eb25bc5fd2aL,0xcba1ffc75eaf3eaaL, + 0x5f99092d42a87e32L,0x2e7b49c76f7a882fL,0x5e9bfc5c29040512L } }, + /* 33 << 378 */ + { { 0xa31d3524b295958dL,0x9713a5e04894f486L,0xe8804ab3329a0b9aL, + 0xd4447c1b20eefa54L,0xf5b944c9040b7ad4L,0x9db0ee0b907f2cfdL }, + { 0x0b1a1f3a5384a999L,0x3137241ea8351764L,0xe0663b5ab29c3cffL, + 0x2b47ca0622d4deefL,0x4f952109f1172bcdL,0x1e7a7fca9b447bd4L } }, + /* 34 << 378 */ + { { 0xc9898355ecf2a473L,0x20d0c4740dcd66f6L,0x6459720f8eeefff5L, + 0xd9b625dcf9ce0cdeL,0xed3a6508ea56be90L,0x6847c20de211c90eL }, + { 0x36d86bed71a73ceeL,0x9222eab23023d16eL,0x3155874750209b4dL, + 0xcac8f277d145b831L,0x49cedc634470e754L,0x6c7c065add370f77L } }, + /* 35 << 378 */ + { { 0x46a95735f8171804L,0x1ff2549ec4c93476L,0xfb8a08285bb5202dL, + 0xaff5505f1070737aL,0x162aaad842f412c5L,0x02a37213fac8a477L }, + { 0x05ff9238932f08e2L,0x9be6a0b29fc66787L,0x373a9039db1e5a40L, + 0xe657e8c782d04913L,0xa2006f207e6ee867L,0xd7aa1d2378d82f9aL } }, + /* 36 << 378 */ + { { 0xfa070e22142403d1L,0x68ff316015c6f7f5L,0xe09f04e6223a0ce8L, + 0x22bbd01853e14183L,0x35d9fafccf45b75bL,0x3a34819d7eceec88L }, + { 0xd9cf7568d33262d2L,0x431036d5841d1505L,0x0c8005659eb2a79aL, + 0x8e77d9f05f7edc6aL,0x19e12d0565e800aaL,0x335c8d36b7784e7cL } }, + /* 37 << 378 */ + { { 0xdcac39d87c1d9f4dL,0x88322d8bc225ce6eL,0x5c240cefa3ef5202L, + 0xf60ce5d991f1d487L,0x8e857069e462cfa8L,0xa6e5585e996d2033L }, + { 0x709675a556281e6aL,0xcd90c140f907ebf0L,0x5343a0a2a3231eecL, + 0x74b1443214892291L,0xf8cb9c26a5325b8cL,0x1bb28be140089be5L } }, + /* 38 << 378 */ + { { 0x2bb6e7ec3092d0b2L,0xc7c9e5f1d27d1f31L,0xbac785aeac0939e3L, + 0x186d3d934f810d8fL,0xda296dacfe7d778fL,0x6189f5e41a991ea2L }, + { 0x098f794e9634363eL,0x04aaf59a88a4dccaL,0x09d718487196dfa8L, + 0xa447a31ed83044a6L,0x720cd3908d1363fdL,0x6f670479e22efa03L } }, + /* 39 << 378 */ + { { 0xaa452e81cdf60f9aL,0xf3dc472a8e2c58e9L,0x16ddefa50589fd01L, + 0xd56ec8f223a1656eL,0xcccb784f77921ca4L,0x9bace7adf8a7c0baL }, + { 0xc94ef3ef51f052e2L,0xa70c0579c34e7cb5L,0x3599817883ce8674L, + 0x033647c392a20951L,0xc828fcc77a21add6L,0x5a446de871ba27a5L } }, + /* 40 << 378 */ + { { 0x75cba9d530a3ada1L,0xb69e308bf8ae9565L,0x990e3425ca7b8369L, + 0x9f67567fe0a7ad0bL,0x76ed6fe718bd01b7L,0x282358aa2ff95cfeL }, + { 0x28d2ea41410f8841L,0x89d1533fccd67c81L,0x969bb272b6a7b8f9L, + 0x54f8664c26330782L,0xb89f3ae81dcd9164L,0x54d845b93d962c14L } }, + /* 41 << 378 */ + { { 0x08ba5b61fde4ca03L,0x39b1a9c697b17ee6L,0x885253779336b2b9L, + 0xe964dc9c9aabc3fcL,0x6aed101a5295e728L,0x30369ea0ee12356aL }, + { 0xe081e022c8e80e5eL,0x3a769ef0df9f47c0L,0x3b2f7aab5590750cL, + 0xd16c7a85a1a5e504L,0x9e528623e854d7cfL,0xaca079354468e419L } }, + /* 42 << 378 */ + { { 0xee521c0af93098bfL,0xf517c925b79aa0ebL,0x17779f5e7bbc58feL, + 0x093c3dc2769de891L,0xafbf32372a69ad0dL,0x33a95de702001e8cL }, + { 0x3b30afc73410a2b0L,0xb379a3f425bc7d9aL,0xf1c069251604a646L, + 0x04f0bb334fca052fL,0xe5cd9c39cab33871L,0xf259795816fa1b16L } }, + /* 43 << 378 */ + { { 0x291d65c801189d9aL,0xb16ca18bd8e94e49L,0x55f7680599440d4bL, + 0x55d40c1b2eb7f0fdL,0x752d98f6018d7c64L,0xa1cae78c7b491c4dL }, + { 0x898fc8c78f66b8d3L,0xbb48956a3ceecd27L,0xb8f9498dfaa9451fL, + 0x583b336aa5683ef8L,0x0deaa373e92656f4L,0x7f87b4412a9a0272L } }, + /* 44 << 378 */ + { { 0x8b2fc4e96484fd40L,0xee702764a35d24eaL,0x15b28ac7b871c3f3L, + 0x805b4048e097047fL,0xd6f1b8df647cad2fL,0xf1d5b458dc7dd67fL }, + { 0x324c529c25148803L,0xf6185ebe21274fafL,0xaf14751e95148b55L, + 0x283ed89d28f284f4L,0x93ad20e74cbebf1aL,0x5f6ec65d882935e1L } }, + /* 45 << 378 */ + { { 0x4b0c7d0c69c284cbL,0x907e4f38199c5176L,0x4ebfbda7cf3dab12L, + 0x675f12cca4fa74a9L,0x86628102bdf579e6L,0xf08cbfe771c4d061L }, + { 0x9dde390e03bc1cb9L,0xb6d0d48b4c727915L,0x7cad28c370c0b7bfL, + 0x8d978a8110d1e881L,0x1c071597924baeb1L,0x83c09192eb103fe0L } }, + /* 46 << 378 */ + { { 0x494dbd2665925506L,0xe239b1d404b6fc45L,0x38a1ec5ce16b874dL, + 0x1588c4712a3f012dL,0x5bd45adcdc6938b9L,0xe4c35c2244ab2fccL }, + { 0x87cbd9ff887108a2L,0x92a9c3b2144fd3eeL,0x3a0e55c7982a4928L, + 0xcaf679765bb0fddfL,0x04616318263ea256L,0x56eb022838caa901L } }, + /* 47 << 378 */ + { { 0x2f7de141a48da000L,0x323bd638835a4edfL,0xd2d9da967e155bd5L, + 0x717c302a766b69daL,0x5927968beb0f6ca5L,0xfd96bd168940c766L }, + { 0xf89f7539a334fd71L,0x4ba9cd8bd870954fL,0x7e639523a3d57aa8L, + 0x88f31e162314c0ceL,0xa836a6ad53b7e6e9L,0xd35a825190e43169L } }, + /* 48 << 378 */ + { { 0xb3984b176c0f3509L,0xf9fa4483d8b4d6bcL,0xf4ac2b677dec20d2L, + 0x67ef024eb3dbe034L,0x2dcc51180f94f4d7L,0x024cdcfd74a51393L }, + { 0xf1c0fead20e7abcbL,0xffc18f81d3a7414fL,0xb00ce5567062cb0bL, + 0xeccb0521817bc8d1L,0xa0c0fe6040411c15L,0x053113221defbe00L } }, + /* 49 << 378 */ + { { 0x74faca8a6af7e742L,0x6f206002d878a97aL,0xd69b7c83177305ffL, + 0x605e7a32d2e2bcf1L,0x65bd03584590bf03L,0xab3ae700d1a378c5L }, + { 0x037e79028a929b0dL,0x83625ae0a7c451c6L,0x82a18f03492b01d4L, + 0x12c6d168e67756b1L,0x1e704c3bd7924df1L,0x7708617f1989244eL } }, + /* 50 << 378 */ + { { 0x4c98c61d097bde48L,0x6a55edf1c354f433L,0x1ceee947c3f39212L, + 0x162cf27f36ba3cebL,0xd9f3982e3ec5f7ffL,0xd363e435d58d42d2L }, + { 0x2ee90d7bad36681dL,0xd916df56ebfbf51cL,0x61d94ed8d7c27fe7L, + 0x5010582e923c1acdL,0x89d23e8b6de52994L,0x0a4f9c10525dbccfL } }, + /* 51 << 378 */ + { { 0x7778fad7e65573e2L,0xa4af7a2d74986210L,0xd78ecebfec57d967L, + 0x9be8a33f67d61b2eL,0x6888444f98a9add7L,0x218e7fb1b71a25a4L }, + { 0xf75a6b795f46323bL,0x2f8610ad11a52cd9L,0x23692f85fc6837caL, + 0x3a37965f71fe847bL,0x29c25cc3fe3bdeeeL,0x68fefc83f624665aL } }, + /* 52 << 378 */ + { { 0xe222eba4a4dcefe9L,0x63ad235fec1ceb74L,0x2e0bf749e05b18e7L, + 0x547bd050b48bdd87L,0x0490c970f5aa2fc4L,0xced5e4cf2b431390L }, + { 0x07d8270451d2898eL,0x44b72442083b57d4L,0xa4ada2305037fce8L, + 0x55f7905e50510da6L,0xd8ee724f8d890a98L,0x925a8e7c11b85640L } }, + /* 53 << 378 */ + { { 0x8357d8bb460e77b2L,0xc749a6a77709a52bL,0x94035a1f0c82ab81L, + 0x15245ac616c11ef4L,0xbf3cd96c034d021bL,0xf79e2d39b2e8fac1L }, + { 0x387015194b6cf1bdL,0x341f9b53b3143bf7L,0xb2584aabdda9acf2L, + 0x16f34bdd553a8e68L,0x89d0c4c5da7830b3L,0x6cfe44c63f488c2eL } }, + /* 54 << 378 */ + { { 0xee536a26d4bcaa59L,0x5ea6a57c699397bfL,0xb28f476b59a7eb99L, + 0xa901f2551406ec90L,0x7b6e3e4d1f54ef38L,0x058ff1904c89c9a8L }, + { 0x5690fa10fca546ccL,0xfe98793145e14268L,0x6181fa1675362f5dL, + 0x3ebe84466964b9aeL,0x3e1957812ce0f969L,0xb33ea619b0195852L } }, + /* 55 << 378 */ + { { 0xeef402410ec537acL,0x1f72c1f8911316f6L,0xab4bb08268cc6678L, + 0x031fc087255e8c5eL,0x99c2ff0b948ac53bL,0x13db3201919c1870L }, + { 0xdec81fd312057a3cL,0xbdffa226ff7a44cbL,0x748d2e93d97167e2L, + 0x33a9fe40bd21effeL,0xe08e4213817ea560L,0x2221798b9f4337d5L } }, + /* 56 << 378 */ + { { 0xda828fe556467257L,0x5e9abf67d640c2a1L,0x0eed233cc25c696aL, + 0x72483dc5b3e1d84fL,0x30bf1ee34f114abcL,0xf58b321ed1f9bce8L }, + { 0xcb26564c97524f33L,0xdc2f105e1e453229L,0x9da43ceb72a982ddL, + 0xecf5649dfeef8862L,0xd8afda341fa2f06dL,0xf0d0ced355035432L } }, + /* 57 << 378 */ + { { 0xec22bb32205a5301L,0xe4d168e75b0b727bL,0x91217a6be34fe2e0L, + 0x03c6831675f0f139L,0xb21e275d8b991b29L,0x7f517c9c01f3f401L }, + { 0xbbe95d19e55e49faL,0xc5470808504514b1L,0xb88be15c7cc1367dL, + 0x242cb06bbfd24bacL,0x08647a158d2ab0baL,0x8f1fd1bd5716ed9bL } }, + /* 58 << 378 */ + { { 0xe787054518ba5236L,0x243622f9e8a47507L,0xe7d94f4697b97d7cL, + 0xb120589021649255L,0x8b5101310dd4e1d4L,0x1690687e164c44baL }, + { 0x65bb4d8cf100fef5L,0xfffffee70a684c3dL,0x2aa11707c463a975L, + 0xccaddeaf391ad03dL,0x4d2cda1c81cca7deL,0x9d3eaa58c5b0f8e7L } }, + /* 59 << 378 */ + { { 0x3d92ecc18f8802dfL,0x3024ce311a719461L,0x6bdf53fc46c1f31bL, + 0x4f4576a12c9c7744L,0xe1ee7508c3ff7356L,0xd4b25ed3883ebf03L }, + { 0x1dc46052420c3ac9L,0x376ebbfa11ecefa9L,0x36e175265e9693f5L, + 0xeb82b33740ed3143L,0x6960312ff19fa66aL,0xc7edb5db6c742e1bL } }, + /* 60 << 378 */ + { { 0x5bfa10cd1ca459edL,0x593f085a6dcf56bfL,0xe6f0ad9bc0579c3eL, + 0xc11c95a22527c1adL,0x7cfa71e1cf1cb8b3L,0xedcff8331d6dc79dL }, + { 0x581c4bbe432521c9L,0xbf620096144e11a0L,0x54c38b71be3a107bL, + 0xed555e37e2606ec0L,0x3fb148b8d721d034L,0x79d53dad0091bc90L } }, + /* 61 << 378 */ + { { 0x4b98cb69c5c8a182L,0x887071bbcac96dabL,0x03d42e96afc190c3L, + 0xbc2c3b8d7a813820L,0x1ee7797f6590d0ecL,0x4a95f7f3ad4777a4L }, + { 0x7a36de4e2a8d2736L,0x7f8c6751ad78dab6L,0xf9874bf6974c0a8eL, + 0x759fee1c8b53025aL,0x1b00fb28a2171c8bL,0xdf206f19be8f2e7eL } }, + /* 62 << 378 */ + { { 0xe6bbcf0bf8ed6302L,0x7734dc91f8fe7a42L,0x840210ee61ff9d1eL, + 0xbbf2d5477007f2e9L,0x0f17d421a6542ac0L,0x0b2d3d2ee01df4e9L }, + { 0x520e4fbb84f3703fL,0x8362f7b1431106b7L,0xdcfc96ae6e50d836L, + 0x2dfa176cc44153bbL,0xeef1c6710b09ffe2L,0x633a2ac888531d81L } }, + /* 63 << 378 */ + { { 0x29262b6d7636a78dL,0xdc504f01d3ce2967L,0xa441e5035bcf0e19L, + 0x8025224f7ad39d9aL,0x780ec65de871b792L,0x977b4bce597694b4L }, + { 0xe05eaeb87fe3ef11L,0x1cff87ac9748b10eL,0xb669c1d60c34153aL, + 0xf5da63e0f8f90368L,0x6f7f2fc47d31bf61L,0x37e9158235c16a0fL } }, + /* 64 << 378 */ + { { 0xcf17f9dc08d1be5dL,0xb55de4c8afdfeb23L,0xa69454ffe437b29cL, + 0x6628d789e27ee9e2L,0x56e3b975ee3af03bL,0x0083fe9c2f532d62L }, + { 0xcae15213e63e7511L,0xdb5384f386ed849cL,0x902ba959fa4d825fL, + 0xbad700d55ae17566L,0x16b2c5dc14c82eb4L,0xa4b057a736708ea7L } }, +}; + +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Pre-computed table containing multiples of g times powers of 2. + * Width between powers is 7 bits. + * Accumulate into the result. + * + * r Resulting point. + * g Point to scalar multiply. + * k Scalar to multiply by. + * table Pre-computed table of points. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_add_only_6(sp_point_384* r, const sp_point_384* g, + const sp_table_entry_384* table, const sp_digit* k, int map, + int ct, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_384 rtd; + sp_point_384 pd; + sp_digit tmpd[2 * 6 * 6]; +#endif + sp_point_384* rt; + sp_point_384* p = NULL; + sp_digit* tmp; + sp_digit* negy; + int i; + ecc_recode_384 v[55]; + int err; + + (void)g; + (void)ct; + (void)heap; + + err = sp_384_point_new_6(heap, rtd, rt); + if (err == MP_OKAY) + err = sp_384_point_new_6(heap, pd, p); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 6 * 6, heap, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) + err = MEMORY_E; +#else + tmp = tmpd; +#endif + negy = tmp; + + if (err == MP_OKAY) { + sp_384_ecc_recode_7_6(k, v); + + XMEMCPY(p->z, p384_norm_mod, sizeof(p384_norm_mod)); + XMEMCPY(rt->z, p384_norm_mod, sizeof(p384_norm_mod)); + + i = 54; + #ifndef WC_NO_CACHE_RESISTANT + if (ct) { + sp_384_get_entry_65_6(rt, &table[i * 65], v[i].i); + } + else + #endif + { + XMEMCPY(rt->x, table[i * 65 + v[i].i].x, sizeof(table->x)); + XMEMCPY(rt->y, table[i * 65 + v[i].i].y, sizeof(table->y)); + } + rt->infinity = !v[i].i; + for (--i; i>=0; i--) { + #ifndef WC_NO_CACHE_RESISTANT + if (ct) { + sp_384_get_entry_65_6(p, &table[i * 65], v[i].i); + } + else + #endif + { + XMEMCPY(p->x, table[i * 65 + v[i].i].x, sizeof(table->x)); + XMEMCPY(p->y, table[i * 65 + v[i].i].y, sizeof(table->y)); + } + p->infinity = !v[i].i; + sp_384_sub_6(negy, p384_mod, p->y); + sp_384_norm_6(negy); + sp_384_cond_copy_6(p->y, negy, 0 - v[i].neg); + sp_384_proj_point_add_qz1_6(rt, rt, p, tmp); + } + if (map != 0) { + sp_384_map_6(r, rt, tmp); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_384)); + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (tmp != NULL) { + XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 6 * 6); + XFREE(tmp, heap, DYNAMIC_TYPE_ECC); + } +#else + ForceZero(tmp, sizeof(sp_digit) * 2 * 6 * 6); +#endif + sp_384_point_free_6(p, 0, heap); + sp_384_point_free_6(rt, 0, heap); + + return MP_OKAY; +} + +/* Multiply the base point of P384 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * r Resulting point. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_base_6(sp_point_384* r, const sp_digit* k, + int map, int ct, void* heap) +{ + return sp_384_ecc_mulmod_add_only_6(r, NULL, p384_table, + k, map, ct, heap); +} + +#endif /* WOLFSSL_SP_SMALL */ /* Multiply the base point of P384 by the scalar and return the result. * If map is true then convert result to affine coordinates. * @@ -43034,7 +62999,7 @@ static int sp_384_ecc_mulmod_base_6(sp_point_384* r, const sp_digit* k, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_base_384(mp_int* km, ecc_point* r, int map, void* heap) +int sp_ecc_mulmod_base_384(const mp_int* km, ecc_point* r, int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_384 p; @@ -43075,6 +63040,87 @@ int sp_ecc_mulmod_base_384(mp_int* km, ecc_point* r, int map, void* heap) return err; } +/* Multiply the base point of P384 by the scalar, add point a and return + * the result. If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_add_384(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_384 p; + sp_point_384 a; + sp_digit kd[6]; + sp_digit t[6 * 2 * 6]; +#endif + sp_point_384* point; + sp_point_384* addP = NULL; + sp_digit* tmp = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_6(heap, p, point); + if (err == MP_OKAY) { + err = sp_384_point_new_6(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (6 + 6 * 2 * 6), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 6; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 6, km); + sp_384_point_from_ecc_point_6(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_6(addP->x, addP->x, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_6(addP->y, addP->y, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_6(addP->z, addP->z, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_base_6(point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_384_proj_point_add_6(point, point, addP, tmp); + + if (map) { + sp_384_map_6(point, point, tmp); + } + + err = sp_384_point_to_ecc_point_6(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_6(addP, 0, heap); + sp_384_point_free_6(point, 0, heap); + + return err; +} + #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \ defined(HAVE_ECC_VERIFY) /* Returns 1 if the number of zero. @@ -43088,7 +63134,7 @@ static int sp_384_iszero_6(const sp_digit* a) return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5]) == 0; } -#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN | HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ /* Add 1 to a. (a = a + 1) * * a A single precision integer. @@ -43124,7 +63170,8 @@ static void sp_384_add_one_6(sp_digit* a) */ static void sp_384_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j; + int i; + int j; byte* d; for (i = n - 1,j = 0; i >= 7; i -= 8) { @@ -43279,7 +63326,8 @@ int sp_ecc_make_key_384(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) */ static void sp_384_to_bin(sp_digit* r, byte* a) { - int i, j; + int i; + int j; for (i = 5, j = 0; i >= 0; i--) { a[j++] = r[i] >> 56; @@ -43305,7 +63353,7 @@ static void sp_384_to_bin(sp_digit* r, byte* a) * returns BUFFER_E if the buffer is to small for output size, * MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_secret_gen_384(mp_int* priv, ecc_point* pub, byte* out, +int sp_ecc_secret_gen_384(const mp_int* priv, const ecc_point* pub, byte* out, word32* outLen, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) @@ -43632,7 +63680,6 @@ static const uint64_t p384_order_minus_2[6] = { /* The low half of the order-2 of the P384 curve. */ static const uint64_t p384_order_low[3] = { 0xecec196accc52971U,0x581a0db248b0a77aU,0xc7634d81f4372ddfU - }; #endif /* WOLFSSL_SP_SMALL */ @@ -43780,7 +63827,7 @@ static void sp_384_mont_inv_order_6(sp_digit* r, const sp_digit* a, sp_384_mont_mul_order_6(t2, t2, t); for (i=191; i>=1; i--) { sp_384_mont_sqr_order_6(t2, t2); - if (((sp_digit)p384_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { + if ((p384_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { sp_384_mont_mul_order_6(t2, t2, a); } } @@ -43789,12 +63836,63 @@ static void sp_384_mont_inv_order_6(sp_digit* r, const sp_digit* a, #endif /* WOLFSSL_SP_SMALL */ } -#endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ #ifdef HAVE_ECC_SIGN #ifndef SP_ECC_MAX_SIG_GEN #define SP_ECC_MAX_SIG_GEN 64 #endif +/* Calculate second signature value S from R, k and private value. + * + * s = (r * x + e) / k + * + * s Signature value. + * r First signature value. + * k Ephemeral private key. + * x Private key as a number. + * e Hash of message as a number. + * tmp Temporary storage for intermediate numbers. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_calc_s_6(sp_digit* s, const sp_digit* r, sp_digit* k, + sp_digit* x, const sp_digit* e, sp_digit* tmp) +{ + int err; + sp_digit carry; + int64_t c; + sp_digit* kInv = k; + + /* Conv k to Montgomery form (mod order) */ + sp_384_mul_6(k, k, p384_norm_order); + err = sp_384_mod_6(k, k, p384_order); + if (err == MP_OKAY) { + sp_384_norm_6(k); + + /* kInv = 1/k mod order */ + sp_384_mont_inv_order_6(kInv, k, tmp); + sp_384_norm_6(kInv); + + /* s = r * x + e */ + sp_384_mul_6(x, x, r); + err = sp_384_mod_6(x, x, p384_order); + } + if (err == MP_OKAY) { + sp_384_norm_6(x); + carry = sp_384_add_6(s, e, x); + sp_384_cond_sub_6(s, s, p384_order, 0 - carry); + sp_384_norm_6(s); + c = sp_384_cmp_6(s, p384_order); + sp_384_cond_sub_6(s, s, p384_order, 0L - (sp_digit)(c >= 0)); + sp_384_norm_6(s); + + /* s = s * k^-1 mod order */ + sp_384_mont_mul_order_6(s, s, kInv); + sp_384_norm_6(s); + } + + return err; +} + /* Sign the hash using the private key. * e = [hash, 384 bits] from binary * r = (k.G)->x mod order @@ -43829,8 +63927,8 @@ typedef struct sp_ecc_sign_384_ctx { int i; } sp_ecc_sign_384_ctx; -int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, + mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_sign_384_ctx* ctx = (sp_ecc_sign_384_ctx*)sp_ctx->data; @@ -43970,8 +64068,8 @@ int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, W } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, + const mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -43989,11 +64087,9 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit* r = NULL; sp_digit* tmp = NULL; sp_point_384* point = NULL; - sp_digit carry; sp_digit* s = NULL; - sp_digit* kInv = NULL; - int err = MP_OKAY; int64_t c; + int err = MP_OKAY; int i; (void)heap; @@ -44024,7 +64120,6 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, tmp = td; #endif s = e; - kInv = k; if (hashLen > 48U) { hashLen = 48U; @@ -44032,8 +64127,6 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, } for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) { - sp_384_from_mp(x, 6, priv); - /* New random point. */ if (km == NULL || mp_iszero(km)) { err = sp_384_ecc_gen_k_6(rng, k); @@ -44043,7 +64136,7 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, mp_zero(km); } if (err == MP_OKAY) { - err = sp_384_ecc_mulmod_base_6(point, k, 1, 1, NULL); + err = sp_384_ecc_mulmod_base_6(point, k, 1, 1, heap); } if (err == MP_OKAY) { @@ -44054,38 +64147,15 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_384_cond_sub_6(r, r, p384_order, 0L - (sp_digit)(c >= 0)); sp_384_norm_6(r); - /* Conv k to Montgomery form (mod order) */ - sp_384_mul_6(k, k, p384_norm_order); - err = sp_384_mod_6(k, k, p384_order); - } - if (err == MP_OKAY) { - sp_384_norm_6(k); - /* kInv = 1/k mod order */ - sp_384_mont_inv_order_6(kInv, k, tmp); - sp_384_norm_6(kInv); - - /* s = r * x + e */ - sp_384_mul_6(x, x, r); - err = sp_384_mod_6(x, x, p384_order); - } - if (err == MP_OKAY) { - sp_384_norm_6(x); + sp_384_from_mp(x, 6, priv); sp_384_from_bin(e, 6, hash, (int)hashLen); - carry = sp_384_add_6(s, e, x); - sp_384_cond_sub_6(s, s, p384_order, 0 - carry); - sp_384_norm_6(s); - c = sp_384_cmp_6(s, p384_order); - sp_384_cond_sub_6(s, s, p384_order, 0L - (sp_digit)(c >= 0)); - sp_384_norm_6(s); - /* s = s * k^-1 mod order */ - sp_384_mont_mul_order_6(s, s, kInv); - sp_384_norm_6(s); + err = sp_384_calc_s_6(s, r, k, x, e, tmp); + } - /* Check that signature is usable. */ - if (sp_384_iszero_6(s) == 0) { - break; - } + /* Check that signature is usable. */ + if ((err == MP_OKAY) && (sp_384_iszero_6(s) == 0)) { + break; } #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP i = 1; @@ -44113,7 +64183,6 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, XMEMSET(x, 0, sizeof(sp_digit) * 2U * 6U); XMEMSET(k, 0, sizeof(sp_digit) * 2U * 6U); XMEMSET(r, 0, sizeof(sp_digit) * 2U * 6U); - XMEMSET(r, 0, sizeof(sp_digit) * 2U * 6U); XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 6U); #endif sp_384_point_free_6(point, 1, heap); @@ -44292,6 +64361,94 @@ static int sp_384_mod_inv_6(sp_digit* r, const sp_digit* a, const sp_digit* m) } #endif /* WOLFSSL_SP_SMALL */ + +/* Add point p1 into point p2. Handles p1 == p2 and result at infinity. + * + * p1 First point to add and holds result. + * p2 Second point to add. + * tmp Temporary storage for intermediate numbers. + */ +static void sp_384_add_points_6(sp_point_384* p1, const sp_point_384* p2, + sp_digit* tmp) +{ + + sp_384_proj_point_add_6(p1, p1, p2, tmp); + if (sp_384_iszero_6(p1->z)) { + if (sp_384_iszero_6(p1->x) && sp_384_iszero_6(p1->y)) { + sp_384_proj_point_dbl_6(p1, p2, tmp); + } + else { + /* Y ordinate is not used from here - don't set. */ + p1->x[0] = 0; + p1->x[1] = 0; + p1->x[2] = 0; + p1->x[3] = 0; + p1->x[4] = 0; + p1->x[5] = 0; + XMEMCPY(p1->z, p384_norm_mod, sizeof(p384_norm_mod)); + } + } +} + +/* Calculate the verification point: [e/s]G + [r/s]Q + * + * p1 Calculated point. + * p2 Public point and temporary. + * s Second part of signature as a number. + * u1 Temporary number. + * u2 Temproray number. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_calc_vfy_point_6(sp_point_384* p1, sp_point_384* p2, + sp_digit* s, sp_digit* u1, sp_digit* u2, sp_digit* tmp, void* heap) +{ + int err; + +#ifndef WOLFSSL_SP_SMALL + { + sp_384_mod_inv_6(s, s, p384_order); + } +#endif /* !WOLFSSL_SP_SMALL */ + { + sp_384_mul_6(s, s, p384_norm_order); + } + err = sp_384_mod_6(s, s, p384_order); + if (err == MP_OKAY) { + sp_384_norm_6(s); +#ifdef WOLFSSL_SP_SMALL + { + sp_384_mont_inv_order_6(s, s, tmp); + sp_384_mont_mul_order_6(u1, u1, s); + sp_384_mont_mul_order_6(u2, u2, s); + } + +#else + { + sp_384_mont_mul_order_6(u1, u1, s); + sp_384_mont_mul_order_6(u2, u2, s); + } + +#endif /* WOLFSSL_SP_SMALL */ + err = sp_384_ecc_mulmod_base_6(p1, u1, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_384_iszero_6(p1->z)) { + p1->infinity = 1; + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_6(p2, p2, u2, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_384_iszero_6(p2->z)) { + p2->infinity = 1; + } + + if (err == MP_OKAY) { + sp_384_add_points_6(p1, p2, tmp); + } + + return err; +} + #ifdef HAVE_ECC_VERIFY /* Verify the signature values with the hash and public key. * e = Truncate(hash, 384) @@ -44310,8 +64467,7 @@ static int sp_384_mod_inv_6(sp_digit* r, const sp_digit* a, const sp_digit* m) * rm First part of result as an mp_int. * sm Sirst part of result as an mp_int. * heap Heap to use for allocation. - * returns RNG failures, MEMORY_E when memory allocation fails and - * MP_OKAY on success. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ #ifdef WOLFSSL_SP_NONBLOCK typedef struct sp_ecc_verify_384_ctx { @@ -44330,8 +64486,9 @@ typedef struct sp_ecc_verify_384_ctx { sp_point_384 p2; } sp_ecc_verify_384_ctx; -int sp_ecc_verify_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, + word32 hashLen, const mp_int* pX, const mp_int* pY, const mp_int* pZ, + const mp_int* r, const mp_int* sm, int* res, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_verify_384_ctx* ctx = (sp_ecc_verify_384_ctx*)sp_ctx->data; @@ -44485,8 +64642,9 @@ int sp_ecc_verify_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_384(const byte* hash, word32 hashLen, const mp_int* pX, + const mp_int* pY, const mp_int* pZ, const mp_int* r, const mp_int* sm, + int* res, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -44505,7 +64663,7 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, sp_point_384* p1; sp_point_384* p2 = NULL; sp_digit carry; - int64_t c; + int64_t c = 0; int err; err = sp_384_point_new_6(heap, p1d, p1); @@ -44546,64 +64704,9 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, sp_384_from_mp(p2->y, 6, pY); sp_384_from_mp(p2->z, 6, pZ); -#ifndef WOLFSSL_SP_SMALL - { - sp_384_mod_inv_6(s, s, p384_order); - } -#endif /* !WOLFSSL_SP_SMALL */ - { - sp_384_mul_6(s, s, p384_norm_order); - } - err = sp_384_mod_6(s, s, p384_order); + err = sp_384_calc_vfy_point_6(p1, p2, s, u1, u2, tmp, heap); } if (err == MP_OKAY) { - sp_384_norm_6(s); -#ifdef WOLFSSL_SP_SMALL - { - sp_384_mont_inv_order_6(s, s, tmp); - sp_384_mont_mul_order_6(u1, u1, s); - sp_384_mont_mul_order_6(u2, u2, s); - } - -#else - { - sp_384_mont_mul_order_6(u1, u1, s); - sp_384_mont_mul_order_6(u2, u2, s); - } - -#endif /* WOLFSSL_SP_SMALL */ - err = sp_384_ecc_mulmod_base_6(p1, u1, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_384_iszero_6(p1->z)) { - p1->infinity = 1; - } - if (err == MP_OKAY) { - err = sp_384_ecc_mulmod_6(p2, p2, u2, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_384_iszero_6(p2->z)) { - p2->infinity = 1; - } - - if (err == MP_OKAY) { - { - sp_384_proj_point_add_6(p1, p1, p2, tmp); - if (sp_384_iszero_6(p1->z)) { - if (sp_384_iszero_6(p1->x) && sp_384_iszero_6(p1->y)) { - sp_384_proj_point_dbl_6(p1, p2, tmp); - } - else { - /* Y ordinate is not used from here - don't set. */ - p1->x[0] = 0; - p1->x[1] = 0; - p1->x[2] = 0; - p1->x[3] = 0; - p1->x[4] = 0; - p1->x[5] = 0; - XMEMCPY(p1->z, p384_norm_mod, sizeof(p384_norm_mod)); - } - } - } - /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */ /* Reload r and convert to Montgomery form. */ sp_384_from_mp(u2, 6, r); @@ -44625,16 +64728,16 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, /* Compare with mod and if greater or equal then not valid. */ c = sp_384_cmp_6(u2, p384_mod); - if (c < 0) { - /* Convert to Montogomery form */ - err = sp_384_mod_mul_norm_6(u2, u2, p384_mod); - if (err == MP_OKAY) { - /* u1 = (r + 1*order).z'.z' mod prime */ - sp_384_mont_mul_6(u1, u2, p1->z, p384_mod, - p384_mp_mod); - *res = (int)(sp_384_cmp_6(p1->x, u1) == 0); - } - } + } + } + if ((*res == 0) && (c < 0)) { + /* Convert to Montogomery form */ + err = sp_384_mod_mul_norm_6(u2, u2, p384_mod); + if (err == MP_OKAY) { + /* u1 = (r + 1*order).z'.z' mod prime */ + sp_384_mont_mul_6(u1, u2, p1->z, p384_mod, + p384_mp_mod); + *res = (sp_384_cmp_6(p1->x, u1) == 0); } } } @@ -44658,7 +64761,8 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -static int sp_384_ecc_is_point_6(sp_point_384* point, void* heap) +static int sp_384_ecc_is_point_6(const sp_point_384* point, + void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -44721,7 +64825,7 @@ static int sp_384_ecc_is_point_6(sp_point_384* point, void* heap) * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -int sp_ecc_is_point_384(mp_int* pX, mp_int* pY) +int sp_ecc_is_point_384(const mp_int* pX, const mp_int* pY) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_384 pubd; @@ -44755,7 +64859,8 @@ int sp_ecc_is_point_384(mp_int* pX, mp_int* pY) * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and * MP_OKAY otherwise. */ -int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) +int sp_ecc_check_key_384(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit privd[6]; @@ -44809,12 +64914,11 @@ int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) } } - if (err == MP_OKAY) { - /* Check range of X and Y */ - if (sp_384_cmp_6(pub->x, p384_mod) >= 0 || - sp_384_cmp_6(pub->y, p384_mod) >= 0) { - err = ECC_OUT_OF_RANGE_E; - } + /* Check range of X and Y */ + if ((err == MP_OKAY) && + ((sp_384_cmp_6(pub->x, p384_mod) >= 0) || + (sp_384_cmp_6(pub->y, p384_mod) >= 0))) { + err = ECC_OUT_OF_RANGE_E; } if (err == MP_OKAY) { @@ -44826,12 +64930,10 @@ int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Point * order = infinity */ err = sp_384_ecc_mulmod_6(p, pub, p384_order, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is infinity */ - if ((sp_384_iszero_6(p->x) == 0) || - (sp_384_iszero_6(p->y) == 0)) { - err = ECC_INF_E; - } + /* Check result is infinity */ + if ((err == MP_OKAY) && ((sp_384_iszero_6(p->x) == 0) || + (sp_384_iszero_6(p->y) == 0))) { + err = ECC_INF_E; } if (privm) { @@ -44839,12 +64941,11 @@ int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Base * private = point */ err = sp_384_ecc_mulmod_base_6(p, priv, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is public key */ - if (sp_384_cmp_6(p->x, pub->x) != 0 || - sp_384_cmp_6(p->y, pub->y) != 0) { - err = ECC_PRIV_KEY_E; - } + /* Check result is public key */ + if ((err == MP_OKAY) && + ((sp_384_cmp_6(p->x, pub->x) != 0) || + (sp_384_cmp_6(p->y, pub->y) != 0))) { + err = ECC_PRIV_KEY_E; } } @@ -45034,7 +65135,7 @@ int sp_ecc_map_384(mp_int* pX, mp_int* pY, mp_int* pZ) sp_384_from_mp(p->y, 6, pY); sp_384_from_mp(p->z, 6, pZ); - sp_384_map_6(p, p, tmp); + sp_384_map_6(p, p, tmp); } if (err == MP_OKAY) { @@ -45247,6 +65348,11824 @@ int sp_ecc_uncompress_384(mp_int* xm, int odd, mp_int* ym) } #endif #endif /* WOLFSSL_SP_384 */ +#ifdef WOLFSSL_SP_1024 + +/* Point structure to use. */ +typedef struct sp_point_1024 { + /* X ordinate of point. */ + sp_digit x[2 * 16]; + /* Y ordinate of point. */ + sp_digit y[2 * 16]; + /* Z ordinate of point. */ + sp_digit z[2 * 16]; + /* Indicates point is at infinity. */ + int infinity; +} sp_point_1024; + +#ifndef WOLFSSL_SP_SMALL +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static void sp_1024_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) +{ + __asm__ __volatile__ ( + "ldp x8, x9, [%[a], 0]\n\t" + "ldp x10, x11, [%[a], 16]\n\t" + "ldp x12, x13, [%[a], 32]\n\t" + "ldp x14, x15, [%[a], 48]\n\t" + "ldp x16, x17, [%[b], 0]\n\t" + "ldp x19, x20, [%[b], 16]\n\t" + "ldp x21, x22, [%[b], 32]\n\t" + "ldp x23, x24, [%[b], 48]\n\t" + "# A[0] * B[0]\n\t" + "mul x3, x8, x16\n\t" + "umulh x4, x8, x16\n\t" + "str x3, [%[r]]\n\t" + "# A[0] * B[1]\n\t" + "mul x6, x8, x17\n\t" + "umulh x7, x8, x17\n\t" + "adds x4, x4, x6\n\t" + "# A[1] * B[0]\n\t" + "mul x6, x9, x16\n\t" + "adc x5, xzr, x7\n\t" + "umulh x7, x9, x16\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "str x4, [%[r], 8]\n\t" + "adc x3, xzr, xzr\n\t" + "# A[0] * B[2]\n\t" + "mul x6, x8, x19\n\t" + "umulh x7, x8, x19\n\t" + "adds x5, x5, x6\n\t" + "# A[1] * B[1]\n\t" + "mul x6, x9, x17\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x9, x17\n\t" + "adc x4, xzr, xzr\n\t" + "adds x5, x5, x6\n\t" + "# A[2] * B[0]\n\t" + "mul x6, x10, x16\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x10, x16\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" + "adcs x3, x3, x7\n\t" + "str x5, [%[r], 16]\n\t" + "adc x4, x4, xzr\n\t" + "# A[0] * B[3]\n\t" + "mul x6, x8, x20\n\t" + "umulh x7, x8, x20\n\t" + "adds x3, x3, x6\n\t" + "# A[1] * B[2]\n\t" + "mul x6, x9, x19\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x9, x19\n\t" + "adc x5, xzr, xzr\n\t" + "adds x3, x3, x6\n\t" + "# A[2] * B[1]\n\t" + "mul x6, x10, x17\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x10, x17\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" + "# A[3] * B[0]\n\t" + "mul x6, x11, x16\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x11, x16\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" + "adcs x4, x4, x7\n\t" + "str x3, [%[r], 24]\n\t" + "adc x5, x5, xzr\n\t" + "# A[0] * B[4]\n\t" + "mul x6, x8, x21\n\t" + "umulh x7, x8, x21\n\t" + "adds x4, x4, x6\n\t" + "# A[1] * B[3]\n\t" + "mul x6, x9, x20\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x9, x20\n\t" + "adc x3, xzr, xzr\n\t" + "adds x4, x4, x6\n\t" + "# A[2] * B[2]\n\t" + "mul x6, x10, x19\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x10, x19\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" + "# A[3] * B[1]\n\t" + "mul x6, x11, x17\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x11, x17\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" + "# A[4] * B[0]\n\t" + "mul x6, x12, x16\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x12, x16\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "str x4, [%[r], 32]\n\t" + "adc x3, x3, xzr\n\t" + "# A[0] * B[5]\n\t" + "mul x6, x8, x22\n\t" + "umulh x7, x8, x22\n\t" + "adds x5, x5, x6\n\t" + "# A[1] * B[4]\n\t" + "mul x6, x9, x21\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x9, x21\n\t" + "adc x4, xzr, xzr\n\t" + "adds x5, x5, x6\n\t" + "# A[2] * B[3]\n\t" + "mul x6, x10, x20\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x10, x20\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" + "# A[3] * B[2]\n\t" + "mul x6, x11, x19\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x11, x19\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" + "# A[4] * B[1]\n\t" + "mul x6, x12, x17\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x12, x17\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" + "# A[5] * B[0]\n\t" + "mul x6, x13, x16\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x13, x16\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" + "adcs x3, x3, x7\n\t" + "str x5, [%[r], 40]\n\t" + "adc x4, x4, xzr\n\t" + "# A[0] * B[6]\n\t" + "mul x6, x8, x23\n\t" + "umulh x7, x8, x23\n\t" + "adds x3, x3, x6\n\t" + "# A[1] * B[5]\n\t" + "mul x6, x9, x22\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x9, x22\n\t" + "adc x5, xzr, xzr\n\t" + "adds x3, x3, x6\n\t" + "# A[2] * B[4]\n\t" + "mul x6, x10, x21\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x10, x21\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" + "# A[3] * B[3]\n\t" + "mul x6, x11, x20\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x11, x20\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" + "# A[4] * B[2]\n\t" + "mul x6, x12, x19\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x12, x19\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" + "# A[5] * B[1]\n\t" + "mul x6, x13, x17\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x13, x17\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" + "# A[6] * B[0]\n\t" + "mul x6, x14, x16\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x14, x16\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" + "adcs x4, x4, x7\n\t" + "str x3, [%[r], 48]\n\t" + "adc x5, x5, xzr\n\t" + "# A[0] * B[7]\n\t" + "mul x6, x8, x24\n\t" + "umulh x7, x8, x24\n\t" + "adds x4, x4, x6\n\t" + "# A[1] * B[6]\n\t" + "mul x6, x9, x23\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x9, x23\n\t" + "adc x3, xzr, xzr\n\t" + "adds x4, x4, x6\n\t" + "# A[2] * B[5]\n\t" + "mul x6, x10, x22\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x10, x22\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" + "# A[3] * B[4]\n\t" + "mul x6, x11, x21\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x11, x21\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" + "# A[4] * B[3]\n\t" + "mul x6, x12, x20\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x12, x20\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" + "# A[5] * B[2]\n\t" + "mul x6, x13, x19\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x13, x19\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" + "# A[6] * B[1]\n\t" + "mul x6, x14, x17\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x14, x17\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" + "# A[7] * B[0]\n\t" + "mul x6, x15, x16\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x15, x16\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "str x4, [%[r], 56]\n\t" + "adc x3, x3, xzr\n\t" + "# A[1] * B[7]\n\t" + "mul x6, x9, x24\n\t" + "umulh x7, x9, x24\n\t" + "adds x5, x5, x6\n\t" + "# A[2] * B[6]\n\t" + "mul x6, x10, x23\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x10, x23\n\t" + "adc x4, xzr, xzr\n\t" + "adds x5, x5, x6\n\t" + "# A[3] * B[5]\n\t" + "mul x6, x11, x22\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x11, x22\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" + "# A[4] * B[4]\n\t" + "mul x6, x12, x21\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x12, x21\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" + "# A[5] * B[3]\n\t" + "mul x6, x13, x20\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x13, x20\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" + "# A[6] * B[2]\n\t" + "mul x6, x14, x19\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x14, x19\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" + "# A[7] * B[1]\n\t" + "mul x6, x15, x17\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x15, x17\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" + "adcs x3, x3, x7\n\t" + "str x5, [%[r], 64]\n\t" + "adc x4, x4, xzr\n\t" + "# A[2] * B[7]\n\t" + "mul x6, x10, x24\n\t" + "umulh x7, x10, x24\n\t" + "adds x3, x3, x6\n\t" + "# A[3] * B[6]\n\t" + "mul x6, x11, x23\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x11, x23\n\t" + "adc x5, xzr, xzr\n\t" + "adds x3, x3, x6\n\t" + "# A[4] * B[5]\n\t" + "mul x6, x12, x22\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x12, x22\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" + "# A[5] * B[4]\n\t" + "mul x6, x13, x21\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x13, x21\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" + "# A[6] * B[3]\n\t" + "mul x6, x14, x20\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x14, x20\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" + "# A[7] * B[2]\n\t" + "mul x6, x15, x19\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x15, x19\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" + "adcs x4, x4, x7\n\t" + "str x3, [%[r], 72]\n\t" + "adc x5, x5, xzr\n\t" + "# A[3] * B[7]\n\t" + "mul x6, x11, x24\n\t" + "umulh x7, x11, x24\n\t" + "adds x4, x4, x6\n\t" + "# A[4] * B[6]\n\t" + "mul x6, x12, x23\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x12, x23\n\t" + "adc x3, xzr, xzr\n\t" + "adds x4, x4, x6\n\t" + "# A[5] * B[5]\n\t" + "mul x6, x13, x22\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x13, x22\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" + "# A[6] * B[4]\n\t" + "mul x6, x14, x21\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x14, x21\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" + "# A[7] * B[3]\n\t" + "mul x6, x15, x20\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x15, x20\n\t" + "adc x3, x3, xzr\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "str x4, [%[r], 80]\n\t" + "adc x3, x3, xzr\n\t" + "# A[4] * B[7]\n\t" + "mul x6, x12, x24\n\t" + "umulh x7, x12, x24\n\t" + "adds x5, x5, x6\n\t" + "# A[5] * B[6]\n\t" + "mul x6, x13, x23\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x13, x23\n\t" + "adc x4, xzr, xzr\n\t" + "adds x5, x5, x6\n\t" + "# A[6] * B[5]\n\t" + "mul x6, x14, x22\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x14, x22\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" + "# A[7] * B[4]\n\t" + "mul x6, x15, x21\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, x15, x21\n\t" + "adc x4, x4, xzr\n\t" + "adds x5, x5, x6\n\t" + "adcs x3, x3, x7\n\t" + "str x5, [%[r], 88]\n\t" + "adc x4, x4, xzr\n\t" + "# A[5] * B[7]\n\t" + "mul x6, x13, x24\n\t" + "umulh x7, x13, x24\n\t" + "adds x3, x3, x6\n\t" + "# A[6] * B[6]\n\t" + "mul x6, x14, x23\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x14, x23\n\t" + "adc x5, xzr, xzr\n\t" + "adds x3, x3, x6\n\t" + "# A[7] * B[5]\n\t" + "mul x6, x15, x22\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, x15, x22\n\t" + "adc x5, x5, xzr\n\t" + "adds x3, x3, x6\n\t" + "adcs x4, x4, x7\n\t" + "str x3, [%[r], 96]\n\t" + "adc x5, x5, xzr\n\t" + "# A[6] * B[7]\n\t" + "mul x6, x14, x24\n\t" + "umulh x7, x14, x24\n\t" + "adds x4, x4, x6\n\t" + "# A[7] * B[6]\n\t" + "mul x6, x15, x23\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, x15, x23\n\t" + "adc x3, xzr, xzr\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "str x4, [%[r], 104]\n\t" + "adc x3, x3, xzr\n\t" + "# A[7] * B[7]\n\t" + "mul x6, x15, x24\n\t" + "umulh x7, x15, x24\n\t" + "adds x5, x5, x6\n\t" + "adc x3, x3, x7\n\t" + "stp x5, x3, [%[r], 112]\n\t" + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24" + ); +} + +/* Square a and put result in r. (r = a * a) + * + * All registers version. + * + * r A single precision integer. + * a A single precision integer. + */ +static void sp_1024_sqr_8(sp_digit* r, const sp_digit* a) +{ + __asm__ __volatile__ ( + "ldp x21, x22, [%[a], 0]\n\t" + "ldp x23, x24, [%[a], 16]\n\t" + "ldp x25, x26, [%[a], 32]\n\t" + "ldp x27, x28, [%[a], 48]\n\t" + "# A[0] * A[1]\n\t" + "mul x6, x21, x22\n\t" + "umulh x7, x21, x22\n\t" + "# A[0] * A[2]\n\t" + "mul x4, x21, x23\n\t" + "umulh x5, x21, x23\n\t" + "adds x7, x7, x4\n\t" + "# A[0] * A[3]\n\t" + "mul x4, x21, x24\n\t" + "adc x8, xzr, x5\n\t" + "umulh x5, x21, x24\n\t" + "adds x8, x8, x4\n\t" + "# A[1] * A[2]\n\t" + "mul x4, x22, x23\n\t" + "adc x9, xzr, x5\n\t" + "umulh x5, x22, x23\n\t" + "adds x8, x8, x4\n\t" + "# A[0] * A[4]\n\t" + "mul x4, x21, x25\n\t" + "adcs x9, x9, x5\n\t" + "umulh x5, x21, x25\n\t" + "adc x10, xzr, xzr\n\t" + "adds x9, x9, x4\n\t" + "# A[1] * A[3]\n\t" + "mul x4, x22, x24\n\t" + "adc x10, x10, x5\n\t" + "umulh x5, x22, x24\n\t" + "adds x9, x9, x4\n\t" + "# A[0] * A[5]\n\t" + "mul x4, x21, x26\n\t" + "adcs x10, x10, x5\n\t" + "umulh x5, x21, x26\n\t" + "adc x11, xzr, xzr\n\t" + "adds x10, x10, x4\n\t" + "# A[1] * A[4]\n\t" + "mul x4, x22, x25\n\t" + "adc x11, x11, x5\n\t" + "umulh x5, x22, x25\n\t" + "adds x10, x10, x4\n\t" + "# A[2] * A[3]\n\t" + "mul x4, x23, x24\n\t" + "adcs x11, x11, x5\n\t" + "umulh x5, x23, x24\n\t" + "adc x12, xzr, xzr\n\t" + "adds x10, x10, x4\n\t" + "# A[0] * A[6]\n\t" + "mul x4, x21, x27\n\t" + "adcs x11, x11, x5\n\t" + "umulh x5, x21, x27\n\t" + "adc x12, x12, xzr\n\t" + "adds x11, x11, x4\n\t" + "# A[1] * A[5]\n\t" + "mul x4, x22, x26\n\t" + "adcs x12, x12, x5\n\t" + "umulh x5, x22, x26\n\t" + "adc x13, xzr, xzr\n\t" + "adds x11, x11, x4\n\t" + "# A[2] * A[4]\n\t" + "mul x4, x23, x25\n\t" + "adcs x12, x12, x5\n\t" + "umulh x5, x23, x25\n\t" + "adc x13, x13, xzr\n\t" + "adds x11, x11, x4\n\t" + "# A[0] * A[7]\n\t" + "mul x4, x21, x28\n\t" + "adcs x12, x12, x5\n\t" + "umulh x5, x21, x28\n\t" + "adc x13, x13, xzr\n\t" + "adds x12, x12, x4\n\t" + "# A[1] * A[6]\n\t" + "mul x4, x22, x27\n\t" + "adcs x13, x13, x5\n\t" + "umulh x5, x22, x27\n\t" + "adc x14, xzr, xzr\n\t" + "adds x12, x12, x4\n\t" + "# A[2] * A[5]\n\t" + "mul x4, x23, x26\n\t" + "adcs x13, x13, x5\n\t" + "umulh x5, x23, x26\n\t" + "adc x14, x14, xzr\n\t" + "adds x12, x12, x4\n\t" + "# A[3] * A[4]\n\t" + "mul x4, x24, x25\n\t" + "adcs x13, x13, x5\n\t" + "umulh x5, x24, x25\n\t" + "adc x14, x14, xzr\n\t" + "adds x12, x12, x4\n\t" + "# A[1] * A[7]\n\t" + "mul x4, x22, x28\n\t" + "adcs x13, x13, x5\n\t" + "umulh x5, x22, x28\n\t" + "adc x14, x14, xzr\n\t" + "adds x13, x13, x4\n\t" + "# A[2] * A[6]\n\t" + "mul x4, x23, x27\n\t" + "adcs x14, x14, x5\n\t" + "umulh x5, x23, x27\n\t" + "adc x15, xzr, xzr\n\t" + "adds x13, x13, x4\n\t" + "# A[3] * A[5]\n\t" + "mul x4, x24, x26\n\t" + "adcs x14, x14, x5\n\t" + "umulh x5, x24, x26\n\t" + "adc x15, x15, xzr\n\t" + "adds x13, x13, x4\n\t" + "# A[2] * A[7]\n\t" + "mul x4, x23, x28\n\t" + "adcs x14, x14, x5\n\t" + "umulh x5, x23, x28\n\t" + "adc x15, x15, xzr\n\t" + "adds x14, x14, x4\n\t" + "# A[3] * A[6]\n\t" + "mul x4, x24, x27\n\t" + "adcs x15, x15, x5\n\t" + "umulh x5, x24, x27\n\t" + "adc x16, xzr, xzr\n\t" + "adds x14, x14, x4\n\t" + "# A[4] * A[5]\n\t" + "mul x4, x25, x26\n\t" + "adcs x15, x15, x5\n\t" + "umulh x5, x25, x26\n\t" + "adc x16, x16, xzr\n\t" + "adds x14, x14, x4\n\t" + "# A[3] * A[7]\n\t" + "mul x4, x24, x28\n\t" + "adcs x15, x15, x5\n\t" + "umulh x5, x24, x28\n\t" + "adc x16, x16, xzr\n\t" + "adds x15, x15, x4\n\t" + "# A[4] * A[6]\n\t" + "mul x4, x25, x27\n\t" + "adcs x16, x16, x5\n\t" + "umulh x5, x25, x27\n\t" + "adc x17, xzr, xzr\n\t" + "adds x15, x15, x4\n\t" + "# A[4] * A[7]\n\t" + "mul x4, x25, x28\n\t" + "adcs x16, x16, x5\n\t" + "umulh x5, x25, x28\n\t" + "adc x17, x17, xzr\n\t" + "adds x16, x16, x4\n\t" + "# A[5] * A[6]\n\t" + "mul x4, x26, x27\n\t" + "adcs x17, x17, x5\n\t" + "umulh x5, x26, x27\n\t" + "adc x19, xzr, xzr\n\t" + "adds x16, x16, x4\n\t" + "# A[5] * A[7]\n\t" + "mul x4, x26, x28\n\t" + "adcs x17, x17, x5\n\t" + "umulh x5, x26, x28\n\t" + "adc x19, x19, xzr\n\t" + "adds x17, x17, x4\n\t" + "# A[6] * A[7]\n\t" + "mul x4, x27, x28\n\t" + "adcs x19, x19, x5\n\t" + "umulh x5, x27, x28\n\t" + "adc x20, xzr, xzr\n\t" + "adds x19, x19, x4\n\t" + "adc x20, x20, x5\n\t" + "# Double\n\t" + "adds x6, x6, x6\n\t" + "adcs x7, x7, x7\n\t" + "adcs x8, x8, x8\n\t" + "adcs x9, x9, x9\n\t" + "adcs x10, x10, x10\n\t" + "adcs x11, x11, x11\n\t" + "adcs x12, x12, x12\n\t" + "adcs x13, x13, x13\n\t" + "adcs x14, x14, x14\n\t" + "adcs x15, x15, x15\n\t" + "adcs x16, x16, x16\n\t" + "adcs x17, x17, x17\n\t" + "adcs x19, x19, x19\n\t" + "# A[0] * A[0]\n\t" + "mul x5, x21, x21\n\t" + "adcs x20, x20, x20\n\t" + "umulh x2, x21, x21\n\t" + "cset x21, cs\n\t" + "# A[1] * A[1]\n\t" + "mul x3, x22, x22\n\t" + "adds x6, x6, x2\n\t" + "umulh x4, x22, x22\n\t" + "adcs x7, x7, x3\n\t" + "# A[2] * A[2]\n\t" + "mul x2, x23, x23\n\t" + "adcs x8, x8, x4\n\t" + "umulh x3, x23, x23\n\t" + "adcs x9, x9, x2\n\t" + "# A[3] * A[3]\n\t" + "mul x4, x24, x24\n\t" + "adcs x10, x10, x3\n\t" + "umulh x2, x24, x24\n\t" + "adcs x11, x11, x4\n\t" + "# A[4] * A[4]\n\t" + "mul x3, x25, x25\n\t" + "adcs x12, x12, x2\n\t" + "umulh x4, x25, x25\n\t" + "adcs x13, x13, x3\n\t" + "# A[5] * A[5]\n\t" + "mul x2, x26, x26\n\t" + "adcs x14, x14, x4\n\t" + "umulh x3, x26, x26\n\t" + "adcs x15, x15, x2\n\t" + "# A[6] * A[6]\n\t" + "mul x4, x27, x27\n\t" + "adcs x16, x16, x3\n\t" + "umulh x2, x27, x27\n\t" + "adcs x17, x17, x4\n\t" + "# A[7] * A[7]\n\t" + "mul x3, x28, x28\n\t" + "adcs x19, x19, x2\n\t" + "umulh x4, x28, x28\n\t" + "adcs x20, x20, x3\n\t" + "stp x5, x6, [%[r], 0]\n\t" + "adc x21, x21, x4\n\t" + "stp x7, x8, [%[r], 16]\n\t" + "stp x9, x10, [%[r], 32]\n\t" + "stp x11, x12, [%[r], 48]\n\t" + "stp x13, x14, [%[r], 64]\n\t" + "stp x15, x16, [%[r], 80]\n\t" + "stp x17, x19, [%[r], 96]\n\t" + "stp x20, x21, [%[r], 112]\n\t" + : + : [r] "r" (r), [a] "r" (a) + : "memory", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28" + ); +} + +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_1024_add_8(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + __asm__ __volatile__ ( + "ldp x3, x4, [%[a], 0]\n\t" + "ldp x7, x8, [%[b], 0]\n\t" + "adds x3, x3, x7\n\t" + "ldp x5, x6, [%[a], 16]\n\t" + "adcs x4, x4, x8\n\t" + "ldp x9, x10, [%[b], 16]\n\t" + "adcs x5, x5, x9\n\t" + "stp x3, x4, [%[r], 0]\n\t" + "adcs x6, x6, x10\n\t" + "stp x5, x6, [%[r], 16]\n\t" + "ldp x3, x4, [%[a], 32]\n\t" + "ldp x7, x8, [%[b], 32]\n\t" + "adcs x3, x3, x7\n\t" + "ldp x5, x6, [%[a], 48]\n\t" + "adcs x4, x4, x8\n\t" + "ldp x9, x10, [%[b], 48]\n\t" + "adcs x5, x5, x9\n\t" + "stp x3, x4, [%[r], 32]\n\t" + "adcs x6, x6, x10\n\t" + "stp x5, x6, [%[r], 48]\n\t" + "cset %[r], cs\n\t" + : [r] "+r" (r) + : [a] "r" (a), [b] "r" (b) + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10" + ); + + return (sp_digit)r; +} + +/* Sub b from a into a. (a -= b) + * + * a A single precision integer and result. + * b A single precision integer. + */ +static sp_digit sp_1024_sub_in_place_16(sp_digit* a, const sp_digit* b) +{ + __asm__ __volatile__ ( + "ldp x2, x3, [%[a], 0]\n\t" + "ldp x6, x7, [%[b], 0]\n\t" + "subs x2, x2, x6\n\t" + "ldp x4, x5, [%[a], 16]\n\t" + "sbcs x3, x3, x7\n\t" + "ldp x8, x9, [%[b], 16]\n\t" + "sbcs x4, x4, x8\n\t" + "stp x2, x3, [%[a], 0]\n\t" + "sbcs x5, x5, x9\n\t" + "stp x4, x5, [%[a], 16]\n\t" + "ldp x2, x3, [%[a], 32]\n\t" + "ldp x6, x7, [%[b], 32]\n\t" + "sbcs x2, x2, x6\n\t" + "ldp x4, x5, [%[a], 48]\n\t" + "sbcs x3, x3, x7\n\t" + "ldp x8, x9, [%[b], 48]\n\t" + "sbcs x4, x4, x8\n\t" + "stp x2, x3, [%[a], 32]\n\t" + "sbcs x5, x5, x9\n\t" + "stp x4, x5, [%[a], 48]\n\t" + "ldp x2, x3, [%[a], 64]\n\t" + "ldp x6, x7, [%[b], 64]\n\t" + "sbcs x2, x2, x6\n\t" + "ldp x4, x5, [%[a], 80]\n\t" + "sbcs x3, x3, x7\n\t" + "ldp x8, x9, [%[b], 80]\n\t" + "sbcs x4, x4, x8\n\t" + "stp x2, x3, [%[a], 64]\n\t" + "sbcs x5, x5, x9\n\t" + "stp x4, x5, [%[a], 80]\n\t" + "ldp x2, x3, [%[a], 96]\n\t" + "ldp x6, x7, [%[b], 96]\n\t" + "sbcs x2, x2, x6\n\t" + "ldp x4, x5, [%[a], 112]\n\t" + "sbcs x3, x3, x7\n\t" + "ldp x8, x9, [%[b], 112]\n\t" + "sbcs x4, x4, x8\n\t" + "stp x2, x3, [%[a], 96]\n\t" + "sbcs x5, x5, x9\n\t" + "stp x4, x5, [%[a], 112]\n\t" + "csetm %[a], cc\n\t" + : [a] "+r" (a) + : [b] "r" (b) + : "memory", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9" + ); + + return (sp_digit)a; +} + +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_1024_add_16(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + __asm__ __volatile__ ( + "ldp x3, x4, [%[a], 0]\n\t" + "ldp x7, x8, [%[b], 0]\n\t" + "adds x3, x3, x7\n\t" + "ldp x5, x6, [%[a], 16]\n\t" + "adcs x4, x4, x8\n\t" + "ldp x9, x10, [%[b], 16]\n\t" + "adcs x5, x5, x9\n\t" + "stp x3, x4, [%[r], 0]\n\t" + "adcs x6, x6, x10\n\t" + "stp x5, x6, [%[r], 16]\n\t" + "ldp x3, x4, [%[a], 32]\n\t" + "ldp x7, x8, [%[b], 32]\n\t" + "adcs x3, x3, x7\n\t" + "ldp x5, x6, [%[a], 48]\n\t" + "adcs x4, x4, x8\n\t" + "ldp x9, x10, [%[b], 48]\n\t" + "adcs x5, x5, x9\n\t" + "stp x3, x4, [%[r], 32]\n\t" + "adcs x6, x6, x10\n\t" + "stp x5, x6, [%[r], 48]\n\t" + "ldp x3, x4, [%[a], 64]\n\t" + "ldp x7, x8, [%[b], 64]\n\t" + "adcs x3, x3, x7\n\t" + "ldp x5, x6, [%[a], 80]\n\t" + "adcs x4, x4, x8\n\t" + "ldp x9, x10, [%[b], 80]\n\t" + "adcs x5, x5, x9\n\t" + "stp x3, x4, [%[r], 64]\n\t" + "adcs x6, x6, x10\n\t" + "stp x5, x6, [%[r], 80]\n\t" + "ldp x3, x4, [%[a], 96]\n\t" + "ldp x7, x8, [%[b], 96]\n\t" + "adcs x3, x3, x7\n\t" + "ldp x5, x6, [%[a], 112]\n\t" + "adcs x4, x4, x8\n\t" + "ldp x9, x10, [%[b], 112]\n\t" + "adcs x5, x5, x9\n\t" + "stp x3, x4, [%[r], 96]\n\t" + "adcs x6, x6, x10\n\t" + "stp x5, x6, [%[r], 112]\n\t" + "cset %[r], cs\n\t" + : [r] "+r" (r) + : [a] "r" (a), [b] "r" (b) + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10" + ); + + return (sp_digit)r; +} + +/* AND m into each word of a and store in r. + * + * r A single precision integer. + * a A single precision integer. + * m Mask to AND against each digit. + */ +static void sp_1024_mask_8(sp_digit* r, const sp_digit* a, sp_digit m) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i=0; i<8; i++) { + r[i] = a[i] & m; + } +#else + r[0] = a[0] & m; + r[1] = a[1] & m; + r[2] = a[2] & m; + r[3] = a[3] & m; + r[4] = a[4] & m; + r[5] = a[5] & m; + r[6] = a[6] & m; + r[7] = a[7] & m; +#endif +} + +/* Add digit to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static void sp_1024_add_zero_8(sp_digit* r, const sp_digit* a, + const sp_digit d) +{ + __asm__ __volatile__ ( + "ldp x3, x4, [%[a], 0]\n\t" + "ldp x5, x6, [%[a], 16]\n\t" + "adds x3, x3, %[d]\n\t" + "adcs x4, x4, xzr\n\t" + "adcs x5, x5, xzr\n\t" + "stp x3, x4, [%[r], 0]\n\t" + "adcs x6, x6, xzr\n\t" + "stp x5, x6, [%[r], 16]\n\t" + "ldp x3, x4, [%[a], 32]\n\t" + "ldp x5, x6, [%[a], 48]\n\t" + "adcs x3, x3, xzr\n\t" + "adcs x4, x4, xzr\n\t" + "adcs x5, x5, xzr\n\t" + "stp x3, x4, [%[r], 32]\n\t" + "adcs x6, x6, xzr\n\t" + "stp x5, x6, [%[r], 48]\n\t" + : + : [r] "r" (r), [a] "r" (a), [d] "r" (d) + : "memory", "x3", "x4", "x5", "x6" + ); +} + +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static void sp_1024_mul_16(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit* z0 = r; + sp_digit z1[16]; + sp_digit a1[8]; + sp_digit b1[8]; + sp_digit z2[16]; + sp_digit u, ca, cb; + + ca = sp_1024_add_8(a1, a, &a[8]); + cb = sp_1024_add_8(b1, b, &b[8]); + u = ca & cb; + sp_1024_mul_8(z1, a1, b1); + sp_1024_mul_8(z2, &a[8], &b[8]); + sp_1024_mul_8(z0, a, b); + sp_1024_mask_8(r + 16, a1, 0 - cb); + sp_1024_mask_8(b1, b1, 0 - ca); + u += sp_1024_add_8(r + 16, r + 16, b1); + u += sp_1024_sub_in_place_16(z1, z2); + u += sp_1024_sub_in_place_16(z1, z0); + u += sp_1024_add_16(r + 8, r + 8, z1); + u += sp_1024_add_8(r + 16, r + 16, z2); + sp_1024_add_zero_8(r + 24, z2 + 8, u); +} + +#ifdef WOLFSSL_SP_SMALL +/* Double a into r. (r = a + a) + * + * r A single precision integer. + * a A single precision integer. + */ +static sp_digit sp_1024_dbl_8(sp_digit* r, const sp_digit* a) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "add x11, %[a], 64\n\t" + "\n1:\n\t" + "adds %[c], %[c], #-1\n\t" + "ldp x3, x4, [%[a]], #16\n\t" + "ldp x5, x6, [%[a]], #16\n\t" + "adcs x3, x3, x3\n\t" + "adcs x4, x4, x4\n\t" + "adcs x5, x5, x5\n\t" + "stp x3, x4, [%[r]], #16\n\t" + "adcs x6, x6, x6\n\t" + "stp x5, x6, [%[r]], #16\n\t" + "cset %[c], cs\n\t" + "cmp %[a], x11\n\t" + "b.ne 1b\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a) + : + : "memory", "x3", "x4", "x5", "x6", "x11" + ); + + return c; +} + +#else +/* Double a into r. (r = a + a) + * + * r A single precision integer. + * a A single precision integer. + */ +static sp_digit sp_1024_dbl_8(sp_digit* r, const sp_digit* a) +{ + __asm__ __volatile__ ( + "ldp x3, x4, [%[a], 0]\n\t" + "adds x3, x3, x3\n\t" + "ldr x5, [%[a], 16]\n\t" + "adcs x4, x4, x4\n\t" + "ldr x6, [%[a], 24]\n\t" + "adcs x5, x5, x5\n\t" + "stp x3, x4, [%[r], 0]\n\t" + "adcs x6, x6, x6\n\t" + "stp x5, x6, [%[r], 16]\n\t" + "ldp x3, x4, [%[a], 32]\n\t" + "adcs x3, x3, x3\n\t" + "ldr x5, [%[a], 48]\n\t" + "adcs x4, x4, x4\n\t" + "ldr x6, [%[a], 56]\n\t" + "adcs x5, x5, x5\n\t" + "stp x3, x4, [%[r], 32]\n\t" + "adcs x6, x6, x6\n\t" + "stp x5, x6, [%[r], 48]\n\t" + "cset %[r], cs\n\t" + : [r] "+r" (r) + : [a] "r" (a) + : "memory", "x3", "x4", "x5", "x6" + ); + + return (sp_digit)r; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_1024_sqr_16(sp_digit* r, const sp_digit* a) +{ + sp_digit* z0 = r; + sp_digit z2[16]; + sp_digit z1[16]; + sp_digit a1[8]; + sp_digit u; + + u = sp_1024_add_8(a1, a, &a[8]); + sp_1024_sqr_8(z1, a1); + sp_1024_sqr_8(z2, &a[8]); + sp_1024_sqr_8(z0, a); + sp_1024_mask_8(r + 16, a1, 0 - u); + u += sp_1024_dbl_8(r + 16, r + 16); + u += sp_1024_sub_in_place_16(z1, z2); + u += sp_1024_sub_in_place_16(z1, z0); + u += sp_1024_add_16(r + 8, r + 8, z1); + u += sp_1024_add_8(r + 16, r + 16, z2); + sp_1024_add_zero_8(r + 24, z2 + 8, u); +} + +#else +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static void sp_1024_mul_16(sp_digit* r, const sp_digit* a, const sp_digit* b) +{ + sp_digit tmp[32]; + + __asm__ __volatile__ ( + "mov x5, 0\n\t" + "mov x6, 0\n\t" + "mov x7, 0\n\t" + "mov x8, 0\n\t" + "\n1:\n\t" + "subs x3, x5, 120\n\t" + "csel x3, xzr, x3, cc\n\t" + "sub x4, x5, x3\n\t" + "\n2:\n\t" + "ldr x10, [%[a], x3]\n\t" + "ldr x11, [%[b], x4]\n\t" + "mul x9, x10, x11\n\t" + "umulh x10, x10, x11\n\t" + "adds x6, x6, x9\n\t" + "adcs x7, x7, x10\n\t" + "adc x8, x8, xzr\n\t" + "add x3, x3, #8\n\t" + "sub x4, x4, #8\n\t" + "cmp x3, 128\n\t" + "b.eq 3f\n\t" + "cmp x3, x5\n\t" + "b.le 2b\n\t" + "\n3:\n\t" + "str x6, [%[r], x5]\n\t" + "mov x6, x7\n\t" + "mov x7, x8\n\t" + "mov x8, #0\n\t" + "add x5, x5, #8\n\t" + "cmp x5, 240\n\t" + "b.le 1b\n\t" + "str x6, [%[r], x5]\n\t" + : + : [r] "r" (tmp), [a] "r" (a), [b] "r" (b) + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11" + ); + + XMEMCPY(r, tmp, sizeof(tmp)); +} + +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +static void sp_1024_sqr_16(sp_digit* r, const sp_digit* a) +{ + sp_digit tmp[32]; + + __asm__ __volatile__ ( + "mov x6, 0\n\t" + "mov x7, 0\n\t" + "mov x8, 0\n\t" + "mov x5, 0\n\t" + "\n1:\n\t" + "subs x3, x5, 120\n\t" + "csel x3, xzr, x3, cc\n\t" + "sub x4, x5, x3\n\t" + "\n2:\n\t" + "cmp x4, x3\n\t" + "b.eq 4f\n\t" + "ldr x10, [%[a], x3]\n\t" + "ldr x11, [%[a], x4]\n\t" + "mul x9, x10, x11\n\t" + "umulh x10, x10, x11\n\t" + "adds x6, x6, x9\n\t" + "adcs x7, x7, x10\n\t" + "adc x8, x8, xzr\n\t" + "adds x6, x6, x9\n\t" + "adcs x7, x7, x10\n\t" + "adc x8, x8, xzr\n\t" + "b.al 5f\n\t" + "\n4:\n\t" + "ldr x10, [%[a], x3]\n\t" + "mul x9, x10, x10\n\t" + "umulh x10, x10, x10\n\t" + "adds x6, x6, x9\n\t" + "adcs x7, x7, x10\n\t" + "adc x8, x8, xzr\n\t" + "\n5:\n\t" + "add x3, x3, #8\n\t" + "sub x4, x4, #8\n\t" + "cmp x3, 128\n\t" + "b.eq 3f\n\t" + "cmp x3, x4\n\t" + "b.gt 3f\n\t" + "cmp x3, x5\n\t" + "b.le 2b\n\t" + "\n3:\n\t" + "str x6, [%[r], x5]\n\t" + "mov x6, x7\n\t" + "mov x7, x8\n\t" + "mov x8, #0\n\t" + "add x5, x5, #8\n\t" + "cmp x5, 240\n\t" + "b.le 1b\n\t" + "str x6, [%[r], x5]\n\t" + : + : [r] "r" (tmp), [a] "r" (a) + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11" + ); + + XMEMCPY(r, tmp, sizeof(tmp)); +} + +#endif /* !WOLFSSL_SP_SMALL */ +/* The modulus (prime) of the curve P1024. */ +static const sp_digit p1024_mod[16] = { + 0x666d807afea85febL,0x80c5df10ac7ace87L,0xfce3e82389857db0L, + 0x9f94d6af56971f1fL,0xa7cf3c521c3c09aaL,0xb6aff4a831852a82L, + 0x512ac5cd65681ce1L,0xe26c6487326b4cd4L,0x356d27f4a666a6d0L, + 0xe791b39ff7c88a19L,0x228730d531a59cb0L,0xf40aab27e2fc0f1bL, + 0xbe9ae358b3e01a2eL,0x416c0ce19cb48261L,0x65c61198dad0657aL, + 0x997abb1f0a563fdaL +}; +/* The Montogmery normalizer for modulus of the curve P1024. */ +static const sp_digit p1024_norm_mod[16] = { + 0x99927f850157a015L,0x7f3a20ef53853178L,0x031c17dc767a824fL, + 0x606b2950a968e0e0L,0x5830c3ade3c3f655L,0x49500b57ce7ad57dL, + 0xaed53a329a97e31eL,0x1d939b78cd94b32bL,0xca92d80b5999592fL, + 0x186e4c60083775e6L,0xdd78cf2ace5a634fL,0x0bf554d81d03f0e4L, + 0x41651ca74c1fe5d1L,0xbe93f31e634b7d9eL,0x9a39ee67252f9a85L, + 0x668544e0f5a9c025L +}; +/* The Montogmery multiplier for modulus of the curve P1024. */ +static sp_digit p1024_mp_mod = 0x290420077c8f2f3d; +#if defined(WOLFSSL_SP_SMALL) || defined(HAVE_ECC_CHECK_KEY) +/* The order of the curve P1024. */ +static const sp_digit p1024_order[16] = { + 0xd99b601ebfaa17fbL,0x203177c42b1eb3a1L,0xff38fa08e2615f6cL, + 0xa7e535abd5a5c7c7L,0xa9f3cf14870f026aL,0x6dabfd2a0c614aa0L, + 0x144ab173595a0738L,0x389b1921cc9ad335L,0x4d5b49fd2999a9b4L, + 0x39e46ce7fdf22286L,0xc8a1cc354c69672cL,0xbd02aac9f8bf03c6L, + 0x6fa6b8d62cf8068bL,0x905b0338672d2098L,0x9971846636b4195eL, + 0x265eaec7c2958ff6L +}; +#endif +/* The base point of curve P1024. */ +static const sp_point_1024 p1024_base = { + /* X ordinate */ + { + 0x880dc8abeae63895L,0x80ec46c4967e0979L,0xee9163a5b63f73ecL, + 0xd5cfb4cc80728d87L,0xa7c1514dba66910dL,0xa702c3397a60de74L, + 0x337c86548b72f2e1L,0x9760af765dd5bccbL,0x718bd9e7406ce890L, + 0x43d5f22cdb9dfa55L,0xab10db9030b09e10L,0xb5edb6c0f6ce2308L, + 0x98b2f204b6ff7cbfL,0x2b1a2fd60aec69c6L,0x0a7990053ed9b52aL, + 0x53fc09ee332c29adL, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* Y ordinate */ + { + 0x75573fd71bef16d7L,0xadb9b5706a67dcdeL,0x80bdad5ad5bb4636L, + 0x13515ad7e9cb99a9L,0x492d979fc5a4d5f2L,0xac6f1e80164aa989L, + 0xcad696b5b7652fe0L,0x70dae117ad547c6cL,0x416cff0ca9e032b9L, + 0x6b598ccf9a140b2eL,0xe7f7f5e5f0de55f6L,0xf5ea69f4654ec2b9L, + 0x3d778d821e141178L,0xd3e8201602990696L,0xf9f1f0533634a135L, + 0x0a8249063f6009f1L, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* Z ordinate */ + { + 0x0000000000000001L,0x0000000000000000L,0x0000000000000000L, + 0x0000000000000000L,0x0000000000000000L,0x0000000000000000L, + 0x0000000000000000L,0x0000000000000000L,0x0000000000000000L, + 0x0000000000000000L,0x0000000000000000L,0x0000000000000000L, + 0x0000000000000000L,0x0000000000000000L,0x0000000000000000L, + 0x0000000000000000L, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* infinity */ + 0 +}; + +#ifdef WOLFSSL_SP_SMALL +/* Sub b from a into a. (a -= b) + * + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_1024_sub_in_place_16(sp_digit* a, const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "add x10, %[a], 128\n\t" + "\n1:\n\t" + "subs %[c], xzr, %[c]\n\t" + "ldp x2, x3, [%[a]]\n\t" + "ldp x4, x5, [%[a], #16]\n\t" + "ldp x6, x7, [%[b]], #16\n\t" + "sbcs x2, x2, x6\n\t" + "ldp x8, x9, [%[b]], #16\n\t" + "sbcs x3, x3, x7\n\t" + "sbcs x4, x4, x8\n\t" + "stp x2, x3, [%[a]], #16\n\t" + "sbcs x5, x5, x9\n\t" + "stp x4, x5, [%[a]], #16\n\t" + "csetm %[c], cc\n\t" + "cmp %[a], x10\n\t" + "b.ne 1b\n\t" + : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10" + ); + + return c; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Conditionally subtract b from a using the mask m. + * m is -1 to subtract and 0 when not copying. + * + * r A single precision number representing condition subtract result. + * a A single precision number to subtract from. + * b A single precision number to subtract. + * m Mask value to apply. + */ +static sp_digit sp_1024_cond_sub_16(sp_digit* r, const sp_digit* a, const sp_digit* b, + sp_digit m) +{ +#ifdef WOLFSSL_SP_SMALL + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov x8, #0\n\t" + "1:\n\t" + "subs %[c], xzr, %[c]\n\t" + "ldr x4, [%[a], x8]\n\t" + "ldr x5, [%[b], x8]\n\t" + "and x5, x5, %[m]\n\t" + "sbcs x4, x4, x5\n\t" + "csetm %[c], cc\n\t" + "str x4, [%[r], x8]\n\t" + "add x8, x8, #8\n\t" + "cmp x8, 128\n\t" + "b.lt 1b\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "x4", "x6", "x5", "x7", "x8", "x9", "x10", "x11", "x12" + ); + + return c; +#else + __asm__ __volatile__ ( + + "ldp x5, x7, [%[b], 0]\n\t" + "ldp x11, x12, [%[b], 16]\n\t" + "ldp x4, x6, [%[a], 0]\n\t" + "and x5, x5, %[m]\n\t" + "ldp x9, x10, [%[a], 16]\n\t" + "and x7, x7, %[m]\n\t" + "subs x4, x4, x5\n\t" + "and x11, x11, %[m]\n\t" + "sbcs x6, x6, x7\n\t" + "and x12, x12, %[m]\n\t" + "sbcs x9, x9, x11\n\t" + "stp x4, x6, [%[r], 0]\n\t" + "sbcs x10, x10, x12\n\t" + "stp x9, x10, [%[r], 16]\n\t" + "ldp x5, x7, [%[b], 32]\n\t" + "ldp x11, x12, [%[b], 48]\n\t" + "ldp x4, x6, [%[a], 32]\n\t" + "and x5, x5, %[m]\n\t" + "ldp x9, x10, [%[a], 48]\n\t" + "and x7, x7, %[m]\n\t" + "sbcs x4, x4, x5\n\t" + "and x11, x11, %[m]\n\t" + "sbcs x6, x6, x7\n\t" + "and x12, x12, %[m]\n\t" + "sbcs x9, x9, x11\n\t" + "stp x4, x6, [%[r], 32]\n\t" + "sbcs x10, x10, x12\n\t" + "stp x9, x10, [%[r], 48]\n\t" + "ldp x5, x7, [%[b], 64]\n\t" + "ldp x11, x12, [%[b], 80]\n\t" + "ldp x4, x6, [%[a], 64]\n\t" + "and x5, x5, %[m]\n\t" + "ldp x9, x10, [%[a], 80]\n\t" + "and x7, x7, %[m]\n\t" + "sbcs x4, x4, x5\n\t" + "and x11, x11, %[m]\n\t" + "sbcs x6, x6, x7\n\t" + "and x12, x12, %[m]\n\t" + "sbcs x9, x9, x11\n\t" + "stp x4, x6, [%[r], 64]\n\t" + "sbcs x10, x10, x12\n\t" + "stp x9, x10, [%[r], 80]\n\t" + "ldp x5, x7, [%[b], 96]\n\t" + "ldp x11, x12, [%[b], 112]\n\t" + "ldp x4, x6, [%[a], 96]\n\t" + "and x5, x5, %[m]\n\t" + "ldp x9, x10, [%[a], 112]\n\t" + "and x7, x7, %[m]\n\t" + "sbcs x4, x4, x5\n\t" + "and x11, x11, %[m]\n\t" + "sbcs x6, x6, x7\n\t" + "and x12, x12, %[m]\n\t" + "sbcs x9, x9, x11\n\t" + "stp x4, x6, [%[r], 96]\n\t" + "sbcs x10, x10, x12\n\t" + "stp x9, x10, [%[r], 112]\n\t" + "csetm %[r], cc\n\t" + : [r] "+r" (r) + : [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "x4", "x6", "x5", "x7", "x8", "x9", "x10", "x11", "x12" + ); + + return (sp_digit)r; +#endif /* WOLFSSL_SP_SMALL */ +} + +#ifdef WOLFSSL_SP_SMALL +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_1024_add_16(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "add x11, %[a], 128\n\t" + "\n1:\n\t" + "adds %[c], %[c], #-1\n\t" + "ldp x3, x4, [%[a]], #16\n\t" + "ldp x5, x6, [%[a]], #16\n\t" + "ldp x7, x8, [%[b]], #16\n\t" + "adcs x3, x3, x7\n\t" + "ldp x9, x10, [%[b]], #16\n\t" + "adcs x4, x4, x8\n\t" + "adcs x5, x5, x9\n\t" + "stp x3, x4, [%[r]], #16\n\t" + "adcs x6, x6, x10\n\t" + "stp x5, x6, [%[r]], #16\n\t" + "cset %[c], cs\n\t" + "cmp %[a], x11\n\t" + "b.ne 1b\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11" + ); + + return c; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Mul a by digit b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision digit. + */ +static void sp_1024_mul_d_16(sp_digit* r, const sp_digit* a, + sp_digit b) +{ +#ifdef WOLFSSL_SP_SMALL + __asm__ __volatile__ ( + "# A[0] * B\n\t" + "ldr x8, [%[a]]\n\t" + "mul x5, %[b], x8\n\t" + "umulh x3, %[b], x8\n\t" + "mov x4, 0\n\t" + "str x5, [%[r]]\n\t" + "mov x5, 0\n\t" + "mov x9, #8\n\t" + "1:\n\t" + "ldr x8, [%[a], x9]\n\t" + "mul x6, %[b], x8\n\t" + "umulh x7, %[b], x8\n\t" + "adds x3, x3, x6\n\t" + "adcs x4, x4, x7\n\t" + "adc x5, xzr, xzr\n\t" + "str x3, [%[r], x9]\n\t" + "mov x3, x4\n\t" + "mov x4, x5\n\t" + "mov x5, #0\n\t" + "add x9, x9, #8\n\t" + "cmp x9, 128\n\t" + "b.lt 1b\n\t" + "str x3, [%[r], 128]\n\t" + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9" + ); +#else + __asm__ __volatile__ ( + "# A[0] * B\n\t" + "ldp x8, x9, [%[a]]\n\t" + "mul x3, %[b], x8\n\t" + "umulh x4, %[b], x8\n\t" + "mov x5, 0\n\t" + "# A[1] * B\n\t" + "str x3, [%[r]]\n\t" + "mov x3, 0\n\t" + "mul x6, %[b], x9\n\t" + "umulh x7, %[b], x9\n\t" + "adds x4, x4, x6\n\t" + "# A[2] * B\n\t" + "ldp x8, x9, [%[a], 16]\n\t" + "str x4, [%[r], 8]\n\t" + "mov x4, 0\n\t" + "mul x6, %[b], x8\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, %[b], x8\n\t" + "adc x3, xzr, xzr\n\t" + "adds x5, x5, x6\n\t" + "# A[3] * B\n\t" + "str x5, [%[r], 16]\n\t" + "mov x5, 0\n\t" + "mul x6, %[b], x9\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, %[b], x9\n\t" + "adc x4, xzr, xzr\n\t" + "adds x3, x3, x6\n\t" + "# A[4] * B\n\t" + "ldp x8, x9, [%[a], 32]\n\t" + "str x3, [%[r], 24]\n\t" + "mov x3, 0\n\t" + "mul x6, %[b], x8\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, %[b], x8\n\t" + "adc x5, xzr, xzr\n\t" + "adds x4, x4, x6\n\t" + "# A[5] * B\n\t" + "str x4, [%[r], 32]\n\t" + "mov x4, 0\n\t" + "mul x6, %[b], x9\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, %[b], x9\n\t" + "adc x3, xzr, xzr\n\t" + "adds x5, x5, x6\n\t" + "# A[6] * B\n\t" + "ldp x8, x9, [%[a], 48]\n\t" + "str x5, [%[r], 40]\n\t" + "mov x5, 0\n\t" + "mul x6, %[b], x8\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, %[b], x8\n\t" + "adc x4, xzr, xzr\n\t" + "adds x3, x3, x6\n\t" + "# A[7] * B\n\t" + "str x3, [%[r], 48]\n\t" + "mov x3, 0\n\t" + "mul x6, %[b], x9\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, %[b], x9\n\t" + "adc x5, xzr, xzr\n\t" + "adds x4, x4, x6\n\t" + "# A[8] * B\n\t" + "ldp x8, x9, [%[a], 64]\n\t" + "str x4, [%[r], 56]\n\t" + "mov x4, 0\n\t" + "mul x6, %[b], x8\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, %[b], x8\n\t" + "adc x3, xzr, xzr\n\t" + "adds x5, x5, x6\n\t" + "# A[9] * B\n\t" + "str x5, [%[r], 64]\n\t" + "mov x5, 0\n\t" + "mul x6, %[b], x9\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, %[b], x9\n\t" + "adc x4, xzr, xzr\n\t" + "adds x3, x3, x6\n\t" + "# A[10] * B\n\t" + "ldp x8, x9, [%[a], 80]\n\t" + "str x3, [%[r], 72]\n\t" + "mov x3, 0\n\t" + "mul x6, %[b], x8\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, %[b], x8\n\t" + "adc x5, xzr, xzr\n\t" + "adds x4, x4, x6\n\t" + "# A[11] * B\n\t" + "str x4, [%[r], 80]\n\t" + "mov x4, 0\n\t" + "mul x6, %[b], x9\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, %[b], x9\n\t" + "adc x3, xzr, xzr\n\t" + "adds x5, x5, x6\n\t" + "# A[12] * B\n\t" + "ldp x8, x9, [%[a], 96]\n\t" + "str x5, [%[r], 88]\n\t" + "mov x5, 0\n\t" + "mul x6, %[b], x8\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, %[b], x8\n\t" + "adc x4, xzr, xzr\n\t" + "adds x3, x3, x6\n\t" + "# A[13] * B\n\t" + "str x3, [%[r], 96]\n\t" + "mov x3, 0\n\t" + "mul x6, %[b], x9\n\t" + "adcs x4, x4, x7\n\t" + "umulh x7, %[b], x9\n\t" + "adc x5, xzr, xzr\n\t" + "adds x4, x4, x6\n\t" + "# A[14] * B\n\t" + "ldp x8, x9, [%[a], 112]\n\t" + "str x4, [%[r], 104]\n\t" + "mov x4, 0\n\t" + "mul x6, %[b], x8\n\t" + "adcs x5, x5, x7\n\t" + "umulh x7, %[b], x8\n\t" + "adc x3, xzr, xzr\n\t" + "adds x5, x5, x6\n\t" + "# A[15] * B\n\t" + "str x5, [%[r], 112]\n\t" + "mul x6, %[b], x9\n\t" + "adcs x3, x3, x7\n\t" + "umulh x7, %[b], x9\n\t" + "adc x4, xzr, xzr\n\t" + "adds x3, x3, x6\n\t" + "adc x4, x4, x7\n\t" + "stp x3, x4, [%[r], 120]\n\t" + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9" + ); +#endif +} + +/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) + * + * d1 The high order half of the number to divide. + * d0 The low order half of the number to divide. + * div The dividend. + * returns the result of the division. + */ +static sp_digit div_1024_word_16(sp_digit d1, sp_digit d0, sp_digit div) +{ + sp_digit r; + + __asm__ __volatile__ ( + "lsr x5, %[div], 32\n\t" + "add x5, x5, 1\n\t" + + "udiv x3, %[d1], x5\n\t" + "lsl x6, x3, 32\n\t" + "mul x4, %[div], x6\n\t" + "umulh x3, %[div], x6\n\t" + "subs %[d0], %[d0], x4\n\t" + "sbc %[d1], %[d1], x3\n\t" + + "udiv x3, %[d1], x5\n\t" + "lsl x3, x3, 32\n\t" + "add x6, x6, x3\n\t" + "mul x4, %[div], x3\n\t" + "umulh x3, %[div], x3\n\t" + "subs %[d0], %[d0], x4\n\t" + "sbc %[d1], %[d1], x3\n\t" + + "lsr x3, %[d0], 32\n\t" + "orr x3, x3, %[d1], lsl 32\n\t" + + "udiv x3, x3, x5\n\t" + "add x6, x6, x3\n\t" + "mul x4, %[div], x3\n\t" + "umulh x3, %[div], x3\n\t" + "subs %[d0], %[d0], x4\n\t" + "sbc %[d1], %[d1], x3\n\t" + + "lsr x3, %[d0], 32\n\t" + "orr x3, x3, %[d1], lsl 32\n\t" + + "udiv x3, x3, x5\n\t" + "add x6, x6, x3\n\t" + "mul x4, %[div], x3\n\t" + "sub %[d0], %[d0], x4\n\t" + + "udiv x3, %[d0], %[div]\n\t" + "add %[r], x6, x3\n\t" + + : [r] "=r" (r) + : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div) + : "x3", "x4", "x5", "x6" + ); + + return r; +} + +/* AND m into each word of a and store in r. + * + * r A single precision integer. + * a A single precision integer. + * m Mask to AND against each digit. + */ +static void sp_1024_mask_16(sp_digit* r, const sp_digit* a, sp_digit m) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i=0; i<16; i++) { + r[i] = a[i] & m; + } +#else + int i; + + for (i = 0; i < 16; i += 8) { + r[i+0] = a[i+0] & m; + r[i+1] = a[i+1] & m; + r[i+2] = a[i+2] & m; + r[i+3] = a[i+3] & m; + r[i+4] = a[i+4] & m; + r[i+5] = a[i+5] & m; + r[i+6] = a[i+6] & m; + r[i+7] = a[i+7] & m; + } +#endif +} + +/* Compare a with b in constant time. + * + * a A single precision integer. + * b A single precision integer. + * return -ve, 0 or +ve if a is less than, equal to or greater than b + * respectively. + */ +static int64_t sp_1024_cmp_16(const sp_digit* a, const sp_digit* b) +{ +#ifdef WOLFSSL_SP_SMALL + __asm__ __volatile__ ( + "mov x2, -1\n\t" + "mov x3, 1\n\t" + "mov x4, -1\n\t" + "mov x5, 120\n\t" + "1:\n\t" + "ldr x6, [%[a], x5]\n\t" + "ldr x7, [%[b], x5]\n\t" + "and x6, x6, x4\n\t" + "and x7, x7, x4\n\t" + "subs x6, x6, x7\n\t" + "csel x2, x3, x2, hi\n\t" + "csel x2, x4, x2, lo\n\t" + "csel x4, x4, xzr, eq\n\t" + "subs x5, x5, #8\n\t" + "b.cs 1b\n\t" + "eor %[a], x2, x4\n\t" + : [a] "+r" (a) + : [b] "r" (b) + : "x2", "x3", "x4", "x5", "x6", "x7", "x8" + ); +#else + __asm__ __volatile__ ( + "mov x2, -1\n\t" + "mov x3, 1\n\t" + "mov x4, -1\n\t" + "ldp x5, x6, [%[a], 112]\n\t" + "ldp x7, x8, [%[b], 112]\n\t" + "and x6, x6, x4\n\t" + "and x8, x8, x4\n\t" + "subs x6, x6, x8\n\t" + "csel x2, x4, x2, lo\n\t" + "csel x4, x4, xzr, eq\n\t" + "csel x2, x3, x2, hi\n\t" + "and x5, x5, x4\n\t" + "and x7, x7, x4\n\t" + "subs x5, x5, x7\n\t" + "csel x2, x4, x2, lo\n\t" + "csel x4, x4, xzr, eq\n\t" + "csel x2, x3, x2, hi\n\t" + "ldp x5, x6, [%[a], 96]\n\t" + "ldp x7, x8, [%[b], 96]\n\t" + "and x6, x6, x4\n\t" + "and x8, x8, x4\n\t" + "subs x6, x6, x8\n\t" + "csel x2, x4, x2, lo\n\t" + "csel x4, x4, xzr, eq\n\t" + "csel x2, x3, x2, hi\n\t" + "and x5, x5, x4\n\t" + "and x7, x7, x4\n\t" + "subs x5, x5, x7\n\t" + "csel x2, x4, x2, lo\n\t" + "csel x4, x4, xzr, eq\n\t" + "csel x2, x3, x2, hi\n\t" + "ldp x5, x6, [%[a], 80]\n\t" + "ldp x7, x8, [%[b], 80]\n\t" + "and x6, x6, x4\n\t" + "and x8, x8, x4\n\t" + "subs x6, x6, x8\n\t" + "csel x2, x4, x2, lo\n\t" + "csel x4, x4, xzr, eq\n\t" + "csel x2, x3, x2, hi\n\t" + "and x5, x5, x4\n\t" + "and x7, x7, x4\n\t" + "subs x5, x5, x7\n\t" + "csel x2, x4, x2, lo\n\t" + "csel x4, x4, xzr, eq\n\t" + "csel x2, x3, x2, hi\n\t" + "ldp x5, x6, [%[a], 64]\n\t" + "ldp x7, x8, [%[b], 64]\n\t" + "and x6, x6, x4\n\t" + "and x8, x8, x4\n\t" + "subs x6, x6, x8\n\t" + "csel x2, x4, x2, lo\n\t" + "csel x4, x4, xzr, eq\n\t" + "csel x2, x3, x2, hi\n\t" + "and x5, x5, x4\n\t" + "and x7, x7, x4\n\t" + "subs x5, x5, x7\n\t" + "csel x2, x4, x2, lo\n\t" + "csel x4, x4, xzr, eq\n\t" + "csel x2, x3, x2, hi\n\t" + "ldp x5, x6, [%[a], 48]\n\t" + "ldp x7, x8, [%[b], 48]\n\t" + "and x6, x6, x4\n\t" + "and x8, x8, x4\n\t" + "subs x6, x6, x8\n\t" + "csel x2, x4, x2, lo\n\t" + "csel x4, x4, xzr, eq\n\t" + "csel x2, x3, x2, hi\n\t" + "and x5, x5, x4\n\t" + "and x7, x7, x4\n\t" + "subs x5, x5, x7\n\t" + "csel x2, x4, x2, lo\n\t" + "csel x4, x4, xzr, eq\n\t" + "csel x2, x3, x2, hi\n\t" + "ldp x5, x6, [%[a], 32]\n\t" + "ldp x7, x8, [%[b], 32]\n\t" + "and x6, x6, x4\n\t" + "and x8, x8, x4\n\t" + "subs x6, x6, x8\n\t" + "csel x2, x4, x2, lo\n\t" + "csel x4, x4, xzr, eq\n\t" + "csel x2, x3, x2, hi\n\t" + "and x5, x5, x4\n\t" + "and x7, x7, x4\n\t" + "subs x5, x5, x7\n\t" + "csel x2, x4, x2, lo\n\t" + "csel x4, x4, xzr, eq\n\t" + "csel x2, x3, x2, hi\n\t" + "ldp x5, x6, [%[a], 16]\n\t" + "ldp x7, x8, [%[b], 16]\n\t" + "and x6, x6, x4\n\t" + "and x8, x8, x4\n\t" + "subs x6, x6, x8\n\t" + "csel x2, x4, x2, lo\n\t" + "csel x4, x4, xzr, eq\n\t" + "csel x2, x3, x2, hi\n\t" + "and x5, x5, x4\n\t" + "and x7, x7, x4\n\t" + "subs x5, x5, x7\n\t" + "csel x2, x4, x2, lo\n\t" + "csel x4, x4, xzr, eq\n\t" + "csel x2, x3, x2, hi\n\t" + "ldp x5, x6, [%[a], 0]\n\t" + "ldp x7, x8, [%[b], 0]\n\t" + "and x6, x6, x4\n\t" + "and x8, x8, x4\n\t" + "subs x6, x6, x8\n\t" + "csel x2, x4, x2, lo\n\t" + "csel x4, x4, xzr, eq\n\t" + "csel x2, x3, x2, hi\n\t" + "and x5, x5, x4\n\t" + "and x7, x7, x4\n\t" + "subs x5, x5, x7\n\t" + "csel x2, x4, x2, lo\n\t" + "csel x4, x4, xzr, eq\n\t" + "csel x2, x3, x2, hi\n\t" + "eor %[a], x2, x4\n\t" + : [a] "+r" (a) + : [b] "r" (b) + : "x2", "x3", "x4", "x5", "x6", "x7", "x8" + ); +#endif + + return (int64_t)a; +} + +/* Divide d in a and put remainder into r (m*d + r = a) + * m is not calculated as it is not needed at this time. + * + * a Number to be divided. + * d Number to divide with. + * m Multiplier result. + * r Remainder from the division. + * returns MP_OKAY indicating success. + */ +static WC_INLINE int sp_1024_div_16(const sp_digit* a, const sp_digit* d, sp_digit* m, + sp_digit* r) +{ + sp_digit t1[32], t2[17]; + sp_digit div, r1; + int i; + + (void)m; + + div = d[15]; + XMEMCPY(t1, a, sizeof(*t1) * 2 * 16); + for (i=15; i>=0; i--) { + sp_digit hi = t1[16 + i] - (t1[16 + i] == div); + r1 = div_1024_word_16(hi, t1[16 + i - 1], div); + + sp_1024_mul_d_16(t2, d, r1); + t1[16 + i] += sp_1024_sub_in_place_16(&t1[i], t2); + t1[16 + i] -= t2[16]; + sp_1024_mask_16(t2, d, t1[16 + i]); + t1[16 + i] += sp_1024_add_16(&t1[i], &t1[i], t2); + sp_1024_mask_16(t2, d, t1[16 + i]); + t1[16 + i] += sp_1024_add_16(&t1[i], &t1[i], t2); + } + + r1 = sp_1024_cmp_16(t1, d) >= 0; + sp_1024_cond_sub_16(r, t1, d, (sp_digit)0 - r1); + + return MP_OKAY; +} + +/* Reduce a modulo m into r. (r = a mod m) + * + * r A single precision number that is the reduced result. + * a A single precision number that is to be reduced. + * m A single precision number that is the modulus to reduce with. + * returns MP_OKAY indicating success. + */ +static WC_INLINE int sp_1024_mod_16(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + return sp_1024_div_16(a, m, NULL, r); +} + +/* Multiply a number by Montogmery normalizer mod modulus (prime). + * + * r The resulting Montgomery form number. + * a The number to convert. + * m The modulus (prime). + * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. + */ +static int sp_1024_mod_mul_norm_16(sp_digit* r, const sp_digit* a, + const sp_digit* m) +{ + sp_1024_mul_16(r, a, p1024_norm_mod); + return sp_1024_mod_16(r, r, m); +} + +/* Create a new point. + * + * heap [in] Buffer to allocate dynamic memory from. + * sp [in] Data for point - only if not allocating. + * p [out] New point. + * returns MEMORY_E when dynamic memory allocation fails and 0 otherwise. + */ +static int sp_1024_point_new_ex_16(void* heap, sp_point_1024* sp, + sp_point_1024** p) +{ + int ret = MP_OKAY; + (void)heap; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + (void)sp; + *p = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024), heap, DYNAMIC_TYPE_ECC); +#else + *p = sp; +#endif + if (*p == NULL) { + ret = MEMORY_E; + } + return ret; +} + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* Allocate memory for point and return error. */ +#define sp_1024_point_new_16(heap, sp, p) sp_1024_point_new_ex_16((heap), NULL, &(p)) +#else +/* Set pointer to data and return no error. */ +#define sp_1024_point_new_16(heap, sp, p) sp_1024_point_new_ex_16((heap), &(sp), &(p)) +#endif + + +/* Free the point. + * + * p [in,out] Point to free. + * clear [in] Indicates whether to zeroize point. + * heap [in] Buffer from which dynamic memory was allocate from. + */ +static void sp_1024_point_free_16(sp_point_1024* p, int clear, void* heap) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* If valid pointer then clear point data if requested and free data. */ + if (p != NULL) { + if (clear != 0) { + XMEMSET(p, 0, sizeof(*p)); + } + XFREE(p, heap, DYNAMIC_TYPE_ECC); + } +#else +/* Clear point data if requested. */ + if ((p != NULL) && (clear != 0)) { + XMEMSET(p, 0, sizeof(*p)); + } +#endif + (void)heap; +} + +/* Convert an mp_int to an array of sp_digit. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a A multi-precision integer. + */ +static void sp_1024_from_mp(sp_digit* r, int size, const mp_int* a) +{ +#if DIGIT_BIT == 64 + int j; + + XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); + + for (j = a->used; j < size; j++) { + r[j] = 0; + } +#elif DIGIT_BIT > 64 + int i; + int j = 0; + word32 s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i] << s); + r[j] &= 0xffffffffffffffffl; + s = 64U - s; + if (j + 1 >= size) { + break; + } + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + while ((s + 64U) <= (word32)DIGIT_BIT) { + s += 64U; + r[j] &= 0xffffffffffffffffl; + if (j + 1 >= size) { + break; + } + if (s < (word32)DIGIT_BIT) { + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + } + else { + r[++j] = 0L; + } + } + s = (word32)DIGIT_BIT - s; + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#else + int i; + int j = 0; + int s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i]) << s; + if (s + DIGIT_BIT >= 64) { + r[j] &= 0xffffffffffffffffl; + if (j + 1 >= size) { + break; + } + s = 64 - s; + if (s == DIGIT_BIT) { + r[++j] = 0; + s = 0; + } + else { + r[++j] = a->dp[i] >> s; + s = DIGIT_BIT - s; + } + } + else { + s += DIGIT_BIT; + } + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#endif +} + +/* Convert a point of type ecc_point to type sp_point_1024. + * + * p Point of type sp_point_1024 (result). + * pm Point of type ecc_point. + */ +static void sp_1024_point_from_ecc_point_16(sp_point_1024* p, + const ecc_point* pm) +{ + XMEMSET(p->x, 0, sizeof(p->x)); + XMEMSET(p->y, 0, sizeof(p->y)); + XMEMSET(p->z, 0, sizeof(p->z)); + sp_1024_from_mp(p->x, 16, pm->x); + sp_1024_from_mp(p->y, 16, pm->y); + sp_1024_from_mp(p->z, 16, pm->z); + p->infinity = 0; +} + +/* Convert an array of sp_digit to an mp_int. + * + * a A single precision integer. + * r A multi-precision integer. + */ +static int sp_1024_to_mp(const sp_digit* a, mp_int* r) +{ + int err; + + err = mp_grow(r, (1024 + DIGIT_BIT - 1) / DIGIT_BIT); + if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ +#if DIGIT_BIT == 64 + XMEMCPY(r->dp, a, sizeof(sp_digit) * 16); + r->used = 16; + mp_clamp(r); +#elif DIGIT_BIT < 64 + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 16; i++) { + r->dp[j] |= (mp_digit)(a[i] << s); + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + s = DIGIT_BIT - s; + r->dp[++j] = (mp_digit)(a[i] >> s); + while (s + DIGIT_BIT <= 64) { + s += DIGIT_BIT; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; + if (s == SP_WORD_SIZE) { + r->dp[j] = 0; + } + else { + r->dp[j] = (mp_digit)(a[i] >> s); + } + } + s = 64 - s; + } + r->used = (1024 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#else + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 16; i++) { + r->dp[j] |= ((mp_digit)a[i]) << s; + if (s + 64 >= DIGIT_BIT) { + #if DIGIT_BIT != 32 && DIGIT_BIT != 64 + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + #endif + s = DIGIT_BIT - s; + r->dp[++j] = a[i] >> s; + s = 64 - s; + } + else { + s += 64; + } + } + r->used = (1024 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#endif + } + + return err; +} + +/* Convert a point of type sp_point_1024 to type ecc_point. + * + * p Point of type sp_point_1024. + * pm Point of type ecc_point (result). + * returns MEMORY_E when allocation of memory in ecc_point fails otherwise + * MP_OKAY. + */ +static int sp_1024_point_to_ecc_point_16(const sp_point_1024* p, ecc_point* pm) +{ + int err; + + err = sp_1024_to_mp(p->x, pm->x); + if (err == MP_OKAY) { + err = sp_1024_to_mp(p->y, pm->y); + } + if (err == MP_OKAY) { + err = sp_1024_to_mp(p->z, pm->z); + } + + return err; +} + +/* Conditionally copy a into r using the mask m. + * m is -1 to copy and 0 when not. + * + * r A single precision number to copy over. + * a A single precision number to copy. + * m Mask value to apply. + */ +static void sp_1024_cond_copy_16(sp_digit* r, const sp_digit* a, sp_digit m) +{ + __asm__ __volatile__ ( + "ldp x3, x4, [%[r], 0]\n\t" + "ldp x5, x6, [%[a], 0]\n\t" + "eor x5, x5, x3\n\t" + "eor x6, x6, x4\n\t" + "and x5, x5, %[m]\n\t" + "and x6, x6, %[m]\n\t" + "eor x3, x3, x5\n\t" + "eor x4, x4, x6\n\t" + "stp x3, x4, [%[r], 0]\n\t" + "ldp x3, x4, [%[r], 16]\n\t" + "ldp x5, x6, [%[a], 16]\n\t" + "eor x5, x5, x3\n\t" + "eor x6, x6, x4\n\t" + "and x5, x5, %[m]\n\t" + "and x6, x6, %[m]\n\t" + "eor x3, x3, x5\n\t" + "eor x4, x4, x6\n\t" + "stp x3, x4, [%[r], 16]\n\t" + "ldp x3, x4, [%[r], 32]\n\t" + "ldp x5, x6, [%[a], 32]\n\t" + "eor x5, x5, x3\n\t" + "eor x6, x6, x4\n\t" + "and x5, x5, %[m]\n\t" + "and x6, x6, %[m]\n\t" + "eor x3, x3, x5\n\t" + "eor x4, x4, x6\n\t" + "stp x3, x4, [%[r], 32]\n\t" + "ldp x3, x4, [%[r], 48]\n\t" + "ldp x5, x6, [%[a], 48]\n\t" + "eor x5, x5, x3\n\t" + "eor x6, x6, x4\n\t" + "and x5, x5, %[m]\n\t" + "and x6, x6, %[m]\n\t" + "eor x3, x3, x5\n\t" + "eor x4, x4, x6\n\t" + "stp x3, x4, [%[r], 48]\n\t" + "ldp x3, x4, [%[r], 64]\n\t" + "ldp x5, x6, [%[a], 64]\n\t" + "eor x5, x5, x3\n\t" + "eor x6, x6, x4\n\t" + "and x5, x5, %[m]\n\t" + "and x6, x6, %[m]\n\t" + "eor x3, x3, x5\n\t" + "eor x4, x4, x6\n\t" + "stp x3, x4, [%[r], 64]\n\t" + "ldp x3, x4, [%[r], 80]\n\t" + "ldp x5, x6, [%[a], 80]\n\t" + "eor x5, x5, x3\n\t" + "eor x6, x6, x4\n\t" + "and x5, x5, %[m]\n\t" + "and x6, x6, %[m]\n\t" + "eor x3, x3, x5\n\t" + "eor x4, x4, x6\n\t" + "stp x3, x4, [%[r], 80]\n\t" + "ldp x3, x4, [%[r], 96]\n\t" + "ldp x5, x6, [%[a], 96]\n\t" + "eor x5, x5, x3\n\t" + "eor x6, x6, x4\n\t" + "and x5, x5, %[m]\n\t" + "and x6, x6, %[m]\n\t" + "eor x3, x3, x5\n\t" + "eor x4, x4, x6\n\t" + "stp x3, x4, [%[r], 96]\n\t" + "ldp x3, x4, [%[r], 112]\n\t" + "ldp x5, x6, [%[a], 112]\n\t" + "eor x5, x5, x3\n\t" + "eor x6, x6, x4\n\t" + "and x5, x5, %[m]\n\t" + "and x6, x6, %[m]\n\t" + "eor x3, x3, x5\n\t" + "eor x4, x4, x6\n\t" + "stp x3, x4, [%[r], 112]\n\t" + : + : [r] "r" (r), [a] "r" (a), [m] "r" (m) + : "memory", "x3", "x4", "x5", "x6" + ); +} + +/* Reduce the number back to 1024 bits using Montgomery reduction. + * + * a A single precision number to reduce in place. + * m The single precision number representing the modulus. + * mp The digit representing the negative inverse of m mod 2^n. + */ +SP_NOINLINE static void sp_1024_mont_reduce_16(sp_digit* a, const sp_digit* m, + sp_digit mp) +{ + + __asm__ __volatile__ ( + "ldp x14, x15, [%[m], 0]\n\t" + "ldp x16, x17, [%[m], 16]\n\t" + "ldp x19, x20, [%[m], 32]\n\t" + "ldp x21, x22, [%[m], 48]\n\t" + "ldp x23, x24, [%[m], 64]\n\t" + "ldp x25, x26, [%[m], 80]\n\t" + "ldp x27, x28, [%[m], 96]\n\t" + "mov x3, xzr\n\t" + "# i = 16\n\t" + "mov x4, 16\n\t" + "ldp x12, x13, [%[a], 0]\n\t" + "\n1:\n\t" + "# mu = a[i] * mp\n\t" + "mul x9, %[mp], x12\n\t" + "# a[i+0] += m[0] * mu\n\t" + "mul x7, x14, x9\n\t" + "umulh x8, x14, x9\n\t" + "adds x12, x12, x7\n\t" + "# a[i+1] += m[1] * mu\n\t" + "mul x7, x15, x9\n\t" + "adc x6, x8, xzr\n\t" + "umulh x8, x15, x9\n\t" + "adds x12, x13, x7\n\t" + "# a[i+2] += m[2] * mu\n\t" + "ldr x13, [%[a], 16]\n\t" + "adc x5, x8, xzr\n\t" + "mul x7, x16, x9\n\t" + "adds x12, x12, x6\n\t" + "umulh x8, x16, x9\n\t" + "adc x5, x5, xzr\n\t" + "adds x13, x13, x7\n\t" + "# a[i+3] += m[3] * mu\n\t" + "ldr x10, [%[a], 24]\n\t" + "adc x6, x8, xzr\n\t" + "mul x7, x17, x9\n\t" + "adds x13, x13, x5\n\t" + "umulh x8, x17, x9\n\t" + "adc x6, x6, xzr\n\t" + "adds x10, x10, x7\n\t" + "# a[i+4] += m[4] * mu\n\t" + "ldr x11, [%[a], 32]\n\t" + "adc x5, x8, xzr\n\t" + "adds x10, x10, x6\n\t" + "mul x7, x19, x9\n\t" + "adc x5, x5, xzr\n\t" + "umulh x8, x19, x9\n\t" + "str x10, [%[a], 24]\n\t" + "adds x11, x11, x7\n\t" + "# a[i+5] += m[5] * mu\n\t" + "ldr x10, [%[a], 40]\n\t" + "adc x6, x8, xzr\n\t" + "adds x11, x11, x5\n\t" + "mul x7, x20, x9\n\t" + "adc x6, x6, xzr\n\t" + "umulh x8, x20, x9\n\t" + "str x11, [%[a], 32]\n\t" + "adds x10, x10, x7\n\t" + "# a[i+6] += m[6] * mu\n\t" + "ldr x11, [%[a], 48]\n\t" + "adc x5, x8, xzr\n\t" + "adds x10, x10, x6\n\t" + "mul x7, x21, x9\n\t" + "adc x5, x5, xzr\n\t" + "umulh x8, x21, x9\n\t" + "str x10, [%[a], 40]\n\t" + "adds x11, x11, x7\n\t" + "# a[i+7] += m[7] * mu\n\t" + "ldr x10, [%[a], 56]\n\t" + "adc x6, x8, xzr\n\t" + "adds x11, x11, x5\n\t" + "mul x7, x22, x9\n\t" + "adc x6, x6, xzr\n\t" + "umulh x8, x22, x9\n\t" + "str x11, [%[a], 48]\n\t" + "adds x10, x10, x7\n\t" + "# a[i+8] += m[8] * mu\n\t" + "ldr x11, [%[a], 64]\n\t" + "adc x5, x8, xzr\n\t" + "adds x10, x10, x6\n\t" + "mul x7, x23, x9\n\t" + "adc x5, x5, xzr\n\t" + "umulh x8, x23, x9\n\t" + "str x10, [%[a], 56]\n\t" + "adds x11, x11, x7\n\t" + "# a[i+9] += m[9] * mu\n\t" + "ldr x10, [%[a], 72]\n\t" + "adc x6, x8, xzr\n\t" + "adds x11, x11, x5\n\t" + "mul x7, x24, x9\n\t" + "adc x6, x6, xzr\n\t" + "umulh x8, x24, x9\n\t" + "str x11, [%[a], 64]\n\t" + "adds x10, x10, x7\n\t" + "# a[i+10] += m[10] * mu\n\t" + "ldr x11, [%[a], 80]\n\t" + "adc x5, x8, xzr\n\t" + "adds x10, x10, x6\n\t" + "mul x7, x25, x9\n\t" + "adc x5, x5, xzr\n\t" + "umulh x8, x25, x9\n\t" + "str x10, [%[a], 72]\n\t" + "adds x11, x11, x7\n\t" + "# a[i+11] += m[11] * mu\n\t" + "ldr x10, [%[a], 88]\n\t" + "adc x6, x8, xzr\n\t" + "adds x11, x11, x5\n\t" + "mul x7, x26, x9\n\t" + "adc x6, x6, xzr\n\t" + "umulh x8, x26, x9\n\t" + "str x11, [%[a], 80]\n\t" + "adds x10, x10, x7\n\t" + "# a[i+12] += m[12] * mu\n\t" + "ldr x11, [%[a], 96]\n\t" + "adc x5, x8, xzr\n\t" + "adds x10, x10, x6\n\t" + "mul x7, x27, x9\n\t" + "adc x5, x5, xzr\n\t" + "umulh x8, x27, x9\n\t" + "str x10, [%[a], 88]\n\t" + "adds x11, x11, x7\n\t" + "# a[i+13] += m[13] * mu\n\t" + "ldr x10, [%[a], 104]\n\t" + "adc x6, x8, xzr\n\t" + "adds x11, x11, x5\n\t" + "mul x7, x28, x9\n\t" + "adc x6, x6, xzr\n\t" + "umulh x8, x28, x9\n\t" + "str x11, [%[a], 96]\n\t" + "adds x10, x10, x7\n\t" + "# a[i+14] += m[14] * mu\n\t" + "ldr x11, [%[a], 112]\n\t" + "adc x5, x8, xzr\n\t" + "ldr x8, [%[m], 112]\n\t" + "adds x10, x10, x6\n\t" + "mul x7, x8, x9\n\t" + "adc x5, x5, xzr\n\t" + "umulh x8, x8, x9\n\t" + "str x10, [%[a], 104]\n\t" + "adds x11, x11, x7\n\t" + "# a[i+15] += m[15] * mu\n\t" + "ldr x10, [%[a], 120]\n\t" + "adc x6, x8, xzr\n\t" + "ldr x8, [%[m], 120]\n\t" + "adds x11, x11, x5\n\t" + "mul x7, x8, x9\n\t" + "adc x6, x6, xzr\n\t" + "umulh x8, x8, x9\n\t" + "adds x6, x6, x7\n\t" + "adcs x8, x8, x3\n\t" + "str x11, [%[a], 112]\n\t" + "cset x3, cs\n\t" + "adds x10, x10, x6\n\t" + "ldr x11, [%[a], 128]\n\t" + "str x10, [%[a], 120]\n\t" + "adcs x11, x11, x8\n\t" + "str x11, [%[a], 128]\n\t" + "adc x3, x3, xzr\n\t" + "subs x4, x4, 1\n\t" + "add %[a], %[a], 8\n\t" + "bne 1b\n\t" + "# x12 and x13 hold a[0] and a[1]\n\t" + "# Create mask\n\t" + "ldr x9, [%[m], 120]\n\t" + "subs x11, x9, x11\n\t" + "neg x3, x3\n\t" + "sbc x11, x11, x11\n\t" + "orr x3, x3, x11\n\t" + "mov x9, %[a]\n\t" + "sub %[a], %[a], 128\n\t" + "# Subtract masked modulus\n\t" + "# x12 and x13 hold a[0] and a[1]\n\t" + "and x14, x14, x3\n\t" + "ldp x11, x10, [x9, 16]\n\t" + "and x15, x15, x3\n\t" + "subs x12, x12, x14\n\t" + "and x16, x16, x3\n\t" + "sbcs x13, x13, x15\n\t" + "and x17, x17, x3\n\t" + "sbcs x11, x11, x16\n\t" + "stp x12, x13, [%[a], 0]\n\t" + "sbcs x10, x10, x17\n\t" + "stp x11, x10, [%[a], 16]\n\t" + "ldp x12, x13, [x9, 32]\n\t" + "and x19, x19, x3\n\t" + "ldp x11, x10, [x9, 48]\n\t" + "and x20, x20, x3\n\t" + "sbcs x12, x12, x19\n\t" + "and x21, x21, x3\n\t" + "sbcs x13, x13, x20\n\t" + "and x22, x22, x3\n\t" + "sbcs x11, x11, x21\n\t" + "stp x12, x13, [%[a], 32]\n\t" + "sbcs x10, x10, x22\n\t" + "stp x11, x10, [%[a], 48]\n\t" + "ldp x12, x13, [x9, 64]\n\t" + "and x23, x23, x3\n\t" + "ldp x11, x10, [x9, 80]\n\t" + "and x24, x24, x3\n\t" + "sbcs x12, x12, x23\n\t" + "and x25, x25, x3\n\t" + "sbcs x13, x13, x24\n\t" + "and x26, x26, x3\n\t" + "sbcs x11, x11, x25\n\t" + "stp x12, x13, [%[a], 64]\n\t" + "sbcs x10, x10, x26\n\t" + "stp x11, x10, [%[a], 80]\n\t" + "ldp x7, x8, [%[m], 112]\n\t" + "ldp x12, x13, [x9, 96]\n\t" + "and x27, x27, x3\n\t" + "ldp x11, x10, [x9, 112]\n\t" + "and x28, x28, x3\n\t" + "sbcs x12, x12, x27\n\t" + "and x7, x7, x3\n\t" + "sbcs x13, x13, x28\n\t" + "and x8, x8, x3\n\t" + "sbcs x11, x11, x7\n\t" + "stp x12, x13, [%[a], 96]\n\t" + "sbcs x10, x10, x8\n\t" + "stp x11, x10, [%[a], 112]\n\t" + : [a] "+r" (a) + : [m] "r" (m), [mp] "r" (mp) + : "memory", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28" + ); + +} + +/* Multiply two Montogmery form numbers mod the modulus (prime). + * (r = a * b mod m) + * + * r Result of multiplication. + * a First number to multiply in Montogmery form. + * b Second number to multiply in Montogmery form. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_1024_mont_mul_16(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) +{ + sp_1024_mul_16(r, a, b); + sp_1024_mont_reduce_16(r, m, mp); +} + +/* Square the Montgomery form number. (r = a * a mod m) + * + * r Result of squaring. + * a Number to square in Montogmery form. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_1024_mont_sqr_16(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) +{ + sp_1024_sqr_16(r, a); + sp_1024_mont_reduce_16(r, m, mp); +} + +/* Mod-2 for the P1024 curve. */ +static const uint8_t p1024_mod_minus_2[] = { + 6,0x06, 7,0x0f, 7,0x0b, 6,0x0c, 7,0x1e, 9,0x09, 7,0x0c, 7,0x1f, + 6,0x16, 6,0x06, 7,0x0e, 8,0x10, 6,0x03, 8,0x11, 6,0x0d, 7,0x14, + 9,0x12, 6,0x0f, 7,0x04, 9,0x0d, 6,0x00, 7,0x13, 6,0x01, 6,0x07, + 8,0x0d, 8,0x00, 6,0x06, 9,0x17, 6,0x14, 6,0x15, 6,0x11, 6,0x0b, + 9,0x0c, 6,0x1e, 13,0x14, 7,0x0e, 6,0x1d, 12,0x0a, 6,0x0b, 8,0x07, + 6,0x18, 6,0x0f, 6,0x10, 8,0x1c, 7,0x16, 7,0x02, 6,0x01, 6,0x13, + 10,0x15, 7,0x06, 8,0x14, 6,0x0c, 6,0x19, 7,0x10, 6,0x19, 6,0x19, + 9,0x16, 7,0x19, 6,0x1f, 6,0x17, 6,0x12, 8,0x02, 6,0x01, 6,0x04, + 6,0x15, 7,0x16, 6,0x04, 6,0x1f, 6,0x09, 7,0x06, 7,0x13, 7,0x09, + 6,0x0d, 10,0x18, 6,0x06, 6,0x11, 6,0x04, 6,0x01, 6,0x13, 8,0x06, + 6,0x0d, 8,0x13, 7,0x08, 6,0x08, 6,0x05, 7,0x0c, 7,0x0e, 7,0x15, + 6,0x05, 7,0x14, 10,0x19, 6,0x10, 6,0x16, 6,0x15, 7,0x1f, 6,0x14, + 6,0x0a, 10,0x11, 6,0x01, 7,0x05, 7,0x08, 8,0x0a, 7,0x1e, 7,0x1c, + 6,0x1c, 7,0x09, 10,0x18, 7,0x1c, 10,0x06, 6,0x0a, 6,0x07, 6,0x19, + 7,0x06, 6,0x0d, 7,0x0f, 7,0x0b, 7,0x05, 6,0x11, 6,0x1c, 7,0x1f, + 6,0x1e, 7,0x18, 6,0x1e, 6,0x00, 6,0x03, 6,0x02, 7,0x10, 6,0x0b, + 6,0x1b, 7,0x10, 6,0x00, 8,0x11, 7,0x1b, 6,0x18, 6,0x01, 7,0x0c, + 7,0x1d, 7,0x13, 6,0x08, 7,0x1b, 8,0x13, 7,0x16, 13,0x1d, 7,0x1f, + 6,0x0a, 6,0x01, 7,0x1f, 6,0x14, 1,0x01 +}; + +/* Invert the number, in Montgomery form, modulo the modulus (prime) of the + * P1024 curve. (r = 1 / a mod m) + * + * r Inverse result. + * a Number to invert. + * td Temporary data. + */ +static void sp_1024_mont_inv_16(sp_digit* r, const sp_digit* a, + sp_digit* td) +{ + sp_digit* t = td; + int i; + int j; + sp_digit table[32][2 * 16]; + + XMEMCPY(table[0], a, sizeof(sp_digit) * 16); + for (i = 1; i < 6; i++) { + sp_1024_mont_sqr_16(table[0], table[0], p1024_mod, p1024_mp_mod); + } + for (i = 1; i < 32; i++) { + sp_1024_mont_mul_16(table[i], table[i-1], a, p1024_mod, p1024_mp_mod); + } + + XMEMCPY(t, table[p1024_mod_minus_2[1]], sizeof(sp_digit) * 16); + for (i = 2; i < (int)sizeof(p1024_mod_minus_2) - 2; i += 2) { + for (j = 0; j < p1024_mod_minus_2[i]; j++) { + sp_1024_mont_sqr_16(t, t, p1024_mod, p1024_mp_mod); + } + sp_1024_mont_mul_16(t, t, table[p1024_mod_minus_2[i+1]], p1024_mod, + p1024_mp_mod); + } + sp_1024_mont_sqr_16(t, t, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(r, t, a, p1024_mod, p1024_mp_mod); +} + +/* Normalize the values in each word to 64. + * + * a Array of sp_digit to normalize. + */ +#define sp_1024_norm_16(a) + +/* Map the Montgomery form projective coordinate point to an affine point. + * + * r Resulting affine coordinate point. + * p Montgomery form projective coordinate point. + * t Temporary ordinate data. + */ +static void sp_1024_map_16(sp_point_1024* r, const sp_point_1024* p, + sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*16; + int64_t n; + + sp_1024_mont_inv_16(t1, p->z, t + 2*16); + + sp_1024_mont_sqr_16(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t1, t2, t1, p1024_mod, p1024_mp_mod); + + /* x /= z^2 */ + sp_1024_mont_mul_16(r->x, p->x, t2, p1024_mod, p1024_mp_mod); + XMEMSET(r->x + 16, 0, sizeof(r->x) / 2U); + sp_1024_mont_reduce_16(r->x, p1024_mod, p1024_mp_mod); + /* Reduce x to less than modulus */ + n = sp_1024_cmp_16(r->x, p1024_mod); + sp_1024_cond_sub_16(r->x, r->x, p1024_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_16(r->x); + + /* y /= z^3 */ + sp_1024_mont_mul_16(r->y, p->y, t1, p1024_mod, p1024_mp_mod); + XMEMSET(r->y + 16, 0, sizeof(r->y) / 2U); + sp_1024_mont_reduce_16(r->y, p1024_mod, p1024_mp_mod); + /* Reduce y to less than modulus */ + n = sp_1024_cmp_16(r->y, p1024_mod); + sp_1024_cond_sub_16(r->y, r->y, p1024_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_16(r->y); + + XMEMSET(r->z, 0, sizeof(r->z)); + r->z[0] = 1; + +} + +/* Add two Montgomery form numbers (r = a + b % m). + * + * r Result of addition. + * a First number to add in Montogmery form. + * b Second number to add in Montogmery form. + * m Modulus (prime). + */ +static void sp_1024_mont_add_16(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + __asm__ __volatile__ ( + "ldp x4, x5, [%[a], 0]\n\t" + "ldp x6, x7, [%[a], 16]\n\t" + "ldp x8, x9, [%[a], 32]\n\t" + "ldp x10, x11, [%[a], 48]\n\t" + "ldp x12, x13, [%[a], 64]\n\t" + "ldp x14, x15, [%[a], 80]\n\t" + "ldp x16, x17, [%[a], 96]\n\t" + "ldp x19, x20, [%[a], 112]\n\t" + "ldp x21, x22, [%[b], 0]\n\t" + "ldp x23, x24, [%[b], 16]\n\t" + "adds x4, x4, x21\n\t" + "adcs x5, x5, x22\n\t" + "adcs x6, x6, x23\n\t" + "adcs x7, x7, x24\n\t" + "ldp x21, x22, [%[b], 32]\n\t" + "ldp x23, x24, [%[b], 48]\n\t" + "adcs x8, x8, x21\n\t" + "adcs x9, x9, x22\n\t" + "adcs x10, x10, x23\n\t" + "adcs x11, x11, x24\n\t" + "ldp x21, x22, [%[b], 64]\n\t" + "ldp x23, x24, [%[b], 80]\n\t" + "adcs x12, x12, x21\n\t" + "adcs x13, x13, x22\n\t" + "adcs x14, x14, x23\n\t" + "adcs x15, x15, x24\n\t" + "ldp x21, x22, [%[b], 96]\n\t" + "ldp x23, x24, [%[b], 112]\n\t" + "adcs x16, x16, x21\n\t" + "adcs x17, x17, x22\n\t" + "adcs x19, x19, x23\n\t" + "adcs x20, x20, x24\n\t" + "csetm x25, cs\n\t" + "ldr x21, [%[m], 120]\n\t" + "subs x21, x21, x20\n\t" + "csetm x21, cc\n\t" + "orr x25, x25, x21\n\t" + "ldp x21, x22, [%[m], 0]\n\t" + "ldp x23, x24, [%[m], 16]\n\t" + "and x21, x21, x25\n\t" + "and x22, x22, x25\n\t" + "and x23, x23, x25\n\t" + "and x24, x24, x25\n\t" + "subs x4, x4, x21\n\t" + "sbcs x5, x5, x22\n\t" + "sbcs x6, x6, x23\n\t" + "sbcs x7, x7, x24\n\t" + "ldp x21, x22, [%[m], 32]\n\t" + "ldp x23, x24, [%[m], 48]\n\t" + "and x21, x21, x25\n\t" + "and x22, x22, x25\n\t" + "and x23, x23, x25\n\t" + "and x24, x24, x25\n\t" + "sbcs x8, x8, x21\n\t" + "sbcs x9, x9, x22\n\t" + "sbcs x10, x10, x23\n\t" + "sbcs x11, x11, x24\n\t" + "ldp x21, x22, [%[m], 64]\n\t" + "ldp x23, x24, [%[m], 80]\n\t" + "and x21, x21, x25\n\t" + "and x22, x22, x25\n\t" + "and x23, x23, x25\n\t" + "and x24, x24, x25\n\t" + "sbcs x12, x12, x21\n\t" + "sbcs x13, x13, x22\n\t" + "sbcs x14, x14, x23\n\t" + "sbcs x15, x15, x24\n\t" + "ldp x21, x22, [%[m], 96]\n\t" + "ldp x23, x24, [%[m], 112]\n\t" + "and x21, x21, x25\n\t" + "and x22, x22, x25\n\t" + "and x23, x23, x25\n\t" + "and x24, x24, x25\n\t" + "sbcs x16, x16, x21\n\t" + "sbcs x17, x17, x22\n\t" + "sbcs x19, x19, x23\n\t" + "sbc x20, x20, x24\n\t" + "stp x4, x5, [%[r], 0]\n\t" + "stp x6, x7, [%[r], 16]\n\t" + "stp x8, x9, [%[r], 32]\n\t" + "stp x10, x11, [%[r], 48]\n\t" + "stp x12, x13, [%[r], 64]\n\t" + "stp x14, x15, [%[r], 80]\n\t" + "stp x16, x17, [%[r], 96]\n\t" + "stp x19, x20, [%[r], 112]\n\t" + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24", "x25" + ); +} + +/* Double a Montgomery form number (r = a + a % m). + * + * r Result of doubling. + * a Number to double in Montogmery form. + * m Modulus (prime). + */ +static void sp_1024_mont_dbl_16(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + __asm__ __volatile__ ( + "ldp x4, x5, [%[a], 0]\n\t" + "ldp x6, x7, [%[a], 16]\n\t" + "ldp x8, x9, [%[a], 32]\n\t" + "ldp x10, x11, [%[a], 48]\n\t" + "ldp x12, x13, [%[a], 64]\n\t" + "ldp x14, x15, [%[a], 80]\n\t" + "ldp x16, x17, [%[a], 96]\n\t" + "ldp x19, x20, [%[a], 112]\n\t" + "adds x4, x4, x4\n\t" + "adcs x5, x5, x5\n\t" + "adcs x6, x6, x6\n\t" + "adcs x7, x7, x7\n\t" + "adcs x8, x8, x8\n\t" + "adcs x9, x9, x9\n\t" + "adcs x10, x10, x10\n\t" + "adcs x11, x11, x11\n\t" + "adcs x12, x12, x12\n\t" + "adcs x13, x13, x13\n\t" + "adcs x14, x14, x14\n\t" + "adcs x15, x15, x15\n\t" + "adcs x16, x16, x16\n\t" + "adcs x17, x17, x17\n\t" + "adcs x19, x19, x19\n\t" + "adcs x20, x20, x20\n\t" + "csetm x25, cs\n\t" + "ldr x21, [%[m], 120]\n\t" + "subs x21, x21, x20\n\t" + "csetm x21, cc\n\t" + "orr x25, x25, x21\n\t" + "ldp x21, x22, [%[m], 0]\n\t" + "ldp x23, x24, [%[m], 16]\n\t" + "and x21, x21, x25\n\t" + "and x22, x22, x25\n\t" + "and x23, x23, x25\n\t" + "and x24, x24, x25\n\t" + "subs x4, x4, x21\n\t" + "sbcs x5, x5, x22\n\t" + "sbcs x6, x6, x23\n\t" + "sbcs x7, x7, x24\n\t" + "ldp x21, x22, [%[m], 32]\n\t" + "ldp x23, x24, [%[m], 48]\n\t" + "and x21, x21, x25\n\t" + "and x22, x22, x25\n\t" + "and x23, x23, x25\n\t" + "and x24, x24, x25\n\t" + "sbcs x8, x8, x21\n\t" + "sbcs x9, x9, x22\n\t" + "sbcs x10, x10, x23\n\t" + "sbcs x11, x11, x24\n\t" + "ldp x21, x22, [%[m], 64]\n\t" + "ldp x23, x24, [%[m], 80]\n\t" + "and x21, x21, x25\n\t" + "and x22, x22, x25\n\t" + "and x23, x23, x25\n\t" + "and x24, x24, x25\n\t" + "sbcs x12, x12, x21\n\t" + "sbcs x13, x13, x22\n\t" + "sbcs x14, x14, x23\n\t" + "sbcs x15, x15, x24\n\t" + "ldp x21, x22, [%[m], 96]\n\t" + "ldp x23, x24, [%[m], 112]\n\t" + "and x21, x21, x25\n\t" + "and x22, x22, x25\n\t" + "and x23, x23, x25\n\t" + "and x24, x24, x25\n\t" + "sbcs x16, x16, x21\n\t" + "sbcs x17, x17, x22\n\t" + "sbcs x19, x19, x23\n\t" + "sbc x20, x20, x24\n\t" + "stp x4, x5, [%[r], 0]\n\t" + "stp x6, x7, [%[r], 16]\n\t" + "stp x8, x9, [%[r], 32]\n\t" + "stp x10, x11, [%[r], 48]\n\t" + "stp x12, x13, [%[r], 64]\n\t" + "stp x14, x15, [%[r], 80]\n\t" + "stp x16, x17, [%[r], 96]\n\t" + "stp x19, x20, [%[r], 112]\n\t" + : + : [r] "r" (r), [a] "r" (a), [m] "r" (m) + : "memory", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24", "x25" + ); +} + +/* Triple a Montgomery form number (r = a + a + a % m). + * + * r Result of Tripling. + * a Number to triple in Montogmery form. + * m Modulus (prime). + */ +static void sp_1024_mont_tpl_16(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + __asm__ __volatile__ ( + "ldp x4, x5, [%[a], 0]\n\t" + "ldp x6, x7, [%[a], 16]\n\t" + "ldp x8, x9, [%[a], 32]\n\t" + "ldp x10, x11, [%[a], 48]\n\t" + "ldp x12, x13, [%[a], 64]\n\t" + "ldp x14, x15, [%[a], 80]\n\t" + "ldp x16, x17, [%[a], 96]\n\t" + "ldp x19, x20, [%[a], 112]\n\t" + "adds x4, x4, x4\n\t" + "adcs x5, x5, x5\n\t" + "adcs x6, x6, x6\n\t" + "adcs x7, x7, x7\n\t" + "adcs x8, x8, x8\n\t" + "adcs x9, x9, x9\n\t" + "adcs x10, x10, x10\n\t" + "adcs x11, x11, x11\n\t" + "adcs x12, x12, x12\n\t" + "adcs x13, x13, x13\n\t" + "adcs x14, x14, x14\n\t" + "adcs x15, x15, x15\n\t" + "adcs x16, x16, x16\n\t" + "adcs x17, x17, x17\n\t" + "adcs x19, x19, x19\n\t" + "adcs x20, x20, x20\n\t" + "csetm x25, cs\n\t" + "ldr x21, [%[m], 120]\n\t" + "subs x21, x21, x20\n\t" + "csetm x21, cc\n\t" + "orr x25, x25, x21\n\t" + "ldp x21, x22, [%[m], 0]\n\t" + "ldp x23, x24, [%[m], 16]\n\t" + "and x21, x21, x25\n\t" + "and x22, x22, x25\n\t" + "and x23, x23, x25\n\t" + "and x24, x24, x25\n\t" + "subs x4, x4, x21\n\t" + "sbcs x5, x5, x22\n\t" + "sbcs x6, x6, x23\n\t" + "sbcs x7, x7, x24\n\t" + "ldp x21, x22, [%[m], 32]\n\t" + "ldp x23, x24, [%[m], 48]\n\t" + "and x21, x21, x25\n\t" + "and x22, x22, x25\n\t" + "and x23, x23, x25\n\t" + "and x24, x24, x25\n\t" + "sbcs x8, x8, x21\n\t" + "sbcs x9, x9, x22\n\t" + "sbcs x10, x10, x23\n\t" + "sbcs x11, x11, x24\n\t" + "ldp x21, x22, [%[m], 64]\n\t" + "ldp x23, x24, [%[m], 80]\n\t" + "and x21, x21, x25\n\t" + "and x22, x22, x25\n\t" + "and x23, x23, x25\n\t" + "and x24, x24, x25\n\t" + "sbcs x12, x12, x21\n\t" + "sbcs x13, x13, x22\n\t" + "sbcs x14, x14, x23\n\t" + "sbcs x15, x15, x24\n\t" + "ldp x21, x22, [%[m], 96]\n\t" + "ldp x23, x24, [%[m], 112]\n\t" + "and x21, x21, x25\n\t" + "and x22, x22, x25\n\t" + "and x23, x23, x25\n\t" + "and x24, x24, x25\n\t" + "sbcs x16, x16, x21\n\t" + "sbcs x17, x17, x22\n\t" + "sbcs x19, x19, x23\n\t" + "sbc x20, x20, x24\n\t" + "ldp x21, x22, [%[a], 0]\n\t" + "ldp x23, x24, [%[a], 16]\n\t" + "adds x4, x4, x21\n\t" + "adcs x5, x5, x22\n\t" + "adcs x6, x6, x23\n\t" + "adcs x7, x7, x24\n\t" + "ldp x21, x22, [%[a], 32]\n\t" + "ldp x23, x24, [%[a], 48]\n\t" + "adcs x8, x8, x21\n\t" + "adcs x9, x9, x22\n\t" + "adcs x10, x10, x23\n\t" + "adcs x11, x11, x24\n\t" + "ldp x21, x22, [%[a], 64]\n\t" + "ldp x23, x24, [%[a], 80]\n\t" + "adcs x12, x12, x21\n\t" + "adcs x13, x13, x22\n\t" + "adcs x14, x14, x23\n\t" + "adcs x15, x15, x24\n\t" + "ldp x21, x22, [%[a], 96]\n\t" + "ldp x23, x24, [%[a], 112]\n\t" + "adcs x16, x16, x21\n\t" + "adcs x17, x17, x22\n\t" + "adcs x19, x19, x23\n\t" + "adcs x20, x20, x24\n\t" + "csetm x25, cs\n\t" + "ldr x21, [%[m], 120]\n\t" + "subs x21, x21, x20\n\t" + "csetm x21, cc\n\t" + "orr x25, x25, x21\n\t" + "ldp x21, x22, [%[m], 0]\n\t" + "ldp x23, x24, [%[m], 16]\n\t" + "and x21, x21, x25\n\t" + "and x22, x22, x25\n\t" + "and x23, x23, x25\n\t" + "and x24, x24, x25\n\t" + "subs x4, x4, x21\n\t" + "sbcs x5, x5, x22\n\t" + "sbcs x6, x6, x23\n\t" + "sbcs x7, x7, x24\n\t" + "ldp x21, x22, [%[m], 32]\n\t" + "ldp x23, x24, [%[m], 48]\n\t" + "and x21, x21, x25\n\t" + "and x22, x22, x25\n\t" + "and x23, x23, x25\n\t" + "and x24, x24, x25\n\t" + "sbcs x8, x8, x21\n\t" + "sbcs x9, x9, x22\n\t" + "sbcs x10, x10, x23\n\t" + "sbcs x11, x11, x24\n\t" + "ldp x21, x22, [%[m], 64]\n\t" + "ldp x23, x24, [%[m], 80]\n\t" + "and x21, x21, x25\n\t" + "and x22, x22, x25\n\t" + "and x23, x23, x25\n\t" + "and x24, x24, x25\n\t" + "sbcs x12, x12, x21\n\t" + "sbcs x13, x13, x22\n\t" + "sbcs x14, x14, x23\n\t" + "sbcs x15, x15, x24\n\t" + "ldp x21, x22, [%[m], 96]\n\t" + "ldp x23, x24, [%[m], 112]\n\t" + "and x21, x21, x25\n\t" + "and x22, x22, x25\n\t" + "and x23, x23, x25\n\t" + "and x24, x24, x25\n\t" + "sbcs x16, x16, x21\n\t" + "sbcs x17, x17, x22\n\t" + "sbcs x19, x19, x23\n\t" + "sbc x20, x20, x24\n\t" + "stp x4, x5, [%[r], 0]\n\t" + "stp x6, x7, [%[r], 16]\n\t" + "stp x8, x9, [%[r], 32]\n\t" + "stp x10, x11, [%[r], 48]\n\t" + "stp x12, x13, [%[r], 64]\n\t" + "stp x14, x15, [%[r], 80]\n\t" + "stp x16, x17, [%[r], 96]\n\t" + "stp x19, x20, [%[r], 112]\n\t" + : + : [r] "r" (r), [a] "r" (a), [m] "r" (m) + : "memory", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24", "x25" + ); +} + +/* Subtract two Montgomery form numbers (r = a - b % m). + * + * r Result of subtration. + * a Number to subtract from in Montogmery form. + * b Number to subtract with in Montogmery form. + * m Modulus (prime). + */ +static void sp_1024_mont_sub_16(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + __asm__ __volatile__ ( + "ldp x4, x5, [%[a], 0]\n\t" + "ldp x6, x7, [%[a], 16]\n\t" + "ldp x8, x9, [%[a], 32]\n\t" + "ldp x10, x11, [%[a], 48]\n\t" + "ldp x12, x13, [%[a], 64]\n\t" + "ldp x14, x15, [%[a], 80]\n\t" + "ldp x16, x17, [%[a], 96]\n\t" + "ldp x19, x20, [%[a], 112]\n\t" + "ldp x21, x22, [%[b], 0]\n\t" + "ldp x23, x24, [%[b], 16]\n\t" + "subs x4, x4, x21\n\t" + "sbcs x5, x5, x22\n\t" + "sbcs x6, x6, x23\n\t" + "sbcs x7, x7, x24\n\t" + "ldp x21, x22, [%[b], 32]\n\t" + "ldp x23, x24, [%[b], 48]\n\t" + "sbcs x8, x8, x21\n\t" + "sbcs x9, x9, x22\n\t" + "sbcs x10, x10, x23\n\t" + "sbcs x11, x11, x24\n\t" + "ldp x21, x22, [%[b], 64]\n\t" + "ldp x23, x24, [%[b], 80]\n\t" + "sbcs x12, x12, x21\n\t" + "sbcs x13, x13, x22\n\t" + "sbcs x14, x14, x23\n\t" + "sbcs x15, x15, x24\n\t" + "ldp x21, x22, [%[b], 96]\n\t" + "ldp x23, x24, [%[b], 112]\n\t" + "sbcs x16, x16, x21\n\t" + "sbcs x17, x17, x22\n\t" + "sbcs x19, x19, x23\n\t" + "sbcs x20, x20, x24\n\t" + "csetm x25, cc\n\t" + "ldp x21, x22, [%[m], 0]\n\t" + "ldp x23, x24, [%[m], 16]\n\t" + "and x21, x21, x25\n\t" + "and x22, x22, x25\n\t" + "and x23, x23, x25\n\t" + "and x24, x24, x25\n\t" + "adds x4, x4, x21\n\t" + "adcs x5, x5, x22\n\t" + "adcs x6, x6, x23\n\t" + "adcs x7, x7, x24\n\t" + "ldp x21, x22, [%[m], 32]\n\t" + "ldp x23, x24, [%[m], 48]\n\t" + "and x21, x21, x25\n\t" + "and x22, x22, x25\n\t" + "and x23, x23, x25\n\t" + "and x24, x24, x25\n\t" + "adcs x8, x8, x21\n\t" + "adcs x9, x9, x22\n\t" + "adcs x10, x10, x23\n\t" + "adcs x11, x11, x24\n\t" + "ldp x21, x22, [%[m], 64]\n\t" + "ldp x23, x24, [%[m], 80]\n\t" + "and x21, x21, x25\n\t" + "and x22, x22, x25\n\t" + "and x23, x23, x25\n\t" + "and x24, x24, x25\n\t" + "adcs x12, x12, x21\n\t" + "adcs x13, x13, x22\n\t" + "adcs x14, x14, x23\n\t" + "adcs x15, x15, x24\n\t" + "ldp x21, x22, [%[m], 96]\n\t" + "ldp x23, x24, [%[m], 112]\n\t" + "and x21, x21, x25\n\t" + "and x22, x22, x25\n\t" + "and x23, x23, x25\n\t" + "and x24, x24, x25\n\t" + "adcs x16, x16, x21\n\t" + "adcs x17, x17, x22\n\t" + "adcs x19, x19, x23\n\t" + "adc x20, x20, x24\n\t" + "stp x4, x5, [%[r], 0]\n\t" + "stp x6, x7, [%[r], 16]\n\t" + "stp x8, x9, [%[r], 32]\n\t" + "stp x10, x11, [%[r], 48]\n\t" + "stp x12, x13, [%[r], 64]\n\t" + "stp x14, x15, [%[r], 80]\n\t" + "stp x16, x17, [%[r], 96]\n\t" + "stp x19, x20, [%[r], 112]\n\t" + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20", "x21", "x22", "x23", "x24", "x25" + ); +} + +/* Conditionally add a and b using the mask m. + * m is -1 to add and 0 when not. + * + * r A single precision number representing conditional add result. + * a A single precision number to add with. + * b A single precision number to add. + * m Mask value to apply. + */ +static sp_digit sp_1024_cond_add_16(sp_digit* r, const sp_digit* a, const sp_digit* b, + sp_digit m) +{ +#ifdef WOLFSSL_SP_SMALL + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov x8, #0\n\t" + "1:\n\t" + "adds %[c], %[c], #-1\n\t" + "ldr x4, [%[a], x8]\n\t" + "ldr x5, [%[b], x8]\n\t" + "and x5, x5, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "cset %[c], cs\n\t" + "str x4, [%[r], x8]\n\t" + "add x8, x8, #8\n\t" + "cmp x8, 128\n\t" + "b.lt 1b\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "x4", "x6", "x5", "x7", "x8", "x9", "x10", "x11", "x12" + ); + + return c; +#else + __asm__ __volatile__ ( + + "ldp x5, x7, [%[b], 0]\n\t" + "ldp x11, x12, [%[b], 16]\n\t" + "ldp x4, x6, [%[a], 0]\n\t" + "and x5, x5, %[m]\n\t" + "ldp x9, x10, [%[a], 16]\n\t" + "and x7, x7, %[m]\n\t" + "adds x4, x4, x5\n\t" + "and x11, x11, %[m]\n\t" + "adcs x6, x6, x7\n\t" + "and x12, x12, %[m]\n\t" + "adcs x9, x9, x11\n\t" + "stp x4, x6, [%[r], 0]\n\t" + "adcs x10, x10, x12\n\t" + "stp x9, x10, [%[r], 16]\n\t" + "ldp x5, x7, [%[b], 32]\n\t" + "ldp x11, x12, [%[b], 48]\n\t" + "ldp x4, x6, [%[a], 32]\n\t" + "and x5, x5, %[m]\n\t" + "ldp x9, x10, [%[a], 48]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "and x11, x11, %[m]\n\t" + "adcs x6, x6, x7\n\t" + "and x12, x12, %[m]\n\t" + "adcs x9, x9, x11\n\t" + "stp x4, x6, [%[r], 32]\n\t" + "adcs x10, x10, x12\n\t" + "stp x9, x10, [%[r], 48]\n\t" + "ldp x5, x7, [%[b], 64]\n\t" + "ldp x11, x12, [%[b], 80]\n\t" + "ldp x4, x6, [%[a], 64]\n\t" + "and x5, x5, %[m]\n\t" + "ldp x9, x10, [%[a], 80]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "and x11, x11, %[m]\n\t" + "adcs x6, x6, x7\n\t" + "and x12, x12, %[m]\n\t" + "adcs x9, x9, x11\n\t" + "stp x4, x6, [%[r], 64]\n\t" + "adcs x10, x10, x12\n\t" + "stp x9, x10, [%[r], 80]\n\t" + "ldp x5, x7, [%[b], 96]\n\t" + "ldp x11, x12, [%[b], 112]\n\t" + "ldp x4, x6, [%[a], 96]\n\t" + "and x5, x5, %[m]\n\t" + "ldp x9, x10, [%[a], 112]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "and x11, x11, %[m]\n\t" + "adcs x6, x6, x7\n\t" + "and x12, x12, %[m]\n\t" + "adcs x9, x9, x11\n\t" + "stp x4, x6, [%[r], 96]\n\t" + "adcs x10, x10, x12\n\t" + "stp x9, x10, [%[r], 112]\n\t" + "cset %[r], cs\n\t" + : [r] "+r" (r) + : [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "x4", "x6", "x5", "x7", "x8", "x9", "x10", "x11", "x12" + ); + + return (sp_digit)r; +#endif /* WOLFSSL_SP_SMALL */ +} + +static void sp_1024_rshift1_16(sp_digit* r, sp_digit* a) +{ + __asm__ __volatile__ ( + "ldr x2, [%[a]]\n\t" + "ldr x3, [%[a], 8]\n\t" + "lsr x2, x2, 1\n\t" + "orr x2, x2, x3, lsl 63\n\t" + "lsr x3, x3, 1\n\t" + "ldr x4, [%[a], 16]\n\t" + "str x2, [%[r], 0]\n\t" + "orr x3, x3, x4, lsl 63\n\t" + "lsr x4, x4, 1\n\t" + "ldr x2, [%[a], 24]\n\t" + "str x3, [%[r], 8]\n\t" + "orr x4, x4, x2, lsl 63\n\t" + "lsr x2, x2, 1\n\t" + "ldr x3, [%[a], 32]\n\t" + "str x4, [%[r], 16]\n\t" + "orr x2, x2, x3, lsl 63\n\t" + "lsr x3, x3, 1\n\t" + "ldr x4, [%[a], 40]\n\t" + "str x2, [%[r], 24]\n\t" + "orr x3, x3, x4, lsl 63\n\t" + "lsr x4, x4, 1\n\t" + "ldr x2, [%[a], 48]\n\t" + "str x3, [%[r], 32]\n\t" + "orr x4, x4, x2, lsl 63\n\t" + "lsr x2, x2, 1\n\t" + "ldr x3, [%[a], 56]\n\t" + "str x4, [%[r], 40]\n\t" + "orr x2, x2, x3, lsl 63\n\t" + "lsr x3, x3, 1\n\t" + "ldr x4, [%[a], 64]\n\t" + "str x2, [%[r], 48]\n\t" + "orr x3, x3, x4, lsl 63\n\t" + "lsr x4, x4, 1\n\t" + "ldr x2, [%[a], 72]\n\t" + "str x3, [%[r], 56]\n\t" + "orr x4, x4, x2, lsl 63\n\t" + "lsr x2, x2, 1\n\t" + "ldr x3, [%[a], 80]\n\t" + "str x4, [%[r], 64]\n\t" + "orr x2, x2, x3, lsl 63\n\t" + "lsr x3, x3, 1\n\t" + "ldr x4, [%[a], 88]\n\t" + "str x2, [%[r], 72]\n\t" + "orr x3, x3, x4, lsl 63\n\t" + "lsr x4, x4, 1\n\t" + "ldr x2, [%[a], 96]\n\t" + "str x3, [%[r], 80]\n\t" + "orr x4, x4, x2, lsl 63\n\t" + "lsr x2, x2, 1\n\t" + "ldr x3, [%[a], 104]\n\t" + "str x4, [%[r], 88]\n\t" + "orr x2, x2, x3, lsl 63\n\t" + "lsr x3, x3, 1\n\t" + "ldr x4, [%[a], 112]\n\t" + "str x2, [%[r], 96]\n\t" + "orr x3, x3, x4, lsl 63\n\t" + "lsr x4, x4, 1\n\t" + "ldr x2, [%[a], 120]\n\t" + "str x3, [%[r], 104]\n\t" + "orr x4, x4, x2, lsl 63\n\t" + "lsr x2, x2, 1\n\t" + "str x4, [%[r], 112]\n\t" + "str x2, [%[r], 120]\n\t" + : + : [r] "r" (r), [a] "r" (a) + : "memory", "x2", "x3", "x4" + ); +} + +/* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m) + * + * r Result of division by 2. + * a Number to divide. + * m Modulus (prime). + */ +static void sp_1024_div2_16(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_digit o; + + o = sp_1024_cond_add_16(r, a, m, 0 - (a[0] & 1)); + sp_1024_rshift1_16(r, r); + r[15] |= o << 63; +} + +/* Double the Montgomery form projective point p. + * + * r Result of doubling point. + * p Point to double. + * t Temporary ordinate data. + */ +#ifdef WOLFSSL_SP_NONBLOCK +typedef struct sp_1024_proj_point_dbl_16_ctx { + int state; + sp_digit* t1; + sp_digit* t2; + sp_digit* x; + sp_digit* y; + sp_digit* z; +} sp_1024_proj_point_dbl_16_ctx; + +static int sp_1024_proj_point_dbl_16_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r, const sp_point_1024* p, sp_digit* t) +{ + int err = FP_WOULDBLOCK; + sp_1024_proj_point_dbl_16_ctx* ctx = (sp_1024_proj_point_dbl_16_ctx*)sp_ctx->data; + + typedef char ctx_size_test[sizeof(sp_1024_proj_point_dbl_16_ctx) >= sizeof(*sp_ctx) ? -1 : 1]; + (void)sizeof(ctx_size_test); + + switch (ctx->state) { + case 0: + ctx->t1 = t; + ctx->t2 = t + 2*16; + ctx->x = r->x; + ctx->y = r->y; + ctx->z = r->z; + + /* Put infinity into result. */ + if (r != p) { + r->infinity = p->infinity; + } + ctx->state = 1; + break; + case 1: + /* T1 = Z * Z */ + sp_1024_mont_sqr_16(ctx->t1, p->z, p1024_mod, p1024_mp_mod); + ctx->state = 2; + break; + case 2: + /* Z = Y * Z */ + sp_1024_mont_mul_16(ctx->z, p->y, p->z, p1024_mod, p1024_mp_mod); + ctx->state = 3; + break; + case 3: + /* Z = 2Z */ + sp_1024_mont_dbl_16(ctx->z, ctx->z, p1024_mod); + ctx->state = 4; + break; + case 4: + /* T2 = X - T1 */ + sp_1024_mont_sub_16(ctx->t2, p->x, ctx->t1, p1024_mod); + ctx->state = 5; + break; + case 5: + /* T1 = X + T1 */ + sp_1024_mont_add_16(ctx->t1, p->x, ctx->t1, p1024_mod); + ctx->state = 6; + break; + case 6: + /* T2 = T1 * T2 */ + sp_1024_mont_mul_16(ctx->t2, ctx->t1, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 7; + break; + case 7: + /* T1 = 3T2 */ + sp_1024_mont_tpl_16(ctx->t1, ctx->t2, p1024_mod); + ctx->state = 8; + break; + case 8: + /* Y = 2Y */ + sp_1024_mont_dbl_16(ctx->y, p->y, p1024_mod); + ctx->state = 9; + break; + case 9: + /* Y = Y * Y */ + sp_1024_mont_sqr_16(ctx->y, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 10; + break; + case 10: + /* T2 = Y * Y */ + sp_1024_mont_sqr_16(ctx->t2, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 11; + break; + case 11: + /* T2 = T2/2 */ + sp_1024_div2_16(ctx->t2, ctx->t2, p1024_mod); + ctx->state = 12; + break; + case 12: + /* Y = Y * X */ + sp_1024_mont_mul_16(ctx->y, ctx->y, p->x, p1024_mod, p1024_mp_mod); + ctx->state = 13; + break; + case 13: + /* X = T1 * T1 */ + sp_1024_mont_sqr_16(ctx->x, ctx->t1, p1024_mod, p1024_mp_mod); + ctx->state = 14; + break; + case 14: + /* X = X - Y */ + sp_1024_mont_sub_16(ctx->x, ctx->x, ctx->y, p1024_mod); + ctx->state = 15; + break; + case 15: + /* X = X - Y */ + sp_1024_mont_sub_16(ctx->x, ctx->x, ctx->y, p1024_mod); + ctx->state = 16; + break; + case 16: + /* Y = Y - X */ + sp_1024_mont_sub_16(ctx->y, ctx->y, ctx->x, p1024_mod); + ctx->state = 17; + break; + case 17: + /* Y = Y * T1 */ + sp_1024_mont_mul_16(ctx->y, ctx->y, ctx->t1, p1024_mod, p1024_mp_mod); + ctx->state = 18; + break; + case 18: + /* Y = Y - T2 */ + sp_1024_mont_sub_16(ctx->y, ctx->y, ctx->t2, p1024_mod); + ctx->state = 19; + /* fall-through */ + case 19: + err = MP_OKAY; + break; + } + + if (err == MP_OKAY && ctx->state != 19) { + err = FP_WOULDBLOCK; + } + + return err; +} +#endif /* WOLFSSL_SP_NONBLOCK */ + +static void sp_1024_proj_point_dbl_16(sp_point_1024* r, const sp_point_1024* p, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*16; + sp_digit* x; + sp_digit* y; + sp_digit* z; + + x = r->x; + y = r->y; + z = r->z; + /* Put infinity into result. */ + if (r != p) { + r->infinity = p->infinity; + } + + /* T1 = Z * Z */ + sp_1024_mont_sqr_16(t1, p->z, p1024_mod, p1024_mp_mod); + /* Z = Y * Z */ + sp_1024_mont_mul_16(z, p->y, p->z, p1024_mod, p1024_mp_mod); + /* Z = 2Z */ + sp_1024_mont_dbl_16(z, z, p1024_mod); + /* T2 = X - T1 */ + sp_1024_mont_sub_16(t2, p->x, t1, p1024_mod); + /* T1 = X + T1 */ + sp_1024_mont_add_16(t1, p->x, t1, p1024_mod); + /* T2 = T1 * T2 */ + sp_1024_mont_mul_16(t2, t1, t2, p1024_mod, p1024_mp_mod); + /* T1 = 3T2 */ + sp_1024_mont_tpl_16(t1, t2, p1024_mod); + /* Y = 2Y */ + sp_1024_mont_dbl_16(y, p->y, p1024_mod); + /* Y = Y * Y */ + sp_1024_mont_sqr_16(y, y, p1024_mod, p1024_mp_mod); + /* T2 = Y * Y */ + sp_1024_mont_sqr_16(t2, y, p1024_mod, p1024_mp_mod); + /* T2 = T2/2 */ + sp_1024_div2_16(t2, t2, p1024_mod); + /* Y = Y * X */ + sp_1024_mont_mul_16(y, y, p->x, p1024_mod, p1024_mp_mod); + /* X = T1 * T1 */ + sp_1024_mont_sqr_16(x, t1, p1024_mod, p1024_mp_mod); + /* X = X - Y */ + sp_1024_mont_sub_16(x, x, y, p1024_mod); + /* X = X - Y */ + sp_1024_mont_sub_16(x, x, y, p1024_mod); + /* Y = Y - X */ + sp_1024_mont_sub_16(y, y, x, p1024_mod); + /* Y = Y * T1 */ + sp_1024_mont_mul_16(y, y, t1, p1024_mod, p1024_mp_mod); + /* Y = Y - T2 */ + sp_1024_mont_sub_16(y, y, t2, p1024_mod); +} + +/* Double the Montgomery form projective point p a number of times. + * + * r Result of repeated doubling of point. + * p Point to double. + * n Number of times to double + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_dbl_n_16(sp_point_1024* p, int n, + sp_digit* t) +{ + sp_digit* w = t; + sp_digit* a = t + 2*16; + sp_digit* b = t + 4*16; + sp_digit* t1 = t + 6*16; + sp_digit* t2 = t + 8*16; + sp_digit* x; + sp_digit* y; + sp_digit* z; + + x = p->x; + y = p->y; + z = p->z; + + /* Y = 2*Y */ + sp_1024_mont_dbl_16(y, y, p1024_mod); + /* W = Z^4 */ + sp_1024_mont_sqr_16(w, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_16(w, w, p1024_mod, p1024_mp_mod); + +#ifndef WOLFSSL_SP_SMALL + while (--n > 0) +#else + while (--n >= 0) +#endif + { + /* A = 3*(X^2 - W) */ + sp_1024_mont_sqr_16(t1, x, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_16(t1, t1, w, p1024_mod); + sp_1024_mont_tpl_16(a, t1, p1024_mod); + /* B = X*Y^2 */ + sp_1024_mont_sqr_16(t1, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(b, t1, x, p1024_mod, p1024_mp_mod); + /* X = A^2 - 2B */ + sp_1024_mont_sqr_16(x, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_16(t2, b, p1024_mod); + sp_1024_mont_sub_16(x, x, t2, p1024_mod); + /* Z = Z*Y */ + sp_1024_mont_mul_16(z, z, y, p1024_mod, p1024_mp_mod); + /* t2 = Y^4 */ + sp_1024_mont_sqr_16(t1, t1, p1024_mod, p1024_mp_mod); +#ifdef WOLFSSL_SP_SMALL + if (n != 0) +#endif + { + /* W = W*Y^4 */ + sp_1024_mont_mul_16(w, w, t1, p1024_mod, p1024_mp_mod); + } + /* y = 2*A*(B - X) - Y^4 */ + sp_1024_mont_sub_16(y, b, x, p1024_mod); + sp_1024_mont_mul_16(y, y, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_16(y, y, p1024_mod); + sp_1024_mont_sub_16(y, y, t1, p1024_mod); + } +#ifndef WOLFSSL_SP_SMALL + /* A = 3*(X^2 - W) */ + sp_1024_mont_sqr_16(t1, x, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_16(t1, t1, w, p1024_mod); + sp_1024_mont_tpl_16(a, t1, p1024_mod); + /* B = X*Y^2 */ + sp_1024_mont_sqr_16(t1, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(b, t1, x, p1024_mod, p1024_mp_mod); + /* X = A^2 - 2B */ + sp_1024_mont_sqr_16(x, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_16(t2, b, p1024_mod); + sp_1024_mont_sub_16(x, x, t2, p1024_mod); + /* Z = Z*Y */ + sp_1024_mont_mul_16(z, z, y, p1024_mod, p1024_mp_mod); + /* t2 = Y^4 */ + sp_1024_mont_sqr_16(t1, t1, p1024_mod, p1024_mp_mod); + /* y = 2*A*(B - X) - Y^4 */ + sp_1024_mont_sub_16(y, b, x, p1024_mod); + sp_1024_mont_mul_16(y, y, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_16(y, y, p1024_mod); + sp_1024_mont_sub_16(y, y, t1, p1024_mod); +#endif + /* Y = Y/2 */ + sp_1024_div2_16(y, y, p1024_mod); +} + +#ifdef WOLFSSL_SP_SMALL +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_1024_sub_16(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "add x11, %[a], 128\n\t" + "\n1:\n\t" + "subs %[c], xzr, %[c]\n\t" + "ldp x3, x4, [%[a]], #16\n\t" + "ldp x5, x6, [%[a]], #16\n\t" + "ldp x7, x8, [%[b]], #16\n\t" + "sbcs x3, x3, x7\n\t" + "ldp x9, x10, [%[b]], #16\n\t" + "sbcs x4, x4, x8\n\t" + "sbcs x5, x5, x9\n\t" + "stp x3, x4, [%[r]], #16\n\t" + "sbcs x6, x6, x10\n\t" + "stp x5, x6, [%[r]], #16\n\t" + "csetm %[c], cc\n\t" + "cmp %[a], x11\n\t" + "b.ne 1b\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11" + ); + + return c; +} + +#else +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static sp_digit sp_1024_sub_16(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + __asm__ __volatile__ ( + "ldp x3, x4, [%[a], 0]\n\t" + "ldp x7, x8, [%[b], 0]\n\t" + "subs x3, x3, x7\n\t" + "ldp x5, x6, [%[a], 16]\n\t" + "sbcs x4, x4, x8\n\t" + "ldp x9, x10, [%[b], 16]\n\t" + "sbcs x5, x5, x9\n\t" + "stp x3, x4, [%[r], 0]\n\t" + "sbcs x6, x6, x10\n\t" + "stp x5, x6, [%[r], 16]\n\t" + "ldp x3, x4, [%[a], 32]\n\t" + "ldp x7, x8, [%[b], 32]\n\t" + "sbcs x3, x3, x7\n\t" + "ldp x5, x6, [%[a], 48]\n\t" + "sbcs x4, x4, x8\n\t" + "ldp x9, x10, [%[b], 48]\n\t" + "sbcs x5, x5, x9\n\t" + "stp x3, x4, [%[r], 32]\n\t" + "sbcs x6, x6, x10\n\t" + "stp x5, x6, [%[r], 48]\n\t" + "ldp x3, x4, [%[a], 64]\n\t" + "ldp x7, x8, [%[b], 64]\n\t" + "sbcs x3, x3, x7\n\t" + "ldp x5, x6, [%[a], 80]\n\t" + "sbcs x4, x4, x8\n\t" + "ldp x9, x10, [%[b], 80]\n\t" + "sbcs x5, x5, x9\n\t" + "stp x3, x4, [%[r], 64]\n\t" + "sbcs x6, x6, x10\n\t" + "stp x5, x6, [%[r], 80]\n\t" + "ldp x3, x4, [%[a], 96]\n\t" + "ldp x7, x8, [%[b], 96]\n\t" + "sbcs x3, x3, x7\n\t" + "ldp x5, x6, [%[a], 112]\n\t" + "sbcs x4, x4, x8\n\t" + "ldp x9, x10, [%[b], 112]\n\t" + "sbcs x5, x5, x9\n\t" + "stp x3, x4, [%[r], 96]\n\t" + "sbcs x6, x6, x10\n\t" + "stp x5, x6, [%[r], 112]\n\t" + "csetm %[r], cc\n\t" + : [r] "+r" (r) + : [a] "r" (a), [b] "r" (b) + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10" + ); + + return (sp_digit)r; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Compare two numbers to determine if they are equal. + * Constant time implementation. + * + * a First number to compare. + * b Second number to compare. + * returns 1 when equal and 0 otherwise. + */ +static int sp_1024_cmp_equal_16(const sp_digit* a, const sp_digit* b) +{ + return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) | (a[3] ^ b[3]) | + (a[4] ^ b[4]) | (a[5] ^ b[5]) | (a[6] ^ b[6]) | (a[7] ^ b[7]) | + (a[8] ^ b[8]) | (a[9] ^ b[9]) | (a[10] ^ b[10]) | (a[11] ^ b[11]) | + (a[12] ^ b[12]) | (a[13] ^ b[13]) | (a[14] ^ b[14]) | (a[15] ^ b[15])) == 0; +} + +/* Add two Montgomery form projective points. + * + * r Result of addition. + * p First point to add. + * q Second point to add. + * t Temporary ordinate data. + */ + +#ifdef WOLFSSL_SP_NONBLOCK +typedef struct sp_1024_proj_point_add_16_ctx { + int state; + sp_1024_proj_point_dbl_16_ctx dbl_ctx; + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1; + sp_digit* t2; + sp_digit* t3; + sp_digit* t4; + sp_digit* t5; + sp_digit* x; + sp_digit* y; + sp_digit* z; +} sp_1024_proj_point_add_16_ctx; + +static int sp_1024_proj_point_add_16_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r, + const sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + int err = FP_WOULDBLOCK; + sp_1024_proj_point_add_16_ctx* ctx = (sp_1024_proj_point_add_16_ctx*)sp_ctx->data; + + /* Ensure only the first point is the same as the result. */ + if (q == r) { + const sp_point_1024* a = p; + p = q; + q = a; + } + + typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_16_ctx) >= sizeof(*sp_ctx) ? -1 : 1]; + (void)sizeof(ctx_size_test); + + switch (ctx->state) { + case 0: /* INIT */ + ctx->t1 = t; + ctx->t2 = t + 2*16; + ctx->t3 = t + 4*16; + ctx->t4 = t + 6*16; + ctx->t5 = t + 8*16; + + ctx->state = 1; + break; + case 1: + /* Check double */ + (void)sp_1024_sub_16(ctx->t1, p1024_mod, q->y); + sp_1024_norm_16(ctx->t1); + if ((sp_1024_cmp_equal_16(p->x, q->x) & sp_1024_cmp_equal_16(p->z, q->z) & + (sp_1024_cmp_equal_16(p->y, q->y) | sp_1024_cmp_equal_16(p->y, ctx->t1))) != 0) + { + XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx)); + ctx->state = 2; + } + else { + ctx->state = 3; + } + break; + case 2: + err = sp_1024_proj_point_dbl_16_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, r, p, t); + if (err == MP_OKAY) + ctx->state = 27; /* done */ + break; + case 3: + { + int i; + ctx->rp[0] = r; + + /*lint allow cast to different type of pointer*/ + ctx->rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(ctx->rp[1], 0, sizeof(sp_point_1024)); + ctx->x = ctx->rp[p->infinity | q->infinity]->x; + ctx->y = ctx->rp[p->infinity | q->infinity]->y; + ctx->z = ctx->rp[p->infinity | q->infinity]->z; + + ctx->ap[0] = p; + ctx->ap[1] = q; + for (i=0; i<16; i++) { + r->x[i] = ctx->ap[p->infinity]->x[i]; + } + for (i=0; i<16; i++) { + r->y[i] = ctx->ap[p->infinity]->y[i]; + } + for (i=0; i<16; i++) { + r->z[i] = ctx->ap[p->infinity]->z[i]; + } + r->infinity = ctx->ap[p->infinity]->infinity; + + ctx->state = 4; + break; + } + case 4: + /* U1 = X1*Z2^2 */ + sp_1024_mont_sqr_16(ctx->t1, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 5; + break; + case 5: + sp_1024_mont_mul_16(ctx->t3, ctx->t1, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 6; + break; + case 6: + sp_1024_mont_mul_16(ctx->t1, ctx->t1, ctx->x, p1024_mod, p1024_mp_mod); + ctx->state = 7; + break; + case 7: + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_16(ctx->t2, ctx->z, p1024_mod, p1024_mp_mod); + ctx->state = 8; + break; + case 8: + sp_1024_mont_mul_16(ctx->t4, ctx->t2, ctx->z, p1024_mod, p1024_mp_mod); + ctx->state = 9; + break; + case 9: + sp_1024_mont_mul_16(ctx->t2, ctx->t2, q->x, p1024_mod, p1024_mp_mod); + ctx->state = 10; + break; + case 10: + /* S1 = Y1*Z2^3 */ + sp_1024_mont_mul_16(ctx->t3, ctx->t3, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 11; + break; + case 11: + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_16(ctx->t4, ctx->t4, q->y, p1024_mod, p1024_mp_mod); + ctx->state = 12; + break; + case 12: + /* H = U2 - U1 */ + sp_1024_mont_sub_16(ctx->t2, ctx->t2, ctx->t1, p1024_mod); + ctx->state = 13; + break; + case 13: + /* R = S2 - S1 */ + sp_1024_mont_sub_16(ctx->t4, ctx->t4, ctx->t3, p1024_mod); + ctx->state = 14; + break; + case 14: + /* Z3 = H*Z1*Z2 */ + sp_1024_mont_mul_16(ctx->z, ctx->z, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 15; + break; + case 15: + sp_1024_mont_mul_16(ctx->z, ctx->z, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 16; + break; + case 16: + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_1024_mont_sqr_16(ctx->x, ctx->t4, p1024_mod, p1024_mp_mod); + ctx->state = 17; + break; + case 17: + sp_1024_mont_sqr_16(ctx->t5, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 18; + break; + case 18: + sp_1024_mont_mul_16(ctx->y, ctx->t1, ctx->t5, p1024_mod, p1024_mp_mod); + ctx->state = 19; + break; + case 19: + sp_1024_mont_mul_16(ctx->t5, ctx->t5, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 20; + break; + case 20: + sp_1024_mont_sub_16(ctx->x, ctx->x, ctx->t5, p1024_mod); + ctx->state = 21; + break; + case 21: + sp_1024_mont_dbl_16(ctx->t1, ctx->y, p1024_mod); + ctx->state = 22; + break; + case 22: + sp_1024_mont_sub_16(ctx->x, ctx->x, ctx->t1, p1024_mod); + ctx->state = 23; + break; + case 23: + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_1024_mont_sub_16(ctx->y, ctx->y, ctx->x, p1024_mod); + ctx->state = 24; + break; + case 24: + sp_1024_mont_mul_16(ctx->y, ctx->y, ctx->t4, p1024_mod, p1024_mp_mod); + ctx->state = 25; + break; + case 25: + sp_1024_mont_mul_16(ctx->t5, ctx->t5, ctx->t3, p1024_mod, p1024_mp_mod); + ctx->state = 26; + break; + case 26: + sp_1024_mont_sub_16(ctx->y, ctx->y, ctx->t5, p1024_mod); + ctx->state = 27; + /* fall-through */ + case 27: + err = MP_OKAY; + break; + } + + if (err == MP_OKAY && ctx->state != 27) { + err = FP_WOULDBLOCK; + } + return err; +} +#endif /* WOLFSSL_SP_NONBLOCK */ + +static void sp_1024_proj_point_add_16(sp_point_1024* r, + const sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*16; + sp_digit* t3 = t + 4*16; + sp_digit* t4 = t + 6*16; + sp_digit* t5 = t + 8*16; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Ensure only the first point is the same as the result. */ + if (q == r) { + const sp_point_1024* a = p; + p = q; + q = a; + } + + /* Check double */ + (void)sp_1024_mont_sub_16(t1, p1024_mod, q->y, p1024_mod); + sp_1024_norm_16(t1); + if ((sp_1024_cmp_equal_16(p->x, q->x) & sp_1024_cmp_equal_16(p->z, q->z) & + (sp_1024_cmp_equal_16(p->y, q->y) | sp_1024_cmp_equal_16(p->y, t1))) != 0) { + sp_1024_proj_point_dbl_16(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_1024)); + x = rp[p->infinity | q->infinity]->x; + y = rp[p->infinity | q->infinity]->y; + z = rp[p->infinity | q->infinity]->z; + + ap[0] = p; + ap[1] = q; + for (i=0; i<16; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<16; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<16; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U1 = X1*Z2^2 */ + sp_1024_mont_sqr_16(t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t3, t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t1, t1, x, p1024_mod, p1024_mp_mod); + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_16(t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t4, t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t2, t2, q->x, p1024_mod, p1024_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_1024_mont_mul_16(t3, t3, y, p1024_mod, p1024_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_16(t4, t4, q->y, p1024_mod, p1024_mp_mod); + /* H = U2 - U1 */ + sp_1024_mont_sub_16(t2, t2, t1, p1024_mod); + /* R = S2 - S1 */ + sp_1024_mont_sub_16(t4, t4, t3, p1024_mod); + /* Z3 = H*Z1*Z2 */ + sp_1024_mont_mul_16(z, z, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(z, z, t2, p1024_mod, p1024_mp_mod); + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_1024_mont_sqr_16(x, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_16(t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(y, t1, t5, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t5, t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_16(x, x, t5, p1024_mod); + sp_1024_mont_dbl_16(t1, y, p1024_mod); + sp_1024_mont_sub_16(x, x, t1, p1024_mod); + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_1024_mont_sub_16(y, y, x, p1024_mod); + sp_1024_mont_mul_16(y, y, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t5, t5, t3, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_16(y, y, t5, p1024_mod); + } +} + +/* Double the Montgomery form projective point p a number of times. + * + * r Result of repeated doubling of point. + * p Point to double. + * n Number of times to double + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_dbl_n_store_16(sp_point_1024* r, + const sp_point_1024* p, int n, int m, sp_digit* t) +{ + sp_digit* w = t; + sp_digit* a = t + 2*16; + sp_digit* b = t + 4*16; + sp_digit* t1 = t + 6*16; + sp_digit* t2 = t + 8*16; + sp_digit* x = r[2*m].x; + sp_digit* y = r[(1<x[i]; + } + for (i=0; i<16; i++) { + y[i] = p->y[i]; + } + for (i=0; i<16; i++) { + z[i] = p->z[i]; + } + + /* Y = 2*Y */ + sp_1024_mont_dbl_16(y, y, p1024_mod); + /* W = Z^4 */ + sp_1024_mont_sqr_16(w, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_16(w, w, p1024_mod, p1024_mp_mod); + j = m; + for (i=1; i<=n; i++) { + j *= 2; + + /* A = 3*(X^2 - W) */ + sp_1024_mont_sqr_16(t1, x, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_16(t1, t1, w, p1024_mod); + sp_1024_mont_tpl_16(a, t1, p1024_mod); + /* B = X*Y^2 */ + sp_1024_mont_sqr_16(t2, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(b, t2, x, p1024_mod, p1024_mp_mod); + x = r[j].x; + /* X = A^2 - 2B */ + sp_1024_mont_sqr_16(x, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_16(t1, b, p1024_mod); + sp_1024_mont_sub_16(x, x, t1, p1024_mod); + /* Z = Z*Y */ + sp_1024_mont_mul_16(r[j].z, z, y, p1024_mod, p1024_mp_mod); + z = r[j].z; + /* t2 = Y^4 */ + sp_1024_mont_sqr_16(t2, t2, p1024_mod, p1024_mp_mod); + if (i != n) { + /* W = W*Y^4 */ + sp_1024_mont_mul_16(w, w, t2, p1024_mod, p1024_mp_mod); + } + /* y = 2*A*(B - X) - Y^4 */ + sp_1024_mont_sub_16(y, b, x, p1024_mod); + sp_1024_mont_mul_16(y, y, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_16(y, y, p1024_mod); + sp_1024_mont_sub_16(y, y, t2, p1024_mod); + + /* Y = Y/2 */ + sp_1024_div2_16(r[j].y, y, p1024_mod); + r[j].infinity = 0; + } +} + +/* Add two Montgomery form projective points. + * + * ra Result of addition. + * rs Result of subtraction. + * p First point to add. + * q Second point to add. + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_add_sub_16(sp_point_1024* ra, + sp_point_1024* rs, const sp_point_1024* p, const sp_point_1024* q, + sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*16; + sp_digit* t3 = t + 4*16; + sp_digit* t4 = t + 6*16; + sp_digit* t5 = t + 8*16; + sp_digit* t6 = t + 10*16; + sp_digit* x = ra->x; + sp_digit* y = ra->y; + sp_digit* z = ra->z; + sp_digit* xs = rs->x; + sp_digit* ys = rs->y; + sp_digit* zs = rs->z; + + + XMEMCPY(x, p->x, sizeof(p->x) / 2); + XMEMCPY(y, p->y, sizeof(p->y) / 2); + XMEMCPY(z, p->z, sizeof(p->z) / 2); + ra->infinity = 0; + rs->infinity = 0; + + /* U1 = X1*Z2^2 */ + sp_1024_mont_sqr_16(t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t3, t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t1, t1, x, p1024_mod, p1024_mp_mod); + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_16(t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t4, t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t2, t2, q->x, p1024_mod, p1024_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_1024_mont_mul_16(t3, t3, y, p1024_mod, p1024_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_16(t4, t4, q->y, p1024_mod, p1024_mp_mod); + /* H = U2 - U1 */ + sp_1024_mont_sub_16(t2, t2, t1, p1024_mod); + /* RS = S2 + S1 */ + sp_1024_mont_add_16(t6, t4, t3, p1024_mod); + /* R = S2 - S1 */ + sp_1024_mont_sub_16(t4, t4, t3, p1024_mod); + /* Z3 = H*Z1*Z2 */ + /* ZS = H*Z1*Z2 */ + sp_1024_mont_mul_16(z, z, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(z, z, t2, p1024_mod, p1024_mp_mod); + XMEMCPY(zs, z, sizeof(p->z)/2); + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + /* XS = RS^2 - H^3 - 2*U1*H^2 */ + sp_1024_mont_sqr_16(x, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_16(xs, t6, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_16(t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(y, t1, t5, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t5, t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_16(x, x, t5, p1024_mod); + sp_1024_mont_sub_16(xs, xs, t5, p1024_mod); + sp_1024_mont_dbl_16(t1, y, p1024_mod); + sp_1024_mont_sub_16(x, x, t1, p1024_mod); + sp_1024_mont_sub_16(xs, xs, t1, p1024_mod); + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + /* YS = -RS*(U1*H^2 - XS) - S1*H^3 */ + sp_1024_mont_sub_16(ys, y, xs, p1024_mod); + sp_1024_mont_sub_16(y, y, x, p1024_mod); + sp_1024_mont_mul_16(y, y, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_16(t6, p1024_mod, t6, p1024_mod); + sp_1024_mont_mul_16(ys, ys, t6, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t5, t5, t3, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_16(y, y, t5, p1024_mod); + sp_1024_mont_sub_16(ys, ys, t5, p1024_mod); +} + +/* Structure used to describe recoding of scalar multiplication. */ +typedef struct ecc_recode_1024 { + /* Index into pre-computation table. */ + uint8_t i; + /* Use the negative of the point. */ + uint8_t neg; +} ecc_recode_1024; + +/* The index into pre-computation table to use. */ +static const uint8_t recode_index_16_7[130] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, + 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, + 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, + 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, + 0, 1, +}; + +/* Whether to negate y-ordinate. */ +static const uint8_t recode_neg_16_7[130] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, +}; + +/* Recode the scalar for multiplication using pre-computed values and + * subtraction. + * + * k Scalar to multiply by. + * v Vector of operations to perform. + */ +static void sp_1024_ecc_recode_7_16(const sp_digit* k, ecc_recode_1024* v) +{ + int i; + int j; + uint8_t y; + int carry = 0; + int o; + sp_digit n; + + j = 0; + n = k[j]; + o = 0; + for (i=0; i<147; i++) { + y = (int8_t)n; + if (o + 7 < 64) { + y &= 0x7f; + n >>= 7; + o += 7; + } + else if (o + 7 == 64) { + n >>= 7; + if (++j < 16) + n = k[j]; + o = 0; + } + else if (++j < 16) { + n = k[j]; + y |= (uint8_t)((n << (64 - o)) & 0x7f); + o -= 57; + n >>= o; + } + + y += (uint8_t)carry; + v[i].i = recode_index_16_7[y]; + v[i].neg = recode_neg_16_7[y]; + carry = (y >> 7) + v[i].neg; + } +} + +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Window technique of 7 bits. (Add-Sub variation.) + * Calculate 0..64 times the point. Use function that adds and + * subtracts the same two points. + * Recode to add or subtract one of the computed points. + * Double to push up. + * NOT a sliding window. + * + * r Resulting point. + * g Point to multiply. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_win_add_sub_16(sp_point_1024* r, const sp_point_1024* g, + const sp_digit* k, int map, int ct, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 td[65]; + sp_point_1024 rtd; + sp_point_1024 pd; + sp_digit tmpd[2 * 16 * 6]; +#endif + sp_point_1024* t; + sp_point_1024* rt; + sp_point_1024* p = NULL; + sp_digit* tmp; + sp_digit* negy; + int i; + ecc_recode_1024 v[147]; + int err; + + /* Constant time used for cache attack resistance implementation. */ + (void)ct; + (void)heap; + + err = sp_1024_point_new_16(heap, rtd, rt); + if (err == MP_OKAY) + err = sp_1024_point_new_16(heap, pd, p); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) * 65, heap, DYNAMIC_TYPE_ECC); + if (t == NULL) + err = MEMORY_E; + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 16 * 6, heap, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) + err = MEMORY_E; +#else + t = td; + tmp = tmpd; +#endif + + + if (err == MP_OKAY) { + /* t[0] = {0, 0, 1} * norm */ + XMEMSET(&t[0], 0, sizeof(t[0])); + t[0].infinity = 1; + /* t[1] = {g->x, g->y, g->z} * norm */ + err = sp_1024_mod_mul_norm_16(t[1].x, g->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(t[1].y, g->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(t[1].z, g->z, p1024_mod); + } + + if (err == MP_OKAY) { + t[1].infinity = 0; + /* t[2] ... t[64] */ + sp_1024_proj_point_dbl_n_store_16(t, &t[ 1], 6, 1, tmp); + sp_1024_proj_point_add_16(&t[ 3], &t[ 2], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[ 6], &t[ 3], tmp); + sp_1024_proj_point_add_sub_16(&t[ 7], &t[ 5], &t[ 6], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[10], &t[ 5], tmp); + sp_1024_proj_point_add_sub_16(&t[11], &t[ 9], &t[10], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[12], &t[ 6], tmp); + sp_1024_proj_point_dbl_16(&t[14], &t[ 7], tmp); + sp_1024_proj_point_add_sub_16(&t[15], &t[13], &t[14], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[18], &t[ 9], tmp); + sp_1024_proj_point_add_sub_16(&t[19], &t[17], &t[18], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[20], &t[10], tmp); + sp_1024_proj_point_dbl_16(&t[22], &t[11], tmp); + sp_1024_proj_point_add_sub_16(&t[23], &t[21], &t[22], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[24], &t[12], tmp); + sp_1024_proj_point_dbl_16(&t[26], &t[13], tmp); + sp_1024_proj_point_add_sub_16(&t[27], &t[25], &t[26], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[28], &t[14], tmp); + sp_1024_proj_point_dbl_16(&t[30], &t[15], tmp); + sp_1024_proj_point_add_sub_16(&t[31], &t[29], &t[30], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[34], &t[17], tmp); + sp_1024_proj_point_add_sub_16(&t[35], &t[33], &t[34], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[36], &t[18], tmp); + sp_1024_proj_point_dbl_16(&t[38], &t[19], tmp); + sp_1024_proj_point_add_sub_16(&t[39], &t[37], &t[38], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[40], &t[20], tmp); + sp_1024_proj_point_dbl_16(&t[42], &t[21], tmp); + sp_1024_proj_point_add_sub_16(&t[43], &t[41], &t[42], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[44], &t[22], tmp); + sp_1024_proj_point_dbl_16(&t[46], &t[23], tmp); + sp_1024_proj_point_add_sub_16(&t[47], &t[45], &t[46], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[48], &t[24], tmp); + sp_1024_proj_point_dbl_16(&t[50], &t[25], tmp); + sp_1024_proj_point_add_sub_16(&t[51], &t[49], &t[50], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[52], &t[26], tmp); + sp_1024_proj_point_dbl_16(&t[54], &t[27], tmp); + sp_1024_proj_point_add_sub_16(&t[55], &t[53], &t[54], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[56], &t[28], tmp); + sp_1024_proj_point_dbl_16(&t[58], &t[29], tmp); + sp_1024_proj_point_add_sub_16(&t[59], &t[57], &t[58], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[60], &t[30], tmp); + sp_1024_proj_point_dbl_16(&t[62], &t[31], tmp); + sp_1024_proj_point_add_sub_16(&t[63], &t[61], &t[62], &t[ 1], tmp); + + negy = t[0].y; + + sp_1024_ecc_recode_7_16(k, v); + + i = 146; + XMEMCPY(rt, &t[v[i].i], sizeof(sp_point_1024)); + for (--i; i>=0; i--) { + sp_1024_proj_point_dbl_n_16(rt, 7, tmp); + XMEMCPY(p, &t[v[i].i], sizeof(sp_point_1024)); + sp_1024_mont_sub_16(negy, p1024_mod, p->y, p1024_mod); + sp_1024_norm_16(negy); + sp_1024_cond_copy_16(p->y, negy, (sp_digit)0 - v[i].neg); + sp_1024_proj_point_add_16(rt, rt, p, tmp); + } + + if (map != 0) { + sp_1024_map_16(r, rt, tmp); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_1024)); + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (t != NULL) + XFREE(t, heap, DYNAMIC_TYPE_ECC); + if (tmp != NULL) + XFREE(tmp, heap, DYNAMIC_TYPE_ECC); +#endif + sp_1024_point_free_16(p, 0, heap); + sp_1024_point_free_16(rt, 0, heap); + + return err; +} + +/* A table entry for pre-computed points. */ +typedef struct sp_table_entry_1024 { + sp_digit x[16]; + sp_digit y[16]; +} sp_table_entry_1024; + +#ifdef FP_ECC +#endif /* FP_ECC */ +/* Add two Montgomery form projective points. The second point has a q value of + * one. + * Only the first point can be the same pointer as the result point. + * + * r Result of addition. + * p First point to add. + * q Second point to add. + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_add_qz1_16(sp_point_1024* r, const sp_point_1024* p, + const sp_point_1024* q, sp_digit* t) +{ + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*16; + sp_digit* t3 = t + 4*16; + sp_digit* t4 = t + 6*16; + sp_digit* t5 = t + 8*16; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Check double */ + (void)sp_1024_mont_sub_16(t1, p1024_mod, q->y, p1024_mod); + sp_1024_norm_16(t1); + if ((sp_1024_cmp_equal_16(p->x, q->x) & sp_1024_cmp_equal_16(p->z, q->z) & + (sp_1024_cmp_equal_16(p->y, q->y) | sp_1024_cmp_equal_16(p->y, t1))) != 0) { + sp_1024_proj_point_dbl_16(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_1024)); + x = rp[p->infinity | q->infinity]->x; + y = rp[p->infinity | q->infinity]->y; + z = rp[p->infinity | q->infinity]->z; + + ap[0] = p; + ap[1] = q; + for (i=0; i<16; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<16; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<16; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_16(t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t4, t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t2, t2, q->x, p1024_mod, p1024_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_16(t4, t4, q->y, p1024_mod, p1024_mp_mod); + /* H = U2 - X1 */ + sp_1024_mont_sub_16(t2, t2, x, p1024_mod); + /* R = S2 - Y1 */ + sp_1024_mont_sub_16(t4, t4, y, p1024_mod); + /* Z3 = H*Z1 */ + sp_1024_mont_mul_16(z, z, t2, p1024_mod, p1024_mp_mod); + /* X3 = R^2 - H^3 - 2*X1*H^2 */ + sp_1024_mont_sqr_16(t1, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_16(t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t3, x, t5, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t5, t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_16(x, t1, t5, p1024_mod); + sp_1024_mont_dbl_16(t1, t3, p1024_mod); + sp_1024_mont_sub_16(x, x, t1, p1024_mod); + /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */ + sp_1024_mont_sub_16(t3, t3, x, p1024_mod); + sp_1024_mont_mul_16(t3, t3, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t5, t5, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_16(y, t3, t5, p1024_mod); + } +} + +#if defined(FP_ECC) || !defined(WOLFSSL_SP_SMALL) +/* Convert the projective point to affine. + * Ordinates are in Montgomery form. + * + * a Point to convert. + * t Temporary data. + */ +static void sp_1024_proj_to_affine_16(sp_point_1024* a, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 16; + sp_digit* tmp = t + 4 * 16; + + sp_1024_mont_inv_16(t1, a->z, tmp); + + sp_1024_mont_sqr_16(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t1, t2, t1, p1024_mod, p1024_mp_mod); + + sp_1024_mont_mul_16(a->x, a->x, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(a->y, a->y, t1, p1024_mod, p1024_mp_mod); + XMEMCPY(a->z, p1024_norm_mod, sizeof(p1024_norm_mod)); +} + +/* Generate the pre-computed table of points for the base point. + * + * width = 8 + * 256 entries + * 128 bits between + * + * a The base point. + * table Place to store generated point data. + * tmp Temporary data. + * heap Heap to use for allocation. + */ +static int sp_1024_gen_stripe_table_16(const sp_point_1024* a, + sp_table_entry_1024* table, sp_digit* tmp, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 td; + sp_point_1024 s1d; + sp_point_1024 s2d; +#endif + sp_point_1024* t; + sp_point_1024* s1 = NULL; + sp_point_1024* s2 = NULL; + int i; + int j; + int err; + + (void)heap; + + err = sp_1024_point_new_16(heap, td, t); + if (err == MP_OKAY) { + err = sp_1024_point_new_16(heap, s1d, s1); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_16(heap, s2d, s2); + } + + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(t->x, a->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(t->y, a->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(t->z, a->z, p1024_mod); + } + if (err == MP_OKAY) { + t->infinity = 0; + sp_1024_proj_to_affine_16(t, tmp); + + XMEMCPY(s1->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + s1->infinity = 0; + XMEMCPY(s2->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + s2->infinity = 0; + + /* table[0] = {0, 0, infinity} */ + XMEMSET(&table[0], 0, sizeof(sp_table_entry_1024)); + /* table[1] = Affine version of 'a' in Montgomery form */ + XMEMCPY(table[1].x, t->x, sizeof(table->x)); + XMEMCPY(table[1].y, t->y, sizeof(table->y)); + + for (i=1; i<8; i++) { + sp_1024_proj_point_dbl_n_16(t, 128, tmp); + sp_1024_proj_to_affine_16(t, tmp); + XMEMCPY(table[1<x, sizeof(table->x)); + XMEMCPY(table[1<y, sizeof(table->y)); + } + + for (i=1; i<8; i++) { + XMEMCPY(s1->x, table[1<x)); + XMEMCPY(s1->y, table[1<y)); + for (j=(1<x, table[j-(1<x)); + XMEMCPY(s2->y, table[j-(1<y)); + sp_1024_proj_point_add_qz1_16(t, s1, s2, tmp); + sp_1024_proj_to_affine_16(t, tmp); + XMEMCPY(table[j].x, t->x, sizeof(table->x)); + XMEMCPY(table[j].y, t->y, sizeof(table->y)); + } + } + } + + sp_1024_point_free_16(s2, 0, heap); + sp_1024_point_free_16(s1, 0, heap); + sp_1024_point_free_16( t, 0, heap); + + return err; +} + +#endif /* FP_ECC | !WOLFSSL_SP_SMALL */ +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^128, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * table Pre-computed table. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_stripe_16(sp_point_1024* r, const sp_point_1024* g, + const sp_table_entry_1024* table, const sp_digit* k, int map, + int ct, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 rtd; + sp_point_1024 pd; + sp_digit td[2 * 16 * 5]; +#endif + sp_point_1024* rt; + sp_point_1024* p = NULL; + sp_digit* t; + int i; + int j; + int y; + int x; + int err; + + (void)g; + /* Constant time used for cache attack resistance implementation. */ + (void)ct; + (void)heap; + + + err = sp_1024_point_new_16(heap, rtd, rt); + if (err == MP_OKAY) { + err = sp_1024_point_new_16(heap, pd, p); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 16 * 5, heap, + DYNAMIC_TYPE_ECC); + if (t == NULL) { + err = MEMORY_E; + } +#else + t = td; +#endif + + if (err == MP_OKAY) { + XMEMCPY(p->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + XMEMCPY(rt->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + + y = 0; + x = 127; + for (j=0; j<8; j++) { + y |= (int)(((k[x / 64] >> (x % 64)) & 1) << j); + x += 128; + } + XMEMCPY(rt->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(rt->y, table[y].y, sizeof(table[y].y)); + rt->infinity = !y; + for (i=126; i>=0; i--) { + y = 0; + x = i; + for (j=0; j<8; j++) { + y |= (int)(((k[x / 64] >> (x % 64)) & 1) << j); + x += 128; + } + + sp_1024_proj_point_dbl_16(rt, rt, t); + XMEMCPY(p->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(p->y, table[y].y, sizeof(table[y].y)); + p->infinity = !y; + sp_1024_proj_point_add_qz1_16(rt, rt, p, t); + } + + if (map != 0) { + sp_1024_map_16(r, rt, t); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_1024)); + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (t != NULL) { + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_16(p, 0, heap); + sp_1024_point_free_16(rt, 0, heap); + + return err; +} + +#ifdef FP_ECC +#ifndef FP_ENTRIES + #define FP_ENTRIES 16 +#endif + +/* Cache entry - holds precomputation tables for a point. */ +typedef struct sp_cache_1024_t { + /* X ordinate of point that table was generated from. */ + sp_digit x[16]; + /* Y ordinate of point that table was generated from. */ + sp_digit y[16]; + /* Precomputation table for point. */ + sp_table_entry_1024 table[256]; + /* Count of entries in table. */ + uint32_t cnt; + /* Point and table set in entry. */ + int set; +} sp_cache_1024_t; + +/* Cache of tables. */ +static THREAD_LS_T sp_cache_1024_t sp_cache_1024[FP_ENTRIES]; +/* Index of last entry in cache. */ +static THREAD_LS_T int sp_cache_1024_last = -1; +/* Cache has been initialized. */ +static THREAD_LS_T int sp_cache_1024_inited = 0; + +#ifndef HAVE_THREAD_LS + static volatile int initCacheMutex_1024 = 0; + static wolfSSL_Mutex sp_cache_1024_lock; +#endif + +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ +static void sp_ecc_get_cache_1024(const sp_point_1024* g, sp_cache_1024_t** cache) +{ + int i; + int j; + uint32_t least; + + if (sp_cache_1024_inited == 0) { + for (i=0; ix, sp_cache_1024[i].x) & + sp_1024_cmp_equal_16(g->y, sp_cache_1024[i].y)) { + sp_cache_1024[i].cnt++; + break; + } + } + + /* No match. */ + if (i == FP_ENTRIES) { + /* Find empty entry. */ + i = (sp_cache_1024_last + 1) % FP_ENTRIES; + for (; i != sp_cache_1024_last; i=(i+1)%FP_ENTRIES) { + if (!sp_cache_1024[i].set) { + break; + } + } + + /* Evict least used. */ + if (i == sp_cache_1024_last) { + least = sp_cache_1024[0].cnt; + for (j=1; jx, sizeof(sp_cache_1024[i].x)); + XMEMCPY(sp_cache_1024[i].y, g->y, sizeof(sp_cache_1024[i].y)); + sp_cache_1024[i].set = 1; + sp_cache_1024[i].cnt = 1; + } + + *cache = &sp_cache_1024[i]; + sp_cache_1024_last = i; +} +#endif /* FP_ECC */ + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * r Resulting point. + * g Point to multiply. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_16(sp_point_1024* r, const sp_point_1024* g, const sp_digit* k, + int map, int ct, void* heap) +{ +#ifndef FP_ECC + return sp_1024_ecc_mulmod_win_add_sub_16(r, g, k, map, ct, heap); +#else + sp_digit tmp[2 * 16 * 5]; + sp_cache_1024_t* cache; + int err = MP_OKAY; + +#ifndef HAVE_THREAD_LS + if (initCacheMutex_1024 == 0) { + wc_InitMutex(&sp_cache_1024_lock); + initCacheMutex_1024 = 1; + } + if (wc_LockMutex(&sp_cache_1024_lock) != 0) + err = BAD_MUTEX_E; +#endif /* HAVE_THREAD_LS */ + + if (err == MP_OKAY) { + sp_ecc_get_cache_1024(g, &cache); + if (cache->cnt == 2) + sp_1024_gen_stripe_table_16(g, cache->table, tmp, heap); + +#ifndef HAVE_THREAD_LS + wc_UnLockMutex(&sp_cache_1024_lock); +#endif /* HAVE_THREAD_LS */ + + if (cache->cnt < 2) { + err = sp_1024_ecc_mulmod_win_add_sub_16(r, g, k, map, ct, heap); + } + else { + err = sp_1024_ecc_mulmod_stripe_16(r, g, cache->table, k, + map, ct, heap); + } + } + + return err; +#endif +} + +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * p Point to multiply. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_1024(const mp_int* km, const ecc_point* gm, ecc_point* r, + int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_digit kd[16]; +#endif + sp_point_1024* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_16(heap, p, point); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 16, km); + sp_1024_point_from_ecc_point_16(point, gm); + + err = sp_1024_ecc_mulmod_16(point, point, k, map, 1, heap); + } + if (err == MP_OKAY) { + err = sp_1024_point_to_ecc_point_16(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_16(point, 0, heap); + + return err; +} + +/* Striping precomputation table. + * 8 points combined into a table of 256 points. + * Distance of 128 between points. + */ +static const sp_table_entry_1024 p1024_table[256] = { + /* 0 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 */ + { { 0xbf9c7ec6e0162bc2L,0xddecc6e310a89289L,0x5d599df09e499d81L, + 0x9a96ea286d358218L,0x01aec7d370c5f8dbL,0xe72e49958cf5d066L, + 0xc2e7297d3e91d7f8L,0x8621db92da9f2f5aL,0x4b26c8675a5679edL, + 0x233385df2c56aac1L,0xb88e74d4c6a13f99L,0x1214b173ffa8ec11L, + 0xa0386a271f3f9fefL,0xbd9b1b4ec0e7b44eL,0xafe528dceecd3496L, + 0x8dfff96a1c49f80bL }, + { 0xb4a4753ac03c0c83L,0x68e69d18abcdcd75L,0xe3839b88f775b649L, + 0x803f949abf58f352L,0x5f702679bd0bc15cL,0x85bf5d168ff298c2L, + 0x3f6ebd98c6c7976eL,0x20618af445e3e1b4L,0x67d5598e54e64093L, + 0xb047283b504fed9eL,0x450cabfd70d87517L,0x47d628bf3f5addbeL, + 0x0037ef3078cb4ccaL,0x4e148d3c6b1c4908L,0xe256d3294fcfd837L, + 0x2aa1207bde3c01f3L } }, + /* 2 */ + { { 0xa95b6dae01900955L,0xa5dc9cc1ceb4656dL,0x50c78907e72fe95bL, + 0xa1ae5447a040c334L,0x911913707952ea6eL,0x54ff73436d097305L, + 0xa4db0074bda4d10fL,0xfd5306f191644070L,0x14b9fe738b24522cL, + 0x1468dad67849f762L,0x87b29a18b0dcd2e4L,0xadd7f1a15e1ad492L, + 0x9ac63a81dbba2a1aL,0x01379c5b81223379L,0xf402b2f0b0e53bc8L, + 0x8c3eb27f0bf13b61L }, + { 0x9a4ad3e1e513696fL,0x0350ba5c18c81ffaL,0x1e2fc1363c033d13L, + 0x53da6e7117a531bcL,0x42ec64901aed610dL,0xd33e8df7e99ff567L, + 0xe4aad73e3deed12aL,0xd983b465180f4debL,0x99365269502f30b4L, + 0x7e2799aba8918d7fL,0x0ffe84b6700fc79aL,0x7b4400d640bfd8c2L, + 0xc3a21d215d2641bdL,0x79839442c32621cbL,0xace6500bb1401e83L, + 0x7bf4163e251c4310L } }, + /* 3 */ + { { 0x1c174f88e3fd589eL,0xdb501790df974a03L,0xd09623e33e70549fL, + 0x8d091eff15924f34L,0xeef79cadf9b65ac5L,0xd2cc42623f69c2cfL, + 0x817d903252cd82bcL,0xacf4f4d9a5f1ddddL,0xd06126355011b6bdL, + 0x9f74490d2ed140c9L,0x64092e8c4db686d2L,0x225eef16776b0fccL, + 0x0e8c01e9df16aeb6L,0x6283674184bbd82aL,0x757574e28956e337L, + 0x9871edc6705a7f07L }, + { 0xbd0b76d5776535f7L,0x5214d6022635b3b8L,0xc0c25ad99d216f64L, + 0xfd4df3a75515bf75L,0x24a625bc5e9f1675L,0x3c35efb7406873e7L, + 0xef5c9a33bb2e5c4aL,0xa971b35e806b198aL,0x9f5c0ca5a3c690edL, + 0xa8d5dd898e1e2341L,0x4cecbcce955ad9e4L,0x2ecf4407248d3416L, + 0x1abb381145c0af6eL,0x3f4bee821c780fffL,0xd14df768c272ed57L, + 0x397ed10a371637adL } }, + /* 4 */ + { { 0xcf3e0bb2755c2a27L,0xd38e42f959585c44L,0x46b13e0f19285e60L, + 0xc3ecd0c076273d0fL,0x7800f085193c569aL,0xf04e74ab4351818aL, + 0x9258aa388496363bL,0x8456617cb8c894feL,0x8bc62aaa2af969a0L, + 0x66c2280b5a4668d9L,0xbc9df58ea992f4faL,0x5db0b7d93f401e99L, + 0xe0614fe1c4c38c0eL,0xd531151c2ccdf6b3L,0x1c7575ece143b618L, + 0x40247985df9398a4L }, + { 0xfba251788f055746L,0xc5ba00400ab1e6e0L,0xe1b194fbac292697L, + 0x771521195b4f4740L,0x250091d09bb7ba54L,0x7a674861b9a139a4L, + 0xba8413b3f353aa7eL,0xafe771922443ceeeL,0x14468d363847bbd0L, + 0x61f79ff63da4942dL,0x1563a1c1d425b456L,0x3c270fcd75ff4630L, + 0x42072090eb2802c9L,0x68f0cdcbc85c7004L,0xca4372fbfa032e74L, + 0x1a6fd1e6c8b79d80L } }, + /* 5 */ + { { 0x967a901a8d5116a3L,0x0b844394b2f5f47fL,0xe39ad45260ebaf3bL, + 0x1e1be61760ccfc0cL,0xac07e3d2cc3f53f2L,0xdd838e0e1ed11bb6L, + 0x454753071c15b0c2L,0x70dd4748920fe5b8L,0x1a20be2de471896dL, + 0x3c3fad8a59276c7cL,0x026a1cc3c886ee07L,0x9fdb6f376e831ac4L, + 0x26a35d1aac501d65L,0x0ae9890540da8574L,0x65dde0a4abd734e5L, + 0x29b7d4dc15614750L }, + { 0x44b3c2cbcbf4e20bL,0x1c3f548f58cc44c5L,0x39809b545b0cac1fL, + 0x0c0f02b500f80621L,0xe612b890066905e0L,0x8f158ed78350188cL, + 0xc01dc4583f5576b2L,0x29803272a45492e0L,0x77a5623a0ff92443L, + 0xd12a2b0029d0dc41L,0xb41254592780e87aL,0x1ebcf9030d53f272L, + 0xbae6ea4024301e8dL,0x1e5f3f2fa37d0798L,0x9342c31022b4126cL, + 0x5d0928025382497eL } }, + /* 6 */ + { { 0x583a2b7eff2f780dL,0x34d26820d7d76b1dL,0xe3c3284786f74aecL, + 0x0fd4221210823febL,0x227e417efb5e7bf4L,0x510d49b6a568f8cdL, + 0x53bce7d61781bbecL,0x9cfe3f222f3718b7L,0x7f44e89fd9de6c1fL, + 0xf1cc553f3fac9b55L,0x9d2d0846e6f300bcL,0x976c82a29f0ae6b1L, + 0xe63dbf5e24b8bbe0L,0x4cac7f45973a5aa7L,0xc6eb623784dd33c7L, + 0x0a26e434142fee5dL }, + { 0x8081339facaa9a08L,0x40f311055246ece1L,0x892c817061393747L, + 0x8d8d4103242f02e1L,0x482bfd203b5de98aL,0x89ef946b5abbe952L, + 0xb8d218b937698249L,0xd5268e8966617c7aL,0x962e75518b7d2b91L, + 0x2c5c7973fe8d67c3L,0x42e3150a2b017c51L,0x6f4e5ebcc1a29469L, + 0xa39910ce531c7083L,0xaf4f6eb4b77b9e50L,0x68cbb175da120ad0L, + 0x19497c61b92636ecL } }, + /* 7 */ + { { 0x6920b0c6417659a8L,0xc77ab9c792cb28ffL,0x55b67180b687797fL, + 0x4caf58c1e7759363L,0x5155bdb65561b186L,0x2e64e355780f4946L, + 0xeb0ac9b7229a8b20L,0x88594d782571bd60L,0x5dcc0939e3fa78f9L, + 0x7b8b48302ac2d379L,0x505fbf60b90f1444L,0xac610e813ce4b3c1L, + 0x39a4f27ad59b5c18L,0x5fa339737cea0222L,0xe578730b8dff1c7bL, + 0x96b91b8b517bf7a6L }, + { 0xc1a991f49aac087cL,0xce62f74e6cfdb28dL,0x08d6ff9a5f7600d6L, + 0xd781cd04f917f9c9L,0x7796f5f63de52dbfL,0xe7db64e02ed72180L, + 0x0f0876f66fa4137dL,0x3271ee643ca1f716L,0xcb9b20587c4ab8a3L, + 0xcba1710739481047L,0xdf9a190d598c5c37L,0x0cb6e72a6f20e125L, + 0xa3142204f4f2902dL,0x42d28cb97ce2dcfbL,0xdf261b8aa3d3c351L, + 0x73f3d315cffc249dL } }, + /* 8 */ + { { 0x5d86855be6fd3673L,0x309b70af9d214b7bL,0x8d332f90dcc46cd3L, + 0xe553c015595510deL,0x5746a09638c1251cL,0xcd7cea5b85cc1bc9L, + 0x4ffa1468002eba8fL,0x10a3cb7022fcd77cL,0xb6999dfbc4ea05e3L, + 0x3375a0d04efa756eL,0x4d90279edced5fd8L,0x48192403251fd56eL, + 0xe87633a482a4c5f1L,0x3170d1301b34105bL,0x93998b0f7247e578L, + 0x88934f64436ba1faL }, + { 0xf09f43b04713eabcL,0x4ca7dd91accdc517L,0x27daa63bef13ca7cL, + 0x8b2e5a7a2588184bL,0x0a8cb612d95dc269L,0x346975a2e1f2f14cL, + 0x1f29b8ede172935cL,0xc3cbfd6ed40bc1e3L,0xd3f46b3f132623daL, + 0xc115be6dfb0b7681L,0x5e31c34556da4344L,0xa7c63f18a8e43d98L, + 0x55cb20834bddb4eaL,0xb16a0c384a54f58cL,0x74eacca246fd69d9L, + 0x0d1898bb153548e1L } }, + /* 9 */ + { { 0x4ea73461e35ef043L,0x107b67d93496b564L,0xd62c173bd0f83a3cL, + 0xfad4b03851d29c35L,0x3f42882a71b1c1a4L,0x5d2bcf6654b43b9eL, + 0xc77b15aa2abdf543L,0x5cb38a80dabe3dc1L,0x15fda0aea481673bL, + 0x86996b4de7b90ebeL,0x84f87e252bc8f3d8L,0xaded03d637c4e424L, + 0xe5ede666d7a7afd8L,0x80dd95a2a1ccb93aL,0xa55cfd2546fba391L, + 0x2bdab1dc46f82e60L }, + { 0x7a4de22bfa6fed61L,0xca458aa5cc8dd94eL,0x3e372df1071222f5L, + 0x06a4b44fe5aff377L,0xbc2d0ba74a738e6dL,0x1a470e1d5f31f136L, + 0x77ff933ae102a911L,0x8b380a50310c7885L,0x9f3c0228783fc5acL, + 0xec66892544725d06L,0x878f0e165ac84221L,0x9a3af1afcfda6e8aL, + 0x0183ed3778cd2abaL,0x32cdbd60826d0eaeL,0xb3234661cbee6415L, + 0x353eb892b9c10120L } }, + /* 10 */ + { { 0xc8fdcad610b5521eL,0x1a11b44052e702f0L,0x6302680d8ffda49cL, + 0xcdb9654acbf36badL,0x7b58ce114c10a2d7L,0x1e5d1f7de630e7e0L, + 0x8cbe3d7d6760a813L,0xeb35866b6480d77fL,0x58728cf37f036219L, + 0xdd5865ed42a8a757L,0x283f1f1d906a2870L,0x79e23fa4a51f906bL, + 0xf2ac6e83543b20a8L,0x4f0b6379b81e7754L,0x57fbc0d4840016eeL, + 0x8da20771e621b67dL }, + { 0x3c855004ecce65ecL,0x76d10d1fb748185eL,0x64be7bca78797ad2L, + 0x43444db077e54aadL,0x17b6b0c9be0df0ffL,0x8fc4256c055086a4L, + 0xf952c43bfd74d5a3L,0x501e005a01c4edb8L,0xd5172dfc4a57e328L, + 0xdb40ce4e535d6ee3L,0xbaef1e5c0c650918L,0xe85145e7857561fcL, + 0xe468536a34a224c6L,0x69a8e2270ec0e0a2L,0xb3f52247242b03fcL, + 0x862f55e2c3bebd5fL } }, + /* 11 */ + { { 0x2d6a390f226049feL,0xcc92a578dcbbc9fbL,0xa52feca497634fb7L, + 0x2b340cb63dea5893L,0xa39f338a2a49e916L,0x26b2df3d949e41f3L, + 0xc71c7cdb065a7e40L,0x4a9b84a0468281a2L,0x63eeb503731eeecaL, + 0xe6d0913476cbb725L,0x0cf979a9b94a678cL,0xb44d8c3b808fd9f1L, + 0xe60da613e0afc5b9L,0x52dce7de3ea5be69L,0x3a5d6864dc1ee74fL, + 0x71ab28913bc80790L }, + { 0xcf618fc43b5b60adL,0x0afb5e304a0c3184L,0xd22381ccbc403302L, + 0x33cf8953db1c0c66L,0x9c994e4da6112a8dL,0xd7aae2c3d1967a86L, + 0xc28d54935b7acd29L,0x8075bd136c9a57fbL,0xc9c0373e9c8427f9L, + 0x2cbca18d193225f5L,0x73777d13442c018cL,0xebe5ed47fbb3a727L, + 0x70437d491962dc18L,0xf39c1e092dc08806L,0x03e9c6f715fff35cL, + 0x8d087bb65e360a65L } }, + /* 12 */ + { { 0xbe2123023fdc1844L,0x6eca27ef105eac56L,0x2183a606f168a348L, + 0x295f807de1d7a4cbL,0x7246a6327ef5d43eL,0xae143205c77025c7L, + 0x4bdfc7caf3484e3eL,0xec939895df52c075L,0x82e655f6d7a9cac0L, + 0x985dfe208baeddb0L,0x79c817e4527de731L,0x30ce0fbc313de1eaL, + 0x9df95b89cc4f6cbbL,0xf2aedf1ef5bb20cdL,0xfc1e0a891a8cfb01L, + 0x225ed34a63edb7ecL }, + { 0x3e13154dbabb1a85L,0xd3d8dae71e6a565aL,0xd3217d56ab4b100fL, + 0xd44d934eebc78e1aL,0x0215321b48e73d37L,0xbbc90bfa201e43cbL, + 0x3c23f1d027500905L,0x2a2e5000c86691a1L,0x08b2bad26065841cL, + 0x15d41caf30026b60L,0x1712c2f45276ce61L,0x01c4c3e715932ffbL, + 0x7894e13d6a74caf2L,0x02d6f5df0c0537a4L,0xa8fb7602c2b1c97eL, + 0x612b60e5d0887c7bL } }, + /* 13 */ + { { 0xefd495cfba245d6bL,0x5cf0cbb7a2ce3ff6L,0x24da2ac0dff5feeeL, + 0x90c914f8cf28c6a3L,0x72fdb50d4308a56bL,0x03dbf77913d72034L, + 0xcfa5ec91822ac9e9L,0x0dde73c83aea3e81L,0x545ba96266289139L, + 0xa52f648bca6acbd3L,0xff6f276e98a0683aL,0x2536d3aca378ed52L, + 0x353c2c54885ac1d9L,0xcaff52da00bc84a7L,0x3971f81c37684167L, + 0x0f7334e1d2d7986eL }, + { 0xafbb5c836596067eL,0x33e54e1938c19806L,0x8285d96739cb0dccL, + 0x2b53f43d424035f9L,0x38c531f8dfef9095L,0x90fbe8e4db0f571aL, + 0x9a0c1ed2a39ca787L,0x2fecc1d6606f2620L,0x9dc890b172b7cb4aL, + 0xc33ca6fbccbb7868L,0xd1b11082fe73ee49L,0x590b7d17fcb66c48L, + 0x9356b0a686e14573L,0x75d682c4053ead85L,0xb2ae55fac54d30fbL, + 0x67636a72f8aee949L } }, + /* 14 */ + { { 0x638063bcb91d6beaL,0xae263a2e923ecb96L,0x9d7b0992c627aca6L, + 0xc6ed001a77af9e7eL,0x9214accf24aafebbL,0xa3564b9678055a90L, + 0x00999b1ce027499dL,0xe413a4e1e46a06a5L,0xa05d13f62e51efe7L, + 0x35e87d349ba843beL,0x0a6338253183159eL,0x6023e8ba54601923L, + 0x9b107721b7fd1cf2L,0x46b5542bfdf2fd53L,0xb314f4f81c18af38L, + 0x086f987660ac8965L }, + { 0x767019548cbb9850L,0x6210b730a20d2c8cL,0x4084d0575335670cL, + 0x3ecdc5950324baeaL,0x607fc5f2c76ee9b4L,0xf393d00f440ffa64L, + 0xe01117962dc1463cL,0xf00b82519c7725e7L,0x35e607365bd1d186L, + 0xf3d8554c2cf72aacL,0xb4dd0fdeefa3497dL,0xd712268cf646ad11L, + 0x07c20afb9f7b8eadL,0x630969d4fc06dfe5L,0x76b7df1c7245549aL, + 0x681f9403e61ae810L } }, + /* 15 */ + { { 0x7cad5163c9a0623bL,0xdbf8295767fab8d4L,0x2ccab0ec81af7c7cL, + 0x469e38c8e966d5c2L,0x34430d52f0d4e41cL,0x426075a2a52b359cL, + 0x242dd3e333bd0127L,0xcda3f6359fed2341L,0x4df33730d7d52ffaL, + 0x5fff56f07640c3efL,0x4783c21c1bbde57cL,0xd8784a2aeb8bb336L, + 0x1ec7c533ead08405L,0x4b7f1423f9b62bd4L,0x5543145c7075d4afL, + 0x0c9de94aba60590aL }, + { 0x8ed7273595d5682bL,0x711c42832ec276edL,0xd1f4aed58b36a0d2L, + 0x62ab40c48498a88fL,0x58c8fc624480f451L,0x8bc8ca4bb79cffe2L, + 0x90ab583c701a359dL,0xaee31a733fd5d15dL,0x02a5597bc912333cL, + 0x1019cae4b6c3e3c2L,0xe513042c29938088L,0x0e00283df47c8199L, + 0x90d68e58f2a00e92L,0x69e2df41a775ae3bL,0xb8d2eca5871c30b2L, + 0x733dca0ebb1de396L } }, + /* 16 */ + { { 0xf5b495d04b59213aL,0xca6720398d70200eL,0x4bcb09a62b6771c1L, + 0x26adeed42b9eb0cbL,0xeb5447548cdba212L,0x0e1abfcdf08890d1L, + 0x52509963698e46b4L,0xe1bff0b082e9c138L,0xa189e4cd51099a71L, + 0x2360c9bcc9b91cc7L,0x9bd4d7dc137ec4beL,0xd0356521d1519f6eL, + 0xbf5f6d78cf832503L,0xe43010318deea2b4L,0xc3132494ef4c319cL, + 0x2ab3bd470f1fa7d7L }, + { 0x5753b680922c9fbbL,0x869e7dc80f16c6d1L,0x83445135bac16efcL, + 0x4326a3b4846d1d9bL,0xb517fee3b2d62c21L,0x6905afa20b292ad5L, + 0x2a57131a2cadac13L,0xcd904d8febdbca8dL,0xdfeda86f3f365fb2L, + 0x7097b208dc7eaa1cL,0x89a35a84a45e77c0L,0x417a062ccf5d118eL, + 0x3c0c04a81f6e99e8L,0xc44704b0ba7a087dL,0x6f8a27d13ea22ad2L, + 0x93a4b4164c27d229L } }, + /* 17 */ + { { 0xd4271bc11f1efb7aL,0xae4e68e633fccc0dL,0x9d9bc8f1b11f50a8L, + 0x5430398faf076089L,0x45e242fb443d0e03L,0x73ec2519f6e3d4c1L, + 0xab70f790ba9bad09L,0xde612ad5f9add10fL,0xb837e54e14e942b4L, + 0x175a56d3ddb8b68aL,0xe85b233c1ac2a408L,0xf8ff6c30f0c80f94L, + 0x4b7f3fb7898db4f9L,0xa2c6044f45a7dcddL,0xf3abb2f6fe3d3895L, + 0x342ce0d732ee7763L }, + { 0xeb261394cf491b1fL,0xdcaaeed71909e395L,0xdcc4055a9fe4dbeaL, + 0x17a6611d493d604dL,0xba445a3a1ce5ebefL,0xe82e2858e3989cb5L, + 0xb96f428283f58406L,0x99877b99a156cf55L,0xaf906a664e166a0eL, + 0xcea1d353b2976d13L,0xefc16f2736c61a01L,0xdb04c433b0f55d86L, + 0x3cb4b2698eb34c01L,0x38d07f782ae60280L,0x43ac3bcb43be3ec5L, + 0x455f4af3e156fd20L } }, + /* 18 */ + { { 0xc057f262754ec21cL,0x3eacd4c9e3a1ba38L,0x3a0210d1116c1fe9L, + 0xe4ea4e94eacc8ab6L,0x31c00c9aea6f32caL,0x5cb6239d86b975ceL, + 0x654d5d8ca14ea1e9L,0x230d31f45067fc8bL,0x48bb90cb6355fecbL, + 0x78f81ecedc172e8eL,0x288380a8cb006737L,0x19b02e01e162d012L, + 0x0e087a06c5af145cL,0xf04dc8b7b72dc354L,0xf70ef2148de3c066L, + 0x4f14824313009fb7L }, + { 0x5e004fce6e2055e2L,0x89e247ea86c32067L,0x4ebcbd955f9daaa2L, + 0xd15f212fceb7f63bL,0x5ecc5c1f863784a0L,0x53b3800b75760251L, + 0xeb9301c38a6a2954L,0x0f16ba18a13cdd19L,0x8313d251887c2d24L, + 0xf99235859a9413f6L,0x423405e6fe3fd7c5L,0x678aeb3416e0ee05L, + 0x1f3be7bb3fadaab0L,0x7901fa2c82884471L,0xc950db304d662ff6L, + 0x74d5d2d43c01170bL } }, + /* 19 */ + { { 0xa3002dc02b5bfe11L,0x0733410d52d321e7L,0x15920f659679ba89L, + 0x0e248c14685b236eL,0x8cfab594346f6040L,0x9f57afb740c717f0L, + 0x0dbab28c66044576L,0x0fa099689cdc3247L,0x41e02ae2c230ed05L, + 0x0d961554e45bef74L,0x9688a982ce4d7b6fL,0xfadefac75e62d22eL, + 0xaf1512a6bd2cba28L,0x78868e62be7c749fL,0x88048d81ae9f5a6bL, + 0x6b1a5442c5857a29L }, + { 0x9f5ab9ad43242066L,0x0afef1b52ccca2aeL,0xb1b43ec7988edc4eL, + 0x0d0c00f10341b0d5L,0x4d68b8f7b50aab37L,0x9a8e4e6ff3a64a99L, + 0x198338fb7f1a684eL,0x8bc0e748351a0f5cL,0x2cacf2cddac44515L, + 0xc14d39995e9ff76bL,0x54a01b3f16393055L,0x6ac3eea5888d8376L, + 0xb84d9a9a723277b1L,0x99132691e11dbbbfL,0x597717aeabb67178L, + 0x4c2135268bb14ac8L } }, + /* 20 */ + { { 0x2e6fe0a695532833L,0xabca228ed626d067L,0x22aef3d9649e73bdL, + 0x2083a87af03c4c0cL,0xe954e75d35169b45L,0x577509ee74506a89L, + 0x49cb276e2aeacf90L,0x08275d77fa409f91L,0x61eb6f3df0bbd6b9L, + 0x948202cbe4132704L,0x35f3fc21b1c498b1L,0x76c68ba8361fee59L, + 0xa18cbbd950e051f3L,0x2384a879318e7042L,0x292abead80dd1e8bL, + 0x65713c295c37c334L }, + { 0xdccca8e9ceb77b9aL,0x2f97e72723b69469L,0xc76abee6a01d6b28L, + 0x3925203d5abecdfeL,0x8944808229290d70L,0xf9931424b0314438L, + 0x04209df17cd447c3L,0x7c6f2059c855c827L,0xd97d786256c0e069L, + 0x5a9db6fe412d94c4L,0x19a64591994c41ddL,0x12348aa1c89e21a3L, + 0xd6904b50c6a03f0eL,0x55c15156a616feacL,0x4e36d1b57cc7693bL, + 0x6b0e996c3bae3c38L } }, + /* 21 */ + { { 0x32789fabcceced00L,0x3237e71ae5b7aa66L,0x87b2e2692ddebcdfL, + 0xb7245120b61dad8fL,0xe11e5e48d35f803cL,0xfb4df5d798e50f0dL, + 0x60ee68b4bcd2ab92L,0x98ab2f5c1ce3363dL,0x15ba39da7cd42647L, + 0x1a6572eb83f4fb3fL,0x0f77de88e56f08dbL,0x1743761e172562c2L, + 0xbe349ff88a58f0f4L,0xe04da71b84d1d6e2L,0x368f03429e9ff3b4L, + 0x4022a205678223f8L }, + { 0x527bbd0583847375L,0x3ae56b623f451af0L,0x6198f24d4b2c7f18L, + 0xee323f5b4525b98dL,0xa9d8d39a0e0884b5L,0xd005d7f6fb12c776L, + 0xd71c483e708bc154L,0x8ca6fd28742541bcL,0x0af3dccdf8397ddbL, + 0xb80d31253eccf243L,0xc743a10858d81b8dL,0x3f48eb2171391f68L, + 0x493aff8833bb657fL,0x1d15ed6607e47e31L,0x10159b11e08279f6L, + 0x312179cb24a6a956L } }, + /* 22 */ + { { 0xa94cc3ca07615ac2L,0x85865e64121ad581L,0xae47616fa7986b79L, + 0x395a40eb9d5e0f1dL,0xa91432643d9457eaL,0x8de6d6a3fa2865d9L, + 0x0771db961014ae8cL,0x77a7cce6976a87cbL,0xa7de42e1143a0f60L, + 0xe203cc09d993d934L,0x9201869398ec4c3dL,0xd77546d83a25df4bL, + 0x0ad9eb4762b02d6bL,0xfaaaf208d05a7189L,0x5238181f431221bbL, + 0x417d6c78733511eaL }, + { 0x3cbd81b70e91e9a8L,0x73340418c370d6b3L,0x825db10a8eaa2373L, + 0x8f2b09e46c7d6756L,0xe288ee9b94c33dedL,0xcd8426bb1695e3fbL, + 0xa6176c86dce9e888L,0x3f4c89226165e362L,0x514e411f6063fb09L, + 0x6907ac20c8f9e04cL,0xcef7469cdfd2ad61L,0xba30bae48452199aL, + 0x3068129312ac3462L,0x011be873c92d482dL,0xff4cbf89e8330995L, + 0x02189d52d1470a0aL } }, + /* 23 */ + { { 0x73e419dd92599c69L,0x5b94221b7fec32caL,0xb2bf9bd209bbfbfdL, + 0x61ea97a463ed895bL,0x6609146b3f486f79L,0xbd1c7a05fd141a39L, + 0xc79ec8cf83d64135L,0x7f8fd42f9883507bL,0xafcb53b717b3d027L, + 0x86658dcd67ca5a21L,0xa6a6c0accd149786L,0x16f3d70e34b95067L, + 0x371208e3df44958cL,0xd2dd64e6ec280212L,0x33b2c4ab30782c71L, + 0x7bbf8abd521176faL }, + { 0xbe9e4aafa78b981aL,0x788b4e36304ec828L,0x0c45cf393959dea3L, + 0x70a9bdd3240b39c7L,0x499cd7dd28383b7dL,0x30690b2e307a1026L, + 0x2262d598ee92f1b3L,0xc62d77deb4725a48L,0xa16f25bc7bc3aa0eL, + 0x62dd8b65d15ef7faL,0xd979221d0b96d68fL,0xb92885c3a00f1906L, + 0xfa476b9beb74c740L,0x217ddbb5c7576222L,0xc2782c305788504fL, + 0x860d096cf812716bL } }, + /* 24 */ + { { 0xfebc337d4d79bbf9L,0x5d53eab869f74f80L,0xff36a09533104d53L, + 0x2ab820da196f8b97L,0x961d3d1f75ce6909L,0xb197ec0404683754L, + 0xa68ce1bf93a6cb9bL,0x503456ffc5f021a3L,0xb50a2db18940ffdbL, + 0x77c50f8fef004209L,0xd635d17704965875L,0x725766d98bb8770aL, + 0x8e19b028a078e53eL,0x364d4ccaf9fc8378L,0x1a3df411f0dd39a0L, + 0x7e80e44203adf920L }, + { 0x4b5f8a57539a1ddfL,0xd248e7aeee486562L,0x1c7b491d816021e1L, + 0x2e7b871bfd36d2c4L,0xda38b5040aec00d9L,0xf28276126193f1b3L, + 0x69c3fe86fb1f78d6L,0x56c8b786e827ac33L,0x1687f6c73487c8f7L, + 0xab8f221719dee5bcL,0x04e8473fff399418L,0xf384c014a9027c80L, + 0x9967be9aaa1d2e28L,0x869686d3e065eef1L,0x737c6b08c7bd837cL, + 0x5dcab5d19e8bd863L } }, + /* 25 */ + { { 0x0784283a9a7d772bL,0x6b49e525e540959bL,0x546bb00886414ab5L, + 0xd44481629d74b2a9L,0x267890ad203b0b1bL,0x1e7a82bcc8d3f86bL, + 0x1352bfb5d85a83c7L,0xf29f16e3fad07ccfL,0xc02a63b841e0c43fL, + 0x904f22c56b379fefL,0x19d8a653b1244f26L,0x6635b6df3a28bdeaL, + 0x18b68851f6d455ceL,0x74ac28189cff3735L,0xad40f9df8b2cbdabL, + 0x08cc2d9eadc9d498L }, + { 0x2e6a6866c170c84bL,0xbb989e8b5a49a484L,0x7b0e00e0d04c8992L, + 0x55ad347861b3a423L,0x3c952450b0d01899L,0xe3922155e3100cb3L, + 0x19265b6ef03276d0L,0x0fe8595a76d42b53L,0x0a96dee0fc6353b6L, + 0x761e0dc8246f893eL,0x4ec902bef0a74cbaL,0x610086843fdfad9bL, + 0x5d6a60e44fdb6975L,0x3f53aac87ef7590aL,0xd29e6be012870a37L, + 0x991fadc155aa55b0L } }, + /* 26 */ + { { 0x82bc4b0fb4844ffeL,0x7392271460f8b871L,0x8ac000e24ce3f1f3L, + 0xf0d548b4163519ecL,0x7aaf842b88288b5fL,0x9e8b0c4c2bdc9a70L, + 0xa06d51524ba5fd67L,0xd0b1afa0f93cdec3L,0x280955badf89f8f0L, + 0x86cbe92deea32c92L,0x0cae3f993fe05be4L,0xf2607095fa6919aaL, + 0x0f54741e6e0f1b8bL,0x2aed1f7430ecf988L,0x9296f76b734991d7L, + 0x66cf8d28259f0fe9L }, + { 0x9b01905b226f5868L,0xc102e88c16909e9eL,0x2bd089164a37eb54L, + 0xf72253e8c9816323L,0x37f84e9d86bac53cL,0x2e352454afeaaaf7L, + 0x67c86f772ca0046eL,0x86bce50e6663372eL,0xf6a3a960b6950a04L, + 0x61f994d7fc1aba93L,0x1957c12bc1326e6eL,0x9b658fe42e56b005L, + 0x9cd297fc8592740cL,0x7654ce9b177f26a5L,0xaaa699dba79d2ebbL, + 0x5fca0c5a0ecb6448L } }, + /* 27 */ + { { 0xe26e25f3569a6663L,0x09597ee7e6aa4ca7L,0x25a4cda68d18b80cL, + 0x450602b522926730L,0x9af5f65007387209L,0xfeeedb3426733a53L, + 0x0f5ce76886572951L,0x872a360b8398ae9aL,0x60347a802b30f6c3L, + 0xd2113b231a162158L,0x6fd9cf92ee6c6decL,0x85f0a5a85cbcf9e6L, + 0xd7a5a6e42ba3fe84L,0xaafe672051ecd727L,0xe09c6bb2a2081a10L, + 0x657acbf0b973b0b4L }, + { 0x3130466fc274c8d4L,0x4276517630a994d1L,0x217258ca7079435fL, + 0x44850406eb897a06L,0xf38dfeee561ee130L,0x11f4facfaa1778bbL, + 0x765c6617b9abb9e9L,0xb135499bd8f10932L,0xc0eb6337a73b9159L, + 0xf2c1ccf16f7e8b6aL,0x5b32c03a187def53L,0x89ad1d49830b9c62L, + 0x1735eae32f10e538L,0xb1cbd9c29d5f55bcL,0x42428c47e539db0dL, + 0x3d2da412c852b3bbL } }, + /* 28 */ + { { 0x97702b6e871f2865L,0x56cb639f142920d6L,0x328522a045b58611L, + 0xf3943ad1f3b13812L,0xe6c2200a712206e8L,0xc2890e5aa34d59eaL, + 0xab52fd40f6b7f759L,0xf522c8de180bf567L,0x181e97b2accee396L, + 0xe0375819c4ea5cbbL,0x0d9985e8ab51d3efL,0xe26c96cabcb50fd8L, + 0xfb9d6b1397e1c80dL,0x582b1814f796357dL,0x89a7822107f4c7fbL, + 0x02aeef2dc0357e61L }, + { 0x2ba7926f2c7ec9beL,0x292f307e7258b201L,0x74e62a10c6fa6b4aL, + 0x80c08549e2bcc5abL,0xb4160db87bb8c073L,0xd5ef0529329f194dL, + 0x0eb8da146dda4a9cL,0x0b5d43d215ea23d1L,0x6cebef02fc34bfaeL, + 0xacd364d0848757a7L,0xc14013682d34cca3L,0x09ca67421d2d95e2L, + 0xc3fd1d6e786eaa28L,0x9eb1136da2965fecL,0x48871baac0779203L, + 0x6b446c014b15aeb0L } }, + /* 29 */ + { { 0xc819eb2e25e8fe80L,0x2b5f790698238a17L,0xd6f1e99681e41849L, + 0x58ad8ad698ea6d45L,0x5bae5ad4bfd02e40L,0x016dc327a812416dL, + 0x8b31a985a3347ca1L,0x0b4da61082a65391L,0x1cb91b2db48c35fbL, + 0x9e96817cd2aaf8c4L,0x1a630483cdfdcdc0L,0x7055936112b69254L, + 0x5fdcd712f8a2a097L,0x59ab623a35cc5281L,0x30c8ebe0932b6095L, + 0x8613424bb08e052fL }, + { 0x28902063b2231d8aL,0xb0f62329d9a61667L,0xaafa0fe7071a9f27L, + 0x6bcd8960603f047eL,0x118cca76fd92a1c3L,0x3414e62b71d483b6L, + 0xa123ccddba705262L,0x1a576437fd9b5c5aL,0xa5301bc24c8d0fa3L, + 0x96f0ad44102427cdL,0x0e6fb5e0d3aa6c02L,0xcd8c4880072a3996L, + 0x4dafca12840d3fadL,0x29f4ca3dde91d541L,0x0037c5988441734dL, + 0x86333a999ccfe57cL } }, + /* 30 */ + { { 0xd213a751ecf53b40L,0xcff2c6f22f78a542L,0x0f59f0e2f13ae56dL, + 0x91f8ccbf0e61748eL,0x0aadecb9d72c4145L,0x6b2ed8524c9cdcb7L, + 0x8e00b72c1eaffc70L,0x89b24285aa728102L,0xaa7ea7e0b679cafaL, + 0x5d2b8c264f0a6f6fL,0x7ed7b1730e804397L,0x5a93eb45c8573049L, + 0xc92bf5d40986e93eL,0x526b5a9c6a20c0afL,0x0adf47c9b99dc3afL, + 0x12b25fe2ba202cc9L }, + { 0x09b8d78a33eea395L,0xc7a93618f633fc5cL,0x7e821629270eceefL, + 0x524779b8c628ed0cL,0x91db5ca1a1d68939L,0x8626e18e586edc90L, + 0xfe023e8bfeb3f3bfL,0x6279fde10250171cL,0xe52ec7dc55e172deL, + 0x445e8695c6d4ca45L,0x42de3878bdbc10f1L,0x2b114de86fc3835eL, + 0x9faba4567e10b652L,0x4111d82a390e78feL,0x576b61c2aedf0acaL, + 0x216279a974accb74L } }, + /* 31 */ + { { 0xc14cdabf4047f747L,0x03ca233dc1315a1eL,0x59e7cbd340e5d0a7L, + 0x1fd0c4e9bb413869L,0x189d08b10f01fbd8L,0x50449c42a76b823dL, + 0x81c224a1398b00a1L,0x08084e4f8e8179e4L,0xfd8af994698e41e9L, + 0x1e30e37c5610bf2eL,0x4e6a043fa7d2790fL,0x9d96e60cb3195388L, + 0xe75f986d03799dfdL,0x3b4a8f11f8ff902fL,0xfa9453787588416eL, + 0x20683e3f9827535eL }, + { 0xcb582e26d0378878L,0x9e214c23a7945787L,0x13d000bf8f6688b3L, + 0x7548d4f540515270L,0x7113c15d40111f5dL,0x3bf5a526a8bff902L, + 0xbda6b0109b4945ccL,0x83dcc74ebc2f3a05L,0x2aef628443efdfa1L, + 0xd2e60ee9565c5bf4L,0x4f0fa10d592f243aL,0x6ae58b321bc3bf51L, + 0x813b086860576a74L,0x0bc023f84d73081aL,0x9fd03aa032dcee59L, + 0x5e416bf527d6c795L } }, + /* 32 */ + { { 0x24313760026cc23cL,0xf819aaeeb5b29058L,0xa92272f8c5d2ee17L, + 0x8048e7cbee5cc402L,0xdbc7d6ee77def07dL,0x61d69244f6af821eL, + 0x5f7966ed996cbb89L,0xf81b17ea96a155a4L,0xb2d9ef7003f3ed56L, + 0x5e6e5906e882a5b2L,0x86fa1072ae947180L,0x34d9fc51658c76f4L, + 0x9f603dc0cb035aa0L,0xb7b39feb75be6481L,0xca87554acf04a9efL, + 0x4ff682ec87b4fde3L }, + { 0x3125627fd0a10ad5L,0x7fd45c72968e6f45L,0x2981bd6b806a1163L, + 0xb92de1cdde5033e3L,0x3b44b45ebf4f8988L,0xca1b9896dae7e1dcL, + 0x52166e5a0778d878L,0x82d472bea5116847L,0xfbdd382af2895445L, + 0x22ed16025d6ec4c9L,0x3614eb1cb6552b02L,0x63c5df73a1e6210fL, + 0xe9160285021a74a7L,0xa44ca400c65cbd4dL,0x48cb187e0f15e299L, + 0x51eb818e3402507cL } }, + /* 33 */ + { { 0x1fc1d178b92100abL,0xdf2e3d609605b839L,0x12a7c255b71e59d0L, + 0x3f8b667514fcbe04L,0x0e8a393559fd06afL,0x5632650212020d07L, + 0x6696fcd1528e7be5L,0x6588514b0c7b7654L,0x0cd80f8c5912a5b5L, + 0x8bafef04f324cb7fL,0x6b53eecfc6da3d75L,0xedef48d831d1df2fL, + 0xf336b96573812b6dL,0xc82eae4aee626031L,0x300abd32d244f09bL, + 0x8b0af95531d9647fL }, + { 0xb770180a2e603544L,0x2b573ac3221acd9eL,0x3a17f66562407032L, + 0xad3e74adb89abc3dL,0x8a3d2e3ad793225aL,0x457bba04ef02564bL, + 0x8875652ffc2dd2b5L,0xd2905d15e67143e8L,0x6d884b4202e48d70L, + 0x06f99219c7636a57L,0xa8dc342135e378dfL,0x95c1d73d10c64a02L, + 0xcd6a4ececc157a66L,0xbadcc1c88e24a354L,0x8024f1b29839329dL, + 0x5363e5494da48ad0L } }, + /* 34 */ + { { 0x1f5523b7e23fc641L,0xfe54e72f86667063L,0x294a15f58e009d2fL, + 0xf203997f8c57f5e1L,0xa229724cb16d64dcL,0x697be4fd4baa2ffbL, + 0x3f507e460a6e8ed6L,0x0afe3a5d78508536L,0xeeef6cdd95408208L, + 0x701fd889f2c4237cL,0x496d883a5c385253L,0xe25c67ed72a212f1L, + 0x4b4167831ff78fcdL,0xe9967004c16f4146L,0xfa45c3a1c45b0697L, + 0x633340183fbd30c3L }, + { 0x39c9a0cca2fbbbceL,0x876f6e5caa0cb744L,0x9ce6010e3438ece3L, + 0x0aad148e13802d82L,0x9c3e5c609cd45a1bL,0x875cb8597bcfc1e0L, + 0xb19ff790d8584dd0L,0x2598b81ed81c2a2bL,0x118bdf2f02be07e3L, + 0x074fc8eeb9765ce9L,0x125e9d88b24f95aeL,0x3bb12cdc0c98f09dL, + 0x4a6aee07a0b74b27L,0x4723d2f9c08077ceL,0x959447d6bea8026fL, + 0x93a7075c16280b73L } }, + /* 35 */ + { { 0x26bbefe2715b27f9L,0xa935a5e22a280923L,0x5ddf23affd58a26aL, + 0x54c83e167c138694L,0x44799bc9892a2153L,0x4e6e47109b8d09f5L, + 0xc63af616d588ea68L,0x5e896706883ab1b6L,0x3c1393a03d209336L, + 0xd02f292192c23ddaL,0xab70cb7adcf6ea43L,0x12434ea8791559e1L, + 0x040680db6d70ff0bL,0x1a10fe522832ba45L,0xd69f9c08e5f0cb8fL, + 0x1a7422ac44b141fdL }, + { 0xc3a9dd2e9f40b675L,0x2a7c6603fcc71f39L,0x18939a611948e342L, + 0x8f3b6158ed0ab484L,0xa3aa7d97ee31ca6bL,0xbc1e865ef7a8db63L, + 0x315f8c092c7c62e4L,0xa260788f9f5c6d0fL,0xb18331294b6f3ec5L, + 0x73adbcd636b4d849L,0x66e14890bc699a9bL,0xbf3790d82a1175e7L, + 0x7f43605afc53ca4fL,0x577f6c4787ff6091L,0x827c7552600c82b6L, + 0x0944d6309d25599cL } }, + /* 36 */ + { { 0xcfdeb63ee6ab9620L,0xdff4fa6d786cd808L,0x145edd82456320b3L, + 0x2ae5f862c4943915L,0x9508e813b73b3f87L,0x3bd805f3e52f97a9L, + 0xf71b5c28c9829b62L,0xb394c70e86e0cefcL,0x534fb1a923bdb36eL, + 0xd64f5862dbe27e5aL,0xbae23df383ab6169L,0xdd6df1b127c828cbL, + 0x1901899f3a307a8aL,0x36cc8659811ddf66L,0xa3cb777479943b77L, + 0x7d89f3836fd86576L }, + { 0xf8564242c9f92b2bL,0x700c6a75c46e32bdL,0x93e768b77f99a5c5L, + 0xb6efe85803149568L,0xbbfe8a19c2ce6709L,0x721a3b1bee6ec493L, + 0x26eeeea9c371c28dL,0xd798115e15177e1dL,0xd7bf3bceb068a5a5L, + 0xdf8da22046d2b4b2L,0x3df0995b59be9dfcL,0xc96897bc77640b79L, + 0xce0cf4c25a2bd3c5L,0x16f45d6e89afe744L,0xb53f3acb3a8509bbL, + 0x449af81f63f2a6e6L } }, + /* 37 */ + { { 0xc2fcf132a16d9377L,0x9ab377b37e1a2f9eL,0x72e1a12e86d19ae5L, + 0xd2b12e66d013bbb1L,0x0972e055cb5f66baL,0xd11de1c0399eab50L, + 0xc1f314fdc65f5ec2L,0xfc3118418a9ff593L,0xdf73c1ece05246e6L, + 0xc28d13631625056dL,0x30a9dbd76fb25e19L,0x049ed244845cd2d7L, + 0xc779b83fd36e852dL,0x85a35fc7f68c8a83L,0x299bf1e1c95e8033L, + 0x0e8617c320891af5L }, + { 0x5372060267c81b5cL,0x2fa89dcde737873cL,0x2a7430b0a8144fd0L, + 0x3006c5a726208c83L,0x4e066660d8ea40f5L,0x9dd025f9896413a4L, + 0xbdf380cc46b9149fL,0x801566190a125cc2L,0x04d6a3b752793c37L, + 0xb60013746b7a62f2L,0xa9cfe268585d5978L,0xdcad0cb88395fe66L, + 0xbab468fc46b261f6L,0xca0ef5ef9d9d9218L,0xc507d4a85e452402L, + 0x6f4404f1326cf687L } }, + /* 38 */ + { { 0xa3e1920b4febd3ffL,0xca6234d8fdfd2bbaL,0xb7d1af2ae19a9829L, + 0x23de1610c6f5bc20L,0xe204dbf3daa39ca9L,0x2a2de9b86d8c70abL, + 0x272e0c377c9d370bL,0x80914c06e565510eL,0xb611e7a857cbb6b0L, + 0x076fc6efd8266a6eL,0xdfac34ee3095801cL,0x69ff40a2b9e24063L, + 0xa7ba31a9787aa5c5L,0x0e4d1fdf33c70cd2L,0x903e31326895f074L, + 0x905771f87fb671e2L }, + { 0x5199ba0da4062beeL,0x18e7238c94d7d9f9L,0xf53f29bc1e0922c0L, + 0xde9b2a81b12d855fL,0x649f3eed6d68ca29L,0x64adfc34c50c097fL, + 0x81964ab99db398a0L,0x00d59c477a587224L,0x09fea39674c5903aL, + 0x6aafd8ee15043dd0L,0xc5721a6e5f1ecc20L,0xb6d6a4830db9b7b4L, + 0x06ffc61766c8d52aL,0x3de241d6acc82a27L,0x0605f05227f2f7a8L, + 0x6a22953b6404deccL } }, + /* 39 */ + { { 0x92452d8f74fce389L,0x059634c02afa5564L,0x9377ccbbf0ed7825L, + 0x89f4045b37718e0dL,0x11074e7d9fa69a4dL,0x5d70bb077295b0baL, + 0xb22d54adf107ede6L,0x5c39a3d8a1a29c7bL,0x37236c02d795e3abL, + 0xf7282d002b589951L,0x5e2265be5790bee2L,0x91e0ea11a8e65ea2L, + 0x0e71a7086001cebdL,0x16900f5a2c1c5402L,0xc3b2d5c0357f6981L, + 0x528c9ea0619e3427L }, + { 0x1edc86b45f26c577L,0xf80747089438bd45L,0x2dfe1013792582a7L, + 0xe08eaca0de1e569fL,0x5f952efa9a55a356L,0xa4d80b53e4976216L, + 0xd2b65855cd5d71f2L,0x246704bf66cea3f0L,0x193f641f492323caL, + 0xa681855c9adb1325L,0x86d522ce2d19d652L,0x53609f105b82ed7bL, + 0x3b0f00948e150d29L,0x23ad8bfb0b13e891L,0xcbb1556cf794b449L, + 0x200f9093738bcf57L } }, + /* 40 */ + { { 0xf9b22fc58388387fL,0xcf26f17028e883c5L,0x447cab90d1b7973cL, + 0x8d5d4ea2f6ec9171L,0x2e16f498c30cdbc0L,0xdc92910c48623c2bL, + 0xeb1491b030dbc545L,0x631deb2e14de21b0L,0x04a210662fe830f4L, + 0xa4c6979c379c1f3fL,0x8a732b68fb06a795L,0x3a44327a1619dfa9L, + 0x91a307d38dbe2c9bL,0x939bc8d203989feaL,0x3daabaf20f4a331fL, + 0x5c307e98dd0f55dcL }, + { 0xbbc4e0c435b233daL,0xe3d2908522f6f985L,0x99dd2d21a8b02468L, + 0x978f40e9a96916e7L,0x0327d86c614bccedL,0x95e95502b290762cL, + 0x0ffd2197a879f2edL,0xc436513750e0bd33L,0x26c3148a0827c4c4L, + 0xc79812a83fcfc0b2L,0xc3d8d17e31928589L,0x8b572cfe8830f42dL, + 0x7cd9ff924b07f83fL,0x331ca9500a51148fL,0xd0c539684c59f9acL, + 0x1df16dfac1434785L } }, + /* 41 */ + { { 0xcc7bb4ac68bcacc3L,0x06ded34f430f58cfL,0xc59f9f4fd461855aL, + 0xf549199445c9f0bcL,0xdc5f7ec64375c892L,0x1b8708f13c85983aL, + 0xb32a5cc482fcd087L,0xefdcdc352d6b4c0fL,0x4bb24f048ac6fb2dL, + 0x5982d4f533906471L,0x162eb52fb83a3ac4L,0x7130df282337a223L, + 0xdce7b802cbc3dbd3L,0x8b3959592467ac0eL,0x21d3d2e81b56717eL, + 0x729a7f5046512617L }, + { 0x874ed1aa8420f90aL,0x6368e19e0fe4c855L,0xb62d4aaab0be74afL, + 0x76fcc4808ca60ca9L,0xf310b5a57645a867L,0x131bac9bddb1b24cL, + 0xef77d71d2dea5b44L,0x4706d21072fcc64eL,0x29b92691673d77f0L, + 0x22e00bf3e89e0663L,0x472d0cd374077d40L,0x3e21040d829232e2L, + 0x2f916dfb38dc8533L,0x48bbb59b14b8f667L,0x19de9f4ad44be19dL, + 0x7f6d3649232d9d5cL } }, + /* 42 */ + { { 0x3bd064de6e794819L,0x5a6b694ef82ebda1L,0x1f017fe0b91e2804L, + 0x190d31f307a43cd2L,0x6c26f226630433e9L,0xba488aa70abfdcb4L, + 0x418d9085a46411c0L,0x1b934fe6bffb5880L,0x75d1e237e200f849L, + 0xdf04d63fa55413dbL,0xe216ed75e23b3f77L,0xa05866cb0f91bd30L, + 0x84c395d97729c509L,0xec97e188452ab2d7L,0x8cb7c1f90093d686L, + 0x2d032395628f086cL }, + { 0xa81c94074a44b4c5L,0xb9846879cc702c98L,0xcb502287ceb0dc97L, + 0x303011266e3aa321L,0xc0ac8763e4c256c2L,0x65034d20e55b4845L, + 0xaa96a040f240f35bL,0x046d26d37cf7eedcL,0x62a5a8e13b810656L, + 0x86044b9783d70c2bL,0x2fbaff8859e4da8fL,0x929d901a5457f5d1L, + 0xd29e1eb2b531b757L,0x214dabdc9e4e9739L,0x5bd724fc4eaa9bd9L, + 0x734c12b31ef9bb9bL } }, + /* 43 */ + { { 0x98fe3c2e92f9b086L,0x4641b93eb3fd4544L,0x47ce208b5c02c65cL, + 0x8a52dca1c4f03242L,0xb5ec17d9679d29f6L,0x11d2fed09406f5f4L, + 0x260f63dc0d9ba811L,0xde2b056f15472a3fL,0x1b170d9f007290e6L, + 0xa2e23e8db6b5c8f9L,0x345a2839cf34c3eeL,0x9bdc54611b973ee2L, + 0x65bda6c2bb24d1c5L,0x97d52ba33c6141a1L,0x47bb16129d2eb201L, + 0x7c558a8721fbe49fL }, + { 0xb9485a523f350fecL,0x016678c56a38d4c0L,0x8ef346a20d5aa64dL, + 0xb85daa02d96da2e4L,0x845ec4ea4f647b3cL,0xc0d1a6ca0d5e946cL, + 0x41d8d1c14fa9f4abL,0x43972cc59c8b1303L,0x67e1f48d434ffbfbL, + 0x350ce93a819d2318L,0x49f530906ddef23fL,0x3c2e6cf9200cf12cL, + 0x42691cc1640432fcL,0xbfff74b472496b52L,0x44527c9f020a97beL, + 0x34cd7dca7b3c4348L } }, + /* 44 */ + { { 0xf031761a59e7fe87L,0xb1eae31a0047cd72L,0x27902e68fae30f62L, + 0xa666f48db71db143L,0x75ee66780e0038f4L,0x3b45ac6702bdd76dL, + 0x0d2fb828a0d6cd5cL,0x27ce7f1d9d8c5b11L,0x141fe0e4120b5e96L, + 0x95a1b984b9267c37L,0x5206e589d60312cdL,0x1867342eda549356L, + 0x374520b9070c74acL,0x2703cbb59557b0b3L,0xf621f59ca6ed8c14L, + 0x7ceb1cc2abf7b887L }, + { 0x0647a5bbdb7fd65bL,0xd8d45cc036c9457cL,0xc6da99db9e12718aL, + 0xed1dbbf4e93a7fb1L,0x4512c95cbd1566a1L,0x4861ba00dbc0c919L, + 0x3c6cc2989e7f5269L,0x671961500941aaaeL,0xbfcf5d0fc8c538e3L, + 0xad6e9929a25a551fL,0x9071098517ca0f26L,0x743b78eafa89ef7eL, + 0x39d5ea3171ab4549L,0x7442f3f3e6d1c36dL,0x25a683e0059d568dL, + 0x1f629a99227ced5cL } }, + /* 45 */ + { { 0x8925ddace45a1c3eL,0x72d2936541f7545fL,0x45622fcb37e7f828L, + 0x882345133e4c79d2L,0x5dffaf849c2645d6L,0x3078f4dd994802b9L, + 0x566927f09d339fa0L,0x9a500a1e9fd91dccL,0xce0081800ab0abd7L, + 0xd97135a38194e5dfL,0x9e87630798adf088L,0x3baf01b89a45a2a7L, + 0x6fed6154788b4399L,0x980e5722e77a997dL,0xaac90ffa2a378eedL, + 0x4a75fda28bd805a2L }, + { 0xd09a8fbb55e74cbcL,0x737738cefab18f25L,0x0fc23ad69764ec3aL, + 0xc5a7d35be7e0ad31L,0xe75e068ee481cc9bL,0xf0c2ea993d4aec34L, + 0xf1324fe80d4a63c4L,0x5dbb7c1699b0592cL,0x442d674da7e0f46bL, + 0x5a5d66c7a300faeaL,0xe83dc8213333ac83L,0x70ef812e8c408496L, + 0x96e1dcb699ef5fc1L,0x6e2b771b1734e862L,0x04629cdc583507d8L, + 0x5819f9ae23d8179aL } }, + /* 46 */ + { { 0xd99691216aa78811L,0xf64ee8f42103e7c3L,0xddf0107022b9e698L, + 0xe6001f9e4f582cdeL,0x24a608af2ecfac1aL,0x6ef4c78406393009L, + 0x5262eae6ebf72911L,0xddbd0af58c4ee5a0L,0x875aff90ecd87bc7L, + 0x2fddb34c6f24f114L,0x48104281e865f172L,0x95692426886c1b9aL, + 0x6f5f32089ef4231fL,0xaf587acfd0a7e82eL,0xd65719179ac395c8L, + 0x7459603c1364a750L }, + { 0x1c2475bff41ae519L,0x34401fb14af8f251L,0x70ddfcd2aefb2c3dL, + 0x9b2d385b51cdaf08L,0x8531c2568208bb19L,0x16c89df64c33f3f6L, + 0xc23cfa9924571769L,0x2339b51e86d010baL,0x08db0e8d22638313L, + 0xf769e17900fedeb7L,0x3fd96dcba3687ef1L,0xcd046b2391476475L, + 0xf3ff20640c45c8ddL,0xefd167bdb8343d78L,0x493ccb6d4b77ee90L, + 0x33025513b3cf7b45L } }, + /* 47 */ + { { 0x36f0046935eaaca1L,0x0c384b7589119102L,0xcb375665e6d2954cL, + 0xcb9199b9b1e9d6d7L,0x75852349c29c2757L,0x89cbd1bab8e738d0L, + 0x9b8dbe905923a427L,0xa237793e18fe1889L,0xa4271757a742e083L, + 0x8c4979d24eebd613L,0x40325054d4f2cf77L,0xa3b8a091958705deL, + 0x1b191bd933d999baL,0xbafefba43b0fee1eL,0xb3bad1843facdf14L, + 0x9328adb04387561cL }, + { 0xabe84e80f906b872L,0x705523a078262665L,0xd89c6a7e3398ccf7L, + 0x2fab551df55b5323L,0xa0578eca0554dea8L,0xef26523d375589cdL, + 0xd8fd6242864ad750L,0x93f27fc5178fe1feL,0x7b3e6f309df87422L, + 0x2862e49e3750d054L,0x7d90c6b25dc038a1L,0xc1a1ae2284db682bL, + 0x47f3dab79881930aL,0x30e6bd52baf3e0a4L,0x0680025bf62d25c5L, + 0x0aa1f3cfadd0d5e7L } }, + /* 48 */ + { { 0xa982219022a10453L,0xdd1eb91c2a03a10bL,0xafbb5d9596646f3bL, + 0xa58de344f38b6fc6L,0xce47c3e5b8cfca1dL,0xfcd8e16d0f70da04L, + 0xac44349bda262ed6L,0x9320d87bc56e2f8eL,0x9ce3ea0819138e58L, + 0xa5862dffa2b236c0L,0x6b0f9a5c8e7efb0dL,0x4b53432b16ac78ebL, + 0x6ff43105709b51afL,0x08e236f88f519628L,0x1f93f176eed403adL, + 0x559337e09636545eL }, + { 0x30ddf738d8fd807aL,0xf4e0ec9dab131222L,0x14a2f4db625afbc3L, + 0xd5b706049f12f895L,0xb46f3c23ac3044fdL,0x1b232d1ff540148fL, + 0x61b458f539b4e554L,0xf694b24a0dd70b75L,0x0fc64299289581d9L, + 0xc05d49beee5fe22dL,0x7af3447f6a18bf63L,0xe96a1dc27f1929d6L, + 0x6afe6028c1551e8cL,0x27dacaf32b5d4fa2L,0x4a1631bc545c2cb4L, + 0x930070f9b0c914d3L } }, + /* 49 */ + { { 0xd2f32c5e69a9bc05L,0x0a5c19c6589c4b73L,0x095c9e5e94665f9cL, + 0x8ab0f293bcfb4c39L,0xb90708771ddb7c31L,0x894e965866b38048L, + 0xf19a90cf606bd9bdL,0xcc1d58dfb6fd2d69L,0x886dcc4e461d8a69L, + 0xc455c277f9ce4831L,0x749a5996765f8a82L,0x2ffc668cc3badc8dL, + 0x380183969112cdabL,0xa98795c3b243c7cbL,0x8775f310010a2224L, + 0x043a2141587b5e14L }, + { 0x7bbe9dbc3a873752L,0xee1493f42f442feeL,0x981ca2c8c18c2181L, + 0x00ce3090e29769e7L,0xb4626ac8de768c5fL,0x33e9ce4634d7677eL, + 0xf89c2cade0fa94e6L,0x04f5cc1141f5b5bfL,0x2565f7362228c12cL, + 0xf1bf706a0c05cce5L,0x5d07ffffbe487c4fL,0x3ec43c09a499f1a4L, + 0x4f4e79bb98d94800L,0x8a335a16073f12f8L,0x4bb5eaf70f970d6dL, + 0x18d0747bf24d0ae8L } }, + /* 50 */ + { { 0x58d3c77c84601fafL,0xc9465be2af1c1f72L,0xff626798d116d806L, + 0x3996c0c6d5b0d93cL,0x2fa1ad755ec6723aL,0x966a814403ba5349L, + 0xdc4c94222ac34d8aL,0xddf471deed675865L,0xd8aca597953d528fL, + 0xb2e463b524ebf67dL,0x258248717e25b4d3L,0x23c5adba43159daaL, + 0x5458f9c683357540L,0xcf685da7f938b1a6L,0x981a4fdacefed231L, + 0x711093ed08bb5e59L }, + { 0x12aa3fc6401f161aL,0xf7358560974c5e87L,0x4aa252fb17b5df82L, + 0xb0b82b07a48e6299L,0x0023415729dd847dL,0xf1e54d004529c5a6L, + 0xcc1c539e6d98f538L,0x36162b5328d3abcbL,0x75a379382a84f0cdL, + 0xf717a81b4dee7484L,0x16cf35fb4c23bf1bL,0x7fd1c29f787e8b3eL, + 0xb7da7e6859b79ab0L,0x072100a085f6c60bL,0x31840159e7ed48b5L, + 0x17898bda4d9c97d4L } }, + /* 51 */ + { { 0xcd8483d8ae1b8cf8L,0x323d4b42e9a28856L,0x7633584f204a4bc2L, + 0x4e0b2228ca7a69faL,0x8afbda8bf757bab2L,0x85b240886cc5f9caL, + 0x47fb4813d41a95c3L,0x3f1bc53cc2aabe6bL,0xf22cda3f1ad1599dL, + 0x1b2ec081c31ea9b1L,0x048f304b01614ac1L,0xce31cee9c6afa7abL, + 0x55af76334140dc3dL,0x84b7ab37dce8abbaL,0x50de7648c7cf3efeL, + 0x73a88dcf15356ab2L }, + { 0x3f86828806e83b39L,0x477a44139f44037dL,0xf9058b0f17dbc841L, + 0x2db64f4f54d17549L,0xa23cea6af2307ffeL,0x393efd554f126261L, + 0x2f4e658a10f37f26L,0xa4437ce3f4ee1e35L,0x64ef42a7a93cde8bL, + 0x1debc9f4939aa901L,0x44223d6a3d7b5cd4L,0x789a6a11f88a3accL, + 0x56fb9df82c608a2dL,0xe79db8e3bbf56c06L,0x73c56af2668fa300L, + 0x52f32b17ae396a1eL } }, + /* 52 */ + { { 0x56f524c1e714f71aL,0xc1be12629add8519L,0xad9189d865cadbe3L, + 0xd88bf5c85a0fb649L,0x9efa6a9221d192d9L,0xe3fe83896f724b6fL, + 0xec3fae24b250119cL,0x4b6af9f62ae0d3c0L,0x8fceba0bd619624dL, + 0x7dc3092b2fdb6e3aL,0xc91da3763263cd29L,0x30c0761ef95c43bdL, + 0x89136400cdeb44d9L,0xfd7dce8443c0d31dL,0x78fec3b19871899fL, + 0x79e14d28efdf58c1L }, + { 0xe38222359bb40c55L,0x0a27202d0ed07a42L,0x48e6c1a94838c1f4L, + 0x2b5f24a7d864a78eL,0x7e7f140a0c6c55c9L,0xe62c104ace12d508L, + 0x9b0a1a7ec11b1e10L,0xfd8a275fafbb3dd5L,0xdff354fe9a3b6b30L, + 0x5a105d9e46602a01L,0x3d371b4d93bb65f7L,0xda5cbf0b0f82fdebL, + 0x4601229bde468545L,0x505e10b9c73d517eL,0x77cfa541672ff492L, + 0x0d8ec28a99566ce2L } }, + /* 53 */ + { { 0x014cf73ecbeee995L,0xb2eb88bcd491e80cL,0x615a6cadd9aba5d4L, + 0x2f7d46339304c84dL,0xba0501d28ab03c9aL,0xc8f723de91babb94L, + 0xc885f97750405772L,0xb5e1d2b3c7fcb094L,0x61ee7995df96c71aL, + 0xb8c8daab3464499eL,0xdb425ddd5f607932L,0x70251ca1b1243587L, + 0x26d7d3be9fc74340L,0x8c179310c902ac89L,0x72522c154559a74fL, + 0x86001e27c3734afcL }, + { 0x13b00ba5e7693947L,0x6478641e012c062bL,0xe1a438e0e85490a8L, + 0x5173dbbfd9574d5eL,0x9532eb8c9bd3ba61L,0x1f41bcb85f3ea075L, + 0xac1cc2478cbb92b9L,0x0f34648e1ef901b4L,0xdd929d1ed2b3b2eeL, + 0x470f1eabc3d75bfcL,0x5cdbc6f7139cf4d2L,0xcd86454df0424953L, + 0x1e07981247fcb383L,0xb9f209b417df930cL,0x4225fc31114ebc00L, + 0x020591cb347946c1L } }, + /* 54 */ + { { 0xe3003721275e0af4L,0x721141efe78a4a4bL,0x666cfcf6d1757485L, + 0x5fa1d737168e659eL,0x263e3e540e2842eeL,0xadecc3d4948bd5f6L, + 0x019de03d246b104aL,0xf8a9e903f343d818L,0xcb57ba4a5b0c0d31L, + 0x8246c50651e2765fL,0x80c5751f6519bf67L,0x5f05c200f2119a01L, + 0x7e6487b87821d4f4L,0x262f94aa261c3a06L,0x56cfe48972146052L, + 0x5119985fa1df05efL }, + { 0x5819497db18586c0L,0x004415d6c6eeaa62L,0x7c6a46b697cda28bL, + 0x9a149b287c194594L,0xb56369fa4ed3a506L,0x7092aa6643c94cb4L, + 0x55bce73aa9e9eee2L,0x34bb287077893509L,0x8af95fb006eb5326L, + 0x87cd03239638f485L,0x293762685ba75bf8L,0xf32d6f3d9d42d581L, + 0xa4cad57465c6d64dL,0x985f50fbb2cded41L,0xcf34ce0e9006a067L, + 0x59eaf26558a57f9aL } }, + /* 55 */ + { { 0x7b407efb6ec3876fL,0x780c6123f0f48648L,0x2abb56ffbf893039L, + 0x9592eaa045a91ab0L,0xce5b84d778811b82L,0x86a71a341f9f3fc9L, + 0xc17fdd86f0e7e13bL,0x88ed8297655a0880L,0x75d6dc7481d5e666L, + 0xeffc9df61d171797L,0x36ad4c8de3f79e1fL,0xdb15317d2046192eL, + 0x78c9fa7a274fda62L,0x04ec924f82dd9914L,0x059d1e383a64971cL, + 0x3b4450ea2620bbfbL }, + { 0x3db7a955c776dcdbL,0x35c4a57c81c8ba47L,0xae285003505760fbL, + 0xe3e80691b3aec353L,0x380335be47117be5L,0xe1c47e3a056ccf61L, + 0x253cfdeb33977916L,0x3decdfbaf5cb7ee1L,0xf3c9794f7cf4b704L, + 0x2401680c9ff81462L,0x4e440e11be3daa9fL,0xc5d0437769f91d8aL, + 0x4106c7a8cb5e9c5dL,0x191909a133b7d24dL,0xe893c8383764b4a2L, + 0x4a7fe30cc429b614L } }, + /* 56 */ + { { 0xe78f3a702455c7c5L,0x5b7636e870157754L,0xf32c45247623262cL, + 0x2c98b11e1bc780c7L,0xd48eaeac915ed877L,0xbb04d3c0199265f4L, + 0x6b52b19bcfa5200fL,0xc46a098193ea3fe8L,0xd82c733dba758059L, + 0xd324bbd61896aaccL,0xac09a2fcce8ecd51L,0x529918fd02fc44b3L, + 0xf0c45e4aaaa1784bL,0x35626340fe22085cL,0x53cbb676c50c7d61L, + 0x83fa1ea365126b23L }, + { 0x60ac86da10ccc646L,0x2ce0637f7b0451e9L,0xbbbcf6308a088610L, + 0x23c1901920349982L,0x707fc39cfc0bcda0L,0x7f4d1f151bd4fd7dL, + 0xd6a64e7444713bbbL,0x57bdc676c5ac9e60L,0x456c530337b61169L, + 0xd3451396dcf40a1dL,0xf3edec254997d2c7L,0x534ae9a4c2c4a739L, + 0x1401397e6a6ad2e2L,0x20769d4d23e95f81L,0xcee007c6de98fabfL, + 0x61409779931c51e0L } }, + /* 57 */ + { { 0x3ddb32db15156623L,0x68137fbcab7a67c2L,0x26011f506f19e3c2L, + 0x34218b0289924c61L,0x492a0b0fc6804c1cL,0xd65be706afaae6a7L, + 0x3b13d23e0d01be61L,0x44545b47f87f4c69L,0xd42236e204dc1aa3L, + 0x6135261d3c5161ecL,0x1eb46a63bd88bc07L,0x78c6d8361599d720L, + 0xf6955fe169baf0f3L,0x467eebd617072820L,0x2f1b8a2a3e3a340aL, + 0x636dac762d0b5f88L }, + { 0x94280db9b4c80af3L,0x9a189cd14e3892abL,0x26e702e0d1477ddcL, + 0xe91aee3868f9f14fL,0x2864f63a80baa0b2L,0xacd81f738b714a29L, + 0x30e1b870c5fe7cb6L,0x883ea1c3b10837fdL,0x2da279536b20489fL, + 0x3aeb2a6858a2da5fL,0xe2330bf203a8fa14L,0xb5c488b5dc70b1c4L, + 0x0a78c4d9299678f4L,0x233bd09825df675cL,0x37b5c0767b67d368L, + 0x2f6dbdfe4d0bef3fL } }, + /* 58 */ + { { 0x2f8472fd2e4da7c7L,0x708cfc91ae677932L,0x364af08a3dc268e2L, + 0x0f10dfe0799a2424L,0xef912d5871d58bffL,0x6bf35dfc988962e6L, + 0x28b96fa95f47ea0aL,0x734a79eaaad308c1L,0x957303379f437bbaL, + 0x002cbd8e6cf54f75L,0x47606dcfe7632eecL,0x404b5ecb53193104L, + 0x0ae0897c0acf729dL,0x89628b863bddf1deL,0xeced154ef87d7448L, + 0x5cb6e197458d5d4eL }, + { 0x98cef197008c75edL,0x7cf49d3ef6eeaaf8L,0x1d6f9e021875e96dL, + 0xfcec2cfedd9b0d8aL,0x38a61cfeb9576daaL,0x10003f3936a7dbb8L, + 0xb37c386823b814f4L,0x9fb66dcbb80e3153L,0x9e7e2eba059847a8L, + 0xa4ec63fd35a72770L,0x311f3d91fc9e0ed0L,0x3c1dc094d515baa4L, + 0x75a06ebca08cd4e3L,0xab6172382ed5eeaaL,0x2e82bbb0e1f52c1fL, + 0x2149d6305175d6e5L } }, + /* 59 */ + { { 0xee1a8e6f5f9311f6L,0xc97e3c9fbabc1f85L,0x4fa7c52eb494209aL, + 0x04c2f51c19774fe1L,0x5cefd1228555844fL,0xb53862a3b5873ab3L, + 0x768efdd6cbed19fcL,0xcdc12479ee58469aL,0x11237e313d80c09cL, + 0xdd74a290c044c28cL,0x9ee6517abd47e287L,0xc2421228ad0ffeefL, + 0x4273088f818d281fL,0xebc744bc43ec0de1L,0x5b26eccfb415bd73L, + 0x14e2f350cb07c26cL }, + { 0x548d2a104216946bL,0x6e801f077a4bd92dL,0x5996d0a343695160L, + 0x0f1b5c2f63a197c9L,0x79da3c4f061f77c9L,0x1c1cd63493ff7b22L, + 0x5e61b650a234123fL,0x826b34c5f284033cL,0x718b90e8c2f34214L, + 0xa5f35620ae806ec5L,0xa2fae345e324a9b4L,0x8c0bb95e8b53cb51L, + 0xc94f6ac2f9965778L,0x07ec607d6b9def32L,0x63bf1dbad0ed8f27L, + 0x58537e02dcb61e4fL } }, + /* 60 */ + { { 0x1f64b06464f80ba2L,0xe8e055e70559a45bL,0xc3262b34f1f4b634L, + 0xef4f7d5fde8c8482L,0x9d55dea0c30c780aL,0x1740afb9cfa1e693L, + 0x2cfe6a667460c34bL,0xf66959411187c1eeL,0x1382f2775f974d94L, + 0x1ca0ace4004549ebL,0xf8244b3fbabded02L,0xc36f4d064e3653eaL, + 0xeab9f0dcc55c5f83L,0xd93b9cefacebce90L,0x16658e7219061425L, + 0x4857835f82d7970dL }, + { 0xdcd525bcd2576210L,0x9f378aa7d51b5443L,0xfe97bf171bd83994L, + 0x930d0f63f38ac621L,0xaf8f2c17818408ccL,0x2692c87e260f53f6L, + 0x0ee45407db0a75e4L,0x0ec47ae5ffdb1b37L,0x769129dc7aa6a44bL, + 0xb6f932b22e40b75dL,0xe06764d095ef3b77L,0x28fd47f568bc63e8L, + 0xd18104949c0014c0L,0x90e2d3fdd7995d8eL,0xeb39a05d6c2a85afL, + 0x6c0277bda21f3128L } }, + /* 61 */ + { { 0xe41b7086b509e7efL,0x8842ec7b3d7f9f91L,0xcd285f945526b88bL, + 0x6e44e064051dd0abL,0x90198c10774f1cebL,0x6ecabe98123e661bL, + 0x4481113632f647d9L,0x1dd82b4526c52aeeL,0xd650907f939dc9d5L, + 0xbd5eeef2fcd455bfL,0x7815a4dd8d2e5d7cL,0x5ad4ec9288bc9f2aL, + 0xc6f10d0b57a3b322L,0xe8d0c1e720b9cbdbL,0x5a0b071a9b774ee8L, + 0x3067bc9af22fcf8fL }, + { 0xe0e589f2b7ca9326L,0x17a106fdb1224f63L,0xb2354521747a57bdL, + 0x2614982d62b0882eL,0x7f3af5444391ffcfL,0x1aaa337ba84e440dL, + 0x28ea37b0941bb071L,0xa957dcb42e4a7f54L,0xe7ab662c1a6ad5fbL, + 0xd135e381f7c36a20L,0x42e7980c9baa0b6bL,0x4237030c94e4671fL, + 0x24cc63ff8b0922e3L,0xd10d5279445a589fL,0xbb99d316a870ff6cL, + 0x390c83caa996c195L } }, + /* 62 */ + { { 0x50d3fa82ffc4a73fL,0x2665d6353bd53303L,0x80a06f8a264bb77dL, + 0x81c04a6e22d73d84L,0x2409cff50323b8aaL,0x31dce2178c4c4d5aL, + 0x374aa80e0c0f9c19L,0x0b25a38700186bb8L,0xd0b77a10aaf1487fL, + 0x15f39ad5ab498de1L,0x92e32da61aa0c116L,0x228e3dbd96e25ce8L, + 0xb57c88dc5e8646d1L,0x672b1164267b1c68L,0x5d0d807f600bdec5L, + 0x3ea4007d223e573aL }, + { 0xd76debd0a595d0a3L,0xa6bd76cbaff0b3b4L,0xbf2c154f9b1bdb97L, + 0x62b19ab44c714c71L,0xc9bf33b9221af663L,0x23d87c498c941ef6L, + 0x255804c3d79f0f6dL,0x6f1a10052a7acbc1L,0x5dab79d9550528afL, + 0xfd77a6f0c8d16213L,0x40508b6dde5e1029L,0xd95ac0f2f95da12bL, + 0x8860af71758a8ba1L,0x0b194c837160c8fbL,0xa40e6c80ce004d34L, + 0x09f82a176b14aaa0L } }, + /* 63 */ + { { 0x60abe588c21366dcL,0x729c0a4faf75daf9L,0x70501fd9acb93ed4L, + 0xb97e744e87a16d70L,0xa42e0a7a98e7361bL,0x1acdaff228b54cf3L, + 0xf087ccbbb7bd9078L,0xda6f3983663250e7L,0x66d693eebaf07c09L, + 0x79baf4c38cbaf157L,0x5a984e07dfca99d0L,0xab4d3247f26d8dabL, + 0x4d0be7017eba36f9L,0x37bb9e650e8dd216L,0x72aa4e24531c4f03L, + 0x77d1e984b753d85aL }, + { 0xd9373239d8e62367L,0x3361848bb9820cf1L,0x00c7e3445a9c97c4L, + 0x9a0ec9ae14f960fcL,0xcf41f0cf740474b5L,0xa5eede8fece065d5L, + 0xb1de5a4e9e808610L,0x17c44ae4ae0cf75dL,0x2fa563236b148d0bL, + 0x64fa740fd29ff2dcL,0xc605eb8a88cb212eL,0xf2c771ad6a863016L, + 0x6d6112e7607b4c17L,0xfe90ec0740d49785L,0x599be18be256e0e5L, + 0x4e6eabecca54adb0L } }, + /* 64 */ + { { 0x950323d3fb99cfe6L,0x7b09bc26c9334178L,0x64111e417cbdfb6fL, + 0x9114174489a75760L,0x4c633df910919cb0L,0x715fc7c7396bfd2fL, + 0x8ca195128cab62dbL,0x306724734db81aacL,0xe67a246bb4c4c54aL, + 0xd77ea0fabf229646L,0x5bed15f1fa5b5d70L,0xa5686da5c2f192f3L, + 0xdecac72a7f6690adL,0x0c4af2a2caa50b7dL,0xf44631c16049ad2fL, + 0x325d279604ecf056L }, + { 0xee11fb554848c144L,0x4e062925b6a7af32L,0x125b68e1369e0f9aL, + 0xad9bdae6ca53b21eL,0xf50d605c2e98ea1bL,0xbdb9e1539f2fa395L, + 0x4570e32de91532f5L,0x810698ae46a250d7L,0x7fd9546cad9d9145L, + 0xabf6772111e97a5eL,0xca29f7d5249f82e9L,0xa9c539a99851df63L, + 0xfd84d54b71d0e3e5L,0xd1e0459c041d2b56L,0xceb3eb6efd80096aL, + 0x19d48546e32a79d3L } }, + /* 65 */ + { { 0xfe19ee8fb540f5e5L,0x86d2a52f04e68d17L,0xd2320db0adbdc871L, + 0xa83ad5a8d03a7fc8L,0x54bf83c708bcb916L,0x092133ea2e51e840L, + 0xbce38424cb52dddfL,0xd5c7be4031063583L,0xc1ebb9df458e3176L, + 0xafb19639bc4dabbfL,0x36350fe4c05725a8L,0xac4a063484e1cd24L, + 0xadf73154c145b8deL,0x0aa6dd9eb3483237L,0xa3345c3dcbff2720L, + 0x1b3ace6cb4e453b0L }, + { 0x0343e5e990a8bdc5L,0xa203bf9d6306a089L,0x98489a358e48520eL, + 0xbd17debede7d1d06L,0x8fafa6d75f795d3fL,0xa4ceb630387b0a3fL, + 0xe0166b32ffddeafaL,0xa2fe20547e764e02L,0x55ab9824e871f304L, + 0xa2bd36bb952ec45eL,0x7b4c1484a90d20caL,0x5319f38775bcfb53L, + 0x34238a4a6982c4e5L,0xa2bb61c7a102921dL,0x1e061b64db3ab17eL, + 0x538ec33e192f0a14L } }, + /* 66 */ + { { 0x193496fea19b56cfL,0x663d77f47bb99acdL,0x8f04afa857d0a881L, + 0xcced3da2082835fdL,0x7e21faed5d82cec7L,0x6e175b99f8009c85L, + 0xd9c6e31b2d05a307L,0x96948d4a81487d82L,0x86ebd3f2d46f6655L, + 0x86851aa8773ccc49L,0x3e220f228b1640a6L,0x9f06e3a841a20b75L, + 0x2cfffe5e90ac0a6fL,0xf5a9b1da8ebeb3fbL,0x2587d9976e08e2c9L, + 0x6fd6029803e9f401L }, + { 0x54709f8d8eb7516aL,0x83058a74bdc598abL,0xd234dd9887e801ceL, + 0xfd0f9d90d17b8a96L,0xaa1e549f6e90f6abL,0x2496ff805a7ed55bL, + 0x0d9f657a6c254c19L,0x3cdea49cb8962575L,0xb685a3f02dff27deL, + 0x3c50e7fddb8bc04bL,0x904ff0ff987236b0L,0x494298fdbb0d5055L, + 0x34b3386de14be8d0L,0x7ad34e9c7c3d30d6L,0x1f2b32bde159fdd9L, + 0x84cfa23cc761e5c0L } }, + /* 67 */ + { { 0x13bc11eb8b99b964L,0x8e280c0a58e2fc47L,0x870fbc49d4c9a54bL, + 0x37a334a2bf6e20faL,0xee583d0dd7c88cfaL,0x05e029a8ef4af1daL, + 0x6d55e2340c2ef8a6L,0x61b6fdfe209e9b62L,0x3b1dad26bb8e080fL, + 0x5adbc1629392fc1aL,0x02ac0fe60aae3f4eL,0x8d99801ac2bf4d5bL, + 0x2333f93fc282fed2L,0x16dcb10cb52db33fL,0x09f90f84c55752e7L, + 0x287d4c51c84a0d8eL }, + { 0x5fa582010e9867daL,0x614589b31a874cdaL,0x005e27c5fbdee22eL, + 0xe357fef5e612bda8L,0x4e0dbedf2d3635f9L,0x62be70e46f125a86L, + 0xa09b98840d94a2e5L,0x7eb99a1528b5e5d1L,0x21b9416e751028b5L, + 0x1b137fd7e06d2cc4L,0x6fa1f517fea09845L,0x3ba1e966ffcecbd7L, + 0xd4c89a4a832f453eL,0x07b1e2afeca68fa1L,0xd0fb44534bd395a3L, + 0x0132a3dcd8ef9e13L } }, + /* 68 */ + { { 0xe53c7785576374c2L,0xe60526d184727040L,0x8a066dc8228ca044L, + 0x1fe1c1b2f1ce1313L,0x2aeec832cdeb0c5dL,0xa75966999cbf826fL, + 0xcd188e81de77a589L,0xe5ce0fe0118d1254L,0xa142a9840790b86aL, + 0xe28f043f39ac28ceL,0x4eef829087de5804L,0x83c31b32f639a8c5L, + 0xd70454a75887794fL,0xca635d5018b1b391L,0xcefea07631d9c795L, + 0x13cbee76b6f8aa25L }, + { 0x79cabe0f8d3f34f3L,0xbda9c31ca3617fe3L,0xb26dee23dd9426a1L, + 0xe9dd9627f29c9104L,0x033eb169e2c6cd3bL,0x8a73f492fcba2196L, + 0x92e37e0bb858c83cL,0xe4f2aca623b3fbb7L,0x8101fb1e64be00a2L, + 0x91a7826a948f6448L,0x414067b4907260e7L,0xf774aa50e30bb835L, + 0xf922ca80c999c06eL,0x6b8635b90ba08511L,0xbf936b5c25fa04f0L, + 0x4e0a1adae02e8967L } }, + /* 69 */ + { { 0x00ca66708ba29c4dL,0xc08240ce22988094L,0x21c5ca6716dda752L, + 0x689c0e45abbbfa34L,0x1d7545fd3ed28b72L,0x5f221198d7c56ab4L, + 0x4b3d8f7438759d65L,0x93490dfb8fe50b89L,0xb641f5d7e80eba16L, + 0x7b0da5eb79acb537L,0xab6b14970c1d5e5eL,0x2338e68da5da429aL, + 0xe010c4372f6d2f25L,0x226f16d26530f3a7L,0xefb0f7b6cbef08bcL, + 0x733e30d99f99c999L }, + { 0xecfe1582a42a38f9L,0xaec2d58e4730b500L,0x2ee2f2a7de976b2cL, + 0xf0539db5a969c1bbL,0x31954168fcecdb4aL,0xf2f7348ae7a8e902L, + 0x1d58d7cc3121541fL,0x5d25b75c2202ae52L,0xdea9965af40835a7L, + 0x3feb6a41529b4e46L,0x5c97fb6fbd27ad9bL,0xd87554c0261f900bL, + 0xb43031d904d5b19eL,0x33d5e9b8cb219b9cL,0x7a43d4923ee00bcfL, + 0x56facb39b79a5c0cL } }, + /* 70 */ + { { 0x019165a2a3018bfaL,0x100c6b249ffad984L,0xbbf1b1f655341a9bL, + 0xe6bd1d9725dc4cc9L,0x52850ed52bfffe60L,0x24e992cc7e5509abL, + 0xff6c502e4ceb59f1L,0x2f0b35731aa7d148L,0xe90c1ddde7e3aa46L, + 0xbaec9f45d1142880L,0x475cfd2665be5dd5L,0x83abb14e1febce13L, + 0x6aba482980942d30L,0x1e1b235d297e82c8L,0xb771cdbe50d8218dL, + 0x88599266d94d6cbbL }, + { 0x08847290155ccaf2L,0x8679ebc77c5b773eL,0xa88b2dd1b2dd08edL, + 0x960a180e87d475dbL,0x80fdb6b76694d02aL,0x3e8758c93f3f9e96L, + 0xbda3f6fa4ad836c4L,0x9400c58132fb387dL,0x25a785422550200fL, + 0x2a97c351776ecf18L,0x03ebf46e566db59aL,0x4743a28026545edaL, + 0xed169d84cf74ab44L,0xbaab931d88cb3f69L,0x70ae932cd8257196L, + 0x797224a6a0c09719L } }, + /* 71 */ + { { 0x632923f8441f3567L,0xc11c31682e24bf1dL,0x4b97726bb7671fffL, + 0x601746a77a5e1a22L,0x53dddea03addb417L,0x57867a3c7f59b846L, + 0xb012a98756cd7ff7L,0x1bd5fec9f19ba9a8L,0x750379a2f8306748L, + 0x7763445dab8c05d1L,0x5d7f441b7903f42aL,0xc011674da903e46dL, + 0x1b1d3c4dadd126c1L,0xa2752aac61455b40L,0x4da42a68555c356eL, + 0x3ff09c15d820852cL }, + { 0x4c0a1bcef9cb7784L,0xaec539bc2422f305L,0x5f40f9fd0c414aa7L, + 0xd3aa316cffd42bc4L,0x42f5a4c32f358e15L,0x00bdcd9ed6e27682L, + 0x069f789ff8a5eceeL,0x8078018e05e14f5dL,0x2bb3e4938b40c741L, + 0x5dbc8c1d7917f72dL,0xe0eea664cc57150cL,0xa25ecc5ac3fa8920L, + 0x3c21b0f51c797164L,0x8f09a2f2634ad16bL,0x8e730fc558391d9aL, + 0x47ef18054fdfae4cL } }, + /* 72 */ + { { 0x9965f3d13da285e4L,0xba7d4dba3a01e3f4L,0x4738413a61214ad0L, + 0xd3b7d53522397549L,0xa53dbdcf5a730b92L,0x3130d92b332d165dL, + 0x44a2854182f97ef4L,0xbf62221c44dce1b6L,0xbba138587e2a0ec9L, + 0x33f32c8dcbfad998L,0x409e5f3fb5fed44bL,0x5c328c65c66217bbL, + 0xb00db69ffcdf71a9L,0xa23c2a21b8920788L,0xf8ab28e63ae6464bL, + 0x1a6b6e9cb8de0861L }, + { 0xaf6ec2b606af77aaL,0x2e60f5cda887f065L,0x87d214009f498c56L, + 0xdb595b59fcbaaf4bL,0x0fb592a1271ab855L,0xa0ce10e5d4349b0cL, + 0x9d6187d8887d8c9cL,0x03ee95f9154bd6dbL,0x8fe532135d06c999L, + 0xf4a7bc30fb6a64d0L,0x3d22af0d66a4cb60L,0x16952cef5d37367cL, + 0x6f0ea734997d8e55L,0xb447c70f731732d0L,0x00ab3034a9cb3942L, + 0x79dd018028510fd0L } }, + /* 73 */ + { { 0x04e0033a3ac7424eL,0xdb06b68860fda4d0L,0x236a9766bcb772fbL, + 0x294a8e2bf297cda4L,0x4b0aab85db013c6eL,0x3d2aec988723a3adL, + 0x0cae32cd13c84a6bL,0x21888f5e70ec169eL,0x739633bd42a88262L, + 0x68ac792e7b60d9b8L,0x89f2b72210769fe1L,0x8f3fcfe6d24bed34L, + 0xd35efb88a3eb24aaL,0xddecfa3f484c706bL,0x7cc119a9929ece0dL, + 0x87e5ad458d405436L }, + { 0xba99aa9d7d1000a7L,0x8b94affcae823833L,0xc8229628dfb83dc5L, + 0x2f59fe11845a418dL,0xa8b970f85d417054L,0x8918c26572b71581L, + 0xe4ef477dc0d1dd17L,0xb50b4cf33afad7c0L,0x21baea7901870a5bL, + 0xc77087f9bb3a2868L,0x7857531e124a59cdL,0xed74c26f57f43239L, + 0xd5f5ae250164c94aL,0x6608b7e2f094bf74L,0xf4cdb5bafdceea32L, + 0x0b712519990cc045L } }, + /* 74 */ + { { 0x5a290ca188d5c64dL,0x0596d749a7492534L,0xa04b0d3d2a00e925L, + 0x082cd02ccaf7b66bL,0x912b50c2ecdded83L,0x813ce9deff31646eL, + 0x62ae70c7c75fff95L,0x6f6852e07e2a4615L,0x320fd7d003804fd1L, + 0xb1a2a4dd8218e8d9L,0x4918a6fbafc645d7L,0xfb080fa1e8d9fdbeL, + 0x33d4d08a4470b6eeL,0xd2ba20776d974ef7L,0x8ecb95a769dae5d2L, + 0x7a3f423a7d69596dL }, + { 0x362d2ca69a929387L,0xabdb7581cb1c1fffL,0xd892ec9f7e51b6cbL, + 0xee8d86323a4e131fL,0x4680e3f15bd87561L,0xe3a597e1d4e7e732L, + 0x3cc72b7c5581fefeL,0xf3e77f8aca8cae0bL,0xfcc7d7dc5e2fd4afL, + 0xdd3a455221355b79L,0x546b24f2a2c07177L,0x415b532d0689621fL, + 0x2be9af513f78163eL,0x27d63b9b33d7ed21L,0xab019ef296802943L, + 0x2da5fc551623faf4L } }, + /* 75 */ + { { 0x62429cf3c8a5c600L,0xa7a80c223fe33e7cL,0x9ffda7400a57ddcbL, + 0xd1ae156d925b0c74L,0x097a43f96b100eb0L,0x169e945cef943c81L, + 0xa1f734e51128cf24L,0x04387c4a419f0133L,0xc007868b01044024L, + 0xe5416abf90359cf2L,0xf9c76fee478d54e3L,0x66219da642a2173eL, + 0x61e031569fe30141L,0xa0ff5ce393ef247eL,0x811792ba072b6592L, + 0x855f021970c854d3L }, + { 0x61fbfb6c847314c4L,0x97906155eb45b96aL,0x7102e1466ba2afacL, + 0xed51f975ab949781L,0x9d2f5b17c110c4feL,0x7ac8ce70aff57667L, + 0xe7366a216eb244e7L,0xdd1bbcec551c65c7L,0xb525060ae1a859deL, + 0x7a0481748ba7d2e7L,0xe1a2c541ab8ea8c4L,0x6e7824c36fdff078L, + 0x79b49fc714874b04L,0x22ae337f06b1f733L,0x1c3521926f8fe6cfL, + 0x292236cf525d0797L } }, + /* 76 */ + { { 0xcdb8d80a7d8b29dcL,0xd17a202408ea648aL,0x7db12c5eae92be91L, + 0x1f347d18fda72fbcL,0x11374b409e760c6fL,0x7361e8f1d8e38d91L, + 0x7714be9d739ac1f4L,0xc1f9701cb4df5c4eL,0xd9138ed86f72cae1L, + 0x1c7fe1f76ad180c4L,0xf8c185be9e2dbf9cL,0x835db2697c70c44dL, + 0xf997cfeab0d15b5fL,0x5101445a61e6545eL,0x16b0688425184e5eL, + 0x7cfac3597521e7aaL }, + { 0x811821673c0bc53aL,0x84b5ede37e751367L,0x3ca255fda3657a18L, + 0x096abbf4ba1fdd98L,0x9ce8369fc5da77d8L,0xf27b9ae7aab342c5L, + 0x06c91bd6972059f1L,0xee0dab30914ecfe9L,0xbb647fbb93f53f12L, + 0x30c38a7affa57e0eL,0x517d06ef9f2ad607L,0x49728d87bb99dcc9L, + 0xb0034af1446080a1L,0xcc810c3f12b9c17dL,0x7225f14f772a22a0L, + 0x6ce3dc7f1ddf82bdL } }, + /* 77 */ + { { 0xc07cd835a4397830L,0x4dd9290cf4733306L,0xdd35d3a829989e8cL, + 0x79902559563d8152L,0xf278d911e87de61bL,0x9c7340c71024e35cL, + 0x2d4444614a0d0e59L,0x63e7608ff32626a1L,0x627a37e9c4c9baa9L, + 0x0c56dc5176fffd25L,0xcb6defc8cef2a1cdL,0xcbcc0d56efc559d9L, + 0xe45f3fc5041cb692L,0xcd05c239e5161e09L,0x2a731ee95c3b559cL, + 0x85151122a3d0a16dL }, + { 0x782d033586ff19e2L,0xc2c60daa1da28603L,0xb2e78cfe557c7eedL, + 0xa8f6f9841bc4e8b0L,0xcc1f9b4b3df35c67L,0x96e136034764462aL, + 0xbf910b977c7ae0b0L,0x27c7f30551435956L,0xc14db15cf631eae5L, + 0xa51d61427e69b34cL,0xdec828515fc12ff2L,0xfcceae13fb887162L, + 0xda332ac1de1488bdL,0xa20374e22ee3e74cL,0x597ea1a1f0ae069cL, + 0x8b1159f277bdec04L } }, + /* 78 */ + { { 0x4af71a442f961d30L,0xbdf968a87ac7248fL,0xd32df87cb1a906cdL, + 0x00c10e2604abf925L,0xb8711759b9f04d4cL,0x00d54e60939705daL, + 0xf7587433c9f80849L,0x2e9abade6a7a2375L,0x5676d47894ac17acL, + 0x4ca0525bc202d99cL,0x95b8bcadabfae73dL,0x2371ed383405991bL, + 0x2b69e47a458a99c3L,0x7cac0b182b78c866L,0x6ceaa79be0232c7cL, + 0x0bd86433588f7459L }, + { 0xdea1a8b47e734189L,0x52c5ac88cfe5fa17L,0x444a4d4e11437664L, + 0xc2522308af9e9750L,0x78b1d0c3d30c6b3bL,0x2edae5f04c6df477L, + 0x53131d9a2ee88dd7L,0xc4e380eeacc93e34L,0xd499b1aca8db0e8eL, + 0x77348c167f5d49d7L,0xc96632571556ccd7L,0x65ce0e8c2611d13dL, + 0x2c95fe66b5a2fdccL,0x266988328658faa1L,0xda87d1f431c32c98L, + 0x46650598fcd91907L } }, + /* 79 */ + { { 0x4c6c13cc6b4a5efaL,0xc481989b1d07b265L,0x10b966ce8bdc69c0L, + 0xf54cfaa22c2531d4L,0xcb5f1808cad0a100L,0xbeb52538ee5da449L, + 0xa6240085bedd83ccL,0xe792dacfd6255c78L,0x883719062062058fL, + 0x96615e83ed1658c1L,0x4b549b277d28d542L,0xeaf127db83b75df3L, + 0x4f60df6d17fbb942L,0xd08631dbf6f7c930L,0x17c38f986018789fL, + 0x0c43574ab9a9280cL }, + { 0x76eb324c1d20cad0L,0x90decb098c61108aL,0xa6e9d39c6f06d36dL, + 0x6cd978babc0da197L,0x5948b1c0507ac5ceL,0x2bd47164c5497eb5L, + 0x2a9c4c0f4d5914e3L,0x772c5046a759f03cL,0xe7d7328a69ac847eL, + 0xa8d57d0c3048b330L,0xe60034e040f7baceL,0x823d9193a85f1790L, + 0xa6e9b66c5c859736L,0x22ca2c7a679e1022L,0x00e7a19c09023fa4L, + 0x324999f12726d5b9L } }, + /* 80 */ + { { 0x667eaed67c834915L,0x9f77aa6abc5eb64dL,0x729ebcb625d62011L, + 0x0aee24f2699fd9c2L,0xe1eb58742b8d4f6cL,0x7f12710c14c976d6L, + 0x91390335f6d9ea65L,0x668b704906b50064L,0x65969a0e0876ee4fL, + 0xf901bf3f2f9d9360L,0xfb1a8651b499e3ceL,0x80b953fbf2dbcaaaL, + 0x312cc566973b06b6L,0x3534d9c33af36c64L,0xe4463a5210ffd815L, + 0x57ea2b4bf18c2b91L }, + { 0x00f5e1628aa0f2f2L,0x8c7e75c50e46bcaaL,0x97ab479aa4a2c42dL, + 0xb4f308ea14baa202L,0xa901bd146943cc2eL,0xbb125feeeed58804L, + 0x6502c8f99d180f7cL,0xe53539191580c61cL,0x7e27806927101ee3L, + 0x7a0a40a1faa72717L,0x32edce024c75b153L,0xda23660b538f1c22L, + 0x4d511e98be307d2eL,0x24276e409baee0b4L,0xa78c39277ff1f307L, + 0x60480b46ea7935c9L } }, + /* 81 */ + { { 0x31087d663872ece3L,0x5f29be7d955b70f8L,0xb50b4fc79cf95bb8L, + 0xbae3b58ddbffa621L,0x0e61d280e022ba5dL,0x78ae51174181449cL, + 0x0b132840cf555485L,0x800ed1b6b8ce0b0eL,0x35dffdd578d5de3dL, + 0xf7e4237469a56b47L,0xd5e323698d910ae7L,0xb6ff52a06313c7c7L, + 0x5a2fe20da92de9e5L,0x41b347d3d12110bbL,0xc5905edb40c16f23L, + 0x0774a0d39a8f88ccL }, + { 0x3ae181abe3b6c106L,0x4ebe163f8de150b7L,0xcf75b82f6f354836L, + 0xaa0d20633ac7ac16L,0x5c680668291722afL,0x73941e6111545553L, + 0x17127e38bf5de3f7L,0x32cfdf031afb41daL,0xc6893c9187bc8663L, + 0x75046744a62c9c99L,0x96866e2d962c1947L,0x489ec8df378cdf4cL, + 0x3a60709b3407fa32L,0xd37d2159551290d1L,0x9623d303bab92273L, + 0x081519542432014bL } }, + /* 82 */ + { { 0xf9236d89fb7b2108L,0x3ecc83ccad75f9aaL,0xf7c72b15b4e1da11L, + 0x552aeaef0315c362L,0x11e140edf272fe3fL,0x99d79bf687843ee8L, + 0xce6b54fd1d9bb25bL,0xb20b0e215b1bad74L,0x54a0214f5b84c90dL, + 0x459bbf52fca6cec9L,0xe363c48d9e4df76fL,0x3045f84ed64cf17eL, + 0x8402a167f62ada48L,0x2c9e1bf36a74ca01L,0xe8cf9d41f691c42dL, + 0x5abf2178c2c4b874L }, + { 0x4777966bf3b3bccdL,0x0047e0f0be3e0caaL,0xcb8383b38c7d5043L, + 0xe77e3baf946fd5fcL,0x79baa785e9ec0e87L,0xd83c557cc8a18d25L, + 0x9b96e5af25befcfeL,0x4f05d15e98c71b61L,0x081f991a77e62da1L, + 0x1c6ec781cbaa3821L,0x7522f65de54d9bfbL,0xf5d0557344ed1430L, + 0x3035b31f95cafddaL,0x47e67f436378f5bfL,0x029f7cad5270b9d9L, + 0x15ad15874d916a48L } }, + /* 83 */ + { { 0x00de2eceaa588ae4L,0x552ebc58a371a232L,0xd00ea93471230444L, + 0xafbfa67de4b1832dL,0x29216341b689e843L,0x1f96bbbd61f4e2e8L, + 0x9542068404c29dc5L,0xc7fe382742317fd1L,0xe0a0aec663483162L, + 0xfc2b94d10700184fL,0x07219973fe1fbd85L,0x648b6ab1fb074352L, + 0x23bbdaadc46e5392L,0x0db8dd1f00fa56ffL,0x104815eb866725f6L, + 0x3f9c4cca52e81963L }, + { 0xff36b29732ce637eL,0x81a15f2df5d25cddL,0x1a1d052d8b02ad97L, + 0x2e5f3bbccfbab3e9L,0x60d2cbd7614eeb75L,0xd4491843cd5a793aL, + 0x2242cf75cdba2144L,0xa20705e788b99766L,0x64e12cc0ec77e132L, + 0xb1c14df6b61a9b05L,0x8fd97f0474825b5aL,0x956048213da31223L, + 0xde4867274d30c70dL,0xbcab8f151c12ee69L,0x5dc638b4668d893dL, + 0x6479dad6223f574bL } }, + /* 84 */ + { { 0x569044f3b05f2b26L,0xb35a294a80b9f76cL,0x8839fe284290f6aeL, + 0x761cfb23026a5877L,0x768926b62e5ff9c3L,0xbae6cd200b11c576L, + 0xdc85775672a03efeL,0x0cae074ae1bad63aL,0x3fe491a1d709d99cL, + 0x76c5ded66501d9c1L,0x1da6eca1c32aeff7L,0x50849d55c57683e8L, + 0x9e392e9cdf98d847L,0xfad7982f64d9a564L,0xf7c3bdb7a37b98b2L, + 0x1fe09f94f0860497L }, + { 0x49a7eaae7648cc63L,0x13ea251167cfa714L,0xfc8b923c653f4559L, + 0xd957619b81a16e86L,0x0c7e804b3c864674L,0xfc88134a1616599aL, + 0x366ea9690a652328L,0x415329604bc9029eL,0xef9e1994ae2aad2bL, + 0x9e2a8c527f10bef5L,0x73dcb586c67bf860L,0xf61a43fa844cc25dL, + 0xd74e7eea74eb3653L,0xf3356706dd240f02L,0xeec7694cfd83bcb4L, + 0x4de95786db62526aL } }, + /* 85 */ + { { 0x4867d3153deac2f7L,0xa084778ab61d9a8eL,0xf3b76f960ab7b2d5L, + 0x00b30056cfdf4f79L,0xd0701e1531ab8f4bL,0x07f948d59c779d01L, + 0x7c994ebc82675371L,0x1104d4ee48bad4c0L,0x798ce0b5bfc9d058L, + 0xc7ca898d309fa80bL,0x0244f225acb33eafL,0xd51e8dfc5b2f3175L, + 0x3e49ba6ba4d7be34L,0x1760f4c7bda02b43L,0x37e36a7e4435275aL, + 0x1c94418be636980cL }, + { 0x43a2131309dc1414L,0x060765fc43c93537L,0x6ff3207adf5f79ceL, + 0x6f18b1fa85d4cfcaL,0xf5c4272e63e995abL,0x121a09e4a82b3002L, + 0x82b65d1b97147f16L,0x4993c20c20a7fe26L,0x99c9cb98e6716726L, + 0x5a02d673feb440a0L,0x3f3fa9e1251b4bc5L,0x75dbc474a05338eaL, + 0x3cb4044b7b09f6cbL,0x6767da1880434609L,0x97851422098ceac2L, + 0x611bfbb2b55235baL } }, + /* 86 */ + { { 0xbdbaa55ef00ad2a1L,0x29efa85e14a290d7L,0x3b4a4768e92b1694L, + 0x67111bcd11ec8130L,0x0e42570288bd27b2L,0xf28cf2a3d9a03c06L, + 0xbb7c8d2df318884aL,0xe2ea1462e3aaeb20L,0x3353580443b85d77L, + 0x81ee4482554ee9bdL,0xeb2eee9ee6aa198fL,0x7a5aa804c26c5944L, + 0xa0ef2da582ab167cL,0x5a2ab47602fe21a5L,0x169cb3b83370298eL, + 0x86e6c5440eb3aa8dL }, + { 0xede033210b793d9bL,0xf79fade11ddb5eceL,0xf73fda9268930b64L, + 0x06aad97dfe4fd1b2L,0x073a5b1d92a4dc88L,0x8af8cbd8bc976d75L, + 0x60b4abb163ce26c0L,0x9c8300a9dcb1fb06L,0x335a594cda95b3d3L, + 0x1f97d7d4b37eac87L,0xa3d2eba220eefaabL,0x3258c906f3e828c8L, + 0xc832616f85ab7781L,0x725971928c28b617L,0xcd7196bc3233b82dL, + 0x83867eb919fa126dL } }, + /* 87 */ + { { 0x774fe73e22474edbL,0x2a7663941a84e1aeL,0x270329ad9c6dd6e3L, + 0x00c4a41514f8bf5dL,0x3ce2ea37d2267b90L,0x1275301511d24faeL, + 0x7c14d854263a1b78L,0x20c8401b1ae0b206L,0xf32a011b081f49fcL, + 0x1e8123fb959c6df8L,0xa328dc7c800e1d06L,0x5876a37824259a9aL, + 0x23ada8b5b7ef6c37L,0x023f6b6ea93d4c9fL,0x89f5414dffb6389fL, + 0x4b26bba2e628b39eL }, + { 0xd30b1cb45d318454L,0x123b749fd7436cb6L,0x3110c726568a7461L, + 0xc85de1231c84fd1eL,0xa5f8d6e608403d55L,0x395b6e139b1fabf8L, + 0xfe6d68c33cfedce0L,0x1d90381f94b91110L,0xf0a8ea812dcc6eb7L, + 0x59e804137e90ca2bL,0xbeb5fc07c8a25c5aL,0x009c253a5d84663cL, + 0x00b15073910b6a7cL,0x8607da4c4108f8d5L,0x02c3d9c3cb901e65L, + 0x4d697bc52c9615c6L } }, + /* 88 */ + { { 0xe0db1ef0efa8fb40L,0x29021c5b5ba3989cL,0xa8d6fb15809d19dfL, + 0x6b787b734c1219e1L,0x6417e16814ef05e2L,0x449342db8f9796e2L, + 0x2f878a5ebf84421bL,0xe71916d7e94a4536L,0x9818bba3ae119693L, + 0xec674be95768804eL,0x0a26074cf8424f8aL,0xdbc93b9d466ce6abL, + 0xb3f15a98c920078bL,0x9d10fd0d3870f1a3L,0xa61241d9e4e785a7L, + 0x76ca87a1e6c8cd80L }, + { 0x4357fb56e02e48b7L,0xfbd14b13cc09e9c6L,0xdb5f243524069cf0L, + 0xf878165c2c3b01a9L,0xe549e7c4e6956dadL,0xf2fe9538bbd60b68L, + 0x952f856b059dc653L,0xd3f60225b377fe9bL,0x6a0c7328bfe908c4L, + 0xce6aa2d3bc8f5f2dL,0xf721344324425050L,0x17e1266a3d3b3ce5L, + 0x75b5e43fc1677512L,0x1592706237fb894aL,0x152607532be3e375L, + 0x27e7f2c66da3b7beL } }, + /* 89 */ + { { 0x638f65ade6a15883L,0xd4a7e68c66afdb33L,0x6207b6abd3f12de5L, + 0x1c6ff95037b87810L,0xc0d44cb264acf6d3L,0x163ac601f2be78c2L, + 0x1c63cc5a1636980eL,0x3e92cfe895c9349bL,0x7738e0d841ec7220L, + 0x6169d7642d5fa961L,0x2aa776c1c3e028e9L,0x93dc5646b16d5409L, + 0xa0b27fb5706df4d9L,0x9e991170ce9c6b97L,0xea8e42be53c85f40L, + 0x02e9643783246528L }, + { 0x91540addae78ea1fL,0x51a1b74d7b670e96L,0xf9936441f7006826L, + 0x8f97d6ea7d7520c7L,0x0faa6a0269ce12e1L,0x2590aca879208342L, + 0x7a48386375614436L,0x07c6149ef381408fL,0x733bf584d7853406L, + 0x8761b0109abbb6f7L,0xe4eb249ff528a09aL,0x08781ed82e00ae3cL, + 0x864c1b252178effaL,0xcc1e62a29d513a7eL,0xedb8b94e1919062fL, + 0x739f53da4f16527dL } }, + /* 90 */ + { { 0x7a5f4a88924adc5fL,0x95646c16a818f56dL,0x0ec491297795f954L, + 0x2b48753dd19c5400L,0x16fa236b205912b4L,0x6b3d65f3e87a4946L, + 0xa7174a01045fd066L,0xb635031312a5e140L,0xa79c4b44a96b8623L, + 0x7a339d659ab003d5L,0xc72f30c63826f31aL,0xb4e7390c6f7090cdL, + 0x59ac6c36906ebe24L,0x39a7f06dbba4505aL,0x839991e1c58c413aL, + 0x020c23ffa20e0e84L }, + { 0x120e4adaafc74661L,0x37bbcf63277fc065L,0x41049cf6b6dce799L, + 0x5b8d6b537b161ba1L,0x22218431a9610fb2L,0xde9ec9d1dfdde769L, + 0xd32bfa4d42d80630L,0x3885702a6244df4bL,0xcdedd1ed45592dfbL, + 0x0e1df45bfb4e01b8L,0x8f4bded286e215b0L,0x809354876a937e6aL, + 0x415278ba8130f723L,0xc6dc469238a821f8L,0x2207b119fd8b4f8aL, + 0x76e7bf53f9269cefL } }, + /* 91 */ + { { 0x5f12842827ebd187L,0x8d3320abb65aadbbL,0xb042765a72258695L, + 0xda3f33f98f0986abL,0x411807a7aebff503L,0x25c776ca825f71a5L, + 0xc0de7bedff7df24bL,0xda8b0f42165f1fb4L,0x5f3ff737731f3ae3L, + 0x4cd1d7e7193e0a52L,0x8df84aa3b6b3ba46L,0xba84b897aa1f3782L, + 0x6e7960cce7733ac7L,0x4d46d6ab50981a21L,0x1ec12c257cbb80edL, + 0x79e7ad272b96ef09L }, + { 0x3cd970dc8f30caaeL,0x85cabcf10a6ebef4L,0x63c1863ec714616dL, + 0x1c50db0b519e3a98L,0xf39b896364cb13d6L,0xdf67d81f22547b69L, + 0x7157abb9d67db0ccL,0xccca25ba889491b7L,0xf689207c7a27e0dcL, + 0x34ae8fbe0fd43281L,0xa5d91f735720ec09L,0xb2f61909cdfd7bedL, + 0x1ec102324a039e32L,0xd3c3d65edb0d8fdcL,0x32c916c84fe5005dL, + 0x7f8c37ac4c0bea94L } }, + /* 92 */ + { { 0x33ec1e5443ac05e5L,0xda4a4da4cd8d3825L,0x86d88c0b88bf9e2bL, + 0x34d71dd0b53811dcL,0x655040d2a3c3aba4L,0x2bc40949b61611beL, + 0x1c2d426e279a4fa0L,0x535a5aa23b065ac3L,0xdaa8a32fc52ea890L, + 0x5a5deca79fddad22L,0x911f05fd2ab3b26fL,0x5dace7dbf37cd81eL, + 0x0e0e44e790d16b8cL,0x15e68aede4f5894eL,0xafe04999fc92a74fL, + 0x1d7703aa970e7c2fL }, + { 0xa8a4c81d3f0062a9L,0xe31eb2b8d96a20baL,0x66dd98df864bd101L, + 0xba05f5924413b614L,0x51a67a0de9a555f8L,0xacc2f0972e4b52d1L, + 0xab5daaec7184ab23L,0xce08b43e7c7f691bL,0x520e530b76c427f4L, + 0x7d352069e423ebdcL,0x6b5e39e834df14ceL,0x3dcbf295446305acL, + 0x682cb2e1fe34cdc1L,0xd4ac45d1111f5afbL,0xc5ef63cd47f296f9L, + 0x0a2c40ec93c20871L } }, + /* 93 */ + { { 0x09bc384faf5747dbL,0x3bad6086c06ab86bL,0xa406882e9e7c1547L, + 0x2d5326d155977abfL,0x063a9a05da81deb0L,0x9a86e4a7524b6111L, + 0x1402f87a4ab2eb90L,0x7d0721d4d5c600baL,0x1a2fd9a9f289fdbfL, + 0xf5dce66decde6f07L,0x62171277dab9fa73L,0x6d2dc49f6c474babL, + 0xdc017e1f76eed033L,0xb97175c04da825d3L,0x6c297e3d54b05e43L, + 0x2efb454656c9c87eL }, + { 0xa4712b008b21c064L,0xd186fe424a70629eL,0x6435b3409b74f0afL, + 0x6965aa437ec9e629L,0xdda14673c4c60d08L,0x0b656670bf3057aaL, + 0x7f05e8403ce86f60L,0xc05073a904401a16L,0x16b1e638294e607eL, + 0x2078325269cf7046L,0x2941141be8ce7d3aL,0xd38ad8d37577053dL, + 0xdba68fb3caa6630dL,0xecbeaff1e9504350L,0x9f5166d51d2d760bL, + 0x337532ce462891e4L } }, + /* 94 */ + { { 0x3f1118533a00bb9bL,0x2d2ffbae45f66685L,0x9ae11a85d4aee24dL, + 0x18ba1e1b0341856eL,0xa9ac81782731349fL,0xc13dfd4a545715b5L, + 0xa5f7423c5daad2eaL,0x30a483b9535b76a7L,0x92e9ada4ff873e9bL, + 0x15662d84723a1055L,0xb935497b8edac4e0L,0x61b6441a39d8fa70L, + 0x1541d75640d1589fL,0x62994237f0a05f0aL,0xfd8b00346bb28908L, + 0x192a2b5dd4cd32bfL }, + { 0x63576628365ced07L,0x029f32fb05de1d1fL,0x6d17b9bcbf40a7aaL, + 0x1b1b2a089bb50a47L,0x9389abbb795a6278L,0x52cff60fb34fc19bL, + 0xf3ab9492387d8739L,0xa8f053e66920ccd6L,0x3ef2dd4b63a9b4f0L, + 0x9ab0ede151e82129L,0xafba0c0b0838bfa1L,0x2bd5a7ac9ffc11beL, + 0x058bfd9595cc0878L,0x686d48a3f8c2f0c6L,0xc33abaaf1d9b31baL, + 0x632e22893bc0c268L } }, + /* 95 */ + { { 0x1c851d2015a1cccaL,0x4efe290c7e522bc3L,0x0b741d5518eab053L, + 0xae656197bc85e217L,0xae13141e01cf8b29L,0x2e2cb59366948478L, + 0xeb57bb0fc31bd8aeL,0xdecef5d6c264e788L,0x6fa856cc9cb96d86L, + 0x2db16813279183daL,0xf03f3820383d796aL,0x58a456ff1d0c6fedL, + 0x255898058a6abd9bL,0x339f52c583f96f19L,0xcf6ded8fda7e9ea7L, + 0x68c3d9c15d1ccd45L }, + { 0x67e26265e6b392b7L,0xcec1d9bf775d9509L,0xe16abcd4d76514f7L, + 0xd86f59b20de72e1cL,0xa66e43cd1adfb033L,0xdb34434005e457ccL, + 0xb67a79165681daa2L,0xc32e7babf0114731L,0x066fe16ed3b1e961L, + 0x924e298ef63d26e6L,0x9bea0dd8541add6dL,0xef9500df9982f971L, + 0x5c876e63c5f076acL,0x55e12ae5b23d396bL,0x09efbb362ec6747aL, + 0x8f2055ee233286a5L } }, + /* 96 */ + { { 0x4a4ab9e3b82c1af0L,0xfc65e9e7f2cae264L,0x4feaac0a60187d46L, + 0x27d3f335e393b363L,0x9c9f7c00819bacceL,0x3f7418b5b8aa6611L, + 0xffa94557372aae95L,0x937d78048db38589L,0xd10c86df6f1fbc1cL, + 0x48aebd89a2f0a0ceL,0xae5d5fa2367439ebL,0x103a6a0b3f17d2d8L, + 0xf233f68a411d9894L,0x7fece8b3218b67a2L,0x0422540f2319bf06L, + 0x1292c8c9340d322eL }, + { 0xf5eb55870386463dL,0xd4bbc2b20371d97fL,0x1b3645710b819c5aL, + 0x0cbb42d6cf04ad41L,0x5d819c7666939ec1L,0x8745ac13a01847e7L, + 0x4f704b021c7232e4L,0x2c9e58a0acb05780L,0x9523b8b3b561e295L, + 0x3384df0079f9ba35L,0x78231fc21eaa9628L,0xa2eac54f8aea2b90L, + 0x8075ed7730d1c263L,0xacb44ed5fb339000L,0x92546ac2f011293aL, + 0x7c78762beb821764L } }, + /* 97 */ + { { 0xb8f7d6fb067902b6L,0xb2823a43d1735980L,0x062cfb1259741dddL, + 0x6e391b074033f95cL,0x3831d0a368589b8cL,0xe3474d49522290f2L, + 0x4dab14d6222e1f3aL,0x8f00fcde53f08d39L,0x559917ae707f28f5L, + 0x166aa0ba068e607cL,0x602713e7d7e1f824L,0x7c2555404d6a328fL, + 0x0d2e32649890cd2aL,0xf2207944eca0b20aL,0x5c98dc0752f4e09cL, + 0x69403504d84de81dL }, + { 0xf8b7b366e5407206L,0x1ecf54cf0d88fa8cL,0x6fefe548f7272e6fL, + 0xd653137281ab4468L,0x52cb5f0e4e474408L,0x9e426b3a6490737fL, + 0x2576c19b4980d071L,0x91f346280f272cafL,0x78e60a4f468f31c9L, + 0x8776a32990844d89L,0x8a55700cb951582bL,0xab1af36514b1adbfL, + 0x22ebff92fbd343efL,0x32f9fb01b7d81f34L,0xad850e06ba6b30e1L, + 0x6da9e027bc5f9546L } }, + /* 98 */ + { { 0x21eee4c25c9490ceL,0xa96ec4a30df68381L,0xe6c607e0a4a9368eL, + 0xd8b0492a4bc262f3L,0x0846a210460c34ffL,0xf7ff7a6428df33cdL, + 0x10c5504421827612L,0x9d25fce9149bcd01L,0x725611cdcfc613dcL, + 0x159f7e8897f51ce5L,0x3fa3bf314e8c08b5L,0xea15611575e7538fL, + 0xd1e0a95191c84020L,0x0d2268bacf02ad0aL,0xa04c6ac4058b8e5fL, + 0x773b40b9b3515912L }, + { 0x00ff2cdc3631cfd2L,0x14c4c2d3807737bcL,0xd600616a338a5270L, + 0xd0e3306db32cabdeL,0x336738eaa70b17caL,0xf2f4aa8d79f353eeL, + 0x712f6ad9576f3ad3L,0xe427985289b2bce0L,0x05d8f94dda92ca30L, + 0x9891d475d8492dd9L,0x3e06a5ca4d15e4bdL,0x4725d4eb254eabbdL, + 0x31394acec0ed513cL,0x7e0f9859bbfaae6cL,0xdc125546833fd137L, + 0x12b46385c56c4f75L } }, + /* 99 */ + { { 0x810dbebd932951deL,0x96959d425aa69c94L,0x5fc49c04ecb2f08dL, + 0xac74f0cc2250b82cL,0x96a439a53aec4e1dL,0xc33cab9a90499acdL, + 0x2fccde6654d9b3afL,0xf4af285c3863ae8bL,0x2373373e46febf88L, + 0x751d672c3c9ab7edL,0xc1c51130fe12020cL,0xad82402f52f3e56eL, + 0x3489ab7aa4a64a81L,0x0a1fb661d9f163f2L,0x17c69be10e553317L, + 0x61c1935e7d88d417L }, + { 0x2e722d9b3492ae43L,0x1ef89d950538f05aL,0xae77e588200aab63L, + 0x2872c120eba4b117L,0x5c2432c83a461cb8L,0x315b3434cb938f26L, + 0x05bf2ac58c4c7dc0L,0xd2e501dd596b378dL,0xa8506c9fcb890c30L, + 0x3d0af4617c361f0cL,0x21f7b7185a35cbaeL,0xbd1035f1f3fc0138L, + 0x74628af58b248edfL,0x8d6421d048c9cae0L,0x75e3da392ca18773L, + 0x27ad0df271d3db94L } }, + /* 100 */ + { { 0x9e3bda79305b5aedL,0x2c67d4a45998d6a7L,0xc855e1d30f7eb700L, + 0xc18a7e9e147d1c44L,0x3ea99618c89540edL,0xa53be20a7e6bfd20L, + 0xc9487e64ecc14437L,0x7297920734ef85c6L,0xfa0d4e71d5e1ebd5L, + 0xfda2b1e64d48d6b6L,0x782a1e0566e200d4L,0x2a3c70da5a5366a1L, + 0xfe3fbd2b1a473738L,0xd7ef8c067fe020e8L,0xec686fdeeacfb665L, + 0x5d9b5e276dd1542fL }, + { 0x3637c5a5cb3e472eL,0x2153d92730a1405eL,0x009992e5b4498558L, + 0x18f00ccdf39a0851L,0x26237c11b5c6c560L,0x418ed4081343540eL, + 0xfef7cbf07e7f3184L,0xecd92366bf48576bL,0x1b75be1abc94c91aL, + 0x8e1778de4a162276L,0xc52e57d3c5c6bcb8L,0x5cc382c75ab71858L, + 0xe12c2c283f6e39f9L,0x4c7e0ef2d62735fcL,0xe071deb1835a5996L, + 0x24f891cdcbb8c766L } }, + /* 101 */ + { { 0x24ef60bf6778c1e2L,0xff49c03d00d5be5cL,0xec11986e2f01a09fL, + 0x59a728a4ae096e58L,0xaabbcedb7077984cL,0xfb473bd2870ca5a5L, + 0x8c928c614de30e3dL,0x3fae7f9a4f67abcaL,0x83c2b2ebec21a9cfL, + 0xafa70d629cd9b5deL,0xadeaea59c60b18dfL,0xd5fef7be4049b54cL, + 0xfceebc766dd310e3L,0x7748efe38f6321ccL,0xfe9c32b118ee8af5L, + 0x863ac3cfd42df612L }, + { 0x0a36fca7b85a2fe2L,0xf3e70d08ee429dc6L,0x8c9ba209141c3944L, + 0x306a810667272a0aL,0xe69a1555f968bd06L,0xb86f7e47153c603dL, + 0x9706614aef56e4faL,0xc0dc36b898780b4cL,0x43657fe23a1d3263L, + 0x01f97a86435522c9L,0xd91897f6edfef679L,0xebbe31d46daa17a0L, + 0x6f17910085accfbdL,0xe0da6e328f9fc1deL,0x1c9d53dbe1e7142cL, + 0x3e3f1b1e8b86725aL } }, + /* 102 */ + { { 0xb7ea15c07b7fbf05L,0x992f11b61f1a3882L,0xc9ddd95ad1dcd1bcL, + 0x31f5b7faad0f7e8bL,0x2936e5ebfca7ab79L,0x30f417dc19a55be6L, + 0x1f6f4e4343cde554L,0x971f5e6582f044bfL,0x73c3b8e44288c408L, + 0x61aac59fb807f575L,0xa64ee2dd818b58f0L,0x6f7a0a6097a3b0d3L, + 0x8b85ecc80394b058L,0x9a059474bfb3517dL,0x89ad5977a79c3f06L, + 0x81208ed8700a8025L }, + { 0x1093509914c4ce37L,0xf34bb843a1aa48a6L,0x86007024580d58e8L, + 0x6db42c49b375b8baL,0xac365524ed3bde83L,0x5521e1b4649233b6L, + 0xbc7cc5d564dd946fL,0x9c14b035bfb5b6aeL,0x7f22ba180146c1a3L, + 0x0b62fbbc872214f5L,0x3acfd7f7b4921764L,0x5ff10da1cb4d6df1L, + 0x660e262062600a91L,0x7ac7da9d81d9167fL,0x6e8e260cb6e7a199L, + 0x44383fb880deb3c2L } }, + /* 103 */ + { { 0xe107f01de44f9af6L,0x36381a4d8cb1fa1cL,0xe65be3ecfb7dd493L, + 0xd0b8435a26a8839fL,0xee60f9153ec789d8L,0xe25fea502bcc5e1fL, + 0x0477c0c57e44a81cL,0x349e9f83230ba5b8L,0xdd42f32fde180dd9L, + 0x8b039eaf64a3d11cL,0x80ef884ebeb7083aL,0x288e60c4f12742cbL, + 0x44156cc5720a0262L,0xcd547de67253b77fL,0x9829a6eca6013a59L, + 0x8aee708f0d548445L }, + { 0x18f22d9c32c54409L,0xa9ebfa4675ebaac4L,0x90e2e92886284981L, + 0xd0201f6f6b3a8e0cL,0xc973016cbd77641eL,0xf926f2f070170575L, + 0x4984048ffec0ce01L,0xbf696211f319d304L,0x74b5c844c91a88c4L, + 0x4c40fbcee0030a82L,0xbed67525e4f6d521L,0xaf7e47cc29d67d1eL, + 0xfa307db8c21d3536L,0x56b6c46abbb29405L,0xf059a7e3033e805fL, + 0x970f61fe6096a5a0L } }, + /* 104 */ + { { 0x1bc53d231bec8e4aL,0x8809ac1435a6034cL,0x4ee081da509e464dL, + 0x496ae1fd8a488235L,0xa1ae9863325864b6L,0xbaca13e974cd069fL, + 0x3738cc58b1d8a6b4L,0x5fa71f58e76b9da4L,0xc919be88c7eb16fbL, + 0xf5c8f13fad4e429dL,0x4583b6712499f9edL,0xbce20115a10d8bd7L, + 0xf66d76055790bb7eL,0x9316aede482b78ddL,0xe0d8fb2d75f855faL, + 0x404b5b945a7dcca7L }, + { 0xf9ee682a517a15c7L,0xaae4cfbcef880202L,0xcee2c1395106a354L, + 0x5de60192170febe7L,0x589e39fd73d0c54bL,0x195c71358c9092b7L, + 0xcb7ed53f0a7bfe5fL,0x2bd9242af61cc979L,0x8d2ef16c5395f7d9L, + 0x0d4ac1ca70b32f09L,0xa587526d52d185c1L,0x2932b04a942d6195L, + 0xfe25a979a500b0acL,0x5fa1f4ae562fd230L,0x60f55af220da253cL, + 0x7faa11b583146002L } }, + /* 105 */ + { { 0xb0ba4f0c6e402149L,0x3584cc1d963cc119L,0x7740dc1aa6527476L, + 0x3f77ff75c95715f2L,0xb2f234ad3f89fb0eL,0x55159032ef9be3ffL, + 0xfc9fb21d04237e82L,0xeb2eff38a153ed93L,0x89d53ae010041d13L, + 0xcf2e545b7f1bd828L,0xdd4a27ce43953ea5L,0x00d2e5d4d85e75c8L, + 0xeb93ed62241be1c3L,0x1e53f25f0242032dL,0xb9957636c3a4e701L, + 0x14b63a52ed98febfL }, + { 0x7610b55371c43336L,0x19dfd4a623a4824bL,0x7b97a2e00286051bL, + 0x86abbb9c8f5f1edbL,0x67a57d779b67daadL,0x8ace506dcd5ffafbL, + 0x85da9f9589ac3c63L,0x081cbaa875a3d150L,0x03353d8fe9346ed2L, + 0xb2ab61f1a1f9a02dL,0xb0cb09373a659c71L,0xb7e0e30b4f5df8a1L, + 0x77c4c741eb7d5a1dL,0x8f046c9c728e5cf0L,0x32dd0bc7f7c171acL, + 0x02485873836d2655L } }, + /* 106 */ + { { 0xcd40dd2375a4cd8dL,0x132ca43397bcba78L,0x30c5cd84258d61f5L, + 0x0a7ec059da1e8e68L,0x07a8f1711d65d40aL,0x869e655ef4350d76L, + 0xb98ce6f05983ae42L,0x7b61391d9d8bebd0L,0x3a529e25b1ba5d49L, + 0x46f732e91f6b2cf6L,0xbd66ec6a3fa3b629L,0x397950ecc3ef0ed2L, + 0xee9008cb5f08b476L,0xfd6be425965a0e2eL,0x78ed513c1177bc87L, + 0x6798cedffe512daeL }, + { 0x49e3f8fd1b97c5c6L,0x39fbab3e78c3b33fL,0x4427441240f595baL, + 0x174225b95d7d4376L,0x880b3fcc79c44777L,0xdc3aca833296b245L, + 0x55913df71734e184L,0xa4db23d39c934472L,0xcebb3733d1420a11L, + 0xb9d20cf9f3608bdcL,0xa618acf630cfe13fL,0x75f06b315f30874cL, + 0x506efe7f9f0005a5L,0x8aaea78c01bfc9dbL,0xf9179255f78e7c41L, + 0x3ea7aed252e96395L } }, + /* 107 */ + { { 0x98617e045b06ae25L,0xbcac148dcb5750efL,0x91ea2f0e604c2ba2L, + 0x00c19f6b76b78975L,0x79b9b6d0651da181L,0xf3225bebc945705bL, + 0x30b435f35c005bf1L,0x440b4482bc24d86dL,0x2b8f0996d6373777L, + 0x65fd6c561c44b4dcL,0xe9405ee630906999L,0x19ff092408aa1ec1L, + 0xeef3246a3d2f2895L,0x016c3765bc746797L,0x62d2569fd0705f7eL, + 0x6a8ad39c05250044L }, + { 0xe45f020d46be7282L,0x9405afed21380f12L,0x4cdca5bdd5da6ad0L, + 0xc2d6f1847f8be61eL,0x20132953596b8178L,0x8d3b1e7b7a8df954L, + 0x757c61bb39572b4dL,0xd749b57b80cc3b56L,0x9590ff9337b3ffecL, + 0x39bbb653145dc94dL,0x70c1c6062335e573L,0x9c2e72d7f763febaL, + 0x4768e424cc61b732L,0x777d2fa6aa73f2caL,0xdee4dbaac5cb58cdL, + 0x1a1811799cfae1aaL } }, + /* 108 */ + { { 0x6f6ff62f77575ed0L,0x18f14fa97d1da99bL,0x2e72aefb69efd7f6L, + 0xc45ab4cbddc28633L,0xb0e20d48586c5834L,0xd397011a39775dd8L, + 0x0130c808f4134498L,0x2d408ebaf5115ed8L,0xc506a05c0260ded9L, + 0x9e5b736219cab911L,0x4cf508c6e8693a86L,0x4e71245fcc773617L, + 0x2f71aa1f95d89ca3L,0x4bba7c6a607bbc98L,0xf3a515e7212b7fd2L, + 0x7d2ddc759230f5a8L }, + { 0x3d05816d4ed2cae8L,0x4cf6bc7db9c00377L,0xc23e98e6646b08d4L, + 0xf9ee6c614b9c0180L,0xe11c9a13ef9179c1L,0xa5b6147e8ed9688aL, + 0x7afeb648d06670a7L,0xd670333c17685275L,0xa89dd96975f9e8f2L, + 0xbb57228d37a68adeL,0x21a05d5e454cb186L,0x4810158f063dd550L, + 0x92dd4f084cb6caf3L,0x70c4d8527854abe7L,0x845969dc6e729d76L, + 0x5a52f87ab1bf40baL } }, + /* 109 */ + { { 0xed019e9109ecacbdL,0x6544023d7b89bdeaL,0x7cc51f0b5707371eL, + 0x14832b0416c8e217L,0xb1aa668281259ab5L,0x6e100f9223e361d4L, + 0xe593eee9e3a95c2aL,0x699b6bbd16c10e26L,0xad4878739473a13fL, + 0xf1c14dc5b274987cL,0x57dc00752559e2e9L,0x8449849dc3d47ad2L, + 0x83df278add527793L,0x770e3ec8eefd5b99L,0x2ae5844676bd02a0L, + 0x17f027643e705ffeL }, + { 0xdda4010d29abea1fL,0x636b96952407ac4cL,0x96a601290433218bL, + 0xf221fc3b163d534aL,0x05ba15beccc20565L,0x1238e54d96285577L, + 0x1b144257878804d3L,0x96fbf304a89a9fe4L,0xc8a7f06c4be642b1L, + 0xdd1a20e86e2b085eL,0x8f7f27c2ff4a591dL,0xc17b0753a4a343b8L, + 0x684b1e88bb173d4dL,0x3accea443dc07bbeL,0xdb15c88d4c441d77L, + 0x0ef0309a53e5957eL } }, + /* 110 */ + { { 0x4fc25721fa8e5b60L,0x646938ad691c0bb2L,0xe46d4b760b0a2248L, + 0x863f9ac27de16877L,0x503bb6ef2721c630L,0xf8c199df0b67fb02L, + 0x78c1ed72e07abd39L,0xcf9deb7bb32f0ddaL,0xaff726f06c3c89f3L, + 0xb7008b2d1972225aL,0x8f5a61174f145f5cL,0x4e0e6f8c457c4f37L, + 0x8bbdaa441c453c64L,0x57be326da6e92c80L,0xa9bc3fd95d773561L, + 0x3d3b6cc6bb37b72aL }, + { 0x6e6f12cc9722c880L,0x3a1b6ae7286b6889L,0xba1cc09bad2fafecL, + 0xad64ad7a43bb8befL,0xa5af6a0097c3f4c3L,0x2afcb0d9c353a91bL, + 0xca13fcab69ccbf6bL,0x699a1391f2abc190L,0x2dbd554223a247e5L, + 0xe206180f95488d9aL,0xba9e7bff1244cc3cL,0x29297abe87d3a365L, + 0x4054fa38fa4ca5e2L,0xb390623d67be1b6cL,0x1fa67c5778f41a44L, + 0x2e946e43c7b544e7L } }, + /* 111 */ + { { 0x2980fddfc60934aeL,0x2c3e7eff164206d1L,0xf75e7f96416ed75aL, + 0xfac60cf35cd0b2dcL,0xddc4bece1faad87bL,0x753fa87c9849e5ddL, + 0xc5d516a32c1bf1aeL,0x565dbea814732b4bL,0x007ebe3ace48696bL, + 0x40ca74d6cdb97694L,0x3f5cd27065e4e7beL,0x74847c013aac4ebcL, + 0x6762e03443d6c3a1L,0x690d8c95467a076aL,0x768d78d61eda677dL, + 0x0997ce550181d8c2L }, + { 0x9297746c965a0b81L,0x48b58be6e5e12dfaL,0x5573b3c4715f437fL, + 0xe425e907b565c459L,0x4f43f5121582797cL,0xe5dafa6f8ea5474fL, + 0x2aeb8fbe13de04acL,0xed7f95f0e8a07c83L,0x3e012a6e662c09feL, + 0xbf96e9b8c742cf17L,0x8ea5759ae28a1c45L,0x475941b45cf4e2f3L, + 0x7dd3c02df901a019L,0xe7a4deea70916b2eL,0x50b272b52fa9b988L, + 0x96f9f09fd0917fe6L } }, + /* 112 */ + { { 0x78e8aac42c310a96L,0x32a98303f7a2a734L,0xc46ca83d23962207L, + 0xad131e6ed9541280L,0x5791fc5e2cabe911L,0x50cb77eb841b6c68L, + 0xaff93dea3d3c8878L,0x06541f1df1007bceL,0x4ee729c255cdf1fdL, + 0xe0f71317323e3972L,0xa2de7a41ad4d08c1L,0xa9912abfa35e22bfL, + 0xa050122b89b03325L,0x8b9e51f406514d4eL,0x423c7aad79d3e0abL, + 0x71998e2640b8fea5L }, + { 0x40140fcdceb6ed78L,0x653cf37718534516L,0x0450b65ae8d60dccL, + 0xce6c1a769dac55f8L,0x8a96a92dae05686cL,0x2fe4476212712562L, + 0x747bcb50a4f39425L,0xf0ec6ff2fc531fc2L,0xc97c344710fe9ff0L, + 0xfb4887839c792cffL,0x552c5248026fb019L,0x4001a29cd804c290L, + 0x742b5ad835c8ca73L,0xc3781f176ee5dfa0L,0xca6b85f03dfa4ab1L, + 0x8389941a0b0d32acL } }, + /* 113 */ + { { 0xc0f062a2de067dffL,0xd4f32690bcb80162L,0x98cd990d0707a2bdL, + 0x5afc63b8fae4a391L,0x684f1b7bb32ad814L,0xb0a2dce2f199dfb1L, + 0x2260e17f48f25848L,0x7393db00c2d5e862L,0x9e88f854338cf171L, + 0x0067942902acf522L,0x19157cb86835af3dL,0x2faa6f92b8a2614cL, + 0x04ff95f5134ec46cL,0xcf00626efb7a8135L,0x454b3d05b37a4704L, + 0x1fbfda312694ec25L }, + { 0xfdebb657c8f69c77L,0x92a8278ba3df88faL,0x463b5571c1fb78b4L, + 0xd2066a1a11c71a33L,0x10c88143089958b0L,0xb975c7e0cf9d67a6L, + 0xdaa5d20873037b8fL,0x5ee5005d40bf5861L,0x300e6ce77dba69a9L, + 0x893c3cb3c962cc74L,0x0ac986294cf84055L,0x0a7ef63a225c9d70L, + 0xfe184869b91e47e8L,0x1b9d7deb8c2f84beL,0x67788915c0e278bfL, + 0x4f9488cac426f19eL } }, + /* 114 */ + { { 0x610dfcd4dd51b8ceL,0x0857927836230e80L,0xedc7ff1c36599562L, + 0x905ead4be2cae877L,0xa1c325d9e7967608L,0x3e39edddbd38926cL, + 0xda92c8685f6f0a4eL,0xe16f800af47a0fa4L,0x50b4db5be5f60aabL, + 0x3665412f983853d3L,0x64b622509b79789cL,0xea5600584e0e72b2L, + 0xabbd4901e555c2bbL,0x378419a717292e11L,0x6e0b5aaae174218fL, + 0x688e06848f796b92L }, + { 0xcdfef641313b8f64L,0xaef11b7b942c7462L,0x067cfb775c0d8abdL, + 0x608ea5f0af4041a9L,0x23d5bd826935210fL,0x5ab904fc27917a08L, + 0x85dbb1fe45d22d21L,0xc3d5e5094d36159fL,0xaebb528e1d39b8f2L, + 0xdd5ca828f44acef0L,0x24209adf20c57a54L,0x5742b43378f95f44L, + 0xd11fa7d9a9337d37L,0xd66a0c09c64cfdb7L,0x56e55b8f9bb817ecL, + 0x1723c7e3e4c41265L } }, + /* 115 */ + { { 0x9a6486d8dc8b43f3L,0xfc3e0e6126409e68L,0x1889c437d9b46003L, + 0x3a8503356284ec7bL,0x5a3665c46a9dbaeaL,0x7bf6941de978933cL, + 0x1ed5a51069341490L,0x664a7b7a8cb8002dL,0x603f76e460ed0a59L, + 0xc3e06ba31f4ebf27L,0x296ced41f2c38a7fL,0x2ac18f79cf1db08aL, + 0xc919e882cde7a3b6L,0x15e77d29dbf68b06L,0x21978baa4e947cb5L, + 0x84bf542b7630993aL }, + { 0xc1decda9e364f21eL,0x0d6cf345012e557eL,0xba246848588f90e1L, + 0x9f6dda4be3b104b8L,0x6bf7a346e3aef57aL,0x210299fee8327ea9L, + 0xaa99f487da95e6c7L,0x24ff813ed2cdf645L,0xd1dbb2d28bd414b8L, + 0x065101afcafa1a61L,0x7d9f4b9a9cdebda4L,0xaf41b395e41039e4L, + 0xe3e9e6bac50adf42L,0x4f2133ae341e9e49L,0x4968c0f3cb157f23L, + 0x383f827bda068153L } }, + /* 116 */ + { { 0x2ec46a216583ff4cL,0x4e645a294ad709e7L,0xdc66e9cfc04ca12aL, + 0x82f128f49160a7e5L,0xbfb227b1569c762eL,0xf80c7963c2edb8e7L, + 0xa7dafe0649a0f688L,0xb7e417542d14b8ccL,0x3a0c5c5386de40beL, + 0xf0d052861db79331L,0xb902ce69fbfe071bL,0x61e46956210e9903L, + 0xfaef874ef703ebb8L,0xf668947edd5f78b6L,0x6fe865475af5ea3aL, + 0x3b121f1543f94625L }, + { 0x5b26e847659275e9L,0x47581cfd6d0fce50L,0x55f5cbfd8aa3f1efL, + 0x1e7be315e484e60eL,0xd8f1a20ffe9698e4L,0x25d46da97ab04784L, + 0xa526db75834cdb3eL,0x1fd408d98d08a009L,0xfc004b205b5ca816L, + 0x5b3e3bb365e4bbe8L,0xf50cc125759bb6efL,0xf05fa817c2fac737L, + 0x9ee102d2d273951aL,0x2a8e540bfecb3367L,0x673446fb2a6a515fL, + 0x5505e1d137290c83L } }, + /* 117 */ + { { 0x0c3014a1d15e68a6L,0x6f9f0b2664dd35e5L,0x18c3742d03ad67f9L, + 0x74818c0ed2c14484L,0xc51811690d41a3cbL,0x65c8c83fc49f3e9eL, + 0x9b260c612c279386L,0xf6086faeced04e9cL,0xa7b2ccebfd7c4758L, + 0x4b3c313390297fd8L,0xca8264e809701ac8L,0x9f976a87508b3762L, + 0x5d582714983a8dfeL,0x350d2669d9d598e9L,0x85cb89cb0f6fd348L, + 0x617d80d4a574317cL }, + { 0x4cef267e70022b67L,0x80536bb53768b94aL,0x3153a566d2784462L, + 0x49054d4438243919L,0x8d11e1725df78c4aL,0x9b252a71d5a1e35aL, + 0x07866c808171e31dL,0x0a8501db1b38a00eL,0x2ed932b8ce770236L, + 0xa2d776098edaf7d0L,0x3aee5dabb93006e9L,0xfaffc8c4bbfeb036L, + 0x077b96784e21b38bL,0x491fc59fdca8e069L,0x3f624f550e938471L, + 0x5156f5087cd1780bL } }, + /* 118 */ + { { 0x58234e220206e8d0L,0xf5f6f5d47f15af32L,0xafab7289d638950fL, + 0x66ec4d097d4495f4L,0xad890c5d68da80a9L,0xe4aa092064f8a36bL, + 0x799e257e0f4d5c5fL,0x44c677ae24495e31L,0x720387b3a5b8e352L, + 0x703790f475a287b9L,0x54895cc5c3c1f2f7L,0xb8680f9b41a7fa41L, + 0xfcd47458b00b008bL,0x149cc838ba6473cbL,0x78ed5f7aac9be19aL, + 0x5254599cb33765baL }, + { 0x08739679a21b54c4L,0x029ece2ab6497d9dL,0xf14f1a92c8488640L, + 0xae48dcffe9fa79d9L,0x14b911c246c208dbL,0x5ab0fbf2dae3f69eL, + 0x180ac87ed1edb838L,0x146fd718188586bbL,0x210eb6545467cbd0L, + 0xaa2394081667cfeeL,0xdb125c1ab73d1a60L,0xde685300881c1cbeL, + 0xfe34c71337c30232L,0xc6c6070e6f3c8d18L,0x07e365bab4af4e83L, + 0x22f0a7eddcf82b45L } }, + /* 119 */ + { { 0xe262791fea7f1b7fL,0x9c3d8c5ddcff09d4L,0x86c2a9c339c7dc58L, + 0x4dad40174276e8c0L,0x0a918f59e9fe1d56L,0xb8d796702aa810c9L, + 0xeb7a88364aa5cdc4L,0xfc4c23bbe7afa72eL,0x4dbb5c9e4ac86908L, + 0x37e390136a0c7e6fL,0x855d700149c218d2L,0xe475bc6794b324a2L, + 0xc98a8dc66287a071L,0x395a299b5fb4323cL,0xe186c3ee0c0389e9L, + 0x79f81e6f16734c46L }, + { 0x83f2c1f3364f3c4eL,0x536b2ac51367e14bL,0x44a6dcfc5933e43dL, + 0x34e5947510d961feL,0x08234ece7e3f2aaeL,0xcb92e00abdea7f25L, + 0x1efba4f0a791a124L,0xc2086fd21192d53aL,0xfec0d0fcb51c8af6L, + 0x48d1b2cadc0f1b5fL,0xb07a388f812dbe19L,0x40873a6adedbdd45L, + 0xbc2a1268d702589aL,0xbbf6e3a817e27b64L,0x73ee56636d386e85L, + 0x442ecd379de7c000L } }, + /* 120 */ + { { 0xb4cd1ae68a2f90a6L,0xf277d41d6f5ad0ccL,0x6a3828c4401d4b8eL, + 0xe817a134d8376631L,0x142b758df5e1124bL,0x25fbc69dfd6b95e4L, + 0xa30c9f5fd74a9e3eL,0x5ac0f163d89663ceL,0x32a9eef70ce6386dL, + 0x7a690ea5d8ed5544L,0x5de23ff09889427aL,0x75ad36a5eaaced58L, + 0x3514a6c1d3e18465L,0x3d9162c37f093910L,0x5c10add9e33d56e8L, + 0x85176b7306aa691eL }, + { 0xa32110fa28a21e38L,0x97b6379d5773d538L,0xd3697bbf2d020dc4L, + 0x59177593961833cdL,0x6d7045fae5fa8516L,0x3390f29a786ab5d2L, + 0xac0bda30dc4f5b70L,0xcca0240adcc615c6L,0x8e1f1702c5146d91L, + 0xceb472d0a72cef87L,0x848407080b669ba1L,0x79b08f9d7e61aa0aL, + 0x388160be4669560bL,0x23935c2d948eb71eL,0xd7fd83c09431590cL, + 0x8ab154bb6e5768b3L } }, + /* 121 */ + { { 0x28686003353c4a96L,0x4e5c60e8905cd835L,0xbd5913648f66f8ccL, + 0xb6b80b989faccf9eL,0xbc1c1faee32639e5L,0x2f6396d2278aadebL, + 0x00a796d01898202dL,0x18ab548f3a474835L,0xacd056c3b31b0e3eL, + 0x15ba68dd0164512dL,0x203836d94b03f3bcL,0xd64eca6bd8f206c5L, + 0x931a361e9f1779b6L,0xd82690fc52ab34a8L,0x342bb8e092922e22L, + 0x1bfcdd84e00b02a9L }, + { 0x310b9a4375a365d9L,0xd4ade15e08d8fb03L,0x9c9753d7d742df83L, + 0xcf7309d4de318742L,0x1228e2123360ace0L,0x1043d238f7669643L, + 0xfc2adbedf90f5a53L,0x41d64cb77b5f9397L,0x5200b30ac446d010L, + 0xc3c8642d231720feL,0xfcc0122db9aa2075L,0x856e3b12041eae47L, + 0x4586445568c876a4L,0x1a1c7842233606b1L,0x9b766d1f227757bfL, + 0x25b78a3bf7b9d4f1L } }, + /* 122 */ + { { 0x90835718156707ceL,0x9bdc23984314f90aL,0x017c885a8be57dbdL, + 0xd4bba225ad63a4b8L,0x5ce71b8615aacffdL,0x5f26647572954722L, + 0x0a80f1f74f0ad3ddL,0x010538a3fc352ed7L,0xf8a640454203c6caL, + 0x2b2c7a88330c73b4L,0xb3433ee602dcac1bL,0x2e0499cfed2b17c7L, + 0x9f8681a4bd6329c7L,0x3897994636fadc37L,0xdc5650c892b7895bL, + 0x70ab957065a51cf0L }, + { 0x46778ec47b585d93L,0xca6d3610a633fe4eL,0x21da154e4ea0311aL, + 0xaf22190bbd64002fL,0x9e633ac7d91cb7a9L,0xed13c31fee6837d7L, + 0xda4a07d71616ee8aL,0xd78a27323afcd616L,0xc06696e5ba14d694L, + 0x733754d74df58420L,0xe85e504e2778e3c9L,0x3055aa0c55b5a5c2L, + 0x313df5388a3acb5cL,0x5896acb52a088edaL,0xfc8842a084c85ddeL, + 0x5fec9f7951dde6beL } }, + /* 123 */ + { { 0x5ebc2c7cfe519f99L,0xe396bd80e5410353L,0xaded94028a3988f3L, + 0x1c03b735d601bda1L,0xfd30203614ce64acL,0x5837ebe901240290L, + 0xcaaea1a3a554097dL,0xdce73d25b0b88139L,0x35ed412becb090b9L, + 0x99029ff7d63dab3cL,0x555437d9062db071L,0x277d2f5642a4c11dL, + 0x477fa64524fc9109L,0x7b12e9b72799254dL,0x7ad2ae22d84c618cL, + 0x0a8d5663ce8ed195L }, + { 0x43ac51630a21fde1L,0xcfcf5dd66903d849L,0x6d2499ee5fdd6281L, + 0x4dedc6f077a49a34L,0x46bda2c02875c06fL,0xd0e0e0f6347b8046L, + 0x1058169b5e67836fL,0xc961912ade8a8042L,0xdf3fea0aa93b3d32L, + 0x9f138edb0c576bc5L,0x7971ad6ed8d37e47L,0xeab85739cce5e7cbL, + 0x88a4b4341d202b40L,0x5d842557e3a1fd26L,0x872fabd5b3a86f91L, + 0x95b934936aa4629fL } }, + /* 124 */ + { { 0x9998a70199f951deL,0x8fade596f058db45L,0x4d479c1ef3d03dd3L, + 0x6e928d5d33b141d3L,0x9a465800acfe8a40L,0xd108ad2fc1cefa3dL, + 0x64b96921e013726eL,0xb9b6a6b68e83bb9fL,0x29f1e6dc1242e544L, + 0xd3f8f6762f65966bL,0xa34dd0965e105b41L,0xd4e9139a16011e1cL, + 0xeea4dc682515541bL,0x6f8030acc822166dL,0xbdc7ae1d31d16124L, + 0x2e25ef51621afa7dL }, + { 0x2533cf8fdd8e7357L,0x333ba218eaceddb8L,0x68e3e31d0784d2acL, + 0x1c927f36f2804ae2L,0x01433d2277e7ad7eL,0x0b401cf0587f78a0L, + 0x9dfcf036aa0027aeL,0xc9e46c8b1d9a46b5L,0xaa6de4861f288d32L, + 0xdd56da2f1b8a043dL,0x346230e5f2d0bb56L,0x19f0b6e419defb56L, + 0x55ec37cd21d2c874L,0x3dbf0397b70e45b3L,0xf0862a8dac7ce852L, + 0x87979ea7e141f3d6L } }, + /* 125 */ + { { 0x9b7e7b3f7f1c747fL,0x151a4c1dc6e63369L,0x4273ff70b372dba0L, + 0xca6d2234d3ee54feL,0x12fc8e0cd33cae0fL,0x273285385dd6f10cL, + 0xc86f3fbdf01a9cf9L,0x5322677fe36cae91L,0x39a700332fefea44L, + 0x2c9ca328ce8af217L,0xc0256776f6a731f4L,0xc687b3df66a96813L, + 0x194aab128db2eda8L,0xde30dc5aeec4febdL,0xc052236a979241b2L, + 0x3ec98802c23d4c16L }, + { 0x0f9e760c4072f74dL,0xe78eb0deab594059L,0xdb3dea40c9b009c2L, + 0x47e875f038b59ae5L,0xf40eb4362b4daa06L,0x9a6a4f92090f3788L, + 0xefebe9afedbfaf8bL,0xf87f96a59867e256L,0x1e6fed2375ab6aebL, + 0x17f2782a3fdb13cbL,0x5102c71e70fa2621L,0x5d2b06ecfd4c0dbeL, + 0x537cc26830347297L,0x8dbf5e2b2b67e780L,0x2f633f3aba25da32L, + 0x3e9315e8efaec914L } }, + /* 126 */ + { { 0x9255cfa5239a9ea9L,0x20f3c6900be33a62L,0x759eeb4b9cb642bdL, + 0x3316c54600bae718L,0x874a76d5f3410f84L,0x123b502e90f129b6L, + 0xadc8f9a812851f1cL,0xf57b764a1b62408cL,0x116ec01f1a80777bL, + 0x746ecef21f0ddc5cL,0x3c49d47ce5a6a5a7L,0x1e15dbe706e955baL, + 0x629c0c79b45d79b0L,0x11278308778d1087L,0x22585dc78c6a22d7L, + 0x2ed02a0d0a682791L }, + { 0x530434164daa2682L,0x0e26d32b01359625L,0x449c834abd867097L, + 0x11a19d2bee77ae2eL,0x39bd529a3af6c169L,0x36cca5c05cd61054L, + 0x6370a59bdc6c0fe1L,0xca420d27b93d5135L,0xd8730d45554c451aL, + 0xebd258c996cdebf2L,0x0cb1b990a50f9a05L,0x69a8c97a7b0f0151L, + 0x2cc36d3411d217e1L,0xf117688a752f75e8L,0x1db01394a09b2a61L, + 0x14627844a9efd7ddL } }, + /* 127 */ + { { 0x6bca3aed232803cfL,0xc1e4398b9a96ff34L,0xcaf6757f74ab788bL, + 0xc3a53e007e68c04dL,0x5f969c195cb7cd20L,0xf28b65a6dc068bcaL, + 0xe3ca01d31d863032L,0x9b733b8187808e14L,0xb5d704d9efe618beL, + 0x276f3542b01b946dL,0xe057e19efbedddbfL,0x7d182f2b903275ceL, + 0x3cdc5f77880f7bc6L,0xd6f03d3f78476c14L,0x035f5557a9ba5072L, + 0x7acb57b6b4029628L }, + { 0xd241356944e6b07cL,0x451c4cc9e1c7345dL,0x407444d8e273b9fbL, + 0xfe496079b88e34fcL,0x77d184cff152776dL,0x6d1033b9c742299cL, + 0x29a0a68477bf2897L,0x59ffdf10ee8f0420L,0x4e17146c44bb56d6L, + 0x831d06c2fb9ae855L,0xb2cb82dbd93e7cd5L,0x83381c463c96b607L, + 0x06aed2517549e2a8L,0xef97891c774a21d4L,0xae9807c78675fbddL, + 0x6a5a05b96363516cL } }, + /* 128 */ + { { 0x92e71ea66a8f4f33L,0xf2fc6fc64dea8f4aL,0xd356252cfee88461L, + 0x59b0a83e08954d08L,0x5bd68c23468ab766L,0x40281357900f8d04L, + 0x181c19c052b867aeL,0x986a516918764c41L,0xcb01dfae13575d24L, + 0x17269ae5593677b7L,0xf6d1702546dc9b19L,0x8de68499c40097c8L, + 0x76df0032259c407bL,0x4091aad917d29d8bL,0xa7f46d214a7ab5f6L, + 0x688054b470ece48cL }, + { 0xf0d168aa51a5b86cL,0x2437e4d895777247L,0xae844076f1720329L, + 0x0a7ac87d9647a54eL,0x1e597a4b0405622cL,0xedefe5c6f0a79f2fL, + 0xaf3ef0c24d55156dL,0x917fb04eef047cf6L,0x3792799f54b62137L, + 0x875ea32f314be0b8L,0xe157c65b0c466b0cL,0xd28c90ce7e218978L, + 0xb90fc3bacde587afL,0xdd32d71c8b877bedL,0x3b432200ca8e10cdL, + 0x0021f419d94f6e53L } }, + /* 129 */ + { { 0x2191122c43519d26L,0xbdafac1d40a51845L,0xcc6f71e9548bb89fL, + 0x9ef3375c16844bf9L,0xe7789f79178e8d55L,0x04f599b61f8be1c5L, + 0x8088c99a2cbbde40L,0x8939a260893206c9L,0xa1ae4bfffcd30851L, + 0x664cb3fee08feafeL,0x61f38099ff14aabcL,0x0d8394cc2a841ef9L, + 0x75fad8ad17f01db6L,0x6fc345766debb773L,0x1e716b05a4252512L, + 0x7985588029e1ed9fL }, + { 0xa2cb3aaa95106473L,0x95fafa415a61da04L,0xfd3c9362539563c0L, + 0xbaa4809195312b87L,0x6c7e7582bf885c76L,0x70f6dab6230c78d5L, + 0x8ce3051c7747440dL,0x6dbebd14ffdb6186L,0xb0e041fa190e4096L, + 0xba10c4666ee62e2aL,0x93d57e2a74f333d6L,0x006aadc4fe7b9b66L, + 0xfaf72f6c06d2837dL,0x318cc5e6910741eaL,0x9c50260965692477L, + 0x95d823c31d0fb08dL } }, + /* 130 */ + { { 0x6aeebd86140528a5L,0xf268c2ba53979bc8L,0xb1bc9b8a4ec144abL, + 0x1efabb0d82a7d7edL,0xf12c70d14e0118d8L,0x31607168a1c1558eL, + 0x33e428b7e4b7e73eL,0x6317663783aec9ddL,0x5172ffbee12ac35cL, + 0x37df0bfbbc17b2a4L,0x4212f870741f812aL,0x3dcecbdbe2888f9cL, + 0xa9dc15aa756ca55dL,0xf31918ecb9028e41L,0x7ede02856aeadb03L, + 0x0e2708d578654f54L }, + { 0x2270cc53cde20f88L,0x9338272c5f5b1039L,0x5042e19e5dcb1dbfL, + 0x4b3de219b72d74c1L,0x16c49a8b2aaaaa55L,0x008443e5bba86ba6L, + 0xee6bcd7220cf1695L,0x59ffac6ba89abd11L,0x2831217bf115639dL, + 0xe4d28af2f34cba52L,0xf27f03e70727a906L,0x6842c79f69017766L, + 0xcb3469bd7a81123eL,0x48c0f346a42973b8L,0xfc5784a623990dbdL, + 0x0d3dab3bfb299678L } }, + /* 131 */ + { { 0x8f8376e6ce29c3ccL,0xcb0507ecf016cbc6L,0xdebff9965e394ce1L, + 0x24fc526f73c50d41L,0x4edd5a542d16ce3dL,0xbb37bdd991c13141L, + 0xe3442ef2e33a8606L,0x2ae90337c0629da8L,0x57faec64592ab331L, + 0x1a938997d82b857bL,0xad6c8cb9a3373176L,0x82595de29086751fL, + 0xa81e97fb18c17196L,0xe4f48a13bf697357L,0xa1387c2e5cb89f69L, + 0x530b4eeb5874b426L }, + { 0xe9f275a1bab7b5aeL,0xbb69dc4d03a57bf4L,0xc974dc4aa45c505bL, + 0x726369f3416ac402L,0x735e4e78aed985dcL,0x0548d879cdd446a1L, + 0x84ceb0699e16b02aL,0xf73f6fa4789b11a6L,0x6aa0c41fb2a4e784L, + 0xb1f7690293a9b697L,0x814cce00f03a8ab2L,0x64cb255b844d66c1L, + 0xb794e7d630952201L,0xe052d4e43da32271L,0x5278b2e708b6a4d9L, + 0x9094255280c6577fL } }, + /* 132 */ + { { 0xd269a14d0d5b4c2fL,0x2b8fc59b5c8a649cL,0x95becb3ab0e37d4aL, + 0xfda1a7689111037eL,0x5810e05a94e35322L,0xa24dcc12a178fafcL, + 0x5c2c63b28e3dce62L,0x995c3f179452c444L,0x35330ec342d45161L, + 0xa025a60ab4ef8129L,0x854932528bae9c13L,0x25d1a606e2e3caf8L, + 0xd44091ab3649bf47L,0xc7d0afbf704ec5f1L,0x27bd1d62bd8b3333L, + 0x50570111cfe616f5L }, + { 0xd0084acef534356bL,0x9df1de054b4b0fbcL,0x021afe05cee04dc1L, + 0x64bde688361b78e1L,0xa324fcc7ef78d38bL,0xfeb372ceeb0a5e4eL, + 0xef04fcb365811996L,0x7dce5d505eb0ab4eL,0x1e29b588238c586eL, + 0xde5e3197bcd80037L,0x8bf5e4514806b9cfL,0x4330968bd18e67abL, + 0x26a7d04ef9f63fadL,0xa1c7f123b5c18bb4L,0x485b848225dce22cL, + 0x8ff0b36fd540e79fL } }, + /* 133 */ + { { 0x99f2e2f43ff42cffL,0xa3c19f9d1c35317cL,0xdb749392aba1b545L, + 0x84232b054afa9a32L,0x0b855d46d7dcd436L,0x8ac35e2045cf9915L, + 0xd7cf22c7f001a218L,0x057d35aeed408305L,0x25a4a519553ccfcdL, + 0x5e56579393e2b939L,0xa20332b03422ec27L,0x9b09005e3ac53958L, + 0x628051a379e9b163L,0xb4a0dc09fc6618d6L,0x9e0e857f6748e7afL, + 0x71b28eeec577d63eL }, + { 0x4942b0cd99726bf8L,0x1290a3b91c208f3cL,0xfd7290e7b0598eaaL, + 0xc6a7791fa25a9128L,0x2d33db24c037d7daL,0xc21efeb070e2837bL, + 0xbf70d96ee3dae2a0L,0x43ed819185076027L,0x4aeb0aa84d4ad7e3L, + 0xbc75101fe8c5b74cL,0xdbfb2a6ead26ebddL,0xba8120686b78aa4eL, + 0xc94aa8f2e1159848L,0x0d10d9db3eba5c4eL,0xce7fec476318295aL, + 0x7294711a330d925aL } }, + /* 134 */ + { { 0xfce4590432bbd495L,0x330f4dd1be54973fL,0x006bee1d5d9c3f4eL, + 0x40ee607859ba7204L,0xc194fd3f42c2c768L,0xa0e76b12e9fe88beL, + 0x17cddddbec2b0210L,0x689d436b00811ec7L,0xa6a6ba37284be9e4L, + 0xabc395b2007d4114L,0xf8cdf9f30f11e744L,0xc5febec8e9396402L, + 0x8a751743eeb46285L,0x99bf8782c6e0d137L,0x3965e170beb292e3L, + 0x001c39d85801fd5fL }, + { 0xf4805cb9da4a0912L,0xd27cb76a4410bca4L,0xef3dcb8eec71d65bL, + 0x780fbb2b4816849aL,0xef6a7026a8b24635L,0x15625c8812c44e68L, + 0x624c232c4d7a74a8L,0x81a770374b1631e4L,0x04e4f7f1db917c2eL, + 0x1d0465fd1f61ed95L,0xb1048049cbde6e3dL,0x637ce0c1d7131fcfL, + 0x22e4dbc28ada4715L,0xf7530c5cace99726L,0xa0160dccee287450L, + 0x9132e670bb91af13L } }, + /* 135 */ + { { 0x8057efe27996099dL,0xb72344dba06e608cL,0xeb4a8740d0958588L, + 0xe53daf0679e5aee9L,0xc9560a9a908a2fadL,0x7f4be131107e706aL, + 0x6d5f3d9b2830246aL,0xa5f8e8da27cca3e6L,0xeb51dca64c28f292L, + 0x4cfa310ef31dfd78L,0x92e0c7c22ca073e5L,0x102f1694a40da683L, + 0x16bb07cc750d38fcL,0x703e83e2badae035L,0xea93c066b4d3c9ddL, + 0x7d0b03e579940ed1L }, + { 0x5fe7ea304dd94c63L,0x57ef01c5738b0b3aL,0x9534a78ca14e6b4bL, + 0x07622cdea5353276L,0xaf696a077c22d006L,0x733c18867d46b209L, + 0x9654ccbb626c2b4aL,0xa098d3a1a84f3c4cL,0x3596f9ed2d734b74L, + 0xdfd3021a5d551c90L,0xe2ba7d2f1ec5123fL,0xf9726925b2c1aa39L, + 0xd2e75d0ef8eb2927L,0xfaba712e19192a6fL,0xa606b43a9b83e50eL, + 0x31b1782fdab5de60L } }, + /* 136 */ + { { 0x878dba454034db92L,0xa39779018f34dc4dL,0x8d004f2edf754c33L, + 0xeaa5954acd563a88L,0xa29d6c89bb5ffad1L,0xa8adf655b0d8bdb8L, + 0xf7fb842d8cdbdb47L,0xb72e3a0380d3205bL,0xc335b0b27cac7ca9L, + 0xffc60bcbd8a5475dL,0x736f7719eba4d25fL,0x3d901c380c50fca6L, + 0x1fdacf7b80c01900L,0x75cf658f5681f84dL,0x57a7e6345cefbbc1L, + 0x6fc0fbe53e07ed1fL }, + { 0x496d116bb81b0e5fL,0xd82dd2a52ac853b8L,0x357e22d4327387f0L, + 0x3e332a84ba912c59L,0x8b71c64349d5dcc1L,0x0c982ee9438d85d3L, + 0x90b9553cbf7fcd4eL,0x2cb39bbc38fed5e3L,0xa2c67c9c5ac42903L, + 0xebf21217bf07da55L,0x55ac05ada0b9e4eeL,0x10bb12c28ee9e0c6L, + 0x5cf3aee548bb6e3fL,0x4ae7269c8b046e91L,0xcb266012aa0e553fL, + 0x701935a1a94c8fc8L } }, + /* 137 */ + { { 0xde58d41da4626deaL,0x25ef66ca15b9039fL,0x99a810a43164e65bL, + 0x9fe6daad748cfccfL,0x7ab9a6bd2f142fa9L,0xa4cba1685d471796L, + 0x12d30b366bc3a39bL,0x1f46a5dc8bf45076L,0xb868e5291421ac0eL, + 0x7a68620659bba1c4L,0x2b4b552eda698b90L,0x5039dcd4e5453707L, + 0x42a07a9e9e90165fL,0xa838fff3d7d45dfcL,0x41991e5a3b5ceb30L, + 0x6c961ec8969ca600L }, + { 0x703bdc1bc4e7eb46L,0xd6bac557596c7b48L,0x4f9917cd66afd74dL, + 0x56355105656ce6f3L,0x3d1fb50c32497175L,0xfda6783e63effb2dL, + 0xbd79f1f3eefaa2bdL,0xa4efbe5417af9ef7L,0x6cef64625a55b7a4L, + 0x116f32381a713304L,0xdb2a2a7fb95625a3L,0x6a0aa43a0b027e96L, + 0x458fe5d24832b3bcL,0x523418df5adfaac0L,0xc05a89cbc49e7f9aL, + 0x830883d869e24b53L } }, + /* 138 */ + { { 0x959b1c6202557389L,0x5fe5ce97adefc0bcL,0x893bbe7f8330f383L, + 0x27e0c6af16cfb81eL,0x6f64e65bd04428fdL,0x53de9245b79e6182L, + 0x08a313c1487e11caL,0x65cec3b9445bce93L,0x33bc0314d67ed49eL, + 0x69f36b2430782352L,0xd78e5daf93ad31d2L,0xf2682b70c780890cL, + 0x7015c34f9e45efe9L,0x135d4ba4e6cbafeaL,0x43a378a47e3fcc6cL, + 0x2376f97f96638f8cL }, + { 0x0a6e1ec0ae575b99L,0x7e14cb4f81b970dcL,0xf00a3824d3a73947L, + 0x0b4b9c81fb235a9dL,0x8d15115f5bf62944L,0xcfd35b431e165d7aL, + 0x5d12fea2b2ee3e3bL,0x629984a6f5182e7bL,0x4e43e2f3c365d08eL, + 0x9932709130f36e72L,0x698b4a00fd345401L,0x23c4fd0ebaf96dceL, + 0xa60ba0ae23675554L,0x51bdac2db0325784L,0x8ab4190a215464a1L, + 0x8c4616616bf10296L } }, + /* 139 */ + { { 0xeffca2582d1f36a5L,0x0eded2b2894c5f2dL,0x35a5cdb843ced84fL, + 0x290f8982db0e3b9bL,0xcce0eaf00719a112L,0xd0e657e439a362d6L, + 0x5516a55d62697e47L,0x269e1f778e636514L,0x5e3dedcbd50269bcL, + 0xecec2300441c57c5L,0xdb83f31cc705578dL,0x1bdefb731e489eabL, + 0x20b678cf395fcdb4L,0x908cf91cff9db001L,0xcbebc6f455f52cc8L, + 0x155ea622b4c61162L }, + { 0x94be2f1f876fa42eL,0xab5e87497fadeee7L,0x692e70f538c865afL, + 0x16e99b84df8059b0L,0x0ceb606e8b5a7ac9L,0xced233572d463d2bL, + 0x2d0f26232a9a09a0L,0x2529998c3861fbdfL,0x711888a7c1be310bL, + 0x9b1229c50d8aade3L,0xdbcf9b783b13533dL,0x3ca746f8ff029708L, + 0xa5a013a1da83ef88L,0x8e904d184ab28444L,0x2fe84b3dbcbd4abaL, + 0x8f570f24259058c3L } }, + /* 140 */ + { { 0xdeb66c8a2ca9c508L,0x2dc5bec269d6b780L,0x16d6126688ead600L, + 0x61841b9749d72614L,0x41e40e6cce472e6fL,0xada242641fa7a876L, + 0x45b9fd33cc3997a0L,0xb25e8fa97c15dcf4L,0x0124ceb212e9629dL, + 0x3a8c72c67db3d956L,0x8e2ded2b7c1a7844L,0x94ab09c66dd027ffL, + 0xf89a057d7e7a2bc6L,0xad8bf226cf70c763L,0x4cb268e7c8a26212L, + 0x3d171e87b2c44c1dL }, + { 0x382ac16e8ce49820L,0x24ee45e2c0c44dc9L,0x0ec6791273e858c4L, + 0x918cb25c46327cf9L,0x43e3876bc6159c1fL,0xb6b6e0e037545cb3L, + 0x64b839ab5d12347eL,0x72e09274a300d541L,0x26ab28e6881c1169L, + 0x4a580fffeb75a843L,0x0a5802ca359120dfL,0x7fee82d03209f4a3L, + 0xb518016b8e6a9380L,0xb99c6c70c2ee11caL,0x16105af1ab9d4ec7L, + 0x234e98f834cd9004L } }, + /* 141 */ + { { 0xff43520814db9cdaL,0x99cfdc4796adec90L,0x843aaa6faf458b6dL, + 0x3f1f7415743eaa31L,0x915e192e61735d81L,0x3441a22d0ac595d5L, + 0x704bbf67c044bc8dL,0x2f960471be23a236L,0xcc32638815d1d557L, + 0x9410230b76b1dd94L,0xf2e5439f0c1c8a67L,0x56b141ac833c910dL, + 0x467c999f865b84dfL,0x1b0251fa21f02b7bL,0xde5b526096216950L, + 0x6a2130e3ce3a1e93L }, + { 0xd21b67a04b3ca1a7L,0xaf42ed5300c0ce80L,0x22ccd368932cf07aL, + 0x36523a815c25c35aL,0xecdd39588dd04d06L,0x73da3502b2f93a3bL, + 0x4c5e0c3cd5e5b530L,0xef9f548613268777L,0xed87fefc1e742292L, + 0x6d9ac29ea24e5edeL,0x08abc9f033849f1aL,0xb09b229240f23905L, + 0x6791072c7f934353L,0x102a6381e6aeb550L,0x3ee0740996feb870L, + 0x34f06faa9c4d2830L } }, + /* 142 */ + { { 0x869dc79f2348f005L,0x9b5c5d71df4920b1L,0xfd1b57ca6dee64a4L, + 0x21b7f734e82a4fb4L,0x637cb834b9578366L,0xc934101b7d287d96L, + 0x1590f8ac0392ecabL,0x280dc3737f75f4e3L,0x8b36f50f6a61ac62L, + 0x74f58304a65568daL,0x80d792a9d930870aL,0x6d17b192fc8895ccL, + 0x498392fa4914939fL,0xaf36027dd41d5b9eL,0x452d79e25caa82b5L, + 0x764d47b1f4115d1aL }, + { 0x5df22303a2ee8b9cL,0x1b9f72d385dfcd48L,0x6b42b98310813a37L, + 0xe28c523b3de741f5L,0x0857625af303bb5bL,0x926f299aac9bf9afL, + 0x21beac080d445b34L,0x6a523a02d6ba2c0eL,0xe302a1b17fce2864L, + 0x4516a235e300c1eaL,0x4543736a7b4a9311L,0xd3c0b9e8c0cc89f7L, + 0x0481904f40ed88deL,0x4f269b563cb7fc70L,0x09a1d53a321b9738L, + 0x1c0dd9c3230a3810L } }, + /* 143 */ + { { 0xffaa1f67c46a7d9aL,0x64743334bedf91ccL,0x45833a7447a42f2eL, + 0x67980051241ffaa9L,0x70979a84335efe6bL,0x5f0613f5f08b2403L, + 0x6bb22fcd64f211dcL,0xe1b8b2a3a0572cfcL,0x19e0eb417950a14aL, + 0xe634bb293eb6cd4cL,0x31a04b25470a25ffL,0xa41f7ac9a3d15a0aL, + 0xefed85ecbf2fede9L,0x1f581f5f81b94a00L,0xaa3996b09ef4a15cL, + 0x52d8be39b06041bcL }, + { 0xbd1536f6fd631a2fL,0x91fae7f0b351a8dcL,0xd1a590c79b126212L, + 0x52d4875f2bd0f435L,0x9aedb6d392b0ea70L,0x0bd0abdcb83ab89eL, + 0x827a106289fe192cL,0x6566a960102a0bdaL,0xda083037ce036814L, + 0x30bed79f58639405L,0x972019b6dbca8df9L,0x89201286efdaa3f5L, + 0xb337b9965236b892L,0x11d3e38e28fc2e73L,0x70787f41880e8da3L, + 0x6cff6367dae4a45dL } }, + /* 144 */ + { { 0xbd3d0433f89a8bb4L,0x42144c3393b98f71L,0x82b616c803470a2dL, + 0x98fcc757e5da089eL,0x542354ef7bf5fda6L,0x1885c2539ebd34ccL, + 0x2e20b285bec5dd0dL,0xe71bbbe1782a1bcaL,0x959ded309b854ef0L, + 0x172499798997fa6aL,0x50cf8fa8d81f3c45L,0xa9a3b51760c11152L, + 0xc9b0ef7decf845eaL,0xc9339e23b9fed11bL,0xc93e9c5c28256080L, + 0x1d2c8217613ec1e7L }, + { 0x7381347d987cfc93L,0x047603bbf187f810L,0x3fa6bc9d1250ca31L, + 0x480091e0bb055bf3L,0xbdf95f1a3a3af87cL,0xe2687770140540abL, + 0x998df730d7fe045bL,0xb398135fb723bc2dL,0xac230f8c15ebec46L, + 0xe08e18305f5561c0L,0x7c0fbf4cda60a47fL,0x06e95c24e16d4bfcL, + 0x7416349574617e92L,0x397198694ae0c20eL,0xfe2693122131e2b6L, + 0x25486e360a537722L } }, + /* 145 */ + { { 0x618795ca53572806L,0xb2c89449656968e1L,0x149c2c973fb323aeL, + 0xfb15de26409bc7d6L,0xa90cda72c79121b3L,0x6d2fa14e204cabbbL, + 0xcbcda6f791604125L,0x25086261b435f947L,0xdb686c38c282eb10L, + 0x51016d62f1a791cbL,0x6b1c7ed161a2266cL,0x26780666271d74a6L, + 0xb5ffeda1824287a4L,0xcbe503ffbbe4f0f3L,0xd7f7f0beb9482a74L, + 0x751b2358088493f1L }, + { 0xd597b9d6e9c9be68L,0x1794b5c467d10c6cL,0xa88cdc3d7762b2f4L, + 0x6d94a63aa1b44e11L,0xfb0bbbb9aaa8eca8L,0xf4b0f2d0c963d87fL, + 0xb753062c5dc7075dL,0xfed726ac49933989L,0x5da6063857f9ccdeL, + 0x221c392a75f8c766L,0xcd264d955dc672caL,0x7004ff22b66ecc8dL, + 0xfb1aa9ae18a458baL,0xea9644df8babd653L,0xa9378e802ba0de7cL, + 0x144cc12dca2c6c75L } }, + /* 146 */ + { { 0x593a0a1d2989aa3aL,0xd83f228359e6e64dL,0xe938b0cbd32e732eL, + 0xf4c464c53c3cb249L,0x9750a5f8f89ea6acL,0x467e5bbf346cfc32L, + 0xc9bfab9d37b2b809L,0xf8eb74533b339c6dL,0x3fe01fbe3b766deeL, + 0xb3154254ef6aea27L,0x555c3df27be61b10L,0x70fb6d81dd818488L, + 0xda1af3a4bbe714f9L,0x575f20179d18f693L,0xdc08fc6b2465b839L, + 0x874ecf336b84a951L }, + { 0x624af83ebbb3f6beL,0xf578fbb908bb423dL,0x5623b0bad7873527L, + 0xc3659bd8a62e0442L,0x2903b167fe236f79L,0x55a430c6e53f26a6L, + 0x222547ae3ad712cfL,0xb73890d776eb272bL,0x95b4f70b3d628df9L, + 0x9f0e13b053eae4acL,0x5b4f5138e7f2174eL,0x75482cf998dbae17L, + 0x2b69bbde44518480L,0x4f279652cafef15cL,0xa0a3ef2bb6bcaf19L, + 0x31fb8581ce4c634fL } }, + /* 147 */ + { { 0x398306d1615cd607L,0x680c9faaaa32c3a6L,0xe87a705b7779131dL, + 0x1031013a36708b00L,0x814fa0e19445297fL,0x70c5583aa6a79b56L, + 0x03039cbf4b16bed4L,0x18a7ca8daaaaf8d3L,0xf33159e75cdb68a5L, + 0xdea0e738d23814faL,0xeb3527188d0f4f9fL,0xb0b76609dcdff032L, + 0x65ba8ea93d48338bL,0x18044d8255dd507aL,0x844a223e4a4a50b4L, + 0x9832300018e19e54L }, + { 0x28a2102757f3d5a6L,0xffce56486e8cadcdL,0x9590381b02551f3bL, + 0xb26cc64f935ebdf1L,0x60611291c083aa6eL,0xcd988a6688e4cf41L, + 0x581c3f73dd53b1b5L,0x78c804a977fc621dL,0x31874330fadca2faL, + 0xf7008da4c83ccf02L,0xc4122a1da79a4707L,0x9a8e0d3f4a915eb5L, + 0xa2de157dd0123660L,0x45ef43b265ead2a0L,0xd0a22ade188db285L, + 0x8abbe39e922e0caaL } }, + /* 148 */ + { { 0xb44469053a2d2f01L,0xd27c31935dc6685cL,0x6a908bbf1d74a027L, + 0x01da350f5b50ec1dL,0x1d3dd45e3f3c2e26L,0xf66e11d0b836ee92L, + 0x7e03908f474b979cL,0x19e7c5b998b87834L,0xa741d3febd3d1de9L, + 0x63c68e8d1ef6059bL,0x9b9ff9393674e247L,0x1d7d53e73e7e67f6L, + 0x698dc326aee9e248L,0x52f23edab3bd984cL,0xf95e31b06f8fe8a7L, + 0x0f15b4d0c3d0ba95L }, + { 0x8f2f6635790a8d85L,0x51bffbaee2595af1L,0xd15b7ec624b51287L, + 0x7639b6ab3234715dL,0x0cdd52992bc5441dL,0x54800ea4f6d05833L, + 0x21efd752f6d6e360L,0xc0b7ffe519290613L,0xb68a5825eea898cdL, + 0xecedba9222982266L,0x678a91b0bbd06bb2L,0xb2436dc04bb6b0cbL, + 0xcf7a99e7caf8ea98L,0xb92d0e6e71aa05bbL,0xbf8d0471f5993eb1L, + 0x515db37820385ddbL } }, + /* 149 */ + { { 0xee43eaaa6f5bef22L,0x952d269820348712L,0x1e4c484e7a3af6c6L, + 0x18d434c69a8c9403L,0x63e5d7415001899aL,0x5238dbbcfe8ea40cL, + 0xca6cc8d296798721L,0x73db6aee04acbde8L,0xbf69328db7f993ceL, + 0xa3f79bbfad45e334L,0x8c51ec937c1f1630L,0x4907325f9b00a6deL, + 0x49e6acb412d82bc3L,0x5901b36d0ec59fc9L,0xcb09b7109cf34e3bL, + 0x2de0487e1abf4c02L }, + { 0x18b722f38dd9d484L,0x833493937c77baccL,0x58dbb8f193d92b8aL, + 0x80d78d508e3fac25L,0xf0500981745f4a7dL,0xd072bfed877cc29dL, + 0x67abf8f2c30a89f8L,0x92c567ea9a0820d7L,0x425ab12e8a3a5738L, + 0xc162faebf055521bL,0xee1c4f26b94ea5e9L,0x1e4149943d71e546L, + 0x258183b843e8be1dL,0x44917c82ef9eae0bL,0x6813a45773874a30L, + 0x6f6ac071cc42f86eL } }, + /* 150 */ + { { 0xd38822ad4dd6e3b1L,0xfc78e1ccad620869L,0xe78438452cacde80L, + 0x121cc14aa8469fe3L,0x8e8f3da7e67e8ef2L,0xdb83d16e4d347448L, + 0x3ba1dd98798631f4L,0xdfab59770a4c4c17L,0x1f0a13063edc701fL, + 0x4649d6016cd8ff28L,0x2267230bbcc55bc9L,0x02a19c605760412aL, + 0xc719d5f1328faef6L,0x27cb969ef67eaad9L,0xf342530e719bafb5L, + 0x6e2c24ccff5a82cbL }, + { 0x6313024badaf8793L,0x944bccf1035c948eL,0xe9a066b7953500bfL, + 0x7991a9461d116765L,0x95addb2e9fd93c78L,0x05d2c037e92e5495L, + 0xcb145b189f03e5cfL,0x81ae48ca95aa1f72L,0x203f2702135a6e4fL, + 0x2bcef5a249b2a7d5L,0x0687a90002d7f2a3L,0x2f7d32286c6745b0L, + 0x3da8a87586507305L,0xbe38b8842e8dc58fL,0x6b48bf34dbf11185L, + 0x5af7fd0d97c08f91L } }, + /* 151 */ + { { 0x55f9b950f4a224a5L,0x41904574cc50273aL,0x34f81330643f1fd5L, + 0x996801bb0e50f783L,0x866d740389581712L,0xdb9a405da4091d36L, + 0xf1e379df16a46fe7L,0x8d04a93f83bf9168L,0xae4c833532b20bcaL, + 0x99d334b1f72a1c10L,0x8fbc9977d8195db4L,0xcaeb3dfffba14b5dL, + 0x60fef02276daf476L,0x4b948dfedb5b72f4L,0x5185c925b6dfb062L, + 0x27a9c3819609d4aeL }, + { 0x73c37346f12a93afL,0x028b707c5536634dL,0x8efa58d5498193d1L, + 0x4f83a5ccef21b69dL,0x05cbb0a3a788a0e2L,0x0103178165b13c98L, + 0xfea20e582b73784cL,0xdf9713a0e50361f2L,0x31449a0fd0cc22d9L, + 0x183752e77c5e2e1bL,0x6e44d6bdb67044cfL,0x012dde95733e177aL, + 0x68b4966908ee2c23L,0xd9bb05411f5f1949L,0x95182c716acd886fL, + 0x1c690694fbde9244L } }, + /* 152 */ + { { 0x5db67d173a880026L,0x89c4f0a0125d95f2L,0x290505513f6cb7a4L, + 0x3eb231d15cbbdca5L,0xf8cffc99972bcbd3L,0xcb4ef4d4ad55a03aL, + 0x944d47ca22867c2fL,0x96d885480ead1aa5L,0x76a57cf8cbc8b045L, + 0xdfe5844b005e55a0L,0x5e9e7e191d18a097L,0x957a26e852923c74L, + 0xd0867b797f5db339L,0x2553408e63bed0c8L,0x1596e5d5689ad23cL, + 0x7b8c13d6a504c339L }, + { 0x2fc43aad52fb6901L,0x1c0313f916ca253bL,0x1475830a515aadc6L, + 0xc93d19267f577dc2L,0x26e52e8ef723c0ddL,0x2f1e0eb83eb9f6daL, + 0x9979de82f180376dL,0x43e28ecbb0834939L,0x9a2d51dca39c38e7L, + 0x6e6063a9a8e3f6b5L,0x4cf1da3a4b9b3270L,0x6e5348a2d2f8915dL, + 0x5e75e3e050507912L,0xaeffce5720d383faL,0x1d6d53cc8fd2fb29L, + 0x0e3c3ef6696f4cd0L } }, + /* 153 */ + { { 0x3bc337c121ee1d83L,0x97e08f6d787b7788L,0xbf709fcc138fa4ceL, + 0xbaf77647a0348e58L,0x04f8babca55e672dL,0x0ed2919d7d5ec5ddL, + 0x8ce64bff33e99218L,0xac09fc5724b059afL,0x506831f9dc5e32baL, + 0x26a22677465af6a9L,0x3c5efe66c97f1ff8L,0x1515e0d6bc6087fdL, + 0xb1a39c5eaa8edc6bL,0x3dd816bb0e79ed29L,0x6cc13769bc3788b8L, + 0x463098e3c092a51cL }, + { 0x3a6408c7c8bd0fa7L,0xd1764311ce6bde49L,0xe315e108283ef7beL, + 0x8213cc7799b5d938L,0xaf7f158145a49a6bL,0xd00fdb0fe529e4d1L, + 0x55d38f77ce66c9d6L,0xb4f7ccc01bd4b952L,0x8d975b49af71f986L, + 0x12b59fcbcd64d00aL,0x1860e504a5a3bad7L,0x6d9760442b5c89f1L, + 0xfed0c6597a3e231fL,0x58114c33178cba92L,0xe2e74c066698e11eL, + 0x7f8fd093a348b85aL } }, + /* 154 */ + { { 0xf24592cac19428afL,0x192a1c813a308665L,0x42589812e30bbd7fL, + 0x10db0723836c6bb9L,0x9c7a41e9598e4987L,0x8aff179e6ead6f4bL, + 0x70f8f9b975862c44L,0x6b3b02376f21983eL,0x25d83e9b98e65152L, + 0x3b2d26a8d751218aL,0x9508281a9d6f1da6L,0x8df78d05a5a81f74L, + 0xd79ee559e4687471L,0x2060ca576787d8ccL,0x427a84ffa8476c95L, + 0x87b64c51e6435131L }, + { 0x87f46f654b30d3c4L,0xcdec4c5c23b4ef14L,0xb3b7476663ca4d68L, + 0x1df34269cf3fb56dL,0xd4f139c40fd7d46aL,0xa3b7c7c76a69a8bdL, + 0xee56b4c9cbadd7d2L,0xb28ff342ac942334L,0x0046fdfa786f1da3L, + 0xce5d149cb700c82eL,0xca30ef8150966597L,0x44a20609fcff4bddL, + 0x0f2f65e744925268L,0xe5b6552cd4021f38L,0x77ea9c2a042dbbd0L, + 0x8c95267cd9c062f5L } }, + /* 155 */ + { { 0x6655032e5fc1abb1L,0x2215af5412fe4743L,0xfd65756029f05ef5L, + 0xb0e73325dc191be9L,0x7ab3c65ec08639b0L,0x67507f511c3e6673L, + 0x638befc3c8615555L,0x5d0188cf42f0c4adL,0x843a301cd896186dL, + 0x045603f7b2c6741eL,0xf7545c0cfa3cd1d0L,0xf612affd4a40672eL, + 0x56197c9f45b9e8ddL,0xb453237d87922d74L,0xbf132e3a4b2d59bfL, + 0x8afa1b73b84a6a16L }, + { 0x6b3596eae793ac70L,0x4c94ef8eeef6dd10L,0x926b4fa270422e40L, + 0xc8c71dcee9e5d763L,0x352fcb70f512aadfL,0x1b7ba138a883975fL, + 0x57991390058c3b13L,0x9692092a97740fd1L,0x19ad945b160b0697L, + 0xbc63438810837ab2L,0x76ee11c4f174bb71L,0x6111bfc1ab1b80ebL, + 0xbc82bac870ec458aL,0xeee60127312d3325L,0xb4118b1ab240adc8L, + 0x672111912b5a093cL } }, + /* 156 */ + { { 0x91e99306f55cf9bfL,0x9b045308a46b96d9L,0xae3c1e1d9e7a65dfL, + 0x453cb151c731bcbbL,0x14be5227a4d58a61L,0x39dac92297c74cc2L, + 0x4d0f7a45822e00d6L,0xafeb1d51c62b03dfL,0xbb1dc3a4baa18b2dL, + 0x7f3c7178df2b74f0L,0xfcd328a6896b6a33L,0xe95ed4541dce055fL, + 0x97fbc76b6a4e2b87L,0xe5ec67f1fa59dce9L,0x052368accc0367c1L, + 0x7c86391654e4a3feL }, + { 0x55e94b5eca7388cfL,0x17cc0a60c0335d38L,0x9b69b78b616f85baL, + 0x705d02ef10122980L,0x565a6e801cfd0a79L,0xeb74a96d7d1ee352L, + 0x5c8832ed427b9dadL,0x96ea8528e6d5330fL,0x30d8862b18d24ee8L, + 0x9cd38ed59ff939f7L,0x690fc9a201060252L,0xc62d88b82303b3ffL, + 0xfc42d7a4dd52b469L,0x06f8dfa28cad2d93L,0x5023609060920438L, + 0x32582758fce855adL } }, + /* 157 */ + { { 0xeb20e45f359e8c60L,0xc71bb8a5364ca186L,0x02b15071dff8e110L, + 0x074e91d34c93e578L,0xc0326e00b829d0d8L,0x3c192258626a83faL, + 0x387a64d5fb29a09eL,0xcaaa3d34e5ac5c82L,0x8ed685e5ada2da29L, + 0x92720267eb29650eL,0xf7184b19763802f3L,0x23f5dd0edf6b1aeaL, + 0xbe1fa34725e6125dL,0xd6287f9d0c872a1aL,0x49aa93d2ac57c3afL, + 0x1a4e6a715bda7656L }, + { 0x1a126ede554d1267L,0x37f945331cd02b48L,0xd70af04cce31fb1dL, + 0xcf410b0b097dc012L,0x930e1d1736c7b6c5L,0x902fee41c6891085L, + 0x349ba4a779fb638fL,0xa16c5821acd6f8dfL,0xfb3b83c12e076aceL, + 0x6b8d033be501d14dL,0x0593d45220f2d2daL,0x3752526d99df1880L, + 0xca32351c9feb33a6L,0xd91343bc1f6ef456L,0xc74857db35b9dc8aL, + 0x856a7c9385b4e832L } }, + /* 158 */ + { { 0xa007d0020d0a5583L,0x2f1301ddeda4658aL,0x91c0796434d939beL, + 0xa0cb6780a70c0836L,0xc0b4df95be81e540L,0x6cbbcd345d4ac8b8L, + 0x57c52ed054756239L,0xcac2dca41805ceb6L,0x915ee6ab79344255L, + 0x366def3124c9a2a6L,0xbd3b962f8c12c674L,0xaab64f1b7dbb7c3bL, + 0x3c0e4553e22bb95bL,0x2408febac4c63b74L,0x3ca773122a4da631L, + 0x62889084c636da40L }, + { 0xa457fd538cb8d208L,0x7a8f8009543f06d4L,0xb66de154f2eff2abL, + 0xfddb28ebf72517e7L,0x0149fe66f9389d2cL,0x79e8773fd85b88ceL, + 0x452e090b0ba543f7L,0xdeb9b5cfb0b03fc0L,0x3113448a6c5ed77bL, + 0x3609f3cf8ffc0372L,0x2bc9c46d5c1b4c4aL,0xe66f3bf38fa59be9L, + 0x1396bf5fcdb02691L,0xf1ec59d4009f88f9L,0xc29034562ad9dfe3L, + 0x79d8122c5ada4d58L } }, + /* 159 */ + { { 0x14d4e4ceaa529507L,0x056a081474655d00L,0xc0d30a384f0fc474L, + 0x8a8203ea3443cb8eL,0x33c62fb097f1728dL,0x8a38dcfdb520ef52L, + 0xa0f90d5d7cac9d3eL,0x28a7b0bf873cea50L,0xd115ae3a6c6c41cbL, + 0xa35171daa13812c1L,0x25d4bba5624d507eL,0x91dad2897e98f42fL, + 0xffd6b1e996a41371L,0xd46c2125b69e5b77L,0xc7d2b42420c4f707L, + 0x2ab3af958142557aL }, + { 0x86ca074c6a5372a6L,0x728fb83e56292ba7L,0x745596dc77741cf5L, + 0x70b4cea1520ef49dL,0x1472fe3461e46472L,0xf4d6bd663fb8ac5dL, + 0x46e52cc9c10bc071L,0x28794efe371a3461L,0xa4850718276fe877L, + 0xedad57739bef5ab4L,0x24c2d9ff3f15c815L,0x188950e58f8395c3L, + 0xbae4099680b6a855L,0x4f53e22c8a8803e1L,0xaf233f61039d25eeL, + 0x07db2c35250409caL } }, + /* 160 */ + { { 0xc7f3b8db037d4703L,0xe83708dfc5f488b9L,0x1fba830f8471d402L, + 0xa55ee8d25a2faae9L,0xc2e5bf105404fc1eL,0x647d5027aa2d5651L, + 0x37a53c0c7ebaf5f9L,0x7adf0bb295b30abfL,0x5a62e1fed64c93baL, + 0x7ffc18c0e2ef4a78L,0x139dd9d94d2cd04fL,0x253fbab75ea0af02L, + 0x7c8100ea0fef9acfL,0x74c5384dc8615aa7L,0xcb28682d9fe52069L, + 0x08b6ca8fcf7dd759L }, + { 0xe04e5bea036c3b5aL,0x387261027f9f2b4bL,0xa9fca57029797c0fL, + 0x1656180b82879ea3L,0x153389bb607f0ddfL,0x99a1223c67b0e087L, + 0x0d1808ec9d897fc7L,0x9470711a916edf19L,0xf8f52f2b07217118L, + 0x5d8b29ffd18888b6L,0xef1e22c54cc6f900L,0xc4036165eb24877fL, + 0xfda9523335479525L,0xd622a4216861468aL,0x5d043b0774faba08L, + 0x2c337b020d31a7d2L } }, + /* 161 */ + { { 0x7b2305bcea22fa65L,0xbe183ef4d159f63aL,0x3473d87d3f35923fL, + 0xb27fb306c11d7753L,0x702e7e6b2a054cffL,0x3ce9f97caf185619L, + 0x835502434e7d51c5L,0xa63e3d82f356ac5bL,0x867b7caad7645131L, + 0xee85e6afa671fc9dL,0x3b985ede2b07cd77L,0x07d598b0ffda5193L, + 0xb10eca39a942dc36L,0x17f3dcee506218a9L,0x3d94e8d106b7d5caL, + 0x509b2634ed8831c9L }, + { 0xb1b9414e48caed54L,0x77a78c6ccbf51e97L,0xa4688c8d4de9b258L, + 0x0024137c91ee3d78L,0xa68f9234e30ee64cL,0x573255bc88190d78L, + 0x41e8e05fba80690bL,0x50038d84ec354f4cL,0xb18f02d6dfa52816L, + 0xc47f9007ccb63fdaL,0x29d480fbe98ae455L,0x4ac45d225d0e319dL, + 0xd06f3575026db719L,0x733b9e202c3587b9L,0x224839922c317727L, + 0x1592d5a754bb8752L } }, + /* 162 */ + { { 0x5778d9a2cf7453f0L,0xaffb899aed83c1f0L,0xae6506d3e0a82ba7L, + 0x32c84e1aea3d5081L,0x9ad528c0810aa38bL,0xb1fdb020bd37d041L, + 0x78d6cbe1d06ce41fL,0xd287f0f02e74b7f6L,0xf5cd2575c43bb022L, + 0x6d28f2f3f81a71b3L,0xe65bb1f5c633e7f4L,0x32e5fc1cc4fc580eL, + 0xcd55539fbb7b07a5L,0xb5a94471c3caaf3aL,0xb958bdf44cc22d2dL, + 0x1614bdbd77a2777cL }, + { 0x4c1f0230ed0ab04dL,0xae347b006e2082eaL,0x9f10bc63c42c5b5fL, + 0xb0539e6fde019935L,0xd89bd4e765dd0825L,0x92260fefbbceda16L, + 0x8aaa755ce62aca32L,0xed762fa95ec82c5fL,0x99e64c0118650768L, + 0x57dd6245c92e348cL,0x0db88a7731ea6d68L,0xef0012ab07b44736L, + 0xb9356b94171d70feL,0xe68b062803f891b0L,0x3a54a53ab79c20a2L, + 0x489656c7b00b0728L } }, + /* 163 */ + { { 0xe43649ba71353c25L,0x517f27a113f67e24L,0x10bd333a1c1eb9e3L, + 0x94e1c05c78e29bf9L,0x84fe7d974743f15dL,0x9c87490890da2df0L, + 0x82403fa753673be1L,0x7ebf5db41baea1b1L,0xcfe0ae3524180eadL, + 0x1d15873fc2f50c3fL,0x16851ad670661cd9L,0x802968d9a51e8c2cL, + 0xe7d1a9cde0161099L,0x2b153c89a8a7ea56L,0x6d41b78906e3c498L, + 0x082bb2e9d6769dcbL }, + { 0x6180ef46c4d6615fL,0xfc629dc101b9829cL,0xde222ec00fb264caL, + 0xc5457e0610ecc2c4L,0x95ce599f1eea2c4dL,0x0433fa728f9c5b2cL, + 0xee035462cd6310f9L,0x84c57c3bce2e2253L,0x6c8ec31a96d87e44L, + 0x30bfe393a452c5a7L,0xc592b140a047b235L,0x7bd8be18c018545eL, + 0x794e01075c178c46L,0x484719462e23005bL,0x2665e237622a54f3L, + 0x36451a46901c9042L } }, + /* 164 */ + { { 0x17802d1819893e71L,0xa1765d8b539a2082L,0xfc6aea012302ecfcL, + 0x8d4cf51b365bf59dL,0x87741d720d232a80L,0xac343eb318e80427L, + 0x553ecb2fe74739ecL,0xaeca79a81a8b07caL,0x089ff32256f4ab3aL, + 0x5e95d7293fa1d1f7L,0x260569aef62a9a16L,0x5e776232aa08ddc2L, + 0x93fabec31b7bb54aL,0x48a20956743d56e7L,0x749cdb12eb0ebeffL, + 0x705307a469b8fcf1L }, + { 0x7a8e4c04e488310bL,0x12726e325325cd7bL,0x5d0fd8b04983efacL, + 0x796e552c02ddb913L,0x0eeca3f777b9685cL,0x9b766e89b15f24a3L, + 0x7c2736d648efc979L,0x3d619685a8021c6cL,0xfe33e278a0b2f1eaL, + 0x95c69879b676d6b0L,0xa07473191af4e0beL,0xa2fab5f136c4ee55L, + 0x6938b8ff59e5f3b9L,0x1e114da439cafe6eL,0xc9595ec36a6ad120L, + 0x80f79bd057e62aecL } }, + /* 165 */ + { { 0x3cef42a760af09b3L,0x3c016ebd933dfe14L,0x720cf1e0ed85eaa8L, + 0xd4f5e99fceaa3bc9L,0x7216b9d2b7106f97L,0x65f34c36c9668ad2L, + 0xa8fb82bc5b0c651fL,0x20f42f1cf2fda4deL,0xeb31ab2cd21f659eL, + 0xb7a776c7a13d1618L,0xec44102238662be5L,0xc825da70cad08e0bL, + 0x99299079022c0180L,0x7623bda02aef9ffdL,0xde84f4f3f5c58b50L, + 0x5f5a5da4d824ff19L }, + { 0x5737257e7e8311dcL,0xdef94f51466cf136L,0xa73e1645b05ca21aL, + 0x38ea9b3c02e4ab37L,0x7760eac98579165bL,0xdffdd047c24b01a4L, + 0x188d4fd13fb95584L,0xfaac38b825548bdaL,0x1a79a6f059e9dcacL, + 0x983f720f09a2700fL,0x8cbba554fb8a7e48L,0x38a1996847a1fad5L, + 0x118565475abd6b5eL,0x75113d31f3716ec2L,0x1391e7814212907bL, + 0x5319c8010dc15889L } }, + /* 166 */ + { { 0x2320136e6b61c3afL,0x1d40f2de07b4bb68L,0x651dee7f380c97f0L, + 0xa978ba706a8c313aL,0x22c587d62011ca10L,0x48bba218ab1f445bL, + 0x8c5eaf07e50444e6L,0x5549f02a442fccf9L,0x2564746f3d80493dL, + 0x42d24f6179c04591L,0x1600fa18abdc8887L,0x5cb8600aded38f8fL, + 0xa4bf9b90923aeb46L,0xd63fee351e1c578aL,0xf3c9c5acebb9ea14L, + 0x3d13314df11a4ff0L }, + { 0xe5cc662db4513d1eL,0xde78a8c5d55952bdL,0xe8a37a3fe7f86d0aL, + 0xca2d12a47a04f0c5L,0x4c6696e42e25d06cL,0x52614698b2136071L, + 0xf4d2701b89f6e1cbL,0xaafd617780efd95eL,0xe6d73ac4c5bb6907L, + 0x49e874ac420db35aL,0x11631de4f2751fa0L,0xb29f7336a1fa2eddL, + 0x4c406864b7fd794dL,0x73cb21d3e22f92a6L,0xeae904e62043cc76L, + 0x67f28a9fb322c6adL } }, + /* 167 */ + { { 0x7c17b258ca148ab5L,0xb9a1976fb3c60051L,0xea260698c8f28df9L, + 0x87b2cc74e8d45017L,0x372573290578a422L,0x81d5ee2517bec732L, + 0xd7411fcf1d48bbc4L,0x46217e6b487f5cfeL,0xcb007ac541eb8e1bL, + 0xc41c57a6e05a00c8L,0x1f954d2bd2f9fa99L,0x370bd5db40941cadL, + 0xe487879c3829509dL,0x4c1375525ceca5eeL,0xe8ef7fa4fd3efb9eL, + 0x5ff091741bd1bdb2L }, + { 0x791912a4579c6632L,0xbb19a44fb8a20815L,0xf4f97b84535639d3L, + 0xe57e2bcbbc3c9bceL,0x122b3f2bf19e6410L,0x1f0189da1357d9adL, + 0x675573bb79e5ff66L,0x444e5c98ef2f3c4cL,0xd6f61e2004d10731L, + 0x0dfa366fac75d635L,0x9fc47c862c854f23L,0xc04ae43e0ad0850bL, + 0x5ce94f642f720c32L,0x67efae65a753bc9dL,0xc27d30d3b0373a63L, + 0x6681013a29721646L } }, + /* 168 */ + { { 0x1385d913e84509dfL,0xe978beddcf339376L,0x2df425d33423a148L, + 0x43fa0ae3ee8cb579L,0xf015369d31c4553cL,0x05cf08bbdfbf1d48L, + 0xadff4be69444244aL,0x01635f81a35dda33L,0x085c8949e76fab7cL, + 0x4bd7fcde16737783L,0xfd8cb52ca254f8d2L,0x62168a66413ec985L, + 0xf2db97417a9026ccL,0x3962ee5650e1e1b7L,0xbee0a346d3beffdeL, + 0x3b35b72f0bdfab1fL }, + { 0xbff8de9f535c3749L,0x23c1f20f8add9c48L,0xa975b37bc8f8f663L, + 0x2529e475e8f3ae49L,0xc32f10d51d5e2628L,0x5ac0d29767862f1dL, + 0x13c79338854cbe36L,0x48f004ef4b67e462L,0xfa37a150e5d10ee1L, + 0x4974778dd28288a0L,0x96830a66cfb73f4dL,0x9f44401307804952L, + 0x8233c7099760b694L,0x8340cca525b75c99L,0x3f62e40bc771f99cL, + 0x47d0a1ebcd95c685L } }, + /* 169 */ + { { 0x266f4fff652811f1L,0xeaacaa9362ef3002L,0x6c387a5550cba0caL, + 0xa350142a007f5467L,0xc7fd102a202f2673L,0x5daee57033dc6e65L, + 0x60682ec3064a63d9L,0x46cf0bb0462b251eL,0x0e030ca55da936e7L, + 0xc87a60f2434265b5L,0x9637b2bb69b4e8f5L,0x601fb58c7ad7770aL, + 0x1f2147f6ed3a15a6L,0x05b47d5e2995e961L,0xcb0ca9b383213a16L, + 0x8f4b614a4995a85cL }, + { 0x5aa8ec194b4eb3c1L,0x8c549ac420323a70L,0x00d493224f6cc6aaL, + 0x0e53b9bb45f9a5a3L,0xe46ef1100897abbbL,0xfe873e57d7acd7d0L, + 0x7cfccfe50f7cb588L,0x0ea53d65c85557d1L,0xfdd9eb447288f2e2L, + 0xab2dedfac0eb68a8L,0x5822147008603a0cL,0x6946468900feb06cL, + 0x804cf5bf25e5caacL,0xd85598589fc91ae9L,0xed9378b173c45eaeL, + 0x8f942d02524c9801L } }, + /* 170 */ + { { 0x1f1ec3028e845808L,0xc302bffab77abfc5L,0x26afd4b9f8d97dc7L, + 0x3d3a83c43aac594bL,0xe3b74bd1674d94dcL,0x4464b737caa5911cL, + 0x62925773871c2cd2L,0x419f24853b4440feL,0xdda6a0f3e052ad7dL, + 0x645280d6846c86c0L,0xa25689faf8324f42L,0xc74ad1e807cf117aL, + 0x5626dea08ddc9db7L,0x52620373966fc85dL,0xe0ad57c3f3b1eb53L, + 0x38300252949c1acbL }, + { 0xa0ef5a405e744723L,0xdb5bcf751ae08481L,0xabfad8ccfec1f76fL, + 0xfba5d831fab37fc6L,0xbe39e248c8fedb78L,0xa5cfad5fad93f310L, + 0x747fdb1e913d5c24L,0x052a47c94518b7f5L,0x9e208d6c7cfb4327L, + 0xb135cb9c70e538beL,0x363527595bb17916L,0xa2c078805b3106c7L, + 0xd2d42a06c209bb06L,0xb525b471d3c504adL,0xc9f4b368822ce034L, + 0x15f18796eb4185a5L } }, + /* 171 */ + { { 0x094dea060aee4684L,0x42b21f067cdbdbc8L,0xa439e149b1931319L, + 0xea4bdd4181a7dba6L,0xc62137063c2ae80fL,0xb58b096712823dc2L, + 0x7443d515832611b1L,0x2e16f83113c20384L,0x0ce204d62bd992d2L, + 0x499dbcd6f419388bL,0x492ded1d1d3778c7L,0x9d5bd74fc5ddae73L, + 0xd4813d52994b6259L,0x191d9cf60e86ca68L,0x562179eaf3e9c2acL, + 0x6146f1f39fee1238L }, + { 0xbd06d33e078e2aa6L,0x693af7f79dee9265L,0xd56e0f81daa40e84L, + 0x05fbbb889b9a407eL,0xdcf44adcede99519L,0x7f71f8d3092dba39L, + 0x675b5da54231774bL,0x7456a251a5f605ebL,0x9031d4af87a39a9eL, + 0xdb43000605b474bdL,0xbda5dbf2b665aa91L,0x5d1a3df56631eeb4L, + 0x028149ef62377c58L,0x2e1af4e9685d0bffL,0xe0ea087582a465deL, + 0x95543f9e06bd0050L } }, + /* 172 */ + { { 0xf7cbc6f485d7c6efL,0xcad8084d63b1bc24L,0xdf90ce88bf8cba62L, + 0x98e4b686b455c192L,0x6146b8d5774fc6edL,0x70e2389e7ae20077L, + 0x5241c47961c22529L,0x7d2215103884e5f5L,0xd6d20ce217e28273L, + 0xe3119f514f2674f8L,0x8545905570c011dbL,0xdfab75d9fcfb760eL, + 0x9546362a9e8c2a19L,0x4b6d3f8a4a7d4b27L,0xa5c87104ee5d698cL, + 0x6db434782ba296ffL }, + { 0x064864935c3f0d95L,0x8917db824e748895L,0xf73fdf626b2f3e44L, + 0xc60edc542b7f574bL,0xbe1c09a2af732723L,0x7d34669d7cad114cL, + 0x9646600a321aaff9L,0xb94e2bbaed0cd61cL,0x866e1a41dec4750eL, + 0xa1be990db1a89f58L,0xc39e4d6cf2759693L,0x11cfb780c0e0dddfL, + 0xf0afcd7fd99c8a41L,0xcebffadb6e1c3050L,0x4f3981b096d2c6e4L, + 0x07a791e72ae27a94L } }, + /* 173 */ + { { 0xe70e90471e9f0300L,0xe0253ad9bccdf904L,0x51c0289dff053078L, + 0xf1ef092eae893462L,0x2c90a91aa4846845L,0x1946eda0f1dad4b4L, + 0xf07650f333df67b2L,0xc6e988db0b15a014L,0x72e0c66eb542f0f9L, + 0x5d4b6311e0c0378fL,0x548badaaae86950dL,0x6801638db35f1c8fL, + 0x129e3216944d1ad4L,0x9951bac840471d32L,0x03cc29f385e94ddeL, + 0x6d6acc2e4543ecacL }, + { 0xeb999e9557b2d299L,0x3a2bcd9be3d721cdL,0x2e60384fbb4cb444L, + 0xae177709dc060faaL,0x74f0e6d38c987cdeL,0x9a237cf81076fbedL, + 0x69af15137983fbffL,0x6c3f7a1d323f9584L,0x3e21cacf6db64398L, + 0x7cd8134f96703d92L,0x0755898fb8393f76L,0x1b5b28bc2e825222L, + 0xb78799c17924aa7cL,0x1db378f281427a8aL,0xd5a451b1ff289492L, + 0x79d182123d3c46eeL } }, + /* 174 */ + { { 0x1a3edff9109d5589L,0xded52eb4029b4499L,0x13eb9d30b4b54adfL, + 0x4f9214c1a27bff67L,0x4c817ee767f0f460L,0xbadf8d83c3a50e28L, + 0xc5dc03c994026237L,0x5f29581b966647c1L,0x10b6a0898a0687f3L, + 0xae787cec31634517L,0x2001dba562e75188L,0x55d4e1a745e2c3fbL, + 0xbfcacdebb67d3395L,0xa1a0af9cbc6842eeL,0x50590a2b3e88580bL, + 0x73104491a784cdc8L }, + { 0x44ca2cdf2648d676L,0x9a85eca54f1b12b1L,0x1b9dac942980e1ebL, + 0xf30d37091ac8aa89L,0x73072ab7c719e195L,0xba518c822f703797L, + 0xac090e14ac0067f6L,0x0e6cfc708dcd2927L,0x4f5889e221e7da63L, + 0xb4aaa40b8371c7c6L,0x1f9dabe28f7878c9L,0xf78aed6bd84caf3fL, + 0x3c39dd079e0e1d92L,0x680be5fb122424dcL,0xf41b214d0bdc0099L, + 0x6a8f8fc95180c54fL } }, + /* 175 */ + { { 0x62a1ed6353235132L,0x1db233f159dba88bL,0x85625452291efdd8L, + 0xc7505297b25111aeL,0xb5921af91d701bd8L,0xb4d05d729774f45dL, + 0x6e3d4c5ef18e73ffL,0x897d985f899b3038L,0x8a9c30fbc89b1558L, + 0x3c92d1a34d13181cL,0x292e86ba2223320eL,0xcf2454c201ceed02L, + 0x27a45f74583f309fL,0x75a6102cad0fd1a3L,0xdb4f45d2cb9c7538L, + 0x4752d8c1db283fd7L }, + { 0x514d6cead5dff4d5L,0x74cd5fdb45a827f4L,0x1070a60c4fc7135eL, + 0xdec0bb781be5778eL,0x271e12cd58dc6b08L,0xb765089b54bc2496L, + 0x6ddf2c63619098acL,0xfd6ebac667528832L,0xeaa2d025c2508af1L, + 0x13c2cda84dcfc1f0L,0x1c7836a845510be0L,0x3904688d1a886801L, + 0x643132aaafaf2545L,0x496855772830a88dL,0x569491ca8744b470L, + 0x3a6518f375fb8552L } }, + /* 176 */ + { { 0xaaa8ed50224042a0L,0x6cb4e3b02452f1e6L,0xedca5f4c768211d8L, + 0x4e0fe3f9ef4d5d3fL,0x33a8e2a4522d46e5L,0x5998e21ff1446775L, + 0x1496c50ef592d01bL,0x69104c2f83a67739L,0x28670bcb472bbf00L, + 0x8ea883b2503177bdL,0xc5d8bc057d2712a2L,0x41ef9317b439c994L, + 0x9801d3a8dcda1affL,0xd686eeb57038f6fbL,0xe80c5cd0fbfbf820L, + 0x540ac363edc25817L }, + { 0xa71969a9fe7f43dfL,0xe66538082c1b9e4cL,0xad9677d8859c2917L, + 0xbaca954596aa4404L,0x0e9d855fff1297daL,0x1f61897b22aea7deL, + 0x96edccfd36f13f8eL,0x627d307016e200dfL,0x729f0736c98988a4L, + 0x95e25e6097f231d2L,0xaf7f221bf6048752L,0xd66826094019b299L, + 0x1d99de0926b4b1d9L,0xec47cf661acdd7a3L,0x4de9f2b36ebe15e9L, + 0x17db32ecfa16974fL } }, + /* 177 */ + { { 0x75ef69196cf40599L,0x7ea10dfb00c020eaL,0x3da5ae7bfcaaf679L, + 0x0d663ca388ddd678L,0x5a21f8fe255bcfcdL,0xe9c3f538e344bc7eL, + 0x35f62b1d548e0632L,0x654f242543c6e64dL,0xc755a7a626993627L, + 0xa3b7c5f7b0f41324L,0x05697f793a2180f3L,0x6cf85fb11e81675bL, + 0x6d3cdb35e53428f5L,0xe3aa159152d28b02L,0xa8470255f7a3fb78L, + 0x460bd01ba194445dL }, + { 0xbc34dc23c24d8077L,0x82f4b5804c720d2cL,0xa29da9116f5d1ffeL, + 0x578af52092783ce2L,0xe29f51abb5904af3L,0x46c570d7f7aa1190L, + 0x4a522fba571bddf0L,0xbf4e2a06ae89bb51L,0x799b35cc59f3444dL, + 0xc302836726cc2557L,0x94a4e985afcec177L,0xadaf7dcb7c36cbd0L, + 0xed31b78775d39077L,0x52d6904f2d3e24bcL,0xc5ca26691f95421bL, + 0x7d342c3c1734878dL } }, + /* 178 */ + { { 0xe5cf2c0a11fd127fL,0x66d36bb8119e4c5eL,0x621ab2526ef56ac3L, + 0x30cfeaeee5430675L,0x2ede27d2ac3e9619L,0x6413513af8fce671L, + 0x6159c61b075f4c3dL,0xd447efe959069d98L,0xaf8d6f68ea76aea9L, + 0xac5dc61b0f5bd164L,0xdbab446e1e88bb98L,0x618b8b161ba92320L, + 0xa0eafb3c78989865L,0x0c7abcc2c08b7e82L,0x10f09b6e20d160bbL, + 0x5be0afa68e4c63a7L }, + { 0x82ab6d381bbbf49cL,0x3e09ce498c0703feL,0xeca58b5de10f4263L, + 0xd9cc6581da5a4532L,0x07e18876f618f7b7L,0x0419a5e3250f7fe7L, + 0xbb1a9e90de6b86beL,0x584a7deb37359169L,0x38eb34895149db2cL, + 0x14546a33b0ebabb8L,0x0067f0b0c2f88a92L,0xbde0dfe70a2db019L, + 0xba51b06cc63e6f3eL,0xa19127b9e9206fadL,0xe4eb5e87fe80dc0aL, + 0x1e6fccf5d4de30aeL } }, + /* 179 */ + { { 0xb57dff66aa8ac924L,0x06e9ad31c298b3e8L,0xd140e32965fb080cL, + 0x7dab211d1d95c93fL,0x6d68d8428a180caaL,0x1a929408a20ded69L, + 0xa815175338df461fL,0xff5604ae60eae932L,0x901b9e497dae4c0bL, + 0x4573a97fde262e89L,0xed69d9a4f1084983L,0x8ffa022f64724f1dL, + 0xd5f1c2e4ea85a15fL,0x4c626ce901453794L,0x80440cd6bf0907ddL, + 0x4522d4615ddaa837L }, + { 0x8895f079ebfbe7c5L,0x30ea1ded84ef3446L,0x716a9eb6d4a1ab96L, + 0x1a4a5d2250a30c68L,0x5a16631c0043bbaaL,0xbd1075025010e5f5L, + 0xbffe3e9d3d8c0556L,0x31b30b1807772419L,0x90ff7ef084b82297L, + 0x00c37d75f21a18c3L,0x18d0a635565bb8f8L,0xbac1da2a45e3bcebL, + 0x1c38e90c23f0b08dL,0xf1ba1aa25fbc5ac5L,0x09d5256bdda71fc6L, + 0x346501a96d7e40baL } }, + /* 180 */ + { { 0x86be448ccc2b0f1dL,0xe3eb45c9ac4c3703L,0x5387f65d9fc96bbfL, + 0xcef3c4e95ae27fdaL,0xa008f7761bc18089L,0xf374a08422ca18a1L, + 0xee88284253b73371L,0xcb6fc6d87cc09354L,0x8489ec1b61496d6bL, + 0xa92c29b949e325c4L,0x15c6ca527bdec166L,0x95444eeedcea2813L, + 0x34683eb33a21154fL,0x8fb26f98d39061cfL,0xc3b08aa806c940bbL, + 0x7c1d42cfe554c96dL }, + { 0x766e703fdc110aa7L,0xab7b79d7f362e378L,0xd259c75d5aadca3cL, + 0x2a6eca7960be3373L,0xf4744a4b06c4e8ffL,0xb2842ccef3b705bfL, + 0x1a3af5aaae304b53L,0x7bbfa2011b2d31b8L,0xc4ba6eba4bee88d9L, + 0x2d3565ce565cb839L,0x24808696daf7ece8L,0x2c7ccce7e6959745L, + 0xefd6eb3ce94f9837L,0x0a33b4cf3811a326L,0x14203f43fffa93a6L, + 0x031e982873c31d90L } }, + /* 181 */ + { { 0x4fefecfc765a17ffL,0xa09f3888d1290a65L,0xbf265c46938da038L, + 0x4bb6145da169ad46L,0x33cf821423a62fe8L,0x562df571abc860a5L, + 0xbf2a90fa815c38c4L,0x45ba1d6e17eda875L,0x799d881a946fa5e1L, + 0x6c1be784b90f5a3bL,0x0910a37cb10ff52aL,0xc38c1fe4a4f4fd36L, + 0xc3180fc58e2d3ba0L,0x3e2ff050b17a6187L,0x3a00059b943a35c2L, + 0x494d3645a28cc51cL }, + { 0x398426b64ba021f8L,0xd14c9083796deb6cL,0x6d2e53957e36c762L, + 0x8f556eca751cf216L,0xdaca1e0019b24a19L,0x47887da44b20c2aeL, + 0x93ed4ccdff41a733L,0x8d717c445c7c0cd7L,0xcc48634a91bf7009L, + 0xa1f146f93b59bbafL,0xdd38bb39e5624f15L,0x96d41aad303f8443L, + 0x6b670f034bf104fcL,0x0503f9ed29706582L,0x768e1f47b34200f5L, + 0x3cfdcc5ebbd4c6f3L } }, + /* 182 */ + { { 0x536c2a86b523e13dL,0x1014a4582920d0a0L,0x3d52b478e7571296L, + 0x057460667eb51beaL,0x709f786187b0e919L,0x028aed88686888e8L, + 0x79a809d7d94afcd4L,0x50c6032fe2129af3L,0x75e4be72983c4082L, + 0x98331bbb7ab3be8eL,0xd31a032cb618c728L,0x36dd85a13f59c4a4L, + 0xdbece345ed4f61e2L,0xba7aaccd1e571715L,0x138c58da64a1ebd7L, + 0x89296d0f3d1aeea1L }, + { 0xb165288fcca82c97L,0x26c6c12d1427e8dcL,0x66a94f074c3edda9L, + 0x94600e1eeaa01ebeL,0x14abce7c30f5e86dL,0x741d7020cb456a31L, + 0xab05aa13279f42c2L,0x70b60fafd4238468L,0xa18efec1318d39e6L, + 0xeb07f1ac8920b318L,0x01e3cba8d8399e03L,0x65f8932e3c81a301L, + 0xae8bca7dccc667d8L,0xcee1ae79a268607cL,0x3182e64ccac0a12cL, + 0x9233a2f72b1a4c54L } }, + /* 183 */ + { { 0x717e8df60acbee17L,0x0f0959c25c24fcdcL,0x46f09887e54ffcb0L, + 0xb993decad285116bL,0x0bfaa4f8bba1fa51L,0x9c9249efd0f2183eL, + 0xf93cb35896847779L,0x284bfb7f2322d421L,0x40cc709ad42af009L, + 0xc69f22749bb1d615L,0x76f50b3a717c3c6aL,0x8b21e985bb9c5eebL, + 0x58fb19aea4783b5fL,0x04c86b9b52e1c3e7L,0xaca59092f2971ac8L, + 0x2bb26a6921ed8291L }, + { 0x98a3443515f81416L,0x086e72e7aaff5bb4L,0x3d1f64de0317261cL, + 0x31c0786c5c0a1cfeL,0x542ea4d8b3683401L,0x2f77273a1a39b4cdL, + 0x14fe7ee1cbef27f1L,0xee7fc09e16bb27dcL,0xc0dccc17410e5dc7L, + 0xa34667421943b3ddL,0x92934b603f31c1b7L,0x0186ded9c22c1070L, + 0xa37ee8ba799f966bL,0x0f3bfcb4249b0893L,0xbae614472e92d4deL, + 0x937cb3f8e196eb08L } }, + /* 184 */ + { { 0x57c0e77c16fbfdceL,0xea034cc9c98d4cc0L,0xe7606d7242572d20L, + 0x9861b55c0019a83cL,0x80ba2803f1597162L,0x0f4141dd05a0fd7bL, + 0x8865913b4b0daaa2L,0xe6685746aa3848ecL,0x16d15a5a3e0485d2L, + 0x81c0c7743b6905ddL,0xcec31b7d818af2baL,0x80d8f194d2b74b78L, + 0xca659db2543e2f28L,0x31b83a7d9fb07c1cL,0x86537fdc1f1048c0L, + 0x4d57bb0778586a11L }, + { 0xbc4b768a53b396b6L,0xbc8b24c493b51dacL,0x33e511eba30ae1b3L, + 0x893bbd95945147c5L,0x6cc86031179fe3ceL,0x34b0a1673f920bd4L, + 0xb32912eb6b256160L,0xbc69a2a49d168d83L,0xb4949e7aef0dd128L, + 0x2613419a872699e1L,0x06c58477bf21376bL,0xe55b1909a4f97147L, + 0x63d6eb757b9b745fL,0xb5365b2908df3c85L,0x0e257e4355fcfae3L, + 0x1067c118979f2aa8L } }, + /* 185 */ + { { 0xc845508432bf8883L,0x4755286a6fd06667L,0xd70b0f8f77c2335dL, + 0x678e60da2f4a2c94L,0xa468d8acd118acf5L,0xce93830bbf5b90d9L, + 0xea4b1c74ed4e9104L,0xac67316d27776ea4L,0xb98ad75c361bab12L, + 0xc323d48299122451L,0x26440220530a43aeL,0x3a44532e3292d5a5L, + 0xdb48694b5fecf1bcL,0xe4e0516ec667b8b8L,0xb3aa595fa4306adeL, + 0x7e4f7091f34e9725L }, + { 0x3f3816e9b7f70919L,0x765216ed16b003f5L,0x46c6cff4778c99e5L, + 0xe6a5abe830a51810L,0xef6f49e645e728dbL,0x6fdd73eacaccefd6L, + 0xec394e6f8c37f3f7L,0x73320802b6407fc3L,0x988e8f7a96625cbdL, + 0x832923637cabfb00L,0x258ba9df407f359aL,0xff01aee5ccbfae50L, + 0xfbeaeacefe251813L,0x9c69f16183f1cba1L,0x512c58ad9eadcdb5L, + 0x2ae49cd46ccce8bdL } }, + /* 186 */ + { { 0x1239b0e3c40849f2L,0x5136a4cda441098cL,0x61535a99e547f649L, + 0x92e4bdc47a9bbac6L,0x195a164653547af6L,0x85ecb3198b47a74aL, + 0x278553fc9de6a2b2L,0x471c038a0e2ba52dL,0x12ba1b8835bcba93L, + 0xd4bf50da6f31eca2L,0xd146e3f6802b32c6L,0x0c9c01313c64c8c4L, + 0xad30f12deed21297L,0x9b75bffb9c68530fL,0x23c0ad3e8918de51L, + 0x180e9d52a73771b7L }, + { 0xc316542f29ab77b0L,0xdd411d9cf7aee628L,0x044c0685353c2f40L, + 0x638dc7e44b0ae4cfL,0xa092418595fc266fL,0x639da671fd2feb7dL, + 0x56858ed55ea39798L,0x7a694f3158f3832aL,0xa94233c6d316d831L, + 0x2fcacb2630a35a7bL,0xfef8f7ddf1ff713bL,0x8b9b452559eee2f3L, + 0xd1b4f91b156d064aL,0x177866c22f5cfcfcL,0x12bc25663777eb41L, + 0x21ca6f3cd8ab85b4L } }, + /* 187 */ + { { 0x0e162b13a3e66635L,0x1ef20a2b2a9f76afL,0xab473a3046db3356L, + 0x0840bd777802bb8dL,0x5b6baf5ea699b44cL,0xc6e119001b2207f1L, + 0xe5de16a9790b0105L,0x22b12f15db67f004L,0x185fad458a025d25L, + 0xbccf6953df0a1142L,0x4c42129bf45034c0L,0x0f7404001c277bffL, + 0x6e440b4c280a9e18L,0x767de8f5842aa2b4L,0x3de20ab805e8d94fL, + 0x5aff585920227635L }, + { 0x805acd20a8458e40L,0x5a5557d8149732bdL,0xc70741315f1ca72dL, + 0x7f2e269c952b5323L,0x5c5925566494fadfL,0x153b7acd1a7d2666L, + 0xa6df063d86fe2865L,0x1e91db1357d53b6bL,0x9195bb89e93ead01L, + 0x3d71e1af2963bfe6L,0xfab2b9c288278886L,0x778366923b859b6fL, + 0x6e695174f7029dd1L,0xc79878767b984561L,0x64fb4f1d5907d849L, + 0x3eab7e1c88d8a977L } }, + /* 188 */ + { { 0xc73a94b652e5718bL,0xe3aefa54f4cee1e9L,0x654e9e63553eedeaL, + 0xf2541e1b5f3aca1aL,0xd71294890d083316L,0x7965af63fb7f950eL, + 0xd8fc9e0dc74e3e4aL,0xb4ee48d2eaf79ebcL,0xa458a86a8b7787e6L, + 0xd8c7621ff7cceaf0L,0x8228eeffdf67980dL,0x210d4742f9106727L, + 0x91f63501b07e3629L,0x441761c67971e29dL,0xc0ccc65f03a3b8a5L, + 0x3491da4f38e09544L }, + { 0x6706d046cb062eaeL,0xee7db7355d08776dL,0x80de8052292315d2L, + 0x40785662c402bbdbL,0x5f93525c26ed3337L,0x6cea14d67d568ed3L, + 0x916a118966888b1eL,0x0fbd52055dc71675L,0x833d1077e4575df2L, + 0x4e93100aec092335L,0x2f9e1d016cd85389L,0xeebd372543226368L, + 0x401d172b1ba4cfd7L,0x377dab9d574c5838L,0xaeaa695880d517deL, + 0x0c843dfd6ad15a18L } }, + /* 189 */ + { { 0x455811ffc9373300L,0x1c39332a99fdc300L,0xe19bb81c353cb655L, + 0x774b924a96a83d27L,0xcbfc8fcbb2ee3f1aL,0xaf278ec4010d56c7L, + 0x6fde682fe0abaf79L,0x7566d0727339aebfL,0xbd35ad5d71205db6L, + 0xb5bbe6947051c9d0L,0x577db480d3a3067cL,0x2c70ff54572d7530L, + 0xe8615aece06d853dL,0x71999ccb05abfb5dL,0xeeefc96bea0a8ed7L, + 0x2dcc469d35f6df69L }, + { 0xcca6cd06c65f0e77L,0xddcc7980bd71b14aL,0xb6221f8b3c93cc00L, + 0xddfcd5b3ae8cbf57L,0xbc92973f76f8e63fL,0xe9848a3406e132b7L, + 0x4cc59a03d51ec9e2L,0x9c9d32bb3a33081aL,0x0012105280e8466bL, + 0xc2b0032a1bbe7295L,0xdbfc657224938448L,0xe972a0ceb6bba0ffL, + 0xf60c0a4fc0a94802L,0xf62c41cc599d8bc7L,0x820c96ee312da0b8L, + 0x5a1a65dbcdbdf9fcL } }, + /* 190 */ + { { 0xbfba691a42485684L,0x613116b929c470c9L,0xb4b01971e62a0519L, + 0xf3245aa65ff499daL,0xc2ef87f4a5238effL,0xc16dc6bacc9d5515L, + 0x5a7f227e2dbdacacL,0x8dedaac4a9bbaecbL,0xff308a6d2e7c9885L, + 0x4c6f2fc2e6895593L,0x3655f285177e0611L,0xa63e8d06300b1beeL, + 0xbed0ce7913c17b54L,0xca4abe35c4974262L,0xf4b44a17bc4e4037L, + 0x5ae95099efe5fbd9L }, + { 0x122e5ee7804f7455L,0x341a499722066682L,0x97d24c317795e333L, + 0x12f4123ce48efcedL,0xe8738d9219fbc21cL,0xbb3bdc610663a3aeL, + 0x3603d8c28593a6dbL,0x926227f2e3c1ac75L,0xfea92ac05eaae519L, + 0x5b596f0bfd6812acL,0x3ce7e844fc2a82dcL,0x3840481a63522b27L, + 0x836088b152867895L,0x21ffb7cc26588688L,0x0ca331612f4a7cacL, + 0x4110667ea3edd298L } }, + /* 191 */ + { { 0x81830357c2d04b63L,0x3fc5a34df4929a18L,0xc73bf6da22d195dfL, + 0x14df2f89cb432473L,0x345afe5ce997f138L,0xd8e3f5f98b9604f4L, + 0xad7942e950c10ae5L,0xcefd5447eed25ff3L,0xbf68e51e0e73c0ccL, + 0x5b1ad591ab54fa4cL,0x8bbc110512b61c8cL,0xbb932913b5abf760L, + 0xdb1231be01e79649L,0xd0a83e91040ccbe7L,0x3dde426f90a96db9L, + 0x1cceb64534df11eaL }, + { 0x2d210c4f0c6d0f55L,0x6cadf61b9c673c9dL,0xdd7f9919a9ce3fbbL, + 0x135f494c93b063e4L,0x580bdb3c145a93beL,0x4d8723320f52ef7cL, + 0x74d876e88814bb6aL,0x4f6f723ac7a97deeL,0x7de2b8f03e3cd833L, + 0x6162f082ae720270L,0xe88ec2d4ddfa486eL,0xd965c8598d3a17c6L, + 0x62e59e543980171aL,0x0ab6285dbbef6b22L,0x3cf451954d48b203L, + 0x1f1752334ea25ea3L } }, + /* 192 */ + { { 0x808a765b3467ea91L,0x3f4632eefd2d9c45L,0x7b75dc6d9cf2bc6fL, + 0xefc8d240359813aeL,0x23ecb209e44cbd8dL,0x59ba10e321525622L, + 0xfa14d9343f1ee19aL,0xdf97c21bfb0c48f7L,0xc4e62890ea30d437L, + 0xb286e2a4651475c2L,0x291f01e4126672a5L,0x9c6fda5c31aab3b8L, + 0xb7277a5ae17d22ecL,0xbd88ed83914f0badL,0xd0b05d1b6a2392e1L, + 0x4cb8af9065893c2bL }, + { 0xa2b02057bb4b1953L,0x4ce08b44f597f6eeL,0x854f5d9b5e6412c8L, + 0x1913262db3cd4919L,0x902762e46e42bb5dL,0x8355c8e6d78e7f60L, + 0x8efaa82438b6c16cL,0xd0173790e550f618L,0x118af462e57d778eL, + 0xa16ad5e8715b4714L,0x900596c341dea4f9L,0x2a957c32280ca610L, + 0x2faee800374c65a1L,0xdb10512750080414L,0x8c1db931ff080fa1L, + 0x486a5c25d79878fcL } }, + /* 193 */ + { { 0x0521e213941b4f36L,0xbaacfb14f803b4f9L,0xfdf1e22e52a54ba8L, + 0xacfabbba8fe4796cL,0xae0788db58dbacb6L,0xdf98d736c19dfa51L, + 0x155c286a35a716eeL,0xbe7d46769c86461bL,0x50b6380f63a64a5eL, + 0x14b419149f609262L,0x0919a7d0a2dfc5b3L,0xc454da55cef466acL, + 0x93fa4a246986aaecL,0x5090b17171a49cedL,0x602f1d6cc1fa75adL, + 0x5d269f8978e4c054L }, + { 0x3a74030c14920419L,0x0845d86890968739L,0x81b994c4eeb70fa6L, + 0xabcaa06dd9fc5bcbL,0x06539427f58f8f2dL,0x35c85f67b1dc52aaL, + 0x5a7d8d722c911baaL,0x4041005caec2d834L,0xb5868a447a8e5347L, + 0x04ee180b8de512c3L,0x4daa66e5211168ebL,0xc0bd5dab2317cd8aL, + 0xa1d4185d61164df6L,0xacedca261dbad7c9L,0x0fe4b5ac09b02683L, + 0x8ac9995a26d9550fL } }, + /* 194 */ + { { 0xb2c8dc9b2640a39dL,0x21ff0b38ede0c9f9L,0x74f469bda1ecba0aL, + 0x8a902ccd080d0417L,0xe956fa32f4994604L,0x348f85cf9776ab15L, + 0xc21fc6ee0066f492L,0x35b1ebfefeeef367L,0x7804581c4613e5edL, + 0xcbdfe8e6ea6ba071L,0xddfcaa32950d73edL,0xc97479361da48889L, + 0xce867c8cdbaffbd1L,0xd267431f1cbaeae7L,0x68255045897912c8L, + 0x0c7c1ddcd7ea1e4dL }, + { 0x53aa30cc1ce963a7L,0x7352f64cc4c5fadeL,0x2b9aa2f82828afbfL, + 0x64273c56ca212107L,0xaadd765485a576dcL,0x6196ac3e90b5c77cL, + 0x20d43e9fd1aaf39bL,0xfc392062cd05cbc4L,0x141638724c0ff2fdL, + 0xcf32b8d82ae821e6L,0x5f58f9433fa7a3f0L,0xaebf1d2df644ca92L, + 0x0c0615631918a75fL,0x7989b5ed6b876118L,0xbf342445ad412441L, + 0x24ffc9ae1df633abL } }, + /* 195 */ + { { 0x89fcdc0593c7cb2bL,0xc1243b95590053fbL,0x601debcf6182343cL, + 0x364546ef66c18a63L,0xa5290701ec913287L,0xc35b8026f9788c31L, + 0x852b862a92d1f7d7L,0x1809cb050aa79728L,0x897d467ca3cb2005L, + 0xf20c77c09ef5b946L,0xc3372c42f2241984L,0xda053e0df35bb206L, + 0xbc26c6d0a9c140b5L,0x61cfcc0ccb56fb33L,0x1c3cf9ef299b3968L, + 0x89e4d3d140621ba4L }, + { 0xd35e80e7a45a9be3L,0xc4daa57807356fbdL,0x0186d62eb967bc2fL, + 0xa702679e47cd16e3L,0xca2f1c025f30ce9bL,0xf1205b461f864f50L, + 0x7fd6d79785061d66L,0x47edc4f68a08809eL,0x5dac04499a4d3ae2L, + 0xf844664a6d1f9da8L,0x9f30ce84d7a83a71L,0xe9382baceaac33f1L, + 0x1f033831948622abL,0xb037a4baf7681eb2L,0xd156a90899a1b5c7L, + 0x675d3e6fe6f1d0fbL } }, + /* 196 */ + { { 0xd9767ffd707193e5L,0xe478aa91810358e5L,0x5634f9ff328d8ef7L, + 0x913a0ee86dbbd9a7L,0x379b29687e215686L,0x903f410a89d9da38L, + 0xd9f8d7b91b1334d2L,0x9fe74229bd82efb5L,0xdb568b623803c778L, + 0x93e9a350d3d25344L,0x559c35b0724497e8L,0xc472d436a169e23bL, + 0x09864632cc5b4c69L,0x9f6d759d83c7f531L,0xa91cf1db1e497888L, + 0x5f7f92fe60af1a4bL }, + { 0xf18a1cc60545167eL,0x55ee2e02affa88e0L,0x24cdff51432a7bcfL, + 0x7382da42a7510866L,0xe894c11f40511af7L,0xaa4e4e312aaf1423L, + 0x8c3d36f0f63dd2aeL,0xfc5c9550d7660635L,0x0125373137ea7eabL, + 0x2a5cd59839b950f6L,0x95a0f60140e63442L,0x905e238ef2ac7045L, + 0x44bacc0e446b0f73L,0x4cd4206ec448578aL,0x367b1aaaa5bd7803L, + 0x25beced90a2b458dL } }, + /* 197 */ + { { 0x079a73820c33a8fbL,0xcfbf6cd10f25dc1dL,0x4ffc73f8c6d482b6L, + 0x3e51f18c07bf844aL,0xa7651236599162f0L,0xac59a74e14013811L, + 0x957a6865e55018a0L,0xe1ec51bde3ca09b1L,0xbc0c7eb3a960253fL, + 0xe83bfd147de03f84L,0xc0540ed152fbdb09L,0x6ba52eddcea15ec1L, + 0xf3d30ed54b261307L,0x9bd7bae8e8397206L,0xf20d8692096373aaL, + 0x0a616a4bc3b0bf63L }, + { 0x2075f3ed6e1339c9L,0x7afaa072bf8b00a6L,0xdfafec82bccd9b47L, + 0x4713158f00ca54c7L,0x449102f138bc31aeL,0xaf98f158310dfc8aL, + 0xc9ef207559e954d4L,0xe8021af9c527a0c4L,0x6e8012777a192023L, + 0x635f538c7fb02377L,0x5df1974fe8c9e951L,0x0287faed15cc9097L, + 0xfa0728f0f7a5115cL,0x90dbfbe60fac623dL,0xa8d40fd40311ba09L, + 0x876d154e07c6464cL } }, + /* 198 */ + { { 0xd3a4d6d2c2d3ea8aL,0x36be681ba842600eL,0xc53f100de4070672L, + 0xe3e5b6fe6a7d7a7bL,0x6e6994f95d5e1a83L,0x07cacd2276097c2aL, + 0x12d98dbaa6791011L,0xddfc4461102e0e24L,0x4815dbc2d493272aL, + 0x7e38e64ba9436696L,0x4960eb1a32b2bf90L,0xda457525d928e28bL, + 0x72f75b392a077c9eL,0x27760cbb7fd61d00L,0xaf235d1b0f4b1456L, + 0x3040c23be76d1700L }, + { 0xb10dc55b4efa9a70L,0xd4de414f53e86610L,0x3d95c11309f8a27fL, + 0x505109a506661d3cL,0xcaa2994a60eb513eL,0x3ee415371e7d338bL, + 0x4fd145fc4651e71fL,0x51bbf838cbc313b4L,0xb039e0781eb92150L, + 0xe8696b4414bf5ac7L,0x2d6671888be0d48cL,0xbe93b2f5dd8f2b6fL, + 0xc1dfd1e7eb8a7f8aL,0x862b3dd990f751c5L,0x1eb1ad58a32a74beL, + 0x5486d79a1ebbc9a2L } }, + /* 199 */ + { { 0xcb2e34ffa1359e13L,0x202d8dbf28196051L,0xe95e023d23564b5eL, + 0xfb1340b642f6ac12L,0x543ba852b653725dL,0x81aedcd68d2466adL, + 0xbf780224547c728bL,0x559f8a119569fb65L,0x505b7a62dfb22ec9L, + 0x071075409eed5e52L,0x9c899288299f6f11L,0xa7d692613db6f8c7L, + 0x30eb7fb3b3ca79a9L,0xcab99bb8fb2160b0L,0xd2012568d28b409aL, + 0x380f1b0f5ac45f8bL }, + { 0xc0b99e6be6a0068fL,0x4b67cf2ac8a73753L,0xa6c9a548b2faeb7cL, + 0x7f417f99340260c3L,0x8ee56855cc0f739eL,0xf08b510f780949daL, + 0xb1770fc28d5c6effL,0xb4f5abeefd96a7bbL,0xa07b1136f2665a2aL, + 0x2fb380a4b601dcf9L,0xcc803614162becc6L,0x3498fb96ee6b83b3L, + 0xea9b0fd6a8c17eebL,0x5834b5baa177efc2L,0x929044f55b110b3eL, + 0x4abeddedebd7285eL } }, + /* 200 */ + { { 0x3355e1b9700ef376L,0xd56e5d9a66cdabffL,0xb3dc257547e87646L, + 0x28f44b8a00f79369L,0x08c32b1ea0c52e29L,0x5a78de123729b392L, + 0x4184519ab26d239dL,0x23f6b4b7e0ce4a6bL,0x235f6f8aacb2a9f9L, + 0xbb8bc454e2064a59L,0x37efd0341bf3062eL,0x6bac683b94dff6f9L, + 0xc3364b1e8aa7fa06L,0x0616772ace0b3745L,0x46f08d08d1e3fb0fL, + 0x6a20abb318e132d3L }, + { 0xea8310166a85cbc7L,0xd0990946934f9aa7L,0xc2211088e778f1b3L, + 0x7ea4ff8f2247b799L,0xb3171d71454484ceL,0x294039494f98c364L, + 0x5da911f397df1458L,0xa6b5809309439116L,0x75f9509a174238bcL, + 0xfeb518218209758dL,0xae0c6021a47925d0L,0x0e946694af8a315eL, + 0xae7af8a36bad04b7L,0x44c15e7ff072447dL,0x5184668aa5456ffeL, + 0x45e353a7bf36b977L } }, + /* 201 */ + { { 0x7605676493092f71L,0xeb66b6c2f5b92d71L,0x9db3149be2c8b6c5L, + 0xf62f583a20c0363eL,0x688acd3303cd7097L,0x85d0c0f8ebb916acL, + 0x1bf7462c84c19b0eL,0xc76ed5f97c4a6ad1L,0xec8b88bad119f369L, + 0x59b8371bebe50b83L,0x0cc69508866706a6L,0x531c75a3f8373d2cL, + 0x4e1cd3a32a5a02fbL,0xe8274778da39a1d0L,0xedfc5bbb75da333eL, + 0x15941f24ca79bd36L }, + { 0x42e8c0f8a77dd512L,0xa91b59a71dc365f6L,0xe80d14cd08753862L, + 0x1624230dd272facaL,0xeea3ec164027cb5aL,0xc1700b59c1ef9f03L, + 0xd411c1270da3148dL,0x801ee448c4181af1L,0xedf285599e3a900bL, + 0x5d67b0bd0d09affdL,0xd839df968b370024L,0x3b6307e0e6f836b8L, + 0x5382e588bd3201c9L,0x636d8a6b7a1d02bbL,0x70b7db76968641e9L, + 0x6d17c34a118fad03L } }, + /* 202 */ + { { 0xcf608841c181c99bL,0xb65dc901c87bdcafL,0xb460b4473720dabeL, + 0x4c79c3965377515bL,0xd447f22e0a96c277L,0x0d9521302ac0f440L, + 0x8330b26bc90583adL,0xe25e977a928904a0L,0x1deaffd985c50b18L, + 0xcf4dbcb7a5ad5f6aL,0xcbcd0019c8a37ed5L,0x7846dd901e9850b6L, + 0x1ac8194ab0b8e605L,0xb972857134132f90L,0x4ce9f149f56ee28bL, + 0x1ab9b5a43e9e1d4eL }, + { 0x206dab92314fa7a3L,0xcc4af0f0478ff963L,0x4cce1713904d9fdbL, + 0xac20a2eb12c045feL,0x44fc5478fd8f6d7dL,0x886e72c5ca7b6ffaL, + 0x7fa4529b6fd6f758L,0x4df1d1b192a820d5L,0x3d812f9f2789f149L, + 0x9842f083aabb53d2L,0x2648539b2a03ab32L,0x631ce090b1512502L, + 0xe1294d15731f6bd5L,0xb229361d9436e634L,0x8c4281c43ca966afL, + 0x24b34956c21ab3edL } }, + /* 203 */ + { { 0x49bdcb86659824e2L,0x6dc4ce484e13e74cL,0xa4c01a266bbe1eeaL, + 0x47b2b8e71e3ec457L,0x7e8b15e02f5a8e4bL,0xe81eb6e6e333530dL, + 0xacba369e17a45202L,0x81241431d70e4c9fL,0xc190af4b3e12beb8L, + 0x5327052311f486fdL,0x9f6c41e129fb2bceL,0xbe6287ebb70f6c08L, + 0x1479850a3feb4477L,0xfcfdfb119bcf18bbL,0x925c292fda80d040L, + 0x212d65e57e3c5bf9L }, + { 0x23adb386ca15cf08L,0x4dfa4ac481e172ebL,0x9d1dbf934d42d0c0L, + 0xd9cf607374404dc7L,0x60508441e932bfcdL,0x9ae910ca1c682a98L, + 0x9528fc1841ac1cc0L,0xe6a120aedbbed630L,0x94e0e1ec30ccf250L, + 0xfe84ba54e58bbf2fL,0xc66d0b4f9faa4415L,0x0c58f1e7ecee7ce5L, + 0x7a1d43eb6fa6873aL,0x96c6c5a0399f1348L,0xe6ef9aaae6727ab7L, + 0x66afa5549a5c2447L } }, + /* 204 */ + { { 0xda5aaba8c980e91dL,0xa93cf5096ac98efaL,0xb0990e0a8da32662L, + 0x01d215300081453eL,0x2bb0d33e3d71de84L,0x465f6d803e19a012L, + 0x5902ff4c78a838e7L,0x74e2afb71931348cL,0xa49327579cfb057bL, + 0x761ea6423ad03f8fL,0xb7d4c24558ffa40aL,0xb5e9c0d977a87e30L, + 0xd1c5edbac9c84d26L,0xeca8839a3d1963a0L,0xbc6f2f35ebf6bf0dL, + 0x01ef06310d58abdfL }, + { 0x2bf903163ecdcbb0L,0x19e2d72827c1c955L,0x9e5270309575c930L, + 0x0dc1c5a996983930L,0xef9f80ff7cd082dfL,0xcd915075df97e051L, + 0xf286fffe9cc61b55L,0x352db38f80f24cc4L,0xed9b99ec36523ae3L, + 0x109a8ca810b104a9L,0xc2700fe7305203adL,0x2a2ee24e769400f5L, + 0xd595d399ee0c452cL,0x0ab75d6af7f02a41L,0x341080990db730b7L, + 0x0e4f5ffd5e8d1202L } }, + /* 205 */ + { { 0xbd1c64440ff14c38L,0x9a5b59faaece11f2L,0xaa4605a722af6330L, + 0xddc9f65a82af24eeL,0xf4ee4bfeeb9a1159L,0x2463d07674e84eafL, + 0x88cbe1e00e0baaceL,0x7ca568ead5fabdcbL,0xbd80d524c57eb99dL, + 0x9c46572ce9be9873L,0x918a1dcd7300b85eL,0x4922131240f54176L, + 0xf7e324ffb5b14236L,0x40dda5012434f16aL,0x08833421a133d97cL, + 0x33d411610876f020L }, + { 0x7531a36b9878e5ecL,0x5de3e32146918232L,0xd15f9a33d0a30464L, + 0x734c1b87aa173659L,0xac2094a2f925d4feL,0x43c965a1c262b0f4L, + 0x759c903e447d5cbcL,0x92af215e05239300L,0xfffb6d5f1f593f34L, + 0x65943b4bc3cddb5fL,0x9d03a29cbfdd5408L,0x8f7cda6b198d76c0L, + 0xc0790a22c0f27b59L,0xba557a848cb58ccfL,0x5922052d76c54fdcL, + 0x2d3de7aa47b6b466L } }, + /* 206 */ + { { 0xaade746265add3b7L,0xe5888f35abf24c2aL,0xd41549cae1a57d93L, + 0x0e22e18e2c76f7bfL,0x67f288eabe3202b3L,0xb79a66ba1d1d0f0aL, + 0x0e0ab7492881ad18L,0x7d424086c7adb0e9L,0x870c32c52842132fL, + 0x858477f158f9a09eL,0x422a9372ec025589L,0xbe428c5ca5098777L, + 0x45b7956457660058L,0x6c7fc631957f37cfL,0x8b7023ddd6316289L, + 0x47003bb65b1c12a6L }, + { 0xd99401c1c91c1c96L,0xaa5dcdf927a12970L,0x3ab92e17c3c29107L, + 0x26fce8f7a3fe4710L,0xb0d09d5e4ee998eeL,0xafa622048e3a41f8L, + 0xb1c012a5a26ca506L,0x2c6f734c99b57252L,0x1093d79f512f7fe1L, + 0x2f30906eacee19a6L,0x6bff8381056d1ea6L,0x61c75856eff35f21L, + 0x6e07e978c1ad2224L,0x2cca6ca16b20fde8L,0xab4d6d2d633fe81bL, + 0x73dff504b06a2ce6L } }, + /* 207 */ + { { 0x8b615805d8e20fb8L,0x7c6873e482b533f0L,0x5205f00156a854caL, + 0x87fec6accb369211L,0x1fa3c0ecc7f092b7L,0x5b36647ee845fe4cL, + 0xd4781e85f8b1f112L,0xc65268398b0f1a6fL,0xceeb8c6cdcb8eb92L, + 0x133f0ead8e5f6d52L,0x31883e23c8d934dcL,0x214ed5bd428ac45aL, + 0xf77ca492dbbfca85L,0xdf4113fe07e5ae13L,0x63e4a0d272ab05fbL, + 0x7544d0b77148f535L }, + { 0x4fe8d13480797aceL,0x216d6aa0af86d97eL,0xdbf0a688ef5a68fcL, + 0x18b26f459f9b2684L,0x52fefcfa8999d2fcL,0xd5af8d8262423955L, + 0x8f123469f63a3780L,0x2933454fdcd4feafL,0xba8018b7a73b5d09L, + 0x9af1f276e5552c18L,0xc5d4773dff26bb1cL,0x9ef4941006dd4f44L, + 0xad8f12f95f39ba49L,0x5767f6dcf66ca4f2L,0xba8773f17922f59aL, + 0x220081eac1e42d49L } }, + /* 208 */ + { { 0x3043d573ba37a0baL,0x05a431bcdd176df6L,0x03322cfcc42070f7L, + 0x5cabd30e67c2d109L,0x362c95decbf8bcfaL,0xd767d2777787b10bL, + 0x612c915e6ec05e64L,0x9e669631ce69c30eL,0x27c9dd8f682e2635L, + 0x79021f1295ffcc38L,0x06a8ee798a2adca2L,0x8e00e7844b5d500aL, + 0x87746fc78d80d6c5L,0x246053be915f10ccL,0x844e328b219f6fd8L, + 0x620541ac11bd3733L }, + { 0x0f7fd382509e5a29L,0x8748d7d0b432531eL,0x8f749354cd3883b9L, + 0xc6b8ac748bfbb17aL,0xa4616a6605f2d2c5L,0xb3d966251bcb1b83L, + 0xcf7531042fee265aL,0xc70d73fbdb225058L,0x1211d434f0c2d556L, + 0x862061d854b259b3L,0xffe4606dc42b3f7dL,0x4c5c8585e86a4949L, + 0x04ddcc8b160eedacL,0x1804ce67568e2420L,0x91f3855a42141656L, + 0x7f378198f932be97L } }, + /* 209 */ + { { 0x9a374bdadfa6639aL,0x0cbd48d402ab7391L,0x5c5ef23647031e2dL, + 0xb49ee2bcd0599d1fL,0xd285eb60e0d38443L,0xdbbea92f269392e8L, + 0x91455fbfb8bc538fL,0xae259ff1e469b768L,0xc1cecb1f41de5682L, + 0xc876f0719952d1aeL,0x1ce25181e7bf7446L,0xcb93ad86282ad2f1L, + 0x8fa3cd316ba4ef67L,0xfce68a04e507aa3eL,0xced74170a61bb608L, + 0x6de716b3f6ac10d0L }, + { 0xd4e58d04172d6dc5L,0xbed2cde66397c65cL,0x7ae77e180c9eb4e8L, + 0x5627546875fa2edbL,0x4b30324ea91e6738L,0x6023a856235c8b2eL, + 0x9df6d6c2a8f92887L,0xec2c185ff6f5e8b5L,0x7892e12b3ad5748aL, + 0x7aebb4f2d54aefbcL,0x14915448ee868821L,0xa26c5f71b1d9bd5bL, + 0xe5ccd1662ff00df7L,0xebc99f17b95b1deeL,0x909836163fe1f774L, + 0x51f90830bb3d25b0L } }, + /* 210 */ + { { 0x49376fa1f2922461L,0xdbb1b1c31650d0d1L,0x92b91c330dd8608dL, + 0x3e612c4b36b89906L,0xe1977b0bdf560052L,0xf8afff70636a2545L, + 0xcda7d27811723d8eL,0x0b0bc4bb81bde7baL,0x3cb080b2ed2a578eL, + 0x5bda0d0d171b2e02L,0xf6df38cf941bb9aeL,0x85dd81dbc14a65c5L, + 0x7f98c82dc19dd98eL,0xc613747f52206f93L,0x9e13a2c25f5bbe78L, + 0x5eed218e0aa34be7L }, + { 0xe156575401d4dc0bL,0xa1ae5f27f566bb07L,0xe985ebebb82225d5L, + 0x5f3ad21c1189ec6bL,0x17da518cecce4d9dL,0xc84a2d3ed6b65b59L, + 0x7f9881758ffa771cL,0x50d6ae122ac69a7aL,0xcb7f30b1c6e6846dL, + 0x8c023a605bd0bb13L,0x9a10fecdd73f2407L,0x8c5158cce5f0a996L, + 0xd26bf615bd8f5806L,0xaf32ea87915a46e1L,0xeaf74e810287d308L, + 0x8c14ba06a6264254L } }, + /* 211 */ + { { 0x0c877895b17ee201L,0xc05aa47188e57a77L,0x19c3e76397822456L, + 0x0be6f8c0c9c3ba1dL,0xfe85f4ffb4389ebeL,0x538bccce0ce7fbb6L, + 0x876eab2a65266c64L,0x5c9ac690cf9a3842L,0x9f5cf3b1ccc8f981L, + 0xfa17be6a9cf687deL,0xfcfc10fc83835c15L,0x086b0fdb150ef2ebL, + 0x9f97ecd9884a52e6L,0x416e6fa2b0cd1eb8L,0xe2bd15993ecc03baL, + 0x645c0a5deabb165eL }, + { 0xd94c420550aa7e31L,0xaec8df0c2f851da5L,0x996469093c726e6aL, + 0x72dbdc362619bf9aL,0x1b4260e0e253fbd5L,0x97c259fb8c709e06L, + 0xfabf7cbbcddaec5bL,0xb4d5e8b1e4b703e9L,0x1b06e56e0734efddL, + 0x02d4a4f91f55f8a5L,0x7f8608ba3f565c8dL,0x822f47d2816d1d94L, + 0x0cc361565ce7b136L,0xe46ee5ef31d04242L,0xb2a65f70683567f6L, + 0x27e9ff40d2fa6c91L } }, + /* 212 */ + { { 0x75251893d7e952e7L,0x15b30583c735bf18L,0x732b599296fe0491L, + 0x27451858806d2fcaL,0x71ab76a01b885ed9L,0xbdce9d976d9f55ecL, + 0x3da60b2048f2ba9cL,0x6977c086592b132bL,0xb6dca9cb099051d7L, + 0xd9c2ab23d188ae25L,0x9f469f3fe20aaf3dL,0xdbd1f7cf5aad74d0L, + 0x3d5efe5c22a9eb3bL,0x8c5edfa2137010c4L,0xada2217b57870260L, + 0x4feee5673dac9776L }, + { 0x30e18d52b5d3d780L,0x4dadb5d307166744L,0x320d386e5a742156L, + 0x5d8c290e8d6bbb86L,0x981a43232d263dd1L,0x33d0e7ca98984636L, + 0x5138784da519acb1L,0x832e3fabdddc81ffL,0xfc2785943199a43aL, + 0x5b4cabcf32743163L,0x9fa010bd74f94fa7L,0xc28a743d5694a627L, + 0xc1d2a888cb657a24L,0x7eef2503e86a25eaL,0xed11a5d304c561ffL, + 0x4fe818e79c9ede0eL } }, + /* 213 */ + { { 0x00252c9d7fc1c7ffL,0xa9bd419d9fa89ad1L,0xc93a124a4064e9ccL, + 0x384cbcb843942eccL,0x004c21fd8749695bL,0x69c81d9f421165bfL, + 0xe2325628dde01102L,0xec9374575a9b004dL,0xfb3346bff6dcfc21L, + 0xac4da64b4d372c7dL,0xcecb7ad3f20494e2L,0x562c41b5e867c150L, + 0x299395cec2b723d8L,0xc91adfc57ee53231L,0xe06f1161f10b6597L, + 0x81915529b74d3ffcL }, + { 0x8ec124316ed9d4eeL,0x3dffa154689aff01L,0x4aba349f2a89a3f4L, + 0x2db1e8e2d467efb2L,0x18dea354039102e2L,0x422ab853e52f082bL, + 0x7130a2c1ed36dd47L,0xca60e86d0295d1eeL,0xe6ac68087c7f5ad3L, + 0x0f83cecfde864658L,0x72e66c21461d1265L,0xfeef4150bd385099L, + 0x0f183f3aa6632289L,0x275454be792dc795L,0x2744c11b11367702L, + 0x7d06bcc7e8ea6ef3L } }, + /* 214 */ + { { 0x892859427090212fL,0x691b7d4c5521e844L,0x4c038422be2dbb92L, + 0x317721edbd81f880L,0xc136cbeeac89bc36L,0x4f71b60b7b8f004dL, + 0x269132d04e218ab8L,0xb0e2496ee6cc814dL,0x0b2ce31775fadc15L, + 0x82e3c08466d223c5L,0x9721caa64c612f8bL,0x59a751eba4b65355L, + 0x3433aad5c7d3d9d1L,0x1e61b9d2e80d4246L,0x149f655ffc673caaL, + 0x48b52b99d0f9cb92L }, + { 0xa3915399efdc05beL,0xde70db1813e095e9L,0x447862e9cddb3fdaL, + 0xa2b031621a009451L,0x4b27980c23920ea3L,0xac5394f1a23b8febL, + 0x163f72563e5616d4L,0xaa0ff93fb714219aL,0xd26f96d293d62474L, + 0xdd212ea87dcfe276L,0xab27bf2f47038d15L,0xe58c8325f418168eL, + 0xe3704222b32a989aL,0xa3694390bfc9f13bL,0xf16e26060d0684adL, + 0x17c0de879d8c76ecL } }, + /* 215 */ + { { 0xbca5f453dcc01958L,0x7d9459541ce88393L,0x5e6350a1561f5b6dL, + 0x291c3c867e2d36bcL,0xf6c7ed84a5ac3a6cL,0x7913c40bd98006cdL, + 0xf78bb0875671ec3bL,0x1c928f6eb43e89a9L,0xfdf28df3ae1ea1edL, + 0x62bba5b1b924b2b5L,0x491d27051a116e05L,0x08ec02b7167ed3e3L, + 0xe291cf7b5bc0b046L,0x30e501698c5d7f59L,0x0c7c350df5c799b7L, + 0x6862b9e20ac6e1d7L }, + { 0x56c6f4e79ffa1f64L,0xfed6a91aa1e24349L,0xe9a0ee0ccdb75232L, + 0xbfc90b370322d607L,0x29480ad2462fef87L,0xfc214969c2bfcf34L, + 0x6e5211e0a539e38fL,0x2a59ec2612a5149cL,0x195fe212d706b532L, + 0xf77fb108e99c8429L,0x74ceaea35dc80482L,0xa5a6030bbd92d298L, + 0xad42dca5aaea15eeL,0xd6ac3bc74987109cL,0xc64e1c40290af649L, + 0x5093fa2d51f8de6cL } }, + /* 216 */ + { { 0xc4cf32804c2d553bL,0xdc1abe223b966c29L,0x556a549c2296914aL, + 0xd8c9f8b5999976c9L,0xc22c57bd776e83f3L,0x4f2942ab7c85ec57L, + 0xef3407e56e2c61f5L,0xf005e8caf213db48L,0x470c853df32698c7L, + 0xe6f488d7cac0a54bL,0xb6bd6bed60b7501eL,0xf0103106714a4bd9L, + 0x5285bc3b6e098894L,0xec06741af5f92a00L,0x32f16426ef7ef24aL, + 0x12f9c44d6c77a438L }, + { 0x1951e96483313a1cL,0x98edd3da33c58b37L,0x4edbbf52c7ac4044L, + 0x866ca6f70dcb5ee8L,0xec0ae8f56dd422f8L,0x1077bc540661ec2eL, + 0x6d39913ad422523cL,0xd105e1e858e7cb3eL,0x47c9397fc979bb45L, + 0x3221d4a90997b592L,0x0ef628a3e8952fe7L,0xd08d58274e946241L, + 0x64cbed0f59780f40L,0x13d7c22708e110ecL,0xd186d8667679b1a3L, + 0x02f75e4e26ae1d18L } }, + /* 217 */ + { { 0x1b637ebf47f307d7L,0x6b644a6ad0141477L,0x82a33d652e05a80cL, + 0xc8f1a0f3fed07b31L,0xc09ee7f93696e597L,0xcdaa7ec3c7ffc01eL, + 0x549f88fef8f373b9L,0xc88d1961c3bb8989L,0xd92a4fe9dfcaa7b7L, + 0x12ff9ee23ae4ab20L,0xf5aea641f5ecb1a5L,0xe769237fe32fb47dL, + 0x96a5c42025d085c0L,0xdc91255826c755a2L,0x580b985f9bce9723L, + 0x72b1b56663961941L }, + { 0x9d708a08790e5558L,0x985360410689af80L,0xe85e7b8a42313b5fL, + 0xe6ba129255a49d1aL,0x5e76c4b0ac371b0bL,0x58504f39938e6e19L, + 0x8dd4142260ae9a21L,0xd8b04e9b968485ceL,0xf94c4ba5887efe43L, + 0x11268e67f11c5e73L,0x92623e28cf6b99c4L,0xf2d0aaa87a0a9662L, + 0xb266772a4ca02ed3L,0x68ee8e4e2d63b551L,0xcdebb2992e78b5b5L, + 0x5df19216e17225adL } }, + /* 218 */ + { { 0x20027e1e8df2e7e3L,0xb183cc68d8da07deL,0xce35ba694b4ae694L, + 0x896d97df3ca62e88L,0x3de4713b52efed2cL,0xd006c40e26bd084fL, + 0x1e9b71bbfc81923bL,0x9991c7b61aacc6b0L,0x650c93648f656840L, + 0x138561d187f47524L,0x610f2b11bffd3ca2L,0x96915faffa191418L, + 0x8f1236de955e5309L,0x613cbeeaa1872d79L,0x7f7b44ea66a2a48bL, + 0x452265c2e0a89c32L }, + { 0x4ad5ec7925430010L,0xcac786ffebd090c0L,0xa5f9f4ff20a9d3f5L, + 0xfcbf4112a3edc65fL,0x8824839c0cf3eb11L,0xb8dd6d4e8aa5b700L, + 0xe2271dfdb7568ab8L,0xe43ec373b744560eL,0x78eaf9261cf75296L, + 0x1809ae0e3fa96d9bL,0x0b312d2ddc25dfd5L,0x6b8f78b46bab7711L, + 0x069efc8db5ecf1e4L,0xc1952bae609fecaaL,0x43e302ed5f4dbde1L, + 0x14b02bf91e078555L } }, + /* 219 */ + { { 0x2c71c768b87e5b57L,0x0bcc78f7f531a557L,0x4ff93f8bf7597dc8L, + 0xb28e026d139e175fL,0x6b83b727cb94ca6cL,0x2eafe3b20079f7fcL, + 0x2aca54decf3bd170L,0x17c4133c6af0dc6cL,0xbea1e665ccf5e35eL, + 0xa6691a48345505c6L,0x2633abd0e6100b89L,0x966c6706c17d0388L, + 0x7aefffbe1a0cf90cL,0x4d847be7d0add64cL,0xd49bcdfbaea2aa46L, + 0x85e07e742cc7d0a5L }, + { 0x23aae0a60bc25bcaL,0x6e8e55f1e44f64ecL,0xe1e696d8b607b773L, + 0xaa90a746d3005909L,0x072b1ccd2cbc4990L,0x0d0fe6c6c68e2f5dL, + 0x920ec5f053e28ec9L,0x79b21fb4f0040cc1L,0xa7375bd3fcc4a2c7L, + 0xf5f5def9e1bac7ddL,0xdc315d7935c0f8d3L,0x7117c1702cacd318L, + 0x6f2823c4e926f71cL,0x38db58bbed02f39aL,0xe5b492317db69323L, + 0x0964039f8d49f430L } }, + /* 220 */ + { { 0x21774f1656999ebaL,0x3d8ee287b1de6305L,0xd81af726de0b2669L, + 0x374469393f8942a1L,0xbcf6b615ea03e13cL,0xd30c0c3594e273cfL, + 0x4fd33a56c6725c56L,0xa57534ada8be97a2L,0x799242a67c22a251L, + 0x4e51bdb59d0c5c49L,0xd7cd76ccc6a42768L,0x914097acd426bf59L, + 0x59404a2c66e9beb2L,0x4738fe985c96e3e9L,0xbcbb3e0eaad666d0L, + 0x626b0fd263bc5e56L }, + { 0x47217dbae1a1ec42L,0xaa6ae7dbab5acc50L,0xb7e1ab1e865331d1L, + 0xb84530703d30126fL,0x280649e0dee61851L,0x8806f4a3ea689544L, + 0x4bbe43adcb56f632L,0x036b9bdabcaff94fL,0x0d941e65bd0637beL, + 0x82179d44686f3abbL,0x1486912caad6afd6L,0x9a3b891eff7e1534L, + 0x88c426ceeb86fd96L,0xb56e6a81117928c3L,0x933e713596399e00L, + 0x09bbddd9a17b6ac1L } }, + /* 221 */ + { { 0x75e39c1de4fd3673L,0xf880d9d1a65c8e07L,0x4725c1dc7289c7feL, + 0x5b6735ee3529d200L,0xc1f8f2ed3c747af3L,0x5cf3998f912efdf5L, + 0xed72261849859c39L,0x23793a2f0e69795dL,0x8a6ab8d686b1d2a7L, + 0x00c815de22a882e4L,0xbe77d6fcf9db8d7eL,0x0886fb3202267547L, + 0xb62687d449c10edcL,0x9f1c3e177c83ed4cL,0xe6d5d7f05af366eaL, + 0x2eaa01b8d1efad24L }, + { 0x5e47fb701f357c74L,0x93085c4aa9e3b794L,0x4f0987336e85a905L, + 0xf53808ffbe0244c9L,0x91dddf93a3b5660dL,0x8b76377bf3b95ed6L, + 0x91b911b7bb3920d4L,0x7ccf08bf86a13cf3L,0x53ed8f97ea018e58L, + 0xb1ea434378c55194L,0x8e6adde9e0d2d5a6L,0xfc2b248f9b96259aL, + 0x96ebceaeeef17dddL,0xf694b443557f9c85L,0x48cd150f07d5bba8L, + 0x02d31de9b4c1986bL } }, + /* 222 */ + { { 0xa6bb9e1ede79499dL,0xf6ca8ff8fd0fc2adL,0xbec0f8e81a7d9356L, + 0xbc3d1c9fe8f06327L,0x805c72173b300bebL,0x00420a08413c181bL, + 0x9e9a167ef0ca9d01L,0x076c909d1aeeddd6L,0x64a1997f8e3a8a72L, + 0x3ce7f7a7a77b429eL,0xaac0fbf45c94d3e9L,0xf37694a7e6d48407L, + 0xf56679e2a91921e7L,0xf23fe0f3ee1dbbd6L,0xc7917566cbf9fa99L, + 0x965860f2e0f4d765L }, + { 0xe734702b7fa5f79cL,0x930bd4265af2d26dL,0x45bd8b986c73e0ceL, + 0x7dbe7bed4ee44a2dL,0xc129e024956c8a1aL,0x6fdc05ac77cdf80eL, + 0x70a6ba2b589ca59bL,0xfc484021999825afL,0x1d284b547a23f0b6L, + 0xb1da10a428a0a8afL,0xb1eb1b312b2af6d8L,0xf051443a33935ee3L, + 0x7a07eb268effa6ecL,0x16ee4086d662654cL,0x7a7bc5014549ee4cL, + 0x650810321fa98a52L } }, + /* 223 */ + { { 0x49f0e460b67ed9b2L,0x0cda0fd0c36d93d2L,0xbb5963e988c75e1cL, + 0x757bbe93614bc0c9L,0x9a9b88019a768605L,0xa8b7e2af48edc544L, + 0x9e77ed9eb51a5985L,0xdd025274ebbf024cL,0x598b62881545c636L, + 0x39bdaed04800dba0L,0x7fc2013981e2a23aL,0xdc66fd5c550cb4f2L, + 0xad27032fb52068c7L,0xc9a0bcae8169fa15L,0x60606f213a7ca8a2L, + 0x982950469862652fL }, + { 0x3e3746002e11c128L,0x80dfae5d0e6dca7eL,0xe44016e2d9552264L, + 0xf65f88f2880b7143L,0xca3d28d4526b881cL,0xf9c59dd1dfb86afeL, + 0x548860c24c74f958L,0xd06ea43c9cb69f4fL,0x5343c9ae7334ececL, + 0x5cc2ccd635329713L,0xa95ff4035f3a6c0cL,0x2e01a1ccb372653bL, + 0x31510fdfa250523dL,0xeee538e2a6227eb2L,0xeadfc8a0ca23cd10L, + 0x4b7e6e1b3e78f54bL } }, + /* 224 */ + { { 0x79c9076fdb5f928bL,0xe6250bb6b7347cecL,0x54b67798ac00ec41L, + 0x900d20ba9d9619c7L,0xed42c0d059e4343fL,0x3df39e85451935d7L, + 0x2639118264f701ceL,0xce8f2554e1f87aacL,0xfddd678965f91aaaL, + 0x96cd163fa324539fL,0x5c815f2c4bace995L,0xd78c8c2aa94f9ea5L, + 0x7ab2aff4ef24e455L,0xf0ed64091cddc26aL,0x954a420b00ca2822L, + 0x0611c4c5d3297658L }, + { 0xf192001ca9e81829L,0xded3332008a282ccL,0x0bfd7de18f9ded9bL, + 0x6793ac0db7889003L,0xbb00d91d3577a5ddL,0xe17a23a7802d3c2bL, + 0xff95f88cfb549014L,0x7cd1bf4bc71b6e07L,0x2e3b24a023588c8bL, + 0x9b5335b8a4112076L,0x2481c05ec4056d30L,0x55c7410ce916a1b5L, + 0xbbe03271850179f4L,0x15e6c177b3cd1208L,0x509a24c090cbfe50L, + 0x820795291c108566L } }, + /* 225 */ + { { 0x5d2d3cff1c7d353eL,0xd5e7eccd7de0ce3bL,0xb4b1075f6ca87635L, + 0xda8404e025f9ad3eL,0x6b963e89205cb5aeL,0x9e5ee0d809f221a1L, + 0xd64c85d9ea41aca4L,0x6a46c4e934442a34L,0xac6ff97e3cf655a4L, + 0x76565c1ee5417d7cL,0x681009a9eebf9c4cL,0x95b61d3988da6388L, + 0x6402b46af6b472c6L,0x1fde51650b7f1171L,0x94f8f273be0c05e3L, + 0x7487b036a88344a7L }, + { 0xa860e5759c3e2370L,0x19d58193f8048719L,0x3a0dbf3ca6e2f9aaL, + 0xb6c7e9596144719bL,0xa9049c74deffec21L,0x8ba064b23f50cebfL, + 0xb12822c049a1de15L,0xb654b7d9b1d527f2L,0xc470859d0ffd0430L, + 0x37c74a674f05446bL,0xe553251ba3add995L,0x4a3ed6cbe33533b5L, + 0x2f2f44d027e419ceL,0x2d84ee82a5d1b979L,0xcc76b123db6fa69fL, + 0x834f85c521fa3bddL } }, + /* 226 */ + { { 0x329347c12ce9b31aL,0x1d88522afe3fb3b7L,0x4bcefb4d52ff90fdL, + 0x53b173862b1a081dL,0x538c11ba2a411f08L,0x7895b93c141b603aL, + 0x2993b9aab10bd741L,0xccbbd04609912986L,0x669fafb0eea0aba5L, + 0xd484462235661897L,0x4a63b89c367ffa54L,0xcbad5d1d1c3478daL, + 0xc5339227aa6034f7L,0x0e6d705fe61b1391L,0xdd14b660f74ff515L, + 0x639d8b0a5332b54cL }, + { 0xfa423162162217cdL,0x2e0e4a2a811c28e6L,0x68d9ce1821766dc0L, + 0x51263739046a06efL,0x44eea231dde92101L,0x0607c8f2114298d3L, + 0x27f272ba63d957e9L,0xe7ce80cca5e8cae1L,0x5816ebe224f7a63fL, + 0x4dece5a789673e34L,0x13756a22536babd4L,0x644d61aee3bf77afL, + 0x60b2bf6e2bcf98bcL,0x3b0b59f329fa962cL,0xb0769a1aabb50023L, + 0x409031360c75402cL } }, + /* 227 */ + { { 0x84d2873a1670433fL,0xc9394df625493dfcL,0xeb05a19a80fcf89eL, + 0xe39e4310db297616L,0x50742dc9d9e63046L,0xf31ad8c81de9ca9eL, + 0x86aabf94fb7b1d0dL,0x36cda27a1b3c82d1L,0xfb1a2ef439702d84L, + 0x280bfddc46081299L,0xe4b2b48dd2396238L,0x2db2c2f37b3c9353L, + 0xd5b5b31712fb8a69L,0xf9b87a3b08180474L,0xd85909861e952578L, + 0x80668eedf37a2bc8L }, + { 0xe2edcd35b39a0249L,0xaf230cd4b2f8aeaeL,0x295b15e47223df05L, + 0xbb66982ae0e937f4L,0x019d2b728cbc9162L,0x5c512ae9cf49dca1L, + 0x11b491a7630f07b4L,0x48d4f34ca03874e9L,0xc1fd0ea644cb7433L, + 0x13f79ae1f95b30c3L,0x40362d4ded8b60acL,0x9e8314ff61ead81cL, + 0xed600dd4498c3d28L,0x5fcb1c19c2521702L,0x592329fc3a9c1f33L, + 0x046775481bde6ce9L } }, + /* 228 */ + { { 0xee3de56e39233c96L,0x868c409c80737eafL,0xacae11bd201abc68L, + 0x0f2cea9b2b486205L,0xe32387e16f19056cL,0xea75365aa5dc2a41L, + 0x76c29acc12b4be86L,0xa01fcab78d63294dL,0x81dbe88b0cab9f24L, + 0x76646e5bf414c054L,0xfe111893cb96b7aaL,0xb649f5b17664e097L, + 0xa196422e53fcf5a9L,0x5978c9bd0b7ff634L,0xb5feb38e3c229895L, + 0x038a49fb0833c456L }, + { 0x35e3818c13e93257L,0x14cebc9da612741bL,0x4f6e92497caac06bL, + 0x82278e333daa1116L,0xe7cc565e4de2034aL,0xbb7dc95f0a1ba630L, + 0x81dd9f2366956fbdL,0xc63e6319bb132dd6L,0x6e22b022fc241337L, + 0x238481937e8beb1cL,0x83b1994dd8c938acL,0xb54cfacaa6bb5644L, + 0x1a7cd44e06f91807L,0x1dd439bba8f8d9f3L,0x660c2a787f74a8e6L, + 0x4bb76e22121b5660L } }, + /* 229 */ + { { 0x7a151e8ae6354817L,0x33d494eaf038b438L,0x4c86c68885958986L, + 0x721538271dcbac12L,0xf487af8cc0edad06L,0xad33051fe500e5d6L, + 0x0a711b1bd6e47f55L,0xa68709a78c746ad5L,0x27f172626402f35eL, + 0xc6d08efafb30c130L,0x9ef1c041c06c7497L,0xd0c74ecedcc3e2daL, + 0x30c5f96e092e1073L,0x0f1393cf2aa12b74L,0x245840162107eb02L, + 0x8843d25f7b76f98bL }, + { 0x4e1501dcedb2a83eL,0xbcfe8fb02bb8d724L,0x09020659d925df62L, + 0x3c715dcf42ab6fc3L,0x73c05055a0f09dfdL,0x126745d8e3590aeaL, + 0x5382f4d876ff749eL,0xfc69feefa920c663L,0xde1602119fd711caL, + 0x4219c3bd9075c4d5L,0x3800cbd13ded6bf2L,0x8c7ea0eb6263a116L, + 0x35bd79587d264c37L,0x56e22e457159c98cL,0x71bf2a2dfa7373b5L, + 0x0503f9398935c949L } }, + /* 230 */ + { { 0x65addc6671dad4f6L,0x238e4889024bea1bL,0xfb76c8e2f605d3ddL, + 0x13d5f5deb0d96b89L,0xe0b5ba356601b2cbL,0xe37d491d83e3d254L, + 0xe8860423240c8ea7L,0x374182f3e91c99baL,0x26c2caf9a87ad919L, + 0x4b13040af574f295L,0x5b9bced1944000a3L,0x4ccc57be06df42e7L, + 0x22e8ec504bd1089dL,0x0c53177adddbb500L,0x690d31d29ecfeadbL, + 0x735778fe176668f9L }, + { 0x0f86ee3e843c1137L,0x3c1c42fa3f0b73cdL,0x0e75679d8ab20e3aL, + 0x6f95f1f416242faeL,0x7b88e11c39b092e4L,0x1629403e4c236ac0L, + 0x66105f412dac02e6L,0x74dc28a7862e0632L,0x2118ffb2f3b23c8dL, + 0x1182417c0745ffbfL,0x49b55a044c05711eL,0x2c665b74cefbe4deL, + 0x1cc4c01d97bf7107L,0xb2ca06dac54f0676L,0xfc599daa7450d0f8L, + 0x52e637a61a3182a1L } }, + /* 231 */ + { { 0x481700f16bebc6dbL,0x4a6b45dbf9503d92L,0xc715cd3c5d153919L, + 0x942a1c05e5ad2abcL,0x36a82433ab7b466fL,0xba413bedba13918bL, + 0x698a562490f4e6ceL,0xbb720da6f3f1f3caL,0x2116d41d63471ab3L, + 0xe00d2227303d3609L,0x7fd4cc00463ba69eL,0xac609e4d62845fd1L, + 0x63603b2c80adc9c7L,0xbf16fc9a45fafbcaL,0x41007f7fc4bc94abL, + 0x7c916b4fa74b1698L }, + { 0xc1026f9178bac2d4L,0x8a2e80982601a875L,0xad2f276e0073d640L, + 0x443610c4fcc1fb88L,0x5727b822ca6b291fL,0x0645532c88ec60fcL, + 0x51e48899ed9ad48bL,0x841b48b5f543f103L,0xa6ccb1bed591ceebL, + 0xfc4adf0f9dcf5a8bL,0x3a7ca020b347ddb4L,0xaa1accc2cb44c521L, + 0x773b68280527c0c4L,0xaa374c107023cf50L,0x733d10006b74c926L, + 0x1ff3916f77a8d07cL } }, + /* 232 */ + { { 0xaa218fe4f997939dL,0x3d4dfbbb791583b3L,0xb3a7b5da87f7560bL, + 0xa9c028015da92c98L,0xe1eb4aad46666f4aL,0x2eb17a5114ce9dd7L, + 0xf46a66a4ef8f3076L,0x900b45c6810e546eL,0xf7af22584baf04ddL, + 0x3cc1c8725c84d42fL,0x3093f2258e4c83deL,0x62fade41170d88b2L, + 0xe19612e4ac076e44L,0xf48d734632dd141bL,0xc1b1f759925e34daL, + 0x19ed1a56072b90c9L }, + { 0x9cf7fcde6c735473L,0xaab88e676003bc3eL,0x12187cbcfb199bb8L, + 0xbb7304419accccbdL,0x214aff3cb0f65459L,0x6aec81a36f926282L, + 0xaa82cb329f9d20b8L,0x82f3f90f5773cc90L,0x4af60e6bf62257e1L, + 0xf18b44bfbd4762dfL,0x3948b129db970753L,0xc6e920e97c22c18eL, + 0x393d620857be97adL,0xe8d7382c46b637f9L,0xf6625ccbf1fed1d5L, + 0x6f31e0f968681599L } }, + /* 233 */ + { { 0xc45afe5582b8f204L,0xac0441b6d358b54aL,0x7213e7bfacd5f5edL, + 0x1914c70b139bcd93L,0x714b458196dbcbb0L,0xe9297d351ed35d21L, + 0x8f6408376a3e1f20L,0x150a8a9d2f3cd705L,0xfb36e801dcdd9f6dL, + 0x5a54eb655cf56d82L,0x7610500c92aa5a21L,0xd10d0ae23b089f03L, + 0x491b2079c42b66e8L,0x4af1ae3d0eee8d48L,0x137e4c2841556f45L, + 0x875e330863d8a7e6L }, + { 0xdc80fddcaf6c0accL,0xd5ad1e66bb1e7c08L,0xdc717ae1828585adL, + 0xbdc54340275c7da6L,0xf4b4c852d26b9e15L,0x5f0a1fbf6a05fa50L, + 0xc6f81e47817bcb32L,0x2cbd432870ff2e1dL,0x8a24901667c7f7fcL, + 0xd045acb7b585a6c4L,0x2e972ad44666c057L,0xc74d87cfe6d7d63dL, + 0xf7067d870e274144L,0xb2ca157a8b2584aeL,0x495c5bfb75f0fdebL, + 0x5abb0581f386e009L } }, + /* 234 */ + { { 0x8be62d2bf0c97f57L,0x0fe04871962f28c7L,0xc548a46747b50abbL, + 0xf6b26e0344fa09edL,0xfd44c6e3ab05a96eL,0xedb0032c70e6ae82L, + 0x28bd402bd7e4899dL,0x43f2e9639b7c11c2L,0x0ec3fc0ece913716L, + 0x769b8bc902fd0f8cL,0x9d9cb3aa7cabc3acL,0xe88a889206924cc9L, + 0xa51461aa42609014L,0xc7f4aa8b962e79e0L,0x4ef0210a8b1b3e80L, + 0x705446801bfee4bcL }, + { 0xfab3d713121901c1L,0xe90a2627fead54aaL,0x64f6d285bc08ba23L, + 0x8d99301536ec227eL,0x99a16ab906c191abL,0x86b1cf5bf649ce2cL, + 0x5920675966be3a80L,0x18836279ccba2cf0L,0x2c157b87eff53486L, + 0xbfac98964b223af2L,0xcd0fd4f00aae7a57L,0xdaddb94063218a80L, + 0x3844bb79df88f14eL,0xc1b3e3d4b71ed9fdL,0x6c634a13d6205036L, + 0x6f56aecfb8680a6bL } }, + /* 235 */ + { { 0xb01dc803d9205c5dL,0x68955f7d67123929L,0x3debbffd9d9b6565L, + 0xb844395ed3b1acfeL,0x04328b216094eeffL,0x6631ffa822991febL, + 0x0dde66e6190dd075L,0x75b03c55e8577c05L,0x6c91ce5f91722407L, + 0x9a288a408ebb3a3fL,0x1d376f8a058a1396L,0xf3a594579a6e0676L, + 0x103029c57b71d288L,0x0843f428b44c30c0L,0xd8e6aff8730e0b9cL, + 0x7b6be8114ed644adL }, + { 0x3ec38e4a3d3aa54eL,0x10233943d83d509aL,0xf84aa621243955e2L, + 0x29104717f51d3d44L,0x62d2442c7eca4e37L,0x8c5a523d85fa55deL, + 0xc6f5ccda851da1b5L,0x044bcaa820001468L,0xf7501e68e01702e0L, + 0xf0819359e6a0acecL,0x33dda6adac0ef0b2L,0x97aeedc8fd964f01L, + 0x48dacd0e530b90d8L,0x4c5fad6fb84122ebL,0x2284ec1ed700a1deL, + 0x86f9a835dbca5474L } }, + /* 236 */ + { { 0x0e1d9055450cc69fL,0x50eb14bcc9edf98fL,0x1bb94e77ee7eba01L, + 0x5f7a6737998f8e53L,0x588384e31b16eef0L,0xbb928723d85c5e15L, + 0xfe51e345cbd952aaL,0xc5d0ee287e241674L,0xfdc146ef100182f0L, + 0x0f739e92e7f5be2cL,0x501ab3afb656bd3eL,0xb1552dde5168e289L, + 0x940dfe31b8ee104aL,0x42923603c4304475L,0x9306f114c460a913L, + 0x5bfa9faf03b51f86L }, + { 0x2a23f52c107b258eL,0x989e82bbd66341dcL,0x54a3ced8823cff1aL, + 0xf45b7794719b491fL,0x898c22182433dfb8L,0x0f9dd91cc49250eeL, + 0x50c2a2ae4fa17655L,0xf7aa1ce42c327f45L,0x13a15ad6583b1e41L, + 0x9aa0d5a5a1bfad9eL,0x9b1caa288e1fbdcdL,0xaf9283b6915f7f87L, + 0xc10e4e0c87e81a1eL,0x04fdca561080d296L,0x6acc961612755bd8L, + 0x1b1266aa828feedaL } }, + /* 237 */ + { { 0x4ebc0a00774ee49cL,0x776f6852cb6237d7L,0xfc0544ac5df938a3L, + 0xc3388ec8b6fbfbbdL,0x84ac8bcd745f2eaeL,0xa9c56609b1ece937L, + 0x656fb6ac7de8fa13L,0x5f8ded74a532b871L,0xab0d428baa889f09L, + 0x43b27f2810b7aec2L,0x26426e1efeecb34cL,0x44431b6b9e89c2dbL, + 0xaac4bc5d39211090L,0x926f73684fd81058L,0x452fa691471ef60eL, + 0x33517fdb218d7a23L }, + { 0xa9c33f46593c4a36L,0xac69d71836b1a9eeL,0x55a20c1d4277beecL, + 0x3e8ca24e7e4f179cL,0x57373369d46d88a2L,0x71ceb1cc730702f8L, + 0x8b184d9735eed574L,0x7f4517a20704cec2L,0x7f129d18d7062a53L, + 0x07a4571bb1d77e1cL,0x774ac3098350d8b2L,0x27b2919f61fab8efL, + 0xa7c4cc13b5dd801bL,0xe7e6255b1434591fL,0x349937b85a3592b3L, + 0x31fac63d30c77549L } }, + /* 238 */ + { { 0x2ee8cf1b04913fb6L,0x7e4013501769a6b3L,0x790ebb71783e61f0L, + 0x1e5107f9e27f2ffeL,0x124ba67fedaf89bfL,0x189200e1e58de68dL, + 0x962732a36df5abeeL,0x72cc37cfacbeb4aaL,0xb0c5fa96e93c5a76L, + 0x4c2a317cde63393bL,0x97f65e67830b2d6cL,0x4afc35041be5b96aL, + 0x0bf40a60730ce66dL,0x96a1ba799340d84fL,0x3ee1825407626b08L, + 0x01db35db7ab0cbf5L }, + { 0x6e0fbc2dac0efee2L,0x8406ebcdd71dbb45L,0xe72bde3e19b69abeL, + 0x49cb7e6137e01822L,0xcbb8c01c11458b4cL,0x420b4847687c5d63L, + 0x1847dfa1454c6776L,0xbede911dd1839d18L,0x1b9dc9c9278df046L, + 0x294bd62b881a336cL,0x7f09687993e77adcL,0x7ac9066543ce3ba7L, + 0x148695fd7764eefcL,0xe0c20f0b9ac465cfL,0x636e8d28a6e2cdb1L, + 0x7b6ba98cd755341dL } }, + /* 239 */ + { { 0xcb1d9e03c1881ab4L,0x19c25d55b3168c88L,0xa82d3d47282364ceL, + 0x95994390f161aa24L,0x7838bc00e1ebb2c9L,0x8fd5dfccbdec7a75L, + 0x4dd203c24ff7220aL,0x5ec173b30efeff48L,0x99f1d2b316428b35L, + 0xc06bd9e5056e813fL,0x929172bac0b319f1L,0x6ae0e384fd223b15L, + 0xbd01059e98d091edL,0x6b3168e4a654648eL,0x2211447f3375e798L, + 0x47e8101971eb4508L }, + { 0x7045d45abc8c290dL,0xa33d1355810fb33aL,0x2baf009246fbbf2fL, + 0xacff3f1b385c7cd9L,0xc5b150ece161985cL,0xc6ee0a7f2a888748L, + 0x9d888c8e5e88dcc8L,0x4dd735f2ccb86443L,0xcc1e13b73c40f6f2L, + 0xfc3a25fff3fed691L,0x4cb43b17257ee5c7L,0xaa654f93f32db135L, + 0x44f58d0a02dff2d3L,0x78e3f188a8ca6394L,0x39646ccef3e86697L, + 0x785b1902e0dce87bL } }, + /* 240 */ + { { 0xfcce2361a92f9a20L,0xb7bdca879d64540eL,0xd4739a851d00d7c5L, + 0x067ac8dc2e97c926L,0x2aea3ffe78da6a8bL,0x6828bf5463c51b69L, + 0x76f1c4797155141aL,0xf4bcbef63977d810L,0x75bc4949541bce7aL, + 0xe01f4066d17041a5L,0xd282d5bd87755eafL,0x6e2107dd59e7ae80L, + 0xaa56e166382ab36fL,0x65ee8ef6b9d1d634L,0x99a2160ace4ed844L, + 0x6557c367b7712c27L }, + { 0x561b0268d75b6e52L,0xb0813640118d0e89L,0xcff533306a2eb1aeL, + 0x4e4622266d090894L,0xbb351227b5fc1d48L,0x9365ea0757a3062dL, + 0x4caca37bd66e2dc5L,0x220d7d23b9095887L,0x9c0fd3938c4473bfL, + 0xadff370a6787da4fL,0xef0aebccd057f4b8L,0x205e744c1173f33aL, + 0xb8d1f0a5925a26b4L,0xa9364f49722fbbfdL,0xc891ae778227d284L, + 0x15c40d04a0e08ab4L } }, + /* 241 */ + { { 0x9baf169a2a0e18d1L,0x9971c0174c0327c2L,0xd81a323f7bc262ceL, + 0x2099db8d818ff379L,0x663f663d4cd3c330L,0xef5325c3011a0553L, + 0x9cd70bdcf980a470L,0xe64452d11c9ed070L,0xafbf43f4ac676e13L, + 0x97bec0a6ae85c2a5L,0x2faae550470490c4L,0x0ab97a87491e6ba9L, + 0x4055f537aafa9914L,0xfc95adbb36726557L,0x646343b9d119d6bfL, + 0x788e94a09d341e37L }, + { 0x053a6fe59c53461aL,0x75ec897e08e3b6edL,0xa8f5d2f30768d939L, + 0x9bd6bff6cc213d4fL,0x590c7b4105b0147cL,0x20a3628b7c7b8169L, + 0xc66a086e5bce78e9L,0x3dd4d2824dec1d8fL,0x890acf44c19dcce9L, + 0x6632d875d8435a7eL,0x590167c1ea6381b2L,0xb2259797f0dcc128L, + 0x91a612b446f8d463L,0x42185d78c15efa39L,0xdf55ec37119f6788L, + 0x91b19cc6780dea93L } }, + /* 242 */ + { { 0xebf2709dcb5d8b80L,0x03b96182fc35660eL,0xb873d991055ef969L, + 0xd1ea4b4de47c4342L,0xcc4b9244d54f8867L,0x93b1a2cafd8d77efL, + 0x068d24e7e8c1f563L,0x5f5fabb649973056L,0x83248c500542374fL, + 0xc36de2b53f38e913L,0xed07e8eb7bb680beL,0x964813d7d8f313b5L, + 0x7bb6a069afd2d392L,0xc06d848e0848a31aL,0x6867fb2fe4f0c325L, + 0x3c2ba834067343afL }, + { 0xab62d7759d3ad63bL,0x3f9cab9759e0eb1fL,0x70332a633885e117L, + 0xf22cafcee20b2f9eL,0xb529ba7e49eca947L,0x249542166228d88dL, + 0x80ea23ec39239561L,0x1b8907e7d4370644L,0x4b7fa455563e4e44L, + 0xcca9829eb2a4b0faL,0xd0a720a448060792L,0x8ccdda0c246991ceL, + 0x37a2325b348d086bL,0x566ed509f60aee13L,0x3d30e091147f253fL, + 0x1fa627a5c1073bd8L } }, + /* 243 */ + { { 0xa11222a242478fd4L,0xacf4c6f1670b2000L,0xf71bb04f8359c6deL, + 0x618e28297b93cdbcL,0x96e1bae3230db60bL,0xf17fd3b4965b3b29L, + 0xa58639c6bc7055ddL,0xc3ea92ed4b817d7fL,0x9082b2a6d23b08a4L, + 0x8471228adc17010eL,0x753b9e4620e89d97L,0xcf7e4f9703ff77c9L, + 0x6c3f82452bbe60e5L,0x9e432cbcb80e017dL,0x150a5acdc0a45edbL, + 0x67b8bd054798743eL }, + { 0xe66079b4f4797cf7L,0xe31c998ad03fde02L,0x5aa3763a54caaef1L, + 0x64d9a1fef7649711L,0x7ce0dc73af29b1a7L,0x6661b083fb66ca93L, + 0xbf4d74fe32fb6a78L,0x25f6ef09df00a561L,0x2bc4383f831d1159L, + 0x6d5cc10c536bde37L,0xd4945f9f882cc65bL,0x81f48f13451a99b8L, + 0x140161cd6bac11a4L,0x9d94d4edf18a4a0aL,0x65363165a467a824L, + 0x74297aa9a4c9aedfL } }, + /* 244 */ + { { 0xc49758a4e21124baL,0x99bd8198a87ffbd2L,0x45fbcdd13d6638a8L, + 0x94645ff815f7bf76L,0x5fa6736fc4e6d57eL,0x1eae647592e61db9L, + 0x79575c0ccbdf944aL,0xa3d1304725b31d74L,0x7881df224cab5ae6L, + 0x8dbfd2991a2887f2L,0x23d07590a26ac459L,0x2e589852d8661d4aL, + 0x37b5c13b8a0140f7L,0x0f94199e3fb3782aL,0x722aa0591bc14e90L, + 0x89aab7bad55bbb12L }, + { 0x8b345a96d656bdc7L,0x43bdc8afe176cd3bL,0xd69518b632d64c43L, + 0xfcf364a779b82b41L,0x907b344effb0cf82L,0xf3d0c83c5101287bL, + 0xe9f26a5934cd90efL,0xe5f5aaf207082b5cL,0x4eb72c75ece7c165L, + 0xe9590a81be986cd6L,0xfeef498fff1536aaL,0x04560243a8263d5eL, + 0x940be14f54ae872bL,0xbee7bcc9e3207686L,0xd496a27dc1bc4d7aL, + 0x002dc2975940ab46L } }, + /* 245 */ + { { 0xee533937b69d60c3L,0x260be552fe972755L,0xb11fb78dc0c725a6L, + 0x6982c27ecab2e7c2L,0x4bceedd9ee2322cbL,0x952b19ed122704f7L, + 0x2df4c285854a6165L,0xba40b5bf7b192485L,0xfcbca9500119f52aL, + 0x7467d1cbe5add86fL,0x9bf536fbd9d0f2c1L,0x3c296e34b8d4ebc9L, + 0x0495f8f405a81317L,0x8c59e8d673335f76L,0x0b53d324e0542122L, + 0x4d5645353c3bda73L }, + { 0x7322f8007e5c0877L,0x481b43e60ca9a764L,0x231f4f4ba2c12716L, + 0x09596857ed3136c2L,0xae82632238db30deL,0x652fad4099908ebcL, + 0x0b8d1814af0d231eL,0x2680c54b09cbc349L,0xfd4562f34bf3bf8eL, + 0x2985090b092b595fL,0xe6f39ca45e15fc34L,0x70175191bc378168L, + 0x906944b3845a4a87L,0xacc6d74a82a1541aL,0xadc9bab3b155c8b4L, + 0x1f2f89ce77306c62L } }, + /* 246 */ + { { 0x8253ef419affefdfL,0x05d7ece54cf9256bL,0x377002f2b444e483L, + 0xb189755fcba5471fL,0xc88483cbd5cbe015L,0x254f7c696a0b8429L, + 0x18850bd461f3f61dL,0x7ba210890a247157L,0x35abbc2ed92eeb0dL, + 0xfb56cabe965dec89L,0x9da23724bc55684aL,0xd8ba396f6a7a7492L, + 0xfcb90db72ef4ba46L,0xdd234fe09909b27aL,0xbdf3c16476f4366eL, + 0x09c8097f17e50d47L }, + { 0x6a04b14060050c07L,0xc29e831843a8e37eL,0xcb9429b2bb55e41fL, + 0xed2fea5a2ce60e3aL,0xdc7b1ff3db9d82f4L,0x48ebecc3687d37faL, + 0x79153e32ecb07539L,0x6a60054f57075692L,0x3871cd0c800759baL, + 0x17a7386f30922df1L,0x4e9fc59e83357b7cL,0x1d26b3a939415186L, + 0x912a0222d34db889L,0x6672fcf459fcdb71L,0x5a3f268d44ff3036L, + 0x6f113ed36911e16cL } }, + /* 247 */ + { { 0x52a9df591836f1c9L,0xfa6519f54232307dL,0x8406c7015ded285aL, + 0x0a1545caaf627f75L,0xae1111eeace0417dL,0xfb28bdf6a6113443L, + 0xde9ef0ab52dbcbcbL,0xe9dc181b7813e658L,0x0b1dabdb99127225L, + 0x5f0598e322814c59L,0x5c3b966ed934ee7eL,0x4eb84edab99ba4bfL, + 0xb2919a343c1b55e7L,0xa9addb4994aa860fL,0x1b7220dff6811ff6L, + 0x6636a23bd1a183e2L }, + { 0xdf5d5a2d20587283L,0x0b3822c9ef07fc5dL,0x1786bd550ef6de38L, + 0x163cf90725d1671dL,0x74bf971f1cdb1defL,0x5749e8300842fc4aL, + 0x0e2edbc727f854f7L,0xbb27bbdabce24acbL,0xc1b19cec05bed08dL, + 0xaada123ef7c904bcL,0x02429f1bd89982dbL,0x49d3616e65f6e632L, + 0xa3789fa8ee59fd32L,0x160ba3bafe9f29f5L,0x0f2d3b61af5378a0L, + 0x7aeecc7673c2a6f8L } }, + /* 248 */ + { { 0xf3a4757cdc43b0dbL,0x3d8a4e8598119cadL,0xf8095bf64616c156L, + 0x3e2a07bc4f533e97L,0xa982436739cfc5adL,0x18a6ba3acd68052cL, + 0xbd60e5908a1cec66L,0xae3841a502b1b695L,0x986dff12190a195bL, + 0x2df2beacad31fd9bL,0x7d893224cc728f7bL,0xc38ea7380cf0a992L, + 0xa8439a80586a44eaL,0xede7f7f01615f03cL,0x4824990827a1f885L, + 0x28ec4006b78a7645L }, + { 0xe1820c2ea2fe0009L,0xe11ba5d2f13874e9L,0x97522454c524db52L, + 0x4d4774267fede529L,0x01d3419a9b2500d4L,0xce08a4921869244bL, + 0xba169023dd1be1b9L,0x242c3e5432a301e0L,0x9b56f7ba70906788L, + 0xf0ad2a09c74a8cc4L,0x99cd1841d76f9439L,0xeddafe0b621fb60eL, + 0x056bee54bc397634L,0x4653f860ff7f0a84L,0x6bd4876f2011c0afL, + 0x134f4cc70c9525c3L } }, + /* 249 */ + { { 0x9621a3ece938dff4L,0x7d101a7b486a79a3L,0xf2c4ef97de950537L, + 0xf3184099e65d87dbL,0xb89c7ffb373b8cfaL,0x68baa505e842916eL, + 0xa790fd094ebea764L,0x679df6d4e592892bL,0x2023331cfcfed741L, + 0x0bf4efd29880ff21L,0x7ca78dddd0344501L,0x2cb09ecb342858c8L, + 0x9e5eb6dc2575487aL,0x50675a15ebcb0491L,0x09d2e74f7381d471L, + 0x6ea3782983d3d6f4L }, + { 0xc65c094b4e5cc40aL,0x7a2e3f6a1af37dfbL,0xef677e9df9026e44L, + 0xb7878c9593880f53L,0x4aa30b077f644aa9L,0xa0c516832f208c3cL, + 0x7c0277ae658d663bL,0xef0b3c38ae1d9130L,0x302f37a7695c3ea4L, + 0xe004c1c56a0c5e0dL,0x9fd495c420cbcf9fL,0x706d5b9d568a0e7cL, + 0x8b225dff59286454L,0x527d44658d9a709cL,0x47c558da87c08d68L, + 0x606ee6e6bb4ef07dL } }, + /* 250 */ + { { 0x02d99fc757c621f6L,0x292e40c17fe83d48L,0x1bdfc7a19ef199b0L, + 0x78a04102e62c7666L,0x16cda370e6738753L,0xbc81974d1e3a65afL, + 0x19742048f78fe209L,0xc83a058abf5981c6L,0xf26b24349c89702dL, + 0x988b2f1e9d1a678aL,0x472bf9b0ff29ae29L,0xa143e3981d7cf5ecL, + 0x9c9d7e45b268ddd8L,0x166cda555fc4ff76L,0x6044cdf0a4aa7673L, + 0x49dba6f7e9148707L }, + { 0x20e47fb2a758e37aL,0xaf6b31d72d8eaf66L,0x352ad5f96f9c2210L, + 0x0093f72790efc32bL,0x435c99dc41e4b264L,0xbfa878e005b15795L, + 0x99c520a40e673575L,0xca68259487eea759L,0x029f7b81f12a348bL, + 0xa547cc182aa2ce35L,0xa11d874bead5e2c5L,0x9af0349b55682cdfL, + 0xf86ebfea8bbe8e66L,0x3dab8782f55394abL,0x458bf797ebc8eb8fL, + 0x4890a7a49b7de78cL } }, + /* 251 */ + { { 0xd72996898da995f6L,0xd39eaae7ec6156efL,0x6959040c356a82d5L, + 0xb2046b21c135bcfeL,0xea720b640f595c78L,0x02824efae7c5fb40L, + 0x97d8fd4c0edb3bfcL,0x12f0290579f24ebeL,0x16fc47cf187ea6b9L, + 0xc219fd27789d5c23L,0x233a6b6c89263eccL,0x823634b28b6d30a6L, + 0xca352e25c9b33680L,0x9388d6ca40c77456L,0xf8e55b0b3c92065bL, + 0x5c17474b02439a76L }, + { 0xd888e7c28aaccab5L,0x18027836aaced05bL,0x185b877dccec0f65L, + 0x93cadc1c125c2882L,0x45df540a67fdc54cL,0x4f3c86e2c2788a33L, + 0x3e874469e3a0fa2cL,0xc59daa47273983cfL,0x3063c48b4a96d8a5L, + 0xc38d2bcfc2e58915L,0x90e78b8784e428c3L,0x900a292cf0c4fd53L, + 0xb7f92db7941e6005L,0x956792416ca53a1cL,0x35f6f31db1ab0fa7L, + 0x5d675eb47b58408cL } }, + /* 252 */ + { { 0xaeee1a77870c6025L,0xfc4a23b791a2dfcaL,0x7b0e60c4386b64c4L, + 0xd5d5b17de5ae72b1L,0x6dfc88ac9eefa212L,0x4feaefbed4038b96L, + 0x099ac3568e2d2eccL,0x548ea612012af207L,0x4ffed9db89c31218L, + 0x1c1e91c4e0e67331L,0x009bb64faf8300e0L,0x8780501c6773c3beL, + 0xe0cd6edec08219faL,0x7c055e07f81b06ffL,0x82b63f9ce080b36fL, + 0x02fccbaf0a9feca3L }, + { 0x9991d4d1b47cac61L,0x2e9d1687ab86e12cL,0x8c6855ec2b94f042L, + 0xca40051948e648e5L,0x9ba91fb2ef89ac57L,0x4f4192061be792cdL, + 0x82d221cbbd0f1e15L,0x062eb13bfc444019L,0xf3a97c3299790fdcL, + 0x4e796d946067a64bL,0xc46dd3006d23775aL,0x8672c4d5ed7f0f23L, + 0x821851dc3b4f63d7L,0x50a3ae0cd26273f2L,0x800e58fceac60f6fL, + 0x56f1e45613845545L } }, + /* 253 */ + { { 0x01ccb3f632c24f3bL,0x99eb1c7f06d817e6L,0x8dc640bb6aa26776L, + 0x7838affe0845d5e0L,0xf34fecb1f81a79a8L,0x6a2e282d3e6819b0L, + 0xc4b977ce8237a4b8L,0x0f46b3db87636439L,0xa465f54097970497L, + 0xd7e087628791be43L,0x00220b6c34198ec6L,0x57b38637093d94bbL, + 0x84012e1629d690b2L,0x02ec9db520aad1a4L,0xafee2fc685dc34e3L, + 0x911d193625500cf8L }, + { 0x13b1bd58f5e5af5bL,0xa7ca263b7b6a22a7L,0xab6bec4df3af2adcL, + 0x16651e59a04420bdL,0x3b448b3b4ba36c11L,0x3c62bfcdff424310L, + 0xde15c4a5f1a96cbbL,0xbe0ad8a1e4d1f980L,0x812bd14e36673a3aL, + 0x40303af69212acddL,0x8f6dab9c576095ceL,0x7df1882a107f5ca5L, + 0xb903e63c8896a3b0L,0xf5048544d863b3f0L,0x5e5019b9c09887deL, + 0x2be744fea0f53865L } }, + /* 254 */ + { { 0x054cd05f5b50f324L,0xb9b1eb241ea3c7a2L,0x4a858a5c7ff8e6b7L, + 0xd83902feec040882L,0x72b26494d0cba9bdL,0xd0176f90b29c9e1eL, + 0x05d4eb02cebadb81L,0x874405b1372b8bfcL,0x5c41288179ead190L, + 0xd44a3dd3ec2b48cdL,0x84499a773f4d5033L,0xb37b38cd564c3a09L, + 0x80e99497f42e803bL,0xc07b47a0b8f518b2L,0xc710e3c53568fde4L, + 0x735f542fcead0e7aL }, + { 0xcaa9a17138380039L,0xadfafe17f74d19c8L,0x92d4393eccbc1a8bL, + 0x3c5dbf39fe029705L,0x4552b5ab930e9b36L,0x7ee630322afd494aL, + 0x826a9ad73f02ac43L,0x98c5356299356298L,0x0c869f877342bb39L, + 0xd7510020e4f9b79aL,0x6361d1a4d34789a9L,0xf0ded5bacfa85637L, + 0x407ee73f88ac07e4L,0xfac7d03f09ef1cbdL,0x25d697cb4d475badL, + 0x1e984c9d14bd399eL } }, + /* 255 */ + { { 0xc76d05614850c817L,0xb08a5b193489812dL,0x7273d1545e58cbbeL, + 0x8900b5fa4be61e5aL,0xaa088691d7aeb8e1L,0xe66666afd35a3d4bL, + 0x38a2c19957ec7d3dL,0xa0648e8f668d6f5cL,0x1f9fc92c7adc1746L, + 0x23a116c0843065c3L,0x36370a2061e6ae69L,0x626c37362aa47e73L, + 0x540c25f2deff6d84L,0x9804824ccdbed2d4L,0x4b5bfce0039a9492L, + 0x6c474a5676942e01L }, + { 0x3aeb9a417d88e3a1L,0x105d3c88c484742aL,0xe59de8d13fe61131L, + 0x148f5b6b1a869e8bL,0x7a8abc59aa75d90aL,0x2f0c9bc762146013L, + 0x43faa747c3824cd9L,0x81763a186a5d0b92L,0xbbc341bc9bcbaebcL, + 0xe1813160f745d1ddL,0xa53ce52db75ce5f4L,0x15eae66cd50de4c2L, + 0x5ed8996c75d7656dL,0xe4ff5711c4ca552aL,0x215e985a3c5305b4L, + 0x6b258954fa1ba2ceL } }, +}; + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^128, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_base_16(sp_point_1024* r, const sp_digit* k, + int map, int ct, void* heap) +{ + return sp_1024_ecc_mulmod_stripe_16(r, &p1024_base, p1024_table, + k, map, ct, heap); +} + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_1024(const mp_int* km, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_digit kd[16]; +#endif + sp_point_1024* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_16(heap, p, point); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 16, km); + + err = sp_1024_ecc_mulmod_base_16(point, k, map, 1, heap); + } + if (err == MP_OKAY) { + err = sp_1024_point_to_ecc_point_16(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_16(point, 0, heap); + + return err; +} + +/* Multiply the base point of P1024 by the scalar, add point a and return + * the result. If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_add_1024(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_point_1024 a; + sp_digit kd[16]; + sp_digit t[16 * 2 * 5]; +#endif + sp_point_1024* point; + sp_point_1024* addP = NULL; + sp_digit* tmp = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_16(heap, p, point); + if (err == MP_OKAY) { + err = sp_1024_point_new_16(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (16 + 16 * 2 * 5), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 16; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 16, km); + sp_1024_point_from_ecc_point_16(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_1024_mod_mul_norm_16(addP->x, addP->x, p1024_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_1024_mod_mul_norm_16(addP->y, addP->y, p1024_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_1024_mod_mul_norm_16(addP->z, addP->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_ecc_mulmod_base_16(point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_1024_proj_point_add_16(point, point, addP, tmp); + + if (map) { + sp_1024_map_16(point, point, tmp); + } + + err = sp_1024_point_to_ecc_point_16(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_16(addP, 0, heap); + sp_1024_point_free_16(point, 0, heap); + + return err; +} + +#ifndef WOLFSSL_SP_SMALL +/* Generate a pre-computation table for the point. + * + * gm Point to generate table for. + * table Buffer to hold pre-computed points table. + * len Length of table. + * heap Heap to use for allocation. + * returns BAD_FUNC_ARG when gm or len is NULL, LENGTH_ONLY_E when table is + * NULL and length is returned, BUFFER_E if length is too small and 0 otherwise. + */ +int sp_ecc_gen_table_1024(const ecc_point* gm, byte* table, word32* len, + void* heap) +{ + int err = 0; +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; +#endif + sp_point_1024* point = NULL; + sp_digit t[5 * 2 * 16]; + + if ((gm == NULL) || (len == NULL)) { + err = BAD_FUNC_ARG; + } + + if ((err == 0) && (table == NULL)) { + *len = sizeof(sp_table_entry_1024) * 256; + err = LENGTH_ONLY_E; + } + if ((err == 0) && (*len < (int)(sizeof(sp_table_entry_1024) * 256))) { + err = BUFFER_E; + } + + if (err == 0) { + err = sp_1024_point_new_16(heap, p, point); + } + if (err == 0) { + sp_1024_point_from_ecc_point_16(point, gm); + err = sp_1024_gen_stripe_table_16(point, + (sp_table_entry_1024*)table, t, heap); + } + if (err == 0) { + *len = sizeof(sp_table_entry_1024) * 256; + } + + sp_1024_point_free_16(point, 0, heap); + + return err; +} +#else +/* Generate a pre-computation table for the point. + * + * gm Point to generate table for. + * table Buffer to hold pre-computed points table. + * len Length of table. + * heap Heap to use for allocation. + * returns BAD_FUNC_ARG when gm or len is NULL, LENGTH_ONLY_E when table is + * NULL and length is returned, BUFFER_E if length is too small and 0 otherwise. + */ +int sp_ecc_gen_table_1024(const ecc_point* gm, byte* table, word32* len, + void* heap) +{ + int err = 0; + + if ((gm == NULL) || (len == NULL)) { + err = BAD_FUNC_ARG; + } + + if ((err == 0) && (table == NULL)) { + *len = 0; + err = LENGTH_ONLY_E; + } + if ((err == 0) && (*len != 0)) { + err = BUFFER_E; + } + if (err == 0) { + *len = 0; + } + + (void)heap; + + return err; +} +#endif +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * gm Point to multiply. + * table Pre-computed points. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_table_1024(const mp_int* km, const ecc_point* gm, byte* table, + ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_digit kd[16]; +#endif + sp_point_1024* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_16(heap, p, point); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16, heap, DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 16, km); + sp_1024_point_from_ecc_point_16(point, gm); + +#ifndef WOLFSSL_SP_SMALL + err = sp_1024_ecc_mulmod_stripe_16(point, point, + (const sp_table_entry_1024*)table, k, map, 0, heap); +#else + (void)table; + err = sp_1024_ecc_mulmod_16(point, point, k, map, 0, heap); +#endif + } + if (err == MP_OKAY) { + err = sp_1024_point_to_ecc_point_16(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_16(point, 0, heap); + + return err; +} + +/* Multiply p* in projective co-ordinates by q*. + * + * r.x = p.x - (p.y * q.y) + * r.y = (p.x * q.y) + p.y + * + * px [in,out] A single precision integer - X ordinate of number to multiply. + * py [in,out] A single precision integer - Y ordinate of number to multiply. + * q [in] A single precision integer - multiplier. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_mul_qx1_16(sp_digit* px, sp_digit* py, + const sp_digit* q, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 16; + + /* t1 = p.x * q.y */ + sp_1024_mont_mul_16(t1, px, q, p1024_mod, p1024_mp_mod); + /* t2 = p.y * q.y */ + sp_1024_mont_mul_16(t2, py, q, p1024_mod, p1024_mp_mod); + /* r.x = p.x - (p.y * q.y) */ + sp_1024_mont_sub_16(px, px, t2, p1024_mod); + /* r.y = (p.x * q.y) + p.y */ + sp_1024_mont_add_16(py, t1, py, p1024_mod); +} + +/* Square p* in projective co-ordinates. + * + * px' = (p.x + p.y) * (p.x - p.y) = p.x^2 - p.y^2 + * py' = 2 * p.x * p.y + * + * px [in,out] A single precision integer - X ordinate of number to square. + * py [in,out] A single precision integer - Y ordinate of number to square. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_sqr_16(sp_digit* px, sp_digit* py, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 16; + + /* t1 = p.x + p.y */ + sp_1024_mont_add_16(t1, px, py, p1024_mod); + /* t2 = p.x - p.y */ + sp_1024_mont_sub_16(t2, px, py, p1024_mod); + /* r.y = p.x * p.y */ + sp_1024_mont_mul_16(py, px, py, p1024_mod, p1024_mp_mod); + /* r.x = (p.x + p.y) * (p.x - p.y) */ + sp_1024_mont_mul_16(px, t1, t2, p1024_mod, p1024_mp_mod); + /* r.y = (p.x * p.y) * 2 */ + sp_1024_mont_dbl_16(py, py, p1024_mod); +} + +#ifdef WOLFSSL_SP_SMALL +/* Perform the modular exponentiation in Fp* for SAKKE. + * + * Simple square and multiply when expontent bit is one algorithm. + * Square and multiply performed in Fp*. + * + * base [in] Base. MP integer. + * exp [in] Exponent. MP integer. + * res [out] Result. MP integer. + * returns 0 on success and MEMORY_E if memory allocation fails. + */ +int sp_ModExp_Fp_star_1024(const mp_int* base, mp_int* exp, mp_int* res) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td; + sp_digit* t; + sp_digit* tx; + sp_digit* ty; + sp_digit* b; + sp_digit* e; +#else + sp_digit t[4 * 2 * 16]; + sp_digit tx[2 * 16]; + sp_digit ty[2 * 16]; + sp_digit b[2 * 16]; + sp_digit e[2 * 16]; +#endif + sp_digit* r; + int err = MP_OKAY; + int bits; + int i; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8 * 16 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + tx = td + 4 * 16 * 2; + ty = td + 5 * 16 * 2; + b = td + 6 * 16 * 2; + e = td + 7 * 16 * 2; +#endif + r = ty; + + bits = mp_count_bits(exp); + sp_1024_from_mp(b, 16, base); + sp_1024_from_mp(e, 16, exp); + + XMEMCPY(tx, p1024_norm_mod, sizeof(sp_digit) * 16); + sp_1024_mul_16(b, b, p1024_norm_mod); + err = sp_1024_mod_16(b, b, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(ty, b, sizeof(sp_digit) * 16); + + for (i = bits - 2; i >= 0; i--) { + sp_1024_proj_sqr_16(tx, ty, t); + if ((e[i / 64] >> (i % 64)) & 1) { + sp_1024_proj_mul_qx1_16(tx, ty, b, t); + } + } + } + + if (err == MP_OKAY) { + sp_1024_mont_inv_16(tx, tx, t); + + XMEMSET(tx + 16, 0, sizeof(sp_digit) * 16); + sp_1024_mont_reduce_16(tx, p1024_mod, p1024_mp_mod); + XMEMSET(ty + 16, 0, sizeof(sp_digit) * 16); + sp_1024_mont_reduce_16(ty, p1024_mod, p1024_mp_mod); + + sp_1024_mul_16(r, tx, ty); + err = sp_1024_mod_16(r, r, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + return err; +} + +#else +/* Pre-computed table for exponentiating g. + * Striping: 8 points at a distance of (128 combined for + * a total of 256 points. + */ +static const sp_digit sp_1024_g_table[256][16] = { + { 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, + 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, + 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, + 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, + 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, + 0x0000000000000000L }, + { 0x170a46d2335c1685L, 0xeac9e971e1007a58L, 0x40e8f3df43ca4a73L, + 0x2646f81582642475L, 0x3af49bb4b36576d1L, 0xd89e2d1472bf1afbL, + 0x27be882c2fd151e6L, 0xaddedc858f88717cL, 0xd6d859bf16ac6c6fL, + 0x0e741a1b2d8eae58L, 0x6faf7a0061c1f30dL, 0x66dbd09a9b67e096L, + 0x21f11c067d3b4f7dL, 0x6152ba02c727c98eL, 0xafd58891e86cb221L, + 0x59e93c6a6bd3baf4L }, + { 0xe54dd36f71dd4594L, 0xbbc9cc9f00aef1e6L, 0x9ea5a44ea19f6530L, + 0x8588aa993f520928L, 0x9753794c8f5c1418L, 0x118bd792c11399faL, + 0xb9bd3afdf5cb6ab5L, 0x813d1cb22ecb9652L, 0xfd45626740389813L, + 0x51f7119b4ac8431cL, 0xdd9f6a910a180eb6L, 0x13946d179f7bfa2eL, + 0x16f1863150a9d0d9L, 0x5f19c20d6f8373d3L, 0xbe85ac6a9b6a52b9L, + 0x63ef187b74f62e03L }, + { 0x7c376b7f016f45e7L, 0x1c1bdb572bec82f8L, 0x7392f741ce429b60L, + 0x6fdbf0a2c7afd81dL, 0xbda41b1f7241098bL, 0x5b407474bb60f8cfL, + 0x933e0d41b330bc4dL, 0xae182830733fa3beL, 0xa0ed299b0f5c6cd1L, + 0x7ff3354e3f9860c8L, 0xb136098615559c41L, 0xab0cb63c129f85cbL, + 0x682ecc4947685fbeL, 0x505e8ec2eb199633L, 0x90dcc794ddac2cdaL, + 0x4fe6791cf192da23L }, + { 0x94a423d505e8733cL, 0xcc845e651d5717c1L, 0x237c7e88e961b322L, + 0x0c4471c6db4181ccL, 0x00c875e2713bd721L, 0x9dfde9edb2c17b09L, + 0x430a6de5e88ceaf6L, 0xaaa7a61a7b81cea6L, 0xea52d026233f98d5L, + 0xb55efdd060689a9aL, 0x30cfa7ce5cac4aabL, 0xfa4db1148e950761L, + 0x309570c44e9a1e52L, 0x18c21f611a040170L, 0x555d1ffebe78d9d2L, + 0x04482a18561db297L }, + { 0xe7758ac273d486d8L, 0x8169f94661cdc1e7L, 0x723c99fc2188ab4fL, + 0xa0e54f02f3373630L, 0x560bee25bd8c2260L, 0x28fc307c4531bc60L, + 0xd6f21f1a7e44feb5L, 0xc8e4499c57128d37L, 0x963b053ed7b2ea45L, + 0x40c27a0432a3d222L, 0x5b51854d35459668L, 0x66e1a49fd73557e9L, + 0x0d267fd98692077aL, 0xfa1350d3e7342702L, 0x1a9c3f2568ccdb44L, + 0x833a0ff8dedbf89fL }, + { 0xa8c419c7ab376b76L, 0x3b7294f327d0f0ccL, 0xe56bb9e2a90c514dL, + 0x931ba51ea62575a6L, 0x56fee07b098c0a88L, 0x04be5aeeb4c16a2aL, + 0xe513350be6eb260bL, 0x339edad6a1d5c270L, 0xf366ed59e9dbadd1L, + 0x4213be882dd06ec0L, 0x22d639c8cb1187dbL, 0x1fec95e1d8a1058aL, + 0x03f73ea6a2b744f1L, 0x741fd51af4f05c0cL, 0x2e2df95a85f811a0L, + 0x692b3ce3eb24965fL }, + { 0x0ce6cb72d2a127b4L, 0x66a46ea58f92816fL, 0x43ecf46347a37616L, + 0x163d9a01e0ab96eeL, 0xc8145c6db2edbe8cL, 0x2f426cae4de4e665L, + 0x174d0b4074e252f9L, 0x54c240d77d2af831L, 0x581fa3973d652936L, + 0x05b9491ca09d4695L, 0x8c4e85335452643cL, 0x32d64331d4128327L, + 0x6447903870361f25L, 0x774191b189ef09f2L, 0xc0cf0aaf81de5fe0L, + 0x333e430af40042d6L }, + { 0x5df04de4cf26d3b7L, 0x57a77306b53f79beL, 0xa4013c5f1808b664L, + 0xef291ea485037360L, 0x1ffc9d7d0b061037L, 0xd9d04dd965c913bbL, + 0x948a37aff13b8587L, 0xb5443483fe3ee755L, 0x3fc21e7404631386L, + 0xb3a104e5cddeb58cL, 0x94fe18626572cd52L, 0xeb9a71a115aaa408L, + 0x8adc6fe5459ea462L, 0xbb18d1754aeb02a3L, 0xae1276362f7791d1L, + 0x10e8b31dd6bbd708L }, + { 0xb87f03e53ed9f1afL, 0x03ad247756676166L, 0x38dcd63074ce15b8L, + 0x1877e2b026b1e85bL, 0xb1654d171af99c15L, 0x9782e9e49382547aL, + 0x6dc7fc7c26d55ef5L, 0x9038f95d2fbeb54cL, 0xfe590dfe036c0357L, + 0xcfcb6eae4fdc3f7fL, 0xcb1fbc54f35e1a88L, 0x3c8e1db2da0a5568L, + 0x9a87393f5b6f5557L, 0x38646b32e7ac0a06L, 0xfd261c832a8495abL, + 0x6485524c0cdcc4bcL }, + { 0x1abfb3e2c4a6ff2aL, 0x2aa03fba35a6428aL, 0x884227f089aff742L, + 0x2337883aba5dbd93L, 0x38186ae9d2a182cbL, 0xb9f0764d49a01f05L, + 0x92411feb917b1e7aL, 0x700b1903570cbb5bL, 0x5d5181d5b914be7cL, + 0x135c44371981182dL, 0x32758d24574b9997L, 0xa650a8f5632d28b2L, + 0x24078bacfa383f09L, 0x6546a60c00a33d80L, 0xa4061c7a2df8b449L, + 0x1f76f3f2f234563cL }, + { 0x9aa2c14344c436b0L, 0x790705561f69c87aL, 0x35f3117b5f6db2dfL, + 0x85761f41ed56ba82L, 0xf831464f7d0afa48L, 0xa99f29153adce71eL, + 0xb27bf693116b7488L, 0xa98a5a8c9bb9443aL, 0x7f8780262ee5fde8L, + 0x3a6f93dd1812acb7L, 0xaf92a4ccdc84bc92L, 0x3c2562aff1d4995aL, + 0xfd9fc33c04ed899dL, 0xc028ca944ed2a538L, 0xd0f367bb049ea726L, + 0x04924ffb3d108e05L }, + { 0x06548e3dc673562fL, 0xd3b33025e2eae48cL, 0xe61fd32b5e1c6977L, + 0x424e20646ebe557bL, 0x767391c041d6e18eL, 0x4b8ebb8e14d7e95bL, + 0x4ae8b7d420991b8cL, 0xf8a0df66e01290d3L, 0xc97e24a3925e5f4eL, + 0x79a7b2cb1508272aL, 0xb40b072e25072661L, 0xdad9e1829062fa49L, + 0x8780a784f3c53bceL, 0x58a82b769f142799L, 0x08cd849cc1468426L, + 0x4dfce809c380ae35L }, + { 0x45069cb2d527b780L, 0xd52da015977930ddL, 0x10cc600be27d0263L, + 0x34102c26bb2d1b2bL, 0x4c652623554adf3cL, 0xd689138245f0ff47L, + 0x83fa8cc5ca916e7cL, 0x1e10f139d15c8d8aL, 0xf173dc2e81dc56b3L, + 0x7fcecb045c4ed9baL, 0x307fd7d847d01228L, 0x24a571539f3a532fL, + 0x59e9e81de2153c22L, 0xc562595de428a408L, 0xdc7daff89339bd23L, + 0x0d075908b8a06802L }, + { 0x870af2a7de085f2aL, 0x88fcd24fbe99b2e5L, 0x88c0d26159ca413bL, + 0x1f02a2e48559f851L, 0x83b96021f622da0dL, 0x5c05c2f56dca3615L, + 0x0148cf1c7910c682L, 0x392f2896272695beL, 0x883d0bb5a8d64ef6L, + 0xef0d22441cfcbc52L, 0xf5dafcec526117e5L, 0xb68612b9f04928e9L, + 0x283f744d393f2e2aL, 0xfbeed7ed700c1151L, 0xf2cde215a4360dfeL, + 0x24fa961c2f08535aL }, + { 0x0767db3f616df7f6L, 0x643057d8fbd90326L, 0x174daa906e82d544L, + 0x2284f345689643dbL, 0x18b191dfcc89a060L, 0xbab46af4d6c27d12L, + 0x5a57f486c9895145L, 0xc03214e9cc942f9eL, 0x273e1c8f41950158L, + 0x8ceb759f39ad43abL, 0x5e1b8b7fe50ee173L, 0xf635b1fc8f4d7d4eL, + 0x8eff77e3755603f3L, 0x201f61d17752fa60L, 0x94d7a03d4a6fb6e1L, + 0x371cc23dfc4f0114L }, + { 0x289b115dda90c351L, 0x6d196ebf364d9c06L, 0x77a89202f650b31bL, + 0xcc28c1646f57642fL, 0xdc4f7e3608100127L, 0x8836cd08dc4c807bL, + 0x1280f156e00240f2L, 0x3f9a6d7899cb3953L, 0x40a494d33a802038L, + 0x45697e91e87d3474L, 0x70d97d0726dde24aL, 0x06f6a58d7640c30eL, + 0x03c2c0e85ba6e6c6L, 0x330f6a7af1bc13e8L, 0x3e602e4fc9f4d78fL, + 0x92b6bca00c80fb7fL }, + { 0x2e3d5c835f00822eL, 0x0e825712b8b16f12L, 0x81c329c492b0a330L, + 0x6b4e32ada7cc1954L, 0x0bee9cee1bb1413fL, 0xedfb7baa4a92ca27L, + 0xcd472afaea3b9153L, 0xe8f09e7e00f0c0f9L, 0xa4e1d8725cdebb70L, + 0xfe2bae084a9b63b6L, 0xf40141b83fd58f65L, 0xd7ec5edaa3b62759L, + 0x9aaf6e67790e3088L, 0x215ad8301f277e31L, 0xe7db4b98cf33871cL, + 0x71ff62c94f02f89dL }, + { 0xaa4c71022a4a84d9L, 0xe2ee4acd5ebc71e6L, 0x3b11a8a5f1cd6578L, + 0x83f5ef9ffff120a5L, 0xa4c598e109e65033L, 0xe1e9f990ca044180L, + 0x8b832d46f59828c1L, 0x753f28a033af536bL, 0x92edc4b1b6d4f68aL, + 0xedde692a72ccd1f0L, 0xd3aa0f7dd2226432L, 0x38dbb63ea3d2661cL, + 0xf1e19fc6fdc37ddaL, 0x6c18b35084ef6b4cL, 0xe6a83fe9df1bba69L, + 0x40fd47e75f958273L }, + { 0x5b88b746267140a4L, 0x6dbbfc1eeab6f2fbL, 0xdd9ec88e69862548L, + 0x69beeba12eb6efc2L, 0xcfc2214a8ac8ff88L, 0x95d5c96eb5a21950L, + 0x93389c054171fb69L, 0x2d85d4521b468337L, 0x14d68a084113425cL, + 0xe52c0139ec6c2174L, 0x20cf0b97f730084dL, 0x1ac16a261f578aa3L, + 0x18b9fab3f9b6ae43L, 0x68d82111d854a695L, 0x0b334d98dffbe286L, + 0x5b1c1157e639338cL }, + { 0x90edaab172b6bb8fL, 0x8dc64ed202fc92c2L, 0xf42ba3c5fe694c73L, + 0x316dc65fcb54dce4L, 0xcb2d66a3632420dcL, 0x16e706e7056dcf94L, + 0x2809c764a4f32c9dL, 0xab18d830ea6edca8L, 0x4fd1ace681c65f57L, + 0x1f91651c7da12c10L, 0x0ac3bd66c7791a48L, 0xb6ad1cf4785e67a3L, + 0xe4d3fc44da0fd591L, 0xce1648016e1c6344L, 0x84de9cb833e50ab3L, + 0x963ab83aa756eef4L }, + { 0x944b47d8df4ea5a3L, 0x965688155cfe45feL, 0xd16e7d588a3c3564L, + 0x84e55b3ee7c99e15L, 0x3fee204df55071bcL, 0x71006f2904057dceL, + 0xfe8c390dbba75570L, 0x3645bcb63319adacL, 0x8189e8b07c20bfd8L, + 0x8e5509697d7d9578L, 0x037d1321b99f4e3bL, 0x011b2521a60cfb6aL, + 0x66594aaa837382daL, 0xc89b91fd83c1dc07L, 0x6b82b899076b9884L, + 0x443480fcbe45c558L }, + { 0xf8ffffb49114221aL, 0x4aec4f2e3e857a7aL, 0x42e2d0e40fa54787L, + 0xef3e6b31d6f96152L, 0xb2296537fbfe9b77L, 0xc2a9d0f2fb43a86aL, + 0x241284ed24572ac6L, 0xa3868917e721ba7bL, 0xdbef7c00c117a78dL, + 0x38149071d31605acL, 0xc2dada9e065a8ee9L, 0xd5b138d8c442be82L, + 0x9b6c224bf6d72b58L, 0xb9d355cf8eb03e6dL, 0xab6d1eb0a1700371L, + 0x97118a88cffaa7ebL }, + { 0xbf9c59a2cdecb5d8L, 0x8083c81ba93a6866L, 0x24e0dd8104774fbfL, + 0xe779a3caa02070b4L, 0x9d352fbb0fbfb781L, 0xa8b0d8203ef2a1c4L, + 0xb858637b14b3e501L, 0x5ba70a498a882ff2L, 0xa27300833b06efa5L, + 0xa42c02f4102fee2aL, 0xe4e762998a0223a5L, 0xdba2ba2685c3fc72L, + 0x554fe763fe52eae7L, 0x30b5405a270f45f6L, 0xd56a177aa573387cL, + 0x17c0778d4b71fa82L }, + { 0x0e6dff1d2735e37bL, 0xc9884e56656ec572L, 0xa2f5ac9d9ebba978L, + 0x40fa4518ba09f3c4L, 0x8c3fa177f5b04377L, 0xa1a1decd967a2ecaL, + 0x768bca700528bd40L, 0xf224952b18691c4aL, 0x16e12c45e86d5fd5L, + 0x7a0d915737859a6aL, 0x723f4309a0ffce0eL, 0x5a8db79ba96cc9a3L, + 0x6dd12ae01ad23a38L, 0x9ffec3a1e2bf5d84L, 0xd6ce84e1a452ed66L, + 0x1219d5c8571fe4c6L }, + { 0x43eaa67f262969ebL, 0x3a3ab39d2f03e773L, 0xe6127e5157bb0909L, + 0x0f82b0ed8d150274L, 0xffffcad8e580bdbdL, 0x51d3d075a9743e6bL, + 0x1484bdb18bac11d6L, 0x95cd9990eb24c388L, 0x216a61d07fac67c6L, + 0x4308f762a04e6b87L, 0x2865dd61cba57cc8L, 0x3c296b0dd234a07aL, + 0x76f928393a0793f9L, 0x70b57e1f0be29eceL, 0x1314a82f7e626f42L, + 0x2c8d7ab2d657f230L }, + { 0x67cf58920825e4d6L, 0xdf51eaa56ef83b44L, 0x63e665d81310108dL, + 0x229f89f58dd0963fL, 0x8c4b14dd9df6436aL, 0x99dae469d45ebba7L, + 0x118aab775a4df381L, 0xda8978bd29e37febL, 0x69ced5aaaca2d7efL, + 0x6c98d05dc67d6a8aL, 0x7474bf0d77f84a34L, 0xd4428b2eed8cd59aL, + 0xb0fd1cd5d1d398fbL, 0x596013db94a20b11L, 0x96eb705a1b404c44L, + 0x2299d2774b09d958L }, + { 0x5b9cd58dc64397e6L, 0xac198f1ebf6dd31eL, 0x5866d8e13e9f1db2L, + 0x405ae2878fcdc68cL, 0xa4b280cde53c01fdL, 0xdc963f2d411db5f6L, + 0xed5d5189bec4f8a0L, 0x336fd13d916ee98bL, 0x6925b1b3042df48eL, + 0x0cf56291ace0074eL, 0xe8d38b4825317e95L, 0xc7ad1d2b821c446bL, + 0x71c44135f0b65934L, 0x971b736f52ca0d50L, 0xaf9ffa5727b46c26L, + 0x21ac67791936618eL }, + { 0xab420e3f2d7fbcd2L, 0x1272247397bdfc18L, 0x492033f84df5d4b4L, + 0x6fcd42363807b7d3L, 0xdfc19b09b33c3625L, 0x13d6f375a0f22814L, + 0x70978a59037c19b8L, 0x4f3989970ff27b9cL, 0xfc0e1a45615a4389L, + 0xffa3496a3e602f74L, 0xc3f1c431b261ca1cL, 0x612211dbee0164cdL, + 0x30463ee4e7f7be9fL, 0x015f7e7892c2e1bbL, 0x663d88d624483a56L, + 0x0e8ec1e70e62d9d8L }, + { 0xa88ccc298a0878ddL, 0x99ac175d6640071aL, 0x90344820a5173617L, + 0x316d023edd58a315L, 0x30785bd488d221a1L, 0xb74b3de7959c48e3L, + 0x42ee03824c67a771L, 0x59ef6cdde0b91453L, 0x7830ae289b237e91L, + 0xe1847a4c495d8325L, 0x67b1217ed0773666L, 0x58192c86a294a325L, + 0x76aa0f56864d8326L, 0xe2a2bd12f4b13e5bL, 0xd850c1c01b6b73fdL, + 0x653a795f5d103635L }, + { 0xcfe2898550dcb199L, 0xb35b8e5e7fa02b60L, 0xbca7d7c3c97603d0L, + 0xb0e5288d27f131b5L, 0x3aa704dee2b12d52L, 0xe206b1d81db725c7L, + 0x0b12839ac5d1b113L, 0x14f970cbdb45d763L, 0xc997f93eb2125e8eL, + 0xbd75739cee7daa26L, 0x46ecbd3f1fef20e9L, 0xf994a1147c6a42b1L, + 0xd289eb4f27fb0fd1L, 0x11186d319a40da4bL, 0x083f65a5fb9d7976L, + 0x30dfc47bd444675eL }, + { 0xbcfc5ae29eaadfe8L, 0x25027e54b4d4e812L, 0xab0702df8b533561L, + 0xa2b9c20456a6a214L, 0xb1a3df7a3059068eL, 0xa3514b219883110fL, + 0xb7be2336c4b78e1cL, 0x17073ce63e2f6984L, 0x86e114a62ddf7ac6L, + 0x276192bf07d7c3c8L, 0x5da69e0beb1ae289L, 0x983af17525184939L, + 0x9ac52a4d407a3aa0L, 0x1535c7daae0fe218L, 0xe16fe872397f2501L, + 0x572a591f54c212cfL }, + { 0x4966841909a5553aL, 0x3f054318327733bcL, 0xf9ceb4b23eefd690L, + 0xbd3cbf9bf22126d4L, 0x6d9671c02fed9578L, 0xbba597ceca0306d8L, + 0xb705ed613d674fe5L, 0xf1d3622b67f33f76L, 0x15bcf3c611cb8c31L, + 0xa38467dce53d1aa9L, 0x902fe929f908ab43L, 0x6e3e499d8d15767aL, + 0x8142db5c90afd07bL, 0x120c6fbc6c8b190eL, 0x80c8655324919a4eL, + 0x65c2cbe1d8c82c3cL }, + { 0x684cda20a660bb63L, 0x27dc3b0a86e86245L, 0x76472cf66ba0eed7L, + 0x79c162e5679dd158L, 0xb688427708452d44L, 0x829bc6b3413f579eL, + 0x92ea15ec95011770L, 0x5e34e30047738183L, 0x8c3ca34973e1d2f1L, + 0xa5c4f1dc229bd3deL, 0x783eff1b94ef7ed3L, 0x46db738ddfae7a1aL, + 0x4353d72e1a099852L, 0x2533ad58a0dcf4abL, 0xd80550160e7888b9L, + 0x831440d53ba77f66L }, + { 0xf43e2e32f611b2daL, 0x5d066e29d0fa46acL, 0xe897f3e8820b3c0dL, + 0xc45c28e61d3e44f0L, 0x929d7f66dfd27a66L, 0x735b860a101e8517L, + 0xea3fce983de078ddL, 0xc9977db5638ce11aL, 0x0488382f48536b3bL, + 0x7e0c7a3c64cadfc6L, 0x3cd17f7f82147b71L, 0xe95663cc1b411e3eL, + 0x5739ac8f985fb46dL, 0x385399cdbcf119caL, 0x4a985a70e15a2815L, + 0x504c3a8a6d5f4566L }, + { 0x00b55283b8fa53c7L, 0x985cff38509474e3L, 0x234d241c437ce25fL, + 0x29832430e5a129edL, 0x6ad38956aabcc674L, 0xa2dc001d7ee81ee1L, + 0x4c23c6b6670b2702L, 0xb35e567ea6e8a3bbL, 0xbc70b3cea69673eaL, + 0x85a7a9c3e6e28eacL, 0x2ae684de5537b7daL, 0x5ecac3e56de937dcL, + 0xbf2ea6c9f8430422L, 0x38caf7d077fdc520L, 0xc27af0b169f56addL, + 0x496e4699c71d21d2L }, + { 0xba14fc829fa93467L, 0xc2e376840eb2a614L, 0x659bcfaf4833e09bL, + 0xbc8597523686bdccL, 0x40bfd08081f3216aL, 0xc463bda617c081b8L, + 0xbd01fa86bb04793bL, 0x5a21ece62cd640c5L, 0x97bf6a542203d5c4L, + 0xceb40edc951167b7L, 0xd67aacaf765ba268L, 0x8ba0d9e9aeab51f9L, + 0xc14b215eb0d6863aL, 0x354cdcdbe5f06952L, 0x4f2b5ccfcb3744b5L, + 0x1338917313037fe8L }, + { 0xee68064045003cd1L, 0xfdac17bc44ae2ac6L, 0x4bcd419fde8e5314L, + 0x81e34eb9c7cea95cL, 0xbb57762d38f37e01L, 0xecc4cfb0260990c8L, + 0x0bc493f950a34a7bL, 0x68074172543304efL, 0xaec0fcb26bc8aa2aL, + 0x9e7a9b463b45fea5L, 0x4bb2952e55fbdbacL, 0x50f0c0a60485dff4L, + 0x02c5104d4dea4796L, 0xd2cefa09695e3a02L, 0x4c8102b46da1f345L, + 0x422eb573f3833fbdL }, + { 0xac592eb6a6ad3f47L, 0xb0861f6d9714ba0eL, 0x57c1e91907281459L, + 0xcf7c94e264ea5803L, 0x725376ac54b12723L, 0xf2a6ba41dafb736aL, + 0xc89e8920cba03cdcL, 0xf2e20cb45b0fd3adL, 0x26ea5a54d66059feL, + 0xee63fa8b889df8bcL, 0x40f1c7e166a3f2bfL, 0x09febc9c747312e1L, + 0x7d19b9c2727999ffL, 0xa9fbbb4cb7fd2b05L, 0xcfba27d7a0da2dc6L, + 0x368541cf2c252582L }, + { 0x510d3c9e22799d37L, 0x1b677de5acfa333aL, 0x4e6ae18f080f795bL, + 0x69b53c2aafc8dfc2L, 0x797541b60e842dc2L, 0xd5a6f2afac067fe8L, + 0xd0208a03bd07d877L, 0x34b473f0654be2f2L, 0xe67c102af515e23eL, + 0xb00dbf9d2ac1af48L, 0xe264fa41b6a13d00L, 0x1669786a97e94c11L, + 0x09d8cf2d86a586f4L, 0x073bf869c7f927e9L, 0xb89778802241a566L, + 0x59a5bf5922261334L }, + { 0xe9d1c91e81347191L, 0x186c1abceb969972L, 0x07888767a9d46a7fL, + 0xda93cfccdaa7d397L, 0x08bee9f1d91b9aa0L, 0x8267fd78f8dd3c6cL, + 0xf93860d094228100L, 0x6a6a71aadadb47fbL, 0x9caa06b7a6156f8aL, + 0xaa1b05e039848bc9L, 0x36ddc2372aaa9135L, 0x77e7e079b13f3bd1L, + 0x8d0b5cbe4acc5f4dL, 0x04da45f8984cfd36L, 0xf14ef618d3d3e0f8L, + 0x467564c143eb799cL }, + { 0x8d725904b6fff5d7L, 0x037f33af92dc4752L, 0x9095d5756d20b8aaL, + 0x32235fc143baec39L, 0xa2feb4af68a2b9b0L, 0x61c5031894d35c61L, + 0xac92b6a2ea877486L, 0x8eb48b15011bc6f3L, 0xa28fe128c79edcb2L, + 0x9f71bc0ca5d2a006L, 0xf31677322f15b850L, 0xfe8d728c7a036218L, + 0x068f39cb4f81e09eL, 0x1773f0167b7c50d9L, 0x0d0f7adbed6a1e03L, + 0x8a0dee164ee984d5L }, + { 0x504991bf47366e6fL, 0xb8084d9fe86c3005L, 0x14c4c751a40cce36L, + 0xbbb46aa63f1961e2L, 0x56a785f940445e43L, 0xdb8d1b57c91e215fL, + 0x6a8e453ec7ee808dL, 0xc0367ef8bbaa1e8cL, 0x310d91f1e3e18109L, + 0xf97cfd0e7e20a2c3L, 0xf1e80c84554cc277L, 0xe89bbc1d7b628403L, + 0x7778a9663fe0a17cL, 0x9e9db19fc1f00073L, 0x2ce7fe7db6f6bed2L, + 0x7b04b5d2ee97ce23L }, + { 0x5b546bc782c5faf8L, 0x1a734c5e8eb81097L, 0x3d566861e77851e0L, + 0x833a1013e956d51fL, 0xc7351731c3c3c37cL, 0x607738fbe0c148ecL, + 0x2ec6f0bbe1bbef41L, 0x0aa2ac6ecfa51857L, 0x072902d766e3adf0L, + 0xcd4d5089c622d6e3L, 0x3ae21b23a6dd802fL, 0xe5465a5533886372L, + 0xd85119a0a8d81822L, 0x4f14d0323786977aL, 0x515b081c9c7b272cL, + 0x1c6a95a4c99be31cL }, + { 0xa6b14ad5c2821363L, 0x829c18234d17de1cL, 0xaef5d2c4ccade848L, + 0xf412ab3982489e27L, 0x92c9c098f081d927L, 0x6f87bdf475cbad1fL, + 0xf4aadab81a1d9fb1L, 0x475a7923b75f3b76L, 0x99dd0ad6dbbba8feL, + 0x836f61644b70ab45L, 0x2a46488134bd9af1L, 0x5c91226eba9abda3L, + 0x4cec8709e65625fbL, 0xd4b3919e0818e4beL, 0xa5c09c8414f6879cL, + 0x72708a0230a864c9L }, + { 0x4f33c0b1f34a466cL, 0xa1bae09c7f9d45baL, 0xd70f0fee0e28785cL, + 0x824c714690880881L, 0xe2416c2abb043da3L, 0x733da713cec6f432L, + 0x2b590649c9793e1cL, 0xdb62d5b0b35c9365L, 0x355eb6e23e5c1b2aL, + 0xcfe8b5cebb16b515L, 0x9e081869f709691cL, 0xc865f9fb61a85bd5L, + 0xf169d3ccfae103f7L, 0x9525c47373467e9dL, 0x7db55c0b43695113L, + 0x7491c74c73265d21L }, + { 0x312ed5bf80d2b94dL, 0x1b8ac633ba4b260bL, 0xac86c58cd62219a1L, + 0x317ccf6baeb82c8eL, 0x2dfb29ee59ef9cedL, 0xdaa7d898e42bcd5aL, + 0x93e295c85974b201L, 0x69e75784d9fc5adcL, 0xd6c4709f012aa3baL, + 0x1fda9f37c85d3cb9L, 0xe5487e25d3dd4abdL, 0x00fd4b010b3ba22eL, + 0xcb591493c6e8dcbbL, 0xb7329fabbce68664L, 0x6829d1c268906b76L, + 0x8bcfd3e574176841L }, + { 0x06882734d3c8c314L, 0x95f0b2f111870833L, 0xb937f7c3c068ba16L, + 0x5365e0d877924787L, 0x15527e5e1f992227L, 0x0a06964827dffd4fL, + 0xd58b3df22f586389L, 0x83446b896af20eadL, 0x09d7970b50746257L, + 0xd9e8d2064022a691L, 0xd1e5f8af671ec379L, 0x6f542509057fe91eL, + 0xf14dda8152890418L, 0xbd78010e1db932adL, 0x3e18d1e4905a9378L, + 0x53cadcf7bd37ab49L }, + { 0x1bb5edf75e53d0ffL, 0xd886606c888abf67L, 0x6491b0f812206d15L, + 0xb3018345e22b6a33L, 0xaba6794bb173b317L, 0x8c1e58677dc9e595L, + 0x4e106482239624d1L, 0x61752e59da55dd53L, 0x018b4eab9e42879cL, + 0xcaf6784b491f2bedL, 0x3dcdb9d21e79429eL, 0x3694148510f26224L, + 0x106f190aa650ec5cL, 0x7542a5aeb69a9760L, 0x69bd75e9c32d1046L, + 0x90849964bf8c62b1L }, + { 0xb1390cf65a93c661L, 0x184862649db5f056L, 0x92a93a9da51a1788L, + 0x1b0cbb8f6772de9aL, 0x6e67febd7c71487cL, 0xf9b4382d4e62423eL, + 0x96fda50ebb5a42f8L, 0xc921b3376089a4f2L, 0x49d32d7b875ec516L, + 0xbd86d2cac410124bL, 0xf6862209c421fb7aL, 0x3e1949abf6b7de33L, + 0xcdee18f0e93c9268L, 0xd4edbd5e08dc4cc0L, 0xc2b75be473580d22L, + 0x3d7f6ffa468cd7e8L }, + { 0xea7b290cdffbd5d1L, 0x9d759da6970338dfL, 0x56680b0890feedc9L, + 0xbc690af542dce68eL, 0x8519df2bb2ae4d82L, 0x5612467f7f195b60L, + 0x659a342cd83c21f4L, 0x55771bf555651633L, 0x5fc68935548ba562L, + 0xb54192039492f23aL, 0x567528e39c9c6017L, 0x3f064ed4511e6019L, + 0x303f9eb91d16a555L, 0x3e18c4fd2254abeeL, 0x40994d6ffd434e7cL, + 0x8fb12d3f6dde74e6L }, + { 0x6c6381a2293cb7a4L, 0x453e09f0b87b7e4dL, 0x4f212823078ac3efL, + 0xe89ffad0578cae91L, 0x4a2b696a716ba4ddL, 0x14681a14f6f580a0L, + 0x1358f97b4c2f1307L, 0x878969962932fb89L, 0x29dd850a268a5af7L, + 0xaf771f6dfe239f83L, 0x5f20fd2e4f47499dL, 0x9b643e77867ca0e9L, + 0xe7858ecd375981ecL, 0xbe946a5919ab1c97L, 0x4f9303a206ff3453L, + 0x3fcc673175d237b1L }, + { 0x509debd5df21f920L, 0xfaf70e1fc1401b90L, 0x2429cbfd95a64aafL, + 0xf21208552c37a122L, 0x1d4c93f47deb926bL, 0x12f3e4c09fb3f1dcL, + 0x56085a595b51bc46L, 0x2a2f5d62f10fdbd2L, 0x60dd62cfdf0cb3c2L, + 0x154424a36b0f254bL, 0xc3a5a05d564612b7L, 0xbebe30cfa1f5249cL, + 0x24ec69037e62a188L, 0x75f0fbacaf429939L, 0xd41345dcb3fa8685L, + 0x645146fdc7151c34L }, + { 0xecec633aba1924f9L, 0xbba6f136006326e1L, 0x203757ac7e50fc17L, + 0xca531919ef3d8e00L, 0x9545a6aa51dc5a74L, 0x6e21d58fd31412b8L, + 0x01bc30057bb1d000L, 0xf1789c696ed1a9c3L, 0x7af2d35f9858fa48L, + 0x434d09b98197be85L, 0x1dc0775529aa265dL, 0xcad03be7c058fa80L, + 0x92d70a9f54ba14ceL, 0x6dc785056c050a74L, 0x2a7ca4a94d005ddaL, + 0x448d3d72abfb9f2eL }, + { 0xdc56f14529b33989L, 0x868351bca9ae815aL, 0xb3f456134b074414L, + 0x955ce42a3cd9f33bL, 0x13ade4ec5ff6e4a3L, 0xd3aac715a50eaa91L, + 0x0c61ec995666efdfL, 0x108a28b8f6a4470aL, 0x402ef584e54844c9L, + 0xb825b162d0e2f337L, 0x3dcd131fb46f7cbcL, 0x208178ec96f2fd89L, + 0x4d8c5d6725928c78L, 0x285a33df9963c459L, 0x72497175d92a309fL, + 0x76881479cb7019a5L }, + { 0xba43a11491767eedL, 0x5e11b9ad92bf65dbL, 0xe8a22ce003a5e21aL, + 0x636044212a335415L, 0xc2c563b44a9ead62L, 0x4bc06264a0b2aee5L, + 0x75b8d5758bf2e1d7L, 0x1cff0ee7d08a265dL, 0x17914e1db0b712a7L, + 0xc35925d04b18692dL, 0xde253f4c56cce815L, 0xa479241c9fff0e3aL, + 0x50b9d06eddabed19L, 0x6713526059fae506L, 0xf37600fb532ce180L, + 0x670eb01c5e5a8626L }, + { 0xdf73c0af73cdbb43L, 0xcf08ecc57f2431adL, 0x917805412a1a3845L, + 0x69a104f29224ddf1L, 0x4352f38dbeac7effL, 0xfc3b3b4e7c2d1322L, + 0xa69e9430b5e4b476L, 0x7d932340975a46f0L, 0x8093899e5d64eeceL, + 0x7b821250db2345e9L, 0x235529327f4b796bL, 0x2ee9cc154bb90b1fL, + 0x1fa9c8f59112f7d6L, 0x2d0f2f981cbaae32L, 0xb77f03660075166aL, + 0x504852e7635dff27L }, + { 0x2f0f3ce5a2f392faL, 0x326c076aec6c9078L, 0xad01de9284baaaf6L, + 0xb01b16d3cbe8e993L, 0x71305c242d950908L, 0xc66fd6173853af38L, + 0x7735140ed3c429a0L, 0x8a31b12a1fabf027L, 0xa0530002058b3177L, + 0xabffd9fca9c7deb9L, 0xd05ef69be8667d30L, 0x2f3a7308e9a9e13fL, + 0x3f4c9a19b91eae9cL, 0x50d0cee7618ce6c4L, 0xfb24dc405240f8b0L, + 0x992fe151f7e90cc4L }, + { 0x4454db3138f197aaL, 0xa4ded69d87872f98L, 0x97b427b044f0a828L, + 0x9821e1aea31e48c6L, 0xe38cb09fdd98efecL, 0x20b84fa8480cb3aeL, + 0xba5bb4a847475573L, 0xa9be080acd50e96bL, 0xc4451e9cef103550L, + 0x626ee75fc441325cL, 0x6eea5e9838a5e33dL, 0x7321beb9a2b0abd2L, + 0xca92e4849b6082a9L, 0x1dc8168a992bcc2aL, 0x134ecf4b9c8eb9fbL, + 0x5a68bfa84c5b71e0L }, + { 0xb4ff3b45ff0a2bfbL, 0xd105fff95502f8b0L, 0x14de58855b1c0c26L, + 0xed16865b0d3b9d04L, 0x2f5a2453026d3917L, 0x6a22f493f4db3c0eL, + 0x4871548ae2418f2eL, 0x6ab363a8509bef61L, 0x91ca1e3ab8cbbbecL, + 0x71e0dc984011a396L, 0xff982e0a0d5ca577L, 0xeb40b04581897bc1L, + 0x4bc24a46085ad5e7L, 0xd15c8fa0a6337b7cL, 0x56ce6ef7bef1628fL, + 0x78acfdf99f5ef439L }, + { 0x45bf7f15f8520189L, 0x954202a0c77f61c4L, 0x39edc6b9dfa22e1bL, + 0xd2d602671f4a3487L, 0xcd9339294814cc52L, 0xde76a12405e9f123L, + 0xe2306ea0ae36b6f7L, 0x53815218b83a58e0L, 0x9862bb76a041231aL, + 0xe8da253cbf31be71L, 0x2dfc533237de861fL, 0xf25c93f690ae4890L, + 0x66bcb8f08baa6ed2L, 0x6f10ae0f908b4a29L, 0x8cb4b48cb061c949L, + 0x0ad92d73d075a366L }, + { 0xbfb95fedc2ca548aL, 0x4778c62080cd89abL, 0xbe99154b3466c280L, + 0xea3be093d4be8902L, 0x847b799513e681edL, 0xf22a8f4b02f40161L, + 0x3ef2cb4d4aeb7fe8L, 0x9adc5151b3aed5f6L, 0xec1ccfd198c31163L, + 0xdc2ac17ba3d7d88fL, 0x08fa64d346421097L, 0x5ebf80b794b90bcfL, + 0x1b78b4ba0b50a9ebL, 0x1a4fe934279aa66bL, 0x8ef4dcaf075b3cedL, + 0x95bbd8a070a6e9aeL }, + { 0x59f92495e614bbd0L, 0x7567a887b823e363L, 0xe247c9ecfc1bd6a7L, + 0x2bfaaf478e835c42L, 0x314ef4e0aade066aL, 0x072baa635c16d336L, + 0xfa429c71e2f0e389L, 0xcac1e5d0bd07d90fL, 0x69ff35ea514f5c04L, + 0x893053fcc0554ec1L, 0xab1d86b72a35947fL, 0xe29fb0602aebe487L, + 0xa0a10d6ddfb9cf21L, 0xad147059f20dfcf5L, 0x480dc66fb8867a2aL, + 0x375a884fc125a919L }, + { 0x178cbe2e1217f7eaL, 0x1a161e2a875c6dabL, 0xf7707ec01bdb1a54L, + 0x678864a0e4fd73caL, 0xbaebc664d13a0d86L, 0x40325f99c8d30668L, + 0xb93ed9c92f1c5950L, 0xfdf36763541e0667L, 0xfd97fbb0b91a6763L, + 0x26aa69ea6079c9a0L, 0xc7303c801eaa8c47L, 0xdec75c81afa63c55L, + 0x01cdcde24fd12adbL, 0x9fe0dda71968838aL, 0x66bb093b38415379L, + 0x268d818b08cb84ecL }, + { 0x73dae35841580555L, 0x4fc32e67473d103bL, 0x240c1013beccc1abL, + 0xda4099f2b24ee9deL, 0x37b0cb5b9fa8e066L, 0xb5ae04e46438d7eeL, + 0x7f7d31642b720140L, 0x86ef4edb339e4a78L, 0xa5e77eed3a7d8375L, + 0x883fad37bd707c2eL, 0x816b633a0f979189L, 0xe24c028a2e7a208eL, + 0x1171fe3c4435516aL, 0x3eb93b334f5f2bf5L, 0x8419ed4b01b53a56L, + 0x8b02735c056ca44bL }, + { 0xb89bb464e1019195L, 0x1de4c026f3fc28c1L, 0xac120e6e2bfc3b21L, + 0xec71bc5a91bdf92fL, 0x485d7ab40d995bc9L, 0x97c6768ee6491ffeL, + 0xd9552d19afbce265L, 0xbae6c7fe8e1b76c2L, 0x167d8281d7e3ad1bL, + 0x3e149af95e989734L, 0xd1f0024c8a0c8182L, 0xf571ffdbc3006c0dL, + 0xb32ecf7e58773d4cL, 0x5822a782fd3540d8L, 0x5ab45c3f04365042L, + 0x400e3aa04b4d85feL }, + { 0x473216495e46e4a2L, 0x37a2ed6424136074L, 0x659223b1c60ec77dL, + 0x5e13aac3e5e0ac2eL, 0xda17c41bc5107ab7L, 0x65b22ec973c253dbL, + 0xff3867b8a5012296L, 0xfed660d50621a99bL, 0xa3c28506c89fc3f5L, + 0x3ed350b9f16451a7L, 0x27c3e03267cb586fL, 0xc807c779967185b1L, + 0x09c157d44a13009bL, 0x362f7647adaf1f4dL, 0x4a42b9acf3a6a198L, + 0x131c3da28da6e039L }, + { 0x4a785ff1a7da83baL, 0xf415b425d04f4436L, 0x7c0899bdec03f812L, + 0xc58d411a80f5f4a2L, 0x3d32d610fda251b9L, 0x99bb4504cd3b2f32L, + 0x198c444bf4c2083cL, 0x60c261af730e83fdL, 0x060ca4dfcb02db90L, + 0x0ff7838b9df1e7c8L, 0x6b79cf97c4c690c9L, 0x131514d75d75f154L, + 0xa7c074f11cb0e8ffL, 0xb920aac1b2c17615L, 0xde8098ad44aa0ff0L, + 0x71d1a46a34545ce9L }, + { 0x76178f76fa1b382eL, 0xa0d8ecc3772dda0dL, 0xaa5aab2ac5d4d130L, + 0x27d38ba48d72622cL, 0xc5410db6ca3bed06L, 0xf637a588793ceccfL, + 0x1f65dafd6e65e3d7L, 0xc3b44a8560a45641L, 0x0f47b3a84f78540bL, + 0x824fdadd5e4d60f6L, 0xd8ccf90c17d3b6d5L, 0x008eabdf325fc13aL, + 0x3e90d7163648fab9L, 0x3964ff3a24c52d4bL, 0xb95cc416533d0acbL, + 0x6cd2699f1167f521L }, + { 0x2d8c0b3b12f4f3acL, 0xb03dcfe299d1bdfbL, 0x540034f830f37326L, + 0x22dd68937c5a8c82L, 0xeb7093d0cd8f1442L, 0x892795a7585742f2L, + 0xe15f282c087adaddL, 0x7bbdc74916ab7b5eL, 0xd30fe40ba58acbb4L, + 0x0de417ebe2bac39bL, 0x4b4b19a6c61a04bcL, 0x9338c34df2735569L, + 0xe8f0374230ab196fL, 0xfa2efcb86c88c965L, 0x19eee274c7eeb826L, + 0x327c063fda345dc2L }, + { 0xab399eff5b47cd53L, 0xbbe9869d1943aefeL, 0xe64ecc7b1402a866L, + 0xc3e7c2aab1c25a16L, 0xc4216b79022de271L, 0xe58dfcc8366d6a5fL, + 0xd159509eda813336L, 0x370400f2130bfb7cL, 0x1be4e05993b48780L, + 0x0623a1fe39f3cd22L, 0x72aa22b2eecb4f87L, 0x1af4c4966c27b83bL, + 0x7a42a94bda5fa5bfL, 0x9afba82248b01af2L, 0xeb6b9d2a3670112cL, + 0x020f19d1c0df6856L }, + { 0x37051a86a4dbba20L, 0xb618ebc6db1de5c5L, 0x9a780a19e6525840L, + 0x9440302dd2bccc4dL, 0xe9ff023d10285a24L, 0x3b937ee33a486268L, + 0xe37ee2f24cd61147L, 0x79fbbfd3a3d057cfL, 0x5fba16d3ccddefceL, + 0x916058ec5b231727L, 0x47699ebe720c3adbL, 0x262743868b4f6bbaL, + 0x54b0092af18a0770L, 0x99d090ebacca1160L, 0xf757e1ff0c888f60L, + 0x79e72720b0050544L }, + { 0x632acf252820a239L, 0xb1a3974eaae6b310L, 0xd61fd6ba48c0a1dfL, + 0xd2453c395a3ee7aaL, 0x548455a0b980446dL, 0x9f29d97bde16676fL, + 0xf252ca0c789375a1L, 0xe961af3e7743a985L, 0x70c79c5666cdbd8dL, + 0x14a3854ecbc538f9L, 0x58daa73aa126851cL, 0xe9b5bb452a9f558cL, + 0x37af7f83fbd15e05L, 0xa448792738a1939dL, 0xe428b2b59511a056L, + 0x001d3ce37015846dL }, + { 0xd6be36b9e145b1d7L, 0xf3e3938a009c5664L, 0x2e562e7de7c0f6dbL, + 0x951044e6c343f539L, 0xa5ab62b8d90897b1L, 0xb1a1f70b512f797cL, + 0x91cdd754750f28e4L, 0xb4c80e2fffb8165dL, 0x65ed39c7594d02b3L, + 0xcc12a49d56833edcL, 0xe73694bcf3693a18L, 0x34cc134afcd2c404L, + 0x071bd5fc11d40194L, 0x05759047fc585e46L, 0xb3280360790b7a04L, + 0x4bb8c6fc40afc684L }, + { 0x3120e2ddfd0f8796L, 0x6968a40db133c9deL, 0xfea366c0a9369c6eL, + 0x37e5b6d66007273bL, 0x39e4ecf08cb81439L, 0x487fe9cd9febc005L, + 0xeb8af4440199b53cL, 0x2f124e3b293519ebL, 0x860c218ac82c9c16L, + 0xacd1d6f2709dc590L, 0x5696d54536d50529L, 0xc03f5df959120bfcL, + 0x99a3e88d10ffa690L, 0xd4f9cfa56c432827L, 0x2e8fea9e9a135d89L, + 0x3699a881b6a77e78L }, + { 0x5bca33721eb1c64dL, 0xe9cf3a2df1d28154L, 0xb7e2e9b36537106fL, + 0x06c171514f7cbf4dL, 0xcbde416e2058b37fL, 0x82c53a7e8834e9c5L, + 0x94dbdfe2e9ac3a75L, 0x795ec6cbc5e67c02L, 0x8c23c25f1426a80dL, + 0xee2cd20d6a8d4f9fL, 0x838daa54d3b7c235L, 0xb9e08ec03d7a4d52L, + 0xca9475e9781cb473L, 0x7271f39e5ec31caaL, 0x1df08e9f82535187L, + 0x4f3a4b03208aff8bL }, + { 0x0f7b81071ed095f8L, 0x23e37fa6da226d4eL, 0x8b0f9852afb36d1dL, + 0xb114634e07d8e311L, 0xb9634a97e3e0f16eL, 0x2454bb9c421eec37L, + 0xb4ecd5dbd72b21c1L, 0xf96038686df20d7cL, 0x9f5359fddf86e0a2L, + 0xc43d54fa5ac488aaL, 0x56d714abd1049df4L, 0x13152b3eb020607aL, + 0x49be1c187a02325eL, 0x44f24f4a52ae84dbL, 0x9e525c030b5a7b80L, + 0x6d874446a6d179fdL }, + { 0xd29d07aabe9a42f5L, 0x1fd5316c3781ccc8L, 0x71a75a6d9dc69ea1L, + 0x4e19e0df88fee91aL, 0x99c2b4dcf8d44f12L, 0x05f6df9231ae94e4L, + 0x27fba876cf28ccc2L, 0x6e1a0f01f57f7cebL, 0xe03f1f34f3fd3b74L, + 0xa0edc4a742c1d213L, 0x5caac2707deb8580L, 0x0f5d791faf0848bcL, + 0x17f514ad07ac759dL, 0x95a39734904fc531L, 0x95a4aca97bb70f3dL, + 0x3cf384c9ff9c5609L }, + { 0x700506bace1fc9e3L, 0x49721742676b0399L, 0x2b4a1b8de72bf7b3L, + 0xca8602a879b209f7L, 0x90580b90ce26a8e1L, 0x1ef339b7fe24f39aL, + 0xb6c5d991629362e1L, 0x51174e1a577b24f4L, 0xf380fcb505e451e9L, + 0xf4d97afb148321bdL, 0x099806bb747e5d2aL, 0x85525d65be99a608L, + 0x264828d9d455e820L, 0x8c8c5405d8560a65L, 0x3c67e73c71030770L, + 0x2b248850ee73df26L }, + { 0x2173cde68541159fL, 0x78224c184fb410b2L, 0x07a286191f2ca1c7L, + 0x52c207d6a8b23e40L, 0x071a0210a6b2344aL, 0xdb0e587cb5ed2945L, + 0x6c56b8ef810fcc6cL, 0x1248c58f62d843b9L, 0x4b90363d74c66975L, + 0x6348f7f2e66c66f6L, 0xb2f9d441c126bcbeL, 0xac07f2a373ce49e8L, + 0x52486758e81b0df0L, 0xa108b54d1d4621d1L, 0x17261ece74414a1cL, + 0x938b3bcc6a3ac215L }, + { 0xa9e4a16be4ded340L, 0x8e65fb2a80e88036L, 0x97089606dcd73acbL, + 0x1c3a0434aaa657a9L, 0xf304fc5849101b06L, 0xe60fb61ada0bb64cL, + 0x818c2aecf5542df5L, 0x7402057656f76d5fL, 0xb566b79092533d97L, + 0xae4655e574d6eb5fL, 0x60f7a1b5a55b44b7L, 0x7970179b93747ea5L, + 0x8ae7e0e8f2dace56L, 0x9847460784e83c06L, 0x24e8c9ed15307341L, + 0x6cff58a5d9e89d6bL }, + { 0x508c01b003e51f68L, 0xe1d1f2251d2fe7d6L, 0xf7998d0b09bd8805L, + 0x255e907a03e415b7L, 0xd148467d607d9798L, 0x055c3b1e9b453896L, + 0x35001013809f50f4L, 0xfbbb2fa6d0233fdcL, 0x0b680b0aff1820b8L, + 0xb1d404dc38d317e0L, 0x133d5444ccc8c7dfL, 0x7fa847e66ec13f84L, + 0xc33f83d8046e2e48L, 0x3c627fc54863b3acL, 0x5f67f8aaeb936af7L, + 0x5fe4ac8f31b79327L }, + { 0x581aa4bf8b6f401eL, 0x05db12a3ad5c7ed4L, 0x7b0187266fb07b4aL, + 0xfdd11f049c22bcd4L, 0x5454a7d469371c95L, 0x066c55fb99a46eafL, + 0x18637c7c7fef96d0L, 0xbafc1d346b83e95cL, 0x55c3859300bb42dcL, + 0xdd8dec2b34e7e712L, 0x69c9cfb0b184cee8L, 0x8dcc0c4249a27864L, + 0x290d95f22010f2e7L, 0x86e254c96977a420L, 0x20931c89eb2abdadL, + 0x81377164121c0548L }, + { 0x6266b25e9c5a8edfL, 0x6e1388c21078a7adL, 0x5f02737d4876eedfL, + 0x242fa7f962744617L, 0x3e2cfbd9b385382aL, 0xbadad7b102f71befL, + 0x562abcfa677d0a92L, 0x573ebd1751fdff34L, 0xd7f658527c250c78L, + 0xe0cf16eec47ca896L, 0x8ccd79b067622c9eL, 0x31fc5882f8f2c075L, + 0x9232b37ea6008515L, 0x4d7bb36182e8c5baL, 0xbf24735cd2f146feL, + 0x79c280ee9cd2db98L }, + { 0xbdcc8203f2b48122L, 0xa8c04916b04ac48eL, 0xacf064dc9fc4885eL, + 0xab83899782c1001cL, 0x7339e721676de250L, 0x17aa5aea8e1ab820L, + 0x24d28ca06bc14b2eL, 0x570c5bb7816b6230L, 0x6c51235ccee6b606L, + 0x1b2bf89f183eae42L, 0x3e3af3c69c66274bL, 0xe0b04426b51e38bcL, + 0x26dbc58e73e40e3bL, 0x3f9dd578b5be5be4L, 0x9fd9f79152c8f408L, + 0x758073a4a9e3ff4fL }, + { 0x7d27b0578691ca22L, 0xf206bfd613a2a1b6L, 0xe84bd385ac795413L, + 0xc5d18a2a75536607L, 0x2e166de7c8a0e24cL, 0x56d5750c3c474dbdL, + 0xdef444c11366843aL, 0x14646e53cf4b8432L, 0x4bc0d030a9fd9783L, + 0xbda4c824297ee203L, 0x3d0b10bffd7be6c7L, 0x2d21647608c7f3ffL, + 0x06e52599b4fd4c45L, 0xfbab9fa149e9e104L, 0x9342a7fa8661d32dL, + 0x3f3e3458faf66aa8L }, + { 0x51ec35af951597aaL, 0xb677d4ac49df64ebL, 0x0276cd9c9bf4eff5L, + 0x423eca49515a2935L, 0x8a696553fd9bb9c3L, 0xf99ee9dfede1f09cL, + 0xb8fa2956199e5f98L, 0xb763875835292c32L, 0x8734eddcfc40e81bL, + 0xd82d5e9f65457d95L, 0xc8ee323e30c78d2bL, 0xe77b2e4cc1433d67L, + 0x56d9f8073c8314aeL, 0x441eede22a0e2f63L, 0x1e9e17ed6c48295eL, + 0x640d20c434c294efL }, + { 0x4e9a0b8e3284d513L, 0x074c3545f315053aL, 0xb36e740745acd52aL, + 0xd80bdcfc1de50db7L, 0x8d9d47dc2549fc46L, 0x29b6ef13303f07a8L, + 0x4e461aca6d4ad4c2L, 0xca8e351dfc9f1b73L, 0x8bc4094d57460e65L, + 0xb6302b330f32d367L, 0x69a074b6285742e8L, 0xdfe52b11876c29c3L, + 0xf39e4609912bd17aL, 0x8ee40d66349aa639L, 0xb968902ac72e05c1L, + 0x0f9c1ca8c0d92816L }, + { 0x1ebbaab367433df3L, 0xb6aa534715d3628cL, 0x13a320d897f0c5ccL, + 0x72c918cb65e408f9L, 0x4b638854d5373451L, 0x731399a30b4dca09L, + 0xcf2567300a3b1326L, 0x5ea60dfa6608b388L, 0x58ad74b07b290dfdL, + 0x83202789d7694f9bL, 0x48593db8b6630fb1L, 0x3db47f70c65e3eafL, + 0x63949c913e7263f8L, 0x9b9acec6e6e6ff33L, 0x34bd9ba7098a8240L, + 0x7e31c12f45d36ec5L }, + { 0xbe281d680dfd2dd7L, 0x1efacb0024ab61d8L, 0xb9c3005f94431f97L, + 0x660c8dfa959cb3bcL, 0xfdd5fc30cffbb406L, 0x7a4631be7969a10dL, + 0x336e309ede13fd1bL, 0x76b3bfadfc947076L, 0xfa91925ddcc72223L, + 0x741f0d73156c4ee1L, 0x4f64ee410e2b3747L, 0x86be92d3efc4d93cL, + 0xc53b7e03fc4fbb2eL, 0xac196cf5337ca1bbL, 0x4de41a307e23ba60L, + 0x1a219c45326d5357L }, + { 0xfdcf7ef8aa4db0bcL, 0x2e2318067b6c9963L, 0xc26390673d8a192fL, + 0xc0cec2e2ffdc7771L, 0x997c8e35a2fc0edbL, 0x78e10ec182cc6043L, + 0xfd0de2cb2b0c8120L, 0x4d6c457f69e57f8eL, 0x953e69b25b53f1c3L, + 0x422a330ac4f89cb8L, 0x92ff232995566be6L, 0x73cd502d437442d1L, + 0xf04ce590bea69403L, 0x6ac1537ef8030662L, 0xe02bcf77b6d0bf93L, + 0x17aaa999bc90192fL }, + { 0x0d3d56438e55db2eL, 0x835dee433b946851L, 0x1a1440e55b88462fL, + 0xa6ff3b35ea17e27cL, 0x23f99c36dd95f7a9L, 0x7217fdd9bdd672cfL, + 0xf400ac1edd2045c0L, 0x94b55c874ff06b25L, 0x0a44a0e50e4a49beL, + 0xe8925e91b43b6813L, 0x78bedde1214f96c5L, 0x0f456a4c0f97fa97L, + 0xa28fd86ba5bfd267L, 0x3b4b2d8fbe7608efL, 0xfbd5ff8c226474bcL, + 0x6b282af0a5f3b24aL }, + { 0x78fc025f6341a595L, 0x591c38d6a445e28cL, 0x72bd6e3deb446842L, + 0x3f9466d375547833L, 0x911414d3083e16c4L, 0x145d946695a7acb4L, + 0x102ddf098fd2fb64L, 0x2a2b2d2d0bfd87b1L, 0x69e9be5c59455088L, + 0xee378bf4a80245deL, 0x80b0bd68b2306b0eL, 0x76a545c6c2be9f3dL, + 0x429d167b4802c245L, 0x13e644272b412dfbL, 0xb664f529ee8d9762L, + 0x6d4f5d2354706ebfL }, + { 0x35c8f2b600ba9f88L, 0xfdc807e07bb6d0bfL, 0x0a126d42b3b81e5bL, + 0x335ce6cea7ac781eL, 0x3e308e6ff37dcba6L, 0x028dca6263c96487L, + 0x72eba57e8818434dL, 0xa9e3d59f79b78a26L, 0xd2f0a7dd2f07aea3L, + 0xe0fe467824d05f74L, 0xb20851700116deb6L, 0x9c2a5e9258f37580L, + 0xe78bd7a574070bb3L, 0x551fc872b9977d90L, 0x6eda93c440db81b4L, + 0x4aaf0b4fd65d34adL }, + { 0x9bef25063514c7afL, 0xb09e7dadbc181eadL, 0xef3cae878fa3ec58L, + 0xd8dbfab5173b8685L, 0xb2490fc0921d32ddL, 0x4eef386b8bd9c466L, + 0xc1cdd52fa061dbdbL, 0x64de989a25bc04dbL, 0x06f9836b85728636L, + 0x11a5a8048be44aa0L, 0x16dede4e097018c7L, 0x72aec577b2c11fb1L, + 0x144dade1a721ecd9L, 0xf99c526bd6ebf3a9L, 0xa1d4165b1c2e14d7L, + 0x8b2cbd3982bc6337L }, + { 0x28ec1bf28a52e991L, 0x0ba202f6cf9d42ecL, 0x8307d130c634ea45L, + 0x3fc257b3c5762b9cL, 0xbd3298d1487c2a2dL, 0xca14f1a7a319488aL, + 0xc70ca93b06ba06d2L, 0x9aa3f4b3ee405e89L, 0xcc64eeb335deeae7L, + 0xd155f57803bf1d4cL, 0x041ec0b545616bfdL, 0x23df80e6086e33f6L, + 0x399a79c8f0243cf5L, 0x86c2824e874ccd58L, 0x220eeaec8fc5c831L, + 0x57e283047dbe3670L }, + { 0x6e60b698fbcdf666L, 0xbdd06a998bebb1d2L, 0x4044adba80498436L, + 0xd76bf75e522bc88dL, 0x655c4b9b28423b20L, 0x65c0f49253398a72L, + 0x76d4f2b70ca37601L, 0x469899252030fa5aL, 0x96b37e87b6054705L, + 0xef96f73153de1b2fL, 0x5ecbbc8cad54ef05L, 0xeb289d0aa93617b0L, + 0x3ac0fbd57cba217dL, 0xd0d3cb5619d4a2d7L, 0xe8bee9d4c91d6063L, + 0x4f12e037696ffda6L }, + { 0x4ccfa42215f1a610L, 0x804a5c553786519aL, 0x1246a45473838134L, + 0xfa15b4844b284e2aL, 0x36464c65146d1320L, 0xfb6ba88c70a8a0faL, + 0x74e7cee793c4804eL, 0x8c34d22cb95ae16aL, 0x9d9ed89ff9c1d4ddL, + 0x61a0866d32025371L, 0x45b232b29bd6444aL, 0xf888e92cf277bab1L, + 0x73e69c6ea9448b02L, 0x1a496ea95b521ecbL, 0xa8f78ea75858afb2L, + 0x83d2333eb1266f91L }, + { 0x1c63328867b478d7L, 0xa1ee1ae150a2fc9cL, 0x05b6ab3018d2241bL, + 0x69f1f288893cd696L, 0x159d6660a8117a87L, 0xe812011970e73d77L, + 0x528fef0093f55f0aL, 0xb3978db8d854dfb2L, 0xd6b43ef6f45d9fbbL, + 0x17de4bfed5bee397L, 0xa01e0f596bf76dadL, 0x28b2280e3d40754cL, + 0x8edb6122f8e86ef3L, 0x8226b6afb7d1e586L, 0x463532152f40a55bL, + 0x7362f13ec5a31621L }, + { 0x792eb27c73c0c430L, 0x8cc0a65fa51c3657L, 0x50a5ceced2194f1bL, + 0x18945688814b4947L, 0xbbf0a81a4b6fbbf4L, 0x376f4f58f0aa8608L, + 0xd9361d683987795eL, 0xb6510cd8e3a8d0d5L, 0x63e2fdbfb6c1a455L, + 0x2c91154eaec891f9L, 0x0eb1e715ff568f64L, 0xe7af9cd72f2b399eL, + 0x1fc39bac89f0bf0bL, 0xf0861d9290983695L, 0xd9b16f02da0a20a8L, + 0x2f10693fa38c0eadL }, + { 0x07a6ce910c06ded2L, 0xf974842f2fd9087bL, 0xe468bfd6a9f635a6L, + 0x04b618911ed60626L, 0x1fb2f89f369ee548L, 0x9cbd1113dc96a201L, + 0x6759acfe10d633acL, 0x64ba66fc8faa629eL, 0xa686ae4947f38283L, + 0x828c3a05d59cda99L, 0x7c7afb1408ea2f6eL, 0x2551c8e4af3953c8L, + 0x5b53d2799daa9e4fL, 0x1eff68d4ad6f1940L, 0x2775dbdd96437cdbL, + 0x985f83e44fe7a043L }, + { 0x89603c16eaf45294L, 0x70131160c24b5751L, 0x4c11201839d6b52dL, + 0x7079cf02ed943340L, 0x0c5b028b74f41b68L, 0x3dc3f0769c8ac1e1L, + 0x5ac5eea3f8b24f0eL, 0xee6684bae34c5c22L, 0xa5259e639abc452aL, + 0xb07d2cd1e9df45ccL, 0x07019c931a443cfaL, 0x68fddaa992c003b3L, + 0x2d9f179c0d8cbc2eL, 0xbbf15a6f1e781ca7L, 0x54d779d550dcc799L, + 0x0c88e5400fe962f1L }, + { 0x84f71a6ae8f44357L, 0xf75b4bf63a3cab6aL, 0x334c9d9e5aebc680L, + 0xcecaf0848a753ef2L, 0xe28014c1075e3c8eL, 0xbb9d5a38f74f8d3aL, + 0x75988464b80e32aeL, 0x7b328e6ff2bc3792L, 0xebbb1fafeed0e197L, + 0x674eac955a33065aL, 0x8c19fd8f922dbce8L, 0x8c17ae85987b907aL, + 0x89f336273b3a2cd7L, 0xebaea019fa87772fL, 0x4e5de4993a25ced6L, + 0x8e2560b8af110715L }, + { 0x56d3746c3141aba6L, 0x45a1079fbab2cf9eL, 0xb63828319cdd27c7L, + 0x222376329dfd950eL, 0x1e0b15cd3a9408ffL, 0x49a80200b1160118L, + 0x2719db5da383bba7L, 0x6078340a651046d5L, 0x8929d4de97523b1fL, + 0x4040345c8e0a28abL, 0x61275ac20adf09c7L, 0xb41ab2652331d611L, + 0x230cc77c5391ca50L, 0x88be0c928f922315L, 0xfef3d92b92fd9a29L, + 0x59005f228324f2e5L }, + { 0x6bb1750c3c4c1c74L, 0xbe73aac0e966fb79L, 0x85a75d9266c5973fL, + 0x8c97f9323a8656b6L, 0x2b7043b150446cdeL, 0x548916f73ff3897fL, + 0x913dd01cb18b72b2L, 0xd0a751f1488c0de6L, 0x191757148558ca58L, + 0x9771430144a663daL, 0x2df190acb0e08618L, 0x0080fc0cf39ead9cL, + 0x0085ac6e17382da1L, 0xe97918513262a338L, 0xe4495936b43bae8dL, + 0x57a78e26d783df6eL }, + { 0x161b346f40dbddd8L, 0x2b49a9279410c3acL, 0x8c5427831886cf3bL, + 0x72df323233b93debL, 0x9c8d59f540df579dL, 0xe5d7a67dc20ef500L, + 0xc46b391867f08643L, 0xecfa2445ad96adc3L, 0x658f589b0c4544d0L, + 0xe6ec9301e08417d7L, 0x6ca5ef6ac454e288L, 0x4191048fac0f462dL, + 0x852407d808d8a036L, 0xb4c533a7f6d35b7eL, 0x3251e4128f6ada87L, + 0x1ca370c581c472e8L }, + { 0x94bd5171a801b68aL, 0x7312879cfd1998b3L, 0x4905aabf41163202L, + 0xb5fe87f4f5b01fdbL, 0x78de523a9cda128bL, 0x0bf161a1c7bd31f7L, + 0xb5decfd023904c35L, 0x224b2882e188f12dL, 0x0dd2801df99dae74L, + 0xcad467b508cd1cd2L, 0x6c311c3dc0867e39L, 0x71a117202b425072L, + 0x83bf464e2efd9003L, 0x53d0448a1dbd3b03L, 0x32db52f4e6265baaL, + 0x2584b34c4c33ac79L }, + { 0x3cb863892aeec688L, 0xa5e740ba45fbe523L, 0x422e71f7fd60b5f8L, + 0x455d185c4874913dL, 0x04c2bb36fa17d80dL, 0x3f271854ac054524L, + 0x76dd3045a8b9a657L, 0x2e42c3e162ee7cc8L, 0x002667064df6c7d0L, + 0x5927dd51dc7cb488L, 0x6b3faabe187897e0L, 0xfe6ad22ef2d5737cL, + 0xafb60269ff51a9ffL, 0xe1c8354569807baaL, 0xacddb6ff951ca49aL, + 0x7e8113743f9ab085L }, + { 0xad722a8b830a88b1L, 0x91918ea8ce1117e1L, 0x3e02d0b80409b47dL, + 0xb53812d36c46d1d3L, 0x2fd09db0e589669cL, 0x9845cd0615b0cd5eL, + 0x0c1c155a2386c453L, 0xda774de5f5ff43cbL, 0xbb076b98e391c0cdL, + 0x97d71eff5004f286L, 0x23e0b46caeec0bfeL, 0xe453866732a1ad94L, + 0xfe0c9f81396da422L, 0x6376c1a263db2bfeL, 0x001c7918ba56fa91L, + 0x436b8c64df8485a6L }, + { 0x88117e9d8ab764bcL, 0xdfa61e94a077df84L, 0x5a7765d30c18eebdL, + 0x548916affc9451dcL, 0x01a52e33071a347aL, 0x633b95deb23b41dfL, + 0xdd7d68c943c8c286L, 0xe4f9d41e18d97068L, 0x79908b908c92799dL, + 0xe614148ed47394a3L, 0xe5018517cd51e53fL, 0x5060075e0243dcb6L, + 0xe5dcde6217954405L, 0x6f7c90e1537da5ffL, 0x1df7aae40768cb66L, + 0x5266ca9e6dbe95e1L }, + { 0x84ddee6d1386b3dbL, 0xf9e4af5a7c38e540L, 0xb3418440eb04f49dL, + 0x2138a1e8fde5a4fdL, 0x3e6e692430257cfcL, 0x3519c6e319fd70c1L, + 0x8f34e17486c31ff0L, 0xf1e298fd940ce1e8L, 0x6fb8cb1d14960d7cL, + 0x207c13472b2f3bffL, 0x899a20b4146ef8ffL, 0x7dec362b7bd3e220L, + 0xa975044e626bea27L, 0x0f32b4494fb4cb67L, 0xc17a09201fc6703aL, + 0x41f325b99cd84a2bL }, + { 0x312ed513ce2843a4L, 0xe748498e00728afcL, 0xa8ef28224d864ce5L, + 0x34064704a620083bL, 0x5905e1d94bed338dL, 0x2a578cb5063e7b38L, + 0x98276d96289e7bb9L, 0xdfe2dc47f17b7341L, 0x5923521f1dac8944L, + 0x3db6d28d23400aa7L, 0xc647705ea761ba43L, 0x8947ba6d9bfd07ddL, + 0x00f2e3ac242ca8fdL, 0x49ef4670eb8c3468L, 0x7db3d37bd9aa18fdL, + 0x56b30fb6e58cea9eL }, + { 0x07ecdcaacd80a428L, 0x7af922dc8732c891L, 0x20d887983ada441fL, + 0x3bed9a44924b008aL, 0x2123533cb2e81c3aL, 0xc34e407565f807d3L, + 0x0bfaefa51f2faecbL, 0x78b634a5ade8a88dL, 0xc4e0b7f894392a91L, + 0x3092237790bb1cd8L, 0xdea9b4faf87204aeL, 0x3edf81f585d3cd83L, + 0x58f88c51c6523a79L, 0xe472fb8b17c0d969L, 0x899081e5dccf7f07L, + 0x1353cc5758bdd146L }, + { 0x28a5649739bf6e18L, 0x59e8b5a2649b89c7L, 0x8d9434a0dce8b8e7L, + 0xd935bf512047040cL, 0x2ab3a1646a7b8e82L, 0xf1583ed627f81294L, + 0x8416a7e072d67297L, 0x49685d86cd39e42bL, 0x8a797fc7958ddbadL, + 0xa558f928155ce6deL, 0x75f4e570f8a36235L, 0xbc69cfc052877ae5L, + 0x8f4193a9a6b16ebdL, 0x8d1df43cbb1cc1f1L, 0x723a830e5a21e789L, + 0x3ec2185df451df58L }, + { 0xb9d4c7d71f0bc2d7L, 0x6982c6cc6e51d412L, 0x92e02d93a09f80f6L, + 0xb7dd2d25047ae09cL, 0x3503149f37f351f9L, 0x69d49ce1c77850beL, + 0x60242acb12f0d2c8L, 0xba188c567bc28b9dL, 0x8e40612106bc0550L, + 0xb0d84b1f8d7d4329L, 0xb4a67ae7d38951e0L, 0xb527c57b8bc97607L, + 0xbc93c5f35497aa72L, 0x5f1de8cc39bdd666L, 0x3087dc5ce9d447a3L, + 0x89b356b6a211abe5L }, + { 0xed6db0afdfdcc837L, 0x0fb80baaa871b7a9L, 0x413abfc91c1d4b72L, + 0xf5b56bf7adac9e5cL, 0x5664a2da8b8657a3L, 0x11b04f720e41d94eL, + 0x63e11d2637433658L, 0xee628ecef426daeaL, 0x011619c9cb162dc2L, + 0x9cf5817f87648643L, 0xe1bb97025584bc86L, 0x2cc27cef00bf7928L, + 0x4ef3a80edc60eee5L, 0x7e1202be87adc2f9L, 0x656f18e08a0d4f52L, + 0x39c4f10d57c5d126L }, + { 0xb3a9b68ce88aecd3L, 0x555b0918a518aa9dL, 0xedc1cdad4bd4ee54L, + 0x79b68b6702068d84L, 0x7dac80d0811ac72dL, 0x6d1e6d35a81a0a78L, + 0xc841e9ea3bd16283L, 0xa7bc1775894c4444L, 0xf2b63725f1aa1202L, + 0xbec7767ec7d4c556L, 0x2817ebb3d46ff51bL, 0xfde5be8d73f7e339L, + 0x44c6c9775aed24c4L, 0x0b9a1707b6e579cfL, 0xcff164789069fbccL, + 0x414b542d49152b00L }, + { 0x33c31e58606e173bL, 0x5b7f4e1b90e6713aL, 0x425fb512debb20afL, + 0xc788c61705120e70L, 0x3ef056029013e4ecL, 0x9f9d35ac81c6e6d7L, + 0xe131e88f9450690aL, 0x708f9b3244af082eL, 0xb2e4d66c1ba2aea9L, + 0xaf1f4a6e740db29cL, 0x74ab9248d1843007L, 0x13338ef8ed556a6cL, + 0xf48e623e270d17a6L, 0x3c7362fa9608f5bfL, 0x43977874444e8515L, + 0x52678d6ae00b8b2aL }, + { 0x5dff1c59df36aeb4L, 0x52d6653ca92bc0abL, 0x0e03f496927a5f81L, + 0x8509d4142dfd491fL, 0x258c2c52a571f89bL, 0x2bd6180493334485L, + 0x1a33e94f3f7d9e09L, 0xfab418d32c1bf906L, 0xf39c490e5aa5695cL, + 0x0e41196ef6d2d7ffL, 0x3ecd40750f7948a9L, 0x4b58f9b2d3053b4fL, + 0xb8ee842a5d9974c9L, 0x23a59c1dbf22f682L, 0x045ac614c8efcea6L, + 0x7040ba5bc10ceeddL }, + { 0x2c364f81515a1a96L, 0x31a63503184327e0L, 0x0a0966501ad93d4fL, + 0x9d7694f1273b6173L, 0x8886d876d2cda9d2L, 0x1e01a7422814c177L, + 0x3492276b8667696bL, 0x2fd4f0c65b25f006L, 0x6527349ffb294c4aL, + 0xc1fe0d8ade1d336fL, 0xaf9a23e8e7e3860eL, 0x97d2b721b774c31eL, + 0xfac3e5824365784aL, 0xff2dff4e70f4eaa3L, 0x3d281e1afe873248L, + 0x9043a6d60bd1c9c1L }, + { 0x1511a0fe766c7937L, 0x1b2ded5cabbc3be3L, 0x2ac160cce00888acL, + 0x928754bd616200f3L, 0xb801c83d34a2ea06L, 0x8ad7a03a9cbe106fL, + 0x996b0822cedfcd94L, 0xc3c3463ae4069880L, 0xfb12ea4df597f663L, + 0x2c8d383440c92af9L, 0x79bc85c64e8da154L, 0x95771fa2db4e801aL, + 0x7bd2c1381e3579b2L, 0xe45c75dfffaad078L, 0xb0760a3cb73eac46L, + 0x26362b483a125f35L }, + { 0x25c68d28eefc3e89L, 0x2d0ee87769e9ee71L, 0x8b07bb86af5e4b75L, + 0xdb709072cb86b333L, 0xfd3d20eaff552bacL, 0xa5eeb2b14c0da1e9L, + 0x391f688a44f97145L, 0x21fbd3101e06d485L, 0x45e4f2a5bea9cd49L, + 0x7b60d464a7bf21daL, 0x193f88c8054d5471L, 0x5ace53d1bee0f2e9L, + 0x92c26563c1439273L, 0x9c86e0b296c6b5eeL, 0x452fe23109ff59baL, + 0x2e952b20555c935eL }, + { 0x2a846bcad75f886eL, 0xe68a5dbed43dfc58L, 0x103e45b6007b1b86L, + 0x580e2ec9355ff2b5L, 0xbc702f26a263ecc9L, 0x2835b386181e5e33L, + 0x025113ec6c122076L, 0xa5c26e3a7fbd856dL, 0x8ef83fb39d6ebcb1L, + 0x7aaa53f2a44d2fa8L, 0x7c14ef3353b1fa97L, 0xff604a1117559a30L, + 0x2bcd96b0b09377e0L, 0xa5c14896db2f0273L, 0x1c0a84c9eb53ef06L, + 0x1236d01730378e4bL }, + { 0xd7481c8fc084373bL, 0x29ae4768646097aeL, 0x1300dfa0613bc34bL, + 0x3712714c934bc2b0L, 0x865246290e2be7e2L, 0x554fbb9fed010800L, + 0xf0ec0b3842314576L, 0x65baf594330a3282L, 0x3bdde1a8706ef817L, + 0x7d2c727dba7530e9L, 0xbb0c5d6674cc95cbL, 0xb3fcd3652438906dL, + 0x19881941d14658f3L, 0xe616f5556c97f0e9L, 0x353c2d854b9ec7eaL, + 0x02a48014620cb56eL }, + { 0x11d6d23d506ccd38L, 0x229a1c549059baa6L, 0x717c9c2769d011c5L, + 0xe87e1b46d828937dL, 0xf5d63bbb83835083L, 0xf0a7b427aadac258L, + 0x99ab26bd9f154d1fL, 0xdec0ffbf8ec955fdL, 0xee957c6749fcb880L, + 0x32395dee1e0114deL, 0x192a64b7369f46c7L, 0x4304466091eb2599L, + 0xbe2da887a2e8c3daL, 0xa44e2c25c3556d18L, 0x31390414b55f75f3L, + 0x1d8bde6f8f217fe0L }, + { 0x03cd39f8a2028924L, 0x6e54f19cb06ecb9fL, 0x862bbcb7d6f05846L, + 0xdbe067165a060776L, 0x9397c97ab10fec10L, 0xf42138266f1bb65cL, + 0x414deccba672ba38L, 0x594d4d43f88b05e6L, 0x7993f57aac94d4d1L, + 0x74fc2a6abfb17638L, 0xd8196b5bb6fc655aL, 0xdc375c84ee8d2139L, + 0xb9b00a02360d3a26L, 0xb36ed35cdeb93b87L, 0xf565b28bcc83209eL, + 0x349c6943c61013c1L }, + { 0xd1b394444de6c88aL, 0xd5c2c4714700207eL, 0xb6f458a221c2b780L, + 0x749f75640850993eL, 0x400ba579baef0c18L, 0x2d742938737c70f0L, + 0xc5a8e2ec21467ebfL, 0x243a666e5337f453L, 0xc991f1c7ed0bd50aL, + 0x3a7f3e90f4bd1f91L, 0x96089e8a5f0e129bL, 0xd0d3a17707389635L, + 0x9cf842d527182ac9L, 0x211952990817c5c2L, 0xa32f327e87255769L, + 0x056587ab89c2d8faL }, + { 0x008562ed1ce4733dL, 0x5faff7cb98e51444L, 0x5f03021fa9ab46b9L, + 0x89494c5eb61a8c13L, 0x57c9503636b35976L, 0x6be84c8f2ac2d2f6L, + 0x0e5b34d89bd2703eL, 0xc4ad918f7e872abbL, 0xc2a89e9fc4052ee1L, + 0xc2caee3f3190b51eL, 0x58fd14376fff254fL, 0x6f3c0d68883e0972L, + 0x63d0a0e90fb15438L, 0xc438764bf6caae00L, 0x815f15653f1d0f6cL, + 0x1b87f2edb86cdbdeL }, + { 0x35792bbb2b0b15b1L, 0xa3e4b5a7ce6ba779L, 0xfbacffd9dd8f3779L, + 0x005450bdc298d1efL, 0x0e3f5556c47031c6L, 0x0770f07a95d68066L, + 0xce3e84e02d1052c2L, 0xb050791e7aa8cc54L, 0x4d621e73ba3223a3L, + 0x87b9b94d39632990L, 0x8df9cb477eb8056dL, 0xe2430de8edfca0ccL, + 0x374bf4169712a0caL, 0xbe3f3c7788848a99L, 0xb22b87b1c4a3e59eL, + 0x8e0227c43e95bc23L }, + { 0x000e22a83210964dL, 0xdccd5df5ff056eebL, 0x02173a1fdaf1ead7L, + 0xd02833e067cdcae3L, 0x1cc574cb8bdcc90cL, 0x86eca7143224b4f5L, + 0xd00e603abb3f8298L, 0xb98ece1b0c1a8debL, 0x228a46e4378c261dL, + 0xc6f9dd0da6165e5dL, 0xb3ae38994b7ef0e2L, 0x3a3c16b3bda9f306L, + 0x5e9a26d338a084dbL, 0x528e59935394e950L, 0x848ecb114ea206bcL, + 0x14b15ab540545d6eL }, + { 0x0f6d86c9664c59a2L, 0x3dfe2be160fd7aa5L, 0x33f9b5699072cb8eL, + 0x5f2325d98176a7e0L, 0x79a0d4e74587080bL, 0xa4ee0def0d5d4e05L, + 0xc0ad9ffac87b28e1L, 0xd6f18d2f3f09b4eeL, 0xcc896ae7292e9d87L, + 0xca88953d6094763cL, 0xdbee97a818fbf9faL, 0xdf20e0e94b63d701L, + 0xcbba6e3047ea722fL, 0xce57e1ca612b571fL, 0x1e16ac76009a55f5L, + 0x742bbed8c4389e2eL }, + { 0x23ea86dcc1dc2c73L, 0x4bbbfd5bc1643abfL, 0x07f8fa1f24d8ca1fL, + 0xde68a6e08cb5cac7L, 0x7d54c64b54e66a7dL, 0x789dba22a9b7ad78L, + 0x4d88d540e364ab94L, 0xc8c2e02d1f72e011L, 0x4c82605746e2a278L, + 0xe6c35bb34b187c7dL, 0xed8b3dfeeb8fe0c9L, 0xb6bc34e87d11e415L, + 0xb3908bbfb865c7f9L, 0x717d1ce6e1ecc17cL, 0x151e3308f7cdd69bL, + 0x97bd5a14b5c94124L }, + { 0xe01c62fe81e82861L, 0x703d4b6ddd42c40eL, 0x7e52e55be65e91e5L, + 0xb8b493745abbbfddL, 0xb4f15f52c72a45f4L, 0xce8435a8550f29d8L, + 0x9df76b9b582de75fL, 0x52e84c5fa20c8b96L, 0xaf77d2d10a8a0af4L, + 0x0389bbd8ca6013c3L, 0xb0d9b9ba26f8305fL, 0xf053e8480cec8b9aL, + 0x4d63367affabda18L, 0x50f53be4a6424c2aL, 0xf892c58c864fba2eL, + 0x317c6d3148cc5469L }, + { 0x0c3525b02cb7d42bL, 0x55240bc9310facaeL, 0x8d5d2022ff20408fL, + 0x6b01402fe0c10ea0L, 0x7fbef68a718eb23dL, 0xa0146b5a41252a19L, + 0x59afce48110e0d6eL, 0xe9a1d27f022de181L, 0x6db96d16dc3f49daL, + 0xfc1ae3f5efbe4008L, 0xf9d70641eccbc11cL, 0x49022279525f8636L, + 0x3769796ac2763c30L, 0x9cc3483c1d90630bL, 0x451651f0ee3d3f17L, + 0x6ae597399da0b8fdL }, + { 0x57b13bc7bff4d2eeL, 0x2075422930b173d8L, 0xb6254bd50794936cL, + 0x1d5f232a5efd55beL, 0xc06f4a854e0c3389L, 0xcf2c5b598e61f944L, + 0xc564861ffd5f87b7L, 0xee261fb15a2afa4cL, 0xb0ff72262d97a774L, + 0x1a89ae22d6cf007aL, 0x28880534d346f214L, 0x8fe73bff97b6497eL, + 0x8a8595b2fa2afffcL, 0x9ef9cf3ef151a726L, 0xa84ee5f1e744b82bL, + 0x6649048dbc63fe72L }, + { 0x91b7bb781e8b760dL, 0xd47b0bd825aadaa0L, 0x81493d9ffab5226fL, + 0x4a6dd226bffc148eL, 0x5a032f8aa29be3dbL, 0x318dbc7034b0ab0bL, + 0xdcccbfb57d654868L, 0x8506ab379c581e46L, 0x09136a6e2830ece2L, + 0x48b79356cf6c80c7L, 0xfa176377ef6b1e86L, 0x2c9c1cc183f0f1c9L, + 0x96f0526d16abedddL, 0x3e0e98e2a93b0de4L, 0x6f2d7ada0f13873aL, + 0x4eb93b5cf3fa49ecL }, + { 0xbd89f7e5e11fae32L, 0xd13d74f5c4023f51L, 0x1b0014df491c3f6fL, + 0x1d849a57555279b7L, 0xbb9e889705ba0068L, 0x82222419c13ca2caL, + 0xafbbb685fd33676fL, 0x931c3f5275878a2aL, 0x12aeefefef3d5173L, + 0x189a5cc8bd8a6878L, 0x82cffdb3d99f0c16L, 0xbf565406a19d48b6L, + 0x5605e223e9c6c4e0L, 0x53e781de86804172L, 0xcdf5c90bc7001cc8L, + 0x2b582d937c043f68L }, + { 0xa1165c8281abc2aeL, 0xa73380f5e2b69ecaL, 0xc097b3d207fff66fL, + 0x5d60382654776506L, 0xdcbac9f3b57fa21cL, 0x78750db4c98dbdd5L, + 0x85e21103d9eff32aL, 0xceed172c2f11c41cL, 0xa8e392649e348c09L, + 0x71cb936b831eddfbL, 0x915c3d06f50864a3L, 0xfe8e33cde93acfcdL, + 0x4bee10d7b3f2f7aaL, 0xc1d8eb48eb7cee9aL, 0x4fa49ce3fa574afdL, + 0x78615109862db4c0L }, + { 0x3fe3f4807ae72c21L, 0x631aa144fd0f0da5L, 0xc76ee1e8f8c3a454L, + 0x379ae09451b4f1abL, 0x2a3a4397d7cdbb24L, 0x7a14cffe82bd5fcdL, + 0xbbe4ed12f427ef5aL, 0x9b0a43ee284d3ccfL, 0x57b78b938eec6e1eL, + 0x18d404e467b8e87bL, 0x0c8adc0534374c20L, 0x643736055428deb5L, + 0xb4d80ec0c3afa2cfL, 0x6d51f93c3aa956f9L, 0x9f9a28ab84161c68L, + 0x540b6bb76bc9c025L }, + { 0x04e1734c321d315dL, 0x4ef56612d86e05d0L, 0xeafae145bba8cd81L, + 0x1fb07a49acdc789aL, 0x6a21e9ad5877570fL, 0x2e4a837eb9bc53deL, + 0x436db2931d6298ebL, 0x43afbc78ea362f45L, 0x2a973d97aabf6585L, + 0xdce7dabe0c924d60L, 0xf69d98f07cadf0e9L, 0xe0b505a175020538L, + 0x3db7d1a34461cd29L, 0xe1c287765e20e818L, 0x2ca2586752dd50f6L, + 0x897cab1492e0388cL }, + { 0x59ed38130d8bab8aL, 0xc11d364ca438200aL, 0x0687bf2c40581415L, + 0x86ad0d3a7ac89674L, 0x44928105b97411a0L, 0x74984b11f383371cL, + 0x70d2ed840d1a831eL, 0xd883628b6c912fe0L, 0x44f8f7fb14fa88d2L, + 0x564f2a4dcf0ac93eL, 0x82f629aaa6c24fa6L, 0xab906ba3bf6cd949L, + 0x2c822e6720a5182dL, 0x2ff47dac30eb93a5L, 0xdc62c4a4fff673aaL, + 0x64b00763476b0ec5L }, + { 0x1e3f533eb3c9a404L, 0xb1db7f73b7ef9952L, 0xc7f13e296c253693L, + 0x7ce7f4c40738eed4L, 0xccfd3b33ce26cad0L, 0xd878493501ec5cf1L, + 0x3f8fc09ddc084e01L, 0x217cab32c39b5acfL, 0x42daf0bb9ef5551cL, + 0xfbc76f56e1217a95L, 0x80178b12c237002aL, 0x0b52c39fb070a293L, + 0xe3925153576ca964L, 0x2555942419d68e36L, 0x291fb82c09e50e84L, + 0x7dd22ea66618ed8cL }, + { 0x7ffe844b49cbb3bfL, 0xde0cc7045562fb25L, 0x1e6ee5379f5a845aL, + 0x956d7f26e51277fcL, 0x2c75d4b930635718L, 0x39a1489296957f34L, + 0x8cf4eb3282e5742bL, 0x6b0d3ddd83247b72L, 0x67a9f633201a4237L, + 0x416403c11414a485L, 0x60afd447b6f6a916L, 0x95f94930dac6f790L, + 0x685ff94bbd3b9d82L, 0x5c8f98fc51cadf0fL, 0x9559c88ab13b7489L, + 0x31377c665f18fcc8L }, + { 0x35c5de097dcfb35fL, 0x2dccca9f01cc36f8L, 0x7e93e85d7576cb63L, + 0x0c2dd48af7b4b375L, 0x9d95cd4fb09a19b5L, 0x752ed15971bfe607L, + 0x439880cf2596dad2L, 0xe52efb5369e90a6fL, 0x4409766303d3e60aL, + 0xfcf364faa95070e0L, 0xd8f993b605624dd2L, 0xb35a982400d5e467L, + 0xe289d0240c8f4524L, 0xef45423c648a0179L, 0x3a5fd695587edabdL, + 0x3dacc50ca11e5271L }, + { 0xcb3e4f946499ae4cL, 0xa46dcbe17053c527L, 0x807f5ce9be782e8aL, + 0xb6c64d28d8481e45L, 0xf35e4518aa286fd0L, 0xf7b7b9badf1cdb49L, + 0xf3fb6210aec23eafL, 0x0a9ba385b9bfd2fbL, 0xe51a0d538807f3a0L, + 0x7ab24404b17b2842L, 0x6fd57687f9dd9f0aL, 0xcd1efdb4f3e9df64L, + 0x5dd2df7a60df194dL, 0xbed3f2c3e069df05L, 0x469b756123248a31L, + 0x866949e1694744f7L }, + { 0x3a9a0da53f4ab07aL, 0x2cd6f333f54a6fbfL, 0x0c92e921b23cf290L, + 0xc9581c3e848e3d58L, 0x93af1fbdd3b218abL, 0x38598ea1066cb4d7L, + 0x5001394e990c03a0L, 0x3b664b1e7d0877b5L, 0xd79db1bbd74c7091L, + 0x852d44354e2d5dd0L, 0x0d2b841b3329db82L, 0xfa844eb07b96d480L, + 0x37a50569c295dc46L, 0xc2d3837394f7ec4eL, 0xdc3884ff5b083177L, + 0x574352b88b1fa598L }, + { 0xed2193f70d5d7ce9L, 0x3c19fd260b487eafL, 0x7c44ab597be65fd0L, + 0xdd9da86078270d56L, 0x8a84ec00baa70198L, 0x2ec27e49285985dfL, + 0x996ccaf0de2028d8L, 0x4e7648c761c2201dL, 0xa96335bc091c19ebL, + 0x253a3a69f0d6782bL, 0x3f204340d2946493L, 0x444521a1099f6873L, + 0x5fcbcc096996011aL, 0x3884d5d8f853a94eL, 0x2418c624d3b6a3a1L, + 0x3e431af206ae3c4fL }, + { 0xf967d93983d381f1L, 0x36501aaed0c033c3L, 0xbf3af4d054410768L, + 0xa86d15985093a6d3L, 0x43ae0741d92f2900L, 0xfeb2afa636f0b755L, + 0xd090a6a3aa456d6fL, 0x336a4fdaaefdb646L, 0xfd1bfe441a942f7dL, + 0x7fc2a3ed851ee41eL, 0x4f1c968611e935c5L, 0xcd57766653bbb343L, + 0xf26931baad896c2aL, 0x8a0fbbd186bbfa41L, 0x1c3d7d82a203cef1L, + 0x6dad3f15e2664d35L }, + { 0xd1940b7d12ec35a1L, 0x6219c5b6e7dfb128L, 0x2cc278c6f13321d5L, + 0x5e76904a33c58eb6L, 0x15090f55d9903c43L, 0x061bc926c3d96a19L, + 0x974a9f038c0acba7L, 0x7a4140217198b21bL, 0xb069599df8958c6fL, + 0x517f2f1dbebd0129L, 0x1109a613df3a8dc3L, 0x08e58448672375c5L, + 0x56590ba49383d2d3L, 0xfc3ee7c60bff837cL, 0xc87a539027d2d55fL, + 0x2438e9d45f517a3fL }, + { 0xc4a453088815af3cL, 0xe55f1a32f3c9bed5L, 0xaef1cdc997b65ddfL, + 0x61c61d9412e51eb5L, 0xbd0dac54e63f2490L, 0x6f14429cd0b3e231L, + 0xf737c3c2f1da6010L, 0x7150e04b6bbc4fb1L, 0x205b4c891be281cbL, + 0xf1b4633cd7701f5bL, 0x8b33ef462a513490L, 0xddb47c7368f1f7f2L, + 0xf4ada511bd416b67L, 0x9d2a97cdff795bb3L, 0x00a8b7b296200e67L, + 0x13f39011afe30e01L }, + { 0x3dd296ef7bd0c827L, 0x506110f34a29ff46L, 0xf87930681c9a515aL, + 0xde8d8045268bca77L, 0xcbb83024998045dfL, 0x3f90d71068c0e584L, + 0x2a838ca8263b6062L, 0x293bb5e7535c5d0bL, 0xceea99d556415110L, + 0xfe311ad01bbda005L, 0x2497e0bfa4d8d018L, 0x33dd77a01cf2b866L, + 0xbc075b73d8c4ba8bL, 0x298466d4722b7bc9L, 0x17a7ce24cbda1b0bL, + 0x458d4b6b680703b6L }, + { 0x8a26a20e4d54d8b2L, 0x05a5696e4d320a0dL, 0x698b5858f994f700L, + 0x7a4adc3c2f6549a8L, 0x1812e8193694d00dL, 0x46b9b000730402bdL, + 0xe10a1449a1b36410L, 0xeae95ea599230220L, 0x3efc2e9b1b4820c3L, + 0xfe5b5cb585c9eb8aL, 0x21ae031997847064L, 0x68ef0b708f27d49fL, + 0x3259ef182f72556bL, 0x00ae0457624db01aL, 0x628e3b065668f95cL, + 0x5f13f5fab6fbbf91L }, + { 0x7c6ed9ae3a9b0dc6L, 0xaea1bde96f883ec8L, 0xea66bf88ea8b3677L, + 0xdefa6abc9a66e3abL, 0xc4d3317b68217ffdL, 0xf741c8f2290df05cL, + 0x1f0fdf177d11674eL, 0xfdf0ece7c35989caL, 0x0eed92df6b9c482dL, + 0x73713e6655bf1ca7L, 0x90acb29025cec99cL, 0x37c9e3a2e803e69cL, + 0x7c0a3c5317713a1aL, 0x350dc5656f5a174dL, 0x11625a4405f802f6L, + 0x2196495da37ba4a2L }, + { 0x00cb2fd313142680L, 0xab9e91d765d14cf4L, 0xc6a0ceabdfe2669eL, + 0xbeefce580ae22bc5L, 0x3c2b7986cb6ec250L, 0x84adb1a2d738f1ffL, + 0x9709bc28516ec8ecL, 0xf36931298e8f7db5L, 0xc48efc6b95b197f9L, + 0x9ff109529aaaa404L, 0x2c3c8cbd144154b0L, 0x33ef7bc3427f3435L, + 0x04a17940d21897c1L, 0x5aa0c47d6ce548a0L, 0x2971cea73d56fa62L, + 0x93ad0eb004475f08L }, + { 0x7a0b6967988a9963L, 0x61e477f76515e8ddL, 0x6274e3863b6b50f2L, + 0x63a9b8d5d33922deL, 0x3c38d3fb687a5b3dL, 0x18f6f09c1302e323L, + 0x254c05c3e02fcccfL, 0xc04ed0b726e662f7L, 0x1d5646b8143fe079L, + 0xef8a9448c9016c8cL, 0xe5674c4bf823d797L, 0x0586f72fbccde451L, + 0xc5fc88d54417eadeL, 0x2b952209576e588dL, 0x4408dd425844d1f9L, + 0x73f8c3f0ea41c034L }, + { 0x89534fc85df763ddL, 0x3b1427f33ac71836L, 0x0db5be176e8f15a0L, + 0x1d390944cb20888eL, 0x7804c9ad857caea6L, 0xaa584428519f7bf3L, + 0x626eecf1293aa8cfL, 0x749e0d98ea36a015L, 0xefff6dae3321edcdL, + 0x963deea628b791ccL, 0xa14e05522d16e361L, 0xa2e058fcb15ae206L, + 0x0f268745fca325e4L, 0x7cf9d40721341a8aL, 0xdfed25d97caa51b8L, + 0x0108ae39adbedd75L }, + { 0x54d178f3a9e88f63L, 0xaa05b11eab0c7325L, 0x773a53e6e261d8a6L, + 0x24db7dae8d0b91c8L, 0xde10b073e9bb004dL, 0xfc8befe754e3090bL, + 0x16af05990cc69c89L, 0xddc838039d59511aL, 0xc3f65b9946c5dafcL, + 0xfbbe4be81ee0a599L, 0x88891e36fb3a9b17L, 0x0c9aad75445dad00L, + 0xdffc46abd5097e1fL, 0x8848089bac85a4e1L, 0x348bb42fa0c45233L, + 0x807c06d8eb13c1dfL }, + { 0x00a969ec98ee0ef6L, 0xba9d54838bb7b7afL, 0x24484c92a02f8fdbL, + 0x7bdb201a8b70557cL, 0xe59343e460ad1af2L, 0x53a9a942998c95fbL, + 0x974db3deda861d3bL, 0xce1525c9ed399c0eL, 0x89b56881f72109bdL, + 0x08ff7d15998211a4L, 0x5df76b3aef0f275aL, 0x93f180f7fa2f358bL, + 0xaac4ffcfc39b0634L, 0x2692c62617583b53L, 0xb2fdfa36b55399fcL, + 0x16424c6c99607a61L }, + { 0x5dd65c55dd2744a9L, 0x2544c1c2fe3af418L, 0x32c82e99efe8b089L, + 0x30b7ab25a9df691aL, 0x983845509be99674L, 0xbcecd258caf2d122L, + 0x88ae4098bcc77272L, 0xd43961414b8efa0cL, 0x44ff67b9ed64d12cL, + 0xa9e655e42e7f3404L, 0x3d16fc4545b0e9ebL, 0x474a3e14f03ded28L, + 0xa3c9adffacccb85cL, 0x3dfe6bc17253a51bL, 0xdddaf4b9fb5831b1L, + 0x5544e602a4f4478aL }, + { 0x897c5313baa80b4fL, 0x0122716f63bdc8efL, 0xae2742db7b42c5a8L, + 0xe9d9e1e90883308cL, 0x352c8c3f2d341ab1L, 0x163d0500ed945870L, + 0x8349dd73c290d9d8L, 0x2053c5e01f6c7d29L, 0x83107446cb42033cL, + 0x76c88bd209d09af1L, 0xd0f70e6eb2794681L, 0x720b59de19b1b540L, + 0x80b7ecdc22994b43L, 0xc1a4cdce2dec53cfL, 0xdd7d3edd1ed60f42L, + 0x5735995ce241d261L }, + { 0xdc4ba3fba0237056L, 0x6856c16433ab3388L, 0xc01eebbd271ec612L, + 0xabdeb033e3031becL, 0x4eee44196118a1f5L, 0xec4974215b600f33L, + 0x1b7185cf08868773L, 0x7b0c46cd7c1b7dfdL, 0xd143b2da4a4c5e89L, + 0xdb9a5984bb1ff94dL, 0xac3904e4c9cf3465L, 0xf8729bc0eace64c9L, + 0x5cc22821768ad99aL, 0xbbd3b0818a9540c2L, 0xe468ed5f049a6917L, + 0x885486df3ec45ef0L }, + { 0x6a942c934bdff464L, 0x3db2719f25a7b451L, 0xccb0070b325be324L, + 0x2055a31b19fe3339L, 0xaca69ae8241ee8ffL, 0x7607dd0855ef8defL, + 0x9e24960f1a1b73c6L, 0xbcb0e8a271d36810L, 0x29e11aa26885e6b9L, + 0x98b5d0ab185eae19L, 0x1a0b96e40f81f91cL, 0x4d0e8bcf994fc503L, + 0x33d81697f119d6e0L, 0x29083287aaa4ce0cL, 0xc5dd4d3ec91ff9d7L, + 0x31cecfe8d4ab962dL }, + { 0x437bfd9afc8b21e8L, 0xe5dd32b3b19436dfL, 0xfe5902d4921c36a0L, + 0x8e9de84da3d0fa90L, 0x9663e6ad5bb523bdL, 0x9800a23faecd6975L, + 0x1009c0d9b4fbb59cL, 0x839aa7bdc9d20ff1L, 0xf502f66decd6fa3dL, + 0x480ed4fbc5516ca9L, 0x65ffa5f66c742ac4L, 0x2b7c7945ff3252f8L, + 0x72fefc0575d9cb3dL, 0x11b0863bd6d6f1d2L, 0x5d8f3cf09a6a4ec3L, + 0x6961b46ada2547b3L }, + { 0xd07b587ecb35e2acL, 0x1ed5546b57af14d9L, 0xeca17a5bdb28a04cL, + 0xa1f91d44709d54f0L, 0xa6e719fd9c6f400eL, 0x4e4b88edfb8ce190L, + 0xf9781edd246e3fd2L, 0xd67120e6b655af5dL, 0xda782d1d93413ca7L, + 0x697e20a29707fa21L, 0x1eb51f3254e84123L, 0x2e254d9e36051f9fL, + 0xddaec42b73ce5be9L, 0x89a9a32ecd3f794fL, 0x1964e22f0781aad9L, + 0x6a63a90c53755212L }, + { 0x76554e003d7acbbbL, 0x2c01668ab74f6108L, 0xe4a29672388c519bL, + 0x016677143eb94d4fL, 0x086a3cdf0cd6d2f6L, 0xf86580217b370f7fL, + 0x658880c15a4d3e7cL, 0xd6ed58165ba3f4a1L, 0xabcc78135ca471ddL, + 0x809bf074e844a576L, 0xa53a81b36ea502eaL, 0xc20b93070e021ed3L, + 0x8c27f8928617f165L, 0xa54764468235cd0bL, 0xffc89ffd82552961L, + 0x51ed4a22d151d90eL }, + { 0x37d6963a449701b4L, 0xea8d91a3bb27caf2L, 0x3ef9be15b572965fL, + 0x75a7a055db50bf7dL, 0xfd67480ece643b9bL, 0xf2a60d2d6ceb5d5eL, + 0x68fc320c5ed7c897L, 0x41c53cf628ce685fL, 0x0e29711f7106615eL, + 0x7a87213823500eccL, 0xaf0a92606c29fe48L, 0x93df3f2ae1ef9712L, + 0x0d5f6fb1d2d169bfL, 0xeb7afe2674a9793cL, 0x4173d94ae9f49256L, + 0x2d6951bc2b8b5ce5L }, + { 0xdd007d9f904e222eL, 0x333f248f86f4e109L, 0xd4994e8b8f429eeeL, + 0x29573415cfc77518L, 0x6e7fea3a0b0f42f1L, 0xc795cb7dc2743519L, + 0x820a8f66711e71a0L, 0x83d95d9c2b874f55L, 0xd4b64d78e70e1627L, + 0x924353f58b92a742L, 0x322048b1447b5e6dL, 0x0bad730cbcf931a0L, + 0x75c4d089a7af2268L, 0x464904c1b83b93f9L, 0xa24eba02165b3aeeL, + 0x65c48e78e08cc5f0L }, + { 0x1a1c73cede222c22L, 0x5683d8cdfcea23b4L, 0x0301cb14b2143b06L, + 0x284adf8f59fcec77L, 0xfb1c581c31204cefL, 0xf54d3eee94735107L, + 0xdbf67f0b4d3188c0L, 0x76a3f2d110f18d12L, 0x3809fa2807d3e013L, + 0xf06f0a4625e7ece0L, 0xd82867edb2895d2eL, 0xe106f48908b0553aL, + 0xe2280fa6ef245445L, 0x402d5785a8d9a3cbL, 0xf63dd9ffd438ba2dL, + 0x36b5cd2c7a6b226fL }, + { 0x87ff4e20545679a7L, 0x64d80b414520c750L, 0x90a357fa9b459cd8L, + 0xa19eaf39c85af1a3L, 0x0d475d798d935a5eL, 0x74501983781a678aL, + 0x748397790cc2e810L, 0xc6a21d112f412244L, 0x8d0e85f936a51a37L, + 0xff50151eeaa74df8L, 0x14e182a793cf99c4L, 0x45593df1376a9ab6L, + 0x18f73caf522389ffL, 0xd27cc960f7445e8aL, 0x0692f4c539a51dc8L, + 0x08d7c144db39bfd8L }, + { 0x809c0d963ecca773L, 0x87ea9192d48c2156L, 0xf0eccd74db6bd641L, + 0x773123742a678cdfL, 0x7a966d8bd1587b7eL, 0xf3c1a1016130a4c6L, + 0x7cc6e8385fce17bdL, 0x95e95bb8a8de7aa4L, 0x3fe1e8b5898308e3L, + 0x0197243ee347694aL, 0xf3fe9c42bb0cd2bfL, 0xb59052640f9b2b49L, + 0x4c385e8bc7367d1fL, 0x1d3050aeb5ee147bL, 0x8e2c387904004ad9L, + 0x5f2aa8eebab70202L }, + { 0xe208d4641266524bL, 0xb7bf3880d0a19f66L, 0xa5aa685eda106ebfL, + 0x0a69e8d3e642dd46L, 0xef349c61c682e4d6L, 0x26f6ee3b0fcb534cL, + 0x7daba12705eb67b8L, 0x2babb27e18be05f6L, 0x959afcba8e2d85d1L, + 0xedcf2d1ae2d9d386L, 0x59dc52e61ea6f06eL, 0xc28278b4866e5ae8L, + 0xd9ff034002bcd3c7L, 0xe884ac76784be82fL, 0xa316498083c9f224L, + 0x62501a98b46ff949L }, + { 0x563f7d9aad264086L, 0xca6a33dba5e0e4bdL, 0xe82530028c8d3d67L, + 0xa288dac846e64b19L, 0xfa3c919720aa4536L, 0x8130c9b0ed553eacL, + 0x622806e02ea8abd3L, 0x52fbf54dceccfe77L, 0xbd9a8e314f0d1b70L, + 0x519d2133d59b1741L, 0xfd74101c9a6fea8aL, 0xd1acf7a0b5c4eb10L, + 0x78499b7391f9da5eL, 0xabaa4c49c0dea586L, 0xcc9c5f73a1f3531aL, + 0x497b15fefd3fc665L }, + { 0x8a56cbaaf45568e9L, 0xf491a0fec7192a6fL, 0xdbb03dd39ab2539aL, + 0xc86522f84ac37da9L, 0x8c8cdba202a0f5b4L, 0x8109fc75a29c539fL, + 0x9cd06d31ca90f02eL, 0x8f31f0443e216dbfL, 0x99aa68acba3ebd91L, + 0x2a80d0d242c007f4L, 0xdd8dffbf86a9b7ceL, 0x405d3e84d6308edcL, + 0xdafa33fe068012caL, 0xc2eebd13edea1071L, 0xb7ae7e5c2ff637e6L, + 0x18d46a6c9e514cb7L }, + { 0x868cbb22a78b7802L, 0x0745ddb2497cbaf4L, 0xc4eb2f3e42ae8addL, + 0xac0abcdab4ceb4e4L, 0x2e0d8325a325fd40L, 0x6cfe057113ac7345L, + 0x7407a788b14171b9L, 0x70eb06036da7a52bL, 0xab0b36f9d85176acL, + 0x14109d297c2954f3L, 0x370de9c8dcd705adL, 0x3f0db5cd7bb5e751L, + 0x45f93d41a06e708cL, 0x10d54f8a7e93050dL, 0x69e6f8e45a38fef9L, + 0x55044601d3f62e40L }, + { 0xd1c5c91006cb9cc9L, 0x542074d741d00014L, 0x7cd8663e11236fb8L, + 0x39721ffe29ad5f82L, 0x1d21fbfa2951fc83L, 0x1cde06e7400d144fL, + 0x9042596b91792e6bL, 0x3365c8e529ad5166L, 0xe2220e859aeefe98L, + 0xbcb5318970c2aee3L, 0x477ca3db9ff100bcL, 0x27074176f532973fL, + 0xa12118ac9a2bd01bL, 0xf34252093dd79f93L, 0x563a8ff7c6f5d7dbL, + 0x0da313fcd7b0ec4fL }, + { 0x37125a8c15aa2557L, 0xca21d70c00893e9cL, 0x4871399467b8a823L, + 0x0d3e9a747cb0042aL, 0x2d2bf4ffc9e2ce18L, 0xd5531a0d049aeac2L, + 0x4d29a616f03d0660L, 0x473d50d61f1b7f00L, 0x3af0ecbbca3de50cL, + 0xe2959bea09c28f27L, 0x6d7c2ea0f8704664L, 0xadfae4e1731083efL, + 0x50940c26941c2554L, 0x44167410a1162d03L, 0x620230d81e82290eL, + 0x63630be8db414accL }, + { 0xbf8d52228a7d2e41L, 0x49e75823eb62f879L, 0x1b4d33dd6c402d89L, + 0x883e04d6de2c59adL, 0xbf3f38f449b9dc38L, 0x9d997d18b4b70c4cL, + 0x1f69b20c13cea045L, 0xca3d702558e2606dL, 0x3d4fd977261d1b79L, + 0x56aeafa85a1436faL, 0x369b3e98bb443c07L, 0xfce5186ce558f6beL, + 0xeb0cd478f8ac8f89L, 0x68074f37d5e5aa72L, 0x295845c068544eb0L, + 0x306a9871f16688edL }, + { 0xbc451e9d634ec136L, 0x1edf27ca0e6f658fL, 0xa9be0152c0db4120L, + 0x87b6ef20c5bfee67L, 0x352832389a2d6023L, 0x60e564d8c7afb899L, + 0x4af22bc00ac9c2deL, 0x28e6f63182a9d22bL, 0xc075c701f532701bL, + 0xf6d418f882075f91L, 0xf9fa628d1beaa511L, 0x551e7a176e72a13dL, + 0x9306215b77f4c01cL, 0x71aba73193c9d588L, 0x6443ebe058e57cd4L, + 0x2833ac41e8103e37L }, + { 0x7e564b868da5ec5cL, 0xac3d9da81c08db24L, 0x9d7c1f0b8c57a728L, + 0x3512afe79d343dc2L, 0xb438e4cffdc60339L, 0x7d5a2700dcfa1941L, + 0xd5f323f827320449L, 0x1b87a58e1393c6e6L, 0xecb68bd104baa431L, + 0xc09c1c5a4722b4d7L, 0xf42faa97206b5faaL, 0xe1dcbcd69976327eL, + 0x655ba9e4087787d9L, 0xbd59c757de5c0191L, 0x673020ed0bcf3538L, + 0x120cd454a49d6303L }, + { 0xebfdb8f4cab0f9eeL, 0xbc003ef02cce58eeL, 0x9b6a68415a8d0665L, + 0x642ed3a69b957774L, 0x3de487f04721ab5cL, 0xef2ff38021a4f0d3L, + 0xbd16f55829dbddcdL, 0x2ef05b4b0e93dff2L, 0xde1faa120bc9aec1L, + 0x66dae2c2d467fa92L, 0x758daf645eb33e34L, 0xa67ad9f68f0103cbL, + 0x151f693a9be02430L, 0xd5698496eb4054bcL, 0x8ef1677e7019336eL, + 0x021cfd167fdeea3eL }, + { 0x5c73715fdf5c36f3L, 0x703bde37d64ad254L, 0x55368d10f2cf7713L, + 0x1e5ec7b70f3993c8L, 0xfdb16776304ae4caL, 0x0d8f717e3d3bb18bL, + 0x5267073f66343d5aL, 0xfaeb52ef156008b5L, 0xb97ad5f9224a470fL, + 0xaf86e391ed2ab51aL, 0xdc0c7e579974302cL, 0xc88fa817fd0ae28aL, + 0x807c22dfbf8ed59cL, 0x5dedc231eb128bb6L, 0x71edcd9ca20595a3L, + 0x07265b46c73cf78eL }, + { 0x73dd99f0bd66232fL, 0xc59aaf89c4027716L, 0xaf826dfa5b860fc4L, + 0x239ea8aa7a943f3bL, 0x0e0e1b1a523c428dL, 0x55ea0e3a6973b95aL, + 0xea399caa2557753bL, 0xf8adf72f06957b1fL, 0x0389f3413bd34302L, + 0x333f27d0f8a43a97L, 0xcd9c0c08adaf796fL, 0x6dcca49b49c12aa2L, + 0xdd88deee7a0ac6e9L, 0x8f47575d0644080eL, 0x6e9d667d0cc2f4bdL, + 0x36c5754b31d1496cL }, + { 0x9120046ef323d84bL, 0xa69911227e789c4fL, 0x4b0eaf4e921b8055L, + 0x6339844a8079974eL, 0xc905466a740f8c79L, 0x1c18d0f7cd6def49L, + 0x5297da6b4b23e4baL, 0x1c09dff3c41800c5L, 0x6c49075b37ef6777L, + 0xa94c3a4050513dedL, 0x3d6742e96b0b1705L, 0xc0784494c48af5aeL, + 0x40c01532c95822deL, 0xa2ddade5c164d94fL, 0xfc8a8ac9a2975eb5L, + 0x06fbf8611946944eL }, + { 0x2d65338e3f45aa97L, 0xd83b58c81d040febL, 0x05fef59b0fdef8b9L, + 0x7beb071ae4d7417cL, 0x982b61f5b30a1a23L, 0x4c5f2a2afb65bd03L, + 0xe40abc9d5cbf6bf3L, 0x422c326df06612a5L, 0xc921e69d9571ae28L, + 0x7c88b10b23d3434eL, 0x96d2e9579da07933L, 0x833d46a13619cf4dL, + 0xd9d19653d95eefa1L, 0x2a7d8411a03e8f0eL, 0x5e64295304bb5ab1L, + 0x5e9ca0fd1f0fa9eaL }, + { 0x5bd54571197c5dc4L, 0xe2da40bfe78a95a2L, 0x65fb9efcffdb0eb2L, + 0xe952dc2c0d17467cL, 0xc1fc9c7bc758c6a3L, 0xfc79562cd4034a9aL, + 0x26e36fbe61f64b56L, 0x6adc4b9e1e84728bL, 0x7f165fd3a8f9ac8aL, + 0x7bc93a4503e3e013L, 0xeacc5513656478e3L, 0xd3391717064ddc77L, + 0x75b318dc76936914L, 0x69b1f1c7362424a6L, 0x8cc2045b49955f34L, + 0x940622b3c6836af8L }, + { 0x4710ccb70d997973L, 0x3b29625dd3f8f115L, 0x8cf0c4d55b97abd5L, + 0xc6321e0a673e14a5L, 0x0541af9d3d262246L, 0xde6d87546fc83b11L, + 0x47e97da8f01652a4L, 0x0f82b3a6ad9802b6L, 0x69aa4075ae9c44b2L, + 0xaf3f5de2ced2bf77L, 0x1ef1ea8a497a40daL, 0x2e0f86083c23ba9cL, + 0xd8a998a4f190a2c8L, 0xe2b49c8ccfde3368L, 0xb9f49824bde6bd71L, + 0x80bb1664785bedb6L }, + { 0x05e575fefd145cb5L, 0x155ee561ac5e6883L, 0x461e70cf8793b273L, + 0x9f1553de133b2338L, 0x2fb9e0c3a2a7ba07L, 0xc3bfd6a83e7086faL, + 0xb6ba85008bb4cb93L, 0x0b66d78976f82dbdL, 0x7d5a6ff654eb49ffL, + 0xcd65d2371f20b322L, 0x79ea49c254e29cdcL, 0x64975963cb118ff9L, + 0x969598ddcc58000bL, 0x95107918110c779cL, 0xedfc154863b85a35L, + 0x077ba5ea41212350L }, + { 0x0b3a38d3cdd86f61L, 0x431214450502a0abL, 0x1912edc5806d0272L, + 0x01dc1f988a32f10fL, 0xbb1d31d10e80c760L, 0xd46ec7e5f464e8b3L, + 0xd569af369abf49eeL, 0x9d286ea72cdade77L, 0x2be7020d45ad5920L, + 0xabe5236e6299ae7fL, 0xc93179bdd3f55c07L, 0x8138995a52350e80L, + 0x0901265caff07586L, 0x5b3c81b2f4739653L, 0xbaf7581d9bc77d21L, + 0x6b2006df4591a2e2L }, + { 0xb2fe50a8965b1bc1L, 0x931f536a962bb4fdL, 0xd5718d33000e7f99L, + 0x84728f2553d5125eL, 0x4f8a6184d2125cafL, 0x54f1a701357f679eL, + 0x70a9f40c1531c05aL, 0x10d0cb976fa8b775L, 0xb476f41e9dc12ce9L, + 0x5c8d7a752755f894L, 0xd6c12e10625741a4L, 0x262a6fb8c917b16cL, + 0x24d116e638d6b0a0L, 0x849540c032c38e83L, 0x855b911c66868afcL, + 0x53217ea6bd26b550L }, + { 0xfc840473259f52b4L, 0x968da9cbe621146cL, 0x964eb85ecacbd26eL, + 0xab7daa2de4a54344L, 0x6dc3b848381a4ff7L, 0xa07a96b341c815efL, + 0xc4fae9e8c3d4b1e1L, 0x0f938d1e42ce9ea8L, 0xa727dacc35cc052fL, + 0xc81e01c9e9a06f07L, 0xa9e08dcb4a6d65a1L, 0xf8e2d1736044a9a6L, + 0x99893dd0f2bd295bL, 0xa08d3379f9781b12L, 0x64bd600161830ac2L, + 0x0386931ed9adbeefL }, + { 0xd0d7abb3d09885a5L, 0xed9d2b67e355bb07L, 0x3bc238cf536ebaedL, + 0x61ca2e78699ce4d6L, 0x354ff447111594cdL, 0x55cbe70903316ad2L, + 0x418679fd49fff5c4L, 0x75bacd750f9c6c40L, 0x677edc882972721aL, + 0x82596887e5ef502fL, 0x459e9367bf320e0eL, 0x81ce36ef8bbdccb2L, + 0x1ba097fcb766863dL, 0xcd3a21d6d58c6db8L, 0x0e4967cdb4a8748bL, + 0x2caaf74915041c20L }, + { 0x44f980066ed20424L, 0xb3e4ea2322471545L, 0x268ed1a5781a8c86L, + 0x48d0ab757ae5b70bL, 0x6ca8b320356d3982L, 0x9ce8e6812df31fa4L, + 0xb909d232d925dcf2L, 0x302c8f78f56723deL, 0x11725d69abac96f9L, + 0x656a47ca57d1a170L, 0x6bb5d511c18a2be7L, 0xb56e45f1ad50d9d9L, + 0x36e886e270b05518L, 0xc7c71f3d09d8ff91L, 0x65a1bbe29350361eL, + 0x86d7f53245fe3bd8L }, + { 0x99f16eb6b0bf719aL, 0xb69750988bc3d913L, 0xfae50e5226cd01b4L, + 0xd3e3ac5490898d1cL, 0x4da3b9db887ec666L, 0x58300644fbea45b8L, + 0x369f3bd98355b058L, 0x0fb239a8579bcc13L, 0x4f5b45396e2bd811L, + 0x007f3baf24198fd2L, 0x68a676db8837d51dL, 0x68eeea62eae75b16L, + 0x5ffe5f943db6083cL, 0x52c94d0f7d836c5aL, 0x5a4c3c6fcbc1ff85L, + 0x682a55e386c0b4ddL }, + { 0xc8f235a4587495aaL, 0x2276026c34c7245dL, 0xd6ae0cc5b75a46e3L, + 0x890d3965ecc3e5e7L, 0x1b13342f14296629L, 0xc89927e68a877227L, + 0x1543f27e2324a68bL, 0x6c44768449cdc21aL, 0x9bc7fd4f1452d0acL, + 0x2cc30a31ff4b045cL, 0x415d46a0852f7611L, 0xad737052c6fdd7a6L, + 0xdcecc3ab7b4c7c91L, 0xd2cdf01b7688d70cL, 0x054f2542e40d3905L, + 0x02227fa6fefe4dcdL }, + { 0x1805efd9b751948bL, 0x8efeed46fdfd225dL, 0xcb128e094f2c8b22L, + 0x9d1090bf96f7c5e5L, 0x0959d044b4cbeca0L, 0x21c955f98e08cb04L, + 0xbc1f279d68fa4fceL, 0xb021e14e0710ae9aL, 0x64d16e9f881167f4L, + 0xf5a5c22ebbc9f1a5L, 0x5f3716dfe3420eeaL, 0x971eb915d5c4e843L, + 0x64fc55fc28ffba81L, 0x3427e54d7dd37578L, 0x446e6a6215ebc7d0L, + 0x547e249a29269778L }, + { 0x4706868aa1ffda27L, 0xb4e6cdcc7955cf50L, 0xf65151e10a63f3d8L, + 0x5b4127ea9de5e70aL, 0x3d2c09baf9342823L, 0x18c99d83aa2f7d51L, + 0xa0c5bb1dddeec025L, 0x7ffddf8403dcf1ceL, 0xe57e4d29616fdedaL, + 0xd24565697932a1f0L, 0x7475e0e83191d4e3L, 0x3479bea1c220218bL, + 0xfceb5c908bcb2505L, 0x1c685cea3c6132e6L, 0xc42dc745bfe6c1ebL, + 0x45a41cc0d2b08eeaL }, + { 0x3ea9b2c74dbbf0e1L, 0x41ff962fa17cf70eL, 0xdc1ea7585eeb4c66L, + 0x4f5412d2a9beb17eL, 0x2c9e4f52a285741aL, 0x93df7da4984fd11fL, + 0xb2afbddc0df3184eL, 0x96323d252421e375L, 0xc87be1e449df781eL, + 0x145601ed3d589beaL, 0x0f0bd9bd28fff6ddL, 0x2d3259d48a0f298cL, + 0x362d7a77d88e6944L, 0xa84c06b6b6ac2af6L, 0xba850ac9d087da02L, + 0x128763c942ee40c8L }, + { 0x29a80f07acbac178L, 0x7cc2004434b08f6eL, 0xe9631d1470feded2L, + 0xb2115da386615767L, 0x7c75f5c4cb088548L, 0x5b29d2139a2e8e03L, + 0xfe9fda668b881752L, 0x3f1d8d88c1de7ebcL, 0xb476565e03218123L, + 0x07365561b1c995f3L, 0x2160cb18b13eb71bL, 0x7e8da51399b3a0ebL, + 0x5e8ca1f9b20fcd74L, 0x6a7e0067b4126d72L, 0x1e8204b768bb637fL, + 0x75e96bccfc4f74d2L }, + { 0x189d1fdc0d19716eL, 0xdf5850587c384525L, 0x64a846d1ea987d2aL, + 0x12b6bf836c07150fL, 0x91d85d464d6fd5b7L, 0xa97888364f53f55fL, + 0x60083bd881509129L, 0xa7672683ea876f48L, 0xe80b2e7ac15b2489L, + 0x985ef8d242d1d992L, 0x9c57b029cf3de492L, 0xfe02f83cb1487627L, + 0xaeba4fe48ae5b687L, 0x8a86f09b5d6b8196L, 0xd88f566ba16e523dL, + 0x309a6e9aba268949L }, + { 0xef27ee50bdfbe97aL, 0x1a5fe70fb8c50c4dL, 0xcc7beb017fe09f5cL, + 0x8fa15a85bed36cc5L, 0xc0c3acdb7550ed3aL, 0xc581ef87eb908681L, + 0xa15b3362c49d5ccbL, 0x0fbb17141fa264e8L, 0x267f8d8f8e1eee88L, + 0xd31ccfd621c2b63dL, 0x924dbe7d53be7efdL, 0xd42e877fdb2a358aL, + 0xcf9673c775d68ac1L, 0xe35978fd714fea55L, 0xeeb366535769b202L, + 0x0458258ad7593789L }, + { 0x5df71a74a042dbdfL, 0x2d4058575779dfa2L, 0x0e66cba70d2e6657L, + 0x285d6745ca2e892eL, 0xf56a8def0f0e6b5fL, 0xe0ee851da30767c3L, + 0x98c0565843346b9cL, 0xb35fce26d6b3c742L, 0xc0895bff39777e00L, + 0x83c8f6a6e7b6d886L, 0xbee148434f02904bL, 0x7f74915b2e84ec34L, + 0xbaaf663c96d10991L, 0x004b8757e41facc0L, 0xa2b880e56f86c029L, + 0x53f4a3e095b77358L }, + { 0x11bb08ce89fc48e7L, 0xba60c577afab5aebL, 0xf06bcbf8a0c1cb5aL, + 0x7d2efaea79757cb6L, 0xe26d90b176319160L, 0x42aa1ab62b77b7a9L, + 0x38eec0cd285df2bfL, 0xd35947f5f3a8f7f0L, 0x97c8dc0efc1cb5b5L, + 0xfeb8cca0c45845cfL, 0x16e8d989249e26f2L, 0x7c264e6d483ed89aL, + 0x13a3f14551d91073L, 0x8501562e305e99f0L, 0xaaf98d746908d563L, + 0x0a99e653d723d236L }, + { 0x23536f46abbc0559L, 0xc163067b9aa1a160L, 0x229fd2290c1681b5L, + 0x61254be11378e907L, 0xc60ff57aab793a2dL, 0xa6f2df8b466552dbL, + 0x9ad318938c170a36L, 0xc5cd9abe29b74d9aL, 0xcf747273f7848523L, + 0xc126a93a0d0e3063L, 0xfe2021e34248e3d8L, 0xd97343ee8323ddfaL, + 0x9f768775332639e7L, 0x9650fc3175325548L, 0xb595dbd13eebf7eaL, + 0x3a95cb45010fcbc0L }, + { 0x954e68cb39d7ff2eL, 0x8dd1cb4bc1d5c48fL, 0x02a92c777169438aL, + 0x7965c0b091cad8ceL, 0x0c5798ab32cd08d2L, 0x1a5bc3c3a6902bdaL, + 0x545d09255186d218L, 0xf0077cdbd27e64dbL, 0x0157caa48cd092daL, + 0x2a2fa3a024532ab3L, 0xa5fb639b41ccaba3L, 0x01702dc14744aee6L, + 0x485bb436cdba93daL, 0x93597f66329784f1L, 0x5d713c1ddad672c3L, + 0x366d222e030b7245L }, + { 0xd50b4875573ea5b2L, 0x0fce401ba90da44dL, 0x7b53fa657a1a0310L, + 0x722a80a5cf114460L, 0x0b8ebf05a538bf49L, 0xae141147d32acd21L, + 0x6692712c7b5ad07dL, 0x6dc5fee73f48ca07L, 0x98ed14992b8a78d8L, + 0x4e8b3145dd2f1759L, 0x43408de15f971b8eL, 0x055ea6ddadf1b368L, + 0x4bb76e73e5932b7eL, 0x44287153d30893fdL, 0x173dccd20661bfdaL, + 0x9072ba9979defd25L }, + { 0x474de4dd9620ea39L, 0xfbf1649fc831cee8L, 0x0b0e8bb1cd3a9c43L, + 0x6a38286f3f3df1d5L, 0x4ed072b38f0ec9b3L, 0xa6e4c987729c09e3L, + 0xea3e8ac68ad12242L, 0x6ae0e22bfbdfa5baL, 0x56171ecfb0a0f592L, + 0x33b2886d6b871f8dL, 0x6b19bea935e11bdaL, 0x4d815a407f0f153fL, + 0x7e608d977d6c02eeL, 0x7e8f23d9b6a88f46L, 0x26ac9652439d1654L, + 0x8d92c6bd35546c29L }, + { 0xb3e0d7ceabeb0ff7L, 0xfbe352543e0e42f8L, 0x57d1b226de808499L, + 0x9ece2e1f1cd44bc3L, 0x1245adbc435cfee1L, 0x874ee840f93f581cL, + 0x916a779cbda0b947L, 0xabcc815afa57ae0aL, 0x97adec2df0a621b0L, + 0xbe6a502b81f90bdcL, 0x54bf9de153bde63dL, 0xa88fdabf78884c25L, + 0x30aa52b1cbbb5470L, 0xf805396c29053ef5L, 0x8d43d8988dd827eaL, + 0x4e4bec175c1ae5c0L }, + { 0xbf8483a2fcc09676L, 0x457c4a3f19ea9a94L, 0xa6852ef3d702a5ddL, + 0xe7915fd2843fe7d8L, 0x644bba9816e35158L, 0x8d1b95d09ed746f0L, + 0x47704581b90af0b5L, 0x0bd4bc6bd4fd135eL, 0xa6dce067b4e833a5L, + 0x2c0e8f30ff56a9a1L, 0xa9c80800ec2c63feL, 0x449c20a598f508a8L, + 0x02b94cb33292813aL, 0x647e3d28ec7e81a2L, 0x72e67d1ab4877677L, + 0x7a4aa3f56f9ded24L }, + { 0x559ef1bae27a0045L, 0xdc812d4fb242cb50L, 0x23a478e439cf8d24L, + 0x97544fc59b3f9c54L, 0x5ac68132affa1fcfL, 0x74f8fee034a2c83bL, + 0x96cc640fcd3f4bb7L, 0x775dce9db0512ea6L, 0x67dca19dcdce381eL, + 0xc1eeb3f3a9d3fe55L, 0x38e0bf421a19274fL, 0x15992fb428d69b12L, + 0x48fcebde9fd09df8L, 0xdc9dfa4fb41ab5dfL, 0x0cbd7dc8c0a269c5L, + 0x60282a7bf7f0ade1L }, + { 0x7c07e538dceea2e7L, 0x38a322c83c42061dL, 0x676828f94f1f6516L, + 0xf21b69fbc7776a10L, 0xc63a3417b5e6b405L, 0x4c99f25891a7b642L, + 0x38692ca82cad1440L, 0xf1e82ffe00869bcdL, 0xc30b714e16fe466aL, + 0x5fb742f919019138L, 0xe90166d00fa516aeL, 0x5550f7acd8c73a43L, + 0x2d6a407dfbc5c372L, 0xe47a753968cc39edL, 0x3fd286d94a5fbe70L, + 0x5f4ae9c723c6b942L }, + { 0xd96a2dda53f4d561L, 0x286d45d016da1992L, 0x449a01fbfdd4b051L, + 0x25488a0d9f2195eaL, 0xc4151b0aa37661b3L, 0xb98c471ef9e5ee02L, + 0xa4bca86ea8658817L, 0xbbcadb877a68fc0aL, 0x88b346496b7366a9L, + 0x32ee98d415661c2dL, 0xf5b3b4c6c901420cL, 0xa23527352f2752afL, + 0x2f64ce73510e4d9cL, 0x939a7f26aca4aa80L, 0x9cd3e291401aa503L, + 0x92a01423dc46afd2L }, + { 0xe9f24be11c2f7dbdL, 0xda8c900fb7d527faL, 0x963e25bb8648f128L, + 0x9ab713e248141941L, 0xe87f7d017a6756fbL, 0x274dd85e058d90bdL, + 0x823fee7a82566abdL, 0x9f6230d774240195L, 0x04579f2cacb5e46eL, + 0x2a22626316a4c87eL, 0x9ca19a43d99b0857L, 0x86dc2ba3e488789eL, + 0xf960b5b99406c3bdL, 0x6f2c428b8960957eL, 0x90748706161c515bL, + 0x0fc8fe1eaa88cb9bL }, + { 0x68ae1bedfeb90f2dL, 0xf393bb3ca48b1559L, 0x2be62f9cf64e9635L, + 0x354c2410f8be75c2L, 0xbd7ea7035e6f7529L, 0xc264868e162cab31L, + 0xb1391e70c860f3ffL, 0xdf367c751d89837eL, 0xe150b6b42bf32941L, + 0x95e8f46e78c1318fL, 0x2b3f1daba2c4b160L, 0xc6ccf5ce701afbf3L, + 0x3ad275305e8874c5L, 0x39285e515dc6dcbeL, 0x3c954d86d99892ddL, + 0x2d0ba862dfd3789fL }, + { 0xeacd8ee8b472e1afL, 0xeb354eaeb76abbccL, 0x9b520bf8d0d93fbdL, + 0xfccd60d7fe6fc706L, 0xa9353ddea4ee2f39L, 0x5eb0925e9a81e51eL, + 0xee334da1d1366777L, 0xc1d28c9fd5354d69L, 0xb977175592a5ed54L, + 0x5d3e367fb7f70d81L, 0x7be7eecaa933ae7aL, 0x264cf1f9e23cfbb7L, + 0x0d129f4a89497681L, 0x705375a409b6235bL, 0xccf64c7548a376daL, + 0x963c87124d41dbfcL }, + { 0xbae290cbde36a814L, 0x9bdb0195733b12b5L, 0x0ebad867f77fe0e1L, + 0x0a7d19fd29720ceaL, 0x434d76519029ec72L, 0x856aff17bb51911eL, + 0xd0a25d9ad80a7f60L, 0xffca86aff848c106L, 0x53e8bdf943ad749cL, + 0xfb9e0284e3e696bbL, 0x3eb6630aeeee4215L, 0x9d8fbb9e2ecf3c63L, + 0x71da4ffa4e00c0c0L, 0xb296be595d57beacL, 0x1751fbada8cec7efL, + 0x2d03eb3cff55d7bdL }, + { 0xeb16925f04f2ec1dL, 0xa878f2760d147ee2L, 0x442df604aad9d9e0L, + 0x891df44b3f71035bL, 0xc28272b38cb95d5bL, 0x6f14efb55ee8ed23L, + 0xf3c4460f13b0f3e3L, 0x889f9bd76bd7335eL, 0x889ee771f755ba6eL, + 0x626984feed219b6cL, 0x2d44c737ec2ee411L, 0xb94385a263efcd37L, + 0xd909321b6637826bL, 0xc24f8a793ee6b7a7L, 0xa3ca8d24a7cf61b7L, + 0x842e40c1c54bacd9L }, + { 0x5a268ed6a661d843L, 0x02328cca4f5b30cdL, 0x16e6fed11311e177L, + 0x690decb4c6695967L, 0xbdac5bf657b2e280L, 0x827f82ca1efe42d0L, + 0xc554ec0aca5fca2fL, 0xac5276c1dde45506L, 0xb7f4cb08e3077513L, + 0x8caf6d9acc8797ccL, 0xd59648140d9332d2L, 0xcc6ae297285a409fL, + 0x7773c2a56223d093L, 0x2d5266ac5128fc09L, 0xa596b7cbbc31fe6cL, + 0x0e63319acac91328L }, + { 0xb5cd2fadf0360ac2L, 0x86b660de285e605aL, 0x82c6cf10e25b9b14L, + 0x9d5fa38daa9ac554L, 0x3dfcf1b8526c070eL, 0x0379a96b3fccc52dL, + 0xe3659c290bfcc7f5L, 0x5b1a3db569d3e6a1L, 0xb41528b59b7b42d5L, + 0x934defa49c22a006L, 0x90f380189b4ce3b6L, 0xb073bc04b3abaf32L, + 0x27a5a222ff8389e2L, 0x0b7a9d51ffa5a35bL, 0x4939ecef28e1a7c2L, + 0x88839da21872705aL }, + { 0x56b66c30701ce29aL, 0x3acaf12658981d50L, 0xd4dafc0c105f9f21L, + 0xfee571e6373e3d13L, 0xe7269c86fa2ee3caL, 0xf5cca64add20385aL, + 0x217f27573000e9acL, 0xc934db470e7273efL, 0x4294f4f7355b6776L, + 0x1faa36b96fc05180L, 0x8f88b1dbb052190bL, 0x35791b90e9eaef52L, + 0xf37fb2ebdb681b90L, 0x39d0a51d4415c369L, 0xfc59cca71d2e21c9L, + 0x64128cfea1f50c26L }, + { 0xf03678a2e8f5b0b5L, 0x5c7e249cd340f059L, 0x4144044193ca7cecL, + 0x075ca346bc83af98L, 0xf39f0033faa8bbb0L, 0x3d18f0edf38230f7L, + 0x78dff00cd448f345L, 0x849228c0d51aa475L, 0xdd4e270830c928d1L, + 0xc66ba6868f12cfd3L, 0x091049db88b3a206L, 0xd865d059016dae01L, + 0x4599e905e253e37dL, 0x322cf0c27ce9871bL, 0x014f54da174a132eL, + 0x93634a09bdabcbdaL }, + { 0x62826b27a9a2e304L, 0xc57e1866c1a4c124L, 0x913ab83222381710L, + 0x7e9b6b85a9847cfeL, 0x29655cf12b5f46fdL, 0x7295572b8038e66dL, + 0xe4cba6016fa95eabL, 0xbbc11071b9deda81L, 0x97f0009a3f1cf61eL, + 0x5372777b373e0cfbL, 0x302f909cd139d63bL, 0x1ed672da4f87d78eL, + 0x362077a3b4048763L, 0xc408c32d9dcc22b2L, 0x4b4c5bf226deeee7L, + 0x266cb467bc06357eL }, + { 0x6faa4154b56363e8L, 0x4b4fd0783c1aa4dbL, 0x14358dde2b9e6597L, + 0x5b34ae3efa004b84L, 0xcf44b2ecf19911a6L, 0x55caa833a536bf78L, + 0x606e1eb98870dc95L, 0xe3c3287d09f3511dL, 0x68b2f4eb9d5cf364L, + 0xc154e89263ab8c9eL, 0x1548828ec36ab611L, 0x0932bfcba1b7d120L, + 0x7ee7b5bc5315b8d7L, 0x782fd0d1f7473ac1L, 0xbcb029a83c8f2af3L, + 0x4b1d5a1b52454ee1L }, + { 0x12fe517463d52c0cL, 0x3735525e188c099dL, 0x5c621563360e3956L, + 0x88b3f1caacfa5a43L, 0x90123a0a797e8107L, 0xba31f6b5b15e080aL, + 0xd7de5e12fca3dadaL, 0x3287361b0df511c8L, 0x7cc800d465757d4eL, + 0x10810f3d5207ec91L, 0x0d4e56f130eea0e3L, 0xbbf7ee133ea5a2ecL, + 0x6fc07762be6abbd0L, 0xc831fdce120bf619L, 0xe07439fab622d42aL, + 0x8186b93f508e4b27L }, + { 0xc619d15409312867L, 0x7e042c05bfaf7db4L, 0xc1cf16681f5f5ddaL, + 0x50aa5057a4fc3d82L, 0xed30ed65ce68b8feL, 0xecb01c0bbeb4d644L, + 0x7b5dc444831c0497L, 0x351e6a009b7d9b1cL, 0x4bb863b9d9477c91L, + 0xaba6589105d4110aL, 0x30086cf443580b7aL, 0xb139c07690be357eL, + 0x12bfff1a27b5214eL, 0x79cfc6d722c3ab57L, 0x4743de57f34a9bfaL, + 0x0bf97e97c9ee2b2aL }, + { 0x96ec4ec8dda19e96L, 0x54ce18ea6c306e8bL, 0x7e83612b65f6918aL, + 0x1ac6f68b0d9a0d99L, 0x98a697a462fdcc09L, 0x65ce25f195bc3e13L, + 0x1896ecdab3939730L, 0x9eb81a0f32f12806L, 0xd3d7416e1d2dc7dfL, + 0xe22c7976ad473599L, 0x3de37a9a9f5ef439L, 0x6b7ac0ab9e69d94eL, + 0xe6bfa9e00a9d0bc8L, 0x576a870d5676f120L, 0x3bd91bb4feaac23fL, + 0x8fe5482c3e40aabbL }, + { 0x85ae67c2ce9a4d1eL, 0x4c3eb8034f1d2038L, 0x5c6c8f3a25d06192L, + 0x803de0ad308fb41cL, 0x9961f5bce71c294eL, 0xdc62078df02eb0daL, + 0xc87ef515b64ae8b6L, 0x69679f1e50b4d18fL, 0xc5c009a152199f43L, + 0xa7d484be0f640a5fL, 0x4c918bb123dab566L, 0xa67c114c64275d2cL, + 0x95a913b9cad2ded6L, 0x189ed18b6b4b5c8dL, 0x4aeb6206b42d3bf6L, + 0x3928c669bbc8bc3fL }, + { 0xde4bea4adacb4b64L, 0x03f62a44f26179a1L, 0xf3aac94e7a9112a4L, + 0x90448fbdd36f331eL, 0x426042bc407b85c4L, 0x5ad8a5962121b77bL, + 0x31674a4f67cee984L, 0x7fae8bbe4e3b2f0dL, 0x681df6dda7c930ebL, + 0xadeefa98c259d0d4L, 0x1b14d9e6bea1c1fdL, 0x3baadc8b21d405d1L, + 0xf01dff9373892754L, 0x81c35b3ef071cde4L, 0x1704d2e19150d0d9L, + 0x6ccc888f355134f6L }, + { 0xf8d36f0e7ad7504cL, 0xbca3265ff7959dddL, 0x0dcd1edefede67aaL, + 0x1276f4cebaebf32fL, 0x6825a6e6014edcfcL, 0x0b8c1a8299ad8eb7L, + 0x312024a909b8ce1eL, 0xcb8fd98b9cbd351aL, 0xa4841378fab1e8beL, + 0x17ed0f5d3973cacfL, 0xa17e1484259d5254L, 0x53d5b84374b91393L, + 0x8f792b211aca3ce9L, 0x035ff110c8c0f815L, 0x6afa6357ad4ed7bdL, + 0x2f151980b26faef9L }, + { 0x0c8631da29d2d439L, 0x121fbbc2bc039955L, 0x3e5a97926c05b75bL, + 0x6d6cf4c0b6ce47ecL, 0xbaaa17679d88c658L, 0x031db9e7f3355a17L, + 0x8381e3d80aef5a85L, 0xc71db29015a31bdfL, 0x638f6b749498fd7dL, + 0x44edf3f913beeef6L, 0xe6173271f4ab67b3L, 0x3a202c70fd22df11L, + 0xf7be0389205c4e92L, 0x1c219085a8eb9920L, 0x6c805ce8beb54aaaL, + 0x354b05b70ac58d65L }, + { 0x7171e2367a9170e9L, 0x01eec42d4cad50cdL, 0xffbe824f3cddccfbL, + 0xa73e8ce3a66cae1aL, 0xb7138a7f965c7d01L, 0x00058e3f5c3d971eL, + 0x52591ac32ff0a72bL, 0xa32fb5bcbbbce76fL, 0xf3241ab8a9f81a18L, + 0xf31d3332eca68630L, 0x847af9fc4482f13bL, 0x6196e217a4681be2L, + 0x9938f932e55efcf9L, 0x3e7dacb870acc705L, 0xd41be893cf09fac2L, + 0x48dc55c4ae3523a1L }, + { 0x8e623826a5092193L, 0xe46ec3626898970cL, 0x2f1356af25c9eb41L, + 0x4178064083c7d245L, 0x982def6797d00e38L, 0x382eb6e7a512151cL, + 0x154e10778af58869L, 0x187070758a51cf02L, 0xcdeba9f771313c58L, + 0x5d67b973ba155904L, 0x851c9f4b1d0d7b3aL, 0x19f29d718b8af2cdL, + 0xcb94ccff986b8d62L, 0x8725e24bb93b9c33L, 0x405ce4c566e38c68L, + 0x5f6a8edd0b6dc021L }, + { 0x83704ca58f9a8690L, 0x3f3697662f76a407L, 0xfbc12d8c69201028L, + 0x4cd58f16bce3a4cfL, 0x7804664a04aab26dL, 0x005cfbba4ea457a8L, + 0x537951b3b8a59794L, 0x4ca2b9e44fe1f739L, 0xe4428acddf325797L, + 0x648da3420ea243dbL, 0xcce6562bf43ce01eL, 0x840f0421f27db490L, + 0x156ccb708bfb7cf0L, 0x9b33480d5a8797d3L, 0x2e12e07a9eb814bbL, + 0x1ca65072ca7f87acL }, + { 0xfbb321cf2b9d25a0L, 0x66affdca40a746dbL, 0xc1c1530e59e368b5L, + 0x56ed1ea47d80068fL, 0x9b74d8fe5647dd68L, 0x1d96b50789b78da8L, + 0x39b752438bbe3391L, 0xef8d443e0d858c5fL, 0x4dd2db499646aa34L, + 0x7fad3bd1e667543cL, 0xd0d710c068980985L, 0x9f7aff3249facabaL, + 0x055dec1c14f9a192L, 0xaca663991fb307a1L, 0xac44fd9135ffff64L, + 0x462cafb6cbad3ceeL }, + { 0x1660a647de3237ddL, 0x95f735cc82b87404L, 0xf7879f59ddfa55f8L, + 0x15ef043e726b914aL, 0x1875393d1c93e298L, 0xa1a2be746ef18331L, + 0x4e7e8dfc25a9a12bL, 0xdfefc97da9c3917fL, 0xbc875d030a2ebe41L, + 0x0f75d235a732d1ccL, 0x06fee7fed9baa6d3L, 0xaa784fab65f48576L, + 0x23155e22513f83c0L, 0xd2fb77183e8f9d13L, 0x2a291503b546eafdL, + 0x1293c98c6cd93608L }, + { 0x7278125149d53b77L, 0xa6ab403d96eafac7L, 0xb7d7c7db4a36b711L, + 0x8238c70887e771c1L, 0x495f6abf33b37522L, 0xb0b0289c8c87530dL, + 0xca83cb86e77b111aL, 0xbe1c0fb8a1bd189eL, 0x58cfb2fb1ae9d7c7L, + 0xd05c23c54940c3e8L, 0x16e79e4174ad9107L, 0xa0a47f05064e7142L, + 0xc6929cd4fdfd614fL, 0xedb2584c3946988bL, 0x73e4b5f3e46f8fb1L, + 0x53b79aa168ea94baL }, + { 0x216fafce44bbb6a1L, 0xd3a5bba067821728L, 0xef1e4b30a9dd939aL, + 0x022eaf3df19efafeL, 0xfed5abce7b4ec014L, 0x64968ee6512c6738L, + 0x2311986929fe89a2L, 0x0d539d8d47397c05L, 0x6400bc54234596c4L, + 0xb9287f585346611dL, 0x04099903c9d5da0fL, 0xe5ef4997c83af2a8L, + 0xc89dc01b328151e1L, 0x150fb4a958401104L, 0x40a6f7d5f3872c9dL, + 0x8290d6d156c2e833L }, + { 0xf84637c6d8546946L, 0xda134a3969ec57faL, 0xd42359a4d789007eL, + 0xb42557fe0dc7b809L, 0xe62ae52d2d6784a9L, 0xa2714ca60bcadb5fL, + 0xcc208de633aafca5L, 0x2380ed5ced967811L, 0x6e6b55e9db321660L, + 0x1bead02ca675235aL, 0x51cc6ef9b33fa0e1L, 0xfd223e26f06a2a08L, + 0x00f332e1ec47b3cfL, 0x459f297ba0aa984eL, 0x6fa1d969ee952e14L, + 0x506ef1ab304fabb0L }, + { 0x11b4eb2735bff163L, 0x7130b96fea9fa984L, 0x66aceb3f9deb27ceL, + 0xa2daf1a59dd1c3d5L, 0xf5090a7ea73075aaL, 0x36a6af39e3071b58L, + 0xa28d633ddf73ad9cL, 0xdd354cacbdc89a16L, 0xdfea3423d4dcbc3cL, + 0x6eec74d2379d92d1L, 0xe14a456f8eed6765L, 0xfabe7743fa8feb1fL, + 0x1404ccf8b98fcbc7L, 0x6ccd2fbff71a706eL, 0xdaaf3fdb4d85c678L, + 0x415b7dbf15200344L }, + { 0x970105867d8377a7L, 0x068a3d68cb803272L, 0xfd67d289f03a4c32L, + 0x4bc7095d93c8f290L, 0x712fa13ce9e5a2b8L, 0xfc6ac6c60feb9f3bL, + 0x0cda36d96e0e54c2L, 0x4549975186320a01L, 0xf9318c9197f00f11L, + 0x01dc4c3fe6936508L, 0x769a2ef985f068aaL, 0x3522cef0a2b5511cL, + 0x006965edb4122e05L, 0xfce0fafcc175d43fL, 0x525dc9bdec831d59L, + 0x1ec314f1af58879dL }, + { 0x0663feef2c8310c2L, 0xaa7e14da457e3f74L, 0x392b10fce5346887L, + 0xcde4a38f637ec2c5L, 0x50773320b542f8dfL, 0x341302f9f7de1711L, + 0x018b1c63ae4b9bc6L, 0xf001c46edd2f9e6fL, 0xd3bb0a9726eccfa0L, + 0xa931b99d7746e0c7L, 0xe0c8b6f7f5875aecL, 0xbb32f17c96939c82L, + 0x765135d23de5a664L, 0x71936cb452abfa6bL, 0xad5cc08f2dc105deL, + 0x17e91d127fff5788L }, + { 0xbe92ced3b7e051caL, 0xc644d4fd19c776d4L, 0xc8ab4b520086784bL, + 0x3ea66227ce9d6b31L, 0x395249a3d289e9c7L, 0x54509e65d12a19eeL, + 0xa7bd46928c365aecL, 0x354997e477963e0eL, 0x0d765957b599732dL, + 0x99584aeb91d4a3b6L, 0x6e653ea41deb3e28L, 0xca7c98ed572571dfL, + 0xf301a38fb18ae1f9L, 0x1629f7c263f7b97eL, 0xdf242282afc4a0d5L, + 0x118f3b4b3ddd0c01L }, + { 0x74a0a0a87ad4762bL, 0x1aef84da8c58d175L, 0x16ff49604cf76d86L, + 0xc0be87867e60d98bL, 0x83637ffb3ecc1dbaL, 0xc244a6095dd6147aL, + 0xa3e178345b0846e5L, 0x735eb686e77a4c05L, 0x5bc18b4fdf758695L, + 0x15618d0b1bdfe52fL, 0x878ecc0d00715ba1L, 0x1dbdbd1ac2dd617fL, + 0x21d2b63121b61710L, 0x22ce8a7944f593c2L, 0x3b9b536a44f17024L, + 0x01d0a67c8d03e727L }, + { 0x7b9642361e46533cL, 0xe9477990fb88c2aeL, 0x019b5d16a42c4a18L, + 0x7135e81dd83c7a45L, 0x74a69bdd4cb663e3L, 0x7b67ecdbe76c0d63L, + 0x03d5452111e68da6L, 0x596cceb5d2e8650aL, 0xcd572dfd2af03b37L, + 0x52364ba1fabd5952L, 0x7f47d456b4ed8569L, 0x5ad8b572c950d5d4L, + 0xcadd2dfa486e2f84L, 0xdd527b43c56bb044L, 0xc9adba24997c08e6L, + 0x1b625b067da6320fL }, + { 0x44dfaa7b4fd8446dL, 0xc01b2f01af6febebL, 0xbf444388fe8838b5L, + 0xf33c434fbba9758bL, 0x2b971cba87156bc9L, 0x6b245e5c1f49098bL, + 0x87dcb5342b41c5ddL, 0xdb1f80c634d852d7L, 0x6d6e32582433da34L, + 0xf66820653f7df0c2L, 0xc4ca567c360cb365L, 0x321faac29826656aL, + 0x13f5ca6fbf069768L, 0x15397921a7076639L, 0xbdf143288400736eL, + 0x333eca9619fc948dL }, + { 0x23337948ac775d81L, 0x38c2518fd41dbbcaL, 0x623c7a4fbcfce948L, + 0xaad3623654703fe7L, 0x2b3a13a413fb3b5bL, 0x5db3565a7f5c01f0L, + 0xd72408dc52359661L, 0x5a17f8e51d616e91L, 0x90c16eebcb25b999L, + 0xf35e8cf13393743eL, 0x987da74ae54b64a7L, 0x557b322a65cd449dL, + 0x765082a537e7b15dL, 0x4d25c742f2cd134fL, 0xae9d9c074ccf0746L, + 0x72fc21108728d135L }, + { 0xa906b203f96004c8L, 0xd83f95cf458055ffL, 0xd77d586755f35909L, + 0x4a9ea6fbe550c8eeL, 0x91c8cca955a06081L, 0x4a1fee78bce82062L, + 0xeb9ade069a3df85eL, 0xfbbdcf0c7d3de666L, 0x228a391b5d336d51L, + 0x760f8d285c2ffc3cL, 0x1ee48de32f7b165bL, 0x03803d8456177040L, + 0xe573f6489deff9a0L, 0xe1a2738ea17e35a4L, 0x238ef17c8840a6c6L, + 0x480946f8b11ed92dL }, + { 0x84c747a8fd71f119L, 0x19e65c5e53eb3695L, 0x0e2f67866298587aL, + 0x48a48899ab18d6f4L, 0xa1a99024c630b8c0L, 0x849750962caaf892L, + 0xc8869abae20fd624L, 0x3b72b04d6c2b7dd4L, 0xe2775eb60992f7d0L, + 0x0089c06e7d06e684L, 0xcb3b4361e4bbd007L, 0xa1ae666b4ba846e4L, + 0xc01c2eb246464d9eL, 0xf86f2be6c1f8539fL, 0x16e8e8aecf68afc7L, + 0x8dab61fdc7386902L }, + { 0x42a5c903d54d1d45L, 0xacd4297eff4f9ba2L, 0x2d88b52034d478b4L, + 0x35b2ba2b08c4621aL, 0xd3d239bb34865402L, 0x1de76aed911f32e6L, + 0x877f8bcf3f06fdc2L, 0x802714c19ec51502L, 0xa10444eba590700dL, + 0x8694229f31dcc957L, 0x5ece77abb8169fedL, 0x55be8a152caf080eL, + 0x3eb21b14cbd7cef1L, 0x9def7ad167b97ee1L, 0xe03ca879118f690cL, + 0x6f77e62df99b29e7L }, + { 0xa271bdede40bbf59L, 0x177ba4536401aad6L, 0x1755e03573541cd1L, + 0x3465b4664b71b02fL, 0x22eb7113a813359fL, 0x9792a8fd6f38eac7L, + 0x11aa012fff3bf3b5L, 0x99aafabff85c3fbfL, 0x91e0a2ef06c0cc42L, + 0x314d5d57773b7b3aL, 0xae5e2e76d669840aL, 0x861360732e5a8be6L, + 0xee6d7578c1cf5580L, 0x2344e00f68bed102L, 0x799d78868184f0ebL, + 0x63819c91c3d2cf80L }, + { 0xca5392e17884b073L, 0x9ec3a1fceb1267eaL, 0x3d07f5f0907038a7L, + 0xcb2ac07ce4c47b70L, 0xf96664ee1bf96b91L, 0xebf575892aea4fbfL, + 0x5aabf391fade6500L, 0xc5b3376f171d1204L, 0x1ff60c51a0d3d81aL, + 0x10b2cfe7976a844bL, 0xe131cc9abda6125aL, 0xe0fc16d34ebd453eL, + 0xc0d0319a504b6bc1L, 0xe43a0be70a2f8cabL, 0xc80afeec55e49b47L, + 0x67d48d128265d7eeL }, + { 0x068d59a7ea2d56d6L, 0xd71abd0e27480a63L, 0x6bd11db0ae7366cdL, + 0xfbb639ca07204ebcL, 0x89a242e7f77e6293L, 0xdee7ca2b75ba8c3dL, + 0x472ddc3d64a2f9a8L, 0x84229df47561a010L, 0x95f62c85c5b649d4L, + 0xfdd56b1b4dc927cdL, 0xfe8bb1205ee60596L, 0x3efcaa50abf29401L, + 0xd4900d0f10d1c184L, 0x2cf113a928b01df5L, 0xa3d7ebc31f0e43f5L, + 0x27950e38e8384dc7L }, + { 0xeab21ff0e1d0fa79L, 0x4b9fd033048b5de9L, 0x4c9346892fe374cbL, + 0xbb4827fa4eb21f6bL, 0x46716f79a925e7e7L, 0x1442bf367dd4c531L, + 0x2073954cd2e96ddfL, 0x4e0141ae8502aa89L, 0x8ee00e1a8eef6cc9L, + 0x55ce84915880cdafL, 0xff3aba5c69628046L, 0x335cc4f85d15dfbfL, + 0xa7f0440c9f684f25L, 0xae80453fbb1e5bd8L, 0xa1c99813ff2225abL, + 0x54ff788479b25d71L }, + { 0x27c6ee30de40b068L, 0x9226465be6f3a51eL, 0xe24a4604fa3b21f6L, + 0x50a5a5adc0418115L, 0xe32854418df90d2bL, 0xbb74e58fdcb0c00fL, + 0xc68f1b3b4a2c08e3L, 0x339df0810ccd9ec9L, 0x915362dcb786ea9fL, + 0x28945e31c955aeadL, 0xd6a2c01d8b6a6c6bL, 0x069e82dc3678a427L, + 0x1787550028c9302cL, 0x8acda9659fa101e6L, 0x4e4e4573ee30b286L, + 0x8adbad853f1830feL }, + { 0x060ae11f0969d524L, 0xf42fdaf7f39bcc79L, 0x3cec67667cc1fcc2L, + 0x456b9cf2e2336d4fL, 0x6aa1f5de8e1c0f7fL, 0xcdbc2ad20984fb0eL, + 0x4090cfa61b464b28L, 0x40d86f301243f3efL, 0x95b16ccccd5e87e7L, + 0x403f168c3026cd41L, 0xdbe386cb816c0730L, 0x14eb86f358407a1dL, + 0xf588b4f81717e1afL, 0xb75c41a666cbc96cL, 0xf342c1aa027e71c1L, + 0x73930036c0945e5fL }, + { 0x954f757d22cdaf42L, 0x788b591df4181aabL, 0x8b986819f5514f25L, + 0x69642e08f18fd5bcL, 0x92b305d1022ceb91L, 0x1715903e6a4f6985L, + 0x4bd7d69d61179caeL, 0xdacdfd5dd29c01aaL, 0x705ddd5ad91108ccL, + 0x434ac7b164ac8f15L, 0x61a514e1b524632fL, 0x45b9e61b731fc447L, + 0xcf561348e0961b31L, 0x9c28a96773eaf223L, 0x5bd10182aa7c99d3L, + 0x8bc6ec4ae42965e2L }, + { 0xd096e5c0e7f2a32bL, 0xff54800c09388a30L, 0x06fe437c401e360cL, + 0x6655fc9cbb6054a6L, 0x510e18608457aa6eL, 0xa0acfca22b29b2b7L, + 0x732483e351b7da61L, 0xe31471ee6be6c8caL, 0xe565431c8b65c9a1L, + 0xfc9ac3b948d65cbbL, 0xd308fc21ae9b2aa8L, 0xd6a7df0daa60aa6aL, + 0x2844d96a982fc0d4L, 0xab012c2c5847a4d7L, 0x2b3c8f71dceb8955L, + 0x8e85437dbe9c7e15L }, +}; + +/* Perform the modular exponentiation in Fp* for SAKKE. + * + * Base is fixed to be the g parameter - a precomputed table is used. + * + * Striping: 128 points at a distance of 8 combined. + * Total of 256 points in table. + * Square and multiply performed in Fp*. + * + * base [in] Base. MP integer. + * exp [in] Exponent. MP integer. + * res [out] Result. MP integer. + * returns 0 on success, MP_READ_E if there are too many bytes in an array + * and MEMORY_E if memory allocation fails. + */ +int sp_ModExp_Fp_star_1024(const mp_int* base, mp_int* exp, mp_int* res) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td; + sp_digit* t; + sp_digit* tx; + sp_digit* ty; +#else + sp_digit t[4 * 2 * 16]; + sp_digit tx[2 * 16]; + sp_digit ty[2 * 16]; +#endif + sp_digit* r = NULL; + unsigned char e[128]; + int err = MP_OKAY; + int i; + int y; + + (void)base; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6 * 16 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + tx = td + 4 * 16 * 2; + ty = td + 5 * 16 * 2; +#endif + r = ty; + + (void)mp_to_unsigned_bin_len(exp, e, 128); + + XMEMCPY(tx, p1024_norm_mod, sizeof(sp_digit) * 16); + y = e[112] >> 7; + y |= (e[96] >> 7) << 1; + y |= (e[80] >> 7) << 2; + y |= (e[64] >> 7) << 3; + y |= (e[48] >> 7) << 4; + y |= (e[32] >> 7) << 5; + y |= (e[16] >> 7) << 6; + y |= (e[0] >> 7) << 7; + XMEMCPY(ty, sp_1024_g_table[y], sizeof(sp_digit) * 16); + for (i = 126; i >= 0; i--) { + y = (e[127 - (i / 8)] >> (i & 0x7)) & 1; + y |= ((e[111 - (i / 8)] >> (i & 0x7)) & 1) << 1; + y |= ((e[95 - (i / 8)] >> (i & 0x7)) & 1) << 2; + y |= ((e[79 - (i / 8)] >> (i & 0x7)) & 1) << 3; + y |= ((e[63 - (i / 8)] >> (i & 0x7)) & 1) << 4; + y |= ((e[47 - (i / 8)] >> (i & 0x7)) & 1) << 5; + y |= ((e[31 - (i / 8)] >> (i & 0x7)) & 1) << 6; + y |= ((e[15 - (i / 8)] >> (i & 0x7)) & 1) << 7; + + sp_1024_proj_sqr_16(tx, ty, t); + sp_1024_proj_mul_qx1_16(tx, ty, sp_1024_g_table[y], t); + } + } + + if (err == MP_OKAY) { + sp_1024_mont_inv_16(tx, tx, t); + sp_1024_mont_mul_16(r, tx, ty, p1024_mod, p1024_mp_mod); + XMEMSET(r + 16, 0, sizeof(sp_digit) * 16); + sp_1024_mont_reduce_16(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Multiply p* by q* in projective co-ordinates. + * + * p.x' = (p.x * q.x) - (p.y * q.y) + * p.y' = (p.x * q.y) + (p.y * q.x) + * But applying Karatsuba: + * v0 = p.x * q.x + * v1 = p.y * q.y + * p.x' = v0 - v1 + * p.y' = (px + py) * (qx + qy) - v0 - v1 + * + * px [in,out] A single precision integer - X ordinate of number to multiply. + * py [in,out] A single precision integer - Y ordinate of number to multiply. + * qx [in] A single precision integer - X ordinate of number of + * multiplier. + * qy [in] A single precision integer - Y ordinate of number of + * multiplier. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_mul_16(sp_digit* px, sp_digit* py, + const sp_digit* qx, const sp_digit* qy, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 16; + + /* t1 = px + py */ + sp_1024_mont_add_16(t1, px, py, p1024_mod); + /* t2 = qx + qy */ + sp_1024_mont_add_16(t2, qx, qy, p1024_mod); + /* t2 = (px + py) * (qx + qy) */ + sp_1024_mont_mul_16(t2, t1, t2, p1024_mod, p1024_mp_mod); + /* t1 = py * qy */ + sp_1024_mont_mul_16(t1, py, qy, p1024_mod, p1024_mp_mod); + /* t2 = (px + py) * (qx + qy) - (py * qy) */ + sp_1024_mont_sub_16(t2, t2, t1, p1024_mod); + /* px = px * qx */ + sp_1024_mont_mul_16(px, px, qx, p1024_mod, p1024_mp_mod); + /* py = (px + py) * (qx + qy) - (py * qy) - (px * qx) */ + sp_1024_mont_sub_16(py, t2, px, p1024_mod); + /* px = (px * qx) - (py * qy)*/ + sp_1024_mont_sub_16(px, px, t1, p1024_mod); +} + +#ifndef WOLFSSL_SP_SMALL +/* + * Convert point from projective to affine but keep in Montgomery form. + * + * p [in,out] Point to convert. + * t [in] Temporary numbers: 2. + */ +static void sp_1024_mont_map_16(sp_point_1024* p, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 16; + + sp_1024_mont_inv_16(t1, p->z, t2); + sp_1024_mont_sqr_16(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t1, t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(p->x, p->x, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(p->y, p->y, t1, p1024_mod, p1024_mp_mod); + XMEMCPY(p->z, p1024_norm_mod, sizeof(sp_digit) * 16); +} + +#endif /* WOLFSSL_SP_SMALL */ +/* + * Calculate gradient of line through P, P and [-2]P, accumulate line and + * double P. + * + * Calculations: + * l = 3 * (p.x^2 - p.z^4) = 3 * (p.x - p.z^2) * (p.x + p.z^2) + * r.x = l * (p.x + q.x * p.z^2) - 2 * p.y^2 + * r.y = 2 * p.y * p.z^3 * q.y (= p'.z * p.z^2 * q.y) + * v* = v*^2 * r* + * p'.x = l^2 - 8 * p.y^2 * p.x + * p'.y = (4 * p.y^2 * p.x - p'.x) * l - 8 * p.y^4 + * p'.z = 2 * p.y * p.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] p ECC point - point on E(F_p^2) to double. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_dbl_16(sp_digit* vx, sp_digit* vy, + sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 16; + sp_digit* pz2 = t + 2 * 16; + sp_digit* rx = t + 4 * 16; + sp_digit* ry = t + 6 * 16; + sp_digit* l = t + 8 * 16; + sp_digit* ty = t + 10 * 16; + + /* v = v^2 */ + sp_1024_proj_sqr_16(vx, vy, t); + /* pz2 = p.z^2 */ + sp_1024_mont_sqr_16(pz2, p->z, p1024_mod, p1024_mp_mod); + /* t1 = p.x + p.z^2 */ + sp_1024_mont_add_16(ty, p->x, pz2, p1024_mod); + /* l = p.x - p.z^2 */ + sp_1024_mont_sub_16(l, p->x, pz2, p1024_mod); + /* t1 = (p.x + p.z^2) * (p.x - p.z^2) = p.x^2 - p.z^4 */ + sp_1024_mont_mul_16(t1, l, ty, p1024_mod, p1024_mp_mod); + /* l = 3 * (p.x^2 - p.z^4) */ + sp_1024_mont_tpl_16(l, t1, p1024_mod); + /* t1 = q.x * p.z^2 */ + sp_1024_mont_mul_16(t1, q->x, pz2, p1024_mod, p1024_mp_mod); + /* t1 = p.x + q.x * p.z^2 */ + sp_1024_mont_add_16(t1, p->x, t1, p1024_mod); + /* r.x = l * (p.x + q.x * p.z^2) */ + sp_1024_mont_mul_16(rx, l, t1, p1024_mod, p1024_mp_mod); + /* r.y = 2 * p.y */ + sp_1024_mont_dbl_16(ry, p->y, p1024_mod); + /* ty = 4 * p.y ^ 2 */ + sp_1024_mont_sqr_16(ty, ry, p1024_mod, p1024_mp_mod); + /* t1 = 2 * p.y ^ 2 */ + sp_1024_div2_16(t1, ty, p1024_mod); + /* r.x -= 2 * (p.y ^ 2) */ + sp_1024_mont_sub_16(rx, rx, t1, p1024_mod); + /* p'.z = p.y * 2 * p.z */ + sp_1024_mont_mul_16(p->z, p->z, ry, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 */ + sp_1024_mont_mul_16(t1, p->z, pz2, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 * q.y */ + sp_1024_mont_mul_16(ry, t1, q->y, p1024_mod, p1024_mp_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_16(vx, vy, rx, ry, t); + + /* Double point using previously calculated values + * l = 3 * (p.x - p.z^2).(p.x + p.z^2) + * ty = 4 * p.y^2 + * p'.z = 2 * p.y * p.z + */ + /* t1 = (4 * p.y^2) ^ 2 = 16 * p.y^4 */ + sp_1024_mont_sqr_16(t1, ty, p1024_mod, p1024_mp_mod); + /* t1 = 16 * p.y^4 / 2 = 8 * p.y^4 */ + sp_1024_div2_16(t1, t1, p1024_mod); + /* p'.y = 4 * p.y^2 * p.x */ + sp_1024_mont_mul_16(p->y, ty, p->x, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 */ + sp_1024_mont_sqr_16(p->x, l, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 - 4 * p.y^2 * p.x */ + sp_1024_mont_sub_16(p->x, p->x, p->y, p1024_mod); + /* p'.x = l^2 - 8 * p.y^2 * p.x */ + sp_1024_mont_sub_16(p->x, p->x, p->y, p1024_mod); + /* p'.y = 4 * p.y^2 * p.x - p.x' */ + sp_1024_mont_sub_16(ty, p->y, p->x, p1024_mod); + /* p'.y = (4 * p.y^2 * p.x - p'.x) * l */ + sp_1024_mont_mul_16(p->y, ty, l, p1024_mod, p1024_mp_mod); + /* p'.y = (4 * p.y^2 * p.x - p'.x) * l - 8 * p.y^4 */ + sp_1024_mont_sub_16(p->y, p->y, t1, p1024_mod); +} + +#ifdef WOLFSSL_SP_SMALL +/* + * Calculate gradient of line through C, P and -C-P, accumulate line and + * add P to C. + * + * Calculations: + * r.x = (q.x + p.x) * c.y - (q.x * c.z^2 + c.x) * p.y * c.z + * r.y = (c.x - p.x * c.z^2) * q.y * c.z + * v* = v* * r* + * r = p.y * c.z^3 - c.y + * c'.x = r^2 + h^3 - 2 * c.x * h^2 + * c'.y = r * (c'.x - c.x * h^2) - c.y * h^3 + * c'.z = (c.x - p.x * c.z^2) * c.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] c ECC point - current point on E(F_p^2) to be added + * to. + * @param [in] p ECC point - point on E(F_p^2) to add. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] qx_px SP that is a constant value across adds. + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_add_one_16(sp_digit* vx, sp_digit* vy, + sp_point_1024* c, sp_point_1024* p, sp_point_1024* q, sp_digit* qx_px, + sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 16; + sp_digit* rx = t + 4 * 16; + sp_digit* ry = t + 6 * 16; + sp_digit* h = t + 8 * 16; + sp_digit* r = t + 10 * 16; + + /* r.x = (q.x + p.x) * c.y */ + sp_1024_mont_mul_16(rx, qx_px, c->y, p1024_mod, p1024_mp_mod); + /* t2 = c.z^2 */ + sp_1024_mont_sqr_16(t2, c->z, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 */ + sp_1024_mont_mul_16(t1, q->x, t2, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 + c.x */ + sp_1024_mont_add_16(h, t1, c->x, p1024_mod); + /* r = p.y * c.z */ + sp_1024_mont_mul_16(ry, p->y, c->z, p1024_mod, p1024_mp_mod); + /* t1 = (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_mul_16(t1, h, ry, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z * c.z^2 = p.y * c.z^3 */ + sp_1024_mont_mul_16(r, ry, t2, p1024_mod, p1024_mp_mod); + /* r.x -= (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_sub_16(rx, rx, t1, p1024_mod); + /* t1 = p.x * c.z^2 */ + sp_1024_mont_mul_16(t1, p->x, t2, p1024_mod, p1024_mp_mod); + /* h = c.x - p.x * c.z^2 */ + sp_1024_mont_sub_16(h, c->x, t1, p1024_mod); + /* c'.z = (c.x - p.x * c.z^2) * c.z */ + sp_1024_mont_mul_16(c->z, h, c->z, p1024_mod, p1024_mp_mod); + /* r.y = (c.x - p.x * c.z^2) * c.z * q.y */ + sp_1024_mont_mul_16(ry, c->z, q->y, p1024_mod, p1024_mp_mod); + /* v = v * r */ + sp_1024_proj_mul_16(vx, vy, rx, ry, t); + + /* Add p to c using previously calculated values. + * h = c.x - p.x * c.z^2 + * r = p.y * c.z^3 + * c'.z = (c.x - p.x * c.z^2) * c.z + */ + + /* r = p.y * c.z^3 - c.y */ + sp_1024_mont_sub_16(r, r, c->y, p1024_mod); + /* t1 = r^2 */ + sp_1024_mont_sqr_16(t1, r, p1024_mod, p1024_mp_mod); + /* t2 = h^2 */ + sp_1024_mont_sqr_16(rx, h, p1024_mod, p1024_mp_mod); + /* ry = c.x * h^2 */ + sp_1024_mont_mul_16(ry, c->x, rx, p1024_mod, p1024_mp_mod); + /* t2 = h^3 */ + sp_1024_mont_mul_16(t2, rx, h, p1024_mod, p1024_mp_mod); + /* c->x = r^2 + h^3 */ + sp_1024_mont_add_16(c->x, t1, t2, p1024_mod); + /* t1 = 2 * c.x * h^2 */ + sp_1024_mont_dbl_16(t1, ry, p1024_mod); + /* c'.x = r^2 + h^3 - 2 * c.x * h^2 */ + sp_1024_mont_sub_16(c->x, c->x, t1, p1024_mod); + /* ry = c'.x - c.x * h^2 */ + sp_1024_mont_sub_16(t1, c->x, ry, p1024_mod); + /* ry = r * (c'.x - c.x * h^2) */ + sp_1024_mont_mul_16(ry, t1, r, p1024_mod, p1024_mp_mod); + /* t2 = c.y * h^3 */ + sp_1024_mont_mul_16(t1, t2, c->y, p1024_mod, p1024_mp_mod); + /* c'.y = r * (c'.x - c.x * h^2) - c.y * h^3 */ + sp_1024_mont_sub_16(c->y, ry, t1, p1024_mod); +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * @param [in] key SAKKE key. + * @param [in] p First point on E(F_p)[q]. + * @param [in] q Second point on E(F_p)[q]. + * @param [in] r Result of calculation. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +int sp_Pairing_1024(const ecc_point* pm, const ecc_point* qm, mp_int* res) +{ + int err = MP_OKAY; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit* qx_px; +#else + sp_digit t[6 * 2 * 16]; + sp_digit vx[2 * 16]; + sp_digit vy[2 * 16]; + sp_digit qx_px[2 * 16]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + + err = sp_1024_point_new_16(NULL, pd, p); + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 9 * 16 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 16 * 2; + vy = td + 7 * 16 * 2; + qx_px = td + 8 * 16 * 2; +#endif + r = vy; + + sp_1024_point_from_ecc_point_16(p, pm); + sp_1024_point_from_ecc_point_16(q, qm); + + err = sp_1024_mod_mul_norm_16(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 16); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 16); + + sp_1024_mont_add_16(qx_px, q->x, p->x, p1024_mod); + + for (i = 1020; i >= 0; i--) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_dbl_16(vx, vy, c, q, t); + + if ((i > 0) && ((p1024_order[i / 64] >> (i % 64)) & 1)) { + /* Accumulate line into v and add P into C. */ + sp_1024_accumulate_line_add_one_16(vx, vy, c, p, q, qx_px, t); + } + } + + /* Final exponentiation */ + sp_1024_proj_sqr_16(vx, vy, t); + sp_1024_proj_sqr_16(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_16(vx, vx, t); + sp_1024_mont_mul_16(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 16, 0, sizeof(sp_digit) * 16); + sp_1024_mont_reduce_16(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_16(c, 1, NULL); + sp_1024_point_free_16(q, 1, NULL); + sp_1024_point_free_16(p, 1, NULL); + return err; +} + +#else +/* + * Calculate gradient of line through C, P and -C-P, accumulate line and + * add P to C. + * + * Both C and P have z ordinates to use in the calculation. + * + * Calculations: + * r.x = (q.x * c.z^2 + c.x) * p.y * c.z - (q.x * p.z^2 + p.x) * c.y * p.z + * r.y = (p.x * c.z^2 - c.x * p.z^2) * q.y * p.z * c.z + * v* = v* * r* + * h = p.x * c.z^2 - c.x * p.z^2 + * r = p.y * c.z^3 - c.y * p.z^3 + * c'.x = r^2 - h^3 - 2 * c.x * p.z^2 * h^2 + * c'.y = r * (c.x * p.z^2 * h^2 - c'.x) - c.y * p.z^3 * h^3 + * c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] c ECC point - current point on E(F_p^2) to be added + * to. + * @param [in,out] p ECC point - point on E(F_p^2) to add. + * @param [in,out] q ECC point - second point on E(F_P^2). + * @param [in,out] t SP temporaries (6 used). + * @param [in,out] neg Indicates to use negative P. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static void sp_1024_accumulate_line_add_n_16(sp_digit* vx, sp_digit* vy, + const sp_point_1024* p, const sp_point_1024* q, + sp_point_1024* c, sp_digit* t, int neg) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 16; + sp_digit* rx = t + 4 * 16; + sp_digit* ry = t + 6 * 16; + sp_digit* h = t + 8 * 16; + sp_digit* r = t + 10 * 16; + + /* h = p.z^2 */ + sp_1024_mont_sqr_16(h, p->z, p1024_mod, p1024_mp_mod); + /* rx = q.x * p.z^2 */ + sp_1024_mont_mul_16(rx, q->x, h, p1024_mod, p1024_mp_mod); + /* rx = q.x * p.z^2 + p.x */ + sp_1024_mont_add_16(t2, rx, p->x, p1024_mod); + /* c.y = c.y * p.z */ + sp_1024_mont_mul_16(t1, c->y, p->z, p1024_mod, p1024_mp_mod); + /* r.x = (q.x * p.z^2 + p.x) * c.y * p.z */ + sp_1024_mont_mul_16(rx, t2, t1, p1024_mod, p1024_mp_mod); + /* c.y = c.y * p.z^3 */ + sp_1024_mont_mul_16(c->y, t1, h, p1024_mod, p1024_mp_mod); + /* t2 = c.z^2 */ + sp_1024_mont_sqr_16(t2, c->z, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 */ + sp_1024_mont_mul_16(t1, q->x, t2, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 + c.x */ + sp_1024_mont_add_16(t1, t1, c->x, p1024_mod); + /* c.x = c.x * p.z^2 */ + sp_1024_mont_mul_16(c->x, c->x, h, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z */ + sp_1024_mont_mul_16(r, p->y, c->z, p1024_mod, p1024_mp_mod); + if (neg) { + /* r = -p.y * c.z */ + sp_1024_mont_sub_16(r, p1024_mod, r, p1024_mod); + } + /* t1 = (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_mul_16(ry, t1, r, p1024_mod, p1024_mp_mod); + /* r.x -= (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_sub_16(rx, ry, rx, p1024_mod); + /* t1 = p.x * c.z^2 */ + sp_1024_mont_mul_16(t1, p->x, t2, p1024_mod, p1024_mp_mod); + /* h = p.x * c.z^2 - c.x * p.z^2 */ + sp_1024_mont_sub_16(h, t1, c->x, p1024_mod); + /* c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z */ + sp_1024_mont_mul_16(t1, h, c->z, p1024_mod, p1024_mp_mod); + /* c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z * p.z */ + sp_1024_mont_mul_16(c->z, t1, p->z, p1024_mod, p1024_mp_mod); + /* r.y = (p.x * c.z^2 - c.x * p.z^2) * c.z * p.z * q.y */ + sp_1024_mont_mul_16(ry, c->z, q->y, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z^3 */ + sp_1024_mont_mul_16(t1, r, t2, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z^3 - c.y * p.z^3 */ + sp_1024_mont_sub_16(r, t1, c->y, p1024_mod); + /* v = v * r */ + sp_1024_proj_mul_16(vx, vy, rx, ry, t); + + /* Add p to c using previously calculated values. + * h = p.x * c.z^2 - c.x * p.z^2 + * r = p.y * c.z^3 - c.y * p.z^3 + * c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z + */ + + /* t1 = r^2 */ + sp_1024_mont_sqr_16(t1, r, p1024_mod, p1024_mp_mod); + /* t2 = h^2 */ + sp_1024_mont_sqr_16(rx, h, p1024_mod, p1024_mp_mod); + /* ry = c.x * p.z^2 * h^2 */ + sp_1024_mont_mul_16(ry, rx, c->x, p1024_mod, p1024_mp_mod); + /* t2 = h^3 */ + sp_1024_mont_mul_16(t2, rx, h, p1024_mod, p1024_mp_mod); + /* c'.x = r^2 - h^3 */ + sp_1024_mont_sub_16(c->x, t1, t2, p1024_mod); + /* t1 = 2 * c.x * p.z^2 * h^2 */ + sp_1024_mont_dbl_16(t1, ry, p1024_mod); + /* c'.x = r^2 - h^3 - 2 * c.x * p.z^2 * h^2 */ + sp_1024_mont_sub_16(c->x, c->x, t1, p1024_mod); + /* ry = c.x * p.z^2 * h^2 - c'.x */ + sp_1024_mont_sub_16(t1, ry, c->x, p1024_mod); + /* ry = r * (c.x * p.z^2 * h^2 - c'.x) */ + sp_1024_mont_mul_16(ry, t1, r, p1024_mod, p1024_mp_mod); + /* t2 = c.y * p.z^3 * h^3 */ + sp_1024_mont_mul_16(t1, t2, c->y, p1024_mod, p1024_mp_mod); + /* c'.y = r * (c.x * p.z^2 * h^2 - c'.x) - c.y * p.z^3 * h^3 */ + sp_1024_mont_sub_16(c->y, ry, t1, p1024_mod); +} + +/* + * Perform n accumulate doubles and doubles of P. + * + * py = 2 * p.y + * + * For each double: + * Calculate gradient of line through P, P and [-2]P, accumulate line and + * double P. + * + * Calculations: + * l = 3 * (p.x^2 - p.z^4) = 3 * (p.x - p.z^2) * (p.x + p.z^2) + * r.x = l * (p.x + q.x * p.z^2) - py^2 / 2 + * r.y = py * p.z^3 * q.y (= p'.z * p.z^2 * q.y) + * v* = v*^2 * r* + * p'.x = l^2 - 2 * py^2 * p.x + * py' = (py^2 * p.x - p'.x) * l - py^4 (= 2 * p'.y) + * p'.z = py * p.z + * + * Finally: + * p'.y = py' / 2 + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] p ECC point - point on E(F_p^2) to double. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] n Number of times to double. + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_dbl_n_16(sp_digit* vx, sp_digit* vy, + sp_point_1024* p, const sp_point_1024* q, int n, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 16; + sp_digit* pz2 = t + 2 * 16; + sp_digit* rx = t + 4 * 16; + sp_digit* ry = t + 6 * 16; + sp_digit* l = t + 8 * 16; + sp_digit* ty = t + 10 * 16; + int i; + + /* py = 2 * p.y */ + sp_1024_mont_dbl_16(p->y, p->y, p1024_mod); + + for (i = 0; i < n; i++) { + /* v = v^2 */ + sp_1024_proj_sqr_16(vx, vy, t); + /* pz2 = p.z^2 */ + sp_1024_mont_sqr_16(pz2, p->z, p1024_mod, p1024_mp_mod); + /* t1 = p.x + p.z^2 */ + sp_1024_mont_add_16(t1, p->x, pz2, p1024_mod); + /* l = p.x - p.z^2 */ + sp_1024_mont_sub_16(l, p->x, pz2, p1024_mod); + /* t1 = (p.x + p.z^2) * (p.x - p.z^2) = p.x^2 - p.z^4 */ + sp_1024_mont_mul_16(ty, l, t1, p1024_mod, p1024_mp_mod); + /* l = 3 * (p.x^2 - p.z^4) */ + sp_1024_mont_tpl_16(l, ty, p1024_mod); + /* t1 = q.x * p.z^2 */ + sp_1024_mont_mul_16(t1, q->x, pz2, p1024_mod, p1024_mp_mod); + /* t1 = p.x + q.x * p.z^2 */ + sp_1024_mont_add_16(t1, p->x, t1, p1024_mod); + /* r.x = l * (p.x + q.x * p.z^2) */ + sp_1024_mont_mul_16(rx, l, t1, p1024_mod, p1024_mp_mod); + /* ty = py ^ 2 */ + sp_1024_mont_sqr_16(ty, p->y, p1024_mod, p1024_mp_mod); + /* t1 = py ^ 2 / 2 */ + sp_1024_div2_16(t1, ty, p1024_mod); + /* r.x -= py ^ 2 / 2 */ + sp_1024_mont_sub_16(rx, rx, t1, p1024_mod); + /* p'.z = py * pz */ + sp_1024_mont_mul_16(p->z, p->z, p->y, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 */ + sp_1024_mont_mul_16(t1, p->z, pz2, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 * q.y */ + sp_1024_mont_mul_16(ry, t1, q->y, p1024_mod, p1024_mp_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_16(vx, vy, rx, ry, t); + + /* Double point using previously calculated values + * l = 3 * (p.x - p.z^2).(p.x + p.z^2) + * ty = py^2 + * p'.z = py * p.z + */ + /* t1 = py^2 ^ 2 = py^4 */ + sp_1024_mont_sqr_16(t1, ty, p1024_mod, p1024_mp_mod); + /* py' = py^2 * p. x */ + sp_1024_mont_mul_16(p->y, ty, p->x, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 */ + sp_1024_mont_sqr_16(p->x, l, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 - py^2 * p.x */ + sp_1024_mont_sub_16(p->x, p->x, p->y, p1024_mod); + /* p'.x = l^2 - 2 * p.y^2 * p.x */ + sp_1024_mont_sub_16(p->x, p->x, p->y, p1024_mod); + /* py' = py^2 * p.x - p.x' */ + sp_1024_mont_sub_16(ty, p->y, p->x, p1024_mod); + /* py' = (p.y^2 * p.x - p'.x) * l */ + sp_1024_mont_mul_16(p->y, ty, l, p1024_mod, p1024_mp_mod); + /* py' = (p.y^2 * p.x - p'.x) * l * 2 */ + sp_1024_mont_dbl_16(p->y, p->y, p1024_mod); + /* py' = (p.y^2 * p.x - p'.x) * l * 2 - p.y^4 */ + sp_1024_mont_sub_16(p->y, p->y, t1, p1024_mod); + } + + /* p'.y = py' / 2 */ + sp_1024_div2_16(p->y, p->y, p1024_mod); +} + +/* Operations to perform based on order - 1. + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * Pairs: #dbls, add/subtract window value + */ +static const signed char sp_1024_order_op[] = { + 5, 6, -13, 9, -21, 6, -5, 8, 31, 6, 3, 6, -27, 6, 25, 9, + -1, 6, -11, 6, -13, 6, -7, 6, -15, 6, -29, 7, 25, 6, -9, 6, + -19, 7, 3, 6, 11, 9, -23, 6, 1, 6, 27, 6, 1, 7, -25, 8, + 13, 7, -13, 7, -23, 10, 19, 7, 7, 7, -3, 7, 27, 6, -7, 7, + -21, 7, 11, 7, 31, 8, 1, 7, -23, 6, -17, 6, -3, 10, 11, 6, + -21, 7, -27, 11, -29, 6, -1, 10, 15, 8, 27, 7, 17, 6, 17, 7, + -13, 8, 13, 6, 21, 7, -29, 6, 19, 7, -25, 6, 11, 9, 29, 7, + -7, 8, 27, 7, 29, 10, -1, 8, -7, 8, 17, 6, 17, 7, -27, 7, + -21, 6, -9, 6, -27, 12, -23, 6, 19, 6, 13, 6, -11, 7, 27, 6, + 17, 6, -7, 6, -25, 7, -29, 6, 9, 7, 7, 6, 13, 6, -25, 6, + -19, 6, 13, 6, -11, 6, 5, 8, 19, 6, -21, 8, 23, 7, 27, 6, + -13, 6, -19, 11, 29, 7, -15, 6, -9, 7, -21, 10, -3, 7, 21, 10, + 25, 6, -15, 6, -23, 6, 21, 6, 1, 6, 21, 7, -3, 6, -3, 7, + -7, 6, -23, 7, 7, 8, 15, 9, 5, 6, -11, 6, 21, 11, -27, 7, + 27, 6, -11, 6, 31, 6, -21, 6, 19, 6, -7, 8, -7, 13, -3, 6, + -7, 7, -3, 6, 1, 6, 7, 8, 19, 8, 11, 9, -9, 7, -31, 12, + 25, 6, -17, 9, -15, 7, 5, 6, 25, 7, -5, 7, -25, 6, 17, 8, + -19, 6, -13, 6, 27, 8, 1, 7, -5, 7, -1, 6, 21, 6, 3, 10, + -3, 1, +}; +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int sp_Pairing_1024(const ecc_point* pm, const ecc_point* qm, mp_int* res) +{ + int err; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit (*pre_vx)[32]; + sp_digit (*pre_vy)[32]; + sp_digit (*pre_nvy)[32]; + sp_point_1024* pre_p; +#else + sp_digit t[6 * 2 * 16]; + sp_digit vx[2 * 16]; + sp_digit vy[2 * 16]; + sp_digit pre_vx[16][32]; + sp_digit pre_vy[16][32]; + sp_digit pre_nvy[16][32]; + sp_point_1024 pre_p[16]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + int j; + + err = sp_1024_point_new_16(NULL, pd, p); + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 56 * 16 * 2 + 16 * sizeof(sp_point_1024), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 16 * 2; + vy = td + 7 * 16 * 2; + pre_vx = (sp_digit(*)[32])(td + 8 * 16 * 2); + pre_vy = (sp_digit(*)[32])(td + 24 * 16 * 2); + pre_nvy = (sp_digit(*)[32])(td + 40 * 16 * 2); + pre_p = (sp_point_1024*)(td + 56 * 16 * 2); +#endif + r = vy; + + sp_1024_point_from_ecc_point_16(p, pm); + sp_1024_point_from_ecc_point_16(q, qm); + + err = sp_1024_mod_mul_norm_16(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMCPY(&pre_p[0], p, sizeof(sp_point_1024)); + XMEMSET(pre_vx[0], 0, sizeof(sp_digit) * 2 * 16); + pre_vx[0][0] = 1; + XMEMSET(pre_vy[0], 0, sizeof(sp_digit) * 2 * 16); + sp_1024_mont_sub_16(pre_nvy[0], p1024_mod, pre_vy[0], p1024_mod); + + /* [2]P for adding */ + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 16); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 16); + sp_1024_accumulate_line_dbl_16(vx, vy, c, q, t); + + /* 3, 5, ... */ + for (i = 1; i < 16; i++) { + XMEMCPY(&pre_p[i], &pre_p[i-1], sizeof(sp_point_1024)); + XMEMCPY(pre_vx[i], pre_vx[i-1], sizeof(sp_digit) * 2 * 16); + XMEMCPY(pre_vy[i], pre_vy[i-1], sizeof(sp_digit) * 2 * 16); + sp_1024_proj_mul_16(pre_vx[i], pre_vy[i], vx, vy, t); + sp_1024_accumulate_line_add_n_16(pre_vx[i], pre_vy[i], c, + q, &pre_p[i], t, 0); + sp_1024_mont_sub_16(pre_nvy[i], p1024_mod, pre_vy[i], p1024_mod); + } + + j = sp_1024_order_op[0] / 2; + XMEMCPY(c, &pre_p[j], sizeof(sp_point_1024)); + XMEMCPY(vx, pre_vx[j], sizeof(sp_digit) * 2 * 16); + XMEMCPY(vy, pre_vy[j], sizeof(sp_digit) * 2 * 16); + + /* Accumulate line into v and double point n times. */ + sp_1024_accumulate_line_dbl_n_16(vx, vy, c, q, + sp_1024_order_op[1], t); + + for (i = 2; i < 290; i += 2) { + j = sp_1024_order_op[i]; + if (j > 0) { + j /= 2; + /* Accumulate line into v and add P into C. */ + sp_1024_proj_mul_16(vx, vy, pre_vx[j], pre_vy[j], t); + sp_1024_accumulate_line_add_n_16(vx, vy, &pre_p[j], q, c, + t, 0); + } + else { + j = -j / 2; + /* Accumulate line into v and add P into C. */ + sp_1024_proj_mul_16(vx, vy, pre_vx[j], pre_nvy[j], t); + sp_1024_accumulate_line_add_n_16(vx, vy, &pre_p[j], q, c, + t, 1); + } + + /* Accumulate line into v and double point n times. */ + sp_1024_accumulate_line_dbl_n_16(vx, vy, c, q, + sp_1024_order_op[i + 1], t); + } + + /* Final exponentiation */ + sp_1024_proj_sqr_16(vx, vy, t); + sp_1024_proj_sqr_16(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_16(vx, vx, t); + sp_1024_mont_mul_16(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 16, 0, sizeof(sp_digit) * 16); + sp_1024_mont_reduce_16(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_16(c, 1, NULL); + sp_1024_point_free_16(q, 1, NULL); + sp_1024_point_free_16(p, 1, NULL); + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* + * Generate table for pairing. + * + * Small implementation does not use a table - returns 0 length. + * + * pm [in] Point to generate table for. + * table [in] Generated table. + * len [in,out] On in, the size of the buffer. + * On out, length of table generated. + * @return 0 on success. + * LENGTH_ONLY_E when table is NULL and only length returned. + * BUFFER_E when len is too small. + */ +int sp_Pairing_gen_precomp_1024(const ecc_point* pm, byte* table, + word32* len) +{ + int err = 0; + + if (table == NULL) { + *len = 0; + err = LENGTH_ONLY_E; + } + else if (*len != 0) { + err = BUFFER_E; + } + + (void)*pm; + + return err; +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Small implementation does not use a table - use the normal implementation. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @param [in] table Precomputed table of values. + * @param [in] len Length of precomputed table of values in bytes. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int sp_Pairing_precomp_1024(const ecc_point* pm, const ecc_point* qm, + mp_int* res, const byte* table, word32 len) +{ + (void)table; + (void)len; + return sp_Pairing_1024(pm, qm, res); +} + +#else +/* + * Calc l and c for the point when doubling p. + * + * l = 3 * (p.x^2 - 1) / (2 * p.y) + * c = l * p.x - p.y + * + * @param [out] lr Gradient result - table entry. + * @param [out] cr Constant result - table entry. + * @param [in] px X-ordinate of point to double. + * @param [in] py Y-ordinate of point to double. + * @param [in] t SP temporaries (3 used). + */ +static void sp_1024_accum_dbl_calc_lc_16(sp_digit* lr, sp_digit* cr, + const sp_digit* px, const sp_digit* py, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 2 * 16; + sp_digit* t2 = t + 2 * 2 * 16; + sp_digit* l = t + 4 * 2 * 16; + + + /* l = 1 / 2 * p.y */ + sp_1024_mont_dbl_16(l, py, p1024_mod); + sp_1024_mont_inv_16(l, l, t); + + /* t1 = p.x^2 */ + sp_1024_mont_sqr_16(t1, px, p1024_mod, p1024_mp_mod); + /* t1 = p.x - 1 */ + sp_1024_mont_sub_16(t1, t1, p1024_norm_mod, p1024_mod); + /* t1 = 3 * (p.x^2 - 1) */ + sp_1024_mont_dbl_16(t2, t1, p1024_mod); + sp_1024_mont_add_16(t1, t1, t2, p1024_mod); + /* t1 = 3 * (p.x^2 - 1) / (2 * p.y) */ + sp_1024_mont_mul_16(l, l, t1, p1024_mod, p1024_mp_mod); + /* t2 = l * p.x */ + sp_1024_mont_mul_16(t2, l, px, p1024_mod, p1024_mp_mod); + /* c = t2 = l * p.x - p.y */ + sp_1024_mont_sub_16(t2, t2, py, p1024_mod); + + XMEMCPY(lr, l, sizeof(sp_digit) * 16); + XMEMCPY(cr, t2, sizeof(sp_digit) * 16); +} + +/* + * Calc l and c when adding p and c. + * + * l = (c.y - p.y) / (c.x - p.x) + * c = (p.x * c.y - cx * p.y) / (cx - p.x) + * + * @param [out] lr Gradient result - table entry. + * @param [out] cr Constant result - table entry. + * @param [in] px X-ordinate of point to add. + * @param [in] py Y-ordinate of point to add. + * @param [in] cx X-ordinate of current point. + * @param [in] cy Y-ordinate of current point. + * @param [in] t SP temporaries (3 used). + */ +static void sp_1024_accum_add_calc_lc_16(sp_digit* lr, sp_digit* cr, + const sp_digit* px, const sp_digit* py, const sp_digit* cx, + const sp_digit* cy, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 2 * 16; + sp_digit* c = t + 2 * 2 * 16; + sp_digit* l = t + 4 * 2 * 16; + + + /* l = 1 / (c.x - p.x) */ + sp_1024_mont_sub_16(l, cx, px, p1024_mod); + sp_1024_mont_inv_16(l, l, t); + + /* c = p.x * c.y */ + sp_1024_mont_mul_16(c, px, cy, p1024_mod, p1024_mp_mod); + /* t1 = c.x * p.y */ + sp_1024_mont_mul_16(t1, cx, py, p1024_mod, p1024_mp_mod); + /* c = (p.x * c.y) - (c.x * p.y) */ + sp_1024_mont_sub_16(c, c, t1, p1024_mod); + /* c = ((p.x * c.y) - (c.x * p.y)) / (c.x - p.x) */ + sp_1024_mont_mul_16(c, c, l, p1024_mod, p1024_mp_mod); + /* t1 = c.y - p.y */ + sp_1024_mont_sub_16(t1, cy, py, p1024_mod); + /* l = (c.y - p.y) / (c.x - p.x) */ + sp_1024_mont_mul_16(l, t1, l, p1024_mod, p1024_mp_mod); + + XMEMCPY(lr, l, sizeof(sp_digit) * 16); + XMEMCPY(cr, c, sizeof(sp_digit) * 16); +} + +/* + * Calculate vx and vy given gradient l and constant c and point q. + * + * l is a the gradient and is multiplied by q->x. + * c is a the constant that is added to the multiplicative result. + * q->y is the y-ordinate in result to multiply. + * + * if dbl + * v* = v*^2 + * r.x = l * q.x + c + * r.y = q->y + * v* = v* * r* + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in] l Gradient to multiply with. + * @param [in] c Constant to add with. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] t SP temporaries (3 used). + * @param [in] dbl Indicates whether this is for doubling. Otherwise + * adding. + */ +static void sp_1024_accumulate_line_lc_16(sp_digit* vx, sp_digit* vy, + const sp_digit* l, const sp_digit* c, const sp_point_1024* q, + sp_digit* t, int dbl) +{ + sp_digit* rx = t + 4 * 2 * 16; + + /* v = v^2 */ + if (dbl) { + sp_1024_proj_sqr_16(vx, vy, t); + } + /* rx = l * q.x + c */ + sp_1024_mont_mul_16(rx, l, q->x, p1024_mod, p1024_mp_mod); + sp_1024_mont_add_16(rx, rx, c, p1024_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_16(vx, vy, rx, q->y, t); +} + +/* Operations to perform based on order - 1. + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * Pairs: #dbls, add/subtract window value + */ +static const signed char sp_1024_order_op_pre[] = { + 5, 6, -13, 9, -21, 6, -5, 8, 31, 6, 3, 6, -27, 6, 25, 9, + -1, 6, -11, 6, -13, 6, -7, 6, -15, 6, -29, 7, 25, 6, -9, 6, + -19, 7, 3, 6, 11, 9, -23, 6, 1, 6, 27, 6, 1, 7, -25, 8, + 13, 7, -13, 7, -23, 10, 19, 7, 7, 7, -3, 7, 27, 6, -7, 7, + -21, 7, 11, 7, 31, 8, 1, 7, -23, 6, -17, 6, -3, 10, 11, 6, + -21, 7, -27, 11, -29, 6, -1, 10, 15, 8, 27, 7, 17, 6, 17, 7, + -13, 8, 13, 6, 21, 7, -29, 6, 19, 7, -25, 6, 11, 9, 29, 7, + -7, 8, 27, 7, 29, 10, -1, 8, -7, 8, 17, 6, 17, 7, -27, 7, + -21, 6, -9, 6, -27, 12, -23, 6, 19, 6, 13, 6, -11, 7, 27, 6, + 17, 6, -7, 6, -25, 7, -29, 6, 9, 7, 7, 6, 13, 6, -25, 6, + -19, 6, 13, 6, -11, 6, 5, 8, 19, 6, -21, 8, 23, 7, 27, 6, + -13, 6, -19, 11, 29, 7, -15, 6, -9, 7, -21, 10, -3, 7, 21, 10, + 25, 6, -15, 6, -23, 6, 21, 6, 1, 6, 21, 7, -3, 6, -3, 7, + -7, 6, -23, 7, 7, 8, 15, 9, 5, 6, -11, 6, 21, 11, -27, 7, + 27, 6, -11, 6, 31, 6, -21, 6, 19, 6, -7, 8, -7, 13, -3, 6, + -7, 7, -3, 6, 1, 6, 7, 8, 19, 8, 11, 9, -9, 7, -31, 12, + 25, 6, -17, 9, -15, 7, 5, 6, 25, 7, -5, 7, -25, 6, 17, 8, + -19, 6, -13, 6, 27, 8, 1, 7, -5, 7, -1, 6, 21, 6, 3, 10, + -3, 1, +}; + +/* + * Generate table for pairing. + * + * Calculate the graident (l) and constant (c) at each step of the way. + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * + * pm [in] Point to generate table for. + * table [in] Generated table. + * len [in,out] On in, the size of the buffer. + * On out, length of table generated. + * @return 0 on success. + * LENGTH_ONLY_E when table is NULL and only length returned. + * BUFFER_E when len is too small. + * MEMORY_E when dynamic memory allocation fauls. + */ +int sp_Pairing_gen_precomp_1024(const ecc_point* pm, byte* table, + word32* len) +{ + int err = 0; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_point_1024* pre_p; +#else + sp_digit t[6 * 2 * 16]; + sp_point_1024 pre_p[16]; + sp_point_1024 pd; + sp_point_1024 cd; + sp_point_1024 negd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* c = NULL; + sp_point_1024* neg = NULL; + int i; + int j; + int k; + sp_table_entry_1024* precomp = (sp_table_entry_1024*)table; + + if (table == NULL) { + *len = sizeof(sp_table_entry_1024) * 1167; + err = LENGTH_ONLY_E; + } + + if ((err == MP_OKAY) && + (*len < (int)(sizeof(sp_table_entry_1024) * 1167))) { + err = BUFFER_E; + } + + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, pd, p); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, cd, c); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, negd, neg); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6 * 16 * 2 + 16 * sizeof(sp_point_1024), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + pre_p = (sp_point_1024*)(td + 6 * 16 * 2); +#endif + + sp_1024_point_from_ecc_point_16(p, pm); + + err = sp_1024_mod_mul_norm_16(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(p->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + neg->infinity = 0; + c->infinity = 0; + + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMCPY(&pre_p[0], p, sizeof(sp_point_1024)); + /* [2]P for adding */ + sp_1024_proj_point_dbl_16(c, p, t); + + /* 1, 3, ... */ + for (i = 1; i < 16; i++) { + sp_1024_proj_point_add_16(&pre_p[i], &pre_p[i-1], c, t); + sp_1024_mont_map_16(&pre_p[i], t); + } + + k = 0; + j = sp_1024_order_op_pre[0] / 2; + XMEMCPY(c, &pre_p[j], sizeof(sp_point_1024)); + + for (j = 0; j < sp_1024_order_op_pre[1]; j++) { + sp_1024_accum_dbl_calc_lc_16(precomp[k].x, precomp[k].y, c->x, c->y, t); + k++; + sp_1024_proj_point_dbl_16(c, c, t); + sp_1024_mont_map_16(c, t); + } + + for (i = 2; i < 290; i += 2) { + j = sp_1024_order_op_pre[i]; + if (j > 0) { + sp_1024_accum_add_calc_lc_16(precomp[k].x, precomp[k].y, + pre_p[j/2].x, pre_p[j/2].y, c->x, c->y, t); + k++; + sp_1024_proj_point_add_16(c, c, &pre_p[j/2], t); + sp_1024_mont_map_16(c, t); + } + else { + XMEMCPY(neg->x, pre_p[-j / 2].x, sizeof(pre_p->x)); + sp_1024_mont_sub_16(neg->y, p1024_mod, pre_p[-j / 2].y, + p1024_mod); + XMEMCPY(neg->z, pre_p[-j / 2].z, sizeof(pre_p->z)); + + sp_1024_accum_add_calc_lc_16(precomp[k].x, precomp[k].y, + neg->x, neg->y, c->x, c->y, t); + k++; + sp_1024_proj_point_add_16(c, c, neg, t); + sp_1024_mont_map_16(c, t); + } + + for (j = 0; j < sp_1024_order_op_pre[i + 1]; j++) { + sp_1024_accum_dbl_calc_lc_16(precomp[k].x, precomp[k].y, c->x, c->y, t); + k++; + sp_1024_proj_point_dbl_16(c, c, t); + sp_1024_mont_map_16(c, t); + } + } + + *len = sizeof(sp_table_entry_1024) * 1167; + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_16(neg, 1, NULL); + sp_1024_point_free_16(c, 1, NULL); + sp_1024_point_free_16(p, 1, NULL); + return err; +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * Pre-generate values in window (1, 3, ...) - only V. + * Table contains all gradient l and a constant for each point on the path. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @param [in] table Precomputed table of values. + * @param [in] len Length of precomputed table of values in bytes. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int sp_Pairing_precomp_1024(const ecc_point* pm, const ecc_point* qm, + mp_int* res, const byte* table, word32 len) +{ + int err = 0; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit (*pre_vx)[32]; + sp_digit (*pre_vy)[32]; + sp_digit (*pre_nvy)[32]; +#else + sp_digit t[6 * 2 * 16]; + sp_digit vx[2 * 16]; + sp_digit vy[2 * 16]; + sp_digit pre_vx[16][32]; + sp_digit pre_vy[16][32]; + sp_digit pre_nvy[16][32]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + int j; + int k; + const sp_table_entry_1024* precomp = (const sp_table_entry_1024*)table; + + if (len < (int)(sizeof(sp_table_entry_1024) * 1167)) { + err = BUFFER_E; + } + + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, pd, p); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 56 * 16 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 16 * 2; + vy = td + 7 * 16 * 2; + pre_vx = (sp_digit(*)[32])(td + 8 * 16 * 2); + pre_vy = (sp_digit(*)[32])(td + 24 * 16 * 2); + pre_nvy = (sp_digit(*)[32])(td + 40 * 16 * 2); +#endif + r = vy; + + sp_1024_point_from_ecc_point_16(p, pm); + sp_1024_point_from_ecc_point_16(q, qm); + + err = sp_1024_mod_mul_norm_16(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMSET(pre_vx[0], 0, sizeof(sp_digit) * 2 * 16); + pre_vx[0][0] = 1; + XMEMSET(pre_vy[0], 0, sizeof(sp_digit) * 2 * 16); + sp_1024_mont_sub_16(pre_nvy[0], p1024_mod, pre_vy[0], p1024_mod); + + /* [2]P for adding */ + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 16); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 16); + sp_1024_accumulate_line_dbl_16(vx, vy, c, q, t); + + /* 3, 5, ... */ + for (i = 1; i < 16; i++) { + XMEMCPY(pre_vx[i], pre_vx[i-1], sizeof(sp_digit) * 2 * 16); + XMEMCPY(pre_vy[i], pre_vy[i-1], sizeof(sp_digit) * 2 * 16); + sp_1024_proj_mul_16(pre_vx[i], pre_vy[i], vx, vy, t); + sp_1024_accumulate_line_add_n_16(pre_vx[i], pre_vy[i], c, + q, p, t, 0); + sp_1024_mont_sub_16(pre_nvy[i], p1024_mod, pre_vy[i], + p1024_mod); + } + + XMEMCPY(c->z, p1024_norm_mod, sizeof(sp_digit) * 16); + c->infinity = 0; + j = sp_1024_order_op_pre[0] / 2; + XMEMCPY(vx, pre_vx[j], sizeof(sp_digit) * 2 * 16); + XMEMCPY(vy, pre_vy[j], sizeof(sp_digit) * 2 * 16); + + k = 0; + for (j = 0; j < sp_1024_order_op_pre[1]; j++) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_lc_16(vx, vy, precomp[k].x, + precomp[k].y, q, t, 1); + k++; + } + + for (i = 2; i < 290; i += 2) { + sp_1024_accumulate_line_lc_16(vx, vy, precomp[k].x, + precomp[k].y, q, t, 0); + k++; + + j = sp_1024_order_op_pre[i]; + if (j > 0) { + j /= 2; + /* Accumulate line into v. */ + sp_1024_proj_mul_16(vx, vy, pre_vx[j], pre_vy[j], t); + } + else { + j = -j / 2; + /* Accumulate line into v. */ + sp_1024_proj_mul_16(vx, vy, pre_vx[j], pre_nvy[j], t); + } + + for (j = 0; j < sp_1024_order_op_pre[i + 1]; j++) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_lc_16(vx, vy, precomp[k].x, + precomp[k].y, q, t, 1); + k++; + } + } + + /* Final exponentiation */ + sp_1024_proj_sqr_16(vx, vy, t); + sp_1024_proj_sqr_16(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_16(vx, vx, t); + sp_1024_mont_mul_16(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 16, 0, sizeof(sp_digit) * 16); + sp_1024_mont_reduce_16(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_16(c, 1, NULL); + sp_1024_point_free_16(q, 1, NULL); + sp_1024_point_free_16(p, 1, NULL); + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Returns 1 if the number of zero. + * Implementation is constant time. + * + * a Number to check. + * returns 1 if the number is zero and 0 otherwise. + */ +static int sp_1024_iszero_16(const sp_digit* a) +{ + return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6] | a[7] | + a[8] | a[9] | a[10] | a[11] | a[12] | a[13] | a[14] | a[15]) == 0; +} + +#ifdef HAVE_ECC_CHECK_KEY +/* Read big endian unsigned byte array into r. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a Byte array. + * n Number of bytes in array to read. + */ +static void sp_1024_from_bin(sp_digit* r, int size, const byte* a, int n) +{ + int i; + int j; + byte* d; + + for (i = n - 1,j = 0; i >= 7; i -= 8) { + r[j] = ((sp_digit)a[i - 0] << 0) | + ((sp_digit)a[i - 1] << 8) | + ((sp_digit)a[i - 2] << 16) | + ((sp_digit)a[i - 3] << 24) | + ((sp_digit)a[i - 4] << 32) | + ((sp_digit)a[i - 5] << 40) | + ((sp_digit)a[i - 6] << 48) | + ((sp_digit)a[i - 7] << 56); + j++; + } + + if (i >= 0) { + r[j] = 0; + + d = (byte*)r; + switch (i) { + case 6: d[n - 1 - 6] = a[6]; //fallthrough + case 5: d[n - 1 - 5] = a[5]; //fallthrough + case 4: d[n - 1 - 4] = a[4]; //fallthrough + case 3: d[n - 1 - 3] = a[3]; //fallthrough + case 2: d[n - 1 - 2] = a[2]; //fallthrough + case 1: d[n - 1 - 1] = a[1]; //fallthrough + case 0: d[n - 1 - 0] = a[0]; //fallthrough + } + j++; + } + + for (; j < size; j++) { + r[j] = 0; + } +} + +/* Check that the x and y oridinates are a valid point on the curve. + * + * point EC point. + * heap Heap to use if dynamically allocating. + * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is + * not on the curve and MP_OKAY otherwise. + */ +static int sp_1024_ecc_is_point_16(const sp_point_1024* point, + void* heap) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* d = NULL; +#else + sp_digit t1d[2*16]; + sp_digit t2d[2*16]; +#endif + sp_digit* t1; + sp_digit* t2; + int64_t n; + int err = MP_OKAY; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 4, heap, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + (void)heap; + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t1 = d + 0 * 16; + t2 = d + 2 * 16; +#else + t1 = t1d; + t2 = t2d; +#endif + + sp_1024_sqr_16(t1, point->y); + (void)sp_1024_mod_16(t1, t1, p1024_mod); + sp_1024_sqr_16(t2, point->x); + (void)sp_1024_mod_16(t2, t2, p1024_mod); + sp_1024_mul_16(t2, t2, point->x); + (void)sp_1024_mod_16(t2, t2, p1024_mod); + (void)sp_1024_sub_16(t2, p1024_mod, t2); + sp_1024_mont_add_16(t1, t1, t2, p1024_mod); + + sp_1024_mont_add_16(t1, t1, point->x, p1024_mod); + sp_1024_mont_add_16(t1, t1, point->x, p1024_mod); + sp_1024_mont_add_16(t1, t1, point->x, p1024_mod); + + n = sp_1024_cmp_16(t1, p1024_mod); + sp_1024_cond_sub_16(t1, t1, p1024_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_16(t1); + if (!sp_1024_iszero_16(t1)) { + err = MP_VAL; + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (d != NULL) { + XFREE(d, heap, DYNAMIC_TYPE_ECC); + } +#endif + + return err; +} + +/* Check that the x and y oridinates are a valid point on the curve. + * + * pX X ordinate of EC point. + * pY Y ordinate of EC point. + * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is + * not on the curve and MP_OKAY otherwise. + */ +int sp_ecc_is_point_1024(const mp_int* pX, const mp_int* pY) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 pubd; +#endif + sp_point_1024* pub; + byte one[1] = { 1 }; + int err; + + err = sp_1024_point_new_16(NULL, pubd, pub); + if (err == MP_OKAY) { + sp_1024_from_mp(pub->x, 16, pX); + sp_1024_from_mp(pub->y, 16, pY); + sp_1024_from_bin(pub->z, 16, one, (int)sizeof(one)); + + err = sp_1024_ecc_is_point_16(pub, NULL); + } + + sp_1024_point_free_16(pub, 0, NULL); + + return err; +} + +/* Check that the private scalar generates the EC point (px, py), the point is + * on the curve and the point has the correct order. + * + * pX X ordinate of EC point. + * pY Y ordinate of EC point. + * privm Private scalar that generates EC point. + * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is + * not on the curve, ECC_INF_E if the point does not have the correct order, + * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and + * MP_OKAY otherwise. + */ +int sp_ecc_check_key_1024(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_digit privd[16]; + sp_point_1024 pubd; + sp_point_1024 pd; +#endif + sp_digit* priv = NULL; + sp_point_1024* pub; + sp_point_1024* p = NULL; + byte one[1] = { 1 }; + int err; + + err = sp_1024_point_new_16(heap, pubd, pub); + if (err == MP_OKAY) { + err = sp_1024_point_new_16(heap, pd, p); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY && privm) { + priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16, heap, + DYNAMIC_TYPE_ECC); + if (priv == NULL) { + err = MEMORY_E; + } + } +#endif + + /* Quick check the lengs of public key ordinates and private key are in + * range. Proper check later. + */ + if ((err == MP_OKAY) && ((mp_count_bits(pX) > 1024) || + (mp_count_bits(pY) > 1024) || + ((privm != NULL) && (mp_count_bits(privm) > 1024)))) { + err = ECC_OUT_OF_RANGE_E; + } + + if (err == MP_OKAY) { +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + priv = privd; +#endif + + sp_1024_from_mp(pub->x, 16, pX); + sp_1024_from_mp(pub->y, 16, pY); + sp_1024_from_bin(pub->z, 16, one, (int)sizeof(one)); + if (privm) + sp_1024_from_mp(priv, 16, privm); + + /* Check point at infinitiy. */ + if ((sp_1024_iszero_16(pub->x) != 0) && + (sp_1024_iszero_16(pub->y) != 0)) { + err = ECC_INF_E; + } + } + + /* Check range of X and Y */ + if ((err == MP_OKAY) && + ((sp_1024_cmp_16(pub->x, p1024_mod) >= 0) || + (sp_1024_cmp_16(pub->y, p1024_mod) >= 0))) { + err = ECC_OUT_OF_RANGE_E; + } + + if (err == MP_OKAY) { + /* Check point is on curve */ + err = sp_1024_ecc_is_point_16(pub, heap); + } + + if (err == MP_OKAY) { + /* Point * order = infinity */ + err = sp_1024_ecc_mulmod_16(p, pub, p1024_order, 1, 1, heap); + } + /* Check result is infinity */ + if ((err == MP_OKAY) && ((sp_1024_iszero_16(p->x) == 0) || + (sp_1024_iszero_16(p->y) == 0))) { + err = ECC_INF_E; + } + + if (privm) { + if (err == MP_OKAY) { + /* Base * private = point */ + err = sp_1024_ecc_mulmod_base_16(p, priv, 1, 1, heap); + } + /* Check result is public key */ + if ((err == MP_OKAY) && + ((sp_1024_cmp_16(p->x, pub->x) != 0) || + (sp_1024_cmp_16(p->y, pub->y) != 0))) { + err = ECC_PRIV_KEY_E; + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (priv != NULL) { + XFREE(priv, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_16(p, 0, heap); + sp_1024_point_free_16(pub, 0, heap); + + return err; +} +#endif +#endif /* WOLFSSL_SP_1024 */ #endif /* WOLFSSL_HAVE_SP_ECC */ #endif /* WOLFSSL_SP_ARM64_ASM */ -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH || WOLFSSL_HAVE_SP_ECC */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH | WOLFSSL_HAVE_SP_ECC */ diff --git a/wolfcrypt/src/sp_armthumb.c b/wolfcrypt/src/sp_armthumb.c index 42c44ad7c..a7e2ddd70 100644 --- a/wolfcrypt/src/sp_armthumb.c +++ b/wolfcrypt/src/sp_armthumb.c @@ -1,6 +1,6 @@ /* sp.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -58,7 +58,8 @@ */ static void sp_2048_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -100,7 +101,8 @@ static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 32 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -134,7 +136,9 @@ static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -173,7 +177,10 @@ static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a) */ static void sp_2048_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; j = 2048 / 8 - 1; a[j] = 0; @@ -716,7 +723,9 @@ SP_NOINLINE static void sp_2048_mul_16(sp_digit* r, const sp_digit* a, sp_digit a1[8]; sp_digit b1[8]; sp_digit z2[16]; - sp_digit u, ca, cb; + sp_digit u; + sp_digit ca; + sp_digit cb; ca = sp_2048_add_8(a1, a, &a[8]); cb = sp_2048_add_8(b1, b, &b[8]); @@ -1105,7 +1114,9 @@ SP_NOINLINE static void sp_2048_mul_32(sp_digit* r, const sp_digit* a, sp_digit a1[16]; sp_digit b1[16]; sp_digit z2[32]; - sp_digit u, ca, cb; + sp_digit u; + sp_digit ca; + sp_digit cb; ca = sp_2048_add_16(a1, a, &a[16]); cb = sp_2048_add_16(b1, b, &b[16]); @@ -1763,7 +1774,9 @@ SP_NOINLINE static void sp_2048_mul_64(sp_digit* r, const sp_digit* a, sp_digit a1[32]; sp_digit b1[32]; sp_digit z2[64]; - sp_digit u, ca, cb; + sp_digit u; + sp_digit ca; + sp_digit cb; ca = sp_2048_add_32(a1, a, &a[32]); cb = sp_2048_add_32(b1, b, &b[32]); @@ -2498,7 +2511,7 @@ SP_NOINLINE static void sp_2048_sqr_32(sp_digit* r, const sp_digit* a) } #endif /* WOLFSSL_SP_SMALL */ -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ /* Caclulate the bottom digit of -1/a mod 2^n. * @@ -2507,7 +2520,8 @@ SP_NOINLINE static void sp_2048_sqr_32(sp_digit* r, const sp_digit* a) */ static void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho) { - sp_digit x, b; + sp_digit x; + sp_digit b; b = a[0]; x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ @@ -2516,7 +2530,7 @@ static void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho) x *= 2 - b * x; /* here x*a==1 mod 2**32 */ /* rho = -1/m mod b */ - *rho = -x; + *rho = (sp_digit)0 - x; } /* Mul a by digit b into r. (r = a * b) @@ -2791,8 +2805,8 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_2048_mont_mul_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_2048_mul_32(r, a, b); sp_2048_mont_reduce_32(r, m, mp); @@ -2805,8 +2819,8 @@ static void sp_2048_mont_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_sqr_32(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_2048_mont_sqr_32(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_2048_sqr_32(r, a); sp_2048_mont_reduce_32(r, m, mp); @@ -3140,7 +3154,8 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -3206,34 +3221,34 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 32); for (; i>=0 || c>=4; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 28); + y = (byte)(n >> 28); n <<= 4; c = 28; } else if (c < 4) { - y = (int)(n >> 28); + y = (byte)(n >> 28); n = e[i--]; c = 4 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 28) & 0xf); + y = (byte)((n >> 28) & 0xf); n <<= 4; c -= 4; } @@ -3285,7 +3300,8 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -3367,34 +3383,34 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 32); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -3425,7 +3441,7 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, } #endif /* WOLFSSL_SP_SMALL */ -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) /* r = 2^n mod m where n is the number of bits to reduce by. @@ -3442,7 +3458,7 @@ static void sp_2048_mont_norm_64(sp_digit* r, const sp_digit* m) sp_2048_sub_in_place_64(r, m); } -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */ /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -3634,8 +3650,8 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_mul_64(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_2048_mont_mul_64(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_2048_mul_64(r, a, b); sp_2048_mont_reduce_64(r, m, mp); @@ -3648,8 +3664,8 @@ static void sp_2048_mont_mul_64(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_sqr_64(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_2048_mont_sqr_64(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_2048_sqr_64(r, a); sp_2048_mont_reduce_64(r, m, mp); @@ -4000,7 +4016,8 @@ static int sp_2048_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -4066,34 +4083,34 @@ static int sp_2048_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 64); for (; i>=0 || c>=4; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 28); + y = (byte)(n >> 28); n <<= 4; c = 28; } else if (c < 4) { - y = (int)(n >> 28); + y = (byte)(n >> 28); n = e[i--]; c = 4 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 28) & 0xf); + y = (byte)((n >> 28) & 0xf); n <<= 4; c -= 4; } @@ -4145,7 +4162,8 @@ static int sp_2048_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -4227,34 +4245,34 @@ static int sp_2048_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 64); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -4299,11 +4317,13 @@ static int sp_2048_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPublic_2048(const byte* in, word32 inLen, const mp_int* em, + const mp_int* mm, byte* out, word32* outLen) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_digit a[128], m[64], r[128]; + sp_digit a[128]; + sp_digit m[64]; + sp_digit r[128]; #else sp_digit* d = NULL; sp_digit* a = NULL; @@ -4479,9 +4499,9 @@ SP_NOINLINE static sp_digit sp_2048_cond_add_32(sp_digit* r, const sp_digit* a, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_2048(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM) sp_digit* a = NULL; @@ -4545,8 +4565,11 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, #else #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit a[64 * 2]; - sp_digit p[32], q[32], dp[32]; - sp_digit tmpa[64], tmpb[64]; + sp_digit p[32]; + sp_digit q[32]; + sp_digit dp[32]; + sp_digit tmpa[64]; + sp_digit tmpb[64]; #else sp_digit* t = NULL; sp_digit* a = NULL; @@ -4643,7 +4666,7 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, XMEMSET(q, 0, sizeof(q)); XMEMSET(dp, 0, sizeof(dp)); #endif -#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */ +#endif /* SP_RSA_PRIVATE_EXP_D | RSA_LOW_MEM */ return err; } #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -4666,17 +4689,19 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->used = 64; mp_clamp(r); #elif DIGIT_BIT < 32 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 64; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -4689,14 +4714,16 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 64; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 32 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -4723,10 +4750,13 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_2048(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[128], e[64], m[64]; + sp_digit b[128]; + sp_digit e[64]; + sp_digit m[64]; sp_digit* r = b; int expBits = mp_count_bits(exp); @@ -5185,10 +5215,12 @@ static int sp_2048_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits, sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -5223,34 +5255,34 @@ static int sp_2048_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } - sp_2048_lshift_64(r, norm, (byte)y); + sp_2048_lshift_64(r, norm, y); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -5261,7 +5293,7 @@ static int sp_2048_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits, sp_2048_mont_sqr_64(r, r, m, mp); sp_2048_mont_sqr_64(r, r, m, mp); - sp_2048_lshift_64(r, r, (byte)y); + sp_2048_lshift_64(r, r, y); sp_2048_mul_d_64(tmp, norm, r[64]); r[64] = 0; o = sp_2048_add_64(r, r, tmp); @@ -5297,11 +5329,13 @@ static int sp_2048_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, - mp_int* mod, byte* out, word32* outLen) +int sp_DhExp_2048(const mp_int* base, const byte* exp, word32 expLen, + const mp_int* mod, byte* out, word32* outLen) { int err = MP_OKAY; - sp_digit b[128], e[64], m[64]; + sp_digit b[128]; + sp_digit e[64]; + sp_digit m[64]; sp_digit* r = b; word32 i; @@ -5336,6 +5370,7 @@ int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, sp_2048_to_bin(r, out); *outLen = 256; for (i=0; i<256 && out[i] == 0; i++) { + /* Search for first non-zero. */ } *outLen -= i; XMEMMOVE(out, out + i, *outLen); @@ -5357,10 +5392,13 @@ int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_1024(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[64], e[32], m[32]; + sp_digit b[64]; + sp_digit e[32]; + sp_digit m[32]; sp_digit* r = b; int expBits = mp_count_bits(exp); @@ -5397,7 +5435,7 @@ int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) return err; } -#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */ +#endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */ #endif /* !WOLFSSL_SP_NO_2048 */ @@ -5411,7 +5449,8 @@ int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) */ static void sp_3072_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -5453,7 +5492,8 @@ static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 32 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -5487,7 +5527,9 @@ static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -5526,7 +5568,10 @@ static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a) */ static void sp_3072_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; j = 3072 / 8 - 1; a[j] = 0; @@ -6153,7 +6198,9 @@ SP_NOINLINE static void sp_3072_mul_24(sp_digit* r, const sp_digit* a, sp_digit a1[12]; sp_digit b1[12]; sp_digit z2[24]; - sp_digit u, ca, cb; + sp_digit u; + sp_digit ca; + sp_digit cb; ca = sp_3072_add_12(a1, a, &a[12]); cb = sp_3072_add_12(b1, b, &b[12]); @@ -6683,7 +6730,9 @@ SP_NOINLINE static void sp_3072_mul_48(sp_digit* r, const sp_digit* a, sp_digit a1[24]; sp_digit b1[24]; sp_digit z2[48]; - sp_digit u, ca, cb; + sp_digit u; + sp_digit ca; + sp_digit cb; ca = sp_3072_add_24(a1, a, &a[24]); cb = sp_3072_add_24(b1, b, &b[24]); @@ -7608,7 +7657,9 @@ SP_NOINLINE static void sp_3072_mul_96(sp_digit* r, const sp_digit* a, sp_digit a1[48]; sp_digit b1[48]; sp_digit z2[96]; - sp_digit u, ca, cb; + sp_digit u; + sp_digit ca; + sp_digit cb; ca = sp_3072_add_48(a1, a, &a[48]); cb = sp_3072_add_48(b1, b, &b[48]); @@ -8359,7 +8410,7 @@ SP_NOINLINE static void sp_3072_sqr_48(sp_digit* r, const sp_digit* a) } #endif /* WOLFSSL_SP_SMALL */ -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ /* Caclulate the bottom digit of -1/a mod 2^n. * @@ -8368,7 +8419,8 @@ SP_NOINLINE static void sp_3072_sqr_48(sp_digit* r, const sp_digit* a) */ static void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho) { - sp_digit x, b; + sp_digit x; + sp_digit b; b = a[0]; x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ @@ -8377,7 +8429,7 @@ static void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho) x *= 2 - b * x; /* here x*a==1 mod 2**32 */ /* rho = -1/m mod b */ - *rho = -x; + *rho = (sp_digit)0 - x; } /* Mul a by digit b into r. (r = a * b) @@ -8653,8 +8705,8 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_mul_48(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_3072_mont_mul_48(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_3072_mul_48(r, a, b); sp_3072_mont_reduce_48(r, m, mp); @@ -8667,8 +8719,8 @@ static void sp_3072_mont_mul_48(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_sqr_48(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_3072_mont_sqr_48(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_3072_sqr_48(r, a); sp_3072_mont_reduce_48(r, m, mp); @@ -9002,7 +9054,8 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -9068,34 +9121,34 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 48); for (; i>=0 || c>=4; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 28); + y = (byte)(n >> 28); n <<= 4; c = 28; } else if (c < 4) { - y = (int)(n >> 28); + y = (byte)(n >> 28); n = e[i--]; c = 4 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 28) & 0xf); + y = (byte)((n >> 28) & 0xf); n <<= 4; c -= 4; } @@ -9147,7 +9200,8 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -9229,34 +9283,34 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 48); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -9287,7 +9341,7 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, } #endif /* WOLFSSL_SP_SMALL */ -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) /* r = 2^n mod m where n is the number of bits to reduce by. @@ -9304,7 +9358,7 @@ static void sp_3072_mont_norm_96(sp_digit* r, const sp_digit* m) sp_3072_sub_in_place_96(r, m); } -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */ /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -9500,8 +9554,8 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_mul_96(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_3072_mont_mul_96(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_3072_mul_96(r, a, b); sp_3072_mont_reduce_96(r, m, mp); @@ -9514,8 +9568,8 @@ static void sp_3072_mont_mul_96(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_sqr_96(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_3072_mont_sqr_96(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_3072_sqr_96(r, a); sp_3072_mont_reduce_96(r, m, mp); @@ -9868,7 +9922,8 @@ static int sp_3072_mod_exp_96(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -9934,34 +9989,34 @@ static int sp_3072_mod_exp_96(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 96); for (; i>=0 || c>=4; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 28); + y = (byte)(n >> 28); n <<= 4; c = 28; } else if (c < 4) { - y = (int)(n >> 28); + y = (byte)(n >> 28); n = e[i--]; c = 4 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 28) & 0xf); + y = (byte)((n >> 28) & 0xf); n <<= 4; c -= 4; } @@ -10013,7 +10068,8 @@ static int sp_3072_mod_exp_96(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -10095,34 +10151,34 @@ static int sp_3072_mod_exp_96(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 96); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -10167,11 +10223,13 @@ static int sp_3072_mod_exp_96(sp_digit* r, const sp_digit* a, const sp_digit* e, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPublic_3072(const byte* in, word32 inLen, const mp_int* em, + const mp_int* mm, byte* out, word32* outLen) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_digit a[192], m[96], r[192]; + sp_digit a[192]; + sp_digit m[96]; + sp_digit r[192]; #else sp_digit* d = NULL; sp_digit* a = NULL; @@ -10347,9 +10405,9 @@ SP_NOINLINE static sp_digit sp_3072_cond_add_48(sp_digit* r, const sp_digit* a, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_3072(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM) sp_digit* a = NULL; @@ -10413,8 +10471,11 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, #else #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit a[96 * 2]; - sp_digit p[48], q[48], dp[48]; - sp_digit tmpa[96], tmpb[96]; + sp_digit p[48]; + sp_digit q[48]; + sp_digit dp[48]; + sp_digit tmpa[96]; + sp_digit tmpb[96]; #else sp_digit* t = NULL; sp_digit* a = NULL; @@ -10511,7 +10572,7 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, XMEMSET(q, 0, sizeof(q)); XMEMSET(dp, 0, sizeof(dp)); #endif -#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */ +#endif /* SP_RSA_PRIVATE_EXP_D | RSA_LOW_MEM */ return err; } #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -10534,17 +10595,19 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->used = 96; mp_clamp(r); #elif DIGIT_BIT < 32 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 96; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -10557,14 +10620,16 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 96; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 32 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -10591,10 +10656,13 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_3072(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[192], e[96], m[96]; + sp_digit b[192]; + sp_digit e[96]; + sp_digit m[96]; sp_digit* r = b; int expBits = mp_count_bits(exp); @@ -11251,10 +11319,12 @@ static int sp_3072_mod_exp_2_96(sp_digit* r, const sp_digit* e, int bits, sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -11289,34 +11359,34 @@ static int sp_3072_mod_exp_2_96(sp_digit* r, const sp_digit* e, int bits, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } - sp_3072_lshift_96(r, norm, (byte)y); + sp_3072_lshift_96(r, norm, y); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -11327,7 +11397,7 @@ static int sp_3072_mod_exp_2_96(sp_digit* r, const sp_digit* e, int bits, sp_3072_mont_sqr_96(r, r, m, mp); sp_3072_mont_sqr_96(r, r, m, mp); - sp_3072_lshift_96(r, r, (byte)y); + sp_3072_lshift_96(r, r, y); sp_3072_mul_d_96(tmp, norm, r[96]); r[96] = 0; o = sp_3072_add_96(r, r, tmp); @@ -11363,11 +11433,13 @@ static int sp_3072_mod_exp_2_96(sp_digit* r, const sp_digit* e, int bits, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, - mp_int* mod, byte* out, word32* outLen) +int sp_DhExp_3072(const mp_int* base, const byte* exp, word32 expLen, + const mp_int* mod, byte* out, word32* outLen) { int err = MP_OKAY; - sp_digit b[192], e[96], m[96]; + sp_digit b[192]; + sp_digit e[96]; + sp_digit m[96]; sp_digit* r = b; word32 i; @@ -11402,6 +11474,7 @@ int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, sp_3072_to_bin(r, out); *outLen = 384; for (i=0; i<384 && out[i] == 0; i++) { + /* Search for first non-zero. */ } *outLen -= i; XMEMMOVE(out, out + i, *outLen); @@ -11423,10 +11496,13 @@ int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_1536(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[96], e[48], m[48]; + sp_digit b[96]; + sp_digit e[48]; + sp_digit m[48]; sp_digit* r = b; int expBits = mp_count_bits(exp); @@ -11463,7 +11539,7 @@ int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) return err; } -#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */ +#endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */ #endif /* !WOLFSSL_SP_NO_3072 */ @@ -11477,7 +11553,8 @@ int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) */ static void sp_4096_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -11519,7 +11596,8 @@ static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 32 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -11553,7 +11631,9 @@ static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -11592,7 +11672,10 @@ static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a) */ static void sp_4096_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; j = 4096 / 8 - 1; a[j] = 0; @@ -12738,7 +12821,9 @@ SP_NOINLINE static void sp_4096_mul_128(sp_digit* r, const sp_digit* a, sp_digit a1[64]; sp_digit b1[64]; sp_digit z2[128]; - sp_digit u, ca, cb; + sp_digit u; + sp_digit ca; + sp_digit cb; ca = sp_2048_add_64(a1, a, &a[64]); cb = sp_2048_add_64(b1, b, &b[64]); @@ -13137,7 +13222,8 @@ SP_NOINLINE static void sp_4096_sqr_128(sp_digit* r, const sp_digit* a) */ static void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho) { - sp_digit x, b; + sp_digit x; + sp_digit b; b = a[0]; x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ @@ -13146,7 +13232,7 @@ static void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho) x *= 2 - b * x; /* here x*a==1 mod 2**32 */ /* rho = -1/m mod b */ - *rho = -x; + *rho = (sp_digit)0 - x; } /* Mul a by digit b into r. (r = a * b) @@ -13232,7 +13318,7 @@ static void sp_4096_mont_norm_128(sp_digit* r, const sp_digit* m) sp_4096_sub_in_place_128(r, m); } -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */ /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -13426,8 +13512,8 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_4096_mont_mul_128(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_4096_mont_mul_128(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_4096_mul_128(r, a, b); sp_4096_mont_reduce_128(r, m, mp); @@ -13440,8 +13526,8 @@ static void sp_4096_mont_mul_128(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_4096_mont_sqr_128(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_4096_mont_sqr_128(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_4096_sqr_128(r, a); sp_4096_mont_reduce_128(r, m, mp); @@ -13794,7 +13880,8 @@ static int sp_4096_mod_exp_128(sp_digit* r, const sp_digit* a, const sp_digit* e sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -13860,34 +13947,34 @@ static int sp_4096_mod_exp_128(sp_digit* r, const sp_digit* a, const sp_digit* e if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 128); for (; i>=0 || c>=4; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 28); + y = (byte)(n >> 28); n <<= 4; c = 28; } else if (c < 4) { - y = (int)(n >> 28); + y = (byte)(n >> 28); n = e[i--]; c = 4 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 28) & 0xf); + y = (byte)((n >> 28) & 0xf); n <<= 4; c -= 4; } @@ -13939,7 +14026,8 @@ static int sp_4096_mod_exp_128(sp_digit* r, const sp_digit* a, const sp_digit* e sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -14021,34 +14109,34 @@ static int sp_4096_mod_exp_128(sp_digit* r, const sp_digit* a, const sp_digit* e if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 128); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -14093,11 +14181,13 @@ static int sp_4096_mod_exp_128(sp_digit* r, const sp_digit* a, const sp_digit* e * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPublic_4096(const byte* in, word32 inLen, const mp_int* em, + const mp_int* mm, byte* out, word32* outLen) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_digit a[256], m[128], r[256]; + sp_digit a[256]; + sp_digit m[128]; + sp_digit r[256]; #else sp_digit* d = NULL; sp_digit* a = NULL; @@ -14274,9 +14364,9 @@ SP_NOINLINE static sp_digit sp_4096_cond_add_64(sp_digit* r, const sp_digit* a, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_4096(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM) sp_digit* a = NULL; @@ -14340,8 +14430,11 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, #else #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit a[128 * 2]; - sp_digit p[64], q[64], dp[64]; - sp_digit tmpa[128], tmpb[128]; + sp_digit p[64]; + sp_digit q[64]; + sp_digit dp[64]; + sp_digit tmpa[128]; + sp_digit tmpb[128]; #else sp_digit* t = NULL; sp_digit* a = NULL; @@ -14438,7 +14531,7 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, XMEMSET(q, 0, sizeof(q)); XMEMSET(dp, 0, sizeof(dp)); #endif -#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */ +#endif /* SP_RSA_PRIVATE_EXP_D | RSA_LOW_MEM */ return err; } #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -14461,17 +14554,19 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->used = 128; mp_clamp(r); #elif DIGIT_BIT < 32 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 128; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -14484,14 +14579,16 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 128; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 32 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -14518,10 +14615,13 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_4096(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[256], e[128], m[128]; + sp_digit b[256]; + sp_digit e[128]; + sp_digit m[128]; sp_digit* r = b; int expBits = mp_count_bits(exp); @@ -15374,10 +15474,12 @@ static int sp_4096_mod_exp_2_128(sp_digit* r, const sp_digit* e, int bits, sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -15412,34 +15514,34 @@ static int sp_4096_mod_exp_2_128(sp_digit* r, const sp_digit* e, int bits, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } - sp_4096_lshift_128(r, norm, (byte)y); + sp_4096_lshift_128(r, norm, y); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -15450,7 +15552,7 @@ static int sp_4096_mod_exp_2_128(sp_digit* r, const sp_digit* e, int bits, sp_4096_mont_sqr_128(r, r, m, mp); sp_4096_mont_sqr_128(r, r, m, mp); - sp_4096_lshift_128(r, r, (byte)y); + sp_4096_lshift_128(r, r, y); sp_4096_mul_d_128(tmp, norm, r[128]); r[128] = 0; o = sp_4096_add_128(r, r, tmp); @@ -15486,11 +15588,13 @@ static int sp_4096_mod_exp_2_128(sp_digit* r, const sp_digit* e, int bits, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, - mp_int* mod, byte* out, word32* outLen) +int sp_DhExp_4096(const mp_int* base, const byte* exp, word32 expLen, + const mp_int* mod, byte* out, word32* outLen) { int err = MP_OKAY; - sp_digit b[256], e[128], m[128]; + sp_digit b[256]; + sp_digit e[128]; + sp_digit m[128]; sp_digit* r = b; word32 i; @@ -15525,6 +15629,7 @@ int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, sp_4096_to_bin(r, out); *outLen = 512; for (i=0; i<512 && out[i] == 0; i++) { + /* Search for first non-zero. */ } *outLen -= i; XMEMMOVE(out, out + i, *outLen); @@ -15537,19 +15642,23 @@ int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, } #endif /* WOLFSSL_HAVE_SP_DH */ -#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */ +#endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */ #endif /* WOLFSSL_SP_4096 */ -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */ #ifdef WOLFSSL_HAVE_SP_ECC #ifndef WOLFSSL_SP_NO_256 /* Point structure to use. */ typedef struct sp_point_256 { + /* X ordinate of point. */ sp_digit x[2 * 8]; + /* Y ordinate of point. */ sp_digit y[2 * 8]; + /* Z ordinate of point. */ sp_digit z[2 * 8]; + /* Indicates point is at infinity. */ int infinity; } sp_point_256; @@ -15619,305 +15728,6 @@ static const sp_digit p256_b[8] = { }; #endif -static int sp_256_point_new_ex_8(void* heap, sp_point_256* sp, sp_point_256** p) -{ - int ret = MP_OKAY; - (void)heap; -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - (void)sp; - *p = (sp_point_256*)XMALLOC(sizeof(sp_point_256), heap, DYNAMIC_TYPE_ECC); -#else - *p = sp; -#endif - if (*p == NULL) { - ret = MEMORY_E; - } - return ret; -} - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) -/* Allocate memory for point and return error. */ -#define sp_256_point_new_8(heap, sp, p) sp_256_point_new_ex_8((heap), NULL, &(p)) -#else -/* Set pointer to data and return no error. */ -#define sp_256_point_new_8(heap, sp, p) sp_256_point_new_ex_8((heap), &(sp), &(p)) -#endif - - -static void sp_256_point_free_8(sp_point_256* p, int clear, void* heap) -{ -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) -/* If valid pointer then clear point data if requested and free data. */ - if (p != NULL) { - if (clear != 0) { - XMEMSET(p, 0, sizeof(*p)); - } - XFREE(p, heap, DYNAMIC_TYPE_ECC); - } -#else -/* Clear point data if requested. */ - if (clear != 0) { - XMEMSET(p, 0, sizeof(*p)); - } -#endif - (void)heap; -} - -/* Multiply a number by Montogmery normalizer mod modulus (prime). - * - * r The resulting Montgomery form number. - * a The number to convert. - * m The modulus (prime). - */ -static int sp_256_mod_mul_norm_8(sp_digit* r, const sp_digit* a, const sp_digit* m) -{ - int64_t t[8]; - int64_t a64[8]; - int64_t o; - - (void)m; - - a64[0] = a[0]; - a64[1] = a[1]; - a64[2] = a[2]; - a64[3] = a[3]; - a64[4] = a[4]; - a64[5] = a[5]; - a64[6] = a[6]; - a64[7] = a[7]; - - /* 1 1 0 -1 -1 -1 -1 0 */ - t[0] = 0 + a64[0] + a64[1] - a64[3] - a64[4] - a64[5] - a64[6]; - /* 0 1 1 0 -1 -1 -1 -1 */ - t[1] = 0 + a64[1] + a64[2] - a64[4] - a64[5] - a64[6] - a64[7]; - /* 0 0 1 1 0 -1 -1 -1 */ - t[2] = 0 + a64[2] + a64[3] - a64[5] - a64[6] - a64[7]; - /* -1 -1 0 2 2 1 0 -1 */ - t[3] = 0 - a64[0] - a64[1] + 2 * a64[3] + 2 * a64[4] + a64[5] - a64[7]; - /* 0 -1 -1 0 2 2 1 0 */ - t[4] = 0 - a64[1] - a64[2] + 2 * a64[4] + 2 * a64[5] + a64[6]; - /* 0 0 -1 -1 0 2 2 1 */ - t[5] = 0 - a64[2] - a64[3] + 2 * a64[5] + 2 * a64[6] + a64[7]; - /* -1 -1 0 0 0 1 3 2 */ - t[6] = 0 - a64[0] - a64[1] + a64[5] + 3 * a64[6] + 2 * a64[7]; - /* 1 0 -1 -1 -1 -1 0 3 */ - t[7] = 0 + a64[0] - a64[2] - a64[3] - a64[4] - a64[5] + 3 * a64[7]; - - t[1] += t[0] >> 32; t[0] &= 0xffffffff; - t[2] += t[1] >> 32; t[1] &= 0xffffffff; - t[3] += t[2] >> 32; t[2] &= 0xffffffff; - t[4] += t[3] >> 32; t[3] &= 0xffffffff; - t[5] += t[4] >> 32; t[4] &= 0xffffffff; - t[6] += t[5] >> 32; t[5] &= 0xffffffff; - t[7] += t[6] >> 32; t[6] &= 0xffffffff; - o = t[7] >> 32; t[7] &= 0xffffffff; - t[0] += o; - t[3] -= o; - t[6] -= o; - t[7] += o; - t[1] += t[0] >> 32; t[0] &= 0xffffffff; - t[2] += t[1] >> 32; t[1] &= 0xffffffff; - t[3] += t[2] >> 32; t[2] &= 0xffffffff; - t[4] += t[3] >> 32; t[3] &= 0xffffffff; - t[5] += t[4] >> 32; t[4] &= 0xffffffff; - t[6] += t[5] >> 32; t[5] &= 0xffffffff; - t[7] += t[6] >> 32; t[6] &= 0xffffffff; - r[0] = t[0]; - r[1] = t[1]; - r[2] = t[2]; - r[3] = t[3]; - r[4] = t[4]; - r[5] = t[5]; - r[6] = t[6]; - r[7] = t[7]; - - return MP_OKAY; -} - -/* Convert an mp_int to an array of sp_digit. - * - * r A single precision integer. - * size Maximum number of bytes to convert - * a A multi-precision integer. - */ -static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) -{ -#if DIGIT_BIT == 32 - int j; - - XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); - - for (j = a->used; j < size; j++) { - r[j] = 0; - } -#elif DIGIT_BIT > 32 - int i, j = 0; - word32 s = 0; - - r[0] = 0; - for (i = 0; i < a->used && j < size; i++) { - r[j] |= ((sp_digit)a->dp[i] << s); - r[j] &= 0xffffffff; - s = 32U - s; - if (j + 1 >= size) { - break; - } - /* lint allow cast of mismatch word32 and mp_digit */ - r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ - while ((s + 32U) <= (word32)DIGIT_BIT) { - s += 32U; - r[j] &= 0xffffffff; - if (j + 1 >= size) { - break; - } - if (s < (word32)DIGIT_BIT) { - /* lint allow cast of mismatch word32 and mp_digit */ - r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ - } - else { - r[++j] = 0L; - } - } - s = (word32)DIGIT_BIT - s; - } - - for (j++; j < size; j++) { - r[j] = 0; - } -#else - int i, j = 0, s = 0; - - r[0] = 0; - for (i = 0; i < a->used && j < size; i++) { - r[j] |= ((sp_digit)a->dp[i]) << s; - if (s + DIGIT_BIT >= 32) { - r[j] &= 0xffffffff; - if (j + 1 >= size) { - break; - } - s = 32 - s; - if (s == DIGIT_BIT) { - r[++j] = 0; - s = 0; - } - else { - r[++j] = a->dp[i] >> s; - s = DIGIT_BIT - s; - } - } - else { - s += DIGIT_BIT; - } - } - - for (j++; j < size; j++) { - r[j] = 0; - } -#endif -} - -/* Convert a point of type ecc_point to type sp_point_256. - * - * p Point of type sp_point_256 (result). - * pm Point of type ecc_point. - */ -static void sp_256_point_from_ecc_point_8(sp_point_256* p, const ecc_point* pm) -{ - XMEMSET(p->x, 0, sizeof(p->x)); - XMEMSET(p->y, 0, sizeof(p->y)); - XMEMSET(p->z, 0, sizeof(p->z)); - sp_256_from_mp(p->x, 8, pm->x); - sp_256_from_mp(p->y, 8, pm->y); - sp_256_from_mp(p->z, 8, pm->z); - p->infinity = 0; -} - -/* Convert an array of sp_digit to an mp_int. - * - * a A single precision integer. - * r A multi-precision integer. - */ -static int sp_256_to_mp(const sp_digit* a, mp_int* r) -{ - int err; - - err = mp_grow(r, (256 + DIGIT_BIT - 1) / DIGIT_BIT); - if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ -#if DIGIT_BIT == 32 - XMEMCPY(r->dp, a, sizeof(sp_digit) * 8); - r->used = 8; - mp_clamp(r); -#elif DIGIT_BIT < 32 - int i, j = 0, s = 0; - - r->dp[0] = 0; - for (i = 0; i < 8; i++) { - r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; - s = DIGIT_BIT - s; - r->dp[++j] = (mp_digit)(a[i] >> s); - while (s + DIGIT_BIT <= 32) { - s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; - if (s == SP_WORD_SIZE) { - r->dp[j] = 0; - } - else { - r->dp[j] = (mp_digit)(a[i] >> s); - } - } - s = 32 - s; - } - r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT; - mp_clamp(r); -#else - int i, j = 0, s = 0; - - r->dp[0] = 0; - for (i = 0; i < 8; i++) { - r->dp[j] |= ((mp_digit)a[i]) << s; - if (s + 32 >= DIGIT_BIT) { - #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; - #endif - s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; - s = 32 - s; - } - else { - s += 32; - } - } - r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT; - mp_clamp(r); -#endif - } - - return err; -} - -/* Convert a point of type sp_point_256 to type ecc_point. - * - * p Point of type sp_point_256. - * pm Point of type ecc_point (result). - * returns MEMORY_E when allocation of memory in ecc_point fails otherwise - * MP_OKAY. - */ -static int sp_256_point_to_ecc_point_8(const sp_point_256* p, ecc_point* pm) -{ - int err; - - err = sp_256_to_mp(p->x, pm->x); - if (err == MP_OKAY) { - err = sp_256_to_mp(p->y, pm->y); - } - if (err == MP_OKAY) { - err = sp_256_to_mp(p->z, pm->z); - } - - return err; -} - /* Multiply a and b into r. (r = a * b) * * r A single precision integer. @@ -16018,6 +15828,660 @@ SP_NOINLINE static void sp_256_mul_8(sp_digit* r, const sp_digit* a, XMEMCPY(r, tmp, sizeof(tmp)); } +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_256_sqr_8(sp_digit* r, const sp_digit* a) +{ + __asm__ __volatile__ ( + "mov r3, #0\n\t" + "mov r4, #0\n\t" + "mov r5, #0\n\t" + "mov r8, r3\n\t" + "mov r11, %[r]\n\t" + "mov r6, #64\n\t" + "neg r6, r6\n\t" + "add sp, r6\n\t" + "mov r10, sp\n\t" + "mov r9, %[a]\n\t" + "\n1:\n\t" + "mov %[r], #0\n\t" + "mov r6, #28\n\t" + "mov %[a], r8\n\t" + "sub %[a], r6\n\t" + "sbc r6, r6\n\t" + "mvn r6, r6\n\t" + "and %[a], r6\n\t" + "mov r2, r8\n\t" + "sub r2, %[a]\n\t" + "add %[a], r9\n\t" + "add r2, r9\n\t" + "\n2:\n\t" + "cmp r2, %[a]\n\t" + "beq 4f\n\t" + "# Multiply * 2: Start\n\t" + "ldr r6, [%[a]]\n\t" + "ldr r7, [r2]\n\t" + "lsl r6, r6, #16\n\t" + "lsl r7, r7, #16\n\t" + "lsr r6, r6, #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r7, r6\n\t" + "add r3, r7\n\t" + "adc r4, %[r]\n\t" + "adc r5, %[r]\n\t" + "add r3, r7\n\t" + "adc r4, %[r]\n\t" + "adc r5, %[r]\n\t" + "ldr r7, [r2]\n\t" + "lsr r7, r7, #16\n\t" + "mul r6, r7\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "ldr r6, [%[a]]\n\t" + "ldr r7, [r2]\n\t" + "lsr r6, r6, #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r7, r6\n\t" + "add r4, r7\n\t" + "adc r5, %[r]\n\t" + "add r4, r7\n\t" + "adc r5, %[r]\n\t" + "ldr r7, [r2]\n\t" + "lsl r7, r7, #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r6, r7\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "# Multiply * 2: Done\n\t" + "bal 5f\n\t" + "\n4:\n\t" + "# Square: Start\n\t" + "ldr r6, [%[a]]\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "lsr r6, r6, #16\n\t" + "mul r6, r6\n\t" + "add r3, r6\n\t" + "adc r4, %[r]\n\t" + "adc r5, %[r]\n\t" + "mul r7, r7\n\t" + "add r4, r7\n\t" + "adc r5, %[r]\n\t" + "ldr r6, [%[a]]\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "lsr r6, r6, #16\n\t" + "mul r6, r7\n\t" + "lsr r7, r6, #15\n\t" + "lsl r6, r6, #17\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "# Square: Done\n\t" + "\n5:\n\t" + "add %[a], #4\n\t" + "sub r2, #4\n\t" + "mov r6, #32\n\t" + "add r6, r9\n\t" + "cmp %[a], r6\n\t" + "beq 3f\n\t" + "cmp %[a], r2\n\t" + "bgt 3f\n\t" + "mov r7, r8\n\t" + "add r7, r9\n\t" + "cmp %[a], r7\n\t" + "ble 2b\n\t" + "\n3:\n\t" + "mov %[r], r10\n\t" + "mov r7, r8\n\t" + "str r3, [%[r], r7]\n\t" + "mov r3, r4\n\t" + "mov r4, r5\n\t" + "mov r5, #0\n\t" + "add r7, #4\n\t" + "mov r8, r7\n\t" + "mov r6, #56\n\t" + "cmp r7, r6\n\t" + "ble 1b\n\t" + "mov %[a], r9\n\t" + "str r3, [%[r], r7]\n\t" + "mov %[r], r11\n\t" + "mov %[a], r10\n\t" + "mov r3, #60\n\t" + "\n4:\n\t" + "ldr r6, [%[a], r3]\n\t" + "str r6, [%[r], r3]\n\t" + "sub r3, #4\n\t" + "bge 4b\n\t" + "mov r6, #64\n\t" + "add sp, r6\n\t" + : + : [r] "r" (r), [a] "r" (a) + : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" + ); +} + +#ifdef WOLFSSL_SP_SMALL +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r6, %[a]\n\t" + "mov r7, #0\n\t" + "add r6, #32\n\t" + "sub r7, #1\n\t" + "\n1:\n\t" + "add %[c], r7\n\t" + "ldr r4, [%[a]]\n\t" + "ldr r5, [%[b]]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r]]\n\t" + "mov %[c], #0\n\t" + "adc %[c], %[c]\n\t" + "add %[a], #4\n\t" + "add %[b], #4\n\t" + "add %[r], #4\n\t" + "cmp %[a], r6\n\t" + "bne 1b\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6", "r7" + ); + + return c; +} + +#else +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldr r4, [%[a], #0]\n\t" + "ldr r5, [%[b], #0]\n\t" + "add r4, r5\n\t" + "str r4, [%[r], #0]\n\t" + "ldr r4, [%[a], #4]\n\t" + "ldr r5, [%[b], #4]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #4]\n\t" + "ldr r4, [%[a], #8]\n\t" + "ldr r5, [%[b], #8]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #8]\n\t" + "ldr r4, [%[a], #12]\n\t" + "ldr r5, [%[b], #12]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #12]\n\t" + "ldr r4, [%[a], #16]\n\t" + "ldr r5, [%[b], #16]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #16]\n\t" + "ldr r4, [%[a], #20]\n\t" + "ldr r5, [%[b], #20]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #20]\n\t" + "ldr r4, [%[a], #24]\n\t" + "ldr r5, [%[b], #24]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #24]\n\t" + "ldr r4, [%[a], #28]\n\t" + "ldr r5, [%[b], #28]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #28]\n\t" + "mov %[c], #0\n\t" + "adc %[c], %[c]\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5" + ); + + return c; +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r6, %[a]\n\t" + "add r6, #32\n\t" + "\n1:\n\t" + "mov r5, #0\n\t" + "sub r5, %[c]\n\t" + "ldr r4, [%[a]]\n\t" + "ldr r5, [%[b]]\n\t" + "sbc r4, r5\n\t" + "str r4, [%[r]]\n\t" + "sbc %[c], %[c]\n\t" + "add %[a], #4\n\t" + "add %[b], #4\n\t" + "add %[r], #4\n\t" + "cmp %[a], r6\n\t" + "bne 1b\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6" + ); + + return c; +} + +#else +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldr r4, [%[a], #0]\n\t" + "ldr r5, [%[a], #4]\n\t" + "ldr r6, [%[b], #0]\n\t" + "ldr r7, [%[b], #4]\n\t" + "sub r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #0]\n\t" + "str r5, [%[r], #4]\n\t" + "ldr r4, [%[a], #8]\n\t" + "ldr r5, [%[a], #12]\n\t" + "ldr r6, [%[b], #8]\n\t" + "ldr r7, [%[b], #12]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #8]\n\t" + "str r5, [%[r], #12]\n\t" + "ldr r4, [%[a], #16]\n\t" + "ldr r5, [%[a], #20]\n\t" + "ldr r6, [%[b], #16]\n\t" + "ldr r7, [%[b], #20]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #16]\n\t" + "str r5, [%[r], #20]\n\t" + "ldr r4, [%[a], #24]\n\t" + "ldr r5, [%[a], #28]\n\t" + "ldr r6, [%[b], #24]\n\t" + "ldr r7, [%[b], #28]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #24]\n\t" + "str r5, [%[r], #28]\n\t" + "sbc %[c], %[c]\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6", "r7" + ); + + return c; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Create a new point. + * + * heap [in] Buffer to allocate dynamic memory from. + * sp [in] Data for point - only if not allocating. + * p [out] New point. + * returns MEMORY_E when dynamic memory allocation fails and 0 otherwise. + */ +static int sp_256_point_new_ex_8(void* heap, sp_point_256* sp, + sp_point_256** p) +{ + int ret = MP_OKAY; + (void)heap; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + (void)sp; + *p = (sp_point_256*)XMALLOC(sizeof(sp_point_256), heap, DYNAMIC_TYPE_ECC); +#else + *p = sp; +#endif + if (*p == NULL) { + ret = MEMORY_E; + } + return ret; +} + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* Allocate memory for point and return error. */ +#define sp_256_point_new_8(heap, sp, p) sp_256_point_new_ex_8((heap), NULL, &(p)) +#else +/* Set pointer to data and return no error. */ +#define sp_256_point_new_8(heap, sp, p) sp_256_point_new_ex_8((heap), &(sp), &(p)) +#endif + + +/* Free the point. + * + * p [in,out] Point to free. + * clear [in] Indicates whether to zeroize point. + * heap [in] Buffer from which dynamic memory was allocate from. + */ +static void sp_256_point_free_8(sp_point_256* p, int clear, void* heap) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* If valid pointer then clear point data if requested and free data. */ + if (p != NULL) { + if (clear != 0) { + XMEMSET(p, 0, sizeof(*p)); + } + XFREE(p, heap, DYNAMIC_TYPE_ECC); + } +#else +/* Clear point data if requested. */ + if ((p != NULL) && (clear != 0)) { + XMEMSET(p, 0, sizeof(*p)); + } +#endif + (void)heap; +} + +/* Multiply a number by Montogmery normalizer mod modulus (prime). + * + * r The resulting Montgomery form number. + * a The number to convert. + * m The modulus (prime). + */ +static int sp_256_mod_mul_norm_8(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + int64_t t[8]; + int64_t a64[8]; + int64_t o; + + (void)m; + + a64[0] = a[0]; + a64[1] = a[1]; + a64[2] = a[2]; + a64[3] = a[3]; + a64[4] = a[4]; + a64[5] = a[5]; + a64[6] = a[6]; + a64[7] = a[7]; + + /* 1 1 0 -1 -1 -1 -1 0 */ + t[0] = 0 + a64[0] + a64[1] - a64[3] - a64[4] - a64[5] - a64[6]; + /* 0 1 1 0 -1 -1 -1 -1 */ + t[1] = 0 + a64[1] + a64[2] - a64[4] - a64[5] - a64[6] - a64[7]; + /* 0 0 1 1 0 -1 -1 -1 */ + t[2] = 0 + a64[2] + a64[3] - a64[5] - a64[6] - a64[7]; + /* -1 -1 0 2 2 1 0 -1 */ + t[3] = 0 - a64[0] - a64[1] + 2 * a64[3] + 2 * a64[4] + a64[5] - a64[7]; + /* 0 -1 -1 0 2 2 1 0 */ + t[4] = 0 - a64[1] - a64[2] + 2 * a64[4] + 2 * a64[5] + a64[6]; + /* 0 0 -1 -1 0 2 2 1 */ + t[5] = 0 - a64[2] - a64[3] + 2 * a64[5] + 2 * a64[6] + a64[7]; + /* -1 -1 0 0 0 1 3 2 */ + t[6] = 0 - a64[0] - a64[1] + a64[5] + 3 * a64[6] + 2 * a64[7]; + /* 1 0 -1 -1 -1 -1 0 3 */ + t[7] = 0 + a64[0] - a64[2] - a64[3] - a64[4] - a64[5] + 3 * a64[7]; + + t[1] += t[0] >> 32; t[0] &= 0xffffffff; + t[2] += t[1] >> 32; t[1] &= 0xffffffff; + t[3] += t[2] >> 32; t[2] &= 0xffffffff; + t[4] += t[3] >> 32; t[3] &= 0xffffffff; + t[5] += t[4] >> 32; t[4] &= 0xffffffff; + t[6] += t[5] >> 32; t[5] &= 0xffffffff; + t[7] += t[6] >> 32; t[6] &= 0xffffffff; + o = t[7] >> 32; t[7] &= 0xffffffff; + t[0] += o; + t[3] -= o; + t[6] -= o; + t[7] += o; + t[1] += t[0] >> 32; t[0] &= 0xffffffff; + t[2] += t[1] >> 32; t[1] &= 0xffffffff; + t[3] += t[2] >> 32; t[2] &= 0xffffffff; + t[4] += t[3] >> 32; t[3] &= 0xffffffff; + t[5] += t[4] >> 32; t[4] &= 0xffffffff; + t[6] += t[5] >> 32; t[5] &= 0xffffffff; + t[7] += t[6] >> 32; t[6] &= 0xffffffff; + r[0] = t[0]; + r[1] = t[1]; + r[2] = t[2]; + r[3] = t[3]; + r[4] = t[4]; + r[5] = t[5]; + r[6] = t[6]; + r[7] = t[7]; + + return MP_OKAY; +} + +/* Convert an mp_int to an array of sp_digit. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a A multi-precision integer. + */ +static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) +{ +#if DIGIT_BIT == 32 + int j; + + XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); + + for (j = a->used; j < size; j++) { + r[j] = 0; + } +#elif DIGIT_BIT > 32 + int i; + int j = 0; + word32 s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i] << s); + r[j] &= 0xffffffff; + s = 32U - s; + if (j + 1 >= size) { + break; + } + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + while ((s + 32U) <= (word32)DIGIT_BIT) { + s += 32U; + r[j] &= 0xffffffff; + if (j + 1 >= size) { + break; + } + if (s < (word32)DIGIT_BIT) { + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + } + else { + r[++j] = 0L; + } + } + s = (word32)DIGIT_BIT - s; + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#else + int i; + int j = 0; + int s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i]) << s; + if (s + DIGIT_BIT >= 32) { + r[j] &= 0xffffffff; + if (j + 1 >= size) { + break; + } + s = 32 - s; + if (s == DIGIT_BIT) { + r[++j] = 0; + s = 0; + } + else { + r[++j] = a->dp[i] >> s; + s = DIGIT_BIT - s; + } + } + else { + s += DIGIT_BIT; + } + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#endif +} + +/* Convert a point of type ecc_point to type sp_point_256. + * + * p Point of type sp_point_256 (result). + * pm Point of type ecc_point. + */ +static void sp_256_point_from_ecc_point_8(sp_point_256* p, + const ecc_point* pm) +{ + XMEMSET(p->x, 0, sizeof(p->x)); + XMEMSET(p->y, 0, sizeof(p->y)); + XMEMSET(p->z, 0, sizeof(p->z)); + sp_256_from_mp(p->x, 8, pm->x); + sp_256_from_mp(p->y, 8, pm->y); + sp_256_from_mp(p->z, 8, pm->z); + p->infinity = 0; +} + +/* Convert an array of sp_digit to an mp_int. + * + * a A single precision integer. + * r A multi-precision integer. + */ +static int sp_256_to_mp(const sp_digit* a, mp_int* r) +{ + int err; + + err = mp_grow(r, (256 + DIGIT_BIT - 1) / DIGIT_BIT); + if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ +#if DIGIT_BIT == 32 + XMEMCPY(r->dp, a, sizeof(sp_digit) * 8); + r->used = 8; + mp_clamp(r); +#elif DIGIT_BIT < 32 + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 8; i++) { + r->dp[j] |= (mp_digit)(a[i] << s); + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + s = DIGIT_BIT - s; + r->dp[++j] = (mp_digit)(a[i] >> s); + while (s + DIGIT_BIT <= 32) { + s += DIGIT_BIT; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; + if (s == SP_WORD_SIZE) { + r->dp[j] = 0; + } + else { + r->dp[j] = (mp_digit)(a[i] >> s); + } + } + s = 32 - s; + } + r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#else + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 8; i++) { + r->dp[j] |= ((mp_digit)a[i]) << s; + if (s + 32 >= DIGIT_BIT) { + #if DIGIT_BIT != 32 && DIGIT_BIT != 64 + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + #endif + s = DIGIT_BIT - s; + r->dp[++j] = a[i] >> s; + s = 32 - s; + } + else { + s += 32; + } + } + r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#endif + } + + return err; +} + +/* Convert a point of type sp_point_256 to type ecc_point. + * + * p Point of type sp_point_256. + * pm Point of type ecc_point (result). + * returns MEMORY_E when allocation of memory in ecc_point fails otherwise + * MP_OKAY. + */ +static int sp_256_point_to_ecc_point_8(const sp_point_256* p, ecc_point* pm) +{ + int err; + + err = sp_256_to_mp(p->x, pm->x); + if (err == MP_OKAY) { + err = sp_256_to_mp(p->y, pm->y); + } + if (err == MP_OKAY) { + err = sp_256_to_mp(p->z, pm->z); + } + + return err; +} + /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -16332,161 +16796,13 @@ SP_NOINLINE static void sp_256_mont_reduce_order_8(sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_256_mont_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_256_mont_mul_8(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_256_mul_8(r, a, b); sp_256_mont_reduce_8(r, m, mp); } -/* Square a and put result in r. (r = a * a) - * - * r A single precision integer. - * a A single precision integer. - */ -SP_NOINLINE static void sp_256_sqr_8(sp_digit* r, const sp_digit* a) -{ - __asm__ __volatile__ ( - "mov r3, #0\n\t" - "mov r4, #0\n\t" - "mov r5, #0\n\t" - "mov r8, r3\n\t" - "mov r11, %[r]\n\t" - "mov r6, #64\n\t" - "neg r6, r6\n\t" - "add sp, r6\n\t" - "mov r10, sp\n\t" - "mov r9, %[a]\n\t" - "\n1:\n\t" - "mov %[r], #0\n\t" - "mov r6, #28\n\t" - "mov %[a], r8\n\t" - "sub %[a], r6\n\t" - "sbc r6, r6\n\t" - "mvn r6, r6\n\t" - "and %[a], r6\n\t" - "mov r2, r8\n\t" - "sub r2, %[a]\n\t" - "add %[a], r9\n\t" - "add r2, r9\n\t" - "\n2:\n\t" - "cmp r2, %[a]\n\t" - "beq 4f\n\t" - "# Multiply * 2: Start\n\t" - "ldr r6, [%[a]]\n\t" - "ldr r7, [r2]\n\t" - "lsl r6, r6, #16\n\t" - "lsl r7, r7, #16\n\t" - "lsr r6, r6, #16\n\t" - "lsr r7, r7, #16\n\t" - "mul r7, r6\n\t" - "add r3, r7\n\t" - "adc r4, %[r]\n\t" - "adc r5, %[r]\n\t" - "add r3, r7\n\t" - "adc r4, %[r]\n\t" - "adc r5, %[r]\n\t" - "ldr r7, [r2]\n\t" - "lsr r7, r7, #16\n\t" - "mul r6, r7\n\t" - "lsr r7, r6, #16\n\t" - "lsl r6, r6, #16\n\t" - "add r3, r6\n\t" - "adc r4, r7\n\t" - "adc r5, %[r]\n\t" - "add r3, r6\n\t" - "adc r4, r7\n\t" - "adc r5, %[r]\n\t" - "ldr r6, [%[a]]\n\t" - "ldr r7, [r2]\n\t" - "lsr r6, r6, #16\n\t" - "lsr r7, r7, #16\n\t" - "mul r7, r6\n\t" - "add r4, r7\n\t" - "adc r5, %[r]\n\t" - "add r4, r7\n\t" - "adc r5, %[r]\n\t" - "ldr r7, [r2]\n\t" - "lsl r7, r7, #16\n\t" - "lsr r7, r7, #16\n\t" - "mul r6, r7\n\t" - "lsr r7, r6, #16\n\t" - "lsl r6, r6, #16\n\t" - "add r3, r6\n\t" - "adc r4, r7\n\t" - "adc r5, %[r]\n\t" - "add r3, r6\n\t" - "adc r4, r7\n\t" - "adc r5, %[r]\n\t" - "# Multiply * 2: Done\n\t" - "bal 5f\n\t" - "\n4:\n\t" - "# Square: Start\n\t" - "ldr r6, [%[a]]\n\t" - "lsr r7, r6, #16\n\t" - "lsl r6, r6, #16\n\t" - "lsr r6, r6, #16\n\t" - "mul r6, r6\n\t" - "add r3, r6\n\t" - "adc r4, %[r]\n\t" - "adc r5, %[r]\n\t" - "mul r7, r7\n\t" - "add r4, r7\n\t" - "adc r5, %[r]\n\t" - "ldr r6, [%[a]]\n\t" - "lsr r7, r6, #16\n\t" - "lsl r6, r6, #16\n\t" - "lsr r6, r6, #16\n\t" - "mul r6, r7\n\t" - "lsr r7, r6, #15\n\t" - "lsl r6, r6, #17\n\t" - "add r3, r6\n\t" - "adc r4, r7\n\t" - "adc r5, %[r]\n\t" - "# Square: Done\n\t" - "\n5:\n\t" - "add %[a], #4\n\t" - "sub r2, #4\n\t" - "mov r6, #32\n\t" - "add r6, r9\n\t" - "cmp %[a], r6\n\t" - "beq 3f\n\t" - "cmp %[a], r2\n\t" - "bgt 3f\n\t" - "mov r7, r8\n\t" - "add r7, r9\n\t" - "cmp %[a], r7\n\t" - "ble 2b\n\t" - "\n3:\n\t" - "mov %[r], r10\n\t" - "mov r7, r8\n\t" - "str r3, [%[r], r7]\n\t" - "mov r3, r4\n\t" - "mov r4, r5\n\t" - "mov r5, #0\n\t" - "add r7, #4\n\t" - "mov r8, r7\n\t" - "mov r6, #56\n\t" - "cmp r7, r6\n\t" - "ble 1b\n\t" - "mov %[a], r9\n\t" - "str r3, [%[r], r7]\n\t" - "mov %[r], r11\n\t" - "mov %[a], r10\n\t" - "mov r3, #60\n\t" - "\n4:\n\t" - "ldr r6, [%[a], r3]\n\t" - "str r6, [%[r], r3]\n\t" - "sub r3, #4\n\t" - "bge 4b\n\t" - "mov r6, #64\n\t" - "add sp, r6\n\t" - : - : [r] "r" (r), [a] "r" (a) - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" - ); -} - /* Square the Montgomery form number. (r = a * a mod m) * * r Result of squaring. @@ -16494,8 +16810,8 @@ SP_NOINLINE static void sp_256_sqr_8(sp_digit* r, const sp_digit* a) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_256_mont_sqr_8(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_256_mont_sqr_8(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_256_sqr_8(r, a); sp_256_mont_reduce_8(r, m, mp); @@ -16519,7 +16835,7 @@ static void sp_256_mont_sqr_n_8(sp_digit* r, const sp_digit* a, int n, } } -#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */ +#endif /* !WOLFSSL_SP_SMALL | HAVE_COMP_KEY */ #ifdef WOLFSSL_SP_SMALL /* Mod-2 for the P256 curve. */ static const uint32_t p256_mod_minus_2[8] = { @@ -16652,7 +16968,8 @@ SP_NOINLINE static int32_t sp_256_cmp_8(const sp_digit* a, const sp_digit* b) * p Montgomery form projective coordinate point. * t Temporary ordinate data. */ -static void sp_256_map_8(sp_point_256* r, const sp_point_256* p, sp_digit* t) +static void sp_256_map_8(sp_point_256* r, const sp_point_256* p, + sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2*8; @@ -16688,100 +17005,6 @@ static void sp_256_map_8(sp_point_256* r, const sp_point_256* p, sp_digit* t) } -#ifdef WOLFSSL_SP_SMALL -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "mov r6, %[a]\n\t" - "mov r7, #0\n\t" - "add r6, #32\n\t" - "sub r7, #1\n\t" - "\n1:\n\t" - "add %[c], r7\n\t" - "ldr r4, [%[a]]\n\t" - "ldr r5, [%[b]]\n\t" - "adc r4, r5\n\t" - "str r4, [%[r]]\n\t" - "mov %[c], #0\n\t" - "adc %[c], %[c]\n\t" - "add %[a], #4\n\t" - "add %[b], #4\n\t" - "add %[r], #4\n\t" - "cmp %[a], r6\n\t" - "bne 1b\n\t" - : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) - : - : "memory", "r4", "r5", "r6", "r7" - ); - - return c; -} - -#else -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "ldr r4, [%[a], #0]\n\t" - "ldr r5, [%[b], #0]\n\t" - "add r4, r5\n\t" - "str r4, [%[r], #0]\n\t" - "ldr r4, [%[a], #4]\n\t" - "ldr r5, [%[b], #4]\n\t" - "adc r4, r5\n\t" - "str r4, [%[r], #4]\n\t" - "ldr r4, [%[a], #8]\n\t" - "ldr r5, [%[b], #8]\n\t" - "adc r4, r5\n\t" - "str r4, [%[r], #8]\n\t" - "ldr r4, [%[a], #12]\n\t" - "ldr r5, [%[b], #12]\n\t" - "adc r4, r5\n\t" - "str r4, [%[r], #12]\n\t" - "ldr r4, [%[a], #16]\n\t" - "ldr r5, [%[b], #16]\n\t" - "adc r4, r5\n\t" - "str r4, [%[r], #16]\n\t" - "ldr r4, [%[a], #20]\n\t" - "ldr r5, [%[b], #20]\n\t" - "adc r4, r5\n\t" - "str r4, [%[r], #20]\n\t" - "ldr r4, [%[a], #24]\n\t" - "ldr r5, [%[b], #24]\n\t" - "adc r4, r5\n\t" - "str r4, [%[r], #24]\n\t" - "ldr r4, [%[a], #28]\n\t" - "ldr r5, [%[b], #28]\n\t" - "adc r4, r5\n\t" - "str r4, [%[r], #28]\n\t" - "mov %[c], #0\n\t" - "adc %[c], %[c]\n\t" - : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) - : - : "memory", "r4", "r5" - ); - - return c; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Add two Montgomery form numbers (r = a + b % m). * * r Result of addition. @@ -17415,97 +17638,6 @@ static void sp_256_proj_point_dbl_8(sp_point_256* r, const sp_point_256* p, sp_d sp_256_mont_sub_8(y, y, t2, p256_mod); } -#ifdef WOLFSSL_SP_SMALL -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "mov r6, %[a]\n\t" - "add r6, #32\n\t" - "\n1:\n\t" - "mov r5, #0\n\t" - "sub r5, %[c]\n\t" - "ldr r4, [%[a]]\n\t" - "ldr r5, [%[b]]\n\t" - "sbc r4, r5\n\t" - "str r4, [%[r]]\n\t" - "sbc %[c], %[c]\n\t" - "add %[a], #4\n\t" - "add %[b], #4\n\t" - "add %[r], #4\n\t" - "cmp %[a], r6\n\t" - "bne 1b\n\t" - : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) - : - : "memory", "r4", "r5", "r6" - ); - - return c; -} - -#else -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "ldr r4, [%[a], #0]\n\t" - "ldr r5, [%[a], #4]\n\t" - "ldr r6, [%[b], #0]\n\t" - "ldr r7, [%[b], #4]\n\t" - "sub r4, r6\n\t" - "sbc r5, r7\n\t" - "str r4, [%[r], #0]\n\t" - "str r5, [%[r], #4]\n\t" - "ldr r4, [%[a], #8]\n\t" - "ldr r5, [%[a], #12]\n\t" - "ldr r6, [%[b], #8]\n\t" - "ldr r7, [%[b], #12]\n\t" - "sbc r4, r6\n\t" - "sbc r5, r7\n\t" - "str r4, [%[r], #8]\n\t" - "str r5, [%[r], #12]\n\t" - "ldr r4, [%[a], #16]\n\t" - "ldr r5, [%[a], #20]\n\t" - "ldr r6, [%[b], #16]\n\t" - "ldr r7, [%[b], #20]\n\t" - "sbc r4, r6\n\t" - "sbc r5, r7\n\t" - "str r4, [%[r], #16]\n\t" - "str r5, [%[r], #20]\n\t" - "ldr r4, [%[a], #24]\n\t" - "ldr r5, [%[a], #28]\n\t" - "ldr r6, [%[b], #24]\n\t" - "ldr r7, [%[b], #28]\n\t" - "sbc r4, r6\n\t" - "sbc r5, r7\n\t" - "str r4, [%[r], #24]\n\t" - "str r5, [%[r], #28]\n\t" - "sbc %[c], %[c]\n\t" - : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) - : - : "memory", "r4", "r5", "r6", "r7" - ); - - return c; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Compare two numbers to determine if they are equal. * Constant time implementation. * @@ -17729,8 +17861,8 @@ static int sp_256_proj_point_add_8_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r, } #endif /* WOLFSSL_SP_NONBLOCK */ -static void sp_256_proj_point_add_8(sp_point_256* r, const sp_point_256* p, const sp_point_256* q, - sp_digit* t) +static void sp_256_proj_point_add_8(sp_point_256* r, + const sp_point_256* p, const sp_point_256* q, sp_digit* t) { const sp_point_256* ap[2]; sp_point_256* rp[2]; @@ -17885,9 +18017,11 @@ static void sp_256_get_point_16_8(sp_point_256* r, const sp_point_256* table, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Simple, smaller code size and memory size, of windowing. - * Calculate uindow of 4 bits. - * Only add points from table. + * Fast implementation that generates a pre-computation table. + * 4 bits of window (no sliding!). + * Uses add and double for calculating table. + * 256 doubles. + * 76 adds. * * r Resulting point. * g Point to multiply. @@ -17916,7 +18050,8 @@ static int sp_256_ecc_mulmod_fast_8(sp_point_256* r, const sp_point_256* g, cons sp_digit* tmp; sp_digit n; int i; - int c, y; + int c; + int y; int err; /* Constant time used for cache attack resistance implementation. */ @@ -17989,7 +18124,7 @@ static int sp_256_ecc_mulmod_fast_8(sp_point_256* r, const sp_point_256* g, cons i = 6; n = k[i+1] << 0; c = 28; - y = n >> 28; + y = (int)(n >> 28); #ifndef WC_NO_CACHE_RESISTANT if (ct) { sp_256_get_point_16_8(rt, t, y); @@ -18054,12 +18189,6 @@ static int sp_256_ecc_mulmod_fast_8(sp_point_256* r, const sp_point_256* g, cons return err; } -/* A table entry for pre-computed points. */ -typedef struct sp_table_entry_256 { - sp_digit x[8]; - sp_digit y[8]; -} sp_table_entry_256; - #ifdef FP_ECC /* Double the Montgomery form projective point p a number of times. * @@ -18068,7 +18197,8 @@ typedef struct sp_table_entry_256 { * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_8(sp_point_256* p, int n, sp_digit* t) +static void sp_256_proj_point_dbl_n_8(sp_point_256* p, int n, + sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*8; @@ -18149,6 +18279,36 @@ static void sp_256_proj_point_dbl_n_8(sp_point_256* p, int n, sp_digit* t) sp_256_div2_8(y, y, p256_mod); } +/* Convert the projective point to affine. + * Ordinates are in Montgomery form. + * + * a Point to convert. + * t Temporary data. + */ +static void sp_256_proj_to_affine_8(sp_point_256* a, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 8; + sp_digit* tmp = t + 4 * 8; + + sp_256_mont_inv_8(t1, a->z, tmp); + + sp_256_mont_sqr_8(t2, t1, p256_mod, p256_mp_mod); + sp_256_mont_mul_8(t1, t2, t1, p256_mod, p256_mp_mod); + + sp_256_mont_mul_8(a->x, a->x, t2, p256_mod, p256_mp_mod); + sp_256_mont_mul_8(a->y, a->y, t1, p256_mod, p256_mp_mod); + XMEMCPY(a->z, p256_norm_mod, sizeof(p256_norm_mod)); +} + +#endif /* FP_ECC */ +/* A table entry for pre-computed points. */ +typedef struct sp_table_entry_256 { + sp_digit x[8]; + sp_digit y[8]; +} sp_table_entry_256; + +#ifdef FP_ECC #endif /* FP_ECC */ /* Add two Montgomery form projective points. The second point has a q value of * one. @@ -18234,29 +18394,11 @@ static void sp_256_proj_point_add_qz1_8(sp_point_256* r, const sp_point_256* p, #ifdef WOLFSSL_SP_SMALL #ifdef FP_ECC -/* Convert the projective point to affine. - * Ordinates are in Montgomery form. - * - * a Point to convert. - * t Temporary data. - */ -static void sp_256_proj_to_affine_8(sp_point_256* a, sp_digit* t) -{ - sp_digit* t1 = t; - sp_digit* t2 = t + 2 * 8; - sp_digit* tmp = t + 4 * 8; - - sp_256_mont_inv_8(t1, a->z, tmp); - - sp_256_mont_sqr_8(t2, t1, p256_mod, p256_mp_mod); - sp_256_mont_mul_8(t1, t2, t1, p256_mod, p256_mp_mod); - - sp_256_mont_mul_8(a->x, a->x, t2, p256_mod, p256_mp_mod); - sp_256_mont_mul_8(a->y, a->y, t1, p256_mod, p256_mp_mod); - XMEMCPY(a->z, p256_norm_mod, sizeof(p256_norm_mod)); -} - /* Generate the pre-computed table of points for the base point. + * + * width = 4 + * 16 entries + * 64 bits between * * a The base point. * table Place to store generated point data. @@ -18267,12 +18409,15 @@ static int sp_256_gen_stripe_table_8(const sp_point_256* a, sp_table_entry_256* table, sp_digit* tmp, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_point_256 td, s1d, s2d; + sp_point_256 td; + sp_point_256 s1d; + sp_point_256 s2d; #endif sp_point_256* t; sp_point_256* s1 = NULL; sp_point_256* s2 = NULL; - int i, j; + int i; + int j; int err; (void)heap; @@ -18391,8 +18536,10 @@ static void sp_256_get_entry_16_8(sp_point_256* r, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Implementation uses striping of bits. - * Choose bits 4 bits apart. + * Stripe implementation. + * Pre-generated: 2^0, 2^64, ... + * Pre-generated: products of all combinations of above. + * 4 doubles and adds (with qz=1) * * r Resulting point. * k Scalar to multiply by. @@ -18414,8 +18561,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, sp_point_256* rt; sp_point_256* p = NULL; sp_digit* t; - int i, j; - int y, x; + int i; + int j; + int y; + int x; int err; (void)g; @@ -18443,8 +18592,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod)); y = 0; - for (j=0,x=63; j<4; j++,x+=64) { + x = 63; + for (j=0; j<4; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 64; } #ifndef WC_NO_CACHE_RESISTANT if (ct) { @@ -18458,8 +18609,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, rt->infinity = !y; for (i=62; i>=0; i--) { y = 0; - for (j=0,x=i; j<4; j++,x+=64) { + x = i; + for (j=0; j<4; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 64; } sp_256_proj_point_dbl_8(rt, rt, t); @@ -18501,16 +18654,25 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, #define FP_ENTRIES 16 #endif +/* Cache entry - holds precomputation tables for a point. */ typedef struct sp_cache_256_t { + /* X ordinate of point that table was generated from. */ sp_digit x[8]; + /* Y ordinate of point that table was generated from. */ sp_digit y[8]; + /* Precomputation table for point. */ sp_table_entry_256 table[16]; + /* Count of entries in table. */ uint32_t cnt; + /* Point and table set in entry. */ int set; } sp_cache_256_t; +/* Cache of tables. */ static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES]; +/* Index of last entry in cache. */ static THREAD_LS_T int sp_cache_256_last = -1; +/* Cache has been initialized. */ static THREAD_LS_T int sp_cache_256_inited = 0; #ifndef HAVE_THREAD_LS @@ -18518,9 +18680,15 @@ static THREAD_LS_T int sp_cache_256_inited = 0; static wolfSSL_Mutex sp_cache_256_lock; #endif +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache) { - int i, j; + int i; + int j; uint32_t least; if (sp_cache_256_inited == 0) { @@ -18629,6 +18797,10 @@ static int sp_256_ecc_mulmod_8(sp_point_256* r, const sp_point_256* g, const sp_ #else #ifdef FP_ECC /* Generate the pre-computed table of points for the base point. + * + * width = 8 + * 256 entries + * 32 bits between * * a The base point. * table Place to store generated point data. @@ -18639,12 +18811,15 @@ static int sp_256_gen_stripe_table_8(const sp_point_256* a, sp_table_entry_256* table, sp_digit* tmp, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_point_256 td, s1d, s2d; + sp_point_256 td; + sp_point_256 s1d; + sp_point_256 s2d; #endif sp_point_256* t; sp_point_256* s1 = NULL; sp_point_256* s2 = NULL; - int i, j; + int i; + int j; int err; (void)heap; @@ -18763,8 +18938,10 @@ static void sp_256_get_entry_256_8(sp_point_256* r, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Implementation uses striping of bits. - * Choose bits 8 bits apart. + * Stripe implementation. + * Pre-generated: 2^0, 2^32, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) * * r Resulting point. * k Scalar to multiply by. @@ -18786,8 +18963,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, sp_point_256* rt; sp_point_256* p = NULL; sp_digit* t; - int i, j; - int y, x; + int i; + int j; + int y; + int x; int err; (void)g; @@ -18815,8 +18994,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod)); y = 0; - for (j=0,x=31; j<8; j++,x+=32) { + x = 31; + for (j=0; j<8; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 32; } #ifndef WC_NO_CACHE_RESISTANT if (ct) { @@ -18830,8 +19011,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, rt->infinity = !y; for (i=30; i>=0; i--) { y = 0; - for (j=0,x=i; j<8; j++,x+=32) { + x = i; + for (j=0; j<8; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 32; } sp_256_proj_point_dbl_8(rt, rt, t); @@ -18873,16 +19056,25 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, #define FP_ENTRIES 16 #endif +/* Cache entry - holds precomputation tables for a point. */ typedef struct sp_cache_256_t { + /* X ordinate of point that table was generated from. */ sp_digit x[8]; + /* Y ordinate of point that table was generated from. */ sp_digit y[8]; + /* Precomputation table for point. */ sp_table_entry_256 table[256]; + /* Count of entries in table. */ uint32_t cnt; + /* Point and table set in entry. */ int set; } sp_cache_256_t; +/* Cache of tables. */ static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES]; +/* Index of last entry in cache. */ static THREAD_LS_T int sp_cache_256_last = -1; +/* Cache has been initialized. */ static THREAD_LS_T int sp_cache_256_inited = 0; #ifndef HAVE_THREAD_LS @@ -18890,9 +19082,15 @@ static THREAD_LS_T int sp_cache_256_inited = 0; static wolfSSL_Mutex sp_cache_256_lock; #endif +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache) { - int i, j; + int i; + int j; uint32_t least; if (sp_cache_256_inited == 0) { @@ -19009,8 +19207,8 @@ static int sp_256_ecc_mulmod_8(sp_point_256* r, const sp_point_256* g, const sp_ * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, - void* heap) +int sp_ecc_mulmod_256(const mp_int* km, const ecc_point* gm, ecc_point* r, + int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_256 p; @@ -19051,7 +19249,94 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, return err; } +/* Multiply the point by the scalar, add point a and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * p Point to multiply. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_add_256(const mp_int* km, const ecc_point* gm, + const ecc_point* am, int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_256 p; + sp_point_256 a; + sp_digit kd[8]; + sp_digit t[8 * 2 * 5]; +#endif + sp_point_256* point; + sp_point_256* addP = NULL; + sp_digit* k = NULL; + sp_digit* tmp = NULL; + int err = MP_OKAY; + + err = sp_256_point_new_8(heap, p, point); + if (err == MP_OKAY) { + err = sp_256_point_new_8(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (8 + 8 * 2 * 5), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 8; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_256_from_mp(k, 8, km); + sp_256_point_from_ecc_point_8(point, gm); + sp_256_point_from_ecc_point_8(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_8(addP->x, addP->x, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_8(addP->y, addP->y, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_8(addP->z, addP->z, p256_mod); + } + if (err == MP_OKAY) { + err = sp_256_ecc_mulmod_8(point, point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_256_proj_point_add_8(point, point, addP, tmp); + + if (map) { + sp_256_map_8(point, point, tmp); + } + + err = sp_256_point_to_ecc_point_8(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_256_point_free_8(addP, 0, heap); + sp_256_point_free_8(point, 0, heap); + + return err; +} + #ifdef WOLFSSL_SP_SMALL +/* Striping precomputation table. + * 4 points combined into a table of 16 points. + * Distance of 64 between points. + */ static const sp_table_entry_256 p256_table[16] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -19136,6 +19421,11 @@ static const sp_table_entry_256 p256_table[16] = { /* Multiply the base point of P256 by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Stripe implementation. + * Pre-generated: 2^0, 2^64, ... + * Pre-generated: products of all combinations of above. + * 4 doubles and adds (with qz=1) + * * r Resulting point. * k Scalar to multiply by. * map Indicates whether to convert result to affine. @@ -19151,6 +19441,10 @@ static int sp_256_ecc_mulmod_base_8(sp_point_256* r, const sp_digit* k, } #else +/* Striping precomputation table. + * 8 points combined into a table of 256 points. + * Distance of 32 between points. + */ static const sp_table_entry_256 p256_table[256] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -20435,6 +20729,11 @@ static const sp_table_entry_256 p256_table[256] = { /* Multiply the base point of P256 by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Stripe implementation. + * Pre-generated: 2^0, 2^32, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * * r Resulting point. * k Scalar to multiply by. * map Indicates whether to convert result to affine. @@ -20460,7 +20759,7 @@ static int sp_256_ecc_mulmod_base_8(sp_point_256* r, const sp_digit* k, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) +int sp_ecc_mulmod_base_256(const mp_int* km, ecc_point* r, int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_256 p; @@ -20501,6 +20800,87 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) return err; } +/* Multiply the base point of P256 by the scalar, add point a and return + * the result. If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_add_256(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_256 p; + sp_point_256 a; + sp_digit kd[8]; + sp_digit t[8 * 2 * 5]; +#endif + sp_point_256* point; + sp_point_256* addP = NULL; + sp_digit* tmp = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_256_point_new_8(heap, p, point); + if (err == MP_OKAY) { + err = sp_256_point_new_8(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (8 + 8 * 2 * 5), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 8; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_256_from_mp(k, 8, km); + sp_256_point_from_ecc_point_8(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_8(addP->x, addP->x, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_8(addP->y, addP->y, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_8(addP->z, addP->z, p256_mod); + } + if (err == MP_OKAY) { + err = sp_256_ecc_mulmod_base_8(point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_256_proj_point_add_8(point, point, addP, tmp); + + if (map) { + sp_256_map_8(point, point, tmp); + } + + err = sp_256_point_to_ecc_point_8(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_256_point_free_8(addP, 0, heap); + sp_256_point_free_8(point, 0, heap); + + return err; +} + #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \ defined(HAVE_ECC_VERIFY) /* Returns 1 if the number of zero. @@ -20514,7 +20894,7 @@ static int sp_256_iszero_8(const sp_digit* a) return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6] | a[7]) == 0; } -#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN | HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ /* Add 1 to a. (a = a + 1) * * a A single precision integer. @@ -20563,7 +20943,8 @@ SP_NOINLINE static void sp_256_add_one_8(sp_digit* a) */ static void sp_256_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -20707,7 +21088,10 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) */ static void sp_256_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; j = 256 / 8 - 1; a[j] = 0; @@ -20748,7 +21132,7 @@ static void sp_256_to_bin(sp_digit* r, byte* a) * returns BUFFER_E if the buffer is to small for output size, * MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, +int sp_ecc_secret_gen_256(const mp_int* priv, const ecc_point* pub, byte* out, word32* outLen, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) @@ -21190,7 +21574,7 @@ static const uint32_t p256_order_minus_2[8] = { }; #else /* The low half of the order-2 of the P256 curve. */ -static const uint32_t p256_order_low[4] = { +static const sp_int_digit p256_order_low[4] = { 0xfc63254fU,0xf3b9cac2U,0xa7179e84U,0xbce6faadU }; #endif /* WOLFSSL_SP_SMALL */ @@ -21336,7 +21720,7 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6 */ for (i=127; i>=112; i--) { sp_256_mont_sqr_order_8(t2, t2); - if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_256_mont_mul_order_8(t2, t2, a); } } @@ -21346,7 +21730,7 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84 */ for (i=107; i>=64; i--) { sp_256_mont_sqr_order_8(t2, t2); - if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_256_mont_mul_order_8(t2, t2, a); } } @@ -21356,7 +21740,7 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2 */ for (i=59; i>=32; i--) { sp_256_mont_sqr_order_8(t2, t2); - if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_256_mont_mul_order_8(t2, t2, a); } } @@ -21366,7 +21750,7 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254 */ for (i=27; i>=0; i--) { sp_256_mont_sqr_order_8(t2, t2); - if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_256_mont_mul_order_8(t2, t2, a); } } @@ -21377,12 +21761,63 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a, #endif /* WOLFSSL_SP_SMALL */ } -#endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ #ifdef HAVE_ECC_SIGN #ifndef SP_ECC_MAX_SIG_GEN #define SP_ECC_MAX_SIG_GEN 64 #endif +/* Calculate second signature value S from R, k and private value. + * + * s = (r * x + e) / k + * + * s Signature value. + * r First signature value. + * k Ephemeral private key. + * x Private key as a number. + * e Hash of message as a number. + * tmp Temporary storage for intermediate numbers. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_256_calc_s_8(sp_digit* s, const sp_digit* r, sp_digit* k, + sp_digit* x, const sp_digit* e, sp_digit* tmp) +{ + int err; + sp_digit carry; + int32_t c; + sp_digit* kInv = k; + + /* Conv k to Montgomery form (mod order) */ + sp_256_mul_8(k, k, p256_norm_order); + err = sp_256_mod_8(k, k, p256_order); + if (err == MP_OKAY) { + sp_256_norm_8(k); + + /* kInv = 1/k mod order */ + sp_256_mont_inv_order_8(kInv, k, tmp); + sp_256_norm_8(kInv); + + /* s = r * x + e */ + sp_256_mul_8(x, x, r); + err = sp_256_mod_8(x, x, p256_order); + } + if (err == MP_OKAY) { + sp_256_norm_8(x); + carry = sp_256_add_8(s, e, x); + sp_256_cond_sub_8(s, s, p256_order, 0 - carry); + sp_256_norm_8(s); + c = sp_256_cmp_8(s, p256_order); + sp_256_cond_sub_8(s, s, p256_order, 0L - (sp_digit)(c >= 0)); + sp_256_norm_8(s); + + /* s = s * k^-1 mod order */ + sp_256_mont_mul_order_8(s, s, kInv); + sp_256_norm_8(s); + } + + return err; +} + /* Sign the hash using the private key. * e = [hash, 256 bits] from binary * r = (k.G)->x mod order @@ -21417,8 +21852,8 @@ typedef struct sp_ecc_sign_256_ctx { int i; } sp_ecc_sign_256_ctx; -int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, + mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_sign_256_ctx* ctx = (sp_ecc_sign_256_ctx*)sp_ctx->data; @@ -21558,8 +21993,8 @@ int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, W } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, + const mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -21577,11 +22012,9 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit* r = NULL; sp_digit* tmp = NULL; sp_point_256* point = NULL; - sp_digit carry; sp_digit* s = NULL; - sp_digit* kInv = NULL; - int err = MP_OKAY; int32_t c; + int err = MP_OKAY; int i; (void)heap; @@ -21612,7 +22045,6 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, tmp = td; #endif s = e; - kInv = k; if (hashLen > 32U) { hashLen = 32U; @@ -21620,8 +22052,6 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, } for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) { - sp_256_from_mp(x, 8, priv); - /* New random point. */ if (km == NULL || mp_iszero(km)) { err = sp_256_ecc_gen_k_8(rng, k); @@ -21631,7 +22061,7 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, mp_zero(km); } if (err == MP_OKAY) { - err = sp_256_ecc_mulmod_base_8(point, k, 1, 1, NULL); + err = sp_256_ecc_mulmod_base_8(point, k, 1, 1, heap); } if (err == MP_OKAY) { @@ -21642,38 +22072,15 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_256_cond_sub_8(r, r, p256_order, 0L - (sp_digit)(c >= 0)); sp_256_norm_8(r); - /* Conv k to Montgomery form (mod order) */ - sp_256_mul_8(k, k, p256_norm_order); - err = sp_256_mod_8(k, k, p256_order); - } - if (err == MP_OKAY) { - sp_256_norm_8(k); - /* kInv = 1/k mod order */ - sp_256_mont_inv_order_8(kInv, k, tmp); - sp_256_norm_8(kInv); - - /* s = r * x + e */ - sp_256_mul_8(x, x, r); - err = sp_256_mod_8(x, x, p256_order); - } - if (err == MP_OKAY) { - sp_256_norm_8(x); + sp_256_from_mp(x, 8, priv); sp_256_from_bin(e, 8, hash, (int)hashLen); - carry = sp_256_add_8(s, e, x); - sp_256_cond_sub_8(s, s, p256_order, 0 - carry); - sp_256_norm_8(s); - c = sp_256_cmp_8(s, p256_order); - sp_256_cond_sub_8(s, s, p256_order, 0L - (sp_digit)(c >= 0)); - sp_256_norm_8(s); - /* s = s * k^-1 mod order */ - sp_256_mont_mul_order_8(s, s, kInv); - sp_256_norm_8(s); + err = sp_256_calc_s_8(s, r, k, x, e, tmp); + } - /* Check that signature is usable. */ - if (sp_256_iszero_8(s) == 0) { - break; - } + /* Check that signature is usable. */ + if ((err == MP_OKAY) && (sp_256_iszero_8(s) == 0)) { + break; } #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP i = 1; @@ -21701,7 +22108,6 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, XMEMSET(x, 0, sizeof(sp_digit) * 2U * 8U); XMEMSET(k, 0, sizeof(sp_digit) * 2U * 8U); XMEMSET(r, 0, sizeof(sp_digit) * 2U * 8U); - XMEMSET(r, 0, sizeof(sp_digit) * 2U * 8U); XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 8U); #endif sp_256_point_free_8(point, 1, heap); @@ -22286,6 +22692,96 @@ static int sp_256_mod_inv_8(sp_digit* r, const sp_digit* a, const sp_digit* m) } #endif /* WOLFSSL_SP_SMALL */ + +/* Add point p1 into point p2. Handles p1 == p2 and result at infinity. + * + * p1 First point to add and holds result. + * p2 Second point to add. + * tmp Temporary storage for intermediate numbers. + */ +static void sp_256_add_points_8(sp_point_256* p1, const sp_point_256* p2, + sp_digit* tmp) +{ + + sp_256_proj_point_add_8(p1, p1, p2, tmp); + if (sp_256_iszero_8(p1->z)) { + if (sp_256_iszero_8(p1->x) && sp_256_iszero_8(p1->y)) { + sp_256_proj_point_dbl_8(p1, p2, tmp); + } + else { + /* Y ordinate is not used from here - don't set. */ + p1->x[0] = 0; + p1->x[1] = 0; + p1->x[2] = 0; + p1->x[3] = 0; + p1->x[4] = 0; + p1->x[5] = 0; + p1->x[6] = 0; + p1->x[7] = 0; + XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod)); + } + } +} + +/* Calculate the verification point: [e/s]G + [r/s]Q + * + * p1 Calculated point. + * p2 Public point and temporary. + * s Second part of signature as a number. + * u1 Temporary number. + * u2 Temproray number. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_256_calc_vfy_point_8(sp_point_256* p1, sp_point_256* p2, + sp_digit* s, sp_digit* u1, sp_digit* u2, sp_digit* tmp, void* heap) +{ + int err; + +#ifndef WOLFSSL_SP_SMALL + { + sp_256_mod_inv_8(s, s, p256_order); + } +#endif /* !WOLFSSL_SP_SMALL */ + { + sp_256_mul_8(s, s, p256_norm_order); + } + err = sp_256_mod_8(s, s, p256_order); + if (err == MP_OKAY) { + sp_256_norm_8(s); +#ifdef WOLFSSL_SP_SMALL + { + sp_256_mont_inv_order_8(s, s, tmp); + sp_256_mont_mul_order_8(u1, u1, s); + sp_256_mont_mul_order_8(u2, u2, s); + } + +#else + { + sp_256_mont_mul_order_8(u1, u1, s); + sp_256_mont_mul_order_8(u2, u2, s); + } + +#endif /* WOLFSSL_SP_SMALL */ + err = sp_256_ecc_mulmod_base_8(p1, u1, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_256_iszero_8(p1->z)) { + p1->infinity = 1; + } + if (err == MP_OKAY) { + err = sp_256_ecc_mulmod_8(p2, p2, u2, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_256_iszero_8(p2->z)) { + p2->infinity = 1; + } + + if (err == MP_OKAY) { + sp_256_add_points_8(p1, p2, tmp); + } + + return err; +} + #ifdef HAVE_ECC_VERIFY /* Verify the signature values with the hash and public key. * e = Truncate(hash, 256) @@ -22304,8 +22800,7 @@ static int sp_256_mod_inv_8(sp_digit* r, const sp_digit* a, const sp_digit* m) * rm First part of result as an mp_int. * sm Sirst part of result as an mp_int. * heap Heap to use for allocation. - * returns RNG failures, MEMORY_E when memory allocation fails and - * MP_OKAY on success. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ #ifdef WOLFSSL_SP_NONBLOCK typedef struct sp_ecc_verify_256_ctx { @@ -22324,8 +22819,9 @@ typedef struct sp_ecc_verify_256_ctx { sp_point_256 p2; } sp_ecc_verify_256_ctx; -int sp_ecc_verify_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, + word32 hashLen, const mp_int* pX, const mp_int* pY, const mp_int* pZ, + const mp_int* r, const mp_int* sm, int* res, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_verify_256_ctx* ctx = (sp_ecc_verify_256_ctx*)sp_ctx->data; @@ -22479,8 +22975,9 @@ int sp_ecc_verify_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_256(const byte* hash, word32 hashLen, const mp_int* pX, + const mp_int* pY, const mp_int* pZ, const mp_int* r, const mp_int* sm, + int* res, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -22499,7 +22996,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_point_256* p1; sp_point_256* p2 = NULL; sp_digit carry; - int32_t c; + int32_t c = 0; int err; err = sp_256_point_new_8(heap, p1d, p1); @@ -22540,66 +23037,9 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_256_from_mp(p2->y, 8, pY); sp_256_from_mp(p2->z, 8, pZ); -#ifndef WOLFSSL_SP_SMALL - { - sp_256_mod_inv_8(s, s, p256_order); - } -#endif /* !WOLFSSL_SP_SMALL */ - { - sp_256_mul_8(s, s, p256_norm_order); - } - err = sp_256_mod_8(s, s, p256_order); + err = sp_256_calc_vfy_point_8(p1, p2, s, u1, u2, tmp, heap); } if (err == MP_OKAY) { - sp_256_norm_8(s); -#ifdef WOLFSSL_SP_SMALL - { - sp_256_mont_inv_order_8(s, s, tmp); - sp_256_mont_mul_order_8(u1, u1, s); - sp_256_mont_mul_order_8(u2, u2, s); - } - -#else - { - sp_256_mont_mul_order_8(u1, u1, s); - sp_256_mont_mul_order_8(u2, u2, s); - } - -#endif /* WOLFSSL_SP_SMALL */ - err = sp_256_ecc_mulmod_base_8(p1, u1, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_256_iszero_8(p1->z)) { - p1->infinity = 1; - } - if (err == MP_OKAY) { - err = sp_256_ecc_mulmod_8(p2, p2, u2, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_256_iszero_8(p2->z)) { - p2->infinity = 1; - } - - if (err == MP_OKAY) { - { - sp_256_proj_point_add_8(p1, p1, p2, tmp); - if (sp_256_iszero_8(p1->z)) { - if (sp_256_iszero_8(p1->x) && sp_256_iszero_8(p1->y)) { - sp_256_proj_point_dbl_8(p1, p2, tmp); - } - else { - /* Y ordinate is not used from here - don't set. */ - p1->x[0] = 0; - p1->x[1] = 0; - p1->x[2] = 0; - p1->x[3] = 0; - p1->x[4] = 0; - p1->x[5] = 0; - p1->x[6] = 0; - p1->x[7] = 0; - XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod)); - } - } - } - /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */ /* Reload r and convert to Montgomery form. */ sp_256_from_mp(u2, 8, r); @@ -22621,16 +23061,16 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, /* Compare with mod and if greater or equal then not valid. */ c = sp_256_cmp_8(u2, p256_mod); - if (c < 0) { - /* Convert to Montogomery form */ - err = sp_256_mod_mul_norm_8(u2, u2, p256_mod); - if (err == MP_OKAY) { - /* u1 = (r + 1*order).z'.z' mod prime */ - sp_256_mont_mul_8(u1, u2, p1->z, p256_mod, - p256_mp_mod); - *res = (int)(sp_256_cmp_8(p1->x, u1) == 0); - } - } + } + } + if ((*res == 0) && (c < 0)) { + /* Convert to Montogomery form */ + err = sp_256_mod_mul_norm_8(u2, u2, p256_mod); + if (err == MP_OKAY) { + /* u1 = (r + 1*order).z'.z' mod prime */ + sp_256_mont_mul_8(u1, u2, p1->z, p256_mod, + p256_mp_mod); + *res = (sp_256_cmp_8(p1->x, u1) == 0); } } } @@ -22654,7 +23094,8 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -static int sp_256_ecc_is_point_8(sp_point_256* point, void* heap) +static int sp_256_ecc_is_point_8(const sp_point_256* point, + void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -22717,7 +23158,7 @@ static int sp_256_ecc_is_point_8(sp_point_256* point, void* heap) * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) +int sp_ecc_is_point_256(const mp_int* pX, const mp_int* pY) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_256 pubd; @@ -22751,7 +23192,8 @@ int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and * MP_OKAY otherwise. */ -int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) +int sp_ecc_check_key_256(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit privd[8]; @@ -22805,12 +23247,11 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) } } - if (err == MP_OKAY) { - /* Check range of X and Y */ - if (sp_256_cmp_8(pub->x, p256_mod) >= 0 || - sp_256_cmp_8(pub->y, p256_mod) >= 0) { - err = ECC_OUT_OF_RANGE_E; - } + /* Check range of X and Y */ + if ((err == MP_OKAY) && + ((sp_256_cmp_8(pub->x, p256_mod) >= 0) || + (sp_256_cmp_8(pub->y, p256_mod) >= 0))) { + err = ECC_OUT_OF_RANGE_E; } if (err == MP_OKAY) { @@ -22822,12 +23263,10 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Point * order = infinity */ err = sp_256_ecc_mulmod_8(p, pub, p256_order, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is infinity */ - if ((sp_256_iszero_8(p->x) == 0) || - (sp_256_iszero_8(p->y) == 0)) { - err = ECC_INF_E; - } + /* Check result is infinity */ + if ((err == MP_OKAY) && ((sp_256_iszero_8(p->x) == 0) || + (sp_256_iszero_8(p->y) == 0))) { + err = ECC_INF_E; } if (privm) { @@ -22835,12 +23274,11 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Base * private = point */ err = sp_256_ecc_mulmod_base_8(p, priv, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is public key */ - if (sp_256_cmp_8(p->x, pub->x) != 0 || - sp_256_cmp_8(p->y, pub->y) != 0) { - err = ECC_PRIV_KEY_E; - } + /* Check result is public key */ + if ((err == MP_OKAY) && + ((sp_256_cmp_8(p->x, pub->x) != 0) || + (sp_256_cmp_8(p->y, pub->y) != 0))) { + err = ECC_PRIV_KEY_E; } } @@ -23030,7 +23468,7 @@ int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ) sp_256_from_mp(p->y, 8, pY); sp_256_from_mp(p->z, 8, pZ); - sp_256_map_8(p, p, tmp); + sp_256_map_8(p, p, tmp); } if (err == MP_OKAY) { @@ -23210,9 +23648,13 @@ int sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym) /* Point structure to use. */ typedef struct sp_point_384 { + /* X ordinate of point. */ sp_digit x[2 * 12]; + /* Y ordinate of point. */ sp_digit y[2 * 12]; + /* Z ordinate of point. */ sp_digit z[2 * 12]; + /* Indicates point is at infinity. */ int infinity; } sp_point_384; @@ -23282,336 +23724,6 @@ static const sp_digit p384_b[12] = { }; #endif -static int sp_384_point_new_ex_12(void* heap, sp_point_384* sp, sp_point_384** p) -{ - int ret = MP_OKAY; - (void)heap; -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - (void)sp; - *p = (sp_point_384*)XMALLOC(sizeof(sp_point_384), heap, DYNAMIC_TYPE_ECC); -#else - *p = sp; -#endif - if (*p == NULL) { - ret = MEMORY_E; - } - return ret; -} - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) -/* Allocate memory for point and return error. */ -#define sp_384_point_new_12(heap, sp, p) sp_384_point_new_ex_12((heap), NULL, &(p)) -#else -/* Set pointer to data and return no error. */ -#define sp_384_point_new_12(heap, sp, p) sp_384_point_new_ex_12((heap), &(sp), &(p)) -#endif - - -static void sp_384_point_free_12(sp_point_384* p, int clear, void* heap) -{ -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) -/* If valid pointer then clear point data if requested and free data. */ - if (p != NULL) { - if (clear != 0) { - XMEMSET(p, 0, sizeof(*p)); - } - XFREE(p, heap, DYNAMIC_TYPE_ECC); - } -#else -/* Clear point data if requested. */ - if (clear != 0) { - XMEMSET(p, 0, sizeof(*p)); - } -#endif - (void)heap; -} - -/* Multiply a number by Montogmery normalizer mod modulus (prime). - * - * r The resulting Montgomery form number. - * a The number to convert. - * m The modulus (prime). - * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. - */ -static int sp_384_mod_mul_norm_12(sp_digit* r, const sp_digit* a, const sp_digit* m) -{ -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - int64_t* t; -#else - int64_t t[12]; -#endif - int64_t o; - int err = MP_OKAY; - - (void)m; - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - t = (int64_t*)XMALLOC(sizeof(int64_t) * 12, NULL, DYNAMIC_TYPE_ECC); - if (t == NULL) { - err = MEMORY_E; - } -#endif - - if (err == MP_OKAY) { - /* 1 0 0 0 0 0 0 0 1 1 0 -1 */ - t[0] = 0 + (uint64_t)a[0] + (uint64_t)a[8] + (uint64_t)a[9] - (uint64_t)a[11]; - /* -1 1 0 0 0 0 0 0 -1 0 1 1 */ - t[1] = 0 - (uint64_t)a[0] + (uint64_t)a[1] - (uint64_t)a[8] + (uint64_t)a[10] + (uint64_t)a[11]; - /* 0 -1 1 0 0 0 0 0 0 -1 0 1 */ - t[2] = 0 - (uint64_t)a[1] + (uint64_t)a[2] - (uint64_t)a[9] + (uint64_t)a[11]; - /* 1 0 -1 1 0 0 0 0 1 1 -1 -1 */ - t[3] = 0 + (uint64_t)a[0] - (uint64_t)a[2] + (uint64_t)a[3] + (uint64_t)a[8] + (uint64_t)a[9] - (uint64_t)a[10] - (uint64_t)a[11]; - /* 1 1 0 -1 1 0 0 0 1 2 1 -2 */ - t[4] = 0 + (uint64_t)a[0] + (uint64_t)a[1] - (uint64_t)a[3] + (uint64_t)a[4] + (uint64_t)a[8] + 2 * (uint64_t)a[9] + (uint64_t)a[10] - 2 * (uint64_t)a[11]; - /* 0 1 1 0 -1 1 0 0 0 1 2 1 */ - t[5] = 0 + (uint64_t)a[1] + (uint64_t)a[2] - (uint64_t)a[4] + (uint64_t)a[5] + (uint64_t)a[9] + 2 * (uint64_t)a[10] + (uint64_t)a[11]; - /* 0 0 1 1 0 -1 1 0 0 0 1 2 */ - t[6] = 0 + (uint64_t)a[2] + (uint64_t)a[3] - (uint64_t)a[5] + (uint64_t)a[6] + (uint64_t)a[10] + 2 * (uint64_t)a[11]; - /* 0 0 0 1 1 0 -1 1 0 0 0 1 */ - t[7] = 0 + (uint64_t)a[3] + (uint64_t)a[4] - (uint64_t)a[6] + (uint64_t)a[7] + (uint64_t)a[11]; - /* 0 0 0 0 1 1 0 -1 1 0 0 0 */ - t[8] = 0 + (uint64_t)a[4] + (uint64_t)a[5] - (uint64_t)a[7] + (uint64_t)a[8]; - /* 0 0 0 0 0 1 1 0 -1 1 0 0 */ - t[9] = 0 + (uint64_t)a[5] + (uint64_t)a[6] - (uint64_t)a[8] + (uint64_t)a[9]; - /* 0 0 0 0 0 0 1 1 0 -1 1 0 */ - t[10] = 0 + (uint64_t)a[6] + (uint64_t)a[7] - (uint64_t)a[9] + (uint64_t)a[10]; - /* 0 0 0 0 0 0 0 1 1 0 -1 1 */ - t[11] = 0 + (uint64_t)a[7] + (uint64_t)a[8] - (uint64_t)a[10] + (uint64_t)a[11]; - - t[1] += t[0] >> 32; t[0] &= 0xffffffff; - t[2] += t[1] >> 32; t[1] &= 0xffffffff; - t[3] += t[2] >> 32; t[2] &= 0xffffffff; - t[4] += t[3] >> 32; t[3] &= 0xffffffff; - t[5] += t[4] >> 32; t[4] &= 0xffffffff; - t[6] += t[5] >> 32; t[5] &= 0xffffffff; - t[7] += t[6] >> 32; t[6] &= 0xffffffff; - t[8] += t[7] >> 32; t[7] &= 0xffffffff; - t[9] += t[8] >> 32; t[8] &= 0xffffffff; - t[10] += t[9] >> 32; t[9] &= 0xffffffff; - t[11] += t[10] >> 32; t[10] &= 0xffffffff; - o = t[11] >> 32; t[11] &= 0xffffffff; - t[0] += o; - t[1] -= o; - t[3] += o; - t[4] += o; - t[1] += t[0] >> 32; t[0] &= 0xffffffff; - t[2] += t[1] >> 32; t[1] &= 0xffffffff; - t[3] += t[2] >> 32; t[2] &= 0xffffffff; - t[4] += t[3] >> 32; t[3] &= 0xffffffff; - t[5] += t[4] >> 32; t[4] &= 0xffffffff; - t[6] += t[5] >> 32; t[5] &= 0xffffffff; - t[7] += t[6] >> 32; t[6] &= 0xffffffff; - t[8] += t[7] >> 32; t[7] &= 0xffffffff; - t[9] += t[8] >> 32; t[8] &= 0xffffffff; - t[10] += t[9] >> 32; t[9] &= 0xffffffff; - t[11] += t[10] >> 32; t[10] &= 0xffffffff; - - r[0] = t[0]; - r[1] = t[1]; - r[2] = t[2]; - r[3] = t[3]; - r[4] = t[4]; - r[5] = t[5]; - r[6] = t[6]; - r[7] = t[7]; - r[8] = t[8]; - r[9] = t[9]; - r[10] = t[10]; - r[11] = t[11]; - } - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - if (t != NULL) - XFREE(t, NULL, DYNAMIC_TYPE_ECC); -#endif - - return err; -} - -/* Convert an mp_int to an array of sp_digit. - * - * r A single precision integer. - * size Maximum number of bytes to convert - * a A multi-precision integer. - */ -static void sp_384_from_mp(sp_digit* r, int size, const mp_int* a) -{ -#if DIGIT_BIT == 32 - int j; - - XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); - - for (j = a->used; j < size; j++) { - r[j] = 0; - } -#elif DIGIT_BIT > 32 - int i, j = 0; - word32 s = 0; - - r[0] = 0; - for (i = 0; i < a->used && j < size; i++) { - r[j] |= ((sp_digit)a->dp[i] << s); - r[j] &= 0xffffffff; - s = 32U - s; - if (j + 1 >= size) { - break; - } - /* lint allow cast of mismatch word32 and mp_digit */ - r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ - while ((s + 32U) <= (word32)DIGIT_BIT) { - s += 32U; - r[j] &= 0xffffffff; - if (j + 1 >= size) { - break; - } - if (s < (word32)DIGIT_BIT) { - /* lint allow cast of mismatch word32 and mp_digit */ - r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ - } - else { - r[++j] = 0L; - } - } - s = (word32)DIGIT_BIT - s; - } - - for (j++; j < size; j++) { - r[j] = 0; - } -#else - int i, j = 0, s = 0; - - r[0] = 0; - for (i = 0; i < a->used && j < size; i++) { - r[j] |= ((sp_digit)a->dp[i]) << s; - if (s + DIGIT_BIT >= 32) { - r[j] &= 0xffffffff; - if (j + 1 >= size) { - break; - } - s = 32 - s; - if (s == DIGIT_BIT) { - r[++j] = 0; - s = 0; - } - else { - r[++j] = a->dp[i] >> s; - s = DIGIT_BIT - s; - } - } - else { - s += DIGIT_BIT; - } - } - - for (j++; j < size; j++) { - r[j] = 0; - } -#endif -} - -/* Convert a point of type ecc_point to type sp_point_384. - * - * p Point of type sp_point_384 (result). - * pm Point of type ecc_point. - */ -static void sp_384_point_from_ecc_point_12(sp_point_384* p, const ecc_point* pm) -{ - XMEMSET(p->x, 0, sizeof(p->x)); - XMEMSET(p->y, 0, sizeof(p->y)); - XMEMSET(p->z, 0, sizeof(p->z)); - sp_384_from_mp(p->x, 12, pm->x); - sp_384_from_mp(p->y, 12, pm->y); - sp_384_from_mp(p->z, 12, pm->z); - p->infinity = 0; -} - -/* Convert an array of sp_digit to an mp_int. - * - * a A single precision integer. - * r A multi-precision integer. - */ -static int sp_384_to_mp(const sp_digit* a, mp_int* r) -{ - int err; - - err = mp_grow(r, (384 + DIGIT_BIT - 1) / DIGIT_BIT); - if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ -#if DIGIT_BIT == 32 - XMEMCPY(r->dp, a, sizeof(sp_digit) * 12); - r->used = 12; - mp_clamp(r); -#elif DIGIT_BIT < 32 - int i, j = 0, s = 0; - - r->dp[0] = 0; - for (i = 0; i < 12; i++) { - r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; - s = DIGIT_BIT - s; - r->dp[++j] = (mp_digit)(a[i] >> s); - while (s + DIGIT_BIT <= 32) { - s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; - if (s == SP_WORD_SIZE) { - r->dp[j] = 0; - } - else { - r->dp[j] = (mp_digit)(a[i] >> s); - } - } - s = 32 - s; - } - r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; - mp_clamp(r); -#else - int i, j = 0, s = 0; - - r->dp[0] = 0; - for (i = 0; i < 12; i++) { - r->dp[j] |= ((mp_digit)a[i]) << s; - if (s + 32 >= DIGIT_BIT) { - #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; - #endif - s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; - s = 32 - s; - } - else { - s += 32; - } - } - r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; - mp_clamp(r); -#endif - } - - return err; -} - -/* Convert a point of type sp_point_384 to type ecc_point. - * - * p Point of type sp_point_384. - * pm Point of type ecc_point (result). - * returns MEMORY_E when allocation of memory in ecc_point fails otherwise - * MP_OKAY. - */ -static int sp_384_point_to_ecc_point_12(const sp_point_384* p, ecc_point* pm) -{ - int err; - - err = sp_384_to_mp(p->x, pm->x); - if (err == MP_OKAY) { - err = sp_384_to_mp(p->y, pm->y); - } - if (err == MP_OKAY) { - err = sp_384_to_mp(p->z, pm->z); - } - - return err; -} - /* Multiply a and b into r. (r = a * b) * * r A single precision integer. @@ -23712,6 +23824,723 @@ SP_NOINLINE static void sp_384_mul_12(sp_digit* r, const sp_digit* a, XMEMCPY(r, tmp, sizeof(tmp)); } +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_384_sqr_12(sp_digit* r, const sp_digit* a) +{ + __asm__ __volatile__ ( + "mov r3, #0\n\t" + "mov r4, #0\n\t" + "mov r5, #0\n\t" + "mov r8, r3\n\t" + "mov r11, %[r]\n\t" + "mov r6, #96\n\t" + "neg r6, r6\n\t" + "add sp, r6\n\t" + "mov r10, sp\n\t" + "mov r9, %[a]\n\t" + "\n1:\n\t" + "mov %[r], #0\n\t" + "mov r6, #44\n\t" + "mov %[a], r8\n\t" + "sub %[a], r6\n\t" + "sbc r6, r6\n\t" + "mvn r6, r6\n\t" + "and %[a], r6\n\t" + "mov r2, r8\n\t" + "sub r2, %[a]\n\t" + "add %[a], r9\n\t" + "add r2, r9\n\t" + "\n2:\n\t" + "cmp r2, %[a]\n\t" + "beq 4f\n\t" + "# Multiply * 2: Start\n\t" + "ldr r6, [%[a]]\n\t" + "ldr r7, [r2]\n\t" + "lsl r6, r6, #16\n\t" + "lsl r7, r7, #16\n\t" + "lsr r6, r6, #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r7, r6\n\t" + "add r3, r7\n\t" + "adc r4, %[r]\n\t" + "adc r5, %[r]\n\t" + "add r3, r7\n\t" + "adc r4, %[r]\n\t" + "adc r5, %[r]\n\t" + "ldr r7, [r2]\n\t" + "lsr r7, r7, #16\n\t" + "mul r6, r7\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "ldr r6, [%[a]]\n\t" + "ldr r7, [r2]\n\t" + "lsr r6, r6, #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r7, r6\n\t" + "add r4, r7\n\t" + "adc r5, %[r]\n\t" + "add r4, r7\n\t" + "adc r5, %[r]\n\t" + "ldr r7, [r2]\n\t" + "lsl r7, r7, #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r6, r7\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "# Multiply * 2: Done\n\t" + "bal 5f\n\t" + "\n4:\n\t" + "# Square: Start\n\t" + "ldr r6, [%[a]]\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "lsr r6, r6, #16\n\t" + "mul r6, r6\n\t" + "add r3, r6\n\t" + "adc r4, %[r]\n\t" + "adc r5, %[r]\n\t" + "mul r7, r7\n\t" + "add r4, r7\n\t" + "adc r5, %[r]\n\t" + "ldr r6, [%[a]]\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "lsr r6, r6, #16\n\t" + "mul r6, r7\n\t" + "lsr r7, r6, #15\n\t" + "lsl r6, r6, #17\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "# Square: Done\n\t" + "\n5:\n\t" + "add %[a], #4\n\t" + "sub r2, #4\n\t" + "mov r6, #48\n\t" + "add r6, r9\n\t" + "cmp %[a], r6\n\t" + "beq 3f\n\t" + "cmp %[a], r2\n\t" + "bgt 3f\n\t" + "mov r7, r8\n\t" + "add r7, r9\n\t" + "cmp %[a], r7\n\t" + "ble 2b\n\t" + "\n3:\n\t" + "mov %[r], r10\n\t" + "mov r7, r8\n\t" + "str r3, [%[r], r7]\n\t" + "mov r3, r4\n\t" + "mov r4, r5\n\t" + "mov r5, #0\n\t" + "add r7, #4\n\t" + "mov r8, r7\n\t" + "mov r6, #88\n\t" + "cmp r7, r6\n\t" + "ble 1b\n\t" + "mov %[a], r9\n\t" + "str r3, [%[r], r7]\n\t" + "mov %[r], r11\n\t" + "mov %[a], r10\n\t" + "mov r3, #92\n\t" + "\n4:\n\t" + "ldr r6, [%[a], r3]\n\t" + "str r6, [%[r], r3]\n\t" + "sub r3, #4\n\t" + "bge 4b\n\t" + "mov r6, #96\n\t" + "add sp, r6\n\t" + : + : [r] "r" (r), [a] "r" (a) + : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" + ); +} + +#ifdef WOLFSSL_SP_SMALL +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_384_add_12(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r6, %[a]\n\t" + "mov r7, #0\n\t" + "add r6, #48\n\t" + "sub r7, #1\n\t" + "\n1:\n\t" + "add %[c], r7\n\t" + "ldr r4, [%[a]]\n\t" + "ldr r5, [%[b]]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r]]\n\t" + "mov %[c], #0\n\t" + "adc %[c], %[c]\n\t" + "add %[a], #4\n\t" + "add %[b], #4\n\t" + "add %[r], #4\n\t" + "cmp %[a], r6\n\t" + "bne 1b\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6", "r7" + ); + + return c; +} + +#else +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_384_add_12(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldr r4, [%[a], #0]\n\t" + "ldr r5, [%[b], #0]\n\t" + "add r4, r5\n\t" + "str r4, [%[r], #0]\n\t" + "ldr r4, [%[a], #4]\n\t" + "ldr r5, [%[b], #4]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #4]\n\t" + "ldr r4, [%[a], #8]\n\t" + "ldr r5, [%[b], #8]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #8]\n\t" + "ldr r4, [%[a], #12]\n\t" + "ldr r5, [%[b], #12]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #12]\n\t" + "ldr r4, [%[a], #16]\n\t" + "ldr r5, [%[b], #16]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #16]\n\t" + "ldr r4, [%[a], #20]\n\t" + "ldr r5, [%[b], #20]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #20]\n\t" + "ldr r4, [%[a], #24]\n\t" + "ldr r5, [%[b], #24]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #24]\n\t" + "ldr r4, [%[a], #28]\n\t" + "ldr r5, [%[b], #28]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #28]\n\t" + "ldr r4, [%[a], #32]\n\t" + "ldr r5, [%[b], #32]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #32]\n\t" + "ldr r4, [%[a], #36]\n\t" + "ldr r5, [%[b], #36]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #36]\n\t" + "ldr r4, [%[a], #40]\n\t" + "ldr r5, [%[b], #40]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #40]\n\t" + "ldr r4, [%[a], #44]\n\t" + "ldr r5, [%[b], #44]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #44]\n\t" + "mov %[c], #0\n\t" + "adc %[c], %[c]\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5" + ); + + return c; +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_384_sub_12(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r6, %[a]\n\t" + "add r6, #48\n\t" + "\n1:\n\t" + "mov r5, #0\n\t" + "sub r5, %[c]\n\t" + "ldr r4, [%[a]]\n\t" + "ldr r5, [%[b]]\n\t" + "sbc r4, r5\n\t" + "str r4, [%[r]]\n\t" + "sbc %[c], %[c]\n\t" + "add %[a], #4\n\t" + "add %[b], #4\n\t" + "add %[r], #4\n\t" + "cmp %[a], r6\n\t" + "bne 1b\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6" + ); + + return c; +} + +#else +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_384_sub_12(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldr r4, [%[a], #0]\n\t" + "ldr r5, [%[a], #4]\n\t" + "ldr r6, [%[b], #0]\n\t" + "ldr r7, [%[b], #4]\n\t" + "sub r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #0]\n\t" + "str r5, [%[r], #4]\n\t" + "ldr r4, [%[a], #8]\n\t" + "ldr r5, [%[a], #12]\n\t" + "ldr r6, [%[b], #8]\n\t" + "ldr r7, [%[b], #12]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #8]\n\t" + "str r5, [%[r], #12]\n\t" + "ldr r4, [%[a], #16]\n\t" + "ldr r5, [%[a], #20]\n\t" + "ldr r6, [%[b], #16]\n\t" + "ldr r7, [%[b], #20]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #16]\n\t" + "str r5, [%[r], #20]\n\t" + "ldr r4, [%[a], #24]\n\t" + "ldr r5, [%[a], #28]\n\t" + "ldr r6, [%[b], #24]\n\t" + "ldr r7, [%[b], #28]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #24]\n\t" + "str r5, [%[r], #28]\n\t" + "ldr r4, [%[a], #32]\n\t" + "ldr r5, [%[a], #36]\n\t" + "ldr r6, [%[b], #32]\n\t" + "ldr r7, [%[b], #36]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #32]\n\t" + "str r5, [%[r], #36]\n\t" + "ldr r4, [%[a], #40]\n\t" + "ldr r5, [%[a], #44]\n\t" + "ldr r6, [%[b], #40]\n\t" + "ldr r7, [%[b], #44]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #40]\n\t" + "str r5, [%[r], #44]\n\t" + "sbc %[c], %[c]\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6", "r7" + ); + + return c; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Create a new point. + * + * heap [in] Buffer to allocate dynamic memory from. + * sp [in] Data for point - only if not allocating. + * p [out] New point. + * returns MEMORY_E when dynamic memory allocation fails and 0 otherwise. + */ +static int sp_384_point_new_ex_12(void* heap, sp_point_384* sp, + sp_point_384** p) +{ + int ret = MP_OKAY; + (void)heap; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + (void)sp; + *p = (sp_point_384*)XMALLOC(sizeof(sp_point_384), heap, DYNAMIC_TYPE_ECC); +#else + *p = sp; +#endif + if (*p == NULL) { + ret = MEMORY_E; + } + return ret; +} + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* Allocate memory for point and return error. */ +#define sp_384_point_new_12(heap, sp, p) sp_384_point_new_ex_12((heap), NULL, &(p)) +#else +/* Set pointer to data and return no error. */ +#define sp_384_point_new_12(heap, sp, p) sp_384_point_new_ex_12((heap), &(sp), &(p)) +#endif + + +/* Free the point. + * + * p [in,out] Point to free. + * clear [in] Indicates whether to zeroize point. + * heap [in] Buffer from which dynamic memory was allocate from. + */ +static void sp_384_point_free_12(sp_point_384* p, int clear, void* heap) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* If valid pointer then clear point data if requested and free data. */ + if (p != NULL) { + if (clear != 0) { + XMEMSET(p, 0, sizeof(*p)); + } + XFREE(p, heap, DYNAMIC_TYPE_ECC); + } +#else +/* Clear point data if requested. */ + if ((p != NULL) && (clear != 0)) { + XMEMSET(p, 0, sizeof(*p)); + } +#endif + (void)heap; +} + +/* Multiply a number by Montogmery normalizer mod modulus (prime). + * + * r The resulting Montgomery form number. + * a The number to convert. + * m The modulus (prime). + * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. + */ +static int sp_384_mod_mul_norm_12(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + int64_t* t; +#else + int64_t t[12]; +#endif + int64_t o; + int err = MP_OKAY; + + (void)m; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = (int64_t*)XMALLOC(sizeof(int64_t) * 12, NULL, DYNAMIC_TYPE_ECC); + if (t == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { + /* 1 0 0 0 0 0 0 0 1 1 0 -1 */ + t[0] = 0 + (int64_t)a[0] + (int64_t)a[8] + (int64_t)a[9] - (int64_t)a[11]; + /* -1 1 0 0 0 0 0 0 -1 0 1 1 */ + t[1] = 0 - (int64_t)a[0] + (int64_t)a[1] - (int64_t)a[8] + (int64_t)a[10] + (int64_t)a[11]; + /* 0 -1 1 0 0 0 0 0 0 -1 0 1 */ + t[2] = 0 - (int64_t)a[1] + (int64_t)a[2] - (int64_t)a[9] + (int64_t)a[11]; + /* 1 0 -1 1 0 0 0 0 1 1 -1 -1 */ + t[3] = 0 + (int64_t)a[0] - (int64_t)a[2] + (int64_t)a[3] + (int64_t)a[8] + (int64_t)a[9] - (int64_t)a[10] - (int64_t)a[11]; + /* 1 1 0 -1 1 0 0 0 1 2 1 -2 */ + t[4] = 0 + (int64_t)a[0] + (int64_t)a[1] - (int64_t)a[3] + (int64_t)a[4] + (int64_t)a[8] + 2 * (int64_t)a[9] + (int64_t)a[10] - 2 * (int64_t)a[11]; + /* 0 1 1 0 -1 1 0 0 0 1 2 1 */ + t[5] = 0 + (int64_t)a[1] + (int64_t)a[2] - (int64_t)a[4] + (int64_t)a[5] + (int64_t)a[9] + 2 * (int64_t)a[10] + (int64_t)a[11]; + /* 0 0 1 1 0 -1 1 0 0 0 1 2 */ + t[6] = 0 + (int64_t)a[2] + (int64_t)a[3] - (int64_t)a[5] + (int64_t)a[6] + (int64_t)a[10] + 2 * (int64_t)a[11]; + /* 0 0 0 1 1 0 -1 1 0 0 0 1 */ + t[7] = 0 + (int64_t)a[3] + (int64_t)a[4] - (int64_t)a[6] + (int64_t)a[7] + (int64_t)a[11]; + /* 0 0 0 0 1 1 0 -1 1 0 0 0 */ + t[8] = 0 + (int64_t)a[4] + (int64_t)a[5] - (int64_t)a[7] + (int64_t)a[8]; + /* 0 0 0 0 0 1 1 0 -1 1 0 0 */ + t[9] = 0 + (int64_t)a[5] + (int64_t)a[6] - (int64_t)a[8] + (int64_t)a[9]; + /* 0 0 0 0 0 0 1 1 0 -1 1 0 */ + t[10] = 0 + (int64_t)a[6] + (int64_t)a[7] - (int64_t)a[9] + (int64_t)a[10]; + /* 0 0 0 0 0 0 0 1 1 0 -1 1 */ + t[11] = 0 + (int64_t)a[7] + (int64_t)a[8] - (int64_t)a[10] + (int64_t)a[11]; + + t[1] += t[0] >> 32; t[0] &= 0xffffffff; + t[2] += t[1] >> 32; t[1] &= 0xffffffff; + t[3] += t[2] >> 32; t[2] &= 0xffffffff; + t[4] += t[3] >> 32; t[3] &= 0xffffffff; + t[5] += t[4] >> 32; t[4] &= 0xffffffff; + t[6] += t[5] >> 32; t[5] &= 0xffffffff; + t[7] += t[6] >> 32; t[6] &= 0xffffffff; + t[8] += t[7] >> 32; t[7] &= 0xffffffff; + t[9] += t[8] >> 32; t[8] &= 0xffffffff; + t[10] += t[9] >> 32; t[9] &= 0xffffffff; + t[11] += t[10] >> 32; t[10] &= 0xffffffff; + o = t[11] >> 32; t[11] &= 0xffffffff; + t[0] += o; + t[1] -= o; + t[3] += o; + t[4] += o; + t[1] += t[0] >> 32; t[0] &= 0xffffffff; + t[2] += t[1] >> 32; t[1] &= 0xffffffff; + t[3] += t[2] >> 32; t[2] &= 0xffffffff; + t[4] += t[3] >> 32; t[3] &= 0xffffffff; + t[5] += t[4] >> 32; t[4] &= 0xffffffff; + t[6] += t[5] >> 32; t[5] &= 0xffffffff; + t[7] += t[6] >> 32; t[6] &= 0xffffffff; + t[8] += t[7] >> 32; t[7] &= 0xffffffff; + t[9] += t[8] >> 32; t[8] &= 0xffffffff; + t[10] += t[9] >> 32; t[9] &= 0xffffffff; + t[11] += t[10] >> 32; t[10] &= 0xffffffff; + + r[0] = t[0]; + r[1] = t[1]; + r[2] = t[2]; + r[3] = t[3]; + r[4] = t[4]; + r[5] = t[5]; + r[6] = t[6]; + r[7] = t[7]; + r[8] = t[8]; + r[9] = t[9]; + r[10] = t[10]; + r[11] = t[11]; + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (t != NULL) + XFREE(t, NULL, DYNAMIC_TYPE_ECC); +#endif + + return err; +} + +/* Convert an mp_int to an array of sp_digit. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a A multi-precision integer. + */ +static void sp_384_from_mp(sp_digit* r, int size, const mp_int* a) +{ +#if DIGIT_BIT == 32 + int j; + + XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); + + for (j = a->used; j < size; j++) { + r[j] = 0; + } +#elif DIGIT_BIT > 32 + int i; + int j = 0; + word32 s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i] << s); + r[j] &= 0xffffffff; + s = 32U - s; + if (j + 1 >= size) { + break; + } + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + while ((s + 32U) <= (word32)DIGIT_BIT) { + s += 32U; + r[j] &= 0xffffffff; + if (j + 1 >= size) { + break; + } + if (s < (word32)DIGIT_BIT) { + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + } + else { + r[++j] = 0L; + } + } + s = (word32)DIGIT_BIT - s; + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#else + int i; + int j = 0; + int s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i]) << s; + if (s + DIGIT_BIT >= 32) { + r[j] &= 0xffffffff; + if (j + 1 >= size) { + break; + } + s = 32 - s; + if (s == DIGIT_BIT) { + r[++j] = 0; + s = 0; + } + else { + r[++j] = a->dp[i] >> s; + s = DIGIT_BIT - s; + } + } + else { + s += DIGIT_BIT; + } + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#endif +} + +/* Convert a point of type ecc_point to type sp_point_384. + * + * p Point of type sp_point_384 (result). + * pm Point of type ecc_point. + */ +static void sp_384_point_from_ecc_point_12(sp_point_384* p, + const ecc_point* pm) +{ + XMEMSET(p->x, 0, sizeof(p->x)); + XMEMSET(p->y, 0, sizeof(p->y)); + XMEMSET(p->z, 0, sizeof(p->z)); + sp_384_from_mp(p->x, 12, pm->x); + sp_384_from_mp(p->y, 12, pm->y); + sp_384_from_mp(p->z, 12, pm->z); + p->infinity = 0; +} + +/* Convert an array of sp_digit to an mp_int. + * + * a A single precision integer. + * r A multi-precision integer. + */ +static int sp_384_to_mp(const sp_digit* a, mp_int* r) +{ + int err; + + err = mp_grow(r, (384 + DIGIT_BIT - 1) / DIGIT_BIT); + if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ +#if DIGIT_BIT == 32 + XMEMCPY(r->dp, a, sizeof(sp_digit) * 12); + r->used = 12; + mp_clamp(r); +#elif DIGIT_BIT < 32 + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 12; i++) { + r->dp[j] |= (mp_digit)(a[i] << s); + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + s = DIGIT_BIT - s; + r->dp[++j] = (mp_digit)(a[i] >> s); + while (s + DIGIT_BIT <= 32) { + s += DIGIT_BIT; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; + if (s == SP_WORD_SIZE) { + r->dp[j] = 0; + } + else { + r->dp[j] = (mp_digit)(a[i] >> s); + } + } + s = 32 - s; + } + r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#else + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 12; i++) { + r->dp[j] |= ((mp_digit)a[i]) << s; + if (s + 32 >= DIGIT_BIT) { + #if DIGIT_BIT != 32 && DIGIT_BIT != 64 + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + #endif + s = DIGIT_BIT - s; + r->dp[++j] = a[i] >> s; + s = 32 - s; + } + else { + s += 32; + } + } + r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#endif + } + + return err; +} + +/* Convert a point of type sp_point_384 to type ecc_point. + * + * p Point of type sp_point_384. + * pm Point of type ecc_point (result). + * returns MEMORY_E when allocation of memory in ecc_point fails otherwise + * MP_OKAY. + */ +static int sp_384_point_to_ecc_point_12(const sp_point_384* p, ecc_point* pm) +{ + int err; + + err = sp_384_to_mp(p->x, pm->x); + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, pm->y); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, pm->z); + } + + return err; +} + /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -23903,161 +24732,13 @@ SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_384_mont_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_384_mont_mul_12(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_384_mul_12(r, a, b); sp_384_mont_reduce_12(r, m, mp); } -/* Square a and put result in r. (r = a * a) - * - * r A single precision integer. - * a A single precision integer. - */ -SP_NOINLINE static void sp_384_sqr_12(sp_digit* r, const sp_digit* a) -{ - __asm__ __volatile__ ( - "mov r3, #0\n\t" - "mov r4, #0\n\t" - "mov r5, #0\n\t" - "mov r8, r3\n\t" - "mov r11, %[r]\n\t" - "mov r6, #96\n\t" - "neg r6, r6\n\t" - "add sp, r6\n\t" - "mov r10, sp\n\t" - "mov r9, %[a]\n\t" - "\n1:\n\t" - "mov %[r], #0\n\t" - "mov r6, #44\n\t" - "mov %[a], r8\n\t" - "sub %[a], r6\n\t" - "sbc r6, r6\n\t" - "mvn r6, r6\n\t" - "and %[a], r6\n\t" - "mov r2, r8\n\t" - "sub r2, %[a]\n\t" - "add %[a], r9\n\t" - "add r2, r9\n\t" - "\n2:\n\t" - "cmp r2, %[a]\n\t" - "beq 4f\n\t" - "# Multiply * 2: Start\n\t" - "ldr r6, [%[a]]\n\t" - "ldr r7, [r2]\n\t" - "lsl r6, r6, #16\n\t" - "lsl r7, r7, #16\n\t" - "lsr r6, r6, #16\n\t" - "lsr r7, r7, #16\n\t" - "mul r7, r6\n\t" - "add r3, r7\n\t" - "adc r4, %[r]\n\t" - "adc r5, %[r]\n\t" - "add r3, r7\n\t" - "adc r4, %[r]\n\t" - "adc r5, %[r]\n\t" - "ldr r7, [r2]\n\t" - "lsr r7, r7, #16\n\t" - "mul r6, r7\n\t" - "lsr r7, r6, #16\n\t" - "lsl r6, r6, #16\n\t" - "add r3, r6\n\t" - "adc r4, r7\n\t" - "adc r5, %[r]\n\t" - "add r3, r6\n\t" - "adc r4, r7\n\t" - "adc r5, %[r]\n\t" - "ldr r6, [%[a]]\n\t" - "ldr r7, [r2]\n\t" - "lsr r6, r6, #16\n\t" - "lsr r7, r7, #16\n\t" - "mul r7, r6\n\t" - "add r4, r7\n\t" - "adc r5, %[r]\n\t" - "add r4, r7\n\t" - "adc r5, %[r]\n\t" - "ldr r7, [r2]\n\t" - "lsl r7, r7, #16\n\t" - "lsr r7, r7, #16\n\t" - "mul r6, r7\n\t" - "lsr r7, r6, #16\n\t" - "lsl r6, r6, #16\n\t" - "add r3, r6\n\t" - "adc r4, r7\n\t" - "adc r5, %[r]\n\t" - "add r3, r6\n\t" - "adc r4, r7\n\t" - "adc r5, %[r]\n\t" - "# Multiply * 2: Done\n\t" - "bal 5f\n\t" - "\n4:\n\t" - "# Square: Start\n\t" - "ldr r6, [%[a]]\n\t" - "lsr r7, r6, #16\n\t" - "lsl r6, r6, #16\n\t" - "lsr r6, r6, #16\n\t" - "mul r6, r6\n\t" - "add r3, r6\n\t" - "adc r4, %[r]\n\t" - "adc r5, %[r]\n\t" - "mul r7, r7\n\t" - "add r4, r7\n\t" - "adc r5, %[r]\n\t" - "ldr r6, [%[a]]\n\t" - "lsr r7, r6, #16\n\t" - "lsl r6, r6, #16\n\t" - "lsr r6, r6, #16\n\t" - "mul r6, r7\n\t" - "lsr r7, r6, #15\n\t" - "lsl r6, r6, #17\n\t" - "add r3, r6\n\t" - "adc r4, r7\n\t" - "adc r5, %[r]\n\t" - "# Square: Done\n\t" - "\n5:\n\t" - "add %[a], #4\n\t" - "sub r2, #4\n\t" - "mov r6, #48\n\t" - "add r6, r9\n\t" - "cmp %[a], r6\n\t" - "beq 3f\n\t" - "cmp %[a], r2\n\t" - "bgt 3f\n\t" - "mov r7, r8\n\t" - "add r7, r9\n\t" - "cmp %[a], r7\n\t" - "ble 2b\n\t" - "\n3:\n\t" - "mov %[r], r10\n\t" - "mov r7, r8\n\t" - "str r3, [%[r], r7]\n\t" - "mov r3, r4\n\t" - "mov r4, r5\n\t" - "mov r5, #0\n\t" - "add r7, #4\n\t" - "mov r8, r7\n\t" - "mov r6, #88\n\t" - "cmp r7, r6\n\t" - "ble 1b\n\t" - "mov %[a], r9\n\t" - "str r3, [%[r], r7]\n\t" - "mov %[r], r11\n\t" - "mov %[a], r10\n\t" - "mov r3, #92\n\t" - "\n4:\n\t" - "ldr r6, [%[a], r3]\n\t" - "str r6, [%[r], r3]\n\t" - "sub r3, #4\n\t" - "bge 4b\n\t" - "mov r6, #96\n\t" - "add sp, r6\n\t" - : - : [r] "r" (r), [a] "r" (a) - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" - ); -} - /* Square the Montgomery form number. (r = a * a mod m) * * r Result of squaring. @@ -24065,8 +24746,8 @@ SP_NOINLINE static void sp_384_sqr_12(sp_digit* r, const sp_digit* a) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_384_mont_sqr_12(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_384_mont_sqr_12(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_384_sqr_12(r, a); sp_384_mont_reduce_12(r, m, mp); @@ -24090,7 +24771,7 @@ static void sp_384_mont_sqr_n_12(sp_digit* r, const sp_digit* a, int n, } } -#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */ +#endif /* !WOLFSSL_SP_SMALL | HAVE_COMP_KEY */ #ifdef WOLFSSL_SP_SMALL /* Mod-2 for the P384 curve. */ static const uint32_t p384_mod_minus_2[12] = { @@ -24239,7 +24920,8 @@ SP_NOINLINE static int32_t sp_384_cmp_12(const sp_digit* a, const sp_digit* b) * p Montgomery form projective coordinate point. * t Temporary ordinate data. */ -static void sp_384_map_12(sp_point_384* r, const sp_point_384* p, sp_digit* t) +static void sp_384_map_12(sp_point_384* r, const sp_point_384* p, + sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2*12; @@ -24275,116 +24957,6 @@ static void sp_384_map_12(sp_point_384* r, const sp_point_384* p, sp_digit* t) } -#ifdef WOLFSSL_SP_SMALL -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static sp_digit sp_384_add_12(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "mov r6, %[a]\n\t" - "mov r7, #0\n\t" - "add r6, #48\n\t" - "sub r7, #1\n\t" - "\n1:\n\t" - "add %[c], r7\n\t" - "ldr r4, [%[a]]\n\t" - "ldr r5, [%[b]]\n\t" - "adc r4, r5\n\t" - "str r4, [%[r]]\n\t" - "mov %[c], #0\n\t" - "adc %[c], %[c]\n\t" - "add %[a], #4\n\t" - "add %[b], #4\n\t" - "add %[r], #4\n\t" - "cmp %[a], r6\n\t" - "bne 1b\n\t" - : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) - : - : "memory", "r4", "r5", "r6", "r7" - ); - - return c; -} - -#else -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static sp_digit sp_384_add_12(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "ldr r4, [%[a], #0]\n\t" - "ldr r5, [%[b], #0]\n\t" - "add r4, r5\n\t" - "str r4, [%[r], #0]\n\t" - "ldr r4, [%[a], #4]\n\t" - "ldr r5, [%[b], #4]\n\t" - "adc r4, r5\n\t" - "str r4, [%[r], #4]\n\t" - "ldr r4, [%[a], #8]\n\t" - "ldr r5, [%[b], #8]\n\t" - "adc r4, r5\n\t" - "str r4, [%[r], #8]\n\t" - "ldr r4, [%[a], #12]\n\t" - "ldr r5, [%[b], #12]\n\t" - "adc r4, r5\n\t" - "str r4, [%[r], #12]\n\t" - "ldr r4, [%[a], #16]\n\t" - "ldr r5, [%[b], #16]\n\t" - "adc r4, r5\n\t" - "str r4, [%[r], #16]\n\t" - "ldr r4, [%[a], #20]\n\t" - "ldr r5, [%[b], #20]\n\t" - "adc r4, r5\n\t" - "str r4, [%[r], #20]\n\t" - "ldr r4, [%[a], #24]\n\t" - "ldr r5, [%[b], #24]\n\t" - "adc r4, r5\n\t" - "str r4, [%[r], #24]\n\t" - "ldr r4, [%[a], #28]\n\t" - "ldr r5, [%[b], #28]\n\t" - "adc r4, r5\n\t" - "str r4, [%[r], #28]\n\t" - "ldr r4, [%[a], #32]\n\t" - "ldr r5, [%[b], #32]\n\t" - "adc r4, r5\n\t" - "str r4, [%[r], #32]\n\t" - "ldr r4, [%[a], #36]\n\t" - "ldr r5, [%[b], #36]\n\t" - "adc r4, r5\n\t" - "str r4, [%[r], #36]\n\t" - "ldr r4, [%[a], #40]\n\t" - "ldr r5, [%[b], #40]\n\t" - "adc r4, r5\n\t" - "str r4, [%[r], #40]\n\t" - "ldr r4, [%[a], #44]\n\t" - "ldr r5, [%[b], #44]\n\t" - "adc r4, r5\n\t" - "str r4, [%[r], #44]\n\t" - "mov %[c], #0\n\t" - "adc %[c], %[c]\n\t" - : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) - : - : "memory", "r4", "r5" - ); - - return c; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Add two Montgomery form numbers (r = a + b % m). * * r Result of addition. @@ -24431,113 +25003,6 @@ SP_NOINLINE static void sp_384_mont_tpl_12(sp_digit* r, const sp_digit* a, const sp_384_cond_sub_12(r, r, m, 0 - o); } -#ifdef WOLFSSL_SP_SMALL -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static sp_digit sp_384_sub_12(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "mov r6, %[a]\n\t" - "add r6, #48\n\t" - "\n1:\n\t" - "mov r5, #0\n\t" - "sub r5, %[c]\n\t" - "ldr r4, [%[a]]\n\t" - "ldr r5, [%[b]]\n\t" - "sbc r4, r5\n\t" - "str r4, [%[r]]\n\t" - "sbc %[c], %[c]\n\t" - "add %[a], #4\n\t" - "add %[b], #4\n\t" - "add %[r], #4\n\t" - "cmp %[a], r6\n\t" - "bne 1b\n\t" - : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) - : - : "memory", "r4", "r5", "r6" - ); - - return c; -} - -#else -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static sp_digit sp_384_sub_12(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "ldr r4, [%[a], #0]\n\t" - "ldr r5, [%[a], #4]\n\t" - "ldr r6, [%[b], #0]\n\t" - "ldr r7, [%[b], #4]\n\t" - "sub r4, r6\n\t" - "sbc r5, r7\n\t" - "str r4, [%[r], #0]\n\t" - "str r5, [%[r], #4]\n\t" - "ldr r4, [%[a], #8]\n\t" - "ldr r5, [%[a], #12]\n\t" - "ldr r6, [%[b], #8]\n\t" - "ldr r7, [%[b], #12]\n\t" - "sbc r4, r6\n\t" - "sbc r5, r7\n\t" - "str r4, [%[r], #8]\n\t" - "str r5, [%[r], #12]\n\t" - "ldr r4, [%[a], #16]\n\t" - "ldr r5, [%[a], #20]\n\t" - "ldr r6, [%[b], #16]\n\t" - "ldr r7, [%[b], #20]\n\t" - "sbc r4, r6\n\t" - "sbc r5, r7\n\t" - "str r4, [%[r], #16]\n\t" - "str r5, [%[r], #20]\n\t" - "ldr r4, [%[a], #24]\n\t" - "ldr r5, [%[a], #28]\n\t" - "ldr r6, [%[b], #24]\n\t" - "ldr r7, [%[b], #28]\n\t" - "sbc r4, r6\n\t" - "sbc r5, r7\n\t" - "str r4, [%[r], #24]\n\t" - "str r5, [%[r], #28]\n\t" - "ldr r4, [%[a], #32]\n\t" - "ldr r5, [%[a], #36]\n\t" - "ldr r6, [%[b], #32]\n\t" - "ldr r7, [%[b], #36]\n\t" - "sbc r4, r6\n\t" - "sbc r5, r7\n\t" - "str r4, [%[r], #32]\n\t" - "str r5, [%[r], #36]\n\t" - "ldr r4, [%[a], #40]\n\t" - "ldr r5, [%[a], #44]\n\t" - "ldr r6, [%[b], #40]\n\t" - "ldr r7, [%[b], #44]\n\t" - "sbc r4, r6\n\t" - "sbc r5, r7\n\t" - "str r4, [%[r], #40]\n\t" - "str r5, [%[r], #44]\n\t" - "sbc %[c], %[c]\n\t" - : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) - : - : "memory", "r4", "r5", "r6", "r7" - ); - - return c; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Conditionally add a and b using the mask m. * m is -1 to add and 0 when not. * @@ -25094,8 +25559,8 @@ static int sp_384_proj_point_add_12_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r, } #endif /* WOLFSSL_SP_NONBLOCK */ -static void sp_384_proj_point_add_12(sp_point_384* r, const sp_point_384* p, const sp_point_384* q, - sp_digit* t) +static void sp_384_proj_point_add_12(sp_point_384* r, + const sp_point_384* p, const sp_point_384* q, sp_digit* t) { const sp_point_384* ap[2]; sp_point_384* rp[2]; @@ -25274,9 +25739,11 @@ static void sp_384_get_point_16_12(sp_point_384* r, const sp_point_384* table, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Simple, smaller code size and memory size, of windowing. - * Calculate uindow of 4 bits. - * Only add points from table. + * Fast implementation that generates a pre-computation table. + * 4 bits of window (no sliding!). + * Uses add and double for calculating table. + * 384 doubles. + * 108 adds. * * r Resulting point. * g Point to multiply. @@ -25305,7 +25772,8 @@ static int sp_384_ecc_mulmod_fast_12(sp_point_384* r, const sp_point_384* g, con sp_digit* tmp; sp_digit n; int i; - int c, y; + int c; + int y; int err; /* Constant time used for cache attack resistance implementation. */ @@ -25378,7 +25846,7 @@ static int sp_384_ecc_mulmod_fast_12(sp_point_384* r, const sp_point_384* g, con i = 10; n = k[i+1] << 0; c = 28; - y = n >> 28; + y = (int)(n >> 28); #ifndef WC_NO_CACHE_RESISTANT if (ct) { sp_384_get_point_16_12(rt, t, y); @@ -25443,12 +25911,6 @@ static int sp_384_ecc_mulmod_fast_12(sp_point_384* r, const sp_point_384* g, con return err; } -/* A table entry for pre-computed points. */ -typedef struct sp_table_entry_384 { - sp_digit x[12]; - sp_digit y[12]; -} sp_table_entry_384; - #ifdef FP_ECC /* Double the Montgomery form projective point p a number of times. * @@ -25457,7 +25919,8 @@ typedef struct sp_table_entry_384 { * n Number of times to double * t Temporary ordinate data. */ -static void sp_384_proj_point_dbl_n_12(sp_point_384* p, int n, sp_digit* t) +static void sp_384_proj_point_dbl_n_12(sp_point_384* p, int n, + sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*12; @@ -25538,6 +26001,36 @@ static void sp_384_proj_point_dbl_n_12(sp_point_384* p, int n, sp_digit* t) sp_384_div2_12(y, y, p384_mod); } +/* Convert the projective point to affine. + * Ordinates are in Montgomery form. + * + * a Point to convert. + * t Temporary data. + */ +static void sp_384_proj_to_affine_12(sp_point_384* a, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 12; + sp_digit* tmp = t + 4 * 12; + + sp_384_mont_inv_12(t1, a->z, tmp); + + sp_384_mont_sqr_12(t2, t1, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t1, t2, t1, p384_mod, p384_mp_mod); + + sp_384_mont_mul_12(a->x, a->x, t2, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(a->y, a->y, t1, p384_mod, p384_mp_mod); + XMEMCPY(a->z, p384_norm_mod, sizeof(p384_norm_mod)); +} + +#endif /* FP_ECC */ +/* A table entry for pre-computed points. */ +typedef struct sp_table_entry_384 { + sp_digit x[12]; + sp_digit y[12]; +} sp_table_entry_384; + +#ifdef FP_ECC #endif /* FP_ECC */ /* Add two Montgomery form projective points. The second point has a q value of * one. @@ -25623,29 +26116,11 @@ static void sp_384_proj_point_add_qz1_12(sp_point_384* r, const sp_point_384* p, #ifdef WOLFSSL_SP_SMALL #ifdef FP_ECC -/* Convert the projective point to affine. - * Ordinates are in Montgomery form. - * - * a Point to convert. - * t Temporary data. - */ -static void sp_384_proj_to_affine_12(sp_point_384* a, sp_digit* t) -{ - sp_digit* t1 = t; - sp_digit* t2 = t + 2 * 12; - sp_digit* tmp = t + 4 * 12; - - sp_384_mont_inv_12(t1, a->z, tmp); - - sp_384_mont_sqr_12(t2, t1, p384_mod, p384_mp_mod); - sp_384_mont_mul_12(t1, t2, t1, p384_mod, p384_mp_mod); - - sp_384_mont_mul_12(a->x, a->x, t2, p384_mod, p384_mp_mod); - sp_384_mont_mul_12(a->y, a->y, t1, p384_mod, p384_mp_mod); - XMEMCPY(a->z, p384_norm_mod, sizeof(p384_norm_mod)); -} - /* Generate the pre-computed table of points for the base point. + * + * width = 4 + * 16 entries + * 96 bits between * * a The base point. * table Place to store generated point data. @@ -25656,12 +26131,15 @@ static int sp_384_gen_stripe_table_12(const sp_point_384* a, sp_table_entry_384* table, sp_digit* tmp, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_point_384 td, s1d, s2d; + sp_point_384 td; + sp_point_384 s1d; + sp_point_384 s2d; #endif sp_point_384* t; sp_point_384* s1 = NULL; sp_point_384* s2 = NULL; - int i, j; + int i; + int j; int err; (void)heap; @@ -25796,8 +26274,10 @@ static void sp_384_get_entry_16_12(sp_point_384* r, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Implementation uses striping of bits. - * Choose bits 4 bits apart. + * Stripe implementation. + * Pre-generated: 2^0, 2^96, ... + * Pre-generated: products of all combinations of above. + * 4 doubles and adds (with qz=1) * * r Resulting point. * k Scalar to multiply by. @@ -25819,8 +26299,10 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, sp_point_384* rt; sp_point_384* p = NULL; sp_digit* t; - int i, j; - int y, x; + int i; + int j; + int y; + int x; int err; (void)g; @@ -25848,8 +26330,10 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, XMEMCPY(rt->z, p384_norm_mod, sizeof(p384_norm_mod)); y = 0; - for (j=0,x=95; j<4; j++,x+=96) { + x = 95; + for (j=0; j<4; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 96; } #ifndef WC_NO_CACHE_RESISTANT if (ct) { @@ -25863,8 +26347,10 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, rt->infinity = !y; for (i=94; i>=0; i--) { y = 0; - for (j=0,x=i; j<4; j++,x+=96) { + x = i; + for (j=0; j<4; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 96; } sp_384_proj_point_dbl_12(rt, rt, t); @@ -25906,16 +26392,25 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, #define FP_ENTRIES 16 #endif +/* Cache entry - holds precomputation tables for a point. */ typedef struct sp_cache_384_t { + /* X ordinate of point that table was generated from. */ sp_digit x[12]; + /* Y ordinate of point that table was generated from. */ sp_digit y[12]; + /* Precomputation table for point. */ sp_table_entry_384 table[16]; + /* Count of entries in table. */ uint32_t cnt; + /* Point and table set in entry. */ int set; } sp_cache_384_t; +/* Cache of tables. */ static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES]; +/* Index of last entry in cache. */ static THREAD_LS_T int sp_cache_384_last = -1; +/* Cache has been initialized. */ static THREAD_LS_T int sp_cache_384_inited = 0; #ifndef HAVE_THREAD_LS @@ -25923,9 +26418,15 @@ static THREAD_LS_T int sp_cache_384_inited = 0; static wolfSSL_Mutex sp_cache_384_lock; #endif +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache) { - int i, j; + int i; + int j; uint32_t least; if (sp_cache_384_inited == 0) { @@ -26034,6 +26535,10 @@ static int sp_384_ecc_mulmod_12(sp_point_384* r, const sp_point_384* g, const sp #else #ifdef FP_ECC /* Generate the pre-computed table of points for the base point. + * + * width = 8 + * 256 entries + * 48 bits between * * a The base point. * table Place to store generated point data. @@ -26044,12 +26549,15 @@ static int sp_384_gen_stripe_table_12(const sp_point_384* a, sp_table_entry_384* table, sp_digit* tmp, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_point_384 td, s1d, s2d; + sp_point_384 td; + sp_point_384 s1d; + sp_point_384 s2d; #endif sp_point_384* t; sp_point_384* s1 = NULL; sp_point_384* s2 = NULL; - int i, j; + int i; + int j; int err; (void)heap; @@ -26184,8 +26692,10 @@ static void sp_384_get_entry_256_12(sp_point_384* r, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Implementation uses striping of bits. - * Choose bits 8 bits apart. + * Stripe implementation. + * Pre-generated: 2^0, 2^48, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) * * r Resulting point. * k Scalar to multiply by. @@ -26207,8 +26717,10 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, sp_point_384* rt; sp_point_384* p = NULL; sp_digit* t; - int i, j; - int y, x; + int i; + int j; + int y; + int x; int err; (void)g; @@ -26236,8 +26748,10 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, XMEMCPY(rt->z, p384_norm_mod, sizeof(p384_norm_mod)); y = 0; - for (j=0,x=47; j<8; j++,x+=48) { + x = 47; + for (j=0; j<8; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 48; } #ifndef WC_NO_CACHE_RESISTANT if (ct) { @@ -26251,8 +26765,10 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, rt->infinity = !y; for (i=46; i>=0; i--) { y = 0; - for (j=0,x=i; j<8; j++,x+=48) { + x = i; + for (j=0; j<8; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 48; } sp_384_proj_point_dbl_12(rt, rt, t); @@ -26294,16 +26810,25 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, #define FP_ENTRIES 16 #endif +/* Cache entry - holds precomputation tables for a point. */ typedef struct sp_cache_384_t { + /* X ordinate of point that table was generated from. */ sp_digit x[12]; + /* Y ordinate of point that table was generated from. */ sp_digit y[12]; + /* Precomputation table for point. */ sp_table_entry_384 table[256]; + /* Count of entries in table. */ uint32_t cnt; + /* Point and table set in entry. */ int set; } sp_cache_384_t; +/* Cache of tables. */ static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES]; +/* Index of last entry in cache. */ static THREAD_LS_T int sp_cache_384_last = -1; +/* Cache has been initialized. */ static THREAD_LS_T int sp_cache_384_inited = 0; #ifndef HAVE_THREAD_LS @@ -26311,9 +26836,15 @@ static THREAD_LS_T int sp_cache_384_inited = 0; static wolfSSL_Mutex sp_cache_384_lock; #endif +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache) { - int i, j; + int i; + int j; uint32_t least; if (sp_cache_384_inited == 0) { @@ -26430,8 +26961,8 @@ static int sp_384_ecc_mulmod_12(sp_point_384* r, const sp_point_384* g, const sp * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_384(mp_int* km, ecc_point* gm, ecc_point* r, int map, - void* heap) +int sp_ecc_mulmod_384(const mp_int* km, const ecc_point* gm, ecc_point* r, + int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_384 p; @@ -26472,7 +27003,94 @@ int sp_ecc_mulmod_384(mp_int* km, ecc_point* gm, ecc_point* r, int map, return err; } +/* Multiply the point by the scalar, add point a and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * p Point to multiply. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_add_384(const mp_int* km, const ecc_point* gm, + const ecc_point* am, int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_384 p; + sp_point_384 a; + sp_digit kd[12]; + sp_digit t[12 * 2 * 6]; +#endif + sp_point_384* point; + sp_point_384* addP = NULL; + sp_digit* k = NULL; + sp_digit* tmp = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_12(heap, p, point); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (12 + 12 * 2 * 6), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 12; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 12, km); + sp_384_point_from_ecc_point_12(point, gm); + sp_384_point_from_ecc_point_12(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_12(addP->x, addP->x, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_12(addP->y, addP->y, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_12(addP->z, addP->z, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_12(point, point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_384_proj_point_add_12(point, point, addP, tmp); + + if (map) { + sp_384_map_12(point, point, tmp); + } + + err = sp_384_point_to_ecc_point_12(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(addP, 0, heap); + sp_384_point_free_12(point, 0, heap); + + return err; +} + #ifdef WOLFSSL_SP_SMALL +/* Striping precomputation table. + * 4 points combined into a table of 16 points. + * Distance of 96 between points. + */ static const sp_table_entry_384 p384_table[16] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -26557,6 +27175,11 @@ static const sp_table_entry_384 p384_table[16] = { /* Multiply the base point of P384 by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Stripe implementation. + * Pre-generated: 2^0, 2^96, ... + * Pre-generated: products of all combinations of above. + * 4 doubles and adds (with qz=1) + * * r Resulting point. * k Scalar to multiply by. * map Indicates whether to convert result to affine. @@ -26572,6 +27195,10 @@ static int sp_384_ecc_mulmod_base_12(sp_point_384* r, const sp_digit* k, } #else +/* Striping precomputation table. + * 8 points combined into a table of 256 points. + * Distance of 48 between points. + */ static const sp_table_entry_384 p384_table[256] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -27856,6 +28483,11 @@ static const sp_table_entry_384 p384_table[256] = { /* Multiply the base point of P384 by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Stripe implementation. + * Pre-generated: 2^0, 2^48, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * * r Resulting point. * k Scalar to multiply by. * map Indicates whether to convert result to affine. @@ -27881,7 +28513,7 @@ static int sp_384_ecc_mulmod_base_12(sp_point_384* r, const sp_digit* k, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_base_384(mp_int* km, ecc_point* r, int map, void* heap) +int sp_ecc_mulmod_base_384(const mp_int* km, ecc_point* r, int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_384 p; @@ -27922,6 +28554,87 @@ int sp_ecc_mulmod_base_384(mp_int* km, ecc_point* r, int map, void* heap) return err; } +/* Multiply the base point of P384 by the scalar, add point a and return + * the result. If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_add_384(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_384 p; + sp_point_384 a; + sp_digit kd[12]; + sp_digit t[12 * 2 * 6]; +#endif + sp_point_384* point; + sp_point_384* addP = NULL; + sp_digit* tmp = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_12(heap, p, point); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (12 + 12 * 2 * 6), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 12; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 12, km); + sp_384_point_from_ecc_point_12(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_12(addP->x, addP->x, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_12(addP->y, addP->y, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_12(addP->z, addP->z, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_base_12(point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_384_proj_point_add_12(point, point, addP, tmp); + + if (map) { + sp_384_map_12(point, point, tmp); + } + + err = sp_384_point_to_ecc_point_12(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(addP, 0, heap); + sp_384_point_free_12(point, 0, heap); + + return err; +} + #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \ defined(HAVE_ECC_VERIFY) /* Returns 1 if the number of zero. @@ -27936,7 +28649,7 @@ static int sp_384_iszero_12(const sp_digit* a) a[8] | a[9] | a[10] | a[11]) == 0; } -#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN | HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ /* Add 1 to a. (a = a + 1) * * a A single precision integer. @@ -27997,7 +28710,8 @@ SP_NOINLINE static void sp_384_add_one_12(sp_digit* a) */ static void sp_384_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -28141,7 +28855,10 @@ int sp_ecc_make_key_384(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) */ static void sp_384_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; j = 384 / 8 - 1; a[j] = 0; @@ -28182,7 +28899,7 @@ static void sp_384_to_bin(sp_digit* r, byte* a) * returns BUFFER_E if the buffer is to small for output size, * MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_secret_gen_384(mp_int* priv, ecc_point* pub, byte* out, +int sp_ecc_secret_gen_384(const mp_int* priv, const ecc_point* pub, byte* out, word32* outLen, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) @@ -28646,7 +29363,6 @@ static const uint32_t p384_order_minus_2[12] = { /* The low half of the order-2 of the P384 curve. */ static const uint32_t p384_order_low[6] = { 0xccc52971U,0xecec196aU,0x48b0a77aU,0x581a0db2U,0xf4372ddfU,0xc7634d81U - }; #endif /* WOLFSSL_SP_SMALL */ @@ -28794,7 +29510,7 @@ static void sp_384_mont_inv_order_12(sp_digit* r, const sp_digit* a, sp_384_mont_mul_order_12(t2, t2, t); for (i=191; i>=1; i--) { sp_384_mont_sqr_order_12(t2, t2); - if (((sp_digit)p384_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p384_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_384_mont_mul_order_12(t2, t2, a); } } @@ -28803,12 +29519,63 @@ static void sp_384_mont_inv_order_12(sp_digit* r, const sp_digit* a, #endif /* WOLFSSL_SP_SMALL */ } -#endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ #ifdef HAVE_ECC_SIGN #ifndef SP_ECC_MAX_SIG_GEN #define SP_ECC_MAX_SIG_GEN 64 #endif +/* Calculate second signature value S from R, k and private value. + * + * s = (r * x + e) / k + * + * s Signature value. + * r First signature value. + * k Ephemeral private key. + * x Private key as a number. + * e Hash of message as a number. + * tmp Temporary storage for intermediate numbers. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_calc_s_12(sp_digit* s, const sp_digit* r, sp_digit* k, + sp_digit* x, const sp_digit* e, sp_digit* tmp) +{ + int err; + sp_digit carry; + int32_t c; + sp_digit* kInv = k; + + /* Conv k to Montgomery form (mod order) */ + sp_384_mul_12(k, k, p384_norm_order); + err = sp_384_mod_12(k, k, p384_order); + if (err == MP_OKAY) { + sp_384_norm_12(k); + + /* kInv = 1/k mod order */ + sp_384_mont_inv_order_12(kInv, k, tmp); + sp_384_norm_12(kInv); + + /* s = r * x + e */ + sp_384_mul_12(x, x, r); + err = sp_384_mod_12(x, x, p384_order); + } + if (err == MP_OKAY) { + sp_384_norm_12(x); + carry = sp_384_add_12(s, e, x); + sp_384_cond_sub_12(s, s, p384_order, 0 - carry); + sp_384_norm_12(s); + c = sp_384_cmp_12(s, p384_order); + sp_384_cond_sub_12(s, s, p384_order, 0L - (sp_digit)(c >= 0)); + sp_384_norm_12(s); + + /* s = s * k^-1 mod order */ + sp_384_mont_mul_order_12(s, s, kInv); + sp_384_norm_12(s); + } + + return err; +} + /* Sign the hash using the private key. * e = [hash, 384 bits] from binary * r = (k.G)->x mod order @@ -28843,8 +29610,8 @@ typedef struct sp_ecc_sign_384_ctx { int i; } sp_ecc_sign_384_ctx; -int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, + mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_sign_384_ctx* ctx = (sp_ecc_sign_384_ctx*)sp_ctx->data; @@ -28984,8 +29751,8 @@ int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, W } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, + const mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -29003,11 +29770,9 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit* r = NULL; sp_digit* tmp = NULL; sp_point_384* point = NULL; - sp_digit carry; sp_digit* s = NULL; - sp_digit* kInv = NULL; - int err = MP_OKAY; int32_t c; + int err = MP_OKAY; int i; (void)heap; @@ -29038,7 +29803,6 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, tmp = td; #endif s = e; - kInv = k; if (hashLen > 48U) { hashLen = 48U; @@ -29046,8 +29810,6 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, } for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) { - sp_384_from_mp(x, 12, priv); - /* New random point. */ if (km == NULL || mp_iszero(km)) { err = sp_384_ecc_gen_k_12(rng, k); @@ -29057,7 +29819,7 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, mp_zero(km); } if (err == MP_OKAY) { - err = sp_384_ecc_mulmod_base_12(point, k, 1, 1, NULL); + err = sp_384_ecc_mulmod_base_12(point, k, 1, 1, heap); } if (err == MP_OKAY) { @@ -29068,38 +29830,15 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_384_cond_sub_12(r, r, p384_order, 0L - (sp_digit)(c >= 0)); sp_384_norm_12(r); - /* Conv k to Montgomery form (mod order) */ - sp_384_mul_12(k, k, p384_norm_order); - err = sp_384_mod_12(k, k, p384_order); - } - if (err == MP_OKAY) { - sp_384_norm_12(k); - /* kInv = 1/k mod order */ - sp_384_mont_inv_order_12(kInv, k, tmp); - sp_384_norm_12(kInv); - - /* s = r * x + e */ - sp_384_mul_12(x, x, r); - err = sp_384_mod_12(x, x, p384_order); - } - if (err == MP_OKAY) { - sp_384_norm_12(x); + sp_384_from_mp(x, 12, priv); sp_384_from_bin(e, 12, hash, (int)hashLen); - carry = sp_384_add_12(s, e, x); - sp_384_cond_sub_12(s, s, p384_order, 0 - carry); - sp_384_norm_12(s); - c = sp_384_cmp_12(s, p384_order); - sp_384_cond_sub_12(s, s, p384_order, 0L - (sp_digit)(c >= 0)); - sp_384_norm_12(s); - /* s = s * k^-1 mod order */ - sp_384_mont_mul_order_12(s, s, kInv); - sp_384_norm_12(s); + err = sp_384_calc_s_12(s, r, k, x, e, tmp); + } - /* Check that signature is usable. */ - if (sp_384_iszero_12(s) == 0) { - break; - } + /* Check that signature is usable. */ + if ((err == MP_OKAY) && (sp_384_iszero_12(s) == 0)) { + break; } #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP i = 1; @@ -29127,7 +29866,6 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, XMEMSET(x, 0, sizeof(sp_digit) * 2U * 12U); XMEMSET(k, 0, sizeof(sp_digit) * 2U * 12U); XMEMSET(r, 0, sizeof(sp_digit) * 2U * 12U); - XMEMSET(r, 0, sizeof(sp_digit) * 2U * 12U); XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 12U); #endif sp_384_point_free_12(point, 1, heap); @@ -29919,6 +30657,100 @@ static int sp_384_mod_inv_12(sp_digit* r, const sp_digit* a, const sp_digit* m) } #endif /* WOLFSSL_SP_SMALL */ + +/* Add point p1 into point p2. Handles p1 == p2 and result at infinity. + * + * p1 First point to add and holds result. + * p2 Second point to add. + * tmp Temporary storage for intermediate numbers. + */ +static void sp_384_add_points_12(sp_point_384* p1, const sp_point_384* p2, + sp_digit* tmp) +{ + + sp_384_proj_point_add_12(p1, p1, p2, tmp); + if (sp_384_iszero_12(p1->z)) { + if (sp_384_iszero_12(p1->x) && sp_384_iszero_12(p1->y)) { + sp_384_proj_point_dbl_12(p1, p2, tmp); + } + else { + /* Y ordinate is not used from here - don't set. */ + p1->x[0] = 0; + p1->x[1] = 0; + p1->x[2] = 0; + p1->x[3] = 0; + p1->x[4] = 0; + p1->x[5] = 0; + p1->x[6] = 0; + p1->x[7] = 0; + p1->x[8] = 0; + p1->x[9] = 0; + p1->x[10] = 0; + p1->x[11] = 0; + XMEMCPY(p1->z, p384_norm_mod, sizeof(p384_norm_mod)); + } + } +} + +/* Calculate the verification point: [e/s]G + [r/s]Q + * + * p1 Calculated point. + * p2 Public point and temporary. + * s Second part of signature as a number. + * u1 Temporary number. + * u2 Temproray number. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_calc_vfy_point_12(sp_point_384* p1, sp_point_384* p2, + sp_digit* s, sp_digit* u1, sp_digit* u2, sp_digit* tmp, void* heap) +{ + int err; + +#ifndef WOLFSSL_SP_SMALL + { + sp_384_mod_inv_12(s, s, p384_order); + } +#endif /* !WOLFSSL_SP_SMALL */ + { + sp_384_mul_12(s, s, p384_norm_order); + } + err = sp_384_mod_12(s, s, p384_order); + if (err == MP_OKAY) { + sp_384_norm_12(s); +#ifdef WOLFSSL_SP_SMALL + { + sp_384_mont_inv_order_12(s, s, tmp); + sp_384_mont_mul_order_12(u1, u1, s); + sp_384_mont_mul_order_12(u2, u2, s); + } + +#else + { + sp_384_mont_mul_order_12(u1, u1, s); + sp_384_mont_mul_order_12(u2, u2, s); + } + +#endif /* WOLFSSL_SP_SMALL */ + err = sp_384_ecc_mulmod_base_12(p1, u1, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_384_iszero_12(p1->z)) { + p1->infinity = 1; + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_12(p2, p2, u2, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_384_iszero_12(p2->z)) { + p2->infinity = 1; + } + + if (err == MP_OKAY) { + sp_384_add_points_12(p1, p2, tmp); + } + + return err; +} + #ifdef HAVE_ECC_VERIFY /* Verify the signature values with the hash and public key. * e = Truncate(hash, 384) @@ -29937,8 +30769,7 @@ static int sp_384_mod_inv_12(sp_digit* r, const sp_digit* a, const sp_digit* m) * rm First part of result as an mp_int. * sm Sirst part of result as an mp_int. * heap Heap to use for allocation. - * returns RNG failures, MEMORY_E when memory allocation fails and - * MP_OKAY on success. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ #ifdef WOLFSSL_SP_NONBLOCK typedef struct sp_ecc_verify_384_ctx { @@ -29957,8 +30788,9 @@ typedef struct sp_ecc_verify_384_ctx { sp_point_384 p2; } sp_ecc_verify_384_ctx; -int sp_ecc_verify_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, + word32 hashLen, const mp_int* pX, const mp_int* pY, const mp_int* pZ, + const mp_int* r, const mp_int* sm, int* res, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_verify_384_ctx* ctx = (sp_ecc_verify_384_ctx*)sp_ctx->data; @@ -30112,8 +30944,9 @@ int sp_ecc_verify_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_384(const byte* hash, word32 hashLen, const mp_int* pX, + const mp_int* pY, const mp_int* pZ, const mp_int* r, const mp_int* sm, + int* res, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -30132,7 +30965,7 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, sp_point_384* p1; sp_point_384* p2 = NULL; sp_digit carry; - int32_t c; + int32_t c = 0; int err; err = sp_384_point_new_12(heap, p1d, p1); @@ -30173,70 +31006,9 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, sp_384_from_mp(p2->y, 12, pY); sp_384_from_mp(p2->z, 12, pZ); -#ifndef WOLFSSL_SP_SMALL - { - sp_384_mod_inv_12(s, s, p384_order); - } -#endif /* !WOLFSSL_SP_SMALL */ - { - sp_384_mul_12(s, s, p384_norm_order); - } - err = sp_384_mod_12(s, s, p384_order); + err = sp_384_calc_vfy_point_12(p1, p2, s, u1, u2, tmp, heap); } if (err == MP_OKAY) { - sp_384_norm_12(s); -#ifdef WOLFSSL_SP_SMALL - { - sp_384_mont_inv_order_12(s, s, tmp); - sp_384_mont_mul_order_12(u1, u1, s); - sp_384_mont_mul_order_12(u2, u2, s); - } - -#else - { - sp_384_mont_mul_order_12(u1, u1, s); - sp_384_mont_mul_order_12(u2, u2, s); - } - -#endif /* WOLFSSL_SP_SMALL */ - err = sp_384_ecc_mulmod_base_12(p1, u1, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_384_iszero_12(p1->z)) { - p1->infinity = 1; - } - if (err == MP_OKAY) { - err = sp_384_ecc_mulmod_12(p2, p2, u2, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_384_iszero_12(p2->z)) { - p2->infinity = 1; - } - - if (err == MP_OKAY) { - { - sp_384_proj_point_add_12(p1, p1, p2, tmp); - if (sp_384_iszero_12(p1->z)) { - if (sp_384_iszero_12(p1->x) && sp_384_iszero_12(p1->y)) { - sp_384_proj_point_dbl_12(p1, p2, tmp); - } - else { - /* Y ordinate is not used from here - don't set. */ - p1->x[0] = 0; - p1->x[1] = 0; - p1->x[2] = 0; - p1->x[3] = 0; - p1->x[4] = 0; - p1->x[5] = 0; - p1->x[6] = 0; - p1->x[7] = 0; - p1->x[8] = 0; - p1->x[9] = 0; - p1->x[10] = 0; - p1->x[11] = 0; - XMEMCPY(p1->z, p384_norm_mod, sizeof(p384_norm_mod)); - } - } - } - /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */ /* Reload r and convert to Montgomery form. */ sp_384_from_mp(u2, 12, r); @@ -30258,16 +31030,16 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, /* Compare with mod and if greater or equal then not valid. */ c = sp_384_cmp_12(u2, p384_mod); - if (c < 0) { - /* Convert to Montogomery form */ - err = sp_384_mod_mul_norm_12(u2, u2, p384_mod); - if (err == MP_OKAY) { - /* u1 = (r + 1*order).z'.z' mod prime */ - sp_384_mont_mul_12(u1, u2, p1->z, p384_mod, - p384_mp_mod); - *res = (int)(sp_384_cmp_12(p1->x, u1) == 0); - } - } + } + } + if ((*res == 0) && (c < 0)) { + /* Convert to Montogomery form */ + err = sp_384_mod_mul_norm_12(u2, u2, p384_mod); + if (err == MP_OKAY) { + /* u1 = (r + 1*order).z'.z' mod prime */ + sp_384_mont_mul_12(u1, u2, p1->z, p384_mod, + p384_mp_mod); + *res = (sp_384_cmp_12(p1->x, u1) == 0); } } } @@ -30291,7 +31063,8 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -static int sp_384_ecc_is_point_12(sp_point_384* point, void* heap) +static int sp_384_ecc_is_point_12(const sp_point_384* point, + void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -30354,7 +31127,7 @@ static int sp_384_ecc_is_point_12(sp_point_384* point, void* heap) * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -int sp_ecc_is_point_384(mp_int* pX, mp_int* pY) +int sp_ecc_is_point_384(const mp_int* pX, const mp_int* pY) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_384 pubd; @@ -30388,7 +31161,8 @@ int sp_ecc_is_point_384(mp_int* pX, mp_int* pY) * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and * MP_OKAY otherwise. */ -int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) +int sp_ecc_check_key_384(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit privd[12]; @@ -30442,12 +31216,11 @@ int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) } } - if (err == MP_OKAY) { - /* Check range of X and Y */ - if (sp_384_cmp_12(pub->x, p384_mod) >= 0 || - sp_384_cmp_12(pub->y, p384_mod) >= 0) { - err = ECC_OUT_OF_RANGE_E; - } + /* Check range of X and Y */ + if ((err == MP_OKAY) && + ((sp_384_cmp_12(pub->x, p384_mod) >= 0) || + (sp_384_cmp_12(pub->y, p384_mod) >= 0))) { + err = ECC_OUT_OF_RANGE_E; } if (err == MP_OKAY) { @@ -30459,12 +31232,10 @@ int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Point * order = infinity */ err = sp_384_ecc_mulmod_12(p, pub, p384_order, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is infinity */ - if ((sp_384_iszero_12(p->x) == 0) || - (sp_384_iszero_12(p->y) == 0)) { - err = ECC_INF_E; - } + /* Check result is infinity */ + if ((err == MP_OKAY) && ((sp_384_iszero_12(p->x) == 0) || + (sp_384_iszero_12(p->y) == 0))) { + err = ECC_INF_E; } if (privm) { @@ -30472,12 +31243,11 @@ int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Base * private = point */ err = sp_384_ecc_mulmod_base_12(p, priv, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is public key */ - if (sp_384_cmp_12(p->x, pub->x) != 0 || - sp_384_cmp_12(p->y, pub->y) != 0) { - err = ECC_PRIV_KEY_E; - } + /* Check result is public key */ + if ((err == MP_OKAY) && + ((sp_384_cmp_12(p->x, pub->x) != 0) || + (sp_384_cmp_12(p->y, pub->y) != 0))) { + err = ECC_PRIV_KEY_E; } } @@ -30667,7 +31437,7 @@ int sp_ecc_map_384(mp_int* pX, mp_int* pY, mp_int* pZ) sp_384_from_mp(p->y, 12, pY); sp_384_from_mp(p->z, 12, pZ); - sp_384_map_12(p, p, tmp); + sp_384_map_12(p, p, tmp); } if (err == MP_OKAY) { @@ -30880,6 +31650,13182 @@ int sp_ecc_uncompress_384(mp_int* xm, int odd, mp_int* ym) } #endif #endif /* WOLFSSL_SP_384 */ +#ifdef WOLFSSL_SP_1024 + +/* Point structure to use. */ +typedef struct sp_point_1024 { + /* X ordinate of point. */ + sp_digit x[2 * 32]; + /* Y ordinate of point. */ + sp_digit y[2 * 32]; + /* Z ordinate of point. */ + sp_digit z[2 * 32]; + /* Indicates point is at infinity. */ + int infinity; +} sp_point_1024; + +#ifndef WOLFSSL_SP_SMALL +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static void sp_1024_mul_16(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit tmp[16 * 2]; + __asm__ __volatile__ ( + "mov r3, #0\n\t" + "mov r4, #0\n\t" + "mov r8, r3\n\t" + "mov r11, %[r]\n\t" + "mov r9, %[a]\n\t" + "mov r10, %[b]\n\t" + "mov r6, #64\n\t" + "add r6, r9\n\t" + "mov r12, r6\n\t" + "\n1:\n\t" + "mov %[r], #0\n\t" + "mov r5, #0\n\t" + "mov r6, #60\n\t" + "mov %[a], r8\n\t" + "sub %[a], r6\n\t" + "sbc r6, r6\n\t" + "mvn r6, r6\n\t" + "and %[a], r6\n\t" + "mov %[b], r8\n\t" + "sub %[b], %[a]\n\t" + "add %[a], r9\n\t" + "add %[b], r10\n\t" + "\n2:\n\t" + "# Multiply Start\n\t" + "ldr r6, [%[a]]\n\t" + "ldr r7, [%[b]]\n\t" + "lsl r6, r6, #16\n\t" + "lsl r7, r7, #16\n\t" + "lsr r6, r6, #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r7, r6\n\t" + "add r3, r7\n\t" + "adc r4, %[r]\n\t" + "adc r5, %[r]\n\t" + "ldr r7, [%[b]]\n\t" + "lsr r7, r7, #16\n\t" + "mul r6, r7\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "ldr r6, [%[a]]\n\t" + "ldr r7, [%[b]]\n\t" + "lsr r6, r6, #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r7, r6\n\t" + "add r4, r7\n\t" + "adc r5, %[r]\n\t" + "ldr r7, [%[b]]\n\t" + "lsl r7, r7, #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r6, r7\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "# Multiply Done\n\t" + "add %[a], #4\n\t" + "sub %[b], #4\n\t" + "cmp %[a], r12\n\t" + "beq 3f\n\t" + "mov r6, r8\n\t" + "add r6, r9\n\t" + "cmp %[a], r6\n\t" + "ble 2b\n\t" + "\n3:\n\t" + "mov %[r], r11\n\t" + "mov r7, r8\n\t" + "str r3, [%[r], r7]\n\t" + "mov r3, r4\n\t" + "mov r4, r5\n\t" + "add r7, #4\n\t" + "mov r8, r7\n\t" + "mov r6, #120\n\t" + "cmp r7, r6\n\t" + "ble 1b\n\t" + "str r3, [%[r], r7]\n\t" + "mov %[a], r9\n\t" + "mov %[b], r10\n\t" + : + : [r] "r" (tmp), [a] "r" (a), [b] "r" (b) + : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" + ); + + XMEMCPY(r, tmp, sizeof(tmp)); +} + +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_1024_sqr_16(sp_digit* r, const sp_digit* a) +{ + __asm__ __volatile__ ( + "mov r3, #0\n\t" + "mov r4, #0\n\t" + "mov r5, #0\n\t" + "mov r8, r3\n\t" + "mov r11, %[r]\n\t" + "mov r6, #128\n\t" + "neg r6, r6\n\t" + "add sp, r6\n\t" + "mov r10, sp\n\t" + "mov r9, %[a]\n\t" + "\n1:\n\t" + "mov %[r], #0\n\t" + "mov r6, #60\n\t" + "mov %[a], r8\n\t" + "sub %[a], r6\n\t" + "sbc r6, r6\n\t" + "mvn r6, r6\n\t" + "and %[a], r6\n\t" + "mov r2, r8\n\t" + "sub r2, %[a]\n\t" + "add %[a], r9\n\t" + "add r2, r9\n\t" + "\n2:\n\t" + "cmp r2, %[a]\n\t" + "beq 4f\n\t" + "# Multiply * 2: Start\n\t" + "ldr r6, [%[a]]\n\t" + "ldr r7, [r2]\n\t" + "lsl r6, r6, #16\n\t" + "lsl r7, r7, #16\n\t" + "lsr r6, r6, #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r7, r6\n\t" + "add r3, r7\n\t" + "adc r4, %[r]\n\t" + "adc r5, %[r]\n\t" + "add r3, r7\n\t" + "adc r4, %[r]\n\t" + "adc r5, %[r]\n\t" + "ldr r7, [r2]\n\t" + "lsr r7, r7, #16\n\t" + "mul r6, r7\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "ldr r6, [%[a]]\n\t" + "ldr r7, [r2]\n\t" + "lsr r6, r6, #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r7, r6\n\t" + "add r4, r7\n\t" + "adc r5, %[r]\n\t" + "add r4, r7\n\t" + "adc r5, %[r]\n\t" + "ldr r7, [r2]\n\t" + "lsl r7, r7, #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r6, r7\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "# Multiply * 2: Done\n\t" + "bal 5f\n\t" + "\n4:\n\t" + "# Square: Start\n\t" + "ldr r6, [%[a]]\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "lsr r6, r6, #16\n\t" + "mul r6, r6\n\t" + "add r3, r6\n\t" + "adc r4, %[r]\n\t" + "adc r5, %[r]\n\t" + "mul r7, r7\n\t" + "add r4, r7\n\t" + "adc r5, %[r]\n\t" + "ldr r6, [%[a]]\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "lsr r6, r6, #16\n\t" + "mul r6, r7\n\t" + "lsr r7, r6, #15\n\t" + "lsl r6, r6, #17\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "# Square: Done\n\t" + "\n5:\n\t" + "add %[a], #4\n\t" + "sub r2, #4\n\t" + "mov r6, #64\n\t" + "add r6, r9\n\t" + "cmp %[a], r6\n\t" + "beq 3f\n\t" + "cmp %[a], r2\n\t" + "bgt 3f\n\t" + "mov r7, r8\n\t" + "add r7, r9\n\t" + "cmp %[a], r7\n\t" + "ble 2b\n\t" + "\n3:\n\t" + "mov %[r], r10\n\t" + "mov r7, r8\n\t" + "str r3, [%[r], r7]\n\t" + "mov r3, r4\n\t" + "mov r4, r5\n\t" + "mov r5, #0\n\t" + "add r7, #4\n\t" + "mov r8, r7\n\t" + "mov r6, #120\n\t" + "cmp r7, r6\n\t" + "ble 1b\n\t" + "mov %[a], r9\n\t" + "str r3, [%[r], r7]\n\t" + "mov %[r], r11\n\t" + "mov %[a], r10\n\t" + "mov r3, #124\n\t" + "\n4:\n\t" + "ldr r6, [%[a], r3]\n\t" + "str r6, [%[r], r3]\n\t" + "sub r3, #4\n\t" + "bge 4b\n\t" + "mov r6, #128\n\t" + "add sp, r6\n\t" + : + : [r] "r" (r), [a] "r" (a) + : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" + ); +} + +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_1024_add_16(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldr r4, [%[a], #0]\n\t" + "ldr r5, [%[b], #0]\n\t" + "add r4, r5\n\t" + "str r4, [%[r], #0]\n\t" + "ldr r4, [%[a], #4]\n\t" + "ldr r5, [%[b], #4]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #4]\n\t" + "ldr r4, [%[a], #8]\n\t" + "ldr r5, [%[b], #8]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #8]\n\t" + "ldr r4, [%[a], #12]\n\t" + "ldr r5, [%[b], #12]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #12]\n\t" + "ldr r4, [%[a], #16]\n\t" + "ldr r5, [%[b], #16]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #16]\n\t" + "ldr r4, [%[a], #20]\n\t" + "ldr r5, [%[b], #20]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #20]\n\t" + "ldr r4, [%[a], #24]\n\t" + "ldr r5, [%[b], #24]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #24]\n\t" + "ldr r4, [%[a], #28]\n\t" + "ldr r5, [%[b], #28]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #28]\n\t" + "ldr r4, [%[a], #32]\n\t" + "ldr r5, [%[b], #32]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #32]\n\t" + "ldr r4, [%[a], #36]\n\t" + "ldr r5, [%[b], #36]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #36]\n\t" + "ldr r4, [%[a], #40]\n\t" + "ldr r5, [%[b], #40]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #40]\n\t" + "ldr r4, [%[a], #44]\n\t" + "ldr r5, [%[b], #44]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #44]\n\t" + "ldr r4, [%[a], #48]\n\t" + "ldr r5, [%[b], #48]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #48]\n\t" + "ldr r4, [%[a], #52]\n\t" + "ldr r5, [%[b], #52]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #52]\n\t" + "ldr r4, [%[a], #56]\n\t" + "ldr r5, [%[b], #56]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #56]\n\t" + "ldr r4, [%[a], #60]\n\t" + "ldr r5, [%[b], #60]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #60]\n\t" + "mov %[c], #0\n\t" + "adc %[c], %[c]\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5" + ); + + return c; +} + +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_1024_sub_in_place_32(sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldr r3, [%[a], #0]\n\t" + "ldr r4, [%[a], #4]\n\t" + "ldr r5, [%[b], #0]\n\t" + "ldr r6, [%[b], #4]\n\t" + "sub r3, r5\n\t" + "sbc r4, r6\n\t" + "str r3, [%[a], #0]\n\t" + "str r4, [%[a], #4]\n\t" + "ldr r3, [%[a], #8]\n\t" + "ldr r4, [%[a], #12]\n\t" + "ldr r5, [%[b], #8]\n\t" + "ldr r6, [%[b], #12]\n\t" + "sbc r3, r5\n\t" + "sbc r4, r6\n\t" + "str r3, [%[a], #8]\n\t" + "str r4, [%[a], #12]\n\t" + "ldr r3, [%[a], #16]\n\t" + "ldr r4, [%[a], #20]\n\t" + "ldr r5, [%[b], #16]\n\t" + "ldr r6, [%[b], #20]\n\t" + "sbc r3, r5\n\t" + "sbc r4, r6\n\t" + "str r3, [%[a], #16]\n\t" + "str r4, [%[a], #20]\n\t" + "ldr r3, [%[a], #24]\n\t" + "ldr r4, [%[a], #28]\n\t" + "ldr r5, [%[b], #24]\n\t" + "ldr r6, [%[b], #28]\n\t" + "sbc r3, r5\n\t" + "sbc r4, r6\n\t" + "str r3, [%[a], #24]\n\t" + "str r4, [%[a], #28]\n\t" + "ldr r3, [%[a], #32]\n\t" + "ldr r4, [%[a], #36]\n\t" + "ldr r5, [%[b], #32]\n\t" + "ldr r6, [%[b], #36]\n\t" + "sbc r3, r5\n\t" + "sbc r4, r6\n\t" + "str r3, [%[a], #32]\n\t" + "str r4, [%[a], #36]\n\t" + "ldr r3, [%[a], #40]\n\t" + "ldr r4, [%[a], #44]\n\t" + "ldr r5, [%[b], #40]\n\t" + "ldr r6, [%[b], #44]\n\t" + "sbc r3, r5\n\t" + "sbc r4, r6\n\t" + "str r3, [%[a], #40]\n\t" + "str r4, [%[a], #44]\n\t" + "ldr r3, [%[a], #48]\n\t" + "ldr r4, [%[a], #52]\n\t" + "ldr r5, [%[b], #48]\n\t" + "ldr r6, [%[b], #52]\n\t" + "sbc r3, r5\n\t" + "sbc r4, r6\n\t" + "str r3, [%[a], #48]\n\t" + "str r4, [%[a], #52]\n\t" + "ldr r3, [%[a], #56]\n\t" + "ldr r4, [%[a], #60]\n\t" + "ldr r5, [%[b], #56]\n\t" + "ldr r6, [%[b], #60]\n\t" + "sbc r3, r5\n\t" + "sbc r4, r6\n\t" + "str r3, [%[a], #56]\n\t" + "str r4, [%[a], #60]\n\t" + "ldr r3, [%[a], #64]\n\t" + "ldr r4, [%[a], #68]\n\t" + "ldr r5, [%[b], #64]\n\t" + "ldr r6, [%[b], #68]\n\t" + "sbc r3, r5\n\t" + "sbc r4, r6\n\t" + "str r3, [%[a], #64]\n\t" + "str r4, [%[a], #68]\n\t" + "ldr r3, [%[a], #72]\n\t" + "ldr r4, [%[a], #76]\n\t" + "ldr r5, [%[b], #72]\n\t" + "ldr r6, [%[b], #76]\n\t" + "sbc r3, r5\n\t" + "sbc r4, r6\n\t" + "str r3, [%[a], #72]\n\t" + "str r4, [%[a], #76]\n\t" + "ldr r3, [%[a], #80]\n\t" + "ldr r4, [%[a], #84]\n\t" + "ldr r5, [%[b], #80]\n\t" + "ldr r6, [%[b], #84]\n\t" + "sbc r3, r5\n\t" + "sbc r4, r6\n\t" + "str r3, [%[a], #80]\n\t" + "str r4, [%[a], #84]\n\t" + "ldr r3, [%[a], #88]\n\t" + "ldr r4, [%[a], #92]\n\t" + "ldr r5, [%[b], #88]\n\t" + "ldr r6, [%[b], #92]\n\t" + "sbc r3, r5\n\t" + "sbc r4, r6\n\t" + "str r3, [%[a], #88]\n\t" + "str r4, [%[a], #92]\n\t" + "ldr r3, [%[a], #96]\n\t" + "ldr r4, [%[a], #100]\n\t" + "ldr r5, [%[b], #96]\n\t" + "ldr r6, [%[b], #100]\n\t" + "sbc r3, r5\n\t" + "sbc r4, r6\n\t" + "str r3, [%[a], #96]\n\t" + "str r4, [%[a], #100]\n\t" + "ldr r3, [%[a], #104]\n\t" + "ldr r4, [%[a], #108]\n\t" + "ldr r5, [%[b], #104]\n\t" + "ldr r6, [%[b], #108]\n\t" + "sbc r3, r5\n\t" + "sbc r4, r6\n\t" + "str r3, [%[a], #104]\n\t" + "str r4, [%[a], #108]\n\t" + "ldr r3, [%[a], #112]\n\t" + "ldr r4, [%[a], #116]\n\t" + "ldr r5, [%[b], #112]\n\t" + "ldr r6, [%[b], #116]\n\t" + "sbc r3, r5\n\t" + "sbc r4, r6\n\t" + "str r3, [%[a], #112]\n\t" + "str r4, [%[a], #116]\n\t" + "ldr r3, [%[a], #120]\n\t" + "ldr r4, [%[a], #124]\n\t" + "ldr r5, [%[b], #120]\n\t" + "ldr r6, [%[b], #124]\n\t" + "sbc r3, r5\n\t" + "sbc r4, r6\n\t" + "str r3, [%[a], #120]\n\t" + "str r4, [%[a], #124]\n\t" + "sbc %[c], %[c]\n\t" + : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r3", "r4", "r5", "r6" + ); + + return c; +} + +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_1024_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldr r4, [%[a], #0]\n\t" + "ldr r5, [%[b], #0]\n\t" + "add r4, r5\n\t" + "str r4, [%[r], #0]\n\t" + "ldr r4, [%[a], #4]\n\t" + "ldr r5, [%[b], #4]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #4]\n\t" + "ldr r4, [%[a], #8]\n\t" + "ldr r5, [%[b], #8]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #8]\n\t" + "ldr r4, [%[a], #12]\n\t" + "ldr r5, [%[b], #12]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #12]\n\t" + "ldr r4, [%[a], #16]\n\t" + "ldr r5, [%[b], #16]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #16]\n\t" + "ldr r4, [%[a], #20]\n\t" + "ldr r5, [%[b], #20]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #20]\n\t" + "ldr r4, [%[a], #24]\n\t" + "ldr r5, [%[b], #24]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #24]\n\t" + "ldr r4, [%[a], #28]\n\t" + "ldr r5, [%[b], #28]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #28]\n\t" + "ldr r4, [%[a], #32]\n\t" + "ldr r5, [%[b], #32]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #32]\n\t" + "ldr r4, [%[a], #36]\n\t" + "ldr r5, [%[b], #36]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #36]\n\t" + "ldr r4, [%[a], #40]\n\t" + "ldr r5, [%[b], #40]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #40]\n\t" + "ldr r4, [%[a], #44]\n\t" + "ldr r5, [%[b], #44]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #44]\n\t" + "ldr r4, [%[a], #48]\n\t" + "ldr r5, [%[b], #48]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #48]\n\t" + "ldr r4, [%[a], #52]\n\t" + "ldr r5, [%[b], #52]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #52]\n\t" + "ldr r4, [%[a], #56]\n\t" + "ldr r5, [%[b], #56]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #56]\n\t" + "ldr r4, [%[a], #60]\n\t" + "ldr r5, [%[b], #60]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #60]\n\t" + "ldr r4, [%[a], #64]\n\t" + "ldr r5, [%[b], #64]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #64]\n\t" + "ldr r4, [%[a], #68]\n\t" + "ldr r5, [%[b], #68]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #68]\n\t" + "ldr r4, [%[a], #72]\n\t" + "ldr r5, [%[b], #72]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #72]\n\t" + "ldr r4, [%[a], #76]\n\t" + "ldr r5, [%[b], #76]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #76]\n\t" + "ldr r4, [%[a], #80]\n\t" + "ldr r5, [%[b], #80]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #80]\n\t" + "ldr r4, [%[a], #84]\n\t" + "ldr r5, [%[b], #84]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #84]\n\t" + "ldr r4, [%[a], #88]\n\t" + "ldr r5, [%[b], #88]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #88]\n\t" + "ldr r4, [%[a], #92]\n\t" + "ldr r5, [%[b], #92]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #92]\n\t" + "ldr r4, [%[a], #96]\n\t" + "ldr r5, [%[b], #96]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #96]\n\t" + "ldr r4, [%[a], #100]\n\t" + "ldr r5, [%[b], #100]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #100]\n\t" + "ldr r4, [%[a], #104]\n\t" + "ldr r5, [%[b], #104]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #104]\n\t" + "ldr r4, [%[a], #108]\n\t" + "ldr r5, [%[b], #108]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #108]\n\t" + "ldr r4, [%[a], #112]\n\t" + "ldr r5, [%[b], #112]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #112]\n\t" + "ldr r4, [%[a], #116]\n\t" + "ldr r5, [%[b], #116]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #116]\n\t" + "ldr r4, [%[a], #120]\n\t" + "ldr r5, [%[b], #120]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #120]\n\t" + "ldr r4, [%[a], #124]\n\t" + "ldr r5, [%[b], #124]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r], #124]\n\t" + "mov %[c], #0\n\t" + "adc %[c], %[c]\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5" + ); + + return c; +} + +/* AND m into each word of a and store in r. + * + * r A single precision integer. + * a A single precision integer. + * m Mask to AND against each digit. + */ +static void sp_1024_mask_16(sp_digit* r, const sp_digit* a, sp_digit m) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i=0; i<16; i++) { + r[i] = a[i] & m; + } +#else + int i; + + for (i = 0; i < 16; i += 8) { + r[i+0] = a[i+0] & m; + r[i+1] = a[i+1] & m; + r[i+2] = a[i+2] & m; + r[i+3] = a[i+3] & m; + r[i+4] = a[i+4] & m; + r[i+5] = a[i+5] & m; + r[i+6] = a[i+6] & m; + r[i+7] = a[i+7] & m; + } +#endif +} + +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static void sp_1024_mul_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit* z0 = r; + sp_digit z1[32]; + sp_digit a1[16]; + sp_digit b1[16]; + sp_digit z2[32]; + sp_digit u; + sp_digit ca; + sp_digit cb; + + ca = sp_1024_add_16(a1, a, &a[16]); + cb = sp_1024_add_16(b1, b, &b[16]); + u = ca & cb; + sp_1024_mul_16(z1, a1, b1); + sp_1024_mul_16(z2, &a[16], &b[16]); + sp_1024_mul_16(z0, a, b); + sp_1024_mask_16(r + 32, a1, 0 - cb); + sp_1024_mask_16(b1, b1, 0 - ca); + u += sp_1024_add_16(r + 32, r + 32, b1); + u += sp_1024_sub_in_place_32(z1, z2); + u += sp_1024_sub_in_place_32(z1, z0); + u += sp_1024_add_32(r + 16, r + 16, z1); + r[48] = u; + XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1)); + (void)sp_1024_add_32(r + 32, r + 32, z2); +} + +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_1024_sqr_32(sp_digit* r, const sp_digit* a) +{ + sp_digit* z0 = r; + sp_digit z2[32]; + sp_digit z1[32]; + sp_digit a1[16]; + sp_digit u; + + u = sp_1024_add_16(a1, a, &a[16]); + sp_1024_sqr_16(z1, a1); + sp_1024_sqr_16(z2, &a[16]); + sp_1024_sqr_16(z0, a); + sp_1024_mask_16(r + 32, a1, 0 - u); + u += sp_1024_add_16(r + 32, r + 32, r + 32); + u += sp_1024_sub_in_place_32(z1, z2); + u += sp_1024_sub_in_place_32(z1, z0); + u += sp_1024_add_32(r + 16, r + 16, z1); + r[48] = u; + XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1)); + (void)sp_1024_add_32(r + 32, r + 32, z2); +} + +#else +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static void sp_1024_mul_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit tmp[32 * 2]; + __asm__ __volatile__ ( + "mov r3, #0\n\t" + "mov r4, #0\n\t" + "mov r8, r3\n\t" + "mov r11, %[r]\n\t" + "mov r9, %[a]\n\t" + "mov r10, %[b]\n\t" + "mov r6, #128\n\t" + "add r6, r9\n\t" + "mov r12, r6\n\t" + "\n1:\n\t" + "mov %[r], #0\n\t" + "mov r5, #0\n\t" + "mov r6, #124\n\t" + "mov %[a], r8\n\t" + "sub %[a], r6\n\t" + "sbc r6, r6\n\t" + "mvn r6, r6\n\t" + "and %[a], r6\n\t" + "mov %[b], r8\n\t" + "sub %[b], %[a]\n\t" + "add %[a], r9\n\t" + "add %[b], r10\n\t" + "\n2:\n\t" + "# Multiply Start\n\t" + "ldr r6, [%[a]]\n\t" + "ldr r7, [%[b]]\n\t" + "lsl r6, r6, #16\n\t" + "lsl r7, r7, #16\n\t" + "lsr r6, r6, #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r7, r6\n\t" + "add r3, r7\n\t" + "adc r4, %[r]\n\t" + "adc r5, %[r]\n\t" + "ldr r7, [%[b]]\n\t" + "lsr r7, r7, #16\n\t" + "mul r6, r7\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "ldr r6, [%[a]]\n\t" + "ldr r7, [%[b]]\n\t" + "lsr r6, r6, #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r7, r6\n\t" + "add r4, r7\n\t" + "adc r5, %[r]\n\t" + "ldr r7, [%[b]]\n\t" + "lsl r7, r7, #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r6, r7\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "# Multiply Done\n\t" + "add %[a], #4\n\t" + "sub %[b], #4\n\t" + "cmp %[a], r12\n\t" + "beq 3f\n\t" + "mov r6, r8\n\t" + "add r6, r9\n\t" + "cmp %[a], r6\n\t" + "ble 2b\n\t" + "\n3:\n\t" + "mov %[r], r11\n\t" + "mov r7, r8\n\t" + "str r3, [%[r], r7]\n\t" + "mov r3, r4\n\t" + "mov r4, r5\n\t" + "add r7, #4\n\t" + "mov r8, r7\n\t" + "mov r6, #248\n\t" + "cmp r7, r6\n\t" + "ble 1b\n\t" + "str r3, [%[r], r7]\n\t" + "mov %[a], r9\n\t" + "mov %[b], r10\n\t" + : + : [r] "r" (tmp), [a] "r" (a), [b] "r" (b) + : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" + ); + + XMEMCPY(r, tmp, sizeof(tmp)); +} + +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_1024_sqr_32(sp_digit* r, const sp_digit* a) +{ + __asm__ __volatile__ ( + "mov r3, #0\n\t" + "mov r4, #0\n\t" + "mov r5, #0\n\t" + "mov r8, r3\n\t" + "mov r11, %[r]\n\t" + "mov r6, #1\n\t" + "lsl r6, r6, #8\n\t" + "neg r6, r6\n\t" + "add sp, r6\n\t" + "mov r10, sp\n\t" + "mov r9, %[a]\n\t" + "\n1:\n\t" + "mov %[r], #0\n\t" + "mov r6, #124\n\t" + "mov %[a], r8\n\t" + "sub %[a], r6\n\t" + "sbc r6, r6\n\t" + "mvn r6, r6\n\t" + "and %[a], r6\n\t" + "mov r2, r8\n\t" + "sub r2, %[a]\n\t" + "add %[a], r9\n\t" + "add r2, r9\n\t" + "\n2:\n\t" + "cmp r2, %[a]\n\t" + "beq 4f\n\t" + "# Multiply * 2: Start\n\t" + "ldr r6, [%[a]]\n\t" + "ldr r7, [r2]\n\t" + "lsl r6, r6, #16\n\t" + "lsl r7, r7, #16\n\t" + "lsr r6, r6, #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r7, r6\n\t" + "add r3, r7\n\t" + "adc r4, %[r]\n\t" + "adc r5, %[r]\n\t" + "add r3, r7\n\t" + "adc r4, %[r]\n\t" + "adc r5, %[r]\n\t" + "ldr r7, [r2]\n\t" + "lsr r7, r7, #16\n\t" + "mul r6, r7\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "ldr r6, [%[a]]\n\t" + "ldr r7, [r2]\n\t" + "lsr r6, r6, #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r7, r6\n\t" + "add r4, r7\n\t" + "adc r5, %[r]\n\t" + "add r4, r7\n\t" + "adc r5, %[r]\n\t" + "ldr r7, [r2]\n\t" + "lsl r7, r7, #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r6, r7\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "# Multiply * 2: Done\n\t" + "bal 5f\n\t" + "\n4:\n\t" + "# Square: Start\n\t" + "ldr r6, [%[a]]\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "lsr r6, r6, #16\n\t" + "mul r6, r6\n\t" + "add r3, r6\n\t" + "adc r4, %[r]\n\t" + "adc r5, %[r]\n\t" + "mul r7, r7\n\t" + "add r4, r7\n\t" + "adc r5, %[r]\n\t" + "ldr r6, [%[a]]\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "lsr r6, r6, #16\n\t" + "mul r6, r7\n\t" + "lsr r7, r6, #15\n\t" + "lsl r6, r6, #17\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "# Square: Done\n\t" + "\n5:\n\t" + "add %[a], #4\n\t" + "sub r2, #4\n\t" + "mov r6, #128\n\t" + "add r6, r9\n\t" + "cmp %[a], r6\n\t" + "beq 3f\n\t" + "cmp %[a], r2\n\t" + "bgt 3f\n\t" + "mov r7, r8\n\t" + "add r7, r9\n\t" + "cmp %[a], r7\n\t" + "ble 2b\n\t" + "\n3:\n\t" + "mov %[r], r10\n\t" + "mov r7, r8\n\t" + "str r3, [%[r], r7]\n\t" + "mov r3, r4\n\t" + "mov r4, r5\n\t" + "mov r5, #0\n\t" + "add r7, #4\n\t" + "mov r8, r7\n\t" + "mov r6, #248\n\t" + "cmp r7, r6\n\t" + "ble 1b\n\t" + "mov %[a], r9\n\t" + "str r3, [%[r], r7]\n\t" + "mov %[r], r11\n\t" + "mov %[a], r10\n\t" + "mov r3, #252\n\t" + "\n4:\n\t" + "ldr r6, [%[a], r3]\n\t" + "str r6, [%[r], r3]\n\t" + "sub r3, #4\n\t" + "bge 4b\n\t" + "mov r6, #1\n\t" + "lsl r6, r6, #8\n\t" + "add sp, r6\n\t" + : + : [r] "r" (r), [a] "r" (a) + : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" + ); +} + +#endif /* !WOLFSSL_SP_SMALL */ +/* The modulus (prime) of the curve P1024. */ +static const sp_digit p1024_mod[32] = { + 0xfea85feb,0x666d807a,0xac7ace87,0x80c5df10,0x89857db0,0xfce3e823, + 0x56971f1f,0x9f94d6af,0x1c3c09aa,0xa7cf3c52,0x31852a82,0xb6aff4a8, + 0x65681ce1,0x512ac5cd,0x326b4cd4,0xe26c6487,0xa666a6d0,0x356d27f4, + 0xf7c88a19,0xe791b39f,0x31a59cb0,0x228730d5,0xe2fc0f1b,0xf40aab27, + 0xb3e01a2e,0xbe9ae358,0x9cb48261,0x416c0ce1,0xdad0657a,0x65c61198, + 0x0a563fda,0x997abb1f +}; +/* The Montogmery normalizer for modulus of the curve P1024. */ +static const sp_digit p1024_norm_mod[32] = { + 0x0157a015,0x99927f85,0x53853178,0x7f3a20ef,0x767a824f,0x031c17dc, + 0xa968e0e0,0x606b2950,0xe3c3f655,0x5830c3ad,0xce7ad57d,0x49500b57, + 0x9a97e31e,0xaed53a32,0xcd94b32b,0x1d939b78,0x5999592f,0xca92d80b, + 0x083775e6,0x186e4c60,0xce5a634f,0xdd78cf2a,0x1d03f0e4,0x0bf554d8, + 0x4c1fe5d1,0x41651ca7,0x634b7d9e,0xbe93f31e,0x252f9a85,0x9a39ee67, + 0xf5a9c025,0x668544e0 +}; +/* The Montogmery multiplier for modulus of the curve P1024. */ +static sp_digit p1024_mp_mod = 0x7c8f2f3d; +#if defined(WOLFSSL_SP_SMALL) || defined(HAVE_ECC_CHECK_KEY) +/* The order of the curve P1024. */ +static const sp_digit p1024_order[32] = { + 0xbfaa17fb,0xd99b601e,0x2b1eb3a1,0x203177c4,0xe2615f6c,0xff38fa08, + 0xd5a5c7c7,0xa7e535ab,0x870f026a,0xa9f3cf14,0x0c614aa0,0x6dabfd2a, + 0x595a0738,0x144ab173,0xcc9ad335,0x389b1921,0x2999a9b4,0x4d5b49fd, + 0xfdf22286,0x39e46ce7,0x4c69672c,0xc8a1cc35,0xf8bf03c6,0xbd02aac9, + 0x2cf8068b,0x6fa6b8d6,0x672d2098,0x905b0338,0x36b4195e,0x99718466, + 0xc2958ff6,0x265eaec7 +}; +#endif +/* The base point of curve P1024. */ +static const sp_point_1024 p1024_base = { + /* X ordinate */ + { + 0xeae63895,0x880dc8ab,0x967e0979,0x80ec46c4,0xb63f73ec,0xee9163a5, + 0x80728d87,0xd5cfb4cc,0xba66910d,0xa7c1514d,0x7a60de74,0xa702c339, + 0x8b72f2e1,0x337c8654,0x5dd5bccb,0x9760af76,0x406ce890,0x718bd9e7, + 0xdb9dfa55,0x43d5f22c,0x30b09e10,0xab10db90,0xf6ce2308,0xb5edb6c0, + 0xb6ff7cbf,0x98b2f204,0x0aec69c6,0x2b1a2fd6,0x3ed9b52a,0x0a799005, + 0x332c29ad,0x53fc09ee, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* Y ordinate */ + { + 0x1bef16d7,0x75573fd7,0x6a67dcde,0xadb9b570,0xd5bb4636,0x80bdad5a, + 0xe9cb99a9,0x13515ad7,0xc5a4d5f2,0x492d979f,0x164aa989,0xac6f1e80, + 0xb7652fe0,0xcad696b5,0xad547c6c,0x70dae117,0xa9e032b9,0x416cff0c, + 0x9a140b2e,0x6b598ccf,0xf0de55f6,0xe7f7f5e5,0x654ec2b9,0xf5ea69f4, + 0x1e141178,0x3d778d82,0x02990696,0xd3e82016,0x3634a135,0xf9f1f053, + 0x3f6009f1,0x0a824906, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* Z ordinate */ + { + 0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* infinity */ + 0 +}; + +#ifdef WOLFSSL_SP_SMALL +/* Sub b from a into a. (a -= b) + * + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_1024_sub_in_place_32(sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + __asm__ __volatile__ ( + "mov r7, %[a]\n\t" + "add r7, #128\n\t" + "\n1:\n\t" + "mov r5, #0\n\t" + "sub r5, %[c]\n\t" + "ldr r3, [%[a]]\n\t" + "ldr r4, [%[a], #4]\n\t" + "ldr r5, [%[b]]\n\t" + "ldr r6, [%[b], #4]\n\t" + "sbc r3, r5\n\t" + "sbc r4, r6\n\t" + "str r3, [%[a]]\n\t" + "str r4, [%[a], #4]\n\t" + "sbc %[c], %[c]\n\t" + "add %[a], #8\n\t" + "add %[b], #8\n\t" + "cmp %[a], r7\n\t" + "bne 1b\n\t" + : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r3", "r4", "r5", "r6", "r7" + ); + + return c; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Conditionally subtract b from a using the mask m. + * m is -1 to subtract and 0 when not copying. + * + * r A single precision number representing condition subtract result. + * a A single precision number to subtract from. + * b A single precision number to subtract. + * m Mask value to apply. + */ +SP_NOINLINE static sp_digit sp_1024_cond_sub_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r5, #128\n\t" + "mov r8, r5\n\t" + "mov r7, #0\n\t" + "1:\n\t" + "ldr r6, [%[b], r7]\n\t" + "and r6, %[m]\n\t" + "mov r5, #0\n\t" + "sub r5, %[c]\n\t" + "ldr r5, [%[a], r7]\n\t" + "sbc r5, r6\n\t" + "sbc %[c], %[c]\n\t" + "str r5, [%[r], r7]\n\t" + "add r7, #4\n\t" + "cmp r7, r8\n\t" + "blt 1b\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "r5", "r6", "r7", "r8" + ); + + return c; +} + +#ifdef WOLFSSL_SP_SMALL +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_1024_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r6, %[a]\n\t" + "mov r7, #0\n\t" + "add r6, #128\n\t" + "sub r7, #1\n\t" + "\n1:\n\t" + "add %[c], r7\n\t" + "ldr r4, [%[a]]\n\t" + "ldr r5, [%[b]]\n\t" + "adc r4, r5\n\t" + "str r4, [%[r]]\n\t" + "mov %[c], #0\n\t" + "adc %[c], %[c]\n\t" + "add %[a], #4\n\t" + "add %[b], #4\n\t" + "add %[r], #4\n\t" + "cmp %[a], r6\n\t" + "bne 1b\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6", "r7" + ); + + return c; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Mul a by digit b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision digit. + */ +SP_NOINLINE static void sp_1024_mul_d_32(sp_digit* r, const sp_digit* a, + sp_digit b) +{ + __asm__ __volatile__ ( + "mov r6, #128\n\t" + "add r6, %[a]\n\t" + "mov r8, %[r]\n\t" + "mov r9, r6\n\t" + "mov r3, #0\n\t" + "mov r4, #0\n\t" + "1:\n\t" + "mov %[r], #0\n\t" + "mov r5, #0\n\t" + "# A[] * B\n\t" + "ldr r6, [%[a]]\n\t" + "lsl r6, r6, #16\n\t" + "lsl r7, %[b], #16\n\t" + "lsr r6, r6, #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r7, r6\n\t" + "add r3, r7\n\t" + "adc r4, %[r]\n\t" + "adc r5, %[r]\n\t" + "lsr r7, %[b], #16\n\t" + "mul r6, r7\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "ldr r6, [%[a]]\n\t" + "lsr r6, r6, #16\n\t" + "lsr r7, %[b], #16\n\t" + "mul r7, r6\n\t" + "add r4, r7\n\t" + "adc r5, %[r]\n\t" + "lsl r7, %[b], #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r6, r7\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "add r3, r6\n\t" + "adc r4, r7\n\t" + "adc r5, %[r]\n\t" + "# A[] * B - Done\n\t" + "mov %[r], r8\n\t" + "str r3, [%[r]]\n\t" + "mov r3, r4\n\t" + "mov r4, r5\n\t" + "add %[r], #4\n\t" + "add %[a], #4\n\t" + "mov r8, %[r]\n\t" + "cmp %[a], r9\n\t" + "blt 1b\n\t" + "str r3, [%[r]]\n\t" + : [r] "+r" (r), [a] "+r" (a) + : [b] "r" (b) + : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9" + ); +} + +/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) + * + * d1 The high order half of the number to divide. + * d0 The low order half of the number to divide. + * div The dividend. + * returns the result of the division. + * + * Note that this is an approximate div. It may give an answer 1 larger. + */ +SP_NOINLINE static sp_digit div_1024_word_32(sp_digit d1, sp_digit d0, + sp_digit div) +{ + sp_digit r = 0; + + __asm__ __volatile__ ( + "lsr r5, %[div], #1\n\t" + "add r5, #1\n\t" + "mov r8, %[d0]\n\t" + "mov r9, %[d1]\n\t" + "# Do top 32\n\t" + "mov r6, r5\n\t" + "sub r6, %[d1]\n\t" + "sbc r6, r6\n\t" + "add %[r], %[r]\n\t" + "sub %[r], r6\n\t" + "and r6, r5\n\t" + "sub %[d1], r6\n\t" + "# Next 30 bits\n\t" + "mov r4, #29\n\t" + "1:\n\t" + "lsl %[d0], %[d0], #1\n\t" + "adc %[d1], %[d1]\n\t" + "mov r6, r5\n\t" + "sub r6, %[d1]\n\t" + "sbc r6, r6\n\t" + "add %[r], %[r]\n\t" + "sub %[r], r6\n\t" + "and r6, r5\n\t" + "sub %[d1], r6\n\t" + "sub r4, #1\n\t" + "bpl 1b\n\t" + "mov r7, #0\n\t" + "add %[r], %[r]\n\t" + "add %[r], #1\n\t" + "# r * div - Start\n\t" + "lsl %[d1], %[r], #16\n\t" + "lsl r4, %[div], #16\n\t" + "lsr %[d1], %[d1], #16\n\t" + "lsr r4, r4, #16\n\t" + "mul r4, %[d1]\n\t" + "lsr r6, %[div], #16\n\t" + "mul %[d1], r6\n\t" + "lsr r5, %[d1], #16\n\t" + "lsl %[d1], %[d1], #16\n\t" + "add r4, %[d1]\n\t" + "adc r5, r7\n\t" + "lsr %[d1], %[r], #16\n\t" + "mul r6, %[d1]\n\t" + "add r5, r6\n\t" + "lsl r6, %[div], #16\n\t" + "lsr r6, r6, #16\n\t" + "mul %[d1], r6\n\t" + "lsr r6, %[d1], #16\n\t" + "lsl %[d1], %[d1], #16\n\t" + "add r4, %[d1]\n\t" + "adc r5, r6\n\t" + "# r * div - Done\n\t" + "mov %[d1], r8\n\t" + "sub %[d1], r4\n\t" + "mov r4, %[d1]\n\t" + "mov %[d1], r9\n\t" + "sbc %[d1], r5\n\t" + "mov r5, %[d1]\n\t" + "add %[r], r5\n\t" + "# r * div - Start\n\t" + "lsl %[d1], %[r], #16\n\t" + "lsl r4, %[div], #16\n\t" + "lsr %[d1], %[d1], #16\n\t" + "lsr r4, r4, #16\n\t" + "mul r4, %[d1]\n\t" + "lsr r6, %[div], #16\n\t" + "mul %[d1], r6\n\t" + "lsr r5, %[d1], #16\n\t" + "lsl %[d1], %[d1], #16\n\t" + "add r4, %[d1]\n\t" + "adc r5, r7\n\t" + "lsr %[d1], %[r], #16\n\t" + "mul r6, %[d1]\n\t" + "add r5, r6\n\t" + "lsl r6, %[div], #16\n\t" + "lsr r6, r6, #16\n\t" + "mul %[d1], r6\n\t" + "lsr r6, %[d1], #16\n\t" + "lsl %[d1], %[d1], #16\n\t" + "add r4, %[d1]\n\t" + "adc r5, r6\n\t" + "# r * div - Done\n\t" + "mov %[d1], r8\n\t" + "mov r6, r9\n\t" + "sub r4, %[d1], r4\n\t" + "sbc r6, r5\n\t" + "mov r5, r6\n\t" + "add %[r], r5\n\t" + "# r * div - Start\n\t" + "lsl %[d1], %[r], #16\n\t" + "lsl r4, %[div], #16\n\t" + "lsr %[d1], %[d1], #16\n\t" + "lsr r4, r4, #16\n\t" + "mul r4, %[d1]\n\t" + "lsr r6, %[div], #16\n\t" + "mul %[d1], r6\n\t" + "lsr r5, %[d1], #16\n\t" + "lsl %[d1], %[d1], #16\n\t" + "add r4, %[d1]\n\t" + "adc r5, r7\n\t" + "lsr %[d1], %[r], #16\n\t" + "mul r6, %[d1]\n\t" + "add r5, r6\n\t" + "lsl r6, %[div], #16\n\t" + "lsr r6, r6, #16\n\t" + "mul %[d1], r6\n\t" + "lsr r6, %[d1], #16\n\t" + "lsl %[d1], %[d1], #16\n\t" + "add r4, %[d1]\n\t" + "adc r5, r6\n\t" + "# r * div - Done\n\t" + "mov %[d1], r8\n\t" + "mov r6, r9\n\t" + "sub r4, %[d1], r4\n\t" + "sbc r6, r5\n\t" + "mov r5, r6\n\t" + "add %[r], r5\n\t" + "mov r6, %[div]\n\t" + "sub r6, r4\n\t" + "sbc r6, r6\n\t" + "sub %[r], r6\n\t" + : [r] "+r" (r) + : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div) + : "r4", "r5", "r7", "r6", "r8", "r9" + ); + return r; +} + +/* AND m into each word of a and store in r. + * + * r A single precision integer. + * a A single precision integer. + * m Mask to AND against each digit. + */ +static void sp_1024_mask_32(sp_digit* r, const sp_digit* a, sp_digit m) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i=0; i<32; i++) { + r[i] = a[i] & m; + } +#else + int i; + + for (i = 0; i < 32; i += 8) { + r[i+0] = a[i+0] & m; + r[i+1] = a[i+1] & m; + r[i+2] = a[i+2] & m; + r[i+3] = a[i+3] & m; + r[i+4] = a[i+4] & m; + r[i+5] = a[i+5] & m; + r[i+6] = a[i+6] & m; + r[i+7] = a[i+7] & m; + } +#endif +} + +/* Compare a with b in constant time. + * + * a A single precision integer. + * b A single precision integer. + * return -ve, 0 or +ve if a is less than, equal to or greater than b + * respectively. + */ +SP_NOINLINE static int32_t sp_1024_cmp_32(const sp_digit* a, const sp_digit* b) +{ + sp_digit r = 0; + + + __asm__ __volatile__ ( + "mov r3, #0\n\t" + "mvn r3, r3\n\t" + "mov r6, #124\n\t" + "1:\n\t" + "ldr r7, [%[a], r6]\n\t" + "ldr r5, [%[b], r6]\n\t" + "and r7, r3\n\t" + "and r5, r3\n\t" + "mov r4, r7\n\t" + "sub r7, r5\n\t" + "sbc r7, r7\n\t" + "add %[r], r7\n\t" + "mvn r7, r7\n\t" + "and r3, r7\n\t" + "sub r5, r4\n\t" + "sbc r7, r7\n\t" + "sub %[r], r7\n\t" + "mvn r7, r7\n\t" + "and r3, r7\n\t" + "sub r6, #4\n\t" + "cmp r6, #0\n\t" + "bge 1b\n\t" + : [r] "+r" (r) + : [a] "r" (a), [b] "r" (b) + : "r3", "r4", "r5", "r6", "r7" + ); + + return r; +} + +/* Divide d in a and put remainder into r (m*d + r = a) + * m is not calculated as it is not needed at this time. + * + * a Number to be divided. + * d Number to divide with. + * m Multiplier result. + * r Remainder from the division. + * returns MP_OKAY indicating success. + */ +static WC_INLINE int sp_1024_div_32(const sp_digit* a, const sp_digit* d, sp_digit* m, + sp_digit* r) +{ + sp_digit t1[64], t2[33]; + sp_digit div, r1; + int i; + + (void)m; + + div = d[31]; + XMEMCPY(t1, a, sizeof(*t1) * 2 * 32); + for (i=31; i>=0; i--) { + sp_digit hi = t1[32 + i] - (t1[32 + i] == div); + r1 = div_1024_word_32(hi, t1[32 + i - 1], div); + + sp_1024_mul_d_32(t2, d, r1); + t1[32 + i] += sp_1024_sub_in_place_32(&t1[i], t2); + t1[32 + i] -= t2[32]; + sp_1024_mask_32(t2, d, t1[32 + i]); + t1[32 + i] += sp_1024_add_32(&t1[i], &t1[i], t2); + sp_1024_mask_32(t2, d, t1[32 + i]); + t1[32 + i] += sp_1024_add_32(&t1[i], &t1[i], t2); + } + + r1 = sp_1024_cmp_32(t1, d) >= 0; + sp_1024_cond_sub_32(r, t1, d, (sp_digit)0 - r1); + + return MP_OKAY; +} + +/* Reduce a modulo m into r. (r = a mod m) + * + * r A single precision number that is the reduced result. + * a A single precision number that is to be reduced. + * m A single precision number that is the modulus to reduce with. + * returns MP_OKAY indicating success. + */ +static WC_INLINE int sp_1024_mod_32(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + return sp_1024_div_32(a, m, NULL, r); +} + +/* Multiply a number by Montogmery normalizer mod modulus (prime). + * + * r The resulting Montgomery form number. + * a The number to convert. + * m The modulus (prime). + * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. + */ +static int sp_1024_mod_mul_norm_32(sp_digit* r, const sp_digit* a, + const sp_digit* m) +{ + sp_1024_mul_32(r, a, p1024_norm_mod); + return sp_1024_mod_32(r, r, m); +} + +/* Create a new point. + * + * heap [in] Buffer to allocate dynamic memory from. + * sp [in] Data for point - only if not allocating. + * p [out] New point. + * returns MEMORY_E when dynamic memory allocation fails and 0 otherwise. + */ +static int sp_1024_point_new_ex_32(void* heap, sp_point_1024* sp, + sp_point_1024** p) +{ + int ret = MP_OKAY; + (void)heap; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + (void)sp; + *p = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024), heap, DYNAMIC_TYPE_ECC); +#else + *p = sp; +#endif + if (*p == NULL) { + ret = MEMORY_E; + } + return ret; +} + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* Allocate memory for point and return error. */ +#define sp_1024_point_new_32(heap, sp, p) sp_1024_point_new_ex_32((heap), NULL, &(p)) +#else +/* Set pointer to data and return no error. */ +#define sp_1024_point_new_32(heap, sp, p) sp_1024_point_new_ex_32((heap), &(sp), &(p)) +#endif + + +/* Free the point. + * + * p [in,out] Point to free. + * clear [in] Indicates whether to zeroize point. + * heap [in] Buffer from which dynamic memory was allocate from. + */ +static void sp_1024_point_free_32(sp_point_1024* p, int clear, void* heap) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* If valid pointer then clear point data if requested and free data. */ + if (p != NULL) { + if (clear != 0) { + XMEMSET(p, 0, sizeof(*p)); + } + XFREE(p, heap, DYNAMIC_TYPE_ECC); + } +#else +/* Clear point data if requested. */ + if ((p != NULL) && (clear != 0)) { + XMEMSET(p, 0, sizeof(*p)); + } +#endif + (void)heap; +} + +/* Convert an mp_int to an array of sp_digit. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a A multi-precision integer. + */ +static void sp_1024_from_mp(sp_digit* r, int size, const mp_int* a) +{ +#if DIGIT_BIT == 32 + int j; + + XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); + + for (j = a->used; j < size; j++) { + r[j] = 0; + } +#elif DIGIT_BIT > 32 + int i; + int j = 0; + word32 s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i] << s); + r[j] &= 0xffffffff; + s = 32U - s; + if (j + 1 >= size) { + break; + } + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + while ((s + 32U) <= (word32)DIGIT_BIT) { + s += 32U; + r[j] &= 0xffffffff; + if (j + 1 >= size) { + break; + } + if (s < (word32)DIGIT_BIT) { + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + } + else { + r[++j] = 0L; + } + } + s = (word32)DIGIT_BIT - s; + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#else + int i; + int j = 0; + int s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i]) << s; + if (s + DIGIT_BIT >= 32) { + r[j] &= 0xffffffff; + if (j + 1 >= size) { + break; + } + s = 32 - s; + if (s == DIGIT_BIT) { + r[++j] = 0; + s = 0; + } + else { + r[++j] = a->dp[i] >> s; + s = DIGIT_BIT - s; + } + } + else { + s += DIGIT_BIT; + } + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#endif +} + +/* Convert a point of type ecc_point to type sp_point_1024. + * + * p Point of type sp_point_1024 (result). + * pm Point of type ecc_point. + */ +static void sp_1024_point_from_ecc_point_32(sp_point_1024* p, + const ecc_point* pm) +{ + XMEMSET(p->x, 0, sizeof(p->x)); + XMEMSET(p->y, 0, sizeof(p->y)); + XMEMSET(p->z, 0, sizeof(p->z)); + sp_1024_from_mp(p->x, 32, pm->x); + sp_1024_from_mp(p->y, 32, pm->y); + sp_1024_from_mp(p->z, 32, pm->z); + p->infinity = 0; +} + +/* Convert an array of sp_digit to an mp_int. + * + * a A single precision integer. + * r A multi-precision integer. + */ +static int sp_1024_to_mp(const sp_digit* a, mp_int* r) +{ + int err; + + err = mp_grow(r, (1024 + DIGIT_BIT - 1) / DIGIT_BIT); + if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ +#if DIGIT_BIT == 32 + XMEMCPY(r->dp, a, sizeof(sp_digit) * 32); + r->used = 32; + mp_clamp(r); +#elif DIGIT_BIT < 32 + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 32; i++) { + r->dp[j] |= (mp_digit)(a[i] << s); + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + s = DIGIT_BIT - s; + r->dp[++j] = (mp_digit)(a[i] >> s); + while (s + DIGIT_BIT <= 32) { + s += DIGIT_BIT; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; + if (s == SP_WORD_SIZE) { + r->dp[j] = 0; + } + else { + r->dp[j] = (mp_digit)(a[i] >> s); + } + } + s = 32 - s; + } + r->used = (1024 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#else + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 32; i++) { + r->dp[j] |= ((mp_digit)a[i]) << s; + if (s + 32 >= DIGIT_BIT) { + #if DIGIT_BIT != 32 && DIGIT_BIT != 64 + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + #endif + s = DIGIT_BIT - s; + r->dp[++j] = a[i] >> s; + s = 32 - s; + } + else { + s += 32; + } + } + r->used = (1024 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#endif + } + + return err; +} + +/* Convert a point of type sp_point_1024 to type ecc_point. + * + * p Point of type sp_point_1024. + * pm Point of type ecc_point (result). + * returns MEMORY_E when allocation of memory in ecc_point fails otherwise + * MP_OKAY. + */ +static int sp_1024_point_to_ecc_point_32(const sp_point_1024* p, ecc_point* pm) +{ + int err; + + err = sp_1024_to_mp(p->x, pm->x); + if (err == MP_OKAY) { + err = sp_1024_to_mp(p->y, pm->y); + } + if (err == MP_OKAY) { + err = sp_1024_to_mp(p->z, pm->z); + } + + return err; +} + +/* Reduce the number back to 1024 bits using Montgomery reduction. + * + * a A single precision number to reduce in place. + * m The single precision number representing the modulus. + * mp The digit representing the negative inverse of m mod 2^n. + */ +SP_NOINLINE static void sp_1024_mont_reduce_32(sp_digit* a, const sp_digit* m, + sp_digit mp) +{ + sp_digit ca = 0; + + __asm__ __volatile__ ( + "mov r8, %[mp]\n\t" + "mov r12, %[ca]\n\t" + "mov r14, %[m]\n\t" + "mov r9, %[a]\n\t" + "mov r4, #0\n\t" + "# i = 0\n\t" + "mov r11, r4\n\t" + "\n1:\n\t" + "mov r5, #0\n\t" + "mov %[ca], #0\n\t" + "# mu = a[i] * mp\n\t" + "mov %[mp], r8\n\t" + "ldr %[a], [%[a]]\n\t" + "mul %[mp], %[a]\n\t" + "mov %[m], r14\n\t" + "mov r10, r9\n\t" + "\n2:\n\t" + "# a[i+j] += m[j] * mu\n\t" + "mov %[a], r10\n\t" + "ldr %[a], [%[a]]\n\t" + "mov %[ca], #0\n\t" + "mov r4, r5\n\t" + "mov r5, #0\n\t" + "# Multiply m[j] and mu - Start\n\t" + "ldr r7, [%[m]]\n\t" + "lsl r6, %[mp], #16\n\t" + "lsl r7, r7, #16\n\t" + "lsr r6, r6, #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r7, r6\n\t" + "add %[a], r7\n\t" + "adc r5, %[ca]\n\t" + "ldr r7, [%[m]]\n\t" + "lsr r7, r7, #16\n\t" + "mul r6, r7\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "add %[a], r6\n\t" + "adc r5, r7\n\t" + "ldr r7, [%[m]]\n\t" + "lsr r6, %[mp], #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r7, r6\n\t" + "add r5, r7\n\t" + "ldr r7, [%[m]]\n\t" + "lsl r7, r7, #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r6, r7\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "add %[a], r6\n\t" + "adc r5, r7\n\t" + "# Multiply m[j] and mu - Done\n\t" + "add r4, %[a]\n\t" + "adc r5, %[ca]\n\t" + "mov %[a], r10\n\t" + "str r4, [%[a]]\n\t" + "mov r6, #4\n\t" + "add %[m], #4\n\t" + "add r10, r6\n\t" + "mov r4, #124\n\t" + "add r4, r9\n\t" + "cmp r10, r4\n\t" + "blt 2b\n\t" + "# a[i+31] += m[31] * mu\n\t" + "mov %[ca], #0\n\t" + "mov r4, r12\n\t" + "mov %[a], #0\n\t" + "# Multiply m[31] and mu - Start\n\t" + "ldr r7, [%[m]]\n\t" + "lsl r6, %[mp], #16\n\t" + "lsl r7, r7, #16\n\t" + "lsr r6, r6, #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r7, r6\n\t" + "add r5, r7\n\t" + "adc r4, %[ca]\n\t" + "adc %[a], %[ca]\n\t" + "ldr r7, [%[m]]\n\t" + "lsr r7, r7, #16\n\t" + "mul r6, r7\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "add r5, r6\n\t" + "adc r4, r7\n\t" + "adc %[a], %[ca]\n\t" + "ldr r7, [%[m]]\n\t" + "lsr r6, %[mp], #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r7, r6\n\t" + "add r4, r7\n\t" + "adc %[a], %[ca]\n\t" + "ldr r7, [%[m]]\n\t" + "lsl r7, r7, #16\n\t" + "lsr r7, r7, #16\n\t" + "mul r6, r7\n\t" + "lsr r7, r6, #16\n\t" + "lsl r6, r6, #16\n\t" + "add r5, r6\n\t" + "adc r4, r7\n\t" + "adc %[a], %[ca]\n\t" + "# Multiply m[31] and mu - Done\n\t" + "mov %[ca], %[a]\n\t" + "mov %[a], r10\n\t" + "ldr r7, [%[a], #4]\n\t" + "ldr %[a], [%[a]]\n\t" + "mov r6, #0\n\t" + "add r5, %[a]\n\t" + "adc r7, r4\n\t" + "adc %[ca], r6\n\t" + "mov %[a], r10\n\t" + "str r5, [%[a]]\n\t" + "str r7, [%[a], #4]\n\t" + "# i += 1\n\t" + "mov r6, #4\n\t" + "add r9, r6\n\t" + "add r11, r6\n\t" + "mov r12, %[ca]\n\t" + "mov %[a], r9\n\t" + "mov r4, #128\n\t" + "cmp r11, r4\n\t" + "blt 1b\n\t" + "ldr r6, [%[m]]\n\t" + "neg %[ca], %[ca]\n\t" + "sub r6, r7\n\t" + "sbc r6, r6\n\t" + "orr %[ca], r6\n\t" + "mov %[m], r14\n\t" + : [ca] "+r" (ca), [a] "+r" (a) + : [m] "r" (m), [mp] "r" (mp) + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14" + ); + + sp_1024_cond_sub_32(a - 32, a, m, ca); +} + +/* Multiply two Montogmery form numbers mod the modulus (prime). + * (r = a * b mod m) + * + * r Result of multiplication. + * a First number to multiply in Montogmery form. + * b Second number to multiply in Montogmery form. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_1024_mont_mul_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) +{ + sp_1024_mul_32(r, a, b); + sp_1024_mont_reduce_32(r, m, mp); +} + +/* Square the Montgomery form number. (r = a * a mod m) + * + * r Result of squaring. + * a Number to square in Montogmery form. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_1024_mont_sqr_32(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) +{ + sp_1024_sqr_32(r, a); + sp_1024_mont_reduce_32(r, m, mp); +} + +/* Mod-2 for the P1024 curve. */ +static const uint8_t p1024_mod_minus_2[] = { + 6,0x06, 7,0x0f, 7,0x0b, 6,0x0c, 7,0x1e, 9,0x09, 7,0x0c, 7,0x1f, + 6,0x16, 6,0x06, 7,0x0e, 8,0x10, 6,0x03, 8,0x11, 6,0x0d, 7,0x14, + 9,0x12, 6,0x0f, 7,0x04, 9,0x0d, 6,0x00, 7,0x13, 6,0x01, 6,0x07, + 8,0x0d, 8,0x00, 6,0x06, 9,0x17, 6,0x14, 6,0x15, 6,0x11, 6,0x0b, + 9,0x0c, 6,0x1e, 13,0x14, 7,0x0e, 6,0x1d, 12,0x0a, 6,0x0b, 8,0x07, + 6,0x18, 6,0x0f, 6,0x10, 8,0x1c, 7,0x16, 7,0x02, 6,0x01, 6,0x13, + 10,0x15, 7,0x06, 8,0x14, 6,0x0c, 6,0x19, 7,0x10, 6,0x19, 6,0x19, + 9,0x16, 7,0x19, 6,0x1f, 6,0x17, 6,0x12, 8,0x02, 6,0x01, 6,0x04, + 6,0x15, 7,0x16, 6,0x04, 6,0x1f, 6,0x09, 7,0x06, 7,0x13, 7,0x09, + 6,0x0d, 10,0x18, 6,0x06, 6,0x11, 6,0x04, 6,0x01, 6,0x13, 8,0x06, + 6,0x0d, 8,0x13, 7,0x08, 6,0x08, 6,0x05, 7,0x0c, 7,0x0e, 7,0x15, + 6,0x05, 7,0x14, 10,0x19, 6,0x10, 6,0x16, 6,0x15, 7,0x1f, 6,0x14, + 6,0x0a, 10,0x11, 6,0x01, 7,0x05, 7,0x08, 8,0x0a, 7,0x1e, 7,0x1c, + 6,0x1c, 7,0x09, 10,0x18, 7,0x1c, 10,0x06, 6,0x0a, 6,0x07, 6,0x19, + 7,0x06, 6,0x0d, 7,0x0f, 7,0x0b, 7,0x05, 6,0x11, 6,0x1c, 7,0x1f, + 6,0x1e, 7,0x18, 6,0x1e, 6,0x00, 6,0x03, 6,0x02, 7,0x10, 6,0x0b, + 6,0x1b, 7,0x10, 6,0x00, 8,0x11, 7,0x1b, 6,0x18, 6,0x01, 7,0x0c, + 7,0x1d, 7,0x13, 6,0x08, 7,0x1b, 8,0x13, 7,0x16, 13,0x1d, 7,0x1f, + 6,0x0a, 6,0x01, 7,0x1f, 6,0x14, 1,0x01 +}; + +/* Invert the number, in Montgomery form, modulo the modulus (prime) of the + * P1024 curve. (r = 1 / a mod m) + * + * r Inverse result. + * a Number to invert. + * td Temporary data. + */ +static void sp_1024_mont_inv_32(sp_digit* r, const sp_digit* a, + sp_digit* td) +{ + sp_digit* t = td; + int i; + int j; + sp_digit table[32][2 * 32]; + + XMEMCPY(table[0], a, sizeof(sp_digit) * 32); + for (i = 1; i < 6; i++) { + sp_1024_mont_sqr_32(table[0], table[0], p1024_mod, p1024_mp_mod); + } + for (i = 1; i < 32; i++) { + sp_1024_mont_mul_32(table[i], table[i-1], a, p1024_mod, p1024_mp_mod); + } + + XMEMCPY(t, table[p1024_mod_minus_2[1]], sizeof(sp_digit) * 32); + for (i = 2; i < (int)sizeof(p1024_mod_minus_2) - 2; i += 2) { + for (j = 0; j < p1024_mod_minus_2[i]; j++) { + sp_1024_mont_sqr_32(t, t, p1024_mod, p1024_mp_mod); + } + sp_1024_mont_mul_32(t, t, table[p1024_mod_minus_2[i+1]], p1024_mod, + p1024_mp_mod); + } + sp_1024_mont_sqr_32(t, t, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(r, t, a, p1024_mod, p1024_mp_mod); +} + +/* Normalize the values in each word to 32. + * + * a Array of sp_digit to normalize. + */ +#define sp_1024_norm_32(a) + +/* Map the Montgomery form projective coordinate point to an affine point. + * + * r Resulting affine coordinate point. + * p Montgomery form projective coordinate point. + * t Temporary ordinate data. + */ +static void sp_1024_map_32(sp_point_1024* r, const sp_point_1024* p, + sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*32; + int32_t n; + + sp_1024_mont_inv_32(t1, p->z, t + 2*32); + + sp_1024_mont_sqr_32(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t1, t2, t1, p1024_mod, p1024_mp_mod); + + /* x /= z^2 */ + sp_1024_mont_mul_32(r->x, p->x, t2, p1024_mod, p1024_mp_mod); + XMEMSET(r->x + 32, 0, sizeof(r->x) / 2U); + sp_1024_mont_reduce_32(r->x, p1024_mod, p1024_mp_mod); + /* Reduce x to less than modulus */ + n = sp_1024_cmp_32(r->x, p1024_mod); + sp_1024_cond_sub_32(r->x, r->x, p1024_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_32(r->x); + + /* y /= z^3 */ + sp_1024_mont_mul_32(r->y, p->y, t1, p1024_mod, p1024_mp_mod); + XMEMSET(r->y + 32, 0, sizeof(r->y) / 2U); + sp_1024_mont_reduce_32(r->y, p1024_mod, p1024_mp_mod); + /* Reduce y to less than modulus */ + n = sp_1024_cmp_32(r->y, p1024_mod); + sp_1024_cond_sub_32(r->y, r->y, p1024_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_32(r->y); + + XMEMSET(r->z, 0, sizeof(r->z)); + r->z[0] = 1; + +} + +/* Add two Montgomery form numbers (r = a + b % m). + * + * r Result of addition. + * a First number to add in Montogmery form. + * b Second number to add in Montogmery form. + * m Modulus (prime). + */ +SP_NOINLINE static void sp_1024_mont_add_32(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + __asm__ __volatile__ ( + "ldr r4, [%[a], #0]\n\t" + "ldr r5, [%[a], #4]\n\t" + "ldr r6, [%[b], #0]\n\t" + "ldr r7, [%[b], #4]\n\t" + "add r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #0]\n\t" + "str r5, [%[r], #4]\n\t" + "ldr r4, [%[a], #8]\n\t" + "ldr r5, [%[a], #12]\n\t" + "ldr r6, [%[b], #8]\n\t" + "ldr r7, [%[b], #12]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #8]\n\t" + "str r5, [%[r], #12]\n\t" + "ldr r4, [%[a], #16]\n\t" + "ldr r5, [%[a], #20]\n\t" + "ldr r6, [%[b], #16]\n\t" + "ldr r7, [%[b], #20]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #16]\n\t" + "str r5, [%[r], #20]\n\t" + "ldr r4, [%[a], #24]\n\t" + "ldr r5, [%[a], #28]\n\t" + "ldr r6, [%[b], #24]\n\t" + "ldr r7, [%[b], #28]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #24]\n\t" + "str r5, [%[r], #28]\n\t" + "ldr r4, [%[a], #32]\n\t" + "ldr r5, [%[a], #36]\n\t" + "ldr r6, [%[b], #32]\n\t" + "ldr r7, [%[b], #36]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #32]\n\t" + "str r5, [%[r], #36]\n\t" + "ldr r4, [%[a], #40]\n\t" + "ldr r5, [%[a], #44]\n\t" + "ldr r6, [%[b], #40]\n\t" + "ldr r7, [%[b], #44]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #40]\n\t" + "str r5, [%[r], #44]\n\t" + "ldr r4, [%[a], #48]\n\t" + "ldr r5, [%[a], #52]\n\t" + "ldr r6, [%[b], #48]\n\t" + "ldr r7, [%[b], #52]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #48]\n\t" + "str r5, [%[r], #52]\n\t" + "ldr r4, [%[a], #56]\n\t" + "ldr r5, [%[a], #60]\n\t" + "ldr r6, [%[b], #56]\n\t" + "ldr r7, [%[b], #60]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #56]\n\t" + "str r5, [%[r], #60]\n\t" + "ldr r4, [%[a], #64]\n\t" + "ldr r5, [%[a], #68]\n\t" + "ldr r6, [%[b], #64]\n\t" + "ldr r7, [%[b], #68]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #64]\n\t" + "str r5, [%[r], #68]\n\t" + "ldr r4, [%[a], #72]\n\t" + "ldr r5, [%[a], #76]\n\t" + "ldr r6, [%[b], #72]\n\t" + "ldr r7, [%[b], #76]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #72]\n\t" + "str r5, [%[r], #76]\n\t" + "ldr r4, [%[a], #80]\n\t" + "ldr r5, [%[a], #84]\n\t" + "ldr r6, [%[b], #80]\n\t" + "ldr r7, [%[b], #84]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #80]\n\t" + "str r5, [%[r], #84]\n\t" + "ldr r4, [%[a], #88]\n\t" + "ldr r5, [%[a], #92]\n\t" + "ldr r6, [%[b], #88]\n\t" + "ldr r7, [%[b], #92]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #88]\n\t" + "str r5, [%[r], #92]\n\t" + "ldr r4, [%[a], #96]\n\t" + "ldr r5, [%[a], #100]\n\t" + "ldr r6, [%[b], #96]\n\t" + "ldr r7, [%[b], #100]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #96]\n\t" + "str r5, [%[r], #100]\n\t" + "ldr r4, [%[a], #104]\n\t" + "ldr r5, [%[a], #108]\n\t" + "ldr r6, [%[b], #104]\n\t" + "ldr r7, [%[b], #108]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #104]\n\t" + "str r5, [%[r], #108]\n\t" + "ldr r4, [%[a], #112]\n\t" + "ldr r5, [%[a], #116]\n\t" + "ldr r6, [%[b], #112]\n\t" + "ldr r7, [%[b], #116]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #112]\n\t" + "str r5, [%[r], #116]\n\t" + "ldr r4, [%[a], #120]\n\t" + "ldr r5, [%[a], #124]\n\t" + "ldr r6, [%[b], #120]\n\t" + "ldr r7, [%[b], #124]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #120]\n\t" + "str r5, [%[r], #124]\n\t" + "mov %[b], #0\n\t" + "ldr r7, [%[m], #124]\n\t" + "adc %[b], %[b]\n\t" + "sub r7, r5\n\t" + "neg %[b], %[b]\n\t" + "sbc r7, r7\n\t" + "orr %[b], r7\n\t" + "ldr r4, [%[r], #0]\n\t" + "ldr r5, [%[r], #4]\n\t" + "ldr r6, [%[m], #0]\n\t" + "ldr r7, [%[m], #4]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "sub r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #0]\n\t" + "str r5, [%[r], #4]\n\t" + "ldr r4, [%[r], #8]\n\t" + "ldr r5, [%[r], #12]\n\t" + "ldr r6, [%[m], #8]\n\t" + "ldr r7, [%[m], #12]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #8]\n\t" + "str r5, [%[r], #12]\n\t" + "ldr r4, [%[r], #16]\n\t" + "ldr r5, [%[r], #20]\n\t" + "ldr r6, [%[m], #16]\n\t" + "ldr r7, [%[m], #20]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #16]\n\t" + "str r5, [%[r], #20]\n\t" + "ldr r4, [%[r], #24]\n\t" + "ldr r5, [%[r], #28]\n\t" + "ldr r6, [%[m], #24]\n\t" + "ldr r7, [%[m], #28]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #24]\n\t" + "str r5, [%[r], #28]\n\t" + "ldr r4, [%[r], #32]\n\t" + "ldr r5, [%[r], #36]\n\t" + "ldr r6, [%[m], #32]\n\t" + "ldr r7, [%[m], #36]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #32]\n\t" + "str r5, [%[r], #36]\n\t" + "ldr r4, [%[r], #40]\n\t" + "ldr r5, [%[r], #44]\n\t" + "ldr r6, [%[m], #40]\n\t" + "ldr r7, [%[m], #44]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #40]\n\t" + "str r5, [%[r], #44]\n\t" + "ldr r4, [%[r], #48]\n\t" + "ldr r5, [%[r], #52]\n\t" + "ldr r6, [%[m], #48]\n\t" + "ldr r7, [%[m], #52]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #48]\n\t" + "str r5, [%[r], #52]\n\t" + "ldr r4, [%[r], #56]\n\t" + "ldr r5, [%[r], #60]\n\t" + "ldr r6, [%[m], #56]\n\t" + "ldr r7, [%[m], #60]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #56]\n\t" + "str r5, [%[r], #60]\n\t" + "ldr r4, [%[r], #64]\n\t" + "ldr r5, [%[r], #68]\n\t" + "ldr r6, [%[m], #64]\n\t" + "ldr r7, [%[m], #68]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #64]\n\t" + "str r5, [%[r], #68]\n\t" + "ldr r4, [%[r], #72]\n\t" + "ldr r5, [%[r], #76]\n\t" + "ldr r6, [%[m], #72]\n\t" + "ldr r7, [%[m], #76]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #72]\n\t" + "str r5, [%[r], #76]\n\t" + "ldr r4, [%[r], #80]\n\t" + "ldr r5, [%[r], #84]\n\t" + "ldr r6, [%[m], #80]\n\t" + "ldr r7, [%[m], #84]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #80]\n\t" + "str r5, [%[r], #84]\n\t" + "ldr r4, [%[r], #88]\n\t" + "ldr r5, [%[r], #92]\n\t" + "ldr r6, [%[m], #88]\n\t" + "ldr r7, [%[m], #92]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #88]\n\t" + "str r5, [%[r], #92]\n\t" + "ldr r4, [%[r], #96]\n\t" + "ldr r5, [%[r], #100]\n\t" + "ldr r6, [%[m], #96]\n\t" + "ldr r7, [%[m], #100]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #96]\n\t" + "str r5, [%[r], #100]\n\t" + "ldr r4, [%[r], #104]\n\t" + "ldr r5, [%[r], #108]\n\t" + "ldr r6, [%[m], #104]\n\t" + "ldr r7, [%[m], #108]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #104]\n\t" + "str r5, [%[r], #108]\n\t" + "ldr r4, [%[r], #112]\n\t" + "ldr r5, [%[r], #116]\n\t" + "ldr r6, [%[m], #112]\n\t" + "ldr r7, [%[m], #116]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #112]\n\t" + "str r5, [%[r], #116]\n\t" + "ldr r4, [%[r], #120]\n\t" + "ldr r5, [%[r], #124]\n\t" + "ldr r6, [%[m], #120]\n\t" + "ldr r7, [%[m], #124]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #120]\n\t" + "str r5, [%[r], #124]\n\t" + : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) + : + : "memory", "r4", "r5", "r6", "r7" + ); +} + +/* Double a Montgomery form number (r = a + a % m). + * + * r Result of doubling. + * a Number to double in Montogmery form. + * m Modulus (prime). + */ +SP_NOINLINE static void sp_1024_mont_dbl_32(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + __asm__ __volatile__ ( + "ldr r4, [%[a], #0]\n\t" + "ldr r5, [%[a], #4]\n\t" + "ldr r6, [%[a], #8]\n\t" + "ldr r7, [%[a], #12]\n\t" + "add r4, r4\n\t" + "adc r5, r5\n\t" + "adc r6, r6\n\t" + "adc r7, r7\n\t" + "str r4, [%[r], #0]\n\t" + "str r5, [%[r], #4]\n\t" + "str r6, [%[r], #8]\n\t" + "str r7, [%[r], #12]\n\t" + "ldr r4, [%[a], #16]\n\t" + "ldr r5, [%[a], #20]\n\t" + "ldr r6, [%[a], #24]\n\t" + "ldr r7, [%[a], #28]\n\t" + "adc r4, r4\n\t" + "adc r5, r5\n\t" + "adc r6, r6\n\t" + "adc r7, r7\n\t" + "str r4, [%[r], #16]\n\t" + "str r5, [%[r], #20]\n\t" + "str r6, [%[r], #24]\n\t" + "str r7, [%[r], #28]\n\t" + "ldr r4, [%[a], #32]\n\t" + "ldr r5, [%[a], #36]\n\t" + "ldr r6, [%[a], #40]\n\t" + "ldr r7, [%[a], #44]\n\t" + "adc r4, r4\n\t" + "adc r5, r5\n\t" + "adc r6, r6\n\t" + "adc r7, r7\n\t" + "str r4, [%[r], #32]\n\t" + "str r5, [%[r], #36]\n\t" + "str r6, [%[r], #40]\n\t" + "str r7, [%[r], #44]\n\t" + "ldr r4, [%[a], #48]\n\t" + "ldr r5, [%[a], #52]\n\t" + "ldr r6, [%[a], #56]\n\t" + "ldr r7, [%[a], #60]\n\t" + "adc r4, r4\n\t" + "adc r5, r5\n\t" + "adc r6, r6\n\t" + "adc r7, r7\n\t" + "str r4, [%[r], #48]\n\t" + "str r5, [%[r], #52]\n\t" + "str r6, [%[r], #56]\n\t" + "str r7, [%[r], #60]\n\t" + "ldr r4, [%[a], #64]\n\t" + "ldr r5, [%[a], #68]\n\t" + "ldr r6, [%[a], #72]\n\t" + "ldr r7, [%[a], #76]\n\t" + "adc r4, r4\n\t" + "adc r5, r5\n\t" + "adc r6, r6\n\t" + "adc r7, r7\n\t" + "str r4, [%[r], #64]\n\t" + "str r5, [%[r], #68]\n\t" + "str r6, [%[r], #72]\n\t" + "str r7, [%[r], #76]\n\t" + "ldr r4, [%[a], #80]\n\t" + "ldr r5, [%[a], #84]\n\t" + "ldr r6, [%[a], #88]\n\t" + "ldr r7, [%[a], #92]\n\t" + "adc r4, r4\n\t" + "adc r5, r5\n\t" + "adc r6, r6\n\t" + "adc r7, r7\n\t" + "str r4, [%[r], #80]\n\t" + "str r5, [%[r], #84]\n\t" + "str r6, [%[r], #88]\n\t" + "str r7, [%[r], #92]\n\t" + "ldr r4, [%[a], #96]\n\t" + "ldr r5, [%[a], #100]\n\t" + "ldr r6, [%[a], #104]\n\t" + "ldr r7, [%[a], #108]\n\t" + "adc r4, r4\n\t" + "adc r5, r5\n\t" + "adc r6, r6\n\t" + "adc r7, r7\n\t" + "str r4, [%[r], #96]\n\t" + "str r5, [%[r], #100]\n\t" + "str r6, [%[r], #104]\n\t" + "str r7, [%[r], #108]\n\t" + "ldr r4, [%[a], #112]\n\t" + "ldr r5, [%[a], #116]\n\t" + "ldr r6, [%[a], #120]\n\t" + "ldr r7, [%[a], #124]\n\t" + "adc r4, r4\n\t" + "adc r5, r5\n\t" + "adc r6, r6\n\t" + "adc r7, r7\n\t" + "str r4, [%[r], #112]\n\t" + "str r5, [%[r], #116]\n\t" + "str r6, [%[r], #120]\n\t" + "str r7, [%[r], #124]\n\t" + "mov r3, #0\n\t" + "ldr r4, [%[m], #124]\n\t" + "adc r3, r3\n\t" + "sub r4, r7\n\t" + "neg r3, r3\n\t" + "sbc r4, r4\n\t" + "orr r3, r4\n\t" + "ldr r4, [%[r], #0]\n\t" + "ldr r5, [%[r], #4]\n\t" + "ldr r6, [%[m], #0]\n\t" + "ldr r7, [%[m], #4]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sub r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #0]\n\t" + "str r5, [%[r], #4]\n\t" + "ldr r4, [%[r], #8]\n\t" + "ldr r5, [%[r], #12]\n\t" + "ldr r6, [%[m], #8]\n\t" + "ldr r7, [%[m], #12]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #8]\n\t" + "str r5, [%[r], #12]\n\t" + "ldr r4, [%[r], #16]\n\t" + "ldr r5, [%[r], #20]\n\t" + "ldr r6, [%[m], #16]\n\t" + "ldr r7, [%[m], #20]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #16]\n\t" + "str r5, [%[r], #20]\n\t" + "ldr r4, [%[r], #24]\n\t" + "ldr r5, [%[r], #28]\n\t" + "ldr r6, [%[m], #24]\n\t" + "ldr r7, [%[m], #28]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #24]\n\t" + "str r5, [%[r], #28]\n\t" + "ldr r4, [%[r], #32]\n\t" + "ldr r5, [%[r], #36]\n\t" + "ldr r6, [%[m], #32]\n\t" + "ldr r7, [%[m], #36]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #32]\n\t" + "str r5, [%[r], #36]\n\t" + "ldr r4, [%[r], #40]\n\t" + "ldr r5, [%[r], #44]\n\t" + "ldr r6, [%[m], #40]\n\t" + "ldr r7, [%[m], #44]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #40]\n\t" + "str r5, [%[r], #44]\n\t" + "ldr r4, [%[r], #48]\n\t" + "ldr r5, [%[r], #52]\n\t" + "ldr r6, [%[m], #48]\n\t" + "ldr r7, [%[m], #52]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #48]\n\t" + "str r5, [%[r], #52]\n\t" + "ldr r4, [%[r], #56]\n\t" + "ldr r5, [%[r], #60]\n\t" + "ldr r6, [%[m], #56]\n\t" + "ldr r7, [%[m], #60]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #56]\n\t" + "str r5, [%[r], #60]\n\t" + "ldr r4, [%[r], #64]\n\t" + "ldr r5, [%[r], #68]\n\t" + "ldr r6, [%[m], #64]\n\t" + "ldr r7, [%[m], #68]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #64]\n\t" + "str r5, [%[r], #68]\n\t" + "ldr r4, [%[r], #72]\n\t" + "ldr r5, [%[r], #76]\n\t" + "ldr r6, [%[m], #72]\n\t" + "ldr r7, [%[m], #76]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #72]\n\t" + "str r5, [%[r], #76]\n\t" + "ldr r4, [%[r], #80]\n\t" + "ldr r5, [%[r], #84]\n\t" + "ldr r6, [%[m], #80]\n\t" + "ldr r7, [%[m], #84]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #80]\n\t" + "str r5, [%[r], #84]\n\t" + "ldr r4, [%[r], #88]\n\t" + "ldr r5, [%[r], #92]\n\t" + "ldr r6, [%[m], #88]\n\t" + "ldr r7, [%[m], #92]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #88]\n\t" + "str r5, [%[r], #92]\n\t" + "ldr r4, [%[r], #96]\n\t" + "ldr r5, [%[r], #100]\n\t" + "ldr r6, [%[m], #96]\n\t" + "ldr r7, [%[m], #100]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #96]\n\t" + "str r5, [%[r], #100]\n\t" + "ldr r4, [%[r], #104]\n\t" + "ldr r5, [%[r], #108]\n\t" + "ldr r6, [%[m], #104]\n\t" + "ldr r7, [%[m], #108]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #104]\n\t" + "str r5, [%[r], #108]\n\t" + "ldr r4, [%[r], #112]\n\t" + "ldr r5, [%[r], #116]\n\t" + "ldr r6, [%[m], #112]\n\t" + "ldr r7, [%[m], #116]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #112]\n\t" + "str r5, [%[r], #116]\n\t" + "ldr r4, [%[r], #120]\n\t" + "ldr r5, [%[r], #124]\n\t" + "ldr r6, [%[m], #120]\n\t" + "ldr r7, [%[m], #124]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #120]\n\t" + "str r5, [%[r], #124]\n\t" + : [r] "+r" (r), [a] "+r" (a), [m] "+r" (m) + : + : "memory", "r4", "r5", "r6", "r7", "r3" + ); +} + +/* Triple a Montgomery form number (r = a + a + a % m). + * + * r Result of Tripling. + * a Number to triple in Montogmery form. + * m Modulus (prime). + */ +SP_NOINLINE static void sp_1024_mont_tpl_32(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + __asm__ __volatile__ ( + "ldr r4, [%[a], #0]\n\t" + "ldr r5, [%[a], #4]\n\t" + "ldr r6, [%[a], #8]\n\t" + "ldr r7, [%[a], #12]\n\t" + "add r4, r4\n\t" + "adc r5, r5\n\t" + "adc r6, r6\n\t" + "adc r7, r7\n\t" + "str r4, [%[r], #0]\n\t" + "str r5, [%[r], #4]\n\t" + "str r6, [%[r], #8]\n\t" + "str r7, [%[r], #12]\n\t" + "ldr r4, [%[a], #16]\n\t" + "ldr r5, [%[a], #20]\n\t" + "ldr r6, [%[a], #24]\n\t" + "ldr r7, [%[a], #28]\n\t" + "adc r4, r4\n\t" + "adc r5, r5\n\t" + "adc r6, r6\n\t" + "adc r7, r7\n\t" + "str r4, [%[r], #16]\n\t" + "str r5, [%[r], #20]\n\t" + "str r6, [%[r], #24]\n\t" + "str r7, [%[r], #28]\n\t" + "ldr r4, [%[a], #32]\n\t" + "ldr r5, [%[a], #36]\n\t" + "ldr r6, [%[a], #40]\n\t" + "ldr r7, [%[a], #44]\n\t" + "adc r4, r4\n\t" + "adc r5, r5\n\t" + "adc r6, r6\n\t" + "adc r7, r7\n\t" + "str r4, [%[r], #32]\n\t" + "str r5, [%[r], #36]\n\t" + "str r6, [%[r], #40]\n\t" + "str r7, [%[r], #44]\n\t" + "ldr r4, [%[a], #48]\n\t" + "ldr r5, [%[a], #52]\n\t" + "ldr r6, [%[a], #56]\n\t" + "ldr r7, [%[a], #60]\n\t" + "adc r4, r4\n\t" + "adc r5, r5\n\t" + "adc r6, r6\n\t" + "adc r7, r7\n\t" + "str r4, [%[r], #48]\n\t" + "str r5, [%[r], #52]\n\t" + "str r6, [%[r], #56]\n\t" + "str r7, [%[r], #60]\n\t" + "ldr r4, [%[a], #64]\n\t" + "ldr r5, [%[a], #68]\n\t" + "ldr r6, [%[a], #72]\n\t" + "ldr r7, [%[a], #76]\n\t" + "adc r4, r4\n\t" + "adc r5, r5\n\t" + "adc r6, r6\n\t" + "adc r7, r7\n\t" + "str r4, [%[r], #64]\n\t" + "str r5, [%[r], #68]\n\t" + "str r6, [%[r], #72]\n\t" + "str r7, [%[r], #76]\n\t" + "ldr r4, [%[a], #80]\n\t" + "ldr r5, [%[a], #84]\n\t" + "ldr r6, [%[a], #88]\n\t" + "ldr r7, [%[a], #92]\n\t" + "adc r4, r4\n\t" + "adc r5, r5\n\t" + "adc r6, r6\n\t" + "adc r7, r7\n\t" + "str r4, [%[r], #80]\n\t" + "str r5, [%[r], #84]\n\t" + "str r6, [%[r], #88]\n\t" + "str r7, [%[r], #92]\n\t" + "ldr r4, [%[a], #96]\n\t" + "ldr r5, [%[a], #100]\n\t" + "ldr r6, [%[a], #104]\n\t" + "ldr r7, [%[a], #108]\n\t" + "adc r4, r4\n\t" + "adc r5, r5\n\t" + "adc r6, r6\n\t" + "adc r7, r7\n\t" + "str r4, [%[r], #96]\n\t" + "str r5, [%[r], #100]\n\t" + "str r6, [%[r], #104]\n\t" + "str r7, [%[r], #108]\n\t" + "ldr r4, [%[a], #112]\n\t" + "ldr r5, [%[a], #116]\n\t" + "ldr r6, [%[a], #120]\n\t" + "ldr r7, [%[a], #124]\n\t" + "adc r4, r4\n\t" + "adc r5, r5\n\t" + "adc r6, r6\n\t" + "adc r7, r7\n\t" + "str r4, [%[r], #112]\n\t" + "str r5, [%[r], #116]\n\t" + "str r6, [%[r], #120]\n\t" + "str r7, [%[r], #124]\n\t" + "mov r3, #0\n\t" + "ldr r4, [%[m], #124]\n\t" + "adc r3, r3\n\t" + "sub r4, r7\n\t" + "neg r3, r3\n\t" + "sbc r4, r4\n\t" + "orr r3, r4\n\t" + "ldr r4, [%[r], #0]\n\t" + "ldr r5, [%[r], #4]\n\t" + "ldr r6, [%[m], #0]\n\t" + "ldr r7, [%[m], #4]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sub r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #0]\n\t" + "str r5, [%[r], #4]\n\t" + "ldr r4, [%[r], #8]\n\t" + "ldr r5, [%[r], #12]\n\t" + "ldr r6, [%[m], #8]\n\t" + "ldr r7, [%[m], #12]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #8]\n\t" + "str r5, [%[r], #12]\n\t" + "ldr r4, [%[r], #16]\n\t" + "ldr r5, [%[r], #20]\n\t" + "ldr r6, [%[m], #16]\n\t" + "ldr r7, [%[m], #20]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #16]\n\t" + "str r5, [%[r], #20]\n\t" + "ldr r4, [%[r], #24]\n\t" + "ldr r5, [%[r], #28]\n\t" + "ldr r6, [%[m], #24]\n\t" + "ldr r7, [%[m], #28]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #24]\n\t" + "str r5, [%[r], #28]\n\t" + "ldr r4, [%[r], #32]\n\t" + "ldr r5, [%[r], #36]\n\t" + "ldr r6, [%[m], #32]\n\t" + "ldr r7, [%[m], #36]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #32]\n\t" + "str r5, [%[r], #36]\n\t" + "ldr r4, [%[r], #40]\n\t" + "ldr r5, [%[r], #44]\n\t" + "ldr r6, [%[m], #40]\n\t" + "ldr r7, [%[m], #44]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #40]\n\t" + "str r5, [%[r], #44]\n\t" + "ldr r4, [%[r], #48]\n\t" + "ldr r5, [%[r], #52]\n\t" + "ldr r6, [%[m], #48]\n\t" + "ldr r7, [%[m], #52]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #48]\n\t" + "str r5, [%[r], #52]\n\t" + "ldr r4, [%[r], #56]\n\t" + "ldr r5, [%[r], #60]\n\t" + "ldr r6, [%[m], #56]\n\t" + "ldr r7, [%[m], #60]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #56]\n\t" + "str r5, [%[r], #60]\n\t" + "ldr r4, [%[r], #64]\n\t" + "ldr r5, [%[r], #68]\n\t" + "ldr r6, [%[m], #64]\n\t" + "ldr r7, [%[m], #68]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #64]\n\t" + "str r5, [%[r], #68]\n\t" + "ldr r4, [%[r], #72]\n\t" + "ldr r5, [%[r], #76]\n\t" + "ldr r6, [%[m], #72]\n\t" + "ldr r7, [%[m], #76]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #72]\n\t" + "str r5, [%[r], #76]\n\t" + "ldr r4, [%[r], #80]\n\t" + "ldr r5, [%[r], #84]\n\t" + "ldr r6, [%[m], #80]\n\t" + "ldr r7, [%[m], #84]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #80]\n\t" + "str r5, [%[r], #84]\n\t" + "ldr r4, [%[r], #88]\n\t" + "ldr r5, [%[r], #92]\n\t" + "ldr r6, [%[m], #88]\n\t" + "ldr r7, [%[m], #92]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #88]\n\t" + "str r5, [%[r], #92]\n\t" + "ldr r4, [%[r], #96]\n\t" + "ldr r5, [%[r], #100]\n\t" + "ldr r6, [%[m], #96]\n\t" + "ldr r7, [%[m], #100]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #96]\n\t" + "str r5, [%[r], #100]\n\t" + "ldr r4, [%[r], #104]\n\t" + "ldr r5, [%[r], #108]\n\t" + "ldr r6, [%[m], #104]\n\t" + "ldr r7, [%[m], #108]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #104]\n\t" + "str r5, [%[r], #108]\n\t" + "ldr r4, [%[r], #112]\n\t" + "ldr r5, [%[r], #116]\n\t" + "ldr r6, [%[m], #112]\n\t" + "ldr r7, [%[m], #116]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #112]\n\t" + "str r5, [%[r], #116]\n\t" + "ldr r4, [%[r], #120]\n\t" + "ldr r5, [%[r], #124]\n\t" + "ldr r6, [%[m], #120]\n\t" + "ldr r7, [%[m], #124]\n\t" + "and r6, r3\n\t" + "and r7, r3\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #120]\n\t" + "str r5, [%[r], #124]\n\t" + "ldr r4, [%[a], #0]\n\t" + "ldr r5, [%[a], #4]\n\t" + "ldr r6, [%[r], #0]\n\t" + "ldr r7, [%[r], #4]\n\t" + "add r6, r4\n\t" + "adc r7, r5\n\t" + "str r6, [%[r], #0]\n\t" + "str r7, [%[r], #4]\n\t" + "ldr r4, [%[a], #8]\n\t" + "ldr r5, [%[a], #12]\n\t" + "ldr r6, [%[r], #8]\n\t" + "ldr r7, [%[r], #12]\n\t" + "adc r6, r4\n\t" + "adc r7, r5\n\t" + "str r6, [%[r], #8]\n\t" + "str r7, [%[r], #12]\n\t" + "ldr r4, [%[a], #16]\n\t" + "ldr r5, [%[a], #20]\n\t" + "ldr r6, [%[r], #16]\n\t" + "ldr r7, [%[r], #20]\n\t" + "adc r6, r4\n\t" + "adc r7, r5\n\t" + "str r6, [%[r], #16]\n\t" + "str r7, [%[r], #20]\n\t" + "ldr r4, [%[a], #24]\n\t" + "ldr r5, [%[a], #28]\n\t" + "ldr r6, [%[r], #24]\n\t" + "ldr r7, [%[r], #28]\n\t" + "adc r6, r4\n\t" + "adc r7, r5\n\t" + "str r6, [%[r], #24]\n\t" + "str r7, [%[r], #28]\n\t" + "ldr r4, [%[a], #32]\n\t" + "ldr r5, [%[a], #36]\n\t" + "ldr r6, [%[r], #32]\n\t" + "ldr r7, [%[r], #36]\n\t" + "adc r6, r4\n\t" + "adc r7, r5\n\t" + "str r6, [%[r], #32]\n\t" + "str r7, [%[r], #36]\n\t" + "ldr r4, [%[a], #40]\n\t" + "ldr r5, [%[a], #44]\n\t" + "ldr r6, [%[r], #40]\n\t" + "ldr r7, [%[r], #44]\n\t" + "adc r6, r4\n\t" + "adc r7, r5\n\t" + "str r6, [%[r], #40]\n\t" + "str r7, [%[r], #44]\n\t" + "ldr r4, [%[a], #48]\n\t" + "ldr r5, [%[a], #52]\n\t" + "ldr r6, [%[r], #48]\n\t" + "ldr r7, [%[r], #52]\n\t" + "adc r6, r4\n\t" + "adc r7, r5\n\t" + "str r6, [%[r], #48]\n\t" + "str r7, [%[r], #52]\n\t" + "ldr r4, [%[a], #56]\n\t" + "ldr r5, [%[a], #60]\n\t" + "ldr r6, [%[r], #56]\n\t" + "ldr r7, [%[r], #60]\n\t" + "adc r6, r4\n\t" + "adc r7, r5\n\t" + "str r6, [%[r], #56]\n\t" + "str r7, [%[r], #60]\n\t" + "ldr r4, [%[a], #64]\n\t" + "ldr r5, [%[a], #68]\n\t" + "ldr r6, [%[r], #64]\n\t" + "ldr r7, [%[r], #68]\n\t" + "adc r6, r4\n\t" + "adc r7, r5\n\t" + "str r6, [%[r], #64]\n\t" + "str r7, [%[r], #68]\n\t" + "ldr r4, [%[a], #72]\n\t" + "ldr r5, [%[a], #76]\n\t" + "ldr r6, [%[r], #72]\n\t" + "ldr r7, [%[r], #76]\n\t" + "adc r6, r4\n\t" + "adc r7, r5\n\t" + "str r6, [%[r], #72]\n\t" + "str r7, [%[r], #76]\n\t" + "ldr r4, [%[a], #80]\n\t" + "ldr r5, [%[a], #84]\n\t" + "ldr r6, [%[r], #80]\n\t" + "ldr r7, [%[r], #84]\n\t" + "adc r6, r4\n\t" + "adc r7, r5\n\t" + "str r6, [%[r], #80]\n\t" + "str r7, [%[r], #84]\n\t" + "ldr r4, [%[a], #88]\n\t" + "ldr r5, [%[a], #92]\n\t" + "ldr r6, [%[r], #88]\n\t" + "ldr r7, [%[r], #92]\n\t" + "adc r6, r4\n\t" + "adc r7, r5\n\t" + "str r6, [%[r], #88]\n\t" + "str r7, [%[r], #92]\n\t" + "ldr r4, [%[a], #96]\n\t" + "ldr r5, [%[a], #100]\n\t" + "ldr r6, [%[r], #96]\n\t" + "ldr r7, [%[r], #100]\n\t" + "adc r6, r4\n\t" + "adc r7, r5\n\t" + "str r6, [%[r], #96]\n\t" + "str r7, [%[r], #100]\n\t" + "ldr r4, [%[a], #104]\n\t" + "ldr r5, [%[a], #108]\n\t" + "ldr r6, [%[r], #104]\n\t" + "ldr r7, [%[r], #108]\n\t" + "adc r6, r4\n\t" + "adc r7, r5\n\t" + "str r6, [%[r], #104]\n\t" + "str r7, [%[r], #108]\n\t" + "ldr r4, [%[a], #112]\n\t" + "ldr r5, [%[a], #116]\n\t" + "ldr r6, [%[r], #112]\n\t" + "ldr r7, [%[r], #116]\n\t" + "adc r6, r4\n\t" + "adc r7, r5\n\t" + "str r6, [%[r], #112]\n\t" + "str r7, [%[r], #116]\n\t" + "ldr r4, [%[a], #120]\n\t" + "ldr r5, [%[a], #124]\n\t" + "ldr r6, [%[r], #120]\n\t" + "ldr r7, [%[r], #124]\n\t" + "adc r6, r4\n\t" + "adc r7, r5\n\t" + "str r6, [%[r], #120]\n\t" + "str r7, [%[r], #124]\n\t" + "mov r3, #0\n\t" + "ldr r5, [%[m], #124]\n\t" + "adc r3, r3\n\t" + "sub r5, r7\n\t" + "neg r3, r3\n\t" + "sbc r5, r5\n\t" + "orr r3, r5\n\t" + "ldr r6, [%[r], #0]\n\t" + "ldr r7, [%[r], #4]\n\t" + "ldr r4, [%[m], #0]\n\t" + "ldr r5, [%[m], #4]\n\t" + "and r4, r3\n\t" + "and r5, r3\n\t" + "sub r6, r4\n\t" + "sbc r7, r5\n\t" + "str r6, [%[r], #0]\n\t" + "str r7, [%[r], #4]\n\t" + "ldr r6, [%[r], #8]\n\t" + "ldr r7, [%[r], #12]\n\t" + "ldr r4, [%[m], #8]\n\t" + "ldr r5, [%[m], #12]\n\t" + "and r4, r3\n\t" + "and r5, r3\n\t" + "sbc r6, r4\n\t" + "sbc r7, r5\n\t" + "str r6, [%[r], #8]\n\t" + "str r7, [%[r], #12]\n\t" + "ldr r6, [%[r], #16]\n\t" + "ldr r7, [%[r], #20]\n\t" + "ldr r4, [%[m], #16]\n\t" + "ldr r5, [%[m], #20]\n\t" + "and r4, r3\n\t" + "and r5, r3\n\t" + "sbc r6, r4\n\t" + "sbc r7, r5\n\t" + "str r6, [%[r], #16]\n\t" + "str r7, [%[r], #20]\n\t" + "ldr r6, [%[r], #24]\n\t" + "ldr r7, [%[r], #28]\n\t" + "ldr r4, [%[m], #24]\n\t" + "ldr r5, [%[m], #28]\n\t" + "and r4, r3\n\t" + "and r5, r3\n\t" + "sbc r6, r4\n\t" + "sbc r7, r5\n\t" + "str r6, [%[r], #24]\n\t" + "str r7, [%[r], #28]\n\t" + "ldr r6, [%[r], #32]\n\t" + "ldr r7, [%[r], #36]\n\t" + "ldr r4, [%[m], #32]\n\t" + "ldr r5, [%[m], #36]\n\t" + "and r4, r3\n\t" + "and r5, r3\n\t" + "sbc r6, r4\n\t" + "sbc r7, r5\n\t" + "str r6, [%[r], #32]\n\t" + "str r7, [%[r], #36]\n\t" + "ldr r6, [%[r], #40]\n\t" + "ldr r7, [%[r], #44]\n\t" + "ldr r4, [%[m], #40]\n\t" + "ldr r5, [%[m], #44]\n\t" + "and r4, r3\n\t" + "and r5, r3\n\t" + "sbc r6, r4\n\t" + "sbc r7, r5\n\t" + "str r6, [%[r], #40]\n\t" + "str r7, [%[r], #44]\n\t" + "ldr r6, [%[r], #48]\n\t" + "ldr r7, [%[r], #52]\n\t" + "ldr r4, [%[m], #48]\n\t" + "ldr r5, [%[m], #52]\n\t" + "and r4, r3\n\t" + "and r5, r3\n\t" + "sbc r6, r4\n\t" + "sbc r7, r5\n\t" + "str r6, [%[r], #48]\n\t" + "str r7, [%[r], #52]\n\t" + "ldr r6, [%[r], #56]\n\t" + "ldr r7, [%[r], #60]\n\t" + "ldr r4, [%[m], #56]\n\t" + "ldr r5, [%[m], #60]\n\t" + "and r4, r3\n\t" + "and r5, r3\n\t" + "sbc r6, r4\n\t" + "sbc r7, r5\n\t" + "str r6, [%[r], #56]\n\t" + "str r7, [%[r], #60]\n\t" + "ldr r6, [%[r], #64]\n\t" + "ldr r7, [%[r], #68]\n\t" + "ldr r4, [%[m], #64]\n\t" + "ldr r5, [%[m], #68]\n\t" + "and r4, r3\n\t" + "and r5, r3\n\t" + "sbc r6, r4\n\t" + "sbc r7, r5\n\t" + "str r6, [%[r], #64]\n\t" + "str r7, [%[r], #68]\n\t" + "ldr r6, [%[r], #72]\n\t" + "ldr r7, [%[r], #76]\n\t" + "ldr r4, [%[m], #72]\n\t" + "ldr r5, [%[m], #76]\n\t" + "and r4, r3\n\t" + "and r5, r3\n\t" + "sbc r6, r4\n\t" + "sbc r7, r5\n\t" + "str r6, [%[r], #72]\n\t" + "str r7, [%[r], #76]\n\t" + "ldr r6, [%[r], #80]\n\t" + "ldr r7, [%[r], #84]\n\t" + "ldr r4, [%[m], #80]\n\t" + "ldr r5, [%[m], #84]\n\t" + "and r4, r3\n\t" + "and r5, r3\n\t" + "sbc r6, r4\n\t" + "sbc r7, r5\n\t" + "str r6, [%[r], #80]\n\t" + "str r7, [%[r], #84]\n\t" + "ldr r6, [%[r], #88]\n\t" + "ldr r7, [%[r], #92]\n\t" + "ldr r4, [%[m], #88]\n\t" + "ldr r5, [%[m], #92]\n\t" + "and r4, r3\n\t" + "and r5, r3\n\t" + "sbc r6, r4\n\t" + "sbc r7, r5\n\t" + "str r6, [%[r], #88]\n\t" + "str r7, [%[r], #92]\n\t" + "ldr r6, [%[r], #96]\n\t" + "ldr r7, [%[r], #100]\n\t" + "ldr r4, [%[m], #96]\n\t" + "ldr r5, [%[m], #100]\n\t" + "and r4, r3\n\t" + "and r5, r3\n\t" + "sbc r6, r4\n\t" + "sbc r7, r5\n\t" + "str r6, [%[r], #96]\n\t" + "str r7, [%[r], #100]\n\t" + "ldr r6, [%[r], #104]\n\t" + "ldr r7, [%[r], #108]\n\t" + "ldr r4, [%[m], #104]\n\t" + "ldr r5, [%[m], #108]\n\t" + "and r4, r3\n\t" + "and r5, r3\n\t" + "sbc r6, r4\n\t" + "sbc r7, r5\n\t" + "str r6, [%[r], #104]\n\t" + "str r7, [%[r], #108]\n\t" + "ldr r6, [%[r], #112]\n\t" + "ldr r7, [%[r], #116]\n\t" + "ldr r4, [%[m], #112]\n\t" + "ldr r5, [%[m], #116]\n\t" + "and r4, r3\n\t" + "and r5, r3\n\t" + "sbc r6, r4\n\t" + "sbc r7, r5\n\t" + "str r6, [%[r], #112]\n\t" + "str r7, [%[r], #116]\n\t" + "ldr r6, [%[r], #120]\n\t" + "ldr r7, [%[r], #124]\n\t" + "ldr r4, [%[m], #120]\n\t" + "ldr r5, [%[m], #124]\n\t" + "and r4, r3\n\t" + "and r5, r3\n\t" + "sbc r6, r4\n\t" + "sbc r7, r5\n\t" + "str r6, [%[r], #120]\n\t" + "str r7, [%[r], #124]\n\t" + : [r] "+r" (r), [a] "+r" (a), [m] "+r" (m) + : + : "memory", "r4", "r5", "r6", "r7", "r3" + ); +} + +/* Subtract two Montgomery form numbers (r = a - b % m). + * + * r Result of subtration. + * a Number to subtract from in Montogmery form. + * b Number to subtract with in Montogmery form. + * m Modulus (prime). + */ +SP_NOINLINE static void sp_1024_mont_sub_32(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + __asm__ __volatile__ ( + "ldr r4, [%[a], #0]\n\t" + "ldr r5, [%[a], #4]\n\t" + "ldr r6, [%[b], #0]\n\t" + "ldr r7, [%[b], #4]\n\t" + "sub r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #0]\n\t" + "str r5, [%[r], #4]\n\t" + "ldr r4, [%[a], #8]\n\t" + "ldr r5, [%[a], #12]\n\t" + "ldr r6, [%[b], #8]\n\t" + "ldr r7, [%[b], #12]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #8]\n\t" + "str r5, [%[r], #12]\n\t" + "ldr r4, [%[a], #16]\n\t" + "ldr r5, [%[a], #20]\n\t" + "ldr r6, [%[b], #16]\n\t" + "ldr r7, [%[b], #20]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #16]\n\t" + "str r5, [%[r], #20]\n\t" + "ldr r4, [%[a], #24]\n\t" + "ldr r5, [%[a], #28]\n\t" + "ldr r6, [%[b], #24]\n\t" + "ldr r7, [%[b], #28]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #24]\n\t" + "str r5, [%[r], #28]\n\t" + "ldr r4, [%[a], #32]\n\t" + "ldr r5, [%[a], #36]\n\t" + "ldr r6, [%[b], #32]\n\t" + "ldr r7, [%[b], #36]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #32]\n\t" + "str r5, [%[r], #36]\n\t" + "ldr r4, [%[a], #40]\n\t" + "ldr r5, [%[a], #44]\n\t" + "ldr r6, [%[b], #40]\n\t" + "ldr r7, [%[b], #44]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #40]\n\t" + "str r5, [%[r], #44]\n\t" + "ldr r4, [%[a], #48]\n\t" + "ldr r5, [%[a], #52]\n\t" + "ldr r6, [%[b], #48]\n\t" + "ldr r7, [%[b], #52]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #48]\n\t" + "str r5, [%[r], #52]\n\t" + "ldr r4, [%[a], #56]\n\t" + "ldr r5, [%[a], #60]\n\t" + "ldr r6, [%[b], #56]\n\t" + "ldr r7, [%[b], #60]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #56]\n\t" + "str r5, [%[r], #60]\n\t" + "ldr r4, [%[a], #64]\n\t" + "ldr r5, [%[a], #68]\n\t" + "ldr r6, [%[b], #64]\n\t" + "ldr r7, [%[b], #68]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #64]\n\t" + "str r5, [%[r], #68]\n\t" + "ldr r4, [%[a], #72]\n\t" + "ldr r5, [%[a], #76]\n\t" + "ldr r6, [%[b], #72]\n\t" + "ldr r7, [%[b], #76]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #72]\n\t" + "str r5, [%[r], #76]\n\t" + "ldr r4, [%[a], #80]\n\t" + "ldr r5, [%[a], #84]\n\t" + "ldr r6, [%[b], #80]\n\t" + "ldr r7, [%[b], #84]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #80]\n\t" + "str r5, [%[r], #84]\n\t" + "ldr r4, [%[a], #88]\n\t" + "ldr r5, [%[a], #92]\n\t" + "ldr r6, [%[b], #88]\n\t" + "ldr r7, [%[b], #92]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #88]\n\t" + "str r5, [%[r], #92]\n\t" + "ldr r4, [%[a], #96]\n\t" + "ldr r5, [%[a], #100]\n\t" + "ldr r6, [%[b], #96]\n\t" + "ldr r7, [%[b], #100]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #96]\n\t" + "str r5, [%[r], #100]\n\t" + "ldr r4, [%[a], #104]\n\t" + "ldr r5, [%[a], #108]\n\t" + "ldr r6, [%[b], #104]\n\t" + "ldr r7, [%[b], #108]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #104]\n\t" + "str r5, [%[r], #108]\n\t" + "ldr r4, [%[a], #112]\n\t" + "ldr r5, [%[a], #116]\n\t" + "ldr r6, [%[b], #112]\n\t" + "ldr r7, [%[b], #116]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #112]\n\t" + "str r5, [%[r], #116]\n\t" + "ldr r4, [%[a], #120]\n\t" + "ldr r5, [%[a], #124]\n\t" + "ldr r6, [%[b], #120]\n\t" + "ldr r7, [%[b], #124]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #120]\n\t" + "str r5, [%[r], #124]\n\t" + "sbc %[b], %[b]\n\t" + "ldr r4, [%[r], #0]\n\t" + "ldr r5, [%[r], #4]\n\t" + "ldr r6, [%[m], #0]\n\t" + "ldr r7, [%[m], #4]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "add r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #0]\n\t" + "str r5, [%[r], #4]\n\t" + "ldr r4, [%[r], #8]\n\t" + "ldr r5, [%[r], #12]\n\t" + "ldr r6, [%[m], #8]\n\t" + "ldr r7, [%[m], #12]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #8]\n\t" + "str r5, [%[r], #12]\n\t" + "ldr r4, [%[r], #16]\n\t" + "ldr r5, [%[r], #20]\n\t" + "ldr r6, [%[m], #16]\n\t" + "ldr r7, [%[m], #20]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #16]\n\t" + "str r5, [%[r], #20]\n\t" + "ldr r4, [%[r], #24]\n\t" + "ldr r5, [%[r], #28]\n\t" + "ldr r6, [%[m], #24]\n\t" + "ldr r7, [%[m], #28]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #24]\n\t" + "str r5, [%[r], #28]\n\t" + "ldr r4, [%[r], #32]\n\t" + "ldr r5, [%[r], #36]\n\t" + "ldr r6, [%[m], #32]\n\t" + "ldr r7, [%[m], #36]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #32]\n\t" + "str r5, [%[r], #36]\n\t" + "ldr r4, [%[r], #40]\n\t" + "ldr r5, [%[r], #44]\n\t" + "ldr r6, [%[m], #40]\n\t" + "ldr r7, [%[m], #44]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #40]\n\t" + "str r5, [%[r], #44]\n\t" + "ldr r4, [%[r], #48]\n\t" + "ldr r5, [%[r], #52]\n\t" + "ldr r6, [%[m], #48]\n\t" + "ldr r7, [%[m], #52]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #48]\n\t" + "str r5, [%[r], #52]\n\t" + "ldr r4, [%[r], #56]\n\t" + "ldr r5, [%[r], #60]\n\t" + "ldr r6, [%[m], #56]\n\t" + "ldr r7, [%[m], #60]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #56]\n\t" + "str r5, [%[r], #60]\n\t" + "ldr r4, [%[r], #64]\n\t" + "ldr r5, [%[r], #68]\n\t" + "ldr r6, [%[m], #64]\n\t" + "ldr r7, [%[m], #68]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #64]\n\t" + "str r5, [%[r], #68]\n\t" + "ldr r4, [%[r], #72]\n\t" + "ldr r5, [%[r], #76]\n\t" + "ldr r6, [%[m], #72]\n\t" + "ldr r7, [%[m], #76]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #72]\n\t" + "str r5, [%[r], #76]\n\t" + "ldr r4, [%[r], #80]\n\t" + "ldr r5, [%[r], #84]\n\t" + "ldr r6, [%[m], #80]\n\t" + "ldr r7, [%[m], #84]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #80]\n\t" + "str r5, [%[r], #84]\n\t" + "ldr r4, [%[r], #88]\n\t" + "ldr r5, [%[r], #92]\n\t" + "ldr r6, [%[m], #88]\n\t" + "ldr r7, [%[m], #92]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #88]\n\t" + "str r5, [%[r], #92]\n\t" + "ldr r4, [%[r], #96]\n\t" + "ldr r5, [%[r], #100]\n\t" + "ldr r6, [%[m], #96]\n\t" + "ldr r7, [%[m], #100]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #96]\n\t" + "str r5, [%[r], #100]\n\t" + "ldr r4, [%[r], #104]\n\t" + "ldr r5, [%[r], #108]\n\t" + "ldr r6, [%[m], #104]\n\t" + "ldr r7, [%[m], #108]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #104]\n\t" + "str r5, [%[r], #108]\n\t" + "ldr r4, [%[r], #112]\n\t" + "ldr r5, [%[r], #116]\n\t" + "ldr r6, [%[m], #112]\n\t" + "ldr r7, [%[m], #116]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #112]\n\t" + "str r5, [%[r], #116]\n\t" + "ldr r4, [%[r], #120]\n\t" + "ldr r5, [%[r], #124]\n\t" + "ldr r6, [%[m], #120]\n\t" + "ldr r7, [%[m], #124]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #120]\n\t" + "str r5, [%[r], #124]\n\t" + "mov r6, #0\n\t" + "adc %[b], r6\n\t" + "ldr r4, [%[r], #0]\n\t" + "ldr r5, [%[r], #4]\n\t" + "ldr r6, [%[m], #0]\n\t" + "ldr r7, [%[m], #4]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "add r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #0]\n\t" + "str r5, [%[r], #4]\n\t" + "ldr r4, [%[r], #8]\n\t" + "ldr r5, [%[r], #12]\n\t" + "ldr r6, [%[m], #8]\n\t" + "ldr r7, [%[m], #12]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #8]\n\t" + "str r5, [%[r], #12]\n\t" + "ldr r4, [%[r], #16]\n\t" + "ldr r5, [%[r], #20]\n\t" + "ldr r6, [%[m], #16]\n\t" + "ldr r7, [%[m], #20]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #16]\n\t" + "str r5, [%[r], #20]\n\t" + "ldr r4, [%[r], #24]\n\t" + "ldr r5, [%[r], #28]\n\t" + "ldr r6, [%[m], #24]\n\t" + "ldr r7, [%[m], #28]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #24]\n\t" + "str r5, [%[r], #28]\n\t" + "ldr r4, [%[r], #32]\n\t" + "ldr r5, [%[r], #36]\n\t" + "ldr r6, [%[m], #32]\n\t" + "ldr r7, [%[m], #36]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #32]\n\t" + "str r5, [%[r], #36]\n\t" + "ldr r4, [%[r], #40]\n\t" + "ldr r5, [%[r], #44]\n\t" + "ldr r6, [%[m], #40]\n\t" + "ldr r7, [%[m], #44]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #40]\n\t" + "str r5, [%[r], #44]\n\t" + "ldr r4, [%[r], #48]\n\t" + "ldr r5, [%[r], #52]\n\t" + "ldr r6, [%[m], #48]\n\t" + "ldr r7, [%[m], #52]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #48]\n\t" + "str r5, [%[r], #52]\n\t" + "ldr r4, [%[r], #56]\n\t" + "ldr r5, [%[r], #60]\n\t" + "ldr r6, [%[m], #56]\n\t" + "ldr r7, [%[m], #60]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #56]\n\t" + "str r5, [%[r], #60]\n\t" + "ldr r4, [%[r], #64]\n\t" + "ldr r5, [%[r], #68]\n\t" + "ldr r6, [%[m], #64]\n\t" + "ldr r7, [%[m], #68]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #64]\n\t" + "str r5, [%[r], #68]\n\t" + "ldr r4, [%[r], #72]\n\t" + "ldr r5, [%[r], #76]\n\t" + "ldr r6, [%[m], #72]\n\t" + "ldr r7, [%[m], #76]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #72]\n\t" + "str r5, [%[r], #76]\n\t" + "ldr r4, [%[r], #80]\n\t" + "ldr r5, [%[r], #84]\n\t" + "ldr r6, [%[m], #80]\n\t" + "ldr r7, [%[m], #84]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #80]\n\t" + "str r5, [%[r], #84]\n\t" + "ldr r4, [%[r], #88]\n\t" + "ldr r5, [%[r], #92]\n\t" + "ldr r6, [%[m], #88]\n\t" + "ldr r7, [%[m], #92]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #88]\n\t" + "str r5, [%[r], #92]\n\t" + "ldr r4, [%[r], #96]\n\t" + "ldr r5, [%[r], #100]\n\t" + "ldr r6, [%[m], #96]\n\t" + "ldr r7, [%[m], #100]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #96]\n\t" + "str r5, [%[r], #100]\n\t" + "ldr r4, [%[r], #104]\n\t" + "ldr r5, [%[r], #108]\n\t" + "ldr r6, [%[m], #104]\n\t" + "ldr r7, [%[m], #108]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #104]\n\t" + "str r5, [%[r], #108]\n\t" + "ldr r4, [%[r], #112]\n\t" + "ldr r5, [%[r], #116]\n\t" + "ldr r6, [%[m], #112]\n\t" + "ldr r7, [%[m], #116]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #112]\n\t" + "str r5, [%[r], #116]\n\t" + "ldr r4, [%[r], #120]\n\t" + "ldr r5, [%[r], #124]\n\t" + "ldr r6, [%[m], #120]\n\t" + "ldr r7, [%[m], #124]\n\t" + "and r6, %[b]\n\t" + "and r7, %[b]\n\t" + "adc r4, r6\n\t" + "adc r5, r7\n\t" + "str r4, [%[r], #120]\n\t" + "str r5, [%[r], #124]\n\t" + : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) + : + : "memory", "r4", "r5", "r6", "r7" + ); +} + +/* Conditionally add a and b using the mask m. + * m is -1 to add and 0 when not. + * + * r A single precision number representing conditional add result. + * a A single precision number to add with. + * b A single precision number to add. + * m Mask value to apply. + */ +SP_NOINLINE static sp_digit sp_1024_cond_add_32(sp_digit* r, const sp_digit* a, const sp_digit* b, + sp_digit m) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r5, #128\n\t" + "mov r8, r5\n\t" + "mov r7, #0\n\t" + "1:\n\t" + "ldr r6, [%[b], r7]\n\t" + "and r6, %[m]\n\t" + "mov r5, #0\n\t" + "sub r5, #1\n\t" + "add r5, %[c]\n\t" + "ldr r5, [%[a], r7]\n\t" + "adc r5, r6\n\t" + "mov %[c], #0\n\t" + "adc %[c], %[c]\n\t" + "str r5, [%[r], r7]\n\t" + "add r7, #4\n\t" + "cmp r7, r8\n\t" + "blt 1b\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "r5", "r6", "r7", "r8" + ); + + return c; +} + +static void sp_1024_rshift1_32(sp_digit* r, sp_digit* a) +{ + __asm__ __volatile__ ( + "ldr r2, [%[a]]\n\t" + "ldr r3, [%[a], #4]\n\t" + "lsr r2, r2, #1\n\t" + "lsl r5, r3, #31\n\t" + "lsr r3, r3, #1\n\t" + "orr r2, r2, r5\n\t" + "ldr r4, [%[a], #8]\n\t" + "str r2, [%[r], #0]\n\t" + "lsl r5, r4, #31\n\t" + "lsr r4, r4, #1\n\t" + "orr r3, r3, r5\n\t" + "ldr r2, [%[a], #12]\n\t" + "str r3, [%[r], #4]\n\t" + "lsl r5, r2, #31\n\t" + "lsr r2, r2, #1\n\t" + "orr r4, r4, r5\n\t" + "ldr r3, [%[a], #16]\n\t" + "str r4, [%[r], #8]\n\t" + "lsl r5, r3, #31\n\t" + "lsr r3, r3, #1\n\t" + "orr r2, r2, r5\n\t" + "ldr r4, [%[a], #20]\n\t" + "str r2, [%[r], #12]\n\t" + "lsl r5, r4, #31\n\t" + "lsr r4, r4, #1\n\t" + "orr r3, r3, r5\n\t" + "ldr r2, [%[a], #24]\n\t" + "str r3, [%[r], #16]\n\t" + "lsl r5, r2, #31\n\t" + "lsr r2, r2, #1\n\t" + "orr r4, r4, r5\n\t" + "ldr r3, [%[a], #28]\n\t" + "str r4, [%[r], #20]\n\t" + "lsl r5, r3, #31\n\t" + "lsr r3, r3, #1\n\t" + "orr r2, r2, r5\n\t" + "ldr r4, [%[a], #32]\n\t" + "str r2, [%[r], #24]\n\t" + "lsl r5, r4, #31\n\t" + "lsr r4, r4, #1\n\t" + "orr r3, r3, r5\n\t" + "ldr r2, [%[a], #36]\n\t" + "str r3, [%[r], #28]\n\t" + "lsl r5, r2, #31\n\t" + "lsr r2, r2, #1\n\t" + "orr r4, r4, r5\n\t" + "ldr r3, [%[a], #40]\n\t" + "str r4, [%[r], #32]\n\t" + "lsl r5, r3, #31\n\t" + "lsr r3, r3, #1\n\t" + "orr r2, r2, r5\n\t" + "ldr r4, [%[a], #44]\n\t" + "str r2, [%[r], #36]\n\t" + "lsl r5, r4, #31\n\t" + "lsr r4, r4, #1\n\t" + "orr r3, r3, r5\n\t" + "ldr r2, [%[a], #48]\n\t" + "str r3, [%[r], #40]\n\t" + "lsl r5, r2, #31\n\t" + "lsr r2, r2, #1\n\t" + "orr r4, r4, r5\n\t" + "ldr r3, [%[a], #52]\n\t" + "str r4, [%[r], #44]\n\t" + "lsl r5, r3, #31\n\t" + "lsr r3, r3, #1\n\t" + "orr r2, r2, r5\n\t" + "ldr r4, [%[a], #56]\n\t" + "str r2, [%[r], #48]\n\t" + "lsl r5, r4, #31\n\t" + "lsr r4, r4, #1\n\t" + "orr r3, r3, r5\n\t" + "ldr r2, [%[a], #60]\n\t" + "str r3, [%[r], #52]\n\t" + "lsl r5, r2, #31\n\t" + "lsr r2, r2, #1\n\t" + "orr r4, r4, r5\n\t" + "ldr r3, [%[a], #64]\n\t" + "str r4, [%[r], #56]\n\t" + "lsl r5, r3, #31\n\t" + "lsr r3, r3, #1\n\t" + "orr r2, r2, r5\n\t" + "ldr r4, [%[a], #68]\n\t" + "str r2, [%[r], #60]\n\t" + "lsl r5, r4, #31\n\t" + "lsr r4, r4, #1\n\t" + "orr r3, r3, r5\n\t" + "ldr r2, [%[a], #72]\n\t" + "str r3, [%[r], #64]\n\t" + "lsl r5, r2, #31\n\t" + "lsr r2, r2, #1\n\t" + "orr r4, r4, r5\n\t" + "ldr r3, [%[a], #76]\n\t" + "str r4, [%[r], #68]\n\t" + "lsl r5, r3, #31\n\t" + "lsr r3, r3, #1\n\t" + "orr r2, r2, r5\n\t" + "ldr r4, [%[a], #80]\n\t" + "str r2, [%[r], #72]\n\t" + "lsl r5, r4, #31\n\t" + "lsr r4, r4, #1\n\t" + "orr r3, r3, r5\n\t" + "ldr r2, [%[a], #84]\n\t" + "str r3, [%[r], #76]\n\t" + "lsl r5, r2, #31\n\t" + "lsr r2, r2, #1\n\t" + "orr r4, r4, r5\n\t" + "ldr r3, [%[a], #88]\n\t" + "str r4, [%[r], #80]\n\t" + "lsl r5, r3, #31\n\t" + "lsr r3, r3, #1\n\t" + "orr r2, r2, r5\n\t" + "ldr r4, [%[a], #92]\n\t" + "str r2, [%[r], #84]\n\t" + "lsl r5, r4, #31\n\t" + "lsr r4, r4, #1\n\t" + "orr r3, r3, r5\n\t" + "ldr r2, [%[a], #96]\n\t" + "str r3, [%[r], #88]\n\t" + "lsl r5, r2, #31\n\t" + "lsr r2, r2, #1\n\t" + "orr r4, r4, r5\n\t" + "ldr r3, [%[a], #100]\n\t" + "str r4, [%[r], #92]\n\t" + "lsl r5, r3, #31\n\t" + "lsr r3, r3, #1\n\t" + "orr r2, r2, r5\n\t" + "ldr r4, [%[a], #104]\n\t" + "str r2, [%[r], #96]\n\t" + "lsl r5, r4, #31\n\t" + "lsr r4, r4, #1\n\t" + "orr r3, r3, r5\n\t" + "ldr r2, [%[a], #108]\n\t" + "str r3, [%[r], #100]\n\t" + "lsl r5, r2, #31\n\t" + "lsr r2, r2, #1\n\t" + "orr r4, r4, r5\n\t" + "ldr r3, [%[a], #112]\n\t" + "str r4, [%[r], #104]\n\t" + "lsl r5, r3, #31\n\t" + "lsr r3, r3, #1\n\t" + "orr r2, r2, r5\n\t" + "ldr r4, [%[a], #116]\n\t" + "str r2, [%[r], #108]\n\t" + "lsl r5, r4, #31\n\t" + "lsr r4, r4, #1\n\t" + "orr r3, r3, r5\n\t" + "ldr r2, [%[a], #120]\n\t" + "str r3, [%[r], #112]\n\t" + "lsl r5, r2, #31\n\t" + "lsr r2, r2, #1\n\t" + "orr r4, r4, r5\n\t" + "ldr r3, [%[a], #124]\n\t" + "str r4, [%[r], #116]\n\t" + "lsl r5, r3, #31\n\t" + "lsr r3, r3, #1\n\t" + "orr r2, r2, r5\n\t" + "str r2, [%[r], #120]\n\t" + "str r3, [%[r], #124]\n\t" + : + : [r] "r" (r), [a] "r" (a) + : "memory", "r2", "r3", "r4", "r5" + ); +} + +/* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m) + * + * r Result of division by 2. + * a Number to divide. + * m Modulus (prime). + */ +SP_NOINLINE static void sp_1024_div2_32(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_digit o; + + o = sp_1024_cond_add_32(r, a, m, 0 - (a[0] & 1)); + sp_1024_rshift1_32(r, r); + r[31] |= o << 31; +} + +/* Double the Montgomery form projective point p. + * + * r Result of doubling point. + * p Point to double. + * t Temporary ordinate data. + */ +#ifdef WOLFSSL_SP_NONBLOCK +typedef struct sp_1024_proj_point_dbl_32_ctx { + int state; + sp_digit* t1; + sp_digit* t2; + sp_digit* x; + sp_digit* y; + sp_digit* z; +} sp_1024_proj_point_dbl_32_ctx; + +static int sp_1024_proj_point_dbl_32_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r, const sp_point_1024* p, sp_digit* t) +{ + int err = FP_WOULDBLOCK; + sp_1024_proj_point_dbl_32_ctx* ctx = (sp_1024_proj_point_dbl_32_ctx*)sp_ctx->data; + + typedef char ctx_size_test[sizeof(sp_1024_proj_point_dbl_32_ctx) >= sizeof(*sp_ctx) ? -1 : 1]; + (void)sizeof(ctx_size_test); + + switch (ctx->state) { + case 0: + ctx->t1 = t; + ctx->t2 = t + 2*32; + ctx->x = r->x; + ctx->y = r->y; + ctx->z = r->z; + + /* Put infinity into result. */ + if (r != p) { + r->infinity = p->infinity; + } + ctx->state = 1; + break; + case 1: + /* T1 = Z * Z */ + sp_1024_mont_sqr_32(ctx->t1, p->z, p1024_mod, p1024_mp_mod); + ctx->state = 2; + break; + case 2: + /* Z = Y * Z */ + sp_1024_mont_mul_32(ctx->z, p->y, p->z, p1024_mod, p1024_mp_mod); + ctx->state = 3; + break; + case 3: + /* Z = 2Z */ + sp_1024_mont_dbl_32(ctx->z, ctx->z, p1024_mod); + ctx->state = 4; + break; + case 4: + /* T2 = X - T1 */ + sp_1024_mont_sub_32(ctx->t2, p->x, ctx->t1, p1024_mod); + ctx->state = 5; + break; + case 5: + /* T1 = X + T1 */ + sp_1024_mont_add_32(ctx->t1, p->x, ctx->t1, p1024_mod); + ctx->state = 6; + break; + case 6: + /* T2 = T1 * T2 */ + sp_1024_mont_mul_32(ctx->t2, ctx->t1, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 7; + break; + case 7: + /* T1 = 3T2 */ + sp_1024_mont_tpl_32(ctx->t1, ctx->t2, p1024_mod); + ctx->state = 8; + break; + case 8: + /* Y = 2Y */ + sp_1024_mont_dbl_32(ctx->y, p->y, p1024_mod); + ctx->state = 9; + break; + case 9: + /* Y = Y * Y */ + sp_1024_mont_sqr_32(ctx->y, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 10; + break; + case 10: + /* T2 = Y * Y */ + sp_1024_mont_sqr_32(ctx->t2, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 11; + break; + case 11: + /* T2 = T2/2 */ + sp_1024_div2_32(ctx->t2, ctx->t2, p1024_mod); + ctx->state = 12; + break; + case 12: + /* Y = Y * X */ + sp_1024_mont_mul_32(ctx->y, ctx->y, p->x, p1024_mod, p1024_mp_mod); + ctx->state = 13; + break; + case 13: + /* X = T1 * T1 */ + sp_1024_mont_sqr_32(ctx->x, ctx->t1, p1024_mod, p1024_mp_mod); + ctx->state = 14; + break; + case 14: + /* X = X - Y */ + sp_1024_mont_sub_32(ctx->x, ctx->x, ctx->y, p1024_mod); + ctx->state = 15; + break; + case 15: + /* X = X - Y */ + sp_1024_mont_sub_32(ctx->x, ctx->x, ctx->y, p1024_mod); + ctx->state = 16; + break; + case 16: + /* Y = Y - X */ + sp_1024_mont_sub_32(ctx->y, ctx->y, ctx->x, p1024_mod); + ctx->state = 17; + break; + case 17: + /* Y = Y * T1 */ + sp_1024_mont_mul_32(ctx->y, ctx->y, ctx->t1, p1024_mod, p1024_mp_mod); + ctx->state = 18; + break; + case 18: + /* Y = Y - T2 */ + sp_1024_mont_sub_32(ctx->y, ctx->y, ctx->t2, p1024_mod); + ctx->state = 19; + /* fall-through */ + case 19: + err = MP_OKAY; + break; + } + + if (err == MP_OKAY && ctx->state != 19) { + err = FP_WOULDBLOCK; + } + + return err; +} +#endif /* WOLFSSL_SP_NONBLOCK */ + +static void sp_1024_proj_point_dbl_32(sp_point_1024* r, const sp_point_1024* p, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*32; + sp_digit* x; + sp_digit* y; + sp_digit* z; + + x = r->x; + y = r->y; + z = r->z; + /* Put infinity into result. */ + if (r != p) { + r->infinity = p->infinity; + } + + /* T1 = Z * Z */ + sp_1024_mont_sqr_32(t1, p->z, p1024_mod, p1024_mp_mod); + /* Z = Y * Z */ + sp_1024_mont_mul_32(z, p->y, p->z, p1024_mod, p1024_mp_mod); + /* Z = 2Z */ + sp_1024_mont_dbl_32(z, z, p1024_mod); + /* T2 = X - T1 */ + sp_1024_mont_sub_32(t2, p->x, t1, p1024_mod); + /* T1 = X + T1 */ + sp_1024_mont_add_32(t1, p->x, t1, p1024_mod); + /* T2 = T1 * T2 */ + sp_1024_mont_mul_32(t2, t1, t2, p1024_mod, p1024_mp_mod); + /* T1 = 3T2 */ + sp_1024_mont_tpl_32(t1, t2, p1024_mod); + /* Y = 2Y */ + sp_1024_mont_dbl_32(y, p->y, p1024_mod); + /* Y = Y * Y */ + sp_1024_mont_sqr_32(y, y, p1024_mod, p1024_mp_mod); + /* T2 = Y * Y */ + sp_1024_mont_sqr_32(t2, y, p1024_mod, p1024_mp_mod); + /* T2 = T2/2 */ + sp_1024_div2_32(t2, t2, p1024_mod); + /* Y = Y * X */ + sp_1024_mont_mul_32(y, y, p->x, p1024_mod, p1024_mp_mod); + /* X = T1 * T1 */ + sp_1024_mont_sqr_32(x, t1, p1024_mod, p1024_mp_mod); + /* X = X - Y */ + sp_1024_mont_sub_32(x, x, y, p1024_mod); + /* X = X - Y */ + sp_1024_mont_sub_32(x, x, y, p1024_mod); + /* Y = Y - X */ + sp_1024_mont_sub_32(y, y, x, p1024_mod); + /* Y = Y * T1 */ + sp_1024_mont_mul_32(y, y, t1, p1024_mod, p1024_mp_mod); + /* Y = Y - T2 */ + sp_1024_mont_sub_32(y, y, t2, p1024_mod); +} + +#ifdef WOLFSSL_SP_SMALL +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_1024_sub_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r6, %[a]\n\t" + "add r6, #128\n\t" + "\n1:\n\t" + "mov r5, #0\n\t" + "sub r5, %[c]\n\t" + "ldr r4, [%[a]]\n\t" + "ldr r5, [%[b]]\n\t" + "sbc r4, r5\n\t" + "str r4, [%[r]]\n\t" + "sbc %[c], %[c]\n\t" + "add %[a], #4\n\t" + "add %[b], #4\n\t" + "add %[r], #4\n\t" + "cmp %[a], r6\n\t" + "bne 1b\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6" + ); + + return c; +} + +#else +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_1024_sub_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldr r4, [%[a], #0]\n\t" + "ldr r5, [%[a], #4]\n\t" + "ldr r6, [%[b], #0]\n\t" + "ldr r7, [%[b], #4]\n\t" + "sub r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #0]\n\t" + "str r5, [%[r], #4]\n\t" + "ldr r4, [%[a], #8]\n\t" + "ldr r5, [%[a], #12]\n\t" + "ldr r6, [%[b], #8]\n\t" + "ldr r7, [%[b], #12]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #8]\n\t" + "str r5, [%[r], #12]\n\t" + "ldr r4, [%[a], #16]\n\t" + "ldr r5, [%[a], #20]\n\t" + "ldr r6, [%[b], #16]\n\t" + "ldr r7, [%[b], #20]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #16]\n\t" + "str r5, [%[r], #20]\n\t" + "ldr r4, [%[a], #24]\n\t" + "ldr r5, [%[a], #28]\n\t" + "ldr r6, [%[b], #24]\n\t" + "ldr r7, [%[b], #28]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #24]\n\t" + "str r5, [%[r], #28]\n\t" + "ldr r4, [%[a], #32]\n\t" + "ldr r5, [%[a], #36]\n\t" + "ldr r6, [%[b], #32]\n\t" + "ldr r7, [%[b], #36]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #32]\n\t" + "str r5, [%[r], #36]\n\t" + "ldr r4, [%[a], #40]\n\t" + "ldr r5, [%[a], #44]\n\t" + "ldr r6, [%[b], #40]\n\t" + "ldr r7, [%[b], #44]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #40]\n\t" + "str r5, [%[r], #44]\n\t" + "ldr r4, [%[a], #48]\n\t" + "ldr r5, [%[a], #52]\n\t" + "ldr r6, [%[b], #48]\n\t" + "ldr r7, [%[b], #52]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #48]\n\t" + "str r5, [%[r], #52]\n\t" + "ldr r4, [%[a], #56]\n\t" + "ldr r5, [%[a], #60]\n\t" + "ldr r6, [%[b], #56]\n\t" + "ldr r7, [%[b], #60]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #56]\n\t" + "str r5, [%[r], #60]\n\t" + "ldr r4, [%[a], #64]\n\t" + "ldr r5, [%[a], #68]\n\t" + "ldr r6, [%[b], #64]\n\t" + "ldr r7, [%[b], #68]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #64]\n\t" + "str r5, [%[r], #68]\n\t" + "ldr r4, [%[a], #72]\n\t" + "ldr r5, [%[a], #76]\n\t" + "ldr r6, [%[b], #72]\n\t" + "ldr r7, [%[b], #76]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #72]\n\t" + "str r5, [%[r], #76]\n\t" + "ldr r4, [%[a], #80]\n\t" + "ldr r5, [%[a], #84]\n\t" + "ldr r6, [%[b], #80]\n\t" + "ldr r7, [%[b], #84]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #80]\n\t" + "str r5, [%[r], #84]\n\t" + "ldr r4, [%[a], #88]\n\t" + "ldr r5, [%[a], #92]\n\t" + "ldr r6, [%[b], #88]\n\t" + "ldr r7, [%[b], #92]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #88]\n\t" + "str r5, [%[r], #92]\n\t" + "ldr r4, [%[a], #96]\n\t" + "ldr r5, [%[a], #100]\n\t" + "ldr r6, [%[b], #96]\n\t" + "ldr r7, [%[b], #100]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #96]\n\t" + "str r5, [%[r], #100]\n\t" + "ldr r4, [%[a], #104]\n\t" + "ldr r5, [%[a], #108]\n\t" + "ldr r6, [%[b], #104]\n\t" + "ldr r7, [%[b], #108]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #104]\n\t" + "str r5, [%[r], #108]\n\t" + "ldr r4, [%[a], #112]\n\t" + "ldr r5, [%[a], #116]\n\t" + "ldr r6, [%[b], #112]\n\t" + "ldr r7, [%[b], #116]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #112]\n\t" + "str r5, [%[r], #116]\n\t" + "ldr r4, [%[a], #120]\n\t" + "ldr r5, [%[a], #124]\n\t" + "ldr r6, [%[b], #120]\n\t" + "ldr r7, [%[b], #124]\n\t" + "sbc r4, r6\n\t" + "sbc r5, r7\n\t" + "str r4, [%[r], #120]\n\t" + "str r5, [%[r], #124]\n\t" + "sbc %[c], %[c]\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6", "r7" + ); + + return c; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Compare two numbers to determine if they are equal. + * Constant time implementation. + * + * a First number to compare. + * b Second number to compare. + * returns 1 when equal and 0 otherwise. + */ +static int sp_1024_cmp_equal_32(const sp_digit* a, const sp_digit* b) +{ + return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) | (a[3] ^ b[3]) | + (a[4] ^ b[4]) | (a[5] ^ b[5]) | (a[6] ^ b[6]) | (a[7] ^ b[7]) | + (a[8] ^ b[8]) | (a[9] ^ b[9]) | (a[10] ^ b[10]) | (a[11] ^ b[11]) | + (a[12] ^ b[12]) | (a[13] ^ b[13]) | (a[14] ^ b[14]) | (a[15] ^ b[15]) | + (a[16] ^ b[16]) | (a[17] ^ b[17]) | (a[18] ^ b[18]) | (a[19] ^ b[19]) | + (a[20] ^ b[20]) | (a[21] ^ b[21]) | (a[22] ^ b[22]) | (a[23] ^ b[23]) | + (a[24] ^ b[24]) | (a[25] ^ b[25]) | (a[26] ^ b[26]) | (a[27] ^ b[27]) | + (a[28] ^ b[28]) | (a[29] ^ b[29]) | (a[30] ^ b[30]) | (a[31] ^ b[31])) == 0; +} + +/* Add two Montgomery form projective points. + * + * r Result of addition. + * p First point to add. + * q Second point to add. + * t Temporary ordinate data. + */ + +#ifdef WOLFSSL_SP_NONBLOCK +typedef struct sp_1024_proj_point_add_32_ctx { + int state; + sp_1024_proj_point_dbl_32_ctx dbl_ctx; + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1; + sp_digit* t2; + sp_digit* t3; + sp_digit* t4; + sp_digit* t5; + sp_digit* x; + sp_digit* y; + sp_digit* z; +} sp_1024_proj_point_add_32_ctx; + +static int sp_1024_proj_point_add_32_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r, + const sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + int err = FP_WOULDBLOCK; + sp_1024_proj_point_add_32_ctx* ctx = (sp_1024_proj_point_add_32_ctx*)sp_ctx->data; + + /* Ensure only the first point is the same as the result. */ + if (q == r) { + const sp_point_1024* a = p; + p = q; + q = a; + } + + typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_32_ctx) >= sizeof(*sp_ctx) ? -1 : 1]; + (void)sizeof(ctx_size_test); + + switch (ctx->state) { + case 0: /* INIT */ + ctx->t1 = t; + ctx->t2 = t + 2*32; + ctx->t3 = t + 4*32; + ctx->t4 = t + 6*32; + ctx->t5 = t + 8*32; + + ctx->state = 1; + break; + case 1: + /* Check double */ + (void)sp_1024_sub_32(ctx->t1, p1024_mod, q->y); + sp_1024_norm_32(ctx->t1); + if ((sp_1024_cmp_equal_32(p->x, q->x) & sp_1024_cmp_equal_32(p->z, q->z) & + (sp_1024_cmp_equal_32(p->y, q->y) | sp_1024_cmp_equal_32(p->y, ctx->t1))) != 0) + { + XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx)); + ctx->state = 2; + } + else { + ctx->state = 3; + } + break; + case 2: + err = sp_1024_proj_point_dbl_32_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, r, p, t); + if (err == MP_OKAY) + ctx->state = 27; /* done */ + break; + case 3: + { + int i; + ctx->rp[0] = r; + + /*lint allow cast to different type of pointer*/ + ctx->rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(ctx->rp[1], 0, sizeof(sp_point_1024)); + ctx->x = ctx->rp[p->infinity | q->infinity]->x; + ctx->y = ctx->rp[p->infinity | q->infinity]->y; + ctx->z = ctx->rp[p->infinity | q->infinity]->z; + + ctx->ap[0] = p; + ctx->ap[1] = q; + for (i=0; i<32; i++) { + r->x[i] = ctx->ap[p->infinity]->x[i]; + } + for (i=0; i<32; i++) { + r->y[i] = ctx->ap[p->infinity]->y[i]; + } + for (i=0; i<32; i++) { + r->z[i] = ctx->ap[p->infinity]->z[i]; + } + r->infinity = ctx->ap[p->infinity]->infinity; + + ctx->state = 4; + break; + } + case 4: + /* U1 = X1*Z2^2 */ + sp_1024_mont_sqr_32(ctx->t1, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 5; + break; + case 5: + sp_1024_mont_mul_32(ctx->t3, ctx->t1, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 6; + break; + case 6: + sp_1024_mont_mul_32(ctx->t1, ctx->t1, ctx->x, p1024_mod, p1024_mp_mod); + ctx->state = 7; + break; + case 7: + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_32(ctx->t2, ctx->z, p1024_mod, p1024_mp_mod); + ctx->state = 8; + break; + case 8: + sp_1024_mont_mul_32(ctx->t4, ctx->t2, ctx->z, p1024_mod, p1024_mp_mod); + ctx->state = 9; + break; + case 9: + sp_1024_mont_mul_32(ctx->t2, ctx->t2, q->x, p1024_mod, p1024_mp_mod); + ctx->state = 10; + break; + case 10: + /* S1 = Y1*Z2^3 */ + sp_1024_mont_mul_32(ctx->t3, ctx->t3, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 11; + break; + case 11: + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_32(ctx->t4, ctx->t4, q->y, p1024_mod, p1024_mp_mod); + ctx->state = 12; + break; + case 12: + /* H = U2 - U1 */ + sp_1024_mont_sub_32(ctx->t2, ctx->t2, ctx->t1, p1024_mod); + ctx->state = 13; + break; + case 13: + /* R = S2 - S1 */ + sp_1024_mont_sub_32(ctx->t4, ctx->t4, ctx->t3, p1024_mod); + ctx->state = 14; + break; + case 14: + /* Z3 = H*Z1*Z2 */ + sp_1024_mont_mul_32(ctx->z, ctx->z, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 15; + break; + case 15: + sp_1024_mont_mul_32(ctx->z, ctx->z, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 16; + break; + case 16: + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_1024_mont_sqr_32(ctx->x, ctx->t4, p1024_mod, p1024_mp_mod); + ctx->state = 17; + break; + case 17: + sp_1024_mont_sqr_32(ctx->t5, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 18; + break; + case 18: + sp_1024_mont_mul_32(ctx->y, ctx->t1, ctx->t5, p1024_mod, p1024_mp_mod); + ctx->state = 19; + break; + case 19: + sp_1024_mont_mul_32(ctx->t5, ctx->t5, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 20; + break; + case 20: + sp_1024_mont_sub_32(ctx->x, ctx->x, ctx->t5, p1024_mod); + ctx->state = 21; + break; + case 21: + sp_1024_mont_dbl_32(ctx->t1, ctx->y, p1024_mod); + ctx->state = 22; + break; + case 22: + sp_1024_mont_sub_32(ctx->x, ctx->x, ctx->t1, p1024_mod); + ctx->state = 23; + break; + case 23: + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_1024_mont_sub_32(ctx->y, ctx->y, ctx->x, p1024_mod); + ctx->state = 24; + break; + case 24: + sp_1024_mont_mul_32(ctx->y, ctx->y, ctx->t4, p1024_mod, p1024_mp_mod); + ctx->state = 25; + break; + case 25: + sp_1024_mont_mul_32(ctx->t5, ctx->t5, ctx->t3, p1024_mod, p1024_mp_mod); + ctx->state = 26; + break; + case 26: + sp_1024_mont_sub_32(ctx->y, ctx->y, ctx->t5, p1024_mod); + ctx->state = 27; + /* fall-through */ + case 27: + err = MP_OKAY; + break; + } + + if (err == MP_OKAY && ctx->state != 27) { + err = FP_WOULDBLOCK; + } + return err; +} +#endif /* WOLFSSL_SP_NONBLOCK */ + +static void sp_1024_proj_point_add_32(sp_point_1024* r, + const sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*32; + sp_digit* t3 = t + 4*32; + sp_digit* t4 = t + 6*32; + sp_digit* t5 = t + 8*32; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Ensure only the first point is the same as the result. */ + if (q == r) { + const sp_point_1024* a = p; + p = q; + q = a; + } + + /* Check double */ + (void)sp_1024_mont_sub_32(t1, p1024_mod, q->y, p1024_mod); + sp_1024_norm_32(t1); + if ((sp_1024_cmp_equal_32(p->x, q->x) & sp_1024_cmp_equal_32(p->z, q->z) & + (sp_1024_cmp_equal_32(p->y, q->y) | sp_1024_cmp_equal_32(p->y, t1))) != 0) { + sp_1024_proj_point_dbl_32(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_1024)); + x = rp[p->infinity | q->infinity]->x; + y = rp[p->infinity | q->infinity]->y; + z = rp[p->infinity | q->infinity]->z; + + ap[0] = p; + ap[1] = q; + for (i=0; i<32; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<32; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<32; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U1 = X1*Z2^2 */ + sp_1024_mont_sqr_32(t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t3, t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t1, t1, x, p1024_mod, p1024_mp_mod); + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_32(t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t4, t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t2, t2, q->x, p1024_mod, p1024_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_1024_mont_mul_32(t3, t3, y, p1024_mod, p1024_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_32(t4, t4, q->y, p1024_mod, p1024_mp_mod); + /* H = U2 - U1 */ + sp_1024_mont_sub_32(t2, t2, t1, p1024_mod); + /* R = S2 - S1 */ + sp_1024_mont_sub_32(t4, t4, t3, p1024_mod); + /* Z3 = H*Z1*Z2 */ + sp_1024_mont_mul_32(z, z, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(z, z, t2, p1024_mod, p1024_mp_mod); + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_1024_mont_sqr_32(x, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_32(t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(y, t1, t5, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t5, t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_32(x, x, t5, p1024_mod); + sp_1024_mont_dbl_32(t1, y, p1024_mod); + sp_1024_mont_sub_32(x, x, t1, p1024_mod); + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_1024_mont_sub_32(y, y, x, p1024_mod); + sp_1024_mont_mul_32(y, y, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t5, t5, t3, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_32(y, y, t5, p1024_mod); + } +} + +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Fast implementation that generates a pre-computation table. + * 4 bits of window (no sliding!). + * Uses add and double for calculating table. + * 1024 doubles. + * 268 adds. + * + * r Resulting point. + * g Point to multiply. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_fast_32(sp_point_1024* r, const sp_point_1024* g, const sp_digit* k, + int map, int ct, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 td[16]; + sp_point_1024 rtd; + sp_digit tmpd[2 * 32 * 5]; +#endif + sp_point_1024* t; + sp_point_1024* rt; + sp_digit* tmp; + sp_digit n; + int i; + int c; + int y; + int err; + + /* Constant time used for cache attack resistance implementation. */ + (void)ct; + (void)heap; + + err = sp_1024_point_new_32(heap, rtd, rt); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +#ifndef WC_NO_CACHE_RESISTANT + t = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) * 17, heap, DYNAMIC_TYPE_ECC); +#else + t = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) * 16, heap, DYNAMIC_TYPE_ECC); +#endif + if (t == NULL) + err = MEMORY_E; + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 32 * 5, heap, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) + err = MEMORY_E; +#else + t = td; + tmp = tmpd; +#endif + + if (err == MP_OKAY) { + /* t[0] = {0, 0, 1} * norm */ + XMEMSET(&t[0], 0, sizeof(t[0])); + t[0].infinity = 1; + /* t[1] = {g->x, g->y, g->z} * norm */ + (void)sp_1024_mod_mul_norm_32(t[1].x, g->x, p1024_mod); + (void)sp_1024_mod_mul_norm_32(t[1].y, g->y, p1024_mod); + (void)sp_1024_mod_mul_norm_32(t[1].z, g->z, p1024_mod); + t[1].infinity = 0; + sp_1024_proj_point_dbl_32(&t[ 2], &t[ 1], tmp); + t[ 2].infinity = 0; + sp_1024_proj_point_add_32(&t[ 3], &t[ 2], &t[ 1], tmp); + t[ 3].infinity = 0; + sp_1024_proj_point_dbl_32(&t[ 4], &t[ 2], tmp); + t[ 4].infinity = 0; + sp_1024_proj_point_add_32(&t[ 5], &t[ 3], &t[ 2], tmp); + t[ 5].infinity = 0; + sp_1024_proj_point_dbl_32(&t[ 6], &t[ 3], tmp); + t[ 6].infinity = 0; + sp_1024_proj_point_add_32(&t[ 7], &t[ 4], &t[ 3], tmp); + t[ 7].infinity = 0; + sp_1024_proj_point_dbl_32(&t[ 8], &t[ 4], tmp); + t[ 8].infinity = 0; + sp_1024_proj_point_add_32(&t[ 9], &t[ 5], &t[ 4], tmp); + t[ 9].infinity = 0; + sp_1024_proj_point_dbl_32(&t[10], &t[ 5], tmp); + t[10].infinity = 0; + sp_1024_proj_point_add_32(&t[11], &t[ 6], &t[ 5], tmp); + t[11].infinity = 0; + sp_1024_proj_point_dbl_32(&t[12], &t[ 6], tmp); + t[12].infinity = 0; + sp_1024_proj_point_add_32(&t[13], &t[ 7], &t[ 6], tmp); + t[13].infinity = 0; + sp_1024_proj_point_dbl_32(&t[14], &t[ 7], tmp); + t[14].infinity = 0; + sp_1024_proj_point_add_32(&t[15], &t[ 8], &t[ 7], tmp); + t[15].infinity = 0; + + i = 30; + n = k[i+1] << 0; + c = 28; + y = (int)(n >> 28); + XMEMCPY(rt, &t[y], sizeof(sp_point_1024)); + n <<= 4; + for (; i>=0 || c>=4; ) { + if (c < 4) { + n |= k[i--]; + c += 32; + } + y = (n >> 28) & 0xf; + n <<= 4; + c -= 4; + + sp_1024_proj_point_dbl_32(rt, rt, tmp); + sp_1024_proj_point_dbl_32(rt, rt, tmp); + sp_1024_proj_point_dbl_32(rt, rt, tmp); + sp_1024_proj_point_dbl_32(rt, rt, tmp); + sp_1024_proj_point_add_32(rt, rt, &t[y], tmp); + } + + if (map != 0) { + sp_1024_map_32(r, rt, tmp); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_1024)); + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (tmp != NULL) { + XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 32 * 5); + XFREE(tmp, heap, DYNAMIC_TYPE_ECC); + } + if (t != NULL) { + XMEMSET(t, 0, sizeof(sp_point_1024) * 16); + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#else + ForceZero(tmpd, sizeof(tmpd)); + ForceZero(td, sizeof(td)); +#endif + sp_1024_point_free_32(rt, 1, heap); + + return err; +} + +#if defined(FP_ECC) || !defined(WOLFSSL_SP_SMALL) +/* Double the Montgomery form projective point p a number of times. + * + * r Result of repeated doubling of point. + * p Point to double. + * n Number of times to double + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_dbl_n_32(sp_point_1024* p, int n, + sp_digit* t) +{ + sp_digit* w = t; + sp_digit* a = t + 2*32; + sp_digit* b = t + 4*32; + sp_digit* t1 = t + 6*32; + sp_digit* t2 = t + 8*32; + sp_digit* x; + sp_digit* y; + sp_digit* z; + + x = p->x; + y = p->y; + z = p->z; + + /* Y = 2*Y */ + sp_1024_mont_dbl_32(y, y, p1024_mod); + /* W = Z^4 */ + sp_1024_mont_sqr_32(w, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_32(w, w, p1024_mod, p1024_mp_mod); + +#ifndef WOLFSSL_SP_SMALL + while (--n > 0) +#else + while (--n >= 0) +#endif + { + /* A = 3*(X^2 - W) */ + sp_1024_mont_sqr_32(t1, x, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_32(t1, t1, w, p1024_mod); + sp_1024_mont_tpl_32(a, t1, p1024_mod); + /* B = X*Y^2 */ + sp_1024_mont_sqr_32(t1, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(b, t1, x, p1024_mod, p1024_mp_mod); + /* X = A^2 - 2B */ + sp_1024_mont_sqr_32(x, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_32(t2, b, p1024_mod); + sp_1024_mont_sub_32(x, x, t2, p1024_mod); + /* Z = Z*Y */ + sp_1024_mont_mul_32(z, z, y, p1024_mod, p1024_mp_mod); + /* t2 = Y^4 */ + sp_1024_mont_sqr_32(t1, t1, p1024_mod, p1024_mp_mod); +#ifdef WOLFSSL_SP_SMALL + if (n != 0) +#endif + { + /* W = W*Y^4 */ + sp_1024_mont_mul_32(w, w, t1, p1024_mod, p1024_mp_mod); + } + /* y = 2*A*(B - X) - Y^4 */ + sp_1024_mont_sub_32(y, b, x, p1024_mod); + sp_1024_mont_mul_32(y, y, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_32(y, y, p1024_mod); + sp_1024_mont_sub_32(y, y, t1, p1024_mod); + } +#ifndef WOLFSSL_SP_SMALL + /* A = 3*(X^2 - W) */ + sp_1024_mont_sqr_32(t1, x, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_32(t1, t1, w, p1024_mod); + sp_1024_mont_tpl_32(a, t1, p1024_mod); + /* B = X*Y^2 */ + sp_1024_mont_sqr_32(t1, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(b, t1, x, p1024_mod, p1024_mp_mod); + /* X = A^2 - 2B */ + sp_1024_mont_sqr_32(x, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_32(t2, b, p1024_mod); + sp_1024_mont_sub_32(x, x, t2, p1024_mod); + /* Z = Z*Y */ + sp_1024_mont_mul_32(z, z, y, p1024_mod, p1024_mp_mod); + /* t2 = Y^4 */ + sp_1024_mont_sqr_32(t1, t1, p1024_mod, p1024_mp_mod); + /* y = 2*A*(B - X) - Y^4 */ + sp_1024_mont_sub_32(y, b, x, p1024_mod); + sp_1024_mont_mul_32(y, y, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_32(y, y, p1024_mod); + sp_1024_mont_sub_32(y, y, t1, p1024_mod); +#endif + /* Y = Y/2 */ + sp_1024_div2_32(y, y, p1024_mod); +} + +/* Convert the projective point to affine. + * Ordinates are in Montgomery form. + * + * a Point to convert. + * t Temporary data. + */ +static void sp_1024_proj_to_affine_32(sp_point_1024* a, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 32; + sp_digit* tmp = t + 4 * 32; + + sp_1024_mont_inv_32(t1, a->z, tmp); + + sp_1024_mont_sqr_32(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t1, t2, t1, p1024_mod, p1024_mp_mod); + + sp_1024_mont_mul_32(a->x, a->x, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(a->y, a->y, t1, p1024_mod, p1024_mp_mod); + XMEMCPY(a->z, p1024_norm_mod, sizeof(p1024_norm_mod)); +} + +#endif /* FP_ECC || !WOLFSSL_SP_SMALL */ +/* A table entry for pre-computed points. */ +typedef struct sp_table_entry_1024 { + sp_digit x[32]; + sp_digit y[32]; +} sp_table_entry_1024; + +#ifdef FP_ECC +#endif /* FP_ECC */ +/* Add two Montgomery form projective points. The second point has a q value of + * one. + * Only the first point can be the same pointer as the result point. + * + * r Result of addition. + * p First point to add. + * q Second point to add. + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_add_qz1_32(sp_point_1024* r, const sp_point_1024* p, + const sp_point_1024* q, sp_digit* t) +{ + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*32; + sp_digit* t3 = t + 4*32; + sp_digit* t4 = t + 6*32; + sp_digit* t5 = t + 8*32; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Check double */ + (void)sp_1024_mont_sub_32(t1, p1024_mod, q->y, p1024_mod); + sp_1024_norm_32(t1); + if ((sp_1024_cmp_equal_32(p->x, q->x) & sp_1024_cmp_equal_32(p->z, q->z) & + (sp_1024_cmp_equal_32(p->y, q->y) | sp_1024_cmp_equal_32(p->y, t1))) != 0) { + sp_1024_proj_point_dbl_32(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_1024)); + x = rp[p->infinity | q->infinity]->x; + y = rp[p->infinity | q->infinity]->y; + z = rp[p->infinity | q->infinity]->z; + + ap[0] = p; + ap[1] = q; + for (i=0; i<32; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<32; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<32; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_32(t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t4, t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t2, t2, q->x, p1024_mod, p1024_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_32(t4, t4, q->y, p1024_mod, p1024_mp_mod); + /* H = U2 - X1 */ + sp_1024_mont_sub_32(t2, t2, x, p1024_mod); + /* R = S2 - Y1 */ + sp_1024_mont_sub_32(t4, t4, y, p1024_mod); + /* Z3 = H*Z1 */ + sp_1024_mont_mul_32(z, z, t2, p1024_mod, p1024_mp_mod); + /* X3 = R^2 - H^3 - 2*X1*H^2 */ + sp_1024_mont_sqr_32(t1, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_32(t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t3, x, t5, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t5, t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_32(x, t1, t5, p1024_mod); + sp_1024_mont_dbl_32(t1, t3, p1024_mod); + sp_1024_mont_sub_32(x, x, t1, p1024_mod); + /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */ + sp_1024_mont_sub_32(t3, t3, x, p1024_mod); + sp_1024_mont_mul_32(t3, t3, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t5, t5, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_32(y, t3, t5, p1024_mod); + } +} + +#ifdef WOLFSSL_SP_SMALL +#if defined(FP_ECC) || !defined(WOLFSSL_SP_SMALL) +/* Generate the pre-computed table of points for the base point. + * + * width = 4 + * 16 entries + * 256 bits between + * + * a The base point. + * table Place to store generated point data. + * tmp Temporary data. + * heap Heap to use for allocation. + */ +static int sp_1024_gen_stripe_table_32(const sp_point_1024* a, + sp_table_entry_1024* table, sp_digit* tmp, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 td; + sp_point_1024 s1d; + sp_point_1024 s2d; +#endif + sp_point_1024* t; + sp_point_1024* s1 = NULL; + sp_point_1024* s2 = NULL; + int i; + int j; + int err; + + (void)heap; + + err = sp_1024_point_new_32(heap, td, t); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, s1d, s1); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, s2d, s2); + } + + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(t->x, a->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(t->y, a->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(t->z, a->z, p1024_mod); + } + if (err == MP_OKAY) { + t->infinity = 0; + sp_1024_proj_to_affine_32(t, tmp); + + XMEMCPY(s1->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + s1->infinity = 0; + XMEMCPY(s2->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + s2->infinity = 0; + + /* table[0] = {0, 0, infinity} */ + XMEMSET(&table[0], 0, sizeof(sp_table_entry_1024)); + /* table[1] = Affine version of 'a' in Montgomery form */ + XMEMCPY(table[1].x, t->x, sizeof(table->x)); + XMEMCPY(table[1].y, t->y, sizeof(table->y)); + + for (i=1; i<4; i++) { + sp_1024_proj_point_dbl_n_32(t, 256, tmp); + sp_1024_proj_to_affine_32(t, tmp); + XMEMCPY(table[1<x, sizeof(table->x)); + XMEMCPY(table[1<y, sizeof(table->y)); + } + + for (i=1; i<4; i++) { + XMEMCPY(s1->x, table[1<x)); + XMEMCPY(s1->y, table[1<y)); + for (j=(1<x, table[j-(1<x)); + XMEMCPY(s2->y, table[j-(1<y)); + sp_1024_proj_point_add_qz1_32(t, s1, s2, tmp); + sp_1024_proj_to_affine_32(t, tmp); + XMEMCPY(table[j].x, t->x, sizeof(table->x)); + XMEMCPY(table[j].y, t->y, sizeof(table->y)); + } + } + } + + sp_1024_point_free_32(s2, 0, heap); + sp_1024_point_free_32(s1, 0, heap); + sp_1024_point_free_32( t, 0, heap); + + return err; +} + +#endif /* FP_ECC || !WOLFSSL_SP_SMALL */ +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^256, ... + * Pre-generated: products of all combinations of above. + * 4 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * table Pre-computed table. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_stripe_32(sp_point_1024* r, const sp_point_1024* g, + const sp_table_entry_1024* table, const sp_digit* k, int map, + int ct, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 rtd; + sp_point_1024 pd; + sp_digit td[2 * 32 * 5]; +#endif + sp_point_1024* rt; + sp_point_1024* p = NULL; + sp_digit* t; + int i; + int j; + int y; + int x; + int err; + + (void)g; + /* Constant time used for cache attack resistance implementation. */ + (void)ct; + (void)heap; + + + err = sp_1024_point_new_32(heap, rtd, rt); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, pd, p); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 32 * 5, heap, + DYNAMIC_TYPE_ECC); + if (t == NULL) { + err = MEMORY_E; + } +#else + t = td; +#endif + + if (err == MP_OKAY) { + XMEMCPY(p->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + XMEMCPY(rt->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + + y = 0; + x = 255; + for (j=0; j<4; j++) { + y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 256; + } + XMEMCPY(rt->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(rt->y, table[y].y, sizeof(table[y].y)); + rt->infinity = !y; + for (i=254; i>=0; i--) { + y = 0; + x = i; + for (j=0; j<4; j++) { + y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 256; + } + + sp_1024_proj_point_dbl_32(rt, rt, t); + XMEMCPY(p->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(p->y, table[y].y, sizeof(table[y].y)); + p->infinity = !y; + sp_1024_proj_point_add_qz1_32(rt, rt, p, t); + } + + if (map != 0) { + sp_1024_map_32(r, rt, t); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_1024)); + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (t != NULL) { + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_32(p, 0, heap); + sp_1024_point_free_32(rt, 0, heap); + + return err; +} + +#ifdef FP_ECC +#ifndef FP_ENTRIES + #define FP_ENTRIES 16 +#endif + +/* Cache entry - holds precomputation tables for a point. */ +typedef struct sp_cache_1024_t { + /* X ordinate of point that table was generated from. */ + sp_digit x[32]; + /* Y ordinate of point that table was generated from. */ + sp_digit y[32]; + /* Precomputation table for point. */ + sp_table_entry_1024 table[16]; + /* Count of entries in table. */ + uint32_t cnt; + /* Point and table set in entry. */ + int set; +} sp_cache_1024_t; + +/* Cache of tables. */ +static THREAD_LS_T sp_cache_1024_t sp_cache_1024[FP_ENTRIES]; +/* Index of last entry in cache. */ +static THREAD_LS_T int sp_cache_1024_last = -1; +/* Cache has been initialized. */ +static THREAD_LS_T int sp_cache_1024_inited = 0; + +#ifndef HAVE_THREAD_LS + static volatile int initCacheMutex_1024 = 0; + static wolfSSL_Mutex sp_cache_1024_lock; +#endif + +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ +static void sp_ecc_get_cache_1024(const sp_point_1024* g, sp_cache_1024_t** cache) +{ + int i; + int j; + uint32_t least; + + if (sp_cache_1024_inited == 0) { + for (i=0; ix, sp_cache_1024[i].x) & + sp_1024_cmp_equal_32(g->y, sp_cache_1024[i].y)) { + sp_cache_1024[i].cnt++; + break; + } + } + + /* No match. */ + if (i == FP_ENTRIES) { + /* Find empty entry. */ + i = (sp_cache_1024_last + 1) % FP_ENTRIES; + for (; i != sp_cache_1024_last; i=(i+1)%FP_ENTRIES) { + if (!sp_cache_1024[i].set) { + break; + } + } + + /* Evict least used. */ + if (i == sp_cache_1024_last) { + least = sp_cache_1024[0].cnt; + for (j=1; jx, sizeof(sp_cache_1024[i].x)); + XMEMCPY(sp_cache_1024[i].y, g->y, sizeof(sp_cache_1024[i].y)); + sp_cache_1024[i].set = 1; + sp_cache_1024[i].cnt = 1; + } + + *cache = &sp_cache_1024[i]; + sp_cache_1024_last = i; +} +#endif /* FP_ECC */ + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * r Resulting point. + * g Point to multiply. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_32(sp_point_1024* r, const sp_point_1024* g, const sp_digit* k, + int map, int ct, void* heap) +{ +#ifndef FP_ECC + return sp_1024_ecc_mulmod_fast_32(r, g, k, map, ct, heap); +#else + sp_digit tmp[2 * 32 * 5]; + sp_cache_1024_t* cache; + int err = MP_OKAY; + +#ifndef HAVE_THREAD_LS + if (initCacheMutex_1024 == 0) { + wc_InitMutex(&sp_cache_1024_lock); + initCacheMutex_1024 = 1; + } + if (wc_LockMutex(&sp_cache_1024_lock) != 0) + err = BAD_MUTEX_E; +#endif /* HAVE_THREAD_LS */ + + if (err == MP_OKAY) { + sp_ecc_get_cache_1024(g, &cache); + if (cache->cnt == 2) + sp_1024_gen_stripe_table_32(g, cache->table, tmp, heap); + +#ifndef HAVE_THREAD_LS + wc_UnLockMutex(&sp_cache_1024_lock); +#endif /* HAVE_THREAD_LS */ + + if (cache->cnt < 2) { + err = sp_1024_ecc_mulmod_fast_32(r, g, k, map, ct, heap); + } + else { + err = sp_1024_ecc_mulmod_stripe_32(r, g, cache->table, k, + map, ct, heap); + } + } + + return err; +#endif +} + +#else +#if defined(FP_ECC) || !defined(WOLFSSL_SP_SMALL) +/* Generate the pre-computed table of points for the base point. + * + * width = 8 + * 256 entries + * 128 bits between + * + * a The base point. + * table Place to store generated point data. + * tmp Temporary data. + * heap Heap to use for allocation. + */ +static int sp_1024_gen_stripe_table_32(const sp_point_1024* a, + sp_table_entry_1024* table, sp_digit* tmp, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 td; + sp_point_1024 s1d; + sp_point_1024 s2d; +#endif + sp_point_1024* t; + sp_point_1024* s1 = NULL; + sp_point_1024* s2 = NULL; + int i; + int j; + int err; + + (void)heap; + + err = sp_1024_point_new_32(heap, td, t); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, s1d, s1); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, s2d, s2); + } + + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(t->x, a->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(t->y, a->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(t->z, a->z, p1024_mod); + } + if (err == MP_OKAY) { + t->infinity = 0; + sp_1024_proj_to_affine_32(t, tmp); + + XMEMCPY(s1->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + s1->infinity = 0; + XMEMCPY(s2->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + s2->infinity = 0; + + /* table[0] = {0, 0, infinity} */ + XMEMSET(&table[0], 0, sizeof(sp_table_entry_1024)); + /* table[1] = Affine version of 'a' in Montgomery form */ + XMEMCPY(table[1].x, t->x, sizeof(table->x)); + XMEMCPY(table[1].y, t->y, sizeof(table->y)); + + for (i=1; i<8; i++) { + sp_1024_proj_point_dbl_n_32(t, 128, tmp); + sp_1024_proj_to_affine_32(t, tmp); + XMEMCPY(table[1<x, sizeof(table->x)); + XMEMCPY(table[1<y, sizeof(table->y)); + } + + for (i=1; i<8; i++) { + XMEMCPY(s1->x, table[1<x)); + XMEMCPY(s1->y, table[1<y)); + for (j=(1<x, table[j-(1<x)); + XMEMCPY(s2->y, table[j-(1<y)); + sp_1024_proj_point_add_qz1_32(t, s1, s2, tmp); + sp_1024_proj_to_affine_32(t, tmp); + XMEMCPY(table[j].x, t->x, sizeof(table->x)); + XMEMCPY(table[j].y, t->y, sizeof(table->y)); + } + } + } + + sp_1024_point_free_32(s2, 0, heap); + sp_1024_point_free_32(s1, 0, heap); + sp_1024_point_free_32( t, 0, heap); + + return err; +} + +#endif /* FP_ECC || !WOLFSSL_SP_SMALL */ +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^128, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * table Pre-computed table. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_stripe_32(sp_point_1024* r, const sp_point_1024* g, + const sp_table_entry_1024* table, const sp_digit* k, int map, + int ct, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 rtd; + sp_point_1024 pd; + sp_digit td[2 * 32 * 5]; +#endif + sp_point_1024* rt; + sp_point_1024* p = NULL; + sp_digit* t; + int i; + int j; + int y; + int x; + int err; + + (void)g; + /* Constant time used for cache attack resistance implementation. */ + (void)ct; + (void)heap; + + + err = sp_1024_point_new_32(heap, rtd, rt); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, pd, p); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 32 * 5, heap, + DYNAMIC_TYPE_ECC); + if (t == NULL) { + err = MEMORY_E; + } +#else + t = td; +#endif + + if (err == MP_OKAY) { + XMEMCPY(p->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + XMEMCPY(rt->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + + y = 0; + x = 127; + for (j=0; j<8; j++) { + y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 128; + } + XMEMCPY(rt->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(rt->y, table[y].y, sizeof(table[y].y)); + rt->infinity = !y; + for (i=126; i>=0; i--) { + y = 0; + x = i; + for (j=0; j<8; j++) { + y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 128; + } + + sp_1024_proj_point_dbl_32(rt, rt, t); + XMEMCPY(p->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(p->y, table[y].y, sizeof(table[y].y)); + p->infinity = !y; + sp_1024_proj_point_add_qz1_32(rt, rt, p, t); + } + + if (map != 0) { + sp_1024_map_32(r, rt, t); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_1024)); + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (t != NULL) { + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_32(p, 0, heap); + sp_1024_point_free_32(rt, 0, heap); + + return err; +} + +#ifdef FP_ECC +#ifndef FP_ENTRIES + #define FP_ENTRIES 16 +#endif + +/* Cache entry - holds precomputation tables for a point. */ +typedef struct sp_cache_1024_t { + /* X ordinate of point that table was generated from. */ + sp_digit x[32]; + /* Y ordinate of point that table was generated from. */ + sp_digit y[32]; + /* Precomputation table for point. */ + sp_table_entry_1024 table[256]; + /* Count of entries in table. */ + uint32_t cnt; + /* Point and table set in entry. */ + int set; +} sp_cache_1024_t; + +/* Cache of tables. */ +static THREAD_LS_T sp_cache_1024_t sp_cache_1024[FP_ENTRIES]; +/* Index of last entry in cache. */ +static THREAD_LS_T int sp_cache_1024_last = -1; +/* Cache has been initialized. */ +static THREAD_LS_T int sp_cache_1024_inited = 0; + +#ifndef HAVE_THREAD_LS + static volatile int initCacheMutex_1024 = 0; + static wolfSSL_Mutex sp_cache_1024_lock; +#endif + +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ +static void sp_ecc_get_cache_1024(const sp_point_1024* g, sp_cache_1024_t** cache) +{ + int i; + int j; + uint32_t least; + + if (sp_cache_1024_inited == 0) { + for (i=0; ix, sp_cache_1024[i].x) & + sp_1024_cmp_equal_32(g->y, sp_cache_1024[i].y)) { + sp_cache_1024[i].cnt++; + break; + } + } + + /* No match. */ + if (i == FP_ENTRIES) { + /* Find empty entry. */ + i = (sp_cache_1024_last + 1) % FP_ENTRIES; + for (; i != sp_cache_1024_last; i=(i+1)%FP_ENTRIES) { + if (!sp_cache_1024[i].set) { + break; + } + } + + /* Evict least used. */ + if (i == sp_cache_1024_last) { + least = sp_cache_1024[0].cnt; + for (j=1; jx, sizeof(sp_cache_1024[i].x)); + XMEMCPY(sp_cache_1024[i].y, g->y, sizeof(sp_cache_1024[i].y)); + sp_cache_1024[i].set = 1; + sp_cache_1024[i].cnt = 1; + } + + *cache = &sp_cache_1024[i]; + sp_cache_1024_last = i; +} +#endif /* FP_ECC */ + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * r Resulting point. + * g Point to multiply. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_32(sp_point_1024* r, const sp_point_1024* g, const sp_digit* k, + int map, int ct, void* heap) +{ +#ifndef FP_ECC + return sp_1024_ecc_mulmod_fast_32(r, g, k, map, ct, heap); +#else + sp_digit tmp[2 * 32 * 5]; + sp_cache_1024_t* cache; + int err = MP_OKAY; + +#ifndef HAVE_THREAD_LS + if (initCacheMutex_1024 == 0) { + wc_InitMutex(&sp_cache_1024_lock); + initCacheMutex_1024 = 1; + } + if (wc_LockMutex(&sp_cache_1024_lock) != 0) + err = BAD_MUTEX_E; +#endif /* HAVE_THREAD_LS */ + + if (err == MP_OKAY) { + sp_ecc_get_cache_1024(g, &cache); + if (cache->cnt == 2) + sp_1024_gen_stripe_table_32(g, cache->table, tmp, heap); + +#ifndef HAVE_THREAD_LS + wc_UnLockMutex(&sp_cache_1024_lock); +#endif /* HAVE_THREAD_LS */ + + if (cache->cnt < 2) { + err = sp_1024_ecc_mulmod_fast_32(r, g, k, map, ct, heap); + } + else { + err = sp_1024_ecc_mulmod_stripe_32(r, g, cache->table, k, + map, ct, heap); + } + } + + return err; +#endif +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * p Point to multiply. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_1024(const mp_int* km, const ecc_point* gm, ecc_point* r, + int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_digit kd[32]; +#endif + sp_point_1024* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_32(heap, p, point); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 32, km); + sp_1024_point_from_ecc_point_32(point, gm); + + err = sp_1024_ecc_mulmod_32(point, point, k, map, 1, heap); + } + if (err == MP_OKAY) { + err = sp_1024_point_to_ecc_point_32(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_32(point, 0, heap); + + return err; +} + +#ifdef WOLFSSL_SP_SMALL +/* Striping precomputation table. + * 4 points combined into a table of 16 points. + * Distance of 256 between points. + */ +static const sp_table_entry_1024 p1024_table[16] = { + /* 0 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 */ + { { 0xe0162bc2,0xbf9c7ec6,0x10a89289,0xddecc6e3,0x9e499d81,0x5d599df0, + 0x6d358218,0x9a96ea28,0x70c5f8db,0x01aec7d3,0x8cf5d066,0xe72e4995, + 0x3e91d7f8,0xc2e7297d,0xda9f2f5a,0x8621db92,0x5a5679ed,0x4b26c867, + 0x2c56aac1,0x233385df,0xc6a13f99,0xb88e74d4,0xffa8ec11,0x1214b173, + 0x1f3f9fef,0xa0386a27,0xc0e7b44e,0xbd9b1b4e,0xeecd3496,0xafe528dc, + 0x1c49f80b,0x8dfff96a }, + { 0xc03c0c83,0xb4a4753a,0xabcdcd75,0x68e69d18,0xf775b649,0xe3839b88, + 0xbf58f352,0x803f949a,0xbd0bc15c,0x5f702679,0x8ff298c2,0x85bf5d16, + 0xc6c7976e,0x3f6ebd98,0x45e3e1b4,0x20618af4,0x54e64093,0x67d5598e, + 0x504fed9e,0xb047283b,0x70d87517,0x450cabfd,0x3f5addbe,0x47d628bf, + 0x78cb4cca,0x0037ef30,0x6b1c4908,0x4e148d3c,0x4fcfd837,0xe256d329, + 0xde3c01f3,0x2aa1207b } }, + /* 2 */ + { { 0x755c2a27,0xcf3e0bb2,0x59585c44,0xd38e42f9,0x19285e60,0x46b13e0f, + 0x76273d0f,0xc3ecd0c0,0x193c569a,0x7800f085,0x4351818a,0xf04e74ab, + 0x8496363b,0x9258aa38,0xb8c894fe,0x8456617c,0x2af969a0,0x8bc62aaa, + 0x5a4668d9,0x66c2280b,0xa992f4fa,0xbc9df58e,0x3f401e99,0x5db0b7d9, + 0xc4c38c0e,0xe0614fe1,0x2ccdf6b3,0xd531151c,0xe143b618,0x1c7575ec, + 0xdf9398a4,0x40247985 }, + { 0x8f055746,0xfba25178,0x0ab1e6e0,0xc5ba0040,0xac292697,0xe1b194fb, + 0x5b4f4740,0x77152119,0x9bb7ba54,0x250091d0,0xb9a139a4,0x7a674861, + 0xf353aa7e,0xba8413b3,0x2443ceee,0xafe77192,0x3847bbd0,0x14468d36, + 0x3da4942d,0x61f79ff6,0xd425b456,0x1563a1c1,0x75ff4630,0x3c270fcd, + 0xeb2802c9,0x42072090,0xc85c7004,0x68f0cdcb,0xfa032e74,0xca4372fb, + 0xc8b79d80,0x1a6fd1e6 } }, + /* 3 */ + { { 0x8d5116a3,0x967a901a,0xb2f5f47f,0x0b844394,0x60ebaf3b,0xe39ad452, + 0x60ccfc0c,0x1e1be617,0xcc3f53f2,0xac07e3d2,0x1ed11bb6,0xdd838e0e, + 0x1c15b0c2,0x45475307,0x920fe5b8,0x70dd4748,0xe471896d,0x1a20be2d, + 0x59276c7c,0x3c3fad8a,0xc886ee07,0x026a1cc3,0x6e831ac4,0x9fdb6f37, + 0xac501d65,0x26a35d1a,0x40da8574,0x0ae98905,0xabd734e5,0x65dde0a4, + 0x15614750,0x29b7d4dc }, + { 0xcbf4e20b,0x44b3c2cb,0x58cc44c5,0x1c3f548f,0x5b0cac1f,0x39809b54, + 0x00f80621,0x0c0f02b5,0x066905e0,0xe612b890,0x8350188c,0x8f158ed7, + 0x3f5576b2,0xc01dc458,0xa45492e0,0x29803272,0x0ff92443,0x77a5623a, + 0x29d0dc41,0xd12a2b00,0x2780e87a,0xb4125459,0x0d53f272,0x1ebcf903, + 0x24301e8d,0xbae6ea40,0xa37d0798,0x1e5f3f2f,0x22b4126c,0x9342c310, + 0x5382497e,0x5d092802 } }, + /* 4 */ + { { 0x4b59213a,0xf5b495d0,0x8d70200e,0xca672039,0x2b6771c1,0x4bcb09a6, + 0x2b9eb0cb,0x26adeed4,0x8cdba212,0xeb544754,0xf08890d1,0x0e1abfcd, + 0x698e46b4,0x52509963,0x82e9c138,0xe1bff0b0,0x51099a71,0xa189e4cd, + 0xc9b91cc7,0x2360c9bc,0x137ec4be,0x9bd4d7dc,0xd1519f6e,0xd0356521, + 0xcf832503,0xbf5f6d78,0x8deea2b4,0xe4301031,0xef4c319c,0xc3132494, + 0x0f1fa7d7,0x2ab3bd47 }, + { 0x922c9fbb,0x5753b680,0x0f16c6d1,0x869e7dc8,0xbac16efc,0x83445135, + 0x846d1d9b,0x4326a3b4,0xb2d62c21,0xb517fee3,0x0b292ad5,0x6905afa2, + 0x2cadac13,0x2a57131a,0xebdbca8d,0xcd904d8f,0x3f365fb2,0xdfeda86f, + 0xdc7eaa1c,0x7097b208,0xa45e77c0,0x89a35a84,0xcf5d118e,0x417a062c, + 0x1f6e99e8,0x3c0c04a8,0xba7a087d,0xc44704b0,0x3ea22ad2,0x6f8a27d1, + 0x4c27d229,0x93a4b416 } }, + /* 5 */ + { { 0x1f1efb7a,0xd4271bc1,0x33fccc0d,0xae4e68e6,0xb11f50a8,0x9d9bc8f1, + 0xaf076089,0x5430398f,0x443d0e03,0x45e242fb,0xf6e3d4c1,0x73ec2519, + 0xba9bad09,0xab70f790,0xf9add10f,0xde612ad5,0x14e942b4,0xb837e54e, + 0xddb8b68a,0x175a56d3,0x1ac2a408,0xe85b233c,0xf0c80f94,0xf8ff6c30, + 0x898db4f9,0x4b7f3fb7,0x45a7dcdd,0xa2c6044f,0xfe3d3895,0xf3abb2f6, + 0x32ee7763,0x342ce0d7 }, + { 0xcf491b1f,0xeb261394,0x1909e395,0xdcaaeed7,0x9fe4dbea,0xdcc4055a, + 0x493d604d,0x17a6611d,0x1ce5ebef,0xba445a3a,0xe3989cb5,0xe82e2858, + 0x83f58406,0xb96f4282,0xa156cf55,0x99877b99,0x4e166a0e,0xaf906a66, + 0xb2976d13,0xcea1d353,0x36c61a01,0xefc16f27,0xb0f55d86,0xdb04c433, + 0x8eb34c01,0x3cb4b269,0x2ae60280,0x38d07f78,0x43be3ec5,0x43ac3bcb, + 0xe156fd20,0x455f4af3 } }, + /* 6 */ + { { 0x95532833,0x2e6fe0a6,0xd626d067,0xabca228e,0x649e73bd,0x22aef3d9, + 0xf03c4c0c,0x2083a87a,0x35169b45,0xe954e75d,0x74506a89,0x577509ee, + 0x2aeacf90,0x49cb276e,0xfa409f91,0x08275d77,0xf0bbd6b9,0x61eb6f3d, + 0xe4132704,0x948202cb,0xb1c498b1,0x35f3fc21,0x361fee59,0x76c68ba8, + 0x50e051f3,0xa18cbbd9,0x318e7042,0x2384a879,0x80dd1e8b,0x292abead, + 0x5c37c334,0x65713c29 }, + { 0xceb77b9a,0xdccca8e9,0x23b69469,0x2f97e727,0xa01d6b28,0xc76abee6, + 0x5abecdfe,0x3925203d,0x29290d70,0x89448082,0xb0314438,0xf9931424, + 0x7cd447c3,0x04209df1,0xc855c827,0x7c6f2059,0x56c0e069,0xd97d7862, + 0x412d94c4,0x5a9db6fe,0x994c41dd,0x19a64591,0xc89e21a3,0x12348aa1, + 0xc6a03f0e,0xd6904b50,0xa616feac,0x55c15156,0x7cc7693b,0x4e36d1b5, + 0x3bae3c38,0x6b0e996c } }, + /* 7 */ + { { 0xcceced00,0x32789fab,0xe5b7aa66,0x3237e71a,0x2ddebcdf,0x87b2e269, + 0xb61dad8f,0xb7245120,0xd35f803c,0xe11e5e48,0x98e50f0d,0xfb4df5d7, + 0xbcd2ab92,0x60ee68b4,0x1ce3363d,0x98ab2f5c,0x7cd42647,0x15ba39da, + 0x83f4fb3f,0x1a6572eb,0xe56f08db,0x0f77de88,0x172562c2,0x1743761e, + 0x8a58f0f4,0xbe349ff8,0x84d1d6e2,0xe04da71b,0x9e9ff3b4,0x368f0342, + 0x678223f8,0x4022a205 }, + { 0x83847375,0x527bbd05,0x3f451af0,0x3ae56b62,0x4b2c7f18,0x6198f24d, + 0x4525b98d,0xee323f5b,0x0e0884b5,0xa9d8d39a,0xfb12c776,0xd005d7f6, + 0x708bc154,0xd71c483e,0x742541bc,0x8ca6fd28,0xf8397ddb,0x0af3dccd, + 0x3eccf243,0xb80d3125,0x58d81b8d,0xc743a108,0x71391f68,0x3f48eb21, + 0x33bb657f,0x493aff88,0x07e47e31,0x1d15ed66,0xe08279f6,0x10159b11, + 0x24a6a956,0x312179cb } }, + /* 8 */ + { { 0xfb99cfe6,0x950323d3,0xc9334178,0x7b09bc26,0x7cbdfb6f,0x64111e41, + 0x89a75760,0x91141744,0x10919cb0,0x4c633df9,0x396bfd2f,0x715fc7c7, + 0x8cab62db,0x8ca19512,0x4db81aac,0x30672473,0xb4c4c54a,0xe67a246b, + 0xbf229646,0xd77ea0fa,0xfa5b5d70,0x5bed15f1,0xc2f192f3,0xa5686da5, + 0x7f6690ad,0xdecac72a,0xcaa50b7d,0x0c4af2a2,0x6049ad2f,0xf44631c1, + 0x04ecf056,0x325d2796 }, + { 0x4848c144,0xee11fb55,0xb6a7af32,0x4e062925,0x369e0f9a,0x125b68e1, + 0xca53b21e,0xad9bdae6,0x2e98ea1b,0xf50d605c,0x9f2fa395,0xbdb9e153, + 0xe91532f5,0x4570e32d,0x46a250d7,0x810698ae,0xad9d9145,0x7fd9546c, + 0x11e97a5e,0xabf67721,0x249f82e9,0xca29f7d5,0x9851df63,0xa9c539a9, + 0x71d0e3e5,0xfd84d54b,0x041d2b56,0xd1e0459c,0xfd80096a,0xceb3eb6e, + 0xe32a79d3,0x19d48546 } }, + /* 9 */ + { { 0xb540f5e5,0xfe19ee8f,0x04e68d17,0x86d2a52f,0xadbdc871,0xd2320db0, + 0xd03a7fc8,0xa83ad5a8,0x08bcb916,0x54bf83c7,0x2e51e840,0x092133ea, + 0xcb52dddf,0xbce38424,0x31063583,0xd5c7be40,0x458e3176,0xc1ebb9df, + 0xbc4dabbf,0xafb19639,0xc05725a8,0x36350fe4,0x84e1cd24,0xac4a0634, + 0xc145b8de,0xadf73154,0xb3483237,0x0aa6dd9e,0xcbff2720,0xa3345c3d, + 0xb4e453b0,0x1b3ace6c }, + { 0x90a8bdc5,0x0343e5e9,0x6306a089,0xa203bf9d,0x8e48520e,0x98489a35, + 0xde7d1d06,0xbd17debe,0x5f795d3f,0x8fafa6d7,0x387b0a3f,0xa4ceb630, + 0xffddeafa,0xe0166b32,0x7e764e02,0xa2fe2054,0xe871f304,0x55ab9824, + 0x952ec45e,0xa2bd36bb,0xa90d20ca,0x7b4c1484,0x75bcfb53,0x5319f387, + 0x6982c4e5,0x34238a4a,0xa102921d,0xa2bb61c7,0xdb3ab17e,0x1e061b64, + 0x192f0a14,0x538ec33e } }, + /* 10 */ + { { 0x576374c2,0xe53c7785,0x84727040,0xe60526d1,0x228ca044,0x8a066dc8, + 0xf1ce1313,0x1fe1c1b2,0xcdeb0c5d,0x2aeec832,0x9cbf826f,0xa7596699, + 0xde77a589,0xcd188e81,0x118d1254,0xe5ce0fe0,0x0790b86a,0xa142a984, + 0x39ac28ce,0xe28f043f,0x87de5804,0x4eef8290,0xf639a8c5,0x83c31b32, + 0x5887794f,0xd70454a7,0x18b1b391,0xca635d50,0x31d9c795,0xcefea076, + 0xb6f8aa25,0x13cbee76 }, + { 0x8d3f34f3,0x79cabe0f,0xa3617fe3,0xbda9c31c,0xdd9426a1,0xb26dee23, + 0xf29c9104,0xe9dd9627,0xe2c6cd3b,0x033eb169,0xfcba2196,0x8a73f492, + 0xb858c83c,0x92e37e0b,0x23b3fbb7,0xe4f2aca6,0x64be00a2,0x8101fb1e, + 0x948f6448,0x91a7826a,0x907260e7,0x414067b4,0xe30bb835,0xf774aa50, + 0xc999c06e,0xf922ca80,0x0ba08511,0x6b8635b9,0x25fa04f0,0xbf936b5c, + 0xe02e8967,0x4e0a1ada } }, + /* 11 */ + { { 0x8ba29c4d,0x00ca6670,0x22988094,0xc08240ce,0x16dda752,0x21c5ca67, + 0xabbbfa34,0x689c0e45,0x3ed28b72,0x1d7545fd,0xd7c56ab4,0x5f221198, + 0x38759d65,0x4b3d8f74,0x8fe50b89,0x93490dfb,0xe80eba16,0xb641f5d7, + 0x79acb537,0x7b0da5eb,0x0c1d5e5e,0xab6b1497,0xa5da429a,0x2338e68d, + 0x2f6d2f25,0xe010c437,0x6530f3a7,0x226f16d2,0xcbef08bc,0xefb0f7b6, + 0x9f99c999,0x733e30d9 }, + { 0xa42a38f9,0xecfe1582,0x4730b500,0xaec2d58e,0xde976b2c,0x2ee2f2a7, + 0xa969c1bb,0xf0539db5,0xfcecdb4a,0x31954168,0xe7a8e902,0xf2f7348a, + 0x3121541f,0x1d58d7cc,0x2202ae52,0x5d25b75c,0xf40835a7,0xdea9965a, + 0x529b4e46,0x3feb6a41,0xbd27ad9b,0x5c97fb6f,0x261f900b,0xd87554c0, + 0x04d5b19e,0xb43031d9,0xcb219b9c,0x33d5e9b8,0x3ee00bcf,0x7a43d492, + 0xb79a5c0c,0x56facb39 } }, + /* 12 */ + { { 0x7c834915,0x667eaed6,0xbc5eb64d,0x9f77aa6a,0x25d62011,0x729ebcb6, + 0x699fd9c2,0x0aee24f2,0x2b8d4f6c,0xe1eb5874,0x14c976d6,0x7f12710c, + 0xf6d9ea65,0x91390335,0x06b50064,0x668b7049,0x0876ee4f,0x65969a0e, + 0x2f9d9360,0xf901bf3f,0xb499e3ce,0xfb1a8651,0xf2dbcaaa,0x80b953fb, + 0x973b06b6,0x312cc566,0x3af36c64,0x3534d9c3,0x10ffd815,0xe4463a52, + 0xf18c2b91,0x57ea2b4b }, + { 0x8aa0f2f2,0x00f5e162,0x0e46bcaa,0x8c7e75c5,0xa4a2c42d,0x97ab479a, + 0x14baa202,0xb4f308ea,0x6943cc2e,0xa901bd14,0xeed58804,0xbb125fee, + 0x9d180f7c,0x6502c8f9,0x1580c61c,0xe5353919,0x27101ee3,0x7e278069, + 0xfaa72717,0x7a0a40a1,0x4c75b153,0x32edce02,0x538f1c22,0xda23660b, + 0xbe307d2e,0x4d511e98,0x9baee0b4,0x24276e40,0x7ff1f307,0xa78c3927, + 0xea7935c9,0x60480b46 } }, + /* 13 */ + { { 0x3872ece3,0x31087d66,0x955b70f8,0x5f29be7d,0x9cf95bb8,0xb50b4fc7, + 0xdbffa621,0xbae3b58d,0xe022ba5d,0x0e61d280,0x4181449c,0x78ae5117, + 0xcf555485,0x0b132840,0xb8ce0b0e,0x800ed1b6,0x78d5de3d,0x35dffdd5, + 0x69a56b47,0xf7e42374,0x8d910ae7,0xd5e32369,0x6313c7c7,0xb6ff52a0, + 0xa92de9e5,0x5a2fe20d,0xd12110bb,0x41b347d3,0x40c16f23,0xc5905edb, + 0x9a8f88cc,0x0774a0d3 }, + { 0xe3b6c106,0x3ae181ab,0x8de150b7,0x4ebe163f,0x6f354836,0xcf75b82f, + 0x3ac7ac16,0xaa0d2063,0x291722af,0x5c680668,0x11545553,0x73941e61, + 0xbf5de3f7,0x17127e38,0x1afb41da,0x32cfdf03,0x87bc8663,0xc6893c91, + 0xa62c9c99,0x75046744,0x962c1947,0x96866e2d,0x378cdf4c,0x489ec8df, + 0x3407fa32,0x3a60709b,0x551290d1,0xd37d2159,0xbab92273,0x9623d303, + 0x2432014b,0x08151954 } }, + /* 14 */ + { { 0xb05f2b26,0x569044f3,0x80b9f76c,0xb35a294a,0x4290f6ae,0x8839fe28, + 0x026a5877,0x761cfb23,0x2e5ff9c3,0x768926b6,0x0b11c576,0xbae6cd20, + 0x72a03efe,0xdc857756,0xe1bad63a,0x0cae074a,0xd709d99c,0x3fe491a1, + 0x6501d9c1,0x76c5ded6,0xc32aeff7,0x1da6eca1,0xc57683e8,0x50849d55, + 0xdf98d847,0x9e392e9c,0x64d9a564,0xfad7982f,0xa37b98b2,0xf7c3bdb7, + 0xf0860497,0x1fe09f94 }, + { 0x7648cc63,0x49a7eaae,0x67cfa714,0x13ea2511,0x653f4559,0xfc8b923c, + 0x81a16e86,0xd957619b,0x3c864674,0x0c7e804b,0x1616599a,0xfc88134a, + 0x0a652328,0x366ea969,0x4bc9029e,0x41532960,0xae2aad2b,0xef9e1994, + 0x7f10bef5,0x9e2a8c52,0xc67bf860,0x73dcb586,0x844cc25d,0xf61a43fa, + 0x74eb3653,0xd74e7eea,0xdd240f02,0xf3356706,0xfd83bcb4,0xeec7694c, + 0xdb62526a,0x4de95786 } }, + /* 15 */ + { { 0x3deac2f7,0x4867d315,0xb61d9a8e,0xa084778a,0x0ab7b2d5,0xf3b76f96, + 0xcfdf4f79,0x00b30056,0x31ab8f4b,0xd0701e15,0x9c779d01,0x07f948d5, + 0x82675371,0x7c994ebc,0x48bad4c0,0x1104d4ee,0xbfc9d058,0x798ce0b5, + 0x309fa80b,0xc7ca898d,0xacb33eaf,0x0244f225,0x5b2f3175,0xd51e8dfc, + 0xa4d7be34,0x3e49ba6b,0xbda02b43,0x1760f4c7,0x4435275a,0x37e36a7e, + 0xe636980c,0x1c94418b }, + { 0x09dc1414,0x43a21313,0x43c93537,0x060765fc,0xdf5f79ce,0x6ff3207a, + 0x85d4cfca,0x6f18b1fa,0x63e995ab,0xf5c4272e,0xa82b3002,0x121a09e4, + 0x97147f16,0x82b65d1b,0x20a7fe26,0x4993c20c,0xe6716726,0x99c9cb98, + 0xfeb440a0,0x5a02d673,0x251b4bc5,0x3f3fa9e1,0xa05338ea,0x75dbc474, + 0x7b09f6cb,0x3cb4044b,0x80434609,0x6767da18,0x098ceac2,0x97851422, + 0xb55235ba,0x611bfbb2 } }, +}; + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^256, ... + * Pre-generated: products of all combinations of above. + * 4 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_base_32(sp_point_1024* r, const sp_digit* k, + int map, int ct, void* heap) +{ + return sp_1024_ecc_mulmod_stripe_32(r, &p1024_base, p1024_table, + k, map, ct, heap); +} + +#else +/* Striping precomputation table. + * 8 points combined into a table of 256 points. + * Distance of 128 between points. + */ +static const sp_table_entry_1024 p1024_table[256] = { + /* 0 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 */ + { { 0xe0162bc2,0xbf9c7ec6,0x10a89289,0xddecc6e3,0x9e499d81,0x5d599df0, + 0x6d358218,0x9a96ea28,0x70c5f8db,0x01aec7d3,0x8cf5d066,0xe72e4995, + 0x3e91d7f8,0xc2e7297d,0xda9f2f5a,0x8621db92,0x5a5679ed,0x4b26c867, + 0x2c56aac1,0x233385df,0xc6a13f99,0xb88e74d4,0xffa8ec11,0x1214b173, + 0x1f3f9fef,0xa0386a27,0xc0e7b44e,0xbd9b1b4e,0xeecd3496,0xafe528dc, + 0x1c49f80b,0x8dfff96a }, + { 0xc03c0c83,0xb4a4753a,0xabcdcd75,0x68e69d18,0xf775b649,0xe3839b88, + 0xbf58f352,0x803f949a,0xbd0bc15c,0x5f702679,0x8ff298c2,0x85bf5d16, + 0xc6c7976e,0x3f6ebd98,0x45e3e1b4,0x20618af4,0x54e64093,0x67d5598e, + 0x504fed9e,0xb047283b,0x70d87517,0x450cabfd,0x3f5addbe,0x47d628bf, + 0x78cb4cca,0x0037ef30,0x6b1c4908,0x4e148d3c,0x4fcfd837,0xe256d329, + 0xde3c01f3,0x2aa1207b } }, + /* 2 */ + { { 0x01900955,0xa95b6dae,0xceb4656d,0xa5dc9cc1,0xe72fe95b,0x50c78907, + 0xa040c334,0xa1ae5447,0x7952ea6e,0x91191370,0x6d097305,0x54ff7343, + 0xbda4d10f,0xa4db0074,0x91644070,0xfd5306f1,0x8b24522c,0x14b9fe73, + 0x7849f762,0x1468dad6,0xb0dcd2e4,0x87b29a18,0x5e1ad492,0xadd7f1a1, + 0xdbba2a1a,0x9ac63a81,0x81223379,0x01379c5b,0xb0e53bc8,0xf402b2f0, + 0x0bf13b61,0x8c3eb27f }, + { 0xe513696f,0x9a4ad3e1,0x18c81ffa,0x0350ba5c,0x3c033d13,0x1e2fc136, + 0x17a531bc,0x53da6e71,0x1aed610d,0x42ec6490,0xe99ff567,0xd33e8df7, + 0x3deed12a,0xe4aad73e,0x180f4deb,0xd983b465,0x502f30b4,0x99365269, + 0xa8918d7f,0x7e2799ab,0x700fc79a,0x0ffe84b6,0x40bfd8c2,0x7b4400d6, + 0x5d2641bd,0xc3a21d21,0xc32621cb,0x79839442,0xb1401e83,0xace6500b, + 0x251c4310,0x7bf4163e } }, + /* 3 */ + { { 0xe3fd589e,0x1c174f88,0xdf974a03,0xdb501790,0x3e70549f,0xd09623e3, + 0x15924f34,0x8d091eff,0xf9b65ac5,0xeef79cad,0x3f69c2cf,0xd2cc4262, + 0x52cd82bc,0x817d9032,0xa5f1dddd,0xacf4f4d9,0x5011b6bd,0xd0612635, + 0x2ed140c9,0x9f74490d,0x4db686d2,0x64092e8c,0x776b0fcc,0x225eef16, + 0xdf16aeb6,0x0e8c01e9,0x84bbd82a,0x62836741,0x8956e337,0x757574e2, + 0x705a7f07,0x9871edc6 }, + { 0x776535f7,0xbd0b76d5,0x2635b3b8,0x5214d602,0x9d216f64,0xc0c25ad9, + 0x5515bf75,0xfd4df3a7,0x5e9f1675,0x24a625bc,0x406873e7,0x3c35efb7, + 0xbb2e5c4a,0xef5c9a33,0x806b198a,0xa971b35e,0xa3c690ed,0x9f5c0ca5, + 0x8e1e2341,0xa8d5dd89,0x955ad9e4,0x4cecbcce,0x248d3416,0x2ecf4407, + 0x45c0af6e,0x1abb3811,0x1c780fff,0x3f4bee82,0xc272ed57,0xd14df768, + 0x371637ad,0x397ed10a } }, + /* 4 */ + { { 0x755c2a27,0xcf3e0bb2,0x59585c44,0xd38e42f9,0x19285e60,0x46b13e0f, + 0x76273d0f,0xc3ecd0c0,0x193c569a,0x7800f085,0x4351818a,0xf04e74ab, + 0x8496363b,0x9258aa38,0xb8c894fe,0x8456617c,0x2af969a0,0x8bc62aaa, + 0x5a4668d9,0x66c2280b,0xa992f4fa,0xbc9df58e,0x3f401e99,0x5db0b7d9, + 0xc4c38c0e,0xe0614fe1,0x2ccdf6b3,0xd531151c,0xe143b618,0x1c7575ec, + 0xdf9398a4,0x40247985 }, + { 0x8f055746,0xfba25178,0x0ab1e6e0,0xc5ba0040,0xac292697,0xe1b194fb, + 0x5b4f4740,0x77152119,0x9bb7ba54,0x250091d0,0xb9a139a4,0x7a674861, + 0xf353aa7e,0xba8413b3,0x2443ceee,0xafe77192,0x3847bbd0,0x14468d36, + 0x3da4942d,0x61f79ff6,0xd425b456,0x1563a1c1,0x75ff4630,0x3c270fcd, + 0xeb2802c9,0x42072090,0xc85c7004,0x68f0cdcb,0xfa032e74,0xca4372fb, + 0xc8b79d80,0x1a6fd1e6 } }, + /* 5 */ + { { 0x8d5116a3,0x967a901a,0xb2f5f47f,0x0b844394,0x60ebaf3b,0xe39ad452, + 0x60ccfc0c,0x1e1be617,0xcc3f53f2,0xac07e3d2,0x1ed11bb6,0xdd838e0e, + 0x1c15b0c2,0x45475307,0x920fe5b8,0x70dd4748,0xe471896d,0x1a20be2d, + 0x59276c7c,0x3c3fad8a,0xc886ee07,0x026a1cc3,0x6e831ac4,0x9fdb6f37, + 0xac501d65,0x26a35d1a,0x40da8574,0x0ae98905,0xabd734e5,0x65dde0a4, + 0x15614750,0x29b7d4dc }, + { 0xcbf4e20b,0x44b3c2cb,0x58cc44c5,0x1c3f548f,0x5b0cac1f,0x39809b54, + 0x00f80621,0x0c0f02b5,0x066905e0,0xe612b890,0x8350188c,0x8f158ed7, + 0x3f5576b2,0xc01dc458,0xa45492e0,0x29803272,0x0ff92443,0x77a5623a, + 0x29d0dc41,0xd12a2b00,0x2780e87a,0xb4125459,0x0d53f272,0x1ebcf903, + 0x24301e8d,0xbae6ea40,0xa37d0798,0x1e5f3f2f,0x22b4126c,0x9342c310, + 0x5382497e,0x5d092802 } }, + /* 6 */ + { { 0xff2f780d,0x583a2b7e,0xd7d76b1d,0x34d26820,0x86f74aec,0xe3c32847, + 0x10823feb,0x0fd42212,0xfb5e7bf4,0x227e417e,0xa568f8cd,0x510d49b6, + 0x1781bbec,0x53bce7d6,0x2f3718b7,0x9cfe3f22,0xd9de6c1f,0x7f44e89f, + 0x3fac9b55,0xf1cc553f,0xe6f300bc,0x9d2d0846,0x9f0ae6b1,0x976c82a2, + 0x24b8bbe0,0xe63dbf5e,0x973a5aa7,0x4cac7f45,0x84dd33c7,0xc6eb6237, + 0x142fee5d,0x0a26e434 }, + { 0xacaa9a08,0x8081339f,0x5246ece1,0x40f31105,0x61393747,0x892c8170, + 0x242f02e1,0x8d8d4103,0x3b5de98a,0x482bfd20,0x5abbe952,0x89ef946b, + 0x37698249,0xb8d218b9,0x66617c7a,0xd5268e89,0x8b7d2b91,0x962e7551, + 0xfe8d67c3,0x2c5c7973,0x2b017c51,0x42e3150a,0xc1a29469,0x6f4e5ebc, + 0x531c7083,0xa39910ce,0xb77b9e50,0xaf4f6eb4,0xda120ad0,0x68cbb175, + 0xb92636ec,0x19497c61 } }, + /* 7 */ + { { 0x417659a8,0x6920b0c6,0x92cb28ff,0xc77ab9c7,0xb687797f,0x55b67180, + 0xe7759363,0x4caf58c1,0x5561b186,0x5155bdb6,0x780f4946,0x2e64e355, + 0x229a8b20,0xeb0ac9b7,0x2571bd60,0x88594d78,0xe3fa78f9,0x5dcc0939, + 0x2ac2d379,0x7b8b4830,0xb90f1444,0x505fbf60,0x3ce4b3c1,0xac610e81, + 0xd59b5c18,0x39a4f27a,0x7cea0222,0x5fa33973,0x8dff1c7b,0xe578730b, + 0x517bf7a6,0x96b91b8b }, + { 0x9aac087c,0xc1a991f4,0x6cfdb28d,0xce62f74e,0x5f7600d6,0x08d6ff9a, + 0xf917f9c9,0xd781cd04,0x3de52dbf,0x7796f5f6,0x2ed72180,0xe7db64e0, + 0x6fa4137d,0x0f0876f6,0x3ca1f716,0x3271ee64,0x7c4ab8a3,0xcb9b2058, + 0x39481047,0xcba17107,0x598c5c37,0xdf9a190d,0x6f20e125,0x0cb6e72a, + 0xf4f2902d,0xa3142204,0x7ce2dcfb,0x42d28cb9,0xa3d3c351,0xdf261b8a, + 0xcffc249d,0x73f3d315 } }, + /* 8 */ + { { 0xe6fd3673,0x5d86855b,0x9d214b7b,0x309b70af,0xdcc46cd3,0x8d332f90, + 0x595510de,0xe553c015,0x38c1251c,0x5746a096,0x85cc1bc9,0xcd7cea5b, + 0x002eba8f,0x4ffa1468,0x22fcd77c,0x10a3cb70,0xc4ea05e3,0xb6999dfb, + 0x4efa756e,0x3375a0d0,0xdced5fd8,0x4d90279e,0x251fd56e,0x48192403, + 0x82a4c5f1,0xe87633a4,0x1b34105b,0x3170d130,0x7247e578,0x93998b0f, + 0x436ba1fa,0x88934f64 }, + { 0x4713eabc,0xf09f43b0,0xaccdc517,0x4ca7dd91,0xef13ca7c,0x27daa63b, + 0x2588184b,0x8b2e5a7a,0xd95dc269,0x0a8cb612,0xe1f2f14c,0x346975a2, + 0xe172935c,0x1f29b8ed,0xd40bc1e3,0xc3cbfd6e,0x132623da,0xd3f46b3f, + 0xfb0b7681,0xc115be6d,0x56da4344,0x5e31c345,0xa8e43d98,0xa7c63f18, + 0x4bddb4ea,0x55cb2083,0x4a54f58c,0xb16a0c38,0x46fd69d9,0x74eacca2, + 0x153548e1,0x0d1898bb } }, + /* 9 */ + { { 0xe35ef043,0x4ea73461,0x3496b564,0x107b67d9,0xd0f83a3c,0xd62c173b, + 0x51d29c35,0xfad4b038,0x71b1c1a4,0x3f42882a,0x54b43b9e,0x5d2bcf66, + 0x2abdf543,0xc77b15aa,0xdabe3dc1,0x5cb38a80,0xa481673b,0x15fda0ae, + 0xe7b90ebe,0x86996b4d,0x2bc8f3d8,0x84f87e25,0x37c4e424,0xaded03d6, + 0xd7a7afd8,0xe5ede666,0xa1ccb93a,0x80dd95a2,0x46fba391,0xa55cfd25, + 0x46f82e60,0x2bdab1dc }, + { 0xfa6fed61,0x7a4de22b,0xcc8dd94e,0xca458aa5,0x071222f5,0x3e372df1, + 0xe5aff377,0x06a4b44f,0x4a738e6d,0xbc2d0ba7,0x5f31f136,0x1a470e1d, + 0xe102a911,0x77ff933a,0x310c7885,0x8b380a50,0x783fc5ac,0x9f3c0228, + 0x44725d06,0xec668925,0x5ac84221,0x878f0e16,0xcfda6e8a,0x9a3af1af, + 0x78cd2aba,0x0183ed37,0x826d0eae,0x32cdbd60,0xcbee6415,0xb3234661, + 0xb9c10120,0x353eb892 } }, + /* 10 */ + { { 0x10b5521e,0xc8fdcad6,0x52e702f0,0x1a11b440,0x8ffda49c,0x6302680d, + 0xcbf36bad,0xcdb9654a,0x4c10a2d7,0x7b58ce11,0xe630e7e0,0x1e5d1f7d, + 0x6760a813,0x8cbe3d7d,0x6480d77f,0xeb35866b,0x7f036219,0x58728cf3, + 0x42a8a757,0xdd5865ed,0x906a2870,0x283f1f1d,0xa51f906b,0x79e23fa4, + 0x543b20a8,0xf2ac6e83,0xb81e7754,0x4f0b6379,0x840016ee,0x57fbc0d4, + 0xe621b67d,0x8da20771 }, + { 0xecce65ec,0x3c855004,0xb748185e,0x76d10d1f,0x78797ad2,0x64be7bca, + 0x77e54aad,0x43444db0,0xbe0df0ff,0x17b6b0c9,0x055086a4,0x8fc4256c, + 0xfd74d5a3,0xf952c43b,0x01c4edb8,0x501e005a,0x4a57e328,0xd5172dfc, + 0x535d6ee3,0xdb40ce4e,0x0c650918,0xbaef1e5c,0x857561fc,0xe85145e7, + 0x34a224c6,0xe468536a,0x0ec0e0a2,0x69a8e227,0x242b03fc,0xb3f52247, + 0xc3bebd5f,0x862f55e2 } }, + /* 11 */ + { { 0x226049fe,0x2d6a390f,0xdcbbc9fb,0xcc92a578,0x97634fb7,0xa52feca4, + 0x3dea5893,0x2b340cb6,0x2a49e916,0xa39f338a,0x949e41f3,0x26b2df3d, + 0x065a7e40,0xc71c7cdb,0x468281a2,0x4a9b84a0,0x731eeeca,0x63eeb503, + 0x76cbb725,0xe6d09134,0xb94a678c,0x0cf979a9,0x808fd9f1,0xb44d8c3b, + 0xe0afc5b9,0xe60da613,0x3ea5be69,0x52dce7de,0xdc1ee74f,0x3a5d6864, + 0x3bc80790,0x71ab2891 }, + { 0x3b5b60ad,0xcf618fc4,0x4a0c3184,0x0afb5e30,0xbc403302,0xd22381cc, + 0xdb1c0c66,0x33cf8953,0xa6112a8d,0x9c994e4d,0xd1967a86,0xd7aae2c3, + 0x5b7acd29,0xc28d5493,0x6c9a57fb,0x8075bd13,0x9c8427f9,0xc9c0373e, + 0x193225f5,0x2cbca18d,0x442c018c,0x73777d13,0xfbb3a727,0xebe5ed47, + 0x1962dc18,0x70437d49,0x2dc08806,0xf39c1e09,0x15fff35c,0x03e9c6f7, + 0x5e360a65,0x8d087bb6 } }, + /* 12 */ + { { 0x3fdc1844,0xbe212302,0x105eac56,0x6eca27ef,0xf168a348,0x2183a606, + 0xe1d7a4cb,0x295f807d,0x7ef5d43e,0x7246a632,0xc77025c7,0xae143205, + 0xf3484e3e,0x4bdfc7ca,0xdf52c075,0xec939895,0xd7a9cac0,0x82e655f6, + 0x8baeddb0,0x985dfe20,0x527de731,0x79c817e4,0x313de1ea,0x30ce0fbc, + 0xcc4f6cbb,0x9df95b89,0xf5bb20cd,0xf2aedf1e,0x1a8cfb01,0xfc1e0a89, + 0x63edb7ec,0x225ed34a }, + { 0xbabb1a85,0x3e13154d,0x1e6a565a,0xd3d8dae7,0xab4b100f,0xd3217d56, + 0xebc78e1a,0xd44d934e,0x48e73d37,0x0215321b,0x201e43cb,0xbbc90bfa, + 0x27500905,0x3c23f1d0,0xc86691a1,0x2a2e5000,0x6065841c,0x08b2bad2, + 0x30026b60,0x15d41caf,0x5276ce61,0x1712c2f4,0x15932ffb,0x01c4c3e7, + 0x6a74caf2,0x7894e13d,0x0c0537a4,0x02d6f5df,0xc2b1c97e,0xa8fb7602, + 0xd0887c7b,0x612b60e5 } }, + /* 13 */ + { { 0xba245d6b,0xefd495cf,0xa2ce3ff6,0x5cf0cbb7,0xdff5feee,0x24da2ac0, + 0xcf28c6a3,0x90c914f8,0x4308a56b,0x72fdb50d,0x13d72034,0x03dbf779, + 0x822ac9e9,0xcfa5ec91,0x3aea3e81,0x0dde73c8,0x66289139,0x545ba962, + 0xca6acbd3,0xa52f648b,0x98a0683a,0xff6f276e,0xa378ed52,0x2536d3ac, + 0x885ac1d9,0x353c2c54,0x00bc84a7,0xcaff52da,0x37684167,0x3971f81c, + 0xd2d7986e,0x0f7334e1 }, + { 0x6596067e,0xafbb5c83,0x38c19806,0x33e54e19,0x39cb0dcc,0x8285d967, + 0x424035f9,0x2b53f43d,0xdfef9095,0x38c531f8,0xdb0f571a,0x90fbe8e4, + 0xa39ca787,0x9a0c1ed2,0x606f2620,0x2fecc1d6,0x72b7cb4a,0x9dc890b1, + 0xccbb7868,0xc33ca6fb,0xfe73ee49,0xd1b11082,0xfcb66c48,0x590b7d17, + 0x86e14573,0x9356b0a6,0x053ead85,0x75d682c4,0xc54d30fb,0xb2ae55fa, + 0xf8aee949,0x67636a72 } }, + /* 14 */ + { { 0xb91d6bea,0x638063bc,0x923ecb96,0xae263a2e,0xc627aca6,0x9d7b0992, + 0x77af9e7e,0xc6ed001a,0x24aafebb,0x9214accf,0x78055a90,0xa3564b96, + 0xe027499d,0x00999b1c,0xe46a06a5,0xe413a4e1,0x2e51efe7,0xa05d13f6, + 0x9ba843be,0x35e87d34,0x3183159e,0x0a633825,0x54601923,0x6023e8ba, + 0xb7fd1cf2,0x9b107721,0xfdf2fd53,0x46b5542b,0x1c18af38,0xb314f4f8, + 0x60ac8965,0x086f9876 }, + { 0x8cbb9850,0x76701954,0xa20d2c8c,0x6210b730,0x5335670c,0x4084d057, + 0x0324baea,0x3ecdc595,0xc76ee9b4,0x607fc5f2,0x440ffa64,0xf393d00f, + 0x2dc1463c,0xe0111796,0x9c7725e7,0xf00b8251,0x5bd1d186,0x35e60736, + 0x2cf72aac,0xf3d8554c,0xefa3497d,0xb4dd0fde,0xf646ad11,0xd712268c, + 0x9f7b8ead,0x07c20afb,0xfc06dfe5,0x630969d4,0x7245549a,0x76b7df1c, + 0xe61ae810,0x681f9403 } }, + /* 15 */ + { { 0xc9a0623b,0x7cad5163,0x67fab8d4,0xdbf82957,0x81af7c7c,0x2ccab0ec, + 0xe966d5c2,0x469e38c8,0xf0d4e41c,0x34430d52,0xa52b359c,0x426075a2, + 0x33bd0127,0x242dd3e3,0x9fed2341,0xcda3f635,0xd7d52ffa,0x4df33730, + 0x7640c3ef,0x5fff56f0,0x1bbde57c,0x4783c21c,0xeb8bb336,0xd8784a2a, + 0xead08405,0x1ec7c533,0xf9b62bd4,0x4b7f1423,0x7075d4af,0x5543145c, + 0xba60590a,0x0c9de94a }, + { 0x95d5682b,0x8ed72735,0x2ec276ed,0x711c4283,0x8b36a0d2,0xd1f4aed5, + 0x8498a88f,0x62ab40c4,0x4480f451,0x58c8fc62,0xb79cffe2,0x8bc8ca4b, + 0x701a359d,0x90ab583c,0x3fd5d15d,0xaee31a73,0xc912333c,0x02a5597b, + 0xb6c3e3c2,0x1019cae4,0x29938088,0xe513042c,0xf47c8199,0x0e00283d, + 0xf2a00e92,0x90d68e58,0xa775ae3b,0x69e2df41,0x871c30b2,0xb8d2eca5, + 0xbb1de396,0x733dca0e } }, + /* 16 */ + { { 0x4b59213a,0xf5b495d0,0x8d70200e,0xca672039,0x2b6771c1,0x4bcb09a6, + 0x2b9eb0cb,0x26adeed4,0x8cdba212,0xeb544754,0xf08890d1,0x0e1abfcd, + 0x698e46b4,0x52509963,0x82e9c138,0xe1bff0b0,0x51099a71,0xa189e4cd, + 0xc9b91cc7,0x2360c9bc,0x137ec4be,0x9bd4d7dc,0xd1519f6e,0xd0356521, + 0xcf832503,0xbf5f6d78,0x8deea2b4,0xe4301031,0xef4c319c,0xc3132494, + 0x0f1fa7d7,0x2ab3bd47 }, + { 0x922c9fbb,0x5753b680,0x0f16c6d1,0x869e7dc8,0xbac16efc,0x83445135, + 0x846d1d9b,0x4326a3b4,0xb2d62c21,0xb517fee3,0x0b292ad5,0x6905afa2, + 0x2cadac13,0x2a57131a,0xebdbca8d,0xcd904d8f,0x3f365fb2,0xdfeda86f, + 0xdc7eaa1c,0x7097b208,0xa45e77c0,0x89a35a84,0xcf5d118e,0x417a062c, + 0x1f6e99e8,0x3c0c04a8,0xba7a087d,0xc44704b0,0x3ea22ad2,0x6f8a27d1, + 0x4c27d229,0x93a4b416 } }, + /* 17 */ + { { 0x1f1efb7a,0xd4271bc1,0x33fccc0d,0xae4e68e6,0xb11f50a8,0x9d9bc8f1, + 0xaf076089,0x5430398f,0x443d0e03,0x45e242fb,0xf6e3d4c1,0x73ec2519, + 0xba9bad09,0xab70f790,0xf9add10f,0xde612ad5,0x14e942b4,0xb837e54e, + 0xddb8b68a,0x175a56d3,0x1ac2a408,0xe85b233c,0xf0c80f94,0xf8ff6c30, + 0x898db4f9,0x4b7f3fb7,0x45a7dcdd,0xa2c6044f,0xfe3d3895,0xf3abb2f6, + 0x32ee7763,0x342ce0d7 }, + { 0xcf491b1f,0xeb261394,0x1909e395,0xdcaaeed7,0x9fe4dbea,0xdcc4055a, + 0x493d604d,0x17a6611d,0x1ce5ebef,0xba445a3a,0xe3989cb5,0xe82e2858, + 0x83f58406,0xb96f4282,0xa156cf55,0x99877b99,0x4e166a0e,0xaf906a66, + 0xb2976d13,0xcea1d353,0x36c61a01,0xefc16f27,0xb0f55d86,0xdb04c433, + 0x8eb34c01,0x3cb4b269,0x2ae60280,0x38d07f78,0x43be3ec5,0x43ac3bcb, + 0xe156fd20,0x455f4af3 } }, + /* 18 */ + { { 0x754ec21c,0xc057f262,0xe3a1ba38,0x3eacd4c9,0x116c1fe9,0x3a0210d1, + 0xeacc8ab6,0xe4ea4e94,0xea6f32ca,0x31c00c9a,0x86b975ce,0x5cb6239d, + 0xa14ea1e9,0x654d5d8c,0x5067fc8b,0x230d31f4,0x6355fecb,0x48bb90cb, + 0xdc172e8e,0x78f81ece,0xcb006737,0x288380a8,0xe162d012,0x19b02e01, + 0xc5af145c,0x0e087a06,0xb72dc354,0xf04dc8b7,0x8de3c066,0xf70ef214, + 0x13009fb7,0x4f148243 }, + { 0x6e2055e2,0x5e004fce,0x86c32067,0x89e247ea,0x5f9daaa2,0x4ebcbd95, + 0xceb7f63b,0xd15f212f,0x863784a0,0x5ecc5c1f,0x75760251,0x53b3800b, + 0x8a6a2954,0xeb9301c3,0xa13cdd19,0x0f16ba18,0x887c2d24,0x8313d251, + 0x9a9413f6,0xf9923585,0xfe3fd7c5,0x423405e6,0x16e0ee05,0x678aeb34, + 0x3fadaab0,0x1f3be7bb,0x82884471,0x7901fa2c,0x4d662ff6,0xc950db30, + 0x3c01170b,0x74d5d2d4 } }, + /* 19 */ + { { 0x2b5bfe11,0xa3002dc0,0x52d321e7,0x0733410d,0x9679ba89,0x15920f65, + 0x685b236e,0x0e248c14,0x346f6040,0x8cfab594,0x40c717f0,0x9f57afb7, + 0x66044576,0x0dbab28c,0x9cdc3247,0x0fa09968,0xc230ed05,0x41e02ae2, + 0xe45bef74,0x0d961554,0xce4d7b6f,0x9688a982,0x5e62d22e,0xfadefac7, + 0xbd2cba28,0xaf1512a6,0xbe7c749f,0x78868e62,0xae9f5a6b,0x88048d81, + 0xc5857a29,0x6b1a5442 }, + { 0x43242066,0x9f5ab9ad,0x2ccca2ae,0x0afef1b5,0x988edc4e,0xb1b43ec7, + 0x0341b0d5,0x0d0c00f1,0xb50aab37,0x4d68b8f7,0xf3a64a99,0x9a8e4e6f, + 0x7f1a684e,0x198338fb,0x351a0f5c,0x8bc0e748,0xdac44515,0x2cacf2cd, + 0x5e9ff76b,0xc14d3999,0x16393055,0x54a01b3f,0x888d8376,0x6ac3eea5, + 0x723277b1,0xb84d9a9a,0xe11dbbbf,0x99132691,0xabb67178,0x597717ae, + 0x8bb14ac8,0x4c213526 } }, + /* 20 */ + { { 0x95532833,0x2e6fe0a6,0xd626d067,0xabca228e,0x649e73bd,0x22aef3d9, + 0xf03c4c0c,0x2083a87a,0x35169b45,0xe954e75d,0x74506a89,0x577509ee, + 0x2aeacf90,0x49cb276e,0xfa409f91,0x08275d77,0xf0bbd6b9,0x61eb6f3d, + 0xe4132704,0x948202cb,0xb1c498b1,0x35f3fc21,0x361fee59,0x76c68ba8, + 0x50e051f3,0xa18cbbd9,0x318e7042,0x2384a879,0x80dd1e8b,0x292abead, + 0x5c37c334,0x65713c29 }, + { 0xceb77b9a,0xdccca8e9,0x23b69469,0x2f97e727,0xa01d6b28,0xc76abee6, + 0x5abecdfe,0x3925203d,0x29290d70,0x89448082,0xb0314438,0xf9931424, + 0x7cd447c3,0x04209df1,0xc855c827,0x7c6f2059,0x56c0e069,0xd97d7862, + 0x412d94c4,0x5a9db6fe,0x994c41dd,0x19a64591,0xc89e21a3,0x12348aa1, + 0xc6a03f0e,0xd6904b50,0xa616feac,0x55c15156,0x7cc7693b,0x4e36d1b5, + 0x3bae3c38,0x6b0e996c } }, + /* 21 */ + { { 0xcceced00,0x32789fab,0xe5b7aa66,0x3237e71a,0x2ddebcdf,0x87b2e269, + 0xb61dad8f,0xb7245120,0xd35f803c,0xe11e5e48,0x98e50f0d,0xfb4df5d7, + 0xbcd2ab92,0x60ee68b4,0x1ce3363d,0x98ab2f5c,0x7cd42647,0x15ba39da, + 0x83f4fb3f,0x1a6572eb,0xe56f08db,0x0f77de88,0x172562c2,0x1743761e, + 0x8a58f0f4,0xbe349ff8,0x84d1d6e2,0xe04da71b,0x9e9ff3b4,0x368f0342, + 0x678223f8,0x4022a205 }, + { 0x83847375,0x527bbd05,0x3f451af0,0x3ae56b62,0x4b2c7f18,0x6198f24d, + 0x4525b98d,0xee323f5b,0x0e0884b5,0xa9d8d39a,0xfb12c776,0xd005d7f6, + 0x708bc154,0xd71c483e,0x742541bc,0x8ca6fd28,0xf8397ddb,0x0af3dccd, + 0x3eccf243,0xb80d3125,0x58d81b8d,0xc743a108,0x71391f68,0x3f48eb21, + 0x33bb657f,0x493aff88,0x07e47e31,0x1d15ed66,0xe08279f6,0x10159b11, + 0x24a6a956,0x312179cb } }, + /* 22 */ + { { 0x07615ac2,0xa94cc3ca,0x121ad581,0x85865e64,0xa7986b79,0xae47616f, + 0x9d5e0f1d,0x395a40eb,0x3d9457ea,0xa9143264,0xfa2865d9,0x8de6d6a3, + 0x1014ae8c,0x0771db96,0x976a87cb,0x77a7cce6,0x143a0f60,0xa7de42e1, + 0xd993d934,0xe203cc09,0x98ec4c3d,0x92018693,0x3a25df4b,0xd77546d8, + 0x62b02d6b,0x0ad9eb47,0xd05a7189,0xfaaaf208,0x431221bb,0x5238181f, + 0x733511ea,0x417d6c78 }, + { 0x0e91e9a8,0x3cbd81b7,0xc370d6b3,0x73340418,0x8eaa2373,0x825db10a, + 0x6c7d6756,0x8f2b09e4,0x94c33ded,0xe288ee9b,0x1695e3fb,0xcd8426bb, + 0xdce9e888,0xa6176c86,0x6165e362,0x3f4c8922,0x6063fb09,0x514e411f, + 0xc8f9e04c,0x6907ac20,0xdfd2ad61,0xcef7469c,0x8452199a,0xba30bae4, + 0x12ac3462,0x30681293,0xc92d482d,0x011be873,0xe8330995,0xff4cbf89, + 0xd1470a0a,0x02189d52 } }, + /* 23 */ + { { 0x92599c69,0x73e419dd,0x7fec32ca,0x5b94221b,0x09bbfbfd,0xb2bf9bd2, + 0x63ed895b,0x61ea97a4,0x3f486f79,0x6609146b,0xfd141a39,0xbd1c7a05, + 0x83d64135,0xc79ec8cf,0x9883507b,0x7f8fd42f,0x17b3d027,0xafcb53b7, + 0x67ca5a21,0x86658dcd,0xcd149786,0xa6a6c0ac,0x34b95067,0x16f3d70e, + 0xdf44958c,0x371208e3,0xec280212,0xd2dd64e6,0x30782c71,0x33b2c4ab, + 0x521176fa,0x7bbf8abd }, + { 0xa78b981a,0xbe9e4aaf,0x304ec828,0x788b4e36,0x3959dea3,0x0c45cf39, + 0x240b39c7,0x70a9bdd3,0x28383b7d,0x499cd7dd,0x307a1026,0x30690b2e, + 0xee92f1b3,0x2262d598,0xb4725a48,0xc62d77de,0x7bc3aa0e,0xa16f25bc, + 0xd15ef7fa,0x62dd8b65,0x0b96d68f,0xd979221d,0xa00f1906,0xb92885c3, + 0xeb74c740,0xfa476b9b,0xc7576222,0x217ddbb5,0x5788504f,0xc2782c30, + 0xf812716b,0x860d096c } }, + /* 24 */ + { { 0x4d79bbf9,0xfebc337d,0x69f74f80,0x5d53eab8,0x33104d53,0xff36a095, + 0x196f8b97,0x2ab820da,0x75ce6909,0x961d3d1f,0x04683754,0xb197ec04, + 0x93a6cb9b,0xa68ce1bf,0xc5f021a3,0x503456ff,0x8940ffdb,0xb50a2db1, + 0xef004209,0x77c50f8f,0x04965875,0xd635d177,0x8bb8770a,0x725766d9, + 0xa078e53e,0x8e19b028,0xf9fc8378,0x364d4cca,0xf0dd39a0,0x1a3df411, + 0x03adf920,0x7e80e442 }, + { 0x539a1ddf,0x4b5f8a57,0xee486562,0xd248e7ae,0x816021e1,0x1c7b491d, + 0xfd36d2c4,0x2e7b871b,0x0aec00d9,0xda38b504,0x6193f1b3,0xf2827612, + 0xfb1f78d6,0x69c3fe86,0xe827ac33,0x56c8b786,0x3487c8f7,0x1687f6c7, + 0x19dee5bc,0xab8f2217,0xff399418,0x04e8473f,0xa9027c80,0xf384c014, + 0xaa1d2e28,0x9967be9a,0xe065eef1,0x869686d3,0xc7bd837c,0x737c6b08, + 0x9e8bd863,0x5dcab5d1 } }, + /* 25 */ + { { 0x9a7d772b,0x0784283a,0xe540959b,0x6b49e525,0x86414ab5,0x546bb008, + 0x9d74b2a9,0xd4448162,0x203b0b1b,0x267890ad,0xc8d3f86b,0x1e7a82bc, + 0xd85a83c7,0x1352bfb5,0xfad07ccf,0xf29f16e3,0x41e0c43f,0xc02a63b8, + 0x6b379fef,0x904f22c5,0xb1244f26,0x19d8a653,0x3a28bdea,0x6635b6df, + 0xf6d455ce,0x18b68851,0x9cff3735,0x74ac2818,0x8b2cbdab,0xad40f9df, + 0xadc9d498,0x08cc2d9e }, + { 0xc170c84b,0x2e6a6866,0x5a49a484,0xbb989e8b,0xd04c8992,0x7b0e00e0, + 0x61b3a423,0x55ad3478,0xb0d01899,0x3c952450,0xe3100cb3,0xe3922155, + 0xf03276d0,0x19265b6e,0x76d42b53,0x0fe8595a,0xfc6353b6,0x0a96dee0, + 0x246f893e,0x761e0dc8,0xf0a74cba,0x4ec902be,0x3fdfad9b,0x61008684, + 0x4fdb6975,0x5d6a60e4,0x7ef7590a,0x3f53aac8,0x12870a37,0xd29e6be0, + 0x55aa55b0,0x991fadc1 } }, + /* 26 */ + { { 0xb4844ffe,0x82bc4b0f,0x60f8b871,0x73922714,0x4ce3f1f3,0x8ac000e2, + 0x163519ec,0xf0d548b4,0x88288b5f,0x7aaf842b,0x2bdc9a70,0x9e8b0c4c, + 0x4ba5fd67,0xa06d5152,0xf93cdec3,0xd0b1afa0,0xdf89f8f0,0x280955ba, + 0xeea32c92,0x86cbe92d,0x3fe05be4,0x0cae3f99,0xfa6919aa,0xf2607095, + 0x6e0f1b8b,0x0f54741e,0x30ecf988,0x2aed1f74,0x734991d7,0x9296f76b, + 0x259f0fe9,0x66cf8d28 }, + { 0x226f5868,0x9b01905b,0x16909e9e,0xc102e88c,0x4a37eb54,0x2bd08916, + 0xc9816323,0xf72253e8,0x86bac53c,0x37f84e9d,0xafeaaaf7,0x2e352454, + 0x2ca0046e,0x67c86f77,0x6663372e,0x86bce50e,0xb6950a04,0xf6a3a960, + 0xfc1aba93,0x61f994d7,0xc1326e6e,0x1957c12b,0x2e56b005,0x9b658fe4, + 0x8592740c,0x9cd297fc,0x177f26a5,0x7654ce9b,0xa79d2ebb,0xaaa699db, + 0x0ecb6448,0x5fca0c5a } }, + /* 27 */ + { { 0x569a6663,0xe26e25f3,0xe6aa4ca7,0x09597ee7,0x8d18b80c,0x25a4cda6, + 0x22926730,0x450602b5,0x07387209,0x9af5f650,0x26733a53,0xfeeedb34, + 0x86572951,0x0f5ce768,0x8398ae9a,0x872a360b,0x2b30f6c3,0x60347a80, + 0x1a162158,0xd2113b23,0xee6c6dec,0x6fd9cf92,0x5cbcf9e6,0x85f0a5a8, + 0x2ba3fe84,0xd7a5a6e4,0x51ecd727,0xaafe6720,0xa2081a10,0xe09c6bb2, + 0xb973b0b4,0x657acbf0 }, + { 0xc274c8d4,0x3130466f,0x30a994d1,0x42765176,0x7079435f,0x217258ca, + 0xeb897a06,0x44850406,0x561ee130,0xf38dfeee,0xaa1778bb,0x11f4facf, + 0xb9abb9e9,0x765c6617,0xd8f10932,0xb135499b,0xa73b9159,0xc0eb6337, + 0x6f7e8b6a,0xf2c1ccf1,0x187def53,0x5b32c03a,0x830b9c62,0x89ad1d49, + 0x2f10e538,0x1735eae3,0x9d5f55bc,0xb1cbd9c2,0xe539db0d,0x42428c47, + 0xc852b3bb,0x3d2da412 } }, + /* 28 */ + { { 0x871f2865,0x97702b6e,0x142920d6,0x56cb639f,0x45b58611,0x328522a0, + 0xf3b13812,0xf3943ad1,0x712206e8,0xe6c2200a,0xa34d59ea,0xc2890e5a, + 0xf6b7f759,0xab52fd40,0x180bf567,0xf522c8de,0xaccee396,0x181e97b2, + 0xc4ea5cbb,0xe0375819,0xab51d3ef,0x0d9985e8,0xbcb50fd8,0xe26c96ca, + 0x97e1c80d,0xfb9d6b13,0xf796357d,0x582b1814,0x07f4c7fb,0x89a78221, + 0xc0357e61,0x02aeef2d }, + { 0x2c7ec9be,0x2ba7926f,0x7258b201,0x292f307e,0xc6fa6b4a,0x74e62a10, + 0xe2bcc5ab,0x80c08549,0x7bb8c073,0xb4160db8,0x329f194d,0xd5ef0529, + 0x6dda4a9c,0x0eb8da14,0x15ea23d1,0x0b5d43d2,0xfc34bfae,0x6cebef02, + 0x848757a7,0xacd364d0,0x2d34cca3,0xc1401368,0x1d2d95e2,0x09ca6742, + 0x786eaa28,0xc3fd1d6e,0xa2965fec,0x9eb1136d,0xc0779203,0x48871baa, + 0x4b15aeb0,0x6b446c01 } }, + /* 29 */ + { { 0x25e8fe80,0xc819eb2e,0x98238a17,0x2b5f7906,0x81e41849,0xd6f1e996, + 0x98ea6d45,0x58ad8ad6,0xbfd02e40,0x5bae5ad4,0xa812416d,0x016dc327, + 0xa3347ca1,0x8b31a985,0x82a65391,0x0b4da610,0xb48c35fb,0x1cb91b2d, + 0xd2aaf8c4,0x9e96817c,0xcdfdcdc0,0x1a630483,0x12b69254,0x70559361, + 0xf8a2a097,0x5fdcd712,0x35cc5281,0x59ab623a,0x932b6095,0x30c8ebe0, + 0xb08e052f,0x8613424b }, + { 0xb2231d8a,0x28902063,0xd9a61667,0xb0f62329,0x071a9f27,0xaafa0fe7, + 0x603f047e,0x6bcd8960,0xfd92a1c3,0x118cca76,0x71d483b6,0x3414e62b, + 0xba705262,0xa123ccdd,0xfd9b5c5a,0x1a576437,0x4c8d0fa3,0xa5301bc2, + 0x102427cd,0x96f0ad44,0xd3aa6c02,0x0e6fb5e0,0x072a3996,0xcd8c4880, + 0x840d3fad,0x4dafca12,0xde91d541,0x29f4ca3d,0x8441734d,0x0037c598, + 0x9ccfe57c,0x86333a99 } }, + /* 30 */ + { { 0xecf53b40,0xd213a751,0x2f78a542,0xcff2c6f2,0xf13ae56d,0x0f59f0e2, + 0x0e61748e,0x91f8ccbf,0xd72c4145,0x0aadecb9,0x4c9cdcb7,0x6b2ed852, + 0x1eaffc70,0x8e00b72c,0xaa728102,0x89b24285,0xb679cafa,0xaa7ea7e0, + 0x4f0a6f6f,0x5d2b8c26,0x0e804397,0x7ed7b173,0xc8573049,0x5a93eb45, + 0x0986e93e,0xc92bf5d4,0x6a20c0af,0x526b5a9c,0xb99dc3af,0x0adf47c9, + 0xba202cc9,0x12b25fe2 }, + { 0x33eea395,0x09b8d78a,0xf633fc5c,0xc7a93618,0x270eceef,0x7e821629, + 0xc628ed0c,0x524779b8,0xa1d68939,0x91db5ca1,0x586edc90,0x8626e18e, + 0xfeb3f3bf,0xfe023e8b,0x0250171c,0x6279fde1,0x55e172de,0xe52ec7dc, + 0xc6d4ca45,0x445e8695,0xbdbc10f1,0x42de3878,0x6fc3835e,0x2b114de8, + 0x7e10b652,0x9faba456,0x390e78fe,0x4111d82a,0xaedf0aca,0x576b61c2, + 0x74accb74,0x216279a9 } }, + /* 31 */ + { { 0x4047f747,0xc14cdabf,0xc1315a1e,0x03ca233d,0x40e5d0a7,0x59e7cbd3, + 0xbb413869,0x1fd0c4e9,0x0f01fbd8,0x189d08b1,0xa76b823d,0x50449c42, + 0x398b00a1,0x81c224a1,0x8e8179e4,0x08084e4f,0x698e41e9,0xfd8af994, + 0x5610bf2e,0x1e30e37c,0xa7d2790f,0x4e6a043f,0xb3195388,0x9d96e60c, + 0x03799dfd,0xe75f986d,0xf8ff902f,0x3b4a8f11,0x7588416e,0xfa945378, + 0x9827535e,0x20683e3f }, + { 0xd0378878,0xcb582e26,0xa7945787,0x9e214c23,0x8f6688b3,0x13d000bf, + 0x40515270,0x7548d4f5,0x40111f5d,0x7113c15d,0xa8bff902,0x3bf5a526, + 0x9b4945cc,0xbda6b010,0xbc2f3a05,0x83dcc74e,0x43efdfa1,0x2aef6284, + 0x565c5bf4,0xd2e60ee9,0x592f243a,0x4f0fa10d,0x1bc3bf51,0x6ae58b32, + 0x60576a74,0x813b0868,0x4d73081a,0x0bc023f8,0x32dcee59,0x9fd03aa0, + 0x27d6c795,0x5e416bf5 } }, + /* 32 */ + { { 0x026cc23c,0x24313760,0xb5b29058,0xf819aaee,0xc5d2ee17,0xa92272f8, + 0xee5cc402,0x8048e7cb,0x77def07d,0xdbc7d6ee,0xf6af821e,0x61d69244, + 0x996cbb89,0x5f7966ed,0x96a155a4,0xf81b17ea,0x03f3ed56,0xb2d9ef70, + 0xe882a5b2,0x5e6e5906,0xae947180,0x86fa1072,0x658c76f4,0x34d9fc51, + 0xcb035aa0,0x9f603dc0,0x75be6481,0xb7b39feb,0xcf04a9ef,0xca87554a, + 0x87b4fde3,0x4ff682ec }, + { 0xd0a10ad5,0x3125627f,0x968e6f45,0x7fd45c72,0x806a1163,0x2981bd6b, + 0xde5033e3,0xb92de1cd,0xbf4f8988,0x3b44b45e,0xdae7e1dc,0xca1b9896, + 0x0778d878,0x52166e5a,0xa5116847,0x82d472be,0xf2895445,0xfbdd382a, + 0x5d6ec4c9,0x22ed1602,0xb6552b02,0x3614eb1c,0xa1e6210f,0x63c5df73, + 0x021a74a7,0xe9160285,0xc65cbd4d,0xa44ca400,0x0f15e299,0x48cb187e, + 0x3402507c,0x51eb818e } }, + /* 33 */ + { { 0xb92100ab,0x1fc1d178,0x9605b839,0xdf2e3d60,0xb71e59d0,0x12a7c255, + 0x14fcbe04,0x3f8b6675,0x59fd06af,0x0e8a3935,0x12020d07,0x56326502, + 0x528e7be5,0x6696fcd1,0x0c7b7654,0x6588514b,0x5912a5b5,0x0cd80f8c, + 0xf324cb7f,0x8bafef04,0xc6da3d75,0x6b53eecf,0x31d1df2f,0xedef48d8, + 0x73812b6d,0xf336b965,0xee626031,0xc82eae4a,0xd244f09b,0x300abd32, + 0x31d9647f,0x8b0af955 }, + { 0x2e603544,0xb770180a,0x221acd9e,0x2b573ac3,0x62407032,0x3a17f665, + 0xb89abc3d,0xad3e74ad,0xd793225a,0x8a3d2e3a,0xef02564b,0x457bba04, + 0xfc2dd2b5,0x8875652f,0xe67143e8,0xd2905d15,0x02e48d70,0x6d884b42, + 0xc7636a57,0x06f99219,0x35e378df,0xa8dc3421,0x10c64a02,0x95c1d73d, + 0xcc157a66,0xcd6a4ece,0x8e24a354,0xbadcc1c8,0x9839329d,0x8024f1b2, + 0x4da48ad0,0x5363e549 } }, + /* 34 */ + { { 0xe23fc641,0x1f5523b7,0x86667063,0xfe54e72f,0x8e009d2f,0x294a15f5, + 0x8c57f5e1,0xf203997f,0xb16d64dc,0xa229724c,0x4baa2ffb,0x697be4fd, + 0x0a6e8ed6,0x3f507e46,0x78508536,0x0afe3a5d,0x95408208,0xeeef6cdd, + 0xf2c4237c,0x701fd889,0x5c385253,0x496d883a,0x72a212f1,0xe25c67ed, + 0x1ff78fcd,0x4b416783,0xc16f4146,0xe9967004,0xc45b0697,0xfa45c3a1, + 0x3fbd30c3,0x63334018 }, + { 0xa2fbbbce,0x39c9a0cc,0xaa0cb744,0x876f6e5c,0x3438ece3,0x9ce6010e, + 0x13802d82,0x0aad148e,0x9cd45a1b,0x9c3e5c60,0x7bcfc1e0,0x875cb859, + 0xd8584dd0,0xb19ff790,0xd81c2a2b,0x2598b81e,0x02be07e3,0x118bdf2f, + 0xb9765ce9,0x074fc8ee,0xb24f95ae,0x125e9d88,0x0c98f09d,0x3bb12cdc, + 0xa0b74b27,0x4a6aee07,0xc08077ce,0x4723d2f9,0xbea8026f,0x959447d6, + 0x16280b73,0x93a7075c } }, + /* 35 */ + { { 0x715b27f9,0x26bbefe2,0x2a280923,0xa935a5e2,0xfd58a26a,0x5ddf23af, + 0x7c138694,0x54c83e16,0x892a2153,0x44799bc9,0x9b8d09f5,0x4e6e4710, + 0xd588ea68,0xc63af616,0x883ab1b6,0x5e896706,0x3d209336,0x3c1393a0, + 0x92c23dda,0xd02f2921,0xdcf6ea43,0xab70cb7a,0x791559e1,0x12434ea8, + 0x6d70ff0b,0x040680db,0x2832ba45,0x1a10fe52,0xe5f0cb8f,0xd69f9c08, + 0x44b141fd,0x1a7422ac }, + { 0x9f40b675,0xc3a9dd2e,0xfcc71f39,0x2a7c6603,0x1948e342,0x18939a61, + 0xed0ab484,0x8f3b6158,0xee31ca6b,0xa3aa7d97,0xf7a8db63,0xbc1e865e, + 0x2c7c62e4,0x315f8c09,0x9f5c6d0f,0xa260788f,0x4b6f3ec5,0xb1833129, + 0x36b4d849,0x73adbcd6,0xbc699a9b,0x66e14890,0x2a1175e7,0xbf3790d8, + 0xfc53ca4f,0x7f43605a,0x87ff6091,0x577f6c47,0x600c82b6,0x827c7552, + 0x9d25599c,0x0944d630 } }, + /* 36 */ + { { 0xe6ab9620,0xcfdeb63e,0x786cd808,0xdff4fa6d,0x456320b3,0x145edd82, + 0xc4943915,0x2ae5f862,0xb73b3f87,0x9508e813,0xe52f97a9,0x3bd805f3, + 0xc9829b62,0xf71b5c28,0x86e0cefc,0xb394c70e,0x23bdb36e,0x534fb1a9, + 0xdbe27e5a,0xd64f5862,0x83ab6169,0xbae23df3,0x27c828cb,0xdd6df1b1, + 0x3a307a8a,0x1901899f,0x811ddf66,0x36cc8659,0x79943b77,0xa3cb7774, + 0x6fd86576,0x7d89f383 }, + { 0xc9f92b2b,0xf8564242,0xc46e32bd,0x700c6a75,0x7f99a5c5,0x93e768b7, + 0x03149568,0xb6efe858,0xc2ce6709,0xbbfe8a19,0xee6ec493,0x721a3b1b, + 0xc371c28d,0x26eeeea9,0x15177e1d,0xd798115e,0xb068a5a5,0xd7bf3bce, + 0x46d2b4b2,0xdf8da220,0x59be9dfc,0x3df0995b,0x77640b79,0xc96897bc, + 0x5a2bd3c5,0xce0cf4c2,0x89afe744,0x16f45d6e,0x3a8509bb,0xb53f3acb, + 0x63f2a6e6,0x449af81f } }, + /* 37 */ + { { 0xa16d9377,0xc2fcf132,0x7e1a2f9e,0x9ab377b3,0x86d19ae5,0x72e1a12e, + 0xd013bbb1,0xd2b12e66,0xcb5f66ba,0x0972e055,0x399eab50,0xd11de1c0, + 0xc65f5ec2,0xc1f314fd,0x8a9ff593,0xfc311841,0xe05246e6,0xdf73c1ec, + 0x1625056d,0xc28d1363,0x6fb25e19,0x30a9dbd7,0x845cd2d7,0x049ed244, + 0xd36e852d,0xc779b83f,0xf68c8a83,0x85a35fc7,0xc95e8033,0x299bf1e1, + 0x20891af5,0x0e8617c3 }, + { 0x67c81b5c,0x53720602,0xe737873c,0x2fa89dcd,0xa8144fd0,0x2a7430b0, + 0x26208c83,0x3006c5a7,0xd8ea40f5,0x4e066660,0x896413a4,0x9dd025f9, + 0x46b9149f,0xbdf380cc,0x0a125cc2,0x80156619,0x52793c37,0x04d6a3b7, + 0x6b7a62f2,0xb6001374,0x585d5978,0xa9cfe268,0x8395fe66,0xdcad0cb8, + 0x46b261f6,0xbab468fc,0x9d9d9218,0xca0ef5ef,0x5e452402,0xc507d4a8, + 0x326cf687,0x6f4404f1 } }, + /* 38 */ + { { 0x4febd3ff,0xa3e1920b,0xfdfd2bba,0xca6234d8,0xe19a9829,0xb7d1af2a, + 0xc6f5bc20,0x23de1610,0xdaa39ca9,0xe204dbf3,0x6d8c70ab,0x2a2de9b8, + 0x7c9d370b,0x272e0c37,0xe565510e,0x80914c06,0x57cbb6b0,0xb611e7a8, + 0xd8266a6e,0x076fc6ef,0x3095801c,0xdfac34ee,0xb9e24063,0x69ff40a2, + 0x787aa5c5,0xa7ba31a9,0x33c70cd2,0x0e4d1fdf,0x6895f074,0x903e3132, + 0x7fb671e2,0x905771f8 }, + { 0xa4062bee,0x5199ba0d,0x94d7d9f9,0x18e7238c,0x1e0922c0,0xf53f29bc, + 0xb12d855f,0xde9b2a81,0x6d68ca29,0x649f3eed,0xc50c097f,0x64adfc34, + 0x9db398a0,0x81964ab9,0x7a587224,0x00d59c47,0x74c5903a,0x09fea396, + 0x15043dd0,0x6aafd8ee,0x5f1ecc20,0xc5721a6e,0x0db9b7b4,0xb6d6a483, + 0x66c8d52a,0x06ffc617,0xacc82a27,0x3de241d6,0x27f2f7a8,0x0605f052, + 0x6404decc,0x6a22953b } }, + /* 39 */ + { { 0x74fce389,0x92452d8f,0x2afa5564,0x059634c0,0xf0ed7825,0x9377ccbb, + 0x37718e0d,0x89f4045b,0x9fa69a4d,0x11074e7d,0x7295b0ba,0x5d70bb07, + 0xf107ede6,0xb22d54ad,0xa1a29c7b,0x5c39a3d8,0xd795e3ab,0x37236c02, + 0x2b589951,0xf7282d00,0x5790bee2,0x5e2265be,0xa8e65ea2,0x91e0ea11, + 0x6001cebd,0x0e71a708,0x2c1c5402,0x16900f5a,0x357f6981,0xc3b2d5c0, + 0x619e3427,0x528c9ea0 }, + { 0x5f26c577,0x1edc86b4,0x9438bd45,0xf8074708,0x792582a7,0x2dfe1013, + 0xde1e569f,0xe08eaca0,0x9a55a356,0x5f952efa,0xe4976216,0xa4d80b53, + 0xcd5d71f2,0xd2b65855,0x66cea3f0,0x246704bf,0x492323ca,0x193f641f, + 0x9adb1325,0xa681855c,0x2d19d652,0x86d522ce,0x5b82ed7b,0x53609f10, + 0x8e150d29,0x3b0f0094,0x0b13e891,0x23ad8bfb,0xf794b449,0xcbb1556c, + 0x738bcf57,0x200f9093 } }, + /* 40 */ + { { 0x8388387f,0xf9b22fc5,0x28e883c5,0xcf26f170,0xd1b7973c,0x447cab90, + 0xf6ec9171,0x8d5d4ea2,0xc30cdbc0,0x2e16f498,0x48623c2b,0xdc92910c, + 0x30dbc545,0xeb1491b0,0x14de21b0,0x631deb2e,0x2fe830f4,0x04a21066, + 0x379c1f3f,0xa4c6979c,0xfb06a795,0x8a732b68,0x1619dfa9,0x3a44327a, + 0x8dbe2c9b,0x91a307d3,0x03989fea,0x939bc8d2,0x0f4a331f,0x3daabaf2, + 0xdd0f55dc,0x5c307e98 }, + { 0x35b233da,0xbbc4e0c4,0x22f6f985,0xe3d29085,0xa8b02468,0x99dd2d21, + 0xa96916e7,0x978f40e9,0x614bcced,0x0327d86c,0xb290762c,0x95e95502, + 0xa879f2ed,0x0ffd2197,0x50e0bd33,0xc4365137,0x0827c4c4,0x26c3148a, + 0x3fcfc0b2,0xc79812a8,0x31928589,0xc3d8d17e,0x8830f42d,0x8b572cfe, + 0x4b07f83f,0x7cd9ff92,0x0a51148f,0x331ca950,0x4c59f9ac,0xd0c53968, + 0xc1434785,0x1df16dfa } }, + /* 41 */ + { { 0x68bcacc3,0xcc7bb4ac,0x430f58cf,0x06ded34f,0xd461855a,0xc59f9f4f, + 0x45c9f0bc,0xf5491994,0x4375c892,0xdc5f7ec6,0x3c85983a,0x1b8708f1, + 0x82fcd087,0xb32a5cc4,0x2d6b4c0f,0xefdcdc35,0x8ac6fb2d,0x4bb24f04, + 0x33906471,0x5982d4f5,0xb83a3ac4,0x162eb52f,0x2337a223,0x7130df28, + 0xcbc3dbd3,0xdce7b802,0x2467ac0e,0x8b395959,0x1b56717e,0x21d3d2e8, + 0x46512617,0x729a7f50 }, + { 0x8420f90a,0x874ed1aa,0x0fe4c855,0x6368e19e,0xb0be74af,0xb62d4aaa, + 0x8ca60ca9,0x76fcc480,0x7645a867,0xf310b5a5,0xddb1b24c,0x131bac9b, + 0x2dea5b44,0xef77d71d,0x72fcc64e,0x4706d210,0x673d77f0,0x29b92691, + 0xe89e0663,0x22e00bf3,0x74077d40,0x472d0cd3,0x829232e2,0x3e21040d, + 0x38dc8533,0x2f916dfb,0x14b8f667,0x48bbb59b,0xd44be19d,0x19de9f4a, + 0x232d9d5c,0x7f6d3649 } }, + /* 42 */ + { { 0x6e794819,0x3bd064de,0xf82ebda1,0x5a6b694e,0xb91e2804,0x1f017fe0, + 0x07a43cd2,0x190d31f3,0x630433e9,0x6c26f226,0x0abfdcb4,0xba488aa7, + 0xa46411c0,0x418d9085,0xbffb5880,0x1b934fe6,0xe200f849,0x75d1e237, + 0xa55413db,0xdf04d63f,0xe23b3f77,0xe216ed75,0x0f91bd30,0xa05866cb, + 0x7729c509,0x84c395d9,0x452ab2d7,0xec97e188,0x0093d686,0x8cb7c1f9, + 0x628f086c,0x2d032395 }, + { 0x4a44b4c5,0xa81c9407,0xcc702c98,0xb9846879,0xceb0dc97,0xcb502287, + 0x6e3aa321,0x30301126,0xe4c256c2,0xc0ac8763,0xe55b4845,0x65034d20, + 0xf240f35b,0xaa96a040,0x7cf7eedc,0x046d26d3,0x3b810656,0x62a5a8e1, + 0x83d70c2b,0x86044b97,0x59e4da8f,0x2fbaff88,0x5457f5d1,0x929d901a, + 0xb531b757,0xd29e1eb2,0x9e4e9739,0x214dabdc,0x4eaa9bd9,0x5bd724fc, + 0x1ef9bb9b,0x734c12b3 } }, + /* 43 */ + { { 0x92f9b086,0x98fe3c2e,0xb3fd4544,0x4641b93e,0x5c02c65c,0x47ce208b, + 0xc4f03242,0x8a52dca1,0x679d29f6,0xb5ec17d9,0x9406f5f4,0x11d2fed0, + 0x0d9ba811,0x260f63dc,0x15472a3f,0xde2b056f,0x007290e6,0x1b170d9f, + 0xb6b5c8f9,0xa2e23e8d,0xcf34c3ee,0x345a2839,0x1b973ee2,0x9bdc5461, + 0xbb24d1c5,0x65bda6c2,0x3c6141a1,0x97d52ba3,0x9d2eb201,0x47bb1612, + 0x21fbe49f,0x7c558a87 }, + { 0x3f350fec,0xb9485a52,0x6a38d4c0,0x016678c5,0x0d5aa64d,0x8ef346a2, + 0xd96da2e4,0xb85daa02,0x4f647b3c,0x845ec4ea,0x0d5e946c,0xc0d1a6ca, + 0x4fa9f4ab,0x41d8d1c1,0x9c8b1303,0x43972cc5,0x434ffbfb,0x67e1f48d, + 0x819d2318,0x350ce93a,0x6ddef23f,0x49f53090,0x200cf12c,0x3c2e6cf9, + 0x640432fc,0x42691cc1,0x72496b52,0xbfff74b4,0x020a97be,0x44527c9f, + 0x7b3c4348,0x34cd7dca } }, + /* 44 */ + { { 0x59e7fe87,0xf031761a,0x0047cd72,0xb1eae31a,0xfae30f62,0x27902e68, + 0xb71db143,0xa666f48d,0x0e0038f4,0x75ee6678,0x02bdd76d,0x3b45ac67, + 0xa0d6cd5c,0x0d2fb828,0x9d8c5b11,0x27ce7f1d,0x120b5e96,0x141fe0e4, + 0xb9267c37,0x95a1b984,0xd60312cd,0x5206e589,0xda549356,0x1867342e, + 0x070c74ac,0x374520b9,0x9557b0b3,0x2703cbb5,0xa6ed8c14,0xf621f59c, + 0xabf7b887,0x7ceb1cc2 }, + { 0xdb7fd65b,0x0647a5bb,0x36c9457c,0xd8d45cc0,0x9e12718a,0xc6da99db, + 0xe93a7fb1,0xed1dbbf4,0xbd1566a1,0x4512c95c,0xdbc0c919,0x4861ba00, + 0x9e7f5269,0x3c6cc298,0x0941aaae,0x67196150,0xc8c538e3,0xbfcf5d0f, + 0xa25a551f,0xad6e9929,0x17ca0f26,0x90710985,0xfa89ef7e,0x743b78ea, + 0x71ab4549,0x39d5ea31,0xe6d1c36d,0x7442f3f3,0x059d568d,0x25a683e0, + 0x227ced5c,0x1f629a99 } }, + /* 45 */ + { { 0xe45a1c3e,0x8925ddac,0x41f7545f,0x72d29365,0x37e7f828,0x45622fcb, + 0x3e4c79d2,0x88234513,0x9c2645d6,0x5dffaf84,0x994802b9,0x3078f4dd, + 0x9d339fa0,0x566927f0,0x9fd91dcc,0x9a500a1e,0x0ab0abd7,0xce008180, + 0x8194e5df,0xd97135a3,0x98adf088,0x9e876307,0x9a45a2a7,0x3baf01b8, + 0x788b4399,0x6fed6154,0xe77a997d,0x980e5722,0x2a378eed,0xaac90ffa, + 0x8bd805a2,0x4a75fda2 }, + { 0x55e74cbc,0xd09a8fbb,0xfab18f25,0x737738ce,0x9764ec3a,0x0fc23ad6, + 0xe7e0ad31,0xc5a7d35b,0xe481cc9b,0xe75e068e,0x3d4aec34,0xf0c2ea99, + 0x0d4a63c4,0xf1324fe8,0x99b0592c,0x5dbb7c16,0xa7e0f46b,0x442d674d, + 0xa300faea,0x5a5d66c7,0x3333ac83,0xe83dc821,0x8c408496,0x70ef812e, + 0x99ef5fc1,0x96e1dcb6,0x1734e862,0x6e2b771b,0x583507d8,0x04629cdc, + 0x23d8179a,0x5819f9ae } }, + /* 46 */ + { { 0x6aa78811,0xd9969121,0x2103e7c3,0xf64ee8f4,0x22b9e698,0xddf01070, + 0x4f582cde,0xe6001f9e,0x2ecfac1a,0x24a608af,0x06393009,0x6ef4c784, + 0xebf72911,0x5262eae6,0x8c4ee5a0,0xddbd0af5,0xecd87bc7,0x875aff90, + 0x6f24f114,0x2fddb34c,0xe865f172,0x48104281,0x886c1b9a,0x95692426, + 0x9ef4231f,0x6f5f3208,0xd0a7e82e,0xaf587acf,0x9ac395c8,0xd6571917, + 0x1364a750,0x7459603c }, + { 0xf41ae519,0x1c2475bf,0x4af8f251,0x34401fb1,0xaefb2c3d,0x70ddfcd2, + 0x51cdaf08,0x9b2d385b,0x8208bb19,0x8531c256,0x4c33f3f6,0x16c89df6, + 0x24571769,0xc23cfa99,0x86d010ba,0x2339b51e,0x22638313,0x08db0e8d, + 0x00fedeb7,0xf769e179,0xa3687ef1,0x3fd96dcb,0x91476475,0xcd046b23, + 0x0c45c8dd,0xf3ff2064,0xb8343d78,0xefd167bd,0x4b77ee90,0x493ccb6d, + 0xb3cf7b45,0x33025513 } }, + /* 47 */ + { { 0x35eaaca1,0x36f00469,0x89119102,0x0c384b75,0xe6d2954c,0xcb375665, + 0xb1e9d6d7,0xcb9199b9,0xc29c2757,0x75852349,0xb8e738d0,0x89cbd1ba, + 0x5923a427,0x9b8dbe90,0x18fe1889,0xa237793e,0xa742e083,0xa4271757, + 0x4eebd613,0x8c4979d2,0xd4f2cf77,0x40325054,0x958705de,0xa3b8a091, + 0x33d999ba,0x1b191bd9,0x3b0fee1e,0xbafefba4,0x3facdf14,0xb3bad184, + 0x4387561c,0x9328adb0 }, + { 0xf906b872,0xabe84e80,0x78262665,0x705523a0,0x3398ccf7,0xd89c6a7e, + 0xf55b5323,0x2fab551d,0x0554dea8,0xa0578eca,0x375589cd,0xef26523d, + 0x864ad750,0xd8fd6242,0x178fe1fe,0x93f27fc5,0x9df87422,0x7b3e6f30, + 0x3750d054,0x2862e49e,0x5dc038a1,0x7d90c6b2,0x84db682b,0xc1a1ae22, + 0x9881930a,0x47f3dab7,0xbaf3e0a4,0x30e6bd52,0xf62d25c5,0x0680025b, + 0xadd0d5e7,0x0aa1f3cf } }, + /* 48 */ + { { 0x22a10453,0xa9822190,0x2a03a10b,0xdd1eb91c,0x96646f3b,0xafbb5d95, + 0xf38b6fc6,0xa58de344,0xb8cfca1d,0xce47c3e5,0x0f70da04,0xfcd8e16d, + 0xda262ed6,0xac44349b,0xc56e2f8e,0x9320d87b,0x19138e58,0x9ce3ea08, + 0xa2b236c0,0xa5862dff,0x8e7efb0d,0x6b0f9a5c,0x16ac78eb,0x4b53432b, + 0x709b51af,0x6ff43105,0x8f519628,0x08e236f8,0xeed403ad,0x1f93f176, + 0x9636545e,0x559337e0 }, + { 0xd8fd807a,0x30ddf738,0xab131222,0xf4e0ec9d,0x625afbc3,0x14a2f4db, + 0x9f12f895,0xd5b70604,0xac3044fd,0xb46f3c23,0xf540148f,0x1b232d1f, + 0x39b4e554,0x61b458f5,0x0dd70b75,0xf694b24a,0x289581d9,0x0fc64299, + 0xee5fe22d,0xc05d49be,0x6a18bf63,0x7af3447f,0x7f1929d6,0xe96a1dc2, + 0xc1551e8c,0x6afe6028,0x2b5d4fa2,0x27dacaf3,0x545c2cb4,0x4a1631bc, + 0xb0c914d3,0x930070f9 } }, + /* 49 */ + { { 0x69a9bc05,0xd2f32c5e,0x589c4b73,0x0a5c19c6,0x94665f9c,0x095c9e5e, + 0xbcfb4c39,0x8ab0f293,0x1ddb7c31,0xb9070877,0x66b38048,0x894e9658, + 0x606bd9bd,0xf19a90cf,0xb6fd2d69,0xcc1d58df,0x461d8a69,0x886dcc4e, + 0xf9ce4831,0xc455c277,0x765f8a82,0x749a5996,0xc3badc8d,0x2ffc668c, + 0x9112cdab,0x38018396,0xb243c7cb,0xa98795c3,0x010a2224,0x8775f310, + 0x587b5e14,0x043a2141 }, + { 0x3a873752,0x7bbe9dbc,0x2f442fee,0xee1493f4,0xc18c2181,0x981ca2c8, + 0xe29769e7,0x00ce3090,0xde768c5f,0xb4626ac8,0x34d7677e,0x33e9ce46, + 0xe0fa94e6,0xf89c2cad,0x41f5b5bf,0x04f5cc11,0x2228c12c,0x2565f736, + 0x0c05cce5,0xf1bf706a,0xbe487c4f,0x5d07ffff,0xa499f1a4,0x3ec43c09, + 0x98d94800,0x4f4e79bb,0x073f12f8,0x8a335a16,0x0f970d6d,0x4bb5eaf7, + 0xf24d0ae8,0x18d0747b } }, + /* 50 */ + { { 0x84601faf,0x58d3c77c,0xaf1c1f72,0xc9465be2,0xd116d806,0xff626798, + 0xd5b0d93c,0x3996c0c6,0x5ec6723a,0x2fa1ad75,0x03ba5349,0x966a8144, + 0x2ac34d8a,0xdc4c9422,0xed675865,0xddf471de,0x953d528f,0xd8aca597, + 0x24ebf67d,0xb2e463b5,0x7e25b4d3,0x25824871,0x43159daa,0x23c5adba, + 0x83357540,0x5458f9c6,0xf938b1a6,0xcf685da7,0xcefed231,0x981a4fda, + 0x08bb5e59,0x711093ed }, + { 0x401f161a,0x12aa3fc6,0x974c5e87,0xf7358560,0x17b5df82,0x4aa252fb, + 0xa48e6299,0xb0b82b07,0x29dd847d,0x00234157,0x4529c5a6,0xf1e54d00, + 0x6d98f538,0xcc1c539e,0x28d3abcb,0x36162b53,0x2a84f0cd,0x75a37938, + 0x4dee7484,0xf717a81b,0x4c23bf1b,0x16cf35fb,0x787e8b3e,0x7fd1c29f, + 0x59b79ab0,0xb7da7e68,0x85f6c60b,0x072100a0,0xe7ed48b5,0x31840159, + 0x4d9c97d4,0x17898bda } }, + /* 51 */ + { { 0xae1b8cf8,0xcd8483d8,0xe9a28856,0x323d4b42,0x204a4bc2,0x7633584f, + 0xca7a69fa,0x4e0b2228,0xf757bab2,0x8afbda8b,0x6cc5f9ca,0x85b24088, + 0xd41a95c3,0x47fb4813,0xc2aabe6b,0x3f1bc53c,0x1ad1599d,0xf22cda3f, + 0xc31ea9b1,0x1b2ec081,0x01614ac1,0x048f304b,0xc6afa7ab,0xce31cee9, + 0x4140dc3d,0x55af7633,0xdce8abba,0x84b7ab37,0xc7cf3efe,0x50de7648, + 0x15356ab2,0x73a88dcf }, + { 0x06e83b39,0x3f868288,0x9f44037d,0x477a4413,0x17dbc841,0xf9058b0f, + 0x54d17549,0x2db64f4f,0xf2307ffe,0xa23cea6a,0x4f126261,0x393efd55, + 0x10f37f26,0x2f4e658a,0xf4ee1e35,0xa4437ce3,0xa93cde8b,0x64ef42a7, + 0x939aa901,0x1debc9f4,0x3d7b5cd4,0x44223d6a,0xf88a3acc,0x789a6a11, + 0x2c608a2d,0x56fb9df8,0xbbf56c06,0xe79db8e3,0x668fa300,0x73c56af2, + 0xae396a1e,0x52f32b17 } }, + /* 52 */ + { { 0xe714f71a,0x56f524c1,0x9add8519,0xc1be1262,0x65cadbe3,0xad9189d8, + 0x5a0fb649,0xd88bf5c8,0x21d192d9,0x9efa6a92,0x6f724b6f,0xe3fe8389, + 0xb250119c,0xec3fae24,0x2ae0d3c0,0x4b6af9f6,0xd619624d,0x8fceba0b, + 0x2fdb6e3a,0x7dc3092b,0x3263cd29,0xc91da376,0xf95c43bd,0x30c0761e, + 0xcdeb44d9,0x89136400,0x43c0d31d,0xfd7dce84,0x9871899f,0x78fec3b1, + 0xefdf58c1,0x79e14d28 }, + { 0x9bb40c55,0xe3822235,0x0ed07a42,0x0a27202d,0x4838c1f4,0x48e6c1a9, + 0xd864a78e,0x2b5f24a7,0x0c6c55c9,0x7e7f140a,0xce12d508,0xe62c104a, + 0xc11b1e10,0x9b0a1a7e,0xafbb3dd5,0xfd8a275f,0x9a3b6b30,0xdff354fe, + 0x46602a01,0x5a105d9e,0x93bb65f7,0x3d371b4d,0x0f82fdeb,0xda5cbf0b, + 0xde468545,0x4601229b,0xc73d517e,0x505e10b9,0x672ff492,0x77cfa541, + 0x99566ce2,0x0d8ec28a } }, + /* 53 */ + { { 0xcbeee995,0x014cf73e,0xd491e80c,0xb2eb88bc,0xd9aba5d4,0x615a6cad, + 0x9304c84d,0x2f7d4633,0x8ab03c9a,0xba0501d2,0x91babb94,0xc8f723de, + 0x50405772,0xc885f977,0xc7fcb094,0xb5e1d2b3,0xdf96c71a,0x61ee7995, + 0x3464499e,0xb8c8daab,0x5f607932,0xdb425ddd,0xb1243587,0x70251ca1, + 0x9fc74340,0x26d7d3be,0xc902ac89,0x8c179310,0x4559a74f,0x72522c15, + 0xc3734afc,0x86001e27 }, + { 0xe7693947,0x13b00ba5,0x012c062b,0x6478641e,0xe85490a8,0xe1a438e0, + 0xd9574d5e,0x5173dbbf,0x9bd3ba61,0x9532eb8c,0x5f3ea075,0x1f41bcb8, + 0x8cbb92b9,0xac1cc247,0x1ef901b4,0x0f34648e,0xd2b3b2ee,0xdd929d1e, + 0xc3d75bfc,0x470f1eab,0x139cf4d2,0x5cdbc6f7,0xf0424953,0xcd86454d, + 0x47fcb383,0x1e079812,0x17df930c,0xb9f209b4,0x114ebc00,0x4225fc31, + 0x347946c1,0x020591cb } }, + /* 54 */ + { { 0x275e0af4,0xe3003721,0xe78a4a4b,0x721141ef,0xd1757485,0x666cfcf6, + 0x168e659e,0x5fa1d737,0x0e2842ee,0x263e3e54,0x948bd5f6,0xadecc3d4, + 0x246b104a,0x019de03d,0xf343d818,0xf8a9e903,0x5b0c0d31,0xcb57ba4a, + 0x51e2765f,0x8246c506,0x6519bf67,0x80c5751f,0xf2119a01,0x5f05c200, + 0x7821d4f4,0x7e6487b8,0x261c3a06,0x262f94aa,0x72146052,0x56cfe489, + 0xa1df05ef,0x5119985f }, + { 0xb18586c0,0x5819497d,0xc6eeaa62,0x004415d6,0x97cda28b,0x7c6a46b6, + 0x7c194594,0x9a149b28,0x4ed3a506,0xb56369fa,0x43c94cb4,0x7092aa66, + 0xa9e9eee2,0x55bce73a,0x77893509,0x34bb2870,0x06eb5326,0x8af95fb0, + 0x9638f485,0x87cd0323,0x5ba75bf8,0x29376268,0x9d42d581,0xf32d6f3d, + 0x65c6d64d,0xa4cad574,0xb2cded41,0x985f50fb,0x9006a067,0xcf34ce0e, + 0x58a57f9a,0x59eaf265 } }, + /* 55 */ + { { 0x6ec3876f,0x7b407efb,0xf0f48648,0x780c6123,0xbf893039,0x2abb56ff, + 0x45a91ab0,0x9592eaa0,0x78811b82,0xce5b84d7,0x1f9f3fc9,0x86a71a34, + 0xf0e7e13b,0xc17fdd86,0x655a0880,0x88ed8297,0x81d5e666,0x75d6dc74, + 0x1d171797,0xeffc9df6,0xe3f79e1f,0x36ad4c8d,0x2046192e,0xdb15317d, + 0x274fda62,0x78c9fa7a,0x82dd9914,0x04ec924f,0x3a64971c,0x059d1e38, + 0x2620bbfb,0x3b4450ea }, + { 0xc776dcdb,0x3db7a955,0x81c8ba47,0x35c4a57c,0x505760fb,0xae285003, + 0xb3aec353,0xe3e80691,0x47117be5,0x380335be,0x056ccf61,0xe1c47e3a, + 0x33977916,0x253cfdeb,0xf5cb7ee1,0x3decdfba,0x7cf4b704,0xf3c9794f, + 0x9ff81462,0x2401680c,0xbe3daa9f,0x4e440e11,0x69f91d8a,0xc5d04377, + 0xcb5e9c5d,0x4106c7a8,0x33b7d24d,0x191909a1,0x3764b4a2,0xe893c838, + 0xc429b614,0x4a7fe30c } }, + /* 56 */ + { { 0x2455c7c5,0xe78f3a70,0x70157754,0x5b7636e8,0x7623262c,0xf32c4524, + 0x1bc780c7,0x2c98b11e,0x915ed877,0xd48eaeac,0x199265f4,0xbb04d3c0, + 0xcfa5200f,0x6b52b19b,0x93ea3fe8,0xc46a0981,0xba758059,0xd82c733d, + 0x1896aacc,0xd324bbd6,0xce8ecd51,0xac09a2fc,0x02fc44b3,0x529918fd, + 0xaaa1784b,0xf0c45e4a,0xfe22085c,0x35626340,0xc50c7d61,0x53cbb676, + 0x65126b23,0x83fa1ea3 }, + { 0x10ccc646,0x60ac86da,0x7b0451e9,0x2ce0637f,0x8a088610,0xbbbcf630, + 0x20349982,0x23c19019,0xfc0bcda0,0x707fc39c,0x1bd4fd7d,0x7f4d1f15, + 0x44713bbb,0xd6a64e74,0xc5ac9e60,0x57bdc676,0x37b61169,0x456c5303, + 0xdcf40a1d,0xd3451396,0x4997d2c7,0xf3edec25,0xc2c4a739,0x534ae9a4, + 0x6a6ad2e2,0x1401397e,0x23e95f81,0x20769d4d,0xde98fabf,0xcee007c6, + 0x931c51e0,0x61409779 } }, + /* 57 */ + { { 0x15156623,0x3ddb32db,0xab7a67c2,0x68137fbc,0x6f19e3c2,0x26011f50, + 0x89924c61,0x34218b02,0xc6804c1c,0x492a0b0f,0xafaae6a7,0xd65be706, + 0x0d01be61,0x3b13d23e,0xf87f4c69,0x44545b47,0x04dc1aa3,0xd42236e2, + 0x3c5161ec,0x6135261d,0xbd88bc07,0x1eb46a63,0x1599d720,0x78c6d836, + 0x69baf0f3,0xf6955fe1,0x17072820,0x467eebd6,0x3e3a340a,0x2f1b8a2a, + 0x2d0b5f88,0x636dac76 }, + { 0xb4c80af3,0x94280db9,0x4e3892ab,0x9a189cd1,0xd1477ddc,0x26e702e0, + 0x68f9f14f,0xe91aee38,0x80baa0b2,0x2864f63a,0x8b714a29,0xacd81f73, + 0xc5fe7cb6,0x30e1b870,0xb10837fd,0x883ea1c3,0x6b20489f,0x2da27953, + 0x58a2da5f,0x3aeb2a68,0x03a8fa14,0xe2330bf2,0xdc70b1c4,0xb5c488b5, + 0x299678f4,0x0a78c4d9,0x25df675c,0x233bd098,0x7b67d368,0x37b5c076, + 0x4d0bef3f,0x2f6dbdfe } }, + /* 58 */ + { { 0x2e4da7c7,0x2f8472fd,0xae677932,0x708cfc91,0x3dc268e2,0x364af08a, + 0x799a2424,0x0f10dfe0,0x71d58bff,0xef912d58,0x988962e6,0x6bf35dfc, + 0x5f47ea0a,0x28b96fa9,0xaad308c1,0x734a79ea,0x9f437bba,0x95730337, + 0x6cf54f75,0x002cbd8e,0xe7632eec,0x47606dcf,0x53193104,0x404b5ecb, + 0x0acf729d,0x0ae0897c,0x3bddf1de,0x89628b86,0xf87d7448,0xeced154e, + 0x458d5d4e,0x5cb6e197 }, + { 0x008c75ed,0x98cef197,0xf6eeaaf8,0x7cf49d3e,0x1875e96d,0x1d6f9e02, + 0xdd9b0d8a,0xfcec2cfe,0xb9576daa,0x38a61cfe,0x36a7dbb8,0x10003f39, + 0x23b814f4,0xb37c3868,0xb80e3153,0x9fb66dcb,0x059847a8,0x9e7e2eba, + 0x35a72770,0xa4ec63fd,0xfc9e0ed0,0x311f3d91,0xd515baa4,0x3c1dc094, + 0xa08cd4e3,0x75a06ebc,0x2ed5eeaa,0xab617238,0xe1f52c1f,0x2e82bbb0, + 0x5175d6e5,0x2149d630 } }, + /* 59 */ + { { 0x5f9311f6,0xee1a8e6f,0xbabc1f85,0xc97e3c9f,0xb494209a,0x4fa7c52e, + 0x19774fe1,0x04c2f51c,0x8555844f,0x5cefd122,0xb5873ab3,0xb53862a3, + 0xcbed19fc,0x768efdd6,0xee58469a,0xcdc12479,0x3d80c09c,0x11237e31, + 0xc044c28c,0xdd74a290,0xbd47e287,0x9ee6517a,0xad0ffeef,0xc2421228, + 0x818d281f,0x4273088f,0x43ec0de1,0xebc744bc,0xb415bd73,0x5b26eccf, + 0xcb07c26c,0x14e2f350 }, + { 0x4216946b,0x548d2a10,0x7a4bd92d,0x6e801f07,0x43695160,0x5996d0a3, + 0x63a197c9,0x0f1b5c2f,0x061f77c9,0x79da3c4f,0x93ff7b22,0x1c1cd634, + 0xa234123f,0x5e61b650,0xf284033c,0x826b34c5,0xc2f34214,0x718b90e8, + 0xae806ec5,0xa5f35620,0xe324a9b4,0xa2fae345,0x8b53cb51,0x8c0bb95e, + 0xf9965778,0xc94f6ac2,0x6b9def32,0x07ec607d,0xd0ed8f27,0x63bf1dba, + 0xdcb61e4f,0x58537e02 } }, + /* 60 */ + { { 0x64f80ba2,0x1f64b064,0x0559a45b,0xe8e055e7,0xf1f4b634,0xc3262b34, + 0xde8c8482,0xef4f7d5f,0xc30c780a,0x9d55dea0,0xcfa1e693,0x1740afb9, + 0x7460c34b,0x2cfe6a66,0x1187c1ee,0xf6695941,0x5f974d94,0x1382f277, + 0x004549eb,0x1ca0ace4,0xbabded02,0xf8244b3f,0x4e3653ea,0xc36f4d06, + 0xc55c5f83,0xeab9f0dc,0xacebce90,0xd93b9cef,0x19061425,0x16658e72, + 0x82d7970d,0x4857835f }, + { 0xd2576210,0xdcd525bc,0xd51b5443,0x9f378aa7,0x1bd83994,0xfe97bf17, + 0xf38ac621,0x930d0f63,0x818408cc,0xaf8f2c17,0x260f53f6,0x2692c87e, + 0xdb0a75e4,0x0ee45407,0xffdb1b37,0x0ec47ae5,0x7aa6a44b,0x769129dc, + 0x2e40b75d,0xb6f932b2,0x95ef3b77,0xe06764d0,0x68bc63e8,0x28fd47f5, + 0x9c0014c0,0xd1810494,0xd7995d8e,0x90e2d3fd,0x6c2a85af,0xeb39a05d, + 0xa21f3128,0x6c0277bd } }, + /* 61 */ + { { 0xb509e7ef,0xe41b7086,0x3d7f9f91,0x8842ec7b,0x5526b88b,0xcd285f94, + 0x051dd0ab,0x6e44e064,0x774f1ceb,0x90198c10,0x123e661b,0x6ecabe98, + 0x32f647d9,0x44811136,0x26c52aee,0x1dd82b45,0x939dc9d5,0xd650907f, + 0xfcd455bf,0xbd5eeef2,0x8d2e5d7c,0x7815a4dd,0x88bc9f2a,0x5ad4ec92, + 0x57a3b322,0xc6f10d0b,0x20b9cbdb,0xe8d0c1e7,0x9b774ee8,0x5a0b071a, + 0xf22fcf8f,0x3067bc9a }, + { 0xb7ca9326,0xe0e589f2,0xb1224f63,0x17a106fd,0x747a57bd,0xb2354521, + 0x62b0882e,0x2614982d,0x4391ffcf,0x7f3af544,0xa84e440d,0x1aaa337b, + 0x941bb071,0x28ea37b0,0x2e4a7f54,0xa957dcb4,0x1a6ad5fb,0xe7ab662c, + 0xf7c36a20,0xd135e381,0x9baa0b6b,0x42e7980c,0x94e4671f,0x4237030c, + 0x8b0922e3,0x24cc63ff,0x445a589f,0xd10d5279,0xa870ff6c,0xbb99d316, + 0xa996c195,0x390c83ca } }, + /* 62 */ + { { 0xffc4a73f,0x50d3fa82,0x3bd53303,0x2665d635,0x264bb77d,0x80a06f8a, + 0x22d73d84,0x81c04a6e,0x0323b8aa,0x2409cff5,0x8c4c4d5a,0x31dce217, + 0x0c0f9c19,0x374aa80e,0x00186bb8,0x0b25a387,0xaaf1487f,0xd0b77a10, + 0xab498de1,0x15f39ad5,0x1aa0c116,0x92e32da6,0x96e25ce8,0x228e3dbd, + 0x5e8646d1,0xb57c88dc,0x267b1c68,0x672b1164,0x600bdec5,0x5d0d807f, + 0x223e573a,0x3ea4007d }, + { 0xa595d0a3,0xd76debd0,0xaff0b3b4,0xa6bd76cb,0x9b1bdb97,0xbf2c154f, + 0x4c714c71,0x62b19ab4,0x221af663,0xc9bf33b9,0x8c941ef6,0x23d87c49, + 0xd79f0f6d,0x255804c3,0x2a7acbc1,0x6f1a1005,0x550528af,0x5dab79d9, + 0xc8d16213,0xfd77a6f0,0xde5e1029,0x40508b6d,0xf95da12b,0xd95ac0f2, + 0x758a8ba1,0x8860af71,0x7160c8fb,0x0b194c83,0xce004d34,0xa40e6c80, + 0x6b14aaa0,0x09f82a17 } }, + /* 63 */ + { { 0xc21366dc,0x60abe588,0xaf75daf9,0x729c0a4f,0xacb93ed4,0x70501fd9, + 0x87a16d70,0xb97e744e,0x98e7361b,0xa42e0a7a,0x28b54cf3,0x1acdaff2, + 0xb7bd9078,0xf087ccbb,0x663250e7,0xda6f3983,0xbaf07c09,0x66d693ee, + 0x8cbaf157,0x79baf4c3,0xdfca99d0,0x5a984e07,0xf26d8dab,0xab4d3247, + 0x7eba36f9,0x4d0be701,0x0e8dd216,0x37bb9e65,0x531c4f03,0x72aa4e24, + 0xb753d85a,0x77d1e984 }, + { 0xd8e62367,0xd9373239,0xb9820cf1,0x3361848b,0x5a9c97c4,0x00c7e344, + 0x14f960fc,0x9a0ec9ae,0x740474b5,0xcf41f0cf,0xece065d5,0xa5eede8f, + 0x9e808610,0xb1de5a4e,0xae0cf75d,0x17c44ae4,0x6b148d0b,0x2fa56323, + 0xd29ff2dc,0x64fa740f,0x88cb212e,0xc605eb8a,0x6a863016,0xf2c771ad, + 0x607b4c17,0x6d6112e7,0x40d49785,0xfe90ec07,0xe256e0e5,0x599be18b, + 0xca54adb0,0x4e6eabec } }, + /* 64 */ + { { 0xfb99cfe6,0x950323d3,0xc9334178,0x7b09bc26,0x7cbdfb6f,0x64111e41, + 0x89a75760,0x91141744,0x10919cb0,0x4c633df9,0x396bfd2f,0x715fc7c7, + 0x8cab62db,0x8ca19512,0x4db81aac,0x30672473,0xb4c4c54a,0xe67a246b, + 0xbf229646,0xd77ea0fa,0xfa5b5d70,0x5bed15f1,0xc2f192f3,0xa5686da5, + 0x7f6690ad,0xdecac72a,0xcaa50b7d,0x0c4af2a2,0x6049ad2f,0xf44631c1, + 0x04ecf056,0x325d2796 }, + { 0x4848c144,0xee11fb55,0xb6a7af32,0x4e062925,0x369e0f9a,0x125b68e1, + 0xca53b21e,0xad9bdae6,0x2e98ea1b,0xf50d605c,0x9f2fa395,0xbdb9e153, + 0xe91532f5,0x4570e32d,0x46a250d7,0x810698ae,0xad9d9145,0x7fd9546c, + 0x11e97a5e,0xabf67721,0x249f82e9,0xca29f7d5,0x9851df63,0xa9c539a9, + 0x71d0e3e5,0xfd84d54b,0x041d2b56,0xd1e0459c,0xfd80096a,0xceb3eb6e, + 0xe32a79d3,0x19d48546 } }, + /* 65 */ + { { 0xb540f5e5,0xfe19ee8f,0x04e68d17,0x86d2a52f,0xadbdc871,0xd2320db0, + 0xd03a7fc8,0xa83ad5a8,0x08bcb916,0x54bf83c7,0x2e51e840,0x092133ea, + 0xcb52dddf,0xbce38424,0x31063583,0xd5c7be40,0x458e3176,0xc1ebb9df, + 0xbc4dabbf,0xafb19639,0xc05725a8,0x36350fe4,0x84e1cd24,0xac4a0634, + 0xc145b8de,0xadf73154,0xb3483237,0x0aa6dd9e,0xcbff2720,0xa3345c3d, + 0xb4e453b0,0x1b3ace6c }, + { 0x90a8bdc5,0x0343e5e9,0x6306a089,0xa203bf9d,0x8e48520e,0x98489a35, + 0xde7d1d06,0xbd17debe,0x5f795d3f,0x8fafa6d7,0x387b0a3f,0xa4ceb630, + 0xffddeafa,0xe0166b32,0x7e764e02,0xa2fe2054,0xe871f304,0x55ab9824, + 0x952ec45e,0xa2bd36bb,0xa90d20ca,0x7b4c1484,0x75bcfb53,0x5319f387, + 0x6982c4e5,0x34238a4a,0xa102921d,0xa2bb61c7,0xdb3ab17e,0x1e061b64, + 0x192f0a14,0x538ec33e } }, + /* 66 */ + { { 0xa19b56cf,0x193496fe,0x7bb99acd,0x663d77f4,0x57d0a881,0x8f04afa8, + 0x082835fd,0xcced3da2,0x5d82cec7,0x7e21faed,0xf8009c85,0x6e175b99, + 0x2d05a307,0xd9c6e31b,0x81487d82,0x96948d4a,0xd46f6655,0x86ebd3f2, + 0x773ccc49,0x86851aa8,0x8b1640a6,0x3e220f22,0x41a20b75,0x9f06e3a8, + 0x90ac0a6f,0x2cfffe5e,0x8ebeb3fb,0xf5a9b1da,0x6e08e2c9,0x2587d997, + 0x03e9f401,0x6fd60298 }, + { 0x8eb7516a,0x54709f8d,0xbdc598ab,0x83058a74,0x87e801ce,0xd234dd98, + 0xd17b8a96,0xfd0f9d90,0x6e90f6ab,0xaa1e549f,0x5a7ed55b,0x2496ff80, + 0x6c254c19,0x0d9f657a,0xb8962575,0x3cdea49c,0x2dff27de,0xb685a3f0, + 0xdb8bc04b,0x3c50e7fd,0x987236b0,0x904ff0ff,0xbb0d5055,0x494298fd, + 0xe14be8d0,0x34b3386d,0x7c3d30d6,0x7ad34e9c,0xe159fdd9,0x1f2b32bd, + 0xc761e5c0,0x84cfa23c } }, + /* 67 */ + { { 0x8b99b964,0x13bc11eb,0x58e2fc47,0x8e280c0a,0xd4c9a54b,0x870fbc49, + 0xbf6e20fa,0x37a334a2,0xd7c88cfa,0xee583d0d,0xef4af1da,0x05e029a8, + 0x0c2ef8a6,0x6d55e234,0x209e9b62,0x61b6fdfe,0xbb8e080f,0x3b1dad26, + 0x9392fc1a,0x5adbc162,0x0aae3f4e,0x02ac0fe6,0xc2bf4d5b,0x8d99801a, + 0xc282fed2,0x2333f93f,0xb52db33f,0x16dcb10c,0xc55752e7,0x09f90f84, + 0xc84a0d8e,0x287d4c51 }, + { 0x0e9867da,0x5fa58201,0x1a874cda,0x614589b3,0xfbdee22e,0x005e27c5, + 0xe612bda8,0xe357fef5,0x2d3635f9,0x4e0dbedf,0x6f125a86,0x62be70e4, + 0x0d94a2e5,0xa09b9884,0x28b5e5d1,0x7eb99a15,0x751028b5,0x21b9416e, + 0xe06d2cc4,0x1b137fd7,0xfea09845,0x6fa1f517,0xffcecbd7,0x3ba1e966, + 0x832f453e,0xd4c89a4a,0xeca68fa1,0x07b1e2af,0x4bd395a3,0xd0fb4453, + 0xd8ef9e13,0x0132a3dc } }, + /* 68 */ + { { 0x576374c2,0xe53c7785,0x84727040,0xe60526d1,0x228ca044,0x8a066dc8, + 0xf1ce1313,0x1fe1c1b2,0xcdeb0c5d,0x2aeec832,0x9cbf826f,0xa7596699, + 0xde77a589,0xcd188e81,0x118d1254,0xe5ce0fe0,0x0790b86a,0xa142a984, + 0x39ac28ce,0xe28f043f,0x87de5804,0x4eef8290,0xf639a8c5,0x83c31b32, + 0x5887794f,0xd70454a7,0x18b1b391,0xca635d50,0x31d9c795,0xcefea076, + 0xb6f8aa25,0x13cbee76 }, + { 0x8d3f34f3,0x79cabe0f,0xa3617fe3,0xbda9c31c,0xdd9426a1,0xb26dee23, + 0xf29c9104,0xe9dd9627,0xe2c6cd3b,0x033eb169,0xfcba2196,0x8a73f492, + 0xb858c83c,0x92e37e0b,0x23b3fbb7,0xe4f2aca6,0x64be00a2,0x8101fb1e, + 0x948f6448,0x91a7826a,0x907260e7,0x414067b4,0xe30bb835,0xf774aa50, + 0xc999c06e,0xf922ca80,0x0ba08511,0x6b8635b9,0x25fa04f0,0xbf936b5c, + 0xe02e8967,0x4e0a1ada } }, + /* 69 */ + { { 0x8ba29c4d,0x00ca6670,0x22988094,0xc08240ce,0x16dda752,0x21c5ca67, + 0xabbbfa34,0x689c0e45,0x3ed28b72,0x1d7545fd,0xd7c56ab4,0x5f221198, + 0x38759d65,0x4b3d8f74,0x8fe50b89,0x93490dfb,0xe80eba16,0xb641f5d7, + 0x79acb537,0x7b0da5eb,0x0c1d5e5e,0xab6b1497,0xa5da429a,0x2338e68d, + 0x2f6d2f25,0xe010c437,0x6530f3a7,0x226f16d2,0xcbef08bc,0xefb0f7b6, + 0x9f99c999,0x733e30d9 }, + { 0xa42a38f9,0xecfe1582,0x4730b500,0xaec2d58e,0xde976b2c,0x2ee2f2a7, + 0xa969c1bb,0xf0539db5,0xfcecdb4a,0x31954168,0xe7a8e902,0xf2f7348a, + 0x3121541f,0x1d58d7cc,0x2202ae52,0x5d25b75c,0xf40835a7,0xdea9965a, + 0x529b4e46,0x3feb6a41,0xbd27ad9b,0x5c97fb6f,0x261f900b,0xd87554c0, + 0x04d5b19e,0xb43031d9,0xcb219b9c,0x33d5e9b8,0x3ee00bcf,0x7a43d492, + 0xb79a5c0c,0x56facb39 } }, + /* 70 */ + { { 0xa3018bfa,0x019165a2,0x9ffad984,0x100c6b24,0x55341a9b,0xbbf1b1f6, + 0x25dc4cc9,0xe6bd1d97,0x2bfffe60,0x52850ed5,0x7e5509ab,0x24e992cc, + 0x4ceb59f1,0xff6c502e,0x1aa7d148,0x2f0b3573,0xe7e3aa46,0xe90c1ddd, + 0xd1142880,0xbaec9f45,0x65be5dd5,0x475cfd26,0x1febce13,0x83abb14e, + 0x80942d30,0x6aba4829,0x297e82c8,0x1e1b235d,0x50d8218d,0xb771cdbe, + 0xd94d6cbb,0x88599266 }, + { 0x155ccaf2,0x08847290,0x7c5b773e,0x8679ebc7,0xb2dd08ed,0xa88b2dd1, + 0x87d475db,0x960a180e,0x6694d02a,0x80fdb6b7,0x3f3f9e96,0x3e8758c9, + 0x4ad836c4,0xbda3f6fa,0x32fb387d,0x9400c581,0x2550200f,0x25a78542, + 0x776ecf18,0x2a97c351,0x566db59a,0x03ebf46e,0x26545eda,0x4743a280, + 0xcf74ab44,0xed169d84,0x88cb3f69,0xbaab931d,0xd8257196,0x70ae932c, + 0xa0c09719,0x797224a6 } }, + /* 71 */ + { { 0x441f3567,0x632923f8,0x2e24bf1d,0xc11c3168,0xb7671fff,0x4b97726b, + 0x7a5e1a22,0x601746a7,0x3addb417,0x53dddea0,0x7f59b846,0x57867a3c, + 0x56cd7ff7,0xb012a987,0xf19ba9a8,0x1bd5fec9,0xf8306748,0x750379a2, + 0xab8c05d1,0x7763445d,0x7903f42a,0x5d7f441b,0xa903e46d,0xc011674d, + 0xadd126c1,0x1b1d3c4d,0x61455b40,0xa2752aac,0x555c356e,0x4da42a68, + 0xd820852c,0x3ff09c15 }, + { 0xf9cb7784,0x4c0a1bce,0x2422f305,0xaec539bc,0x0c414aa7,0x5f40f9fd, + 0xffd42bc4,0xd3aa316c,0x2f358e15,0x42f5a4c3,0xd6e27682,0x00bdcd9e, + 0xf8a5ecee,0x069f789f,0x05e14f5d,0x8078018e,0x8b40c741,0x2bb3e493, + 0x7917f72d,0x5dbc8c1d,0xcc57150c,0xe0eea664,0xc3fa8920,0xa25ecc5a, + 0x1c797164,0x3c21b0f5,0x634ad16b,0x8f09a2f2,0x58391d9a,0x8e730fc5, + 0x4fdfae4c,0x47ef1805 } }, + /* 72 */ + { { 0x3da285e4,0x9965f3d1,0x3a01e3f4,0xba7d4dba,0x61214ad0,0x4738413a, + 0x22397549,0xd3b7d535,0x5a730b92,0xa53dbdcf,0x332d165d,0x3130d92b, + 0x82f97ef4,0x44a28541,0x44dce1b6,0xbf62221c,0x7e2a0ec9,0xbba13858, + 0xcbfad998,0x33f32c8d,0xb5fed44b,0x409e5f3f,0xc66217bb,0x5c328c65, + 0xfcdf71a9,0xb00db69f,0xb8920788,0xa23c2a21,0x3ae6464b,0xf8ab28e6, + 0xb8de0861,0x1a6b6e9c }, + { 0x06af77aa,0xaf6ec2b6,0xa887f065,0x2e60f5cd,0x9f498c56,0x87d21400, + 0xfcbaaf4b,0xdb595b59,0x271ab855,0x0fb592a1,0xd4349b0c,0xa0ce10e5, + 0x887d8c9c,0x9d6187d8,0x154bd6db,0x03ee95f9,0x5d06c999,0x8fe53213, + 0xfb6a64d0,0xf4a7bc30,0x66a4cb60,0x3d22af0d,0x5d37367c,0x16952cef, + 0x997d8e55,0x6f0ea734,0x731732d0,0xb447c70f,0xa9cb3942,0x00ab3034, + 0x28510fd0,0x79dd0180 } }, + /* 73 */ + { { 0x3ac7424e,0x04e0033a,0x60fda4d0,0xdb06b688,0xbcb772fb,0x236a9766, + 0xf297cda4,0x294a8e2b,0xdb013c6e,0x4b0aab85,0x8723a3ad,0x3d2aec98, + 0x13c84a6b,0x0cae32cd,0x70ec169e,0x21888f5e,0x42a88262,0x739633bd, + 0x7b60d9b8,0x68ac792e,0x10769fe1,0x89f2b722,0xd24bed34,0x8f3fcfe6, + 0xa3eb24aa,0xd35efb88,0x484c706b,0xddecfa3f,0x929ece0d,0x7cc119a9, + 0x8d405436,0x87e5ad45 }, + { 0x7d1000a7,0xba99aa9d,0xae823833,0x8b94affc,0xdfb83dc5,0xc8229628, + 0x845a418d,0x2f59fe11,0x5d417054,0xa8b970f8,0x72b71581,0x8918c265, + 0xc0d1dd17,0xe4ef477d,0x3afad7c0,0xb50b4cf3,0x01870a5b,0x21baea79, + 0xbb3a2868,0xc77087f9,0x124a59cd,0x7857531e,0x57f43239,0xed74c26f, + 0x0164c94a,0xd5f5ae25,0xf094bf74,0x6608b7e2,0xfdceea32,0xf4cdb5ba, + 0x990cc045,0x0b712519 } }, + /* 74 */ + { { 0x88d5c64d,0x5a290ca1,0xa7492534,0x0596d749,0x2a00e925,0xa04b0d3d, + 0xcaf7b66b,0x082cd02c,0xecdded83,0x912b50c2,0xff31646e,0x813ce9de, + 0xc75fff95,0x62ae70c7,0x7e2a4615,0x6f6852e0,0x03804fd1,0x320fd7d0, + 0x8218e8d9,0xb1a2a4dd,0xafc645d7,0x4918a6fb,0xe8d9fdbe,0xfb080fa1, + 0x4470b6ee,0x33d4d08a,0x6d974ef7,0xd2ba2077,0x69dae5d2,0x8ecb95a7, + 0x7d69596d,0x7a3f423a }, + { 0x9a929387,0x362d2ca6,0xcb1c1fff,0xabdb7581,0x7e51b6cb,0xd892ec9f, + 0x3a4e131f,0xee8d8632,0x5bd87561,0x4680e3f1,0xd4e7e732,0xe3a597e1, + 0x5581fefe,0x3cc72b7c,0xca8cae0b,0xf3e77f8a,0x5e2fd4af,0xfcc7d7dc, + 0x21355b79,0xdd3a4552,0xa2c07177,0x546b24f2,0x0689621f,0x415b532d, + 0x3f78163e,0x2be9af51,0x33d7ed21,0x27d63b9b,0x96802943,0xab019ef2, + 0x1623faf4,0x2da5fc55 } }, + /* 75 */ + { { 0xc8a5c600,0x62429cf3,0x3fe33e7c,0xa7a80c22,0x0a57ddcb,0x9ffda740, + 0x925b0c74,0xd1ae156d,0x6b100eb0,0x097a43f9,0xef943c81,0x169e945c, + 0x1128cf24,0xa1f734e5,0x419f0133,0x04387c4a,0x01044024,0xc007868b, + 0x90359cf2,0xe5416abf,0x478d54e3,0xf9c76fee,0x42a2173e,0x66219da6, + 0x9fe30141,0x61e03156,0x93ef247e,0xa0ff5ce3,0x072b6592,0x811792ba, + 0x70c854d3,0x855f0219 }, + { 0x847314c4,0x61fbfb6c,0xeb45b96a,0x97906155,0x6ba2afac,0x7102e146, + 0xab949781,0xed51f975,0xc110c4fe,0x9d2f5b17,0xaff57667,0x7ac8ce70, + 0x6eb244e7,0xe7366a21,0x551c65c7,0xdd1bbcec,0xe1a859de,0xb525060a, + 0x8ba7d2e7,0x7a048174,0xab8ea8c4,0xe1a2c541,0x6fdff078,0x6e7824c3, + 0x14874b04,0x79b49fc7,0x06b1f733,0x22ae337f,0x6f8fe6cf,0x1c352192, + 0x525d0797,0x292236cf } }, + /* 76 */ + { { 0x7d8b29dc,0xcdb8d80a,0x08ea648a,0xd17a2024,0xae92be91,0x7db12c5e, + 0xfda72fbc,0x1f347d18,0x9e760c6f,0x11374b40,0xd8e38d91,0x7361e8f1, + 0x739ac1f4,0x7714be9d,0xb4df5c4e,0xc1f9701c,0x6f72cae1,0xd9138ed8, + 0x6ad180c4,0x1c7fe1f7,0x9e2dbf9c,0xf8c185be,0x7c70c44d,0x835db269, + 0xb0d15b5f,0xf997cfea,0x61e6545e,0x5101445a,0x25184e5e,0x16b06884, + 0x7521e7aa,0x7cfac359 }, + { 0x3c0bc53a,0x81182167,0x7e751367,0x84b5ede3,0xa3657a18,0x3ca255fd, + 0xba1fdd98,0x096abbf4,0xc5da77d8,0x9ce8369f,0xaab342c5,0xf27b9ae7, + 0x972059f1,0x06c91bd6,0x914ecfe9,0xee0dab30,0x93f53f12,0xbb647fbb, + 0xffa57e0e,0x30c38a7a,0x9f2ad607,0x517d06ef,0xbb99dcc9,0x49728d87, + 0x446080a1,0xb0034af1,0x12b9c17d,0xcc810c3f,0x772a22a0,0x7225f14f, + 0x1ddf82bd,0x6ce3dc7f } }, + /* 77 */ + { { 0xa4397830,0xc07cd835,0xf4733306,0x4dd9290c,0x29989e8c,0xdd35d3a8, + 0x563d8152,0x79902559,0xe87de61b,0xf278d911,0x1024e35c,0x9c7340c7, + 0x4a0d0e59,0x2d444461,0xf32626a1,0x63e7608f,0xc4c9baa9,0x627a37e9, + 0x76fffd25,0x0c56dc51,0xcef2a1cd,0xcb6defc8,0xefc559d9,0xcbcc0d56, + 0x041cb692,0xe45f3fc5,0xe5161e09,0xcd05c239,0x5c3b559c,0x2a731ee9, + 0xa3d0a16d,0x85151122 }, + { 0x86ff19e2,0x782d0335,0x1da28603,0xc2c60daa,0x557c7eed,0xb2e78cfe, + 0x1bc4e8b0,0xa8f6f984,0x3df35c67,0xcc1f9b4b,0x4764462a,0x96e13603, + 0x7c7ae0b0,0xbf910b97,0x51435956,0x27c7f305,0xf631eae5,0xc14db15c, + 0x7e69b34c,0xa51d6142,0x5fc12ff2,0xdec82851,0xfb887162,0xfcceae13, + 0xde1488bd,0xda332ac1,0x2ee3e74c,0xa20374e2,0xf0ae069c,0x597ea1a1, + 0x77bdec04,0x8b1159f2 } }, + /* 78 */ + { { 0x2f961d30,0x4af71a44,0x7ac7248f,0xbdf968a8,0xb1a906cd,0xd32df87c, + 0x04abf925,0x00c10e26,0xb9f04d4c,0xb8711759,0x939705da,0x00d54e60, + 0xc9f80849,0xf7587433,0x6a7a2375,0x2e9abade,0x94ac17ac,0x5676d478, + 0xc202d99c,0x4ca0525b,0xabfae73d,0x95b8bcad,0x3405991b,0x2371ed38, + 0x458a99c3,0x2b69e47a,0x2b78c866,0x7cac0b18,0xe0232c7c,0x6ceaa79b, + 0x588f7459,0x0bd86433 }, + { 0x7e734189,0xdea1a8b4,0xcfe5fa17,0x52c5ac88,0x11437664,0x444a4d4e, + 0xaf9e9750,0xc2522308,0xd30c6b3b,0x78b1d0c3,0x4c6df477,0x2edae5f0, + 0x2ee88dd7,0x53131d9a,0xacc93e34,0xc4e380ee,0xa8db0e8e,0xd499b1ac, + 0x7f5d49d7,0x77348c16,0x1556ccd7,0xc9663257,0x2611d13d,0x65ce0e8c, + 0xb5a2fdcc,0x2c95fe66,0x8658faa1,0x26698832,0x31c32c98,0xda87d1f4, + 0xfcd91907,0x46650598 } }, + /* 79 */ + { { 0x6b4a5efa,0x4c6c13cc,0x1d07b265,0xc481989b,0x8bdc69c0,0x10b966ce, + 0x2c2531d4,0xf54cfaa2,0xcad0a100,0xcb5f1808,0xee5da449,0xbeb52538, + 0xbedd83cc,0xa6240085,0xd6255c78,0xe792dacf,0x2062058f,0x88371906, + 0xed1658c1,0x96615e83,0x7d28d542,0x4b549b27,0x83b75df3,0xeaf127db, + 0x17fbb942,0x4f60df6d,0xf6f7c930,0xd08631db,0x6018789f,0x17c38f98, + 0xb9a9280c,0x0c43574a }, + { 0x1d20cad0,0x76eb324c,0x8c61108a,0x90decb09,0x6f06d36d,0xa6e9d39c, + 0xbc0da197,0x6cd978ba,0x507ac5ce,0x5948b1c0,0xc5497eb5,0x2bd47164, + 0x4d5914e3,0x2a9c4c0f,0xa759f03c,0x772c5046,0x69ac847e,0xe7d7328a, + 0x3048b330,0xa8d57d0c,0x40f7bace,0xe60034e0,0xa85f1790,0x823d9193, + 0x5c859736,0xa6e9b66c,0x679e1022,0x22ca2c7a,0x09023fa4,0x00e7a19c, + 0x2726d5b9,0x324999f1 } }, + /* 80 */ + { { 0x7c834915,0x667eaed6,0xbc5eb64d,0x9f77aa6a,0x25d62011,0x729ebcb6, + 0x699fd9c2,0x0aee24f2,0x2b8d4f6c,0xe1eb5874,0x14c976d6,0x7f12710c, + 0xf6d9ea65,0x91390335,0x06b50064,0x668b7049,0x0876ee4f,0x65969a0e, + 0x2f9d9360,0xf901bf3f,0xb499e3ce,0xfb1a8651,0xf2dbcaaa,0x80b953fb, + 0x973b06b6,0x312cc566,0x3af36c64,0x3534d9c3,0x10ffd815,0xe4463a52, + 0xf18c2b91,0x57ea2b4b }, + { 0x8aa0f2f2,0x00f5e162,0x0e46bcaa,0x8c7e75c5,0xa4a2c42d,0x97ab479a, + 0x14baa202,0xb4f308ea,0x6943cc2e,0xa901bd14,0xeed58804,0xbb125fee, + 0x9d180f7c,0x6502c8f9,0x1580c61c,0xe5353919,0x27101ee3,0x7e278069, + 0xfaa72717,0x7a0a40a1,0x4c75b153,0x32edce02,0x538f1c22,0xda23660b, + 0xbe307d2e,0x4d511e98,0x9baee0b4,0x24276e40,0x7ff1f307,0xa78c3927, + 0xea7935c9,0x60480b46 } }, + /* 81 */ + { { 0x3872ece3,0x31087d66,0x955b70f8,0x5f29be7d,0x9cf95bb8,0xb50b4fc7, + 0xdbffa621,0xbae3b58d,0xe022ba5d,0x0e61d280,0x4181449c,0x78ae5117, + 0xcf555485,0x0b132840,0xb8ce0b0e,0x800ed1b6,0x78d5de3d,0x35dffdd5, + 0x69a56b47,0xf7e42374,0x8d910ae7,0xd5e32369,0x6313c7c7,0xb6ff52a0, + 0xa92de9e5,0x5a2fe20d,0xd12110bb,0x41b347d3,0x40c16f23,0xc5905edb, + 0x9a8f88cc,0x0774a0d3 }, + { 0xe3b6c106,0x3ae181ab,0x8de150b7,0x4ebe163f,0x6f354836,0xcf75b82f, + 0x3ac7ac16,0xaa0d2063,0x291722af,0x5c680668,0x11545553,0x73941e61, + 0xbf5de3f7,0x17127e38,0x1afb41da,0x32cfdf03,0x87bc8663,0xc6893c91, + 0xa62c9c99,0x75046744,0x962c1947,0x96866e2d,0x378cdf4c,0x489ec8df, + 0x3407fa32,0x3a60709b,0x551290d1,0xd37d2159,0xbab92273,0x9623d303, + 0x2432014b,0x08151954 } }, + /* 82 */ + { { 0xfb7b2108,0xf9236d89,0xad75f9aa,0x3ecc83cc,0xb4e1da11,0xf7c72b15, + 0x0315c362,0x552aeaef,0xf272fe3f,0x11e140ed,0x87843ee8,0x99d79bf6, + 0x1d9bb25b,0xce6b54fd,0x5b1bad74,0xb20b0e21,0x5b84c90d,0x54a0214f, + 0xfca6cec9,0x459bbf52,0x9e4df76f,0xe363c48d,0xd64cf17e,0x3045f84e, + 0xf62ada48,0x8402a167,0x6a74ca01,0x2c9e1bf3,0xf691c42d,0xe8cf9d41, + 0xc2c4b874,0x5abf2178 }, + { 0xf3b3bccd,0x4777966b,0xbe3e0caa,0x0047e0f0,0x8c7d5043,0xcb8383b3, + 0x946fd5fc,0xe77e3baf,0xe9ec0e87,0x79baa785,0xc8a18d25,0xd83c557c, + 0x25befcfe,0x9b96e5af,0x98c71b61,0x4f05d15e,0x77e62da1,0x081f991a, + 0xcbaa3821,0x1c6ec781,0xe54d9bfb,0x7522f65d,0x44ed1430,0xf5d05573, + 0x95cafdda,0x3035b31f,0x6378f5bf,0x47e67f43,0x5270b9d9,0x029f7cad, + 0x4d916a48,0x15ad1587 } }, + /* 83 */ + { { 0xaa588ae4,0x00de2ece,0xa371a232,0x552ebc58,0x71230444,0xd00ea934, + 0xe4b1832d,0xafbfa67d,0xb689e843,0x29216341,0x61f4e2e8,0x1f96bbbd, + 0x04c29dc5,0x95420684,0x42317fd1,0xc7fe3827,0x63483162,0xe0a0aec6, + 0x0700184f,0xfc2b94d1,0xfe1fbd85,0x07219973,0xfb074352,0x648b6ab1, + 0xc46e5392,0x23bbdaad,0x00fa56ff,0x0db8dd1f,0x866725f6,0x104815eb, + 0x52e81963,0x3f9c4cca }, + { 0x32ce637e,0xff36b297,0xf5d25cdd,0x81a15f2d,0x8b02ad97,0x1a1d052d, + 0xcfbab3e9,0x2e5f3bbc,0x614eeb75,0x60d2cbd7,0xcd5a793a,0xd4491843, + 0xcdba2144,0x2242cf75,0x88b99766,0xa20705e7,0xec77e132,0x64e12cc0, + 0xb61a9b05,0xb1c14df6,0x74825b5a,0x8fd97f04,0x3da31223,0x95604821, + 0x4d30c70d,0xde486727,0x1c12ee69,0xbcab8f15,0x668d893d,0x5dc638b4, + 0x223f574b,0x6479dad6 } }, + /* 84 */ + { { 0xb05f2b26,0x569044f3,0x80b9f76c,0xb35a294a,0x4290f6ae,0x8839fe28, + 0x026a5877,0x761cfb23,0x2e5ff9c3,0x768926b6,0x0b11c576,0xbae6cd20, + 0x72a03efe,0xdc857756,0xe1bad63a,0x0cae074a,0xd709d99c,0x3fe491a1, + 0x6501d9c1,0x76c5ded6,0xc32aeff7,0x1da6eca1,0xc57683e8,0x50849d55, + 0xdf98d847,0x9e392e9c,0x64d9a564,0xfad7982f,0xa37b98b2,0xf7c3bdb7, + 0xf0860497,0x1fe09f94 }, + { 0x7648cc63,0x49a7eaae,0x67cfa714,0x13ea2511,0x653f4559,0xfc8b923c, + 0x81a16e86,0xd957619b,0x3c864674,0x0c7e804b,0x1616599a,0xfc88134a, + 0x0a652328,0x366ea969,0x4bc9029e,0x41532960,0xae2aad2b,0xef9e1994, + 0x7f10bef5,0x9e2a8c52,0xc67bf860,0x73dcb586,0x844cc25d,0xf61a43fa, + 0x74eb3653,0xd74e7eea,0xdd240f02,0xf3356706,0xfd83bcb4,0xeec7694c, + 0xdb62526a,0x4de95786 } }, + /* 85 */ + { { 0x3deac2f7,0x4867d315,0xb61d9a8e,0xa084778a,0x0ab7b2d5,0xf3b76f96, + 0xcfdf4f79,0x00b30056,0x31ab8f4b,0xd0701e15,0x9c779d01,0x07f948d5, + 0x82675371,0x7c994ebc,0x48bad4c0,0x1104d4ee,0xbfc9d058,0x798ce0b5, + 0x309fa80b,0xc7ca898d,0xacb33eaf,0x0244f225,0x5b2f3175,0xd51e8dfc, + 0xa4d7be34,0x3e49ba6b,0xbda02b43,0x1760f4c7,0x4435275a,0x37e36a7e, + 0xe636980c,0x1c94418b }, + { 0x09dc1414,0x43a21313,0x43c93537,0x060765fc,0xdf5f79ce,0x6ff3207a, + 0x85d4cfca,0x6f18b1fa,0x63e995ab,0xf5c4272e,0xa82b3002,0x121a09e4, + 0x97147f16,0x82b65d1b,0x20a7fe26,0x4993c20c,0xe6716726,0x99c9cb98, + 0xfeb440a0,0x5a02d673,0x251b4bc5,0x3f3fa9e1,0xa05338ea,0x75dbc474, + 0x7b09f6cb,0x3cb4044b,0x80434609,0x6767da18,0x098ceac2,0x97851422, + 0xb55235ba,0x611bfbb2 } }, + /* 86 */ + { { 0xf00ad2a1,0xbdbaa55e,0x14a290d7,0x29efa85e,0xe92b1694,0x3b4a4768, + 0x11ec8130,0x67111bcd,0x88bd27b2,0x0e425702,0xd9a03c06,0xf28cf2a3, + 0xf318884a,0xbb7c8d2d,0xe3aaeb20,0xe2ea1462,0x43b85d77,0x33535804, + 0x554ee9bd,0x81ee4482,0xe6aa198f,0xeb2eee9e,0xc26c5944,0x7a5aa804, + 0x82ab167c,0xa0ef2da5,0x02fe21a5,0x5a2ab476,0x3370298e,0x169cb3b8, + 0x0eb3aa8d,0x86e6c544 }, + { 0x0b793d9b,0xede03321,0x1ddb5ece,0xf79fade1,0x68930b64,0xf73fda92, + 0xfe4fd1b2,0x06aad97d,0x92a4dc88,0x073a5b1d,0xbc976d75,0x8af8cbd8, + 0x63ce26c0,0x60b4abb1,0xdcb1fb06,0x9c8300a9,0xda95b3d3,0x335a594c, + 0xb37eac87,0x1f97d7d4,0x20eefaab,0xa3d2eba2,0xf3e828c8,0x3258c906, + 0x85ab7781,0xc832616f,0x8c28b617,0x72597192,0x3233b82d,0xcd7196bc, + 0x19fa126d,0x83867eb9 } }, + /* 87 */ + { { 0x22474edb,0x774fe73e,0x1a84e1ae,0x2a766394,0x9c6dd6e3,0x270329ad, + 0x14f8bf5d,0x00c4a415,0xd2267b90,0x3ce2ea37,0x11d24fae,0x12753015, + 0x263a1b78,0x7c14d854,0x1ae0b206,0x20c8401b,0x081f49fc,0xf32a011b, + 0x959c6df8,0x1e8123fb,0x800e1d06,0xa328dc7c,0x24259a9a,0x5876a378, + 0xb7ef6c37,0x23ada8b5,0xa93d4c9f,0x023f6b6e,0xffb6389f,0x89f5414d, + 0xe628b39e,0x4b26bba2 }, + { 0x5d318454,0xd30b1cb4,0xd7436cb6,0x123b749f,0x568a7461,0x3110c726, + 0x1c84fd1e,0xc85de123,0x08403d55,0xa5f8d6e6,0x9b1fabf8,0x395b6e13, + 0x3cfedce0,0xfe6d68c3,0x94b91110,0x1d90381f,0x2dcc6eb7,0xf0a8ea81, + 0x7e90ca2b,0x59e80413,0xc8a25c5a,0xbeb5fc07,0x5d84663c,0x009c253a, + 0x910b6a7c,0x00b15073,0x4108f8d5,0x8607da4c,0xcb901e65,0x02c3d9c3, + 0x2c9615c6,0x4d697bc5 } }, + /* 88 */ + { { 0xefa8fb40,0xe0db1ef0,0x5ba3989c,0x29021c5b,0x809d19df,0xa8d6fb15, + 0x4c1219e1,0x6b787b73,0x14ef05e2,0x6417e168,0x8f9796e2,0x449342db, + 0xbf84421b,0x2f878a5e,0xe94a4536,0xe71916d7,0xae119693,0x9818bba3, + 0x5768804e,0xec674be9,0xf8424f8a,0x0a26074c,0x466ce6ab,0xdbc93b9d, + 0xc920078b,0xb3f15a98,0x3870f1a3,0x9d10fd0d,0xe4e785a7,0xa61241d9, + 0xe6c8cd80,0x76ca87a1 }, + { 0xe02e48b7,0x4357fb56,0xcc09e9c6,0xfbd14b13,0x24069cf0,0xdb5f2435, + 0x2c3b01a9,0xf878165c,0xe6956dad,0xe549e7c4,0xbbd60b68,0xf2fe9538, + 0x059dc653,0x952f856b,0xb377fe9b,0xd3f60225,0xbfe908c4,0x6a0c7328, + 0xbc8f5f2d,0xce6aa2d3,0x24425050,0xf7213443,0x3d3b3ce5,0x17e1266a, + 0xc1677512,0x75b5e43f,0x37fb894a,0x15927062,0x2be3e375,0x15260753, + 0x6da3b7be,0x27e7f2c6 } }, + /* 89 */ + { { 0xe6a15883,0x638f65ad,0x66afdb33,0xd4a7e68c,0xd3f12de5,0x6207b6ab, + 0x37b87810,0x1c6ff950,0x64acf6d3,0xc0d44cb2,0xf2be78c2,0x163ac601, + 0x1636980e,0x1c63cc5a,0x95c9349b,0x3e92cfe8,0x41ec7220,0x7738e0d8, + 0x2d5fa961,0x6169d764,0xc3e028e9,0x2aa776c1,0xb16d5409,0x93dc5646, + 0x706df4d9,0xa0b27fb5,0xce9c6b97,0x9e991170,0x53c85f40,0xea8e42be, + 0x83246528,0x02e96437 }, + { 0xae78ea1f,0x91540add,0x7b670e96,0x51a1b74d,0xf7006826,0xf9936441, + 0x7d7520c7,0x8f97d6ea,0x69ce12e1,0x0faa6a02,0x79208342,0x2590aca8, + 0x75614436,0x7a483863,0xf381408f,0x07c6149e,0xd7853406,0x733bf584, + 0x9abbb6f7,0x8761b010,0xf528a09a,0xe4eb249f,0x2e00ae3c,0x08781ed8, + 0x2178effa,0x864c1b25,0x9d513a7e,0xcc1e62a2,0x1919062f,0xedb8b94e, + 0x4f16527d,0x739f53da } }, + /* 90 */ + { { 0x924adc5f,0x7a5f4a88,0xa818f56d,0x95646c16,0x7795f954,0x0ec49129, + 0xd19c5400,0x2b48753d,0x205912b4,0x16fa236b,0xe87a4946,0x6b3d65f3, + 0x045fd066,0xa7174a01,0x12a5e140,0xb6350313,0xa96b8623,0xa79c4b44, + 0x9ab003d5,0x7a339d65,0x3826f31a,0xc72f30c6,0x6f7090cd,0xb4e7390c, + 0x906ebe24,0x59ac6c36,0xbba4505a,0x39a7f06d,0xc58c413a,0x839991e1, + 0xa20e0e84,0x020c23ff }, + { 0xafc74661,0x120e4ada,0x277fc065,0x37bbcf63,0xb6dce799,0x41049cf6, + 0x7b161ba1,0x5b8d6b53,0xa9610fb2,0x22218431,0xdfdde769,0xde9ec9d1, + 0x42d80630,0xd32bfa4d,0x6244df4b,0x3885702a,0x45592dfb,0xcdedd1ed, + 0xfb4e01b8,0x0e1df45b,0x86e215b0,0x8f4bded2,0x6a937e6a,0x80935487, + 0x8130f723,0x415278ba,0x38a821f8,0xc6dc4692,0xfd8b4f8a,0x2207b119, + 0xf9269cef,0x76e7bf53 } }, + /* 91 */ + { { 0x27ebd187,0x5f128428,0xb65aadbb,0x8d3320ab,0x72258695,0xb042765a, + 0x8f0986ab,0xda3f33f9,0xaebff503,0x411807a7,0x825f71a5,0x25c776ca, + 0xff7df24b,0xc0de7bed,0x165f1fb4,0xda8b0f42,0x731f3ae3,0x5f3ff737, + 0x193e0a52,0x4cd1d7e7,0xb6b3ba46,0x8df84aa3,0xaa1f3782,0xba84b897, + 0xe7733ac7,0x6e7960cc,0x50981a21,0x4d46d6ab,0x7cbb80ed,0x1ec12c25, + 0x2b96ef09,0x79e7ad27 }, + { 0x8f30caae,0x3cd970dc,0x0a6ebef4,0x85cabcf1,0xc714616d,0x63c1863e, + 0x519e3a98,0x1c50db0b,0x64cb13d6,0xf39b8963,0x22547b69,0xdf67d81f, + 0xd67db0cc,0x7157abb9,0x889491b7,0xccca25ba,0x7a27e0dc,0xf689207c, + 0x0fd43281,0x34ae8fbe,0x5720ec09,0xa5d91f73,0xcdfd7bed,0xb2f61909, + 0x4a039e32,0x1ec10232,0xdb0d8fdc,0xd3c3d65e,0x4fe5005d,0x32c916c8, + 0x4c0bea94,0x7f8c37ac } }, + /* 92 */ + { { 0x43ac05e5,0x33ec1e54,0xcd8d3825,0xda4a4da4,0x88bf9e2b,0x86d88c0b, + 0xb53811dc,0x34d71dd0,0xa3c3aba4,0x655040d2,0xb61611be,0x2bc40949, + 0x279a4fa0,0x1c2d426e,0x3b065ac3,0x535a5aa2,0xc52ea890,0xdaa8a32f, + 0x9fddad22,0x5a5deca7,0x2ab3b26f,0x911f05fd,0xf37cd81e,0x5dace7db, + 0x90d16b8c,0x0e0e44e7,0xe4f5894e,0x15e68aed,0xfc92a74f,0xafe04999, + 0x970e7c2f,0x1d7703aa }, + { 0x3f0062a9,0xa8a4c81d,0xd96a20ba,0xe31eb2b8,0x864bd101,0x66dd98df, + 0x4413b614,0xba05f592,0xe9a555f8,0x51a67a0d,0x2e4b52d1,0xacc2f097, + 0x7184ab23,0xab5daaec,0x7c7f691b,0xce08b43e,0x76c427f4,0x520e530b, + 0xe423ebdc,0x7d352069,0x34df14ce,0x6b5e39e8,0x446305ac,0x3dcbf295, + 0xfe34cdc1,0x682cb2e1,0x111f5afb,0xd4ac45d1,0x47f296f9,0xc5ef63cd, + 0x93c20871,0x0a2c40ec } }, + /* 93 */ + { { 0xaf5747db,0x09bc384f,0xc06ab86b,0x3bad6086,0x9e7c1547,0xa406882e, + 0x55977abf,0x2d5326d1,0xda81deb0,0x063a9a05,0x524b6111,0x9a86e4a7, + 0x4ab2eb90,0x1402f87a,0xd5c600ba,0x7d0721d4,0xf289fdbf,0x1a2fd9a9, + 0xecde6f07,0xf5dce66d,0xdab9fa73,0x62171277,0x6c474bab,0x6d2dc49f, + 0x76eed033,0xdc017e1f,0x4da825d3,0xb97175c0,0x54b05e43,0x6c297e3d, + 0x56c9c87e,0x2efb4546 }, + { 0x8b21c064,0xa4712b00,0x4a70629e,0xd186fe42,0x9b74f0af,0x6435b340, + 0x7ec9e629,0x6965aa43,0xc4c60d08,0xdda14673,0xbf3057aa,0x0b656670, + 0x3ce86f60,0x7f05e840,0x04401a16,0xc05073a9,0x294e607e,0x16b1e638, + 0x69cf7046,0x20783252,0xe8ce7d3a,0x2941141b,0x7577053d,0xd38ad8d3, + 0xcaa6630d,0xdba68fb3,0xe9504350,0xecbeaff1,0x1d2d760b,0x9f5166d5, + 0x462891e4,0x337532ce } }, + /* 94 */ + { { 0x3a00bb9b,0x3f111853,0x45f66685,0x2d2ffbae,0xd4aee24d,0x9ae11a85, + 0x0341856e,0x18ba1e1b,0x2731349f,0xa9ac8178,0x545715b5,0xc13dfd4a, + 0x5daad2ea,0xa5f7423c,0x535b76a7,0x30a483b9,0xff873e9b,0x92e9ada4, + 0x723a1055,0x15662d84,0x8edac4e0,0xb935497b,0x39d8fa70,0x61b6441a, + 0x40d1589f,0x1541d756,0xf0a05f0a,0x62994237,0x6bb28908,0xfd8b0034, + 0xd4cd32bf,0x192a2b5d }, + { 0x365ced07,0x63576628,0x05de1d1f,0x029f32fb,0xbf40a7aa,0x6d17b9bc, + 0x9bb50a47,0x1b1b2a08,0x795a6278,0x9389abbb,0xb34fc19b,0x52cff60f, + 0x387d8739,0xf3ab9492,0x6920ccd6,0xa8f053e6,0x63a9b4f0,0x3ef2dd4b, + 0x51e82129,0x9ab0ede1,0x0838bfa1,0xafba0c0b,0x9ffc11be,0x2bd5a7ac, + 0x95cc0878,0x058bfd95,0xf8c2f0c6,0x686d48a3,0x1d9b31ba,0xc33abaaf, + 0x3bc0c268,0x632e2289 } }, + /* 95 */ + { { 0x15a1ccca,0x1c851d20,0x7e522bc3,0x4efe290c,0x18eab053,0x0b741d55, + 0xbc85e217,0xae656197,0x01cf8b29,0xae13141e,0x66948478,0x2e2cb593, + 0xc31bd8ae,0xeb57bb0f,0xc264e788,0xdecef5d6,0x9cb96d86,0x6fa856cc, + 0x279183da,0x2db16813,0x383d796a,0xf03f3820,0x1d0c6fed,0x58a456ff, + 0x8a6abd9b,0x25589805,0x83f96f19,0x339f52c5,0xda7e9ea7,0xcf6ded8f, + 0x5d1ccd45,0x68c3d9c1 }, + { 0xe6b392b7,0x67e26265,0x775d9509,0xcec1d9bf,0xd76514f7,0xe16abcd4, + 0x0de72e1c,0xd86f59b2,0x1adfb033,0xa66e43cd,0x05e457cc,0xdb344340, + 0x5681daa2,0xb67a7916,0xf0114731,0xc32e7bab,0xd3b1e961,0x066fe16e, + 0xf63d26e6,0x924e298e,0x541add6d,0x9bea0dd8,0x9982f971,0xef9500df, + 0xc5f076ac,0x5c876e63,0xb23d396b,0x55e12ae5,0x2ec6747a,0x09efbb36, + 0x233286a5,0x8f2055ee } }, + /* 96 */ + { { 0xb82c1af0,0x4a4ab9e3,0xf2cae264,0xfc65e9e7,0x60187d46,0x4feaac0a, + 0xe393b363,0x27d3f335,0x819bacce,0x9c9f7c00,0xb8aa6611,0x3f7418b5, + 0x372aae95,0xffa94557,0x8db38589,0x937d7804,0x6f1fbc1c,0xd10c86df, + 0xa2f0a0ce,0x48aebd89,0x367439eb,0xae5d5fa2,0x3f17d2d8,0x103a6a0b, + 0x411d9894,0xf233f68a,0x218b67a2,0x7fece8b3,0x2319bf06,0x0422540f, + 0x340d322e,0x1292c8c9 }, + { 0x0386463d,0xf5eb5587,0x0371d97f,0xd4bbc2b2,0x0b819c5a,0x1b364571, + 0xcf04ad41,0x0cbb42d6,0x66939ec1,0x5d819c76,0xa01847e7,0x8745ac13, + 0x1c7232e4,0x4f704b02,0xacb05780,0x2c9e58a0,0xb561e295,0x9523b8b3, + 0x79f9ba35,0x3384df00,0x1eaa9628,0x78231fc2,0x8aea2b90,0xa2eac54f, + 0x30d1c263,0x8075ed77,0xfb339000,0xacb44ed5,0xf011293a,0x92546ac2, + 0xeb821764,0x7c78762b } }, + /* 97 */ + { { 0x067902b6,0xb8f7d6fb,0xd1735980,0xb2823a43,0x59741ddd,0x062cfb12, + 0x4033f95c,0x6e391b07,0x68589b8c,0x3831d0a3,0x522290f2,0xe3474d49, + 0x222e1f3a,0x4dab14d6,0x53f08d39,0x8f00fcde,0x707f28f5,0x559917ae, + 0x068e607c,0x166aa0ba,0xd7e1f824,0x602713e7,0x4d6a328f,0x7c255540, + 0x9890cd2a,0x0d2e3264,0xeca0b20a,0xf2207944,0x52f4e09c,0x5c98dc07, + 0xd84de81d,0x69403504 }, + { 0xe5407206,0xf8b7b366,0x0d88fa8c,0x1ecf54cf,0xf7272e6f,0x6fefe548, + 0x81ab4468,0xd6531372,0x4e474408,0x52cb5f0e,0x6490737f,0x9e426b3a, + 0x4980d071,0x2576c19b,0x0f272caf,0x91f34628,0x468f31c9,0x78e60a4f, + 0x90844d89,0x8776a329,0xb951582b,0x8a55700c,0x14b1adbf,0xab1af365, + 0xfbd343ef,0x22ebff92,0xb7d81f34,0x32f9fb01,0xba6b30e1,0xad850e06, + 0xbc5f9546,0x6da9e027 } }, + /* 98 */ + { { 0x5c9490ce,0x21eee4c2,0x0df68381,0xa96ec4a3,0xa4a9368e,0xe6c607e0, + 0x4bc262f3,0xd8b0492a,0x460c34ff,0x0846a210,0x28df33cd,0xf7ff7a64, + 0x21827612,0x10c55044,0x149bcd01,0x9d25fce9,0xcfc613dc,0x725611cd, + 0x97f51ce5,0x159f7e88,0x4e8c08b5,0x3fa3bf31,0x75e7538f,0xea156115, + 0x91c84020,0xd1e0a951,0xcf02ad0a,0x0d2268ba,0x058b8e5f,0xa04c6ac4, + 0xb3515912,0x773b40b9 }, + { 0x3631cfd2,0x00ff2cdc,0x807737bc,0x14c4c2d3,0x338a5270,0xd600616a, + 0xb32cabde,0xd0e3306d,0xa70b17ca,0x336738ea,0x79f353ee,0xf2f4aa8d, + 0x576f3ad3,0x712f6ad9,0x89b2bce0,0xe4279852,0xda92ca30,0x05d8f94d, + 0xd8492dd9,0x9891d475,0x4d15e4bd,0x3e06a5ca,0x254eabbd,0x4725d4eb, + 0xc0ed513c,0x31394ace,0xbbfaae6c,0x7e0f9859,0x833fd137,0xdc125546, + 0xc56c4f75,0x12b46385 } }, + /* 99 */ + { { 0x932951de,0x810dbebd,0x5aa69c94,0x96959d42,0xecb2f08d,0x5fc49c04, + 0x2250b82c,0xac74f0cc,0x3aec4e1d,0x96a439a5,0x90499acd,0xc33cab9a, + 0x54d9b3af,0x2fccde66,0x3863ae8b,0xf4af285c,0x46febf88,0x2373373e, + 0x3c9ab7ed,0x751d672c,0xfe12020c,0xc1c51130,0x52f3e56e,0xad82402f, + 0xa4a64a81,0x3489ab7a,0xd9f163f2,0x0a1fb661,0x0e553317,0x17c69be1, + 0x7d88d417,0x61c1935e }, + { 0x3492ae43,0x2e722d9b,0x0538f05a,0x1ef89d95,0x200aab63,0xae77e588, + 0xeba4b117,0x2872c120,0x3a461cb8,0x5c2432c8,0xcb938f26,0x315b3434, + 0x8c4c7dc0,0x05bf2ac5,0x596b378d,0xd2e501dd,0xcb890c30,0xa8506c9f, + 0x7c361f0c,0x3d0af461,0x5a35cbae,0x21f7b718,0xf3fc0138,0xbd1035f1, + 0x8b248edf,0x74628af5,0x48c9cae0,0x8d6421d0,0x2ca18773,0x75e3da39, + 0x71d3db94,0x27ad0df2 } }, + /* 100 */ + { { 0x305b5aed,0x9e3bda79,0x5998d6a7,0x2c67d4a4,0x0f7eb700,0xc855e1d3, + 0x147d1c44,0xc18a7e9e,0xc89540ed,0x3ea99618,0x7e6bfd20,0xa53be20a, + 0xecc14437,0xc9487e64,0x34ef85c6,0x72979207,0xd5e1ebd5,0xfa0d4e71, + 0x4d48d6b6,0xfda2b1e6,0x66e200d4,0x782a1e05,0x5a5366a1,0x2a3c70da, + 0x1a473738,0xfe3fbd2b,0x7fe020e8,0xd7ef8c06,0xeacfb665,0xec686fde, + 0x6dd1542f,0x5d9b5e27 }, + { 0xcb3e472e,0x3637c5a5,0x30a1405e,0x2153d927,0xb4498558,0x009992e5, + 0xf39a0851,0x18f00ccd,0xb5c6c560,0x26237c11,0x1343540e,0x418ed408, + 0x7e7f3184,0xfef7cbf0,0xbf48576b,0xecd92366,0xbc94c91a,0x1b75be1a, + 0x4a162276,0x8e1778de,0xc5c6bcb8,0xc52e57d3,0x5ab71858,0x5cc382c7, + 0x3f6e39f9,0xe12c2c28,0xd62735fc,0x4c7e0ef2,0x835a5996,0xe071deb1, + 0xcbb8c766,0x24f891cd } }, + /* 101 */ + { { 0x6778c1e2,0x24ef60bf,0x00d5be5c,0xff49c03d,0x2f01a09f,0xec11986e, + 0xae096e58,0x59a728a4,0x7077984c,0xaabbcedb,0x870ca5a5,0xfb473bd2, + 0x4de30e3d,0x8c928c61,0x4f67abca,0x3fae7f9a,0xec21a9cf,0x83c2b2eb, + 0x9cd9b5de,0xafa70d62,0xc60b18df,0xadeaea59,0x4049b54c,0xd5fef7be, + 0x6dd310e3,0xfceebc76,0x8f6321cc,0x7748efe3,0x18ee8af5,0xfe9c32b1, + 0xd42df612,0x863ac3cf }, + { 0xb85a2fe2,0x0a36fca7,0xee429dc6,0xf3e70d08,0x141c3944,0x8c9ba209, + 0x67272a0a,0x306a8106,0xf968bd06,0xe69a1555,0x153c603d,0xb86f7e47, + 0xef56e4fa,0x9706614a,0x98780b4c,0xc0dc36b8,0x3a1d3263,0x43657fe2, + 0x435522c9,0x01f97a86,0xedfef679,0xd91897f6,0x6daa17a0,0xebbe31d4, + 0x85accfbd,0x6f179100,0x8f9fc1de,0xe0da6e32,0xe1e7142c,0x1c9d53db, + 0x8b86725a,0x3e3f1b1e } }, + /* 102 */ + { { 0x7b7fbf05,0xb7ea15c0,0x1f1a3882,0x992f11b6,0xd1dcd1bc,0xc9ddd95a, + 0xad0f7e8b,0x31f5b7fa,0xfca7ab79,0x2936e5eb,0x19a55be6,0x30f417dc, + 0x43cde554,0x1f6f4e43,0x82f044bf,0x971f5e65,0x4288c408,0x73c3b8e4, + 0xb807f575,0x61aac59f,0x818b58f0,0xa64ee2dd,0x97a3b0d3,0x6f7a0a60, + 0x0394b058,0x8b85ecc8,0xbfb3517d,0x9a059474,0xa79c3f06,0x89ad5977, + 0x700a8025,0x81208ed8 }, + { 0x14c4ce37,0x10935099,0xa1aa48a6,0xf34bb843,0x580d58e8,0x86007024, + 0xb375b8ba,0x6db42c49,0xed3bde83,0xac365524,0x649233b6,0x5521e1b4, + 0x64dd946f,0xbc7cc5d5,0xbfb5b6ae,0x9c14b035,0x0146c1a3,0x7f22ba18, + 0x872214f5,0x0b62fbbc,0xb4921764,0x3acfd7f7,0xcb4d6df1,0x5ff10da1, + 0x62600a91,0x660e2620,0x81d9167f,0x7ac7da9d,0xb6e7a199,0x6e8e260c, + 0x80deb3c2,0x44383fb8 } }, + /* 103 */ + { { 0xe44f9af6,0xe107f01d,0x8cb1fa1c,0x36381a4d,0xfb7dd493,0xe65be3ec, + 0x26a8839f,0xd0b8435a,0x3ec789d8,0xee60f915,0x2bcc5e1f,0xe25fea50, + 0x7e44a81c,0x0477c0c5,0x230ba5b8,0x349e9f83,0xde180dd9,0xdd42f32f, + 0x64a3d11c,0x8b039eaf,0xbeb7083a,0x80ef884e,0xf12742cb,0x288e60c4, + 0x720a0262,0x44156cc5,0x7253b77f,0xcd547de6,0xa6013a59,0x9829a6ec, + 0x0d548445,0x8aee708f }, + { 0x32c54409,0x18f22d9c,0x75ebaac4,0xa9ebfa46,0x86284981,0x90e2e928, + 0x6b3a8e0c,0xd0201f6f,0xbd77641e,0xc973016c,0x70170575,0xf926f2f0, + 0xfec0ce01,0x4984048f,0xf319d304,0xbf696211,0xc91a88c4,0x74b5c844, + 0xe0030a82,0x4c40fbce,0xe4f6d521,0xbed67525,0x29d67d1e,0xaf7e47cc, + 0xc21d3536,0xfa307db8,0xbbb29405,0x56b6c46a,0x033e805f,0xf059a7e3, + 0x6096a5a0,0x970f61fe } }, + /* 104 */ + { { 0x1bec8e4a,0x1bc53d23,0x35a6034c,0x8809ac14,0x509e464d,0x4ee081da, + 0x8a488235,0x496ae1fd,0x325864b6,0xa1ae9863,0x74cd069f,0xbaca13e9, + 0xb1d8a6b4,0x3738cc58,0xe76b9da4,0x5fa71f58,0xc7eb16fb,0xc919be88, + 0xad4e429d,0xf5c8f13f,0x2499f9ed,0x4583b671,0xa10d8bd7,0xbce20115, + 0x5790bb7e,0xf66d7605,0x482b78dd,0x9316aede,0x75f855fa,0xe0d8fb2d, + 0x5a7dcca7,0x404b5b94 }, + { 0x517a15c7,0xf9ee682a,0xef880202,0xaae4cfbc,0x5106a354,0xcee2c139, + 0x170febe7,0x5de60192,0x73d0c54b,0x589e39fd,0x8c9092b7,0x195c7135, + 0x0a7bfe5f,0xcb7ed53f,0xf61cc979,0x2bd9242a,0x5395f7d9,0x8d2ef16c, + 0x70b32f09,0x0d4ac1ca,0x52d185c1,0xa587526d,0x942d6195,0x2932b04a, + 0xa500b0ac,0xfe25a979,0x562fd230,0x5fa1f4ae,0x20da253c,0x60f55af2, + 0x83146002,0x7faa11b5 } }, + /* 105 */ + { { 0x6e402149,0xb0ba4f0c,0x963cc119,0x3584cc1d,0xa6527476,0x7740dc1a, + 0xc95715f2,0x3f77ff75,0x3f89fb0e,0xb2f234ad,0xef9be3ff,0x55159032, + 0x04237e82,0xfc9fb21d,0xa153ed93,0xeb2eff38,0x10041d13,0x89d53ae0, + 0x7f1bd828,0xcf2e545b,0x43953ea5,0xdd4a27ce,0xd85e75c8,0x00d2e5d4, + 0x241be1c3,0xeb93ed62,0x0242032d,0x1e53f25f,0xc3a4e701,0xb9957636, + 0xed98febf,0x14b63a52 }, + { 0x71c43336,0x7610b553,0x23a4824b,0x19dfd4a6,0x0286051b,0x7b97a2e0, + 0x8f5f1edb,0x86abbb9c,0x9b67daad,0x67a57d77,0xcd5ffafb,0x8ace506d, + 0x89ac3c63,0x85da9f95,0x75a3d150,0x081cbaa8,0xe9346ed2,0x03353d8f, + 0xa1f9a02d,0xb2ab61f1,0x3a659c71,0xb0cb0937,0x4f5df8a1,0xb7e0e30b, + 0xeb7d5a1d,0x77c4c741,0x728e5cf0,0x8f046c9c,0xf7c171ac,0x32dd0bc7, + 0x836d2655,0x02485873 } }, + /* 106 */ + { { 0x75a4cd8d,0xcd40dd23,0x97bcba78,0x132ca433,0x258d61f5,0x30c5cd84, + 0xda1e8e68,0x0a7ec059,0x1d65d40a,0x07a8f171,0xf4350d76,0x869e655e, + 0x5983ae42,0xb98ce6f0,0x9d8bebd0,0x7b61391d,0xb1ba5d49,0x3a529e25, + 0x1f6b2cf6,0x46f732e9,0x3fa3b629,0xbd66ec6a,0xc3ef0ed2,0x397950ec, + 0x5f08b476,0xee9008cb,0x965a0e2e,0xfd6be425,0x1177bc87,0x78ed513c, + 0xfe512dae,0x6798cedf }, + { 0x1b97c5c6,0x49e3f8fd,0x78c3b33f,0x39fbab3e,0x40f595ba,0x44274412, + 0x5d7d4376,0x174225b9,0x79c44777,0x880b3fcc,0x3296b245,0xdc3aca83, + 0x1734e184,0x55913df7,0x9c934472,0xa4db23d3,0xd1420a11,0xcebb3733, + 0xf3608bdc,0xb9d20cf9,0x30cfe13f,0xa618acf6,0x5f30874c,0x75f06b31, + 0x9f0005a5,0x506efe7f,0x01bfc9db,0x8aaea78c,0xf78e7c41,0xf9179255, + 0x52e96395,0x3ea7aed2 } }, + /* 107 */ + { { 0x5b06ae25,0x98617e04,0xcb5750ef,0xbcac148d,0x604c2ba2,0x91ea2f0e, + 0x76b78975,0x00c19f6b,0x651da181,0x79b9b6d0,0xc945705b,0xf3225beb, + 0x5c005bf1,0x30b435f3,0xbc24d86d,0x440b4482,0xd6373777,0x2b8f0996, + 0x1c44b4dc,0x65fd6c56,0x30906999,0xe9405ee6,0x08aa1ec1,0x19ff0924, + 0x3d2f2895,0xeef3246a,0xbc746797,0x016c3765,0xd0705f7e,0x62d2569f, + 0x05250044,0x6a8ad39c }, + { 0x46be7282,0xe45f020d,0x21380f12,0x9405afed,0xd5da6ad0,0x4cdca5bd, + 0x7f8be61e,0xc2d6f184,0x596b8178,0x20132953,0x7a8df954,0x8d3b1e7b, + 0x39572b4d,0x757c61bb,0x80cc3b56,0xd749b57b,0x37b3ffec,0x9590ff93, + 0x145dc94d,0x39bbb653,0x2335e573,0x70c1c606,0xf763feba,0x9c2e72d7, + 0xcc61b732,0x4768e424,0xaa73f2ca,0x777d2fa6,0xc5cb58cd,0xdee4dbaa, + 0x9cfae1aa,0x1a181179 } }, + /* 108 */ + { { 0x77575ed0,0x6f6ff62f,0x7d1da99b,0x18f14fa9,0x69efd7f6,0x2e72aefb, + 0xddc28633,0xc45ab4cb,0x586c5834,0xb0e20d48,0x39775dd8,0xd397011a, + 0xf4134498,0x0130c808,0xf5115ed8,0x2d408eba,0x0260ded9,0xc506a05c, + 0x19cab911,0x9e5b7362,0xe8693a86,0x4cf508c6,0xcc773617,0x4e71245f, + 0x95d89ca3,0x2f71aa1f,0x607bbc98,0x4bba7c6a,0x212b7fd2,0xf3a515e7, + 0x9230f5a8,0x7d2ddc75 }, + { 0x4ed2cae8,0x3d05816d,0xb9c00377,0x4cf6bc7d,0x646b08d4,0xc23e98e6, + 0x4b9c0180,0xf9ee6c61,0xef9179c1,0xe11c9a13,0x8ed9688a,0xa5b6147e, + 0xd06670a7,0x7afeb648,0x17685275,0xd670333c,0x75f9e8f2,0xa89dd969, + 0x37a68ade,0xbb57228d,0x454cb186,0x21a05d5e,0x063dd550,0x4810158f, + 0x4cb6caf3,0x92dd4f08,0x7854abe7,0x70c4d852,0x6e729d76,0x845969dc, + 0xb1bf40ba,0x5a52f87a } }, + /* 109 */ + { { 0x09ecacbd,0xed019e91,0x7b89bdea,0x6544023d,0x5707371e,0x7cc51f0b, + 0x16c8e217,0x14832b04,0x81259ab5,0xb1aa6682,0x23e361d4,0x6e100f92, + 0xe3a95c2a,0xe593eee9,0x16c10e26,0x699b6bbd,0x9473a13f,0xad487873, + 0xb274987c,0xf1c14dc5,0x2559e2e9,0x57dc0075,0xc3d47ad2,0x8449849d, + 0xdd527793,0x83df278a,0xeefd5b99,0x770e3ec8,0x76bd02a0,0x2ae58446, + 0x3e705ffe,0x17f02764 }, + { 0x29abea1f,0xdda4010d,0x2407ac4c,0x636b9695,0x0433218b,0x96a60129, + 0x163d534a,0xf221fc3b,0xccc20565,0x05ba15be,0x96285577,0x1238e54d, + 0x878804d3,0x1b144257,0xa89a9fe4,0x96fbf304,0x4be642b1,0xc8a7f06c, + 0x6e2b085e,0xdd1a20e8,0xff4a591d,0x8f7f27c2,0xa4a343b8,0xc17b0753, + 0xbb173d4d,0x684b1e88,0x3dc07bbe,0x3accea44,0x4c441d77,0xdb15c88d, + 0x53e5957e,0x0ef0309a } }, + /* 110 */ + { { 0xfa8e5b60,0x4fc25721,0x691c0bb2,0x646938ad,0x0b0a2248,0xe46d4b76, + 0x7de16877,0x863f9ac2,0x2721c630,0x503bb6ef,0x0b67fb02,0xf8c199df, + 0xe07abd39,0x78c1ed72,0xb32f0dda,0xcf9deb7b,0x6c3c89f3,0xaff726f0, + 0x1972225a,0xb7008b2d,0x4f145f5c,0x8f5a6117,0x457c4f37,0x4e0e6f8c, + 0x1c453c64,0x8bbdaa44,0xa6e92c80,0x57be326d,0x5d773561,0xa9bc3fd9, + 0xbb37b72a,0x3d3b6cc6 }, + { 0x9722c880,0x6e6f12cc,0x286b6889,0x3a1b6ae7,0xad2fafec,0xba1cc09b, + 0x43bb8bef,0xad64ad7a,0x97c3f4c3,0xa5af6a00,0xc353a91b,0x2afcb0d9, + 0x69ccbf6b,0xca13fcab,0xf2abc190,0x699a1391,0x23a247e5,0x2dbd5542, + 0x95488d9a,0xe206180f,0x1244cc3c,0xba9e7bff,0x87d3a365,0x29297abe, + 0xfa4ca5e2,0x4054fa38,0x67be1b6c,0xb390623d,0x78f41a44,0x1fa67c57, + 0xc7b544e7,0x2e946e43 } }, + /* 111 */ + { { 0xc60934ae,0x2980fddf,0x164206d1,0x2c3e7eff,0x416ed75a,0xf75e7f96, + 0x5cd0b2dc,0xfac60cf3,0x1faad87b,0xddc4bece,0x9849e5dd,0x753fa87c, + 0x2c1bf1ae,0xc5d516a3,0x14732b4b,0x565dbea8,0xce48696b,0x007ebe3a, + 0xcdb97694,0x40ca74d6,0x65e4e7be,0x3f5cd270,0x3aac4ebc,0x74847c01, + 0x43d6c3a1,0x6762e034,0x467a076a,0x690d8c95,0x1eda677d,0x768d78d6, + 0x0181d8c2,0x0997ce55 }, + { 0x965a0b81,0x9297746c,0xe5e12dfa,0x48b58be6,0x715f437f,0x5573b3c4, + 0xb565c459,0xe425e907,0x1582797c,0x4f43f512,0x8ea5474f,0xe5dafa6f, + 0x13de04ac,0x2aeb8fbe,0xe8a07c83,0xed7f95f0,0x662c09fe,0x3e012a6e, + 0xc742cf17,0xbf96e9b8,0xe28a1c45,0x8ea5759a,0x5cf4e2f3,0x475941b4, + 0xf901a019,0x7dd3c02d,0x70916b2e,0xe7a4deea,0x2fa9b988,0x50b272b5, + 0xd0917fe6,0x96f9f09f } }, + /* 112 */ + { { 0x2c310a96,0x78e8aac4,0xf7a2a734,0x32a98303,0x23962207,0xc46ca83d, + 0xd9541280,0xad131e6e,0x2cabe911,0x5791fc5e,0x841b6c68,0x50cb77eb, + 0x3d3c8878,0xaff93dea,0xf1007bce,0x06541f1d,0x55cdf1fd,0x4ee729c2, + 0x323e3972,0xe0f71317,0xad4d08c1,0xa2de7a41,0xa35e22bf,0xa9912abf, + 0x89b03325,0xa050122b,0x06514d4e,0x8b9e51f4,0x79d3e0ab,0x423c7aad, + 0x40b8fea5,0x71998e26 }, + { 0xceb6ed78,0x40140fcd,0x18534516,0x653cf377,0xe8d60dcc,0x0450b65a, + 0x9dac55f8,0xce6c1a76,0xae05686c,0x8a96a92d,0x12712562,0x2fe44762, + 0xa4f39425,0x747bcb50,0xfc531fc2,0xf0ec6ff2,0x10fe9ff0,0xc97c3447, + 0x9c792cff,0xfb488783,0x026fb019,0x552c5248,0xd804c290,0x4001a29c, + 0x35c8ca73,0x742b5ad8,0x6ee5dfa0,0xc3781f17,0x3dfa4ab1,0xca6b85f0, + 0x0b0d32ac,0x8389941a } }, + /* 113 */ + { { 0xde067dff,0xc0f062a2,0xbcb80162,0xd4f32690,0x0707a2bd,0x98cd990d, + 0xfae4a391,0x5afc63b8,0xb32ad814,0x684f1b7b,0xf199dfb1,0xb0a2dce2, + 0x48f25848,0x2260e17f,0xc2d5e862,0x7393db00,0x338cf171,0x9e88f854, + 0x02acf522,0x00679429,0x6835af3d,0x19157cb8,0xb8a2614c,0x2faa6f92, + 0x134ec46c,0x04ff95f5,0xfb7a8135,0xcf00626e,0xb37a4704,0x454b3d05, + 0x2694ec25,0x1fbfda31 }, + { 0xc8f69c77,0xfdebb657,0xa3df88fa,0x92a8278b,0xc1fb78b4,0x463b5571, + 0x11c71a33,0xd2066a1a,0x089958b0,0x10c88143,0xcf9d67a6,0xb975c7e0, + 0x73037b8f,0xdaa5d208,0x40bf5861,0x5ee5005d,0x7dba69a9,0x300e6ce7, + 0xc962cc74,0x893c3cb3,0x4cf84055,0x0ac98629,0x225c9d70,0x0a7ef63a, + 0xb91e47e8,0xfe184869,0x8c2f84be,0x1b9d7deb,0xc0e278bf,0x67788915, + 0xc426f19e,0x4f9488ca } }, + /* 114 */ + { { 0xdd51b8ce,0x610dfcd4,0x36230e80,0x08579278,0x36599562,0xedc7ff1c, + 0xe2cae877,0x905ead4b,0xe7967608,0xa1c325d9,0xbd38926c,0x3e39eddd, + 0x5f6f0a4e,0xda92c868,0xf47a0fa4,0xe16f800a,0xe5f60aab,0x50b4db5b, + 0x983853d3,0x3665412f,0x9b79789c,0x64b62250,0x4e0e72b2,0xea560058, + 0xe555c2bb,0xabbd4901,0x17292e11,0x378419a7,0xe174218f,0x6e0b5aaa, + 0x8f796b92,0x688e0684 }, + { 0x313b8f64,0xcdfef641,0x942c7462,0xaef11b7b,0x5c0d8abd,0x067cfb77, + 0xaf4041a9,0x608ea5f0,0x6935210f,0x23d5bd82,0x27917a08,0x5ab904fc, + 0x45d22d21,0x85dbb1fe,0x4d36159f,0xc3d5e509,0x1d39b8f2,0xaebb528e, + 0xf44acef0,0xdd5ca828,0x20c57a54,0x24209adf,0x78f95f44,0x5742b433, + 0xa9337d37,0xd11fa7d9,0xc64cfdb7,0xd66a0c09,0x9bb817ec,0x56e55b8f, + 0xe4c41265,0x1723c7e3 } }, + /* 115 */ + { { 0xdc8b43f3,0x9a6486d8,0x26409e68,0xfc3e0e61,0xd9b46003,0x1889c437, + 0x6284ec7b,0x3a850335,0x6a9dbaea,0x5a3665c4,0xe978933c,0x7bf6941d, + 0x69341490,0x1ed5a510,0x8cb8002d,0x664a7b7a,0x60ed0a59,0x603f76e4, + 0x1f4ebf27,0xc3e06ba3,0xf2c38a7f,0x296ced41,0xcf1db08a,0x2ac18f79, + 0xcde7a3b6,0xc919e882,0xdbf68b06,0x15e77d29,0x4e947cb5,0x21978baa, + 0x7630993a,0x84bf542b }, + { 0xe364f21e,0xc1decda9,0x012e557e,0x0d6cf345,0x588f90e1,0xba246848, + 0xe3b104b8,0x9f6dda4b,0xe3aef57a,0x6bf7a346,0xe8327ea9,0x210299fe, + 0xda95e6c7,0xaa99f487,0xd2cdf645,0x24ff813e,0x8bd414b8,0xd1dbb2d2, + 0xcafa1a61,0x065101af,0x9cdebda4,0x7d9f4b9a,0xe41039e4,0xaf41b395, + 0xc50adf42,0xe3e9e6ba,0x341e9e49,0x4f2133ae,0xcb157f23,0x4968c0f3, + 0xda068153,0x383f827b } }, + /* 116 */ + { { 0x6583ff4c,0x2ec46a21,0x4ad709e7,0x4e645a29,0xc04ca12a,0xdc66e9cf, + 0x9160a7e5,0x82f128f4,0x569c762e,0xbfb227b1,0xc2edb8e7,0xf80c7963, + 0x49a0f688,0xa7dafe06,0x2d14b8cc,0xb7e41754,0x86de40be,0x3a0c5c53, + 0x1db79331,0xf0d05286,0xfbfe071b,0xb902ce69,0x210e9903,0x61e46956, + 0xf703ebb8,0xfaef874e,0xdd5f78b6,0xf668947e,0x5af5ea3a,0x6fe86547, + 0x43f94625,0x3b121f15 }, + { 0x659275e9,0x5b26e847,0x6d0fce50,0x47581cfd,0x8aa3f1ef,0x55f5cbfd, + 0xe484e60e,0x1e7be315,0xfe9698e4,0xd8f1a20f,0x7ab04784,0x25d46da9, + 0x834cdb3e,0xa526db75,0x8d08a009,0x1fd408d9,0x5b5ca816,0xfc004b20, + 0x65e4bbe8,0x5b3e3bb3,0x759bb6ef,0xf50cc125,0xc2fac737,0xf05fa817, + 0xd273951a,0x9ee102d2,0xfecb3367,0x2a8e540b,0x2a6a515f,0x673446fb, + 0x37290c83,0x5505e1d1 } }, + /* 117 */ + { { 0xd15e68a6,0x0c3014a1,0x64dd35e5,0x6f9f0b26,0x03ad67f9,0x18c3742d, + 0xd2c14484,0x74818c0e,0x0d41a3cb,0xc5181169,0xc49f3e9e,0x65c8c83f, + 0x2c279386,0x9b260c61,0xced04e9c,0xf6086fae,0xfd7c4758,0xa7b2cceb, + 0x90297fd8,0x4b3c3133,0x09701ac8,0xca8264e8,0x508b3762,0x9f976a87, + 0x983a8dfe,0x5d582714,0xd9d598e9,0x350d2669,0x0f6fd348,0x85cb89cb, + 0xa574317c,0x617d80d4 }, + { 0x70022b67,0x4cef267e,0x3768b94a,0x80536bb5,0xd2784462,0x3153a566, + 0x38243919,0x49054d44,0x5df78c4a,0x8d11e172,0xd5a1e35a,0x9b252a71, + 0x8171e31d,0x07866c80,0x1b38a00e,0x0a8501db,0xce770236,0x2ed932b8, + 0x8edaf7d0,0xa2d77609,0xb93006e9,0x3aee5dab,0xbbfeb036,0xfaffc8c4, + 0x4e21b38b,0x077b9678,0xdca8e069,0x491fc59f,0x0e938471,0x3f624f55, + 0x7cd1780b,0x5156f508 } }, + /* 118 */ + { { 0x0206e8d0,0x58234e22,0x7f15af32,0xf5f6f5d4,0xd638950f,0xafab7289, + 0x7d4495f4,0x66ec4d09,0x68da80a9,0xad890c5d,0x64f8a36b,0xe4aa0920, + 0x0f4d5c5f,0x799e257e,0x24495e31,0x44c677ae,0xa5b8e352,0x720387b3, + 0x75a287b9,0x703790f4,0xc3c1f2f7,0x54895cc5,0x41a7fa41,0xb8680f9b, + 0xb00b008b,0xfcd47458,0xba6473cb,0x149cc838,0xac9be19a,0x78ed5f7a, + 0xb33765ba,0x5254599c }, + { 0xa21b54c4,0x08739679,0xb6497d9d,0x029ece2a,0xc8488640,0xf14f1a92, + 0xe9fa79d9,0xae48dcff,0x46c208db,0x14b911c2,0xdae3f69e,0x5ab0fbf2, + 0xd1edb838,0x180ac87e,0x188586bb,0x146fd718,0x5467cbd0,0x210eb654, + 0x1667cfee,0xaa239408,0xb73d1a60,0xdb125c1a,0x881c1cbe,0xde685300, + 0x37c30232,0xfe34c713,0x6f3c8d18,0xc6c6070e,0xb4af4e83,0x07e365ba, + 0xdcf82b45,0x22f0a7ed } }, + /* 119 */ + { { 0xea7f1b7f,0xe262791f,0xdcff09d4,0x9c3d8c5d,0x39c7dc58,0x86c2a9c3, + 0x4276e8c0,0x4dad4017,0xe9fe1d56,0x0a918f59,0x2aa810c9,0xb8d79670, + 0x4aa5cdc4,0xeb7a8836,0xe7afa72e,0xfc4c23bb,0x4ac86908,0x4dbb5c9e, + 0x6a0c7e6f,0x37e39013,0x49c218d2,0x855d7001,0x94b324a2,0xe475bc67, + 0x6287a071,0xc98a8dc6,0x5fb4323c,0x395a299b,0x0c0389e9,0xe186c3ee, + 0x16734c46,0x79f81e6f }, + { 0x364f3c4e,0x83f2c1f3,0x1367e14b,0x536b2ac5,0x5933e43d,0x44a6dcfc, + 0x10d961fe,0x34e59475,0x7e3f2aae,0x08234ece,0xbdea7f25,0xcb92e00a, + 0xa791a124,0x1efba4f0,0x1192d53a,0xc2086fd2,0xb51c8af6,0xfec0d0fc, + 0xdc0f1b5f,0x48d1b2ca,0x812dbe19,0xb07a388f,0xdedbdd45,0x40873a6a, + 0xd702589a,0xbc2a1268,0x17e27b64,0xbbf6e3a8,0x6d386e85,0x73ee5663, + 0x9de7c000,0x442ecd37 } }, + /* 120 */ + { { 0x8a2f90a6,0xb4cd1ae6,0x6f5ad0cc,0xf277d41d,0x401d4b8e,0x6a3828c4, + 0xd8376631,0xe817a134,0xf5e1124b,0x142b758d,0xfd6b95e4,0x25fbc69d, + 0xd74a9e3e,0xa30c9f5f,0xd89663ce,0x5ac0f163,0x0ce6386d,0x32a9eef7, + 0xd8ed5544,0x7a690ea5,0x9889427a,0x5de23ff0,0xeaaced58,0x75ad36a5, + 0xd3e18465,0x3514a6c1,0x7f093910,0x3d9162c3,0xe33d56e8,0x5c10add9, + 0x06aa691e,0x85176b73 }, + { 0x28a21e38,0xa32110fa,0x5773d538,0x97b6379d,0x2d020dc4,0xd3697bbf, + 0x961833cd,0x59177593,0xe5fa8516,0x6d7045fa,0x786ab5d2,0x3390f29a, + 0xdc4f5b70,0xac0bda30,0xdcc615c6,0xcca0240a,0xc5146d91,0x8e1f1702, + 0xa72cef87,0xceb472d0,0x0b669ba1,0x84840708,0x7e61aa0a,0x79b08f9d, + 0x4669560b,0x388160be,0x948eb71e,0x23935c2d,0x9431590c,0xd7fd83c0, + 0x6e5768b3,0x8ab154bb } }, + /* 121 */ + { { 0x353c4a96,0x28686003,0x905cd835,0x4e5c60e8,0x8f66f8cc,0xbd591364, + 0x9faccf9e,0xb6b80b98,0xe32639e5,0xbc1c1fae,0x278aadeb,0x2f6396d2, + 0x1898202d,0x00a796d0,0x3a474835,0x18ab548f,0xb31b0e3e,0xacd056c3, + 0x0164512d,0x15ba68dd,0x4b03f3bc,0x203836d9,0xd8f206c5,0xd64eca6b, + 0x9f1779b6,0x931a361e,0x52ab34a8,0xd82690fc,0x92922e22,0x342bb8e0, + 0xe00b02a9,0x1bfcdd84 }, + { 0x75a365d9,0x310b9a43,0x08d8fb03,0xd4ade15e,0xd742df83,0x9c9753d7, + 0xde318742,0xcf7309d4,0x3360ace0,0x1228e212,0xf7669643,0x1043d238, + 0xf90f5a53,0xfc2adbed,0x7b5f9397,0x41d64cb7,0xc446d010,0x5200b30a, + 0x231720fe,0xc3c8642d,0xb9aa2075,0xfcc0122d,0x041eae47,0x856e3b12, + 0x68c876a4,0x45864455,0x233606b1,0x1a1c7842,0x227757bf,0x9b766d1f, + 0xf7b9d4f1,0x25b78a3b } }, + /* 122 */ + { { 0x156707ce,0x90835718,0x4314f90a,0x9bdc2398,0x8be57dbd,0x017c885a, + 0xad63a4b8,0xd4bba225,0x15aacffd,0x5ce71b86,0x72954722,0x5f266475, + 0x4f0ad3dd,0x0a80f1f7,0xfc352ed7,0x010538a3,0x4203c6ca,0xf8a64045, + 0x330c73b4,0x2b2c7a88,0x02dcac1b,0xb3433ee6,0xed2b17c7,0x2e0499cf, + 0xbd6329c7,0x9f8681a4,0x36fadc37,0x38979946,0x92b7895b,0xdc5650c8, + 0x65a51cf0,0x70ab9570 }, + { 0x7b585d93,0x46778ec4,0xa633fe4e,0xca6d3610,0x4ea0311a,0x21da154e, + 0xbd64002f,0xaf22190b,0xd91cb7a9,0x9e633ac7,0xee6837d7,0xed13c31f, + 0x1616ee8a,0xda4a07d7,0x3afcd616,0xd78a2732,0xba14d694,0xc06696e5, + 0x4df58420,0x733754d7,0x2778e3c9,0xe85e504e,0x55b5a5c2,0x3055aa0c, + 0x8a3acb5c,0x313df538,0x2a088eda,0x5896acb5,0x84c85dde,0xfc8842a0, + 0x51dde6be,0x5fec9f79 } }, + /* 123 */ + { { 0xfe519f99,0x5ebc2c7c,0xe5410353,0xe396bd80,0x8a3988f3,0xaded9402, + 0xd601bda1,0x1c03b735,0x14ce64ac,0xfd302036,0x01240290,0x5837ebe9, + 0xa554097d,0xcaaea1a3,0xb0b88139,0xdce73d25,0xecb090b9,0x35ed412b, + 0xd63dab3c,0x99029ff7,0x062db071,0x555437d9,0x42a4c11d,0x277d2f56, + 0x24fc9109,0x477fa645,0x2799254d,0x7b12e9b7,0xd84c618c,0x7ad2ae22, + 0xce8ed195,0x0a8d5663 }, + { 0x0a21fde1,0x43ac5163,0x6903d849,0xcfcf5dd6,0x5fdd6281,0x6d2499ee, + 0x77a49a34,0x4dedc6f0,0x2875c06f,0x46bda2c0,0x347b8046,0xd0e0e0f6, + 0x5e67836f,0x1058169b,0xde8a8042,0xc961912a,0xa93b3d32,0xdf3fea0a, + 0x0c576bc5,0x9f138edb,0xd8d37e47,0x7971ad6e,0xcce5e7cb,0xeab85739, + 0x1d202b40,0x88a4b434,0xe3a1fd26,0x5d842557,0xb3a86f91,0x872fabd5, + 0x6aa4629f,0x95b93493 } }, + /* 124 */ + { { 0x99f951de,0x9998a701,0xf058db45,0x8fade596,0xf3d03dd3,0x4d479c1e, + 0x33b141d3,0x6e928d5d,0xacfe8a40,0x9a465800,0xc1cefa3d,0xd108ad2f, + 0xe013726e,0x64b96921,0x8e83bb9f,0xb9b6a6b6,0x1242e544,0x29f1e6dc, + 0x2f65966b,0xd3f8f676,0x5e105b41,0xa34dd096,0x16011e1c,0xd4e9139a, + 0x2515541b,0xeea4dc68,0xc822166d,0x6f8030ac,0x31d16124,0xbdc7ae1d, + 0x621afa7d,0x2e25ef51 }, + { 0xdd8e7357,0x2533cf8f,0xeaceddb8,0x333ba218,0x0784d2ac,0x68e3e31d, + 0xf2804ae2,0x1c927f36,0x77e7ad7e,0x01433d22,0x587f78a0,0x0b401cf0, + 0xaa0027ae,0x9dfcf036,0x1d9a46b5,0xc9e46c8b,0x1f288d32,0xaa6de486, + 0x1b8a043d,0xdd56da2f,0xf2d0bb56,0x346230e5,0x19defb56,0x19f0b6e4, + 0x21d2c874,0x55ec37cd,0xb70e45b3,0x3dbf0397,0xac7ce852,0xf0862a8d, + 0xe141f3d6,0x87979ea7 } }, + /* 125 */ + { { 0x7f1c747f,0x9b7e7b3f,0xc6e63369,0x151a4c1d,0xb372dba0,0x4273ff70, + 0xd3ee54fe,0xca6d2234,0xd33cae0f,0x12fc8e0c,0x5dd6f10c,0x27328538, + 0xf01a9cf9,0xc86f3fbd,0xe36cae91,0x5322677f,0x2fefea44,0x39a70033, + 0xce8af217,0x2c9ca328,0xf6a731f4,0xc0256776,0x66a96813,0xc687b3df, + 0x8db2eda8,0x194aab12,0xeec4febd,0xde30dc5a,0x979241b2,0xc052236a, + 0xc23d4c16,0x3ec98802 }, + { 0x4072f74d,0x0f9e760c,0xab594059,0xe78eb0de,0xc9b009c2,0xdb3dea40, + 0x38b59ae5,0x47e875f0,0x2b4daa06,0xf40eb436,0x090f3788,0x9a6a4f92, + 0xedbfaf8b,0xefebe9af,0x9867e256,0xf87f96a5,0x75ab6aeb,0x1e6fed23, + 0x3fdb13cb,0x17f2782a,0x70fa2621,0x5102c71e,0xfd4c0dbe,0x5d2b06ec, + 0x30347297,0x537cc268,0x2b67e780,0x8dbf5e2b,0xba25da32,0x2f633f3a, + 0xefaec914,0x3e9315e8 } }, + /* 126 */ + { { 0x239a9ea9,0x9255cfa5,0x0be33a62,0x20f3c690,0x9cb642bd,0x759eeb4b, + 0x00bae718,0x3316c546,0xf3410f84,0x874a76d5,0x90f129b6,0x123b502e, + 0x12851f1c,0xadc8f9a8,0x1b62408c,0xf57b764a,0x1a80777b,0x116ec01f, + 0x1f0ddc5c,0x746ecef2,0xe5a6a5a7,0x3c49d47c,0x06e955ba,0x1e15dbe7, + 0xb45d79b0,0x629c0c79,0x778d1087,0x11278308,0x8c6a22d7,0x22585dc7, + 0x0a682791,0x2ed02a0d }, + { 0x4daa2682,0x53043416,0x01359625,0x0e26d32b,0xbd867097,0x449c834a, + 0xee77ae2e,0x11a19d2b,0x3af6c169,0x39bd529a,0x5cd61054,0x36cca5c0, + 0xdc6c0fe1,0x6370a59b,0xb93d5135,0xca420d27,0x554c451a,0xd8730d45, + 0x96cdebf2,0xebd258c9,0xa50f9a05,0x0cb1b990,0x7b0f0151,0x69a8c97a, + 0x11d217e1,0x2cc36d34,0x752f75e8,0xf117688a,0xa09b2a61,0x1db01394, + 0xa9efd7dd,0x14627844 } }, + /* 127 */ + { { 0x232803cf,0x6bca3aed,0x9a96ff34,0xc1e4398b,0x74ab788b,0xcaf6757f, + 0x7e68c04d,0xc3a53e00,0x5cb7cd20,0x5f969c19,0xdc068bca,0xf28b65a6, + 0x1d863032,0xe3ca01d3,0x87808e14,0x9b733b81,0xefe618be,0xb5d704d9, + 0xb01b946d,0x276f3542,0xfbedddbf,0xe057e19e,0x903275ce,0x7d182f2b, + 0x880f7bc6,0x3cdc5f77,0x78476c14,0xd6f03d3f,0xa9ba5072,0x035f5557, + 0xb4029628,0x7acb57b6 }, + { 0x44e6b07c,0xd2413569,0xe1c7345d,0x451c4cc9,0xe273b9fb,0x407444d8, + 0xb88e34fc,0xfe496079,0xf152776d,0x77d184cf,0xc742299c,0x6d1033b9, + 0x77bf2897,0x29a0a684,0xee8f0420,0x59ffdf10,0x44bb56d6,0x4e17146c, + 0xfb9ae855,0x831d06c2,0xd93e7cd5,0xb2cb82db,0x3c96b607,0x83381c46, + 0x7549e2a8,0x06aed251,0x774a21d4,0xef97891c,0x8675fbdd,0xae9807c7, + 0x6363516c,0x6a5a05b9 } }, + /* 128 */ + { { 0x6a8f4f33,0x92e71ea6,0x4dea8f4a,0xf2fc6fc6,0xfee88461,0xd356252c, + 0x08954d08,0x59b0a83e,0x468ab766,0x5bd68c23,0x900f8d04,0x40281357, + 0x52b867ae,0x181c19c0,0x18764c41,0x986a5169,0x13575d24,0xcb01dfae, + 0x593677b7,0x17269ae5,0x46dc9b19,0xf6d17025,0xc40097c8,0x8de68499, + 0x259c407b,0x76df0032,0x17d29d8b,0x4091aad9,0x4a7ab5f6,0xa7f46d21, + 0x70ece48c,0x688054b4 }, + { 0x51a5b86c,0xf0d168aa,0x95777247,0x2437e4d8,0xf1720329,0xae844076, + 0x9647a54e,0x0a7ac87d,0x0405622c,0x1e597a4b,0xf0a79f2f,0xedefe5c6, + 0x4d55156d,0xaf3ef0c2,0xef047cf6,0x917fb04e,0x54b62137,0x3792799f, + 0x314be0b8,0x875ea32f,0x0c466b0c,0xe157c65b,0x7e218978,0xd28c90ce, + 0xcde587af,0xb90fc3ba,0x8b877bed,0xdd32d71c,0xca8e10cd,0x3b432200, + 0xd94f6e53,0x0021f419 } }, + /* 129 */ + { { 0x43519d26,0x2191122c,0x40a51845,0xbdafac1d,0x548bb89f,0xcc6f71e9, + 0x16844bf9,0x9ef3375c,0x178e8d55,0xe7789f79,0x1f8be1c5,0x04f599b6, + 0x2cbbde40,0x8088c99a,0x893206c9,0x8939a260,0xfcd30851,0xa1ae4bff, + 0xe08feafe,0x664cb3fe,0xff14aabc,0x61f38099,0x2a841ef9,0x0d8394cc, + 0x17f01db6,0x75fad8ad,0x6debb773,0x6fc34576,0xa4252512,0x1e716b05, + 0x29e1ed9f,0x79855880 }, + { 0x95106473,0xa2cb3aaa,0x5a61da04,0x95fafa41,0x539563c0,0xfd3c9362, + 0x95312b87,0xbaa48091,0xbf885c76,0x6c7e7582,0x230c78d5,0x70f6dab6, + 0x7747440d,0x8ce3051c,0xffdb6186,0x6dbebd14,0x190e4096,0xb0e041fa, + 0x6ee62e2a,0xba10c466,0x74f333d6,0x93d57e2a,0xfe7b9b66,0x006aadc4, + 0x06d2837d,0xfaf72f6c,0x910741ea,0x318cc5e6,0x65692477,0x9c502609, + 0x1d0fb08d,0x95d823c3 } }, + /* 130 */ + { { 0x140528a5,0x6aeebd86,0x53979bc8,0xf268c2ba,0x4ec144ab,0xb1bc9b8a, + 0x82a7d7ed,0x1efabb0d,0x4e0118d8,0xf12c70d1,0xa1c1558e,0x31607168, + 0xe4b7e73e,0x33e428b7,0x83aec9dd,0x63176637,0xe12ac35c,0x5172ffbe, + 0xbc17b2a4,0x37df0bfb,0x741f812a,0x4212f870,0xe2888f9c,0x3dcecbdb, + 0x756ca55d,0xa9dc15aa,0xb9028e41,0xf31918ec,0x6aeadb03,0x7ede0285, + 0x78654f54,0x0e2708d5 }, + { 0xcde20f88,0x2270cc53,0x5f5b1039,0x9338272c,0x5dcb1dbf,0x5042e19e, + 0xb72d74c1,0x4b3de219,0x2aaaaa55,0x16c49a8b,0xbba86ba6,0x008443e5, + 0x20cf1695,0xee6bcd72,0xa89abd11,0x59ffac6b,0xf115639d,0x2831217b, + 0xf34cba52,0xe4d28af2,0x0727a906,0xf27f03e7,0x69017766,0x6842c79f, + 0x7a81123e,0xcb3469bd,0xa42973b8,0x48c0f346,0x23990dbd,0xfc5784a6, + 0xfb299678,0x0d3dab3b } }, + /* 131 */ + { { 0xce29c3cc,0x8f8376e6,0xf016cbc6,0xcb0507ec,0x5e394ce1,0xdebff996, + 0x73c50d41,0x24fc526f,0x2d16ce3d,0x4edd5a54,0x91c13141,0xbb37bdd9, + 0xe33a8606,0xe3442ef2,0xc0629da8,0x2ae90337,0x592ab331,0x57faec64, + 0xd82b857b,0x1a938997,0xa3373176,0xad6c8cb9,0x9086751f,0x82595de2, + 0x18c17196,0xa81e97fb,0xbf697357,0xe4f48a13,0x5cb89f69,0xa1387c2e, + 0x5874b426,0x530b4eeb }, + { 0xbab7b5ae,0xe9f275a1,0x03a57bf4,0xbb69dc4d,0xa45c505b,0xc974dc4a, + 0x416ac402,0x726369f3,0xaed985dc,0x735e4e78,0xcdd446a1,0x0548d879, + 0x9e16b02a,0x84ceb069,0x789b11a6,0xf73f6fa4,0xb2a4e784,0x6aa0c41f, + 0x93a9b697,0xb1f76902,0xf03a8ab2,0x814cce00,0x844d66c1,0x64cb255b, + 0x30952201,0xb794e7d6,0x3da32271,0xe052d4e4,0x08b6a4d9,0x5278b2e7, + 0x80c6577f,0x90942552 } }, + /* 132 */ + { { 0x0d5b4c2f,0xd269a14d,0x5c8a649c,0x2b8fc59b,0xb0e37d4a,0x95becb3a, + 0x9111037e,0xfda1a768,0x94e35322,0x5810e05a,0xa178fafc,0xa24dcc12, + 0x8e3dce62,0x5c2c63b2,0x9452c444,0x995c3f17,0x42d45161,0x35330ec3, + 0xb4ef8129,0xa025a60a,0x8bae9c13,0x85493252,0xe2e3caf8,0x25d1a606, + 0x3649bf47,0xd44091ab,0x704ec5f1,0xc7d0afbf,0xbd8b3333,0x27bd1d62, + 0xcfe616f5,0x50570111 }, + { 0xf534356b,0xd0084ace,0x4b4b0fbc,0x9df1de05,0xcee04dc1,0x021afe05, + 0x361b78e1,0x64bde688,0xef78d38b,0xa324fcc7,0xeb0a5e4e,0xfeb372ce, + 0x65811996,0xef04fcb3,0x5eb0ab4e,0x7dce5d50,0x238c586e,0x1e29b588, + 0xbcd80037,0xde5e3197,0x4806b9cf,0x8bf5e451,0xd18e67ab,0x4330968b, + 0xf9f63fad,0x26a7d04e,0xb5c18bb4,0xa1c7f123,0x25dce22c,0x485b8482, + 0xd540e79f,0x8ff0b36f } }, + /* 133 */ + { { 0x3ff42cff,0x99f2e2f4,0x1c35317c,0xa3c19f9d,0xaba1b545,0xdb749392, + 0x4afa9a32,0x84232b05,0xd7dcd436,0x0b855d46,0x45cf9915,0x8ac35e20, + 0xf001a218,0xd7cf22c7,0xed408305,0x057d35ae,0x553ccfcd,0x25a4a519, + 0x93e2b939,0x5e565793,0x3422ec27,0xa20332b0,0x3ac53958,0x9b09005e, + 0x79e9b163,0x628051a3,0xfc6618d6,0xb4a0dc09,0x6748e7af,0x9e0e857f, + 0xc577d63e,0x71b28eee }, + { 0x99726bf8,0x4942b0cd,0x1c208f3c,0x1290a3b9,0xb0598eaa,0xfd7290e7, + 0xa25a9128,0xc6a7791f,0xc037d7da,0x2d33db24,0x70e2837b,0xc21efeb0, + 0xe3dae2a0,0xbf70d96e,0x85076027,0x43ed8191,0x4d4ad7e3,0x4aeb0aa8, + 0xe8c5b74c,0xbc75101f,0xad26ebdd,0xdbfb2a6e,0x6b78aa4e,0xba812068, + 0xe1159848,0xc94aa8f2,0x3eba5c4e,0x0d10d9db,0x6318295a,0xce7fec47, + 0x330d925a,0x7294711a } }, + /* 134 */ + { { 0x32bbd495,0xfce45904,0xbe54973f,0x330f4dd1,0x5d9c3f4e,0x006bee1d, + 0x59ba7204,0x40ee6078,0x42c2c768,0xc194fd3f,0xe9fe88be,0xa0e76b12, + 0xec2b0210,0x17cddddb,0x00811ec7,0x689d436b,0x284be9e4,0xa6a6ba37, + 0x007d4114,0xabc395b2,0x0f11e744,0xf8cdf9f3,0xe9396402,0xc5febec8, + 0xeeb46285,0x8a751743,0xc6e0d137,0x99bf8782,0xbeb292e3,0x3965e170, + 0x5801fd5f,0x001c39d8 }, + { 0xda4a0912,0xf4805cb9,0x4410bca4,0xd27cb76a,0xec71d65b,0xef3dcb8e, + 0x4816849a,0x780fbb2b,0xa8b24635,0xef6a7026,0x12c44e68,0x15625c88, + 0x4d7a74a8,0x624c232c,0x4b1631e4,0x81a77037,0xdb917c2e,0x04e4f7f1, + 0x1f61ed95,0x1d0465fd,0xcbde6e3d,0xb1048049,0xd7131fcf,0x637ce0c1, + 0x8ada4715,0x22e4dbc2,0xace99726,0xf7530c5c,0xee287450,0xa0160dcc, + 0xbb91af13,0x9132e670 } }, + /* 135 */ + { { 0x7996099d,0x8057efe2,0xa06e608c,0xb72344db,0xd0958588,0xeb4a8740, + 0x79e5aee9,0xe53daf06,0x908a2fad,0xc9560a9a,0x107e706a,0x7f4be131, + 0x2830246a,0x6d5f3d9b,0x27cca3e6,0xa5f8e8da,0x4c28f292,0xeb51dca6, + 0xf31dfd78,0x4cfa310e,0x2ca073e5,0x92e0c7c2,0xa40da683,0x102f1694, + 0x750d38fc,0x16bb07cc,0xbadae035,0x703e83e2,0xb4d3c9dd,0xea93c066, + 0x79940ed1,0x7d0b03e5 }, + { 0x4dd94c63,0x5fe7ea30,0x738b0b3a,0x57ef01c5,0xa14e6b4b,0x9534a78c, + 0xa5353276,0x07622cde,0x7c22d006,0xaf696a07,0x7d46b209,0x733c1886, + 0x626c2b4a,0x9654ccbb,0xa84f3c4c,0xa098d3a1,0x2d734b74,0x3596f9ed, + 0x5d551c90,0xdfd3021a,0x1ec5123f,0xe2ba7d2f,0xb2c1aa39,0xf9726925, + 0xf8eb2927,0xd2e75d0e,0x19192a6f,0xfaba712e,0x9b83e50e,0xa606b43a, + 0xdab5de60,0x31b1782f } }, + /* 136 */ + { { 0x4034db92,0x878dba45,0x8f34dc4d,0xa3977901,0xdf754c33,0x8d004f2e, + 0xcd563a88,0xeaa5954a,0xbb5ffad1,0xa29d6c89,0xb0d8bdb8,0xa8adf655, + 0x8cdbdb47,0xf7fb842d,0x80d3205b,0xb72e3a03,0x7cac7ca9,0xc335b0b2, + 0xd8a5475d,0xffc60bcb,0xeba4d25f,0x736f7719,0x0c50fca6,0x3d901c38, + 0x80c01900,0x1fdacf7b,0x5681f84d,0x75cf658f,0x5cefbbc1,0x57a7e634, + 0x3e07ed1f,0x6fc0fbe5 }, + { 0xb81b0e5f,0x496d116b,0x2ac853b8,0xd82dd2a5,0x327387f0,0x357e22d4, + 0xba912c59,0x3e332a84,0x49d5dcc1,0x8b71c643,0x438d85d3,0x0c982ee9, + 0xbf7fcd4e,0x90b9553c,0x38fed5e3,0x2cb39bbc,0x5ac42903,0xa2c67c9c, + 0xbf07da55,0xebf21217,0xa0b9e4ee,0x55ac05ad,0x8ee9e0c6,0x10bb12c2, + 0x48bb6e3f,0x5cf3aee5,0x8b046e91,0x4ae7269c,0xaa0e553f,0xcb266012, + 0xa94c8fc8,0x701935a1 } }, + /* 137 */ + { { 0xa4626dea,0xde58d41d,0x15b9039f,0x25ef66ca,0x3164e65b,0x99a810a4, + 0x748cfccf,0x9fe6daad,0x2f142fa9,0x7ab9a6bd,0x5d471796,0xa4cba168, + 0x6bc3a39b,0x12d30b36,0x8bf45076,0x1f46a5dc,0x1421ac0e,0xb868e529, + 0x59bba1c4,0x7a686206,0xda698b90,0x2b4b552e,0xe5453707,0x5039dcd4, + 0x9e90165f,0x42a07a9e,0xd7d45dfc,0xa838fff3,0x3b5ceb30,0x41991e5a, + 0x969ca600,0x6c961ec8 }, + { 0xc4e7eb46,0x703bdc1b,0x596c7b48,0xd6bac557,0x66afd74d,0x4f9917cd, + 0x656ce6f3,0x56355105,0x32497175,0x3d1fb50c,0x63effb2d,0xfda6783e, + 0xeefaa2bd,0xbd79f1f3,0x17af9ef7,0xa4efbe54,0x5a55b7a4,0x6cef6462, + 0x1a713304,0x116f3238,0xb95625a3,0xdb2a2a7f,0x0b027e96,0x6a0aa43a, + 0x4832b3bc,0x458fe5d2,0x5adfaac0,0x523418df,0xc49e7f9a,0xc05a89cb, + 0x69e24b53,0x830883d8 } }, + /* 138 */ + { { 0x02557389,0x959b1c62,0xadefc0bc,0x5fe5ce97,0x8330f383,0x893bbe7f, + 0x16cfb81e,0x27e0c6af,0xd04428fd,0x6f64e65b,0xb79e6182,0x53de9245, + 0x487e11ca,0x08a313c1,0x445bce93,0x65cec3b9,0xd67ed49e,0x33bc0314, + 0x30782352,0x69f36b24,0x93ad31d2,0xd78e5daf,0xc780890c,0xf2682b70, + 0x9e45efe9,0x7015c34f,0xe6cbafea,0x135d4ba4,0x7e3fcc6c,0x43a378a4, + 0x96638f8c,0x2376f97f }, + { 0xae575b99,0x0a6e1ec0,0x81b970dc,0x7e14cb4f,0xd3a73947,0xf00a3824, + 0xfb235a9d,0x0b4b9c81,0x5bf62944,0x8d15115f,0x1e165d7a,0xcfd35b43, + 0xb2ee3e3b,0x5d12fea2,0xf5182e7b,0x629984a6,0xc365d08e,0x4e43e2f3, + 0x30f36e72,0x99327091,0xfd345401,0x698b4a00,0xbaf96dce,0x23c4fd0e, + 0x23675554,0xa60ba0ae,0xb0325784,0x51bdac2d,0x215464a1,0x8ab4190a, + 0x6bf10296,0x8c461661 } }, + /* 139 */ + { { 0x2d1f36a5,0xeffca258,0x894c5f2d,0x0eded2b2,0x43ced84f,0x35a5cdb8, + 0xdb0e3b9b,0x290f8982,0x0719a112,0xcce0eaf0,0x39a362d6,0xd0e657e4, + 0x62697e47,0x5516a55d,0x8e636514,0x269e1f77,0xd50269bc,0x5e3dedcb, + 0x441c57c5,0xecec2300,0xc705578d,0xdb83f31c,0x1e489eab,0x1bdefb73, + 0x395fcdb4,0x20b678cf,0xff9db001,0x908cf91c,0x55f52cc8,0xcbebc6f4, + 0xb4c61162,0x155ea622 }, + { 0x876fa42e,0x94be2f1f,0x7fadeee7,0xab5e8749,0x38c865af,0x692e70f5, + 0xdf8059b0,0x16e99b84,0x8b5a7ac9,0x0ceb606e,0x2d463d2b,0xced23357, + 0x2a9a09a0,0x2d0f2623,0x3861fbdf,0x2529998c,0xc1be310b,0x711888a7, + 0x0d8aade3,0x9b1229c5,0x3b13533d,0xdbcf9b78,0xff029708,0x3ca746f8, + 0xda83ef88,0xa5a013a1,0x4ab28444,0x8e904d18,0xbcbd4aba,0x2fe84b3d, + 0x259058c3,0x8f570f24 } }, + /* 140 */ + { { 0x2ca9c508,0xdeb66c8a,0x69d6b780,0x2dc5bec2,0x88ead600,0x16d61266, + 0x49d72614,0x61841b97,0xce472e6f,0x41e40e6c,0x1fa7a876,0xada24264, + 0xcc3997a0,0x45b9fd33,0x7c15dcf4,0xb25e8fa9,0x12e9629d,0x0124ceb2, + 0x7db3d956,0x3a8c72c6,0x7c1a7844,0x8e2ded2b,0x6dd027ff,0x94ab09c6, + 0x7e7a2bc6,0xf89a057d,0xcf70c763,0xad8bf226,0xc8a26212,0x4cb268e7, + 0xb2c44c1d,0x3d171e87 }, + { 0x8ce49820,0x382ac16e,0xc0c44dc9,0x24ee45e2,0x73e858c4,0x0ec67912, + 0x46327cf9,0x918cb25c,0xc6159c1f,0x43e3876b,0x37545cb3,0xb6b6e0e0, + 0x5d12347e,0x64b839ab,0xa300d541,0x72e09274,0x881c1169,0x26ab28e6, + 0xeb75a843,0x4a580fff,0x359120df,0x0a5802ca,0x3209f4a3,0x7fee82d0, + 0x8e6a9380,0xb518016b,0xc2ee11ca,0xb99c6c70,0xab9d4ec7,0x16105af1, + 0x34cd9004,0x234e98f8 } }, + /* 141 */ + { { 0x14db9cda,0xff435208,0x96adec90,0x99cfdc47,0xaf458b6d,0x843aaa6f, + 0x743eaa31,0x3f1f7415,0x61735d81,0x915e192e,0x0ac595d5,0x3441a22d, + 0xc044bc8d,0x704bbf67,0xbe23a236,0x2f960471,0x15d1d557,0xcc326388, + 0x76b1dd94,0x9410230b,0x0c1c8a67,0xf2e5439f,0x833c910d,0x56b141ac, + 0x865b84df,0x467c999f,0x21f02b7b,0x1b0251fa,0x96216950,0xde5b5260, + 0xce3a1e93,0x6a2130e3 }, + { 0x4b3ca1a7,0xd21b67a0,0x00c0ce80,0xaf42ed53,0x932cf07a,0x22ccd368, + 0x5c25c35a,0x36523a81,0x8dd04d06,0xecdd3958,0xb2f93a3b,0x73da3502, + 0xd5e5b530,0x4c5e0c3c,0x13268777,0xef9f5486,0x1e742292,0xed87fefc, + 0xa24e5ede,0x6d9ac29e,0x33849f1a,0x08abc9f0,0x40f23905,0xb09b2292, + 0x7f934353,0x6791072c,0xe6aeb550,0x102a6381,0x96feb870,0x3ee07409, + 0x9c4d2830,0x34f06faa } }, + /* 142 */ + { { 0x2348f005,0x869dc79f,0xdf4920b1,0x9b5c5d71,0x6dee64a4,0xfd1b57ca, + 0xe82a4fb4,0x21b7f734,0xb9578366,0x637cb834,0x7d287d96,0xc934101b, + 0x0392ecab,0x1590f8ac,0x7f75f4e3,0x280dc373,0x6a61ac62,0x8b36f50f, + 0xa65568da,0x74f58304,0xd930870a,0x80d792a9,0xfc8895cc,0x6d17b192, + 0x4914939f,0x498392fa,0xd41d5b9e,0xaf36027d,0x5caa82b5,0x452d79e2, + 0xf4115d1a,0x764d47b1 }, + { 0xa2ee8b9c,0x5df22303,0x85dfcd48,0x1b9f72d3,0x10813a37,0x6b42b983, + 0x3de741f5,0xe28c523b,0xf303bb5b,0x0857625a,0xac9bf9af,0x926f299a, + 0x0d445b34,0x21beac08,0xd6ba2c0e,0x6a523a02,0x7fce2864,0xe302a1b1, + 0xe300c1ea,0x4516a235,0x7b4a9311,0x4543736a,0xc0cc89f7,0xd3c0b9e8, + 0x40ed88de,0x0481904f,0x3cb7fc70,0x4f269b56,0x321b9738,0x09a1d53a, + 0x230a3810,0x1c0dd9c3 } }, + /* 143 */ + { { 0xc46a7d9a,0xffaa1f67,0xbedf91cc,0x64743334,0x47a42f2e,0x45833a74, + 0x241ffaa9,0x67980051,0x335efe6b,0x70979a84,0xf08b2403,0x5f0613f5, + 0x64f211dc,0x6bb22fcd,0xa0572cfc,0xe1b8b2a3,0x7950a14a,0x19e0eb41, + 0x3eb6cd4c,0xe634bb29,0x470a25ff,0x31a04b25,0xa3d15a0a,0xa41f7ac9, + 0xbf2fede9,0xefed85ec,0x81b94a00,0x1f581f5f,0x9ef4a15c,0xaa3996b0, + 0xb06041bc,0x52d8be39 }, + { 0xfd631a2f,0xbd1536f6,0xb351a8dc,0x91fae7f0,0x9b126212,0xd1a590c7, + 0x2bd0f435,0x52d4875f,0x92b0ea70,0x9aedb6d3,0xb83ab89e,0x0bd0abdc, + 0x89fe192c,0x827a1062,0x102a0bda,0x6566a960,0xce036814,0xda083037, + 0x58639405,0x30bed79f,0xdbca8df9,0x972019b6,0xefdaa3f5,0x89201286, + 0x5236b892,0xb337b996,0x28fc2e73,0x11d3e38e,0x880e8da3,0x70787f41, + 0xdae4a45d,0x6cff6367 } }, + /* 144 */ + { { 0xf89a8bb4,0xbd3d0433,0x93b98f71,0x42144c33,0x03470a2d,0x82b616c8, + 0xe5da089e,0x98fcc757,0x7bf5fda6,0x542354ef,0x9ebd34cc,0x1885c253, + 0xbec5dd0d,0x2e20b285,0x782a1bca,0xe71bbbe1,0x9b854ef0,0x959ded30, + 0x8997fa6a,0x17249979,0xd81f3c45,0x50cf8fa8,0x60c11152,0xa9a3b517, + 0xecf845ea,0xc9b0ef7d,0xb9fed11b,0xc9339e23,0x28256080,0xc93e9c5c, + 0x613ec1e7,0x1d2c8217 }, + { 0x987cfc93,0x7381347d,0xf187f810,0x047603bb,0x1250ca31,0x3fa6bc9d, + 0xbb055bf3,0x480091e0,0x3a3af87c,0xbdf95f1a,0x140540ab,0xe2687770, + 0xd7fe045b,0x998df730,0xb723bc2d,0xb398135f,0x15ebec46,0xac230f8c, + 0x5f5561c0,0xe08e1830,0xda60a47f,0x7c0fbf4c,0xe16d4bfc,0x06e95c24, + 0x74617e92,0x74163495,0x4ae0c20e,0x39719869,0x2131e2b6,0xfe269312, + 0x0a537722,0x25486e36 } }, + /* 145 */ + { { 0x53572806,0x618795ca,0x656968e1,0xb2c89449,0x3fb323ae,0x149c2c97, + 0x409bc7d6,0xfb15de26,0xc79121b3,0xa90cda72,0x204cabbb,0x6d2fa14e, + 0x91604125,0xcbcda6f7,0xb435f947,0x25086261,0xc282eb10,0xdb686c38, + 0xf1a791cb,0x51016d62,0x61a2266c,0x6b1c7ed1,0x271d74a6,0x26780666, + 0x824287a4,0xb5ffeda1,0xbbe4f0f3,0xcbe503ff,0xb9482a74,0xd7f7f0be, + 0x088493f1,0x751b2358 }, + { 0xe9c9be68,0xd597b9d6,0x67d10c6c,0x1794b5c4,0x7762b2f4,0xa88cdc3d, + 0xa1b44e11,0x6d94a63a,0xaaa8eca8,0xfb0bbbb9,0xc963d87f,0xf4b0f2d0, + 0x5dc7075d,0xb753062c,0x49933989,0xfed726ac,0x57f9ccde,0x5da60638, + 0x75f8c766,0x221c392a,0x5dc672ca,0xcd264d95,0xb66ecc8d,0x7004ff22, + 0x18a458ba,0xfb1aa9ae,0x8babd653,0xea9644df,0x2ba0de7c,0xa9378e80, + 0xca2c6c75,0x144cc12d } }, + /* 146 */ + { { 0x2989aa3a,0x593a0a1d,0x59e6e64d,0xd83f2283,0xd32e732e,0xe938b0cb, + 0x3c3cb249,0xf4c464c5,0xf89ea6ac,0x9750a5f8,0x346cfc32,0x467e5bbf, + 0x37b2b809,0xc9bfab9d,0x3b339c6d,0xf8eb7453,0x3b766dee,0x3fe01fbe, + 0xef6aea27,0xb3154254,0x7be61b10,0x555c3df2,0xdd818488,0x70fb6d81, + 0xbbe714f9,0xda1af3a4,0x9d18f693,0x575f2017,0x2465b839,0xdc08fc6b, + 0x6b84a951,0x874ecf33 }, + { 0xbbb3f6be,0x624af83e,0x08bb423d,0xf578fbb9,0xd7873527,0x5623b0ba, + 0xa62e0442,0xc3659bd8,0xfe236f79,0x2903b167,0xe53f26a6,0x55a430c6, + 0x3ad712cf,0x222547ae,0x76eb272b,0xb73890d7,0x3d628df9,0x95b4f70b, + 0x53eae4ac,0x9f0e13b0,0xe7f2174e,0x5b4f5138,0x98dbae17,0x75482cf9, + 0x44518480,0x2b69bbde,0xcafef15c,0x4f279652,0xb6bcaf19,0xa0a3ef2b, + 0xce4c634f,0x31fb8581 } }, + /* 147 */ + { { 0x615cd607,0x398306d1,0xaa32c3a6,0x680c9faa,0x7779131d,0xe87a705b, + 0x36708b00,0x1031013a,0x9445297f,0x814fa0e1,0xa6a79b56,0x70c5583a, + 0x4b16bed4,0x03039cbf,0xaaaaf8d3,0x18a7ca8d,0x5cdb68a5,0xf33159e7, + 0xd23814fa,0xdea0e738,0x8d0f4f9f,0xeb352718,0xdcdff032,0xb0b76609, + 0x3d48338b,0x65ba8ea9,0x55dd507a,0x18044d82,0x4a4a50b4,0x844a223e, + 0x18e19e54,0x98323000 }, + { 0x57f3d5a6,0x28a21027,0x6e8cadcd,0xffce5648,0x02551f3b,0x9590381b, + 0x935ebdf1,0xb26cc64f,0xc083aa6e,0x60611291,0x88e4cf41,0xcd988a66, + 0xdd53b1b5,0x581c3f73,0x77fc621d,0x78c804a9,0xfadca2fa,0x31874330, + 0xc83ccf02,0xf7008da4,0xa79a4707,0xc4122a1d,0x4a915eb5,0x9a8e0d3f, + 0xd0123660,0xa2de157d,0x65ead2a0,0x45ef43b2,0x188db285,0xd0a22ade, + 0x922e0caa,0x8abbe39e } }, + /* 148 */ + { { 0x3a2d2f01,0xb4446905,0x5dc6685c,0xd27c3193,0x1d74a027,0x6a908bbf, + 0x5b50ec1d,0x01da350f,0x3f3c2e26,0x1d3dd45e,0xb836ee92,0xf66e11d0, + 0x474b979c,0x7e03908f,0x98b87834,0x19e7c5b9,0xbd3d1de9,0xa741d3fe, + 0x1ef6059b,0x63c68e8d,0x3674e247,0x9b9ff939,0x3e7e67f6,0x1d7d53e7, + 0xaee9e248,0x698dc326,0xb3bd984c,0x52f23eda,0x6f8fe8a7,0xf95e31b0, + 0xc3d0ba95,0x0f15b4d0 }, + { 0x790a8d85,0x8f2f6635,0xe2595af1,0x51bffbae,0x24b51287,0xd15b7ec6, + 0x3234715d,0x7639b6ab,0x2bc5441d,0x0cdd5299,0xf6d05833,0x54800ea4, + 0xf6d6e360,0x21efd752,0x19290613,0xc0b7ffe5,0xeea898cd,0xb68a5825, + 0x22982266,0xecedba92,0xbbd06bb2,0x678a91b0,0x4bb6b0cb,0xb2436dc0, + 0xcaf8ea98,0xcf7a99e7,0x71aa05bb,0xb92d0e6e,0xf5993eb1,0xbf8d0471, + 0x20385ddb,0x515db378 } }, + /* 149 */ + { { 0x6f5bef22,0xee43eaaa,0x20348712,0x952d2698,0x7a3af6c6,0x1e4c484e, + 0x9a8c9403,0x18d434c6,0x5001899a,0x63e5d741,0xfe8ea40c,0x5238dbbc, + 0x96798721,0xca6cc8d2,0x04acbde8,0x73db6aee,0xb7f993ce,0xbf69328d, + 0xad45e334,0xa3f79bbf,0x7c1f1630,0x8c51ec93,0x9b00a6de,0x4907325f, + 0x12d82bc3,0x49e6acb4,0x0ec59fc9,0x5901b36d,0x9cf34e3b,0xcb09b710, + 0x1abf4c02,0x2de0487e }, + { 0x8dd9d484,0x18b722f3,0x7c77bacc,0x83349393,0x93d92b8a,0x58dbb8f1, + 0x8e3fac25,0x80d78d50,0x745f4a7d,0xf0500981,0x877cc29d,0xd072bfed, + 0xc30a89f8,0x67abf8f2,0x9a0820d7,0x92c567ea,0x8a3a5738,0x425ab12e, + 0xf055521b,0xc162faeb,0xb94ea5e9,0xee1c4f26,0x3d71e546,0x1e414994, + 0x43e8be1d,0x258183b8,0xef9eae0b,0x44917c82,0x73874a30,0x6813a457, + 0xcc42f86e,0x6f6ac071 } }, + /* 150 */ + { { 0x4dd6e3b1,0xd38822ad,0xad620869,0xfc78e1cc,0x2cacde80,0xe7843845, + 0xa8469fe3,0x121cc14a,0xe67e8ef2,0x8e8f3da7,0x4d347448,0xdb83d16e, + 0x798631f4,0x3ba1dd98,0x0a4c4c17,0xdfab5977,0x3edc701f,0x1f0a1306, + 0x6cd8ff28,0x4649d601,0xbcc55bc9,0x2267230b,0x5760412a,0x02a19c60, + 0x328faef6,0xc719d5f1,0xf67eaad9,0x27cb969e,0x719bafb5,0xf342530e, + 0xff5a82cb,0x6e2c24cc }, + { 0xadaf8793,0x6313024b,0x035c948e,0x944bccf1,0x953500bf,0xe9a066b7, + 0x1d116765,0x7991a946,0x9fd93c78,0x95addb2e,0xe92e5495,0x05d2c037, + 0x9f03e5cf,0xcb145b18,0x95aa1f72,0x81ae48ca,0x135a6e4f,0x203f2702, + 0x49b2a7d5,0x2bcef5a2,0x02d7f2a3,0x0687a900,0x6c6745b0,0x2f7d3228, + 0x86507305,0x3da8a875,0x2e8dc58f,0xbe38b884,0xdbf11185,0x6b48bf34, + 0x97c08f91,0x5af7fd0d } }, + /* 151 */ + { { 0xf4a224a5,0x55f9b950,0xcc50273a,0x41904574,0x643f1fd5,0x34f81330, + 0x0e50f783,0x996801bb,0x89581712,0x866d7403,0xa4091d36,0xdb9a405d, + 0x16a46fe7,0xf1e379df,0x83bf9168,0x8d04a93f,0x32b20bca,0xae4c8335, + 0xf72a1c10,0x99d334b1,0xd8195db4,0x8fbc9977,0xfba14b5d,0xcaeb3dff, + 0x76daf476,0x60fef022,0xdb5b72f4,0x4b948dfe,0xb6dfb062,0x5185c925, + 0x9609d4ae,0x27a9c381 }, + { 0xf12a93af,0x73c37346,0x5536634d,0x028b707c,0x498193d1,0x8efa58d5, + 0xef21b69d,0x4f83a5cc,0xa788a0e2,0x05cbb0a3,0x65b13c98,0x01031781, + 0x2b73784c,0xfea20e58,0xe50361f2,0xdf9713a0,0xd0cc22d9,0x31449a0f, + 0x7c5e2e1b,0x183752e7,0xb67044cf,0x6e44d6bd,0x733e177a,0x012dde95, + 0x08ee2c23,0x68b49669,0x1f5f1949,0xd9bb0541,0x6acd886f,0x95182c71, + 0xfbde9244,0x1c690694 } }, + /* 152 */ + { { 0x3a880026,0x5db67d17,0x125d95f2,0x89c4f0a0,0x3f6cb7a4,0x29050551, + 0x5cbbdca5,0x3eb231d1,0x972bcbd3,0xf8cffc99,0xad55a03a,0xcb4ef4d4, + 0x22867c2f,0x944d47ca,0x0ead1aa5,0x96d88548,0xcbc8b045,0x76a57cf8, + 0x005e55a0,0xdfe5844b,0x1d18a097,0x5e9e7e19,0x52923c74,0x957a26e8, + 0x7f5db339,0xd0867b79,0x63bed0c8,0x2553408e,0x689ad23c,0x1596e5d5, + 0xa504c339,0x7b8c13d6 }, + { 0x52fb6901,0x2fc43aad,0x16ca253b,0x1c0313f9,0x515aadc6,0x1475830a, + 0x7f577dc2,0xc93d1926,0xf723c0dd,0x26e52e8e,0x3eb9f6da,0x2f1e0eb8, + 0xf180376d,0x9979de82,0xb0834939,0x43e28ecb,0xa39c38e7,0x9a2d51dc, + 0xa8e3f6b5,0x6e6063a9,0x4b9b3270,0x4cf1da3a,0xd2f8915d,0x6e5348a2, + 0x50507912,0x5e75e3e0,0x20d383fa,0xaeffce57,0x8fd2fb29,0x1d6d53cc, + 0x696f4cd0,0x0e3c3ef6 } }, + /* 153 */ + { { 0x21ee1d83,0x3bc337c1,0x787b7788,0x97e08f6d,0x138fa4ce,0xbf709fcc, + 0xa0348e58,0xbaf77647,0xa55e672d,0x04f8babc,0x7d5ec5dd,0x0ed2919d, + 0x33e99218,0x8ce64bff,0x24b059af,0xac09fc57,0xdc5e32ba,0x506831f9, + 0x465af6a9,0x26a22677,0xc97f1ff8,0x3c5efe66,0xbc6087fd,0x1515e0d6, + 0xaa8edc6b,0xb1a39c5e,0x0e79ed29,0x3dd816bb,0xbc3788b8,0x6cc13769, + 0xc092a51c,0x463098e3 }, + { 0xc8bd0fa7,0x3a6408c7,0xce6bde49,0xd1764311,0x283ef7be,0xe315e108, + 0x99b5d938,0x8213cc77,0x45a49a6b,0xaf7f1581,0xe529e4d1,0xd00fdb0f, + 0xce66c9d6,0x55d38f77,0x1bd4b952,0xb4f7ccc0,0xaf71f986,0x8d975b49, + 0xcd64d00a,0x12b59fcb,0xa5a3bad7,0x1860e504,0x2b5c89f1,0x6d976044, + 0x7a3e231f,0xfed0c659,0x178cba92,0x58114c33,0x6698e11e,0xe2e74c06, + 0xa348b85a,0x7f8fd093 } }, + /* 154 */ + { { 0xc19428af,0xf24592ca,0x3a308665,0x192a1c81,0xe30bbd7f,0x42589812, + 0x836c6bb9,0x10db0723,0x598e4987,0x9c7a41e9,0x6ead6f4b,0x8aff179e, + 0x75862c44,0x70f8f9b9,0x6f21983e,0x6b3b0237,0x98e65152,0x25d83e9b, + 0xd751218a,0x3b2d26a8,0x9d6f1da6,0x9508281a,0xa5a81f74,0x8df78d05, + 0xe4687471,0xd79ee559,0x6787d8cc,0x2060ca57,0xa8476c95,0x427a84ff, + 0xe6435131,0x87b64c51 }, + { 0x4b30d3c4,0x87f46f65,0x23b4ef14,0xcdec4c5c,0x63ca4d68,0xb3b74766, + 0xcf3fb56d,0x1df34269,0x0fd7d46a,0xd4f139c4,0x6a69a8bd,0xa3b7c7c7, + 0xcbadd7d2,0xee56b4c9,0xac942334,0xb28ff342,0x786f1da3,0x0046fdfa, + 0xb700c82e,0xce5d149c,0x50966597,0xca30ef81,0xfcff4bdd,0x44a20609, + 0x44925268,0x0f2f65e7,0xd4021f38,0xe5b6552c,0x042dbbd0,0x77ea9c2a, + 0xd9c062f5,0x8c95267c } }, + /* 155 */ + { { 0x5fc1abb1,0x6655032e,0x12fe4743,0x2215af54,0x29f05ef5,0xfd657560, + 0xdc191be9,0xb0e73325,0xc08639b0,0x7ab3c65e,0x1c3e6673,0x67507f51, + 0xc8615555,0x638befc3,0x42f0c4ad,0x5d0188cf,0xd896186d,0x843a301c, + 0xb2c6741e,0x045603f7,0xfa3cd1d0,0xf7545c0c,0x4a40672e,0xf612affd, + 0x45b9e8dd,0x56197c9f,0x87922d74,0xb453237d,0x4b2d59bf,0xbf132e3a, + 0xb84a6a16,0x8afa1b73 }, + { 0xe793ac70,0x6b3596ea,0xeef6dd10,0x4c94ef8e,0x70422e40,0x926b4fa2, + 0xe9e5d763,0xc8c71dce,0xf512aadf,0x352fcb70,0xa883975f,0x1b7ba138, + 0x058c3b13,0x57991390,0x97740fd1,0x9692092a,0x160b0697,0x19ad945b, + 0x10837ab2,0xbc634388,0xf174bb71,0x76ee11c4,0xab1b80eb,0x6111bfc1, + 0x70ec458a,0xbc82bac8,0x312d3325,0xeee60127,0xb240adc8,0xb4118b1a, + 0x2b5a093c,0x67211191 } }, + /* 156 */ + { { 0xf55cf9bf,0x91e99306,0xa46b96d9,0x9b045308,0x9e7a65df,0xae3c1e1d, + 0xc731bcbb,0x453cb151,0xa4d58a61,0x14be5227,0x97c74cc2,0x39dac922, + 0x822e00d6,0x4d0f7a45,0xc62b03df,0xafeb1d51,0xbaa18b2d,0xbb1dc3a4, + 0xdf2b74f0,0x7f3c7178,0x896b6a33,0xfcd328a6,0x1dce055f,0xe95ed454, + 0x6a4e2b87,0x97fbc76b,0xfa59dce9,0xe5ec67f1,0xcc0367c1,0x052368ac, + 0x54e4a3fe,0x7c863916 }, + { 0xca7388cf,0x55e94b5e,0xc0335d38,0x17cc0a60,0x616f85ba,0x9b69b78b, + 0x10122980,0x705d02ef,0x1cfd0a79,0x565a6e80,0x7d1ee352,0xeb74a96d, + 0x427b9dad,0x5c8832ed,0xe6d5330f,0x96ea8528,0x18d24ee8,0x30d8862b, + 0x9ff939f7,0x9cd38ed5,0x01060252,0x690fc9a2,0x2303b3ff,0xc62d88b8, + 0xdd52b469,0xfc42d7a4,0x8cad2d93,0x06f8dfa2,0x60920438,0x50236090, + 0xfce855ad,0x32582758 } }, + /* 157 */ + { { 0x359e8c60,0xeb20e45f,0x364ca186,0xc71bb8a5,0xdff8e110,0x02b15071, + 0x4c93e578,0x074e91d3,0xb829d0d8,0xc0326e00,0x626a83fa,0x3c192258, + 0xfb29a09e,0x387a64d5,0xe5ac5c82,0xcaaa3d34,0xada2da29,0x8ed685e5, + 0xeb29650e,0x92720267,0x763802f3,0xf7184b19,0xdf6b1aea,0x23f5dd0e, + 0x25e6125d,0xbe1fa347,0x0c872a1a,0xd6287f9d,0xac57c3af,0x49aa93d2, + 0x5bda7656,0x1a4e6a71 }, + { 0x554d1267,0x1a126ede,0x1cd02b48,0x37f94533,0xce31fb1d,0xd70af04c, + 0x097dc012,0xcf410b0b,0x36c7b6c5,0x930e1d17,0xc6891085,0x902fee41, + 0x79fb638f,0x349ba4a7,0xacd6f8df,0xa16c5821,0x2e076ace,0xfb3b83c1, + 0xe501d14d,0x6b8d033b,0x20f2d2da,0x0593d452,0x99df1880,0x3752526d, + 0x9feb33a6,0xca32351c,0x1f6ef456,0xd91343bc,0x35b9dc8a,0xc74857db, + 0x85b4e832,0x856a7c93 } }, + /* 158 */ + { { 0x0d0a5583,0xa007d002,0xeda4658a,0x2f1301dd,0x34d939be,0x91c07964, + 0xa70c0836,0xa0cb6780,0xbe81e540,0xc0b4df95,0x5d4ac8b8,0x6cbbcd34, + 0x54756239,0x57c52ed0,0x1805ceb6,0xcac2dca4,0x79344255,0x915ee6ab, + 0x24c9a2a6,0x366def31,0x8c12c674,0xbd3b962f,0x7dbb7c3b,0xaab64f1b, + 0xe22bb95b,0x3c0e4553,0xc4c63b74,0x2408feba,0x2a4da631,0x3ca77312, + 0xc636da40,0x62889084 }, + { 0x8cb8d208,0xa457fd53,0x543f06d4,0x7a8f8009,0xf2eff2ab,0xb66de154, + 0xf72517e7,0xfddb28eb,0xf9389d2c,0x0149fe66,0xd85b88ce,0x79e8773f, + 0x0ba543f7,0x452e090b,0xb0b03fc0,0xdeb9b5cf,0x6c5ed77b,0x3113448a, + 0x8ffc0372,0x3609f3cf,0x5c1b4c4a,0x2bc9c46d,0x8fa59be9,0xe66f3bf3, + 0xcdb02691,0x1396bf5f,0x009f88f9,0xf1ec59d4,0x2ad9dfe3,0xc2903456, + 0x5ada4d58,0x79d8122c } }, + /* 159 */ + { { 0xaa529507,0x14d4e4ce,0x74655d00,0x056a0814,0x4f0fc474,0xc0d30a38, + 0x3443cb8e,0x8a8203ea,0x97f1728d,0x33c62fb0,0xb520ef52,0x8a38dcfd, + 0x7cac9d3e,0xa0f90d5d,0x873cea50,0x28a7b0bf,0x6c6c41cb,0xd115ae3a, + 0xa13812c1,0xa35171da,0x624d507e,0x25d4bba5,0x7e98f42f,0x91dad289, + 0x96a41371,0xffd6b1e9,0xb69e5b77,0xd46c2125,0x20c4f707,0xc7d2b424, + 0x8142557a,0x2ab3af95 }, + { 0x6a5372a6,0x86ca074c,0x56292ba7,0x728fb83e,0x77741cf5,0x745596dc, + 0x520ef49d,0x70b4cea1,0x61e46472,0x1472fe34,0x3fb8ac5d,0xf4d6bd66, + 0xc10bc071,0x46e52cc9,0x371a3461,0x28794efe,0x276fe877,0xa4850718, + 0x9bef5ab4,0xedad5773,0x3f15c815,0x24c2d9ff,0x8f8395c3,0x188950e5, + 0x80b6a855,0xbae40996,0x8a8803e1,0x4f53e22c,0x039d25ee,0xaf233f61, + 0x250409ca,0x07db2c35 } }, + /* 160 */ + { { 0x037d4703,0xc7f3b8db,0xc5f488b9,0xe83708df,0x8471d402,0x1fba830f, + 0x5a2faae9,0xa55ee8d2,0x5404fc1e,0xc2e5bf10,0xaa2d5651,0x647d5027, + 0x7ebaf5f9,0x37a53c0c,0x95b30abf,0x7adf0bb2,0xd64c93ba,0x5a62e1fe, + 0xe2ef4a78,0x7ffc18c0,0x4d2cd04f,0x139dd9d9,0x5ea0af02,0x253fbab7, + 0x0fef9acf,0x7c8100ea,0xc8615aa7,0x74c5384d,0x9fe52069,0xcb28682d, + 0xcf7dd759,0x08b6ca8f }, + { 0x036c3b5a,0xe04e5bea,0x7f9f2b4b,0x38726102,0x29797c0f,0xa9fca570, + 0x82879ea3,0x1656180b,0x607f0ddf,0x153389bb,0x67b0e087,0x99a1223c, + 0x9d897fc7,0x0d1808ec,0x916edf19,0x9470711a,0x07217118,0xf8f52f2b, + 0xd18888b6,0x5d8b29ff,0x4cc6f900,0xef1e22c5,0xeb24877f,0xc4036165, + 0x35479525,0xfda95233,0x6861468a,0xd622a421,0x74faba08,0x5d043b07, + 0x0d31a7d2,0x2c337b02 } }, + /* 161 */ + { { 0xea22fa65,0x7b2305bc,0xd159f63a,0xbe183ef4,0x3f35923f,0x3473d87d, + 0xc11d7753,0xb27fb306,0x2a054cff,0x702e7e6b,0xaf185619,0x3ce9f97c, + 0x4e7d51c5,0x83550243,0xf356ac5b,0xa63e3d82,0xd7645131,0x867b7caa, + 0xa671fc9d,0xee85e6af,0x2b07cd77,0x3b985ede,0xffda5193,0x07d598b0, + 0xa942dc36,0xb10eca39,0x506218a9,0x17f3dcee,0x06b7d5ca,0x3d94e8d1, + 0xed8831c9,0x509b2634 }, + { 0x48caed54,0xb1b9414e,0xcbf51e97,0x77a78c6c,0x4de9b258,0xa4688c8d, + 0x91ee3d78,0x0024137c,0xe30ee64c,0xa68f9234,0x88190d78,0x573255bc, + 0xba80690b,0x41e8e05f,0xec354f4c,0x50038d84,0xdfa52816,0xb18f02d6, + 0xccb63fda,0xc47f9007,0xe98ae455,0x29d480fb,0x5d0e319d,0x4ac45d22, + 0x026db719,0xd06f3575,0x2c3587b9,0x733b9e20,0x2c317727,0x22483992, + 0x54bb8752,0x1592d5a7 } }, + /* 162 */ + { { 0xcf7453f0,0x5778d9a2,0xed83c1f0,0xaffb899a,0xe0a82ba7,0xae6506d3, + 0xea3d5081,0x32c84e1a,0x810aa38b,0x9ad528c0,0xbd37d041,0xb1fdb020, + 0xd06ce41f,0x78d6cbe1,0x2e74b7f6,0xd287f0f0,0xc43bb022,0xf5cd2575, + 0xf81a71b3,0x6d28f2f3,0xc633e7f4,0xe65bb1f5,0xc4fc580e,0x32e5fc1c, + 0xbb7b07a5,0xcd55539f,0xc3caaf3a,0xb5a94471,0x4cc22d2d,0xb958bdf4, + 0x77a2777c,0x1614bdbd }, + { 0xed0ab04d,0x4c1f0230,0x6e2082ea,0xae347b00,0xc42c5b5f,0x9f10bc63, + 0xde019935,0xb0539e6f,0x65dd0825,0xd89bd4e7,0xbbceda16,0x92260fef, + 0xe62aca32,0x8aaa755c,0x5ec82c5f,0xed762fa9,0x18650768,0x99e64c01, + 0xc92e348c,0x57dd6245,0x31ea6d68,0x0db88a77,0x07b44736,0xef0012ab, + 0x171d70fe,0xb9356b94,0x03f891b0,0xe68b0628,0xb79c20a2,0x3a54a53a, + 0xb00b0728,0x489656c7 } }, + /* 163 */ + { { 0x71353c25,0xe43649ba,0x13f67e24,0x517f27a1,0x1c1eb9e3,0x10bd333a, + 0x78e29bf9,0x94e1c05c,0x4743f15d,0x84fe7d97,0x90da2df0,0x9c874908, + 0x53673be1,0x82403fa7,0x1baea1b1,0x7ebf5db4,0x24180ead,0xcfe0ae35, + 0xc2f50c3f,0x1d15873f,0x70661cd9,0x16851ad6,0xa51e8c2c,0x802968d9, + 0xe0161099,0xe7d1a9cd,0xa8a7ea56,0x2b153c89,0x06e3c498,0x6d41b789, + 0xd6769dcb,0x082bb2e9 }, + { 0xc4d6615f,0x6180ef46,0x01b9829c,0xfc629dc1,0x0fb264ca,0xde222ec0, + 0x10ecc2c4,0xc5457e06,0x1eea2c4d,0x95ce599f,0x8f9c5b2c,0x0433fa72, + 0xcd6310f9,0xee035462,0xce2e2253,0x84c57c3b,0x96d87e44,0x6c8ec31a, + 0xa452c5a7,0x30bfe393,0xa047b235,0xc592b140,0xc018545e,0x7bd8be18, + 0x5c178c46,0x794e0107,0x2e23005b,0x48471946,0x622a54f3,0x2665e237, + 0x901c9042,0x36451a46 } }, + /* 164 */ + { { 0x19893e71,0x17802d18,0x539a2082,0xa1765d8b,0x2302ecfc,0xfc6aea01, + 0x365bf59d,0x8d4cf51b,0x0d232a80,0x87741d72,0x18e80427,0xac343eb3, + 0xe74739ec,0x553ecb2f,0x1a8b07ca,0xaeca79a8,0x56f4ab3a,0x089ff322, + 0x3fa1d1f7,0x5e95d729,0xf62a9a16,0x260569ae,0xaa08ddc2,0x5e776232, + 0x1b7bb54a,0x93fabec3,0x743d56e7,0x48a20956,0xeb0ebeff,0x749cdb12, + 0x69b8fcf1,0x705307a4 }, + { 0xe488310b,0x7a8e4c04,0x5325cd7b,0x12726e32,0x4983efac,0x5d0fd8b0, + 0x02ddb913,0x796e552c,0x77b9685c,0x0eeca3f7,0xb15f24a3,0x9b766e89, + 0x48efc979,0x7c2736d6,0xa8021c6c,0x3d619685,0xa0b2f1ea,0xfe33e278, + 0xb676d6b0,0x95c69879,0x1af4e0be,0xa0747319,0x36c4ee55,0xa2fab5f1, + 0x59e5f3b9,0x6938b8ff,0x39cafe6e,0x1e114da4,0x6a6ad120,0xc9595ec3, + 0x57e62aec,0x80f79bd0 } }, + /* 165 */ + { { 0x60af09b3,0x3cef42a7,0x933dfe14,0x3c016ebd,0xed85eaa8,0x720cf1e0, + 0xceaa3bc9,0xd4f5e99f,0xb7106f97,0x7216b9d2,0xc9668ad2,0x65f34c36, + 0x5b0c651f,0xa8fb82bc,0xf2fda4de,0x20f42f1c,0xd21f659e,0xeb31ab2c, + 0xa13d1618,0xb7a776c7,0x38662be5,0xec441022,0xcad08e0b,0xc825da70, + 0x022c0180,0x99299079,0x2aef9ffd,0x7623bda0,0xf5c58b50,0xde84f4f3, + 0xd824ff19,0x5f5a5da4 }, + { 0x7e8311dc,0x5737257e,0x466cf136,0xdef94f51,0xb05ca21a,0xa73e1645, + 0x02e4ab37,0x38ea9b3c,0x8579165b,0x7760eac9,0xc24b01a4,0xdffdd047, + 0x3fb95584,0x188d4fd1,0x25548bda,0xfaac38b8,0x59e9dcac,0x1a79a6f0, + 0x09a2700f,0x983f720f,0xfb8a7e48,0x8cbba554,0x47a1fad5,0x38a19968, + 0x5abd6b5e,0x11856547,0xf3716ec2,0x75113d31,0x4212907b,0x1391e781, + 0x0dc15889,0x5319c801 } }, + /* 166 */ + { { 0x6b61c3af,0x2320136e,0x07b4bb68,0x1d40f2de,0x380c97f0,0x651dee7f, + 0x6a8c313a,0xa978ba70,0x2011ca10,0x22c587d6,0xab1f445b,0x48bba218, + 0xe50444e6,0x8c5eaf07,0x442fccf9,0x5549f02a,0x3d80493d,0x2564746f, + 0x79c04591,0x42d24f61,0xabdc8887,0x1600fa18,0xded38f8f,0x5cb8600a, + 0x923aeb46,0xa4bf9b90,0x1e1c578a,0xd63fee35,0xebb9ea14,0xf3c9c5ac, + 0xf11a4ff0,0x3d13314d }, + { 0xb4513d1e,0xe5cc662d,0xd55952bd,0xde78a8c5,0xe7f86d0a,0xe8a37a3f, + 0x7a04f0c5,0xca2d12a4,0x2e25d06c,0x4c6696e4,0xb2136071,0x52614698, + 0x89f6e1cb,0xf4d2701b,0x80efd95e,0xaafd6177,0xc5bb6907,0xe6d73ac4, + 0x420db35a,0x49e874ac,0xf2751fa0,0x11631de4,0xa1fa2edd,0xb29f7336, + 0xb7fd794d,0x4c406864,0xe22f92a6,0x73cb21d3,0x2043cc76,0xeae904e6, + 0xb322c6ad,0x67f28a9f } }, + /* 167 */ + { { 0xca148ab5,0x7c17b258,0xb3c60051,0xb9a1976f,0xc8f28df9,0xea260698, + 0xe8d45017,0x87b2cc74,0x0578a422,0x37257329,0x17bec732,0x81d5ee25, + 0x1d48bbc4,0xd7411fcf,0x487f5cfe,0x46217e6b,0x41eb8e1b,0xcb007ac5, + 0xe05a00c8,0xc41c57a6,0xd2f9fa99,0x1f954d2b,0x40941cad,0x370bd5db, + 0x3829509d,0xe487879c,0x5ceca5ee,0x4c137552,0xfd3efb9e,0xe8ef7fa4, + 0x1bd1bdb2,0x5ff09174 }, + { 0x579c6632,0x791912a4,0xb8a20815,0xbb19a44f,0x535639d3,0xf4f97b84, + 0xbc3c9bce,0xe57e2bcb,0xf19e6410,0x122b3f2b,0x1357d9ad,0x1f0189da, + 0x79e5ff66,0x675573bb,0xef2f3c4c,0x444e5c98,0x04d10731,0xd6f61e20, + 0xac75d635,0x0dfa366f,0x2c854f23,0x9fc47c86,0x0ad0850b,0xc04ae43e, + 0x2f720c32,0x5ce94f64,0xa753bc9d,0x67efae65,0xb0373a63,0xc27d30d3, + 0x29721646,0x6681013a } }, + /* 168 */ + { { 0xe84509df,0x1385d913,0xcf339376,0xe978bedd,0x3423a148,0x2df425d3, + 0xee8cb579,0x43fa0ae3,0x31c4553c,0xf015369d,0xdfbf1d48,0x05cf08bb, + 0x9444244a,0xadff4be6,0xa35dda33,0x01635f81,0xe76fab7c,0x085c8949, + 0x16737783,0x4bd7fcde,0xa254f8d2,0xfd8cb52c,0x413ec985,0x62168a66, + 0x7a9026cc,0xf2db9741,0x50e1e1b7,0x3962ee56,0xd3beffde,0xbee0a346, + 0x0bdfab1f,0x3b35b72f }, + { 0x535c3749,0xbff8de9f,0x8add9c48,0x23c1f20f,0xc8f8f663,0xa975b37b, + 0xe8f3ae49,0x2529e475,0x1d5e2628,0xc32f10d5,0x67862f1d,0x5ac0d297, + 0x854cbe36,0x13c79338,0x4b67e462,0x48f004ef,0xe5d10ee1,0xfa37a150, + 0xd28288a0,0x4974778d,0xcfb73f4d,0x96830a66,0x07804952,0x9f444013, + 0x9760b694,0x8233c709,0x25b75c99,0x8340cca5,0xc771f99c,0x3f62e40b, + 0xcd95c685,0x47d0a1eb } }, + /* 169 */ + { { 0x652811f1,0x266f4fff,0x62ef3002,0xeaacaa93,0x50cba0ca,0x6c387a55, + 0x007f5467,0xa350142a,0x202f2673,0xc7fd102a,0x33dc6e65,0x5daee570, + 0x064a63d9,0x60682ec3,0x462b251e,0x46cf0bb0,0x5da936e7,0x0e030ca5, + 0x434265b5,0xc87a60f2,0x69b4e8f5,0x9637b2bb,0x7ad7770a,0x601fb58c, + 0xed3a15a6,0x1f2147f6,0x2995e961,0x05b47d5e,0x83213a16,0xcb0ca9b3, + 0x4995a85c,0x8f4b614a }, + { 0x4b4eb3c1,0x5aa8ec19,0x20323a70,0x8c549ac4,0x4f6cc6aa,0x00d49322, + 0x45f9a5a3,0x0e53b9bb,0x0897abbb,0xe46ef110,0xd7acd7d0,0xfe873e57, + 0x0f7cb588,0x7cfccfe5,0xc85557d1,0x0ea53d65,0x7288f2e2,0xfdd9eb44, + 0xc0eb68a8,0xab2dedfa,0x08603a0c,0x58221470,0x00feb06c,0x69464689, + 0x25e5caac,0x804cf5bf,0x9fc91ae9,0xd8559858,0x73c45eae,0xed9378b1, + 0x524c9801,0x8f942d02 } }, + /* 170 */ + { { 0x8e845808,0x1f1ec302,0xb77abfc5,0xc302bffa,0xf8d97dc7,0x26afd4b9, + 0x3aac594b,0x3d3a83c4,0x674d94dc,0xe3b74bd1,0xcaa5911c,0x4464b737, + 0x871c2cd2,0x62925773,0x3b4440fe,0x419f2485,0xe052ad7d,0xdda6a0f3, + 0x846c86c0,0x645280d6,0xf8324f42,0xa25689fa,0x07cf117a,0xc74ad1e8, + 0x8ddc9db7,0x5626dea0,0x966fc85d,0x52620373,0xf3b1eb53,0xe0ad57c3, + 0x949c1acb,0x38300252 }, + { 0x5e744723,0xa0ef5a40,0x1ae08481,0xdb5bcf75,0xfec1f76f,0xabfad8cc, + 0xfab37fc6,0xfba5d831,0xc8fedb78,0xbe39e248,0xad93f310,0xa5cfad5f, + 0x913d5c24,0x747fdb1e,0x4518b7f5,0x052a47c9,0x7cfb4327,0x9e208d6c, + 0x70e538be,0xb135cb9c,0x5bb17916,0x36352759,0x5b3106c7,0xa2c07880, + 0xc209bb06,0xd2d42a06,0xd3c504ad,0xb525b471,0x822ce034,0xc9f4b368, + 0xeb4185a5,0x15f18796 } }, + /* 171 */ + { { 0x0aee4684,0x094dea06,0x7cdbdbc8,0x42b21f06,0xb1931319,0xa439e149, + 0x81a7dba6,0xea4bdd41,0x3c2ae80f,0xc6213706,0x12823dc2,0xb58b0967, + 0x832611b1,0x7443d515,0x13c20384,0x2e16f831,0x2bd992d2,0x0ce204d6, + 0xf419388b,0x499dbcd6,0x1d3778c7,0x492ded1d,0xc5ddae73,0x9d5bd74f, + 0x994b6259,0xd4813d52,0x0e86ca68,0x191d9cf6,0xf3e9c2ac,0x562179ea, + 0x9fee1238,0x6146f1f3 }, + { 0x078e2aa6,0xbd06d33e,0x9dee9265,0x693af7f7,0xdaa40e84,0xd56e0f81, + 0x9b9a407e,0x05fbbb88,0xede99519,0xdcf44adc,0x092dba39,0x7f71f8d3, + 0x4231774b,0x675b5da5,0xa5f605eb,0x7456a251,0x87a39a9e,0x9031d4af, + 0x05b474bd,0xdb430006,0xb665aa91,0xbda5dbf2,0x6631eeb4,0x5d1a3df5, + 0x62377c58,0x028149ef,0x685d0bff,0x2e1af4e9,0x82a465de,0xe0ea0875, + 0x06bd0050,0x95543f9e } }, + /* 172 */ + { { 0x85d7c6ef,0xf7cbc6f4,0x63b1bc24,0xcad8084d,0xbf8cba62,0xdf90ce88, + 0xb455c192,0x98e4b686,0x774fc6ed,0x6146b8d5,0x7ae20077,0x70e2389e, + 0x61c22529,0x5241c479,0x3884e5f5,0x7d221510,0x17e28273,0xd6d20ce2, + 0x4f2674f8,0xe3119f51,0x70c011db,0x85459055,0xfcfb760e,0xdfab75d9, + 0x9e8c2a19,0x9546362a,0x4a7d4b27,0x4b6d3f8a,0xee5d698c,0xa5c87104, + 0x2ba296ff,0x6db43478 }, + { 0x5c3f0d95,0x06486493,0x4e748895,0x8917db82,0x6b2f3e44,0xf73fdf62, + 0x2b7f574b,0xc60edc54,0xaf732723,0xbe1c09a2,0x7cad114c,0x7d34669d, + 0x321aaff9,0x9646600a,0xed0cd61c,0xb94e2bba,0xdec4750e,0x866e1a41, + 0xb1a89f58,0xa1be990d,0xf2759693,0xc39e4d6c,0xc0e0dddf,0x11cfb780, + 0xd99c8a41,0xf0afcd7f,0x6e1c3050,0xcebffadb,0x96d2c6e4,0x4f3981b0, + 0x2ae27a94,0x07a791e7 } }, + /* 173 */ + { { 0x1e9f0300,0xe70e9047,0xbccdf904,0xe0253ad9,0xff053078,0x51c0289d, + 0xae893462,0xf1ef092e,0xa4846845,0x2c90a91a,0xf1dad4b4,0x1946eda0, + 0x33df67b2,0xf07650f3,0x0b15a014,0xc6e988db,0xb542f0f9,0x72e0c66e, + 0xe0c0378f,0x5d4b6311,0xae86950d,0x548badaa,0xb35f1c8f,0x6801638d, + 0x944d1ad4,0x129e3216,0x40471d32,0x9951bac8,0x85e94dde,0x03cc29f3, + 0x4543ecac,0x6d6acc2e }, + { 0x57b2d299,0xeb999e95,0xe3d721cd,0x3a2bcd9b,0xbb4cb444,0x2e60384f, + 0xdc060faa,0xae177709,0x8c987cde,0x74f0e6d3,0x1076fbed,0x9a237cf8, + 0x7983fbff,0x69af1513,0x323f9584,0x6c3f7a1d,0x6db64398,0x3e21cacf, + 0x96703d92,0x7cd8134f,0xb8393f76,0x0755898f,0x2e825222,0x1b5b28bc, + 0x7924aa7c,0xb78799c1,0x81427a8a,0x1db378f2,0xff289492,0xd5a451b1, + 0x3d3c46ee,0x79d18212 } }, + /* 174 */ + { { 0x109d5589,0x1a3edff9,0x029b4499,0xded52eb4,0xb4b54adf,0x13eb9d30, + 0xa27bff67,0x4f9214c1,0x67f0f460,0x4c817ee7,0xc3a50e28,0xbadf8d83, + 0x94026237,0xc5dc03c9,0x966647c1,0x5f29581b,0x8a0687f3,0x10b6a089, + 0x31634517,0xae787cec,0x62e75188,0x2001dba5,0x45e2c3fb,0x55d4e1a7, + 0xb67d3395,0xbfcacdeb,0xbc6842ee,0xa1a0af9c,0x3e88580b,0x50590a2b, + 0xa784cdc8,0x73104491 }, + { 0x2648d676,0x44ca2cdf,0x4f1b12b1,0x9a85eca5,0x2980e1eb,0x1b9dac94, + 0x1ac8aa89,0xf30d3709,0xc719e195,0x73072ab7,0x2f703797,0xba518c82, + 0xac0067f6,0xac090e14,0x8dcd2927,0x0e6cfc70,0x21e7da63,0x4f5889e2, + 0x8371c7c6,0xb4aaa40b,0x8f7878c9,0x1f9dabe2,0xd84caf3f,0xf78aed6b, + 0x9e0e1d92,0x3c39dd07,0x122424dc,0x680be5fb,0x0bdc0099,0xf41b214d, + 0x5180c54f,0x6a8f8fc9 } }, + /* 175 */ + { { 0x53235132,0x62a1ed63,0x59dba88b,0x1db233f1,0x291efdd8,0x85625452, + 0xb25111ae,0xc7505297,0x1d701bd8,0xb5921af9,0x9774f45d,0xb4d05d72, + 0xf18e73ff,0x6e3d4c5e,0x899b3038,0x897d985f,0xc89b1558,0x8a9c30fb, + 0x4d13181c,0x3c92d1a3,0x2223320e,0x292e86ba,0x01ceed02,0xcf2454c2, + 0x583f309f,0x27a45f74,0xad0fd1a3,0x75a6102c,0xcb9c7538,0xdb4f45d2, + 0xdb283fd7,0x4752d8c1 }, + { 0xd5dff4d5,0x514d6cea,0x45a827f4,0x74cd5fdb,0x4fc7135e,0x1070a60c, + 0x1be5778e,0xdec0bb78,0x58dc6b08,0x271e12cd,0x54bc2496,0xb765089b, + 0x619098ac,0x6ddf2c63,0x67528832,0xfd6ebac6,0xc2508af1,0xeaa2d025, + 0x4dcfc1f0,0x13c2cda8,0x45510be0,0x1c7836a8,0x1a886801,0x3904688d, + 0xafaf2545,0x643132aa,0x2830a88d,0x49685577,0x8744b470,0x569491ca, + 0x75fb8552,0x3a6518f3 } }, + /* 176 */ + { { 0x224042a0,0xaaa8ed50,0x2452f1e6,0x6cb4e3b0,0x768211d8,0xedca5f4c, + 0xef4d5d3f,0x4e0fe3f9,0x522d46e5,0x33a8e2a4,0xf1446775,0x5998e21f, + 0xf592d01b,0x1496c50e,0x83a67739,0x69104c2f,0x472bbf00,0x28670bcb, + 0x503177bd,0x8ea883b2,0x7d2712a2,0xc5d8bc05,0xb439c994,0x41ef9317, + 0xdcda1aff,0x9801d3a8,0x7038f6fb,0xd686eeb5,0xfbfbf820,0xe80c5cd0, + 0xedc25817,0x540ac363 }, + { 0xfe7f43df,0xa71969a9,0x2c1b9e4c,0xe6653808,0x859c2917,0xad9677d8, + 0x96aa4404,0xbaca9545,0xff1297da,0x0e9d855f,0x22aea7de,0x1f61897b, + 0x36f13f8e,0x96edccfd,0x16e200df,0x627d3070,0xc98988a4,0x729f0736, + 0x97f231d2,0x95e25e60,0xf6048752,0xaf7f221b,0x4019b299,0xd6682609, + 0x26b4b1d9,0x1d99de09,0x1acdd7a3,0xec47cf66,0x6ebe15e9,0x4de9f2b3, + 0xfa16974f,0x17db32ec } }, + /* 177 */ + { { 0x6cf40599,0x75ef6919,0x00c020ea,0x7ea10dfb,0xfcaaf679,0x3da5ae7b, + 0x88ddd678,0x0d663ca3,0x255bcfcd,0x5a21f8fe,0xe344bc7e,0xe9c3f538, + 0x548e0632,0x35f62b1d,0x43c6e64d,0x654f2425,0x26993627,0xc755a7a6, + 0xb0f41324,0xa3b7c5f7,0x3a2180f3,0x05697f79,0x1e81675b,0x6cf85fb1, + 0xe53428f5,0x6d3cdb35,0x52d28b02,0xe3aa1591,0xf7a3fb78,0xa8470255, + 0xa194445d,0x460bd01b }, + { 0xc24d8077,0xbc34dc23,0x4c720d2c,0x82f4b580,0x6f5d1ffe,0xa29da911, + 0x92783ce2,0x578af520,0xb5904af3,0xe29f51ab,0xf7aa1190,0x46c570d7, + 0x571bddf0,0x4a522fba,0xae89bb51,0xbf4e2a06,0x59f3444d,0x799b35cc, + 0x26cc2557,0xc3028367,0xafcec177,0x94a4e985,0x7c36cbd0,0xadaf7dcb, + 0x75d39077,0xed31b787,0x2d3e24bc,0x52d6904f,0x1f95421b,0xc5ca2669, + 0x1734878d,0x7d342c3c } }, + /* 178 */ + { { 0x11fd127f,0xe5cf2c0a,0x119e4c5e,0x66d36bb8,0x6ef56ac3,0x621ab252, + 0xe5430675,0x30cfeaee,0xac3e9619,0x2ede27d2,0xf8fce671,0x6413513a, + 0x075f4c3d,0x6159c61b,0x59069d98,0xd447efe9,0xea76aea9,0xaf8d6f68, + 0x0f5bd164,0xac5dc61b,0x1e88bb98,0xdbab446e,0x1ba92320,0x618b8b16, + 0x78989865,0xa0eafb3c,0xc08b7e82,0x0c7abcc2,0x20d160bb,0x10f09b6e, + 0x8e4c63a7,0x5be0afa6 }, + { 0x1bbbf49c,0x82ab6d38,0x8c0703fe,0x3e09ce49,0xe10f4263,0xeca58b5d, + 0xda5a4532,0xd9cc6581,0xf618f7b7,0x07e18876,0x250f7fe7,0x0419a5e3, + 0xde6b86be,0xbb1a9e90,0x37359169,0x584a7deb,0x5149db2c,0x38eb3489, + 0xb0ebabb8,0x14546a33,0xc2f88a92,0x0067f0b0,0x0a2db019,0xbde0dfe7, + 0xc63e6f3e,0xba51b06c,0xe9206fad,0xa19127b9,0xfe80dc0a,0xe4eb5e87, + 0xd4de30ae,0x1e6fccf5 } }, + /* 179 */ + { { 0xaa8ac924,0xb57dff66,0xc298b3e8,0x06e9ad31,0x65fb080c,0xd140e329, + 0x1d95c93f,0x7dab211d,0x8a180caa,0x6d68d842,0xa20ded69,0x1a929408, + 0x38df461f,0xa8151753,0x60eae932,0xff5604ae,0x7dae4c0b,0x901b9e49, + 0xde262e89,0x4573a97f,0xf1084983,0xed69d9a4,0x64724f1d,0x8ffa022f, + 0xea85a15f,0xd5f1c2e4,0x01453794,0x4c626ce9,0xbf0907dd,0x80440cd6, + 0x5ddaa837,0x4522d461 }, + { 0xebfbe7c5,0x8895f079,0x84ef3446,0x30ea1ded,0xd4a1ab96,0x716a9eb6, + 0x50a30c68,0x1a4a5d22,0x0043bbaa,0x5a16631c,0x5010e5f5,0xbd107502, + 0x3d8c0556,0xbffe3e9d,0x07772419,0x31b30b18,0x84b82297,0x90ff7ef0, + 0xf21a18c3,0x00c37d75,0x565bb8f8,0x18d0a635,0x45e3bceb,0xbac1da2a, + 0x23f0b08d,0x1c38e90c,0x5fbc5ac5,0xf1ba1aa2,0xdda71fc6,0x09d5256b, + 0x6d7e40ba,0x346501a9 } }, + /* 180 */ + { { 0xcc2b0f1d,0x86be448c,0xac4c3703,0xe3eb45c9,0x9fc96bbf,0x5387f65d, + 0x5ae27fda,0xcef3c4e9,0x1bc18089,0xa008f776,0x22ca18a1,0xf374a084, + 0x53b73371,0xee882842,0x7cc09354,0xcb6fc6d8,0x61496d6b,0x8489ec1b, + 0x49e325c4,0xa92c29b9,0x7bdec166,0x15c6ca52,0xdcea2813,0x95444eee, + 0x3a21154f,0x34683eb3,0xd39061cf,0x8fb26f98,0x06c940bb,0xc3b08aa8, + 0xe554c96d,0x7c1d42cf }, + { 0xdc110aa7,0x766e703f,0xf362e378,0xab7b79d7,0x5aadca3c,0xd259c75d, + 0x60be3373,0x2a6eca79,0x06c4e8ff,0xf4744a4b,0xf3b705bf,0xb2842cce, + 0xae304b53,0x1a3af5aa,0x1b2d31b8,0x7bbfa201,0x4bee88d9,0xc4ba6eba, + 0x565cb839,0x2d3565ce,0xdaf7ece8,0x24808696,0xe6959745,0x2c7ccce7, + 0xe94f9837,0xefd6eb3c,0x3811a326,0x0a33b4cf,0xfffa93a6,0x14203f43, + 0x73c31d90,0x031e9828 } }, + /* 181 */ + { { 0x765a17ff,0x4fefecfc,0xd1290a65,0xa09f3888,0x938da038,0xbf265c46, + 0xa169ad46,0x4bb6145d,0x23a62fe8,0x33cf8214,0xabc860a5,0x562df571, + 0x815c38c4,0xbf2a90fa,0x17eda875,0x45ba1d6e,0x946fa5e1,0x799d881a, + 0xb90f5a3b,0x6c1be784,0xb10ff52a,0x0910a37c,0xa4f4fd36,0xc38c1fe4, + 0x8e2d3ba0,0xc3180fc5,0xb17a6187,0x3e2ff050,0x943a35c2,0x3a00059b, + 0xa28cc51c,0x494d3645 }, + { 0x4ba021f8,0x398426b6,0x796deb6c,0xd14c9083,0x7e36c762,0x6d2e5395, + 0x751cf216,0x8f556eca,0x19b24a19,0xdaca1e00,0x4b20c2ae,0x47887da4, + 0xff41a733,0x93ed4ccd,0x5c7c0cd7,0x8d717c44,0x91bf7009,0xcc48634a, + 0x3b59bbaf,0xa1f146f9,0xe5624f15,0xdd38bb39,0x303f8443,0x96d41aad, + 0x4bf104fc,0x6b670f03,0x29706582,0x0503f9ed,0xb34200f5,0x768e1f47, + 0xbbd4c6f3,0x3cfdcc5e } }, + /* 182 */ + { { 0xb523e13d,0x536c2a86,0x2920d0a0,0x1014a458,0xe7571296,0x3d52b478, + 0x7eb51bea,0x05746066,0x87b0e919,0x709f7861,0x686888e8,0x028aed88, + 0xd94afcd4,0x79a809d7,0xe2129af3,0x50c6032f,0x983c4082,0x75e4be72, + 0x7ab3be8e,0x98331bbb,0xb618c728,0xd31a032c,0x3f59c4a4,0x36dd85a1, + 0xed4f61e2,0xdbece345,0x1e571715,0xba7aaccd,0x64a1ebd7,0x138c58da, + 0x3d1aeea1,0x89296d0f }, + { 0xcca82c97,0xb165288f,0x1427e8dc,0x26c6c12d,0x4c3edda9,0x66a94f07, + 0xeaa01ebe,0x94600e1e,0x30f5e86d,0x14abce7c,0xcb456a31,0x741d7020, + 0x279f42c2,0xab05aa13,0xd4238468,0x70b60faf,0x318d39e6,0xa18efec1, + 0x8920b318,0xeb07f1ac,0xd8399e03,0x01e3cba8,0x3c81a301,0x65f8932e, + 0xccc667d8,0xae8bca7d,0xa268607c,0xcee1ae79,0xcac0a12c,0x3182e64c, + 0x2b1a4c54,0x9233a2f7 } }, + /* 183 */ + { { 0x0acbee17,0x717e8df6,0x5c24fcdc,0x0f0959c2,0xe54ffcb0,0x46f09887, + 0xd285116b,0xb993deca,0xbba1fa51,0x0bfaa4f8,0xd0f2183e,0x9c9249ef, + 0x96847779,0xf93cb358,0x2322d421,0x284bfb7f,0xd42af009,0x40cc709a, + 0x9bb1d615,0xc69f2274,0x717c3c6a,0x76f50b3a,0xbb9c5eeb,0x8b21e985, + 0xa4783b5f,0x58fb19ae,0x52e1c3e7,0x04c86b9b,0xf2971ac8,0xaca59092, + 0x21ed8291,0x2bb26a69 }, + { 0x15f81416,0x98a34435,0xaaff5bb4,0x086e72e7,0x0317261c,0x3d1f64de, + 0x5c0a1cfe,0x31c0786c,0xb3683401,0x542ea4d8,0x1a39b4cd,0x2f77273a, + 0xcbef27f1,0x14fe7ee1,0x16bb27dc,0xee7fc09e,0x410e5dc7,0xc0dccc17, + 0x1943b3dd,0xa3466742,0x3f31c1b7,0x92934b60,0xc22c1070,0x0186ded9, + 0x799f966b,0xa37ee8ba,0x249b0893,0x0f3bfcb4,0x2e92d4de,0xbae61447, + 0xe196eb08,0x937cb3f8 } }, + /* 184 */ + { { 0x16fbfdce,0x57c0e77c,0xc98d4cc0,0xea034cc9,0x42572d20,0xe7606d72, + 0x0019a83c,0x9861b55c,0xf1597162,0x80ba2803,0x05a0fd7b,0x0f4141dd, + 0x4b0daaa2,0x8865913b,0xaa3848ec,0xe6685746,0x3e0485d2,0x16d15a5a, + 0x3b6905dd,0x81c0c774,0x818af2ba,0xcec31b7d,0xd2b74b78,0x80d8f194, + 0x543e2f28,0xca659db2,0x9fb07c1c,0x31b83a7d,0x1f1048c0,0x86537fdc, + 0x78586a11,0x4d57bb07 }, + { 0x53b396b6,0xbc4b768a,0x93b51dac,0xbc8b24c4,0xa30ae1b3,0x33e511eb, + 0x945147c5,0x893bbd95,0x179fe3ce,0x6cc86031,0x3f920bd4,0x34b0a167, + 0x6b256160,0xb32912eb,0x9d168d83,0xbc69a2a4,0xef0dd128,0xb4949e7a, + 0x872699e1,0x2613419a,0xbf21376b,0x06c58477,0xa4f97147,0xe55b1909, + 0x7b9b745f,0x63d6eb75,0x08df3c85,0xb5365b29,0x55fcfae3,0x0e257e43, + 0x979f2aa8,0x1067c118 } }, + /* 185 */ + { { 0x32bf8883,0xc8455084,0x6fd06667,0x4755286a,0x77c2335d,0xd70b0f8f, + 0x2f4a2c94,0x678e60da,0xd118acf5,0xa468d8ac,0xbf5b90d9,0xce93830b, + 0xed4e9104,0xea4b1c74,0x27776ea4,0xac67316d,0x361bab12,0xb98ad75c, + 0x99122451,0xc323d482,0x530a43ae,0x26440220,0x3292d5a5,0x3a44532e, + 0x5fecf1bc,0xdb48694b,0xc667b8b8,0xe4e0516e,0xa4306ade,0xb3aa595f, + 0xf34e9725,0x7e4f7091 }, + { 0xb7f70919,0x3f3816e9,0x16b003f5,0x765216ed,0x778c99e5,0x46c6cff4, + 0x30a51810,0xe6a5abe8,0x45e728db,0xef6f49e6,0xcaccefd6,0x6fdd73ea, + 0x8c37f3f7,0xec394e6f,0xb6407fc3,0x73320802,0x96625cbd,0x988e8f7a, + 0x7cabfb00,0x83292363,0x407f359a,0x258ba9df,0xccbfae50,0xff01aee5, + 0xfe251813,0xfbeaeace,0x83f1cba1,0x9c69f161,0x9eadcdb5,0x512c58ad, + 0x6ccce8bd,0x2ae49cd4 } }, + /* 186 */ + { { 0xc40849f2,0x1239b0e3,0xa441098c,0x5136a4cd,0xe547f649,0x61535a99, + 0x7a9bbac6,0x92e4bdc4,0x53547af6,0x195a1646,0x8b47a74a,0x85ecb319, + 0x9de6a2b2,0x278553fc,0x0e2ba52d,0x471c038a,0x35bcba93,0x12ba1b88, + 0x6f31eca2,0xd4bf50da,0x802b32c6,0xd146e3f6,0x3c64c8c4,0x0c9c0131, + 0xeed21297,0xad30f12d,0x9c68530f,0x9b75bffb,0x8918de51,0x23c0ad3e, + 0xa73771b7,0x180e9d52 }, + { 0x29ab77b0,0xc316542f,0xf7aee628,0xdd411d9c,0x353c2f40,0x044c0685, + 0x4b0ae4cf,0x638dc7e4,0x95fc266f,0xa0924185,0xfd2feb7d,0x639da671, + 0x5ea39798,0x56858ed5,0x58f3832a,0x7a694f31,0xd316d831,0xa94233c6, + 0x30a35a7b,0x2fcacb26,0xf1ff713b,0xfef8f7dd,0x59eee2f3,0x8b9b4525, + 0x156d064a,0xd1b4f91b,0x2f5cfcfc,0x177866c2,0x3777eb41,0x12bc2566, + 0xd8ab85b4,0x21ca6f3c } }, + /* 187 */ + { { 0xa3e66635,0x0e162b13,0x2a9f76af,0x1ef20a2b,0x46db3356,0xab473a30, + 0x7802bb8d,0x0840bd77,0xa699b44c,0x5b6baf5e,0x1b2207f1,0xc6e11900, + 0x790b0105,0xe5de16a9,0xdb67f004,0x22b12f15,0x8a025d25,0x185fad45, + 0xdf0a1142,0xbccf6953,0xf45034c0,0x4c42129b,0x1c277bff,0x0f740400, + 0x280a9e18,0x6e440b4c,0x842aa2b4,0x767de8f5,0x05e8d94f,0x3de20ab8, + 0x20227635,0x5aff5859 }, + { 0xa8458e40,0x805acd20,0x149732bd,0x5a5557d8,0x5f1ca72d,0xc7074131, + 0x952b5323,0x7f2e269c,0x6494fadf,0x5c592556,0x1a7d2666,0x153b7acd, + 0x86fe2865,0xa6df063d,0x57d53b6b,0x1e91db13,0xe93ead01,0x9195bb89, + 0x2963bfe6,0x3d71e1af,0x88278886,0xfab2b9c2,0x3b859b6f,0x77836692, + 0xf7029dd1,0x6e695174,0x7b984561,0xc7987876,0x5907d849,0x64fb4f1d, + 0x88d8a977,0x3eab7e1c } }, + /* 188 */ + { { 0x52e5718b,0xc73a94b6,0xf4cee1e9,0xe3aefa54,0x553eedea,0x654e9e63, + 0x5f3aca1a,0xf2541e1b,0x0d083316,0xd7129489,0xfb7f950e,0x7965af63, + 0xc74e3e4a,0xd8fc9e0d,0xeaf79ebc,0xb4ee48d2,0x8b7787e6,0xa458a86a, + 0xf7cceaf0,0xd8c7621f,0xdf67980d,0x8228eeff,0xf9106727,0x210d4742, + 0xb07e3629,0x91f63501,0x7971e29d,0x441761c6,0x03a3b8a5,0xc0ccc65f, + 0x38e09544,0x3491da4f }, + { 0xcb062eae,0x6706d046,0x5d08776d,0xee7db735,0x292315d2,0x80de8052, + 0xc402bbdb,0x40785662,0x26ed3337,0x5f93525c,0x7d568ed3,0x6cea14d6, + 0x66888b1e,0x916a1189,0x5dc71675,0x0fbd5205,0xe4575df2,0x833d1077, + 0xec092335,0x4e93100a,0x6cd85389,0x2f9e1d01,0x43226368,0xeebd3725, + 0x1ba4cfd7,0x401d172b,0x574c5838,0x377dab9d,0x80d517de,0xaeaa6958, + 0x6ad15a18,0x0c843dfd } }, + /* 189 */ + { { 0xc9373300,0x455811ff,0x99fdc300,0x1c39332a,0x353cb655,0xe19bb81c, + 0x96a83d27,0x774b924a,0xb2ee3f1a,0xcbfc8fcb,0x010d56c7,0xaf278ec4, + 0xe0abaf79,0x6fde682f,0x7339aebf,0x7566d072,0x71205db6,0xbd35ad5d, + 0x7051c9d0,0xb5bbe694,0xd3a3067c,0x577db480,0x572d7530,0x2c70ff54, + 0xe06d853d,0xe8615aec,0x05abfb5d,0x71999ccb,0xea0a8ed7,0xeeefc96b, + 0x35f6df69,0x2dcc469d }, + { 0xc65f0e77,0xcca6cd06,0xbd71b14a,0xddcc7980,0x3c93cc00,0xb6221f8b, + 0xae8cbf57,0xddfcd5b3,0x76f8e63f,0xbc92973f,0x06e132b7,0xe9848a34, + 0xd51ec9e2,0x4cc59a03,0x3a33081a,0x9c9d32bb,0x80e8466b,0x00121052, + 0x1bbe7295,0xc2b0032a,0x24938448,0xdbfc6572,0xb6bba0ff,0xe972a0ce, + 0xc0a94802,0xf60c0a4f,0x599d8bc7,0xf62c41cc,0x312da0b8,0x820c96ee, + 0xcdbdf9fc,0x5a1a65db } }, + /* 190 */ + { { 0x42485684,0xbfba691a,0x29c470c9,0x613116b9,0xe62a0519,0xb4b01971, + 0x5ff499da,0xf3245aa6,0xa5238eff,0xc2ef87f4,0xcc9d5515,0xc16dc6ba, + 0x2dbdacac,0x5a7f227e,0xa9bbaecb,0x8dedaac4,0x2e7c9885,0xff308a6d, + 0xe6895593,0x4c6f2fc2,0x177e0611,0x3655f285,0x300b1bee,0xa63e8d06, + 0x13c17b54,0xbed0ce79,0xc4974262,0xca4abe35,0xbc4e4037,0xf4b44a17, + 0xefe5fbd9,0x5ae95099 }, + { 0x804f7455,0x122e5ee7,0x22066682,0x341a4997,0x7795e333,0x97d24c31, + 0xe48efced,0x12f4123c,0x19fbc21c,0xe8738d92,0x0663a3ae,0xbb3bdc61, + 0x8593a6db,0x3603d8c2,0xe3c1ac75,0x926227f2,0x5eaae519,0xfea92ac0, + 0xfd6812ac,0x5b596f0b,0xfc2a82dc,0x3ce7e844,0x63522b27,0x3840481a, + 0x52867895,0x836088b1,0x26588688,0x21ffb7cc,0x2f4a7cac,0x0ca33161, + 0xa3edd298,0x4110667e } }, + /* 191 */ + { { 0xc2d04b63,0x81830357,0xf4929a18,0x3fc5a34d,0x22d195df,0xc73bf6da, + 0xcb432473,0x14df2f89,0xe997f138,0x345afe5c,0x8b9604f4,0xd8e3f5f9, + 0x50c10ae5,0xad7942e9,0xeed25ff3,0xcefd5447,0x0e73c0cc,0xbf68e51e, + 0xab54fa4c,0x5b1ad591,0x12b61c8c,0x8bbc1105,0xb5abf760,0xbb932913, + 0x01e79649,0xdb1231be,0x040ccbe7,0xd0a83e91,0x90a96db9,0x3dde426f, + 0x34df11ea,0x1cceb645 }, + { 0x0c6d0f55,0x2d210c4f,0x9c673c9d,0x6cadf61b,0xa9ce3fbb,0xdd7f9919, + 0x93b063e4,0x135f494c,0x145a93be,0x580bdb3c,0x0f52ef7c,0x4d872332, + 0x8814bb6a,0x74d876e8,0xc7a97dee,0x4f6f723a,0x3e3cd833,0x7de2b8f0, + 0xae720270,0x6162f082,0xddfa486e,0xe88ec2d4,0x8d3a17c6,0xd965c859, + 0x3980171a,0x62e59e54,0xbbef6b22,0x0ab6285d,0x4d48b203,0x3cf45195, + 0x4ea25ea3,0x1f175233 } }, + /* 192 */ + { { 0x3467ea91,0x808a765b,0xfd2d9c45,0x3f4632ee,0x9cf2bc6f,0x7b75dc6d, + 0x359813ae,0xefc8d240,0xe44cbd8d,0x23ecb209,0x21525622,0x59ba10e3, + 0x3f1ee19a,0xfa14d934,0xfb0c48f7,0xdf97c21b,0xea30d437,0xc4e62890, + 0x651475c2,0xb286e2a4,0x126672a5,0x291f01e4,0x31aab3b8,0x9c6fda5c, + 0xe17d22ec,0xb7277a5a,0x914f0bad,0xbd88ed83,0x6a2392e1,0xd0b05d1b, + 0x65893c2b,0x4cb8af90 }, + { 0xbb4b1953,0xa2b02057,0xf597f6ee,0x4ce08b44,0x5e6412c8,0x854f5d9b, + 0xb3cd4919,0x1913262d,0x6e42bb5d,0x902762e4,0xd78e7f60,0x8355c8e6, + 0x38b6c16c,0x8efaa824,0xe550f618,0xd0173790,0xe57d778e,0x118af462, + 0x715b4714,0xa16ad5e8,0x41dea4f9,0x900596c3,0x280ca610,0x2a957c32, + 0x374c65a1,0x2faee800,0x50080414,0xdb105127,0xff080fa1,0x8c1db931, + 0xd79878fc,0x486a5c25 } }, + /* 193 */ + { { 0x941b4f36,0x0521e213,0xf803b4f9,0xbaacfb14,0x52a54ba8,0xfdf1e22e, + 0x8fe4796c,0xacfabbba,0x58dbacb6,0xae0788db,0xc19dfa51,0xdf98d736, + 0x35a716ee,0x155c286a,0x9c86461b,0xbe7d4676,0x63a64a5e,0x50b6380f, + 0x9f609262,0x14b41914,0xa2dfc5b3,0x0919a7d0,0xcef466ac,0xc454da55, + 0x6986aaec,0x93fa4a24,0x71a49ced,0x5090b171,0xc1fa75ad,0x602f1d6c, + 0x78e4c054,0x5d269f89 }, + { 0x14920419,0x3a74030c,0x90968739,0x0845d868,0xeeb70fa6,0x81b994c4, + 0xd9fc5bcb,0xabcaa06d,0xf58f8f2d,0x06539427,0xb1dc52aa,0x35c85f67, + 0x2c911baa,0x5a7d8d72,0xaec2d834,0x4041005c,0x7a8e5347,0xb5868a44, + 0x8de512c3,0x04ee180b,0x211168eb,0x4daa66e5,0x2317cd8a,0xc0bd5dab, + 0x61164df6,0xa1d4185d,0x1dbad7c9,0xacedca26,0x09b02683,0x0fe4b5ac, + 0x26d9550f,0x8ac9995a } }, + /* 194 */ + { { 0x2640a39d,0xb2c8dc9b,0xede0c9f9,0x21ff0b38,0xa1ecba0a,0x74f469bd, + 0x080d0417,0x8a902ccd,0xf4994604,0xe956fa32,0x9776ab15,0x348f85cf, + 0x0066f492,0xc21fc6ee,0xfeeef367,0x35b1ebfe,0x4613e5ed,0x7804581c, + 0xea6ba071,0xcbdfe8e6,0x950d73ed,0xddfcaa32,0x1da48889,0xc9747936, + 0xdbaffbd1,0xce867c8c,0x1cbaeae7,0xd267431f,0x897912c8,0x68255045, + 0xd7ea1e4d,0x0c7c1ddc }, + { 0x1ce963a7,0x53aa30cc,0xc4c5fade,0x7352f64c,0x2828afbf,0x2b9aa2f8, + 0xca212107,0x64273c56,0x85a576dc,0xaadd7654,0x90b5c77c,0x6196ac3e, + 0xd1aaf39b,0x20d43e9f,0xcd05cbc4,0xfc392062,0x4c0ff2fd,0x14163872, + 0x2ae821e6,0xcf32b8d8,0x3fa7a3f0,0x5f58f943,0xf644ca92,0xaebf1d2d, + 0x1918a75f,0x0c061563,0x6b876118,0x7989b5ed,0xad412441,0xbf342445, + 0x1df633ab,0x24ffc9ae } }, + /* 195 */ + { { 0x93c7cb2b,0x89fcdc05,0x590053fb,0xc1243b95,0x6182343c,0x601debcf, + 0x66c18a63,0x364546ef,0xec913287,0xa5290701,0xf9788c31,0xc35b8026, + 0x92d1f7d7,0x852b862a,0x0aa79728,0x1809cb05,0xa3cb2005,0x897d467c, + 0x9ef5b946,0xf20c77c0,0xf2241984,0xc3372c42,0xf35bb206,0xda053e0d, + 0xa9c140b5,0xbc26c6d0,0xcb56fb33,0x61cfcc0c,0x299b3968,0x1c3cf9ef, + 0x40621ba4,0x89e4d3d1 }, + { 0xa45a9be3,0xd35e80e7,0x07356fbd,0xc4daa578,0xb967bc2f,0x0186d62e, + 0x47cd16e3,0xa702679e,0x5f30ce9b,0xca2f1c02,0x1f864f50,0xf1205b46, + 0x85061d66,0x7fd6d797,0x8a08809e,0x47edc4f6,0x9a4d3ae2,0x5dac0449, + 0x6d1f9da8,0xf844664a,0xd7a83a71,0x9f30ce84,0xeaac33f1,0xe9382bac, + 0x948622ab,0x1f033831,0xf7681eb2,0xb037a4ba,0x99a1b5c7,0xd156a908, + 0xe6f1d0fb,0x675d3e6f } }, + /* 196 */ + { { 0x707193e5,0xd9767ffd,0x810358e5,0xe478aa91,0x328d8ef7,0x5634f9ff, + 0x6dbbd9a7,0x913a0ee8,0x7e215686,0x379b2968,0x89d9da38,0x903f410a, + 0x1b1334d2,0xd9f8d7b9,0xbd82efb5,0x9fe74229,0x3803c778,0xdb568b62, + 0xd3d25344,0x93e9a350,0x724497e8,0x559c35b0,0xa169e23b,0xc472d436, + 0xcc5b4c69,0x09864632,0x83c7f531,0x9f6d759d,0x1e497888,0xa91cf1db, + 0x60af1a4b,0x5f7f92fe }, + { 0x0545167e,0xf18a1cc6,0xaffa88e0,0x55ee2e02,0x432a7bcf,0x24cdff51, + 0xa7510866,0x7382da42,0x40511af7,0xe894c11f,0x2aaf1423,0xaa4e4e31, + 0xf63dd2ae,0x8c3d36f0,0xd7660635,0xfc5c9550,0x37ea7eab,0x01253731, + 0x39b950f6,0x2a5cd598,0x40e63442,0x95a0f601,0xf2ac7045,0x905e238e, + 0x446b0f73,0x44bacc0e,0xc448578a,0x4cd4206e,0xa5bd7803,0x367b1aaa, + 0x0a2b458d,0x25beced9 } }, + /* 197 */ + { { 0x0c33a8fb,0x079a7382,0x0f25dc1d,0xcfbf6cd1,0xc6d482b6,0x4ffc73f8, + 0x07bf844a,0x3e51f18c,0x599162f0,0xa7651236,0x14013811,0xac59a74e, + 0xe55018a0,0x957a6865,0xe3ca09b1,0xe1ec51bd,0xa960253f,0xbc0c7eb3, + 0x7de03f84,0xe83bfd14,0x52fbdb09,0xc0540ed1,0xcea15ec1,0x6ba52edd, + 0x4b261307,0xf3d30ed5,0xe8397206,0x9bd7bae8,0x096373aa,0xf20d8692, + 0xc3b0bf63,0x0a616a4b }, + { 0x6e1339c9,0x2075f3ed,0xbf8b00a6,0x7afaa072,0xbccd9b47,0xdfafec82, + 0x00ca54c7,0x4713158f,0x38bc31ae,0x449102f1,0x310dfc8a,0xaf98f158, + 0x59e954d4,0xc9ef2075,0xc527a0c4,0xe8021af9,0x7a192023,0x6e801277, + 0x7fb02377,0x635f538c,0xe8c9e951,0x5df1974f,0x15cc9097,0x0287faed, + 0xf7a5115c,0xfa0728f0,0x0fac623d,0x90dbfbe6,0x0311ba09,0xa8d40fd4, + 0x07c6464c,0x876d154e } }, + /* 198 */ + { { 0xc2d3ea8a,0xd3a4d6d2,0xa842600e,0x36be681b,0xe4070672,0xc53f100d, + 0x6a7d7a7b,0xe3e5b6fe,0x5d5e1a83,0x6e6994f9,0x76097c2a,0x07cacd22, + 0xa6791011,0x12d98dba,0x102e0e24,0xddfc4461,0xd493272a,0x4815dbc2, + 0xa9436696,0x7e38e64b,0x32b2bf90,0x4960eb1a,0xd928e28b,0xda457525, + 0x2a077c9e,0x72f75b39,0x7fd61d00,0x27760cbb,0x0f4b1456,0xaf235d1b, + 0xe76d1700,0x3040c23b }, + { 0x4efa9a70,0xb10dc55b,0x53e86610,0xd4de414f,0x09f8a27f,0x3d95c113, + 0x06661d3c,0x505109a5,0x60eb513e,0xcaa2994a,0x1e7d338b,0x3ee41537, + 0x4651e71f,0x4fd145fc,0xcbc313b4,0x51bbf838,0x1eb92150,0xb039e078, + 0x14bf5ac7,0xe8696b44,0x8be0d48c,0x2d667188,0xdd8f2b6f,0xbe93b2f5, + 0xeb8a7f8a,0xc1dfd1e7,0x90f751c5,0x862b3dd9,0xa32a74be,0x1eb1ad58, + 0x1ebbc9a2,0x5486d79a } }, + /* 199 */ + { { 0xa1359e13,0xcb2e34ff,0x28196051,0x202d8dbf,0x23564b5e,0xe95e023d, + 0x42f6ac12,0xfb1340b6,0xb653725d,0x543ba852,0x8d2466ad,0x81aedcd6, + 0x547c728b,0xbf780224,0x9569fb65,0x559f8a11,0xdfb22ec9,0x505b7a62, + 0x9eed5e52,0x07107540,0x299f6f11,0x9c899288,0x3db6f8c7,0xa7d69261, + 0xb3ca79a9,0x30eb7fb3,0xfb2160b0,0xcab99bb8,0xd28b409a,0xd2012568, + 0x5ac45f8b,0x380f1b0f }, + { 0xe6a0068f,0xc0b99e6b,0xc8a73753,0x4b67cf2a,0xb2faeb7c,0xa6c9a548, + 0x340260c3,0x7f417f99,0xcc0f739e,0x8ee56855,0x780949da,0xf08b510f, + 0x8d5c6eff,0xb1770fc2,0xfd96a7bb,0xb4f5abee,0xf2665a2a,0xa07b1136, + 0xb601dcf9,0x2fb380a4,0x162becc6,0xcc803614,0xee6b83b3,0x3498fb96, + 0xa8c17eeb,0xea9b0fd6,0xa177efc2,0x5834b5ba,0x5b110b3e,0x929044f5, + 0xebd7285e,0x4abedded } }, + /* 200 */ + { { 0x700ef376,0x3355e1b9,0x66cdabff,0xd56e5d9a,0x47e87646,0xb3dc2575, + 0x00f79369,0x28f44b8a,0xa0c52e29,0x08c32b1e,0x3729b392,0x5a78de12, + 0xb26d239d,0x4184519a,0xe0ce4a6b,0x23f6b4b7,0xacb2a9f9,0x235f6f8a, + 0xe2064a59,0xbb8bc454,0x1bf3062e,0x37efd034,0x94dff6f9,0x6bac683b, + 0x8aa7fa06,0xc3364b1e,0xce0b3745,0x0616772a,0xd1e3fb0f,0x46f08d08, + 0x18e132d3,0x6a20abb3 }, + { 0x6a85cbc7,0xea831016,0x934f9aa7,0xd0990946,0xe778f1b3,0xc2211088, + 0x2247b799,0x7ea4ff8f,0x454484ce,0xb3171d71,0x4f98c364,0x29403949, + 0x97df1458,0x5da911f3,0x09439116,0xa6b58093,0x174238bc,0x75f9509a, + 0x8209758d,0xfeb51821,0xa47925d0,0xae0c6021,0xaf8a315e,0x0e946694, + 0x6bad04b7,0xae7af8a3,0xf072447d,0x44c15e7f,0xa5456ffe,0x5184668a, + 0xbf36b977,0x45e353a7 } }, + /* 201 */ + { { 0x93092f71,0x76056764,0xf5b92d71,0xeb66b6c2,0xe2c8b6c5,0x9db3149b, + 0x20c0363e,0xf62f583a,0x03cd7097,0x688acd33,0xebb916ac,0x85d0c0f8, + 0x84c19b0e,0x1bf7462c,0x7c4a6ad1,0xc76ed5f9,0xd119f369,0xec8b88ba, + 0xebe50b83,0x59b8371b,0x866706a6,0x0cc69508,0xf8373d2c,0x531c75a3, + 0x2a5a02fb,0x4e1cd3a3,0xda39a1d0,0xe8274778,0x75da333e,0xedfc5bbb, + 0xca79bd36,0x15941f24 }, + { 0xa77dd512,0x42e8c0f8,0x1dc365f6,0xa91b59a7,0x08753862,0xe80d14cd, + 0xd272faca,0x1624230d,0x4027cb5a,0xeea3ec16,0xc1ef9f03,0xc1700b59, + 0x0da3148d,0xd411c127,0xc4181af1,0x801ee448,0x9e3a900b,0xedf28559, + 0x0d09affd,0x5d67b0bd,0x8b370024,0xd839df96,0xe6f836b8,0x3b6307e0, + 0xbd3201c9,0x5382e588,0x7a1d02bb,0x636d8a6b,0x968641e9,0x70b7db76, + 0x118fad03,0x6d17c34a } }, + /* 202 */ + { { 0xc181c99b,0xcf608841,0xc87bdcaf,0xb65dc901,0x3720dabe,0xb460b447, + 0x5377515b,0x4c79c396,0x0a96c277,0xd447f22e,0x2ac0f440,0x0d952130, + 0xc90583ad,0x8330b26b,0x928904a0,0xe25e977a,0x85c50b18,0x1deaffd9, + 0xa5ad5f6a,0xcf4dbcb7,0xc8a37ed5,0xcbcd0019,0x1e9850b6,0x7846dd90, + 0xb0b8e605,0x1ac8194a,0x34132f90,0xb9728571,0xf56ee28b,0x4ce9f149, + 0x3e9e1d4e,0x1ab9b5a4 }, + { 0x314fa7a3,0x206dab92,0x478ff963,0xcc4af0f0,0x904d9fdb,0x4cce1713, + 0x12c045fe,0xac20a2eb,0xfd8f6d7d,0x44fc5478,0xca7b6ffa,0x886e72c5, + 0x6fd6f758,0x7fa4529b,0x92a820d5,0x4df1d1b1,0x2789f149,0x3d812f9f, + 0xaabb53d2,0x9842f083,0x2a03ab32,0x2648539b,0xb1512502,0x631ce090, + 0x731f6bd5,0xe1294d15,0x9436e634,0xb229361d,0x3ca966af,0x8c4281c4, + 0xc21ab3ed,0x24b34956 } }, + /* 203 */ + { { 0x659824e2,0x49bdcb86,0x4e13e74c,0x6dc4ce48,0x6bbe1eea,0xa4c01a26, + 0x1e3ec457,0x47b2b8e7,0x2f5a8e4b,0x7e8b15e0,0xe333530d,0xe81eb6e6, + 0x17a45202,0xacba369e,0xd70e4c9f,0x81241431,0x3e12beb8,0xc190af4b, + 0x11f486fd,0x53270523,0x29fb2bce,0x9f6c41e1,0xb70f6c08,0xbe6287eb, + 0x3feb4477,0x1479850a,0x9bcf18bb,0xfcfdfb11,0xda80d040,0x925c292f, + 0x7e3c5bf9,0x212d65e5 }, + { 0xca15cf08,0x23adb386,0x81e172eb,0x4dfa4ac4,0x4d42d0c0,0x9d1dbf93, + 0x74404dc7,0xd9cf6073,0xe932bfcd,0x60508441,0x1c682a98,0x9ae910ca, + 0x41ac1cc0,0x9528fc18,0xdbbed630,0xe6a120ae,0x30ccf250,0x94e0e1ec, + 0xe58bbf2f,0xfe84ba54,0x9faa4415,0xc66d0b4f,0xecee7ce5,0x0c58f1e7, + 0x6fa6873a,0x7a1d43eb,0x399f1348,0x96c6c5a0,0xe6727ab7,0xe6ef9aaa, + 0x9a5c2447,0x66afa554 } }, + /* 204 */ + { { 0xc980e91d,0xda5aaba8,0x6ac98efa,0xa93cf509,0x8da32662,0xb0990e0a, + 0x0081453e,0x01d21530,0x3d71de84,0x2bb0d33e,0x3e19a012,0x465f6d80, + 0x78a838e7,0x5902ff4c,0x1931348c,0x74e2afb7,0x9cfb057b,0xa4932757, + 0x3ad03f8f,0x761ea642,0x58ffa40a,0xb7d4c245,0x77a87e30,0xb5e9c0d9, + 0xc9c84d26,0xd1c5edba,0x3d1963a0,0xeca8839a,0xebf6bf0d,0xbc6f2f35, + 0x0d58abdf,0x01ef0631 }, + { 0x3ecdcbb0,0x2bf90316,0x27c1c955,0x19e2d728,0x9575c930,0x9e527030, + 0x96983930,0x0dc1c5a9,0x7cd082df,0xef9f80ff,0xdf97e051,0xcd915075, + 0x9cc61b55,0xf286fffe,0x80f24cc4,0x352db38f,0x36523ae3,0xed9b99ec, + 0x10b104a9,0x109a8ca8,0x305203ad,0xc2700fe7,0x769400f5,0x2a2ee24e, + 0xee0c452c,0xd595d399,0xf7f02a41,0x0ab75d6a,0x0db730b7,0x34108099, + 0x5e8d1202,0x0e4f5ffd } }, + /* 205 */ + { { 0x0ff14c38,0xbd1c6444,0xaece11f2,0x9a5b59fa,0x22af6330,0xaa4605a7, + 0x82af24ee,0xddc9f65a,0xeb9a1159,0xf4ee4bfe,0x74e84eaf,0x2463d076, + 0x0e0baace,0x88cbe1e0,0xd5fabdcb,0x7ca568ea,0xc57eb99d,0xbd80d524, + 0xe9be9873,0x9c46572c,0x7300b85e,0x918a1dcd,0x40f54176,0x49221312, + 0xb5b14236,0xf7e324ff,0x2434f16a,0x40dda501,0xa133d97c,0x08833421, + 0x0876f020,0x33d41161 }, + { 0x9878e5ec,0x7531a36b,0x46918232,0x5de3e321,0xd0a30464,0xd15f9a33, + 0xaa173659,0x734c1b87,0xf925d4fe,0xac2094a2,0xc262b0f4,0x43c965a1, + 0x447d5cbc,0x759c903e,0x05239300,0x92af215e,0x1f593f34,0xfffb6d5f, + 0xc3cddb5f,0x65943b4b,0xbfdd5408,0x9d03a29c,0x198d76c0,0x8f7cda6b, + 0xc0f27b59,0xc0790a22,0x8cb58ccf,0xba557a84,0x76c54fdc,0x5922052d, + 0x47b6b466,0x2d3de7aa } }, + /* 206 */ + { { 0x65add3b7,0xaade7462,0xabf24c2a,0xe5888f35,0xe1a57d93,0xd41549ca, + 0x2c76f7bf,0x0e22e18e,0xbe3202b3,0x67f288ea,0x1d1d0f0a,0xb79a66ba, + 0x2881ad18,0x0e0ab749,0xc7adb0e9,0x7d424086,0x2842132f,0x870c32c5, + 0x58f9a09e,0x858477f1,0xec025589,0x422a9372,0xa5098777,0xbe428c5c, + 0x57660058,0x45b79564,0x957f37cf,0x6c7fc631,0xd6316289,0x8b7023dd, + 0x5b1c12a6,0x47003bb6 }, + { 0xc91c1c96,0xd99401c1,0x27a12970,0xaa5dcdf9,0xc3c29107,0x3ab92e17, + 0xa3fe4710,0x26fce8f7,0x4ee998ee,0xb0d09d5e,0x8e3a41f8,0xafa62204, + 0xa26ca506,0xb1c012a5,0x99b57252,0x2c6f734c,0x512f7fe1,0x1093d79f, + 0xacee19a6,0x2f30906e,0x056d1ea6,0x6bff8381,0xeff35f21,0x61c75856, + 0xc1ad2224,0x6e07e978,0x6b20fde8,0x2cca6ca1,0x633fe81b,0xab4d6d2d, + 0xb06a2ce6,0x73dff504 } }, + /* 207 */ + { { 0xd8e20fb8,0x8b615805,0x82b533f0,0x7c6873e4,0x56a854ca,0x5205f001, + 0xcb369211,0x87fec6ac,0xc7f092b7,0x1fa3c0ec,0xe845fe4c,0x5b36647e, + 0xf8b1f112,0xd4781e85,0x8b0f1a6f,0xc6526839,0xdcb8eb92,0xceeb8c6c, + 0x8e5f6d52,0x133f0ead,0xc8d934dc,0x31883e23,0x428ac45a,0x214ed5bd, + 0xdbbfca85,0xf77ca492,0x07e5ae13,0xdf4113fe,0x72ab05fb,0x63e4a0d2, + 0x7148f535,0x7544d0b7 }, + { 0x80797ace,0x4fe8d134,0xaf86d97e,0x216d6aa0,0xef5a68fc,0xdbf0a688, + 0x9f9b2684,0x18b26f45,0x8999d2fc,0x52fefcfa,0x62423955,0xd5af8d82, + 0xf63a3780,0x8f123469,0xdcd4feaf,0x2933454f,0xa73b5d09,0xba8018b7, + 0xe5552c18,0x9af1f276,0xff26bb1c,0xc5d4773d,0x06dd4f44,0x9ef49410, + 0x5f39ba49,0xad8f12f9,0xf66ca4f2,0x5767f6dc,0x7922f59a,0xba8773f1, + 0xc1e42d49,0x220081ea } }, + /* 208 */ + { { 0xba37a0ba,0x3043d573,0xdd176df6,0x05a431bc,0xc42070f7,0x03322cfc, + 0x67c2d109,0x5cabd30e,0xcbf8bcfa,0x362c95de,0x7787b10b,0xd767d277, + 0x6ec05e64,0x612c915e,0xce69c30e,0x9e669631,0x682e2635,0x27c9dd8f, + 0x95ffcc38,0x79021f12,0x8a2adca2,0x06a8ee79,0x4b5d500a,0x8e00e784, + 0x8d80d6c5,0x87746fc7,0x915f10cc,0x246053be,0x219f6fd8,0x844e328b, + 0x11bd3733,0x620541ac }, + { 0x509e5a29,0x0f7fd382,0xb432531e,0x8748d7d0,0xcd3883b9,0x8f749354, + 0x8bfbb17a,0xc6b8ac74,0x05f2d2c5,0xa4616a66,0x1bcb1b83,0xb3d96625, + 0x2fee265a,0xcf753104,0xdb225058,0xc70d73fb,0xf0c2d556,0x1211d434, + 0x54b259b3,0x862061d8,0xc42b3f7d,0xffe4606d,0xe86a4949,0x4c5c8585, + 0x160eedac,0x04ddcc8b,0x568e2420,0x1804ce67,0x42141656,0x91f3855a, + 0xf932be97,0x7f378198 } }, + /* 209 */ + { { 0xdfa6639a,0x9a374bda,0x02ab7391,0x0cbd48d4,0x47031e2d,0x5c5ef236, + 0xd0599d1f,0xb49ee2bc,0xe0d38443,0xd285eb60,0x269392e8,0xdbbea92f, + 0xb8bc538f,0x91455fbf,0xe469b768,0xae259ff1,0x41de5682,0xc1cecb1f, + 0x9952d1ae,0xc876f071,0xe7bf7446,0x1ce25181,0x282ad2f1,0xcb93ad86, + 0x6ba4ef67,0x8fa3cd31,0xe507aa3e,0xfce68a04,0xa61bb608,0xced74170, + 0xf6ac10d0,0x6de716b3 }, + { 0x172d6dc5,0xd4e58d04,0x6397c65c,0xbed2cde6,0x0c9eb4e8,0x7ae77e18, + 0x75fa2edb,0x56275468,0xa91e6738,0x4b30324e,0x235c8b2e,0x6023a856, + 0xa8f92887,0x9df6d6c2,0xf6f5e8b5,0xec2c185f,0x3ad5748a,0x7892e12b, + 0xd54aefbc,0x7aebb4f2,0xee868821,0x14915448,0xb1d9bd5b,0xa26c5f71, + 0x2ff00df7,0xe5ccd166,0xb95b1dee,0xebc99f17,0x3fe1f774,0x90983616, + 0xbb3d25b0,0x51f90830 } }, + /* 210 */ + { { 0xf2922461,0x49376fa1,0x1650d0d1,0xdbb1b1c3,0x0dd8608d,0x92b91c33, + 0x36b89906,0x3e612c4b,0xdf560052,0xe1977b0b,0x636a2545,0xf8afff70, + 0x11723d8e,0xcda7d278,0x81bde7ba,0x0b0bc4bb,0xed2a578e,0x3cb080b2, + 0x171b2e02,0x5bda0d0d,0x941bb9ae,0xf6df38cf,0xc14a65c5,0x85dd81db, + 0xc19dd98e,0x7f98c82d,0x52206f93,0xc613747f,0x5f5bbe78,0x9e13a2c2, + 0x0aa34be7,0x5eed218e }, + { 0x01d4dc0b,0xe1565754,0xf566bb07,0xa1ae5f27,0xb82225d5,0xe985ebeb, + 0x1189ec6b,0x5f3ad21c,0xecce4d9d,0x17da518c,0xd6b65b59,0xc84a2d3e, + 0x8ffa771c,0x7f988175,0x2ac69a7a,0x50d6ae12,0xc6e6846d,0xcb7f30b1, + 0x5bd0bb13,0x8c023a60,0xd73f2407,0x9a10fecd,0xe5f0a996,0x8c5158cc, + 0xbd8f5806,0xd26bf615,0x915a46e1,0xaf32ea87,0x0287d308,0xeaf74e81, + 0xa6264254,0x8c14ba06 } }, + /* 211 */ + { { 0xb17ee201,0x0c877895,0x88e57a77,0xc05aa471,0x97822456,0x19c3e763, + 0xc9c3ba1d,0x0be6f8c0,0xb4389ebe,0xfe85f4ff,0x0ce7fbb6,0x538bccce, + 0x65266c64,0x876eab2a,0xcf9a3842,0x5c9ac690,0xccc8f981,0x9f5cf3b1, + 0x9cf687de,0xfa17be6a,0x83835c15,0xfcfc10fc,0x150ef2eb,0x086b0fdb, + 0x884a52e6,0x9f97ecd9,0xb0cd1eb8,0x416e6fa2,0x3ecc03ba,0xe2bd1599, + 0xeabb165e,0x645c0a5d }, + { 0x50aa7e31,0xd94c4205,0x2f851da5,0xaec8df0c,0x3c726e6a,0x99646909, + 0x2619bf9a,0x72dbdc36,0xe253fbd5,0x1b4260e0,0x8c709e06,0x97c259fb, + 0xcddaec5b,0xfabf7cbb,0xe4b703e9,0xb4d5e8b1,0x0734efdd,0x1b06e56e, + 0x1f55f8a5,0x02d4a4f9,0x3f565c8d,0x7f8608ba,0x816d1d94,0x822f47d2, + 0x5ce7b136,0x0cc36156,0x31d04242,0xe46ee5ef,0x683567f6,0xb2a65f70, + 0xd2fa6c91,0x27e9ff40 } }, + /* 212 */ + { { 0xd7e952e7,0x75251893,0xc735bf18,0x15b30583,0x96fe0491,0x732b5992, + 0x806d2fca,0x27451858,0x1b885ed9,0x71ab76a0,0x6d9f55ec,0xbdce9d97, + 0x48f2ba9c,0x3da60b20,0x592b132b,0x6977c086,0x099051d7,0xb6dca9cb, + 0xd188ae25,0xd9c2ab23,0xe20aaf3d,0x9f469f3f,0x5aad74d0,0xdbd1f7cf, + 0x22a9eb3b,0x3d5efe5c,0x137010c4,0x8c5edfa2,0x57870260,0xada2217b, + 0x3dac9776,0x4feee567 }, + { 0xb5d3d780,0x30e18d52,0x07166744,0x4dadb5d3,0x5a742156,0x320d386e, + 0x8d6bbb86,0x5d8c290e,0x2d263dd1,0x981a4323,0x98984636,0x33d0e7ca, + 0xa519acb1,0x5138784d,0xdddc81ff,0x832e3fab,0x3199a43a,0xfc278594, + 0x32743163,0x5b4cabcf,0x74f94fa7,0x9fa010bd,0x5694a627,0xc28a743d, + 0xcb657a24,0xc1d2a888,0xe86a25ea,0x7eef2503,0x04c561ff,0xed11a5d3, + 0x9c9ede0e,0x4fe818e7 } }, + /* 213 */ + { { 0x7fc1c7ff,0x00252c9d,0x9fa89ad1,0xa9bd419d,0x4064e9cc,0xc93a124a, + 0x43942ecc,0x384cbcb8,0x8749695b,0x004c21fd,0x421165bf,0x69c81d9f, + 0xdde01102,0xe2325628,0x5a9b004d,0xec937457,0xf6dcfc21,0xfb3346bf, + 0x4d372c7d,0xac4da64b,0xf20494e2,0xcecb7ad3,0xe867c150,0x562c41b5, + 0xc2b723d8,0x299395ce,0x7ee53231,0xc91adfc5,0xf10b6597,0xe06f1161, + 0xb74d3ffc,0x81915529 }, + { 0x6ed9d4ee,0x8ec12431,0x689aff01,0x3dffa154,0x2a89a3f4,0x4aba349f, + 0xd467efb2,0x2db1e8e2,0x039102e2,0x18dea354,0xe52f082b,0x422ab853, + 0xed36dd47,0x7130a2c1,0x0295d1ee,0xca60e86d,0x7c7f5ad3,0xe6ac6808, + 0xde864658,0x0f83cecf,0x461d1265,0x72e66c21,0xbd385099,0xfeef4150, + 0xa6632289,0x0f183f3a,0x792dc795,0x275454be,0x11367702,0x2744c11b, + 0xe8ea6ef3,0x7d06bcc7 } }, + /* 214 */ + { { 0x7090212f,0x89285942,0x5521e844,0x691b7d4c,0xbe2dbb92,0x4c038422, + 0xbd81f880,0x317721ed,0xac89bc36,0xc136cbee,0x7b8f004d,0x4f71b60b, + 0x4e218ab8,0x269132d0,0xe6cc814d,0xb0e2496e,0x75fadc15,0x0b2ce317, + 0x66d223c5,0x82e3c084,0x4c612f8b,0x9721caa6,0xa4b65355,0x59a751eb, + 0xc7d3d9d1,0x3433aad5,0xe80d4246,0x1e61b9d2,0xfc673caa,0x149f655f, + 0xd0f9cb92,0x48b52b99 }, + { 0xefdc05be,0xa3915399,0x13e095e9,0xde70db18,0xcddb3fda,0x447862e9, + 0x1a009451,0xa2b03162,0x23920ea3,0x4b27980c,0xa23b8feb,0xac5394f1, + 0x3e5616d4,0x163f7256,0xb714219a,0xaa0ff93f,0x93d62474,0xd26f96d2, + 0x7dcfe276,0xdd212ea8,0x47038d15,0xab27bf2f,0xf418168e,0xe58c8325, + 0xb32a989a,0xe3704222,0xbfc9f13b,0xa3694390,0x0d0684ad,0xf16e2606, + 0x9d8c76ec,0x17c0de87 } }, + /* 215 */ + { { 0xdcc01958,0xbca5f453,0x1ce88393,0x7d945954,0x561f5b6d,0x5e6350a1, + 0x7e2d36bc,0x291c3c86,0xa5ac3a6c,0xf6c7ed84,0xd98006cd,0x7913c40b, + 0x5671ec3b,0xf78bb087,0xb43e89a9,0x1c928f6e,0xae1ea1ed,0xfdf28df3, + 0xb924b2b5,0x62bba5b1,0x1a116e05,0x491d2705,0x167ed3e3,0x08ec02b7, + 0x5bc0b046,0xe291cf7b,0x8c5d7f59,0x30e50169,0xf5c799b7,0x0c7c350d, + 0x0ac6e1d7,0x6862b9e2 }, + { 0x9ffa1f64,0x56c6f4e7,0xa1e24349,0xfed6a91a,0xcdb75232,0xe9a0ee0c, + 0x0322d607,0xbfc90b37,0x462fef87,0x29480ad2,0xc2bfcf34,0xfc214969, + 0xa539e38f,0x6e5211e0,0x12a5149c,0x2a59ec26,0xd706b532,0x195fe212, + 0xe99c8429,0xf77fb108,0x5dc80482,0x74ceaea3,0xbd92d298,0xa5a6030b, + 0xaaea15ee,0xad42dca5,0x4987109c,0xd6ac3bc7,0x290af649,0xc64e1c40, + 0x51f8de6c,0x5093fa2d } }, + /* 216 */ + { { 0x4c2d553b,0xc4cf3280,0x3b966c29,0xdc1abe22,0x2296914a,0x556a549c, + 0x999976c9,0xd8c9f8b5,0x776e83f3,0xc22c57bd,0x7c85ec57,0x4f2942ab, + 0x6e2c61f5,0xef3407e5,0xf213db48,0xf005e8ca,0xf32698c7,0x470c853d, + 0xcac0a54b,0xe6f488d7,0x60b7501e,0xb6bd6bed,0x714a4bd9,0xf0103106, + 0x6e098894,0x5285bc3b,0xf5f92a00,0xec06741a,0xef7ef24a,0x32f16426, + 0x6c77a438,0x12f9c44d }, + { 0x83313a1c,0x1951e964,0x33c58b37,0x98edd3da,0xc7ac4044,0x4edbbf52, + 0x0dcb5ee8,0x866ca6f7,0x6dd422f8,0xec0ae8f5,0x0661ec2e,0x1077bc54, + 0xd422523c,0x6d39913a,0x58e7cb3e,0xd105e1e8,0xc979bb45,0x47c9397f, + 0x0997b592,0x3221d4a9,0xe8952fe7,0x0ef628a3,0x4e946241,0xd08d5827, + 0x59780f40,0x64cbed0f,0x08e110ec,0x13d7c227,0x7679b1a3,0xd186d866, + 0x26ae1d18,0x02f75e4e } }, + /* 217 */ + { { 0x47f307d7,0x1b637ebf,0xd0141477,0x6b644a6a,0x2e05a80c,0x82a33d65, + 0xfed07b31,0xc8f1a0f3,0x3696e597,0xc09ee7f9,0xc7ffc01e,0xcdaa7ec3, + 0xf8f373b9,0x549f88fe,0xc3bb8989,0xc88d1961,0xdfcaa7b7,0xd92a4fe9, + 0x3ae4ab20,0x12ff9ee2,0xf5ecb1a5,0xf5aea641,0xe32fb47d,0xe769237f, + 0x25d085c0,0x96a5c420,0x26c755a2,0xdc912558,0x9bce9723,0x580b985f, + 0x63961941,0x72b1b566 }, + { 0x790e5558,0x9d708a08,0x0689af80,0x98536041,0x42313b5f,0xe85e7b8a, + 0x55a49d1a,0xe6ba1292,0xac371b0b,0x5e76c4b0,0x938e6e19,0x58504f39, + 0x60ae9a21,0x8dd41422,0x968485ce,0xd8b04e9b,0x887efe43,0xf94c4ba5, + 0xf11c5e73,0x11268e67,0xcf6b99c4,0x92623e28,0x7a0a9662,0xf2d0aaa8, + 0x4ca02ed3,0xb266772a,0x2d63b551,0x68ee8e4e,0x2e78b5b5,0xcdebb299, + 0xe17225ad,0x5df19216 } }, + /* 218 */ + { { 0x8df2e7e3,0x20027e1e,0xd8da07de,0xb183cc68,0x4b4ae694,0xce35ba69, + 0x3ca62e88,0x896d97df,0x52efed2c,0x3de4713b,0x26bd084f,0xd006c40e, + 0xfc81923b,0x1e9b71bb,0x1aacc6b0,0x9991c7b6,0x8f656840,0x650c9364, + 0x87f47524,0x138561d1,0xbffd3ca2,0x610f2b11,0xfa191418,0x96915faf, + 0x955e5309,0x8f1236de,0xa1872d79,0x613cbeea,0x66a2a48b,0x7f7b44ea, + 0xe0a89c32,0x452265c2 }, + { 0x25430010,0x4ad5ec79,0xebd090c0,0xcac786ff,0x20a9d3f5,0xa5f9f4ff, + 0xa3edc65f,0xfcbf4112,0x0cf3eb11,0x8824839c,0x8aa5b700,0xb8dd6d4e, + 0xb7568ab8,0xe2271dfd,0xb744560e,0xe43ec373,0x1cf75296,0x78eaf926, + 0x3fa96d9b,0x1809ae0e,0xdc25dfd5,0x0b312d2d,0x6bab7711,0x6b8f78b4, + 0xb5ecf1e4,0x069efc8d,0x609fecaa,0xc1952bae,0x5f4dbde1,0x43e302ed, + 0x1e078555,0x14b02bf9 } }, + /* 219 */ + { { 0xb87e5b57,0x2c71c768,0xf531a557,0x0bcc78f7,0xf7597dc8,0x4ff93f8b, + 0x139e175f,0xb28e026d,0xcb94ca6c,0x6b83b727,0x0079f7fc,0x2eafe3b2, + 0xcf3bd170,0x2aca54de,0x6af0dc6c,0x17c4133c,0xccf5e35e,0xbea1e665, + 0x345505c6,0xa6691a48,0xe6100b89,0x2633abd0,0xc17d0388,0x966c6706, + 0x1a0cf90c,0x7aefffbe,0xd0add64c,0x4d847be7,0xaea2aa46,0xd49bcdfb, + 0x2cc7d0a5,0x85e07e74 }, + { 0x0bc25bca,0x23aae0a6,0xe44f64ec,0x6e8e55f1,0xb607b773,0xe1e696d8, + 0xd3005909,0xaa90a746,0x2cbc4990,0x072b1ccd,0xc68e2f5d,0x0d0fe6c6, + 0x53e28ec9,0x920ec5f0,0xf0040cc1,0x79b21fb4,0xfcc4a2c7,0xa7375bd3, + 0xe1bac7dd,0xf5f5def9,0x35c0f8d3,0xdc315d79,0x2cacd318,0x7117c170, + 0xe926f71c,0x6f2823c4,0xed02f39a,0x38db58bb,0x7db69323,0xe5b49231, + 0x8d49f430,0x0964039f } }, + /* 220 */ + { { 0x56999eba,0x21774f16,0xb1de6305,0x3d8ee287,0xde0b2669,0xd81af726, + 0x3f8942a1,0x37446939,0xea03e13c,0xbcf6b615,0x94e273cf,0xd30c0c35, + 0xc6725c56,0x4fd33a56,0xa8be97a2,0xa57534ad,0x7c22a251,0x799242a6, + 0x9d0c5c49,0x4e51bdb5,0xc6a42768,0xd7cd76cc,0xd426bf59,0x914097ac, + 0x66e9beb2,0x59404a2c,0x5c96e3e9,0x4738fe98,0xaad666d0,0xbcbb3e0e, + 0x63bc5e56,0x626b0fd2 }, + { 0xe1a1ec42,0x47217dba,0xab5acc50,0xaa6ae7db,0x865331d1,0xb7e1ab1e, + 0x3d30126f,0xb8453070,0xdee61851,0x280649e0,0xea689544,0x8806f4a3, + 0xcb56f632,0x4bbe43ad,0xbcaff94f,0x036b9bda,0xbd0637be,0x0d941e65, + 0x686f3abb,0x82179d44,0xaad6afd6,0x1486912c,0xff7e1534,0x9a3b891e, + 0xeb86fd96,0x88c426ce,0x117928c3,0xb56e6a81,0x96399e00,0x933e7135, + 0xa17b6ac1,0x09bbddd9 } }, + /* 221 */ + { { 0xe4fd3673,0x75e39c1d,0xa65c8e07,0xf880d9d1,0x7289c7fe,0x4725c1dc, + 0x3529d200,0x5b6735ee,0x3c747af3,0xc1f8f2ed,0x912efdf5,0x5cf3998f, + 0x49859c39,0xed722618,0x0e69795d,0x23793a2f,0x86b1d2a7,0x8a6ab8d6, + 0x22a882e4,0x00c815de,0xf9db8d7e,0xbe77d6fc,0x02267547,0x0886fb32, + 0x49c10edc,0xb62687d4,0x7c83ed4c,0x9f1c3e17,0x5af366ea,0xe6d5d7f0, + 0xd1efad24,0x2eaa01b8 }, + { 0x1f357c74,0x5e47fb70,0xa9e3b794,0x93085c4a,0x6e85a905,0x4f098733, + 0xbe0244c9,0xf53808ff,0xa3b5660d,0x91dddf93,0xf3b95ed6,0x8b76377b, + 0xbb3920d4,0x91b911b7,0x86a13cf3,0x7ccf08bf,0xea018e58,0x53ed8f97, + 0x78c55194,0xb1ea4343,0xe0d2d5a6,0x8e6adde9,0x9b96259a,0xfc2b248f, + 0xeef17ddd,0x96ebceae,0x557f9c85,0xf694b443,0x07d5bba8,0x48cd150f, + 0xb4c1986b,0x02d31de9 } }, + /* 222 */ + { { 0xde79499d,0xa6bb9e1e,0xfd0fc2ad,0xf6ca8ff8,0x1a7d9356,0xbec0f8e8, + 0xe8f06327,0xbc3d1c9f,0x3b300beb,0x805c7217,0x413c181b,0x00420a08, + 0xf0ca9d01,0x9e9a167e,0x1aeeddd6,0x076c909d,0x8e3a8a72,0x64a1997f, + 0xa77b429e,0x3ce7f7a7,0x5c94d3e9,0xaac0fbf4,0xe6d48407,0xf37694a7, + 0xa91921e7,0xf56679e2,0xee1dbbd6,0xf23fe0f3,0xcbf9fa99,0xc7917566, + 0xe0f4d765,0x965860f2 }, + { 0x7fa5f79c,0xe734702b,0x5af2d26d,0x930bd426,0x6c73e0ce,0x45bd8b98, + 0x4ee44a2d,0x7dbe7bed,0x956c8a1a,0xc129e024,0x77cdf80e,0x6fdc05ac, + 0x589ca59b,0x70a6ba2b,0x999825af,0xfc484021,0x7a23f0b6,0x1d284b54, + 0x28a0a8af,0xb1da10a4,0x2b2af6d8,0xb1eb1b31,0x33935ee3,0xf051443a, + 0x8effa6ec,0x7a07eb26,0xd662654c,0x16ee4086,0x4549ee4c,0x7a7bc501, + 0x1fa98a52,0x65081032 } }, + /* 223 */ + { { 0xb67ed9b2,0x49f0e460,0xc36d93d2,0x0cda0fd0,0x88c75e1c,0xbb5963e9, + 0x614bc0c9,0x757bbe93,0x9a768605,0x9a9b8801,0x48edc544,0xa8b7e2af, + 0xb51a5985,0x9e77ed9e,0xebbf024c,0xdd025274,0x1545c636,0x598b6288, + 0x4800dba0,0x39bdaed0,0x81e2a23a,0x7fc20139,0x550cb4f2,0xdc66fd5c, + 0xb52068c7,0xad27032f,0x8169fa15,0xc9a0bcae,0x3a7ca8a2,0x60606f21, + 0x9862652f,0x98295046 }, + { 0x2e11c128,0x3e374600,0x0e6dca7e,0x80dfae5d,0xd9552264,0xe44016e2, + 0x880b7143,0xf65f88f2,0x526b881c,0xca3d28d4,0xdfb86afe,0xf9c59dd1, + 0x4c74f958,0x548860c2,0x9cb69f4f,0xd06ea43c,0x7334ecec,0x5343c9ae, + 0x35329713,0x5cc2ccd6,0x5f3a6c0c,0xa95ff403,0xb372653b,0x2e01a1cc, + 0xa250523d,0x31510fdf,0xa6227eb2,0xeee538e2,0xca23cd10,0xeadfc8a0, + 0x3e78f54b,0x4b7e6e1b } }, + /* 224 */ + { { 0xdb5f928b,0x79c9076f,0xb7347cec,0xe6250bb6,0xac00ec41,0x54b67798, + 0x9d9619c7,0x900d20ba,0x59e4343f,0xed42c0d0,0x451935d7,0x3df39e85, + 0x64f701ce,0x26391182,0xe1f87aac,0xce8f2554,0x65f91aaa,0xfddd6789, + 0xa324539f,0x96cd163f,0x4bace995,0x5c815f2c,0xa94f9ea5,0xd78c8c2a, + 0xef24e455,0x7ab2aff4,0x1cddc26a,0xf0ed6409,0x00ca2822,0x954a420b, + 0xd3297658,0x0611c4c5 }, + { 0xa9e81829,0xf192001c,0x08a282cc,0xded33320,0x8f9ded9b,0x0bfd7de1, + 0xb7889003,0x6793ac0d,0x3577a5dd,0xbb00d91d,0x802d3c2b,0xe17a23a7, + 0xfb549014,0xff95f88c,0xc71b6e07,0x7cd1bf4b,0x23588c8b,0x2e3b24a0, + 0xa4112076,0x9b5335b8,0xc4056d30,0x2481c05e,0xe916a1b5,0x55c7410c, + 0x850179f4,0xbbe03271,0xb3cd1208,0x15e6c177,0x90cbfe50,0x509a24c0, + 0x1c108566,0x82079529 } }, + /* 225 */ + { { 0x1c7d353e,0x5d2d3cff,0x7de0ce3b,0xd5e7eccd,0x6ca87635,0xb4b1075f, + 0x25f9ad3e,0xda8404e0,0x205cb5ae,0x6b963e89,0x09f221a1,0x9e5ee0d8, + 0xea41aca4,0xd64c85d9,0x34442a34,0x6a46c4e9,0x3cf655a4,0xac6ff97e, + 0xe5417d7c,0x76565c1e,0xeebf9c4c,0x681009a9,0x88da6388,0x95b61d39, + 0xf6b472c6,0x6402b46a,0x0b7f1171,0x1fde5165,0xbe0c05e3,0x94f8f273, + 0xa88344a7,0x7487b036 }, + { 0x9c3e2370,0xa860e575,0xf8048719,0x19d58193,0xa6e2f9aa,0x3a0dbf3c, + 0x6144719b,0xb6c7e959,0xdeffec21,0xa9049c74,0x3f50cebf,0x8ba064b2, + 0x49a1de15,0xb12822c0,0xb1d527f2,0xb654b7d9,0x0ffd0430,0xc470859d, + 0x4f05446b,0x37c74a67,0xa3add995,0xe553251b,0xe33533b5,0x4a3ed6cb, + 0x27e419ce,0x2f2f44d0,0xa5d1b979,0x2d84ee82,0xdb6fa69f,0xcc76b123, + 0x21fa3bdd,0x834f85c5 } }, + /* 226 */ + { { 0x2ce9b31a,0x329347c1,0xfe3fb3b7,0x1d88522a,0x52ff90fd,0x4bcefb4d, + 0x2b1a081d,0x53b17386,0x2a411f08,0x538c11ba,0x141b603a,0x7895b93c, + 0xb10bd741,0x2993b9aa,0x09912986,0xccbbd046,0xeea0aba5,0x669fafb0, + 0x35661897,0xd4844622,0x367ffa54,0x4a63b89c,0x1c3478da,0xcbad5d1d, + 0xaa6034f7,0xc5339227,0xe61b1391,0x0e6d705f,0xf74ff515,0xdd14b660, + 0x5332b54c,0x639d8b0a }, + { 0x162217cd,0xfa423162,0x811c28e6,0x2e0e4a2a,0x21766dc0,0x68d9ce18, + 0x046a06ef,0x51263739,0xdde92101,0x44eea231,0x114298d3,0x0607c8f2, + 0x63d957e9,0x27f272ba,0xa5e8cae1,0xe7ce80cc,0x24f7a63f,0x5816ebe2, + 0x89673e34,0x4dece5a7,0x536babd4,0x13756a22,0xe3bf77af,0x644d61ae, + 0x2bcf98bc,0x60b2bf6e,0x29fa962c,0x3b0b59f3,0xabb50023,0xb0769a1a, + 0x0c75402c,0x40903136 } }, + /* 227 */ + { { 0x1670433f,0x84d2873a,0x25493dfc,0xc9394df6,0x80fcf89e,0xeb05a19a, + 0xdb297616,0xe39e4310,0xd9e63046,0x50742dc9,0x1de9ca9e,0xf31ad8c8, + 0xfb7b1d0d,0x86aabf94,0x1b3c82d1,0x36cda27a,0x39702d84,0xfb1a2ef4, + 0x46081299,0x280bfddc,0xd2396238,0xe4b2b48d,0x7b3c9353,0x2db2c2f3, + 0x12fb8a69,0xd5b5b317,0x08180474,0xf9b87a3b,0x1e952578,0xd8590986, + 0xf37a2bc8,0x80668eed }, + { 0xb39a0249,0xe2edcd35,0xb2f8aeae,0xaf230cd4,0x7223df05,0x295b15e4, + 0xe0e937f4,0xbb66982a,0x8cbc9162,0x019d2b72,0xcf49dca1,0x5c512ae9, + 0x630f07b4,0x11b491a7,0xa03874e9,0x48d4f34c,0x44cb7433,0xc1fd0ea6, + 0xf95b30c3,0x13f79ae1,0xed8b60ac,0x40362d4d,0x61ead81c,0x9e8314ff, + 0x498c3d28,0xed600dd4,0xc2521702,0x5fcb1c19,0x3a9c1f33,0x592329fc, + 0x1bde6ce9,0x04677548 } }, + /* 228 */ + { { 0x39233c96,0xee3de56e,0x80737eaf,0x868c409c,0x201abc68,0xacae11bd, + 0x2b486205,0x0f2cea9b,0x6f19056c,0xe32387e1,0xa5dc2a41,0xea75365a, + 0x12b4be86,0x76c29acc,0x8d63294d,0xa01fcab7,0x0cab9f24,0x81dbe88b, + 0xf414c054,0x76646e5b,0xcb96b7aa,0xfe111893,0x7664e097,0xb649f5b1, + 0x53fcf5a9,0xa196422e,0x0b7ff634,0x5978c9bd,0x3c229895,0xb5feb38e, + 0x0833c456,0x038a49fb }, + { 0x13e93257,0x35e3818c,0xa612741b,0x14cebc9d,0x7caac06b,0x4f6e9249, + 0x3daa1116,0x82278e33,0x4de2034a,0xe7cc565e,0x0a1ba630,0xbb7dc95f, + 0x66956fbd,0x81dd9f23,0xbb132dd6,0xc63e6319,0xfc241337,0x6e22b022, + 0x7e8beb1c,0x23848193,0xd8c938ac,0x83b1994d,0xa6bb5644,0xb54cfaca, + 0x06f91807,0x1a7cd44e,0xa8f8d9f3,0x1dd439bb,0x7f74a8e6,0x660c2a78, + 0x121b5660,0x4bb76e22 } }, + /* 229 */ + { { 0xe6354817,0x7a151e8a,0xf038b438,0x33d494ea,0x85958986,0x4c86c688, + 0x1dcbac12,0x72153827,0xc0edad06,0xf487af8c,0xe500e5d6,0xad33051f, + 0xd6e47f55,0x0a711b1b,0x8c746ad5,0xa68709a7,0x6402f35e,0x27f17262, + 0xfb30c130,0xc6d08efa,0xc06c7497,0x9ef1c041,0xdcc3e2da,0xd0c74ece, + 0x092e1073,0x30c5f96e,0x2aa12b74,0x0f1393cf,0x2107eb02,0x24584016, + 0x7b76f98b,0x8843d25f }, + { 0xedb2a83e,0x4e1501dc,0x2bb8d724,0xbcfe8fb0,0xd925df62,0x09020659, + 0x42ab6fc3,0x3c715dcf,0xa0f09dfd,0x73c05055,0xe3590aea,0x126745d8, + 0x76ff749e,0x5382f4d8,0xa920c663,0xfc69feef,0x9fd711ca,0xde160211, + 0x9075c4d5,0x4219c3bd,0x3ded6bf2,0x3800cbd1,0x6263a116,0x8c7ea0eb, + 0x7d264c37,0x35bd7958,0x7159c98c,0x56e22e45,0xfa7373b5,0x71bf2a2d, + 0x8935c949,0x0503f939 } }, + /* 230 */ + { { 0x71dad4f6,0x65addc66,0x024bea1b,0x238e4889,0xf605d3dd,0xfb76c8e2, + 0xb0d96b89,0x13d5f5de,0x6601b2cb,0xe0b5ba35,0x83e3d254,0xe37d491d, + 0x240c8ea7,0xe8860423,0xe91c99ba,0x374182f3,0xa87ad919,0x26c2caf9, + 0xf574f295,0x4b13040a,0x944000a3,0x5b9bced1,0x06df42e7,0x4ccc57be, + 0x4bd1089d,0x22e8ec50,0xdddbb500,0x0c53177a,0x9ecfeadb,0x690d31d2, + 0x176668f9,0x735778fe }, + { 0x843c1137,0x0f86ee3e,0x3f0b73cd,0x3c1c42fa,0x8ab20e3a,0x0e75679d, + 0x16242fae,0x6f95f1f4,0x39b092e4,0x7b88e11c,0x4c236ac0,0x1629403e, + 0x2dac02e6,0x66105f41,0x862e0632,0x74dc28a7,0xf3b23c8d,0x2118ffb2, + 0x0745ffbf,0x1182417c,0x4c05711e,0x49b55a04,0xcefbe4de,0x2c665b74, + 0x97bf7107,0x1cc4c01d,0xc54f0676,0xb2ca06da,0x7450d0f8,0xfc599daa, + 0x1a3182a1,0x52e637a6 } }, + /* 231 */ + { { 0x6bebc6db,0x481700f1,0xf9503d92,0x4a6b45db,0x5d153919,0xc715cd3c, + 0xe5ad2abc,0x942a1c05,0xab7b466f,0x36a82433,0xba13918b,0xba413bed, + 0x90f4e6ce,0x698a5624,0xf3f1f3ca,0xbb720da6,0x63471ab3,0x2116d41d, + 0x303d3609,0xe00d2227,0x463ba69e,0x7fd4cc00,0x62845fd1,0xac609e4d, + 0x80adc9c7,0x63603b2c,0x45fafbca,0xbf16fc9a,0xc4bc94ab,0x41007f7f, + 0xa74b1698,0x7c916b4f }, + { 0x78bac2d4,0xc1026f91,0x2601a875,0x8a2e8098,0x0073d640,0xad2f276e, + 0xfcc1fb88,0x443610c4,0xca6b291f,0x5727b822,0x88ec60fc,0x0645532c, + 0xed9ad48b,0x51e48899,0xf543f103,0x841b48b5,0xd591ceeb,0xa6ccb1be, + 0x9dcf5a8b,0xfc4adf0f,0xb347ddb4,0x3a7ca020,0xcb44c521,0xaa1accc2, + 0x0527c0c4,0x773b6828,0x7023cf50,0xaa374c10,0x6b74c926,0x733d1000, + 0x77a8d07c,0x1ff3916f } }, + /* 232 */ + { { 0xf997939d,0xaa218fe4,0x791583b3,0x3d4dfbbb,0x87f7560b,0xb3a7b5da, + 0x5da92c98,0xa9c02801,0x46666f4a,0xe1eb4aad,0x14ce9dd7,0x2eb17a51, + 0xef8f3076,0xf46a66a4,0x810e546e,0x900b45c6,0x4baf04dd,0xf7af2258, + 0x5c84d42f,0x3cc1c872,0x8e4c83de,0x3093f225,0x170d88b2,0x62fade41, + 0xac076e44,0xe19612e4,0x32dd141b,0xf48d7346,0x925e34da,0xc1b1f759, + 0x072b90c9,0x19ed1a56 }, + { 0x6c735473,0x9cf7fcde,0x6003bc3e,0xaab88e67,0xfb199bb8,0x12187cbc, + 0x9accccbd,0xbb730441,0xb0f65459,0x214aff3c,0x6f926282,0x6aec81a3, + 0x9f9d20b8,0xaa82cb32,0x5773cc90,0x82f3f90f,0xf62257e1,0x4af60e6b, + 0xbd4762df,0xf18b44bf,0xdb970753,0x3948b129,0x7c22c18e,0xc6e920e9, + 0x57be97ad,0x393d6208,0x46b637f9,0xe8d7382c,0xf1fed1d5,0xf6625ccb, + 0x68681599,0x6f31e0f9 } }, + /* 233 */ + { { 0x82b8f204,0xc45afe55,0xd358b54a,0xac0441b6,0xacd5f5ed,0x7213e7bf, + 0x139bcd93,0x1914c70b,0x96dbcbb0,0x714b4581,0x1ed35d21,0xe9297d35, + 0x6a3e1f20,0x8f640837,0x2f3cd705,0x150a8a9d,0xdcdd9f6d,0xfb36e801, + 0x5cf56d82,0x5a54eb65,0x92aa5a21,0x7610500c,0x3b089f03,0xd10d0ae2, + 0xc42b66e8,0x491b2079,0x0eee8d48,0x4af1ae3d,0x41556f45,0x137e4c28, + 0x63d8a7e6,0x875e3308 }, + { 0xaf6c0acc,0xdc80fddc,0xbb1e7c08,0xd5ad1e66,0x828585ad,0xdc717ae1, + 0x275c7da6,0xbdc54340,0xd26b9e15,0xf4b4c852,0x6a05fa50,0x5f0a1fbf, + 0x817bcb32,0xc6f81e47,0x70ff2e1d,0x2cbd4328,0x67c7f7fc,0x8a249016, + 0xb585a6c4,0xd045acb7,0x4666c057,0x2e972ad4,0xe6d7d63d,0xc74d87cf, + 0x0e274144,0xf7067d87,0x8b2584ae,0xb2ca157a,0x75f0fdeb,0x495c5bfb, + 0xf386e009,0x5abb0581 } }, + /* 234 */ + { { 0xf0c97f57,0x8be62d2b,0x962f28c7,0x0fe04871,0x47b50abb,0xc548a467, + 0x44fa09ed,0xf6b26e03,0xab05a96e,0xfd44c6e3,0x70e6ae82,0xedb0032c, + 0xd7e4899d,0x28bd402b,0x9b7c11c2,0x43f2e963,0xce913716,0x0ec3fc0e, + 0x02fd0f8c,0x769b8bc9,0x7cabc3ac,0x9d9cb3aa,0x06924cc9,0xe88a8892, + 0x42609014,0xa51461aa,0x962e79e0,0xc7f4aa8b,0x8b1b3e80,0x4ef0210a, + 0x1bfee4bc,0x70544680 }, + { 0x121901c1,0xfab3d713,0xfead54aa,0xe90a2627,0xbc08ba23,0x64f6d285, + 0x36ec227e,0x8d993015,0x06c191ab,0x99a16ab9,0xf649ce2c,0x86b1cf5b, + 0x66be3a80,0x59206759,0xccba2cf0,0x18836279,0xeff53486,0x2c157b87, + 0x4b223af2,0xbfac9896,0x0aae7a57,0xcd0fd4f0,0x63218a80,0xdaddb940, + 0xdf88f14e,0x3844bb79,0xb71ed9fd,0xc1b3e3d4,0xd6205036,0x6c634a13, + 0xb8680a6b,0x6f56aecf } }, + /* 235 */ + { { 0xd9205c5d,0xb01dc803,0x67123929,0x68955f7d,0x9d9b6565,0x3debbffd, + 0xd3b1acfe,0xb844395e,0x6094eeff,0x04328b21,0x22991feb,0x6631ffa8, + 0x190dd075,0x0dde66e6,0xe8577c05,0x75b03c55,0x91722407,0x6c91ce5f, + 0x8ebb3a3f,0x9a288a40,0x058a1396,0x1d376f8a,0x9a6e0676,0xf3a59457, + 0x7b71d288,0x103029c5,0xb44c30c0,0x0843f428,0x730e0b9c,0xd8e6aff8, + 0x4ed644ad,0x7b6be811 }, + { 0x3d3aa54e,0x3ec38e4a,0xd83d509a,0x10233943,0x243955e2,0xf84aa621, + 0xf51d3d44,0x29104717,0x7eca4e37,0x62d2442c,0x85fa55de,0x8c5a523d, + 0x851da1b5,0xc6f5ccda,0x20001468,0x044bcaa8,0xe01702e0,0xf7501e68, + 0xe6a0acec,0xf0819359,0xac0ef0b2,0x33dda6ad,0xfd964f01,0x97aeedc8, + 0x530b90d8,0x48dacd0e,0xb84122eb,0x4c5fad6f,0xd700a1de,0x2284ec1e, + 0xdbca5474,0x86f9a835 } }, + /* 236 */ + { { 0x450cc69f,0x0e1d9055,0xc9edf98f,0x50eb14bc,0xee7eba01,0x1bb94e77, + 0x998f8e53,0x5f7a6737,0x1b16eef0,0x588384e3,0xd85c5e15,0xbb928723, + 0xcbd952aa,0xfe51e345,0x7e241674,0xc5d0ee28,0x100182f0,0xfdc146ef, + 0xe7f5be2c,0x0f739e92,0xb656bd3e,0x501ab3af,0x5168e289,0xb1552dde, + 0xb8ee104a,0x940dfe31,0xc4304475,0x42923603,0xc460a913,0x9306f114, + 0x03b51f86,0x5bfa9faf }, + { 0x107b258e,0x2a23f52c,0xd66341dc,0x989e82bb,0x823cff1a,0x54a3ced8, + 0x719b491f,0xf45b7794,0x2433dfb8,0x898c2218,0xc49250ee,0x0f9dd91c, + 0x4fa17655,0x50c2a2ae,0x2c327f45,0xf7aa1ce4,0x583b1e41,0x13a15ad6, + 0xa1bfad9e,0x9aa0d5a5,0x8e1fbdcd,0x9b1caa28,0x915f7f87,0xaf9283b6, + 0x87e81a1e,0xc10e4e0c,0x1080d296,0x04fdca56,0x12755bd8,0x6acc9616, + 0x828feeda,0x1b1266aa } }, + /* 237 */ + { { 0x774ee49c,0x4ebc0a00,0xcb6237d7,0x776f6852,0x5df938a3,0xfc0544ac, + 0xb6fbfbbd,0xc3388ec8,0x745f2eae,0x84ac8bcd,0xb1ece937,0xa9c56609, + 0x7de8fa13,0x656fb6ac,0xa532b871,0x5f8ded74,0xaa889f09,0xab0d428b, + 0x10b7aec2,0x43b27f28,0xfeecb34c,0x26426e1e,0x9e89c2db,0x44431b6b, + 0x39211090,0xaac4bc5d,0x4fd81058,0x926f7368,0x471ef60e,0x452fa691, + 0x218d7a23,0x33517fdb }, + { 0x593c4a36,0xa9c33f46,0x36b1a9ee,0xac69d718,0x4277beec,0x55a20c1d, + 0x7e4f179c,0x3e8ca24e,0xd46d88a2,0x57373369,0x730702f8,0x71ceb1cc, + 0x35eed574,0x8b184d97,0x0704cec2,0x7f4517a2,0xd7062a53,0x7f129d18, + 0xb1d77e1c,0x07a4571b,0x8350d8b2,0x774ac309,0x61fab8ef,0x27b2919f, + 0xb5dd801b,0xa7c4cc13,0x1434591f,0xe7e6255b,0x5a3592b3,0x349937b8, + 0x30c77549,0x31fac63d } }, + /* 238 */ + { { 0x04913fb6,0x2ee8cf1b,0x1769a6b3,0x7e401350,0x783e61f0,0x790ebb71, + 0xe27f2ffe,0x1e5107f9,0xedaf89bf,0x124ba67f,0xe58de68d,0x189200e1, + 0x6df5abee,0x962732a3,0xacbeb4aa,0x72cc37cf,0xe93c5a76,0xb0c5fa96, + 0xde63393b,0x4c2a317c,0x830b2d6c,0x97f65e67,0x1be5b96a,0x4afc3504, + 0x730ce66d,0x0bf40a60,0x9340d84f,0x96a1ba79,0x07626b08,0x3ee18254, + 0x7ab0cbf5,0x01db35db }, + { 0xac0efee2,0x6e0fbc2d,0xd71dbb45,0x8406ebcd,0x19b69abe,0xe72bde3e, + 0x37e01822,0x49cb7e61,0x11458b4c,0xcbb8c01c,0x687c5d63,0x420b4847, + 0x454c6776,0x1847dfa1,0xd1839d18,0xbede911d,0x278df046,0x1b9dc9c9, + 0x881a336c,0x294bd62b,0x93e77adc,0x7f096879,0x43ce3ba7,0x7ac90665, + 0x7764eefc,0x148695fd,0x9ac465cf,0xe0c20f0b,0xa6e2cdb1,0x636e8d28, + 0xd755341d,0x7b6ba98c } }, + /* 239 */ + { { 0xc1881ab4,0xcb1d9e03,0xb3168c88,0x19c25d55,0x282364ce,0xa82d3d47, + 0xf161aa24,0x95994390,0xe1ebb2c9,0x7838bc00,0xbdec7a75,0x8fd5dfcc, + 0x4ff7220a,0x4dd203c2,0x0efeff48,0x5ec173b3,0x16428b35,0x99f1d2b3, + 0x056e813f,0xc06bd9e5,0xc0b319f1,0x929172ba,0xfd223b15,0x6ae0e384, + 0x98d091ed,0xbd01059e,0xa654648e,0x6b3168e4,0x3375e798,0x2211447f, + 0x71eb4508,0x47e81019 }, + { 0xbc8c290d,0x7045d45a,0x810fb33a,0xa33d1355,0x46fbbf2f,0x2baf0092, + 0x385c7cd9,0xacff3f1b,0xe161985c,0xc5b150ec,0x2a888748,0xc6ee0a7f, + 0x5e88dcc8,0x9d888c8e,0xccb86443,0x4dd735f2,0x3c40f6f2,0xcc1e13b7, + 0xf3fed691,0xfc3a25ff,0x257ee5c7,0x4cb43b17,0xf32db135,0xaa654f93, + 0x02dff2d3,0x44f58d0a,0xa8ca6394,0x78e3f188,0xf3e86697,0x39646cce, + 0xe0dce87b,0x785b1902 } }, + /* 240 */ + { { 0xa92f9a20,0xfcce2361,0x9d64540e,0xb7bdca87,0x1d00d7c5,0xd4739a85, + 0x2e97c926,0x067ac8dc,0x78da6a8b,0x2aea3ffe,0x63c51b69,0x6828bf54, + 0x7155141a,0x76f1c479,0x3977d810,0xf4bcbef6,0x541bce7a,0x75bc4949, + 0xd17041a5,0xe01f4066,0x87755eaf,0xd282d5bd,0x59e7ae80,0x6e2107dd, + 0x382ab36f,0xaa56e166,0xb9d1d634,0x65ee8ef6,0xce4ed844,0x99a2160a, + 0xb7712c27,0x6557c367 }, + { 0xd75b6e52,0x561b0268,0x118d0e89,0xb0813640,0x6a2eb1ae,0xcff53330, + 0x6d090894,0x4e462226,0xb5fc1d48,0xbb351227,0x57a3062d,0x9365ea07, + 0xd66e2dc5,0x4caca37b,0xb9095887,0x220d7d23,0x8c4473bf,0x9c0fd393, + 0x6787da4f,0xadff370a,0xd057f4b8,0xef0aebcc,0x1173f33a,0x205e744c, + 0x925a26b4,0xb8d1f0a5,0x722fbbfd,0xa9364f49,0x8227d284,0xc891ae77, + 0xa0e08ab4,0x15c40d04 } }, + /* 241 */ + { { 0x2a0e18d1,0x9baf169a,0x4c0327c2,0x9971c017,0x7bc262ce,0xd81a323f, + 0x818ff379,0x2099db8d,0x4cd3c330,0x663f663d,0x011a0553,0xef5325c3, + 0xf980a470,0x9cd70bdc,0x1c9ed070,0xe64452d1,0xac676e13,0xafbf43f4, + 0xae85c2a5,0x97bec0a6,0x470490c4,0x2faae550,0x491e6ba9,0x0ab97a87, + 0xaafa9914,0x4055f537,0x36726557,0xfc95adbb,0xd119d6bf,0x646343b9, + 0x9d341e37,0x788e94a0 }, + { 0x9c53461a,0x053a6fe5,0x08e3b6ed,0x75ec897e,0x0768d939,0xa8f5d2f3, + 0xcc213d4f,0x9bd6bff6,0x05b0147c,0x590c7b41,0x7c7b8169,0x20a3628b, + 0x5bce78e9,0xc66a086e,0x4dec1d8f,0x3dd4d282,0xc19dcce9,0x890acf44, + 0xd8435a7e,0x6632d875,0xea6381b2,0x590167c1,0xf0dcc128,0xb2259797, + 0x46f8d463,0x91a612b4,0xc15efa39,0x42185d78,0x119f6788,0xdf55ec37, + 0x780dea93,0x91b19cc6 } }, + /* 242 */ + { { 0xcb5d8b80,0xebf2709d,0xfc35660e,0x03b96182,0x055ef969,0xb873d991, + 0xe47c4342,0xd1ea4b4d,0xd54f8867,0xcc4b9244,0xfd8d77ef,0x93b1a2ca, + 0xe8c1f563,0x068d24e7,0x49973056,0x5f5fabb6,0x0542374f,0x83248c50, + 0x3f38e913,0xc36de2b5,0x7bb680be,0xed07e8eb,0xd8f313b5,0x964813d7, + 0xafd2d392,0x7bb6a069,0x0848a31a,0xc06d848e,0xe4f0c325,0x6867fb2f, + 0x067343af,0x3c2ba834 }, + { 0x9d3ad63b,0xab62d775,0x59e0eb1f,0x3f9cab97,0x3885e117,0x70332a63, + 0xe20b2f9e,0xf22cafce,0x49eca947,0xb529ba7e,0x6228d88d,0x24954216, + 0x39239561,0x80ea23ec,0xd4370644,0x1b8907e7,0x563e4e44,0x4b7fa455, + 0xb2a4b0fa,0xcca9829e,0x48060792,0xd0a720a4,0x246991ce,0x8ccdda0c, + 0x348d086b,0x37a2325b,0xf60aee13,0x566ed509,0x147f253f,0x3d30e091, + 0xc1073bd8,0x1fa627a5 } }, + /* 243 */ + { { 0x42478fd4,0xa11222a2,0x670b2000,0xacf4c6f1,0x8359c6de,0xf71bb04f, + 0x7b93cdbc,0x618e2829,0x230db60b,0x96e1bae3,0x965b3b29,0xf17fd3b4, + 0xbc7055dd,0xa58639c6,0x4b817d7f,0xc3ea92ed,0xd23b08a4,0x9082b2a6, + 0xdc17010e,0x8471228a,0x20e89d97,0x753b9e46,0x03ff77c9,0xcf7e4f97, + 0x2bbe60e5,0x6c3f8245,0xb80e017d,0x9e432cbc,0xc0a45edb,0x150a5acd, + 0x4798743e,0x67b8bd05 }, + { 0xf4797cf7,0xe66079b4,0xd03fde02,0xe31c998a,0x54caaef1,0x5aa3763a, + 0xf7649711,0x64d9a1fe,0xaf29b1a7,0x7ce0dc73,0xfb66ca93,0x6661b083, + 0x32fb6a78,0xbf4d74fe,0xdf00a561,0x25f6ef09,0x831d1159,0x2bc4383f, + 0x536bde37,0x6d5cc10c,0x882cc65b,0xd4945f9f,0x451a99b8,0x81f48f13, + 0x6bac11a4,0x140161cd,0xf18a4a0a,0x9d94d4ed,0xa467a824,0x65363165, + 0xa4c9aedf,0x74297aa9 } }, + /* 244 */ + { { 0xe21124ba,0xc49758a4,0xa87ffbd2,0x99bd8198,0x3d6638a8,0x45fbcdd1, + 0x15f7bf76,0x94645ff8,0xc4e6d57e,0x5fa6736f,0x92e61db9,0x1eae6475, + 0xcbdf944a,0x79575c0c,0x25b31d74,0xa3d13047,0x4cab5ae6,0x7881df22, + 0x1a2887f2,0x8dbfd299,0xa26ac459,0x23d07590,0xd8661d4a,0x2e589852, + 0x8a0140f7,0x37b5c13b,0x3fb3782a,0x0f94199e,0x1bc14e90,0x722aa059, + 0xd55bbb12,0x89aab7ba }, + { 0xd656bdc7,0x8b345a96,0xe176cd3b,0x43bdc8af,0x32d64c43,0xd69518b6, + 0x79b82b41,0xfcf364a7,0xffb0cf82,0x907b344e,0x5101287b,0xf3d0c83c, + 0x34cd90ef,0xe9f26a59,0x07082b5c,0xe5f5aaf2,0xece7c165,0x4eb72c75, + 0xbe986cd6,0xe9590a81,0xff1536aa,0xfeef498f,0xa8263d5e,0x04560243, + 0x54ae872b,0x940be14f,0xe3207686,0xbee7bcc9,0xc1bc4d7a,0xd496a27d, + 0x5940ab46,0x002dc297 } }, + /* 245 */ + { { 0xb69d60c3,0xee533937,0xfe972755,0x260be552,0xc0c725a6,0xb11fb78d, + 0xcab2e7c2,0x6982c27e,0xee2322cb,0x4bceedd9,0x122704f7,0x952b19ed, + 0x854a6165,0x2df4c285,0x7b192485,0xba40b5bf,0x0119f52a,0xfcbca950, + 0xe5add86f,0x7467d1cb,0xd9d0f2c1,0x9bf536fb,0xb8d4ebc9,0x3c296e34, + 0x05a81317,0x0495f8f4,0x73335f76,0x8c59e8d6,0xe0542122,0x0b53d324, + 0x3c3bda73,0x4d564535 }, + { 0x7e5c0877,0x7322f800,0x0ca9a764,0x481b43e6,0xa2c12716,0x231f4f4b, + 0xed3136c2,0x09596857,0x38db30de,0xae826322,0x99908ebc,0x652fad40, + 0xaf0d231e,0x0b8d1814,0x09cbc349,0x2680c54b,0x4bf3bf8e,0xfd4562f3, + 0x092b595f,0x2985090b,0x5e15fc34,0xe6f39ca4,0xbc378168,0x70175191, + 0x845a4a87,0x906944b3,0x82a1541a,0xacc6d74a,0xb155c8b4,0xadc9bab3, + 0x77306c62,0x1f2f89ce } }, + /* 246 */ + { { 0x9affefdf,0x8253ef41,0x4cf9256b,0x05d7ece5,0xb444e483,0x377002f2, + 0xcba5471f,0xb189755f,0xd5cbe015,0xc88483cb,0x6a0b8429,0x254f7c69, + 0x61f3f61d,0x18850bd4,0x0a247157,0x7ba21089,0xd92eeb0d,0x35abbc2e, + 0x965dec89,0xfb56cabe,0xbc55684a,0x9da23724,0x6a7a7492,0xd8ba396f, + 0x2ef4ba46,0xfcb90db7,0x9909b27a,0xdd234fe0,0x76f4366e,0xbdf3c164, + 0x17e50d47,0x09c8097f }, + { 0x60050c07,0x6a04b140,0x43a8e37e,0xc29e8318,0xbb55e41f,0xcb9429b2, + 0x2ce60e3a,0xed2fea5a,0xdb9d82f4,0xdc7b1ff3,0x687d37fa,0x48ebecc3, + 0xecb07539,0x79153e32,0x57075692,0x6a60054f,0x800759ba,0x3871cd0c, + 0x30922df1,0x17a7386f,0x83357b7c,0x4e9fc59e,0x39415186,0x1d26b3a9, + 0xd34db889,0x912a0222,0x59fcdb71,0x6672fcf4,0x44ff3036,0x5a3f268d, + 0x6911e16c,0x6f113ed3 } }, + /* 247 */ + { { 0x1836f1c9,0x52a9df59,0x4232307d,0xfa6519f5,0x5ded285a,0x8406c701, + 0xaf627f75,0x0a1545ca,0xace0417d,0xae1111ee,0xa6113443,0xfb28bdf6, + 0x52dbcbcb,0xde9ef0ab,0x7813e658,0xe9dc181b,0x99127225,0x0b1dabdb, + 0x22814c59,0x5f0598e3,0xd934ee7e,0x5c3b966e,0xb99ba4bf,0x4eb84eda, + 0x3c1b55e7,0xb2919a34,0x94aa860f,0xa9addb49,0xf6811ff6,0x1b7220df, + 0xd1a183e2,0x6636a23b }, + { 0x20587283,0xdf5d5a2d,0xef07fc5d,0x0b3822c9,0x0ef6de38,0x1786bd55, + 0x25d1671d,0x163cf907,0x1cdb1def,0x74bf971f,0x0842fc4a,0x5749e830, + 0x27f854f7,0x0e2edbc7,0xbce24acb,0xbb27bbda,0x05bed08d,0xc1b19cec, + 0xf7c904bc,0xaada123e,0xd89982db,0x02429f1b,0x65f6e632,0x49d3616e, + 0xee59fd32,0xa3789fa8,0xfe9f29f5,0x160ba3ba,0xaf5378a0,0x0f2d3b61, + 0x73c2a6f8,0x7aeecc76 } }, + /* 248 */ + { { 0xdc43b0db,0xf3a4757c,0x98119cad,0x3d8a4e85,0x4616c156,0xf8095bf6, + 0x4f533e97,0x3e2a07bc,0x39cfc5ad,0xa9824367,0xcd68052c,0x18a6ba3a, + 0x8a1cec66,0xbd60e590,0x02b1b695,0xae3841a5,0x190a195b,0x986dff12, + 0xad31fd9b,0x2df2beac,0xcc728f7b,0x7d893224,0x0cf0a992,0xc38ea738, + 0x586a44ea,0xa8439a80,0x1615f03c,0xede7f7f0,0x27a1f885,0x48249908, + 0xb78a7645,0x28ec4006 }, + { 0xa2fe0009,0xe1820c2e,0xf13874e9,0xe11ba5d2,0xc524db52,0x97522454, + 0x7fede529,0x4d477426,0x9b2500d4,0x01d3419a,0x1869244b,0xce08a492, + 0xdd1be1b9,0xba169023,0x32a301e0,0x242c3e54,0x70906788,0x9b56f7ba, + 0xc74a8cc4,0xf0ad2a09,0xd76f9439,0x99cd1841,0x621fb60e,0xeddafe0b, + 0xbc397634,0x056bee54,0xff7f0a84,0x4653f860,0x2011c0af,0x6bd4876f, + 0x0c9525c3,0x134f4cc7 } }, + /* 249 */ + { { 0xe938dff4,0x9621a3ec,0x486a79a3,0x7d101a7b,0xde950537,0xf2c4ef97, + 0xe65d87db,0xf3184099,0x373b8cfa,0xb89c7ffb,0xe842916e,0x68baa505, + 0x4ebea764,0xa790fd09,0xe592892b,0x679df6d4,0xfcfed741,0x2023331c, + 0x9880ff21,0x0bf4efd2,0xd0344501,0x7ca78ddd,0x342858c8,0x2cb09ecb, + 0x2575487a,0x9e5eb6dc,0xebcb0491,0x50675a15,0x7381d471,0x09d2e74f, + 0x83d3d6f4,0x6ea37829 }, + { 0x4e5cc40a,0xc65c094b,0x1af37dfb,0x7a2e3f6a,0xf9026e44,0xef677e9d, + 0x93880f53,0xb7878c95,0x7f644aa9,0x4aa30b07,0x2f208c3c,0xa0c51683, + 0x658d663b,0x7c0277ae,0xae1d9130,0xef0b3c38,0x695c3ea4,0x302f37a7, + 0x6a0c5e0d,0xe004c1c5,0x20cbcf9f,0x9fd495c4,0x568a0e7c,0x706d5b9d, + 0x59286454,0x8b225dff,0x8d9a709c,0x527d4465,0x87c08d68,0x47c558da, + 0xbb4ef07d,0x606ee6e6 } }, + /* 250 */ + { { 0x57c621f6,0x02d99fc7,0x7fe83d48,0x292e40c1,0x9ef199b0,0x1bdfc7a1, + 0xe62c7666,0x78a04102,0xe6738753,0x16cda370,0x1e3a65af,0xbc81974d, + 0xf78fe209,0x19742048,0xbf5981c6,0xc83a058a,0x9c89702d,0xf26b2434, + 0x9d1a678a,0x988b2f1e,0xff29ae29,0x472bf9b0,0x1d7cf5ec,0xa143e398, + 0xb268ddd8,0x9c9d7e45,0x5fc4ff76,0x166cda55,0xa4aa7673,0x6044cdf0, + 0xe9148707,0x49dba6f7 }, + { 0xa758e37a,0x20e47fb2,0x2d8eaf66,0xaf6b31d7,0x6f9c2210,0x352ad5f9, + 0x90efc32b,0x0093f727,0x41e4b264,0x435c99dc,0x05b15795,0xbfa878e0, + 0x0e673575,0x99c520a4,0x87eea759,0xca682594,0xf12a348b,0x029f7b81, + 0x2aa2ce35,0xa547cc18,0xead5e2c5,0xa11d874b,0x55682cdf,0x9af0349b, + 0x8bbe8e66,0xf86ebfea,0xf55394ab,0x3dab8782,0xebc8eb8f,0x458bf797, + 0x9b7de78c,0x4890a7a4 } }, + /* 251 */ + { { 0x8da995f6,0xd7299689,0xec6156ef,0xd39eaae7,0x356a82d5,0x6959040c, + 0xc135bcfe,0xb2046b21,0x0f595c78,0xea720b64,0xe7c5fb40,0x02824efa, + 0x0edb3bfc,0x97d8fd4c,0x79f24ebe,0x12f02905,0x187ea6b9,0x16fc47cf, + 0x789d5c23,0xc219fd27,0x89263ecc,0x233a6b6c,0x8b6d30a6,0x823634b2, + 0xc9b33680,0xca352e25,0x40c77456,0x9388d6ca,0x3c92065b,0xf8e55b0b, + 0x02439a76,0x5c17474b }, + { 0x8aaccab5,0xd888e7c2,0xaaced05b,0x18027836,0xccec0f65,0x185b877d, + 0x125c2882,0x93cadc1c,0x67fdc54c,0x45df540a,0xc2788a33,0x4f3c86e2, + 0xe3a0fa2c,0x3e874469,0x273983cf,0xc59daa47,0x4a96d8a5,0x3063c48b, + 0xc2e58915,0xc38d2bcf,0x84e428c3,0x90e78b87,0xf0c4fd53,0x900a292c, + 0x941e6005,0xb7f92db7,0x6ca53a1c,0x95679241,0xb1ab0fa7,0x35f6f31d, + 0x7b58408c,0x5d675eb4 } }, + /* 252 */ + { { 0x870c6025,0xaeee1a77,0x91a2dfca,0xfc4a23b7,0x386b64c4,0x7b0e60c4, + 0xe5ae72b1,0xd5d5b17d,0x9eefa212,0x6dfc88ac,0xd4038b96,0x4feaefbe, + 0x8e2d2ecc,0x099ac356,0x012af207,0x548ea612,0x89c31218,0x4ffed9db, + 0xe0e67331,0x1c1e91c4,0xaf8300e0,0x009bb64f,0x6773c3be,0x8780501c, + 0xc08219fa,0xe0cd6ede,0xf81b06ff,0x7c055e07,0xe080b36f,0x82b63f9c, + 0x0a9feca3,0x02fccbaf }, + { 0xb47cac61,0x9991d4d1,0xab86e12c,0x2e9d1687,0x2b94f042,0x8c6855ec, + 0x48e648e5,0xca400519,0xef89ac57,0x9ba91fb2,0x1be792cd,0x4f419206, + 0xbd0f1e15,0x82d221cb,0xfc444019,0x062eb13b,0x99790fdc,0xf3a97c32, + 0x6067a64b,0x4e796d94,0x6d23775a,0xc46dd300,0xed7f0f23,0x8672c4d5, + 0x3b4f63d7,0x821851dc,0xd26273f2,0x50a3ae0c,0xeac60f6f,0x800e58fc, + 0x13845545,0x56f1e456 } }, + /* 253 */ + { { 0x32c24f3b,0x01ccb3f6,0x06d817e6,0x99eb1c7f,0x6aa26776,0x8dc640bb, + 0x0845d5e0,0x7838affe,0xf81a79a8,0xf34fecb1,0x3e6819b0,0x6a2e282d, + 0x8237a4b8,0xc4b977ce,0x87636439,0x0f46b3db,0x97970497,0xa465f540, + 0x8791be43,0xd7e08762,0x34198ec6,0x00220b6c,0x093d94bb,0x57b38637, + 0x29d690b2,0x84012e16,0x20aad1a4,0x02ec9db5,0x85dc34e3,0xafee2fc6, + 0x25500cf8,0x911d1936 }, + { 0xf5e5af5b,0x13b1bd58,0x7b6a22a7,0xa7ca263b,0xf3af2adc,0xab6bec4d, + 0xa04420bd,0x16651e59,0x4ba36c11,0x3b448b3b,0xff424310,0x3c62bfcd, + 0xf1a96cbb,0xde15c4a5,0xe4d1f980,0xbe0ad8a1,0x36673a3a,0x812bd14e, + 0x9212acdd,0x40303af6,0x576095ce,0x8f6dab9c,0x107f5ca5,0x7df1882a, + 0x8896a3b0,0xb903e63c,0xd863b3f0,0xf5048544,0xc09887de,0x5e5019b9, + 0xa0f53865,0x2be744fe } }, + /* 254 */ + { { 0x5b50f324,0x054cd05f,0x1ea3c7a2,0xb9b1eb24,0x7ff8e6b7,0x4a858a5c, + 0xec040882,0xd83902fe,0xd0cba9bd,0x72b26494,0xb29c9e1e,0xd0176f90, + 0xcebadb81,0x05d4eb02,0x372b8bfc,0x874405b1,0x79ead190,0x5c412881, + 0xec2b48cd,0xd44a3dd3,0x3f4d5033,0x84499a77,0x564c3a09,0xb37b38cd, + 0xf42e803b,0x80e99497,0xb8f518b2,0xc07b47a0,0x3568fde4,0xc710e3c5, + 0xcead0e7a,0x735f542f }, + { 0x38380039,0xcaa9a171,0xf74d19c8,0xadfafe17,0xccbc1a8b,0x92d4393e, + 0xfe029705,0x3c5dbf39,0x930e9b36,0x4552b5ab,0x2afd494a,0x7ee63032, + 0x3f02ac43,0x826a9ad7,0x99356298,0x98c53562,0x7342bb39,0x0c869f87, + 0xe4f9b79a,0xd7510020,0xd34789a9,0x6361d1a4,0xcfa85637,0xf0ded5ba, + 0x88ac07e4,0x407ee73f,0x09ef1cbd,0xfac7d03f,0x4d475bad,0x25d697cb, + 0x14bd399e,0x1e984c9d } }, + /* 255 */ + { { 0x4850c817,0xc76d0561,0x3489812d,0xb08a5b19,0x5e58cbbe,0x7273d154, + 0x4be61e5a,0x8900b5fa,0xd7aeb8e1,0xaa088691,0xd35a3d4b,0xe66666af, + 0x57ec7d3d,0x38a2c199,0x668d6f5c,0xa0648e8f,0x7adc1746,0x1f9fc92c, + 0x843065c3,0x23a116c0,0x61e6ae69,0x36370a20,0x2aa47e73,0x626c3736, + 0xdeff6d84,0x540c25f2,0xcdbed2d4,0x9804824c,0x039a9492,0x4b5bfce0, + 0x76942e01,0x6c474a56 }, + { 0x7d88e3a1,0x3aeb9a41,0xc484742a,0x105d3c88,0x3fe61131,0xe59de8d1, + 0x1a869e8b,0x148f5b6b,0xaa75d90a,0x7a8abc59,0x62146013,0x2f0c9bc7, + 0xc3824cd9,0x43faa747,0x6a5d0b92,0x81763a18,0x9bcbaebc,0xbbc341bc, + 0xf745d1dd,0xe1813160,0xb75ce5f4,0xa53ce52d,0xd50de4c2,0x15eae66c, + 0x75d7656d,0x5ed8996c,0xc4ca552a,0xe4ff5711,0x3c5305b4,0x215e985a, + 0xfa1ba2ce,0x6b258954 } }, +}; + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^128, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_base_32(sp_point_1024* r, const sp_digit* k, + int map, int ct, void* heap) +{ + return sp_1024_ecc_mulmod_stripe_32(r, &p1024_base, p1024_table, + k, map, ct, heap); +} + +#endif + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_1024(const mp_int* km, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_digit kd[32]; +#endif + sp_point_1024* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_32(heap, p, point); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 32, km); + + err = sp_1024_ecc_mulmod_base_32(point, k, map, 1, heap); + } + if (err == MP_OKAY) { + err = sp_1024_point_to_ecc_point_32(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_32(point, 0, heap); + + return err; +} + +/* Multiply the base point of P1024 by the scalar, add point a and return + * the result. If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_add_1024(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_point_1024 a; + sp_digit kd[32]; + sp_digit t[32 * 2 * 5]; +#endif + sp_point_1024* point; + sp_point_1024* addP = NULL; + sp_digit* tmp = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_32(heap, p, point); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (32 + 32 * 2 * 5), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 32; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 32, km); + sp_1024_point_from_ecc_point_32(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_1024_mod_mul_norm_32(addP->x, addP->x, p1024_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_1024_mod_mul_norm_32(addP->y, addP->y, p1024_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_1024_mod_mul_norm_32(addP->z, addP->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_ecc_mulmod_base_32(point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_1024_proj_point_add_32(point, point, addP, tmp); + + if (map) { + sp_1024_map_32(point, point, tmp); + } + + err = sp_1024_point_to_ecc_point_32(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_32(addP, 0, heap); + sp_1024_point_free_32(point, 0, heap); + + return err; +} + +#ifndef WOLFSSL_SP_SMALL +/* Generate a pre-computation table for the point. + * + * gm Point to generate table for. + * table Buffer to hold pre-computed points table. + * len Length of table. + * heap Heap to use for allocation. + * returns BAD_FUNC_ARG when gm or len is NULL, LENGTH_ONLY_E when table is + * NULL and length is returned, BUFFER_E if length is too small and 0 otherwise. + */ +int sp_ecc_gen_table_1024(const ecc_point* gm, byte* table, word32* len, + void* heap) +{ + int err = 0; +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; +#endif + sp_point_1024* point = NULL; + sp_digit t[5 * 2 * 32]; + + if ((gm == NULL) || (len == NULL)) { + err = BAD_FUNC_ARG; + } + + if ((err == 0) && (table == NULL)) { + *len = sizeof(sp_table_entry_1024) * 256; + err = LENGTH_ONLY_E; + } + if ((err == 0) && (*len < (int)(sizeof(sp_table_entry_1024) * 256))) { + err = BUFFER_E; + } + + if (err == 0) { + err = sp_1024_point_new_32(heap, p, point); + } + if (err == 0) { + sp_1024_point_from_ecc_point_32(point, gm); + err = sp_1024_gen_stripe_table_32(point, + (sp_table_entry_1024*)table, t, heap); + } + if (err == 0) { + *len = sizeof(sp_table_entry_1024) * 256; + } + + sp_1024_point_free_32(point, 0, heap); + + return err; +} +#else +/* Generate a pre-computation table for the point. + * + * gm Point to generate table for. + * table Buffer to hold pre-computed points table. + * len Length of table. + * heap Heap to use for allocation. + * returns BAD_FUNC_ARG when gm or len is NULL, LENGTH_ONLY_E when table is + * NULL and length is returned, BUFFER_E if length is too small and 0 otherwise. + */ +int sp_ecc_gen_table_1024(const ecc_point* gm, byte* table, word32* len, + void* heap) +{ + int err = 0; + + if ((gm == NULL) || (len == NULL)) { + err = BAD_FUNC_ARG; + } + + if ((err == 0) && (table == NULL)) { + *len = 0; + err = LENGTH_ONLY_E; + } + if ((err == 0) && (*len != 0)) { + err = BUFFER_E; + } + if (err == 0) { + *len = 0; + } + + (void)heap; + + return err; +} +#endif +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * gm Point to multiply. + * table Pre-computed points. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_table_1024(const mp_int* km, const ecc_point* gm, byte* table, + ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_digit kd[32]; +#endif + sp_point_1024* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_32(heap, p, point); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32, heap, DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 32, km); + sp_1024_point_from_ecc_point_32(point, gm); + +#ifndef WOLFSSL_SP_SMALL + err = sp_1024_ecc_mulmod_stripe_32(point, point, + (const sp_table_entry_1024*)table, k, map, 0, heap); +#else + (void)table; + err = sp_1024_ecc_mulmod_32(point, point, k, map, 0, heap); +#endif + } + if (err == MP_OKAY) { + err = sp_1024_point_to_ecc_point_32(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_32(point, 0, heap); + + return err; +} + +/* Multiply p* in projective co-ordinates by q*. + * + * r.x = p.x - (p.y * q.y) + * r.y = (p.x * q.y) + p.y + * + * px [in,out] A single precision integer - X ordinate of number to multiply. + * py [in,out] A single precision integer - Y ordinate of number to multiply. + * q [in] A single precision integer - multiplier. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_mul_qx1_32(sp_digit* px, sp_digit* py, + const sp_digit* q, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 32; + + /* t1 = p.x * q.y */ + sp_1024_mont_mul_32(t1, px, q, p1024_mod, p1024_mp_mod); + /* t2 = p.y * q.y */ + sp_1024_mont_mul_32(t2, py, q, p1024_mod, p1024_mp_mod); + /* r.x = p.x - (p.y * q.y) */ + sp_1024_mont_sub_32(px, px, t2, p1024_mod); + /* r.y = (p.x * q.y) + p.y */ + sp_1024_mont_add_32(py, t1, py, p1024_mod); +} + +/* Square p* in projective co-ordinates. + * + * px' = (p.x + p.y) * (p.x - p.y) = p.x^2 - p.y^2 + * py' = 2 * p.x * p.y + * + * px [in,out] A single precision integer - X ordinate of number to square. + * py [in,out] A single precision integer - Y ordinate of number to square. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_sqr_32(sp_digit* px, sp_digit* py, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 32; + + /* t1 = p.x + p.y */ + sp_1024_mont_add_32(t1, px, py, p1024_mod); + /* t2 = p.x - p.y */ + sp_1024_mont_sub_32(t2, px, py, p1024_mod); + /* r.y = p.x * p.y */ + sp_1024_mont_mul_32(py, px, py, p1024_mod, p1024_mp_mod); + /* r.x = (p.x + p.y) * (p.x - p.y) */ + sp_1024_mont_mul_32(px, t1, t2, p1024_mod, p1024_mp_mod); + /* r.y = (p.x * p.y) * 2 */ + sp_1024_mont_dbl_32(py, py, p1024_mod); +} + +#ifdef WOLFSSL_SP_SMALL +/* Perform the modular exponentiation in Fp* for SAKKE. + * + * Simple square and multiply when expontent bit is one algorithm. + * Square and multiply performed in Fp*. + * + * base [in] Base. MP integer. + * exp [in] Exponent. MP integer. + * res [out] Result. MP integer. + * returns 0 on success and MEMORY_E if memory allocation fails. + */ +int sp_ModExp_Fp_star_1024(const mp_int* base, mp_int* exp, mp_int* res) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td; + sp_digit* t; + sp_digit* tx; + sp_digit* ty; + sp_digit* b; + sp_digit* e; +#else + sp_digit t[4 * 2 * 32]; + sp_digit tx[2 * 32]; + sp_digit ty[2 * 32]; + sp_digit b[2 * 32]; + sp_digit e[2 * 32]; +#endif + sp_digit* r; + int err = MP_OKAY; + int bits; + int i; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8 * 32 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + tx = td + 4 * 32 * 2; + ty = td + 5 * 32 * 2; + b = td + 6 * 32 * 2; + e = td + 7 * 32 * 2; +#endif + r = ty; + + bits = mp_count_bits(exp); + sp_1024_from_mp(b, 32, base); + sp_1024_from_mp(e, 32, exp); + + XMEMCPY(tx, p1024_norm_mod, sizeof(sp_digit) * 32); + sp_1024_mul_32(b, b, p1024_norm_mod); + err = sp_1024_mod_32(b, b, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(ty, b, sizeof(sp_digit) * 32); + + for (i = bits - 2; i >= 0; i--) { + sp_1024_proj_sqr_32(tx, ty, t); + if ((e[i / 32] >> (i % 32)) & 1) { + sp_1024_proj_mul_qx1_32(tx, ty, b, t); + } + } + } + + if (err == MP_OKAY) { + sp_1024_mont_inv_32(tx, tx, t); + + XMEMSET(tx + 32, 0, sizeof(sp_digit) * 32); + sp_1024_mont_reduce_32(tx, p1024_mod, p1024_mp_mod); + XMEMSET(ty + 32, 0, sizeof(sp_digit) * 32); + sp_1024_mont_reduce_32(ty, p1024_mod, p1024_mp_mod); + + sp_1024_mul_32(r, tx, ty); + err = sp_1024_mod_32(r, r, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + return err; +} + +#else +/* Pre-computed table for exponentiating g. + * Striping: 8 points at a distance of (128 combined for + * a total of 256 points. + */ +static const sp_digit sp_1024_g_table[256][32] = { + { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000 }, + { 0x335c1685, 0x170a46d2, 0xe1007a58, 0xeac9e971, 0x43ca4a73, + 0x40e8f3df, 0x82642475, 0x2646f815, 0xb36576d1, 0x3af49bb4, + 0x72bf1afb, 0xd89e2d14, 0x2fd151e6, 0x27be882c, 0x8f88717c, + 0xaddedc85, 0x16ac6c6f, 0xd6d859bf, 0x2d8eae58, 0x0e741a1b, + 0x61c1f30d, 0x6faf7a00, 0x9b67e096, 0x66dbd09a, 0x7d3b4f7d, + 0x21f11c06, 0xc727c98e, 0x6152ba02, 0xe86cb221, 0xafd58891, + 0x6bd3baf4, 0x59e93c6a }, + { 0x71dd4594, 0xe54dd36f, 0x00aef1e6, 0xbbc9cc9f, 0xa19f6530, + 0x9ea5a44e, 0x3f520928, 0x8588aa99, 0x8f5c1418, 0x9753794c, + 0xc11399fa, 0x118bd792, 0xf5cb6ab5, 0xb9bd3afd, 0x2ecb9652, + 0x813d1cb2, 0x40389813, 0xfd456267, 0x4ac8431c, 0x51f7119b, + 0x0a180eb6, 0xdd9f6a91, 0x9f7bfa2e, 0x13946d17, 0x50a9d0d9, + 0x16f18631, 0x6f8373d3, 0x5f19c20d, 0x9b6a52b9, 0xbe85ac6a, + 0x74f62e03, 0x63ef187b }, + { 0x016f45e7, 0x7c376b7f, 0x2bec82f8, 0x1c1bdb57, 0xce429b60, + 0x7392f741, 0xc7afd81d, 0x6fdbf0a2, 0x7241098b, 0xbda41b1f, + 0xbb60f8cf, 0x5b407474, 0xb330bc4d, 0x933e0d41, 0x733fa3be, + 0xae182830, 0x0f5c6cd1, 0xa0ed299b, 0x3f9860c8, 0x7ff3354e, + 0x15559c41, 0xb1360986, 0x129f85cb, 0xab0cb63c, 0x47685fbe, + 0x682ecc49, 0xeb199633, 0x505e8ec2, 0xddac2cda, 0x90dcc794, + 0xf192da23, 0x4fe6791c }, + { 0x05e8733c, 0x94a423d5, 0x1d5717c1, 0xcc845e65, 0xe961b322, + 0x237c7e88, 0xdb4181cc, 0x0c4471c6, 0x713bd721, 0x00c875e2, + 0xb2c17b09, 0x9dfde9ed, 0xe88ceaf6, 0x430a6de5, 0x7b81cea6, + 0xaaa7a61a, 0x233f98d5, 0xea52d026, 0x60689a9a, 0xb55efdd0, + 0x5cac4aab, 0x30cfa7ce, 0x8e950761, 0xfa4db114, 0x4e9a1e52, + 0x309570c4, 0x1a040170, 0x18c21f61, 0xbe78d9d2, 0x555d1ffe, + 0x561db297, 0x04482a18 }, + { 0x73d486d8, 0xe7758ac2, 0x61cdc1e7, 0x8169f946, 0x2188ab4f, + 0x723c99fc, 0xf3373630, 0xa0e54f02, 0xbd8c2260, 0x560bee25, + 0x4531bc60, 0x28fc307c, 0x7e44feb5, 0xd6f21f1a, 0x57128d37, + 0xc8e4499c, 0xd7b2ea45, 0x963b053e, 0x32a3d222, 0x40c27a04, + 0x35459668, 0x5b51854d, 0xd73557e9, 0x66e1a49f, 0x8692077a, + 0x0d267fd9, 0xe7342702, 0xfa1350d3, 0x68ccdb44, 0x1a9c3f25, + 0xdedbf89f, 0x833a0ff8 }, + { 0xab376b76, 0xa8c419c7, 0x27d0f0cc, 0x3b7294f3, 0xa90c514d, + 0xe56bb9e2, 0xa62575a6, 0x931ba51e, 0x098c0a88, 0x56fee07b, + 0xb4c16a2a, 0x04be5aee, 0xe6eb260b, 0xe513350b, 0xa1d5c270, + 0x339edad6, 0xe9dbadd1, 0xf366ed59, 0x2dd06ec0, 0x4213be88, + 0xcb1187db, 0x22d639c8, 0xd8a1058a, 0x1fec95e1, 0xa2b744f1, + 0x03f73ea6, 0xf4f05c0c, 0x741fd51a, 0x85f811a0, 0x2e2df95a, + 0xeb24965f, 0x692b3ce3 }, + { 0xd2a127b4, 0x0ce6cb72, 0x8f92816f, 0x66a46ea5, 0x47a37616, + 0x43ecf463, 0xe0ab96ee, 0x163d9a01, 0xb2edbe8c, 0xc8145c6d, + 0x4de4e665, 0x2f426cae, 0x74e252f9, 0x174d0b40, 0x7d2af831, + 0x54c240d7, 0x3d652936, 0x581fa397, 0xa09d4695, 0x05b9491c, + 0x5452643c, 0x8c4e8533, 0xd4128327, 0x32d64331, 0x70361f25, + 0x64479038, 0x89ef09f2, 0x774191b1, 0x81de5fe0, 0xc0cf0aaf, + 0xf40042d6, 0x333e430a }, + { 0xcf26d3b7, 0x5df04de4, 0xb53f79be, 0x57a77306, 0x1808b664, + 0xa4013c5f, 0x85037360, 0xef291ea4, 0x0b061037, 0x1ffc9d7d, + 0x65c913bb, 0xd9d04dd9, 0xf13b8587, 0x948a37af, 0xfe3ee755, + 0xb5443483, 0x04631386, 0x3fc21e74, 0xcddeb58c, 0xb3a104e5, + 0x6572cd52, 0x94fe1862, 0x15aaa408, 0xeb9a71a1, 0x459ea462, + 0x8adc6fe5, 0x4aeb02a3, 0xbb18d175, 0x2f7791d1, 0xae127636, + 0xd6bbd708, 0x10e8b31d }, + { 0x3ed9f1af, 0xb87f03e5, 0x56676166, 0x03ad2477, 0x74ce15b8, + 0x38dcd630, 0x26b1e85b, 0x1877e2b0, 0x1af99c15, 0xb1654d17, + 0x9382547a, 0x9782e9e4, 0x26d55ef5, 0x6dc7fc7c, 0x2fbeb54c, + 0x9038f95d, 0x036c0357, 0xfe590dfe, 0x4fdc3f7f, 0xcfcb6eae, + 0xf35e1a88, 0xcb1fbc54, 0xda0a5568, 0x3c8e1db2, 0x5b6f5557, + 0x9a87393f, 0xe7ac0a06, 0x38646b32, 0x2a8495ab, 0xfd261c83, + 0x0cdcc4bc, 0x6485524c }, + { 0xc4a6ff2a, 0x1abfb3e2, 0x35a6428a, 0x2aa03fba, 0x89aff742, + 0x884227f0, 0xba5dbd93, 0x2337883a, 0xd2a182cb, 0x38186ae9, + 0x49a01f05, 0xb9f0764d, 0x917b1e7a, 0x92411feb, 0x570cbb5b, + 0x700b1903, 0xb914be7c, 0x5d5181d5, 0x1981182d, 0x135c4437, + 0x574b9997, 0x32758d24, 0x632d28b2, 0xa650a8f5, 0xfa383f09, + 0x24078bac, 0x00a33d80, 0x6546a60c, 0x2df8b449, 0xa4061c7a, + 0xf234563c, 0x1f76f3f2 }, + { 0x44c436b0, 0x9aa2c143, 0x1f69c87a, 0x79070556, 0x5f6db2df, + 0x35f3117b, 0xed56ba82, 0x85761f41, 0x7d0afa48, 0xf831464f, + 0x3adce71e, 0xa99f2915, 0x116b7488, 0xb27bf693, 0x9bb9443a, + 0xa98a5a8c, 0x2ee5fde8, 0x7f878026, 0x1812acb7, 0x3a6f93dd, + 0xdc84bc92, 0xaf92a4cc, 0xf1d4995a, 0x3c2562af, 0x04ed899d, + 0xfd9fc33c, 0x4ed2a538, 0xc028ca94, 0x049ea726, 0xd0f367bb, + 0x3d108e05, 0x04924ffb }, + { 0xc673562f, 0x06548e3d, 0xe2eae48c, 0xd3b33025, 0x5e1c6977, + 0xe61fd32b, 0x6ebe557b, 0x424e2064, 0x41d6e18e, 0x767391c0, + 0x14d7e95b, 0x4b8ebb8e, 0x20991b8c, 0x4ae8b7d4, 0xe01290d3, + 0xf8a0df66, 0x925e5f4e, 0xc97e24a3, 0x1508272a, 0x79a7b2cb, + 0x25072661, 0xb40b072e, 0x9062fa49, 0xdad9e182, 0xf3c53bce, + 0x8780a784, 0x9f142799, 0x58a82b76, 0xc1468426, 0x08cd849c, + 0xc380ae35, 0x4dfce809 }, + { 0xd527b780, 0x45069cb2, 0x977930dd, 0xd52da015, 0xe27d0263, + 0x10cc600b, 0xbb2d1b2b, 0x34102c26, 0x554adf3c, 0x4c652623, + 0x45f0ff47, 0xd6891382, 0xca916e7c, 0x83fa8cc5, 0xd15c8d8a, + 0x1e10f139, 0x81dc56b3, 0xf173dc2e, 0x5c4ed9ba, 0x7fcecb04, + 0x47d01228, 0x307fd7d8, 0x9f3a532f, 0x24a57153, 0xe2153c22, + 0x59e9e81d, 0xe428a408, 0xc562595d, 0x9339bd23, 0xdc7daff8, + 0xb8a06802, 0x0d075908 }, + { 0xde085f2a, 0x870af2a7, 0xbe99b2e5, 0x88fcd24f, 0x59ca413b, + 0x88c0d261, 0x8559f851, 0x1f02a2e4, 0xf622da0d, 0x83b96021, + 0x6dca3615, 0x5c05c2f5, 0x7910c682, 0x0148cf1c, 0x272695be, + 0x392f2896, 0xa8d64ef6, 0x883d0bb5, 0x1cfcbc52, 0xef0d2244, + 0x526117e5, 0xf5dafcec, 0xf04928e9, 0xb68612b9, 0x393f2e2a, + 0x283f744d, 0x700c1151, 0xfbeed7ed, 0xa4360dfe, 0xf2cde215, + 0x2f08535a, 0x24fa961c }, + { 0x616df7f6, 0x0767db3f, 0xfbd90326, 0x643057d8, 0x6e82d544, + 0x174daa90, 0x689643db, 0x2284f345, 0xcc89a060, 0x18b191df, + 0xd6c27d12, 0xbab46af4, 0xc9895145, 0x5a57f486, 0xcc942f9e, + 0xc03214e9, 0x41950158, 0x273e1c8f, 0x39ad43ab, 0x8ceb759f, + 0xe50ee173, 0x5e1b8b7f, 0x8f4d7d4e, 0xf635b1fc, 0x755603f3, + 0x8eff77e3, 0x7752fa60, 0x201f61d1, 0x4a6fb6e1, 0x94d7a03d, + 0xfc4f0114, 0x371cc23d }, + { 0xda90c351, 0x289b115d, 0x364d9c06, 0x6d196ebf, 0xf650b31b, + 0x77a89202, 0x6f57642f, 0xcc28c164, 0x08100127, 0xdc4f7e36, + 0xdc4c807b, 0x8836cd08, 0xe00240f2, 0x1280f156, 0x99cb3953, + 0x3f9a6d78, 0x3a802038, 0x40a494d3, 0xe87d3474, 0x45697e91, + 0x26dde24a, 0x70d97d07, 0x7640c30e, 0x06f6a58d, 0x5ba6e6c6, + 0x03c2c0e8, 0xf1bc13e8, 0x330f6a7a, 0xc9f4d78f, 0x3e602e4f, + 0x0c80fb7f, 0x92b6bca0 }, + { 0x5f00822e, 0x2e3d5c83, 0xb8b16f12, 0x0e825712, 0x92b0a330, + 0x81c329c4, 0xa7cc1954, 0x6b4e32ad, 0x1bb1413f, 0x0bee9cee, + 0x4a92ca27, 0xedfb7baa, 0xea3b9153, 0xcd472afa, 0x00f0c0f9, + 0xe8f09e7e, 0x5cdebb70, 0xa4e1d872, 0x4a9b63b6, 0xfe2bae08, + 0x3fd58f65, 0xf40141b8, 0xa3b62759, 0xd7ec5eda, 0x790e3088, + 0x9aaf6e67, 0x1f277e31, 0x215ad830, 0xcf33871c, 0xe7db4b98, + 0x4f02f89d, 0x71ff62c9 }, + { 0x2a4a84d9, 0xaa4c7102, 0x5ebc71e6, 0xe2ee4acd, 0xf1cd6578, + 0x3b11a8a5, 0xfff120a5, 0x83f5ef9f, 0x09e65033, 0xa4c598e1, + 0xca044180, 0xe1e9f990, 0xf59828c1, 0x8b832d46, 0x33af536b, + 0x753f28a0, 0xb6d4f68a, 0x92edc4b1, 0x72ccd1f0, 0xedde692a, + 0xd2226432, 0xd3aa0f7d, 0xa3d2661c, 0x38dbb63e, 0xfdc37dda, + 0xf1e19fc6, 0x84ef6b4c, 0x6c18b350, 0xdf1bba69, 0xe6a83fe9, + 0x5f958273, 0x40fd47e7 }, + { 0x267140a4, 0x5b88b746, 0xeab6f2fb, 0x6dbbfc1e, 0x69862548, + 0xdd9ec88e, 0x2eb6efc2, 0x69beeba1, 0x8ac8ff88, 0xcfc2214a, + 0xb5a21950, 0x95d5c96e, 0x4171fb69, 0x93389c05, 0x1b468337, + 0x2d85d452, 0x4113425c, 0x14d68a08, 0xec6c2174, 0xe52c0139, + 0xf730084d, 0x20cf0b97, 0x1f578aa3, 0x1ac16a26, 0xf9b6ae43, + 0x18b9fab3, 0xd854a695, 0x68d82111, 0xdffbe286, 0x0b334d98, + 0xe639338c, 0x5b1c1157 }, + { 0x72b6bb8f, 0x90edaab1, 0x02fc92c2, 0x8dc64ed2, 0xfe694c73, + 0xf42ba3c5, 0xcb54dce4, 0x316dc65f, 0x632420dc, 0xcb2d66a3, + 0x056dcf94, 0x16e706e7, 0xa4f32c9d, 0x2809c764, 0xea6edca8, + 0xab18d830, 0x81c65f57, 0x4fd1ace6, 0x7da12c10, 0x1f91651c, + 0xc7791a48, 0x0ac3bd66, 0x785e67a3, 0xb6ad1cf4, 0xda0fd591, + 0xe4d3fc44, 0x6e1c6344, 0xce164801, 0x33e50ab3, 0x84de9cb8, + 0xa756eef4, 0x963ab83a }, + { 0xdf4ea5a3, 0x944b47d8, 0x5cfe45fe, 0x96568815, 0x8a3c3564, + 0xd16e7d58, 0xe7c99e15, 0x84e55b3e, 0xf55071bc, 0x3fee204d, + 0x04057dce, 0x71006f29, 0xbba75570, 0xfe8c390d, 0x3319adac, + 0x3645bcb6, 0x7c20bfd8, 0x8189e8b0, 0x7d7d9578, 0x8e550969, + 0xb99f4e3b, 0x037d1321, 0xa60cfb6a, 0x011b2521, 0x837382da, + 0x66594aaa, 0x83c1dc07, 0xc89b91fd, 0x076b9884, 0x6b82b899, + 0xbe45c558, 0x443480fc }, + { 0x9114221a, 0xf8ffffb4, 0x3e857a7a, 0x4aec4f2e, 0x0fa54787, + 0x42e2d0e4, 0xd6f96152, 0xef3e6b31, 0xfbfe9b77, 0xb2296537, + 0xfb43a86a, 0xc2a9d0f2, 0x24572ac6, 0x241284ed, 0xe721ba7b, + 0xa3868917, 0xc117a78d, 0xdbef7c00, 0xd31605ac, 0x38149071, + 0x065a8ee9, 0xc2dada9e, 0xc442be82, 0xd5b138d8, 0xf6d72b58, + 0x9b6c224b, 0x8eb03e6d, 0xb9d355cf, 0xa1700371, 0xab6d1eb0, + 0xcffaa7eb, 0x97118a88 }, + { 0xcdecb5d8, 0xbf9c59a2, 0xa93a6866, 0x8083c81b, 0x04774fbf, + 0x24e0dd81, 0xa02070b4, 0xe779a3ca, 0x0fbfb781, 0x9d352fbb, + 0x3ef2a1c4, 0xa8b0d820, 0x14b3e501, 0xb858637b, 0x8a882ff2, + 0x5ba70a49, 0x3b06efa5, 0xa2730083, 0x102fee2a, 0xa42c02f4, + 0x8a0223a5, 0xe4e76299, 0x85c3fc72, 0xdba2ba26, 0xfe52eae7, + 0x554fe763, 0x270f45f6, 0x30b5405a, 0xa573387c, 0xd56a177a, + 0x4b71fa82, 0x17c0778d }, + { 0x2735e37b, 0x0e6dff1d, 0x656ec572, 0xc9884e56, 0x9ebba978, + 0xa2f5ac9d, 0xba09f3c4, 0x40fa4518, 0xf5b04377, 0x8c3fa177, + 0x967a2eca, 0xa1a1decd, 0x0528bd40, 0x768bca70, 0x18691c4a, + 0xf224952b, 0xe86d5fd5, 0x16e12c45, 0x37859a6a, 0x7a0d9157, + 0xa0ffce0e, 0x723f4309, 0xa96cc9a3, 0x5a8db79b, 0x1ad23a38, + 0x6dd12ae0, 0xe2bf5d84, 0x9ffec3a1, 0xa452ed66, 0xd6ce84e1, + 0x571fe4c6, 0x1219d5c8 }, + { 0x262969eb, 0x43eaa67f, 0x2f03e773, 0x3a3ab39d, 0x57bb0909, + 0xe6127e51, 0x8d150274, 0x0f82b0ed, 0xe580bdbd, 0xffffcad8, + 0xa9743e6b, 0x51d3d075, 0x8bac11d6, 0x1484bdb1, 0xeb24c388, + 0x95cd9990, 0x7fac67c6, 0x216a61d0, 0xa04e6b87, 0x4308f762, + 0xcba57cc8, 0x2865dd61, 0xd234a07a, 0x3c296b0d, 0x3a0793f9, + 0x76f92839, 0x0be29ece, 0x70b57e1f, 0x7e626f42, 0x1314a82f, + 0xd657f230, 0x2c8d7ab2 }, + { 0x0825e4d6, 0x67cf5892, 0x6ef83b44, 0xdf51eaa5, 0x1310108d, + 0x63e665d8, 0x8dd0963f, 0x229f89f5, 0x9df6436a, 0x8c4b14dd, + 0xd45ebba7, 0x99dae469, 0x5a4df381, 0x118aab77, 0x29e37feb, + 0xda8978bd, 0xaca2d7ef, 0x69ced5aa, 0xc67d6a8a, 0x6c98d05d, + 0x77f84a34, 0x7474bf0d, 0xed8cd59a, 0xd4428b2e, 0xd1d398fb, + 0xb0fd1cd5, 0x94a20b11, 0x596013db, 0x1b404c44, 0x96eb705a, + 0x4b09d958, 0x2299d277 }, + { 0xc64397e6, 0x5b9cd58d, 0xbf6dd31e, 0xac198f1e, 0x3e9f1db2, + 0x5866d8e1, 0x8fcdc68c, 0x405ae287, 0xe53c01fd, 0xa4b280cd, + 0x411db5f6, 0xdc963f2d, 0xbec4f8a0, 0xed5d5189, 0x916ee98b, + 0x336fd13d, 0x042df48e, 0x6925b1b3, 0xace0074e, 0x0cf56291, + 0x25317e95, 0xe8d38b48, 0x821c446b, 0xc7ad1d2b, 0xf0b65934, + 0x71c44135, 0x52ca0d50, 0x971b736f, 0x27b46c26, 0xaf9ffa57, + 0x1936618e, 0x21ac6779 }, + { 0x2d7fbcd2, 0xab420e3f, 0x97bdfc18, 0x12722473, 0x4df5d4b4, + 0x492033f8, 0x3807b7d3, 0x6fcd4236, 0xb33c3625, 0xdfc19b09, + 0xa0f22814, 0x13d6f375, 0x037c19b8, 0x70978a59, 0x0ff27b9c, + 0x4f398997, 0x615a4389, 0xfc0e1a45, 0x3e602f74, 0xffa3496a, + 0xb261ca1c, 0xc3f1c431, 0xee0164cd, 0x612211db, 0xe7f7be9f, + 0x30463ee4, 0x92c2e1bb, 0x015f7e78, 0x24483a56, 0x663d88d6, + 0x0e62d9d8, 0x0e8ec1e7 }, + { 0x8a0878dd, 0xa88ccc29, 0x6640071a, 0x99ac175d, 0xa5173617, + 0x90344820, 0xdd58a315, 0x316d023e, 0x88d221a1, 0x30785bd4, + 0x959c48e3, 0xb74b3de7, 0x4c67a771, 0x42ee0382, 0xe0b91453, + 0x59ef6cdd, 0x9b237e91, 0x7830ae28, 0x495d8325, 0xe1847a4c, + 0xd0773666, 0x67b1217e, 0xa294a325, 0x58192c86, 0x864d8326, + 0x76aa0f56, 0xf4b13e5b, 0xe2a2bd12, 0x1b6b73fd, 0xd850c1c0, + 0x5d103635, 0x653a795f }, + { 0x50dcb199, 0xcfe28985, 0x7fa02b60, 0xb35b8e5e, 0xc97603d0, + 0xbca7d7c3, 0x27f131b5, 0xb0e5288d, 0xe2b12d52, 0x3aa704de, + 0x1db725c7, 0xe206b1d8, 0xc5d1b113, 0x0b12839a, 0xdb45d763, + 0x14f970cb, 0xb2125e8e, 0xc997f93e, 0xee7daa26, 0xbd75739c, + 0x1fef20e9, 0x46ecbd3f, 0x7c6a42b1, 0xf994a114, 0x27fb0fd1, + 0xd289eb4f, 0x9a40da4b, 0x11186d31, 0xfb9d7976, 0x083f65a5, + 0xd444675e, 0x30dfc47b }, + { 0x9eaadfe8, 0xbcfc5ae2, 0xb4d4e812, 0x25027e54, 0x8b533561, + 0xab0702df, 0x56a6a214, 0xa2b9c204, 0x3059068e, 0xb1a3df7a, + 0x9883110f, 0xa3514b21, 0xc4b78e1c, 0xb7be2336, 0x3e2f6984, + 0x17073ce6, 0x2ddf7ac6, 0x86e114a6, 0x07d7c3c8, 0x276192bf, + 0xeb1ae289, 0x5da69e0b, 0x25184939, 0x983af175, 0x407a3aa0, + 0x9ac52a4d, 0xae0fe218, 0x1535c7da, 0x397f2501, 0xe16fe872, + 0x54c212cf, 0x572a591f }, + { 0x09a5553a, 0x49668419, 0x327733bc, 0x3f054318, 0x3eefd690, + 0xf9ceb4b2, 0xf22126d4, 0xbd3cbf9b, 0x2fed9578, 0x6d9671c0, + 0xca0306d8, 0xbba597ce, 0x3d674fe5, 0xb705ed61, 0x67f33f76, + 0xf1d3622b, 0x11cb8c31, 0x15bcf3c6, 0xe53d1aa9, 0xa38467dc, + 0xf908ab43, 0x902fe929, 0x8d15767a, 0x6e3e499d, 0x90afd07b, + 0x8142db5c, 0x6c8b190e, 0x120c6fbc, 0x24919a4e, 0x80c86553, + 0xd8c82c3c, 0x65c2cbe1 }, + { 0xa660bb63, 0x684cda20, 0x86e86245, 0x27dc3b0a, 0x6ba0eed7, + 0x76472cf6, 0x679dd158, 0x79c162e5, 0x08452d44, 0xb6884277, + 0x413f579e, 0x829bc6b3, 0x95011770, 0x92ea15ec, 0x47738183, + 0x5e34e300, 0x73e1d2f1, 0x8c3ca349, 0x229bd3de, 0xa5c4f1dc, + 0x94ef7ed3, 0x783eff1b, 0xdfae7a1a, 0x46db738d, 0x1a099852, + 0x4353d72e, 0xa0dcf4ab, 0x2533ad58, 0x0e7888b9, 0xd8055016, + 0x3ba77f66, 0x831440d5 }, + { 0xf611b2da, 0xf43e2e32, 0xd0fa46ac, 0x5d066e29, 0x820b3c0d, + 0xe897f3e8, 0x1d3e44f0, 0xc45c28e6, 0xdfd27a66, 0x929d7f66, + 0x101e8517, 0x735b860a, 0x3de078dd, 0xea3fce98, 0x638ce11a, + 0xc9977db5, 0x48536b3b, 0x0488382f, 0x64cadfc6, 0x7e0c7a3c, + 0x82147b71, 0x3cd17f7f, 0x1b411e3e, 0xe95663cc, 0x985fb46d, + 0x5739ac8f, 0xbcf119ca, 0x385399cd, 0xe15a2815, 0x4a985a70, + 0x6d5f4566, 0x504c3a8a }, + { 0xb8fa53c7, 0x00b55283, 0x509474e3, 0x985cff38, 0x437ce25f, + 0x234d241c, 0xe5a129ed, 0x29832430, 0xaabcc674, 0x6ad38956, + 0x7ee81ee1, 0xa2dc001d, 0x670b2702, 0x4c23c6b6, 0xa6e8a3bb, + 0xb35e567e, 0xa69673ea, 0xbc70b3ce, 0xe6e28eac, 0x85a7a9c3, + 0x5537b7da, 0x2ae684de, 0x6de937dc, 0x5ecac3e5, 0xf8430422, + 0xbf2ea6c9, 0x77fdc520, 0x38caf7d0, 0x69f56add, 0xc27af0b1, + 0xc71d21d2, 0x496e4699 }, + { 0x9fa93467, 0xba14fc82, 0x0eb2a614, 0xc2e37684, 0x4833e09b, + 0x659bcfaf, 0x3686bdcc, 0xbc859752, 0x81f3216a, 0x40bfd080, + 0x17c081b8, 0xc463bda6, 0xbb04793b, 0xbd01fa86, 0x2cd640c5, + 0x5a21ece6, 0x2203d5c4, 0x97bf6a54, 0x951167b7, 0xceb40edc, + 0x765ba268, 0xd67aacaf, 0xaeab51f9, 0x8ba0d9e9, 0xb0d6863a, + 0xc14b215e, 0xe5f06952, 0x354cdcdb, 0xcb3744b5, 0x4f2b5ccf, + 0x13037fe8, 0x13389173 }, + { 0x45003cd1, 0xee680640, 0x44ae2ac6, 0xfdac17bc, 0xde8e5314, + 0x4bcd419f, 0xc7cea95c, 0x81e34eb9, 0x38f37e01, 0xbb57762d, + 0x260990c8, 0xecc4cfb0, 0x50a34a7b, 0x0bc493f9, 0x543304ef, + 0x68074172, 0x6bc8aa2a, 0xaec0fcb2, 0x3b45fea5, 0x9e7a9b46, + 0x55fbdbac, 0x4bb2952e, 0x0485dff4, 0x50f0c0a6, 0x4dea4796, + 0x02c5104d, 0x695e3a02, 0xd2cefa09, 0x6da1f345, 0x4c8102b4, + 0xf3833fbd, 0x422eb573 }, + { 0xa6ad3f47, 0xac592eb6, 0x9714ba0e, 0xb0861f6d, 0x07281459, + 0x57c1e919, 0x64ea5803, 0xcf7c94e2, 0x54b12723, 0x725376ac, + 0xdafb736a, 0xf2a6ba41, 0xcba03cdc, 0xc89e8920, 0x5b0fd3ad, + 0xf2e20cb4, 0xd66059fe, 0x26ea5a54, 0x889df8bc, 0xee63fa8b, + 0x66a3f2bf, 0x40f1c7e1, 0x747312e1, 0x09febc9c, 0x727999ff, + 0x7d19b9c2, 0xb7fd2b05, 0xa9fbbb4c, 0xa0da2dc6, 0xcfba27d7, + 0x2c252582, 0x368541cf }, + { 0x22799d37, 0x510d3c9e, 0xacfa333a, 0x1b677de5, 0x080f795b, + 0x4e6ae18f, 0xafc8dfc2, 0x69b53c2a, 0x0e842dc2, 0x797541b6, + 0xac067fe8, 0xd5a6f2af, 0xbd07d877, 0xd0208a03, 0x654be2f2, + 0x34b473f0, 0xf515e23e, 0xe67c102a, 0x2ac1af48, 0xb00dbf9d, + 0xb6a13d00, 0xe264fa41, 0x97e94c11, 0x1669786a, 0x86a586f4, + 0x09d8cf2d, 0xc7f927e9, 0x073bf869, 0x2241a566, 0xb8977880, + 0x22261334, 0x59a5bf59 }, + { 0x81347191, 0xe9d1c91e, 0xeb969972, 0x186c1abc, 0xa9d46a7f, + 0x07888767, 0xdaa7d397, 0xda93cfcc, 0xd91b9aa0, 0x08bee9f1, + 0xf8dd3c6c, 0x8267fd78, 0x94228100, 0xf93860d0, 0xdadb47fb, + 0x6a6a71aa, 0xa6156f8a, 0x9caa06b7, 0x39848bc9, 0xaa1b05e0, + 0x2aaa9135, 0x36ddc237, 0xb13f3bd1, 0x77e7e079, 0x4acc5f4d, + 0x8d0b5cbe, 0x984cfd36, 0x04da45f8, 0xd3d3e0f8, 0xf14ef618, + 0x43eb799c, 0x467564c1 }, + { 0xb6fff5d7, 0x8d725904, 0x92dc4752, 0x037f33af, 0x6d20b8aa, + 0x9095d575, 0x43baec39, 0x32235fc1, 0x68a2b9b0, 0xa2feb4af, + 0x94d35c61, 0x61c50318, 0xea877486, 0xac92b6a2, 0x011bc6f3, + 0x8eb48b15, 0xc79edcb2, 0xa28fe128, 0xa5d2a006, 0x9f71bc0c, + 0x2f15b850, 0xf3167732, 0x7a036218, 0xfe8d728c, 0x4f81e09e, + 0x068f39cb, 0x7b7c50d9, 0x1773f016, 0xed6a1e03, 0x0d0f7adb, + 0x4ee984d5, 0x8a0dee16 }, + { 0x47366e6f, 0x504991bf, 0xe86c3005, 0xb8084d9f, 0xa40cce36, + 0x14c4c751, 0x3f1961e2, 0xbbb46aa6, 0x40445e43, 0x56a785f9, + 0xc91e215f, 0xdb8d1b57, 0xc7ee808d, 0x6a8e453e, 0xbbaa1e8c, + 0xc0367ef8, 0xe3e18109, 0x310d91f1, 0x7e20a2c3, 0xf97cfd0e, + 0x554cc277, 0xf1e80c84, 0x7b628403, 0xe89bbc1d, 0x3fe0a17c, + 0x7778a966, 0xc1f00073, 0x9e9db19f, 0xb6f6bed2, 0x2ce7fe7d, + 0xee97ce23, 0x7b04b5d2 }, + { 0x82c5faf8, 0x5b546bc7, 0x8eb81097, 0x1a734c5e, 0xe77851e0, + 0x3d566861, 0xe956d51f, 0x833a1013, 0xc3c3c37c, 0xc7351731, + 0xe0c148ec, 0x607738fb, 0xe1bbef41, 0x2ec6f0bb, 0xcfa51857, + 0x0aa2ac6e, 0x66e3adf0, 0x072902d7, 0xc622d6e3, 0xcd4d5089, + 0xa6dd802f, 0x3ae21b23, 0x33886372, 0xe5465a55, 0xa8d81822, + 0xd85119a0, 0x3786977a, 0x4f14d032, 0x9c7b272c, 0x515b081c, + 0xc99be31c, 0x1c6a95a4 }, + { 0xc2821363, 0xa6b14ad5, 0x4d17de1c, 0x829c1823, 0xccade848, + 0xaef5d2c4, 0x82489e27, 0xf412ab39, 0xf081d927, 0x92c9c098, + 0x75cbad1f, 0x6f87bdf4, 0x1a1d9fb1, 0xf4aadab8, 0xb75f3b76, + 0x475a7923, 0xdbbba8fe, 0x99dd0ad6, 0x4b70ab45, 0x836f6164, + 0x34bd9af1, 0x2a464881, 0xba9abda3, 0x5c91226e, 0xe65625fb, + 0x4cec8709, 0x0818e4be, 0xd4b3919e, 0x14f6879c, 0xa5c09c84, + 0x30a864c9, 0x72708a02 }, + { 0xf34a466c, 0x4f33c0b1, 0x7f9d45ba, 0xa1bae09c, 0x0e28785c, + 0xd70f0fee, 0x90880881, 0x824c7146, 0xbb043da3, 0xe2416c2a, + 0xcec6f432, 0x733da713, 0xc9793e1c, 0x2b590649, 0xb35c9365, + 0xdb62d5b0, 0x3e5c1b2a, 0x355eb6e2, 0xbb16b515, 0xcfe8b5ce, + 0xf709691c, 0x9e081869, 0x61a85bd5, 0xc865f9fb, 0xfae103f7, + 0xf169d3cc, 0x73467e9d, 0x9525c473, 0x43695113, 0x7db55c0b, + 0x73265d21, 0x7491c74c }, + { 0x80d2b94d, 0x312ed5bf, 0xba4b260b, 0x1b8ac633, 0xd62219a1, + 0xac86c58c, 0xaeb82c8e, 0x317ccf6b, 0x59ef9ced, 0x2dfb29ee, + 0xe42bcd5a, 0xdaa7d898, 0x5974b201, 0x93e295c8, 0xd9fc5adc, + 0x69e75784, 0x012aa3ba, 0xd6c4709f, 0xc85d3cb9, 0x1fda9f37, + 0xd3dd4abd, 0xe5487e25, 0x0b3ba22e, 0x00fd4b01, 0xc6e8dcbb, + 0xcb591493, 0xbce68664, 0xb7329fab, 0x68906b76, 0x6829d1c2, + 0x74176841, 0x8bcfd3e5 }, + { 0xd3c8c314, 0x06882734, 0x11870833, 0x95f0b2f1, 0xc068ba16, + 0xb937f7c3, 0x77924787, 0x5365e0d8, 0x1f992227, 0x15527e5e, + 0x27dffd4f, 0x0a069648, 0x2f586389, 0xd58b3df2, 0x6af20ead, + 0x83446b89, 0x50746257, 0x09d7970b, 0x4022a691, 0xd9e8d206, + 0x671ec379, 0xd1e5f8af, 0x057fe91e, 0x6f542509, 0x52890418, + 0xf14dda81, 0x1db932ad, 0xbd78010e, 0x905a9378, 0x3e18d1e4, + 0xbd37ab49, 0x53cadcf7 }, + { 0x5e53d0ff, 0x1bb5edf7, 0x888abf67, 0xd886606c, 0x12206d15, + 0x6491b0f8, 0xe22b6a33, 0xb3018345, 0xb173b317, 0xaba6794b, + 0x7dc9e595, 0x8c1e5867, 0x239624d1, 0x4e106482, 0xda55dd53, + 0x61752e59, 0x9e42879c, 0x018b4eab, 0x491f2bed, 0xcaf6784b, + 0x1e79429e, 0x3dcdb9d2, 0x10f26224, 0x36941485, 0xa650ec5c, + 0x106f190a, 0xb69a9760, 0x7542a5ae, 0xc32d1046, 0x69bd75e9, + 0xbf8c62b1, 0x90849964 }, + { 0x5a93c661, 0xb1390cf6, 0x9db5f056, 0x18486264, 0xa51a1788, + 0x92a93a9d, 0x6772de9a, 0x1b0cbb8f, 0x7c71487c, 0x6e67febd, + 0x4e62423e, 0xf9b4382d, 0xbb5a42f8, 0x96fda50e, 0x6089a4f2, + 0xc921b337, 0x875ec516, 0x49d32d7b, 0xc410124b, 0xbd86d2ca, + 0xc421fb7a, 0xf6862209, 0xf6b7de33, 0x3e1949ab, 0xe93c9268, + 0xcdee18f0, 0x08dc4cc0, 0xd4edbd5e, 0x73580d22, 0xc2b75be4, + 0x468cd7e8, 0x3d7f6ffa }, + { 0xdffbd5d1, 0xea7b290c, 0x970338df, 0x9d759da6, 0x90feedc9, + 0x56680b08, 0x42dce68e, 0xbc690af5, 0xb2ae4d82, 0x8519df2b, + 0x7f195b60, 0x5612467f, 0xd83c21f4, 0x659a342c, 0x55651633, + 0x55771bf5, 0x548ba562, 0x5fc68935, 0x9492f23a, 0xb5419203, + 0x9c9c6017, 0x567528e3, 0x511e6019, 0x3f064ed4, 0x1d16a555, + 0x303f9eb9, 0x2254abee, 0x3e18c4fd, 0xfd434e7c, 0x40994d6f, + 0x6dde74e6, 0x8fb12d3f }, + { 0x293cb7a4, 0x6c6381a2, 0xb87b7e4d, 0x453e09f0, 0x078ac3ef, + 0x4f212823, 0x578cae91, 0xe89ffad0, 0x716ba4dd, 0x4a2b696a, + 0xf6f580a0, 0x14681a14, 0x4c2f1307, 0x1358f97b, 0x2932fb89, + 0x87896996, 0x268a5af7, 0x29dd850a, 0xfe239f83, 0xaf771f6d, + 0x4f47499d, 0x5f20fd2e, 0x867ca0e9, 0x9b643e77, 0x375981ec, + 0xe7858ecd, 0x19ab1c97, 0xbe946a59, 0x06ff3453, 0x4f9303a2, + 0x75d237b1, 0x3fcc6731 }, + { 0xdf21f920, 0x509debd5, 0xc1401b90, 0xfaf70e1f, 0x95a64aaf, + 0x2429cbfd, 0x2c37a122, 0xf2120855, 0x7deb926b, 0x1d4c93f4, + 0x9fb3f1dc, 0x12f3e4c0, 0x5b51bc46, 0x56085a59, 0xf10fdbd2, + 0x2a2f5d62, 0xdf0cb3c2, 0x60dd62cf, 0x6b0f254b, 0x154424a3, + 0x564612b7, 0xc3a5a05d, 0xa1f5249c, 0xbebe30cf, 0x7e62a188, + 0x24ec6903, 0xaf429939, 0x75f0fbac, 0xb3fa8685, 0xd41345dc, + 0xc7151c34, 0x645146fd }, + { 0xba1924f9, 0xecec633a, 0x006326e1, 0xbba6f136, 0x7e50fc17, + 0x203757ac, 0xef3d8e00, 0xca531919, 0x51dc5a74, 0x9545a6aa, + 0xd31412b8, 0x6e21d58f, 0x7bb1d000, 0x01bc3005, 0x6ed1a9c3, + 0xf1789c69, 0x9858fa48, 0x7af2d35f, 0x8197be85, 0x434d09b9, + 0x29aa265d, 0x1dc07755, 0xc058fa80, 0xcad03be7, 0x54ba14ce, + 0x92d70a9f, 0x6c050a74, 0x6dc78505, 0x4d005dda, 0x2a7ca4a9, + 0xabfb9f2e, 0x448d3d72 }, + { 0x29b33989, 0xdc56f145, 0xa9ae815a, 0x868351bc, 0x4b074414, + 0xb3f45613, 0x3cd9f33b, 0x955ce42a, 0x5ff6e4a3, 0x13ade4ec, + 0xa50eaa91, 0xd3aac715, 0x5666efdf, 0x0c61ec99, 0xf6a4470a, + 0x108a28b8, 0xe54844c9, 0x402ef584, 0xd0e2f337, 0xb825b162, + 0xb46f7cbc, 0x3dcd131f, 0x96f2fd89, 0x208178ec, 0x25928c78, + 0x4d8c5d67, 0x9963c459, 0x285a33df, 0xd92a309f, 0x72497175, + 0xcb7019a5, 0x76881479 }, + { 0x91767eed, 0xba43a114, 0x92bf65db, 0x5e11b9ad, 0x03a5e21a, + 0xe8a22ce0, 0x2a335415, 0x63604421, 0x4a9ead62, 0xc2c563b4, + 0xa0b2aee5, 0x4bc06264, 0x8bf2e1d7, 0x75b8d575, 0xd08a265d, + 0x1cff0ee7, 0xb0b712a7, 0x17914e1d, 0x4b18692d, 0xc35925d0, + 0x56cce815, 0xde253f4c, 0x9fff0e3a, 0xa479241c, 0xddabed19, + 0x50b9d06e, 0x59fae506, 0x67135260, 0x532ce180, 0xf37600fb, + 0x5e5a8626, 0x670eb01c }, + { 0x73cdbb43, 0xdf73c0af, 0x7f2431ad, 0xcf08ecc5, 0x2a1a3845, + 0x91780541, 0x9224ddf1, 0x69a104f2, 0xbeac7eff, 0x4352f38d, + 0x7c2d1322, 0xfc3b3b4e, 0xb5e4b476, 0xa69e9430, 0x975a46f0, + 0x7d932340, 0x5d64eece, 0x8093899e, 0xdb2345e9, 0x7b821250, + 0x7f4b796b, 0x23552932, 0x4bb90b1f, 0x2ee9cc15, 0x9112f7d6, + 0x1fa9c8f5, 0x1cbaae32, 0x2d0f2f98, 0x0075166a, 0xb77f0366, + 0x635dff27, 0x504852e7 }, + { 0xa2f392fa, 0x2f0f3ce5, 0xec6c9078, 0x326c076a, 0x84baaaf6, + 0xad01de92, 0xcbe8e993, 0xb01b16d3, 0x2d950908, 0x71305c24, + 0x3853af38, 0xc66fd617, 0xd3c429a0, 0x7735140e, 0x1fabf027, + 0x8a31b12a, 0x058b3177, 0xa0530002, 0xa9c7deb9, 0xabffd9fc, + 0xe8667d30, 0xd05ef69b, 0xe9a9e13f, 0x2f3a7308, 0xb91eae9c, + 0x3f4c9a19, 0x618ce6c4, 0x50d0cee7, 0x5240f8b0, 0xfb24dc40, + 0xf7e90cc4, 0x992fe151 }, + { 0x38f197aa, 0x4454db31, 0x87872f98, 0xa4ded69d, 0x44f0a828, + 0x97b427b0, 0xa31e48c6, 0x9821e1ae, 0xdd98efec, 0xe38cb09f, + 0x480cb3ae, 0x20b84fa8, 0x47475573, 0xba5bb4a8, 0xcd50e96b, + 0xa9be080a, 0xef103550, 0xc4451e9c, 0xc441325c, 0x626ee75f, + 0x38a5e33d, 0x6eea5e98, 0xa2b0abd2, 0x7321beb9, 0x9b6082a9, + 0xca92e484, 0x992bcc2a, 0x1dc8168a, 0x9c8eb9fb, 0x134ecf4b, + 0x4c5b71e0, 0x5a68bfa8 }, + { 0xff0a2bfb, 0xb4ff3b45, 0x5502f8b0, 0xd105fff9, 0x5b1c0c26, + 0x14de5885, 0x0d3b9d04, 0xed16865b, 0x026d3917, 0x2f5a2453, + 0xf4db3c0e, 0x6a22f493, 0xe2418f2e, 0x4871548a, 0x509bef61, + 0x6ab363a8, 0xb8cbbbec, 0x91ca1e3a, 0x4011a396, 0x71e0dc98, + 0x0d5ca577, 0xff982e0a, 0x81897bc1, 0xeb40b045, 0x085ad5e7, + 0x4bc24a46, 0xa6337b7c, 0xd15c8fa0, 0xbef1628f, 0x56ce6ef7, + 0x9f5ef439, 0x78acfdf9 }, + { 0xf8520189, 0x45bf7f15, 0xc77f61c4, 0x954202a0, 0xdfa22e1b, + 0x39edc6b9, 0x1f4a3487, 0xd2d60267, 0x4814cc52, 0xcd933929, + 0x05e9f123, 0xde76a124, 0xae36b6f7, 0xe2306ea0, 0xb83a58e0, + 0x53815218, 0xa041231a, 0x9862bb76, 0xbf31be71, 0xe8da253c, + 0x37de861f, 0x2dfc5332, 0x90ae4890, 0xf25c93f6, 0x8baa6ed2, + 0x66bcb8f0, 0x908b4a29, 0x6f10ae0f, 0xb061c949, 0x8cb4b48c, + 0xd075a366, 0x0ad92d73 }, + { 0xc2ca548a, 0xbfb95fed, 0x80cd89ab, 0x4778c620, 0x3466c280, + 0xbe99154b, 0xd4be8902, 0xea3be093, 0x13e681ed, 0x847b7995, + 0x02f40161, 0xf22a8f4b, 0x4aeb7fe8, 0x3ef2cb4d, 0xb3aed5f6, + 0x9adc5151, 0x98c31163, 0xec1ccfd1, 0xa3d7d88f, 0xdc2ac17b, + 0x46421097, 0x08fa64d3, 0x94b90bcf, 0x5ebf80b7, 0x0b50a9eb, + 0x1b78b4ba, 0x279aa66b, 0x1a4fe934, 0x075b3ced, 0x8ef4dcaf, + 0x70a6e9ae, 0x95bbd8a0 }, + { 0xe614bbd0, 0x59f92495, 0xb823e363, 0x7567a887, 0xfc1bd6a7, + 0xe247c9ec, 0x8e835c42, 0x2bfaaf47, 0xaade066a, 0x314ef4e0, + 0x5c16d336, 0x072baa63, 0xe2f0e389, 0xfa429c71, 0xbd07d90f, + 0xcac1e5d0, 0x514f5c04, 0x69ff35ea, 0xc0554ec1, 0x893053fc, + 0x2a35947f, 0xab1d86b7, 0x2aebe487, 0xe29fb060, 0xdfb9cf21, + 0xa0a10d6d, 0xf20dfcf5, 0xad147059, 0xb8867a2a, 0x480dc66f, + 0xc125a919, 0x375a884f }, + { 0x1217f7ea, 0x178cbe2e, 0x875c6dab, 0x1a161e2a, 0x1bdb1a54, + 0xf7707ec0, 0xe4fd73ca, 0x678864a0, 0xd13a0d86, 0xbaebc664, + 0xc8d30668, 0x40325f99, 0x2f1c5950, 0xb93ed9c9, 0x541e0667, + 0xfdf36763, 0xb91a6763, 0xfd97fbb0, 0x6079c9a0, 0x26aa69ea, + 0x1eaa8c47, 0xc7303c80, 0xafa63c55, 0xdec75c81, 0x4fd12adb, + 0x01cdcde2, 0x1968838a, 0x9fe0dda7, 0x38415379, 0x66bb093b, + 0x08cb84ec, 0x268d818b }, + { 0x41580555, 0x73dae358, 0x473d103b, 0x4fc32e67, 0xbeccc1ab, + 0x240c1013, 0xb24ee9de, 0xda4099f2, 0x9fa8e066, 0x37b0cb5b, + 0x6438d7ee, 0xb5ae04e4, 0x2b720140, 0x7f7d3164, 0x339e4a78, + 0x86ef4edb, 0x3a7d8375, 0xa5e77eed, 0xbd707c2e, 0x883fad37, + 0x0f979189, 0x816b633a, 0x2e7a208e, 0xe24c028a, 0x4435516a, + 0x1171fe3c, 0x4f5f2bf5, 0x3eb93b33, 0x01b53a56, 0x8419ed4b, + 0x056ca44b, 0x8b02735c }, + { 0xe1019195, 0xb89bb464, 0xf3fc28c1, 0x1de4c026, 0x2bfc3b21, + 0xac120e6e, 0x91bdf92f, 0xec71bc5a, 0x0d995bc9, 0x485d7ab4, + 0xe6491ffe, 0x97c6768e, 0xafbce265, 0xd9552d19, 0x8e1b76c2, + 0xbae6c7fe, 0xd7e3ad1b, 0x167d8281, 0x5e989734, 0x3e149af9, + 0x8a0c8182, 0xd1f0024c, 0xc3006c0d, 0xf571ffdb, 0x58773d4c, + 0xb32ecf7e, 0xfd3540d8, 0x5822a782, 0x04365042, 0x5ab45c3f, + 0x4b4d85fe, 0x400e3aa0 }, + { 0x5e46e4a2, 0x47321649, 0x24136074, 0x37a2ed64, 0xc60ec77d, + 0x659223b1, 0xe5e0ac2e, 0x5e13aac3, 0xc5107ab7, 0xda17c41b, + 0x73c253db, 0x65b22ec9, 0xa5012296, 0xff3867b8, 0x0621a99b, + 0xfed660d5, 0xc89fc3f5, 0xa3c28506, 0xf16451a7, 0x3ed350b9, + 0x67cb586f, 0x27c3e032, 0x967185b1, 0xc807c779, 0x4a13009b, + 0x09c157d4, 0xadaf1f4d, 0x362f7647, 0xf3a6a198, 0x4a42b9ac, + 0x8da6e039, 0x131c3da2 }, + { 0xa7da83ba, 0x4a785ff1, 0xd04f4436, 0xf415b425, 0xec03f812, + 0x7c0899bd, 0x80f5f4a2, 0xc58d411a, 0xfda251b9, 0x3d32d610, + 0xcd3b2f32, 0x99bb4504, 0xf4c2083c, 0x198c444b, 0x730e83fd, + 0x60c261af, 0xcb02db90, 0x060ca4df, 0x9df1e7c8, 0x0ff7838b, + 0xc4c690c9, 0x6b79cf97, 0x5d75f154, 0x131514d7, 0x1cb0e8ff, + 0xa7c074f1, 0xb2c17615, 0xb920aac1, 0x44aa0ff0, 0xde8098ad, + 0x34545ce9, 0x71d1a46a }, + { 0xfa1b382e, 0x76178f76, 0x772dda0d, 0xa0d8ecc3, 0xc5d4d130, + 0xaa5aab2a, 0x8d72622c, 0x27d38ba4, 0xca3bed06, 0xc5410db6, + 0x793ceccf, 0xf637a588, 0x6e65e3d7, 0x1f65dafd, 0x60a45641, + 0xc3b44a85, 0x4f78540b, 0x0f47b3a8, 0x5e4d60f6, 0x824fdadd, + 0x17d3b6d5, 0xd8ccf90c, 0x325fc13a, 0x008eabdf, 0x3648fab9, + 0x3e90d716, 0x24c52d4b, 0x3964ff3a, 0x533d0acb, 0xb95cc416, + 0x1167f521, 0x6cd2699f }, + { 0x12f4f3ac, 0x2d8c0b3b, 0x99d1bdfb, 0xb03dcfe2, 0x30f37326, + 0x540034f8, 0x7c5a8c82, 0x22dd6893, 0xcd8f1442, 0xeb7093d0, + 0x585742f2, 0x892795a7, 0x087adadd, 0xe15f282c, 0x16ab7b5e, + 0x7bbdc749, 0xa58acbb4, 0xd30fe40b, 0xe2bac39b, 0x0de417eb, + 0xc61a04bc, 0x4b4b19a6, 0xf2735569, 0x9338c34d, 0x30ab196f, + 0xe8f03742, 0x6c88c965, 0xfa2efcb8, 0xc7eeb826, 0x19eee274, + 0xda345dc2, 0x327c063f }, + { 0x5b47cd53, 0xab399eff, 0x1943aefe, 0xbbe9869d, 0x1402a866, + 0xe64ecc7b, 0xb1c25a16, 0xc3e7c2aa, 0x022de271, 0xc4216b79, + 0x366d6a5f, 0xe58dfcc8, 0xda813336, 0xd159509e, 0x130bfb7c, + 0x370400f2, 0x93b48780, 0x1be4e059, 0x39f3cd22, 0x0623a1fe, + 0xeecb4f87, 0x72aa22b2, 0x6c27b83b, 0x1af4c496, 0xda5fa5bf, + 0x7a42a94b, 0x48b01af2, 0x9afba822, 0x3670112c, 0xeb6b9d2a, + 0xc0df6856, 0x020f19d1 }, + { 0xa4dbba20, 0x37051a86, 0xdb1de5c5, 0xb618ebc6, 0xe6525840, + 0x9a780a19, 0xd2bccc4d, 0x9440302d, 0x10285a24, 0xe9ff023d, + 0x3a486268, 0x3b937ee3, 0x4cd61147, 0xe37ee2f2, 0xa3d057cf, + 0x79fbbfd3, 0xccddefce, 0x5fba16d3, 0x5b231727, 0x916058ec, + 0x720c3adb, 0x47699ebe, 0x8b4f6bba, 0x26274386, 0xf18a0770, + 0x54b0092a, 0xacca1160, 0x99d090eb, 0x0c888f60, 0xf757e1ff, + 0xb0050544, 0x79e72720 }, + { 0x2820a239, 0x632acf25, 0xaae6b310, 0xb1a3974e, 0x48c0a1df, + 0xd61fd6ba, 0x5a3ee7aa, 0xd2453c39, 0xb980446d, 0x548455a0, + 0xde16676f, 0x9f29d97b, 0x789375a1, 0xf252ca0c, 0x7743a985, + 0xe961af3e, 0x66cdbd8d, 0x70c79c56, 0xcbc538f9, 0x14a3854e, + 0xa126851c, 0x58daa73a, 0x2a9f558c, 0xe9b5bb45, 0xfbd15e05, + 0x37af7f83, 0x38a1939d, 0xa4487927, 0x9511a056, 0xe428b2b5, + 0x7015846d, 0x001d3ce3 }, + { 0xe145b1d7, 0xd6be36b9, 0x009c5664, 0xf3e3938a, 0xe7c0f6db, + 0x2e562e7d, 0xc343f539, 0x951044e6, 0xd90897b1, 0xa5ab62b8, + 0x512f797c, 0xb1a1f70b, 0x750f28e4, 0x91cdd754, 0xffb8165d, + 0xb4c80e2f, 0x594d02b3, 0x65ed39c7, 0x56833edc, 0xcc12a49d, + 0xf3693a18, 0xe73694bc, 0xfcd2c404, 0x34cc134a, 0x11d40194, + 0x071bd5fc, 0xfc585e46, 0x05759047, 0x790b7a04, 0xb3280360, + 0x40afc684, 0x4bb8c6fc }, + { 0xfd0f8796, 0x3120e2dd, 0xb133c9de, 0x6968a40d, 0xa9369c6e, + 0xfea366c0, 0x6007273b, 0x37e5b6d6, 0x8cb81439, 0x39e4ecf0, + 0x9febc005, 0x487fe9cd, 0x0199b53c, 0xeb8af444, 0x293519eb, + 0x2f124e3b, 0xc82c9c16, 0x860c218a, 0x709dc590, 0xacd1d6f2, + 0x36d50529, 0x5696d545, 0x59120bfc, 0xc03f5df9, 0x10ffa690, + 0x99a3e88d, 0x6c432827, 0xd4f9cfa5, 0x9a135d89, 0x2e8fea9e, + 0xb6a77e78, 0x3699a881 }, + { 0x1eb1c64d, 0x5bca3372, 0xf1d28154, 0xe9cf3a2d, 0x6537106f, + 0xb7e2e9b3, 0x4f7cbf4d, 0x06c17151, 0x2058b37f, 0xcbde416e, + 0x8834e9c5, 0x82c53a7e, 0xe9ac3a75, 0x94dbdfe2, 0xc5e67c02, + 0x795ec6cb, 0x1426a80d, 0x8c23c25f, 0x6a8d4f9f, 0xee2cd20d, + 0xd3b7c235, 0x838daa54, 0x3d7a4d52, 0xb9e08ec0, 0x781cb473, + 0xca9475e9, 0x5ec31caa, 0x7271f39e, 0x82535187, 0x1df08e9f, + 0x208aff8b, 0x4f3a4b03 }, + { 0x1ed095f8, 0x0f7b8107, 0xda226d4e, 0x23e37fa6, 0xafb36d1d, + 0x8b0f9852, 0x07d8e311, 0xb114634e, 0xe3e0f16e, 0xb9634a97, + 0x421eec37, 0x2454bb9c, 0xd72b21c1, 0xb4ecd5db, 0x6df20d7c, + 0xf9603868, 0xdf86e0a2, 0x9f5359fd, 0x5ac488aa, 0xc43d54fa, + 0xd1049df4, 0x56d714ab, 0xb020607a, 0x13152b3e, 0x7a02325e, + 0x49be1c18, 0x52ae84db, 0x44f24f4a, 0x0b5a7b80, 0x9e525c03, + 0xa6d179fd, 0x6d874446 }, + { 0xbe9a42f5, 0xd29d07aa, 0x3781ccc8, 0x1fd5316c, 0x9dc69ea1, + 0x71a75a6d, 0x88fee91a, 0x4e19e0df, 0xf8d44f12, 0x99c2b4dc, + 0x31ae94e4, 0x05f6df92, 0xcf28ccc2, 0x27fba876, 0xf57f7ceb, + 0x6e1a0f01, 0xf3fd3b74, 0xe03f1f34, 0x42c1d213, 0xa0edc4a7, + 0x7deb8580, 0x5caac270, 0xaf0848bc, 0x0f5d791f, 0x07ac759d, + 0x17f514ad, 0x904fc531, 0x95a39734, 0x7bb70f3d, 0x95a4aca9, + 0xff9c5609, 0x3cf384c9 }, + { 0xce1fc9e3, 0x700506ba, 0x676b0399, 0x49721742, 0xe72bf7b3, + 0x2b4a1b8d, 0x79b209f7, 0xca8602a8, 0xce26a8e1, 0x90580b90, + 0xfe24f39a, 0x1ef339b7, 0x629362e1, 0xb6c5d991, 0x577b24f4, + 0x51174e1a, 0x05e451e9, 0xf380fcb5, 0x148321bd, 0xf4d97afb, + 0x747e5d2a, 0x099806bb, 0xbe99a608, 0x85525d65, 0xd455e820, + 0x264828d9, 0xd8560a65, 0x8c8c5405, 0x71030770, 0x3c67e73c, + 0xee73df26, 0x2b248850 }, + { 0x8541159f, 0x2173cde6, 0x4fb410b2, 0x78224c18, 0x1f2ca1c7, + 0x07a28619, 0xa8b23e40, 0x52c207d6, 0xa6b2344a, 0x071a0210, + 0xb5ed2945, 0xdb0e587c, 0x810fcc6c, 0x6c56b8ef, 0x62d843b9, + 0x1248c58f, 0x74c66975, 0x4b90363d, 0xe66c66f6, 0x6348f7f2, + 0xc126bcbe, 0xb2f9d441, 0x73ce49e8, 0xac07f2a3, 0xe81b0df0, + 0x52486758, 0x1d4621d1, 0xa108b54d, 0x74414a1c, 0x17261ece, + 0x6a3ac215, 0x938b3bcc }, + { 0xe4ded340, 0xa9e4a16b, 0x80e88036, 0x8e65fb2a, 0xdcd73acb, + 0x97089606, 0xaaa657a9, 0x1c3a0434, 0x49101b06, 0xf304fc58, + 0xda0bb64c, 0xe60fb61a, 0xf5542df5, 0x818c2aec, 0x56f76d5f, + 0x74020576, 0x92533d97, 0xb566b790, 0x74d6eb5f, 0xae4655e5, + 0xa55b44b7, 0x60f7a1b5, 0x93747ea5, 0x7970179b, 0xf2dace56, + 0x8ae7e0e8, 0x84e83c06, 0x98474607, 0x15307341, 0x24e8c9ed, + 0xd9e89d6b, 0x6cff58a5 }, + { 0x03e51f68, 0x508c01b0, 0x1d2fe7d6, 0xe1d1f225, 0x09bd8805, + 0xf7998d0b, 0x03e415b7, 0x255e907a, 0x607d9798, 0xd148467d, + 0x9b453896, 0x055c3b1e, 0x809f50f4, 0x35001013, 0xd0233fdc, + 0xfbbb2fa6, 0xff1820b8, 0x0b680b0a, 0x38d317e0, 0xb1d404dc, + 0xccc8c7df, 0x133d5444, 0x6ec13f84, 0x7fa847e6, 0x046e2e48, + 0xc33f83d8, 0x4863b3ac, 0x3c627fc5, 0xeb936af7, 0x5f67f8aa, + 0x31b79327, 0x5fe4ac8f }, + { 0x8b6f401e, 0x581aa4bf, 0xad5c7ed4, 0x05db12a3, 0x6fb07b4a, + 0x7b018726, 0x9c22bcd4, 0xfdd11f04, 0x69371c95, 0x5454a7d4, + 0x99a46eaf, 0x066c55fb, 0x7fef96d0, 0x18637c7c, 0x6b83e95c, + 0xbafc1d34, 0x00bb42dc, 0x55c38593, 0x34e7e712, 0xdd8dec2b, + 0xb184cee8, 0x69c9cfb0, 0x49a27864, 0x8dcc0c42, 0x2010f2e7, + 0x290d95f2, 0x6977a420, 0x86e254c9, 0xeb2abdad, 0x20931c89, + 0x121c0548, 0x81377164 }, + { 0x9c5a8edf, 0x6266b25e, 0x1078a7ad, 0x6e1388c2, 0x4876eedf, + 0x5f02737d, 0x62744617, 0x242fa7f9, 0xb385382a, 0x3e2cfbd9, + 0x02f71bef, 0xbadad7b1, 0x677d0a92, 0x562abcfa, 0x51fdff34, + 0x573ebd17, 0x7c250c78, 0xd7f65852, 0xc47ca896, 0xe0cf16ee, + 0x67622c9e, 0x8ccd79b0, 0xf8f2c075, 0x31fc5882, 0xa6008515, + 0x9232b37e, 0x82e8c5ba, 0x4d7bb361, 0xd2f146fe, 0xbf24735c, + 0x9cd2db98, 0x79c280ee }, + { 0xf2b48122, 0xbdcc8203, 0xb04ac48e, 0xa8c04916, 0x9fc4885e, + 0xacf064dc, 0x82c1001c, 0xab838997, 0x676de250, 0x7339e721, + 0x8e1ab820, 0x17aa5aea, 0x6bc14b2e, 0x24d28ca0, 0x816b6230, + 0x570c5bb7, 0xcee6b606, 0x6c51235c, 0x183eae42, 0x1b2bf89f, + 0x9c66274b, 0x3e3af3c6, 0xb51e38bc, 0xe0b04426, 0x73e40e3b, + 0x26dbc58e, 0xb5be5be4, 0x3f9dd578, 0x52c8f408, 0x9fd9f791, + 0xa9e3ff4f, 0x758073a4 }, + { 0x8691ca22, 0x7d27b057, 0x13a2a1b6, 0xf206bfd6, 0xac795413, + 0xe84bd385, 0x75536607, 0xc5d18a2a, 0xc8a0e24c, 0x2e166de7, + 0x3c474dbd, 0x56d5750c, 0x1366843a, 0xdef444c1, 0xcf4b8432, + 0x14646e53, 0xa9fd9783, 0x4bc0d030, 0x297ee203, 0xbda4c824, + 0xfd7be6c7, 0x3d0b10bf, 0x08c7f3ff, 0x2d216476, 0xb4fd4c45, + 0x06e52599, 0x49e9e104, 0xfbab9fa1, 0x8661d32d, 0x9342a7fa, + 0xfaf66aa8, 0x3f3e3458 }, + { 0x951597aa, 0x51ec35af, 0x49df64eb, 0xb677d4ac, 0x9bf4eff5, + 0x0276cd9c, 0x515a2935, 0x423eca49, 0xfd9bb9c3, 0x8a696553, + 0xede1f09c, 0xf99ee9df, 0x199e5f98, 0xb8fa2956, 0x35292c32, + 0xb7638758, 0xfc40e81b, 0x8734eddc, 0x65457d95, 0xd82d5e9f, + 0x30c78d2b, 0xc8ee323e, 0xc1433d67, 0xe77b2e4c, 0x3c8314ae, + 0x56d9f807, 0x2a0e2f63, 0x441eede2, 0x6c48295e, 0x1e9e17ed, + 0x34c294ef, 0x640d20c4 }, + { 0x3284d513, 0x4e9a0b8e, 0xf315053a, 0x074c3545, 0x45acd52a, + 0xb36e7407, 0x1de50db7, 0xd80bdcfc, 0x2549fc46, 0x8d9d47dc, + 0x303f07a8, 0x29b6ef13, 0x6d4ad4c2, 0x4e461aca, 0xfc9f1b73, + 0xca8e351d, 0x57460e65, 0x8bc4094d, 0x0f32d367, 0xb6302b33, + 0x285742e8, 0x69a074b6, 0x876c29c3, 0xdfe52b11, 0x912bd17a, + 0xf39e4609, 0x349aa639, 0x8ee40d66, 0xc72e05c1, 0xb968902a, + 0xc0d92816, 0x0f9c1ca8 }, + { 0x67433df3, 0x1ebbaab3, 0x15d3628c, 0xb6aa5347, 0x97f0c5cc, + 0x13a320d8, 0x65e408f9, 0x72c918cb, 0xd5373451, 0x4b638854, + 0x0b4dca09, 0x731399a3, 0x0a3b1326, 0xcf256730, 0x6608b388, + 0x5ea60dfa, 0x7b290dfd, 0x58ad74b0, 0xd7694f9b, 0x83202789, + 0xb6630fb1, 0x48593db8, 0xc65e3eaf, 0x3db47f70, 0x3e7263f8, + 0x63949c91, 0xe6e6ff33, 0x9b9acec6, 0x098a8240, 0x34bd9ba7, + 0x45d36ec5, 0x7e31c12f }, + { 0x0dfd2dd7, 0xbe281d68, 0x24ab61d8, 0x1efacb00, 0x94431f97, + 0xb9c3005f, 0x959cb3bc, 0x660c8dfa, 0xcffbb406, 0xfdd5fc30, + 0x7969a10d, 0x7a4631be, 0xde13fd1b, 0x336e309e, 0xfc947076, + 0x76b3bfad, 0xdcc72223, 0xfa91925d, 0x156c4ee1, 0x741f0d73, + 0x0e2b3747, 0x4f64ee41, 0xefc4d93c, 0x86be92d3, 0xfc4fbb2e, + 0xc53b7e03, 0x337ca1bb, 0xac196cf5, 0x7e23ba60, 0x4de41a30, + 0x326d5357, 0x1a219c45 }, + { 0xaa4db0bc, 0xfdcf7ef8, 0x7b6c9963, 0x2e231806, 0x3d8a192f, + 0xc2639067, 0xffdc7771, 0xc0cec2e2, 0xa2fc0edb, 0x997c8e35, + 0x82cc6043, 0x78e10ec1, 0x2b0c8120, 0xfd0de2cb, 0x69e57f8e, + 0x4d6c457f, 0x5b53f1c3, 0x953e69b2, 0xc4f89cb8, 0x422a330a, + 0x95566be6, 0x92ff2329, 0x437442d1, 0x73cd502d, 0xbea69403, + 0xf04ce590, 0xf8030662, 0x6ac1537e, 0xb6d0bf93, 0xe02bcf77, + 0xbc90192f, 0x17aaa999 }, + { 0x8e55db2e, 0x0d3d5643, 0x3b946851, 0x835dee43, 0x5b88462f, + 0x1a1440e5, 0xea17e27c, 0xa6ff3b35, 0xdd95f7a9, 0x23f99c36, + 0xbdd672cf, 0x7217fdd9, 0xdd2045c0, 0xf400ac1e, 0x4ff06b25, + 0x94b55c87, 0x0e4a49be, 0x0a44a0e5, 0xb43b6813, 0xe8925e91, + 0x214f96c5, 0x78bedde1, 0x0f97fa97, 0x0f456a4c, 0xa5bfd267, + 0xa28fd86b, 0xbe7608ef, 0x3b4b2d8f, 0x226474bc, 0xfbd5ff8c, + 0xa5f3b24a, 0x6b282af0 }, + { 0x6341a595, 0x78fc025f, 0xa445e28c, 0x591c38d6, 0xeb446842, + 0x72bd6e3d, 0x75547833, 0x3f9466d3, 0x083e16c4, 0x911414d3, + 0x95a7acb4, 0x145d9466, 0x8fd2fb64, 0x102ddf09, 0x0bfd87b1, + 0x2a2b2d2d, 0x59455088, 0x69e9be5c, 0xa80245de, 0xee378bf4, + 0xb2306b0e, 0x80b0bd68, 0xc2be9f3d, 0x76a545c6, 0x4802c245, + 0x429d167b, 0x2b412dfb, 0x13e64427, 0xee8d9762, 0xb664f529, + 0x54706ebf, 0x6d4f5d23 }, + { 0x00ba9f88, 0x35c8f2b6, 0x7bb6d0bf, 0xfdc807e0, 0xb3b81e5b, + 0x0a126d42, 0xa7ac781e, 0x335ce6ce, 0xf37dcba6, 0x3e308e6f, + 0x63c96487, 0x028dca62, 0x8818434d, 0x72eba57e, 0x79b78a26, + 0xa9e3d59f, 0x2f07aea3, 0xd2f0a7dd, 0x24d05f74, 0xe0fe4678, + 0x0116deb6, 0xb2085170, 0x58f37580, 0x9c2a5e92, 0x74070bb3, + 0xe78bd7a5, 0xb9977d90, 0x551fc872, 0x40db81b4, 0x6eda93c4, + 0xd65d34ad, 0x4aaf0b4f }, + { 0x3514c7af, 0x9bef2506, 0xbc181ead, 0xb09e7dad, 0x8fa3ec58, + 0xef3cae87, 0x173b8685, 0xd8dbfab5, 0x921d32dd, 0xb2490fc0, + 0x8bd9c466, 0x4eef386b, 0xa061dbdb, 0xc1cdd52f, 0x25bc04db, + 0x64de989a, 0x85728636, 0x06f9836b, 0x8be44aa0, 0x11a5a804, + 0x097018c7, 0x16dede4e, 0xb2c11fb1, 0x72aec577, 0xa721ecd9, + 0x144dade1, 0xd6ebf3a9, 0xf99c526b, 0x1c2e14d7, 0xa1d4165b, + 0x82bc6337, 0x8b2cbd39 }, + { 0x8a52e991, 0x28ec1bf2, 0xcf9d42ec, 0x0ba202f6, 0xc634ea45, + 0x8307d130, 0xc5762b9c, 0x3fc257b3, 0x487c2a2d, 0xbd3298d1, + 0xa319488a, 0xca14f1a7, 0x06ba06d2, 0xc70ca93b, 0xee405e89, + 0x9aa3f4b3, 0x35deeae7, 0xcc64eeb3, 0x03bf1d4c, 0xd155f578, + 0x45616bfd, 0x041ec0b5, 0x086e33f6, 0x23df80e6, 0xf0243cf5, + 0x399a79c8, 0x874ccd58, 0x86c2824e, 0x8fc5c831, 0x220eeaec, + 0x7dbe3670, 0x57e28304 }, + { 0xfbcdf666, 0x6e60b698, 0x8bebb1d2, 0xbdd06a99, 0x80498436, + 0x4044adba, 0x522bc88d, 0xd76bf75e, 0x28423b20, 0x655c4b9b, + 0x53398a72, 0x65c0f492, 0x0ca37601, 0x76d4f2b7, 0x2030fa5a, + 0x46989925, 0xb6054705, 0x96b37e87, 0x53de1b2f, 0xef96f731, + 0xad54ef05, 0x5ecbbc8c, 0xa93617b0, 0xeb289d0a, 0x7cba217d, + 0x3ac0fbd5, 0x19d4a2d7, 0xd0d3cb56, 0xc91d6063, 0xe8bee9d4, + 0x696ffda6, 0x4f12e037 }, + { 0x15f1a610, 0x4ccfa422, 0x3786519a, 0x804a5c55, 0x73838134, + 0x1246a454, 0x4b284e2a, 0xfa15b484, 0x146d1320, 0x36464c65, + 0x70a8a0fa, 0xfb6ba88c, 0x93c4804e, 0x74e7cee7, 0xb95ae16a, + 0x8c34d22c, 0xf9c1d4dd, 0x9d9ed89f, 0x32025371, 0x61a0866d, + 0x9bd6444a, 0x45b232b2, 0xf277bab1, 0xf888e92c, 0xa9448b02, + 0x73e69c6e, 0x5b521ecb, 0x1a496ea9, 0x5858afb2, 0xa8f78ea7, + 0xb1266f91, 0x83d2333e }, + { 0x67b478d7, 0x1c633288, 0x50a2fc9c, 0xa1ee1ae1, 0x18d2241b, + 0x05b6ab30, 0x893cd696, 0x69f1f288, 0xa8117a87, 0x159d6660, + 0x70e73d77, 0xe8120119, 0x93f55f0a, 0x528fef00, 0xd854dfb2, + 0xb3978db8, 0xf45d9fbb, 0xd6b43ef6, 0xd5bee397, 0x17de4bfe, + 0x6bf76dad, 0xa01e0f59, 0x3d40754c, 0x28b2280e, 0xf8e86ef3, + 0x8edb6122, 0xb7d1e586, 0x8226b6af, 0x2f40a55b, 0x46353215, + 0xc5a31621, 0x7362f13e }, + { 0x73c0c430, 0x792eb27c, 0xa51c3657, 0x8cc0a65f, 0xd2194f1b, + 0x50a5cece, 0x814b4947, 0x18945688, 0x4b6fbbf4, 0xbbf0a81a, + 0xf0aa8608, 0x376f4f58, 0x3987795e, 0xd9361d68, 0xe3a8d0d5, + 0xb6510cd8, 0xb6c1a455, 0x63e2fdbf, 0xaec891f9, 0x2c91154e, + 0xff568f64, 0x0eb1e715, 0x2f2b399e, 0xe7af9cd7, 0x89f0bf0b, + 0x1fc39bac, 0x90983695, 0xf0861d92, 0xda0a20a8, 0xd9b16f02, + 0xa38c0ead, 0x2f10693f }, + { 0x0c06ded2, 0x07a6ce91, 0x2fd9087b, 0xf974842f, 0xa9f635a6, + 0xe468bfd6, 0x1ed60626, 0x04b61891, 0x369ee548, 0x1fb2f89f, + 0xdc96a201, 0x9cbd1113, 0x10d633ac, 0x6759acfe, 0x8faa629e, + 0x64ba66fc, 0x47f38283, 0xa686ae49, 0xd59cda99, 0x828c3a05, + 0x08ea2f6e, 0x7c7afb14, 0xaf3953c8, 0x2551c8e4, 0x9daa9e4f, + 0x5b53d279, 0xad6f1940, 0x1eff68d4, 0x96437cdb, 0x2775dbdd, + 0x4fe7a043, 0x985f83e4 }, + { 0xeaf45294, 0x89603c16, 0xc24b5751, 0x70131160, 0x39d6b52d, + 0x4c112018, 0xed943340, 0x7079cf02, 0x74f41b68, 0x0c5b028b, + 0x9c8ac1e1, 0x3dc3f076, 0xf8b24f0e, 0x5ac5eea3, 0xe34c5c22, + 0xee6684ba, 0x9abc452a, 0xa5259e63, 0xe9df45cc, 0xb07d2cd1, + 0x1a443cfa, 0x07019c93, 0x92c003b3, 0x68fddaa9, 0x0d8cbc2e, + 0x2d9f179c, 0x1e781ca7, 0xbbf15a6f, 0x50dcc799, 0x54d779d5, + 0x0fe962f1, 0x0c88e540 }, + { 0xe8f44357, 0x84f71a6a, 0x3a3cab6a, 0xf75b4bf6, 0x5aebc680, + 0x334c9d9e, 0x8a753ef2, 0xcecaf084, 0x075e3c8e, 0xe28014c1, + 0xf74f8d3a, 0xbb9d5a38, 0xb80e32ae, 0x75988464, 0xf2bc3792, + 0x7b328e6f, 0xeed0e197, 0xebbb1faf, 0x5a33065a, 0x674eac95, + 0x922dbce8, 0x8c19fd8f, 0x987b907a, 0x8c17ae85, 0x3b3a2cd7, + 0x89f33627, 0xfa87772f, 0xebaea019, 0x3a25ced6, 0x4e5de499, + 0xaf110715, 0x8e2560b8 }, + { 0x3141aba6, 0x56d3746c, 0xbab2cf9e, 0x45a1079f, 0x9cdd27c7, + 0xb6382831, 0x9dfd950e, 0x22237632, 0x3a9408ff, 0x1e0b15cd, + 0xb1160118, 0x49a80200, 0xa383bba7, 0x2719db5d, 0x651046d5, + 0x6078340a, 0x97523b1f, 0x8929d4de, 0x8e0a28ab, 0x4040345c, + 0x0adf09c7, 0x61275ac2, 0x2331d611, 0xb41ab265, 0x5391ca50, + 0x230cc77c, 0x8f922315, 0x88be0c92, 0x92fd9a29, 0xfef3d92b, + 0x8324f2e5, 0x59005f22 }, + { 0x3c4c1c74, 0x6bb1750c, 0xe966fb79, 0xbe73aac0, 0x66c5973f, + 0x85a75d92, 0x3a8656b6, 0x8c97f932, 0x50446cde, 0x2b7043b1, + 0x3ff3897f, 0x548916f7, 0xb18b72b2, 0x913dd01c, 0x488c0de6, + 0xd0a751f1, 0x8558ca58, 0x19175714, 0x44a663da, 0x97714301, + 0xb0e08618, 0x2df190ac, 0xf39ead9c, 0x0080fc0c, 0x17382da1, + 0x0085ac6e, 0x3262a338, 0xe9791851, 0xb43bae8d, 0xe4495936, + 0xd783df6e, 0x57a78e26 }, + { 0x40dbddd8, 0x161b346f, 0x9410c3ac, 0x2b49a927, 0x1886cf3b, + 0x8c542783, 0x33b93deb, 0x72df3232, 0x40df579d, 0x9c8d59f5, + 0xc20ef500, 0xe5d7a67d, 0x67f08643, 0xc46b3918, 0xad96adc3, + 0xecfa2445, 0x0c4544d0, 0x658f589b, 0xe08417d7, 0xe6ec9301, + 0xc454e288, 0x6ca5ef6a, 0xac0f462d, 0x4191048f, 0x08d8a036, + 0x852407d8, 0xf6d35b7e, 0xb4c533a7, 0x8f6ada87, 0x3251e412, + 0x81c472e8, 0x1ca370c5 }, + { 0xa801b68a, 0x94bd5171, 0xfd1998b3, 0x7312879c, 0x41163202, + 0x4905aabf, 0xf5b01fdb, 0xb5fe87f4, 0x9cda128b, 0x78de523a, + 0xc7bd31f7, 0x0bf161a1, 0x23904c35, 0xb5decfd0, 0xe188f12d, + 0x224b2882, 0xf99dae74, 0x0dd2801d, 0x08cd1cd2, 0xcad467b5, + 0xc0867e39, 0x6c311c3d, 0x2b425072, 0x71a11720, 0x2efd9003, + 0x83bf464e, 0x1dbd3b03, 0x53d0448a, 0xe6265baa, 0x32db52f4, + 0x4c33ac79, 0x2584b34c }, + { 0x2aeec688, 0x3cb86389, 0x45fbe523, 0xa5e740ba, 0xfd60b5f8, + 0x422e71f7, 0x4874913d, 0x455d185c, 0xfa17d80d, 0x04c2bb36, + 0xac054524, 0x3f271854, 0xa8b9a657, 0x76dd3045, 0x62ee7cc8, + 0x2e42c3e1, 0x4df6c7d0, 0x00266706, 0xdc7cb488, 0x5927dd51, + 0x187897e0, 0x6b3faabe, 0xf2d5737c, 0xfe6ad22e, 0xff51a9ff, + 0xafb60269, 0x69807baa, 0xe1c83545, 0x951ca49a, 0xacddb6ff, + 0x3f9ab085, 0x7e811374 }, + { 0x830a88b1, 0xad722a8b, 0xce1117e1, 0x91918ea8, 0x0409b47d, + 0x3e02d0b8, 0x6c46d1d3, 0xb53812d3, 0xe589669c, 0x2fd09db0, + 0x15b0cd5e, 0x9845cd06, 0x2386c453, 0x0c1c155a, 0xf5ff43cb, + 0xda774de5, 0xe391c0cd, 0xbb076b98, 0x5004f286, 0x97d71eff, + 0xaeec0bfe, 0x23e0b46c, 0x32a1ad94, 0xe4538667, 0x396da422, + 0xfe0c9f81, 0x63db2bfe, 0x6376c1a2, 0xba56fa91, 0x001c7918, + 0xdf8485a6, 0x436b8c64 }, + { 0x8ab764bc, 0x88117e9d, 0xa077df84, 0xdfa61e94, 0x0c18eebd, + 0x5a7765d3, 0xfc9451dc, 0x548916af, 0x071a347a, 0x01a52e33, + 0xb23b41df, 0x633b95de, 0x43c8c286, 0xdd7d68c9, 0x18d97068, + 0xe4f9d41e, 0x8c92799d, 0x79908b90, 0xd47394a3, 0xe614148e, + 0xcd51e53f, 0xe5018517, 0x0243dcb6, 0x5060075e, 0x17954405, + 0xe5dcde62, 0x537da5ff, 0x6f7c90e1, 0x0768cb66, 0x1df7aae4, + 0x6dbe95e1, 0x5266ca9e }, + { 0x1386b3db, 0x84ddee6d, 0x7c38e540, 0xf9e4af5a, 0xeb04f49d, + 0xb3418440, 0xfde5a4fd, 0x2138a1e8, 0x30257cfc, 0x3e6e6924, + 0x19fd70c1, 0x3519c6e3, 0x86c31ff0, 0x8f34e174, 0x940ce1e8, + 0xf1e298fd, 0x14960d7c, 0x6fb8cb1d, 0x2b2f3bff, 0x207c1347, + 0x146ef8ff, 0x899a20b4, 0x7bd3e220, 0x7dec362b, 0x626bea27, + 0xa975044e, 0x4fb4cb67, 0x0f32b449, 0x1fc6703a, 0xc17a0920, + 0x9cd84a2b, 0x41f325b9 }, + { 0xce2843a4, 0x312ed513, 0x00728afc, 0xe748498e, 0x4d864ce5, + 0xa8ef2822, 0xa620083b, 0x34064704, 0x4bed338d, 0x5905e1d9, + 0x063e7b38, 0x2a578cb5, 0x289e7bb9, 0x98276d96, 0xf17b7341, + 0xdfe2dc47, 0x1dac8944, 0x5923521f, 0x23400aa7, 0x3db6d28d, + 0xa761ba43, 0xc647705e, 0x9bfd07dd, 0x8947ba6d, 0x242ca8fd, + 0x00f2e3ac, 0xeb8c3468, 0x49ef4670, 0xd9aa18fd, 0x7db3d37b, + 0xe58cea9e, 0x56b30fb6 }, + { 0xcd80a428, 0x07ecdcaa, 0x8732c891, 0x7af922dc, 0x3ada441f, + 0x20d88798, 0x924b008a, 0x3bed9a44, 0xb2e81c3a, 0x2123533c, + 0x65f807d3, 0xc34e4075, 0x1f2faecb, 0x0bfaefa5, 0xade8a88d, + 0x78b634a5, 0x94392a91, 0xc4e0b7f8, 0x90bb1cd8, 0x30922377, + 0xf87204ae, 0xdea9b4fa, 0x85d3cd83, 0x3edf81f5, 0xc6523a79, + 0x58f88c51, 0x17c0d969, 0xe472fb8b, 0xdccf7f07, 0x899081e5, + 0x58bdd146, 0x1353cc57 }, + { 0x39bf6e18, 0x28a56497, 0x649b89c7, 0x59e8b5a2, 0xdce8b8e7, + 0x8d9434a0, 0x2047040c, 0xd935bf51, 0x6a7b8e82, 0x2ab3a164, + 0x27f81294, 0xf1583ed6, 0x72d67297, 0x8416a7e0, 0xcd39e42b, + 0x49685d86, 0x958ddbad, 0x8a797fc7, 0x155ce6de, 0xa558f928, + 0xf8a36235, 0x75f4e570, 0x52877ae5, 0xbc69cfc0, 0xa6b16ebd, + 0x8f4193a9, 0xbb1cc1f1, 0x8d1df43c, 0x5a21e789, 0x723a830e, + 0xf451df58, 0x3ec2185d }, + { 0x1f0bc2d7, 0xb9d4c7d7, 0x6e51d412, 0x6982c6cc, 0xa09f80f6, + 0x92e02d93, 0x047ae09c, 0xb7dd2d25, 0x37f351f9, 0x3503149f, + 0xc77850be, 0x69d49ce1, 0x12f0d2c8, 0x60242acb, 0x7bc28b9d, + 0xba188c56, 0x06bc0550, 0x8e406121, 0x8d7d4329, 0xb0d84b1f, + 0xd38951e0, 0xb4a67ae7, 0x8bc97607, 0xb527c57b, 0x5497aa72, + 0xbc93c5f3, 0x39bdd666, 0x5f1de8cc, 0xe9d447a3, 0x3087dc5c, + 0xa211abe5, 0x89b356b6 }, + { 0xdfdcc837, 0xed6db0af, 0xa871b7a9, 0x0fb80baa, 0x1c1d4b72, + 0x413abfc9, 0xadac9e5c, 0xf5b56bf7, 0x8b8657a3, 0x5664a2da, + 0x0e41d94e, 0x11b04f72, 0x37433658, 0x63e11d26, 0xf426daea, + 0xee628ece, 0xcb162dc2, 0x011619c9, 0x87648643, 0x9cf5817f, + 0x5584bc86, 0xe1bb9702, 0x00bf7928, 0x2cc27cef, 0xdc60eee5, + 0x4ef3a80e, 0x87adc2f9, 0x7e1202be, 0x8a0d4f52, 0x656f18e0, + 0x57c5d126, 0x39c4f10d }, + { 0xe88aecd3, 0xb3a9b68c, 0xa518aa9d, 0x555b0918, 0x4bd4ee54, + 0xedc1cdad, 0x02068d84, 0x79b68b67, 0x811ac72d, 0x7dac80d0, + 0xa81a0a78, 0x6d1e6d35, 0x3bd16283, 0xc841e9ea, 0x894c4444, + 0xa7bc1775, 0xf1aa1202, 0xf2b63725, 0xc7d4c556, 0xbec7767e, + 0xd46ff51b, 0x2817ebb3, 0x73f7e339, 0xfde5be8d, 0x5aed24c4, + 0x44c6c977, 0xb6e579cf, 0x0b9a1707, 0x9069fbcc, 0xcff16478, + 0x49152b00, 0x414b542d }, + { 0x606e173b, 0x33c31e58, 0x90e6713a, 0x5b7f4e1b, 0xdebb20af, + 0x425fb512, 0x05120e70, 0xc788c617, 0x9013e4ec, 0x3ef05602, + 0x81c6e6d7, 0x9f9d35ac, 0x9450690a, 0xe131e88f, 0x44af082e, + 0x708f9b32, 0x1ba2aea9, 0xb2e4d66c, 0x740db29c, 0xaf1f4a6e, + 0xd1843007, 0x74ab9248, 0xed556a6c, 0x13338ef8, 0x270d17a6, + 0xf48e623e, 0x9608f5bf, 0x3c7362fa, 0x444e8515, 0x43977874, + 0xe00b8b2a, 0x52678d6a }, + { 0xdf36aeb4, 0x5dff1c59, 0xa92bc0ab, 0x52d6653c, 0x927a5f81, + 0x0e03f496, 0x2dfd491f, 0x8509d414, 0xa571f89b, 0x258c2c52, + 0x93334485, 0x2bd61804, 0x3f7d9e09, 0x1a33e94f, 0x2c1bf906, + 0xfab418d3, 0x5aa5695c, 0xf39c490e, 0xf6d2d7ff, 0x0e41196e, + 0x0f7948a9, 0x3ecd4075, 0xd3053b4f, 0x4b58f9b2, 0x5d9974c9, + 0xb8ee842a, 0xbf22f682, 0x23a59c1d, 0xc8efcea6, 0x045ac614, + 0xc10ceedd, 0x7040ba5b }, + { 0x515a1a96, 0x2c364f81, 0x184327e0, 0x31a63503, 0x1ad93d4f, + 0x0a096650, 0x273b6173, 0x9d7694f1, 0xd2cda9d2, 0x8886d876, + 0x2814c177, 0x1e01a742, 0x8667696b, 0x3492276b, 0x5b25f006, + 0x2fd4f0c6, 0xfb294c4a, 0x6527349f, 0xde1d336f, 0xc1fe0d8a, + 0xe7e3860e, 0xaf9a23e8, 0xb774c31e, 0x97d2b721, 0x4365784a, + 0xfac3e582, 0x70f4eaa3, 0xff2dff4e, 0xfe873248, 0x3d281e1a, + 0x0bd1c9c1, 0x9043a6d6 }, + { 0x766c7937, 0x1511a0fe, 0xabbc3be3, 0x1b2ded5c, 0xe00888ac, + 0x2ac160cc, 0x616200f3, 0x928754bd, 0x34a2ea06, 0xb801c83d, + 0x9cbe106f, 0x8ad7a03a, 0xcedfcd94, 0x996b0822, 0xe4069880, + 0xc3c3463a, 0xf597f663, 0xfb12ea4d, 0x40c92af9, 0x2c8d3834, + 0x4e8da154, 0x79bc85c6, 0xdb4e801a, 0x95771fa2, 0x1e3579b2, + 0x7bd2c138, 0xffaad078, 0xe45c75df, 0xb73eac46, 0xb0760a3c, + 0x3a125f35, 0x26362b48 }, + { 0xeefc3e89, 0x25c68d28, 0x69e9ee71, 0x2d0ee877, 0xaf5e4b75, + 0x8b07bb86, 0xcb86b333, 0xdb709072, 0xff552bac, 0xfd3d20ea, + 0x4c0da1e9, 0xa5eeb2b1, 0x44f97145, 0x391f688a, 0x1e06d485, + 0x21fbd310, 0xbea9cd49, 0x45e4f2a5, 0xa7bf21da, 0x7b60d464, + 0x054d5471, 0x193f88c8, 0xbee0f2e9, 0x5ace53d1, 0xc1439273, + 0x92c26563, 0x96c6b5ee, 0x9c86e0b2, 0x09ff59ba, 0x452fe231, + 0x555c935e, 0x2e952b20 }, + { 0xd75f886e, 0x2a846bca, 0xd43dfc58, 0xe68a5dbe, 0x007b1b86, + 0x103e45b6, 0x355ff2b5, 0x580e2ec9, 0xa263ecc9, 0xbc702f26, + 0x181e5e33, 0x2835b386, 0x6c122076, 0x025113ec, 0x7fbd856d, + 0xa5c26e3a, 0x9d6ebcb1, 0x8ef83fb3, 0xa44d2fa8, 0x7aaa53f2, + 0x53b1fa97, 0x7c14ef33, 0x17559a30, 0xff604a11, 0xb09377e0, + 0x2bcd96b0, 0xdb2f0273, 0xa5c14896, 0xeb53ef06, 0x1c0a84c9, + 0x30378e4b, 0x1236d017 }, + { 0xc084373b, 0xd7481c8f, 0x646097ae, 0x29ae4768, 0x613bc34b, + 0x1300dfa0, 0x934bc2b0, 0x3712714c, 0x0e2be7e2, 0x86524629, + 0xed010800, 0x554fbb9f, 0x42314576, 0xf0ec0b38, 0x330a3282, + 0x65baf594, 0x706ef817, 0x3bdde1a8, 0xba7530e9, 0x7d2c727d, + 0x74cc95cb, 0xbb0c5d66, 0x2438906d, 0xb3fcd365, 0xd14658f3, + 0x19881941, 0x6c97f0e9, 0xe616f555, 0x4b9ec7ea, 0x353c2d85, + 0x620cb56e, 0x02a48014 }, + { 0x506ccd38, 0x11d6d23d, 0x9059baa6, 0x229a1c54, 0x69d011c5, + 0x717c9c27, 0xd828937d, 0xe87e1b46, 0x83835083, 0xf5d63bbb, + 0xaadac258, 0xf0a7b427, 0x9f154d1f, 0x99ab26bd, 0x8ec955fd, + 0xdec0ffbf, 0x49fcb880, 0xee957c67, 0x1e0114de, 0x32395dee, + 0x369f46c7, 0x192a64b7, 0x91eb2599, 0x43044660, 0xa2e8c3da, + 0xbe2da887, 0xc3556d18, 0xa44e2c25, 0xb55f75f3, 0x31390414, + 0x8f217fe0, 0x1d8bde6f }, + { 0xa2028924, 0x03cd39f8, 0xb06ecb9f, 0x6e54f19c, 0xd6f05846, + 0x862bbcb7, 0x5a060776, 0xdbe06716, 0xb10fec10, 0x9397c97a, + 0x6f1bb65c, 0xf4213826, 0xa672ba38, 0x414deccb, 0xf88b05e6, + 0x594d4d43, 0xac94d4d1, 0x7993f57a, 0xbfb17638, 0x74fc2a6a, + 0xb6fc655a, 0xd8196b5b, 0xee8d2139, 0xdc375c84, 0x360d3a26, + 0xb9b00a02, 0xdeb93b87, 0xb36ed35c, 0xcc83209e, 0xf565b28b, + 0xc61013c1, 0x349c6943 }, + { 0x4de6c88a, 0xd1b39444, 0x4700207e, 0xd5c2c471, 0x21c2b780, + 0xb6f458a2, 0x0850993e, 0x749f7564, 0xbaef0c18, 0x400ba579, + 0x737c70f0, 0x2d742938, 0x21467ebf, 0xc5a8e2ec, 0x5337f453, + 0x243a666e, 0xed0bd50a, 0xc991f1c7, 0xf4bd1f91, 0x3a7f3e90, + 0x5f0e129b, 0x96089e8a, 0x07389635, 0xd0d3a177, 0x27182ac9, + 0x9cf842d5, 0x0817c5c2, 0x21195299, 0x87255769, 0xa32f327e, + 0x89c2d8fa, 0x056587ab }, + { 0x1ce4733d, 0x008562ed, 0x98e51444, 0x5faff7cb, 0xa9ab46b9, + 0x5f03021f, 0xb61a8c13, 0x89494c5e, 0x36b35976, 0x57c95036, + 0x2ac2d2f6, 0x6be84c8f, 0x9bd2703e, 0x0e5b34d8, 0x7e872abb, + 0xc4ad918f, 0xc4052ee1, 0xc2a89e9f, 0x3190b51e, 0xc2caee3f, + 0x6fff254f, 0x58fd1437, 0x883e0972, 0x6f3c0d68, 0x0fb15438, + 0x63d0a0e9, 0xf6caae00, 0xc438764b, 0x3f1d0f6c, 0x815f1565, + 0xb86cdbde, 0x1b87f2ed }, + { 0x2b0b15b1, 0x35792bbb, 0xce6ba779, 0xa3e4b5a7, 0xdd8f3779, + 0xfbacffd9, 0xc298d1ef, 0x005450bd, 0xc47031c6, 0x0e3f5556, + 0x95d68066, 0x0770f07a, 0x2d1052c2, 0xce3e84e0, 0x7aa8cc54, + 0xb050791e, 0xba3223a3, 0x4d621e73, 0x39632990, 0x87b9b94d, + 0x7eb8056d, 0x8df9cb47, 0xedfca0cc, 0xe2430de8, 0x9712a0ca, + 0x374bf416, 0x88848a99, 0xbe3f3c77, 0xc4a3e59e, 0xb22b87b1, + 0x3e95bc23, 0x8e0227c4 }, + { 0x3210964d, 0x000e22a8, 0xff056eeb, 0xdccd5df5, 0xdaf1ead7, + 0x02173a1f, 0x67cdcae3, 0xd02833e0, 0x8bdcc90c, 0x1cc574cb, + 0x3224b4f5, 0x86eca714, 0xbb3f8298, 0xd00e603a, 0x0c1a8deb, + 0xb98ece1b, 0x378c261d, 0x228a46e4, 0xa6165e5d, 0xc6f9dd0d, + 0x4b7ef0e2, 0xb3ae3899, 0xbda9f306, 0x3a3c16b3, 0x38a084db, + 0x5e9a26d3, 0x5394e950, 0x528e5993, 0x4ea206bc, 0x848ecb11, + 0x40545d6e, 0x14b15ab5 }, + { 0x664c59a2, 0x0f6d86c9, 0x60fd7aa5, 0x3dfe2be1, 0x9072cb8e, + 0x33f9b569, 0x8176a7e0, 0x5f2325d9, 0x4587080b, 0x79a0d4e7, + 0x0d5d4e05, 0xa4ee0def, 0xc87b28e1, 0xc0ad9ffa, 0x3f09b4ee, + 0xd6f18d2f, 0x292e9d87, 0xcc896ae7, 0x6094763c, 0xca88953d, + 0x18fbf9fa, 0xdbee97a8, 0x4b63d701, 0xdf20e0e9, 0x47ea722f, + 0xcbba6e30, 0x612b571f, 0xce57e1ca, 0x009a55f5, 0x1e16ac76, + 0xc4389e2e, 0x742bbed8 }, + { 0xc1dc2c73, 0x23ea86dc, 0xc1643abf, 0x4bbbfd5b, 0x24d8ca1f, + 0x07f8fa1f, 0x8cb5cac7, 0xde68a6e0, 0x54e66a7d, 0x7d54c64b, + 0xa9b7ad78, 0x789dba22, 0xe364ab94, 0x4d88d540, 0x1f72e011, + 0xc8c2e02d, 0x46e2a278, 0x4c826057, 0x4b187c7d, 0xe6c35bb3, + 0xeb8fe0c9, 0xed8b3dfe, 0x7d11e415, 0xb6bc34e8, 0xb865c7f9, + 0xb3908bbf, 0xe1ecc17c, 0x717d1ce6, 0xf7cdd69b, 0x151e3308, + 0xb5c94124, 0x97bd5a14 }, + { 0x81e82861, 0xe01c62fe, 0xdd42c40e, 0x703d4b6d, 0xe65e91e5, + 0x7e52e55b, 0x5abbbfdd, 0xb8b49374, 0xc72a45f4, 0xb4f15f52, + 0x550f29d8, 0xce8435a8, 0x582de75f, 0x9df76b9b, 0xa20c8b96, + 0x52e84c5f, 0x0a8a0af4, 0xaf77d2d1, 0xca6013c3, 0x0389bbd8, + 0x26f8305f, 0xb0d9b9ba, 0x0cec8b9a, 0xf053e848, 0xffabda18, + 0x4d63367a, 0xa6424c2a, 0x50f53be4, 0x864fba2e, 0xf892c58c, + 0x48cc5469, 0x317c6d31 }, + { 0x2cb7d42b, 0x0c3525b0, 0x310facae, 0x55240bc9, 0xff20408f, + 0x8d5d2022, 0xe0c10ea0, 0x6b01402f, 0x718eb23d, 0x7fbef68a, + 0x41252a19, 0xa0146b5a, 0x110e0d6e, 0x59afce48, 0x022de181, + 0xe9a1d27f, 0xdc3f49da, 0x6db96d16, 0xefbe4008, 0xfc1ae3f5, + 0xeccbc11c, 0xf9d70641, 0x525f8636, 0x49022279, 0xc2763c30, + 0x3769796a, 0x1d90630b, 0x9cc3483c, 0xee3d3f17, 0x451651f0, + 0x9da0b8fd, 0x6ae59739 }, + { 0xbff4d2ee, 0x57b13bc7, 0x30b173d8, 0x20754229, 0x0794936c, + 0xb6254bd5, 0x5efd55be, 0x1d5f232a, 0x4e0c3389, 0xc06f4a85, + 0x8e61f944, 0xcf2c5b59, 0xfd5f87b7, 0xc564861f, 0x5a2afa4c, + 0xee261fb1, 0x2d97a774, 0xb0ff7226, 0xd6cf007a, 0x1a89ae22, + 0xd346f214, 0x28880534, 0x97b6497e, 0x8fe73bff, 0xfa2afffc, + 0x8a8595b2, 0xf151a726, 0x9ef9cf3e, 0xe744b82b, 0xa84ee5f1, + 0xbc63fe72, 0x6649048d }, + { 0x1e8b760d, 0x91b7bb78, 0x25aadaa0, 0xd47b0bd8, 0xfab5226f, + 0x81493d9f, 0xbffc148e, 0x4a6dd226, 0xa29be3db, 0x5a032f8a, + 0x34b0ab0b, 0x318dbc70, 0x7d654868, 0xdcccbfb5, 0x9c581e46, + 0x8506ab37, 0x2830ece2, 0x09136a6e, 0xcf6c80c7, 0x48b79356, + 0xef6b1e86, 0xfa176377, 0x83f0f1c9, 0x2c9c1cc1, 0x16abeddd, + 0x96f0526d, 0xa93b0de4, 0x3e0e98e2, 0x0f13873a, 0x6f2d7ada, + 0xf3fa49ec, 0x4eb93b5c }, + { 0xe11fae32, 0xbd89f7e5, 0xc4023f51, 0xd13d74f5, 0x491c3f6f, + 0x1b0014df, 0x555279b7, 0x1d849a57, 0x05ba0068, 0xbb9e8897, + 0xc13ca2ca, 0x82222419, 0xfd33676f, 0xafbbb685, 0x75878a2a, + 0x931c3f52, 0xef3d5173, 0x12aeefef, 0xbd8a6878, 0x189a5cc8, + 0xd99f0c16, 0x82cffdb3, 0xa19d48b6, 0xbf565406, 0xe9c6c4e0, + 0x5605e223, 0x86804172, 0x53e781de, 0xc7001cc8, 0xcdf5c90b, + 0x7c043f68, 0x2b582d93 }, + { 0x81abc2ae, 0xa1165c82, 0xe2b69eca, 0xa73380f5, 0x07fff66f, + 0xc097b3d2, 0x54776506, 0x5d603826, 0xb57fa21c, 0xdcbac9f3, + 0xc98dbdd5, 0x78750db4, 0xd9eff32a, 0x85e21103, 0x2f11c41c, + 0xceed172c, 0x9e348c09, 0xa8e39264, 0x831eddfb, 0x71cb936b, + 0xf50864a3, 0x915c3d06, 0xe93acfcd, 0xfe8e33cd, 0xb3f2f7aa, + 0x4bee10d7, 0xeb7cee9a, 0xc1d8eb48, 0xfa574afd, 0x4fa49ce3, + 0x862db4c0, 0x78615109 }, + { 0x7ae72c21, 0x3fe3f480, 0xfd0f0da5, 0x631aa144, 0xf8c3a454, + 0xc76ee1e8, 0x51b4f1ab, 0x379ae094, 0xd7cdbb24, 0x2a3a4397, + 0x82bd5fcd, 0x7a14cffe, 0xf427ef5a, 0xbbe4ed12, 0x284d3ccf, + 0x9b0a43ee, 0x8eec6e1e, 0x57b78b93, 0x67b8e87b, 0x18d404e4, + 0x34374c20, 0x0c8adc05, 0x5428deb5, 0x64373605, 0xc3afa2cf, + 0xb4d80ec0, 0x3aa956f9, 0x6d51f93c, 0x84161c68, 0x9f9a28ab, + 0x6bc9c025, 0x540b6bb7 }, + { 0x321d315d, 0x04e1734c, 0xd86e05d0, 0x4ef56612, 0xbba8cd81, + 0xeafae145, 0xacdc789a, 0x1fb07a49, 0x5877570f, 0x6a21e9ad, + 0xb9bc53de, 0x2e4a837e, 0x1d6298eb, 0x436db293, 0xea362f45, + 0x43afbc78, 0xaabf6585, 0x2a973d97, 0x0c924d60, 0xdce7dabe, + 0x7cadf0e9, 0xf69d98f0, 0x75020538, 0xe0b505a1, 0x4461cd29, + 0x3db7d1a3, 0x5e20e818, 0xe1c28776, 0x52dd50f6, 0x2ca25867, + 0x92e0388c, 0x897cab14 }, + { 0x0d8bab8a, 0x59ed3813, 0xa438200a, 0xc11d364c, 0x40581415, + 0x0687bf2c, 0x7ac89674, 0x86ad0d3a, 0xb97411a0, 0x44928105, + 0xf383371c, 0x74984b11, 0x0d1a831e, 0x70d2ed84, 0x6c912fe0, + 0xd883628b, 0x14fa88d2, 0x44f8f7fb, 0xcf0ac93e, 0x564f2a4d, + 0xa6c24fa6, 0x82f629aa, 0xbf6cd949, 0xab906ba3, 0x20a5182d, + 0x2c822e67, 0x30eb93a5, 0x2ff47dac, 0xfff673aa, 0xdc62c4a4, + 0x476b0ec5, 0x64b00763 }, + { 0xb3c9a404, 0x1e3f533e, 0xb7ef9952, 0xb1db7f73, 0x6c253693, + 0xc7f13e29, 0x0738eed4, 0x7ce7f4c4, 0xce26cad0, 0xccfd3b33, + 0x01ec5cf1, 0xd8784935, 0xdc084e01, 0x3f8fc09d, 0xc39b5acf, + 0x217cab32, 0x9ef5551c, 0x42daf0bb, 0xe1217a95, 0xfbc76f56, + 0xc237002a, 0x80178b12, 0xb070a293, 0x0b52c39f, 0x576ca964, + 0xe3925153, 0x19d68e36, 0x25559424, 0x09e50e84, 0x291fb82c, + 0x6618ed8c, 0x7dd22ea6 }, + { 0x49cbb3bf, 0x7ffe844b, 0x5562fb25, 0xde0cc704, 0x9f5a845a, + 0x1e6ee537, 0xe51277fc, 0x956d7f26, 0x30635718, 0x2c75d4b9, + 0x96957f34, 0x39a14892, 0x82e5742b, 0x8cf4eb32, 0x83247b72, + 0x6b0d3ddd, 0x201a4237, 0x67a9f633, 0x1414a485, 0x416403c1, + 0xb6f6a916, 0x60afd447, 0xdac6f790, 0x95f94930, 0xbd3b9d82, + 0x685ff94b, 0x51cadf0f, 0x5c8f98fc, 0xb13b7489, 0x9559c88a, + 0x5f18fcc8, 0x31377c66 }, + { 0x7dcfb35f, 0x35c5de09, 0x01cc36f8, 0x2dccca9f, 0x7576cb63, + 0x7e93e85d, 0xf7b4b375, 0x0c2dd48a, 0xb09a19b5, 0x9d95cd4f, + 0x71bfe607, 0x752ed159, 0x2596dad2, 0x439880cf, 0x69e90a6f, + 0xe52efb53, 0x03d3e60a, 0x44097663, 0xa95070e0, 0xfcf364fa, + 0x05624dd2, 0xd8f993b6, 0x00d5e467, 0xb35a9824, 0x0c8f4524, + 0xe289d024, 0x648a0179, 0xef45423c, 0x587edabd, 0x3a5fd695, + 0xa11e5271, 0x3dacc50c }, + { 0x6499ae4c, 0xcb3e4f94, 0x7053c527, 0xa46dcbe1, 0xbe782e8a, + 0x807f5ce9, 0xd8481e45, 0xb6c64d28, 0xaa286fd0, 0xf35e4518, + 0xdf1cdb49, 0xf7b7b9ba, 0xaec23eaf, 0xf3fb6210, 0xb9bfd2fb, + 0x0a9ba385, 0x8807f3a0, 0xe51a0d53, 0xb17b2842, 0x7ab24404, + 0xf9dd9f0a, 0x6fd57687, 0xf3e9df64, 0xcd1efdb4, 0x60df194d, + 0x5dd2df7a, 0xe069df05, 0xbed3f2c3, 0x23248a31, 0x469b7561, + 0x694744f7, 0x866949e1 }, + { 0x3f4ab07a, 0x3a9a0da5, 0xf54a6fbf, 0x2cd6f333, 0xb23cf290, + 0x0c92e921, 0x848e3d58, 0xc9581c3e, 0xd3b218ab, 0x93af1fbd, + 0x066cb4d7, 0x38598ea1, 0x990c03a0, 0x5001394e, 0x7d0877b5, + 0x3b664b1e, 0xd74c7091, 0xd79db1bb, 0x4e2d5dd0, 0x852d4435, + 0x3329db82, 0x0d2b841b, 0x7b96d480, 0xfa844eb0, 0xc295dc46, + 0x37a50569, 0x94f7ec4e, 0xc2d38373, 0x5b083177, 0xdc3884ff, + 0x8b1fa598, 0x574352b8 }, + { 0x0d5d7ce9, 0xed2193f7, 0x0b487eaf, 0x3c19fd26, 0x7be65fd0, + 0x7c44ab59, 0x78270d56, 0xdd9da860, 0xbaa70198, 0x8a84ec00, + 0x285985df, 0x2ec27e49, 0xde2028d8, 0x996ccaf0, 0x61c2201d, + 0x4e7648c7, 0x091c19eb, 0xa96335bc, 0xf0d6782b, 0x253a3a69, + 0xd2946493, 0x3f204340, 0x099f6873, 0x444521a1, 0x6996011a, + 0x5fcbcc09, 0xf853a94e, 0x3884d5d8, 0xd3b6a3a1, 0x2418c624, + 0x06ae3c4f, 0x3e431af2 }, + { 0x83d381f1, 0xf967d939, 0xd0c033c3, 0x36501aae, 0x54410768, + 0xbf3af4d0, 0x5093a6d3, 0xa86d1598, 0xd92f2900, 0x43ae0741, + 0x36f0b755, 0xfeb2afa6, 0xaa456d6f, 0xd090a6a3, 0xaefdb646, + 0x336a4fda, 0x1a942f7d, 0xfd1bfe44, 0x851ee41e, 0x7fc2a3ed, + 0x11e935c5, 0x4f1c9686, 0x53bbb343, 0xcd577666, 0xad896c2a, + 0xf26931ba, 0x86bbfa41, 0x8a0fbbd1, 0xa203cef1, 0x1c3d7d82, + 0xe2664d35, 0x6dad3f15 }, + { 0x12ec35a1, 0xd1940b7d, 0xe7dfb128, 0x6219c5b6, 0xf13321d5, + 0x2cc278c6, 0x33c58eb6, 0x5e76904a, 0xd9903c43, 0x15090f55, + 0xc3d96a19, 0x061bc926, 0x8c0acba7, 0x974a9f03, 0x7198b21b, + 0x7a414021, 0xf8958c6f, 0xb069599d, 0xbebd0129, 0x517f2f1d, + 0xdf3a8dc3, 0x1109a613, 0x672375c5, 0x08e58448, 0x9383d2d3, + 0x56590ba4, 0x0bff837c, 0xfc3ee7c6, 0x27d2d55f, 0xc87a5390, + 0x5f517a3f, 0x2438e9d4 }, + { 0x8815af3c, 0xc4a45308, 0xf3c9bed5, 0xe55f1a32, 0x97b65ddf, + 0xaef1cdc9, 0x12e51eb5, 0x61c61d94, 0xe63f2490, 0xbd0dac54, + 0xd0b3e231, 0x6f14429c, 0xf1da6010, 0xf737c3c2, 0x6bbc4fb1, + 0x7150e04b, 0x1be281cb, 0x205b4c89, 0xd7701f5b, 0xf1b4633c, + 0x2a513490, 0x8b33ef46, 0x68f1f7f2, 0xddb47c73, 0xbd416b67, + 0xf4ada511, 0xff795bb3, 0x9d2a97cd, 0x96200e67, 0x00a8b7b2, + 0xafe30e01, 0x13f39011 }, + { 0x7bd0c827, 0x3dd296ef, 0x4a29ff46, 0x506110f3, 0x1c9a515a, + 0xf8793068, 0x268bca77, 0xde8d8045, 0x998045df, 0xcbb83024, + 0x68c0e584, 0x3f90d710, 0x263b6062, 0x2a838ca8, 0x535c5d0b, + 0x293bb5e7, 0x56415110, 0xceea99d5, 0x1bbda005, 0xfe311ad0, + 0xa4d8d018, 0x2497e0bf, 0x1cf2b866, 0x33dd77a0, 0xd8c4ba8b, + 0xbc075b73, 0x722b7bc9, 0x298466d4, 0xcbda1b0b, 0x17a7ce24, + 0x680703b6, 0x458d4b6b }, + { 0x4d54d8b2, 0x8a26a20e, 0x4d320a0d, 0x05a5696e, 0xf994f700, + 0x698b5858, 0x2f6549a8, 0x7a4adc3c, 0x3694d00d, 0x1812e819, + 0x730402bd, 0x46b9b000, 0xa1b36410, 0xe10a1449, 0x99230220, + 0xeae95ea5, 0x1b4820c3, 0x3efc2e9b, 0x85c9eb8a, 0xfe5b5cb5, + 0x97847064, 0x21ae0319, 0x8f27d49f, 0x68ef0b70, 0x2f72556b, + 0x3259ef18, 0x624db01a, 0x00ae0457, 0x5668f95c, 0x628e3b06, + 0xb6fbbf91, 0x5f13f5fa }, + { 0x3a9b0dc6, 0x7c6ed9ae, 0x6f883ec8, 0xaea1bde9, 0xea8b3677, + 0xea66bf88, 0x9a66e3ab, 0xdefa6abc, 0x68217ffd, 0xc4d3317b, + 0x290df05c, 0xf741c8f2, 0x7d11674e, 0x1f0fdf17, 0xc35989ca, + 0xfdf0ece7, 0x6b9c482d, 0x0eed92df, 0x55bf1ca7, 0x73713e66, + 0x25cec99c, 0x90acb290, 0xe803e69c, 0x37c9e3a2, 0x17713a1a, + 0x7c0a3c53, 0x6f5a174d, 0x350dc565, 0x05f802f6, 0x11625a44, + 0xa37ba4a2, 0x2196495d }, + { 0x13142680, 0x00cb2fd3, 0x65d14cf4, 0xab9e91d7, 0xdfe2669e, + 0xc6a0ceab, 0x0ae22bc5, 0xbeefce58, 0xcb6ec250, 0x3c2b7986, + 0xd738f1ff, 0x84adb1a2, 0x516ec8ec, 0x9709bc28, 0x8e8f7db5, + 0xf3693129, 0x95b197f9, 0xc48efc6b, 0x9aaaa404, 0x9ff10952, + 0x144154b0, 0x2c3c8cbd, 0x427f3435, 0x33ef7bc3, 0xd21897c1, + 0x04a17940, 0x6ce548a0, 0x5aa0c47d, 0x3d56fa62, 0x2971cea7, + 0x04475f08, 0x93ad0eb0 }, + { 0x988a9963, 0x7a0b6967, 0x6515e8dd, 0x61e477f7, 0x3b6b50f2, + 0x6274e386, 0xd33922de, 0x63a9b8d5, 0x687a5b3d, 0x3c38d3fb, + 0x1302e323, 0x18f6f09c, 0xe02fcccf, 0x254c05c3, 0x26e662f7, + 0xc04ed0b7, 0x143fe079, 0x1d5646b8, 0xc9016c8c, 0xef8a9448, + 0xf823d797, 0xe5674c4b, 0xbccde451, 0x0586f72f, 0x4417eade, + 0xc5fc88d5, 0x576e588d, 0x2b952209, 0x5844d1f9, 0x4408dd42, + 0xea41c034, 0x73f8c3f0 }, + { 0x5df763dd, 0x89534fc8, 0x3ac71836, 0x3b1427f3, 0x6e8f15a0, + 0x0db5be17, 0xcb20888e, 0x1d390944, 0x857caea6, 0x7804c9ad, + 0x519f7bf3, 0xaa584428, 0x293aa8cf, 0x626eecf1, 0xea36a015, + 0x749e0d98, 0x3321edcd, 0xefff6dae, 0x28b791cc, 0x963deea6, + 0x2d16e361, 0xa14e0552, 0xb15ae206, 0xa2e058fc, 0xfca325e4, + 0x0f268745, 0x21341a8a, 0x7cf9d407, 0x7caa51b8, 0xdfed25d9, + 0xadbedd75, 0x0108ae39 }, + { 0xa9e88f63, 0x54d178f3, 0xab0c7325, 0xaa05b11e, 0xe261d8a6, + 0x773a53e6, 0x8d0b91c8, 0x24db7dae, 0xe9bb004d, 0xde10b073, + 0x54e3090b, 0xfc8befe7, 0x0cc69c89, 0x16af0599, 0x9d59511a, + 0xddc83803, 0x46c5dafc, 0xc3f65b99, 0x1ee0a599, 0xfbbe4be8, + 0xfb3a9b17, 0x88891e36, 0x445dad00, 0x0c9aad75, 0xd5097e1f, + 0xdffc46ab, 0xac85a4e1, 0x8848089b, 0xa0c45233, 0x348bb42f, + 0xeb13c1df, 0x807c06d8 }, + { 0x98ee0ef6, 0x00a969ec, 0x8bb7b7af, 0xba9d5483, 0xa02f8fdb, + 0x24484c92, 0x8b70557c, 0x7bdb201a, 0x60ad1af2, 0xe59343e4, + 0x998c95fb, 0x53a9a942, 0xda861d3b, 0x974db3de, 0xed399c0e, + 0xce1525c9, 0xf72109bd, 0x89b56881, 0x998211a4, 0x08ff7d15, + 0xef0f275a, 0x5df76b3a, 0xfa2f358b, 0x93f180f7, 0xc39b0634, + 0xaac4ffcf, 0x17583b53, 0x2692c626, 0xb55399fc, 0xb2fdfa36, + 0x99607a61, 0x16424c6c }, + { 0xdd2744a9, 0x5dd65c55, 0xfe3af418, 0x2544c1c2, 0xefe8b089, + 0x32c82e99, 0xa9df691a, 0x30b7ab25, 0x9be99674, 0x98384550, + 0xcaf2d122, 0xbcecd258, 0xbcc77272, 0x88ae4098, 0x4b8efa0c, + 0xd4396141, 0xed64d12c, 0x44ff67b9, 0x2e7f3404, 0xa9e655e4, + 0x45b0e9eb, 0x3d16fc45, 0xf03ded28, 0x474a3e14, 0xacccb85c, + 0xa3c9adff, 0x7253a51b, 0x3dfe6bc1, 0xfb5831b1, 0xdddaf4b9, + 0xa4f4478a, 0x5544e602 }, + { 0xbaa80b4f, 0x897c5313, 0x63bdc8ef, 0x0122716f, 0x7b42c5a8, + 0xae2742db, 0x0883308c, 0xe9d9e1e9, 0x2d341ab1, 0x352c8c3f, + 0xed945870, 0x163d0500, 0xc290d9d8, 0x8349dd73, 0x1f6c7d29, + 0x2053c5e0, 0xcb42033c, 0x83107446, 0x09d09af1, 0x76c88bd2, + 0xb2794681, 0xd0f70e6e, 0x19b1b540, 0x720b59de, 0x22994b43, + 0x80b7ecdc, 0x2dec53cf, 0xc1a4cdce, 0x1ed60f42, 0xdd7d3edd, + 0xe241d261, 0x5735995c }, + { 0xa0237056, 0xdc4ba3fb, 0x33ab3388, 0x6856c164, 0x271ec612, + 0xc01eebbd, 0xe3031bec, 0xabdeb033, 0x6118a1f5, 0x4eee4419, + 0x5b600f33, 0xec497421, 0x08868773, 0x1b7185cf, 0x7c1b7dfd, + 0x7b0c46cd, 0x4a4c5e89, 0xd143b2da, 0xbb1ff94d, 0xdb9a5984, + 0xc9cf3465, 0xac3904e4, 0xeace64c9, 0xf8729bc0, 0x768ad99a, + 0x5cc22821, 0x8a9540c2, 0xbbd3b081, 0x049a6917, 0xe468ed5f, + 0x3ec45ef0, 0x885486df }, + { 0x4bdff464, 0x6a942c93, 0x25a7b451, 0x3db2719f, 0x325be324, + 0xccb0070b, 0x19fe3339, 0x2055a31b, 0x241ee8ff, 0xaca69ae8, + 0x55ef8def, 0x7607dd08, 0x1a1b73c6, 0x9e24960f, 0x71d36810, + 0xbcb0e8a2, 0x6885e6b9, 0x29e11aa2, 0x185eae19, 0x98b5d0ab, + 0x0f81f91c, 0x1a0b96e4, 0x994fc503, 0x4d0e8bcf, 0xf119d6e0, + 0x33d81697, 0xaaa4ce0c, 0x29083287, 0xc91ff9d7, 0xc5dd4d3e, + 0xd4ab962d, 0x31cecfe8 }, + { 0xfc8b21e8, 0x437bfd9a, 0xb19436df, 0xe5dd32b3, 0x921c36a0, + 0xfe5902d4, 0xa3d0fa90, 0x8e9de84d, 0x5bb523bd, 0x9663e6ad, + 0xaecd6975, 0x9800a23f, 0xb4fbb59c, 0x1009c0d9, 0xc9d20ff1, + 0x839aa7bd, 0xecd6fa3d, 0xf502f66d, 0xc5516ca9, 0x480ed4fb, + 0x6c742ac4, 0x65ffa5f6, 0xff3252f8, 0x2b7c7945, 0x75d9cb3d, + 0x72fefc05, 0xd6d6f1d2, 0x11b0863b, 0x9a6a4ec3, 0x5d8f3cf0, + 0xda2547b3, 0x6961b46a }, + { 0xcb35e2ac, 0xd07b587e, 0x57af14d9, 0x1ed5546b, 0xdb28a04c, + 0xeca17a5b, 0x709d54f0, 0xa1f91d44, 0x9c6f400e, 0xa6e719fd, + 0xfb8ce190, 0x4e4b88ed, 0x246e3fd2, 0xf9781edd, 0xb655af5d, + 0xd67120e6, 0x93413ca7, 0xda782d1d, 0x9707fa21, 0x697e20a2, + 0x54e84123, 0x1eb51f32, 0x36051f9f, 0x2e254d9e, 0x73ce5be9, + 0xddaec42b, 0xcd3f794f, 0x89a9a32e, 0x0781aad9, 0x1964e22f, + 0x53755212, 0x6a63a90c }, + { 0x3d7acbbb, 0x76554e00, 0xb74f6108, 0x2c01668a, 0x388c519b, + 0xe4a29672, 0x3eb94d4f, 0x01667714, 0x0cd6d2f6, 0x086a3cdf, + 0x7b370f7f, 0xf8658021, 0x5a4d3e7c, 0x658880c1, 0x5ba3f4a1, + 0xd6ed5816, 0x5ca471dd, 0xabcc7813, 0xe844a576, 0x809bf074, + 0x6ea502ea, 0xa53a81b3, 0x0e021ed3, 0xc20b9307, 0x8617f165, + 0x8c27f892, 0x8235cd0b, 0xa5476446, 0x82552961, 0xffc89ffd, + 0xd151d90e, 0x51ed4a22 }, + { 0x449701b4, 0x37d6963a, 0xbb27caf2, 0xea8d91a3, 0xb572965f, + 0x3ef9be15, 0xdb50bf7d, 0x75a7a055, 0xce643b9b, 0xfd67480e, + 0x6ceb5d5e, 0xf2a60d2d, 0x5ed7c897, 0x68fc320c, 0x28ce685f, + 0x41c53cf6, 0x7106615e, 0x0e29711f, 0x23500ecc, 0x7a872138, + 0x6c29fe48, 0xaf0a9260, 0xe1ef9712, 0x93df3f2a, 0xd2d169bf, + 0x0d5f6fb1, 0x74a9793c, 0xeb7afe26, 0xe9f49256, 0x4173d94a, + 0x2b8b5ce5, 0x2d6951bc }, + { 0x904e222e, 0xdd007d9f, 0x86f4e109, 0x333f248f, 0x8f429eee, + 0xd4994e8b, 0xcfc77518, 0x29573415, 0x0b0f42f1, 0x6e7fea3a, + 0xc2743519, 0xc795cb7d, 0x711e71a0, 0x820a8f66, 0x2b874f55, + 0x83d95d9c, 0xe70e1627, 0xd4b64d78, 0x8b92a742, 0x924353f5, + 0x447b5e6d, 0x322048b1, 0xbcf931a0, 0x0bad730c, 0xa7af2268, + 0x75c4d089, 0xb83b93f9, 0x464904c1, 0x165b3aee, 0xa24eba02, + 0xe08cc5f0, 0x65c48e78 }, + { 0xde222c22, 0x1a1c73ce, 0xfcea23b4, 0x5683d8cd, 0xb2143b06, + 0x0301cb14, 0x59fcec77, 0x284adf8f, 0x31204cef, 0xfb1c581c, + 0x94735107, 0xf54d3eee, 0x4d3188c0, 0xdbf67f0b, 0x10f18d12, + 0x76a3f2d1, 0x07d3e013, 0x3809fa28, 0x25e7ece0, 0xf06f0a46, + 0xb2895d2e, 0xd82867ed, 0x08b0553a, 0xe106f489, 0xef245445, + 0xe2280fa6, 0xa8d9a3cb, 0x402d5785, 0xd438ba2d, 0xf63dd9ff, + 0x7a6b226f, 0x36b5cd2c }, + { 0x545679a7, 0x87ff4e20, 0x4520c750, 0x64d80b41, 0x9b459cd8, + 0x90a357fa, 0xc85af1a3, 0xa19eaf39, 0x8d935a5e, 0x0d475d79, + 0x781a678a, 0x74501983, 0x0cc2e810, 0x74839779, 0x2f412244, + 0xc6a21d11, 0x36a51a37, 0x8d0e85f9, 0xeaa74df8, 0xff50151e, + 0x93cf99c4, 0x14e182a7, 0x376a9ab6, 0x45593df1, 0x522389ff, + 0x18f73caf, 0xf7445e8a, 0xd27cc960, 0x39a51dc8, 0x0692f4c5, + 0xdb39bfd8, 0x08d7c144 }, + { 0x3ecca773, 0x809c0d96, 0xd48c2156, 0x87ea9192, 0xdb6bd641, + 0xf0eccd74, 0x2a678cdf, 0x77312374, 0xd1587b7e, 0x7a966d8b, + 0x6130a4c6, 0xf3c1a101, 0x5fce17bd, 0x7cc6e838, 0xa8de7aa4, + 0x95e95bb8, 0x898308e3, 0x3fe1e8b5, 0xe347694a, 0x0197243e, + 0xbb0cd2bf, 0xf3fe9c42, 0x0f9b2b49, 0xb5905264, 0xc7367d1f, + 0x4c385e8b, 0xb5ee147b, 0x1d3050ae, 0x04004ad9, 0x8e2c3879, + 0xbab70202, 0x5f2aa8ee }, + { 0x1266524b, 0xe208d464, 0xd0a19f66, 0xb7bf3880, 0xda106ebf, + 0xa5aa685e, 0xe642dd46, 0x0a69e8d3, 0xc682e4d6, 0xef349c61, + 0x0fcb534c, 0x26f6ee3b, 0x05eb67b8, 0x7daba127, 0x18be05f6, + 0x2babb27e, 0x8e2d85d1, 0x959afcba, 0xe2d9d386, 0xedcf2d1a, + 0x1ea6f06e, 0x59dc52e6, 0x866e5ae8, 0xc28278b4, 0x02bcd3c7, + 0xd9ff0340, 0x784be82f, 0xe884ac76, 0x83c9f224, 0xa3164980, + 0xb46ff949, 0x62501a98 }, + { 0xad264086, 0x563f7d9a, 0xa5e0e4bd, 0xca6a33db, 0x8c8d3d67, + 0xe8253002, 0x46e64b19, 0xa288dac8, 0x20aa4536, 0xfa3c9197, + 0xed553eac, 0x8130c9b0, 0x2ea8abd3, 0x622806e0, 0xceccfe77, + 0x52fbf54d, 0x4f0d1b70, 0xbd9a8e31, 0xd59b1741, 0x519d2133, + 0x9a6fea8a, 0xfd74101c, 0xb5c4eb10, 0xd1acf7a0, 0x91f9da5e, + 0x78499b73, 0xc0dea586, 0xabaa4c49, 0xa1f3531a, 0xcc9c5f73, + 0xfd3fc665, 0x497b15fe }, + { 0xf45568e9, 0x8a56cbaa, 0xc7192a6f, 0xf491a0fe, 0x9ab2539a, + 0xdbb03dd3, 0x4ac37da9, 0xc86522f8, 0x02a0f5b4, 0x8c8cdba2, + 0xa29c539f, 0x8109fc75, 0xca90f02e, 0x9cd06d31, 0x3e216dbf, + 0x8f31f044, 0xba3ebd91, 0x99aa68ac, 0x42c007f4, 0x2a80d0d2, + 0x86a9b7ce, 0xdd8dffbf, 0xd6308edc, 0x405d3e84, 0x068012ca, + 0xdafa33fe, 0xedea1071, 0xc2eebd13, 0x2ff637e6, 0xb7ae7e5c, + 0x9e514cb7, 0x18d46a6c }, + { 0xa78b7802, 0x868cbb22, 0x497cbaf4, 0x0745ddb2, 0x42ae8add, + 0xc4eb2f3e, 0xb4ceb4e4, 0xac0abcda, 0xa325fd40, 0x2e0d8325, + 0x13ac7345, 0x6cfe0571, 0xb14171b9, 0x7407a788, 0x6da7a52b, + 0x70eb0603, 0xd85176ac, 0xab0b36f9, 0x7c2954f3, 0x14109d29, + 0xdcd705ad, 0x370de9c8, 0x7bb5e751, 0x3f0db5cd, 0xa06e708c, + 0x45f93d41, 0x7e93050d, 0x10d54f8a, 0x5a38fef9, 0x69e6f8e4, + 0xd3f62e40, 0x55044601 }, + { 0x06cb9cc9, 0xd1c5c910, 0x41d00014, 0x542074d7, 0x11236fb8, + 0x7cd8663e, 0x29ad5f82, 0x39721ffe, 0x2951fc83, 0x1d21fbfa, + 0x400d144f, 0x1cde06e7, 0x91792e6b, 0x9042596b, 0x29ad5166, + 0x3365c8e5, 0x9aeefe98, 0xe2220e85, 0x70c2aee3, 0xbcb53189, + 0x9ff100bc, 0x477ca3db, 0xf532973f, 0x27074176, 0x9a2bd01b, + 0xa12118ac, 0x3dd79f93, 0xf3425209, 0xc6f5d7db, 0x563a8ff7, + 0xd7b0ec4f, 0x0da313fc }, + { 0x15aa2557, 0x37125a8c, 0x00893e9c, 0xca21d70c, 0x67b8a823, + 0x48713994, 0x7cb0042a, 0x0d3e9a74, 0xc9e2ce18, 0x2d2bf4ff, + 0x049aeac2, 0xd5531a0d, 0xf03d0660, 0x4d29a616, 0x1f1b7f00, + 0x473d50d6, 0xca3de50c, 0x3af0ecbb, 0x09c28f27, 0xe2959bea, + 0xf8704664, 0x6d7c2ea0, 0x731083ef, 0xadfae4e1, 0x941c2554, + 0x50940c26, 0xa1162d03, 0x44167410, 0x1e82290e, 0x620230d8, + 0xdb414acc, 0x63630be8 }, + { 0x8a7d2e41, 0xbf8d5222, 0xeb62f879, 0x49e75823, 0x6c402d89, + 0x1b4d33dd, 0xde2c59ad, 0x883e04d6, 0x49b9dc38, 0xbf3f38f4, + 0xb4b70c4c, 0x9d997d18, 0x13cea045, 0x1f69b20c, 0x58e2606d, + 0xca3d7025, 0x261d1b79, 0x3d4fd977, 0x5a1436fa, 0x56aeafa8, + 0xbb443c07, 0x369b3e98, 0xe558f6be, 0xfce5186c, 0xf8ac8f89, + 0xeb0cd478, 0xd5e5aa72, 0x68074f37, 0x68544eb0, 0x295845c0, + 0xf16688ed, 0x306a9871 }, + { 0x634ec136, 0xbc451e9d, 0x0e6f658f, 0x1edf27ca, 0xc0db4120, + 0xa9be0152, 0xc5bfee67, 0x87b6ef20, 0x9a2d6023, 0x35283238, + 0xc7afb899, 0x60e564d8, 0x0ac9c2de, 0x4af22bc0, 0x82a9d22b, + 0x28e6f631, 0xf532701b, 0xc075c701, 0x82075f91, 0xf6d418f8, + 0x1beaa511, 0xf9fa628d, 0x6e72a13d, 0x551e7a17, 0x77f4c01c, + 0x9306215b, 0x93c9d588, 0x71aba731, 0x58e57cd4, 0x6443ebe0, + 0xe8103e37, 0x2833ac41 }, + { 0x8da5ec5c, 0x7e564b86, 0x1c08db24, 0xac3d9da8, 0x8c57a728, + 0x9d7c1f0b, 0x9d343dc2, 0x3512afe7, 0xfdc60339, 0xb438e4cf, + 0xdcfa1941, 0x7d5a2700, 0x27320449, 0xd5f323f8, 0x1393c6e6, + 0x1b87a58e, 0x04baa431, 0xecb68bd1, 0x4722b4d7, 0xc09c1c5a, + 0x206b5faa, 0xf42faa97, 0x9976327e, 0xe1dcbcd6, 0x087787d9, + 0x655ba9e4, 0xde5c0191, 0xbd59c757, 0x0bcf3538, 0x673020ed, + 0xa49d6303, 0x120cd454 }, + { 0xcab0f9ee, 0xebfdb8f4, 0x2cce58ee, 0xbc003ef0, 0x5a8d0665, + 0x9b6a6841, 0x9b957774, 0x642ed3a6, 0x4721ab5c, 0x3de487f0, + 0x21a4f0d3, 0xef2ff380, 0x29dbddcd, 0xbd16f558, 0x0e93dff2, + 0x2ef05b4b, 0x0bc9aec1, 0xde1faa12, 0xd467fa92, 0x66dae2c2, + 0x5eb33e34, 0x758daf64, 0x8f0103cb, 0xa67ad9f6, 0x9be02430, + 0x151f693a, 0xeb4054bc, 0xd5698496, 0x7019336e, 0x8ef1677e, + 0x7fdeea3e, 0x021cfd16 }, + { 0xdf5c36f3, 0x5c73715f, 0xd64ad254, 0x703bde37, 0xf2cf7713, + 0x55368d10, 0x0f3993c8, 0x1e5ec7b7, 0x304ae4ca, 0xfdb16776, + 0x3d3bb18b, 0x0d8f717e, 0x66343d5a, 0x5267073f, 0x156008b5, + 0xfaeb52ef, 0x224a470f, 0xb97ad5f9, 0xed2ab51a, 0xaf86e391, + 0x9974302c, 0xdc0c7e57, 0xfd0ae28a, 0xc88fa817, 0xbf8ed59c, + 0x807c22df, 0xeb128bb6, 0x5dedc231, 0xa20595a3, 0x71edcd9c, + 0xc73cf78e, 0x07265b46 }, + { 0xbd66232f, 0x73dd99f0, 0xc4027716, 0xc59aaf89, 0x5b860fc4, + 0xaf826dfa, 0x7a943f3b, 0x239ea8aa, 0x523c428d, 0x0e0e1b1a, + 0x6973b95a, 0x55ea0e3a, 0x2557753b, 0xea399caa, 0x06957b1f, + 0xf8adf72f, 0x3bd34302, 0x0389f341, 0xf8a43a97, 0x333f27d0, + 0xadaf796f, 0xcd9c0c08, 0x49c12aa2, 0x6dcca49b, 0x7a0ac6e9, + 0xdd88deee, 0x0644080e, 0x8f47575d, 0x0cc2f4bd, 0x6e9d667d, + 0x31d1496c, 0x36c5754b }, + { 0xf323d84b, 0x9120046e, 0x7e789c4f, 0xa6991122, 0x921b8055, + 0x4b0eaf4e, 0x8079974e, 0x6339844a, 0x740f8c79, 0xc905466a, + 0xcd6def49, 0x1c18d0f7, 0x4b23e4ba, 0x5297da6b, 0xc41800c5, + 0x1c09dff3, 0x37ef6777, 0x6c49075b, 0x50513ded, 0xa94c3a40, + 0x6b0b1705, 0x3d6742e9, 0xc48af5ae, 0xc0784494, 0xc95822de, + 0x40c01532, 0xc164d94f, 0xa2ddade5, 0xa2975eb5, 0xfc8a8ac9, + 0x1946944e, 0x06fbf861 }, + { 0x3f45aa97, 0x2d65338e, 0x1d040feb, 0xd83b58c8, 0x0fdef8b9, + 0x05fef59b, 0xe4d7417c, 0x7beb071a, 0xb30a1a23, 0x982b61f5, + 0xfb65bd03, 0x4c5f2a2a, 0x5cbf6bf3, 0xe40abc9d, 0xf06612a5, + 0x422c326d, 0x9571ae28, 0xc921e69d, 0x23d3434e, 0x7c88b10b, + 0x9da07933, 0x96d2e957, 0x3619cf4d, 0x833d46a1, 0xd95eefa1, + 0xd9d19653, 0xa03e8f0e, 0x2a7d8411, 0x04bb5ab1, 0x5e642953, + 0x1f0fa9ea, 0x5e9ca0fd }, + { 0x197c5dc4, 0x5bd54571, 0xe78a95a2, 0xe2da40bf, 0xffdb0eb2, + 0x65fb9efc, 0x0d17467c, 0xe952dc2c, 0xc758c6a3, 0xc1fc9c7b, + 0xd4034a9a, 0xfc79562c, 0x61f64b56, 0x26e36fbe, 0x1e84728b, + 0x6adc4b9e, 0xa8f9ac8a, 0x7f165fd3, 0x03e3e013, 0x7bc93a45, + 0x656478e3, 0xeacc5513, 0x064ddc77, 0xd3391717, 0x76936914, + 0x75b318dc, 0x362424a6, 0x69b1f1c7, 0x49955f34, 0x8cc2045b, + 0xc6836af8, 0x940622b3 }, + { 0x0d997973, 0x4710ccb7, 0xd3f8f115, 0x3b29625d, 0x5b97abd5, + 0x8cf0c4d5, 0x673e14a5, 0xc6321e0a, 0x3d262246, 0x0541af9d, + 0x6fc83b11, 0xde6d8754, 0xf01652a4, 0x47e97da8, 0xad9802b6, + 0x0f82b3a6, 0xae9c44b2, 0x69aa4075, 0xced2bf77, 0xaf3f5de2, + 0x497a40da, 0x1ef1ea8a, 0x3c23ba9c, 0x2e0f8608, 0xf190a2c8, + 0xd8a998a4, 0xcfde3368, 0xe2b49c8c, 0xbde6bd71, 0xb9f49824, + 0x785bedb6, 0x80bb1664 }, + { 0xfd145cb5, 0x05e575fe, 0xac5e6883, 0x155ee561, 0x8793b273, + 0x461e70cf, 0x133b2338, 0x9f1553de, 0xa2a7ba07, 0x2fb9e0c3, + 0x3e7086fa, 0xc3bfd6a8, 0x8bb4cb93, 0xb6ba8500, 0x76f82dbd, + 0x0b66d789, 0x54eb49ff, 0x7d5a6ff6, 0x1f20b322, 0xcd65d237, + 0x54e29cdc, 0x79ea49c2, 0xcb118ff9, 0x64975963, 0xcc58000b, + 0x969598dd, 0x110c779c, 0x95107918, 0x63b85a35, 0xedfc1548, + 0x41212350, 0x077ba5ea }, + { 0xcdd86f61, 0x0b3a38d3, 0x0502a0ab, 0x43121445, 0x806d0272, + 0x1912edc5, 0x8a32f10f, 0x01dc1f98, 0x0e80c760, 0xbb1d31d1, + 0xf464e8b3, 0xd46ec7e5, 0x9abf49ee, 0xd569af36, 0x2cdade77, + 0x9d286ea7, 0x45ad5920, 0x2be7020d, 0x6299ae7f, 0xabe5236e, + 0xd3f55c07, 0xc93179bd, 0x52350e80, 0x8138995a, 0xaff07586, + 0x0901265c, 0xf4739653, 0x5b3c81b2, 0x9bc77d21, 0xbaf7581d, + 0x4591a2e2, 0x6b2006df }, + { 0x965b1bc1, 0xb2fe50a8, 0x962bb4fd, 0x931f536a, 0x000e7f99, + 0xd5718d33, 0x53d5125e, 0x84728f25, 0xd2125caf, 0x4f8a6184, + 0x357f679e, 0x54f1a701, 0x1531c05a, 0x70a9f40c, 0x6fa8b775, + 0x10d0cb97, 0x9dc12ce9, 0xb476f41e, 0x2755f894, 0x5c8d7a75, + 0x625741a4, 0xd6c12e10, 0xc917b16c, 0x262a6fb8, 0x38d6b0a0, + 0x24d116e6, 0x32c38e83, 0x849540c0, 0x66868afc, 0x855b911c, + 0xbd26b550, 0x53217ea6 }, + { 0x259f52b4, 0xfc840473, 0xe621146c, 0x968da9cb, 0xcacbd26e, + 0x964eb85e, 0xe4a54344, 0xab7daa2d, 0x381a4ff7, 0x6dc3b848, + 0x41c815ef, 0xa07a96b3, 0xc3d4b1e1, 0xc4fae9e8, 0x42ce9ea8, + 0x0f938d1e, 0x35cc052f, 0xa727dacc, 0xe9a06f07, 0xc81e01c9, + 0x4a6d65a1, 0xa9e08dcb, 0x6044a9a6, 0xf8e2d173, 0xf2bd295b, + 0x99893dd0, 0xf9781b12, 0xa08d3379, 0x61830ac2, 0x64bd6001, + 0xd9adbeef, 0x0386931e }, + { 0xd09885a5, 0xd0d7abb3, 0xe355bb07, 0xed9d2b67, 0x536ebaed, + 0x3bc238cf, 0x699ce4d6, 0x61ca2e78, 0x111594cd, 0x354ff447, + 0x03316ad2, 0x55cbe709, 0x49fff5c4, 0x418679fd, 0x0f9c6c40, + 0x75bacd75, 0x2972721a, 0x677edc88, 0xe5ef502f, 0x82596887, + 0xbf320e0e, 0x459e9367, 0x8bbdccb2, 0x81ce36ef, 0xb766863d, + 0x1ba097fc, 0xd58c6db8, 0xcd3a21d6, 0xb4a8748b, 0x0e4967cd, + 0x15041c20, 0x2caaf749 }, + { 0x6ed20424, 0x44f98006, 0x22471545, 0xb3e4ea23, 0x781a8c86, + 0x268ed1a5, 0x7ae5b70b, 0x48d0ab75, 0x356d3982, 0x6ca8b320, + 0x2df31fa4, 0x9ce8e681, 0xd925dcf2, 0xb909d232, 0xf56723de, + 0x302c8f78, 0xabac96f9, 0x11725d69, 0x57d1a170, 0x656a47ca, + 0xc18a2be7, 0x6bb5d511, 0xad50d9d9, 0xb56e45f1, 0x70b05518, + 0x36e886e2, 0x09d8ff91, 0xc7c71f3d, 0x9350361e, 0x65a1bbe2, + 0x45fe3bd8, 0x86d7f532 }, + { 0xb0bf719a, 0x99f16eb6, 0x8bc3d913, 0xb6975098, 0x26cd01b4, + 0xfae50e52, 0x90898d1c, 0xd3e3ac54, 0x887ec666, 0x4da3b9db, + 0xfbea45b8, 0x58300644, 0x8355b058, 0x369f3bd9, 0x579bcc13, + 0x0fb239a8, 0x6e2bd811, 0x4f5b4539, 0x24198fd2, 0x007f3baf, + 0x8837d51d, 0x68a676db, 0xeae75b16, 0x68eeea62, 0x3db6083c, + 0x5ffe5f94, 0x7d836c5a, 0x52c94d0f, 0xcbc1ff85, 0x5a4c3c6f, + 0x86c0b4dd, 0x682a55e3 }, + { 0x587495aa, 0xc8f235a4, 0x34c7245d, 0x2276026c, 0xb75a46e3, + 0xd6ae0cc5, 0xecc3e5e7, 0x890d3965, 0x14296629, 0x1b13342f, + 0x8a877227, 0xc89927e6, 0x2324a68b, 0x1543f27e, 0x49cdc21a, + 0x6c447684, 0x1452d0ac, 0x9bc7fd4f, 0xff4b045c, 0x2cc30a31, + 0x852f7611, 0x415d46a0, 0xc6fdd7a6, 0xad737052, 0x7b4c7c91, + 0xdcecc3ab, 0x7688d70c, 0xd2cdf01b, 0xe40d3905, 0x054f2542, + 0xfefe4dcd, 0x02227fa6 }, + { 0xb751948b, 0x1805efd9, 0xfdfd225d, 0x8efeed46, 0x4f2c8b22, + 0xcb128e09, 0x96f7c5e5, 0x9d1090bf, 0xb4cbeca0, 0x0959d044, + 0x8e08cb04, 0x21c955f9, 0x68fa4fce, 0xbc1f279d, 0x0710ae9a, + 0xb021e14e, 0x881167f4, 0x64d16e9f, 0xbbc9f1a5, 0xf5a5c22e, + 0xe3420eea, 0x5f3716df, 0xd5c4e843, 0x971eb915, 0x28ffba81, + 0x64fc55fc, 0x7dd37578, 0x3427e54d, 0x15ebc7d0, 0x446e6a62, + 0x29269778, 0x547e249a }, + { 0xa1ffda27, 0x4706868a, 0x7955cf50, 0xb4e6cdcc, 0x0a63f3d8, + 0xf65151e1, 0x9de5e70a, 0x5b4127ea, 0xf9342823, 0x3d2c09ba, + 0xaa2f7d51, 0x18c99d83, 0xddeec025, 0xa0c5bb1d, 0x03dcf1ce, + 0x7ffddf84, 0x616fdeda, 0xe57e4d29, 0x7932a1f0, 0xd2456569, + 0x3191d4e3, 0x7475e0e8, 0xc220218b, 0x3479bea1, 0x8bcb2505, + 0xfceb5c90, 0x3c6132e6, 0x1c685cea, 0xbfe6c1eb, 0xc42dc745, + 0xd2b08eea, 0x45a41cc0 }, + { 0x4dbbf0e1, 0x3ea9b2c7, 0xa17cf70e, 0x41ff962f, 0x5eeb4c66, + 0xdc1ea758, 0xa9beb17e, 0x4f5412d2, 0xa285741a, 0x2c9e4f52, + 0x984fd11f, 0x93df7da4, 0x0df3184e, 0xb2afbddc, 0x2421e375, + 0x96323d25, 0x49df781e, 0xc87be1e4, 0x3d589bea, 0x145601ed, + 0x28fff6dd, 0x0f0bd9bd, 0x8a0f298c, 0x2d3259d4, 0xd88e6944, + 0x362d7a77, 0xb6ac2af6, 0xa84c06b6, 0xd087da02, 0xba850ac9, + 0x42ee40c8, 0x128763c9 }, + { 0xacbac178, 0x29a80f07, 0x34b08f6e, 0x7cc20044, 0x70feded2, + 0xe9631d14, 0x86615767, 0xb2115da3, 0xcb088548, 0x7c75f5c4, + 0x9a2e8e03, 0x5b29d213, 0x8b881752, 0xfe9fda66, 0xc1de7ebc, + 0x3f1d8d88, 0x03218123, 0xb476565e, 0xb1c995f3, 0x07365561, + 0xb13eb71b, 0x2160cb18, 0x99b3a0eb, 0x7e8da513, 0xb20fcd74, + 0x5e8ca1f9, 0xb4126d72, 0x6a7e0067, 0x68bb637f, 0x1e8204b7, + 0xfc4f74d2, 0x75e96bcc }, + { 0x0d19716e, 0x189d1fdc, 0x7c384525, 0xdf585058, 0xea987d2a, + 0x64a846d1, 0x6c07150f, 0x12b6bf83, 0x4d6fd5b7, 0x91d85d46, + 0x4f53f55f, 0xa9788836, 0x81509129, 0x60083bd8, 0xea876f48, + 0xa7672683, 0xc15b2489, 0xe80b2e7a, 0x42d1d992, 0x985ef8d2, + 0xcf3de492, 0x9c57b029, 0xb1487627, 0xfe02f83c, 0x8ae5b687, + 0xaeba4fe4, 0x5d6b8196, 0x8a86f09b, 0xa16e523d, 0xd88f566b, + 0xba268949, 0x309a6e9a }, + { 0xbdfbe97a, 0xef27ee50, 0xb8c50c4d, 0x1a5fe70f, 0x7fe09f5c, + 0xcc7beb01, 0xbed36cc5, 0x8fa15a85, 0x7550ed3a, 0xc0c3acdb, + 0xeb908681, 0xc581ef87, 0xc49d5ccb, 0xa15b3362, 0x1fa264e8, + 0x0fbb1714, 0x8e1eee88, 0x267f8d8f, 0x21c2b63d, 0xd31ccfd6, + 0x53be7efd, 0x924dbe7d, 0xdb2a358a, 0xd42e877f, 0x75d68ac1, + 0xcf9673c7, 0x714fea55, 0xe35978fd, 0x5769b202, 0xeeb36653, + 0xd7593789, 0x0458258a }, + { 0xa042dbdf, 0x5df71a74, 0x5779dfa2, 0x2d405857, 0x0d2e6657, + 0x0e66cba7, 0xca2e892e, 0x285d6745, 0x0f0e6b5f, 0xf56a8def, + 0xa30767c3, 0xe0ee851d, 0x43346b9c, 0x98c05658, 0xd6b3c742, + 0xb35fce26, 0x39777e00, 0xc0895bff, 0xe7b6d886, 0x83c8f6a6, + 0x4f02904b, 0xbee14843, 0x2e84ec34, 0x7f74915b, 0x96d10991, + 0xbaaf663c, 0xe41facc0, 0x004b8757, 0x6f86c029, 0xa2b880e5, + 0x95b77358, 0x53f4a3e0 }, + { 0x89fc48e7, 0x11bb08ce, 0xafab5aeb, 0xba60c577, 0xa0c1cb5a, + 0xf06bcbf8, 0x79757cb6, 0x7d2efaea, 0x76319160, 0xe26d90b1, + 0x2b77b7a9, 0x42aa1ab6, 0x285df2bf, 0x38eec0cd, 0xf3a8f7f0, + 0xd35947f5, 0xfc1cb5b5, 0x97c8dc0e, 0xc45845cf, 0xfeb8cca0, + 0x249e26f2, 0x16e8d989, 0x483ed89a, 0x7c264e6d, 0x51d91073, + 0x13a3f145, 0x305e99f0, 0x8501562e, 0x6908d563, 0xaaf98d74, + 0xd723d236, 0x0a99e653 }, + { 0xabbc0559, 0x23536f46, 0x9aa1a160, 0xc163067b, 0x0c1681b5, + 0x229fd229, 0x1378e907, 0x61254be1, 0xab793a2d, 0xc60ff57a, + 0x466552db, 0xa6f2df8b, 0x8c170a36, 0x9ad31893, 0x29b74d9a, + 0xc5cd9abe, 0xf7848523, 0xcf747273, 0x0d0e3063, 0xc126a93a, + 0x4248e3d8, 0xfe2021e3, 0x8323ddfa, 0xd97343ee, 0x332639e7, + 0x9f768775, 0x75325548, 0x9650fc31, 0x3eebf7ea, 0xb595dbd1, + 0x010fcbc0, 0x3a95cb45 }, + { 0x39d7ff2e, 0x954e68cb, 0xc1d5c48f, 0x8dd1cb4b, 0x7169438a, + 0x02a92c77, 0x91cad8ce, 0x7965c0b0, 0x32cd08d2, 0x0c5798ab, + 0xa6902bda, 0x1a5bc3c3, 0x5186d218, 0x545d0925, 0xd27e64db, + 0xf0077cdb, 0x8cd092da, 0x0157caa4, 0x24532ab3, 0x2a2fa3a0, + 0x41ccaba3, 0xa5fb639b, 0x4744aee6, 0x01702dc1, 0xcdba93da, + 0x485bb436, 0x329784f1, 0x93597f66, 0xdad672c3, 0x5d713c1d, + 0x030b7245, 0x366d222e }, + { 0x573ea5b2, 0xd50b4875, 0xa90da44d, 0x0fce401b, 0x7a1a0310, + 0x7b53fa65, 0xcf114460, 0x722a80a5, 0xa538bf49, 0x0b8ebf05, + 0xd32acd21, 0xae141147, 0x7b5ad07d, 0x6692712c, 0x3f48ca07, + 0x6dc5fee7, 0x2b8a78d8, 0x98ed1499, 0xdd2f1759, 0x4e8b3145, + 0x5f971b8e, 0x43408de1, 0xadf1b368, 0x055ea6dd, 0xe5932b7e, + 0x4bb76e73, 0xd30893fd, 0x44287153, 0x0661bfda, 0x173dccd2, + 0x79defd25, 0x9072ba99 }, + { 0x9620ea39, 0x474de4dd, 0xc831cee8, 0xfbf1649f, 0xcd3a9c43, + 0x0b0e8bb1, 0x3f3df1d5, 0x6a38286f, 0x8f0ec9b3, 0x4ed072b3, + 0x729c09e3, 0xa6e4c987, 0x8ad12242, 0xea3e8ac6, 0xfbdfa5ba, + 0x6ae0e22b, 0xb0a0f592, 0x56171ecf, 0x6b871f8d, 0x33b2886d, + 0x35e11bda, 0x6b19bea9, 0x7f0f153f, 0x4d815a40, 0x7d6c02ee, + 0x7e608d97, 0xb6a88f46, 0x7e8f23d9, 0x439d1654, 0x26ac9652, + 0x35546c29, 0x8d92c6bd }, + { 0xabeb0ff7, 0xb3e0d7ce, 0x3e0e42f8, 0xfbe35254, 0xde808499, + 0x57d1b226, 0x1cd44bc3, 0x9ece2e1f, 0x435cfee1, 0x1245adbc, + 0xf93f581c, 0x874ee840, 0xbda0b947, 0x916a779c, 0xfa57ae0a, + 0xabcc815a, 0xf0a621b0, 0x97adec2d, 0x81f90bdc, 0xbe6a502b, + 0x53bde63d, 0x54bf9de1, 0x78884c25, 0xa88fdabf, 0xcbbb5470, + 0x30aa52b1, 0x29053ef5, 0xf805396c, 0x8dd827ea, 0x8d43d898, + 0x5c1ae5c0, 0x4e4bec17 }, + { 0xfcc09676, 0xbf8483a2, 0x19ea9a94, 0x457c4a3f, 0xd702a5dd, + 0xa6852ef3, 0x843fe7d8, 0xe7915fd2, 0x16e35158, 0x644bba98, + 0x9ed746f0, 0x8d1b95d0, 0xb90af0b5, 0x47704581, 0xd4fd135e, + 0x0bd4bc6b, 0xb4e833a5, 0xa6dce067, 0xff56a9a1, 0x2c0e8f30, + 0xec2c63fe, 0xa9c80800, 0x98f508a8, 0x449c20a5, 0x3292813a, + 0x02b94cb3, 0xec7e81a2, 0x647e3d28, 0xb4877677, 0x72e67d1a, + 0x6f9ded24, 0x7a4aa3f5 }, + { 0xe27a0045, 0x559ef1ba, 0xb242cb50, 0xdc812d4f, 0x39cf8d24, + 0x23a478e4, 0x9b3f9c54, 0x97544fc5, 0xaffa1fcf, 0x5ac68132, + 0x34a2c83b, 0x74f8fee0, 0xcd3f4bb7, 0x96cc640f, 0xb0512ea6, + 0x775dce9d, 0xcdce381e, 0x67dca19d, 0xa9d3fe55, 0xc1eeb3f3, + 0x1a19274f, 0x38e0bf42, 0x28d69b12, 0x15992fb4, 0x9fd09df8, + 0x48fcebde, 0xb41ab5df, 0xdc9dfa4f, 0xc0a269c5, 0x0cbd7dc8, + 0xf7f0ade1, 0x60282a7b }, + { 0xdceea2e7, 0x7c07e538, 0x3c42061d, 0x38a322c8, 0x4f1f6516, + 0x676828f9, 0xc7776a10, 0xf21b69fb, 0xb5e6b405, 0xc63a3417, + 0x91a7b642, 0x4c99f258, 0x2cad1440, 0x38692ca8, 0x00869bcd, + 0xf1e82ffe, 0x16fe466a, 0xc30b714e, 0x19019138, 0x5fb742f9, + 0x0fa516ae, 0xe90166d0, 0xd8c73a43, 0x5550f7ac, 0xfbc5c372, + 0x2d6a407d, 0x68cc39ed, 0xe47a7539, 0x4a5fbe70, 0x3fd286d9, + 0x23c6b942, 0x5f4ae9c7 }, + { 0x53f4d561, 0xd96a2dda, 0x16da1992, 0x286d45d0, 0xfdd4b051, + 0x449a01fb, 0x9f2195ea, 0x25488a0d, 0xa37661b3, 0xc4151b0a, + 0xf9e5ee02, 0xb98c471e, 0xa8658817, 0xa4bca86e, 0x7a68fc0a, + 0xbbcadb87, 0x6b7366a9, 0x88b34649, 0x15661c2d, 0x32ee98d4, + 0xc901420c, 0xf5b3b4c6, 0x2f2752af, 0xa2352735, 0x510e4d9c, + 0x2f64ce73, 0xaca4aa80, 0x939a7f26, 0x401aa503, 0x9cd3e291, + 0xdc46afd2, 0x92a01423 }, + { 0x1c2f7dbd, 0xe9f24be1, 0xb7d527fa, 0xda8c900f, 0x8648f128, + 0x963e25bb, 0x48141941, 0x9ab713e2, 0x7a6756fb, 0xe87f7d01, + 0x058d90bd, 0x274dd85e, 0x82566abd, 0x823fee7a, 0x74240195, + 0x9f6230d7, 0xacb5e46e, 0x04579f2c, 0x16a4c87e, 0x2a226263, + 0xd99b0857, 0x9ca19a43, 0xe488789e, 0x86dc2ba3, 0x9406c3bd, + 0xf960b5b9, 0x8960957e, 0x6f2c428b, 0x161c515b, 0x90748706, + 0xaa88cb9b, 0x0fc8fe1e }, + { 0xfeb90f2d, 0x68ae1bed, 0xa48b1559, 0xf393bb3c, 0xf64e9635, + 0x2be62f9c, 0xf8be75c2, 0x354c2410, 0x5e6f7529, 0xbd7ea703, + 0x162cab31, 0xc264868e, 0xc860f3ff, 0xb1391e70, 0x1d89837e, + 0xdf367c75, 0x2bf32941, 0xe150b6b4, 0x78c1318f, 0x95e8f46e, + 0xa2c4b160, 0x2b3f1dab, 0x701afbf3, 0xc6ccf5ce, 0x5e8874c5, + 0x3ad27530, 0x5dc6dcbe, 0x39285e51, 0xd99892dd, 0x3c954d86, + 0xdfd3789f, 0x2d0ba862 }, + { 0xb472e1af, 0xeacd8ee8, 0xb76abbcc, 0xeb354eae, 0xd0d93fbd, + 0x9b520bf8, 0xfe6fc706, 0xfccd60d7, 0xa4ee2f39, 0xa9353dde, + 0x9a81e51e, 0x5eb0925e, 0xd1366777, 0xee334da1, 0xd5354d69, + 0xc1d28c9f, 0x92a5ed54, 0xb9771755, 0xb7f70d81, 0x5d3e367f, + 0xa933ae7a, 0x7be7eeca, 0xe23cfbb7, 0x264cf1f9, 0x89497681, + 0x0d129f4a, 0x09b6235b, 0x705375a4, 0x48a376da, 0xccf64c75, + 0x4d41dbfc, 0x963c8712 }, + { 0xde36a814, 0xbae290cb, 0x733b12b5, 0x9bdb0195, 0xf77fe0e1, + 0x0ebad867, 0x29720cea, 0x0a7d19fd, 0x9029ec72, 0x434d7651, + 0xbb51911e, 0x856aff17, 0xd80a7f60, 0xd0a25d9a, 0xf848c106, + 0xffca86af, 0x43ad749c, 0x53e8bdf9, 0xe3e696bb, 0xfb9e0284, + 0xeeee4215, 0x3eb6630a, 0x2ecf3c63, 0x9d8fbb9e, 0x4e00c0c0, + 0x71da4ffa, 0x5d57beac, 0xb296be59, 0xa8cec7ef, 0x1751fbad, + 0xff55d7bd, 0x2d03eb3c }, + { 0x04f2ec1d, 0xeb16925f, 0x0d147ee2, 0xa878f276, 0xaad9d9e0, + 0x442df604, 0x3f71035b, 0x891df44b, 0x8cb95d5b, 0xc28272b3, + 0x5ee8ed23, 0x6f14efb5, 0x13b0f3e3, 0xf3c4460f, 0x6bd7335e, + 0x889f9bd7, 0xf755ba6e, 0x889ee771, 0xed219b6c, 0x626984fe, + 0xec2ee411, 0x2d44c737, 0x63efcd37, 0xb94385a2, 0x6637826b, + 0xd909321b, 0x3ee6b7a7, 0xc24f8a79, 0xa7cf61b7, 0xa3ca8d24, + 0xc54bacd9, 0x842e40c1 }, + { 0xa661d843, 0x5a268ed6, 0x4f5b30cd, 0x02328cca, 0x1311e177, + 0x16e6fed1, 0xc6695967, 0x690decb4, 0x57b2e280, 0xbdac5bf6, + 0x1efe42d0, 0x827f82ca, 0xca5fca2f, 0xc554ec0a, 0xdde45506, + 0xac5276c1, 0xe3077513, 0xb7f4cb08, 0xcc8797cc, 0x8caf6d9a, + 0x0d9332d2, 0xd5964814, 0x285a409f, 0xcc6ae297, 0x6223d093, + 0x7773c2a5, 0x5128fc09, 0x2d5266ac, 0xbc31fe6c, 0xa596b7cb, + 0xcac91328, 0x0e63319a }, + { 0xf0360ac2, 0xb5cd2fad, 0x285e605a, 0x86b660de, 0xe25b9b14, + 0x82c6cf10, 0xaa9ac554, 0x9d5fa38d, 0x526c070e, 0x3dfcf1b8, + 0x3fccc52d, 0x0379a96b, 0x0bfcc7f5, 0xe3659c29, 0x69d3e6a1, + 0x5b1a3db5, 0x9b7b42d5, 0xb41528b5, 0x9c22a006, 0x934defa4, + 0x9b4ce3b6, 0x90f38018, 0xb3abaf32, 0xb073bc04, 0xff8389e2, + 0x27a5a222, 0xffa5a35b, 0x0b7a9d51, 0x28e1a7c2, 0x4939ecef, + 0x1872705a, 0x88839da2 }, + { 0x701ce29a, 0x56b66c30, 0x58981d50, 0x3acaf126, 0x105f9f21, + 0xd4dafc0c, 0x373e3d13, 0xfee571e6, 0xfa2ee3ca, 0xe7269c86, + 0xdd20385a, 0xf5cca64a, 0x3000e9ac, 0x217f2757, 0x0e7273ef, + 0xc934db47, 0x355b6776, 0x4294f4f7, 0x6fc05180, 0x1faa36b9, + 0xb052190b, 0x8f88b1db, 0xe9eaef52, 0x35791b90, 0xdb681b90, + 0xf37fb2eb, 0x4415c369, 0x39d0a51d, 0x1d2e21c9, 0xfc59cca7, + 0xa1f50c26, 0x64128cfe }, + { 0xe8f5b0b5, 0xf03678a2, 0xd340f059, 0x5c7e249c, 0x93ca7cec, + 0x41440441, 0xbc83af98, 0x075ca346, 0xfaa8bbb0, 0xf39f0033, + 0xf38230f7, 0x3d18f0ed, 0xd448f345, 0x78dff00c, 0xd51aa475, + 0x849228c0, 0x30c928d1, 0xdd4e2708, 0x8f12cfd3, 0xc66ba686, + 0x88b3a206, 0x091049db, 0x016dae01, 0xd865d059, 0xe253e37d, + 0x4599e905, 0x7ce9871b, 0x322cf0c2, 0x174a132e, 0x014f54da, + 0xbdabcbda, 0x93634a09 }, + { 0xa9a2e304, 0x62826b27, 0xc1a4c124, 0xc57e1866, 0x22381710, + 0x913ab832, 0xa9847cfe, 0x7e9b6b85, 0x2b5f46fd, 0x29655cf1, + 0x8038e66d, 0x7295572b, 0x6fa95eab, 0xe4cba601, 0xb9deda81, + 0xbbc11071, 0x3f1cf61e, 0x97f0009a, 0x373e0cfb, 0x5372777b, + 0xd139d63b, 0x302f909c, 0x4f87d78e, 0x1ed672da, 0xb4048763, + 0x362077a3, 0x9dcc22b2, 0xc408c32d, 0x26deeee7, 0x4b4c5bf2, + 0xbc06357e, 0x266cb467 }, + { 0xb56363e8, 0x6faa4154, 0x3c1aa4db, 0x4b4fd078, 0x2b9e6597, + 0x14358dde, 0xfa004b84, 0x5b34ae3e, 0xf19911a6, 0xcf44b2ec, + 0xa536bf78, 0x55caa833, 0x8870dc95, 0x606e1eb9, 0x09f3511d, + 0xe3c3287d, 0x9d5cf364, 0x68b2f4eb, 0x63ab8c9e, 0xc154e892, + 0xc36ab611, 0x1548828e, 0xa1b7d120, 0x0932bfcb, 0x5315b8d7, + 0x7ee7b5bc, 0xf7473ac1, 0x782fd0d1, 0x3c8f2af3, 0xbcb029a8, + 0x52454ee1, 0x4b1d5a1b }, + { 0x63d52c0c, 0x12fe5174, 0x188c099d, 0x3735525e, 0x360e3956, + 0x5c621563, 0xacfa5a43, 0x88b3f1ca, 0x797e8107, 0x90123a0a, + 0xb15e080a, 0xba31f6b5, 0xfca3dada, 0xd7de5e12, 0x0df511c8, + 0x3287361b, 0x65757d4e, 0x7cc800d4, 0x5207ec91, 0x10810f3d, + 0x30eea0e3, 0x0d4e56f1, 0x3ea5a2ec, 0xbbf7ee13, 0xbe6abbd0, + 0x6fc07762, 0x120bf619, 0xc831fdce, 0xb622d42a, 0xe07439fa, + 0x508e4b27, 0x8186b93f }, + { 0x09312867, 0xc619d154, 0xbfaf7db4, 0x7e042c05, 0x1f5f5dda, + 0xc1cf1668, 0xa4fc3d82, 0x50aa5057, 0xce68b8fe, 0xed30ed65, + 0xbeb4d644, 0xecb01c0b, 0x831c0497, 0x7b5dc444, 0x9b7d9b1c, + 0x351e6a00, 0xd9477c91, 0x4bb863b9, 0x05d4110a, 0xaba65891, + 0x43580b7a, 0x30086cf4, 0x90be357e, 0xb139c076, 0x27b5214e, + 0x12bfff1a, 0x22c3ab57, 0x79cfc6d7, 0xf34a9bfa, 0x4743de57, + 0xc9ee2b2a, 0x0bf97e97 }, + { 0xdda19e96, 0x96ec4ec8, 0x6c306e8b, 0x54ce18ea, 0x65f6918a, + 0x7e83612b, 0x0d9a0d99, 0x1ac6f68b, 0x62fdcc09, 0x98a697a4, + 0x95bc3e13, 0x65ce25f1, 0xb3939730, 0x1896ecda, 0x32f12806, + 0x9eb81a0f, 0x1d2dc7df, 0xd3d7416e, 0xad473599, 0xe22c7976, + 0x9f5ef439, 0x3de37a9a, 0x9e69d94e, 0x6b7ac0ab, 0x0a9d0bc8, + 0xe6bfa9e0, 0x5676f120, 0x576a870d, 0xfeaac23f, 0x3bd91bb4, + 0x3e40aabb, 0x8fe5482c }, + { 0xce9a4d1e, 0x85ae67c2, 0x4f1d2038, 0x4c3eb803, 0x25d06192, + 0x5c6c8f3a, 0x308fb41c, 0x803de0ad, 0xe71c294e, 0x9961f5bc, + 0xf02eb0da, 0xdc62078d, 0xb64ae8b6, 0xc87ef515, 0x50b4d18f, + 0x69679f1e, 0x52199f43, 0xc5c009a1, 0x0f640a5f, 0xa7d484be, + 0x23dab566, 0x4c918bb1, 0x64275d2c, 0xa67c114c, 0xcad2ded6, + 0x95a913b9, 0x6b4b5c8d, 0x189ed18b, 0xb42d3bf6, 0x4aeb6206, + 0xbbc8bc3f, 0x3928c669 }, + { 0xdacb4b64, 0xde4bea4a, 0xf26179a1, 0x03f62a44, 0x7a9112a4, + 0xf3aac94e, 0xd36f331e, 0x90448fbd, 0x407b85c4, 0x426042bc, + 0x2121b77b, 0x5ad8a596, 0x67cee984, 0x31674a4f, 0x4e3b2f0d, + 0x7fae8bbe, 0xa7c930eb, 0x681df6dd, 0xc259d0d4, 0xadeefa98, + 0xbea1c1fd, 0x1b14d9e6, 0x21d405d1, 0x3baadc8b, 0x73892754, + 0xf01dff93, 0xf071cde4, 0x81c35b3e, 0x9150d0d9, 0x1704d2e1, + 0x355134f6, 0x6ccc888f }, + { 0x7ad7504c, 0xf8d36f0e, 0xf7959ddd, 0xbca3265f, 0xfede67aa, + 0x0dcd1ede, 0xbaebf32f, 0x1276f4ce, 0x014edcfc, 0x6825a6e6, + 0x99ad8eb7, 0x0b8c1a82, 0x09b8ce1e, 0x312024a9, 0x9cbd351a, + 0xcb8fd98b, 0xfab1e8be, 0xa4841378, 0x3973cacf, 0x17ed0f5d, + 0x259d5254, 0xa17e1484, 0x74b91393, 0x53d5b843, 0x1aca3ce9, + 0x8f792b21, 0xc8c0f815, 0x035ff110, 0xad4ed7bd, 0x6afa6357, + 0xb26faef9, 0x2f151980 }, + { 0x29d2d439, 0x0c8631da, 0xbc039955, 0x121fbbc2, 0x6c05b75b, + 0x3e5a9792, 0xb6ce47ec, 0x6d6cf4c0, 0x9d88c658, 0xbaaa1767, + 0xf3355a17, 0x031db9e7, 0x0aef5a85, 0x8381e3d8, 0x15a31bdf, + 0xc71db290, 0x9498fd7d, 0x638f6b74, 0x13beeef6, 0x44edf3f9, + 0xf4ab67b3, 0xe6173271, 0xfd22df11, 0x3a202c70, 0x205c4e92, + 0xf7be0389, 0xa8eb9920, 0x1c219085, 0xbeb54aaa, 0x6c805ce8, + 0x0ac58d65, 0x354b05b7 }, + { 0x7a9170e9, 0x7171e236, 0x4cad50cd, 0x01eec42d, 0x3cddccfb, + 0xffbe824f, 0xa66cae1a, 0xa73e8ce3, 0x965c7d01, 0xb7138a7f, + 0x5c3d971e, 0x00058e3f, 0x2ff0a72b, 0x52591ac3, 0xbbbce76f, + 0xa32fb5bc, 0xa9f81a18, 0xf3241ab8, 0xeca68630, 0xf31d3332, + 0x4482f13b, 0x847af9fc, 0xa4681be2, 0x6196e217, 0xe55efcf9, + 0x9938f932, 0x70acc705, 0x3e7dacb8, 0xcf09fac2, 0xd41be893, + 0xae3523a1, 0x48dc55c4 }, + { 0xa5092193, 0x8e623826, 0x6898970c, 0xe46ec362, 0x25c9eb41, + 0x2f1356af, 0x83c7d245, 0x41780640, 0x97d00e38, 0x982def67, + 0xa512151c, 0x382eb6e7, 0x8af58869, 0x154e1077, 0x8a51cf02, + 0x18707075, 0x71313c58, 0xcdeba9f7, 0xba155904, 0x5d67b973, + 0x1d0d7b3a, 0x851c9f4b, 0x8b8af2cd, 0x19f29d71, 0x986b8d62, + 0xcb94ccff, 0xb93b9c33, 0x8725e24b, 0x66e38c68, 0x405ce4c5, + 0x0b6dc021, 0x5f6a8edd }, + { 0x8f9a8690, 0x83704ca5, 0x2f76a407, 0x3f369766, 0x69201028, + 0xfbc12d8c, 0xbce3a4cf, 0x4cd58f16, 0x04aab26d, 0x7804664a, + 0x4ea457a8, 0x005cfbba, 0xb8a59794, 0x537951b3, 0x4fe1f739, + 0x4ca2b9e4, 0xdf325797, 0xe4428acd, 0x0ea243db, 0x648da342, + 0xf43ce01e, 0xcce6562b, 0xf27db490, 0x840f0421, 0x8bfb7cf0, + 0x156ccb70, 0x5a8797d3, 0x9b33480d, 0x9eb814bb, 0x2e12e07a, + 0xca7f87ac, 0x1ca65072 }, + { 0x2b9d25a0, 0xfbb321cf, 0x40a746db, 0x66affdca, 0x59e368b5, + 0xc1c1530e, 0x7d80068f, 0x56ed1ea4, 0x5647dd68, 0x9b74d8fe, + 0x89b78da8, 0x1d96b507, 0x8bbe3391, 0x39b75243, 0x0d858c5f, + 0xef8d443e, 0x9646aa34, 0x4dd2db49, 0xe667543c, 0x7fad3bd1, + 0x68980985, 0xd0d710c0, 0x49facaba, 0x9f7aff32, 0x14f9a192, + 0x055dec1c, 0x1fb307a1, 0xaca66399, 0x35ffff64, 0xac44fd91, + 0xcbad3cee, 0x462cafb6 }, + { 0xde3237dd, 0x1660a647, 0x82b87404, 0x95f735cc, 0xddfa55f8, + 0xf7879f59, 0x726b914a, 0x15ef043e, 0x1c93e298, 0x1875393d, + 0x6ef18331, 0xa1a2be74, 0x25a9a12b, 0x4e7e8dfc, 0xa9c3917f, + 0xdfefc97d, 0x0a2ebe41, 0xbc875d03, 0xa732d1cc, 0x0f75d235, + 0xd9baa6d3, 0x06fee7fe, 0x65f48576, 0xaa784fab, 0x513f83c0, + 0x23155e22, 0x3e8f9d13, 0xd2fb7718, 0xb546eafd, 0x2a291503, + 0x6cd93608, 0x1293c98c }, + { 0x49d53b77, 0x72781251, 0x96eafac7, 0xa6ab403d, 0x4a36b711, + 0xb7d7c7db, 0x87e771c1, 0x8238c708, 0x33b37522, 0x495f6abf, + 0x8c87530d, 0xb0b0289c, 0xe77b111a, 0xca83cb86, 0xa1bd189e, + 0xbe1c0fb8, 0x1ae9d7c7, 0x58cfb2fb, 0x4940c3e8, 0xd05c23c5, + 0x74ad9107, 0x16e79e41, 0x064e7142, 0xa0a47f05, 0xfdfd614f, + 0xc6929cd4, 0x3946988b, 0xedb2584c, 0xe46f8fb1, 0x73e4b5f3, + 0x68ea94ba, 0x53b79aa1 }, + { 0x44bbb6a1, 0x216fafce, 0x67821728, 0xd3a5bba0, 0xa9dd939a, + 0xef1e4b30, 0xf19efafe, 0x022eaf3d, 0x7b4ec014, 0xfed5abce, + 0x512c6738, 0x64968ee6, 0x29fe89a2, 0x23119869, 0x47397c05, + 0x0d539d8d, 0x234596c4, 0x6400bc54, 0x5346611d, 0xb9287f58, + 0xc9d5da0f, 0x04099903, 0xc83af2a8, 0xe5ef4997, 0x328151e1, + 0xc89dc01b, 0x58401104, 0x150fb4a9, 0xf3872c9d, 0x40a6f7d5, + 0x56c2e833, 0x8290d6d1 }, + { 0xd8546946, 0xf84637c6, 0x69ec57fa, 0xda134a39, 0xd789007e, + 0xd42359a4, 0x0dc7b809, 0xb42557fe, 0x2d6784a9, 0xe62ae52d, + 0x0bcadb5f, 0xa2714ca6, 0x33aafca5, 0xcc208de6, 0xed967811, + 0x2380ed5c, 0xdb321660, 0x6e6b55e9, 0xa675235a, 0x1bead02c, + 0xb33fa0e1, 0x51cc6ef9, 0xf06a2a08, 0xfd223e26, 0xec47b3cf, + 0x00f332e1, 0xa0aa984e, 0x459f297b, 0xee952e14, 0x6fa1d969, + 0x304fabb0, 0x506ef1ab }, + { 0x35bff163, 0x11b4eb27, 0xea9fa984, 0x7130b96f, 0x9deb27ce, + 0x66aceb3f, 0x9dd1c3d5, 0xa2daf1a5, 0xa73075aa, 0xf5090a7e, + 0xe3071b58, 0x36a6af39, 0xdf73ad9c, 0xa28d633d, 0xbdc89a16, + 0xdd354cac, 0xd4dcbc3c, 0xdfea3423, 0x379d92d1, 0x6eec74d2, + 0x8eed6765, 0xe14a456f, 0xfa8feb1f, 0xfabe7743, 0xb98fcbc7, + 0x1404ccf8, 0xf71a706e, 0x6ccd2fbf, 0x4d85c678, 0xdaaf3fdb, + 0x15200344, 0x415b7dbf }, + { 0x7d8377a7, 0x97010586, 0xcb803272, 0x068a3d68, 0xf03a4c32, + 0xfd67d289, 0x93c8f290, 0x4bc7095d, 0xe9e5a2b8, 0x712fa13c, + 0x0feb9f3b, 0xfc6ac6c6, 0x6e0e54c2, 0x0cda36d9, 0x86320a01, + 0x45499751, 0x97f00f11, 0xf9318c91, 0xe6936508, 0x01dc4c3f, + 0x85f068aa, 0x769a2ef9, 0xa2b5511c, 0x3522cef0, 0xb4122e05, + 0x006965ed, 0xc175d43f, 0xfce0fafc, 0xec831d59, 0x525dc9bd, + 0xaf58879d, 0x1ec314f1 }, + { 0x2c8310c2, 0x0663feef, 0x457e3f74, 0xaa7e14da, 0xe5346887, + 0x392b10fc, 0x637ec2c5, 0xcde4a38f, 0xb542f8df, 0x50773320, + 0xf7de1711, 0x341302f9, 0xae4b9bc6, 0x018b1c63, 0xdd2f9e6f, + 0xf001c46e, 0x26eccfa0, 0xd3bb0a97, 0x7746e0c7, 0xa931b99d, + 0xf5875aec, 0xe0c8b6f7, 0x96939c82, 0xbb32f17c, 0x3de5a664, + 0x765135d2, 0x52abfa6b, 0x71936cb4, 0x2dc105de, 0xad5cc08f, + 0x7fff5788, 0x17e91d12 }, + { 0xb7e051ca, 0xbe92ced3, 0x19c776d4, 0xc644d4fd, 0x0086784b, + 0xc8ab4b52, 0xce9d6b31, 0x3ea66227, 0xd289e9c7, 0x395249a3, + 0xd12a19ee, 0x54509e65, 0x8c365aec, 0xa7bd4692, 0x77963e0e, + 0x354997e4, 0xb599732d, 0x0d765957, 0x91d4a3b6, 0x99584aeb, + 0x1deb3e28, 0x6e653ea4, 0x572571df, 0xca7c98ed, 0xb18ae1f9, + 0xf301a38f, 0x63f7b97e, 0x1629f7c2, 0xafc4a0d5, 0xdf242282, + 0x3ddd0c01, 0x118f3b4b }, + { 0x7ad4762b, 0x74a0a0a8, 0x8c58d175, 0x1aef84da, 0x4cf76d86, + 0x16ff4960, 0x7e60d98b, 0xc0be8786, 0x3ecc1dba, 0x83637ffb, + 0x5dd6147a, 0xc244a609, 0x5b0846e5, 0xa3e17834, 0xe77a4c05, + 0x735eb686, 0xdf758695, 0x5bc18b4f, 0x1bdfe52f, 0x15618d0b, + 0x00715ba1, 0x878ecc0d, 0xc2dd617f, 0x1dbdbd1a, 0x21b61710, + 0x21d2b631, 0x44f593c2, 0x22ce8a79, 0x44f17024, 0x3b9b536a, + 0x8d03e727, 0x01d0a67c }, + { 0x1e46533c, 0x7b964236, 0xfb88c2ae, 0xe9477990, 0xa42c4a18, + 0x019b5d16, 0xd83c7a45, 0x7135e81d, 0x4cb663e3, 0x74a69bdd, + 0xe76c0d63, 0x7b67ecdb, 0x11e68da6, 0x03d54521, 0xd2e8650a, + 0x596cceb5, 0x2af03b37, 0xcd572dfd, 0xfabd5952, 0x52364ba1, + 0xb4ed8569, 0x7f47d456, 0xc950d5d4, 0x5ad8b572, 0x486e2f84, + 0xcadd2dfa, 0xc56bb044, 0xdd527b43, 0x997c08e6, 0xc9adba24, + 0x7da6320f, 0x1b625b06 }, + { 0x4fd8446d, 0x44dfaa7b, 0xaf6febeb, 0xc01b2f01, 0xfe8838b5, + 0xbf444388, 0xbba9758b, 0xf33c434f, 0x87156bc9, 0x2b971cba, + 0x1f49098b, 0x6b245e5c, 0x2b41c5dd, 0x87dcb534, 0x34d852d7, + 0xdb1f80c6, 0x2433da34, 0x6d6e3258, 0x3f7df0c2, 0xf6682065, + 0x360cb365, 0xc4ca567c, 0x9826656a, 0x321faac2, 0xbf069768, + 0x13f5ca6f, 0xa7076639, 0x15397921, 0x8400736e, 0xbdf14328, + 0x19fc948d, 0x333eca96 }, + { 0xac775d81, 0x23337948, 0xd41dbbca, 0x38c2518f, 0xbcfce948, + 0x623c7a4f, 0x54703fe7, 0xaad36236, 0x13fb3b5b, 0x2b3a13a4, + 0x7f5c01f0, 0x5db3565a, 0x52359661, 0xd72408dc, 0x1d616e91, + 0x5a17f8e5, 0xcb25b999, 0x90c16eeb, 0x3393743e, 0xf35e8cf1, + 0xe54b64a7, 0x987da74a, 0x65cd449d, 0x557b322a, 0x37e7b15d, + 0x765082a5, 0xf2cd134f, 0x4d25c742, 0x4ccf0746, 0xae9d9c07, + 0x8728d135, 0x72fc2110 }, + { 0xf96004c8, 0xa906b203, 0x458055ff, 0xd83f95cf, 0x55f35909, + 0xd77d5867, 0xe550c8ee, 0x4a9ea6fb, 0x55a06081, 0x91c8cca9, + 0xbce82062, 0x4a1fee78, 0x9a3df85e, 0xeb9ade06, 0x7d3de666, + 0xfbbdcf0c, 0x5d336d51, 0x228a391b, 0x5c2ffc3c, 0x760f8d28, + 0x2f7b165b, 0x1ee48de3, 0x56177040, 0x03803d84, 0x9deff9a0, + 0xe573f648, 0xa17e35a4, 0xe1a2738e, 0x8840a6c6, 0x238ef17c, + 0xb11ed92d, 0x480946f8 }, + { 0xfd71f119, 0x84c747a8, 0x53eb3695, 0x19e65c5e, 0x6298587a, + 0x0e2f6786, 0xab18d6f4, 0x48a48899, 0xc630b8c0, 0xa1a99024, + 0x2caaf892, 0x84975096, 0xe20fd624, 0xc8869aba, 0x6c2b7dd4, + 0x3b72b04d, 0x0992f7d0, 0xe2775eb6, 0x7d06e684, 0x0089c06e, + 0xe4bbd007, 0xcb3b4361, 0x4ba846e4, 0xa1ae666b, 0x46464d9e, + 0xc01c2eb2, 0xc1f8539f, 0xf86f2be6, 0xcf68afc7, 0x16e8e8ae, + 0xc7386902, 0x8dab61fd }, + { 0xd54d1d45, 0x42a5c903, 0xff4f9ba2, 0xacd4297e, 0x34d478b4, + 0x2d88b520, 0x08c4621a, 0x35b2ba2b, 0x34865402, 0xd3d239bb, + 0x911f32e6, 0x1de76aed, 0x3f06fdc2, 0x877f8bcf, 0x9ec51502, + 0x802714c1, 0xa590700d, 0xa10444eb, 0x31dcc957, 0x8694229f, + 0xb8169fed, 0x5ece77ab, 0x2caf080e, 0x55be8a15, 0xcbd7cef1, + 0x3eb21b14, 0x67b97ee1, 0x9def7ad1, 0x118f690c, 0xe03ca879, + 0xf99b29e7, 0x6f77e62d }, + { 0xe40bbf59, 0xa271bded, 0x6401aad6, 0x177ba453, 0x73541cd1, + 0x1755e035, 0x4b71b02f, 0x3465b466, 0xa813359f, 0x22eb7113, + 0x6f38eac7, 0x9792a8fd, 0xff3bf3b5, 0x11aa012f, 0xf85c3fbf, + 0x99aafabf, 0x06c0cc42, 0x91e0a2ef, 0x773b7b3a, 0x314d5d57, + 0xd669840a, 0xae5e2e76, 0x2e5a8be6, 0x86136073, 0xc1cf5580, + 0xee6d7578, 0x68bed102, 0x2344e00f, 0x8184f0eb, 0x799d7886, + 0xc3d2cf80, 0x63819c91 }, + { 0x7884b073, 0xca5392e1, 0xeb1267ea, 0x9ec3a1fc, 0x907038a7, + 0x3d07f5f0, 0xe4c47b70, 0xcb2ac07c, 0x1bf96b91, 0xf96664ee, + 0x2aea4fbf, 0xebf57589, 0xfade6500, 0x5aabf391, 0x171d1204, + 0xc5b3376f, 0xa0d3d81a, 0x1ff60c51, 0x976a844b, 0x10b2cfe7, + 0xbda6125a, 0xe131cc9a, 0x4ebd453e, 0xe0fc16d3, 0x504b6bc1, + 0xc0d0319a, 0x0a2f8cab, 0xe43a0be7, 0x55e49b47, 0xc80afeec, + 0x8265d7ee, 0x67d48d12 }, + { 0xea2d56d6, 0x068d59a7, 0x27480a63, 0xd71abd0e, 0xae7366cd, + 0x6bd11db0, 0x07204ebc, 0xfbb639ca, 0xf77e6293, 0x89a242e7, + 0x75ba8c3d, 0xdee7ca2b, 0x64a2f9a8, 0x472ddc3d, 0x7561a010, + 0x84229df4, 0xc5b649d4, 0x95f62c85, 0x4dc927cd, 0xfdd56b1b, + 0x5ee60596, 0xfe8bb120, 0xabf29401, 0x3efcaa50, 0x10d1c184, + 0xd4900d0f, 0x28b01df5, 0x2cf113a9, 0x1f0e43f5, 0xa3d7ebc3, + 0xe8384dc7, 0x27950e38 }, + { 0xe1d0fa79, 0xeab21ff0, 0x048b5de9, 0x4b9fd033, 0x2fe374cb, + 0x4c934689, 0x4eb21f6b, 0xbb4827fa, 0xa925e7e7, 0x46716f79, + 0x7dd4c531, 0x1442bf36, 0xd2e96ddf, 0x2073954c, 0x8502aa89, + 0x4e0141ae, 0x8eef6cc9, 0x8ee00e1a, 0x5880cdaf, 0x55ce8491, + 0x69628046, 0xff3aba5c, 0x5d15dfbf, 0x335cc4f8, 0x9f684f25, + 0xa7f0440c, 0xbb1e5bd8, 0xae80453f, 0xff2225ab, 0xa1c99813, + 0x79b25d71, 0x54ff7884 }, + { 0xde40b068, 0x27c6ee30, 0xe6f3a51e, 0x9226465b, 0xfa3b21f6, + 0xe24a4604, 0xc0418115, 0x50a5a5ad, 0x8df90d2b, 0xe3285441, + 0xdcb0c00f, 0xbb74e58f, 0x4a2c08e3, 0xc68f1b3b, 0x0ccd9ec9, + 0x339df081, 0xb786ea9f, 0x915362dc, 0xc955aead, 0x28945e31, + 0x8b6a6c6b, 0xd6a2c01d, 0x3678a427, 0x069e82dc, 0x28c9302c, + 0x17875500, 0x9fa101e6, 0x8acda965, 0xee30b286, 0x4e4e4573, + 0x3f1830fe, 0x8adbad85 }, + { 0x0969d524, 0x060ae11f, 0xf39bcc79, 0xf42fdaf7, 0x7cc1fcc2, + 0x3cec6766, 0xe2336d4f, 0x456b9cf2, 0x8e1c0f7f, 0x6aa1f5de, + 0x0984fb0e, 0xcdbc2ad2, 0x1b464b28, 0x4090cfa6, 0x1243f3ef, + 0x40d86f30, 0xcd5e87e7, 0x95b16ccc, 0x3026cd41, 0x403f168c, + 0x816c0730, 0xdbe386cb, 0x58407a1d, 0x14eb86f3, 0x1717e1af, + 0xf588b4f8, 0x66cbc96c, 0xb75c41a6, 0x027e71c1, 0xf342c1aa, + 0xc0945e5f, 0x73930036 }, + { 0x22cdaf42, 0x954f757d, 0xf4181aab, 0x788b591d, 0xf5514f25, + 0x8b986819, 0xf18fd5bc, 0x69642e08, 0x022ceb91, 0x92b305d1, + 0x6a4f6985, 0x1715903e, 0x61179cae, 0x4bd7d69d, 0xd29c01aa, + 0xdacdfd5d, 0xd91108cc, 0x705ddd5a, 0x64ac8f15, 0x434ac7b1, + 0xb524632f, 0x61a514e1, 0x731fc447, 0x45b9e61b, 0xe0961b31, + 0xcf561348, 0x73eaf223, 0x9c28a967, 0xaa7c99d3, 0x5bd10182, + 0xe42965e2, 0x8bc6ec4a }, + { 0xe7f2a32b, 0xd096e5c0, 0x09388a30, 0xff54800c, 0x401e360c, + 0x06fe437c, 0xbb6054a6, 0x6655fc9c, 0x8457aa6e, 0x510e1860, + 0x2b29b2b7, 0xa0acfca2, 0x51b7da61, 0x732483e3, 0x6be6c8ca, + 0xe31471ee, 0x8b65c9a1, 0xe565431c, 0x48d65cbb, 0xfc9ac3b9, + 0xae9b2aa8, 0xd308fc21, 0xaa60aa6a, 0xd6a7df0d, 0x982fc0d4, + 0x2844d96a, 0x5847a4d7, 0xab012c2c, 0xdceb8955, 0x2b3c8f71, + 0xbe9c7e15, 0x8e85437d }, +}; + +/* Perform the modular exponentiation in Fp* for SAKKE. + * + * Base is fixed to be the g parameter - a precomputed table is used. + * + * Striping: 128 points at a distance of 8 combined. + * Total of 256 points in table. + * Square and multiply performed in Fp*. + * + * base [in] Base. MP integer. + * exp [in] Exponent. MP integer. + * res [out] Result. MP integer. + * returns 0 on success, MP_READ_E if there are too many bytes in an array + * and MEMORY_E if memory allocation fails. + */ +int sp_ModExp_Fp_star_1024(const mp_int* base, mp_int* exp, mp_int* res) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td; + sp_digit* t; + sp_digit* tx; + sp_digit* ty; +#else + sp_digit t[4 * 2 * 32]; + sp_digit tx[2 * 32]; + sp_digit ty[2 * 32]; +#endif + sp_digit* r = NULL; + unsigned char e[128]; + int err = MP_OKAY; + int i; + int y; + + (void)base; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6 * 32 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + tx = td + 4 * 32 * 2; + ty = td + 5 * 32 * 2; +#endif + r = ty; + + (void)mp_to_unsigned_bin_len(exp, e, 128); + + XMEMCPY(tx, p1024_norm_mod, sizeof(sp_digit) * 32); + y = e[112] >> 7; + y |= (e[96] >> 7) << 1; + y |= (e[80] >> 7) << 2; + y |= (e[64] >> 7) << 3; + y |= (e[48] >> 7) << 4; + y |= (e[32] >> 7) << 5; + y |= (e[16] >> 7) << 6; + y |= (e[0] >> 7) << 7; + XMEMCPY(ty, sp_1024_g_table[y], sizeof(sp_digit) * 32); + for (i = 126; i >= 0; i--) { + y = (e[127 - (i / 8)] >> (i & 0x7)) & 1; + y |= ((e[111 - (i / 8)] >> (i & 0x7)) & 1) << 1; + y |= ((e[95 - (i / 8)] >> (i & 0x7)) & 1) << 2; + y |= ((e[79 - (i / 8)] >> (i & 0x7)) & 1) << 3; + y |= ((e[63 - (i / 8)] >> (i & 0x7)) & 1) << 4; + y |= ((e[47 - (i / 8)] >> (i & 0x7)) & 1) << 5; + y |= ((e[31 - (i / 8)] >> (i & 0x7)) & 1) << 6; + y |= ((e[15 - (i / 8)] >> (i & 0x7)) & 1) << 7; + + sp_1024_proj_sqr_32(tx, ty, t); + sp_1024_proj_mul_qx1_32(tx, ty, sp_1024_g_table[y], t); + } + } + + if (err == MP_OKAY) { + sp_1024_mont_inv_32(tx, tx, t); + sp_1024_mont_mul_32(r, tx, ty, p1024_mod, p1024_mp_mod); + XMEMSET(r + 32, 0, sizeof(sp_digit) * 32); + sp_1024_mont_reduce_32(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Multiply p* by q* in projective co-ordinates. + * + * p.x' = (p.x * q.x) - (p.y * q.y) + * p.y' = (p.x * q.y) + (p.y * q.x) + * But applying Karatsuba: + * v0 = p.x * q.x + * v1 = p.y * q.y + * p.x' = v0 - v1 + * p.y' = (px + py) * (qx + qy) - v0 - v1 + * + * px [in,out] A single precision integer - X ordinate of number to multiply. + * py [in,out] A single precision integer - Y ordinate of number to multiply. + * qx [in] A single precision integer - X ordinate of number of + * multiplier. + * qy [in] A single precision integer - Y ordinate of number of + * multiplier. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_mul_32(sp_digit* px, sp_digit* py, + const sp_digit* qx, const sp_digit* qy, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 32; + + /* t1 = px + py */ + sp_1024_mont_add_32(t1, px, py, p1024_mod); + /* t2 = qx + qy */ + sp_1024_mont_add_32(t2, qx, qy, p1024_mod); + /* t2 = (px + py) * (qx + qy) */ + sp_1024_mont_mul_32(t2, t1, t2, p1024_mod, p1024_mp_mod); + /* t1 = py * qy */ + sp_1024_mont_mul_32(t1, py, qy, p1024_mod, p1024_mp_mod); + /* t2 = (px + py) * (qx + qy) - (py * qy) */ + sp_1024_mont_sub_32(t2, t2, t1, p1024_mod); + /* px = px * qx */ + sp_1024_mont_mul_32(px, px, qx, p1024_mod, p1024_mp_mod); + /* py = (px + py) * (qx + qy) - (py * qy) - (px * qx) */ + sp_1024_mont_sub_32(py, t2, px, p1024_mod); + /* px = (px * qx) - (py * qy)*/ + sp_1024_mont_sub_32(px, px, t1, p1024_mod); +} + +#ifndef WOLFSSL_SP_SMALL +/* + * Convert point from projective to affine but keep in Montgomery form. + * + * p [in,out] Point to convert. + * t [in] Temporary numbers: 2. + */ +static void sp_1024_mont_map_32(sp_point_1024* p, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 32; + + sp_1024_mont_inv_32(t1, p->z, t2); + sp_1024_mont_sqr_32(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t1, t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(p->x, p->x, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(p->y, p->y, t1, p1024_mod, p1024_mp_mod); + XMEMCPY(p->z, p1024_norm_mod, sizeof(sp_digit) * 32); +} + +#endif /* WOLFSSL_SP_SMALL */ +/* + * Calculate gradient of line through P, P and [-2]P, accumulate line and + * double P. + * + * Calculations: + * l = 3 * (p.x^2 - p.z^4) = 3 * (p.x - p.z^2) * (p.x + p.z^2) + * r.x = l * (p.x + q.x * p.z^2) - 2 * p.y^2 + * r.y = 2 * p.y * p.z^3 * q.y (= p'.z * p.z^2 * q.y) + * v* = v*^2 * r* + * p'.x = l^2 - 8 * p.y^2 * p.x + * p'.y = (4 * p.y^2 * p.x - p'.x) * l - 8 * p.y^4 + * p'.z = 2 * p.y * p.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] p ECC point - point on E(F_p^2) to double. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_dbl_32(sp_digit* vx, sp_digit* vy, + sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 32; + sp_digit* pz2 = t + 2 * 32; + sp_digit* rx = t + 4 * 32; + sp_digit* ry = t + 6 * 32; + sp_digit* l = t + 8 * 32; + sp_digit* ty = t + 10 * 32; + + /* v = v^2 */ + sp_1024_proj_sqr_32(vx, vy, t); + /* pz2 = p.z^2 */ + sp_1024_mont_sqr_32(pz2, p->z, p1024_mod, p1024_mp_mod); + /* t1 = p.x + p.z^2 */ + sp_1024_mont_add_32(ty, p->x, pz2, p1024_mod); + /* l = p.x - p.z^2 */ + sp_1024_mont_sub_32(l, p->x, pz2, p1024_mod); + /* t1 = (p.x + p.z^2) * (p.x - p.z^2) = p.x^2 - p.z^4 */ + sp_1024_mont_mul_32(t1, l, ty, p1024_mod, p1024_mp_mod); + /* l = 3 * (p.x^2 - p.z^4) */ + sp_1024_mont_tpl_32(l, t1, p1024_mod); + /* t1 = q.x * p.z^2 */ + sp_1024_mont_mul_32(t1, q->x, pz2, p1024_mod, p1024_mp_mod); + /* t1 = p.x + q.x * p.z^2 */ + sp_1024_mont_add_32(t1, p->x, t1, p1024_mod); + /* r.x = l * (p.x + q.x * p.z^2) */ + sp_1024_mont_mul_32(rx, l, t1, p1024_mod, p1024_mp_mod); + /* r.y = 2 * p.y */ + sp_1024_mont_dbl_32(ry, p->y, p1024_mod); + /* ty = 4 * p.y ^ 2 */ + sp_1024_mont_sqr_32(ty, ry, p1024_mod, p1024_mp_mod); + /* t1 = 2 * p.y ^ 2 */ + sp_1024_div2_32(t1, ty, p1024_mod); + /* r.x -= 2 * (p.y ^ 2) */ + sp_1024_mont_sub_32(rx, rx, t1, p1024_mod); + /* p'.z = p.y * 2 * p.z */ + sp_1024_mont_mul_32(p->z, p->z, ry, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 */ + sp_1024_mont_mul_32(t1, p->z, pz2, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 * q.y */ + sp_1024_mont_mul_32(ry, t1, q->y, p1024_mod, p1024_mp_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_32(vx, vy, rx, ry, t); + + /* Double point using previously calculated values + * l = 3 * (p.x - p.z^2).(p.x + p.z^2) + * ty = 4 * p.y^2 + * p'.z = 2 * p.y * p.z + */ + /* t1 = (4 * p.y^2) ^ 2 = 16 * p.y^4 */ + sp_1024_mont_sqr_32(t1, ty, p1024_mod, p1024_mp_mod); + /* t1 = 16 * p.y^4 / 2 = 8 * p.y^4 */ + sp_1024_div2_32(t1, t1, p1024_mod); + /* p'.y = 4 * p.y^2 * p.x */ + sp_1024_mont_mul_32(p->y, ty, p->x, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 */ + sp_1024_mont_sqr_32(p->x, l, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 - 4 * p.y^2 * p.x */ + sp_1024_mont_sub_32(p->x, p->x, p->y, p1024_mod); + /* p'.x = l^2 - 8 * p.y^2 * p.x */ + sp_1024_mont_sub_32(p->x, p->x, p->y, p1024_mod); + /* p'.y = 4 * p.y^2 * p.x - p.x' */ + sp_1024_mont_sub_32(ty, p->y, p->x, p1024_mod); + /* p'.y = (4 * p.y^2 * p.x - p'.x) * l */ + sp_1024_mont_mul_32(p->y, ty, l, p1024_mod, p1024_mp_mod); + /* p'.y = (4 * p.y^2 * p.x - p'.x) * l - 8 * p.y^4 */ + sp_1024_mont_sub_32(p->y, p->y, t1, p1024_mod); +} + +#ifdef WOLFSSL_SP_SMALL +/* + * Calculate gradient of line through C, P and -C-P, accumulate line and + * add P to C. + * + * Calculations: + * r.x = (q.x + p.x) * c.y - (q.x * c.z^2 + c.x) * p.y * c.z + * r.y = (c.x - p.x * c.z^2) * q.y * c.z + * v* = v* * r* + * r = p.y * c.z^3 - c.y + * c'.x = r^2 + h^3 - 2 * c.x * h^2 + * c'.y = r * (c'.x - c.x * h^2) - c.y * h^3 + * c'.z = (c.x - p.x * c.z^2) * c.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] c ECC point - current point on E(F_p^2) to be added + * to. + * @param [in] p ECC point - point on E(F_p^2) to add. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] qx_px SP that is a constant value across adds. + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_add_one_32(sp_digit* vx, sp_digit* vy, + sp_point_1024* c, sp_point_1024* p, sp_point_1024* q, sp_digit* qx_px, + sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 32; + sp_digit* rx = t + 4 * 32; + sp_digit* ry = t + 6 * 32; + sp_digit* h = t + 8 * 32; + sp_digit* r = t + 10 * 32; + + /* r.x = (q.x + p.x) * c.y */ + sp_1024_mont_mul_32(rx, qx_px, c->y, p1024_mod, p1024_mp_mod); + /* t2 = c.z^2 */ + sp_1024_mont_sqr_32(t2, c->z, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 */ + sp_1024_mont_mul_32(t1, q->x, t2, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 + c.x */ + sp_1024_mont_add_32(h, t1, c->x, p1024_mod); + /* r = p.y * c.z */ + sp_1024_mont_mul_32(ry, p->y, c->z, p1024_mod, p1024_mp_mod); + /* t1 = (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_mul_32(t1, h, ry, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z * c.z^2 = p.y * c.z^3 */ + sp_1024_mont_mul_32(r, ry, t2, p1024_mod, p1024_mp_mod); + /* r.x -= (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_sub_32(rx, rx, t1, p1024_mod); + /* t1 = p.x * c.z^2 */ + sp_1024_mont_mul_32(t1, p->x, t2, p1024_mod, p1024_mp_mod); + /* h = c.x - p.x * c.z^2 */ + sp_1024_mont_sub_32(h, c->x, t1, p1024_mod); + /* c'.z = (c.x - p.x * c.z^2) * c.z */ + sp_1024_mont_mul_32(c->z, h, c->z, p1024_mod, p1024_mp_mod); + /* r.y = (c.x - p.x * c.z^2) * c.z * q.y */ + sp_1024_mont_mul_32(ry, c->z, q->y, p1024_mod, p1024_mp_mod); + /* v = v * r */ + sp_1024_proj_mul_32(vx, vy, rx, ry, t); + + /* Add p to c using previously calculated values. + * h = c.x - p.x * c.z^2 + * r = p.y * c.z^3 + * c'.z = (c.x - p.x * c.z^2) * c.z + */ + + /* r = p.y * c.z^3 - c.y */ + sp_1024_mont_sub_32(r, r, c->y, p1024_mod); + /* t1 = r^2 */ + sp_1024_mont_sqr_32(t1, r, p1024_mod, p1024_mp_mod); + /* t2 = h^2 */ + sp_1024_mont_sqr_32(rx, h, p1024_mod, p1024_mp_mod); + /* ry = c.x * h^2 */ + sp_1024_mont_mul_32(ry, c->x, rx, p1024_mod, p1024_mp_mod); + /* t2 = h^3 */ + sp_1024_mont_mul_32(t2, rx, h, p1024_mod, p1024_mp_mod); + /* c->x = r^2 + h^3 */ + sp_1024_mont_add_32(c->x, t1, t2, p1024_mod); + /* t1 = 2 * c.x * h^2 */ + sp_1024_mont_dbl_32(t1, ry, p1024_mod); + /* c'.x = r^2 + h^3 - 2 * c.x * h^2 */ + sp_1024_mont_sub_32(c->x, c->x, t1, p1024_mod); + /* ry = c'.x - c.x * h^2 */ + sp_1024_mont_sub_32(t1, c->x, ry, p1024_mod); + /* ry = r * (c'.x - c.x * h^2) */ + sp_1024_mont_mul_32(ry, t1, r, p1024_mod, p1024_mp_mod); + /* t2 = c.y * h^3 */ + sp_1024_mont_mul_32(t1, t2, c->y, p1024_mod, p1024_mp_mod); + /* c'.y = r * (c'.x - c.x * h^2) - c.y * h^3 */ + sp_1024_mont_sub_32(c->y, ry, t1, p1024_mod); +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * @param [in] key SAKKE key. + * @param [in] p First point on E(F_p)[q]. + * @param [in] q Second point on E(F_p)[q]. + * @param [in] r Result of calculation. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +int sp_Pairing_1024(const ecc_point* pm, const ecc_point* qm, mp_int* res) +{ + int err = MP_OKAY; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit* qx_px; +#else + sp_digit t[6 * 2 * 32]; + sp_digit vx[2 * 32]; + sp_digit vy[2 * 32]; + sp_digit qx_px[2 * 32]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + + err = sp_1024_point_new_32(NULL, pd, p); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 9 * 32 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 32 * 2; + vy = td + 7 * 32 * 2; + qx_px = td + 8 * 32 * 2; +#endif + r = vy; + + sp_1024_point_from_ecc_point_32(p, pm); + sp_1024_point_from_ecc_point_32(q, qm); + + err = sp_1024_mod_mul_norm_32(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 32); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 32); + + sp_1024_mont_add_32(qx_px, q->x, p->x, p1024_mod); + + for (i = 1020; i >= 0; i--) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_dbl_32(vx, vy, c, q, t); + + if ((i > 0) && ((p1024_order[i / 32] >> (i % 32)) & 1)) { + /* Accumulate line into v and add P into C. */ + sp_1024_accumulate_line_add_one_32(vx, vy, c, p, q, qx_px, t); + } + } + + /* Final exponentiation */ + sp_1024_proj_sqr_32(vx, vy, t); + sp_1024_proj_sqr_32(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_32(vx, vx, t); + sp_1024_mont_mul_32(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 32, 0, sizeof(sp_digit) * 32); + sp_1024_mont_reduce_32(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_32(c, 1, NULL); + sp_1024_point_free_32(q, 1, NULL); + sp_1024_point_free_32(p, 1, NULL); + return err; +} + +#else +/* + * Calculate gradient of line through C, P and -C-P, accumulate line and + * add P to C. + * + * Both C and P have z ordinates to use in the calculation. + * + * Calculations: + * r.x = (q.x * c.z^2 + c.x) * p.y * c.z - (q.x * p.z^2 + p.x) * c.y * p.z + * r.y = (p.x * c.z^2 - c.x * p.z^2) * q.y * p.z * c.z + * v* = v* * r* + * h = p.x * c.z^2 - c.x * p.z^2 + * r = p.y * c.z^3 - c.y * p.z^3 + * c'.x = r^2 - h^3 - 2 * c.x * p.z^2 * h^2 + * c'.y = r * (c.x * p.z^2 * h^2 - c'.x) - c.y * p.z^3 * h^3 + * c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] c ECC point - current point on E(F_p^2) to be added + * to. + * @param [in,out] p ECC point - point on E(F_p^2) to add. + * @param [in,out] q ECC point - second point on E(F_P^2). + * @param [in,out] t SP temporaries (6 used). + * @param [in,out] neg Indicates to use negative P. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static void sp_1024_accumulate_line_add_n_32(sp_digit* vx, sp_digit* vy, + const sp_point_1024* p, const sp_point_1024* q, + sp_point_1024* c, sp_digit* t, int neg) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 32; + sp_digit* rx = t + 4 * 32; + sp_digit* ry = t + 6 * 32; + sp_digit* h = t + 8 * 32; + sp_digit* r = t + 10 * 32; + + /* h = p.z^2 */ + sp_1024_mont_sqr_32(h, p->z, p1024_mod, p1024_mp_mod); + /* rx = q.x * p.z^2 */ + sp_1024_mont_mul_32(rx, q->x, h, p1024_mod, p1024_mp_mod); + /* rx = q.x * p.z^2 + p.x */ + sp_1024_mont_add_32(t2, rx, p->x, p1024_mod); + /* c.y = c.y * p.z */ + sp_1024_mont_mul_32(t1, c->y, p->z, p1024_mod, p1024_mp_mod); + /* r.x = (q.x * p.z^2 + p.x) * c.y * p.z */ + sp_1024_mont_mul_32(rx, t2, t1, p1024_mod, p1024_mp_mod); + /* c.y = c.y * p.z^3 */ + sp_1024_mont_mul_32(c->y, t1, h, p1024_mod, p1024_mp_mod); + /* t2 = c.z^2 */ + sp_1024_mont_sqr_32(t2, c->z, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 */ + sp_1024_mont_mul_32(t1, q->x, t2, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 + c.x */ + sp_1024_mont_add_32(t1, t1, c->x, p1024_mod); + /* c.x = c.x * p.z^2 */ + sp_1024_mont_mul_32(c->x, c->x, h, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z */ + sp_1024_mont_mul_32(r, p->y, c->z, p1024_mod, p1024_mp_mod); + if (neg) { + /* r = -p.y * c.z */ + sp_1024_mont_sub_32(r, p1024_mod, r, p1024_mod); + } + /* t1 = (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_mul_32(ry, t1, r, p1024_mod, p1024_mp_mod); + /* r.x -= (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_sub_32(rx, ry, rx, p1024_mod); + /* t1 = p.x * c.z^2 */ + sp_1024_mont_mul_32(t1, p->x, t2, p1024_mod, p1024_mp_mod); + /* h = p.x * c.z^2 - c.x * p.z^2 */ + sp_1024_mont_sub_32(h, t1, c->x, p1024_mod); + /* c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z */ + sp_1024_mont_mul_32(t1, h, c->z, p1024_mod, p1024_mp_mod); + /* c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z * p.z */ + sp_1024_mont_mul_32(c->z, t1, p->z, p1024_mod, p1024_mp_mod); + /* r.y = (p.x * c.z^2 - c.x * p.z^2) * c.z * p.z * q.y */ + sp_1024_mont_mul_32(ry, c->z, q->y, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z^3 */ + sp_1024_mont_mul_32(t1, r, t2, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z^3 - c.y * p.z^3 */ + sp_1024_mont_sub_32(r, t1, c->y, p1024_mod); + /* v = v * r */ + sp_1024_proj_mul_32(vx, vy, rx, ry, t); + + /* Add p to c using previously calculated values. + * h = p.x * c.z^2 - c.x * p.z^2 + * r = p.y * c.z^3 - c.y * p.z^3 + * c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z + */ + + /* t1 = r^2 */ + sp_1024_mont_sqr_32(t1, r, p1024_mod, p1024_mp_mod); + /* t2 = h^2 */ + sp_1024_mont_sqr_32(rx, h, p1024_mod, p1024_mp_mod); + /* ry = c.x * p.z^2 * h^2 */ + sp_1024_mont_mul_32(ry, rx, c->x, p1024_mod, p1024_mp_mod); + /* t2 = h^3 */ + sp_1024_mont_mul_32(t2, rx, h, p1024_mod, p1024_mp_mod); + /* c'.x = r^2 - h^3 */ + sp_1024_mont_sub_32(c->x, t1, t2, p1024_mod); + /* t1 = 2 * c.x * p.z^2 * h^2 */ + sp_1024_mont_dbl_32(t1, ry, p1024_mod); + /* c'.x = r^2 - h^3 - 2 * c.x * p.z^2 * h^2 */ + sp_1024_mont_sub_32(c->x, c->x, t1, p1024_mod); + /* ry = c.x * p.z^2 * h^2 - c'.x */ + sp_1024_mont_sub_32(t1, ry, c->x, p1024_mod); + /* ry = r * (c.x * p.z^2 * h^2 - c'.x) */ + sp_1024_mont_mul_32(ry, t1, r, p1024_mod, p1024_mp_mod); + /* t2 = c.y * p.z^3 * h^3 */ + sp_1024_mont_mul_32(t1, t2, c->y, p1024_mod, p1024_mp_mod); + /* c'.y = r * (c.x * p.z^2 * h^2 - c'.x) - c.y * p.z^3 * h^3 */ + sp_1024_mont_sub_32(c->y, ry, t1, p1024_mod); +} + +/* + * Perform n accumulate doubles and doubles of P. + * + * py = 2 * p.y + * + * For each double: + * Calculate gradient of line through P, P and [-2]P, accumulate line and + * double P. + * + * Calculations: + * l = 3 * (p.x^2 - p.z^4) = 3 * (p.x - p.z^2) * (p.x + p.z^2) + * r.x = l * (p.x + q.x * p.z^2) - py^2 / 2 + * r.y = py * p.z^3 * q.y (= p'.z * p.z^2 * q.y) + * v* = v*^2 * r* + * p'.x = l^2 - 2 * py^2 * p.x + * py' = (py^2 * p.x - p'.x) * l - py^4 (= 2 * p'.y) + * p'.z = py * p.z + * + * Finally: + * p'.y = py' / 2 + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] p ECC point - point on E(F_p^2) to double. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] n Number of times to double. + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_dbl_n_32(sp_digit* vx, sp_digit* vy, + sp_point_1024* p, const sp_point_1024* q, int n, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 32; + sp_digit* pz2 = t + 2 * 32; + sp_digit* rx = t + 4 * 32; + sp_digit* ry = t + 6 * 32; + sp_digit* l = t + 8 * 32; + sp_digit* ty = t + 10 * 32; + int i; + + /* py = 2 * p.y */ + sp_1024_mont_dbl_32(p->y, p->y, p1024_mod); + + for (i = 0; i < n; i++) { + /* v = v^2 */ + sp_1024_proj_sqr_32(vx, vy, t); + /* pz2 = p.z^2 */ + sp_1024_mont_sqr_32(pz2, p->z, p1024_mod, p1024_mp_mod); + /* t1 = p.x + p.z^2 */ + sp_1024_mont_add_32(t1, p->x, pz2, p1024_mod); + /* l = p.x - p.z^2 */ + sp_1024_mont_sub_32(l, p->x, pz2, p1024_mod); + /* t1 = (p.x + p.z^2) * (p.x - p.z^2) = p.x^2 - p.z^4 */ + sp_1024_mont_mul_32(ty, l, t1, p1024_mod, p1024_mp_mod); + /* l = 3 * (p.x^2 - p.z^4) */ + sp_1024_mont_tpl_32(l, ty, p1024_mod); + /* t1 = q.x * p.z^2 */ + sp_1024_mont_mul_32(t1, q->x, pz2, p1024_mod, p1024_mp_mod); + /* t1 = p.x + q.x * p.z^2 */ + sp_1024_mont_add_32(t1, p->x, t1, p1024_mod); + /* r.x = l * (p.x + q.x * p.z^2) */ + sp_1024_mont_mul_32(rx, l, t1, p1024_mod, p1024_mp_mod); + /* ty = py ^ 2 */ + sp_1024_mont_sqr_32(ty, p->y, p1024_mod, p1024_mp_mod); + /* t1 = py ^ 2 / 2 */ + sp_1024_div2_32(t1, ty, p1024_mod); + /* r.x -= py ^ 2 / 2 */ + sp_1024_mont_sub_32(rx, rx, t1, p1024_mod); + /* p'.z = py * pz */ + sp_1024_mont_mul_32(p->z, p->z, p->y, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 */ + sp_1024_mont_mul_32(t1, p->z, pz2, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 * q.y */ + sp_1024_mont_mul_32(ry, t1, q->y, p1024_mod, p1024_mp_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_32(vx, vy, rx, ry, t); + + /* Double point using previously calculated values + * l = 3 * (p.x - p.z^2).(p.x + p.z^2) + * ty = py^2 + * p'.z = py * p.z + */ + /* t1 = py^2 ^ 2 = py^4 */ + sp_1024_mont_sqr_32(t1, ty, p1024_mod, p1024_mp_mod); + /* py' = py^2 * p. x */ + sp_1024_mont_mul_32(p->y, ty, p->x, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 */ + sp_1024_mont_sqr_32(p->x, l, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 - py^2 * p.x */ + sp_1024_mont_sub_32(p->x, p->x, p->y, p1024_mod); + /* p'.x = l^2 - 2 * p.y^2 * p.x */ + sp_1024_mont_sub_32(p->x, p->x, p->y, p1024_mod); + /* py' = py^2 * p.x - p.x' */ + sp_1024_mont_sub_32(ty, p->y, p->x, p1024_mod); + /* py' = (p.y^2 * p.x - p'.x) * l */ + sp_1024_mont_mul_32(p->y, ty, l, p1024_mod, p1024_mp_mod); + /* py' = (p.y^2 * p.x - p'.x) * l * 2 */ + sp_1024_mont_dbl_32(p->y, p->y, p1024_mod); + /* py' = (p.y^2 * p.x - p'.x) * l * 2 - p.y^4 */ + sp_1024_mont_sub_32(p->y, p->y, t1, p1024_mod); + } + + /* p'.y = py' / 2 */ + sp_1024_div2_32(p->y, p->y, p1024_mod); +} + +/* Operations to perform based on order - 1. + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * Pairs: #dbls, add/subtract window value + */ +static const signed char sp_1024_order_op[] = { + 5, 6, -13, 9, -21, 6, -5, 8, 31, 6, 3, 6, -27, 6, 25, 9, + -1, 6, -11, 6, -13, 6, -7, 6, -15, 6, -29, 7, 25, 6, -9, 6, + -19, 7, 3, 6, 11, 9, -23, 6, 1, 6, 27, 6, 1, 7, -25, 8, + 13, 7, -13, 7, -23, 10, 19, 7, 7, 7, -3, 7, 27, 6, -7, 7, + -21, 7, 11, 7, 31, 8, 1, 7, -23, 6, -17, 6, -3, 10, 11, 6, + -21, 7, -27, 11, -29, 6, -1, 10, 15, 8, 27, 7, 17, 6, 17, 7, + -13, 8, 13, 6, 21, 7, -29, 6, 19, 7, -25, 6, 11, 9, 29, 7, + -7, 8, 27, 7, 29, 10, -1, 8, -7, 8, 17, 6, 17, 7, -27, 7, + -21, 6, -9, 6, -27, 12, -23, 6, 19, 6, 13, 6, -11, 7, 27, 6, + 17, 6, -7, 6, -25, 7, -29, 6, 9, 7, 7, 6, 13, 6, -25, 6, + -19, 6, 13, 6, -11, 6, 5, 8, 19, 6, -21, 8, 23, 7, 27, 6, + -13, 6, -19, 11, 29, 7, -15, 6, -9, 7, -21, 10, -3, 7, 21, 10, + 25, 6, -15, 6, -23, 6, 21, 6, 1, 6, 21, 7, -3, 6, -3, 7, + -7, 6, -23, 7, 7, 8, 15, 9, 5, 6, -11, 6, 21, 11, -27, 7, + 27, 6, -11, 6, 31, 6, -21, 6, 19, 6, -7, 8, -7, 13, -3, 6, + -7, 7, -3, 6, 1, 6, 7, 8, 19, 8, 11, 9, -9, 7, -31, 12, + 25, 6, -17, 9, -15, 7, 5, 6, 25, 7, -5, 7, -25, 6, 17, 8, + -19, 6, -13, 6, 27, 8, 1, 7, -5, 7, -1, 6, 21, 6, 3, 10, + -3, 1, +}; +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int sp_Pairing_1024(const ecc_point* pm, const ecc_point* qm, mp_int* res) +{ + int err; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit (*pre_vx)[64]; + sp_digit (*pre_vy)[64]; + sp_digit (*pre_nvy)[64]; + sp_point_1024* pre_p; +#else + sp_digit t[6 * 2 * 32]; + sp_digit vx[2 * 32]; + sp_digit vy[2 * 32]; + sp_digit pre_vx[16][64]; + sp_digit pre_vy[16][64]; + sp_digit pre_nvy[16][64]; + sp_point_1024 pre_p[16]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + int j; + + err = sp_1024_point_new_32(NULL, pd, p); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 56 * 32 * 2 + 16 * sizeof(sp_point_1024), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 32 * 2; + vy = td + 7 * 32 * 2; + pre_vx = (sp_digit(*)[64])(td + 8 * 32 * 2); + pre_vy = (sp_digit(*)[64])(td + 24 * 32 * 2); + pre_nvy = (sp_digit(*)[64])(td + 40 * 32 * 2); + pre_p = (sp_point_1024*)(td + 56 * 32 * 2); +#endif + r = vy; + + sp_1024_point_from_ecc_point_32(p, pm); + sp_1024_point_from_ecc_point_32(q, qm); + + err = sp_1024_mod_mul_norm_32(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMCPY(&pre_p[0], p, sizeof(sp_point_1024)); + XMEMSET(pre_vx[0], 0, sizeof(sp_digit) * 2 * 32); + pre_vx[0][0] = 1; + XMEMSET(pre_vy[0], 0, sizeof(sp_digit) * 2 * 32); + sp_1024_mont_sub_32(pre_nvy[0], p1024_mod, pre_vy[0], p1024_mod); + + /* [2]P for adding */ + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 32); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 32); + sp_1024_accumulate_line_dbl_32(vx, vy, c, q, t); + + /* 3, 5, ... */ + for (i = 1; i < 16; i++) { + XMEMCPY(&pre_p[i], &pre_p[i-1], sizeof(sp_point_1024)); + XMEMCPY(pre_vx[i], pre_vx[i-1], sizeof(sp_digit) * 2 * 32); + XMEMCPY(pre_vy[i], pre_vy[i-1], sizeof(sp_digit) * 2 * 32); + sp_1024_proj_mul_32(pre_vx[i], pre_vy[i], vx, vy, t); + sp_1024_accumulate_line_add_n_32(pre_vx[i], pre_vy[i], c, + q, &pre_p[i], t, 0); + sp_1024_mont_sub_32(pre_nvy[i], p1024_mod, pre_vy[i], p1024_mod); + } + + j = sp_1024_order_op[0] / 2; + XMEMCPY(c, &pre_p[j], sizeof(sp_point_1024)); + XMEMCPY(vx, pre_vx[j], sizeof(sp_digit) * 2 * 32); + XMEMCPY(vy, pre_vy[j], sizeof(sp_digit) * 2 * 32); + + /* Accumulate line into v and double point n times. */ + sp_1024_accumulate_line_dbl_n_32(vx, vy, c, q, + sp_1024_order_op[1], t); + + for (i = 2; i < 290; i += 2) { + j = sp_1024_order_op[i]; + if (j > 0) { + j /= 2; + /* Accumulate line into v and add P into C. */ + sp_1024_proj_mul_32(vx, vy, pre_vx[j], pre_vy[j], t); + sp_1024_accumulate_line_add_n_32(vx, vy, &pre_p[j], q, c, + t, 0); + } + else { + j = -j / 2; + /* Accumulate line into v and add P into C. */ + sp_1024_proj_mul_32(vx, vy, pre_vx[j], pre_nvy[j], t); + sp_1024_accumulate_line_add_n_32(vx, vy, &pre_p[j], q, c, + t, 1); + } + + /* Accumulate line into v and double point n times. */ + sp_1024_accumulate_line_dbl_n_32(vx, vy, c, q, + sp_1024_order_op[i + 1], t); + } + + /* Final exponentiation */ + sp_1024_proj_sqr_32(vx, vy, t); + sp_1024_proj_sqr_32(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_32(vx, vx, t); + sp_1024_mont_mul_32(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 32, 0, sizeof(sp_digit) * 32); + sp_1024_mont_reduce_32(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_32(c, 1, NULL); + sp_1024_point_free_32(q, 1, NULL); + sp_1024_point_free_32(p, 1, NULL); + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* + * Generate table for pairing. + * + * Small implementation does not use a table - returns 0 length. + * + * pm [in] Point to generate table for. + * table [in] Generated table. + * len [in,out] On in, the size of the buffer. + * On out, length of table generated. + * @return 0 on success. + * LENGTH_ONLY_E when table is NULL and only length returned. + * BUFFER_E when len is too small. + */ +int sp_Pairing_gen_precomp_1024(const ecc_point* pm, byte* table, + word32* len) +{ + int err = 0; + + if (table == NULL) { + *len = 0; + err = LENGTH_ONLY_E; + } + else if (*len != 0) { + err = BUFFER_E; + } + + (void)*pm; + + return err; +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Small implementation does not use a table - use the normal implementation. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @param [in] table Precomputed table of values. + * @param [in] len Length of precomputed table of values in bytes. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int sp_Pairing_precomp_1024(const ecc_point* pm, const ecc_point* qm, + mp_int* res, const byte* table, word32 len) +{ + (void)table; + (void)len; + return sp_Pairing_1024(pm, qm, res); +} + +#else +/* + * Calc l and c for the point when doubling p. + * + * l = 3 * (p.x^2 - 1) / (2 * p.y) + * c = l * p.x - p.y + * + * @param [out] lr Gradient result - table entry. + * @param [out] cr Constant result - table entry. + * @param [in] px X-ordinate of point to double. + * @param [in] py Y-ordinate of point to double. + * @param [in] t SP temporaries (3 used). + */ +static void sp_1024_accum_dbl_calc_lc_32(sp_digit* lr, sp_digit* cr, + const sp_digit* px, const sp_digit* py, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 2 * 32; + sp_digit* t2 = t + 2 * 2 * 32; + sp_digit* l = t + 4 * 2 * 32; + + + /* l = 1 / 2 * p.y */ + sp_1024_mont_dbl_32(l, py, p1024_mod); + sp_1024_mont_inv_32(l, l, t); + + /* t1 = p.x^2 */ + sp_1024_mont_sqr_32(t1, px, p1024_mod, p1024_mp_mod); + /* t1 = p.x - 1 */ + sp_1024_mont_sub_32(t1, t1, p1024_norm_mod, p1024_mod); + /* t1 = 3 * (p.x^2 - 1) */ + sp_1024_mont_dbl_32(t2, t1, p1024_mod); + sp_1024_mont_add_32(t1, t1, t2, p1024_mod); + /* t1 = 3 * (p.x^2 - 1) / (2 * p.y) */ + sp_1024_mont_mul_32(l, l, t1, p1024_mod, p1024_mp_mod); + /* t2 = l * p.x */ + sp_1024_mont_mul_32(t2, l, px, p1024_mod, p1024_mp_mod); + /* c = t2 = l * p.x - p.y */ + sp_1024_mont_sub_32(t2, t2, py, p1024_mod); + + XMEMCPY(lr, l, sizeof(sp_digit) * 32); + XMEMCPY(cr, t2, sizeof(sp_digit) * 32); +} + +/* + * Calc l and c when adding p and c. + * + * l = (c.y - p.y) / (c.x - p.x) + * c = (p.x * c.y - cx * p.y) / (cx - p.x) + * + * @param [out] lr Gradient result - table entry. + * @param [out] cr Constant result - table entry. + * @param [in] px X-ordinate of point to add. + * @param [in] py Y-ordinate of point to add. + * @param [in] cx X-ordinate of current point. + * @param [in] cy Y-ordinate of current point. + * @param [in] t SP temporaries (3 used). + */ +static void sp_1024_accum_add_calc_lc_32(sp_digit* lr, sp_digit* cr, + const sp_digit* px, const sp_digit* py, const sp_digit* cx, + const sp_digit* cy, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 2 * 32; + sp_digit* c = t + 2 * 2 * 32; + sp_digit* l = t + 4 * 2 * 32; + + + /* l = 1 / (c.x - p.x) */ + sp_1024_mont_sub_32(l, cx, px, p1024_mod); + sp_1024_mont_inv_32(l, l, t); + + /* c = p.x * c.y */ + sp_1024_mont_mul_32(c, px, cy, p1024_mod, p1024_mp_mod); + /* t1 = c.x * p.y */ + sp_1024_mont_mul_32(t1, cx, py, p1024_mod, p1024_mp_mod); + /* c = (p.x * c.y) - (c.x * p.y) */ + sp_1024_mont_sub_32(c, c, t1, p1024_mod); + /* c = ((p.x * c.y) - (c.x * p.y)) / (c.x - p.x) */ + sp_1024_mont_mul_32(c, c, l, p1024_mod, p1024_mp_mod); + /* t1 = c.y - p.y */ + sp_1024_mont_sub_32(t1, cy, py, p1024_mod); + /* l = (c.y - p.y) / (c.x - p.x) */ + sp_1024_mont_mul_32(l, t1, l, p1024_mod, p1024_mp_mod); + + XMEMCPY(lr, l, sizeof(sp_digit) * 32); + XMEMCPY(cr, c, sizeof(sp_digit) * 32); +} + +/* + * Calculate vx and vy given gradient l and constant c and point q. + * + * l is a the gradient and is multiplied by q->x. + * c is a the constant that is added to the multiplicative result. + * q->y is the y-ordinate in result to multiply. + * + * if dbl + * v* = v*^2 + * r.x = l * q.x + c + * r.y = q->y + * v* = v* * r* + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in] l Gradient to multiply with. + * @param [in] c Constant to add with. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] t SP temporaries (3 used). + * @param [in] dbl Indicates whether this is for doubling. Otherwise + * adding. + */ +static void sp_1024_accumulate_line_lc_32(sp_digit* vx, sp_digit* vy, + const sp_digit* l, const sp_digit* c, const sp_point_1024* q, + sp_digit* t, int dbl) +{ + sp_digit* rx = t + 4 * 2 * 32; + + /* v = v^2 */ + if (dbl) { + sp_1024_proj_sqr_32(vx, vy, t); + } + /* rx = l * q.x + c */ + sp_1024_mont_mul_32(rx, l, q->x, p1024_mod, p1024_mp_mod); + sp_1024_mont_add_32(rx, rx, c, p1024_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_32(vx, vy, rx, q->y, t); +} + +/* Operations to perform based on order - 1. + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * Pairs: #dbls, add/subtract window value + */ +static const signed char sp_1024_order_op_pre[] = { + 5, 6, -13, 9, -21, 6, -5, 8, 31, 6, 3, 6, -27, 6, 25, 9, + -1, 6, -11, 6, -13, 6, -7, 6, -15, 6, -29, 7, 25, 6, -9, 6, + -19, 7, 3, 6, 11, 9, -23, 6, 1, 6, 27, 6, 1, 7, -25, 8, + 13, 7, -13, 7, -23, 10, 19, 7, 7, 7, -3, 7, 27, 6, -7, 7, + -21, 7, 11, 7, 31, 8, 1, 7, -23, 6, -17, 6, -3, 10, 11, 6, + -21, 7, -27, 11, -29, 6, -1, 10, 15, 8, 27, 7, 17, 6, 17, 7, + -13, 8, 13, 6, 21, 7, -29, 6, 19, 7, -25, 6, 11, 9, 29, 7, + -7, 8, 27, 7, 29, 10, -1, 8, -7, 8, 17, 6, 17, 7, -27, 7, + -21, 6, -9, 6, -27, 12, -23, 6, 19, 6, 13, 6, -11, 7, 27, 6, + 17, 6, -7, 6, -25, 7, -29, 6, 9, 7, 7, 6, 13, 6, -25, 6, + -19, 6, 13, 6, -11, 6, 5, 8, 19, 6, -21, 8, 23, 7, 27, 6, + -13, 6, -19, 11, 29, 7, -15, 6, -9, 7, -21, 10, -3, 7, 21, 10, + 25, 6, -15, 6, -23, 6, 21, 6, 1, 6, 21, 7, -3, 6, -3, 7, + -7, 6, -23, 7, 7, 8, 15, 9, 5, 6, -11, 6, 21, 11, -27, 7, + 27, 6, -11, 6, 31, 6, -21, 6, 19, 6, -7, 8, -7, 13, -3, 6, + -7, 7, -3, 6, 1, 6, 7, 8, 19, 8, 11, 9, -9, 7, -31, 12, + 25, 6, -17, 9, -15, 7, 5, 6, 25, 7, -5, 7, -25, 6, 17, 8, + -19, 6, -13, 6, 27, 8, 1, 7, -5, 7, -1, 6, 21, 6, 3, 10, + -3, 1, +}; + +/* + * Generate table for pairing. + * + * Calculate the graident (l) and constant (c) at each step of the way. + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * + * pm [in] Point to generate table for. + * table [in] Generated table. + * len [in,out] On in, the size of the buffer. + * On out, length of table generated. + * @return 0 on success. + * LENGTH_ONLY_E when table is NULL and only length returned. + * BUFFER_E when len is too small. + * MEMORY_E when dynamic memory allocation fauls. + */ +int sp_Pairing_gen_precomp_1024(const ecc_point* pm, byte* table, + word32* len) +{ + int err = 0; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_point_1024* pre_p; +#else + sp_digit t[6 * 2 * 32]; + sp_point_1024 pre_p[16]; + sp_point_1024 pd; + sp_point_1024 cd; + sp_point_1024 negd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* c = NULL; + sp_point_1024* neg = NULL; + int i; + int j; + int k; + sp_table_entry_1024* precomp = (sp_table_entry_1024*)table; + + if (table == NULL) { + *len = sizeof(sp_table_entry_1024) * 1167; + err = LENGTH_ONLY_E; + } + + if ((err == MP_OKAY) && + (*len < (int)(sizeof(sp_table_entry_1024) * 1167))) { + err = BUFFER_E; + } + + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, pd, p); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, cd, c); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, negd, neg); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6 * 32 * 2 + 16 * sizeof(sp_point_1024), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + pre_p = (sp_point_1024*)(td + 6 * 32 * 2); +#endif + + sp_1024_point_from_ecc_point_32(p, pm); + + err = sp_1024_mod_mul_norm_32(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(p->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + neg->infinity = 0; + c->infinity = 0; + + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMCPY(&pre_p[0], p, sizeof(sp_point_1024)); + /* [2]P for adding */ + sp_1024_proj_point_dbl_32(c, p, t); + + /* 1, 3, ... */ + for (i = 1; i < 16; i++) { + sp_1024_proj_point_add_32(&pre_p[i], &pre_p[i-1], c, t); + sp_1024_mont_map_32(&pre_p[i], t); + } + + k = 0; + j = sp_1024_order_op_pre[0] / 2; + XMEMCPY(c, &pre_p[j], sizeof(sp_point_1024)); + + for (j = 0; j < sp_1024_order_op_pre[1]; j++) { + sp_1024_accum_dbl_calc_lc_32(precomp[k].x, precomp[k].y, c->x, c->y, t); + k++; + sp_1024_proj_point_dbl_32(c, c, t); + sp_1024_mont_map_32(c, t); + } + + for (i = 2; i < 290; i += 2) { + j = sp_1024_order_op_pre[i]; + if (j > 0) { + sp_1024_accum_add_calc_lc_32(precomp[k].x, precomp[k].y, + pre_p[j/2].x, pre_p[j/2].y, c->x, c->y, t); + k++; + sp_1024_proj_point_add_32(c, c, &pre_p[j/2], t); + sp_1024_mont_map_32(c, t); + } + else { + XMEMCPY(neg->x, pre_p[-j / 2].x, sizeof(pre_p->x)); + sp_1024_mont_sub_32(neg->y, p1024_mod, pre_p[-j / 2].y, + p1024_mod); + XMEMCPY(neg->z, pre_p[-j / 2].z, sizeof(pre_p->z)); + + sp_1024_accum_add_calc_lc_32(precomp[k].x, precomp[k].y, + neg->x, neg->y, c->x, c->y, t); + k++; + sp_1024_proj_point_add_32(c, c, neg, t); + sp_1024_mont_map_32(c, t); + } + + for (j = 0; j < sp_1024_order_op_pre[i + 1]; j++) { + sp_1024_accum_dbl_calc_lc_32(precomp[k].x, precomp[k].y, c->x, c->y, t); + k++; + sp_1024_proj_point_dbl_32(c, c, t); + sp_1024_mont_map_32(c, t); + } + } + + *len = sizeof(sp_table_entry_1024) * 1167; + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_32(neg, 1, NULL); + sp_1024_point_free_32(c, 1, NULL); + sp_1024_point_free_32(p, 1, NULL); + return err; +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * Pre-generate values in window (1, 3, ...) - only V. + * Table contains all gradient l and a constant for each point on the path. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @param [in] table Precomputed table of values. + * @param [in] len Length of precomputed table of values in bytes. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int sp_Pairing_precomp_1024(const ecc_point* pm, const ecc_point* qm, + mp_int* res, const byte* table, word32 len) +{ + int err = 0; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit (*pre_vx)[64]; + sp_digit (*pre_vy)[64]; + sp_digit (*pre_nvy)[64]; +#else + sp_digit t[6 * 2 * 32]; + sp_digit vx[2 * 32]; + sp_digit vy[2 * 32]; + sp_digit pre_vx[16][64]; + sp_digit pre_vy[16][64]; + sp_digit pre_nvy[16][64]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + int j; + int k; + const sp_table_entry_1024* precomp = (const sp_table_entry_1024*)table; + + if (len < (int)(sizeof(sp_table_entry_1024) * 1167)) { + err = BUFFER_E; + } + + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, pd, p); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 56 * 32 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 32 * 2; + vy = td + 7 * 32 * 2; + pre_vx = (sp_digit(*)[64])(td + 8 * 32 * 2); + pre_vy = (sp_digit(*)[64])(td + 24 * 32 * 2); + pre_nvy = (sp_digit(*)[64])(td + 40 * 32 * 2); +#endif + r = vy; + + sp_1024_point_from_ecc_point_32(p, pm); + sp_1024_point_from_ecc_point_32(q, qm); + + err = sp_1024_mod_mul_norm_32(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMSET(pre_vx[0], 0, sizeof(sp_digit) * 2 * 32); + pre_vx[0][0] = 1; + XMEMSET(pre_vy[0], 0, sizeof(sp_digit) * 2 * 32); + sp_1024_mont_sub_32(pre_nvy[0], p1024_mod, pre_vy[0], p1024_mod); + + /* [2]P for adding */ + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 32); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 32); + sp_1024_accumulate_line_dbl_32(vx, vy, c, q, t); + + /* 3, 5, ... */ + for (i = 1; i < 16; i++) { + XMEMCPY(pre_vx[i], pre_vx[i-1], sizeof(sp_digit) * 2 * 32); + XMEMCPY(pre_vy[i], pre_vy[i-1], sizeof(sp_digit) * 2 * 32); + sp_1024_proj_mul_32(pre_vx[i], pre_vy[i], vx, vy, t); + sp_1024_accumulate_line_add_n_32(pre_vx[i], pre_vy[i], c, + q, p, t, 0); + sp_1024_mont_sub_32(pre_nvy[i], p1024_mod, pre_vy[i], + p1024_mod); + } + + XMEMCPY(c->z, p1024_norm_mod, sizeof(sp_digit) * 32); + c->infinity = 0; + j = sp_1024_order_op_pre[0] / 2; + XMEMCPY(vx, pre_vx[j], sizeof(sp_digit) * 2 * 32); + XMEMCPY(vy, pre_vy[j], sizeof(sp_digit) * 2 * 32); + + k = 0; + for (j = 0; j < sp_1024_order_op_pre[1]; j++) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_lc_32(vx, vy, precomp[k].x, + precomp[k].y, q, t, 1); + k++; + } + + for (i = 2; i < 290; i += 2) { + sp_1024_accumulate_line_lc_32(vx, vy, precomp[k].x, + precomp[k].y, q, t, 0); + k++; + + j = sp_1024_order_op_pre[i]; + if (j > 0) { + j /= 2; + /* Accumulate line into v. */ + sp_1024_proj_mul_32(vx, vy, pre_vx[j], pre_vy[j], t); + } + else { + j = -j / 2; + /* Accumulate line into v. */ + sp_1024_proj_mul_32(vx, vy, pre_vx[j], pre_nvy[j], t); + } + + for (j = 0; j < sp_1024_order_op_pre[i + 1]; j++) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_lc_32(vx, vy, precomp[k].x, + precomp[k].y, q, t, 1); + k++; + } + } + + /* Final exponentiation */ + sp_1024_proj_sqr_32(vx, vy, t); + sp_1024_proj_sqr_32(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_32(vx, vx, t); + sp_1024_mont_mul_32(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 32, 0, sizeof(sp_digit) * 32); + sp_1024_mont_reduce_32(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_32(c, 1, NULL); + sp_1024_point_free_32(q, 1, NULL); + sp_1024_point_free_32(p, 1, NULL); + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Returns 1 if the number of zero. + * Implementation is constant time. + * + * a Number to check. + * returns 1 if the number is zero and 0 otherwise. + */ +static int sp_1024_iszero_32(const sp_digit* a) +{ + return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6] | a[7] | + a[8] | a[9] | a[10] | a[11] | a[12] | a[13] | a[14] | a[15] | + a[16] | a[17] | a[18] | a[19] | a[20] | a[21] | a[22] | a[23] | + a[24] | a[25] | a[26] | a[27] | a[28] | a[29] | a[30] | a[31]) == 0; +} + +#ifdef HAVE_ECC_CHECK_KEY +/* Read big endian unsigned byte array into r. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a Byte array. + * n Number of bytes in array to read. + */ +static void sp_1024_from_bin(sp_digit* r, int size, const byte* a, int n) +{ + int i; + int j = 0; + word32 s = 0; + + r[0] = 0; + for (i = n-1; i >= 0; i--) { + r[j] |= (((sp_digit)a[i]) << s); + if (s >= 24U) { + r[j] &= 0xffffffff; + s = 32U - s; + if (j + 1 >= size) { + break; + } + r[++j] = (sp_digit)a[i] >> s; + s = 8U - s; + } + else { + s += 8U; + } + } + + for (j++; j < size; j++) { + r[j] = 0; + } +} + +/* Check that the x and y oridinates are a valid point on the curve. + * + * point EC point. + * heap Heap to use if dynamically allocating. + * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is + * not on the curve and MP_OKAY otherwise. + */ +static int sp_1024_ecc_is_point_32(const sp_point_1024* point, + void* heap) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* d = NULL; +#else + sp_digit t1d[2*32]; + sp_digit t2d[2*32]; +#endif + sp_digit* t1; + sp_digit* t2; + int32_t n; + int err = MP_OKAY; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 4, heap, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + (void)heap; + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t1 = d + 0 * 32; + t2 = d + 2 * 32; +#else + t1 = t1d; + t2 = t2d; +#endif + + sp_1024_sqr_32(t1, point->y); + (void)sp_1024_mod_32(t1, t1, p1024_mod); + sp_1024_sqr_32(t2, point->x); + (void)sp_1024_mod_32(t2, t2, p1024_mod); + sp_1024_mul_32(t2, t2, point->x); + (void)sp_1024_mod_32(t2, t2, p1024_mod); + (void)sp_1024_sub_32(t2, p1024_mod, t2); + sp_1024_mont_add_32(t1, t1, t2, p1024_mod); + + sp_1024_mont_add_32(t1, t1, point->x, p1024_mod); + sp_1024_mont_add_32(t1, t1, point->x, p1024_mod); + sp_1024_mont_add_32(t1, t1, point->x, p1024_mod); + + n = sp_1024_cmp_32(t1, p1024_mod); + sp_1024_cond_sub_32(t1, t1, p1024_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_32(t1); + if (!sp_1024_iszero_32(t1)) { + err = MP_VAL; + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (d != NULL) { + XFREE(d, heap, DYNAMIC_TYPE_ECC); + } +#endif + + return err; +} + +/* Check that the x and y oridinates are a valid point on the curve. + * + * pX X ordinate of EC point. + * pY Y ordinate of EC point. + * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is + * not on the curve and MP_OKAY otherwise. + */ +int sp_ecc_is_point_1024(const mp_int* pX, const mp_int* pY) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 pubd; +#endif + sp_point_1024* pub; + byte one[1] = { 1 }; + int err; + + err = sp_1024_point_new_32(NULL, pubd, pub); + if (err == MP_OKAY) { + sp_1024_from_mp(pub->x, 32, pX); + sp_1024_from_mp(pub->y, 32, pY); + sp_1024_from_bin(pub->z, 32, one, (int)sizeof(one)); + + err = sp_1024_ecc_is_point_32(pub, NULL); + } + + sp_1024_point_free_32(pub, 0, NULL); + + return err; +} + +/* Check that the private scalar generates the EC point (px, py), the point is + * on the curve and the point has the correct order. + * + * pX X ordinate of EC point. + * pY Y ordinate of EC point. + * privm Private scalar that generates EC point. + * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is + * not on the curve, ECC_INF_E if the point does not have the correct order, + * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and + * MP_OKAY otherwise. + */ +int sp_ecc_check_key_1024(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_digit privd[32]; + sp_point_1024 pubd; + sp_point_1024 pd; +#endif + sp_digit* priv = NULL; + sp_point_1024* pub; + sp_point_1024* p = NULL; + byte one[1] = { 1 }; + int err; + + err = sp_1024_point_new_32(heap, pubd, pub); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, pd, p); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY && privm) { + priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32, heap, + DYNAMIC_TYPE_ECC); + if (priv == NULL) { + err = MEMORY_E; + } + } +#endif + + /* Quick check the lengs of public key ordinates and private key are in + * range. Proper check later. + */ + if ((err == MP_OKAY) && ((mp_count_bits(pX) > 1024) || + (mp_count_bits(pY) > 1024) || + ((privm != NULL) && (mp_count_bits(privm) > 1024)))) { + err = ECC_OUT_OF_RANGE_E; + } + + if (err == MP_OKAY) { +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + priv = privd; +#endif + + sp_1024_from_mp(pub->x, 32, pX); + sp_1024_from_mp(pub->y, 32, pY); + sp_1024_from_bin(pub->z, 32, one, (int)sizeof(one)); + if (privm) + sp_1024_from_mp(priv, 32, privm); + + /* Check point at infinitiy. */ + if ((sp_1024_iszero_32(pub->x) != 0) && + (sp_1024_iszero_32(pub->y) != 0)) { + err = ECC_INF_E; + } + } + + /* Check range of X and Y */ + if ((err == MP_OKAY) && + ((sp_1024_cmp_32(pub->x, p1024_mod) >= 0) || + (sp_1024_cmp_32(pub->y, p1024_mod) >= 0))) { + err = ECC_OUT_OF_RANGE_E; + } + + if (err == MP_OKAY) { + /* Check point is on curve */ + err = sp_1024_ecc_is_point_32(pub, heap); + } + + if (err == MP_OKAY) { + /* Point * order = infinity */ + err = sp_1024_ecc_mulmod_32(p, pub, p1024_order, 1, 1, heap); + } + /* Check result is infinity */ + if ((err == MP_OKAY) && ((sp_1024_iszero_32(p->x) == 0) || + (sp_1024_iszero_32(p->y) == 0))) { + err = ECC_INF_E; + } + + if (privm) { + if (err == MP_OKAY) { + /* Base * private = point */ + err = sp_1024_ecc_mulmod_base_32(p, priv, 1, 1, heap); + } + /* Check result is public key */ + if ((err == MP_OKAY) && + ((sp_1024_cmp_32(p->x, pub->x) != 0) || + (sp_1024_cmp_32(p->y, pub->y) != 0))) { + err = ECC_PRIV_KEY_E; + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (priv != NULL) { + XFREE(priv, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_32(p, 0, heap); + sp_1024_point_free_32(pub, 0, heap); + + return err; +} +#endif +#endif /* WOLFSSL_SP_1024 */ #endif /* WOLFSSL_HAVE_SP_ECC */ #endif /* WOLFSSL_SP_ARM_THUMB_ASM */ -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH || WOLFSSL_HAVE_SP_ECC */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH | WOLFSSL_HAVE_SP_ECC */ diff --git a/wolfcrypt/src/sp_c32.c b/wolfcrypt/src/sp_c32.c index 6abd9a64f..890e1006f 100644 --- a/wolfcrypt/src/sp_c32.c +++ b/wolfcrypt/src/sp_c32.c @@ -1,6 +1,6 @@ /* sp.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -75,7 +75,8 @@ static const size_t addr_mask[2] = { 0, (size_t)-1 }; */ static void sp_2048_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -117,7 +118,8 @@ static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 23 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -151,7 +153,9 @@ static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -190,7 +194,10 @@ static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a) */ static void sp_2048_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; for (i=0; i<89; i++) { r[i+1] += r[i] >> 23; @@ -1011,7 +1018,9 @@ SP_NOINLINE static int sp_2048_sub_90(sp_digit* r, const sp_digit* a, SP_NOINLINE static void sp_2048_mul_90(sp_digit* r, const sp_digit* a, const sp_digit* b) { - int i, j, k; + int i; + int j; + int k; int64_t c; c = ((int64_t)a[89]) * b[89]; @@ -1043,7 +1052,9 @@ SP_NOINLINE static void sp_2048_mul_90(sp_digit* r, const sp_digit* a, */ SP_NOINLINE static void sp_2048_sqr_90(sp_digit* r, const sp_digit* a) { - int i, j, k; + int i; + int j; + int k; int64_t c; c = ((int64_t)a[89]) * a[89]; @@ -1154,7 +1165,9 @@ SP_NOINLINE static int sp_2048_sub_45(sp_digit* r, const sp_digit* a, SP_NOINLINE static void sp_2048_mul_45(sp_digit* r, const sp_digit* a, const sp_digit* b) { - int i, j, k; + int i; + int j; + int k; int64_t c; c = ((int64_t)a[44]) * b[44]; @@ -1186,7 +1199,9 @@ SP_NOINLINE static void sp_2048_mul_45(sp_digit* r, const sp_digit* a, */ SP_NOINLINE static void sp_2048_sqr_45(sp_digit* r, const sp_digit* a) { - int i, j, k; + int i; + int j; + int k; int64_t c; c = ((int64_t)a[44]) * a[44]; @@ -1216,7 +1231,7 @@ SP_NOINLINE static void sp_2048_sqr_45(sp_digit* r, const sp_digit* a) } #endif /* WOLFSSL_SP_SMALL */ -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ /* Caclulate the bottom digit of -1/a mod 2^n. * @@ -1225,7 +1240,8 @@ SP_NOINLINE static void sp_2048_sqr_45(sp_digit* r, const sp_digit* a) */ static void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho) { - sp_digit x, b; + sp_digit x; + sp_digit b; b = a[0]; x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ @@ -1571,7 +1587,6 @@ static void sp_2048_mont_reduce_45(sp_digit* a, const sp_digit* m, sp_digit mp) sp_2048_mul_add_45(a+i, m, mu); a[i+1] += a[i] >> 23; a[i] &= 0x7fffff; - sp_2048_mont_shift_45(a, a); sp_2048_cond_sub_45(a, a, m, 0 - (((a[44] >> 12) > 0) ? (sp_digit)1 : (sp_digit)0)); @@ -1587,8 +1602,8 @@ static void sp_2048_mont_reduce_45(sp_digit* a, const sp_digit* m, sp_digit mp) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_mul_45(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_2048_mont_mul_45(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_2048_mul_45(r, a, b); sp_2048_mont_reduce_45(r, m, mp); @@ -1601,8 +1616,8 @@ static void sp_2048_mont_mul_45(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_sqr_45(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_2048_mont_sqr_45(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_2048_sqr_45(r, a); sp_2048_mont_reduce_45(r, m, mp); @@ -1702,26 +1717,8 @@ static void sp_2048_cond_add_45(sp_digit* r, const sp_digit* a, #endif /* WOLFSSL_SP_SMALL */ } -#ifdef WOLFSSL_SMALL -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_2048_add_45(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 45; i++) { - r[i] = a[i] + b[i]; - } - - return 0; -} -#endif -SP_NOINLINE static void sp_2048_rshift_45(sp_digit* r, sp_digit* a, byte n) +SP_NOINLINE static void sp_2048_rshift_45(sp_digit* r, const sp_digit* a, + byte n) { int i; @@ -1731,19 +1728,19 @@ SP_NOINLINE static void sp_2048_rshift_45(sp_digit* r, sp_digit* a, byte n) } #else for (i=0; i<40; i += 8) { - r[i+0] = ((a[i+0] >> n) | (a[i+1] << (23 - n))) & 0x7fffff; - r[i+1] = ((a[i+1] >> n) | (a[i+2] << (23 - n))) & 0x7fffff; - r[i+2] = ((a[i+2] >> n) | (a[i+3] << (23 - n))) & 0x7fffff; - r[i+3] = ((a[i+3] >> n) | (a[i+4] << (23 - n))) & 0x7fffff; - r[i+4] = ((a[i+4] >> n) | (a[i+5] << (23 - n))) & 0x7fffff; - r[i+5] = ((a[i+5] >> n) | (a[i+6] << (23 - n))) & 0x7fffff; - r[i+6] = ((a[i+6] >> n) | (a[i+7] << (23 - n))) & 0x7fffff; - r[i+7] = ((a[i+7] >> n) | (a[i+8] << (23 - n))) & 0x7fffff; + r[i+0] = (a[i+0] >> n) | ((a[i+1] << (23 - n)) & 0x7fffff); + r[i+1] = (a[i+1] >> n) | ((a[i+2] << (23 - n)) & 0x7fffff); + r[i+2] = (a[i+2] >> n) | ((a[i+3] << (23 - n)) & 0x7fffff); + r[i+3] = (a[i+3] >> n) | ((a[i+4] << (23 - n)) & 0x7fffff); + r[i+4] = (a[i+4] >> n) | ((a[i+5] << (23 - n)) & 0x7fffff); + r[i+5] = (a[i+5] >> n) | ((a[i+6] << (23 - n)) & 0x7fffff); + r[i+6] = (a[i+6] >> n) | ((a[i+7] << (23 - n)) & 0x7fffff); + r[i+7] = (a[i+7] >> n) | ((a[i+8] << (23 - n)) & 0x7fffff); } - r[40] = ((a[40] >> n) | (a[41] << (23 - n))) & 0x7fffff; - r[41] = ((a[41] >> n) | (a[42] << (23 - n))) & 0x7fffff; - r[42] = ((a[42] >> n) | (a[43] << (23 - n))) & 0x7fffff; - r[43] = ((a[43] >> n) | (a[44] << (23 - n))) & 0x7fffff; + r[40] = (a[40] >> n) | ((a[41] << (23 - n)) & 0x7fffff); + r[41] = (a[41] >> n) | ((a[42] << (23 - n)) & 0x7fffff); + r[42] = (a[42] >> n) | ((a[43] << (23 - n)) & 0x7fffff); + r[43] = (a[43] >> n) | ((a[44] << (23 - n)) & 0x7fffff); #endif r[44] = a[44] >> n; } @@ -1752,7 +1749,9 @@ SP_NOINLINE static void sp_2048_rshift_45(sp_digit* r, sp_digit* a, byte n) static WC_INLINE sp_digit sp_2048_div_word_45(sp_digit d1, sp_digit d0, sp_digit dv) { - sp_digit d, r, t; + sp_digit d; + sp_digit r; + sp_digit t; /* All 23 bits from d1 and top 8 bits from d0. */ d = (d1 << 8) | (d0 >> 15); @@ -1781,24 +1780,29 @@ static WC_INLINE sp_digit sp_2048_div_word_45(sp_digit d1, sp_digit d0, /* Divide d in a and put remainder into r (m*d + r = a) * m is not calculated as it is not needed at this time. * + * Full implementation. + * * a Number to be divided. * d Number to divide with. * m Multiplier result. * r Remainder from the division. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise. */ -static int sp_2048_div_45(const sp_digit* a, const sp_digit* d, sp_digit* m, - sp_digit* r) +static int sp_2048_div_45(const sp_digit* a, const sp_digit* d, + const sp_digit* m, sp_digit* r) { int i; #ifndef WOLFSSL_SP_DIV_32 int64_t d1; #endif - sp_digit dv, r1; + sp_digit dv; + sp_digit r1; #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* td; #else - sp_digit t1d[90 + 1], t2d[45 + 1], sdd[45 + 1]; + sp_digit t1d[90 + 1]; + sp_digit t2d[45 + 1]; + sp_digit sdd[45 + 1]; #endif sp_digit* t1; sp_digit* t2; @@ -1831,18 +1835,16 @@ static int sp_2048_div_45(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_2048_mul_d_45(sd, d, 1L << 11); sp_2048_mul_d_90(t1, a, 1L << 11); dv = sd[44]; + t1[45 + 45] += t1[45 + 45 - 1] >> 23; + t1[45 + 45 - 1] &= 0x7fffff; for (i=45; i>=0; i--) { - sp_digit hi; - t1[45 + i] += t1[45 + i - 1] >> 23; - t1[45 + i - 1] &= 0x7fffff; - hi = t1[45 + i] - (t1[45 + i] == dv); #ifndef WOLFSSL_SP_DIV_32 - d1 = hi; + d1 = t1[45 + i]; d1 <<= 23; d1 += t1[45 + i - 1]; r1 = (sp_digit)(d1 / dv); #else - r1 = sp_2048_div_word_45(hi, t1[45 + i - 1], dv); + r1 = sp_2048_div_word_45(t1[45 + i], t1[45 + i - 1], dv); #endif sp_2048_mul_d_45(t2, sd, r1); @@ -1863,7 +1865,7 @@ static int sp_2048_div_45(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_2048_mul_d_45(t2, sd, r1); sp_2048_sub_45(t1, t1, t2); - XMEMCPY(r, t1, sizeof(*r) * 2U * 45U); + XMEMCPY(r, t1, sizeof(*r) * 90U); for (i=0; i<44; i++) { r[i+1] += r[i] >> 23; r[i] &= 0x7fffff; @@ -1919,7 +1921,8 @@ static int sp_2048_mod_exp_45(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if !defined(WOLFSSL_SP_NO_MALLOC) @@ -2010,7 +2013,8 @@ static int sp_2048_mod_exp_45(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #ifdef WOLFSSL_SMALL_STACK @@ -2096,12 +2100,13 @@ static int sp_2048_mod_exp_45(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit td[(32 * 90) + 90]; #endif sp_digit* t[32]; - sp_digit* rt; + sp_digit* rt = NULL; sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -2193,7 +2198,7 @@ static int sp_2048_mod_exp_45(sp_digit* r, const sp_digit* a, const sp_digit* e, n <<= 5; c -= 5; XMEMCPY(rt, t[y], sizeof(sp_digit) * 90); - for (; i>=0 || c>=5; ) { + while ((i >= 0) || (c >= 5)) { if (c < 5) { n |= e[i--] << (9 - c); c += 23; @@ -2228,7 +2233,7 @@ static int sp_2048_mod_exp_45(sp_digit* r, const sp_digit* a, const sp_digit* e, #endif } -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ /* r = 2^n mod m where n is the number of bits to reduce by. * Given m must be 2048 bits, just need to subtract. @@ -2476,7 +2481,7 @@ static void sp_2048_mont_reduce_90(sp_digit* a, const sp_digit* m, sp_digit mp) sp_2048_norm_90(a + 90); -#ifdef WOLFSSL_HAVE_SP_DH +#ifdef WOLFSSL_SP_DH if (mp != 1) { for (i=0; i<89; i++) { mu = (a[i] * mp) & 0x7fffff; @@ -2510,7 +2515,6 @@ static void sp_2048_mont_reduce_90(sp_digit* a, const sp_digit* m, sp_digit mp) a[i+1] += a[i] >> 23; a[i] &= 0x7fffff; #endif - sp_2048_mont_shift_90(a, a); sp_2048_cond_sub_90(a, a, m, 0 - (((a[89] >> 1) > 0) ? (sp_digit)1 : (sp_digit)0)); @@ -2526,8 +2530,8 @@ static void sp_2048_mont_reduce_90(sp_digit* a, const sp_digit* m, sp_digit mp) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_mul_90(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_2048_mont_mul_90(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_2048_mul_90(r, a, b); sp_2048_mont_reduce_90(r, m, mp); @@ -2540,8 +2544,8 @@ static void sp_2048_mont_mul_90(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_sqr_90(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_2048_mont_sqr_90(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_2048_sqr_90(r, a); sp_2048_mont_reduce_90(r, m, mp); @@ -2635,46 +2639,8 @@ static void sp_2048_cond_add_90(sp_digit* r, const sp_digit* a, #endif /* WOLFSSL_SP_SMALL */ } -#ifdef WOLFSSL_SMALL -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_2048_sub_90(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 90; i++) { - r[i] = a[i] - b[i]; - } - - return 0; -} - -#endif -#ifdef WOLFSSL_SMALL -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_2048_add_90(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 90; i++) { - r[i] = a[i] + b[i]; - } - - return 0; -} -#endif -SP_NOINLINE static void sp_2048_rshift_90(sp_digit* r, sp_digit* a, byte n) +SP_NOINLINE static void sp_2048_rshift_90(sp_digit* r, const sp_digit* a, + byte n) { int i; @@ -2684,16 +2650,16 @@ SP_NOINLINE static void sp_2048_rshift_90(sp_digit* r, sp_digit* a, byte n) } #else for (i=0; i<88; i += 8) { - r[i+0] = ((a[i+0] >> n) | (a[i+1] << (23 - n))) & 0x7fffff; - r[i+1] = ((a[i+1] >> n) | (a[i+2] << (23 - n))) & 0x7fffff; - r[i+2] = ((a[i+2] >> n) | (a[i+3] << (23 - n))) & 0x7fffff; - r[i+3] = ((a[i+3] >> n) | (a[i+4] << (23 - n))) & 0x7fffff; - r[i+4] = ((a[i+4] >> n) | (a[i+5] << (23 - n))) & 0x7fffff; - r[i+5] = ((a[i+5] >> n) | (a[i+6] << (23 - n))) & 0x7fffff; - r[i+6] = ((a[i+6] >> n) | (a[i+7] << (23 - n))) & 0x7fffff; - r[i+7] = ((a[i+7] >> n) | (a[i+8] << (23 - n))) & 0x7fffff; + r[i+0] = (a[i+0] >> n) | ((a[i+1] << (23 - n)) & 0x7fffff); + r[i+1] = (a[i+1] >> n) | ((a[i+2] << (23 - n)) & 0x7fffff); + r[i+2] = (a[i+2] >> n) | ((a[i+3] << (23 - n)) & 0x7fffff); + r[i+3] = (a[i+3] >> n) | ((a[i+4] << (23 - n)) & 0x7fffff); + r[i+4] = (a[i+4] >> n) | ((a[i+5] << (23 - n)) & 0x7fffff); + r[i+5] = (a[i+5] >> n) | ((a[i+6] << (23 - n)) & 0x7fffff); + r[i+6] = (a[i+6] >> n) | ((a[i+7] << (23 - n)) & 0x7fffff); + r[i+7] = (a[i+7] >> n) | ((a[i+8] << (23 - n)) & 0x7fffff); } - r[88] = ((a[88] >> n) | (a[89] << (23 - n))) & 0x7fffff; + r[88] = (a[88] >> n) | ((a[89] << (23 - n)) & 0x7fffff); #endif r[89] = a[89] >> n; } @@ -2702,7 +2668,9 @@ SP_NOINLINE static void sp_2048_rshift_90(sp_digit* r, sp_digit* a, byte n) static WC_INLINE sp_digit sp_2048_div_word_90(sp_digit d1, sp_digit d0, sp_digit dv) { - sp_digit d, r, t; + sp_digit d; + sp_digit r; + sp_digit t; /* All 23 bits from d1 and top 8 bits from d0. */ d = (d1 << 8) | (d0 >> 15); @@ -2731,24 +2699,29 @@ static WC_INLINE sp_digit sp_2048_div_word_90(sp_digit d1, sp_digit d0, /* Divide d in a and put remainder into r (m*d + r = a) * m is not calculated as it is not needed at this time. * + * Full implementation. + * * a Number to be divided. * d Number to divide with. * m Multiplier result. * r Remainder from the division. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise. */ -static int sp_2048_div_90(const sp_digit* a, const sp_digit* d, sp_digit* m, - sp_digit* r) +static int sp_2048_div_90(const sp_digit* a, const sp_digit* d, + const sp_digit* m, sp_digit* r) { int i; #ifndef WOLFSSL_SP_DIV_32 int64_t d1; #endif - sp_digit dv, r1; + sp_digit dv; + sp_digit r1; #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* td; #else - sp_digit t1d[180 + 1], t2d[90 + 1], sdd[90 + 1]; + sp_digit t1d[180 + 1]; + sp_digit t2d[90 + 1]; + sp_digit sdd[90 + 1]; #endif sp_digit* t1; sp_digit* t2; @@ -2781,18 +2754,16 @@ static int sp_2048_div_90(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_2048_mul_d_90(sd, d, 1L << 22); sp_2048_mul_d_180(t1, a, 1L << 22); dv = sd[89]; + t1[90 + 90] += t1[90 + 90 - 1] >> 23; + t1[90 + 90 - 1] &= 0x7fffff; for (i=90; i>=0; i--) { - sp_digit hi; - t1[90 + i] += t1[90 + i - 1] >> 23; - t1[90 + i - 1] &= 0x7fffff; - hi = t1[90 + i] - (t1[90 + i] == dv); #ifndef WOLFSSL_SP_DIV_32 - d1 = hi; + d1 = t1[90 + i]; d1 <<= 23; d1 += t1[90 + i - 1]; r1 = (sp_digit)(d1 / dv); #else - r1 = sp_2048_div_word_90(hi, t1[90 + i - 1], dv); + r1 = sp_2048_div_word_90(t1[90 + i], t1[90 + i - 1], dv); #endif sp_2048_mul_d_90(t2, sd, r1); @@ -2813,7 +2784,7 @@ static int sp_2048_div_90(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_2048_mul_d_90(t2, sd, r1); sp_2048_sub_90(t1, t1, t2); - XMEMCPY(r, t1, sizeof(*r) * 2U * 90U); + XMEMCPY(r, t1, sizeof(*r) * 180U); for (i=0; i<89; i++) { r[i+1] += r[i] >> 23; r[i] &= 0x7fffff; @@ -2871,7 +2842,8 @@ static int sp_2048_mod_exp_90(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if !defined(WOLFSSL_SP_NO_MALLOC) @@ -2962,7 +2934,8 @@ static int sp_2048_mod_exp_90(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #ifdef WOLFSSL_SMALL_STACK @@ -3048,12 +3021,13 @@ static int sp_2048_mod_exp_90(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit td[(32 * 180) + 180]; #endif sp_digit* t[32]; - sp_digit* rt; + sp_digit* rt = NULL; sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -3145,7 +3119,7 @@ static int sp_2048_mod_exp_90(sp_digit* r, const sp_digit* a, const sp_digit* e, n <<= 5; c -= 5; XMEMCPY(rt, t[y], sizeof(sp_digit) * 180); - for (; i>=0 || c>=5; ) { + while ((i >= 0) || (c >= 5)) { if (c < 5) { n |= e[i--] << (9 - c); c += 23; @@ -3179,7 +3153,7 @@ static int sp_2048_mod_exp_90(sp_digit* r, const sp_digit* a, const sp_digit* e, return err; #endif } -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) || */ /* WOLFSSL_HAVE_SP_DH */ #ifdef WOLFSSL_HAVE_SP_RSA @@ -3195,15 +3169,15 @@ static int sp_2048_mod_exp_90(sp_digit* r, const sp_digit* a, const sp_digit* e, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPublic_2048(const byte* in, word32 inLen, const mp_int* em, + const mp_int* mm, byte* out, word32* outLen) { #ifdef WOLFSSL_SP_SMALL sp_digit* d = NULL; sp_digit* a = NULL; sp_digit* m = NULL; sp_digit* r = NULL; - sp_digit* norm; + sp_digit* norm = NULL; sp_digit e[1] = {0}; sp_digit mp; int i; @@ -3296,13 +3270,15 @@ int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, return err; #else #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_digit ad[180], md[90], rd[180]; + sp_digit ad[180]; + sp_digit md[90]; + sp_digit rd[180]; #else sp_digit* d = NULL; #endif - sp_digit* a; - sp_digit* m; - sp_digit* r; + sp_digit* a = NULL; + sp_digit* m = NULL; + sp_digit* r = NULL; sp_digit e[1] = {0}; int err = MP_OKAY; @@ -3420,7 +3396,7 @@ int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #ifndef WOLFSSL_RSA_PUBLIC_ONLY #if !defined(SP_RSA_PRIVATE_EXP_D) && !defined(RSA_LOW_MEM) -#endif /* !SP_RSA_PRIVATE_EXP_D && !RSA_LOW_MEM */ +#endif /* !SP_RSA_PRIVATE_EXP_D & !RSA_LOW_MEM */ /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -3438,9 +3414,9 @@ int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_2048(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM) #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -3503,7 +3479,9 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, return err; #else - sp_digit a[180], d[90], m[90]; + sp_digit a[180]; + sp_digit d[90]; + sp_digit m[90]; sp_digit* r = a; int err = MP_OKAY; @@ -3546,19 +3524,19 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, XMEMSET(d, 0, sizeof(sp_digit) * 90); return err; -#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */ +#endif /* WOLFSSL_SP_SMALL | defined(WOLFSSL_SMALL_STACK) */ #else #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* t = NULL; - sp_digit* a; - sp_digit* p; - sp_digit* q; - sp_digit* dp; - sp_digit* dq; - sp_digit* qi; - sp_digit* tmpa; - sp_digit* tmpb; - sp_digit* r; + sp_digit* a = NULL; + sp_digit* p = NULL; + sp_digit* q = NULL; + sp_digit* dp = NULL; + sp_digit* dq = NULL; + sp_digit* qi = NULL; + sp_digit* tmpa = NULL; + sp_digit* tmpb = NULL; + sp_digit* r = NULL; int err = MP_OKAY; (void)dm; @@ -3633,8 +3611,13 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, return err; #else sp_digit a[90 * 2]; - sp_digit p[45], q[45], dp[45], dq[45], qi[45]; - sp_digit tmpa[90], tmpb[90]; + sp_digit p[45]; + sp_digit q[45]; + sp_digit dp[45]; + sp_digit dq[45]; + sp_digit qi[45]; + sp_digit tmpa[90]; + sp_digit tmpb[90]; sp_digit* r = a; int err = MP_OKAY; @@ -3696,8 +3679,8 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, XMEMSET(qi, 0, sizeof(qi)); return err; -#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */ -#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */ +#endif /* WOLFSSL_SP_SMALL | defined(WOLFSSL_SMALL_STACK) */ +#endif /* SP_RSA_PRIVATE_EXP_D | RSA_LOW_MEM */ } #endif /* !WOLFSSL_RSA_PUBLIC_ONLY */ @@ -3720,17 +3703,19 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->used = 90; mp_clamp(r); #elif DIGIT_BIT < 23 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 90; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 23) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -3743,14 +3728,16 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 90; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 23 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -3777,7 +3764,8 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_2048(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { #ifdef WOLFSSL_SP_SMALL int err = MP_OKAY; @@ -3833,7 +3821,9 @@ int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) return err; #else #ifndef WOLFSSL_SMALL_STACK - sp_digit bd[180], ed[90], md[90]; + sp_digit bd[180]; + sp_digit ed[90]; + sp_digit md[90]; #else sp_digit* d = NULL; #endif @@ -3905,7 +3895,8 @@ int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) #ifdef WOLFSSL_HAVE_SP_DH #ifdef HAVE_FFDHE_2048 -SP_NOINLINE static void sp_2048_lshift_90(sp_digit* r, sp_digit* a, byte n) +SP_NOINLINE static void sp_2048_lshift_90(sp_digit* r, const sp_digit* a, + byte n) { #ifdef WOLFSSL_SP_SMALL int i; @@ -3915,7 +3906,8 @@ SP_NOINLINE static void sp_2048_lshift_90(sp_digit* r, sp_digit* a, byte n) r[i] = ((a[i] << n) | (a[i-1] >> (23 - n))) & 0x7fffff; } #else - sp_int_digit s, t; + sp_int_digit s; + sp_int_digit t; s = (sp_int_digit)a[89]; r[90] = s >> (23U - n); @@ -4119,9 +4111,11 @@ static int sp_2048_mod_exp_2_90(sp_digit* r, const sp_digit* e, int bits, const sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -4166,7 +4160,7 @@ static int sp_2048_mod_exp_2_90(sp_digit* r, const sp_digit* e, int bits, const n <<= 4; c -= 4; sp_2048_lshift_90(r, norm, (byte)y); - for (; i>=0 || c>=4; ) { + while ((i >= 0) || (c >= 4)) { if (c < 4) { n |= e[i--] << (9 - c); c += 23; @@ -4220,8 +4214,8 @@ static int sp_2048_mod_exp_2_90(sp_digit* r, const sp_digit* e, int bits, const * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, - mp_int* mod, byte* out, word32* outLen) +int sp_DhExp_2048(const mp_int* base, const byte* exp, word32 expLen, + const mp_int* mod, byte* out, word32* outLen) { #ifdef WOLFSSL_SP_SMALL int err = MP_OKAY; @@ -4288,7 +4282,9 @@ int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, return err; #else #ifndef WOLFSSL_SMALL_STACK - sp_digit bd[180], ed[90], md[90]; + sp_digit bd[180]; + sp_digit ed[90]; + sp_digit md[90]; #else sp_digit* d = NULL; #endif @@ -4353,6 +4349,7 @@ int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, sp_2048_to_bin(r, out); *outLen = 256; for (i=0; i<256U && out[i] == 0U; i++) { + /* Search for first non-zero. */ } *outLen -= i; XMEMMOVE(out, out + i, *outLen); @@ -4381,7 +4378,8 @@ int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_1024(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { #ifdef WOLFSSL_SP_SMALL int err = MP_OKAY; @@ -4438,7 +4436,9 @@ int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) return err; #else #ifndef WOLFSSL_SMALL_STACK - sp_digit bd[90], ed[45], md[45]; + sp_digit bd[90]; + sp_digit ed[45]; + sp_digit md[45]; #else sp_digit* d = NULL; #endif @@ -4508,7 +4508,7 @@ int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) #endif } -#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */ +#endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */ #endif /* !WOLFSSL_SP_NO_2048 */ @@ -4522,7 +4522,8 @@ int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) */ static void sp_3072_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -4564,7 +4565,8 @@ static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 23 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -4598,7 +4600,9 @@ static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -4637,7 +4641,10 @@ static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a) */ static void sp_3072_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; for (i=0; i<133; i++) { r[i+1] += r[i] >> 23; @@ -4680,7 +4687,8 @@ static void sp_3072_to_bin(sp_digit* r, byte* a) SP_NOINLINE static void sp_3072_mul_67(sp_digit* r, const sp_digit* a, const sp_digit* b) { - int i, j; + int i; + int j; int64_t t[134]; XMEMSET(t, 0, sizeof(t)); @@ -4703,7 +4711,8 @@ SP_NOINLINE static void sp_3072_mul_67(sp_digit* r, const sp_digit* a, */ SP_NOINLINE static void sp_3072_sqr_67(sp_digit* r, const sp_digit* a) { - int i, j; + int i; + int j; int64_t t[134]; XMEMSET(t, 0, sizeof(t)); @@ -4904,7 +4913,9 @@ SP_NOINLINE static int sp_3072_sub_134(sp_digit* r, const sp_digit* a, SP_NOINLINE static void sp_3072_mul_134(sp_digit* r, const sp_digit* a, const sp_digit* b) { - int i, j, k; + int i; + int j; + int k; int64_t c; c = ((int64_t)a[133]) * b[133]; @@ -4936,7 +4947,9 @@ SP_NOINLINE static void sp_3072_mul_134(sp_digit* r, const sp_digit* a, */ SP_NOINLINE static void sp_3072_sqr_134(sp_digit* r, const sp_digit* a) { - int i, j, k; + int i; + int j; + int k; int64_t c; c = ((int64_t)a[133]) * a[133]; @@ -5045,7 +5058,9 @@ SP_NOINLINE static int sp_3072_sub_67(sp_digit* r, const sp_digit* a, SP_NOINLINE static void sp_3072_mul_67(sp_digit* r, const sp_digit* a, const sp_digit* b) { - int i, j, k; + int i; + int j; + int k; int64_t c; c = ((int64_t)a[66]) * b[66]; @@ -5077,7 +5092,9 @@ SP_NOINLINE static void sp_3072_mul_67(sp_digit* r, const sp_digit* a, */ SP_NOINLINE static void sp_3072_sqr_67(sp_digit* r, const sp_digit* a) { - int i, j, k; + int i; + int j; + int k; int64_t c; c = ((int64_t)a[66]) * a[66]; @@ -5107,7 +5124,7 @@ SP_NOINLINE static void sp_3072_sqr_67(sp_digit* r, const sp_digit* a) } #endif /* WOLFSSL_SP_SMALL */ -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ /* Caclulate the bottom digit of -1/a mod 2^n. * @@ -5116,7 +5133,8 @@ SP_NOINLINE static void sp_3072_sqr_67(sp_digit* r, const sp_digit* a) */ static void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho) { - sp_digit x, b; + sp_digit x; + sp_digit b; b = a[0]; x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ @@ -5390,7 +5408,8 @@ static void sp_3072_mont_shift_67(sp_digit* r, const sp_digit* a) { #ifdef WOLFSSL_SP_SMALL int i; - sp_digit n, s; + sp_digit n; + sp_digit s; s = a[67]; n = a[66] >> 18; @@ -5403,7 +5422,8 @@ static void sp_3072_mont_shift_67(sp_digit* r, const sp_digit* a) n += s << 5; r[66] = n; #else - sp_digit n, s; + sp_digit n; + sp_digit s; int i; s = a[67]; n = a[66] >> 18; @@ -5456,7 +5476,6 @@ static void sp_3072_mont_reduce_67(sp_digit* a, const sp_digit* m, sp_digit mp) sp_3072_mul_add_67(a+i, m, mu); a[i+1] += a[i] >> 23; a[i] &= 0x7fffff; - sp_3072_mont_shift_67(a, a); sp_3072_cond_sub_67(a, a, m, 0 - (((a[66] >> 18) > 0) ? (sp_digit)1 : (sp_digit)0)); @@ -5472,8 +5491,8 @@ static void sp_3072_mont_reduce_67(sp_digit* a, const sp_digit* m, sp_digit mp) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_mul_67(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_3072_mont_mul_67(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_3072_mul_67(r, a, b); sp_3072_mont_reduce_67(r, m, mp); @@ -5486,8 +5505,8 @@ static void sp_3072_mont_mul_67(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_sqr_67(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_3072_mont_sqr_67(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_3072_sqr_67(r, a); sp_3072_mont_reduce_67(r, m, mp); @@ -5591,30 +5610,13 @@ static void sp_3072_cond_add_67(sp_digit* r, const sp_digit* a, #endif /* WOLFSSL_SP_SMALL */ } -#ifdef WOLFSSL_SMALL -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_3072_add_67(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 67; i++) { - r[i] = a[i] + b[i]; - } - - return 0; -} -#endif #ifdef WOLFSSL_SP_DIV_32 static WC_INLINE sp_digit sp_3072_div_word_67(sp_digit d1, sp_digit d0, sp_digit dv) { - sp_digit d, r, t; + sp_digit d; + sp_digit r; + sp_digit t; /* All 23 bits from d1 and top 8 bits from d0. */ d = (d1 << 8) | (d0 >> 15); @@ -5643,24 +5645,28 @@ static WC_INLINE sp_digit sp_3072_div_word_67(sp_digit d1, sp_digit d0, /* Divide d in a and put remainder into r (m*d + r = a) * m is not calculated as it is not needed at this time. * + * Large number of bits in last word. + * * a Number to be divided. * d Number to divide with. * m Multiplier result. * r Remainder from the division. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise. */ -static int sp_3072_div_67(const sp_digit* a, const sp_digit* d, sp_digit* m, - sp_digit* r) +static int sp_3072_div_67(const sp_digit* a, const sp_digit* d, + const sp_digit* m, sp_digit* r) { int i; #ifndef WOLFSSL_SP_DIV_32 int64_t d1; #endif - sp_digit dv, r1; + sp_digit dv; + sp_digit r1; #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* td; #else - sp_digit t1d[134], t2d[67 + 1]; + sp_digit t1d[134]; + sp_digit t2d[67 + 1]; #endif sp_digit* t1; sp_digit* t2; @@ -5688,17 +5694,15 @@ static int sp_3072_div_67(const sp_digit* a, const sp_digit* d, sp_digit* m, dv = d[66]; XMEMCPY(t1, a, sizeof(*t1) * 2U * 67U); for (i=66; i>=0; i--) { - sp_digit hi; t1[67 + i] += t1[67 + i - 1] >> 23; t1[67 + i - 1] &= 0x7fffff; - hi = t1[67 + i] - (t1[67 + i] == dv); #ifndef WOLFSSL_SP_DIV_32 - d1 = hi; + d1 = t1[67 + i]; d1 <<= 23; d1 += t1[67 + i - 1]; r1 = (sp_digit)(d1 / dv); #else - r1 = sp_3072_div_word_67(hi, t1[67 + i - 1], dv); + r1 = sp_3072_div_word_67(t1[67 + i], t1[67 + i - 1], dv); #endif sp_3072_mul_d_67(t2, d, r1); @@ -5719,7 +5723,7 @@ static int sp_3072_div_67(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_3072_mul_d_67(t2, d, r1); (void)sp_3072_sub_67(t1, t1, t2); - XMEMCPY(r, t1, sizeof(*r) * 2U * 67U); + XMEMCPY(r, t1, sizeof(*r) * 134U); for (i=0; i<66; i++) { r[i+1] += r[i] >> 23; r[i] &= 0x7fffff; @@ -5772,7 +5776,8 @@ static int sp_3072_mod_exp_67(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if !defined(WOLFSSL_SP_NO_MALLOC) @@ -5863,7 +5868,8 @@ static int sp_3072_mod_exp_67(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #ifdef WOLFSSL_SMALL_STACK @@ -5949,12 +5955,13 @@ static int sp_3072_mod_exp_67(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit td[(32 * 134) + 134]; #endif sp_digit* t[32]; - sp_digit* rt; + sp_digit* rt = NULL; sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -6046,7 +6053,7 @@ static int sp_3072_mod_exp_67(sp_digit* r, const sp_digit* a, const sp_digit* e, n <<= 5; c -= 5; XMEMCPY(rt, t[y], sizeof(sp_digit) * 134); - for (; i>=0 || c>=5; ) { + while ((i >= 0) || (c >= 5)) { if (c < 5) { n |= e[i--] << (9 - c); c += 23; @@ -6081,7 +6088,7 @@ static int sp_3072_mod_exp_67(sp_digit* r, const sp_digit* a, const sp_digit* e, #endif } -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ /* r = 2^n mod m where n is the number of bits to reduce by. * Given m must be 3072 bits, just need to subtract. @@ -6353,7 +6360,7 @@ static void sp_3072_mont_reduce_134(sp_digit* a, const sp_digit* m, sp_digit mp) sp_3072_norm_134(a + 134); -#ifdef WOLFSSL_HAVE_SP_DH +#ifdef WOLFSSL_SP_DH if (mp != 1) { for (i=0; i<133; i++) { mu = (a[i] * mp) & 0x7fffff; @@ -6387,7 +6394,6 @@ static void sp_3072_mont_reduce_134(sp_digit* a, const sp_digit* m, sp_digit mp) a[i+1] += a[i] >> 23; a[i] &= 0x7fffff; #endif - sp_3072_mont_shift_134(a, a); sp_3072_cond_sub_134(a, a, m, 0 - (((a[133] >> 13) > 0) ? (sp_digit)1 : (sp_digit)0)); @@ -6403,8 +6409,8 @@ static void sp_3072_mont_reduce_134(sp_digit* a, const sp_digit* m, sp_digit mp) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_mul_134(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_3072_mont_mul_134(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_3072_mul_134(r, a, b); sp_3072_mont_reduce_134(r, m, mp); @@ -6417,8 +6423,8 @@ static void sp_3072_mont_mul_134(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_sqr_134(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_3072_mont_sqr_134(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_3072_sqr_134(r, a); sp_3072_mont_reduce_134(r, m, mp); @@ -6516,46 +6522,8 @@ static void sp_3072_cond_add_134(sp_digit* r, const sp_digit* a, #endif /* WOLFSSL_SP_SMALL */ } -#ifdef WOLFSSL_SMALL -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_3072_sub_134(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 134; i++) { - r[i] = a[i] - b[i]; - } - - return 0; -} - -#endif -#ifdef WOLFSSL_SMALL -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_3072_add_134(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 134; i++) { - r[i] = a[i] + b[i]; - } - - return 0; -} -#endif -SP_NOINLINE static void sp_3072_rshift_134(sp_digit* r, sp_digit* a, byte n) +SP_NOINLINE static void sp_3072_rshift_134(sp_digit* r, const sp_digit* a, + byte n) { int i; @@ -6565,20 +6533,20 @@ SP_NOINLINE static void sp_3072_rshift_134(sp_digit* r, sp_digit* a, byte n) } #else for (i=0; i<128; i += 8) { - r[i+0] = ((a[i+0] >> n) | (a[i+1] << (23 - n))) & 0x7fffff; - r[i+1] = ((a[i+1] >> n) | (a[i+2] << (23 - n))) & 0x7fffff; - r[i+2] = ((a[i+2] >> n) | (a[i+3] << (23 - n))) & 0x7fffff; - r[i+3] = ((a[i+3] >> n) | (a[i+4] << (23 - n))) & 0x7fffff; - r[i+4] = ((a[i+4] >> n) | (a[i+5] << (23 - n))) & 0x7fffff; - r[i+5] = ((a[i+5] >> n) | (a[i+6] << (23 - n))) & 0x7fffff; - r[i+6] = ((a[i+6] >> n) | (a[i+7] << (23 - n))) & 0x7fffff; - r[i+7] = ((a[i+7] >> n) | (a[i+8] << (23 - n))) & 0x7fffff; + r[i+0] = (a[i+0] >> n) | ((a[i+1] << (23 - n)) & 0x7fffff); + r[i+1] = (a[i+1] >> n) | ((a[i+2] << (23 - n)) & 0x7fffff); + r[i+2] = (a[i+2] >> n) | ((a[i+3] << (23 - n)) & 0x7fffff); + r[i+3] = (a[i+3] >> n) | ((a[i+4] << (23 - n)) & 0x7fffff); + r[i+4] = (a[i+4] >> n) | ((a[i+5] << (23 - n)) & 0x7fffff); + r[i+5] = (a[i+5] >> n) | ((a[i+6] << (23 - n)) & 0x7fffff); + r[i+6] = (a[i+6] >> n) | ((a[i+7] << (23 - n)) & 0x7fffff); + r[i+7] = (a[i+7] >> n) | ((a[i+8] << (23 - n)) & 0x7fffff); } - r[128] = ((a[128] >> n) | (a[129] << (23 - n))) & 0x7fffff; - r[129] = ((a[129] >> n) | (a[130] << (23 - n))) & 0x7fffff; - r[130] = ((a[130] >> n) | (a[131] << (23 - n))) & 0x7fffff; - r[131] = ((a[131] >> n) | (a[132] << (23 - n))) & 0x7fffff; - r[132] = ((a[132] >> n) | (a[133] << (23 - n))) & 0x7fffff; + r[128] = (a[128] >> n) | ((a[129] << (23 - n)) & 0x7fffff); + r[129] = (a[129] >> n) | ((a[130] << (23 - n)) & 0x7fffff); + r[130] = (a[130] >> n) | ((a[131] << (23 - n)) & 0x7fffff); + r[131] = (a[131] >> n) | ((a[132] << (23 - n)) & 0x7fffff); + r[132] = (a[132] >> n) | ((a[133] << (23 - n)) & 0x7fffff); #endif r[133] = a[133] >> n; } @@ -6587,7 +6555,9 @@ SP_NOINLINE static void sp_3072_rshift_134(sp_digit* r, sp_digit* a, byte n) static WC_INLINE sp_digit sp_3072_div_word_134(sp_digit d1, sp_digit d0, sp_digit dv) { - sp_digit d, r, t; + sp_digit d; + sp_digit r; + sp_digit t; /* All 23 bits from d1 and top 8 bits from d0. */ d = (d1 << 8) | (d0 >> 15); @@ -6616,24 +6586,29 @@ static WC_INLINE sp_digit sp_3072_div_word_134(sp_digit d1, sp_digit d0, /* Divide d in a and put remainder into r (m*d + r = a) * m is not calculated as it is not needed at this time. * + * Full implementation. + * * a Number to be divided. * d Number to divide with. * m Multiplier result. * r Remainder from the division. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise. */ -static int sp_3072_div_134(const sp_digit* a, const sp_digit* d, sp_digit* m, - sp_digit* r) +static int sp_3072_div_134(const sp_digit* a, const sp_digit* d, + const sp_digit* m, sp_digit* r) { int i; #ifndef WOLFSSL_SP_DIV_32 int64_t d1; #endif - sp_digit dv, r1; + sp_digit dv; + sp_digit r1; #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* td; #else - sp_digit t1d[268 + 1], t2d[134 + 1], sdd[134 + 1]; + sp_digit t1d[268 + 1]; + sp_digit t2d[134 + 1]; + sp_digit sdd[134 + 1]; #endif sp_digit* t1; sp_digit* t2; @@ -6666,18 +6641,16 @@ static int sp_3072_div_134(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_3072_mul_d_134(sd, d, 1L << 10); sp_3072_mul_d_268(t1, a, 1L << 10); dv = sd[133]; + t1[134 + 134] += t1[134 + 134 - 1] >> 23; + t1[134 + 134 - 1] &= 0x7fffff; for (i=134; i>=0; i--) { - sp_digit hi; - t1[134 + i] += t1[134 + i - 1] >> 23; - t1[134 + i - 1] &= 0x7fffff; - hi = t1[134 + i] - (t1[134 + i] == dv); #ifndef WOLFSSL_SP_DIV_32 - d1 = hi; + d1 = t1[134 + i]; d1 <<= 23; d1 += t1[134 + i - 1]; r1 = (sp_digit)(d1 / dv); #else - r1 = sp_3072_div_word_134(hi, t1[134 + i - 1], dv); + r1 = sp_3072_div_word_134(t1[134 + i], t1[134 + i - 1], dv); #endif sp_3072_mul_d_134(t2, sd, r1); @@ -6698,7 +6671,7 @@ static int sp_3072_div_134(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_3072_mul_d_134(t2, sd, r1); sp_3072_sub_134(t1, t1, t2); - XMEMCPY(r, t1, sizeof(*r) * 2U * 134U); + XMEMCPY(r, t1, sizeof(*r) * 268U); for (i=0; i<133; i++) { r[i+1] += r[i] >> 23; r[i] &= 0x7fffff; @@ -6756,7 +6729,8 @@ static int sp_3072_mod_exp_134(sp_digit* r, const sp_digit* a, const sp_digit* e sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if !defined(WOLFSSL_SP_NO_MALLOC) @@ -6847,7 +6821,8 @@ static int sp_3072_mod_exp_134(sp_digit* r, const sp_digit* a, const sp_digit* e sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #ifdef WOLFSSL_SMALL_STACK @@ -6933,12 +6908,13 @@ static int sp_3072_mod_exp_134(sp_digit* r, const sp_digit* a, const sp_digit* e sp_digit td[(32 * 268) + 268]; #endif sp_digit* t[32]; - sp_digit* rt; + sp_digit* rt = NULL; sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -7030,7 +7006,7 @@ static int sp_3072_mod_exp_134(sp_digit* r, const sp_digit* a, const sp_digit* e n <<= 5; c -= 5; XMEMCPY(rt, t[y], sizeof(sp_digit) * 268); - for (; i>=0 || c>=5; ) { + while ((i >= 0) || (c >= 5)) { if (c < 5) { n |= e[i--] << (9 - c); c += 23; @@ -7064,7 +7040,7 @@ static int sp_3072_mod_exp_134(sp_digit* r, const sp_digit* a, const sp_digit* e return err; #endif } -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) || */ /* WOLFSSL_HAVE_SP_DH */ #ifdef WOLFSSL_HAVE_SP_RSA @@ -7080,15 +7056,15 @@ static int sp_3072_mod_exp_134(sp_digit* r, const sp_digit* a, const sp_digit* e * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPublic_3072(const byte* in, word32 inLen, const mp_int* em, + const mp_int* mm, byte* out, word32* outLen) { #ifdef WOLFSSL_SP_SMALL sp_digit* d = NULL; sp_digit* a = NULL; sp_digit* m = NULL; sp_digit* r = NULL; - sp_digit* norm; + sp_digit* norm = NULL; sp_digit e[1] = {0}; sp_digit mp; int i; @@ -7181,13 +7157,15 @@ int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, return err; #else #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_digit ad[268], md[134], rd[268]; + sp_digit ad[268]; + sp_digit md[134]; + sp_digit rd[268]; #else sp_digit* d = NULL; #endif - sp_digit* a; - sp_digit* m; - sp_digit* r; + sp_digit* a = NULL; + sp_digit* m = NULL; + sp_digit* r = NULL; sp_digit e[1] = {0}; int err = MP_OKAY; @@ -7305,7 +7283,7 @@ int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #ifndef WOLFSSL_RSA_PUBLIC_ONLY #if !defined(SP_RSA_PRIVATE_EXP_D) && !defined(RSA_LOW_MEM) -#endif /* !SP_RSA_PRIVATE_EXP_D && !RSA_LOW_MEM */ +#endif /* !SP_RSA_PRIVATE_EXP_D & !RSA_LOW_MEM */ /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -7323,9 +7301,9 @@ int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_3072(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM) #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -7388,7 +7366,9 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, return err; #else - sp_digit a[268], d[134], m[134]; + sp_digit a[268]; + sp_digit d[134]; + sp_digit m[134]; sp_digit* r = a; int err = MP_OKAY; @@ -7431,19 +7411,19 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, XMEMSET(d, 0, sizeof(sp_digit) * 134); return err; -#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */ +#endif /* WOLFSSL_SP_SMALL | defined(WOLFSSL_SMALL_STACK) */ #else #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* t = NULL; - sp_digit* a; - sp_digit* p; - sp_digit* q; - sp_digit* dp; - sp_digit* dq; - sp_digit* qi; - sp_digit* tmpa; - sp_digit* tmpb; - sp_digit* r; + sp_digit* a = NULL; + sp_digit* p = NULL; + sp_digit* q = NULL; + sp_digit* dp = NULL; + sp_digit* dq = NULL; + sp_digit* qi = NULL; + sp_digit* tmpa = NULL; + sp_digit* tmpb = NULL; + sp_digit* r = NULL; int err = MP_OKAY; (void)dm; @@ -7518,8 +7498,13 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, return err; #else sp_digit a[134 * 2]; - sp_digit p[67], q[67], dp[67], dq[67], qi[67]; - sp_digit tmpa[134], tmpb[134]; + sp_digit p[67]; + sp_digit q[67]; + sp_digit dp[67]; + sp_digit dq[67]; + sp_digit qi[67]; + sp_digit tmpa[134]; + sp_digit tmpb[134]; sp_digit* r = a; int err = MP_OKAY; @@ -7581,8 +7566,8 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, XMEMSET(qi, 0, sizeof(qi)); return err; -#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */ -#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */ +#endif /* WOLFSSL_SP_SMALL | defined(WOLFSSL_SMALL_STACK) */ +#endif /* SP_RSA_PRIVATE_EXP_D | RSA_LOW_MEM */ } #endif /* !WOLFSSL_RSA_PUBLIC_ONLY */ @@ -7605,17 +7590,19 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->used = 134; mp_clamp(r); #elif DIGIT_BIT < 23 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 134; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 23) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -7628,14 +7615,16 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 134; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 23 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -7662,7 +7651,8 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_3072(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { #ifdef WOLFSSL_SP_SMALL int err = MP_OKAY; @@ -7718,7 +7708,9 @@ int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) return err; #else #ifndef WOLFSSL_SMALL_STACK - sp_digit bd[268], ed[134], md[134]; + sp_digit bd[268]; + sp_digit ed[134]; + sp_digit md[134]; #else sp_digit* d = NULL; #endif @@ -7790,7 +7782,8 @@ int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) #ifdef WOLFSSL_HAVE_SP_DH #ifdef HAVE_FFDHE_3072 -SP_NOINLINE static void sp_3072_lshift_134(sp_digit* r, sp_digit* a, byte n) +SP_NOINLINE static void sp_3072_lshift_134(sp_digit* r, const sp_digit* a, + byte n) { #ifdef WOLFSSL_SP_SMALL int i; @@ -7800,7 +7793,8 @@ SP_NOINLINE static void sp_3072_lshift_134(sp_digit* r, sp_digit* a, byte n) r[i] = ((a[i] << n) | (a[i-1] >> (23 - n))) & 0x7fffff; } #else - sp_int_digit s, t; + sp_int_digit s; + sp_int_digit t; s = (sp_int_digit)a[133]; r[134] = s >> (23U - n); @@ -8092,9 +8086,11 @@ static int sp_3072_mod_exp_2_134(sp_digit* r, const sp_digit* e, int bits, const sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -8139,7 +8135,7 @@ static int sp_3072_mod_exp_2_134(sp_digit* r, const sp_digit* e, int bits, const n <<= 4; c -= 4; sp_3072_lshift_134(r, norm, (byte)y); - for (; i>=0 || c>=4; ) { + while ((i >= 0) || (c >= 4)) { if (c < 4) { n |= e[i--] << (9 - c); c += 23; @@ -8193,8 +8189,8 @@ static int sp_3072_mod_exp_2_134(sp_digit* r, const sp_digit* e, int bits, const * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, - mp_int* mod, byte* out, word32* outLen) +int sp_DhExp_3072(const mp_int* base, const byte* exp, word32 expLen, + const mp_int* mod, byte* out, word32* outLen) { #ifdef WOLFSSL_SP_SMALL int err = MP_OKAY; @@ -8261,7 +8257,9 @@ int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, return err; #else #ifndef WOLFSSL_SMALL_STACK - sp_digit bd[268], ed[134], md[134]; + sp_digit bd[268]; + sp_digit ed[134]; + sp_digit md[134]; #else sp_digit* d = NULL; #endif @@ -8326,6 +8324,7 @@ int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, sp_3072_to_bin(r, out); *outLen = 384; for (i=0; i<384U && out[i] == 0U; i++) { + /* Search for first non-zero. */ } *outLen -= i; XMEMMOVE(out, out + i, *outLen); @@ -8354,7 +8353,8 @@ int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_1536(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { #ifdef WOLFSSL_SP_SMALL int err = MP_OKAY; @@ -8411,7 +8411,9 @@ int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) return err; #else #ifndef WOLFSSL_SMALL_STACK - sp_digit bd[134], ed[67], md[67]; + sp_digit bd[134]; + sp_digit ed[67]; + sp_digit md[67]; #else sp_digit* d = NULL; #endif @@ -8481,7 +8483,7 @@ int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) #endif } -#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */ +#endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */ #endif /* !WOLFSSL_SP_NO_3072 */ @@ -8495,7 +8497,8 @@ int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) */ static void sp_4096_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -8537,7 +8540,8 @@ static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 21 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -8571,7 +8575,9 @@ static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -8610,7 +8616,10 @@ static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a) */ static void sp_4096_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; for (i=0; i<195; i++) { r[i+1] += r[i] >> 21; @@ -8653,7 +8662,8 @@ static void sp_4096_to_bin(sp_digit* r, byte* a) SP_NOINLINE static void sp_4096_mul_49(sp_digit* r, const sp_digit* a, const sp_digit* b) { - int i, j; + int i; + int j; int64_t t[98]; XMEMSET(t, 0, sizeof(t)); @@ -8676,7 +8686,8 @@ SP_NOINLINE static void sp_4096_mul_49(sp_digit* r, const sp_digit* a, */ SP_NOINLINE static void sp_4096_sqr_49(sp_digit* r, const sp_digit* a) { - int i, j; + int i; + int j; int64_t t[98]; XMEMSET(t, 0, sizeof(t)); @@ -8969,7 +8980,9 @@ SP_NOINLINE static int sp_4096_sub_196(sp_digit* r, const sp_digit* a, SP_NOINLINE static void sp_4096_mul_196(sp_digit* r, const sp_digit* a, const sp_digit* b) { - int i, j, k; + int i; + int j; + int k; int64_t c; c = ((int64_t)a[195]) * b[195]; @@ -9001,7 +9014,9 @@ SP_NOINLINE static void sp_4096_mul_196(sp_digit* r, const sp_digit* a, */ SP_NOINLINE static void sp_4096_sqr_196(sp_digit* r, const sp_digit* a) { - int i, j, k; + int i; + int j; + int k; int64_t c; c = ((int64_t)a[195]) * a[195]; @@ -9082,7 +9097,9 @@ SP_NOINLINE static int sp_4096_sub_98(sp_digit* r, const sp_digit* a, SP_NOINLINE static void sp_4096_mul_98(sp_digit* r, const sp_digit* a, const sp_digit* b) { - int i, j, k; + int i; + int j; + int k; int64_t c; c = ((int64_t)a[97]) * b[97]; @@ -9114,7 +9131,9 @@ SP_NOINLINE static void sp_4096_mul_98(sp_digit* r, const sp_digit* a, */ SP_NOINLINE static void sp_4096_sqr_98(sp_digit* r, const sp_digit* a) { - int i, j, k; + int i; + int j; + int k; int64_t c; c = ((int64_t)a[97]) * a[97]; @@ -9144,8 +9163,8 @@ SP_NOINLINE static void sp_4096_sqr_98(sp_digit* r, const sp_digit* a) } #endif /* WOLFSSL_SP_SMALL */ -#endif /* WOLFSSL_HAVE_SP_RSA && !SP_RSA_PRIVATE_EXP_D */ -#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */ +#endif /* WOLFSSL_HAVE_SP_RSA & !SP_RSA_PRIVATE_EXP_D */ +#endif /* (WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH) & !WOLFSSL_RSA_PUBLIC_ONLY */ /* Caclulate the bottom digit of -1/a mod 2^n. * @@ -9154,7 +9173,8 @@ SP_NOINLINE static void sp_4096_sqr_98(sp_digit* r, const sp_digit* a) */ static void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho) { - sp_digit x, b; + sp_digit x; + sp_digit b; b = a[0]; x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ @@ -9477,7 +9497,6 @@ static void sp_4096_mont_reduce_98(sp_digit* a, const sp_digit* m, sp_digit mp) sp_4096_mul_add_98(a+i, m, mu); a[i+1] += a[i] >> 21; a[i] &= 0x1fffff; - sp_4096_mont_shift_98(a, a); sp_4096_cond_sub_98(a, a, m, 0 - (((a[97] >> 11) > 0) ? (sp_digit)1 : (sp_digit)0)); @@ -9493,8 +9512,8 @@ static void sp_4096_mont_reduce_98(sp_digit* a, const sp_digit* m, sp_digit mp) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_4096_mont_mul_98(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_4096_mont_mul_98(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_4096_mul_98(r, a, b); sp_4096_mont_reduce_98(r, m, mp); @@ -9507,8 +9526,8 @@ static void sp_4096_mont_mul_98(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_4096_mont_sqr_98(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_4096_mont_sqr_98(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_4096_sqr_98(r, a); sp_4096_mont_reduce_98(r, m, mp); @@ -9608,46 +9627,8 @@ static void sp_4096_cond_add_98(sp_digit* r, const sp_digit* a, #endif /* WOLFSSL_SP_SMALL */ } -#ifdef WOLFSSL_SMALL -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_4096_sub_98(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 98; i++) { - r[i] = a[i] - b[i]; - } - - return 0; -} - -#endif -#ifdef WOLFSSL_SMALL -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_4096_add_98(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 98; i++) { - r[i] = a[i] + b[i]; - } - - return 0; -} -#endif -SP_NOINLINE static void sp_4096_rshift_98(sp_digit* r, sp_digit* a, byte n) +SP_NOINLINE static void sp_4096_rshift_98(sp_digit* r, const sp_digit* a, + byte n) { int i; @@ -9657,16 +9638,16 @@ SP_NOINLINE static void sp_4096_rshift_98(sp_digit* r, sp_digit* a, byte n) } #else for (i=0; i<96; i += 8) { - r[i+0] = ((a[i+0] >> n) | (a[i+1] << (21 - n))) & 0x1fffff; - r[i+1] = ((a[i+1] >> n) | (a[i+2] << (21 - n))) & 0x1fffff; - r[i+2] = ((a[i+2] >> n) | (a[i+3] << (21 - n))) & 0x1fffff; - r[i+3] = ((a[i+3] >> n) | (a[i+4] << (21 - n))) & 0x1fffff; - r[i+4] = ((a[i+4] >> n) | (a[i+5] << (21 - n))) & 0x1fffff; - r[i+5] = ((a[i+5] >> n) | (a[i+6] << (21 - n))) & 0x1fffff; - r[i+6] = ((a[i+6] >> n) | (a[i+7] << (21 - n))) & 0x1fffff; - r[i+7] = ((a[i+7] >> n) | (a[i+8] << (21 - n))) & 0x1fffff; + r[i+0] = (a[i+0] >> n) | ((a[i+1] << (21 - n)) & 0x1fffff); + r[i+1] = (a[i+1] >> n) | ((a[i+2] << (21 - n)) & 0x1fffff); + r[i+2] = (a[i+2] >> n) | ((a[i+3] << (21 - n)) & 0x1fffff); + r[i+3] = (a[i+3] >> n) | ((a[i+4] << (21 - n)) & 0x1fffff); + r[i+4] = (a[i+4] >> n) | ((a[i+5] << (21 - n)) & 0x1fffff); + r[i+5] = (a[i+5] >> n) | ((a[i+6] << (21 - n)) & 0x1fffff); + r[i+6] = (a[i+6] >> n) | ((a[i+7] << (21 - n)) & 0x1fffff); + r[i+7] = (a[i+7] >> n) | ((a[i+8] << (21 - n)) & 0x1fffff); } - r[96] = ((a[96] >> n) | (a[97] << (21 - n))) & 0x1fffff; + r[96] = (a[96] >> n) | ((a[97] << (21 - n)) & 0x1fffff); #endif r[97] = a[97] >> n; } @@ -9675,7 +9656,9 @@ SP_NOINLINE static void sp_4096_rshift_98(sp_digit* r, sp_digit* a, byte n) static WC_INLINE sp_digit sp_4096_div_word_98(sp_digit d1, sp_digit d0, sp_digit dv) { - sp_digit d, r, t; + sp_digit d; + sp_digit r; + sp_digit t; /* All 21 bits from d1 and top 10 bits from d0. */ d = (d1 << 10) | (d0 >> 11); @@ -9704,24 +9687,29 @@ static WC_INLINE sp_digit sp_4096_div_word_98(sp_digit d1, sp_digit d0, /* Divide d in a and put remainder into r (m*d + r = a) * m is not calculated as it is not needed at this time. * + * Full implementation. + * * a Number to be divided. * d Number to divide with. * m Multiplier result. * r Remainder from the division. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise. */ -static int sp_4096_div_98(const sp_digit* a, const sp_digit* d, sp_digit* m, - sp_digit* r) +static int sp_4096_div_98(const sp_digit* a, const sp_digit* d, + const sp_digit* m, sp_digit* r) { int i; #ifndef WOLFSSL_SP_DIV_32 int64_t d1; #endif - sp_digit dv, r1; + sp_digit dv; + sp_digit r1; #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* td; #else - sp_digit t1d[196 + 1], t2d[98 + 1], sdd[98 + 1]; + sp_digit t1d[196 + 1]; + sp_digit t2d[98 + 1]; + sp_digit sdd[98 + 1]; #endif sp_digit* t1; sp_digit* t2; @@ -9754,18 +9742,16 @@ static int sp_4096_div_98(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_4096_mul_d_98(sd, d, 1L << 10); sp_4096_mul_d_196(t1, a, 1L << 10); dv = sd[97]; + t1[98 + 98] += t1[98 + 98 - 1] >> 21; + t1[98 + 98 - 1] &= 0x1fffff; for (i=98; i>=0; i--) { - sp_digit hi; - t1[98 + i] += t1[98 + i - 1] >> 21; - t1[98 + i - 1] &= 0x1fffff; - hi = t1[98 + i] - (t1[98 + i] == dv); #ifndef WOLFSSL_SP_DIV_32 - d1 = hi; + d1 = t1[98 + i]; d1 <<= 21; d1 += t1[98 + i - 1]; r1 = (sp_digit)(d1 / dv); #else - r1 = sp_4096_div_word_98(hi, t1[98 + i - 1], dv); + r1 = sp_4096_div_word_98(t1[98 + i], t1[98 + i - 1], dv); #endif sp_4096_mul_d_98(t2, sd, r1); @@ -9786,7 +9772,7 @@ static int sp_4096_div_98(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_4096_mul_d_98(t2, sd, r1); sp_4096_sub_98(t1, t1, t2); - XMEMCPY(r, t1, sizeof(*r) * 2U * 98U); + XMEMCPY(r, t1, sizeof(*r) * 196U); for (i=0; i<97; i++) { r[i+1] += r[i] >> 21; r[i] &= 0x1fffff; @@ -9842,7 +9828,8 @@ static int sp_4096_mod_exp_98(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if !defined(WOLFSSL_SP_NO_MALLOC) @@ -9933,7 +9920,8 @@ static int sp_4096_mod_exp_98(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #ifdef WOLFSSL_SMALL_STACK @@ -10019,12 +10007,13 @@ static int sp_4096_mod_exp_98(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit td[(32 * 196) + 196]; #endif sp_digit* t[32]; - sp_digit* rt; + sp_digit* rt = NULL; sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -10116,7 +10105,7 @@ static int sp_4096_mod_exp_98(sp_digit* r, const sp_digit* a, const sp_digit* e, n <<= 5; c -= 5; XMEMCPY(rt, t[y], sizeof(sp_digit) * 196); - for (; i>=0 || c>=5; ) { + while ((i >= 0) || (c >= 5)) { if (c < 5) { n |= e[i--] << (11 - c); c += 21; @@ -10151,8 +10140,8 @@ static int sp_4096_mod_exp_98(sp_digit* r, const sp_digit* a, const sp_digit* e, #endif } -#endif /* WOLFSSL_HAVE_SP_RSA && !SP_RSA_PRIVATE_EXP_D */ -#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */ +#endif /* WOLFSSL_HAVE_SP_RSA & !SP_RSA_PRIVATE_EXP_D */ +#endif /* (WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH) & !WOLFSSL_RSA_PUBLIC_ONLY */ /* r = 2^n mod m where n is the number of bits to reduce by. * Given m must be 4096 bits, just need to subtract. @@ -10412,7 +10401,7 @@ static void sp_4096_mont_reduce_196(sp_digit* a, const sp_digit* m, sp_digit mp) sp_4096_norm_196(a + 196); -#ifdef WOLFSSL_HAVE_SP_DH +#ifdef WOLFSSL_SP_DH if (mp != 1) { for (i=0; i<195; i++) { mu = (a[i] * mp) & 0x1fffff; @@ -10446,7 +10435,6 @@ static void sp_4096_mont_reduce_196(sp_digit* a, const sp_digit* m, sp_digit mp) a[i+1] += a[i] >> 21; a[i] &= 0x1fffff; #endif - sp_4096_mont_shift_196(a, a); sp_4096_cond_sub_196(a, a, m, 0 - (((a[195] >> 1) > 0) ? (sp_digit)1 : (sp_digit)0)); @@ -10462,8 +10450,8 @@ static void sp_4096_mont_reduce_196(sp_digit* a, const sp_digit* m, sp_digit mp) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_4096_mont_mul_196(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_4096_mont_mul_196(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_4096_mul_196(r, a, b); sp_4096_mont_reduce_196(r, m, mp); @@ -10476,8 +10464,8 @@ static void sp_4096_mont_mul_196(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_4096_mont_sqr_196(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_4096_mont_sqr_196(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_4096_sqr_196(r, a); sp_4096_mont_reduce_196(r, m, mp); @@ -10573,46 +10561,8 @@ static void sp_4096_cond_add_196(sp_digit* r, const sp_digit* a, #endif /* WOLFSSL_SP_SMALL */ } -#ifdef WOLFSSL_SMALL -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_4096_sub_196(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 196; i++) { - r[i] = a[i] - b[i]; - } - - return 0; -} - -#endif -#ifdef WOLFSSL_SMALL -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_4096_add_196(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 196; i++) { - r[i] = a[i] + b[i]; - } - - return 0; -} -#endif -SP_NOINLINE static void sp_4096_rshift_196(sp_digit* r, sp_digit* a, byte n) +SP_NOINLINE static void sp_4096_rshift_196(sp_digit* r, const sp_digit* a, + byte n) { int i; @@ -10622,18 +10572,18 @@ SP_NOINLINE static void sp_4096_rshift_196(sp_digit* r, sp_digit* a, byte n) } #else for (i=0; i<192; i += 8) { - r[i+0] = ((a[i+0] >> n) | (a[i+1] << (21 - n))) & 0x1fffff; - r[i+1] = ((a[i+1] >> n) | (a[i+2] << (21 - n))) & 0x1fffff; - r[i+2] = ((a[i+2] >> n) | (a[i+3] << (21 - n))) & 0x1fffff; - r[i+3] = ((a[i+3] >> n) | (a[i+4] << (21 - n))) & 0x1fffff; - r[i+4] = ((a[i+4] >> n) | (a[i+5] << (21 - n))) & 0x1fffff; - r[i+5] = ((a[i+5] >> n) | (a[i+6] << (21 - n))) & 0x1fffff; - r[i+6] = ((a[i+6] >> n) | (a[i+7] << (21 - n))) & 0x1fffff; - r[i+7] = ((a[i+7] >> n) | (a[i+8] << (21 - n))) & 0x1fffff; + r[i+0] = (a[i+0] >> n) | ((a[i+1] << (21 - n)) & 0x1fffff); + r[i+1] = (a[i+1] >> n) | ((a[i+2] << (21 - n)) & 0x1fffff); + r[i+2] = (a[i+2] >> n) | ((a[i+3] << (21 - n)) & 0x1fffff); + r[i+3] = (a[i+3] >> n) | ((a[i+4] << (21 - n)) & 0x1fffff); + r[i+4] = (a[i+4] >> n) | ((a[i+5] << (21 - n)) & 0x1fffff); + r[i+5] = (a[i+5] >> n) | ((a[i+6] << (21 - n)) & 0x1fffff); + r[i+6] = (a[i+6] >> n) | ((a[i+7] << (21 - n)) & 0x1fffff); + r[i+7] = (a[i+7] >> n) | ((a[i+8] << (21 - n)) & 0x1fffff); } - r[192] = ((a[192] >> n) | (a[193] << (21 - n))) & 0x1fffff; - r[193] = ((a[193] >> n) | (a[194] << (21 - n))) & 0x1fffff; - r[194] = ((a[194] >> n) | (a[195] << (21 - n))) & 0x1fffff; + r[192] = (a[192] >> n) | ((a[193] << (21 - n)) & 0x1fffff); + r[193] = (a[193] >> n) | ((a[194] << (21 - n)) & 0x1fffff); + r[194] = (a[194] >> n) | ((a[195] << (21 - n)) & 0x1fffff); #endif r[195] = a[195] >> n; } @@ -10642,7 +10592,9 @@ SP_NOINLINE static void sp_4096_rshift_196(sp_digit* r, sp_digit* a, byte n) static WC_INLINE sp_digit sp_4096_div_word_196(sp_digit d1, sp_digit d0, sp_digit dv) { - sp_digit d, r, t; + sp_digit d; + sp_digit r; + sp_digit t; /* All 21 bits from d1 and top 10 bits from d0. */ d = (d1 << 10) | (d0 >> 11); @@ -10671,24 +10623,29 @@ static WC_INLINE sp_digit sp_4096_div_word_196(sp_digit d1, sp_digit d0, /* Divide d in a and put remainder into r (m*d + r = a) * m is not calculated as it is not needed at this time. * + * Full implementation. + * * a Number to be divided. * d Number to divide with. * m Multiplier result. * r Remainder from the division. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise. */ -static int sp_4096_div_196(const sp_digit* a, const sp_digit* d, sp_digit* m, - sp_digit* r) +static int sp_4096_div_196(const sp_digit* a, const sp_digit* d, + const sp_digit* m, sp_digit* r) { int i; #ifndef WOLFSSL_SP_DIV_32 int64_t d1; #endif - sp_digit dv, r1; + sp_digit dv; + sp_digit r1; #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* td; #else - sp_digit t1d[392 + 1], t2d[196 + 1], sdd[196 + 1]; + sp_digit t1d[392 + 1]; + sp_digit t2d[196 + 1]; + sp_digit sdd[196 + 1]; #endif sp_digit* t1; sp_digit* t2; @@ -10721,18 +10678,16 @@ static int sp_4096_div_196(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_4096_mul_d_196(sd, d, 1L << 20); sp_4096_mul_d_392(t1, a, 1L << 20); dv = sd[195]; + t1[196 + 196] += t1[196 + 196 - 1] >> 21; + t1[196 + 196 - 1] &= 0x1fffff; for (i=196; i>=0; i--) { - sp_digit hi; - t1[196 + i] += t1[196 + i - 1] >> 21; - t1[196 + i - 1] &= 0x1fffff; - hi = t1[196 + i] - (t1[196 + i] == dv); #ifndef WOLFSSL_SP_DIV_32 - d1 = hi; + d1 = t1[196 + i]; d1 <<= 21; d1 += t1[196 + i - 1]; r1 = (sp_digit)(d1 / dv); #else - r1 = sp_4096_div_word_196(hi, t1[196 + i - 1], dv); + r1 = sp_4096_div_word_196(t1[196 + i], t1[196 + i - 1], dv); #endif sp_4096_mul_d_196(t2, sd, r1); @@ -10753,7 +10708,7 @@ static int sp_4096_div_196(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_4096_mul_d_196(t2, sd, r1); sp_4096_sub_196(t1, t1, t2); - XMEMCPY(r, t1, sizeof(*r) * 2U * 196U); + XMEMCPY(r, t1, sizeof(*r) * 392U); for (i=0; i<195; i++) { r[i+1] += r[i] >> 21; r[i] &= 0x1fffff; @@ -10811,7 +10766,8 @@ static int sp_4096_mod_exp_196(sp_digit* r, const sp_digit* a, const sp_digit* e sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if !defined(WOLFSSL_SP_NO_MALLOC) @@ -10902,7 +10858,8 @@ static int sp_4096_mod_exp_196(sp_digit* r, const sp_digit* a, const sp_digit* e sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #ifdef WOLFSSL_SMALL_STACK @@ -10988,12 +10945,13 @@ static int sp_4096_mod_exp_196(sp_digit* r, const sp_digit* a, const sp_digit* e sp_digit td[(32 * 392) + 392]; #endif sp_digit* t[32]; - sp_digit* rt; + sp_digit* rt = NULL; sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -11085,7 +11043,7 @@ static int sp_4096_mod_exp_196(sp_digit* r, const sp_digit* a, const sp_digit* e n <<= 5; c -= 5; XMEMCPY(rt, t[y], sizeof(sp_digit) * 392); - for (; i>=0 || c>=5; ) { + while ((i >= 0) || (c >= 5)) { if (c < 5) { n |= e[i--] << (11 - c); c += 21; @@ -11119,7 +11077,7 @@ static int sp_4096_mod_exp_196(sp_digit* r, const sp_digit* a, const sp_digit* e return err; #endif } -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) || */ /* WOLFSSL_HAVE_SP_DH */ #ifdef WOLFSSL_HAVE_SP_RSA @@ -11135,15 +11093,15 @@ static int sp_4096_mod_exp_196(sp_digit* r, const sp_digit* a, const sp_digit* e * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPublic_4096(const byte* in, word32 inLen, const mp_int* em, + const mp_int* mm, byte* out, word32* outLen) { #ifdef WOLFSSL_SP_SMALL sp_digit* d = NULL; sp_digit* a = NULL; sp_digit* m = NULL; sp_digit* r = NULL; - sp_digit* norm; + sp_digit* norm = NULL; sp_digit e[1] = {0}; sp_digit mp; int i; @@ -11236,13 +11194,15 @@ int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, return err; #else #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_digit ad[392], md[196], rd[392]; + sp_digit ad[392]; + sp_digit md[196]; + sp_digit rd[392]; #else sp_digit* d = NULL; #endif - sp_digit* a; - sp_digit* m; - sp_digit* r; + sp_digit* a = NULL; + sp_digit* m = NULL; + sp_digit* r = NULL; sp_digit e[1] = {0}; int err = MP_OKAY; @@ -11360,7 +11320,7 @@ int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #ifndef WOLFSSL_RSA_PUBLIC_ONLY #if !defined(SP_RSA_PRIVATE_EXP_D) && !defined(RSA_LOW_MEM) -#endif /* !SP_RSA_PRIVATE_EXP_D && !RSA_LOW_MEM */ +#endif /* !SP_RSA_PRIVATE_EXP_D & !RSA_LOW_MEM */ /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -11378,9 +11338,9 @@ int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_4096(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM) #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -11443,7 +11403,9 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, return err; #else - sp_digit a[392], d[196], m[196]; + sp_digit a[392]; + sp_digit d[196]; + sp_digit m[196]; sp_digit* r = a; int err = MP_OKAY; @@ -11486,19 +11448,19 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, XMEMSET(d, 0, sizeof(sp_digit) * 196); return err; -#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */ +#endif /* WOLFSSL_SP_SMALL | defined(WOLFSSL_SMALL_STACK) */ #else #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* t = NULL; - sp_digit* a; - sp_digit* p; - sp_digit* q; - sp_digit* dp; - sp_digit* dq; - sp_digit* qi; - sp_digit* tmpa; - sp_digit* tmpb; - sp_digit* r; + sp_digit* a = NULL; + sp_digit* p = NULL; + sp_digit* q = NULL; + sp_digit* dp = NULL; + sp_digit* dq = NULL; + sp_digit* qi = NULL; + sp_digit* tmpa = NULL; + sp_digit* tmpb = NULL; + sp_digit* r = NULL; int err = MP_OKAY; (void)dm; @@ -11573,8 +11535,13 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, return err; #else sp_digit a[196 * 2]; - sp_digit p[98], q[98], dp[98], dq[98], qi[98]; - sp_digit tmpa[196], tmpb[196]; + sp_digit p[98]; + sp_digit q[98]; + sp_digit dp[98]; + sp_digit dq[98]; + sp_digit qi[98]; + sp_digit tmpa[196]; + sp_digit tmpb[196]; sp_digit* r = a; int err = MP_OKAY; @@ -11636,8 +11603,8 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, XMEMSET(qi, 0, sizeof(qi)); return err; -#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */ -#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */ +#endif /* WOLFSSL_SP_SMALL | defined(WOLFSSL_SMALL_STACK) */ +#endif /* SP_RSA_PRIVATE_EXP_D | RSA_LOW_MEM */ } #endif /* !WOLFSSL_RSA_PUBLIC_ONLY */ @@ -11660,17 +11627,19 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->used = 196; mp_clamp(r); #elif DIGIT_BIT < 21 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 196; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 21) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -11683,14 +11652,16 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 196; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 21 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -11717,7 +11688,8 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_4096(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { #ifdef WOLFSSL_SP_SMALL int err = MP_OKAY; @@ -11773,7 +11745,9 @@ int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) return err; #else #ifndef WOLFSSL_SMALL_STACK - sp_digit bd[392], ed[196], md[196]; + sp_digit bd[392]; + sp_digit ed[196]; + sp_digit md[196]; #else sp_digit* d = NULL; #endif @@ -11845,7 +11819,8 @@ int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) #ifdef WOLFSSL_HAVE_SP_DH #ifdef HAVE_FFDHE_4096 -SP_NOINLINE static void sp_4096_lshift_196(sp_digit* r, sp_digit* a, byte n) +SP_NOINLINE static void sp_4096_lshift_196(sp_digit* r, const sp_digit* a, + byte n) { #ifdef WOLFSSL_SP_SMALL int i; @@ -11855,7 +11830,8 @@ SP_NOINLINE static void sp_4096_lshift_196(sp_digit* r, sp_digit* a, byte n) r[i] = ((a[i] << n) | (a[i-1] >> (21 - n))) & 0x1fffff; } #else - sp_int_digit s, t; + sp_int_digit s; + sp_int_digit t; s = (sp_int_digit)a[195]; r[196] = s >> (21U - n); @@ -12271,9 +12247,11 @@ static int sp_4096_mod_exp_2_196(sp_digit* r, const sp_digit* e, int bits, const sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -12318,7 +12296,7 @@ static int sp_4096_mod_exp_2_196(sp_digit* r, const sp_digit* e, int bits, const n <<= 4; c -= 4; sp_4096_lshift_196(r, norm, (byte)y); - for (; i>=0 || c>=4; ) { + while ((i >= 0) || (c >= 4)) { if (c < 4) { n |= e[i--] << (11 - c); c += 21; @@ -12372,8 +12350,8 @@ static int sp_4096_mod_exp_2_196(sp_digit* r, const sp_digit* e, int bits, const * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, - mp_int* mod, byte* out, word32* outLen) +int sp_DhExp_4096(const mp_int* base, const byte* exp, word32 expLen, + const mp_int* mod, byte* out, word32* outLen) { #ifdef WOLFSSL_SP_SMALL int err = MP_OKAY; @@ -12440,7 +12418,9 @@ int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, return err; #else #ifndef WOLFSSL_SMALL_STACK - sp_digit bd[392], ed[196], md[196]; + sp_digit bd[392]; + sp_digit ed[196]; + sp_digit md[196]; #else sp_digit* d = NULL; #endif @@ -12505,6 +12485,7 @@ int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, sp_4096_to_bin(r, out); *outLen = 512; for (i=0; i<512U && out[i] == 0U; i++) { + /* Search for first non-zero. */ } *outLen -= i; XMEMMOVE(out, out + i, *outLen); @@ -12524,19 +12505,23 @@ int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, } #endif /* WOLFSSL_HAVE_SP_DH */ -#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */ +#endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */ #endif /* WOLFSSL_SP_4096 */ -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */ #ifdef WOLFSSL_HAVE_SP_ECC #ifndef WOLFSSL_SP_NO_256 /* Point structure to use. */ typedef struct sp_point_256 { + /* X ordinate of point. */ sp_digit x[2 * 10]; + /* Y ordinate of point. */ sp_digit y[2 * 10]; + /* Z ordinate of point. */ sp_digit z[2 * 10]; + /* Indicates point is at infinity. */ int infinity; } sp_point_256; @@ -12606,370 +12591,6 @@ static const sp_digit p256_b[10] = { }; #endif -static int sp_256_point_new_ex_10(void* heap, sp_point_256* sp, sp_point_256** p) -{ - int ret = MP_OKAY; - (void)heap; -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - (void)sp; - *p = (sp_point_256*)XMALLOC(sizeof(sp_point_256), heap, DYNAMIC_TYPE_ECC); -#else - *p = sp; -#endif - if (*p == NULL) { - ret = MEMORY_E; - } - return ret; -} - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) -/* Allocate memory for point and return error. */ -#define sp_256_point_new_10(heap, sp, p) sp_256_point_new_ex_10((heap), NULL, &(p)) -#else -/* Set pointer to data and return no error. */ -#define sp_256_point_new_10(heap, sp, p) sp_256_point_new_ex_10((heap), &(sp), &(p)) -#endif - - -static void sp_256_point_free_10(sp_point_256* p, int clear, void* heap) -{ -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) -/* If valid pointer then clear point data if requested and free data. */ - if (p != NULL) { - if (clear != 0) { - XMEMSET(p, 0, sizeof(*p)); - } - XFREE(p, heap, DYNAMIC_TYPE_ECC); - } -#else -/* Clear point data if requested. */ - if (clear != 0) { - XMEMSET(p, 0, sizeof(*p)); - } -#endif - (void)heap; -} - -/* Multiply a number by Montogmery normalizer mod modulus (prime). - * - * r The resulting Montgomery form number. - * a The number to convert. - * m The modulus (prime). - * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. - */ -static int sp_256_mod_mul_norm_10(sp_digit* r, const sp_digit* a, const sp_digit* m) -{ -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - int64_t* td; -#else - int64_t td[8]; - int64_t a32d[8]; -#endif - int64_t* t; - int64_t* a32; - int64_t o; - int err = MP_OKAY; - - (void)m; - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - td = (int64_t*)XMALLOC(sizeof(int64_t) * 2 * 8, NULL, DYNAMIC_TYPE_ECC); - if (td == NULL) { - return MEMORY_E; - } -#endif - - if (err == MP_OKAY) { -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - t = td; - a32 = td + 8; -#else - t = td; - a32 = a32d; -#endif - - a32[0] = a[0]; - a32[0] |= a[1] << 26U; - a32[0] &= 0xffffffffL; - a32[1] = (sp_digit)(a[1] >> 6); - a32[1] |= a[2] << 20U; - a32[1] &= 0xffffffffL; - a32[2] = (sp_digit)(a[2] >> 12); - a32[2] |= a[3] << 14U; - a32[2] &= 0xffffffffL; - a32[3] = (sp_digit)(a[3] >> 18); - a32[3] |= a[4] << 8U; - a32[3] &= 0xffffffffL; - a32[4] = (sp_digit)(a[4] >> 24); - a32[4] |= a[5] << 2U; - a32[4] |= a[6] << 28U; - a32[4] &= 0xffffffffL; - a32[5] = (sp_digit)(a[6] >> 4); - a32[5] |= a[7] << 22U; - a32[5] &= 0xffffffffL; - a32[6] = (sp_digit)(a[7] >> 10); - a32[6] |= a[8] << 16U; - a32[6] &= 0xffffffffL; - a32[7] = (sp_digit)(a[8] >> 16); - a32[7] |= a[9] << 10U; - a32[7] &= 0xffffffffL; - - /* 1 1 0 -1 -1 -1 -1 0 */ - t[0] = 0 + a32[0] + a32[1] - a32[3] - a32[4] - a32[5] - a32[6]; - /* 0 1 1 0 -1 -1 -1 -1 */ - t[1] = 0 + a32[1] + a32[2] - a32[4] - a32[5] - a32[6] - a32[7]; - /* 0 0 1 1 0 -1 -1 -1 */ - t[2] = 0 + a32[2] + a32[3] - a32[5] - a32[6] - a32[7]; - /* -1 -1 0 2 2 1 0 -1 */ - t[3] = 0 - a32[0] - a32[1] + 2 * a32[3] + 2 * a32[4] + a32[5] - a32[7]; - /* 0 -1 -1 0 2 2 1 0 */ - t[4] = 0 - a32[1] - a32[2] + 2 * a32[4] + 2 * a32[5] + a32[6]; - /* 0 0 -1 -1 0 2 2 1 */ - t[5] = 0 - a32[2] - a32[3] + 2 * a32[5] + 2 * a32[6] + a32[7]; - /* -1 -1 0 0 0 1 3 2 */ - t[6] = 0 - a32[0] - a32[1] + a32[5] + 3 * a32[6] + 2 * a32[7]; - /* 1 0 -1 -1 -1 -1 0 3 */ - t[7] = 0 + a32[0] - a32[2] - a32[3] - a32[4] - a32[5] + 3 * a32[7]; - - t[1] += t[0] >> 32U; t[0] &= 0xffffffffL; - t[2] += t[1] >> 32U; t[1] &= 0xffffffffL; - t[3] += t[2] >> 32U; t[2] &= 0xffffffffL; - t[4] += t[3] >> 32U; t[3] &= 0xffffffffL; - t[5] += t[4] >> 32U; t[4] &= 0xffffffffL; - t[6] += t[5] >> 32U; t[5] &= 0xffffffffL; - t[7] += t[6] >> 32U; t[6] &= 0xffffffffL; - o = t[7] >> 32U; t[7] &= 0xffffffffL; - t[0] += o; - t[3] -= o; - t[6] -= o; - t[7] += o; - t[1] += t[0] >> 32U; t[0] &= 0xffffffffL; - t[2] += t[1] >> 32U; t[1] &= 0xffffffffL; - t[3] += t[2] >> 32U; t[2] &= 0xffffffffL; - t[4] += t[3] >> 32U; t[3] &= 0xffffffffL; - t[5] += t[4] >> 32U; t[4] &= 0xffffffffL; - t[6] += t[5] >> 32U; t[5] &= 0xffffffffL; - t[7] += t[6] >> 32U; t[6] &= 0xffffffffL; - - r[0] = (sp_digit)(t[0]) & 0x3ffffffL; - r[1] = (sp_digit)(t[0] >> 26U); - r[1] |= (sp_digit)(t[1] << 6U); - r[1] &= 0x3ffffffL; - r[2] = (sp_digit)(t[1] >> 20U); - r[2] |= (sp_digit)(t[2] << 12U); - r[2] &= 0x3ffffffL; - r[3] = (sp_digit)(t[2] >> 14U); - r[3] |= (sp_digit)(t[3] << 18U); - r[3] &= 0x3ffffffL; - r[4] = (sp_digit)(t[3] >> 8U); - r[4] |= (sp_digit)(t[4] << 24U); - r[4] &= 0x3ffffffL; - r[5] = (sp_digit)(t[4] >> 2U) & 0x3ffffffL; - r[6] = (sp_digit)(t[4] >> 28U); - r[6] |= (sp_digit)(t[5] << 4U); - r[6] &= 0x3ffffffL; - r[7] = (sp_digit)(t[5] >> 22U); - r[7] |= (sp_digit)(t[6] << 10U); - r[7] &= 0x3ffffffL; - r[8] = (sp_digit)(t[6] >> 16U); - r[8] |= (sp_digit)(t[7] << 16U); - r[8] &= 0x3ffffffL; - r[9] = (sp_digit)(t[7] >> 10U); - } - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - if (td != NULL) { - XFREE(td, NULL, DYNAMIC_TYPE_ECC); - } -#endif - - return err; -} - -/* Convert an mp_int to an array of sp_digit. - * - * r A single precision integer. - * size Maximum number of bytes to convert - * a A multi-precision integer. - */ -static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) -{ -#if DIGIT_BIT == 26 - int j; - - XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); - - for (j = a->used; j < size; j++) { - r[j] = 0; - } -#elif DIGIT_BIT > 26 - int i, j = 0; - word32 s = 0; - - r[0] = 0; - for (i = 0; i < a->used && j < size; i++) { - r[j] |= ((sp_digit)a->dp[i] << s); - r[j] &= 0x3ffffff; - s = 26U - s; - if (j + 1 >= size) { - break; - } - /* lint allow cast of mismatch word32 and mp_digit */ - r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ - while ((s + 26U) <= (word32)DIGIT_BIT) { - s += 26U; - r[j] &= 0x3ffffff; - if (j + 1 >= size) { - break; - } - if (s < (word32)DIGIT_BIT) { - /* lint allow cast of mismatch word32 and mp_digit */ - r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ - } - else { - r[++j] = 0L; - } - } - s = (word32)DIGIT_BIT - s; - } - - for (j++; j < size; j++) { - r[j] = 0; - } -#else - int i, j = 0, s = 0; - - r[0] = 0; - for (i = 0; i < a->used && j < size; i++) { - r[j] |= ((sp_digit)a->dp[i]) << s; - if (s + DIGIT_BIT >= 26) { - r[j] &= 0x3ffffff; - if (j + 1 >= size) { - break; - } - s = 26 - s; - if (s == DIGIT_BIT) { - r[++j] = 0; - s = 0; - } - else { - r[++j] = a->dp[i] >> s; - s = DIGIT_BIT - s; - } - } - else { - s += DIGIT_BIT; - } - } - - for (j++; j < size; j++) { - r[j] = 0; - } -#endif -} - -/* Convert a point of type ecc_point to type sp_point_256. - * - * p Point of type sp_point_256 (result). - * pm Point of type ecc_point. - */ -static void sp_256_point_from_ecc_point_10(sp_point_256* p, const ecc_point* pm) -{ - XMEMSET(p->x, 0, sizeof(p->x)); - XMEMSET(p->y, 0, sizeof(p->y)); - XMEMSET(p->z, 0, sizeof(p->z)); - sp_256_from_mp(p->x, 10, pm->x); - sp_256_from_mp(p->y, 10, pm->y); - sp_256_from_mp(p->z, 10, pm->z); - p->infinity = 0; -} - -/* Convert an array of sp_digit to an mp_int. - * - * a A single precision integer. - * r A multi-precision integer. - */ -static int sp_256_to_mp(const sp_digit* a, mp_int* r) -{ - int err; - - err = mp_grow(r, (256 + DIGIT_BIT - 1) / DIGIT_BIT); - if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ -#if DIGIT_BIT == 26 - XMEMCPY(r->dp, a, sizeof(sp_digit) * 10); - r->used = 10; - mp_clamp(r); -#elif DIGIT_BIT < 26 - int i, j = 0, s = 0; - - r->dp[0] = 0; - for (i = 0; i < 10; i++) { - r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; - s = DIGIT_BIT - s; - r->dp[++j] = (mp_digit)(a[i] >> s); - while (s + DIGIT_BIT <= 26) { - s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; - if (s == SP_WORD_SIZE) { - r->dp[j] = 0; - } - else { - r->dp[j] = (mp_digit)(a[i] >> s); - } - } - s = 26 - s; - } - r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT; - mp_clamp(r); -#else - int i, j = 0, s = 0; - - r->dp[0] = 0; - for (i = 0; i < 10; i++) { - r->dp[j] |= ((mp_digit)a[i]) << s; - if (s + 26 >= DIGIT_BIT) { - #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; - #endif - s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; - s = 26 - s; - } - else { - s += 26; - } - } - r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT; - mp_clamp(r); -#endif - } - - return err; -} - -/* Convert a point of type sp_point_256 to type ecc_point. - * - * p Point of type sp_point_256. - * pm Point of type ecc_point (result). - * returns MEMORY_E when allocation of memory in ecc_point fails otherwise - * MP_OKAY. - */ -static int sp_256_point_to_ecc_point_10(const sp_point_256* p, ecc_point* pm) -{ - int err; - - err = sp_256_to_mp(p->x, pm->x); - if (err == MP_OKAY) { - err = sp_256_to_mp(p->y, pm->y); - } - if (err == MP_OKAY) { - err = sp_256_to_mp(p->z, pm->z); - } - - return err; -} - #ifdef WOLFSSL_SP_SMALL /* Multiply a and b into r. (r = a * b) * @@ -12980,7 +12601,9 @@ static int sp_256_point_to_ecc_point_10(const sp_point_256* p, ecc_point* pm) SP_NOINLINE static void sp_256_mul_10(sp_digit* r, const sp_digit* a, const sp_digit* b) { - int i, j, k; + int i; + int j; + int k; int64_t c; c = ((int64_t)a[9]) * b[9]; @@ -13139,6 +12762,469 @@ SP_NOINLINE static void sp_256_mul_10(sp_digit* r, const sp_digit* a, } #endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_256_sqr_10(sp_digit* r, const sp_digit* a) +{ + int i; + int j; + int k; + int64_t c; + + c = ((int64_t)a[9]) * a[9]; + r[19] = (sp_digit)(c >> 26); + c = (c & 0x3ffffff) << 26; + for (k = 17; k >= 0; k--) { + for (i = 9; i >= 0; i--) { + j = k - i; + if (j >= 10 || i <= j) { + break; + } + if (j < 0) { + continue; + } + + c += ((int64_t)a[i]) * a[j] * 2; + } + if (i == j) { + c += ((int64_t)a[i]) * a[i]; + } + + r[k + 2] += (sp_digit)(c >> 52); + r[k + 1] = (sp_digit)((c >> 26) & 0x3ffffff); + c = (c & 0x3ffffff) << 26; + } + r[0] = (sp_digit)(c >> 26); +} + +#else +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_256_sqr_10(sp_digit* r, const sp_digit* a) +{ + int64_t t0 = ((int64_t)a[ 0]) * a[ 0]; + int64_t t1 = (((int64_t)a[ 0]) * a[ 1]) * 2; + int64_t t2 = (((int64_t)a[ 0]) * a[ 2]) * 2 + + ((int64_t)a[ 1]) * a[ 1]; + int64_t t3 = (((int64_t)a[ 0]) * a[ 3] + + ((int64_t)a[ 1]) * a[ 2]) * 2; + int64_t t4 = (((int64_t)a[ 0]) * a[ 4] + + ((int64_t)a[ 1]) * a[ 3]) * 2 + + ((int64_t)a[ 2]) * a[ 2]; + int64_t t5 = (((int64_t)a[ 0]) * a[ 5] + + ((int64_t)a[ 1]) * a[ 4] + + ((int64_t)a[ 2]) * a[ 3]) * 2; + int64_t t6 = (((int64_t)a[ 0]) * a[ 6] + + ((int64_t)a[ 1]) * a[ 5] + + ((int64_t)a[ 2]) * a[ 4]) * 2 + + ((int64_t)a[ 3]) * a[ 3]; + int64_t t7 = (((int64_t)a[ 0]) * a[ 7] + + ((int64_t)a[ 1]) * a[ 6] + + ((int64_t)a[ 2]) * a[ 5] + + ((int64_t)a[ 3]) * a[ 4]) * 2; + int64_t t8 = (((int64_t)a[ 0]) * a[ 8] + + ((int64_t)a[ 1]) * a[ 7] + + ((int64_t)a[ 2]) * a[ 6] + + ((int64_t)a[ 3]) * a[ 5]) * 2 + + ((int64_t)a[ 4]) * a[ 4]; + int64_t t9 = (((int64_t)a[ 0]) * a[ 9] + + ((int64_t)a[ 1]) * a[ 8] + + ((int64_t)a[ 2]) * a[ 7] + + ((int64_t)a[ 3]) * a[ 6] + + ((int64_t)a[ 4]) * a[ 5]) * 2; + int64_t t10 = (((int64_t)a[ 1]) * a[ 9] + + ((int64_t)a[ 2]) * a[ 8] + + ((int64_t)a[ 3]) * a[ 7] + + ((int64_t)a[ 4]) * a[ 6]) * 2 + + ((int64_t)a[ 5]) * a[ 5]; + int64_t t11 = (((int64_t)a[ 2]) * a[ 9] + + ((int64_t)a[ 3]) * a[ 8] + + ((int64_t)a[ 4]) * a[ 7] + + ((int64_t)a[ 5]) * a[ 6]) * 2; + int64_t t12 = (((int64_t)a[ 3]) * a[ 9] + + ((int64_t)a[ 4]) * a[ 8] + + ((int64_t)a[ 5]) * a[ 7]) * 2 + + ((int64_t)a[ 6]) * a[ 6]; + int64_t t13 = (((int64_t)a[ 4]) * a[ 9] + + ((int64_t)a[ 5]) * a[ 8] + + ((int64_t)a[ 6]) * a[ 7]) * 2; + int64_t t14 = (((int64_t)a[ 5]) * a[ 9] + + ((int64_t)a[ 6]) * a[ 8]) * 2 + + ((int64_t)a[ 7]) * a[ 7]; + int64_t t15 = (((int64_t)a[ 6]) * a[ 9] + + ((int64_t)a[ 7]) * a[ 8]) * 2; + int64_t t16 = (((int64_t)a[ 7]) * a[ 9]) * 2 + + ((int64_t)a[ 8]) * a[ 8]; + int64_t t17 = (((int64_t)a[ 8]) * a[ 9]) * 2; + int64_t t18 = ((int64_t)a[ 9]) * a[ 9]; + + t1 += t0 >> 26; r[ 0] = t0 & 0x3ffffff; + t2 += t1 >> 26; r[ 1] = t1 & 0x3ffffff; + t3 += t2 >> 26; r[ 2] = t2 & 0x3ffffff; + t4 += t3 >> 26; r[ 3] = t3 & 0x3ffffff; + t5 += t4 >> 26; r[ 4] = t4 & 0x3ffffff; + t6 += t5 >> 26; r[ 5] = t5 & 0x3ffffff; + t7 += t6 >> 26; r[ 6] = t6 & 0x3ffffff; + t8 += t7 >> 26; r[ 7] = t7 & 0x3ffffff; + t9 += t8 >> 26; r[ 8] = t8 & 0x3ffffff; + t10 += t9 >> 26; r[ 9] = t9 & 0x3ffffff; + t11 += t10 >> 26; r[10] = t10 & 0x3ffffff; + t12 += t11 >> 26; r[11] = t11 & 0x3ffffff; + t13 += t12 >> 26; r[12] = t12 & 0x3ffffff; + t14 += t13 >> 26; r[13] = t13 & 0x3ffffff; + t15 += t14 >> 26; r[14] = t14 & 0x3ffffff; + t16 += t15 >> 26; r[15] = t15 & 0x3ffffff; + t17 += t16 >> 26; r[16] = t16 & 0x3ffffff; + t18 += t17 >> 26; r[17] = t17 & 0x3ffffff; + r[19] = (sp_digit)(t18 >> 26); + r[18] = t18 & 0x3ffffff; +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_256_add_10(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + int i; + + for (i = 0; i < 10; i++) { + r[i] = a[i] + b[i]; + } + + return 0; +} +#else +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_256_add_10(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + r[ 0] = a[ 0] + b[ 0]; + r[ 1] = a[ 1] + b[ 1]; + r[ 2] = a[ 2] + b[ 2]; + r[ 3] = a[ 3] + b[ 3]; + r[ 4] = a[ 4] + b[ 4]; + r[ 5] = a[ 5] + b[ 5]; + r[ 6] = a[ 6] + b[ 6]; + r[ 7] = a[ 7] + b[ 7]; + r[ 8] = a[ 8] + b[ 8]; + r[ 9] = a[ 9] + b[ 9]; + + return 0; +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_256_sub_10(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + int i; + + for (i = 0; i < 10; i++) { + r[i] = a[i] - b[i]; + } + + return 0; +} + +#else +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_256_sub_10(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + r[ 0] = a[ 0] - b[ 0]; + r[ 1] = a[ 1] - b[ 1]; + r[ 2] = a[ 2] - b[ 2]; + r[ 3] = a[ 3] - b[ 3]; + r[ 4] = a[ 4] - b[ 4]; + r[ 5] = a[ 5] - b[ 5]; + r[ 6] = a[ 6] - b[ 6]; + r[ 7] = a[ 7] - b[ 7]; + r[ 8] = a[ 8] - b[ 8]; + r[ 9] = a[ 9] - b[ 9]; + + return 0; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Create a new point. + * + * heap [in] Buffer to allocate dynamic memory from. + * sp [in] Data for point - only if not allocating. + * p [out] New point. + * returns MEMORY_E when dynamic memory allocation fails and 0 otherwise. + */ +static int sp_256_point_new_ex_10(void* heap, sp_point_256* sp, + sp_point_256** p) +{ + int ret = MP_OKAY; + (void)heap; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + (void)sp; + *p = (sp_point_256*)XMALLOC(sizeof(sp_point_256), heap, DYNAMIC_TYPE_ECC); +#else + *p = sp; +#endif + if (*p == NULL) { + ret = MEMORY_E; + } + return ret; +} + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* Allocate memory for point and return error. */ +#define sp_256_point_new_10(heap, sp, p) sp_256_point_new_ex_10((heap), NULL, &(p)) +#else +/* Set pointer to data and return no error. */ +#define sp_256_point_new_10(heap, sp, p) sp_256_point_new_ex_10((heap), &(sp), &(p)) +#endif + + +/* Free the point. + * + * p [in,out] Point to free. + * clear [in] Indicates whether to zeroize point. + * heap [in] Buffer from which dynamic memory was allocate from. + */ +static void sp_256_point_free_10(sp_point_256* p, int clear, void* heap) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* If valid pointer then clear point data if requested and free data. */ + if (p != NULL) { + if (clear != 0) { + XMEMSET(p, 0, sizeof(*p)); + } + XFREE(p, heap, DYNAMIC_TYPE_ECC); + } +#else +/* Clear point data if requested. */ + if ((p != NULL) && (clear != 0)) { + XMEMSET(p, 0, sizeof(*p)); + } +#endif + (void)heap; +} + +/* Convert an mp_int to an array of sp_digit. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a A multi-precision integer. + */ +static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) +{ +#if DIGIT_BIT == 26 + int j; + + XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); + + for (j = a->used; j < size; j++) { + r[j] = 0; + } +#elif DIGIT_BIT > 26 + int i; + int j = 0; + word32 s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i] << s); + r[j] &= 0x3ffffff; + s = 26U - s; + if (j + 1 >= size) { + break; + } + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + while ((s + 26U) <= (word32)DIGIT_BIT) { + s += 26U; + r[j] &= 0x3ffffff; + if (j + 1 >= size) { + break; + } + if (s < (word32)DIGIT_BIT) { + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + } + else { + r[++j] = 0L; + } + } + s = (word32)DIGIT_BIT - s; + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#else + int i; + int j = 0; + int s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i]) << s; + if (s + DIGIT_BIT >= 26) { + r[j] &= 0x3ffffff; + if (j + 1 >= size) { + break; + } + s = 26 - s; + if (s == DIGIT_BIT) { + r[++j] = 0; + s = 0; + } + else { + r[++j] = a->dp[i] >> s; + s = DIGIT_BIT - s; + } + } + else { + s += DIGIT_BIT; + } + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#endif +} + +/* Convert a point of type ecc_point to type sp_point_256. + * + * p Point of type sp_point_256 (result). + * pm Point of type ecc_point. + */ +static void sp_256_point_from_ecc_point_10(sp_point_256* p, + const ecc_point* pm) +{ + XMEMSET(p->x, 0, sizeof(p->x)); + XMEMSET(p->y, 0, sizeof(p->y)); + XMEMSET(p->z, 0, sizeof(p->z)); + sp_256_from_mp(p->x, 10, pm->x); + sp_256_from_mp(p->y, 10, pm->y); + sp_256_from_mp(p->z, 10, pm->z); + p->infinity = 0; +} + +/* Convert an array of sp_digit to an mp_int. + * + * a A single precision integer. + * r A multi-precision integer. + */ +static int sp_256_to_mp(const sp_digit* a, mp_int* r) +{ + int err; + + err = mp_grow(r, (256 + DIGIT_BIT - 1) / DIGIT_BIT); + if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ +#if DIGIT_BIT == 26 + XMEMCPY(r->dp, a, sizeof(sp_digit) * 10); + r->used = 10; + mp_clamp(r); +#elif DIGIT_BIT < 26 + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 10; i++) { + r->dp[j] |= (mp_digit)(a[i] << s); + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + s = DIGIT_BIT - s; + r->dp[++j] = (mp_digit)(a[i] >> s); + while (s + DIGIT_BIT <= 26) { + s += DIGIT_BIT; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; + if (s == SP_WORD_SIZE) { + r->dp[j] = 0; + } + else { + r->dp[j] = (mp_digit)(a[i] >> s); + } + } + s = 26 - s; + } + r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#else + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 10; i++) { + r->dp[j] |= ((mp_digit)a[i]) << s; + if (s + 26 >= DIGIT_BIT) { + #if DIGIT_BIT != 32 && DIGIT_BIT != 64 + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + #endif + s = DIGIT_BIT - s; + r->dp[++j] = a[i] >> s; + s = 26 - s; + } + else { + s += 26; + } + } + r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#endif + } + + return err; +} + +/* Convert a point of type sp_point_256 to type ecc_point. + * + * p Point of type sp_point_256. + * pm Point of type ecc_point (result). + * returns MEMORY_E when allocation of memory in ecc_point fails otherwise + * MP_OKAY. + */ +static int sp_256_point_to_ecc_point_10(const sp_point_256* p, ecc_point* pm) +{ + int err; + + err = sp_256_to_mp(p->x, pm->x); + if (err == MP_OKAY) { + err = sp_256_to_mp(p->y, pm->y); + } + if (err == MP_OKAY) { + err = sp_256_to_mp(p->z, pm->z); + } + + return err; +} + #define sp_256_mont_reduce_order_10 sp_256_mont_reduce_10 /* Compare a with b in constant time. @@ -13286,7 +13372,8 @@ static void sp_256_mont_shift_10(sp_digit* r, const sp_digit* a) { #ifdef WOLFSSL_SP_SMALL int i; - sp_digit n, s; + sp_digit n; + sp_digit s; s = a[10]; n = a[9] >> 22; @@ -13299,7 +13386,8 @@ static void sp_256_mont_shift_10(sp_digit* r, const sp_digit* a) n += s << 4; r[9] = n; #else - sp_digit n, s; + sp_digit n; + sp_digit s; s = a[10]; n = a[9] >> 22; n += (s & 0x3ffffff) << 4; r[ 0] = n & 0x3ffffff; @@ -13374,137 +13462,13 @@ static void sp_256_mont_reduce_10(sp_digit* a, const sp_digit* m, sp_digit mp) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_256_mont_mul_10(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_256_mont_mul_10(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_256_mul_10(r, a, b); sp_256_mont_reduce_10(r, m, mp); } -#ifdef WOLFSSL_SP_SMALL -/* Square a and put result in r. (r = a * a) - * - * r A single precision integer. - * a A single precision integer. - */ -SP_NOINLINE static void sp_256_sqr_10(sp_digit* r, const sp_digit* a) -{ - int i, j, k; - int64_t c; - - c = ((int64_t)a[9]) * a[9]; - r[19] = (sp_digit)(c >> 26); - c = (c & 0x3ffffff) << 26; - for (k = 17; k >= 0; k--) { - for (i = 9; i >= 0; i--) { - j = k - i; - if (j >= 10 || i <= j) { - break; - } - if (j < 0) { - continue; - } - - c += ((int64_t)a[i]) * a[j] * 2; - } - if (i == j) { - c += ((int64_t)a[i]) * a[i]; - } - - r[k + 2] += (sp_digit)(c >> 52); - r[k + 1] = (sp_digit)((c >> 26) & 0x3ffffff); - c = (c & 0x3ffffff) << 26; - } - r[0] = (sp_digit)(c >> 26); -} - -#else -/* Square a and put result in r. (r = a * a) - * - * r A single precision integer. - * a A single precision integer. - */ -SP_NOINLINE static void sp_256_sqr_10(sp_digit* r, const sp_digit* a) -{ - int64_t t0 = ((int64_t)a[ 0]) * a[ 0]; - int64_t t1 = (((int64_t)a[ 0]) * a[ 1]) * 2; - int64_t t2 = (((int64_t)a[ 0]) * a[ 2]) * 2 - + ((int64_t)a[ 1]) * a[ 1]; - int64_t t3 = (((int64_t)a[ 0]) * a[ 3] - + ((int64_t)a[ 1]) * a[ 2]) * 2; - int64_t t4 = (((int64_t)a[ 0]) * a[ 4] - + ((int64_t)a[ 1]) * a[ 3]) * 2 - + ((int64_t)a[ 2]) * a[ 2]; - int64_t t5 = (((int64_t)a[ 0]) * a[ 5] - + ((int64_t)a[ 1]) * a[ 4] - + ((int64_t)a[ 2]) * a[ 3]) * 2; - int64_t t6 = (((int64_t)a[ 0]) * a[ 6] - + ((int64_t)a[ 1]) * a[ 5] - + ((int64_t)a[ 2]) * a[ 4]) * 2 - + ((int64_t)a[ 3]) * a[ 3]; - int64_t t7 = (((int64_t)a[ 0]) * a[ 7] - + ((int64_t)a[ 1]) * a[ 6] - + ((int64_t)a[ 2]) * a[ 5] - + ((int64_t)a[ 3]) * a[ 4]) * 2; - int64_t t8 = (((int64_t)a[ 0]) * a[ 8] - + ((int64_t)a[ 1]) * a[ 7] - + ((int64_t)a[ 2]) * a[ 6] - + ((int64_t)a[ 3]) * a[ 5]) * 2 - + ((int64_t)a[ 4]) * a[ 4]; - int64_t t9 = (((int64_t)a[ 0]) * a[ 9] - + ((int64_t)a[ 1]) * a[ 8] - + ((int64_t)a[ 2]) * a[ 7] - + ((int64_t)a[ 3]) * a[ 6] - + ((int64_t)a[ 4]) * a[ 5]) * 2; - int64_t t10 = (((int64_t)a[ 1]) * a[ 9] - + ((int64_t)a[ 2]) * a[ 8] - + ((int64_t)a[ 3]) * a[ 7] - + ((int64_t)a[ 4]) * a[ 6]) * 2 - + ((int64_t)a[ 5]) * a[ 5]; - int64_t t11 = (((int64_t)a[ 2]) * a[ 9] - + ((int64_t)a[ 3]) * a[ 8] - + ((int64_t)a[ 4]) * a[ 7] - + ((int64_t)a[ 5]) * a[ 6]) * 2; - int64_t t12 = (((int64_t)a[ 3]) * a[ 9] - + ((int64_t)a[ 4]) * a[ 8] - + ((int64_t)a[ 5]) * a[ 7]) * 2 - + ((int64_t)a[ 6]) * a[ 6]; - int64_t t13 = (((int64_t)a[ 4]) * a[ 9] - + ((int64_t)a[ 5]) * a[ 8] - + ((int64_t)a[ 6]) * a[ 7]) * 2; - int64_t t14 = (((int64_t)a[ 5]) * a[ 9] - + ((int64_t)a[ 6]) * a[ 8]) * 2 - + ((int64_t)a[ 7]) * a[ 7]; - int64_t t15 = (((int64_t)a[ 6]) * a[ 9] - + ((int64_t)a[ 7]) * a[ 8]) * 2; - int64_t t16 = (((int64_t)a[ 7]) * a[ 9]) * 2 - + ((int64_t)a[ 8]) * a[ 8]; - int64_t t17 = (((int64_t)a[ 8]) * a[ 9]) * 2; - int64_t t18 = ((int64_t)a[ 9]) * a[ 9]; - - t1 += t0 >> 26; r[ 0] = t0 & 0x3ffffff; - t2 += t1 >> 26; r[ 1] = t1 & 0x3ffffff; - t3 += t2 >> 26; r[ 2] = t2 & 0x3ffffff; - t4 += t3 >> 26; r[ 3] = t3 & 0x3ffffff; - t5 += t4 >> 26; r[ 4] = t4 & 0x3ffffff; - t6 += t5 >> 26; r[ 5] = t5 & 0x3ffffff; - t7 += t6 >> 26; r[ 6] = t6 & 0x3ffffff; - t8 += t7 >> 26; r[ 7] = t7 & 0x3ffffff; - t9 += t8 >> 26; r[ 8] = t8 & 0x3ffffff; - t10 += t9 >> 26; r[ 9] = t9 & 0x3ffffff; - t11 += t10 >> 26; r[10] = t10 & 0x3ffffff; - t12 += t11 >> 26; r[11] = t11 & 0x3ffffff; - t13 += t12 >> 26; r[12] = t12 & 0x3ffffff; - t14 += t13 >> 26; r[13] = t13 & 0x3ffffff; - t15 += t14 >> 26; r[14] = t14 & 0x3ffffff; - t16 += t15 >> 26; r[15] = t15 & 0x3ffffff; - t17 += t16 >> 26; r[16] = t16 & 0x3ffffff; - t18 += t17 >> 26; r[17] = t17 & 0x3ffffff; - r[19] = (sp_digit)(t18 >> 26); - r[18] = t18 & 0x3ffffff; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Square the Montgomery form number. (r = a * a mod m) * * r Result of squaring. @@ -13512,8 +13476,8 @@ SP_NOINLINE static void sp_256_sqr_10(sp_digit* r, const sp_digit* a) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_256_mont_sqr_10(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_256_mont_sqr_10(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_256_sqr_10(r, a); sp_256_mont_reduce_10(r, m, mp); @@ -13537,7 +13501,7 @@ static void sp_256_mont_sqr_n_10(sp_digit* r, const sp_digit* a, int n, } } -#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */ +#endif /* !WOLFSSL_SP_SMALL | HAVE_COMP_KEY */ #ifdef WOLFSSL_SP_SMALL /* Mod-2 for the P256 curve. */ static const uint32_t p256_mod_minus_2[8] = { @@ -13621,7 +13585,8 @@ static void sp_256_mont_inv_10(sp_digit* r, const sp_digit* a, sp_digit* td) * p Montgomery form projective coordinate point. * t Temporary ordinate data. */ -static void sp_256_map_10(sp_point_256* r, const sp_point_256* p, sp_digit* t) +static void sp_256_map_10(sp_point_256* r, const sp_point_256* p, + sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2*10; @@ -13657,49 +13622,6 @@ static void sp_256_map_10(sp_point_256* r, const sp_point_256* p, sp_digit* t) } -#ifdef WOLFSSL_SP_SMALL -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_256_add_10(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 10; i++) { - r[i] = a[i] + b[i]; - } - - return 0; -} -#else -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_256_add_10(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - r[ 0] = a[ 0] + b[ 0]; - r[ 1] = a[ 1] + b[ 1]; - r[ 2] = a[ 2] + b[ 2]; - r[ 3] = a[ 3] + b[ 3]; - r[ 4] = a[ 4] + b[ 4]; - r[ 5] = a[ 5] + b[ 5]; - r[ 6] = a[ 6] + b[ 6]; - r[ 7] = a[ 7] + b[ 7]; - r[ 8] = a[ 8] + b[ 8]; - r[ 9] = a[ 9] + b[ 9]; - - return 0; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Add two Montgomery form numbers (r = a + b % m). * * r Result of addition. @@ -13752,50 +13674,6 @@ static void sp_256_mont_tpl_10(sp_digit* r, const sp_digit* a, const sp_digit* m sp_256_norm_10(r); } -#ifdef WOLFSSL_SP_SMALL -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_256_sub_10(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 10; i++) { - r[i] = a[i] - b[i]; - } - - return 0; -} - -#else -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_256_sub_10(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - r[ 0] = a[ 0] - b[ 0]; - r[ 1] = a[ 1] - b[ 1]; - r[ 2] = a[ 2] - b[ 2]; - r[ 3] = a[ 3] - b[ 3]; - r[ 4] = a[ 4] - b[ 4]; - r[ 5] = a[ 5] - b[ 5]; - r[ 6] = a[ 6] - b[ 6]; - r[ 7] = a[ 7] - b[ 7]; - r[ 8] = a[ 8] - b[ 8]; - r[ 9] = a[ 9] - b[ 9]; - - return 0; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Conditionally add a and b using the mask m. * m is -1 to add and 0 when not. * @@ -13848,13 +13726,13 @@ static void sp_256_mont_sub_10(sp_digit* r, const sp_digit* a, const sp_digit* b * r Result of shift. * a Number to shift. */ -SP_NOINLINE static void sp_256_rshift1_10(sp_digit* r, sp_digit* a) +SP_NOINLINE static void sp_256_rshift1_10(sp_digit* r, const sp_digit* a) { #ifdef WOLFSSL_SP_SMALL int i; for (i=0; i<9; i++) { - r[i] = ((a[i] >> 1) + (a[i + 1] << 25)) & 0x3ffffff; + r[i] = (a[i] >> 1) + ((a[i + 1] << 25) & 0x3ffffff); } #else r[0] = (a[0] >> 1) + ((a[1] << 25) & 0x3ffffff); @@ -14302,8 +14180,8 @@ static int sp_256_proj_point_add_10_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r, } #endif /* WOLFSSL_SP_NONBLOCK */ -static void sp_256_proj_point_add_10(sp_point_256* r, const sp_point_256* p, const sp_point_256* q, - sp_digit* t) +static void sp_256_proj_point_add_10(sp_point_256* r, + const sp_point_256* p, const sp_point_256* q, sp_digit* t) { const sp_point_256* ap[2]; sp_point_256* rp[2]; @@ -14389,10 +14267,150 @@ static void sp_256_proj_point_add_10(sp_point_256* r, const sp_point_256* p, con } } +/* Multiply a number by Montogmery normalizer mod modulus (prime). + * + * r The resulting Montgomery form number. + * a The number to convert. + * m The modulus (prime). + * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. + */ +static int sp_256_mod_mul_norm_10(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + int64_t* td; +#else + int64_t td[8]; + int64_t a32d[8]; +#endif + int64_t* t; + int64_t* a32; + int64_t o; + int err = MP_OKAY; + + (void)m; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + td = (int64_t*)XMALLOC(sizeof(int64_t) * 2 * 8, NULL, DYNAMIC_TYPE_ECC); + if (td == NULL) { + return MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + a32 = td + 8; +#else + t = td; + a32 = a32d; +#endif + + a32[0] = a[0]; + a32[0] |= a[1] << 26U; + a32[0] &= 0xffffffffL; + a32[1] = (a[1] >> 6); + a32[1] |= a[2] << 20U; + a32[1] &= 0xffffffffL; + a32[2] = (a[2] >> 12); + a32[2] |= a[3] << 14U; + a32[2] &= 0xffffffffL; + a32[3] = (a[3] >> 18); + a32[3] |= a[4] << 8U; + a32[3] &= 0xffffffffL; + a32[4] = (a[4] >> 24); + a32[4] |= a[5] << 2U; + a32[4] |= a[6] << 28U; + a32[4] &= 0xffffffffL; + a32[5] = (a[6] >> 4); + a32[5] |= a[7] << 22U; + a32[5] &= 0xffffffffL; + a32[6] = (a[7] >> 10); + a32[6] |= a[8] << 16U; + a32[6] &= 0xffffffffL; + a32[7] = (a[8] >> 16); + a32[7] |= a[9] << 10U; + a32[7] &= 0xffffffffL; + + /* 1 1 0 -1 -1 -1 -1 0 */ + t[0] = 0 + a32[0] + a32[1] - a32[3] - a32[4] - a32[5] - a32[6]; + /* 0 1 1 0 -1 -1 -1 -1 */ + t[1] = 0 + a32[1] + a32[2] - a32[4] - a32[5] - a32[6] - a32[7]; + /* 0 0 1 1 0 -1 -1 -1 */ + t[2] = 0 + a32[2] + a32[3] - a32[5] - a32[6] - a32[7]; + /* -1 -1 0 2 2 1 0 -1 */ + t[3] = 0 - a32[0] - a32[1] + 2 * a32[3] + 2 * a32[4] + a32[5] - a32[7]; + /* 0 -1 -1 0 2 2 1 0 */ + t[4] = 0 - a32[1] - a32[2] + 2 * a32[4] + 2 * a32[5] + a32[6]; + /* 0 0 -1 -1 0 2 2 1 */ + t[5] = 0 - a32[2] - a32[3] + 2 * a32[5] + 2 * a32[6] + a32[7]; + /* -1 -1 0 0 0 1 3 2 */ + t[6] = 0 - a32[0] - a32[1] + a32[5] + 3 * a32[6] + 2 * a32[7]; + /* 1 0 -1 -1 -1 -1 0 3 */ + t[7] = 0 + a32[0] - a32[2] - a32[3] - a32[4] - a32[5] + 3 * a32[7]; + + t[1] += t[0] >> 32U; t[0] &= 0xffffffffL; + t[2] += t[1] >> 32U; t[1] &= 0xffffffffL; + t[3] += t[2] >> 32U; t[2] &= 0xffffffffL; + t[4] += t[3] >> 32U; t[3] &= 0xffffffffL; + t[5] += t[4] >> 32U; t[4] &= 0xffffffffL; + t[6] += t[5] >> 32U; t[5] &= 0xffffffffL; + t[7] += t[6] >> 32U; t[6] &= 0xffffffffL; + o = t[7] >> 32U; t[7] &= 0xffffffffL; + t[0] += o; + t[3] -= o; + t[6] -= o; + t[7] += o; + t[1] += t[0] >> 32U; t[0] &= 0xffffffffL; + t[2] += t[1] >> 32U; t[1] &= 0xffffffffL; + t[3] += t[2] >> 32U; t[2] &= 0xffffffffL; + t[4] += t[3] >> 32U; t[3] &= 0xffffffffL; + t[5] += t[4] >> 32U; t[4] &= 0xffffffffL; + t[6] += t[5] >> 32U; t[5] &= 0xffffffffL; + t[7] += t[6] >> 32U; t[6] &= 0xffffffffL; + + r[0] = (sp_digit)(t[0]) & 0x3ffffffL; + r[1] = (sp_digit)(t[0] >> 26U); + r[1] |= (sp_digit)(t[1] << 6U); + r[1] &= 0x3ffffffL; + r[2] = (sp_digit)(t[1] >> 20U); + r[2] |= (sp_digit)(t[2] << 12U); + r[2] &= 0x3ffffffL; + r[3] = (sp_digit)(t[2] >> 14U); + r[3] |= (sp_digit)(t[3] << 18U); + r[3] &= 0x3ffffffL; + r[4] = (sp_digit)(t[3] >> 8U); + r[4] |= (sp_digit)(t[4] << 24U); + r[4] &= 0x3ffffffL; + r[5] = (sp_digit)(t[4] >> 2U) & 0x3ffffffL; + r[6] = (sp_digit)(t[4] >> 28U); + r[6] |= (sp_digit)(t[5] << 4U); + r[6] &= 0x3ffffffL; + r[7] = (sp_digit)(t[5] >> 22U); + r[7] |= (sp_digit)(t[6] << 10U); + r[7] &= 0x3ffffffL; + r[8] = (sp_digit)(t[6] >> 16U); + r[8] |= (sp_digit)(t[7] << 16U); + r[8] &= 0x3ffffffL; + r[9] = (sp_digit)(t[7] >> 10U); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_ECC); + } +#endif + + return err; +} + #ifdef WOLFSSL_SP_SMALL /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Small implementation using add and double that is cache attack resistant but + * allocates memory rather than use large stacks. + * 256 adds and doubles. + * * r Resulting point. * g Point to multiply. * k Scalar to multiply by. @@ -14516,8 +14534,8 @@ static int sp_256_ecc_mulmod_10_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r, #endif /* WOLFSSL_SP_NONBLOCK */ -static int sp_256_ecc_mulmod_10(sp_point_256* r, const sp_point_256* g, const sp_digit* k, - int map, int ct, void* heap) +static int sp_256_ecc_mulmod_10(sp_point_256* r, const sp_point_256* g, + const sp_digit* k, int map, int ct, void* heap) { #ifdef WOLFSSL_SP_NO_MALLOC sp_point_256 t[3]; @@ -14528,7 +14546,8 @@ static int sp_256_ecc_mulmod_10(sp_point_256* r, const sp_point_256* g, const sp #endif sp_digit n; int i; - int c, y; + int c; + int y; int err = MP_OKAY; /* Implementatio is constant time. */ @@ -14667,7 +14686,8 @@ static void sp_256_cond_copy_10(sp_digit* r, const sp_digit* a, const sp_digit m * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_10(sp_point_256* p, int n, sp_digit* t) +static void sp_256_proj_point_dbl_n_10(sp_point_256* p, int n, + sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*10; @@ -14755,8 +14775,8 @@ static void sp_256_proj_point_dbl_n_10(sp_point_256* p, int n, sp_digit* t) * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_store_10(sp_point_256* r, const sp_point_256* p, - int n, int m, sp_digit* t) +static void sp_256_proj_point_dbl_n_store_10(sp_point_256* r, + const sp_point_256* p, int n, int m, sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*10; @@ -14767,6 +14787,7 @@ static void sp_256_proj_point_dbl_n_store_10(sp_point_256* r, const sp_point_256 sp_digit* y = r[(1<x[i]; @@ -14783,7 +14804,10 @@ static void sp_256_proj_point_dbl_n_store_10(sp_point_256* r, const sp_point_256 /* W = Z^4 */ sp_256_mont_sqr_10(w, z, p256_mod, p256_mp_mod); sp_256_mont_sqr_10(w, w, p256_mod, p256_mp_mod); + j = m; for (i=1; i<=n; i++) { + j *= 2; + /* A = 3*(X^2 - W) */ sp_256_mont_sqr_10(t1, x, p256_mod, p256_mp_mod); sp_256_mont_sub_10(t1, t1, w, p256_mod); @@ -14791,14 +14815,14 @@ static void sp_256_proj_point_dbl_n_store_10(sp_point_256* r, const sp_point_256 /* B = X*Y^2 */ sp_256_mont_sqr_10(t2, y, p256_mod, p256_mp_mod); sp_256_mont_mul_10(b, t2, x, p256_mod, p256_mp_mod); - x = r[(1<y); + sp_256_norm_10(negy); sp_256_cond_copy_10(p->y, negy, (sp_digit)0 - v[i].neg); sp_256_proj_point_add_10(rt, rt, p, tmp); } @@ -15298,6 +15326,10 @@ static void sp_256_proj_to_affine_10(sp_point_256* a, sp_digit* t) } /* Generate the pre-computed table of points for the base point. + * + * width = 8 + * 256 entries + * 32 bits between * * a The base point. * table Place to store generated point data. @@ -15308,12 +15340,15 @@ static int sp_256_gen_stripe_table_10(const sp_point_256* a, sp_table_entry_256* table, sp_digit* tmp, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_point_256 td, s1d, s2d; + sp_point_256 td; + sp_point_256 s1d; + sp_point_256 s2d; #endif sp_point_256* t; sp_point_256* s1 = NULL; sp_point_256* s2 = NULL; - int i, j; + int i; + int j; int err; (void)heap; @@ -15440,8 +15475,10 @@ static void sp_256_get_entry_256_10(sp_point_256* r, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Implementation uses striping of bits. - * Choose bits 8 bits apart. + * Stripe implementation. + * Pre-generated: 2^0, 2^32, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) * * r Resulting point. * k Scalar to multiply by. @@ -15463,8 +15500,10 @@ static int sp_256_ecc_mulmod_stripe_10(sp_point_256* r, const sp_point_256* g, sp_point_256* rt; sp_point_256* p = NULL; sp_digit* t; - int i, j; - int y, x; + int i; + int j; + int y; + int x; int err; (void)g; @@ -15492,8 +15531,10 @@ static int sp_256_ecc_mulmod_stripe_10(sp_point_256* r, const sp_point_256* g, XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod)); y = 0; - for (j=0,x=31; j<8; j++,x+=32) { + x = 31; + for (j=0; j<8; j++) { y |= (int)(((k[x / 26] >> (x % 26)) & 1) << j); + x += 32; } #ifndef WC_NO_CACHE_RESISTANT if (ct) { @@ -15507,8 +15548,10 @@ static int sp_256_ecc_mulmod_stripe_10(sp_point_256* r, const sp_point_256* g, rt->infinity = !y; for (i=30; i>=0; i--) { y = 0; - for (j=0,x=i; j<8; j++,x+=32) { + x = i; + for (j=0; j<8; j++) { y |= (int)(((k[x / 26] >> (x % 26)) & 1) << j); + x += 32; } sp_256_proj_point_dbl_10(rt, rt, t); @@ -15550,16 +15593,25 @@ static int sp_256_ecc_mulmod_stripe_10(sp_point_256* r, const sp_point_256* g, #define FP_ENTRIES 16 #endif +/* Cache entry - holds precomputation tables for a point. */ typedef struct sp_cache_256_t { + /* X ordinate of point that table was generated from. */ sp_digit x[10]; + /* Y ordinate of point that table was generated from. */ sp_digit y[10]; + /* Precomputation table for point. */ sp_table_entry_256 table[256]; + /* Count of entries in table. */ uint32_t cnt; + /* Point and table set in entry. */ int set; } sp_cache_256_t; +/* Cache of tables. */ static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES]; +/* Index of last entry in cache. */ static THREAD_LS_T int sp_cache_256_last = -1; +/* Cache has been initialized. */ static THREAD_LS_T int sp_cache_256_inited = 0; #ifndef HAVE_THREAD_LS @@ -15567,9 +15619,15 @@ static THREAD_LS_T int sp_cache_256_inited = 0; static wolfSSL_Mutex sp_cache_256_lock; #endif +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache) { - int i, j; + int i; + int j; uint32_t least; if (sp_cache_256_inited == 0) { @@ -15686,8 +15744,8 @@ static int sp_256_ecc_mulmod_10(sp_point_256* r, const sp_point_256* g, const sp * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, - void* heap) +int sp_ecc_mulmod_256(const mp_int* km, const ecc_point* gm, ecc_point* r, + int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_256 p; @@ -15728,6 +15786,89 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, return err; } +/* Multiply the point by the scalar, add point a and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * p Point to multiply. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_add_256(const mp_int* km, const ecc_point* gm, + const ecc_point* am, int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_256 p; + sp_point_256 a; + sp_digit kd[10]; + sp_digit t[10 * 2 * 5]; +#endif + sp_point_256* point; + sp_point_256* addP = NULL; + sp_digit* k = NULL; + sp_digit* tmp = NULL; + int err = MP_OKAY; + + err = sp_256_point_new_10(heap, p, point); + if (err == MP_OKAY) { + err = sp_256_point_new_10(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (10 + 10 * 2 * 5), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 10; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_256_from_mp(k, 10, km); + sp_256_point_from_ecc_point_10(point, gm); + sp_256_point_from_ecc_point_10(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_10(addP->x, addP->x, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_10(addP->y, addP->y, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_10(addP->z, addP->z, p256_mod); + } + if (err == MP_OKAY) { + err = sp_256_ecc_mulmod_10(point, point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_256_proj_point_add_10(point, point, addP, tmp); + + if (map) { + sp_256_map_10(point, point, tmp); + } + + err = sp_256_point_to_ecc_point_10(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_256_point_free_10(addP, 0, heap); + sp_256_point_free_10(point, 0, heap); + + return err; +} + #ifdef WOLFSSL_SP_SMALL /* Multiply the base point of P256 by the scalar and return the result. * If map is true then convert result to affine coordinates. @@ -15746,6 +15887,10 @@ static int sp_256_ecc_mulmod_base_10(sp_point_256* r, const sp_digit* k, } #else +/* Striping precomputation table. + * 8 points combined into a table of 256 points. + * Distance of 32 between points. + */ static const sp_table_entry_256 p256_table[256] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -17030,6 +17175,11 @@ static const sp_table_entry_256 p256_table[256] = { /* Multiply the base point of P256 by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Stripe implementation. + * Pre-generated: 2^0, 2^32, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * * r Resulting point. * k Scalar to multiply by. * map Indicates whether to convert result to affine. @@ -17055,7 +17205,7 @@ static int sp_256_ecc_mulmod_base_10(sp_point_256* r, const sp_digit* k, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) +int sp_ecc_mulmod_base_256(const mp_int* km, ecc_point* r, int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_256 p; @@ -17096,6 +17246,87 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) return err; } +/* Multiply the base point of P256 by the scalar, add point a and return + * the result. If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_add_256(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_256 p; + sp_point_256 a; + sp_digit kd[10]; + sp_digit t[10 * 2 * 5]; +#endif + sp_point_256* point; + sp_point_256* addP = NULL; + sp_digit* tmp = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_256_point_new_10(heap, p, point); + if (err == MP_OKAY) { + err = sp_256_point_new_10(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (10 + 10 * 2 * 5), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 10; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_256_from_mp(k, 10, km); + sp_256_point_from_ecc_point_10(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_10(addP->x, addP->x, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_10(addP->y, addP->y, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_10(addP->z, addP->z, p256_mod); + } + if (err == MP_OKAY) { + err = sp_256_ecc_mulmod_base_10(point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_256_proj_point_add_10(point, point, addP, tmp); + + if (map) { + sp_256_map_10(point, point, tmp); + } + + err = sp_256_point_to_ecc_point_10(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_256_point_free_10(addP, 0, heap); + sp_256_point_free_10(point, 0, heap); + + return err; +} + #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \ defined(HAVE_ECC_VERIFY) /* Returns 1 if the number of zero. @@ -17110,7 +17341,7 @@ static int sp_256_iszero_10(const sp_digit* a) a[8] | a[9]) == 0; } -#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN | HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ /* Add 1 to a. (a = a + 1) * * r A single precision integer. @@ -17131,7 +17362,8 @@ SP_NOINLINE static void sp_256_add_one_10(sp_digit* a) */ static void sp_256_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -17275,7 +17507,10 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) */ static void sp_256_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; for (i=0; i<9; i++) { r[i+1] += r[i] >> 26; @@ -17320,7 +17555,7 @@ static void sp_256_to_bin(sp_digit* r, byte* a) * returns BUFFER_E if the buffer is to small for output size, * MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, +int sp_ecc_secret_gen_256(const mp_int* priv, const ecc_point* pub, byte* out, word32* outLen, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) @@ -17425,7 +17660,9 @@ SP_NOINLINE static void sp_256_mul_d_10(sp_digit* r, const sp_digit* a, static WC_INLINE sp_digit sp_256_div_word_10(sp_digit d1, sp_digit d0, sp_digit dv) { - sp_digit d, r, t; + sp_digit d; + sp_digit r; + sp_digit t; /* All 26 bits from d1 and top 5 bits from d0. */ d = (d1 << 5) | (d0 >> 21); @@ -17478,24 +17715,28 @@ static WC_INLINE sp_digit sp_256_div_word_10(sp_digit d1, sp_digit d0, /* Divide d in a and put remainder into r (m*d + r = a) * m is not calculated as it is not needed at this time. * + * Large number of bits in last word. + * * a Number to be divided. * d Number to divide with. * m Multiplier result. * r Remainder from the division. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise. */ -static int sp_256_div_10(const sp_digit* a, const sp_digit* d, sp_digit* m, - sp_digit* r) +static int sp_256_div_10(const sp_digit* a, const sp_digit* d, + const sp_digit* m, sp_digit* r) { int i; #ifndef WOLFSSL_SP_DIV_32 int64_t d1; #endif - sp_digit dv, r1; + sp_digit dv; + sp_digit r1; #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* td; #else - sp_digit t1d[20], t2d[10 + 1]; + sp_digit t1d[20]; + sp_digit t2d[10 + 1]; #endif sp_digit* t1; sp_digit* t2; @@ -17523,17 +17764,15 @@ static int sp_256_div_10(const sp_digit* a, const sp_digit* d, sp_digit* m, dv = d[9]; XMEMCPY(t1, a, sizeof(*t1) * 2U * 10U); for (i=9; i>=0; i--) { - sp_digit hi; t1[10 + i] += t1[10 + i - 1] >> 26; t1[10 + i - 1] &= 0x3ffffff; - hi = t1[10 + i] - (t1[10 + i] == dv); #ifndef WOLFSSL_SP_DIV_32 - d1 = hi; + d1 = t1[10 + i]; d1 <<= 26; d1 += t1[10 + i - 1]; r1 = (sp_digit)(d1 / dv); #else - r1 = sp_256_div_word_10(hi, t1[10 + i - 1], dv); + r1 = sp_256_div_word_10(t1[10 + i], t1[10 + i - 1], dv); #endif sp_256_mul_d_10(t2, d, r1); @@ -17554,7 +17793,7 @@ static int sp_256_div_10(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_256_mul_d_10(t2, d, r1); (void)sp_256_sub_10(t1, t1, t2); - XMEMCPY(r, t1, sizeof(*r) * 2U * 10U); + XMEMCPY(r, t1, sizeof(*r) * 20U); for (i=0; i<9; i++) { r[i+1] += r[i] >> 26; r[i] &= 0x3ffffff; @@ -17594,7 +17833,7 @@ static const uint32_t p256_order_minus_2[8] = { }; #else /* The low half of the order-2 of the P256 curve. */ -static const uint32_t p256_order_low[4] = { +static const sp_int_digit p256_order_low[4] = { 0xfc63254fU,0xf3b9cac2U,0xa7179e84U,0xbce6faadU }; #endif /* WOLFSSL_SP_SMALL */ @@ -17740,7 +17979,7 @@ static void sp_256_mont_inv_order_10(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6 */ for (i=127; i>=112; i--) { sp_256_mont_sqr_order_10(t2, t2); - if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_256_mont_mul_order_10(t2, t2, a); } } @@ -17750,7 +17989,7 @@ static void sp_256_mont_inv_order_10(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84 */ for (i=107; i>=64; i--) { sp_256_mont_sqr_order_10(t2, t2); - if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_256_mont_mul_order_10(t2, t2, a); } } @@ -17760,7 +17999,7 @@ static void sp_256_mont_inv_order_10(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2 */ for (i=59; i>=32; i--) { sp_256_mont_sqr_order_10(t2, t2); - if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_256_mont_mul_order_10(t2, t2, a); } } @@ -17770,7 +18009,7 @@ static void sp_256_mont_inv_order_10(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254 */ for (i=27; i>=0; i--) { sp_256_mont_sqr_order_10(t2, t2); - if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_256_mont_mul_order_10(t2, t2, a); } } @@ -17781,12 +18020,63 @@ static void sp_256_mont_inv_order_10(sp_digit* r, const sp_digit* a, #endif /* WOLFSSL_SP_SMALL */ } -#endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ #ifdef HAVE_ECC_SIGN #ifndef SP_ECC_MAX_SIG_GEN #define SP_ECC_MAX_SIG_GEN 64 #endif +/* Calculate second signature value S from R, k and private value. + * + * s = (r * x + e) / k + * + * s Signature value. + * r First signature value. + * k Ephemeral private key. + * x Private key as a number. + * e Hash of message as a number. + * tmp Temporary storage for intermediate numbers. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_256_calc_s_10(sp_digit* s, const sp_digit* r, sp_digit* k, + sp_digit* x, const sp_digit* e, sp_digit* tmp) +{ + int err; + sp_digit carry; + int32_t c; + sp_digit* kInv = k; + + /* Conv k to Montgomery form (mod order) */ + sp_256_mul_10(k, k, p256_norm_order); + err = sp_256_mod_10(k, k, p256_order); + if (err == MP_OKAY) { + sp_256_norm_10(k); + + /* kInv = 1/k mod order */ + sp_256_mont_inv_order_10(kInv, k, tmp); + sp_256_norm_10(kInv); + + /* s = r * x + e */ + sp_256_mul_10(x, x, r); + err = sp_256_mod_10(x, x, p256_order); + } + if (err == MP_OKAY) { + sp_256_norm_10(x); + carry = sp_256_add_10(s, e, x); + sp_256_cond_sub_10(s, s, p256_order, 0 - carry); + sp_256_norm_10(s); + c = sp_256_cmp_10(s, p256_order); + sp_256_cond_sub_10(s, s, p256_order, 0L - (sp_digit)(c >= 0)); + sp_256_norm_10(s); + + /* s = s * k^-1 mod order */ + sp_256_mont_mul_order_10(s, s, kInv); + sp_256_norm_10(s); + } + + return err; +} + /* Sign the hash using the private key. * e = [hash, 256 bits] from binary * r = (k.G)->x mod order @@ -17821,8 +18111,8 @@ typedef struct sp_ecc_sign_256_ctx { int i; } sp_ecc_sign_256_ctx; -int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, + mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_sign_256_ctx* ctx = (sp_ecc_sign_256_ctx*)sp_ctx->data; @@ -17962,8 +18252,8 @@ int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, W } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, + const mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -17981,11 +18271,9 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit* r = NULL; sp_digit* tmp = NULL; sp_point_256* point = NULL; - sp_digit carry; sp_digit* s = NULL; - sp_digit* kInv = NULL; - int err = MP_OKAY; int32_t c; + int err = MP_OKAY; int i; (void)heap; @@ -18016,7 +18304,6 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, tmp = td; #endif s = e; - kInv = k; if (hashLen > 32U) { hashLen = 32U; @@ -18024,8 +18311,6 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, } for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) { - sp_256_from_mp(x, 10, priv); - /* New random point. */ if (km == NULL || mp_iszero(km)) { err = sp_256_ecc_gen_k_10(rng, k); @@ -18035,7 +18320,7 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, mp_zero(km); } if (err == MP_OKAY) { - err = sp_256_ecc_mulmod_base_10(point, k, 1, 1, NULL); + err = sp_256_ecc_mulmod_base_10(point, k, 1, 1, heap); } if (err == MP_OKAY) { @@ -18046,38 +18331,15 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_256_cond_sub_10(r, r, p256_order, 0L - (sp_digit)(c >= 0)); sp_256_norm_10(r); - /* Conv k to Montgomery form (mod order) */ - sp_256_mul_10(k, k, p256_norm_order); - err = sp_256_mod_10(k, k, p256_order); - } - if (err == MP_OKAY) { - sp_256_norm_10(k); - /* kInv = 1/k mod order */ - sp_256_mont_inv_order_10(kInv, k, tmp); - sp_256_norm_10(kInv); - - /* s = r * x + e */ - sp_256_mul_10(x, x, r); - err = sp_256_mod_10(x, x, p256_order); - } - if (err == MP_OKAY) { - sp_256_norm_10(x); + sp_256_from_mp(x, 10, priv); sp_256_from_bin(e, 10, hash, (int)hashLen); - carry = sp_256_add_10(s, e, x); - sp_256_cond_sub_10(s, s, p256_order, 0 - carry); - sp_256_norm_10(s); - c = sp_256_cmp_10(s, p256_order); - sp_256_cond_sub_10(s, s, p256_order, 0L - (sp_digit)(c >= 0)); - sp_256_norm_10(s); - /* s = s * k^-1 mod order */ - sp_256_mont_mul_order_10(s, s, kInv); - sp_256_norm_10(s); + err = sp_256_calc_s_10(s, r, k, x, e, tmp); + } - /* Check that signature is usable. */ - if (sp_256_iszero_10(s) == 0) { - break; - } + /* Check that signature is usable. */ + if ((err == MP_OKAY) && (sp_256_iszero_10(s) == 0)) { + break; } #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP i = 1; @@ -18105,7 +18367,6 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, XMEMSET(x, 0, sizeof(sp_digit) * 2U * 10U); XMEMSET(k, 0, sizeof(sp_digit) * 2U * 10U); XMEMSET(r, 0, sizeof(sp_digit) * 2U * 10U); - XMEMSET(r, 0, sizeof(sp_digit) * 2U * 10U); XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 10U); #endif sp_256_point_free_10(point, 1, heap); @@ -18270,6 +18531,98 @@ static int sp_256_mod_inv_10(sp_digit* r, const sp_digit* a, const sp_digit* m) } #endif /* WOLFSSL_SP_SMALL */ + +/* Add point p1 into point p2. Handles p1 == p2 and result at infinity. + * + * p1 First point to add and holds result. + * p2 Second point to add. + * tmp Temporary storage for intermediate numbers. + */ +static void sp_256_add_points_10(sp_point_256* p1, const sp_point_256* p2, + sp_digit* tmp) +{ + + sp_256_proj_point_add_10(p1, p1, p2, tmp); + if (sp_256_iszero_10(p1->z)) { + if (sp_256_iszero_10(p1->x) && sp_256_iszero_10(p1->y)) { + sp_256_proj_point_dbl_10(p1, p2, tmp); + } + else { + /* Y ordinate is not used from here - don't set. */ + p1->x[0] = 0; + p1->x[1] = 0; + p1->x[2] = 0; + p1->x[3] = 0; + p1->x[4] = 0; + p1->x[5] = 0; + p1->x[6] = 0; + p1->x[7] = 0; + p1->x[8] = 0; + p1->x[9] = 0; + XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod)); + } + } +} + +/* Calculate the verification point: [e/s]G + [r/s]Q + * + * p1 Calculated point. + * p2 Public point and temporary. + * s Second part of signature as a number. + * u1 Temporary number. + * u2 Temproray number. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_256_calc_vfy_point_10(sp_point_256* p1, sp_point_256* p2, + sp_digit* s, sp_digit* u1, sp_digit* u2, sp_digit* tmp, void* heap) +{ + int err; + +#ifndef WOLFSSL_SP_SMALL + { + sp_256_mod_inv_10(s, s, p256_order); + } +#endif /* !WOLFSSL_SP_SMALL */ + { + sp_256_mul_10(s, s, p256_norm_order); + } + err = sp_256_mod_10(s, s, p256_order); + if (err == MP_OKAY) { + sp_256_norm_10(s); +#ifdef WOLFSSL_SP_SMALL + { + sp_256_mont_inv_order_10(s, s, tmp); + sp_256_mont_mul_order_10(u1, u1, s); + sp_256_mont_mul_order_10(u2, u2, s); + } + +#else + { + sp_256_mont_mul_order_10(u1, u1, s); + sp_256_mont_mul_order_10(u2, u2, s); + } + +#endif /* WOLFSSL_SP_SMALL */ + err = sp_256_ecc_mulmod_base_10(p1, u1, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_256_iszero_10(p1->z)) { + p1->infinity = 1; + } + if (err == MP_OKAY) { + err = sp_256_ecc_mulmod_10(p2, p2, u2, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_256_iszero_10(p2->z)) { + p2->infinity = 1; + } + + if (err == MP_OKAY) { + sp_256_add_points_10(p1, p2, tmp); + } + + return err; +} + #ifdef HAVE_ECC_VERIFY /* Verify the signature values with the hash and public key. * e = Truncate(hash, 256) @@ -18288,8 +18641,7 @@ static int sp_256_mod_inv_10(sp_digit* r, const sp_digit* a, const sp_digit* m) * rm First part of result as an mp_int. * sm Sirst part of result as an mp_int. * heap Heap to use for allocation. - * returns RNG failures, MEMORY_E when memory allocation fails and - * MP_OKAY on success. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ #ifdef WOLFSSL_SP_NONBLOCK typedef struct sp_ecc_verify_256_ctx { @@ -18308,8 +18660,9 @@ typedef struct sp_ecc_verify_256_ctx { sp_point_256 p2; } sp_ecc_verify_256_ctx; -int sp_ecc_verify_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, + word32 hashLen, const mp_int* pX, const mp_int* pY, const mp_int* pZ, + const mp_int* r, const mp_int* sm, int* res, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_verify_256_ctx* ctx = (sp_ecc_verify_256_ctx*)sp_ctx->data; @@ -18463,8 +18816,9 @@ int sp_ecc_verify_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_256(const byte* hash, word32 hashLen, const mp_int* pX, + const mp_int* pY, const mp_int* pZ, const mp_int* r, const mp_int* sm, + int* res, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -18483,7 +18837,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_point_256* p1; sp_point_256* p2 = NULL; sp_digit carry; - int32_t c; + int32_t c = 0; int err; err = sp_256_point_new_10(heap, p1d, p1); @@ -18524,68 +18878,9 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_256_from_mp(p2->y, 10, pY); sp_256_from_mp(p2->z, 10, pZ); -#ifndef WOLFSSL_SP_SMALL - { - sp_256_mod_inv_10(s, s, p256_order); - } -#endif /* !WOLFSSL_SP_SMALL */ - { - sp_256_mul_10(s, s, p256_norm_order); - } - err = sp_256_mod_10(s, s, p256_order); + err = sp_256_calc_vfy_point_10(p1, p2, s, u1, u2, tmp, heap); } if (err == MP_OKAY) { - sp_256_norm_10(s); -#ifdef WOLFSSL_SP_SMALL - { - sp_256_mont_inv_order_10(s, s, tmp); - sp_256_mont_mul_order_10(u1, u1, s); - sp_256_mont_mul_order_10(u2, u2, s); - } - -#else - { - sp_256_mont_mul_order_10(u1, u1, s); - sp_256_mont_mul_order_10(u2, u2, s); - } - -#endif /* WOLFSSL_SP_SMALL */ - err = sp_256_ecc_mulmod_base_10(p1, u1, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_256_iszero_10(p1->z)) { - p1->infinity = 1; - } - if (err == MP_OKAY) { - err = sp_256_ecc_mulmod_10(p2, p2, u2, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_256_iszero_10(p2->z)) { - p2->infinity = 1; - } - - if (err == MP_OKAY) { - { - sp_256_proj_point_add_10(p1, p1, p2, tmp); - if (sp_256_iszero_10(p1->z)) { - if (sp_256_iszero_10(p1->x) && sp_256_iszero_10(p1->y)) { - sp_256_proj_point_dbl_10(p1, p2, tmp); - } - else { - /* Y ordinate is not used from here - don't set. */ - p1->x[0] = 0; - p1->x[1] = 0; - p1->x[2] = 0; - p1->x[3] = 0; - p1->x[4] = 0; - p1->x[5] = 0; - p1->x[6] = 0; - p1->x[7] = 0; - p1->x[8] = 0; - p1->x[9] = 0; - XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod)); - } - } - } - /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */ /* Reload r and convert to Montgomery form. */ sp_256_from_mp(u2, 10, r); @@ -18607,16 +18902,16 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, /* Compare with mod and if greater or equal then not valid. */ c = sp_256_cmp_10(u2, p256_mod); - if (c < 0) { - /* Convert to Montogomery form */ - err = sp_256_mod_mul_norm_10(u2, u2, p256_mod); - if (err == MP_OKAY) { - /* u1 = (r + 1*order).z'.z' mod prime */ - sp_256_mont_mul_10(u1, u2, p1->z, p256_mod, - p256_mp_mod); - *res = (int)(sp_256_cmp_10(p1->x, u1) == 0); - } - } + } + } + if ((*res == 0) && (c < 0)) { + /* Convert to Montogomery form */ + err = sp_256_mod_mul_norm_10(u2, u2, p256_mod); + if (err == MP_OKAY) { + /* u1 = (r + 1*order).z'.z' mod prime */ + sp_256_mont_mul_10(u1, u2, p1->z, p256_mod, + p256_mp_mod); + *res = (sp_256_cmp_10(p1->x, u1) == 0); } } } @@ -18640,7 +18935,8 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -static int sp_256_ecc_is_point_10(sp_point_256* point, void* heap) +static int sp_256_ecc_is_point_10(const sp_point_256* point, + void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -18703,7 +18999,7 @@ static int sp_256_ecc_is_point_10(sp_point_256* point, void* heap) * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) +int sp_ecc_is_point_256(const mp_int* pX, const mp_int* pY) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_256 pubd; @@ -18737,7 +19033,8 @@ int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and * MP_OKAY otherwise. */ -int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) +int sp_ecc_check_key_256(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit privd[10]; @@ -18791,12 +19088,11 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) } } - if (err == MP_OKAY) { - /* Check range of X and Y */ - if (sp_256_cmp_10(pub->x, p256_mod) >= 0 || - sp_256_cmp_10(pub->y, p256_mod) >= 0) { - err = ECC_OUT_OF_RANGE_E; - } + /* Check range of X and Y */ + if ((err == MP_OKAY) && + ((sp_256_cmp_10(pub->x, p256_mod) >= 0) || + (sp_256_cmp_10(pub->y, p256_mod) >= 0))) { + err = ECC_OUT_OF_RANGE_E; } if (err == MP_OKAY) { @@ -18808,12 +19104,10 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Point * order = infinity */ err = sp_256_ecc_mulmod_10(p, pub, p256_order, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is infinity */ - if ((sp_256_iszero_10(p->x) == 0) || - (sp_256_iszero_10(p->y) == 0)) { - err = ECC_INF_E; - } + /* Check result is infinity */ + if ((err == MP_OKAY) && ((sp_256_iszero_10(p->x) == 0) || + (sp_256_iszero_10(p->y) == 0))) { + err = ECC_INF_E; } if (privm) { @@ -18821,12 +19115,11 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Base * private = point */ err = sp_256_ecc_mulmod_base_10(p, priv, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is public key */ - if (sp_256_cmp_10(p->x, pub->x) != 0 || - sp_256_cmp_10(p->y, pub->y) != 0) { - err = ECC_PRIV_KEY_E; - } + /* Check result is public key */ + if ((err == MP_OKAY) && + ((sp_256_cmp_10(p->x, pub->x) != 0) || + (sp_256_cmp_10(p->y, pub->y) != 0))) { + err = ECC_PRIV_KEY_E; } } @@ -19016,7 +19309,7 @@ int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ) sp_256_from_mp(p->y, 10, pY); sp_256_from_mp(p->z, 10, pZ); - sp_256_map_10(p, p, tmp); + sp_256_map_10(p, p, tmp); } if (err == MP_OKAY) { @@ -19196,23 +19489,27 @@ int sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym) /* Point structure to use. */ typedef struct sp_point_384 { + /* X ordinate of point. */ sp_digit x[2 * 15]; + /* Y ordinate of point. */ sp_digit y[2 * 15]; + /* Z ordinate of point. */ sp_digit z[2 * 15]; + /* Indicates point is at infinity. */ int infinity; } sp_point_384; /* The modulus (prime) of the curve P384. */ static const sp_digit p384_mod[15] = { 0x3ffffff,0x000003f,0x0000000,0x3fc0000,0x2ffffff,0x3ffffff,0x3ffffff, - 0x3ffffff,0x3ffffff,0x3ffffff,0x3ffffff,0x3ffffff,0x3ffffff,0x3ffffff,0x00fffff - + 0x3ffffff,0x3ffffff,0x3ffffff,0x3ffffff,0x3ffffff,0x3ffffff,0x3ffffff, + 0x00fffff }; /* The Montogmery normalizer for modulus of the curve P384. */ static const sp_digit p384_norm_mod[15] = { 0x0000001,0x3ffffc0,0x3ffffff,0x003ffff,0x1000000,0x0000000,0x0000000, - 0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000 - + 0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000, + 0x0000000 }; /* The Montogmery multiplier for modulus of the curve P384. */ static sp_digit p384_mp_mod = 0x000001; @@ -19221,22 +19518,22 @@ static sp_digit p384_mp_mod = 0x000001; /* The order of the curve P384. */ static const sp_digit p384_order[15] = { 0x0c52973,0x3065ab3,0x277aece,0x2c922c2,0x3581a0d,0x10dcb77,0x234d81f, - 0x3ffff1d,0x3ffffff,0x3ffffff,0x3ffffff,0x3ffffff,0x3ffffff,0x3ffffff,0x00fffff - + 0x3ffff1d,0x3ffffff,0x3ffffff,0x3ffffff,0x3ffffff,0x3ffffff,0x3ffffff, + 0x00fffff }; #endif /* The order of the curve P384 minus 2. */ static const sp_digit p384_order2[15] = { 0x0c52971,0x3065ab3,0x277aece,0x2c922c2,0x3581a0d,0x10dcb77,0x234d81f, - 0x3ffff1d,0x3ffffff,0x3ffffff,0x3ffffff,0x3ffffff,0x3ffffff,0x3ffffff,0x00fffff - + 0x3ffff1d,0x3ffffff,0x3ffffff,0x3ffffff,0x3ffffff,0x3ffffff,0x3ffffff, + 0x00fffff }; #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) /* The Montogmery normalizer for order of the curve P384. */ static const sp_digit p384_norm_order[15] = { 0x33ad68d,0x0f9a54c,0x1885131,0x136dd3d,0x0a7e5f2,0x2f23488,0x1cb27e0, - 0x00000e2,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000 - + 0x00000e2,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000, + 0x0000000 }; #endif #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) @@ -19248,22 +19545,22 @@ static const sp_point_384 p384_base = { /* X ordinate */ { 0x2760ab7,0x1178e1c,0x296c3a5,0x176fd54,0x05502f2,0x0950a8e,0x3741e08, - 0x26e6167,0x3628ba7,0x11b874e,0x3320ad7,0x2c71c7b,0x305378e,0x288afa2,0x00aa87c, - + 0x26e6167,0x3628ba7,0x11b874e,0x3320ad7,0x2c71c7b,0x305378e,0x288afa2, + 0x00aa87c, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L }, /* Y ordinate */ { 0x0ea0e5f,0x0c75f24,0x019d7a4,0x33875fa,0x00a60b1,0x17c2e30,0x1a3113b, - 0x051f3a7,0x1bd289a,0x27e3d07,0x1292dc2,0x27a62fe,0x22c6f5d,0x392a589,0x003617d, - + 0x051f3a7,0x1bd289a,0x27e3d07,0x1292dc2,0x27a62fe,0x22c6f5d,0x392a589, + 0x003617d, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L }, /* Z ordinate */ { 0x0000001,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000, - 0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000, - + 0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000, + 0x0000000, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L }, /* infinity */ @@ -19272,416 +19569,11 @@ static const sp_point_384 p384_base = { #if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY) static const sp_digit p384_b[15] = { 0x3ec2aef,0x1723b74,0x119d2a8,0x23628bb,0x2c65639,0x004e1d6,0x14088f5, - 0x104480c,0x06efe81,0x2460767,0x23f82d1,0x23815af,0x2e7e498,0x3e9f88f,0x00b3312 - + 0x104480c,0x06efe81,0x2460767,0x23f82d1,0x23815af,0x2e7e498,0x3e9f88f, + 0x00b3312 }; #endif -static int sp_384_point_new_ex_15(void* heap, sp_point_384* sp, sp_point_384** p) -{ - int ret = MP_OKAY; - (void)heap; -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - (void)sp; - *p = (sp_point_384*)XMALLOC(sizeof(sp_point_384), heap, DYNAMIC_TYPE_ECC); -#else - *p = sp; -#endif - if (*p == NULL) { - ret = MEMORY_E; - } - return ret; -} - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) -/* Allocate memory for point and return error. */ -#define sp_384_point_new_15(heap, sp, p) sp_384_point_new_ex_15((heap), NULL, &(p)) -#else -/* Set pointer to data and return no error. */ -#define sp_384_point_new_15(heap, sp, p) sp_384_point_new_ex_15((heap), &(sp), &(p)) -#endif - - -static void sp_384_point_free_15(sp_point_384* p, int clear, void* heap) -{ -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) -/* If valid pointer then clear point data if requested and free data. */ - if (p != NULL) { - if (clear != 0) { - XMEMSET(p, 0, sizeof(*p)); - } - XFREE(p, heap, DYNAMIC_TYPE_ECC); - } -#else -/* Clear point data if requested. */ - if (clear != 0) { - XMEMSET(p, 0, sizeof(*p)); - } -#endif - (void)heap; -} - -/* Multiply a number by Montogmery normalizer mod modulus (prime). - * - * r The resulting Montgomery form number. - * a The number to convert. - * m The modulus (prime). - * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. - */ -static int sp_384_mod_mul_norm_15(sp_digit* r, const sp_digit* a, const sp_digit* m) -{ -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - int64_t* td; -#else - int64_t td[12]; - int64_t a32d[12]; -#endif - int64_t* t; - int64_t* a32; - int64_t o; - int err = MP_OKAY; - - (void)m; - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - td = (int64_t*)XMALLOC(sizeof(int64_t) * 2 * 12, NULL, DYNAMIC_TYPE_ECC); - if (td == NULL) { - err = MEMORY_E; - } -#endif - - if (err == MP_OKAY) { -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - t = td; - a32 = td + 12; -#else - t = td; - a32 = a32d; -#endif - - a32[0] = a[0]; - a32[0] |= a[1] << 26U; - a32[0] &= 0xffffffffL; - a32[1] = (sp_digit)(a[1] >> 6); - a32[1] |= a[2] << 20U; - a32[1] &= 0xffffffffL; - a32[2] = (sp_digit)(a[2] >> 12); - a32[2] |= a[3] << 14U; - a32[2] &= 0xffffffffL; - a32[3] = (sp_digit)(a[3] >> 18); - a32[3] |= a[4] << 8U; - a32[3] &= 0xffffffffL; - a32[4] = (sp_digit)(a[4] >> 24); - a32[4] |= a[5] << 2U; - a32[4] |= a[6] << 28U; - a32[4] &= 0xffffffffL; - a32[5] = (sp_digit)(a[6] >> 4); - a32[5] |= a[7] << 22U; - a32[5] &= 0xffffffffL; - a32[6] = (sp_digit)(a[7] >> 10); - a32[6] |= a[8] << 16U; - a32[6] &= 0xffffffffL; - a32[7] = (sp_digit)(a[8] >> 16); - a32[7] |= a[9] << 10U; - a32[7] &= 0xffffffffL; - a32[8] = (sp_digit)(a[9] >> 22); - a32[8] |= a[10] << 4U; - a32[8] |= a[11] << 30U; - a32[8] &= 0xffffffffL; - a32[9] = (sp_digit)(a[11] >> 2); - a32[9] |= a[12] << 24U; - a32[9] &= 0xffffffffL; - a32[10] = (sp_digit)(a[12] >> 8); - a32[10] |= a[13] << 18U; - a32[10] &= 0xffffffffL; - a32[11] = (sp_digit)(a[13] >> 14); - a32[11] |= a[14] << 12U; - a32[11] &= 0xffffffffL; - - /* 1 0 0 0 0 0 0 0 1 1 0 -1 */ - t[0] = 0 + a32[0] + a32[8] + a32[9] - a32[11]; - /* -1 1 0 0 0 0 0 0 -1 0 1 1 */ - t[1] = 0 - a32[0] + a32[1] - a32[8] + a32[10] + a32[11]; - /* 0 -1 1 0 0 0 0 0 0 -1 0 1 */ - t[2] = 0 - a32[1] + a32[2] - a32[9] + a32[11]; - /* 1 0 -1 1 0 0 0 0 1 1 -1 -1 */ - t[3] = 0 + a32[0] - a32[2] + a32[3] + a32[8] + a32[9] - a32[10] - a32[11]; - /* 1 1 0 -1 1 0 0 0 1 2 1 -2 */ - t[4] = 0 + a32[0] + a32[1] - a32[3] + a32[4] + a32[8] + 2 * a32[9] + a32[10] - 2 * a32[11]; - /* 0 1 1 0 -1 1 0 0 0 1 2 1 */ - t[5] = 0 + a32[1] + a32[2] - a32[4] + a32[5] + a32[9] + 2 * a32[10] + a32[11]; - /* 0 0 1 1 0 -1 1 0 0 0 1 2 */ - t[6] = 0 + a32[2] + a32[3] - a32[5] + a32[6] + a32[10] + 2 * a32[11]; - /* 0 0 0 1 1 0 -1 1 0 0 0 1 */ - t[7] = 0 + a32[3] + a32[4] - a32[6] + a32[7] + a32[11]; - /* 0 0 0 0 1 1 0 -1 1 0 0 0 */ - t[8] = 0 + a32[4] + a32[5] - a32[7] + a32[8]; - /* 0 0 0 0 0 1 1 0 -1 1 0 0 */ - t[9] = 0 + a32[5] + a32[6] - a32[8] + a32[9]; - /* 0 0 0 0 0 0 1 1 0 -1 1 0 */ - t[10] = 0 + a32[6] + a32[7] - a32[9] + a32[10]; - /* 0 0 0 0 0 0 0 1 1 0 -1 1 */ - t[11] = 0 + a32[7] + a32[8] - a32[10] + a32[11]; - - t[1] += t[0] >> 32; t[0] &= 0xffffffff; - t[2] += t[1] >> 32; t[1] &= 0xffffffff; - t[3] += t[2] >> 32; t[2] &= 0xffffffff; - t[4] += t[3] >> 32; t[3] &= 0xffffffff; - t[5] += t[4] >> 32; t[4] &= 0xffffffff; - t[6] += t[5] >> 32; t[5] &= 0xffffffff; - t[7] += t[6] >> 32; t[6] &= 0xffffffff; - t[8] += t[7] >> 32; t[7] &= 0xffffffff; - t[9] += t[8] >> 32; t[8] &= 0xffffffff; - t[10] += t[9] >> 32; t[9] &= 0xffffffff; - t[11] += t[10] >> 32; t[10] &= 0xffffffff; - o = t[11] >> 32; t[11] &= 0xffffffff; - t[0] += o; - t[1] -= o; - t[3] += o; - t[4] += o; - t[1] += t[0] >> 32; t[0] &= 0xffffffff; - t[2] += t[1] >> 32; t[1] &= 0xffffffff; - t[3] += t[2] >> 32; t[2] &= 0xffffffff; - t[4] += t[3] >> 32; t[3] &= 0xffffffff; - t[5] += t[4] >> 32; t[4] &= 0xffffffff; - t[6] += t[5] >> 32; t[5] &= 0xffffffff; - t[7] += t[6] >> 32; t[6] &= 0xffffffff; - t[8] += t[7] >> 32; t[7] &= 0xffffffff; - t[9] += t[8] >> 32; t[8] &= 0xffffffff; - t[10] += t[9] >> 32; t[9] &= 0xffffffff; - t[11] += t[10] >> 32; t[10] &= 0xffffffff; - - r[0] = (sp_digit)(t[0]) & 0x3ffffffL; - r[1] = (sp_digit)(t[0] >> 26U); - r[1] |= (sp_digit)(t[1] << 6U); - r[1] &= 0x3ffffffL; - r[2] = (sp_digit)(t[1] >> 20U); - r[2] |= (sp_digit)(t[2] << 12U); - r[2] &= 0x3ffffffL; - r[3] = (sp_digit)(t[2] >> 14U); - r[3] |= (sp_digit)(t[3] << 18U); - r[3] &= 0x3ffffffL; - r[4] = (sp_digit)(t[3] >> 8U); - r[4] |= (sp_digit)(t[4] << 24U); - r[4] &= 0x3ffffffL; - r[5] = (sp_digit)(t[4] >> 2U) & 0x3ffffffL; - r[6] = (sp_digit)(t[4] >> 28U); - r[6] |= (sp_digit)(t[5] << 4U); - r[6] &= 0x3ffffffL; - r[7] = (sp_digit)(t[5] >> 22U); - r[7] |= (sp_digit)(t[6] << 10U); - r[7] &= 0x3ffffffL; - r[8] = (sp_digit)(t[6] >> 16U); - r[8] |= (sp_digit)(t[7] << 16U); - r[8] &= 0x3ffffffL; - r[9] = (sp_digit)(t[7] >> 10U); - r[9] |= (sp_digit)(t[8] << 22U); - r[9] &= 0x3ffffffL; - r[10] = (sp_digit)(t[8] >> 4U) & 0x3ffffffL; - r[11] = (sp_digit)(t[8] >> 30U); - r[11] |= (sp_digit)(t[9] << 2U); - r[11] &= 0x3ffffffL; - r[12] = (sp_digit)(t[9] >> 24U); - r[12] |= (sp_digit)(t[10] << 8U); - r[12] &= 0x3ffffffL; - r[13] = (sp_digit)(t[10] >> 18U); - r[13] |= (sp_digit)(t[11] << 14U); - r[13] &= 0x3ffffffL; - r[14] = (sp_digit)(t[11] >> 12U); - } - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - if (td != NULL) - XFREE(td, NULL, DYNAMIC_TYPE_ECC); -#endif - - return err; -} - -/* Convert an mp_int to an array of sp_digit. - * - * r A single precision integer. - * size Maximum number of bytes to convert - * a A multi-precision integer. - */ -static void sp_384_from_mp(sp_digit* r, int size, const mp_int* a) -{ -#if DIGIT_BIT == 26 - int j; - - XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); - - for (j = a->used; j < size; j++) { - r[j] = 0; - } -#elif DIGIT_BIT > 26 - int i, j = 0; - word32 s = 0; - - r[0] = 0; - for (i = 0; i < a->used && j < size; i++) { - r[j] |= ((sp_digit)a->dp[i] << s); - r[j] &= 0x3ffffff; - s = 26U - s; - if (j + 1 >= size) { - break; - } - /* lint allow cast of mismatch word32 and mp_digit */ - r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ - while ((s + 26U) <= (word32)DIGIT_BIT) { - s += 26U; - r[j] &= 0x3ffffff; - if (j + 1 >= size) { - break; - } - if (s < (word32)DIGIT_BIT) { - /* lint allow cast of mismatch word32 and mp_digit */ - r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ - } - else { - r[++j] = 0L; - } - } - s = (word32)DIGIT_BIT - s; - } - - for (j++; j < size; j++) { - r[j] = 0; - } -#else - int i, j = 0, s = 0; - - r[0] = 0; - for (i = 0; i < a->used && j < size; i++) { - r[j] |= ((sp_digit)a->dp[i]) << s; - if (s + DIGIT_BIT >= 26) { - r[j] &= 0x3ffffff; - if (j + 1 >= size) { - break; - } - s = 26 - s; - if (s == DIGIT_BIT) { - r[++j] = 0; - s = 0; - } - else { - r[++j] = a->dp[i] >> s; - s = DIGIT_BIT - s; - } - } - else { - s += DIGIT_BIT; - } - } - - for (j++; j < size; j++) { - r[j] = 0; - } -#endif -} - -/* Convert a point of type ecc_point to type sp_point_384. - * - * p Point of type sp_point_384 (result). - * pm Point of type ecc_point. - */ -static void sp_384_point_from_ecc_point_15(sp_point_384* p, const ecc_point* pm) -{ - XMEMSET(p->x, 0, sizeof(p->x)); - XMEMSET(p->y, 0, sizeof(p->y)); - XMEMSET(p->z, 0, sizeof(p->z)); - sp_384_from_mp(p->x, 15, pm->x); - sp_384_from_mp(p->y, 15, pm->y); - sp_384_from_mp(p->z, 15, pm->z); - p->infinity = 0; -} - -/* Convert an array of sp_digit to an mp_int. - * - * a A single precision integer. - * r A multi-precision integer. - */ -static int sp_384_to_mp(const sp_digit* a, mp_int* r) -{ - int err; - - err = mp_grow(r, (384 + DIGIT_BIT - 1) / DIGIT_BIT); - if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ -#if DIGIT_BIT == 26 - XMEMCPY(r->dp, a, sizeof(sp_digit) * 15); - r->used = 15; - mp_clamp(r); -#elif DIGIT_BIT < 26 - int i, j = 0, s = 0; - - r->dp[0] = 0; - for (i = 0; i < 15; i++) { - r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; - s = DIGIT_BIT - s; - r->dp[++j] = (mp_digit)(a[i] >> s); - while (s + DIGIT_BIT <= 26) { - s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; - if (s == SP_WORD_SIZE) { - r->dp[j] = 0; - } - else { - r->dp[j] = (mp_digit)(a[i] >> s); - } - } - s = 26 - s; - } - r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; - mp_clamp(r); -#else - int i, j = 0, s = 0; - - r->dp[0] = 0; - for (i = 0; i < 15; i++) { - r->dp[j] |= ((mp_digit)a[i]) << s; - if (s + 26 >= DIGIT_BIT) { - #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; - #endif - s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; - s = 26 - s; - } - else { - s += 26; - } - } - r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; - mp_clamp(r); -#endif - } - - return err; -} - -/* Convert a point of type sp_point_384 to type ecc_point. - * - * p Point of type sp_point_384. - * pm Point of type ecc_point (result). - * returns MEMORY_E when allocation of memory in ecc_point fails otherwise - * MP_OKAY. - */ -static int sp_384_point_to_ecc_point_15(const sp_point_384* p, ecc_point* pm) -{ - int err; - - err = sp_384_to_mp(p->x, pm->x); - if (err == MP_OKAY) { - err = sp_384_to_mp(p->y, pm->y); - } - if (err == MP_OKAY) { - err = sp_384_to_mp(p->z, pm->z); - } - - return err; -} - #ifdef WOLFSSL_SP_SMALL /* Multiply a and b into r. (r = a * b) * @@ -19692,7 +19584,9 @@ static int sp_384_point_to_ecc_point_15(const sp_point_384* p, ecc_point* pm) SP_NOINLINE static void sp_384_mul_15(sp_digit* r, const sp_digit* a, const sp_digit* b) { - int i, j, k; + int i; + int j; + int k; int64_t c; c = ((int64_t)a[14]) * b[14]; @@ -19986,6 +19880,554 @@ SP_NOINLINE static void sp_384_mul_15(sp_digit* r, const sp_digit* a, } #endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_384_sqr_15(sp_digit* r, const sp_digit* a) +{ + int i; + int j; + int k; + int64_t c; + + c = ((int64_t)a[14]) * a[14]; + r[29] = (sp_digit)(c >> 26); + c = (c & 0x3ffffff) << 26; + for (k = 27; k >= 0; k--) { + for (i = 14; i >= 0; i--) { + j = k - i; + if (j >= 15 || i <= j) { + break; + } + if (j < 0) { + continue; + } + + c += ((int64_t)a[i]) * a[j] * 2; + } + if (i == j) { + c += ((int64_t)a[i]) * a[i]; + } + + r[k + 2] += (sp_digit)(c >> 52); + r[k + 1] = (sp_digit)((c >> 26) & 0x3ffffff); + c = (c & 0x3ffffff) << 26; + } + r[0] = (sp_digit)(c >> 26); +} + +#else +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_384_sqr_15(sp_digit* r, const sp_digit* a) +{ + int64_t t0 = ((int64_t)a[ 0]) * a[ 0]; + int64_t t1 = (((int64_t)a[ 0]) * a[ 1]) * 2; + int64_t t2 = (((int64_t)a[ 0]) * a[ 2]) * 2 + + ((int64_t)a[ 1]) * a[ 1]; + int64_t t3 = (((int64_t)a[ 0]) * a[ 3] + + ((int64_t)a[ 1]) * a[ 2]) * 2; + int64_t t4 = (((int64_t)a[ 0]) * a[ 4] + + ((int64_t)a[ 1]) * a[ 3]) * 2 + + ((int64_t)a[ 2]) * a[ 2]; + int64_t t5 = (((int64_t)a[ 0]) * a[ 5] + + ((int64_t)a[ 1]) * a[ 4] + + ((int64_t)a[ 2]) * a[ 3]) * 2; + int64_t t6 = (((int64_t)a[ 0]) * a[ 6] + + ((int64_t)a[ 1]) * a[ 5] + + ((int64_t)a[ 2]) * a[ 4]) * 2 + + ((int64_t)a[ 3]) * a[ 3]; + int64_t t7 = (((int64_t)a[ 0]) * a[ 7] + + ((int64_t)a[ 1]) * a[ 6] + + ((int64_t)a[ 2]) * a[ 5] + + ((int64_t)a[ 3]) * a[ 4]) * 2; + int64_t t8 = (((int64_t)a[ 0]) * a[ 8] + + ((int64_t)a[ 1]) * a[ 7] + + ((int64_t)a[ 2]) * a[ 6] + + ((int64_t)a[ 3]) * a[ 5]) * 2 + + ((int64_t)a[ 4]) * a[ 4]; + int64_t t9 = (((int64_t)a[ 0]) * a[ 9] + + ((int64_t)a[ 1]) * a[ 8] + + ((int64_t)a[ 2]) * a[ 7] + + ((int64_t)a[ 3]) * a[ 6] + + ((int64_t)a[ 4]) * a[ 5]) * 2; + int64_t t10 = (((int64_t)a[ 0]) * a[10] + + ((int64_t)a[ 1]) * a[ 9] + + ((int64_t)a[ 2]) * a[ 8] + + ((int64_t)a[ 3]) * a[ 7] + + ((int64_t)a[ 4]) * a[ 6]) * 2 + + ((int64_t)a[ 5]) * a[ 5]; + int64_t t11 = (((int64_t)a[ 0]) * a[11] + + ((int64_t)a[ 1]) * a[10] + + ((int64_t)a[ 2]) * a[ 9] + + ((int64_t)a[ 3]) * a[ 8] + + ((int64_t)a[ 4]) * a[ 7] + + ((int64_t)a[ 5]) * a[ 6]) * 2; + int64_t t12 = (((int64_t)a[ 0]) * a[12] + + ((int64_t)a[ 1]) * a[11] + + ((int64_t)a[ 2]) * a[10] + + ((int64_t)a[ 3]) * a[ 9] + + ((int64_t)a[ 4]) * a[ 8] + + ((int64_t)a[ 5]) * a[ 7]) * 2 + + ((int64_t)a[ 6]) * a[ 6]; + int64_t t13 = (((int64_t)a[ 0]) * a[13] + + ((int64_t)a[ 1]) * a[12] + + ((int64_t)a[ 2]) * a[11] + + ((int64_t)a[ 3]) * a[10] + + ((int64_t)a[ 4]) * a[ 9] + + ((int64_t)a[ 5]) * a[ 8] + + ((int64_t)a[ 6]) * a[ 7]) * 2; + int64_t t14 = (((int64_t)a[ 0]) * a[14] + + ((int64_t)a[ 1]) * a[13] + + ((int64_t)a[ 2]) * a[12] + + ((int64_t)a[ 3]) * a[11] + + ((int64_t)a[ 4]) * a[10] + + ((int64_t)a[ 5]) * a[ 9] + + ((int64_t)a[ 6]) * a[ 8]) * 2 + + ((int64_t)a[ 7]) * a[ 7]; + int64_t t15 = (((int64_t)a[ 1]) * a[14] + + ((int64_t)a[ 2]) * a[13] + + ((int64_t)a[ 3]) * a[12] + + ((int64_t)a[ 4]) * a[11] + + ((int64_t)a[ 5]) * a[10] + + ((int64_t)a[ 6]) * a[ 9] + + ((int64_t)a[ 7]) * a[ 8]) * 2; + int64_t t16 = (((int64_t)a[ 2]) * a[14] + + ((int64_t)a[ 3]) * a[13] + + ((int64_t)a[ 4]) * a[12] + + ((int64_t)a[ 5]) * a[11] + + ((int64_t)a[ 6]) * a[10] + + ((int64_t)a[ 7]) * a[ 9]) * 2 + + ((int64_t)a[ 8]) * a[ 8]; + int64_t t17 = (((int64_t)a[ 3]) * a[14] + + ((int64_t)a[ 4]) * a[13] + + ((int64_t)a[ 5]) * a[12] + + ((int64_t)a[ 6]) * a[11] + + ((int64_t)a[ 7]) * a[10] + + ((int64_t)a[ 8]) * a[ 9]) * 2; + int64_t t18 = (((int64_t)a[ 4]) * a[14] + + ((int64_t)a[ 5]) * a[13] + + ((int64_t)a[ 6]) * a[12] + + ((int64_t)a[ 7]) * a[11] + + ((int64_t)a[ 8]) * a[10]) * 2 + + ((int64_t)a[ 9]) * a[ 9]; + int64_t t19 = (((int64_t)a[ 5]) * a[14] + + ((int64_t)a[ 6]) * a[13] + + ((int64_t)a[ 7]) * a[12] + + ((int64_t)a[ 8]) * a[11] + + ((int64_t)a[ 9]) * a[10]) * 2; + int64_t t20 = (((int64_t)a[ 6]) * a[14] + + ((int64_t)a[ 7]) * a[13] + + ((int64_t)a[ 8]) * a[12] + + ((int64_t)a[ 9]) * a[11]) * 2 + + ((int64_t)a[10]) * a[10]; + int64_t t21 = (((int64_t)a[ 7]) * a[14] + + ((int64_t)a[ 8]) * a[13] + + ((int64_t)a[ 9]) * a[12] + + ((int64_t)a[10]) * a[11]) * 2; + int64_t t22 = (((int64_t)a[ 8]) * a[14] + + ((int64_t)a[ 9]) * a[13] + + ((int64_t)a[10]) * a[12]) * 2 + + ((int64_t)a[11]) * a[11]; + int64_t t23 = (((int64_t)a[ 9]) * a[14] + + ((int64_t)a[10]) * a[13] + + ((int64_t)a[11]) * a[12]) * 2; + int64_t t24 = (((int64_t)a[10]) * a[14] + + ((int64_t)a[11]) * a[13]) * 2 + + ((int64_t)a[12]) * a[12]; + int64_t t25 = (((int64_t)a[11]) * a[14] + + ((int64_t)a[12]) * a[13]) * 2; + int64_t t26 = (((int64_t)a[12]) * a[14]) * 2 + + ((int64_t)a[13]) * a[13]; + int64_t t27 = (((int64_t)a[13]) * a[14]) * 2; + int64_t t28 = ((int64_t)a[14]) * a[14]; + + t1 += t0 >> 26; r[ 0] = t0 & 0x3ffffff; + t2 += t1 >> 26; r[ 1] = t1 & 0x3ffffff; + t3 += t2 >> 26; r[ 2] = t2 & 0x3ffffff; + t4 += t3 >> 26; r[ 3] = t3 & 0x3ffffff; + t5 += t4 >> 26; r[ 4] = t4 & 0x3ffffff; + t6 += t5 >> 26; r[ 5] = t5 & 0x3ffffff; + t7 += t6 >> 26; r[ 6] = t6 & 0x3ffffff; + t8 += t7 >> 26; r[ 7] = t7 & 0x3ffffff; + t9 += t8 >> 26; r[ 8] = t8 & 0x3ffffff; + t10 += t9 >> 26; r[ 9] = t9 & 0x3ffffff; + t11 += t10 >> 26; r[10] = t10 & 0x3ffffff; + t12 += t11 >> 26; r[11] = t11 & 0x3ffffff; + t13 += t12 >> 26; r[12] = t12 & 0x3ffffff; + t14 += t13 >> 26; r[13] = t13 & 0x3ffffff; + t15 += t14 >> 26; r[14] = t14 & 0x3ffffff; + t16 += t15 >> 26; r[15] = t15 & 0x3ffffff; + t17 += t16 >> 26; r[16] = t16 & 0x3ffffff; + t18 += t17 >> 26; r[17] = t17 & 0x3ffffff; + t19 += t18 >> 26; r[18] = t18 & 0x3ffffff; + t20 += t19 >> 26; r[19] = t19 & 0x3ffffff; + t21 += t20 >> 26; r[20] = t20 & 0x3ffffff; + t22 += t21 >> 26; r[21] = t21 & 0x3ffffff; + t23 += t22 >> 26; r[22] = t22 & 0x3ffffff; + t24 += t23 >> 26; r[23] = t23 & 0x3ffffff; + t25 += t24 >> 26; r[24] = t24 & 0x3ffffff; + t26 += t25 >> 26; r[25] = t25 & 0x3ffffff; + t27 += t26 >> 26; r[26] = t26 & 0x3ffffff; + t28 += t27 >> 26; r[27] = t27 & 0x3ffffff; + r[29] = (sp_digit)(t28 >> 26); + r[28] = t28 & 0x3ffffff; +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_384_add_15(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + int i; + + for (i = 0; i < 15; i++) { + r[i] = a[i] + b[i]; + } + + return 0; +} +#else +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_384_add_15(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + r[ 0] = a[ 0] + b[ 0]; + r[ 1] = a[ 1] + b[ 1]; + r[ 2] = a[ 2] + b[ 2]; + r[ 3] = a[ 3] + b[ 3]; + r[ 4] = a[ 4] + b[ 4]; + r[ 5] = a[ 5] + b[ 5]; + r[ 6] = a[ 6] + b[ 6]; + r[ 7] = a[ 7] + b[ 7]; + r[ 8] = a[ 8] + b[ 8]; + r[ 9] = a[ 9] + b[ 9]; + r[10] = a[10] + b[10]; + r[11] = a[11] + b[11]; + r[12] = a[12] + b[12]; + r[13] = a[13] + b[13]; + r[14] = a[14] + b[14]; + + return 0; +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_384_sub_15(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + int i; + + for (i = 0; i < 15; i++) { + r[i] = a[i] - b[i]; + } + + return 0; +} + +#else +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_384_sub_15(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + r[ 0] = a[ 0] - b[ 0]; + r[ 1] = a[ 1] - b[ 1]; + r[ 2] = a[ 2] - b[ 2]; + r[ 3] = a[ 3] - b[ 3]; + r[ 4] = a[ 4] - b[ 4]; + r[ 5] = a[ 5] - b[ 5]; + r[ 6] = a[ 6] - b[ 6]; + r[ 7] = a[ 7] - b[ 7]; + r[ 8] = a[ 8] - b[ 8]; + r[ 9] = a[ 9] - b[ 9]; + r[10] = a[10] - b[10]; + r[11] = a[11] - b[11]; + r[12] = a[12] - b[12]; + r[13] = a[13] - b[13]; + r[14] = a[14] - b[14]; + + return 0; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Create a new point. + * + * heap [in] Buffer to allocate dynamic memory from. + * sp [in] Data for point - only if not allocating. + * p [out] New point. + * returns MEMORY_E when dynamic memory allocation fails and 0 otherwise. + */ +static int sp_384_point_new_ex_15(void* heap, sp_point_384* sp, + sp_point_384** p) +{ + int ret = MP_OKAY; + (void)heap; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + (void)sp; + *p = (sp_point_384*)XMALLOC(sizeof(sp_point_384), heap, DYNAMIC_TYPE_ECC); +#else + *p = sp; +#endif + if (*p == NULL) { + ret = MEMORY_E; + } + return ret; +} + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* Allocate memory for point and return error. */ +#define sp_384_point_new_15(heap, sp, p) sp_384_point_new_ex_15((heap), NULL, &(p)) +#else +/* Set pointer to data and return no error. */ +#define sp_384_point_new_15(heap, sp, p) sp_384_point_new_ex_15((heap), &(sp), &(p)) +#endif + + +/* Free the point. + * + * p [in,out] Point to free. + * clear [in] Indicates whether to zeroize point. + * heap [in] Buffer from which dynamic memory was allocate from. + */ +static void sp_384_point_free_15(sp_point_384* p, int clear, void* heap) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* If valid pointer then clear point data if requested and free data. */ + if (p != NULL) { + if (clear != 0) { + XMEMSET(p, 0, sizeof(*p)); + } + XFREE(p, heap, DYNAMIC_TYPE_ECC); + } +#else +/* Clear point data if requested. */ + if ((p != NULL) && (clear != 0)) { + XMEMSET(p, 0, sizeof(*p)); + } +#endif + (void)heap; +} + +/* Convert an mp_int to an array of sp_digit. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a A multi-precision integer. + */ +static void sp_384_from_mp(sp_digit* r, int size, const mp_int* a) +{ +#if DIGIT_BIT == 26 + int j; + + XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); + + for (j = a->used; j < size; j++) { + r[j] = 0; + } +#elif DIGIT_BIT > 26 + int i; + int j = 0; + word32 s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i] << s); + r[j] &= 0x3ffffff; + s = 26U - s; + if (j + 1 >= size) { + break; + } + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + while ((s + 26U) <= (word32)DIGIT_BIT) { + s += 26U; + r[j] &= 0x3ffffff; + if (j + 1 >= size) { + break; + } + if (s < (word32)DIGIT_BIT) { + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + } + else { + r[++j] = 0L; + } + } + s = (word32)DIGIT_BIT - s; + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#else + int i; + int j = 0; + int s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i]) << s; + if (s + DIGIT_BIT >= 26) { + r[j] &= 0x3ffffff; + if (j + 1 >= size) { + break; + } + s = 26 - s; + if (s == DIGIT_BIT) { + r[++j] = 0; + s = 0; + } + else { + r[++j] = a->dp[i] >> s; + s = DIGIT_BIT - s; + } + } + else { + s += DIGIT_BIT; + } + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#endif +} + +/* Convert a point of type ecc_point to type sp_point_384. + * + * p Point of type sp_point_384 (result). + * pm Point of type ecc_point. + */ +static void sp_384_point_from_ecc_point_15(sp_point_384* p, + const ecc_point* pm) +{ + XMEMSET(p->x, 0, sizeof(p->x)); + XMEMSET(p->y, 0, sizeof(p->y)); + XMEMSET(p->z, 0, sizeof(p->z)); + sp_384_from_mp(p->x, 15, pm->x); + sp_384_from_mp(p->y, 15, pm->y); + sp_384_from_mp(p->z, 15, pm->z); + p->infinity = 0; +} + +/* Convert an array of sp_digit to an mp_int. + * + * a A single precision integer. + * r A multi-precision integer. + */ +static int sp_384_to_mp(const sp_digit* a, mp_int* r) +{ + int err; + + err = mp_grow(r, (384 + DIGIT_BIT - 1) / DIGIT_BIT); + if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ +#if DIGIT_BIT == 26 + XMEMCPY(r->dp, a, sizeof(sp_digit) * 15); + r->used = 15; + mp_clamp(r); +#elif DIGIT_BIT < 26 + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 15; i++) { + r->dp[j] |= (mp_digit)(a[i] << s); + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + s = DIGIT_BIT - s; + r->dp[++j] = (mp_digit)(a[i] >> s); + while (s + DIGIT_BIT <= 26) { + s += DIGIT_BIT; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; + if (s == SP_WORD_SIZE) { + r->dp[j] = 0; + } + else { + r->dp[j] = (mp_digit)(a[i] >> s); + } + } + s = 26 - s; + } + r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#else + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 15; i++) { + r->dp[j] |= ((mp_digit)a[i]) << s; + if (s + 26 >= DIGIT_BIT) { + #if DIGIT_BIT != 32 && DIGIT_BIT != 64 + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + #endif + s = DIGIT_BIT - s; + r->dp[++j] = a[i] >> s; + s = 26 - s; + } + else { + s += 26; + } + } + r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#endif + } + + return err; +} + +/* Convert a point of type sp_point_384 to type ecc_point. + * + * p Point of type sp_point_384. + * pm Point of type ecc_point (result). + * returns MEMORY_E when allocation of memory in ecc_point fails otherwise + * MP_OKAY. + */ +static int sp_384_point_to_ecc_point_15(const sp_point_384* p, ecc_point* pm) +{ + int err; + + err = sp_384_to_mp(p->x, pm->x); + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, pm->y); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, pm->z); + } + + return err; +} + #define sp_384_mont_reduce_order_15 sp_384_mont_reduce_15 /* Compare a with b in constant time. @@ -20211,7 +20653,6 @@ static void sp_384_mont_reduce_15(sp_digit* a, const sp_digit* m, sp_digit mp) sp_384_mul_add_15(a+i, m, mu); a[i+1] += a[i] >> 26; a[i] &= 0x3ffffff; - sp_384_mont_shift_15(a, a); sp_384_cond_sub_15(a, a, m, 0 - (((a[14] >> 20) > 0) ? (sp_digit)1 : (sp_digit)0)); @@ -20227,212 +20668,13 @@ static void sp_384_mont_reduce_15(sp_digit* a, const sp_digit* m, sp_digit mp) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_384_mont_mul_15(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_384_mont_mul_15(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_384_mul_15(r, a, b); sp_384_mont_reduce_15(r, m, mp); } -#ifdef WOLFSSL_SP_SMALL -/* Square a and put result in r. (r = a * a) - * - * r A single precision integer. - * a A single precision integer. - */ -SP_NOINLINE static void sp_384_sqr_15(sp_digit* r, const sp_digit* a) -{ - int i, j, k; - int64_t c; - - c = ((int64_t)a[14]) * a[14]; - r[29] = (sp_digit)(c >> 26); - c = (c & 0x3ffffff) << 26; - for (k = 27; k >= 0; k--) { - for (i = 14; i >= 0; i--) { - j = k - i; - if (j >= 15 || i <= j) { - break; - } - if (j < 0) { - continue; - } - - c += ((int64_t)a[i]) * a[j] * 2; - } - if (i == j) { - c += ((int64_t)a[i]) * a[i]; - } - - r[k + 2] += (sp_digit)(c >> 52); - r[k + 1] = (sp_digit)((c >> 26) & 0x3ffffff); - c = (c & 0x3ffffff) << 26; - } - r[0] = (sp_digit)(c >> 26); -} - -#else -/* Square a and put result in r. (r = a * a) - * - * r A single precision integer. - * a A single precision integer. - */ -SP_NOINLINE static void sp_384_sqr_15(sp_digit* r, const sp_digit* a) -{ - int64_t t0 = ((int64_t)a[ 0]) * a[ 0]; - int64_t t1 = (((int64_t)a[ 0]) * a[ 1]) * 2; - int64_t t2 = (((int64_t)a[ 0]) * a[ 2]) * 2 - + ((int64_t)a[ 1]) * a[ 1]; - int64_t t3 = (((int64_t)a[ 0]) * a[ 3] - + ((int64_t)a[ 1]) * a[ 2]) * 2; - int64_t t4 = (((int64_t)a[ 0]) * a[ 4] - + ((int64_t)a[ 1]) * a[ 3]) * 2 - + ((int64_t)a[ 2]) * a[ 2]; - int64_t t5 = (((int64_t)a[ 0]) * a[ 5] - + ((int64_t)a[ 1]) * a[ 4] - + ((int64_t)a[ 2]) * a[ 3]) * 2; - int64_t t6 = (((int64_t)a[ 0]) * a[ 6] - + ((int64_t)a[ 1]) * a[ 5] - + ((int64_t)a[ 2]) * a[ 4]) * 2 - + ((int64_t)a[ 3]) * a[ 3]; - int64_t t7 = (((int64_t)a[ 0]) * a[ 7] - + ((int64_t)a[ 1]) * a[ 6] - + ((int64_t)a[ 2]) * a[ 5] - + ((int64_t)a[ 3]) * a[ 4]) * 2; - int64_t t8 = (((int64_t)a[ 0]) * a[ 8] - + ((int64_t)a[ 1]) * a[ 7] - + ((int64_t)a[ 2]) * a[ 6] - + ((int64_t)a[ 3]) * a[ 5]) * 2 - + ((int64_t)a[ 4]) * a[ 4]; - int64_t t9 = (((int64_t)a[ 0]) * a[ 9] - + ((int64_t)a[ 1]) * a[ 8] - + ((int64_t)a[ 2]) * a[ 7] - + ((int64_t)a[ 3]) * a[ 6] - + ((int64_t)a[ 4]) * a[ 5]) * 2; - int64_t t10 = (((int64_t)a[ 0]) * a[10] - + ((int64_t)a[ 1]) * a[ 9] - + ((int64_t)a[ 2]) * a[ 8] - + ((int64_t)a[ 3]) * a[ 7] - + ((int64_t)a[ 4]) * a[ 6]) * 2 - + ((int64_t)a[ 5]) * a[ 5]; - int64_t t11 = (((int64_t)a[ 0]) * a[11] - + ((int64_t)a[ 1]) * a[10] - + ((int64_t)a[ 2]) * a[ 9] - + ((int64_t)a[ 3]) * a[ 8] - + ((int64_t)a[ 4]) * a[ 7] - + ((int64_t)a[ 5]) * a[ 6]) * 2; - int64_t t12 = (((int64_t)a[ 0]) * a[12] - + ((int64_t)a[ 1]) * a[11] - + ((int64_t)a[ 2]) * a[10] - + ((int64_t)a[ 3]) * a[ 9] - + ((int64_t)a[ 4]) * a[ 8] - + ((int64_t)a[ 5]) * a[ 7]) * 2 - + ((int64_t)a[ 6]) * a[ 6]; - int64_t t13 = (((int64_t)a[ 0]) * a[13] - + ((int64_t)a[ 1]) * a[12] - + ((int64_t)a[ 2]) * a[11] - + ((int64_t)a[ 3]) * a[10] - + ((int64_t)a[ 4]) * a[ 9] - + ((int64_t)a[ 5]) * a[ 8] - + ((int64_t)a[ 6]) * a[ 7]) * 2; - int64_t t14 = (((int64_t)a[ 0]) * a[14] - + ((int64_t)a[ 1]) * a[13] - + ((int64_t)a[ 2]) * a[12] - + ((int64_t)a[ 3]) * a[11] - + ((int64_t)a[ 4]) * a[10] - + ((int64_t)a[ 5]) * a[ 9] - + ((int64_t)a[ 6]) * a[ 8]) * 2 - + ((int64_t)a[ 7]) * a[ 7]; - int64_t t15 = (((int64_t)a[ 1]) * a[14] - + ((int64_t)a[ 2]) * a[13] - + ((int64_t)a[ 3]) * a[12] - + ((int64_t)a[ 4]) * a[11] - + ((int64_t)a[ 5]) * a[10] - + ((int64_t)a[ 6]) * a[ 9] - + ((int64_t)a[ 7]) * a[ 8]) * 2; - int64_t t16 = (((int64_t)a[ 2]) * a[14] - + ((int64_t)a[ 3]) * a[13] - + ((int64_t)a[ 4]) * a[12] - + ((int64_t)a[ 5]) * a[11] - + ((int64_t)a[ 6]) * a[10] - + ((int64_t)a[ 7]) * a[ 9]) * 2 - + ((int64_t)a[ 8]) * a[ 8]; - int64_t t17 = (((int64_t)a[ 3]) * a[14] - + ((int64_t)a[ 4]) * a[13] - + ((int64_t)a[ 5]) * a[12] - + ((int64_t)a[ 6]) * a[11] - + ((int64_t)a[ 7]) * a[10] - + ((int64_t)a[ 8]) * a[ 9]) * 2; - int64_t t18 = (((int64_t)a[ 4]) * a[14] - + ((int64_t)a[ 5]) * a[13] - + ((int64_t)a[ 6]) * a[12] - + ((int64_t)a[ 7]) * a[11] - + ((int64_t)a[ 8]) * a[10]) * 2 - + ((int64_t)a[ 9]) * a[ 9]; - int64_t t19 = (((int64_t)a[ 5]) * a[14] - + ((int64_t)a[ 6]) * a[13] - + ((int64_t)a[ 7]) * a[12] - + ((int64_t)a[ 8]) * a[11] - + ((int64_t)a[ 9]) * a[10]) * 2; - int64_t t20 = (((int64_t)a[ 6]) * a[14] - + ((int64_t)a[ 7]) * a[13] - + ((int64_t)a[ 8]) * a[12] - + ((int64_t)a[ 9]) * a[11]) * 2 - + ((int64_t)a[10]) * a[10]; - int64_t t21 = (((int64_t)a[ 7]) * a[14] - + ((int64_t)a[ 8]) * a[13] - + ((int64_t)a[ 9]) * a[12] - + ((int64_t)a[10]) * a[11]) * 2; - int64_t t22 = (((int64_t)a[ 8]) * a[14] - + ((int64_t)a[ 9]) * a[13] - + ((int64_t)a[10]) * a[12]) * 2 - + ((int64_t)a[11]) * a[11]; - int64_t t23 = (((int64_t)a[ 9]) * a[14] - + ((int64_t)a[10]) * a[13] - + ((int64_t)a[11]) * a[12]) * 2; - int64_t t24 = (((int64_t)a[10]) * a[14] - + ((int64_t)a[11]) * a[13]) * 2 - + ((int64_t)a[12]) * a[12]; - int64_t t25 = (((int64_t)a[11]) * a[14] - + ((int64_t)a[12]) * a[13]) * 2; - int64_t t26 = (((int64_t)a[12]) * a[14]) * 2 - + ((int64_t)a[13]) * a[13]; - int64_t t27 = (((int64_t)a[13]) * a[14]) * 2; - int64_t t28 = ((int64_t)a[14]) * a[14]; - - t1 += t0 >> 26; r[ 0] = t0 & 0x3ffffff; - t2 += t1 >> 26; r[ 1] = t1 & 0x3ffffff; - t3 += t2 >> 26; r[ 2] = t2 & 0x3ffffff; - t4 += t3 >> 26; r[ 3] = t3 & 0x3ffffff; - t5 += t4 >> 26; r[ 4] = t4 & 0x3ffffff; - t6 += t5 >> 26; r[ 5] = t5 & 0x3ffffff; - t7 += t6 >> 26; r[ 6] = t6 & 0x3ffffff; - t8 += t7 >> 26; r[ 7] = t7 & 0x3ffffff; - t9 += t8 >> 26; r[ 8] = t8 & 0x3ffffff; - t10 += t9 >> 26; r[ 9] = t9 & 0x3ffffff; - t11 += t10 >> 26; r[10] = t10 & 0x3ffffff; - t12 += t11 >> 26; r[11] = t11 & 0x3ffffff; - t13 += t12 >> 26; r[12] = t12 & 0x3ffffff; - t14 += t13 >> 26; r[13] = t13 & 0x3ffffff; - t15 += t14 >> 26; r[14] = t14 & 0x3ffffff; - t16 += t15 >> 26; r[15] = t15 & 0x3ffffff; - t17 += t16 >> 26; r[16] = t16 & 0x3ffffff; - t18 += t17 >> 26; r[17] = t17 & 0x3ffffff; - t19 += t18 >> 26; r[18] = t18 & 0x3ffffff; - t20 += t19 >> 26; r[19] = t19 & 0x3ffffff; - t21 += t20 >> 26; r[20] = t20 & 0x3ffffff; - t22 += t21 >> 26; r[21] = t21 & 0x3ffffff; - t23 += t22 >> 26; r[22] = t22 & 0x3ffffff; - t24 += t23 >> 26; r[23] = t23 & 0x3ffffff; - t25 += t24 >> 26; r[24] = t24 & 0x3ffffff; - t26 += t25 >> 26; r[25] = t25 & 0x3ffffff; - t27 += t26 >> 26; r[26] = t26 & 0x3ffffff; - t28 += t27 >> 26; r[27] = t27 & 0x3ffffff; - r[29] = (sp_digit)(t28 >> 26); - r[28] = t28 & 0x3ffffff; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Square the Montgomery form number. (r = a * a mod m) * * r Result of squaring. @@ -20440,8 +20682,8 @@ SP_NOINLINE static void sp_384_sqr_15(sp_digit* r, const sp_digit* a) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_384_mont_sqr_15(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_384_mont_sqr_15(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_384_sqr_15(r, a); sp_384_mont_reduce_15(r, m, mp); @@ -20465,7 +20707,7 @@ static void sp_384_mont_sqr_n_15(sp_digit* r, const sp_digit* a, int n, } } -#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */ +#endif /* !WOLFSSL_SP_SMALL | HAVE_COMP_KEY */ #ifdef WOLFSSL_SP_SMALL /* Mod-2 for the P384 curve. */ static const uint32_t p384_mod_minus_2[12] = { @@ -20565,7 +20807,8 @@ static void sp_384_mont_inv_15(sp_digit* r, const sp_digit* a, sp_digit* td) * p Montgomery form projective coordinate point. * t Temporary ordinate data. */ -static void sp_384_map_15(sp_point_384* r, const sp_point_384* p, sp_digit* t) +static void sp_384_map_15(sp_point_384* r, const sp_point_384* p, + sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2*15; @@ -20601,54 +20844,6 @@ static void sp_384_map_15(sp_point_384* r, const sp_point_384* p, sp_digit* t) } -#ifdef WOLFSSL_SP_SMALL -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_384_add_15(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 15; i++) { - r[i] = a[i] + b[i]; - } - - return 0; -} -#else -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_384_add_15(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - r[ 0] = a[ 0] + b[ 0]; - r[ 1] = a[ 1] + b[ 1]; - r[ 2] = a[ 2] + b[ 2]; - r[ 3] = a[ 3] + b[ 3]; - r[ 4] = a[ 4] + b[ 4]; - r[ 5] = a[ 5] + b[ 5]; - r[ 6] = a[ 6] + b[ 6]; - r[ 7] = a[ 7] + b[ 7]; - r[ 8] = a[ 8] + b[ 8]; - r[ 9] = a[ 9] + b[ 9]; - r[10] = a[10] + b[10]; - r[11] = a[11] + b[11]; - r[12] = a[12] + b[12]; - r[13] = a[13] + b[13]; - r[14] = a[14] + b[14]; - - return 0; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Add two Montgomery form numbers (r = a + b % m). * * r Result of addition. @@ -20701,55 +20896,6 @@ static void sp_384_mont_tpl_15(sp_digit* r, const sp_digit* a, const sp_digit* m sp_384_norm_15(r); } -#ifdef WOLFSSL_SP_SMALL -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_384_sub_15(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 15; i++) { - r[i] = a[i] - b[i]; - } - - return 0; -} - -#else -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_384_sub_15(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - r[ 0] = a[ 0] - b[ 0]; - r[ 1] = a[ 1] - b[ 1]; - r[ 2] = a[ 2] - b[ 2]; - r[ 3] = a[ 3] - b[ 3]; - r[ 4] = a[ 4] - b[ 4]; - r[ 5] = a[ 5] - b[ 5]; - r[ 6] = a[ 6] - b[ 6]; - r[ 7] = a[ 7] - b[ 7]; - r[ 8] = a[ 8] - b[ 8]; - r[ 9] = a[ 9] - b[ 9]; - r[10] = a[10] - b[10]; - r[11] = a[11] - b[11]; - r[12] = a[12] - b[12]; - r[13] = a[13] - b[13]; - r[14] = a[14] - b[14]; - - return 0; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Conditionally add a and b using the mask m. * m is -1 to add and 0 when not. * @@ -20807,13 +20953,13 @@ static void sp_384_mont_sub_15(sp_digit* r, const sp_digit* a, const sp_digit* b * r Result of shift. * a Number to shift. */ -SP_NOINLINE static void sp_384_rshift1_15(sp_digit* r, sp_digit* a) +SP_NOINLINE static void sp_384_rshift1_15(sp_digit* r, const sp_digit* a) { #ifdef WOLFSSL_SP_SMALL int i; for (i=0; i<14; i++) { - r[i] = ((a[i] >> 1) + (a[i + 1] << 25)) & 0x3ffffff; + r[i] = (a[i] >> 1) + ((a[i + 1] << 25) & 0x3ffffff); } #else r[0] = (a[0] >> 1) + ((a[1] << 25) & 0x3ffffff); @@ -21267,8 +21413,8 @@ static int sp_384_proj_point_add_15_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r, } #endif /* WOLFSSL_SP_NONBLOCK */ -static void sp_384_proj_point_add_15(sp_point_384* r, const sp_point_384* p, const sp_point_384* q, - sp_digit* t) +static void sp_384_proj_point_add_15(sp_point_384* r, + const sp_point_384* p, const sp_point_384* q, sp_digit* t) { const sp_point_384* ap[2]; sp_point_384* rp[2]; @@ -21354,10 +21500,191 @@ static void sp_384_proj_point_add_15(sp_point_384* r, const sp_point_384* p, con } } +/* Multiply a number by Montogmery normalizer mod modulus (prime). + * + * r The resulting Montgomery form number. + * a The number to convert. + * m The modulus (prime). + * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. + */ +static int sp_384_mod_mul_norm_15(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + int64_t* td; +#else + int64_t td[12]; + int64_t a32d[12]; +#endif + int64_t* t; + int64_t* a32; + int64_t o; + int err = MP_OKAY; + + (void)m; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + td = (int64_t*)XMALLOC(sizeof(int64_t) * 2 * 12, NULL, DYNAMIC_TYPE_ECC); + if (td == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + a32 = td + 12; +#else + t = td; + a32 = a32d; +#endif + + a32[0] = a[0]; + a32[0] |= a[1] << 26U; + a32[0] &= 0xffffffffL; + a32[1] = (a[1] >> 6); + a32[1] |= a[2] << 20U; + a32[1] &= 0xffffffffL; + a32[2] = (a[2] >> 12); + a32[2] |= a[3] << 14U; + a32[2] &= 0xffffffffL; + a32[3] = (a[3] >> 18); + a32[3] |= a[4] << 8U; + a32[3] &= 0xffffffffL; + a32[4] = (a[4] >> 24); + a32[4] |= a[5] << 2U; + a32[4] |= a[6] << 28U; + a32[4] &= 0xffffffffL; + a32[5] = (a[6] >> 4); + a32[5] |= a[7] << 22U; + a32[5] &= 0xffffffffL; + a32[6] = (a[7] >> 10); + a32[6] |= a[8] << 16U; + a32[6] &= 0xffffffffL; + a32[7] = (a[8] >> 16); + a32[7] |= a[9] << 10U; + a32[7] &= 0xffffffffL; + a32[8] = (a[9] >> 22); + a32[8] |= a[10] << 4U; + a32[8] |= a[11] << 30U; + a32[8] &= 0xffffffffL; + a32[9] = (a[11] >> 2); + a32[9] |= a[12] << 24U; + a32[9] &= 0xffffffffL; + a32[10] = (a[12] >> 8); + a32[10] |= a[13] << 18U; + a32[10] &= 0xffffffffL; + a32[11] = (a[13] >> 14); + a32[11] |= a[14] << 12U; + a32[11] &= 0xffffffffL; + + /* 1 0 0 0 0 0 0 0 1 1 0 -1 */ + t[0] = 0 + a32[0] + a32[8] + a32[9] - a32[11]; + /* -1 1 0 0 0 0 0 0 -1 0 1 1 */ + t[1] = 0 - a32[0] + a32[1] - a32[8] + a32[10] + a32[11]; + /* 0 -1 1 0 0 0 0 0 0 -1 0 1 */ + t[2] = 0 - a32[1] + a32[2] - a32[9] + a32[11]; + /* 1 0 -1 1 0 0 0 0 1 1 -1 -1 */ + t[3] = 0 + a32[0] - a32[2] + a32[3] + a32[8] + a32[9] - a32[10] - a32[11]; + /* 1 1 0 -1 1 0 0 0 1 2 1 -2 */ + t[4] = 0 + a32[0] + a32[1] - a32[3] + a32[4] + a32[8] + 2 * a32[9] + a32[10] - 2 * a32[11]; + /* 0 1 1 0 -1 1 0 0 0 1 2 1 */ + t[5] = 0 + a32[1] + a32[2] - a32[4] + a32[5] + a32[9] + 2 * a32[10] + a32[11]; + /* 0 0 1 1 0 -1 1 0 0 0 1 2 */ + t[6] = 0 + a32[2] + a32[3] - a32[5] + a32[6] + a32[10] + 2 * a32[11]; + /* 0 0 0 1 1 0 -1 1 0 0 0 1 */ + t[7] = 0 + a32[3] + a32[4] - a32[6] + a32[7] + a32[11]; + /* 0 0 0 0 1 1 0 -1 1 0 0 0 */ + t[8] = 0 + a32[4] + a32[5] - a32[7] + a32[8]; + /* 0 0 0 0 0 1 1 0 -1 1 0 0 */ + t[9] = 0 + a32[5] + a32[6] - a32[8] + a32[9]; + /* 0 0 0 0 0 0 1 1 0 -1 1 0 */ + t[10] = 0 + a32[6] + a32[7] - a32[9] + a32[10]; + /* 0 0 0 0 0 0 0 1 1 0 -1 1 */ + t[11] = 0 + a32[7] + a32[8] - a32[10] + a32[11]; + + t[1] += t[0] >> 32; t[0] &= 0xffffffff; + t[2] += t[1] >> 32; t[1] &= 0xffffffff; + t[3] += t[2] >> 32; t[2] &= 0xffffffff; + t[4] += t[3] >> 32; t[3] &= 0xffffffff; + t[5] += t[4] >> 32; t[4] &= 0xffffffff; + t[6] += t[5] >> 32; t[5] &= 0xffffffff; + t[7] += t[6] >> 32; t[6] &= 0xffffffff; + t[8] += t[7] >> 32; t[7] &= 0xffffffff; + t[9] += t[8] >> 32; t[8] &= 0xffffffff; + t[10] += t[9] >> 32; t[9] &= 0xffffffff; + t[11] += t[10] >> 32; t[10] &= 0xffffffff; + o = t[11] >> 32; t[11] &= 0xffffffff; + t[0] += o; + t[1] -= o; + t[3] += o; + t[4] += o; + t[1] += t[0] >> 32; t[0] &= 0xffffffff; + t[2] += t[1] >> 32; t[1] &= 0xffffffff; + t[3] += t[2] >> 32; t[2] &= 0xffffffff; + t[4] += t[3] >> 32; t[3] &= 0xffffffff; + t[5] += t[4] >> 32; t[4] &= 0xffffffff; + t[6] += t[5] >> 32; t[5] &= 0xffffffff; + t[7] += t[6] >> 32; t[6] &= 0xffffffff; + t[8] += t[7] >> 32; t[7] &= 0xffffffff; + t[9] += t[8] >> 32; t[8] &= 0xffffffff; + t[10] += t[9] >> 32; t[9] &= 0xffffffff; + t[11] += t[10] >> 32; t[10] &= 0xffffffff; + + r[0] = (sp_digit)(t[0]) & 0x3ffffffL; + r[1] = (sp_digit)(t[0] >> 26U); + r[1] |= (sp_digit)(t[1] << 6U); + r[1] &= 0x3ffffffL; + r[2] = (sp_digit)(t[1] >> 20U); + r[2] |= (sp_digit)(t[2] << 12U); + r[2] &= 0x3ffffffL; + r[3] = (sp_digit)(t[2] >> 14U); + r[3] |= (sp_digit)(t[3] << 18U); + r[3] &= 0x3ffffffL; + r[4] = (sp_digit)(t[3] >> 8U); + r[4] |= (sp_digit)(t[4] << 24U); + r[4] &= 0x3ffffffL; + r[5] = (sp_digit)(t[4] >> 2U) & 0x3ffffffL; + r[6] = (sp_digit)(t[4] >> 28U); + r[6] |= (sp_digit)(t[5] << 4U); + r[6] &= 0x3ffffffL; + r[7] = (sp_digit)(t[5] >> 22U); + r[7] |= (sp_digit)(t[6] << 10U); + r[7] &= 0x3ffffffL; + r[8] = (sp_digit)(t[6] >> 16U); + r[8] |= (sp_digit)(t[7] << 16U); + r[8] &= 0x3ffffffL; + r[9] = (sp_digit)(t[7] >> 10U); + r[9] |= (sp_digit)(t[8] << 22U); + r[9] &= 0x3ffffffL; + r[10] = (sp_digit)(t[8] >> 4U) & 0x3ffffffL; + r[11] = (sp_digit)(t[8] >> 30U); + r[11] |= (sp_digit)(t[9] << 2U); + r[11] &= 0x3ffffffL; + r[12] = (sp_digit)(t[9] >> 24U); + r[12] |= (sp_digit)(t[10] << 8U); + r[12] &= 0x3ffffffL; + r[13] = (sp_digit)(t[10] >> 18U); + r[13] |= (sp_digit)(t[11] << 14U); + r[13] &= 0x3ffffffL; + r[14] = (sp_digit)(t[11] >> 12U); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) + XFREE(td, NULL, DYNAMIC_TYPE_ECC); +#endif + + return err; +} + #ifdef WOLFSSL_SP_SMALL /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Small implementation using add and double that is cache attack resistant but + * allocates memory rather than use large stacks. + * 384 adds and doubles. + * * r Resulting point. * g Point to multiply. * k Scalar to multiply by. @@ -21481,8 +21808,8 @@ static int sp_384_ecc_mulmod_15_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r, #endif /* WOLFSSL_SP_NONBLOCK */ -static int sp_384_ecc_mulmod_15(sp_point_384* r, const sp_point_384* g, const sp_digit* k, - int map, int ct, void* heap) +static int sp_384_ecc_mulmod_15(sp_point_384* r, const sp_point_384* g, + const sp_digit* k, int map, int ct, void* heap) { #ifdef WOLFSSL_SP_NO_MALLOC sp_point_384 t[3]; @@ -21493,7 +21820,8 @@ static int sp_384_ecc_mulmod_15(sp_point_384* r, const sp_point_384* g, const sp #endif sp_digit n; int i; - int c, y; + int c; + int y; int err = MP_OKAY; /* Implementatio is constant time. */ @@ -21642,7 +21970,8 @@ static void sp_384_cond_copy_15(sp_digit* r, const sp_digit* a, const sp_digit m * n Number of times to double * t Temporary ordinate data. */ -static void sp_384_proj_point_dbl_n_15(sp_point_384* p, int n, sp_digit* t) +static void sp_384_proj_point_dbl_n_15(sp_point_384* p, int n, + sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*15; @@ -21730,8 +22059,8 @@ static void sp_384_proj_point_dbl_n_15(sp_point_384* p, int n, sp_digit* t) * n Number of times to double * t Temporary ordinate data. */ -static void sp_384_proj_point_dbl_n_store_15(sp_point_384* r, const sp_point_384* p, - int n, int m, sp_digit* t) +static void sp_384_proj_point_dbl_n_store_15(sp_point_384* r, + const sp_point_384* p, int n, int m, sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*15; @@ -21742,6 +22071,7 @@ static void sp_384_proj_point_dbl_n_store_15(sp_point_384* r, const sp_point_384 sp_digit* y = r[(1<x[i]; @@ -21758,7 +22088,10 @@ static void sp_384_proj_point_dbl_n_store_15(sp_point_384* r, const sp_point_384 /* W = Z^4 */ sp_384_mont_sqr_15(w, z, p384_mod, p384_mp_mod); sp_384_mont_sqr_15(w, w, p384_mod, p384_mp_mod); + j = m; for (i=1; i<=n; i++) { + j *= 2; + /* A = 3*(X^2 - W) */ sp_384_mont_sqr_15(t1, x, p384_mod, p384_mp_mod); sp_384_mont_sub_15(t1, t1, w, p384_mod); @@ -21766,14 +22099,14 @@ static void sp_384_proj_point_dbl_n_store_15(sp_point_384* r, const sp_point_384 /* B = X*Y^2 */ sp_384_mont_sqr_15(t2, y, p384_mod, p384_mp_mod); sp_384_mont_mul_15(b, t2, x, p384_mod, p384_mp_mod); - x = r[(1<y); + sp_384_norm_15(negy); sp_384_cond_copy_15(p->y, negy, (sp_digit)0 - v[i].neg); sp_384_proj_point_add_15(rt, rt, p, tmp); } @@ -22303,6 +22640,10 @@ static void sp_384_proj_to_affine_15(sp_point_384* a, sp_digit* t) } /* Generate the pre-computed table of points for the base point. + * + * width = 8 + * 256 entries + * 48 bits between * * a The base point. * table Place to store generated point data. @@ -22313,12 +22654,15 @@ static int sp_384_gen_stripe_table_15(const sp_point_384* a, sp_table_entry_384* table, sp_digit* tmp, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_point_384 td, s1d, s2d; + sp_point_384 td; + sp_point_384 s1d; + sp_point_384 s2d; #endif sp_point_384* t; sp_point_384* s1 = NULL; sp_point_384* s2 = NULL; - int i, j; + int i; + int j; int err; (void)heap; @@ -22465,8 +22809,10 @@ static void sp_384_get_entry_256_15(sp_point_384* r, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Implementation uses striping of bits. - * Choose bits 8 bits apart. + * Stripe implementation. + * Pre-generated: 2^0, 2^48, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) * * r Resulting point. * k Scalar to multiply by. @@ -22488,8 +22834,10 @@ static int sp_384_ecc_mulmod_stripe_15(sp_point_384* r, const sp_point_384* g, sp_point_384* rt; sp_point_384* p = NULL; sp_digit* t; - int i, j; - int y, x; + int i; + int j; + int y; + int x; int err; (void)g; @@ -22517,8 +22865,10 @@ static int sp_384_ecc_mulmod_stripe_15(sp_point_384* r, const sp_point_384* g, XMEMCPY(rt->z, p384_norm_mod, sizeof(p384_norm_mod)); y = 0; - for (j=0,x=47; j<8; j++,x+=48) { + x = 47; + for (j=0; j<8; j++) { y |= (int)(((k[x / 26] >> (x % 26)) & 1) << j); + x += 48; } #ifndef WC_NO_CACHE_RESISTANT if (ct) { @@ -22532,8 +22882,10 @@ static int sp_384_ecc_mulmod_stripe_15(sp_point_384* r, const sp_point_384* g, rt->infinity = !y; for (i=46; i>=0; i--) { y = 0; - for (j=0,x=i; j<8; j++,x+=48) { + x = i; + for (j=0; j<8; j++) { y |= (int)(((k[x / 26] >> (x % 26)) & 1) << j); + x += 48; } sp_384_proj_point_dbl_15(rt, rt, t); @@ -22575,16 +22927,25 @@ static int sp_384_ecc_mulmod_stripe_15(sp_point_384* r, const sp_point_384* g, #define FP_ENTRIES 16 #endif +/* Cache entry - holds precomputation tables for a point. */ typedef struct sp_cache_384_t { + /* X ordinate of point that table was generated from. */ sp_digit x[15]; + /* Y ordinate of point that table was generated from. */ sp_digit y[15]; + /* Precomputation table for point. */ sp_table_entry_384 table[256]; + /* Count of entries in table. */ uint32_t cnt; + /* Point and table set in entry. */ int set; } sp_cache_384_t; +/* Cache of tables. */ static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES]; +/* Index of last entry in cache. */ static THREAD_LS_T int sp_cache_384_last = -1; +/* Cache has been initialized. */ static THREAD_LS_T int sp_cache_384_inited = 0; #ifndef HAVE_THREAD_LS @@ -22592,9 +22953,15 @@ static THREAD_LS_T int sp_cache_384_inited = 0; static wolfSSL_Mutex sp_cache_384_lock; #endif +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache) { - int i, j; + int i; + int j; uint32_t least; if (sp_cache_384_inited == 0) { @@ -22711,8 +23078,8 @@ static int sp_384_ecc_mulmod_15(sp_point_384* r, const sp_point_384* g, const sp * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_384(mp_int* km, ecc_point* gm, ecc_point* r, int map, - void* heap) +int sp_ecc_mulmod_384(const mp_int* km, const ecc_point* gm, ecc_point* r, + int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_384 p; @@ -22753,6 +23120,89 @@ int sp_ecc_mulmod_384(mp_int* km, ecc_point* gm, ecc_point* r, int map, return err; } +/* Multiply the point by the scalar, add point a and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * p Point to multiply. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_add_384(const mp_int* km, const ecc_point* gm, + const ecc_point* am, int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_384 p; + sp_point_384 a; + sp_digit kd[15]; + sp_digit t[15 * 2 * 6]; +#endif + sp_point_384* point; + sp_point_384* addP = NULL; + sp_digit* k = NULL; + sp_digit* tmp = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_15(heap, p, point); + if (err == MP_OKAY) { + err = sp_384_point_new_15(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (15 + 15 * 2 * 6), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 15; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 15, km); + sp_384_point_from_ecc_point_15(point, gm); + sp_384_point_from_ecc_point_15(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_15(addP->x, addP->x, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_15(addP->y, addP->y, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_15(addP->z, addP->z, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_15(point, point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_384_proj_point_add_15(point, point, addP, tmp); + + if (map) { + sp_384_map_15(point, point, tmp); + } + + err = sp_384_point_to_ecc_point_15(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_15(addP, 0, heap); + sp_384_point_free_15(point, 0, heap); + + return err; +} + #ifdef WOLFSSL_SP_SMALL /* Multiply the base point of P384 by the scalar and return the result. * If map is true then convert result to affine coordinates. @@ -22771,6 +23221,10 @@ static int sp_384_ecc_mulmod_base_15(sp_point_384* r, const sp_digit* k, } #else +/* Striping precomputation table. + * 8 points combined into a table of 256 points. + * Distance of 48 between points. + */ static const sp_table_entry_384 p384_table[256] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -24565,6 +25019,11 @@ static const sp_table_entry_384 p384_table[256] = { /* Multiply the base point of P384 by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Stripe implementation. + * Pre-generated: 2^0, 2^48, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * * r Resulting point. * k Scalar to multiply by. * map Indicates whether to convert result to affine. @@ -24590,7 +25049,7 @@ static int sp_384_ecc_mulmod_base_15(sp_point_384* r, const sp_digit* k, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_base_384(mp_int* km, ecc_point* r, int map, void* heap) +int sp_ecc_mulmod_base_384(const mp_int* km, ecc_point* r, int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_384 p; @@ -24631,6 +25090,87 @@ int sp_ecc_mulmod_base_384(mp_int* km, ecc_point* r, int map, void* heap) return err; } +/* Multiply the base point of P384 by the scalar, add point a and return + * the result. If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_add_384(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_384 p; + sp_point_384 a; + sp_digit kd[15]; + sp_digit t[15 * 2 * 6]; +#endif + sp_point_384* point; + sp_point_384* addP = NULL; + sp_digit* tmp = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_15(heap, p, point); + if (err == MP_OKAY) { + err = sp_384_point_new_15(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (15 + 15 * 2 * 6), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 15; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 15, km); + sp_384_point_from_ecc_point_15(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_15(addP->x, addP->x, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_15(addP->y, addP->y, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_15(addP->z, addP->z, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_base_15(point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_384_proj_point_add_15(point, point, addP, tmp); + + if (map) { + sp_384_map_15(point, point, tmp); + } + + err = sp_384_point_to_ecc_point_15(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_15(addP, 0, heap); + sp_384_point_free_15(point, 0, heap); + + return err; +} + #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \ defined(HAVE_ECC_VERIFY) /* Returns 1 if the number of zero. @@ -24645,7 +25185,7 @@ static int sp_384_iszero_15(const sp_digit* a) a[8] | a[9] | a[10] | a[11] | a[12] | a[13] | a[14]) == 0; } -#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN | HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ /* Add 1 to a. (a = a + 1) * * r A single precision integer. @@ -24666,7 +25206,8 @@ SP_NOINLINE static void sp_384_add_one_15(sp_digit* a) */ static void sp_384_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -24810,7 +25351,10 @@ int sp_ecc_make_key_384(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) */ static void sp_384_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; for (i=0; i<14; i++) { r[i+1] += r[i] >> 26; @@ -24855,7 +25399,7 @@ static void sp_384_to_bin(sp_digit* r, byte* a) * returns BUFFER_E if the buffer is to small for output size, * MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_secret_gen_384(mp_int* priv, ecc_point* pub, byte* out, +int sp_ecc_secret_gen_384(const mp_int* priv, const ecc_point* pub, byte* out, word32* outLen, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) @@ -24970,7 +25514,9 @@ SP_NOINLINE static void sp_384_mul_d_15(sp_digit* r, const sp_digit* a, static WC_INLINE sp_digit sp_384_div_word_15(sp_digit d1, sp_digit d0, sp_digit dv) { - sp_digit d, r, t; + sp_digit d; + sp_digit r; + sp_digit t; /* All 26 bits from d1 and top 5 bits from d0. */ d = (d1 << 5) | (d0 >> 21); @@ -25023,24 +25569,28 @@ static WC_INLINE sp_digit sp_384_div_word_15(sp_digit d1, sp_digit d0, /* Divide d in a and put remainder into r (m*d + r = a) * m is not calculated as it is not needed at this time. * + * Large number of bits in last word. + * * a Number to be divided. * d Number to divide with. * m Multiplier result. * r Remainder from the division. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise. */ -static int sp_384_div_15(const sp_digit* a, const sp_digit* d, sp_digit* m, - sp_digit* r) +static int sp_384_div_15(const sp_digit* a, const sp_digit* d, + const sp_digit* m, sp_digit* r) { int i; #ifndef WOLFSSL_SP_DIV_32 int64_t d1; #endif - sp_digit dv, r1; + sp_digit dv; + sp_digit r1; #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* td; #else - sp_digit t1d[30], t2d[15 + 1]; + sp_digit t1d[30]; + sp_digit t2d[15 + 1]; #endif sp_digit* t1; sp_digit* t2; @@ -25068,17 +25618,15 @@ static int sp_384_div_15(const sp_digit* a, const sp_digit* d, sp_digit* m, dv = d[14]; XMEMCPY(t1, a, sizeof(*t1) * 2U * 15U); for (i=14; i>=0; i--) { - sp_digit hi; t1[15 + i] += t1[15 + i - 1] >> 26; t1[15 + i - 1] &= 0x3ffffff; - hi = t1[15 + i] - (t1[15 + i] == dv); #ifndef WOLFSSL_SP_DIV_32 - d1 = hi; + d1 = t1[15 + i]; d1 <<= 26; d1 += t1[15 + i - 1]; r1 = (sp_digit)(d1 / dv); #else - r1 = sp_384_div_word_15(hi, t1[15 + i - 1], dv); + r1 = sp_384_div_word_15(t1[15 + i], t1[15 + i - 1], dv); #endif sp_384_mul_d_15(t2, d, r1); @@ -25099,7 +25647,7 @@ static int sp_384_div_15(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_384_mul_d_15(t2, d, r1); (void)sp_384_sub_15(t1, t1, t2); - XMEMCPY(r, t1, sizeof(*r) * 2U * 15U); + XMEMCPY(r, t1, sizeof(*r) * 30U); for (i=0; i<14; i++) { r[i+1] += r[i] >> 26; r[i] &= 0x3ffffff; @@ -25141,7 +25689,6 @@ static const uint32_t p384_order_minus_2[12] = { /* The low half of the order-2 of the P384 curve. */ static const uint32_t p384_order_low[6] = { 0xccc52971U,0xecec196aU,0x48b0a77aU,0x581a0db2U,0xf4372ddfU,0xc7634d81U - }; #endif /* WOLFSSL_SP_SMALL */ @@ -25289,7 +25836,7 @@ static void sp_384_mont_inv_order_15(sp_digit* r, const sp_digit* a, sp_384_mont_mul_order_15(t2, t2, t); for (i=191; i>=1; i--) { sp_384_mont_sqr_order_15(t2, t2); - if (((sp_digit)p384_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p384_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_384_mont_mul_order_15(t2, t2, a); } } @@ -25298,12 +25845,63 @@ static void sp_384_mont_inv_order_15(sp_digit* r, const sp_digit* a, #endif /* WOLFSSL_SP_SMALL */ } -#endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ #ifdef HAVE_ECC_SIGN #ifndef SP_ECC_MAX_SIG_GEN #define SP_ECC_MAX_SIG_GEN 64 #endif +/* Calculate second signature value S from R, k and private value. + * + * s = (r * x + e) / k + * + * s Signature value. + * r First signature value. + * k Ephemeral private key. + * x Private key as a number. + * e Hash of message as a number. + * tmp Temporary storage for intermediate numbers. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_calc_s_15(sp_digit* s, const sp_digit* r, sp_digit* k, + sp_digit* x, const sp_digit* e, sp_digit* tmp) +{ + int err; + sp_digit carry; + int32_t c; + sp_digit* kInv = k; + + /* Conv k to Montgomery form (mod order) */ + sp_384_mul_15(k, k, p384_norm_order); + err = sp_384_mod_15(k, k, p384_order); + if (err == MP_OKAY) { + sp_384_norm_15(k); + + /* kInv = 1/k mod order */ + sp_384_mont_inv_order_15(kInv, k, tmp); + sp_384_norm_15(kInv); + + /* s = r * x + e */ + sp_384_mul_15(x, x, r); + err = sp_384_mod_15(x, x, p384_order); + } + if (err == MP_OKAY) { + sp_384_norm_15(x); + carry = sp_384_add_15(s, e, x); + sp_384_cond_sub_15(s, s, p384_order, 0 - carry); + sp_384_norm_15(s); + c = sp_384_cmp_15(s, p384_order); + sp_384_cond_sub_15(s, s, p384_order, 0L - (sp_digit)(c >= 0)); + sp_384_norm_15(s); + + /* s = s * k^-1 mod order */ + sp_384_mont_mul_order_15(s, s, kInv); + sp_384_norm_15(s); + } + + return err; +} + /* Sign the hash using the private key. * e = [hash, 384 bits] from binary * r = (k.G)->x mod order @@ -25338,8 +25936,8 @@ typedef struct sp_ecc_sign_384_ctx { int i; } sp_ecc_sign_384_ctx; -int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, + mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_sign_384_ctx* ctx = (sp_ecc_sign_384_ctx*)sp_ctx->data; @@ -25479,8 +26077,8 @@ int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, W } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, + const mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -25498,11 +26096,9 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit* r = NULL; sp_digit* tmp = NULL; sp_point_384* point = NULL; - sp_digit carry; sp_digit* s = NULL; - sp_digit* kInv = NULL; - int err = MP_OKAY; int32_t c; + int err = MP_OKAY; int i; (void)heap; @@ -25533,7 +26129,6 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, tmp = td; #endif s = e; - kInv = k; if (hashLen > 48U) { hashLen = 48U; @@ -25541,8 +26136,6 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, } for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) { - sp_384_from_mp(x, 15, priv); - /* New random point. */ if (km == NULL || mp_iszero(km)) { err = sp_384_ecc_gen_k_15(rng, k); @@ -25552,7 +26145,7 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, mp_zero(km); } if (err == MP_OKAY) { - err = sp_384_ecc_mulmod_base_15(point, k, 1, 1, NULL); + err = sp_384_ecc_mulmod_base_15(point, k, 1, 1, heap); } if (err == MP_OKAY) { @@ -25563,38 +26156,15 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_384_cond_sub_15(r, r, p384_order, 0L - (sp_digit)(c >= 0)); sp_384_norm_15(r); - /* Conv k to Montgomery form (mod order) */ - sp_384_mul_15(k, k, p384_norm_order); - err = sp_384_mod_15(k, k, p384_order); - } - if (err == MP_OKAY) { - sp_384_norm_15(k); - /* kInv = 1/k mod order */ - sp_384_mont_inv_order_15(kInv, k, tmp); - sp_384_norm_15(kInv); - - /* s = r * x + e */ - sp_384_mul_15(x, x, r); - err = sp_384_mod_15(x, x, p384_order); - } - if (err == MP_OKAY) { - sp_384_norm_15(x); + sp_384_from_mp(x, 15, priv); sp_384_from_bin(e, 15, hash, (int)hashLen); - carry = sp_384_add_15(s, e, x); - sp_384_cond_sub_15(s, s, p384_order, 0 - carry); - sp_384_norm_15(s); - c = sp_384_cmp_15(s, p384_order); - sp_384_cond_sub_15(s, s, p384_order, 0L - (sp_digit)(c >= 0)); - sp_384_norm_15(s); - /* s = s * k^-1 mod order */ - sp_384_mont_mul_order_15(s, s, kInv); - sp_384_norm_15(s); + err = sp_384_calc_s_15(s, r, k, x, e, tmp); + } - /* Check that signature is usable. */ - if (sp_384_iszero_15(s) == 0) { - break; - } + /* Check that signature is usable. */ + if ((err == MP_OKAY) && (sp_384_iszero_15(s) == 0)) { + break; } #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP i = 1; @@ -25622,7 +26192,6 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, XMEMSET(x, 0, sizeof(sp_digit) * 2U * 15U); XMEMSET(k, 0, sizeof(sp_digit) * 2U * 15U); XMEMSET(r, 0, sizeof(sp_digit) * 2U * 15U); - XMEMSET(r, 0, sizeof(sp_digit) * 2U * 15U); XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 15U); #endif sp_384_point_free_15(point, 1, heap); @@ -25787,6 +26356,103 @@ static int sp_384_mod_inv_15(sp_digit* r, const sp_digit* a, const sp_digit* m) } #endif /* WOLFSSL_SP_SMALL */ + +/* Add point p1 into point p2. Handles p1 == p2 and result at infinity. + * + * p1 First point to add and holds result. + * p2 Second point to add. + * tmp Temporary storage for intermediate numbers. + */ +static void sp_384_add_points_15(sp_point_384* p1, const sp_point_384* p2, + sp_digit* tmp) +{ + + sp_384_proj_point_add_15(p1, p1, p2, tmp); + if (sp_384_iszero_15(p1->z)) { + if (sp_384_iszero_15(p1->x) && sp_384_iszero_15(p1->y)) { + sp_384_proj_point_dbl_15(p1, p2, tmp); + } + else { + /* Y ordinate is not used from here - don't set. */ + p1->x[0] = 0; + p1->x[1] = 0; + p1->x[2] = 0; + p1->x[3] = 0; + p1->x[4] = 0; + p1->x[5] = 0; + p1->x[6] = 0; + p1->x[7] = 0; + p1->x[8] = 0; + p1->x[9] = 0; + p1->x[10] = 0; + p1->x[11] = 0; + p1->x[12] = 0; + p1->x[13] = 0; + p1->x[14] = 0; + XMEMCPY(p1->z, p384_norm_mod, sizeof(p384_norm_mod)); + } + } +} + +/* Calculate the verification point: [e/s]G + [r/s]Q + * + * p1 Calculated point. + * p2 Public point and temporary. + * s Second part of signature as a number. + * u1 Temporary number. + * u2 Temproray number. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_calc_vfy_point_15(sp_point_384* p1, sp_point_384* p2, + sp_digit* s, sp_digit* u1, sp_digit* u2, sp_digit* tmp, void* heap) +{ + int err; + +#ifndef WOLFSSL_SP_SMALL + { + sp_384_mod_inv_15(s, s, p384_order); + } +#endif /* !WOLFSSL_SP_SMALL */ + { + sp_384_mul_15(s, s, p384_norm_order); + } + err = sp_384_mod_15(s, s, p384_order); + if (err == MP_OKAY) { + sp_384_norm_15(s); +#ifdef WOLFSSL_SP_SMALL + { + sp_384_mont_inv_order_15(s, s, tmp); + sp_384_mont_mul_order_15(u1, u1, s); + sp_384_mont_mul_order_15(u2, u2, s); + } + +#else + { + sp_384_mont_mul_order_15(u1, u1, s); + sp_384_mont_mul_order_15(u2, u2, s); + } + +#endif /* WOLFSSL_SP_SMALL */ + err = sp_384_ecc_mulmod_base_15(p1, u1, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_384_iszero_15(p1->z)) { + p1->infinity = 1; + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_15(p2, p2, u2, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_384_iszero_15(p2->z)) { + p2->infinity = 1; + } + + if (err == MP_OKAY) { + sp_384_add_points_15(p1, p2, tmp); + } + + return err; +} + #ifdef HAVE_ECC_VERIFY /* Verify the signature values with the hash and public key. * e = Truncate(hash, 384) @@ -25805,8 +26471,7 @@ static int sp_384_mod_inv_15(sp_digit* r, const sp_digit* a, const sp_digit* m) * rm First part of result as an mp_int. * sm Sirst part of result as an mp_int. * heap Heap to use for allocation. - * returns RNG failures, MEMORY_E when memory allocation fails and - * MP_OKAY on success. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ #ifdef WOLFSSL_SP_NONBLOCK typedef struct sp_ecc_verify_384_ctx { @@ -25825,8 +26490,9 @@ typedef struct sp_ecc_verify_384_ctx { sp_point_384 p2; } sp_ecc_verify_384_ctx; -int sp_ecc_verify_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, + word32 hashLen, const mp_int* pX, const mp_int* pY, const mp_int* pZ, + const mp_int* r, const mp_int* sm, int* res, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_verify_384_ctx* ctx = (sp_ecc_verify_384_ctx*)sp_ctx->data; @@ -25980,8 +26646,9 @@ int sp_ecc_verify_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_384(const byte* hash, word32 hashLen, const mp_int* pX, + const mp_int* pY, const mp_int* pZ, const mp_int* r, const mp_int* sm, + int* res, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -26000,7 +26667,7 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, sp_point_384* p1; sp_point_384* p2 = NULL; sp_digit carry; - int32_t c; + int32_t c = 0; int err; err = sp_384_point_new_15(heap, p1d, p1); @@ -26041,73 +26708,9 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, sp_384_from_mp(p2->y, 15, pY); sp_384_from_mp(p2->z, 15, pZ); -#ifndef WOLFSSL_SP_SMALL - { - sp_384_mod_inv_15(s, s, p384_order); - } -#endif /* !WOLFSSL_SP_SMALL */ - { - sp_384_mul_15(s, s, p384_norm_order); - } - err = sp_384_mod_15(s, s, p384_order); + err = sp_384_calc_vfy_point_15(p1, p2, s, u1, u2, tmp, heap); } if (err == MP_OKAY) { - sp_384_norm_15(s); -#ifdef WOLFSSL_SP_SMALL - { - sp_384_mont_inv_order_15(s, s, tmp); - sp_384_mont_mul_order_15(u1, u1, s); - sp_384_mont_mul_order_15(u2, u2, s); - } - -#else - { - sp_384_mont_mul_order_15(u1, u1, s); - sp_384_mont_mul_order_15(u2, u2, s); - } - -#endif /* WOLFSSL_SP_SMALL */ - err = sp_384_ecc_mulmod_base_15(p1, u1, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_384_iszero_15(p1->z)) { - p1->infinity = 1; - } - if (err == MP_OKAY) { - err = sp_384_ecc_mulmod_15(p2, p2, u2, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_384_iszero_15(p2->z)) { - p2->infinity = 1; - } - - if (err == MP_OKAY) { - { - sp_384_proj_point_add_15(p1, p1, p2, tmp); - if (sp_384_iszero_15(p1->z)) { - if (sp_384_iszero_15(p1->x) && sp_384_iszero_15(p1->y)) { - sp_384_proj_point_dbl_15(p1, p2, tmp); - } - else { - /* Y ordinate is not used from here - don't set. */ - p1->x[0] = 0; - p1->x[1] = 0; - p1->x[2] = 0; - p1->x[3] = 0; - p1->x[4] = 0; - p1->x[5] = 0; - p1->x[6] = 0; - p1->x[7] = 0; - p1->x[8] = 0; - p1->x[9] = 0; - p1->x[10] = 0; - p1->x[11] = 0; - p1->x[12] = 0; - p1->x[13] = 0; - p1->x[14] = 0; - XMEMCPY(p1->z, p384_norm_mod, sizeof(p384_norm_mod)); - } - } - } - /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */ /* Reload r and convert to Montgomery form. */ sp_384_from_mp(u2, 15, r); @@ -26129,16 +26732,16 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, /* Compare with mod and if greater or equal then not valid. */ c = sp_384_cmp_15(u2, p384_mod); - if (c < 0) { - /* Convert to Montogomery form */ - err = sp_384_mod_mul_norm_15(u2, u2, p384_mod); - if (err == MP_OKAY) { - /* u1 = (r + 1*order).z'.z' mod prime */ - sp_384_mont_mul_15(u1, u2, p1->z, p384_mod, - p384_mp_mod); - *res = (int)(sp_384_cmp_15(p1->x, u1) == 0); - } - } + } + } + if ((*res == 0) && (c < 0)) { + /* Convert to Montogomery form */ + err = sp_384_mod_mul_norm_15(u2, u2, p384_mod); + if (err == MP_OKAY) { + /* u1 = (r + 1*order).z'.z' mod prime */ + sp_384_mont_mul_15(u1, u2, p1->z, p384_mod, + p384_mp_mod); + *res = (sp_384_cmp_15(p1->x, u1) == 0); } } } @@ -26162,7 +26765,8 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -static int sp_384_ecc_is_point_15(sp_point_384* point, void* heap) +static int sp_384_ecc_is_point_15(const sp_point_384* point, + void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -26225,7 +26829,7 @@ static int sp_384_ecc_is_point_15(sp_point_384* point, void* heap) * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -int sp_ecc_is_point_384(mp_int* pX, mp_int* pY) +int sp_ecc_is_point_384(const mp_int* pX, const mp_int* pY) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_384 pubd; @@ -26259,7 +26863,8 @@ int sp_ecc_is_point_384(mp_int* pX, mp_int* pY) * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and * MP_OKAY otherwise. */ -int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) +int sp_ecc_check_key_384(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit privd[15]; @@ -26313,12 +26918,11 @@ int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) } } - if (err == MP_OKAY) { - /* Check range of X and Y */ - if (sp_384_cmp_15(pub->x, p384_mod) >= 0 || - sp_384_cmp_15(pub->y, p384_mod) >= 0) { - err = ECC_OUT_OF_RANGE_E; - } + /* Check range of X and Y */ + if ((err == MP_OKAY) && + ((sp_384_cmp_15(pub->x, p384_mod) >= 0) || + (sp_384_cmp_15(pub->y, p384_mod) >= 0))) { + err = ECC_OUT_OF_RANGE_E; } if (err == MP_OKAY) { @@ -26330,12 +26934,10 @@ int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Point * order = infinity */ err = sp_384_ecc_mulmod_15(p, pub, p384_order, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is infinity */ - if ((sp_384_iszero_15(p->x) == 0) || - (sp_384_iszero_15(p->y) == 0)) { - err = ECC_INF_E; - } + /* Check result is infinity */ + if ((err == MP_OKAY) && ((sp_384_iszero_15(p->x) == 0) || + (sp_384_iszero_15(p->y) == 0))) { + err = ECC_INF_E; } if (privm) { @@ -26343,12 +26945,11 @@ int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Base * private = point */ err = sp_384_ecc_mulmod_base_15(p, priv, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is public key */ - if (sp_384_cmp_15(p->x, pub->x) != 0 || - sp_384_cmp_15(p->y, pub->y) != 0) { - err = ECC_PRIV_KEY_E; - } + /* Check result is public key */ + if ((err == MP_OKAY) && + ((sp_384_cmp_15(p->x, pub->x) != 0) || + (sp_384_cmp_15(p->y, pub->y) != 0))) { + err = ECC_PRIV_KEY_E; } } @@ -26538,7 +27139,7 @@ int sp_ecc_map_384(mp_int* pX, mp_int* pY, mp_int* pZ) sp_384_from_mp(p->y, 15, pY); sp_384_from_mp(p->z, 15, pZ); - sp_384_map_15(p, p, tmp); + sp_384_map_15(p, p, tmp); } if (err == MP_OKAY) { @@ -26751,7 +27352,11278 @@ int sp_ecc_uncompress_384(mp_int* xm, int odd, mp_int* ym) } #endif #endif /* WOLFSSL_SP_384 */ +#ifdef WOLFSSL_SP_1024 + +/* Point structure to use. */ +typedef struct sp_point_1024 { + /* X ordinate of point. */ + sp_digit x[2 * 42]; + /* Y ordinate of point. */ + sp_digit y[2 * 42]; + /* Z ordinate of point. */ + sp_digit z[2 * 42]; + /* Indicates point is at infinity. */ + int infinity; +} sp_point_1024; + +#ifndef WOLFSSL_SP_SMALL +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static void sp_1024_mul_7(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + int64_t t0 = ((int64_t)a[ 0]) * b[ 0]; + int64_t t1 = ((int64_t)a[ 0]) * b[ 1] + + ((int64_t)a[ 1]) * b[ 0]; + int64_t t2 = ((int64_t)a[ 0]) * b[ 2] + + ((int64_t)a[ 1]) * b[ 1] + + ((int64_t)a[ 2]) * b[ 0]; + int64_t t3 = ((int64_t)a[ 0]) * b[ 3] + + ((int64_t)a[ 1]) * b[ 2] + + ((int64_t)a[ 2]) * b[ 1] + + ((int64_t)a[ 3]) * b[ 0]; + int64_t t4 = ((int64_t)a[ 0]) * b[ 4] + + ((int64_t)a[ 1]) * b[ 3] + + ((int64_t)a[ 2]) * b[ 2] + + ((int64_t)a[ 3]) * b[ 1] + + ((int64_t)a[ 4]) * b[ 0]; + int64_t t5 = ((int64_t)a[ 0]) * b[ 5] + + ((int64_t)a[ 1]) * b[ 4] + + ((int64_t)a[ 2]) * b[ 3] + + ((int64_t)a[ 3]) * b[ 2] + + ((int64_t)a[ 4]) * b[ 1] + + ((int64_t)a[ 5]) * b[ 0]; + int64_t t6 = ((int64_t)a[ 0]) * b[ 6] + + ((int64_t)a[ 1]) * b[ 5] + + ((int64_t)a[ 2]) * b[ 4] + + ((int64_t)a[ 3]) * b[ 3] + + ((int64_t)a[ 4]) * b[ 2] + + ((int64_t)a[ 5]) * b[ 1] + + ((int64_t)a[ 6]) * b[ 0]; + int64_t t7 = ((int64_t)a[ 1]) * b[ 6] + + ((int64_t)a[ 2]) * b[ 5] + + ((int64_t)a[ 3]) * b[ 4] + + ((int64_t)a[ 4]) * b[ 3] + + ((int64_t)a[ 5]) * b[ 2] + + ((int64_t)a[ 6]) * b[ 1]; + int64_t t8 = ((int64_t)a[ 2]) * b[ 6] + + ((int64_t)a[ 3]) * b[ 5] + + ((int64_t)a[ 4]) * b[ 4] + + ((int64_t)a[ 5]) * b[ 3] + + ((int64_t)a[ 6]) * b[ 2]; + int64_t t9 = ((int64_t)a[ 3]) * b[ 6] + + ((int64_t)a[ 4]) * b[ 5] + + ((int64_t)a[ 5]) * b[ 4] + + ((int64_t)a[ 6]) * b[ 3]; + int64_t t10 = ((int64_t)a[ 4]) * b[ 6] + + ((int64_t)a[ 5]) * b[ 5] + + ((int64_t)a[ 6]) * b[ 4]; + int64_t t11 = ((int64_t)a[ 5]) * b[ 6] + + ((int64_t)a[ 6]) * b[ 5]; + int64_t t12 = ((int64_t)a[ 6]) * b[ 6]; + + t1 += t0 >> 25; r[ 0] = t0 & 0x1ffffff; + t2 += t1 >> 25; r[ 1] = t1 & 0x1ffffff; + t3 += t2 >> 25; r[ 2] = t2 & 0x1ffffff; + t4 += t3 >> 25; r[ 3] = t3 & 0x1ffffff; + t5 += t4 >> 25; r[ 4] = t4 & 0x1ffffff; + t6 += t5 >> 25; r[ 5] = t5 & 0x1ffffff; + t7 += t6 >> 25; r[ 6] = t6 & 0x1ffffff; + t8 += t7 >> 25; r[ 7] = t7 & 0x1ffffff; + t9 += t8 >> 25; r[ 8] = t8 & 0x1ffffff; + t10 += t9 >> 25; r[ 9] = t9 & 0x1ffffff; + t11 += t10 >> 25; r[10] = t10 & 0x1ffffff; + t12 += t11 >> 25; r[11] = t11 & 0x1ffffff; + r[13] = (sp_digit)(t12 >> 25); + r[12] = t12 & 0x1ffffff; +} + +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_1024_sqr_7(sp_digit* r, const sp_digit* a) +{ + int64_t t0 = ((int64_t)a[ 0]) * a[ 0]; + int64_t t1 = (((int64_t)a[ 0]) * a[ 1]) * 2; + int64_t t2 = (((int64_t)a[ 0]) * a[ 2]) * 2 + + ((int64_t)a[ 1]) * a[ 1]; + int64_t t3 = (((int64_t)a[ 0]) * a[ 3] + + ((int64_t)a[ 1]) * a[ 2]) * 2; + int64_t t4 = (((int64_t)a[ 0]) * a[ 4] + + ((int64_t)a[ 1]) * a[ 3]) * 2 + + ((int64_t)a[ 2]) * a[ 2]; + int64_t t5 = (((int64_t)a[ 0]) * a[ 5] + + ((int64_t)a[ 1]) * a[ 4] + + ((int64_t)a[ 2]) * a[ 3]) * 2; + int64_t t6 = (((int64_t)a[ 0]) * a[ 6] + + ((int64_t)a[ 1]) * a[ 5] + + ((int64_t)a[ 2]) * a[ 4]) * 2 + + ((int64_t)a[ 3]) * a[ 3]; + int64_t t7 = (((int64_t)a[ 1]) * a[ 6] + + ((int64_t)a[ 2]) * a[ 5] + + ((int64_t)a[ 3]) * a[ 4]) * 2; + int64_t t8 = (((int64_t)a[ 2]) * a[ 6] + + ((int64_t)a[ 3]) * a[ 5]) * 2 + + ((int64_t)a[ 4]) * a[ 4]; + int64_t t9 = (((int64_t)a[ 3]) * a[ 6] + + ((int64_t)a[ 4]) * a[ 5]) * 2; + int64_t t10 = (((int64_t)a[ 4]) * a[ 6]) * 2 + + ((int64_t)a[ 5]) * a[ 5]; + int64_t t11 = (((int64_t)a[ 5]) * a[ 6]) * 2; + int64_t t12 = ((int64_t)a[ 6]) * a[ 6]; + + t1 += t0 >> 25; r[ 0] = t0 & 0x1ffffff; + t2 += t1 >> 25; r[ 1] = t1 & 0x1ffffff; + t3 += t2 >> 25; r[ 2] = t2 & 0x1ffffff; + t4 += t3 >> 25; r[ 3] = t3 & 0x1ffffff; + t5 += t4 >> 25; r[ 4] = t4 & 0x1ffffff; + t6 += t5 >> 25; r[ 5] = t5 & 0x1ffffff; + t7 += t6 >> 25; r[ 6] = t6 & 0x1ffffff; + t8 += t7 >> 25; r[ 7] = t7 & 0x1ffffff; + t9 += t8 >> 25; r[ 8] = t8 & 0x1ffffff; + t10 += t9 >> 25; r[ 9] = t9 & 0x1ffffff; + t11 += t10 >> 25; r[10] = t10 & 0x1ffffff; + t12 += t11 >> 25; r[11] = t11 & 0x1ffffff; + r[13] = (sp_digit)(t12 >> 25); + r[12] = t12 & 0x1ffffff; +} + +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_1024_add_7(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + r[ 0] = a[ 0] + b[ 0]; + r[ 1] = a[ 1] + b[ 1]; + r[ 2] = a[ 2] + b[ 2]; + r[ 3] = a[ 3] + b[ 3]; + r[ 4] = a[ 4] + b[ 4]; + r[ 5] = a[ 5] + b[ 5]; + r[ 6] = a[ 6] + b[ 6]; + + return 0; +} + +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_1024_sub_14(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + r[ 0] = a[ 0] - b[ 0]; + r[ 1] = a[ 1] - b[ 1]; + r[ 2] = a[ 2] - b[ 2]; + r[ 3] = a[ 3] - b[ 3]; + r[ 4] = a[ 4] - b[ 4]; + r[ 5] = a[ 5] - b[ 5]; + r[ 6] = a[ 6] - b[ 6]; + r[ 7] = a[ 7] - b[ 7]; + r[ 8] = a[ 8] - b[ 8]; + r[ 9] = a[ 9] - b[ 9]; + r[10] = a[10] - b[10]; + r[11] = a[11] - b[11]; + r[12] = a[12] - b[12]; + r[13] = a[13] - b[13]; + + return 0; +} + +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_1024_add_14(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + r[ 0] = a[ 0] + b[ 0]; + r[ 1] = a[ 1] + b[ 1]; + r[ 2] = a[ 2] + b[ 2]; + r[ 3] = a[ 3] + b[ 3]; + r[ 4] = a[ 4] + b[ 4]; + r[ 5] = a[ 5] + b[ 5]; + r[ 6] = a[ 6] + b[ 6]; + r[ 7] = a[ 7] + b[ 7]; + r[ 8] = a[ 8] + b[ 8]; + r[ 9] = a[ 9] + b[ 9]; + r[10] = a[10] + b[10]; + r[11] = a[11] + b[11]; + r[12] = a[12] + b[12]; + r[13] = a[13] + b[13]; + + return 0; +} + +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static void sp_1024_mul_21(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit p0[14]; + sp_digit p1[14]; + sp_digit p2[14]; + sp_digit p3[14]; + sp_digit p4[14]; + sp_digit p5[14]; + sp_digit t0[14]; + sp_digit t1[14]; + sp_digit t2[14]; + sp_digit a0[7]; + sp_digit a1[7]; + sp_digit a2[7]; + sp_digit b0[7]; + sp_digit b1[7]; + sp_digit b2[7]; + (void)sp_1024_add_7(a0, a, &a[7]); + (void)sp_1024_add_7(b0, b, &b[7]); + (void)sp_1024_add_7(a1, &a[7], &a[14]); + (void)sp_1024_add_7(b1, &b[7], &b[14]); + (void)sp_1024_add_7(a2, a0, &a[14]); + (void)sp_1024_add_7(b2, b0, &b[14]); + sp_1024_mul_7(p0, a, b); + sp_1024_mul_7(p2, &a[7], &b[7]); + sp_1024_mul_7(p4, &a[14], &b[14]); + sp_1024_mul_7(p1, a0, b0); + sp_1024_mul_7(p3, a1, b1); + sp_1024_mul_7(p5, a2, b2); + XMEMSET(r, 0, sizeof(*r)*2U*21U); + (void)sp_1024_sub_14(t0, p3, p2); + (void)sp_1024_sub_14(t1, p1, p2); + (void)sp_1024_sub_14(t2, p5, t0); + (void)sp_1024_sub_14(t2, t2, t1); + (void)sp_1024_sub_14(t0, t0, p4); + (void)sp_1024_sub_14(t1, t1, p0); + (void)sp_1024_add_14(r, r, p0); + (void)sp_1024_add_14(&r[7], &r[7], t1); + (void)sp_1024_add_14(&r[14], &r[14], t2); + (void)sp_1024_add_14(&r[21], &r[21], t0); + (void)sp_1024_add_14(&r[28], &r[28], p4); +} + +/* Square a into r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_1024_sqr_21(sp_digit* r, const sp_digit* a) +{ + sp_digit p0[14]; + sp_digit p1[14]; + sp_digit p2[14]; + sp_digit p3[14]; + sp_digit p4[14]; + sp_digit p5[14]; + sp_digit t0[14]; + sp_digit t1[14]; + sp_digit t2[14]; + sp_digit a0[7]; + sp_digit a1[7]; + sp_digit a2[7]; + (void)sp_1024_add_7(a0, a, &a[7]); + (void)sp_1024_add_7(a1, &a[7], &a[14]); + (void)sp_1024_add_7(a2, a0, &a[14]); + sp_1024_sqr_7(p0, a); + sp_1024_sqr_7(p2, &a[7]); + sp_1024_sqr_7(p4, &a[14]); + sp_1024_sqr_7(p1, a0); + sp_1024_sqr_7(p3, a1); + sp_1024_sqr_7(p5, a2); + XMEMSET(r, 0, sizeof(*r)*2U*21U); + (void)sp_1024_sub_14(t0, p3, p2); + (void)sp_1024_sub_14(t1, p1, p2); + (void)sp_1024_sub_14(t2, p5, t0); + (void)sp_1024_sub_14(t2, t2, t1); + (void)sp_1024_sub_14(t0, t0, p4); + (void)sp_1024_sub_14(t1, t1, p0); + (void)sp_1024_add_14(r, r, p0); + (void)sp_1024_add_14(&r[7], &r[7], t1); + (void)sp_1024_add_14(&r[14], &r[14], t2); + (void)sp_1024_add_14(&r[21], &r[21], t0); + (void)sp_1024_add_14(&r[28], &r[28], p4); +} + +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_1024_add_21(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + int i; + + for (i = 0; i < 16; i += 8) { + r[i + 0] = a[i + 0] + b[i + 0]; + r[i + 1] = a[i + 1] + b[i + 1]; + r[i + 2] = a[i + 2] + b[i + 2]; + r[i + 3] = a[i + 3] + b[i + 3]; + r[i + 4] = a[i + 4] + b[i + 4]; + r[i + 5] = a[i + 5] + b[i + 5]; + r[i + 6] = a[i + 6] + b[i + 6]; + r[i + 7] = a[i + 7] + b[i + 7]; + } + r[16] = a[16] + b[16]; + r[17] = a[17] + b[17]; + r[18] = a[18] + b[18]; + r[19] = a[19] + b[19]; + r[20] = a[20] + b[20]; + + return 0; +} + +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_1024_add_42(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + int i; + + for (i = 0; i < 40; i += 8) { + r[i + 0] = a[i + 0] + b[i + 0]; + r[i + 1] = a[i + 1] + b[i + 1]; + r[i + 2] = a[i + 2] + b[i + 2]; + r[i + 3] = a[i + 3] + b[i + 3]; + r[i + 4] = a[i + 4] + b[i + 4]; + r[i + 5] = a[i + 5] + b[i + 5]; + r[i + 6] = a[i + 6] + b[i + 6]; + r[i + 7] = a[i + 7] + b[i + 7]; + } + r[40] = a[40] + b[40]; + r[41] = a[41] + b[41]; + + return 0; +} + +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_1024_sub_42(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + int i; + + for (i = 0; i < 40; i += 8) { + r[i + 0] = a[i + 0] - b[i + 0]; + r[i + 1] = a[i + 1] - b[i + 1]; + r[i + 2] = a[i + 2] - b[i + 2]; + r[i + 3] = a[i + 3] - b[i + 3]; + r[i + 4] = a[i + 4] - b[i + 4]; + r[i + 5] = a[i + 5] - b[i + 5]; + r[i + 6] = a[i + 6] - b[i + 6]; + r[i + 7] = a[i + 7] - b[i + 7]; + } + r[40] = a[40] - b[40]; + r[41] = a[41] - b[41]; + + return 0; +} + +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static void sp_1024_mul_42(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit* z0 = r; + sp_digit z1[42]; + sp_digit* a1 = z1; + sp_digit b1[21]; + sp_digit* z2 = r + 42; + (void)sp_1024_add_21(a1, a, &a[21]); + (void)sp_1024_add_21(b1, b, &b[21]); + sp_1024_mul_21(z2, &a[21], &b[21]); + sp_1024_mul_21(z0, a, b); + sp_1024_mul_21(z1, a1, b1); + (void)sp_1024_sub_42(z1, z1, z2); + (void)sp_1024_sub_42(z1, z1, z0); + (void)sp_1024_add_42(r + 21, r + 21, z1); +} + +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_1024_sqr_42(sp_digit* r, const sp_digit* a) +{ + sp_digit* z0 = r; + sp_digit z1[42]; + sp_digit* a1 = z1; + sp_digit* z2 = r + 42; + (void)sp_1024_add_21(a1, a, &a[21]); + sp_1024_sqr_21(z2, &a[21]); + sp_1024_sqr_21(z0, a); + sp_1024_sqr_21(z1, a1); + (void)sp_1024_sub_42(z1, z1, z2); + (void)sp_1024_sub_42(z1, z1, z0); + (void)sp_1024_add_42(r + 21, r + 21, z1); +} + +#else +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static void sp_1024_mul_42(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + int i; + int j; + int k; + int64_t c; + + c = ((int64_t)a[41]) * b[41]; + r[83] = (sp_digit)(c >> 25); + c = (c & 0x1ffffff) << 25; + for (k = 81; k >= 0; k--) { + for (i = 41; i >= 0; i--) { + j = k - i; + if (j >= 42) { + break; + } + if (j < 0) { + continue; + } + + c += ((int64_t)a[i]) * b[j]; + } + r[k + 2] += (sp_digit)(c >> 50); + r[k + 1] = (sp_digit)((c >> 25) & 0x1ffffff); + c = (c & 0x1ffffff) << 25; + } + r[0] = (sp_digit)(c >> 25); +} + +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_1024_sqr_42(sp_digit* r, const sp_digit* a) +{ + int i; + int j; + int k; + int64_t c; + + c = ((int64_t)a[41]) * a[41]; + r[83] = (sp_digit)(c >> 25); + c = (c & 0x1ffffff) << 25; + for (k = 81; k >= 0; k--) { + for (i = 41; i >= 0; i--) { + j = k - i; + if (j >= 42 || i <= j) { + break; + } + if (j < 0) { + continue; + } + + c += ((int64_t)a[i]) * a[j] * 2; + } + if (i == j) { + c += ((int64_t)a[i]) * a[i]; + } + + r[k + 2] += (sp_digit)(c >> 50); + r[k + 1] = (sp_digit)((c >> 25) & 0x1ffffff); + c = (c & 0x1ffffff) << 25; + } + r[0] = (sp_digit)(c >> 25); +} + +#endif /* !WOLFSSL_SP_SMALL */ +/* The modulus (prime) of the curve P1024. */ +static const sp_digit p1024_mod[42] = { + 0x0a85feb,0x0c03d7f,0x1a1d99b,0x0158f59,0x00c5df1,0x02bed84,0x1a08e26, + 0x03ff9c7,0x156971f,0x1ca6b57,0x1026aa7,0x18a4387,0x02a7cf3,0x18c2954, + 0x0bfd2a0,0x039c36d,0x1cd6568,0x0289562,0x09ad335,0x18c90e6,0x06d0e26, + 0x1a53335,0x0d5b49f,0x1911432,0x1b39ff7,0x05873c8,0x14c6967,0x050e61a, + 0x1c0f1b2,0x1593f17,0x0bbd02a,0x167c034,0x09ae358,0x04130df,0x138672d, + 0x1482d81,0x1ad0657,0x0308cc6,0x0ff6997,0x03e14ac,0x0997abb,0x0000000 +}; +/* The Montogmery normalizer for modulus of the curve P1024. */ +static const sp_digit p1024_norm_mod[42] = { + 0x157a015,0x13fc280,0x05e2664,0x1ea70a6,0x1f3a20e,0x1d4127b,0x05f71d9, + 0x1c00638,0x0a968e0,0x03594a8,0x0fd9558,0x075bc78,0x1d5830c,0x073d6ab, + 0x1402d5f,0x1c63c92,0x0329a97,0x1d76a9d,0x1652cca,0x0736f19,0x192f1d9, + 0x05accca,0x12a4b60,0x06eebcd,0x04c6008,0x1a78c37,0x0b39698,0x1af19e5, + 0x03f0e4d,0x0a6c0e8,0x1442fd5,0x0983fcb,0x1651ca7,0x1becf20,0x0c798d2, + 0x0b7d27e,0x052f9a8,0x1cf7339,0x1009668,0x1c1eb53,0x0668544,0x0000000 +}; +/* The Montogmery multiplier for modulus of the curve P1024. */ +static sp_digit p1024_mp_mod = 0x8f2f3d; +#if defined(WOLFSSL_SP_SMALL) || defined(HAVE_ECC_CHECK_KEY) +/* The order of the curve P1024. */ +static const sp_digit p1024_order[42] = { + 0x1aa17fb,0x1b00f5f,0x0e87666,0x08563d6,0x003177c,0x10afb61,0x1e82389, + 0x18ffe71,0x1d5a5c7,0x1f29ad5,0x1c09aa9,0x1e290e1,0x00a9f3c,0x0630a55, + 0x0aff4a8,0x00e70db,0x173595a,0x08a2558,0x126b4cd,0x1632439,0x09b4389, + 0x1e94ccd,0x1356d27,0x1e4450c,0x06ce7fd,0x1961cf2,0x1531a59,0x1143986, + 0x1f03c6c,0x1564fc5,0x02ef40a,0x059f00d,0x1a6b8d6,0x0904c37,0x0ce19cb, + 0x1d20b60,0x16b4195,0x18c2331,0x03fda65,0x18f852b,0x0265eae,0x0000000 +}; +#endif +/* The base point of curve P1024. */ +static const sp_point_1024 p1024_base = { + /* X ordinate */ + { + 0x0e63895,0x0e455f5,0x05e6203,0x092cfc1,0x00ec46c,0x1fb9f64,0x18e96d8, + 0x10fdd22,0x080728d,0x0e7da66,0x1a44375,0x029b74c,0x14a7c15,0x1d306f3, + 0x00b0ce5,0x1e5c34e,0x0548b72,0x199be43,0x1756f32,0x015eecb,0x0890976, + 0x13a0367,0x1c62f67,0x13bf4aa,0x1f22cdb,0x10821ea,0x00c2c27,0x1621b72, + 0x0e2308a,0x1b607b6,0x0fed7b6,0x16dfef9,0x0b2f204,0x034e34c,0x1f582bb, + 0x1456345,0x1ed9b52,0x1cc8029,0x0a6b429,0x1dc6658,0x053fc09,0x0000000, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* Y ordinate */ + { + 0x1ef16d7,0x19feb8d,0x1379d55,0x00d4cfb,0x0db9b57,0x1da31b5,0x0b56b56, + 0x153017b,0x1e9cb99,0x1a8ad6b,0x1357c84,0x0f3f8b4,0x09492d9,0x0b2554c, + 0x1bc7a00,0x05fc158,0x0b5b765,0x0656b4b,0x1551f1b,0x15c22f5,0x12b970d, + 0x0654f01,0x105b3fc,0x028165c,0x18ccf9a,0x0fb35ac,0x17c3795,0x0fefebc, + 0x0ec2b9e,0x14fa32a,0x1e3d7a9,0x03c2822,0x1778d82,0x0834b1e,0x00580a6, + 0x0ba7d04,0x1634a13,0x18f8299,0x027c7e7,0x00c7ec0,0x00a8249,0x0000000, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* Z ordinate */ + { + 0x0000001,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000, + 0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000, + 0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000, + 0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000, + 0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000, + 0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* infinity */ + 0 +}; + +/* Multiply a by scalar b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A scalar. + */ +SP_NOINLINE static void sp_1024_mul_d_42(sp_digit* r, const sp_digit* a, + sp_digit b) +{ +#ifdef WOLFSSL_SP_SMALL + int64_t tb = b; + int64_t t = 0; + int i; + + for (i = 0; i < 42; i++) { + t += tb * a[i]; + r[i] = (sp_digit)(t & 0x1ffffff); + t >>= 25; + } + r[42] = (sp_digit)t; +#else + int64_t tb = b; + int64_t t = 0; + sp_digit t2; + int64_t p[4]; + int i; + + for (i = 0; i < 40; i += 4) { + p[0] = tb * a[i + 0]; + p[1] = tb * a[i + 1]; + p[2] = tb * a[i + 2]; + p[3] = tb * a[i + 3]; + t += p[0]; + t2 = (sp_digit)(t & 0x1ffffff); + t >>= 25; + r[i + 0] = (sp_digit)t2; + t += p[1]; + t2 = (sp_digit)(t & 0x1ffffff); + t >>= 25; + r[i + 1] = (sp_digit)t2; + t += p[2]; + t2 = (sp_digit)(t & 0x1ffffff); + t >>= 25; + r[i + 2] = (sp_digit)t2; + t += p[3]; + t2 = (sp_digit)(t & 0x1ffffff); + t >>= 25; + r[i + 3] = (sp_digit)t2; + } + t += tb * a[40]; + r[40] = (sp_digit)(t & 0x1ffffff); + t >>= 25; + t += tb * a[41]; + r[41] = (sp_digit)(t & 0x1ffffff); + t >>= 25; + r[42] = (sp_digit)(t & 0x1ffffff); +#endif /* WOLFSSL_SP_SMALL */ +} + +/* Conditionally add a and b using the mask m. + * m is -1 to add and 0 when not. + * + * r A single precision number representing conditional add result. + * a A single precision number to add with. + * b A single precision number to add. + * m Mask value to apply. + */ +static void sp_1024_cond_add_42(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit m) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i = 0; i < 42; i++) { + r[i] = a[i] + (b[i] & m); + } +#else + int i; + + for (i = 0; i < 40; i += 8) { + r[i + 0] = a[i + 0] + (b[i + 0] & m); + r[i + 1] = a[i + 1] + (b[i + 1] & m); + r[i + 2] = a[i + 2] + (b[i + 2] & m); + r[i + 3] = a[i + 3] + (b[i + 3] & m); + r[i + 4] = a[i + 4] + (b[i + 4] & m); + r[i + 5] = a[i + 5] + (b[i + 5] & m); + r[i + 6] = a[i + 6] + (b[i + 6] & m); + r[i + 7] = a[i + 7] + (b[i + 7] & m); + } + r[40] = a[40] + (b[40] & m); + r[41] = a[41] + (b[41] & m); +#endif /* WOLFSSL_SP_SMALL */ +} + +#ifdef WOLFSSL_SP_SMALL +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_1024_sub_42(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + int i; + + for (i = 0; i < 42; i++) { + r[i] = a[i] - b[i]; + } + + return 0; +} + +#endif +#ifdef WOLFSSL_SP_SMALL +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_1024_add_42(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + int i; + + for (i = 0; i < 42; i++) { + r[i] = a[i] + b[i]; + } + + return 0; +} +#endif +#ifdef WOLFSSL_SP_DIV_32 +static WC_INLINE sp_digit sp_1024_div_word_42(sp_digit d1, sp_digit d0, + sp_digit dv) +{ + sp_digit d; + sp_digit r; + sp_digit t; + + /* All 25 bits from d1 and top 6 bits from d0. */ + d = (d1 << 6) | (d0 >> 19); + r = d / dv; + d -= r * dv; + /* Up to 7 bits in r */ + /* Next 6 bits from d0. */ + r <<= 6; + d <<= 6; + d |= (d0 >> 13) & ((1 << 6) - 1); + t = d / dv; + d -= t * dv; + r += t; + /* Up to 13 bits in r */ + /* Next 6 bits from d0. */ + r <<= 6; + d <<= 6; + d |= (d0 >> 7) & ((1 << 6) - 1); + t = d / dv; + d -= t * dv; + r += t; + /* Up to 19 bits in r */ + /* Next 6 bits from d0. */ + r <<= 6; + d <<= 6; + d |= (d0 >> 1) & ((1 << 6) - 1); + t = d / dv; + d -= t * dv; + r += t; + /* Up to 25 bits in r */ + /* Remaining 1 bits from d0. */ + r <<= 1; + d <<= 1; + d |= d0 & ((1 << 1) - 1); + t = d / dv; + r += t; + + return r; +} +#endif /* WOLFSSL_SP_DIV_32 */ + +/* Divide d in a and put remainder into r (m*d + r = a) + * m is not calculated as it is not needed at this time. + * + * Large number of bits in last word. + * + * a Number to be divided. + * d Number to divide with. + * m Multiplier result. + * r Remainder from the division. + * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise. + */ +static int sp_1024_div_42(const sp_digit* a, const sp_digit* d, + const sp_digit* m, sp_digit* r) +{ + int i; +#ifndef WOLFSSL_SP_DIV_32 + int64_t d1; +#endif + sp_digit dv; + sp_digit r1; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td; +#else + sp_digit t1d[84]; + sp_digit t2d[42 + 1]; +#endif + sp_digit* t1; + sp_digit* t2; + int err = MP_OKAY; + + (void)m; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * (3 * 42 + 1), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t1 = td; + t2 = td + 2 * 42; +#else + t1 = t1d; + t2 = t2d; +#endif + + dv = d[40]; + XMEMCPY(t1, a, sizeof(*t1) * 2U * 42U); + for (i=40; i>=0; i--) { + t1[42 + i] += t1[42 + i - 1] >> 25; + t1[42 + i - 1] &= 0x1ffffff; +#ifndef WOLFSSL_SP_DIV_32 + d1 = t1[41 + i]; + d1 <<= 25; + d1 += t1[41 + i - 1]; + r1 = (sp_digit)(d1 / dv); +#else + r1 = sp_1024_div_word_42(t1[41 + i], t1[41 + i - 1], dv); +#endif + + sp_1024_mul_d_42(t2, d, r1); + (void)sp_1024_sub_42(&t1[i], &t1[i], t2); + t1[42 + i] -= t2[42]; + t1[41 + i] += t1[41 + i - 1] >> 25; + t1[41 + i - 1] &= 0x1ffffff; + r1 = (((-t1[41 + i]) << 25) - t1[41 + i - 1]) / dv; + r1++; + sp_1024_mul_d_42(t2, d, r1); + (void)sp_1024_add_42(&t1[i], &t1[i], t2); + t1[41 + i] += t1[41 + i - 1] >> 25; + t1[41 + i - 1] &= 0x1ffffff; + } + t1[41 - 1] += t1[41 - 2] >> 25; + t1[41 - 2] &= 0x1ffffff; + r1 = t1[41 - 1] / dv; + + sp_1024_mul_d_42(t2, d, r1); + (void)sp_1024_sub_42(t1, t1, t2); + XMEMCPY(r, t1, sizeof(*r) * 84U); + for (i=0; i<40; i++) { + r[i+1] += r[i] >> 25; + r[i] &= 0x1ffffff; + } + sp_1024_cond_add_42(r, r, d, 0 - ((r[40] < 0) ? + (sp_digit)1 : (sp_digit)0)); + r[41] = 0; + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + + return err; +} + +/* Reduce a modulo m into r. (r = a mod m) + * + * r A single precision number that is the reduced result. + * a A single precision number that is to be reduced. + * m A single precision number that is the modulus to reduce with. + * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise. + */ +static int sp_1024_mod_42(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + return sp_1024_div_42(a, m, NULL, r); +} + +/* Multiply a number by Montogmery normalizer mod modulus (prime). + * + * r The resulting Montgomery form number. + * a The number to convert. + * m The modulus (prime). + * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. + */ +static int sp_1024_mod_mul_norm_42(sp_digit* r, const sp_digit* a, + const sp_digit* m) +{ + sp_1024_mul_42(r, a, p1024_norm_mod); + return sp_1024_mod_42(r, r, m); +} + +/* Create a new point. + * + * heap [in] Buffer to allocate dynamic memory from. + * sp [in] Data for point - only if not allocating. + * p [out] New point. + * returns MEMORY_E when dynamic memory allocation fails and 0 otherwise. + */ +static int sp_1024_point_new_ex_42(void* heap, sp_point_1024* sp, + sp_point_1024** p) +{ + int ret = MP_OKAY; + (void)heap; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + (void)sp; + *p = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024), heap, DYNAMIC_TYPE_ECC); +#else + *p = sp; +#endif + if (*p == NULL) { + ret = MEMORY_E; + } + return ret; +} + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* Allocate memory for point and return error. */ +#define sp_1024_point_new_42(heap, sp, p) sp_1024_point_new_ex_42((heap), NULL, &(p)) +#else +/* Set pointer to data and return no error. */ +#define sp_1024_point_new_42(heap, sp, p) sp_1024_point_new_ex_42((heap), &(sp), &(p)) +#endif + + +/* Free the point. + * + * p [in,out] Point to free. + * clear [in] Indicates whether to zeroize point. + * heap [in] Buffer from which dynamic memory was allocate from. + */ +static void sp_1024_point_free_42(sp_point_1024* p, int clear, void* heap) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* If valid pointer then clear point data if requested and free data. */ + if (p != NULL) { + if (clear != 0) { + XMEMSET(p, 0, sizeof(*p)); + } + XFREE(p, heap, DYNAMIC_TYPE_ECC); + } +#else +/* Clear point data if requested. */ + if ((p != NULL) && (clear != 0)) { + XMEMSET(p, 0, sizeof(*p)); + } +#endif + (void)heap; +} + +/* Convert an mp_int to an array of sp_digit. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a A multi-precision integer. + */ +static void sp_1024_from_mp(sp_digit* r, int size, const mp_int* a) +{ +#if DIGIT_BIT == 25 + int j; + + XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); + + for (j = a->used; j < size; j++) { + r[j] = 0; + } +#elif DIGIT_BIT > 25 + int i; + int j = 0; + word32 s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i] << s); + r[j] &= 0x1ffffff; + s = 25U - s; + if (j + 1 >= size) { + break; + } + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + while ((s + 25U) <= (word32)DIGIT_BIT) { + s += 25U; + r[j] &= 0x1ffffff; + if (j + 1 >= size) { + break; + } + if (s < (word32)DIGIT_BIT) { + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + } + else { + r[++j] = 0L; + } + } + s = (word32)DIGIT_BIT - s; + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#else + int i; + int j = 0; + int s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i]) << s; + if (s + DIGIT_BIT >= 25) { + r[j] &= 0x1ffffff; + if (j + 1 >= size) { + break; + } + s = 25 - s; + if (s == DIGIT_BIT) { + r[++j] = 0; + s = 0; + } + else { + r[++j] = a->dp[i] >> s; + s = DIGIT_BIT - s; + } + } + else { + s += DIGIT_BIT; + } + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#endif +} + +/* Convert a point of type ecc_point to type sp_point_1024. + * + * p Point of type sp_point_1024 (result). + * pm Point of type ecc_point. + */ +static void sp_1024_point_from_ecc_point_42(sp_point_1024* p, + const ecc_point* pm) +{ + XMEMSET(p->x, 0, sizeof(p->x)); + XMEMSET(p->y, 0, sizeof(p->y)); + XMEMSET(p->z, 0, sizeof(p->z)); + sp_1024_from_mp(p->x, 42, pm->x); + sp_1024_from_mp(p->y, 42, pm->y); + sp_1024_from_mp(p->z, 42, pm->z); + p->infinity = 0; +} + +/* Convert an array of sp_digit to an mp_int. + * + * a A single precision integer. + * r A multi-precision integer. + */ +static int sp_1024_to_mp(const sp_digit* a, mp_int* r) +{ + int err; + + err = mp_grow(r, (1024 + DIGIT_BIT - 1) / DIGIT_BIT); + if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ +#if DIGIT_BIT == 25 + XMEMCPY(r->dp, a, sizeof(sp_digit) * 42); + r->used = 42; + mp_clamp(r); +#elif DIGIT_BIT < 25 + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 42; i++) { + r->dp[j] |= (mp_digit)(a[i] << s); + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + s = DIGIT_BIT - s; + r->dp[++j] = (mp_digit)(a[i] >> s); + while (s + DIGIT_BIT <= 25) { + s += DIGIT_BIT; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; + if (s == SP_WORD_SIZE) { + r->dp[j] = 0; + } + else { + r->dp[j] = (mp_digit)(a[i] >> s); + } + } + s = 25 - s; + } + r->used = (1024 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#else + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 42; i++) { + r->dp[j] |= ((mp_digit)a[i]) << s; + if (s + 25 >= DIGIT_BIT) { + #if DIGIT_BIT != 32 && DIGIT_BIT != 64 + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + #endif + s = DIGIT_BIT - s; + r->dp[++j] = a[i] >> s; + s = 25 - s; + } + else { + s += 25; + } + } + r->used = (1024 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#endif + } + + return err; +} + +/* Convert a point of type sp_point_1024 to type ecc_point. + * + * p Point of type sp_point_1024. + * pm Point of type ecc_point (result). + * returns MEMORY_E when allocation of memory in ecc_point fails otherwise + * MP_OKAY. + */ +static int sp_1024_point_to_ecc_point_42(const sp_point_1024* p, ecc_point* pm) +{ + int err; + + err = sp_1024_to_mp(p->x, pm->x); + if (err == MP_OKAY) { + err = sp_1024_to_mp(p->y, pm->y); + } + if (err == MP_OKAY) { + err = sp_1024_to_mp(p->z, pm->z); + } + + return err; +} + +/* Compare a with b in constant time. + * + * a A single precision integer. + * b A single precision integer. + * return -ve, 0 or +ve if a is less than, equal to or greater than b + * respectively. + */ +static sp_digit sp_1024_cmp_42(const sp_digit* a, const sp_digit* b) +{ + sp_digit r = 0; +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i=41; i>=0; i--) { + r |= (a[i] - b[i]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + } +#else + int i; + + r |= (a[41] - b[41]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[40] - b[40]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + for (i = 32; i >= 0; i -= 8) { + r |= (a[i + 7] - b[i + 7]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[i + 6] - b[i + 6]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[i + 5] - b[i + 5]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[i + 4] - b[i + 4]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[i + 3] - b[i + 3]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[i + 2] - b[i + 2]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[i + 1] - b[i + 1]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[i + 0] - b[i + 0]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + } +#endif /* WOLFSSL_SP_SMALL */ + + return r; +} + +/* Conditionally subtract b from a using the mask m. + * m is -1 to subtract and 0 when not. + * + * r A single precision number representing condition subtract result. + * a A single precision number to subtract from. + * b A single precision number to subtract. + * m Mask value to apply. + */ +static void sp_1024_cond_sub_42(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit m) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i = 0; i < 42; i++) { + r[i] = a[i] - (b[i] & m); + } +#else + int i; + + for (i = 0; i < 40; i += 8) { + r[i + 0] = a[i + 0] - (b[i + 0] & m); + r[i + 1] = a[i + 1] - (b[i + 1] & m); + r[i + 2] = a[i + 2] - (b[i + 2] & m); + r[i + 3] = a[i + 3] - (b[i + 3] & m); + r[i + 4] = a[i + 4] - (b[i + 4] & m); + r[i + 5] = a[i + 5] - (b[i + 5] & m); + r[i + 6] = a[i + 6] - (b[i + 6] & m); + r[i + 7] = a[i + 7] - (b[i + 7] & m); + } + r[40] = a[40] - (b[40] & m); + r[41] = a[41] - (b[41] & m); +#endif /* WOLFSSL_SP_SMALL */ +} + +/* Mul a by scalar b and add into r. (r += a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A scalar. + */ +SP_NOINLINE static void sp_1024_mul_add_42(sp_digit* r, const sp_digit* a, + const sp_digit b) +{ +#ifdef WOLFSSL_SP_SMALL + int64_t tb = b; + int64_t t = 0; + int i; + + for (i = 0; i < 42; i++) { + t += (tb * a[i]) + r[i]; + r[i] = t & 0x1ffffff; + t >>= 25; + } + r[42] += (sp_digit)t; +#else + int64_t tb = b; + int64_t t[8]; + int i; + + t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1ffffff); + for (i = 0; i < 40; i += 8) { + t[1] = tb * a[i+1]; + r[i+1] += (sp_digit)((t[0] >> 25) + (t[1] & 0x1ffffff)); + t[2] = tb * a[i+2]; + r[i+2] += (sp_digit)((t[1] >> 25) + (t[2] & 0x1ffffff)); + t[3] = tb * a[i+3]; + r[i+3] += (sp_digit)((t[2] >> 25) + (t[3] & 0x1ffffff)); + t[4] = tb * a[i+4]; + r[i+4] += (sp_digit)((t[3] >> 25) + (t[4] & 0x1ffffff)); + t[5] = tb * a[i+5]; + r[i+5] += (sp_digit)((t[4] >> 25) + (t[5] & 0x1ffffff)); + t[6] = tb * a[i+6]; + r[i+6] += (sp_digit)((t[5] >> 25) + (t[6] & 0x1ffffff)); + t[7] = tb * a[i+7]; + r[i+7] += (sp_digit)((t[6] >> 25) + (t[7] & 0x1ffffff)); + t[0] = tb * a[i+8]; + r[i+8] += (sp_digit)((t[7] >> 25) + (t[0] & 0x1ffffff)); + } + t[1] = tb * a[41]; r[41] += (sp_digit)((t[0] >> 25) + (t[1] & 0x1ffffff)); + r[42] += (sp_digit)(t[1] >> 25); +#endif /* WOLFSSL_SP_SMALL */ +} + +/* Normalize the values in each word to 25. + * + * a Array of sp_digit to normalize. + */ +static void sp_1024_norm_42(sp_digit* a) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + for (i = 0; i < 41; i++) { + a[i+1] += a[i] >> 25; + a[i] &= 0x1ffffff; + } +#else + int i; + for (i = 0; i < 40; i += 8) { + a[i+1] += a[i+0] >> 25; a[i+0] &= 0x1ffffff; + a[i+2] += a[i+1] >> 25; a[i+1] &= 0x1ffffff; + a[i+3] += a[i+2] >> 25; a[i+2] &= 0x1ffffff; + a[i+4] += a[i+3] >> 25; a[i+3] &= 0x1ffffff; + a[i+5] += a[i+4] >> 25; a[i+4] &= 0x1ffffff; + a[i+6] += a[i+5] >> 25; a[i+5] &= 0x1ffffff; + a[i+7] += a[i+6] >> 25; a[i+6] &= 0x1ffffff; + a[i+8] += a[i+7] >> 25; a[i+7] &= 0x1ffffff; + } + a[40+1] += a[40] >> 25; a[40] &= 0x1ffffff; +#endif +} + +/* Shift the result in the high 1024 bits down to the bottom. + * + * r A single precision number. + * a A single precision number. + */ +static void sp_1024_mont_shift_42(sp_digit* r, const sp_digit* a) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + word32 n; + + n = a[40] >> 24; + for (i = 0; i < 40; i++) { + n += (word32)a[41 + i] << 1; + r[i] = n & 0x1ffffff; + n >>= 25; + } + n += (word32)a[81] << 1; + r[40] = n; +#else + word32 n; + int i; + + n = (word32)a[40]; + n = n >> 24U; + for (i = 0; i < 40; i += 8) { + n += (word32)a[i+41] << 1U; r[i+0] = n & 0x1ffffff; n >>= 25U; + n += (word32)a[i+42] << 1U; r[i+1] = n & 0x1ffffff; n >>= 25U; + n += (word32)a[i+43] << 1U; r[i+2] = n & 0x1ffffff; n >>= 25U; + n += (word32)a[i+44] << 1U; r[i+3] = n & 0x1ffffff; n >>= 25U; + n += (word32)a[i+45] << 1U; r[i+4] = n & 0x1ffffff; n >>= 25U; + n += (word32)a[i+46] << 1U; r[i+5] = n & 0x1ffffff; n >>= 25U; + n += (word32)a[i+47] << 1U; r[i+6] = n & 0x1ffffff; n >>= 25U; + n += (word32)a[i+48] << 1U; r[i+7] = n & 0x1ffffff; n >>= 25U; + } + n += (word32)a[81] << 1U; r[40] = n; +#endif /* WOLFSSL_SP_SMALL */ + XMEMSET(&r[41], 0, sizeof(*r) * 41U); +} + +/* Reduce the number back to 1024 bits using Montgomery reduction. + * + * a A single precision number to reduce in place. + * m The single precision number representing the modulus. + * mp The digit representing the negative inverse of m mod 2^n. + */ +static void sp_1024_mont_reduce_42(sp_digit* a, const sp_digit* m, sp_digit mp) +{ + int i; + sp_digit mu; + + sp_1024_norm_42(a + 41); + +#ifdef WOLFSSL_SP_DH + if (mp != 1) { + for (i=0; i<40; i++) { + mu = (a[i] * mp) & 0x1ffffff; + sp_1024_mul_add_42(a+i, m, mu); + a[i+1] += a[i] >> 25; + } + mu = (a[i] * mp) & 0xffffffL; + sp_1024_mul_add_42(a+i, m, mu); + a[i+1] += a[i] >> 25; + a[i] &= 0x1ffffff; + } + else { + for (i=0; i<40; i++) { + mu = a[i] & 0x1ffffff; + sp_1024_mul_add_42(a+i, m, mu); + a[i+1] += a[i] >> 25; + } + mu = a[i] & 0xffffffL; + sp_1024_mul_add_42(a+i, m, mu); + a[i+1] += a[i] >> 25; + a[i] &= 0x1ffffff; + } +#else + for (i=0; i<40; i++) { + mu = (a[i] * mp) & 0x1ffffff; + sp_1024_mul_add_42(a+i, m, mu); + a[i+1] += a[i] >> 25; + } + mu = (a[i] * mp) & 0xffffffL; + sp_1024_mul_add_42(a+i, m, mu); + a[i+1] += a[i] >> 25; + a[i] &= 0x1ffffff; +#endif + sp_1024_norm_42(a + 41); + sp_1024_mont_shift_42(a, a); + sp_1024_cond_sub_42(a, a, m, 0 - (((a[40] - m[40]) > 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_42(a); +} + +/* Multiply two Montogmery form numbers mod the modulus (prime). + * (r = a * b mod m) + * + * r Result of multiplication. + * a First number to multiply in Montogmery form. + * b Second number to multiply in Montogmery form. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_1024_mont_mul_42(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) +{ + sp_1024_mul_42(r, a, b); + sp_1024_mont_reduce_42(r, m, mp); +} + +/* Square the Montgomery form number. (r = a * a mod m) + * + * r Result of squaring. + * a Number to square in Montogmery form. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_1024_mont_sqr_42(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) +{ + sp_1024_sqr_42(r, a); + sp_1024_mont_reduce_42(r, m, mp); +} + +/* Mod-2 for the P1024 curve. */ +static const uint8_t p1024_mod_minus_2[] = { + 6,0x06, 7,0x0f, 7,0x0b, 6,0x0c, 7,0x1e, 9,0x09, 7,0x0c, 7,0x1f, + 6,0x16, 6,0x06, 7,0x0e, 8,0x10, 6,0x03, 8,0x11, 6,0x0d, 7,0x14, + 9,0x12, 6,0x0f, 7,0x04, 9,0x0d, 6,0x00, 7,0x13, 6,0x01, 6,0x07, + 8,0x0d, 8,0x00, 6,0x06, 9,0x17, 6,0x14, 6,0x15, 6,0x11, 6,0x0b, + 9,0x0c, 6,0x1e, 13,0x14, 7,0x0e, 6,0x1d, 12,0x0a, 6,0x0b, 8,0x07, + 6,0x18, 6,0x0f, 6,0x10, 8,0x1c, 7,0x16, 7,0x02, 6,0x01, 6,0x13, + 10,0x15, 7,0x06, 8,0x14, 6,0x0c, 6,0x19, 7,0x10, 6,0x19, 6,0x19, + 9,0x16, 7,0x19, 6,0x1f, 6,0x17, 6,0x12, 8,0x02, 6,0x01, 6,0x04, + 6,0x15, 7,0x16, 6,0x04, 6,0x1f, 6,0x09, 7,0x06, 7,0x13, 7,0x09, + 6,0x0d, 10,0x18, 6,0x06, 6,0x11, 6,0x04, 6,0x01, 6,0x13, 8,0x06, + 6,0x0d, 8,0x13, 7,0x08, 6,0x08, 6,0x05, 7,0x0c, 7,0x0e, 7,0x15, + 6,0x05, 7,0x14, 10,0x19, 6,0x10, 6,0x16, 6,0x15, 7,0x1f, 6,0x14, + 6,0x0a, 10,0x11, 6,0x01, 7,0x05, 7,0x08, 8,0x0a, 7,0x1e, 7,0x1c, + 6,0x1c, 7,0x09, 10,0x18, 7,0x1c, 10,0x06, 6,0x0a, 6,0x07, 6,0x19, + 7,0x06, 6,0x0d, 7,0x0f, 7,0x0b, 7,0x05, 6,0x11, 6,0x1c, 7,0x1f, + 6,0x1e, 7,0x18, 6,0x1e, 6,0x00, 6,0x03, 6,0x02, 7,0x10, 6,0x0b, + 6,0x1b, 7,0x10, 6,0x00, 8,0x11, 7,0x1b, 6,0x18, 6,0x01, 7,0x0c, + 7,0x1d, 7,0x13, 6,0x08, 7,0x1b, 8,0x13, 7,0x16, 13,0x1d, 7,0x1f, + 6,0x0a, 6,0x01, 7,0x1f, 6,0x14, 1,0x01 +}; + +/* Invert the number, in Montgomery form, modulo the modulus (prime) of the + * P1024 curve. (r = 1 / a mod m) + * + * r Inverse result. + * a Number to invert. + * td Temporary data. + */ +static void sp_1024_mont_inv_42(sp_digit* r, const sp_digit* a, + sp_digit* td) +{ + sp_digit* t = td; + int i; + int j; + sp_digit table[32][2 * 42]; + + XMEMCPY(table[0], a, sizeof(sp_digit) * 42); + for (i = 1; i < 6; i++) { + sp_1024_mont_sqr_42(table[0], table[0], p1024_mod, p1024_mp_mod); + } + for (i = 1; i < 32; i++) { + sp_1024_mont_mul_42(table[i], table[i-1], a, p1024_mod, p1024_mp_mod); + } + + XMEMCPY(t, table[p1024_mod_minus_2[1]], sizeof(sp_digit) * 42); + for (i = 2; i < (int)sizeof(p1024_mod_minus_2) - 2; i += 2) { + for (j = 0; j < p1024_mod_minus_2[i]; j++) { + sp_1024_mont_sqr_42(t, t, p1024_mod, p1024_mp_mod); + } + sp_1024_mont_mul_42(t, t, table[p1024_mod_minus_2[i+1]], p1024_mod, + p1024_mp_mod); + } + sp_1024_mont_sqr_42(t, t, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(r, t, a, p1024_mod, p1024_mp_mod); +} + +/* Map the Montgomery form projective coordinate point to an affine point. + * + * r Resulting affine coordinate point. + * p Montgomery form projective coordinate point. + * t Temporary ordinate data. + */ +static void sp_1024_map_42(sp_point_1024* r, const sp_point_1024* p, + sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*42; + int32_t n; + + sp_1024_mont_inv_42(t1, p->z, t + 2*42); + + sp_1024_mont_sqr_42(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(t1, t2, t1, p1024_mod, p1024_mp_mod); + + /* x /= z^2 */ + sp_1024_mont_mul_42(r->x, p->x, t2, p1024_mod, p1024_mp_mod); + XMEMSET(r->x + 42, 0, sizeof(r->x) / 2U); + sp_1024_mont_reduce_42(r->x, p1024_mod, p1024_mp_mod); + /* Reduce x to less than modulus */ + n = sp_1024_cmp_42(r->x, p1024_mod); + sp_1024_cond_sub_42(r->x, r->x, p1024_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_42(r->x); + + /* y /= z^3 */ + sp_1024_mont_mul_42(r->y, p->y, t1, p1024_mod, p1024_mp_mod); + XMEMSET(r->y + 42, 0, sizeof(r->y) / 2U); + sp_1024_mont_reduce_42(r->y, p1024_mod, p1024_mp_mod); + /* Reduce y to less than modulus */ + n = sp_1024_cmp_42(r->y, p1024_mod); + sp_1024_cond_sub_42(r->y, r->y, p1024_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_42(r->y); + + XMEMSET(r->z, 0, sizeof(r->z)); + r->z[0] = 1; + +} + +/* Add two Montgomery form numbers (r = a + b % m). + * + * r Result of addition. + * a First number to add in Montogmery form. + * b Second number to add in Montogmery form. + * m Modulus (prime). + */ +static void sp_1024_mont_add_42(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + (void)sp_1024_add_42(r, a, b); + sp_1024_norm_42(r); + sp_1024_cond_sub_42(r, r, m, 0 - (((r[40] - m[40]) > 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_42(r); +} + +/* Double a Montgomery form number (r = a + a % m). + * + * r Result of doubling. + * a Number to double in Montogmery form. + * m Modulus (prime). + */ +static void sp_1024_mont_dbl_42(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + (void)sp_1024_add_42(r, a, a); + sp_1024_norm_42(r); + sp_1024_cond_sub_42(r, r, m, 0 - (((r[40] - m[40]) > 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_42(r); +} + +/* Triple a Montgomery form number (r = a + a + a % m). + * + * r Result of Tripling. + * a Number to triple in Montogmery form. + * m Modulus (prime). + */ +static void sp_1024_mont_tpl_42(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + (void)sp_1024_add_42(r, a, a); + sp_1024_norm_42(r); + sp_1024_cond_sub_42(r, r, m, 0 - (((r[40] - m[40]) > 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_42(r); + (void)sp_1024_add_42(r, r, a); + sp_1024_norm_42(r); + sp_1024_cond_sub_42(r, r, m, 0 - (((r[40] - m[40]) > 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_42(r); +} + +/* Subtract two Montgomery form numbers (r = a - b % m). + * + * r Result of subtration. + * a Number to subtract from in Montogmery form. + * b Number to subtract with in Montogmery form. + * m Modulus (prime). + */ +static void sp_1024_mont_sub_42(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + (void)sp_1024_sub_42(r, a, b); + sp_1024_norm_42(r); + sp_1024_cond_add_42(r, r, m, r[41] >> 7); + sp_1024_norm_42(r); +} + +/* Shift number left one bit. + * Bottom bit is lost. + * + * r Result of shift. + * a Number to shift. + */ +SP_NOINLINE static void sp_1024_rshift1_42(sp_digit* r, const sp_digit* a) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i=0; i<41; i++) { + r[i] = (a[i] >> 1) + ((a[i + 1] << 24) & 0x1ffffff); + } +#else + r[0] = (a[0] >> 1) + ((a[1] << 24) & 0x1ffffff); + r[1] = (a[1] >> 1) + ((a[2] << 24) & 0x1ffffff); + r[2] = (a[2] >> 1) + ((a[3] << 24) & 0x1ffffff); + r[3] = (a[3] >> 1) + ((a[4] << 24) & 0x1ffffff); + r[4] = (a[4] >> 1) + ((a[5] << 24) & 0x1ffffff); + r[5] = (a[5] >> 1) + ((a[6] << 24) & 0x1ffffff); + r[6] = (a[6] >> 1) + ((a[7] << 24) & 0x1ffffff); + r[7] = (a[7] >> 1) + ((a[8] << 24) & 0x1ffffff); + r[8] = (a[8] >> 1) + ((a[9] << 24) & 0x1ffffff); + r[9] = (a[9] >> 1) + ((a[10] << 24) & 0x1ffffff); + r[10] = (a[10] >> 1) + ((a[11] << 24) & 0x1ffffff); + r[11] = (a[11] >> 1) + ((a[12] << 24) & 0x1ffffff); + r[12] = (a[12] >> 1) + ((a[13] << 24) & 0x1ffffff); + r[13] = (a[13] >> 1) + ((a[14] << 24) & 0x1ffffff); + r[14] = (a[14] >> 1) + ((a[15] << 24) & 0x1ffffff); + r[15] = (a[15] >> 1) + ((a[16] << 24) & 0x1ffffff); + r[16] = (a[16] >> 1) + ((a[17] << 24) & 0x1ffffff); + r[17] = (a[17] >> 1) + ((a[18] << 24) & 0x1ffffff); + r[18] = (a[18] >> 1) + ((a[19] << 24) & 0x1ffffff); + r[19] = (a[19] >> 1) + ((a[20] << 24) & 0x1ffffff); + r[20] = (a[20] >> 1) + ((a[21] << 24) & 0x1ffffff); + r[21] = (a[21] >> 1) + ((a[22] << 24) & 0x1ffffff); + r[22] = (a[22] >> 1) + ((a[23] << 24) & 0x1ffffff); + r[23] = (a[23] >> 1) + ((a[24] << 24) & 0x1ffffff); + r[24] = (a[24] >> 1) + ((a[25] << 24) & 0x1ffffff); + r[25] = (a[25] >> 1) + ((a[26] << 24) & 0x1ffffff); + r[26] = (a[26] >> 1) + ((a[27] << 24) & 0x1ffffff); + r[27] = (a[27] >> 1) + ((a[28] << 24) & 0x1ffffff); + r[28] = (a[28] >> 1) + ((a[29] << 24) & 0x1ffffff); + r[29] = (a[29] >> 1) + ((a[30] << 24) & 0x1ffffff); + r[30] = (a[30] >> 1) + ((a[31] << 24) & 0x1ffffff); + r[31] = (a[31] >> 1) + ((a[32] << 24) & 0x1ffffff); + r[32] = (a[32] >> 1) + ((a[33] << 24) & 0x1ffffff); + r[33] = (a[33] >> 1) + ((a[34] << 24) & 0x1ffffff); + r[34] = (a[34] >> 1) + ((a[35] << 24) & 0x1ffffff); + r[35] = (a[35] >> 1) + ((a[36] << 24) & 0x1ffffff); + r[36] = (a[36] >> 1) + ((a[37] << 24) & 0x1ffffff); + r[37] = (a[37] >> 1) + ((a[38] << 24) & 0x1ffffff); + r[38] = (a[38] >> 1) + ((a[39] << 24) & 0x1ffffff); + r[39] = (a[39] >> 1) + ((a[40] << 24) & 0x1ffffff); + r[40] = (a[40] >> 1) + ((a[41] << 24) & 0x1ffffff); +#endif + r[41] = a[41] >> 1; +} + +/* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m) + * + * r Result of division by 2. + * a Number to divide. + * m Modulus (prime). + */ +static void sp_1024_div2_42(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_1024_cond_add_42(r, a, m, 0 - (a[0] & 1)); + sp_1024_norm_42(r); + sp_1024_rshift1_42(r, r); +} + +/* Double the Montgomery form projective point p. + * + * r Result of doubling point. + * p Point to double. + * t Temporary ordinate data. + */ +#ifdef WOLFSSL_SP_NONBLOCK +typedef struct sp_1024_proj_point_dbl_42_ctx { + int state; + sp_digit* t1; + sp_digit* t2; + sp_digit* x; + sp_digit* y; + sp_digit* z; +} sp_1024_proj_point_dbl_42_ctx; + +static int sp_1024_proj_point_dbl_42_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r, const sp_point_1024* p, sp_digit* t) +{ + int err = FP_WOULDBLOCK; + sp_1024_proj_point_dbl_42_ctx* ctx = (sp_1024_proj_point_dbl_42_ctx*)sp_ctx->data; + + typedef char ctx_size_test[sizeof(sp_1024_proj_point_dbl_42_ctx) >= sizeof(*sp_ctx) ? -1 : 1]; + (void)sizeof(ctx_size_test); + + switch (ctx->state) { + case 0: + ctx->t1 = t; + ctx->t2 = t + 2*42; + ctx->x = r->x; + ctx->y = r->y; + ctx->z = r->z; + + /* Put infinity into result. */ + if (r != p) { + r->infinity = p->infinity; + } + ctx->state = 1; + break; + case 1: + /* T1 = Z * Z */ + sp_1024_mont_sqr_42(ctx->t1, p->z, p1024_mod, p1024_mp_mod); + ctx->state = 2; + break; + case 2: + /* Z = Y * Z */ + sp_1024_mont_mul_42(ctx->z, p->y, p->z, p1024_mod, p1024_mp_mod); + ctx->state = 3; + break; + case 3: + /* Z = 2Z */ + sp_1024_mont_dbl_42(ctx->z, ctx->z, p1024_mod); + ctx->state = 4; + break; + case 4: + /* T2 = X - T1 */ + sp_1024_mont_sub_42(ctx->t2, p->x, ctx->t1, p1024_mod); + ctx->state = 5; + break; + case 5: + /* T1 = X + T1 */ + sp_1024_mont_add_42(ctx->t1, p->x, ctx->t1, p1024_mod); + ctx->state = 6; + break; + case 6: + /* T2 = T1 * T2 */ + sp_1024_mont_mul_42(ctx->t2, ctx->t1, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 7; + break; + case 7: + /* T1 = 3T2 */ + sp_1024_mont_tpl_42(ctx->t1, ctx->t2, p1024_mod); + ctx->state = 8; + break; + case 8: + /* Y = 2Y */ + sp_1024_mont_dbl_42(ctx->y, p->y, p1024_mod); + ctx->state = 9; + break; + case 9: + /* Y = Y * Y */ + sp_1024_mont_sqr_42(ctx->y, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 10; + break; + case 10: + /* T2 = Y * Y */ + sp_1024_mont_sqr_42(ctx->t2, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 11; + break; + case 11: + /* T2 = T2/2 */ + sp_1024_div2_42(ctx->t2, ctx->t2, p1024_mod); + ctx->state = 12; + break; + case 12: + /* Y = Y * X */ + sp_1024_mont_mul_42(ctx->y, ctx->y, p->x, p1024_mod, p1024_mp_mod); + ctx->state = 13; + break; + case 13: + /* X = T1 * T1 */ + sp_1024_mont_sqr_42(ctx->x, ctx->t1, p1024_mod, p1024_mp_mod); + ctx->state = 14; + break; + case 14: + /* X = X - Y */ + sp_1024_mont_sub_42(ctx->x, ctx->x, ctx->y, p1024_mod); + ctx->state = 15; + break; + case 15: + /* X = X - Y */ + sp_1024_mont_sub_42(ctx->x, ctx->x, ctx->y, p1024_mod); + ctx->state = 16; + break; + case 16: + /* Y = Y - X */ + sp_1024_mont_sub_42(ctx->y, ctx->y, ctx->x, p1024_mod); + ctx->state = 17; + break; + case 17: + /* Y = Y * T1 */ + sp_1024_mont_mul_42(ctx->y, ctx->y, ctx->t1, p1024_mod, p1024_mp_mod); + ctx->state = 18; + break; + case 18: + /* Y = Y - T2 */ + sp_1024_mont_sub_42(ctx->y, ctx->y, ctx->t2, p1024_mod); + ctx->state = 19; + /* fall-through */ + case 19: + err = MP_OKAY; + break; + } + + if (err == MP_OKAY && ctx->state != 19) { + err = FP_WOULDBLOCK; + } + + return err; +} +#endif /* WOLFSSL_SP_NONBLOCK */ + +static void sp_1024_proj_point_dbl_42(sp_point_1024* r, const sp_point_1024* p, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*42; + sp_digit* x; + sp_digit* y; + sp_digit* z; + + x = r->x; + y = r->y; + z = r->z; + /* Put infinity into result. */ + if (r != p) { + r->infinity = p->infinity; + } + + /* T1 = Z * Z */ + sp_1024_mont_sqr_42(t1, p->z, p1024_mod, p1024_mp_mod); + /* Z = Y * Z */ + sp_1024_mont_mul_42(z, p->y, p->z, p1024_mod, p1024_mp_mod); + /* Z = 2Z */ + sp_1024_mont_dbl_42(z, z, p1024_mod); + /* T2 = X - T1 */ + sp_1024_mont_sub_42(t2, p->x, t1, p1024_mod); + /* T1 = X + T1 */ + sp_1024_mont_add_42(t1, p->x, t1, p1024_mod); + /* T2 = T1 * T2 */ + sp_1024_mont_mul_42(t2, t1, t2, p1024_mod, p1024_mp_mod); + /* T1 = 3T2 */ + sp_1024_mont_tpl_42(t1, t2, p1024_mod); + /* Y = 2Y */ + sp_1024_mont_dbl_42(y, p->y, p1024_mod); + /* Y = Y * Y */ + sp_1024_mont_sqr_42(y, y, p1024_mod, p1024_mp_mod); + /* T2 = Y * Y */ + sp_1024_mont_sqr_42(t2, y, p1024_mod, p1024_mp_mod); + /* T2 = T2/2 */ + sp_1024_div2_42(t2, t2, p1024_mod); + /* Y = Y * X */ + sp_1024_mont_mul_42(y, y, p->x, p1024_mod, p1024_mp_mod); + /* X = T1 * T1 */ + sp_1024_mont_sqr_42(x, t1, p1024_mod, p1024_mp_mod); + /* X = X - Y */ + sp_1024_mont_sub_42(x, x, y, p1024_mod); + /* X = X - Y */ + sp_1024_mont_sub_42(x, x, y, p1024_mod); + /* Y = Y - X */ + sp_1024_mont_sub_42(y, y, x, p1024_mod); + /* Y = Y * T1 */ + sp_1024_mont_mul_42(y, y, t1, p1024_mod, p1024_mp_mod); + /* Y = Y - T2 */ + sp_1024_mont_sub_42(y, y, t2, p1024_mod); +} + +/* Compare two numbers to determine if they are equal. + * Constant time implementation. + * + * a First number to compare. + * b Second number to compare. + * returns 1 when equal and 0 otherwise. + */ +static int sp_1024_cmp_equal_42(const sp_digit* a, const sp_digit* b) +{ + return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) | (a[3] ^ b[3]) | + (a[4] ^ b[4]) | (a[5] ^ b[5]) | (a[6] ^ b[6]) | (a[7] ^ b[7]) | + (a[8] ^ b[8]) | (a[9] ^ b[9]) | (a[10] ^ b[10]) | (a[11] ^ b[11]) | + (a[12] ^ b[12]) | (a[13] ^ b[13]) | (a[14] ^ b[14]) | (a[15] ^ b[15]) | + (a[16] ^ b[16]) | (a[17] ^ b[17]) | (a[18] ^ b[18]) | (a[19] ^ b[19]) | + (a[20] ^ b[20]) | (a[21] ^ b[21]) | (a[22] ^ b[22]) | (a[23] ^ b[23]) | + (a[24] ^ b[24]) | (a[25] ^ b[25]) | (a[26] ^ b[26]) | (a[27] ^ b[27]) | + (a[28] ^ b[28]) | (a[29] ^ b[29]) | (a[30] ^ b[30]) | (a[31] ^ b[31]) | + (a[32] ^ b[32]) | (a[33] ^ b[33]) | (a[34] ^ b[34]) | (a[35] ^ b[35]) | + (a[36] ^ b[36]) | (a[37] ^ b[37]) | (a[38] ^ b[38]) | (a[39] ^ b[39]) | + (a[40] ^ b[40]) | (a[41] ^ b[41])) == 0; +} + +/* Add two Montgomery form projective points. + * + * r Result of addition. + * p First point to add. + * q Second point to add. + * t Temporary ordinate data. + */ + +#ifdef WOLFSSL_SP_NONBLOCK +typedef struct sp_1024_proj_point_add_42_ctx { + int state; + sp_1024_proj_point_dbl_42_ctx dbl_ctx; + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1; + sp_digit* t2; + sp_digit* t3; + sp_digit* t4; + sp_digit* t5; + sp_digit* x; + sp_digit* y; + sp_digit* z; +} sp_1024_proj_point_add_42_ctx; + +static int sp_1024_proj_point_add_42_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r, + const sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + int err = FP_WOULDBLOCK; + sp_1024_proj_point_add_42_ctx* ctx = (sp_1024_proj_point_add_42_ctx*)sp_ctx->data; + + /* Ensure only the first point is the same as the result. */ + if (q == r) { + const sp_point_1024* a = p; + p = q; + q = a; + } + + typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_42_ctx) >= sizeof(*sp_ctx) ? -1 : 1]; + (void)sizeof(ctx_size_test); + + switch (ctx->state) { + case 0: /* INIT */ + ctx->t1 = t; + ctx->t2 = t + 2*42; + ctx->t3 = t + 4*42; + ctx->t4 = t + 6*42; + ctx->t5 = t + 8*42; + + ctx->state = 1; + break; + case 1: + /* Check double */ + (void)sp_1024_sub_42(ctx->t1, p1024_mod, q->y); + sp_1024_norm_42(ctx->t1); + if ((sp_1024_cmp_equal_42(p->x, q->x) & sp_1024_cmp_equal_42(p->z, q->z) & + (sp_1024_cmp_equal_42(p->y, q->y) | sp_1024_cmp_equal_42(p->y, ctx->t1))) != 0) + { + XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx)); + ctx->state = 2; + } + else { + ctx->state = 3; + } + break; + case 2: + err = sp_1024_proj_point_dbl_42_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, r, p, t); + if (err == MP_OKAY) + ctx->state = 27; /* done */ + break; + case 3: + { + int i; + ctx->rp[0] = r; + + /*lint allow cast to different type of pointer*/ + ctx->rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(ctx->rp[1], 0, sizeof(sp_point_1024)); + ctx->x = ctx->rp[p->infinity | q->infinity]->x; + ctx->y = ctx->rp[p->infinity | q->infinity]->y; + ctx->z = ctx->rp[p->infinity | q->infinity]->z; + + ctx->ap[0] = p; + ctx->ap[1] = q; + for (i=0; i<42; i++) { + r->x[i] = ctx->ap[p->infinity]->x[i]; + } + for (i=0; i<42; i++) { + r->y[i] = ctx->ap[p->infinity]->y[i]; + } + for (i=0; i<42; i++) { + r->z[i] = ctx->ap[p->infinity]->z[i]; + } + r->infinity = ctx->ap[p->infinity]->infinity; + + ctx->state = 4; + break; + } + case 4: + /* U1 = X1*Z2^2 */ + sp_1024_mont_sqr_42(ctx->t1, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 5; + break; + case 5: + sp_1024_mont_mul_42(ctx->t3, ctx->t1, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 6; + break; + case 6: + sp_1024_mont_mul_42(ctx->t1, ctx->t1, ctx->x, p1024_mod, p1024_mp_mod); + ctx->state = 7; + break; + case 7: + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_42(ctx->t2, ctx->z, p1024_mod, p1024_mp_mod); + ctx->state = 8; + break; + case 8: + sp_1024_mont_mul_42(ctx->t4, ctx->t2, ctx->z, p1024_mod, p1024_mp_mod); + ctx->state = 9; + break; + case 9: + sp_1024_mont_mul_42(ctx->t2, ctx->t2, q->x, p1024_mod, p1024_mp_mod); + ctx->state = 10; + break; + case 10: + /* S1 = Y1*Z2^3 */ + sp_1024_mont_mul_42(ctx->t3, ctx->t3, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 11; + break; + case 11: + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_42(ctx->t4, ctx->t4, q->y, p1024_mod, p1024_mp_mod); + ctx->state = 12; + break; + case 12: + /* H = U2 - U1 */ + sp_1024_mont_sub_42(ctx->t2, ctx->t2, ctx->t1, p1024_mod); + ctx->state = 13; + break; + case 13: + /* R = S2 - S1 */ + sp_1024_mont_sub_42(ctx->t4, ctx->t4, ctx->t3, p1024_mod); + ctx->state = 14; + break; + case 14: + /* Z3 = H*Z1*Z2 */ + sp_1024_mont_mul_42(ctx->z, ctx->z, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 15; + break; + case 15: + sp_1024_mont_mul_42(ctx->z, ctx->z, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 16; + break; + case 16: + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_1024_mont_sqr_42(ctx->x, ctx->t4, p1024_mod, p1024_mp_mod); + ctx->state = 17; + break; + case 17: + sp_1024_mont_sqr_42(ctx->t5, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 18; + break; + case 18: + sp_1024_mont_mul_42(ctx->y, ctx->t1, ctx->t5, p1024_mod, p1024_mp_mod); + ctx->state = 19; + break; + case 19: + sp_1024_mont_mul_42(ctx->t5, ctx->t5, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 20; + break; + case 20: + sp_1024_mont_sub_42(ctx->x, ctx->x, ctx->t5, p1024_mod); + ctx->state = 21; + break; + case 21: + sp_1024_mont_dbl_42(ctx->t1, ctx->y, p1024_mod); + ctx->state = 22; + break; + case 22: + sp_1024_mont_sub_42(ctx->x, ctx->x, ctx->t1, p1024_mod); + ctx->state = 23; + break; + case 23: + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_1024_mont_sub_42(ctx->y, ctx->y, ctx->x, p1024_mod); + ctx->state = 24; + break; + case 24: + sp_1024_mont_mul_42(ctx->y, ctx->y, ctx->t4, p1024_mod, p1024_mp_mod); + ctx->state = 25; + break; + case 25: + sp_1024_mont_mul_42(ctx->t5, ctx->t5, ctx->t3, p1024_mod, p1024_mp_mod); + ctx->state = 26; + break; + case 26: + sp_1024_mont_sub_42(ctx->y, ctx->y, ctx->t5, p1024_mod); + ctx->state = 27; + /* fall-through */ + case 27: + err = MP_OKAY; + break; + } + + if (err == MP_OKAY && ctx->state != 27) { + err = FP_WOULDBLOCK; + } + return err; +} +#endif /* WOLFSSL_SP_NONBLOCK */ + +static void sp_1024_proj_point_add_42(sp_point_1024* r, + const sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*42; + sp_digit* t3 = t + 4*42; + sp_digit* t4 = t + 6*42; + sp_digit* t5 = t + 8*42; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Ensure only the first point is the same as the result. */ + if (q == r) { + const sp_point_1024* a = p; + p = q; + q = a; + } + + /* Check double */ + (void)sp_1024_mont_sub_42(t1, p1024_mod, q->y, p1024_mod); + sp_1024_norm_42(t1); + if ((sp_1024_cmp_equal_42(p->x, q->x) & sp_1024_cmp_equal_42(p->z, q->z) & + (sp_1024_cmp_equal_42(p->y, q->y) | sp_1024_cmp_equal_42(p->y, t1))) != 0) { + sp_1024_proj_point_dbl_42(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_1024)); + x = rp[p->infinity | q->infinity]->x; + y = rp[p->infinity | q->infinity]->y; + z = rp[p->infinity | q->infinity]->z; + + ap[0] = p; + ap[1] = q; + for (i=0; i<42; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<42; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<42; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U1 = X1*Z2^2 */ + sp_1024_mont_sqr_42(t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(t3, t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(t1, t1, x, p1024_mod, p1024_mp_mod); + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_42(t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(t4, t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(t2, t2, q->x, p1024_mod, p1024_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_1024_mont_mul_42(t3, t3, y, p1024_mod, p1024_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_42(t4, t4, q->y, p1024_mod, p1024_mp_mod); + /* H = U2 - U1 */ + sp_1024_mont_sub_42(t2, t2, t1, p1024_mod); + /* R = S2 - S1 */ + sp_1024_mont_sub_42(t4, t4, t3, p1024_mod); + /* Z3 = H*Z1*Z2 */ + sp_1024_mont_mul_42(z, z, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(z, z, t2, p1024_mod, p1024_mp_mod); + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_1024_mont_sqr_42(x, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_42(t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(y, t1, t5, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(t5, t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_42(x, x, t5, p1024_mod); + sp_1024_mont_dbl_42(t1, y, p1024_mod); + sp_1024_mont_sub_42(x, x, t1, p1024_mod); + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_1024_mont_sub_42(y, y, x, p1024_mod); + sp_1024_mont_mul_42(y, y, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(t5, t5, t3, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_42(y, y, t5, p1024_mod); + } +} + +#ifdef WOLFSSL_SP_SMALL +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Small implementation using add and double that is cache attack resistant but + * allocates memory rather than use large stacks. + * 1024 adds and doubles. + * + * r Resulting point. + * g Point to multiply. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ + +#ifdef WOLFSSL_SP_NONBLOCK +typedef struct sp_1024_ecc_mulmod_42_ctx { + int state; + union { + sp_1024_proj_point_dbl_42_ctx dbl_ctx; + sp_1024_proj_point_add_42_ctx add_ctx; + }; + sp_point_1024 t[3]; + sp_digit tmp[2 * 42 * 5]; + sp_digit n; + int i; + int c; + int y; +} sp_1024_ecc_mulmod_42_ctx; + +static int sp_1024_ecc_mulmod_42_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r, + const sp_point_1024* g, const sp_digit* k, int map, int ct, void* heap) +{ + int err = FP_WOULDBLOCK; + sp_1024_ecc_mulmod_42_ctx* ctx = (sp_1024_ecc_mulmod_42_ctx*)sp_ctx->data; + + typedef char ctx_size_test[sizeof(sp_1024_ecc_mulmod_42_ctx) >= sizeof(*sp_ctx) ? -1 : 1]; + (void)sizeof(ctx_size_test); + + /* Implementation is constant time. */ + (void)ct; + + switch (ctx->state) { + case 0: /* INIT */ + XMEMSET(ctx->t, 0, sizeof(sp_point_1024) * 3); + ctx->i = 40; + ctx->c = 24; + ctx->n = k[ctx->i--] << (25 - ctx->c); + + /* t[0] = {0, 0, 1} * norm */ + ctx->t[0].infinity = 1; + ctx->state = 1; + break; + case 1: /* T1X */ + /* t[1] = {g->x, g->y, g->z} * norm */ + err = sp_1024_mod_mul_norm_42(ctx->t[1].x, g->x, p1024_mod); + ctx->state = 2; + break; + case 2: /* T1Y */ + err = sp_1024_mod_mul_norm_42(ctx->t[1].y, g->y, p1024_mod); + ctx->state = 3; + break; + case 3: /* T1Z */ + err = sp_1024_mod_mul_norm_42(ctx->t[1].z, g->z, p1024_mod); + ctx->state = 4; + break; + case 4: /* ADDPREP */ + if (ctx->c == 0) { + if (ctx->i == -1) { + ctx->state = 7; + break; + } + + ctx->n = k[ctx->i--]; + ctx->c = 25; + } + ctx->y = (ctx->n >> 24) & 1; + ctx->n <<= 1; + XMEMSET(&ctx->add_ctx, 0, sizeof(ctx->add_ctx)); + ctx->state = 5; + break; + case 5: /* ADD */ + err = sp_1024_proj_point_add_42_nb((sp_ecc_ctx_t*)&ctx->add_ctx, + &ctx->t[ctx->y^1], &ctx->t[0], &ctx->t[1], ctx->tmp); + if (err == MP_OKAY) { + XMEMCPY(&ctx->t[2], (void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) + + ((size_t)&ctx->t[1] & addr_mask[ctx->y])), + sizeof(sp_point_1024)); + XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx)); + ctx->state = 6; + } + break; + case 6: /* DBL */ + err = sp_1024_proj_point_dbl_42_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, &ctx->t[2], + &ctx->t[2], ctx->tmp); + if (err == MP_OKAY) { + XMEMCPY((void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) + + ((size_t)&ctx->t[1] & addr_mask[ctx->y])), &ctx->t[2], + sizeof(sp_point_1024)); + ctx->state = 4; + ctx->c--; + } + break; + case 7: /* MAP */ + if (map != 0) { + sp_1024_map_42(r, &ctx->t[0], ctx->tmp); + } + else { + XMEMCPY(r, &ctx->t[0], sizeof(sp_point_1024)); + } + err = MP_OKAY; + break; + } + + if (err == MP_OKAY && ctx->state != 7) { + err = FP_WOULDBLOCK; + } + if (err != FP_WOULDBLOCK) { + ForceZero(ctx->tmp, sizeof(ctx->tmp)); + ForceZero(ctx->t, sizeof(ctx->t)); + } + + (void)heap; + + return err; +} + +#endif /* WOLFSSL_SP_NONBLOCK */ + +static int sp_1024_ecc_mulmod_42(sp_point_1024* r, const sp_point_1024* g, + const sp_digit* k, int map, int ct, void* heap) +{ +#ifdef WOLFSSL_SP_NO_MALLOC + sp_point_1024 t[3]; + sp_digit tmp[2 * 42 * 5]; +#else + sp_point_1024* t; + sp_digit* tmp; +#endif + sp_digit n; + int i; + int c; + int y; + int err = MP_OKAY; + + /* Implementatio is constant time. */ + (void)ct; + (void)heap; + +#ifndef WOLFSSL_SP_NO_MALLOC + t = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) * 3, heap, DYNAMIC_TYPE_ECC); + if (t == NULL) + err = MEMORY_E; + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 42 * 5, heap, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) + err = MEMORY_E; +#endif + + if (err == MP_OKAY) { + XMEMSET(t, 0, sizeof(sp_point_1024) * 3); + + /* t[0] = {0, 0, 1} * norm */ + t[0].infinity = 1; + /* t[1] = {g->x, g->y, g->z} * norm */ + err = sp_1024_mod_mul_norm_42(t[1].x, g->x, p1024_mod); + } + if (err == MP_OKAY) + err = sp_1024_mod_mul_norm_42(t[1].y, g->y, p1024_mod); + if (err == MP_OKAY) + err = sp_1024_mod_mul_norm_42(t[1].z, g->z, p1024_mod); + + if (err == MP_OKAY) { + i = 40; + c = 24; + n = k[i--] << (25 - c); + for (; ; c--) { + if (c == 0) { + if (i == -1) + break; + + n = k[i--]; + c = 25; + } + + y = (n >> 24) & 1; + n <<= 1; + + sp_1024_proj_point_add_42(&t[y^1], &t[0], &t[1], tmp); + + XMEMCPY(&t[2], (void*)(((size_t)&t[0] & addr_mask[y^1]) + + ((size_t)&t[1] & addr_mask[y])), + sizeof(sp_point_1024)); + sp_1024_proj_point_dbl_42(&t[2], &t[2], tmp); + XMEMCPY((void*)(((size_t)&t[0] & addr_mask[y^1]) + + ((size_t)&t[1] & addr_mask[y])), &t[2], + sizeof(sp_point_1024)); + } + + if (map != 0) { + sp_1024_map_42(r, &t[0], tmp); + } + else { + XMEMCPY(r, &t[0], sizeof(sp_point_1024)); + } + } + +#ifndef WOLFSSL_SP_NO_MALLOC + if (tmp != NULL) { + XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 42 * 5); + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } + if (t != NULL) { + XMEMSET(t, 0, sizeof(sp_point_1024) * 3); + XFREE(t, NULL, DYNAMIC_TYPE_ECC); + } +#else + ForceZero(tmp, sizeof(tmp)); + ForceZero(t, sizeof(t)); +#endif + + return err; +} + +#else +/* A table entry for pre-computed points. */ +typedef struct sp_table_entry_1024 { + sp_digit x[42]; + sp_digit y[42]; +} sp_table_entry_1024; + +/* Conditionally copy a into r using the mask m. + * m is -1 to copy and 0 when not. + * + * r A single precision number to copy over. + * a A single precision number to copy. + * m Mask value to apply. + */ +static void sp_1024_cond_copy_42(sp_digit* r, const sp_digit* a, const sp_digit m) +{ + sp_digit t[42]; +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i = 0; i < 42; i++) { + t[i] = r[i] ^ a[i]; + } + for (i = 0; i < 42; i++) { + r[i] ^= t[i] & m; + } +#else + t[ 0] = r[ 0] ^ a[ 0]; + t[ 1] = r[ 1] ^ a[ 1]; + t[ 2] = r[ 2] ^ a[ 2]; + t[ 3] = r[ 3] ^ a[ 3]; + t[ 4] = r[ 4] ^ a[ 4]; + t[ 5] = r[ 5] ^ a[ 5]; + t[ 6] = r[ 6] ^ a[ 6]; + t[ 7] = r[ 7] ^ a[ 7]; + t[ 8] = r[ 8] ^ a[ 8]; + t[ 9] = r[ 9] ^ a[ 9]; + t[10] = r[10] ^ a[10]; + t[11] = r[11] ^ a[11]; + t[12] = r[12] ^ a[12]; + t[13] = r[13] ^ a[13]; + t[14] = r[14] ^ a[14]; + t[15] = r[15] ^ a[15]; + t[16] = r[16] ^ a[16]; + t[17] = r[17] ^ a[17]; + t[18] = r[18] ^ a[18]; + t[19] = r[19] ^ a[19]; + t[20] = r[20] ^ a[20]; + t[21] = r[21] ^ a[21]; + t[22] = r[22] ^ a[22]; + t[23] = r[23] ^ a[23]; + t[24] = r[24] ^ a[24]; + t[25] = r[25] ^ a[25]; + t[26] = r[26] ^ a[26]; + t[27] = r[27] ^ a[27]; + t[28] = r[28] ^ a[28]; + t[29] = r[29] ^ a[29]; + t[30] = r[30] ^ a[30]; + t[31] = r[31] ^ a[31]; + t[32] = r[32] ^ a[32]; + t[33] = r[33] ^ a[33]; + t[34] = r[34] ^ a[34]; + t[35] = r[35] ^ a[35]; + t[36] = r[36] ^ a[36]; + t[37] = r[37] ^ a[37]; + t[38] = r[38] ^ a[38]; + t[39] = r[39] ^ a[39]; + t[40] = r[40] ^ a[40]; + t[41] = r[41] ^ a[41]; + r[ 0] ^= t[ 0] & m; + r[ 1] ^= t[ 1] & m; + r[ 2] ^= t[ 2] & m; + r[ 3] ^= t[ 3] & m; + r[ 4] ^= t[ 4] & m; + r[ 5] ^= t[ 5] & m; + r[ 6] ^= t[ 6] & m; + r[ 7] ^= t[ 7] & m; + r[ 8] ^= t[ 8] & m; + r[ 9] ^= t[ 9] & m; + r[10] ^= t[10] & m; + r[11] ^= t[11] & m; + r[12] ^= t[12] & m; + r[13] ^= t[13] & m; + r[14] ^= t[14] & m; + r[15] ^= t[15] & m; + r[16] ^= t[16] & m; + r[17] ^= t[17] & m; + r[18] ^= t[18] & m; + r[19] ^= t[19] & m; + r[20] ^= t[20] & m; + r[21] ^= t[21] & m; + r[22] ^= t[22] & m; + r[23] ^= t[23] & m; + r[24] ^= t[24] & m; + r[25] ^= t[25] & m; + r[26] ^= t[26] & m; + r[27] ^= t[27] & m; + r[28] ^= t[28] & m; + r[29] ^= t[29] & m; + r[30] ^= t[30] & m; + r[31] ^= t[31] & m; + r[32] ^= t[32] & m; + r[33] ^= t[33] & m; + r[34] ^= t[34] & m; + r[35] ^= t[35] & m; + r[36] ^= t[36] & m; + r[37] ^= t[37] & m; + r[38] ^= t[38] & m; + r[39] ^= t[39] & m; + r[40] ^= t[40] & m; + r[41] ^= t[41] & m; +#endif /* WOLFSSL_SP_SMALL */ +} + +/* Double the Montgomery form projective point p a number of times. + * + * r Result of repeated doubling of point. + * p Point to double. + * n Number of times to double + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_dbl_n_42(sp_point_1024* p, int n, + sp_digit* t) +{ + sp_digit* w = t; + sp_digit* a = t + 2*42; + sp_digit* b = t + 4*42; + sp_digit* t1 = t + 6*42; + sp_digit* t2 = t + 8*42; + sp_digit* x; + sp_digit* y; + sp_digit* z; + + x = p->x; + y = p->y; + z = p->z; + + /* Y = 2*Y */ + sp_1024_mont_dbl_42(y, y, p1024_mod); + /* W = Z^4 */ + sp_1024_mont_sqr_42(w, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_42(w, w, p1024_mod, p1024_mp_mod); + +#ifndef WOLFSSL_SP_SMALL + while (--n > 0) +#else + while (--n >= 0) +#endif + { + /* A = 3*(X^2 - W) */ + sp_1024_mont_sqr_42(t1, x, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_42(t1, t1, w, p1024_mod); + sp_1024_mont_tpl_42(a, t1, p1024_mod); + /* B = X*Y^2 */ + sp_1024_mont_sqr_42(t1, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(b, t1, x, p1024_mod, p1024_mp_mod); + /* X = A^2 - 2B */ + sp_1024_mont_sqr_42(x, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_42(t2, b, p1024_mod); + sp_1024_mont_sub_42(x, x, t2, p1024_mod); + /* Z = Z*Y */ + sp_1024_mont_mul_42(z, z, y, p1024_mod, p1024_mp_mod); + /* t2 = Y^4 */ + sp_1024_mont_sqr_42(t1, t1, p1024_mod, p1024_mp_mod); +#ifdef WOLFSSL_SP_SMALL + if (n != 0) +#endif + { + /* W = W*Y^4 */ + sp_1024_mont_mul_42(w, w, t1, p1024_mod, p1024_mp_mod); + } + /* y = 2*A*(B - X) - Y^4 */ + sp_1024_mont_sub_42(y, b, x, p1024_mod); + sp_1024_mont_mul_42(y, y, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_42(y, y, p1024_mod); + sp_1024_mont_sub_42(y, y, t1, p1024_mod); + } +#ifndef WOLFSSL_SP_SMALL + /* A = 3*(X^2 - W) */ + sp_1024_mont_sqr_42(t1, x, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_42(t1, t1, w, p1024_mod); + sp_1024_mont_tpl_42(a, t1, p1024_mod); + /* B = X*Y^2 */ + sp_1024_mont_sqr_42(t1, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(b, t1, x, p1024_mod, p1024_mp_mod); + /* X = A^2 - 2B */ + sp_1024_mont_sqr_42(x, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_42(t2, b, p1024_mod); + sp_1024_mont_sub_42(x, x, t2, p1024_mod); + /* Z = Z*Y */ + sp_1024_mont_mul_42(z, z, y, p1024_mod, p1024_mp_mod); + /* t2 = Y^4 */ + sp_1024_mont_sqr_42(t1, t1, p1024_mod, p1024_mp_mod); + /* y = 2*A*(B - X) - Y^4 */ + sp_1024_mont_sub_42(y, b, x, p1024_mod); + sp_1024_mont_mul_42(y, y, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_42(y, y, p1024_mod); + sp_1024_mont_sub_42(y, y, t1, p1024_mod); +#endif + /* Y = Y/2 */ + sp_1024_div2_42(y, y, p1024_mod); +} + +/* Double the Montgomery form projective point p a number of times. + * + * r Result of repeated doubling of point. + * p Point to double. + * n Number of times to double + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_dbl_n_store_42(sp_point_1024* r, + const sp_point_1024* p, int n, int m, sp_digit* t) +{ + sp_digit* w = t; + sp_digit* a = t + 2*42; + sp_digit* b = t + 4*42; + sp_digit* t1 = t + 6*42; + sp_digit* t2 = t + 8*42; + sp_digit* x = r[2*m].x; + sp_digit* y = r[(1<x[i]; + } + for (i=0; i<42; i++) { + y[i] = p->y[i]; + } + for (i=0; i<42; i++) { + z[i] = p->z[i]; + } + + /* Y = 2*Y */ + sp_1024_mont_dbl_42(y, y, p1024_mod); + /* W = Z^4 */ + sp_1024_mont_sqr_42(w, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_42(w, w, p1024_mod, p1024_mp_mod); + j = m; + for (i=1; i<=n; i++) { + j *= 2; + + /* A = 3*(X^2 - W) */ + sp_1024_mont_sqr_42(t1, x, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_42(t1, t1, w, p1024_mod); + sp_1024_mont_tpl_42(a, t1, p1024_mod); + /* B = X*Y^2 */ + sp_1024_mont_sqr_42(t2, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(b, t2, x, p1024_mod, p1024_mp_mod); + x = r[j].x; + /* X = A^2 - 2B */ + sp_1024_mont_sqr_42(x, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_42(t1, b, p1024_mod); + sp_1024_mont_sub_42(x, x, t1, p1024_mod); + /* Z = Z*Y */ + sp_1024_mont_mul_42(r[j].z, z, y, p1024_mod, p1024_mp_mod); + z = r[j].z; + /* t2 = Y^4 */ + sp_1024_mont_sqr_42(t2, t2, p1024_mod, p1024_mp_mod); + if (i != n) { + /* W = W*Y^4 */ + sp_1024_mont_mul_42(w, w, t2, p1024_mod, p1024_mp_mod); + } + /* y = 2*A*(B - X) - Y^4 */ + sp_1024_mont_sub_42(y, b, x, p1024_mod); + sp_1024_mont_mul_42(y, y, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_42(y, y, p1024_mod); + sp_1024_mont_sub_42(y, y, t2, p1024_mod); + + /* Y = Y/2 */ + sp_1024_div2_42(r[j].y, y, p1024_mod); + r[j].infinity = 0; + } +} + +/* Add two Montgomery form projective points. + * + * ra Result of addition. + * rs Result of subtraction. + * p First point to add. + * q Second point to add. + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_add_sub_42(sp_point_1024* ra, + sp_point_1024* rs, const sp_point_1024* p, const sp_point_1024* q, + sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*42; + sp_digit* t3 = t + 4*42; + sp_digit* t4 = t + 6*42; + sp_digit* t5 = t + 8*42; + sp_digit* t6 = t + 10*42; + sp_digit* x = ra->x; + sp_digit* y = ra->y; + sp_digit* z = ra->z; + sp_digit* xs = rs->x; + sp_digit* ys = rs->y; + sp_digit* zs = rs->z; + + + XMEMCPY(x, p->x, sizeof(p->x) / 2); + XMEMCPY(y, p->y, sizeof(p->y) / 2); + XMEMCPY(z, p->z, sizeof(p->z) / 2); + ra->infinity = 0; + rs->infinity = 0; + + /* U1 = X1*Z2^2 */ + sp_1024_mont_sqr_42(t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(t3, t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(t1, t1, x, p1024_mod, p1024_mp_mod); + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_42(t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(t4, t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(t2, t2, q->x, p1024_mod, p1024_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_1024_mont_mul_42(t3, t3, y, p1024_mod, p1024_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_42(t4, t4, q->y, p1024_mod, p1024_mp_mod); + /* H = U2 - U1 */ + sp_1024_mont_sub_42(t2, t2, t1, p1024_mod); + /* RS = S2 + S1 */ + sp_1024_mont_add_42(t6, t4, t3, p1024_mod); + /* R = S2 - S1 */ + sp_1024_mont_sub_42(t4, t4, t3, p1024_mod); + /* Z3 = H*Z1*Z2 */ + /* ZS = H*Z1*Z2 */ + sp_1024_mont_mul_42(z, z, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(z, z, t2, p1024_mod, p1024_mp_mod); + XMEMCPY(zs, z, sizeof(p->z)/2); + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + /* XS = RS^2 - H^3 - 2*U1*H^2 */ + sp_1024_mont_sqr_42(x, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_42(xs, t6, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_42(t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(y, t1, t5, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(t5, t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_42(x, x, t5, p1024_mod); + sp_1024_mont_sub_42(xs, xs, t5, p1024_mod); + sp_1024_mont_dbl_42(t1, y, p1024_mod); + sp_1024_mont_sub_42(x, x, t1, p1024_mod); + sp_1024_mont_sub_42(xs, xs, t1, p1024_mod); + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + /* YS = -RS*(U1*H^2 - XS) - S1*H^3 */ + sp_1024_mont_sub_42(ys, y, xs, p1024_mod); + sp_1024_mont_sub_42(y, y, x, p1024_mod); + sp_1024_mont_mul_42(y, y, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_42(t6, p1024_mod, t6, p1024_mod); + sp_1024_mont_mul_42(ys, ys, t6, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(t5, t5, t3, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_42(y, y, t5, p1024_mod); + sp_1024_mont_sub_42(ys, ys, t5, p1024_mod); +} + +/* Structure used to describe recoding of scalar multiplication. */ +typedef struct ecc_recode_1024 { + /* Index into pre-computation table. */ + uint8_t i; + /* Use the negative of the point. */ + uint8_t neg; +} ecc_recode_1024; + +/* The index into pre-computation table to use. */ +static const uint8_t recode_index_42_7[130] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, + 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, + 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, + 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, + 0, 1, +}; + +/* Whether to negate y-ordinate. */ +static const uint8_t recode_neg_42_7[130] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, +}; + +/* Recode the scalar for multiplication using pre-computed values and + * subtraction. + * + * k Scalar to multiply by. + * v Vector of operations to perform. + */ +static void sp_1024_ecc_recode_7_42(const sp_digit* k, ecc_recode_1024* v) +{ + int i; + int j; + uint8_t y; + int carry = 0; + int o; + sp_digit n; + + j = 0; + n = k[j]; + o = 0; + for (i=0; i<147; i++) { + y = (int8_t)n; + if (o + 7 < 25) { + y &= 0x7f; + n >>= 7; + o += 7; + } + else if (o + 7 == 25) { + n >>= 7; + if (++j < 42) + n = k[j]; + o = 0; + } + else if (++j < 42) { + n = k[j]; + y |= (uint8_t)((n << (25 - o)) & 0x7f); + o -= 18; + n >>= o; + } + + y += (uint8_t)carry; + v[i].i = recode_index_42_7[y]; + v[i].neg = recode_neg_42_7[y]; + carry = (y >> 7) + v[i].neg; + } +} + +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Window technique of 7 bits. (Add-Sub variation.) + * Calculate 0..64 times the point. Use function that adds and + * subtracts the same two points. + * Recode to add or subtract one of the computed points. + * Double to push up. + * NOT a sliding window. + * + * r Resulting point. + * g Point to multiply. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_win_add_sub_42(sp_point_1024* r, const sp_point_1024* g, + const sp_digit* k, int map, int ct, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 td[65]; + sp_point_1024 rtd; + sp_point_1024 pd; + sp_digit tmpd[2 * 42 * 6]; +#endif + sp_point_1024* t; + sp_point_1024* rt; + sp_point_1024* p = NULL; + sp_digit* tmp; + sp_digit* negy; + int i; + ecc_recode_1024 v[147]; + int err; + + /* Constant time used for cache attack resistance implementation. */ + (void)ct; + (void)heap; + + err = sp_1024_point_new_42(heap, rtd, rt); + if (err == MP_OKAY) + err = sp_1024_point_new_42(heap, pd, p); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) * 65, heap, DYNAMIC_TYPE_ECC); + if (t == NULL) + err = MEMORY_E; + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 42 * 6, heap, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) + err = MEMORY_E; +#else + t = td; + tmp = tmpd; +#endif + + + if (err == MP_OKAY) { + /* t[0] = {0, 0, 1} * norm */ + XMEMSET(&t[0], 0, sizeof(t[0])); + t[0].infinity = 1; + /* t[1] = {g->x, g->y, g->z} * norm */ + err = sp_1024_mod_mul_norm_42(t[1].x, g->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_42(t[1].y, g->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_42(t[1].z, g->z, p1024_mod); + } + + if (err == MP_OKAY) { + t[1].infinity = 0; + /* t[2] ... t[64] */ + sp_1024_proj_point_dbl_n_store_42(t, &t[ 1], 6, 1, tmp); + sp_1024_proj_point_add_42(&t[ 3], &t[ 2], &t[ 1], tmp); + sp_1024_proj_point_dbl_42(&t[ 6], &t[ 3], tmp); + sp_1024_proj_point_add_sub_42(&t[ 7], &t[ 5], &t[ 6], &t[ 1], tmp); + sp_1024_proj_point_dbl_42(&t[10], &t[ 5], tmp); + sp_1024_proj_point_add_sub_42(&t[11], &t[ 9], &t[10], &t[ 1], tmp); + sp_1024_proj_point_dbl_42(&t[12], &t[ 6], tmp); + sp_1024_proj_point_dbl_42(&t[14], &t[ 7], tmp); + sp_1024_proj_point_add_sub_42(&t[15], &t[13], &t[14], &t[ 1], tmp); + sp_1024_proj_point_dbl_42(&t[18], &t[ 9], tmp); + sp_1024_proj_point_add_sub_42(&t[19], &t[17], &t[18], &t[ 1], tmp); + sp_1024_proj_point_dbl_42(&t[20], &t[10], tmp); + sp_1024_proj_point_dbl_42(&t[22], &t[11], tmp); + sp_1024_proj_point_add_sub_42(&t[23], &t[21], &t[22], &t[ 1], tmp); + sp_1024_proj_point_dbl_42(&t[24], &t[12], tmp); + sp_1024_proj_point_dbl_42(&t[26], &t[13], tmp); + sp_1024_proj_point_add_sub_42(&t[27], &t[25], &t[26], &t[ 1], tmp); + sp_1024_proj_point_dbl_42(&t[28], &t[14], tmp); + sp_1024_proj_point_dbl_42(&t[30], &t[15], tmp); + sp_1024_proj_point_add_sub_42(&t[31], &t[29], &t[30], &t[ 1], tmp); + sp_1024_proj_point_dbl_42(&t[34], &t[17], tmp); + sp_1024_proj_point_add_sub_42(&t[35], &t[33], &t[34], &t[ 1], tmp); + sp_1024_proj_point_dbl_42(&t[36], &t[18], tmp); + sp_1024_proj_point_dbl_42(&t[38], &t[19], tmp); + sp_1024_proj_point_add_sub_42(&t[39], &t[37], &t[38], &t[ 1], tmp); + sp_1024_proj_point_dbl_42(&t[40], &t[20], tmp); + sp_1024_proj_point_dbl_42(&t[42], &t[21], tmp); + sp_1024_proj_point_add_sub_42(&t[43], &t[41], &t[42], &t[ 1], tmp); + sp_1024_proj_point_dbl_42(&t[44], &t[22], tmp); + sp_1024_proj_point_dbl_42(&t[46], &t[23], tmp); + sp_1024_proj_point_add_sub_42(&t[47], &t[45], &t[46], &t[ 1], tmp); + sp_1024_proj_point_dbl_42(&t[48], &t[24], tmp); + sp_1024_proj_point_dbl_42(&t[50], &t[25], tmp); + sp_1024_proj_point_add_sub_42(&t[51], &t[49], &t[50], &t[ 1], tmp); + sp_1024_proj_point_dbl_42(&t[52], &t[26], tmp); + sp_1024_proj_point_dbl_42(&t[54], &t[27], tmp); + sp_1024_proj_point_add_sub_42(&t[55], &t[53], &t[54], &t[ 1], tmp); + sp_1024_proj_point_dbl_42(&t[56], &t[28], tmp); + sp_1024_proj_point_dbl_42(&t[58], &t[29], tmp); + sp_1024_proj_point_add_sub_42(&t[59], &t[57], &t[58], &t[ 1], tmp); + sp_1024_proj_point_dbl_42(&t[60], &t[30], tmp); + sp_1024_proj_point_dbl_42(&t[62], &t[31], tmp); + sp_1024_proj_point_add_sub_42(&t[63], &t[61], &t[62], &t[ 1], tmp); + + negy = t[0].y; + + sp_1024_ecc_recode_7_42(k, v); + + i = 146; + XMEMCPY(rt, &t[v[i].i], sizeof(sp_point_1024)); + for (--i; i>=0; i--) { + sp_1024_proj_point_dbl_n_42(rt, 7, tmp); + XMEMCPY(p, &t[v[i].i], sizeof(sp_point_1024)); + sp_1024_mont_sub_42(negy, p1024_mod, p->y, p1024_mod); + sp_1024_norm_42(negy); + sp_1024_cond_copy_42(p->y, negy, (sp_digit)0 - v[i].neg); + sp_1024_proj_point_add_42(rt, rt, p, tmp); + } + + if (map != 0) { + sp_1024_map_42(r, rt, tmp); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_1024)); + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (t != NULL) + XFREE(t, heap, DYNAMIC_TYPE_ECC); + if (tmp != NULL) + XFREE(tmp, heap, DYNAMIC_TYPE_ECC); +#endif + sp_1024_point_free_42(p, 0, heap); + sp_1024_point_free_42(rt, 0, heap); + + return err; +} + +#ifdef FP_ECC +#endif /* FP_ECC */ +/* Add two Montgomery form projective points. The second point has a q value of + * one. + * Only the first point can be the same pointer as the result point. + * + * r Result of addition. + * p First point to add. + * q Second point to add. + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_add_qz1_42(sp_point_1024* r, const sp_point_1024* p, + const sp_point_1024* q, sp_digit* t) +{ + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*42; + sp_digit* t3 = t + 4*42; + sp_digit* t4 = t + 6*42; + sp_digit* t5 = t + 8*42; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Check double */ + (void)sp_1024_mont_sub_42(t1, p1024_mod, q->y, p1024_mod); + sp_1024_norm_42(t1); + if ((sp_1024_cmp_equal_42(p->x, q->x) & sp_1024_cmp_equal_42(p->z, q->z) & + (sp_1024_cmp_equal_42(p->y, q->y) | sp_1024_cmp_equal_42(p->y, t1))) != 0) { + sp_1024_proj_point_dbl_42(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_1024)); + x = rp[p->infinity | q->infinity]->x; + y = rp[p->infinity | q->infinity]->y; + z = rp[p->infinity | q->infinity]->z; + + ap[0] = p; + ap[1] = q; + for (i=0; i<42; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<42; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<42; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_42(t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(t4, t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(t2, t2, q->x, p1024_mod, p1024_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_42(t4, t4, q->y, p1024_mod, p1024_mp_mod); + /* H = U2 - X1 */ + sp_1024_mont_sub_42(t2, t2, x, p1024_mod); + /* R = S2 - Y1 */ + sp_1024_mont_sub_42(t4, t4, y, p1024_mod); + /* Z3 = H*Z1 */ + sp_1024_mont_mul_42(z, z, t2, p1024_mod, p1024_mp_mod); + /* X3 = R^2 - H^3 - 2*X1*H^2 */ + sp_1024_mont_sqr_42(t1, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_42(t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(t3, x, t5, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(t5, t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_42(x, t1, t5, p1024_mod); + sp_1024_mont_dbl_42(t1, t3, p1024_mod); + sp_1024_mont_sub_42(x, x, t1, p1024_mod); + /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */ + sp_1024_mont_sub_42(t3, t3, x, p1024_mod); + sp_1024_mont_mul_42(t3, t3, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(t5, t5, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_42(y, t3, t5, p1024_mod); + } +} + +#if defined(FP_ECC) || !defined(WOLFSSL_SP_SMALL) +/* Convert the projective point to affine. + * Ordinates are in Montgomery form. + * + * a Point to convert. + * t Temporary data. + */ +static void sp_1024_proj_to_affine_42(sp_point_1024* a, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 42; + sp_digit* tmp = t + 4 * 42; + + sp_1024_mont_inv_42(t1, a->z, tmp); + + sp_1024_mont_sqr_42(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(t1, t2, t1, p1024_mod, p1024_mp_mod); + + sp_1024_mont_mul_42(a->x, a->x, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(a->y, a->y, t1, p1024_mod, p1024_mp_mod); + XMEMCPY(a->z, p1024_norm_mod, sizeof(p1024_norm_mod)); +} + +/* Generate the pre-computed table of points for the base point. + * + * width = 8 + * 256 entries + * 128 bits between + * + * a The base point. + * table Place to store generated point data. + * tmp Temporary data. + * heap Heap to use for allocation. + */ +static int sp_1024_gen_stripe_table_42(const sp_point_1024* a, + sp_table_entry_1024* table, sp_digit* tmp, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 td; + sp_point_1024 s1d; + sp_point_1024 s2d; +#endif + sp_point_1024* t; + sp_point_1024* s1 = NULL; + sp_point_1024* s2 = NULL; + int i; + int j; + int err; + + (void)heap; + + err = sp_1024_point_new_42(heap, td, t); + if (err == MP_OKAY) { + err = sp_1024_point_new_42(heap, s1d, s1); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_42(heap, s2d, s2); + } + + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_42(t->x, a->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_42(t->y, a->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_42(t->z, a->z, p1024_mod); + } + if (err == MP_OKAY) { + t->infinity = 0; + sp_1024_proj_to_affine_42(t, tmp); + + XMEMCPY(s1->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + s1->infinity = 0; + XMEMCPY(s2->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + s2->infinity = 0; + + /* table[0] = {0, 0, infinity} */ + XMEMSET(&table[0], 0, sizeof(sp_table_entry_1024)); + /* table[1] = Affine version of 'a' in Montgomery form */ + XMEMCPY(table[1].x, t->x, sizeof(table->x)); + XMEMCPY(table[1].y, t->y, sizeof(table->y)); + + for (i=1; i<8; i++) { + sp_1024_proj_point_dbl_n_42(t, 128, tmp); + sp_1024_proj_to_affine_42(t, tmp); + XMEMCPY(table[1<x, sizeof(table->x)); + XMEMCPY(table[1<y, sizeof(table->y)); + } + + for (i=1; i<8; i++) { + XMEMCPY(s1->x, table[1<x)); + XMEMCPY(s1->y, table[1<y)); + for (j=(1<x, table[j-(1<x)); + XMEMCPY(s2->y, table[j-(1<y)); + sp_1024_proj_point_add_qz1_42(t, s1, s2, tmp); + sp_1024_proj_to_affine_42(t, tmp); + XMEMCPY(table[j].x, t->x, sizeof(table->x)); + XMEMCPY(table[j].y, t->y, sizeof(table->y)); + } + } + } + + sp_1024_point_free_42(s2, 0, heap); + sp_1024_point_free_42(s1, 0, heap); + sp_1024_point_free_42( t, 0, heap); + + return err; +} + +#endif /* FP_ECC | !WOLFSSL_SP_SMALL */ +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^128, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * table Pre-computed table. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_stripe_42(sp_point_1024* r, const sp_point_1024* g, + const sp_table_entry_1024* table, const sp_digit* k, int map, + int ct, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 rtd; + sp_point_1024 pd; + sp_digit td[2 * 42 * 5]; +#endif + sp_point_1024* rt; + sp_point_1024* p = NULL; + sp_digit* t; + int i; + int j; + int y; + int x; + int err; + + (void)g; + /* Constant time used for cache attack resistance implementation. */ + (void)ct; + (void)heap; + + + err = sp_1024_point_new_42(heap, rtd, rt); + if (err == MP_OKAY) { + err = sp_1024_point_new_42(heap, pd, p); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 42 * 5, heap, + DYNAMIC_TYPE_ECC); + if (t == NULL) { + err = MEMORY_E; + } +#else + t = td; +#endif + + if (err == MP_OKAY) { + XMEMCPY(p->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + XMEMCPY(rt->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + + y = 0; + x = 127; + for (j=0; j<8; j++) { + y |= (int)(((k[x / 25] >> (x % 25)) & 1) << j); + x += 128; + } + XMEMCPY(rt->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(rt->y, table[y].y, sizeof(table[y].y)); + rt->infinity = !y; + for (i=126; i>=0; i--) { + y = 0; + x = i; + for (j=0; j<8; j++) { + y |= (int)(((k[x / 25] >> (x % 25)) & 1) << j); + x += 128; + } + + sp_1024_proj_point_dbl_42(rt, rt, t); + XMEMCPY(p->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(p->y, table[y].y, sizeof(table[y].y)); + p->infinity = !y; + sp_1024_proj_point_add_qz1_42(rt, rt, p, t); + } + + if (map != 0) { + sp_1024_map_42(r, rt, t); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_1024)); + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (t != NULL) { + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_42(p, 0, heap); + sp_1024_point_free_42(rt, 0, heap); + + return err; +} + +#ifdef FP_ECC +#ifndef FP_ENTRIES + #define FP_ENTRIES 16 +#endif + +/* Cache entry - holds precomputation tables for a point. */ +typedef struct sp_cache_1024_t { + /* X ordinate of point that table was generated from. */ + sp_digit x[42]; + /* Y ordinate of point that table was generated from. */ + sp_digit y[42]; + /* Precomputation table for point. */ + sp_table_entry_1024 table[256]; + /* Count of entries in table. */ + uint32_t cnt; + /* Point and table set in entry. */ + int set; +} sp_cache_1024_t; + +/* Cache of tables. */ +static THREAD_LS_T sp_cache_1024_t sp_cache_1024[FP_ENTRIES]; +/* Index of last entry in cache. */ +static THREAD_LS_T int sp_cache_1024_last = -1; +/* Cache has been initialized. */ +static THREAD_LS_T int sp_cache_1024_inited = 0; + +#ifndef HAVE_THREAD_LS + static volatile int initCacheMutex_1024 = 0; + static wolfSSL_Mutex sp_cache_1024_lock; +#endif + +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ +static void sp_ecc_get_cache_1024(const sp_point_1024* g, sp_cache_1024_t** cache) +{ + int i; + int j; + uint32_t least; + + if (sp_cache_1024_inited == 0) { + for (i=0; ix, sp_cache_1024[i].x) & + sp_1024_cmp_equal_42(g->y, sp_cache_1024[i].y)) { + sp_cache_1024[i].cnt++; + break; + } + } + + /* No match. */ + if (i == FP_ENTRIES) { + /* Find empty entry. */ + i = (sp_cache_1024_last + 1) % FP_ENTRIES; + for (; i != sp_cache_1024_last; i=(i+1)%FP_ENTRIES) { + if (!sp_cache_1024[i].set) { + break; + } + } + + /* Evict least used. */ + if (i == sp_cache_1024_last) { + least = sp_cache_1024[0].cnt; + for (j=1; jx, sizeof(sp_cache_1024[i].x)); + XMEMCPY(sp_cache_1024[i].y, g->y, sizeof(sp_cache_1024[i].y)); + sp_cache_1024[i].set = 1; + sp_cache_1024[i].cnt = 1; + } + + *cache = &sp_cache_1024[i]; + sp_cache_1024_last = i; +} +#endif /* FP_ECC */ + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * r Resulting point. + * g Point to multiply. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_42(sp_point_1024* r, const sp_point_1024* g, const sp_digit* k, + int map, int ct, void* heap) +{ +#ifndef FP_ECC + return sp_1024_ecc_mulmod_win_add_sub_42(r, g, k, map, ct, heap); +#else + sp_digit tmp[2 * 42 * 5]; + sp_cache_1024_t* cache; + int err = MP_OKAY; + +#ifndef HAVE_THREAD_LS + if (initCacheMutex_1024 == 0) { + wc_InitMutex(&sp_cache_1024_lock); + initCacheMutex_1024 = 1; + } + if (wc_LockMutex(&sp_cache_1024_lock) != 0) + err = BAD_MUTEX_E; +#endif /* HAVE_THREAD_LS */ + + if (err == MP_OKAY) { + sp_ecc_get_cache_1024(g, &cache); + if (cache->cnt == 2) + sp_1024_gen_stripe_table_42(g, cache->table, tmp, heap); + +#ifndef HAVE_THREAD_LS + wc_UnLockMutex(&sp_cache_1024_lock); +#endif /* HAVE_THREAD_LS */ + + if (cache->cnt < 2) { + err = sp_1024_ecc_mulmod_win_add_sub_42(r, g, k, map, ct, heap); + } + else { + err = sp_1024_ecc_mulmod_stripe_42(r, g, cache->table, k, + map, ct, heap); + } + } + + return err; +#endif +} + +#endif +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * p Point to multiply. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_1024(const mp_int* km, const ecc_point* gm, ecc_point* r, + int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_digit kd[42]; +#endif + sp_point_1024* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_42(heap, p, point); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 42, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 42, km); + sp_1024_point_from_ecc_point_42(point, gm); + + err = sp_1024_ecc_mulmod_42(point, point, k, map, 1, heap); + } + if (err == MP_OKAY) { + err = sp_1024_point_to_ecc_point_42(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_42(point, 0, heap); + + return err; +} + +#ifdef WOLFSSL_SP_SMALL +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * r Resulting point. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_base_42(sp_point_1024* r, const sp_digit* k, + int map, int ct, void* heap) +{ + /* No pre-computed values. */ + return sp_1024_ecc_mulmod_42(r, &p1024_base, k, map, ct, heap); +} + +#else +/* Striping precomputation table. + * 8 points combined into a table of 256 points. + * Distance of 128 between points. + */ +static const sp_table_entry_1024 p1024_table[256] = { + /* 0 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 */ + { { 0x0162bc2,0x03f6370,0x0a26fe7,0x0621512,0x1decc6e,0x04cec0e, + 0x077c279,0x030bab3,0x06d3582,0x14b7514,0x17e36e6,0x0fa6e18, + 0x0601aec,0x067ae83,0x0b92656,0x1aff1ce,0x17d3e91,0x1617394, + 0x0a7cbd6,0x03b725b,0x19ed862,0x13ad2b3,0x12c9b21,0x0ad5582, + 0x185df2c,0x1cc9199,0x131a84f,0x111ce9a,0x08ec11b,0x18b9ffd, + 0x1bc4852,0x03e7f3f,0x0386a27,0x1da2750,0x0d3b039,0x0d7b363, + 0x0ecd349,0x12946e7,0x1e02ebf,0x0d43893,0x08dfff9 }, + { 0x03c0c83,0x03a9d60,0x15d6d29,0x11579b9,0x08e69d1,0x1adb24b, + 0x06e23dd,0x0a5c707,0x0bf58f3,0x01fca4d,0x0f05720,0x0cf37a1, + 0x025f702,0x07f94c6,0x0fd745a,0x12edd0b,0x198c6c7,0x01fb75e, + 0x178f86d,0x0315e88,0x0093206,0x072a732,0x19f5566,0x09fdb3c, + 0x1283b50,0x08bd823,0x15c361d,0x0a1957f,0x1addbe4,0x145f9fa, + 0x1291f58,0x0f19699,0x037ef30,0x0248400,0x14f1ac7,0x0e9c291, + 0x0fcfd83,0x0b6994a,0x007cf89,0x0f7bc78,0x02aa120 } }, + /* 2 */ + { { 0x1900955,0x1b6d700,0x15b6a56,0x039d68c,0x05dc9cc,0x17f4add, + 0x0241f9c,0x068a18f,0x1a040c3,0x0d72a23,0x0ba9ba8,0x06e0f2a, + 0x0591191,0x1684b98,0x1fdcd0d,0x1a21ea9,0x074bda4,0x0526d80, + 0x059101c,0x060de32,0x122cfd5,0x19c5922,0x052e7f9,0x093eec4, + 0x0dad678,0x1720a34,0x02c3734,0x0f65343,0x1ad4928,0x18d0af0, + 0x06ab75f,0x1b77454,0x0c63a81,0x119bccd,0x116e048,0x10026f3, + 0x10e53bc,0x0159785,0x0ed87d0,0x0fe17e2,0x08c3eb2 }, + { 0x113696f,0x169f0f2,0x1fea692,0x1831903,0x0350ba5,0x019e898, + 0x104d8f0,0x1783c5f,0x117a531,0x1ed3738,0x1584354,0x092035d, + 0x0742ec6,0x14cffab,0x0fa37df,0x1a255a6,0x13e3dee,0x1f2556b, + 0x003d37a,0x0768ca3,0x10b4d98,0x14a8179,0x064d949,0x1231aff, + 0x199aba8,0x1cd3f13,0x19c03f1,0x1ffd096,0x1fd8c20,0x006b205, + 0x0f5ed10,0x0ba4c83,0x1a21d21,0x110e5e1,0x110b0c9,0x06f3072, + 0x11401e8,0x132805d,0x10c42b3,0x07c4a38,0x07bf416 } }, + /* 3 */ + { { 0x1fd589e,0x1a7c471,0x080c705,0x01bf2e9,0x1b50179,0x182a4fe, + 0x08f8cf9,0x069a12c,0x115924f,0x0848f7f,0x196b163,0x195bf36, + 0x0feef79,0x1fb4e16,0x1310988,0x10579a5,0x03252cd,0x0c0bec8, + 0x17c7777,0x09e9b34,0x16bdacf,0x1aa808d,0x1418498,0x1a28193, + 0x0490d2e,0x1694fba,0x1136da1,0x08125d1,0x0b0fcc6,0x178b3bb, + 0x0d8897b,0x1be2d5d,0x08c01e9,0x1ec1507,0x1d0612e,0x0ec506c, + 0x0956e33,0x1aba714,0x1fc1dd5,0x18ce0b4,0x09871ed }, + { 0x16535f7,0x1bb6abb,0x0ee2f42,0x044c6b6,0x1214d60,0x10b7b22, + 0x16b6674,0x0eb8184,0x15515bf,0x0a6f9d3,0x1c59d7f,0x0b78bd3, + 0x0724a62,0x003439f,0x0d7bedd,0x0b89478,0x033bb2e,0x177ae4d, + 0x01ac662,0x0366bd0,0x10eda97,0x12d1e34,0x07d7032,0x03c4683, + 0x1dd898e,0x0f2546a,0x1a556b6,0x19d9799,0x0d34164,0x0203924, + 0x1b8bb3d,0x08b815e,0x0bb3811,0x007ff8d,0x1a0871e,0x0e7e97d, + 0x0272ed5,0x06fbb46,0x0deb745,0x0146e2c,0x0397ed1 } }, + /* 4 */ + { { 0x15c2a27,0x105d93a,0x11133cf,0x12b2b0b,0x138e42f,0x142f306, + 0x0f83c64,0x01e8d62,0x076273d,0x1f66860,0x115a6b0,0x010a327, + 0x0a7800f,0x01a8c0c,0x139d2ad,0x06c77e0,0x0388496,0x1492c55, + 0x032253f,0x0cc2f97,0x09a0845,0x15157cb,0x02f18aa,0x08cd1b3, + 0x0280b5a,0x07d3361,0x1aa64bd,0x193beb1,0x001e99b,0x1bec9fa, + 0x03976c2,0x1898718,0x0614fe1,0x0fb59f0,0x1470b33,0x11aa622, + 0x0143b61,0x1abaf67,0x0629071,0x10bbf27,0x0402479 }, + { 0x1055746,0x128bc47,0x1b83ee8,0x001563c,0x05ba004,0x14934be, + 0x053eeb0,0x081c363,0x15b4f47,0x18a908c,0x1ee951d,0x03a1376, + 0x0425009,0x1cd09cd,0x19d2186,0x154fcf4,0x1b3f353,0x15d4209, + 0x110f3bb,0x0ee3244,0x1bd0afe,0x1b1c23d,0x0511a34,0x149285a, + 0x19ff63d,0x02b30fb,0x075096d,0x0ac7438,0x1f46301,0x07e6baf, + 0x124f09c,0x1d65005,0x0072090,0x0380221,0x172f217,0x08d1e19, + 0x1a032e7,0x01b97df,0x0760329,0x1cd916f,0x01a6fd1 } }, + /* 5 */ + { { 0x15116a3,0x1480d46,0x11fe59e,0x0965ebe,0x0b84439,0x15d79d8, + 0x1514983,0x019c735,0x160ccfc,0x10df30b,0x1d4fc87,0x07a5987, + 0x16ac07e,0x0f688dd,0x00e3838,0x16185bb,0x1071c15,0x022a3a9, + 0x083f96e,0x1a8e912,0x096d70d,0x16f238c,0x06882f8,0x04ed8f8, + 0x1ad8a59,0x1039e1f,0x0f221bb,0x04d4398,0x031ac40,0x179bb74, + 0x1967f6d,0x158a03a,0x0a35d1a,0x142ba13,0x0415036,0x0a15d31, + 0x0bd734e,0x0ef0525,0x11d4197,0x1b82ac2,0x029b7d4 }, + { 0x1f4e20b,0x1e165e5,0x131512c,0x1eb1988,0x1c3f548,0x06560f8, + 0x06d516c,0x0427301,0x100f806,0x007815a,0x0417803,0x11200cd, + 0x0ce612b,0x01a80c4,0x0563b5e,0x0ed651e,0x0583f55,0x0600ee2, + 0x11524b8,0x0064e54,0x0443298,0x1d07fc9,0x1de9588,0x1a1b882, + 0x02b0029,0x03d6895,0x049e03a,0x0824a8b,0x13f272b,0x1c8186a, + 0x0347af3,0x048603d,0x0e6ea40,0x083cc5d,0x1cbe8df,0x183cbe7, + 0x02b4126,0x0161881,0x125fa4d,0x004a704,0x05d0928 } }, + /* 6 */ + { { 0x12f780d,0x115bf7f,0x0c7560e,0x01afaed,0x14d2682,0x1ba5761, + 0x0a11e1b,0x1d7c786,0x010823f,0x1ea1109,0x19efd03,0x02fdf6b, + 0x0d227e4,0x12b47c6,0x03526da,0x177d8a2,0x1d61781,0x1a9de73, + 0x1cdc62d,0x1c7e445,0x0c1f9cf,0x0fecef3,0x1fd13a2,0x15936aa, + 0x0553f3f,0x05e78e6,0x1b9bcc0,0x1a5a108,0x0ae6b19,0x01514f8, + 0x1825db2,0x0497177,0x03dbf5e,0x12d53f3,0x1d165ce,0x0e9958f, + 0x04dd33c,0x15b11bc,0x1b9771b,0x068285f,0x00a26e4 }, + { 0x0aa9a08,0x099cfd6,0x1386020,0x0aa48dd,0x00f3110,0x1c9ba3a, + 0x005c184,0x1c31259,0x1242f02,0x0c6a081,0x17a62a3,0x1a4076b, + 0x12482bf,0x0d5df4a,0x1be51ad,0x1049313,0x0b93769,0x15c690c, + 0x1985f1e,0x0d1d12c,0x0b91d52,0x08c5be9,0x058b9d5,0x11acf87, + 0x07973fe,0x028962e,0x08ac05f,0x05c62a1,0x0294694,0x0f5e60d, + 0x00dbd39,0x0a638e1,0x19910ce,0x1cf2851,0x1ad2dde,0x015e9ed, + 0x1a120ad,0x05d8bae,0x0dbb1a3,0x0c3724c,0x019497c } }, + /* 7 */ + { { 0x17659a8,0x0586320,0x03fda48,0x0f25965,0x077ab9c,0x03bcbfe, + 0x1c602da,0x0c6ab6c,0x1e77593,0x057ac60,0x06c6193,0x1b6caac, + 0x065155b,0x1c07a4a,0x1938d55,0x116405c,0x1b7229a,0x0758564, + 0x15c6f58,0x129af04,0x18f9885,0x1cf1fd3,0x1773024,0x185a6f2, + 0x148302a,0x0223dc5,0x02e43c5,0x00bf7ec,0x04b3c15,0x07409e7, + 0x062b184,0x1ab36b8,0x1a4f27a,0x101111c,0x05cdf3a,0x16bf467, + 0x0dff1c7,0x1c3985c,0x1de9b95,0x116a2f7,0x096b91b }, + { 0x0ac087c,0x0c8fa4d,0x0a3706a,0x1cd9fb6,0x0e62f74,0x1b006b6, + 0x1fe697d,0x19211ad,0x0f917f9,0x1c0e682,0x14b6ff5,0x0bec7bc, + 0x007796f,0x176b90c,0x16d9380,0x026fbcf,0x0f66fa4,0x107843b, + 0x1287dc5,0x03dcc87,0x18a3327,0x0c3e255,0x12e6c81,0x090208f, + 0x1710739,0x01be5d0,0x1566317,0x1f34321,0x00e125d,0x1395379, + 0x0b432db,0x1e9e520,0x1142204,0x16e7dd1,0x12e5f38,0x0285a51, + 0x03d3c35,0x130dc55,0x092777c,0x02b9ff8,0x073f3d3 } }, + /* 8 */ + { { 0x0fd3673,0x142adf3,0x0ded761,0x1f3a429,0x109b70a,0x0236699, + 0x0be4373,0x1bd1a66,0x1595510,0x0a9e00a,0x0494739,0x012c718, + 0x095746a,0x02e60de,0x1f3a96e,0x1751f9a,0x068002e,0x027fd0a, + 0x0bf35df,0x0796e04,0x05e310a,0x1de2750,0x0da6677,0x1f4eadd, + 0x1a0d04e,0x1ec19ba,0x1b73b57,0x1b204f3,0x1fd56e4,0x1201928, + 0x1c52064,0x105498b,0x07633a4,0x0082df4,0x04c06cd,0x1062e1a, + 0x1247e57,0x0cc587b,0x087ea4e,0x0c886d7,0x088934f }, + { 0x113eabc,0x1a1d823,0x145fc27,0x03599b8,0x0ca7dd9,0x09e53e2, + 0x098efbc,0x0964fb5,0x0258818,0x1972d3d,0x1709a62,0x0c25b2b, + 0x0c0a8cb,0x10f978a,0x1a5d68b,0x126b868,0x0ede172,0x18f94dc, + 0x102f078,0x17fadda,0x03dac3c,0x1f89931,0x14fd1ac,0x016ed03, + 0x1be6dfb,0x1a2608a,0x155b690,0x1c63868,0x043d985,0x1f8c547, + 0x1aa9f18,0x097bb69,0x1cb2083,0x07ac62a,0x10e1295,0x1362d41, + 0x06fd69d,0x1566512,0x12385d3,0x1762a6a,0x00d1898 } }, + /* 9 */ + { { 0x15ef043,0x19a30f1,0x15913a9,0x12692d6,0x107b67d,0x1c1d1e0, + 0x05cef43,0x06bac58,0x051d29c,0x16a581c,0x070693e,0x1054e36, + 0x1e3f428,0x0a5a1dc,0x0af3d99,0x1ea86ba,0x1aa2abd,0x0e3bd8a, + 0x0af8f70,0x071501b,0x073b5cb,0x175240b,0x057f682,0x1721d7c, + 0x16b4de7,0x1ec434c,0x14af23c,0x09f0fc4,0x04e4248,0x01eb1be, + 0x162b7b4,0x1af4f5f,0x1ede666,0x05c9d72,0x168a873,0x0301bb2, + 0x06fba39,0x0e7e92a,0x0b98295,0x1b88df0,0x02bdab1 }, + { 0x06fed61,0x0f115fd,0x0539e93,0x0b991bb,0x0a458aa,0x09117ae, + 0x0b7c41c,0x0ee7c6e,0x1e5aff3,0x1525a27,0x0e39b41,0x174e94e, + 0x16bc2d0,0x0f98f89,0x11c3875,0x1522234,0x13ae102,0x0bbffc9, + 0x0431e21,0x1014a06,0x05ac8b3,0x143c1fe,0x07cf008,0x0e4ba0d, + 0x0892544,0x110f633,0x196b210,0x0f1e1c2,0x1a6e8a8,0x18d7e7e, + 0x0ea68eb,0x0f19a55,0x183ed37,0x0875700,0x158209b,0x0a659b7, + 0x0bee641,0x11a330e,0x00482cc,0x1257382,0x0353eb8 } }, + /* 10 */ + { { 0x0b5521e,0x0e56b08,0x0bc323f,0x00a5ce0,0x1a11b44,0x1ed24e0, + 0x1a0363f,0x15ac604,0x0cbf36b,0x0dcb2a5,0x028b5f3,0x1c22982, + 0x007b58c,0x131873f,0x1747df7,0x150263c,0x17d6760,0x1c65f1e, + 0x12035df,0x0b0cd6c,0x0219eb3,0x19bf81b,0x161ca33,0x1514eae, + 0x065ed42,0x0386eac,0x1641a8a,0x107e3e3,0x1f906b2,0x1fd2528, + 0x0a1e788,0x0a87641,0x0ac6e83,0x13baa79,0x0de6e07,0x1c9e16c, + 0x040016e,0x1de06a4,0x0d9f55f,0x0e3cc43,0x08da207 }, + { 0x0ce65ec,0x0a80276,0x0178f21,0x1f6e903,0x16d10d1,0x1cbd693, + 0x1ef29e1,0x15ac97c,0x077e54a,0x1a226d8,0x17c3fd0,0x01937c1, + 0x0417b6b,0x02a8435,0x11095b0,0x1ab471f,0x03bfd74,0x07ca962, + 0x0713b6e,0x1c00b40,0x0328501,0x1e252bf,0x1545cb7,0x0baddc7, + 0x0ce4e53,0x08c6da0,0x1031942,0x15de3cb,0x1561fcb,0x02f3c2b, + 0x11ba145,0x0694449,0x068536a,0x0705172,0x089c3b0,0x18d351c, + 0x042b03f,0x1a91239,0x0f57ecf,0x1c5877d,0x0862f55 } }, + /* 11 */ + { { 0x06049fe,0x11c8791,0x07ecb5a,0x11b9779,0x0c92a57,0x11a7dbe, + 0x1b2925d,0x1274a5f,0x03dea58,0x19a065b,0x07a458a,0x0714549, + 0x13a39f3,0x0a4f20f,0x0cb7cf6,0x0fc804d,0x0db065a,0x1638e3e, + 0x1a0a068,0x1709408,0x0eca4a9,0x01b98f7,0x18fbad4,0x1976e4a, + 0x0913476,0x1c67368,0x06e5299,0x19f2f35,0x0fd9f10,0x061dc04, + 0x0e6d136,0x1c15f8b,0x00da613,0x0df34f3,0x1f78fa9,0x1ea5b9c, + 0x1c1ee74,0x0eb4326,0x01e40e9,0x1227790,0x071ab28 }, + { 0x15b60ad,0x0c7e21d,0x06133d8,0x0094186,0x0afb5e3,0x0019810, + 0x00732f1,0x0cda447,0x1db1c0c,0x1e7c4a9,0x04aa34c,0x1c9b4c2, + 0x069c994,0x08cb3d4,0x0ab8b0f,0x19a53af,0x0935b7a,0x1e146aa, + 0x12695fe,0x0b7a26d,0x07f9807,0x1f4e421,0x12700dc,0x0644beb, + 0x0a18d19,0x0c6165e,0x0d10b00,0x06eefa2,0x13a7277,0x16a3fdd, + 0x063af97,0x032c5b8,0x0437d49,0x0440338,0x1824b70,0x19e7383, + 0x15fff35,0x14e37b8,0x029940f,0x16cbc6c,0x08d087b } }, + /* 12 */ + { { 0x1dc1844,0x091811f,0x115af88,0x1e20bd5,0x0eca27e,0x1451a43, + 0x0981bc5,0x1964307,0x1e1d7a4,0x0afc03e,0x1750f8a,0x0c64fde, + 0x077246a,0x03b812e,0x050c817,0x09c7d5c,0x1caf348,0x0a5efe3, + 0x1d4b01d,0x07312bb,0x0ac0ec9,0x1b6bd4e,0x00b9957,0x15dbb61, + 0x1fe208b,0x198cc2e,0x1149f79,0x13902fc,0x1de1ea7,0x07de189, + 0x0ecc338,0x1989ed9,0x1f95b89,0x19066ce,0x1c7bd6e,0x03e55db, + 0x1a8cfb0,0x0f05448,0x0dfb3f0,0x094c7db,0x0225ed3 }, + { 0x0bb1a85,0x18aa6dd,0x1968f84,0x0e3cd4a,0x13d8dae,0x058807e, + 0x1f55aad,0x035a642,0x0ebc78e,0x026c9a7,0x1cf4df5,0x043691c, + 0x0b02153,0x100f21e,0x1242fe8,0x0120b77,0x1d02750,0x09e11f8, + 0x019a468,0x1ca0019,0x041c2a2,0x093032c,0x022caeb,0x004d6c0, + 0x01caf30,0x1308aea,0x1149db3,0x0e2585e,0x132ffb1,0x01f38ac, + 0x1c80713,0x0d4e995,0x094e13d,0x09bd23c,0x177c301,0x1c05ade, + 0x02b1c97,0x1dbb016,0x1f1eea3,0x1cba110,0x0612b60 } }, + /* 13 */ + { { 0x0245d6b,0x04ae7dd,0x1fdbbf5,0x0f459c7,0x1cf0cbb,0x1aff772, + 0x0ab037f,0x14649b4,0x0cf28c6,0x0648a7c,0x0295ae4,0x0a1a861, + 0x1472fdb,0x09eb901,0x16fdde4,0x193d207,0x091822a,0x0e7d2f6, + 0x0ba8fa0,0x1ce7907,0x11390dd,0x1133144,0x1516ea5,0x0d597a6, + 0x1648bca,0x01d5297,0x1a6281a,0x1ede4ed,0x18ed52f,0x09d651b, + 0x16494db,0x110b583,0x13c2c54,0x042539a,0x0b6802f,0x0f95fea, + 0x1768416,0x18fc0e1,0x061b8e5,0x1c3a5af,0x00f7334 }, + { 0x196067e,0x1ae41b2,0x001abee,0x1271833,0x13e54e1,0x0586e61, + 0x1659ce7,0x1f3050b,0x1424035,0x1a9fa1e,0x1e4254a,0x03f1bfd, + 0x1a38c53,0x0d87ab8,0x1efa393,0x14f0f21,0x0d2a39c,0x04d060f, + 0x01bc988,0x1983acc,0x0b4a2fe,0x18b95be,0x0772242,0x176f0d1, + 0x0a6fbcc,0x124e19e,0x0bf9cfb,0x0362210,0x166c48d,0x1e8bfe5, + 0x1cd642d,0x10dc28a,0x156b0a6,0x156c2c9,0x0b1014f,0x16ebad0, + 0x054d30f,0x172afd6,0x1a526ca,0x0e5f15d,0x067636a } }, + /* 14 */ + { { 0x11d6bea,0x031de5c,0x0e598e0,0x1d247d9,0x0e263a2,0x13d6535, + 0x0264b18,0x0fd3af6,0x077af9e,0x176800d,0x0bfaef1,0x199e495, + 0x109214a,0x1c02ad4,0x1592e59,0x0933b46,0x11ce027,0x0804ccd, + 0x11a81a9,0x0749c3c,0x0fe7e41,0x1b1728f,0x081744f,0x150877d, + 0x07d349b,0x0cf1af4,0x14c60c5,0x14c6704,0x0019230,0x145d2a3, + 0x1c9808f,0x16ffa39,0x1107721,0x17ea9cd,0x10aff7c,0x108d6aa, + 0x1c18af3,0x0a7a7c0,0x02596cc,0x0ecc159,0x0086f98 }, + { 0x0bb9850,0x00caa46,0x1231d9c,0x01441a5,0x0210b73,0x1ab3863, + 0x1415d4c,0x1d48109,0x10324ba,0x166e2ca,0x1ba6d0f,0x0be58ed, + 0x04607fc,0x0207fd3,0x04f403d,0x08c79e7,0x1962dc1,0x1f0088b, + 0x11dc979,0x1704a33,0x1186f00,0x1b2de8e,0x0d7981c,0x1ee5558, + 0x0554c2c,0x0bef9ec,0x1bbe8d2,0x09ba1fb,0x06ad11b,0x13467b2, + 0x0b75c48,0x13ef71d,0x1c20afb,0x16ff283,0x0753f01,0x14c612d, + 0x1245549,0x1bef8e3,0x1a041da,0x007cc35,0x0681f94 } }, + /* 15 */ + { { 0x1a0623b,0x0a8b1e4,0x0351f2b,0x0ecff57,0x1bf8295,0x17be3e6, + 0x0c3b206,0x1845995,0x0e966d5,0x14f1c64,0x1390711,0x1aa5e1a, + 0x1c34430,0x12959ac,0x181d68a,0x0024e84,0x1e333bd,0x09216e9, + 0x1fb48d0,0x07ec6b3,0x0ffacda,0x186bea9,0x137ccdc,0x08187de, + 0x156f076,0x0be2fff,0x106ef79,0x0f07843,0x0bb3364,0x051575c, + 0x01761e1,0x1d5a108,0x0c7c533,0x115ea0f,0x108fe6d,0x1e96fe2, + 0x1075d4a,0x018a2e3,0x1642955,0x09574c0,0x00c9de9 }, + { 0x1d5682b,0x1939aca,0x1bb63b5,0x065d84e,0x111c428,0x1b50693, + 0x0bb562c,0x11fa3e9,0x08498a8,0x155a062,0x03d1458,0x18c4890, + 0x0258c8f,0x1bce7ff,0x123292e,0x06b3b17,0x03c701a,0x0c855ac, + 0x1f57457,0x0634e67,0x133caee,0x1de4891,0x00a9565,0x187c784, + 0x1cae4b6,0x044080c,0x10a64e0,0x0a26085,0x1c8199e,0x141efa3, + 0x0483800,0x1e5401d,0x0d68e58,0x0d71dc8,0x1d069dd,0x04d3c5b, + 0x071c30b,0x097652c,0x18e5ae3,0x01d763b,0x0733dca } }, + /* 16 */ + { { 0x159213a,0x04ae825,0x003bd6d,0x131ae04,0x0a67203,0x13b8e0e, + 0x02698ad,0x1969796,0x02b9eb0,0x156f76a,0x0e88489,0x0ea919b, + 0x11eb544,0x1844486,0x06aff37,0x08d681c,0x163698e,0x029284c, + 0x0ba704e,0x1fe1610,0x1a71e1b,0x06a884c,0x0862793,0x172398f, + 0x0c9bcc9,0x05f11b0,0x104dfb1,0x17a9afb,0x119f6e9,0x1290e8a, + 0x00f40d5,0x19f064a,0x15f6d78,0x1515a5f,0x00c637b,0x19c8602, + 0x0f4c319,0x09924a7,0x09f5f0c,0x08e1e3f,0x02ab3bd }, + { 0x02c9fbb,0x1db4049,0x1b455d4,0x101e2d8,0x069e7dc,0x00b77e4, + 0x144d6eb,0x1370688,0x0846d1d,0x19351da,0x18b0850,0x1dc765a, + 0x15b517f,0x0594956,0x016be88,0x15826d2,0x11a2cad,0x0952b89, + 0x0f6f2a3,0x009b1fd,0x1fb2cd9,0x179f9b2,0x17fb6a1,0x0fd5439, + 0x1b208dc,0x1e0384b,0x129179d,0x1346b50,0x1d118e8,0x031667a, + 0x1a105e8,0x03edd33,0x00c04a8,0x1043e9e,0x12c2e9e,0x05888e0, + 0x1ea22ad,0x0513e89,0x148a5be,0x02c984f,0x093a4b4 } }, + /* 17 */ + { { 0x11efb7a,0x18de08f,0x1037509,0x0c67f99,0x0e4e68e,0x0fa8545, + 0x123c6c4,0x1133b37,0x1af0760,0x0181cc7,0x14380d5,0x05f6887, + 0x0145e24,0x1b71ea6,0x1b09467,0x15a12e7,0x190ba9b,0x1d5b87b, + 0x06b7443,0x0255abf,0x02b4de6,0x070a74a,0x0e0df95,0x1716d15, + 0x056d3dd,0x0040bad,0x106b0a9,0x10b6467,0x080f94e,0x1618786, + 0x1e7e3fd,0x1131b69,0x17f3fb7,0x1ee6ea5,0x113d169,0x0b458c0, + 0x1e3d389,0x15d97b7,0x1dd8fce,0x1ae65dc,0x0342ce0 }, + { 0x1491b1f,0x109ca67,0x0e57ac9,0x0e3213c,0x1caaeed,0x126df56, + 0x0156a7f,0x09bb988,0x1493d60,0x1d3308e,0x17afbc5,0x147439c, + 0x15ba445,0x11cc4e5,0x0b8a163,0x1080dd0,0x08283f5,0x0dcb7a1, + 0x055b3d5,0x0ef7334,0x0a0e998,0x13270b3,0x0be41a9,0x12eda27, + 0x1d353b2,0x100e750,0x1cdb186,0x1f82de4,0x155d86e,0x0219d87, + 0x0076c13,0x11d6698,0x0b4b269,0x101401e,0x1de0ab9,0x0a71a0f, + 0x03be3ec,0x161de5a,0x1f4810e,0x1e7c2ad,0x0455f4a } }, + /* 18 */ + { { 0x14ec21c,0x1f9313a,0x08e3015,0x13c7437,0x1eacd4c,0x160ff49, + 0x0434445,0x16c7404,0x0eacc8a,0x075274a,0x1ccb2b9,0x1935d4d, + 0x0e31c00,0x035cbae,0x0d88e76,0x143d2b9,0x18ca14e,0x1b2a6ae, + 0x019ff22,0x1a63e8a,0x1ecb230,0x05b1aaf,0x122ee43,0x02e5d1c, + 0x01ecedc,0x19bbc7c,0x032c019,0x1107015,0x02d0122,0x1700f0b, + 0x17066c0,0x18b5e28,0x0087a06,0x0e1aa07,0x02dedcb,0x0de09b9, + 0x0de3c06,0x07790a4,0x07edfdc,0x0862601,0x04f1482 }, + { 0x02055e2,0x027e737,0x019d780,0x150d864,0x09e247e,0x0ed5514, + 0x0f6557e,0x0769d79,0x1ceb7f6,0x0af9097,0x1e12834,0x183f0c6, + 0x115ecc5,0x1abb012,0x0ce002d,0x052a8a7,0x1c38a6a,0x0f5c980, + 0x04f3746,0x0d74314,0x0d240f1,0x08c43e1,0x00c4f49,0x12827ed, + 0x035859a,0x1e2fcc9,0x1bf8ff5,0x04680bc,0x00ee054,0x159a0b7, + 0x0c19e2b,0x07f5b55,0x13be7bb,0x022388f,0x08b20a2,0x0cf203f, + 0x0d662ff,0x086d982,0x05c2f25,0x1a87802,0x074d5d2 } }, + /* 19 */ + { { 0x15bfe11,0x016e015,0x079e8c0,0x1aa5a64,0x0733410,0x1cdd448, + 0x03d9659,0x0dc2b24,0x0685b23,0x112460a,0x1d81003,0x0b2868d, + 0x108cfab,0x00638bf,0x15ebedd,0x08aed3e,0x08c6604,0x186dd59, + 0x1370c91,0x0132d13,0x0d050fa,0x1161187,0x10780ab,0x0b7dee8, + 0x01554e4,0x1b786cb,0x0b3935e,0x0d11530,0x02d22e9,0x1d63af3, + 0x0a3eb7b,0x17a5974,0x11512a6,0x03a4fd7,0x198af9f,0x16f10d1, + 0x0e9f5a6,0x0246c0d,0x1e8a620,0x0858b0a,0x06b1a54 }, + { 0x1242066,0x15cd6a1,0x0aba7d6,0x0a59994,0x0afef1b,0x076e270, + 0x0fb1e62,0x1ab6368,0x10341b0,0x0860078,0x0aacdc3,0x11ef6a1, + 0x194d68b,0x19d3254,0x03939bf,0x0d09d35,0x0fb7f1a,0x00cc19c, + 0x14683d7,0x01ce906,0x05158bc,0x06ed622,0x0b2b3cb,0x13feed6, + 0x139995e,0x02ae0a6,0x1c58e4c,0x0940367,0x0d83765,0x1752c44, + 0x0c5ab0f,0x0e464ef,0x04d9a9a,0x0dddfdc,0x1a47847,0x1132264, + 0x0bb6717,0x1b8bd75,0x12b2165,0x04d1762,0x04c2135 } }, + /* 20 */ + { { 0x1532833,0x1f0534a,0x019cb9b,0x1dac4da,0x0bca228,0x0f39ded, + 0x1cf6592,0x018455d,0x0f03c4c,0x041d43d,0x1a6d148,0x0eba6a2, + 0x09e954e,0x1a28354,0x1d427b9,0x19f20ae,0x16e2aea,0x0a4e593, + 0x09027e4,0x0ebaeff,0x16b9082,0x1ef85de,0x187adbc,0x0264e08, + 0x002cbe4,0x058ca41,0x06c7126,0x0be7f84,0x1fee593,0x05d41b0, + 0x1cddb1a,0x0a1c0a3,0x18cbbd9,0x1382150,0x01e4c63,0x1647095, + 0x00dd1e8,0x155f56c,0x10cd0a4,0x052b86f,0x065713c }, + { 0x0b77b9a,0x05474e7,0x11a7733,0x0e476d2,0x0f97e72,0x0eb5941, + 0x0fb9a80,0x1fd8ed5,0x15abecd,0x092901e,0x0435c0e,0x0104525, + 0x1889448,0x1818a21,0x04c5092,0x08f87f3,0x1f17cd4,0x182104e, + 0x0157209,0x1e40b39,0x00697c6,0x112b607,0x165f5e1,0x05b2989, + 0x1b6fe41,0x0eead4e,0x0665310,0x134c8b2,0x1e21a31,0x0550e44, + 0x03848d2,0x18d407e,0x0904b50,0x17f566b,0x055a985,0x16ab82a, + 0x1cc7693,0x1b68dab,0x0f0e138,0x0d8775c,0x06b0e99 } }, + /* 21 */ + { { 0x0eced00,0x04fd5e6,0x0998c9e,0x15cb6f5,0x1237e71,0x0f5e6f9, + 0x189a4b7,0x11f0f65,0x0b61dad,0x1922890,0x1e00f2d,0x1c91a6b, + 0x0de11e5,0x0c72878,0x137d75e,0x15725f6,0x0b4bcd2,0x0b07734, + 0x138cd8f,0x165eb83,0x064798a,0x0d3e6a1,0x056e8e7,0x1e9f67e, + 0x172eb83,0x06d8d32,0x0395bc2,0x1eefbd1,0x0562c20,0x1b0f0b9, + 0x1d05d0d,0x114b1e1,0x0349ff8,0x0eb715f,0x1c6e134,0x09c09b4, + 0x1e9ff3b,0x0781a14,0x08fe0da,0x00acf04,0x04022a2 }, + { 0x1847375,0x1de82c1,0x0bc149e,0x047e8a3,0x1ae56b6,0x163f8c1, + 0x1c9352c,0x11ac331,0x14525b9,0x1191fad,0x0212d7b,0x07341c1, + 0x16a9d8d,0x1d8963b,0x0175fdb,0x182a9a0,0x03e708b,0x06b8e24, + 0x109506f,0x0dfa50e,0x1ddb8ca,0x06fc1cb,0x02bcf73,0x199e486, + 0x131253e,0x1c6dc06,0x0163606,0x0e87421,0x191f68c,0x1590b89, + 0x1fcfd23,0x06776ca,0x13aff88,0x03f18a4,0x15981f9,0x0c3a2bd, + 0x008279f,0x0acd88f,0x0a55840,0x196494d,0x0312179 } }, + /* 22 */ + { { 0x1615ac2,0x061e503,0x1606a53,0x082435a,0x05865e6,0x0c35bcc, + 0x185be9e,0x03b5c8e,0x19d5e0f,0x0ad2075,0x115fa8e,0x04c87b2, + 0x19a9143,0x1d1432e,0x19b5a8f,0x15d191b,0x1961014,0x183b8ed, + 0x1daa1f2,0x0f99cd2,0x0f6077a,0x108a1d0,0x09f790b,0x127b269, + 0x1cc09d9,0x01ef101,0x0e63b13,0x04030d2,0x05df4b9,0x036c1d1, + 0x1af5dd5,0x0c5605a,0x0d9eb47,0x138c485,0x0823416,0x17f555e, + 0x031221b,0x1c0c0fa,0x047a948,0x0f0e66a,0x0417d6c }, + { 0x091e9a8,0x0c0db87,0x1accf2f,0x1186e1a,0x1334041,0x1511b9b, + 0x0c42a3a,0x0ad04bb,0x06c7d67,0x19584f2,0x0cf7b63,0x1d37298, + 0x1be288e,0x0b4af1f,0x0109aec,0x1d1119b,0x086dce9,0x1530bb6, + 0x05978d8,0x191244c,0x1b093f4,0x0fb031f,0x1453904,0x1f3c098, + 0x1ac20c8,0x0b0b483,0x137f4ab,0x1dee8d3,0x12199ac,0x1d72422, + 0x18ae8c2,0x0255868,0x0681293,0x0a41698,0x01cf24b,0x0a0237d, + 0x0833099,0x065fc4f,0x0282bfd,0x0a5a28e,0x002189d } }, + /* 23 */ + { { 0x0599c69,0x00ceec9,0x0b29cf9,0x16ffd86,0x1b94221,0x1dfdfea, + 0x06f4826,0x0b7657f,0x063ed89,0x0f54bd2,0x01bde58,0x08d67e9, + 0x1966091,0x1e8a0d1,0x071e817,0x0826b7a,0x0cf83d6,0x1e3cf64, + 0x020d41e,0x1fa85f3,0x10277f8,0x1b8bd9e,0x0bf2d4e,0x194b443, + 0x18dcd67,0x1c34332,0x1334525,0x0d4d815,0x195067a,0x0b871a5, + 0x0305bcf,0x1be892b,0x11208e3,0x001091b,0x139bb0a,0x03a5bac, + 0x10782c7,0x1962559,0x1dbe8ce,0x17aa422,0x07bbf8a }, + { 0x18b981a,0x12557d3,0x00a2fa7,0x0c609d9,0x188b4e3,0x0cef51b, + 0x13ce4e5,0x18e188b,0x1240b39,0x054dee9,0x00edf5c,0x0fba507, + 0x06499cd,0x183d081,0x1a42cb8,0x1e36660,0x198ee92,0x011316a, + 0x11c9692,0x1aefbd6,0x0a0ec62,0x1e3de1d,0x085bc96,0x0bdeff5, + 0x18b65d1,0x147b16e,0x142e5b5,0x12f2443,0x0f1906d,0x02e1d00, + 0x102e4a2,0x1d6e98e,0x0476b9b,0x1b1117d,0x0ed71d5,0x1e42fbb, + 0x1788504,0x1c16182,0x1c5af09,0x0d9f024,0x0860d09 } }, + /* 24 */ + { { 0x179bbf9,0x019bea6,0x1e03faf,0x10d3ee9,0x1d53eab,0x0826a9a, + 0x08254cc,0x12ffe6d,0x0196f8b,0x15c106d,0x19a424a,0x1a3eeb9, + 0x14961d3,0x02341ba,0x05fb010,0x1973763,0x1bf93a6,0x1d34670, + 0x17c0868,0x08adff8,0x1fdb503,0x18c4a07,0x0d428b6,0x0008413, + 0x10f8fef,0x03abbe2,0x1c12596,0x0c6ba2e,0x18770ad,0x136cc5d, + 0x0f9c95d,0x140f1ca,0x019b028,0x041bc47,0x132be7f,0x006c9a9, + 0x10dd39a,0x1efa08f,0x1e48068,0x084075b,0x07e80e4 }, + { 0x19a1ddf,0x1c52ba9,0x15892d7,0x1ddc90c,0x1248e7a,0x1010f0e, + 0x1247605,0x18838f6,0x1fd36d2,0x13dc38d,0x100364b,0x0a0815d, + 0x13da38b,0x10c9f8d,0x009d849,0x0f1ade5,0x086fb1f,0x1b4e1ff, + 0x009eb0c,0x116f0dd,0x08f756c,0x039a43e,0x05a1fdb,0x1bdcb78, + 0x1221719,0x00c55c7,0x1ffce65,0x09d08e7,0x027c800,0x000a548, + 0x0a3ce13,0x1543a5c,0x167be9a,0x0f778cc,0x1b4f819,0x190d2d0, + 0x07bd837,0x1e35846,0x1618dcd,0x1a33d17,0x05dcab5 } }, + /* 25 */ + { { 0x07d772b,0x0141d4d,0x166c1e1,0x0bca812,0x0b49e52,0x00a55ab, + 0x0c02219,0x152a8d7,0x09d74b2,0x02240b1,0x0c2c6f5,0x015a407, + 0x0b26789,0x0469fc3,0x1ea0af3,0x1078e3c,0x1b5d85a,0x189a95f, + 0x0b41f33,0x1e2dc7f,0x043ff29,0x1c20f06,0x100a98e,0x06f3fdf, + 0x122c56b,0x1934827,0x0ec4913,0x13b14ca,0x08bdea1,0x1b6f9d1, + 0x13998d6,0x1eda8ab,0x0b68851,0x19b9a8c,0x006273f,0x16e9585, + 0x0b2cbda,0x007cefc,0x15262b5,0x13d5b93,0x008cc2d }, + { 0x170c84b,0x1343360,0x1210b9a,0x16b4934,0x1b989e8,0x0644c95, + 0x0038341,0x046f61c,0x061b3a4,0x0d69a3c,0x0062655,0x08a161a, + 0x133c952,0x1188065,0x0488557,0x0eda1c7,0x16ef032,0x18c932d, + 0x1b50ad4,0x10b2b4e,0x13b60fe,0x107e31a,0x02a5b7b,0x0df127c, + 0x00dc824,0x05d3b0f,0x1bc29d3,0x1d92057,0x1fad9b4,0x03421fe, + 0x1d58402,0x09fb6d2,0x16a60e4,0x1ac852e,0x0b21fbd,0x0e7ea75, + 0x12870a3,0x0f35f00,0x156c34a,0x182ab54,0x0991fad } }, + /* 26 */ + { { 0x0844ffe,0x02587da,0x01c60af,0x08c1f17,0x1392271,0x11f8f9b, + 0x0038933,0x1d91580,0x0163519,0x06aa45a,0x022d7fc,0x0857105, + 0x107aaf8,0x15ee4d3,0x02c3130,0x1facf3d,0x1524ba5,0x1d036a8, + 0x04f37b0,0x035f41f,0x18f0d0b,0x1d6fc4f,0x0a02556,0x1465924, + 0x1e92dee,0x1f24365,0x04ff816,0x195c7f3,0x0919aa0,0x184afd3, + 0x02fc981,0x0dc1e37,0x154741e,0x07cc407,0x1dd0c3b,0x0e55da3, + 0x134991d,0x0b7bb5b,0x03fa64a,0x0504b3e,0x066cf8d }, + { 0x06f5868,0x0c82d91,0x1a7a6c0,0x182d213,0x0102e88,0x1bf5aa6, + 0x0245928,0x04657a1,0x0c98163,0x19129f4,0x0b14f3d,0x1d3b0d7, + 0x1737f84,0x17f5557,0x0d49152,0x008dc5c,0x1772ca0,0x133e437, + 0x198cdcb,0x19ca1cc,0x0a0486b,0x105b4a8,0x1da8ea5,0x0357527, + 0x194d7fc,0x13730fc,0x0f04c9b,0x12af825,0x16b0051,0x07f2172, + 0x0326d96,0x10b24e8,0x0d297fc,0x19352ce,0x1a6c5df,0x16eca99, + 0x079d2eb,0x134cedd,0x19122aa,0x0b41d96,0x05fca0c } }, + /* 27 */ + { { 0x09a6663,0x112f9ab,0x129f89b,0x0fcd549,0x09597ee,0x0c5c060, + 0x1369a34,0x0604b49,0x1229267,0x083015a,0x01c8251,0x0ca00e7, + 0x139af5f,0x13399d2,0x1bb6cd0,0x052a3fd,0x1688657,0x107ae73, + 0x0e62ba6,0x146c170,0x16c3872,0x0015987,0x180d1ea,0x02c42b0, + 0x13b231a,0x0f66908,0x0bb9b1b,0x1fb39f2,0x1cf9e66,0x12d42e5, + 0x01217c2,0x05747fd,0x1a5a6e4,0x06b93eb,0x1c8147b,0x0155fcc, + 0x02081a1,0x0e35d95,0x0c2d382,0x1e172e7,0x0657acb }, + { 0x074c8d4,0x02337e1,0x1344c4c,0x0c61532,0x0276517,0x1ca1afa, + 0x16329c1,0x00c42e4,0x0eb897a,0x0428203,0x1b84c11,0x1ddcac3, + 0x1bf38df,0x150bbc5,0x1d3eb3e,0x173d223,0x017b9ab,0x13b2e33, + 0x03c424c,0x0a9337b,0x1159b13,0x1bd39dc,0x103ad8c,0x0fd16d5, + 0x1ccf16f,0x1a9f960,0x0861f7b,0x1665807,0x0b9c625,0x0ea4c18, + 0x0e226b4,0x05e21ca,0x135eae3,0x1aade0b,0x070a757,0x1b6397b, + 0x0539db0,0x014623f,0x0ceed09,0x02590a5,0x03d2da4 } }, + /* 28 */ + { { 0x11f2865,0x015b743,0x035a5dc,0x1e28524,0x16cb639,0x1ac308a, + 0x08a8116,0x024650a,0x1f3b138,0x1ca1d68,0x081ba3c,0x0014e24, + 0x0ae6c22,0x11a6acf,0x024396a,0x1eeb385,0x140f6b7,0x1d5a97e, + 0x002fd59,0x0591bc3,0x0396f52,0x1956677,0x0607a5e,0x1d4b976, + 0x15819c4,0x1f7f01b,0x02ad474,0x1b330bd,0x150fd80,0x0b655e5, + 0x03789b2,0x12fc390,0x19d6b13,0x11abefd,0x0053de5,0x16b0563, + 0x07f4c7f,0x13c1108,0x1f98626,0x05b806a,0x002aeef }, + { 0x07ec9be,0x1c93796,0x0804ae9,0x1ce4b16,0x092f307,0x1d35a51, + 0x0a8431b,0x156e9cc,0x1e2bcc5,0x06042a4,0x0301ce0,0x1b70f77, + 0x0db4160,0x194f8ca,0x1bc14a4,0x09539ab,0x0146dda,0x0875c6d, + 0x17a88f4,0x1a87a42,0x1fae0b5,0x017e1a5,0x1b3afbc,0x10eaf4e, + 0x164d084,0x051d669,0x00b4d33,0x028026d,0x0d95e2c,0x13a10e9, + 0x0a02729,0x0f0dd54,0x1fd1d6e,0x12ff661,0x0db68a5,0x073d622, + 0x0077920,0x038dd56,0x0bac122,0x002962b,0x06b446c } }, + /* 29 */ + { { 0x1e8fe80,0x0f59712,0x085f206,0x0d30471,0x0b5f790,0x120c249, + 0x1a65a07,0x08bade3,0x098ea6d,0x056c56b,0x00b9016,0x15a97fa, + 0x0d5bae5,0x140920b,0x1b70c9e,0x0f94202,0x185a334,0x0c598d4, + 0x0a994e4,0x1b4c210,0x15fb0b4,0x16da461,0x072e46c,0x155f188, + 0x0817cd2,0x0e04f4b,0x0f37f73,0x14c6090,0x1692541,0x09b0895, + 0x05dc156,0x1f14541,0x1dcd712,0x02940af,0x08e8d73,0x0ab356c, + 0x132b609,0x0475f04,0x014bcc3,0x097611c,0x0861342 }, + { 0x0231d8a,0x01031d9,0x199ca24,0x13b34c2,0x10f6232,0x0d4f93d, + 0x03f9c1c,0x0fd55f4,0x0603f04,0x1e6c4b0,0x0a870da,0x14edfb2, + 0x16118cc,0x18ea41d,0x05398ad,0x0a4c468,0x0ddba70,0x15091e6, + 0x166d716,0x0ec86ff,0x0fa31a5,0x0126468,0x094c06f,0x0484f9b, + 0x0ad4410,0x0014b78,0x034ea9b,0x1cdf6bc,0x0a39960,0x0440039, + 0x0b73631,0x1081a7f,0x1afca12,0x0eaa0a6,0x08f77a4,0x1a53e99, + 0x0441734,0x1be2cc4,0x195f000,0x133399f,0x086333a } }, + /* 30 */ + { { 0x0f53b40,0x1d3a8f6,0x150b484,0x045ef14,0x0ff2c6f,0x1d72b6e, + 0x1c38bc4,0x11c1eb3,0x10e6174,0x0fc665f,0x1105164,0x1973ae5, + 0x170aade,0x064e6e5,0x0bb6149,0x1f8e0d6,0x12c1eaf,0x147005b, + 0x09ca040,0x04850b5,0x0afa89b,0x105b3ce,0x0a9fa9f,0x014dedf, + 0x18c264f,0x1cbae95,0x0c3a010,0x1daf62e,0x1730497,0x15a2e42, + 0x0f96a4f,0x0130dd2,0x12bf5d4,0x06057e4,0x0a71a88,0x1ea4d6b, + 0x199dc3a,0x0fa3e4d,0x0b3242b,0x1c57440,0x012b25f }, + { 0x1eea395,0x06bc519,0x117026e,0x11ec67f,0x07a9361,0x076777e, + 0x058a49c,0x018fd04,0x0c628ed,0x123bcdc,0x1a24e54,0x194343a, + 0x1091db5,0x0c376e4,0x09b8639,0x1e77f0c,0x08bfeb3,0x07f011f, + 0x09405c7,0x13fbc20,0x12de627,0x0e2af0b,0x194bb1f,0x1a9948b, + 0x08695c6,0x078a22f,0x02f6f04,0x05bc70f,0x03835e4,0x06f437e, + 0x148ac45,0x0fc216c,0x1aba456,0x13c7f4f,0x00a8e43,0x148223b, + 0x0edf0ac,0x15b0e15,0x12dd15d,0x152e959,0x0216279 } }, + /* 31 */ + { { 0x047f747,0x06d5fa0,0x087b053,0x1b8262b,0x03ca233,0x12e8538, + 0x12f4d03,0x0d2b3cf,0x1bb4138,0x1e86274,0x07ef607,0x11621e0, + 0x1d189d0,0x13b5c11,0x112710a,0x00142a0,0x0a1398b,0x040e112, + 0x1a05e79,0x109c9f1,0x01e9080,0x0a34c72,0x1f62be6,0x0217e5d, + 0x0e37c56,0x0878f18,0x1e9f49e,0x1cd4087,0x1953884,0x1306598, + 0x1f6765b,0x006f33b,0x15f986d,0x1c817f3,0x1c47e3f,0x1c76951, + 0x1588416,0x0a29bc3,0x14d7bea,0x07f304e,0x020683e }, + { 0x0378878,0x0171368,0x1e1f2d6,0x074f28a,0x1e214c2,0x134459c, + 0x002fe3d,0x0e027a0,0x1405152,0x0a46a7a,0x047d75d,0x02ba802, + 0x027113c,0x145ffc8,0x1d6949a,0x08b9877,0x0109b49,0x0ded358, + 0x10bce81,0x198e9d7,0x1fa183d,0x0221f7e,0x0abbd8a,0x0b8b7e8, + 0x00ee956,0x01d6973,0x1564bc9,0x1e1f421,0x03bf514,0x05990de, + 0x1d1ab96,0x0c0aed4,0x13b0868,0x1840d40,0x0fe135c,0x1217804, + 0x12dcee5,0x081d501,0x11e567f,0x1ea4fad,0x05e416b } }, + /* 32 */ + { { 0x06cc23c,0x09bb001,0x016090c,0x1d6b652,0x1819aae,0x09770bf, + 0x1cbe317,0x0055244,0x1ee5cc4,0x02473e5,0x1bc1f60,0x0ddcefb, + 0x1edbc7d,0x1b57c10,0x15a4913,0x17712c3,0x0ed996c,0x02fbcb3, + 0x1a85569,0x162fd52,0x0d56f81,0x1801f9f,0x0cb67bd,0x1054b65, + 0x05906e8,0x0c02f37,0x0aba51c,0x0df420e,0x0c76f48,0x1e28b2c, + 0x080d367,0x19606b5,0x1603dc0,0x13240cf,0x1fadd6f,0x1f6f673, + 0x0f04a9e,0x03aaa56,0x1f78f2a,0x1d90f69,0x04ff682 }, + { 0x0a10ad5,0x0b13fe8,0x1d14c49,0x052d1cd,0x1fd45c7,0x1508b1b, + 0x0f5ae01,0x1c65303,0x1de5033,0x096f0e6,0x1e2622e,0x08bd7e9, + 0x1c3b44b,0x0d73f0e,0x06e625b,0x1b0f194,0x05a0778,0x1a90b37, + 0x1445a11,0x08e57d4,0x144582d,0x157944a,0x1ef74e0,0x0dd8993, + 0x116025d,0x1811176,0x12d954a,0x0c29d63,0x06210f3,0x0fb9d0f, + 0x09d8f17,0x00434e9,0x1160285,0x05ea6f4,0x1003197,0x1348994, + 0x0f15e29,0x058c3f0,0x141f123,0x11c6804,0x051eb81 } }, + /* 33 */ + { { 0x12100ab,0x0e8bc5c,0x00e47f0,0x012c0b7,0x1f2e3d6,0x0f2ce86, + 0x10956dc,0x008254f,0x114fcbe,0x1c5b33a,0x141abcf,0x126ab3f, + 0x070e8a3,0x0901068,0x0c99408,0x0f7caac,0x0d1528e,0x0334b7e, + 0x11edd95,0x10a2961,0x05b5658,0x062c895,0x033603e,0x04996fe, + 0x1ef04f3,0x0bac5d7,0x1f1b68f,0x16a7dd9,0x11df2f6,0x046c18e, + 0x1b7b7bd,0x0e70256,0x136b965,0x13018f9,0x192bb98,0x17905d5, + 0x1244f09,0x055e996,0x191fcc0,0x0aa63b2,0x08b0af9 }, + { 0x0603544,0x00c0517,0x167addc,0x0644359,0x0b573ac,0x0038191, + 0x1d99589,0x07a742f,0x1b89abc,0x09f3a56,0x0c896ab,0x1c75af2, + 0x0b8a3d2,0x17812b2,0x1eee813,0x1a56a8a,0x12ffc2d,0x0443ab2, + 0x19c50fa,0x00ba2bc,0x0d70d29,0x0101724,0x1b6212d,0x0c6d4ae, + 0x19219c7,0x06f837c,0x04d78de,0x11b8684,0x064a02a,0x0b9e886, + 0x19a5707,0x1982af4,0x16a4ece,0x051aa66,0x0722389,0x1b75b98, + 0x1839329,0x1278d94,0x02b4200,0x0929b49,0x05363e5 } }, + /* 34 */ + { { 0x03fc641,0x091dbf1,0x018c7d5,0x1f0ccce,0x1e54e72,0x004e97f, + 0x057d638,0x1c25294,0x18c57f5,0x101ccbf,0x159373c,0x049962d, + 0x1ba2297,0x05d517f,0x1ef93f5,0x11dacd2,0x0460a6e,0x11fa83f, + 0x014214d,0x1c74baf,0x02080af,0x0ecaa04,0x1bbbdb3,0x18846f9, + 0x1d889f2,0x129b80f,0x0970e14,0x12db107,0x0212f14,0x13f6b95, + 0x1378971,0x03fef1f,0x1416783,0x1a0a325,0x001305b,0x0fd32ce, + 0x045b069,0x02e1d0e,0x0c30fe9,0x0307f7a,0x0633340 }, + { 0x0fbbbce,0x0d06651,0x1d10e72,0x1954196,0x076f6e5,0x1c7671c, + 0x00438d0,0x10539cc,0x013802d,0x1568a47,0x11686c2,0x18c139a, + 0x009c3e5,0x1de7e0f,0x172e165,0x09ba10e,0x190d858,0x1d8cffb, + 0x0070a8a,0x11703db,0x07e3259,0x17815f0,0x0462f7c,0x0ecb9d2, + 0x1c8eeb9,0x0d703a7,0x02c93e5,0x04bd3b1,0x18f09d1,0x166e064, + 0x09ceec4,0x1416e96,0x06aee07,0x03be725,0x0be7020,0x1e8e47a, + 0x1ea8026,0x0a23eb5,0x02dce56,0x0b82c50,0x093a707 } }, + /* 35 */ + { { 0x15b27f9,0x1f7f138,0x048c9ae,0x0454501,0x0935a5e,0x0c51355, + 0x08ebff5,0x128bbbe,0x07c1386,0x0641f0b,0x08854d5,0x1793125, + 0x1544799,0x0dc684f,0x1b91c42,0x1d4d09c,0x016d588,0x1631d7b, + 0x00eac6d,0x12ce0d1,0x13365e8,0x101e904,0x0f04e4e,0x1847bb4, + 0x1292192,0x121e817,0x0b73dba,0x16e196f,0x1559e1a,0x07543c8, + 0x02c490d,0x0dae1fe,0x00680db,0x15d2282,0x1948a0c,0x1e3421f, + 0x05f0cb8,0x0fce047,0x107f75a,0x1588962,0x01a7422 }, + { 0x140b675,0x0ee974f,0x1ce70ea,0x07f98e3,0x0a7c660,0x0471a11, + 0x0698465,0x1083127,0x0ed0ab4,0x19db0ac,0x0729ae3,0x1b2fdc6, + 0x03a3aa7,0x1bd46db,0x07a197b,0x0c5c978,0x0092c7c,0x198afc6, + 0x1d71b43,0x00f11f3,0x1ec5a26,0x14a5b79,0x0c60cc4,0x169b093, + 0x1bcd636,0x14db9d6,0x02f1a66,0x0dc2912,0x1175e76,0x086c150, + 0x13efcde,0x1f8a794,0x143605a,0x1b048bf,0x111e1ff,0x0caefed, + 0x000c82b,0x1e3aa93,0x1667209,0x0613a4a,0x00944d6 } }, + /* 36 */ + { { 0x0ab9620,0x15b1f73,0x00233f7,0x1af0d9b,0x1ff4fa6,0x119059e, + 0x1760915,0x02a28bd,0x0c49439,0x172fc31,0x0cfe1ca,0x10276e7, + 0x099508e,0x1297cbd,0x16017cf,0x136c477,0x028c982,0x07b8dae, + 0x1b833bf,0x098e1d0,0x136eb39,0x1491ded,0x14d3ec6,0x1c4fcb4, + 0x15862db,0x0b4eb27,0x0e0ead8,0x15c47be,0x0828cbb,0x18d893e, + 0x02b75b7,0x07460f5,0x101899f,0x0efb30c,0x1966047,0x0e6d990, + 0x19943b7,0x05bbba3,0x195da8f,0x106dfb0,0x07d89f3 }, + { 0x1f92b2b,0x1212164,0x0af7e15,0x0b88dc6,0x100c6a7,0x0cd2e2b, + 0x1a2ddfe,0x0d127ce,0x0031495,0x177f42c,0x199c26d,0x1433859, + 0x13bbfe8,0x1737624,0x068ec6f,0x1851ae4,0x0a9c371,0x0937777, + 0x145df87,0x1022bc2,0x05a5d79,0x0758345,0x15efcef,0x1a56965, + 0x1a22046,0x0fe6fc6,0x0d66fa7,0x1be132b,0x040b793,0x0bde3bb, + 0x11725a2,0x0b457a7,0x00cf4c2,0x1f3a267,0x15ba26b,0x162de8b, + 0x1a8509b,0x1f9d659,0x09b9ad4,0x03ec7e5,0x0449af8 } }, + /* 37 */ + { { 0x16d9377,0x0789950,0x1e7b0bf,0x06fc345,0x1ab377b,0x08cd72c, + 0x084ba1b,0x162e5c3,0x0d013bb,0x1589733,0x1d9aeb4,0x00ab96b, + 0x100972e,0x1ccf55a,0x0778700,0x0bd85a2,0x0fdc65f,0x1e0f98a, + 0x0a7fd64,0x0230831,0x06e6fc3,0x1670292,0x17dcf07,0x04a0adb, + 0x1136316,0x10ce146,0x1dbec97,0x0153b7a,0x1cd2d73,0x0922422, + 0x0b4127b,0x1a6dd0a,0x179b83f,0x04541e3,0x1f1fda3,0x070b46b, + 0x095e803,0x0df8f0e,0x06bd4a6,0x1864112,0x00e8617 }, + { 0x1c81b5c,0x1030133,0x1cf14dc,0x1bce6f0,0x0fa89dc,0x0a27e81, + 0x0c2c2a0,0x10654e8,0x126208c,0x00362d3,0x0903d4c,0x0cc1b1d, + 0x044e066,0x04b209d,0x14097e6,0x0293f3b,0x0cc46b9,0x15ef9c0, + 0x0849730,0x0acc321,0x1c37801,0x1ba93c9,0x0135a8e,0x0f4c5e4, + 0x013746b,0x0bc5b00,0x0161756,0x139fc4d,0x15fe66a,0x065c41c, + 0x1db72b4,0x08d64c3,0x0b468fc,0x0c90c5d,0x17be767,0x05941de, + 0x1e45240,0x03ea542,0x1da1f14,0x1e264d9,0x06f4404 } }, + /* 38 */ + { { 0x1ebd3ff,0x0c905a7,0x0eea8f8,0x11fbfa5,0x0a6234d,0x0d4c14e, + 0x0bcab86,0x0416fa3,0x0c6f5bc,0x1ef0b08,0x0e72a48,0x17e7b54, + 0x0be204d,0x16c6385,0x0b7a6e1,0x06e1654,0x0377c9d,0x1139706, + 0x1595443,0x02980dc,0x16b0809,0x142be5d,0x0d8479e,0x04cd4dd, + 0x1c6efd8,0x00e03b7,0x18c2560,0x1f5869d,0x024063d,0x00515cf, + 0x115a7fd,0x0f0f54b,0x1ba31a9,0x1866953,0x1f7ccf1,0x081c9a3, + 0x0895f07,0x1f18993,0x1c78a40,0x1f0ff6c,0x0905771 }, + { 0x0062bee,0x0dd06d2,0x07e5466,0x1929afb,0x18e7238,0x0491600, + 0x0a6f078,0x0bfea7e,0x1b12d85,0x14d9540,0x0328a77,0x1ddadad, + 0x1f649f3,0x028604b,0x0b7f0d3,0x13140c9,0x0b99db3,0x040cb25, + 0x0961c89,0x0b388ef,0x103a00d,0x0b3a62c,0x027fa8e,0x0087ba0, + 0x1d8ee15,0x0103557,0x197c7b3,0x0ae434d,0x19b7b4c,0x124186d, + 0x0aadb5a,0x0cd91aa,0x0ffc617,0x0151383,0x075ab32,0x107bc48, + 0x07f2f7a,0x02f8291,0x17b3018,0x076c809,0x06a2295 } }, + /* 39 */ + { { 0x0fce389,0x096c7ba,0x1592491,0x0055f4a,0x059634c,0x16bc128, + 0x132efc3,0x01b26ef,0x137718e,0x0fa022d,0x1a69362,0x1cfb3f4, + 0x1a11074,0x194ad85,0x1c2ec1d,0x1dbccba,0x0adf107,0x1d916aa, + 0x068a71e,0x1347b14,0x03ab5c3,0x016bcaf,0x0dc8db0,0x0b132a2, + 0x02d002b,0x1717b94,0x195e42f,0x1c44cb7,0x065ea25,0x1508d47, + 0x0f64783,0x0c0039d,0x071a708,0x02a0107,0x1d68b07,0x022d201, + 0x157f698,0x196ae01,0x0d09f0e,0x140c33c,0x0528c9e }, + { 0x126c577,0x0435a2f,0x15147b7,0x1128717,0x1807470,0x12c153f, + 0x0404de4,0x13e5bfc,0x0de1e56,0x0475650,0x168d5b8,0x1df534a, + 0x165f952,0x124bb10,0x1602d4f,0x0e3e549,0x055cd5d,0x0695b2c, + 0x1b3a8fc,0x0e097ec,0x03ca246,0x0fa4919,0x064fd90,0x1b6264a, + 0x1855c9a,0x1295340,0x18b4675,0x0daa459,0x02ed7b8,0x0f882dc, + 0x0a54d82,0x11c2a1a,0x10f0094,0x1f4489d,0x0fec2c4,0x12475b1, + 0x1794b44,0x18aab67,0x13d5f2e,0x126e717,0x0200f90 } }, + /* 40 */ + { { 0x188387f,0x117e2c1,0x0f17e6c,0x0051d10,0x0f26f17,0x1bcb9e6, + 0x0ae4346,0x0e288f9,0x0f6ec91,0x0aea751,0x136f023,0x0931861, + 0x0b2e16f,0x04311e1,0x04a4431,0x18a8bb9,0x1b030db,0x0758a48, + 0x137886c,0x1bd65c2,0x10f4631,0x1317f41,0x0128841,0x1383e7e, + 0x0979c37,0x1cad263,0x03ec1a9,0x14e656d,0x19dfa98,0x193d0b0, + 0x06ce910,0x11b7c59,0x1a307d3,0x04ff548,0x03480e6,0x1f27379, + 0x0f4a331,0x155d790,0x15770f6,0x131ba1e,0x05c307e }, + { 0x1b233da,0x070621a,0x0616ef1,0x0a45edf,0x03d2908,0x1812347, + 0x0b486a2,0x1cf33ba,0x1a96916,0x1c7a074,0x0f33b65,0x10d8c29, + 0x0c0327d,0x19483b1,0x1a5540a,0x1e5db2b,0x197a879,0x187fe90, + 0x0382f4c,0x0ca26ea,0x04c4c43,0x050413e,0x09b0c52,0x19f8164, + 0x012a83f,0x0c4e3cc,0x18c64a1,0x07b1a2f,0x10f42dc,0x167f441, + 0x0fe2d5c,0x0960ff0,0x0d9ff92,0x08a47be,0x0540294,0x1866395, + 0x0c59f9a,0x029cb42,0x11e1743,0x1f58286,0x01df16d } }, + /* 41 */ + { { 0x0bcacc3,0x1da5634,0x033f31e,0x1e861eb,0x06ded34,0x10c2ad0, + 0x07d3f51,0x1798b3f,0x045c9f0,0x0a48cca,0x17224bd,0x1d8c86e, + 0x1adc5f7,0x1e42cc1,0x01c23c4,0x1a10e37,0x0c482fc,0x1d9952e, + 0x15ad303,0x19b86a5,0x1b2defd,0x0245637,0x12ec93c,0x120c8e2, + 0x0d4f533,0x1622cc1,0x1ee0e8e,0x0c5d6a5,0x17a2231,0x0f94119, + 0x14dc4c3,0x19787b7,0x0e7b802,0x1d6076e,0x0564919,0x1d1672b, + 0x1b56717,0x09e9740,0x0985c87,0x0a08ca2,0x0729a7f }, + { 0x020f90a,0x168d542,0x01561d3,0x1c1fc99,0x0368e19,0x1f3a57b, + 0x12aaac2,0x1536c5a,0x08ca60c,0x17e6240,0x16a19dd,0x0b4aec8, + 0x0cf310b,0x0ed8d92,0x06eb26f,0x0b68826,0x11d2dea,0x177bbeb, + 0x0bf3193,0x0da420e,0x17f0470,0x08b39eb,0x0a6e49a,0x13c0cc6, + 0x00bf3e8,0x0a01170,0x0dd01df,0x0e5a19a,0x1232e24,0x0206c14, + 0x0ccf884,0x071b90a,0x1916dfb,0x07b3397,0x166c52e,0x1a91776, + 0x144be19,0x0f4fa56,0x0757067,0x092465b,0x07f6d36 } }, + /* 42 */ + { { 0x0794819,0x0326f37,0x1684ef4,0x1df05d7,0x1a6b694,0x0f14022, + 0x1ff82e4,0x1a43e02,0x107a43c,0x08698f9,0x10cfa46,0x044cc60, + 0x146c26f,0x055fee5,0x1222a9c,0x0238174,0x085a464,0x020c6c8, + 0x1fed620,0x069fcd7,0x18491b9,0x1bf1007,0x1d74788,0x0a827b6, + 0x0d63fa5,0x1bbef82,0x1788ecf,0x042ddae,0x11bd30e,0x136587c, + 0x0268161,0x0ee538a,0x0c395d9,0x1596bc2,0x062114a,0x0dd92fc, + 0x0093d68,0x1be0fc8,0x021b232,0x12ac51e,0x02d0323 }, + { 0x044b4c5,0x04a03a5,0x1262a07,0x1398e05,0x1984687,0x186e4bd, + 0x08a1f3a,0x04396a0,0x06e3aa3,0x0180893,0x095b08c,0x0ec7c98, + 0x05c0ac8,0x12ada42,0x00d3483,0x1e6b6ca,0x040f240,0x0554b50, + 0x13dfbb7,0x1a4da6f,0x0656046,0x109dc08,0x18a96a3,0x1ae1856, + 0x04b9783,0x147c302,0x0167936,0x1f75ff1,0x17f5d12,0x080d2a2, + 0x15e4a76,0x16a636e,0x09e1eb2,0x14b9ce9,0x0f72793,0x12429b5, + 0x0eaa9bd,0x0b927e2,0x0ee6d6f,0x1663df3,0x0734c12 } }, + /* 43 */ + { { 0x0f9b086,0x11e1749,0x151263f,0x1d67fa8,0x0641b93,0x01632e2, + 0x0822d70,0x0848f9c,0x1c4f032,0x1296e50,0x14a7da2,0x0fb2cf3, + 0x14b5ec1,0x0a037af,0x14bfb42,0x1502223,0x1dc0d9b,0x19307b1, + 0x151ca8f,0x160ade2,0x10e6de2,0x0f80394,0x06c5c36,0x16b91f2, + 0x03e8db6,0x1f75171,0x073cd30,0x08b4507,0x173ee23,0x0a308dc, + 0x1166f71,0x17649a3,0x1bda6c2,0x0a0d0b2,0x0e8cf18,0x032faa5, + 0x1d2eb20,0x1d8b094,0x1927d1e,0x10e43f7,0x07c558a }, + { 0x1350fec,0x02d291f,0x1302e52,0x0ad471a,0x016678c,0x0d53268, + 0x11a8835,0x1c91de6,0x0d96da2,0x02ed501,0x11ecf2e,0x09d49ec, + 0x0c845ec,0x06af4a3,0x1469b28,0x1e95781,0x1c14fa9,0x1a0ec68, + 0x122c4c0,0x0e598b3,0x1bfb439,0x06a1a7f,0x19f87d2,0x13a4630, + 0x0e93a81,0x11f9a86,0x01b77bc,0x13ea612,0x0cf12c4,0x167c900, + 0x1f0f0b9,0x0c80865,0x0691cc1,0x0b5a921,0x12d1c92,0x1d7ffee, + 0x020a97b,0x093e4f8,0x10d2111,0x194f678,0x034cd7d } }, + /* 44 */ + { { 0x1e7fe87,0x0bb0d2c,0x15cbc0c,0x14008f9,0x11eae31,0x1187b15, + 0x0b9a3eb,0x0864f20,0x1b71db1,0x1337a46,0x00e3d29,0x0cf01c0, + 0x0d75ee6,0x015eebb,0x116b19c,0x19ab876,0x028a0d6,0x08697dc, + 0x16316c4,0x1cfe3b3,0x1e9627c,0x120905a,0x0507f83,0x04cf86e, + 0x1b984b9,0x166cad0,0x07580c4,0x040dcb1,0x1493565,0x1a176d2, + 0x0b0619c,0x00e18e9,0x14520b9,0x1d8599b,0x0ed6555,0x084e079, + 0x06ed8c1,0x10face5,0x0e21fd8,0x18557ef,0x07ceb1c }, + { 0x17fd65b,0x1d2dded,0x15f0191,0x006d928,0x18d45cc,0x0938c56, + 0x0676e78,0x1638db5,0x0e93a7f,0x08eddfa,0x159a87b,0x12b97a2, + 0x194512c,0x0de0648,0x186e803,0x0a4d290,0x0989e7f,0x11e3661, + 0x0506aab,0x12c2a01,0x18e3671,0x07e4629,0x0ff3d74,0x0b4aa3f, + 0x09929a2,0x19356b7,0x145f283,0x00e2130,0x09ef7e9,0x1c757d4, + 0x125d0ed,0x0e3568a,0x1d5ea31,0x0e1b69c,0x0fcf9b4,0x1ae885e, + 0x059d568,0x1341f00,0x1b57096,0x13244f9,0x01f629a } }, + /* 45 */ + { { 0x05a1c3e,0x0eed672,0x117e249,0x0a83eea,0x12d2936,0x13fc143, + 0x0bf2cdf,0x1a48ac4,0x13e4c79,0x011a289,0x19175a2,0x1f09384, + 0x195dffa,0x0ca4015,0x1e3d376,0x13f4060,0x1f09d33,0x02b3493, + 0x1f64773,0x00143d3,0x0bd79a5,0x0005585,0x1380206,0x129cbbf, + 0x135a381,0x0446cb8,0x1e62b7c,0x1d0ec60,0x05a2a79,0x00dc4d2, + 0x064eebc,0x0f11687,0x1ed6154,0x14cbeb7,0x1c8b9de,0x1b301ca, + 0x0a378ee,0x0487fd1,0x0168aab,0x14517b0,0x04a75fd }, + { 0x1e74cbc,0x147ddaa,0x1c97426,0x1df5631,0x137738c,0x12761d3, + 0x0eb5a5d,0x0621f84,0x1e7e0ad,0x0d3e9ad,0x07326f1,0x0d1dc90, + 0x14e75e0,0x1ea5761,0x10baa64,0x0c789e1,0x1e80d4a,0x0789927, + 0x06c164b,0x16f82d3,0x146b5db,0x06d3f07,0x110b59d,0x001f5d4, + 0x166c7a3,0x041ad2e,0x04ccceb,0x107b904,0x008496e,0x0097462, + 0x105c3be,0x133debf,0x0e1dcb6,0x074314b,0x1c6c5cd,0x10dc56e, + 0x183507d,0x114e6e2,0x05e6811,0x15c47b0,0x05819f9 } }, + /* 46 */ + { { 0x0a78811,0x14890b5,0x1f0f665,0x084207c,0x164ee8f,0x1cf34c7, + 0x041c08a,0x1bdbbe0,0x04f582c,0x1000fcf,0x1eb06b9,0x115e5d9, + 0x0924a60,0x031c980,0x1d31e10,0x05222dd,0x0e6ebf7,0x0293175, + 0x113b968,0x1a15eb1,0x1bc7ddb,0x08766c3,0x01d6bfe,0x049e229, + 0x1b34c6f,0x0b917ee,0x07a197c,0x1020850,0x0c1b9a4,0x1213443, + 0x07e55a4,0x13de846,0x15f3208,0x1f41737,0x0b3f429,0x115eb0f, + 0x1ac395c,0x0b8c8bc,0x09d4359,0x07826c9,0x0745960 }, + { 0x01ae519,0x03adffa,0x0944709,0x0295f1e,0x14401fb,0x1d961e9, + 0x1f34abb,0x010e1bb,0x151cdaf,0x1969c2d,0x02ec666,0x04ad041, + 0x168531c,0x0619f9f,0x12277d9,0x02ed22d,0x0992457,0x1611e7d, + 0x1b4042e,0x136a3d0,0x0313233,0x069131c,0x0236c3a,0x1fdbd6e, + 0x1e17900,0x178fbb4,0x0e8da1f,0x1fb2db9,0x0764753,0x1591c8a, + 0x1773411,0x0188b91,0x1ff2064,0x01ebc79,0x1ef6e0d,0x01dfa2c, + 0x0b77ee9,0x1e65b6a,0x1ed1524,0x027679e,0x0330255 } }, + /* 47 */ + { { 0x1eaaca1,0x002349a,0x0408dbc,0x0b12232,0x0c384b7,0x094aa60, + 0x159979b,0x1af966e,0x1b1e9d6,0x1c8ccdc,0x109d5f2,0x0693853, + 0x1075852,0x1c739c6,0x12f46ea,0x1484f13,0x0905923,0x0cdc6df, + 0x03f8622,0x0ef27c3,0x0083a23,0x0bd3a17,0x0909c5d,0x1d7ac27, + 0x179d24e,0x1bbc624,0x1353cb3,0x0064a0a,0x0705de4,0x1048cac, + 0x0ea8ee2,0x067b333,0x1191bd9,0x1f70f0d,0x0e90ec3,0x0975fdf, + 0x1facdf1,0x1d68c21,0x15872ce,0x160870e,0x09328ad }, + { 0x106b872,0x027407c,0x1996afa,0x00f04c4,0x105523a,0x0c667bb, + 0x1a9f8ce,0x047b138,0x1f55b53,0x1d5aa8e,0x137aa0b,0x1d940aa, + 0x0da0578,0x1baac4e,0x09948f4,0x1aea1de,0x042864a,0x16c7eb1, + 0x1e3f87f,0x04ff8a2,0x142293f,0x184efc3,0x1ecf9bc,0x0a1a0a8, + 0x0e49e37,0x0509431,0x097700e,0x1b218d6,0x1b682b7,0x1711426, + 0x02b0686,0x1310326,0x1f3dab7,0x1f05223,0x154aebc,0x0a61cd7, + 0x162d25c,0x00012df,0x1579c1a,0x19f5ba1,0x00aa1f3 } }, + /* 48 */ + { { 0x0a10453,0x110c811,0x042ea60,0x1854074,0x1d1eb91,0x12379de, + 0x1765659,0x18d5f76,0x0f38b6f,0x0c6f1a2,0x1f28769,0x07cb719, + 0x04ce47c,0x07b86d0,0x16385b4,0x05dadf9,0x09bda26,0x156221a, + 0x15b8be3,0x01b0f78,0x0e58932,0x040c89c,0x0738fa8,0x1646d81, + 0x02dffa2,0x186d2c3,0x1239fbe,0x161f34b,0x0c78eb6,0x01958b5, + 0x0bd2d4d,0x0e136a3,0x1f43105,0x0cb1437,0x1be23d4,0x1a11c46, + 0x0ed403a,0x09f8bb7,0x151787e,0x1c12c6c,0x0559337 }, + { 0x0fd807a,0x0fb9c6c,0x0888c37,0x1b56262,0x14e0ec9,0x0d7de1f, + 0x1d36d89,0x12a2945,0x09f12f8,0x0db8302,0x0113f75,0x1847586, + 0x0fb46f3,0x1aa00a4,0x08cb47f,0x1caa836,0x0f539b4,0x0b0da2c, + 0x175c2dd,0x0964941,0x01d9f69,0x0c944ac,0x03f190a,0x0bfc45a, + 0x149beee,0x1b1e02e,0x1da862f,0x15e688f,0x1929d67,0x0ee13f8, + 0x033a5a8,0x182aa3d,0x0fe6028,0x0a7d135,0x0bccad7,0x084fb59, + 0x145c2cb,0x0b18de2,0x0534d28,0x1f36192,0x0930070 } }, + /* 49 */ + { { 0x1a9bc05,0x1962f34,0x0dcf4bc,0x0cb1389,0x0a5c19c,0x132fce0, + 0x0797a51,0x07212b9,0x1bcfb4c,0x1587949,0x0df0c62,0x10ee3bb, + 0x08b9070,0x1359c02,0x13a5961,0x1b37b12,0x0cf606b,0x0f8cd48, + 0x1bf4b5a,0x1ab1bf6,0x0a69cc1,0x07230ec,0x021b731,0x19c9063, + 0x1c277f9,0x141622a,0x19d97e2,0x0934b32,0x1adc8d7,0x134661d, + 0x0acbff1,0x122259b,0x0018396,0x1e3e59c,0x170ec90,0x09530f2, + 0x010a222,0x1af9880,0x178521d,0x082b0f6,0x0043a21 }, + { 0x0873752,0x14ede1d,0x1fb9eef,0x085e885,0x0e1493f,0x0610c0f, + 0x08b2306,0x1cf3039,0x0e29769,0x0671848,0x1a317c0,0x1591bce, + 0x1eb4626,0x1a6bb3b,0x1a73918,0x129cc67,0x0ade0fa,0x1fc4e16, + 0x07d6d6f,0x0b98228,0x012c04f,0x1b11146,0x09597dc,0x00b99ca, + 0x1706a0c,0x027f8df,0x1ef921f,0x1a0ffff,0x19f1a45,0x1e04d24, + 0x000fb10,0x131b290,0x14e79bb,0x1897c27,0x08581cf,0x1b1466b, + 0x0f970d6,0x1af57b8,0x02ba12e,0x0f7e49a,0x018d074 } }, + /* 50 */ + { { 0x0601faf,0x1e3be42,0x1dc9634,0x055e383,0x09465be,0x0b6c036, + 0x19e6344,0x079fec4,0x0d5b0d9,0x0cb6063,0x19c8e8e,0x1aeabd8, + 0x092fa1a,0x01dd29a,0x1aa0510,0x09b152c,0x0222ac3,0x0ee264a, + 0x159d619,0x08e3bdd,0x128fddf,0x0bca9ea,0x162b296,0x1d7ecfb, + 0x063b524,0x069d972,0x05f896d,0x0b0490e,0x159daa2,0x16dd218, + 0x1008f16,0x1066aea,0x058f9c6,0x058d32a,0x169fe4e,0x039ed0b, + 0x0efed23,0x0d27ed6,0x1796660,0x1da1176,0x0711093 }, + { 0x01f161a,0x11fe320,0x1a1c4aa,0x012e98b,0x1735856,0x1aefc17, + 0x14bec5e,0x1329544,0x1a48e62,0x05c1583,0x1611f6c,0x02ae53b, + 0x0600234,0x0294e2d,0x1953401,0x1ea71e3,0x19e6d98,0x1e60e29, + 0x034eaf2,0x0c56a65,0x10cd361,0x1c15427,0x1d68de4,0x1dce908, + 0x1a81b4d,0x18dfb8b,0x0d308ef,0x0d9e6bf,0x1e8b3e1,0x014fbc3, + 0x0c1ff47,0x0b36f35,0x1da7e68,0x16305db,0x028217d,0x0a0e420, + 0x07ed48b,0x0200acf,0x05f50c6,0x1b49b39,0x017898b } }, + /* 51 */ + { { 0x01b8cf8,0x041ec57,0x015b361,0x05d3451,0x123d4b4,0x0525e11, + 0x1613c81,0x1f4ec66,0x0ca7a69,0x1059114,0x1eeac93,0x1517eea, + 0x0a8afbd,0x1662fce,0x0c90221,0x12b870b,0x013d41a,0x1a3fda4, + 0x0aaaf9a,0x178a798,0x199d3f1,0x1f8d68a,0x1c8b368,0x03d5363, + 0x0c081c3,0x1608d97,0x0c05852,0x091e609,0x0fa7ab0,0x0774e35, + 0x0f738c7,0x08281b8,0x1af7633,0x055dd2a,0x0cdf73a,0x1d096f5, + 0x07cf3ef,0x0f3b246,0x1aac943,0x19e2a6a,0x073a88d }, + { 0x0e83b39,0x1414403,0x0df4fe1,0x073e880,0x077a441,0x0de420a, + 0x02c3c5f,0x093f20b,0x154d175,0x0db27a7,0x01fff8b,0x14d5e46, + 0x01a23ce,0x0789313,0x0fbf555,0x0fe4c72,0x18a10f3,0x097a732, + 0x13b878d,0x06f9c7e,0x1e8ba44,0x13d49e6,0x193bd0a,0x1355202, + 0x1c9f493,0x06a0ef5,0x08f5ed7,0x08447ad,0x0a3acc4,0x1508fc4, + 0x0b5e269,0x058c114,0x0fb9df8,0x0b6032b,0x038eefd,0x01cf3b7, + 0x068fa30,0x02b5793,0x1a879cf,0x02f5c72,0x052f32b } }, + /* 52 */ + { { 0x114f71a,0x09260f3,0x14655bd,0x0535bb0,0x01be126,0x056df1e, + 0x0276197,0x0935b23,0x05a0fb6,0x045fae4,0x064b676,0x152443a, + 0x0f9efa6,0x17b925b,0x1fa0e25,0x02339c7,0x024b250,0x0761fd7, + 0x0b834f0,0x15f3ec5,0x024d4b6,0x05eb0cb,0x03f3ae8,0x1b6dc75, + 0x1092b2f,0x094bee1,0x18c98f3,0x123b46e,0x1c43bdc,0x1b0f7ca, + 0x164c301,0x19bd689,0x1136400,0x0698ec4,0x1a110f0,0x1ffafb9, + 0x1871899,0x1f61d8c,0x16305e3,0x051dfbe,0x079e14d }, + { 0x1b40c55,0x1111acd,0x090b8e0,0x1a1da0f,0x0a27202,0x1c60fa0, + 0x106a520,0x11c91cd,0x1d864a7,0x1af9253,0x115724a,0x081418d, + 0x087e7f1,0x07096a8,0x0b0412b,0x03c21cc,0x07ec11b,0x0cd850d, + 0x1eecf75,0x144ebf5,0x0b30fd8,0x1f4d1db,0x17fcd53,0x0c05403, + 0x05d9e46,0x0fbad08,0x164eed9,0x1a6e369,0x02fdeb3,0x1f8587c, + 0x1176972,0x1bc8d0a,0x001229b,0x0a8bf23,0x02e71cf,0x04a0bc2, + 0x072ff49,0x07d2a0b,0x1b389df,0x11532ac,0x00d8ec2 } }, + /* 53 */ + { { 0x1eee995,0x07b9f65,0x0030053,0x19a923d,0x12eb88b,0x15d2ea5, + 0x1b2b766,0x09ac2b4,0x19304c8,0x1bea319,0x00f268b,0x03a5156, + 0x14ba050,0x08dd5dc,0x1dc8f7a,0x0aee591,0x1775040,0x06442fc, + 0x1ff2c25,0x03a5678,0x071ab5e,0x0aefcb6,0x187b9e6,0x0c8933c, + 0x0daab34,0x0995c64,0x157d81e,0x1684bbb,0x043587d,0x0e50d89, + 0x101c094,0x13f8e86,0x0d7d3be,0x1564493,0x0c43240,0x1f182f2, + 0x0559a74,0x09160aa,0x12bf1c9,0x04f86e6,0x086001e }, + { 0x1693947,0x005d2f3,0x18ac4ec,0x1c02580,0x0478641,0x0a48543, + 0x0e383a1,0x0bdc348,0x1d9574d,0x0b9eddf,0x0ee9854,0x171937a, + 0x159532e,0x0f9f503,0x106f2e1,0x125723e,0x0478cbb,0x0560e61, + 0x1be406d,0x08c91c3,0x12ee0f3,0x0f6959d,0x1764a74,0x1aeb7f9, + 0x11eabc3,0x0692387,0x1c4e73d,0x19b78de,0x0249535,0x02a6f82, + 0x00f3619,0x08ff967,0x0079812,0x1c9860f,0x06d05f7,0x0173e41, + 0x114ebc0,0x12fe188,0x11b0508,0x19668f2,0x0020591 } }, + /* 54 */ + { { 0x15e0af4,0x01b9093,0x092f8c0,0x1fcf149,0x121141e,0x1aba42b, + 0x1f3db45,0x13cccd9,0x1168e65,0x1d0eb9b,0x010bb97,0x1ca81c5, + 0x16263e3,0x0a45eaf,0x1b30f52,0x020955b,0x03d246b,0x000cef0, + 0x0d0f606,0x13d207e,0x0d31f8a,0x052d860,0x12d5ee9,0x1c4ecbf, + 0x0c50651,0x1b3c123,0x1d9466f,0x018aea3,0x119a018,0x0100790, + 0x1d17c17,0x0f043a9,0x06487b8,0x01d033f,0x12a8987,0x044c5f2, + 0x1214605,0x07f244b,0x017bd5b,0x0bf43be,0x0511998 }, + { 0x18586c0,0x0a4bed8,0x0989606,0x0d8ddd5,0x004415d,0x06d1458, + 0x11ada5f,0x128f8d4,0x07c1945,0x10a4d94,0x0e941a6,0x13f49da, + 0x14b5636,0x01e4a65,0x04aa999,0x1ddc4e1,0x13aa9e9,0x0aade73, + 0x1e24d42,0x1650e0e,0x132634b,0x180375a,0x02be57e,0x071e90b, + 0x1032396,0x1fc43e6,0x016e9d6,0x126ec4d,0x02d5812,0x179ecea, + 0x137ccb5,0x0cb8dac,0x0cad574,0x0f6a0d2,0x03eecb3,0x0f30bea, + 0x1006a06,0x1a67074,0x1fe6b3c,0x0cab14a,0x059eaf2 } }, + /* 55 */ + { { 0x0c3876f,0x03f7db7,0x1921ed0,0x07e1e90,0x180c612,0x04981cb, + 0x15bfefe,0x1605576,0x045a91a,0x0c97550,0x046e0a5,0x09aef10, + 0x09ce5b8,0x0fcf9fe,0x09c68d0,0x1c2770d,0x186f0e7,0x060bfee, + 0x1568220,0x1b052ec,0x066688e,0x1a40eaf,0x1d75b71,0x02e2f2e, + 0x09df61d,0x10ff7fe,0x178fde7,0x0d5a991,0x06192e3,0x18be902, + 0x18b6c54,0x04e9fb4,0x0c9fa7a,0x0cc8a3c,0x093e0b7,0x1809d92, + 0x1a64971,0x0e8f1c1,0x0efec16,0x1d44c41,0x03b4450 }, + { 0x176dcdb,0x1d4aae3,0x091cf6d,0x1903917,0x15c4a57,0x0bb07d9, + 0x1400d41,0x0a75c50,0x1b3aec3,0x1f40348,0x05ef978,0x0b7c8e2, + 0x0138033,0x02b667b,0x111f8e8,0x0f22dc3,0x1eb3397,0x0929e7e, + 0x172dfb8,0x19bf75e,0x17043de,0x07be7a5,0x1cf25e5,0x1f028c5, + 0x1680c9f,0x14f9200,0x06f8f6a,0x1c881c2,0x191d8a4,0x01bbb4f, + 0x1771741,0x196bd38,0x106c7a8,0x1e926a0,0x0684ced,0x0432321, + 0x1764b4a,0x09e41c1,0x0d853a2,0x0198853,0x04a7fe3 } }, + /* 56 */ + { { 0x055c7c5,0x19d3812,0x1d539e3,0x10e02ae,0x1b7636e,0x1193162, + 0x11491d8,0x18fe658,0x01bc780,0x04c588f,0x1b61dcb,0x1d5922b, + 0x14d48ea,0x0cc932f,0x0134f00,0x0401f76,0x19bcfa5,0x035a958, + 0x0fa8ffa,0x1413032,0x0059c46,0x1edd3ac,0x160b1cc,0x12d5599, + 0x0bbd618,0x0a8e992,0x133a3b3,0x181345f,0x1c44b3a,0x0c7e817, + 0x12d4a64,0x15542f0,0x0c45e4a,0x1042e78,0x0d03f88,0x026ac4c, + 0x050c7d6,0x05db3b6,0x1ac8d4f,0x146ca24,0x083fa1e }, + { 0x0ccc646,0x0436d08,0x07a582b,0x1ef608a,0x0ce0637,0x0443081, + 0x1d8c228,0x1057779,0x1203499,0x1e0c80c,0x0f36808,0x0739f81, + 0x1d707fc,0x0dea7eb,0x1347c54,0x07776fe,0x0744471,0x06b5327, + 0x16b2798,0x1b8ced8,0x116957b,0x019bdb0,0x115b14c,0x1e8143a, + 0x11396dc,0x163e9a2,0x15265f4,0x07dbd84,0x04a739f,0x14d2616, + 0x1894d2b,0x0d4d5a5,0x001397e,0x0afc08a,0x15348fa,0x1e40ed3, + 0x1e98fab,0x1003e36,0x147833b,0x0f32638,0x0614097 } }, + /* 57 */ + { { 0x1156623,0x1996d8a,0x1f08f76,0x1956f4c,0x08137fb,0x0cf1e13, + 0x07d41bc,0x0c24c02,0x089924c,0x010c581,0x013070d,0x161f8d0, + 0x07492a0,0x17d5735,0x16f9c1a,0x17cc3ac,0x03e0d01,0x09d89e9, + 0x01fd31a,0x08b68ff,0x1aa3445,0x11026e0,0x15088db,0x0a2c3d9, + 0x1261d3c,0x003b09a,0x0ef622f,0x1d68d4c,0x19d7201,0x0c1b0ac, + 0x1cde31b,0x0d375e1,0x0955fe1,0x194107b,0x0f585c1,0x148cfdd, + 0x1e3a340,0x0dc5151,0x17e20bc,0x0ec5a16,0x0636dac }, + { 0x0c80af3,0x006dcda,0x0aae50a,0x029c712,0x1a189cd,0x03beee4, + 0x00b8345,0x09e4dce,0x068f9f1,0x08d771c,0x0a82cba,0x0c75017, + 0x092864f,0x05b8a51,0x1607dce,0x0f96d59,0x070c5fe,0x09870dc, + 0x0420dff,0x1d43876,0x089f883,0x09b5902,0x0b689e5,0x145b4be, + 0x12a6858,0x10a1d75,0x080ea3e,0x046617e,0x10b1c4e,0x045aee3, + 0x1d2d712,0x0532cf1,0x078c4d9,0x1b3ae05,0x0260977,0x104677a, + 0x1b67d36,0x1ae03b3,0x1bcfcde,0x1fc9a17,0x02f6dbd } }, + /* 58 */ + { { 0x04da7c7,0x0397e97,0x04c8be1,0x035ccef,0x108cfc9,0x0134713, + 0x1c228f7,0x0486c95,0x0799a24,0x1886ff0,0x162ffc3,0x1ab0e3a, + 0x06ef912,0x0c44b17,0x1cd77f2,0x1d414d7,0x1a95f47,0x0945cb7, + 0x0b4c230,0x14f3d55,0x1bba734,0x1bcfa1b,0x055cc0c,0x1ea9eeb, + 0x0bd8e6c,0x1760016,0x1f9d8cb,0x0ec0db9,0x1931044,0x0f65a98, + 0x075012d,0x0159ee5,0x0e0897c,0x0f8ef05,0x0e18ef7,0x1112c51, + 0x187d744,0x168aa77,0x1753bb3,0x12e8b1a,0x05cb6e1 }, + { 0x08c75ed,0x178cb80,0x0be2633,0x1deddd5,0x1cf49d3,0x1af4b6b, + 0x0780861,0x1143adf,0x0dd9b0d,0x076167f,0x1db6abf,0x19fd72a, + 0x1838a61,0x1b53edd,0x000fce4,0x029e820,0x06823b8,0x1d9be1c, + 0x0038c54,0x0cdb977,0x07a89fb,0x1d02cc2,0x079f8ba,0x14e4ee1, + 0x063fd35,0x1685276,0x07f2783,0x023e7b2,0x15baa43,0x004a6a8, + 0x18cf077,0x14119a9,0x1a06ebc,0x0f7553a,0x08e0bb5,0x1f56c2e, + 0x01f52c1,0x015dd87,0x15b94ba,0x060a2eb,0x02149d6 } }, + /* 59 */ + { { 0x19311f6,0x14737af,0x1e17b86,0x1f75783,0x097e3c9,0x0a104d6, + 0x114bad2,0x1c29f4f,0x019774f,0x0617a8e,0x16113c1,0x02450aa, + 0x135cefd,0x1ac39d5,0x0e18a8e,0x033f96a,0x1d6cbed,0x13b477e, + 0x19611a6,0x0248f3d,0x009ccdc,0x189ec06,0x0448df8,0x0898518, + 0x0a290c0,0x143eeba,0x0af51f8,0x1dcca2f,0x0ffeef9,0x0914568, + 0x07f0908,0x1031a50,0x073088f,0x006f0a1,0x12f10fb,0x07d78e8, + 0x1415bd7,0x137667d,0x109b16c,0x0a1960f,0x014e2f3 }, + { 0x016946b,0x0950821,0x04b5523,0x0ef497b,0x0e801f0,0x14a8b03, + 0x1428d0d,0x192b32d,0x163a197,0x18dae17,0x1ddf243,0x189e0c3, + 0x0279da3,0x09ffbd9,0x07358d2,0x0247e38,0x050a234,0x02f30db, + 0x0a100cf,0x16698be,0x0214826,0x146179a,0x1c62e43,0x100dd8a, + 0x15620ae,0x0da52f9,0x178c92a,0x05f5c68,0x13cb51a,0x1caf45a, + 0x1e2302e,0x1f32cae,0x14f6ac2,0x0f79964,0x01f5ae7,0x0e0fd8c, + 0x10ed8f2,0x1f8edd6,0x0793d8e,0x005b96c,0x058537e } }, + /* 60 */ + { { 0x0f80ba2,0x0583232,0x116c7d9,0x0e0ab34,0x08e055e,0x1a5b1a7, + 0x0acd3c7,0x105864c,0x1de8c84,0x1a7beaf,0x11e02bb,0x1d41861, + 0x139d55d,0x07d0f34,0x102bee7,0x186962e,0x0667460,0x1167f35, + 0x061f07b,0x12b2822,0x0d94f66,0x1bafcba,0x04e0bc9,0x08a93d6, + 0x0ace400,0x0810e50,0x1eeaf7b,0x1048967,0x1653eaf,0x0683271, + 0x00f0dbd,0x18ab8bf,0x0b9f0dc,0x1e74875,0x13beb3a,0x0bb2773, + 0x1906142,0x12c7390,0x05c3459,0x0bf05af,0x0485783 }, + { 0x0576210,0x092de69,0x110f735,0x0faa36a,0x1f378aa,0x0c1cca4, + 0x0fc5c6f,0x043fd2f,0x1f38ac6,0x18687b1,0x1023324,0x182f030, + 0x16af8f2,0x1307a9f,0x04b21f8,0x0ebc84d,0x007db0a,0x187722a, + 0x1f6c6cd,0x08f5cbf,0x044b0ec,0x0e3d535,0x1da44a7,0x0816eba, + 0x132b22e,0x1bbdb7c,0x0257bce,0x00cec9a,0x1c63e8e,0x03fab45, + 0x100a3f5,0x1380029,0x1810494,0x0aec768,0x0ff75e6,0x1f21c5a, + 0x0c2a85a,0x1cd02eb,0x0c4a3ac,0x17b443e,0x06c0277 } }, + /* 61 */ + { { 0x109e7ef,0x1b8435a,0x1e47906,0x167aff3,0x0842ec7,0x135c45c, + 0x17e5154,0x1579a50,0x0051dd0,0x1227032,0x1c73adb,0x1820ee9, + 0x1b90198,0x091f330,0x12afa60,0x08fb2dd,0x13632f6,0x1224088, + 0x1b14abb,0x10568a4,0x09d51dd,0x1fc9cee,0x1594241,0x1a8ab7f, + 0x0eef2fc,0x0be5eaf,0x1634b97,0x102b49b,0x1c9f2a7,0x1649445, + 0x0896b53,0x0af4766,0x0f10d0b,0x0e5ede3,0x079c82e,0x11d1a18, + 0x1b774ee,0x05838d4,0x13e3d68,0x135e45f,0x03067bc }, + { 0x1ca9326,0x0c4f95b,0x1d8f839,0x1b62449,0x17a106f,0x1d2bde8, + 0x11485d1,0x05d646a,0x162b088,0x10a4c16,0x07ff3c9,0x0a88872, + 0x0d7f3af,0x1427220,0x0a8cdee,0x160e235,0x1b0941b,0x014751b, + 0x1929fd5,0x0fb9685,0x15fba95,0x160d356,0x19ead98,0x186d441, + 0x1e381f7,0x1b5e89a,0x126ea82,0x05cf301,0x04671f4,0x01864a7, + 0x18d08dc,0x1161245,0x0cc63ff,0x12c4f92,0x09e5116,0x19a21aa, + 0x0870ff6,0x0ce98b5,0x10656ee,0x195532d,0x0390c83 } }, + /* 62 */ + { { 0x1c4a73f,0x1fd417f,0x0c0d434,0x0a77aa6,0x0665d63,0x05dbbe9, + 0x1be2899,0x1090140,0x022d73d,0x0e02537,0x0ee2aa0,0x1fea064, + 0x1a2409c,0x062626a,0x173885e,0x1383263,0x00e0c0f,0x01ba554, + 0x0061aee,0x0b470e0,0x087f0b2,0x085578a,0x142dde8,0x0931bc3, + 0x19ad5ab,0x08b0af9,0x186a830,0x05c65b4,0x025ce89,0x1edecb7, + 0x1448a38,0x0bd0c8d,0x17c88dc,0x18e345a,0x059099e,0x0ace562, + 0x000bdec,0x06c03fb,0x15ce974,0x0fa447c,0x03ea400 }, + { 0x195d0a3,0x0f5e852,0x0ed35db,0x175fe16,0x06bd76c,0x0dedcbd, + 0x0553e6c,0x0e37e58,0x04c714c,0x158cd5a,0x0bd98d8,0x0772443, + 0x16c9bf3,0x064a0f7,0x161f126,0x01eda47,0x0c3d79f,0x092ac02, + 0x09eb2f0,0x14200a5,0x08af6f1,0x0caa829,0x176ade7,0x1a2c426, + 0x1a6f0c8,0x014febb,0x1779784,0x00a116d,0x1da12b4,0x00797ca, + 0x087656b,0x0eb1517,0x060af71,0x0647dc4,0x120dc58,0x0816329, + 0x0e004d3,0x0736406,0x0aa8290,0x02ed629,0x009f82a } }, + /* 63 */ + { { 0x01366dc,0x1f2c461,0x0be582a,0x1f5eebb,0x129c0a4,0x1c9f6a3, + 0x07f66b2,0x0e0e0a0,0x087a16d,0x0bf3a27,0x1cd86ee,0x14f531c, + 0x13a42e0,0x145aa67,0x136bfc8,0x120f035,0x0bbb7bd,0x1f843e6, + 0x18c9439,0x1e7306c,0x1c09da6,0x175d783,0x19b5a4f,0x175e2ae, + 0x0f4c38c,0x0e83cdd,0x1f7f2a6,0x15309c0,0x0d8dab5,0x1923f93, + 0x1e6ad34,0x0fd746d,0x10be701,0x0e90b26,0x19943a3,0x066f773, + 0x131c4f0,0x1527122,0x16169ca,0x1096ea7,0x077d1e9 }, + { 0x0e62367,0x1991cec,0x13c764d,0x1773041,0x1361848,0x0e4be21, + 0x18d116a,0x1f8018f,0x014f960,0x10764d7,0x11d2d66,0x019ee80, + 0x15cf41f,0x167032e,0x1bb7a3f,0x10c214b,0x04e9e80,0x0d8ef2d, + 0x1833dd7,0x0895c95,0x0d0b17c,0x11b58a4,0x0be958c,0x13fe5b8, + 0x0740fd2,0x097327d,0x0a232c8,0x0c0bd71,0x063016c,0x18d6b54, + 0x05fcb1d,0x0c0f698,0x16112e7,0x04bc2b6,0x101d035,0x0bfd21d, + 0x0256e0e,0x0df0c5f,0x0b6c166,0x1d994a9,0x04e6eab } }, + /* 64 */ + { { 0x199cfe6,0x191e9fd,0x05e2540,0x0d92668,0x1b09bc2,0x1efdb7b, + 0x07905f2,0x0c0c822,0x089a757,0x08a0ba2,0x0672c24,0x1bf2212, + 0x0f4c633,0x1cb5fe9,0x17f1f1c,0x0c5b6e2,0x1128cab,0x04650ca, + 0x16e06ab,0x0e48e69,0x054a306,0x15da626,0x199e891,0x0452c8d, + 0x0a0fabf,0x0b86bbf,0x07e96d7,0x17da2be,0x1192f35,0x16d2e17, + 0x0b695a1,0x0fecd21,0x0cac72a,0x085beef,0x0a8b2a9,0x1e1895e, + 0x0049ad2,0x0318e0b,0x1c15bd1,0x12c09d9,0x0325d27 }, + { 0x048c144,0x0fdaaa4,0x1ccbb84,0x0b6d4f5,0x0e06292,0x0f07cd2, + 0x1a384da,0x03c24b6,0x0ca53b2,0x0cded73,0x03a86eb,0x00b85d3, + 0x15f50d6,0x0f97d1c,0x0e7854e,0x065eb7b,0x12de915,0x1a2b871, + 0x1a89435,0x0d315c8,0x1145810,0x1656cec,0x1ff6551,0x1d2f4bc, + 0x0772111,0x174d5fb,0x14927e0,0x1453efa,0x11df63c,0x1cd4cc2, + 0x196a714,0x0e3a1c7,0x184d54b,0x095ab7e,0x1670107,0x15a3c08, + 0x1d80096,0x19f5b77,0x1e74f3a,0x08dc654,0x019d485 } }, + /* 65 */ + { { 0x140f5e5,0x0f747da,0x145ff86,0x1e09cd1,0x06d2a52,0x1ee438c, + 0x036c2b6,0x191a464,0x0d03a7f,0x01d6ad4,0x12e45aa,0x078e117, + 0x0054bf8,0x1728f42,0x084cfa8,0x1bbbe12,0x024cb52,0x1de71c2, + 0x0418d60,0x0f7c806,0x1176d5c,0x0fa2c71,0x107aee7,0x09b577f, + 0x19639bc,0x0d457d8,0x13015c9,0x0c6a1fc,0x01cd243,0x031a427, + 0x17ab128,0x1828b71,0x1f73154,0x0191bd6,0x167acd2,0x00154db, + 0x0bff272,0x1a2e1ee,0x14ec28c,0x0d969c8,0x01b3ace }, + { 0x0a8bdc5,0x1f2f4c8,0x02240d0,0x1ac60d4,0x0203bf9,0x0429075, + 0x068d639,0x00d3091,0x0de7d1d,0x08bef5f,0x0574fef,0x0daebef, + 0x1f8fafa,0x1c3d851,0x13ad8c0,0x1d5f549,0x132ffdd,0x1700b35, + 0x19d9380,0x1c40a8f,0x1304a2f,0x127438f,0x156ae60,0x05d88bc, + 0x136bb95,0x065515e,0x12a4348,0x1698290,0x1cfb537,0x19c3bad, + 0x1954c67,0x0d30589,0x0238a4a,0x1490e9a,0x071e840,0x1d4576c, + 0x1b3ab17,0x030db26,0x0285078,0x07c325e,0x0538ec3 } }, + /* 66 */ + { { 0x19b56cf,0x04b7f50,0x0b3464d,0x08f7733,0x063d77f,0x085440b, + 0x0bea15f,0x1fb1e09,0x0082835,0x0769ed1,0x0b3b1f3,0x15dabb0, + 0x057e21f,0x1c004e4,0x05d6e67,0x1460edc,0x11b2d05,0x16ce371, + 0x0521f60,0x091a950,0x0655969,0x196a37b,0x01baf4f,0x0799893, + 0x11aa877,0x0534342,0x0a2c590,0x1c441e4,0x020b753,0x11d420d, + 0x1be7c1b,0x1215814,0x0fffe5e,0x159fd96,0x076a3af,0x13eb536, + 0x0e08e2c,0x03eccbb,0x1d00496,0x13007d3,0x06fd602 }, + { 0x0b7516a,0x04fc6c7,0x02ad51c,0x097b8b3,0x03058a7,0x1400e74, + 0x176621f,0x12da469,0x0d17b8a,0x087cec8,0x03daaff,0x093edd2, + 0x1baa1e5,0x0d3f6aa,0x05bfe01,0x0983249,0x17a6c25,0x086cfb2, + 0x025895d,0x1d49397,0x07de3cd,0x1816ff9,0x0da168f,0x1178097, + 0x0e7fddb,0x1581e28,0x1e61c8d,0x009fe1f,0x0d50559,0x0c7edd8, + 0x141250a,0x1c297d1,0x0b3386d,0x0986b1a,0x1a71f0f,0x12f5a69, + 0x0159fdd,0x15995ef,0x197007c,0x0798ec3,0x084cfa2 } }, + /* 67 */ + { { 0x199b964,0x008f5c5,0x111c4ef,0x14b1c5f,0x0e280c0,0x04d2a5c, + 0x0f12753,0x1f50e1f,0x0bf6e20,0x1d19a51,0x0233e8d,0x1a1baf9, + 0x1aee583,0x17a578e,0x180a6a3,0x1f14c0b,0x0340c2e,0x136aaf1, + 0x027a6d8,0x0dfbfc4,0x080f61b,0x135dc70,0x0ec76b4,0x125f834, + 0x1c16293,0x1a72d6d,0x182ab8f,0x05581fc,0x1f4d5b0,0x000d615, + 0x14a3666,0x18505fd,0x133f93f,0x0d99f91,0x0432d4b,0x0e2db96, + 0x055752e,0x1c87c26,0x0363827,0x0a39094,0x0287d4c }, + { 0x09867da,0x0c10087,0x13697e9,0x06350e9,0x014589b,0x0f71173, + 0x09f17ef,0x15000bc,0x1e612bd,0x1abff7a,0x18d7e78,0x1dbe5a6, + 0x064e0db,0x17892d4,0x0f9c391,0x145cac5,0x0840d94,0x0d04dcc, + 0x02d7974,0x13342a5,0x08b57eb,0x173a881,0x086e505,0x0da5988, + 0x17fd7e0,0x0228d89,0x1ffa826,0x1f43ea2,0x0ecbd76,0x14b37fe, + 0x0f8ee87,0x1065e8a,0x0c89a4a,0x147d0ea,0x0abfb29,0x060f63c, + 0x0bd395a,0x1da229a,0x0784f43,0x1b9b1df,0x00132a3 } }, + /* 68 */ + { { 0x16374c2,0x03bc2ab,0x010394f,0x0308e4e,0x060526d,0x0650227, + 0x1b7208a,0x027140c,0x0f1ce13,0x1f0e0d9,0x0c31747,0x10659bd, + 0x0f2aeec,0x0e5fc13,0x1659a66,0x14b134e,0x081de77,0x0668c47, + 0x0634495,0x1c1fc02,0x186ae5c,0x0203c85,0x0850aa6,0x158519d, + 0x1043f39,0x0027147,0x021f796,0x1ddf052,0x19a8c54,0x0d997b1, + 0x13e0f0c,0x0b10ef2,0x10454a7,0x0d9c8eb,0x154062c,0x0b94c6b, + 0x11d9c79,0x1f503b1,0x0a8973b,0x0ed6df1,0x013cbee }, + { 0x13f34f3,0x15f07c6,0x1f8de72,0x1946c2f,0x1da9c31,0x0a1350d, + 0x1b88f76,0x00964db,0x1f29c91,0x0eecb13,0x1b34efa,0x02d3c58, + 0x16033eb,0x1e5d10c,0x1cfd24b,0x1907914,0x00bb858,0x1c971bf, + 0x0ecfeed,0x05594c4,0x00a2e4f,0x0f325f0,0x00407ec,0x11ec891, + 0x1826a94,0x073c8d3,0x1241c98,0x0280cf6,0x0bb8354,0x1528718, + 0x1bbddd2,0x1933380,0x122ca80,0x04288fc,0x16e42e8,0x00d70c6, + 0x05fa04f,0x09b5ae1,0x0259efe,0x1b5c05d,0x04e0a1a } }, + /* 69 */ + { { 0x1a29c4d,0x1333845,0x0250032,0x1c45310,0x008240c,0x0ed3a96, + 0x1299c5b,0x068438b,0x1abbbfa,0x04e0722,0x0a2dc9a,0x0bfa7da, + 0x141d754,0x0be2b55,0x0884663,0x13acabe,0x1743875,0x0a59ec7, + 0x1f942e2,0x121bf71,0x1a16934,0x0bf4075,0x0d907d7,0x1596a6f, + 0x1a5eb79,0x12f3d86,0x1c30757,0x16d6292,0x1a429aa,0x1346d2e, + 0x0948ce3,0x05eda5e,0x010c437,0x079d3f0,0x1b4994c,0x1844de2, + 0x0bef08b,0x187bdb6,0x12667be,0x1b33f33,0x0733e30 }, + { 0x02a38f9,0x10ac152,0x1403b3f,0x1c8e616,0x0ec2d58,0x0bb5965, + 0x1ca9f7a,0x1765dc5,0x1a969c1,0x029ceda,0x136d2bc,0x02d1f9d, + 0x0231954,0x13d4748,0x1dcd22b,0x0a83fe5,0x1cc3121,0x10eac6b, + 0x080ab94,0x0b6eb84,0x15a75d2,0x0d7a041,0x17aa659,0x1369c8d, + 0x16a4152,0x0cd9ff5,0x1ef49eb,0x192ff6d,0x1f900b5,0x0a60130, + 0x07b61d5,0x009ab63,0x03031d9,0x0cdce5a,0x06e32c8,0x1e67abd, + 0x1ee00bc,0x01ea491,0x17031e9,0x0736f34,0x056facb } }, + /* 70 */ + { { 0x1018bfa,0x0b2d151,0x0610064,0x093ff5b,0x100c6b2,0x1a0d4d8, + 0x0c7d954,0x19377e3,0x125dc4c,0x15e8ecb,0x1ff9839,0x1daa57f, + 0x0b52850,0x1f2a84d,0x1a64b31,0x0b3e249,0x02e4ceb,0x07fb628, + 0x0a9f452,0x166ae63,0x0a462f0,0x0ef3f1d,0x1a43077,0x0285101, + 0x09f45d1,0x0eadd76,0x1996f97,0x0eb9fa4,0x0bce134,0x18a70ff, + 0x0c20eae,0x101285a,0x0ba4829,0x1416435,0x0d74a5f,0x1a3c364, + 0x10d8218,0x18e6df2,0x1b2eedd,0x0cdb29a,0x0885992 }, + { 0x15ccaf2,0x039480a,0x1cf8221,0x0ef8b6e,0x0679ebc,0x0e8476c, + 0x0b746cb,0x1b75116,0x087d475,0x1050c07,0x1340aa5,0x0d6ecd2, + 0x1680fdb,0x1f9fcf4,0x01d6324,0x06d887d,0x0fa4ad8,0x0ded1fb, + 0x0bece1f,0x018b026,0x000f940,0x0112a81,0x0969e15,0x0dd9e30, + 0x1c35177,0x0cd154b,0x1959b6d,0x07d7e8d,0x145eda0,0x1140132, + 0x1111d0e,0x19ee956,0x1169d84,0x19fb4f6,0x0c76232,0x0d75572, + 0x1825719,0x1749966,0x05c65c2,0x14d4181,0x0797224 } }, + /* 71 */ + { { 0x01f3567,0x091fc22,0x1c758ca,0x105c497,0x011c316,0x138fffe, + 0x1c9aedd,0x044972e,0x17a5e1a,0x00ba353,0x16d05d8,0x1d4075b, + 0x0653ddd,0x1facdc2,0x019e8f1,0x0ffeeaf,0x18756cd,0x0580954, + 0x066ea6a,0x0bfd93e,0x07481bd,0x117c183,0x1d40de6,0x1180ba2, + 0x1445dab,0x0153bb1,0x0de40fd,0x1afe883,0x03e46d5,0x13a6d48, + 0x1070045,0x15ba24d,0x11d3c4d,0x0ada00d,0x0ab1851,0x1d44ea5, + 0x155c356,0x1215342,0x014b136,0x02bb041,0x03ff09c }, + { 0x1cb7784,0x10de77c,0x0c15302,0x184845e,0x0ec539b,0x00a553d, + 0x1e7f431,0x188be81,0x0ffd42b,0x1d518b6,0x1638574,0x09865e6, + 0x0242f5a,0x0b713b4,0x0f7367b,0x1d9dc01,0x09ff8a5,0x0834fbc, + 0x17853d7,0x10031c0,0x0741807,0x09c5a06,0x0aecf92,0x02fee5a, + 0x08c1d79,0x0862ede,0x13315c5,0x01dd4cc,0x1a8920e,0x062d61f, + 0x192897b,0x038f2e2,0x021b0f5,0x168b59e,0x0bc98d2,0x151e134, + 0x18391d9,0x1987e2a,0x0b93239,0x00a9fbf,0x047ef18 } }, + /* 72 */ + { { 0x1a285e4,0x0f9e89e,0x0fd2659,0x147403c,0x1a7d4db,0x10a5685, + 0x104e984,0x0928e70,0x1223975,0x1dbea9a,0x0c2e4b4,0x1b9eb4e, + 0x1da53db,0x19968b2,0x0c364ac,0x0fde862,0x14182f9,0x1225142, + 0x137386d,0x0444388,0x0ec9bf6,0x0c3f150,0x0ee84e1,0x1f5b331, + 0x12c8dcb,0x02599f9,0x1ed7fb5,0x013cbe7,0x0217bb4,0x0632e33, + 0x0a570ca,0x1f9bee3,0x00db69f,0x103c458,0x0886e24,0x1744785, + 0x1ae6464,0x1594731,0x02187e2,0x13971bc,0x01a6b6e }, + { 0x0af77aa,0x1615b03,0x0196bdb,0x1b510fe,0x0e60f5c,0x04c62b1, + 0x050027d,0x0970fa4,0x1fcbaaf,0x1acadac,0x0ae1576,0x05424e3, + 0x0c0fb59,0x0a1a4d8,0x1384397,0x1193941,0x1d8887d,0x1ceb0c3, + 0x152f5b6,0x1d2bf22,0x099903e,0x09ae836,0x03f94c8,0x0d4c9a1, + 0x1bc30fb,0x1b07a53,0x159a932,0x1a455e1,0x17367c3,0x1677ae9, + 0x1545a54,0x132fb1c,0x10ea734,0x1996837,0x1c3dcc5,0x05688f8, + 0x09cb394,0x15981a5,0x03f4002,0x10050a2,0x079dd01 } }, + /* 73 */ + { { 0x0c7424e,0x0019d1d,0x1340138,0x10c1fb4,0x1b06b68,0x1bb97de, + 0x05d9af2,0x14846d5,0x1f297cd,0x0a54715,0x04f1b8a,0x170bb60, + 0x0d4b0aa,0x0391d1d,0x0abb262,0x094d67a,0x0cd13c8,0x1065719, + 0x03b05a7,0x111ebce,0x0262218,0x1ea1544,0x1ce58ce,0x0c1b370, + 0x0792e7b,0x1f0b456,0x0841da7,0x13e56e4,0x0bed348,0x07f3692, + 0x0aa3cff,0x147d649,0x15efb88,0x03835e9,0x08fd213,0x1bbbd9f, + 0x129ece0,0x008cd4c,0x150d9f3,0x08b1a80,0x087e5ad }, + { 0x11000a7,0x0d54ebe,0x00ceea6,0x195d047,0x0b94aff,0x1c1ee2c, + 0x058a37e,0x11b9045,0x1845a41,0x1acff08,0x05c150b,0x01f0ba8, + 0x01a8b97,0x195b8ac,0x0630995,0x1ba2f12,0x17dc0d1,0x07277a3, + 0x0beb5f0,0x1699e67,0x0a5bb50,0x1c80c38,0x086eba9,0x07450d0, + 0x087f9bb,0x0e6e3b8,0x1849296,0x10aea63,0x1432397,0x0137abf, + 0x12bb5d3,0x002c992,0x1f5ae25,0x05fba6a,0x1f8bc25,0x04cc116, + 0x1dceea3,0x06dadd7,0x10117d3,0x0333219,0x00b7125 } }, + /* 74 */ + { { 0x0d5c64d,0x08650c4,0x14d168a,0x134e924,0x0596d74,0x0074928, + 0x034f4a8,0x0d74096,0x0caf7b6,0x0166816,0x17b60c2,0x0185d9b, + 0x0e912b5,0x1f98b23,0x0f3a77b,0x1ff2b02,0x0c7c75f,0x0b15738, + 0x18a9185,0x10a5c0f,0x0fd16f6,0x0801c02,0x0c83f5f,0x031d1b2, + 0x0a4dd82,0x0ebd8d1,0x0ebf191,0x12314df,0x19fdbe4,0x07d0f46, + 0x1bbec20,0x088e16d,0x1d4d08a,0x1a77b99,0x01ddb65,0x05a5744, + 0x09dae5d,0x05cad3b,0x165b63b,0x074fad2,0x07a3f42 }, + { 0x0929387,0x096534d,0x1ffcd8b,0x0396383,0x0bdb758,0x08db65d, + 0x1b27df9,0x03fb125,0x03a4e13,0x146c319,0x01d587b,0x07e2b7b, + 0x124680e,0x0a73f39,0x0965f87,0x1fdfdc7,0x17c5581,0x19e6395, + 0x0a32b82,0x0eff159,0x14aff3e,0x0e2f17e,0x1f31f5f,0x06ab6f3, + 0x0455221,0x0bbee9d,0x0a8b01c,0x08d649e,0x09621f5,0x0996834, + 0x0f9056d,0x07ef02c,0x1e9af51,0x1f69095,0x0e6ccf5,0x064fac7, + 0x1680294,0x00cf794,0x1ebd2ac,0x0aa2c47,0x02da5fc } }, + /* 75 */ + { { 0x0a5c600,0x14e79e4,0x19f1890,0x047fc67,0x07a80c2,0x0beee5d, + 0x09d0029,0x0e93ffb,0x1925b0c,0x0d70ab6,0x003ac34,0x07f2d62, + 0x01097a4,0x17ca1e4,0x07a5173,0x19e482d,0x0e51128,0x1d0fb9a, + 0x067c04c,0x10f8948,0x0024043,0x0580822,0x1001e1a,0x06b39e5, + 0x16abf90,0x071f2a0,0x191e355,0x138edfd,0x02173ef,0x0ed3215, + 0x1059886,0x13fc602,0x1e03156,0x1923f30,0x138e4fb,0x0541feb, + 0x072b659,0x0bc95d0,0x1534e04,0x032e190,0x0855f02 }, + { 0x07314c4,0x1fdb642,0x05a987e,0x0bd68b7,0x1790615,0x1157d64, + 0x18519ae,0x102e205,0x1ab9497,0x0a8fcba,0x0313fbb,0x162f822, + 0x079d2f5,0x17fabb3,0x12339c2,0x089cef5,0x0216eb2,0x1f39b35, + 0x1471971,0x1779d8a,0x19dedd1,0x0570d42,0x0d49418,0x14fa5cf, + 0x081748b,0x0623d02,0x06ae3aa,0x03458a8,0x1ff078e,0x1261b7e, + 0x011b9e0,0x0290e96,0x1b49fc7,0x0fb99bc,0x0dfc1ac,0x1e455c6, + 0x0f8fe6c,0x1a90c93,0x01e5c70,0x19ea4ba,0x0292236 } }, + /* 76 */ + { { 0x18b29dc,0x06c053e,0x122b36e,0x0811d4c,0x117a202,0x095f48e, + 0x0b17aba,0x178fb62,0x0fda72f,0x19a3e8c,0x1831bc7,0x16813ce, + 0x1111374,0x0c71c6c,0x187a3c7,0x183e8e6,0x09d739a,0x13b8a5f, + 0x137d713,0x12e0396,0x0ae1c1f,0x0c37b96,0x1644e3b,0x1a30189, + 0x1e1f76a,0x1ce0e3f,0x1a78b6f,0x11830b7,0x10c44df,0x1934be3, + 0x17e0d76,0x161a2b6,0x197cfea,0x12a2f7c,0x1169879,0x1ca2028, + 0x05184e5,0x1834421,0x19ea85a,0x0b2ea43,0x07cfac3 }, + { 0x00bc53a,0x010b39e,0x0d9e046,0x06fcea2,0x04b5ede,0x12bd0c4, + 0x157f68d,0x1307944,0x0ba1fdd,0x0b55dfa,0x09df602,0x0d3f8bb, + 0x059ce83,0x1559a16,0x1ee6b9e,0x0b3e3e4,0x1d69720,0x083648d, + 0x053b3fa,0x1b56612,0x1f12ee0,0x1dc9fa9,0x0ed91fe,0x14afc1d, + 0x18a7aff,0x1039861,0x1e7cab5,0x02fa0dd,0x19dcc95,0x06c3ddc, + 0x08525ca,0x088c101,0x0034af1,0x0e0bed8,0x10fc4ae,0x0199021, + 0x172a22a,0x12f8a7b,0x00af5c8,0x0fe3bbf,0x06ce3dc } }, + /* 77 */ + { { 0x0397830,0x06c1ad2,0x0c1b01f,0x19e8e66,0x0dd9290,0x0c4f462, + 0x14ea0a6,0x0a5ba6b,0x1563d81,0x0c812ac,0x17986de,0x1223d0f, + 0x1cf278d,0x081271a,0x1cd031c,0x01cb338,0x0614a0d,0x096a222, + 0x0c989a8,0x0ec11fe,0x1aa963e,0x14e264d,0x189e8df,0x1fffa4a, + 0x0dc5176,0x0e6862b,0x033bca8,0x16dbdf9,0x0559d9c,0x06ab77e, + 0x04b2f30,0x008396d,0x05f3fc5,0x10f04f2,0x08e7945,0x199a0b8, + 0x1c3b559,0x198f74a,0x085b4a9,0x04547a1,0x0851511 }, + { 0x0ff19e2,0x0819ac3,0x180de0b,0x143b450,0x02c60da,0x1e3f76e, + 0x033f955,0x16165cf,0x01bc4e8,0x07b7cc2,0x0d719ea,0x16967be, + 0x0acc1f9,0x03b2231,0x184d80d,0x1c1612d,0x1977c7a,0x15fc885, + 0x050d655,0x0fe60aa,0x0ae527c,0x0e7b18f,0x10536c5,0x0d36699, + 0x161427e,0x1f9528e,0x057f04b,0x1d9050a,0x087162d,0x1709fdc, + 0x0f7f33a,0x1bc2911,0x0332ac1,0x1f3a66d,0x1388bb8,0x194406e, + 0x10ae069,0x1f50d0f,0x1b01165,0x1e4ef7b,0x08b1159 } }, + /* 78 */ + { { 0x1961d30,0x18d2217,0x123d2bd,0x10f58e4,0x1df968a,0x148366d, + 0x1e1f2c6,0x04ba65b,0x004abf9,0x0608713,0x0135300,0x0eb373e, + 0x1ab8711,0x09cb82e,0x1553982,0x0109201,0x033c9f8,0x0fbac3a, + 0x09e88dd,0x1575bcd,0x17ac2e9,0x1c4a560,0x159db51,0x005b338, + 0x0525bc2,0x19ea650,0x16afeb9,0x0b71795,0x05991b9,0x169c1a0, + 0x10c8dc7,0x08b1533,0x169e47a,0x0643315,0x0c60ade,0x18f9581, + 0x00232c7,0x1553cdf,0x1d165b3,0x066b11e,0x00bd864 }, + { 0x0734189,0x0d45a3f,0x085f7a8,0x119fcbf,0x12c5ac8,0x01bb322, + 0x1353845,0x0a08894,0x0af9e97,0x1291184,0x11acef0,0x0187a61, + 0x1778b1d,0x0636fa3,0x16b97c1,0x11bae5d,0x19a2ee8,0x029898e, + 0x1324f8d,0x0701dd5,0x0e8ec4e,0x16546d8,0x15266c6,0x0ba93af, + 0x08c167f,0x06bbb9a,0x1c555b3,0x12cc64a,0x11d13dc,0x0746130, + 0x1319738,0x16b45fb,0x095fe66,0x07d5096,0x00ca196,0x104cd31, + 0x11c32c9,0x03e8fa1,0x0641f6a,0x131f9b2,0x0466505 } }, + /* 79 */ + { { 0x14a5efa,0x009e635,0x099531b,0x163a0f6,0x0481989,0x0e34e06, + 0x19b3a2f,0x1a82172,0x02c2531,0x0a67d51,0x028403d,0x101195a, + 0x09cb5f1,0x172ed22,0x0d494e3,0x107997d,0x085bedd,0x0531200, + 0x189571e,0x05b59fa,0x058fe79,0x0310310,0x020dc64,0x02cb183, + 0x15e83ed,0x0a14b30,0x1df4a35,0x16a9364,0x175df34,0x13edc1d, + 0x10babc4,0x02ff772,0x160df6d,0x1e49827,0x076fdbd,0x1fa10c6, + 0x0018789,0x01c7cc3,0x0a0305f,0x0957352,0x00c4357 }, + { 0x120cad0,0x199260e,0x0229dba,0x1318c22,0x10decb0,0x0369b6c, + 0x14e71bc,0x12f4dd3,0x0bc0da1,0x06cbc5d,0x0b1739b,0x0380a0f, + 0x155948b,0x02a4bf5,0x151c593,0x029c657,0x00f4d59,0x0154e26, + 0x1d67c0f,0x18a08d4,0x047e772,0x0534d64,0x19f5cca,0x0916661, + 0x17d0c30,0x167546a,0x0103dee,0x0c0069c,0x1f1790e,0x08c9d42, + 0x0da08f6,0x0b90b2e,0x0e9b66c,0x1081153,0x11e99e7,0x0845945, + 0x09023fa,0x13d0ce0,0x156e403,0x1e24e4d,0x0324999 } }, + /* 80 */ + { { 0x0834915,0x1576b3e,0x193599f,0x1578bd6,0x1f77aa6,0x0b1008c, + 0x0f2d897,0x184e53d,0x0699fd9,0x1771279,0x153db02,0x10e8571, + 0x16e1eb5,0x0a64bb6,0x049c430,0x1d4cafe,0x135f6d9,0x0489c81, + 0x1ad4019,0x16e0920,0x0e4f668,0x07043b7,0x1965a68,0x13b26c0, + 0x1bf3f2f,0x1e77c80,0x06d2678,0x16350ca,0x1bcaaaf,0x09fdf96, + 0x0da02e5,0x12e760d,0x12cc566,0x1b63218,0x070cebc,0x0a6a69b, + 0x10ffd81,0x031d290,0x0ae4791,0x097e318,0x057ea2b }, + { 0x0a0f2f2,0x0f0b145,0x12a803d,0x0a1c8d7,0x0c7e75c,0x116216c, + 0x11e6a92,0x0052f56,0x014baa2,0x0798475,0x0f30bad,0x1a28d28, + 0x04a901b,0x176ac40,0x0497fbb,0x01ef976,0x0f99d18,0x0328164, + 0x1603187,0x0a72322,0x1ee3e53,0x1493880,0x1f89e01,0x14e4e2e, + 0x040a1fa,0x0a9bd05,0x0931d6c,0x05db9c0,0x0f1c223,0x1305a9c, + 0x0bb688d,0x17c60fa,0x1511e98,0x1705a26,0x19026eb,0x0e484ed, + 0x1ff1f30,0x061c93b,0x0d7269e,0x08dd4f2,0x060480b } }, + /* 81 */ + { { 0x072ece3,0x03eb31c,0x03e0c42,0x1b2ab6e,0x1f29be7,0x1caddc2, + 0x13f1e73,0x0436a16,0x1dbffa6,0x171dac6,0x0ae976e,0x0501c04, + 0x1c0e61d,0x00c0a24,0x0b9445d,0x0a90af1,0x040cf55,0x1058994, + 0x03382c3,0x1da36d7,0x1e3d800,0x0abc6ae,0x0d77ff7,0x14ad68e, + 0x0237469,0x173fbf2,0x0636442,0x0bc646d,0x13c7c7d,0x0950318, + 0x196dbfd,0x1525bd3,0x02fe20d,0x0885dad,0x1f4f448,0x0683668, + 0x00c16f2,0x082f6da,0x0233316,0x1a7351f,0x00774a0 }, + { 0x1b6c106,0x0c0d5f1,0x02dceb8,0x1f1bc2a,0x0ebe163,0x1aa41b2, + 0x0e0bdbc,0x02d9eeb,0x13ac7ac,0x1069031,0x1c8abea,0x0cd0522, + 0x135c680,0x08aa2aa,0x0507984,0x1c7eee7,0x038bf5d,0x10b893f, + 0x0bed076,0x1fbe063,0x066332c,0x08c3de4,0x11a24f2,0x0593933, + 0x06744a6,0x0a3ba82,0x1658b06,0x0d0cdc5,0x0cdf4c9,0x046f9bc, + 0x0c9227b,0x0680ff4,0x060709b,0x148689d,0x0565544,0x07a6fa4, + 0x1ab9227,0x11e981d,0x0052e58,0x0a84864,0x0081519 } }, + /* 82 */ + { { 0x17b2108,0x1b6c4fd,0x06abe48,0x195aebf,0x1ecc83c,0x10ed089, + 0x0ac56d3,0x0c5ef8e,0x10315c3,0x0957577,0x0bf8fd5,0x01dbe4e, + 0x0811e14,0x03c21f7,0x15e6fda,0x164b733,0x0fd1d9b,0x06735aa, + 0x0c6eb5d,0x161c42b,0x090db20,0x07adc26,0x1528085,0x14d9d92, + 0x1bf52fc,0x1b7a2cd,0x167937d,0x06c7891,0x0cf17ee,0x1c276b2, + 0x120c117,0x1ec55b4,0x002a167,0x06500c2,0x0fcda9d,0x1a593c3, + 0x1691c42,0x07cea0f,0x0e1d3a3,0x0f18589,0x05abf21 }, + { 0x1b3bccd,0x1cb35f9,0x12a91dd,0x017c7c1,0x0047e0f,0x1ea8218, + 0x00ece31,0x1f99707,0x1946fd5,0x1bf1dd7,0x103a1f9,0x0f0bd3d, + 0x0579baa,0x0450c69,0x0f155f3,0x1f9fdb0,0x1af25be,0x0cdcb72, + 0x031c6d8,0x0ba2bd3,0x0da14f0,0x0d3bf31,0x0207e64,0x1547042, + 0x0c781cb,0x1fd8e37,0x1795366,0x0a45ecb,0x0d14307,0x0ab9a27, + 0x16bd741,0x12b95fb,0x035b31f,0x07adf98,0x1d0d8de,0x128fccf, + 0x1270b9d,0x0fbe56a,0x1a9200a,0x10e9b22,0x015ad15 } }, + /* 83 */ + { { 0x0588ae4,0x1176755,0x08c8037,0x1146e34,0x152ebc5,0x1182222, + 0x0a4d1c4,0x05ba01d,0x1e4b183,0x1dfd33e,0x07a10eb,0x06836d1, + 0x0829216,0x10fa717,0x05aeef5,0x13b8a3f,0x08404c2,0x0caa103, + 0x08c5ff4,0x1c704e8,0x1162c7f,0x0331a41,0x18282bb,0x000309f, + 0x194d107,0x0c2fe15,0x0ff87ef,0x0e4332e,0x0743520,0x1558fd8, + 0x049922d,0x188dca7,0x1bbdaad,0x12b7f91,0x147c03e,0x0c1b71b, + 0x066725f,0x040af5c,0x0658c41,0x194a5d0,0x03f9c4c }, + { 0x0ce637e,0x1594b99,0x1377fcd,0x1beba4b,0x01a15f2,0x0156cbc, + 0x014b62c,0x1d2343a,0x0cfbab3,0x12f9dde,0x1badd4b,0x17aec29, + 0x1a60d2c,0x06ad3c9,0x124610f,0x04289a8,0x175cdba,0x1112167, + 0x02e65d9,0x0e0bcf1,0x0132a20,0x00763bf,0x19384b3,0x035360a, + 0x14df6b6,0x1ad58e0,0x11d2096,0x1fb2fe0,0x0312238,0x04109ed, + 0x0365581,0x09a618e,0x0486727,0x17734ef,0x1c54704,0x1b79571, + 0x068d893,0x031c5a3,0x15d2d77,0x1ac447e,0x06479da } }, + /* 84 */ + { { 0x05f2b26,0x02279d8,0x1db15a4,0x150173e,0x135a294,0x087b575, + 0x1f8a10a,0x0ef1073,0x1026a58,0x10e7d91,0x1fe70dd,0x0d6c5cb, + 0x1676892,0x0588e2b,0x19b3480,0x07dfd75,0x15672a0,0x16e42bb, + 0x06eb58e,0x1c0e95c,0x199c0ca,0x10eb84e,0x0ff9246,0x003b382, + 0x1ded665,0x1fbbb62,0x070cabb,0x1b4dd94,0x1683e81,0x0eaae2b, + 0x11d4212,0x1bf31b0,0x0392e9c,0x0d2b24f,0x00bd936,0x05f5af3, + 0x037b98b,0x01dedbd,0x0125fdf,0x129e10c,0x01fe09f }, + { 0x048cc63,0x1f5573b,0x1c51269,0x02cf9f4,0x13ea251,0x1fa2ac8, + 0x048f194,0x10df917,0x181a16e,0x0abb0cd,0x1919d36,0x0096790, + 0x1a0c7e8,0x0b0b2cc,0x0204d28,0x04651f9,0x1690a65,0x11b3754, + 0x0f240a7,0x0652c09,0x0d2b415,0x0a57155,0x1be7866,0x0217deb, + 0x08c527f,0x0304f15,0x1b19efe,0x07b96b0,0x0cc25d7,0x01fd422, + 0x14fd869,0x0e9d66c,0x14e7eea,0x007816b,0x1c1b749,0x09e66ac, + 0x1d83bcb,0x03b4a67,0x149abbb,0x10db6c4,0x04de957 } }, + /* 85 */ + { { 0x1eac2f7,0x1e98a9e,0x0a39219,0x156c3b3,0x0084778,0x1bd96ad, + 0x1be582a,0x0f3e76e,0x0cfdf4f,0x059802b,0x0e3d2c0,0x1c2a635, + 0x01d0701,0x0e3bce8,0x1e52356,0x0a6e20f,0x0bc8267,0x03e4ca7, + 0x02eb530,0x09a9dc9,0x1058110,0x1adfe4e,0x1e63382,0x13f5016, + 0x0898d30,0x157e3e5,0x16b2ccf,0x0489e44,0x0f31750,0x06fe2d9, + 0x0d3547a,0x149af7c,0x049ba6b,0x015a19f,0x131ef68,0x142ec1e, + 0x0435275,0x11b53f2,0x06030df,0x117cc6d,0x01c9441 }, + { 0x1dc1414,0x1098984,0x14dd0e8,0x1887926,0x060765f,0x0fbce70, + 0x081eb7d,0x194dfe6,0x085d4cf,0x18c58fd,0x0656adb,0x0e5cc7d, + 0x02f5c42,0x1415980,0x0682792,0x0fe2c24,0x11b9714,0x1415b2e, + 0x029ff89,0x0784184,0x0726499,0x0c7338b,0x067272e,0x1688141, + 0x0d673fe,0x1e2ad01,0x04946d2,0x1e7f53c,0x1338ea3,0x023a502, + 0x12dd76f,0x0f613ed,0x0b4044b,0x1a3049e,0x0862010,0x04cecfb, + 0x098ceac,0x028a110,0x0d6ea5e,0x1656aa4,0x0611bfb } }, + /* 86 */ + { { 0x00ad2a1,0x152af78,0x035ef6e,0x1c29452,0x09efa85,0x158b4a1, + 0x11da3a4,0x0607694,0x111ec81,0x1888de6,0x149ec99,0x0e05117, + 0x060e425,0x0cd01e0,0x033ca8f,0x11095e5,0x12df318,0x05dbe46, + 0x0eabac8,0x1428c5c,0x1d77e2e,0x0221dc2,0x0cd4d60,0x09dd37a, + 0x0448255,0x0c7c0f7,0x1b9aa86,0x165ddd3,0x0c5944e,0x1402613, + 0x1f1e96a,0x105562c,0x0ef2da5,0x110d2d0,0x11d80bf,0x1cb4556, + 0x1370298,0x0e59dc1,0x0aa345a,0x0881d67,0x086e6c5 }, + { 0x1793d9b,0x0199085,0x1b3bb78,0x023bb6b,0x179fade,0x0985b27, + 0x16a49a2,0x165ee7f,0x1fe4fd1,0x1556cbe,0x1372201,0x163b254, + 0x15073a5,0x1e4bb6b,0x1e32f62,0x04d8115,0x1b163ce,0x1305a55, + 0x12c7ec1,0x060153b,0x13d39c8,0x066d4ad,0x0cd6965,0x0fd590e, + 0x1d7d4b3,0x1558fcb,0x0883bbe,0x07a5d74,0x0828c8a,0x048379f, + 0x004c963,0x10b56ef,0x032616f,0x05b0be4,0x064a30a,0x1ae4b2e, + 0x1233b82,0x18cb5e1,0x049b735,0x17233f4,0x083867e } }, + /* 87 */ + { { 0x0474edb,0x1f39f11,0x06b9dd3,0x083509c,0x0a76639,0x16eb719, + 0x0a6b671,0x0ba4e06,0x114f8bf,0x062520a,0x19ee400,0x146fa44, + 0x0e3ce2e,0x08e927d,0x1d4c054,0x036f024,0x054263a,0x13e0a6c, + 0x0b82c81,0x1080363,0x09fc20c,0x0d840fa,0x1cca804,0x138dbf1, + 0x123fb95,0x0830f40,0x1200387,0x0651b8f,0x059a9aa,0x11bc121, + 0x0dd61da,0x16fded8,0x1ada8b5,0x0a64f91,0x0dbaa4f,0x1e047ed, + 0x1fb6389,0x1aa0a6f,0x0ce7a27,0x145cc51,0x04b26bb }, + { 0x1318454,0x18e5a2e,0x12db4c2,0x1fae86d,0x123b749,0x053a308, + 0x11c995a,0x03c6221,0x11c84fd,0x02ef091,0x00f5572,0x0dcc108, + 0x18a5f8d,0x0d8fd5f,0x16db84e,0x1b9c072,0x0c33cfe,0x07f36b4, + 0x12e4444,0x00703f2,0x0eb71d9,0x0096e63,0x1c2a3aa,0x1219457, + 0x004137e,0x02d2cf4,0x1f22897,0x1d6bf80,0x04663cb,0x129d2ec, + 0x1f00270,0x12216d4,0x0b15073,0x07c6a80,0x0931042,0x0b0c0fb, + 0x0b901e6,0x01ece1e,0x057180b,0x18a592c,0x04d697b } }, + /* 88 */ + { { 0x1a8fb40,0x18f7877,0x0273836,0x16b7473,0x09021c5,0x0e8cef9, + 0x1ec5602,0x1c351ad,0x14c1219,0x1bc3db9,0x1c1789a,0x02d029d, + 0x026417e,0x07cbcb7,0x04d0b6e,0x0843689,0x05ebf84,0x117c3c5, + 0x052914d,0x122dafd,0x1693e71,0x11d708c,0x06062ee,0x0d1009d, + 0x14be957,0x1c57633,0x13e1093,0x144c0e9,0x0ce6ab0,0x1dcea33, + 0x02f6f24,0x192400f,0x1f15a98,0x078d1d9,0x1434e1c,0x0f3a21f, + 0x04e785a,0x0920ecf,0x1360298,0x143cd91,0x076ca87 }, + { 0x02e48b7,0x1fdab70,0x07190d5,0x079813d,0x1bd14b1,0x034e787, + 0x090d490,0x153b6be,0x02c3b01,0x03c0b2e,0x15b6b7e,0x0f89cd2, + 0x08e549e,0x1deb05b,0x1fa54e2,0x18ca7e5,0x16b059d,0x1ca97c2, + 0x0ddffa6,0x0c044b6,0x08c4d3f,0x145ff48,0x1a831cc,0x11ebe5a, + 0x0a2d3bc,0x0286735,0x0c91094,0x0e42688,0x1b3ce5f,0x13351e9, + 0x0485f84,0x182ceea,0x1b5e43f,0x1c4a53a,0x0188dfe,0x0a2b24e, + 0x0be3e37,0x1303a99,0x0def854,0x18cdb47,0x027e7f2 } }, + /* 89 */ + { { 0x0a15883,0x1b2d6f3,0x0ccd8e3,0x18cd5fb,0x14a7e68,0x1896f2e, + 0x0daaf4f,0x020c40f,0x037b878,0x037fca8,0x13db4c7,0x1964c95, + 0x02c0d44,0x195f3c6,0x0eb1807,0x1301c2c,0x05a1636,0x18e31e6, + 0x1724d26,0x059fd12,0x12203e9,0x0c20f63,0x1dce383,0x0bf52c2, + 0x1d7642d,0x074b0b4,0x070f80a,0x154eed8,0x0d54092,0x0b2358b, + 0x1664f71,0x0e0dbe9,0x0b27fb5,0x035cbd0,0x05c33a7,0x013d322, + 0x13c85f4,0x07215f2,0x194a3aa,0x06f0648,0x002e964 }, + { 0x078ea1f,0x0056ed7,0x1a5a455,0x1af6ce1,0x11a1b74,0x0034132, + 0x19107dc,0x18ff326,0x07d7520,0x1cbeb75,0x184b863,0x1404d39, + 0x020faa6,0x1c9041a,0x042b2a1,0x0886c4b,0x0637561,0x1bd241c, + 0x0e05023,0x0c293de,0x140607c,0x026bc29,0x1ccefd6,0x1776dee, + 0x1b0109a,0x04d43b0,0x1fd4a28,0x09d6493,0x00ae3ce,0x0f6c170, + 0x1e821e0,0x042f1df,0x04c1b25,0x09d3f43,0x0a8a754,0x1f983cc, + 0x1919062,0x1c5ca70,0x149f7b6,0x1b49e2c,0x0739f53 } }, + /* 90 */ + { { 0x04adc5f,0x1a54449,0x15b5e97,0x0d5031e,0x15646c1,0x0afcaa4, + 0x044a5de,0x0001d89,0x1d19c54,0x1a43a9e,0x044ad0a,0x06d640b, + 0x0616fa2,0x143d24a,0x0f597cf,0x1a0ccd6,0x001045f,0x0538ba5, + 0x0a97850,0x0a06262,0x0623b63,0x0254b5c,0x09e712d,0x16007ab, + 0x19d659a,0x18d3d19,0x18e09bc,0x0e5e618,0x1090cdc,0x1c8637b, + 0x092d39c,0x120dd7c,0x1ac6c36,0x0282d2c,0x01b6ee9,0x14734fe, + 0x058c413,0x0cc8f0e,0x03a120e,0x1ff441c,0x0020c23 }, + { 0x1c74661,0x1256d57,0x0194483,0x064eff8,0x17bbcf6,0x0e73cc9, + 0x073dadb,0x1428209,0x17b161b,0x1c6b5a9,0x043ec96,0x086352c, + 0x0922218,0x0feef3b,0x07b2747,0x00c61bd,0x04d42d8,0x1e995fd, + 0x09137d2,0x0ae054c,0x0dfb388,0x16a2ac9,0x137b747,0x09c0371, + 0x1f45bfb,0x0d8070e,0x0a1b885,0x1e97bda,0x137e6a8,0x0a43b54, + 0x08e024d,0x10261ee,0x15278ba,0x010fc20,0x1a48e2a,0x158db88, + 0x1d8b4f8,0x03d88cf,0x073bc88,0x0a7f24d,0x076e7bf } }, + /* 91 */ + { { 0x1ebd187,0x1421413,0x16ed7c4,0x176cb55,0x0d3320a,0x12c34ac, + 0x1d969c8,0x1576084,0x18f0986,0x11f99fc,0x1fd40f6,0x0f4f5d7, + 0x0541180,0x012fb8d,0x11ddb2a,0x1e4964b,0x1edff7d,0x0606f3d, + 0x197c7ed,0x161e842,0x1ae3da8,0x1bb98f9,0x17cffdc,0x07c14a4, + 0x1d7e719,0x1232668,0x0edacee,0x1bf0954,0x1f37828,0x1c4bd50, + 0x11eea12,0x1cee675,0x07960cc,0x00d10b7,0x1aad426,0x1a9a8da, + 0x1cbb80e,0x009612b,0x1bc247b,0x04e572d,0x079e7ad }, + { 0x130caae,0x0b86e47,0x1bd0f36,0x0214dd7,0x05cabcf,0x0a30b6c, + 0x018fb1c,0x130c783,0x1519e3a,0x0286d85,0x0c4f587,0x12c6c99, + 0x09f39b8,0x112a3db,0x19f607c,0x16199be,0x1b9d67d,0x1b8abd5, + 0x025246d,0x144b751,0x00dcccc,0x1e3d13f,0x1da2481,0x1a86503, + 0x08fbe0f,0x0049a57,0x0d5c83b,0x0bb23ee,0x1d7beda,0x0c84e6f, + 0x0cacbd8,0x094073c,0x0c10232,0x0c7ee0f,0x197b6c3,0x1ba787a, + 0x0fe5005,0x048b642,0x1aa50cb,0x1589817,0x07f8c37 } }, + /* 92 */ + { { 0x1ac05e5,0x00f2a21,0x0094cfb,0x099b1a7,0x1a4a4da,0x1fcf15e, + 0x0302e22,0x1b90db1,0x0b53811,0x06b8ee8,0x0eae90d,0x01a5478, + 0x1e65504,0x1b0b08d,0x1102526,0x09f4057,0x06e279a,0x18e16a1, + 0x0c196b0,0x14b5447,0x0890535,0x17e2975,0x16aa28c,0x1bb5a45, + 0x1eca79f,0x137ad2e,0x14aacec,0x023e0bf,0x1cd81e9,0x13edf9b, + 0x03176b3,0x121a2d7,0x00e44e7,0x0c4a707,0x0bb793d,0x1e2bcd1, + 0x1c92a74,0x1024ccf,0x1f0bebf,0x1552e1c,0x01d7703 }, + { 0x10062a9,0x0640e9f,0x02eaa29,0x11b2d44,0x031eb2b,0x05e880f, + 0x0637e19,0x028cdbb,0x04413b6,0x102fac9,0x1557e2e,0x141bd34, + 0x1151a67,0x1725a96,0x10bc25c,0x1564759,0x0ec7184,0x1d5aed5, + 0x11fda46,0x11687cf,0x07f4ce0,0x05bb621,0x148394c,0x047d7b8, + 0x12069e4,0x0673e9a,0x00d37c5,0x16bc73d,0x0305ac6,0x194aa23, + 0x104f72f,0x1fc699b,0x02cb2e1,0x1ad7db4,0x1744447,0x13a9588, + 0x07f296f,0x17b1e6a,0x021c717,0x1d92784,0x00a2c40 } }, + /* 93 */ + { { 0x15747db,0x01c27d7,0x01ac26f,0x0d80d57,0x1bad608,0x1e0aa39, + 0x020ba79,0x17f480d,0x155977a,0x0a99368,0x077ac0b,0x140bb50, + 0x11063a9,0x0925b08,0x01b929d,0x1d72135,0x07a4ab2,0x10a017c, + 0x171802e,0x0e43a9a,0x1dbf7d0,0x14f944f,0x068bf66,0x1bcde0e, + 0x0e66dec,0x139faee,0x1f6ae7e,0x042e24e,0x074bab6,0x024fb62, + 0x0cdb4b7,0x0eddda0,0x0017e1f,0x012e9ee,0x170136a,0x0772e2e, + 0x14b05e4,0x14bf1ea,0x121f9b0,0x08cad93,0x02efb45 }, + { 0x121c064,0x0958045,0x0a7a91c,0x0494e0c,0x1186fe4,0x1a7857e, + 0x0cd026d,0x052c86b,0x17ec9e6,0x0b2d521,0x183421a,0x0ce7898, + 0x0adda14,0x1f982bd,0x19599c2,0x0dec016,0x0403ce8,0x13f82f4, + 0x1100685,0x00e7520,0x007ec05,0x1c14a73,0x05ac798,0x19ee08c, + 0x0325269,0x09d103c,0x0fa339f,0x1282283,0x17053d2,0x0c69bab, + 0x0374e2b,0x1954cc6,0x1a68fb3,0x021a86d,0x1fc7a54,0x17d97d5, + 0x1d2d760,0x08b36a8,0x047927d,0x19c8c51,0x0337532 } }, + /* 94 */ + { { 0x000bb9b,0x08c299d,0x1a14fc4,0x1c8becc,0x0d2ffba,0x1771269, + 0x06a1752,0x0dd35c2,0x1034185,0x05d0f0d,0x04d27c6,0x02f04e6, + 0x15a9ac8,0x0a2b8ad,0x0f7f529,0x1a5d582,0x03c5daa,0x1d2fba1, + 0x0d6dda9,0x090772a,0x1e9b30a,0x127fc39,0x04ba6b6,0x07420ab, + 0x02d8472,0x0700ab3,0x0e3b6b1,0x126a92f,0x18fa70b,0x020d1ce, + 0x07d86d9,0x081a2b1,0x141d756,0x02f850a,0x08dfc28,0x10c5328, + 0x0bb2890,0x05801a3,0x0cafff6,0x0bba99a,0x0192a2b }, + { 0x05ced07,0x1b3141b,0x147d8d5,0x160bbc3,0x029f32f,0x0053d50, + 0x0e6f2fd,0x08eda2f,0x09bb50a,0x18d9504,0x0989e06,0x1776f2b, + 0x1b9389a,0x19a7e0c,0x13fd83e,0x10e72a5,0x092387d,0x179d5ca, + 0x0483335,0x00a7ccd,0x14f0a8f,0x05b1d4d,0x0fbcb75,0x1d04252, + 0x0ede151,0x1d0cd58,0x0c20e2f,0x1f74181,0x1c11bea,0x13d64ff, + 0x1e0af56,0x12b9810,0x18bfd95,0x1786302,0x028fe30,0x14d0da9, + 0x1d9b31b,0x1d5d578,0x109a30c,0x1127781,0x0632e22 } }, + /* 95 */ + { { 0x1a1ccca,0x08e900a,0x0f0c721,0x18fca45,0x0efe290,0x155829a, + 0x0755463,0x02e16e8,0x1bc85e2,0x132b0cb,0x1e2ca6b,0x083c039, + 0x18ae131,0x134a423,0x0b2d64d,0x1b15c5c,0x10fc31b,0x075abdd, + 0x09939e2,0x1debad8,0x0d86dec,0x064e5cb,0x1bea15b,0x12307b4, + 0x1681327,0x0b516d8,0x00e0f5e,0x007e704,0x0c6fedf,0x0b7f8e8, + 0x06d6291,0x114d57b,0x1589805,0x0b78c92,0x0b160fe,0x0e673ea, + 0x1a7e9ea,0x16f6c7e,0x135173d,0x182ba39,0x068c3d9 }, + { 0x0b392b7,0x13132f3,0x14259f8,0x1eeebb2,0x0ec1d9b,0x128a7be, + 0x0f3535d,0x039c2d5,0x00de72e,0x037acd9,0x1ec0cf6,0x079a35b, + 0x0ca66e4,0x02f22be,0x0d10d00,0x1b545b6,0x1165681,0x0db3d3c, + 0x00451cc,0x1cf757e,0x0961c32,0x1769d8f,0x019bf85,0x07a4dcc, + 0x0298ef6,0x0b6c927,0x01506b7,0x17d41bb,0x02f9719,0x006fccc, + 0x0b3be54,0x18be0ed,0x0876e63,0x09cb5ae,0x0b96c8f,0x14abc25, + 0x0ec6747,0x17dd9b1,0x01a9427,0x1dc4665,0x08f2055 } }, + /* 96 */ + { { 0x02c1af0,0x15cf1dc,0x0991292,0x0fe595c,0x1c65e9e,0x0c3ea37, + 0x0b02980,0x0c69fd5,0x1e393b3,0x1e9f99a,0x0eb3389,0x1801033, + 0x119c9f7,0x1c55330,0x1d062d6,0x15d2a7e,0x157372a,0x0ffd4a2, + 0x16ce162,0x1af0091,0x1c1c937,0x0fb78fd,0x144321b,0x1e1419d, + 0x0bd89a2,0x0f5a457,0x08d9d0e,0x1cbabf4,0x17d2d8a,0x15059f8, + 0x05040e9,0x0823b31,0x033f68a,0x1b3d179,0x02cc862,0x0cffd9d, + 0x0319bf0,0x112a079,0x0c8b810,0x192681a,0x01292c8 }, + { 0x186463d,0x1aac381,0x05ffd7a,0x0406e3b,0x14bbc2b,0x00ce2d6, + 0x115c42e,0x082366c,0x0cf04ad,0x05da16b,0x0e7b043,0x18eccd2, + 0x075d819,0x100c23f,0x116b04e,0x065c90e,0x1021c72,0x027b825, + 0x12c15e0,0x1cb1415,0x02952c9,0x19dab0f,0x0548ee2,0x1f3746b, + 0x0df0079,0x11419c2,0x087aaa5,0x10463f8,0x0a2b907,0x02a7c57, + 0x18e8bab,0x061a384,0x075ed77,0x1c80040,0x1b57ecc,0x1559689, + 0x1011293,0x0a35617,0x05d9249,0x057d704,0x07c7876 } }, + /* 97 */ + { { 0x07902b6,0x1eb7d83,0x0602e3d,0x07a2e6b,0x12823a4,0x1a0eeed, + 0x1ec4965,0x0b80c59,0x14033f9,0x11c8d83,0x026e31b,0x0146d0b, + 0x123831d,0x0911487,0x11d3525,0x03e75c6,0x0d6222e,0x0a6d58a, + 0x0fc234e,0x01f9bca,0x08f58f0,0x17383f9,0x156645e,0x11cc0f8, + 0x0a0ba06,0x0120b35,0x1f5f87e,0x004e27c,0x0a328f6,0x0aa026b, + 0x0a9f095,0x131219a,0x12e3264,0x0590506,0x0513b28,0x19e440f, + 0x12f4e09,0x0c6e03a,0x1a07572,0x009b09b,0x0694035 }, + { 0x1407206,0x1d9b372,0x0a33e2d,0x1e1b11f,0x1ecf54c,0x1397378, + 0x19523dc,0x0d0dfdf,0x081ab44,0x12989b9,0x1d10235,0x1e1c9c8, + 0x1f52cb5,0x124839b,0x109ace9,0x1a0e33c,0x19b4980,0x192bb60, + 0x1c9cb2b,0x068c501,0x11c991f,0x07a3479,0x1e39829,0x1089b12, + 0x0a32990,0x015c3bb,0x12e5456,0x14aae01,0x11adbf8,0x19b28a5, + 0x1beac6b,0x1f7a687,0x0ebff92,0x00f9a11,0x0c06df6,0x0265f3f, + 0x1a6b30e,0x0287035,0x0551ab6,0x04f78bf,0x06da9e0 } }, + /* 98 */ + { { 0x09490ce,0x172612e,0x0e0487b,0x061bed0,0x096ec4a,0x149b475, + 0x01f8292,0x1e7cd8c,0x04bc262,0x0582495,0x10d3ff6,0x04208c1, + 0x0d0846a,0x146f99e,0x1fde990,0x0ec25ef,0x0442182,0x08862a8, + 0x126f340,0x0bf9d22,0x13dc9d2,0x06e7e30,0x1c95847,0x1ea39ca, + 0x17e8897,0x05a8acf,0x053a302,0x1f477e6,0x07538f3,0x108abaf, + 0x083a855,0x1239080,0x1e0a951,0x1568568,0x02eb3c0,0x1e1a44d, + 0x058b8e5,0x0635620,0x1644a81,0x17366a2,0x0773b40 }, + { 0x031cfd2,0x1966e1b,0x1ef003f,0x0700ee6,0x14c4c2d,0x0529380, + 0x185a8ce,0x1bdac00,0x1b32cab,0x0719836,0x0c5f2b4,0x11d54e1, + 0x0e33673,0x1cf9a9f,0x1d2aa35,0x075a7e5,0x0d9576f,0x03897b5, + 0x06caf38,0x0f30a51,0x0a30e42,0x06ed496,0x01763e5,0x0925bb2, + 0x1d475d8,0x05ecc48,0x0934579,0x1c0d4b9,0x0eabbd3,0x0a7592a, + 0x0f11c97,0x181daa2,0x1394ace,0x1573618,0x0166efe,0x0efc1f3, + 0x033fd13,0x092aa34,0x13dd770,0x10b8ad8,0x012b463 } }, + /* 99 */ + { { 0x12951de,0x0df5ec9,0x1252043,0x04b54d3,0x16959d4,0x197846c, + 0x07013b2,0x058bf89,0x02250b8,0x03a7866,0x113876b,0x134a75d, + 0x0d96a43,0x0824cd6,0x0f2ae6a,0x1675f86,0x06654d9,0x197e66f, + 0x018eba2,0x1e50b87,0x1f88f4a,0x1f237f5,0x08dccdc,0x1356fda, + 0x1672c3c,0x1063a8e,0x03f8480,0x038a226,0x13e56ec,0x0017a97, + 0x006b609,0x1494c95,0x089ab7a,0x0b1f91a,0x198767c,0x0e143f6, + 0x0e55331,0x034df08,0x1505c5f,0x0bcfb11,0x061c193 }, + { 0x092ae43,0x116cd9a,0x0168b9c,0x0a0a71e,0x1ef89d9,0x0555b18, + 0x1962080,0x02f5cef,0x0eba4b1,0x0396090,0x1872e0a,0x0590748, + 0x065c243,0x05c9c79,0x16cd0d3,0x0fb8062,0x0c58c4c,0x082df95, + 0x05acde3,0x0a03bab,0x0c30d2e,0x0fe5c48,0x0a141b2,0x06c3e19, + 0x0f4617c,0x1d71e85,0x0168d72,0x03ef6e3,0x1c01382,0x1af8f9f, + 0x17ef440,0x116491d,0x0628af5,0x0e5703a,0x0741232,0x071ac84, + 0x0ca1877,0x11ed1c9,0x16e51d7,0x1e4e3a7,0x027ad0d } }, + /* 100 */ + { { 0x05b5aed,0x1ed3c98,0x1a9e78e,0x08b331a,0x0c67d4a,0x1f5b801, + 0x1874c3d,0x08990ab,0x0147d1c,0x0c53f4f,0x1503b70,0x0c31912, + 0x003ea99,0x1f35fe9,0x0ef8829,0x0886f4a,0x064ecc1,0x164a43f, + 0x13be171,0x0f240e6,0x0bd5729,0x18eaf0f,0x1e83539,0x091ad6d, + 0x0b1e64d,0x06a7ed1,0x159b880,0x10543c0,0x1366a17,0x186d2d2, + 0x0e0a8f1,0x0348e6e,0x03fbd2b,0x010747f,0x1019ff8,0x0bafdf1, + 0x0acfb66,0x1437ef7,0x150bfb1,0x04edba2,0x05d9b5e }, + { 0x13e472e,0x1e2d2e5,0x0178d8d,0x0e61428,0x0153d92,0x04c2ac1, + 0x04b96d1,0x0a20133,0x1f39a08,0x0780666,0x1b15806,0x18236b8, + 0x0e26237,0x09a1aa0,0x03b5020,0x0630883,0x1f07e7f,0x1ff7be5, + 0x1d215da,0x1246cd7,0x091aecd,0x0d5e4a6,0x06dd6f8,0x02c44ec, + 0x178de4a,0x05c470b,0x0f171af,0x0a5cafa,0x171858c,0x0163ad5, + 0x1e5730e,0x07edc73,0x12c2c28,0x19afe70,0x1bcb589,0x0c98fc1, + 0x035a599,0x18ef58c,0x11d9b81,0x19b9771,0x024f891 } }, + /* 101 */ + { { 0x178c1e2,0x1b05fb3,0x197093b,0x1a01ab7,0x1f49c03,0x00d04ff, + 0x061b8bc,0x0b1d823,0x0ae096e,0x0d39452,0x1e61316,0x1db6e0e, + 0x05aabbc,0x038652d,0x11cef4a,0x01c7bf6,0x0614de3,0x1464946, + 0x1d9eaf2,0x1cff349,0x09cf3fa,0x15f610d,0x00f0acb,0x1b36bbd, + 0x10d629c,0x06fd7d3,0x07182c6,0x1bd5d4b,0x09b54ca,0x1bdf202, + 0x18f57fb,0x0dba621,0x0eebc76,0x190e67e,0x1f8e3d8,0x0aee91d, + 0x18ee8af,0x0e19588,0x1d84bfa,0x19fa85b,0x0863ac3 }, + { 0x05a2fe2,0x17e53dc,0x171828d,0x11dc853,0x13e70d0,0x0e1ca27, + 0x0882450,0x0151937,0x067272a,0x0354083,0x02f418c,0x0aabf2d, + 0x1de69a1,0x0a9e301,0x1bdf91c,0x1c9f570,0x14aef56,0x04b8330, + 0x01e02d3,0x186d713,0x1263c0d,0x111d0e9,0x10d95ff,0x0aa4592, + 0x17a8643,0x13c80fc,0x1bb7fbd,0x12312fe,0x0a17a0d,0x18ea36d, + 0x0f7aef8,0x10b599f,0x1179100,0x1e0ef37,0x18ca3e7,0x19c1b4d, + 0x01e7142,0x0ea9edf,0x1c96872,0x03d170c,0x03e3f1b } }, + /* 102 */ + { { 0x17fbf05,0x10ae03d,0x020adfa,0x0c3e347,0x192f11b,0x0e68de4, + 0x1656b47,0x11793bb,0x0ad0f7e,0x0fadbfd,0x1eade4c,0x0bd7f94, + 0x062936e,0x0cd2adf,0x1d05f70,0x1caa861,0x04343cd,0x18fb7a7, + 0x0bc112f,0x1ebccb0,0x0408971,0x1221446,0x1cf0ee3,0x00feaea, + 0x0c59fb8,0x07830d5,0x16062d6,0x0c9dc5b,0x03b0d3a,0x05304bd, + 0x161bde8,0x0072960,0x185ecc8,0x1a8bec5,0x11d2fec,0x0d340b2, + 0x079c3f0,0x16acbbd,0x0009626,0x1b0e015,0x081208e }, + { 0x0c4ce37,0x1a84c8a,0x0298424,0x0743549,0x134bb84,0x06ac747, + 0x1c09160,0x1750c00,0x1b375b8,0x0da1624,0x0f7a0db,0x0a49da7, + 0x16ac365,0x124919d,0x08786d1,0x128deaa,0x1d564dd,0x15e3e62, + 0x1ed6dab,0x09606b7,0x01a39c1,0x0c00a36,0x1fc8ae8,0x04429ea, + 0x0fbbc87,0x1b205b1,0x1ed2485,0x159fafe,0x0d6df13,0x06d0e5a, + 0x0457fc4,0x0c4c015,0x00e2620,0x08b3fb3,0x0a76076,0x12f58fb, + 0x16e7a19,0x0713065,0x0cf09ba,0x17101bd,0x044383f } }, + /* 103 */ + { { 0x04f9af6,0x1f80ef2,0x0873841,0x1b1963f,0x16381a4,0x1eea499, + 0x18fb3ed,0x13fccb7,0x026a883,0x05c21ad,0x1e27634,0x122a7d8, + 0x1fee60f,0x15e62f0,0x17fa940,0x15039c4,0x0c57e44,0x0023be0, + 0x0c2e96e,0x1d3f064,0x0dd9349,0x17ef0c0,0x1750bcc,0x147a239, + 0x19eaf64,0x01d4581,0x1afadc2,0x01df109,0x0742cb8,0x1062789, + 0x188a239,0x0e41404,0x0156cc5,0x1dbbfa2,0x1799c94,0x139aa8f, + 0x06013a5,0x14d3765,0x0111660,0x11e1aa9,0x08aee70 }, + { 0x0c54409,0x116ce19,0x0b1063c,0x0cebd75,0x09ebfa4,0x1424c0d, + 0x1a4a218,0x01921c5,0x16b3a8e,0x0100fb7,0x1d907b4,0x02d97ae, + 0x15c9730,0x180b82b,0x09bcbc1,0x19c03f2,0x08ffec0,0x024c202, + 0x0c674c1,0x12c423e,0x08c4bf6,0x02648d4,0x1d2d721,0x0061504, + 0x0fbcee0,0x090a620,0x1793db5,0x1dacea4,0x167d1eb,0x03e614e, + 0x0dabdf9,0x1843a6a,0x0307db8,0x14a02fd,0x11aaeec,0x1ead6d8, + 0x033e805,0x0cd3f18,0x09683c1,0x1fcc12d,0x0970f61 } }, + /* 104 */ + { { 0x1ec8e4a,0x09e918d,0x0d306f1,0x086b4c0,0x0809ac1,0x0f2326c, + 0x0076942,0x06a9dc1,0x18a4882,0x0b570fe,0x0192d92,0x10c664b, + 0x1fa1ae9,0x1a66834,0x1284fa5,0x14d6975,0x058b1d8,0x01b9c66, + 0x1dae769,0x0e3eb1c,0x16fb5fa,0x0463f58,0x12466fa,0x09c853b, + 0x0f13fad,0x0f6fae4,0x049267e,0x0b076ce,0x0d8bd74,0x008ad08, + 0x1faf388,0x0af2176,0x06d7605,0x1bc6efb,0x1b7920a,0x15262d5, + 0x15f855f,0x0c7d96b,0x1329f83,0x128b4fb,0x0404b5b }, + { 0x17a15c7,0x1341528,0x080be7b,0x19df100,0x0ae4cfb,0x0351aa5, + 0x104e544,0x1cf9dc5,0x0170feb,0x0f300c9,0x03152d7,0x13fae7a, + 0x17589e3,0x0648495,0x171c4d6,0x1fcbe32,0x13f0a7b,0x0e5bf6a, + 0x187325e,0x124855e,0x17d92bd,0x1629caf,0x034bbc5,0x1665e13, + 0x0c1ca70,0x0e086a5,0x154b461,0x0b0ea4d,0x0d6195a,0x18254a1, + 0x0b0a4ca,0x14a0161,0x025a979,0x1e9187f,0x12b958b,0x18bf43e, + 0x00da253,0x1aad791,0x1800983,0x16b0628,0x07faa11 } }, + /* 105 */ + { { 0x0402149,0x1278637,0x0466c2e,0x1b2c798,0x1584cc1,0x093a3b1, + 0x1706a99,0x1e4ee81,0x1c95715,0x1bbffba,0x07ec38f,0x095a7f1, + 0x1fb2f23,0x17cdf1f,0x05640cb,0x0fd04aa,0x01d0423,0x1fe4fd9, + 0x054fb64,0x1dfe714,0x1d13eb2,0x1008020,0x02754eb,0x037b051, + 0x0545b7f,0x152e797,0x190e54f,0x1a944f9,0x1e75c8d,0x12ea6c2, + 0x10c034b,0x04837c3,0x193ed62,0x10196f5,0x097c090,0x023ca7e, + 0x03a4e70,0x0abb1b6,0x1fafee6,0x0a5db31,0x014b63a }, + { 0x1c43336,0x05aa9b8,0x092dd84,0x0c47490,0x19dfd4a,0x03028d8, + 0x08b800a,0x1b6f72f,0x08f5f1e,0x155ddce,0x1f6ab61,0x1aef36c, + 0x1b67a57,0x06affd7,0x13941b7,0x078c715,0x19589ac,0x042ed4f, + 0x168f454,0x197550e,0x0ed2081,0x07f49a3,0x00cd4f6,0x1f3405a, + 0x161f1a1,0x038d955,0x1ce9967,0x0196126,0x1df8a1b,0x1185a7a, + 0x076df83,0x1d6fab4,0x1c4c741,0x12e783b,0x1271ca3,0x191e08d, + 0x17c171a,0x0e85e3f,0x09954cb,0x0e706da,0x0024858 } }, + /* 106 */ + { { 0x1a4cd8d,0x06e91ba,0x09e3350,0x072f797,0x132ca43,0x06b0fa8, + 0x1361096,0x0d0618b,0x1da1e8e,0x13f602c,0x1750282,0x02e23ac, + 0x1607a8f,0x1a1a86b,0x079957b,0x15c850d,0x0f05983,0x05cc673, + 0x162faf4,0x02723b3,0x1d497b6,0x12d8dd2,0x0e94a78,0x0d659ec, + 0x132e91f,0x114a37b,0x08fe8ed,0x1acdd8d,0x0f0ed2b,0x087661f, + 0x1d8e5e5,0x0be1168,0x09008cb,0x1071777,0x1096596,0x0ffad7c, + 0x1177bc8,0x16a89e0,0x0b6b9e3,0x1bffca2,0x06798ce }, + { 0x197c5c6,0x1fc7e8d,0x0cfd278,0x1cf1876,0x19fbab3,0x1acadd1, + 0x1104903,0x0ec884e,0x15d7d43,0x1a112dc,0x111ddc5,0x1f98f38, + 0x05880b3,0x194b592,0x0eb2a0c,0x1c309b8,0x1f71734,0x12ac89e, + 0x124d11c,0x1647a73,0x0a11a4d,0x19e8a10,0x13aecdc,0x0c117b9, + 0x00cf9f3,0x09fdce9,0x18c33f8,0x0c3159e,0x10874ca,0x1598af9, + 0x095d7c1,0x13e000b,0x06efe7f,0x1e4eda8,0x1e3006f,0x03155d4, + 0x178e7c4,0x0bc92af,0x18e57e4,0x1a4a5d2,0x03ea7ae } }, + /* 107 */ + { { 0x106ae25,0x0bf022d,0x03be618,0x1b96aea,0x1cac148,0x0615d15, + 0x0bc3981,0x0eb23d4,0x176b789,0x060cfb5,0x1686040,0x0da0ca3, + 0x1b79b9b,0x04a2b82,0x0896faf,0x0b7e3e6,0x1f35c00,0x0985a1a, + 0x109361b,0x1689057,0x1777440,0x0b6b1b9,0x0ae3c26,0x08969b8, + 0x16c561c,0x0ccb2fe,0x18c241a,0x1280bdc,0x0a1ec1e,0x0492045, + 0x05467fc,0x07a5e51,0x0f3246a,0x033cbf7,0x1d96f1d,0x1c02d86, + 0x10705f7,0x092b4fe,0x001118b,0x1380a4a,0x06a8ad3 }, + { 0x0be7282,0x18106a3,0x1c4b917,0x1a42701,0x1405afe,0x0d35684, + 0x096f757,0x03c99b9,0x07f8be6,0x16b78c2,0x0e05e30,0x12a6b2d, + 0x1420132,0x1d46fca,0x0ec79ed,0x0569b1a,0x1bb3957,0x13abe30, + 0x0330ed5,0x136af70,0x1fecd74,0x099bd9f,0x05643fe,0x0bb929b, + 0x1b65314,0x0b99cdd,0x188cd79,0x01838c0,0x03feba7,0x196bfbb, + 0x0ca70b9,0x198c36e,0x168e424,0x1f96523,0x1e9aa9c,0x1aeefa5, + 0x05cb58c,0x126dd56,0x186ab7b,0x0f339f5,0x01a1811 } }, + /* 108 */ + { { 0x1575ed0,0x1fb17bb,0x066dbdb,0x12fa3b5,0x18f14fa,0x17ebfb0, + 0x0bbeda7,0x0665ce5,0x1ddc286,0x02d5a65,0x1160d31,0x1a90b0d, + 0x18b0e20,0x1cbbaee,0x05c0468,0x08931a7,0x008f413,0x0009864, + 0x14457b6,0x011d75e,0x1ed92d4,0x0e01306,0x1141a81,0x1957223, + 0x1736219,0x1434f2d,0x1ba1a4e,0x19ea118,0x1736174,0x122fe63, + 0x08d39c4,0x12bb139,0x171aa1f,0x1de4c17,0x11a981e,0x049774f, + 0x012b7fd,0x128af39,0x1d6a3ce,0x0eb2461,0x07d2ddc }, + { 0x0d2cae8,0x0c0b6a7,0x0ddcf41,0x1b73800,0x0cf6bc7,0x15846a2, + 0x0639991,0x101847d,0x14b9c01,0x0f73630,0x05e707e,0x1427df2, + 0x0ae11c9,0x076cb44,0x0d851fa,0x0e14f4b,0x048d066,0x0bd7f5b, + 0x1da149d,0x0066782,0x08f2d67,0x14bafcf,0x0a27765,0x14d15bd, + 0x1228d37,0x0c35dab,0x191532c,0x0340bab,0x1dd5502,0x0ac7831, + 0x1cd2040,0x0996d95,0x0dd4f08,0x055f3c9,0x0149e15,0x0ce189b, + 0x0e729d7,0x0cb4ee3,0x102ea11,0x0f5637e,0x05a52f8 } }, + /* 109 */ + { { 0x1ecacbd,0x0cf4884,0x17abb40,0x1af7137,0x0544023,0x039b8f3, + 0x07c2d5c,0x02ef98a,0x016c8e2,0x0419582,0x166ad45,0x0d05024, + 0x14b1aa6,0x11f1b0e,0x0403e48,0x0b854dc,0x0e9e3a9,0x172c9f7, + 0x1b04389,0x16d77a2,0x013f699,0x19ca39d,0x0b521e1,0x0e930f9, + 0x14dc5b2,0x174f8e0,0x1495678,0x0fb800e,0x147ad25,0x024ee1e, + 0x04e1126,0x1baa4ef,0x1df278a,0x0adccc1,0x1b23bbf,0x00ee1c7, + 0x16bd02a,0x12c2233,0x17ff8ab,0x0c87ce0,0x017f027 }, + { 0x1abea1f,0x0008694,0x1133769,0x0a480f5,0x036b969,0x1990c5b, + 0x004a410,0x0952d4c,0x1163d53,0x110fe1d,0x081597c,0x0b7d998, + 0x1705ba1,0x0b142ab,0x0e39536,0x009a624,0x0578788,0x00d8a21, + 0x026a7f9,0x17e6095,0x02b196f,0x1625f32,0x1229fc1,0x05610bd, + 0x020e86e,0x08eee8d,0x0bfd296,0x1efe4f8,0x0343b88,0x03a9d25, + 0x13705ec,0x1762e7a,0x04b1e88,0x03ddf34,0x0910f70,0x0e7599d, + 0x0c441d7,0x0ae446a,0x055fb6c,0x134a7cb,0x00ef030 } }, + /* 110 */ + { { 0x08e5b60,0x12b90fd,0x0ec93f0,0x1ad2381,0x046938a,0x0511243, + 0x12dd82c,0x0efc8da,0x07de168,0x11fcd61,0x0718c21,0x0dde4e4, + 0x02503bb,0x05b3fd8,0x106677c,0x17a73f1,0x172e07a,0x13c60f6, + 0x0cbc376,0x1bd6f76,0x09f3cf9,0x18361e4,0x0bfdc9b,0x0e444b5, + 0x08b2d19,0x1ae5b80,0x1d3c517,0x1eb4c22,0x1c4f378,0x17c622b, + 0x1913839,0x0388a78,0x1bdaa44,0x0964045,0x09b69ba,0x02af7c6, + 0x1d77356,0x1e1feca,0x0dcaaa6,0x18d766f,0x03d3b6c }, + { 0x122c880,0x189664b,0x0225b9b,0x0e50d6d,0x1a1b6ae,0x17d7f61, + 0x1026eb4,0x1df7439,0x043bb8b,0x0b256bd,0x0fd30eb,0x14012f8, + 0x1ba5af6,0x01a9d48,0x1f2c367,0x17ed655,0x0ab69cc,0x06509fe, + 0x0aaf064,0x142723e,0x07e5699,0x0111d12,0x0b6f555,0x0911b34, + 0x0180f95,0x01e7103,0x1c49133,0x153cf7f,0x13a365b,0x1d5f43e, + 0x188a4a5,0x1f4994b,0x054fa38,0x10db620,0x08f59ef,0x096720c, + 0x18f41a4,0x133e2bb,0x1139c7e,0x0878f6a,0x02e946e } }, + /* 111 */ + { { 0x00934ae,0x07eefe3,0x1b44a60,0x1e2c840,0x0c3e7ef,0x176bad1, + 0x1fe5905,0x1b9eebc,0x15cd0b2,0x1630679,0x0b61efe,0x1d9c3f5, + 0x1dddc4b,0x0c24f2e,0x0fea1f2,0x1e35cea,0x0a32c1b,0x1e2ea8b, + 0x11ccad2,0x1b7d502,0x096b565,0x1d67243,0x001faf8,0x172ed28, + 0x074d6cd,0x1df2065,0x0197939,0x1eb9a4e,0x0c4ebc3,0x1e009d5, + 0x085d211,0x087ad87,0x162e034,0x103b533,0x125519e,0x1ad21b1, + 0x1eda677,0x06bc6b0,0x16309da,0x0aa0303,0x00997ce }, + { 0x05a0b81,0x1ba364b,0x17ea4a5,0x0dcbc25,0x08b58be,0x0fa1bfa, + 0x0cf11c5,0x0b2aae7,0x1b565c4,0x012f483,0x09e5f39,0x0a242b0, + 0x0f4f43f,0x0752a3a,0x16be9be,0x00959cb,0x1be13de,0x19575c7, + 0x0281f20,0x1f2be1d,0x09feed7,0x1733160,0x0f804a9,0x0859e2e, + 0x0e9b8c7,0x022dfcb,0x0b8a287,0x1d4aeb3,0x14e2f38,0x00da2e7, + 0x0651d65,0x1f20340,0x1d3c02d,0x0b5973e,0x1ba9c24,0x11cf49b, + 0x0fa9b98,0x19395a9,0x1ff9942,0x13fa122,0x096f9f0 } }, + /* 112 */ + { { 0x0310a96,0x0556216,0x1cd1e3a,0x07ef454,0x12a9830,0x0b11039, + 0x0a0f48e,0x10188d9,0x0d95412,0x0898f37,0x0fa446b,0x18bc595, + 0x085791f,0x020db63,0x12ddfae,0x110f0a1,0x1ea3d3c,0x157fc9e, + 0x0401ef3,0x083e3be,0x11fd065,0x012ae6f,0x13b9ca7,0x07c72e4, + 0x1131732,0x060f07b,0x06b5342,0x05bcf48,0x1e22bfa,0x155fd1a, + 0x096a644,0x1136066,0x050122b,0x0a6a750,0x07d0194,0x17173ca, + 0x19d3e0a,0x1e3d56b,0x1fa9508,0x04c8171,0x071998e }, + { 0x0b6ed78,0x007e6e7,0x1459005,0x0e30a68,0x053cf37,0x0b06e63, + 0x0d96ba3,0x1f008a1,0x09dac55,0x1360d3b,0x15a1b33,0x125b5c0, + 0x028a96a,0x093892b,0x1911d88,0x1284a5f,0x150a4f3,0x13a3de5, + 0x114c7f0,0x18dfe5f,0x1ff0f0e,0x03887f4,0x125f0d1,0x0f259ff, + 0x087839c,0x00cfda4,0x0009bec,0x0a58a49,0x04c2905,0x114e6c0, + 0x1cd0006,0x06b9194,0x02b5ad8,0x0efd03a,0x1c5dbb9,0x0386f03, + 0x1dfa4ab,0x15c2f81,0x0cab329,0x034161a,0x0838994 } }, + /* 113 */ + { { 0x0067dff,0x031516f,0x058b03c,0x0179700,0x14f3269,0x03d15ee, + 0x064341c,0x123319b,0x0fae4a3,0x17e31dc,0x0b60516,0x16f7665, + 0x11684f1,0x18ccefd,0x08b738b,0x0b09161,0x17f48f2,0x1113070, + 0x0b57a18,0x07b6018,0x1171739,0x0a19c67,0x07a23e1,0x159ea45, + 0x1942902,0x19e8033,0x01a0d6b,0x122af97,0x02614c1,0x17c95c5, + 0x1b0bea9,0x0269d88,0x0ff95f5,0x1409a82,0x09bbede,0x099e00c, + 0x137a470,0x059e82d,0x1b09515,0x0624d29,0x01fbfda }, + { 0x0f69c77,0x1db2be4,0x03ebf7a,0x1747bf1,0x12a8278,0x1dbc5a4, + 0x155c707,0x0668c76,0x011c71a,0x103350d,0x0562c34,0x0286113, + 0x0610c88,0x07ceb3d,0x1d71f83,0x0f71f72,0x0087303,0x0ed52e9, + 0x02fd618,0x0a00ba8,0x09a95ee,0x13bedd3,0x0c039b3,0x0c598e8, + 0x03cb3c9,0x02ac49e,0x0533e10,0x15930c5,0x1c9d700,0x1b1d112, + 0x1a029fb,0x1723c8f,0x0184869,0x1c25f7f,0x17ae30b,0x1e373af, + 0x00e278b,0x1c448ae,0x1c6799d,0x195884d,0x04f9488 } }, + /* 114 */ + { { 0x151b8ce,0x0fe6a6e,0x1a01843,0x106c461,0x0857927,0x0ccab10, + 0x1fc70d9,0x0efdb8f,0x1e2cae8,0x02f56a5,0x19d8224,0x0bb3cf2, + 0x0ca1c32,0x1e9c493,0x0e7b776,0x0149c7c,0x0685f6f,0x06d4964, + 0x11e83e9,0x1f0015e,0x0aabe16,0x0df2fb0,0x142d36d,0x070a7a6, + 0x1412f98,0x04e1b32,0x026de5e,0x096c44a,0x0e72b26,0x002c270, + 0x0efa958,0x1caab85,0x1bd4901,0x09708d5,0x069c5ca,0x1e6f083, + 0x0174218,0x05ad557,0x1ae49b8,0x1091ef2,0x0688e06 }, + { 0x13b8f64,0x17b2098,0x118b37f,0x172858e,0x0ef11b7,0x06c55ed, + 0x1eddd70,0x1520cf9,0x0af4041,0x04752f8,0x14843d8,0x1b04d26, + 0x0823d5b,0x13c8bd0,0x0e413f0,0x05a42b5,0x1fe45d2,0x1c2edd8, + 0x14d8567,0x0bca129,0x18f2c3d,0x070e9cd,0x0baed4a,0x0959de1, + 0x0a828f4,0x12a6eae,0x1c8315e,0x084135b,0x195f442,0x1a19bc7, + 0x0dd5d0a,0x15266fa,0x11fa7d9,0x07edbe8,0x1027193,0x19acd41, + 0x1bb817e,0x12adc7c,0x049955b,0x1c7c988,0x01723c7 } }, + /* 115 */ + { { 0x08b43f3,0x0436c6e,0x19a2699,0x024c813,0x1c3e0e6,0x1a3001f, + 0x110df66,0x0f63113,0x16284ec,0x142819a,0x16eba8e,0x0b88d53, + 0x1c5a366,0x14bc499,0x1da5077,0x02920f7,0x1106934,0x08f6ad2, + 0x12e000b,0x14f6f51,0x0a59664,0x1230768,0x180fddb,0x09d7e4e, + 0x06ba31f,0x13fe1f0,0x07cb0e2,0x12d9da8,0x1db08a2,0x07bce78, + 0x0d8ab06,0x19bcf47,0x119e882,0x1458364,0x14a76fd,0x0a2bcef, + 0x0e947cb,0x0bc5d52,0x064e886,0x056ec61,0x084bf54 }, + { 0x164f21e,0x166d4f1,0x15fb077,0x0a025ca,0x0d6cf34,0x07c8708, + 0x1a12162,0x1717448,0x1e3b104,0x1b6ed25,0x1bd5ea7,0x068dc75, + 0x096bf7a,0x14193f5,0x00a67fb,0x1cd8e42,0x087da95,0x0d54cfa, + 0x0b37d91,0x1f027da,0x14b824f,0x0945ea0,0x1476ecb,0x1f434c3, + 0x101afca,0x0d20328,0x0a737af,0x1b3e973,0x1039e47,0x19caf20, + 0x10abd06,0x18a15be,0x1e9e6ba,0x14f24f1,0x0eb8d07,0x069e426, + 0x0b157f2,0x146079e,0x0054d25,0x0f7b40d,0x0383f82 } }, + /* 116 */ + { { 0x183ff4c,0x03510b2,0x079cbb1,0x1295ae1,0x0e645a2,0x0650952, + 0x1a73f01,0x1cbb8cd,0x09160a7,0x178947a,0x11d8ba0,0x0f62ad3, + 0x07bfb22,0x0176dc7,0x031e58f,0x1ed11f0,0x00649a0,0x053ed7f, + 0x1452e33,0x082ea85,0x00beb7e,0x09c36f2,0x0e83171,0x16f2662, + 0x052861d,0x18df868,0x07eff81,0x12059cd,0x0e9903b,0x14ab108, + 0x0e18791,0x1ee07d7,0x0ef874e,0x1bc5b7d,0x11fb757,0x15ecd12, + 0x1af5ea3,0x1432a3a,0x11895bf,0x02a87f2,0x03b121f }, + { 0x19275e9,0x17423b2,0x19416c9,0x1ada1f9,0x07581cf,0x11f8f7a, + 0x12ff62a,0x01cabeb,0x1e484e6,0x13df18a,0x1a63907,0x041ffd2, + 0x04d8f1a,0x1d5823c,0x151b6a5,0x1b67c4b,0x175834c,0x0d2936d, + 0x1422802,0x0811b31,0x08161fd,0x102dae5,0x1f0012c,0x1c977d1, + 0x03bb365,0x177ad9f,0x15d66ed,0x0a19824,0x1ac737f,0x140be17, + 0x06bc17e,0x1a4e72a,0x0e102d2,0x199b3cf,0x102ffb2,0x1e551ca, + 0x0a6a515,0x1a237d9,0x0320d9c,0x1a26e52,0x05505e1 } }, + /* 117 */ + { { 0x15e68a6,0x00a50e8,0x179430c,0x0cc9ba6,0x0f9f0b2,0x16b3fcb, + 0x1d0b40e,0x1083186,0x0d2c144,0x040c607,0x068f2dd,0x02d21a8, + 0x1ec5181,0x024f9f4,0x12320ff,0x1270ccb,0x0612c27,0x04d9306, + 0x1b413a7,0x10df5d9,0x0758f60,0x15febe2,0x09ecb33,0x052ffb1, + 0x0313390,0x164259e,0x0025c06,0x1504c9d,0x0b3762c,0x1543a84, + 0x1fa7e5d,0x130751b,0x1582714,0x0cc74ae,0x19a7675,0x106a1a4, + 0x0f6fd34,0x05c4e58,0x0c5f217,0x1a94ae8,0x0617d80 }, + { 0x0022b67,0x1933f38,0x052933b,0x0a6ed17,0x00536bb,0x1c22314, + 0x0959b49,0x03262a7,0x0382439,0x082a6a2,0x1e31292,0x02e4bbe, + 0x1a8d11e,0x0ad0f1a,0x094a9c7,0x1c63b36,0x0808171,0x103c336, + 0x0ce2803,0x0a03b63,0x02360a8,0x1c673b8,0x0bb64ca,0x1b5efa0, + 0x176098e,0x174d16b,0x0ee4c01,0x15dcbb5,0x1eb0363,0x04625df, + 0x02febff,0x09c4367,0x17b9678,0x0703483,0x167f72a,0x02923f8, + 0x0e93847,0x1127aa8,0x1e02cfd,0x010f9a2,0x05156f5 } }, + /* 118 */ + { { 0x006e8d0,0x1a71101,0x1cc9608,0x08fe2b5,0x15f6f5d,0x1c4a87f, + 0x1ca2758,0x1e95f56,0x17d4495,0x1762684,0x0a02a59,0x18bad1b, + 0x0bad890,0x127c51b,0x0a82481,0x0b8bfc9,0x17e0f4d,0x0bccf12, + 0x112578c,0x0cef5c4,0x035244c,0x19d2dc7,0x1c80e1e,0x1450f72, + 0x190f475,0x17bb81b,0x170f07c,0x0912b98,0x07fa415,0x07cda0d, + 0x02ee1a0,0x1601601,0x0d47458,0x039e5fe,0x00e2e99,0x1429399, + 0x0c9be19,0x16afbd5,0x196e9e3,0x139666e,0x0525459 }, + { 0x01b54c4,0x1cb3cd1,0x167421c,0x156c92f,0x029ece2,0x0443200, + 0x06a4b21,0x1b3e29e,0x1e9fa79,0x1246e7f,0x08236eb,0x03848d8, + 0x1e14b91,0x0d71fb4,0x0c3efcb,0x17070b5,0x07ed1ed,0x18c0564, + 0x02161ae,0x1fae303,0x0bd0146,0x0a2a33e,0x0843ad9,0x0cf9fdc, + 0x1940816,0x1305511,0x0adcf46,0x1624b83,0x1c1cbed,0x0980440, + 0x0cb79a1,0x06f8604,0x034c713,0x0468c7f,0x1c39bcf,0x078d8c0, + 0x14af4e8,0x11b2dd5,0x0ad141f,0x1dbb9f0,0x022f0a7 } }, + /* 119 */ + { { 0x07f1b7f,0x13c8ff5,0x0753898,0x1bb9fe1,0x1c3d8c5,0x03ee2c4, + 0x0a70ce7,0x1810d85,0x14276e8,0x0d6a00b,0x1875593,0x1eb3d3f, + 0x090a918,0x1554086,0x15e59c0,0x19b8971,0x0364aa5,0x175bd44, + 0x1ebe9cb,0x184777c,0x0908fc4,0x0f25643,0x136ed72,0x018fcde, + 0x190136a,0x0691bf1,0x0527086,0x0abae00,0x1324a28,0x1e33ca5, + 0x1c791d6,0x0c50f40,0x18a8dc6,0x0191e64,0x066d7ed,0x1272b45, + 0x0c0389e,0x0361f70,0x1311b86,0x0de2ce6,0x079f81e }, + { 0x04f3c4e,0x160f99b,0x052e0fc,0x0a26cfc,0x136b2ac,0x19f21ea, + 0x173f164,0x1fc894d,0x110d961,0x072ca3a,0x1caab8d,0x1d9cfc7, + 0x0508234,0x1ef53f9,0x04b802a,0x1424997,0x0f0a791,0x10f7dd2, + 0x064b54e,0x10dfa42,0x0af6c20,0x1e5a8e4,0x1fb0343,0x01e36bf, + 0x1b2cadc,0x10ca468,0x1e04b6f,0x00f4711,0x1bdd45b,0x1d356f6, + 0x069021c,0x1ae04b1,0x02a1268,0x13db25e,0x0ea05f8,0x0b77edc, + 0x0d386e8,0x172b31b,0x10001cf,0x06f3bcf,0x0442ecd } }, + /* 120 */ + { { 0x02f90a6,0x08d7345,0x0332d33,0x1adeb5a,0x1277d41,0x0ea5c77, + 0x0a31100,0x062d470,0x0d83766,0x00bd09a,0x04492fa,0x0b1bebc, + 0x04142b7,0x1eb5caf,0x1ef1a77,0x13c7c4b,0x15fd74a,0x151864f, + 0x02598f3,0x01e2c7b,0x186d5ac,0x1b86731,0x0caa7bb,0x1daaa88, + 0x10ea5d8,0x13d3d34,0x0262250,0x1bc47fe,0x0ced585,0x1b52f55, + 0x195d6b4,0x1a7c308,0x114a6c1,0x09c881a,0x0b0dfc2,0x107b22c, + 0x033d56e,0x0856ecf,0x1a47970,0x0e60d54,0x085176b }, + { 0x0a21e38,0x0887d14,0x14e28c8,0x1aaee7a,0x17b6379,0x0106e24, + 0x1eefcb4,0x19ba6d2,0x1961833,0x08bbac9,0x0a14596,0x0bf5cbf, + 0x126d704,0x1c355ae,0x043ca69,0x0b6e067,0x030dc4f,0x15605ed, + 0x1318571,0x004815b,0x0d91cca,0x01628a3,0x0387c5c,0x059df0f, + 0x072d0a7,0x1d0e75a,0x002d9a6,0x09080e1,0x01aa0a8,0x07cebf3, + 0x02de6c2,0x08cd2ac,0x08160be,0x15b8f1c,0x10b6523,0x184726b, + 0x1431590,0x1ec1e04,0x1a2cf5f,0x176dcae,0x08ab154 } }, + /* 121 */ + { { 0x13c4a96,0x030019a,0x00d4a1a,0x1120b9b,0x0e5c60e,0x137c662, + 0x04d923d,0x13d7ab2,0x09faccf,0x15c05cc,0x18e796d,0x1f5dc64, + 0x0bbc1c1,0x13c556f,0x18e5b48,0x0405a5e,0x0d01898,0x08053cb, + 0x091d20d,0x16a91e7,0x0e3e18a,0x01d98d8,0x0b3415b,0x0c8a25b, + 0x068dd01,0x1de0add,0x052c0fc,0x00706db,0x1206c52,0x0535ec7, + 0x0db593b,0x13e2ef3,0x11a361e,0x19a5449,0x03f14aa,0x05b04d2, + 0x12922e2,0x15dc704,0x00aa4d0,0x109c016,0x01bfcdd }, + { 0x1a365d9,0x1cd21ba,0x0c0cc42,0x1c11b1f,0x14ade15,0x016fc1e, + 0x14f5f5d,0x085392e,0x0de3187,0x1b984ea,0x02b3833,0x042466c, + 0x031228e,0x1bb34b2,0x10f48e3,0x0b4a620,0x1edf90f,0x1fe156d, + 0x0d7e4e5,0x0c996ef,0x101041d,0x0562236,0x14802cc,0x02e41fc, + 0x0642d23,0x03ae1e4,0x16e6a88,0x1980245,0x1eae47f,0x1d89020, + 0x09215b8,0x0d190ed,0x1864455,0x10358a2,0x01088cd,0x1e3438f, + 0x027757b,0x1b368f9,0x153c66d,0x077ef73,0x025b78a } }, + /* 122 */ + { { 0x16707ce,0x1ab8c0a,0x042a420,0x108629f,0x1bdc239,0x12bedec, + 0x0216a2f,0x17002f9,0x1ad63a4,0x05dd112,0x0b3ff75,0x170c2b5, + 0x025ce71,0x194aa39,0x09991d5,0x1a7babe,0x1f74f0a,0x1854078, + 0x10d4bb5,0x0a7147f,0x06ca010,0x02a101e,0x1e29901,0x018e769, + 0x07a8833,0x00d9596,0x180b72b,0x06867dc,0x0b17c7b,0x0ce7f69, + 0x11cb812,0x17ac653,0x18681a4,0x16e1bcf,0x0518dbe,0x16712f3, + 0x12b7895,0x0b28644,0x073c371,0x0e0cb4a,0x070ab95 }, + { 0x1585d93,0x1c7623d,0x193919d,0x014c67f,0x0a6d361,0x10188d6, + 0x055393a,0x05e43b4,0x1bd6400,0x1910c85,0x12dea6b,0x158fb23, + 0x179e633,0x17341be,0x04f0c7f,0x1dd15da,0x1d71616,0x16d2503, + 0x0bf3585,0x144e647,0x1694d78,0x12dd0a6,0x1019a5b,0x1eb0841, + 0x154d74d,0x1e4b99b,0x189de38,0x10bca09,0x15a5c2e,0x15062ad, + 0x170c156,0x1147596,0x13df538,0x0476d18,0x12d4a82,0x1cb12d5, + 0x04c85dd,0x0421504,0x19afbf2,0x0f2a3bb,0x05fec9f } }, + /* 123 */ + { { 0x0519f99,0x0163e7f,0x0d4d7af,0x01ca820,0x0396bd8,0x1cc479f, + 0x0500a28,0x1435bdb,0x1d601bd,0x001db9a,0x1992b07,0x006c299, + 0x10fd302,0x0092014,0x0dfafa4,0x012fab0,0x1a3a554,0x0e55750, + 0x02e204e,0x0e7a4b6,0x10b9dce,0x15f6584,0x0d7b504,0x07b5678, + 0x09ff7d6,0x038cc81,0x0418b6c,0x0aa86fb,0x04c11d5,0x17ab215, + 0x0249df4,0x049f922,0x17fa645,0x092a6a3,0x06dc9e6,0x18f625d, + 0x184c618,0x0957116,0x14655eb,0x0c79d1d,0x00a8d56 }, + { 0x021fde1,0x028b185,0x01250eb,0x0cd207b,0x0fcf5dd,0x0eb140e, + 0x067b97f,0x068da49,0x077a49a,0x0f6e378,0x1701bd3,0x058050e, + 0x0646bda,0x1a3dc02,0x18383d8,0x106dfa1,0x09b5e67,0x1082c0b, + 0x1a2a010,0x032255b,0x1d32c96,0x05549d9,0x17cffa8,0x0aed78b, + 0x18edb0c,0x123cf89,0x1b634df,0x12e35ad,0x05e7cb7,0x0b9ce67, + 0x103aae1,0x03a4056,0x0a4b434,0x0fe9344,0x155f8e8,0x02bb084, + 0x13a86f9,0x17d5ead,0x18a7e1c,0x126d548,0x095b934 } }, + /* 124 */ + { { 0x1f951de,0x05380cc,0x0d16666,0x0de0b1b,0x0fade59,0x081ee9c, + 0x0707bcf,0x1a69a8f,0x133b141,0x14946ae,0x1a2901b,0x100159f, + 0x1d9a465,0x00e77d1,0x022b4bf,0x0e4dda2,0x121e013,0x1b25cb4, + 0x1a0eee7,0x0d4d6d1,0x0544b9b,0x0e09217,0x0a7c79b,0x0cb2cd6, + 0x0f6762f,0x1a0e9fc,0x1978416,0x069ba12,0x011e1ca,0x09cd0b0, + 0x06f53a4,0x04a2aa8,0x0a4dc68,0x10b36f7,0x02b3208,0x08df006, + 0x11d1612,0x03d70e9,0x1e9f6f7,0x0a2c435,0x02e25ef }, + { 0x18e7357,0x1e7c7ee,0x16e094c,0x11d59db,0x133ba21,0x0269561, + 0x18c741e,0x1c4d1c7,0x0f2804a,0x0493f9b,0x1eb5f87,0x1a44efc, + 0x0001433,0x0c3fbc5,0x10073c1,0x04f5c16,0x036aa00,0x0cefe78, + 0x16691ad,0x08d9163,0x0d32c9e,0x030f944,0x0a9b792,0x114087b, + 0x0da2f1b,0x1ab6eab,0x17cb42e,0x08c461c,0x1efb563,0x1b720ce, + 0x1d067c2,0x043a590,0x1ec37cd,0x122d9aa,0x0e5edc3,0x047b7e0, + 0x0c7ce85,0x031546d,0x1cf5bc2,0x14fc283,0x087979e } }, + /* 125 */ + { { 0x11c747f,0x13d9fbf,0x0da66df,0x1b8dcc6,0x151a4c1,0x196dd00, + 0x1fdc2cd,0x1fc84e7,0x0d3ee54,0x136911a,0x12b83f2,0x1c19a67, + 0x0c12fc8,0x0eeb788,0x0ca14e1,0x139f24e,0x1bdf01a,0x0e4379f, + 0x0db2ba4,0x04ceffc,0x0a44532,0x1997f7f,0x0e69c00,0x115e42e, + 0x0a328ce,0x0fa164e,0x1bda9cc,0x004acee,0x096813c,0x19efb35, + 0x0a31a1e,0x11b65db,0x14aab12,0x07f5e8c,0x116bbb1,0x05bc61b, + 0x179241b,0x0911b54,0x1305b01,0x005847a,0x03ec988 }, + { 0x072f74d,0x13b0620,0x01643e7,0x1d56b28,0x078eb0d,0x1804e17, + 0x1a90326,0x1cbb67b,0x038b59a,0x1f43af8,0x16a8191,0x086c569, + 0x08f40eb,0x04879bc,0x1a93e48,0x15f1734,0x1afedbf,0x177f5f4, + 0x019f895,0x1f2d4b3,0x0aebf87,0x11bad5b,0x079bfb4,0x1b62796, + 0x0782a3f,0x1108bf9,0x19c3e89,0x02058e3,0x0c0dbe5,0x03767ea, + 0x05d74ac,0x06068e5,0x17cc268,0x1f3c029,0x18acad9,0x051b7eb, + 0x1a25da3,0x119f9d5,0x12450bd,0x1d1df5d,0x03e9315 } }, + /* 126 */ + { { 0x19a9ea9,0x0e7d291,0x098a495,0x0017c67,0x00f3c69,0x1b215e9, + 0x1ad2e72,0x030eb3d,0x000bae7,0x18b62a3,0x043e10c,0x0dabe68, + 0x16874a7,0x087894d,0x0ed40ba,0x03e3824,0x1a81285,0x056e47c, + 0x0d89023,0x16ec943,0x177bf57,0x0f8d403,0x045bb00,0x01bb8b8, + 0x0cef21f,0x0d3ba37,0x13969a9,0x1893a8f,0x0955ba3,0x0df3837, + 0x0c07857,0x168baf3,0x09c0c79,0x08843b1,0x0c21de3,0x0e224f0, + 0x0c6a22d,0x0c2ee3c,0x09e4489,0x01a14d0,0x02ed02a }, + { 0x1aa2682,0x01a0b26,0x18954c1,0x16026b2,0x0e26d32,0x03384b8, + 0x00d2af6,0x05c8939,0x1ee77ae,0x0d0ce95,0x1b05a44,0x053475e, + 0x1439bd5,0x0e6b082,0x1329701,0x01fc26d,0x19bdc6c,0x0b1b852, + 0x04f544d,0x041a4f7,0x051aca4,0x02aaa62,0x161cc35,0x19bd7e5, + 0x058c996,0x102f5e9,0x02943e6,0x1963732,0x0f01510,0x04bd3d8, + 0x185a6a3,0x023a42f,0x0c36d34,0x1baf416,0x0229d4b,0x03e22ed, + 0x009b2a6,0x1809ca5,0x15f7476,0x08953df,0x0146278 } }, + /* 127 */ + { { 0x12803cf,0x11d7691,0x1cd1af2,0x17352df,0x01e4398,0x15bc45e, + 0x1d5fdd2,0x09b95ec,0x07e68c0,0x1d29f00,0x1f34830,0x1832b96, + 0x0a5f969,0x0e0345e,0x02d969b,0x06065e5,0x1d31d86,0x071e500, + 0x1e02385,0x0677030,0x18be9b7,0x0cf7f30,0x0d75c13,0x03728db, + 0x13542b0,0x0df93b7,0x1befb77,0x00afc33,0x1275cee,0x1795c81, + 0x119f460,0x1101ef7,0x0dc5f77,0x1b60a1e,0x14fde11,0x05ade07, + 0x09ba507,0x0faaabd,0x058a00d,0x16d6805,0x07acb57 }, + { 0x0e6b07c,0x09ab4a2,0x1177490,0x13c38e6,0x051c4cc,0x19dcfda, + 0x1136389,0x1f880e8,0x1b88e34,0x124b03c,0x09ddb7f,0x099fe2a, + 0x1c77d18,0x03a114c,0x040cee7,0x0512eda,0x08477bf,0x014d053, + 0x1a3c108,0x1fbe21d,0x16d659f,0x16225da,0x1385c51,0x135d0aa, + 0x106c2fb,0x06ac18e,0x0f64f9f,0x059705b,0x16b607b,0x0e231e4, + 0x0a20ce0,0x0ea93c5,0x0aed251,0x110ea03,0x0471dd2,0x1bdf2f1, + 0x0675fbd,0x0c03e3c,0x145b2ba,0x172c6c6,0x06a5a05 } }, + /* 128 */ + { { 0x08f4f33,0x18f5335,0x1d2a4b9,0x0c9bd51,0x12fc6fc,0x144230f, + 0x094b3fb,0x011a6ac,0x008954d,0x0d8541f,0x0add996,0x18468d1, + 0x045bd68,0x0807c68,0x0a04d5e,0x0cf5c80,0x1c052b8,0x08c0e0c, + 0x01d9310,0x14a2d23,0x1d24986,0x1709aba,0x12c077e,0x06cef6f, + 0x09ae559,0x18c8b93,0x151b726,0x0da2e04,0x0097c8f,0x024ce20, + 0x1ee379a,0x04b3880,0x0df0032,0x14ec5bb,0x0b645f4,0x0c81235, + 0x0a7ab5f,0x1a3690a,0x192329f,0x168e1d9,0x0688054 }, + { 0x1a5b86c,0x0b45528,0x091fc34,0x112aeee,0x0437e4d,0x1901949, + 0x101dbc5,0x09d5d08,0x19647a5,0x13d643e,0x1588b02,0x1496080, + 0x0f1e597,0x1853cf9,0x1bf971b,0x02adbdb,0x0c24d55,0x1579f78, + 0x1c11f3d,0x1f609dd,0x0137917,0x0faa5b1,0x0de49e6,0x097c170, + 0x0a32f31,0x18643af,0x0c3119a,0x02af8cb,0x018978e,0x08673f1, + 0x0bf4a32,0x19bcb0f,0x10fc3ba,0x1bdf6dc,0x1c722e1,0x1bba65a, + 0x0a8e10c,0x0191006,0x1b94ced,0x033b29e,0x00021f4 } }, + /* 129 */ + { { 0x1519d26,0x0891621,0x0114864,0x1a814a3,0x1dafac1,0x05dc4fd, + 0x1c7a552,0x1f398de,0x016844b,0x1799bae,0x1a35567,0x1ef22f1, + 0x05e7789,0x0fc5f0e,0x1d666d8,0x1bc8009,0x19a2cbb,0x0c04464, + 0x04c81b2,0x1344c11,0x0851893,0x1ffe698,0x086b92f,0x11fd5fd, + 0x0b3fee0,0x15e3326,0x07fc52a,0x03e7013,0x041ef96,0x0a66154, + 0x0d8360e,0x02fe03b,0x1fad8ad,0x1dbb9ba,0x15d9b7a,0x04df868, + 0x0425251,0x18b582d,0x1b67c79,0x10053c3,0x0798558 }, + { 0x1106473,0x19d554a,0x08128b2,0x02b4c3b,0x15fafa4,0x0ab1e04, + 0x04d894e,0x10ffa79,0x195312b,0x1524048,0x0171dae,0x0b057f1, + 0x156c7e7,0x11863c6,0x1db6ad8,0x0881ae1,0x11c7747,0x1467182, + 0x1f6d861,0x1d7a29f,0x00966db,0x1d0c872,0x0c38107,0x1cc5c55, + 0x0c4666e,0x1eb5d08,0x09d3ccc,0x07aafc5,0x1b9b669,0x16e27f3, + 0x1f401aa,0x00da506,0x0f72f6c,0x1a0f57d,0x179a441,0x0e63198, + 0x0569247,0x081304b,0x0c23671,0x1863a1f,0x095d823 } }, + /* 130 */ + { { 0x00528a5,0x15ec30a,0x0f21abb,0x14a72f3,0x1268c2b,0x00a255f, + 0x06e293b,0x1db6379,0x182a7d7,0x17d5d86,0x0463607,0x01a29c0, + 0x0ef12c7,0x10e0aac,0x181c5a2,0x1ce7c62,0x0b7e4b7,0x099f214, + 0x0ebb277,0x0ecc6f0,0x035c631,0x1f70956,0x145cbfe,0x02f6548, + 0x10bfbbc,0x0951bef,0x01d07e0,0x0425f0e,0x088f9c4,0x05edf14, + 0x174f73b,0x0ead94a,0x1dc15aa,0x14720d4,0x03b2e40,0x07e6323, + 0x0aeadb0,0x0f0142b,0x13d51fb,0x1aaf0ca,0x00e2708 }, + { 0x1e20f88,0x06629e6,0x00e489c,0x18beb62,0x1338272,0x058edfc, + 0x1867977,0x182a085,0x1b72d74,0x19ef10c,0x0aa9552,0x1516555, + 0x0616c49,0x1dd435d,0x0110f96,0x02d2a01,0x17220cf,0x0f735e6, + 0x026af44,0x1f58d75,0x039d59f,0x1df88ab,0x0a0c485,0x09974a4, + 0x08af2f3,0x0837269,0x1c1c9ea,0x04fe07c,0x017766f,0x03cfb48, + 0x0f9a10b,0x0f50224,0x13469bd,0x0b9dc65,0x0d1a90a,0x1a9181e, + 0x03990db,0x0bc2531,0x059e3f1,0x077f653,0x00d3dab } }, + /* 131 */ + { { 0x029c3cc,0x1bb7367,0x0f1a3e0,0x19e02d9,0x0b0507e,0x1ca670e, + 0x1e65978,0x083bd7f,0x173c50d,0x07e2937,0x1b38f49,0x14a85a2, + 0x014edd5,0x08e098a,0x0def766,0x10c0d76,0x0f2e33a,0x071a217, + 0x018a76a,0x12066f8,0x13312ae,0x122c955,0x15febb1,0x0570af6, + 0x18997d8,0x0bb0d49,0x068cdcc,0x1ad9197,0x06751fa,0x0ef1484, + 0x05a0965,0x03182e3,0x01e97fb,0x0b9abd4,0x084efda,0x13c9e91, + 0x1cb89f6,0x1c3e172,0x0d09a84,0x1d6b0e9,0x0530b4e }, + { 0x0b7b5ae,0x13ad0dd,0x0fd3a7c,0x1a074af,0x1b69dc4,0x0e282dd, + 0x1712a91,0x00592e9,0x1416ac4,0x131b4f9,0x061771c,0x1cf15db, + 0x01735e4,0x06ea235,0x12361e7,0x160540a,0x0699e16,0x1426758, + 0x026c469,0x1edf48f,0x0784f73,0x0fd9527,0x1aa8310,0x1536d2e, + 0x1690293,0x15958fb,0x03c0ea2,0x02999c0,0x0d66c18,0x12adc22, + 0x005932c,0x0612a44,0x194e7d6,0x19138db,0x1390f68,0x13c0a5a, + 0x08b6a4d,0x1c59738,0x15dfd49,0x0a5018c,0x0909425 } }, + /* 132 */ + { { 0x15b4c2f,0x0d0a686,0x127349a,0x16b914c,0x0b8fc59,0x11bea51, + 0x12ceac3,0x0fd2b7d,0x0911103,0x0d0d3b4,0x0d4c8bf,0x00b529c, + 0x1c5810e,0x10bc7d7,0x137304a,0x19cc544,0x1b28e3d,0x02e1631, + 0x114b111,0x187e2f2,0x1161995,0x01a16a2,0x0d4cc3b,0x1df0252, + 0x1a60ab4,0x009d012,0x0a2eba7,0x0a9264a,0x03caf88,0x1303717, + 0x11c9746,0x06c937e,0x04091ab,0x162f8ea,0x1efdc13,0x078fa15, + 0x1d8b333,0x1e8eb15,0x05bd49e,0x0239fcc,0x0505701 }, + { 0x134356b,0x025677a,0x1ef3402,0x0a96961,0x1df1de0,0x1026e0c, + 0x1f8173b,0x1c20435,0x0361b78,0x05ef344,0x034e2d9,0x198fdef, + 0x0ea324f,0x15852f2,0x0cdcb3b,0x0332dfd,0x0b36581,0x177827e, + 0x1ac2ad3,0x1cbaa0b,0x186e7dc,0x0411c62,0x078a6d6,0x1b0006e, + 0x03197bc,0x0e7ef2f,0x05201ae,0x17ebc8a,0x0e67ab8,0x0b45e8c, + 0x0b50cc2,0x1f3ec7f,0x0a7d04e,0x0c5da13,0x048ed70,0x19438fe, + 0x05dce22,0x0dc2411,0x19e7d21,0x0dfaa81,0x08ff0b3 } }, + /* 133 */ + { { 0x1f42cff,0x1717a1f,0x05f267c,0x1a386a6,0x03c19f9,0x10daa2d, + 0x04e4aae,0x065b6e9,0x14afa9a,0x0119582,0x1350da1,0x1a8dafb, + 0x150b855,0x02e7cc8,0x10d7881,0x1443115,0x0c7f001,0x0ebe791, + 0x15020c1,0x1a6b5dd,0x0fcd057,0x0caa9e6,0x0969294,0x1c57272, + 0x0579393,0x013af2b,0x00d08bb,0x0406656,0x053958a,0x002f1d6, + 0x18e6c24,0x0f3d362,0x08051a3,0x10c6b31,0x1027f19,0x1f6941b, + 0x0748e7a,0x0742bfb,0x158fa78,0x1dd8aef,0x071b28e }, + { 0x1726bf8,0x15866cc,0x1cf1250,0x1238411,0x1290a3b,0x0cc7550, + 0x0439ec1,0x051fae5,0x1a25a91,0x153bc8f,0x1f5f6b1,0x1649806, + 0x1b2d33d,0x187141b,0x07bfac1,0x1c54184,0x16ee3da,0x1dfb86c, + 0x141d809,0x1b03230,0x17e343e,0x1426a56,0x12bac2a,0x18b6e98, + 0x1101fe8,0x1eede3a,0x1ab49ba,0x17f654d,0x18aa4ed,0x103435b, + 0x122ea04,0x1c22b30,0x14aa8f2,0x12e2764,0x076cfae,0x141a21b, + 0x0318295,0x1ff623b,0x0496b39,0x034661b,0x0729471 } }, + /* 134 */ + { { 0x0bbd495,0x02c8219,0x1cfff39,0x037ca92,0x130f4dd,0x0e1fa71, + 0x1b87576,0x00800d7,0x059ba72,0x077303c,0x0b1da10,0x1a7e858, + 0x1ec194f,0x14ff445,0x19dac4b,0x0042141,0x1dbec2b,0x18be6ee, + 0x02047b1,0x1a86d60,0x09e4689,0x1b9425f,0x09a9ae8,0x0fa8229, + 0x195b200,0x1a255e1,0x0c3c479,0x119bf3e,0x196402f,0x1f64749, + 0x01717fa,0x1dd68c5,0x0751743,0x0689bc5,0x1e0b1b8,0x07337f0, + 0x1eb292e,0x12f0b85,0x1f57ce5,0x1b0b003,0x0001c39 }, + { 0x04a0912,0x02e5ced,0x1293d20,0x1488217,0x127cb76,0x18eb2de, + 0x12e3bb1,0x135de7b,0x1481684,0x007dd95,0x0918d5e,0x004d516, + 0x08ef6a7,0x0962273,0x1897220,0x0e9502a,0x12c4d7a,0x0312611, + 0x0c58c79,0x0ee06e9,0x1c2e81a,0x18edc8b,0x01393df,0x0c3db2a, + 0x065fd1f,0x11e8e82,0x072f79b,0x0209009,0x131fcfb,0x1060eb8, + 0x0558df3,0x115b48e,0x0e4dbc2,0x0cb9311,0x1172b3a,0x01eea61, + 0x0e28745,0x0b06e67,0x0bc4e80,0x0e17723,0x09132e6 } }, + /* 135 */ + { { 0x196099d,0x1f7f13c,0x0232015,0x1740dcc,0x172344d,0x0ac2c45, + 0x01d0342,0x1d3d695,0x079e5ae,0x09ed783,0x08beb79,0x1535211, + 0x0ac9560,0x083f383,0x12f84c4,0x048d4fe,0x19b2830,0x136af9e, + 0x1f328f9,0x11d1b44,0x1292a5f,0x1326147,0x1ad4772,0x03bfaf1, + 0x0310ef3,0x1f2a67d,0x08b281c,0x05c18f8,0x0da6839,0x0b4a520, + 0x1f040bc,0x0ea1a71,0x0bb07cc,0x1701a8b,0x0f8aeb6,0x1ae07d0, + 0x14d3c9d,0x09e0335,0x03b47aa,0x1caf328,0x07d0b03 }, + { 0x1d94c63,0x1f51826,0x0ce97f9,0x0ae7161,0x17ef01c,0x0735a5a, + 0x09e3285,0x0ed2a69,0x0a53532,0x1b1166f,0x0b40181,0x140ef84, + 0x09af696,0x1ea3590,0x0f06219,0x05694e6,0x0bb626c,0x04b2a66, + 0x013cf13,0x11a7435,0x0b74a09,0x1696b9a,0x0d65be7,0x0aa3920, + 0x1021a5d,0x11fefe9,0x1c7b144,0x0574fa5,0x01aa39e,0x1492d96, + 0x09fe5c9,0x1f1d652,0x0e75d0e,0x09537e9,0x04b8646,0x1df574e, + 0x1b83e50,0x035a1d4,0x1798298,0x05fb56b,0x031b178 } }, + /* 136 */ + { { 0x034db92,0x0dd22a0,0x11361e3,0x031e69b,0x0397790,0x1aa619d, + 0x13cbb7d,0x1111a00,0x0cd563a,0x152caa5,0x1feb47a,0x191376b, + 0x18a29d6,0x186c5ed,0x0b7d956,0x1b68f51,0x02d8cdb,0x1fbfdc2, + 0x034c816,0x1c74070,0x1ca9b72,0x193e563,0x10cd6c2,0x14a8ebb, + 0x00bcbd8,0x12fffe3,0x07ae934,0x06deee3,0x10fca67,0x0e1c062, + 0x000f640,0x1018032,0x1dacf7b,0x0fc268f,0x163d5a0,0x02eb9ec, + 0x1cefbbc,0x13f31a2,0x1b47d5e,0x1ca7c0f,0x06fc0fb }, + { 0x01b0e5f,0x088b5dc,0x0ee125b,0x0a5590a,0x182dd2a,0x19c3f86, + 0x08b50c9,0x0b26afc,0x0ba912c,0x1199542,0x177304f,0x0c8693a, + 0x138b71c,0x01c6c2e,0x060bba5,0x19a9c19,0x13cbf7f,0x1c85caa, + 0x03fb578,0x0737787,0x09032cb,0x0e2d621,0x08b19f2,0x00fb4ab, + 0x01217bf,0x07775f9,0x1682e79,0x0b580b5,0x09e0c65,0x0961477, + 0x0fc42ec,0x09176dc,0x0f3aee5,0x03748ae,0x1a722c1,0x1e95ce4, + 0x0a0e553,0x1330095,0x03f232c,0x1435299,0x0701935 } }, + /* 137 */ + { { 0x0626dea,0x06a0ed2,0x0e7f796,0x142b720,0x05ef66c,0x12732d9, + 0x04290c5,0x19f3350,0x1748cfc,0x1f36d56,0x10bea67,0x0d7a5e2, + 0x167ab9a,0x0ea38bc,0x12e85a1,0x1473749,0x1366bc3,0x1096985, + 0x0fd141d,0x0d4bb91,0x0c0e1f4,0x148a10d,0x0e1a394,0x1774389, + 0x0620659,0x1c83d34,0x1b69a62,0x1696aa5,0x0537072,0x0e6a72a, + 0x17d40e7,0x13d202c,0x0a07a9e,0x02efe21,0x1fcf5f5,0x015071f, + 0x1b5ceb3,0x0c8f2d1,0x0980106,0x1912d39,0x06c961e }, + { 0x0e7eb46,0x1ee0de2,0x0d21c0e,0x0eb2d8f,0x16bac55,0x17eba6e, + 0x05f359a,0x1e69f32,0x1656ce6,0x11aa882,0x05c5d55,0x0a18649, + 0x0d3d1fb,0x11f7fd9,0x099e0f9,0x1457bfb,0x1f3eefa,0x1debcf8, + 0x1ebe7bd,0x1f7ca82,0x17a4a4e,0x112d2ad,0x1b3bd91,0x0e26608, + 0x132381a,0x0d188b7,0x1ee5589,0x165454f,0x027e96d,0x121d058, + 0x0f1a82a,0x0906567,0x18fe5d2,0x1d56022,0x037d6b7,0x14a4683, + 0x049e7f9,0x0d44e5e,0x12d4f01,0x1b0d3c4,0x0830883 } }, + /* 138 */ + { { 0x0557389,0x18e3101,0x02f2566,0x0f5bdf8,0x1fe5ce9,0x1879c1a, + 0x0f9fe0c,0x03d1277,0x116cfb8,0x1f06357,0x10a3f49,0x0cb7a08, + 0x026f64e,0x1bcf30c,0x17a4916,0x02394a7,0x1c1487e,0x1845189, + 0x116f3a4,0x1d87728,0x149e65c,0x0a6b3f6,0x0cef00c,0x0f046a4, + 0x16b2430,0x0e934f9,0x1e4eb4c,0x0f1cbb5,0x00890cd,0x15b863c, + 0x1a7c9a0,0x13c8bdf,0x015c34f,0x1d7f538,0x0e939b2,0x1826ba9, + 0x1e3fcc6,0x11bc523,0x03e310e,0x0ff2cc7,0x02376f9 }, + { 0x0575b99,0x10f6057,0x037029b,0x1f0372e,0x1e14cb4,0x139ca3b, + 0x0e0934e,0x13be014,0x1fb235a,0x1a5ce40,0x18a5102,0x02beb7e, + 0x1a8d151,0x0f0b2eb,0x14d6d0c,0x07c779f,0x0a2b2ee,0x1ae897f, + 0x1460b9e,0x13094de,0x108e629,0x19e1b2e,0x1390f8b,0x1e6dce4, + 0x0709130,0x000cc99,0x03f4d15,0x1316940,0x196dce6,0x1e875d7, + 0x1508f13,0x046ceaa,0x00ba0ae,0x12bc253,0x10b6c0c,0x02a37b5, + 0x015464a,0x1a0c851,0x00a5a2a,0x0c2d7e2,0x08c4616 } }, + /* 139 */ + { { 0x11f36a5,0x0512c16,0x1cb7bff,0x051298b,0x0eded2b,0x076c278, + 0x136e10f,0x1366b4b,0x0db0e3b,0x087c4c1,0x068448a,0x15e00e3, + 0x16cce0e,0x1cd1b16,0x1995f90,0x0fc8fa1,0x15d6269,0x02a8b52, + 0x198d945,0x1c3eef1,0x09bc269,0x05ea813,0x178f7b7,0x038af8a, + 0x0230044,0x1c6f676,0x131c155,0x1707e63,0x089eabd,0x1db98f2, + 0x0d06f7b,0x072bf9b,0x0b678cf,0x0d80090,0x0473fe7,0x112119f, + 0x15f52cc,0x15e37a2,0x0458b2f,0x045698c,0x0155ea6 }, + { 0x16fa42e,0x1178fc3,0x1b9e52f,0x12ff5bd,0x0b5e874,0x0432d7d, + 0x1c3d4e3,0x160d25c,0x0df8059,0x174cdc2,0x09eb245,0x00dd16b, + 0x0b0ceb6,0x16a31e9,0x148cd5c,0x013419d,0x0232a9a,0x1968793, + 0x0187ef7,0x1333187,0x110b252,0x13e0df1,0x1c46222,0x1155bc6, + 0x029c50d,0x19ecd89,0x00ec4d4,0x179f36f,0x029708d,0x037c7f8, + 0x020f29d,0x1b507df,0x1a013a1,0x1422252,0x14612ac,0x151d209, + 0x1cbd4ab,0x14259ed,0x1630cbf,0x0484b20,0x08f570f } }, + /* 140 */ + { { 0x0a9c508,0x1364516,0x1e037ad,0x04d3ad6,0x0dc5bec,0x156b001, + 0x0499a23,0x0282dac,0x149d726,0x0c20dcb,0x1cb9bd8,0x1cd99c8, + 0x1641e40,0x0fd3d43,0x0890990,0x12f415b,0x133cc39,0x022dcfe, + 0x105773d,0x1d1f52f,0x029db25,0x190974b,0x004933a,0x167b2ac, + 0x072c67d,0x0221d46,0x0df069e,0x1c5bda5,0x1027ff8,0x04e336e, + 0x11a52ac,0x0fcf457,0x09a057d,0x063b1fc,0x089b3dc,0x055b17e, + 0x08a2621,0x193473e,0x1307532,0x10f6588,0x03d171e }, + { 0x0e49820,0x160b746,0x1724e0a,0x0581889,0x04ee45e,0x142c621, + 0x1e449cf,0x1f21d8c,0x046327c,0x0c6592e,0x16707e4,0x0ed78c2, + 0x1343e38,0x1baa2e5,0x0db8380,0x068fd6d,0x1ab5d12,0x0b25c1c, + 0x0c03550,0x0124e94,0x116972e,0x13440e0,0x09aaca3,0x0eb5086, + 0x00fffeb,0x06fa52c,0x08d6448,0x14b0059,0x09f4a30,0x0168190, + 0x001ffba,0x11cd527,0x118016b,0x108e55a,0x11c30bb,0x0f7338d, + 0x0b9d4ec,0x082d78d,0x0401058,0x1f0699b,0x0234e98 } }, + /* 141 */ + { { 0x0db9cda,0x1a9040a,0x1243fd0,0x0f2d5bd,0x19cfdc4,0x02c5b6c, + 0x0a9bebd,0x0630875,0x1743eaa,0x18fba0a,0x0d7604f,0x125cc2e, + 0x15915e1,0x0562cae,0x10688b4,0x1791a68,0x167c044,0x13825df, + 0x188e88d,0x0c08e37,0x15572f9,0x040ae8e,0x130c98e,0x163bb29, + 0x0230b76,0x133ca08,0x1c30722,0x05ca873,0x1c910df,0x00d6419, + 0x17d5ac5,0x10cb709,0x07c999f,0x015bda3,0x07e887c,0x003604a, + 0x1621695,0x0da9304,0x07a4f79,0x1c79c74,0x06a2130 }, + { 0x13ca1a7,0x1b3d025,0x1a03486,0x0601819,0x0f42ed5,0x16783d5, + 0x14da24c,0x0b44599,0x15c25c3,0x1291d40,0x013418d,0x12b11ba, + 0x1becdd3,0x197c9d1,0x168d40a,0x16a60e7,0x03cd5e5,0x1a62f06, + 0x0c9a1dd,0x1ea90c2,0x0292ef9,0x1e0f3a1,0x1b61ffb,0x09cbdbd, + 0x0c29ea2,0x18d36cd,0x00ce127,0x115793e,0x1239050,0x1149207, + 0x14ec26c,0x0ff2686,0x191072c,0x15aa833,0x0e079ab,0x002054c, + 0x16feb87,0x103a04c,0x0a0c0fb,0x155389a,0x034f06f } }, + /* 142 */ + { { 0x148f005,0x0e3cf91,0x02c61a7,0x03be924,0x1b5c5d7,0x1732524, + 0x15f29b7,0x169fa36,0x0e82a4f,0x0dbfb9a,0x1e0d988,0x106972a, + 0x16637cb,0x1e943ec,0x0d0406d,0x1d95792,0x0ac0392,0x18ac87c, + 0x1dd7d38,0x1b86e6f,0x0c62280,0x07b530d,0x02cdbd4,0x0aad1b5, + 0x18304a6,0x1853a7a,0x0764c21,0x01af255,0x0895cc8,0x18c97e4, + 0x07db45e,0x0922927,0x18392fa,0x0adcf24,0x09f7507,0x0b5e6c0, + 0x1caa82b,0x16bcf12,0x1746914,0x163e822,0x0764d47 }, + { 0x0ee8b9c,0x11181d1,0x152177c,0x070bbf9,0x1b9f72d,0x009d1b8, + 0x0e60c42,0x1ead685,0x13de741,0x146291d,0x0eed6f8,0x04b5e60, + 0x0f08576,0x164dfcd,0x1bca66a,0x0b66924,0x0080d44,0x110df56, + 0x1ae8b03,0x047405a,0x08646a5,0x18bfe71,0x18c0a86,0x00183d5, + 0x0a235e3,0x188a28b,0x09ed2a4,0x0a86e6d,0x0c89f74,0x1cf4606, + 0x17b4f02,0x081db11,0x081904f,0x1fe3802,0x0d58f2d,0x109e4d3, + 0x121b973,0x10ea9d1,0x0e04026,0x1864614,0x01c0dd9 } }, + /* 143 */ + { { 0x06a7d9a,0x10fb3e2,0x0733fea,0x097dbf2,0x0474333,0x1217973, + 0x0e9d11e,0x1528b06,0x1241ffa,0x1cc0028,0x1bf9ad9,0x150866b, + 0x0370979,0x1845920,0x0184fd7,0x023b8be,0x1cd64f2,0x035d917, + 0x015cb3f,0x1165474,0x014ae1b,0x00bca85,0x06783ad,0x16d9a98, + 0x0bb293e,0x0fff31a,0x151c289,0x0340964,0x115a0a3,0x1d64d1e, + 0x1a6907d,0x17e5fdb,0x1ed85ec,0x0a50077,0x1d7e06e,0x183eb03, + 0x1ef4a15,0x1ccb584,0x106f2a8,0x07360c0,0x052d8be }, + { 0x1631a2f,0x09b7b7e,0x0372f45,0x0166a35,0x11fae7f,0x0931094, + 0x0431e6c,0x06ba34b,0x12bd0f4,0x16a43af,0x03a9c14,0x0da7256, + 0x1e9aedb,0x1c1d5c4,0x142af72,0x0325817,0x06289fe,0x1413d08, + 0x00a82f6,0x0d52c02,0x0814656,0x1be701b,0x16820c0,0x0c7280b, + 0x0d79f58,0x0fc985f,0x1b6f2a3,0x0e40336,0x1aa3f59,0x094377e, + 0x04a2480,0x0a46d71,0x137b996,0x01739d9,0x0e38a3f,0x0623a7c, + 0x080e8da,0x1c3fa0c,0x09175c1,0x0cfb5c9,0x06cff63 } }, + /* 144 */ + { { 0x09a8bb4,0x08219fc,0x1dc6f4f,0x0727731,0x02144c3,0x038516a, + 0x05b200d,0x13d056c,0x1e5da08,0x07e63ab,0x17f69a6,0x09def7e, + 0x0c54235,0x0f5e9a6,0x017094e,0x1ba1a31,0x085bec5,0x1171059, + 0x00a86f2,0x1777c2f,0x0ef0e71,0x184dc2a,0x05677b4,0x12ff4d5, + 0x0997989,0x0228b92,0x03607cf,0x019f1f5,0x0111525,0x1a8bb06, + 0x1aaa68e,0x1d9f08b,0x1b0ef7d,0x1688de4,0x188ee7f,0x0192673, + 0x0825608,0x1f4e2e1,0x1079f24,0x02ec27d,0x01d2c82 }, + { 0x07cfc93,0x09a3ecc,0x0041ce0,0x17e30ff,0x047603b,0x0865188, + 0x0f27449,0x1e67f4d,0x0bb055b,0x00048f0,0x0be1f12,0x1e34747, + 0x0bbdf95,0x0a02a05,0x1a1ddc0,0x008b7c4,0x130d7fe,0x0ccc6fb, + 0x1c8ef0b,0x1026bf6,0x0c46b39,0x060af5f,0x0b08c3e,0x0aac381, + 0x018305f,0x03ff047,0x1369829,0x181f7e9,0x0d4bfc7,0x0e1270b, + 0x0481ba5,0x0e8c2fd,0x0163495,0x061073a,0x01a52b8,0x0c72e33, + 0x0131e2b,0x1349891,0x1dc8bf8,0x06c14a6,0x025486e } }, + /* 145 */ + { { 0x1572806,0x1cae529,0x0385861,0x12cad2d,0x12c8944,0x1991d75, + 0x0b25cfe,0x1ac2938,0x0409bc7,0x18aef13,0x0486cfe,0x14e58f2, + 0x1ba90cd,0x102655d,0x0be8538,0x0824ada,0x0f79160,0x1e5e6d3, + 0x10d7e51,0x10c4c36,0x0b10250,0x1c61417,0x16da1b0,0x14f2397, + 0x16d62f1,0x1362880,0x0586889,0x1638fda,0x1d74a66,0x0333138, + 0x09099e0,0x104850f,0x1ffeda1,0x07879da,0x0ffeef9,0x0997ca0, + 0x19482a7,0x1bf85f5,0x04fc75f,0x0b01109,0x0751b23 }, + { 0x1c9be68,0x1dceb74,0x11b3565,0x08cfa21,0x1794b5c,0x11597a0, + 0x170f5dd,0x0235119,0x0a1b44e,0x0ca531d,0x03b2a1b,0x1773555, + 0x1ffb0bb,0x04b1ec3,0x0c3cb43,0x00ebbe9,0x02c5dc7,0x0dba983, + 0x064ce62,0x0e4d589,0x0cdefed,0x1c2bfce,0x1769818,0x1f18ecc, + 0x0392a75,0x165110e,0x157719c,0x1a4c9b2,0x0ecc8dc,0x1f915b3, + 0x0e9c013,0x03148b1,0x11aa9ae,0x1eb29fd,0x137e2ea,0x19d52c8, + 0x0ba0de7,0x1bc7401,0x1b1d6a4,0x05b9458,0x0144cc1 } }, + /* 146 */ + { { 0x189aa3a,0x1050e94,0x193564e,0x06b3cdc,0x183f228,0x1739976, + 0x0c32f4c,0x093d271,0x13c3cb2,0x0623262,0x1a9ab3d,0x0bf1f13, + 0x129750a,0x1a367e1,0x1f96efc,0x170128c,0x19d37b2,0x0e4dfd5, + 0x0cce71b,0x16e8a67,0x0deef8e,0x1f1dbb3,0x0ff807e,0x0d5d44e, + 0x14254ef,0x188598a,0x09ef986,0x0ab87be,0x0184885,0x16c0eec, + 0x1e5c3ed,0x177ce29,0x01af3a4,0x07b49ed,0x005e746,0x12aebe4, + 0x0465b83,0x047e359,0x0a54770,0x066d709,0x0874ecf }, + { 0x1b3f6be,0x17c1f5d,0x08f5892,0x1211768,0x1578fbb,0x039a93f, + 0x0c2eb5e,0x084ac47,0x0a62e04,0x1b2cdec,0x0dbde70,0x02cffc4, + 0x062903b,0x129f935,0x090c31b,0x0259eab,0x1ae3ad7,0x19112a3, + 0x1bac9ca,0x1121aee,0x0df9b73,0x059eb14,0x056d3dc,0x1d5c959, + 0x013b053,0x1a74f87,0x039fc85,0x169ea27,0x1bae175,0x167ccc6, + 0x001d520,0x088a309,0x169bbde,0x178ae15,0x194b2bf,0x129e4f2, + 0x16bcaf1,0x11f795d,0x18d3e82,0x1039c98,0x031fb85 } }, + /* 147 */ + { { 0x15cd607,0x18368b0,0x0e98e60,0x1554658,0x080c9fa,0x1c898eb, + 0x1c16ddd,0x001d0f4,0x036708b,0x018809d,0x14a5fc4,0x01c3288, + 0x16814fa,0x1353cda,0x11560ea,0x17da8e1,0x0bf4b16,0x18181ce, + 0x0aabe34,0x0f951b5,0x08a518a,0x13ae6db,0x1ccc567,0x07029f5, + 0x0e738d2,0x1cfef50,0x02343d3,0x166a4e3,0x1ff032e,0x1304ee6, + 0x02ec2dd,0x07a9067,0x1ba8ea9,0x0a83d32,0x1609577,0x0830089, + 0x0a4a50b,0x05111f2,0x0795211,0x00031c3,0x0983230 }, + { 0x1f3d5a6,0x10813ab,0x1734a28,0x10dd195,0x1fce564,0x0a8f9df, + 0x0e06c09,0x1e32b20,0x1935ebd,0x1366327,0x0ea9bac,0x0523810, + 0x0160611,0x047267a,0x062299a,0x1636b9b,0x173dd53,0x0ac0e1f, + 0x1ff1887,0x100952e,0x02fa78c,0x187d6e5,0x0c61d0c,0x0799e04, + 0x08da4c8,0x183fb80,0x169e691,0x0824543,0x115eb5c,0x069fa54, + 0x1826a38,0x1a0246c,0x0de157d,0x1695051,0x0ec997a,0x0a8bde8, + 0x188db28,0x11156f0,0x032ab42,0x13d245c,0x08abbe3 } }, + /* 148 */ + { { 0x02d2f01,0x034829d,0x0172d11,0x06bb8cd,0x127c319,0x1a5013e, + 0x02efc75,0x03ad521,0x15b50ec,0x0ed1a87,0x10b8980,0x08bc7e7, + 0x121d3dd,0x1c1b774,0x1b84742,0x12f39ec,0x08f474b,0x03f01c8, + 0x02e1e0d,0x0f8b733,0x1de919e,0x1f5e9e8,0x09d074f,0x1ec0b37, + 0x08e8d1e,0x123b1e3,0x04d9d38,0x173ff27,0x1e67f69,0x09f39f3, + 0x12075f5,0x15dd3c4,0x18dc326,0x0cc2634,0x1b6acef,0x0ea5e47, + 0x0f8fe8a,0x0f18d83,0x0ea57e5,0x1a187a1,0x00f15b4 }, + { 0x10a8d85,0x1b31abc,0x0bc63cb,0x1dc4b2b,0x11bffba,0x1a8943a, + 0x1fb1892,0x0bba2b6,0x1323471,0x11cdb55,0x151075d,0x0532578, + 0x130cdd5,0x1b682c1,0x0003a93,0x1c6c0a9,0x152f6d6,0x190f7eb, + 0x04a4184,0x0fffca3,0x18cdc0b,0x12f7544,0x0da2960,0x13044cd, + 0x1ba9222,0x1d97676,0x02ef41a,0x0f15236,0x16b0cb6,0x16e025d, + 0x062c90d,0x195f1d5,0x17a99e7,0x102dde7,0x19b9c6a,0x03725a1, + 0x15993eb,0x068238f,0x1776efe,0x0f04070,0x0515db3 } }, + /* 149 */ + { { 0x15bef22,0x1f55537,0x1c4bb90,0x1040690,0x152d269,0x1d7b634, + 0x12139e8,0x0063c98,0x09a8c94,0x06a1a63,0x0626686,0x0e82a00, + 0x0c63e5d,0x1f47520,0x0e36ef3,0x10e42a4,0x0d29679,0x0653664, + 0x12b2f7a,0x16d5dc0,0x13ce73d,0x06dbfcc,0x0fda4ca,0x08bc669, + 0x19bbfad,0x11851fb,0x0df07c5,0x18a3d92,0x00a6de8,0x192fcd8, + 0x10d241c,0x025b057,0x1e6acb4,0x0cfe4a4,0x0db43b1,0x16b2036, + 0x1cf34e3,0x04db884,0x1300b2c,0x0fc357e,0x02de048 }, + { 0x1d9d484,0x19179c6,0x0b3062d,0x06f8ef7,0x0334939,0x0c95c54, + 0x0e3c64f,0x04ab1b7,0x08e3fac,0x06bc6a8,0x1d29f60,0x1302e8b, + 0x1df0500,0x03be614,0x1caffb6,0x113f1a0,0x0f2c30a,0x1b3d5fc, + 0x0820835,0x0acfd53,0x173892c,0x17451d2,0x1096ac4,0x0aaa436, + 0x0faebf0,0x0f4e0b1,0x1ae53a9,0x1c389e4,0x11e546e,0x04ca1eb, + 0x0747905,0x087d17c,0x18183b8,0x1570592,0x120bbe7,0x008922f, + 0x13874a3,0x09d22bb,0x1e1b9a0,0x0e39885,0x06f6ac0 } }, + /* 150 */ + { { 0x1d6e3b1,0x01156a6,0x01a74e2,0x195ac41,0x1c78e1c,0x166f407, + 0x0e114b2,0x1c7cf08,0x0a8469f,0x10e60a5,0x1a3bc84,0x1b4fccf, + 0x088e8f3,0x069a3a2,0x00f45b9,0x063e9b7,0x1987986,0x19dd0ee, + 0x0931305,0x16b2ee1,0x101fdfa,0x031f6e3,0x07c284c,0x1b1fe50, + 0x1d6016c,0x1e4a324,0x0ef3156,0x04ce461,0x00412a2,0x0e302bb, + 0x1d80a86,0x0651f5d,0x119d5f1,0x1556ce3,0x1a7bd9f,0x0a4f972, + 0x119bafb,0x0129873,0x00b2fcd,0x199feb5,0x06e2c24 }, + { 0x1af8793,0x18125d6,0x12398c4,0x0206b92,0x144bccf,0x1a805fc, + 0x19ade54,0x0cbd340,0x01d1167,0x0c8d4a3,0x04f1e1e,0x165d3fb, + 0x1595add,0x14972a4,0x14b00df,0x1cb9e0b,0x1189f03,0x1658a2d, + 0x16a87dc,0x1c91952,0x0e4f81a,0x0109ad3,0x080fc9c,0x1654faa, + 0x0f5a249,0x15195e7,0x000b5fc,0x0d0f520,0x0745b00,0x1914363, + 0x014bdf4,0x10ca0e6,0x1a8a875,0x0e2c79e,0x0210ba3,0x0b7c717, + 0x1bf1118,0x045f9a6,0x03e45ad,0x01b2f81,0x05af7fd } }, + /* 151 */ + { { 0x0a224a5,0x0dca87a,0x1ce957e,0x0998a04,0x0190457,0x1f8feaa, + 0x04cc190,0x10669f0,0x10e50f7,0x0b400dd,0x005c4a6,0x080712b, + 0x16866d7,0x12048e9,0x0690176,0x0dfcfb7,0x1df16a4,0x078f1bc, + 0x0efe45a,0x09527f0,0x0bca8d0,0x1a99590,0x0b9320c,0x0543821, + 0x134b1f7,0x0da4ce9,0x1f60657,0x1f7932e,0x014b5d8,0x1efffdd, + 0x1db2bac,0x0edb5e8,0x0fef022,0x1b97a30,0x17fb6d6,0x0497291, + 0x16dfb06,0x02e492d,0x152b946,0x1032c13,0x027a9c3 }, + { 0x12a93af,0x1b9a378,0x0d35cf0,0x18aa6cc,0x028b707,0x00c9e88, + 0x1635526,0x13b1df4,0x0ef21b6,0x1c1d2e6,0x0283893,0x01474f1, + 0x1805cbb,0x12d89e4,0x00c5e05,0x0f09802,0x0582b73,0x17f5107, + 0x140d87c,0x0e2741c,0x02d9df9,0x07e8661,0x0c51268,0x0bc5c36, + 0x152e77c,0x0678c1b,0x16d9c11,0x1c89ad7,0x1e177a6,0x0f4ab99, + 0x08c04b7,0x011dc58,0x0b49669,0x18ca4b4,0x15047d7,0x1fb3760, + 0x0acd886,0x0c1638b,0x0491254,0x129f7bd,0x01c6906 } }, + /* 152 */ + { { 0x0880026,0x13e8b9d,0x17c976d,0x0024bb2,0x09c4f0a,0x165bd24, + 0x01544fd,0x14a520a,0x15cbbdc,0x15918e8,0x0f2f4cf,0x19332e5, + 0x1af8cff,0x16aad01,0x13bd352,0x0f85f96,0x1ca2286,0x0ca26a3, + 0x1ab46a9,0x110a901,0x104596d,0x1c65e45,0x1da95f3,0x0bcab40, + 0x1844b00,0x04beff2,0x0474628,0x1d3cfc3,0x123c745,0x1374294, + 0x0e655e8,0x0febb66,0x0867b79,0x1686468,0x02398ef,0x184aa68, + 0x089ad23,0x0b72eab,0x10ce456,0x1ad4a09,0x07b8c13 }, + { 0x0fb6901,0x01d56a9,0x14ecbf1,0x122d944,0x1c0313f,0x0d56e30, + 0x00c2945,0x18428eb,0x07f577d,0x09e8c93,0x0f03772,0x1d1dee4, + 0x1a26e52,0x1f5cfb6,0x0783ae0,0x06eda5e,0x082f180,0x0ccbcef, + 0x020d24e,0x051d976,0x18e743e,0x0e51ce1,0x068b547,0x1c7ed6b, + 0x063a9a8,0x1383730,0x092e6cc,0x19e3b47,0x18915d4,0x0451697, + 0x049b94d,0x0a0a0f2,0x075e3e0,0x1c1fd2f,0x195c834,0x135dff9, + 0x0fd2fb2,0x16a9e64,0x1334075,0x1ecd2de,0x00e3c3e } }, + /* 153 */ + { { 0x1ee1d83,0x19be090,0x1e20ef0,0x1af0f6e,0x17e08f6,0x07d2674, + 0x07f304e,0x0b17ee1,0x1a0348e,0x17bbb23,0x199cb6e,0x15794ab, + 0x1d04f8b,0x1eaf62e,0x14a4675,0x124301d,0x1ff33e9,0x1c67325, + 0x12c166b,0x13f8ae4,0x12baac0,0x1cee2f1,0x141a0c7,0x0b5ed52, + 0x0267746,0x1fc1351,0x1b25fc7,0x18bdfcc,0x0087fd3,0x106b5e3, + 0x1ac5457,0x1551db8,0x1a39c5e,0x0f694d8,0x1aec39e,0x107bb02, + 0x1c3788b,0x009bb4d,0x09471b3,0x1c78125,0x0463098 }, + { 0x0bd0fa7,0x00463e4,0x1924e99,0x039cd7b,0x1176431,0x1f7bdf6, + 0x18420a0,0x071c62b,0x199b5d9,0x109e63b,0x1269ae0,0x0b028b4, + 0x11af7f1,0x1294f26,0x03f6c3f,0x193ada0,0x177ce66,0x12ae9c7, + 0x0f52e54,0x0f99803,0x1986b4f,0x04d7b8f,0x0365d6d,0x0c9a015, + 0x19fcbcd,0x16b895a,0x12968ee,0x10c1ca0,0x1c89f11,0x102215a, + 0x07db65d,0x0f47c46,0x0d0c659,0x05d497f,0x10cc5e3,0x1cb0229, + 0x0698e11,0x13a6033,0x0e16b8b,0x1274691,0x07f8fd0 } }, + /* 154 */ + { { 0x19428af,0x0c96560,0x1997c91,0x0274610,0x192a1c8,0x05debf8, + 0x0604b8c,0x17284b1,0x1836c6b,0x06d8391,0x19261c4,0x03d2b31, + 0x0b9c7a4,0x1756b7a,0x1fc5e79,0x0588915,0x1b97586,0x1387c7c, + 0x1c8660f,0x16046ed,0x11526b3,0x0dcc732,0x09760fa,0x0a24314, + 0x126a8d7,0x0d31d96,0x0a75bc7,0x0a10503,0x081f749,0x0682d2d, + 0x1c637de,0x1c8d0e8,0x19ee559,0x1ec666b,0x095d9e1,0x0a40c19, + 0x08476c9,0x1d427fd,0x144c509,0x0a3cc86,0x087b64c }, + { 0x130d3c4,0x037b2a5,0x1c521fd,0x184769d,0x0dec4c5,0x0526b46, + 0x11d998f,0x0db676e,0x1cf3fb5,0x0f9a134,0x1f51a87,0x13881fa, + 0x1dd4f13,0x1534d45,0x0df1f1d,0x1afa547,0x0c9cbad,0x0772b5a, + 0x12508cd,0x1fe6855,0x1da3b28,0x1d3c378,0x0011bf7,0x001905c, + 0x1149cb7,0x0cbe72e,0x0542599,0x1461df0,0x1f4bddc,0x0304fe7, + 0x1a11288,0x08924a4,0x12f65e7,0x10f9c07,0x14b3500,0x01cb6ca, + 0x042dbbd,0x154e150,0x18bd5df,0x0f9b380,0x08c9526 } }, + /* 155 */ + { { 0x1c1abb1,0x081972f,0x1d0d995,0x0825fc8,0x0215af5,0x182f7a9, + 0x1d580a7,0x1d3faca,0x1dc191b,0x0739992,0x18e6c2c,0x0cbd810, + 0x137ab3c,0x0e1f333,0x141fd44,0x0aaaace,0x1c3c861,0x0b1c5f7, + 0x0bc312b,0x03119e8,0x186d5d0,0x0e6c4b0,0x010e8c0,0x18ce83d, + 0x003f7b2,0x0e8022b,0x13e8f34,0x0ea8b81,0x00672ef,0x17fea52, + 0x177d84a,0x08b73d1,0x0197c9f,0x116ba2b,0x0df61e4,0x1f68a64, + 0x0b2d59b,0x09971d2,0x1a85afc,0x0e77094,0x08afa1b }, + { 0x193ac70,0x0cb7573,0x1441acd,0x1dddedb,0x0c94ef8,0x0117202, + 0x13e89c1,0x0c724d6,0x0e9e5d7,0x0638ee7,0x0aab7f2,0x16e1ea2, + 0x1f352fc,0x1441cba,0x1ee84e2,0x0762636,0x190058c,0x0abcc89, + 0x1dd03f4,0x0412552,0x0697969,0x0d8b058,0x066b651,0x106f564, + 0x1438810,0x1b8de31,0x13c5d2e,0x0ddc238,0x1b80eb7,0x1fe0d58, + 0x0298446,0x0e1d88b,0x082bac8,0x09992de,0x049cc4b,0x11ddcc0, + 0x1240adc,0x08c58d5,0x024f2d0,0x12256b4,0x0672111 } }, + /* 156 */ + { { 0x15cf9bf,0x0c9837a,0x1b6647a,0x1148d72,0x1b04530,0x1d32efc, + 0x0787679,0x1775c78,0x1c731bc,0x09e58a8,0x1629851,0x044f49a, + 0x0214be5,0x0be3a66,0x16b248a,0x001ac73,0x045822e,0x1a687bd, + 0x18ac0f7,0x163aa38,0x0b2dafe,0x125d50c,0x0ec770e,0x056e9e1, + 0x07178df,0x119bf9e,0x1a25ada,0x19a6514,0x0e055ff,0x0a2a0ee, + 0x01fa57b,0x0d49c57,0x1fbc76b,0x0ee74cb,0x1fc7e96,0x03cbd8c, + 0x0c0367c,0x11b4566,0x08ff814,0x02ca9c9,0x07c8639 }, + { 0x07388cf,0x0a5af65,0x14e157a,0x018066b,0x17cc0a6,0x17c2dd0, + 0x0de2d85,0x10136d3,0x1101229,0x02e8177,0x1429e5c,0x1d0039f, + 0x12565a6,0x1e8f71a,0x1d2a5b5,0x13b5bd6,0x0ed427b,0x1ae4419, + 0x1b54cc3,0x150a51c,0x0ee896e,0x158c692,0x0c36218,0x1f273ee, + 0x18ed59f,0x1294e69,0x0804180,0x121f934,0x03b3ff6,0x045c118, + 0x1a718b6,0x1baa568,0x042d7a4,0x096c9fe,0x1e8a32b,0x100df1b, + 0x0092043,0x11b0483,0x156b540,0x0b1f9d0,0x0325827 } }, + /* 157 */ + { { 0x19e8c60,0x0722f9a,0x061bac8,0x0a6c994,0x071bb8a,0x1c70886, + 0x141c77f,0x0f00562,0x14c93e5,0x1a748e9,0x0743601,0x1c01705, + 0x1ac0326,0x113541f,0x0648961,0x1413c78,0x0d5fb29,0x11c3d32, + 0x16b1720,0x147a69c,0x1a29caa,0x12d6d16,0x03b5a17,0x052ca1d, + 0x00267eb,0x179c939,0x05d8e00,0x0e30963,0x0b1aeaf,0x0e876fb, + 0x1748fd7,0x04bcc24,0x01fa347,0x1950d5f,0x1e74321,0x1fac50f, + 0x0c57c3a,0x1549e95,0x1d95926,0x0e2b7b4,0x01a4e6a }, + { 0x14d1267,0x1376f2a,0x0d20684,0x0639a05,0x17f9453,0x18fd8e9, + 0x1c13338,0x025ae15,0x1097dc0,0x1a08585,0x1edb173,0x1a2e6d8, + 0x05930e1,0x0344884,0x0bfb907,0x0c71f20,0x0a779fb,0x19a4dd2, + 0x135be37,0x18b0435,0x0acea16,0x009703b,0x1ecee0f,0x003a29b, + 0x1033be5,0x16d35c6,0x0883cb4,0x0b27a8a,0x1f18800,0x0936cce, + 0x098dd49,0x13fd667,0x032351c,0x17a2b65,0x0ef07db,0x15b2268, + 0x15b9dc8,0x042bed9,0x1a0cb1d,0x1270b69,0x0856a7c } }, + /* 158 */ + { { 0x10a5583,0x1e80106,0x162a801,0x1bdb48c,0x0f1301d,0x0c9cdf1, + 0x1e590d3,0x06d2380,0x0a70c08,0x065b3c0,0x0795028,0x1f2b7d0, + 0x18c0b4d,0x0ea5645,0x0ef34d1,0x0c472d9,0x0d05475,0x12be297, + 0x00173ad,0x05b9483,0x0255cac,0x15bc9a2,0x0457b9a,0x193454d, + 0x1ef3124,0x13a1b36,0x1e304b1,0x1a772c5,0x1b7c3bb,0x078dbed, + 0x16eaad9,0x1c45772,0x00e4553,0x11dba1e,0x1aeb131,0x024811f, + 0x0a4da63,0x13b9891,0x16900f2,0x1098c6d,0x0628890 }, + { 0x0b8d208,0x1fea9c6,0x1b52915,0x12a87e0,0x1a8f800,0x17f955b, + 0x18553cb,0x1cf6cdb,0x1f72517,0x0ed9475,0x0274b3f,0x1ccdf27, + 0x0e0149f,0x0c2dc46,0x1a1dcff,0x087eef3,0x10b0ba5,0x0229704, + 0x02c0ff0,0x136b9f6,0x177bdeb,0x05362f6,0x0c44d12,0x1f806e4, + 0x1f3cf8f,0x0251b04,0x15706d3,0x179388d,0x059be92,0x1df9c7d, + 0x04799bc,0x19b604d,0x196bf5f,0x1c47c89,0x0750027,0x07e3d8b, + 0x0ad9dfe,0x081a2b1,0x135630a,0x058b5b4,0x079d812 } }, + /* 159 */ + { { 0x0529507,0x0726755,0x1400535,0x08e8cab,0x056a081,0x07e23a0, + 0x028e13c,0x11d81a6,0x03443cb,0x14101f5,0x05ca362,0x1f612fe, + 0x1233c62,0x1a9077a,0x0e373f6,0x13a7d14,0x15d7cac,0x0507c86, + 0x1cf3a94,0x0f617f0,0x01cb28a,0x1d36362,0x14456b8,0x0702583, + 0x171daa1,0x03f51a8,0x1589354,0x0ba9774,0x18f42f2,0x0944bf4, + 0x1c6476b,0x12d4826,0x1d6b1e9,0x12dbbff,0x0496da7,0x0fa8d84, + 0x00c4f70,0x095a121,0x155eb1f,0x12b0284,0x02ab3af }, + { 0x05372a6,0x103a635,0x0e9e1b2,0x1cac525,0x128fb83,0x1a0e7ab, + 0x05b71dd,0x13ae8ab,0x1520ef4,0x05a6750,0x1191c9c,0x1c68c3c, + 0x1d1472f,0x1fdc562,0x15af598,0x180e3e9,0x0c9c10b,0x0a37296, + 0x1c68d18,0x129dfc6,0x0877287,0x0c13b7f,0x092141c,0x1deb569, + 0x157739b,0x00af6d6,0x1cfc572,0x0985b3f,0x0395c32,0x0872c7c, + 0x1546225,0x1016d50,0x0e40996,0x001f0dd,0x08b22a2,0x1c9ea7c, + 0x039d25e,0x119fb08,0x0272abc,0x06a4a08,0x007db2c } }, + /* 160 */ + { { 0x17d4703,0x1dc6d81,0x02e71fc,0x1f8be91,0x083708d,0x18ea017, + 0x00c3e11,0x1d23f75,0x05a2faa,0x0af7469,0x13f07a9,0x1e20a80, + 0x11c2e5b,0x1516ab2,0x1f5409e,0x1ebf2c8,0x00c7eba,0x19bd29e, + 0x16cc2af,0x1e17652,0x13ba7ad,0x1f6b264,0x1698b87,0x1de94f0, + 0x018c0e2,0x027bffe,0x0534b34,0x073bb3b,0x00af021,0x1d5baf5, + 0x13c94fe,0x01fdf35,0x08100ea,0x0ad53be,0x0137218,0x12e98a7, + 0x1fe5206,0x143416c,0x15d672c,0x11f9efb,0x008b6ca }, + { 0x16c3b5a,0x12df501,0x0d2f813,0x04ff3e5,0x1872610,0x1cbe079, + 0x095c0a5,0x14753f9,0x182879e,0x12b0c05,0x1c377c5,0x1376c0f, + 0x0715338,0x13d8704,0x08488f1,0x0ff8f33,0x0ec9d89,0x0868c04, + 0x05bb7c6,0x00e2352,0x1118947,0x158390b,0x1e3d4bc,0x111116d, + 0x129ffd1,0x0802ec5,0x15331be,0x1e3c458,0x04877fe,0x10b2f59, + 0x097100d,0x06a8f2a,0x1a95233,0x0a3457e,0x1085a18,0x11ac454, + 0x14faba0,0x021d83b,0x09f4974,0x0041a63,0x02c337b } }, + /* 161 */ + { { 0x022fa65,0x182de75,0x18e9ec8,0x09a2b3e,0x1e183ef,0x1ac91fd, + 0x161f4fc,0x0a668e7,0x0c11d77,0x13fd983,0x1533fec,0x1cd6540, + 0x19702e7,0x178c2b0,0x1a7e5f2,0x0a38a79,0x0434e7d,0x1c1aa81, + 0x0d5ab16,0x1c7b05e,0x1131a63,0x156bb22,0x019edf2,0x0e3f93b, + 0x1e6afa6,0x0bbf742,0x18ac1f3,0x1730bdb,0x1a51933,0x0c587fe, + 0x0d81f56,0x15285b8,0x10eca39,0x10c54d8,0x13b9418,0x142fe7b, + 0x06b7d5c,0x0a74688,0x0c724f6,0x069db10,0x0509b26 }, + { 0x0caed54,0x0a0a724,0x1a5ec6e,0x1997ea3,0x17a78c6,0x14d92c3, + 0x0323537,0x0f148d1,0x091ee3d,0x01209be,0x1b99300,0x0469c61, + 0x18a68f9,0x040c86b,0x0c956f2,0x0d216ae,0x05fba80,0x020f470, + 0x10d53d3,0x071b09d,0x0816500,0x0b6fd29,0x0c63c0b,0x16c7fb5, + 0x19007cc,0x02ae23f,0x0fa62b9,0x13a901f,0x0e319d2,0x0e912e8, + 0x0652b11,0x004db6e,0x06f3575,0x0c3dce8,0x1880b0d,0x0ee6773, + 0x0c31772,0x041cc91,0x01d4889,0x14ea977,0x01592d5 } }, + /* 162 */ + { { 0x17453f0,0x06cd167,0x07c15de,0x15db078,0x0ffb899,0x1415d3d, + 0x01b4f82,0x1035cca,0x0ea3d50,0x164270d,0x0a8e2cc,0x1181021, + 0x019ad52,0x1e9be82,0x1f6c082,0x1c83f63,0x1e1d06c,0x13c6b65, + 0x19d2dfd,0x0fe1e05,0x1022d28,0x1ae21dd,0x1d73495,0x034e367, + 0x0f2f3f8,0x1fa3694,0x1718cf9,0x0cb763e,0x1c580ee,0x1e0e627, + 0x094cb97,0x176f60f,0x155539f,0x1579d66,0x11c70f2,0x1b6b528, + 0x0cc22d2,0x0c5efa2,0x1ddf2e5,0x17aef44,0x01614bd }, + { 0x10ab04d,0x1811876,0x0ba9307,0x00dc410,0x0e347b0,0x162dafd, + 0x0f18f10,0x06b3e21,0x1de0199,0x029cf37,0x142096c,0x09cecbb, + 0x16d89bd,0x1de76d0,0x0983fbe,0x1946524,0x15ce62a,0x1c5553a, + 0x1b20b17,0x0c5f52b,0x0768ed7,0x008c328,0x0679930,0x05c6919, + 0x16245c9,0x0b42bee,0x1cc7a9b,0x1b7114e,0x1447360,0x095583d, + 0x1fbbc00,0x02e3ae1,0x1356b94,0x048d85c,0x18a00fe,0x05cd160, + 0x179c20a,0x0a529d5,0x01ca0e9,0x18f6016,0x0489656 } }, + /* 163 */ + { { 0x1353c25,0x124dd38,0x189390d,0x0227ecf,0x117f27a,0x0f5cf1a, + 0x0cce870,0x1f2217a,0x078e29b,0x070e02e,0x0fc5765,0x1b2e8e8, + 0x1084fe7,0x086d16f,0x01d2422,0x077c339,0x1a75367,0x0c1201f, + 0x0eba86c,0x1ebb683,0x0ead7eb,0x1a920c0,0x13f82b8,0x1ea187f, + 0x1873fc2,0x06c8e8a,0x19c1987,0x0d0a35a,0x1e8c2c1,0x146cd28, + 0x06600a5,0x1c02c21,0x1d1a9cd,0x1f52b73,0x1226a29,0x10562a7, + 0x06e3c49,0x00dbc48,0x0772db5,0x1d3aced,0x0082bb2 }, + { 0x0d6615f,0x077a362,0x0a71860,0x0203730,0x1c629dc,0x1932657, + 0x0bb003e,0x189bc44,0x010ecc2,0x0a2bf03,0x08b1371,0x133e3dd, + 0x0c95ce5,0x07ce2d9,0x0cfe9ca,0x021f208,0x062cd63,0x1f701aa, + 0x18b8894,0x0af8779,0x1e4484c,0x0d4b6c3,0x1b23b0c,0x0a58b4e, + 0x1e393a4,0x11a985f,0x02811ec,0x0b25628,0x18545ec,0x1f0c600, + 0x119ef62,0x0b82f18,0x14e0107,0x1802dbc,0x0518b88,0x06908e3, + 0x022a54f,0x12f11bb,0x0410899,0x08d2039,0x036451a } }, + /* 164 */ + { { 0x1893e71,0x0168c0c,0x02085e0,0x16a7344,0x01765d8,0x01767e5, + 0x1a8048c,0x13bf8d5,0x1365bf5,0x0a67a8d,0x0caa023,0x1ae41a4, + 0x0787741,0x0c74021,0x0d0facc,0x073d958,0x12fe747,0x12a9f65, + 0x0a2c1f2,0x14f3503,0x0b3aaec,0x112b7a5,0x0227fcc,0x143a3ee, + 0x1d7293f,0x10b2f4a,0x1bd8aa6,0x0c0ad35,0x08ddc22,0x1119550, + 0x12979dd,0x036f76a,0x1fabec3,0x0ab73c9,0x0559d0f,0x1e91441, + 0x0b0ebef,0x0e6d897,0x1f3c5d2,0x148d371,0x0705307 }, + { 0x088310b,0x1260272,0x15edea3,0x04a64b9,0x12726e3,0x01f7d60, + 0x162c126,0x026ba1f,0x002ddb9,0x0b72a96,0x05a171e,0x07eeef7, + 0x030eeca,0x18af925,0x1d9ba26,0x192f336,0x0d648ef,0x03e139b, + 0x000871b,0x032d0b5,0x11ea3d6,0x1c50597,0x1f8cf89,0x0edad61, + 0x09879b6,0x05f4ae3,0x046bd38,0x00e8e63,0x04ee55a,0x1af89b6, + 0x0e68bea,0x0b3cbe7,0x138b8ff,0x17f3734,0x1690e72,0x003c229, + 0x0a6ad12,0x0caf61b,0x0abb325,0x1a0afcc,0x080f79b } }, + /* 165 */ + { { 0x0af09b3,0x1a153b0,0x1850f3b,0x1b267bf,0x1c016eb,0x02f5541, + 0x1c783b6,0x192e419,0x1ceaa3b,0x07af4cf,0x01be5f5,0x13a56e2, + 0x127216b,0x04b3456,0x1cd30db,0x0ca3ecb,0x0bc5b0c,0x1547dc1, + 0x0bf6937,0x085e39e,0x059e20f,0x16690fb,0x1acc6ac,0x07a2c31, + 0x176c7a1,0x1f2dbd3,0x08e198a,0x1888204,0x108e0be,0x0d38656, + 0x0032097,0x0045803,0x1299079,0x1cffecc,0x1680abb,0x00ec477, + 0x15c58b5,0x027a79f,0x1fc677a,0x149b049,0x05f5a5d }, + { 0x08311dc,0x192bf3f,0x04d95cd,0x028cd9e,0x1ef94f5,0x0e510d6, + 0x05916c1,0x06f4e7c,0x002e4ab,0x0754d9e,0x04596ce,0x15930af, + 0x047760e,0x012580d,0x1f7411f,0x0ab09bf,0x1d13fb9,0x10c46a7, + 0x15522f6,0x1871704,0x1cacfaa,0x182cf4e,0x069e69b,0x144e01e, + 0x1720f09,0x1244c1f,0x13ee29f,0x19774aa,0x01fad58,0x0cb423d, + 0x178e286,0x0b57ad6,0x1856547,0x0b76108,0x14c7cdc,0x16ea227, + 0x0212907,0x08f3c0a,0x162244e,0x0021b82,0x05319c8 } }, + /* 166 */ + { { 0x161c3af,0x009b735,0x0da08c8,0x1c0f697,0x1d40f2d,0x064bf80, + 0x1b9fce0,0x074ca3b,0x06a8c31,0x0bc5d38,0x072842a,0x0fac402, + 0x1b22c58,0x158fa22,0x0ee8862,0x089cc91,0x107e504,0x0c62f57, + 0x10bf33e,0x13e0548,0x093d554,0x179ec02,0x09591d1,0x1808b22, + 0x04f6179,0x043a169,0x02af722,0x0c01f43,0x138f8f1,0x10056f6, + 0x11972e1,0x12475d6,0x0bf9b90,0x02bc552,0x18d4787,0x09ac7fd, + 0x0bb9ea1,0x04e2d67,0x13fc3cf,0x09be234,0x03d1331 }, + { 0x0513d1e,0x03316da,0x0af7973,0x0baab2a,0x1e78a8c,0x1c36856, + 0x1e8ff9f,0x18bd146,0x07a04f0,0x1168952,0x1741b32,0x0dc85c4, + 0x114c669,0x1909b03,0x1851a62,0x1c396a4,0x01b89f6,0x17a6938, + 0x03bf657,0x1ac2ef0,0x0907aaf,0x0262ddb,0x19b5ceb,0x01b66b5, + 0x074ac42,0x1d024f4,0x13c9d47,0x02c63bc,0x1a2edd1,0x199b50f, + 0x136ca7d,0x16ffaf2,0x0406864,0x1c95326,0x074f88b,0x0ce7964, + 0x0043cc7,0x1482731,0x11ab7ab,0x13f6645,0x067f28a } }, + /* 167 */ + { { 0x0148ab5,0x1d92c65,0x0145f05,0x1f678c0,0x19a1976,0x1946fcd, + 0x01a6323,0x02fd44c,0x0e8d450,0x1d9663a,0x02908a1,0x06520af, + 0x1237257,0x0bdf639,0x157b894,0x1778903,0x1cf1d48,0x16ba08f, + 0x01fd73f,0x02fcd69,0x0e1b462,0x02a0f5c,0x12c01eb,0x0b40191, + 0x057a6e0,0x14ce20e,0x0f4be7e,0x1f2a9a5,0x141cad1,0x0aeda04, + 0x074dc2f,0x07052a1,0x087879c,0x052f772,0x154973b,0x1c9826e, + 0x1d3efb9,0x17bfd27,0x0f6cba3,0x0e837a3,0x05ff091 }, + { 0x19c6632,0x089522b,0x0055e46,0x1f71441,0x1b19a44,0x0b1ce9d, + 0x1ee114d,0x19de9f2,0x1bc3c9b,0x0bf15e5,0x1990439,0x1e57e33, + 0x0d122b3,0x09abecd,0x0062768,0x1fecc3e,0x1bb79e5,0x033aab9, + 0x1cbcf13,0x1cb931d,0x0731444,0x1002688,0x15bd878,0x0ebac6b, + 0x0366fac,0x19186fd,0x18b2153,0x1f88f90,0x10850b9,0x121f056, + 0x0cb012b,0x05ee418,0x0e94f64,0x1de4eae,0x19969d4,0x06cfdf5, + 0x10373a6,0x1e9869d,0x0591b09,0x07452e4,0x0668101 } }, + /* 168 */ + { { 0x04509df,0x0ec89f4,0x0dd84e1,0x1b9e672,0x0978bed,0x11d0a47, + 0x0974cd0,0x0f25be8,0x1ee8cb5,0x1fd0571,0x1154f10,0x0d3a638, + 0x08f0153,0x0fdf8ea,0x13c22ef,0x048940b,0x1e69444,0x1d6ffa5, + 0x0d7768c,0x06bf034,0x0b7c016,0x04f3b7d,0x0217225,0x0e6ef06, + 0x1fcde16,0x06925eb,0x128953e,0x1b196a5,0x1ec985f,0x0533209, + 0x131885a,0x0f5204d,0x0db9741,0x0f0dbf9,0x1959438,0x1c72c5d, + 0x13beffd,0x1051a36,0x0ac7efb,0x05e17bf,0x03b35b7 }, + { 0x15c3749,0x06f4fa9,0x1122ffe,0x1f15bb3,0x03c1f20,0x1c7b319, + 0x0cdef23,0x09352eb,0x1e8f3ae,0x094f23a,0x1898a09,0x01aa3ab, + 0x1dc32f1,0x13c3178,0x1034a5d,0x17c6cb5,0x138854c,0x109e3c9, + 0x0d9f918,0x0009de9,0x0ee148f,0x0872e88,0x1e8de85,0x1051141, + 0x0778dd2,0x1a6a4ba,0x1b3edcf,0x0d0614c,0x0049529,0x000983c, + 0x0527d11,0x12ec16d,0x033c709,0x1ae4cc1,0x129496d,0x1906819, + 0x0771f99,0x117205e,0x11a14fd,0x1d79b2b,0x047d0a1 } }, + /* 169 */ + { { 0x12811f1,0x1a7ffb2,0x000899b,0x06c5de6,0x0aacaa9,0x05d0657, + 0x1e95543,0x0ced870,0x0007f54,0x1a80a15,0x1c99ce8,0x0054405, + 0x05c7fd1,0x19ee373,0x0bb95c0,0x0c7b2bb,0x0c3064a,0x1303417, + 0x18ac947,0x1e17608,0x16e746c,0x12aed49,0x0380c32,0x084cb6a, + 0x060f243,0x07ae43d,0x0da6d3a,0x0c6f657,0x17770a9,0x1ac63d6, + 0x099807e,0x1da742b,0x12147f6,0x0f4b08f,0x1578a65,0x0c0b68f, + 0x03213a1,0x0654d9c,0x0a1732c,0x094932b,0x08f4b61 }, + { 0x14eb3c1,0x0760ca5,0x09c16aa,0x0840647,0x0c549ac,0x1663554, + 0x04c893d,0x14601a9,0x145f9a5,0x129dcdd,0x1eaeec3,0x0220112, + 0x10e46ef,0x0bd66be,0x01cf95f,0x16b11fd,0x1e50f7c,0x0be7e67, + 0x01555f4,0x0a7acb9,0x12e20ea,0x0239447,0x1f767ad,0x1d6d151, + 0x1edfac0,0x1065596,0x002180e,0x104428e,0x1eb06c5,0x0344807, + 0x0b1a519,0x04bcb95,0x04cf5bf,0x08d74c0,0x01627f2,0x1db0ab3, + 0x13c45ea,0x09bc58b,0x06007b6,0x004a499,0x08f942d } }, + /* 170 */ + { { 0x0845808,0x1618147,0x1f147c7,0x156ef57,0x0302bff,0x0cbee3e, + 0x152e7e3,0x0964d5f,0x03aac59,0x09d41e2,0x165370f,0x17a2ce9, + 0x1ce3b74,0x0552c88,0x192dcdf,0x059a488,0x173871c,0x131492b, + 0x0d1103f,0x1e490a7,0x0d7d419,0x19f0295,0x1769a83,0x0d90d81, + 0x080d684,0x1a13229,0x0be0c93,0x04ad13f,0x0f117aa,0x08f403e, + 0x0df1d2b,0x11bb93b,0x026dea0,0x1e42eab,0x0dce59b,0x06a4c40, + 0x13b1eb5,0x16abe1f,0x06b2f82,0x0a52938,0x0383002 }, + { 0x0744723,0x1ad202f,0x120683b,0x0a35c10,0x1b5bcf7,0x00fbb7e, + 0x16333fb,0x18d57f5,0x1fab37f,0x1d2ec18,0x1b6de3e,0x049191f, + 0x10be39e,0x16c9f98,0x13eb57e,0x0b8494b,0x11e913d,0x0ba3fed, + 0x1462dfd,0x148f928,0x0327052,0x163e7da,0x0788235,0x1ca717d, + 0x1cb9c70,0x08b589a,0x056ec5e,0x0c6a4eb,0x1106c73,0x1c402d9, + 0x01a8b01,0x1841376,0x0d42a06,0x08256e9,0x11c74f1,0x096a4b6, + 0x022ce03,0x1a59b44,0x0169727,0x12dd683,0x015f187 } }, + /* 171 */ + { { 0x0ee4684,0x0f50305,0x0f20253,0x0cf9b7b,0x02b21f0,0x09898ca, + 0x18526c6,0x14d4873,0x181a7db,0x125eea0,0x0ba03fa,0x0e0c785, + 0x02c6213,0x09411ee,0x02c259c,0x023636b,0x1158326,0x03a21ea, + 0x0f080e1,0x0df0622,0x12d22e1,0x0b15ecc,0x0338813,0x0327116, + 0x1bcd6f4,0x063a4ce,0x1474dde,0x125bda3,0x1dae734,0x0ba7e2e, + 0x166756f,0x13296c4,0x0813d52,0x165346a,0x13d83a1,0x18323b3, + 0x13e9c2a,0x10bcf57,0x048e158,0x1e73fdc,0x06146f1 }, + { 0x18e2aa6,0x1699f03,0x0996f41,0x0f3bdd2,0x093af7f,0x1207423, + 0x03e076a,0x0fdaadc,0x09b9a40,0x0fdddc4,0x0654641,0x15b9dbd, + 0x19dcf44,0x0496dd1,0x1c7e34c,0x0ee96fe,0x1a54231,0x1b3adae, + 0x17d817a,0x0d44a34,0x1a9e745,0x17c3d1c,0x040c752,0x168e97b, + 0x1000605,0x148eda1,0x0ad996a,0x1b4bb7e,0x11eeb4b,0x1efab31, + 0x1617468,0x0c46ef8,0x08149ef,0x085ff81,0x13a5a17,0x1c5c35e, + 0x02a465d,0x15043ac,0x0014383,0x13c0d7a,0x095543f } }, + /* 172 */ + { { 0x1d7c6ef,0x1e37a42,0x1093df2,0x1ac7637,0x0ad8084,0x065d316, + 0x13a22fe,0x125bf21,0x0b455c1,0x0725b43,0x1f1bb66,0x11aaee9, + 0x176146b,0x1d71003,0x188e279,0x04a52e1,0x07961c2,0x0a920e2, + 0x021397d,0x042a207,0x02737d2,0x110bf14,0x15b4833,0x04ce9f1, + 0x19f514f,0x0edf188,0x15c3004,0x0a8b20a,0x1b760e8,0x1aecfe7, + 0x0677ead,0x13d1854,0x146362a,0x0a593ca,0x1e2929f,0x1896da7, + 0x0e5d698,0x0438827,0x05bfe97,0x0f05745,0x06db434 }, + { 0x03f0d95,0x03249ae,0x0254192,0x049ce91,0x0917db8,0x179f224, + 0x17d89ac,0x097ee7f,0x02b7f57,0x1076e2a,0x0c9c8f1,0x13455ee, + 0x0cbe1c0,0x1e5688a,0x0d19a75,0x15ff2fa,0x00a321a,0x04b2330, + 0x1433587,0x1c5775d,0x150eb94,0x00ef623,0x019b869,0x1513eb1, + 0x0990db1,0x149d0df,0x13c9d65,0x073c9ad,0x00dddfc,0x1bc0607, + 0x104473e,0x1b33914,0x0afcd7f,0x0182878,0x0b6db87,0x099d7ff, + 0x16d2c6e,0x1cc0d84,0x1ea513c,0x1ce55c4,0x007a791 } }, + /* 173 */ + { { 0x09f0300,0x148238f,0x04139c3,0x13799bf,0x00253ad,0x02983c7, + 0x0a277fc,0x0c4a380,0x0ae8934,0x0f78497,0x11a117c,0x1235490, + 0x142c90a,0x18ed6a5,0x11bb683,0x0cf6432,0x0f333df,0x0783b28, + 0x0c56805,0x1311b61,0x10f9c6e,0x175aa17,0x1cb8319,0x1806f1e, + 0x16311e0,0x086aea5,0x0aba1a5,0x09175b5,0x1f1c8f5,0x11c6d9a, + 0x151a005,0x1289a35,0x09e3216,0x18e9909,0x0b21011,0x1d32a37, + 0x05e94dd,0x0614f9c,0x1b2b00f,0x05c8a87,0x06d6acc }, + { 0x1b2d299,0x0cf4aab,0x0737ae6,0x17c7ae4,0x1a2bcd9,0x065a221, + 0x0e13eed,0x1545cc0,0x1dc060f,0x10bbb84,0x01f37ab,0x0da7193, + 0x0d74f0e,0x083b7df,0x08df3e0,0x1f7ff34,0x1137983,0x034d78a, + 0x08fe561,0x1ef43a6,0x03986c3,0x07b6db2,0x0f8872b,0x0e07b24, + 0x0134f96,0x1bb3e6c,0x1ee0e4f,0x0eab131,0x0252220,0x145e174, + 0x1f06d6c,0x0f24954,0x18799c1,0x13d455b,0x03ca050,0x043b66f, + 0x1f28949,0x1228d8f,0x11bbb56,0x0247a78,0x079d182 } }, + /* 174 */ + { { 0x09d5589,0x16ffc88,0x126468f,0x0805368,0x1ed52eb,0x1aa56fe, + 0x074c2d2,0x0ce27d7,0x1a27bff,0x1c90a60,0x03d1813,0x1dcecfe, + 0x084c817,0x01d2871,0x17e360f,0x0c46f75,0x1c99402,0x0e2ee01, + 0x19991f0,0x12b0372,0x07f35f2,0x04c5034,0x042da82,0x0c68a2e, + 0x07cec31,0x0c4573c,0x158b9d4,0x0003b74,0x02c3fb2,0x10d3a2f, + 0x0555753,0x16cfa67,0x1cacdeb,0x021775f,0x1e72f1a,0x1743415, + 0x1e88580,0x0c85159,0x1372141,0x1234f09,0x0731044 }, + { 0x048d676,0x1166f93,0x0ac5132,0x0a9e362,0x1a85eca,0x0070f5c, + 0x0b250a6,0x112373b,0x11ac8aa,0x1869b84,0x078657c,0x156f8e3, + 0x1773072,0x17b81bc,0x1463208,0x0cfed74,0x014ac00,0x1d60487, + 0x1734a49,0x19f8e11,0x1a630e6,0x1110f3e,0x13d6227,0x0e38f8c, + 0x0a40b83,0x064da55,0x0a3de1e,0x1f3b57c,0x0caf3f1,0x16b5ec2, + 0x04bde2b,0x13c1c3b,0x039dd07,0x0126e1e,0x17ec489,0x12d017c, + 0x0bdc009,0x0d90a68,0x1153fd0,0x192a301,0x06a8f8f } }, + /* 175 */ + { { 0x1235132,0x0f6b1a9,0x022d8a8,0x02b3b75,0x1db233f,0x0f7eec0, + 0x15148a4,0x15d0ac4,0x1b25111,0x1a8294b,0x006f631,0x15f23ae, + 0x1db5921,0x0bba7a2,0x14175ca,0x0e7ff69,0x05ef18e,0x0371ea6, + 0x066cc0e,0x1b30bf1,0x1558897,0x1de44d8,0x02a70c3,0x0263039, + 0x0d1a34d,0x1071e49,0x08888cc,0x125d0d7,0x0eed022,0x0a6100e, + 0x07f3c91,0x0b07e61,0x1a45f74,0x1e8d193,0x00b2b43,0x10eb4c2, + 0x0b9c753,0x07a2e96,0x0ff5f6d,0x183b650,0x04752d8 }, + { 0x1dff4d5,0x0b6756a,0x1fd1453,0x168b504,0x14cd5fd,0x0389af3, + 0x098313f,0x11c20e1,0x01be577,0x1605dbc,0x11ac237,0x059ab1b, + 0x16271e1,0x0a5e124,0x194226d,0x131596e,0x0636190,0x136ef96, + 0x1d4a20c,0x1d758cc,0x0af1fd6,0x12e1284,0x1aa8b40,0x19f83e1, + 0x0cda84d,0x1f009e1,0x0115442,0x18f06d5,0x0868011,0x14468d4, + 0x114e411,0x15f5e4a,0x03132aa,0x05446b2,0x15dca0c,0x0092d0a, + 0x0744b47,0x0a48e54,0x015495a,0x1e6ebf7,0x03a6518 } }, + /* 176 */ + { { 0x04042a0,0x076a811,0x079aaaa,0x0048a5e,0x0cb4e3b,0x0108ec3, + 0x17d31da,0x07fdb94,0x1ef4d5d,0x107f1fc,0x151b953,0x0548a45, + 0x1533a8e,0x18a233b,0x063887f,0x1a036b3,0x10ef592,0x08a4b62, + 0x0e99dce,0x00985f0,0x1f00691,0x05a395d,0x0a19c2f,0x062ef7a, + 0x083b250,0x1514754,0x15f49c4,0x0bb1780,0x19c994c,0x098bda1, + 0x1fd07be,0x1b9b435,0x001d3a8,0x07b7dcc,0x1ad5c0e,0x01ad0dd, + 0x1bfbf82,0x062e687,0x1605fa0,0x0c7db84,0x0540ac3 }, + { 0x07f43df,0x0b4d4ff,0x19329c6,0x1058373,0x0665380,0x0e148bf, + 0x1df6216,0x0095b2c,0x196aa44,0x1654aa2,0x0a5f6ae,0x0abffe2, + 0x1e0e9d8,0x115753e,0x18625ec,0x07f1c3e,0x0fd36f1,0x1cb76e6, + 0x1b88037,0x1a60e02,0x08a4627,0x1b64c4c,0x1ca7c1c,0x1e463a4, + 0x05e6097,0x1a94af1,0x0fd8121,0x1efe443,0x19b299a,0x1304a00, + 0x16759a0,0x04d6963,0x199de09,0x0ebd18e,0x1d986b3,0x13d88f9, + 0x0ebe15e,0x14f959b,0x05d3d37,0x1d9f42d,0x017db32 } }, + /* 177 */ + { { 0x0f40599,0x1b48cb6,0x03a9d7b,0x1601804,0x1ea10df,0x157b3cb, + 0x0b9eff2,0x0f07b4b,0x188ddd6,0x0b31e51,0x0f3f343,0x11fc4ab, + 0x1e5a21f,0x11a25e3,0x10fd4e3,0x00c65d3,0x11d548e,0x09afb15, + 0x0f1b993,0x1e484a8,0x1627654,0x13134c9,0x11d569e,0x1e82649, + 0x1c5f7b0,0x079d1db,0x04e8860,0x0ad2fef,0x01675b0,0x0fd88f4, + 0x1d5b3e1,0x1ca6851,0x13cdb35,0x1458136,0x16454b4,0x11c7542, + 0x17a3fb7,0x03812af,0x11176a1,0x0374328,0x0460bd0 }, + { 0x04d8077,0x06e11e1,0x14b2f0d,0x0098e41,0x02f4b58,0x0e8fff4, + 0x0a445bd,0x1c5453b,0x092783c,0x1c57a90,0x012bcd5,0x03576b2, + 0x10e29f5,0x1bd508c,0x115c35f,0x1bbe08d,0x1ba571b,0x0a52917, + 0x1a26ed4,0x1c540d5,0x044dbf4,0x062cf9a,0x1e66cd7,0x1984aae, + 0x0836726,0x0bbe181,0x16bf3b0,0x0949d30,0x16cbd09,0x1ee5be1, + 0x1deb6bd,0x0eba720,0x131b787,0x1125e76,0x013cb4f,0x16a5ad2, + 0x1f95421,0x0513348,0x01e3717,0x0782e69,0x07d342c } }, + /* 178 */ + { { 0x1fd127f,0x1960508,0x117b973,0x10233c9,0x06d36bb,0x1ab561b, + 0x0c949bb,0x0eac435,0x0e54306,0x067f577,0x1a5864c,0x0fa5587, + 0x112ede2,0x1c7e733,0x04d44eb,0x0987ac8,0x01b075f,0x030ace3, + 0x041a766,0x0fdfd2b,0x0ea9d44,0x14753b5,0x0be35bd,0x0b7a2c9, + 0x1c61b0f,0x1cc562e,0x187a22e,0x175688d,0x092320d,0x058b0dd, + 0x195862e,0x0f13130,0x0eafb3c,0x1bf4150,0x130b022,0x1618f57, + 0x00d160b,0x184db71,0x18e9c43,0x14d1c98,0x05be0af }, + { 0x1bbf49c,0x1b69c0d,0x0ffa0aa,0x13180e0,0x1e09ce4,0x07a1319, + 0x02d7784,0x065d94b,0x1da5a45,0x0e632c0,0x03dedf6,0x10edec3, + 0x0707e18,0x1287bff,0x066978c,0x10d7c08,0x090de6b,0x0dd8d4f, + 0x1cd645a,0x14fbd66,0x1b2c584,0x04a8a4e,0x0e3acd2,0x1d75770, + 0x06a33b0,0x1490a2a,0x030be22,0x00cfe16,0x0db0190,0x0ff3851, + 0x0faf783,0x18c7cde,0x051b06c,0x037d6dd,0x1ee7a48,0x1543224, + 0x1e80dc0,0x15af43f,0x0c2bb93,0x1eba9bc,0x01e6fcc } }, + /* 179 */ + { { 0x08ac924,0x0ffb355,0x0fa2d5f,0x0385316,0x06e9ad3,0x1d84060, + 0x18ca597,0x07fa281,0x11d95c9,0x0d5908e,0x0032a9f,0x1085143, + 0x096d68d,0x1106f6b,0x04a5022,0x08c3e35,0x15338df,0x1540a8b, + 0x03aba4c,0x0c095cc,0x0c0bff5,0x04bed72,0x0406e79,0x04c5d13, + 0x1a97fde,0x0c1a2b9,0x13c4212,0x1ad3b34,0x124f1de,0x0117b23, + 0x17e3fe8,0x1d50b42,0x1f1c2e4,0x09bca6a,0x13a4051,0x1a98c4d, + 0x1f0907d,0x02066b5,0x0a0de01,0x0c2bbb5,0x04522d4 }, + { 0x1fbe7c5,0x0f83cf5,0x111a225,0x1b09de6,0x10ea1de,0x10d5cb1, + 0x07adb52,0x0d0e2d5,0x050a30c,0x1252e91,0x0eeea86,0x0638008, + 0x155a166,0x080872f,0x041d409,0x00aad7a,0x09d3d8c,0x0dfff1f, + 0x1ddc906,0x0616300,0x029731b,0x18425c1,0x043fdfb,0x0343187, + 0x17d75f2,0x07c0061,0x15596ee,0x11a14c6,0x03bceb1,0x0d1522f, + 0x036eb07,0x047e161,0x038e90c,0x02d628e,0x0a897ef,0x0de3743, + 0x1da71fc,0x0a92b5e,0x102e827,0x152dafc,0x0346501 } }, + /* 180 */ + { { 0x02b0f1d,0x1224666,0x1c0e1af,0x1358986,0x03eb45c,0x04b5dff, + 0x1d9767f,0x1b4a70f,0x15ae27f,0x179e274,0x0602273,0x0eec378, + 0x01a008f,0x11650c5,0x1d28210,0x066e3e6,0x04253b7,0x0774414, + 0x13024d5,0x1f8db0f,0x0d6bcb6,0x0db0a4b,0x01227b0,0x1c64b89, + 0x029b949,0x0b35496,0x09ef7b0,0x0b8d94a,0x0a28131,0x07776e7, + 0x13e5511,0x074422a,0x0683eb3,0x030e79a,0x1e634e4,0x171f64d, + 0x06c940b,0x1845540,0x125b70e,0x19fcaa9,0x07c1d42 }, + { 0x0110aa7,0x1381fee,0x0de1d9b,0x0fe6c5c,0x0b7b79d,0x16e51e5, + 0x11d756a,0x0e7a4b3,0x160be33,0x137653c,0x13a3fca,0x14960d8, + 0x1ff4744,0x19db82d,0x010b33b,0x096a765,0x1aaae30,0x00d1d7a, + 0x0cb4c6e,0x1f44023,0x08d97bb,0x1d25f74,0x112e9ba,0x0b97073, + 0x165ce56,0x074169a,0x1b6bdfb,0x09010d2,0x1597452,0x0673f34, + 0x0dcb1f3,0x1d29f30,0x1d6eb3c,0x0d19377,0x133ce04,0x0c14676, + 0x1ffa93a,0x101fa1f,0x0764050,0x050e786,0x0031e98 } }, + /* 181 */ + { { 0x05a17ff,0x1f67e3b,0x09953fb,0x11a2521,0x009f388,0x06d01c5, + 0x1711a4e,0x08d7e4c,0x1a169ad,0x1db0a2e,0x18bfa12,0x0428474, + 0x0533cf8,0x15e4305,0x0b7d5c6,0x07188ac,0x0fa815c,0x0df9548, + 0x1fb6a1d,0x143adc2,0x05e145b,0x0d4a37d,0x1e67620,0x01eb476, + 0x1e784b9,0x095360d,0x12c43fd,0x122146f,0x14fd360,0x0ff2527, + 0x0830e30,0x11c5a77,0x1180fc5,0x130c3e1,0x0142c5e,0x047c5fe, + 0x143a35c,0x0002cdc,0x11470e8,0x08b4519,0x0494d36 }, + { 0x1a021f8,0x0135b25,0x0db0e61,0x06f2dbd,0x114c908,0x1b63b16, + 0x14e55f8,0x02cda5c,0x0751cf2,0x1aab765,0x0928663,0x1c00336, + 0x0edaca1,0x0590615,0x021f691,0x14e668f,0x0cdff41,0x1c9f6a6, + 0x11f0335,0x02f888b,0x10098d7,0x0548dfb,0x131218d,0x0b3775f, + 0x146f93b,0x18ad0f8,0x0795893,0x1a71767,0x1f8443d,0x0d56981, + 0x1f25b50,0x097e209,0x1670f03,0x032c135,0x07b4a5c,0x0a0a07f, + 0x134200f,0x070fa3d,0x11bcdda,0x0bd77a9,0x03cfdcc } }, + /* 182 */ + { { 0x123e13d,0x015435a,0x02814db,0x105241a,0x1014a45,0x0b894b0, + 0x0d1e39d,0x1d47aa5,0x07eb51b,0x0ba3033,0x03a4641,0x10c30f6, + 0x08709f7,0x1434447,0x02bb621,0x1f9a805,0x1d7d94a,0x1bcd404, + 0x084a6bc,0x0c065fc,0x008250c,0x194c1e2,0x1d792f9,0x1677d1c, + 0x11bbb7a,0x1944c19,0x12d8631,0x0634065,0x19c4a4d,0x02d09fa, + 0x188db76,0x1da9ec3,0x1ece345,0x18b8aed,0x1334795,0x0f74f55, + 0x04a1ebd,0x062c6d3,0x1ba844e,0x01e7a35,0x089296d }, + { 0x0a82c97,0x09447e6,0x0372c59,0x1a284fd,0x06c6c12,0x1f6ed49, + 0x13c1d30,0x17ccd52,0x0eaa01e,0x030070f,0x17a1b65,0x1cf861e, + 0x1114abc,0x05a2b51,0x075c083,0x08584e8,0x013279f,0x05582d5, + 0x108e11a,0x0c1f5fa,0x19e670b,0x0098c69,0x0863bfb,0x0416631, + 0x1f1ac89,0x101f583,0x0360e67,0x03c7975,0x01a3010,0x09971e4, + 0x16197e2,0x1998ccf,0x08bca7d,0x0303e57,0x19e689a,0x199dc35, + 0x0ac0a12,0x0173266,0x13150c6,0x1ee5634,0x09233a2 } }, + /* 183 */ + { { 0x0cbee17,0x146fb05,0x1371c5f,0x04b849f,0x0f0959c,0x07fe580, + 0x0621f95,0x0d68de1,0x0d28511,0x0c9ef65,0x07e946e,0x09f1774, + 0x1e0bfaa,0x08790c1,0x04927bf,0x0eef339,0x1589684,0x0fc9e59, + 0x0c8b508,0x17f6fe4,0x1009284,0x0d6a157,0x10331c2,0x163ac2a, + 0x122749b,0x035634f,0x09c5f0f,0x0dea167,0x1c5eeb7,0x14c2ddc, + 0x17e2c87,0x148f076,0x0fb19ae,0x0e1f3ac,0x0e6d4b8,0x100990d, + 0x12971ac,0x12c8497,0x00a46b2,0x0d243db,0x02bb26a }, + { 0x1f81416,0x1a21a8a,0x0ed2628,0x0f55feb,0x086e72e,0x0b930e0, + 0x193780c,0x1fc7a3e,0x05c0a1c,0x0e03c36,0x00d004c,0x09b166d, + 0x0d542ea,0x0d1cda6,0x1dc9ce8,0x04fe25e,0x0e1cbef,0x00a7f3f, + 0x1aec9f7,0x1f813c2,0x1dc7ee7,0x0ba0872,0x1037330,0x08767bb, + 0x0674219,0x0dbd1a3,0x00fcc70,0x052696c,0x0c10709,0x0f6ce11, + 0x1ac061b,0x0f33f2c,0x17ee8ba,0x18449d1,0x12d0926,0x1c1e77f, + 0x0e92d4d,0x130a239,0x1ac22eb,0x1f1c32d,0x0937cb3 } }, + /* 184 */ + { { 0x0fbfdce,0x073be0b,0x13015f0,0x13931a9,0x0a034cc,0x0b96907, + 0x1b5c909,0x079cec0,0x00019a8,0x030daae,0x05c58a6,0x1007e2b, + 0x1b80ba2,0x02d07eb,0x1050774,0x155441e,0x13b4b0d,0x04432c8, + 0x08e123b,0x10ae8d5,0x05d2e66,0x0d1f024,0x05b4569,0x0d20bba, + 0x0c7743b,0x15d40e0,0x16062bc,0x1d8636f,0x174b78c,0x18ca695, + 0x0a20363,0x0a87c5e,0x0659db2,0x03e0e65,0x09f67ec,0x0063707, + 0x1f1048c,0x09bfee0,0x1a84619,0x00ef0b0,0x04d57bb }, + { 0x1b396b6,0x1bb4529,0x16b2f12,0x09276a3,0x1c8b24c,0x0570d9d, + 0x047ae8c,0x18a67ca,0x1945147,0x09ddeca,0x1f8f3a2,0x00622f3, + 0x146cc86,0x1fc905e,0x0c2859c,0x0c2c069,0x0eb6b25,0x1d99489, + 0x145a360,0x1345493,0x1128bc6,0x1d7786e,0x0d25279,0x04d33c3, + 0x1419a87,0x1b59309,0x1efc84d,0x0d8b08e,0x1971470,0x0c84d27, + 0x17f956c,0x0f736e8,0x1d6eb75,0x19e42b1,0x0ca4237,0x076a6cb, + 0x15fcfae,0x12bf21a,0x0aaa038,0x0312f3e,0x01067c1 } }, + /* 185 */ + { { 0x0bf8883,0x0a84219,0x199f211,0x14dfa0c,0x0755286,0x0119aea, + 0x03e3ddf,0x129ae16,0x02f4a2c,0x1c7306d,0x02b3d59,0x1159a23, + 0x19a468d,0x1fadc86,0x04e0c2e,0x122099d,0x074ed4e,0x075258e, + 0x1dddba9,0x0e62da4,0x0b12ac6,0x0e1b0dd,0x0e62b5d,0x02448a3, + 0x1d48299,0x1d76191,0x014c290,0x0c88044,0x12d5a52,0x0997194, + 0x0f0e911,0x0bfd9e3,0x148694b,0x1dc5c6d,0x05bb199,0x1dc9c0a, + 0x04306ad,0x152cafd,0x05c96ce,0x123e69d,0x07e4f70 }, + { 0x1f70919,0x00b74db,0x0fd4fce,0x1a2d600,0x165216e,0x064cf2b, + 0x13fd1de,0x0208d8d,0x030a518,0x152d5f4,0x1ca36f9,0x13cc8bc, + 0x16ef6f4,0x056677e,0x175cfab,0x1e7eedf,0x06f8c37,0x1f61ca7, + 0x1901ff0,0x0410056,0x1cbd733,0x1d4b312,0x0623a3d,0x157f601, + 0x123637c,0x0cd4194,0x1d01fcd,0x0b1753b,0x1fae502,0x1772e65, + 0x04ffc06,0x1fc4a30,0x1eaeace,0x0e5d0fd,0x05860fc,0x0b38d3e, + 0x1eadcdb,0x162c56c,0x1a2f544,0x1a8d999,0x02ae49c } }, + /* 186 */ + { { 0x00849f2,0x0d871e2,0x063048e,0x1b48821,0x1136a4c,0x03fb24a, + 0x16a6795,0x18cc2a6,0x07a9bba,0x1725ee2,0x11ebda4,0x0c8ca6a, + 0x0a195a1,0x05a3d3a,0x1b2cc66,0x145650b,0x1fc9de6,0x093c2a9, + 0x18ae94b,0x1807141,0x1a93471,0x041ade5,0x04ae86e,0x063d944, + 0x150da6f,0x1636a5f,0x1a00acc,0x028dc7e,0x04c8c4d,0x00989e3, + 0x05c3270,0x1dda425,0x130f12d,0x02987d6,0x1fee71a,0x0336eb7, + 0x0918de5,0x00569f4,0x1c6dc8f,0x0a54e6e,0x0180e9d }, + { 0x1ab77b0,0x12a1794,0x18a30c5,0x19ef5dc,0x1d411d9,0x1e17a06, + 0x01a14d4,0x19e0898,0x04b0ae4,0x1c6e3f2,0x1099bd8,0x030b2bf, + 0x1da0924,0x1e97f5b,0x07699c7,0x12f30c7,0x0d55ea3,0x12b42c7, + 0x03ce0ca,0x129e62b,0x18317a6,0x03698b6,0x0a508cf,0x146b4f7, + 0x0cb2630,0x09d97e5,0x17c7fdc,0x1df1efb,0x0ee2f3f,0x0292acf, + 0x12a2e6d,0x02ada0c,0x1b4f91b,0x07e7e68,0x1b08bd7,0x022ef0c, + 0x1777eb4,0x1e12b31,0x016d04a,0x079b157,0x021ca6f } }, + /* 187 */ + { { 0x1e66635,0x11589d1,0x1abc385,0x16553ee,0x1ef20a2,0x0d99ab0, + 0x0e8c11b,0x11b568e,0x17802bb,0x0205ebb,0x06d1302,0x1ebd4d3, + 0x115b6ba,0x0d9103f,0x1846400,0x0020b8d,0x0a9790b,0x072ef0b, + 0x0d9fc01,0x025e2bb,0x1d2522b,0x02c5012,0x0617eb5,0x0142284, + 0x16953df,0x0605e67,0x0fd140d,0x1884253,0x077bff4,0x02000e1, + 0x0603dd0,0x050153c,0x0440b4c,0x1515a37,0x03d610a,0x1eecfbd, + 0x05e8d94,0x11055c0,0x1d8d4f7,0x0b24044,0x05aff58 }, + { 0x0458e40,0x1669054,0x0af6016,0x10292e6,0x1a5557d,0x0e5396a, + 0x104c57c,0x0478e0e,0x0952b53,0x197134e,0x13eb7df,0x0aacc92, + 0x065c592,0x0d3e933,0x0edeb34,0x050ca2a,0x03d86fe,0x1d36f83, + 0x1f54eda,0x03b626a,0x0d011e9,0x04f49f5,0x04656ee,0x0c77fcd, + 0x1e1af29,0x0431eb8,0x0a209e2,0x1565738,0x059b6ff,0x13491dc, + 0x145de0d,0x1ee053b,0x0695174,0x022b0b7,0x01d9ee6,0x138f30f, + 0x1907d84,0x1da78ea,0x0a5dd93,0x03911b1,0x03eab7e } }, + /* 188 */ + { { 0x0e5718b,0x14a5b29,0x07a71ce,0x09e99dc,0x03aefa5,0x1f76f57, + 0x0798d54,0x034ca9d,0x15f3aca,0x12a0f0d,0x00cc5bc,0x09121a1, + 0x0ed7129,0x1dbfca8,0x196bd8f,0x07c94f2,0x00dc74e,0x06c7e4f, + 0x0bde7af,0x1c91a5d,0x07e6b4e,0x1545bbc,0x09162a1,0x199d5e1, + 0x1621ff7,0x006ec63,0x1f7d9e6,0x0451ddf,0x1067278,0x03a17c8, + 0x0a48435,0x160fc6c,0x1f63501,0x0f14ec8,0x0719e5c,0x0a882ec, + 0x03a3b8a,0x06632f8,0x0551303,0x09e71c1,0x03491da }, + { 0x1062eae,0x1682365,0x1db59c1,0x0aba10e,0x0e7db73,0x118ae97, + 0x00148a4,0x1b701bd,0x0c402bb,0x03c2b31,0x14ccdd0,0x04b84dd, + 0x135f935,0x1eab476,0x1a85359,0x1163cd9,0x1896688,0x0c8b508, + 0x171c59d,0x1aa40ab,0x1df20fb,0x1bf22ba,0x00cf441,0x012466b, + 0x1100aec,0x1c4a749,0x05b3614,0x1f3c3a0,0x0263682,0x1b92a19, + 0x15fbaf4,0x037499f,0x01d172b,0x02c1c20,0x0e755d3,0x1c6efb5, + 0x00d517d,0x1534ac4,0x16862ba,0x1fad5a2,0x00c843d } }, + /* 189 */ + { { 0x1373300,0x008ffe4,0x0c01156,0x1533fb8,0x1c39332,0x1e5b2a8, + 0x0e070d4,0x04fc337,0x096a83d,0x1a5c925,0x18fc69d,0x1f9765d, + 0x07cbfc8,0x0086ab6,0x09e3b10,0x15ef35e,0x02fe0ab,0x1b7ef34, + 0x0ce6baf,0x0da0e4e,0x1db6756,0x0eb8902,0x0f4d6b5,0x0a393a1, + 0x1e69470,0x13e5add,0x034e8c1,0x0efb690,0x0d75305,0x1faa2b9, + 0x0f4b1c3,0x1c0db0a,0x0615aec,0x1fdaef4,0x132c16a,0x0ee3333, + 0x0a0a8ed,0x17e4b5f,0x17da7bb,0x13a6bed,0x02dcc46 }, + { 0x05f0e77,0x1668363,0x052b329,0x017ae36,0x1dcc798,0x09e6006, + 0x07e2cf2,0x0af6c44,0x1ae8cbf,0x0fe6ad9,0x0398ff7,0x0e7eedf, + 0x17bc929,0x0370995,0x01228d0,0x193c5d3,0x003d51e,0x12662cd, + 0x08cc206,0x1a65767,0x066b9c9,0x0940742,0x0004841,0x17ce52a, + 0x0032a1b,0x0246158,0x08924e1,0x17f8cae,0x1ba0ffd,0x10675b5, + 0x00ba5ca,0x1815290,0x00c0a4f,0x0c5e3fb,0x0731667,0x11ec588, + 0x112da0b,0x064b771,0x1e7f208,0x1b79b7b,0x05a1a65 } }, + /* 190 */ + { { 0x0485684,0x1348d21,0x0326fee,0x125388e,0x013116b,0x15028cb, + 0x065c798,0x1b56960,0x05ff499,0x1922d53,0x0e3bffc,0x0fe94a4, + 0x15c2ef8,0x064eaa8,0x1b71aeb,0x1595982,0x07e2dbd,0x1ad3f91, + 0x06eebb2,0x1b55895,0x18858de,0x16973e4,0x1fcc229,0x112ab27, + 0x12fc2e6,0x108a637,0x145df81,0x0cabe50,0x0b1bee3,0x0683180, + 0x15298fa,0x02782f6,0x0d0ce79,0x1a1315f,0x18d7125,0x0f94957, + 0x1c4e403,0x1a250bd,0x1ef67d2,0x133dfcb,0x05ae950 }, + { 0x04f7455,0x12f73c0,0x1a0848b,0x0e440cc,0x141a499,0x0af1999, + 0x130c5de,0x1db2fa4,0x0e48efc,0x17a091e,0x0f08704,0x1b2433f, + 0x0ee8738,0x0331d1d,0x0ef7184,0x14db776,0x0c28593,0x09b01ec, + 0x0f06b1d,0x044fe5c,0x0519926,0x002f557,0x1faa4ab,0x0d02559, + 0x16f0bfd,0x16e2dac,0x13f0aa0,0x19cfd08,0x122b273,0x040d31a, + 0x054e101,0x0a50cf1,0x16088b1,0x0434441,0x1f30996,0x1843ff6, + 0x0f4a7ca,0x1198b09,0x14a6032,0x0fd47db,0x0411066 } }, + /* 191 */ + { { 0x0d04b63,0x181abe1,0x0862060,0x1be9253,0x1fc5a34,0x08caef9, + 0x1db688b,0x0e78e77,0x1cb4324,0x06f97c4,0x1fc4e05,0x1cb9d32, + 0x14345af,0x05cb027,0x18fd7e6,0x015cbb1,0x0e950c1,0x1d6bca1, + 0x1b497fc,0x1aa88fd,0x00cccef,0x0f0739e,0x0fda394,0x0a9f499, + 0x0d591ab,0x0462d8d,0x144ad87,0x1778220,0x0bf7608,0x1489dad, + 0x126ee4c,0x003cf2c,0x11231be,0x065f3ed,0x1a44103,0x13a1507, + 0x10a96db,0x0f2137c,0x047a8f7,0x08a69be,0x01cceb6 }, + { 0x06d0f55,0x0862786,0x1274b48,0x1738ce7,0x0cadf61,0x071fddb, + 0x06466a7,0x1c9baff,0x093b063,0x1afa4a6,0x0a4ef84,0x167828b, + 0x1c580bd,0x07a977b,0x01c8cc8,0x176d49b,0x0e88814,0x13a6c3b, + 0x1ea5f7b,0x1ee4758,0x18334f6,0x181f1e6,0x1f78ae3,0x0e404e0, + 0x0f082ae,0x03730b1,0x1377e92,0x111d85a,0x1a17c6e,0x042cc69, + 0x06b6597,0x073002e,0x0e59e54,0x1b59131,0x0176efb,0x06156c5, + 0x0d48b20,0x1a28caa,0x17a8cf3,0x0669d44,0x01f1752 } }, + /* 192 */ + { { 0x067ea91,0x13b2d9a,0x1116022,0x1dfa5b3,0x1f4632e,0x195e379, + 0x171b673,0x15cf6eb,0x0359813,0x1e46920,0x12f637b,0x0413c89, + 0x0223ecb,0x10a92b1,0x0e8438c,0x1c334b3,0x1343f1e,0x1fd0a6c, + 0x0c3123d,0x0f8437f,0x1437df9,0x0875186,0x11398a2,0x028eb85, + 0x0e2a465,0x152d943,0x104999c,0x123e03c,0x0ab3b82,0x0d2e18d, + 0x1b271bf,0x1c2fa45,0x1277a5a,0x185d6db,0x160e453,0x037b11d, + 0x0a2392e,0x182e8db,0x0f0af42,0x120cb12,0x04cb8af }, + { 0x14b1953,0x0102bdd,0x1bba8ac,0x09eb2fe,0x0ce08b4,0x1209642, + 0x1766d79,0x0330a9e,0x1b3cd49,0x0899316,0x0aed746,0x05c8dc8, + 0x0090276,0x0bc73fb,0x157239b,0x182d906,0x02438b6,0x0477d54, + 0x1543d86,0x0e6f21c,0x178ed01,0x1172beb,0x0462bd1,0x0b68e28, + 0x0d5e871,0x07cd0b5,0x0d077a9,0x000b2d8,0x0ca6109,0x1e19140, + 0x084aa55,0x06e98cb,0x1aee800,0x0020a17,0x049d402,0x03b620a, + 0x1f080fa,0x0edc98f,0x1e3f230,0x04baf30,0x0486a5c } }, + /* 193 */ + { { 0x01b4f36,0x0f109ca,0x13e4148,0x09f0076,0x1aacfb1,0x12a5d45, + 0x188b94a,0x0d9fbe3,0x08fe479,0x07d5ddd,0x0eb2dab,0x11b6b1b, + 0x11ae078,0x00cefd2,0x0635cdb,0x02dddbf,0x06a35a7,0x18aae14, + 0x1219186,0x1a8ced3,0x0a5ebe7,0x07b1d32,0x142d8e0,0x0c124c4, + 0x019149f,0x0d98a5a,0x028b7f1,0x12334fa,0x1466ac0,0x0d2ae77, + 0x1b31153,0x0d30d55,0x1fa4a24,0x04e76c9,0x05c5c69,0x1aa1216, + 0x01fa75a,0x178eb66,0x1015180,0x112f1c9,0x05d269f }, + { 0x0920419,0x001860a,0x1ce4e9d,0x11212d0,0x0845d86,0x1b87d30, + 0x05313ba,0x1970373,0x1d9fc5b,0x1e55036,0x1e3cb6a,0x084feb1, + 0x0a06539,0x18ee295,0x1217d9e,0x037546b,0x1722c91,0x02d3ec6, + 0x1b0b60d,0x0200b95,0x1347404,0x023d472,0x0d61a29,0x1ca2587, + 0x0180b8d,0x0758277,0x148445a,0x1b54cdc,0x17cd8a4,0x0ed5918, + 0x1db02f5,0x0c22c9b,0x1d4185d,0x16be4d0,0x089876e,0x0759db9, + 0x09b0268,0x125ad60,0x1543c3f,0x0b44db2,0x08ac999 } }, + /* 194 */ + { { 0x040a39d,0x06e4d93,0x07e6cb2,0x11dbc19,0x01ff0b3,0x165d051, + 0x1a6f687,0x02ee9e8,0x1080d04,0x1481666,0x0518122,0x1465e93, + 0x15e956f,0x0bbb558,0x03e173e,0x1e92469,0x0ee0066,0x1e10fe3, + 0x1bbbcd9,0x03d7fdf,0x05ed35b,0x0e2309f,0x1e01160,0x0d740e2, + 0x1e8e6ea,0x1f6e5ef,0x0a5435c,0x1bf9546,0x048889d,0x1c9b0ed, + 0x14725d1,0x1b75ff7,0x0867c8c,0x17573e7,0x0c7c72e,0x11a4ce8, + 0x097912c,0x12a822c,0x07935a0,0x1b9afd4,0x00c7c1d }, + { 0x0e963a7,0x118660e,0x0b794ea,0x19898bf,0x1352f64,0x1457dfb, + 0x08be0a0,0x00e5735,0x0ca2121,0x0139e2b,0x15db719,0x0ca90b4, + 0x1caadd7,0x085ae3b,0x05ab0fa,0x1e736c3,0x09fd1aa,0x0106a1f, + 0x14172f1,0x1240c59,0x12fdfc3,0x192607f,0x05058e1,0x1d043cc, + 0x0b8d82a,0x1f86799,0x0cfe9e8,0x1eb1f28,0x04ca925,0x0e96fb2, + 0x17ebafc,0x032314e,0x0061563,0x1b08c06,0x17b5ae1,0x02f3136, + 0x0d41244,0x1a1222d,0x0ceaefc,0x15c3bec,0x024ffc9 } }, + /* 195 */ + { { 0x1c7cb2b,0x06e02c9,0x0fee27f,0x0ab200a,0x01243b9,0x011a1e6, + 0x1af3d86,0x0c6c03b,0x166c18a,0x122a377,0x04ca1cd,0x0e03d92, + 0x11a5290,0x1cbc461,0x16e009b,0x1efaf86,0x02a92d1,0x04295c3, + 0x0a9e5ca,0x13960a1,0x0005180,0x1e51e59,0x025f519,0x1eb728d, + 0x077c09e,0x0c27906,0x0bc8906,0x066e588,0x1bb206c,0x1f06f9a, + 0x0d76814,0x1538281,0x026c6d0,0x17d99de,0x10332d5,0x10c39f9, + 0x099b396,0x1e7cf79,0x06e9070,0x1a280c4,0x089e4d3 }, + { 0x05a9be3,0x14073d2,0x1ef74d7,0x100e6ad,0x04daa57,0x13de17e, + 0x158bae5,0x1c6030d,0x047cd16,0x18133cf,0x033a6e9,0x1804be6, + 0x10ca2f1,0x0fc327a,0x0816d18,0x03acde2,0x1978506,0x13feb6b, + 0x0822027,0x1b89ed1,0x1ae247e,0x04cd269,0x176b011,0x03f3b50, + 0x0664a6d,0x138fc22,0x135ea0e,0x1e619d0,0x0c33f19,0x15d6755, + 0x0afa4e0,0x1290c45,0x1033831,0x00f590f,0x12ebdda,0x0f606f4, + 0x19a1b5c,0x0b54844,0x143ef45,0x0dfcde3,0x0675d3e } }, + /* 196 */ + { { 0x07193e5,0x13ffeb8,0x039765d,0x030206b,0x0478aa9,0x06c77bf, + 0x1e7fcca,0x14eac69,0x06dbbd9,0x09d0774,0x055a1a4,0x12d0fc4, + 0x18379b2,0x04eced1,0x0fd042a,0x069a520,0x1b91b13,0x0ecfc6b, + 0x160bbed,0x0e84537,0x07789fe,0x111c01e,0x16d5a2d,0x1a4a689, + 0x1a350d3,0x1f449f4,0x01c9125,0x0b386b6,0x09e23b5,0x0a1b50b, + 0x1a711cb,0x198b698,0x1864632,0x1fa9884,0x16760f1,0x113edae, + 0x1e49788,0x0e78ed8,0x0692ea4,0x1fcc15e,0x05f7f92 }, + { 0x145167e,0x10e6302,0x0383c62,0x055ff51,0x15ee2e0,0x153de7a, + 0x1fd450c,0x0cc499b,0x0a75108,0x1c16d21,0x046bddc,0x023e80a, + 0x03e894c,0x15578a1,0x13938c4,0x1a55d54,0x0f0f63d,0x0c61e9b, + 0x1d9818d,0x192aa1a,0x1eabfc5,0x189bf53,0x00494dc,0x172a1ec, + 0x0d59839,0x021152e,0x050398d,0x0b41ec0,0x0c70459,0x11c7795, + 0x1ce4178,0x088d61e,0x0bacc0e,0x02bc522,0x01bb112,0x0699a84, + 0x05bd780,0x1d8d555,0x11634d9,0x1b21456,0x025bece } }, + /* 197 */ + { { 0x033a8fb,0x139c106,0x10741e6,0x021e4bb,0x0fbf6cd,0x0a415b6, + 0x1cfe31b,0x0949ff8,0x007bf84,0x128f8c6,0x058bc0f,0x046cb32, + 0x11a7651,0x0a009c0,0x1669d38,0x0314158,0x065e550,0x0cabd34, + 0x0f2826c,0x18a37bc,0x053fe1e,0x19d4b01,0x0f031fa,0x1c07f09, + 0x1fd147d,0x184f41d,0x054bef6,0x00a81da,0x015ec1c,0x176ee75, + 0x01dae94,0x0964c26,0x1d30ed5,0x0b90379,0x0ba3a0e,0x1537af7, + 0x096373a,0x06c3490,0x0fd8fc8,0x0978761,0x00a616a }, + { 0x01339c9,0x0f9f6b7,0x029881d,0x057f160,0x1afaa07,0x06cda3b, + 0x1b20af3,0x18fbf5f,0x100ca54,0x1898ac7,0x10c6b91,0x05e2717, + 0x0a44910,0x1886fe4,0x063c560,0x0a9a95f,0x07559e9,0x064f790, + 0x149e831,0x0435f38,0x0023e80,0x1bbd0c9,0x1ba0049,0x16046ee, + 0x1538c7f,0x0a8b1af,0x1fa327a,0x1be32e9,0x0c90975,0x1d768ae, + 0x1700a1f,0x1ef4a22,0x00728f0,0x0311efd,0x0f983eb,0x1321b7f, + 0x0311ba0,0x0a07ea0,0x11932a3,0x09c0f8c,0x0876d15 } }, + /* 198 */ + { { 0x0d3ea8a,0x06b6961,0x003b4e9,0x175084c,0x16be681,0x0383391, + 0x0403790,0x0f78a7e,0x06a7d7a,0x1f2db7f,0x186a0f8,0x09f2bab, + 0x0a6e699,0x1b04be1,0x12b3489,0x020220f,0x1baa679,0x0096cc6, + 0x00b8389,0x1888c22,0x072addf,0x016a499,0x120576f,0x086cd2c, + 0x0e64ba9,0x1c83f1c,0x08cacaf,0x12c1d63,0x08e28b4,0x1a92ec9, + 0x07b6915,0x0540ef9,0x0f75b39,0x10e8039,0x12edff5,0x0c4eec1, + 0x0f4b145,0x11ae8d8,0x05c02bc,0x077ceda,0x03040c2 }, + { 0x0fa9a70,0x0e2ada7,0x1842c43,0x1ea7d0c,0x14de414,0x1c513fe, + 0x1044c27,0x0787b2b,0x106661d,0x02884d2,0x0d44f94,0x1294c1d, + 0x0bcaa29,0x0f3e99c,0x19054dc,0x1ce3e7d,0x1fc4651,0x027e8a2, + 0x0f0c4ed,0x17f0719,0x015051b,0x1c0f5c9,0x0c0e781,0x17eb58f, + 0x16b4414,0x0467434,0x022f835,0x1acce31,0x0f2b6f2,0x197aeec, + 0x02afa4e,0x1d714ff,0x1dfd1e7,0x1a8e2e0,0x176643d,0x1d0c567, + 0x032a74b,0x18d6ac5,0x126887a,0x1343d77,0x05486d7 } }, + /* 199 */ + { { 0x1359e13,0x11a7fd0,0x01472cb,0x1e5032c,0x002d8db,0x0b25af1, + 0x008f48d,0x025d2bc,0x042f6ac,0x189a05b,0x0dc977e,0x10a56ca, + 0x0d543ba,0x0692335,0x0bb735a,0x0e51703,0x024547c,0x0dfbc01, + 0x15a7ed9,0x1f14232,0x0ec9559,0x116fd91,0x1416de9,0x1dabca4, + 0x075409e,0x1888388,0x00a67db,0x1913251,0x16f8c79,0x09309ed, + 0x0a69f5a,0x16794f3,0x0eb7fb3,0x0b05818,0x0ee3ec8,0x1595733, + 0x128b409,0x0092b46,0x17e2f48,0x01eb588,0x0380f1b }, + { 0x0a0068f,0x0cf35f3,0x1d4f02e,0x15914e6,0x0b67cf2,0x1d75be2, + 0x09522cb,0x1874d93,0x1340260,0x1a0bfcc,0x1dce79f,0x10ab981, + 0x1a8ee56,0x1c04a4e,0x02d443d,0x0ddffe1,0x1c28d5c,0x1d8bb87, + 0x165a9ee,0x0b57ddf,0x1a2ab4f,0x1b79332,0x081ec44,0x003b9f3, + 0x180a4b6,0x06317d9,0x1058afb,0x19006c2,0x0b83b3c,0x1dcb773, + 0x1acd263,0x15182fd,0x09b0fd6,0x1f7e175,0x16ea85d,0x1cb0696, + 0x1b110b3,0x08227aa,0x0a17a4a,0x1dbd7ae,0x04abedd } }, + /* 200 */ + { { 0x00ef376,0x0f0dcb8,0x0ffccd5,0x14cd9b5,0x156e5d9,0x143b236, + 0x095d51f,0x0d367b8,0x000f793,0x07a25c5,0x14b8a4a,0x163d418, + 0x1208c32,0x1b94d9c,0x1e37848,0x0473ab4,0x19ab26d,0x1a0c228, + 0x033929a,0x0d696fc,0x09f923f,0x0556595,0x08d7dbe,0x00c94b2, + 0x1c454e2,0x1175dc5,0x106fcc1,0x0fdfa06,0x1ff6f93,0x141dca6, + 0x019aeb1,0x1154ff4,0x1364b1e,0x19ba2e1,0x1cab382,0x1e0c2ce, + 0x11e3fb0,0x1846846,0x0cb4d1b,0x16631c2,0x06a20ab }, + { 0x085cbc7,0x1880b35,0x0a9faa0,0x0d269f3,0x1099094,0x1c78d9e, + 0x042239d,0x1338442,0x12247b7,0x1527fc7,0x121339f,0x1ae28a8, + 0x04b3171,0x07cc61b,0x100e525,0x028b052,0x1f397df,0x12ed488, + 0x050e445,0x0b01261,0x18bca6b,0x0d0ba11,0x1d7e542,0x012eb1a, + 0x1182182,0x0e87f5a,0x0691e49,0x1c18c04,0x0a315ea,0x134a57c, + 0x0dc3a51,0x0d75a09,0x07af8a3,0x1223ed7,0x19ffc1c,0x1c8982b, + 0x05456ff,0x0233455,0x0e5dd46,0x14f7e6d,0x045e353 } }, + /* 201 */ + { { 0x1092f71,0x0b3b249,0x15c5d81,0x05eb725,0x0b66b6c,0x045b62f, + 0x0526f8b,0x07d3b66,0x020c036,0x117ac1d,0x15c25fd,0x1a66079, + 0x0c688ac,0x15dc8b5,0x14303e3,0x1361d0b,0x02c84c1,0x08dfba3, + 0x1129ab4,0x1dabf2f,0x1369c76,0x1d688cf,0x1b22e22,0x1ca1707, + 0x0371beb,0x1532cdc,0x02199c1,0x198d2a1,0x173d2c0,0x1ad1fc1, + 0x1ed4c71,0x054b405,0x01cd3a3,0x0d0e827,0x1de368e,0x1dd04e8, + 0x15da333,0x1e2dddb,0x0f4dbb7,0x04994f3,0x015941f }, + { 0x17dd512,0x0607c53,0x17d90ba,0x0e3b86c,0x091b59a,0x1a9c315, + 0x0533421,0x195d01a,0x1d272fa,0x1121186,0x1f2d685,0x182c804, + 0x03eea3e,0x00f7cf8,0x1c02d67,0x0291b82,0x1270da3,0x0ea08e0, + 0x10606bc,0x1dc8918,0x100b801,0x0ccf1d4,0x1b7ca15,0x0135ffb, + 0x1b0bd0d,0x0122eb3,0x1a2cdc0,0x1073bf2,0x1836b8d,0x03f0737, + 0x124ed8c,0x17a6403,0x182e588,0x0815da9,0x09ade87,0x12c6db1, + 0x168641e,0x1bedbb4,0x0b40dc2,0x094231f,0x06d17c3 } }, + /* 202 */ + { { 0x181c99b,0x04420e0,0x12bf3d8,0x0390f7b,0x165dc90,0x106d5f5, + 0x0d11cdc,0x0b768c1,0x0537751,0x03ce1cb,0x1b09dd3,0x045c152, + 0x00d447f,0x15607a2,0x05484c0,0x1075a1b,0x06bc905,0x0419859, + 0x0a24128,0x1d2ef52,0x0b18e25,0x0cc2e28,0x077abff,0x15abed4, + 0x1bcb7a5,0x16ae7a6,0x07228df,0x179a003,0x1850b6c,0x0ec80f4, + 0x015e11b,0x16171cc,0x0c8194a,0x197c80d,0x15c4d04,0x1772e50, + 0x156ee28,0x14f8a4f,0x0753933,0x1487d3c,0x01ab9b5 }, + { 0x14fa7a3,0x0d5c918,0x058c81b,0x008f1ff,0x0c4af0f,0x06cfede, + 0x05c4e41,0x1fc999c,0x112c045,0x0105175,0x1db5f6b,0x08f1fb1, + 0x1a44fc5,0x053db7f,0x1b9cb17,0x1eeb110,0x09b6fd6,0x0bfd229, + 0x0aa0835,0x03a3632,0x11494df,0x0f93c4f,0x0f604be,0x176a7a4, + 0x0f083aa,0x1994c21,0x0ca80ea,0x0c90a73,0x1125022,0x104858a, + 0x1558c73,0x0e63ed7,0x1294d15,0x1731a70,0x187650d,0x1f64526, + 0x1ca966a,0x0140e21,0x0cfb631,0x0ad8435,0x024b349 } }, + /* 203 */ + { { 0x19824e2,0x0e5c332,0x1d3126f,0x109c27c,0x0dc4ce4,0x1f0f753, + 0x06899ae,0x0af4980,0x11e3ec4,0x1d95c73,0x0a392d1,0x0bc05eb, + 0x0d7e8b1,0x1199a98,0x07adb9b,0x0a405d0,0x09e17a4,0x1d65d1b, + 0x1c39327,0x082863a,0x1eb8812,0x059f095,0x10642bd,0x1e90dfb, + 0x1052311,0x1e72993,0x04a7eca,0x1ed883c,0x0f6c089,0x03f5db8, + 0x1def98a,0x07fd688,0x079850a,0x18c5d8a,0x0c466f3,0x01f9fbf, + 0x1a80d04,0x0e1497e,0x16fe649,0x1cafc78,0x0212d65 }, + { 0x015cf08,0x0d9c365,0x0bac8eb,0x0903c2e,0x0dfa4ac,0x0168602, + 0x0fe4d35,0x18f3a3b,0x174404d,0x0e7b039,0x0aff376,0x0883d26, + 0x1860508,0x0e34154,0x1a44328,0x0398135,0x01841ac,0x04a947e, + 0x0efb58c,0x02415db,0x1250e6a,0x1618667,0x0538387,0x1177e5f, + 0x0ba54e5,0x00aff42,0x1e7ea91,0x0cda169,0x0e7ce5c,0x18f3f67, + 0x0e83163,0x0df4d0e,0x01d43eb,0x189a43d,0x1680e67,0x0f2d8d8, + 0x06727ab,0x17cd557,0x0911f9b,0x0a934b8,0x066afa5 } }, + /* 204 */ + { { 0x180e91d,0x155d464,0x1beb696,0x12d5931,0x093cf50,0x1193315, + 0x0382a36,0x07d6132,0x0008145,0x0e90a98,0x077a100,0x067c7ae, + 0x122bb0d,0x1f0cd00,0x17db600,0x071ce8c,0x14c78a8,0x02c817f, + 0x04c4d23,0x055f6e3,0x057b74e,0x0bce7d8,0x0924c9d,0x1a07f1f, + 0x0a6423a,0x0053b0f,0x1563fe9,0x0fa9848,0x087e30b,0x006cbbd, + 0x09ad7a7,0x193909a,0x1c5edba,0x0b1d068,0x0e68f46,0x1bd9510, + 0x0bf6bf0,0x17979af,0x0af7ef1,0x0621ab1,0x001ef06 }, + { 0x0cdcbb0,0x0818b1f,0x0554afe,0x104f839,0x19e2d72,0x1ae4980, + 0x1c0c255,0x0613ca4,0x1969839,0x0e0e2d4,0x020b7c3,0x01fef9a, + 0x11ef9f8,0x0fcbf02,0x04541d7,0x036ab9b,0x1fe9cc6,0x079437f, + 0x03c9331,0x1b671f0,0x1ae3352,0x161b291,0x1b66e67,0x1620953, + 0x08ca810,0x1d6884d,0x1cc1480,0x04e01fc,0x1400f5c,0x11273b4, + 0x0b0a8bb,0x1dc188a,0x195d399,0x01520ea,0x15abdfc,0x0e156eb, + 0x0db730b,0x08404c8,0x04808d0,0x1fabd1a,0x00e4f5f } }, + /* 205 */ + { { 0x1f14c38,0x0322207,0x07caf47,0x155d9c2,0x1a5b59f,0x17b1984, + 0x0169c8a,0x1dd548c,0x082af24,0x0e4fb2d,0x0845677,0x17fdd73, + 0x0ff4ee4,0x1a74275,0x18f41d9,0x1559c48,0x1e00e0b,0x1c465f0, + 0x17eaf72,0x0ad1d5a,0x199d7ca,0x1262bf5,0x0f60354,0x17d30e7, + 0x0572ce9,0x02f4e23,0x15cc02e,0x03143b9,0x1541769,0x0989207, + 0x0d92488,0x16b6284,0x1e324ff,0x078b57b,0x140490d,0x1881bb4, + 0x0133d97,0x019a10d,0x1c08022,0x0c210ed,0x033d411 }, + { 0x078e5ec,0x0d1b5cc,0x08c9d4c,0x028d230,0x1de3e32,0x1182322, + 0x068cf42,0x0b3a2bf,0x1aa1736,0x1a60dc3,0x1753f9c,0x0945f24, + 0x14ac209,0x0131587,0x1259687,0x0b97887,0x03e447d,0x03ace48, + 0x148e4c0,0x1e42bc0,0x1f3492a,0x0f8fac9,0x1ffedb5,0x19bb6bf, + 0x03b4bc3,0x00432ca,0x12ff755,0x1a07453,0x0d76c09,0x0d358cc, + 0x1663df3,0x181e4f6,0x0790a22,0x0c667e0,0x0a1232d,0x1974aaf, + 0x16c54fd,0x110296b,0x0d19964,0x1548f6d,0x02d3de7 } }, + /* 206 */ + { { 0x1add3b7,0x13a3132,0x10aaab7,0x0b57e49,0x05888f3,0x12bec9f, + 0x1272b86,0x17fa82a,0x02c76f7,0x11170c7,0x080acc3,0x11d57c6, + 0x0a67f28,0x0e8e878,0x0699ae8,0x15a316f,0x1492881,0x087055b, + 0x1eb6c3a,0x04810d8,0x132f7d4,0x0294210,0x01c30cb,0x1f3413d, + 0x077f158,0x0c4c2c2,0x0bb0095,0x045526e,0x0987774,0x062e528, + 0x162f90a,0x0aecc00,0x1b79564,0x19be7a2,0x18c655f,0x12d8ff8, + 0x1631628,0x1811eee,0x04a9a2d,0x16cb638,0x047003b }, + { 0x11c1c96,0x000e0e4,0x05c3665,0x124f425,0x0a5dcdf,0x014883d, + 0x0b85f0f,0x0207572,0x1a3fe47,0x17e747b,0x0663b89,0x1abc9dd, + 0x18b0d09,0x071d20f,0x0988812,0x14a0d5f,0x0a5a26c,0x158e009, + 0x06d5c94,0x1ee6993,0x1fe12c6,0x0fa897b,0x0424f5e,0x1dc334c, + 0x0906eac,0x1531798,0x0415b47,0x17ff070,0x135f216,0x0c2b77f, + 0x091871d,0x1835a44,0x007e978,0x07ef437,0x1285ac8,0x165994d, + 0x033fe81,0x06b696b,0x0b39aad,0x00960d4,0x073dff5 } }, + /* 207 */ + { { 0x0e20fb8,0x0ac02ec,0x0fc22d8,0x09056a6,0x1c6873e,0x142a653, + 0x1c0055a,0x022a40b,0x0cb3692,0x1ff6356,0x024ade1,0x01d98fe, + 0x0c1fa3c,0x1422ff2,0x0d991fb,0x1e224b6,0x085f8b1,0x1ea3c0f, + 0x0c3c69b,0x04d0731,0x0b92c65,0x166e5c7,0x13bae31,0x0bedaa5, + 0x10ead8e,0x06e099f,0x0f2364d,0x03107c4,0x0ac45a3,0x0adea14, + 0x014853b,0x1b77f95,0x17ca492,0x0d709fb,0x0ff81f9,0x17be822, + 0x12ab05f,0x1250693,0x1d4d58f,0x16ee291,0x07544d0 }, + { 0x0797ace,0x0689a40,0x05f93fa,0x015f0db,0x016d6aa,0x0d347e1, + 0x09a23bd,0x109b7e1,0x19f9b26,0x05937a2,0x074bf06,0x19f5133, + 0x1552fef,0x11211ca,0x0be3609,0x06f01ab,0x069f63a,0x1c7891a, + 0x1353fab,0x068a9fb,0x1d09293,0x1bd39da,0x0ea0062,0x0aa5831, + 0x1f276e5,0x18e4d78,0x17fc9ae,0x0ba8ee7,0x1d4f44c,0x0a08036, + 0x1267bd2,0x0be7374,0x18f12f9,0x0527956,0x1b73d9b,0x14aecfe, + 0x1922f59,0x03b9f8b,0x0b526ea,0x1d583c8,0x0220081 } }, + /* 208 */ + { { 0x037a0ba,0x1eab9dd,0x17d8c10,0x19ba2ed,0x05a431b,0x10387b8, + 0x0b3f310,0x0120664,0x067c2d1,0x055e987,0x02f3e97,0x0bbd97f, + 0x0b362c9,0x1bc3d88,0x19f49dd,0x0bcc9ae,0x15e6ec0,0x1309648, + 0x19a70c3,0x0d2c639,0x06359e6,0x07b4171,0x09f2776,0x1ff9870, + 0x01f1295,0x0513c81,0x0628ab7,0x0d51dcf,0x1d500a0,0x13c225a, + 0x1163803,0x11b01ad,0x1746fc7,0x1886643,0x0efa457,0x1048c0a, + 0x019f6fd,0x0719459,0x0dcce11,0x158237a,0x0620541 }, + { 0x09e5a29,0x1e9c128,0x0c783df,0x016864a,0x0748d7d,0x1c41dcc, + 0x04d5334,0x0f51ee9,0x08bfbb1,0x15c563a,0x0b4b171,0x14cc0be, + 0x03a4616,0x0de58dc,0x1659894,0x04cb567,0x1042fee,0x067ba98, + 0x0c89416,0x1ae7f7b,0x1556c70,0x1a78616,0x0484750,0x164b366, + 0x061d854,0x1bec310,0x1710acf,0x1fc8c0d,0x0a4949f,0x02c2f43, + 0x0b13172,0x02c1ddb,0x0ddcc8b,0x1121002,0x199d5a3,0x0c30099, + 0x0214165,0x19c2ad2,0x0fa5e47,0x131f265,0x07f3781 } }, + /* 209 */ + { { 0x1a6639a,0x1a5ed6f,0x0e4668d,0x080556e,0x0cbd48d,0x018f168, + 0x1c8d91c,0x03eb8bd,0x0d0599d,0x04f715e,0x0e110ed,0x16c1c1a, + 0x08d285e,0x1349c97,0x0faa4bc,0x0a71fb7,0x1bfb8bc,0x048a2af, + 0x11a6dda,0x0b3fe3c,0x1682ae2,0x0fa0ef2,0x1073b2c,0x0a5a35d, + 0x0f07199,0x023643b,0x079efdd,0x19c4a30,0x0ad2f11,0x16c3141, + 0x19f2e4e,0x0d749de,0x1a3cd31,0x1d51f47,0x0813941,0x11f9cd1, + 0x061bb60,0x0ba0b85,0x043433b,0x167ed58,0x06de716 }, + { 0x12d6dc5,0x0c6820b,0x1973539,0x0cc72f8,0x1ed2cde,0x0f5a745, + 0x1f86032,0x1b6f5ce,0x075fa2e,0x113aa34,0x199ce15,0x049d523, + 0x0e4b303,0x11ae459,0x08ea158,0x0510ec0,0x0c2a8f9,0x0cefb6b, + 0x1bd7a2d,0x1830bfe,0x148aec2,0x159d6ab,0x1e24b84,0x095df78, + 0x1b4f2d5,0x010bd75,0x03ba1a2,0x0922a89,0x19bd5b1,0x0fb8d8e, + 0x1de89b1,0x05fe01b,0x1ccd166,0x18ef772,0x1c5ee56,0x09d7933, + 0x1fe1f77,0x0c1b0b1,0x096c242,0x061767a,0x051f908 } }, + /* 210 */ + { { 0x0922461,0x1b7d0f9,0x034524d,0x062ca1a,0x1bb1b1c,0x0c3046e, + 0x070cc37,0x00d2572,0x136b899,0x1309625,0x180148f,0x1617bea, + 0x05e1977,0x11b512a,0x0bffdc1,0x07b1df1,0x0781172,0x166d3e9, + 0x06f79ee,0x1789770,0x178e0b0,0x1976952,0x0f2c202,0x0365c04, + 0x00d0d17,0x0d72ded,0x1e506ee,0x0dbe719,0x0a65c5f,0x00ede0a, + 0x03a1776,0x1833bb3,0x198c82d,0x037c9bf,0x11fd488,0x118c26e, + 0x1f5bbe7,0x09d1612,0x12f9e78,0x11c1546,0x05eed21 }, + { 0x1d4dc0b,0x12baa00,0x0c1f855,0x0feacd7,0x01ae5f2,0x1112ead, + 0x1afaee0,0x0d7d30b,0x01189ec,0x19d690e,0x1936757,0x0319d99, + 0x1917da5,0x0b5b2da,0x128b4fb,0x0ee3990,0x1758ffa,0x13fcc40, + 0x0b1a69e,0x0d5c245,0x046d50d,0x18e3734,0x12dfcc2,0x1a17627, + 0x03a605b,0x003c601,0x175cfc9,0x1421fd9,0x10a9969,0x0c6672f, + 0x01a3145,0x17b1eb0,0x06bf615,0x12370e9,0x0a1e456,0x115e65d, + 0x0287d30,0x1ba7408,0x10953ab,0x00d4c4c,0x08c14ba } }, + /* 211 */ + { { 0x17ee201,0x1bc4ad8,0x09dc321,0x0311caf,0x005aa47,0x01122b6, + 0x19d8e5e,0x03a3387,0x0c9c3ba,0x1f37c60,0x027af82,0x09ff687, + 0x16fe85f,0x0673fdd,0x02f3338,0x0d8c8a7,0x12a6526,0x143b755, + 0x1e68e10,0x158d219,0x19815c9,0x18e6647,0x07d73ce,0x1ed0fbd, + 0x1be6a9c,0x00afd0b,0x120e0d7,0x19f821f,0x0ef2ebf,0x07ed8a8, + 0x19821ac,0x11094a5,0x197ecd9,0x08f5c4f,0x1e8ac33,0x1482dcd, + 0x1ecc03b,0x1e8acc9,0x0597b8a,0x0bbd576,0x0645c0a }, + { 0x0aa7e31,0x02102a8,0x1697653,0x185f0a3,0x0ec8df0,0x1937355, + 0x1a424f1,0x13532c8,0x02619bf,0x16dee1b,0x0fef55c,0x01c1c4a, + 0x061b426,0x06384f0,0x10967ee,0x1d8b72f,0x0bbcdda,0x0fd5fbe, + 0x12dc0fa,0x0bd163c,0x0fddb4d,0x17039a7,0x06c1b95,0x0abf14a, + 0x0a4f91f,0x046816a,0x08fd597,0x1f0c117,0x0d1d947,0x03e940b, + 0x0da08bd,0x0b9cf62,0x0c36156,0x0212106,0x17bcc74,0x0dc8ddc, + 0x083567f,0x132fb83,0x1b246ca,0x081a5f4,0x027e9ff } }, + /* 212 */ + { { 0x1e952e7,0x08c49eb,0x1c61d49,0x078e6b7,0x15b3058,0x1f02488, + 0x1664a5b,0x194e656,0x0806d2f,0x1a28c2c,0x017b649,0x0d40371, + 0x0c71ab7,0x16cfaaf,0x13a765d,0x175397b,0x12048f2,0x19ed305, + 0x04ac4ca,0x0f810cb,0x11d7697,0x0584c82,0x0db72a7,0x1115c4b, + 0x0ab23d1,0x19eece1,0x1f882ab,0x1e8d3e7,0x0d74d09,0x1be7ad5, + 0x0ef6f47,0x04553d6,0x15efe5c,0x008621e,0x1e884dc,0x0118bdb, + 0x1787026,0x1110bda,0x05ddab6,0x0ce7b59,0x04feee5 }, + { 0x1d3d780,0x0c6a95a,0x1d10c38,0x060e2cc,0x0dadb5d,0x1a10ab2, + 0x0e1b969,0x10c641a,0x08d6bbb,0x0c61487,0x18f7457,0x06465a4, + 0x16981a4,0x0c4c231,0x1439f2a,0x1596267,0x04da519,0x1a89c3c, + 0x177207f,0x1c7f57b,0x043a832,0x0a18ccd,0x1f09e16,0x0e862c7, + 0x0abcf32,0x1d3ada6,0x15d3e53,0x1f40217,0x14a6279,0x1a1eab4, + 0x0930a29,0x196caf4,0x1d2a888,0x112f560,0x140fa1a,0x1efdde4, + 0x04c561f,0x08d2e98,0x1783bb4,0x1cf393d,0x04fe818 } }, + /* 213 */ + { { 0x1c1c7ff,0x0964ebf,0x0b44009,0x1b3f513,0x09bd419,0x1274e65, + 0x0492901,0x1999274,0x043942e,0x0265e5c,0x05a56ce,0x03fb0e9, + 0x1f004c2,0x0108b2d,0x120767d,0x02204d3,0x028dde0,0x0f1192b, + 0x0a6c013,0x06e8aeb,0x1c21ec9,0x1ffb6e7,0x1eccd1a,0x06e58fb, + 0x1a64b4d,0x0715626,0x0fc8125,0x1d96f5a,0x07c150c,0x00daf43, + 0x16158b1,0x1856e47,0x19395ce,0x0991894,0x1f15fb9,0x0f9235b, + 0x110b659,0x1788b0f,0x0fff381,0x0536e9a,0x0819155 }, + { 0x0d9d4ee,0x09218b7,0x1c063b0,0x08d135f,0x1dffa15,0x04d1fa1, + 0x0d27caa,0x1649574,0x0d467ef,0x0d8f471,0x040b88b,0x06a8072, + 0x0b18dea,0x1297841,0x0aae14f,0x1ba8e84,0x0c1ed36,0x1389851, + 0x0a5747b,0x01d0da0,0x1ad3ca6,0x043e3fa,0x19ab1a0,0x10c8cb1, + 0x1cecfde,0x13287c1,0x0518744,0x05ccd84,0x1850997,0x00a85e9, + 0x027fbbd,0x14cc645,0x1183f3a,0x0e3ca87,0x12f9e4b,0x044ea8a, + 0x1136770,0x02608d8,0x1bbcc9d,0x18fd1d4,0x07d06bc } }, + /* 214 */ + { { 0x090212f,0x02ca138,0x011224a,0x18aa43d,0x091b7d4,0x16ddc93, + 0x0108af8,0x1009807,0x1bd81f8,0x0bb90f6,0x06f0d8c,0x17dd591, + 0x0dc136c,0x1dc7802,0x1c6d82d,0x115709e,0x0d04e21,0x0934899, + 0x1b32053,0x0492ddc,0x1c15b0e,0x0bbafd6,0x02cb38c,0x1a4478a, + 0x1c08466,0x1c5c171,0x193184b,0x0e43954,0x1653559,0x08f5d25, + 0x145669d,0x18fa7b3,0x033aad5,0x0a1231a,0x074ba03,0x143cc37, + 0x1c673ca,0x0fb2aff,0x12e4852,0x133a1f3,0x048b52b }, + { 0x1dc05be,0x0a9ccf7,0x17a68e4,0x1027c12,0x1e70db1,0x0d9fed6, + 0x18ba737,0x0a288f0,0x01a0094,0x15818b1,0x083a8e8,0x1018472, + 0x0b4b279,0x111dc7f,0x14e53c6,0x02da958,0x0563e56,0x10b1fb9, + 0x1c50866,0x1ff27f6,0x0474aa0,0x0949eb1,0x149be5b,0x19fc4ed, + 0x12ea87d,0x08aee90,0x1d1c0e3,0x164f7e5,0x18168ea,0x0192fa0, + 0x06b9632,0x1665531,0x1704222,0x0f89df1,0x0e42ff2,0x1b46d28, + 0x0d0684a,0x1713030,0x1dbb3c5,0x10f3b18,0x017c0de } }, + /* 215 */ + { { 0x0c01958,0x0fa29ee,0x0e4ef29,0x0839d10,0x1d94595,0x0fadb6b, + 0x1428558,0x178bcc6,0x07e2d36,0x08e1e43,0x10e9b0a,0x1b094b5, + 0x0df6c7e,0x0cc0036,0x04f102f,0x1d876f2,0x0875671,0x0fbc5d8, + 0x10fa26a,0x051edd6,0x01ed1c9,0x19d70f5,0x1f7ca37,0x049656b, + 0x1a5b1b9,0x102b15d,0x146845b,0x123a4e0,0x1ed3e34,0x015b8b3, + 0x11823b0,0x0b78160,0x091cf7b,0x0bfacf1,0x05a6317,0x0e61ca0, + 0x15c799b,0x1e1a86f,0x1875c31,0x1c4158d,0x06862b9 }, + { 0x1fa1f64,0x17a73cf,0x0d255b1,0x1543c48,0x1ed6a91,0x1ba9197, + 0x1b83336,0x00fd341,0x10322d6,0x1e4859b,0x1fbe1ef,0x15a48c5, + 0x1429480,0x015fe79,0x08525a7,0x1c71ff8,0x1e0a539,0x0372908, + 0x0a94527,0x13d84c2,0x15322a5,0x096b835,0x0657f88,0x1390852, + 0x1b108e9,0x0417bbf,0x0d77201,0x099d5d4,0x12d2987,0x0185dec, + 0x1ba9698,0x155d42b,0x142dca5,0x1884e56,0x0f1d261,0x13ad587, + 0x090af64,0x070e201,0x179b319,0x05aa3f1,0x05093fa } }, + /* 216 */ + { { 0x02d553b,0x1994026,0x10a7133,0x04772cd,0x1c1abe2,0x0b48a56, + 0x152708a,0x192aad4,0x1999976,0x064fc5a,0x1a0fcf6,0x0f7aeed, + 0x17c22c5,0x1e42f62,0x0a50aad,0x0c3ea9e,0x1e56e2c,0x0779a03, + 0x084f6d2,0x0bd195e,0x18c7f00,0x1ef9934,0x11c3214,0x1814a96, + 0x088d7ca,0x00f737a,0x1582dd4,0x0d7ad7d,0x0a4bd9b,0x188338a, + 0x053c040,0x0dc1311,0x085bc3b,0x0950029,0x106bd7e,0x15d80ce, + 0x0f7ef24,0x18b2137,0x090e0cb,0x09ad8ef,0x012f9c4 }, + { 0x1313a1c,0x0f4b241,0x0cdc654,0x14678b1,0x18edd3d,0x1620224, + 0x0fd4b1e,0x1d09db7,0x10dcb5e,0x136537b,0x108be21,0x11eadba, + 0x0eec0ae,0x0330f61,0x1def150,0x0a47820,0x13ad422,0x1369cc8, + 0x039f2cf,0x0bc3d0b,0x1b45d10,0x1fe4bcd,0x11f24e5,0x12f6b24, + 0x1d4a909,0x1f39910,0x0fa254b,0x1dec514,0x1462410,0x0c13a74, + 0x1034235,0x0b2f01e,0x0cbed0f,0x0887632,0x089c238,0x0627af8, + 0x1679b1a,0x036c333,0x0746346,0x09c4d5c,0x002f75e } }, + /* 217 */ + { { 0x1f307d7,0x1bf5fa3,0x11dc6d8,0x15a0282,0x0b644a6,0x02d4063, + 0x0f594b8,0x0630546,0x1fed07b,0x078d079,0x1b965f2,0x0ff26d2, + 0x1ec09ee,0x03ffe00,0x0a9fb0f,0x0e7739b,0x0fef8f3,0x0aa4fc4, + 0x0eee262,0x1a32c38,0x07b7c88,0x14efe55,0x164a93f,0x1c95641, + 0x19ee23a,0x0d2897f,0x07d7b2c,0x0b5d4c8,0x0fb47df,0x11bff19, + 0x1039da4,0x04ba10b,0x0a5c420,0x1aad14b,0x15609b1,0x07b9224, + 0x1bce972,0x05cc2fc,0x0650560,0x0ccc72c,0x072b1b5 }, + { 0x10e5558,0x045043c,0x1e0275c,0x020d135,0x1853604,0x189dafc, + 0x1ee2908,0x035d0bc,0x055a49d,0x15d0949,0x1c6c2f9,0x0961586, + 0x195e76c,0x09c7370,0x1413ce6,0x13442b0,0x02260ae,0x146ea0a, + 0x1a12173,0x009d372,0x1e43d8b,0x12c43f7,0x1e5312e,0x038bce7, + 0x08e67f1,0x0e20893,0x033dae6,0x04c47c5,0x0a96629,0x15543d0, + 0x14fcb42,0x099405d,0x066772a,0x1daa8d9,0x1938b58,0x0ad1dd1, + 0x0e78b5b,0x15d94c9,0x096b737,0x02dc2e4,0x05df192 } }, + /* 218 */ + { { 0x1f2e7e3,0x13f0f46,0x1f78800,0x11b1b40,0x1183cc6,0x05734a5, + 0x0e9a52d,0x1119c6b,0x13ca62e,0x0b6cbef,0x1fb4b22,0x0276a5d, + 0x0f3de47,0x135e842,0x01b1038,0x12477a0,0x1bbfc81,0x00f4db8, + 0x0ab31ac,0x038f6c3,0x0840999,0x1247b2b,0x194324d,0x1e8ea48, + 0x161d187,0x05109c2,0x06fff4f,0x021e562,0x1914186,0x0fd7fd0, + 0x0265a45,0x12abca6,0x11236de,0x196bcc7,0x1baa861,0x16c2797, + 0x06a2a48,0x1da2753,0x070c9fd,0x185c151,0x0452265 }, + { 0x1430010,0x0f63c92,0x03012b5,0x1fd7a12,0x0ac786f,0x14e9fae, + 0x1d3fc82,0x0bf4bf3,0x0a3edc6,0x05fa089,0x0fac47f,0x073819e, + 0x0088248,0x0552db8,0x175b53a,0x1157171,0x1fdb756,0x171138e, + 0x1d11583,0x1d86e76,0x1296e43,0x130e7ba,0x1e3abe4,0x152db36, + 0x1ae0e3f,0x1ea8c04,0x1770977,0x16625a5,0x0b77110,0x1c5a35d, + 0x191ae3d,0x16bd9e3,0x09efc8d,0x1f65503,0x0eb9827,0x03832a5, + 0x1f4dbde,0x118176a,0x015550f,0x1f23c0f,0x014b02b } }, + /* 219 */ + { { 0x07e5b57,0x0e3b45c,0x155cb1c,0x0fea634,0x0bcc78f,0x0cbee40, + 0x0fe2fdd,0x0be9ff2,0x1139e17,0x1470136,0x1329b2c,0x0e4f972, + 0x1c6b83b,0x003cfbf,0x0bf8ec8,0x1a2e05d,0x0decf3b,0x015652a, + 0x0bc371b,0x082678d,0x035e17c,0x12e67af,0x0fa8799,0x0aa0b8d, + 0x11a4834,0x1c4d334,0x0398402,0x0c6757a,0x1d03882,0x138360b, + 0x03259b1,0x03419f2,0x0efffbe,0x0eb263d,0x0f9f42b,0x0c9b08f, + 0x0ea2aa4,0x0de6fdd,0x1429752,0x0e8598f,0x085e07e }, + { 0x1c25bca,0x1705305,0x13b08ea,0x03c89ec,0x0e8e55f,0x03dbb9b, + 0x05b62d8,0x013c3cd,0x0d30059,0x14853a3,0x112642a,0x199a597, + 0x1d072b1,0x034717a,0x03f9b1b,0x11d921a,0x1f053e2,0x0c90762, + 0x0010330,0x043f69e,0x02c779b,0x09fe625,0x09cdd6f,0x1758fbb, + 0x1def9e1,0x069fafa,0x04d703e,0x1862baf,0x0cd318d,0x00b8165, + 0x071c45f,0x1d24dee,0x12823c4,0x179cd37,0x02efb40,0x0671b6b, + 0x1db6932,0x1a4918b,0x1d0c396,0x13f1a93,0x0096403 } }, + /* 220 */ + { { 0x0999eba,0x1a78b2b,0x0c1485d,0x0f63bcc,0x1d8ee28,0x0593349, + 0x1dc9b78,0x143b035,0x13f8942,0x1a2349c,0x0f84f0d,0x0c2bd40, + 0x0fbcf6b,0x0a7139e,0x03030d6,0x0b8ada6,0x056c672,0x127e99d, + 0x02fa5e8,0x0a695b5,0x0251a57,0x133e115,0x1e6490a,0x018b892, + 0x1bdb59d,0x1b42728,0x131a909,0x0f9aed9,0x06bf59d,0x0bd66a1, + 0x0ca4502,0x0cdd37d,0x1404a2c,0x171f4ac,0x1a61725,0x008e71f, + 0x0ad666d,0x1d9f075,0x1795af2,0x1a4c778,0x0626b0f }, + { 0x1a1ec42,0x0bedd70,0x11411c8,0x1756b59,0x0a6ae7d,0x0998e8d, + 0x0ac7a19,0x0df6fc3,0x03d3012,0x0229838,0x186146e,0x13c1bdc, + 0x0428064,0x15344aa,0x01bd28f,0x1ec6510,0x1adcb56,0x1a5df21, + 0x12bfe53,0x1737b57,0x17be036,0x12de831,0x0365079,0x0de7576, + 0x19d4468,0x1eb410b,0x12ab5ab,0x090d225,0x1e15341,0x048f7fb, + 0x05a68ee,0x1d70dfb,0x0c426ce,0x09461c4,0x0a0445e,0x016adcd, + 0x16399e0,0x1f389ac,0x1ab064c,0x1b342f6,0x009bbdd } }, + /* 221 */ + { { 0x0fd3673,0x1ce0ef2,0x181dd78,0x034cb91,0x1880d9d,0x04e3ff7, + 0x10771ca,0x0008e4b,0x03529d2,0x1b39af7,0x11ebcd6,0x05da78e, + 0x15c1f8f,0x08977ef,0x1ce663e,0x13872b9,0x0184985,0x0f6b913, + 0x19a5e57,0x12745e1,0x12a7237,0x0b4358e,0x029aae3,0x15105c9, + 0x015de22,0x0bf0064,0x13e76e3,0x1cefadf,0x067547b,0x1d99011, + 0x170221b,0x093821d,0x02687d4,0x1f6a65b,0x185df20,0x153e387, + 0x1af366e,0x0aebf82,0x0b4939b,0x171a3df,0x02eaa01 }, + { 0x1357c74,0x1fdb80f,0x1e51791,0x1553c76,0x13085c4,0x02d482c, + 0x01ccdba,0x1929e13,0x1be0244,0x09c047f,0x159837d,0x1f27476, + 0x1691ddd,0x19dcaf6,0x1d8ddef,0x041a916,0x1b7bb39,0x1c8dc88, + 0x1a84f3c,0x1e117f0,0x0e587cc,0x0bf500c,0x14fb63e,0x18aa328, + 0x0434378,0x0d358f5,0x07834b5,0x1cd5bbd,0x16259a8,0x1247cdc, + 0x177f0ac,0x1dde2fb,0x0ebceae,0x1ce42cb,0x110d55f,0x11ed296, + 0x07d5bba,0x068a878,0x061ad23,0x1d36983,0x002d31d } }, + /* 222 */ + { { 0x079499d,0x1cf0f6f,0x0ab69ae,0x11fa1f8,0x16ca8ff,0x1ec9ab7, + 0x1e3a069,0x04f7d81,0x1e8f063,0x01e8e4f,0x002faef,0x042e766, + 0x1b805c7,0x009e0c0,0x1082821,0x13a0200,0x07ef0ca,0x14f4d0b, + 0x0bbb775,0x19213a3,0x0a72076,0x1fc71d4,0x1928665,0x0f6853c, + 0x1f7a7a7,0x1f49e73,0x1172534,0x1581f7e,0x148407a,0x0a53f36, + 0x19fcdda,0x1523243,0x16679e2,0x0ddeb7a,0x03cfb87,0x13e47fc, + 0x0bf9fa9,0x08bab36,0x15d971e,0x1e5c1e9,0x0965860 }, + { 0x1a5f79c,0x03815bf,0x09b79cd,0x0cb5e5a,0x130bd42,0x19f0674, + 0x02e61b1,0x05a8b7b,0x14ee44a,0x0df3df6,0x122869f,0x00492ad, + 0x0ec129e,0x1be6fc0,0x17016b1,0x14b36df,0x02b589c,0x1b8535d, + 0x066096b,0x1080433,0x10b6fc4,0x0a3d11f,0x074a12d,0x141515e, + 0x010a428,0x16c58ed,0x04acabd,0x03d6366,0x135ee3b,0x021d19c, + 0x1b3c145,0x11dff4d,0x007eb26,0x132a63d,0x021b598,0x182ddc8, + 0x0549ee4,0x1de280a,0x02949e9,0x0643f53,0x0650810 } }, + /* 223 */ + { { 0x07ed9b2,0x072305b,0x0f4927c,0x0186db2,0x0cda0fd,0x03af0e0, + 0x18fa623,0x19376b2,0x1614bc0,0x0bddf49,0x1a1815d,0x100334e, + 0x049a9b8,0x0476e2a,0x0df8abd,0x0b30b51,0x19eb51a,0x04f3bf6, + 0x0efc093,0x04a4e9d,0x0636dd0,0x040aa2e,0x1662d8a,0x001b740, + 0x1aed048,0x11d1cde,0x06078a8,0x1f84027,0x0cb4f27,0x1eae2a8, + 0x11f719b,0x16a40d1,0x127032f,0x0fd0ad6,0x12ba05a,0x0593417, + 0x1a7ca8a,0x1037909,0x194bd81,0x08d30c4,0x0982950 }, + { 0x011c128,0x1a30017,0x09f8f8d,0x1a1cdb9,0x00dfae5,0x0a91324, + 0x05b8b65,0x087c880,0x0880b71,0x12fc479,0x0e2073d,0x11a8a4d, + 0x1eca3d2,0x0fdc357,0x1167747,0x1f2b1f3,0x0c24c74,0x1aa4430, + 0x12da7d3,0x1d48793,0x0cecd06,0x17399a7,0x14d0f26,0x0652e26, + 0x0ccd635,0x0062e61,0x0d7ce9b,0x12bfe80,0x12653ba,0x10e659b, + 0x0f4b806,0x144a0a4,0x1510fdf,0x13f5918,0x038a988,0x01ddca7, + 0x0a23cd1,0x0fe4506,0x1d52fab,0x0367cf1,0x04b7e6e } }, + /* 224 */ + { { 0x15f928b,0x083b7ed,0x13b1e72,0x0d6e68f,0x06250bb,0x007620f, + 0x1de62b0,0x18ea96c,0x09d9619,0x006905d,0x10d0fe4,0x01a0b3c, + 0x17ed42c,0x028c9ae,0x1ce7a15,0x0039c7b,0x18264f7,0x0131c88, + 0x07e1eab,0x1e4aa9c,0x1aaace8,0x04b2fc8,0x1f7759e,0x048a73f, + 0x1163fa3,0x0cacb66,0x112eb3a,0x1902be5,0x0f9ea55,0x061554a, + 0x1575e32,0x1de49c8,0x0b2aff4,0x0e1353d,0x1024737,0x05e1dac, + 0x00ca282,0x0521058,0x1d96255,0x18ba652,0x00611c4 }, + { 0x1e81829,0x1000e54,0x0b33c64,0x0011450,0x1ed3332,0x0ef6cde, + 0x1f7863e,0x00617fa,0x1b78890,0x1c9d606,0x1e97759,0x123a6ae, + 0x0bbb00d,0x00169e1,0x1e88e9e,0x12029c2,0x08cfb54,0x1ffcafc, + 0x1c6db81,0x037e978,0x0c8b7cd,0x1011ac4,0x0b8ec92,0x02240ec, + 0x135b8a4,0x0984da9,0x1b1015b,0x090380b,0x16a1b52,0x0086748, + 0x1d1571d,0x10a02f3,0x1e03271,0x089045d,0x05decf3,0x002bcd8, + 0x10cbfe5,0x0d12604,0x0159942,0x0523821,0x0820795 } }, + /* 225 */ + { { 0x07d353e,0x09e7f8e,0x18ed74b,0x1afbc19,0x15e7ecc,0x143b1ae, + 0x01d7db2,0x07d6962,0x025f9ad,0x1420270,0x12d6bb6,0x1d1240b, + 0x016b963,0x04f910d,0x17b8360,0x159493c,0x1d9ea41,0x06b2642, + 0x1110a8d,0x0d89d26,0x15a46a4,0x1f1e7b2,0x0b1bfe5,0x082faf9, + 0x05c1ee5,0x0263b2b,0x07bafe7,0x1020135,0x1a63886,0x0e9cc46, + 0x11a56d8,0x1ed68e5,0x002b46a,0x188b8b2,0x05942df,0x063fbca, + 0x1e0c05e,0x1c7939d,0x1129e53,0x06d5106,0x07487b0 }, + { 0x03e2370,0x072bace,0x1c66a18,0x07f0090,0x19d5819,0x117cd50, + 0x0fcf29b,0x136741b,0x1614471,0x163f4ac,0x1fb086d,0x18e9bdf, + 0x1fa9049,0x1fa8675,0x08192c8,0x1bc2b17,0x0c049a1,0x1589411, + 0x07549fc,0x096fb36,0x0430b65,0x0e87fe8,0x111c216,0x00a88d7, + 0x14a674f,0x0ca9be3,0x0e8eb76,0x0aa64a3,0x1533b5e,0x0b65f19, + 0x13928fb,0x04fc833,0x12f44d0,0x0dcbc97,0x1a0a974,0x1e5b09d, + 0x1b6fa69,0x1b5891e,0x0ef7731,0x18a43f4,0x0834f85 } }, + /* 226 */ + { { 0x0e9b31a,0x1a3e096,0x0edcca4,0x15fc7f6,0x1d88522,0x1fc87e8, + 0x1ed354b,0x03a979d,0x02b1a08,0x1d8b9c3,0x047c214,0x0374548, + 0x1a538c1,0x0a0db01,0x056e4f0,0x1ae82f1,0x1aab10b,0x114c9dc, + 0x0644a61,0x17a08c1,0x0ba5ccb,0x1877505,0x19a7ebe,0x0cc312e, + 0x0462235,0x12a6a42,0x10d9ffe,0x14c7713,0x1478da4,0x0e8e8e1, + 0x1df2eb5,0x154c069,0x1339227,0x189c8e2,0x017f986,0x0a1cdae, + 0x174ff51,0x0a5b307,0x0d53374,0x014a665,0x0639d8b }, + { 0x02217cd,0x118b10b,0x039be90,0x1502385,0x0e0e4a2,0x1b36e01, + 0x1386085,0x1ded1b3,0x1046a06,0x0931b9c,0x0484054,0x0463bbd, + 0x1344eea,0x08a14c6,0x01f23c8,0x0afd20c,0x0ba63d9,0x093f939, + 0x17a32b8,0x1d01994,0x063fe7c,0x11127bd,0x1605baf,0x0ce7c68, + 0x0e5a789,0x1ea26f6,0x094daea,0x06ead44,0x1f77af1,0x10d771d, + 0x0f19135,0x0579f31,0x0b2bf6e,0x14b1630,0x07cca7e,0x067616b, + 0x0bb5002,0x1b4d0d5,0x100b2c1,0x06c18ea,0x0409031 } }, + /* 227 */ + { { 0x070433f,0x1439d0b,0x17f2134,0x0c4a927,0x09394df,0x1e7c4f6, + 0x0866a03,0x02dd60b,0x0db2976,0x1cf2188,0x18c11b8,0x1b93b3c, + 0x1e50742,0x0ef4e54,0x06b6320,0x03a1be6,0x194fb7b,0x0c3555f, + 0x0cf20b4,0x1b44f43,0x0d8436c,0x1a1cb81,0x1ec68bb,0x0102533, + 0x1fddc46,0x11c1405,0x1748e58,0x0965691,0x1c9353e,0x0179bd9, + 0x1a4b6cb,0x025f714,0x1b5b317,0x0023a6a,0x08ec206,0x11f370f, + 0x1e95257,0x0c84c30,0x0af2361,0x1dbe6f4,0x080668e }, + { 0x19a0249,0x0e69ad9,0x1abb8bb,0x0965f15,0x0f230cd,0x11ef82d, + 0x05791c8,0x1e852b6,0x0e0e937,0x1b34c15,0x12458ae,0x16e5197, + 0x01019d2,0x07a4ee5,0x144aba7,0x00f68b8,0x1a7630f,0x088da48, + 0x00e1d3a,0x09e6994,0x143348d,0x132265b,0x107f43a,0x0b66187, + 0x19ae1f9,0x05609fb,0x17b62d8,0x006c5a9,0x0ad81c4,0x0a7fb0f, + 0x0a27a0c,0x093187a,0x1600dd4,0x10b8176,0x1067094,0x06bf963, + 0x1a9c1f3,0x1194fe1,0x1b3a564,0x09037bc,0x0046775 } }, + /* 228 */ + { { 0x1233c96,0x0f2b71c,0x1abfb8f,0x1900e6f,0x068c409,0x0d5e344, + 0x046f480,0x00b595c,0x12b4862,0x196754d,0x0415b03,0x0fc2de3, + 0x01e3238,0x12ee152,0x1d4d96a,0x17d0dd4,0x0cc12b4,0x0bb614d, + 0x158ca53,0x1f956f1,0x1f24a01,0x058655c,0x0076fa2,0x02980a9, + 0x06e5bf4,0x1d53b32,0x0f2e5ad,0x1c22312,0x04e097f,0x1ad8bb3, + 0x0a6d927,0x0a7f9eb,0x196422e,0x1fb1a50,0x06f42df,0x0ab2f19, + 0x1c22989,0x1f59c71,0x1115ad7,0x1f61067,0x0038a49 }, + { 0x1e93257,0x1c0c609,0x106cd78,0x1b4c24e,0x14cebc9,0x1560358, + 0x04925f2,0x02c9edd,0x13daa11,0x113c719,0x080d2a0,0x0cbc9bc, + 0x10e7cc5,0x050dd31,0x1f7257c,0x0df7b76,0x1236695,0x140eecf, + 0x0c4cb75,0x1cc6337,0x1337c63,0x117e120,0x1b88ac0,0x117d638, + 0x081937e,0x05611c2,0x176324e,0x0763329,0x1b56448,0x1d65535, + 0x01ed533,0x00df230,0x07cd44e,0x06cf98d,0x06eea3e,0x0c3ba87, + 0x1f74a8e,0x06153c3,0x1598198,0x0442436,0x04bb76e } }, + /* 229 */ + { { 0x0354817,0x08f4573,0x10e1e85,0x15e0716,0x13d494e,0x0ac4c31, + 0x11a2216,0x024990d,0x11dcbac,0x10a9c13,0x16b419c,0x1f1981d, + 0x16f487a,0x128072e,0x0cc147f,0x0feab5a,0x11bd6e4,0x085388d, + 0x11d1ab5,0x0e134f1,0x135ea68,0x1132017,0x09fc5c9,0x0618260, + 0x08efafb,0x04be368,0x0701b1d,0x1de3808,0x03e2da9,0x07676e6, + 0x1cf431d,0x0125c20,0x0c5f96e,0x095ba18,0x0f3caa8,0x041e272, + 0x0107eb0,0x0c200b1,0x1e62c91,0x0bef6ed,0x08843d2 }, + { 0x1b2a83e,0x080ee76,0x1c91385,0x005771a,0x1cfe8fb,0x12efb15, + 0x0196764,0x1861204,0x142ab6f,0x038aee7,0x0277f4f,0x00ab41e, + 0x0a73c05,0x11ac857,0x19d1763,0x0e93c24,0x0d876ff,0x1a9c17a, + 0x0483198,0x13fddf5,0x11cafc6,0x08cfeb8,0x1785808,0x0eb89ab, + 0x1c3bd90,0x1f9210c,0x04f7b5a,0x100197a,0x03a1163,0x1075b13, + 0x0de31fa,0x0fa4c98,0x1bd7958,0x0e4c61a,0x1915c56,0x0aadc45, + 0x1a7373b,0x1f9516f,0x12525c6,0x073126b,0x00503f9 } }, + /* 230 */ + { { 0x1dad4f6,0x0ee3338,0x086d96b,0x120497d,0x038e488,0x02e9ee9, + 0x1238bd8,0x113f6ed,0x0b0d96b,0x1eafaef,0x06cb2c4,0x146acc0, + 0x14e0b5b,0x01f1e92,0x1f52476,0x11d4fc6,0x023240c,0x1744302, + 0x047266e,0x0305e7d,0x1919374,0x1cd43d6,0x09b0b2b,0x0e9e52a, + 0x1040af5,0x051a589,0x0651000,0x17379da,0x1f42e75,0x0bdf036, + 0x0753331,0x097a211,0x0e8ec50,0x1da8011,0x1deb776,0x1618a62, + 0x1ecfead,0x0698e94,0x1a3e5a4,0x1fc2ecc,0x0735778 }, + { 0x03c1137,0x1771f42,0x0f343e1,0x147e16e,0x1c1c42f,0x19071d1, + 0x19e762a,0x15c1cea,0x016242f,0x1caf8fa,0x024b91b,0x0238736, + 0x007b88e,0x0611b56,0x0a500f9,0x005cc2c,0x1412dac,0x133082f, + 0x18b818c,0x18514f0,0x1c8d74d,0x1979d91,0x08463fe,0x08bff7e, + 0x0417c07,0x08f08c1,0x113015c,0x136ab40,0x1be4de4,0x0dba677, + 0x01cb199,0x12f7ee2,0x0c4c01d,0x1833b0e,0x1b6b153,0x1165940, + 0x1450d0f,0x0cced53,0x00a87f1,0x14c3463,0x052e637 } }, + /* 231 */ + { { 0x1ebc6db,0x18078b5,0x1649205,0x17f2a07,0x0a6b45d,0x0a9c8ca, + 0x134f174,0x1798e2b,0x1e5ad2a,0x0150e02,0x0d19be5,0x086756f, + 0x0b36a82,0x1d09c8c,0x104efb6,0x1cd9d74,0x02490f4,0x134c52b, + 0x0fc7cf2,0x041b4de,0x1ab3bb7,0x0eb1a38,0x0845b50,0x07a6c12, + 0x1222730,0x14f7006,0x0118ee9,0x1fa9980,0x045fd17,0x0f26b14, + 0x11eb182,0x1015b93,0x1603b2c,0x17de531,0x126917e,0x177e2df, + 0x04bc94a,0x003fbfe,0x05a6104,0x09f4e96,0x07c916b }, + { 0x0bac2d4,0x137c8bc,0x01d7040,0x104c035,0x0a2e809,0x19eb204, + 0x09db801,0x1115a5e,0x0fcc1fb,0x01b0862,0x0ca47d1,0x104594d, + 0x1c5727b,0x0476307,0x1154cb2,0x1a9160c,0x099ed9a,0x1a8f244, + 0x150fc40,0x16916be,0x0eeb841,0x1f6ac8e,0x09b32c6,0x19eb517, + 0x0df0f9d,0x0da7e25,0x02cd1f7,0x14f9404,0x04c5213,0x066165a, + 0x112a86b,0x00a4f81,0x13b6828,0x1e7a83b,0x1041c08,0x0d546e9, + 0x0b74c92,0x1e88003,0x141f1cc,0x0deef51,0x01ff391 } }, + /* 232 */ + { { 0x197939d,0x0c7f27c,0x0ecea88,0x16f22b0,0x1d4dfbb,0x1bab059, + 0x0d76a1f,0x131674f,0x15da92c,0x0e01400,0x19bd2aa,0x155a8cc, + 0x17e1eb4,0x0a674ee,0x0c5e944,0x060ec5d,0x0a4ef8f,0x17a3533, + 0x043951b,0x168b8d0,0x04dd900,0x0c25d78,0x1debc89,0x109a85f, + 0x1c8725c,0x1ef1e60,0x1639320,0x0127e44,0x0d88b23,0x0f208b8, + 0x1118beb,0x1580edc,0x19612e4,0x08a0df0,0x0d18cb7,0x15e91ae, + 0x125e34d,0x18fbacc,0x0432706,0x0ac0e57,0x019ed1a }, + { 0x0735473,0x1fe6f36,0x10fa73d,0x0ec0077,0x0ab88e6,0x0ccddc5, + 0x1f2f3ec,0x17a2430,0x19acccc,0x1b98220,0x195166e,0x1e7961e, + 0x02214af,0x17c9314,0x1b2068d,0x04170d5,0x1329f9d,0x0554165, + 0x1dcf324,0x07f21ea,0x17e182f,0x15fb112,0x12bd839,0x08ec5be, + 0x144bfbd,0x1a9f8c5,0x076e5c1,0x1291625,0x02c18e3,0x1074be1, + 0x0b71ba4,0x0af7d2f,0x13d6208,0x11bfc9c,0x00b11ad,0x0bd1ae7, + 0x11fed1d,0x112e65f,0x05667d9,0x1f2d0d0,0x06f31e0 } }, + /* 233 */ + { { 0x0b8f204,0x17f2ac1,0x152b116,0x0da6b16,0x0c0441b,0x0afaf6d, + 0x19efeb3,0x126e427,0x1139bcd,0x08a6385,0x0f2ec06,0x0b032db, + 0x01714b4,0x0f69ae9,0x0a5f4d4,0x03e41d2,0x0376a3e,0x0c7b204, + 0x1cf35c1,0x15153a5,0x1f6d150,0x00ee6ec,0x1ecdba0,0x1eadb05, + 0x0eb655c,0x110ad2a,0x124aa96,0x0c20a01,0x089f037,0x05711d8, + 0x1a34434,0x18856cd,0x11b2079,0x146a424,0x18f43bb,0x0a95e35, + 0x01556f4,0x1f26142,0x09f984d,0x010c7b1,0x0875e33 }, + { 0x16c0acc,0x07eee57,0x1023720,0x0d763cf,0x15ad1e6,0x02c2d6e, + 0x1eb860a,0x14db8e2,0x0275c7d,0x0e2a1a0,0x0e7856f,0x10a5a4d, + 0x10f4b4c,0x1502fd2,0x0287efd,0x19664be,0x047817b,0x0e37c0f, + 0x03fcb87,0x1a8650e,0x17fc2cb,0x0b33e3f,0x0289240,0x10b4d89, + 0x1acb7b5,0x02be822,0x11199b0,0x1d2e55a,0x17d63d2,0x03e7f36, + 0x1131d36,0x01c4e82,0x1067d87,0x0c2577b,0x15ea2c9,0x1765942, + 0x15f0fde,0x0e2dfdb,0x1802525,0x103e70d,0x05abb05 } }, + /* 234 */ + { { 0x0c97f57,0x11695f8,0x031e2f9,0x032c5e5,0x0fe0487,0x1a855d8, + 0x0919d1e,0x1db8a91,0x144fa09,0x1593701,0x16a5bbd,0x0dc7560, + 0x02fd44c,0x1873574,0x0c00cb1,0x1133bdb,0x02bd7e4,0x1145ea0, + 0x0df0470,0x05d2c73,0x171643f,0x0767489,0x03b0ff0,0x1fa1f18, + 0x18bc902,0x1d63b4d,0x09f2af0,0x1b39675,0x124cc99,0x0449034, + 0x053a22a,0x084c120,0x11461aa,0x13cf052,0x0a2e58b,0x018fe95, + 0x0b1b3e8,0x1810854,0x192f13b,0x10037fd,0x0705446 }, + { 0x01901c1,0x1eb8989,0x12abeac,0x0ffd5aa,0x090a262,0x045d11f, + 0x14a16f0,0x0fcc9ed,0x136ec22,0x0cc980a,0x0646ae3,0x15720d8, + 0x0c99a16,0x1b24e71,0x0c73d6f,0x075010d,0x15966be,0x02c9033, + 0x12e8b3c,0x06c4f39,0x1486188,0x03f7fa9,0x0b055ee,0x04475e4, + 0x098964b,0x12bdfd6,0x002ab9e,0x1a1fa9e,0x018a80c,0x1ca0319, + 0x13b6b76,0x1bf11e2,0x044bb79,0x16cfe9c,0x0f52dc7,0x0d8367c, + 0x1620503,0x11a509e,0x029adb1,0x19f70d0,0x06f56ae } }, + /* 235 */ + { { 0x1205c5d,0x0e401ec,0x04a6c07,0x1ace247,0x08955f7,0x0db2b2b, + 0x0fff676,0x1fc7bd7,0x0d3b1ac,0x0221caf,0x13bbfee,0x1642c12, + 0x0b04328,0x114c8ff,0x0c7fea0,0x1a0eacc,0x0e6190d,0x086ef33, + 0x015df01,0x0078abd,0x040775b,0x0fc8b91,0x1b24739,0x176747e, + 0x08a408e,0x1cb4d14,0x0816284,0x1a6edf1,0x0e06761,0x0a2bcd3, + 0x023ce96,0x0f6e3a5,0x03029c5,0x0186008,0x10a2d13,0x181087e, + 0x130e0b9,0x1357fc3,0x112b763,0x0229dac,0x07b6be8 }, + { 0x13aa54e,0x1c7251e,0x0268fb0,0x07b07aa,0x1023394,0x1caaf10, + 0x0988490,0x089f095,0x1f51d3d,0x088238b,0x0938dca,0x0858fd9, + 0x1e62d24,0x02fd2ae,0x16948f6,0x1436b18,0x0da851d,0x0637ae6, + 0x000051a,0x1795504,0x02e0044,0x14700b8,0x1dd4079,0x14159d9, + 0x19359e6,0x0597840,0x16b03bc,0x07bb4d5,0x164f013,0x16e47ec, + 0x1625ebb,0x0a61721,0x0dacd0e,0x09175a4,0x15bee10,0x1c98bf5, + 0x1700a1d,0x02760f6,0x151d08a,0x06bb794,0x086f9a8 } }, + /* 236 */ + { { 0x10cc69f,0x0c82aa2,0x063c387,0x1993dbf,0x10eb14b,0x1f5d00a, + 0x139dfb9,0x0a63772,0x1998f8e,0x1bd339b,0x1bbbc17,0x09c6362, + 0x1558838,0x0c2e2f0,0x04a1c8f,0x0a55577,0x145cbd9,0x07f28f1, + 0x189059d,0x01dc50f,0x02f0c5d,0x178800c,0x1f7051b,0x1eb7c59, + 0x19e92e7,0x09f07b9,0x1ed95af,0x0035675,0x08e2895,0x16ef28b, + 0x12ac554,0x171dc20,0x00dfe31,0x0223aca,0x180f10c,0x0685246, + 0x0460a91,0x03788a6,0x07e1a4c,0x15e076a,0x05bfa9f }, + { 0x07b258e,0x1fa9608,0x0770a88,0x17acc68,0x189e82b,0x1e7f8d4, + 0x13b6208,0x03ea947,0x0719b49,0x02dbbca,0x0f7ee3d,0x0430486, + 0x0e898c2,0x0249287,0x0776473,0x0ecaa1f,0x0ae4fa1,0x0a86151, + 0x10c9fd1,0x1439c85,0x1e41f7a,0x0b2c1d8,0x04e856b,0x17f5b3c, + 0x0d5a5a1,0x0e6cd50,0x02387ef,0x1639545,0x1f7f879,0x01db48a, + 0x07abe4a,0x10fd034,0x10e4e0c,0x0694b60,0x0958420,0x1009fb9, + 0x12755bd,0x064b0b0,0x1bb69ab,0x155051f,0x01b1266 } }, + /* 237 */ + { { 0x14ee49c,0x005003b,0x1f5d3af,0x0596c46,0x176f685,0x1c9c51b, + 0x112b177,0x17bf80a,0x0b6fbfb,0x19c4764,0x1cbabb0,0x179ae8b, + 0x1784ac8,0x18f6749,0x1159826,0x1f42753,0x0ac7de8,0x0b2b7db, + 0x14cae1c,0x1bdae94,0x1f095f8,0x05d5444,0x0ac350a,0x16f5d85, + 0x07f2810,0x1a621d9,0x1bfbb2c,0x0c84dc3,0x09c2db2,0x0db5cf4, + 0x041110c,0x0724221,0x0c4bc5d,0x0082c55,0x0da13f6,0x1d24dee, + 0x071ef60,0x17d348a,0x1e88d14,0x1b6431a,0x033517f }, + { 0x13c4a36,0x19fa32c,0x07baa70,0x106d635,0x0c69d71,0x1bdf765, + 0x0307509,0x138ab44,0x07e4f17,0x1465127,0x162288f,0x06d3a8d, + 0x1857373,0x1983817,0x13ac731,0x1aae8e3,0x19735ee,0x1458c26, + 0x1c133b0,0x0a2f440,0x0a537f4,0x0c6b831,0x1fc4a74,0x1aefc38, + 0x0571bb1,0x05903d2,0x060d436,0x0e95861,0x1ab8ef7,0x08cfb0f, + 0x06c9eca,0x16bbb00,0x1c4cc13,0x02c8fd3,0x156c50d,0x07cfcc4, + 0x1a3592b,0x0c9bdc2,0x1d524d2,0x07a618e,0x031fac6 } }, + /* 238 */ + { { 0x0913fb6,0x0678d82,0x1accbba,0x002ed34,0x1e40135,0x1f30f83, + 0x0edc5e0,0x1fcf21d,0x1e27f2f,0x12883fc,0x1e26fc7,0x0cffdb5, + 0x0d124ba,0x12c6f34,0x0480387,0x157dc31,0x0a36df5,0x14b1399, + 0x12fad2a,0x186f9f5,0x1a7672c,0x0b749e2,0x0c317ea,0x0c67277, + 0x0317cde,0x0b62615,0x1e0c2cb,0x0fecbcc,0x05b96a9,0x1a820df, + 0x1b52bf0,0x0e619cc,0x1f40a60,0x06c2785,0x09e64d0,0x112d437, + 0x07626b0,0x10c12a0,0x12fd4fb,0x1b6f561,0x001db35 }, + { 0x00efee2,0x1de16d6,0x0d15b83,0x1bae3b7,0x0406ebc,0x1b4d5f4, + 0x178f866,0x045ce57,0x137e018,0x0e5bf30,0x162d312,0x0038228, + 0x03cbb8c,0x143e2eb,0x02d211d,0x0ceec84,0x1a1454c,0x00c23ef, + 0x060e746,0x1d223ba,0x1046bed,0x0493c6f,0x06e7727,0x03466d8, + 0x1d62b88,0x16e14a5,0x064f9de,0x1e12d0f,0x0e3ba77,0x0332a1e, + 0x1f1eb24,0x0eec9dd,0x08695fd,0x032e78a,0x1c2e6b1,0x03c1841, + 0x06e2cdb,0x1746945,0x0d0758d,0x119aeaa,0x07b6ba9 } }, + /* 239 */ + { { 0x1881ab4,0x0cf01e0,0x12232c7,0x0b662d1,0x19c25d5,0x11b2670, + 0x0f51ca0,0x049505a,0x0f161aa,0x0cca1c8,0x0ecb265,0x1801c3d, + 0x157838b,0x1ef63d3,0x1577f32,0x044151f,0x1c24ff7,0x026e901, + 0x1bfbfd2,0x02e7661,0x0b355ec,0x198b214,0x067c74a,0x0dd027f, + 0x1d9e505,0x0f8e035,0x0b02cc6,0x0522e57,0x023b159,0x11c27e9, + 0x1b5ab83,0x131a123,0x101059e,0x032475e,0x0392995,0x10d662d, + 0x1375e79,0x08a23f9,0x1142088,0x032e3d6,0x047e810 }, + { 0x08c290d,0x0ea2d5e,0x0ce9c11,0x0b021f6,0x033d135,0x1ddf97d, + 0x002491b,0x1b2575e,0x1385c7c,0x07f9f8d,0x066172b,0x01d9c2c, + 0x08c5b15,0x154443a,0x1b829fc,0x1b9918d,0x08e5e88,0x1cec446, + 0x12e1910,0x0e6be59,0x16f24dd,0x1b9e207,0x130784e,0x1fdad23, + 0x025fff3,0x0e3fe1d,0x1c95fb9,0x1968762,0x0db1354,0x07c9f99, + 0x14ea995,0x005bfe5,0x0f58d0a,0x131ca22,0x0622a32,0x0ef1c7e, + 0x13e8669,0x1236677,0x1a1ece5,0x005c1b9,0x0785b19 } }, + /* 240 */ + { { 0x12f9a20,0x111b0d4,0x103bf33,0x0f3ac8a,0x17bdca8,0x006be2d, + 0x06a1474,0x04da8e7,0x02e97c9,0x13d646e,0x09aa2c1,0x1ffcf1b, + 0x092aea3,0x11e28db,0x0a2fd51,0x02834d0,0x0797155,0x03b78e2, + 0x05df604,0x197dec7,0x0e7af4b,0x04aa0de,0x1d6f125,0x0e0834a, + 0x14066d1,0x157f00f,0x161dd57,0x0505ab7,0x07ae80d,0x03eeacf, + 0x1bdb884,0x0705566,0x056e166,0x0eb1a55,0x1bdae74,0x08cbdd1, + 0x0e4ed84,0x110b056,0x0b09e66,0x0cf6ee2,0x06557c3 }, + { 0x15b6e52,0x181346b,0x1a25586,0x00231a1,0x1081364,0x1758d75, + 0x0ccc1a8,0x1299fea,0x06d0908,0x1231113,0x1075213,0x044f6bf, + 0x0dbb351,0x0bd1831,0x197a81d,0x05b8b26,0x17bd66e,0x1a65651, + 0x0425621,0x1afa477,0x13bf220,0x09c6223,0x0703f4e,0x10fb49f, + 0x1370a67,0x05c56ff,0x13415fd,0x1e15d79,0x13f33ae,0x1a2608b, + 0x0d08179,0x124b44d,0x0d1f0a5,0x1ddfedc,0x1d25c8b,0x09526c9, + 0x0227d28,0x08d73bc,0x02ad322,0x00941c1,0x015c40d } }, + /* 241 */ + { { 0x00e18d1,0x18b4d15,0x1f0a6eb,0x0e98064,0x1971c01,0x0131674, + 0x0c8fdef,0x0f3b034,0x1818ff3,0x04cedc6,0x0f0cc08,0x0c7a99a, + 0x13663f6,0x008d02a,0x14c970c,0x148e1de,0x1dcf980,0x04e6b85, + 0x127b41c,0x08a5a23,0x0e13e64,0x1a5633b,0x0befd0f,0x10b854b, + 0x0c0a6ae,0x0624bdf,0x011c124,0x1f55caa,0x1e6ba92,0x1d43a48, + 0x0502ae5,0x155f532,0x055f537,0x132aba0,0x16ecd9c,0x1ff92b5, + 0x1119d6b,0x11a1dce,0x078dd91,0x1413a68,0x0788e94 }, + { 0x053461a,0x137f2ce,0x1bb414e,0x1c11c76,0x15ec897,0x146c9cb, + 0x14bcc1d,0x09f51eb,0x0cc213d,0x1eb5ffb,0x0051f26,0x16820b6, + 0x09590c7,0x1e3dc0b,0x08d8a2d,0x0f1d241,0x06e5bce,0x1e33504, + 0x17b0763,0x09a5049,0x0ce93dd,0x0260cee,0x0242b3d,0x086b4fd, + 0x0d875d8,0x0d93319,0x07a98e0,0x1202cf8,0x1cc1285,0x0bcbf86, + 0x18ec896,0x08df1a8,0x1a612b4,0x17d1cc8,0x15e3057,0x108430b, + 0x119f678,0x0af61b8,0x1aa4f7d,0x18cf01b,0x091b19c } }, + /* 242 */ + { { 0x15d8b80,0x1384ee5,0x183bafc,0x05f86ac,0x03b9618,0x0f7cb48, + 0x1664415,0x08570e7,0x1e47c43,0x0f525a6,0x1e219f4,0x0489aa9, + 0x0fcc4b9,0x1ec6bbf,0x0c68b2b,0x1eac727,0x0e7e8c1,0x1034692, + 0x065cc15,0x1f576c9,0x174f5f5,0x0802a11,0x00c9231,0x071d227, + 0x1e2b53f,0x05f61b6,0x0deeda0,0x1a0fd1d,0x1313b5e,0x09ebec7, + 0x04a5920,0x15fa5a7,0x1b6a069,0x0518d3d,0x1238212,0x0b80db0, + 0x04f0c32,0x13fd97f,0x10ebda1,0x0680ce6,0x03c2ba8 }, + { 0x13ad63b,0x16bbace,0x0c7ead8,0x0eb3c1d,0x1f9cab9,0x02f08b9, + 0x0a98ce2,0x13ce066,0x0e20b2f,0x11657e7,0x12a51fc,0x14fc93d, + 0x0db529b,0x11146c4,0x0550859,0x12ac249,0x1ec3923,0x0407511, + 0x10dc191,0x120fcfa,0x0e441b8,0x0aab1f2,0x12dfe91,0x14961f4, + 0x1829eb2,0x1c96654,0x1120181,0x014e414,0x0991ced,0x0d06123, + 0x1ae3337,0x0691a10,0x1a2325b,0x177099b,0x1427d82,0x1eacdda, + 0x147f253,0x1870488,0x0ef60f4,0x14b820e,0x01fa627 } }, + /* 243 */ + { { 0x0478fd4,0x1115121,0x0002844,0x02ce164,0x0cf4c6f,0x0ce36f5, + 0x0c13e0d,0x179ee37,0x17b93cd,0x0c71414,0x16d82d8,0x15c6461, + 0x0996e1b,0x0b2d9d9,0x1ff4ed2,0x0abbbe2,0x1c6bc70,0x1d2c31c, + 0x0e05f5f,0x1525da9,0x08a4c3e,0x13691d8,0x0420aca,0x02e021d, + 0x1228adc,0x0cbc238,0x1883a27,0x0a773c8,0x1f77c97,0x07cb81f, + 0x1973df9,0x0577cc1,0x03f8245,0x100beb6,0x12f2e03,0x173c865, + 0x00a45ed,0x052d66e,0x1d0f854,0x00a8f30,0x067b8bd }, + { 0x0797cf7,0x03cda7a,0x180b998,0x15a07fb,0x031c998,0x055778f, + 0x1d8e953,0x022b546,0x0f76497,0x06cd0ff,0x06c69d9,0x18e75e5, + 0x137ce0d,0x1db3654,0x186c20f,0x0d4f0cc,0x0fe32fb,0x0dfa6ba, + 0x1c02958,0x0dde13b,0x115925f,0x1fc18e8,0x0af10e0,0x0d7bc6e, + 0x0c10c53,0x12db6ae,0x1e20b31,0x0928bf3,0x1a99b8d,0x0789a28, + 0x09207d2,0x0d75823,0x00161cd,0x125050a,0x13b7c62,0x093b29a, + 0x0467a82,0x1b18b2d,0x0bb7d94,0x1534993,0x074297a } }, + /* 244 */ + { { 0x01124ba,0x1ac5271,0x0f4b125,0x1150fff,0x19bd819,0x131c544, + 0x13744f5,0x0ec8bf7,0x015f7bf,0x0322ffc,0x1b55fa5,0x06df89c, + 0x195fa67,0x09730ed,0x0b991d6,0x128943d,0x00ccbdf,0x03cabae, + 0x16cc75d,0x02608e4,0x1ae6a3d,0x112655a,0x1e2077c,0x0510fe4, + 0x1d2991a,0x02cc6df,0x0289ab1,0x07a0eb2,0x061d4a2,0x0c296c3, + 0x1dcb962,0x1140281,0x1b5c13b,0x1bc151b,0x0678fec,0x001f283, + 0x1bc14e9,0x15502c8,0x0ec49c8,0x175aab7,0x089aab7 }, + { 0x056bdc7,0x02d4b6b,0x14ee2cd,0x1fc2ed9,0x03bdc8a,0x0b2621a, + 0x062d8cb,0x083ad2a,0x179b82b,0x079b253,0x033e0bf,0x089dff6, + 0x1b907b3,0x0880943,0x14320f1,0x121dfe7,0x05934cd,0x074f935, + 0x1c20ad7,0x0b55e40,0x0165e5f,0x1af673e,0x13adcb1,0x130d9ac, + 0x10a81be,0x15574ac,0x1ffc54d,0x1dde931,0x063d5ef,0x0121d41, + 0x0ac1158,0x0a95d0e,0x00be14f,0x03b434a,0x13278c8,0x157dcf7, + 0x01bc4d7,0x0b513ee,0x0ad1b52,0x12eb281,0x0002dc2 } }, + /* 245 */ + { { 0x09d60c3,0x19c9bdb,0x1d57b94,0x05fd2e4,0x060be55,0x0392d31, + 0x0de3703,0x185623f,0x0cab2e7,0x0c1613f,0x0c8b2da,0x1bb3dc4, + 0x174bcee,0x0913827,0x0ac67b4,0x0c2cb2a,0x085854a,0x096fa61, + 0x0c64921,0x016b7ef,0x152aba4,0x08008cf,0x1f2f2a5,0x15bb0df, + 0x1d1cbe5,0x160ba33,0x0f6743c,0x17ea6df,0x14ebc99,0x171a5c6, + 0x05cf0a5,0x00b5026,0x095f8f4,0x1afbb02,0x0359ccc,0x0518b3d, + 0x0054212,0x09e9927,0x169cc2d,0x06a7877,0x04d5645 }, + { 0x05c0877,0x17c003f,0x1d91cc8,0x0c19534,0x081b43e,0x00938b2, + 0x13d2e8b,0x184463e,0x1ed3136,0x0acb42b,0x0cc3782,0x064471b, + 0x1cae826,0x0cc8475,0x0beb502,0x0463cca,0x014af0d,0x085c68c, + 0x072f0d2,0x018a961,0x1f8e268,0x19a5f9d,0x1f5158b,0x056b2bf, + 0x1090b09,0x01a14c2,0x117857f,0x0de7394,0x178168e,0x08c8de1, + 0x01dc05d,0x108b495,0x06944b3,0x0aa0d48,0x1d2a0a8,0x09598da, + 0x1155c8b,0x04dd59d,0x1b18ab7,0x19cee60,0x01f2f89 } }, + /* 246 */ + { { 0x0ffefdf,0x1f7a0cd,0x15ae094,0x0a99f24,0x05d7ece,0x0272418, + 0x00bcad1,0x03e6ee0,0x1cba547,0x0c4baaf,0x0f8056c,0x0797ab9, + 0x09c8848,0x1505c21,0x13df1a5,0x1ec3a4a,0x1d461f3,0x18c4285, + 0x0891c55,0x0421121,0x0b0d7ba,0x176c977,0x0d6aef0,0x0bbd912, + 0x0cabe96,0x0257dab,0x12f155a,0x1b446e4,0x1a74929,0x1cb7b53, + 0x11b62e8,0x05de974,0x0b90db7,0x0d93d7e,0x1f82642,0x1dba469, + 0x16f4366,0x19e0b23,0x0351ef7,0x0fe2fca,0x009c809 }, + { 0x0050c07,0x058a030,0x0df9a81,0x108751c,0x029e831,0x0af20fe, + 0x0a6caed,0x0759728,0x02ce60e,0x097f52d,0x160bd3b,0x1fe7b73, + 0x1adc7b1,0x143e9bf,0x1afb30d,0x0ea7291,0x032ecb0,0x13c8a9f, + 0x1c1d5a4,0x000a9ea,0x19ba6a6,0x064003a,0x0e1c734,0x1245be2, + 0x1386f30,0x1be0bd3,0x1a0cd5e,0x1d3f8b3,0x0151864,0x19d49ca, + 0x024749a,0x1a69b71,0x12a0222,0x06db8c8,0x13d167f,0x0ccce5f, + 0x04ff303,0x1f9346a,0x185b168,0x1a6d223,0x06f113e } }, + /* 247 */ + { { 0x036f1c9,0x0efac8c,0x01f54aa,0x0a84646,0x1a6519f,0x16942d7, + 0x11c0577,0x0eb080d,0x0af627f,0x10aa2e5,0x0105f42,0x03dd59c, + 0x03ae111,0x13089a2,0x0a2f7da,0x19797f6,0x0ab52db,0x06f4f78, + 0x004f996,0x183036f,0x1225e9d,0x0dcc893,0x02c76af,0x10298b2, + 0x198e322,0x13f2f82,0x1b64d3b,0x18772cd,0x1ba4bf5,0x076d5cc, + 0x19d3ae1,0x07836ab,0x0919a34,0x14307d9,0x0d2652a,0x0d535bb, + 0x16811ff,0x19106ff,0x00f886d,0x077a343,0x06636a2 }, + { 0x0587283,0x0ad1690,0x11777d7,0x13de0ff,0x0b3822c,0x1b6f1c0, + 0x0f5543b,0x03a2f0d,0x125d167,0x11e7c83,0x0c77bc5,0x0e3e39b, + 0x0a74bf9,0x04217e2,0x127a0c0,0x0a9eeae,0x1c727f8,0x187176d, + 0x13892b2,0x0f77b57,0x108dbb2,0x1602df6,0x106c673,0x1920979, + 0x0123ef7,0x16dd56d,0x0f62660,0x04853e3,0x16e6320,0x10b732f, + 0x0c9274d,0x1dcb3fa,0x1789fa8,0x194fad1,0x0eebfa7,0x002c174, + 0x0f5378a,0x169db0d,0x09be03c,0x0ece785,0x07aeecc } }, + /* 248 */ + { { 0x043b0db,0x03abe6e,0x12b7ce9,0x0b30233,0x1d8a4e8,0x0b60ab1, + 0x16fd918,0x12ff012,0x04f533e,0x11503de,0x1f16b4f,0x06ce739, + 0x0ca9824,0x06b4029,0x09ae8eb,0x1d8cc31,0x1908a1c,0x0deb072, + 0x0ac6da5,0x10834a0,0x195bae3,0x090c850,0x061b7fc,0x063fb37, + 0x0beacad,0x1bd96f9,0x1331ca3,0x1b12644,0x10a9927,0x139c067, + 0x1ab0e3a,0x0b0d489,0x0439a80,0x0f81e54,0x1fc0585,0x0bdbcfe, + 0x07a1f88,0x124c841,0x1d91520,0x00d6f14,0x028ec40 }, + { 0x0fe0009,0x1061751,0x13a7860,0x05e270e,0x011ba5d,0x126da97, + 0x0915314,0x0532ea4,0x07fede5,0x0a3ba13,0x1403513,0x0335364, + 0x0b01d34,0x0c34922,0x0229248,0x1c3739c,0x023dd1b,0x05d0b48, + 0x0a8c078,0x187ca86,0x0788242,0x1d38483,0x06d5bde,0x0951989, + 0x12a09c7,0x01cf856,0x075dbe5,0x139a308,0x1fb60e9,0x1f05b10, + 0x0d3b76b,0x17872ec,0x16bee54,0x1854202,0x0183fdf,0x1e8ca7f, + 0x0011c0a,0x0a43b79,0x0970daf,0x18e192a,0x0134f4c } }, + /* 249 */ + { { 0x138dff4,0x0d1f674,0x068e588,0x1690d4f,0x1d101a7,0x0a829bb, + 0x1be5f7a,0x1b7e589,0x1e65d87,0x18c204c,0x0e33ebc,0x1ff66e7, + 0x0eb89c7,0x142148b,0x0ea9417,0x14ec8d1,0x1094ebe,0x1d3c87e, + 0x164a24a,0x1beda9c,0x1741679,0x0e7e7f6,0x0808ccc,0x101fe42, + 0x0efd298,0x08085fa,0x1740d11,0x194f1bb,0x0858c87,0x0f659a1, + 0x1e8b2c2,0x04aea90,0x05eb6dc,0x18248cf,0x0857af2,0x02a0ceb, + 0x1381d47,0x0973a7b,0x15bd027,0x05307a7,0x06ea378 }, + { 0x05cc40a,0x004a5a7,0x17ef197,0x1435e6f,0x1a2e3f6,0x0137223, + 0x1fa77e4,0x0a7dece,0x193880f,0x1c3c64a,0x112aa6d,0x160efec, + 0x1c4aa30,0x1790461,0x1145a0c,0x0cc7741,0x1ae658d,0x03e013b, + 0x187644c,0x1678715,0x1ea4ef0,0x13b4ae1,0x0c0bcde,0x018bc1a, + 0x0c1c56a,0x1cff002,0x10832f3,0x1fa92b8,0x0a0e7c9,0x0dceab4, + 0x151c1b5,0x0b250c8,0x1225dff,0x1384e45,0x1196366,0x10a4fa8, + 0x07c08d6,0x02ac6d4,0x1c1f51f,0x1cd769d,0x0606ee6 } }, + /* 250 */ + { { 0x1c621f6,0x0cfe3ab,0x15200b6,0x02ffd07,0x092e40c,0x18ccd81, + 0x11e867b,0x0cc37bf,0x0e62c76,0x0502081,0x0e1d4de,0x06e1cce, + 0x0f16cda,0x0f1d32d,0x0065d34,0x1c41379,0x048f78f,0x10cba10, + 0x1d66071,0x140b157,0x102dc83,0x1a4e44b,0x1c9ac90,0x034cf15, + 0x12f1e9d,0x114cc45,0x03fca6b,0x0e57f36,0x1cf5ec4,0x11cc0eb, + 0x162850f,0x164d1bb,0x09d7e45,0x07fbb4e,0x09557f1,0x062cd9b, + 0x04aa767,0x0266f85,0x01c1d81,0x1efd229,0x049dba6 }, + { 0x158e37a,0x03fd953,0x1d98839,0x0e5b1d5,0x0f6b31d,0x0e11085, + 0x157e5be,0x0566a55,0x190efc3,0x049fb93,0x12c9900,0x13b883c, + 0x15435c9,0x02d8abc,0x0a1e380,0x06aeb7f,0x0a40e67,0x0cce290, + 0x1fba9d6,0x104b290,0x148bca6,0x00f8951,0x00a7dee,0x1459c6a, + 0x1cc182a,0x162d2a3,0x0fab578,0x023b0e9,0x082cdfa,0x1a4daab, + 0x19a6bc0,0x1177d1c,0x06ebfea,0x1ca55fc,0x1e0bd54,0x1e7b570, + 0x0bc8eb8,0x05fbcbf,0x19e3116,0x14936fb,0x04890a7 } }, + /* 251 */ + { { 0x1a995f6,0x0cb44c6,0x1bbf5ca,0x0fd8c2a,0x139eaae,0x15416ae, + 0x01030d5,0x1fcd2b2,0x1c135bc,0x1023590,0x0571e2c,0x16c81eb, + 0x00ea720,0x13e2fda,0x0093beb,0x077f805,0x14c0edb,0x14bec7e, + 0x07c93af,0x00520af,0x06b912f,0x078c3f5,0x05bf11f,0x13ab846, + 0x1fd2778,0x166610c,0x122498f,0x0674d6d,0x0d30a62,0x1a5945b, + 0x00208d8,0x193666d,0x0352e25,0x1ba2b65,0x1b29031,0x172711a, + 0x1c92065,0x12ad859,0x069dbe3,0x0960487,0x05c1747 }, + { 0x0accab5,0x073e145,0x016f622,0x0d559da,0x1802783,0x1607b28, + 0x01df733,0x10430b7,0x0125c28,0x1e56e0e,0x1715324,0x0814cff, + 0x1345df5,0x013c451,0x0f21b8b,0x1f4589e,0x069e3a0,0x19f43a2, + 0x1ce60f3,0x1b548e4,0x18a5c59,0x05a54b6,0x0c18f12,0x1cb122a, + 0x12bcfc2,0x061e1c6,0x1e1390a,0x01cf170,0x04fd539,0x1496786, + 0x0164028,0x1283cc0,0x1f92db7,0x09d0e5b,0x0905b29,0x0f2acf2, + 0x11ab0fa,0x1b798ed,0x10230d7,0x168f6b0,0x05d675e } }, + /* 252 */ + { { 0x10c6025,0x10d3bc3,0x1f2abbb,0x0f2345b,0x1c4a23b,0x15b2627, + 0x18310e1,0x162f61c,0x1e5ae72,0x0ead8be,0x1e884b5,0x11593dd, + 0x166dfc8,0x0a01c5c,0x1abbefb,0x05d989f,0x1568e2d,0x184cd61, + 0x04abc81,0x1d4c240,0x1218548,0x0dc4e18,0x13ffb67,0x1cce662, + 0x091c4e0,0x0700e0f,0x1ebe0c0,0x01376c9,0x13c3be0,0x080e33b, + 0x1ea1e01,0x1810433,0x0cd6ede,0x1837ff0,0x181fe06,0x1ef80ab, + 0x0080b36,0x1b1fce7,0x1b28e0a,0x15e153f,0x002fccb }, + { 0x07cac61,0x0ea68da,0x04b2664,0x0f570dc,0x0e9d168,0x0a78211, + 0x157b0ae,0x1cb18d0,0x148e648,0x120028c,0x06b15f2,0x1f65df1, + 0x0d9ba91,0x0df3c96,0x1064818,0x03c2a9e,0x1cbbd0f,0x0c16910, + 0x1111006,0x1d6277f,0x0fdc062,0x194cbc8,0x1cea5f0,0x0cf4c97, + 0x16d9460,0x1ad273c,0x01b48dd,0x08dba60,0x1f0f23c,0x026af6b, + 0x15e19cb,0x0769ec7,0x01851dc,0x139f941,0x1833498,0x1ea1475, + 0x0ac60f6,0x072c7e7,0x1551600,0x0ac2708,0x056f1e4 } }, + /* 253 */ + { { 0x0c24f3b,0x059fb19,0x1f98073,0x1e0db02,0x19eb1c7,0x1133bb4, + 0x102edaa,0x1c11b8c,0x00845d5,0x01c57ff,0x09e6a1e,0x1963f03, + 0x10f34fe,0x1f340cd,0x0b8a0b4,0x14970d4,0x1ce8237,0x0e25cbb, + 0x1d8d90e,0x0d67b70,0x04970f4,0x004bcb8,0x09197d5,0x1237c87, + 0x0876287,0x1636bf0,0x10d0663,0x004416d,0x1d94bb0,0x031b849, + 0x0c95ece,0x053ad21,0x0012e16,0x168d242,0x16d482a,0x0605d93, + 0x05dc34e,0x1717e34,0x033e2bf,0x06c4aa0,0x0911d19 }, + { 0x1e5af5b,0x0deac7a,0x0a9c4ec,0x16f6d44,0x07ca263,0x17956e5, + 0x1b137ce,0x17b56d7,0x1a04420,0x1328f2c,0x0db0445,0x1676974, + 0x103b448,0x1fa1218,0x18aff37,0x0d97678,0x0a5f1a9,0x06f0ae2, + 0x1347e60,0x15b143c,0x1a3abe0,0x071b339,0x004af45,0x02559bb, + 0x03af692,0x0e72018,0x115d825,0x1edb573,0x1f5ca58,0x0415083, + 0x0c1f7c6,0x1112d47,0x103e63c,0x1d9f85c,0x1513618,0x1dea090, + 0x009887d,0x080cdce,0x0e19579,0x1fd41ea,0x02be744 } }, + /* 254 */ + { { 0x150f324,0x0682fad,0x1e88153,0x083d478,0x19b1eb2,0x1c735bd, + 0x02971ff,0x104950b,0x0ec0408,0x01c817f,0x0ea6f76,0x0929a19, + 0x1e72b26,0x194e4f0,0x05dbe42,0x1b703a0,0x102ceba,0x002ea75, + 0x1cae2ff,0x080b626,0x1190874,0x00bcf56,0x17104a2,0x056919a, + 0x03dd3ec,0x019ea25,0x1cfd354,0x089334e,0x0c3a098,0x1c66ab2, + 0x0eecdec,0x1e85d00,0x0e99497,0x08c5940,0x1e82e3d,0x0980f68, + 0x1568fde,0x0871e29,0x039eb1c,0x05f9d5a,0x0735f54 }, + { 0x0380039,0x0d0b89c,0x07232aa,0x0fee9a3,0x0dfafe1,0x1e0d45d, + 0x0e4fb32,0x00b25a8,0x1fe0297,0x02edf9c,0x1a6cd8f,0x0b57261, + 0x0a4552b,0x157ea4a,0x198c0c8,0x15886fd,0x0d73f02,0x041354d, + 0x04d58a6,0x0a6ac53,0x1b3998c,0x03b9a15,0x0321a7e,0x1f36f34, + 0x10020e4,0x0d4eba8,0x134d1e2,0x06c3a34,0x0856376,0x0add67d, + 0x193c37b,0x111580f,0x07ee73f,0x18e5ea0,0x00fc27b,0x1bf58fa, + 0x0d475ba,0x0b4be5a,0x0e67897,0x13a297a,0x01e984c } }, + /* 255 */ + { { 0x050c817,0x082b0a4,0x04b71db,0x1269130,0x108a5b1,0x0c65df5, + 0x1455179,0x0b4e4e7,0x04be61e,0x0805afd,0x1ae3862,0x0d23af5, + 0x0baa088,0x09ad1ea,0x1999abf,0x0fa7bcc,0x19957ec,0x01c5160, + 0x1a35bd7,0x091d1ec,0x1746a06,0x163d6e0,0x07e7f24,0x060cb86, + 0x116c084,0x13491d0,0x01879ab,0x0c6e144,0x047e733,0x1b9b155, + 0x01189b0,0x1bdfedb,0x00c25f2,0x1696a2a,0x093336f,0x0530090, + 0x039a949,0x0dfe700,0x0b8052d,0x0aced28,0x06c474a }, + { 0x188e3a1,0x1cd20be,0x10a8eba,0x118908e,0x105d3c8,0x1308988, + 0x1a344ff,0x117cb3b,0x11a869e,0x047adb5,0x1764285,0x18b354e, + 0x137a8ab,0x110a300,0x0326f1d,0x099b25e,0x147c382,0x121fd53, + 0x09742e4,0x0c7430d,0x0ebc817,0x1e4de5d,0x0ef0d06,0x08ba3bb, + 0x13160f7,0x0fa70c0,0x16dd739,0x0a79ca5,0x0de4c2a,0x13366a8, + 0x1b457ab,0x0ebaeca,0x0d8996c,0x12a952f,0x1c47132,0x09c9fea, + 0x1c5305b,0x0f4c2d1,0x08b3885,0x0a9f437,0x06b2589 } }, +}; + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^128, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_base_42(sp_point_1024* r, const sp_digit* k, + int map, int ct, void* heap) +{ + return sp_1024_ecc_mulmod_stripe_42(r, &p1024_base, p1024_table, + k, map, ct, heap); +} + +#endif + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_1024(const mp_int* km, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_digit kd[42]; +#endif + sp_point_1024* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_42(heap, p, point); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 42, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 42, km); + + err = sp_1024_ecc_mulmod_base_42(point, k, map, 1, heap); + } + if (err == MP_OKAY) { + err = sp_1024_point_to_ecc_point_42(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_42(point, 0, heap); + + return err; +} + +/* Multiply the base point of P1024 by the scalar, add point a and return + * the result. If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_add_1024(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_point_1024 a; + sp_digit kd[42]; + sp_digit t[42 * 2 * 5]; +#endif + sp_point_1024* point; + sp_point_1024* addP = NULL; + sp_digit* tmp = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_42(heap, p, point); + if (err == MP_OKAY) { + err = sp_1024_point_new_42(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (42 + 42 * 2 * 5), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 42; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 42, km); + sp_1024_point_from_ecc_point_42(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_1024_mod_mul_norm_42(addP->x, addP->x, p1024_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_1024_mod_mul_norm_42(addP->y, addP->y, p1024_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_1024_mod_mul_norm_42(addP->z, addP->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_ecc_mulmod_base_42(point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_1024_proj_point_add_42(point, point, addP, tmp); + + if (map) { + sp_1024_map_42(point, point, tmp); + } + + err = sp_1024_point_to_ecc_point_42(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_42(addP, 0, heap); + sp_1024_point_free_42(point, 0, heap); + + return err; +} + +#ifndef WOLFSSL_SP_SMALL +/* Generate a pre-computation table for the point. + * + * gm Point to generate table for. + * table Buffer to hold pre-computed points table. + * len Length of table. + * heap Heap to use for allocation. + * returns BAD_FUNC_ARG when gm or len is NULL, LENGTH_ONLY_E when table is + * NULL and length is returned, BUFFER_E if length is too small and 0 otherwise. + */ +int sp_ecc_gen_table_1024(const ecc_point* gm, byte* table, word32* len, + void* heap) +{ + int err = 0; +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; +#endif + sp_point_1024* point = NULL; + sp_digit t[5 * 2 * 42]; + + if ((gm == NULL) || (len == NULL)) { + err = BAD_FUNC_ARG; + } + + if ((err == 0) && (table == NULL)) { + *len = sizeof(sp_table_entry_1024) * 256; + err = LENGTH_ONLY_E; + } + if ((err == 0) && (*len < (int)(sizeof(sp_table_entry_1024) * 256))) { + err = BUFFER_E; + } + + if (err == 0) { + err = sp_1024_point_new_42(heap, p, point); + } + if (err == 0) { + sp_1024_point_from_ecc_point_42(point, gm); + err = sp_1024_gen_stripe_table_42(point, + (sp_table_entry_1024*)table, t, heap); + } + if (err == 0) { + *len = sizeof(sp_table_entry_1024) * 256; + } + + sp_1024_point_free_42(point, 0, heap); + + return err; +} +#else +/* Generate a pre-computation table for the point. + * + * gm Point to generate table for. + * table Buffer to hold pre-computed points table. + * len Length of table. + * heap Heap to use for allocation. + * returns BAD_FUNC_ARG when gm or len is NULL, LENGTH_ONLY_E when table is + * NULL and length is returned, BUFFER_E if length is too small and 0 otherwise. + */ +int sp_ecc_gen_table_1024(const ecc_point* gm, byte* table, word32* len, + void* heap) +{ + int err = 0; + + if ((gm == NULL) || (len == NULL)) { + err = BAD_FUNC_ARG; + } + + if ((err == 0) && (table == NULL)) { + *len = 0; + err = LENGTH_ONLY_E; + } + if ((err == 0) && (*len != 0)) { + err = BUFFER_E; + } + if (err == 0) { + *len = 0; + } + + (void)heap; + + return err; +} +#endif +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * gm Point to multiply. + * table Pre-computed points. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_table_1024(const mp_int* km, const ecc_point* gm, byte* table, + ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_digit kd[42]; +#endif + sp_point_1024* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_42(heap, p, point); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 42, heap, DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 42, km); + sp_1024_point_from_ecc_point_42(point, gm); + +#ifndef WOLFSSL_SP_SMALL + err = sp_1024_ecc_mulmod_stripe_42(point, point, + (const sp_table_entry_1024*)table, k, map, 0, heap); +#else + (void)table; + err = sp_1024_ecc_mulmod_42(point, point, k, map, 0, heap); +#endif + } + if (err == MP_OKAY) { + err = sp_1024_point_to_ecc_point_42(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_42(point, 0, heap); + + return err; +} + +/* Multiply p* in projective co-ordinates by q*. + * + * r.x = p.x - (p.y * q.y) + * r.y = (p.x * q.y) + p.y + * + * px [in,out] A single precision integer - X ordinate of number to multiply. + * py [in,out] A single precision integer - Y ordinate of number to multiply. + * q [in] A single precision integer - multiplier. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_mul_qx1_42(sp_digit* px, sp_digit* py, + const sp_digit* q, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 42; + + /* t1 = p.x * q.y */ + sp_1024_mont_mul_42(t1, px, q, p1024_mod, p1024_mp_mod); + /* t2 = p.y * q.y */ + sp_1024_mont_mul_42(t2, py, q, p1024_mod, p1024_mp_mod); + /* r.x = p.x - (p.y * q.y) */ + sp_1024_mont_sub_42(px, px, t2, p1024_mod); + /* r.y = (p.x * q.y) + p.y */ + sp_1024_mont_add_42(py, t1, py, p1024_mod); +} + +/* Square p* in projective co-ordinates. + * + * px' = (p.x + p.y) * (p.x - p.y) = p.x^2 - p.y^2 + * py' = 2 * p.x * p.y + * + * px [in,out] A single precision integer - X ordinate of number to square. + * py [in,out] A single precision integer - Y ordinate of number to square. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_sqr_42(sp_digit* px, sp_digit* py, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 42; + + /* t1 = p.x + p.y */ + sp_1024_mont_add_42(t1, px, py, p1024_mod); + /* t2 = p.x - p.y */ + sp_1024_mont_sub_42(t2, px, py, p1024_mod); + /* r.y = p.x * p.y */ + sp_1024_mont_mul_42(py, px, py, p1024_mod, p1024_mp_mod); + /* r.x = (p.x + p.y) * (p.x - p.y) */ + sp_1024_mont_mul_42(px, t1, t2, p1024_mod, p1024_mp_mod); + /* r.y = (p.x * p.y) * 2 */ + sp_1024_mont_dbl_42(py, py, p1024_mod); +} + +#ifdef WOLFSSL_SP_SMALL +/* Perform the modular exponentiation in Fp* for SAKKE. + * + * Simple square and multiply when expontent bit is one algorithm. + * Square and multiply performed in Fp*. + * + * base [in] Base. MP integer. + * exp [in] Exponent. MP integer. + * res [out] Result. MP integer. + * returns 0 on success and MEMORY_E if memory allocation fails. + */ +int sp_ModExp_Fp_star_1024(const mp_int* base, mp_int* exp, mp_int* res) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td; + sp_digit* t; + sp_digit* tx; + sp_digit* ty; + sp_digit* b; + sp_digit* e; +#else + sp_digit t[4 * 2 * 42]; + sp_digit tx[2 * 42]; + sp_digit ty[2 * 42]; + sp_digit b[2 * 42]; + sp_digit e[2 * 42]; +#endif + sp_digit* r; + int err = MP_OKAY; + int bits; + int i; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8 * 42 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + tx = td + 4 * 42 * 2; + ty = td + 5 * 42 * 2; + b = td + 6 * 42 * 2; + e = td + 7 * 42 * 2; +#endif + r = ty; + + bits = mp_count_bits(exp); + sp_1024_from_mp(b, 42, base); + sp_1024_from_mp(e, 42, exp); + + XMEMCPY(tx, p1024_norm_mod, sizeof(sp_digit) * 42); + sp_1024_mul_42(b, b, p1024_norm_mod); + err = sp_1024_mod_42(b, b, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(ty, b, sizeof(sp_digit) * 42); + + for (i = bits - 2; i >= 0; i--) { + sp_1024_proj_sqr_42(tx, ty, t); + if ((e[i / 25] >> (i % 25)) & 1) { + sp_1024_proj_mul_qx1_42(tx, ty, b, t); + } + } + } + + if (err == MP_OKAY) { + sp_1024_mont_inv_42(tx, tx, t); + + XMEMSET(tx + 42, 0, sizeof(sp_digit) * 42); + sp_1024_mont_reduce_42(tx, p1024_mod, p1024_mp_mod); + XMEMSET(ty + 42, 0, sizeof(sp_digit) * 42); + sp_1024_mont_reduce_42(ty, p1024_mod, p1024_mp_mod); + + sp_1024_mul_42(r, tx, ty); + err = sp_1024_mod_42(r, r, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + return err; +} + +#else +/* Pre-computed table for exponentiating g. + * Striping: 8 points at a distance of (128 combined for + * a total of 256 points. + */ +static const sp_digit sp_1024_g_table[256][42] = { + { 0x0000000, 0x0000000, 0x0000000, 0x0000000, 0x0000000, 0x0000000, + 0x0000000, 0x0000000, 0x0000000, 0x0000000, 0x0000000, 0x0000000, + 0x0000000, 0x0000000, 0x0000000, 0x0000000, 0x0000000, 0x0000000, + 0x0000000, 0x0000000, 0x0000000, 0x0000000, 0x0000000, 0x0000000, + 0x0000000, 0x0000000, 0x0000000, 0x0000000, 0x0000000, 0x0000000, + 0x0000000, 0x0000000, 0x0000000, 0x0000000, 0x0000000, 0x0000000, + 0x0000000, 0x0000000, 0x0000000, 0x0000000, 0x0000000 }, + { 0x15c1685, 0x1236919, 0x09605c2, 0x03c200f, 0x0ac9e97, 0x052539f, + 0x1cf7d0f, 0x0ea81d1, 0x1826424, 0x1237c0a, 0x15db449, 0x176966c, + 0x1b3af49, 0x195f8d7, 0x078b451, 0x0a3cdb1, 0x02c2fd1, 0x013df44, + 0x1e21c5f, 0x1db90b1, 0x0c6fadd, 0x1f8b563, 0x15b6166, 0x11d5cb1, + 0x01a1b2d, 0x186873a, 0x018707c, 0x1f5ef40, 0x07e0966, 0x084d4db, + 0x1f59b6f, 0x0fa769e, 0x1f11c06, 0x1e4c710, 0x080b1c9, 0x02c2a57, + 0x086cb22, 0x0ac448f, 0x0ebd2bf, 0x0d4d7a7, 0x059e93c }, + { 0x1dd4594, 0x0e9b7b8, 0x079b953, 0x1e015de, 0x1bc9cc9, 0x0fb2985, + 0x0913a86, 0x0513d4b, 0x13f5209, 0x0c4554c, 0x1050621, 0x12991eb, + 0x1a97537, 0x0089ccf, 0x02f5e4b, 0x0d56a23, 0x0fdf5cb, 0x15cde9d, + 0x1b2e594, 0x1a39645, 0x1813813, 0x13a01c4, 0x1f51589, 0x1908639, + 0x1119b4a, 0x15b28fb, 0x0428603, 0x1b3ed52, 0x1bfa2ed, 0x168bcfb, + 0x1644e51, 0x0a153a1, 0x0f18631, 0x1b9e98b, 0x0835be0, 0x12be338, + 0x1b6a52b, 0x02d6354, 0x0b80efa, 0x0f6e9ec, 0x063ef18 }, + { 0x16f45e7, 0x1b5bf80, 0x0be1f0d, 0x0e57d90, 0x1c1bdb5, 0x014db00, + 0x1dd0739, 0x03ae725, 0x0c7afd8, 0x1edf851, 0x04262db, 0x163ee48, + 0x0fbda41, 0x1db07c6, 0x101d1d2, 0x1789ab6, 0x141b330, 0x1499f06, + 0x0cfe8ef, 0x105060e, 0x0cd1ae1, 0x0d87ae3, 0x083b4a6, 0x130c191, + 0x1354e3f, 0x020bff9, 0x1855567, 0x026c130, 0x1f85cbb, 0x1b1e094, + 0x0faac32, 0x08ed0bf, 0x02ecc49, 0x0cb19b4, 0x1b0bac6, 0x14a0bd1, + 0x1dac2cd, 0x0e63ca6, 0x1688e43, 0x039e325, 0x04fe679 }, + { 0x1e8733c, 0x011ea82, 0x1f06529, 0x0a3aae2, 0x0c845e6, 0x10d9916, + 0x1fa23a5, 0x19846f8, 0x0db4181, 0x02238e3, 0x0f5c843, 0x0bc4e27, + 0x0900c87, 0x1960bd8, 0x1f7a7b6, 0x1d5ed3b, 0x1e5e88c, 0x1218536, + 0x0e073a9, 0x0f4c34f, 0x18d5aaa, 0x13119fc, 0x1a94b40, 0x0d13535, + 0x0fdd060, 0x155daaf, 0x1972b12, 0x019f4f9, 0x1507613, 0x188a474, + 0x14be936, 0x09d343c, 0x09570c4, 0x000b818, 0x1d84681, 0x0431843, + 0x1e78d9d, 0x0e8fff5, 0x0ca5d55, 0x030ac3b, 0x004482a }, + { 0x1d486d8, 0x0c56139, 0x079f9dd, 0x0cc39b8, 0x0169f94, 0x0455a7c, + 0x067f086, 0x060e479, 0x0f33736, 0x072a781, 0x1089828, 0x1c4b7b1, + 0x00560be, 0x0298de3, 0x1f0c1f1, 0x1fd6a51, 0x11a7e44, 0x1eb790f, + 0x1c4a34d, 0x089338a, 0x0a45c8e, 0x1f6bd97, 0x058ec14, 0x147a445, + 0x07a0432, 0x1342061, 0x14d5165, 0x16a30a9, 0x1557e95, 0x124feb9, + 0x1e99b86, 0x10d240e, 0x1267fd9, 0x0138106, 0x034f9cd, 0x09f426a, + 0x08ccdb4, 0x0e1f92b, 0x1e27c6a, 0x1f1bdb7, 0x0833a0f }, + { 0x1376b76, 0x00ce3d5, 0x0332a31, 0x064fa1e, 0x1b7294f, 0x0628a69, + 0x0e78aa4, 0x14dcad7, 0x0a62575, 0x18dd28f, 0x102a224, 0x00f6131, + 0x0a56fee, 0x1a60b51, 0x0f96bba, 0x04c1609, 0x10be6eb, 0x072899a, + 0x075709c, 0x1db5ad4, 0x0dd1339, 0x0cf4edd, 0x1cd9bb5, 0x1a0dd81, + 0x1be882d, 0x1eda109, 0x032c461, 0x05ac739, 0x01058a2, 0x0af0ec5, + 0x1c47fb2, 0x1456e89, 0x1f73ea6, 0x02e0601, 0x146bd3c, 0x00e83fa, + 0x05f811a, 0x16fcad4, 0x0597cb8, 0x1c7d649, 0x0692b3c }, + { 0x0a127b4, 0x165b969, 0x05bc339, 0x0b1f250, 0x06a46ea, 0x11bb0b3, + 0x1d18d1e, 0x1dc87d9, 0x1e0ab96, 0x11ecd00, 0x16fa305, 0x18db65d, + 0x05c8145, 0x06f2733, 0x109b2b9, 0x0a5f25e, 0x14074e2, 0x08ba685, + 0x14abe0c, 0x0481aef, 0x093654c, 0x0b9eb29, 0x1607e8e, 0x13a8d2a, + 0x1491ca0, 0x01e02dc, 0x0d51499, 0x189d0a6, 0x1283278, 0x0198ea0, + 0x094cb59, 0x0e06c3e, 0x0479038, 0x184f932, 0x06c627b, 0x00ee832, + 0x01de5fe, 0x078557c, 0x10b5b03, 0x015e800, 0x0333e43 }, + { 0x126d3b7, 0x026f267, 0x06f977c, 0x0d6a7ef, 0x17a7730, 0x045b322, + 0x0f17c60, 0x0c14802, 0x0850373, 0x1948f52, 0x1840dfb, 0x1afa160, + 0x1b1ffc9, 0x12e489d, 0x1413765, 0x10b0fb3, 0x1aff13b, 0x0ca451b, + 0x18fb9d5, 0x086907f, 0x1386b54, 0x1a02318, 0x0ff0879, 0x1bd6b18, + 0x104e5cd, 0x0a959d0, 0x0995cb3, 0x09fc30c, 0x0aa4089, 0x18d08ad, + 0x18bae69, 0x08b3d48, 0x0dc6fe5, 0x18151c5, 0x05d52ba, 0x037631a, + 0x0f7791d, 0x093b1b1, 0x15c22b8, 0x03bad77, 0x010e8b3 }, + { 0x0d9f1af, 0x181f29f, 0x059ae1f, 0x0eaccec, 0x03ad247, 0x070adc0, + 0x158c1d3, 0x0b671b9, 0x026b1e8, 0x03bf158, 0x0670546, 0x1a2e35f, + 0x1ab1654, 0x09c12a3, 0x00ba792, 0x0bdeb2f, 0x07c26d5, 0x036e3fe, + 0x1efad53, 0x11f2ba5, 0x0357903, 0x1f01b60, 0x1f96437, 0x1b87eff, + 0x16eae4f, 0x14467e5, 0x13cd786, 0x163f78a, 0x0a5568c, 0x0ed96d0, + 0x15cf238, 0x0b6deaa, 0x087393f, 0x005034d, 0x0ccb9eb, 0x1670c8d, + 0x0a8495a, 0x130e419, 0x112f3f4, 0x09819b9, 0x0648552 }, + { 0x0a6ff2a, 0x1d9f162, 0x0a286af, 0x146b4c8, 0x0aa03fb, 0x17fba11, + 0x09fc226, 0x1271084, 0x0ba5dbd, 0x19bc41d, 0x060b2c8, 0x15d3a54, + 0x0538186, 0x04d00f8, 0x1c1d935, 0x03cf573, 0x1eb917b, 0x1c9208f, + 0x1c32ed6, 0x163206a, 0x1e7c700, 0x0adc8a5, 0x1754607, 0x102305a, + 0x0443719, 0x0cb89ae, 0x115d2e6, 0x04eb1a4, 0x0d28b23, 0x147ab19, + 0x0269942, 0x1f4707e, 0x0078bac, 0x19ec012, 0x1830028, 0x12ca8d4, + 0x0df8b44, 0x030e3d1, 0x158f290, 0x1e5e468, 0x01f76f3 }, + { 0x0c436b0, 0x160a1a2, 0x01ea6a8, 0x0c3ed39, 0x1907055, 0x16d96fb, + 0x045ed7d, 0x1046be6, 0x1ed56ba, 0x0bb0fa0, 0x0be9221, 0x0c9efa1, + 0x1ef8314, 0x1d6e738, 0x07ca454, 0x0e91153, 0x093116b, 0x1593dfb, + 0x0ee510e, 0x14b5193, 0x1de8a98, 0x131772f, 0x1fe1e00, 0x025596e, + 0x193dd18, 0x0491d37, 0x137212f, 0x1f25499, 0x14995aa, 0x1157f8e, + 0x074f095, 0x009db13, 0x19fc33c, 0x1529c7e, 0x0a513b4, 0x0d80519, + 0x049ea72, 0x19b3dd8, 0x0381743, 0x1f67a21, 0x004924f }, + { 0x073562f, 0x0471ee3, 0x1230195, 0x0bc5d5c, 0x13b3302, 0x0e34bbe, + 0x14cad78, 0x0f7cc3f, 0x06ebe55, 0x1271032, 0x1b86390, 0x038083a, + 0x1b76739, 0x0a6bf4a, 0x03aee38, 0x0371897, 0x1d42099, 0x1a5745b, + 0x004a434, 0x01becdc, 0x1f4ef8a, 0x11c92f2, 0x125f892, 0x0104e55, + 0x1b2cb15, 0x130bcd3, 0x18941c9, 0x08160e5, 0x02fa49b, 0x10c1483, + 0x13b6b67, 0x1e78a77, 0x180a784, 0x013ccc3, 0x0dda7c5, 0x0cb1505, + 0x0146842, 0x06c24e6, 0x0b8d423, 0x0138701, 0x04dfce8 }, + { 0x127b780, 0x14e596a, 0x0375141, 0x0b2ef26, 0x152da01, 0x1e8131e, + 0x1802f89, 0x0562198, 0x0bb2d1b, 0x0081613, 0x0b7cf0d, 0x0c46aa9, + 0x074c652, 0x02f87fa, 0x0244e09, 0x0dcf9ad, 0x0c5ca91, 0x141fd46, + 0x0572362, 0x01e273a, 0x16b31e1, 0x1740ee2, 0x1c5cf70, 0x09db375, + 0x0cb045c, 0x1143fe7, 0x011f404, 0x00ffafb, 0x1a532f3, 0x18a9cf9, + 0x0889295, 0x1c42a78, 0x1e9e81d, 0x052042c, 0x057790a, 0x078ac4b, + 0x1339bd2, 0x1ed7fc4, 0x1a00b71, 0x0117140, 0x00d0759 }, + { 0x0085f2a, 0x17953ef, 0x0b961c2, 0x1f7d336, 0x08fcd24, 0x05209dc, + 0x1498567, 0x0a31181, 0x08559f8, 0x1815172, 0x0b68347, 0x0043ec4, + 0x1583b96, 0x16e51b0, 0x0170bd5, 0x18d04b8, 0x11c7910, 0x100a467, + 0x1c9a56f, 0x1e512c4, 0x0ef6392, 0x1ad46b2, 0x020f42e, 0x1f978a5, + 0x122441c, 0x1f2f786, 0x1149845, 0x0bb5f9d, 0x0928e9f, 0x095cf82, + 0x0aada18, 0x0727e5c, 0x03f744d, 0x008a894, 0x1fb5c03, 0x1df7dda, + 0x04360df, 0x06f10ad, 0x14d6bcb, 0x0385e10, 0x024fa96 }, + { 0x16df7f6, 0x1ed9fb0, 0x0c981d9, 0x11f7b20, 0x043057d, 0x016aa23, + 0x0aa41ba, 0x1b62e9b, 0x1689643, 0x14279a2, 0x0681808, 0x03bf991, + 0x1218b19, 0x0b613e8, 0x0d1abd3, 0x0a28b75, 0x086c989, 0x12d2bfa, + 0x1250be7, 0x0429d39, 0x0158c03, 0x07a0ca8, 0x09cf872, 0x15a8756, + 0x1759f39, 0x0b9c675, 0x1f943b8, 0x1c3716f, 0x0d7d4e5, 0x18fe47a, + 0x1cfd8d6, 0x0eaac07, 0x0ff77e3, 0x17d3047, 0x0745dd4, 0x02403ec, + 0x0a6fb6e, 0x0bd01ea, 0x0045253, 0x07bf89e, 0x0371cc2 }, + { 0x090c351, 0x188aeed, 0x1018a26, 0x1e6c9b3, 0x0d196eb, 0x08598db, + 0x0480bd9, 0x05eef51, 0x06f5764, 0x01460b2, 0x00049f3, 0x1c6c102, + 0x1bdc4f7, 0x0e26403, 0x0db3423, 0x081e510, 0x156e002, 0x1894078, + 0x072ce54, 0x14daf13, 0x00383f9, 0x099d401, 0x1029253, 0x0fa68e8, + 0x17e91e8, 0x12522b4, 0x1c9b778, 0x01b2fa0, 0x00c30e7, 0x12c6bb2, + 0x1181bda, 0x0b74dcd, 0x1c2c0e8, 0x009f401, 0x09ebc6f, 0x1e661ed, + 0x09f4d78, 0x101727e, 0x1edfcf9, 0x1401901, 0x092b6bc }, + { 0x100822e, 0x0ae41af, 0x1c48b8f, 0x057162d, 0x0e82571, 0x1851980, + 0x0a7124a, 0x0a90386, 0x1a7cc19, 0x1a71956, 0x0504fda, 0x19dc376, + 0x070bee9, 0x0549651, 0x1edeea9, 0x122a7db, 0x0faea3b, 0x0e6a395, + 0x03c303e, 0x013cfc0, 0x1b70e8f, 0x192e6f5, 0x0938761, 0x136c76d, + 0x1ae084a, 0x1b2ff15, 0x00ff563, 0x0802837, 0x162759f, 0x0f6d51d, + 0x0235fb1, 0x0f21c61, 0x0af6e67, 0x1bf18cd, 0x00c07c9, 0x1842b5b, + 0x0f33871, 0x0da5cc6, 0x1e2779f, 0x1929e05, 0x071ff62 }, + { 0x04a84d9, 0x0388115, 0x079aa93, 0x1abd78e, 0x02ee4ac, 0x06b2bc7, + 0x0a297c7, 0x14a7623, 0x1fff120, 0x1faf7cf, 0x1940ce0, 0x11c213c, + 0x00a4c59, 0x050220c, 0x1a7e643, 0x05183c3, 0x146f598, 0x1c5c196, + 0x0ebd4da, 0x1e51406, 0x168a753, 0x18db6a7, 0x04bb712, 0x199a3e1, + 0x0692a72, 0x01976ef, 0x1748899, 0x07541ef, 0x12661cd, 0x1b1f51e, + 0x168e36e, 0x1fb86fb, 0x1e19fc6, 0x1b5a678, 0x0d4213b, 0x12d8316, + 0x1f1bba6, 0x141ff4e, 0x009cf9a, 0x1cebf2b, 0x040fd47 }, + { 0x07140a4, 0x05ba313, 0x0bed6e2, 0x1dd56de, 0x0dbbfc1, 0x0312a43, + 0x12239a6, 0x185bb3d, 0x12eb6ef, 0x0df75d0, 0x03fe21a, 0x0295159, + 0x10cfc22, 0x1ad10ca, 0x15725ba, 0x1f6d32b, 0x0054171, 0x1c99c4e, + 0x0d1a0cd, 0x0ba8a43, 0x025c2d8, 0x042089a, 0x0535a28, 0x0d842e8, + 0x00139ec, 0x026f296, 0x1fdcc02, 0x019e172, 0x178aa32, 0x15130fa, + 0x10c6b05, 0x1f36d5c, 0x0b9fab3, 0x0534a8c, 0x0447615, 0x0cd1b04, + 0x1ffbe28, 0x19a6cc6, 0x0ce302c, 0x0afcc72, 0x05b1c11 }, + { 0x0b6bb8f, 0x0d558b9, 0x0b0a43b, 0x0405f92, 0x0dc64ed, 0x14a639c, + 0x08f17f9, 0x1c9e857, 0x1cb54dc, 0x0b6e32f, 0x108370c, 0x0d46c64, + 0x14cb2d6, 0x02b6e7c, 0x19c1b9c, 0x0593a2d, 0x164a4f3, 0x01404e3, + 0x09bb72a, 0x11b061d, 0x1f57ab1, 0x1340e32, 0x13f46b3, 0x1425820, + 0x1651c7d, 0x1240fc8, 0x1b1de46, 0x15877ac, 0x1e67a30, 0x0e7a3c2, + 0x046dab4, 0x1b41fab, 0x0d3fc44, 0x031a272, 0x0005b87, 0x079c2c9, + 0x13e50ab, 0x0f4e5c1, 0x1bbd213, 0x0754ead, 0x0963ab8 }, + { 0x14ea5a3, 0x1a3ec6f, 0x17fa512, 0x0ab9fc8, 0x1656881, 0x1e1ab24, + 0x1f56228, 0x02ba2dc, 0x0e7c99e, 0x072ad9f, 0x01c6f21, 0x009beaa, + 0x0e3fee2, 0x0202bee, 0x001bca4, 0x0aae0e2, 0x10dbba7, 0x07f461c, + 0x0c66b6b, 0x0b796c6, 0x1fd8364, 0x183e105, 0x00627a2, 0x0fb2af1, + 0x109697d, 0x11dc72a, 0x06e67d3, 0x06fa264, 0x0cfb6a0, 0x1290d30, + 0x168046c, 0x106e705, 0x0594aaa, 0x0ee03b3, 0x07f60f0, 0x0991372, + 0x076b988, 0x015c4c8, 0x11561ae, 0x1f97c8b, 0x0443480 }, + { 0x114221a, 0x1ffda48, 0x09ebe3f, 0x1c7d0af, 0x0aec4f2, 0x12a3c3a, + 0x143903e, 0x0a485c5, 0x1d6f961, 0x19f3598, 0x1a6ddfb, 0x0a6ff7f, + 0x0ab2296, 0x1da1d43, 0x0a743cb, 0x0558d85, 0x0ed2457, 0x1920942, + 0x1c86e9e, 0x0d122fc, 0x078da38, 0x00608bd, 0x16fbdf0, 0x02c0b59, + 0x09071d3, 0x1749c0a, 0x18196a3, 0x05b5b53, 0x02be82c, 0x1c6c622, + 0x16356c4, 0x1edae56, 0x16c224b, 0x01f36cd, 0x173e3ac, 0x0373a6a, + 0x0170037, 0x168f585, 0x09faead, 0x1119ff5, 0x097118a }, + { 0x1ecb5d8, 0x02cd166, 0x019afe7, 0x175274d, 0x0083c81, 0x1ba7dfc, + 0x1760411, 0x16849c1, 0x0a02070, 0x1bcd1e5, 0x1ede079, 0x1f761f7, + 0x049d352, 0x1f7950e, 0x0c36080, 0x1ca0351, 0x17b14b3, 0x15c2c31, + 0x0a20bfc, 0x0e14931, 0x0fa55ba, 0x019d837, 0x089cc02, 0x05fdc55, + 0x002f410, 0x1d2d216, 0x0628088, 0x09cec53, 0x03fc72e, 0x1d1342e, + 0x19f6e8a, 0x1fca5d5, 0x14fe763, 0x1a2fb2a, 0x01689c3, 0x18616a8, + 0x0573387, 0x150bbd5, 0x1ea0b55, 0x11a96e3, 0x017c077 }, + { 0x135e37b, 0x0ff8e93, 0x15c839b, 0x0ccadd8, 0x09884e5, 0x1dd4bc6, + 0x0b2767a, 0x18945eb, 0x0ba09f3, 0x07d228c, 0x010ddd0, 0x02efeb6, + 0x0a8c3fa, 0x0b3d176, 0x0877b36, 0x17a8143, 0x0700528, 0x13b45e5, + 0x01a4712, 0x092a563, 0x1fd5f22, 0x02f436a, 0x05b84b1, 0x10b34d4, + 0x1915737, 0x1073d06, 0x0683ff3, 0x047e861, 0x0cc9a37, 0x1bcdd4b, + 0x0e16a36, 0x035a474, 0x1d12ae0, 0x1aec236, 0x0e878af, 0x0d3ffd8, + 0x0452ed6, 0x074270d, 0x1931b5b, 0x190ae3f, 0x01219d5 }, + { 0x02969eb, 0x1533f93, 0x1dcd0fa, 0x1a5e07c, 0x1a3ab39, 0x1d84849, + 0x1f9455e, 0x0e9cc24, 0x18d1502, 0x1c15876, 0x02f6f43, 0x15b1cb0, + 0x0bffffc, 0x14ba1f3, 0x14f41d6, 0x023aca3, 0x1b18bac, 0x00a425e, + 0x0c930e2, 0x1b3321d, 0x07c695c, 0x083fd63, 0x085a987, 0x09cd70e, + 0x0f762a0, 0x0642184, 0x072e95f, 0x10cbbac, 0x14a07a2, 0x1586e91, + 0x1e4f0a5, 0x0740f27, 0x0f92839, 0x14f673b, 0x187c2f8, 0x04e16af, + 0x1e626f4, 0x0a5417b, 0x1c8c04c, 0x165acaf, 0x02c8d7a }, + { 0x025e4d6, 0x1ac4904, 0x0d119f3, 0x0addf07, 0x1f51eaa, 0x080846e, + 0x197604c, 0x07ec7cc, 0x18dd096, 0x14fc4fa, 0x190da88, 0x09bb3be, + 0x078c4b1, 0x0a2f5dd, 0x16b91a7, 0x1e70333, 0x1775a4d, 0x188c555, + 0x078dffa, 0x12f17a5, 0x17efda8, 0x1556516, 0x1a73b56, 0x0fad514, + 0x0d05dc6, 0x11a364c, 0x15dfe12, 0x08e97e1, 0x0cd59a7, 0x059776c, + 0x1ef510a, 0x1a3a731, 0x0fd1cd5, 0x10588d8, 0x0f6e528, 0x08b2c02, + 0x1b404c4, 0x15b82d0, 0x165625b, 0x0ee9613, 0x02299d2 }, + { 0x04397e6, 0x06ac6e3, 0x0c796e7, 0x1d7edba, 0x0c198f1, 0x0f8ed95, + 0x16384fa, 0x118b0cd, 0x18fcdc6, 0x02d7143, 0x1007f50, 0x019bca7, + 0x16a4b28, 0x008edaf, 0x058fcb5, 0x1f141b9, 0x189bec4, 0x1f6aea8, + 0x05bba62, 0x1fa27b2, 0x148e336, 0x198216f, 0x1a496c6, 0x1c00e9c, + 0x16291ac, 0x14a867a, 0x0094c5f, 0x11a7169, 0x1c446be, 0x0e95c10, + 0x0d31eb4, 0x1e16cb2, 0x1c44135, 0x106a838, 0x0dbd4b2, 0x0d2e36e, + 0x07b46c2, 0x0ffd2b9, 0x1863abe, 0x0f2326c, 0x021ac67 }, + { 0x17fbcd2, 0x1071f96, 0x1062ad0, 0x072f7bf, 0x1272247, 0x1aea5a0, + 0x0cfe137, 0x1a69240, 0x03807b7, 0x1e6a11b, 0x10d895b, 0x1613667, + 0x14dfc19, 0x1079140, 0x15bcdd6, 0x0337027, 0x059037c, 0x0384bc5, + 0x1fc9ee7, 0x13132e1, 0x03894f3, 0x02b0ad2, 0x1f03869, 0x0c05ee9, + 0x1496a3e, 0x10e7fd1, 0x06c9872, 0x07e3886, 0x0164cdc, 0x08edf70, + 0x07d8488, 0x1cfef7d, 0x0463ee4, 0x170dd98, 0x19e24b0, 0x0c02bef, + 0x04483a5, 0x1ec46b1, 0x1676198, 0x1ce1cc5, 0x00e8ec1 }, + { 0x00878dd, 0x06614c5, 0x1c6aa23, 0x1acc800, 0x19ac175, 0x0b9b0bc, + 0x1208294, 0x02b2068, 0x0dd58a3, 0x0b6811f, 0x088684c, 0x17a911a, + 0x0330785, 0x0ace247, 0x12cf79e, 0x14ee36e, 0x1824c67, 0x1a17701, + 0x02e4514, 0x1ed9bbc, 0x1e9159e, 0x144d91b, 0x1e0c2b8, 0x0bb064a, + 0x07a4c49, 0x13370c2, 0x1b41dcd, 0x0f6242f, 0x14a3256, 0x1643514, + 0x0996064, 0x10c9b06, 0x0aa0f56, 0x09f2dbb, 0x144bd2c, 0x1bc5457, + 0x1b6b73f, 0x0860e00, 0x0d8d761, 0x0beba20, 0x0653a79 }, + { 0x0dcb199, 0x144c2a8, 0x0d833f8, 0x1cff405, 0x135b8e5, 0x1b01e85, + 0x15f0f25, 0x16b794f, 0x127f131, 0x0729446, 0x04b54ac, 0x09bdc56, + 0x073aa70, 0x0edb92e, 0x01ac760, 0x16227c4, 0x19ac5d1, 0x1858941, + 0x0d175d8, 0x12e197b, 0x1e8e14f, 0x1f59092, 0x1265fe4, 0x0fb544d, + 0x1739cee, 0x074deba, 0x1c7fbc8, 0x0dd97a7, 0x0a42b14, 0x108a3e3, + 0x147e652, 0x04ff61f, 0x089eb4f, 0x06d25e9, 0x14c6690, 0x0c2230d, + 0x1b9d797, 0x1fb2d2f, 0x19d7820, 0x0f7a888, 0x030dfc4 }, + { 0x0aadfe8, 0x02d714f, 0x004af3f, 0x0969a9d, 0x05027e5, 0x099ab09, + 0x00b7e2d, 0x029560e, 0x056a6a2, 0x15ce102, 0x041a3a8, 0x1ef460b, + 0x0fb1a3d, 0x0c41888, 0x1452c86, 0x11c3946, 0x136c4b7, 0x05bdf11, + 0x18bda61, 0x0e79cc7, 0x1ac6170, 0x1316efb, 0x01b8452, 0x1af8791, + 0x192bf07, 0x14493b0, 0x0fac6b8, 0x1b4d3c1, 0x1849395, 0x18ba928, + 0x08260eb, 0x080f475, 0x0c52a4d, 0x1f10c4d, 0x1f6ab83, 0x022a6b8, + 0x197f250, 0x17f4391, 0x04b3f85, 0x03ea984, 0x0572a59 }, + { 0x1a5553a, 0x1420c84, 0x0ef1259, 0x1064ee6, 0x1f05431, 0x17eb481, + 0x0d2c8fb, 0x1a9f39d, 0x1f22126, 0x09e5fcd, 0x1655e2f, 0x03805fd, + 0x186d967, 0x0501836, 0x0965f3b, 0x09fcb77, 0x1613d67, 0x15b82f6, + 0x1fccfdd, 0x06c456c, 0x0c31f1d, 0x0308e5c, 0x056f3cf, 0x07a3552, + 0x067dce5, 0x1a1d1c2, 0x07e422a, 0x005fd25, 0x15767a9, 0x04cec68, + 0x1edb8f9, 0x1215fa0, 0x142db5c, 0x18c8740, 0x1ef1b22, 0x1c2418d, + 0x04919a4, 0x0432a99, 0x0b0f203, 0x1c3b190, 0x065c2cb }, + { 0x060bb63, 0x06d1053, 0x0915a13, 0x150dd0c, 0x07dc3b0, 0x10776b9, + 0x0b3d9ae, 0x0b0ec8e, 0x1679dd1, 0x0e0b172, 0x14b511e, 0x04ee108, + 0x1eb6884, 0x009fabc, 0x06f1acd, 0x02ee105, 0x1ec9501, 0x1c9750a, + 0x1dce060, 0x09c6008, 0x12f15e3, 0x04b9f0e, 0x030f28d, 0x137a7bd, + 0x0f1dc22, 0x169d2e2, 0x0e53bdf, 0x107dfe3, 0x0e7a1a7, 0x19c6efd, + 0x1491b6d, 0x0341330, 0x153d72e, 0x07a55a1, 0x1562837, 0x124a675, + 0x0e7888b, 0x02a80b0, 0x1fd9b60, 0x1aa774e, 0x0831440 }, + { 0x011b2da, 0x117197b, 0x1ab3d0f, 0x13a1f48, 0x1d066e2, 0x059e06a, + 0x1cfa208, 0x1e1d12f, 0x01d3e44, 0x02e1473, 0x09e99b1, 0x1ecdbfa, + 0x17929d7, 0x080f428, 0x16e1828, 0x0f1bae6, 0x0983de0, 0x1751fe7, + 0x0e33846, 0x0efb6ac, 0x0b3bc99, 0x17a429b, 0x01220e0, 0x195bf8c, + 0x07a3c64, 0x1b8bf06, 0x1e0851e, 0x19a2fef, 0x011e3e3, 0x11e60da, + 0x1b7a559, 0x130bf68, 0x139ac8f, 0x08ce52b, 0x0736f3c, 0x0a70a73, + 0x015a281, 0x0c2d387, 0x115992a, 0x114dabe, 0x0504c3a }, + { 0x0fa53c7, 0x0a941dc, 0x138c02d, 0x10a128e, 0x185cff3, 0x1e712fc, + 0x090710d, 0x1da469a, 0x0e5a129, 0x0c19218, 0x1319d0a, 0x12ad557, + 0x016ad38, 0x1f740f7, 0x1700075, 0x04e0545, 0x0b6670b, 0x1a611e3, + 0x1ba28ee, 0x1cacfd4, 0x13eab35, 0x07534b3, 0x0f1c2cf, 0x1c51d59, + 0x1a9c3e6, 0x1ed42d3, 0x1954ded, 0x15cd09b, 0x0937dc2, 0x01f2b6f, + 0x0897b2b, 0x1f08608, 0x12ea6c9, 0x0e2905f, 0x1f41dff, 0x1a7195e, + 0x09f56ad, 0x1d7858b, 0x0874b09, 0x1338e3a, 0x0496e46 }, + { 0x1a93467, 0x07e414f, 0x1852e85, 0x081d654, 0x02e3768, 0x19f04de, + 0x13ebd20, 0x198cb37, 0x03686bd, 0x042cba9, 0x0c85aaf, 0x010103e, + 0x1840bfd, 0x0be040d, 0x18ef698, 0x0f27788, 0x086bb04, 0x0de80fd, + 0x1359031, 0x03d9cc5, 0x15c45a2, 0x0a1101e, 0x05efda9, 0x022cf6f, + 0x00edc95, 0x134675a, 0x1dd96e8, 0x0cf5595, 0x0b51f9d, 0x0cf4d75, + 0x0ea2e83, 0x161ad0c, 0x14b215e, 0x034a960, 0x136f97c, 0x0a6a99b, + 0x0b3744b, 0x15ae67e, 0x1ffa13c, 0x0e62606, 0x0133891 }, + { 0x1003cd1, 0x0032022, 0x0b1bb9a, 0x18895c5, 0x1dac17b, 0x07298a7, + 0x1067f7a, 0x0b8979a, 0x1c7cea9, 0x0f1a75c, 0x0df8060, 0x0c5a71e, + 0x08bb577, 0x1304c86, 0x1133ec0, 0x094f7d9, 0x1f950a3, 0x185e249, + 0x10cc13b, 0x0e82e4a, 0x0a2a680, 0x1935e45, 0x0bb03f2, 0x08bfd4b, + 0x09b463b, 0x1d64f3d, 0x1957ef6, 0x17652a5, 0x05dff44, 0x0053024, + 0x05943c3, 0x09bd48f, 0x0c5104d, 0x11d0101, 0x0825a57, 0x0ba59df, + 0x0da1f34, 0x00815a3, 0x0fef532, 0x0e7e706, 0x0422eb5 }, + { 0x0ad3f47, 0x0975b53, 0x083ab16, 0x1b2e297, 0x10861f6, 0x140a2cd, + 0x1a4641c, 0x006af83, 0x064ea58, 0x1be4a71, 0x049c8f3, 0x0d58a96, + 0x0a72537, 0x0d7db9b, 0x09ae907, 0x079b9e5, 0x120cba0, 0x0e44f44, + 0x0c3f4eb, 0x041968b, 0x19fef2e, 0x0a6b302, 0x09ba969, 0x13bf178, + 0x1fa8b88, 0x15ff731, 0x059a8fc, 0x01e38fc, 0x1312e14, 0x1e4e3a3, + 0x1fc27fa, 0x0e4f333, 0x119b9c2, 0x09582be, 0x0d32dff, 0x0d53f77, + 0x00da2dc, 0x1d13ebd, 0x0960b3e, 0x19e584a, 0x0368541 }, + { 0x0799d37, 0x09e4f11, 0x0ce9443, 0x0b59f46, 0x1b677de, 0x07bcad8, + 0x1863c20, 0x1849cd5, 0x0afc8df, 0x0da9e15, 0x10b709a, 0x036c1d0, + 0x0879754, 0x16033ff, 0x09bcabe, 0x1b0efab, 0x003bd07, 0x1681045, + 0x152f8bc, 0x08e7e0c, 0x023e34b, 0x157a8af, 0x199f040, 0x1835e91, + 0x1bf9d2a, 0x0805806, 0x06da84f, 0x04c9f48, 0x094c11e, 0x1c354bf, + 0x1d059a5, 0x10d4b0d, 0x1d8cf2d, 0x093f484, 0x01a71fe, 0x0c0e77f, + 0x0241a56, 0x0bbc401, 0x04cd2e2, 0x0b2444c, 0x059a5bf }, + { 0x1347191, 0x0e48f40, 0x05cba74, 0x19d72d3, 0x186c1ab, 0x0a353f8, + 0x01d9ea7, 0x12e0f11, 0x0daa7d3, 0x149e7e6, 0x0e6a836, 0x13e3b23, + 0x0c08bee, 0x1c6e9e3, 0x19ff5e3, 0x1020104, 0x0d09422, 0x1fc9c30, + 0x0b6d1fe, 0x14e355b, 0x0f8a6a6, 0x1bd30ab, 0x072a81a, 0x1091793, + 0x105e039, 0x09ad50d, 0x1caaaa4, 0x0dbb846, 0x1f3bd13, 0x103cd89, + 0x135df9f, 0x09598be, 0x10b5cbe, 0x07e9b46, 0x17e2613, 0x1009b48, + 0x13d3e0f, 0x077b0c6, 0x1e673c5, 0x18287d6, 0x0467564 }, + { 0x0fff5d7, 0x12c825b, 0x1d4a35c, 0x1f25b88, 0x037f33a, 0x105c550, + 0x155d5b4, 0x073212b, 0x143baec, 0x111afe0, 0x0ae6c0c, 0x095ed14, + 0x01a2feb, 0x0a69ae3, 0x1140c62, 0x0e90cc3, 0x0a2ea87, 0x1d6495b, + 0x046f1bc, 0x09162a0, 0x1cb28eb, 0x1463cf6, 0x08a3f84, 0x1a5400d, + 0x1bc0ca5, 0x0284fb8, 0x08bc56e, 0x062cee6, 0x036218f, 0x19463d0, + 0x07bfa35, 0x09f03c1, 0x08f39cb, 0x0286c83, 0x0059edf, 0x062ee7e, + 0x0d6a1e0, 0x07bd6df, 0x0135434, 0x02c9dd3, 0x08a0dee }, + { 0x1366e6f, 0x0c8dfa3, 0x0015412, 0x1fd0d86, 0x18084d9, 0x06671b5, + 0x11d4690, 0x1c42989, 0x03f1961, 0x1da3553, 0x11790ee, 0x0bf2808, + 0x1f56a78, 0x048f10a, 0x0346d5f, 0x1011bb7, 0x13ec7ee, 0x0354722, + 0x0ea87a3, 0x0cfdf17, 0x0109c03, 0x18f1f0c, 0x0c43647, 0x0414586, + 0x0fd0e7e, 0x13bfcbe, 0x1155330, 0x03d0190, 0x028403f, 0x1e0ebdb, + 0x1f3a26e, 0x07fc142, 0x178a966, 0x00039bb, 0x067f07c, 0x053d3b6, + 0x16f6bed, 0x13ff3ed, 0x1388cb3, 0x1a5dd2f, 0x07b04b5 }, + { 0x0c5faf8, 0x035e3c1, 0x025d6d5, 0x1d1d702, 0x1a734c5, 0x1c28f00, + 0x1a1879d, 0x03e7aac, 0x1e956d5, 0x19d0809, 0x0f0df20, 0x0e63878, + 0x0cc7351, 0x1060a47, 0x1dce3ef, 0x1de82c0, 0x0bbe1bb, 0x1976378, + 0x1e94615, 0x0558dd9, 0x0df00aa, 0x0bb371d, 0x01ca40b, 0x045adc6, + 0x15089c6, 0x017e6a6, 0x0e9b760, 0x15c4364, 0x0863723, 0x0d2a99c, + 0x08b9519, 0x151b030, 0x05119a0, 0x14bbd6c, 0x00c8de1, 0x189e29a, + 0x1c7b272, 0x0d840e4, 0x18c7145, 0x1499337, 0x01c6a95 }, + { 0x0821363, 0x0a56ae1, 0x18729ac, 0x069a2fb, 0x029c182, 0x16f4244, + 0x14b1332, 0x04f5deb, 0x182489e, 0x009559c, 0x07649fd, 0x0131e10, + 0x1f92c9c, 0x1ae5d68, 0x01ef7d1, 0x13f62df, 0x0b81a1d, 0x17a556d, + 0x1d7cedd, 0x14f2476, 0x08fe475, 0x0b6dddd, 0x067742b, 0x0e1568b, + 0x161644b, 0x178c1b7, 0x04d2f66, 0x148c910, 0x1abda32, 0x11375d4, + 0x1ed7244, 0x1ccac4b, 0x0ec8709, 0x0725f26, 0x0678206, 0x19a9672, + 0x14f6879, 0x004e420, 0x1932697, 0x0046150, 0x072708a }, + { 0x14a466c, 0x1e058f9, 0x16e93cc, 0x18ff3a8, 0x01bae09, 0x143c2e5, + 0x03fb838, 0x103ae1e, 0x0908808, 0x12638a3, 0x10f68e0, 0x1855760, + 0x12e2416, 0x07637a1, 0x0f69c4f, 0x07c38e6, 0x049c979, 0x095ac83, + 0x0d724d9, 0x05ab616, 0x1b2adb6, 0x111f2e0, 0x0d57adb, 0x02d6a2a, + 0x0b5cebb, 0x08e67f4, 0x07dc25a, 0x1c1030d, 0x085bd59, 0x1cfdb0d, + 0x1df2197, 0x1f5c207, 0x169d3cc, 0x13f4ef8, 0x11cdcd1, 0x072a4b8, + 0x0369511, 0x1aae05a, 0x17485f6, 0x098e64c, 0x07491c7 }, + { 0x0d2b94d, 0x16adfc0, 0x182cc4b, 0x0774964, 0x1b8ac63, 0x110cd08, + 0x1163358, 0x11d590d, 0x1aeb82c, 0x0be67b5, 0x1e73b4c, 0x13dcb3d, + 0x1a2dfb2, 0x1215e6a, 0x09f6263, 0x16403b5, 0x1c85974, 0x049f14a, + 0x07f16b7, 0x0eaf09b, 0x03ba69e, 0x0f80955, 0x15b11c2, 0x0ba7973, + 0x09f37c8, 0x15e8fed, 0x174f752, 0x0a90fc4, 0x1ba22ee, 0x0580859, + 0x0ec03f5, 0x18dd1b9, 0x1591493, 0x1433265, 0x1eaef39, 0x0d6e653, + 0x08906b7, 0x14e8e13, 0x1a105a0, 0x1cae82e, 0x08bcfd3 }, + { 0x1c8c314, 0x0139a69, 0x00cc1a2, 0x02230e1, 0x15f0b2f, 0x145d0b4, + 0x1df0f01, 0x10f726f, 0x0779247, 0x1b2f06c, 0x04889d4, 0x1cbc3f3, + 0x0f15527, 0x13effea, 0x01a5920, 0x0c71214, 0x1f22f58, 0x0eac59e, + 0x0bc83ab, 0x08d712d, 0x0257834, 0x05a83a3, 0x0275e5c, 0x0454d22, + 0x0d20640, 0x1bcecf4, 0x1d9c7b0, 0x03cbf15, 0x1fe91ed, 0x128482b, + 0x061bd50, 0x0a51208, 0x14dda81, 0x09956f8, 0x043876e, 0x117af00, + 0x105a937, 0x0c68f24, 0x0ad24f8, 0x1ef7a6f, 0x053cadc }, + { 0x053d0ff, 0x0f6fbaf, 0x1d9c6ed, 0x1911157, 0x1886606, 0x10368ae, + 0x0c3e048, 0x066c923, 0x1e22b6a, 0x180c1a2, 0x0ecc5ec, 0x129762e, + 0x15aba67, 0x1ee4f2c, 0x079619d, 0x049a318, 0x0822396, 0x1a70832, + 0x0957754, 0x0a5cb3b, 0x079c617, 0x15cf214, 0x0062d3a, 0x03e57da, + 0x0784b49, 0x14f657b, 0x0879e50, 0x1b9b73a, 0x1262243, 0x0a42887, + 0x170da50, 0x14ca1d8, 0x06f190a, 0x14bb008, 0x16bada6, 0x0cea854, + 0x032d104, 0x1ebaf4e, 0x18ac5a6, 0x0c97f18, 0x0908499 }, + { 0x093c661, 0x0867b2d, 0x015ac4e, 0x093b6be, 0x1848626, 0x0d0bc40, + 0x0ea7694, 0x1352552, 0x16772de, 0x1865dc7, 0x0521f06, 0x1d7af8e, + 0x1e6e67f, 0x0731211, 0x0d0e0b5, 0x085f1f3, 0x10ebb5a, 0x14b7ed2, + 0x022693c, 0x03666ec, 0x0516c92, 0x1dc3af6, 0x1274cb5, 0x0202496, + 0x0d2cac4, 0x1bd5ec3, 0x071087e, 0x0d0c441, 0x17de33f, 0x04d5fb5, + 0x1a0f865, 0x1d27924, 0x1ee18f0, 0x0266066, 0x1578237, 0x05a9db7, + 0x13580d2, 0x1badf23, 0x15fa30a, 0x1f48d19, 0x03d7f6f }, + { 0x1fbd5d1, 0x194866f, 0x037fa9e, 0x0d2e067, 0x1d759da, 0x1f76e4c, + 0x02c2243, 0x11cacd0, 0x142dce6, 0x034857a, 0x19360af, 0x1e57655, + 0x008519d, 0x1f8cadb, 0x04919fd, 0x043e8ac, 0x02cd83c, 0x1b2cd1a, + 0x159458c, 0x0e37eaa, 0x0562557, 0x1aaa45d, 0x17f1a24, 0x125e474, + 0x1920394, 0x00bdaa0, 0x0e72718, 0x0cea51c, 0x1e60195, 0x076a288, + 0x154fc19, 0x03a2d4a, 0x03f9eb9, 0x055f718, 0x13f4895, 0x187c318, + 0x1d434e7, 0x0ca6b7f, 0x1d39902, 0x07edbbc, 0x08fb12d }, + { 0x13cb7a4, 0x1c0d114, 0x1935b18, 0x0170f6f, 0x053e09f, 0x0561f7a, + 0x0a08c1e, 0x1229e42, 0x0578cae, 0x04ffd68, 0x0e9377a, 0x12d4e2d, + 0x004a2b6, 0x1b7ac05, 0x1a06853, 0x0260e28, 0x17b4c2f, 0x089ac7c, + 0x04cbee2, 0x12d32c5, 0x1af7878, 0x0513452, 0x0a77614, 0x0473f06, + 0x11f6dfe, 0x0ced7bb, 0x193d1d2, 0x1e41fa5, 0x1ca0e95, 0x1f3bc33, + 0x1b26d90, 0x06eb303, 0x1858ecd, 0x18e4bf3, 0x096466a, 0x077d28d, + 0x06ff345, 0x0981d10, 0x0dec53e, 0x062eba4, 0x03fcc67 }, + { 0x121f920, 0x0f5eaef, 0x0e41427, 0x1f82803, 0x1af70e1, 0x132557f, + 0x12ff656, 0x0444853, 0x12c37a1, 0x109042a, 0x0e49afc, 0x07e8fbd, + 0x1c1d4c9, 0x0fd9f8e, 0x1cf9302, 0x1788c25, 0x0595b51, 0x12b042d, + 0x043f6f4, 0x1ebac5e, 0x13c22a2, 0x07ef865, 0x183758b, 0x01e4a96, + 0x024a36b, 0x15b8aa2, 0x1559184, 0x074b40b, 0x15249cc, 0x1867d0f, + 0x022faf8, 0x0fcc543, 0x0ec6903, 0x14c9c92, 0x0eb2bd0, 0x0aebe1f, + 0x13fa868, 0x09a2ee5, 0x070d350, 0x1fb8e2a, 0x0645146 }, + { 0x01924f9, 0x0319d5d, 0x1b87b3b, 0x0c00c64, 0x1ba6f13, 0x087e0bd, + 0x15eb1f9, 0x000406e, 0x1ef3d8e, 0x1298c8c, 0x1169d32, 0x0d54a3b, + 0x189545a, 0x098a095, 0x087563f, 0x1a000dc, 0x0057bb1, 0x180de18, + 0x1b46a70, 0x1138d2d, 0x1a48f17, 0x0fcc2c7, 0x1ebcb4d, 0x12f7d0a, + 0x109b981, 0x12ea1a6, 0x14a6a89, 0x1b80eea, 0x18fa801, 0x1df3e02, + 0x13b2b40, 0x0a97429, 0x0d70a9f, 0x0853a49, 0x1415b01, 0x14db8f0, + 0x0d005dd, 0x1e5254a, 0x07cb8a9, 0x0e557f7, 0x0448d3d }, + { 0x1b33989, 0x178a294, 0x056b715, 0x19535d0, 0x068351b, 0x03a20a4, + 0x1584d2c, 0x07767e8, 0x03cd9f3, 0x0ae7215, 0x1b928e5, 0x09d8bfe, + 0x1113ade, 0x1287554, 0x0ab1c56, 0x1dfbfa7, 0x0995666, 0x10630f6, + 0x1a911c2, 0x145171e, 0x04c9108, 0x0272a42, 0x100bbd6, 0x1c5e66e, + 0x1b162d0, 0x05e5c12, 0x1ed1bdf, 0x1b9a263, 0x12fd893, 0x1c764b7, + 0x1e08205, 0x04b2518, 0x18c5d67, 0x1e22ca6, 0x0f7e658, 0x1e50b46, + 0x192a309, 0x04b8bae, 0x06695c9, 0x0f396e0, 0x0768814 }, + { 0x1767eed, 0x1d08a48, 0x176ee90, 0x1b257ec, 0x1e11b9a, 0x12f10d2, + 0x0b3800e, 0x02bd144, 0x12a3354, 0x1b02210, 0x1ab5898, 0x0768953, + 0x05c2c56, 0x1059577, 0x1018992, 0x1c3ae97, 0x1758bf2, 0x0badc6a, + 0x0228997, 0x1e1dcfa, 0x12a71cf, 0x0ed85b8, 0x05e4538, 0x030d25a, + 0x125d04b, 0x00ae1ac, 0x115b33a, 0x1c4a7e9, 0x1f0e3ad, 0x120e4ff, + 0x06691e4, 0x1bb57da, 0x0b9d06e, 0x1728328, 0x098167e, 0x00ce26a, + 0x132ce18, 0x1b007da, 0x0189bcd, 0x038bcb5, 0x0670eb0 }, + { 0x1cdbb43, 0x1e057b9, 0x06b77dc, 0x0afe486, 0x0f08ecc, 0x0d1c22e, + 0x01504a8, 0x1e322f0, 0x09224dd, 0x0d08279, 0x11fbfda, 0x071b7d5, + 0x024352f, 0x1e16899, 0x0eced39, 0x168edf8, 0x030b5e4, 0x0534f4a, + 0x1d691bc, 0x0646812, 0x0ece7d9, 0x0f2eb27, 0x0024e26, 0x0468bd3, + 0x01250db, 0x0b5bdc1, 0x09fd2de, 0x06aa526, 0x190b1f2, 0x060aa5d, + 0x158bba7, 0x12225ef, 0x1a9c8f5, 0x157190f, 0x1e6072e, 0x145a1e5, + 0x0075166, 0x1f81b30, 0x1fc9edd, 0x1cec6bb, 0x0504852 }, + { 0x0f392fa, 0x19e72d1, 0x01e0bc3, 0x15d8d92, 0x126c076, 0x1d557b1, + 0x17a4a12, 0x1275a03, 0x1cbe8e9, 0x00d8b69, 0x142422c, 0x18485b2, + 0x1871305, 0x1c29d79, 0x1bf585c, 0x053418c, 0x00ed3c4, 0x1bb9a8a, + 0x1eafc09, 0x0362543, 0x11778a3, 0x0102c59, 0x0814c00, 0x18fbd73, + 0x1d9fca9, 0x09855ff, 0x0fa199f, 0x00bded3, 0x09e13fd, 0x198474d, + 0x070bce9, 0x1723d5d, 0x14c9a19, 0x073621f, 0x1b9d863, 0x00a1a19, + 0x1240f8b, 0x126e202, 0x03313ec, 0x0a3efd2, 0x0992fe1 }, + { 0x0f197aa, 0x06d989c, 0x1e61115, 0x1b0f0e5, 0x04ded69, 0x1854145, + 0x09ec113, 0x18d2f68, 0x0a31e48, 0x010f0d7, 0x03bfb26, 0x013fbb3, + 0x0ee38cb, 0x040659d, 0x0e13ea1, 0x0aae641, 0x0a84747, 0x1dd2dda, + 0x1543a5a, 0x1c10159, 0x1550a9b, 0x0e77881, 0x111147a, 0x08264b9, + 0x0e75fc4, 0x19eb137, 0x00e2978, 0x1dd4bd3, 0x10abd26, 0x1f5cd15, + 0x0a5cc86, 0x136c105, 0x092e484, 0x1e61565, 0x1a2a64a, 0x163b902, + 0x1c8eb9f, 0x0767a5c, 0x1c7804d, 0x15098b6, 0x05a68bf }, + { 0x10a2bfb, 0x19da2ff, 0x02c2d3f, 0x12aa05f, 0x1105fff, 0x0e06136, + 0x162156c, 0x00829bc, 0x10d3b9d, 0x08b432d, 0x14e45fb, 0x08a604d, + 0x0e2f5a2, 0x1a6d9e0, 0x08bd24f, 0x11e5cd4, 0x08ae241, 0x0a438aa, + 0x026fbd8, 0x06c750a, 0x1bec6ab, 0x1d5c65d, 0x0472878, 0x023472d, + 0x0dc9840, 0x0bbb8f0, 0x0835729, 0x1f305c1, 0x097bc1f, 0x1822c0c, + 0x19fad02, 0x010b5ab, 0x1c24a46, 0x1bdbe25, 0x1e8298c, 0x1fa2b91, + 0x1ef1628, 0x07377bd, 0x1d0e55b, 0x1f33ebd, 0x078acfd }, + { 0x0520189, 0x1bf8afc, 0x071116f, 0x018efec, 0x154202a, 0x11170dc, + 0x11ae77e, 0x10e73db, 0x11f4a34, 0x16b0133, 0x13314b4, 0x1252902, + 0x03cd933, 0x02f4f89, 0x1da8490, 0x16defbc, 0x0a0ae36, 0x0711837, + 0x00e9638, 0x02a4317, 0x031a538, 0x1b50209, 0x0618aed, 0x0637ce3, + 0x0253cbf, 0x10ff46d, 0x08df7a1, 0x1bf8a66, 0x0e48902, 0x09fb485, + 0x14bc972, 0x11754dd, 0x0bcb8f0, 0x1a514b3, 0x183e422, 0x12de215, + 0x1061c94, 0x1a5a465, 0x08d9a32, 0x0e7a0eb, 0x00ad92d }, + { 0x0ca548a, 0x0aff6e1, 0x06aefee, 0x01019b1, 0x0778c62, 0x1361402, + 0x0552cd1, 0x0057d32, 0x1d4be89, 0x11df049, 0x1a07b7a, 0x132a27c, + 0x01847b7, 0x017a00b, 0x0aa3d2c, 0x0ffd1e4, 0x14d4aeb, 0x11f7965, + 0x0ebb57d, 0x18a2a36, 0x11639ad, 0x08cc618, 0x1b0733f, 0x1afb11f, + 0x0c17ba3, 0x04bee15, 0x0d19084, 0x11f4c9a, 0x190bcf0, 0x005bca5, + 0x1ad7afe, 0x016a153, 0x178b4ba, 0x153358d, 0x04d09e6, 0x1a349fd, + 0x075b3ce, 0x1a6e578, 0x1a6ba3b, 0x140e14d, 0x095bbd8 }, + { 0x014bbd0, 0x0924af3, 0x0d8d67e, 0x0f7047c, 0x1567a88, 0x0deb53b, + 0x127b3f0, 0x085c48f, 0x18e835c, 0x1fd57a3, 0x1819a8a, 0x09c155b, + 0x16314ef, 0x0e0b699, 0x0aea98d, 0x1c7120e, 0x071e2f0, 0x1fd214e, + 0x141f643, 0x03cba17, 0x1c04cac, 0x1528a7a, 0x1a7fcd7, 0x0aa9d82, + 0x053fcc0, 0x03fc498, 0x1ca8d65, 0x163b0d6, 0x0be487a, 0x1830157, + 0x0878a7e, 0x1bf739e, 0x0a10d6d, 0x0fe7ad0, 0x0167c83, 0x155a28e, + 0x18867a2, 0x06e337d, 0x0a46520, 0x09f824b, 0x0375a88 }, + { 0x017f7ea, 0x05f1709, 0x16ac5e3, 0x150eb8d, 0x1a161e2, 0x0d8d2a0, + 0x1fb006f, 0x195eee0, 0x0e4fd73, 0x1c43250, 0x0836199, 0x0cc9a27, + 0x08baebc, 0x0469833, 0x0c97e67, 0x0b2a080, 0x1c92f1c, 0x1dc9f6c, + 0x1078199, 0x06cec6a, 0x0763fdf, 0x185c8d3, 0x1f65fee, 0x0f39341, + 0x069ea60, 0x0239355, 0x007aaa3, 0x0e60790, 0x063c55c, 0x0e40d7d, + 0x16f7b1d, 0x09fa255, 0x1cdcde2, 0x041c500, 0x169c65a, 0x133fc1b, + 0x1841537, 0x1d849d9, 0x013b19a, 0x1161197, 0x0268d81 }, + { 0x1580555, 0x171ac20, 0x00edcf6, 0x0e8e7a2, 0x0fc32e6, 0x0660d5a, + 0x0404efb, 0x1bc4818, 0x0b24ee9, 0x1204cf9, 0x03819b6, 0x16b73f5, + 0x0e37b0c, 0x121c6bf, 0x0b81391, 0x002816b, 0x1642b72, 0x03fbe98, + 0x0e7929e, 0x1e9db66, 0x037586e, 0x169d3ec, 0x0979dfb, 0x0e0f85d, + 0x1ad37bd, 0x0c4c41f, 0x083e5e4, 0x02d6c67, 0x1a208e8, 0x0145173, + 0x1ab8930, 0x0886aa2, 0x171fe3c, 0x195fa88, 0x0ccd3d7, 0x0c7d727, + 0x01b53a5, 0x0cf6a58, 0x0912e10, 0x0b80ad9, 0x08b0273 }, + { 0x1019195, 0x1da3270, 0x0306e26, 0x0de7f85, 0x1de4c02, 0x1e1d908, + 0x039b8af, 0x05f5824, 0x091bdf9, 0x038de2d, 0x056f27b, 0x15681b3, + 0x1e485d7, 0x13248ff, 0x119da3b, 0x1c4cb2f, 0x119afbc, 0x16caa96, + 0x186ddb0, 0x0d8ffd1, 0x0d1bbae, 0x00ebf1d, 0x059f60a, 0x1312e68, + 0x09af95e, 0x0c11f0a, 0x1228320, 0x03e0049, 0x006c0dd, 0x1fede18, + 0x133d5c7, 0x0b0ee7a, 0x12ecf7e, 0x0a06c59, 0x1e0bf4d, 0x04b0454, + 0x0436504, 0x1a2e1f8, 0x017f96a, 0x140969b, 0x0400e3a }, + { 0x046e4a2, 0x10b24af, 0x01d11cc, 0x084826c, 0x17a2ed6, 0x0763be9, + 0x08ec718, 0x05ccb24, 0x1e5e0ac, 0x109d561, 0x01eadd7, 0x08378a2, + 0x1bda17c, 0x19e129e, 0x0c8bb25, 0x0452ccb, 0x1b8a501, 0x1ff9c33, + 0x1886a66, 0x0cc1aa0, 0x03f5fed, 0x03644fe, 0x08f0a14, 0x0c8a34f, + 0x150b9f1, 0x0379f69, 0x099f2d6, 0x0f87c06, 0x1185b12, 0x03bccb3, + 0x06f201f, 0x0942601, 0x1c157d4, 0x18fa684, 0x191eb6b, 0x106c5ee, + 0x13a6a19, 0x015cd67, 0x180e529, 0x1451b4d, 0x0131c3d }, + { 0x1da83ba, 0x02ff8d3, 0x10d929e, 0x0ba09e8, 0x1415b42, 0x01fc097, + 0x066f7b0, 0x144f811, 0x080f5f4, 0x0c6a08d, 0x0946e71, 0x0c21fb4, + 0x123d32d, 0x069d979, 0x0ed1413, 0x0107933, 0x04bf4c2, 0x08cc622, + 0x0c3a0ff, 0x04c35ee, 0x1b9060c, 0x0fe5816, 0x0183293, 0x1e3cf90, + 0x1838b9d, 0x06487fb, 0x1f131a4, 0x16f39f2, 0x15f1546, 0x0a6baeb, + 0x1fc4c54, 0x03961d1, 0x1c074f1, 0x0bb0ad3, 0x0b06cb0, 0x0172415, + 0x04aa0ff, 0x004c56a, 0x173a77a, 0x0d468a8, 0x071d1a4 }, + { 0x01b382e, 0x1c7bb7d, 0x0835d85, 0x06ee5bb, 0x00d8ecc, 0x0a68985, + 0x0acab17, 0x05954b5, 0x08d7262, 0x1e9c5d2, 0x0fb4189, 0x1b6d947, + 0x0fc5410, 0x1c9e766, 0x0de9621, 0x1c7afec, 0x0fd6e65, 0x08fb2ed, + 0x0291590, 0x08950ac, 0x140bc3b, 0x1427bc2, 0x03d1ece, 0x09ac1ec, + 0x1dadd5e, 0x16ac127, 0x105f4ed, 0x1199f21, 0x1fc13ad, 0x15ef992, + 0x0e4023a, 0x06c91f5, 0x090d716, 0x096a59f, 0x1ce8931, 0x1672c9f, + 0x133d0ac, 0x0e620b2, 0x1d486e5, 0x13e22cf, 0x06cd269 }, + { 0x0f4f3ac, 0x0059d89, 0x17ecb63, 0x0533a37, 0x103dcfe, 0x19b9935, + 0x0d3e0c3, 0x104a800, 0x17c5a8c, 0x16eb449, 0x1c51088, 0x07a19b1, + 0x12eb709, 0x0c2ba17, 0x09e569d, 0x1b5bb12, 0x02c087a, 0x170af94, + 0x1aaded7, 0x1b8e922, 0x0bb47bb, 0x05d2c56, 0x14c3f90, 0x1758737, + 0x017ebe2, 0x05e06f2, 0x1b18681, 0x1696334, 0x1355694, 0x01a6f93, + 0x1be4ce3, 0x0615632, 0x0f03742, 0x064b2f4, 0x12e1b22, 0x0df45df, + 0x07eeb82, 0x17713a6, 0x1770867, 0x07fb468, 0x0327c06 }, + { 0x147cd53, 0x0cf7fad, 0x1bfaace, 0x1a32875, 0x1be9869, 0x0154335, + 0x131ec50, 0x02dcc9d, 0x0b1c25a, 0x1f3e155, 0x1789c70, 0x16f2045, + 0x1fc4216, 0x1b36b52, 0x037f320, 0x0666dcb, 0x09eda81, 0x068aca8, + 0x0c2fedf, 0x0801e42, 0x0780370, 0x0cc9da4, 0x06f9381, 0x1e79a44, + 0x1a1fe39, 0x1c38311, 0x0bbb2d3, 0x0554456, 0x07b83b7, 0x024b361, + 0x0fc6bd3, 0x1b4bf4b, 0x042a94b, 0x00d793d, 0x008922c, 0x1935f75, + 0x1670112, 0x15ce951, 0x1a15bad, 0x1a381be, 0x0020f19 }, + { 0x0dbba20, 0x08d4352, 0x1714dc1, 0x0db63bc, 0x1618ebc, 0x092c205, + 0x0286799, 0x09b34f0, 0x1d2bccc, 0x0201816, 0x0168925, 0x047a205, + 0x08e9ff0, 0x1d24313, 0x04dfb8c, 0x0228e77, 0x0f24cd6, 0x1f1bf71, + 0x0f415f3, 0x177fa74, 0x0fce79f, 0x09e66ef, 0x17ee85b, 0x0462e4e, + 0x058ec5b, 0x16dc8b0, 0x19c830e, 0x0ed33d7, 0x0f6bba4, 0x01c345a, + 0x1c0989d, 0x1e3140e, 0x0b0092a, 0x108b02a, 0x03aeb32, 0x0133a12, + 0x0c888f6, 0x0bf0ff8, 0x01513dd, 0x041600a, 0x079e727 }, + { 0x020a239, 0x1679294, 0x0c418ca, 0x1d55cd6, 0x11a3974, 0x0050efd, + 0x15ae923, 0x155ac3f, 0x15a3ee7, 0x1229e1c, 0x0111b74, 0x0b41730, + 0x0f54845, 0x0f0b33b, 0x0a765ef, 0x0eb433e, 0x00c7893, 0x0f92965, + 0x1d0ea61, 0x035e7ce, 0x1d8de96, 0x0b3366d, 0x1c31e71, 0x18a71f2, + 0x1854ecb, 0x08e0a51, 0x0a849a1, 0x11b54e7, 0x1f558c5, 0x1da2954, + 0x017a6d6, 0x1f7a2bc, 0x1af7f83, 0x0c9ce9b, 0x049ce28, 0x0d4890f, + 0x1511a05, 0x14595ac, 0x011b790, 0x1c6e02b, 0x0001d3c }, + { 0x145b1d7, 0x11b5cf0, 0x19935af, 0x140138a, 0x13e3938, 0x007b6df, + 0x0b9f79f, 0x0725cac, 0x0c343f5, 0x0882273, 0x025ec65, 0x0571b21, + 0x1ca5ab6, 0x0897bcb, 0x087dc2d, 0x051c963, 0x154750f, 0x0c8e6eb, + 0x1ee0597, 0x101c5ff, 0x02b3b4c, 0x03aca68, 0x197b4e7, 0x1067db8, + 0x0a49d56, 0x10c6609, 0x13cda4e, 0x0e6d297, 0x12c404e, 0x09a57e6, + 0x050d330, 0x023a803, 0x11bd5fc, 0x02f2303, 0x011ff16, 0x080aeb2, + 0x190b7a0, 0x1401b03, 0x11a12cc, 0x1f8815f, 0x04bb8c6 }, + { 0x10f8796, 0x0716efe, 0x0778c48, 0x1b62679, 0x0968a40, 0x1b4e373, + 0x19b02a4, 0x077fd46, 0x0600727, 0x1f2db6b, 0x0050e4d, 0x19e1197, + 0x0539e4e, 0x0ff5e00, 0x1ffa736, 0x16a7890, 0x0440199, 0x1f5c57a, + 0x04d467a, 0x049c765, 0x1c162f1, 0x0564164, 0x0183086, 0x13b8b21, + 0x1d6f270, 0x094d668, 0x14db541, 0x0d2daa8, 0x120bfc5, 0x0efcac8, + 0x04300fd, 0x021ff4d, 0x1a3e88d, 0x19413cc, 0x1e95b10, 0x13a9f39, + 0x1a135d8, 0x07f54f4, 0x1f9e0ba, 0x1036d4e, 0x03699a8 }, + { 0x0b1c64d, 0x119b90f, 0x05516f2, 0x1be3a50, 0x09cf3a2, 0x1b8837f, + 0x1a6cd94, 0x09b6fc5, 0x14f7cbf, 0x160b8a8, 0x02cdfc1, 0x02dc40b, + 0x05cbde4, 0x041a74e, 0x114e9fa, 0x074eb05, 0x1e2e9ac, 0x14a6def, + 0x1799f00, 0x1d8d978, 0x080d795, 0x0f8a135, 0x0308f09, 0x11a9f3f, + 0x0d20d6a, 0x11af716, 0x134edf0, 0x071b54a, 0x1a4d528, 0x07601eb, + 0x1cee782, 0x0f03968, 0x09475e9, 0x18e5565, 0x0e797b0, 0x0ee4e3e, + 0x0253518, 0x18474fc, 0x1fe2c77, 0x0064115, 0x04f3a4b }, + { 0x0d095f8, 0x1c0838f, 0x15383de, 0x0db444d, 0x03e37fa, 0x19b68e9, + 0x0614abe, 0x023161f, 0x007d8e3, 0x08a31a7, 0x03c5bac, 0x152fc7c, + 0x17b9634, 0x010f761, 0x152ee71, 0x0438248, 0x1dbd72b, 0x05a766a, + 0x17c835f, 0x0070d0d, 0x00a2f96, 0x1eefc37, 0x07d4d67, 0x1891155, + 0x154fa5a, 0x0fa621e, 0x0f44127, 0x0dae295, 0x00607a5, 0x159f581, + 0x1784c54, 0x0f40464, 0x1be1c18, 0x1426da4, 0x1d294ab, 0x0089e49, + 0x0b5a7b8, 0x092e018, 0x1e7f679, 0x08d4da2, 0x06d8744 }, + { 0x09a42f5, 0x083d55f, 0x13234a7, 0x186f039, 0x1fd5316, 0x034f508, + 0x169b677, 0x034e34e, 0x188fee9, 0x10cf06f, 0x113c493, 0x09b9f1a, + 0x0499c2b, 0x18d74a7, 0x1db7e48, 0x199840b, 0x076cf28, 0x193fdd4, + 0x15fdf3a, 0x141e03e, 0x1b746e1, 0x1a79fe9, 0x180fc7c, 0x183a427, + 0x1c4a742, 0x0c05076, 0x01f7ae1, 0x195584e, 0x0848bc5, 0x1c8fd78, + 0x0743d75, 0x00f58eb, 0x1f514ad, 0x1e2988b, 0x1cd2413, 0x1b2b472, + 0x1bb70f3, 0x125654b, 0x1582656, 0x193ff38, 0x03cf384 }, + { 0x01fc9e3, 0x0835d67, 0x0e65c01, 0x04ced60, 0x0972174, 0x15fbd9a, + 0x06e379c, 0x1ee5694, 0x079b209, 0x1430154, 0x1aa3872, 0x17219c4, + 0x1a90580, 0x1f1279c, 0x1cce6df, 0x0c5c23d, 0x1916293, 0x05b62ec, + 0x1dec93d, 0x0e9c34a, 0x11e9511, 0x1a82f22, 0x1ce03f2, 0x106437b, + 0x17afb14, 0x0957a6c, 0x0dd1f97, 0x13300d7, 0x19a6080, 0x0eb2df4, + 0x0821549, 0x1a8abd0, 0x04828d9, 0x1053293, 0x1017615, 0x011918a, + 0x1103077, 0x13f39e3, 0x17c98f1, 0x0a1dce7, 0x02b2488 }, + { 0x141159f, 0x1e6f342, 0x02c885c, 0x109f682, 0x18224c1, 0x1650e3b, + 0x018647c, 0x0800f45, 0x0a8b23e, 0x16103eb, 0x08d1294, 0x04214d6, + 0x05071a0, 0x1af694a, 0x03961f2, 0x198d9b6, 0x0ef810f, 0x0b62b5c, + 0x0b610ee, 0x118b1ec, 0x0975124, 0x1eba633, 0x12e40d8, 0x0d8cdec, + 0x0f7f2e6, 0x05f31a4, 0x07049af, 0x05f3a88, 0x0e49e8b, 0x1951b9e, + 0x1c2b01f, 0x1d0361b, 0x0486758, 0x110e8a9, 0x1534751, 0x1942116, + 0x14414a1, 0x130f673, 0x108545c, 0x198d475, 0x0938b3b }, + { 0x0ded340, 0x050b5f2, 0x00daa79, 0x1501d10, 0x0e65fb2, 0x0b9d65c, + 0x0581b73, 0x1532e11, 0x0aaa657, 0x01d021a, 0x006c187, 0x18b0922, + 0x0cf304f, 0x0d05db2, 0x03ed86b, 0x05bebcc, 0x0ecf554, 0x1c0c615, + 0x1bddb57, 0x040aeca, 0x1d97740, 0x0849299, 0x0d59ade, 0x1add6bf, + 0x055e574, 0x05bd723, 0x16956d1, 0x01ef436, 0x147ea56, 0x0bcdc9b, + 0x159e5c0, 0x1e5b59c, 0x0e7e0e8, 0x01e0345, 0x181e13a, 0x03308e8, + 0x1530734, 0x1464f68, 0x075ac93, 0x14bb3d1, 0x06cff58 }, + { 0x1e51f68, 0x000d801, 0x1f59423, 0x0a3a5fc, 0x01d1f22, 0x1ec402f, + 0x0342c26, 0x16fef33, 0x003e415, 0x0af483d, 0x165e609, 0x0cfac0f, + 0x16d1484, 0x0da29c4, 0x170ec7a, 0x0a1e80a, 0x013809f, 0x01a8008, + 0x008cff7, 0x165f4da, 0x00b8fbb, 0x057f8c1, 0x02da02c, 0x1a62fc0, + 0x004dc38, 0x1efd8ea, 0x1333231, 0x067aa88, 0x013f841, 0x03f3376, + 0x121fea1, 0x008dc5c, 0x13f83d8, 0x1d9d661, 0x1f15218, 0x0e78c4f, + 0x0b936af, 0x13fc557, 0x04c9d7d, 0x11e636f, 0x05fe4ac }, + { 0x16f401e, 0x1525fc5, 0x1b51606, 0x075ab8f, 0x05db12a, 0x183da50, + 0x01c99be, 0x1a8f603, 0x09c22bc, 0x0e88f82, 0x1c7257f, 0x0fa8d26, + 0x0f5454a, 0x0cd2375, 0x1b157ee, 0x12da00c, 0x07c7fef, 0x00c31be, + 0x0e0fa57, 0x183a68d, 0x02dcbaf, 0x09805da, 0x1570e16, 0x1cfce24, + 0x1ec2b34, 0x1746ec6, 0x02c6133, 0x13939f6, 0x0278646, 0x062124d, + 0x19e3730, 0x04021e5, 0x10d95f2, 0x1d21014, 0x1325a5d, 0x1b0dc4a, + 0x0b2abda, 0x098e44f, 0x0152082, 0x0c82438, 0x0813771 }, + { 0x05a8edf, 0x1592f4e, 0x1eb5899, 0x0420f14, 0x0e1388c, 0x1b776fb, + 0x1cdf521, 0x02ebe04, 0x1627446, 0x017d3fc, 0x14e0a89, 0x17b3670, + 0x0f3e2cf, 0x017b8df, 0x16b5ec4, 0x0152575, 0x0fa677d, 0x02b155e, + 0x07f7fcd, 0x1d7a2ea, 0x0c78573, 0x093e128, 0x15fd961, 0x0f9512d, + 0x116eec4, 0x04f7067, 0x019d88b, 0x199af36, 0x12c0758, 0x0c417c7, + 0x054c7f1, 0x14c010a, 0x032b37e, 0x062dd49, 0x0d860ba, 0x1c9af76, + 0x12f146f, 0x1239ae6, 0x16e62fc, 0x1dd39a5, 0x079c280 }, + { 0x0b48122, 0x04101f9, 0x123af73, 0x0d60958, 0x08c0491, 0x02442f5, + 0x193727f, 0x03959e0, 0x182c100, 0x1c1c4cb, 0x178942a, 0x0e42ced, + 0x007339e, 0x070d5c1, 0x0a96baa, 0x0965c2f, 0x0a06bc1, 0x0126946, + 0x05ad88c, 0x18b76f0, 0x1606570, 0x0e67735, 0x1b1448d, 0x07d5c84, + 0x1f89f18, 0x1a58d95, 0x1a71989, 0x1c75e78, 0x1e38bc3, 0x02135a8, + 0x0ef82c1, 0x0e7c81c, 0x0dbc58e, 0x12df213, 0x15e2d6f, 0x107f3ba, + 0x12c8f40, 0x0cfbc8a, 0x1fd3e7f, 0x14953c7, 0x0758073 }, + { 0x091ca22, 0x1d82bc3, 0x06d9f49, 0x0c27454, 0x1206bfd, 0x1caa09f, + 0x14e16b1, 0x00fd097, 0x0755366, 0x0e8c515, 0x0389331, 0x1bcf914, + 0x1d2e166, 0x1e23a6d, 0x155d430, 0x10874ad, 0x0c11366, 0x16f7a22, + 0x1d2e10c, 0x08dca79, 0x1783146, 0x1854fec, 0x12f0340, 0x0fdc406, + 0x0c82429, 0x163ded2, 0x1ff5ef9, 0x1a16217, 0x07f3ff3, 0x123b046, + 0x114b485, 0x169fa98, 0x0e52599, 0x0f08203, 0x1e8527a, 0x1bf7573, + 0x0661d32, 0x0153fd4, 0x1aaa24d, 0x0b1f5ec, 0x03f3e34 }, + { 0x11597aa, 0x01ad7ca, 0x13ad47b, 0x1893bec, 0x1677d4a, 0x1a77fad, + 0x136726f, 0x06a04ed, 0x1515a29, 0x11f6524, 0x0ee70d0, 0x0aa7fb3, + 0x1c8a696, 0x16f0f84, 0x07ba77f, 0x0bf31f3, 0x156199e, 0x15c7d14, + 0x14a4b0c, 0x070eb06, 0x081bb76, 0x0e7e207, 0x01cd3b7, 0x08afb2b, + 0x15e9f65, 0x095ec16, 0x18c31e3, 0x11dc647, 0x033d67c, 0x172660a, + 0x0bb9dec, 0x0790629, 0x0d9f807, 0x117b1ab, 0x1788a83, 0x1c883dd, + 0x0c48295, 0x0f0bf6b, 0x053bc7a, 0x1886985, 0x0640d20 }, + { 0x084d513, 0x105c719, 0x14e93a6, 0x0be62a0, 0x074c354, 0x166a950, + 0x1d01d16, 0x16f66dc, 0x01de50d, 0x005ee7e, 0x07f11b6, 0x0fb84a9, + 0x088d9d4, 0x181f83d, 0x0dbbc4c, 0x1a98453, 0x0ca6d4a, 0x1a7230d, + 0x127c6dc, 0x1c6a3bf, 0x0e65ca8, 0x06aba30, 0x02f1025, 0x065a6cf, + 0x02b330f, 0x1745b18, 0x18a15d0, 0x1340e96, 0x0c29c36, 0x1588c3b, + 0x1eb7f94, 0x12257a2, 0x19e4609, 0x1531cf9, 0x1598d26, 0x031dc81, + 0x072e05c, 0x1448156, 0x0a05ae5, 0x15181b2, 0x00f9c1c }, + { 0x1433df3, 0x1d559b3, 0x0a307ae, 0x0e2ba6c, 0x16aa534, 0x1862e65, + 0x083625f, 0x1f22746, 0x165e408, 0x1648c65, 0x1cd145c, 0x10a9aa6, + 0x094b638, 0x05a6e50, 0x04e668c, 0x0264ce6, 0x1300a3b, 0x06792b3, + 0x1822ce2, 0x0c1bf4c, 0x0dfd5ea, 0x183d948, 0x162b5d2, 0x0d29f36, + 0x02789d7, 0x1d8c190, 0x02d98c3, 0x10b27b7, 0x1e3eaf4, 0x1fb8632, + 0x1e0f6d1, 0x07ce4c7, 0x1949c91, 0x17f99b1, 0x1b1b9b9, 0x0137359, + 0x098a824, 0x1ecdd38, 0x1bb14d2, 0x05e8ba6, 0x07e31c1 }, + { 0x1fd2dd7, 0x00eb406, 0x0762f8a, 0x004956c, 0x1efacb0, 0x018fcb8, + 0x0017e51, 0x1797386, 0x0959cb3, 0x10646fd, 0x0ed0199, 0x18619ff, + 0x0dfdd5f, 0x1cb4d08, 0x118c6f9, 0x1fa36f4, 0x09ede13, 0x119b718, + 0x1251c1d, 0x077f5bf, 0x022376b, 0x0eee639, 0x1ea4649, 0x0d89dc3, + 0x10d7315, 0x1a3ba0f, 0x0438acd, 0x1ec9dc8, 0x04d93c4, 0x0969f7e, + 0x0ba1afa, 0x1f89f76, 0x13b7e03, 0x050dde2, 0x13d4cdf, 0x015832d, + 0x1e23ba6, 0x120d183, 0x14d5d37, 0x08a64da, 0x01a219c }, + { 0x04db0bc, 0x1bf7c55, 0x058ff73, 0x0cf6d93, 0x0e23180, 0x050c979, + 0x0419cf6, 0x0e384c7, 0x0ffdc77, 0x0676171, 0x103b6f0, 0x1c6b45f, + 0x03997c8, 0x0166302, 0x1843b06, 0x10240f1, 0x0cb2b0c, 0x17e86f1, + 0x0795fe3, 0x188afed, 0x11c34d6, 0x192da9f, 0x054f9a6, 0x1f13971, + 0x0330ac4, 0x1f32115, 0x065559a, 0x05fe465, 0x1442d19, 0x0816a1b, + 0x00dcf35, 0x17d4d28, 0x04ce590, 0x1833178, 0x0dfbe00, 0x06d582a, + 0x16d0bf9, 0x15e7bbd, 0x064bf80, 0x1337920, 0x017aaa9 }, + { 0x055db2e, 0x0ab21c7, 0x014434f, 0x067728d, 0x035dee4, 0x042317c, + 0x103956e, 0x0f83428, 0x1ea17e2, 0x17f9d9a, 0x17dea69, 0x186dbb2, + 0x0f23f99, 0x1eeb396, 0x05ff766, 0x08b80e4, 0x01edd20, 0x0fa0056, + 0x1fc1ac9, 0x0ab90e9, 0x09be94b, 0x1287252, 0x0291283, 0x076d026, + 0x05e91b4, 0x162f449, 0x04853e5, 0x117dbbc, 0x17fa977, 0x152607c, + 0x19c3d15, 0x14b7fa4, 0x08fd86b, 0x10477d1, 0x163ef9d, 0x1876965, + 0x026474b, 0x0affc61, 0x0c92bef, 0x1e14be7, 0x06b282a }, + { 0x141a595, 0x0012fb1, 0x0a31e3f, 0x0d488bc, 0x191c38d, 0x0234212, + 0x1b8f7ad, 0x066e57a, 0x1755478, 0x1ca3369, 0x185b10f, 0x09a6107, + 0x1491141, 0x0ad3d65, 0x176519a, 0x1f6c828, 0x1098fd2, 0x08816ef, + 0x0ff61ec, 0x165a5a1, 0x10882a2, 0x0e2ca2a, 0x1a7a6f9, 0x0048bbc, + 0x18bf4a8, 0x187771b, 0x02c8c1a, 0x01617ad, 0x1e9f3d8, 0x02e3615, + 0x115da95, 0x0900584, 0x09d167b, 0x096fda1, 0x109cad0, 0x0427cc8, + 0x0e8d976, 0x127a94f, 0x1bafed9, 0x046a8e0, 0x06d4f5d }, + { 0x0ba9f88, 0x0795b00, 0x02fcd72, 0x00f76da, 0x1dc807e, 0x1c0f2df, + 0x1b50ace, 0x03c1424, 0x0a7ac78, 0x1ae7367, 0x172e98c, 0x1cdfe6f, + 0x073e308, 0x11e4b24, 0x0372989, 0x0869a05, 0x17e8818, 0x13975d2, + 0x06de289, 0x07ab3ef, 0x0ea3a9e, 0x0e9783d, 0x14bc29f, 0x1a0bee9, + 0x0467824, 0x15b707f, 0x00045b7, 0x0410a2e, 0x137580b, 0x0f492c7, + 0x0ce70a9, 0x0e80e17, 0x18bd7a5, 0x1bec873, 0x01cae65, 0x08aa3f9, + 0x00db81b, 0x0d49e22, 0x0d2b5bb, 0x09facba, 0x04aaf0b }, + { 0x114c7af, 0x192831a, 0x1ab66fb, 0x1b78303, 0x109e7da, 0x11f62c5, + 0x0ba1e3e, 0x10bde79, 0x1173b86, 0x06dfd5a, 0x14cb776, 0x1f81243, + 0x06b2490, 0x05ece23, 0x1bce1ae, 0x1b7b69d, 0x12fa061, 0x1e0e6ea, + 0x16f0136, 0x1d31344, 0x063664d, 0x15c2b94, 0x01be60d, 0x1c89540, + 0x1a8048b, 0x06388d2, 0x1825c06, 0x0dbdbc9, 0x011fb11, 0x02bbd96, + 0x165cabb, 0x14e43d9, 0x04dade1, 0x1f9d48a, 0x09af5ba, 0x0ff338a, + 0x1c2e14d, 0x0a0b2d8, 0x18cde87, 0x0730578, 0x08b2cbd }, + { 0x052e991, 0x00df945, 0x0bb0a3b, 0x0d9f3a8, 0x0ba202f, 0x1a75228, + 0x144c318, 0x139060f, 0x1c5762b, 0x1e12bd9, 0x10a8b4f, 0x11a290f, + 0x0abd329, 0x118ca44, 0x053c69e, 0x00da594, 0x13b06ba, 0x0e38654, + 0x19017a2, 0x07e967d, 0x0ae79aa, 0x199aef7, 0x13193ba, 0x17e3a99, + 0x1f57803, 0x1fee8aa, 0x151585a, 0x083d816, 0x0e33f60, 0x0073043, + 0x1d48f7e, 0x1e04879, 0x19a79c8, 0x066ac1c, 0x093a1d3, 0x030d850, + 0x0fc5c83, 0x0775764, 0x0d9c088, 0x008fb7c, 0x057e283 }, + { 0x1cdf666, 0x05b4c7d, 0x0749b98, 0x1317d76, 0x1dd06a9, 0x04c21b5, + 0x0b6ea01, 0x11a8089, 0x0522bc8, 0x1b5fbaf, 0x08ec835, 0x1736508, + 0x12655c4, 0x099cc53, 0x103d249, 0x0ec02cb, 0x0b70ca3, 0x13b6a79, + 0x00c3e96, 0x11324a4, 0x0705469, 0x03db02a, 0x05acdfa, 0x1bc365f, + 0x0f73153, 0x182f7cb, 0x12b553b, 0x1d97791, 0x1617b05, 0x0e85549, + 0x1f7aca2, 0x0f97442, 0x0c0fbd5, 0x0516b9d, 0x0d58675, 0x07a1a79, + 0x091d606, 0x1f74ea6, 0x1f69ba2, 0x06ed2df, 0x04f12e0 }, + { 0x1f1a610, 0x1d2110a, 0x0669333, 0x0a6f0ca, 0x004a5c5, 0x01c09a4, + 0x09151ce, 0x054248d, 0x04b284e, 0x10ada42, 0x144c83e, 0x18ca28d, + 0x1a36464, 0x1854507, 0x1aea231, 0x1009df6, 0x0e793c4, 0x13a73e7, + 0x056b85a, 0x09a4597, 0x14dd8c3, 0x0ffce0e, 0x0767b62, 0x004a6e3, + 0x0866d32, 0x02530d0, 0x0a6f591, 0x0b64656, 0x17bab14, 0x1496793, + 0x00be223, 0x1528916, 0x1e69c6e, 0x10f65b9, 0x1aa56d4, 0x043492d, + 0x1858afb, 0x1bc753a, 0x1be46a3, 0x07d624c, 0x083d233 }, + { 0x1b478d7, 0x1994433, 0x1270718, 0x02a145f, 0x01ee1ae, 0x09120dd, + 0x0acc063, 0x12c0b6d, 0x0893cd6, 0x0f8f944, 0x05ea1da, 0x0cc1502, + 0x17159d6, 0x18739eb, 0x0480465, 0x0be15d0, 0x10093f5, 0x12947f7, + 0x01537ec, 0x0f1b71b, 0x1fbbb39, 0x1b7a2ec, 0x15ad0fb, 0x17dc72f, + 0x04bfed5, 0x0d68bef, 0x05afddb, 0x003c1eb, 0x00754ca, 0x14071ea, + 0x1cca2c8, 0x1f1d0dd, 0x0db6122, 0x0f2c347, 0x1abedf4, 0x17044d6, + 0x0f40a55, 0x1a990a9, 0x0588518, 0x07d8b46, 0x07362f1 }, + { 0x1c0c430, 0x1593e39, 0x195de4b, 0x1f4a386, 0x0cc0a65, 0x0ca78dc, + 0x13b3b48, 0x08ea14b, 0x0814b49, 0x04a2b44, 0x1eefd06, 0x103496d, + 0x08bbf0a, 0x1855430, 0x1bd3d63, 0x0f2bc6e, 0x1683987, 0x0ec9b0e, + 0x0ea3435, 0x0219b1c, 0x0455b65, 0x1fdb60d, 0x18f8bf6, 0x19123f2, + 0x1154eae, 0x1b21648, 0x17fd5a3, 0x1d63ce2, 0x0b399e0, 0x0e6b979, + 0x02f9ebe, 0x113e17e, 0x1c39bac, 0x01b4a8f, 0x164a426, 0x11e10c3, + 0x1a0a20a, 0x18b7816, 0x03ab766, 0x07f4718, 0x02f1069 }, + { 0x006ded2, 0x1674886, 0x01ec1e9, 0x1e5fb21, 0x1974842, 0x1b1ad37, + 0x0ff5aa7, 0x04dc8d1, 0x11ed606, 0x05b0c48, 0x1b95201, 0x113e6d3, + 0x011fb2f, 0x0e4b510, 0x0f4444f, 0x0675939, 0x0fe10d6, 0x133acd6, + 0x1ea98a7, 0x14cdf91, 0x028364b, 0x04a3f9c, 0x09a1ab9, 0x139b533, + 0x03a05d5, 0x1b74146, 0x1023a8b, 0x18f5f62, 0x1953c87, 0x0472579, + 0x13c9547, 0x13b553c, 0x153d279, 0x18ca02d, 0x0352b5b, 0x163dfed, + 0x16437cd, 0x1aedeec, 0x0810c9d, 0x1c89fcf, 0x0985f83 }, + { 0x0f45294, 0x01e0b75, 0x1d46258, 0x018496a, 0x1013116, 0x0b5a96b, + 0x08060e7, 0x0809822, 0x0ed9433, 0x03ce781, 0x106da1c, 0x0516e9e, + 0x010c5b0, 0x0e4560f, 0x10fc1da, 0x09e1c7b, 0x0a3f8b2, 0x12d62f7, + 0x0d31708, 0x0d0975c, 0x052aee6, 0x11cd5e2, 0x0949679, 0x1be8b99, + 0x12cd1e9, 0x07d583e, 0x0c6910f, 0x0e03392, 0x0003b30, 0x0d54c96, + 0x0b9a3f7, 0x01b1978, 0x19f179c, 0x00e5396, 0x09bc79e, 0x1377e2b, + 0x10dcc79, 0x0bbceaa, 0x18bc553, 0x0801fd2, 0x00c88e5 }, + { 0x0f44357, 0x18d3574, 0x0daa13d, 0x0c74795, 0x175b4bf, 0x15e3407, + 0x076796b, 0x1e46699, 0x08a753e, 0x1657842, 0x18f23b3, 0x09820eb, + 0x1ae2801, 0x1ba7c69, 0x07568e3, 0x0655d77, 0x064b80e, 0x13acc42, + 0x0af0de4, 0x051cdfe, 0x01977b3, 0x17f7687, 0x1aeec7e, 0x0660cb5, + 0x0ac955a, 0x07433a7, 0x1e48b6f, 0x1833fb1, 0x1b907a8, 0x1742cc3, + 0x15e305e, 0x0767459, 0x1f33627, 0x1bb97c4, 0x0067ea1, 0x0dd75d4, + 0x1a25ced, 0x0ef24c9, 0x01c5539, 0x1715e22, 0x08e2560 }, + { 0x141aba6, 0x1ba3618, 0x1e795b4, 0x1f75659, 0x05a1079, 0x0e93e3a, + 0x0a0c673, 0x01d6c70, 0x09dfd95, 0x111bb19, 0x1023fc8, 0x0b9a752, + 0x181e0b1, 0x188b008, 0x0a00802, 0x1774e93, 0x15da383, 0x0938ced, + 0x14411b5, 0x106814c, 0x1b1f607, 0x0f4ba91, 0x024a753, 0x0145157, + 0x0345c8e, 0x0e3a020, 0x082b7c2, 0x024eb58, 0x11d6116, 0x1932919, + 0x142d06a, 0x0a72394, 0x10cc77c, 0x1118a91, 0x124a3e4, 0x13117c1, + 0x12fd9a2, 0x19ec95c, 0x1cb97fb, 0x0450649, 0x059005f }, + { 0x04c1c74, 0x0ba861e, 0x0de5aec, 0x01d2cdf, 0x1e73aac, 0x02cb9fd, + 0x176499b, 0x16d0b4e, 0x03a8656, 0x04bfc99, 0x11b37a3, 0x0762a08, + 0x1f2b704, 0x1ff9c4b, 0x0245bdc, 0x0e564a9, 0x01cb18b, 0x1489ee8, + 0x0230379, 0x0ea3e29, 0x0a58d0a, 0x0a42ac6, 0x0645d5c, 0x14cc7b4, + 0x1430144, 0x10c4bb8, 0x12c3821, 0x1be3215, 0x1ead9c2, 0x1e0679c, + 0x0840203, 0x02e705b, 0x085ac6e, 0x1519c00, 0x0144c98, 0x1bd2f23, + 0x143bae8, 0x04ac9b5, 0x17dbb91, 0x04daf07, 0x057a78e }, + { 0x0dbddd8, 0x19a37a0, 0x0eb0586, 0x0f28218, 0x0b49a92, 0x03679d9, + 0x09e0c62, 0x1d718a8, 0x033b93d, 0x16f9919, 0x1d5e75c, 0x13ea81b, + 0x009c8d5, 0x01077a8, 0x15e99f7, 0x10c87cb, 0x11867f0, 0x1e2359c, + 0x165ab70, 0x14488b5, 0x04d0ecf, 0x0d8622a, 0x1963d62, 0x1082fae, + 0x09301e0, 0x1447376, 0x0b11538, 0x194bded, 0x0f462d6, 0x0247d60, + 0x0d90644, 0x011b140, 0x12407d8, 0x1adbf42, 0x0e9fdb4, 0x0f698a6, + 0x0f6ada8, 0x08f2094, 0x1cba0c9, 0x18b0388, 0x01ca370 }, + { 0x001b68a, 0x0a8b8d4, 0x02ce52f, 0x19fa333, 0x1312879, 0x0b19013, + 0x0aafd04, 0x1b6920b, 0x0f5b01f, 0x0ff43fa, 0x084a2ed, 0x047539b, + 0x1778de5, 0x03de98f, 0x1c58687, 0x0986a17, 0x1d02390, 0x0daef67, + 0x0623c4b, 0x165105c, 0x0e74224, 0x0efcced, 0x0374a00, 0x19a39a4, + 0x067b508, 0x11ce56a, 0x170219f, 0x1862387, 0x0250726, 0x0b9015a, + 0x00dc684, 0x05dfb20, 0x1bf464e, 0x09d81c1, 0x122876f, 0x14a7a08, + 0x06265ba, 0x0da97a7, 0x0b1e4cb, 0x0989867, 0x02584b3 }, + { 0x0eec688, 0x031c495, 0x148cf2e, 0x148bf7c, 0x05e740b, 0x105afc5, + 0x1c7dff5, 0x07a845c, 0x0487491, 0x0ae8c2e, 0x1f60351, 0x166df42, + 0x0404c2b, 0x1602a29, 0x09c6152, 0x14cae7e, 0x045a8b9, 0x03b6e98, + 0x0bb9f32, 0x0587c2c, 0x07d02e4, 0x0326fb6, 0x000999c, 0x0f96910, + 0x1dd51dc, 0x1f02c93, 0x1861e25, 0x167f557, 0x15737c6, 0x0917796, + 0x1fff9ab, 0x1fea353, 0x1b60269, 0x03dd557, 0x1515a60, 0x15c3906, + 0x151ca49, 0x0edb7fc, 0x0c216b3, 0x0e87f35, 0x07e8113 }, + { 0x10a88b1, 0x11545c1, 0x1f86b5c, 0x119c222, 0x11918ea, 0x04da3ec, + 0x142e010, 0x1a67c05, 0x16c46d1, 0x09c0969, 0x059a72d, 0x1b61cb1, + 0x1e2fd09, 0x0ad866a, 0x1173418, 0x188a730, 0x15a2386, 0x1860e0a, + 0x17fd0f2, 0x0e9bcbe, 0x00cdda7, 0x0c71c8e, 0x0ec1dae, 0x009e50d, + 0x11eff50, 0x1ff4beb, 0x12bbb02, 0x07c168d, 0x01ad942, 0x0333995, + 0x08b914e, 0x072db48, 0x00c9f81, 0x195ff7f, 0x06898f6, 0x02c6ed8, + 0x1a56fa9, 0x0e3c8c5, 0x0169800, 0x0c9bf09, 0x0436b8c }, + { 0x0b764bc, 0x0bf4ec5, 0x1e12204, 0x0940efb, 0x1fa61e9, 0x0c775ee, + 0x1974c30, 0x1b8b4ee, 0x1fc9451, 0x0448b57, 0x08d1e95, 0x1c660e3, + 0x1f01a52, 0x191da0e, 0x0ee577a, 0x1850cc6, 0x0c943c8, 0x06ebeb4, + 0x0365c1a, 0x13a83c3, 0x199de4f, 0x0846493, 0x1e6422e, 0x0e72946, + 0x0148ed4, 0x09ff30a, 0x1f35479, 0x0a030a2, 0x03dcb6e, 0x03af012, + 0x0154180, 0x02f2a88, 0x1dcde62, 0x0d2fff2, 0x03854df, 0x0cdef92, + 0x0768cb6, 0x1bd5720, 0x0578477, 0x13cdb7d, 0x05266ca }, + { 0x186b3db, 0x0f73689, 0x1502137, 0x14f871c, 0x19e4af5, 0x027a4ef, + 0x01103ac, 0x1fb6683, 0x0fde5a4, 0x09c50f4, 0x15f3f08, 0x1248604, + 0x013e6e6, 0x0cfeb86, 0x0671b8c, 0x03fe06a, 0x17486c3, 0x0479a70, + 0x103387a, 0x0531fb2, 0x0d7cf1e, 0x0e8a4b0, 0x1bee32c, 0x05e77fe, + 0x013472b, 0x07f903e, 0x1051bbe, 0x1334416, 0x13e2208, 0x1b15bde, + 0x09df7b0, 0x0c4d7d4, 0x175044e, 0x065b3d4, 0x11253ed, 0x141e656, + 0x1fc6703, 0x1d04900, 0x128af05, 0x17339b0, 0x041f325 }, + { 0x02843a4, 0x16a89e7, 0x0bf0c4b, 0x1c00e51, 0x0748498, 0x032672f, + 0x0a08936, 0x07751de, 0x0a62008, 0x0032382, 0x14ce34d, 0x03b297d, + 0x185905e, 0x031f3d9, 0x15e32d4, 0x0f77254, 0x196289e, 0x0cc13b6, + 0x05edcd0, 0x05b88fe, 0x0944dfe, 0x0f8ed64, 0x1648d48, 0x080154e, + 0x0d28d23, 0x1219edb, 0x1a9d86e, 0x0c8ee0b, 0x1d07ddc, 0x1d36cdf, + 0x1f6251e, 0x0485951, 0x0f2e3ac, 0x01a3400, 0x19c3ae3, 0x1a93de8, + 0x19aa18f, 0x19e9bde, 0x1aa79f6, 0x16dcb19, 0x056b30f }, + { 0x180a428, 0x06e5566, 0x02441fb, 0x190e659, 0x1af922d, 0x0d220fb, + 0x01e60eb, 0x11441b1, 0x0924b00, 0x1f6cd22, 0x0070e8e, 0x067965d, + 0x1321235, 0x12fc03e, 0x13901d5, 0x15d9786, 0x1a51f2f, 0x085fd77, + 0x17a2a23, 0x0c694b5, 0x0a9178b, 0x1c4a1c9, 0x11382df, 0x17639b1, + 0x0237790, 0x0571849, 0x0be1c81, 0x1d5369f, 0x13cd83d, 0x00fac2e, + 0x1e4fb7e, 0x18ca474, 0x0f88c51, 0x06cb4ac, 0x0e2c5f0, 0x0fc8e5f, + 0x1ccf7f0, 0x0840f2e, 0x1451a26, 0x0aeb17b, 0x01353cc }, + { 0x1bf6e18, 0x0b24b9c, 0x071ca29, 0x04c9371, 0x19e8b5a, 0x145c73a, + 0x0d28373, 0x0191b28, 0x1204704, 0x09adfa8, 0x0e3a0b6, 0x02c8d4f, + 0x142ab3a, 0x13fc094, 0x160fb58, 0x0e52fe2, 0x1e072d6, 0x1c20b53, + 0x14e790a, 0x10bb0d9, 0x1bad496, 0x03cac6e, 0x029e5ff, 0x0b9cdbd, + 0x0f92815, 0x11ad2ac, 0x03e28d8, 0x0be9cae, 0x077ae57, 0x07e0294, + 0x0f6f1a7, 0x14d62dd, 0x14193a9, 0x060f8c7, 0x10f2ec7, 0x131a3be, + 0x1a21e78, 0x1d41872, 0x17d61c8, 0x0bbe8a3, 0x03ec218 }, + { 0x10bc2d7, 0x063eb8f, 0x104ae75, 0x18dca3a, 0x0982c6c, 0x0fc07b3, + 0x0b64e82, 0x13925c0, 0x1047ae0, 0x1ee9692, 0x0d47e6d, 0x093e6fe, + 0x1e35031, 0x03bc285, 0x1527387, 0x1a590d3, 0x0cb12f0, 0x0b01215, + 0x0f0a2e7, 0x1118acf, 0x0550ba1, 0x10835e0, 0x0390184, 0x0fa8653, + 0x04b1f8d, 0x0f0586c, 0x1f4e254, 0x094cf5c, 0x097607b, 0x02bdc5e, + 0x1cad49f, 0x0a92f54, 0x093c5f3, 0x0eb335e, 0x0330e6f, 0x06be3bd, + 0x09d447a, 0x03ee2e7, 0x0af94c2, 0x16d4423, 0x089b356 }, + { 0x1dcc837, 0x0d857ef, 0x1ea7b5b, 0x1550e36, 0x0fb80ba, 0x0ea5b90, + 0x0ff2470, 0x0b88275, 0x1adac9e, 0x0dab5fb, 0x195e8fd, 0x05b5170, + 0x0e5664a, 0x0720eca, 0x0c13dc8, 0x06cb023, 0x1263743, 0x131f08e, + 0x109b6ba, 0x051d9de, 0x0dc2ee6, 0x04e58b1, 0x0045867, 0x0c90c86, + 0x1817f87, 0x0434e7a, 0x095612f, 0x03772e0, 0x1f7928e, 0x1e77805, + 0x194b309, 0x1b8c1dd, 0x0f3a80e, 0x0e17ca7, 0x0afa1eb, 0x04fc240, + 0x0a0d4f5, 0x178c704, 0x1449995, 0x01aaf8b, 0x039c4f1 }, + { 0x08aecd3, 0x0db4674, 0x0a76cea, 0x114a315, 0x155b091, 0x0a772a2, + 0x136b52f, 0x109db83, 0x102068d, 0x0db45b3, 0x0b1cb5e, 0x01a1023, + 0x187dac8, 0x140d053, 0x079b4d6, 0x0c506da, 0x1ea3bd1, 0x06420f4, + 0x0531111, 0x182eeb1, 0x1202a7b, 0x12f8d50, 0x1cad8dc, 0x1a98aad, + 0x1767ec7, 0x08ddf63, 0x0f51bfd, 0x102fd76, 0x17e3392, 0x1f46b9f, + 0x113f796, 0x0b5da49, 0x0c6c977, 0x0bce7a2, 0x1c1edb9, 0x1817342, + 0x1069fbc, 0x18b23c4, 0x0ac033f, 0x05a922a, 0x0414b54 }, + { 0x06e173b, 0x18f2c30, 0x04e8cf0, 0x1721cce, 0x1b7f4e1, 0x1d9057a, + 0x0d44b7a, 0x0e084bf, 0x105120e, 0x1c4630b, 0x0f93b31, 0x0c05202, + 0x173ef05, 0x00e3736, 0x074d6b2, 0x0d2153f, 0x08f9450, 0x17098f4, + 0x12bc20b, 0x1f36648, 0x0ea9708, 0x160dd15, 0x0cb9359, 0x01b6539, + 0x14a6e74, 0x003d78f, 0x034610c, 0x0957249, 0x156a6c7, 0x077c76a, + 0x0984cce, 0x04e1a2f, 0x08e623e, 0x07adffa, 0x0bea582, 0x0a78e6c, + 0x044e851, 0x0bbc3a2, 0x02ca90e, 0x0d5c017, 0x052678d }, + { 0x136aeb4, 0x18e2cef, 0x02ad77f, 0x1952578, 0x12d6653, 0x1d2fc0a, + 0x1d25a49, 0x03e1c07, 0x02dfd49, 0x084ea0a, 0x07e26e1, 0x18a54ae, + 0x05258c2, 0x0999a24, 0x1586012, 0x13c1257, 0x14f3f7d, 0x10d19f4, + 0x106fe41, 0x0831a65, 0x095cfab, 0x072d52b, 0x1ce7124, 0x1a5afff, + 0x1196ef6, 0x0548720, 0x143de52, 0x1d9a80e, 0x053b4f3, 0x1cd9698, + 0x1252d63, 0x0bb32e9, 0x0ee842a, 0x17b415c, 0x1076fc8, 0x0c474b3, + 0x08efcea, 0x0d630a6, 0x1bb7411, 0x0b78219, 0x07040ba }, + { 0x15a1a96, 0x127c0a8, 0x1f80b0d, 0x0630864, 0x11a6350, 0x0c9ea79, + 0x199406b, 0x0e61412, 0x1273b61, 0x0bb4a78, 0x16a74a7, 0x10eda59, + 0x178886d, 0x140a60b, 0x0069d08, 0x0d2d63c, 0x16b8667, 0x11a4913, + 0x0c97c01, 0x09e18cb, 0x0c4a2fd, 0x0ffd94a, 0x1949cd2, 0x03a66de, + 0x00d8ade, 0x10760ff, 0x039f8e1, 0x1f3447d, 0x14c31ea, 0x1b90dbb, + 0x12a5f4a, 0x086caf0, 0x0c3e582, 0x07551fd, 0x1d39c3d, 0x11fe5bf, + 0x1e87324, 0x140f0d7, 0x12704f4, 0x1ac17a3, 0x09043a6 }, + { 0x06c7937, 0x0d07f3b, 0x0f8c544, 0x1957787, 0x1b2ded5, 0x0444560, + 0x1833380, 0x1e65582, 0x1616200, 0x143aa5e, 0x0ba81a4, 0x107a694, + 0x0fb801c, 0x0e5f083, 0x15e80ea, 0x19b2915, 0x022cedf, 0x04cb584, + 0x101a620, 0x068c75c, 0x1663c3c, 0x06facbf, 0x1ec4ba9, 0x19255f3, + 0x1383440, 0x0aa1646, 0x193a368, 0x13790b8, 0x0e801a7, 0x0fd16da, + 0x0ca55dc, 0x03c6af3, 0x1d2c138, 0x1683c3d, 0x177ffea, 0x0dc8b8e, + 0x173eac4, 0x1b051e5, 0x17cd6c1, 0x0907424, 0x026362b }, + { 0x0fc3e89, 0x1469477, 0x19c4971, 0x0ed3d3d, 0x0d0ee87, 0x0f25ba9, + 0x0ee1abd, 0x067160f, 0x0cb86b3, 0x1b84839, 0x14aeb36, 0x01d5fea, + 0x09fd3d2, 0x0606d0f, 0x1bacac5, 0x0e28b4b, 0x08a44f9, 0x09c8fb4, + 0x181b521, 0x17a6203, 0x0d4921f, 0x12df54e, 0x11793ca, 0x17e43b4, + 0x0d464a7, 0x038bdb0, 0x0015355, 0x127f119, 0x00f2e91, 0x09e8df7, + 0x1cd6b39, 0x1828724, 0x0c26563, 0x15af749, 0x02ca5b1, 0x15390dc, + 0x09ff59b, 0x17f1188, 0x04d7914, 0x040aab9, 0x02e952b }, + { 0x15f886e, 0x035e56b, 0x1160aa1, 0x1da87bf, 0x068a5db, 0x1d8dc37, + 0x116d801, 0x16a207c, 0x1355ff2, 0x0071764, 0x0fb3256, 0x1e4d44c, + 0x13bc702, 0x0c0f2f1, 0x0d6ce18, 0x040ec50, 0x1ec6c12, 0x0812889, + 0x1ef615b, 0x04dc74f, 0x1cb1a5c, 0x19ceb75, 0x03be0fe, 0x09a5f51, + 0x053f2a4, 0x14bbd55, 0x0d4ec7e, 0x1829de6, 0x159a307, 0x05088ba, + 0x183fd81, 0x16126ef, 0x1cd96b0, 0x1813995, 0x025b6cb, 0x0d4b829, + 0x0b53ef0, 0x054264f, 0x0392c70, 0x02e606f, 0x01236d0 }, + { 0x084373b, 0x00e47e0, 0x1ebb5d2, 0x10c8c12, 0x09ae476, 0x1de1a59, + 0x17e8184, 0x1602601, 0x0934bc2, 0x18938a6, 0x0f9f88d, 0x0c521c5, + 0x0086524, 0x1680840, 0x13eee7f, 0x08aecaa, 0x1384231, 0x1787605, + 0x0c28ca0, 0x15eb286, 0x181765b, 0x1438377, 0x0ef7786, 0x0ea61d2, + 0x0727dba, 0x0e5be96, 0x19d3325, 0x1618bac, 0x18906db, 0x09b2921, + 0x1cecff3, 0x1a28cb1, 0x1881941, 0x1f8748c, 0x1555b25, 0x15cc2de, + 0x0b9ec7e, 0x1e16c2a, 0x0d5b8d4, 0x028c419, 0x002a480 }, + { 0x06ccd38, 0x1691ea8, 0x0a98475, 0x0920b37, 0x029a1c5, 0x0808e29, + 0x0709da7, 0x0fae2f9, 0x0d82893, 0x03f0da3, 0x0d420fa, 0x1777070, + 0x18f5d63, 0x156d612, 0x09ed09e, 0x09a3fe1, 0x0bd9f15, 0x0ccd593, + 0x1b2557f, 0x01ff7f1, 0x1880dec, 0x13a4fe5, 0x1ba55f1, 0x00229bd, + 0x15dee1e, 0x163991c, 0x1cda7d1, 0x1254c96, 0x0b25991, 0x033048f, + 0x1690c11, 0x145d187, 0x02da887, 0x0b68c5f, 0x10970d5, 0x07489c5, + 0x155f75f, 0x1c820a5, 0x1ff80c4, 0x0df1e42, 0x01d8bde }, + { 0x0028924, 0x09cfc51, 0x0e7c0f3, 0x1960dd9, 0x0e54f19, 0x182c233, + 0x0f2df5b, 0x0ed0c57, 0x05a0607, 0x1f0338b, 0x1fb0436, 0x12f5621, + 0x1c9397c, 0x178ddb2, 0x084e099, 0x17471e8, 0x0cba672, 0x120a6f6, + 0x022c179, 0x1a9a87f, 0x14d1594, 0x1d564a6, 0x1e64fd5, 0x162ec70, + 0x02a6abf, 0x0ad3a7e, 0x0edbf19, 0x1032d6b, 0x0d2139d, 0x0e42774, + 0x09b70dd, 0x06c1a74, 0x1b00a02, 0x09dc3dc, 0x0d737ae, 0x1d66dda, + 0x0c83209, 0x12d945e, 0x04f07d5, 0x0878c20, 0x0349c69 }, + { 0x1e6c88a, 0x1ca2226, 0x01fb46c, 0x028e004, 0x15c2c47, 0x015bc06, + 0x1628887, 0x07d6de8, 0x0085099, 0x04fbab2, 0x1c3061d, 0x0af375d, + 0x10400ba, 0x19be387, 0x1d0a4e1, 0x0fd7e5a, 0x0ec2146, 0x1e2d471, + 0x0cdfd14, 0x14ccdca, 0x150a243, 0x03f685e, 0x12647c7, 0x17a3f23, + 0x13e90f4, 0x14d9d3f, 0x097c384, 0x0c113d1, 0x1896359, 0x10bb839, + 0x127434e, 0x04e3055, 0x0f842d5, 0x1e2e14e, 0x0a64205, 0x124232a, + 0x0725576, 0x17993f4, 0x163ea8c, 0x1571385, 0x0056587 }, + { 0x0e4733d, 0x0b1768e, 0x1110021, 0x1731ca2, 0x1faff7c, 0x15a35ca, + 0x0087ea6, 0x026be06, 0x0b61a8c, 0x0a4a62f, 0x0d65da2, 0x006c6d6, + 0x1657c95, 0x1561697, 0x1a1323c, 0x0e07cd7, 0x0d89bd2, 0x1872d9a, + 0x1a1caae, 0x1b231ef, 0x0ee1c4a, 0x0fe2029, 0x10aa27a, 0x1216a3d, + 0x0ee3f31, 0x0a7e165, 0x1dbffc9, 0x11fa286, 0x1e09725, 0x06b4441, + 0x0e1bcf0, 0x01f62a8, 0x1d0a0e9, 0x1570031, 0x192fdb2, 0x198870e, + 0x1f1d0f6, 0x0f8ab29, 0x16f7a05, 0x1db70d9, 0x01b87f2 }, + { 0x10b15b1, 0x095dd95, 0x1de4d5e, 0x0f9cd74, 0x03e4b5a, 0x079bbcd, + 0x1ff6776, 0x1dff759, 0x1c298d1, 0x02a285e, 0x00c7180, 0x0aad88e, + 0x060e3f5, 0x0aeb403, 0x1c3c1ea, 0x0a5840e, 0x0e02d10, 0x0671f42, + 0x0aa3315, 0x00f23cf, 0x03a3b05, 0x19dd191, 0x1358879, 0x0c65320, + 0x1b94d39, 0x0b6c3dc, 0x1dfae01, 0x1bf3968, 0x1ca0cc8, 0x06f476f, + 0x12b890c, 0x12e2541, 0x14bf416, 0x0454c9b, 0x11de221, 0x1d7c7e7, + 0x04a3e59, 0x15c3d8e, 0x0f08ec8, 0x1887d2b, 0x08e0227 }, + { 0x010964d, 0x1115419, 0x1bac003, 0x0bfe0ad, 0x1ccd5df, 0x18f56be, + 0x0e87f6b, 0x1c6042e, 0x067cdca, 0x01419f0, 0x1324334, 0x099717b, + 0x151cc57, 0x19125a7, 0x1b29c50, 0x105310d, 0x03abb3f, 0x1e80730, + 0x106a37a, 0x1d9c361, 0x061db98, 0x121bc61, 0x08a291b, 0x02cbcba, + 0x1dd0da6, 0x071637c, 0x052dfbc, 0x075c713, 0x09f306b, 0x0b59ded, + 0x16ce8f0, 0x0714109, 0x09a26d3, 0x074a82f, 0x064d4e5, 0x18a51cb, + 0x0ea206b, 0x076588a, 0x175ba12, 0x16a80a8, 0x014b15a }, + { 0x04c59a2, 0x0c364b3, 0x0a943db, 0x02c1faf, 0x1dfe2be, 0x1965c71, + 0x0d5a641, 0x1c067f3, 0x18176a7, 0x19192ec, 0x1c202d7, 0x09ce8b0, + 0x0579a0d, 0x06aea70, 0x1b837bc, 0x051c349, 0x1fac87b, 0x16056cf, + 0x1c26d3b, 0x031a5e7, 0x1d87d6f, 0x1394974, 0x13225ab, 0x128ec79, + 0x0953d60, 0x0fd6544, 0x0063efe, 0x17dd2f5, 0x03d701d, 0x1074a5b, + 0x0bf7c83, 0x08fd4e4, 0x1ba6e30, 0x1ab8fe5, 0x072984a, 0x0b9cafc, + 0x009a55f, 0x0b563b0, 0x078b878, 0x1b18871, 0x0742bbe }, + { 0x1dc2c73, 0x1436e60, 0x0afc8fa, 0x1782c87, 0x0bbbfd5, 0x0c650fa, + 0x1e87c93, 0x18e0ff1, 0x08cb5ca, 0x1345370, 0x19a9f77, 0x0c96a9c, + 0x187d54c, 0x14dbd6b, 0x076e88a, 0x15728f1, 0x140e364, 0x0a6c46a, + 0x1dcb804, 0x05c05a3, 0x0278c8c, 0x0ba3715, 0x1320981, 0x030f8fa, + 0x15bb34b, 0x064f361, 0x1bae3f8, 0x1b167bf, 0x11e415e, 0x1a743e8, + 0x1e6daf0, 0x170cb8f, 0x1908bbf, 0x060be59, 0x139b87b, 0x16e2fa3, + 0x17cdd69, 0x0f19847, 0x1049054, 0x0296b92, 0x097bd5a }, + { 0x1e82861, 0x0317f40, 0x103b807, 0x1bba858, 0x103d4b6, 0x0f48f2b, + 0x1956f99, 0x1bafca5, 0x05abbbf, 0x05a49ba, 0x0917d2e, 0x1ea58e5, + 0x18b4f15, 0x0a8794e, 0x010d6a1, 0x1cebf9d, 0x19b582d, 0x14efbb5, + 0x08322e5, 0x1098bf4, 0x0af452e, 0x0885450, 0x0bddf4b, 0x0c02787, + 0x1bbd8ca, 0x02f81c4, 0x089be0c, 0x01b3737, 0x0c8b9ab, 0x1424067, + 0x063c14f, 0x1ff57b4, 0x163367a, 0x1261526, 0x0f92990, 0x1ca1ea7, + 0x064fba2, 0x0962c64, 0x151a7e2, 0x0629198, 0x0317c6d }, + { 0x0b7d42b, 0x092d816, 0x12b830d, 0x12621f5, 0x15240bc, 0x102047a, + 0x0808bfc, 0x1411aba, 0x1e0c10e, 0x180a017, 0x1ac8f5a, 0x0d14e31, + 0x197fbef, 0x0092950, 0x051ad69, 0x01add40, 0x048110e, 0x0acd7e7, + 0x08b7860, 0x03a4fe0, 0x09dae9a, 0x0b6e1fa, 0x1b6e5b4, 0x17c8010, + 0x0e3f5ef, 0x08e7e0d, 0x07b32f0, 0x13ae0c8, 0x1f8636f, 0x113ca92, + 0x0c12408, 0x184ec78, 0x169796a, 0x031859b, 0x00f0764, 0x0f39869, + 0x0e3d3f1, 0x0b28f87, 0x0e3f514, 0x0733b41, 0x06ae597 }, + { 0x1f4d2ee, 0x09de3df, 0x0f615ec, 0x126162e, 0x0075422, 0x0a49b61, + 0x12f541e, 0x17d6c4a, 0x05efd55, 0x0af9195, 0x10ce247, 0x150a9c1, + 0x04c06f4, 0x0730fca, 0x0b16d66, 0x10f6f9e, 0x01ffd5f, 0x062b243, + 0x08abe93, 0x0c3f62b, 0x0774ee2, 0x1316cbd, 0x0c3fdc8, 0x19e00f5, + 0x1ae22d6, 0x10a0d44, 0x134d1bc, 0x11100a6, 0x16497e2, 0x1dffcbd, + 0x1f23f9c, 0x1f455ff, 0x08595b2, 0x0d39345, 0x1cfbc54, 0x173df39, + 0x0744b82, 0x0772f8f, 0x1f9caa1, 0x11b78c7, 0x0664904 }, + { 0x08b760d, 0x1ddbc0f, 0x0a8246d, 0x104b55b, 0x147b0bd, 0x1a9137e, + 0x0f67fea, 0x11d0292, 0x0bffc14, 0x136e913, 0x0f8f6d2, 0x1f15453, + 0x0b5a032, 0x1a58558, 0x036f1c0, 0x090d063, 0x1b57d65, 0x16e665f, + 0x1160791, 0x0d566f3, 0x0ce2850, 0x1714187, 0x0244da9, 0x0d9018e, + 0x19356cf, 0x143245b, 0x1fbdac7, 0x142ec6e, 0x10f1c9f, 0x0e60c1f, + 0x174b270, 0x02d57db, 0x0f0526d, 0x186f24b, 0x038aa4e, 0x147c1d3, + 0x0f13873, 0x16bd6d0, 0x127b1bc, 0x0b9e7f4, 0x04eb93b }, + { 0x11fae32, 0x0fbf2f0, 0x1d46f62, 0x0b88047, 0x113d74f, 0x0e1fb7e, + 0x0537d24, 0x16e3600, 0x1555279, 0x0c24d2b, 0x0801a07, 0x112e0b7, + 0x0abb9e8, 0x009e516, 0x0889067, 0x0cedf04, 0x085fd33, 0x157dddb, + 0x161e28a, 0x187ea4e, 0x1173931, 0x17f79ea, 0x04abbbf, 0x114d0f0, + 0x05cc8bd, 0x00b0c4d, 0x0f667c3, 0x059ffb6, 0x1d48b68, 0x0a0350c, + 0x182fd59, 0x1d38d89, 0x005e223, 0x020b92b, 0x077a1a0, 0x10a7cf0, + 0x07001cc, 0x1ae485e, 0x0fda337, 0x126f808, 0x02b582d }, + { 0x1abc2ae, 0x12e4140, 0x1b2a845, 0x0bc56d3, 0x073380f, 0x1ffb37d, + 0x0cf481f, 0x00d812f, 0x0547765, 0x0b01c13, 0x1e88717, 0x13e76af, + 0x15dcbac, 0x04c6dee, 0x1d436d3, 0x1e654f0, 0x103d9ef, 0x042f108, + 0x1c47107, 0x1a2e585, 0x0c09cee, 0x124f1a4, 0x0a38e49, 0x03dbbf7, + 0x1936b83, 0x051b8e5, 0x1bd4219, 0x02b87a0, 0x1acfcd9, 0x19e6f49, + 0x0abfa38, 0x167e5ef, 0x1ee10d7, 0x0774d25, 0x0d23adf, 0x1b83b1d, + 0x1a574af, 0x124e71f, 0x0d3013e, 0x0130c5b, 0x0786151 }, + { 0x0e72c21, 0x1fa403d, 0x1694ff8, 0x09fa1e1, 0x031aa14, 0x01d22a3, + 0x187a3e3, 0x1578edd, 0x051b4f1, 0x1cd704a, 0x16ec90d, 0x072faf9, + 0x0d2a3a4, 0x015eafe, 0x0533ffa, 0x1deb4f4, 0x112f427, 0x1ddf276, + 0x0134f33, 0x1487dc5, 0x0e1e9b0, 0x09c7763, 0x15ede2e, 0x171d0f6, + 0x004e467, 0x0100c6a, 0x14d0dd3, 0x1915b80, 0x08deb50, 0x1b02aa1, + 0x13d90dc, 0x1875f45, 0x0d80ec0, 0x0ab7cda, 0x04f0eaa, 0x10daa3f, + 0x04161c6, 0x0d1455c, 0x100967e, 0x16ed793, 0x0540b6b }, + { 0x01d315d, 0x0b9a619, 0x1740138, 0x05b0dc0, 0x0ef5661, 0x1466c0a, + 0x18516ee, 0x135d5f5, 0x1acdc78, 0x1d83d24, 0x1d5c3c7, 0x135ab0e, + 0x1e6a21e, 0x1cde29e, 0x12a0dfa, 0x131d65c, 0x0931d62, 0x0a1b6d9, + 0x08d8bd1, 0x1f78f1d, 0x058543a, 0x0bd55fb, 0x0aa5cf6, 0x1249ac0, + 0x1dabe0c, 0x074ee73, 0x01f2b7c, 0x0d3b31e, 0x020538f, 0x02d0ba8, + 0x0a782d4, 0x088c39a, 0x1b7d1a3, 0x0740c1e, 0x1dd9788, 0x0dc3850, + 0x12dd50f, 0x112c33a, 0x0e230b2, 0x02925c0, 0x0897cab }, + { 0x18bab8a, 0x09c0986, 0x002967b, 0x1948704, 0x011d364, 0x0c0a0ae, + 0x0fcb101, 0x0e80d0f, 0x07ac896, 0x156869d, 0x1046821, 0x020b72e, + 0x1c44928, 0x19c19b8, 0x0612c47, 0x1063ce9, 0x1840d1a, 0x0386976, + 0x1244bf8, 0x06c516d, 0x08d2d88, 0x1d8a7d4, 0x113e3df, 0x015927c, + 0x12a4dcf, 0x1d32b27, 0x0a9b093, 0x05ec535, 0x0cd9498, 0x15d1dfb, + 0x0b6ae41, 0x0414a30, 0x0822e67, 0x1c9d296, 0x16b0c3a, 0x145fe8f, + 0x1ff673a, 0x1162527, 0x03b1771, 0x0c68ed6, 0x064b007 }, + { 0x1c9a404, 0x1a99f59, 0x054878f, 0x076fdf3, 0x11db7f7, 0x129b49d, + 0x0f8a5b0, 0x1a98fe2, 0x00738ee, 0x073fa62, 0x1b2b41f, 0x16679c4, + 0x11ccfd3, 0x00f62e7, 0x1e124d4, 0x09c03b0, 0x09ddc08, 0x19fc7e0, + 0x0e6d6b3, 0x1956658, 0x151c217, 0x1dcf7aa, 0x10b6bc2, 0x042f52a, + 0x16f56e1, 0x0157de3, 0x0b08dc0, 0x002f162, 0x10a2938, 0x01cfd83, + 0x1902d4b, 0x0aed952, 0x1925153, 0x1471b71, 0x1090675, 0x084aab2, + 0x09e50e8, 0x0fdc160, 0x1b630a4, 0x14ccc31, 0x07dd22e }, + { 0x1cbb3bf, 0x14225a4, 0x0c95fff, 0x08aac5f, 0x1e0cc70, 0x0d422d6, + 0x194de7d, 0x1f83cdd, 0x0e51277, 0x0b6bf93, 0x0d5c625, 0x097260c, + 0x142c75d, 0x0b4abf9, 0x085224a, 0x0e85673, 0x13282e5, 0x1467a75, + 0x0c91edc, 0x1a7bbb0, 0x02376b0, 0x19900d2, 0x19ea7d8, 0x029490a, + 0x003c114, 0x08b20b2, 0x1edbdaa, 0x015fa88, 0x06f7906, 0x04986d6, + 0x00a57e5, 0x17a773b, 0x05ff94b, 0x16f87b4, 0x03f1472, 0x12b91f3, + 0x113b748, 0x0ce4455, 0x1f32255, 0x0ccbe31, 0x031377c }, + { 0x1cfb35f, 0x0ef04be, 0x1be0d71, 0x1e03986, 0x0dccca9, 0x1b65b19, + 0x1a175d5, 0x0eafd27, 0x0f7b4b3, 0x016ea45, 0x0866d43, 0x1a9f613, + 0x079d95c, 0x18dff30, 0x0bb4565, 0x1b5a4ea, 0x0cf2596, 0x1a1cc40, + 0x07a429b, 0x1df6a6d, 0x060ae52, 0x1181e9f, 0x11025d9, 0x0a0e1c0, + 0x164faa9, 0x0e97e79, 0x1815893, 0x11f3276, 0x15e467d, 0x0c12006, + 0x092cd6a, 0x0191e8a, 0x089d024, 0x100bcf1, 0x08f1922, 0x1bde8a8, + 0x187edab, 0x0feb4aa, 0x149c4e9, 0x019423c, 0x03dacc5 }, + { 0x099ae4c, 0x127ca32, 0x149f2cf, 0x02e0a78, 0x046dcbe, 0x1c17455, + 0x173a6f9, 0x08b00fe, 0x0d8481e, 0x1632694, 0x01bf42d, 0x0a31545, + 0x09f35e4, 0x0f8e6da, 0x0dee6eb, 0x07d5fef, 0x010aec2, 0x1f9fdb1, + 0x06ff4be, 0x17470b7, 0x13a00a9, 0x09c403f, 0x1946835, 0x0f65085, + 0x04404b1, 0x1853d59, 0x1fe7767, 0x1faaed0, 0x09df646, 0x1eda79f, + 0x137347b, 0x0c1be32, 0x1d2df7a, 0x0ef82ae, 0x0b0f81a, 0x037da7e, + 0x03248a3, 0x0dbab09, 0x113dd1a, 0x1c2d28e, 0x0866949 }, + { 0x14ab07a, 0x106d29f, 0x1efcea6, 0x07ea94d, 0x0cd6f33, 0x1e79481, + 0x1a486c8, 0x0b01925, 0x0848e3d, 0x0ac0e1f, 0x0862af2, 0x1f7ba76, + 0x1793af1, 0x03365a6, 0x1663a84, 0x0074070, 0x14e990c, 0x0a8009c, + 0x1421ded, 0x0c963cf, 0x10913b6, 0x1deba63, 0x15e76c6, 0x05abba1, + 0x144354e, 0x1c14296, 0x0ccca76, 0x1a57083, 0x16d4800, 0x07583dc, + 0x11bea11, 0x1852bb8, 0x1a50569, 0x1f6271b, 0x0dce53d, 0x0f85a70, + 0x1b08317, 0x1c427fa, 0x0966370, 0x171163f, 0x0574352 }, + { 0x15d7ce9, 0x0c9fb86, 0x1abfb48, 0x0c1690f, 0x1c19fd2, 0x132fe81, + 0x0ad65ef, 0x0acf889, 0x078270d, 0x0ced430, 0x1c06637, 0x1801754, + 0x1f8a84e, 0x142cc2e, 0x109f924, 0x051b05d, 0x0f0de20, 0x0ccb665, + 0x0708807, 0x0c918ec, 0x19eb4e7, 0x1e048e0, 0x0a58cd6, 0x1acf057, + 0x03a69f0, 0x049929d, 0x034a519, 0x1e40868, 0x1f68733, 0x10d084c, + 0x0691114, 0x0d32c02, 0x1cbcc09, 0x1d4a72f, 0x1763e14, 0x027109a, + 0x13b6a3a, 0x0c63126, 0x0f13c90, 0x1e40d5c, 0x03e431a }, + { 0x1d381f1, 0x1ec9cc1, 0x0f0fe59, 0x1da1806, 0x16501aa, 0x0083b41, + 0x1d34151, 0x1a77e75, 0x05093a6, 0x0368acc, 0x1ca402a, 0x0e83b25, + 0x1543ae0, 0x1b785ba, 0x0cabe98, 0x0dadffd, 0x0a3aa45, 0x1684853, + 0x1bf6d91, 0x149fb55, 0x0f7d336, 0x020d4a1, 0x1f46ff9, 0x03dc83d, + 0x0a3ed85, 0x0e2bfe1, 0x1847a4d, 0x1e392d0, 0x1bb3434, 0x1b3329d, + 0x0ab355d, 0x15b12d8, 0x06931ba, 0x1fd20f9, 0x0f461ae, 0x03141f7, + 0x0203cef, 0x1ebec15, 0x134d470, 0x02bc4cc, 0x06dad3f }, + { 0x0ec35a1, 0x005be89, 0x04a3465, 0x0dcfbf6, 0x0219c5b, 0x1990eab, + 0x1e31bc4, 0x16c5984, 0x033c58e, 0x13b4825, 0x00f10d7, 0x1eabb32, + 0x1915090, 0x01ecb50, 0x06f249b, 0x1974e0c, 0x1038c0a, 0x1cba54f, + 0x0662c86, 0x028042e, 0x0c6f7a4, 0x0efc4ac, 0x0c1a566, 0x17a0253, + 0x12f1dbe, 0x0e1a8bf, 0x0f7cea3, 0x02134c2, 0x0375c51, 0x0224339, + 0x14c2396, 0x12707a5, 0x0590ba4, 0x1c1be2b, 0x1f182ff, 0x1ff87dc, + 0x07d2d55, 0x1d29c81, 0x1e8ff21, 0x1a8bea2, 0x02438e9 }, + { 0x015af3c, 0x0298444, 0x1b57129, 0x05e7937, 0x055f1a3, 0x1b2eeff, + 0x137265e, 0x16b5de3, 0x012e51e, 0x0e30eca, 0x1c92418, 0x18a9cc7, + 0x11bd0da, 0x0859f11, 0x0510a73, 0x0c020de, 0x1c2f1da, 0x0fb9be1, + 0x0ef13ec, 0x01c096d, 0x01cb715, 0x048df14, 0x0816d32, 0x0e03eb6, + 0x0633cd7, 0x04878da, 0x18a944d, 0x1667de8, 0x11f7f28, 0x1e39b47, + 0x19f76d1, 0x17a82d6, 0x0ada511, 0x0add9fa, 0x1f37fde, 0x0f3a552, + 0x16200e6, 0x145bd94, 0x0380402, 0x0235fc6, 0x013f390 }, + { 0x1d0c827, 0x14b77bd, 0x1d18f74, 0x069453f, 0x106110f, 0x0d28ad2, + 0x0c1a072, 0x0eff0f2, 0x1268bca, 0x146c022, 0x01177f7, 0x0049330, + 0x04cbb83, 0x146072c, 0x0435c41, 0x0c0c47f, 0x0a8263b, 0x19541c6, + 0x0d71742, 0x176bcea, 0x1110293, 0x0aab20a, 0x13baa67, 0x17b400b, + 0x11ad01b, 0x00c7f18, 0x1e93634, 0x092fc17, 0x12b8662, 0x1bd00e7, + 0x02ccf75, 0x1b18975, 0x0075b73, 0x1bde4de, 0x1b51c8a, 0x165308c, + 0x0bda1b0, 0x13e7126, 0x00ed85e, 0x0d6d00e, 0x0458d4b }, + { 0x154d8b2, 0x1510726, 0x0836289, 0x1c9a641, 0x05a5696, 0x0a7b800, + 0x16163e6, 0x150d316, 0x02f6549, 0x1256e1e, 0x134035e, 0x10326d2, + 0x1d1812e, 0x1982015, 0x0e6c001, 0x0c8208d, 0x049a1b3, 0x070850a, + 0x048c088, 0x12bd4b3, 0x00c3eae, 0x0d8da41, 0x0fbf0ba, 0x193d714, + 0x15cb585, 0x0327f2d, 0x065e11c, 0x035c063, 0x07d49f2, 0x05b8479, + 0x1ada3bc, 0x05ee4aa, 0x059ef18, 0x0d80d19, 0x115d893, 0x18015c0, + 0x1668f95, 0x071d832, 0x0fe458a, 0x1f56df7, 0x05f13f5 }, + { 0x09b0dc6, 0x16cd71d, 0x1b21f1b, 0x12df107, 0x0ea1bde, 0x059b3bd, + 0x0fe23aa, 0x157d4cd, 0x09a66e3, 0x17d355e, 0x05fff77, 0x02f6d04, + 0x1cc4d33, 0x1486f82, 0x10723c8, 0x0ce9dee, 0x1177d11, 0x10f87ef, + 0x0d66272, 0x01d9cf8, 0x082dfdf, 0x0fb5ce2, 0x03bb64b, 0x17e394e, + 0x13e6655, 0x0ce39b8, 0x00973b2, 0x0159652, 0x03e69c9, 0x11d1740, + 0x068df27, 0x02ee274, 0x00a3c53, 0x10ba6be, 0x1595bd6, 0x0c6a1b8, + 0x05f802f, 0x112d220, 0x0928845, 0x0bb46f7, 0x0219649 }, + { 0x1142680, 0x197e989, 0x13d0032, 0x0ecba29, 0x0b9e91d, 0x11334f5, + 0x13aaf7f, 0x18b8d41, 0x00ae22b, 0x177e72c, 0x1b0942f, 0x130d96d, + 0x1f3c2b7, 0x0b9c78f, 0x0b6c68b, 0x191d909, 0x028516e, 0x0cb84de, + 0x1a3df6d, 0x1262531, 0x17f9f36, 0x15cad8c, 0x1123bf1, 0x1554809, + 0x109529a, 0x0584ff8, 0x1451055, 0x1879197, 0x1f34352, 0x1de1a13, + 0x104cfbd, 0x1a4312f, 0x0a17940, 0x0a45002, 0x11f5b39, 0x04b5418, + 0x1d56fa6, 0x18e7539, 0x17c20a5, 0x160088e, 0x093ad0e }, + { 0x08a9963, 0x1b4b3cc, 0x0375e82, 0x0eca2bd, 0x01e477f, 0x15a8793, + 0x18e18ed, 0x1bcc4e9, 0x1d33922, 0x1d4dc6a, 0x096cf58, 0x07f6d0f, + 0x033c38d, 0x0981719, 0x1dbc270, 0x1999e31, 0x1c3e02f, 0x192a602, + 0x1b998bd, 0x1da16e4, 0x0079c04, 0x1c0a1ff, 0x075591a, 0x002d918, + 0x09448c9, 0x1cbf7c5, 0x0fe08f5, 0x0ace989, 0x0de451e, 0x1b97de6, + 0x178161b, 0x0882fd5, 0x1fc88d5, 0x12c46e2, 0x08255db, 0x12572a4, + 0x1844d1f, 0x046ea12, 0x100d110, 0x1e1d483, 0x073f8c3 }, + { 0x1f763dd, 0x1a7e42e, 0x00da254, 0x06758e3, 0x1b1427f, 0x078ad01, + 0x0f85dba, 0x11c1b6b, 0x0cb2088, 0x09c84a2, 0x12ba987, 0x135b0af, + 0x137804c, 0x08cfbdf, 0x16110a1, 0x1519f54, 0x0f1293a, 0x0b13776, + 0x08da805, 0x1c1b31d, 0x0dcd749, 0x171990f, 0x1bffdb6, 0x16f2399, + 0x1eea628, 0x1b0cb1e, 0x08b45b8, 0x029c0aa, 0x1ae206a, 0x0c7e58a, + 0x1928b81, 0x1f9464b, 0x1268745, 0x00d4507, 0x101c84d, 0x10f9f3a, + 0x1caa51b, 0x1692ecb, 0x175d77f, 0x0735b7d, 0x00108ae }, + { 0x1e88f63, 0x0bc79d4, 0x0c95534, 0x1d5618e, 0x0a05b11, 0x10ec535, + 0x14f9b89, 0x190ee74, 0x08d0b91, 0x06dbed7, 0x0c01349, 0x00e7d37, + 0x0bde10b, 0x0a71848, 0x02fbf9d, 0x13913f9, 0x1990cc6, 0x10b5782, + 0x1565446, 0x1070073, 0x1afcddc, 0x0ca362e, 0x10fd96e, 0x1c14b33, + 0x04be81e, 0x18bfddf, 0x1becea6, 0x11123c6, 0x1dad008, 0x16baa22, + 0x07c326a, 0x1aa12fc, 0x1fc46ab, 0x0d270ef, 0x026eb21, 0x0710901, + 0x00c4523, 0x05da17d, 0x1077cd2, 0x1b1d627, 0x0807c06 }, + { 0x0ee0ef6, 0x0b4f64c, 0x1ebc02a, 0x07176f6, 0x1a9d548, 0x17c7edd, + 0x1324a80, 0x0f84890, 0x08b7055, 0x1ed900d, 0x146bc9e, 0x07c8c15, + 0x1be5934, 0x0cc64af, 0x0a6a50a, 0x03a76a7, 0x1deda86, 0x14ba6d9, + 0x14e6703, 0x0a4b93d, 0x09bdce1, 0x00fb908, 0x026d5a2, 0x1042349, + 0x17d1599, 0x1ad047f, 0x0bbc3c9, 0x1beed67, 0x0f358b5, 0x007bfd1, + 0x0d24fc6, 0x187360c, 0x0c4ffcf, 0x01da9d5, 0x18985d6, 0x184d258, + 0x155399f, 0x1efd1b5, 0x1e986cb, 0x0d932c0, 0x016424c }, + { 0x12744a9, 0x12e2aee, 0x1061775, 0x05fc75e, 0x0544c1c, 0x1458449, + 0x0ba67bf, 0x0346590, 0x1a9df69, 0x05bd592, 0x0659d0c, 0x0aa137d, + 0x0298384, 0x0579689, 0x1b34963, 0x0e4e579, 0x098bcc7, 0x0445720, + 0x0e3be83, 0x12c2829, 0x112cd43, 0x1cf6b26, 0x113fd9e, 0x0fe6808, + 0x055e42e, 0x0f5d4f3, 0x1516c3a, 0x1a2df88, 0x1ded283, 0x1f0a781, + 0x1711d28, 0x1599970, 0x1c9adff, 0x1d28dd1, 0x0f05c94, 0x027bfcd, + 0x1b5831b, 0x0d7a5cf, 0x11e2b77, 0x00549e8, 0x05544e6 }, + { 0x0a80b4f, 0x02989dd, 0x03be25f, 0x1ec77b9, 0x0122716, 0x0162d40, + 0x10b6ded, 0x1195c4e, 0x1088330, 0x0ecf0f4, 0x106ac7a, 0x187e5a6, + 0x10352c8, 0x16ca2c3, 0x0f41403, 0x1b3b02c, 0x173c290, 0x0c1a4ee, + 0x1db1f4a, 0x078bc03, 0x033c205, 0x0365a10, 0x00c41d1, 0x1a135e3, + 0x08bd209, 0x140bb64, 0x1ac9e51, 0x01ee1cd, 0x11b540d, 0x0cef0cd, + 0x10dc82d, 0x0453296, 0x0b7ecdc, 0x029e7c0, 0x1738b7b, 0x0583499, + 0x1ed60f4, 0x1e9f6e8, 0x1498775, 0x0b9c483, 0x0573599 }, + { 0x0237056, 0x1d1fdd0, 0x0e23712, 0x0867566, 0x0856c16, 0x0f63093, + 0x1aef49c, 0x1d9803d, 0x1e3031b, 0x1ef5819, 0x0287d6a, 0x0832c23, + 0x134eee4, 0x0db0079, 0x125d085, 0x10ee7d8, 0x1cf0886, 0x08db8c2, + 0x106df7f, 0x188d9af, 0x1e897b0, 0x0d25262, 0x1450ecb, 0x03ff29b, + 0x05984bb, 0x032edcd, 0x13273cd, 0x187209c, 0x0e64c9a, 0x0de0756, + 0x06be1ca, 0x0ed15b3, 0x0c22821, 0x0a0612e, 0x02062a5, 0x0f77a76, + 0x049a691, 0x1476af8, 0x17bc391, 0x1be7d88, 0x0885486 }, + { 0x1dff464, 0x01649a5, 0x1145aa5, 0x1e4b4f6, 0x1db2719, 0x0df1921, + 0x01c2cc9, 0x0739960, 0x119fe33, 0x02ad18d, 0x1ba3fc8, 0x15d0483, + 0x0faca69, 0x0af7c6f, 0x01f7421, 0x0e78cec, 0x00f1a1b, 0x04f124b, + 0x074da04, 0x01d144e, 0x06b9bcb, 0x113442f, 0x0a7846a, 0x0bd5c32, + 0x1d0ab18, 0x08e4c5a, 0x103e07e, 0x14172dc, 0x0fc5031, 0x05e7cca, + 0x181343a, 0x1e233ad, 0x1d81697, 0x0670619, 0x0a1eaa9, 0x0e52106, + 0x091ff9d, 0x0ea69f6, 0x058b717, 0x1d1a957, 0x031cecf }, + { 0x08b21e8, 0x1fecd7e, 0x1b7d0de, 0x0763286, 0x05dd32b, 0x0e1b507, + 0x00b5248, 0x121fcb2, 0x1a3d0fa, 0x14ef426, 0x148ef63, 0x0d5ab76, + 0x159663e, 0x1766b4b, 0x00288fe, 0x16b3930, 0x0d9b4fb, 0x08804e0, + 0x07483fc, 0x154f7b9, 0x1a3d839, 0x16f66b7, 0x1d40bd9, 0x0a2d953, + 0x0d4fbc5, 0x1622407, 0x19b1d0a, 0x0bff4be, 0x1252f86, 0x1ca2ff9, + 0x0f4adf1, 0x0ebb396, 0x0fefc05, 0x178e939, 0x18ef5b5, 0x0623610, + 0x1a6a4ec, 0x079e784, 0x11ecd76, 0x0d5b44a, 0x06961b4 }, + { 0x135e2ac, 0x1ac3f65, 0x136741e, 0x16af5e2, 0x1ed5546, 0x1450260, + 0x1e96f6c, 0x1e1d942, 0x0709d54, 0x0fc8ea2, 0x1d003a8, 0x13fb38d, + 0x10a6e71, 0x1dc670c, 0x12e23b7, 0x07fa49c, 0x0dd246e, 0x0fcbc0f, + 0x1956bd7, 0x0241cd6, 0x1ca7d67, 0x0ec9a09, 0x169e0b4, 0x00ff443, + 0x020a297, 0x091b4bf, 0x0953a10, 0x1d6a3e6, 0x051f9f1, 0x06cf1b0, + 0x1a4b895, 0x0e79cb7, 0x1aec42b, 0x1bca7ee, 0x0cbb34f, 0x1313534, + 0x0781aad, 0x1271178, 0x1484865, 0x018a6ea, 0x06a63a9 }, + { 0x17acbbb, 0x0a7001e, 0x0421d95, 0x156e9ec, 0x0c01668, 0x0628cd9, + 0x059c8e2, 0x09fc945, 0x03eb94d, 0x0b33b8a, 0x1b4bd80, 0x19be19a, + 0x1f086a3, 0x1d9b87b, 0x1960085, 0x07cf9f0, 0x0c15a4d, 0x0b2c440, + 0x0e8fd28, 0x1ab02cb, 0x11ddd6e, 0x09ae523, 0x0af31e0, 0x0894aed, + 0x1f074e8, 0x175404d, 0x0dba940, 0x0a75036, 0x021ed3a, 0x0983870, + 0x197082e, 0x10c2fe2, 0x027f892, 0x0e685c6, 0x111a08d, 0x034a8ec, + 0x0255296, 0x044ffec, 0x1643bff, 0x045a2a3, 0x051ed4a }, + { 0x09701b4, 0x14b1d22, 0x0bc8df5, 0x07764f9, 0x0a8d91a, 0x194b2ff, + 0x0f856d5, 0x0fa7df3, 0x1db50bf, 0x0d3d02a, 0x10ee6dd, 0x101d9cc, + 0x1efd674, 0x1675aea, 0x09834b5, 0x1912fe5, 0x00c5ed7, 0x1b47e19, + 0x0339a17, 0x0a79ec5, 0x015e41c, 0x0fb8833, 0x038a5c4, 0x0a01d98, + 0x1213823, 0x1243d43, 0x01b0a7f, 0x1e1524c, 0x0f9712a, 0x1f9570f, + 0x0fe4f7c, 0x1a5a2d3, 0x15f6fb1, 0x0bc9e06, 0x1899d2a, 0x0dd6f5f, + 0x09f4925, 0x19eca57, 0x1739505, 0x1785716, 0x02d6951 }, + { 0x04e222e, 0x03ecfc8, 0x0427740, 0x1f0de9c, 0x133f248, 0x014f771, + 0x13a2e3d, 0x031a932, 0x1cfc775, 0x0ab9a0a, 0x1d0bc4a, 0x1474161, + 0x196e7fe, 0x013a1a8, 0x0572df7, 0x0e3418f, 0x166711e, 0x0c10547, + 0x0e1d3d5, 0x12bb385, 0x162783d, 0x1c73870, 0x152d935, 0x1254e85, + 0x153f58b, 0x136c921, 0x0511ed7, 0x0440916, 0x1931a03, 0x19865e7, + 0x1a02eb5, 0x14f5e44, 0x1c4d089, 0x1c9fcba, 0x1306e0e, 0x1c8c920, + 0x165b3ae, 0x075d010, 0x117c289, 0x0f1c119, 0x065c48e }, + { 0x0222c22, 0x039e76f, 0x0ed0687, 0x1bf9d44, 0x1683d8c, 0x0a1d832, + 0x12c52c8, 0x0ee0603, 0x159fcec, 0x0256fc7, 0x0133bca, 0x1038624, + 0x07fb1c5, 0x0a39a88, 0x134fbba, 0x11181ea, 0x10b4d31, 0x16dfb3f, + 0x03c6344, 0x07e5a22, 0x001376a, 0x1403e9f, 0x0e027e8, 0x1cfd9c0, + 0x10a4625, 0x0977837, 0x16ca257, 0x1050cfd, 0x10553ad, 0x1a44845, + 0x117841b, 0x1de48a8, 0x0280fa6, 0x0d1e5f1, 0x1e16a36, 0x1a805aa, + 0x1438ba2, 0x1eecffe, 0x089bfd8, 0x058f4d6, 0x036b5cd }, + { 0x05679a7, 0x1a7102a, 0x1d421ff, 0x028a418, 0x04d80b4, 0x02ce6c3, + 0x15fea6d, 0x1472146, 0x1c85af1, 0x0cf579c, 0x0d697a8, 0x1af31b2, + 0x0a0d475, 0x1c0d33c, 0x140660d, 0x1d020e8, 0x1790cc2, 0x03a41cb, + 0x1d04891, 0x043a225, 0x1a37c6a, 0x1c9b528, 0x0343a17, 0x14e9bf1, + 0x0151eea, 0x0e27fa8, 0x1e4f3e6, 0x09c3054, 0x0a9ab61, 0x1ef89bb, + 0x1fd1564, 0x0a44713, 0x0f73caf, 0x02f450c, 0x0583dd1, 0x11a4f99, + 0x19a51dc, 0x097a629, 0x0ff601a, 0x089b673, 0x008d7c1 }, + { 0x0cca773, 0x006cb1f, 0x055a027, 0x05a9184, 0x07ea919, 0x15eb20c, + 0x135d36d, 0x1bfe1d9, 0x02a678c, 0x19891ba, 0x01edf9d, 0x1b17a2b, + 0x067a966, 0x1098526, 0x1068405, 0x02f7be7, 0x0385fce, 0x03e6374, + 0x0379ea9, 0x12b7715, 0x08e395e, 0x1ac4c18, 0x0ff87a2, 0x08ed294, + 0x1243ee3, 0x15f80cb, 0x0aec334, 0x07fd388, 0x1b2b49f, 0x093207c, + 0x07ed641, 0x18e6cfa, 0x0385e8b, 0x10a3da6, 0x02bad7b, 0x123a60a, + 0x04004ad, 0x161c3c8, 0x0080a38, 0x1dd756e, 0x05f2aa8 }, + { 0x066524b, 0x06a3209, 0x1d9b882, 0x01a1433, 0x17bf388, 0x08375fd, + 0x1a17b68, 0x08d4b54, 0x1e642dd, 0x134f469, 0x0b93582, 0x18c38d0, + 0x0cef349, 0x07e5a9a, 0x1dbb8ec, 0x0cf704d, 0x12705eb, 0x13ed5d0, + 0x02f817d, 0x1764fc3, 0x05d12ba, 0x1d4716c, 0x0566bf2, 0x1b3a70d, + 0x12d1ae2, 0x03776e7, 0x187a9bc, 0x13b8a5c, 0x0e5ae85, 0x1c5a433, + 0x11f0a09, 0x00579a7, 0x1ff0340, 0x1f417ec, 0x11d9e12, 0x09d1095, + 0x03c9f22, 0x0b24c04, 0x1e5268c, 0x13168df, 0x062501a }, + { 0x1264086, 0x1becd56, 0x12f558f, 0x174bc1c, 0x0a6a33d, 0x069eb3e, + 0x0c00a32, 0x033d04a, 0x046e64b, 0x1446d64, 0x0914da8, 0x032e415, + 0x0cfa3c9, 0x16aa9f5, 0x0c326c3, 0x157a702, 0x0e02ea8, 0x1b11403, + 0x1b33f9d, 0x17ea9b9, 0x1b7052f, 0x18a7868, 0x0f66a38, 0x1362e83, + 0x12133d5, 0x14528ce, 0x1269bfa, 0x1ae8203, 0x04eb10f, 0x1bd05ae, + 0x17b46b3, 0x123f3b4, 0x0499b73, 0x152c33c, 0x1127037, 0x1557549, + 0x01f3531, 0x0e2fb9d, 0x1199732, 0x1fdfa7f, 0x0497b15 }, + { 0x05568e9, 0x165d57a, 0x09be295, 0x1d8e325, 0x1491a0f, 0x1929cd7, + 0x0f74e6a, 0x153b760, 0x04ac37d, 0x032917c, 0x03d6d32, 0x1744054, + 0x1f8c8cd, 0x114e29c, 0x027f1d6, 0x1e05d02, 0x131ca90, 0x1ce6836, + 0x1885b6f, 0x03e0887, 0x1d918f3, 0x165d1f5, 0x066a9a2, 0x1800fe9, + 0x0d0d242, 0x1e71540, 0x1e1aa6d, 0x1b1bff7, 0x108edcd, 0x1f426b1, + 0x1290174, 0x00d0025, 0x0fa33fe, 0x10838ed, 0x144fb7a, 0x0d85dd7, + 0x0ff637e, 0x173f2e1, 0x132dede, 0x0d93ca2, 0x018d46a }, + { 0x18b7802, 0x05d9153, 0x0bd21a3, 0x0492f97, 0x0745ddb, 0x17456e8, + 0x0bcf90a, 0x1c989d6, 0x0b4ceb4, 0x0055e6d, 0x17f502b, 0x064b464, + 0x052e0d8, 0x09d639a, 0x1f815c4, 0x0e372d9, 0x188b141, 0x1ba03d3, + 0x169e94a, 0x160c06d, 0x16ac70e, 0x1cec28b, 0x0ac2cdb, 0x052a9e7, + 0x09d297c, 0x0d68a08, 0x03735c1, 0x0e1bd39, 0x15e7513, 0x1ae6bdd, + 0x030fc36, 0x140dce1, 0x1f93d41, 0x18286a2, 0x1e29fa4, 0x1221aa9, + 0x1a38fef, 0x137c722, 0x0b901a7, 0x003a7ec, 0x0550446 }, + { 0x0cb9cc9, 0x0e48803, 0x0053471, 0x0e83a00, 0x142074d, 0x11b7dc2, + 0x198f844, 0x104f9b0, 0x029ad5f, 0x0b90fff, 0x07f20ce, 0x17f452a, + 0x0f1d21f, 0x00068a2, 0x1781b9d, 0x05cd639, 0x16b9179, 0x148212c, + 0x06b5459, 0x0b91ca5, 0x1e98336, 0x02cd777, 0x188883a, 0x1855dc7, + 0x1318970, 0x05e5e5a, 0x0e7fc40, 0x0ef947b, 0x12973f4, 0x00bb7a9, + 0x06c9c1d, 0x13457a0, 0x12118ac, 0x1cfc9d0, 0x0824f75, 0x17e684a, + 0x06f5d7d, 0x1d47fbe, 0x1b13d58, 0x1f9af61, 0x00da313 }, + { 0x1aa2557, 0x12d460a, 0x1a70dc4, 0x1801127, 0x0a21d70, 0x1c5411e, + 0x0e6519e, 0x05490e2, 0x07cb004, 0x09f4d3a, 0x0b38603, 0x09ff93c, + 0x022d2bf, 0x024d756, 0x14c6834, 0x00cc1aa, 0x016f03d, 0x02694d3, + 0x1c6dfc0, 0x1aa1ac3, 0x050c473, 0x1de51ef, 0x0ebc3b2, 0x1851e4e, + 0x19bea09, 0x132714a, 0x03e1c11, 0x1af85d4, 0x1083ef6, 0x1270b98, + 0x152b7eb, 0x128384a, 0x0940c26, 0x11681a8, 0x1042845, 0x1c882ce, + 0x1e82290, 0x01186c0, 0x12b3188, 0x1d1b682, 0x063630b }, + { 0x07d2e41, 0x0a91145, 0x01e6fe3, 0x07d6c5f, 0x09e7582, 0x0016c4a, + 0x0cf75b1, 0x15a369a, 0x0de2c59, 0x01f026b, 0x0770e22, 0x11e8937, + 0x0cbf3f3, 0x1a5b862, 0x065f462, 0x1408b3b, 0x00c13ce, 0x08fb4d9, + 0x038981b, 0x1ae04ab, 0x1b79ca3, 0x1b930e8, 0x0f53f65, 0x0286df4, + 0x0afa85a, 0x003ab57, 0x02ed10f, 0x0d367d3, 0x18f6be3, 0x0c3672a, + 0x027f394, 0x1f1591f, 0x10cd478, 0x0d53975, 0x1cdf579, 0x00d00e9, + 0x08544eb, 0x0c22e03, 0x023b4a5, 0x0e3e2cd, 0x0306a98 }, + { 0x14ec136, 0x08f4eb1, 0x163ef11, 0x141cdec, 0x1edf27c, 0x0da0900, + 0x0054b03, 0x0cf537c, 0x0c5bfee, 0x1db7790, 0x15808e1, 0x0471345, + 0x1935283, 0x03d7dc4, 0x1959363, 0x185bcc1, 0x1c00ac9, 0x1a57915, + 0x0aa748a, 0x0dec630, 0x101b28e, 0x00fa993, 0x101d71c, 0x00ebf23, + 0x018f882, 0x088fb6a, 0x146faa9, 0x13f4c51, 0x12a13df, 0x1d0bb73, + 0x0715479, 0x0efe980, 0x106215b, 0x0eac449, 0x1cc64f2, 0x08e3574, + 0x18e57cd, 0x01f5f02, 0x0f8dd91, 0x083d020, 0x02833ac }, + { 0x1a5ec5c, 0x125c346, 0x0c91f95, 0x103811b, 0x0c3d9da, 0x0bd3945, + 0x07c2e31, 0x1853af8, 0x19d343d, 0x08957f3, 0x180ce4d, 0x099ffb8, + 0x01b438e, 0x0e7d0ca, 0x1689c03, 0x00892fa, 0x1f82732, 0x16af991, + 0x0e4f1b9, 0x0f4b1c2, 0x04311b8, 0x08825d5, 0x1b2da2f, 0x04569af, + 0x01c5a47, 0x1d5604e, 0x1c81ad7, 0x085f552, 0x16327ef, 0x1e6b4cb, + 0x1678772, 0x010ef0f, 0x15ba9e4, 0x000c8b2, 0x1d5f797, 0x117ab38, + 0x0bcf353, 0x1810768, 0x18c0d9c, 0x0a9493a, 0x0120cd4 }, + { 0x0b0f9ee, 0x0dc7a65, 0x03bbaff, 0x00599cb, 0x1c003ef, 0x068332d, + 0x1a1056a, 0x0e936d4, 0x09b9577, 0x01769d3, 0x06ad719, 0x0fe08e4, + 0x133de48, 0x10d2786, 0x0bfce00, 0x1bb9bde, 0x15829db, 0x15e8b7a, + 0x1a4f7fc, 0x00b6961, 0x0ec12ef, 0x0905e4d, 0x1787ea8, 0x0cff525, + 0x0e2c2d4, 0x11a336d, 0x117accf, 0x0b1b5ec, 0x0103cb7, 0x0cfb478, + 0x0c299eb, 0x137c048, 0x11f693a, 0x02a5e0a, 0x125bad0, 0x1daad30, + 0x1019336, 0x18b3bf3, 0x1a8fa3b, 0x02cffbd, 0x0021cfd }, + { 0x15c36f3, 0x1b8afef, 0x095171c, 0x0fac95a, 0x103bde3, 0x07bb89b, + 0x03443cb, 0x190aa6d, 0x10f3993, 0x12f63db, 0x0b93287, 0x0eec609, + 0x0bfdb16, 0x1e9dd8c, 0x03dc5f8, 0x07ab41b, 0x13f6634, 0x0a93383, + 0x158022d, 0x16a5de2, 0x070ffae, 0x1c91252, 0x0e5eb57, 0x0556a35, + 0x0e391ed, 0x01657c3, 0x1e65d0c, 0x1818fca, 0x0ae28ad, 0x140bfe8, + 0x073223e, 0x17f1dab, 0x07c22df, 0x145db40, 0x08c7ac4, 0x06bbdb8, + 0x020595a, 0x16e6ce5, 0x1de39c7, 0x08d8e79, 0x007265b }, + { 0x166232f, 0x0ccf85e, 0x1c59cf7, 0x138804e, 0x059aaf8, 0x0307e26, + 0x1b7e96e, 0x0775f04, 0x07a943f, 0x1cf5455, 0x110a348, 0x1634a47, + 0x1a0e0e1, 0x14b9dca, 0x1a838e9, 0x0ea76ab, 0x0aa2557, 0x1f51cce, + 0x1a55ec7, 0x1bee5e0, 0x0302f8a, 0x009de9a, 0x00e27cd, 0x148752e, + 0x127d0f8, 0x0b7999f, 0x02b6bde, 0x1b38181, 0x012aa2c, 0x124da4e, + 0x1a5b732, 0x0f4158d, 0x188deee, 0x004076e, 0x1d74191, 0x1b1e8ea, + 0x0cc2f4b, 0x0eb33e8, 0x125b1ba, 0x09663a2, 0x036c575 }, + { 0x123d84b, 0x0023779, 0x113e448, 0x04fcf13, 0x0699112, 0x0dc02ad, + 0x0bd3a48, 0x09c961d, 0x0807997, 0x19cc225, 0x1e31e58, 0x0cd4e81, + 0x09c9054, 0x06b6f7a, 0x06343df, 0x1c97438, 0x06b4b23, 0x0a94bed, + 0x1060031, 0x13bfe78, 0x07771c0, 0x0d9bf7b, 0x1b1241d, 0x0a27bda, + 0x03a4050, 0x182d4a6, 0x05ac2c5, 0x1ace85d, 0x0af5ae3, 0x024a624, + 0x17b01e1, 0x192b045, 0x0c01532, 0x06ca7a0, 0x1797059, 0x0b45bb5, + 0x02975eb, 0x054564d, 0x0513bf2, 0x0c2328d, 0x006fbf8 }, + { 0x145aa97, 0x099c71f, 0x1facb59, 0x103a081, 0x183b58c, 0x0f7c5ce, + 0x1d66c3f, 0x0f80bfd, 0x0e4d741, 0x1f5838d, 0x08688de, 0x03eb661, + 0x03982b6, 0x1db2de8, 0x17ca8ab, 0x0d7e698, 0x09d5cbf, 0x0f2055e, + 0x01984a9, 0x1864dbe, 0x0e28422, 0x0ecab8d, 0x124879a, 0x1a6869d, + 0x0b10b23, 0x099be44, 0x1e7681e, 0x0da5d2a, 0x19cf4d9, 0x03509b0, + 0x0860cf5, 0x1b2bddf, 0x1d19653, 0x147876c, 0x104680f, 0x0254fb0, + 0x04bb5ab, 0x1214a98, 0x0a7a979, 0x1fa3e1f, 0x05e9ca0 }, + { 0x17c5dc4, 0x0a2b88c, 0x16896f5, 0x1fcf152, 0x02da40b, 0x0d87597, + 0x07bf3ff, 0x0f8cbf7, 0x00d1746, 0x0a96e16, 0x031a8fa, 0x18f78eb, + 0x1ac1fc9, 0x0a01a54, 0x1e558b3, 0x096adf8, 0x1be61f6, 0x19371b7, + 0x1a11ca2, 0x18973c3, 0x0c8a6ad, 0x09d47cd, 0x1fc597f, 0x1c7c026, + 0x13a4503, 0x071bde4, 0x0d9591e, 0x1598aa2, 0x0ddc77e, 0x0b8b832, + 0x0534ce4, 0x0ed26d2, 0x1b318dc, 0x012533a, 0x071cd89, 0x08d363e, + 0x09955f3, 0x01022da, 0x1abe233, 0x1678d06, 0x0940622 }, + { 0x1997973, 0x0665b86, 0x04551c4, 0x1ba7f1e, 0x1b29625, 0x0bd5ea9, + 0x113556e, 0x14b19e1, 0x0673e14, 0x1190f05, 0x18891b1, 0x1f3a7a4, + 0x110541a, 0x17e41d8, 0x1b61d51, 0x0a549bc, 0x1a8f016, 0x123f4be, + 0x16600ad, 0x05674d5, 0x04b20f8, 0x1ad74e2, 0x1a6a901, 0x1a57eee, + 0x15de2ce, 0x06d579f, 0x0925e90, 0x1de3d51, 0x03ba9c1, 0x03041e1, + 0x120b83e, 0x1e32145, 0x0a998a4, 0x119b46c, 0x12333f7, 0x03c5693, + 0x1de6bd7, 0x1a4c125, 0x1b6dae7, 0x0c8f0b7, 0x080bb16 }, + { 0x1145cb5, 0x0baff7e, 0x020c179, 0x0358bcd, 0x155ee56, 0x09d9398, + 0x1c33e1e, 0x0708c3c, 0x0133b23, 0x18aa9ef, 0x1ee81e7, 0x0187454, + 0x1a2fb9e, 0x1f38437, 0x0ff5aa0, 0x1972787, 0x1008bb4, 0x0db5d42, + 0x1be0b6f, 0x0daf12e, 0x09ff0b6, 0x1b2a75a, 0x1f569bf, 0x0416644, + 0x1d2371f, 0x06e66b2, 0x09538a7, 0x13d4938, 0x118ff97, 0x0cb1e58, + 0x02d925d, 0x198b000, 0x09598dd, 0x03bce4b, 0x0460443, 0x0b2a20f, + 0x03b85a3, 0x1e0aa43, 0x08d43b7, 0x1d48242, 0x0077ba5 }, + { 0x1d86f61, 0x11c69e6, 0x02ac2ce, 0x0a0a054, 0x0312144, 0x1681392, + 0x1b71601, 0x01e3225, 0x08a32f1, 0x0ee0fcc, 0x031d800, 0x03a21d0, + 0x13bb1d3, 0x1a32745, 0x1bb1f97, 0x093dda8, 0x1369abf, 0x1eab4d7, + 0x136b79d, 0x10dd4e5, 0x19209d2, 0x06a2d6a, 0x0af9c08, 0x1335cfe, + 0x1236e62, 0x003d5f2, 0x174fd57, 0x1262f37, 0x150e80c, 0x0cad291, + 0x01a04e2, 0x15fe0eb, 0x101265c, 0x1cb2984, 0x06cbd1c, 0x02b6790, + 0x1bc77d2, 0x1bac0ec, 0x08b8aeb, 0x1be8b23, 0x06b2006 }, + { 0x05b1bc1, 0x128544b, 0x13f6cbf, 0x152c576, 0x131f536, 0x073fccc, + 0x034cc00, 0x0bdaae3, 0x153d512, 0x0394792, 0x0972be1, 0x0309a42, + 0x1e4f8a6, 0x1abfb3c, 0x1c69c04, 0x180b4a9, 0x00c1531, 0x0b854fa, + 0x1ea2ddd, 0x01972ed, 0x0ce910d, 0x0f4ee09, 0x0d1dbd0, 0x0abf129, + 0x17a7527, 0x0d22e46, 0x01895d0, 0x0d825c2, 0x17b16cd, 0x17dc648, + 0x08098a9, 0x071ad61, 0x0d116e6, 0x1c74192, 0x0300cb0, 0x19092a8, + 0x06868af, 0x0dc88e3, 0x0d54215, 0x14d7a4d, 0x053217e }, + { 0x19f52b4, 0x0023992, 0x11b3f21, 0x17cc422, 0x168da9c, 0x05e9374, + 0x0e17b2b, 0x0892c9d, 0x1e4a543, 0x1bed516, 0x093fdea, 0x1090703, + 0x0f6dc3b, 0x00e40af, 0x1ea5acd, 0x163c340, 0x1e8c3d4, 0x0627d74, + 0x0b3a7aa, 0x071a3c8, 0x052f0f9, 0x061ae60, 0x09c9f6b, 0x140de0f, + 0x001c9e9, 0x0d0e40f, 0x0d29b59, 0x13c11b9, 0x04a9a6a, 0x08b9b02, + 0x16fe38b, 0x1e57a52, 0x1893dd0, 0x00d894c, 0x0de7e5e, 0x05411a6, + 0x01830ac, 0x1eb000b, 0x0fbbd92, 0x03db35b, 0x0038693 }, + { 0x09885a5, 0x1d5d9e8, 0x0c1f435, 0x0fc6ab7, 0x0d9d2b6, 0x175d76f, + 0x0e33d4d, 0x1ac7784, 0x0699ce4, 0x0e5173c, 0x1653358, 0x088e222, + 0x12354ff, 0x0198b56, 0x12f9c24, 0x1eb88ab, 0x1fd49ff, 0x020c33c, + 0x1e71b10, 0x159aea1, 0x121a75b, 0x0414b93, 0x19dfb72, 0x1dea05e, + 0x16887e5, 0x107412c, 0x1efcc83, 0x0b3d26c, 0x1dccb24, 0x1b77c5d, + 0x0f60738, 0x16ecd0c, 0x1a097fc, 0x036dc0d, 0x075b563, 0x179a744, + 0x14a8748, 0x04b3e6d, 0x0708039, 0x0922a08, 0x02caaf7 }, + { 0x0d20424, 0x0c00337, 0x151513e, 0x06448e2, 0x13e4ea2, 0x0d46435, + 0x14695e0, 0x0164d1d, 0x17ae5b7, 0x06855ba, 0x14e6092, 0x06406ad, + 0x046ca8b, 0x16f98fd, 0x1a39a04, 0x1b9e539, 0x032d925, 0x15c84e9, + 0x159c8f7, 0x191ef1e, 0x16f9302, 0x14d5d64, 0x045c975, 0x1a342e0, + 0x047ca57, 0x1f3b2b5, 0x070628a, 0x176baa2, 0x10d9d96, 0x02f8d6a, + 0x062d5b9, 0x0e160aa, 0x0e886e2, 0x07fc89b, 0x1cf4276, 0x1d8f8e3, + 0x1350361, 0x10ddf14, 0x0ef6196, 0x0648bfc, 0x086d7f5 }, + { 0x0bf719a, 0x0b75b58, 0x044e67c, 0x111787b, 0x1697509, 0x0680da5, + 0x039489b, 0x039f5ca, 0x090898d, 0x1f1d62a, 0x1b199b4, 0x13b710f, + 0x184da3b, 0x1df522d, 0x0c01913, 0x160b0b0, 0x1d98355, 0x19b4f9d, + 0x1e6f304, 0x047350a, 0x18110fb, 0x1cb715e, 0x13d6d14, 0x0331fa4, + 0x13baf24, 0x08e803f, 0x0e20df5, 0x114cedb, 0x075b166, 0x1531757, + 0x0f1a3bb, 0x07b6c10, 0x1fe5f94, 0x1b62d2f, 0x143df60, 0x0aa5929, + 0x0bc1ff8, 0x061e37e, 0x0d37569, 0x1c70d81, 0x0682a55 }, + { 0x07495aa, 0x11ad22c, 0x117723c, 0x18698e4, 0x0276026, 0x0d23719, + 0x03316dd, 0x1cfad5c, 0x1ecc3e5, 0x0869cb2, 0x0598a62, 0x085e285, + 0x071b133, 0x0543b91, 0x0649f9a, 0x14d1791, 0x07e2324, 0x10aa1f9, + 0x0737086, 0x08ed089, 0x10ac6c4, 0x078a296, 0x06f1ff5, 0x09608b9, + 0x10a31ff, 0x1089661, 0x0214bdd, 0x02ba8d4, 0x1dd7a64, 0x1829637, + 0x046b5cd, 0x0f698f9, 0x0ecc3ab, 0x06b866e, 0x006dda2, 0x0ba59be, + 0x040d390, 0x0792a17, 0x1373415, 0x14dfdfc, 0x002227f }, + { 0x151948b, 0x0f7ecdb, 0x0974601, 0x0dfbfa4, 0x0efeed4, 0x1645914, + 0x038253c, 0x1cb9625, 0x196f7c5, 0x088485f, 0x0fb2827, 0x0089699, + 0x040959d, 0x0704658, 0x12557e6, 0x09f9c43, 0x19d68fa, 0x15e0f93, + 0x1c42ba6, 0x03c29c0, 0x07f4b02, 0x0fc408b, 0x19345ba, 0x193e34a, + 0x1c22ebb, 0x1757ad2, 0x1f8d083, 0x1e6e2db, 0x04e8435, 0x1c8aeae, + 0x0065c7a, 0x051ff75, 0x0fc55fc, 0x1babc32, 0x1535f74, 0x00684fc, + 0x15ebc7d, 0x1735310, 0x05de111, 0x134524d, 0x0547e24 }, + { 0x1ffda27, 0x1434550, 0x1d411c1, 0x18f2ab9, 0x14e6cdc, 0x11f9ec5, + 0x1478429, 0x015eca2, 0x09de5e7, 0x1a093f5, 0x10a08d6, 0x1375f26, + 0x113d2c0, 0x1517bea, 0x126760e, 0x1804a31, 0x11dddee, 0x15062dd, + 0x0f73c73, 0x1bbf080, 0x1eda7ff, 0x14b0b7e, 0x195f934, 0x06543e1, + 0x1656979, 0x071e922, 0x00c6475, 0x08ebc1d, 0x00218b7, 0x1f50e11, + 0x014d1e6, 0x117964a, 0x0eb5c90, 0x099737e, 0x13a8f18, 0x1638d0b, + 0x1fe6c1e, 0x16e3a2d, 0x03bab10, 0x181a561, 0x045a41c }, + { 0x1bbf0e1, 0x0d963a6, 0x1c38faa, 0x1f42f9e, 0x01ff962, 0x15a6332, + 0x09d617b, 0x0fdb83d, 0x0a9beb1, 0x1aa0969, 0x15d0693, 0x1ea5450, + 0x1f2c9e4, 0x0c27e88, 0x17df692, 0x0309d27, 0x1dc0df3, 0x0d957de, + 0x10878dd, 0x047a4a4, 0x181e963, 0x1224efb, 0x121ef87, 0x0b137d5, + 0x001ed3d, 0x16e8a2b, 0x14a3ffd, 0x1e17b37, 0x0f298c0, 0x0cea450, + 0x110b4c9, 0x1b11cd2, 0x02d7a77, 0x0157b1b, 0x1adadab, 0x0550980, + 0x1087da0, 0x028564e, 0x10322ea, 0x19285dc, 0x0128763 }, + { 0x0bac178, 0x00783d6, 0x1db8a6a, 0x0869611, 0x1cc2004, 0x1f6f693, + 0x07451c3, 0x0cfd2c6, 0x1866157, 0x108aed1, 0x021522c, 0x0b89961, + 0x037c75f, 0x0d17470, 0x0a7484e, 0x02ea4b6, 0x0668b88, 0x07f4fed, + 0x0779faf, 0x1b1b118, 0x01233f1, 0x0f0190c, 0x0d1d959, 0x1932be7, + 0x05561b1, 0x18d839b, 0x02c4fad, 0x02c1963, 0x13a0eb2, 0x1289ccd, + 0x1d1fa36, 0x1641f9a, 0x08ca1f9, 0x136b92f, 0x019ed04, 0x1ed4fc0, + 0x08bb637, 0x01025bb, 0x1d3487a, 0x199f89e, 0x075e96b }, + { 0x119716e, 0x08fee06, 0x1494627, 0x10f8708, 0x1f58505, 0x0c3e956, + 0x11b47aa, 0x01ec950, 0x16c0715, 0x15b5fc1, 0x1f56dc4, 0x1a8c9ad, + 0x1f91d85, 0x07a9faa, 0x1e220d9, 0x1225352, 0x1d88150, 0x030041d, + 0x0a1dbd2, 0x0e4d07d, 0x0489a76, 0x1d60ad9, 0x1a02cb9, 0x1a3b325, + 0x0f8d242, 0x0494c2f, 0x073cf79, 0x18af605, 0x0876279, 0x1c1e58a, + 0x01ff80b, 0x115cb6d, 0x0ba4fe4, 0x1c0cb57, 0x026d75a, 0x1b150de, + 0x016e523, 0x07ab35d, 0x0252762, 0x135744d, 0x0309a6e }, + { 0x1fbe97a, 0x1f7285e, 0x1137bc9, 0x1f718a1, 0x1a5fe70, 0x104fae0, + 0x1ac05ff, 0x18b98f7, 0x1bed36c, 0x1d0ad42, 0x03b4ea3, 0x19b6eaa, + 0x01c0c3a, 0x15c8434, 0x007be1f, 0x0b9978b, 0x162c49d, 0x050ad99, + 0x1e8993a, 0x162e283, 0x0e880fb, 0x07c70f7, 0x099fe36, 0x1856c7a, + 0x0cfd621, 0x17ee98e, 0x154ef9f, 0x049b7cf, 0x0a358a9, 0x03bfed9, + 0x10750ba, 0x0ebad15, 0x19673c7, 0x1f52ae7, 0x03f5c53, 0x05c6b2f, + 0x1769b20, 0x19b329a, 0x0de27ba, 0x115aeb2, 0x0045825 }, + { 0x042dbdf, 0x18d3a50, 0x1e8977d, 0x0eaef3b, 0x0d40585, 0x17332b9, + 0x12e9c34, 0x05c1ccd, 0x1ca2e89, 0x02eb3a2, 0x19ad7ca, 0x1bde1e1, + 0x03f56a8, 0x1183b3e, 0x1ba1476, 0x0d739c1, 0x0584334, 0x14c602b, + 0x1acf1d0, 0x1f9c4da, 0x1e00b35, 0x1f9cbbb, 0x102256f, 0x16db10d, + 0x0f6a6e7, 0x025c1e4, 0x0d3c0a4, 0x1dc2908, 0x04ec34b, 0x08ad974, + 0x045fdd2, 0x12da213, 0x0af663c, 0x1d6605d, 0x1d5f907, 0x1200970, + 0x0f86c02, 0x1c4072b, 0x1cd628a, 0x1c12b6e, 0x053f4a3 }, + { 0x1fc48e7, 0x1846744, 0x0bac46e, 0x0f5f56b, 0x1a60c57, 0x00e5ad5, + 0x12fe283, 0x16de0d7, 0x079757c, 0x0977d75, 0x064581f, 0x0162ec6, + 0x09e26d9, 0x15bbdbd, 0x0a86ad8, 0x1e57e85, 0x0cd285d, 0x01c7760, + 0x0ea3dfc, 0x128febe, 0x15b5d35, 0x077e0e5, 0x05f2370, 0x0b08b9f, + 0x0cca0c4, 0x1797f5c, 0x0492789, 0x0dd1b31, 0x1ed89a1, 0x0736a41, + 0x1cdf099, 0x0a3b220, 0x1a3f145, 0x14cf809, 0x18b8c17, 0x070a02a, + 0x0908d56, 0x1cc6ba3, 0x148daab, 0x0a7ae47, 0x00a99e6 }, + { 0x1bc0559, 0x1b7a355, 0x05808d4, 0x1735434, 0x0163067, 0x0b40dae, + 0x148a430, 0x00e453f, 0x11378e9, 0x092a5f0, 0x04e8b58, 0x0af556f, + 0x1bc60ff, 0x0332a96, 0x1cb7e2d, 0x0146d4d, 0x0938c17, 0x14d698c, + 0x06dd366, 0x1b357c5, 0x0523c5c, 0x19fbc24, 0x13dd1c9, 0x01c60c7, + 0x0a93a0d, 0x1ec6093, 0x0d09238, 0x1c4043c, 0x03ddfaf, 0x01f7419, + 0x19f65cd, 0x0664c73, 0x1768775, 0x12aa44f, 0x10c5d4c, 0x152ca1f, + 0x1eebf7e, 0x0aede89, 0x12f02d6, 0x08a021f, 0x03a95cb }, + { 0x1d7ff2e, 0x134659c, 0x123e553, 0x1783ab8, 0x0dd1cb4, 0x14a1c54, + 0x0b1ddc5, 0x19c0552, 0x091cad8, 0x0b2e058, 0x142349e, 0x1156659, + 0x1a0c579, 0x134815e, 0x16f0f0e, 0x1a43034, 0x1255186, 0x1aa2e84, + 0x09f9936, 0x0ef9b7a, 0x12daf00, 0x1246684, 0x0055f2a, 0x0a65566, + 0x1a3a024, 0x1d19517, 0x0d0732a, 0x0bf6c73, 0x04aee6a, 0x16e0a3a, + 0x16805c0, 0x19b7527, 0x05bb436, 0x1c278a4, 0x1d98ca5, 0x0726b2f, + 0x1ad672c, 0x189e0ee, 0x1c91575, 0x05c0616, 0x0366d22 }, + { 0x13ea5b2, 0x1a43aab, 0x1137542, 0x17521b4, 0x0fce401, 0x0d01880, + 0x1e995e8, 0x0c0f6a7, 0x1cf1144, 0x1154052, 0x02fd25c, 0x1e0b4a7, + 0x010b8eb, 0x0995669, 0x050451f, 0x1a0fb5c, 0x12c7b5a, 0x1b34938, + 0x1d23281, 0x0bfdce7, 0x18d86dc, 0x0c95c53, 0x063b452, 0x05e2eb3, + 0x13145dd, 0x1c72745, 0x057e5c6, 0x06811bc, 0x11b3684, 0x136ed6f, + 0x1f8157a, 0x1cb2656, 0x1b76e73, 0x049fea5, 0x054f4c2, 0x148850e, + 0x0661bfd, 0x1ee6690, 0x1f4945c, 0x132f3bd, 0x09072ba }, + { 0x020ea39, 0x0f26ecb, 0x1ba11d3, 0x1f90639, 0x1bf1649, 0x1d4e21f, + 0x02ec734, 0x1aa161d, 0x13f3df1, 0x11c1437, 0x1b26cda, 0x05671e1, + 0x034ed07, 0x194e04f, 0x193261d, 0x044854d, 0x0c68ad1, 0x1751f45, + 0x0f7e96e, 0x01c457f, 0x15926ae, 0x07d8507, 0x1585c7b, 0x10e3f1a, + 0x0886d6b, 0x1ed19d9, 0x04d7846, 0x16337d5, 0x0f153f6, 0x0d203f8, + 0x1b93605, 0x0fad805, 0x0608d97, 0x047a33f, 0x0f66daa, 0x08fd1e4, + 0x039d165, 0x164b292, 0x1b0a49a, 0x17a6aa8, 0x08d92c6 }, + { 0x1eb0ff7, 0x06be755, 0x0be2cf8, 0x087c1c8, 0x1be3525, 0x00424cf, + 0x0c89b7a, 0x186afa3, 0x11cd44b, 0x167170f, 0x13fb867, 0x1b7886b, + 0x1c1245a, 0x1c9fac0, 0x13ba103, 0x1728f0e, 0x19cbda0, 0x148b53b, + 0x095eb82, 0x1902b5f, 0x01b0abc, 0x16f8531, 0x05eb7b0, 0x1f217b9, + 0x0502b81, 0x11edf35, 0x054ef79, 0x097f3bc, 0x084c255, 0x0d5fbc4, + 0x1c2a23f, 0x19776a8, 0x0aa52b1, 0x09f7a98, 0x05b0a41, 0x15f00a7, + 0x0dd827e, 0x01ec4c4, 0x1970235, 0x02eb835, 0x04e4bec }, + { 0x0c09676, 0x041d17e, 0x0a52fe1, 0x1e33d53, 0x057c4a3, 0x0152eea, + 0x0bbcf5c, 0x1b14d0a, 0x0843fe7, 0x1c8afe9, 0x0d45639, 0x15302dc, + 0x10644bb, 0x0f6ba37, 0x06e5742, 0x1e16b1a, 0x181b90a, 0x123b822, + 0x13f44d7, 0x0978d7a, 0x13a50bd, 0x13da741, 0x09b7381, 0x0ad5343, + 0x08f30ff, 0x1ff1607, 0x03b0b18, 0x1390100, 0x1508a8a, 0x1052cc7, + 0x0e91270, 0x0652502, 0x0b94cb3, 0x140d101, 0x14a3b1f, 0x0ec8fc7, + 0x1487767, 0x133e8d5, 0x1b491cb, 0x1eadf3b, 0x07a4aa3 }, + { 0x07a0045, 0x178dd71, 0x0d41567, 0x1f64859, 0x1c812d4, 0x07c6926, + 0x1e390e7, 0x0a84748, 0x19b3f9c, 0x1aa27e2, 0x087f3e5, 0x02655ff, + 0x1b5ac68, 0x1a51641, 0x1e3fb80, 0x0976ee9, 0x00fcd3f, 0x14b6632, + 0x0144ba9, 0x1b9d3b6, 0x181e775, 0x0ee6e71, 0x19f7286, 0x1a7fcaa, + 0x0b3f3a9, 0x1a7e0f7, 0x0868649, 0x11c17e8, 0x169b123, 0x17da146, + 0x1e05664, 0x13fa13b, 0x0fcebde, 0x15aefa4, 0x093ed06, 0x0bb93bf, + 0x00a269c, 0x1ebee46, 0x0b78432, 0x0f7efe1, 0x060282a }, + { 0x0eea2e7, 0x1f29c6e, 0x1875f01, 0x1078840, 0x18a322c, 0x0fb28b1, + 0x0a3e53c, 0x020ced0, 0x1c7776a, 0x10db4fd, 0x1ad017c, 0x082f6bc, + 0x02c63a3, 0x08d3db2, 0x067c962, 0x0288099, 0x0a82cad, 0x09c3496, + 0x021a6f3, 0x105ffc0, 0x066af1e, 0x070b7f2, 0x10c2dc5, 0x0032271, + 0x142f919, 0x1572fdb, 0x003e945, 0x1202cda, 0x073a43e, 0x1bd66c6, + 0x1c95543, 0x1f78b86, 0x16a407d, 0x01cf696, 0x14e5a33, 0x01c8f4e, + 0x0a5fbe7, 0x09436ca, 0x0e508ff, 0x18e478d, 0x05f4ae9 }, + { 0x1f4d561, 0x116ed29, 0x064b65a, 0x002db43, 0x086d45d, 0x0a58289, + 0x007eff7, 0x1d48934, 0x19f2195, 0x0a44506, 0x1986cc9, 0x161546e, + 0x02c4151, 0x1cf2f70, 0x0311c7b, 0x1102f73, 0x06ea865, 0x1525e54, + 0x09a3f02, 0x15b70ef, 0x06a9bbc, 0x04b5b9b, 0x022cd19, 0x0cc385b, + 0x098d415, 0x1061977, 0x1b24050, 0x0b67698, 0x0752aff, 0x139a979, + 0x07288d4, 0x0a21c9b, 0x164ce73, 0x0554017, 0x1c9ab29, 0x072734f, + 0x001aa50, 0x09f148a, 0x0bf4a73, 0x047b88d, 0x092a014 }, + { 0x02f7dbd, 0x125f08e, 0x1feba7c, 0x1f6faa4, 0x1a8c900, 0x0478946, + 0x096ee19, 0x0832c7c, 0x0481419, 0x15b89f1, 0x1d5bee6, 0x1a02f4c, + 0x1de87f7, 0x02c6c85, 0x1376178, 0x0d57a4e, 0x07a8256, 0x0c11ff7, + 0x1090065, 0x0461aee, 0x046e9f6, 0x16565af, 0x0115e7c, 0x14990fc, + 0x0626316, 0x02b9511, 0x0f666c2, 0x1943348, 0x08789e9, 0x15d1f24, + 0x0f61b70, 0x1280d87, 0x160b5b9, 0x04abf7c, 0x0a2e258, 0x16de588, + 0x161c515, 0x1a43830, 0x12e6e41, 0x03d5511, 0x00fc8fe }, + { 0x0b90f2d, 0x10df6ff, 0x1565a2b, 0x1949162, 0x1393bb3, 0x074b1af, + 0x0be73d9, 0x18457cc, 0x0f8be75, 0x0a61208, 0x1dd4a4d, 0x0e06bcd, + 0x11bd7ea, 0x0b16559, 0x1921a38, 0x1e7ff84, 0x070c860, 0x1589c8f, + 0x16260df, 0x0cf8ea3, 0x0941df3, 0x1a15f99, 0x18542da, 0x182631f, + 0x0f46e78, 0x0b04af4, 0x0e8b12c, 0x167e3b5, 0x1afbf32, 0x1ae7380, + 0x1171b33, 0x0bd10e9, 0x0d27530, 0x16e5f1d, 0x1945771, 0x1a7250b, + 0x199892d, 0x0aa6c36, 0x1e27cf2, 0x0c5bfa6, 0x02d0ba8 }, + { 0x072e1af, 0x0c7745a, 0x0f33ab3, 0x1d6ed57, 0x0b354ea, 0x0c9fdef, + 0x02fe343, 0x00d36a4, 0x1fe6fc7, 0x066b06b, 0x18bce7f, 0x1bbd49d, + 0x1ea9353, 0x0d40f28, 0x0c2497a, 0x0ceeebd, 0x1a1d136, 0x0f719a6, + 0x14d535a, 0x05193fa, 0x0d54c1d, 0x0ac952f, 0x0e5dc5d, 0x1ee1b03, + 0x0367fb7, 0x13d2e9f, 0x0aa4ceb, 0x17cfdd9, 0x1cfbb77, 0x18fcf11, + 0x0049933, 0x11292ed, 0x1129f4a, 0x111ad86, 0x169026d, 0x14e0a6e, + 0x08a376d, 0x1b263aa, 0x16ff333, 0x0249a83, 0x0963c87 }, + { 0x036a814, 0x14865ef, 0x0ad6eb8, 0x0ae6762, 0x1bdb019, 0x1ff070c, + 0x1619fdd, 0x1d41d75, 0x129720c, 0x13e8cfe, 0x07b1c82, 0x0ca3205, + 0x1e434d7, 0x1da8c88, 0x1abfc5e, 0x0fec10a, 0x19ad80a, 0x168512e, + 0x0123041, 0x150d5ff, 0x149cffc, 0x1ca1d6b, 0x14fa2f7, 0x1cd2d76, + 0x00284e3, 0x10afdcf, 0x0bbbb90, 0x1d6cc61, 0x0f3c633, 0x1dcf176, + 0x102763e, 0x09c0181, 0x1da4ffa, 0x1df5638, 0x1965755, 0x1f652d7, + 0x08cec7e, 0x08fdd6d, 0x15ef45d, 0x079feab, 0x02d03eb }, + { 0x0f2ec1d, 0x1492f82, 0x1b8bac5, 0x0c1a28f, 0x0878f27, 0x0cecf05, + 0x1d812ab, 0x0b6885b, 0x13f7103, 0x08efa25, 0x05756e2, 0x0567197, + 0x03c2827, 0x0f74769, 0x053bed5, 0x1e7c6de, 0x00f13b0, 0x179e223, + 0x0f5ccd7, 0x1f37aed, 0x1a6e889, 0x18fbaad, 0x0227b9d, 0x04336d9, + 0x184feed, 0x008b134, 0x1fb0bb9, 0x1a898e6, 0x0fcd372, 0x02d131f, + 0x1aee50e, 0x0cc6f04, 0x109321b, 0x15bd3ec, 0x09e4fb9, 0x0f849f1, + 0x07cf61b, 0x0546925, 0x0b3668f, 0x1838a97, 0x0842e40 }, + { 0x061d843, 0x1476b53, 0x0335689, 0x149eb66, 0x02328cc, 0x08f0bb8, + 0x1fb444c, 0x0ce2dcd, 0x0c66959, 0x086f65a, 0x0b8a01a, 0x17ecaf6, + 0x10bdac5, 0x0f7f216, 0x1fe0b28, 0x1945f04, 0x00aca5f, 0x162aa76, + 0x1791541, 0x04ed83b, 0x1513ac5, 0x047183b, 0x0dfd32c, 0x10f2f99, + 0x16d9acc, 0x1694657, 0x10364cc, 0x0b2c902, 0x1a409fd, 0x114b942, + 0x04f31ab, 0x0c447a1, 0x173c2a5, 0x07e04bb, 0x1ab144a, 0x185aa4c, + 0x1c31fe6, 0x0b5be5d, 0x04ca296, 0x1359592, 0x00e6331 }, + { 0x0360ac2, 0x097d6f8, 0x016ad73, 0x1c50bcc, 0x06b660d, 0x0dcd8a4, + 0x13c4389, 0x0a9058d, 0x1aa9ac5, 0x0afd1c6, 0x101c3a7, 0x0370a4d, + 0x0d3dfcf, 0x1fe6629, 0x1e6a5ac, 0x18fea06, 0x0290bfc, 0x0f1b2ce, + 0x074f9a8, 0x147b6ad, 0x02d55b1, 0x1acdbda, 0x0d054a2, 0x045400d, + 0x1efa49c, 0x1db49a6, 0x026d338, 0x01e7003, 0x0baf329, 0x1e0259d, + 0x18ac1ce, 0x1ff0713, 0x1a5a222, 0x0d1ad93, 0x1547fe9, 0x0416f53, + 0x08e1a7c, 0x1cf6779, 0x1c16924, 0x14430e4, 0x088839d }, + { 0x01ce29a, 0x1361838, 0x15415ad, 0x0cb1303, 0x1acaf12, 0x0fcf909, + 0x1f03041, 0x027a9b5, 0x0373e3d, 0x172b8f3, 0x1b8f2bf, 0x190df45, + 0x1ae7269, 0x0e901c2, 0x132992b, 0x1d359eb, 0x1573000, 0x190bf93, + 0x19c9cfb, 0x09b68e1, 0x0776c93, 0x1b9aadb, 0x10a53d3, 0x180a300, + 0x036b96f, 0x0858fd5, 0x0ec1486, 0x1f1163b, 0x0aef528, 0x0dc874f, + 0x040d5e4, 0x1b6d037, 0x17fb2eb, 0x0e1b4f9, 0x1475105, 0x1273a14, + 0x1d2e21c, 0x0ce6538, 0x0309bf1, 0x1fd43ea, 0x064128c }, + { 0x0f5b0b5, 0x13c5174, 0x0167c0d, 0x19a681e, 0x1c7e249, 0x053e762, + 0x011064f, 0x1308288, 0x0bc83af, 0x1ae51a3, 0x02eec01, 0x0067f55, + 0x17f39f0, 0x19c1187, 0x063c3b7, 0x1e68a7a, 0x00cd448, 0x0bc6ff8, + 0x146a91d, 0x045181a, 0x08d1849, 0x0418649, 0x175389c, 0x0259fa7, + 0x1a6868f, 0x1036335, 0x0e22ce8, 0x122093b, 0x0dae010, 0x082c80b, + 0x1f76197, 0x1c4a7c6, 0x199e905, 0x0c38da2, 0x0309f3a, 0x1c6459e, + 0x174a132, 0x07aa6d0, 0x12f6805, 0x0137b57, 0x093634a }, + { 0x1a2e304, 0x13593d4, 0x04918a0, 0x0d83498, 0x057e186, 0x1c0b886, + 0x0e0c888, 0x1fd2275, 0x1a9847c, 0x14db5c2, 0x1d1bf5f, 0x19e256b, + 0x0d29655, 0x001c733, 0x0555cae, 0x0bd56e5, 0x0016fa9, 0x0f265d3, + 0x077b6a0, 0x0220e37, 0x161ebbc, 0x0d1f8e7, 0x05fc002, 0x07c19f7, + 0x0777b37, 0x11da9b9, 0x1344e75, 0x005f213, 0x07d78e3, 0x196d27c, + 0x18c7b59, 0x168090e, 0x02077a3, 0x011591b, 0x0cb6773, 0x0f88118, + 0x06deeee, 0x062df91, 0x0d5f92d, 0x0cf780c, 0x0266cb4 }, + { 0x16363e8, 0x120aa5a, 0x136dbea, 0x1078354, 0x0b4fd07, 0x0f32cba, + 0x03778ae, 0x108286b, 0x0fa004b, 0x19a571f, 0x0446996, 0x05d9e33, + 0x18cf44b, 0x129b5fb, 0x12aa0ce, 0x1b92aab, 0x0b98870, 0x0b0370f, + 0x07cd447, 0x0650fa1, 0x1364e3c, 0x15ceae7, 0x1a2cbd3, 0x157193c, + 0x0e89263, 0x108e0aa, 0x1b0daad, 0x0a91051, 0x17d1201, 0x1fe5d0d, + 0x15c24ca, 0x0a62b71, 0x0e7b5bc, 0x19d60bf, 0x0347dd1, 0x06f05fa, + 0x1c8f2af, 0x1814d41, 0x13b86f2, 0x036a48a, 0x04b1d5a }, + { 0x1d52c0c, 0x128ba31, 0x06744bf, 0x1c31181, 0x1735525, 0x071cab1, + 0x0558cd8, 0x086b8c4, 0x0acfa5a, 0x059f8e5, 0x1a041e2, 0x1414f2f, + 0x0a90123, 0x18af040, 0x0c7dad6, 0x1b5b574, 0x012fca3, 0x06bef2f, + 0x17d4472, 0x0e6c361, 0x1d4e328, 0x0a32bab, 0x1f32003, 0x00fd922, + 0x10f3d52, 0x0718840, 0x04c3ba8, 0x1a9cade, 0x05a2ec0, 0x17099f5, + 0x142efdf, 0x17cd577, 0x1c07762, 0x1fb0cb7, 0x1738482, 0x159063f, + 0x1622d42, 0x1a1cfd5, 0x12c9f81, 0x07ea11c, 0x08186b9 }, + { 0x1312867, 0x0e8aa04, 0x16d3186, 0x0b7f5ef, 0x1e042c0, 0x0faeed3, + 0x059a07d, 0x105839e, 0x1a4fc3d, 0x055282b, 0x02e3f94, 0x1acb9cd, + 0x04ed30e, 0x1f5a6b2, 0x0c0702e, 0x0092fd9, 0x044831c, 0x03daee2, + 0x0df66c7, 0x1cd4013, 0x1c91351, 0x1ceca3b, 0x12ee18e, 0x1a82214, + 0x0589105, 0x1bd55d3, 0x110d602, 0x0010d9e, 0x1e357e3, 0x003b485, + 0x13ac4e7, 0x04f6a42, 0x0bfff1a, 0x1d5ab89, 0x1b5c8b0, 0x14f39f8, + 0x134a9bf, 0x01ef2bf, 0x0aca91d, 0x12f93dc, 0x00bf97e }, + { 0x1a19e96, 0x027646e, 0x1a2e5bb, 0x14d860d, 0x14ce18e, 0x1b48c52, + 0x184ad97, 0x132fd06, 0x10d9a0d, 0x1637b45, 0x1730246, 0x0f48c5f, + 0x1398a69, 0x0ade1f0, 0x13897c6, 0x12e60cb, 0x0dab393, 0x10c4b76, + 0x0bc4a01, 0x10341e6, 0x07df9eb, 0x170e96e, 0x14f5d05, 0x08e6b33, + 0x07976ad, 0x01cf116, 0x0a7d7bd, 0x1bc6f53, 0x09d94e3, 0x0055cf3, + 0x121adeb, 0x0153a17, 0x0bfa9e0, 0x1789073, 0x1c3559d, 0x1eaed50, + 0x1eaac23, 0x0c8dda7, 0x0aaecef, 0x0587c81, 0x08fe548 }, + { 0x09a4d1e, 0x133e167, 0x00e216b, 0x069e3a4, 0x0c3eb80, 0x0830c92, + 0x03ce897, 0x038b8d9, 0x1308fb4, 0x01ef056, 0x10a53a0, 0x0b79ce3, + 0x1a9961f, 0x1817586, 0x1881e37, 0x1d16db8, 0x115b64a, 0x1e43f7a, + 0x02d3463, 0x0f3e3ca, 0x1f43696, 0x10a90cc, 0x1170026, 0x0c814bf, + 0x084be0f, 0x0b353ea, 0x048f6ad, 0x1923176, 0x075d2c4, 0x08a6321, + 0x15a99f0, 0x195a5bd, 0x1a913b9, 0x1ae46ca, 0x062dad2, 0x0c313da, + 0x142d3bf, 0x15b1035, 0x0f0fd2b, 0x0d37791, 0x03928c6 }, + { 0x0cb4b64, 0x1f5256d, 0x0687792, 0x09e4c2f, 0x03f62a4, 0x0889520, + 0x12539ea, 0x03de755, 0x1d36f33, 0x02247de, 0x0e17124, 0x057880f, + 0x1b42604, 0x1090dbb, 0x1629658, 0x1d308b5, 0x04f67ce, 0x098b3a5, + 0x18ecbc3, 0x1d177c9, 0x10eb7fa, 0x0ed3e49, 0x1a077db, 0x0b3a1a8, + 0x0fa98c2, 0x0fed6f7, 0x1afa870, 0x1629b3c, 0x1405d11, 0x0e4590e, + 0x150eeab, 0x0e7124e, 0x01dff93, 0x0e6f278, 0x0cfbc1c, 0x130386b, + 0x1150d0d, 0x026970c, 0x0d3d85c, 0x11e6aa2, 0x06ccc88 }, + { 0x0d7504c, 0x1b7873d, 0x1777e34, 0x1fef2b3, 0x1ca3265, 0x0f33d55, + 0x07b7bfb, 0x05e1b9a, 0x0baebf3, 0x13b7a67, 0x1b73f04, 0x0dcc029, + 0x176825a, 0x0cd6c75, 0x0306a0a, 0x19c3c17, 0x0a909b8, 0x1189012, + 0x12f4d46, 0x1fb3173, 0x08becb8, 0x1c7d58f, 0x092104d, 0x0e7959f, + 0x10f5d39, 0x12a0bf6, 0x1096754, 0x02fc290, 0x191393a, 0x1c21ba5, + 0x1a54f56, 0x0359479, 0x1792b21, 0x07c0ac7, 0x0443230, 0x1a06bfe, + 0x0d4ed7b, 0x1d31abd, 0x0bbe5ab, 0x10164df, 0x02f1519 }, + { 0x1d2d439, 0x118ed14, 0x0554321, 0x0578073, 0x121fbbc, 0x02dbad8, + 0x05e49b0, 0x1d87cb5, 0x0b6ce47, 0x0b67a60, 0x031961b, 0x0ecf3b1, + 0x17baaa1, 0x199aad0, 0x076e79f, 0x0b50a06, 0x1d80aef, 0x1c1c0f1, + 0x168c6f7, 0x1b65202, 0x1d7dc71, 0x1a4a4c7, 0x18e3dad, 0x17dddec, + 0x1f3f913, 0x1d9a276, 0x07d2ad9, 0x0c2e64e, 0x02df11e, 0x16387e9, + 0x048e880, 0x040b89d, 0x1be0389, 0x1cc907b, 0x0216a3a, 0x1438432, + 0x1eb54aa, 0x002e745, 0x03595b2, 0x16e158b, 0x0354b05 }, + { 0x09170e9, 0x0f11b3d, 0x0335c5c, 0x1a995aa, 0x01eec42, 0x0ee67d8, + 0x0093cf3, 0x035ff7d, 0x1a66cae, 0x19f4671, 0x11f4069, 0x14ff2cb, + 0x1eb7138, 0x0e1ecb8, 0x01638fd, 0x14e5600, 0x0c32ff0, 0x1a92c8d, + 0x0ef39db, 0x1f6b797, 0x1a18a32, 0x1c54fc0, 0x1cc906a, 0x14d0c61, + 0x13332ec, 0x09df98e, 0x11120bc, 0x08f5f3f, 0x081be28, 0x110bd23, + 0x1e5865b, 0x1cabdf9, 0x138f932, 0x06382cc, 0x12e1c2b, 0x047cfb5, + 0x0f09fac, 0x0df449e, 0x08e8750, 0x1895c6a, 0x048dc55 }, + { 0x1092193, 0x11c1352, 0x1c32398, 0x04d1312, 0x046ec36, 0x04f5a0f, + 0x15abc97, 0x08a5e26, 0x083c7d2, 0x0bc0320, 0x0038e10, 0x1ecf2fa, + 0x1c982de, 0x12890a8, 0x0badb9e, 0x110d270, 0x0778af5, 0x10aa708, + 0x09473c0, 0x00e0eb1, 0x1c58187, 0x1bb8989, 0x137aea7, 0x02ab209, + 0x1b973ba, 0x19d2eb3, 0x0c7435e, 0x0a393e9, 0x0af2cd8, 0x0eb8c5c, + 0x18867ca, 0x130d71a, 0x194ccff, 0x1ce19e5, 0x092ee4e, 0x110e4bc, + 0x06e38c6, 0x0e7262b, 0x1008501, 0x1ba16db, 0x05f6a8e }, + { 0x19a8690, 0x02652c7, 0x101e0dc, 0x0c5eed4, 0x1f36976, 0x1008141, + 0x0b631a4, 0x19ff782, 0x0bce3a4, 0x06ac78b, 0x0ac9b53, 0x0c94095, + 0x0878046, 0x07522bd, 0x173eee9, 0x12f2800, 0x1b3b8a5, 0x0a9bca8, + 0x1f87dce, 0x0573c89, 0x17974ca, 0x06ef992, 0x1910a2b, 0x14487b7, + 0x1a3420e, 0x00f3246, 0x0fd0f38, 0x19ccac5, 0x1db490c, 0x0210f93, + 0x1c2103c, 0x117f6f9, 0x16ccb70, 0x1cbe98a, 0x00356a1, 0x1736669, + 0x1eb814b, 0x09703d4, 0x01eb0b8, 0x0e594ff, 0x01ca650 }, + { 0x19d25a0, 0x190e795, 0x1b6feec, 0x14814e8, 0x06affdc, 0x11b45ab, + 0x14c3967, 0x11f8382, 0x07d8006, 0x1768f52, 0x1f75a15, 0x11fcac8, + 0x089b74d, 0x04dbc6d, 0x05ad41e, 0x067223b, 0x0438bbe, 0x19cdba9, + 0x1616317, 0x1a887c1, 0x0a34ef8, 0x04cb235, 0x1374b6d, 0x0cea878, + 0x13bd1e6, 0x0c2bfd6, 0x01a2602, 0x01ae218, 0x1acabad, 0x1f9924f, + 0x04a7deb, 0x029f343, 0x15dec1c, 0x183d082, 0x0e647ec, 0x09594cc, + 0x15ffff6, 0x027ec89, 0x0f3bab1, 0x16d975a, 0x0462caf }, + { 0x03237dd, 0x05323ef, 0x1010598, 0x190570e, 0x15f735c, 0x1d2afc4, + 0x07d6777, 0x095ef0f, 0x0726b91, 0x0f7821f, 0x0f8a605, 0x127a392, + 0x1118753, 0x1778c19, 0x08af9d1, 0x1425743, 0x1fc25a9, 0x1a73f46, + 0x070e45f, 0x1f92fb5, 0x1e41dfe, 0x0185175, 0x0f21d74, 0x065a399, + 0x1d235a7, 0x16987ba, 0x1b66ea9, 0x0dfdcff, 0x1485760, 0x07d5b2f, + 0x102a9e1, 0x0a27f07, 0x1155e22, 0x1ce8991, 0x1c60fa3, 0x1ba5f6e, + 0x1546eaf, 0x148a81d, 0x0d820a8, 0x118d9b2, 0x01293c9 }, + { 0x1d53b77, 0x00928a4, 0x0b1dc9e, 0x1b2dd5f, 0x06ab403, 0x1b5b88d, + 0x11f6d28, 0x1836faf, 0x087e771, 0x11c6384, 0x0dd48a0, 0x157e676, + 0x0d495f6, 0x0643a98, 0x0c0a272, 0x0223561, 0x186e77b, 0x16541e5, + 0x06f4627, 0x181f714, 0x17c7be1, 0x1d8d74e, 0x1633ecb, 0x08187d0, + 0x023c549, 0x083e82e, 0x05d2b64, 0x0dcf3c8, 0x0e71421, 0x1f82832, + 0x13e8291, 0x1fbfac2, 0x0929cd4, 0x14c45e3, 0x0130e51, 0x03db64b, + 0x046f8fb, 0x125af9f, 0x052e9cf, 0x142d1d5, 0x053b79a }, + { 0x0bbb6a1, 0x1d7e722, 0x1ca085b, 0x00cf042, 0x13a5bba, 0x0ec9cd6, + 0x12cc2a7, 0x1fdde3c, 0x1f19efa, 0x117579e, 0x1b00500, 0x179cf69, + 0x18fed5a, 0x0896339, 0x05a3b99, 0x11344c9, 0x06929fe, 0x09188cc, + 0x1ce5f01, 0x073b1a8, 0x16c40d5, 0x0a11a2c, 0x19002f1, 0x08cc23a, + 0x07f5853, 0x107dc94, 0x0f27576, 0x0813320, 0x1af2a80, 0x04cbe41, + 0x18797bd, 0x06502a3, 0x09dc01b, 0x0088264, 0x12a5610, 0x1a2a1f6, + 0x13872c9, 0x137beaf, 0x1a0cd02, 0x1a2ad85, 0x08290d6 }, + { 0x0546946, 0x11be36c, 0x1febe11, 0x12d3d8a, 0x1a134a3, 0x04803f6, + 0x166935e, 0x013a846, 0x00dc7b8, 0x012abff, 0x1e12a6d, 0x0a5a5ac, + 0x1fe62ae, 0x05e56da, 0x1c53298, 0x1f94b44, 0x1e633aa, 0x0e61046, + 0x1659e04, 0x01dab9d, 0x1660238, 0x14ed990, 0x1b9ad57, 0x0ea46b4, + 0x0d02ca6, 0x0708df5, 0x06ccfe8, 0x0398ddf, 0x0a2a085, 0x1f13783, + 0x13ff488, 0x1d88f67, 0x0f332e1, 0x14c2700, 0x05ee82a, 0x088b3e5, + 0x0e952e1, 0x10ecb4f, 0x0aec1be, 0x156609f, 0x0506ef1 }, + { 0x1bff163, 0x075939a, 0x061046d, 0x1fd53f5, 0x1130b96, 0x1593e73, + 0x1acfe77, 0x1aacd59, 0x19dd1c3, 0x16d78d2, 0x01d6aa8, 0x14fd4e6, + 0x18f5090, 0x11838da, 0x09abce7, 0x15b386d, 0x13ddf73, 0x15146b1, + 0x1722685, 0x0a99597, 0x1c3cdd3, 0x11ea6e5, 0x17fa8d0, 0x13b25a3, + 0x074d237, 0x1b2b776, 0x1e3bb59, 0x02948ad, 0x0feb1fe, 0x1ba1fd4, + 0x11feaf9, 0x1731f97, 0x004ccf8, 0x138370a, 0x1effdc6, 0x10d99a5, + 0x0d85c67, 0x179feda, 0x00d136a, 0x17e2a40, 0x0415b7d }, + { 0x18377a7, 0x082c33e, 0x09ca5c0, 0x1197006, 0x068a3d6, 0x1d26190, + 0x14a27c0, 0x121facf, 0x193c8f2, 0x1e384ae, 0x168ae12, 0x0279d3c, + 0x1b712fa, 0x07f5cf9, 0x1ab1b18, 0x0a985f8, 0x0d96e0e, 0x0866d1b, + 0x18c8280, 0x132ea30, 0x0f11454, 0x08cbf80, 0x1e4c632, 0x126ca11, + 0x04c3fe6, 0x05500ee, 0x0617c1a, 0x0d345df, 0x15511c7, 0x0778515, + 0x014d48b, 0x168245c, 0x06965ed, 0x0ea1f80, 0x0bf305d, 0x13f9c1f, + 0x0c831d5, 0x0ee4def, 0x01e7549, 0x1e35eb1, 0x01ec314 }, + { 0x08310c2, 0x1ff7796, 0x1dd0198, 0x148afc7, 0x0a7e14d, 0x1a3443d, + 0x043f394, 0x18a7256, 0x1637ec2, 0x0f251c7, 0x0be37f3, 0x06416a8, + 0x1150773, 0x1bef0b8, 0x04c0be7, 0x1378c68, 0x063ae4b, 0x180c58e, + 0x14be79b, 0x0388ddb, 0x0fa0f00, 0x0b93766, 0x14eec2a, 0x08dc18f, + 0x1b99d77, 0x1765498, 0x1fd61d6, 0x01916de, 0x139c82e, 0x18be4b4, + 0x192eccb, 0x07bcb4c, 0x05135d2, 0x1fd35bb, 0x12d14aa, 0x1ce326d, + 0x0dc105d, 0x0e60479, 0x15e22b5, 0x024fffe, 0x017e91d }, + { 0x1e051ca, 0x16769db, 0x1b52fa4, 0x1a338ee, 0x0644d4f, 0x033c25e, + 0x12d4802, 0x0639156, 0x1ce9d6b, 0x1533113, 0x07a71cf, 0x1347a51, + 0x0e39524, 0x08950cf, 0x1427997, 0x0b5d8a8, 0x0928c36, 0x153dea3, + 0x1e58f83, 0x132fc8e, 0x132d354, 0x0bdaccb, 0x035d965, 0x1a9476c, + 0x04aeb91, 0x1144cac, 0x1077acf, 0x1cca7d4, 0x0571df6, 0x0c76ab9, + 0x1e729f2, 0x16315c3, 0x101a38f, 0x1dcbf79, 0x1f098fd, 0x0a2c53e, + 0x0fc4a0d, 0x1211415, 0x030077c, 0x0967bba, 0x0118f3b }, + { 0x0d4762b, 0x050543d, 0x05d5d28, 0x1518b1a, 0x1aef84d, 0x1bb6c30, + 0x1258133, 0x1162dfe, 0x07e60d9, 0x05f43c3, 0x1076eb0, 0x1ff67d9, + 0x1a83637, 0x0eeb0a3, 0x1129825, 0x08dcb84, 0x0345b08, 0x0d1f0bc, + 0x1de9301, 0x1d6d0dc, 0x0695735, 0x07efbac, 0x16f062d, 0x1bfca5e, + 0x18d0b1b, 0x1d08ab0, 0x1401c56, 0x0f1d981, 0x1d617f8, 0x1e8d616, + 0x04076f6, 0x0436c2e, 0x1d2b631, 0x0c9e110, 0x09e513d, 0x08459d1, + 0x04f1702, 0x0da9b52, 0x19c9cee, 0x0f91a07, 0x001d0a6 }, + { 0x046533c, 0x1211b0f, 0x0ab9ee5, 0x01f7118, 0x0947799, 0x16250c7, + 0x1745a90, 0x08a0336, 0x1d83c7a, 0x09af40e, 0x198f8dc, 0x17ba996, + 0x0374a69, 0x13b606b, 0x19fb36f, 0x11b4cf6, 0x12111e6, 0x101eaa2, + 0x0ba1942, 0x199d6ba, 0x1b37596, 0x1e95781, 0x1355cb7, 0x17ab2a5, + 0x04ba1fa, 0x0b4a91b, 0x1ad3b61, 0x1e8fa8a, 0x10d5d47, 0x1ab964a, + 0x0116b62, 0x090dc5f, 0x0dd2dfa, 0x1d82265, 0x0d0f15a, 0x0dbaa4f, + 0x197c08e, 0x16dd124, 0x0c83f26, 0x00cfb4c, 0x01b625b }, + { 0x1d8446d, 0x1d53da7, 0x0fad137, 0x035edfd, 0x001b2f0, 0x041c5ae, + 0x10e23fa, 0x1177e88, 0x1bba975, 0x19e21a7, 0x15af27c, 0x19750e2, + 0x0b2b971, 0x0fa484c, 0x0917970, 0x18bbad6, 0x1342b41, 0x1c3ee5a, + 0x13614b5, 0x1f018c6, 0x1a34db1, 0x0c1219e, 0x1b5b8c9, 0x0fbe184, + 0x020653f, 0x1b2fb34, 0x10d832c, 0x0994acf, 0x06656ac, 0x15614c1, + 0x1a0c87e, 0x17e0d2e, 0x1f5ca6f, 0x1b31c89, 0x04869c1, 0x1c2a72f, + 0x0400736, 0x18a1944, 0x05236f7, 0x12c33f9, 0x0333eca }, + { 0x0775d81, 0x1bca456, 0x0f288cc, 0x1fa83b7, 0x18c2518, 0x1e74a41, + 0x1e93ef3, 0x1cec478, 0x054703f, 0x169b11b, 0x0ced6ea, 0x074827f, + 0x102b3a1, 0x1fae00f, 0x0cd5969, 0x12cc2bb, 0x0dc5235, 0x0eb9204, + 0x1585ba4, 0x0ff1ca3, 0x19995a1, 0x15e592d, 0x04305bb, 0x126e87d, + 0x08cf133, 0x053f9af, 0x0b952d9, 0x10fb4e9, 0x0d449d9, 0x191532e, + 0x17555ec, 0x06fcf62, 0x05082a5, 0x089a7bb, 0x1d0bcb3, 0x0c9a4b8, + 0x0ccf074, 0x0ece03a, 0x144d6ba, 0x0210e51, 0x072fc21 }, + { 0x16004c8, 0x15901fc, 0x17fea41, 0x1e8b00a, 0x183f95c, 0x19ac84e, + 0x1619d57, 0x1ddaefa, 0x1e550c8, 0x14f537d, 0x0182052, 0x1952ab4, + 0x0291c8c, 0x1e74103, 0x07fb9e2, 0x1f0bc94, 0x0069a3d, 0x175cd6f, + 0x14f7999, 0x1b9e18f, 0x0d51fbb, 0x0dae99b, 0x08a28e4, 0x05ff878, + 0x18d285c, 0x12dbb07, 0x0cbdec5, 0x1dc91bc, 0x1770401, 0x1ec22b0, + 0x0800e00, 0x13bdff3, 0x173f648, 0x11ad272, 0x0e3a85f, 0x0dc344e, + 0x0840a6c, 0x0778be4, 0x164b48e, 0x1f1623d, 0x0480946 }, + { 0x171f119, 0x1a3d47e, 0x1a56131, 0x1ca7d66, 0x19e65c5, 0x0c2c3d0, + 0x19e198a, 0x1e81c5e, 0x1ab18d6, 0x052444c, 0x02e3012, 0x00498c6, + 0x12a1a99, 0x16557c4, 0x05d4258, 0x1ac4909, 0x0bae20f, 0x064434d, + 0x10adf75, 0x05609ad, 0x17d03b7, 0x1b04c97, 0x189dd7a, 0x00dcd09, + 0x1c06e7d, 0x0038044, 0x0792ef4, 0x167686c, 0x0846e4c, 0x1335a5d, + 0x07a86b9, 0x08c8c9b, 0x01c2eb2, 0x029cfe0, 0x0f9b07e, 0x0ff0de5, + 0x0f68afc, 0x1474576, 0x1a4085b, 0x1fb8e70, 0x08dab61 }, + { 0x14d1d45, 0x0e481ea, 0x0e890a9, 0x1dfe9f3, 0x0cd4297, 0x0a3c5a5, + 0x0d480d3, 0x0345b11, 0x108c462, 0x0d95d15, 0x195008d, 0x1376690, + 0x06d3d23, 0x088f997, 0x19dabb6, 0x1fb843b, 0x1cf3f06, 0x143bfc5, + 0x1b14540, 0x0e29833, 0x100d802, 0x15d2c83, 0x0841113, 0x1b992af, + 0x0229f31, 0x1f6c34a, 0x0ee05a7, 0x1d9cef5, 0x0f080e5, 0x050a965, + 0x1c556fa, 0x197af9d, 0x0b21b14, 0x0bf709f, 0x0b459ee, 0x193bdef, + 0x118f690, 0x1e543c8, 0x0a79f80, 0x05bf336, 0x06f77e6 }, + { 0x00bbf59, 0x0def6f2, 0x0b5a89c, 0x06c8035, 0x177ba45, 0x0a0e688, + 0x180d5cd, 0x05e2eab, 0x04b71b0, 0x032da33, 0x0cd67cd, 0x0227502, + 0x0722eb7, 0x179c756, 0x04aa3f5, 0x1e76b2f, 0x12fff3b, 0x188d500, + 0x0170fef, 0x15f57ff, 0x0c4299a, 0x1783606, 0x047828b, 0x076f675, + 0x15d5777, 0x00518a6, 0x1b59a61, 0x1cbc5ce, 0x1a8be6a, 0x1039972, + 0x002184d, 0x1839eab, 0x06d7578, 0x1688177, 0x003da2f, 0x164689c, + 0x0184f0e, 0x0ebc434, 0x13e01e6, 0x12387a5, 0x063819c }, + { 0x084b073, 0x1c970bc, 0x1fab294, 0x19d624c, 0x1ec3a1f, 0x181c53c, + 0x1d7c241, 0x0e07a0f, 0x0e4c47b, 0x195603e, 0x05ae472, 0x09dc37f, + 0x1ff9666, 0x157527d, 0x1d5d624, 0x0ca01d7, 0x191fade, 0x02d55f9, + 0x1c74481, 0x066ede2, 0x181ac5b, 0x08d069e, 0x07fd831, 0x0d50896, + 0x0cfe797, 0x12d0859, 0x0af6984, 0x0263993, 0x1d453ee, 0x0b69a75, + 0x10783f0, 0x0a096d7, 0x0d0319a, 0x1c655e0, 0x0f9c28b, 0x0fc8741, + 0x15e49b4, 0x057f762, 0x15fbb20, 0x02504cb, 0x067d48d }, + { 0x02d56d6, 0x0acd3f5, 0x098c1a3, 0x1c4e901, 0x171abd0, 0x19b366e, + 0x076c2b9, 0x178d7a2, 0x007204e, 0x1db1ce5, 0x198a4fe, 0x05cfeef, + 0x1d89a24, 0x1add461, 0x19f28ad, 0x1f351bd, 0x03d64a2, 0x02396ee, + 0x1586804, 0x053be8e, 0x09d4842, 0x02e2db2, 0x057d8b2, 0x1924f9b, + 0x16b1b4d, 0x0cb7eea, 0x017b981, 0x1d17624, 0x129401f, 0x152855f, + 0x010fbf2, 0x021a383, 0x0900d0f, 0x00efaea, 0x0ea4a2c, 0x0a59e22, + 0x1f0e43f, 0x0bf5e18, 0x1371e8f, 0x071d070, 0x027950e }, + { 0x1d0fa79, 0x10ff870, 0x17a7aac, 0x060916b, 0x0b9fd03, 0x11ba65a, + 0x11a24bf, 0x0d69926, 0x04eb21f, 0x1a413fd, 0x179f9ee, 0x1ef3524, + 0x1146716, 0x1eea629, 0x10afcd9, 0x0dbbe28, 0x14cd2e9, 0x09039ca, + 0x140aaa2, 0x02835d0, 0x0cc94e0, 0x0d4777b, 0x03b8038, 0x1019b5f, + 0x0849158, 0x0232ae7, 0x11a58a0, 0x1e7574b, 0x15dfbff, 0x027c2e8, + 0x094cd73, 0x13ed09e, 0x1f0440c, 0x12dec53, 0x14feec7, 0x175d008, + 0x1f2225a, 0x04cc09f, 0x175c687, 0x108f364, 0x054ff78 }, + { 0x040b068, 0x177186f, 0x14789f1, 0x17cde74, 0x1226465, 0x1d90fb4, + 0x11813e8, 0x02bc494, 0x1c04181, 0x052d2d6, 0x0434ad4, 0x08831bf, + 0x0fe3285, 0x0e58600, 0x1d3963f, 0x011c776, 0x13b4a2c, 0x0e3478d, + 0x13367b2, 0x1be1021, 0x0a9f339, 0x0e5bc37, 0x0454d8b, 0x0ab5d5b, + 0x05e31c9, 0x035944a, 0x162da9b, 0x0d45803, 0x18a427d, 0x016e1b3, + 0x0b01a7a, 0x0519260, 0x1875500, 0x080f30b, 0x05967e8, 0x0d159b5, + 0x0e30b28, 0x0722b9f, 0x0c3f939, 0x10a7e30, 0x08adbad }, + { 0x169d524, 0x1708f84, 0x11e4182, 0x0fe7379, 0x142fdaf, 0x00fe617, + 0x19d99f3, 0x09e79d8, 0x0e2336d, 0x0b5ce79, 0x103dfd1, 0x0bbd1c3, + 0x0e6aa1f, 0x04c27d8, 0x0f0ab48, 0x096519b, 0x1a61b46, 0x1a04867, + 0x090fcfb, 0x10de602, 0x07e740d, 0x0666af4, 0x056c5b3, 0x04d9a83, + 0x1168c30, 0x198201f, 0x0e05b01, 0x17c70d9, 0x007a1dd, 0x0379ac2, + 0x0bc53ae, 0x02e2fc3, 0x188b4f8, 0x1e4b67a, 0x06999b2, 0x036eb88, + 0x027e71c, 0x0160d50, 0x1797fcd, 0x06d8128, 0x0739300 }, + { 0x0cdaf42, 0x1babe91, 0x0aae553, 0x1be8303, 0x188b591, 0x08a792b, + 0x1a067d5, 0x1791730, 0x0f18fd5, 0x0b21704, 0x13ae45a, 0x0ba2045, + 0x0592b30, 0x1527b4c, 0x05640f9, 0x1395c2e, 0x09d6117, 0x125ebeb, + 0x0a7006a, 0x1bfabba, 0x08ccdac, 0x0d6c888, 0x1c17775, 0x1591e2a, + 0x0c7b164, 0x197a1a5, 0x06d4918, 0x034a29c, 0x1fc4476, 0x130db98, + 0x0c516e7, 0x1c12c36, 0x1561348, 0x17911e7, 0x059dcfa, 0x0738515, + 0x0a7c99d, 0x0880c15, 0x197896f, 0x095c852, 0x08bc6ec }, + { 0x1f2a32b, 0x172e073, 0x08c3425, 0x1812711, 0x1f54800, 0x0f1b067, + 0x10df100, 0x14c0dfc, 0x0bb6054, 0x12afe4e, 0x1ea9b99, 0x10c108a, + 0x17510e1, 0x1594d95, 0x0b3f288, 0x1b4c341, 0x1e351b7, 0x1399241, + 0x0f9b232, 0x08e3dcd, 0x09a1e31, 0x0e45b2e, 0x195950c, 0x1acb977, + 0x0c3b948, 0x1547e4d, 0x06ba6ca, 0x0611f84, 0x00aa6ad, 0x0f86d53, + 0x1535a9f, 0x1305f81, 0x044d96a, 0x1d26b94, 0x10b1611, 0x0b56025, + 0x1ceb895, 0x1e47b8e, 0x1f854ac, 0x0fb7d38, 0x08e8543 }, +}; + +/* Perform the modular exponentiation in Fp* for SAKKE. + * + * Base is fixed to be the g parameter - a precomputed table is used. + * + * Striping: 128 points at a distance of 8 combined. + * Total of 256 points in table. + * Square and multiply performed in Fp*. + * + * base [in] Base. MP integer. + * exp [in] Exponent. MP integer. + * res [out] Result. MP integer. + * returns 0 on success, MP_READ_E if there are too many bytes in an array + * and MEMORY_E if memory allocation fails. + */ +int sp_ModExp_Fp_star_1024(const mp_int* base, mp_int* exp, mp_int* res) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td; + sp_digit* t; + sp_digit* tx; + sp_digit* ty; +#else + sp_digit t[4 * 2 * 42]; + sp_digit tx[2 * 42]; + sp_digit ty[2 * 42]; +#endif + sp_digit* r = NULL; + unsigned char e[128]; + int err = MP_OKAY; + int i; + int y; + + (void)base; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6 * 42 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + tx = td + 4 * 42 * 2; + ty = td + 5 * 42 * 2; +#endif + r = ty; + + (void)mp_to_unsigned_bin_len(exp, e, 128); + + XMEMCPY(tx, p1024_norm_mod, sizeof(sp_digit) * 42); + y = e[112] >> 7; + y |= (e[96] >> 7) << 1; + y |= (e[80] >> 7) << 2; + y |= (e[64] >> 7) << 3; + y |= (e[48] >> 7) << 4; + y |= (e[32] >> 7) << 5; + y |= (e[16] >> 7) << 6; + y |= (e[0] >> 7) << 7; + XMEMCPY(ty, sp_1024_g_table[y], sizeof(sp_digit) * 42); + for (i = 126; i >= 0; i--) { + y = (e[127 - (i / 8)] >> (i & 0x7)) & 1; + y |= ((e[111 - (i / 8)] >> (i & 0x7)) & 1) << 1; + y |= ((e[95 - (i / 8)] >> (i & 0x7)) & 1) << 2; + y |= ((e[79 - (i / 8)] >> (i & 0x7)) & 1) << 3; + y |= ((e[63 - (i / 8)] >> (i & 0x7)) & 1) << 4; + y |= ((e[47 - (i / 8)] >> (i & 0x7)) & 1) << 5; + y |= ((e[31 - (i / 8)] >> (i & 0x7)) & 1) << 6; + y |= ((e[15 - (i / 8)] >> (i & 0x7)) & 1) << 7; + + sp_1024_proj_sqr_42(tx, ty, t); + sp_1024_proj_mul_qx1_42(tx, ty, sp_1024_g_table[y], t); + } + } + + if (err == MP_OKAY) { + sp_1024_mont_inv_42(tx, tx, t); + sp_1024_mont_mul_42(r, tx, ty, p1024_mod, p1024_mp_mod); + XMEMSET(r + 42, 0, sizeof(sp_digit) * 42); + sp_1024_mont_reduce_42(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Multiply p* by q* in projective co-ordinates. + * + * p.x' = (p.x * q.x) - (p.y * q.y) + * p.y' = (p.x * q.y) + (p.y * q.x) + * But applying Karatsuba: + * v0 = p.x * q.x + * v1 = p.y * q.y + * p.x' = v0 - v1 + * p.y' = (px + py) * (qx + qy) - v0 - v1 + * + * px [in,out] A single precision integer - X ordinate of number to multiply. + * py [in,out] A single precision integer - Y ordinate of number to multiply. + * qx [in] A single precision integer - X ordinate of number of + * multiplier. + * qy [in] A single precision integer - Y ordinate of number of + * multiplier. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_mul_42(sp_digit* px, sp_digit* py, + const sp_digit* qx, const sp_digit* qy, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 42; + + /* t1 = px + py */ + sp_1024_mont_add_42(t1, px, py, p1024_mod); + /* t2 = qx + qy */ + sp_1024_mont_add_42(t2, qx, qy, p1024_mod); + /* t2 = (px + py) * (qx + qy) */ + sp_1024_mont_mul_42(t2, t1, t2, p1024_mod, p1024_mp_mod); + /* t1 = py * qy */ + sp_1024_mont_mul_42(t1, py, qy, p1024_mod, p1024_mp_mod); + /* t2 = (px + py) * (qx + qy) - (py * qy) */ + sp_1024_mont_sub_42(t2, t2, t1, p1024_mod); + /* px = px * qx */ + sp_1024_mont_mul_42(px, px, qx, p1024_mod, p1024_mp_mod); + /* py = (px + py) * (qx + qy) - (py * qy) - (px * qx) */ + sp_1024_mont_sub_42(py, t2, px, p1024_mod); + /* px = (px * qx) - (py * qy)*/ + sp_1024_mont_sub_42(px, px, t1, p1024_mod); +} + +#ifndef WOLFSSL_SP_SMALL +/* + * Convert point from projective to affine but keep in Montgomery form. + * + * p [in,out] Point to convert. + * t [in] Temporary numbers: 2. + */ +static void sp_1024_mont_map_42(sp_point_1024* p, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 42; + + sp_1024_mont_inv_42(t1, p->z, t2); + sp_1024_mont_sqr_42(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(t1, t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(p->x, p->x, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_42(p->y, p->y, t1, p1024_mod, p1024_mp_mod); + XMEMCPY(p->z, p1024_norm_mod, sizeof(sp_digit) * 42); +} + +#endif /* WOLFSSL_SP_SMALL */ +/* + * Calculate gradient of line through P, P and [-2]P, accumulate line and + * double P. + * + * Calculations: + * l = 3 * (p.x^2 - p.z^4) = 3 * (p.x - p.z^2) * (p.x + p.z^2) + * r.x = l * (p.x + q.x * p.z^2) - 2 * p.y^2 + * r.y = 2 * p.y * p.z^3 * q.y (= p'.z * p.z^2 * q.y) + * v* = v*^2 * r* + * p'.x = l^2 - 8 * p.y^2 * p.x + * p'.y = (4 * p.y^2 * p.x - p'.x) * l - 8 * p.y^4 + * p'.z = 2 * p.y * p.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] p ECC point - point on E(F_p^2) to double. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_dbl_42(sp_digit* vx, sp_digit* vy, + sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 42; + sp_digit* pz2 = t + 2 * 42; + sp_digit* rx = t + 4 * 42; + sp_digit* ry = t + 6 * 42; + sp_digit* l = t + 8 * 42; + sp_digit* ty = t + 10 * 42; + + /* v = v^2 */ + sp_1024_proj_sqr_42(vx, vy, t); + /* pz2 = p.z^2 */ + sp_1024_mont_sqr_42(pz2, p->z, p1024_mod, p1024_mp_mod); + /* t1 = p.x + p.z^2 */ + sp_1024_mont_add_42(ty, p->x, pz2, p1024_mod); + /* l = p.x - p.z^2 */ + sp_1024_mont_sub_42(l, p->x, pz2, p1024_mod); + /* t1 = (p.x + p.z^2) * (p.x - p.z^2) = p.x^2 - p.z^4 */ + sp_1024_mont_mul_42(t1, l, ty, p1024_mod, p1024_mp_mod); + /* l = 3 * (p.x^2 - p.z^4) */ + sp_1024_mont_tpl_42(l, t1, p1024_mod); + /* t1 = q.x * p.z^2 */ + sp_1024_mont_mul_42(t1, q->x, pz2, p1024_mod, p1024_mp_mod); + /* t1 = p.x + q.x * p.z^2 */ + sp_1024_mont_add_42(t1, p->x, t1, p1024_mod); + /* r.x = l * (p.x + q.x * p.z^2) */ + sp_1024_mont_mul_42(rx, l, t1, p1024_mod, p1024_mp_mod); + /* r.y = 2 * p.y */ + sp_1024_mont_dbl_42(ry, p->y, p1024_mod); + /* ty = 4 * p.y ^ 2 */ + sp_1024_mont_sqr_42(ty, ry, p1024_mod, p1024_mp_mod); + /* t1 = 2 * p.y ^ 2 */ + sp_1024_div2_42(t1, ty, p1024_mod); + /* r.x -= 2 * (p.y ^ 2) */ + sp_1024_mont_sub_42(rx, rx, t1, p1024_mod); + /* p'.z = p.y * 2 * p.z */ + sp_1024_mont_mul_42(p->z, p->z, ry, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 */ + sp_1024_mont_mul_42(t1, p->z, pz2, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 * q.y */ + sp_1024_mont_mul_42(ry, t1, q->y, p1024_mod, p1024_mp_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_42(vx, vy, rx, ry, t); + + /* Double point using previously calculated values + * l = 3 * (p.x - p.z^2).(p.x + p.z^2) + * ty = 4 * p.y^2 + * p'.z = 2 * p.y * p.z + */ + /* t1 = (4 * p.y^2) ^ 2 = 16 * p.y^4 */ + sp_1024_mont_sqr_42(t1, ty, p1024_mod, p1024_mp_mod); + /* t1 = 16 * p.y^4 / 2 = 8 * p.y^4 */ + sp_1024_div2_42(t1, t1, p1024_mod); + /* p'.y = 4 * p.y^2 * p.x */ + sp_1024_mont_mul_42(p->y, ty, p->x, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 */ + sp_1024_mont_sqr_42(p->x, l, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 - 4 * p.y^2 * p.x */ + sp_1024_mont_sub_42(p->x, p->x, p->y, p1024_mod); + /* p'.x = l^2 - 8 * p.y^2 * p.x */ + sp_1024_mont_sub_42(p->x, p->x, p->y, p1024_mod); + /* p'.y = 4 * p.y^2 * p.x - p.x' */ + sp_1024_mont_sub_42(ty, p->y, p->x, p1024_mod); + /* p'.y = (4 * p.y^2 * p.x - p'.x) * l */ + sp_1024_mont_mul_42(p->y, ty, l, p1024_mod, p1024_mp_mod); + /* p'.y = (4 * p.y^2 * p.x - p'.x) * l - 8 * p.y^4 */ + sp_1024_mont_sub_42(p->y, p->y, t1, p1024_mod); +} + +#ifdef WOLFSSL_SP_SMALL +/* + * Calculate gradient of line through C, P and -C-P, accumulate line and + * add P to C. + * + * Calculations: + * r.x = (q.x + p.x) * c.y - (q.x * c.z^2 + c.x) * p.y * c.z + * r.y = (c.x - p.x * c.z^2) * q.y * c.z + * v* = v* * r* + * r = p.y * c.z^3 - c.y + * c'.x = r^2 + h^3 - 2 * c.x * h^2 + * c'.y = r * (c'.x - c.x * h^2) - c.y * h^3 + * c'.z = (c.x - p.x * c.z^2) * c.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] c ECC point - current point on E(F_p^2) to be added + * to. + * @param [in] p ECC point - point on E(F_p^2) to add. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] qx_px SP that is a constant value across adds. + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_add_one_42(sp_digit* vx, sp_digit* vy, + sp_point_1024* c, sp_point_1024* p, sp_point_1024* q, sp_digit* qx_px, + sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 42; + sp_digit* rx = t + 4 * 42; + sp_digit* ry = t + 6 * 42; + sp_digit* h = t + 8 * 42; + sp_digit* r = t + 10 * 42; + + /* r.x = (q.x + p.x) * c.y */ + sp_1024_mont_mul_42(rx, qx_px, c->y, p1024_mod, p1024_mp_mod); + /* t2 = c.z^2 */ + sp_1024_mont_sqr_42(t2, c->z, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 */ + sp_1024_mont_mul_42(t1, q->x, t2, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 + c.x */ + sp_1024_mont_add_42(h, t1, c->x, p1024_mod); + /* r = p.y * c.z */ + sp_1024_mont_mul_42(ry, p->y, c->z, p1024_mod, p1024_mp_mod); + /* t1 = (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_mul_42(t1, h, ry, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z * c.z^2 = p.y * c.z^3 */ + sp_1024_mont_mul_42(r, ry, t2, p1024_mod, p1024_mp_mod); + /* r.x -= (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_sub_42(rx, rx, t1, p1024_mod); + /* t1 = p.x * c.z^2 */ + sp_1024_mont_mul_42(t1, p->x, t2, p1024_mod, p1024_mp_mod); + /* h = c.x - p.x * c.z^2 */ + sp_1024_mont_sub_42(h, c->x, t1, p1024_mod); + /* c'.z = (c.x - p.x * c.z^2) * c.z */ + sp_1024_mont_mul_42(c->z, h, c->z, p1024_mod, p1024_mp_mod); + /* r.y = (c.x - p.x * c.z^2) * c.z * q.y */ + sp_1024_mont_mul_42(ry, c->z, q->y, p1024_mod, p1024_mp_mod); + /* v = v * r */ + sp_1024_proj_mul_42(vx, vy, rx, ry, t); + + /* Add p to c using previously calculated values. + * h = c.x - p.x * c.z^2 + * r = p.y * c.z^3 + * c'.z = (c.x - p.x * c.z^2) * c.z + */ + + /* r = p.y * c.z^3 - c.y */ + sp_1024_mont_sub_42(r, r, c->y, p1024_mod); + /* t1 = r^2 */ + sp_1024_mont_sqr_42(t1, r, p1024_mod, p1024_mp_mod); + /* t2 = h^2 */ + sp_1024_mont_sqr_42(rx, h, p1024_mod, p1024_mp_mod); + /* ry = c.x * h^2 */ + sp_1024_mont_mul_42(ry, c->x, rx, p1024_mod, p1024_mp_mod); + /* t2 = h^3 */ + sp_1024_mont_mul_42(t2, rx, h, p1024_mod, p1024_mp_mod); + /* c->x = r^2 + h^3 */ + sp_1024_mont_add_42(c->x, t1, t2, p1024_mod); + /* t1 = 2 * c.x * h^2 */ + sp_1024_mont_dbl_42(t1, ry, p1024_mod); + /* c'.x = r^2 + h^3 - 2 * c.x * h^2 */ + sp_1024_mont_sub_42(c->x, c->x, t1, p1024_mod); + /* ry = c'.x - c.x * h^2 */ + sp_1024_mont_sub_42(t1, c->x, ry, p1024_mod); + /* ry = r * (c'.x - c.x * h^2) */ + sp_1024_mont_mul_42(ry, t1, r, p1024_mod, p1024_mp_mod); + /* t2 = c.y * h^3 */ + sp_1024_mont_mul_42(t1, t2, c->y, p1024_mod, p1024_mp_mod); + /* c'.y = r * (c'.x - c.x * h^2) - c.y * h^3 */ + sp_1024_mont_sub_42(c->y, ry, t1, p1024_mod); +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * @param [in] key SAKKE key. + * @param [in] p First point on E(F_p)[q]. + * @param [in] q Second point on E(F_p)[q]. + * @param [in] r Result of calculation. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +int sp_Pairing_1024(const ecc_point* pm, const ecc_point* qm, mp_int* res) +{ + int err = MP_OKAY; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit* qx_px; +#else + sp_digit t[6 * 2 * 42]; + sp_digit vx[2 * 42]; + sp_digit vy[2 * 42]; + sp_digit qx_px[2 * 42]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + + err = sp_1024_point_new_42(NULL, pd, p); + if (err == MP_OKAY) { + err = sp_1024_point_new_42(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_42(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 9 * 42 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 42 * 2; + vy = td + 7 * 42 * 2; + qx_px = td + 8 * 42 * 2; +#endif + r = vy; + + sp_1024_point_from_ecc_point_42(p, pm); + sp_1024_point_from_ecc_point_42(q, qm); + + err = sp_1024_mod_mul_norm_42(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_42(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_42(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_42(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_42(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 42); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 42); + + sp_1024_mont_add_42(qx_px, q->x, p->x, p1024_mod); + + for (i = 1020; i >= 0; i--) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_dbl_42(vx, vy, c, q, t); + + if ((i > 0) && ((p1024_order[i / 25] >> (i % 25)) & 1)) { + /* Accumulate line into v and add P into C. */ + sp_1024_accumulate_line_add_one_42(vx, vy, c, p, q, qx_px, t); + } + } + + /* Final exponentiation */ + sp_1024_proj_sqr_42(vx, vy, t); + sp_1024_proj_sqr_42(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_42(vx, vx, t); + sp_1024_mont_mul_42(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 42, 0, sizeof(sp_digit) * 42); + sp_1024_mont_reduce_42(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_42(c, 1, NULL); + sp_1024_point_free_42(q, 1, NULL); + sp_1024_point_free_42(p, 1, NULL); + return err; +} + +#else +/* + * Calculate gradient of line through C, P and -C-P, accumulate line and + * add P to C. + * + * Both C and P have z ordinates to use in the calculation. + * + * Calculations: + * r.x = (q.x * c.z^2 + c.x) * p.y * c.z - (q.x * p.z^2 + p.x) * c.y * p.z + * r.y = (p.x * c.z^2 - c.x * p.z^2) * q.y * p.z * c.z + * v* = v* * r* + * h = p.x * c.z^2 - c.x * p.z^2 + * r = p.y * c.z^3 - c.y * p.z^3 + * c'.x = r^2 - h^3 - 2 * c.x * p.z^2 * h^2 + * c'.y = r * (c.x * p.z^2 * h^2 - c'.x) - c.y * p.z^3 * h^3 + * c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] c ECC point - current point on E(F_p^2) to be added + * to. + * @param [in,out] p ECC point - point on E(F_p^2) to add. + * @param [in,out] q ECC point - second point on E(F_P^2). + * @param [in,out] t SP temporaries (6 used). + * @param [in,out] neg Indicates to use negative P. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static void sp_1024_accumulate_line_add_n_42(sp_digit* vx, sp_digit* vy, + const sp_point_1024* p, const sp_point_1024* q, + sp_point_1024* c, sp_digit* t, int neg) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 42; + sp_digit* rx = t + 4 * 42; + sp_digit* ry = t + 6 * 42; + sp_digit* h = t + 8 * 42; + sp_digit* r = t + 10 * 42; + + /* h = p.z^2 */ + sp_1024_mont_sqr_42(h, p->z, p1024_mod, p1024_mp_mod); + /* rx = q.x * p.z^2 */ + sp_1024_mont_mul_42(rx, q->x, h, p1024_mod, p1024_mp_mod); + /* rx = q.x * p.z^2 + p.x */ + sp_1024_mont_add_42(t2, rx, p->x, p1024_mod); + /* c.y = c.y * p.z */ + sp_1024_mont_mul_42(t1, c->y, p->z, p1024_mod, p1024_mp_mod); + /* r.x = (q.x * p.z^2 + p.x) * c.y * p.z */ + sp_1024_mont_mul_42(rx, t2, t1, p1024_mod, p1024_mp_mod); + /* c.y = c.y * p.z^3 */ + sp_1024_mont_mul_42(c->y, t1, h, p1024_mod, p1024_mp_mod); + /* t2 = c.z^2 */ + sp_1024_mont_sqr_42(t2, c->z, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 */ + sp_1024_mont_mul_42(t1, q->x, t2, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 + c.x */ + sp_1024_mont_add_42(t1, t1, c->x, p1024_mod); + /* c.x = c.x * p.z^2 */ + sp_1024_mont_mul_42(c->x, c->x, h, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z */ + sp_1024_mont_mul_42(r, p->y, c->z, p1024_mod, p1024_mp_mod); + if (neg) { + /* r = -p.y * c.z */ + sp_1024_mont_sub_42(r, p1024_mod, r, p1024_mod); + } + /* t1 = (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_mul_42(ry, t1, r, p1024_mod, p1024_mp_mod); + /* r.x -= (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_sub_42(rx, ry, rx, p1024_mod); + /* t1 = p.x * c.z^2 */ + sp_1024_mont_mul_42(t1, p->x, t2, p1024_mod, p1024_mp_mod); + /* h = p.x * c.z^2 - c.x * p.z^2 */ + sp_1024_mont_sub_42(h, t1, c->x, p1024_mod); + /* c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z */ + sp_1024_mont_mul_42(t1, h, c->z, p1024_mod, p1024_mp_mod); + /* c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z * p.z */ + sp_1024_mont_mul_42(c->z, t1, p->z, p1024_mod, p1024_mp_mod); + /* r.y = (p.x * c.z^2 - c.x * p.z^2) * c.z * p.z * q.y */ + sp_1024_mont_mul_42(ry, c->z, q->y, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z^3 */ + sp_1024_mont_mul_42(t1, r, t2, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z^3 - c.y * p.z^3 */ + sp_1024_mont_sub_42(r, t1, c->y, p1024_mod); + /* v = v * r */ + sp_1024_proj_mul_42(vx, vy, rx, ry, t); + + /* Add p to c using previously calculated values. + * h = p.x * c.z^2 - c.x * p.z^2 + * r = p.y * c.z^3 - c.y * p.z^3 + * c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z + */ + + /* t1 = r^2 */ + sp_1024_mont_sqr_42(t1, r, p1024_mod, p1024_mp_mod); + /* t2 = h^2 */ + sp_1024_mont_sqr_42(rx, h, p1024_mod, p1024_mp_mod); + /* ry = c.x * p.z^2 * h^2 */ + sp_1024_mont_mul_42(ry, rx, c->x, p1024_mod, p1024_mp_mod); + /* t2 = h^3 */ + sp_1024_mont_mul_42(t2, rx, h, p1024_mod, p1024_mp_mod); + /* c'.x = r^2 - h^3 */ + sp_1024_mont_sub_42(c->x, t1, t2, p1024_mod); + /* t1 = 2 * c.x * p.z^2 * h^2 */ + sp_1024_mont_dbl_42(t1, ry, p1024_mod); + /* c'.x = r^2 - h^3 - 2 * c.x * p.z^2 * h^2 */ + sp_1024_mont_sub_42(c->x, c->x, t1, p1024_mod); + /* ry = c.x * p.z^2 * h^2 - c'.x */ + sp_1024_mont_sub_42(t1, ry, c->x, p1024_mod); + /* ry = r * (c.x * p.z^2 * h^2 - c'.x) */ + sp_1024_mont_mul_42(ry, t1, r, p1024_mod, p1024_mp_mod); + /* t2 = c.y * p.z^3 * h^3 */ + sp_1024_mont_mul_42(t1, t2, c->y, p1024_mod, p1024_mp_mod); + /* c'.y = r * (c.x * p.z^2 * h^2 - c'.x) - c.y * p.z^3 * h^3 */ + sp_1024_mont_sub_42(c->y, ry, t1, p1024_mod); +} + +/* + * Perform n accumulate doubles and doubles of P. + * + * py = 2 * p.y + * + * For each double: + * Calculate gradient of line through P, P and [-2]P, accumulate line and + * double P. + * + * Calculations: + * l = 3 * (p.x^2 - p.z^4) = 3 * (p.x - p.z^2) * (p.x + p.z^2) + * r.x = l * (p.x + q.x * p.z^2) - py^2 / 2 + * r.y = py * p.z^3 * q.y (= p'.z * p.z^2 * q.y) + * v* = v*^2 * r* + * p'.x = l^2 - 2 * py^2 * p.x + * py' = (py^2 * p.x - p'.x) * l - py^4 (= 2 * p'.y) + * p'.z = py * p.z + * + * Finally: + * p'.y = py' / 2 + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] p ECC point - point on E(F_p^2) to double. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] n Number of times to double. + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_dbl_n_42(sp_digit* vx, sp_digit* vy, + sp_point_1024* p, const sp_point_1024* q, int n, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 42; + sp_digit* pz2 = t + 2 * 42; + sp_digit* rx = t + 4 * 42; + sp_digit* ry = t + 6 * 42; + sp_digit* l = t + 8 * 42; + sp_digit* ty = t + 10 * 42; + int i; + + /* py = 2 * p.y */ + sp_1024_mont_dbl_42(p->y, p->y, p1024_mod); + + for (i = 0; i < n; i++) { + /* v = v^2 */ + sp_1024_proj_sqr_42(vx, vy, t); + /* pz2 = p.z^2 */ + sp_1024_mont_sqr_42(pz2, p->z, p1024_mod, p1024_mp_mod); + /* t1 = p.x + p.z^2 */ + sp_1024_mont_add_42(t1, p->x, pz2, p1024_mod); + /* l = p.x - p.z^2 */ + sp_1024_mont_sub_42(l, p->x, pz2, p1024_mod); + /* t1 = (p.x + p.z^2) * (p.x - p.z^2) = p.x^2 - p.z^4 */ + sp_1024_mont_mul_42(ty, l, t1, p1024_mod, p1024_mp_mod); + /* l = 3 * (p.x^2 - p.z^4) */ + sp_1024_mont_tpl_42(l, ty, p1024_mod); + /* t1 = q.x * p.z^2 */ + sp_1024_mont_mul_42(t1, q->x, pz2, p1024_mod, p1024_mp_mod); + /* t1 = p.x + q.x * p.z^2 */ + sp_1024_mont_add_42(t1, p->x, t1, p1024_mod); + /* r.x = l * (p.x + q.x * p.z^2) */ + sp_1024_mont_mul_42(rx, l, t1, p1024_mod, p1024_mp_mod); + /* ty = py ^ 2 */ + sp_1024_mont_sqr_42(ty, p->y, p1024_mod, p1024_mp_mod); + /* t1 = py ^ 2 / 2 */ + sp_1024_div2_42(t1, ty, p1024_mod); + /* r.x -= py ^ 2 / 2 */ + sp_1024_mont_sub_42(rx, rx, t1, p1024_mod); + /* p'.z = py * pz */ + sp_1024_mont_mul_42(p->z, p->z, p->y, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 */ + sp_1024_mont_mul_42(t1, p->z, pz2, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 * q.y */ + sp_1024_mont_mul_42(ry, t1, q->y, p1024_mod, p1024_mp_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_42(vx, vy, rx, ry, t); + + /* Double point using previously calculated values + * l = 3 * (p.x - p.z^2).(p.x + p.z^2) + * ty = py^2 + * p'.z = py * p.z + */ + /* t1 = py^2 ^ 2 = py^4 */ + sp_1024_mont_sqr_42(t1, ty, p1024_mod, p1024_mp_mod); + /* py' = py^2 * p. x */ + sp_1024_mont_mul_42(p->y, ty, p->x, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 */ + sp_1024_mont_sqr_42(p->x, l, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 - py^2 * p.x */ + sp_1024_mont_sub_42(p->x, p->x, p->y, p1024_mod); + /* p'.x = l^2 - 2 * p.y^2 * p.x */ + sp_1024_mont_sub_42(p->x, p->x, p->y, p1024_mod); + /* py' = py^2 * p.x - p.x' */ + sp_1024_mont_sub_42(ty, p->y, p->x, p1024_mod); + /* py' = (p.y^2 * p.x - p'.x) * l */ + sp_1024_mont_mul_42(p->y, ty, l, p1024_mod, p1024_mp_mod); + /* py' = (p.y^2 * p.x - p'.x) * l * 2 */ + sp_1024_mont_dbl_42(p->y, p->y, p1024_mod); + /* py' = (p.y^2 * p.x - p'.x) * l * 2 - p.y^4 */ + sp_1024_mont_sub_42(p->y, p->y, t1, p1024_mod); + } + + /* p'.y = py' / 2 */ + sp_1024_div2_42(p->y, p->y, p1024_mod); +} + +/* Operations to perform based on order - 1. + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * Pairs: #dbls, add/subtract window value + */ +static const signed char sp_1024_order_op[] = { + 5, 6, -13, 9, -21, 6, -5, 8, 31, 6, 3, 6, -27, 6, 25, 9, + -1, 6, -11, 6, -13, 6, -7, 6, -15, 6, -29, 7, 25, 6, -9, 6, + -19, 7, 3, 6, 11, 9, -23, 6, 1, 6, 27, 6, 1, 7, -25, 8, + 13, 7, -13, 7, -23, 10, 19, 7, 7, 7, -3, 7, 27, 6, -7, 7, + -21, 7, 11, 7, 31, 8, 1, 7, -23, 6, -17, 6, -3, 10, 11, 6, + -21, 7, -27, 11, -29, 6, -1, 10, 15, 8, 27, 7, 17, 6, 17, 7, + -13, 8, 13, 6, 21, 7, -29, 6, 19, 7, -25, 6, 11, 9, 29, 7, + -7, 8, 27, 7, 29, 10, -1, 8, -7, 8, 17, 6, 17, 7, -27, 7, + -21, 6, -9, 6, -27, 12, -23, 6, 19, 6, 13, 6, -11, 7, 27, 6, + 17, 6, -7, 6, -25, 7, -29, 6, 9, 7, 7, 6, 13, 6, -25, 6, + -19, 6, 13, 6, -11, 6, 5, 8, 19, 6, -21, 8, 23, 7, 27, 6, + -13, 6, -19, 11, 29, 7, -15, 6, -9, 7, -21, 10, -3, 7, 21, 10, + 25, 6, -15, 6, -23, 6, 21, 6, 1, 6, 21, 7, -3, 6, -3, 7, + -7, 6, -23, 7, 7, 8, 15, 9, 5, 6, -11, 6, 21, 11, -27, 7, + 27, 6, -11, 6, 31, 6, -21, 6, 19, 6, -7, 8, -7, 13, -3, 6, + -7, 7, -3, 6, 1, 6, 7, 8, 19, 8, 11, 9, -9, 7, -31, 12, + 25, 6, -17, 9, -15, 7, 5, 6, 25, 7, -5, 7, -25, 6, 17, 8, + -19, 6, -13, 6, 27, 8, 1, 7, -5, 7, -1, 6, 21, 6, 3, 10, + -3, 1, +}; +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int sp_Pairing_1024(const ecc_point* pm, const ecc_point* qm, mp_int* res) +{ + int err; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit (*pre_vx)[84]; + sp_digit (*pre_vy)[84]; + sp_digit (*pre_nvy)[84]; + sp_point_1024* pre_p; +#else + sp_digit t[6 * 2 * 42]; + sp_digit vx[2 * 42]; + sp_digit vy[2 * 42]; + sp_digit pre_vx[16][84]; + sp_digit pre_vy[16][84]; + sp_digit pre_nvy[16][84]; + sp_point_1024 pre_p[16]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + int j; + + err = sp_1024_point_new_42(NULL, pd, p); + if (err == MP_OKAY) { + err = sp_1024_point_new_42(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_42(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 56 * 42 * 2 + 16 * sizeof(sp_point_1024), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 42 * 2; + vy = td + 7 * 42 * 2; + pre_vx = (sp_digit(*)[84])(td + 8 * 42 * 2); + pre_vy = (sp_digit(*)[84])(td + 24 * 42 * 2); + pre_nvy = (sp_digit(*)[84])(td + 40 * 42 * 2); + pre_p = (sp_point_1024*)(td + 56 * 42 * 2); +#endif + r = vy; + + sp_1024_point_from_ecc_point_42(p, pm); + sp_1024_point_from_ecc_point_42(q, qm); + + err = sp_1024_mod_mul_norm_42(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_42(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_42(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_42(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_42(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMCPY(&pre_p[0], p, sizeof(sp_point_1024)); + XMEMSET(pre_vx[0], 0, sizeof(sp_digit) * 2 * 42); + pre_vx[0][0] = 1; + XMEMSET(pre_vy[0], 0, sizeof(sp_digit) * 2 * 42); + sp_1024_mont_sub_42(pre_nvy[0], p1024_mod, pre_vy[0], p1024_mod); + + /* [2]P for adding */ + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 42); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 42); + sp_1024_accumulate_line_dbl_42(vx, vy, c, q, t); + + /* 3, 5, ... */ + for (i = 1; i < 16; i++) { + XMEMCPY(&pre_p[i], &pre_p[i-1], sizeof(sp_point_1024)); + XMEMCPY(pre_vx[i], pre_vx[i-1], sizeof(sp_digit) * 2 * 42); + XMEMCPY(pre_vy[i], pre_vy[i-1], sizeof(sp_digit) * 2 * 42); + sp_1024_proj_mul_42(pre_vx[i], pre_vy[i], vx, vy, t); + sp_1024_accumulate_line_add_n_42(pre_vx[i], pre_vy[i], c, + q, &pre_p[i], t, 0); + sp_1024_mont_sub_42(pre_nvy[i], p1024_mod, pre_vy[i], p1024_mod); + } + + j = sp_1024_order_op[0] / 2; + XMEMCPY(c, &pre_p[j], sizeof(sp_point_1024)); + XMEMCPY(vx, pre_vx[j], sizeof(sp_digit) * 2 * 42); + XMEMCPY(vy, pre_vy[j], sizeof(sp_digit) * 2 * 42); + + /* Accumulate line into v and double point n times. */ + sp_1024_accumulate_line_dbl_n_42(vx, vy, c, q, + sp_1024_order_op[1], t); + + for (i = 2; i < 290; i += 2) { + j = sp_1024_order_op[i]; + if (j > 0) { + j /= 2; + /* Accumulate line into v and add P into C. */ + sp_1024_proj_mul_42(vx, vy, pre_vx[j], pre_vy[j], t); + sp_1024_accumulate_line_add_n_42(vx, vy, &pre_p[j], q, c, + t, 0); + } + else { + j = -j / 2; + /* Accumulate line into v and add P into C. */ + sp_1024_proj_mul_42(vx, vy, pre_vx[j], pre_nvy[j], t); + sp_1024_accumulate_line_add_n_42(vx, vy, &pre_p[j], q, c, + t, 1); + } + + /* Accumulate line into v and double point n times. */ + sp_1024_accumulate_line_dbl_n_42(vx, vy, c, q, + sp_1024_order_op[i + 1], t); + } + + /* Final exponentiation */ + sp_1024_proj_sqr_42(vx, vy, t); + sp_1024_proj_sqr_42(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_42(vx, vx, t); + sp_1024_mont_mul_42(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 42, 0, sizeof(sp_digit) * 42); + sp_1024_mont_reduce_42(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_42(c, 1, NULL); + sp_1024_point_free_42(q, 1, NULL); + sp_1024_point_free_42(p, 1, NULL); + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* + * Generate table for pairing. + * + * Small implementation does not use a table - returns 0 length. + * + * pm [in] Point to generate table for. + * table [in] Generated table. + * len [in,out] On in, the size of the buffer. + * On out, length of table generated. + * @return 0 on success. + * LENGTH_ONLY_E when table is NULL and only length returned. + * BUFFER_E when len is too small. + */ +int sp_Pairing_gen_precomp_1024(const ecc_point* pm, byte* table, + word32* len) +{ + int err = 0; + + if (table == NULL) { + *len = 0; + err = LENGTH_ONLY_E; + } + else if (*len != 0) { + err = BUFFER_E; + } + + (void)*pm; + + return err; +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Small implementation does not use a table - use the normal implementation. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @param [in] table Precomputed table of values. + * @param [in] len Length of precomputed table of values in bytes. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int sp_Pairing_precomp_1024(const ecc_point* pm, const ecc_point* qm, + mp_int* res, const byte* table, word32 len) +{ + (void)table; + (void)len; + return sp_Pairing_1024(pm, qm, res); +} + +#else +/* + * Calc l and c for the point when doubling p. + * + * l = 3 * (p.x^2 - 1) / (2 * p.y) + * c = l * p.x - p.y + * + * @param [out] lr Gradient result - table entry. + * @param [out] cr Constant result - table entry. + * @param [in] px X-ordinate of point to double. + * @param [in] py Y-ordinate of point to double. + * @param [in] t SP temporaries (3 used). + */ +static void sp_1024_accum_dbl_calc_lc_42(sp_digit* lr, sp_digit* cr, + const sp_digit* px, const sp_digit* py, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 2 * 42; + sp_digit* t2 = t + 2 * 2 * 42; + sp_digit* l = t + 4 * 2 * 42; + + + /* l = 1 / 2 * p.y */ + sp_1024_mont_dbl_42(l, py, p1024_mod); + sp_1024_mont_inv_42(l, l, t); + + /* t1 = p.x^2 */ + sp_1024_mont_sqr_42(t1, px, p1024_mod, p1024_mp_mod); + /* t1 = p.x - 1 */ + sp_1024_mont_sub_42(t1, t1, p1024_norm_mod, p1024_mod); + /* t1 = 3 * (p.x^2 - 1) */ + sp_1024_mont_dbl_42(t2, t1, p1024_mod); + sp_1024_mont_add_42(t1, t1, t2, p1024_mod); + /* t1 = 3 * (p.x^2 - 1) / (2 * p.y) */ + sp_1024_mont_mul_42(l, l, t1, p1024_mod, p1024_mp_mod); + /* t2 = l * p.x */ + sp_1024_mont_mul_42(t2, l, px, p1024_mod, p1024_mp_mod); + /* c = t2 = l * p.x - p.y */ + sp_1024_mont_sub_42(t2, t2, py, p1024_mod); + + XMEMCPY(lr, l, sizeof(sp_digit) * 42); + XMEMCPY(cr, t2, sizeof(sp_digit) * 42); +} + +/* + * Calc l and c when adding p and c. + * + * l = (c.y - p.y) / (c.x - p.x) + * c = (p.x * c.y - cx * p.y) / (cx - p.x) + * + * @param [out] lr Gradient result - table entry. + * @param [out] cr Constant result - table entry. + * @param [in] px X-ordinate of point to add. + * @param [in] py Y-ordinate of point to add. + * @param [in] cx X-ordinate of current point. + * @param [in] cy Y-ordinate of current point. + * @param [in] t SP temporaries (3 used). + */ +static void sp_1024_accum_add_calc_lc_42(sp_digit* lr, sp_digit* cr, + const sp_digit* px, const sp_digit* py, const sp_digit* cx, + const sp_digit* cy, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 2 * 42; + sp_digit* c = t + 2 * 2 * 42; + sp_digit* l = t + 4 * 2 * 42; + + + /* l = 1 / (c.x - p.x) */ + sp_1024_mont_sub_42(l, cx, px, p1024_mod); + sp_1024_mont_inv_42(l, l, t); + + /* c = p.x * c.y */ + sp_1024_mont_mul_42(c, px, cy, p1024_mod, p1024_mp_mod); + /* t1 = c.x * p.y */ + sp_1024_mont_mul_42(t1, cx, py, p1024_mod, p1024_mp_mod); + /* c = (p.x * c.y) - (c.x * p.y) */ + sp_1024_mont_sub_42(c, c, t1, p1024_mod); + /* c = ((p.x * c.y) - (c.x * p.y)) / (c.x - p.x) */ + sp_1024_mont_mul_42(c, c, l, p1024_mod, p1024_mp_mod); + /* t1 = c.y - p.y */ + sp_1024_mont_sub_42(t1, cy, py, p1024_mod); + /* l = (c.y - p.y) / (c.x - p.x) */ + sp_1024_mont_mul_42(l, t1, l, p1024_mod, p1024_mp_mod); + + XMEMCPY(lr, l, sizeof(sp_digit) * 42); + XMEMCPY(cr, c, sizeof(sp_digit) * 42); +} + +/* + * Calculate vx and vy given gradient l and constant c and point q. + * + * l is a the gradient and is multiplied by q->x. + * c is a the constant that is added to the multiplicative result. + * q->y is the y-ordinate in result to multiply. + * + * if dbl + * v* = v*^2 + * r.x = l * q.x + c + * r.y = q->y + * v* = v* * r* + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in] l Gradient to multiply with. + * @param [in] c Constant to add with. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] t SP temporaries (3 used). + * @param [in] dbl Indicates whether this is for doubling. Otherwise + * adding. + */ +static void sp_1024_accumulate_line_lc_42(sp_digit* vx, sp_digit* vy, + const sp_digit* l, const sp_digit* c, const sp_point_1024* q, + sp_digit* t, int dbl) +{ + sp_digit* rx = t + 4 * 2 * 42; + + /* v = v^2 */ + if (dbl) { + sp_1024_proj_sqr_42(vx, vy, t); + } + /* rx = l * q.x + c */ + sp_1024_mont_mul_42(rx, l, q->x, p1024_mod, p1024_mp_mod); + sp_1024_mont_add_42(rx, rx, c, p1024_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_42(vx, vy, rx, q->y, t); +} + +/* Operations to perform based on order - 1. + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * Pairs: #dbls, add/subtract window value + */ +static const signed char sp_1024_order_op_pre[] = { + 5, 6, -13, 9, -21, 6, -5, 8, 31, 6, 3, 6, -27, 6, 25, 9, + -1, 6, -11, 6, -13, 6, -7, 6, -15, 6, -29, 7, 25, 6, -9, 6, + -19, 7, 3, 6, 11, 9, -23, 6, 1, 6, 27, 6, 1, 7, -25, 8, + 13, 7, -13, 7, -23, 10, 19, 7, 7, 7, -3, 7, 27, 6, -7, 7, + -21, 7, 11, 7, 31, 8, 1, 7, -23, 6, -17, 6, -3, 10, 11, 6, + -21, 7, -27, 11, -29, 6, -1, 10, 15, 8, 27, 7, 17, 6, 17, 7, + -13, 8, 13, 6, 21, 7, -29, 6, 19, 7, -25, 6, 11, 9, 29, 7, + -7, 8, 27, 7, 29, 10, -1, 8, -7, 8, 17, 6, 17, 7, -27, 7, + -21, 6, -9, 6, -27, 12, -23, 6, 19, 6, 13, 6, -11, 7, 27, 6, + 17, 6, -7, 6, -25, 7, -29, 6, 9, 7, 7, 6, 13, 6, -25, 6, + -19, 6, 13, 6, -11, 6, 5, 8, 19, 6, -21, 8, 23, 7, 27, 6, + -13, 6, -19, 11, 29, 7, -15, 6, -9, 7, -21, 10, -3, 7, 21, 10, + 25, 6, -15, 6, -23, 6, 21, 6, 1, 6, 21, 7, -3, 6, -3, 7, + -7, 6, -23, 7, 7, 8, 15, 9, 5, 6, -11, 6, 21, 11, -27, 7, + 27, 6, -11, 6, 31, 6, -21, 6, 19, 6, -7, 8, -7, 13, -3, 6, + -7, 7, -3, 6, 1, 6, 7, 8, 19, 8, 11, 9, -9, 7, -31, 12, + 25, 6, -17, 9, -15, 7, 5, 6, 25, 7, -5, 7, -25, 6, 17, 8, + -19, 6, -13, 6, 27, 8, 1, 7, -5, 7, -1, 6, 21, 6, 3, 10, + -3, 1, +}; + +/* + * Generate table for pairing. + * + * Calculate the graident (l) and constant (c) at each step of the way. + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * + * pm [in] Point to generate table for. + * table [in] Generated table. + * len [in,out] On in, the size of the buffer. + * On out, length of table generated. + * @return 0 on success. + * LENGTH_ONLY_E when table is NULL and only length returned. + * BUFFER_E when len is too small. + * MEMORY_E when dynamic memory allocation fauls. + */ +int sp_Pairing_gen_precomp_1024(const ecc_point* pm, byte* table, + word32* len) +{ + int err = 0; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_point_1024* pre_p; +#else + sp_digit t[6 * 2 * 42]; + sp_point_1024 pre_p[16]; + sp_point_1024 pd; + sp_point_1024 cd; + sp_point_1024 negd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* c = NULL; + sp_point_1024* neg = NULL; + int i; + int j; + int k; + sp_table_entry_1024* precomp = (sp_table_entry_1024*)table; + + if (table == NULL) { + *len = sizeof(sp_table_entry_1024) * 1167; + err = LENGTH_ONLY_E; + } + + if ((err == MP_OKAY) && + (*len < (int)(sizeof(sp_table_entry_1024) * 1167))) { + err = BUFFER_E; + } + + if (err == MP_OKAY) { + err = sp_1024_point_new_42(NULL, pd, p); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_42(NULL, cd, c); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_42(NULL, negd, neg); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6 * 42 * 2 + 16 * sizeof(sp_point_1024), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + pre_p = (sp_point_1024*)(td + 6 * 42 * 2); +#endif + + sp_1024_point_from_ecc_point_42(p, pm); + + err = sp_1024_mod_mul_norm_42(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_42(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(p->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + neg->infinity = 0; + c->infinity = 0; + + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMCPY(&pre_p[0], p, sizeof(sp_point_1024)); + /* [2]P for adding */ + sp_1024_proj_point_dbl_42(c, p, t); + + /* 1, 3, ... */ + for (i = 1; i < 16; i++) { + sp_1024_proj_point_add_42(&pre_p[i], &pre_p[i-1], c, t); + sp_1024_mont_map_42(&pre_p[i], t); + } + + k = 0; + j = sp_1024_order_op_pre[0] / 2; + XMEMCPY(c, &pre_p[j], sizeof(sp_point_1024)); + + for (j = 0; j < sp_1024_order_op_pre[1]; j++) { + sp_1024_accum_dbl_calc_lc_42(precomp[k].x, precomp[k].y, c->x, c->y, t); + k++; + sp_1024_proj_point_dbl_42(c, c, t); + sp_1024_mont_map_42(c, t); + } + + for (i = 2; i < 290; i += 2) { + j = sp_1024_order_op_pre[i]; + if (j > 0) { + sp_1024_accum_add_calc_lc_42(precomp[k].x, precomp[k].y, + pre_p[j/2].x, pre_p[j/2].y, c->x, c->y, t); + k++; + sp_1024_proj_point_add_42(c, c, &pre_p[j/2], t); + sp_1024_mont_map_42(c, t); + } + else { + XMEMCPY(neg->x, pre_p[-j / 2].x, sizeof(pre_p->x)); + sp_1024_mont_sub_42(neg->y, p1024_mod, pre_p[-j / 2].y, + p1024_mod); + XMEMCPY(neg->z, pre_p[-j / 2].z, sizeof(pre_p->z)); + + sp_1024_accum_add_calc_lc_42(precomp[k].x, precomp[k].y, + neg->x, neg->y, c->x, c->y, t); + k++; + sp_1024_proj_point_add_42(c, c, neg, t); + sp_1024_mont_map_42(c, t); + } + + for (j = 0; j < sp_1024_order_op_pre[i + 1]; j++) { + sp_1024_accum_dbl_calc_lc_42(precomp[k].x, precomp[k].y, c->x, c->y, t); + k++; + sp_1024_proj_point_dbl_42(c, c, t); + sp_1024_mont_map_42(c, t); + } + } + + *len = sizeof(sp_table_entry_1024) * 1167; + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_42(neg, 1, NULL); + sp_1024_point_free_42(c, 1, NULL); + sp_1024_point_free_42(p, 1, NULL); + return err; +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * Pre-generate values in window (1, 3, ...) - only V. + * Table contains all gradient l and a constant for each point on the path. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @param [in] table Precomputed table of values. + * @param [in] len Length of precomputed table of values in bytes. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int sp_Pairing_precomp_1024(const ecc_point* pm, const ecc_point* qm, + mp_int* res, const byte* table, word32 len) +{ + int err = 0; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit (*pre_vx)[84]; + sp_digit (*pre_vy)[84]; + sp_digit (*pre_nvy)[84]; +#else + sp_digit t[6 * 2 * 42]; + sp_digit vx[2 * 42]; + sp_digit vy[2 * 42]; + sp_digit pre_vx[16][84]; + sp_digit pre_vy[16][84]; + sp_digit pre_nvy[16][84]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + int j; + int k; + const sp_table_entry_1024* precomp = (const sp_table_entry_1024*)table; + + if (len < (int)(sizeof(sp_table_entry_1024) * 1167)) { + err = BUFFER_E; + } + + if (err == MP_OKAY) { + err = sp_1024_point_new_42(NULL, pd, p); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_42(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_42(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 56 * 42 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 42 * 2; + vy = td + 7 * 42 * 2; + pre_vx = (sp_digit(*)[84])(td + 8 * 42 * 2); + pre_vy = (sp_digit(*)[84])(td + 24 * 42 * 2); + pre_nvy = (sp_digit(*)[84])(td + 40 * 42 * 2); +#endif + r = vy; + + sp_1024_point_from_ecc_point_42(p, pm); + sp_1024_point_from_ecc_point_42(q, qm); + + err = sp_1024_mod_mul_norm_42(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_42(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_42(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_42(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_42(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMSET(pre_vx[0], 0, sizeof(sp_digit) * 2 * 42); + pre_vx[0][0] = 1; + XMEMSET(pre_vy[0], 0, sizeof(sp_digit) * 2 * 42); + sp_1024_mont_sub_42(pre_nvy[0], p1024_mod, pre_vy[0], p1024_mod); + + /* [2]P for adding */ + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 42); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 42); + sp_1024_accumulate_line_dbl_42(vx, vy, c, q, t); + + /* 3, 5, ... */ + for (i = 1; i < 16; i++) { + XMEMCPY(pre_vx[i], pre_vx[i-1], sizeof(sp_digit) * 2 * 42); + XMEMCPY(pre_vy[i], pre_vy[i-1], sizeof(sp_digit) * 2 * 42); + sp_1024_proj_mul_42(pre_vx[i], pre_vy[i], vx, vy, t); + sp_1024_accumulate_line_add_n_42(pre_vx[i], pre_vy[i], c, + q, p, t, 0); + sp_1024_mont_sub_42(pre_nvy[i], p1024_mod, pre_vy[i], + p1024_mod); + } + + XMEMCPY(c->z, p1024_norm_mod, sizeof(sp_digit) * 42); + c->infinity = 0; + j = sp_1024_order_op_pre[0] / 2; + XMEMCPY(vx, pre_vx[j], sizeof(sp_digit) * 2 * 42); + XMEMCPY(vy, pre_vy[j], sizeof(sp_digit) * 2 * 42); + + k = 0; + for (j = 0; j < sp_1024_order_op_pre[1]; j++) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_lc_42(vx, vy, precomp[k].x, + precomp[k].y, q, t, 1); + k++; + } + + for (i = 2; i < 290; i += 2) { + sp_1024_accumulate_line_lc_42(vx, vy, precomp[k].x, + precomp[k].y, q, t, 0); + k++; + + j = sp_1024_order_op_pre[i]; + if (j > 0) { + j /= 2; + /* Accumulate line into v. */ + sp_1024_proj_mul_42(vx, vy, pre_vx[j], pre_vy[j], t); + } + else { + j = -j / 2; + /* Accumulate line into v. */ + sp_1024_proj_mul_42(vx, vy, pre_vx[j], pre_nvy[j], t); + } + + for (j = 0; j < sp_1024_order_op_pre[i + 1]; j++) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_lc_42(vx, vy, precomp[k].x, + precomp[k].y, q, t, 1); + k++; + } + } + + /* Final exponentiation */ + sp_1024_proj_sqr_42(vx, vy, t); + sp_1024_proj_sqr_42(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_42(vx, vx, t); + sp_1024_mont_mul_42(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 42, 0, sizeof(sp_digit) * 42); + sp_1024_mont_reduce_42(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_42(c, 1, NULL); + sp_1024_point_free_42(q, 1, NULL); + sp_1024_point_free_42(p, 1, NULL); + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Returns 1 if the number of zero. + * Implementation is constant time. + * + * a Number to check. + * returns 1 if the number is zero and 0 otherwise. + */ +static int sp_1024_iszero_42(const sp_digit* a) +{ + return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6] | a[7] | + a[8] | a[9] | a[10] | a[11] | a[12] | a[13] | a[14] | a[15] | + a[16] | a[17] | a[18] | a[19] | a[20] | a[21] | a[22] | a[23] | + a[24] | a[25] | a[26] | a[27] | a[28] | a[29] | a[30] | a[31] | + a[32] | a[33] | a[34] | a[35] | a[36] | a[37] | a[38] | a[39] | + a[40] | a[41]) == 0; +} + +#ifdef HAVE_ECC_CHECK_KEY +/* Read big endian unsigned byte array into r. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a Byte array. + * n Number of bytes in array to read. + */ +static void sp_1024_from_bin(sp_digit* r, int size, const byte* a, int n) +{ + int i; + int j = 0; + word32 s = 0; + + r[0] = 0; + for (i = n-1; i >= 0; i--) { + r[j] |= (((sp_digit)a[i]) << s); + if (s >= 17U) { + r[j] &= 0x1ffffff; + s = 25U - s; + if (j + 1 >= size) { + break; + } + r[++j] = (sp_digit)a[i] >> s; + s = 8U - s; + } + else { + s += 8U; + } + } + + for (j++; j < size; j++) { + r[j] = 0; + } +} + +/* Check that the x and y oridinates are a valid point on the curve. + * + * point EC point. + * heap Heap to use if dynamically allocating. + * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is + * not on the curve and MP_OKAY otherwise. + */ +static int sp_1024_ecc_is_point_42(const sp_point_1024* point, + void* heap) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* d = NULL; +#else + sp_digit t1d[2*42]; + sp_digit t2d[2*42]; +#endif + sp_digit* t1; + sp_digit* t2; + int32_t n; + int err = MP_OKAY; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 42 * 4, heap, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + (void)heap; + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t1 = d + 0 * 42; + t2 = d + 2 * 42; +#else + t1 = t1d; + t2 = t2d; +#endif + + sp_1024_sqr_42(t1, point->y); + (void)sp_1024_mod_42(t1, t1, p1024_mod); + sp_1024_sqr_42(t2, point->x); + (void)sp_1024_mod_42(t2, t2, p1024_mod); + sp_1024_mul_42(t2, t2, point->x); + (void)sp_1024_mod_42(t2, t2, p1024_mod); + (void)sp_1024_sub_42(t2, p1024_mod, t2); + sp_1024_mont_add_42(t1, t1, t2, p1024_mod); + + sp_1024_mont_add_42(t1, t1, point->x, p1024_mod); + sp_1024_mont_add_42(t1, t1, point->x, p1024_mod); + sp_1024_mont_add_42(t1, t1, point->x, p1024_mod); + + n = sp_1024_cmp_42(t1, p1024_mod); + sp_1024_cond_sub_42(t1, t1, p1024_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_42(t1); + if (!sp_1024_iszero_42(t1)) { + err = MP_VAL; + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (d != NULL) { + XFREE(d, heap, DYNAMIC_TYPE_ECC); + } +#endif + + return err; +} + +/* Check that the x and y oridinates are a valid point on the curve. + * + * pX X ordinate of EC point. + * pY Y ordinate of EC point. + * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is + * not on the curve and MP_OKAY otherwise. + */ +int sp_ecc_is_point_1024(const mp_int* pX, const mp_int* pY) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 pubd; +#endif + sp_point_1024* pub; + byte one[1] = { 1 }; + int err; + + err = sp_1024_point_new_42(NULL, pubd, pub); + if (err == MP_OKAY) { + sp_1024_from_mp(pub->x, 42, pX); + sp_1024_from_mp(pub->y, 42, pY); + sp_1024_from_bin(pub->z, 42, one, (int)sizeof(one)); + + err = sp_1024_ecc_is_point_42(pub, NULL); + } + + sp_1024_point_free_42(pub, 0, NULL); + + return err; +} + +/* Check that the private scalar generates the EC point (px, py), the point is + * on the curve and the point has the correct order. + * + * pX X ordinate of EC point. + * pY Y ordinate of EC point. + * privm Private scalar that generates EC point. + * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is + * not on the curve, ECC_INF_E if the point does not have the correct order, + * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and + * MP_OKAY otherwise. + */ +int sp_ecc_check_key_1024(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_digit privd[42]; + sp_point_1024 pubd; + sp_point_1024 pd; +#endif + sp_digit* priv = NULL; + sp_point_1024* pub; + sp_point_1024* p = NULL; + byte one[1] = { 1 }; + int err; + + err = sp_1024_point_new_42(heap, pubd, pub); + if (err == MP_OKAY) { + err = sp_1024_point_new_42(heap, pd, p); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY && privm) { + priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 42, heap, + DYNAMIC_TYPE_ECC); + if (priv == NULL) { + err = MEMORY_E; + } + } +#endif + + /* Quick check the lengs of public key ordinates and private key are in + * range. Proper check later. + */ + if ((err == MP_OKAY) && ((mp_count_bits(pX) > 1024) || + (mp_count_bits(pY) > 1024) || + ((privm != NULL) && (mp_count_bits(privm) > 1024)))) { + err = ECC_OUT_OF_RANGE_E; + } + + if (err == MP_OKAY) { +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + priv = privd; +#endif + + sp_1024_from_mp(pub->x, 42, pX); + sp_1024_from_mp(pub->y, 42, pY); + sp_1024_from_bin(pub->z, 42, one, (int)sizeof(one)); + if (privm) + sp_1024_from_mp(priv, 42, privm); + + /* Check point at infinitiy. */ + if ((sp_1024_iszero_42(pub->x) != 0) && + (sp_1024_iszero_42(pub->y) != 0)) { + err = ECC_INF_E; + } + } + + /* Check range of X and Y */ + if ((err == MP_OKAY) && + ((sp_1024_cmp_42(pub->x, p1024_mod) >= 0) || + (sp_1024_cmp_42(pub->y, p1024_mod) >= 0))) { + err = ECC_OUT_OF_RANGE_E; + } + + if (err == MP_OKAY) { + /* Check point is on curve */ + err = sp_1024_ecc_is_point_42(pub, heap); + } + + if (err == MP_OKAY) { + /* Point * order = infinity */ + err = sp_1024_ecc_mulmod_42(p, pub, p1024_order, 1, 1, heap); + } + /* Check result is infinity */ + if ((err == MP_OKAY) && ((sp_1024_iszero_42(p->x) == 0) || + (sp_1024_iszero_42(p->y) == 0))) { + err = ECC_INF_E; + } + + if (privm) { + if (err == MP_OKAY) { + /* Base * private = point */ + err = sp_1024_ecc_mulmod_base_42(p, priv, 1, 1, heap); + } + /* Check result is public key */ + if ((err == MP_OKAY) && + ((sp_1024_cmp_42(p->x, pub->x) != 0) || + (sp_1024_cmp_42(p->y, pub->y) != 0))) { + err = ECC_PRIV_KEY_E; + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (priv != NULL) { + XFREE(priv, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_42(p, 0, heap); + sp_1024_point_free_42(pub, 0, heap); + + return err; +} +#endif +#endif /* WOLFSSL_SP_1024 */ #endif /* WOLFSSL_HAVE_SP_ECC */ #endif /* SP_WORD_SIZE == 32 */ #endif /* !WOLFSSL_SP_ASM */ -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH || WOLFSSL_HAVE_SP_ECC */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH | WOLFSSL_HAVE_SP_ECC */ diff --git a/wolfcrypt/src/sp_c64.c b/wolfcrypt/src/sp_c64.c index 3842b58e0..253bc648b 100644 --- a/wolfcrypt/src/sp_c64.c +++ b/wolfcrypt/src/sp_c64.c @@ -1,6 +1,6 @@ /* sp.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -75,7 +75,8 @@ static const size_t addr_mask[2] = { 0, (size_t)-1 }; */ static void sp_2048_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -117,7 +118,8 @@ static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 57 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -151,7 +153,9 @@ static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -190,7 +194,10 @@ static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a) */ static void sp_2048_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; for (i=0; i<35; i++) { r[i+1] += r[i] >> 57; @@ -680,7 +687,9 @@ SP_NOINLINE static int sp_2048_sub_36(sp_digit* r, const sp_digit* a, SP_NOINLINE static void sp_2048_mul_36(sp_digit* r, const sp_digit* a, const sp_digit* b) { - int i, j, k; + int i; + int j; + int k; int128_t c; c = ((int128_t)a[35]) * b[35]; @@ -712,7 +721,9 @@ SP_NOINLINE static void sp_2048_mul_36(sp_digit* r, const sp_digit* a, */ SP_NOINLINE static void sp_2048_sqr_36(sp_digit* r, const sp_digit* a) { - int i, j, k; + int i; + int j; + int k; int128_t c; c = ((int128_t)a[35]) * a[35]; @@ -792,7 +803,9 @@ SP_NOINLINE static int sp_2048_sub_18(sp_digit* r, const sp_digit* a, SP_NOINLINE static void sp_2048_mul_18(sp_digit* r, const sp_digit* a, const sp_digit* b) { - int i, j, k; + int i; + int j; + int k; int128_t c; c = ((int128_t)a[17]) * b[17]; @@ -824,7 +837,9 @@ SP_NOINLINE static void sp_2048_mul_18(sp_digit* r, const sp_digit* a, */ SP_NOINLINE static void sp_2048_sqr_18(sp_digit* r, const sp_digit* a) { - int i, j, k; + int i; + int j; + int k; int128_t c; c = ((int128_t)a[17]) * a[17]; @@ -854,7 +869,7 @@ SP_NOINLINE static void sp_2048_sqr_18(sp_digit* r, const sp_digit* a) } #endif /* WOLFSSL_SP_SMALL */ -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ /* Caclulate the bottom digit of -1/a mod 2^n. * @@ -863,7 +878,8 @@ SP_NOINLINE static void sp_2048_sqr_18(sp_digit* r, const sp_digit* a) */ static void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho) { - sp_digit x, b; + sp_digit x; + sp_digit b; b = a[0]; x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ @@ -1181,7 +1197,6 @@ static void sp_2048_mont_reduce_18(sp_digit* a, const sp_digit* m, sp_digit mp) sp_2048_mul_add_18(a+i, m, mu); a[i+1] += a[i] >> 57; a[i] &= 0x1ffffffffffffffL; - sp_2048_mont_shift_18(a, a); sp_2048_cond_sub_18(a, a, m, 0 - (((a[17] >> 55) > 0) ? (sp_digit)1 : (sp_digit)0)); @@ -1197,8 +1212,8 @@ static void sp_2048_mont_reduce_18(sp_digit* a, const sp_digit* m, sp_digit mp) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_mul_18(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_2048_mont_mul_18(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_2048_mul_18(r, a, b); sp_2048_mont_reduce_18(r, m, mp); @@ -1211,8 +1226,8 @@ static void sp_2048_mont_mul_18(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_sqr_18(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_2048_mont_sqr_18(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_2048_sqr_18(r, a); sp_2048_mont_reduce_18(r, m, mp); @@ -1312,50 +1327,13 @@ static void sp_2048_cond_add_18(sp_digit* r, const sp_digit* a, #endif /* WOLFSSL_SP_SMALL */ } -#ifdef WOLFSSL_SMALL -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_2048_sub_18(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 18; i++) { - r[i] = a[i] - b[i]; - } - - return 0; -} - -#endif -#ifdef WOLFSSL_SMALL -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_2048_add_18(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 18; i++) { - r[i] = a[i] + b[i]; - } - - return 0; -} -#endif #ifdef WOLFSSL_SP_DIV_64 static WC_INLINE sp_digit sp_2048_div_word_18(sp_digit d1, sp_digit d0, sp_digit dv) { - sp_digit d, r, t; + sp_digit d; + sp_digit r; + sp_digit t; /* All 57 bits from d1 and top 6 bits from d0. */ d = (d1 << 6) | (d0 >> 51); @@ -1440,24 +1418,28 @@ static WC_INLINE sp_digit sp_2048_div_word_18(sp_digit d1, sp_digit d0, /* Divide d in a and put remainder into r (m*d + r = a) * m is not calculated as it is not needed at this time. * + * Large number of bits in last word. + * * a Number to be divided. * d Number to divide with. * m Multiplier result. * r Remainder from the division. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise. */ -static int sp_2048_div_18(const sp_digit* a, const sp_digit* d, sp_digit* m, - sp_digit* r) +static int sp_2048_div_18(const sp_digit* a, const sp_digit* d, + const sp_digit* m, sp_digit* r) { int i; #ifndef WOLFSSL_SP_DIV_64 int128_t d1; #endif - sp_digit dv, r1; + sp_digit dv; + sp_digit r1; #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* td; #else - sp_digit t1d[36], t2d[18 + 1]; + sp_digit t1d[36]; + sp_digit t2d[18 + 1]; #endif sp_digit* t1; sp_digit* t2; @@ -1485,17 +1467,15 @@ static int sp_2048_div_18(const sp_digit* a, const sp_digit* d, sp_digit* m, dv = d[17]; XMEMCPY(t1, a, sizeof(*t1) * 2U * 18U); for (i=17; i>=0; i--) { - sp_digit hi; t1[18 + i] += t1[18 + i - 1] >> 57; t1[18 + i - 1] &= 0x1ffffffffffffffL; - hi = t1[18 + i] - (t1[18 + i] == dv); #ifndef WOLFSSL_SP_DIV_64 - d1 = hi; + d1 = t1[18 + i]; d1 <<= 57; d1 += t1[18 + i - 1]; r1 = (sp_digit)(d1 / dv); #else - r1 = sp_2048_div_word_18(hi, t1[18 + i - 1], dv); + r1 = sp_2048_div_word_18(t1[18 + i], t1[18 + i - 1], dv); #endif sp_2048_mul_d_18(t2, d, r1); @@ -1516,7 +1496,7 @@ static int sp_2048_div_18(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_2048_mul_d_18(t2, d, r1); (void)sp_2048_sub_18(t1, t1, t2); - XMEMCPY(r, t1, sizeof(*r) * 2U * 18U); + XMEMCPY(r, t1, sizeof(*r) * 36U); for (i=0; i<17; i++) { r[i+1] += r[i] >> 57; r[i] &= 0x1ffffffffffffffL; @@ -1569,7 +1549,8 @@ static int sp_2048_mod_exp_18(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if !defined(WOLFSSL_SP_NO_MALLOC) @@ -1660,7 +1641,8 @@ static int sp_2048_mod_exp_18(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #ifdef WOLFSSL_SMALL_STACK @@ -1746,12 +1728,13 @@ static int sp_2048_mod_exp_18(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit td[(32 * 36) + 36]; #endif sp_digit* t[32]; - sp_digit* rt; + sp_digit* rt = NULL; sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -1843,7 +1826,7 @@ static int sp_2048_mod_exp_18(sp_digit* r, const sp_digit* a, const sp_digit* e, n <<= 5; c -= 5; XMEMCPY(rt, t[y], sizeof(sp_digit) * 36); - for (; i>=0 || c>=5; ) { + while ((i >= 0) || (c >= 5)) { if (c < 5) { n |= e[i--] << (7 - c); c += 57; @@ -1878,7 +1861,7 @@ static int sp_2048_mod_exp_18(sp_digit* r, const sp_digit* a, const sp_digit* e, #endif } -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ /* r = 2^n mod m where n is the number of bits to reduce by. * Given m must be 2048 bits, just need to subtract. @@ -2086,7 +2069,8 @@ static void sp_2048_mont_shift_36(sp_digit* r, const sp_digit* a) { #ifdef WOLFSSL_SP_SMALL int i; - sp_digit n, s; + sp_digit n; + sp_digit s; s = a[36]; n = a[35] >> 53; @@ -2099,7 +2083,8 @@ static void sp_2048_mont_shift_36(sp_digit* r, const sp_digit* a) n += s << 4; r[35] = n; #else - sp_digit n, s; + sp_digit n; + sp_digit s; int i; s = a[36]; n = a[35] >> 53; @@ -2145,7 +2130,7 @@ static void sp_2048_mont_reduce_36(sp_digit* a, const sp_digit* m, sp_digit mp) sp_2048_norm_36(a + 36); -#ifdef WOLFSSL_HAVE_SP_DH +#ifdef WOLFSSL_SP_DH if (mp != 1) { for (i=0; i<35; i++) { mu = (a[i] * mp) & 0x1ffffffffffffffL; @@ -2179,7 +2164,6 @@ static void sp_2048_mont_reduce_36(sp_digit* a, const sp_digit* m, sp_digit mp) a[i+1] += a[i] >> 57; a[i] &= 0x1ffffffffffffffL; #endif - sp_2048_mont_shift_36(a, a); sp_2048_cond_sub_36(a, a, m, 0 - (((a[35] >> 53) > 0) ? (sp_digit)1 : (sp_digit)0)); @@ -2195,8 +2179,8 @@ static void sp_2048_mont_reduce_36(sp_digit* a, const sp_digit* m, sp_digit mp) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_mul_36(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_2048_mont_mul_36(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_2048_mul_36(r, a, b); sp_2048_mont_reduce_36(r, m, mp); @@ -2209,8 +2193,8 @@ static void sp_2048_mont_mul_36(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_sqr_36(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_2048_mont_sqr_36(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_2048_sqr_36(r, a); sp_2048_mont_reduce_36(r, m, mp); @@ -2253,50 +2237,13 @@ static void sp_2048_cond_add_36(sp_digit* r, const sp_digit* a, #endif /* WOLFSSL_SP_SMALL */ } -#ifdef WOLFSSL_SMALL -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_2048_sub_36(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 36; i++) { - r[i] = a[i] - b[i]; - } - - return 0; -} - -#endif -#ifdef WOLFSSL_SMALL -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_2048_add_36(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 36; i++) { - r[i] = a[i] + b[i]; - } - - return 0; -} -#endif #ifdef WOLFSSL_SP_DIV_64 static WC_INLINE sp_digit sp_2048_div_word_36(sp_digit d1, sp_digit d0, sp_digit dv) { - sp_digit d, r, t; + sp_digit d; + sp_digit r; + sp_digit t; /* All 57 bits from d1 and top 6 bits from d0. */ d = (d1 << 6) | (d0 >> 51); @@ -2381,24 +2328,28 @@ static WC_INLINE sp_digit sp_2048_div_word_36(sp_digit d1, sp_digit d0, /* Divide d in a and put remainder into r (m*d + r = a) * m is not calculated as it is not needed at this time. * + * Large number of bits in last word. + * * a Number to be divided. * d Number to divide with. * m Multiplier result. * r Remainder from the division. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise. */ -static int sp_2048_div_36(const sp_digit* a, const sp_digit* d, sp_digit* m, - sp_digit* r) +static int sp_2048_div_36(const sp_digit* a, const sp_digit* d, + const sp_digit* m, sp_digit* r) { int i; #ifndef WOLFSSL_SP_DIV_64 int128_t d1; #endif - sp_digit dv, r1; + sp_digit dv; + sp_digit r1; #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* td; #else - sp_digit t1d[72], t2d[36 + 1]; + sp_digit t1d[72]; + sp_digit t2d[36 + 1]; #endif sp_digit* t1; sp_digit* t2; @@ -2426,17 +2377,15 @@ static int sp_2048_div_36(const sp_digit* a, const sp_digit* d, sp_digit* m, dv = d[35]; XMEMCPY(t1, a, sizeof(*t1) * 2U * 36U); for (i=35; i>=0; i--) { - sp_digit hi; t1[36 + i] += t1[36 + i - 1] >> 57; t1[36 + i - 1] &= 0x1ffffffffffffffL; - hi = t1[36 + i] - (t1[36 + i] == dv); #ifndef WOLFSSL_SP_DIV_64 - d1 = hi; + d1 = t1[36 + i]; d1 <<= 57; d1 += t1[36 + i - 1]; r1 = (sp_digit)(d1 / dv); #else - r1 = sp_2048_div_word_36(hi, t1[36 + i - 1], dv); + r1 = sp_2048_div_word_36(t1[36 + i], t1[36 + i - 1], dv); #endif sp_2048_mul_d_36(t2, d, r1); @@ -2457,7 +2406,7 @@ static int sp_2048_div_36(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_2048_mul_d_36(t2, d, r1); (void)sp_2048_sub_36(t1, t1, t2); - XMEMCPY(r, t1, sizeof(*r) * 2U * 36U); + XMEMCPY(r, t1, sizeof(*r) * 72U); for (i=0; i<35; i++) { r[i+1] += r[i] >> 57; r[i] &= 0x1ffffffffffffffL; @@ -2512,7 +2461,8 @@ static int sp_2048_mod_exp_36(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if !defined(WOLFSSL_SP_NO_MALLOC) @@ -2603,7 +2553,8 @@ static int sp_2048_mod_exp_36(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #ifdef WOLFSSL_SMALL_STACK @@ -2689,12 +2640,13 @@ static int sp_2048_mod_exp_36(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit td[(32 * 72) + 72]; #endif sp_digit* t[32]; - sp_digit* rt; + sp_digit* rt = NULL; sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -2786,7 +2738,7 @@ static int sp_2048_mod_exp_36(sp_digit* r, const sp_digit* a, const sp_digit* e, n <<= 5; c -= 5; XMEMCPY(rt, t[y], sizeof(sp_digit) * 72); - for (; i>=0 || c>=5; ) { + while ((i >= 0) || (c >= 5)) { if (c < 5) { n |= e[i--] << (7 - c); c += 57; @@ -2820,7 +2772,7 @@ static int sp_2048_mod_exp_36(sp_digit* r, const sp_digit* a, const sp_digit* e, return err; #endif } -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) || */ /* WOLFSSL_HAVE_SP_DH */ #ifdef WOLFSSL_HAVE_SP_RSA @@ -2836,15 +2788,15 @@ static int sp_2048_mod_exp_36(sp_digit* r, const sp_digit* a, const sp_digit* e, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPublic_2048(const byte* in, word32 inLen, const mp_int* em, + const mp_int* mm, byte* out, word32* outLen) { #ifdef WOLFSSL_SP_SMALL sp_digit* d = NULL; sp_digit* a = NULL; sp_digit* m = NULL; sp_digit* r = NULL; - sp_digit* norm; + sp_digit* norm = NULL; sp_digit e[1] = {0}; sp_digit mp; int i; @@ -2937,13 +2889,15 @@ int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, return err; #else #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_digit ad[72], md[36], rd[72]; + sp_digit ad[72]; + sp_digit md[36]; + sp_digit rd[72]; #else sp_digit* d = NULL; #endif - sp_digit* a; - sp_digit* m; - sp_digit* r; + sp_digit* a = NULL; + sp_digit* m = NULL; + sp_digit* r = NULL; sp_digit e[1] = {0}; int err = MP_OKAY; @@ -3061,7 +3015,7 @@ int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #ifndef WOLFSSL_RSA_PUBLIC_ONLY #if !defined(SP_RSA_PRIVATE_EXP_D) && !defined(RSA_LOW_MEM) -#endif /* !SP_RSA_PRIVATE_EXP_D && !RSA_LOW_MEM */ +#endif /* !SP_RSA_PRIVATE_EXP_D & !RSA_LOW_MEM */ /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -3079,9 +3033,9 @@ int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_2048(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM) #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -3144,7 +3098,9 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, return err; #else - sp_digit a[72], d[36], m[36]; + sp_digit a[72]; + sp_digit d[36]; + sp_digit m[36]; sp_digit* r = a; int err = MP_OKAY; @@ -3187,19 +3143,19 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, XMEMSET(d, 0, sizeof(sp_digit) * 36); return err; -#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */ +#endif /* WOLFSSL_SP_SMALL | defined(WOLFSSL_SMALL_STACK) */ #else #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* t = NULL; - sp_digit* a; - sp_digit* p; - sp_digit* q; - sp_digit* dp; - sp_digit* dq; - sp_digit* qi; - sp_digit* tmpa; - sp_digit* tmpb; - sp_digit* r; + sp_digit* a = NULL; + sp_digit* p = NULL; + sp_digit* q = NULL; + sp_digit* dp = NULL; + sp_digit* dq = NULL; + sp_digit* qi = NULL; + sp_digit* tmpa = NULL; + sp_digit* tmpb = NULL; + sp_digit* r = NULL; int err = MP_OKAY; (void)dm; @@ -3274,8 +3230,13 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, return err; #else sp_digit a[36 * 2]; - sp_digit p[18], q[18], dp[18], dq[18], qi[18]; - sp_digit tmpa[36], tmpb[36]; + sp_digit p[18]; + sp_digit q[18]; + sp_digit dp[18]; + sp_digit dq[18]; + sp_digit qi[18]; + sp_digit tmpa[36]; + sp_digit tmpb[36]; sp_digit* r = a; int err = MP_OKAY; @@ -3337,8 +3298,8 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, XMEMSET(qi, 0, sizeof(qi)); return err; -#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */ -#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */ +#endif /* WOLFSSL_SP_SMALL | defined(WOLFSSL_SMALL_STACK) */ +#endif /* SP_RSA_PRIVATE_EXP_D | RSA_LOW_MEM */ } #endif /* !WOLFSSL_RSA_PUBLIC_ONLY */ @@ -3361,17 +3322,19 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->used = 36; mp_clamp(r); #elif DIGIT_BIT < 57 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 36; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 57) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -3384,14 +3347,16 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 36; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 57 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -3418,7 +3383,8 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_2048(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { #ifdef WOLFSSL_SP_SMALL int err = MP_OKAY; @@ -3474,7 +3440,9 @@ int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) return err; #else #ifndef WOLFSSL_SMALL_STACK - sp_digit bd[72], ed[36], md[36]; + sp_digit bd[72]; + sp_digit ed[36]; + sp_digit md[36]; #else sp_digit* d = NULL; #endif @@ -3546,7 +3514,8 @@ int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) #ifdef WOLFSSL_HAVE_SP_DH #ifdef HAVE_FFDHE_2048 -SP_NOINLINE static void sp_2048_lshift_36(sp_digit* r, sp_digit* a, byte n) +SP_NOINLINE static void sp_2048_lshift_36(sp_digit* r, const sp_digit* a, + byte n) { #ifdef WOLFSSL_SP_SMALL int i; @@ -3556,7 +3525,8 @@ SP_NOINLINE static void sp_2048_lshift_36(sp_digit* r, sp_digit* a, byte n) r[i] = ((a[i] << n) | (a[i-1] >> (57 - n))) & 0x1ffffffffffffffL; } #else - sp_int_digit s, t; + sp_int_digit s; + sp_int_digit t; s = (sp_int_digit)a[35]; r[36] = s >> (57U - n); @@ -3652,9 +3622,11 @@ static int sp_2048_mod_exp_2_36(sp_digit* r, const sp_digit* e, int bits, const sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -3699,7 +3671,7 @@ static int sp_2048_mod_exp_2_36(sp_digit* r, const sp_digit* e, int bits, const n <<= 5; c -= 5; sp_2048_lshift_36(r, norm, (byte)y); - for (; i>=0 || c>=5; ) { + while ((i >= 0) || (c >= 5)) { if (c < 5) { n |= e[i--] << (7 - c); c += 57; @@ -3754,8 +3726,8 @@ static int sp_2048_mod_exp_2_36(sp_digit* r, const sp_digit* e, int bits, const * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, - mp_int* mod, byte* out, word32* outLen) +int sp_DhExp_2048(const mp_int* base, const byte* exp, word32 expLen, + const mp_int* mod, byte* out, word32* outLen) { #ifdef WOLFSSL_SP_SMALL int err = MP_OKAY; @@ -3822,7 +3794,9 @@ int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, return err; #else #ifndef WOLFSSL_SMALL_STACK - sp_digit bd[72], ed[36], md[36]; + sp_digit bd[72]; + sp_digit ed[36]; + sp_digit md[36]; #else sp_digit* d = NULL; #endif @@ -3887,6 +3861,7 @@ int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, sp_2048_to_bin(r, out); *outLen = 256; for (i=0; i<256U && out[i] == 0U; i++) { + /* Search for first non-zero. */ } *outLen -= i; XMEMMOVE(out, out + i, *outLen); @@ -3915,7 +3890,8 @@ int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_1024(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { #ifdef WOLFSSL_SP_SMALL int err = MP_OKAY; @@ -3972,7 +3948,9 @@ int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) return err; #else #ifndef WOLFSSL_SMALL_STACK - sp_digit bd[36], ed[18], md[18]; + sp_digit bd[36]; + sp_digit ed[18]; + sp_digit md[18]; #else sp_digit* d = NULL; #endif @@ -4042,7 +4020,7 @@ int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) #endif } -#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */ +#endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */ #endif /* !WOLFSSL_SP_NO_2048 */ @@ -4056,7 +4034,8 @@ int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) */ static void sp_3072_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -4098,7 +4077,8 @@ static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 57 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -4132,7 +4112,9 @@ static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -4171,7 +4153,10 @@ static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a) */ static void sp_3072_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; for (i=0; i<53; i++) { r[i+1] += r[i] >> 57; @@ -4773,7 +4758,9 @@ SP_NOINLINE static int sp_3072_sub_54(sp_digit* r, const sp_digit* a, SP_NOINLINE static void sp_3072_mul_54(sp_digit* r, const sp_digit* a, const sp_digit* b) { - int i, j, k; + int i; + int j; + int k; int128_t c; c = ((int128_t)a[53]) * b[53]; @@ -4805,7 +4792,9 @@ SP_NOINLINE static void sp_3072_mul_54(sp_digit* r, const sp_digit* a, */ SP_NOINLINE static void sp_3072_sqr_54(sp_digit* r, const sp_digit* a) { - int i, j, k; + int i; + int j; + int k; int128_t c; c = ((int128_t)a[53]) * a[53]; @@ -4943,7 +4932,9 @@ SP_NOINLINE static int sp_3072_sub_27(sp_digit* r, const sp_digit* a, SP_NOINLINE static void sp_3072_mul_27(sp_digit* r, const sp_digit* a, const sp_digit* b) { - int i, j, k; + int i; + int j; + int k; int128_t c; c = ((int128_t)a[26]) * b[26]; @@ -4978,7 +4969,8 @@ SP_NOINLINE static void sp_3072_mul_27(sp_digit* r, const sp_digit* a, SP_NOINLINE static void sp_3072_mul_27(sp_digit* r, const sp_digit* a, const sp_digit* b) { - int i, j; + int i; + int j; int128_t t[54]; XMEMSET(t, 0, sizeof(t)); @@ -5003,7 +4995,9 @@ SP_NOINLINE static void sp_3072_mul_27(sp_digit* r, const sp_digit* a, */ SP_NOINLINE static void sp_3072_sqr_27(sp_digit* r, const sp_digit* a) { - int i, j, k; + int i; + int j; + int k; int128_t c; c = ((int128_t)a[26]) * a[26]; @@ -5040,7 +5034,8 @@ SP_NOINLINE static void sp_3072_sqr_27(sp_digit* r, const sp_digit* a) */ SP_NOINLINE static void sp_3072_sqr_27(sp_digit* r, const sp_digit* a) { - int i, j; + int i; + int j; int128_t t[54]; XMEMSET(t, 0, sizeof(t)); @@ -5058,7 +5053,7 @@ SP_NOINLINE static void sp_3072_sqr_27(sp_digit* r, const sp_digit* a) } #endif /* WOLFSSL_SP_SMALL */ -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ /* Caclulate the bottom digit of -1/a mod 2^n. * @@ -5067,7 +5062,8 @@ SP_NOINLINE static void sp_3072_sqr_27(sp_digit* r, const sp_digit* a) */ static void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho) { - sp_digit x, b; + sp_digit x; + sp_digit b; b = a[0]; x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ @@ -5342,7 +5338,8 @@ static void sp_3072_mont_shift_27(sp_digit* r, const sp_digit* a) { #ifdef WOLFSSL_SP_SMALL int i; - sp_digit n, s; + sp_digit n; + sp_digit s; s = a[27]; n = a[26] >> 54; @@ -5355,7 +5352,8 @@ static void sp_3072_mont_shift_27(sp_digit* r, const sp_digit* a) n += s << 3; r[26] = n; #else - sp_digit n, s; + sp_digit n; + sp_digit s; int i; s = a[27]; n = a[26] >> 54; @@ -5408,7 +5406,6 @@ static void sp_3072_mont_reduce_27(sp_digit* a, const sp_digit* m, sp_digit mp) sp_3072_mul_add_27(a+i, m, mu); a[i+1] += a[i] >> 57; a[i] &= 0x1ffffffffffffffL; - sp_3072_mont_shift_27(a, a); sp_3072_cond_sub_27(a, a, m, 0 - (((a[26] >> 54) > 0) ? (sp_digit)1 : (sp_digit)0)); @@ -5424,8 +5421,8 @@ static void sp_3072_mont_reduce_27(sp_digit* a, const sp_digit* m, sp_digit mp) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_mul_27(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_3072_mont_mul_27(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_3072_mul_27(r, a, b); sp_3072_mont_reduce_27(r, m, mp); @@ -5438,8 +5435,8 @@ static void sp_3072_mont_mul_27(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_sqr_27(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_3072_mont_sqr_27(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_3072_sqr_27(r, a); sp_3072_mont_reduce_27(r, m, mp); @@ -5547,7 +5544,9 @@ static void sp_3072_cond_add_27(sp_digit* r, const sp_digit* a, static WC_INLINE sp_digit sp_3072_div_word_27(sp_digit d1, sp_digit d0, sp_digit dv) { - sp_digit d, r, t; + sp_digit d; + sp_digit r; + sp_digit t; /* All 57 bits from d1 and top 6 bits from d0. */ d = (d1 << 6) | (d0 >> 51); @@ -5632,24 +5631,28 @@ static WC_INLINE sp_digit sp_3072_div_word_27(sp_digit d1, sp_digit d0, /* Divide d in a and put remainder into r (m*d + r = a) * m is not calculated as it is not needed at this time. * + * Large number of bits in last word. + * * a Number to be divided. * d Number to divide with. * m Multiplier result. * r Remainder from the division. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise. */ -static int sp_3072_div_27(const sp_digit* a, const sp_digit* d, sp_digit* m, - sp_digit* r) +static int sp_3072_div_27(const sp_digit* a, const sp_digit* d, + const sp_digit* m, sp_digit* r) { int i; #ifndef WOLFSSL_SP_DIV_64 int128_t d1; #endif - sp_digit dv, r1; + sp_digit dv; + sp_digit r1; #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* td; #else - sp_digit t1d[54], t2d[27 + 1]; + sp_digit t1d[54]; + sp_digit t2d[27 + 1]; #endif sp_digit* t1; sp_digit* t2; @@ -5677,17 +5680,15 @@ static int sp_3072_div_27(const sp_digit* a, const sp_digit* d, sp_digit* m, dv = d[26]; XMEMCPY(t1, a, sizeof(*t1) * 2U * 27U); for (i=26; i>=0; i--) { - sp_digit hi; t1[27 + i] += t1[27 + i - 1] >> 57; t1[27 + i - 1] &= 0x1ffffffffffffffL; - hi = t1[27 + i] - (t1[27 + i] == dv); #ifndef WOLFSSL_SP_DIV_64 - d1 = hi; + d1 = t1[27 + i]; d1 <<= 57; d1 += t1[27 + i - 1]; r1 = (sp_digit)(d1 / dv); #else - r1 = sp_3072_div_word_27(hi, t1[27 + i - 1], dv); + r1 = sp_3072_div_word_27(t1[27 + i], t1[27 + i - 1], dv); #endif sp_3072_mul_d_27(t2, d, r1); @@ -5708,7 +5709,7 @@ static int sp_3072_div_27(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_3072_mul_d_27(t2, d, r1); (void)sp_3072_sub_27(t1, t1, t2); - XMEMCPY(r, t1, sizeof(*r) * 2U * 27U); + XMEMCPY(r, t1, sizeof(*r) * 54U); for (i=0; i<26; i++) { r[i+1] += r[i] >> 57; r[i] &= 0x1ffffffffffffffL; @@ -5761,7 +5762,8 @@ static int sp_3072_mod_exp_27(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if !defined(WOLFSSL_SP_NO_MALLOC) @@ -5852,7 +5854,8 @@ static int sp_3072_mod_exp_27(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #ifdef WOLFSSL_SMALL_STACK @@ -5938,12 +5941,13 @@ static int sp_3072_mod_exp_27(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit td[(32 * 54) + 54]; #endif sp_digit* t[32]; - sp_digit* rt; + sp_digit* rt = NULL; sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -6035,7 +6039,7 @@ static int sp_3072_mod_exp_27(sp_digit* r, const sp_digit* a, const sp_digit* e, n <<= 5; c -= 5; XMEMCPY(rt, t[y], sizeof(sp_digit) * 54); - for (; i>=0 || c>=5; ) { + while ((i >= 0) || (c >= 5)) { if (c < 5) { n |= e[i--] << (7 - c); c += 57; @@ -6070,7 +6074,7 @@ static int sp_3072_mod_exp_27(sp_digit* r, const sp_digit* a, const sp_digit* e, #endif } -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ /* r = 2^n mod m where n is the number of bits to reduce by. * Given m must be 3072 bits, just need to subtract. @@ -6342,7 +6346,7 @@ static void sp_3072_mont_reduce_54(sp_digit* a, const sp_digit* m, sp_digit mp) sp_3072_norm_54(a + 54); -#ifdef WOLFSSL_HAVE_SP_DH +#ifdef WOLFSSL_SP_DH if (mp != 1) { for (i=0; i<53; i++) { mu = (a[i] * mp) & 0x1ffffffffffffffL; @@ -6376,7 +6380,6 @@ static void sp_3072_mont_reduce_54(sp_digit* a, const sp_digit* m, sp_digit mp) a[i+1] += a[i] >> 57; a[i] &= 0x1ffffffffffffffL; #endif - sp_3072_mont_shift_54(a, a); sp_3072_cond_sub_54(a, a, m, 0 - (((a[53] >> 51) > 0) ? (sp_digit)1 : (sp_digit)0)); @@ -6392,8 +6395,8 @@ static void sp_3072_mont_reduce_54(sp_digit* a, const sp_digit* m, sp_digit mp) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_mul_54(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_3072_mont_mul_54(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_3072_mul_54(r, a, b); sp_3072_mont_reduce_54(r, m, mp); @@ -6406,8 +6409,8 @@ static void sp_3072_mont_mul_54(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_sqr_54(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_3072_mont_sqr_54(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_3072_sqr_54(r, a); sp_3072_mont_reduce_54(r, m, mp); @@ -6456,7 +6459,9 @@ static void sp_3072_cond_add_54(sp_digit* r, const sp_digit* a, static WC_INLINE sp_digit sp_3072_div_word_54(sp_digit d1, sp_digit d0, sp_digit dv) { - sp_digit d, r, t; + sp_digit d; + sp_digit r; + sp_digit t; /* All 57 bits from d1 and top 6 bits from d0. */ d = (d1 << 6) | (d0 >> 51); @@ -6541,24 +6546,28 @@ static WC_INLINE sp_digit sp_3072_div_word_54(sp_digit d1, sp_digit d0, /* Divide d in a and put remainder into r (m*d + r = a) * m is not calculated as it is not needed at this time. * + * Large number of bits in last word. + * * a Number to be divided. * d Number to divide with. * m Multiplier result. * r Remainder from the division. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise. */ -static int sp_3072_div_54(const sp_digit* a, const sp_digit* d, sp_digit* m, - sp_digit* r) +static int sp_3072_div_54(const sp_digit* a, const sp_digit* d, + const sp_digit* m, sp_digit* r) { int i; #ifndef WOLFSSL_SP_DIV_64 int128_t d1; #endif - sp_digit dv, r1; + sp_digit dv; + sp_digit r1; #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* td; #else - sp_digit t1d[108], t2d[54 + 1]; + sp_digit t1d[108]; + sp_digit t2d[54 + 1]; #endif sp_digit* t1; sp_digit* t2; @@ -6586,17 +6595,15 @@ static int sp_3072_div_54(const sp_digit* a, const sp_digit* d, sp_digit* m, dv = d[53]; XMEMCPY(t1, a, sizeof(*t1) * 2U * 54U); for (i=53; i>=0; i--) { - sp_digit hi; t1[54 + i] += t1[54 + i - 1] >> 57; t1[54 + i - 1] &= 0x1ffffffffffffffL; - hi = t1[54 + i] - (t1[54 + i] == dv); #ifndef WOLFSSL_SP_DIV_64 - d1 = hi; + d1 = t1[54 + i]; d1 <<= 57; d1 += t1[54 + i - 1]; r1 = (sp_digit)(d1 / dv); #else - r1 = sp_3072_div_word_54(hi, t1[54 + i - 1], dv); + r1 = sp_3072_div_word_54(t1[54 + i], t1[54 + i - 1], dv); #endif sp_3072_mul_d_54(t2, d, r1); @@ -6617,7 +6624,7 @@ static int sp_3072_div_54(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_3072_mul_d_54(t2, d, r1); (void)sp_3072_sub_54(t1, t1, t2); - XMEMCPY(r, t1, sizeof(*r) * 2U * 54U); + XMEMCPY(r, t1, sizeof(*r) * 108U); for (i=0; i<53; i++) { r[i+1] += r[i] >> 57; r[i] &= 0x1ffffffffffffffL; @@ -6672,7 +6679,8 @@ static int sp_3072_mod_exp_54(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if !defined(WOLFSSL_SP_NO_MALLOC) @@ -6763,7 +6771,8 @@ static int sp_3072_mod_exp_54(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #ifdef WOLFSSL_SMALL_STACK @@ -6849,12 +6858,13 @@ static int sp_3072_mod_exp_54(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit td[(32 * 108) + 108]; #endif sp_digit* t[32]; - sp_digit* rt; + sp_digit* rt = NULL; sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -6946,7 +6956,7 @@ static int sp_3072_mod_exp_54(sp_digit* r, const sp_digit* a, const sp_digit* e, n <<= 5; c -= 5; XMEMCPY(rt, t[y], sizeof(sp_digit) * 108); - for (; i>=0 || c>=5; ) { + while ((i >= 0) || (c >= 5)) { if (c < 5) { n |= e[i--] << (7 - c); c += 57; @@ -6980,7 +6990,7 @@ static int sp_3072_mod_exp_54(sp_digit* r, const sp_digit* a, const sp_digit* e, return err; #endif } -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) || */ /* WOLFSSL_HAVE_SP_DH */ #ifdef WOLFSSL_HAVE_SP_RSA @@ -6996,15 +7006,15 @@ static int sp_3072_mod_exp_54(sp_digit* r, const sp_digit* a, const sp_digit* e, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPublic_3072(const byte* in, word32 inLen, const mp_int* em, + const mp_int* mm, byte* out, word32* outLen) { #ifdef WOLFSSL_SP_SMALL sp_digit* d = NULL; sp_digit* a = NULL; sp_digit* m = NULL; sp_digit* r = NULL; - sp_digit* norm; + sp_digit* norm = NULL; sp_digit e[1] = {0}; sp_digit mp; int i; @@ -7097,13 +7107,15 @@ int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, return err; #else #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_digit ad[108], md[54], rd[108]; + sp_digit ad[108]; + sp_digit md[54]; + sp_digit rd[108]; #else sp_digit* d = NULL; #endif - sp_digit* a; - sp_digit* m; - sp_digit* r; + sp_digit* a = NULL; + sp_digit* m = NULL; + sp_digit* r = NULL; sp_digit e[1] = {0}; int err = MP_OKAY; @@ -7221,7 +7233,7 @@ int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #ifndef WOLFSSL_RSA_PUBLIC_ONLY #if !defined(SP_RSA_PRIVATE_EXP_D) && !defined(RSA_LOW_MEM) -#endif /* !SP_RSA_PRIVATE_EXP_D && !RSA_LOW_MEM */ +#endif /* !SP_RSA_PRIVATE_EXP_D & !RSA_LOW_MEM */ /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -7239,9 +7251,9 @@ int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_3072(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM) #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -7304,7 +7316,9 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, return err; #else - sp_digit a[108], d[54], m[54]; + sp_digit a[108]; + sp_digit d[54]; + sp_digit m[54]; sp_digit* r = a; int err = MP_OKAY; @@ -7347,19 +7361,19 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, XMEMSET(d, 0, sizeof(sp_digit) * 54); return err; -#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */ +#endif /* WOLFSSL_SP_SMALL | defined(WOLFSSL_SMALL_STACK) */ #else #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* t = NULL; - sp_digit* a; - sp_digit* p; - sp_digit* q; - sp_digit* dp; - sp_digit* dq; - sp_digit* qi; - sp_digit* tmpa; - sp_digit* tmpb; - sp_digit* r; + sp_digit* a = NULL; + sp_digit* p = NULL; + sp_digit* q = NULL; + sp_digit* dp = NULL; + sp_digit* dq = NULL; + sp_digit* qi = NULL; + sp_digit* tmpa = NULL; + sp_digit* tmpb = NULL; + sp_digit* r = NULL; int err = MP_OKAY; (void)dm; @@ -7434,8 +7448,13 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, return err; #else sp_digit a[54 * 2]; - sp_digit p[27], q[27], dp[27], dq[27], qi[27]; - sp_digit tmpa[54], tmpb[54]; + sp_digit p[27]; + sp_digit q[27]; + sp_digit dp[27]; + sp_digit dq[27]; + sp_digit qi[27]; + sp_digit tmpa[54]; + sp_digit tmpb[54]; sp_digit* r = a; int err = MP_OKAY; @@ -7497,8 +7516,8 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, XMEMSET(qi, 0, sizeof(qi)); return err; -#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */ -#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */ +#endif /* WOLFSSL_SP_SMALL | defined(WOLFSSL_SMALL_STACK) */ +#endif /* SP_RSA_PRIVATE_EXP_D | RSA_LOW_MEM */ } #endif /* !WOLFSSL_RSA_PUBLIC_ONLY */ @@ -7521,17 +7540,19 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->used = 54; mp_clamp(r); #elif DIGIT_BIT < 57 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 54; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 57) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -7544,14 +7565,16 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 54; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 57 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -7578,7 +7601,8 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_3072(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { #ifdef WOLFSSL_SP_SMALL int err = MP_OKAY; @@ -7634,7 +7658,9 @@ int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) return err; #else #ifndef WOLFSSL_SMALL_STACK - sp_digit bd[108], ed[54], md[54]; + sp_digit bd[108]; + sp_digit ed[54]; + sp_digit md[54]; #else sp_digit* d = NULL; #endif @@ -7706,7 +7732,8 @@ int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) #ifdef WOLFSSL_HAVE_SP_DH #ifdef HAVE_FFDHE_3072 -SP_NOINLINE static void sp_3072_lshift_54(sp_digit* r, sp_digit* a, byte n) +SP_NOINLINE static void sp_3072_lshift_54(sp_digit* r, const sp_digit* a, + byte n) { #ifdef WOLFSSL_SP_SMALL int i; @@ -7716,7 +7743,8 @@ SP_NOINLINE static void sp_3072_lshift_54(sp_digit* r, sp_digit* a, byte n) r[i] = ((a[i] << n) | (a[i-1] >> (57 - n))) & 0x1ffffffffffffffL; } #else - sp_int_digit s, t; + sp_int_digit s; + sp_int_digit t; s = (sp_int_digit)a[53]; r[54] = s >> (57U - n); @@ -7848,9 +7876,11 @@ static int sp_3072_mod_exp_2_54(sp_digit* r, const sp_digit* e, int bits, const sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -7895,7 +7925,7 @@ static int sp_3072_mod_exp_2_54(sp_digit* r, const sp_digit* e, int bits, const n <<= 5; c -= 5; sp_3072_lshift_54(r, norm, (byte)y); - for (; i>=0 || c>=5; ) { + while ((i >= 0) || (c >= 5)) { if (c < 5) { n |= e[i--] << (7 - c); c += 57; @@ -7950,8 +7980,8 @@ static int sp_3072_mod_exp_2_54(sp_digit* r, const sp_digit* e, int bits, const * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, - mp_int* mod, byte* out, word32* outLen) +int sp_DhExp_3072(const mp_int* base, const byte* exp, word32 expLen, + const mp_int* mod, byte* out, word32* outLen) { #ifdef WOLFSSL_SP_SMALL int err = MP_OKAY; @@ -8018,7 +8048,9 @@ int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, return err; #else #ifndef WOLFSSL_SMALL_STACK - sp_digit bd[108], ed[54], md[54]; + sp_digit bd[108]; + sp_digit ed[54]; + sp_digit md[54]; #else sp_digit* d = NULL; #endif @@ -8083,6 +8115,7 @@ int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, sp_3072_to_bin(r, out); *outLen = 384; for (i=0; i<384U && out[i] == 0U; i++) { + /* Search for first non-zero. */ } *outLen -= i; XMEMMOVE(out, out + i, *outLen); @@ -8111,7 +8144,8 @@ int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_1536(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { #ifdef WOLFSSL_SP_SMALL int err = MP_OKAY; @@ -8168,7 +8202,9 @@ int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) return err; #else #ifndef WOLFSSL_SMALL_STACK - sp_digit bd[54], ed[27], md[27]; + sp_digit bd[54]; + sp_digit ed[27]; + sp_digit md[27]; #else sp_digit* d = NULL; #endif @@ -8238,7 +8274,7 @@ int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) #endif } -#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */ +#endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */ #endif /* !WOLFSSL_SP_NO_3072 */ @@ -8252,7 +8288,8 @@ int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) */ static void sp_4096_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -8294,7 +8331,8 @@ static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 53 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -8328,7 +8366,9 @@ static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -8367,7 +8407,10 @@ static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a) */ static void sp_4096_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; for (i=0; i<77; i++) { r[i+1] += r[i] >> 53; @@ -9095,7 +9138,9 @@ SP_NOINLINE static int sp_4096_sub_78(sp_digit* r, const sp_digit* a, SP_NOINLINE static void sp_4096_mul_78(sp_digit* r, const sp_digit* a, const sp_digit* b) { - int i, j, k; + int i; + int j; + int k; int128_t c; c = ((int128_t)a[77]) * b[77]; @@ -9127,7 +9172,9 @@ SP_NOINLINE static void sp_4096_mul_78(sp_digit* r, const sp_digit* a, */ SP_NOINLINE static void sp_4096_sqr_78(sp_digit* r, const sp_digit* a) { - int i, j, k; + int i; + int j; + int k; int128_t c; c = ((int128_t)a[77]) * a[77]; @@ -9241,7 +9288,9 @@ SP_NOINLINE static int sp_4096_sub_39(sp_digit* r, const sp_digit* a, SP_NOINLINE static void sp_4096_mul_39(sp_digit* r, const sp_digit* a, const sp_digit* b) { - int i, j, k; + int i; + int j; + int k; int128_t c; c = ((int128_t)a[38]) * b[38]; @@ -9273,7 +9322,9 @@ SP_NOINLINE static void sp_4096_mul_39(sp_digit* r, const sp_digit* a, */ SP_NOINLINE static void sp_4096_sqr_39(sp_digit* r, const sp_digit* a) { - int i, j, k; + int i; + int j; + int k; int128_t c; c = ((int128_t)a[38]) * a[38]; @@ -9303,8 +9354,8 @@ SP_NOINLINE static void sp_4096_sqr_39(sp_digit* r, const sp_digit* a) } #endif /* WOLFSSL_SP_SMALL */ -#endif /* WOLFSSL_HAVE_SP_RSA && !SP_RSA_PRIVATE_EXP_D */ -#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */ +#endif /* WOLFSSL_HAVE_SP_RSA & !SP_RSA_PRIVATE_EXP_D */ +#endif /* (WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH) & !WOLFSSL_RSA_PUBLIC_ONLY */ /* Caclulate the bottom digit of -1/a mod 2^n. * @@ -9313,7 +9364,8 @@ SP_NOINLINE static void sp_4096_sqr_39(sp_digit* r, const sp_digit* a) */ static void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho) { - sp_digit x, b; + sp_digit x; + sp_digit b; b = a[0]; x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ @@ -9673,7 +9725,6 @@ static void sp_4096_mont_reduce_39(sp_digit* a, const sp_digit* m, sp_digit mp) sp_4096_mul_add_39(a+i, m, mu); a[i+1] += a[i] >> 53; a[i] &= 0x1fffffffffffffL; - sp_4096_mont_shift_39(a, a); sp_4096_cond_sub_39(a, a, m, 0 - (((a[38] >> 34) > 0) ? (sp_digit)1 : (sp_digit)0)); @@ -9689,8 +9740,8 @@ static void sp_4096_mont_reduce_39(sp_digit* a, const sp_digit* m, sp_digit mp) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_4096_mont_mul_39(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_4096_mont_mul_39(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_4096_mul_39(r, a, b); sp_4096_mont_reduce_39(r, m, mp); @@ -9703,8 +9754,8 @@ static void sp_4096_mont_mul_39(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_4096_mont_sqr_39(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_4096_mont_sqr_39(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_4096_sqr_39(r, a); sp_4096_mont_reduce_39(r, m, mp); @@ -9812,26 +9863,8 @@ static void sp_4096_cond_add_39(sp_digit* r, const sp_digit* a, #endif /* WOLFSSL_SP_SMALL */ } -#ifdef WOLFSSL_SMALL -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_4096_add_39(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 39; i++) { - r[i] = a[i] + b[i]; - } - - return 0; -} -#endif -SP_NOINLINE static void sp_4096_rshift_39(sp_digit* r, sp_digit* a, byte n) +SP_NOINLINE static void sp_4096_rshift_39(sp_digit* r, const sp_digit* a, + byte n) { int i; @@ -9841,21 +9874,21 @@ SP_NOINLINE static void sp_4096_rshift_39(sp_digit* r, sp_digit* a, byte n) } #else for (i=0; i<32; i += 8) { - r[i+0] = ((a[i+0] >> n) | (a[i+1] << (53 - n))) & 0x1fffffffffffffL; - r[i+1] = ((a[i+1] >> n) | (a[i+2] << (53 - n))) & 0x1fffffffffffffL; - r[i+2] = ((a[i+2] >> n) | (a[i+3] << (53 - n))) & 0x1fffffffffffffL; - r[i+3] = ((a[i+3] >> n) | (a[i+4] << (53 - n))) & 0x1fffffffffffffL; - r[i+4] = ((a[i+4] >> n) | (a[i+5] << (53 - n))) & 0x1fffffffffffffL; - r[i+5] = ((a[i+5] >> n) | (a[i+6] << (53 - n))) & 0x1fffffffffffffL; - r[i+6] = ((a[i+6] >> n) | (a[i+7] << (53 - n))) & 0x1fffffffffffffL; - r[i+7] = ((a[i+7] >> n) | (a[i+8] << (53 - n))) & 0x1fffffffffffffL; + r[i+0] = (a[i+0] >> n) | ((a[i+1] << (53 - n)) & 0x1fffffffffffffL); + r[i+1] = (a[i+1] >> n) | ((a[i+2] << (53 - n)) & 0x1fffffffffffffL); + r[i+2] = (a[i+2] >> n) | ((a[i+3] << (53 - n)) & 0x1fffffffffffffL); + r[i+3] = (a[i+3] >> n) | ((a[i+4] << (53 - n)) & 0x1fffffffffffffL); + r[i+4] = (a[i+4] >> n) | ((a[i+5] << (53 - n)) & 0x1fffffffffffffL); + r[i+5] = (a[i+5] >> n) | ((a[i+6] << (53 - n)) & 0x1fffffffffffffL); + r[i+6] = (a[i+6] >> n) | ((a[i+7] << (53 - n)) & 0x1fffffffffffffL); + r[i+7] = (a[i+7] >> n) | ((a[i+8] << (53 - n)) & 0x1fffffffffffffL); } - r[32] = ((a[32] >> n) | (a[33] << (53 - n))) & 0x1fffffffffffffL; - r[33] = ((a[33] >> n) | (a[34] << (53 - n))) & 0x1fffffffffffffL; - r[34] = ((a[34] >> n) | (a[35] << (53 - n))) & 0x1fffffffffffffL; - r[35] = ((a[35] >> n) | (a[36] << (53 - n))) & 0x1fffffffffffffL; - r[36] = ((a[36] >> n) | (a[37] << (53 - n))) & 0x1fffffffffffffL; - r[37] = ((a[37] >> n) | (a[38] << (53 - n))) & 0x1fffffffffffffL; + r[32] = (a[32] >> n) | ((a[33] << (53 - n)) & 0x1fffffffffffffL); + r[33] = (a[33] >> n) | ((a[34] << (53 - n)) & 0x1fffffffffffffL); + r[34] = (a[34] >> n) | ((a[35] << (53 - n)) & 0x1fffffffffffffL); + r[35] = (a[35] >> n) | ((a[36] << (53 - n)) & 0x1fffffffffffffL); + r[36] = (a[36] >> n) | ((a[37] << (53 - n)) & 0x1fffffffffffffL); + r[37] = (a[37] >> n) | ((a[38] << (53 - n)) & 0x1fffffffffffffL); #endif r[38] = a[38] >> n; } @@ -9864,7 +9897,9 @@ SP_NOINLINE static void sp_4096_rshift_39(sp_digit* r, sp_digit* a, byte n) static WC_INLINE sp_digit sp_4096_div_word_39(sp_digit d1, sp_digit d0, sp_digit dv) { - sp_digit d, r, t; + sp_digit d; + sp_digit r; + sp_digit t; /* All 53 bits from d1 and top 10 bits from d0. */ d = (d1 << 10) | (d0 >> 43); @@ -9917,24 +9952,29 @@ static WC_INLINE sp_digit sp_4096_div_word_39(sp_digit d1, sp_digit d0, /* Divide d in a and put remainder into r (m*d + r = a) * m is not calculated as it is not needed at this time. * + * Full implementation. + * * a Number to be divided. * d Number to divide with. * m Multiplier result. * r Remainder from the division. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise. */ -static int sp_4096_div_39(const sp_digit* a, const sp_digit* d, sp_digit* m, - sp_digit* r) +static int sp_4096_div_39(const sp_digit* a, const sp_digit* d, + const sp_digit* m, sp_digit* r) { int i; #ifndef WOLFSSL_SP_DIV_64 int128_t d1; #endif - sp_digit dv, r1; + sp_digit dv; + sp_digit r1; #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* td; #else - sp_digit t1d[78 + 1], t2d[39 + 1], sdd[39 + 1]; + sp_digit t1d[78 + 1]; + sp_digit t2d[39 + 1]; + sp_digit sdd[39 + 1]; #endif sp_digit* t1; sp_digit* t2; @@ -9967,18 +10007,16 @@ static int sp_4096_div_39(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_4096_mul_d_39(sd, d, 1L << 19); sp_4096_mul_d_78(t1, a, 1L << 19); dv = sd[38]; + t1[39 + 39] += t1[39 + 39 - 1] >> 53; + t1[39 + 39 - 1] &= 0x1fffffffffffffL; for (i=39; i>=0; i--) { - sp_digit hi; - t1[39 + i] += t1[39 + i - 1] >> 53; - t1[39 + i - 1] &= 0x1fffffffffffffL; - hi = t1[39 + i] - (t1[39 + i] == dv); #ifndef WOLFSSL_SP_DIV_64 - d1 = hi; + d1 = t1[39 + i]; d1 <<= 53; d1 += t1[39 + i - 1]; r1 = (sp_digit)(d1 / dv); #else - r1 = sp_4096_div_word_39(hi, t1[39 + i - 1], dv); + r1 = sp_4096_div_word_39(t1[39 + i], t1[39 + i - 1], dv); #endif sp_4096_mul_d_39(t2, sd, r1); @@ -9999,7 +10037,7 @@ static int sp_4096_div_39(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_4096_mul_d_39(t2, sd, r1); sp_4096_sub_39(t1, t1, t2); - XMEMCPY(r, t1, sizeof(*r) * 2U * 39U); + XMEMCPY(r, t1, sizeof(*r) * 78U); for (i=0; i<38; i++) { r[i+1] += r[i] >> 53; r[i] &= 0x1fffffffffffffL; @@ -10055,7 +10093,8 @@ static int sp_4096_mod_exp_39(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if !defined(WOLFSSL_SP_NO_MALLOC) @@ -10146,7 +10185,8 @@ static int sp_4096_mod_exp_39(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #ifdef WOLFSSL_SMALL_STACK @@ -10232,12 +10272,13 @@ static int sp_4096_mod_exp_39(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit td[(32 * 78) + 78]; #endif sp_digit* t[32]; - sp_digit* rt; + sp_digit* rt = NULL; sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -10329,7 +10370,7 @@ static int sp_4096_mod_exp_39(sp_digit* r, const sp_digit* a, const sp_digit* e, n <<= 5; c -= 5; XMEMCPY(rt, t[y], sizeof(sp_digit) * 78); - for (; i>=0 || c>=5; ) { + while ((i >= 0) || (c >= 5)) { if (c < 5) { n |= e[i--] << (11 - c); c += 53; @@ -10364,8 +10405,8 @@ static int sp_4096_mod_exp_39(sp_digit* r, const sp_digit* a, const sp_digit* e, #endif } -#endif /* WOLFSSL_HAVE_SP_RSA && !SP_RSA_PRIVATE_EXP_D */ -#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */ +#endif /* WOLFSSL_HAVE_SP_RSA & !SP_RSA_PRIVATE_EXP_D */ +#endif /* (WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH) & !WOLFSSL_RSA_PUBLIC_ONLY */ /* r = 2^n mod m where n is the number of bits to reduce by. * Given m must be 4096 bits, just need to subtract. @@ -10637,7 +10678,7 @@ static void sp_4096_mont_reduce_78(sp_digit* a, const sp_digit* m, sp_digit mp) sp_4096_norm_78(a + 78); -#ifdef WOLFSSL_HAVE_SP_DH +#ifdef WOLFSSL_SP_DH if (mp != 1) { for (i=0; i<77; i++) { mu = (a[i] * mp) & 0x1fffffffffffffL; @@ -10671,7 +10712,6 @@ static void sp_4096_mont_reduce_78(sp_digit* a, const sp_digit* m, sp_digit mp) a[i+1] += a[i] >> 53; a[i] &= 0x1fffffffffffffL; #endif - sp_4096_mont_shift_78(a, a); sp_4096_cond_sub_78(a, a, m, 0 - (((a[77] >> 15) > 0) ? (sp_digit)1 : (sp_digit)0)); @@ -10687,8 +10727,8 @@ static void sp_4096_mont_reduce_78(sp_digit* a, const sp_digit* m, sp_digit mp) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_4096_mont_mul_78(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_4096_mont_mul_78(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_4096_mul_78(r, a, b); sp_4096_mont_reduce_78(r, m, mp); @@ -10701,8 +10741,8 @@ static void sp_4096_mont_mul_78(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_4096_mont_sqr_78(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_4096_mont_sqr_78(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_4096_sqr_78(r, a); sp_4096_mont_reduce_78(r, m, mp); @@ -10800,46 +10840,8 @@ static void sp_4096_cond_add_78(sp_digit* r, const sp_digit* a, #endif /* WOLFSSL_SP_SMALL */ } -#ifdef WOLFSSL_SMALL -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_4096_sub_78(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 78; i++) { - r[i] = a[i] - b[i]; - } - - return 0; -} - -#endif -#ifdef WOLFSSL_SMALL -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_4096_add_78(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 78; i++) { - r[i] = a[i] + b[i]; - } - - return 0; -} -#endif -SP_NOINLINE static void sp_4096_rshift_78(sp_digit* r, sp_digit* a, byte n) +SP_NOINLINE static void sp_4096_rshift_78(sp_digit* r, const sp_digit* a, + byte n) { int i; @@ -10849,20 +10851,20 @@ SP_NOINLINE static void sp_4096_rshift_78(sp_digit* r, sp_digit* a, byte n) } #else for (i=0; i<72; i += 8) { - r[i+0] = ((a[i+0] >> n) | (a[i+1] << (53 - n))) & 0x1fffffffffffffL; - r[i+1] = ((a[i+1] >> n) | (a[i+2] << (53 - n))) & 0x1fffffffffffffL; - r[i+2] = ((a[i+2] >> n) | (a[i+3] << (53 - n))) & 0x1fffffffffffffL; - r[i+3] = ((a[i+3] >> n) | (a[i+4] << (53 - n))) & 0x1fffffffffffffL; - r[i+4] = ((a[i+4] >> n) | (a[i+5] << (53 - n))) & 0x1fffffffffffffL; - r[i+5] = ((a[i+5] >> n) | (a[i+6] << (53 - n))) & 0x1fffffffffffffL; - r[i+6] = ((a[i+6] >> n) | (a[i+7] << (53 - n))) & 0x1fffffffffffffL; - r[i+7] = ((a[i+7] >> n) | (a[i+8] << (53 - n))) & 0x1fffffffffffffL; + r[i+0] = (a[i+0] >> n) | ((a[i+1] << (53 - n)) & 0x1fffffffffffffL); + r[i+1] = (a[i+1] >> n) | ((a[i+2] << (53 - n)) & 0x1fffffffffffffL); + r[i+2] = (a[i+2] >> n) | ((a[i+3] << (53 - n)) & 0x1fffffffffffffL); + r[i+3] = (a[i+3] >> n) | ((a[i+4] << (53 - n)) & 0x1fffffffffffffL); + r[i+4] = (a[i+4] >> n) | ((a[i+5] << (53 - n)) & 0x1fffffffffffffL); + r[i+5] = (a[i+5] >> n) | ((a[i+6] << (53 - n)) & 0x1fffffffffffffL); + r[i+6] = (a[i+6] >> n) | ((a[i+7] << (53 - n)) & 0x1fffffffffffffL); + r[i+7] = (a[i+7] >> n) | ((a[i+8] << (53 - n)) & 0x1fffffffffffffL); } - r[72] = ((a[72] >> n) | (a[73] << (53 - n))) & 0x1fffffffffffffL; - r[73] = ((a[73] >> n) | (a[74] << (53 - n))) & 0x1fffffffffffffL; - r[74] = ((a[74] >> n) | (a[75] << (53 - n))) & 0x1fffffffffffffL; - r[75] = ((a[75] >> n) | (a[76] << (53 - n))) & 0x1fffffffffffffL; - r[76] = ((a[76] >> n) | (a[77] << (53 - n))) & 0x1fffffffffffffL; + r[72] = (a[72] >> n) | ((a[73] << (53 - n)) & 0x1fffffffffffffL); + r[73] = (a[73] >> n) | ((a[74] << (53 - n)) & 0x1fffffffffffffL); + r[74] = (a[74] >> n) | ((a[75] << (53 - n)) & 0x1fffffffffffffL); + r[75] = (a[75] >> n) | ((a[76] << (53 - n)) & 0x1fffffffffffffL); + r[76] = (a[76] >> n) | ((a[77] << (53 - n)) & 0x1fffffffffffffL); #endif r[77] = a[77] >> n; } @@ -10871,7 +10873,9 @@ SP_NOINLINE static void sp_4096_rshift_78(sp_digit* r, sp_digit* a, byte n) static WC_INLINE sp_digit sp_4096_div_word_78(sp_digit d1, sp_digit d0, sp_digit dv) { - sp_digit d, r, t; + sp_digit d; + sp_digit r; + sp_digit t; /* All 53 bits from d1 and top 10 bits from d0. */ d = (d1 << 10) | (d0 >> 43); @@ -10924,24 +10928,29 @@ static WC_INLINE sp_digit sp_4096_div_word_78(sp_digit d1, sp_digit d0, /* Divide d in a and put remainder into r (m*d + r = a) * m is not calculated as it is not needed at this time. * + * Full implementation. + * * a Number to be divided. * d Number to divide with. * m Multiplier result. * r Remainder from the division. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise. */ -static int sp_4096_div_78(const sp_digit* a, const sp_digit* d, sp_digit* m, - sp_digit* r) +static int sp_4096_div_78(const sp_digit* a, const sp_digit* d, + const sp_digit* m, sp_digit* r) { int i; #ifndef WOLFSSL_SP_DIV_64 int128_t d1; #endif - sp_digit dv, r1; + sp_digit dv; + sp_digit r1; #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* td; #else - sp_digit t1d[156 + 1], t2d[78 + 1], sdd[78 + 1]; + sp_digit t1d[156 + 1]; + sp_digit t2d[78 + 1]; + sp_digit sdd[78 + 1]; #endif sp_digit* t1; sp_digit* t2; @@ -10974,18 +10983,16 @@ static int sp_4096_div_78(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_4096_mul_d_78(sd, d, 1L << 38); sp_4096_mul_d_156(t1, a, 1L << 38); dv = sd[77]; + t1[78 + 78] += t1[78 + 78 - 1] >> 53; + t1[78 + 78 - 1] &= 0x1fffffffffffffL; for (i=78; i>=0; i--) { - sp_digit hi; - t1[78 + i] += t1[78 + i - 1] >> 53; - t1[78 + i - 1] &= 0x1fffffffffffffL; - hi = t1[78 + i] - (t1[78 + i] == dv); #ifndef WOLFSSL_SP_DIV_64 - d1 = hi; + d1 = t1[78 + i]; d1 <<= 53; d1 += t1[78 + i - 1]; r1 = (sp_digit)(d1 / dv); #else - r1 = sp_4096_div_word_78(hi, t1[78 + i - 1], dv); + r1 = sp_4096_div_word_78(t1[78 + i], t1[78 + i - 1], dv); #endif sp_4096_mul_d_78(t2, sd, r1); @@ -11006,7 +11013,7 @@ static int sp_4096_div_78(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_4096_mul_d_78(t2, sd, r1); sp_4096_sub_78(t1, t1, t2); - XMEMCPY(r, t1, sizeof(*r) * 2U * 78U); + XMEMCPY(r, t1, sizeof(*r) * 156U); for (i=0; i<77; i++) { r[i+1] += r[i] >> 53; r[i] &= 0x1fffffffffffffL; @@ -11064,7 +11071,8 @@ static int sp_4096_mod_exp_78(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if !defined(WOLFSSL_SP_NO_MALLOC) @@ -11155,7 +11163,8 @@ static int sp_4096_mod_exp_78(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #ifdef WOLFSSL_SMALL_STACK @@ -11241,12 +11250,13 @@ static int sp_4096_mod_exp_78(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit td[(32 * 156) + 156]; #endif sp_digit* t[32]; - sp_digit* rt; + sp_digit* rt = NULL; sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -11338,7 +11348,7 @@ static int sp_4096_mod_exp_78(sp_digit* r, const sp_digit* a, const sp_digit* e, n <<= 5; c -= 5; XMEMCPY(rt, t[y], sizeof(sp_digit) * 156); - for (; i>=0 || c>=5; ) { + while ((i >= 0) || (c >= 5)) { if (c < 5) { n |= e[i--] << (11 - c); c += 53; @@ -11372,7 +11382,7 @@ static int sp_4096_mod_exp_78(sp_digit* r, const sp_digit* a, const sp_digit* e, return err; #endif } -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) || */ /* WOLFSSL_HAVE_SP_DH */ #ifdef WOLFSSL_HAVE_SP_RSA @@ -11388,15 +11398,15 @@ static int sp_4096_mod_exp_78(sp_digit* r, const sp_digit* a, const sp_digit* e, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPublic_4096(const byte* in, word32 inLen, const mp_int* em, + const mp_int* mm, byte* out, word32* outLen) { #ifdef WOLFSSL_SP_SMALL sp_digit* d = NULL; sp_digit* a = NULL; sp_digit* m = NULL; sp_digit* r = NULL; - sp_digit* norm; + sp_digit* norm = NULL; sp_digit e[1] = {0}; sp_digit mp; int i; @@ -11489,13 +11499,15 @@ int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, return err; #else #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_digit ad[156], md[78], rd[156]; + sp_digit ad[156]; + sp_digit md[78]; + sp_digit rd[156]; #else sp_digit* d = NULL; #endif - sp_digit* a; - sp_digit* m; - sp_digit* r; + sp_digit* a = NULL; + sp_digit* m = NULL; + sp_digit* r = NULL; sp_digit e[1] = {0}; int err = MP_OKAY; @@ -11613,7 +11625,7 @@ int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #ifndef WOLFSSL_RSA_PUBLIC_ONLY #if !defined(SP_RSA_PRIVATE_EXP_D) && !defined(RSA_LOW_MEM) -#endif /* !SP_RSA_PRIVATE_EXP_D && !RSA_LOW_MEM */ +#endif /* !SP_RSA_PRIVATE_EXP_D & !RSA_LOW_MEM */ /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -11631,9 +11643,9 @@ int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_4096(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM) #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -11696,7 +11708,9 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, return err; #else - sp_digit a[156], d[78], m[78]; + sp_digit a[156]; + sp_digit d[78]; + sp_digit m[78]; sp_digit* r = a; int err = MP_OKAY; @@ -11739,19 +11753,19 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, XMEMSET(d, 0, sizeof(sp_digit) * 78); return err; -#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */ +#endif /* WOLFSSL_SP_SMALL | defined(WOLFSSL_SMALL_STACK) */ #else #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* t = NULL; - sp_digit* a; - sp_digit* p; - sp_digit* q; - sp_digit* dp; - sp_digit* dq; - sp_digit* qi; - sp_digit* tmpa; - sp_digit* tmpb; - sp_digit* r; + sp_digit* a = NULL; + sp_digit* p = NULL; + sp_digit* q = NULL; + sp_digit* dp = NULL; + sp_digit* dq = NULL; + sp_digit* qi = NULL; + sp_digit* tmpa = NULL; + sp_digit* tmpb = NULL; + sp_digit* r = NULL; int err = MP_OKAY; (void)dm; @@ -11826,8 +11840,13 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, return err; #else sp_digit a[78 * 2]; - sp_digit p[39], q[39], dp[39], dq[39], qi[39]; - sp_digit tmpa[78], tmpb[78]; + sp_digit p[39]; + sp_digit q[39]; + sp_digit dp[39]; + sp_digit dq[39]; + sp_digit qi[39]; + sp_digit tmpa[78]; + sp_digit tmpb[78]; sp_digit* r = a; int err = MP_OKAY; @@ -11889,8 +11908,8 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, XMEMSET(qi, 0, sizeof(qi)); return err; -#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */ -#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */ +#endif /* WOLFSSL_SP_SMALL | defined(WOLFSSL_SMALL_STACK) */ +#endif /* SP_RSA_PRIVATE_EXP_D | RSA_LOW_MEM */ } #endif /* !WOLFSSL_RSA_PUBLIC_ONLY */ @@ -11913,17 +11932,19 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->used = 78; mp_clamp(r); #elif DIGIT_BIT < 53 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 78; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 53) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -11936,14 +11957,16 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 78; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 53 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -11970,7 +11993,8 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_4096(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { #ifdef WOLFSSL_SP_SMALL int err = MP_OKAY; @@ -12026,7 +12050,9 @@ int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) return err; #else #ifndef WOLFSSL_SMALL_STACK - sp_digit bd[156], ed[78], md[78]; + sp_digit bd[156]; + sp_digit ed[78]; + sp_digit md[78]; #else sp_digit* d = NULL; #endif @@ -12098,7 +12124,8 @@ int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) #ifdef WOLFSSL_HAVE_SP_DH #ifdef HAVE_FFDHE_4096 -SP_NOINLINE static void sp_4096_lshift_78(sp_digit* r, sp_digit* a, byte n) +SP_NOINLINE static void sp_4096_lshift_78(sp_digit* r, const sp_digit* a, + byte n) { #ifdef WOLFSSL_SP_SMALL int i; @@ -12108,7 +12135,8 @@ SP_NOINLINE static void sp_4096_lshift_78(sp_digit* r, sp_digit* a, byte n) r[i] = ((a[i] << n) | (a[i-1] >> (53 - n))) & 0x1fffffffffffffL; } #else - sp_int_digit s, t; + sp_int_digit s; + sp_int_digit t; s = (sp_int_digit)a[77]; r[78] = s >> (53U - n); @@ -12288,9 +12316,11 @@ static int sp_4096_mod_exp_2_78(sp_digit* r, const sp_digit* e, int bits, const sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -12335,7 +12365,7 @@ static int sp_4096_mod_exp_2_78(sp_digit* r, const sp_digit* e, int bits, const n <<= 5; c -= 5; sp_4096_lshift_78(r, norm, (byte)y); - for (; i>=0 || c>=5; ) { + while ((i >= 0) || (c >= 5)) { if (c < 5) { n |= e[i--] << (11 - c); c += 53; @@ -12390,8 +12420,8 @@ static int sp_4096_mod_exp_2_78(sp_digit* r, const sp_digit* e, int bits, const * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, - mp_int* mod, byte* out, word32* outLen) +int sp_DhExp_4096(const mp_int* base, const byte* exp, word32 expLen, + const mp_int* mod, byte* out, word32* outLen) { #ifdef WOLFSSL_SP_SMALL int err = MP_OKAY; @@ -12458,7 +12488,9 @@ int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, return err; #else #ifndef WOLFSSL_SMALL_STACK - sp_digit bd[156], ed[78], md[78]; + sp_digit bd[156]; + sp_digit ed[78]; + sp_digit md[78]; #else sp_digit* d = NULL; #endif @@ -12523,6 +12555,7 @@ int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, sp_4096_to_bin(r, out); *outLen = 512; for (i=0; i<512U && out[i] == 0U; i++) { + /* Search for first non-zero. */ } *outLen -= i; XMEMMOVE(out, out + i, *outLen); @@ -12542,19 +12575,23 @@ int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, } #endif /* WOLFSSL_HAVE_SP_DH */ -#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */ +#endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */ #endif /* WOLFSSL_SP_4096 */ -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */ #ifdef WOLFSSL_HAVE_SP_ECC #ifndef WOLFSSL_SP_NO_256 /* Point structure to use. */ typedef struct sp_point_256 { + /* X ordinate of point. */ sp_digit x[2 * 5]; + /* Y ordinate of point. */ sp_digit y[2 * 5]; + /* Z ordinate of point. */ sp_digit z[2 * 5]; + /* Indicates point is at infinity. */ int infinity; } sp_point_256; @@ -12624,353 +12661,6 @@ static const sp_digit p256_b[5] = { }; #endif -static int sp_256_point_new_ex_5(void* heap, sp_point_256* sp, sp_point_256** p) -{ - int ret = MP_OKAY; - (void)heap; -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - (void)sp; - *p = (sp_point_256*)XMALLOC(sizeof(sp_point_256), heap, DYNAMIC_TYPE_ECC); -#else - *p = sp; -#endif - if (*p == NULL) { - ret = MEMORY_E; - } - return ret; -} - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) -/* Allocate memory for point and return error. */ -#define sp_256_point_new_5(heap, sp, p) sp_256_point_new_ex_5((heap), NULL, &(p)) -#else -/* Set pointer to data and return no error. */ -#define sp_256_point_new_5(heap, sp, p) sp_256_point_new_ex_5((heap), &(sp), &(p)) -#endif - - -static void sp_256_point_free_5(sp_point_256* p, int clear, void* heap) -{ -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) -/* If valid pointer then clear point data if requested and free data. */ - if (p != NULL) { - if (clear != 0) { - XMEMSET(p, 0, sizeof(*p)); - } - XFREE(p, heap, DYNAMIC_TYPE_ECC); - } -#else -/* Clear point data if requested. */ - if (clear != 0) { - XMEMSET(p, 0, sizeof(*p)); - } -#endif - (void)heap; -} - -/* Multiply a number by Montogmery normalizer mod modulus (prime). - * - * r The resulting Montgomery form number. - * a The number to convert. - * m The modulus (prime). - * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. - */ -static int sp_256_mod_mul_norm_5(sp_digit* r, const sp_digit* a, const sp_digit* m) -{ -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - int64_t* td; -#else - int64_t td[8]; - int64_t a32d[8]; -#endif - int64_t* t; - int64_t* a32; - int64_t o; - int err = MP_OKAY; - - (void)m; - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - td = (int64_t*)XMALLOC(sizeof(int64_t) * 2 * 8, NULL, DYNAMIC_TYPE_ECC); - if (td == NULL) { - return MEMORY_E; - } -#endif - - if (err == MP_OKAY) { -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - t = td; - a32 = td + 8; -#else - t = td; - a32 = a32d; -#endif - - a32[0] = (sp_digit)(a[0]) & 0xffffffffL; - a32[1] = (sp_digit)(a[0] >> 32U); - a32[1] |= (sp_digit)(a[1] << 20U); - a32[1] &= 0xffffffffL; - a32[2] = (sp_digit)(a[1] >> 12U) & 0xffffffffL; - a32[3] = (sp_digit)(a[1] >> 44U); - a32[3] |= (sp_digit)(a[2] << 8U); - a32[3] &= 0xffffffffL; - a32[4] = (sp_digit)(a[2] >> 24U); - a32[4] |= (sp_digit)(a[3] << 28U); - a32[4] &= 0xffffffffL; - a32[5] = (sp_digit)(a[3] >> 4U) & 0xffffffffL; - a32[6] = (sp_digit)(a[3] >> 36U); - a32[6] |= (sp_digit)(a[4] << 16U); - a32[6] &= 0xffffffffL; - a32[7] = (sp_digit)(a[4] >> 16U) & 0xffffffffL; - - /* 1 1 0 -1 -1 -1 -1 0 */ - t[0] = 0 + a32[0] + a32[1] - a32[3] - a32[4] - a32[5] - a32[6]; - /* 0 1 1 0 -1 -1 -1 -1 */ - t[1] = 0 + a32[1] + a32[2] - a32[4] - a32[5] - a32[6] - a32[7]; - /* 0 0 1 1 0 -1 -1 -1 */ - t[2] = 0 + a32[2] + a32[3] - a32[5] - a32[6] - a32[7]; - /* -1 -1 0 2 2 1 0 -1 */ - t[3] = 0 - a32[0] - a32[1] + 2 * a32[3] + 2 * a32[4] + a32[5] - a32[7]; - /* 0 -1 -1 0 2 2 1 0 */ - t[4] = 0 - a32[1] - a32[2] + 2 * a32[4] + 2 * a32[5] + a32[6]; - /* 0 0 -1 -1 0 2 2 1 */ - t[5] = 0 - a32[2] - a32[3] + 2 * a32[5] + 2 * a32[6] + a32[7]; - /* -1 -1 0 0 0 1 3 2 */ - t[6] = 0 - a32[0] - a32[1] + a32[5] + 3 * a32[6] + 2 * a32[7]; - /* 1 0 -1 -1 -1 -1 0 3 */ - t[7] = 0 + a32[0] - a32[2] - a32[3] - a32[4] - a32[5] + 3 * a32[7]; - - t[1] += t[0] >> 32U; t[0] &= 0xffffffffL; - t[2] += t[1] >> 32U; t[1] &= 0xffffffffL; - t[3] += t[2] >> 32U; t[2] &= 0xffffffffL; - t[4] += t[3] >> 32U; t[3] &= 0xffffffffL; - t[5] += t[4] >> 32U; t[4] &= 0xffffffffL; - t[6] += t[5] >> 32U; t[5] &= 0xffffffffL; - t[7] += t[6] >> 32U; t[6] &= 0xffffffffL; - o = t[7] >> 32U; t[7] &= 0xffffffffL; - t[0] += o; - t[3] -= o; - t[6] -= o; - t[7] += o; - t[1] += t[0] >> 32U; t[0] &= 0xffffffffL; - t[2] += t[1] >> 32U; t[1] &= 0xffffffffL; - t[3] += t[2] >> 32U; t[2] &= 0xffffffffL; - t[4] += t[3] >> 32U; t[3] &= 0xffffffffL; - t[5] += t[4] >> 32U; t[4] &= 0xffffffffL; - t[6] += t[5] >> 32U; t[5] &= 0xffffffffL; - t[7] += t[6] >> 32U; t[6] &= 0xffffffffL; - - r[0] = t[0]; - r[0] |= t[1] << 32U; - r[0] &= 0xfffffffffffffLL; - r[1] = (sp_digit)(t[1] >> 20); - r[1] |= t[2] << 12U; - r[1] |= t[3] << 44U; - r[1] &= 0xfffffffffffffLL; - r[2] = (sp_digit)(t[3] >> 8); - r[2] |= t[4] << 24U; - r[2] &= 0xfffffffffffffLL; - r[3] = (sp_digit)(t[4] >> 28); - r[3] |= t[5] << 4U; - r[3] |= t[6] << 36U; - r[3] &= 0xfffffffffffffLL; - r[4] = (sp_digit)(t[6] >> 16); - r[4] |= t[7] << 16U; - } - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - if (td != NULL) { - XFREE(td, NULL, DYNAMIC_TYPE_ECC); - } -#endif - - return err; -} - -/* Convert an mp_int to an array of sp_digit. - * - * r A single precision integer. - * size Maximum number of bytes to convert - * a A multi-precision integer. - */ -static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) -{ -#if DIGIT_BIT == 52 - int j; - - XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); - - for (j = a->used; j < size; j++) { - r[j] = 0; - } -#elif DIGIT_BIT > 52 - int i, j = 0; - word32 s = 0; - - r[0] = 0; - for (i = 0; i < a->used && j < size; i++) { - r[j] |= ((sp_digit)a->dp[i] << s); - r[j] &= 0xfffffffffffffL; - s = 52U - s; - if (j + 1 >= size) { - break; - } - /* lint allow cast of mismatch word32 and mp_digit */ - r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ - while ((s + 52U) <= (word32)DIGIT_BIT) { - s += 52U; - r[j] &= 0xfffffffffffffL; - if (j + 1 >= size) { - break; - } - if (s < (word32)DIGIT_BIT) { - /* lint allow cast of mismatch word32 and mp_digit */ - r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ - } - else { - r[++j] = 0L; - } - } - s = (word32)DIGIT_BIT - s; - } - - for (j++; j < size; j++) { - r[j] = 0; - } -#else - int i, j = 0, s = 0; - - r[0] = 0; - for (i = 0; i < a->used && j < size; i++) { - r[j] |= ((sp_digit)a->dp[i]) << s; - if (s + DIGIT_BIT >= 52) { - r[j] &= 0xfffffffffffffL; - if (j + 1 >= size) { - break; - } - s = 52 - s; - if (s == DIGIT_BIT) { - r[++j] = 0; - s = 0; - } - else { - r[++j] = a->dp[i] >> s; - s = DIGIT_BIT - s; - } - } - else { - s += DIGIT_BIT; - } - } - - for (j++; j < size; j++) { - r[j] = 0; - } -#endif -} - -/* Convert a point of type ecc_point to type sp_point_256. - * - * p Point of type sp_point_256 (result). - * pm Point of type ecc_point. - */ -static void sp_256_point_from_ecc_point_5(sp_point_256* p, const ecc_point* pm) -{ - XMEMSET(p->x, 0, sizeof(p->x)); - XMEMSET(p->y, 0, sizeof(p->y)); - XMEMSET(p->z, 0, sizeof(p->z)); - sp_256_from_mp(p->x, 5, pm->x); - sp_256_from_mp(p->y, 5, pm->y); - sp_256_from_mp(p->z, 5, pm->z); - p->infinity = 0; -} - -/* Convert an array of sp_digit to an mp_int. - * - * a A single precision integer. - * r A multi-precision integer. - */ -static int sp_256_to_mp(const sp_digit* a, mp_int* r) -{ - int err; - - err = mp_grow(r, (256 + DIGIT_BIT - 1) / DIGIT_BIT); - if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ -#if DIGIT_BIT == 52 - XMEMCPY(r->dp, a, sizeof(sp_digit) * 5); - r->used = 5; - mp_clamp(r); -#elif DIGIT_BIT < 52 - int i, j = 0, s = 0; - - r->dp[0] = 0; - for (i = 0; i < 5; i++) { - r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; - s = DIGIT_BIT - s; - r->dp[++j] = (mp_digit)(a[i] >> s); - while (s + DIGIT_BIT <= 52) { - s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; - if (s == SP_WORD_SIZE) { - r->dp[j] = 0; - } - else { - r->dp[j] = (mp_digit)(a[i] >> s); - } - } - s = 52 - s; - } - r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT; - mp_clamp(r); -#else - int i, j = 0, s = 0; - - r->dp[0] = 0; - for (i = 0; i < 5; i++) { - r->dp[j] |= ((mp_digit)a[i]) << s; - if (s + 52 >= DIGIT_BIT) { - #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; - #endif - s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; - s = 52 - s; - } - else { - s += 52; - } - } - r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT; - mp_clamp(r); -#endif - } - - return err; -} - -/* Convert a point of type sp_point_256 to type ecc_point. - * - * p Point of type sp_point_256. - * pm Point of type ecc_point (result). - * returns MEMORY_E when allocation of memory in ecc_point fails otherwise - * MP_OKAY. - */ -static int sp_256_point_to_ecc_point_5(const sp_point_256* p, ecc_point* pm) -{ - int err; - - err = sp_256_to_mp(p->x, pm->x); - if (err == MP_OKAY) { - err = sp_256_to_mp(p->y, pm->y); - } - if (err == MP_OKAY) { - err = sp_256_to_mp(p->z, pm->z); - } - - return err; -} - #ifdef WOLFSSL_SP_SMALL /* Multiply a and b into r. (r = a * b) * @@ -12981,7 +12671,9 @@ static int sp_256_point_to_ecc_point_5(const sp_point_256* p, ecc_point* pm) SP_NOINLINE static void sp_256_mul_5(sp_digit* r, const sp_digit* a, const sp_digit* b) { - int i, j, k; + int i; + int j; + int k; int128_t c; c = ((int128_t)a[4]) * b[4]; @@ -13055,6 +12747,409 @@ SP_NOINLINE static void sp_256_mul_5(sp_digit* r, const sp_digit* a, } #endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_256_sqr_5(sp_digit* r, const sp_digit* a) +{ + int i; + int j; + int k; + int128_t c; + + c = ((int128_t)a[4]) * a[4]; + r[9] = (sp_digit)(c >> 52); + c = (c & 0xfffffffffffffL) << 52; + for (k = 7; k >= 0; k--) { + for (i = 4; i >= 0; i--) { + j = k - i; + if (j >= 5 || i <= j) { + break; + } + if (j < 0) { + continue; + } + + c += ((int128_t)a[i]) * a[j] * 2; + } + if (i == j) { + c += ((int128_t)a[i]) * a[i]; + } + + r[k + 2] += (sp_digit)(c >> 104); + r[k + 1] = (sp_digit)((c >> 52) & 0xfffffffffffffL); + c = (c & 0xfffffffffffffL) << 52; + } + r[0] = (sp_digit)(c >> 52); +} + +#else +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_256_sqr_5(sp_digit* r, const sp_digit* a) +{ + int128_t t0 = ((int128_t)a[ 0]) * a[ 0]; + int128_t t1 = (((int128_t)a[ 0]) * a[ 1]) * 2; + int128_t t2 = (((int128_t)a[ 0]) * a[ 2]) * 2 + + ((int128_t)a[ 1]) * a[ 1]; + int128_t t3 = (((int128_t)a[ 0]) * a[ 3] + + ((int128_t)a[ 1]) * a[ 2]) * 2; + int128_t t4 = (((int128_t)a[ 0]) * a[ 4] + + ((int128_t)a[ 1]) * a[ 3]) * 2 + + ((int128_t)a[ 2]) * a[ 2]; + int128_t t5 = (((int128_t)a[ 1]) * a[ 4] + + ((int128_t)a[ 2]) * a[ 3]) * 2; + int128_t t6 = (((int128_t)a[ 2]) * a[ 4]) * 2 + + ((int128_t)a[ 3]) * a[ 3]; + int128_t t7 = (((int128_t)a[ 3]) * a[ 4]) * 2; + int128_t t8 = ((int128_t)a[ 4]) * a[ 4]; + + t1 += t0 >> 52; r[ 0] = t0 & 0xfffffffffffffL; + t2 += t1 >> 52; r[ 1] = t1 & 0xfffffffffffffL; + t3 += t2 >> 52; r[ 2] = t2 & 0xfffffffffffffL; + t4 += t3 >> 52; r[ 3] = t3 & 0xfffffffffffffL; + t5 += t4 >> 52; r[ 4] = t4 & 0xfffffffffffffL; + t6 += t5 >> 52; r[ 5] = t5 & 0xfffffffffffffL; + t7 += t6 >> 52; r[ 6] = t6 & 0xfffffffffffffL; + t8 += t7 >> 52; r[ 7] = t7 & 0xfffffffffffffL; + r[9] = (sp_digit)(t8 >> 52); + r[8] = t8 & 0xfffffffffffffL; +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_256_add_5(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + int i; + + for (i = 0; i < 5; i++) { + r[i] = a[i] + b[i]; + } + + return 0; +} +#else +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_256_add_5(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + r[ 0] = a[ 0] + b[ 0]; + r[ 1] = a[ 1] + b[ 1]; + r[ 2] = a[ 2] + b[ 2]; + r[ 3] = a[ 3] + b[ 3]; + r[ 4] = a[ 4] + b[ 4]; + + return 0; +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_256_sub_5(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + int i; + + for (i = 0; i < 5; i++) { + r[i] = a[i] - b[i]; + } + + return 0; +} + +#else +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_256_sub_5(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + r[ 0] = a[ 0] - b[ 0]; + r[ 1] = a[ 1] - b[ 1]; + r[ 2] = a[ 2] - b[ 2]; + r[ 3] = a[ 3] - b[ 3]; + r[ 4] = a[ 4] - b[ 4]; + + return 0; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Create a new point. + * + * heap [in] Buffer to allocate dynamic memory from. + * sp [in] Data for point - only if not allocating. + * p [out] New point. + * returns MEMORY_E when dynamic memory allocation fails and 0 otherwise. + */ +static int sp_256_point_new_ex_5(void* heap, sp_point_256* sp, + sp_point_256** p) +{ + int ret = MP_OKAY; + (void)heap; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + (void)sp; + *p = (sp_point_256*)XMALLOC(sizeof(sp_point_256), heap, DYNAMIC_TYPE_ECC); +#else + *p = sp; +#endif + if (*p == NULL) { + ret = MEMORY_E; + } + return ret; +} + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* Allocate memory for point and return error. */ +#define sp_256_point_new_5(heap, sp, p) sp_256_point_new_ex_5((heap), NULL, &(p)) +#else +/* Set pointer to data and return no error. */ +#define sp_256_point_new_5(heap, sp, p) sp_256_point_new_ex_5((heap), &(sp), &(p)) +#endif + + +/* Free the point. + * + * p [in,out] Point to free. + * clear [in] Indicates whether to zeroize point. + * heap [in] Buffer from which dynamic memory was allocate from. + */ +static void sp_256_point_free_5(sp_point_256* p, int clear, void* heap) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* If valid pointer then clear point data if requested and free data. */ + if (p != NULL) { + if (clear != 0) { + XMEMSET(p, 0, sizeof(*p)); + } + XFREE(p, heap, DYNAMIC_TYPE_ECC); + } +#else +/* Clear point data if requested. */ + if ((p != NULL) && (clear != 0)) { + XMEMSET(p, 0, sizeof(*p)); + } +#endif + (void)heap; +} + +/* Convert an mp_int to an array of sp_digit. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a A multi-precision integer. + */ +static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) +{ +#if DIGIT_BIT == 52 + int j; + + XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); + + for (j = a->used; j < size; j++) { + r[j] = 0; + } +#elif DIGIT_BIT > 52 + int i; + int j = 0; + word32 s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i] << s); + r[j] &= 0xfffffffffffffL; + s = 52U - s; + if (j + 1 >= size) { + break; + } + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + while ((s + 52U) <= (word32)DIGIT_BIT) { + s += 52U; + r[j] &= 0xfffffffffffffL; + if (j + 1 >= size) { + break; + } + if (s < (word32)DIGIT_BIT) { + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + } + else { + r[++j] = 0L; + } + } + s = (word32)DIGIT_BIT - s; + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#else + int i; + int j = 0; + int s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i]) << s; + if (s + DIGIT_BIT >= 52) { + r[j] &= 0xfffffffffffffL; + if (j + 1 >= size) { + break; + } + s = 52 - s; + if (s == DIGIT_BIT) { + r[++j] = 0; + s = 0; + } + else { + r[++j] = a->dp[i] >> s; + s = DIGIT_BIT - s; + } + } + else { + s += DIGIT_BIT; + } + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#endif +} + +/* Convert a point of type ecc_point to type sp_point_256. + * + * p Point of type sp_point_256 (result). + * pm Point of type ecc_point. + */ +static void sp_256_point_from_ecc_point_5(sp_point_256* p, + const ecc_point* pm) +{ + XMEMSET(p->x, 0, sizeof(p->x)); + XMEMSET(p->y, 0, sizeof(p->y)); + XMEMSET(p->z, 0, sizeof(p->z)); + sp_256_from_mp(p->x, 5, pm->x); + sp_256_from_mp(p->y, 5, pm->y); + sp_256_from_mp(p->z, 5, pm->z); + p->infinity = 0; +} + +/* Convert an array of sp_digit to an mp_int. + * + * a A single precision integer. + * r A multi-precision integer. + */ +static int sp_256_to_mp(const sp_digit* a, mp_int* r) +{ + int err; + + err = mp_grow(r, (256 + DIGIT_BIT - 1) / DIGIT_BIT); + if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ +#if DIGIT_BIT == 52 + XMEMCPY(r->dp, a, sizeof(sp_digit) * 5); + r->used = 5; + mp_clamp(r); +#elif DIGIT_BIT < 52 + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 5; i++) { + r->dp[j] |= (mp_digit)(a[i] << s); + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + s = DIGIT_BIT - s; + r->dp[++j] = (mp_digit)(a[i] >> s); + while (s + DIGIT_BIT <= 52) { + s += DIGIT_BIT; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; + if (s == SP_WORD_SIZE) { + r->dp[j] = 0; + } + else { + r->dp[j] = (mp_digit)(a[i] >> s); + } + } + s = 52 - s; + } + r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#else + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 5; i++) { + r->dp[j] |= ((mp_digit)a[i]) << s; + if (s + 52 >= DIGIT_BIT) { + #if DIGIT_BIT != 32 && DIGIT_BIT != 64 + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + #endif + s = DIGIT_BIT - s; + r->dp[++j] = a[i] >> s; + s = 52 - s; + } + else { + s += 52; + } + } + r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#endif + } + + return err; +} + +/* Convert a point of type sp_point_256 to type ecc_point. + * + * p Point of type sp_point_256. + * pm Point of type ecc_point (result). + * returns MEMORY_E when allocation of memory in ecc_point fails otherwise + * MP_OKAY. + */ +static int sp_256_point_to_ecc_point_5(const sp_point_256* p, ecc_point* pm) +{ + int err; + + err = sp_256_to_mp(p->x, pm->x); + if (err == MP_OKAY) { + err = sp_256_to_mp(p->y, pm->y); + } + if (err == MP_OKAY) { + err = sp_256_to_mp(p->z, pm->z); + } + + return err; +} + #define sp_256_mont_reduce_order_5 sp_256_mont_reduce_5 /* Compare a with b in constant time. @@ -13249,87 +13344,13 @@ static void sp_256_mont_reduce_5(sp_digit* a, const sp_digit* m, sp_digit mp) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_256_mont_mul_5(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_256_mont_mul_5(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_256_mul_5(r, a, b); sp_256_mont_reduce_5(r, m, mp); } -#ifdef WOLFSSL_SP_SMALL -/* Square a and put result in r. (r = a * a) - * - * r A single precision integer. - * a A single precision integer. - */ -SP_NOINLINE static void sp_256_sqr_5(sp_digit* r, const sp_digit* a) -{ - int i, j, k; - int128_t c; - - c = ((int128_t)a[4]) * a[4]; - r[9] = (sp_digit)(c >> 52); - c = (c & 0xfffffffffffffL) << 52; - for (k = 7; k >= 0; k--) { - for (i = 4; i >= 0; i--) { - j = k - i; - if (j >= 5 || i <= j) { - break; - } - if (j < 0) { - continue; - } - - c += ((int128_t)a[i]) * a[j] * 2; - } - if (i == j) { - c += ((int128_t)a[i]) * a[i]; - } - - r[k + 2] += (sp_digit)(c >> 104); - r[k + 1] = (sp_digit)((c >> 52) & 0xfffffffffffffL); - c = (c & 0xfffffffffffffL) << 52; - } - r[0] = (sp_digit)(c >> 52); -} - -#else -/* Square a and put result in r. (r = a * a) - * - * r A single precision integer. - * a A single precision integer. - */ -SP_NOINLINE static void sp_256_sqr_5(sp_digit* r, const sp_digit* a) -{ - int128_t t0 = ((int128_t)a[ 0]) * a[ 0]; - int128_t t1 = (((int128_t)a[ 0]) * a[ 1]) * 2; - int128_t t2 = (((int128_t)a[ 0]) * a[ 2]) * 2 - + ((int128_t)a[ 1]) * a[ 1]; - int128_t t3 = (((int128_t)a[ 0]) * a[ 3] - + ((int128_t)a[ 1]) * a[ 2]) * 2; - int128_t t4 = (((int128_t)a[ 0]) * a[ 4] - + ((int128_t)a[ 1]) * a[ 3]) * 2 - + ((int128_t)a[ 2]) * a[ 2]; - int128_t t5 = (((int128_t)a[ 1]) * a[ 4] - + ((int128_t)a[ 2]) * a[ 3]) * 2; - int128_t t6 = (((int128_t)a[ 2]) * a[ 4]) * 2 - + ((int128_t)a[ 3]) * a[ 3]; - int128_t t7 = (((int128_t)a[ 3]) * a[ 4]) * 2; - int128_t t8 = ((int128_t)a[ 4]) * a[ 4]; - - t1 += t0 >> 52; r[ 0] = t0 & 0xfffffffffffffL; - t2 += t1 >> 52; r[ 1] = t1 & 0xfffffffffffffL; - t3 += t2 >> 52; r[ 2] = t2 & 0xfffffffffffffL; - t4 += t3 >> 52; r[ 3] = t3 & 0xfffffffffffffL; - t5 += t4 >> 52; r[ 4] = t4 & 0xfffffffffffffL; - t6 += t5 >> 52; r[ 5] = t5 & 0xfffffffffffffL; - t7 += t6 >> 52; r[ 6] = t6 & 0xfffffffffffffL; - t8 += t7 >> 52; r[ 7] = t7 & 0xfffffffffffffL; - r[9] = (sp_digit)(t8 >> 52); - r[8] = t8 & 0xfffffffffffffL; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Square the Montgomery form number. (r = a * a mod m) * * r Result of squaring. @@ -13337,8 +13358,8 @@ SP_NOINLINE static void sp_256_sqr_5(sp_digit* r, const sp_digit* a) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_256_mont_sqr_5(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_256_mont_sqr_5(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_256_sqr_5(r, a); sp_256_mont_reduce_5(r, m, mp); @@ -13362,7 +13383,7 @@ static void sp_256_mont_sqr_n_5(sp_digit* r, const sp_digit* a, int n, } } -#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */ +#endif /* !WOLFSSL_SP_SMALL | HAVE_COMP_KEY */ #ifdef WOLFSSL_SP_SMALL /* Mod-2 for the P256 curve. */ static const uint64_t p256_mod_minus_2[4] = { @@ -13446,7 +13467,8 @@ static void sp_256_mont_inv_5(sp_digit* r, const sp_digit* a, sp_digit* td) * p Montgomery form projective coordinate point. * t Temporary ordinate data. */ -static void sp_256_map_5(sp_point_256* r, const sp_point_256* p, sp_digit* t) +static void sp_256_map_5(sp_point_256* r, const sp_point_256* p, + sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2*5; @@ -13482,44 +13504,6 @@ static void sp_256_map_5(sp_point_256* r, const sp_point_256* p, sp_digit* t) } -#ifdef WOLFSSL_SP_SMALL -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_256_add_5(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 5; i++) { - r[i] = a[i] + b[i]; - } - - return 0; -} -#else -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_256_add_5(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - r[ 0] = a[ 0] + b[ 0]; - r[ 1] = a[ 1] + b[ 1]; - r[ 2] = a[ 2] + b[ 2]; - r[ 3] = a[ 3] + b[ 3]; - r[ 4] = a[ 4] + b[ 4]; - - return 0; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Add two Montgomery form numbers (r = a + b % m). * * r Result of addition. @@ -13572,45 +13556,6 @@ static void sp_256_mont_tpl_5(sp_digit* r, const sp_digit* a, const sp_digit* m) sp_256_norm_5(r); } -#ifdef WOLFSSL_SP_SMALL -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_256_sub_5(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 5; i++) { - r[i] = a[i] - b[i]; - } - - return 0; -} - -#else -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_256_sub_5(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - r[ 0] = a[ 0] - b[ 0]; - r[ 1] = a[ 1] - b[ 1]; - r[ 2] = a[ 2] - b[ 2]; - r[ 3] = a[ 3] - b[ 3]; - r[ 4] = a[ 4] - b[ 4]; - - return 0; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Conditionally add a and b using the mask m. * m is -1 to add and 0 when not. * @@ -13658,13 +13603,13 @@ static void sp_256_mont_sub_5(sp_digit* r, const sp_digit* a, const sp_digit* b, * r Result of shift. * a Number to shift. */ -SP_NOINLINE static void sp_256_rshift1_5(sp_digit* r, sp_digit* a) +SP_NOINLINE static void sp_256_rshift1_5(sp_digit* r, const sp_digit* a) { #ifdef WOLFSSL_SP_SMALL int i; for (i=0; i<4; i++) { - r[i] = ((a[i] >> 1) + (a[i + 1] << 51)) & 0xfffffffffffffL; + r[i] = (a[i] >> 1) + ((a[i + 1] << 51) & 0xfffffffffffffL); } #else r[0] = (a[0] >> 1) + ((a[1] << 51) & 0xfffffffffffffL); @@ -14106,8 +14051,8 @@ static int sp_256_proj_point_add_5_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r, } #endif /* WOLFSSL_SP_NONBLOCK */ -static void sp_256_proj_point_add_5(sp_point_256* r, const sp_point_256* p, const sp_point_256* q, - sp_digit* t) +static void sp_256_proj_point_add_5(sp_point_256* r, + const sp_point_256* p, const sp_point_256* q, sp_digit* t) { const sp_point_256* ap[2]; sp_point_256* rp[2]; @@ -14193,10 +14138,133 @@ static void sp_256_proj_point_add_5(sp_point_256* r, const sp_point_256* p, cons } } +/* Multiply a number by Montogmery normalizer mod modulus (prime). + * + * r The resulting Montgomery form number. + * a The number to convert. + * m The modulus (prime). + * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. + */ +static int sp_256_mod_mul_norm_5(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + int64_t* td; +#else + int64_t td[8]; + int64_t a32d[8]; +#endif + int64_t* t; + int64_t* a32; + int64_t o; + int err = MP_OKAY; + + (void)m; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + td = (int64_t*)XMALLOC(sizeof(int64_t) * 2 * 8, NULL, DYNAMIC_TYPE_ECC); + if (td == NULL) { + return MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + a32 = td + 8; +#else + t = td; + a32 = a32d; +#endif + + a32[0] = (sp_digit)(a[0]) & 0xffffffffL; + a32[1] = (sp_digit)(a[0] >> 32U); + a32[1] |= (sp_digit)(a[1] << 20U); + a32[1] &= 0xffffffffL; + a32[2] = (sp_digit)(a[1] >> 12U) & 0xffffffffL; + a32[3] = (sp_digit)(a[1] >> 44U); + a32[3] |= (sp_digit)(a[2] << 8U); + a32[3] &= 0xffffffffL; + a32[4] = (sp_digit)(a[2] >> 24U); + a32[4] |= (sp_digit)(a[3] << 28U); + a32[4] &= 0xffffffffL; + a32[5] = (sp_digit)(a[3] >> 4U) & 0xffffffffL; + a32[6] = (sp_digit)(a[3] >> 36U); + a32[6] |= (sp_digit)(a[4] << 16U); + a32[6] &= 0xffffffffL; + a32[7] = (sp_digit)(a[4] >> 16U) & 0xffffffffL; + + /* 1 1 0 -1 -1 -1 -1 0 */ + t[0] = 0 + a32[0] + a32[1] - a32[3] - a32[4] - a32[5] - a32[6]; + /* 0 1 1 0 -1 -1 -1 -1 */ + t[1] = 0 + a32[1] + a32[2] - a32[4] - a32[5] - a32[6] - a32[7]; + /* 0 0 1 1 0 -1 -1 -1 */ + t[2] = 0 + a32[2] + a32[3] - a32[5] - a32[6] - a32[7]; + /* -1 -1 0 2 2 1 0 -1 */ + t[3] = 0 - a32[0] - a32[1] + 2 * a32[3] + 2 * a32[4] + a32[5] - a32[7]; + /* 0 -1 -1 0 2 2 1 0 */ + t[4] = 0 - a32[1] - a32[2] + 2 * a32[4] + 2 * a32[5] + a32[6]; + /* 0 0 -1 -1 0 2 2 1 */ + t[5] = 0 - a32[2] - a32[3] + 2 * a32[5] + 2 * a32[6] + a32[7]; + /* -1 -1 0 0 0 1 3 2 */ + t[6] = 0 - a32[0] - a32[1] + a32[5] + 3 * a32[6] + 2 * a32[7]; + /* 1 0 -1 -1 -1 -1 0 3 */ + t[7] = 0 + a32[0] - a32[2] - a32[3] - a32[4] - a32[5] + 3 * a32[7]; + + t[1] += t[0] >> 32U; t[0] &= 0xffffffffL; + t[2] += t[1] >> 32U; t[1] &= 0xffffffffL; + t[3] += t[2] >> 32U; t[2] &= 0xffffffffL; + t[4] += t[3] >> 32U; t[3] &= 0xffffffffL; + t[5] += t[4] >> 32U; t[4] &= 0xffffffffL; + t[6] += t[5] >> 32U; t[5] &= 0xffffffffL; + t[7] += t[6] >> 32U; t[6] &= 0xffffffffL; + o = t[7] >> 32U; t[7] &= 0xffffffffL; + t[0] += o; + t[3] -= o; + t[6] -= o; + t[7] += o; + t[1] += t[0] >> 32U; t[0] &= 0xffffffffL; + t[2] += t[1] >> 32U; t[1] &= 0xffffffffL; + t[3] += t[2] >> 32U; t[2] &= 0xffffffffL; + t[4] += t[3] >> 32U; t[3] &= 0xffffffffL; + t[5] += t[4] >> 32U; t[4] &= 0xffffffffL; + t[6] += t[5] >> 32U; t[5] &= 0xffffffffL; + t[7] += t[6] >> 32U; t[6] &= 0xffffffffL; + + r[0] = t[0]; + r[0] |= t[1] << 32U; + r[0] &= 0xfffffffffffffLL; + r[1] = (t[1] >> 20); + r[1] |= t[2] << 12U; + r[1] |= t[3] << 44U; + r[1] &= 0xfffffffffffffLL; + r[2] = (t[3] >> 8); + r[2] |= t[4] << 24U; + r[2] &= 0xfffffffffffffLL; + r[3] = (t[4] >> 28); + r[3] |= t[5] << 4U; + r[3] |= t[6] << 36U; + r[3] &= 0xfffffffffffffLL; + r[4] = (t[6] >> 16); + r[4] |= t[7] << 16U; + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_ECC); + } +#endif + + return err; +} + #ifdef WOLFSSL_SP_SMALL /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Small implementation using add and double that is cache attack resistant but + * allocates memory rather than use large stacks. + * 256 adds and doubles. + * * r Resulting point. * g Point to multiply. * k Scalar to multiply by. @@ -14320,8 +14388,8 @@ static int sp_256_ecc_mulmod_5_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r, #endif /* WOLFSSL_SP_NONBLOCK */ -static int sp_256_ecc_mulmod_5(sp_point_256* r, const sp_point_256* g, const sp_digit* k, - int map, int ct, void* heap) +static int sp_256_ecc_mulmod_5(sp_point_256* r, const sp_point_256* g, + const sp_digit* k, int map, int ct, void* heap) { #ifdef WOLFSSL_SP_NO_MALLOC sp_point_256 t[3]; @@ -14332,7 +14400,8 @@ static int sp_256_ecc_mulmod_5(sp_point_256* r, const sp_point_256* g, const sp_ #endif sp_digit n; int i; - int c, y; + int c; + int y; int err = MP_OKAY; /* Implementatio is constant time. */ @@ -14461,7 +14530,8 @@ static void sp_256_cond_copy_5(sp_digit* r, const sp_digit* a, const sp_digit m) * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_5(sp_point_256* p, int n, sp_digit* t) +static void sp_256_proj_point_dbl_n_5(sp_point_256* p, int n, + sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*5; @@ -14549,8 +14619,8 @@ static void sp_256_proj_point_dbl_n_5(sp_point_256* p, int n, sp_digit* t) * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_store_5(sp_point_256* r, const sp_point_256* p, - int n, int m, sp_digit* t) +static void sp_256_proj_point_dbl_n_store_5(sp_point_256* r, + const sp_point_256* p, int n, int m, sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*5; @@ -14561,6 +14631,7 @@ static void sp_256_proj_point_dbl_n_store_5(sp_point_256* r, const sp_point_256* sp_digit* y = r[(1<x[i]; @@ -14577,7 +14648,10 @@ static void sp_256_proj_point_dbl_n_store_5(sp_point_256* r, const sp_point_256* /* W = Z^4 */ sp_256_mont_sqr_5(w, z, p256_mod, p256_mp_mod); sp_256_mont_sqr_5(w, w, p256_mod, p256_mp_mod); + j = m; for (i=1; i<=n; i++) { + j *= 2; + /* A = 3*(X^2 - W) */ sp_256_mont_sqr_5(t1, x, p256_mod, p256_mp_mod); sp_256_mont_sub_5(t1, t1, w, p256_mod); @@ -14585,14 +14659,14 @@ static void sp_256_proj_point_dbl_n_store_5(sp_point_256* r, const sp_point_256* /* B = X*Y^2 */ sp_256_mont_sqr_5(t2, y, p256_mod, p256_mp_mod); sp_256_mont_mul_5(b, t2, x, p256_mod, p256_mp_mod); - x = r[(1<y); + sp_256_norm_5(negy); sp_256_cond_copy_5(p->y, negy, (sp_digit)0 - v[i].neg); sp_256_proj_point_add_5(rt, rt, p, tmp); } @@ -15062,6 +15140,10 @@ static void sp_256_proj_to_affine_5(sp_point_256* a, sp_digit* t) } /* Generate the pre-computed table of points for the base point. + * + * width = 8 + * 256 entries + * 32 bits between * * a The base point. * table Place to store generated point data. @@ -15072,12 +15154,15 @@ static int sp_256_gen_stripe_table_5(const sp_point_256* a, sp_table_entry_256* table, sp_digit* tmp, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_point_256 td, s1d, s2d; + sp_point_256 td; + sp_point_256 s1d; + sp_point_256 s2d; #endif sp_point_256* t; sp_point_256* s1 = NULL; sp_point_256* s2 = NULL; - int i, j; + int i; + int j; int err; (void)heap; @@ -15184,8 +15269,10 @@ static void sp_256_get_entry_256_5(sp_point_256* r, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Implementation uses striping of bits. - * Choose bits 8 bits apart. + * Stripe implementation. + * Pre-generated: 2^0, 2^32, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) * * r Resulting point. * k Scalar to multiply by. @@ -15207,8 +15294,10 @@ static int sp_256_ecc_mulmod_stripe_5(sp_point_256* r, const sp_point_256* g, sp_point_256* rt; sp_point_256* p = NULL; sp_digit* t; - int i, j; - int y, x; + int i; + int j; + int y; + int x; int err; (void)g; @@ -15236,8 +15325,10 @@ static int sp_256_ecc_mulmod_stripe_5(sp_point_256* r, const sp_point_256* g, XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod)); y = 0; - for (j=0,x=31; j<8; j++,x+=32) { + x = 31; + for (j=0; j<8; j++) { y |= (int)(((k[x / 52] >> (x % 52)) & 1) << j); + x += 32; } #ifndef WC_NO_CACHE_RESISTANT if (ct) { @@ -15251,8 +15342,10 @@ static int sp_256_ecc_mulmod_stripe_5(sp_point_256* r, const sp_point_256* g, rt->infinity = !y; for (i=30; i>=0; i--) { y = 0; - for (j=0,x=i; j<8; j++,x+=32) { + x = i; + for (j=0; j<8; j++) { y |= (int)(((k[x / 52] >> (x % 52)) & 1) << j); + x += 32; } sp_256_proj_point_dbl_5(rt, rt, t); @@ -15294,16 +15387,25 @@ static int sp_256_ecc_mulmod_stripe_5(sp_point_256* r, const sp_point_256* g, #define FP_ENTRIES 16 #endif +/* Cache entry - holds precomputation tables for a point. */ typedef struct sp_cache_256_t { + /* X ordinate of point that table was generated from. */ sp_digit x[5]; + /* Y ordinate of point that table was generated from. */ sp_digit y[5]; + /* Precomputation table for point. */ sp_table_entry_256 table[256]; + /* Count of entries in table. */ uint32_t cnt; + /* Point and table set in entry. */ int set; } sp_cache_256_t; +/* Cache of tables. */ static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES]; +/* Index of last entry in cache. */ static THREAD_LS_T int sp_cache_256_last = -1; +/* Cache has been initialized. */ static THREAD_LS_T int sp_cache_256_inited = 0; #ifndef HAVE_THREAD_LS @@ -15311,9 +15413,15 @@ static THREAD_LS_T int sp_cache_256_inited = 0; static wolfSSL_Mutex sp_cache_256_lock; #endif +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache) { - int i, j; + int i; + int j; uint32_t least; if (sp_cache_256_inited == 0) { @@ -15430,8 +15538,8 @@ static int sp_256_ecc_mulmod_5(sp_point_256* r, const sp_point_256* g, const sp_ * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, - void* heap) +int sp_ecc_mulmod_256(const mp_int* km, const ecc_point* gm, ecc_point* r, + int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_256 p; @@ -15472,6 +15580,89 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, return err; } +/* Multiply the point by the scalar, add point a and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * p Point to multiply. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_add_256(const mp_int* km, const ecc_point* gm, + const ecc_point* am, int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_256 p; + sp_point_256 a; + sp_digit kd[5]; + sp_digit t[5 * 2 * 5]; +#endif + sp_point_256* point; + sp_point_256* addP = NULL; + sp_digit* k = NULL; + sp_digit* tmp = NULL; + int err = MP_OKAY; + + err = sp_256_point_new_5(heap, p, point); + if (err == MP_OKAY) { + err = sp_256_point_new_5(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (5 + 5 * 2 * 5), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 5; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_256_from_mp(k, 5, km); + sp_256_point_from_ecc_point_5(point, gm); + sp_256_point_from_ecc_point_5(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_5(addP->x, addP->x, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_5(addP->y, addP->y, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_5(addP->z, addP->z, p256_mod); + } + if (err == MP_OKAY) { + err = sp_256_ecc_mulmod_5(point, point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_256_proj_point_add_5(point, point, addP, tmp); + + if (map) { + sp_256_map_5(point, point, tmp); + } + + err = sp_256_point_to_ecc_point_5(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_256_point_free_5(addP, 0, heap); + sp_256_point_free_5(point, 0, heap); + + return err; +} + #ifdef WOLFSSL_SP_SMALL /* Multiply the base point of P256 by the scalar and return the result. * If map is true then convert result to affine coordinates. @@ -15490,6 +15681,10 @@ static int sp_256_ecc_mulmod_base_5(sp_point_256* r, const sp_digit* k, } #else +/* Striping precomputation table. + * 8 points combined into a table of 256 points. + * Distance of 32 between points. + */ static const sp_table_entry_256 p256_table[256] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -16774,6 +16969,11 @@ static const sp_table_entry_256 p256_table[256] = { /* Multiply the base point of P256 by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Stripe implementation. + * Pre-generated: 2^0, 2^32, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * * r Resulting point. * k Scalar to multiply by. * map Indicates whether to convert result to affine. @@ -16799,7 +16999,7 @@ static int sp_256_ecc_mulmod_base_5(sp_point_256* r, const sp_digit* k, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) +int sp_ecc_mulmod_base_256(const mp_int* km, ecc_point* r, int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_256 p; @@ -16840,6 +17040,87 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) return err; } +/* Multiply the base point of P256 by the scalar, add point a and return + * the result. If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_add_256(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_256 p; + sp_point_256 a; + sp_digit kd[5]; + sp_digit t[5 * 2 * 5]; +#endif + sp_point_256* point; + sp_point_256* addP = NULL; + sp_digit* tmp = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_256_point_new_5(heap, p, point); + if (err == MP_OKAY) { + err = sp_256_point_new_5(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (5 + 5 * 2 * 5), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 5; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_256_from_mp(k, 5, km); + sp_256_point_from_ecc_point_5(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_5(addP->x, addP->x, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_5(addP->y, addP->y, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_5(addP->z, addP->z, p256_mod); + } + if (err == MP_OKAY) { + err = sp_256_ecc_mulmod_base_5(point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_256_proj_point_add_5(point, point, addP, tmp); + + if (map) { + sp_256_map_5(point, point, tmp); + } + + err = sp_256_point_to_ecc_point_5(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_256_point_free_5(addP, 0, heap); + sp_256_point_free_5(point, 0, heap); + + return err; +} + #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \ defined(HAVE_ECC_VERIFY) /* Returns 1 if the number of zero. @@ -16853,7 +17134,7 @@ static int sp_256_iszero_5(const sp_digit* a) return (a[0] | a[1] | a[2] | a[3] | a[4]) == 0; } -#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN | HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ /* Add 1 to a. (a = a + 1) * * r A single precision integer. @@ -16874,7 +17155,8 @@ SP_NOINLINE static void sp_256_add_one_5(sp_digit* a) */ static void sp_256_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -17018,7 +17300,10 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) */ static void sp_256_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; for (i=0; i<4; i++) { r[i+1] += r[i] >> 52; @@ -17063,7 +17348,7 @@ static void sp_256_to_bin(sp_digit* r, byte* a) * returns BUFFER_E if the buffer is to small for output size, * MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, +int sp_ecc_secret_gen_256(const mp_int* priv, const ecc_point* pub, byte* out, word32* outLen, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) @@ -17158,7 +17443,9 @@ SP_NOINLINE static void sp_256_mul_d_5(sp_digit* r, const sp_digit* a, static WC_INLINE sp_digit sp_256_div_word_5(sp_digit d1, sp_digit d0, sp_digit dv) { - sp_digit d, r, t; + sp_digit d; + sp_digit r; + sp_digit t; /* All 52 bits from d1 and top 11 bits from d0. */ d = (d1 << 11) | (d0 >> 41); @@ -17203,24 +17490,28 @@ static WC_INLINE sp_digit sp_256_div_word_5(sp_digit d1, sp_digit d0, /* Divide d in a and put remainder into r (m*d + r = a) * m is not calculated as it is not needed at this time. * + * Large number of bits in last word. + * * a Number to be divided. * d Number to divide with. * m Multiplier result. * r Remainder from the division. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise. */ -static int sp_256_div_5(const sp_digit* a, const sp_digit* d, sp_digit* m, - sp_digit* r) +static int sp_256_div_5(const sp_digit* a, const sp_digit* d, + const sp_digit* m, sp_digit* r) { int i; #ifndef WOLFSSL_SP_DIV_64 int128_t d1; #endif - sp_digit dv, r1; + sp_digit dv; + sp_digit r1; #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* td; #else - sp_digit t1d[10], t2d[5 + 1]; + sp_digit t1d[10]; + sp_digit t2d[5 + 1]; #endif sp_digit* t1; sp_digit* t2; @@ -17248,17 +17539,15 @@ static int sp_256_div_5(const sp_digit* a, const sp_digit* d, sp_digit* m, dv = d[4]; XMEMCPY(t1, a, sizeof(*t1) * 2U * 5U); for (i=4; i>=0; i--) { - sp_digit hi; t1[5 + i] += t1[5 + i - 1] >> 52; t1[5 + i - 1] &= 0xfffffffffffffL; - hi = t1[5 + i] - (t1[5 + i] == dv); #ifndef WOLFSSL_SP_DIV_64 - d1 = hi; + d1 = t1[5 + i]; d1 <<= 52; d1 += t1[5 + i - 1]; r1 = (sp_digit)(d1 / dv); #else - r1 = sp_256_div_word_5(hi, t1[5 + i - 1], dv); + r1 = sp_256_div_word_5(t1[5 + i], t1[5 + i - 1], dv); #endif sp_256_mul_d_5(t2, d, r1); @@ -17279,7 +17568,7 @@ static int sp_256_div_5(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_256_mul_d_5(t2, d, r1); (void)sp_256_sub_5(t1, t1, t2); - XMEMCPY(r, t1, sizeof(*r) * 2U * 5U); + XMEMCPY(r, t1, sizeof(*r) * 10U); for (i=0; i<4; i++) { r[i+1] += r[i] >> 52; r[i] &= 0xfffffffffffffL; @@ -17319,7 +17608,7 @@ static const uint64_t p256_order_minus_2[4] = { }; #else /* The low half of the order-2 of the P256 curve. */ -static const uint64_t p256_order_low[2] = { +static const sp_int_digit p256_order_low[2] = { 0xf3b9cac2fc63254fU,0xbce6faada7179e84U }; #endif /* WOLFSSL_SP_SMALL */ @@ -17465,7 +17754,7 @@ static void sp_256_mont_inv_order_5(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6 */ for (i=127; i>=112; i--) { sp_256_mont_sqr_order_5(t2, t2); - if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { + if ((p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { sp_256_mont_mul_order_5(t2, t2, a); } } @@ -17475,7 +17764,7 @@ static void sp_256_mont_inv_order_5(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84 */ for (i=107; i>=64; i--) { sp_256_mont_sqr_order_5(t2, t2); - if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { + if ((p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { sp_256_mont_mul_order_5(t2, t2, a); } } @@ -17485,7 +17774,7 @@ static void sp_256_mont_inv_order_5(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2 */ for (i=59; i>=32; i--) { sp_256_mont_sqr_order_5(t2, t2); - if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { + if ((p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { sp_256_mont_mul_order_5(t2, t2, a); } } @@ -17495,7 +17784,7 @@ static void sp_256_mont_inv_order_5(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254 */ for (i=27; i>=0; i--) { sp_256_mont_sqr_order_5(t2, t2); - if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { + if ((p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { sp_256_mont_mul_order_5(t2, t2, a); } } @@ -17506,12 +17795,63 @@ static void sp_256_mont_inv_order_5(sp_digit* r, const sp_digit* a, #endif /* WOLFSSL_SP_SMALL */ } -#endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ #ifdef HAVE_ECC_SIGN #ifndef SP_ECC_MAX_SIG_GEN #define SP_ECC_MAX_SIG_GEN 64 #endif +/* Calculate second signature value S from R, k and private value. + * + * s = (r * x + e) / k + * + * s Signature value. + * r First signature value. + * k Ephemeral private key. + * x Private key as a number. + * e Hash of message as a number. + * tmp Temporary storage for intermediate numbers. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_256_calc_s_5(sp_digit* s, const sp_digit* r, sp_digit* k, + sp_digit* x, const sp_digit* e, sp_digit* tmp) +{ + int err; + sp_digit carry; + int64_t c; + sp_digit* kInv = k; + + /* Conv k to Montgomery form (mod order) */ + sp_256_mul_5(k, k, p256_norm_order); + err = sp_256_mod_5(k, k, p256_order); + if (err == MP_OKAY) { + sp_256_norm_5(k); + + /* kInv = 1/k mod order */ + sp_256_mont_inv_order_5(kInv, k, tmp); + sp_256_norm_5(kInv); + + /* s = r * x + e */ + sp_256_mul_5(x, x, r); + err = sp_256_mod_5(x, x, p256_order); + } + if (err == MP_OKAY) { + sp_256_norm_5(x); + carry = sp_256_add_5(s, e, x); + sp_256_cond_sub_5(s, s, p256_order, 0 - carry); + sp_256_norm_5(s); + c = sp_256_cmp_5(s, p256_order); + sp_256_cond_sub_5(s, s, p256_order, 0L - (sp_digit)(c >= 0)); + sp_256_norm_5(s); + + /* s = s * k^-1 mod order */ + sp_256_mont_mul_order_5(s, s, kInv); + sp_256_norm_5(s); + } + + return err; +} + /* Sign the hash using the private key. * e = [hash, 256 bits] from binary * r = (k.G)->x mod order @@ -17546,8 +17886,8 @@ typedef struct sp_ecc_sign_256_ctx { int i; } sp_ecc_sign_256_ctx; -int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, + mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_sign_256_ctx* ctx = (sp_ecc_sign_256_ctx*)sp_ctx->data; @@ -17687,8 +18027,8 @@ int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, W } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, + const mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -17706,11 +18046,9 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit* r = NULL; sp_digit* tmp = NULL; sp_point_256* point = NULL; - sp_digit carry; sp_digit* s = NULL; - sp_digit* kInv = NULL; - int err = MP_OKAY; int64_t c; + int err = MP_OKAY; int i; (void)heap; @@ -17741,7 +18079,6 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, tmp = td; #endif s = e; - kInv = k; if (hashLen > 32U) { hashLen = 32U; @@ -17749,8 +18086,6 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, } for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) { - sp_256_from_mp(x, 5, priv); - /* New random point. */ if (km == NULL || mp_iszero(km)) { err = sp_256_ecc_gen_k_5(rng, k); @@ -17760,7 +18095,7 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, mp_zero(km); } if (err == MP_OKAY) { - err = sp_256_ecc_mulmod_base_5(point, k, 1, 1, NULL); + err = sp_256_ecc_mulmod_base_5(point, k, 1, 1, heap); } if (err == MP_OKAY) { @@ -17771,38 +18106,15 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_256_cond_sub_5(r, r, p256_order, 0L - (sp_digit)(c >= 0)); sp_256_norm_5(r); - /* Conv k to Montgomery form (mod order) */ - sp_256_mul_5(k, k, p256_norm_order); - err = sp_256_mod_5(k, k, p256_order); - } - if (err == MP_OKAY) { - sp_256_norm_5(k); - /* kInv = 1/k mod order */ - sp_256_mont_inv_order_5(kInv, k, tmp); - sp_256_norm_5(kInv); - - /* s = r * x + e */ - sp_256_mul_5(x, x, r); - err = sp_256_mod_5(x, x, p256_order); - } - if (err == MP_OKAY) { - sp_256_norm_5(x); + sp_256_from_mp(x, 5, priv); sp_256_from_bin(e, 5, hash, (int)hashLen); - carry = sp_256_add_5(s, e, x); - sp_256_cond_sub_5(s, s, p256_order, 0 - carry); - sp_256_norm_5(s); - c = sp_256_cmp_5(s, p256_order); - sp_256_cond_sub_5(s, s, p256_order, 0L - (sp_digit)(c >= 0)); - sp_256_norm_5(s); - /* s = s * k^-1 mod order */ - sp_256_mont_mul_order_5(s, s, kInv); - sp_256_norm_5(s); + err = sp_256_calc_s_5(s, r, k, x, e, tmp); + } - /* Check that signature is usable. */ - if (sp_256_iszero_5(s) == 0) { - break; - } + /* Check that signature is usable. */ + if ((err == MP_OKAY) && (sp_256_iszero_5(s) == 0)) { + break; } #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP i = 1; @@ -17830,7 +18142,6 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, XMEMSET(x, 0, sizeof(sp_digit) * 2U * 5U); XMEMSET(k, 0, sizeof(sp_digit) * 2U * 5U); XMEMSET(r, 0, sizeof(sp_digit) * 2U * 5U); - XMEMSET(r, 0, sizeof(sp_digit) * 2U * 5U); XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 5U); #endif sp_256_point_free_5(point, 1, heap); @@ -18000,6 +18311,93 @@ static int sp_256_mod_inv_5(sp_digit* r, const sp_digit* a, const sp_digit* m) } #endif /* WOLFSSL_SP_SMALL */ + +/* Add point p1 into point p2. Handles p1 == p2 and result at infinity. + * + * p1 First point to add and holds result. + * p2 Second point to add. + * tmp Temporary storage for intermediate numbers. + */ +static void sp_256_add_points_5(sp_point_256* p1, const sp_point_256* p2, + sp_digit* tmp) +{ + + sp_256_proj_point_add_5(p1, p1, p2, tmp); + if (sp_256_iszero_5(p1->z)) { + if (sp_256_iszero_5(p1->x) && sp_256_iszero_5(p1->y)) { + sp_256_proj_point_dbl_5(p1, p2, tmp); + } + else { + /* Y ordinate is not used from here - don't set. */ + p1->x[0] = 0; + p1->x[1] = 0; + p1->x[2] = 0; + p1->x[3] = 0; + p1->x[4] = 0; + XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod)); + } + } +} + +/* Calculate the verification point: [e/s]G + [r/s]Q + * + * p1 Calculated point. + * p2 Public point and temporary. + * s Second part of signature as a number. + * u1 Temporary number. + * u2 Temproray number. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_256_calc_vfy_point_5(sp_point_256* p1, sp_point_256* p2, + sp_digit* s, sp_digit* u1, sp_digit* u2, sp_digit* tmp, void* heap) +{ + int err; + +#ifndef WOLFSSL_SP_SMALL + { + sp_256_mod_inv_5(s, s, p256_order); + } +#endif /* !WOLFSSL_SP_SMALL */ + { + sp_256_mul_5(s, s, p256_norm_order); + } + err = sp_256_mod_5(s, s, p256_order); + if (err == MP_OKAY) { + sp_256_norm_5(s); +#ifdef WOLFSSL_SP_SMALL + { + sp_256_mont_inv_order_5(s, s, tmp); + sp_256_mont_mul_order_5(u1, u1, s); + sp_256_mont_mul_order_5(u2, u2, s); + } + +#else + { + sp_256_mont_mul_order_5(u1, u1, s); + sp_256_mont_mul_order_5(u2, u2, s); + } + +#endif /* WOLFSSL_SP_SMALL */ + err = sp_256_ecc_mulmod_base_5(p1, u1, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_256_iszero_5(p1->z)) { + p1->infinity = 1; + } + if (err == MP_OKAY) { + err = sp_256_ecc_mulmod_5(p2, p2, u2, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_256_iszero_5(p2->z)) { + p2->infinity = 1; + } + + if (err == MP_OKAY) { + sp_256_add_points_5(p1, p2, tmp); + } + + return err; +} + #ifdef HAVE_ECC_VERIFY /* Verify the signature values with the hash and public key. * e = Truncate(hash, 256) @@ -18018,8 +18416,7 @@ static int sp_256_mod_inv_5(sp_digit* r, const sp_digit* a, const sp_digit* m) * rm First part of result as an mp_int. * sm Sirst part of result as an mp_int. * heap Heap to use for allocation. - * returns RNG failures, MEMORY_E when memory allocation fails and - * MP_OKAY on success. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ #ifdef WOLFSSL_SP_NONBLOCK typedef struct sp_ecc_verify_256_ctx { @@ -18038,8 +18435,9 @@ typedef struct sp_ecc_verify_256_ctx { sp_point_256 p2; } sp_ecc_verify_256_ctx; -int sp_ecc_verify_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, + word32 hashLen, const mp_int* pX, const mp_int* pY, const mp_int* pZ, + const mp_int* r, const mp_int* sm, int* res, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_verify_256_ctx* ctx = (sp_ecc_verify_256_ctx*)sp_ctx->data; @@ -18193,8 +18591,9 @@ int sp_ecc_verify_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_256(const byte* hash, word32 hashLen, const mp_int* pX, + const mp_int* pY, const mp_int* pZ, const mp_int* r, const mp_int* sm, + int* res, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -18213,7 +18612,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_point_256* p1; sp_point_256* p2 = NULL; sp_digit carry; - int64_t c; + int64_t c = 0; int err; err = sp_256_point_new_5(heap, p1d, p1); @@ -18254,63 +18653,9 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_256_from_mp(p2->y, 5, pY); sp_256_from_mp(p2->z, 5, pZ); -#ifndef WOLFSSL_SP_SMALL - { - sp_256_mod_inv_5(s, s, p256_order); - } -#endif /* !WOLFSSL_SP_SMALL */ - { - sp_256_mul_5(s, s, p256_norm_order); - } - err = sp_256_mod_5(s, s, p256_order); + err = sp_256_calc_vfy_point_5(p1, p2, s, u1, u2, tmp, heap); } if (err == MP_OKAY) { - sp_256_norm_5(s); -#ifdef WOLFSSL_SP_SMALL - { - sp_256_mont_inv_order_5(s, s, tmp); - sp_256_mont_mul_order_5(u1, u1, s); - sp_256_mont_mul_order_5(u2, u2, s); - } - -#else - { - sp_256_mont_mul_order_5(u1, u1, s); - sp_256_mont_mul_order_5(u2, u2, s); - } - -#endif /* WOLFSSL_SP_SMALL */ - err = sp_256_ecc_mulmod_base_5(p1, u1, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_256_iszero_5(p1->z)) { - p1->infinity = 1; - } - if (err == MP_OKAY) { - err = sp_256_ecc_mulmod_5(p2, p2, u2, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_256_iszero_5(p2->z)) { - p2->infinity = 1; - } - - if (err == MP_OKAY) { - { - sp_256_proj_point_add_5(p1, p1, p2, tmp); - if (sp_256_iszero_5(p1->z)) { - if (sp_256_iszero_5(p1->x) && sp_256_iszero_5(p1->y)) { - sp_256_proj_point_dbl_5(p1, p2, tmp); - } - else { - /* Y ordinate is not used from here - don't set. */ - p1->x[0] = 0; - p1->x[1] = 0; - p1->x[2] = 0; - p1->x[3] = 0; - p1->x[4] = 0; - XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod)); - } - } - } - /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */ /* Reload r and convert to Montgomery form. */ sp_256_from_mp(u2, 5, r); @@ -18332,16 +18677,16 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, /* Compare with mod and if greater or equal then not valid. */ c = sp_256_cmp_5(u2, p256_mod); - if (c < 0) { - /* Convert to Montogomery form */ - err = sp_256_mod_mul_norm_5(u2, u2, p256_mod); - if (err == MP_OKAY) { - /* u1 = (r + 1*order).z'.z' mod prime */ - sp_256_mont_mul_5(u1, u2, p1->z, p256_mod, - p256_mp_mod); - *res = (int)(sp_256_cmp_5(p1->x, u1) == 0); - } - } + } + } + if ((*res == 0) && (c < 0)) { + /* Convert to Montogomery form */ + err = sp_256_mod_mul_norm_5(u2, u2, p256_mod); + if (err == MP_OKAY) { + /* u1 = (r + 1*order).z'.z' mod prime */ + sp_256_mont_mul_5(u1, u2, p1->z, p256_mod, + p256_mp_mod); + *res = (sp_256_cmp_5(p1->x, u1) == 0); } } } @@ -18365,7 +18710,8 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -static int sp_256_ecc_is_point_5(sp_point_256* point, void* heap) +static int sp_256_ecc_is_point_5(const sp_point_256* point, + void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -18428,7 +18774,7 @@ static int sp_256_ecc_is_point_5(sp_point_256* point, void* heap) * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) +int sp_ecc_is_point_256(const mp_int* pX, const mp_int* pY) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_256 pubd; @@ -18462,7 +18808,8 @@ int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and * MP_OKAY otherwise. */ -int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) +int sp_ecc_check_key_256(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit privd[5]; @@ -18516,12 +18863,11 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) } } - if (err == MP_OKAY) { - /* Check range of X and Y */ - if (sp_256_cmp_5(pub->x, p256_mod) >= 0 || - sp_256_cmp_5(pub->y, p256_mod) >= 0) { - err = ECC_OUT_OF_RANGE_E; - } + /* Check range of X and Y */ + if ((err == MP_OKAY) && + ((sp_256_cmp_5(pub->x, p256_mod) >= 0) || + (sp_256_cmp_5(pub->y, p256_mod) >= 0))) { + err = ECC_OUT_OF_RANGE_E; } if (err == MP_OKAY) { @@ -18533,12 +18879,10 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Point * order = infinity */ err = sp_256_ecc_mulmod_5(p, pub, p256_order, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is infinity */ - if ((sp_256_iszero_5(p->x) == 0) || - (sp_256_iszero_5(p->y) == 0)) { - err = ECC_INF_E; - } + /* Check result is infinity */ + if ((err == MP_OKAY) && ((sp_256_iszero_5(p->x) == 0) || + (sp_256_iszero_5(p->y) == 0))) { + err = ECC_INF_E; } if (privm) { @@ -18546,12 +18890,11 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Base * private = point */ err = sp_256_ecc_mulmod_base_5(p, priv, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is public key */ - if (sp_256_cmp_5(p->x, pub->x) != 0 || - sp_256_cmp_5(p->y, pub->y) != 0) { - err = ECC_PRIV_KEY_E; - } + /* Check result is public key */ + if ((err == MP_OKAY) && + ((sp_256_cmp_5(p->x, pub->x) != 0) || + (sp_256_cmp_5(p->y, pub->y) != 0))) { + err = ECC_PRIV_KEY_E; } } @@ -18741,7 +19084,7 @@ int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ) sp_256_from_mp(p->y, 5, pY); sp_256_from_mp(p->z, 5, pZ); - sp_256_map_5(p, p, tmp); + sp_256_map_5(p, p, tmp); } if (err == MP_OKAY) { @@ -18921,9 +19264,13 @@ int sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym) /* Point structure to use. */ typedef struct sp_point_384 { + /* X ordinate of point. */ sp_digit x[2 * 7]; + /* Y ordinate of point. */ sp_digit y[2 * 7]; + /* Z ordinate of point. */ sp_digit z[2 * 7]; + /* Indicates point is at infinity. */ int infinity; } sp_point_384; @@ -18961,26 +19308,26 @@ static const sp_digit p384_norm_order[7] = { #endif #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) /* The Montogmery multiplier for order of the curve P384. */ -static sp_digit p384_mp_order = 0x546089e88fdc45l; +static sp_digit p384_mp_order = 0x546089e88fdc45L; #endif /* The base point of curve P384. */ static const sp_point_384 p384_base = { /* X ordinate */ { - 0x545e3872760ab7L,0x64bb7eaa52d874L,0x020950a8e1540bL, - 0x5d3cdcc2cfba0fL,0x0ad746e1d3b628L,0x26f1d638e3de64L,0x2aa1f288afa2c1L, + 0x545e3872760ab7L,0x64bb7eaa52d874L,0x020950a8e1540bL,0x5d3cdcc2cfba0fL, + 0x0ad746e1d3b628L,0x26f1d638e3de64L,0x2aa1f288afa2c1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L }, /* Y ordinate */ { - 0x431d7c90ea0e5fL,0x639c3afd033af4L,0x4ed7c2e3002982L, - 0x44d0a3e74ed188L,0x2dc29f8f41dbd2L,0x0debb3d317f252L,0x0d85f792a5898bL, + 0x431d7c90ea0e5fL,0x639c3afd033af4L,0x4ed7c2e3002982L,0x44d0a3e74ed188L, + 0x2dc29f8f41dbd2L,0x0debb3d317f252L,0x0d85f792a5898bL, 0L, 0L, 0L, 0L, 0L, 0L, 0L }, /* Z ordinate */ { - 0x00000000000001L,0x00000000000000L,0x00000000000000L, - 0x00000000000000L,0x00000000000000L,0x00000000000000L,0x00000000000000L, + 0x00000000000001L,0x00000000000000L,0x00000000000000L,0x00000000000000L, + 0x00000000000000L,0x00000000000000L,0x00000000000000L, 0L, 0L, 0L, 0L, 0L, 0L, 0L }, /* infinity */ @@ -18993,384 +19340,6 @@ static const sp_digit p384_b[7] = { }; #endif -static int sp_384_point_new_ex_7(void* heap, sp_point_384* sp, sp_point_384** p) -{ - int ret = MP_OKAY; - (void)heap; -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - (void)sp; - *p = (sp_point_384*)XMALLOC(sizeof(sp_point_384), heap, DYNAMIC_TYPE_ECC); -#else - *p = sp; -#endif - if (*p == NULL) { - ret = MEMORY_E; - } - return ret; -} - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) -/* Allocate memory for point and return error. */ -#define sp_384_point_new_7(heap, sp, p) sp_384_point_new_ex_7((heap), NULL, &(p)) -#else -/* Set pointer to data and return no error. */ -#define sp_384_point_new_7(heap, sp, p) sp_384_point_new_ex_7((heap), &(sp), &(p)) -#endif - - -static void sp_384_point_free_7(sp_point_384* p, int clear, void* heap) -{ -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) -/* If valid pointer then clear point data if requested and free data. */ - if (p != NULL) { - if (clear != 0) { - XMEMSET(p, 0, sizeof(*p)); - } - XFREE(p, heap, DYNAMIC_TYPE_ECC); - } -#else -/* Clear point data if requested. */ - if (clear != 0) { - XMEMSET(p, 0, sizeof(*p)); - } -#endif - (void)heap; -} - -/* Multiply a number by Montogmery normalizer mod modulus (prime). - * - * r The resulting Montgomery form number. - * a The number to convert. - * m The modulus (prime). - * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. - */ -static int sp_384_mod_mul_norm_7(sp_digit* r, const sp_digit* a, const sp_digit* m) -{ -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - int64_t* td; -#else - int64_t td[12]; - int64_t a32d[12]; -#endif - int64_t* t; - int64_t* a32; - int64_t o; - int err = MP_OKAY; - - (void)m; - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - td = (int64_t*)XMALLOC(sizeof(int64_t) * 2 * 12, NULL, DYNAMIC_TYPE_ECC); - if (td == NULL) { - err = MEMORY_E; - } -#endif - - if (err == MP_OKAY) { -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - t = td; - a32 = td + 12; -#else - t = td; - a32 = a32d; -#endif - - a32[0] = (sp_digit)(a[0]) & 0xffffffffL; - a32[1] = (sp_digit)(a[0] >> 32U); - a32[1] |= (sp_digit)(a[1] << 23U); - a32[1] &= 0xffffffffL; - a32[2] = (sp_digit)(a[1] >> 9U) & 0xffffffffL; - a32[3] = (sp_digit)(a[1] >> 41U); - a32[3] |= (sp_digit)(a[2] << 14U); - a32[3] &= 0xffffffffL; - a32[4] = (sp_digit)(a[2] >> 18U) & 0xffffffffL; - a32[5] = (sp_digit)(a[2] >> 50U); - a32[5] |= (sp_digit)(a[3] << 5U); - a32[5] &= 0xffffffffL; - a32[6] = (sp_digit)(a[3] >> 27U); - a32[6] |= (sp_digit)(a[4] << 28U); - a32[6] &= 0xffffffffL; - a32[7] = (sp_digit)(a[4] >> 4U) & 0xffffffffL; - a32[8] = (sp_digit)(a[4] >> 36U); - a32[8] |= (sp_digit)(a[5] << 19U); - a32[8] &= 0xffffffffL; - a32[9] = (sp_digit)(a[5] >> 13U) & 0xffffffffL; - a32[10] = (sp_digit)(a[5] >> 45U); - a32[10] |= (sp_digit)(a[6] << 10U); - a32[10] &= 0xffffffffL; - a32[11] = (sp_digit)(a[6] >> 22U) & 0xffffffffL; - - /* 1 0 0 0 0 0 0 0 1 1 0 -1 */ - t[0] = 0 + a32[0] + a32[8] + a32[9] - a32[11]; - /* -1 1 0 0 0 0 0 0 -1 0 1 1 */ - t[1] = 0 - a32[0] + a32[1] - a32[8] + a32[10] + a32[11]; - /* 0 -1 1 0 0 0 0 0 0 -1 0 1 */ - t[2] = 0 - a32[1] + a32[2] - a32[9] + a32[11]; - /* 1 0 -1 1 0 0 0 0 1 1 -1 -1 */ - t[3] = 0 + a32[0] - a32[2] + a32[3] + a32[8] + a32[9] - a32[10] - a32[11]; - /* 1 1 0 -1 1 0 0 0 1 2 1 -2 */ - t[4] = 0 + a32[0] + a32[1] - a32[3] + a32[4] + a32[8] + 2 * a32[9] + a32[10] - 2 * a32[11]; - /* 0 1 1 0 -1 1 0 0 0 1 2 1 */ - t[5] = 0 + a32[1] + a32[2] - a32[4] + a32[5] + a32[9] + 2 * a32[10] + a32[11]; - /* 0 0 1 1 0 -1 1 0 0 0 1 2 */ - t[6] = 0 + a32[2] + a32[3] - a32[5] + a32[6] + a32[10] + 2 * a32[11]; - /* 0 0 0 1 1 0 -1 1 0 0 0 1 */ - t[7] = 0 + a32[3] + a32[4] - a32[6] + a32[7] + a32[11]; - /* 0 0 0 0 1 1 0 -1 1 0 0 0 */ - t[8] = 0 + a32[4] + a32[5] - a32[7] + a32[8]; - /* 0 0 0 0 0 1 1 0 -1 1 0 0 */ - t[9] = 0 + a32[5] + a32[6] - a32[8] + a32[9]; - /* 0 0 0 0 0 0 1 1 0 -1 1 0 */ - t[10] = 0 + a32[6] + a32[7] - a32[9] + a32[10]; - /* 0 0 0 0 0 0 0 1 1 0 -1 1 */ - t[11] = 0 + a32[7] + a32[8] - a32[10] + a32[11]; - - t[1] += t[0] >> 32; t[0] &= 0xffffffff; - t[2] += t[1] >> 32; t[1] &= 0xffffffff; - t[3] += t[2] >> 32; t[2] &= 0xffffffff; - t[4] += t[3] >> 32; t[3] &= 0xffffffff; - t[5] += t[4] >> 32; t[4] &= 0xffffffff; - t[6] += t[5] >> 32; t[5] &= 0xffffffff; - t[7] += t[6] >> 32; t[6] &= 0xffffffff; - t[8] += t[7] >> 32; t[7] &= 0xffffffff; - t[9] += t[8] >> 32; t[8] &= 0xffffffff; - t[10] += t[9] >> 32; t[9] &= 0xffffffff; - t[11] += t[10] >> 32; t[10] &= 0xffffffff; - o = t[11] >> 32; t[11] &= 0xffffffff; - t[0] += o; - t[1] -= o; - t[3] += o; - t[4] += o; - t[1] += t[0] >> 32; t[0] &= 0xffffffff; - t[2] += t[1] >> 32; t[1] &= 0xffffffff; - t[3] += t[2] >> 32; t[2] &= 0xffffffff; - t[4] += t[3] >> 32; t[3] &= 0xffffffff; - t[5] += t[4] >> 32; t[4] &= 0xffffffff; - t[6] += t[5] >> 32; t[5] &= 0xffffffff; - t[7] += t[6] >> 32; t[6] &= 0xffffffff; - t[8] += t[7] >> 32; t[7] &= 0xffffffff; - t[9] += t[8] >> 32; t[8] &= 0xffffffff; - t[10] += t[9] >> 32; t[9] &= 0xffffffff; - t[11] += t[10] >> 32; t[10] &= 0xffffffff; - - r[0] = t[0]; - r[0] |= t[1] << 32U; - r[0] &= 0x7fffffffffffffLL; - r[1] = (sp_digit)(t[1] >> 23); - r[1] |= t[2] << 9U; - r[1] |= t[3] << 41U; - r[1] &= 0x7fffffffffffffLL; - r[2] = (sp_digit)(t[3] >> 14); - r[2] |= t[4] << 18U; - r[2] |= t[5] << 50U; - r[2] &= 0x7fffffffffffffLL; - r[3] = (sp_digit)(t[5] >> 5); - r[3] |= t[6] << 27U; - r[3] &= 0x7fffffffffffffLL; - r[4] = (sp_digit)(t[6] >> 28); - r[4] |= t[7] << 4U; - r[4] |= t[8] << 36U; - r[4] &= 0x7fffffffffffffLL; - r[5] = (sp_digit)(t[8] >> 19); - r[5] |= t[9] << 13U; - r[5] |= t[10] << 45U; - r[5] &= 0x7fffffffffffffLL; - r[6] = (sp_digit)(t[10] >> 10); - r[6] |= t[11] << 22U; - } - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - if (td != NULL) - XFREE(td, NULL, DYNAMIC_TYPE_ECC); -#endif - - return err; -} - -/* Convert an mp_int to an array of sp_digit. - * - * r A single precision integer. - * size Maximum number of bytes to convert - * a A multi-precision integer. - */ -static void sp_384_from_mp(sp_digit* r, int size, const mp_int* a) -{ -#if DIGIT_BIT == 55 - int j; - - XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); - - for (j = a->used; j < size; j++) { - r[j] = 0; - } -#elif DIGIT_BIT > 55 - int i, j = 0; - word32 s = 0; - - r[0] = 0; - for (i = 0; i < a->used && j < size; i++) { - r[j] |= ((sp_digit)a->dp[i] << s); - r[j] &= 0x7fffffffffffffL; - s = 55U - s; - if (j + 1 >= size) { - break; - } - /* lint allow cast of mismatch word32 and mp_digit */ - r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ - while ((s + 55U) <= (word32)DIGIT_BIT) { - s += 55U; - r[j] &= 0x7fffffffffffffL; - if (j + 1 >= size) { - break; - } - if (s < (word32)DIGIT_BIT) { - /* lint allow cast of mismatch word32 and mp_digit */ - r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ - } - else { - r[++j] = 0L; - } - } - s = (word32)DIGIT_BIT - s; - } - - for (j++; j < size; j++) { - r[j] = 0; - } -#else - int i, j = 0, s = 0; - - r[0] = 0; - for (i = 0; i < a->used && j < size; i++) { - r[j] |= ((sp_digit)a->dp[i]) << s; - if (s + DIGIT_BIT >= 55) { - r[j] &= 0x7fffffffffffffL; - if (j + 1 >= size) { - break; - } - s = 55 - s; - if (s == DIGIT_BIT) { - r[++j] = 0; - s = 0; - } - else { - r[++j] = a->dp[i] >> s; - s = DIGIT_BIT - s; - } - } - else { - s += DIGIT_BIT; - } - } - - for (j++; j < size; j++) { - r[j] = 0; - } -#endif -} - -/* Convert a point of type ecc_point to type sp_point_384. - * - * p Point of type sp_point_384 (result). - * pm Point of type ecc_point. - */ -static void sp_384_point_from_ecc_point_7(sp_point_384* p, const ecc_point* pm) -{ - XMEMSET(p->x, 0, sizeof(p->x)); - XMEMSET(p->y, 0, sizeof(p->y)); - XMEMSET(p->z, 0, sizeof(p->z)); - sp_384_from_mp(p->x, 7, pm->x); - sp_384_from_mp(p->y, 7, pm->y); - sp_384_from_mp(p->z, 7, pm->z); - p->infinity = 0; -} - -/* Convert an array of sp_digit to an mp_int. - * - * a A single precision integer. - * r A multi-precision integer. - */ -static int sp_384_to_mp(const sp_digit* a, mp_int* r) -{ - int err; - - err = mp_grow(r, (384 + DIGIT_BIT - 1) / DIGIT_BIT); - if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ -#if DIGIT_BIT == 55 - XMEMCPY(r->dp, a, sizeof(sp_digit) * 7); - r->used = 7; - mp_clamp(r); -#elif DIGIT_BIT < 55 - int i, j = 0, s = 0; - - r->dp[0] = 0; - for (i = 0; i < 7; i++) { - r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; - s = DIGIT_BIT - s; - r->dp[++j] = (mp_digit)(a[i] >> s); - while (s + DIGIT_BIT <= 55) { - s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; - if (s == SP_WORD_SIZE) { - r->dp[j] = 0; - } - else { - r->dp[j] = (mp_digit)(a[i] >> s); - } - } - s = 55 - s; - } - r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; - mp_clamp(r); -#else - int i, j = 0, s = 0; - - r->dp[0] = 0; - for (i = 0; i < 7; i++) { - r->dp[j] |= ((mp_digit)a[i]) << s; - if (s + 55 >= DIGIT_BIT) { - #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; - #endif - s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; - s = 55 - s; - } - else { - s += 55; - } - } - r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; - mp_clamp(r); -#endif - } - - return err; -} - -/* Convert a point of type sp_point_384 to type ecc_point. - * - * p Point of type sp_point_384. - * pm Point of type ecc_point (result). - * returns MEMORY_E when allocation of memory in ecc_point fails otherwise - * MP_OKAY. - */ -static int sp_384_point_to_ecc_point_7(const sp_point_384* p, ecc_point* pm) -{ - int err; - - err = sp_384_to_mp(p->x, pm->x); - if (err == MP_OKAY) { - err = sp_384_to_mp(p->y, pm->y); - } - if (err == MP_OKAY) { - err = sp_384_to_mp(p->z, pm->z); - } - - return err; -} - #ifdef WOLFSSL_SP_SMALL /* Multiply a and b into r. (r = a * b) * @@ -19381,7 +19350,9 @@ static int sp_384_point_to_ecc_point_7(const sp_point_384* p, ecc_point* pm) SP_NOINLINE static void sp_384_mul_7(sp_digit* r, const sp_digit* a, const sp_digit* b) { - int i, j, k; + int i; + int j; + int k; int128_t c; c = ((int128_t)a[6]) * b[6]; @@ -19483,6 +19454,430 @@ SP_NOINLINE static void sp_384_mul_7(sp_digit* r, const sp_digit* a, } #endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_384_sqr_7(sp_digit* r, const sp_digit* a) +{ + int i; + int j; + int k; + int128_t c; + + c = ((int128_t)a[6]) * a[6]; + r[13] = (sp_digit)(c >> 55); + c = (c & 0x7fffffffffffffL) << 55; + for (k = 11; k >= 0; k--) { + for (i = 6; i >= 0; i--) { + j = k - i; + if (j >= 7 || i <= j) { + break; + } + if (j < 0) { + continue; + } + + c += ((int128_t)a[i]) * a[j] * 2; + } + if (i == j) { + c += ((int128_t)a[i]) * a[i]; + } + + r[k + 2] += (sp_digit)(c >> 110); + r[k + 1] = (sp_digit)((c >> 55) & 0x7fffffffffffffL); + c = (c & 0x7fffffffffffffL) << 55; + } + r[0] = (sp_digit)(c >> 55); +} + +#else +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_384_sqr_7(sp_digit* r, const sp_digit* a) +{ + int128_t t0 = ((int128_t)a[ 0]) * a[ 0]; + int128_t t1 = (((int128_t)a[ 0]) * a[ 1]) * 2; + int128_t t2 = (((int128_t)a[ 0]) * a[ 2]) * 2 + + ((int128_t)a[ 1]) * a[ 1]; + int128_t t3 = (((int128_t)a[ 0]) * a[ 3] + + ((int128_t)a[ 1]) * a[ 2]) * 2; + int128_t t4 = (((int128_t)a[ 0]) * a[ 4] + + ((int128_t)a[ 1]) * a[ 3]) * 2 + + ((int128_t)a[ 2]) * a[ 2]; + int128_t t5 = (((int128_t)a[ 0]) * a[ 5] + + ((int128_t)a[ 1]) * a[ 4] + + ((int128_t)a[ 2]) * a[ 3]) * 2; + int128_t t6 = (((int128_t)a[ 0]) * a[ 6] + + ((int128_t)a[ 1]) * a[ 5] + + ((int128_t)a[ 2]) * a[ 4]) * 2 + + ((int128_t)a[ 3]) * a[ 3]; + int128_t t7 = (((int128_t)a[ 1]) * a[ 6] + + ((int128_t)a[ 2]) * a[ 5] + + ((int128_t)a[ 3]) * a[ 4]) * 2; + int128_t t8 = (((int128_t)a[ 2]) * a[ 6] + + ((int128_t)a[ 3]) * a[ 5]) * 2 + + ((int128_t)a[ 4]) * a[ 4]; + int128_t t9 = (((int128_t)a[ 3]) * a[ 6] + + ((int128_t)a[ 4]) * a[ 5]) * 2; + int128_t t10 = (((int128_t)a[ 4]) * a[ 6]) * 2 + + ((int128_t)a[ 5]) * a[ 5]; + int128_t t11 = (((int128_t)a[ 5]) * a[ 6]) * 2; + int128_t t12 = ((int128_t)a[ 6]) * a[ 6]; + + t1 += t0 >> 55; r[ 0] = t0 & 0x7fffffffffffffL; + t2 += t1 >> 55; r[ 1] = t1 & 0x7fffffffffffffL; + t3 += t2 >> 55; r[ 2] = t2 & 0x7fffffffffffffL; + t4 += t3 >> 55; r[ 3] = t3 & 0x7fffffffffffffL; + t5 += t4 >> 55; r[ 4] = t4 & 0x7fffffffffffffL; + t6 += t5 >> 55; r[ 5] = t5 & 0x7fffffffffffffL; + t7 += t6 >> 55; r[ 6] = t6 & 0x7fffffffffffffL; + t8 += t7 >> 55; r[ 7] = t7 & 0x7fffffffffffffL; + t9 += t8 >> 55; r[ 8] = t8 & 0x7fffffffffffffL; + t10 += t9 >> 55; r[ 9] = t9 & 0x7fffffffffffffL; + t11 += t10 >> 55; r[10] = t10 & 0x7fffffffffffffL; + t12 += t11 >> 55; r[11] = t11 & 0x7fffffffffffffL; + r[13] = (sp_digit)(t12 >> 55); + r[12] = t12 & 0x7fffffffffffffL; +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_384_add_7(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + int i; + + for (i = 0; i < 7; i++) { + r[i] = a[i] + b[i]; + } + + return 0; +} +#else +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_384_add_7(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + r[ 0] = a[ 0] + b[ 0]; + r[ 1] = a[ 1] + b[ 1]; + r[ 2] = a[ 2] + b[ 2]; + r[ 3] = a[ 3] + b[ 3]; + r[ 4] = a[ 4] + b[ 4]; + r[ 5] = a[ 5] + b[ 5]; + r[ 6] = a[ 6] + b[ 6]; + + return 0; +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_384_sub_7(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + int i; + + for (i = 0; i < 7; i++) { + r[i] = a[i] - b[i]; + } + + return 0; +} + +#else +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_384_sub_7(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + r[ 0] = a[ 0] - b[ 0]; + r[ 1] = a[ 1] - b[ 1]; + r[ 2] = a[ 2] - b[ 2]; + r[ 3] = a[ 3] - b[ 3]; + r[ 4] = a[ 4] - b[ 4]; + r[ 5] = a[ 5] - b[ 5]; + r[ 6] = a[ 6] - b[ 6]; + + return 0; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Create a new point. + * + * heap [in] Buffer to allocate dynamic memory from. + * sp [in] Data for point - only if not allocating. + * p [out] New point. + * returns MEMORY_E when dynamic memory allocation fails and 0 otherwise. + */ +static int sp_384_point_new_ex_7(void* heap, sp_point_384* sp, + sp_point_384** p) +{ + int ret = MP_OKAY; + (void)heap; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + (void)sp; + *p = (sp_point_384*)XMALLOC(sizeof(sp_point_384), heap, DYNAMIC_TYPE_ECC); +#else + *p = sp; +#endif + if (*p == NULL) { + ret = MEMORY_E; + } + return ret; +} + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* Allocate memory for point and return error. */ +#define sp_384_point_new_7(heap, sp, p) sp_384_point_new_ex_7((heap), NULL, &(p)) +#else +/* Set pointer to data and return no error. */ +#define sp_384_point_new_7(heap, sp, p) sp_384_point_new_ex_7((heap), &(sp), &(p)) +#endif + + +/* Free the point. + * + * p [in,out] Point to free. + * clear [in] Indicates whether to zeroize point. + * heap [in] Buffer from which dynamic memory was allocate from. + */ +static void sp_384_point_free_7(sp_point_384* p, int clear, void* heap) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* If valid pointer then clear point data if requested and free data. */ + if (p != NULL) { + if (clear != 0) { + XMEMSET(p, 0, sizeof(*p)); + } + XFREE(p, heap, DYNAMIC_TYPE_ECC); + } +#else +/* Clear point data if requested. */ + if ((p != NULL) && (clear != 0)) { + XMEMSET(p, 0, sizeof(*p)); + } +#endif + (void)heap; +} + +/* Convert an mp_int to an array of sp_digit. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a A multi-precision integer. + */ +static void sp_384_from_mp(sp_digit* r, int size, const mp_int* a) +{ +#if DIGIT_BIT == 55 + int j; + + XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); + + for (j = a->used; j < size; j++) { + r[j] = 0; + } +#elif DIGIT_BIT > 55 + int i; + int j = 0; + word32 s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i] << s); + r[j] &= 0x7fffffffffffffL; + s = 55U - s; + if (j + 1 >= size) { + break; + } + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + while ((s + 55U) <= (word32)DIGIT_BIT) { + s += 55U; + r[j] &= 0x7fffffffffffffL; + if (j + 1 >= size) { + break; + } + if (s < (word32)DIGIT_BIT) { + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + } + else { + r[++j] = 0L; + } + } + s = (word32)DIGIT_BIT - s; + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#else + int i; + int j = 0; + int s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i]) << s; + if (s + DIGIT_BIT >= 55) { + r[j] &= 0x7fffffffffffffL; + if (j + 1 >= size) { + break; + } + s = 55 - s; + if (s == DIGIT_BIT) { + r[++j] = 0; + s = 0; + } + else { + r[++j] = a->dp[i] >> s; + s = DIGIT_BIT - s; + } + } + else { + s += DIGIT_BIT; + } + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#endif +} + +/* Convert a point of type ecc_point to type sp_point_384. + * + * p Point of type sp_point_384 (result). + * pm Point of type ecc_point. + */ +static void sp_384_point_from_ecc_point_7(sp_point_384* p, + const ecc_point* pm) +{ + XMEMSET(p->x, 0, sizeof(p->x)); + XMEMSET(p->y, 0, sizeof(p->y)); + XMEMSET(p->z, 0, sizeof(p->z)); + sp_384_from_mp(p->x, 7, pm->x); + sp_384_from_mp(p->y, 7, pm->y); + sp_384_from_mp(p->z, 7, pm->z); + p->infinity = 0; +} + +/* Convert an array of sp_digit to an mp_int. + * + * a A single precision integer. + * r A multi-precision integer. + */ +static int sp_384_to_mp(const sp_digit* a, mp_int* r) +{ + int err; + + err = mp_grow(r, (384 + DIGIT_BIT - 1) / DIGIT_BIT); + if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ +#if DIGIT_BIT == 55 + XMEMCPY(r->dp, a, sizeof(sp_digit) * 7); + r->used = 7; + mp_clamp(r); +#elif DIGIT_BIT < 55 + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 7; i++) { + r->dp[j] |= (mp_digit)(a[i] << s); + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + s = DIGIT_BIT - s; + r->dp[++j] = (mp_digit)(a[i] >> s); + while (s + DIGIT_BIT <= 55) { + s += DIGIT_BIT; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; + if (s == SP_WORD_SIZE) { + r->dp[j] = 0; + } + else { + r->dp[j] = (mp_digit)(a[i] >> s); + } + } + s = 55 - s; + } + r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#else + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 7; i++) { + r->dp[j] |= ((mp_digit)a[i]) << s; + if (s + 55 >= DIGIT_BIT) { + #if DIGIT_BIT != 32 && DIGIT_BIT != 64 + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + #endif + s = DIGIT_BIT - s; + r->dp[++j] = a[i] >> s; + s = 55 - s; + } + else { + s += 55; + } + } + r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#endif + } + + return err; +} + +/* Convert a point of type sp_point_384 to type ecc_point. + * + * p Point of type sp_point_384. + * pm Point of type ecc_point (result). + * returns MEMORY_E when allocation of memory in ecc_point fails otherwise + * MP_OKAY. + */ +static int sp_384_point_to_ecc_point_7(const sp_point_384* p, ecc_point* pm) +{ + int err; + + err = sp_384_to_mp(p->x, pm->x); + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, pm->y); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, pm->z); + } + + return err; +} + #define sp_384_mont_reduce_order_7 sp_384_mont_reduce_7 /* Compare a with b in constant time. @@ -19662,7 +20057,6 @@ static void sp_384_mont_reduce_7(sp_digit* a, const sp_digit* m, sp_digit mp) sp_384_mul_add_7(a+i, m, mu); a[i+1] += a[i] >> 55; a[i] &= 0x7fffffffffffffL; - sp_384_mont_shift_7(a, a); sp_384_cond_sub_7(a, a, m, 0 - (((a[6] >> 54) > 0) ? (sp_digit)1 : (sp_digit)0)); @@ -19678,104 +20072,13 @@ static void sp_384_mont_reduce_7(sp_digit* a, const sp_digit* m, sp_digit mp) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_384_mont_mul_7(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_384_mont_mul_7(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_384_mul_7(r, a, b); sp_384_mont_reduce_7(r, m, mp); } -#ifdef WOLFSSL_SP_SMALL -/* Square a and put result in r. (r = a * a) - * - * r A single precision integer. - * a A single precision integer. - */ -SP_NOINLINE static void sp_384_sqr_7(sp_digit* r, const sp_digit* a) -{ - int i, j, k; - int128_t c; - - c = ((int128_t)a[6]) * a[6]; - r[13] = (sp_digit)(c >> 55); - c = (c & 0x7fffffffffffffL) << 55; - for (k = 11; k >= 0; k--) { - for (i = 6; i >= 0; i--) { - j = k - i; - if (j >= 7 || i <= j) { - break; - } - if (j < 0) { - continue; - } - - c += ((int128_t)a[i]) * a[j] * 2; - } - if (i == j) { - c += ((int128_t)a[i]) * a[i]; - } - - r[k + 2] += (sp_digit)(c >> 110); - r[k + 1] = (sp_digit)((c >> 55) & 0x7fffffffffffffL); - c = (c & 0x7fffffffffffffL) << 55; - } - r[0] = (sp_digit)(c >> 55); -} - -#else -/* Square a and put result in r. (r = a * a) - * - * r A single precision integer. - * a A single precision integer. - */ -SP_NOINLINE static void sp_384_sqr_7(sp_digit* r, const sp_digit* a) -{ - int128_t t0 = ((int128_t)a[ 0]) * a[ 0]; - int128_t t1 = (((int128_t)a[ 0]) * a[ 1]) * 2; - int128_t t2 = (((int128_t)a[ 0]) * a[ 2]) * 2 - + ((int128_t)a[ 1]) * a[ 1]; - int128_t t3 = (((int128_t)a[ 0]) * a[ 3] - + ((int128_t)a[ 1]) * a[ 2]) * 2; - int128_t t4 = (((int128_t)a[ 0]) * a[ 4] - + ((int128_t)a[ 1]) * a[ 3]) * 2 - + ((int128_t)a[ 2]) * a[ 2]; - int128_t t5 = (((int128_t)a[ 0]) * a[ 5] - + ((int128_t)a[ 1]) * a[ 4] - + ((int128_t)a[ 2]) * a[ 3]) * 2; - int128_t t6 = (((int128_t)a[ 0]) * a[ 6] - + ((int128_t)a[ 1]) * a[ 5] - + ((int128_t)a[ 2]) * a[ 4]) * 2 - + ((int128_t)a[ 3]) * a[ 3]; - int128_t t7 = (((int128_t)a[ 1]) * a[ 6] - + ((int128_t)a[ 2]) * a[ 5] - + ((int128_t)a[ 3]) * a[ 4]) * 2; - int128_t t8 = (((int128_t)a[ 2]) * a[ 6] - + ((int128_t)a[ 3]) * a[ 5]) * 2 - + ((int128_t)a[ 4]) * a[ 4]; - int128_t t9 = (((int128_t)a[ 3]) * a[ 6] - + ((int128_t)a[ 4]) * a[ 5]) * 2; - int128_t t10 = (((int128_t)a[ 4]) * a[ 6]) * 2 - + ((int128_t)a[ 5]) * a[ 5]; - int128_t t11 = (((int128_t)a[ 5]) * a[ 6]) * 2; - int128_t t12 = ((int128_t)a[ 6]) * a[ 6]; - - t1 += t0 >> 55; r[ 0] = t0 & 0x7fffffffffffffL; - t2 += t1 >> 55; r[ 1] = t1 & 0x7fffffffffffffL; - t3 += t2 >> 55; r[ 2] = t2 & 0x7fffffffffffffL; - t4 += t3 >> 55; r[ 3] = t3 & 0x7fffffffffffffL; - t5 += t4 >> 55; r[ 4] = t4 & 0x7fffffffffffffL; - t6 += t5 >> 55; r[ 5] = t5 & 0x7fffffffffffffL; - t7 += t6 >> 55; r[ 6] = t6 & 0x7fffffffffffffL; - t8 += t7 >> 55; r[ 7] = t7 & 0x7fffffffffffffL; - t9 += t8 >> 55; r[ 8] = t8 & 0x7fffffffffffffL; - t10 += t9 >> 55; r[ 9] = t9 & 0x7fffffffffffffL; - t11 += t10 >> 55; r[10] = t10 & 0x7fffffffffffffL; - t12 += t11 >> 55; r[11] = t11 & 0x7fffffffffffffL; - r[13] = (sp_digit)(t12 >> 55); - r[12] = t12 & 0x7fffffffffffffL; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Square the Montgomery form number. (r = a * a mod m) * * r Result of squaring. @@ -19783,8 +20086,8 @@ SP_NOINLINE static void sp_384_sqr_7(sp_digit* r, const sp_digit* a) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_384_mont_sqr_7(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_384_mont_sqr_7(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_384_sqr_7(r, a); sp_384_mont_reduce_7(r, m, mp); @@ -19808,7 +20111,7 @@ static void sp_384_mont_sqr_n_7(sp_digit* r, const sp_digit* a, int n, } } -#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */ +#endif /* !WOLFSSL_SP_SMALL | HAVE_COMP_KEY */ #ifdef WOLFSSL_SP_SMALL /* Mod-2 for the P384 curve. */ static const uint64_t p384_mod_minus_2[6] = { @@ -19908,7 +20211,8 @@ static void sp_384_mont_inv_7(sp_digit* r, const sp_digit* a, sp_digit* td) * p Montgomery form projective coordinate point. * t Temporary ordinate data. */ -static void sp_384_map_7(sp_point_384* r, const sp_point_384* p, sp_digit* t) +static void sp_384_map_7(sp_point_384* r, const sp_point_384* p, + sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2*7; @@ -19944,46 +20248,6 @@ static void sp_384_map_7(sp_point_384* r, const sp_point_384* p, sp_digit* t) } -#ifdef WOLFSSL_SP_SMALL -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_384_add_7(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 7; i++) { - r[i] = a[i] + b[i]; - } - - return 0; -} -#else -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_384_add_7(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - r[ 0] = a[ 0] + b[ 0]; - r[ 1] = a[ 1] + b[ 1]; - r[ 2] = a[ 2] + b[ 2]; - r[ 3] = a[ 3] + b[ 3]; - r[ 4] = a[ 4] + b[ 4]; - r[ 5] = a[ 5] + b[ 5]; - r[ 6] = a[ 6] + b[ 6]; - - return 0; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Add two Montgomery form numbers (r = a + b % m). * * r Result of addition. @@ -20036,47 +20300,6 @@ static void sp_384_mont_tpl_7(sp_digit* r, const sp_digit* a, const sp_digit* m) sp_384_norm_7(r); } -#ifdef WOLFSSL_SP_SMALL -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_384_sub_7(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - int i; - - for (i = 0; i < 7; i++) { - r[i] = a[i] - b[i]; - } - - return 0; -} - -#else -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static int sp_384_sub_7(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - r[ 0] = a[ 0] - b[ 0]; - r[ 1] = a[ 1] - b[ 1]; - r[ 2] = a[ 2] - b[ 2]; - r[ 3] = a[ 3] - b[ 3]; - r[ 4] = a[ 4] - b[ 4]; - r[ 5] = a[ 5] - b[ 5]; - r[ 6] = a[ 6] - b[ 6]; - - return 0; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Conditionally add a and b using the mask m. * m is -1 to add and 0 when not. * @@ -20126,13 +20349,13 @@ static void sp_384_mont_sub_7(sp_digit* r, const sp_digit* a, const sp_digit* b, * r Result of shift. * a Number to shift. */ -SP_NOINLINE static void sp_384_rshift1_7(sp_digit* r, sp_digit* a) +SP_NOINLINE static void sp_384_rshift1_7(sp_digit* r, const sp_digit* a) { #ifdef WOLFSSL_SP_SMALL int i; for (i=0; i<6; i++) { - r[i] = ((a[i] >> 1) + (a[i + 1] << 54)) & 0x7fffffffffffffL; + r[i] = (a[i] >> 1) + ((a[i + 1] << 54) & 0x7fffffffffffffL); } #else r[0] = (a[0] >> 1) + ((a[1] << 54) & 0x7fffffffffffffL); @@ -20576,8 +20799,8 @@ static int sp_384_proj_point_add_7_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r, } #endif /* WOLFSSL_SP_NONBLOCK */ -static void sp_384_proj_point_add_7(sp_point_384* r, const sp_point_384* p, const sp_point_384* q, - sp_digit* t) +static void sp_384_proj_point_add_7(sp_point_384* r, + const sp_point_384* p, const sp_point_384* q, sp_digit* t) { const sp_point_384* ap[2]; sp_point_384* rp[2]; @@ -20663,10 +20886,164 @@ static void sp_384_proj_point_add_7(sp_point_384* r, const sp_point_384* p, cons } } +/* Multiply a number by Montogmery normalizer mod modulus (prime). + * + * r The resulting Montgomery form number. + * a The number to convert. + * m The modulus (prime). + * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. + */ +static int sp_384_mod_mul_norm_7(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + int64_t* td; +#else + int64_t td[12]; + int64_t a32d[12]; +#endif + int64_t* t; + int64_t* a32; + int64_t o; + int err = MP_OKAY; + + (void)m; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + td = (int64_t*)XMALLOC(sizeof(int64_t) * 2 * 12, NULL, DYNAMIC_TYPE_ECC); + if (td == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + a32 = td + 12; +#else + t = td; + a32 = a32d; +#endif + + a32[0] = (sp_digit)(a[0]) & 0xffffffffL; + a32[1] = (sp_digit)(a[0] >> 32U); + a32[1] |= (sp_digit)(a[1] << 23U); + a32[1] &= 0xffffffffL; + a32[2] = (sp_digit)(a[1] >> 9U) & 0xffffffffL; + a32[3] = (sp_digit)(a[1] >> 41U); + a32[3] |= (sp_digit)(a[2] << 14U); + a32[3] &= 0xffffffffL; + a32[4] = (sp_digit)(a[2] >> 18U) & 0xffffffffL; + a32[5] = (sp_digit)(a[2] >> 50U); + a32[5] |= (sp_digit)(a[3] << 5U); + a32[5] &= 0xffffffffL; + a32[6] = (sp_digit)(a[3] >> 27U); + a32[6] |= (sp_digit)(a[4] << 28U); + a32[6] &= 0xffffffffL; + a32[7] = (sp_digit)(a[4] >> 4U) & 0xffffffffL; + a32[8] = (sp_digit)(a[4] >> 36U); + a32[8] |= (sp_digit)(a[5] << 19U); + a32[8] &= 0xffffffffL; + a32[9] = (sp_digit)(a[5] >> 13U) & 0xffffffffL; + a32[10] = (sp_digit)(a[5] >> 45U); + a32[10] |= (sp_digit)(a[6] << 10U); + a32[10] &= 0xffffffffL; + a32[11] = (sp_digit)(a[6] >> 22U) & 0xffffffffL; + + /* 1 0 0 0 0 0 0 0 1 1 0 -1 */ + t[0] = 0 + a32[0] + a32[8] + a32[9] - a32[11]; + /* -1 1 0 0 0 0 0 0 -1 0 1 1 */ + t[1] = 0 - a32[0] + a32[1] - a32[8] + a32[10] + a32[11]; + /* 0 -1 1 0 0 0 0 0 0 -1 0 1 */ + t[2] = 0 - a32[1] + a32[2] - a32[9] + a32[11]; + /* 1 0 -1 1 0 0 0 0 1 1 -1 -1 */ + t[3] = 0 + a32[0] - a32[2] + a32[3] + a32[8] + a32[9] - a32[10] - a32[11]; + /* 1 1 0 -1 1 0 0 0 1 2 1 -2 */ + t[4] = 0 + a32[0] + a32[1] - a32[3] + a32[4] + a32[8] + 2 * a32[9] + a32[10] - 2 * a32[11]; + /* 0 1 1 0 -1 1 0 0 0 1 2 1 */ + t[5] = 0 + a32[1] + a32[2] - a32[4] + a32[5] + a32[9] + 2 * a32[10] + a32[11]; + /* 0 0 1 1 0 -1 1 0 0 0 1 2 */ + t[6] = 0 + a32[2] + a32[3] - a32[5] + a32[6] + a32[10] + 2 * a32[11]; + /* 0 0 0 1 1 0 -1 1 0 0 0 1 */ + t[7] = 0 + a32[3] + a32[4] - a32[6] + a32[7] + a32[11]; + /* 0 0 0 0 1 1 0 -1 1 0 0 0 */ + t[8] = 0 + a32[4] + a32[5] - a32[7] + a32[8]; + /* 0 0 0 0 0 1 1 0 -1 1 0 0 */ + t[9] = 0 + a32[5] + a32[6] - a32[8] + a32[9]; + /* 0 0 0 0 0 0 1 1 0 -1 1 0 */ + t[10] = 0 + a32[6] + a32[7] - a32[9] + a32[10]; + /* 0 0 0 0 0 0 0 1 1 0 -1 1 */ + t[11] = 0 + a32[7] + a32[8] - a32[10] + a32[11]; + + t[1] += t[0] >> 32; t[0] &= 0xffffffff; + t[2] += t[1] >> 32; t[1] &= 0xffffffff; + t[3] += t[2] >> 32; t[2] &= 0xffffffff; + t[4] += t[3] >> 32; t[3] &= 0xffffffff; + t[5] += t[4] >> 32; t[4] &= 0xffffffff; + t[6] += t[5] >> 32; t[5] &= 0xffffffff; + t[7] += t[6] >> 32; t[6] &= 0xffffffff; + t[8] += t[7] >> 32; t[7] &= 0xffffffff; + t[9] += t[8] >> 32; t[8] &= 0xffffffff; + t[10] += t[9] >> 32; t[9] &= 0xffffffff; + t[11] += t[10] >> 32; t[10] &= 0xffffffff; + o = t[11] >> 32; t[11] &= 0xffffffff; + t[0] += o; + t[1] -= o; + t[3] += o; + t[4] += o; + t[1] += t[0] >> 32; t[0] &= 0xffffffff; + t[2] += t[1] >> 32; t[1] &= 0xffffffff; + t[3] += t[2] >> 32; t[2] &= 0xffffffff; + t[4] += t[3] >> 32; t[3] &= 0xffffffff; + t[5] += t[4] >> 32; t[4] &= 0xffffffff; + t[6] += t[5] >> 32; t[5] &= 0xffffffff; + t[7] += t[6] >> 32; t[6] &= 0xffffffff; + t[8] += t[7] >> 32; t[7] &= 0xffffffff; + t[9] += t[8] >> 32; t[8] &= 0xffffffff; + t[10] += t[9] >> 32; t[9] &= 0xffffffff; + t[11] += t[10] >> 32; t[10] &= 0xffffffff; + + r[0] = t[0]; + r[0] |= t[1] << 32U; + r[0] &= 0x7fffffffffffffLL; + r[1] = (t[1] >> 23); + r[1] |= t[2] << 9U; + r[1] |= t[3] << 41U; + r[1] &= 0x7fffffffffffffLL; + r[2] = (t[3] >> 14); + r[2] |= t[4] << 18U; + r[2] |= t[5] << 50U; + r[2] &= 0x7fffffffffffffLL; + r[3] = (t[5] >> 5); + r[3] |= t[6] << 27U; + r[3] &= 0x7fffffffffffffLL; + r[4] = (t[6] >> 28); + r[4] |= t[7] << 4U; + r[4] |= t[8] << 36U; + r[4] &= 0x7fffffffffffffLL; + r[5] = (t[8] >> 19); + r[5] |= t[9] << 13U; + r[5] |= t[10] << 45U; + r[5] &= 0x7fffffffffffffLL; + r[6] = (t[10] >> 10); + r[6] |= t[11] << 22U; + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) + XFREE(td, NULL, DYNAMIC_TYPE_ECC); +#endif + + return err; +} + #ifdef WOLFSSL_SP_SMALL /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Small implementation using add and double that is cache attack resistant but + * allocates memory rather than use large stacks. + * 384 adds and doubles. + * * r Resulting point. * g Point to multiply. * k Scalar to multiply by. @@ -20790,8 +21167,8 @@ static int sp_384_ecc_mulmod_7_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r, #endif /* WOLFSSL_SP_NONBLOCK */ -static int sp_384_ecc_mulmod_7(sp_point_384* r, const sp_point_384* g, const sp_digit* k, - int map, int ct, void* heap) +static int sp_384_ecc_mulmod_7(sp_point_384* r, const sp_point_384* g, + const sp_digit* k, int map, int ct, void* heap) { #ifdef WOLFSSL_SP_NO_MALLOC sp_point_384 t[3]; @@ -20802,7 +21179,8 @@ static int sp_384_ecc_mulmod_7(sp_point_384* r, const sp_point_384* g, const sp_ #endif sp_digit n; int i; - int c, y; + int c; + int y; int err = MP_OKAY; /* Implementatio is constant time. */ @@ -20935,7 +21313,8 @@ static void sp_384_cond_copy_7(sp_digit* r, const sp_digit* a, const sp_digit m) * n Number of times to double * t Temporary ordinate data. */ -static void sp_384_proj_point_dbl_n_7(sp_point_384* p, int n, sp_digit* t) +static void sp_384_proj_point_dbl_n_7(sp_point_384* p, int n, + sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*7; @@ -21023,8 +21402,8 @@ static void sp_384_proj_point_dbl_n_7(sp_point_384* p, int n, sp_digit* t) * n Number of times to double * t Temporary ordinate data. */ -static void sp_384_proj_point_dbl_n_store_7(sp_point_384* r, const sp_point_384* p, - int n, int m, sp_digit* t) +static void sp_384_proj_point_dbl_n_store_7(sp_point_384* r, + const sp_point_384* p, int n, int m, sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*7; @@ -21035,6 +21414,7 @@ static void sp_384_proj_point_dbl_n_store_7(sp_point_384* r, const sp_point_384* sp_digit* y = r[(1<x[i]; @@ -21051,7 +21431,10 @@ static void sp_384_proj_point_dbl_n_store_7(sp_point_384* r, const sp_point_384* /* W = Z^4 */ sp_384_mont_sqr_7(w, z, p384_mod, p384_mp_mod); sp_384_mont_sqr_7(w, w, p384_mod, p384_mp_mod); + j = m; for (i=1; i<=n; i++) { + j *= 2; + /* A = 3*(X^2 - W) */ sp_384_mont_sqr_7(t1, x, p384_mod, p384_mp_mod); sp_384_mont_sub_7(t1, t1, w, p384_mod); @@ -21059,14 +21442,14 @@ static void sp_384_proj_point_dbl_n_store_7(sp_point_384* r, const sp_point_384* /* B = X*Y^2 */ sp_384_mont_sqr_7(t2, y, p384_mod, p384_mp_mod); sp_384_mont_mul_7(b, t2, x, p384_mod, p384_mp_mod); - x = r[(1<y); + sp_384_norm_7(negy); sp_384_cond_copy_7(p->y, negy, (sp_digit)0 - v[i].neg); sp_384_proj_point_add_7(rt, rt, p, tmp); } @@ -21548,6 +21935,10 @@ static void sp_384_proj_to_affine_7(sp_point_384* a, sp_digit* t) } /* Generate the pre-computed table of points for the base point. + * + * width = 8 + * 256 entries + * 48 bits between * * a The base point. * table Place to store generated point data. @@ -21558,12 +21949,15 @@ static int sp_384_gen_stripe_table_7(const sp_point_384* a, sp_table_entry_384* table, sp_digit* tmp, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_point_384 td, s1d, s2d; + sp_point_384 td; + sp_point_384 s1d; + sp_point_384 s2d; #endif sp_point_384* t; sp_point_384* s1 = NULL; sp_point_384* s2 = NULL; - int i, j; + int i; + int j; int err; (void)heap; @@ -21678,8 +22072,10 @@ static void sp_384_get_entry_256_7(sp_point_384* r, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Implementation uses striping of bits. - * Choose bits 8 bits apart. + * Stripe implementation. + * Pre-generated: 2^0, 2^48, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) * * r Resulting point. * k Scalar to multiply by. @@ -21701,8 +22097,10 @@ static int sp_384_ecc_mulmod_stripe_7(sp_point_384* r, const sp_point_384* g, sp_point_384* rt; sp_point_384* p = NULL; sp_digit* t; - int i, j; - int y, x; + int i; + int j; + int y; + int x; int err; (void)g; @@ -21730,8 +22128,10 @@ static int sp_384_ecc_mulmod_stripe_7(sp_point_384* r, const sp_point_384* g, XMEMCPY(rt->z, p384_norm_mod, sizeof(p384_norm_mod)); y = 0; - for (j=0,x=47; j<8; j++,x+=48) { + x = 47; + for (j=0; j<8; j++) { y |= (int)(((k[x / 55] >> (x % 55)) & 1) << j); + x += 48; } #ifndef WC_NO_CACHE_RESISTANT if (ct) { @@ -21745,8 +22145,10 @@ static int sp_384_ecc_mulmod_stripe_7(sp_point_384* r, const sp_point_384* g, rt->infinity = !y; for (i=46; i>=0; i--) { y = 0; - for (j=0,x=i; j<8; j++,x+=48) { + x = i; + for (j=0; j<8; j++) { y |= (int)(((k[x / 55] >> (x % 55)) & 1) << j); + x += 48; } sp_384_proj_point_dbl_7(rt, rt, t); @@ -21788,16 +22190,25 @@ static int sp_384_ecc_mulmod_stripe_7(sp_point_384* r, const sp_point_384* g, #define FP_ENTRIES 16 #endif +/* Cache entry - holds precomputation tables for a point. */ typedef struct sp_cache_384_t { + /* X ordinate of point that table was generated from. */ sp_digit x[7]; + /* Y ordinate of point that table was generated from. */ sp_digit y[7]; + /* Precomputation table for point. */ sp_table_entry_384 table[256]; + /* Count of entries in table. */ uint32_t cnt; + /* Point and table set in entry. */ int set; } sp_cache_384_t; +/* Cache of tables. */ static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES]; +/* Index of last entry in cache. */ static THREAD_LS_T int sp_cache_384_last = -1; +/* Cache has been initialized. */ static THREAD_LS_T int sp_cache_384_inited = 0; #ifndef HAVE_THREAD_LS @@ -21805,9 +22216,15 @@ static THREAD_LS_T int sp_cache_384_inited = 0; static wolfSSL_Mutex sp_cache_384_lock; #endif +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache) { - int i, j; + int i; + int j; uint32_t least; if (sp_cache_384_inited == 0) { @@ -21924,8 +22341,8 @@ static int sp_384_ecc_mulmod_7(sp_point_384* r, const sp_point_384* g, const sp_ * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_384(mp_int* km, ecc_point* gm, ecc_point* r, int map, - void* heap) +int sp_ecc_mulmod_384(const mp_int* km, const ecc_point* gm, ecc_point* r, + int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_384 p; @@ -21966,6 +22383,89 @@ int sp_ecc_mulmod_384(mp_int* km, ecc_point* gm, ecc_point* r, int map, return err; } +/* Multiply the point by the scalar, add point a and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * p Point to multiply. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_add_384(const mp_int* km, const ecc_point* gm, + const ecc_point* am, int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_384 p; + sp_point_384 a; + sp_digit kd[7]; + sp_digit t[7 * 2 * 6]; +#endif + sp_point_384* point; + sp_point_384* addP = NULL; + sp_digit* k = NULL; + sp_digit* tmp = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_7(heap, p, point); + if (err == MP_OKAY) { + err = sp_384_point_new_7(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (7 + 7 * 2 * 6), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 7; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 7, km); + sp_384_point_from_ecc_point_7(point, gm); + sp_384_point_from_ecc_point_7(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_7(addP->x, addP->x, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_7(addP->y, addP->y, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_7(addP->z, addP->z, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_7(point, point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_384_proj_point_add_7(point, point, addP, tmp); + + if (map) { + sp_384_map_7(point, point, tmp); + } + + err = sp_384_point_to_ecc_point_7(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_7(addP, 0, heap); + sp_384_point_free_7(point, 0, heap); + + return err; +} + #ifdef WOLFSSL_SP_SMALL /* Multiply the base point of P384 by the scalar and return the result. * If map is true then convert result to affine coordinates. @@ -21984,6 +22484,10 @@ static int sp_384_ecc_mulmod_base_7(sp_point_384* r, const sp_digit* k, } #else +/* Striping precomputation table. + * 8 points combined into a table of 256 points. + * Distance of 48 between points. + */ static const sp_table_entry_384 p384_table[256] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -23778,6 +24282,11 @@ static const sp_table_entry_384 p384_table[256] = { /* Multiply the base point of P384 by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Stripe implementation. + * Pre-generated: 2^0, 2^48, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * * r Resulting point. * k Scalar to multiply by. * map Indicates whether to convert result to affine. @@ -23803,7 +24312,7 @@ static int sp_384_ecc_mulmod_base_7(sp_point_384* r, const sp_digit* k, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_base_384(mp_int* km, ecc_point* r, int map, void* heap) +int sp_ecc_mulmod_base_384(const mp_int* km, ecc_point* r, int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_384 p; @@ -23844,6 +24353,87 @@ int sp_ecc_mulmod_base_384(mp_int* km, ecc_point* r, int map, void* heap) return err; } +/* Multiply the base point of P384 by the scalar, add point a and return + * the result. If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_add_384(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_384 p; + sp_point_384 a; + sp_digit kd[7]; + sp_digit t[7 * 2 * 6]; +#endif + sp_point_384* point; + sp_point_384* addP = NULL; + sp_digit* tmp = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_7(heap, p, point); + if (err == MP_OKAY) { + err = sp_384_point_new_7(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (7 + 7 * 2 * 6), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 7; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 7, km); + sp_384_point_from_ecc_point_7(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_7(addP->x, addP->x, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_7(addP->y, addP->y, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_7(addP->z, addP->z, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_base_7(point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_384_proj_point_add_7(point, point, addP, tmp); + + if (map) { + sp_384_map_7(point, point, tmp); + } + + err = sp_384_point_to_ecc_point_7(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_7(addP, 0, heap); + sp_384_point_free_7(point, 0, heap); + + return err; +} + #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \ defined(HAVE_ECC_VERIFY) /* Returns 1 if the number of zero. @@ -23857,7 +24447,7 @@ static int sp_384_iszero_7(const sp_digit* a) return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6]) == 0; } -#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN | HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ /* Add 1 to a. (a = a + 1) * * r A single precision integer. @@ -23878,7 +24468,8 @@ SP_NOINLINE static void sp_384_add_one_7(sp_digit* a) */ static void sp_384_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -24022,7 +24613,10 @@ int sp_ecc_make_key_384(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) */ static void sp_384_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; for (i=0; i<6; i++) { r[i+1] += r[i] >> 55; @@ -24067,7 +24661,7 @@ static void sp_384_to_bin(sp_digit* r, byte* a) * returns BUFFER_E if the buffer is to small for output size, * MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_secret_gen_384(mp_int* priv, ecc_point* pub, byte* out, +int sp_ecc_secret_gen_384(const mp_int* priv, const ecc_point* pub, byte* out, word32* outLen, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) @@ -24166,7 +24760,9 @@ SP_NOINLINE static void sp_384_mul_d_7(sp_digit* r, const sp_digit* a, static WC_INLINE sp_digit sp_384_div_word_7(sp_digit d1, sp_digit d0, sp_digit dv) { - sp_digit d, r, t; + sp_digit d; + sp_digit r; + sp_digit t; /* All 55 bits from d1 and top 8 bits from d0. */ d = (d1 << 8) | (d0 >> 47); @@ -24227,24 +24823,28 @@ static WC_INLINE sp_digit sp_384_div_word_7(sp_digit d1, sp_digit d0, /* Divide d in a and put remainder into r (m*d + r = a) * m is not calculated as it is not needed at this time. * + * Large number of bits in last word. + * * a Number to be divided. * d Number to divide with. * m Multiplier result. * r Remainder from the division. * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise. */ -static int sp_384_div_7(const sp_digit* a, const sp_digit* d, sp_digit* m, - sp_digit* r) +static int sp_384_div_7(const sp_digit* a, const sp_digit* d, + const sp_digit* m, sp_digit* r) { int i; #ifndef WOLFSSL_SP_DIV_64 int128_t d1; #endif - sp_digit dv, r1; + sp_digit dv; + sp_digit r1; #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* td; #else - sp_digit t1d[14], t2d[7 + 1]; + sp_digit t1d[14]; + sp_digit t2d[7 + 1]; #endif sp_digit* t1; sp_digit* t2; @@ -24272,17 +24872,15 @@ static int sp_384_div_7(const sp_digit* a, const sp_digit* d, sp_digit* m, dv = d[6]; XMEMCPY(t1, a, sizeof(*t1) * 2U * 7U); for (i=6; i>=0; i--) { - sp_digit hi; t1[7 + i] += t1[7 + i - 1] >> 55; t1[7 + i - 1] &= 0x7fffffffffffffL; - hi = t1[7 + i] - (t1[7 + i] == dv); #ifndef WOLFSSL_SP_DIV_64 - d1 = hi; + d1 = t1[7 + i]; d1 <<= 55; d1 += t1[7 + i - 1]; r1 = (sp_digit)(d1 / dv); #else - r1 = sp_384_div_word_7(hi, t1[7 + i - 1], dv); + r1 = sp_384_div_word_7(t1[7 + i], t1[7 + i - 1], dv); #endif sp_384_mul_d_7(t2, d, r1); @@ -24303,7 +24901,7 @@ static int sp_384_div_7(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_384_mul_d_7(t2, d, r1); (void)sp_384_sub_7(t1, t1, t2); - XMEMCPY(r, t1, sizeof(*r) * 2U * 7U); + XMEMCPY(r, t1, sizeof(*r) * 14U); for (i=0; i<6; i++) { r[i+1] += r[i] >> 55; r[i] &= 0x7fffffffffffffL; @@ -24345,7 +24943,6 @@ static const uint64_t p384_order_minus_2[6] = { /* The low half of the order-2 of the P384 curve. */ static const uint64_t p384_order_low[3] = { 0xecec196accc52971U,0x581a0db248b0a77aU,0xc7634d81f4372ddfU - }; #endif /* WOLFSSL_SP_SMALL */ @@ -24493,7 +25090,7 @@ static void sp_384_mont_inv_order_7(sp_digit* r, const sp_digit* a, sp_384_mont_mul_order_7(t2, t2, t); for (i=191; i>=1; i--) { sp_384_mont_sqr_order_7(t2, t2); - if (((sp_digit)p384_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { + if ((p384_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { sp_384_mont_mul_order_7(t2, t2, a); } } @@ -24502,12 +25099,63 @@ static void sp_384_mont_inv_order_7(sp_digit* r, const sp_digit* a, #endif /* WOLFSSL_SP_SMALL */ } -#endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ #ifdef HAVE_ECC_SIGN #ifndef SP_ECC_MAX_SIG_GEN #define SP_ECC_MAX_SIG_GEN 64 #endif +/* Calculate second signature value S from R, k and private value. + * + * s = (r * x + e) / k + * + * s Signature value. + * r First signature value. + * k Ephemeral private key. + * x Private key as a number. + * e Hash of message as a number. + * tmp Temporary storage for intermediate numbers. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_calc_s_7(sp_digit* s, const sp_digit* r, sp_digit* k, + sp_digit* x, const sp_digit* e, sp_digit* tmp) +{ + int err; + sp_digit carry; + int64_t c; + sp_digit* kInv = k; + + /* Conv k to Montgomery form (mod order) */ + sp_384_mul_7(k, k, p384_norm_order); + err = sp_384_mod_7(k, k, p384_order); + if (err == MP_OKAY) { + sp_384_norm_7(k); + + /* kInv = 1/k mod order */ + sp_384_mont_inv_order_7(kInv, k, tmp); + sp_384_norm_7(kInv); + + /* s = r * x + e */ + sp_384_mul_7(x, x, r); + err = sp_384_mod_7(x, x, p384_order); + } + if (err == MP_OKAY) { + sp_384_norm_7(x); + carry = sp_384_add_7(s, e, x); + sp_384_cond_sub_7(s, s, p384_order, 0 - carry); + sp_384_norm_7(s); + c = sp_384_cmp_7(s, p384_order); + sp_384_cond_sub_7(s, s, p384_order, 0L - (sp_digit)(c >= 0)); + sp_384_norm_7(s); + + /* s = s * k^-1 mod order */ + sp_384_mont_mul_order_7(s, s, kInv); + sp_384_norm_7(s); + } + + return err; +} + /* Sign the hash using the private key. * e = [hash, 384 bits] from binary * r = (k.G)->x mod order @@ -24542,8 +25190,8 @@ typedef struct sp_ecc_sign_384_ctx { int i; } sp_ecc_sign_384_ctx; -int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, + mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_sign_384_ctx* ctx = (sp_ecc_sign_384_ctx*)sp_ctx->data; @@ -24683,8 +25331,8 @@ int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, W } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, + const mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -24702,11 +25350,9 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit* r = NULL; sp_digit* tmp = NULL; sp_point_384* point = NULL; - sp_digit carry; sp_digit* s = NULL; - sp_digit* kInv = NULL; - int err = MP_OKAY; int64_t c; + int err = MP_OKAY; int i; (void)heap; @@ -24737,7 +25383,6 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, tmp = td; #endif s = e; - kInv = k; if (hashLen > 48U) { hashLen = 48U; @@ -24745,8 +25390,6 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, } for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) { - sp_384_from_mp(x, 7, priv); - /* New random point. */ if (km == NULL || mp_iszero(km)) { err = sp_384_ecc_gen_k_7(rng, k); @@ -24756,7 +25399,7 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, mp_zero(km); } if (err == MP_OKAY) { - err = sp_384_ecc_mulmod_base_7(point, k, 1, 1, NULL); + err = sp_384_ecc_mulmod_base_7(point, k, 1, 1, heap); } if (err == MP_OKAY) { @@ -24767,38 +25410,15 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_384_cond_sub_7(r, r, p384_order, 0L - (sp_digit)(c >= 0)); sp_384_norm_7(r); - /* Conv k to Montgomery form (mod order) */ - sp_384_mul_7(k, k, p384_norm_order); - err = sp_384_mod_7(k, k, p384_order); - } - if (err == MP_OKAY) { - sp_384_norm_7(k); - /* kInv = 1/k mod order */ - sp_384_mont_inv_order_7(kInv, k, tmp); - sp_384_norm_7(kInv); - - /* s = r * x + e */ - sp_384_mul_7(x, x, r); - err = sp_384_mod_7(x, x, p384_order); - } - if (err == MP_OKAY) { - sp_384_norm_7(x); + sp_384_from_mp(x, 7, priv); sp_384_from_bin(e, 7, hash, (int)hashLen); - carry = sp_384_add_7(s, e, x); - sp_384_cond_sub_7(s, s, p384_order, 0 - carry); - sp_384_norm_7(s); - c = sp_384_cmp_7(s, p384_order); - sp_384_cond_sub_7(s, s, p384_order, 0L - (sp_digit)(c >= 0)); - sp_384_norm_7(s); - /* s = s * k^-1 mod order */ - sp_384_mont_mul_order_7(s, s, kInv); - sp_384_norm_7(s); + err = sp_384_calc_s_7(s, r, k, x, e, tmp); + } - /* Check that signature is usable. */ - if (sp_384_iszero_7(s) == 0) { - break; - } + /* Check that signature is usable. */ + if ((err == MP_OKAY) && (sp_384_iszero_7(s) == 0)) { + break; } #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP i = 1; @@ -24826,7 +25446,6 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, XMEMSET(x, 0, sizeof(sp_digit) * 2U * 7U); XMEMSET(k, 0, sizeof(sp_digit) * 2U * 7U); XMEMSET(r, 0, sizeof(sp_digit) * 2U * 7U); - XMEMSET(r, 0, sizeof(sp_digit) * 2U * 7U); XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 7U); #endif sp_384_point_free_7(point, 1, heap); @@ -24996,6 +25615,95 @@ static int sp_384_mod_inv_7(sp_digit* r, const sp_digit* a, const sp_digit* m) } #endif /* WOLFSSL_SP_SMALL */ + +/* Add point p1 into point p2. Handles p1 == p2 and result at infinity. + * + * p1 First point to add and holds result. + * p2 Second point to add. + * tmp Temporary storage for intermediate numbers. + */ +static void sp_384_add_points_7(sp_point_384* p1, const sp_point_384* p2, + sp_digit* tmp) +{ + + sp_384_proj_point_add_7(p1, p1, p2, tmp); + if (sp_384_iszero_7(p1->z)) { + if (sp_384_iszero_7(p1->x) && sp_384_iszero_7(p1->y)) { + sp_384_proj_point_dbl_7(p1, p2, tmp); + } + else { + /* Y ordinate is not used from here - don't set. */ + p1->x[0] = 0; + p1->x[1] = 0; + p1->x[2] = 0; + p1->x[3] = 0; + p1->x[4] = 0; + p1->x[5] = 0; + p1->x[6] = 0; + XMEMCPY(p1->z, p384_norm_mod, sizeof(p384_norm_mod)); + } + } +} + +/* Calculate the verification point: [e/s]G + [r/s]Q + * + * p1 Calculated point. + * p2 Public point and temporary. + * s Second part of signature as a number. + * u1 Temporary number. + * u2 Temproray number. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_calc_vfy_point_7(sp_point_384* p1, sp_point_384* p2, + sp_digit* s, sp_digit* u1, sp_digit* u2, sp_digit* tmp, void* heap) +{ + int err; + +#ifndef WOLFSSL_SP_SMALL + { + sp_384_mod_inv_7(s, s, p384_order); + } +#endif /* !WOLFSSL_SP_SMALL */ + { + sp_384_mul_7(s, s, p384_norm_order); + } + err = sp_384_mod_7(s, s, p384_order); + if (err == MP_OKAY) { + sp_384_norm_7(s); +#ifdef WOLFSSL_SP_SMALL + { + sp_384_mont_inv_order_7(s, s, tmp); + sp_384_mont_mul_order_7(u1, u1, s); + sp_384_mont_mul_order_7(u2, u2, s); + } + +#else + { + sp_384_mont_mul_order_7(u1, u1, s); + sp_384_mont_mul_order_7(u2, u2, s); + } + +#endif /* WOLFSSL_SP_SMALL */ + err = sp_384_ecc_mulmod_base_7(p1, u1, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_384_iszero_7(p1->z)) { + p1->infinity = 1; + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_7(p2, p2, u2, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_384_iszero_7(p2->z)) { + p2->infinity = 1; + } + + if (err == MP_OKAY) { + sp_384_add_points_7(p1, p2, tmp); + } + + return err; +} + #ifdef HAVE_ECC_VERIFY /* Verify the signature values with the hash and public key. * e = Truncate(hash, 384) @@ -25014,8 +25722,7 @@ static int sp_384_mod_inv_7(sp_digit* r, const sp_digit* a, const sp_digit* m) * rm First part of result as an mp_int. * sm Sirst part of result as an mp_int. * heap Heap to use for allocation. - * returns RNG failures, MEMORY_E when memory allocation fails and - * MP_OKAY on success. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ #ifdef WOLFSSL_SP_NONBLOCK typedef struct sp_ecc_verify_384_ctx { @@ -25034,8 +25741,9 @@ typedef struct sp_ecc_verify_384_ctx { sp_point_384 p2; } sp_ecc_verify_384_ctx; -int sp_ecc_verify_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, + word32 hashLen, const mp_int* pX, const mp_int* pY, const mp_int* pZ, + const mp_int* r, const mp_int* sm, int* res, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_verify_384_ctx* ctx = (sp_ecc_verify_384_ctx*)sp_ctx->data; @@ -25189,8 +25897,9 @@ int sp_ecc_verify_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_384(const byte* hash, word32 hashLen, const mp_int* pX, + const mp_int* pY, const mp_int* pZ, const mp_int* r, const mp_int* sm, + int* res, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -25209,7 +25918,7 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, sp_point_384* p1; sp_point_384* p2 = NULL; sp_digit carry; - int64_t c; + int64_t c = 0; int err; err = sp_384_point_new_7(heap, p1d, p1); @@ -25250,65 +25959,9 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, sp_384_from_mp(p2->y, 7, pY); sp_384_from_mp(p2->z, 7, pZ); -#ifndef WOLFSSL_SP_SMALL - { - sp_384_mod_inv_7(s, s, p384_order); - } -#endif /* !WOLFSSL_SP_SMALL */ - { - sp_384_mul_7(s, s, p384_norm_order); - } - err = sp_384_mod_7(s, s, p384_order); + err = sp_384_calc_vfy_point_7(p1, p2, s, u1, u2, tmp, heap); } if (err == MP_OKAY) { - sp_384_norm_7(s); -#ifdef WOLFSSL_SP_SMALL - { - sp_384_mont_inv_order_7(s, s, tmp); - sp_384_mont_mul_order_7(u1, u1, s); - sp_384_mont_mul_order_7(u2, u2, s); - } - -#else - { - sp_384_mont_mul_order_7(u1, u1, s); - sp_384_mont_mul_order_7(u2, u2, s); - } - -#endif /* WOLFSSL_SP_SMALL */ - err = sp_384_ecc_mulmod_base_7(p1, u1, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_384_iszero_7(p1->z)) { - p1->infinity = 1; - } - if (err == MP_OKAY) { - err = sp_384_ecc_mulmod_7(p2, p2, u2, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_384_iszero_7(p2->z)) { - p2->infinity = 1; - } - - if (err == MP_OKAY) { - { - sp_384_proj_point_add_7(p1, p1, p2, tmp); - if (sp_384_iszero_7(p1->z)) { - if (sp_384_iszero_7(p1->x) && sp_384_iszero_7(p1->y)) { - sp_384_proj_point_dbl_7(p1, p2, tmp); - } - else { - /* Y ordinate is not used from here - don't set. */ - p1->x[0] = 0; - p1->x[1] = 0; - p1->x[2] = 0; - p1->x[3] = 0; - p1->x[4] = 0; - p1->x[5] = 0; - p1->x[6] = 0; - XMEMCPY(p1->z, p384_norm_mod, sizeof(p384_norm_mod)); - } - } - } - /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */ /* Reload r and convert to Montgomery form. */ sp_384_from_mp(u2, 7, r); @@ -25330,16 +25983,16 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, /* Compare with mod and if greater or equal then not valid. */ c = sp_384_cmp_7(u2, p384_mod); - if (c < 0) { - /* Convert to Montogomery form */ - err = sp_384_mod_mul_norm_7(u2, u2, p384_mod); - if (err == MP_OKAY) { - /* u1 = (r + 1*order).z'.z' mod prime */ - sp_384_mont_mul_7(u1, u2, p1->z, p384_mod, - p384_mp_mod); - *res = (int)(sp_384_cmp_7(p1->x, u1) == 0); - } - } + } + } + if ((*res == 0) && (c < 0)) { + /* Convert to Montogomery form */ + err = sp_384_mod_mul_norm_7(u2, u2, p384_mod); + if (err == MP_OKAY) { + /* u1 = (r + 1*order).z'.z' mod prime */ + sp_384_mont_mul_7(u1, u2, p1->z, p384_mod, + p384_mp_mod); + *res = (sp_384_cmp_7(p1->x, u1) == 0); } } } @@ -25363,7 +26016,8 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -static int sp_384_ecc_is_point_7(sp_point_384* point, void* heap) +static int sp_384_ecc_is_point_7(const sp_point_384* point, + void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -25426,7 +26080,7 @@ static int sp_384_ecc_is_point_7(sp_point_384* point, void* heap) * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -int sp_ecc_is_point_384(mp_int* pX, mp_int* pY) +int sp_ecc_is_point_384(const mp_int* pX, const mp_int* pY) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_384 pubd; @@ -25460,7 +26114,8 @@ int sp_ecc_is_point_384(mp_int* pX, mp_int* pY) * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and * MP_OKAY otherwise. */ -int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) +int sp_ecc_check_key_384(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit privd[7]; @@ -25514,12 +26169,11 @@ int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) } } - if (err == MP_OKAY) { - /* Check range of X and Y */ - if (sp_384_cmp_7(pub->x, p384_mod) >= 0 || - sp_384_cmp_7(pub->y, p384_mod) >= 0) { - err = ECC_OUT_OF_RANGE_E; - } + /* Check range of X and Y */ + if ((err == MP_OKAY) && + ((sp_384_cmp_7(pub->x, p384_mod) >= 0) || + (sp_384_cmp_7(pub->y, p384_mod) >= 0))) { + err = ECC_OUT_OF_RANGE_E; } if (err == MP_OKAY) { @@ -25531,12 +26185,10 @@ int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Point * order = infinity */ err = sp_384_ecc_mulmod_7(p, pub, p384_order, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is infinity */ - if ((sp_384_iszero_7(p->x) == 0) || - (sp_384_iszero_7(p->y) == 0)) { - err = ECC_INF_E; - } + /* Check result is infinity */ + if ((err == MP_OKAY) && ((sp_384_iszero_7(p->x) == 0) || + (sp_384_iszero_7(p->y) == 0))) { + err = ECC_INF_E; } if (privm) { @@ -25544,12 +26196,11 @@ int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Base * private = point */ err = sp_384_ecc_mulmod_base_7(p, priv, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is public key */ - if (sp_384_cmp_7(p->x, pub->x) != 0 || - sp_384_cmp_7(p->y, pub->y) != 0) { - err = ECC_PRIV_KEY_E; - } + /* Check result is public key */ + if ((err == MP_OKAY) && + ((sp_384_cmp_7(p->x, pub->x) != 0) || + (sp_384_cmp_7(p->y, pub->y) != 0))) { + err = ECC_PRIV_KEY_E; } } @@ -25739,7 +26390,7 @@ int sp_ecc_map_384(mp_int* pX, mp_int* pY, mp_int* pZ) sp_384_from_mp(p->y, 7, pY); sp_384_from_mp(p->z, 7, pZ); - sp_384_map_7(p, p, tmp); + sp_384_map_7(p, p, tmp); } if (err == MP_OKAY) { @@ -25952,7 +26603,10349 @@ int sp_ecc_uncompress_384(mp_int* xm, int odd, mp_int* ym) } #endif #endif /* WOLFSSL_SP_384 */ +#ifdef WOLFSSL_SP_1024 + +/* Point structure to use. */ +typedef struct sp_point_1024 { + /* X ordinate of point. */ + sp_digit x[2 * 18]; + /* Y ordinate of point. */ + sp_digit y[2 * 18]; + /* Z ordinate of point. */ + sp_digit z[2 * 18]; + /* Indicates point is at infinity. */ + int infinity; +} sp_point_1024; + +#ifndef WOLFSSL_SP_SMALL +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static void sp_1024_mul_9(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + int128_t t0 = ((int128_t)a[ 0]) * b[ 0]; + int128_t t1 = ((int128_t)a[ 0]) * b[ 1] + + ((int128_t)a[ 1]) * b[ 0]; + int128_t t2 = ((int128_t)a[ 0]) * b[ 2] + + ((int128_t)a[ 1]) * b[ 1] + + ((int128_t)a[ 2]) * b[ 0]; + int128_t t3 = ((int128_t)a[ 0]) * b[ 3] + + ((int128_t)a[ 1]) * b[ 2] + + ((int128_t)a[ 2]) * b[ 1] + + ((int128_t)a[ 3]) * b[ 0]; + int128_t t4 = ((int128_t)a[ 0]) * b[ 4] + + ((int128_t)a[ 1]) * b[ 3] + + ((int128_t)a[ 2]) * b[ 2] + + ((int128_t)a[ 3]) * b[ 1] + + ((int128_t)a[ 4]) * b[ 0]; + int128_t t5 = ((int128_t)a[ 0]) * b[ 5] + + ((int128_t)a[ 1]) * b[ 4] + + ((int128_t)a[ 2]) * b[ 3] + + ((int128_t)a[ 3]) * b[ 2] + + ((int128_t)a[ 4]) * b[ 1] + + ((int128_t)a[ 5]) * b[ 0]; + int128_t t6 = ((int128_t)a[ 0]) * b[ 6] + + ((int128_t)a[ 1]) * b[ 5] + + ((int128_t)a[ 2]) * b[ 4] + + ((int128_t)a[ 3]) * b[ 3] + + ((int128_t)a[ 4]) * b[ 2] + + ((int128_t)a[ 5]) * b[ 1] + + ((int128_t)a[ 6]) * b[ 0]; + int128_t t7 = ((int128_t)a[ 0]) * b[ 7] + + ((int128_t)a[ 1]) * b[ 6] + + ((int128_t)a[ 2]) * b[ 5] + + ((int128_t)a[ 3]) * b[ 4] + + ((int128_t)a[ 4]) * b[ 3] + + ((int128_t)a[ 5]) * b[ 2] + + ((int128_t)a[ 6]) * b[ 1] + + ((int128_t)a[ 7]) * b[ 0]; + int128_t t8 = ((int128_t)a[ 0]) * b[ 8] + + ((int128_t)a[ 1]) * b[ 7] + + ((int128_t)a[ 2]) * b[ 6] + + ((int128_t)a[ 3]) * b[ 5] + + ((int128_t)a[ 4]) * b[ 4] + + ((int128_t)a[ 5]) * b[ 3] + + ((int128_t)a[ 6]) * b[ 2] + + ((int128_t)a[ 7]) * b[ 1] + + ((int128_t)a[ 8]) * b[ 0]; + int128_t t9 = ((int128_t)a[ 1]) * b[ 8] + + ((int128_t)a[ 2]) * b[ 7] + + ((int128_t)a[ 3]) * b[ 6] + + ((int128_t)a[ 4]) * b[ 5] + + ((int128_t)a[ 5]) * b[ 4] + + ((int128_t)a[ 6]) * b[ 3] + + ((int128_t)a[ 7]) * b[ 2] + + ((int128_t)a[ 8]) * b[ 1]; + int128_t t10 = ((int128_t)a[ 2]) * b[ 8] + + ((int128_t)a[ 3]) * b[ 7] + + ((int128_t)a[ 4]) * b[ 6] + + ((int128_t)a[ 5]) * b[ 5] + + ((int128_t)a[ 6]) * b[ 4] + + ((int128_t)a[ 7]) * b[ 3] + + ((int128_t)a[ 8]) * b[ 2]; + int128_t t11 = ((int128_t)a[ 3]) * b[ 8] + + ((int128_t)a[ 4]) * b[ 7] + + ((int128_t)a[ 5]) * b[ 6] + + ((int128_t)a[ 6]) * b[ 5] + + ((int128_t)a[ 7]) * b[ 4] + + ((int128_t)a[ 8]) * b[ 3]; + int128_t t12 = ((int128_t)a[ 4]) * b[ 8] + + ((int128_t)a[ 5]) * b[ 7] + + ((int128_t)a[ 6]) * b[ 6] + + ((int128_t)a[ 7]) * b[ 5] + + ((int128_t)a[ 8]) * b[ 4]; + int128_t t13 = ((int128_t)a[ 5]) * b[ 8] + + ((int128_t)a[ 6]) * b[ 7] + + ((int128_t)a[ 7]) * b[ 6] + + ((int128_t)a[ 8]) * b[ 5]; + int128_t t14 = ((int128_t)a[ 6]) * b[ 8] + + ((int128_t)a[ 7]) * b[ 7] + + ((int128_t)a[ 8]) * b[ 6]; + int128_t t15 = ((int128_t)a[ 7]) * b[ 8] + + ((int128_t)a[ 8]) * b[ 7]; + int128_t t16 = ((int128_t)a[ 8]) * b[ 8]; + + t1 += t0 >> 57; r[ 0] = t0 & 0x1ffffffffffffffL; + t2 += t1 >> 57; r[ 1] = t1 & 0x1ffffffffffffffL; + t3 += t2 >> 57; r[ 2] = t2 & 0x1ffffffffffffffL; + t4 += t3 >> 57; r[ 3] = t3 & 0x1ffffffffffffffL; + t5 += t4 >> 57; r[ 4] = t4 & 0x1ffffffffffffffL; + t6 += t5 >> 57; r[ 5] = t5 & 0x1ffffffffffffffL; + t7 += t6 >> 57; r[ 6] = t6 & 0x1ffffffffffffffL; + t8 += t7 >> 57; r[ 7] = t7 & 0x1ffffffffffffffL; + t9 += t8 >> 57; r[ 8] = t8 & 0x1ffffffffffffffL; + t10 += t9 >> 57; r[ 9] = t9 & 0x1ffffffffffffffL; + t11 += t10 >> 57; r[10] = t10 & 0x1ffffffffffffffL; + t12 += t11 >> 57; r[11] = t11 & 0x1ffffffffffffffL; + t13 += t12 >> 57; r[12] = t12 & 0x1ffffffffffffffL; + t14 += t13 >> 57; r[13] = t13 & 0x1ffffffffffffffL; + t15 += t14 >> 57; r[14] = t14 & 0x1ffffffffffffffL; + t16 += t15 >> 57; r[15] = t15 & 0x1ffffffffffffffL; + r[17] = (sp_digit)(t16 >> 57); + r[16] = t16 & 0x1ffffffffffffffL; +} + +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_1024_sqr_9(sp_digit* r, const sp_digit* a) +{ + int128_t t0 = ((int128_t)a[ 0]) * a[ 0]; + int128_t t1 = (((int128_t)a[ 0]) * a[ 1]) * 2; + int128_t t2 = (((int128_t)a[ 0]) * a[ 2]) * 2 + + ((int128_t)a[ 1]) * a[ 1]; + int128_t t3 = (((int128_t)a[ 0]) * a[ 3] + + ((int128_t)a[ 1]) * a[ 2]) * 2; + int128_t t4 = (((int128_t)a[ 0]) * a[ 4] + + ((int128_t)a[ 1]) * a[ 3]) * 2 + + ((int128_t)a[ 2]) * a[ 2]; + int128_t t5 = (((int128_t)a[ 0]) * a[ 5] + + ((int128_t)a[ 1]) * a[ 4] + + ((int128_t)a[ 2]) * a[ 3]) * 2; + int128_t t6 = (((int128_t)a[ 0]) * a[ 6] + + ((int128_t)a[ 1]) * a[ 5] + + ((int128_t)a[ 2]) * a[ 4]) * 2 + + ((int128_t)a[ 3]) * a[ 3]; + int128_t t7 = (((int128_t)a[ 0]) * a[ 7] + + ((int128_t)a[ 1]) * a[ 6] + + ((int128_t)a[ 2]) * a[ 5] + + ((int128_t)a[ 3]) * a[ 4]) * 2; + int128_t t8 = (((int128_t)a[ 0]) * a[ 8] + + ((int128_t)a[ 1]) * a[ 7] + + ((int128_t)a[ 2]) * a[ 6] + + ((int128_t)a[ 3]) * a[ 5]) * 2 + + ((int128_t)a[ 4]) * a[ 4]; + int128_t t9 = (((int128_t)a[ 1]) * a[ 8] + + ((int128_t)a[ 2]) * a[ 7] + + ((int128_t)a[ 3]) * a[ 6] + + ((int128_t)a[ 4]) * a[ 5]) * 2; + int128_t t10 = (((int128_t)a[ 2]) * a[ 8] + + ((int128_t)a[ 3]) * a[ 7] + + ((int128_t)a[ 4]) * a[ 6]) * 2 + + ((int128_t)a[ 5]) * a[ 5]; + int128_t t11 = (((int128_t)a[ 3]) * a[ 8] + + ((int128_t)a[ 4]) * a[ 7] + + ((int128_t)a[ 5]) * a[ 6]) * 2; + int128_t t12 = (((int128_t)a[ 4]) * a[ 8] + + ((int128_t)a[ 5]) * a[ 7]) * 2 + + ((int128_t)a[ 6]) * a[ 6]; + int128_t t13 = (((int128_t)a[ 5]) * a[ 8] + + ((int128_t)a[ 6]) * a[ 7]) * 2; + int128_t t14 = (((int128_t)a[ 6]) * a[ 8]) * 2 + + ((int128_t)a[ 7]) * a[ 7]; + int128_t t15 = (((int128_t)a[ 7]) * a[ 8]) * 2; + int128_t t16 = ((int128_t)a[ 8]) * a[ 8]; + + t1 += t0 >> 57; r[ 0] = t0 & 0x1ffffffffffffffL; + t2 += t1 >> 57; r[ 1] = t1 & 0x1ffffffffffffffL; + t3 += t2 >> 57; r[ 2] = t2 & 0x1ffffffffffffffL; + t4 += t3 >> 57; r[ 3] = t3 & 0x1ffffffffffffffL; + t5 += t4 >> 57; r[ 4] = t4 & 0x1ffffffffffffffL; + t6 += t5 >> 57; r[ 5] = t5 & 0x1ffffffffffffffL; + t7 += t6 >> 57; r[ 6] = t6 & 0x1ffffffffffffffL; + t8 += t7 >> 57; r[ 7] = t7 & 0x1ffffffffffffffL; + t9 += t8 >> 57; r[ 8] = t8 & 0x1ffffffffffffffL; + t10 += t9 >> 57; r[ 9] = t9 & 0x1ffffffffffffffL; + t11 += t10 >> 57; r[10] = t10 & 0x1ffffffffffffffL; + t12 += t11 >> 57; r[11] = t11 & 0x1ffffffffffffffL; + t13 += t12 >> 57; r[12] = t12 & 0x1ffffffffffffffL; + t14 += t13 >> 57; r[13] = t13 & 0x1ffffffffffffffL; + t15 += t14 >> 57; r[14] = t14 & 0x1ffffffffffffffL; + t16 += t15 >> 57; r[15] = t15 & 0x1ffffffffffffffL; + r[17] = (sp_digit)(t16 >> 57); + r[16] = t16 & 0x1ffffffffffffffL; +} + +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_1024_add_9(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + r[ 0] = a[ 0] + b[ 0]; + r[ 1] = a[ 1] + b[ 1]; + r[ 2] = a[ 2] + b[ 2]; + r[ 3] = a[ 3] + b[ 3]; + r[ 4] = a[ 4] + b[ 4]; + r[ 5] = a[ 5] + b[ 5]; + r[ 6] = a[ 6] + b[ 6]; + r[ 7] = a[ 7] + b[ 7]; + r[ 8] = a[ 8] + b[ 8]; + + return 0; +} + +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_1024_add_18(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + int i; + + for (i = 0; i < 16; i += 8) { + r[i + 0] = a[i + 0] + b[i + 0]; + r[i + 1] = a[i + 1] + b[i + 1]; + r[i + 2] = a[i + 2] + b[i + 2]; + r[i + 3] = a[i + 3] + b[i + 3]; + r[i + 4] = a[i + 4] + b[i + 4]; + r[i + 5] = a[i + 5] + b[i + 5]; + r[i + 6] = a[i + 6] + b[i + 6]; + r[i + 7] = a[i + 7] + b[i + 7]; + } + r[16] = a[16] + b[16]; + r[17] = a[17] + b[17]; + + return 0; +} + +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_1024_sub_18(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + int i; + + for (i = 0; i < 16; i += 8) { + r[i + 0] = a[i + 0] - b[i + 0]; + r[i + 1] = a[i + 1] - b[i + 1]; + r[i + 2] = a[i + 2] - b[i + 2]; + r[i + 3] = a[i + 3] - b[i + 3]; + r[i + 4] = a[i + 4] - b[i + 4]; + r[i + 5] = a[i + 5] - b[i + 5]; + r[i + 6] = a[i + 6] - b[i + 6]; + r[i + 7] = a[i + 7] - b[i + 7]; + } + r[16] = a[16] - b[16]; + r[17] = a[17] - b[17]; + + return 0; +} + +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static void sp_1024_mul_18(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit* z0 = r; + sp_digit z1[18]; + sp_digit* a1 = z1; + sp_digit b1[9]; + sp_digit* z2 = r + 18; + (void)sp_1024_add_9(a1, a, &a[9]); + (void)sp_1024_add_9(b1, b, &b[9]); + sp_1024_mul_9(z2, &a[9], &b[9]); + sp_1024_mul_9(z0, a, b); + sp_1024_mul_9(z1, a1, b1); + (void)sp_1024_sub_18(z1, z1, z2); + (void)sp_1024_sub_18(z1, z1, z0); + (void)sp_1024_add_18(r + 9, r + 9, z1); +} + +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_1024_sqr_18(sp_digit* r, const sp_digit* a) +{ + sp_digit* z0 = r; + sp_digit z1[18]; + sp_digit* a1 = z1; + sp_digit* z2 = r + 18; + (void)sp_1024_add_9(a1, a, &a[9]); + sp_1024_sqr_9(z2, &a[9]); + sp_1024_sqr_9(z0, a); + sp_1024_sqr_9(z1, a1); + (void)sp_1024_sub_18(z1, z1, z2); + (void)sp_1024_sub_18(z1, z1, z0); + (void)sp_1024_add_18(r + 9, r + 9, z1); +} + +#else +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static void sp_1024_mul_18(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + int i; + int j; + int k; + int128_t c; + + c = ((int128_t)a[17]) * b[17]; + r[35] = (sp_digit)(c >> 57); + c = (c & 0x1ffffffffffffffL) << 57; + for (k = 33; k >= 0; k--) { + for (i = 17; i >= 0; i--) { + j = k - i; + if (j >= 18) { + break; + } + if (j < 0) { + continue; + } + + c += ((int128_t)a[i]) * b[j]; + } + r[k + 2] += (sp_digit)(c >> 114); + r[k + 1] = (sp_digit)((c >> 57) & 0x1ffffffffffffffL); + c = (c & 0x1ffffffffffffffL) << 57; + } + r[0] = (sp_digit)(c >> 57); +} + +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_1024_sqr_18(sp_digit* r, const sp_digit* a) +{ + int i; + int j; + int k; + int128_t c; + + c = ((int128_t)a[17]) * a[17]; + r[35] = (sp_digit)(c >> 57); + c = (c & 0x1ffffffffffffffL) << 57; + for (k = 33; k >= 0; k--) { + for (i = 17; i >= 0; i--) { + j = k - i; + if (j >= 18 || i <= j) { + break; + } + if (j < 0) { + continue; + } + + c += ((int128_t)a[i]) * a[j] * 2; + } + if (i == j) { + c += ((int128_t)a[i]) * a[i]; + } + + r[k + 2] += (sp_digit)(c >> 114); + r[k + 1] = (sp_digit)((c >> 57) & 0x1ffffffffffffffL); + c = (c & 0x1ffffffffffffffL) << 57; + } + r[0] = (sp_digit)(c >> 57); +} + +#endif /* !WOLFSSL_SP_SMALL */ +/* The modulus (prime) of the curve P1024. */ +static const sp_digit p1024_mod[18] = { + 0x06d807afea85febL,0x0ef88563d6743b3L,0x008e2615f6c2031L,0x1ead2e3e3ff9c7dL, + 0x1c3c09aa9f94d6aL,0x02954153e79e290L,0x07386dabfd2a0c6L,0x1a8a2558b9acad0L, + 0x0e26c6487326b4cL,0x0b693fa53335368L,0x06ce7fdf222864dL,0x01aa634b3961cf2L, + 0x07e2fc0f1b22873L,0x19f00d177a05559L,0x0d20986fa6b8d62L,0x0caf482d819c339L, + 0x1da65c61198dad0L,0x04cbd5d8f852b1fL +}; +/* The Montogmery normalizer for modulus of the curve P1024. */ +static const sp_digit p1024_norm_mod[18] = { + 0x1927f850157a015L,0x11077a9c298bc4cL,0x1f71d9ea093dfceL,0x0152d1c1c006382L, + 0x03c3f655606b295L,0x1d6abeac1861d6fL,0x18c7925402d5f39L,0x0575daa7465352fL, + 0x11d939b78cd94b3L,0x1496c05acccac97L,0x19318020ddd79b2L,0x1e559cb4c69e30dL, + 0x181d03f0e4dd78cL,0x060ff2e885faaa6L,0x12df6790594729dL,0x1350b7d27e63cc6L, + 0x0259a39ee67252fL,0x03342a2707ad4e0L +}; +/* The Montogmery multiplier for modulus of the curve P1024. */ +static sp_digit p1024_mp_mod = 0x10420077c8f2f3d; +#if defined(WOLFSSL_SP_SMALL) || defined(HAVE_ECC_CHECK_KEY) +/* The order of the curve P1024. */ +static const sp_digit p1024_order[18] = { + 0x19b601ebfaa17fbL,0x0bbe2158f59d0ecL,0x082389857db080cL,0x17ab4b8f8ffe71fL, + 0x070f026aa7e535aL,0x10a55054f9e78a4L,0x01ce1b6aff4a831L,0x06a289562e6b2b4L, + 0x0389b1921cc9ad3L,0x0ada4fe94ccd4daL,0x11b39ff7c88a193L,0x186a98d2ce5873cL, + 0x09f8bf03c6c8a1cL,0x167c0345de81556L,0x0b48261be9ae358L,0x032bd20b60670ceL, + 0x1f69971846636b4L,0x0132f5763e14ac7L +}; +#endif +/* The base point of curve P1024. */ +static const sp_point_1024 p1024_base = { + /* X ordinate */ + { + 0x00dc8abeae63895L,0x023624b3f04bcc4L,0x0e96d8fdcfb203bL, + 0x1900e51b0fdd22cL,0x1a66910dd5cfb4cL,0x106f3a53e0a8a6dL, + 0x1cb869c0b0ce5e9L,0x19666f90ca916e5L,0x09760af765dd5bcL, + 0x0c5ecf3a0367448L,0x17c8b36e77e955cL,0x172061613c2087aL, + 0x00f6ce2308ab10dL,0x1b7fbe5fdaf6db6L,0x1b1a71a62cbc812L, + 0x16a5456345fac15L,0x1ad0a7990053ed9L,0x029fe04f7199614L, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* Y ordinate */ + { + 0x1573fd71bef16d7L,0x0dab83533ee6f3aL,0x156b56ed18dab6eL, + 0x0fd3973353017b5L,0x05a4d5f213515adL,0x0554c4a496cbcfeL, + 0x0bf82b1bc7a0059L,0x0d995ad2d6b6ecaL,0x170dae117ad547cL, + 0x0b67f8654f0195cL,0x06333e68502cb90L,0x0bcbe1bcabecd6bL, + 0x14654ec2b9e7f7fL,0x0f0a08bc7af534fL,0x0641a58f5de3608L, + 0x1426ba7d0402c05L,0x1f1f9f1f0533634L,0x0054124831fb004L, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* Z ordinate */ + { + 0x000000000000001L,0x000000000000000L,0x000000000000000L, + 0x000000000000000L,0x000000000000000L,0x000000000000000L, + 0x000000000000000L,0x000000000000000L,0x000000000000000L, + 0x000000000000000L,0x000000000000000L,0x000000000000000L, + 0x000000000000000L,0x000000000000000L,0x000000000000000L, + 0x000000000000000L,0x000000000000000L,0x000000000000000L, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* infinity */ + 0 +}; + +/* Multiply a by scalar b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A scalar. + */ +SP_NOINLINE static void sp_1024_mul_d_18(sp_digit* r, const sp_digit* a, + sp_digit b) +{ +#ifdef WOLFSSL_SP_SMALL + int128_t tb = b; + int128_t t = 0; + int i; + + for (i = 0; i < 18; i++) { + t += tb * a[i]; + r[i] = (sp_digit)(t & 0x1ffffffffffffffL); + t >>= 57; + } + r[18] = (sp_digit)t; +#else + int128_t tb = b; + int128_t t = 0; + sp_digit t2; + int128_t p[4]; + int i; + + for (i = 0; i < 16; i += 4) { + p[0] = tb * a[i + 0]; + p[1] = tb * a[i + 1]; + p[2] = tb * a[i + 2]; + p[3] = tb * a[i + 3]; + t += p[0]; + t2 = (sp_digit)(t & 0x1ffffffffffffffL); + t >>= 57; + r[i + 0] = (sp_digit)t2; + t += p[1]; + t2 = (sp_digit)(t & 0x1ffffffffffffffL); + t >>= 57; + r[i + 1] = (sp_digit)t2; + t += p[2]; + t2 = (sp_digit)(t & 0x1ffffffffffffffL); + t >>= 57; + r[i + 2] = (sp_digit)t2; + t += p[3]; + t2 = (sp_digit)(t & 0x1ffffffffffffffL); + t >>= 57; + r[i + 3] = (sp_digit)t2; + } + t += tb * a[16]; + r[16] = (sp_digit)(t & 0x1ffffffffffffffL); + t >>= 57; + t += tb * a[17]; + r[17] = (sp_digit)(t & 0x1ffffffffffffffL); + t >>= 57; + r[18] = (sp_digit)(t & 0x1ffffffffffffffL); +#endif /* WOLFSSL_SP_SMALL */ +} + +/* Conditionally add a and b using the mask m. + * m is -1 to add and 0 when not. + * + * r A single precision number representing conditional add result. + * a A single precision number to add with. + * b A single precision number to add. + * m Mask value to apply. + */ +static void sp_1024_cond_add_18(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit m) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i = 0; i < 18; i++) { + r[i] = a[i] + (b[i] & m); + } +#else + int i; + + for (i = 0; i < 16; i += 8) { + r[i + 0] = a[i + 0] + (b[i + 0] & m); + r[i + 1] = a[i + 1] + (b[i + 1] & m); + r[i + 2] = a[i + 2] + (b[i + 2] & m); + r[i + 3] = a[i + 3] + (b[i + 3] & m); + r[i + 4] = a[i + 4] + (b[i + 4] & m); + r[i + 5] = a[i + 5] + (b[i + 5] & m); + r[i + 6] = a[i + 6] + (b[i + 6] & m); + r[i + 7] = a[i + 7] + (b[i + 7] & m); + } + r[16] = a[16] + (b[16] & m); + r[17] = a[17] + (b[17] & m); +#endif /* WOLFSSL_SP_SMALL */ +} + +#ifdef WOLFSSL_SP_SMALL +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_1024_sub_18(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + int i; + + for (i = 0; i < 18; i++) { + r[i] = a[i] - b[i]; + } + + return 0; +} + +#endif +#ifdef WOLFSSL_SP_SMALL +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static int sp_1024_add_18(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + int i; + + for (i = 0; i < 18; i++) { + r[i] = a[i] + b[i]; + } + + return 0; +} +#endif +#ifdef WOLFSSL_SP_DIV_64 +static WC_INLINE sp_digit sp_1024_div_word_18(sp_digit d1, sp_digit d0, + sp_digit dv) +{ + sp_digit d; + sp_digit r; + sp_digit t; + + /* All 57 bits from d1 and top 6 bits from d0. */ + d = (d1 << 6) | (d0 >> 51); + r = d / dv; + d -= r * dv; + /* Up to 7 bits in r */ + /* Next 6 bits from d0. */ + r <<= 6; + d <<= 6; + d |= (d0 >> 45) & ((1 << 6) - 1); + t = d / dv; + d -= t * dv; + r += t; + /* Up to 13 bits in r */ + /* Next 6 bits from d0. */ + r <<= 6; + d <<= 6; + d |= (d0 >> 39) & ((1 << 6) - 1); + t = d / dv; + d -= t * dv; + r += t; + /* Up to 19 bits in r */ + /* Next 6 bits from d0. */ + r <<= 6; + d <<= 6; + d |= (d0 >> 33) & ((1 << 6) - 1); + t = d / dv; + d -= t * dv; + r += t; + /* Up to 25 bits in r */ + /* Next 6 bits from d0. */ + r <<= 6; + d <<= 6; + d |= (d0 >> 27) & ((1 << 6) - 1); + t = d / dv; + d -= t * dv; + r += t; + /* Up to 31 bits in r */ + /* Next 6 bits from d0. */ + r <<= 6; + d <<= 6; + d |= (d0 >> 21) & ((1 << 6) - 1); + t = d / dv; + d -= t * dv; + r += t; + /* Up to 37 bits in r */ + /* Next 6 bits from d0. */ + r <<= 6; + d <<= 6; + d |= (d0 >> 15) & ((1 << 6) - 1); + t = d / dv; + d -= t * dv; + r += t; + /* Up to 43 bits in r */ + /* Next 6 bits from d0. */ + r <<= 6; + d <<= 6; + d |= (d0 >> 9) & ((1 << 6) - 1); + t = d / dv; + d -= t * dv; + r += t; + /* Up to 49 bits in r */ + /* Next 6 bits from d0. */ + r <<= 6; + d <<= 6; + d |= (d0 >> 3) & ((1 << 6) - 1); + t = d / dv; + d -= t * dv; + r += t; + /* Up to 55 bits in r */ + /* Remaining 3 bits from d0. */ + r <<= 3; + d <<= 3; + d |= d0 & ((1 << 3) - 1); + t = d / dv; + r += t; + + return r; +} +#endif /* WOLFSSL_SP_DIV_64 */ + +/* Divide d in a and put remainder into r (m*d + r = a) + * m is not calculated as it is not needed at this time. + * + * Large number of bits in last word. + * + * a Number to be divided. + * d Number to divide with. + * m Multiplier result. + * r Remainder from the division. + * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise. + */ +static int sp_1024_div_18(const sp_digit* a, const sp_digit* d, + const sp_digit* m, sp_digit* r) +{ + int i; +#ifndef WOLFSSL_SP_DIV_64 + int128_t d1; +#endif + sp_digit dv; + sp_digit r1; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td; +#else + sp_digit t1d[36]; + sp_digit t2d[18 + 1]; +#endif + sp_digit* t1; + sp_digit* t2; + int err = MP_OKAY; + + (void)m; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * (3 * 18 + 1), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t1 = td; + t2 = td + 2 * 18; +#else + t1 = t1d; + t2 = t2d; +#endif + + dv = d[17]; + XMEMCPY(t1, a, sizeof(*t1) * 2U * 18U); + for (i=17; i>=0; i--) { + t1[18 + i] += t1[18 + i - 1] >> 57; + t1[18 + i - 1] &= 0x1ffffffffffffffL; +#ifndef WOLFSSL_SP_DIV_64 + d1 = t1[18 + i]; + d1 <<= 57; + d1 += t1[18 + i - 1]; + r1 = (sp_digit)(d1 / dv); +#else + r1 = sp_1024_div_word_18(t1[18 + i], t1[18 + i - 1], dv); +#endif + + sp_1024_mul_d_18(t2, d, r1); + (void)sp_1024_sub_18(&t1[i], &t1[i], t2); + t1[18 + i] -= t2[18]; + t1[18 + i] += t1[18 + i - 1] >> 57; + t1[18 + i - 1] &= 0x1ffffffffffffffL; + r1 = (((-t1[18 + i]) << 57) - t1[18 + i - 1]) / dv; + r1++; + sp_1024_mul_d_18(t2, d, r1); + (void)sp_1024_add_18(&t1[i], &t1[i], t2); + t1[18 + i] += t1[18 + i - 1] >> 57; + t1[18 + i - 1] &= 0x1ffffffffffffffL; + } + t1[18 - 1] += t1[18 - 2] >> 57; + t1[18 - 2] &= 0x1ffffffffffffffL; + r1 = t1[18 - 1] / dv; + + sp_1024_mul_d_18(t2, d, r1); + (void)sp_1024_sub_18(t1, t1, t2); + XMEMCPY(r, t1, sizeof(*r) * 36U); + for (i=0; i<17; i++) { + r[i+1] += r[i] >> 57; + r[i] &= 0x1ffffffffffffffL; + } + sp_1024_cond_add_18(r, r, d, 0 - ((r[17] < 0) ? + (sp_digit)1 : (sp_digit)0)); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + + return err; +} + +/* Reduce a modulo m into r. (r = a mod m) + * + * r A single precision number that is the reduced result. + * a A single precision number that is to be reduced. + * m A single precision number that is the modulus to reduce with. + * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise. + */ +static int sp_1024_mod_18(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + return sp_1024_div_18(a, m, NULL, r); +} + +/* Multiply a number by Montogmery normalizer mod modulus (prime). + * + * r The resulting Montgomery form number. + * a The number to convert. + * m The modulus (prime). + * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. + */ +static int sp_1024_mod_mul_norm_18(sp_digit* r, const sp_digit* a, + const sp_digit* m) +{ + sp_1024_mul_18(r, a, p1024_norm_mod); + return sp_1024_mod_18(r, r, m); +} + +/* Create a new point. + * + * heap [in] Buffer to allocate dynamic memory from. + * sp [in] Data for point - only if not allocating. + * p [out] New point. + * returns MEMORY_E when dynamic memory allocation fails and 0 otherwise. + */ +static int sp_1024_point_new_ex_18(void* heap, sp_point_1024* sp, + sp_point_1024** p) +{ + int ret = MP_OKAY; + (void)heap; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + (void)sp; + *p = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024), heap, DYNAMIC_TYPE_ECC); +#else + *p = sp; +#endif + if (*p == NULL) { + ret = MEMORY_E; + } + return ret; +} + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* Allocate memory for point and return error. */ +#define sp_1024_point_new_18(heap, sp, p) sp_1024_point_new_ex_18((heap), NULL, &(p)) +#else +/* Set pointer to data and return no error. */ +#define sp_1024_point_new_18(heap, sp, p) sp_1024_point_new_ex_18((heap), &(sp), &(p)) +#endif + + +/* Free the point. + * + * p [in,out] Point to free. + * clear [in] Indicates whether to zeroize point. + * heap [in] Buffer from which dynamic memory was allocate from. + */ +static void sp_1024_point_free_18(sp_point_1024* p, int clear, void* heap) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* If valid pointer then clear point data if requested and free data. */ + if (p != NULL) { + if (clear != 0) { + XMEMSET(p, 0, sizeof(*p)); + } + XFREE(p, heap, DYNAMIC_TYPE_ECC); + } +#else +/* Clear point data if requested. */ + if ((p != NULL) && (clear != 0)) { + XMEMSET(p, 0, sizeof(*p)); + } +#endif + (void)heap; +} + +/* Convert an mp_int to an array of sp_digit. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a A multi-precision integer. + */ +static void sp_1024_from_mp(sp_digit* r, int size, const mp_int* a) +{ +#if DIGIT_BIT == 57 + int j; + + XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); + + for (j = a->used; j < size; j++) { + r[j] = 0; + } +#elif DIGIT_BIT > 57 + int i; + int j = 0; + word32 s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i] << s); + r[j] &= 0x1ffffffffffffffL; + s = 57U - s; + if (j + 1 >= size) { + break; + } + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + while ((s + 57U) <= (word32)DIGIT_BIT) { + s += 57U; + r[j] &= 0x1ffffffffffffffL; + if (j + 1 >= size) { + break; + } + if (s < (word32)DIGIT_BIT) { + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + } + else { + r[++j] = 0L; + } + } + s = (word32)DIGIT_BIT - s; + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#else + int i; + int j = 0; + int s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i]) << s; + if (s + DIGIT_BIT >= 57) { + r[j] &= 0x1ffffffffffffffL; + if (j + 1 >= size) { + break; + } + s = 57 - s; + if (s == DIGIT_BIT) { + r[++j] = 0; + s = 0; + } + else { + r[++j] = a->dp[i] >> s; + s = DIGIT_BIT - s; + } + } + else { + s += DIGIT_BIT; + } + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#endif +} + +/* Convert a point of type ecc_point to type sp_point_1024. + * + * p Point of type sp_point_1024 (result). + * pm Point of type ecc_point. + */ +static void sp_1024_point_from_ecc_point_18(sp_point_1024* p, + const ecc_point* pm) +{ + XMEMSET(p->x, 0, sizeof(p->x)); + XMEMSET(p->y, 0, sizeof(p->y)); + XMEMSET(p->z, 0, sizeof(p->z)); + sp_1024_from_mp(p->x, 18, pm->x); + sp_1024_from_mp(p->y, 18, pm->y); + sp_1024_from_mp(p->z, 18, pm->z); + p->infinity = 0; +} + +/* Convert an array of sp_digit to an mp_int. + * + * a A single precision integer. + * r A multi-precision integer. + */ +static int sp_1024_to_mp(const sp_digit* a, mp_int* r) +{ + int err; + + err = mp_grow(r, (1024 + DIGIT_BIT - 1) / DIGIT_BIT); + if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ +#if DIGIT_BIT == 57 + XMEMCPY(r->dp, a, sizeof(sp_digit) * 18); + r->used = 18; + mp_clamp(r); +#elif DIGIT_BIT < 57 + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 18; i++) { + r->dp[j] |= (mp_digit)(a[i] << s); + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + s = DIGIT_BIT - s; + r->dp[++j] = (mp_digit)(a[i] >> s); + while (s + DIGIT_BIT <= 57) { + s += DIGIT_BIT; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; + if (s == SP_WORD_SIZE) { + r->dp[j] = 0; + } + else { + r->dp[j] = (mp_digit)(a[i] >> s); + } + } + s = 57 - s; + } + r->used = (1024 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#else + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 18; i++) { + r->dp[j] |= ((mp_digit)a[i]) << s; + if (s + 57 >= DIGIT_BIT) { + #if DIGIT_BIT != 32 && DIGIT_BIT != 64 + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + #endif + s = DIGIT_BIT - s; + r->dp[++j] = a[i] >> s; + s = 57 - s; + } + else { + s += 57; + } + } + r->used = (1024 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#endif + } + + return err; +} + +/* Convert a point of type sp_point_1024 to type ecc_point. + * + * p Point of type sp_point_1024. + * pm Point of type ecc_point (result). + * returns MEMORY_E when allocation of memory in ecc_point fails otherwise + * MP_OKAY. + */ +static int sp_1024_point_to_ecc_point_18(const sp_point_1024* p, ecc_point* pm) +{ + int err; + + err = sp_1024_to_mp(p->x, pm->x); + if (err == MP_OKAY) { + err = sp_1024_to_mp(p->y, pm->y); + } + if (err == MP_OKAY) { + err = sp_1024_to_mp(p->z, pm->z); + } + + return err; +} + +/* Compare a with b in constant time. + * + * a A single precision integer. + * b A single precision integer. + * return -ve, 0 or +ve if a is less than, equal to or greater than b + * respectively. + */ +static sp_digit sp_1024_cmp_18(const sp_digit* a, const sp_digit* b) +{ + sp_digit r = 0; +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i=17; i>=0; i--) { + r |= (a[i] - b[i]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + } +#else + int i; + + r |= (a[17] - b[17]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[16] - b[16]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + for (i = 8; i >= 0; i -= 8) { + r |= (a[i + 7] - b[i + 7]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[i + 6] - b[i + 6]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[i + 5] - b[i + 5]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[i + 4] - b[i + 4]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[i + 3] - b[i + 3]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[i + 2] - b[i + 2]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[i + 1] - b[i + 1]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[i + 0] - b[i + 0]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + } +#endif /* WOLFSSL_SP_SMALL */ + + return r; +} + +/* Conditionally subtract b from a using the mask m. + * m is -1 to subtract and 0 when not. + * + * r A single precision number representing condition subtract result. + * a A single precision number to subtract from. + * b A single precision number to subtract. + * m Mask value to apply. + */ +static void sp_1024_cond_sub_18(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit m) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i = 0; i < 18; i++) { + r[i] = a[i] - (b[i] & m); + } +#else + int i; + + for (i = 0; i < 16; i += 8) { + r[i + 0] = a[i + 0] - (b[i + 0] & m); + r[i + 1] = a[i + 1] - (b[i + 1] & m); + r[i + 2] = a[i + 2] - (b[i + 2] & m); + r[i + 3] = a[i + 3] - (b[i + 3] & m); + r[i + 4] = a[i + 4] - (b[i + 4] & m); + r[i + 5] = a[i + 5] - (b[i + 5] & m); + r[i + 6] = a[i + 6] - (b[i + 6] & m); + r[i + 7] = a[i + 7] - (b[i + 7] & m); + } + r[16] = a[16] - (b[16] & m); + r[17] = a[17] - (b[17] & m); +#endif /* WOLFSSL_SP_SMALL */ +} + +/* Mul a by scalar b and add into r. (r += a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A scalar. + */ +SP_NOINLINE static void sp_1024_mul_add_18(sp_digit* r, const sp_digit* a, + const sp_digit b) +{ +#ifdef WOLFSSL_SP_SMALL + int128_t tb = b; + int128_t t = 0; + int i; + + for (i = 0; i < 18; i++) { + t += (tb * a[i]) + r[i]; + r[i] = t & 0x1ffffffffffffffL; + t >>= 57; + } + r[18] += (sp_digit)t; +#else + int128_t tb = b; + int128_t t[8]; + int i; + + t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1ffffffffffffffL); + for (i = 0; i < 16; i += 8) { + t[1] = tb * a[i+1]; + r[i+1] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL)); + t[2] = tb * a[i+2]; + r[i+2] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL)); + t[3] = tb * a[i+3]; + r[i+3] += (sp_digit)((t[2] >> 57) + (t[3] & 0x1ffffffffffffffL)); + t[4] = tb * a[i+4]; + r[i+4] += (sp_digit)((t[3] >> 57) + (t[4] & 0x1ffffffffffffffL)); + t[5] = tb * a[i+5]; + r[i+5] += (sp_digit)((t[4] >> 57) + (t[5] & 0x1ffffffffffffffL)); + t[6] = tb * a[i+6]; + r[i+6] += (sp_digit)((t[5] >> 57) + (t[6] & 0x1ffffffffffffffL)); + t[7] = tb * a[i+7]; + r[i+7] += (sp_digit)((t[6] >> 57) + (t[7] & 0x1ffffffffffffffL)); + t[0] = tb * a[i+8]; + r[i+8] += (sp_digit)((t[7] >> 57) + (t[0] & 0x1ffffffffffffffL)); + } + t[1] = tb * a[17]; r[17] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL)); + r[18] += (sp_digit)(t[1] >> 57); +#endif /* WOLFSSL_SP_SMALL */ +} + +/* Normalize the values in each word to 57. + * + * a Array of sp_digit to normalize. + */ +static void sp_1024_norm_18(sp_digit* a) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + for (i = 0; i < 17; i++) { + a[i+1] += a[i] >> 57; + a[i] &= 0x1ffffffffffffffL; + } +#else + int i; + for (i = 0; i < 16; i += 8) { + a[i+1] += a[i+0] >> 57; a[i+0] &= 0x1ffffffffffffffL; + a[i+2] += a[i+1] >> 57; a[i+1] &= 0x1ffffffffffffffL; + a[i+3] += a[i+2] >> 57; a[i+2] &= 0x1ffffffffffffffL; + a[i+4] += a[i+3] >> 57; a[i+3] &= 0x1ffffffffffffffL; + a[i+5] += a[i+4] >> 57; a[i+4] &= 0x1ffffffffffffffL; + a[i+6] += a[i+5] >> 57; a[i+5] &= 0x1ffffffffffffffL; + a[i+7] += a[i+6] >> 57; a[i+6] &= 0x1ffffffffffffffL; + a[i+8] += a[i+7] >> 57; a[i+7] &= 0x1ffffffffffffffL; + } + a[16+1] += a[16] >> 57; a[16] &= 0x1ffffffffffffffL; +#endif +} + +/* Shift the result in the high 1024 bits down to the bottom. + * + * r A single precision number. + * a A single precision number. + */ +static void sp_1024_mont_shift_18(sp_digit* r, const sp_digit* a) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + word64 n; + + n = a[17] >> 55; + for (i = 0; i < 17; i++) { + n += (word64)a[18 + i] << 2; + r[i] = n & 0x1ffffffffffffffL; + n >>= 57; + } + n += (word64)a[35] << 2; + r[17] = n; +#else + word64 n; + int i; + + n = (word64)a[17]; + n = n >> 55U; + for (i = 0; i < 16; i += 8) { + n += (word64)a[i+18] << 2U; r[i+0] = n & 0x1ffffffffffffffUL; n >>= 57U; + n += (word64)a[i+19] << 2U; r[i+1] = n & 0x1ffffffffffffffUL; n >>= 57U; + n += (word64)a[i+20] << 2U; r[i+2] = n & 0x1ffffffffffffffUL; n >>= 57U; + n += (word64)a[i+21] << 2U; r[i+3] = n & 0x1ffffffffffffffUL; n >>= 57U; + n += (word64)a[i+22] << 2U; r[i+4] = n & 0x1ffffffffffffffUL; n >>= 57U; + n += (word64)a[i+23] << 2U; r[i+5] = n & 0x1ffffffffffffffUL; n >>= 57U; + n += (word64)a[i+24] << 2U; r[i+6] = n & 0x1ffffffffffffffUL; n >>= 57U; + n += (word64)a[i+25] << 2U; r[i+7] = n & 0x1ffffffffffffffUL; n >>= 57U; + } + n += (word64)a[34] << 2U; r[16] = n & 0x1ffffffffffffffUL; n >>= 57U; + n += (word64)a[35] << 2U; r[17] = n; +#endif /* WOLFSSL_SP_SMALL */ + XMEMSET(&r[18], 0, sizeof(*r) * 18U); +} + +/* Reduce the number back to 1024 bits using Montgomery reduction. + * + * a A single precision number to reduce in place. + * m The single precision number representing the modulus. + * mp The digit representing the negative inverse of m mod 2^n. + */ +static void sp_1024_mont_reduce_18(sp_digit* a, const sp_digit* m, sp_digit mp) +{ + int i; + sp_digit mu; + + sp_1024_norm_18(a + 18); + +#ifdef WOLFSSL_SP_DH + if (mp != 1) { + for (i=0; i<17; i++) { + mu = (a[i] * mp) & 0x1ffffffffffffffL; + sp_1024_mul_add_18(a+i, m, mu); + a[i+1] += a[i] >> 57; + } + mu = (a[i] * mp) & 0x7fffffffffffffL; + sp_1024_mul_add_18(a+i, m, mu); + a[i+1] += a[i] >> 57; + a[i] &= 0x1ffffffffffffffL; + } + else { + for (i=0; i<17; i++) { + mu = a[i] & 0x1ffffffffffffffL; + sp_1024_mul_add_18(a+i, m, mu); + a[i+1] += a[i] >> 57; + } + mu = a[i] & 0x7fffffffffffffL; + sp_1024_mul_add_18(a+i, m, mu); + a[i+1] += a[i] >> 57; + a[i] &= 0x1ffffffffffffffL; + } +#else + for (i=0; i<17; i++) { + mu = (a[i] * mp) & 0x1ffffffffffffffL; + sp_1024_mul_add_18(a+i, m, mu); + a[i+1] += a[i] >> 57; + } + mu = (a[i] * mp) & 0x7fffffffffffffL; + sp_1024_mul_add_18(a+i, m, mu); + a[i+1] += a[i] >> 57; + a[i] &= 0x1ffffffffffffffL; +#endif + sp_1024_mont_shift_18(a, a); + sp_1024_cond_sub_18(a, a, m, 0 - (((a[17] - m[17]) > 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_18(a); +} + +/* Multiply two Montogmery form numbers mod the modulus (prime). + * (r = a * b mod m) + * + * r Result of multiplication. + * a First number to multiply in Montogmery form. + * b Second number to multiply in Montogmery form. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_1024_mont_mul_18(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) +{ + sp_1024_mul_18(r, a, b); + sp_1024_mont_reduce_18(r, m, mp); +} + +/* Square the Montgomery form number. (r = a * a mod m) + * + * r Result of squaring. + * a Number to square in Montogmery form. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_1024_mont_sqr_18(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) +{ + sp_1024_sqr_18(r, a); + sp_1024_mont_reduce_18(r, m, mp); +} + +/* Mod-2 for the P1024 curve. */ +static const uint8_t p1024_mod_minus_2[] = { + 6,0x06, 7,0x0f, 7,0x0b, 6,0x0c, 7,0x1e, 9,0x09, 7,0x0c, 7,0x1f, + 6,0x16, 6,0x06, 7,0x0e, 8,0x10, 6,0x03, 8,0x11, 6,0x0d, 7,0x14, + 9,0x12, 6,0x0f, 7,0x04, 9,0x0d, 6,0x00, 7,0x13, 6,0x01, 6,0x07, + 8,0x0d, 8,0x00, 6,0x06, 9,0x17, 6,0x14, 6,0x15, 6,0x11, 6,0x0b, + 9,0x0c, 6,0x1e, 13,0x14, 7,0x0e, 6,0x1d, 12,0x0a, 6,0x0b, 8,0x07, + 6,0x18, 6,0x0f, 6,0x10, 8,0x1c, 7,0x16, 7,0x02, 6,0x01, 6,0x13, + 10,0x15, 7,0x06, 8,0x14, 6,0x0c, 6,0x19, 7,0x10, 6,0x19, 6,0x19, + 9,0x16, 7,0x19, 6,0x1f, 6,0x17, 6,0x12, 8,0x02, 6,0x01, 6,0x04, + 6,0x15, 7,0x16, 6,0x04, 6,0x1f, 6,0x09, 7,0x06, 7,0x13, 7,0x09, + 6,0x0d, 10,0x18, 6,0x06, 6,0x11, 6,0x04, 6,0x01, 6,0x13, 8,0x06, + 6,0x0d, 8,0x13, 7,0x08, 6,0x08, 6,0x05, 7,0x0c, 7,0x0e, 7,0x15, + 6,0x05, 7,0x14, 10,0x19, 6,0x10, 6,0x16, 6,0x15, 7,0x1f, 6,0x14, + 6,0x0a, 10,0x11, 6,0x01, 7,0x05, 7,0x08, 8,0x0a, 7,0x1e, 7,0x1c, + 6,0x1c, 7,0x09, 10,0x18, 7,0x1c, 10,0x06, 6,0x0a, 6,0x07, 6,0x19, + 7,0x06, 6,0x0d, 7,0x0f, 7,0x0b, 7,0x05, 6,0x11, 6,0x1c, 7,0x1f, + 6,0x1e, 7,0x18, 6,0x1e, 6,0x00, 6,0x03, 6,0x02, 7,0x10, 6,0x0b, + 6,0x1b, 7,0x10, 6,0x00, 8,0x11, 7,0x1b, 6,0x18, 6,0x01, 7,0x0c, + 7,0x1d, 7,0x13, 6,0x08, 7,0x1b, 8,0x13, 7,0x16, 13,0x1d, 7,0x1f, + 6,0x0a, 6,0x01, 7,0x1f, 6,0x14, 1,0x01 +}; + +/* Invert the number, in Montgomery form, modulo the modulus (prime) of the + * P1024 curve. (r = 1 / a mod m) + * + * r Inverse result. + * a Number to invert. + * td Temporary data. + */ +static void sp_1024_mont_inv_18(sp_digit* r, const sp_digit* a, + sp_digit* td) +{ + sp_digit* t = td; + int i; + int j; + sp_digit table[32][2 * 18]; + + XMEMCPY(table[0], a, sizeof(sp_digit) * 18); + for (i = 1; i < 6; i++) { + sp_1024_mont_sqr_18(table[0], table[0], p1024_mod, p1024_mp_mod); + } + for (i = 1; i < 32; i++) { + sp_1024_mont_mul_18(table[i], table[i-1], a, p1024_mod, p1024_mp_mod); + } + + XMEMCPY(t, table[p1024_mod_minus_2[1]], sizeof(sp_digit) * 18); + for (i = 2; i < (int)sizeof(p1024_mod_minus_2) - 2; i += 2) { + for (j = 0; j < p1024_mod_minus_2[i]; j++) { + sp_1024_mont_sqr_18(t, t, p1024_mod, p1024_mp_mod); + } + sp_1024_mont_mul_18(t, t, table[p1024_mod_minus_2[i+1]], p1024_mod, + p1024_mp_mod); + } + sp_1024_mont_sqr_18(t, t, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(r, t, a, p1024_mod, p1024_mp_mod); +} + +/* Map the Montgomery form projective coordinate point to an affine point. + * + * r Resulting affine coordinate point. + * p Montgomery form projective coordinate point. + * t Temporary ordinate data. + */ +static void sp_1024_map_18(sp_point_1024* r, const sp_point_1024* p, + sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*18; + int64_t n; + + sp_1024_mont_inv_18(t1, p->z, t + 2*18); + + sp_1024_mont_sqr_18(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(t1, t2, t1, p1024_mod, p1024_mp_mod); + + /* x /= z^2 */ + sp_1024_mont_mul_18(r->x, p->x, t2, p1024_mod, p1024_mp_mod); + XMEMSET(r->x + 18, 0, sizeof(r->x) / 2U); + sp_1024_mont_reduce_18(r->x, p1024_mod, p1024_mp_mod); + /* Reduce x to less than modulus */ + n = sp_1024_cmp_18(r->x, p1024_mod); + sp_1024_cond_sub_18(r->x, r->x, p1024_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_18(r->x); + + /* y /= z^3 */ + sp_1024_mont_mul_18(r->y, p->y, t1, p1024_mod, p1024_mp_mod); + XMEMSET(r->y + 18, 0, sizeof(r->y) / 2U); + sp_1024_mont_reduce_18(r->y, p1024_mod, p1024_mp_mod); + /* Reduce y to less than modulus */ + n = sp_1024_cmp_18(r->y, p1024_mod); + sp_1024_cond_sub_18(r->y, r->y, p1024_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_18(r->y); + + XMEMSET(r->z, 0, sizeof(r->z)); + r->z[0] = 1; + +} + +/* Add two Montgomery form numbers (r = a + b % m). + * + * r Result of addition. + * a First number to add in Montogmery form. + * b Second number to add in Montogmery form. + * m Modulus (prime). + */ +static void sp_1024_mont_add_18(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + (void)sp_1024_add_18(r, a, b); + sp_1024_norm_18(r); + sp_1024_cond_sub_18(r, r, m, 0 - (((r[17] - m[17]) > 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_18(r); +} + +/* Double a Montgomery form number (r = a + a % m). + * + * r Result of doubling. + * a Number to double in Montogmery form. + * m Modulus (prime). + */ +static void sp_1024_mont_dbl_18(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + (void)sp_1024_add_18(r, a, a); + sp_1024_norm_18(r); + sp_1024_cond_sub_18(r, r, m, 0 - (((r[17] - m[17]) > 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_18(r); +} + +/* Triple a Montgomery form number (r = a + a + a % m). + * + * r Result of Tripling. + * a Number to triple in Montogmery form. + * m Modulus (prime). + */ +static void sp_1024_mont_tpl_18(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + (void)sp_1024_add_18(r, a, a); + sp_1024_norm_18(r); + sp_1024_cond_sub_18(r, r, m, 0 - (((r[17] - m[17]) > 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_18(r); + (void)sp_1024_add_18(r, r, a); + sp_1024_norm_18(r); + sp_1024_cond_sub_18(r, r, m, 0 - (((r[17] - m[17]) > 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_18(r); +} + +/* Subtract two Montgomery form numbers (r = a - b % m). + * + * r Result of subtration. + * a Number to subtract from in Montogmery form. + * b Number to subtract with in Montogmery form. + * m Modulus (prime). + */ +static void sp_1024_mont_sub_18(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + (void)sp_1024_sub_18(r, a, b); + sp_1024_cond_add_18(r, r, m, r[17] >> 55); + sp_1024_norm_18(r); +} + +/* Shift number left one bit. + * Bottom bit is lost. + * + * r Result of shift. + * a Number to shift. + */ +SP_NOINLINE static void sp_1024_rshift1_18(sp_digit* r, const sp_digit* a) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i=0; i<17; i++) { + r[i] = (a[i] >> 1) + ((a[i + 1] << 56) & 0x1ffffffffffffffL); + } +#else + r[0] = (a[0] >> 1) + ((a[1] << 56) & 0x1ffffffffffffffL); + r[1] = (a[1] >> 1) + ((a[2] << 56) & 0x1ffffffffffffffL); + r[2] = (a[2] >> 1) + ((a[3] << 56) & 0x1ffffffffffffffL); + r[3] = (a[3] >> 1) + ((a[4] << 56) & 0x1ffffffffffffffL); + r[4] = (a[4] >> 1) + ((a[5] << 56) & 0x1ffffffffffffffL); + r[5] = (a[5] >> 1) + ((a[6] << 56) & 0x1ffffffffffffffL); + r[6] = (a[6] >> 1) + ((a[7] << 56) & 0x1ffffffffffffffL); + r[7] = (a[7] >> 1) + ((a[8] << 56) & 0x1ffffffffffffffL); + r[8] = (a[8] >> 1) + ((a[9] << 56) & 0x1ffffffffffffffL); + r[9] = (a[9] >> 1) + ((a[10] << 56) & 0x1ffffffffffffffL); + r[10] = (a[10] >> 1) + ((a[11] << 56) & 0x1ffffffffffffffL); + r[11] = (a[11] >> 1) + ((a[12] << 56) & 0x1ffffffffffffffL); + r[12] = (a[12] >> 1) + ((a[13] << 56) & 0x1ffffffffffffffL); + r[13] = (a[13] >> 1) + ((a[14] << 56) & 0x1ffffffffffffffL); + r[14] = (a[14] >> 1) + ((a[15] << 56) & 0x1ffffffffffffffL); + r[15] = (a[15] >> 1) + ((a[16] << 56) & 0x1ffffffffffffffL); + r[16] = (a[16] >> 1) + ((a[17] << 56) & 0x1ffffffffffffffL); +#endif + r[17] = a[17] >> 1; +} + +/* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m) + * + * r Result of division by 2. + * a Number to divide. + * m Modulus (prime). + */ +static void sp_1024_div2_18(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_1024_cond_add_18(r, a, m, 0 - (a[0] & 1)); + sp_1024_norm_18(r); + sp_1024_rshift1_18(r, r); +} + +/* Double the Montgomery form projective point p. + * + * r Result of doubling point. + * p Point to double. + * t Temporary ordinate data. + */ +#ifdef WOLFSSL_SP_NONBLOCK +typedef struct sp_1024_proj_point_dbl_18_ctx { + int state; + sp_digit* t1; + sp_digit* t2; + sp_digit* x; + sp_digit* y; + sp_digit* z; +} sp_1024_proj_point_dbl_18_ctx; + +static int sp_1024_proj_point_dbl_18_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r, const sp_point_1024* p, sp_digit* t) +{ + int err = FP_WOULDBLOCK; + sp_1024_proj_point_dbl_18_ctx* ctx = (sp_1024_proj_point_dbl_18_ctx*)sp_ctx->data; + + typedef char ctx_size_test[sizeof(sp_1024_proj_point_dbl_18_ctx) >= sizeof(*sp_ctx) ? -1 : 1]; + (void)sizeof(ctx_size_test); + + switch (ctx->state) { + case 0: + ctx->t1 = t; + ctx->t2 = t + 2*18; + ctx->x = r->x; + ctx->y = r->y; + ctx->z = r->z; + + /* Put infinity into result. */ + if (r != p) { + r->infinity = p->infinity; + } + ctx->state = 1; + break; + case 1: + /* T1 = Z * Z */ + sp_1024_mont_sqr_18(ctx->t1, p->z, p1024_mod, p1024_mp_mod); + ctx->state = 2; + break; + case 2: + /* Z = Y * Z */ + sp_1024_mont_mul_18(ctx->z, p->y, p->z, p1024_mod, p1024_mp_mod); + ctx->state = 3; + break; + case 3: + /* Z = 2Z */ + sp_1024_mont_dbl_18(ctx->z, ctx->z, p1024_mod); + ctx->state = 4; + break; + case 4: + /* T2 = X - T1 */ + sp_1024_mont_sub_18(ctx->t2, p->x, ctx->t1, p1024_mod); + ctx->state = 5; + break; + case 5: + /* T1 = X + T1 */ + sp_1024_mont_add_18(ctx->t1, p->x, ctx->t1, p1024_mod); + ctx->state = 6; + break; + case 6: + /* T2 = T1 * T2 */ + sp_1024_mont_mul_18(ctx->t2, ctx->t1, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 7; + break; + case 7: + /* T1 = 3T2 */ + sp_1024_mont_tpl_18(ctx->t1, ctx->t2, p1024_mod); + ctx->state = 8; + break; + case 8: + /* Y = 2Y */ + sp_1024_mont_dbl_18(ctx->y, p->y, p1024_mod); + ctx->state = 9; + break; + case 9: + /* Y = Y * Y */ + sp_1024_mont_sqr_18(ctx->y, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 10; + break; + case 10: + /* T2 = Y * Y */ + sp_1024_mont_sqr_18(ctx->t2, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 11; + break; + case 11: + /* T2 = T2/2 */ + sp_1024_div2_18(ctx->t2, ctx->t2, p1024_mod); + ctx->state = 12; + break; + case 12: + /* Y = Y * X */ + sp_1024_mont_mul_18(ctx->y, ctx->y, p->x, p1024_mod, p1024_mp_mod); + ctx->state = 13; + break; + case 13: + /* X = T1 * T1 */ + sp_1024_mont_sqr_18(ctx->x, ctx->t1, p1024_mod, p1024_mp_mod); + ctx->state = 14; + break; + case 14: + /* X = X - Y */ + sp_1024_mont_sub_18(ctx->x, ctx->x, ctx->y, p1024_mod); + ctx->state = 15; + break; + case 15: + /* X = X - Y */ + sp_1024_mont_sub_18(ctx->x, ctx->x, ctx->y, p1024_mod); + ctx->state = 16; + break; + case 16: + /* Y = Y - X */ + sp_1024_mont_sub_18(ctx->y, ctx->y, ctx->x, p1024_mod); + ctx->state = 17; + break; + case 17: + /* Y = Y * T1 */ + sp_1024_mont_mul_18(ctx->y, ctx->y, ctx->t1, p1024_mod, p1024_mp_mod); + ctx->state = 18; + break; + case 18: + /* Y = Y - T2 */ + sp_1024_mont_sub_18(ctx->y, ctx->y, ctx->t2, p1024_mod); + ctx->state = 19; + /* fall-through */ + case 19: + err = MP_OKAY; + break; + } + + if (err == MP_OKAY && ctx->state != 19) { + err = FP_WOULDBLOCK; + } + + return err; +} +#endif /* WOLFSSL_SP_NONBLOCK */ + +static void sp_1024_proj_point_dbl_18(sp_point_1024* r, const sp_point_1024* p, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*18; + sp_digit* x; + sp_digit* y; + sp_digit* z; + + x = r->x; + y = r->y; + z = r->z; + /* Put infinity into result. */ + if (r != p) { + r->infinity = p->infinity; + } + + /* T1 = Z * Z */ + sp_1024_mont_sqr_18(t1, p->z, p1024_mod, p1024_mp_mod); + /* Z = Y * Z */ + sp_1024_mont_mul_18(z, p->y, p->z, p1024_mod, p1024_mp_mod); + /* Z = 2Z */ + sp_1024_mont_dbl_18(z, z, p1024_mod); + /* T2 = X - T1 */ + sp_1024_mont_sub_18(t2, p->x, t1, p1024_mod); + /* T1 = X + T1 */ + sp_1024_mont_add_18(t1, p->x, t1, p1024_mod); + /* T2 = T1 * T2 */ + sp_1024_mont_mul_18(t2, t1, t2, p1024_mod, p1024_mp_mod); + /* T1 = 3T2 */ + sp_1024_mont_tpl_18(t1, t2, p1024_mod); + /* Y = 2Y */ + sp_1024_mont_dbl_18(y, p->y, p1024_mod); + /* Y = Y * Y */ + sp_1024_mont_sqr_18(y, y, p1024_mod, p1024_mp_mod); + /* T2 = Y * Y */ + sp_1024_mont_sqr_18(t2, y, p1024_mod, p1024_mp_mod); + /* T2 = T2/2 */ + sp_1024_div2_18(t2, t2, p1024_mod); + /* Y = Y * X */ + sp_1024_mont_mul_18(y, y, p->x, p1024_mod, p1024_mp_mod); + /* X = T1 * T1 */ + sp_1024_mont_sqr_18(x, t1, p1024_mod, p1024_mp_mod); + /* X = X - Y */ + sp_1024_mont_sub_18(x, x, y, p1024_mod); + /* X = X - Y */ + sp_1024_mont_sub_18(x, x, y, p1024_mod); + /* Y = Y - X */ + sp_1024_mont_sub_18(y, y, x, p1024_mod); + /* Y = Y * T1 */ + sp_1024_mont_mul_18(y, y, t1, p1024_mod, p1024_mp_mod); + /* Y = Y - T2 */ + sp_1024_mont_sub_18(y, y, t2, p1024_mod); +} + +/* Compare two numbers to determine if they are equal. + * Constant time implementation. + * + * a First number to compare. + * b Second number to compare. + * returns 1 when equal and 0 otherwise. + */ +static int sp_1024_cmp_equal_18(const sp_digit* a, const sp_digit* b) +{ + return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) | (a[3] ^ b[3]) | + (a[4] ^ b[4]) | (a[5] ^ b[5]) | (a[6] ^ b[6]) | (a[7] ^ b[7]) | + (a[8] ^ b[8]) | (a[9] ^ b[9]) | (a[10] ^ b[10]) | (a[11] ^ b[11]) | + (a[12] ^ b[12]) | (a[13] ^ b[13]) | (a[14] ^ b[14]) | (a[15] ^ b[15]) | + (a[16] ^ b[16]) | (a[17] ^ b[17])) == 0; +} + +/* Add two Montgomery form projective points. + * + * r Result of addition. + * p First point to add. + * q Second point to add. + * t Temporary ordinate data. + */ + +#ifdef WOLFSSL_SP_NONBLOCK +typedef struct sp_1024_proj_point_add_18_ctx { + int state; + sp_1024_proj_point_dbl_18_ctx dbl_ctx; + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1; + sp_digit* t2; + sp_digit* t3; + sp_digit* t4; + sp_digit* t5; + sp_digit* x; + sp_digit* y; + sp_digit* z; +} sp_1024_proj_point_add_18_ctx; + +static int sp_1024_proj_point_add_18_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r, + const sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + int err = FP_WOULDBLOCK; + sp_1024_proj_point_add_18_ctx* ctx = (sp_1024_proj_point_add_18_ctx*)sp_ctx->data; + + /* Ensure only the first point is the same as the result. */ + if (q == r) { + const sp_point_1024* a = p; + p = q; + q = a; + } + + typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_18_ctx) >= sizeof(*sp_ctx) ? -1 : 1]; + (void)sizeof(ctx_size_test); + + switch (ctx->state) { + case 0: /* INIT */ + ctx->t1 = t; + ctx->t2 = t + 2*18; + ctx->t3 = t + 4*18; + ctx->t4 = t + 6*18; + ctx->t5 = t + 8*18; + + ctx->state = 1; + break; + case 1: + /* Check double */ + (void)sp_1024_sub_18(ctx->t1, p1024_mod, q->y); + sp_1024_norm_18(ctx->t1); + if ((sp_1024_cmp_equal_18(p->x, q->x) & sp_1024_cmp_equal_18(p->z, q->z) & + (sp_1024_cmp_equal_18(p->y, q->y) | sp_1024_cmp_equal_18(p->y, ctx->t1))) != 0) + { + XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx)); + ctx->state = 2; + } + else { + ctx->state = 3; + } + break; + case 2: + err = sp_1024_proj_point_dbl_18_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, r, p, t); + if (err == MP_OKAY) + ctx->state = 27; /* done */ + break; + case 3: + { + int i; + ctx->rp[0] = r; + + /*lint allow cast to different type of pointer*/ + ctx->rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(ctx->rp[1], 0, sizeof(sp_point_1024)); + ctx->x = ctx->rp[p->infinity | q->infinity]->x; + ctx->y = ctx->rp[p->infinity | q->infinity]->y; + ctx->z = ctx->rp[p->infinity | q->infinity]->z; + + ctx->ap[0] = p; + ctx->ap[1] = q; + for (i=0; i<18; i++) { + r->x[i] = ctx->ap[p->infinity]->x[i]; + } + for (i=0; i<18; i++) { + r->y[i] = ctx->ap[p->infinity]->y[i]; + } + for (i=0; i<18; i++) { + r->z[i] = ctx->ap[p->infinity]->z[i]; + } + r->infinity = ctx->ap[p->infinity]->infinity; + + ctx->state = 4; + break; + } + case 4: + /* U1 = X1*Z2^2 */ + sp_1024_mont_sqr_18(ctx->t1, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 5; + break; + case 5: + sp_1024_mont_mul_18(ctx->t3, ctx->t1, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 6; + break; + case 6: + sp_1024_mont_mul_18(ctx->t1, ctx->t1, ctx->x, p1024_mod, p1024_mp_mod); + ctx->state = 7; + break; + case 7: + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_18(ctx->t2, ctx->z, p1024_mod, p1024_mp_mod); + ctx->state = 8; + break; + case 8: + sp_1024_mont_mul_18(ctx->t4, ctx->t2, ctx->z, p1024_mod, p1024_mp_mod); + ctx->state = 9; + break; + case 9: + sp_1024_mont_mul_18(ctx->t2, ctx->t2, q->x, p1024_mod, p1024_mp_mod); + ctx->state = 10; + break; + case 10: + /* S1 = Y1*Z2^3 */ + sp_1024_mont_mul_18(ctx->t3, ctx->t3, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 11; + break; + case 11: + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_18(ctx->t4, ctx->t4, q->y, p1024_mod, p1024_mp_mod); + ctx->state = 12; + break; + case 12: + /* H = U2 - U1 */ + sp_1024_mont_sub_18(ctx->t2, ctx->t2, ctx->t1, p1024_mod); + ctx->state = 13; + break; + case 13: + /* R = S2 - S1 */ + sp_1024_mont_sub_18(ctx->t4, ctx->t4, ctx->t3, p1024_mod); + ctx->state = 14; + break; + case 14: + /* Z3 = H*Z1*Z2 */ + sp_1024_mont_mul_18(ctx->z, ctx->z, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 15; + break; + case 15: + sp_1024_mont_mul_18(ctx->z, ctx->z, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 16; + break; + case 16: + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_1024_mont_sqr_18(ctx->x, ctx->t4, p1024_mod, p1024_mp_mod); + ctx->state = 17; + break; + case 17: + sp_1024_mont_sqr_18(ctx->t5, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 18; + break; + case 18: + sp_1024_mont_mul_18(ctx->y, ctx->t1, ctx->t5, p1024_mod, p1024_mp_mod); + ctx->state = 19; + break; + case 19: + sp_1024_mont_mul_18(ctx->t5, ctx->t5, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 20; + break; + case 20: + sp_1024_mont_sub_18(ctx->x, ctx->x, ctx->t5, p1024_mod); + ctx->state = 21; + break; + case 21: + sp_1024_mont_dbl_18(ctx->t1, ctx->y, p1024_mod); + ctx->state = 22; + break; + case 22: + sp_1024_mont_sub_18(ctx->x, ctx->x, ctx->t1, p1024_mod); + ctx->state = 23; + break; + case 23: + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_1024_mont_sub_18(ctx->y, ctx->y, ctx->x, p1024_mod); + ctx->state = 24; + break; + case 24: + sp_1024_mont_mul_18(ctx->y, ctx->y, ctx->t4, p1024_mod, p1024_mp_mod); + ctx->state = 25; + break; + case 25: + sp_1024_mont_mul_18(ctx->t5, ctx->t5, ctx->t3, p1024_mod, p1024_mp_mod); + ctx->state = 26; + break; + case 26: + sp_1024_mont_sub_18(ctx->y, ctx->y, ctx->t5, p1024_mod); + ctx->state = 27; + /* fall-through */ + case 27: + err = MP_OKAY; + break; + } + + if (err == MP_OKAY && ctx->state != 27) { + err = FP_WOULDBLOCK; + } + return err; +} +#endif /* WOLFSSL_SP_NONBLOCK */ + +static void sp_1024_proj_point_add_18(sp_point_1024* r, + const sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*18; + sp_digit* t3 = t + 4*18; + sp_digit* t4 = t + 6*18; + sp_digit* t5 = t + 8*18; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Ensure only the first point is the same as the result. */ + if (q == r) { + const sp_point_1024* a = p; + p = q; + q = a; + } + + /* Check double */ + (void)sp_1024_mont_sub_18(t1, p1024_mod, q->y, p1024_mod); + sp_1024_norm_18(t1); + if ((sp_1024_cmp_equal_18(p->x, q->x) & sp_1024_cmp_equal_18(p->z, q->z) & + (sp_1024_cmp_equal_18(p->y, q->y) | sp_1024_cmp_equal_18(p->y, t1))) != 0) { + sp_1024_proj_point_dbl_18(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_1024)); + x = rp[p->infinity | q->infinity]->x; + y = rp[p->infinity | q->infinity]->y; + z = rp[p->infinity | q->infinity]->z; + + ap[0] = p; + ap[1] = q; + for (i=0; i<18; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<18; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<18; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U1 = X1*Z2^2 */ + sp_1024_mont_sqr_18(t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(t3, t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(t1, t1, x, p1024_mod, p1024_mp_mod); + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_18(t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(t4, t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(t2, t2, q->x, p1024_mod, p1024_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_1024_mont_mul_18(t3, t3, y, p1024_mod, p1024_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_18(t4, t4, q->y, p1024_mod, p1024_mp_mod); + /* H = U2 - U1 */ + sp_1024_mont_sub_18(t2, t2, t1, p1024_mod); + /* R = S2 - S1 */ + sp_1024_mont_sub_18(t4, t4, t3, p1024_mod); + /* Z3 = H*Z1*Z2 */ + sp_1024_mont_mul_18(z, z, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(z, z, t2, p1024_mod, p1024_mp_mod); + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_1024_mont_sqr_18(x, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_18(t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(y, t1, t5, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(t5, t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_18(x, x, t5, p1024_mod); + sp_1024_mont_dbl_18(t1, y, p1024_mod); + sp_1024_mont_sub_18(x, x, t1, p1024_mod); + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_1024_mont_sub_18(y, y, x, p1024_mod); + sp_1024_mont_mul_18(y, y, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(t5, t5, t3, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_18(y, y, t5, p1024_mod); + } +} + +#ifdef WOLFSSL_SP_SMALL +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Small implementation using add and double that is cache attack resistant but + * allocates memory rather than use large stacks. + * 1024 adds and doubles. + * + * r Resulting point. + * g Point to multiply. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ + +#ifdef WOLFSSL_SP_NONBLOCK +typedef struct sp_1024_ecc_mulmod_18_ctx { + int state; + union { + sp_1024_proj_point_dbl_18_ctx dbl_ctx; + sp_1024_proj_point_add_18_ctx add_ctx; + }; + sp_point_1024 t[3]; + sp_digit tmp[2 * 18 * 5]; + sp_digit n; + int i; + int c; + int y; +} sp_1024_ecc_mulmod_18_ctx; + +static int sp_1024_ecc_mulmod_18_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r, + const sp_point_1024* g, const sp_digit* k, int map, int ct, void* heap) +{ + int err = FP_WOULDBLOCK; + sp_1024_ecc_mulmod_18_ctx* ctx = (sp_1024_ecc_mulmod_18_ctx*)sp_ctx->data; + + typedef char ctx_size_test[sizeof(sp_1024_ecc_mulmod_18_ctx) >= sizeof(*sp_ctx) ? -1 : 1]; + (void)sizeof(ctx_size_test); + + /* Implementation is constant time. */ + (void)ct; + + switch (ctx->state) { + case 0: /* INIT */ + XMEMSET(ctx->t, 0, sizeof(sp_point_1024) * 3); + ctx->i = 17; + ctx->c = 55; + ctx->n = k[ctx->i--] << (57 - ctx->c); + + /* t[0] = {0, 0, 1} * norm */ + ctx->t[0].infinity = 1; + ctx->state = 1; + break; + case 1: /* T1X */ + /* t[1] = {g->x, g->y, g->z} * norm */ + err = sp_1024_mod_mul_norm_18(ctx->t[1].x, g->x, p1024_mod); + ctx->state = 2; + break; + case 2: /* T1Y */ + err = sp_1024_mod_mul_norm_18(ctx->t[1].y, g->y, p1024_mod); + ctx->state = 3; + break; + case 3: /* T1Z */ + err = sp_1024_mod_mul_norm_18(ctx->t[1].z, g->z, p1024_mod); + ctx->state = 4; + break; + case 4: /* ADDPREP */ + if (ctx->c == 0) { + if (ctx->i == -1) { + ctx->state = 7; + break; + } + + ctx->n = k[ctx->i--]; + ctx->c = 57; + } + ctx->y = (ctx->n >> 56) & 1; + ctx->n <<= 1; + XMEMSET(&ctx->add_ctx, 0, sizeof(ctx->add_ctx)); + ctx->state = 5; + break; + case 5: /* ADD */ + err = sp_1024_proj_point_add_18_nb((sp_ecc_ctx_t*)&ctx->add_ctx, + &ctx->t[ctx->y^1], &ctx->t[0], &ctx->t[1], ctx->tmp); + if (err == MP_OKAY) { + XMEMCPY(&ctx->t[2], (void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) + + ((size_t)&ctx->t[1] & addr_mask[ctx->y])), + sizeof(sp_point_1024)); + XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx)); + ctx->state = 6; + } + break; + case 6: /* DBL */ + err = sp_1024_proj_point_dbl_18_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, &ctx->t[2], + &ctx->t[2], ctx->tmp); + if (err == MP_OKAY) { + XMEMCPY((void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) + + ((size_t)&ctx->t[1] & addr_mask[ctx->y])), &ctx->t[2], + sizeof(sp_point_1024)); + ctx->state = 4; + ctx->c--; + } + break; + case 7: /* MAP */ + if (map != 0) { + sp_1024_map_18(r, &ctx->t[0], ctx->tmp); + } + else { + XMEMCPY(r, &ctx->t[0], sizeof(sp_point_1024)); + } + err = MP_OKAY; + break; + } + + if (err == MP_OKAY && ctx->state != 7) { + err = FP_WOULDBLOCK; + } + if (err != FP_WOULDBLOCK) { + ForceZero(ctx->tmp, sizeof(ctx->tmp)); + ForceZero(ctx->t, sizeof(ctx->t)); + } + + (void)heap; + + return err; +} + +#endif /* WOLFSSL_SP_NONBLOCK */ + +static int sp_1024_ecc_mulmod_18(sp_point_1024* r, const sp_point_1024* g, + const sp_digit* k, int map, int ct, void* heap) +{ +#ifdef WOLFSSL_SP_NO_MALLOC + sp_point_1024 t[3]; + sp_digit tmp[2 * 18 * 5]; +#else + sp_point_1024* t; + sp_digit* tmp; +#endif + sp_digit n; + int i; + int c; + int y; + int err = MP_OKAY; + + /* Implementatio is constant time. */ + (void)ct; + (void)heap; + +#ifndef WOLFSSL_SP_NO_MALLOC + t = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) * 3, heap, DYNAMIC_TYPE_ECC); + if (t == NULL) + err = MEMORY_E; + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 18 * 5, heap, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) + err = MEMORY_E; +#endif + + if (err == MP_OKAY) { + XMEMSET(t, 0, sizeof(sp_point_1024) * 3); + + /* t[0] = {0, 0, 1} * norm */ + t[0].infinity = 1; + /* t[1] = {g->x, g->y, g->z} * norm */ + err = sp_1024_mod_mul_norm_18(t[1].x, g->x, p1024_mod); + } + if (err == MP_OKAY) + err = sp_1024_mod_mul_norm_18(t[1].y, g->y, p1024_mod); + if (err == MP_OKAY) + err = sp_1024_mod_mul_norm_18(t[1].z, g->z, p1024_mod); + + if (err == MP_OKAY) { + i = 17; + c = 55; + n = k[i--] << (57 - c); + for (; ; c--) { + if (c == 0) { + if (i == -1) + break; + + n = k[i--]; + c = 57; + } + + y = (n >> 56) & 1; + n <<= 1; + + sp_1024_proj_point_add_18(&t[y^1], &t[0], &t[1], tmp); + + XMEMCPY(&t[2], (void*)(((size_t)&t[0] & addr_mask[y^1]) + + ((size_t)&t[1] & addr_mask[y])), + sizeof(sp_point_1024)); + sp_1024_proj_point_dbl_18(&t[2], &t[2], tmp); + XMEMCPY((void*)(((size_t)&t[0] & addr_mask[y^1]) + + ((size_t)&t[1] & addr_mask[y])), &t[2], + sizeof(sp_point_1024)); + } + + if (map != 0) { + sp_1024_map_18(r, &t[0], tmp); + } + else { + XMEMCPY(r, &t[0], sizeof(sp_point_1024)); + } + } + +#ifndef WOLFSSL_SP_NO_MALLOC + if (tmp != NULL) { + XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 18 * 5); + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } + if (t != NULL) { + XMEMSET(t, 0, sizeof(sp_point_1024) * 3); + XFREE(t, NULL, DYNAMIC_TYPE_ECC); + } +#else + ForceZero(tmp, sizeof(tmp)); + ForceZero(t, sizeof(t)); +#endif + + return err; +} + +#else +/* A table entry for pre-computed points. */ +typedef struct sp_table_entry_1024 { + sp_digit x[18]; + sp_digit y[18]; +} sp_table_entry_1024; + +/* Conditionally copy a into r using the mask m. + * m is -1 to copy and 0 when not. + * + * r A single precision number to copy over. + * a A single precision number to copy. + * m Mask value to apply. + */ +static void sp_1024_cond_copy_18(sp_digit* r, const sp_digit* a, const sp_digit m) +{ + sp_digit t[18]; +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i = 0; i < 18; i++) { + t[i] = r[i] ^ a[i]; + } + for (i = 0; i < 18; i++) { + r[i] ^= t[i] & m; + } +#else + t[ 0] = r[ 0] ^ a[ 0]; + t[ 1] = r[ 1] ^ a[ 1]; + t[ 2] = r[ 2] ^ a[ 2]; + t[ 3] = r[ 3] ^ a[ 3]; + t[ 4] = r[ 4] ^ a[ 4]; + t[ 5] = r[ 5] ^ a[ 5]; + t[ 6] = r[ 6] ^ a[ 6]; + t[ 7] = r[ 7] ^ a[ 7]; + t[ 8] = r[ 8] ^ a[ 8]; + t[ 9] = r[ 9] ^ a[ 9]; + t[10] = r[10] ^ a[10]; + t[11] = r[11] ^ a[11]; + t[12] = r[12] ^ a[12]; + t[13] = r[13] ^ a[13]; + t[14] = r[14] ^ a[14]; + t[15] = r[15] ^ a[15]; + t[16] = r[16] ^ a[16]; + t[17] = r[17] ^ a[17]; + r[ 0] ^= t[ 0] & m; + r[ 1] ^= t[ 1] & m; + r[ 2] ^= t[ 2] & m; + r[ 3] ^= t[ 3] & m; + r[ 4] ^= t[ 4] & m; + r[ 5] ^= t[ 5] & m; + r[ 6] ^= t[ 6] & m; + r[ 7] ^= t[ 7] & m; + r[ 8] ^= t[ 8] & m; + r[ 9] ^= t[ 9] & m; + r[10] ^= t[10] & m; + r[11] ^= t[11] & m; + r[12] ^= t[12] & m; + r[13] ^= t[13] & m; + r[14] ^= t[14] & m; + r[15] ^= t[15] & m; + r[16] ^= t[16] & m; + r[17] ^= t[17] & m; +#endif /* WOLFSSL_SP_SMALL */ +} + +/* Double the Montgomery form projective point p a number of times. + * + * r Result of repeated doubling of point. + * p Point to double. + * n Number of times to double + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_dbl_n_18(sp_point_1024* p, int n, + sp_digit* t) +{ + sp_digit* w = t; + sp_digit* a = t + 2*18; + sp_digit* b = t + 4*18; + sp_digit* t1 = t + 6*18; + sp_digit* t2 = t + 8*18; + sp_digit* x; + sp_digit* y; + sp_digit* z; + + x = p->x; + y = p->y; + z = p->z; + + /* Y = 2*Y */ + sp_1024_mont_dbl_18(y, y, p1024_mod); + /* W = Z^4 */ + sp_1024_mont_sqr_18(w, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_18(w, w, p1024_mod, p1024_mp_mod); + +#ifndef WOLFSSL_SP_SMALL + while (--n > 0) +#else + while (--n >= 0) +#endif + { + /* A = 3*(X^2 - W) */ + sp_1024_mont_sqr_18(t1, x, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_18(t1, t1, w, p1024_mod); + sp_1024_mont_tpl_18(a, t1, p1024_mod); + /* B = X*Y^2 */ + sp_1024_mont_sqr_18(t1, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(b, t1, x, p1024_mod, p1024_mp_mod); + /* X = A^2 - 2B */ + sp_1024_mont_sqr_18(x, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_18(t2, b, p1024_mod); + sp_1024_mont_sub_18(x, x, t2, p1024_mod); + /* Z = Z*Y */ + sp_1024_mont_mul_18(z, z, y, p1024_mod, p1024_mp_mod); + /* t2 = Y^4 */ + sp_1024_mont_sqr_18(t1, t1, p1024_mod, p1024_mp_mod); +#ifdef WOLFSSL_SP_SMALL + if (n != 0) +#endif + { + /* W = W*Y^4 */ + sp_1024_mont_mul_18(w, w, t1, p1024_mod, p1024_mp_mod); + } + /* y = 2*A*(B - X) - Y^4 */ + sp_1024_mont_sub_18(y, b, x, p1024_mod); + sp_1024_mont_mul_18(y, y, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_18(y, y, p1024_mod); + sp_1024_mont_sub_18(y, y, t1, p1024_mod); + } +#ifndef WOLFSSL_SP_SMALL + /* A = 3*(X^2 - W) */ + sp_1024_mont_sqr_18(t1, x, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_18(t1, t1, w, p1024_mod); + sp_1024_mont_tpl_18(a, t1, p1024_mod); + /* B = X*Y^2 */ + sp_1024_mont_sqr_18(t1, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(b, t1, x, p1024_mod, p1024_mp_mod); + /* X = A^2 - 2B */ + sp_1024_mont_sqr_18(x, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_18(t2, b, p1024_mod); + sp_1024_mont_sub_18(x, x, t2, p1024_mod); + /* Z = Z*Y */ + sp_1024_mont_mul_18(z, z, y, p1024_mod, p1024_mp_mod); + /* t2 = Y^4 */ + sp_1024_mont_sqr_18(t1, t1, p1024_mod, p1024_mp_mod); + /* y = 2*A*(B - X) - Y^4 */ + sp_1024_mont_sub_18(y, b, x, p1024_mod); + sp_1024_mont_mul_18(y, y, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_18(y, y, p1024_mod); + sp_1024_mont_sub_18(y, y, t1, p1024_mod); +#endif + /* Y = Y/2 */ + sp_1024_div2_18(y, y, p1024_mod); +} + +/* Double the Montgomery form projective point p a number of times. + * + * r Result of repeated doubling of point. + * p Point to double. + * n Number of times to double + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_dbl_n_store_18(sp_point_1024* r, + const sp_point_1024* p, int n, int m, sp_digit* t) +{ + sp_digit* w = t; + sp_digit* a = t + 2*18; + sp_digit* b = t + 4*18; + sp_digit* t1 = t + 6*18; + sp_digit* t2 = t + 8*18; + sp_digit* x = r[2*m].x; + sp_digit* y = r[(1<x[i]; + } + for (i=0; i<18; i++) { + y[i] = p->y[i]; + } + for (i=0; i<18; i++) { + z[i] = p->z[i]; + } + + /* Y = 2*Y */ + sp_1024_mont_dbl_18(y, y, p1024_mod); + /* W = Z^4 */ + sp_1024_mont_sqr_18(w, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_18(w, w, p1024_mod, p1024_mp_mod); + j = m; + for (i=1; i<=n; i++) { + j *= 2; + + /* A = 3*(X^2 - W) */ + sp_1024_mont_sqr_18(t1, x, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_18(t1, t1, w, p1024_mod); + sp_1024_mont_tpl_18(a, t1, p1024_mod); + /* B = X*Y^2 */ + sp_1024_mont_sqr_18(t2, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(b, t2, x, p1024_mod, p1024_mp_mod); + x = r[j].x; + /* X = A^2 - 2B */ + sp_1024_mont_sqr_18(x, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_18(t1, b, p1024_mod); + sp_1024_mont_sub_18(x, x, t1, p1024_mod); + /* Z = Z*Y */ + sp_1024_mont_mul_18(r[j].z, z, y, p1024_mod, p1024_mp_mod); + z = r[j].z; + /* t2 = Y^4 */ + sp_1024_mont_sqr_18(t2, t2, p1024_mod, p1024_mp_mod); + if (i != n) { + /* W = W*Y^4 */ + sp_1024_mont_mul_18(w, w, t2, p1024_mod, p1024_mp_mod); + } + /* y = 2*A*(B - X) - Y^4 */ + sp_1024_mont_sub_18(y, b, x, p1024_mod); + sp_1024_mont_mul_18(y, y, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_18(y, y, p1024_mod); + sp_1024_mont_sub_18(y, y, t2, p1024_mod); + + /* Y = Y/2 */ + sp_1024_div2_18(r[j].y, y, p1024_mod); + r[j].infinity = 0; + } +} + +/* Add two Montgomery form projective points. + * + * ra Result of addition. + * rs Result of subtraction. + * p First point to add. + * q Second point to add. + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_add_sub_18(sp_point_1024* ra, + sp_point_1024* rs, const sp_point_1024* p, const sp_point_1024* q, + sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*18; + sp_digit* t3 = t + 4*18; + sp_digit* t4 = t + 6*18; + sp_digit* t5 = t + 8*18; + sp_digit* t6 = t + 10*18; + sp_digit* x = ra->x; + sp_digit* y = ra->y; + sp_digit* z = ra->z; + sp_digit* xs = rs->x; + sp_digit* ys = rs->y; + sp_digit* zs = rs->z; + + + XMEMCPY(x, p->x, sizeof(p->x) / 2); + XMEMCPY(y, p->y, sizeof(p->y) / 2); + XMEMCPY(z, p->z, sizeof(p->z) / 2); + ra->infinity = 0; + rs->infinity = 0; + + /* U1 = X1*Z2^2 */ + sp_1024_mont_sqr_18(t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(t3, t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(t1, t1, x, p1024_mod, p1024_mp_mod); + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_18(t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(t4, t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(t2, t2, q->x, p1024_mod, p1024_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_1024_mont_mul_18(t3, t3, y, p1024_mod, p1024_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_18(t4, t4, q->y, p1024_mod, p1024_mp_mod); + /* H = U2 - U1 */ + sp_1024_mont_sub_18(t2, t2, t1, p1024_mod); + /* RS = S2 + S1 */ + sp_1024_mont_add_18(t6, t4, t3, p1024_mod); + /* R = S2 - S1 */ + sp_1024_mont_sub_18(t4, t4, t3, p1024_mod); + /* Z3 = H*Z1*Z2 */ + /* ZS = H*Z1*Z2 */ + sp_1024_mont_mul_18(z, z, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(z, z, t2, p1024_mod, p1024_mp_mod); + XMEMCPY(zs, z, sizeof(p->z)/2); + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + /* XS = RS^2 - H^3 - 2*U1*H^2 */ + sp_1024_mont_sqr_18(x, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_18(xs, t6, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_18(t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(y, t1, t5, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(t5, t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_18(x, x, t5, p1024_mod); + sp_1024_mont_sub_18(xs, xs, t5, p1024_mod); + sp_1024_mont_dbl_18(t1, y, p1024_mod); + sp_1024_mont_sub_18(x, x, t1, p1024_mod); + sp_1024_mont_sub_18(xs, xs, t1, p1024_mod); + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + /* YS = -RS*(U1*H^2 - XS) - S1*H^3 */ + sp_1024_mont_sub_18(ys, y, xs, p1024_mod); + sp_1024_mont_sub_18(y, y, x, p1024_mod); + sp_1024_mont_mul_18(y, y, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_18(t6, p1024_mod, t6, p1024_mod); + sp_1024_mont_mul_18(ys, ys, t6, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(t5, t5, t3, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_18(y, y, t5, p1024_mod); + sp_1024_mont_sub_18(ys, ys, t5, p1024_mod); +} + +/* Structure used to describe recoding of scalar multiplication. */ +typedef struct ecc_recode_1024 { + /* Index into pre-computation table. */ + uint8_t i; + /* Use the negative of the point. */ + uint8_t neg; +} ecc_recode_1024; + +/* The index into pre-computation table to use. */ +static const uint8_t recode_index_18_7[130] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, + 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, + 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, + 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, + 0, 1, +}; + +/* Whether to negate y-ordinate. */ +static const uint8_t recode_neg_18_7[130] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, +}; + +/* Recode the scalar for multiplication using pre-computed values and + * subtraction. + * + * k Scalar to multiply by. + * v Vector of operations to perform. + */ +static void sp_1024_ecc_recode_7_18(const sp_digit* k, ecc_recode_1024* v) +{ + int i; + int j; + uint8_t y; + int carry = 0; + int o; + sp_digit n; + + j = 0; + n = k[j]; + o = 0; + for (i=0; i<147; i++) { + y = (int8_t)n; + if (o + 7 < 57) { + y &= 0x7f; + n >>= 7; + o += 7; + } + else if (o + 7 == 57) { + n >>= 7; + if (++j < 18) + n = k[j]; + o = 0; + } + else if (++j < 18) { + n = k[j]; + y |= (uint8_t)((n << (57 - o)) & 0x7f); + o -= 50; + n >>= o; + } + + y += (uint8_t)carry; + v[i].i = recode_index_18_7[y]; + v[i].neg = recode_neg_18_7[y]; + carry = (y >> 7) + v[i].neg; + } +} + +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Window technique of 7 bits. (Add-Sub variation.) + * Calculate 0..64 times the point. Use function that adds and + * subtracts the same two points. + * Recode to add or subtract one of the computed points. + * Double to push up. + * NOT a sliding window. + * + * r Resulting point. + * g Point to multiply. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_win_add_sub_18(sp_point_1024* r, const sp_point_1024* g, + const sp_digit* k, int map, int ct, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 td[65]; + sp_point_1024 rtd; + sp_point_1024 pd; + sp_digit tmpd[2 * 18 * 6]; +#endif + sp_point_1024* t; + sp_point_1024* rt; + sp_point_1024* p = NULL; + sp_digit* tmp; + sp_digit* negy; + int i; + ecc_recode_1024 v[147]; + int err; + + /* Constant time used for cache attack resistance implementation. */ + (void)ct; + (void)heap; + + err = sp_1024_point_new_18(heap, rtd, rt); + if (err == MP_OKAY) + err = sp_1024_point_new_18(heap, pd, p); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) * 65, heap, DYNAMIC_TYPE_ECC); + if (t == NULL) + err = MEMORY_E; + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 18 * 6, heap, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) + err = MEMORY_E; +#else + t = td; + tmp = tmpd; +#endif + + + if (err == MP_OKAY) { + /* t[0] = {0, 0, 1} * norm */ + XMEMSET(&t[0], 0, sizeof(t[0])); + t[0].infinity = 1; + /* t[1] = {g->x, g->y, g->z} * norm */ + err = sp_1024_mod_mul_norm_18(t[1].x, g->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_18(t[1].y, g->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_18(t[1].z, g->z, p1024_mod); + } + + if (err == MP_OKAY) { + t[1].infinity = 0; + /* t[2] ... t[64] */ + sp_1024_proj_point_dbl_n_store_18(t, &t[ 1], 6, 1, tmp); + sp_1024_proj_point_add_18(&t[ 3], &t[ 2], &t[ 1], tmp); + sp_1024_proj_point_dbl_18(&t[ 6], &t[ 3], tmp); + sp_1024_proj_point_add_sub_18(&t[ 7], &t[ 5], &t[ 6], &t[ 1], tmp); + sp_1024_proj_point_dbl_18(&t[10], &t[ 5], tmp); + sp_1024_proj_point_add_sub_18(&t[11], &t[ 9], &t[10], &t[ 1], tmp); + sp_1024_proj_point_dbl_18(&t[12], &t[ 6], tmp); + sp_1024_proj_point_dbl_18(&t[14], &t[ 7], tmp); + sp_1024_proj_point_add_sub_18(&t[15], &t[13], &t[14], &t[ 1], tmp); + sp_1024_proj_point_dbl_18(&t[18], &t[ 9], tmp); + sp_1024_proj_point_add_sub_18(&t[19], &t[17], &t[18], &t[ 1], tmp); + sp_1024_proj_point_dbl_18(&t[20], &t[10], tmp); + sp_1024_proj_point_dbl_18(&t[22], &t[11], tmp); + sp_1024_proj_point_add_sub_18(&t[23], &t[21], &t[22], &t[ 1], tmp); + sp_1024_proj_point_dbl_18(&t[24], &t[12], tmp); + sp_1024_proj_point_dbl_18(&t[26], &t[13], tmp); + sp_1024_proj_point_add_sub_18(&t[27], &t[25], &t[26], &t[ 1], tmp); + sp_1024_proj_point_dbl_18(&t[28], &t[14], tmp); + sp_1024_proj_point_dbl_18(&t[30], &t[15], tmp); + sp_1024_proj_point_add_sub_18(&t[31], &t[29], &t[30], &t[ 1], tmp); + sp_1024_proj_point_dbl_18(&t[34], &t[17], tmp); + sp_1024_proj_point_add_sub_18(&t[35], &t[33], &t[34], &t[ 1], tmp); + sp_1024_proj_point_dbl_18(&t[36], &t[18], tmp); + sp_1024_proj_point_dbl_18(&t[38], &t[19], tmp); + sp_1024_proj_point_add_sub_18(&t[39], &t[37], &t[38], &t[ 1], tmp); + sp_1024_proj_point_dbl_18(&t[40], &t[20], tmp); + sp_1024_proj_point_dbl_18(&t[42], &t[21], tmp); + sp_1024_proj_point_add_sub_18(&t[43], &t[41], &t[42], &t[ 1], tmp); + sp_1024_proj_point_dbl_18(&t[44], &t[22], tmp); + sp_1024_proj_point_dbl_18(&t[46], &t[23], tmp); + sp_1024_proj_point_add_sub_18(&t[47], &t[45], &t[46], &t[ 1], tmp); + sp_1024_proj_point_dbl_18(&t[48], &t[24], tmp); + sp_1024_proj_point_dbl_18(&t[50], &t[25], tmp); + sp_1024_proj_point_add_sub_18(&t[51], &t[49], &t[50], &t[ 1], tmp); + sp_1024_proj_point_dbl_18(&t[52], &t[26], tmp); + sp_1024_proj_point_dbl_18(&t[54], &t[27], tmp); + sp_1024_proj_point_add_sub_18(&t[55], &t[53], &t[54], &t[ 1], tmp); + sp_1024_proj_point_dbl_18(&t[56], &t[28], tmp); + sp_1024_proj_point_dbl_18(&t[58], &t[29], tmp); + sp_1024_proj_point_add_sub_18(&t[59], &t[57], &t[58], &t[ 1], tmp); + sp_1024_proj_point_dbl_18(&t[60], &t[30], tmp); + sp_1024_proj_point_dbl_18(&t[62], &t[31], tmp); + sp_1024_proj_point_add_sub_18(&t[63], &t[61], &t[62], &t[ 1], tmp); + + negy = t[0].y; + + sp_1024_ecc_recode_7_18(k, v); + + i = 146; + XMEMCPY(rt, &t[v[i].i], sizeof(sp_point_1024)); + for (--i; i>=0; i--) { + sp_1024_proj_point_dbl_n_18(rt, 7, tmp); + XMEMCPY(p, &t[v[i].i], sizeof(sp_point_1024)); + sp_1024_mont_sub_18(negy, p1024_mod, p->y, p1024_mod); + sp_1024_norm_18(negy); + sp_1024_cond_copy_18(p->y, negy, (sp_digit)0 - v[i].neg); + sp_1024_proj_point_add_18(rt, rt, p, tmp); + } + + if (map != 0) { + sp_1024_map_18(r, rt, tmp); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_1024)); + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (t != NULL) + XFREE(t, heap, DYNAMIC_TYPE_ECC); + if (tmp != NULL) + XFREE(tmp, heap, DYNAMIC_TYPE_ECC); +#endif + sp_1024_point_free_18(p, 0, heap); + sp_1024_point_free_18(rt, 0, heap); + + return err; +} + +#ifdef FP_ECC +#endif /* FP_ECC */ +/* Add two Montgomery form projective points. The second point has a q value of + * one. + * Only the first point can be the same pointer as the result point. + * + * r Result of addition. + * p First point to add. + * q Second point to add. + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_add_qz1_18(sp_point_1024* r, const sp_point_1024* p, + const sp_point_1024* q, sp_digit* t) +{ + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*18; + sp_digit* t3 = t + 4*18; + sp_digit* t4 = t + 6*18; + sp_digit* t5 = t + 8*18; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Check double */ + (void)sp_1024_mont_sub_18(t1, p1024_mod, q->y, p1024_mod); + sp_1024_norm_18(t1); + if ((sp_1024_cmp_equal_18(p->x, q->x) & sp_1024_cmp_equal_18(p->z, q->z) & + (sp_1024_cmp_equal_18(p->y, q->y) | sp_1024_cmp_equal_18(p->y, t1))) != 0) { + sp_1024_proj_point_dbl_18(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_1024)); + x = rp[p->infinity | q->infinity]->x; + y = rp[p->infinity | q->infinity]->y; + z = rp[p->infinity | q->infinity]->z; + + ap[0] = p; + ap[1] = q; + for (i=0; i<18; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<18; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<18; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_18(t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(t4, t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(t2, t2, q->x, p1024_mod, p1024_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_18(t4, t4, q->y, p1024_mod, p1024_mp_mod); + /* H = U2 - X1 */ + sp_1024_mont_sub_18(t2, t2, x, p1024_mod); + /* R = S2 - Y1 */ + sp_1024_mont_sub_18(t4, t4, y, p1024_mod); + /* Z3 = H*Z1 */ + sp_1024_mont_mul_18(z, z, t2, p1024_mod, p1024_mp_mod); + /* X3 = R^2 - H^3 - 2*X1*H^2 */ + sp_1024_mont_sqr_18(t1, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_18(t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(t3, x, t5, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(t5, t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_18(x, t1, t5, p1024_mod); + sp_1024_mont_dbl_18(t1, t3, p1024_mod); + sp_1024_mont_sub_18(x, x, t1, p1024_mod); + /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */ + sp_1024_mont_sub_18(t3, t3, x, p1024_mod); + sp_1024_mont_mul_18(t3, t3, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(t5, t5, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_18(y, t3, t5, p1024_mod); + } +} + +#if defined(FP_ECC) || !defined(WOLFSSL_SP_SMALL) +/* Convert the projective point to affine. + * Ordinates are in Montgomery form. + * + * a Point to convert. + * t Temporary data. + */ +static void sp_1024_proj_to_affine_18(sp_point_1024* a, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 18; + sp_digit* tmp = t + 4 * 18; + + sp_1024_mont_inv_18(t1, a->z, tmp); + + sp_1024_mont_sqr_18(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(t1, t2, t1, p1024_mod, p1024_mp_mod); + + sp_1024_mont_mul_18(a->x, a->x, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(a->y, a->y, t1, p1024_mod, p1024_mp_mod); + XMEMCPY(a->z, p1024_norm_mod, sizeof(p1024_norm_mod)); +} + +/* Generate the pre-computed table of points for the base point. + * + * width = 8 + * 256 entries + * 128 bits between + * + * a The base point. + * table Place to store generated point data. + * tmp Temporary data. + * heap Heap to use for allocation. + */ +static int sp_1024_gen_stripe_table_18(const sp_point_1024* a, + sp_table_entry_1024* table, sp_digit* tmp, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 td; + sp_point_1024 s1d; + sp_point_1024 s2d; +#endif + sp_point_1024* t; + sp_point_1024* s1 = NULL; + sp_point_1024* s2 = NULL; + int i; + int j; + int err; + + (void)heap; + + err = sp_1024_point_new_18(heap, td, t); + if (err == MP_OKAY) { + err = sp_1024_point_new_18(heap, s1d, s1); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_18(heap, s2d, s2); + } + + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_18(t->x, a->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_18(t->y, a->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_18(t->z, a->z, p1024_mod); + } + if (err == MP_OKAY) { + t->infinity = 0; + sp_1024_proj_to_affine_18(t, tmp); + + XMEMCPY(s1->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + s1->infinity = 0; + XMEMCPY(s2->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + s2->infinity = 0; + + /* table[0] = {0, 0, infinity} */ + XMEMSET(&table[0], 0, sizeof(sp_table_entry_1024)); + /* table[1] = Affine version of 'a' in Montgomery form */ + XMEMCPY(table[1].x, t->x, sizeof(table->x)); + XMEMCPY(table[1].y, t->y, sizeof(table->y)); + + for (i=1; i<8; i++) { + sp_1024_proj_point_dbl_n_18(t, 128, tmp); + sp_1024_proj_to_affine_18(t, tmp); + XMEMCPY(table[1<x, sizeof(table->x)); + XMEMCPY(table[1<y, sizeof(table->y)); + } + + for (i=1; i<8; i++) { + XMEMCPY(s1->x, table[1<x)); + XMEMCPY(s1->y, table[1<y)); + for (j=(1<x, table[j-(1<x)); + XMEMCPY(s2->y, table[j-(1<y)); + sp_1024_proj_point_add_qz1_18(t, s1, s2, tmp); + sp_1024_proj_to_affine_18(t, tmp); + XMEMCPY(table[j].x, t->x, sizeof(table->x)); + XMEMCPY(table[j].y, t->y, sizeof(table->y)); + } + } + } + + sp_1024_point_free_18(s2, 0, heap); + sp_1024_point_free_18(s1, 0, heap); + sp_1024_point_free_18( t, 0, heap); + + return err; +} + +#endif /* FP_ECC | !WOLFSSL_SP_SMALL */ +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^128, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * table Pre-computed table. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_stripe_18(sp_point_1024* r, const sp_point_1024* g, + const sp_table_entry_1024* table, const sp_digit* k, int map, + int ct, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 rtd; + sp_point_1024 pd; + sp_digit td[2 * 18 * 5]; +#endif + sp_point_1024* rt; + sp_point_1024* p = NULL; + sp_digit* t; + int i; + int j; + int y; + int x; + int err; + + (void)g; + /* Constant time used for cache attack resistance implementation. */ + (void)ct; + (void)heap; + + + err = sp_1024_point_new_18(heap, rtd, rt); + if (err == MP_OKAY) { + err = sp_1024_point_new_18(heap, pd, p); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 18 * 5, heap, + DYNAMIC_TYPE_ECC); + if (t == NULL) { + err = MEMORY_E; + } +#else + t = td; +#endif + + if (err == MP_OKAY) { + XMEMCPY(p->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + XMEMCPY(rt->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + + y = 0; + x = 127; + for (j=0; j<8; j++) { + y |= (int)(((k[x / 57] >> (x % 57)) & 1) << j); + x += 128; + } + XMEMCPY(rt->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(rt->y, table[y].y, sizeof(table[y].y)); + rt->infinity = !y; + for (i=126; i>=0; i--) { + y = 0; + x = i; + for (j=0; j<8; j++) { + y |= (int)(((k[x / 57] >> (x % 57)) & 1) << j); + x += 128; + } + + sp_1024_proj_point_dbl_18(rt, rt, t); + XMEMCPY(p->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(p->y, table[y].y, sizeof(table[y].y)); + p->infinity = !y; + sp_1024_proj_point_add_qz1_18(rt, rt, p, t); + } + + if (map != 0) { + sp_1024_map_18(r, rt, t); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_1024)); + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (t != NULL) { + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_18(p, 0, heap); + sp_1024_point_free_18(rt, 0, heap); + + return err; +} + +#ifdef FP_ECC +#ifndef FP_ENTRIES + #define FP_ENTRIES 16 +#endif + +/* Cache entry - holds precomputation tables for a point. */ +typedef struct sp_cache_1024_t { + /* X ordinate of point that table was generated from. */ + sp_digit x[18]; + /* Y ordinate of point that table was generated from. */ + sp_digit y[18]; + /* Precomputation table for point. */ + sp_table_entry_1024 table[256]; + /* Count of entries in table. */ + uint32_t cnt; + /* Point and table set in entry. */ + int set; +} sp_cache_1024_t; + +/* Cache of tables. */ +static THREAD_LS_T sp_cache_1024_t sp_cache_1024[FP_ENTRIES]; +/* Index of last entry in cache. */ +static THREAD_LS_T int sp_cache_1024_last = -1; +/* Cache has been initialized. */ +static THREAD_LS_T int sp_cache_1024_inited = 0; + +#ifndef HAVE_THREAD_LS + static volatile int initCacheMutex_1024 = 0; + static wolfSSL_Mutex sp_cache_1024_lock; +#endif + +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ +static void sp_ecc_get_cache_1024(const sp_point_1024* g, sp_cache_1024_t** cache) +{ + int i; + int j; + uint32_t least; + + if (sp_cache_1024_inited == 0) { + for (i=0; ix, sp_cache_1024[i].x) & + sp_1024_cmp_equal_18(g->y, sp_cache_1024[i].y)) { + sp_cache_1024[i].cnt++; + break; + } + } + + /* No match. */ + if (i == FP_ENTRIES) { + /* Find empty entry. */ + i = (sp_cache_1024_last + 1) % FP_ENTRIES; + for (; i != sp_cache_1024_last; i=(i+1)%FP_ENTRIES) { + if (!sp_cache_1024[i].set) { + break; + } + } + + /* Evict least used. */ + if (i == sp_cache_1024_last) { + least = sp_cache_1024[0].cnt; + for (j=1; jx, sizeof(sp_cache_1024[i].x)); + XMEMCPY(sp_cache_1024[i].y, g->y, sizeof(sp_cache_1024[i].y)); + sp_cache_1024[i].set = 1; + sp_cache_1024[i].cnt = 1; + } + + *cache = &sp_cache_1024[i]; + sp_cache_1024_last = i; +} +#endif /* FP_ECC */ + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * r Resulting point. + * g Point to multiply. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_18(sp_point_1024* r, const sp_point_1024* g, const sp_digit* k, + int map, int ct, void* heap) +{ +#ifndef FP_ECC + return sp_1024_ecc_mulmod_win_add_sub_18(r, g, k, map, ct, heap); +#else + sp_digit tmp[2 * 18 * 5]; + sp_cache_1024_t* cache; + int err = MP_OKAY; + +#ifndef HAVE_THREAD_LS + if (initCacheMutex_1024 == 0) { + wc_InitMutex(&sp_cache_1024_lock); + initCacheMutex_1024 = 1; + } + if (wc_LockMutex(&sp_cache_1024_lock) != 0) + err = BAD_MUTEX_E; +#endif /* HAVE_THREAD_LS */ + + if (err == MP_OKAY) { + sp_ecc_get_cache_1024(g, &cache); + if (cache->cnt == 2) + sp_1024_gen_stripe_table_18(g, cache->table, tmp, heap); + +#ifndef HAVE_THREAD_LS + wc_UnLockMutex(&sp_cache_1024_lock); +#endif /* HAVE_THREAD_LS */ + + if (cache->cnt < 2) { + err = sp_1024_ecc_mulmod_win_add_sub_18(r, g, k, map, ct, heap); + } + else { + err = sp_1024_ecc_mulmod_stripe_18(r, g, cache->table, k, + map, ct, heap); + } + } + + return err; +#endif +} + +#endif +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * p Point to multiply. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_1024(const mp_int* km, const ecc_point* gm, ecc_point* r, + int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_digit kd[18]; +#endif + sp_point_1024* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_18(heap, p, point); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 18, km); + sp_1024_point_from_ecc_point_18(point, gm); + + err = sp_1024_ecc_mulmod_18(point, point, k, map, 1, heap); + } + if (err == MP_OKAY) { + err = sp_1024_point_to_ecc_point_18(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_18(point, 0, heap); + + return err; +} + +#ifdef WOLFSSL_SP_SMALL +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * r Resulting point. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_base_18(sp_point_1024* r, const sp_digit* k, + int map, int ct, void* heap) +{ + /* No pre-computed values. */ + return sp_1024_ecc_mulmod_18(r, &p1024_base, k, map, ct, heap); +} + +#else +/* Striping precomputation table. + * 8 points combined into a table of 256 points. + * Distance of 128 between points. + */ +static const sp_table_entry_1024 p1024_table[256] = { + /* 0 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 */ + { { 0x19c7ec6e0162bc2L,0x0637188544944dfL,0x17c27926760777bL, + 0x10da6b0430bab33L,0x10c5f8db9a96ea2L,0x1ae83300d763e9bL, + 0x15fe39cb9265633L,0x0b585ce52fa7d23L,0x18621db92da9f2fL, + 0x1936433ad2b3cf6L,0x0e177cb15aab052L,0x09a98d427f32466L, + 0x13ffa8ec11b88e7L,0x0f9fcff7890a58bL,0x19ed13a80e1a89cL, + 0x0692d7b36369d81L,0x00bafe528dceecdL,0x046fffcb50e24fcL }, + { 0x0a4753ac03c0c83L,0x14e8c55e6e6badaL,0x0e23ddd6d925a39L, + 0x157eb1e6a5c7073L,0x1d0bc15c803f949L,0x194c612fb8133cdL, + 0x05dba16fd745a3fL,0x1687edd7b318d8fL,0x120618af445e3e1L, + 0x1eaacc72a732049L,0x1ca0ed413fb6799L,0x17fae1b0ea2f608L, + 0x1f3f5addbe450caL,0x1c65a66523eb145L,0x071242000dfbcc1L, + 0x1b06e9c291a78d6L,0x1f3e256d3294fcfL,0x01550903def1e00L } }, + /* 2 */ + { { 0x15b6dae01900955L,0x04e60e75a32b6d4L,0x041f9cbfa56e977L, + 0x0f40818668a18f1L,0x1952ea6ea1ae544L,0x04b982c88c89b83L, + 0x1443d53fdcd0db4L,0x0e149b600e97b49L,0x0fd5306f1916440L, + 0x05cff39c5922916L,0x036b59e127dd885L,0x143161b9a5c828dL, + 0x015e1ad49287b29L,0x0ddd150d56ebf8dL,0x088cde66b18ea07L, + 0x07790026f38b702L,0x161f402b2f0b0e5L,0x0461f593f85f89dL }, + { 0x04ad3e1e513696fL,0x05d2e0c640ffd4dL,0x04d8f00cf44c0d4L, + 0x022f4a63783c5f8L,0x1aed610d53da6e7L,0x0ffab3a17632480L, + 0x144ab4cfa37dfa6L,0x1d7c955ae7c7bddL,0x0d983b465180f4dL, + 0x09b2934a817985aL,0x1e66aea24635fe6L,0x096ce01f8f34fc4L, + 0x1640bfd8c20ffe8L,0x0e9320debda2006L,0x098872f0e887485L, + 0x03d06f307288586L,0x110ace6500bb140L,0x03dfa0b1f128e21L } }, + /* 3 */ + { { 0x0174f88e3fd589eL,0x00bc86fcba5018eL,0x0f8cf9c1527f6d4L, + 0x1e2b249e69a12c4L,0x19b65ac58d091efL,0x14e167f77bce56fL, + 0x00af34b310988fdL,0x1bb02fb2064a59bL,0x1acf4f4d9a5f1ddL, + 0x030931aa808db5eL,0x112434bb4503274L,0x1d189b6d0da53eeL, + 0x16776b0fcc64092L,0x0f8b575b112f778L,0x0ef60a83a3007a7L, + 0x1c66ec506ce8309L,0x107757574e28956L,0x04c38f6e3382d3fL }, + { 0x10b76d5776535f7L,0x06b01131ad9dc5eL,0x0b667485bd91485L, + 0x0eaa2b7eeb8184bL,0x1e9f1675fd4df3aL,0x1439f3925312de2L, + 0x17128f0d7bedd01L,0x115deb93467765cL,0x1a971b35e806b19L, + 0x1ae0652d1e34876L,0x17762638788d067L,0x199d2ab5b3c951aL, + 0x07248d34164cecbL,0x02e057b71767a20L,0x1e03ffc6aece045L, + 0x1daae7e97dd0438L,0x1add14df768c272L,0x01cbf68851b8b1bL } }, + /* 4 */ + { { 0x13e0bb2755c2a27L,0x1217cacac2e2267L,0x183c64a179834e3L, + 0x00ec4e7a1e8d627L,0x193c569ac3ecd0cL,0x08c0c53c0078428L, + 0x0d8efc139d2ad0dL,0x1fd24b15471092cL,0x08456617cb8c894L, + 0x1e31555157cb4d0L,0x08a02d6919a3662L,0x0b1d5325e9f4cd8L, + 0x193f401e99bc9dfL,0x0261c6072ed85beL,0x137dacf81853f87L, + 0x16c31aa622a3859L,0x0a41c7575ece143L,0x020123cc2efc9ccL }, + { 0x1a251788f055746L,0x100200558f3707dL,0x13eeb0a49a5f16eL, + 0x12b69e8e81c3632L,0x1bb7ba547715211L,0x109cd2128048e84L, + 0x0a9f9e99d2186e6L,0x1dd75082767e6a7L,0x0afe771922443ceL, + 0x023469b1c23dde8L,0x1e7fd8f69250b45L,0x0383a84b68acc3eL, + 0x0d75ff46301563aL,0x159401649e1387eL,0x171c011081c8243L, + 0x05ce8d1e19b9790L,0x180ca4372fbfa03L,0x00d37e8f3645bceL } }, + /* 5 */ + { { 0x07a901a8d5116a3L,0x021ca597afa3fcbL,0x114983aebcec2e1L, + 0x0ec199f819c735aL,0x0c3f53f21e1be61L,0x088ddb5603f1e96L, + 0x0c30b760e38387bL,0x1708a8ea60e382bL,0x170dd4748920fe5L, + 0x1105f16f238c4b6L,0x1eb629649db1f06L,0x1987910ddc0e787L, + 0x176e831ac4026a1L,0x16280eb2cfedb79L,0x16a15d09a8d746aL, + 0x069ca15d3120a81L,0x15065dde0a4abd7L,0x014dbea6e0ab0a3L }, + { 0x0b3c2cbcbf4e20bL,0x1aa47ac662262a2L,0x0d516c32b07c70fL, + 0x0a01f00c4273013L,0x066905e00c0f02bL,0x080c4673095c480L, + 0x1daca3c563b5e0dL,0x1c1803b88b07eaaL,0x129803272a45492L, + 0x1d2b11d07fc9221L,0x08ac00a7437105dL,0x08b24f01d0f5a25L, + 0x030d53f272b4125L,0x12180f468f5e7c8L,0x1f41e62eb9ba900L, + 0x024d83cbe7e5f46L,0x17e9342c31022b4L,0x02e84940129c124L } }, + /* 6 */ + { { 0x03a2b7eff2f780dL,0x134106bebb58eacL,0x011e1bdd2bb0d34L, + 0x0421047fd7c7865L,0x1b5e7bf40fd4221L,0x147c66913f20bf7L, + 0x0efb1443526da95L,0x16ea779cfac2f03L,0x19cfe3f222f3718L, + 0x1a2744fecef360fL,0x1154fcfeb26d55fL,0x108dcde60179e39L, + 0x029f0ae6b19d2d0L,0x125c5df04bb6415L,0x0e96a9f98f6fd78L, + 0x0678e9958fe8b2eL,0x05dc6eb623784ddL,0x00513721a0a17f7L }, + { 0x081339facaa9a08L,0x18882a9237670c0L,0x05c184e4dd1d03cL, + 0x06485e05c312590L,0x1b5de98a8d8d410L,0x1df4a92415fe901L, + 0x0092627be51ad6aL,0x0f571a431726ed3L,0x1d5268e8966617cL, + 0x1173aa8c5be95c8L,0x11e5cffa359f0e5L,0x0a145602f8a258bL, + 0x1cc1a2946942e31L,0x098e3841b7a72f5L,0x1ee79428e644339L, + 0x015a15e9edd696eL,0x0ec68cbb175da12L,0x00ca4be30dc931bL } }, + /* 7 */ + { { 0x120b0c6417659a8L,0x15ce3c965947fb4L,0x0602da1de5ff1deL, + 0x03ceeb26c6ab6ceL,0x1561b1864caf58cL,0x07a4a328aadedb2L, + 0x02c80b9938d55e0L,0x0c1d615936e4535L,0x188594d782571bdL, + 0x0e6049cf1fd3c7cL,0x0d20c0ab0b4de57L,0x1ec1721e2888f71L, + 0x013ce4b3c1505fbL,0x0acdae0c5630874L,0x1a80888e693c9ebL, + 0x038f6bf4672e6f9L,0x1a6e578730b8dffL,0x04b5c8dc5a8bdfbL }, + { 0x1a991f49aac087cL,0x17ba7367ed946e0L,0x1e697dd8035b398L, + 0x09f22ff39211adfL,0x1de52dbfd781cd0L,0x0b90c03bcb7afb1L, + 0x04df79f6d9380bbL,0x02c1e10edecdf48L,0x13271ee643ca1f7L, + 0x1cd902c3e255c51L,0x05c41ce520411f2L,0x121ab318b86f974L, + 0x0a6f20e125df9a1L,0x1a794816865b739L,0x18b73ee8c508813L, + 0x186a285a51972f9L,0x09ddf261b8aa3d3L,0x039f9e98ae7fe12L } }, + /* 8 */ + { { 0x186855be6fd3673L,0x1b857ce90a5bdaeL,0x1e437311b34cc26L, + 0x0ab2aa21bd1a665L,0x18c1251ce553c01L,0x060de4aba3504b1L, + 0x0ea3f35f3a96e17L,0x0f89ff428d0005dL,0x110a3cb7022fcd7L, + 0x14ccefde27502f1L,0x1683413be9d5badL,0x0f3db9dabfb066eL, + 0x03251fd56e4d902L,0x015262f8a40c920L,0x0d0416fa1d8ce92L, + 0x1caf062e1a26036L,0x1fa93998b0f7247L,0x04449a7b221b5d0L }, + { 0x09f43b04713eabcL,0x1eec8d666e28bf8L,0x18efbc4f29f1329L, + 0x144b1030964fb54L,0x195dc2698b2e5a7L,0x1978a605465b096L, + 0x04d70d1a5d68b87L,0x1c63e5371dbc2e5L,0x0c3cbfd6ed40bc1L, + 0x1fa359f899311edL,0x16f9b7ec2dda074L,0x068aadb48689822L, + 0x18a8e43d985e31cL,0x05eeda7553e31f8L,0x153d631572c820dL, + 0x0d3b362d4187094L,0x0e174eacca246fdL,0x0068c4c5d8a9aa4L } }, + /* 9 */ + { { 0x0a73461e35ef043L,0x1b3ec9a4b5ab227L,0x1cef43e0e8f041eL, + 0x10a3a5386bac582L,0x11b1c1a4fad4b03L,0x1a1dcf1fa144153L, + 0x1d50d74af3d9952L,0x1838ef62b54557bL,0x15cb38a80dabe3dL, + 0x0fed0575240b39dL,0x05ad379ee43af85L,0x1c4a5791e7b10d3L, + 0x1637c4e42484f87L,0x0bd3d7ec56f681eL,0x132e4eb97b7999bL, + 0x1472301bb2b4543L,0x060a55cfd2546fbL,0x015ed58ee237c17L }, + { 0x04de22bfa6fed61L,0x0c552e646eca73dL,0x17c41c488bd7291L, + 0x1fcb5fe6ee7c6e5L,0x0a738e6d06a4b44L,0x18f89b5e1685d3aL, + 0x0a444691c38757cL,0x10aefff2675c205L,0x08b380a50310c78L, + 0x19e01143c1fe2d6L,0x1a249511c9741a7L,0x1c2cb5908443d8cL, + 0x0fcfda6e8a878f0L,0x1c66955d4d1d78dL,0x1b43ab8060fb4ddL, + 0x0c82a659b7ac104L,0x120b3234661cbeeL,0x01a9f5c495ce080L } }, + /* 10 */ + { { 0x0fdcad610b5521eL,0x0da202973817864L,0x00363ff69270684L, + 0x1597e6d75ac604dL,0x0c10a2d7cdb9654L,0x1873f03dac6708aL, + 0x0a04c79747df798L,0x0ff197c7afacec1L,0x1eb35866b6480d7L, + 0x0394679bf81b10cL,0x0197b50aa29d5d6L,0x1e3b20d450e1babL, + 0x04a51f906b283f1L,0x0a1d90543cf11fdL,0x079dd53cab1ba0dL, + 0x02ddc9e16c6f370L,0x07d57fbc0d48400L,0x046d103b8f310dbL }, + { 0x0855004ecce65ecL,0x0868fdba40c2f1eL,0x0f29e1e5eb49db4L, + 0x00efca955ac97cfL,0x1e0df0ff43444dbL,0x0843520bdb5864dL, + 0x1568e3f1095b015L,0x171f2a58877fae9L,0x0501e005a01c4edL, + 0x08b96fe252bf194L,0x0339394d75bb8f5L,0x1cb818ca1231b68L, + 0x07857561fcbaef1L,0x1a5112637428a2fL,0x103828b91a14da8L, + 0x007f8d351c44e1dL,0x15fb3f52247242bL,0x04317aaf161df5eL } }, + /* 11 */ + { { 0x16a390f226049feL,0x152bc6e5de4fd96L,0x12925d8d3edf324L, + 0x0c7bd4b1274a5fdL,0x0a49e9162b340cbL,0x0f20f9d1cf99c51L, + 0x1f9009acb7cf652L,0x1458e38f9b60cb4L,0x04a9b84a0468281L, + 0x1f75a81b98f7765L,0x0244d1db2edc958L,0x13537294cf19cdaL, + 0x1b808fd9f10cf97L,0x1057e2dcda26c61L,0x096f9a79836984fL, + 0x1ce9ea5b9cfbc7dL,0x1903a5d6864dc1eL,0x038d594489de403L }, + { 0x1618fc43b5b60adL,0x1af18250618c267L,0x0732f100cc082beL, + 0x07b63818cda4470L,0x06112a8d33cf895L,0x0b3d434e4ca726dL, + 0x134a75eab8b0f46L,0x1f7851aa926b6f5L,0x18075bd136c9a57L, + 0x0e01b9f4e4213fcL,0x12863464c897d72L,0x1a2688580318597L, + 0x07fbb3a72773777L,0x0cb16e0c75f2f6aL,0x1022019c10df524L, + 0x1e6b9e7383c125bL,0x06503e9c6f715ffL,0x046843ddb2f1b05L } }, + /* 12 */ + { { 0x02123023fdc1844L,0x113f7882f562b5fL,0x181bc5a28d21bb2L, + 0x1bc3af499643074L,0x1ef5d43e295f807L,0x1812e3b92353193L, + 0x138fab850c8171dL,0x0ea97bf8f95e690L,0x0ec939895df52c0L, + 0x1732afb6bd4e560L,0x17f8822ebb76c20L,0x0fc8a4fbce6330bL, + 0x1c313de1ea79c81L,0x0627b65d986707dL,0x0ec833677e56e27L, + 0x1f603e55dbe3debL,0x1ecfc1e0a891a8cL,0x0112f69a531f6dbL }, + { 0x013154dbabb1a85L,0x06d738f352b2d1fL,0x155aad2c403f4f6L, + 0x1dd78f1c35a642fL,0x08e73d37d44d934L,0x0f21e5810a990daL, + 0x02416ef242fe880L,0x1427847e3a04ea0L,0x02a2e5000c86691L, + 0x0595d693032c20eL,0x1072bcc009ad802L,0x05e8a4ed9cc22baL, + 0x0715932ffb1712cL,0x153a657900e261fL,0x014de91e25384f5L, + 0x192fc05adebbe18L,0x07ba8fb7602c2b1L,0x03095b072e8443eL } }, + /* 13 */ + { { 0x1d495cfba245d6bL,0x065dbd1671ffb77L,0x0b037fd7fbb973cL, + 0x119e518d4649b45L,0x0308a56b90c914fL,0x0b901a397eda86aL, + 0x127a40f6fdde44fL,0x1039f4bd9230455L,0x10dde73c83aea3eL, + 0x02dd4b13314489cL,0x1d922f29ab2f4d5L,0x0edd3140d0754a5L, + 0x0ca378ed52ff6f2L,0x042d60ec929b69dL,0x0f2129cd4f0b152L, + 0x082cf95fea5b401L,0x06e3971f81c3768L,0x007b99a70e96bccL }, + { 0x1bb5c836596067eL,0x0a70c9c60cc0357L,0x059ce72c3730cf9L, + 0x1a84806bf3050bbL,0x1fef90952b53f43L,0x07ab8d1c6298fc6L, + 0x09e1e43efa3936cL,0x04134183da54739L,0x02fecc1d6606f26L, + 0x0e44858b95be5a5L,0x129bef32ede1a27L,0x0105fce7dc93867L, + 0x17fcb66c48d1b11L,0x0370a2b9ac85be8L,0x0fab6164d5ac29aL, + 0x061f6ebad05880aL,0x149b2ae55fac54dL,0x033b1b5397c5774L } }, + /* 14 */ + { { 0x18063bcb91d6beaL,0x11d17491f65cb31L,0x064b189eb29ab89L, + 0x14ef5f3cfd3af61L,0x04aafebbc6ed001L,0x02ad48490a56679L, + 0x126768d592e59e0L,0x14a01333639c04eL,0x1e413a4e1e46a06L, + 0x02e89fb1728f7f3L,0x01f4d26ea10efa8L,0x104a63062b3c6bdL, + 0x1a546019230a633L,0x1bfe8e793011f45L,0x1cbf54e6c41dc86L, + 0x15e708d6aa857fbL,0x165b314f4f81c18L,0x00437cc3b305644L }, + { 0x07019548cbb9850L,0x05b98510696463bL,0x015d4cd59c31884L, + 0x0a064975d48109aL,0x076ee9b43ecdc59L,0x07fd32303fe2f96L, + 0x118f3ce4f403d10L,0x1cfc0222f2c5b82L,0x0f00b82519c7725L, + 0x0f3039b2de8e8c3L,0x015530b3dcaab0dL,0x1fbddf4692fbe7bL, + 0x0cf646ad11b4dd0L,0x0fbdc756eb89134L,0x01b7f941f082beeL, + 0x0a934c612d3a9f8L,0x01076b7df1c7245L,0x0340fca01f30d74L } }, + /* 15 */ + { { 0x0ad5163c9a0623bL,0x014abb3fd5c6a3eL,0x03b206bdf1f36feL, + 0x11d2cdab8459956L,0x10d4e41c469e38cL,0x159ace1a2186a97L, + 0x0049d0981d68a94L,0x082485ba7c6677aL,0x0cda3f6359fed23L, + 0x0f99b986bea97fdL,0x1d5bc1d9030fbd3L,0x0438377bcaf8bffL, + 0x0aeb8bb3364783cL,0x15684202ec3c251L,0x0d8af507b1f14cfL, + 0x1a95e96fe2847f3L,0x10a5543145c7075L,0x0064ef4a55d302cL }, + { 0x0d7273595d5682bL,0x0214197613b76c7L,0x1b562cda8349c47L, + 0x090931511fa3e95L,0x0480f45162ab40cL,0x0e7ff12c647e312L, + 0x0d6762f23292edeL,0x0bb2156b078e034L,0x0aee31a733fd5d1L, + 0x152acbde489199eL,0x072b92db0f8f080L,0x085853270110203L, + 0x1df47c8199e5130L,0x195007490700141L,0x1d6b8ee435a3963L, + 0x06164d3c5be834eL,0x196b8d2eca5871cL,0x0399ee5075d8ef1L } }, + /* 16 */ + { { 0x1b495d04b59213aL,0x1901cc6b810077aL,0x0698ad9dc707299L, + 0x08573d619697961L,0x0cdba21226adeedL,0x044868f5aa23aa4L, + 0x11ad0386aff37c2L,0x070a4a132c6d31cL,0x1e1bff0b082e9c1L, + 0x0c4f266a884cd38L,0x0326f326e4731e8L,0x0fb826fd897c46cL, + 0x01d1519f6e9bd4dL,0x07c19281e81ab29L,0x1ba8ad2fd7db5e3L, + 0x06339c86020631bL,0x1d7c3132494ef4cL,0x01559dea3878fd3L }, + { 0x153b680922c9fbbL,0x13ee4078b6368abL,0x04d6eb05bbf21a7L, + 0x0908da3b370688aL,0x12d62c214326a3bL,0x14956ada8bff71dL, + 0x0b04da416be882cL,0x11a54ae2634595bL,0x0cd904d8febdbcaL, + 0x1f6d4379f9b2fd9L,0x1ec82371faa8737L,0x150948bcef80e12L, + 0x0ccf5d118e89a35L,0x0fb74cf420bd031L,0x1e821f4f03012a0L, + 0x055a5888e096174L,0x0296f8a27d13ea2L,0x049d25a0b2613e9L } }, + /* 17 */ + { { 0x0271bc11f1efb7aL,0x1347319fe6606eaL,0x03c6c47d42a2b93L, + 0x1f5e0ec1133b379L,0x043d0e035430398L,0x11ea60a2f1217daL, + 0x0b425cfb09467dbL,0x01f56e1ef217537L,0x0de612ad5f9add1L, + 0x01bf2a70a74a15aL,0x095b4f76e2da2aeL,0x0678358548102ebL, + 0x10f0c80f94e85b2L,0x04c6da7cfc7fb61L,0x09f73752dfcfedeL, + 0x0712b458c089e8bL,0x163f3abb2f6fe3dL,0x01a16706b99773bL }, + { 0x1261394cf491b1fL,0x1776b8c84f1caf5L,0x156a7f936fab72aL, + 0x1a927ac09bb9880L,0x1ce5ebef17a6611L,0x0c4e5add222d1d0L, + 0x0101ba0b8a1638eL,0x0ab72de850507ebL,0x099877b99a156cfL, + 0x1c83533270b3507L,0x074d4eca5db44ebL,0x1e4e6d8c34039d4L, + 0x13b0f55d86efc16L,0x0759a600ed82621L,0x1980a00f2d2c9a6L, + 0x07d8a71a0fef055L,0x12043ac3bcb43beL,0x022afa579f0ab7eL } }, + /* 18 */ + { { 0x057f262754ec21cL,0x06a64f1d0dd1c60L,0x034445b07fa4fabL, + 0x09d599156c74042L,0x0a6f32cae4ea4e9L,0x1cbae718e0064d7L, + 0x087a572d88e761aL,0x116ca9abb19429dL,0x1230d31f45067fcL, + 0x05dc865b1aaff65L,0x007b3b705cba392L,0x01519600ce6ef1fL, + 0x01e162d01228838L,0x02d78a2e0cd8170L,0x0b70d503821e81bL, + 0x180cde09b916f6eL,0x1b7f70ef2148de3L,0x0278a412189804fL }, + { 0x0004fce6e2055e2L,0x123f543619033afL,0x16557e76aa8a278L, + 0x1f9d6fec769d797L,0x063784a0d15f212L,0x1b0128af662e0fcL, + 0x0a5514ece002dd5L,0x033d726038714d4L,0x00f16ba18a13cddL, + 0x189e928c43e1692L,0x08d6166a504fda0L,0x0bcdfc7faf8bf32L, + 0x1416e0ee0542340L,0x1fd6d55833c5759L,0x02111c47cef9eecL, + 0x05fecf203f45905L,0x10bc950db304d66L,0x03a6ae96a1e008bL } }, + /* 19 */ + { { 0x1002dc02b5bfe11L,0x1a086a96990f3d1L,0x1d9659e6ea241ccL, + 0x08d0b646dc2b241L,0x146f60400e248c1L,0x038bf8467d5aca1L, + 0x115da7d5ebedd03L,0x08e1b756518cc08L,0x10fa099689cdc32L, + 0x0f0157161187682L,0x185553916fbdd10L,0x13059c9af6de1b2L, + 0x075e62d22e9688aL,0x1e965d147d6f7d6L,0x1f1d27ebc544a9aL, + 0x0b4d6f10d1cc57cL,0x02988048d81ae9fL,0x0358d2a2162c2bdL }, + { 0x15ab9ad43242066L,0x178da966651574fL,0x1b1e623b71382bfL, + 0x02068361ab63687L,0x150aab370d0c00fL,0x13254ca6b45c7bdL, + 0x1a13a6a3939bfceL,0x0b8330671f6fe34L,0x18bc0e748351a0fL, + 0x0567966ed62228aL,0x14e6657a7fddacbL,0x167e2c7260ab829L, + 0x05888d837654a01L,0x19193bd8b561f75L,0x076eefee1366a69L, + 0x0e2f132264d23c2L,0x0c8597717aeabb6L,0x026109a9345d8a5L } }, + /* 20 */ + { { 0x06fe0a695532833L,0x111476b13683397L,0x0f659279cef6af2L, + 0x15e0789818455deL,0x15169b452083a87L,0x083544f4aa73ae9L, + 0x13e415dd427b9d1L,0x12293964edc55d5L,0x108275d77fa409fL, + 0x0f5b79ef85deb5cL,0x080b2f904c9c118L,0x184363893163290L, + 0x08361fee5935f3fL,0x087028f9bb6345dL,0x039c10a8632ef65L, + 0x03d16470950f263L,0x134292abead80ddL,0x032b89e14ae1be1L }, + { 0x0cca8e9ceb77b9aL,0x1f39391db4a34eeL,0x1b9a8075aca0be5L, + 0x1ab57d9bfd8ed57L,0x09290d703925203L,0x18a21c44a240411L, + 0x11f0fe64c5092c0L,0x04e08413be2f9a8L,0x17c6f2059c855c8L, + 0x0bebc312b607034L,0x16dbf904b653136L,0x0b23329883bab53L, + 0x01c89e21a319a64L,0x03501f87091a455L,0x05bfab35a412d43L, + 0x0d276ab82a2ad4cL,0x0384e36d1b57cc7L,0x035874cb61dd71eL } }, + /* 21 */ + { { 0x0789fabcceced00L,0x1f38d72dbd53319L,0x09a4b77af37cc8dL, + 0x016c3b5b1f0f65cL,0x135f803cb724512L,0x128786f08f2f246L, + 0x0ae4bed37d75e63L,0x07ac1dcd16979a5L,0x198ab2f5c1ce336L, + 0x0dd1ced3e6a1323L,0x15cbae0fd3ecfc5L,0x1d11cade11b634cL, + 0x1e172562c20f77dL,0x052c787a0ba1bb0L,0x1475b8af8d27fe2L, + 0x1e769c09b4e3709L,0x1f8368f03429e9fL,0x020115102b3c111L }, + { 0x07bbd0583847375L,0x0b5b11fa28d7829L,0x09352cb1fc60eb9L, + 0x168a4b731ac331eL,0x0e0884b5ee323f5L,0x0963bb54ec69cd0L, + 0x1055340175fdbecL,0x179ae38907ce117L,0x18ca6fd28742541L, + 0x179ee66fc1cbeedL,0x14c494fb33c90c2L,0x0210b1b0371b701L, + 0x0171391f68c743aL,0x19ddb2bf9fa4759L,0x191f8c524ebfe20L, + 0x0f3ec3a2bdacc0fL,0x15610159b11e082L,0x01890bce5925354L } }, + /* 22 */ + { { 0x14cc3ca07615ac2L,0x12f32090d6ac0d4L,0x05be9e61ade6161L, + 0x173abc1e3b5c8ecL,0x1d9457ea395a40eL,0x1432ecd48a19321L, + 0x0ba32379b5a8fe8L,0x1960ee3b72c2029L,0x077a7cce6976a87L, + 0x1ef21708a1d07b0L,0x0f3027664f64d29L,0x0d2731d8987bc40L, + 0x183a25df4b92018L,0x115816b5ebbaa36L,0x169c6242b67ad1dL, + 0x04377f555e411a0L,0x1ea5238181f4312L,0x020beb63c399a88L }, + { 0x0bd81b70e91e9a8L,0x0020c61b86b599eL,0x042a3aa88dcdccdL, + 0x08d8facead04bb6L,0x14c33ded8f2b09eL,0x0af1fdf144774dcL, + 0x1a22336109aec5aL,0x0c54c2ed90db9d3L,0x13f4c89226165e3L, + 0x0a7208fb031fd84L,0x1eb08323e781314L,0x0d39bfa55ac2d20L, + 0x048452199acef74L,0x09561a315d185d7L,0x0b520b4c1a04a4cL, + 0x0132a0237d0e792L,0x00aff4cbf89e833L,0x0010c4ea968a385L } }, + /* 23 */ + { { 0x1e419dd92599c69L,0x0110dbff6196539L,0x0f4826efeff56e5L, + 0x08c7db12b7657f3L,0x1f486f7961ea97aL,0x0a0d1cb3048a359L, + 0x104d6f471e817f4L,0x0f78f3d919f07acL,0x17f8fd42f988350L, + 0x1e5a9db8bd9e813L,0x1637359f296886bL,0x01599a292f0d0ccL, + 0x0e34b95067a6a6cL,0x0fa24ac60b79eb8L,0x0a00848dc48238fL, + 0x058e3a5bac9cdd8L,0x0fa33b2c4ab3078L,0x03ddfc55ea908bbL }, + { 0x09e4aafa78b981aL,0x1a71b182764145fL,0x1ce4e5677a8de22L, + 0x064816738e188b9L,0x08383b7d70a9bddL,0x1d081324ce6bee9L, + 0x1c6ccc1a42cb8c1L,0x09044c5ab31dd25L,0x0c62d77deb4725aL, + 0x0b792de3de1d507L,0x162d97457bdfea8L,0x043a172dad1ec5bL, + 0x03a00f1906d9792L,0x15ba63a05c9442eL,0x15d888be91dae6fL, + 0x0a09e42fbb76b8eL,0x16bc2782c305788L,0x0430684b67c0938L } }, + /* 24 */ + { { 0x0bc337d4d79bbf9L,0x1f55c34fba7c07fL,0x0254cc41354d754L, + 0x1432df172ffe6d4L,0x15ce69092ab820dL,0x141baa4b0e9e8fbL, + 0x12e6ec65fb01011L,0x1474d19c37f274dL,0x1503456ffc5f021L, + 0x08516d8c4a07fedL,0x143e3fbc010826dL,0x02ee092cb0eaef8L, + 0x198bb8770ad635dL,0x103c729f392bb36L,0x1f20de23866c0a2L, + 0x073406c9a9995f3L,0x1201a3df411f0ddL,0x03f40722101d6fcL }, + { 0x15f8a57539a1ddfL,0x073d7772432b125L,0x047605808787492L, + 0x17fa6da58838f69L,0x0aec00d92e7b871L,0x09f8d9ed1c5a820L, + 0x1e35bca09d84986L,0x066d387fd0df63eL,0x156c8b786e827acL, + 0x143fb639a43e47bL,0x1c885c677b96f05L,0x0e7ffe732831571L, + 0x14a9027c8004e84L,0x150e971479c2600L,0x197bbc6659efa6aL, + 0x106f90d2d0da7c0L,0x063737c6b08c7bdL,0x02ee55ae8cf45ecL } }, + /* 25 */ + { { 0x184283a9a7d772bL,0x0f292f2a04acd83L,0x002219052ad5ad2L, + 0x053ae96552a8d76L,0x003b0b1bd444816L,0x09fc35933c48569L, + 0x00f1c79ea0af323L,0x19e26a57f6bb0b5L,0x1f29f16e3fad07cL, + 0x01531dc20f0621fL,0x1c8b15acde7fbf0L,0x0ca762489e4d209L, + 0x1f3a28bdea19d8aL,0x1b6a2ae7331adb6L,0x1fcdcd462da2147L, + 0x17b56e958503139L,0x098ad40f9df8b2cL,0x0046616cf56e4eaL }, + { 0x06a6866c170c84bL,0x04f45ad24d24217L,0x03834132264aee6L, + 0x10c3674846f61c0L,0x10d0189955ad347L,0x0806599e4a92285L, + 0x1db438e4885578cL,0x0a6324cb6dde064L,0x00fe8595a76d42bL, + 0x14b6f707e31a9dbL,0x18372091be24f82L,0x057de14e9974ec3L, + 0x043fdfad9b4ec90L,0x07edb4bab080434L,0x1dd642975a98391L, + 0x0146e7ea75590fdL,0x1b0d29e6be01287L,0x04c8fd6e0aad52aL } }, + /* 26 */ + { { 0x0bc4b0fb4844ffeL,0x1138a307c5c38c1L,0x0389338fc7cdce4L, + 0x082c6a33d915800L,0x08288b5ff0d548bL,0x0e4d383d57c215cL, + 0x1f59e7a2c3130afL,0x18740daa2a4974bL,0x0d0b1afa0f93cdeL, + 0x004aadd6fc4fc78L,0x0fa4b7ba8cb248aL,0x1f327fc0b7c90d9L, + 0x15fa6919aa0cae3L,0x17078dc5f930384L,0x1b3e6203d51d079L, + 0x123ae55da3ee861L,0x1e99296f76b7349L,0x03367c69412cf87L }, + { 0x101905b226f5868L,0x174460b484f4f4dL,0x045928dfad53040L, + 0x119302c64657a11L,0x06bac53cf72253eL,0x15557b9bfc274ecL, + 0x011b8b8d49152bfL,0x05ccf90deee5940L,0x086bce50e666337L, + 0x151d4b05b4a8502L,0x06535ff06aea4fdL,0x02578264dcdcc3fL, + 0x042e56b0051957cL,0x02c93a064db2c7fL,0x1fc9a96734a5ff2L, + 0x05d76eca99d362eL,0x048aaa699dba79dL,0x02fe5062d0765b2L } }, + /* 27 */ + { { 0x06e25f3569a6663L,0x0bf73f3552653f1L,0x169a3462e030256L, + 0x0a4524ce604b499L,0x07387209450602bL,0x199d29cd7afb280L, + 0x0a547fbbb6cd099L,0x1341eb9ced10caeL,0x1872a360b8398aeL, + 0x01a3d4015987b61L,0x04ec8c685885618L,0x1f25dcd8dbd9a42L, + 0x085cbcf9e66fd9cL,0x15d1ff4242f852dL,0x1b35c9f5e969b90L, + 0x0342155fcce40a3L,0x0b4e09c6bb2a208L,0x032bd65f85cb9d8L }, + { 0x130466fc274c8d4L,0x128bb1854ca6898L,0x0329c1e50d7d09dL, + 0x0dd712f40c42e4bL,0x161ee1304485040L,0x0bbc5df9c6ff772L, + 0x0e7a447d3eb3ea8L,0x064ecb8cc2f7357L,0x1b135499bd8f109L, + 0x075b19bd39dc8acL,0x0733c5bdfa2dab0L,0x007430fbdea7e58L, + 0x09830b9c625b32cL,0x1788729c44d68eaL,0x17d56f05cd7ab8cL, + 0x1b61b6397b3853aL,0x1bb42428c47e539L,0x01e96d209642959L } }, + /* 28 */ + { { 0x1702b6e871f2865L,0x1b1cf8a14906b4bL,0x0a8116d618455b2L, + 0x03e7627024650a4L,0x112206e8f3943adL,0x06acf5736110053L, + 0x1dd670a24396a8dL,0x0cf56a5fa81ed6fL,0x0f522c8de180bf5L, + 0x00f4bd9566771cbL,0x1d606713a972ec6L,0x0bd156a3a7dfc06L, + 0x0abcb50fd80d998L,0x0bf0e406f1364b6L,0x058d5f7ee75ac4eL, + 0x18ff6b0563029efL,0x06189a7822107f4L,0x001577796e01abfL }, + { 0x1a7926f2c7ec9beL,0x1983f392c590095L,0x08431be9ad28a4bL, + 0x13c5798b56e9cc5L,0x1bb8c07380c0854L,0x0f8ca6da0b06dc3L, + 0x12a7357bc14a4caL,0x1a21d71b428dbb4L,0x00b5d43d215ea23L, + 0x075f7817e1a5fd7L,0x0d9342121d5e9dbL,0x06d05a69994759aL, + 0x021d2d95e2c1401L,0x1c37551404e533aL,0x0597fb30ff475b9L, + 0x124073d6226db45L,0x0b048871baac077L,0x035a23600a58ad7L } }, + /* 29 */ + { { 0x019eb2e25e8fe80L,0x1bc834c11c50be4L,0x065a07906124ad7L, + 0x0d31d4da8bade3dL,0x1fd02e4058ad8adL,0x0920b6add72d6a5L, + 0x1f28405b70c9ea0L,0x1231663530b4668L,0x10b4da61082a653L, + 0x05c8d96da461afdL,0x1a05f34aabe3107L,0x09079bfb9b813d2L, + 0x0112b692541a630L,0x1c51504bb82ac9bL,0x1314a057f735c4bL, + 0x0c12ab356c4746bL,0x12f30c8ebe0932bL,0x04309a125d84702L }, + { 0x0902063b2231d8aL,0x11194ecd30b3394L,0x1f9c1c6a7c9ec3dL, + 0x00c07e08fd55f41L,0x1d92a1c36bcd896L,0x0a41db08c6653b7L, + 0x14988d05398adc7L,0x0b5424799bb74e0L,0x11a576437fd9b5cL, + 0x0980de1264687d1L,0x02b51040909f369L,0x0bc1a754d8052deL, + 0x00072a39960e6fbL,0x02069fd6e6c6244L,0x047550536bf284aL, + 0x0e69a53e9947bbdL,0x17c0037c5988441L,0x043199d4cce67f2L } }, + /* 30 */ + { { 0x013a751ecf53b40L,0x1637917bc52a169L,0x038bc4eb95b73fcL, + 0x1e1cc2e91c1eb3eL,0x172c414591f8ccbL,0x0e6e5b8556f65ceL, + 0x1f1c1acbb614932L,0x0051c016e583d5fL,0x089b24285aa7281L, + 0x13f53f05b3ce57dL,0x0e30993c29bdbeaL,0x02e61d00872eba5L, + 0x05c85730497ed7bL,0x04c3749f2d49f5aL,0x08302bf24afd750L, + 0x1875ea4d6b538d4L,0x0c90adf47c9b99dL,0x009592ff15d1016L }, + { 0x1b8d78a33eea395L,0x09b0c7b19fe2e04L,0x18a49c3b3bbf1eaL, + 0x118c51da18fd042L,0x01d68939524779bL,0x176e4848edae50dL, + 0x1cefe189b863961L,0x039fc047d17fd67L,0x06279fde1025017L, + 0x09763ee2af0b96fL,0x1a1a571b5329179L,0x10f17b7821e288bL, + 0x086fc3835e42de3L,0x1f085b291588a6fL,0x039e3fa7eae9159L, + 0x015948223b05472L,0x174576b61c2aedfL,0x010b13cd4ba5665L } }, + /* 31 */ + { { 0x14cdabf4047f747L,0x1119ee098ad0f60L,0x0f4d0397429c0f2L, + 0x13768270d2b3cf9L,0x0f01fbd81fd0c4eL,0x15c11e8c4e84588L, + 0x002854112710a9dL,0x1c9038449427316L,0x108084e4f8e8179L, + 0x0c57cca34c720f4L,0x038df15842fcbbfL,0x087f4fa4f21e3c6L, + 0x0cb31953884e6a0L,0x01bccefececb730L,0x1fe40bf9d7e61b4L, + 0x082dc76951e23f1L,0x15efa9453787588L,0x010341f1fcc13a9L }, + { 0x1582e26d0378878L,0x0a611d3ca2bc3e5L,0x02fe3d9a22ce788L, + 0x0a80a2a4e027a00L,0x00111f5d7548d4fL,0x1ffc813889e0aeaL, + 0x11730efd6949aa2L,0x00b7b4d60213692L,0x183dcc74ebc2f3aL, + 0x177b14221f7efd0L,0x183ba559716fd0aL,0x021ab25e4875a5cL, + 0x121bc3bf514f0faL,0x102bb53a3572c59L,0x1cc206a04ec21a1L, + 0x1dcb2178047f09aL,0x1959fd03aa032dcL,0x02f20b5fa93eb63L } }, + /* 32 */ + { { 0x0313760026cc23cL,0x0d5775ad9482c12L,0x0be3174bb85fe06L, + 0x17dcb988055244eL,0x17def07d8048e7cL,0x17c10f6de3eb773L, + 0x0ee25875a4913daL,0x148bef2cddb32d9L,0x0f81b17ea96a155L, + 0x16cf7b801f9f6abL,0x19641ba20a96cacL,0x00e55d28e300bcdL, + 0x11658c76f486fa1L,0x0581ad501a6cfe2L,0x0f992067d80f703L, + 0x153df6f673fd6ebL,0x1e3ca87554acf04L,0x027fb417643da7eL }, + { 0x125627fd0a10ad5L,0x02e394b4737a298L,0x15ae01a8458dff5L, + 0x1bbca067c653037L,0x1f4f8988b92de1cL,0x13f0ee1da25a2f5L, + 0x161e3286e625b6bL,0x08ea42cdcb40ef1L,0x182d472bea51168L, + 0x1ee9c157944aa22L,0x14580975bb1327eL,0x16396caa560445dL, + 0x13a1e6210f3614eL,0x010d3a53b1e2efbL,0x172f537a4580a14L, + 0x1c533489948018cL,0x07c48cb187e0f15L,0x028f5c0c71a0128L } }, + /* 33 */ + { { 0x1c1d178b92100abL,0x11eb04b02dc1c8fL,0x0956dc7967437cbL, + 0x0a29f97c08254f8L,0x19fd06af3f8b667L,0x01068387451c9aaL, + 0x1ef9558c9940848L,0x0a8cd2df9a2a51cL,0x16588514b0c7b76L, + 0x06c07c62c8952daL,0x1fbc13cc932dfc3L,0x1d9f8db47aeb175L, + 0x1831d1df2f6b53eL,0x19c095b6f6f7a46L,0x18980c7ccdae595L, + 0x1e137905d5c95dcL,0x07f300abd32d244L,0x045857caa98ecb2L }, + { 0x170180a2e603544L,0x19d61910d66cf5bL,0x19958901c0c8ad5L, + 0x1b7135787a742feL,0x1793225aad3e74aL,0x012b25c51e971d6L, + 0x14ad515eee813bcL,0x1d110eaca5ff85bL,0x0d2905d15e67143L, + 0x0c425a1017246b8L,0x0648671d8da95dbL,0x08426bc6f1be0dfL, + 0x1d10c64a02a8dc3L,0x060abd334ae0eb9L,0x0928d5335a93b3bL, + 0x0653b75b983911cL,0x0d08024f1b29839L,0x029b1f2a4a6d245L } }, + /* 34 */ + { { 0x15523b7e23fc641L,0x07397c33338318fL,0x17d6380274bff95L, + 0x1f18afebc252942L,0x116d64dcf203997L,0x1517fdd114b9265L, + 0x03b59a5ef93f52eL,0x06c7ea0fc8c14ddL,0x00afe3a5d785085L, + 0x177b66ecaa04104L,0x1f6227cb108df3bL,0x1074b870a4a6e03L, + 0x0d72a212f1496d8L,0x0ffbc7e6f12e33fL,0x1bd05192d059e0cL, + 0x00d2fd32ce00982L,0x0c3fa45c3a1c45bL,0x03199a00c1fde98L }, + { 0x1c9a0cca2fbbbceL,0x1b72e55065ba21cL,0x0438d0e3b38e1dbL, + 0x1c27005b0539cc0L,0x1cd45a1b0aad148L,0x07e0f04e1f2e304L, + 0x137421d72e165efL,0x057633fef21b0b0L,0x12598b81ed81c2aL, + 0x0c5ef97815f03f1L,0x1f23bae5d973a44L,0x1b11649f2b5c0e9L, + 0x1c0c98f09d125e9L,0x105ba5939dd8966L,0x001df3929abb81eL, + 0x004de8e47a5f381L,0x173959447d6bea8L,0x049d383ae0b1405L } }, + /* 35 */ + { { 0x0bbefe2715b27f9L,0x0d2f11514049193L,0x0ebff56289aaa4dL, + 0x0cf8270d28bbbe4L,0x092a215354c83e1L,0x0684faa23ccde4cL, + 0x1a9a139b91c426eL,0x16d8c75ec2dab11L,0x05e896706883ab1L, + 0x009c9d01e90499bL,0x1ca4864b08f768fL,0x16f5b9edd487a05L, + 0x08791559e1ab70cL,0x16b87f858921a75L,0x0cae914101a036dL, + 0x1971e3421fca450L,0x1fdd69f9c08e5f0L,0x00d3a11562258a0L }, + { 0x1a9dd2e9f40b675L,0x03301fe638f9ce1L,0x098465238d08a9fL, + 0x11da15690831273L,0x0e31ca6b8f3b615L,0x146db1d1d53ecbfL, + 0x18b92f07a197bdeL,0x01e62bf181258f8L,0x1a260788f9f5c6dL, + 0x0c19894a5b79f62L,0x16f358dad36126cL,0x112178d33536e75L, + 0x182a1175e766e14L,0x1e29e527df9bc86L,0x1fd8245fd0d816bL, + 0x1056caefed88f0fL,0x19c827c7552600cL,0x004a26b184e92acL } }, + /* 36 */ + { { 0x1deb63ee6ab9620L,0x07d36bc366c0467L,0x1609158c82cf7fdL, + 0x058928722a28bdbL,0x173b3f872ae5f86L,0x17cbd4ca847409dL, + 0x06d88ef6017cf94L,0x1f9ee36b8519305L,0x0b394c70e86e0ceL, + 0x1a7d8d491ded9b7L,0x1d618b6f89f9694L,0x1be70756c2d3ac9L, + 0x1127c828cbbae23L,0x1d183d456eb6f8dL,0x0777d986406267cL, + 0x076ee6d990cb302L,0x176a3cb77747994L,0x03ec4f9c1b7ec32L }, + { 0x0564242c9f92b2bL,0x0353ae237195efcL,0x02ddfe669715c03L, + 0x1006292ad127cedL,0x02ce6709b6efe85L,0x176249ddff450ceL, + 0x10a35c868ec6fb9L,0x03a4ddddd5386e3L,0x1d798115e15177eL, + 0x1df9de7583452d2L,0x1688811b4ad2cb5L,0x12b6b37d3bf9bf1L, + 0x1c77640b793df09L,0x0d15e9e2e4b44bdL,0x0bf9d133833d309L, + 0x013762de8badd13L,0x0e6b53f3acb3a85L,0x0224d7c0fb1f953L } }, + /* 37 */ + { { 0x0fcf132a16d9377L,0x1bbd9bf0d17cf61L,0x04ba1b466b966acL, + 0x0da0277762e5c34L,0x0b5f66bad2b12e6L,0x0f55a804b9702aeL, + 0x17b0b44778700e6L,0x12783e629fb8cbeL,0x0fc3118418a9ff5L, + 0x1b9e0f670292373L,0x144d8c589415b77L,0x17aedf64bc33851L, + 0x04845cd2d730a9dL,0x09b74296824f692L,0x0322a0f1de6e0ffL, + 0x100670b46bf8fedL,0x0f5299bf1e1c95eL,0x007430be190448dL }, + { 0x172060267c81b5cL,0x04ee6f39bc39e29L,0x02c2a0513f40beaL, + 0x0e4c41190654e86L,0x18ea40f53006c5aL,0x1209d2270333306L, + 0x0527e774097e625L,0x1857be701988d72L,0x1801566190a125cL, + 0x06b51dba93c9e1bL,0x004dd1ade98bc81L,0x04d0b0bab2f16c0L, + 0x188395fe66a9cfeL,0x035930fb6e56865L,0x0764862ead1a3f1L, + 0x04805941debdf3bL,0x087c507d4a85e45L,0x037a2027899367bL } }, + /* 38 */ + { { 0x1e1920b4febd3ffL,0x11a6c7efe95dd51L,0x1cab866a60a7298L, + 0x018deb78416fa35L,0x1aa39ca923de161L,0x063855f1026df9eL, + 0x0dc2ca8b7a6e1b6L,0x01c4e5c186ef93aL,0x080914c06e56551L, + 0x108f3d42be5db58L,0x1f1bbf6099a9badL,0x09dc612b00380edL, + 0x02b9e24063dfac3L,0x1c3d52e2b4ffa05L,0x11c334a9ee8c6a5L, + 0x1e0e81c9a3fbe67L,0x1e2903e31326895L,0x0482bb8fc3fdb38L }, + { 0x199ba0da4062beeL,0x191c64a6becfca8L,0x06f078248b00639L, + 0x03625b0abfea7e5L,0x0d68ca29de9b2a8L,0x0604bfb24f9f76bL, + 0x0628192b7f0d314L,0x049032c95733b67L,0x000d59c477a5872L, + 0x0ff51cb3a62c81dL,0x1f63b85410f7402L,0x14dcbe3d9840d55L, + 0x030db9b7b4c5721L,0x13646a955b6b524L,0x120a89c1bff185dL, + 0x1ef507bc483ad59L,0x0cc0605f05227f2L,0x035114a9db2026fL } }, + /* 39 */ + { { 0x0452d8f74fce389L,0x11a60157d2ab249L,0x12efc3b5e094165L, + 0x166ee31c1b26ef9L,0x1fa69a4d89f4045L,0x0ad85d0883a73ecL, + 0x1b79975c2ec1dcaL,0x0f7645aa95be20fL,0x15c39a3d8a1a29cL, + 0x191b6016bcaf1d5L,0x00b400ad626544dL,0x0b7caf217dc5ee5L, + 0x11a8e65ea25e226L,0x1000e75ec8f0750L,0x071500839c69c21L, + 0x0d3022d201eb458L,0x027c3b2d5c0357fL,0x029464f5030cf1aL }, + { 0x0dc86b45f26c577L,0x1a3844a1c5ea28fL,0x004de4960a9fe01L, + 0x01bc3cad3e5bfc2L,0x1a55a356e08eacaL,0x0bb10b2fca977d4L, + 0x1c7ca93602d4f92L,0x1e1a56cb0ab9abaL,0x0246704bf66cea3L, + 0x09fb20fa49191e5L,0x0615726b6c4c946L,0x059c5a33aca54d0L, + 0x105b82ed7b86d52L,0x070a8694a9b04f8L,0x04fa244ec3c0252L, + 0x16892475b17f616L,0x157cbb1556cf794L,0x01007c849b9c5e7L } }, + /* 40 */ + { { 0x1b22fc58388387fL,0x178b8147441e2fcL,0x0e4346de5cf33c9L, + 0x05edd922e288f95L,0x030cdbc08d5d4eaL,0x111e15970b7a4c6L, + 0x11517724a443121L,0x161d629236061b7L,0x0631deb2e14de21L, + 0x051083317f4187aL,0x1a5e70de707cfc1L,0x16d1f60d4f2b498L, + 0x1a1619dfa98a732L,0x06df164d9d22193L,0x0627faa468c1f4eL, + 0x0663f273791a407L,0x1dc3daabaf20f4aL,0x02e183f4c6e87aaL }, + { 0x1c4e0c435b233daL,0x14842917b7cc2ddL,0x1486a2c091a38f4L, + 0x1352d22dcf33ba5L,0x014bcced978f40eL,0x083b160193ec363L, + 0x1cbb657a5540acaL,0x0661ffa432f50f3L,0x0c436513750e0bdL, + 0x1618a450413e262L,0x004aa0ff3f02c89L,0x02fc63250b138f3L, + 0x1e8830f42dc3d8dL,0x0583fc1fc5ab967L,0x144523df367fe49L, + 0x1f358663952a014L,0x185d0c539684c59L,0x00ef8b6fd60a1a3L } }, + /* 41 */ + { { 0x07bb4ac68bcacc3L,0x169a7a187ac67e6L,0x1d3f518615681b7L, + 0x088b93e1798b3f3L,0x0375c892f549199L,0x02cc1d6e2fbf632L, + 0x1421c6e1c23c4f2L,0x01f6654b98905f9L,0x1efdcdc352d6b4cL, + 0x1d9278245637d96L,0x0b53d4ce4191c52L,0x0a5f70747588b30L, + 0x082337a223162ebL,0x05e1ede9b8986f9L,0x19eb03b739ee00bL, + 0x0e2fd1672b2b248L,0x01721d3d2e81b56L,0x0394d3fa8232893L }, + { 0x14ed1aa8420f90aL,0x070cf07f2642ac3L,0x0aaac2f9d2bd8daL, + 0x01194c19536c5a9L,0x1645a86776fcc48L,0x18d92679885ad2bL, + 0x16d104c6eb26f76L,0x09ddeefae3a5bd4L,0x04706d21072fcc6L, + 0x0dc9348b39ebbf8L,0x002fcfa278198caL,0x19a6e80efa8045cL, + 0x0d829232e2472d0L,0x1c6e42999f10820L,0x0e3d99cbe45b7ecL, + 0x1c33a91776b3629L,0x15c19de9f4ad44bL,0x03fb69b249196ceL } }, + /* 42 */ + { { 0x1d064de6e794819L,0x1b4a77c175ed09dL,0x1f82e478a01169aL, + 0x060f4879a43e02fL,0x030433e9190d31fL,0x1fee5a361379133L, + 0x04702e9222a9c2aL,0x100831b210b48c8L,0x11b934fe6bffb58L, + 0x0e8f11bf1007c24L,0x1358fe95504f6ddL,0x1aebc4767eefbe0L, + 0x0b0f91bd30e216eL,0x1b94e284d02c336L,0x0aacb5e130e5765L, + 0x1ad0dd92fc3108aL,0x06c8cb7c1f90093L,0x0168191cab14784L }, + { 0x01c94074a44b4c5L,0x0343ce638164c54L,0x0a1f3ac3725ee61L, + 0x0cdc75464396a04L,0x04c256c23030112L,0x0da422e05643b1fL, + 0x1cd6d940d348395L,0x1b9552d4081e481L,0x0046d26d37cf7eeL, + 0x152d4709dc0832bL,0x112e5e0f5c30ad8L,0x1f10b3c9b51f0c0L, + 0x1a5457f5d12fbafL,0x1a98dbabc94ec80L,0x13a5ce74a787acaL, + 0x137b2429b57b93cL,0x19b5bd724fc4eaaL,0x039a609598f7cddL } }, + /* 43 */ + { { 0x0fe3c2e92f9b086L,0x0dc9f59fea2a24cL,0x022d700b1971190L, + 0x0389e064848f9c4L,0x079d29f68a52dcaL,0x037afa5af60becbL, + 0x0a044474bfb4250L,0x07e4c1ec7b81b37L,0x0de2b056f15472aL, + 0x18b86cf80394873L,0x08fa36dad723e46L,0x10739e6987dd45cL, + 0x011b973ee2345a2L,0x1d9268e2cdee2a3L,0x185068596f69b0aL, + 0x164032faa574678L,0x09f47bb16129d2eL,0x03e2ac54390fdf2L }, + { 0x1485a523f350fecL,0x13c62b51c6a605cL,0x1a88356a9934059L, + 0x05b2db45c91de68L,0x0f647b3cb85daa0L,0x0f4a36422f62752L, + 0x1d2af03469b2835L,0x00683b1a3829f53L,0x143972cc59c8b13L, + 0x1f0fa46a1a7fdfdL,0x13a4ea06748c619L,0x0120dbbde47e6a1L, + 0x19200cf12c49f53L,0x1202197e1e17367L,0x125ad4909a47305L, + 0x12f7d7ffee968e4L,0x14844527c9f020aL,0x01a66bee53d9e21L } }, + /* 44 */ + { { 0x031761a59e7fe87L,0x1718d0023e6b978L,0x19a3eb8c3d8ac7aL, + 0x1b6e3b62864f205L,0x0e0038f4a666f48L,0x1eebb6baf7333c0L, + 0x13570ed16b19c0aL,0x0221a5f705141adL,0x027ce7f1d9d8c5bL, + 0x00ff0720905af4bL,0x06e612e499f0dc5L,0x0b13ac06259b2b4L, + 0x0eda5493565206eL,0x03863a560c339a1L,0x15ec2ccdd1482e4L, + 0x118284e07976b2aL,0x087f621f59ca6edL,0x03e758e6155fbdcL }, + { 0x047a5bbdb7fd65bL,0x02e601b64a2be03L,0x076e7849c62b635L, + 0x09d274ff638db53L,0x1d1566a1ed1dbbfL,0x00648ca28964ae5L, + 0x149a52186e8036fL,0x15c78d985313cfeL,0x1671961500941aaL, + 0x1e7ae87e4629c71L,0x1a64a68969547efL,0x130a2f941e4d5adL, + 0x0afa89ef7e90710L,0x18d5a2a4ba1dbc7L,0x1470db4e757a8c5L, + 0x0ad1ae885e7e7cdL,0x15c25a683e0059dL,0x00fb14d4c913e76L } }, + /* 45 */ + { { 0x125ddace45a1c3eL,0x149b2a0fbaa2fc4L,0x1f2cdf9fe0a1cb4L, + 0x067c98f3a48ac45L,0x1c2645d68823451L,0x04015caeffd7c24L, + 0x07e80c1e3d37665L,0x198acd24fe13a67L,0x19a500a1e9fd91dL, + 0x10040c0055855ebL,0x04d68e0653977f3L,0x060f315be111b2eL, + 0x189a45a2a79e876L,0x1c45a1cc9dd780dL,0x1ea65f5bfb58551L, + 0x11ddb301cae45ceL,0x1a2aac90ffa2a37L,0x0253afed145ec02L }, + { 0x09a8fbb55e74cbcL,0x19c677d58c792e8L,0x0b5a5d93b0e9cddL, + 0x17cfc15a621f847L,0x0481cc9bc5a7d35L,0x05761a73af03477L, + 0x18f13c30baa64f5L,0x059e2649fd01a94L,0x15dbb7c1699b059L, + 0x016b3a6d3f07a35L,0x159b1e8c03eba91L,0x104266675906b4bL, + 0x0e8c408496e83dcL,0x0cf7afe0b877c09L,0x0d3a18a5b8772daL, + 0x00fb0dc56ee362eL,0x19a04629cdc5835L,0x02c0cfcd711ec0bL } }, + /* 46 */ + { { 0x19691216aa78811L,0x1747a1081f3e1ecL,0x01c08ae79a63d93L, + 0x1c9eb059bdbbe02L,0x0ecfac1ae6001f9L,0x1c9804925304579L, + 0x0a445bbd31e1018L,0x140a4c5d5cdd7eeL,0x1ddbd0af58c4ee5L, + 0x1ad7fc8766c3de3L,0x16cd31bc93c4521L,0x0503d0cbe2e45fbL, + 0x06886c1b9a48104L,0x0f7a118fcab4921L,0x09fa0b9bd7cc822L, + 0x12b915eb0f59fa1L,0x150d65719179ac3L,0x03a2cb01e09b253L }, + { 0x02475bff41ae519L,0x00fd8a57c79288eL,0x134abbecb0f4d10L, + 0x16a39b5e10e1bbfL,0x0208bb199b2d385L,0x19f9fb4298e12b4L, + 0x05da45b2277d930L,0x1758479f53248aeL,0x12339b51e86d010L, + 0x06d87469131c189L,0x0785e403fb7adc2L,0x1b9746d0fde3eedL, + 0x03914764753fd96L,0x0622e46ee682359L,0x0d0f5e3cffc8190L, + 0x1dd21dfa2cf7b70L,0x145493ccb6d4b77L,0x019812a89d9e7bdL } }, + /* 47 */ + { { 0x0f0046935eaaca1L,0x025bac488c8811bL,0x19979b4a553030eL, + 0x1363d3adaf966eaL,0x029c2757cb9199bL,0x139c683ac291a4eL, + 0x0909e272f46eae3L,0x113371b7d20b247L,0x1a237793e18fe18L, + 0x0138babd3a17041L,0x05e7493baf584e9L,0x00a9a9e59eef189L, + 0x11958705de40325L,0x19ecccdd51dc504L,0x03fb8786c646f64L, + 0x1be2975fdf74876L,0x01cb3bad1843facL,0x0499456d821c3abL }, + { 0x1e84e80f906b872L,0x091d03c131332d5L,0x09f8ce6333ddc15L, + 0x1beab6a647b138dL,0x0554dea82fab551L,0x0ac4e6d02bc7650L, + 0x15d43bc9948f4ddL,0x1fdb1fac4850c95L,0x093f27fc5178fe1L, + 0x19f37984efc3a11L,0x0b9278dd434151eL,0x0d64bb80714250cL, + 0x0284db682b7d90cL,0x0c40c98560d0d71L,0x1cf82911fcf6adeL, + 0x04b8a61cd7aa575L,0x1e70680025bf62dL,0x00550f9e7d6e86aL } }, + /* 48 */ + { { 0x182219022a10453L,0x15c8e1501d085d4L,0x16565991bcef747L, + 0x09e716df8d5f76bL,0x18cfca1da58de34L,0x186d026723e1f2dL, + 0x0bb5bf36385b43dL,0x11d58886937b44cL,0x09320d87bc56e2fL, + 0x071f5040c89c72cL,0x18b7fe8ac8db027L,0x14b91cfdf61b4b0L, + 0x0b16ac78eb6b0f9L,0x184da8d7a5a9a19L,0x14658a1bfd0c415L, + 0x0075a11c46df11eL,0x05e1f93f176eed4L,0x02ac99bf04b1b2aL }, + { 0x0ddf738d8fd807aL,0x0764ed589891118L,0x136d896bef0fd38L, + 0x093e25f12a2945eL,0x0c3044fdd5b7060L,0x000a47da379e11dL, + 0x195506c8cb47fd5L,0x0eac368b1ea7369L,0x1f694b24a0dd70bL, + 0x1e3214c944ac0ecL,0x1526fbb97f88b43L,0x08fed4317ec780bL, + 0x027f1929d67af34L,0x00aa8f4674b50eeL,0x1753e89abf980a3L, + 0x059684fb595e656L,0x0d34a1631bc545cL,0x04980387cd8648aL } }, + /* 49 */ + { { 0x0f32c5e69a9bc05L,0x00ce32c4e25b9e9L,0x197a51997e70297L, + 0x0779f6987212b93L,0x1ddb7c318ab0f29L,0x19c0245c83843b8L, + 0x166f6253a59619aL,0x0d3e335219ec0d7L,0x1cc1d58dfb6fd2dL, + 0x036e627230ec534L,0x1709dfe73920c62L,0x132cecbf150588aL, + 0x0cc3badc8d749a5L,0x088966d597fe334L,0x10f1f2ce0060e5aL, + 0x04449530f2b8764L,0x0148775f310010aL,0x0021d10a0ac3dafL }, + { 0x1be9dbc3a873752L,0x049fa17a217f73dL,0x0b2306308607b85L, + 0x01c52ed3cf30394L,0x1e768c5f00ce309L,0x0bb3bf5a3135646L, + 0x05398cfa73918d3L,0x17ff138595bc1f5L,0x004f5cc1141f5b5L, + 0x0b2fb9b11146096L,0x1dc1a8301733949L,0x1fff7c90f89fe37L, + 0x09a499f1a45d07fL,0x0c6ca4001f621e0L,0x0fc4be13d39e6eeL, + 0x01adb1466b42c0eL,0x0e84bb5eaf70f97L,0x00c683a3df92685L } }, + /* 50 */ + { { 0x0d3c77c84601fafL,0x12df1578e0fb92cL,0x1e63445b601b251L, + 0x0dab61b279fec4cL,0x1ec6723a3996c0cL,0x1d29a497d0d6baaL, + 0x1362a59aa05100eL,0x0cbb89928445586L,0x1ddf471deed6758L, + 0x05652cbca9ea947L,0x118ed493afd9f76L,0x10e2fc4b69a765cL, + 0x1a43159daa25824L,0x019abaa011e2d6dL,0x0e2c6995163e71aL, + 0x1a4639ed0bb4ff2L,0x059981a4fdacefeL,0x0388849f6845dafL }, + { 0x0aa3fc6401f161aL,0x0c2b04ba62f4389L,0x0bec5ed77e0bdcdL, + 0x0f491cc5329544aL,0x09dd847db0b82b0L,0x14e2d30011a0ab9L, + 0x1d4e3c795340114L,0x1979838a73cdb31L,0x136162b5328d3abL, + 0x0d1bc9c15427866L,0x1ea06d37b9d211dL,0x0bf698477e37ee2L, + 0x1f787e8b3e16cf3L,0x0cdbcd583fe8e14L,0x1db182edf69f9a1L, + 0x0916a0e4201410bL,0x1d431840159e7edL,0x00bc4c5ed26ce4bL } }, + /* 51 */ + { { 0x18483d8ae1b8cf8L,0x0a5a174d1442b66L,0x013c81292f08c8fL, + 0x1194f4d3f4ec66bL,0x1757bab24e0b222L,0x02fce5457ded45fL, + 0x0570e16c90221b3L,0x0d68ff69027a835L,0x13f1bc53cc2aabeL, + 0x1166d1f8d68acceL,0x1b02070c7aa6c7cL,0x009602c29582365L, + 0x09c6afa7ab048f3L,0x00a06e1ee718e77L,0x1a2aee956bdd8cdL, + 0x07dfd096f566fb9L,0x0b250de7648c7cfL,0x039d446e78a9ab5L }, + { 0x186828806e83b39L,0x12209cfa201be9fL,0x0c3c5f6f21051deL, + 0x1ea9a2ea93f20b1L,0x12307ffe2db64f4L,0x093130d11e75357L, + 0x1fc98e4fbf5553cL,0x06a5e9ccb1421e6L,0x1a4437ce3f4ee1eL, + 0x077a153d49e6f45L,0x0f27d24e6aa4059L,0x1ad47af6b9a83bdL, + 0x11f88a3acc44223L,0x16304516bc4d350L,0x1d5b0195bee77e0L, + 0x14601cf3b71c777L,0x01e73c56af2668fL,0x02979958bd71cb5L } }, + /* 52 */ + { { 0x0f524c1e714f71aL,0x109314d6ec28cabL,0x0761972b6f8f06fL, + 0x10b41f6c935b231L,0x01d192d9d88bf5cL,0x1925b7cf7d35491L, + 0x046738ffa0e25bdL,0x181d87f5c4964a0L,0x14b6af9f62ae0d3L, + 0x1e75d05eb0cb126L,0x0c24acbf6db8ea3L,0x06ec64c79a52fb8L, + 0x1ef95c43bdc91daL,0x06f5a26c98603b0L,0x1034c76244d9003L, + 0x1133ffafb9d0887L,0x0c178fec3b19871L,0x03cf0a69477efacL }, + { 0x18222359bb40c55L,0x1901687683d2171L,0x06a520e307d0289L, + 0x0fb0c94f1c91cd8L,0x0c6c55c92b5f24aL,0x096a843f3f8a050L, + 0x0784398b0412b38L,0x1ab361434fd8236L,0x0fd8a275fafbb3dL, + 0x1f9aa7f4d1db598L,0x0176791980a8077L,0x169b2776cbeeb42L, + 0x0b0f82fdeb3d371L,0x0f2342a2ed2e5f8L,0x0f545f918048a6fL, + 0x1e924a0bc21738eL,0x0e277cfa541672fL,0x006c761454cab36L } }, + /* 53 */ + { { 0x14cf73ecbeee995L,0x1c45e6a48f40600L,0x12b766ae9752cbaL, + 0x072609909ac2b4dL,0x0ab03c9a2f7d463L,0x1d5dca5d0280e94L, + 0x15dcb23dc8f7a46L,0x129910bf2eea080L,0x0b5e1d2b3c7fcb0L, + 0x0f73ccaefcb638dL,0x036aacd19126798L,0x1bbabec0f265719L, + 0x01b1243587db425L,0x0fe3a1a038128e5L,0x00ab2249b5f4efaL, + 0x14e9f182f262192L,0x0fc72522c154559L,0x043000f13e1b9a5L }, + { 0x1b00ba5e7693947L,0x0320f0096031589L,0x0383a15242a191eL, + 0x1fb2ae9abdc3487L,0x1bd3ba615173dbbL,0x1f503aca9975c64L, + 0x04ae47d06f2e17cL,0x1695839848f1977L,0x00f34648e1ef901L, + 0x0c94e8f6959d977L,0x1c7aaf0f5d6ff37L,0x0dee2739e9a48e1L, + 0x0df04249535cdbcL,0x03fe59c1e6c322aL,0x17e4c30781e6049L, + 0x1780173e413682fL,0x0c14225fc31114eL,0x00102c8e59a3ca3L } }, + /* 54 */ + { { 0x1003721275e0af4L,0x0a0f7f3c52525f1L,0x13db45d5d215c84L, + 0x0e2d1ccb3cccd9fL,0x0e2842ee5fa1d73L,0x05eafb131f1f2a0L, + 0x0412ab7b30f5252L,0x030033bc07a48d6L,0x1f8a9e903f343d8L, + 0x1abdd252d860698L,0x1b14194789d97f2L,0x0a3eca337ecf048L, + 0x00f2119a0180c57L,0x1c10ea7a2f82e10L,0x070e819f9921ee1L, + 0x0c0a44c5f29544cL,0x1ef56cfe4897214L,0x0288ccc2fd0ef82L }, + { 0x019497db18586c0L,0x00aeb637755312cL,0x1ada5f368a2c011L, + 0x10f8328b28f8d48L,0x0ed3a5069a149b2L,0x04a65a5ab1b4fd2L, + 0x1bb89c24aa9990fL,0x012ab79ce7553d3L,0x034bb2870778935L, + 0x17cafd80375a993L,0x140c8e58e3d2162L,0x04d0b74eb7f10f9L, + 0x1d9d42d58129376L,0x12e36b26f996b79L,0x137b506932b55d1L, + 0x140cf30bea1f765L,0x19acf34ce0e9006L,0x02cf57932ac52bfL } }, + /* 55 */ + { { 0x1407efb6ec3876fL,0x03091f87a43243dL,0x1bfefe24c0e5e03L, + 0x008b5235605576aL,0x18811b829592eaaL,0x0f9fe4e72dc26bbL, + 0x184ee1a9c68d07eL,0x10182ffbb0de1cfL,0x088ed8297655a08L, + 0x0eb6e3a40eaf333L,0x1277d8745c5e5ddL,0x191bc7ef3c3fdffL, + 0x1d2046192e36ad4L,0x13a7ed316d8a98bL,0x1766451e327e9e8L, + 0x12e3809d9249f05L,0x1fb059d1e383a64L,0x01da2287513105dL }, + { 0x1b7a955c776dcdbL,0x052be40e45d239eL,0x000d415d83ecd71L, + 0x03675d86a75c50aL,0x07117be5e3e8069L,0x1667b09c019adf2L, + 0x1e45b8711f8e815L,0x1c24a79fbd6672eL,0x03decdfbaf5cb7eL, + 0x1e4bca7be7a5b82L,0x05a0327fe0518bcL,0x1c237c7b553e480L, + 0x1769f91d8a4e440L,0x05af4e2ee2e821bL,0x0df4935041b1ea3L, + 0x169443232134267L,0x014e893c8383764L,0x0253ff1866214dbL } }, + /* 56 */ + { { 0x18f3a702455c7c5L,0x11b74380abbaa73L,0x1491d88c98b16ddL, + 0x1c378f018fe6588L,0x115ed8772c98b11L,0x0932fa6a4757564L, + 0x0803eec134f0066L,0x1d0d6a563379f4aL,0x1c46a098193ea3fL, + 0x016399edd3ac02cL,0x12ef58625aab336L,0x05f99d1d9aa3a64L, + 0x1d02fc44b3ac09aL,0x1550bc25a94c8c7L,0x0882173c311792aL, + 0x0fac26ac4c681fcL,0x12353cbb676c50cL,0x041fd0f51b28935L }, + { 0x0ac86da10ccc646L,0x031bfbd8228f4b0L,0x18c228221840b38L, + 0x12406933057779eL,0x1c0bcda023c1901L,0x0a7ebeb83fe1ce7L, + 0x0eeedfd347c546fL,0x0c1ad4c9ce888e2L,0x157bdc676c5ac9eL, + 0x0b629819bdb08b4L,0x144e5b73d028751L,0x184a932fa58fa68L, + 0x04c2c4a739f3edeL,0x1535697129a574dL,0x1a57e045004e5f9L, + 0x1f57e40ed3a9a47L,0x1e0cee007c6de98L,0x030a04bbcc98e28L } }, + /* 57 */ + { { 0x1db32db15156623L,0x1bfde55bd33e11eL,0x1d41bc678f09a04L, + 0x05132498c24c023L,0x06804c1c34218b0L,0x157353a4950587eL, + 0x0f987596f9c1abeL,0x0d27627a47c1a03L,0x144545b47f87f4cL, + 0x0111b71026e0d51L,0x149874f14587b35L,0x14c77b11780ec26L, + 0x161599d7201eb46L,0x14dd7879bc636c1L,0x01ca083da557f85L, + 0x068148cfdd7ac2eL,0x1882f1b8a2a3e3aL,0x031b6d63b1685afL }, + { 0x0280db9b4c80af3L,0x04e68a71c4955caL,0x0b83451df772686L, + 0x10d1f3e29e4dce0L,0x00baa0b2e91aee3L,0x18a51494327b1d4L, + 0x1f2dab3607dce2dL,0x1fa61c370e18bfcL,0x1883ea1c3b10837L, + 0x0d13ca9b590244fL,0x0ca9a1628b697cbL,0x17e40751f42875dL, + 0x15dc70b1c4e2330L,0x14cb3c7a5ae2445L,0x17d9d7029e31364L, + 0x1a6d04677a1304bL,0x13f37b5c0767b67L,0x017b6deff2685f7L } }, + /* 58 */ + { { 0x18472fd2e4da7c7L,0x07e48d733bc9917L,0x0228f709a389c23L, + 0x00f33448486c95eL,0x11d58bff0f10dfeL,0x04b17377c896ac3L, + 0x1a829afcd77f262L,0x1825172df52be8fL,0x0734a79eaaad308L, + 0x0b9819bcfa1bdddL,0x12f639b3d53dd65L,0x1b9fcec65dd8005L, + 0x0b5319310447606L,0x0567b94ea025af6L,0x177c7782b8225f0L, + 0x0e89112c5170c77L,0x14eeced154ef87dL,0x02e5b70cba2c6aeL }, + { 0x0cef197008c75edL,0x04e9f7b77557c4cL,0x180861d7a5b5f3dL, + 0x1dbb361b143adf3L,0x19576daafcec2cfL,0x13eddc1c530e7f5L, + 0x053d04000fce4daL,0x0a766f870d04770L,0x09fb66dcbb80e31L, + 0x13f175d02cc23d4L,0x118ff4d69c9dc27L,0x1b23f93c1da149dL, + 0x14d515baa4311f3L,0x10466a719e0ee04L,0x157baa9d681baf2L, + 0x0583f56c2e4705dL,0x0e52e82bbb0e1f5L,0x010a4eb1828baebL } }, + /* 59 */ + { { 0x01a8e6f5f9311f6L,0x11e4fdd5e0fc2f7L,0x14bad250826b25fL, + 0x1832ee9fc29f4f8L,0x0555844f04c2f51L,0x039d59ae77e8914L, + 0x067f2d4e18a8ed6L,0x134ed1dfbad97daL,0x0cdc12479ee5846L, + 0x091bf189ec0604eL,0x128a4301130a304L,0x02f57a8fc50fbaeL, + 0x08ad0ffeef9ee65L,0x00c6940fe121091L,0x1b0378509cc223eL, + 0x17ae7d78e897887L,0x06c5b26eccfb415L,0x00a7179a86583e1L }, + { 0x08d2a104216946bL,0x00f83bd25ec96aaL,0x028d0da54581ba0L, + 0x1ec7432f92b32daL,0x061f77c90f1b5c2L,0x1fbd913ced1e278L, + 0x048fc707358d24fL,0x078bcc36ca14468L,0x0826b34c5f28403L, + 0x0c5c8746179a10aL,0x0d5882ba01bb15cL,0x068bc64953694beL, + 0x1e8b53cb51a2faeL,0x1ccb2bbc4605dcaL,0x077bccb253dab0bL, + 0x11e4e0fd8c0fad7L,0x04f63bf1dbad0edL,0x02c29bf016e5b0fL } }, + /* 60 */ + { { 0x164b06464f80ba2L,0x02af382acd22d8fL,0x0cd3c7d2d8d3a38L, + 0x1fbd190905864c5L,0x030c780aef4f7d5L,0x10f349ceaaef506L, + 0x10d2c5d02bee73eL,0x1dc59fcd4cce8c1L,0x0f66959411187c1L, + 0x1c1793bafcba6caL,0x02b390011527ac4L,0x167f757bda04394L, + 0x064e3653eaf8244L,0x02ae2fc1e1b7a68L,0x1af3a43aae7c373L, + 0x0284bb27739df59L,0x10d16658e721906L,0x0242bc1afc16bcbL }, + { 0x0d525bcd2576210L,0x1c553ea8daa21eeL,0x1c5c6f60e6527cdL, + 0x07e7158c43fd2f7L,0x018408cc930d0f6L,0x07a9fb57c7960bcL, + 0x1d7909a4b21f898L,0x06e1dc8a80fb614L,0x10ec47ae5ffdb1bL, + 0x14894ee3d535225L,0x04cac8b902dd75dL,0x09a12bde76ef6dfL, + 0x1568bc63e8e0676L,0x0e000a60147ea3fL,0x065763b46041252L, + 0x10b5f21c5a7fbafL,0x128eb39a05d6c2aL,0x036013bded10f98L } }, + /* 61 */ + { { 0x01b7086b509e7efL,0x1763d9ebfcfc8f2L,0x1e51549ae22e210L, + 0x080a3ba1579a50bL,0x174f1ceb6e44e06L,0x1f330dc80cc6083L, + 0x11f65bb2afa6048L,0x1dc8902226c65ecL,0x11dd82b4526c52aL, + 0x128483fc9cee4eaL,0x1bbbcbf35156ff5L,0x09bb1a5cbaf97abL, + 0x1288bc9f2a7815aL,0x0bd1d9912d6a764L,0x0e72f6f1bc4342dL, + 0x09dd1d1a183ce41L,0x18f5a0b071a9b77L,0x01833de4d7917e7L }, + { 0x0e589f2b7ca9326L,0x0837ed89127b1f0L,0x1485d1e95ef45e8L, + 0x1ac561105d646a8L,0x0391ffcf2614982L,0x072206bf9d7aa22L, + 0x0c1c46aa8cdeea1L,0x0a851d46f612837L,0x1a957dcb42e4a7fL, + 0x1d5b3160d356afdL,0x178e07df0da8839L,0x1019375416d7a26L, + 0x0c94e4671f42e79L,0x05849171a11b818L,0x169627c93318ffeL, + 0x1fed9a21aa4f288L,0x195bb99d316a870L,0x01c8641e554cb60L } }, + /* 62 */ + { { 0x0d3fa82ffc4a73fL,0x0eb1a9dea9981a8L,0x1e28992eddf4999L, + 0x1c45ae7b090140dL,0x0323b8aa81c04a6L,0x0626ad1204e7fa8L, + 0x07064c773885e31L,0x1706e95501c181fL,0x10b25a38700186bL, + 0x05bbd085578a43fL,0x0e6b56ad2637874L,0x1b4c3541822c2beL, + 0x1d96e25ce892e32L,0x0f43236891471edL,0x1ec71a2d5f22371L, + 0x1bd8ace5622c84cL,0x13a5d0d807f600bL,0x01f52003e911f2bL }, + { 0x16debd0a595d0a3L,0x0bb65d7f859da6bL,0x153e6c6f6e5e9afL, + 0x0898e298e37e582L,0x021af66362b19abL,0x0a0f7b64df99dc9L, + 0x03db48f61f12632L,0x1824ab00987af3eL,0x16f1a10052a7acbL, + 0x0d5bcecaa829457L,0x1e9bc32345884d7L,0x16dbbcbc2053faeL, + 0x12f95da12b40508L,0x1ac545d0ecad607L,0x18323ee2182bdc5L, + 0x09a6816329906e2L,0x0a0a40e6c80ce00L,0x004fc150bb58a55L } }, + /* 63 */ + { { 0x0abe588c21366dcL,0x00527d7baed7cb0L,0x1f66b2e4fb51ca7L, + 0x1d0f42dae0e0a03L,0x18e7361bb97e744L,0x1aa679d217053d4L, + 0x041e06b36bfc8a2L,0x1cfe10f99776f7bL,0x1da6f3983663250L, + 0x16b49f75d783e04L,0x0bd30e32ebc55d9L,0x1c0fbf9533a0f37L, + 0x07f26d8dab5a984L,0x1f5d1b7cd5a6992L,0x0374859342f9c05L, + 0x09e066f773cca1dL,0x05a72aa4e24531cL,0x03be8f4c25ba9ecL }, + { 0x1373239d8e62367L,0x0c245dcc10678ecL,0x0d116a725f10cd8L, + 0x1c29f2c1f8018fcL,0x140474b59a0ec9aL,0x1032eae7a0f867bL, + 0x0184297bb7a3fb3L,0x0bb63bcb49d3d01L,0x117c44ae4ae0cf7L, + 0x1d2b191b58a4685L,0x09d03f4a7fcb70bL,0x17151196425cc9fL, + 0x0d6a863016c605eL,0x103da60bf963b8dL,0x1525e15b5844b9dL, + 0x1c1cbfd21d80e81L,0x1b0599be18be256L,0x0273755f6652a56L } }, + /* 64 */ + { { 0x10323d3fb99cfe6L,0x0de136499a0bc4aL,0x1905f2f7edbdec2L, + 0x09134eaec0c8223L,0x10919cb09114174L,0x15fe97a6319efc8L, + 0x18b6dc57f1f1ce5L,0x15919432a251956L,0x0306724734db81aL, + 0x13d1235da6262a5L,0x1a83eafc8a591b9L,0x0be3f4b6bae1aefL, + 0x05c2f192f35bed1L,0x1fb34856d2b436dL,0x0942df77b2b1ca9L, + 0x15a5e1895e54595L,0x056f44631c16049L,0x0192e93cb027678L }, + { 0x011fb554848c144L,0x11492db53d79977L,0x0384da783e69381L, + 0x0d94a7643c24b6dL,0x0e98ea1bad9bdaeL,0x17d1cafa86b02e1L, + 0x0cbd6f6e7854e7cL,0x1ae8ae1c65bd22aL,0x1810698ae46a250L, + 0x1ecaa3656cec8a2L,0x19dc8447a5e979fL,0x0faa493f05d357eL, + 0x099851df63ca29fL,0x18e871f2d4e29cdL,0x074ad5bf613552dL, + 0x012d5a3c08b3808L,0x1d3ceb3eb6efd80L,0x00cea42a371953cL } }, + /* 65 */ + { { 0x019ee8fb540f5e5L,0x152978273468bffL,0x16c2b6f721c61b4L, + 0x11a074ff91a4641L,0x08bcb916a83ad5aL,0x08f4202a5fc1e38L, + 0x1777c2484cfa8b9L,0x10779c7084996a5L,0x0d5c7be40310635L, + 0x0f5dcefa2c718bbL,0x0658e6f136aeff0L,0x1fc980ae4b515f6L, + 0x1484e1cd2436350L,0x00a2dc6f5625031L,0x120c8deb7dcc553L, + 0x04e40154dbb3d66L,0x1b0a3345c3dcbffL,0x00d9d67365a7229L }, + { 0x143e5e990a8bdc5L,0x1dfceb183504481L,0x08d63921483a880L, + 0x1dbcfa3a0d30913L,0x1f795d3fbd17debL,0x1d851fc7d7d36baL, + 0x1abea933ad8c0e1L,0x005c02cd665ffbbL,0x0a2fe20547e764eL, + 0x0d5cc127438f982L,0x14daee54bb11795L,0x0909521a4195457L, + 0x0775bcfb537b4c1L,0x14c16272a98cf9cL,0x00a4874d08e2929L, + 0x162fd4576c38f42L,0x0141e061b64db3aL,0x029c7619f0c9785L } }, + /* 66 */ + { { 0x13496fea19b56cfL,0x0bbfa3ddccd668cL,0x1ea15f42a20598fL, + 0x0410506bfb1e095L,0x1d82cec7cced3daL,0x004e42bf10fd76aL, + 0x08c1db85d6e67e0L,0x105b38dc6365a0bL,0x196948d4a81487dL, + 0x175e9f96a37b32aL,0x146aa1dcf331261L,0x1e45162c814d0d0L, + 0x0841a20b753e220L,0x08560537cf8371dL,0x0facfecb3fff97aL, + 0x1c593eb5363b51dL,0x0012587d9976e08L,0x037eb014c01f4faL }, + { 0x0709f8d8eb7516aL,0x0c53a5ee2cc55aaL,0x16621fa0073a0c1L, + 0x01a2f7152da469bL,0x0e90f6abfd0f9d9L,0x1f6aadd50f2a4fbL, + 0x13064925bfe0169L,0x0ea1b3ecaf4d84aL,0x03cdea49cb89625L, + 0x142d1f816ff93efL,0x039ff76e2f012edL,0x01ff30e46d6078aL, + 0x1dbb0d5055904ffL,0x10a5f46824a14c7L,0x0f4c358d2cce1b7L, + 0x1fbb2f5a69d38f8L,0x1c01f2b32bde159L,0x04267d11e63b0f2L } }, + /* 67 */ + { { 0x1bc11eb8b99b964L,0x006052c717e2389L,0x11275326952e38aL, + 0x057edc41f50e1f7L,0x17c88cfa37a334aL,0x0578ed772c1e86eL, + 0x1e2981780a6a3bdL,0x0c4daabc468185dL,0x161b6fdfe209e9bL, + 0x18ed6935dc70407L,0x0f058a4e4bf068eL,0x1fcc155c7e9cb5bL, + 0x1ac2bf4d5b02ac0L,0x01417f6946ccc00L,0x0b6ccfc8ccfe4ffL, + 0x0a5ce2db962196aL,0x18e09f90f84c557L,0x0143ea628e42506L }, + { 0x1a582010e9867daL,0x0c4d98d43a66d2fL,0x1f17ef7b88b9851L, + 0x0bcc257b5000bc4L,0x0d3635f9e357fefL,0x092d432706df6f9L, + 0x08b958af9c391bcL,0x1a3413731081b29L,0x17eb99a1528b5e5L, + 0x0dca0b73a88145aL,0x0dff5f81b4b3108L,0x0a2ffd41308a362L, + 0x06ffcecbd76fa1fL,0x0197a29f1dd0f4bL,0x09a3e875322692aL, + 0x12b460f63c55fd9L,0x013d0fb44534bd3L,0x0009951ee6c77cfL } }, + /* 68 */ + { { 0x13c7785576374c2L,0x09368c239382072L,0x17208a328113981L, + 0x05e39c2627140cdL,0x0deb0c5d1fe1c1bL,0x1fc137957764196L, + 0x096269d659a6672L,0x0a99a311d03bcefL,0x0e5ce0fe0118d12L, + 0x0a154c203c85c35L,0x1c10fce6b0a33a8L,0x05210fbcb009c51L, + 0x12f639a8c54eef8L,0x0c43bca7c1e18d9L,0x0c6ce475c11529dL, + 0x18f2b94c6baa031L,0x025cefea07631d9L,0x009e5f73b5b7c55L }, + { 0x1cabe0f8d3f34f3L,0x0e18e51b0bff1bcL,0x188f76509a86f6aL, + 0x0fe539220964dbdL,0x02c6cd3be9dd962L,0x1d10cb019f58b4fL, + 0x120f229cfd24bf2L,0x16f25c6fc1770b1L,0x0e4f2aca623b3fbL, + 0x080fd8f325f0051L,0x1e09aa523d91220L,0x0f6920e4c1cf234L, + 0x10e30bb83541406L,0x04cce0377bba552L,0x0821447e48b2a03L, + 0x009e0d70c6b7217L,0x167bf936b5c25faL,0x027050d6d701744L } }, + /* 69 */ + { { 0x0ca66708ba29c4dL,0x12067114c404a00L,0x099c5b769d4b020L, + 0x0b5777f468438b9L,0x1ed28b72689c0e4L,0x02b55a0ebaa2fe9L, + 0x075957c8846635fL,0x112967b1ee870ebL,0x093490dfb8fe50bL, + 0x120faebf4075d0bL,0x1697ade6b2d4dedL,0x092e183abcbcf61L, + 0x0da5da429aab6b1L,0x17b69792919c734L,0x0c3ce9f804310dcL, + 0x0117844de2da4caL,0x199efb0f7b6cbefL,0x0399f186ccfcce4L }, + { 0x0fe1582a42a38f9L,0x16ac723985a8076L,0x0a9f7a5dacb2bb0L, + 0x0b52d383765dc5eL,0x1cecdb4af0539dbL,0x14748118caa0b47L, + 0x1507fcbdcd22b9eL,0x0a43ab1af986242L,0x15d25b75c2202aeL, + 0x154cb2d7a041ad3L,0x0da9054a6d391b7L,0x16df7a4f5b367fdL, + 0x00261f900b5c97fL,0x026ad8cf6c3aaa6L,0x0866e72d0c0c764L, + 0x0179e67abd37196L,0x00c7a43d4923ee0L,0x02b7d659cdbcd2eL } }, + /* 70 */ + { { 0x19165a2a3018bfaL,0x035924ffd6cc200L,0x07d954d06a6c403L, + 0x0e4bb8999377e36L,0x0bfffe60e6bd1d9L,0x0a84d5a942876a9L, + 0x167c493a64b31f9L,0x091fed8a05c99d6L,0x02f0b35731aa7d1L, + 0x0860eeef3f1d523L,0x127d174450a203aL,0x1a4ccb7cbbab75dL, + 0x0e1febce13475cfL,0x004a169841d5d8aL,0x1fa0b21aae920a6L, + 0x0431a3c3646ba52L,0x0bbb771cdbe50d8L,0x0442cc9336ca6b6L }, + { 0x0847290155ccaf2L,0x0f5e3be2dbb9f04L,0x1746cb7423b619eL, + 0x1d0fa8ebb751165L,0x0694d02a960a180L,0x1fcf4b407edb5bbL, + 0x0db10fa1d6324fcL,0x0fb7b47edf495b0L,0x19400c58132fb38L, + 0x0d3c2a112a81007L,0x1f0d45ddbb3c609L,0x08dcacdb6b34552L, + 0x0026545eda03ebfL,0x07ba55a223a1d14L,0x12cfda7b45a7613L, + 0x0e32d7557263b11L,0x11970ae932cd825L,0x03cb9125350604bL } }, + /* 71 */ + { { 0x12923f8441f3567L,0x018b417125f8eb1L,0x09aedd9c7fff047L, + 0x0ef4bc3444972eeL,0x1addb417601746aL,0x0cdc2329eeef501L, + 0x1ffdd5e19e8f1fdL,0x1516025530ead9aL,0x01bd5fec9f19ba9L, + 0x081bcd17c1833a4L,0x0d1176ae301745dL,0x0836f207e854eecL, + 0x0da903e46d5d7f4L,0x16e89360e008b3aL,0x1156d006c74f136L, + 0x06add44ea5558c2L,0x12c4da42a68555cL,0x01ff84e0aec1042L }, + { 0x00a1bcef9cb7784L,0x09cde12117982a6L,0x07f431052a9ebb1L, + 0x19ffa85788be81fL,0x0f358e15d3aa316L,0x113b41217ad2619L, + 0x1b3b802f7367b5bL,0x0ba0d3ef13ff14bL,0x18078018e05e14fL, + 0x1d9f249c5a063a0L,0x123075e45fdcb4aL,0x0cc998ae2a18bb7L, + 0x1ac3fa8920e0eeaL,0x0e3cb8b2512f662L,0x12b45acf086c3d4L, + 0x03b351e1345e4c6L,0x04c8e730fc55839L,0x023f78c02a7efd7L } }, + /* 72 */ + { { 0x165f3d13da285e4L,0x0a6dd1d00f1fa4cL,0x04e984852b42e9fL, + 0x0a4472ea928e708L,0x1a730b92d3b7d53L,0x168b2ed29edee7aL, + 0x1fbd0c4c364acccL,0x16c89450a8305f2L,0x1bf62221c44dce1L, + 0x1d09c2c3f150764L,0x0cb2372feb6662eL,0x1e7f6bfda89667eL, + 0x05c66217bb409e5L,0x1e6fb8d4ae19463L,0x0481e22c036da7fL, + 0x08c974478544371L,0x061f8ab28e63ae6L,0x00d35b74e5c6f04L }, + { 0x16ec2b606af77aaL,0x07ae6d443f832d7L,0x10027d263158b98L, + 0x13f9755e970fa42L,0x071ab855db595b5L,0x1a4d8607dac9509L, + 0x032728338439750L,0x1b73ac30fb110fbL,0x103ee95f9154bd6L, + 0x1f29909ae8364ccL,0x1ef0c3eda993423L,0x1e1acd4996c1e94L, + 0x0f5d37367c3d22aL,0x0cbec72a8b4a967L,0x05ccb41bc3a9cd2L, + 0x07285688f8e1ee6L,0x1d000ab3034a9cbL,0x03cee80c0142887L } }, + /* 73 */ + { { 0x0e0033a3ac7424eL,0x15b44307ed26802L,0x1d9af2ddcbef6c1L, + 0x17e52f9b4846d52L,0x1b013c6e294a8e2L,0x11d1d6a58555c2eL, + 0x129acf4abb2621cL,0x13c195c659a2790L,0x021888f5e70ec16L, + 0x1cb19dea1544131L,0x11e4b9ed8366e1cL,0x0e4420ed3fc2d15L, + 0x06d24bed3489f2bL,0x11f59255479fe7fL,0x131c1af4d7bee22L, + 0x19c1bbbd9f47e90L,0x0367cc119a9929eL,0x043f2d6a2c6a02aL }, + { 0x099aa9d7d1000a7L,0x057fe57411c19ddL,0x18a37ee0f7162e5L, + 0x0308b4831b90452L,0x1d4170542f59fe1L,0x1b8ac0d45cb87c2L, + 0x1745e24630995caL,0x181c9de8efb81a3L,0x1b50b4cf33afad7L, + 0x0dd753c80c3852dL,0x021fe6ece8a1a08L,0x063c2494b39b8eeL, + 0x0f57f4323978575L,0x00b264a576ba613L,0x052fdd357d6b894L, + 0x1d464cc116fc5e1L,0x045f4cdb5bafdceL,0x005b8928ccc8660L } }, + /* 74 */ + { { 0x0290ca188d5c64dL,0x16ba4d3a4929a2dL,0x14f4a803a494165L, + 0x1995ef6cd740961L,0x0cdded83082cd02L,0x18b2374895a8617L, + 0x1fe5604f3a77bfcL,0x02ac55ce18f8ebfL,0x16f6852e07e2a46L, + 0x107ebe801c027e8L,0x0a93760863a364cL,0x0df75f8c8baf634L, + 0x01e8d9fdbe4918aL,0x02385b777d8407dL,0x05d3bdccf534229L, + 0x1cba5a57440eedbL,0x16d8ecb95a769daL,0x03d1fa11d3eb4acL }, + { 0x02d2ca69a929387L,0x1bac0e58e0fff9bL,0x127df946db2eaf6L, + 0x04749c263fb125dL,0x1bd87561ee8d863L,0x13f399234071f8aL, + 0x1fbfb8e965f8753L,0x016798e56f8ab03L,0x1f3e77f8aca8caeL, + 0x063ebee2f17ea57L,0x09154884d56de7fL,0x09e54580e2efba7L, + 0x0d0689621f546b2L,0x1fbc0b1f20ada99L,0x15fb484afa6bd44L, + 0x052864fac773667L,0x0f4ab019ef29680L,0x016d2fe2a8b11fdL } }, + /* 75 */ + { { 0x0429cf3c8a5c600L,0x006111ff19f3e31L,0x1d00295f772e9eaL, + 0x1b24b618e93ffb4L,0x0b100eb0d1ae156L,0x0a1e4084bd21fcbL, + 0x13c905a7a5173beL,0x06743ee69ca2251L,0x004387c4a419f01L, + 0x003c34580822012L,0x05aafe40d673cb0L,0x1fdc8f1aa9c7ca8L, + 0x0642a2173ef9c76L,0x0ff180a0b310cedL,0x1bc91f98780c55aL, + 0x0cb2541feb9c727L,0x0d3811792ba072bL,0x042af810cb8642aL }, + { 0x1fbfb6c847314c4L,0x030aaf5a2dcb530L,0x0519ae8abeb25e4L, + 0x0b57292f02e205cL,0x0110c4feed51f97L,0x1abb33ce97ad8beL, + 0x1139deb2339c2bfL,0x18fce6cd442dd64L,0x0dd1bbcec551c65L, + 0x092830570d42cefL,0x1205d22e9f4b9edL,0x0a83571d5188f40L, + 0x036fdff078e1a2cL,0x0a43a582373c126L,0x0c7dccde6d27f1cL, + 0x1cd9e455c66fe0dL,0x1971c3521926f8fL,0x014911b67a92e83L } }, + /* 76 */ + { { 0x1b8d80a7d8b29dcL,0x110120475324566L,0x117aba4afa4745eL, + 0x11fb4e5f78fb625L,0x1e760c6f1f347d1L,0x11c6c8889ba5a04L, + 0x107d1cd87a3c763L,0x09cee297d3ae735L,0x1c1f9701cb4df5cL, + 0x089c76c37b96570L,0x1f87ddab4603136L,0x0b7d3c5b7f3838fL, + 0x097c70c44df8c18L,0x1868adafc1aed93L,0x199517be65f3faaL, + 0x09cbca20288b4c3L,0x1aa16b068842518L,0x03e7d61acba90f3L }, + { 0x11821673c0bc53aL,0x0f6f1bf3a89b3c0L,0x17f68d95e86212dL, + 0x09743fbb307944aL,0x05da77d8096abbfL,0x19a162ce741b4feL, + 0x167c7c9ee6b9eaaL,0x1d20d9237ad2e40L,0x0ee0dab30914ecfL, + 0x1b23fddc9fa9f89L,0x0e29ebfe95f83aeL,0x0ddf3e55ac0e618L, + 0x07bb99dcc9517d0L,0x02304050a4b946cL,0x0e705f6c00d2bc5L, + 0x045419902187e25L,0x0bd7225f14f772aL,0x03671ee3f8eefc1L } }, + /* 77 */ + { { 0x07cd835a4397830L,0x094867a39998360L,0x0ea0a6627a31376L, + 0x12ac7b02a5ba6baL,0x087de61b7990255L,0x1271ae793c6c88fL, + 0x0396671cd031c40L,0x1425a8888c2941aL,0x163e7608ff32626L, + 0x13d1bf4e264dd54L,0x1b7145dbfff4958L,0x1f919de5439a18aL, + 0x16efc559d9cb6deL,0x020e5b4965e606aL,0x0587827917cff14L, + 0x0ab399a0b8473caL,0x16d2a731ee95c3bL,0x0428a889151e850L }, + { 0x02d033586ff19e2L,0x106d50ed14301bcL,0x13f955f1fbb70b1L, + 0x083789d16165cf1L,0x1df35c67a8f6f98L,0x122315660fcda59L, + 0x182c25b84d80d1dL,0x0ad7f22172ef8f5L,0x127c7f305514359L, + 0x0a6d8ae7b18f572L,0x158509f9a6cd330L,0x10a2bf825fe54a3L, + 0x13fb887162dec82L,0x0f0a445efe67570L,0x18f9d3368ccab07L, + 0x00d394406e9c45dL,0x004597ea1a1f0aeL,0x04588acf93bdef6L } }, + /* 78 */ + { { 0x0f71a442f961d30L,0x0b4543d639247a5L,0x01f2c6a41b36f7eL, + 0x0c0957f24ba65bfL,0x19f04d4c00c10e2L,0x0b82ed5c388bacdL, + 0x02124035539824eL,0x0ebeeb0e86793f0L,0x02e9abade6a7a23L, + 0x13b6a3c4a560bd6L,0x01496f080b66715L,0x195b57f5ce7a994L, + 0x183405991b95b8bL,0x02c54ce191b8f69L,0x1e32198ada791e9L, + 0x058f8f958163056L,0x0596ceaa79be023L,0x005ec3219ac47baL }, + { 0x0a1a8b47e734189L,0x0d64467f2fd0befL,0x1538450dd9914b1L, + 0x115f3d2ea088949L,0x130c6b3bc252230L,0x16fa3bbc58e861eL, + 0x0375cbb6b97c131L,0x068a6263b345dd1L,0x0c4e380eeacc93eL, + 0x04cd8d6546d8747L,0x123059fd75275f5L,0x04ae2aad99aeee6L, + 0x0c2611d13dc9663L,0x1ad17ee632e7074L,0x163ea84b257f99aL, + 0x059304cd310650cL,0x107da87d1f431c3L,0x0233282cc7e6c8cL } }, + /* 79 */ + { { 0x06c13cc6b4a5efaL,0x0cc4d8e83d932a6L,0x1b3a2f71a703120L, + 0x04584a63a82172cL,0x0ad0a100f54cfaaL,0x0ed224e5af8c046L, + 0x00f32fad494e3b9L,0x0f14c48010b7dbbL,0x1e792dacfd6255cL, + 0x01b8c83103102c7L,0x057a0fb45963062L,0x164efa51aa852ccL, + 0x1b83b75df34b549L,0x0bfddca1757893eL,0x1df24c13d837db4L, + 0x0f13fa10c63b7edL,0x00c17c38f986018L,0x00621aba55cd494L }, + { 0x0eb324c1d20cad0L,0x16584c63088453bL,0x0e71bc1b4db6437L, + 0x15781b432f4dd3aL,0x107ac5ce6cd978bL,0x04bf5aaca458e02L, + 0x0538caf51c59315L,0x0785538981e9ab2L,0x0772c5046a759f0L, + 0x1eb994534d6423fL,0x15f430c122ccc39L,0x09c081ef759d51aL, + 0x13a85f1790e6003L,0x0e42cb9b411ec8cL,0x078408a9ba6d9b1L, + 0x07f48459458f4cfL,0x1b900e7a19c0902L,0x01924ccf893936aL } }, + /* 80 */ + { { 0x07eaed67c834915L,0x1d5355e2f5b26b3L,0x12d8975880467ddL, + 0x04d33fb384e53d7L,0x0b8d4f6c0aee24fL,0x04bb6b70f5ac3a1L, + 0x1a995fc49c43053L,0x0c92272066bedb3L,0x1668b704906b500L, + 0x0cb4d07043b7727L,0x06fcfcbe764d819L,0x0ca36933c79df20L, + 0x1bf2dbcaaafb1a8L,0x0b9d835b405ca9fL,0x1cdb190c4b3159aL, + 0x1b02a6a69b38675L,0x191e4463a5210ffL,0x02bf515a5f8c615L }, + { 0x0f5e1628aa0f2f2L,0x13ae287235e5500L,0x1e6a928b10b631fL, + 0x14297544052f568L,0x0943cc2eb4f308eL,0x0ac4025480de8a3L, + 0x03df2ec497fbbbbL,0x038ca0591f33a30L,0x1e53539191580c6L, + 0x113c03493880f71L,0x090287ea9c9c5dfL,0x1c0498eb62a6f41L, + 0x0b538f1c2232edcL,0x1f183e976d11b30L,0x0bb82d135447a62L, + 0x1e60e484edc8137L,0x1c9a78c39277ff1L,0x0302405a3753c9aL } }, + /* 81 */ + { { 0x1087d663872ece3L,0x0df3ecaadb87c18L,0x1f1e73e56ee17caL, + 0x1bb7ff4c436a169L,0x0022ba5dbae3b58L,0x00a24e0730e9407L, + 0x15215e2b9445d06L,0x01c162650819eaaL,0x1800ed1b6b8ce0bL, + 0x0effeeabc6aef1eL,0x108dd1a695ad1cdL,0x06d31b2215cfefcL, + 0x006313c7c7d5e32L,0x1496f4f2db7fa95L,0x08442ed68bf8836L, + 0x0de4683668fa7a2L,0x0ccc5905edb40c1L,0x003ba5069cd47c4L }, + { 0x0e181abe3b6c106L,0x10b1fc6f0a85b9dL,0x00bdbcd520d93afL, + 0x06758f582d9eeb7L,0x091722afaa0d206L,0x0a2aa9ae3403341L, + 0x18fddce50798445L,0x1b42e24fc717ebbL,0x132cfdf031afb41L, + 0x1449e48c3de4331L,0x119d1298b272671L,0x1c5b2c58328eea0L, + 0x1f378cdf4c96866L,0x1a03fd19244f646L,0x04a4344e981c26cL, + 0x044e7a6fa42b2aaL,0x14b9623d303bab9L,0x0040a8caa121900L } }, + /* 82 */ + { { 0x1236d89fb7b2108L,0x041e656bafcd57cL,0x0c56d3876844fb3L, + 0x1e062b86c5ef8e5L,0x1272fe3f552aeaeL,0x021f7408f0a076fL, + 0x0c96e675e6fda1eL,0x0e99cd6a9fa3b37L,0x1b20b0e215b1badL, + 0x05010a7adc26486L,0x0efd4bf29b3b255L,0x091b3c9beede8b3L, + 0x0ed64cf17ee363cL,0x1b156d241822fc2L,0x1d32806100a859fL, + 0x1885a593c37e6d4L,0x074e8cf9d41f691L,0x02d5f90bc61625cL }, + { 0x177966bf3b3bccdL,0x1f0785f1f065523L,0x0ece31f5410c011L, + 0x1f28dfabf997070L,0x09ec0e87e77e3baL,0x10c692bcdd53c2fL, + 0x1f3fb60f155f322L,0x0c3372dcb5e4b7dL,0x14f05d15e98c71bL, + 0x00fcc8d3bf316d0L,0x1b1e072ea8e0842L,0x0cbbca9b37f638dL, + 0x1344ed14307522fL,0x0ae57eed7ae82abL,0x1e3d6fcc0d6cc7eL, + 0x173b28fccfe86c6L,0x048029f7cad5270L,0x00ad68ac3a6c8b5L } }, + /* 83 */ + { { 0x0de2eceaa588ae4L,0x15e2c51b8d11900L,0x04d1c48c111154bL, + 0x1bc963065ba01d5L,0x1689e843afbfa67L,0x1a71741490b1a0dL, + 0x077147e5aeef587L,0x1a32a840d080985L,0x0c7fe382742317fL, + 0x050576331a418b1L,0x0e53441c00613f8L,0x12e7fc3f7b0bf85L, + 0x11fb07435207219L,0x023729c93245b55L,0x1e95bfc8eef6ab7L, + 0x04bec1b71ba3e01L,0x163104815eb8667L,0x01fce266529740cL }, + { 0x136b29732ce637eL,0x0af96fae92e6effL,0x14b62c0ab65e068L, + 0x199f7567d2343a0L,0x014eeb752e5f3bbL,0x0d3c9d306965ebbL, + 0x085135124610f35L,0x0cc44859eeb9b74L,0x0a20705e788b997L, + 0x0709660763bf099L,0x0537dad86a6c159L,0x1e08e904b6b5638L, + 0x013da312238fd97L,0x06986386cab0241L,0x04bb9a779219c9dL, + 0x1127b79571e2a38L,0x14b5dc638b4668dL,0x0323ced6b111fabL } }, + /* 84 */ + { { 0x09044f3b05f2b26L,0x114a5405cfbb62bL,0x18a10a43dabacd6L, + 0x0604d4b0ef1073fL,0x0e5ff9c3761cfb2L,0x08e2bb3b44935b1L, + 0x0fbfaeb9b34802cL,0x075b90aeeace540L,0x00cae074ae1bad6L, + 0x1f248d0eb84ecceL,0x177b5994076704fL,0x19438655dfeeed8L, + 0x15c57683e81da6eL,0x0fcc6c23a8424eaL,0x166959278e4ba73L, + 0x13165f5af305ec9L,0x097f7c3bdb7a37bL,0x00ff04fca784302L }, + { 0x1a7eaae7648cc63L,0x11288b3e7d38a24L,0x08f194fd15644faL, + 0x170342dd0df9172L,0x1c864674d957619L,0x0b2ccd063f40259L, + 0x08ca3f2204d2858L,0x13c6cdd52d214caL,0x1415329604bc902L, + 0x1cf0cca57155695L,0x0a3149fc42fbd7bL,0x0b0d8cf7f0c13c5L, + 0x1a844cc25d73dcbL,0x1a759b29fb0d21fL,0x0903c0b5d39fba9L, + 0x17969e66ace0dbaL,0x06aeec7694cfd83L,0x026f4abc36db129L } }, + /* 85 */ + { { 0x067d3153deac2f7L,0x03bc55b0ecd4724L,0x1e582adecb56821L, + 0x0d9fbe9ef3e76edL,0x11ab8f4b00b3005L,0x1bce80e8380f0a9L, + 0x14dc41fe5235671L,0x180f9329d7904ceL,0x01104d4ee48bad4L, + 0x0c6705adfe4e82cL,0x0a2634c27ea02deL,0x044b59667d5f8f9L, + 0x1c5b2f31750244fL,0x126bdf1a6a8f46fL,0x080ad0cf926e9aeL, + 0x04eb42ec1e98f7bL,0x00c37e36a7e4435L,0x00e4a20c5f31b4cL }, + { 0x1a2131309dc1414L,0x1b2fe21e49a9ba1L,0x01eb7d7de738181L, + 0x150ba99f94dfe64L,0x03e995ab6f18b1fL,0x1598017ae213973L, + 0x1fc5848682792a0L,0x04d056cba372e28L,0x04993c20c20a7feL, + 0x0e4e5cc7338b393L,0x0b59cffad102826L,0x13c24a36978ab40L, + 0x14a05338ea3f3faL,0x1d84fb65baede23L,0x10d1824f2d0112dL, + 0x1d584cecfb43100L,0x1ba97851422098cL,0x0308dfdd95aa91aL } }, + /* 86 */ + { { 0x1baa55ef00ad2a1L,0x1d42f0a51486bdeL,0x1da3a4ac5a50a7bL, + 0x1a23d9026076948L,0x08bd27b267111bcL,0x101e0307212b814L, + 0x0212bca33ca8f66L,0x04176f91a5be631L,0x1e2ea1462e3aaebL, + 0x1a9ac0221dc2ebbL,0x191209553ba6f4cL,0x1d3dcd54331f03dL, + 0x04c26c5944eb2eeL,0x01558b3e3d2d540L,0x1f8869683bcb696L, + 0x0531cb45568ec05L,0x08d169cb3b83370L,0x0437362a20759d5L }, + { 0x1e033210b793d9bL,0x1d6f08eedaf6776L,0x0a49a24c2d93de7L, + 0x1bfc9fa365ee7fbL,0x12a4dc8806aad97L,0x0bb6ba839d2d8ecL, + 0x09b022be32f62f2L,0x00cc1695762c79cL,0x19c8300a9dcb1fbL, + 0x1ad2ca66d4ad9e9L,0x1f5f52cdfab21ccL,0x174441ddf5563f2L, + 0x06f3e828c8a3d2eL,0x02d5bbc0992c648L,0x0a2d85f20c985beL, + 0x1705ae4b2e32518L,0x06dcd7196bc3233L,0x041c33f5c8cfd09L } }, + /* 87 */ + { { 0x14fe73e22474edbL,0x131ca0d4270d73bL,0x06b671b75b8ca9dL, + 0x0a29f17eba4e065L,0x12267b9000c4a41L,0x0927d71e71751beL, + 0x06de049d4c05447L,0x00cf829b0a84c74L,0x020c8401b1ae0b2L, + 0x195008d840fa4feL,0x048fee5671b7e3cL,0x18f9001c3a0c3d0L, + 0x1824259a9aa328dL,0x1bf7b61bac3b51bL,0x0f5327c8eb6a2d6L, + 0x0713e047ed6dd52L,0x19e89f5414dffb6L,0x025935dd1731459L }, + { 0x10b1cb45d318454L,0x1ba4feba1b65b69L,0x1c995a29d18448eL, + 0x063909fa3c62218L,0x08403d55c85de12L,0x0fd5fc52fc6b730L, + 0x17380e56db84e6cL,0x021fcdad18679fdL,0x11d90381f94b911L, + 0x054754096e6375bL,0x00104dfa4328afcL,0x180f9144b8b4b3dL, + 0x1a5d84663cbeb5fL,0x0885b53e004e129L,0x023e35402c541ceL, + 0x03ccb0c0fb49882L,0x1c602c3d9c3cb90L,0x026b4bde2964b0aL } }, + /* 88 */ + { { 0x0db1ef0efa8fb40L,0x10e2dadd1cc4e70L,0x0c560274677ca40L, + 0x06982433c351adfL,0x14ef05e26b787b7L,0x0bcb71320bf0b40L, + 0x1086d124d0b6e3eL,0x06c5f0f14bd7f08L,0x1e71916d7e94a45L, + 0x00c5dd1d708cb49L,0x1d2fa55da2013a6L,0x0e99f0849f15d8cL, + 0x1d466ce6ab0a260L,0x049003c5ede49dcL,0x1c3c68ecfc56a63L, + 0x10b4f3a21fa1a70L,0x180a61241d9e4e7L,0x03b6543d0f36466L }, + { 0x157fb56e02e48b7L,0x0a589e604f4e321L,0x10d4901a73c3ef4L, + 0x1858760353b6be4L,0x06956dadf878165L,0x0b05b472a4f3e27L, + 0x1194fcbfa54e2efL,0x1372a5f0ad60b3bL,0x0d3f60225b377feL, + 0x10639945ff48462L,0x0a8b4ef23d7cb5aL,0x08864884a0a19cdL, + 0x0a3d3b3ce5f7213L,0x00b3ba890bf0933L,0x1ee2529d6d790ffL, + 0x1c6ea2b24e0c46fL,0x1be152607532be3L,0x013f3f96336d1dbL } }, + /* 89 */ + { { 0x18f65ade6a15883L,0x1f3463357ed99b1L,0x1aaf4fc4b797529L, + 0x006f70f020c40f6L,0x04acf6d31c6ff95L,0x1f3c61606a26593L, + 0x0603858eb1807caL,0x13638c798b42c6dL,0x03e92cfe895c934L, + 0x19c706c20f63910L,0x075d90b57ea585dL,0x0d8387c051d2c2dL, + 0x06b16d54092aa77L,0x1836fa6cc9ee2b2L,0x071ae5e82c9fed5L, + 0x0be813d3222e19dL,0x128ea8e42be53c8L,0x00174b21bc19232L }, + { 0x1540addae78ea1fL,0x0dba6bdb3874b48L,0x1107dc01a099468L, + 0x14faea418ff326cL,0x09ce12e18f97d6eL,0x1041a107d535013L, + 0x110d89642b2a1e4L,0x11ef49070c6eac2L,0x007c6149ef38140L, + 0x19dfac26bc29a03L,0x06c0426aeedbddcL,0x093fea5141350ecL, + 0x182e00ae3ce4eb2L,0x10bc77fd043c0f6L,0x144e9fa19306c94L, + 0x00c5f983cc5453aL,0x07dedb8b94e1919L,0x039cfa9ed278b29L } }, + /* 90 */ + { { 0x05f4a88924adc5fL,0x0360b540c7ab6bdL,0x04a5de57e552559L, + 0x1ba338a8001d892L,0x005912b42b48753L,0x1d24a30b7d11b59L, + 0x14199acf597cfa1L,0x0814e2e940208bfL,0x1b635031312a5e1L, + 0x1ce25a254b5c311L,0x0e75966ac00f569L,0x018c704de634f46L, + 0x0c6f7090cdc72f3L,0x08375f125a739c8L,0x091416966b1b0daL, + 0x08274734fe0db77L,0x084839991e1c58cL,0x0010611ffd10707L }, + { 0x00e4adaafc74661L,0x1e7b193bfe03289L,0x13dadb739e64deeL, + 0x06f62c374282093L,0x09610fb25b8d6b5L,0x0ef3b49110c218dL, + 0x018c37a7b27477fL,0x097a657f49a85b0L,0x13885702a6244dfL, + 0x0f6e8f6a2ac96fdL,0x17d16fed3806e33L,0x1da50dc42b601c3L, + 0x076a937e6a8f4bdL,0x00987b91c049aa4L,0x0a087e10549e2eaL, + 0x09f158db88d2471L,0x0ef2207b119fd8bL,0x03b73dfa9fc934eL } }, + /* 91 */ + { { 0x112842827ebd187L,0x19055db2d56ddafL,0x1969c8961a5634cL, + 0x131e130d576084eL,0x0ebff503da3f33fL,0x0fb8d2a08c03d3dL, + 0x1c92c971ddb2a09L,0x16981bcf7dbfefbL,0x1da8b0f42165f1fL, + 0x19ffb9bb98f9d71L,0x075f9c64f829497L,0x15476d67748c99aL, + 0x17aa1f37828df84L,0x13b99d63dd425c4L,0x0606885b9e58333L, + 0x101da9a8dad56a1L,0x1091ec12c257cbbL,0x03cf3d69395cb77L }, + { 0x0d970dc8f30caaeL,0x15e7885375f7a1eL,0x18fb1c5185b6172L, + 0x16a33c7530c7830L,0x04cb13d61c50db0L,0x0a3db4f9cdc4b1bL, + 0x0c3337d9f607c89L,0x16ee2af5773acfbL,0x0ccca25ba889491L, + 0x144903e3d13f06eL,0x1a3ef83f50ca07dL,0x1ee6ae41d812695L, + 0x09cdfd7beda5d91L,0x0501cf19597b0c8L,0x0363f707b0408c9L, + 0x000bba787acbdb6L,0x09432c916c84fe5L,0x03fc61bd62605f5L } }, + /* 92 */ + { { 0x1ec1e5443ac05e5L,0x126d266c69c1299L,0x102e22fe78af692L, + 0x016a7023b90db11L,0x03c3aba434d71ddL,0x0b08df32a820695L, + 0x13e80af102526d8L,0x186385a84dc4f34L,0x0535a5aa23b065aL, + 0x1545197e2975448L,0x17b29e7f76b48b6L,0x0bfa556764deb4bL, + 0x1bf37cd81e911f0L,0x0868b5c62ed673eL,0x1d625383839139eL, + 0x14e9e2bcd15dbc9L,0x02fafe04999fc92L,0x00ebb81d54b873eL }, + { 0x0a4c81d3f0062a9L,0x1595c6cb5105d54L,0x037e192f44078c7L, + 0x0488276c28cdbb3L,0x09a555f8ba05f59L,0x05a968a8d33d06fL, + 0x0ac8eb30bc25cb9L,0x03756bb55d8e309L,0x0ce08b43e7c7f69L, + 0x1072985bb6213faL,0x1481a7908faf714L,0x13d069be299cfa6L, + 0x15446305ac6b5e3L,0x1f1a66e09ee5f94L,0x07d6beda0b2cb87L, + 0x12df3a9588ba222L,0x071c5ef63cd47f2L,0x00516207649e104L } }, + /* 93 */ + { { 0x1bc384faf5747dbL,0x0b04360355c3584L,0x00ba79f0551ceebL, + 0x02ab2ef57f480d1L,0x1a81deb02d5326dL,0x05b088831d4d02eL, + 0x1ae426a1b929d49L,0x1742805f0f49565L,0x17d0721d4d5c600L, + 0x117ecd4f944fedfL,0x1399b7b379bc1c6L,0x04efb573f4e7ebbL, + 0x1f6c474bab62171L,0x1b776819b696e24L,0x0a0974f7005f87dL, + 0x0bc8772e2eb809bL,0x07e6c297e3d54b0L,0x0177da2a32b64e4L }, + { 0x0712b008b21c064L,0x17f212538314f52L,0x0d026dd3c2bf461L, + 0x06fd93cc52c86b6L,0x04c60d086965aa4L,0x182bd56ed0a339eL, + 0x1bd802d9599c2fcL,0x02cfe0bd08079d0L,0x0c05073a904401aL, + 0x158f31c14a7303fL,0x00c949a73dc1185L,0x0837d19cfa7440fL, + 0x137577053d29411L,0x05533186e9c56c6L,0x1410d436e9a3ecfL, + 0x0ec17d97d5fe3d2L,0x1e49f5166d51d2dL,0x019ba9967231448L } }, + /* 94 */ + { { 0x11118533a00bb9bL,0x1fdd722fb33429fL,0x0a1752bb8934b4bL, + 0x1606830add35c23L,0x0731349f18ba1e1L,0x0b8adad4d640bc1L, + 0x14bab04f7f52951L,0x14f4bee8478bb55L,0x130a483b9535b76L, + 0x174d6d27fc39f4dL,0x18b611c8e841564L,0x12f71db589c02acL, + 0x1a39d8fa70b9354L,0x0068ac4fb0db220L,0x0817c2855075d59L, + 0x11210c532846fe1L,0x0bffd8b00346bb2L,0x00c9515aeea6699L }, + { 0x1576628365ced07L,0x1997d82ef0e8fb1L,0x06f2fd029ea80a7L, + 0x11376a148eda2f7L,0x195a62781b1b2a0L,0x07e0cdc9c4d5ddbL, + 0x01ce54b3fd83ecdL,0x1ade757292470fbL,0x0a8f053e66920ccL, + 0x1796ea5b1d4da78L,0x03b78547a084a4fL,0x181610717f43356L, + 0x0c9ffc11beafba0L,0x0ae6043c15ead3dL,0x10bc318162ff656L, + 0x06374d0da9147f1L,0x068c33abaaf1d9bL,0x0319711449de061L } }, + /* 95 */ + { { 0x0851d2015a1cccaL,0x114863f2915e18eL,0x155463aac14d3bfL, + 0x0f790bc42e16e83L,0x01cf8b29ae65619L,0x0a423c57098a0f0L, + 0x162b8b8b2d64d9aL,0x111d6af761f8637L,0x0decef5d6c264e7L, + 0x1d42b664e5cb6c3L,0x05a04c9e460f69bL,0x1040707af2d45b6L, + 0x1f1d0c6fedf03f3L,0x05355ecdac522b7L,0x1e5bc6495626016L, + 0x13d4e673ea58b07L,0x145cf6ded8fda7eL,0x03461ece0ae8e66L }, + { 0x1e26265e6b392b7L,0x0ecdfbbaeca84b3L,0x13535d9453df3b0L, + 0x041bce5c39c2d57L,0x1adfb033d86f59bL,0x122be6533721e68L, + 0x16a8b6cd10d0017L,0x0636cf4f22cad03L,0x1c32e7babf01147L, + 0x137f0b769d8f4b0L,0x18a63bd8f49b981L,0x1bb0a835badb249L, + 0x1f9982f9719bea0L,0x02f83b5677ca806L,0x0f4e5ad721db98fL, + 0x0e8f4abc255cb64L,0x0a509efbb362ec6L,0x047902af7119943L } }, + /* 96 */ + { { 0x04ab9e3b82c1af0L,0x0f4f3f965713225L,0x10298061f51bf19L, + 0x0bc72766c69fd55L,0x019bacce27d3f33L,0x153308ce4fbe004L, + 0x0ba54fdd062d6e2L,0x113ff528aae6e55L,0x0937d78048db385L, + 0x086436fb78fde0eL,0x1af6268bc2833b4L,0x1f446ce873d6915L, + 0x0b3f17d2d8ae5d5L,0x008ecc4a081d350L,0x02d9e8bc8cfda29L, + 0x17e0cffd9d16643L,0x02e0422540f2319L,0x0094964649a0699L }, + { 0x1eb55870386463dL,0x1e15901b8ecbffaL,0x15c42e06716b52eL, + 0x0d9e095a82366c8L,0x06939ec10cbb42dL,0x0c23f3aec0ce3b3L, + 0x0cb921d16b04e80L,0x1009ee0960438e4L,0x12c9e58a0acb057L, + 0x091dc59dab0f14aL,0x137c01e7e6e8d65L,0x1f843d552c50670L, + 0x0f8aea2b9078231L,0x1868e131d17562aL,0x0ce400201d7b5dcL, + 0x0527559689dabf6L,0x16492546ac2f011L,0x03e3c3b15f5c10bL } }, + /* 97 */ + { { 0x0f7d6fb067902b6L,0x11d21e8b9acc05cL,0x0c4965d07776ca0L, + 0x0e8067f2b80c59fL,0x08589b8c6e391b0L,0x1148791c18e851bL, + 0x07ceb8d1d352548L,0x0729b5629ac445cL,0x18f00fcde53f08dL, + 0x0cc8bd7383f947aL,0x0a82e81a3981f15L,0x07cfafc3f0482cdL, + 0x004d6a328f60271L,0x0c4866953e12aaaL,0x082c82834b8c992L, + 0x1c139e440f289d9L,0x01d5c98dc0752f4L,0x034a01a826c26f4L }, + { 0x0b7b366e5407206L,0x1aa6786c47d467cL,0x1523dc9cb9bc7b3L, + 0x05035688d0dfdfcL,0x0e474408d653137L,0x0839bfa965af872L, + 0x141c67909ace992L,0x15e4aed83369301L,0x191f346280f272cL, + 0x0730527a34798e4L,0x1a8ca642113625eL,0x001972a2b0570eeL, + 0x0514b1adbf8a557L,0x1de9a1f7d58d79bL,0x1607cd08baffe4bL, + 0x061c265f3f6036fL,0x146ad850e06ba6bL,0x036d4f013de2fcaL } }, + /* 98 */ + { { 0x1eee4c25c9490ceL,0x1625186fb41c090L,0x1f8292a4da3aa5bL, + 0x149784c5e7cd8c0L,0x060c34ffd8b0492L,0x0f99e6842351082L, + 0x1d84bdffde990a3L,0x002218aa0884304L,0x09d25fce9149bcdL, + 0x12b08e6e7e309eeL,0x1dfa225fd47395cL,0x1e629d18116a2b3L, + 0x1575e7538f3fa3bL,0x08e42010750ab08L,0x00ab42b4782a546L, + 0x11cbe1a44d1759eL,0x112a04c6ac4058bL,0x03b9da05cd9a8acL }, + { 0x0ff2cdc3631cfd2L,0x06169c03b9bde00L,0x05a8ce2949c0531L, + 0x1b665957bdac00cL,0x070b17cad0e3306L,0x19a9f719b39c755L, + 0x0eb4fcbd2aa35e7L,0x1c0e25ed5b2aedeL,0x0e427985289b2bcL, + 0x0ec7ca6ed496518L,0x0751d76124b7641L,0x0b949a2bc97b312L, + 0x0b254eabbd3e06aL,0x0076a89e2392ea7L,0x1eab9b0c4e52b3bL, + 0x1a26efc1f30b377L,0x175dc125546833fL,0x0095a31c2e2b627L } }, + /* 99 */ + { { 0x10dbebd932951deL,0x0cea12d534e4a40L,0x1013b2cbc2365a5L, + 0x1844a17058bf893L,0x1aec4e1dac74f0cL,0x04cd66cb521cd29L, + 0x0cebf0cf2ae6a41L,0x1165f99bccca9b3L,0x0f4af285c3863aeL, + 0x1b99b9f237f5fc4L,0x159cb0f26adfb48L,0x0261fc240418ea3L, + 0x0f52f3e56ec1c51L,0x12532540d6c1201L,0x1c58fc8d226adeaL, + 0x0662e143f6cc3b3L,0x01717c69be10e55L,0x030e0c9af3ec46aL }, + { 0x0722d9b3492ae43L,0x04eca829c782d17L,0x1620802aad8c7beL, + 0x01d749622f5cefcL,0x1a461cb82872c12L,0x09c7932e1219641L, + 0x1f700c56cd0d32eL,0x11a0b7e558b1898L,0x0d2e501dd596b37L, + 0x028364fe5c48618L,0x0bd185f0d87c32aL,0x0e30b46b975c7a1L, + 0x11f3fc013821f7bL,0x0592476fde881afL,0x1272b81d18a2bd6L, + 0x10ee71ac843a091L,0x19475e3da392ca1L,0x013d686f938e9edL } }, + /* 100 */ + { { 0x03bda79305b5aedL,0x1ea522ccc6b53cfL,0x074c3dfadc00b19L, + 0x1c28fa388990abcL,0x089540edc18a7e9L,0x15fe901f54cb0c6L, + 0x110de94ef8829f9L,0x18d9290fcc9d982L,0x17297920734ef85L, + 0x106a738eaf0f5eaL,0x0ac79935235adbeL,0x1c0acdc401a9fb4L, + 0x1a5a5366a1782a1L,0x0d239b9c151e386L,0x18083a3f8fef4acL, + 0x16ccbafdf180cffL,0x02fec686fdeeacfL,0x02ecdaf13b6e8aaL }, + { 0x037c5a5cb3e472eL,0x1ec939850a02f1bL,0x0b96d1261560854L, + 0x1be73410a201332L,0x15c6c56018f00ccL,0x01aa071311be08dL, + 0x0c611063b50204dL,0x0d7fdef97e0fcfeL,0x0ecd92366bf4857L, + 0x1badf0d5e4a648dL,0x1de379285889d86L,0x0fa78b8d79711c2L, + 0x075ab71858c52e5L,0x1fb71cfcae61c16L,0x09cd7f384b0b0a0L, + 0x0b32c98fc1de5acL,0x166e071deb1835aL,0x0127c48e6e5dc63L } }, + /* 101 */ + { { 0x0ef60bf6778c1e2L,0x0e01e806adf2e12L,0x01b8bc06827ffd2L, + 0x095c12dcb1d8233L,0x1077984c59a728aL,0x0652d2d55de76dbL, + 0x038f7ed1cef4a1cL,0x195192518c29bc6L,0x13fae7f9a4f67abL, + 0x1e15975f610d4e7L,0x1c358a7366d77a0L,0x14b38c1631bf5f4L, + 0x1e4049b54cadeaeL,0x16e98871eaff7bdL,0x18c8733f3baf1d9L, + 0x115eaee91dfc71eL,0x012fe9c32b118eeL,0x0431d61e7ea16fbL }, + { 0x036fca7b85a2fe2L,0x1868477214ee305L,0x08245070e513cf9L, + 0x0cce4e541519374L,0x1968bd06306a810L,0x1e301ef34d0aaafL, + 0x193eae1bdf91c54L,0x0992e0cc295deadL,0x1c0dc36b898780bL, + 0x1b2bff11d0e9931L,0x05ea190d548b250L,0x0feddbfdecf203fL, + 0x146daa17a0d9189L,0x02d667def5df18eL,0x07f0779bc5e4402L, + 0x02859c1b4dc651fL,0x05a1c9d53dbe1e7L,0x01f1f8d8f45c339L } }, + /* 102 */ + { { 0x1ea15c07b7fbf05L,0x188db0f8d1c415bL,0x056b477346f264bL, + 0x155a1efd1793bbbL,0x1ca7ab7931f5b7fL,0x12adf3149b72f5fL, + 0x19550c3d05f7066L,0x17e3ede9c86879bL,0x0971f5e6582f044L, + 0x1e1dc7221446204L,0x0b167ee01fd5d5cL,0x05bb0316b1e0c35L, + 0x0097a3b0d3a64eeL,0x01ca582c37bd053L,0x0cd45f62e17b320L, + 0x07e0d340b28e97fL,0x02589ad5977a79cL,0x04090476c380540L }, + { 0x093509914c4ce37L,0x1dc21d0d5245308L,0x0091603563a3cd2L, + 0x1366eb71750c00eL,0x0d3bde836db42c4L,0x0919db561b2a927L, + 0x051bd548786d192L,0x15d78f98baac9bbL,0x19c14b035bfb5b6L, + 0x1915d0c00a360d1L,0x0beef21c8853d5fL,0x0fef69242ec816cL, + 0x01cb4d6df13acfdL,0x11300548aff886dL,0x16459fd98389881L, + 0x14332f58fb53b03L,0x1c26e8e260cb6e7L,0x0221c1fdc406f59L } }, + /* 103 */ + { { 0x107f01de44f9af6L,0x00d26c658fd0e70L,0x0fb3edf7524cd8eL, + 0x144d51073fccb7cL,0x1ec789d8d0b8435L,0x062f0ff7307c8a9L, + 0x0a073897fa940afL,0x17008ef818afc89L,0x1349e9f83230ba5L, + 0x0a17997ef0c06ecL,0x0e7abd928f44737L,0x109d7d6e1075160L, + 0x04f12742cb80ef8L,0x190501311447306L,0x14eddfd1055b315L, + 0x074b39aa8fbcce4L,0x0459829a6eca601L,0x04577384786aa42L }, + { 0x0f22d9c32c54409L,0x1fd233af5d5620cL,0x04a218a12606a7aL, + 0x1ed6751c1921c5dL,0x1d77641ed0201f6L,0x0b82bae4b980b65L, + 0x13807e49bcbc1c0L,0x0089308091ffd81L,0x0bf696211f319d3L, + 0x05ae422648d4462L,0x03ef3b800c2a09dL,0x0a4bc9edaa42988L, + 0x0c29d67d1ebed67L,0x010e9a9b57bf23eL,0x0ca5017e8c1f6e3L, + 0x100bead6d88d577L,0x1a0f059a7e3033eL,0x04b87b0ff304b52L } }, + /* 104 */ + { { 0x1c53d231bec8e4aL,0x0d60a1ad301a60dL,0x076942791936202L, + 0x1b1491046a9dc10L,0x125864b6496ae1fL,0x06834fd0d74c319L, + 0x09ad2eb284fa5d3L,0x1486e7198b163b1L,0x15fa71f58e76b9dL, + 0x08cdf4463f58b7dL,0x03c4feb5390a772L,0x0ce24933f3dbeb9L, + 0x15a10d8bd74583bL,0x0bc85dbf5e71008L,0x0ade377d9b5d815L, + 0x0abf5262d5dbc90L,0x0a7e0d8fb2d75f8L,0x02025adca2d3ee6L }, + { 0x1ee682a517a15c7L,0x067de77c401017cL,0x04e5441a8d52ab9L, + 0x042e1fd7cf9dc58L,0x13d0c54b5de6019L,0x08495bac4f1cfebL, + 0x1f97c6571c4d632L,0x0f396fdaa7e14f7L,0x12bd9242af61cc9L, + 0x09778b629cafbecL,0x0b0729c2ccbc263L,0x04daa5a30b821a9L, + 0x0a942d6195a5875L,0x128058561499582L,0x0bf48c3f896a5e6L, + 0x04a78bf43e95cacL,0x00260f55af220daL,0x03fd508dac18a30L } }, + /* 105 */ + { { 0x0ba4f0c6e402149L,0x0660ecb1e608cd8L,0x106a9949d1d8d61L, + 0x0b92ae2be4ee81bL,0x1f89fb0e3f77ff7L,0x0df1ffd9791a569L, + 0x1fa09545640cbbeL,0x127f93f643a0846L,0x1eb2eff38a153edL, + 0x0ea9d7008020e89L,0x19516dfc6f60a22L,0x0f9c872a7d4b9e5L, + 0x14d85e75c8dd4a2L,0x120df0e1806972eL,0x1080cb7ae4fb588L, + 0x1ce023ca7e4be04L,0x0bfb9957636c3a4L,0x00a5b1d2976cc7fL }, + { 0x010b55371c43336L,0x1ea5311d24125bbL,0x0b800a18146c677L, + 0x191ebe3db6f72f4L,0x1b67daad86abbb9L,0x0ffd7db3d2bebbcL, + 0x0f18e2b3941b735L,0x0a10bb53f2b1358L,0x0081cbaa875a3d1L, + 0x19a9ec7f49a3769L,0x0d87c687e680b40L,0x126e74cb38e3655L, + 0x0b4f5df8a1b0cb0L,0x15bead0edbf0718L,0x03973c1df131d07L, + 0x0e3591e08d938e5L,0x05532dd0bc7f7c1L,0x001242c39c1b693L } }, + /* 106 */ + { { 0x140dd2375a4cd8dL,0x05219cbde5d3c66L,0x1610963587d44cbL, + 0x13b43d1cd0618b9L,0x1d65d40a0a7ec05L,0x1a86bb03d478b88L, + 0x0b90a1a79957bd0L,0x1a17319cde0b307L,0x17b61391d9d8bebL, + 0x1294f12d8dd2ea4L,0x1ccba47dacb3d8eL,0x18d47f476c528deL, + 0x0cc3ef0ed2bd66eL,0x0f845a3b1cbca87L,0x16838bbba40232dL, + 0x1790ffad7c84b2cL,0x1ae78ed513c1177L,0x033cc676fff2896L }, + { 0x1e3f8fd1b97c5c6L,0x1d59f3c61d99fa4L,0x104903d656e8e7eL, + 0x12bafa86ec884e8L,0x19c44777174225bL,0x0b5922c4059fe63L, + 0x1861370eb2a0ccaL,0x0e4ab227bee2e69L,0x1a4db23d39c9344L, + 0x15d9b99e8a10508L,0x0833e7cd822f733L,0x19ec619fc27f73aL, + 0x115f30874ca618aL,0x0f8002d2baf8359L,0x0ff276d41bbf9feL, + 0x0f883155d4f1803L,0x195f9179255f78eL,0x01f53d7692974b1L } }, + /* 107 */ + { { 0x0617e045b06ae25L,0x00a46e5aba877ccL,0x1c398130ae8af2bL, + 0x16ed6f12eb23d45L,0x051da18100c19f6L,0x02b82dbcdcdb683L, + 0x16fc7cc896faf25L,0x0da61686be6b800L,0x1440b4482bc24d8L, + 0x1c784cb6b1b9bbbL,0x15b1587112d370aL,0x1dcc6120d332cbfL, + 0x0408aa1ec1e9405L,0x1e97944a8cff849L,0x1d19e5fbbcc91a8L, + 0x0befc02d86ecb78L,0x04462d2569fd070L,0x0354569ce029280L }, + { 0x05f020d46be7282L,0x0d7f6909c078972L,0x16f75769ab42501L, + 0x08ff17cc3c99b94L,0x196b8178c2d6f18L,0x06fcaa100994a9aL, + 0x0ad3634ec79edeaL,0x0aceaf8c37672aeL,0x0d749b57b80cc3bL, + 0x0c87fc99bd9fff6L,0x0ed94c517725365L,0x0c0c466bcae6737L, + 0x17f763feba70c1cL,0x0630db994e17396L,0x1cfcb291da39093L, + 0x0b19aeefa5f4d54L,0x1aadee4dbaac5cbL,0x00d0c08bcce7d70L } }, + /* 108 */ + { { 0x16ff62f77575ed0L,0x0a7d4be8ed4cdb7L,0x1beda7bf5fd863cL, + 0x17bb850c665ce55L,0x186c5834c45ab4cL,0x1baeec587106a42L, + 0x112634e5c0468e5L,0x1b002619011e826L,0x12d408ebaf5115eL, + 0x083502e01306f6cL,0x0dcd88672ae4471L,0x118dd0d2750d3cbL, + 0x1fcc7736174cf50L,0x0aec4e51a738922L,0x1eef260bdc6a87eL, + 0x0ffa49774f8d4c0L,0x1a8f3a515e7212bL,0x03e96ee3ac9187aL }, + { 0x105816d4ed2cae8L,0x15e3edce001bb9eL,0x039991ac235133dL, + 0x0297380301847d3L,0x0f9179c1f9ee6c6L,0x0cb445708e4d09fL, + 0x1c29e96d851fa3bL,0x0eaf5fd6c91a0ccL,0x0d670333c176852L, + 0x04eecb4bafcf479L,0x1c8a34de9a2b7aaL,0x1abc8a99630d76aL, + 0x0f063dd55021a05L,0x065b6579a4080acL,0x152af9e4b753c21L, + 0x13aece189b0a4f0L,0x0ba845969dc6e72L,0x02d297c3d58dfa0L } }, + /* 109 */ + { { 0x1019e9109ecacbdL,0x0011ebdc4def576L,0x1c2d5c1cdc79951L, + 0x082d91c42ef98a3L,0x01259ab514832b0L,0x11b0ea58d533414L, + 0x170a9b8403e488fL,0x04dcb27ddd3c752L,0x1699b6bbd16c10eL, + 0x0a43c39ca39d09fL,0x053716c9d261f2bL,0x00ea4ab3c5d3e38L, + 0x1dc3d47ad257dc0L,0x0ea93bc9c224c24L,0x1f56e660f7c9e2bL, + 0x00540ee1c7d91ddL,0x1fe2ae5844676bdL,0x00bf813b21f382fL }, + { 0x1a4010d29abea1fL,0x1cb4a9203d6266eL,0x04a410cc862d8daL, + 0x162c7aa6952d4c0L,0x0cc20565f221fc3L,0x142abb82dd0adf6L, + 0x0134c48e3953658L,0x1c8362884af0f10L,0x196fbf304a89a9fL, + 0x053f83625f32158L,0x0883a1b8ac217b2L,0x0f85fe94b23bba3L, + 0x13a4a343b88f7f2L,0x1d8b9ea6e0bd83aL,0x101eef9a12c7a22L, + 0x03aee7599d4887bL,0x17edb15c88d4c44L,0x00778184d29f2caL } }, + /* 110 */ + { { 0x1c25721fa8e5b60L,0x09c56b48e05d927L,0x0dd82c28892191aL, + 0x04fbc2d0efc8da9L,0x0721c630863f9acL,0x13fd81281ddb779L, + 0x0f4e7e306677c2dL,0x1b4f183dae5c0f5L,0x1cf9deb7bb32f0dL, + 0x1fb9378361e44f9L,0x022cb465c8896abL,0x022e9e28beb96e0L, + 0x0c457c4f378f5a6L,0x0e229e32270737cL,0x1a4b2022ef6a910L, + 0x06ac2af7c64db4dL,0x12aa9bc3fd95d77L,0x01e9db6635d9bdbL }, + { 0x06f12cc9722c880L,0x1b5739435b444b7L,0x026eb4bebfb0e86L, + 0x14877717df74398L,0x17c3f4c3ad64ad7L,0x09d48dd2d7b5004L, + 0x0fdacabf2c3670dL,0x1219427f956d399L,0x1699a1391f2abc1L, + 0x0deaaa111d123f2L,0x18603e55223668bL,0x17fe24899879c40L, + 0x1e87d3a365ba9e7L,0x1d2652f11494bd5L,0x0f86db10153e8e3L, + 0x034896720c47acfL,0x0e71fa67c5778f4L,0x0174a3721e3daa2L } }, + /* 111 */ + { { 0x180fddfc60934aeL,0x13f7f8b21036894L,0x1e5905bb5d68b0fL, + 0x06b9a165b9eebcfL,0x1faad87bfac60cfL,0x04f2eeeee25f670L, + 0x1c6b9d4fea1f261L,0x0978baa2d465837L,0x1565dbea814732bL, + 0x03f5f1d672434b5L,0x09d35b36e5da500L,0x04e0cbc9cf7c819L, + 0x013aac4ebc3f5cdL,0x01eb61d0ba423e0L,0x1e81da99d8b80d1L, + 0x0cefad21b192a8cL,0x0c2768d78d61edaL,0x004cbe72a80c0ecL }, + { 0x097746c965a0b81L,0x0c5f372f096fd49L,0x0f11c57d0dfd22dL, + 0x0f6acb88b2aae76L,0x1582797ce425e90L,0x12a3a7a7a1fa890L, + 0x012b3976be9be3aL,0x10655d71f7c27bcL,0x0ed7f95f0e8a07cL, + 0x1009537331604ffL,0x1ba6e31d0b3c5cfL,0x0b35c514388b7f2L, + 0x145cf4e2f38ea57L,0x1c80d00ca3aca0dL,0x045acb9f74f00b7L, + 0x17311cf49bdd4e1L,0x1e650b272b52fa9L,0x04b7cf84fe848bfL } }, + /* 112 */ + { { 0x0e8aac42c310a96L,0x0c181fbd1539a3cL,0x00f48e58881ccaaL, + 0x1db2a8250188d95L,0x0cabe911ad131e6L,0x0db6342bc8fe2f1L, + 0x021e1432ddfae10L,0x19d5ff27bd47a79L,0x106541f1df1007bL, + 0x17394e12ae6f8feL,0x1c4c5cc8f8e5c93L,0x14835a9a1183c1eL, + 0x1fa35e22bfa2de7L,0x04d81992d4c8955L,0x145353a814048aeL, + 0x1c157173ca3e80cL,0x0a5423c7aad79d3L,0x038ccc713205c7fL }, + { 0x0140fcdceb6ed78L,0x079bb8c29a28b20L,0x196ba358373194fL, + 0x0d3b58abf008a16L,0x0e05686cce6c1a7L,0x1892b1454b5496dL, + 0x05094bf911d8849L,0x184e8f796a149e7L,0x0f0ec6ff2fc531fL, + 0x0be1a23887f4ff8L,0x021e0e71e4b3ff2L,0x049004df6033f69L, + 0x1cd804c290552c5L,0x1ae46539a000d14L,0x1977e81d0ad6b60L, + 0x0956386f03e2eddL,0x0acca6b85f03dfaL,0x041c4ca0d058699L } }, + /* 113 */ + { { 0x0f062a2de067dffL,0x193485e5c00b160L,0x04341c1e8af753cL, + 0x11f5c94723319b3L,0x132ad8145afc63bL,0x0cefd8b4278dbddL, + 0x16122c28b738bc6L,0x0c444c1c2fe91e4L,0x17393db00c2d5e8L, + 0x1447c2a19c678b8L,0x1e50a40ab3d48a7L,0x1970d06b5e7a00cL, + 0x12b8a2614c19157L,0x09a7623617d537cL,0x1ea04d413fe57d4L, + 0x08e099e00c4ddf6L,0x025454b3d05b37aL,0x00fdfed18934a76L }, + { 0x1ebb657c8f69c77L,0x013c5d1efc47d7eL,0x15c707ede2d24aaL, + 0x14238e34668c76aL,0x089958b0d2066a1L,0x0eb3d3086440a18L, + 0x1ee3ee5d71f833eL,0x0c3b54ba410e606L,0x15ee5005d40bf58L, + 0x0073673bedd34d4L,0x10f2cf258b31d0cL,0x0c5299f080ab127L, + 0x1a225c9d700ac98L,0x1c8f23f4053f7b1L,0x0be12fbf86121a6L, + 0x0f17e373afbd718L,0x19e67788915c0e2L,0x027ca4465621378L } }, + /* 114 */ + { { 0x10dfcd4dd51b8ceL,0x1c93c1b11874030L,0x1c70d9665588215L, + 0x17c595d0efdb8ffL,0x07967608905ead4L,0x1c493650e192ecfL, + 0x02938f8e7b776f4L,0x149b52590d0bedeL,0x1e16f800af47a0fL, + 0x05a6dadf2fb0555L,0x1504be60e14f4d4L,0x04a136f2f1386ccL, + 0x184e0e72b264b62L,0x12aae15df52b002L,0x0a4b846aef52407L, + 0x0431e6f08334e2eL,0x1926e0b5aaae174L,0x03447034247bcb5L }, + { 0x1fef641313b8f64L,0x08dbdca163a3166L,0x0ddd70362af6bbcL, + 0x015e8083520cf9fL,0x0935210f608ea5fL,0x08bd0411eadec13L, + 0x0b4856ae413f09eL,0x13f0bb763fc8ba4L,0x0c3d5e5094d3615L, + 0x15da9470e9cdc79L,0x12a0a3d12b3bc2bL,0x15be418af4a9babL, + 0x1378f95f4424209L,0x1499be9baba15a1L,0x133f6df447e9f66L, + 0x02fd9acd418138cL,0x06556e55b8f9bb8L,0x00b91e3f1f26209L } }, + /* 115 */ + { { 0x06486d8dc8b43f3L,0x1073093204f344dL,0x10df66d1800ff0fL, + 0x0ac509d8f631138L,0x0a9dbaea3a85033L,0x1c499e2d1b32e23L, + 0x05241efda5077a5L,0x05a3dab4a20d268L,0x1664a7b7a8cb800L, + 0x01fbb723076852cL,0x01ae8c7d3afc9d8L,0x1a83e58714ff87cL, + 0x19cf1db08a296ceL,0x06f3d1db1560c7bL,0x1da2c1b2467a20bL, + 0x0f96a2bcefa53b7L,0x13a21978baa4e94L,0x0425faa15bb184cL }, + { 0x1decda9e364f21eL,0x079a280972abf60L,0x0121623e438435bL, + 0x17c76209717448dL,0x03aef57a9f6dda4L,0x193f54b5fbd1a37L, + 0x19b1c840a67fba0L,0x08b5533e90fb52bL,0x024ff813ed2cdf6L, + 0x0edd96945ea0a5cL,0x0406bf2be869874L,0x173539bd7b480caL, + 0x15e41039e47d9f4L,0x02856fa157a0d9cL,0x07a79278fa79aebL, + 0x0fe469e42675c68L,0x1534968c0f3cb15L,0x01c1fc13ded0340L } }, + /* 116 */ + { { 0x0c46a216583ff4cL,0x02d14a56b84f397L,0x073f013284a9399L, + 0x0922c14fcbb8cddL,0x169c762e82f128fL,0x16dc73dfd913d8aL, + 0x1da23e031e58f0bL,0x1994fb5fc0c9341L,0x0b7e417542d14b8L, + 0x1062e29c36f205fL,0x014a1876de4cc4eL,0x1cd3f7fc0e37e1aL, + 0x16210e9903b902cL,0x1b81f5dc30f234aL,0x17de2dbebbe1d3bL, + 0x1d475ecd128fdbaL,0x0256fe865475af5L,0x01d890f8aa1fca3L }, + { 0x126e847659275e9L,0x00e7eb687e7282dL,0x0ff62a8fc7bd1d6L, + 0x0bc909cc1cabeb9L,0x1e9698e41e7be31L,0x1823c26c78d107fL, + 0x16cf89751b6a5eaL,0x0134a4db6eb0699L,0x01fd408d98d08a0L, + 0x00025902dae540bL,0x18eecd9792efa3fL,0x024aeb376ddeb67L, + 0x17c2fac737f50ccL,0x0939ca8d782fd40L,0x12ccd9e7b840b4bL, + 0x0a2be551ca817fdL,0x083673446fb2a6aL,0x02a82f0e89b9486L } }, + /* 117 */ + { { 0x03014a1d15e68a6L,0x18593326e9af286L,0x10b40eb59fe5be7L, + 0x1da58289083186eL,0x0d41a3cb74818c0L,0x0f9f4f628c08b48L, + 0x04e19972320ff12L,0x139364c18c2584fL,0x0f6086faeced04eL, + 0x1d96675febe23acL,0x10c4ce40a5ff629L,0x09d012e03590967L, + 0x07508b3762ca826L,0x0c1d46ff4fcbb54L,0x15663a575609c52L, + 0x1a6906a1a4cd3b3L,0x17c85cb89cb0f6fL,0x030bec06a52ba18L }, + { 0x0ef267e70022b67L,0x1b5da9bb45ca526L,0x159b49e1118a014L, + 0x087048723262a74L,0x1df78c4a49054d4L,0x10f1ad4688f0b92L, + 0x18c766c94a9c756L,0x01c0f0cd90102e3L,0x00a8501db1b38a0L, + 0x16c995c673b811bL,0x1dd8263b6bdf40bL,0x1b5772600dd345aL, + 0x04bbfeb0363aee5L,0x0710d9c5fd7fe46L,0x0a381a41dee59e1L, + 0x108e2923f8b3fb9L,0x00b3f624f550e93L,0x028ab7a843e68bcL } }, + /* 118 */ + { { 0x0234e220206e8d0L,0x17aea3f8ad7992cL,0x0a2758e2543fd7dL, + 0x12fa892be95f56eL,0x08da80a966ec4d0L,0x1c51b5d6c4862ebL, + 0x1717f92a8248193L,0x062f33c4afc1e9aL,0x044c677ae24495eL, + 0x101c3d9d2dc71a9L,0x1e43d1d68a1ee5cL,0x198b8783e5eee06L, + 0x1b41a7fa4154895L,0x18058045dc3407cL,0x191cf2ff351d162L, + 0x1c3342939907174L,0x1ba78ed5f7aac9bL,0x0292a2cce599bb2L }, + { 0x0739679a21b54c4L,0x167155b24bece84L,0x0a4b212219000a7L, + 0x1fd3f4f3b3e29e3L,0x06c208dbae48dcfL,0x11fb4f0a5c88e12L, + 0x0e0e16ac3efcb6bL,0x176301590fda3dbL,0x0146fd718188586L, + 0x0875b2a2a33e5e8L,0x0e5020599f3fb88L,0x18356e7a34c1544L, + 0x00881c1cbedb125L,0x1be181196f34298L,0x0f23463f8d31c4cL, + 0x09d078d8c0e1cdeL,0x14507e365bab4afL,0x0117853f6ee7c15L } }, + /* 119 */ + { { 0x062791fea7f1b7fL,0x0c62eee7f84ea71L,0x070ce71f716270fL, + 0x0e84edd1810d855L,0x09fe1d564dad401L,0x1408648548c7acfL, + 0x13712e35e59c0aaL,0x05dd6f5106c954bL,0x0fc4c23bbe7afa7L, + 0x0ddae4f25643484L,0x0e404da831f9bd3L,0x0002938431a46fcL, + 0x0794b324a2855d7L,0x1143d038f23ade3L,0x0d0c8f3262a3719L, + 0x113d272b45336bfL,0x046e186c3ee0c03L,0x03cfc0f378b39a6L }, + { 0x1f2c1f3364f3c4eL,0x1956289b3f0a5c1L,0x13f164cf90f54daL, + 0x0a21b2c3fc894dbL,0x1e3f2aae34e5947L,0x153f928411a7673L, + 0x084932e4b802af7L,0x0743df749e14f23L,0x0c2086fd21192d5L, + 0x160687e5a8e457bL,0x06cb2b703c6d7ffL,0x111f025b7c3291aL, + 0x0adedbdd45b07a3L,0x0b812c4d20439d3L,0x189ed92f0a849a3L, + 0x0dd0b77edc7502fL,0x00073ee56636d38L,0x02217669bcef3e0L } }, + /* 120 */ + { { 0x0cd1ae68a2f90a6L,0x1ea0eb7ad68665aL,0x031100752e3bc9dL, + 0x09b06ecc62d4705L,0x15e1124be817a13L,0x15caf20a15bac6fL, + 0x078f897ef1a77f5L,0x19d46193ebfae95L,0x15ac0f163d89663L, + 0x154f77b86731c36L,0x043a9763b55510cL,0x1fe1311284f4f4dL, + 0x05eaaced585de23L,0x09f0c232bad69b5L,0x024e440d4529b07L, + 0x0add07b22c586feL,0x11e5c10add9e33dL,0x0428bb5b9835534L }, + { 0x12110fa28a21e38L,0x11bceabb9ea9c51L,0x0efcb40837125edL, + 0x072c30679ba6d2fL,0x05fa85165917759L,0x155ae936b822fd7L, + 0x16dc0ce43ca69e1L,0x18d5817b461b89eL,0x1cca0240adcc615L, + 0x10f8b81628a36c8L,0x11cb429cb3be1e3L,0x0e1016cd37439d6L, + 0x1d7e61aa0a84840L,0x0334ab05bcd847cL,0x03adc78e20582f9L, + 0x0b2184726b85b29L,0x0b3d7fd83c09431L,0x04558aa5db72bb4L } }, + /* 121 */ + { { 0x0686003353c4a96L,0x03074482e6c1a94L,0x0d923d9be331397L, + 0x113f599f3d7ab22L,0x032639e5b6b80b9L,0x0556f5de0e0fd77L, + 0x080b4bd8e5b489eL,0x06a014f2da03130L,0x018ab548f3a4748L, + 0x0682b61d98d871fL,0x09a374059144b6bL,0x0db29607e7782b7L, + 0x0bd8f206c520383L,0x0f8bbcdb6b27653L,0x0acd2a24c68d87aL, + 0x05c45b04d21f8a5L,0x0a9342bb8e09292L,0x00dfe6ec2700581L }, + { 0x10b9a4375a365d9L,0x0f0af046c7d8198L,0x0f5f5d0b7e0f52bL, + 0x09bc630e85392eaL,0x1360ace0cf7309dL,0x134b21891471091L, + 0x1694c410f48e3ddL,0x12ff855b7dbf21eL,0x041d64cb77b5f93L, + 0x100598562236808L,0x0190b48c5c83f94L,0x045b735440eb879L, + 0x12041eae47fcc01L,0x14643b5242b71d8L,0x0d81ac516191155L, + 0x0af7e3438f08446L,0x0f19b766d1f2277L,0x012dbc51dfbdceaL } }, + /* 122 */ + { { 0x0835718156707ceL,0x011cc218a7c8548L,0x016a2f95f6f66f7L, + 0x0b5ac7497002f91L,0x15aacffdd4bba22L,0x0aa3912e738dc30L, + 0x14f757c9991d5caL,0x1ae1501e3ee9e15L,0x0010538a3fc352eL, + 0x0532022a101e365L,0x11ea20cc31ced3eL,0x1dcc05b95836565L, + 0x0fed2b17c7b3433L,0x1eb194e397024ceL,0x1eb70de7e1a0692L, + 0x112b6712f328c6dL,0x0f0dc5650c892b7L,0x03855cab832d28eL }, + { 0x0778ec47b585d93L,0x09b085319ff2723L,0x15393a80c46b29bL, + 0x177ac8005e43b42L,0x191cb7a9af22190L,0x141bebcf319d63eL, + 0x1ba2bb44f0c7fb9L,0x02db4940fae2c2dL,0x0d78a27323afcd6L, + 0x0334b72dd0a6b4aL,0x1d535d37d610830L,0x009c4ef1c792e66L, + 0x0c55b5a5c2e85e5L,0x051d65ae182ad50L,0x0223b68c4f7d4e2L, + 0x0bbbcb12d596a54L,0x0befc8842a084c8L,0x02ff64fbca8eef3L } }, + /* 123 */ + { { 0x0bc2c7cfe519f99L,0x15ec072a081a9afL,0x100a28e623cf8e5L, + 0x0bac037b435bdb2L,0x14ce64ac1c03b73L,0x1201487e98101b0L, + 0x025f560dfafa404L,0x073955d43474aa8L,0x1dce73d25b0b881L, + 0x0f6a095f658485cL,0x0a7fdf58f6acf0dL,0x0fb20c5b60e3320L, + 0x1642a4c11d55543L,0x127e488493be97aL,0x06495351dfe9914L, + 0x0c318f625d36e4fL,0x1957ad2ae22d84cL,0x00546ab31e74768L }, + { 0x1ac51630a21fde1L,0x1aeeb3481ec24a1L,0x07b97f758a073f3L, + 0x00ef493468da493L,0x0875c06f4dedc6fL,0x1dc023235ed1601L, + 0x00dbf438383d8d1L,0x08420b02d36bccfL,0x0c961912ade8a80L, + 0x19ff505549d9e99L,0x0e3b6c315daf177L,0x1addb1a6fc8f3e2L, + 0x19cce5e7cb7971aL,0x0e9015a0755c2b9L,0x087f49a2292d0d0L, + 0x0df22bb084aafc7L,0x09f872fabd5b3a8L,0x04adc9a49b55231L } }, + /* 124 */ + { { 0x198a70199f951deL,0x0f2cb782c6da2ccL,0x107bcf40f74e3ebL, + 0x1a676283a69a8f3L,0x0cfe8a406e928d5L,0x077d1ecd232c005L, + 0x1c9bb4422b4bf07L,0x13ec972d243c026L,0x0b9b6a6b68e83bbL, + 0x0f8f36e092172a2L,0x03d9d8bd9659acaL,0x012cbc20b683a7fL, + 0x1a16011e1ca34ddL,0x128aaa0dea7489cL,0x08859b7ba9371a0L, + 0x0c248df00615990L,0x07dbdc7ae1d31d1L,0x01712f7a8b10d7dL }, + { 0x133cf8fdd8e7357L,0x1d10c75676edc12L,0x0c741e134ab0cceL, + 0x0de50095c4d1c7cL,0x17e7ad7e1c927f3L,0x1fbc5000a19e913L, + 0x09eb82d0073c161L,0x16b3bf9e06d5400L,0x0c9e46c8b1d9a46L, + 0x136f2430f944699L,0x1b68bc6e2810f6aL,0x01cbe5a176adbaaL, + 0x0419defb5634623L,0x10e9643a0cf85b7L,0x03916cd57b0df34L, + 0x1d0a47b7e072f6eL,0x1d6f0862a8dac7cL,0x043cbcf53f0a0f9L } }, + /* 125 */ + { { 0x17e7b3f7f1c747fL,0x1260ee37319b4cdL,0x1dc2cdcb6e80546L, + 0x09a7dca9fc84e7fL,0x133cae0fca6d223L,0x0b7886097e47066L, + 0x073e49cca14e177L,0x12390de7f7be035L,0x05322677fe36caeL, + 0x0d3801997f7f522L,0x128ca33a2bc85ceL,0x0eeded4e63e8593L, + 0x1f66a96813c0256L,0x06d976d46343d9eL,0x113faf4652aac4aL, + 0x08365bc61b8b5ddL,0x016c052236a9792L,0x01f64c401611ea6L }, + { 0x19e760c4072f74dL,0x1586f55aca02c87L,0x090326c0270b9e3L, + 0x00716b35cbb67bdL,0x0b4daa0647e875fL,0x079bc47a075a1b1L, + 0x0be2e69a93e4824L,0x0addfd7d35fdb7fL,0x1f87f96a59867e2L, + 0x137f691bad5b575L,0x09e0a8ff6c4f2c7L,0x0e3ce1f44c422feL, + 0x0cfd4c0dbe5102cL,0x181a394bae95837L,0x19f9e014df309a0L, + 0x1b4651b7ebc5656L,0x1142f633f3aba25L,0x01f498af477d764L } }, + /* 126 */ + { { 0x055cfa5239a9ea9L,0x1e34805f19d3149L,0x0d2e72d90af483cL, + 0x0c0175ce30eb3ddL,0x13410f843316c54L,0x1894db43a53b6afL, + 0x07c7048ed40ba43L,0x1195b91f350250aL,0x1f57b764a1b6240L, + 0x0b7600f8d403bbdL,0x1b3bc87c3771704L,0x08f9cb4d4b4ee8dL, + 0x0706e955ba3c49dL,0x1a2ebcd80f0aedfL,0x034421d8a7031e6L, + 0x045ae224f0610efL,0x19122585dc78c6aL,0x017681506853413L }, + { 0x10434164daa2682L,0x16995809acb12a9L,0x0d2af619c25c389L, + 0x17dcef5c5c89390L,0x1af6c16911a19d2L,0x0b082a1cdea94d1L, + 0x03f84db32970173L,0x06ac6e14b37b8d8L,0x0ca420d27b93d51L, + 0x03986a2aaa6228dL,0x0963265b37afcb6L,0x13214a1f340bd7aL, + 0x1a7b0f01510cb1bL,0x08e90bf0b4d464bL,0x0bdd7a0b30db4d0L, + 0x054c3e22ed114eaL,0x1dd1db01394a09bL,0x00a313c2254f7ebL } }, + /* 127 */ + { { 0x1ca3aed232803cfL,0x01cc5cd4b7f9a35L,0x15fdd2ade22f079L, + 0x00fcd1809b95eceL,0x1cb7cd20c3a53e0L,0x0345e52fcb4e0caL, + 0x0c0cbca2d969b70L,0x029c79403a63b0cL,0x09b733b8187808eL, + 0x0eb826cf7f30c5fL,0x1cd50ac06e51b6dL,0x033df7dbbb7e4edL, + 0x0b903275cee057eL,0x0407bde33e8c179L,0x11db050f3717ddeL, + 0x0a0e5ade07a7ef0L,0x028035f5557a9baL,0x03d65abdb5a014bL }, + { 0x041356944e6b07cL,0x02664f0e39a2ee9L,0x136389cee7ed147L, + 0x13711c69f880e88L,0x1152776dfe49607L,0x0114ce3be8c267fL, + 0x0a25db440cee71dL,0x04053414d08ef7eL,0x059ffdf10ee8f04L, + 0x10b8a36225dab6bL,0x141b0bee6ba1553L,0x05b7b27cf9ab063L, + 0x063c96b607b2cb8L,0x1aa4f154419c0e2L,0x12887501abb4945L, + 0x1f7bbdf2f1238eeL,0x16cae9807c78675L,0x0352d02dcb1b1a8L } }, + /* 128 */ + { { 0x0e71ea66a8f4f33L,0x037e326f547a549L,0x14b3fba21187cbfL, + 0x1c112a9a11a6ac4L,0x068ab76659b0a83L,0x07c6822deb4611aL, + 0x19eb900a04d5e40L,0x08230383380a570L,0x0986a516918764cL, + 0x180efd709abae92L,0x1a6b9564d9dedf2L,0x004a8db936322e4L, + 0x19c40097c8f6d17L,0x12ce203dc6f3424L,0x14a762ddb7c00c8L, + 0x16bec812355b22fL,0x08ca7f46d214a7aL,0x034402a5a387672L }, + { 0x0d168aa51a5b86cL,0x1f26c4abbb923f8L,0x01dbc5c80ca490dL, + 0x1b2c8f4a9d5d088L,0x0405622c0a7ac87L,0x13cf978f2cbd258L, + 0x055b7b7bf971bc2L,0x1ed5e7de1849aaaL,0x1917fb04eef047cL, + 0x1c93ccfaa5b109bL,0x1a8cbcc52f82e0dL,0x0cb6188cd6190ebL, + 0x0e7e218978e157cL,0x06f2c3d7e946486L,0x01defb6e43f0eebL, + 0x0219bba65ae3917L,0x0533b432200ca8eL,0x00010fa0ceca7b7L } }, + /* 129 */ + { { 0x191122c43519d26L,0x1d60ea0528c2290L,0x07a5522ee27ef6bL, + 0x182d0897f398deeL,0x178e8d559ef3375L,0x05f0e2f3bc4fbc8L, + 0x1790013d666d87eL,0x193011193345977L,0x18939a260893206L, + 0x0d725fffe698428L,0x12cffb823fabfa8L,0x0133fe295578cc9L, + 0x0c2a841ef961f38L,0x0bf80edb06c1ca6L,0x1aeddcdd7eb62b4L, + 0x04a24df868aecdbL,0x19f1e716b05a425L,0x03cc2ac4014f0f6L }, + { 0x0cb3aaa95106473L,0x17d20ad30ed0251L,0x0d894e558f0257eL, + 0x032a62570ffa792L,0x1f885c76baa4809L,0x063c6ab63f3ac15L, + 0x11035c3db6ad88cL,0x10d19c60a38ee8eL,0x06dbebd14ffdb61L, + 0x07020fd0c87204bL,0x031199bb98b8aacL,0x1c54e9e667ad742L, + 0x04fe7b9b6693d57L,0x036941be803556eL,0x01d07abebdcbdb0L, + 0x048ee63198bcd22L,0x08d9c5026096569L,0x04aec11e18e87d8L } }, + /* 130 */ + { { 0x0eebd86140528a5L,0x0615d29cbcde435L,0x0e293b0512afc9aL, + 0x1b054fafdb63793L,0x0e0118d81efabb0L,0x00aac778963868aL, + 0x19cf8c581c5a287L,0x1ba67c8516fc96fL,0x06317663783aec9L, + 0x0b97fdf709561aeL,0x1c2feef05eca914L,0x10e0e83f02546fbL, + 0x1be2888f9c4212fL,0x1ab652ae9ee765eL,0x00a3906a77056a9L, + 0x1b607e63231d972L,0x1547ede02856aeaL,0x00713846abc32a7L }, + { 0x070cc53cde20f88L,0x013962fad881c91L,0x0679772c76fe4ceL, + 0x136e5ae982a085cL,0x0aaaaa554b3de21L,0x1435d30b624d459L, + 0x05a5402110f96eeL,0x023dcd79ae4419eL,0x159ffac6ba89abdL, + 0x01890bdf88ab1ceL,0x0a2bcbcd32e948aL,0x07ce0e4f520dc9aL, + 0x1f69017766f27f0L,0x1d40891f342163cL,0x0a5cee32cd1a6f5L, + 0x01b7a9181e68d48L,0x078fc5784a62399L,0x0069ed59dfd94cbL } }, + /* 131 */ + { { 0x18376e6ce29c3ccL,0x083f6780b65e347L,0x065978e533872c1L, + 0x1ee78a1a83bd7ffL,0x0d16ce3d24fc526L,0x0098a0a76ead2a1L, + 0x0181aecdef76647L,0x151c6885de5c675L,0x12ae90337c0629dL, + 0x1fd76322c955998L,0x0e265f60ae15ed5L,0x1973466e62ec352L, + 0x029086751fad6c8L,0x0c60b8cb412caefL,0x1a5cd5ea07a5fecL, + 0x13ed3c9e914277eL,0x026a1387c2e5cb8L,0x02985a775ac3a5aL }, + { 0x1f275a1bab7b5aeL,0x0ee2681d2bdfa74L,0x112a9171416eedaL, + 0x0682d5880592e9bL,0x0ed985dc726369fL,0x0a2350b9af273c5L, + 0x0c0a8152361e737L,0x14d099d60d33c2dL,0x0f73f6fa4789b11L, + 0x150620fd95273c2L,0x1da40a4ea6da5daL,0x1c01e075156563eL, + 0x1b844d66c1814ccL,0x184a9100b26592aL,0x08c89c6de539f58L, + 0x149b3c0a5a9c87bL,0x17f5278b2e708b6L,0x0484a12a940632bL } }, + /* 132 */ + { { 0x069a14d0d5b4c2fL,0x1e2cdae45324e69L,0x0ceac38df528ae3L, + 0x11222206fd2b7d9L,0x14e35322fda1a76L,0x1c7d7e2c08702d4L, + 0x1398a8937304a85L,0x088b858c7651c7bL,0x1995c3f179452c4L, + 0x0998761a16a28b0L,0x16982ad3be04a4dL,0x04a5175d3827404L, + 0x06e2e3caf885493L,0x1b24dfa392e8d30L,0x13b17c7510246acL, + 0x066678fa15f7ee0L,0x0f527bd1d62bd8bL,0x0282b8088e7f30bL }, + { 0x0084acef534356bL,0x0ef02a5a587de68L,0x18173b81370677cL, + 0x106c36f1c20435fL,0x0f78d38b64bde68L,0x052f2751927e63fL, + 0x0665bfacdcb3bacL,0x09dde09f966cb02L,0x07dce5d505eb0abL, + 0x114dac411c62c37L,0x18c65ef36000dc7L,0x08a2900d739fbcbL, + 0x0bd18e67ab8bf5eL,0x1cfb1fd6a1984b4L,0x1062ed09a9f413bL, + 0x1c459438fe2476bL,0x19f485b848225dcL,0x047f859b7eaa073L } }, + /* 133 */ + { { 0x1f2e2f43ff42cffL,0x0cfce8e1a98be4cL,0x0e4aae86d5168f0L, + 0x0a95f53465b6e92L,0x17dcd43684232b0L,0x07cc8a85c2aea36L, + 0x088622b0d788117L,0x00baf9e458fe003L,0x1057d35aeed4083L, + 0x0d2528caa9e67e6L,0x195e4e4f8ae4e49L,0x05606845d84ebcaL, + 0x1e3ac53958a2033L,0x1cf4d8b1cd84802L,0x19863598a01468dL, + 0x1cf5f6941b813f8L,0x03e9e0e857f6748L,0x038d9477762bbebL }, + { 0x142b0cd99726bf8L,0x051dc8e10479e24L,0x039ec1663aa84a4L, + 0x1f44b52251fae52L,0x0037d7dac6a7791L,0x1141bd9699ed926L, + 0x18a83087bfac1c3L,0x04f7ee1b2ddc7b5L,0x143ed8191850760L, + 0x175855426a56bf1L,0x14407fa316dd312L,0x14dd5a4dd7bb78eL, + 0x086b78aa4edbfb2L,0x108acc245d40903L,0x0e9713b252aa3cbL, + 0x052b41a21b3b67dL,0x05ace7fec476318L,0x0394a388d1986c9L } }, + /* 134 */ + { { 0x0e4590432bbd495L,0x1a6e8df2a4b9ffeL,0x18757670fd38cc3L, + 0x10b374e40800d7dL,0x02c2c76840ee607L,0x1f445f60ca7e9faL, + 0x00842839dac4ba7L,0x18e2f9bbbb7d856L,0x0689d436b00811eL, + 0x1535d1b9425f4f2L,0x0e56c801f504529L,0x13e61e23ce89578L, + 0x08e9396402f8cdfL,0x175a3142e2ff5f6L,0x18344de29d45d0fL, + 0x125c7337f0f058dL,0x15f3965e170beb2L,0x0000e1cec2c00feL }, + { 0x0805cb9da4a0912L,0x05bb522085e527aL,0x0e3bb1c7596f49fL, + 0x16902d0935de7b9L,0x08b24635780fbb2L,0x02273477b538135L, + 0x1d2a0558972204bL,0x1c8c49846589af4L,0x081a770374b1631L, + 0x0727bf8edc8be17L,0x1197f47d87b6541L,0x009397bcdc7a3a0L, + 0x01d7131fcfb1048L,0x056d238ab1be706L,0x1a65c988b936f0aL, + 0x0e8a1eea618b959L,0x113a0160dccee28L,0x0489973385dc8d7L } }, + /* 135 */ + { { 0x057efe27996099dL,0x1a26dd037304640L,0x1d0342561622dc8L, + 0x0cf3cb5dd3d6950L,0x108a2fade53daf0L,0x1f383564ab054d4L, + 0x091a9fd2f84c441L,0x1ccdabe7b365060L,0x0a5f8e8da27cca3L, + 0x1a8ee5326147949L,0x08c43bcc77f5e3aL,0x0f845940e7ca99fL, + 0x14a40da68392e0cL,0x1a869c7e08178b4L,0x16b80d45aec1f31L, + 0x193bae07d07c575L,0x0d1ea93c066b4d3L,0x03e8581f2bcca07L }, + { 0x1e7ea304dd94c63L,0x180e2b9c5859d2fL,0x1e328539ad2d5fbL, + 0x1d4a6a64ed2a694L,0x1c22d00607622cdL,0x035904d7b4b503bL, + 0x0ad29ccf06219f5L,0x0992ca99976c4d8L,0x0a098d3a1a84f3cL, + 0x0cb7cf696b9a5baL,0x0c086975547240dL,0x1a5e3d8a247fbfaL, + 0x05b2c1aa39e2ba7L,0x1c759493fcb9349L,0x064a9bf4b9d743bL, + 0x1ca1df574e25c32L,0x060a606b43a9b83L,0x018d8bc17ed5aefL } }, + /* 136 */ + { { 0x18dba454034db92L,0x1bc80c79a6e26c3L,0x1cbb7dd530ce8e5L, + 0x159aac75111a009L,0x1b5ffad1eaa5954L,0x0c5edc514eb644dL, + 0x16d1ea2b7d956c3L,0x0b7eff7085b19b7L,0x1b72e3a0380d320L, + 0x19ad8593e563e54L,0x182f2f62951d770L,0x0e33d749a4bfff8L, + 0x180c50fca6736f7L,0x00600c801ec80e1L,0x007e1347f6b3deeL, + 0x17782eb9ecb1eadL,0x11f57a7e6345cefL,0x037e07df29f03f6L }, + { 0x16d116bb81b0e5fL,0x0e952956429dc24L,0x0b50c9ce1fc360bL, + 0x09752258b26afc4L,0x09d5dcc13e332a8L,0x06c2e9c5b8e321aL, + 0x135383260bba50eL,0x1c72172aa797effL,0x12cb39bbc38fed5L, + 0x1633e4e2d621481L,0x08485efc1f69568L,0x0b5b4173c9ddd7eL, + 0x028ee9e0c655ac0L,0x045db71f885d896L,0x011ba4573cebb95L, + 0x0aa7e95ce4d3916L,0x1c8cb266012aa0eL,0x0380c9ad0d4a647L } }, + /* 137 */ + { { 0x058d41da4626deaL,0x1b3650adc81cfefL,0x0290c593996c97bL, + 0x1ae919f99f33502L,0x0f142fa99fe6daaL,0x038bcb3d5cd35e9L, + 0x08e6e932e85a175L,0x0ec25a6166cd787L,0x01f46a5dc8bf450L, + 0x03472948a10d607L,0x01881966ee8712eL,0x0a5db4d31720f4dL, + 0x14e54537072b4b5L,0x0f480b2fa81cee6L,0x15177f10a81ea7aL, + 0x1d6615071ffe7afL,0x00041991e5a3b5cL,0x0364b0f644b4e53L }, + { 0x03bdc1bc4e7eb46L,0x162abacb63da438L,0x1f359abf5d375aeL, + 0x0acad9cde69f322L,0x124971755635510L,0x17fd969e8fda861L, + 0x08af7f699e0f98fL,0x1ef7af3e3e7ddf5L,0x0a4efbe5417af9eL, + 0x077b2312d2adbd2L,0x1cc8e069c4cc11bL,0x14ff72ac4b4622dL, + 0x1a0b027e96db2a2L,0x041959de3505521L,0x17eab01163f9749L, + 0x0ff34a46831beb5L,0x153c05a89cbc49eL,0x0418441ec34f125L } }, + /* 138 */ + { { 0x19b1c6202557389L,0x0e74bd6f7e05e4aL,0x19fe0cc3ce0d7f9L, + 0x1e2d9f703d12777L,0x104428fd27e0c6aL,0x0f30c137b2732deL, + 0x047294f7a4916deL,0x1261146278290fcL,0x065cec3b9445bceL, + 0x1de018a6b3f6a4fL,0x0dac90c1e08d48cL,0x1b5f275a63a4d3eL, + 0x10c780890cd78e5L,0x0f22f7f4f93415bL,0x12ebfa9c0570d3eL, + 0x198d826ba9749cdL,0x18c43a378a47e3fL,0x011bb7cbfcb31c7L }, + { 0x06e1ec0ae575b99L,0x065a7c0dcb86e05L,0x00934e9ce51df85L, + 0x03f646b53be0147L,0x1bf629440b4b9c8L,0x0b2ebd468a88afaL, + 0x0f8ef3f4d6d0c78L,0x0f6ba25fd4565dcL,0x0629984a6f5182eL, + 0x121f179e1b2e847L,0x09c244c3cdb9c93L,0x1401fa68a803326L, + 0x0ebaf96dce698b4L,0x11b3aaaa11e27e8L,0x0c95e12982e82b8L, + 0x0c942a37b585b60L,0x0968ab4190a2154L,0x046230b30b5f881L } }, + /* 139 */ + { { 0x1fca2582d1f36a5L,0x1695944a62f96f7L,0x16e10f3b613c3b7L, + 0x05b61c77366b4b9L,0x0719a112290f898L,0x11b16b667075780L, + 0x1f91f43995f90e6L,0x028aa2d4abac4d2L,0x0269e1f778e6365L, + 0x11ef6e5ea8134deL,0x108c0110715f157L,0x06398e0aaf1bd9dL, + 0x131e489eabdb83fL,0x1cafe6da0def7dbL,0x076c00482d9e33cL, + 0x059912119f239ffL,0x162cbebc6f455f5L,0x00aaf53115a6308L }, + { 0x0be2f1f876fa42eL,0x143a4bfd6f773caL,0x03d4e32196bead7L, + 0x09bf00b360d25ceL,0x0b5a7ac916e99b8L,0x031e958675b0374L, + 0x026833b48cd5cb5L,0x1be5a1e4c465534L,0x12529998c3861fbL, + 0x08c4453e0df1885L,0x08a714362ab78dcL,0x16f07626a67b362L, + 0x18ff029708dbcf9L,0x0d41f7c41e53a37L,0x0ca111296804e87L, + 0x095751d209a3095L,0x0c32fe84b3dbcbdL,0x047ab879212c82cL } }, + /* 140 */ + { { 0x0b66c8a2ca9c508L,0x0df6134eb5bc06fL,0x099a23ab5800b71L, + 0x0e93ae4c282dac2L,0x0e472e6f61841b9L,0x13d43b20f207366L, + 0x05e82b68909907eL,0x1e88b73fa679873L,0x1b25e8fa97c15dcL, + 0x09267590974b14eL,0x11cb19f6cf65580L,0x1a56f834f088751L, + 0x066dd027ff8e2deL,0x1f3d15e34a5584eL,0x1c31d8fe26815f5L, + 0x0c4255b17e44d9eL,0x01d4cb268e7c8a2L,0x01e8b8f43d96226L }, + { 0x02ac16e8ce49820L,0x122f1606226e49cL,0x0449cfa1631093bL, + 0x188c64f9f21d8cfL,0x06159c1f918cb25L,0x0a2e59a1f1c3b5eL, + 0x0d1fadadb8380ddL,0x082c9707356ba24L,0x172e09274a300d5L, + 0x1559473440e08b4L,0x003fffadd6a10c9L,0x05946b2241be94bL, + 0x103209f4a30a580L,0x073549c03ff7416L,0x1b8472ad46005aeL, + 0x09d8f7338d8e185L,0x00416105af1ab9dL,0x011a74c7c1a66c8L } }, + /* 141 */ + { { 0x143520814db9cdaL,0x1ee23cb56f6487fL,0x09bebd162db6673L, + 0x0ae87d546308755L,0x01735d813f1f741L,0x02caeac8af0c973L, + 0x0f234d10688b42bL,0x06ce0977ecf8089L,0x12f960471be23a2L, + 0x01931c40ae8eaabL,0x008c2ddac776533L,0x073e183914cf282L, + 0x0c833c910df2e54L,0x032dc26fab58a0dL,0x1c0aded19f2667eL, + 0x0d2a03604a3f443L,0x093de5b52609621L,0x035109871e71d0fL }, + { 0x01b67a04b3ca1a7L,0x176a98060674069L,0x0da24cb3c1eabd0L, + 0x02b84b86b44599aL,0x0dd04d0636523a8L,0x1c9d1df66e9cac4L, + 0x0d4c1cf68d40acbL,0x0ee98bc1879abcbL,0x0ef9f5486132687L, + 0x0c3ff7e0f3a1149L,0x0b0a7a89397b7bbL,0x13e067093e34db3L, + 0x1240f2390508abcL,0x1fc9a1a9d84d914L,0x0bad5419e441cb1L, + 0x170e02054c703cdL,0x0303ee0740996feL,0x01a7837d54e2694L } }, + /* 142 */ + { { 0x09dc79f2348f005L,0x02eb8efa49058c3L,0x1f29b7b992926d7L, + 0x09d0549f69fa36aL,0x1957836621b7f73L,0x143ecb31be5c1a5L, + 0x1b2af24d0406df4L,0x1c62b21f1580725L,0x0280dc3737f75f4L, + 0x19b7a87b530d631L,0x160c129955a36a2L,0x0553b2610e14e9eL, + 0x12fc8895cc80d79L,0x048a49cfb68bd8cL,0x0756e79260e4be9L, + 0x1056b5e6c04fba8L,0x11a452d79e25caaL,0x03b26a3d8fa08aeL }, + { 0x1f22303a2ee8b9cL,0x1b969c2efe6a42eL,0x060c4204e8dc6e7L, + 0x167bce83ead6857L,0x1303bb5be28c523L,0x0dfcd7842bb12d7L, + 0x16cd249bca66ab2L,0x01c437d58101a88L,0x06a523a02d6ba2cL, + 0x18150d8bfe71432L,0x1a88d78c0307ab8L,0x06d4f69526228a2L, + 0x08c0cc89f745437L,0x0076c46f69e05cfL,0x0dff1c01206413dL, + 0x12e709e4d36ac79L,0x01009a1d53a321bL,0x00e06ece191851cL } }, + /* 143 */ + { { 0x1aa1f67c46a7d9aL,0x0199a5f6fc8e67fL,0x09d11e90bcb991dL, + 0x02483ff5528b067L,0x135efe6b6798005L,0x059201b84bcd421L, + 0x047717c184fd7c2L,0x1f8d7645f9ac9e4L,0x0e1b8b2a3a0572cL, + 0x0f075a0bca850a5L,0x12eca4fadb35306L,0x164a8e144bffcc6L, + 0x09a3d15a0a31a04L,0x1f97f6f4d20fbd6L,0x0e52803bfb617b2L, + 0x142b83eb03ebf03L,0x1bcaa3996b09ef4L,0x0296c5f1cd83020L }, + { 0x11536f6fd631a2fL,0x173f859a8d46e5eL,0x031e6c49884a47eL, + 0x1e57a1e86ba34b2L,0x12b0ea7052d4875L,0x1d5c4f4d76db69cL, + 0x064b02f42af72e0L,0x1b504f420c513fcL,0x06566a960102a0bL, + 0x104181be701b40aL,0x1b5e7d618e50176L,0x136db7951bf2617L, + 0x06efdaa3f597201L,0x091b5c494490094L,0x1f0b9ceccdee659L, + 0x11b4623a7c71c51L,0x05d70787f41880eL,0x0367fb1b3ed7252L } }, + /* 144 */ + { { 0x13d0433f89a8bb4L,0x02619c9dcc7b8deL,0x1b200d1c28b5085L, + 0x0fcbb4113d056c2L,0x1bf5fda698fcc75L,0x1e9a662a11aa77bL, + 0x174346217094e7aL,0x1945c41650b7d8bL,0x0e71bbbe1782a1bL, + 0x0cef6984dc2a778L,0x1265e6265fe9aa5L,0x1f51b03e788a2e4L, + 0x1760c1115250cf8L,0x167c22f554d1da8L,0x1fb446f26c3bdf7L, + 0x0c10192673c4773L,0x1e7c93e9c5c2825L,0x00e96410bb09f60L }, + { 0x181347d987cfc93L,0x101ddf8c3fc0839L,0x1274494328c411dL, + 0x01760ab7e67f4d7L,0x1a3af87c480091eL,0x02a055defcaf8d1L, + 0x0116f89a1ddc050L,0x05b331bee61affcL,0x0b398135fb723bcL, + 0x01187c60af5f623L,0x1860c17d558702bL,0x1e99b4c148ffc11L, + 0x04e16d4bfc7c0fbL,0x1a30bf490374ae1L,0x1830839d058d255L, + 0x1c56c72e330d295L,0x122fe2693122131L,0x012a4371b0529bbL } }, + /* 145 */ + { { 0x18795ca53572806L,0x04a24b2b4b470b0L,0x125cfecc8ebacb2L, + 0x0c81378fac29385L,0x079121b3fb15de2L,0x0655ddd4866d396L, + 0x10495b4be853881L,0x08f979b4def22c0L,0x025086261b435f9L, + 0x1b4361c61417588L,0x05b58bc69e472f6L,0x1da2c3444cd8a20L, + 0x06271d74a66b1c7L,0x012143d2133c033L,0x193c3ced7ffb686L, + 0x054e997ca07ff77L,0x1f1d7f7f0beb948L,0x03a8d91ac044249L }, + { 0x197b9d6e9c9be68L,0x05ae233e886366aL,0x10f5dd8acbd05e5L, + 0x1543689c235119bL,0x0aa8eca86d94a63L,0x11ec3ffd85dddcdL, + 0x01d77d2c3cb4325L,0x1136ea60c58bb8eL,0x0fed726ac499339L, + 0x0d3031c2bfce66fL,0x10e4a9d7e31d997L,0x1b2abb8ce594443L, + 0x02b66ecc8dcd264L,0x0c522c5d38027f9L,0x0af594fec6aa6b8L, + 0x1bcf9d52c89bf17L,0x075a9378e802ba0L,0x00a266096e51636L } }, + /* 146 */ + { { 0x13a0a1d2989aa3aL,0x19141acf37326acL,0x032f4cb9ccbb60fL, + 0x0a78796493d2716L,0x189ea6acf4c464cL,0x167e194ba852fc7L, + 0x0e02519f96efcd1L,0x0db937f573a6f65L,0x0f8eb74533b339cL, + 0x1f00fdf1dbb36f7L,0x150953bdaba89cfL,0x1be4f7cc3621662L, + 0x01dd818488555c3L,0x1df38a7cb87db6cL,0x063da4f686bce92L, + 0x17072aebe402f3aL,0x151dc08fc6b2465L,0x043a76799b5c254L }, + { 0x04af83ebbb3f6beL,0x07ddc845da11eb1L,0x02eb5e1cd49fd5eL, + 0x114c5c0884ac476L,0x1e236f79c3659bdL,0x1f93531481d8b3fL, + 0x04b3d5690c31b94L,0x056444a8f5c75aeL,0x1b73890d776eb27L, + 0x0da7b859eb146fcL,0x184ec14fab92b25L,0x0271cfe42e9d3e1L, + 0x1998dbae175b4f5L,0x0228c2403aa4167L,0x1fbc570ada6ef79L, + 0x15e329e4f2ca595L,0x14fa0a3ef2bb6bcL,0x018fdc2c0e72631L } }, + /* 147 */ + { { 0x18306d1615cd607L,0x04fd5551961d31cL,0x016ddde44c75a03L, + 0x146ce11601d0f4eL,0x1445297f1031013L,0x13cdab40a7d070cL, + 0x0fb51c31560ea9aL,0x1a60607397e962dL,0x118a7ca8daaaaf8L, + 0x198acf3ae6db452L,0x039ce348e053ebcL,0x0e311a1e9f3fbd4L, + 0x09dcdff032eb352L,0x1ea419c5d85bb30L,0x17541e996ea3aa4L, + 0x0a16830089b04abL,0x054844a223e4a4aL,0x04c1918000c70cfL }, + { 0x0a2102757f3d5a6L,0x12b24374656e694L,0x006c09547cefff3L, + 0x1f26bd7be32b207L,0x0083aa6eb26cc64L,0x1267a0b0308948eL, + 0x0c6d73662299a23L,0x03ab0387ee7baa7L,0x078c804a977fc62L, + 0x0c3a1987d6e517dL,0x02369320f33c08cL,0x143b4f348e0fee0L, + 0x1f4a915eb5c4122L,0x08091b304d47069L,0x1ab4a828b7855f7L, + 0x1650a8bde8764cbL,0x0aad0a22ade188dL,0x0455df1cf491706L } }, + /* 148 */ + { { 0x04469053a2d2f01L,0x018c9aee3342e5aL,0x0efc75d2809f49fL, + 0x1eb6a1d83ad5211L,0x1f3c2e2601da350L,0x1b77490e9eea2f1L, + 0x05e73d9b84742e0L,0x068fc07211e8e97L,0x119e7c5b998b878L, + 0x1a0e9ff5e9e8ef4L,0x1a3a347bd8166e9L,0x12726ce9c48ec78L, + 0x073e7e67f69b9ffL,0x1774f1240ebea9fL,0x0f66131a6370c9aL, + 0x1d14ea5e47db567L,0x095f95e31b06f8fL,0x0078ada6861e85dL }, + { 0x12f6635790a8d85L,0x1fdd7712cad78c7L,0x1b1892d44a1d46fL, + 0x166468e2bba2b6fL,0x0bc5441d7639b6aL,0x082c19866ea94c9L, + 0x18d8152003a93dbL,0x02643dfaea5edadL,0x1c0b7ffe5192906L, + 0x1452c12f7544c66L,0x16ea488a60899adL,0x036177a0d765d9dL, + 0x004bb6b0cb678a9L,0x057c754c5921b6eL,0x0a816ef3dea679fL, + 0x07d63725a1cdce3L,0x1dbbf8d0471f599L,0x028aed9bc101c2eL } }, + /* 149 */ + { { 0x043eaaa6f5bef22L,0x0934c101a438977L,0x0139e8ebdb1a54bL, + 0x0d351928063c989L,0x1001899a18d434cL,0x07520631f2eba0aL, + 0x01c8548e36ef3faL,0x1d194d991a52cf3L,0x073db6aee04acbdL, + 0x1b49946dbfcc9e7L,0x1e6efeb5178cd2fL,0x1926f83e2c6147eL, + 0x1f9b00a6de8c51eL,0x096c15e1a483992L,0x1167f25279ab2d0L, + 0x09c76b20366da1dL,0x002cb09b7109cf3L,0x016f0243f0d5fa6L }, + { 0x0b722f38dd9d484L,0x049c9be3bdd660cL,0x03c64f64ae2a0cdL, + 0x011c7f584ab1b77L,0x145f4a7d80d78d5L,0x1e614ef82804c0bL, + 0x027e341caffb61dL,0x1aecf57f1e58615L,0x092c567ea9a0820L, + 0x12d5897451d2b9cL,0x0bebafc155486d0L,0x1e4d729d4bd382cL, + 0x143d71e546ee1c4L,0x01f45f0e8f20a4cL,0x07ab82c96060ee1L, + 0x094608922f905dfL,0x06e6813a4577387L,0x037b56038e6217cL } }, + /* 150 */ + { { 0x18822ad4dd6e3b1L,0x070e656b10434e9L,0x0114b2b37a03f1eL, + 0x15508d3fc7cf087L,0x067e8ef2121cc14L,0x1a3a2447479ed3fL, + 0x0c7d36e0f45b934L,0x02e7743bb30f30cL,0x1dfab59770a4c4cL, + 0x18509831f6e380fL,0x075805b363fca07L,0x0617798ab7928c9L, + 0x005760412a22672L,0x1947d77b0150ce3L,0x1faab671c6757c4L, + 0x15f6a4f972d3decL,0x0cbf342530e719bL,0x0371612667fad41L }, + { 0x113024badaf8793L,0x1e67881ae4a4731L,0x1ade54d402fe512L, + 0x0c3a22cecbd340cL,0x1fd93c787991a94L,0x172a4acad6ed974L, + 0x1973c174b00dfa4L,0x0e59628b6313e07L,0x181ae48ca95aa1fL, + 0x01f938109ad3727L,0x1bd68926ca9f548L,0x120005afe546579L, + 0x086c6745b00687aL,0x0328398297be991L,0x037163cf6a2a1d6L, + 0x0230b7c7171085dL,0x1916b48bf34dbf1L,0x02d7bfe86cbe047L } }, + /* 151 */ + { { 0x1f9b950f4a224a5L,0x022ba6628139d2aL,0x0cc190fc7f55064L, + 0x161ca1ef0669f02L,0x09581712996801bL,0x048e9b4336ba01cL, + 0x1bf9f6e69017690L,0x0d1e3c6f3be2d48L,0x08d04a93f83bf91L, + 0x126419a995905e5L,0x0cd2c7dca87042bL,0x12efb032bb6933aL, + 0x1ffba14b5d8fbc9L,0x1b6d7a3b65759efL,0x16dcbd183fbc089L, + 0x160c497291bfdb6L,0x0ae5185c925b6dfL,0x013d4e1c0cb04eaL }, + { 0x1c37346f12a93afL,0x1b83e2a9b31a6b9L,0x035526064f440a2L, + 0x19de436d3b1df4bL,0x0788a0e24f83a5cL,0x189e4c02e5d851dL, + 0x1e130040c5e0596L,0x1e5fd441cb056e6L,0x1df9713a0e50361L, + 0x0a24d07e866116cL,0x1d4b9df178b86ccL,0x0d7b6ce0899e306L, + 0x15733e177a6e44dL,0x047716118096ef4L,0x17c6525a2d259a4L, + 0x110dfb3760a823eL,0x04495182c716acdL,0x00e34834a7def49L } }, + /* 152 */ + { { 0x1b67d173a880026L,0x07850092ecaf92eL,0x1544fdb2de92271L, + 0x02b977b94a520a0L,0x172bcbd33eb231dL,0x0ad01d7c67fe4ccL, + 0x1f0bf2d3bd352b5L,0x14b289a8f94450cL,0x196d885480ead1aL, + 0x152be7c65e45822L,0x16112c01795681dL,0x1c323a31412fbfcL, + 0x0852923c745e9e7L,0x1faed99ccabd137L,0x0fb43234219ede5L, + 0x1a4784aa6811cc7L,0x1391596e5d5689aL,0x03dc609eb528261L }, + { 0x1c43aad52fb6901L,0x189fc8b65129d97L,0x0c29456ab718700L, + 0x0cfeaefb8428eb0L,0x1723c0ddc93d192L,0x1cfb6d137297477L, + 0x0ddb4bc783ae0faL,0x07332f3bd05e300L,0x143e28ecbb08349L, + 0x116a8ee51ce1c73L,0x018ea6a38fdad66L,0x1474973664e0dccL, + 0x02d2f8915d4cf1dL,0x08283c893729a45L,0x14e0fe979d78f81L, + 0x1f6535dff9cae41L,0x0d01d6d53cc8fd2L,0x0071e1f7b34b7a6L } }, + /* 153 */ + { { 0x1c337c121ee1d83L,0x047b6bc3dbbc41dL,0x1f304e3e933a5f8L, + 0x0f40691cb17ee13L,0x055e672dbaf7764L,0x0f62ee827c5d5e5L, + 0x048603b4a4675f5L,0x15f19cc97fe67d3L,0x0ac09fc5724b059L, + 0x03418fcee2f195dL,0x0899dd196bdaa54L,0x1ccd92fe3ff04d4L, + 0x16bc6087fd3c5efL,0x15476e358a8af06L,0x1e7b4a6c68e717aL, + 0x111707bb02d761cL,0x11c6cc13769bc37L,0x023184c71e04952L }, + { 0x06408c7c8bd0fa7L,0x12188e735ef249dL,0x0420a0fbdefb45dL, + 0x0f336bb271c62bcL,0x05a49a6b8213cc7L,0x14f268d7bf8ac0aL, + 0x1275b403f6c3f94L,0x0a4aba71eef9ccdL,0x0b4f7ccc01bd4b9L, + 0x0cbada4d7b8fcc3L,0x167f2f3593402a3L,0x0a094b4775ae256L, + 0x042b5c89f11860eL,0x1d1f118fb6cbb02L,0x032ea4bfb431965L, + 0x1c23cb02298662fL,0x05ae2e74c066698L,0x03fc7e849d1a45cL } }, + /* 154 */ + { { 0x04592cac19428afL,0x10e409d184332f9L,0x004b8c2ef5fc64aL, + 0x0706d8d77284b13L,0x198e498710db072L,0x16b7a5ce3d20f4aL, + 0x0b1122bfc5e79baL,0x07ce1f1f372eb0cL,0x06b3b02376f2198L, + 0x0ec1f4dcc7328a9L,0x149aa35d4486289L,0x10353ade3b4c765L, + 0x05a5a81f7495082L,0x12343a38c6fbc68L,0x01f63335e7b9567L, + 0x0d92a40c194aecfL,0x131427a84ffa847L,0x043db2628f321a8L }, + { 0x1f46f654b30d3c4L,0x0262e11da778a43L,0x1d998f2935a337bL, + 0x139e7f6adb676e8L,0x0fd7d46a1df3426L,0x14d45eea789ce20L, + 0x15f4a8edf1f1da9L,0x069dcad6993975bL,0x1b28ff342ac9423L, + 0x0237efd3c378ed1L,0x145272dc0320b80L,0x1f02a12ccb2f9cbL, + 0x09fcff4bddca30eL,0x024929342251030L,0x0087ce03cbd979dL, + 0x177a1cb6caa59a8L,0x0f577ea9c2a042dL,0x0464a933e6ce031L } }, + /* 155 */ + { { 0x055032e5fc1abb1L,0x0d7aa097f23a1b3L,0x1580a7c17bd4885L, + 0x0bb83237d3facaeL,0x008639b0b0e7332L,0x1f3339bd59e32f6L, + 0x155559d41fd4470L,0x15ac717df8790c2L,0x15d0188cf42f0c4L, + 0x01d180e6c4b0c36L,0x180fdecb19d07a1L,0x1819f479a3a008aL, + 0x1d4a40672ef7545L,0x02dcf46efb0957fL,0x048b5d15865f27dL, + 0x0b37f68a646fb0fL,0x016bf132e3a4b2dL,0x0457d0db9dc2535L }, + { 0x13596eae793ac70L,0x077c7777b6e8835L,0x1e89c108b901325L, + 0x1dd3cbaec724d69L,0x1512aadfc8c71dcL,0x01cbaf9a97e5b87L, + 0x0ec4c6dee84e2a2L,0x1a2af3227200b18L,0x19692092a97740fL, + 0x0d6ca2d8b05834bL,0x0d0e20420deac86L,0x0389e2e976e378cL, + 0x01ab1b80eb76ee1L,0x187622c53088dfeL,0x0b4cc96f20aeb21L, + 0x15b91ddcc024e62L,0x13cb4118b1ab240L,0x0339088c895ad04L } }, + /* 156 */ + { { 0x1e99306f55cf9bfL,0x029845235cb6cc8L,0x187679e9977e6c1L, + 0x038e6379775c783L,0x04d58a61453cb15L,0x03a6610a5f2913dL, + 0x00358e76b248a5fL,0x1be9a1ef48b045cL,0x1afeb1d51c62b03L, + 0x18ee1d25d50c596L,0x11c5e37cadd3c2eL,0x114d12d6d466fe7L, + 0x141dce055ffcd32L,0x152715c3f4af6a2L,0x16773a65fef1dadL, + 0x0cf83cbd8cfe3f4L,0x1fe052368accc03L,0x03e431c8b2a7251L }, + { 0x1e94b5eca7388cfL,0x005306019ae9c2aL,0x1e2d85be16e85f3L, + 0x1e2024530136d36L,0x1cfd0a79705d02eL,0x0f71a92b2d37400L, + 0x076b7add2a5b5f4L,0x01eb91065da84f7L,0x096ea8528e6d533L, + 0x06c43158c692774L,0x0e3b567fe4e7dccL,0x1344020c04a539aL, + 0x182303b3ff690fcL,0x0ea95a34e316c45L,0x0b4b64ff10b5e93L, + 0x008700df1bf4519L,0x1ad502360906092L,0x0192c13ac7e742aL } }, + /* 157 */ + { { 0x120e45f359e8c60L,0x1dc529b2650c375L,0x01c77fe384431c6L, + 0x069927caf00562aL,0x1829d0d8074e91dL,0x1541fd601937005L, + 0x08278f064896189L,0x10470f4c9abf653L,0x1caaa3d34e5ac5cL, + 0x16b42f2d6d16d14L,0x08099faca5943a3L,0x1632ec7005e724eL, + 0x0edf6b1aeaf7184L,0x12f3092e91faee8L,0x01ca86af87e8d1cL, + 0x1875fac50ff3a19L,0x05649aa93d2ac57L,0x00d273538aded3bL }, + { 0x0126ede554d1267L,0x0a2998e6815a40dL,0x013338c7ec74dfeL, + 0x1612fb8025ae15eL,0x16c7b6c5cf410b0L,0x048842c9870e8b9L, + 0x18e3e40bfb9071aL,0x1be6937494ef3f6L,0x0a16c5821acd6f8L, + 0x19dc1e09703b567L,0x140cef94074537eL,0x08a441e5a5b4d71L, + 0x0d99df18800593dL,0x0ff599d31ba9293L,0x1bbd15b28c8d472L, + 0x1b915b22687783eL,0x032c74857db35b9L,0x042b53e49c2da74L } }, + /* 158 */ + { { 0x007d0020d0a5583L,0x180eef6d232c550L,0x0590d364e6f8bc4L, + 0x014e18106d2380fL,0x1e81e540a0cb678L,0x05645c605a6fcadL, + 0x188e5b2ef34d175L,0x16caf8a5da0a8eaL,0x1cac2dca41805ceL, + 0x0af7355bc9a212aL,0x17bcc493268a9a4L,0x0c5f18258ce86cdL, + 0x1b7dbb7c3bbd3b9L,0x1115dcadd55b278L,0x118edd0f039154fL, + 0x14c624811fd7589L,0x0403ca773122a4dL,0x031444842631b6dL }, + { 0x057fd538cb8d208L,0x1c004aa1f836a52L,0x0553cbbfcaadea3L, + 0x17ee4a2fcf6cdbcL,0x19389d2cfddb28eL,0x0dc46700a4ff337L, + 0x10fdde7a1dcff61L,0x1808a5c1216174aL,0x1deb9b5cfb0b03fL, + 0x089a245362f6bbdL,0x07cf3e3ff00dc8cL,0x08dab83698946c1L, + 0x138fa59be92bc9cL,0x06d81348f3379dfL,0x07e23e44e5afd7fL, + 0x1bfc7e3d8b3a801L,0x158c29034562ad9L,0x03cec09162d6d26L } }, + /* 159 */ + { { 0x0d4e4ceaa529507L,0x1040a3a32ae800aL,0x08e13c3f11d015aL, + 0x146887971d81a61L,0x17f1728d8a8203eL,0x1077a919e317d84L, + 0x074fa28e373f6d4L,0x0a141f21abaf959L,0x128a7b0bf873ceaL, + 0x08ad71d363620e5L,0x05c76a84e04b074L,0x174ac49aa0fd46aL, + 0x097e98f42f25d4bL,0x0b5209b8c8ed694L,0x0796ddfff5ac7a6L, + 0x1ee0fa8d8424b6dL,0x17ac7d2b42420c4L,0x01559d7cac0a12aL }, + { 0x0ca074c6a5372a6L,0x1dc1f2b1495d3c3L,0x1b71ddd073d5ca3L, + 0x02a41de93ae8ab2L,0x01e4647270b4ceaL,0x1c562e8a397f1a3L, + 0x101c7d35af598feL,0x0c28dca59938217L,0x128794efe371a34L, + 0x042838c13b7f43bL,0x155dce6fbd6ad29L,0x13fe7e2b902bdb5L, + 0x058f8395c324c2dL,0x005b542a8c44a87L,0x0200f86eb90265aL, + 0x04bdc9ea7c45915L,0x1caaf233f61039dL,0x003ed961a928204L } }, + /* 160 */ + { { 0x1f3b8db037d4703L,0x1846fe2fa445ce3L,0x0c3e11c7500ba0dL, + 0x04b45f55d23f750L,0x1404fc1ea55ee8dL,0x16ab28e172df882L, + 0x1d7e591f5409ea8L,0x17e6f4a7818fd75L,0x07adf0bb295b30aL, + 0x13170ff6b2649ddL,0x1063038bbd29e16L,0x13b29a59a09efffL, + 0x175ea0af02139ddL,0x07f7cd67929fdd5L,0x1856a9df20403a8L, + 0x040d2e98a709b90L,0x159cb28682d9fe5L,0x0045b6547e7beebL }, + { 0x04e5bea036c3b5aL,0x130813fcf95a5f0L,0x15c0a5e5f03ce1cL, + 0x17050f3d4753f94L,0x007f0ddf1656180L,0x1870438a99c4ddbL, + 0x1ff1e668488f19eL,0x0321a3011d93b12L,0x09470711a916edfL, + 0x07a97958390b88cL,0x0ca7ff462222dbeL,0x058a998df200bb1L, + 0x05eb24877fef1e2L,0x1aa3ca92e201b0bL,0x1851a2bf6a548ccL, + 0x17411ac454842d0L,0x1d25d043b0774faL,0x01619bd810698d3L } }, + /* 161 */ + { { 0x12305bcea22fa65L,0x01f7a68acfb1d3dL,0x01f4fcd648fef86L, + 0x0d823aeea668e7bL,0x0a054cffb27fb30L,0x0c2b0cb8173f359L, + 0x14714f3a7e5f2bcL,0x0b706aa04869cfaL,0x1a63e3d82f356acL, + 0x13dbe556bb22898L,0x179abe99c7f2761L,0x1dbc560f9aefdd0L, + 0x10ffda51933b985L,0x14a16e1b03eacc5L,0x18862a6c43b28e6L, + 0x1ab942fe7b9dca0L,0x1c93d94e8d106b7L,0x0284d931a76c418L }, + { 0x1b9414e48caed54L,0x1c63665fa8f4bd8L,0x123537a6c961de9L, + 0x1923dc7af148d11L,0x030ee64c0024137L,0x0c86bc5347c91a7L, + 0x1a42d5cc956f220L,0x09883d1c0bf7500L,0x050038d84ec354fL, + 0x0c7816b6fd2940bL,0x1e401f32d8ff6acL,0x01f7d315c8ab88fL, + 0x025d0e319d29d48L,0x0136db8ca5622e9L,0x0d61ee741bcd5d4L, + 0x0ee4ee6773c4058L,0x152224839922c31L,0x00ac96ad3aa5dc3L } }, + /* 162 */ + { { 0x178d9a2cf7453f0L,0x1c4cd76c1e0f82bL,0x1b4f82a0ae9ebfeL, + 0x15d47aa1035cca0L,0x010aa38b32c84e1L,0x1be820cd6a94604L, + 0x1907ec7f6c082f4L,0x1ecf1ad97c3a0d9L,0x0d287f0f02e74b7L, + 0x0e692bae21dd811L,0x03cbcfe069c6cfdL,0x03eb8c67cfe8da5L, + 0x1cc4fc580ee65bbL,0x1dbd83d29972fe0L,0x12abceb35554e7eL, + 0x05a5b6b5288e387L,0x17cb958bdf44cc2L,0x00b0a5edebbd13bL }, + { 0x01f0230ed0ab04dL,0x03d803710417526L,0x118f10b16d7eb8dL, + 0x1fbc03326b3e217L,0x05dd0825b0539e6L,0x076d0b6c4dea73bL, + 0x128ca48983fbeefL,0x0bf1554eab9cc55L,0x0ed762fa95ec82cL, + 0x0f326008c3283b4L,0x15891724b8d2326L,0x14ee63d4dad0afbL, + 0x0b07b447360db88L,0x0b8eb87f7780095L,0x1e246c2e4d5ae50L, + 0x04145cd160c5007L,0x1283a54a53ab79cL,0x0244b2b63d80583L } }, + /* 163 */ + { { 0x03649ba71353c25L,0x193d089fb3f1272L,0x0ce8707ae78d45fL, + 0x18f1c537f2217a6L,0x0743f15d94e1c05L,0x0d16f8427f3ecbaL, + 0x0ef86721d242243L,0x16304807f4ea6ceL,0x17ebf5db41baea1L, + 0x1f0571a920c0756L,0x161cff0bd430ff3L,0x15ace0cc39b23a2L, + 0x19a51e8c2c16851L,0x100b084cc014b46L,0x09fa95b9f46a737L, + 0x18930562a791351L,0x1cb6d41b78906e3L,0x00415d974eb3b4eL }, + { 0x180ef46c4d6615fL,0x14ee080dcc14e30L,0x1b003ec9932bf18L, + 0x0c21d98589bc445L,0x1eea2c4dc5457e0L,0x0e2d964ae72ccf8L, + 0x043e410cfe9ca3eL,0x0a7dc06a8c59ac6L,0x084c57c3bce2e22L, + 0x047618d4b6c3f22L,0x1f8e4e914b169dbL,0x0281408f646a617L, + 0x18c018545ec592bL,0x0e0bc6233dec5f0L,0x08c016de538041dL, + 0x0a9e6908e328c5cL,0x0422665e237622aL,0x01b228d23480e48L } }, + /* 164 */ + { { 0x1802d1819893e71L,0x12ec5a9cd10410bL,0x08048c0bb3f285dL, + 0x166cb7eb3bf8d5dL,0x0d232a808d4cf51L,0x140213c3ba0eb90L, + 0x0e7b2b0d0facc63L,0x194aa7d965fce8eL,0x0aeca79a81a8b07L, + 0x04ff9912b7a559dL,0x175ca4fe8747dc2L,0x135dec55342cbd2L, + 0x12aa08ddc226056L,0x0dbddaa52f3bb11L,0x0f55b9e4feafb0cL, + 0x17dfe914412ace8L,0x0f1749cdb12eb0eL,0x0382983d234dc7eL }, + { 0x08e4c04e488310bL,0x137192992e6bdbdL,0x02c1260fbeb049cL, + 0x1805bb7226ba1fbL,0x17b9685c796e552L,0x0f9251877651fbbL, + 0x125e66dd9ba26c5L,0x0d8f84e6dac91dfL,0x03d619685a8021cL, + 0x119f13c505978f5L,0x1a61e6d9db5ac3fL,0x063235e9c17d2b8L, + 0x1136c4ee55a0747L,0x0cf2f9dcd17d5afL,0x12bf9b9a4e2e3fdL, + 0x1a2403c229b4873L,0x0ecc9595ec36a6aL,0x0407bcde82bf315L } }, + /* 165 */ + { { 0x0ef42a760af09b3L,0x0b75ec99eff0a1eL,0x0783b617aaa0f00L, + 0x1f9d547792e419eL,0x17106f97d4f5e99L,0x134569390b5ce95L, + 0x1947d97cd30db25L,0x1bd51f70578b618L,0x020f42f1cf2fda4L, + 0x198d596690fb2cfL,0x1ddb1e84f45863aL,0x004470cc57cb6f4L, + 0x10cad08e0bec441L,0x011600c06412ed3L,0x1be7ff664a641e4L, + 0x116a0ec477b4055L,0x119de84f4f3f5c5L,0x02fad2ed26c127fL }, + { 0x137257e7e8311dcL,0x0a7a8a336789b2bL,0x1916c172886b7beL, + 0x1805c9566f4e7c2L,0x0579165b38ea9b3L,0x0580d23bb07564cL, + 0x156137ff7411f09L,0x1b4311a9fa27f72L,0x0faac38b825548bL, + 0x13cd3782cf4ee56L,0x1dc83c2689c03c6L,0x0aa9f714fc91307L, + 0x0847a1fad58cbbaL,0x0d5eb5af1c50ccbL,0x1c5bb084615951dL, + 0x120f6ea227a63e6L,0x0891391e7814212L,0x0298ce40086e0acL } }, + /* 166 */ + { { 0x120136e6b61c3afL,0x0796f03da5db411L,0x19fce0325fc0750L, + 0x00d5186274ca3bdL,0x0011ca10a978ba7L,0x0fa22d9162c3eb1L, + 0x1139922ee8862acL,0x1f318bd5e0fca08L,0x15549f02a442fccL, + 0x0b23a379ec0249eL,0x093d85e70116449L,0x143157b9110e85aL, + 0x0aded38f8f1600fL,0x091d75a32e5c300L,0x0715e2a92fe6e42L, + 0x1d429ac7fdc6a3cL,0x1f0f3c9c5acebb9L,0x01e8998a6f88d27L }, + { 0x1cc662db4513d1eL,0x05462eaaca95ef2L,0x08ff9fe1b42b79eL, + 0x08f409e18bd146fL,0x0e25d06cca2d12aL,0x09b038a6334b721L, + 0x1872d49851a62c8L,0x0bde9a4e03713edL,0x1aafd617780efd9L, + 0x16b9d6262ddb483L,0x01d2b10836cd6b9L,0x1bc9e4ea3f4093dL, + 0x16a1fa2edd11631L,0x1bfebca6d94fb99L,0x0be4a993101a192L, + 0x198ece79643a7c4L,0x0adeae904e62043L,0x033f9454fd99163L } }, + /* 167 */ + { { 0x017b258ca148ab5L,0x0cbb7d9e30028beL,0x1a6323ca37e6e68L, + 0x09d1a8a02fd44c0L,0x0578a42287b2cc7L,0x1f63991b92b9948L, + 0x0ef120757b8945eL,0x1fdae823f9e3a91L,0x146217e6b487f5cL, + 0x1803d62a0f5c70dL,0x115e9b816803232L,0x1a57a5f3f533883L, + 0x1b40941cad1f954L,0x1c14a84e9b85eaeL,0x1b297bb921e1e70L, + 0x1f73c9826eaa4b9L,0x1b2e8ef7fa4fd3eL,0x02ff848ba0de8deL }, + { 0x11912a4579c6632L,0x0d227dc51040abcL,0x0e114d58e74eec6L, + 0x177879379de9f2fL,0x119e6410e57e2bcL,0x0becd689159f95fL, + 0x1fd987c0627684dL,0x098ceaae776f3cbL,0x1444e5c98ef2f3cL, + 0x17b0f1002688398L,0x08d9beb1d758d75L,0x190c590a9e461bfL, + 0x1e0ad0850b9fc47L,0x17b906196025721L,0x14ef27573a53d90L, + 0x074c6cfdf5ccb4eL,0x046c27d30d3b037L,0x03340809d14b90bL } }, + /* 168 */ + { { 0x185d913e84509dfL,0x05f6ee799c9bb09L,0x174cd08e8523a5eL, + 0x07dd196af25be84L,0x11c4553c43fa0aeL,0x1f8ea4780a9b4e9L, + 0x09128173c22ef7eL,0x0675bfe97cd2888L,0x001635f81a35ddaL, + 0x02e44a4f3b7d5beL,0x1ff37859cdde0c2L,0x0a5944a9f1a497aL, + 0x06413ec985fd8cbL,0x1d481366310b453L,0x18786dfcb6e5d05L, + 0x1ffbc72c5dcaca1L,0x11fbee0a346d3beL,0x01d9adb9785efd5L }, + { 0x1f8de9f535c3749L,0x0f907c56ece245fL,0x0def23e3d98c8f0L, + 0x0bd1e75c9352eb6L,0x1d5e26282529e47L,0x03178ee197886a8L, + 0x0f8d96b034a5d9eL,0x0c4278f26710a99L,0x148f004ef4b67e4L, + 0x11bd0a872e88770L,0x11de374a0a2283eL,0x14cd9f6e7e9a92eL, + 0x130780495296830L,0x0bb05b4a4fa2200L,0x0dd726608cf1c26L, + 0x1f3390681994a4bL,0x0853f62e40bc771L,0x023e850f5e6cae3L } }, + /* 169 */ + { { 0x06f4fff652811f1L,0x05549b177980113L,0x0955432e832baabL, + 0x1400fea8ced870fL,0x002f2673a350142L,0x0e3732e3fe88151L, + 0x18f6576bb95c0cfL,0x03cc0d05d860c94L,0x146cf0bb0462b25L, + 0x1018652aed49b73L,0x0983c90d0996d43L,0x0576d369d1eb90fL, + 0x0c7ad7770a9637bL,0x169d0ad3300fdacL,0x057a5847c851fdbL, + 0x0742c0b68fabc53L,0x05ccb0ca9b38321L,0x047a5b0a524cad4L }, + { 0x0a8ec194b4eb3c1L,0x04d6210191d382dL,0x0c893db31aaa315L, + 0x168bf34b4601a92L,0x0897abbb0e53b9bL,0x166be8723778880L, + 0x0d623fa1cf95f5eL,0x1a2f9f99fca1ef9L,0x00ea53d65c85557L, + 0x0ecf5a239447971L,0x17b7eb03ada2a3fL,0x08e010c07419565L, + 0x0900feb06c58221L,0x12f2e55634a3234L,0x1246ba60133d6fcL, + 0x0bd5db0ab30b13fL,0x001ed9378b173c4L,0x047ca168129264cL } }, + /* 170 */ + { { 0x11ec3028e845808L,0x15ffd5bbd5fe28fL,0x12e7e365f71f0c0L, + 0x087558b2964d5faL,0x074d94dc3d3a83cL,0x12c88e71dba5e8bL, + 0x0b3491192dcdf2aL,0x1fcc524aee70e38L,0x1419f24853b4440L, + 0x0d35079f02956beL,0x0a035a11b21b037L,0x13f5f0649e84c8aL, + 0x0807cf117aa2568L,0x06ee4edbe3a568fL,0x1bf2175589b7a82L, + 0x1d6a6a4c406e72cL,0x0cbe0ad57c3f3b1L,0x01c1801294a4e0dL }, + { 0x0ef5a405e744723L,0x1e7ba8d704240d0L,0x0333fb07ddbf6d6L, + 0x03f566ff8d57f5bL,0x08fedb78fba5d83L,0x09f9885f1cf1246L, + 0x17092973eb57eb6L,0x1eae8ffb63d227aL,0x1052a47c94518b7L, + 0x11046b63e7da193L,0x172e71c394e2fa7L,0x0eb2b762f22d626L, + 0x005b3106c736352L,0x0104dd8351603c4L,0x11412b74b50a81bL, + 0x1c0696a4b68e3a7L,0x1a5c9f4b368822cL,0x00af8c3cb75a0c2L } }, + /* 171 */ + { { 0x14dea060aee4684L,0x10f833e6dede404L,0x0526c64c4c650acL, + 0x03034fb74d4873cL,0x1c2ae80fea4bdd4L,0x011ee163109b831L, + 0x046c6d62c259c4aL,0x108e887aa2b064cL,0x02e16f83113c203L, + 0x071026b15ecc969L,0x16f35bd064e22c3L,0x1a3a3a6ef18e933L, + 0x0fc5ddae73492deL,0x0ca5b12cceadebaL,0x01b29a35204f54aL, + 0x18558323b39ec1dL,0x038562179eaf3e9L,0x030a378f9cff709L }, + { 0x106d33e078e2aa6L,0x17bfbcef74932deL,0x1e076a903a11a4eL, + 0x11373480fdaadc1L,0x0de9951905fbbb8L,0x16dd1cee7a256e7L, + 0x1dd2dfdc7e34c24L,0x1d6ceb6bb4a8462L,0x07456a251a5f605L, + 0x018ea57c3d1cd4fL,0x0c001816d1d2f64L,0x17e56ccb5523b68L, + 0x156631eeb4bda5dL,0x111bbe2c2e8d1efL,0x1742ffc0a0527bdL, + 0x0cbbc5c35e9d2d0L,0x050e0ea087582a4L,0x04aaa1fcf035e80L } }, + /* 172 */ + { { 0x1cbc6f485d7c6efL,0x00426b1d8de127bL,0x1a22fe32e98b2b6L, + 0x0d68ab8325bf219L,0x174fc6ed98e4b68L,0x11003bb0a35c6abL, + 0x094a5c388e279ebL,0x1eaa48388f2c384L,0x17d2215103884e5L, + 0x16906710bf14139L,0x067d453c99d3e35L,0x00aae18023b7c62L, + 0x19fcfb760e85459L,0x0f46150cefd5baeL,0x1f52c9e5518d8aaL, + 0x0d31896da7f1494L,0x0ffa5c87104ee5dL,0x036da1a3c15d14bL }, + { 0x04864935c3f0d95L,0x1edc1273a444a83L,0x1d89acbcf912245L, + 0x0856feae97ee7fbL,0x0f732723c60edc5L,0x1688a65f0e04d15L, + 0x0bfe5f4d19a75f2L,0x0392c8cc0146435L,0x0b94e2bbaed0cd6L, + 0x1370d20ef623a87L,0x1a6436c6a27d621L,0x1ad9e4eb2d27437L, + 0x00c0e0dddfc39e4L,0x0cce452088e7dbcL,0x070c143c2bf35ffL, + 0x18dc99d7ff5b6dcL,0x0944f3981b096d2L,0x003d3c8f395713dL } }, + /* 173 */ + { { 0x10e90471e9f0300L,0x09d6cde66fc8273L,0x0277fc14c1e3809L, + 0x1d5d1268c4a3805L,0x04846845f1ef092L,0x0d6a5a1648548d5L, + 0x19ec8651bb683c7L,0x029e0eca1e667beL,0x1c6e988db0b15a0L, + 0x17063375aa1787cL,0x0d8c478300de3dcL,0x1b555d0d2a1aba9L, + 0x0db35f1c8f548baL,0x0a268d6a3400b1cL,0x11c74c84a78c85aL, + 0x09bbd32a3759080L,0x0ac03cc29f385e9L,0x036b5661722a1f6L }, + { 0x1999e9557b2d299L,0x1e6cdf1eb90e6f5L,0x013eed32d110e8aL, + 0x13b80c1f545cc07L,0x0c987cdeae17770L,0x1b7df6ba787369cL, + 0x1effe688df3e041L,0x108d35e2a26f307L,0x06c3f7a1d323f95L, + 0x110e567b6db21ccL,0x004d3e59c0f648fL,0x131f70727eecf9bL, + 0x1c2e82522207558L,0x1c92553e0dad945L,0x109ea2ade1e6705L, + 0x129243b66f1e502L,0x0eed5a451b1ff28L,0x03ce8c1091e9e23L } }, + /* 174 */ + { { 0x03edff9109d5589L,0x0975a014da24c8dL,0x14c2d2d52b7f7b5L, + 0x0344f7fece27d73L,0x07f0f4604f9214cL,0x1287142640bf73bL, + 0x188deeb7e360f0eL,0x1838bb807932804L,0x15f29581b966647L, + 0x05b5044c50343f9L,0x01f3b0c58d145c4L,0x174ac5cea3115cfL, + 0x0745e2c3fb2001dL,0x1b3e99caaaea70dL,0x1a10bbaff2b37aeL, + 0x0b01743415f3978L,0x1c850590a2b3e88L,0x039882248d3c266L }, + { 0x0ca2cdf2648d676L,0x0f652a78d8958a2L,0x1250a60387ae6a1L, + 0x1235915512373b5L,0x0719e195f30d370L,0x181bcbb983955beL, + 0x19fdae9463208bdL,0x04f58121c295800L,0x10e6cfc708dcd29L, + 0x1ac44f110f3ed31L,0x0a902e0dc71f193L,0x17c51ef0f193695L, + 0x0bd84caf3f1f9daL,0x0f070ec97bc576bL,0x0909370f0e7741eL, + 0x00132d017cbf624L,0x14ff41b214d0bdcL,0x03547c7e4a8c062L } }, + /* 175 */ + { { 0x0a1ed6353235132L,0x119f8acedd445b1L,0x1148a47bf76076cL, + 0x0f64a2235d0ac4aL,0x1d701bd8c750529L,0x1a7a2edac90d7c8L, + 0x1cffed34175ca5dL,0x070dc7a98bde31cL,0x0897d985f899b30L, + 0x14e187de44d8aacL,0x0b468d344c60722L,0x0d744446641c792L, + 0x0201ceed02292e8L,0x0c1f984fe7922a6L,0x03f468c9e917dd1L, + 0x0ea70eb4c20595aL,0x1d7db4f45d2cb9cL,0x023a96c60ed941fL }, + { 0x14d6cead5dff4d5L,0x0afeda2d413fa28L,0x18313f1c4d79d33L, + 0x1037caef1c20e14L,0x18dc6b08dec0bb7L,0x1e124b138f0966aL, + 0x062b2dd94226d52L,0x064dbbe58c6c321L,0x1fd6ebac6675288L, + 0x1516812e1284578L,0x0b36a1373f07c3aL,0x0d508aa217c0278L, + 0x0d1a8868011c783L,0x17d792a29c82344L,0x0c2a23590c4caaaL, + 0x168e092d0aaee50L,0x152569491ca8744L,0x01d328c79bafdc2L } }, + /* 176 */ + { { 0x0a8ed50224042a0L,0x071d8122978f355L,0x1d31da084761b2dL, + 0x13de9aba7fdb94bL,0x122d46e54e0fe3fL,0x0233ba99d471522L, + 0x1406d6663887fc5L,0x072292d8a1deb25L,0x069104c2f83a677L, + 0x03385e5a395df80L,0x020ec940c5def4aL,0x180afa4e25451d5L, + 0x17b439c994c5d8bL,0x0e6d0d7fa0f7c98L,0x0e3dbee60074ea3L, + 0x1f041ad0ddd6ae0L,0x017e80c5cd0fbfbL,0x02a0561b1f6e12cL }, + { 0x11969a9fe7f43dfL,0x09c04160dcf2653L,0x1f621670a45f999L, + 0x0b2d5488095b2ceL,0x1f1297dabaca954L,0x1753ef074ec2affL, + 0x0fe387d8625ec8aL,0x1bf2ddb99fa6de2L,0x0627d307016e200L, + 0x14f839b64c4c452L,0x0979825fc8c749cL,0x0437ec090ea52bcL, + 0x094019b299af7f2L,0x135a58eceb34130L,0x1375e8c76677824L, + 0x02bd3d88f9ecc35L,0x14f4de9f2b36ebeL,0x00bed99767d0b4bL } }, + /* 177 */ + { { 0x1ef69196cf40599L,0x086fd806010753aL,0x19eff2abd9e5fa8L, + 0x0711bbacf07b4b5L,0x055bcfcd0d663caL,0x025e3f2d10fc7f1L, + 0x018cba70fd4e38dL,0x09a6bec563aa91cL,0x1654f242543c6e6L, + 0x1aad3d3134c9b13L,0x1f17dec3d04c931L,0x1ef2744301e7476L, + 0x111e81675b05697L,0x129a147ab67c2fdL,0x14a2c09b4f36cd7L, + 0x1f6f1c7542b22a5L,0x05da8470255f7a3L,0x02305e80dd0ca22L }, + { 0x034dc23c24d8077L,0x05ac0263906965eL,0x0445bd747ffa0bdL, + 0x0124f079c5453b5L,0x15904af3578af52L,0x1508c8714fa8d5dL, + 0x177c11b15c35fdeL,0x0a294a45f74ae37L,0x1bf4e2a06ae89bbL, + 0x0cd9ae62cf9a226L,0x0a0d9c9b30955deL,0x130b5f9d82ef860L, + 0x0b7c36cbd094a4eL,0x1ae9c83bd6d7beeL,0x0f892f3b4c6de1dL, + 0x08436a5ad209e5aL,0x18dc5ca26691f95L,0x03e9a161e0b9a43L } }, + /* 178 */ + { { 0x1cf2c0a11fd127fL,0x1b5dc08cf262f72L,0x0949bbd5ab0d9b4L, + 0x1dca860ceac4356L,0x0c3e961930cfeaeL,0x1e7338976f13e95L, + 0x130f5904d44ebe3L,0x130c2b38c360ebeL,0x1d447efe959069dL, + 0x1c6b7b4753b5754L,0x17186c3d6f4592bL,0x08dc3d11773158bL, + 0x161ba92320dbab4L,0x1c4c4c32b0c5c58L,0x02dfa0a83abecf1L, + 0x0c17618f5798581L,0x1a710f09b6e20d1L,0x02df057d3472631L }, + { 0x0ab6d381bbbf49cL,0x0e724c60381ff41L,0x0d77843d098cf82L, + 0x03b4b48a65d94b1L,0x1618f7b7d9cc658L,0x07bff383f0c43b7L, + 0x01af81066978c94L,0x0d376353d21bcd7L,0x0584a7deb373591L, + 0x0759a44a8a4ed96L,0x11a8cec3aeaee0eL,0x016185f1152428aL, + 0x070a2db0190067fL,0x031f379f5ef06ffL,0x081beb6e946c1b3L, + 0x1b81543224f73d2L,0x0aee4eb5e87fe80L,0x00f37e67aea6f18L } }, + /* 179 */ + { { 0x17dff66aa8ac924L,0x0d698e14c59f45aL,0x0ca597ec20301baL, + 0x1a3b2b927fa281cL,0x0a180caa7dab211L,0x06f6b4b6b46c214L, + 0x1187c6a4a502288L,0x065502a2ea671beL,0x1ff5604ae60eae9L, + 0x00dcf24bed72605L,0x0ea5ff7898ba264L,0x1349e21093068aeL, + 0x0f64724f1ded69dL,0x1542d0afc7fd011L,0x114de5357c70b93L, + 0x00fba98c4d9d202L,0x03780440cd6bf09L,0x022916a30aeed54L }, + { 0x095f079ebfbe7c5L,0x10ef6c2779a2344L,0x1adb5286ae58c3aL, + 0x04a14618d0e2d53L,0x0043bbaa1a4a5d2L,0x0872faad0b318e0L, + 0x0155af441d40940L,0x0337ffc7d3a7b18L,0x131b30b18077724L, + 0x07fbf78425c114bL,0x0df5d7c868630e4L,0x0c6aacb771f0018L, + 0x0a45e3bceb18d0aL,0x11f85846dd60ed1L,0x0f16b1470e3a430L, + 0x03f8de3743544bfL,0x0ba09d5256bdda7L,0x01a3280d4b6bf20L } }, + /* 180 */ + { { 0x0be448ccc2b0f1dL,0x1a2e4d6261b81c3L,0x19767f25aeff8faL, + 0x12b5c4ffb4a70feL,0x1bc18089cef3c4eL,0x050c50d0047bbb0L, + 0x0cdc7cdd282108bL,0x0a9dd105084a76eL,0x1cb6fc6d87cc093L, + 0x044f60db0a4b6b5L,0x10a6e5278c97121L,0x14a4f7bd82cd525L, + 0x0edcea281315c6cL,0x1d108aa7caa2277L,0x041873cd1a0faccL, + 0x081771f64df31a7L,0x16dc3b08aa806c9L,0x03e0ea167f2aa64L }, + { 0x06e703fdc110aa7L,0x1bcebf9b171bc3bL,0x1d756ab728f2adeL, + 0x12c17c66e7a4b38L,0x06c4e8ff2a6eca7L,0x1b82dffa3a25258L, + 0x12d4eca10b33bceL,0x1703475eb555c60L,0x17bbfa2011b2d31L, + 0x05d375d25f7446cL,0x1597395972e0e71L,0x0d2db5efd9d05a6L, + 0x07e695974524808L,0x14a7cc1b963e667L,0x0468c9bbf5bacf3L, + 0x1274c1467699e70L,0x19014203f43fffaL,0x0018f4c1439e18eL } }, + /* 181 */ + { { 0x1efecfc765a17ffL,0x19c4468948532a7L,0x111a4e3680e2827L, + 0x1b42d35a8d7e4cbL,0x03a62fe84bb6145L,0x04305299e7c10a1L, + 0x0e31158b7d5c6afL,0x0eb7e5521f502b8L,0x145ba1d6e17eda8L, + 0x0cec40d4a37d2f0L,0x0f9e12e43d68edeL,0x06f9621fea54d83L, + 0x04a4f4fd360910aL,0x07169dd061c60ffL,0x1e9861f0c603f16L, + 0x06b847c5fe0a162L,0x11c3a00059b943aL,0x024a69b22d14662L }, + { 0x18426b64ba021f8L,0x04841bcb6f5b61cL,0x0e55f8db1d8b453L, + 0x14ea39e42cda5caL,0x19b24a198f556ecL,0x1061576d650f000L, + 0x09ccd1e21f6912cL,0x1af27da999bfe83L,0x18d717c445c7c0cL, + 0x02431a548dfb804L,0x051be4ed66eebf3L,0x1673cac49e2b43eL, + 0x0d303f8443dd38bL,0x05f8827e4b6a0d5L,0x1c19609ad9c3c0dL, + 0x001ea0a07f3da52L,0x0f3768e1f47b342L,0x01e7ee62f5dea63L } }, + /* 182 */ + { { 0x16c2a86b523e13dL,0x0522c1490685029L,0x11e39d5c4a58405L, + 0x0cfd6a37d47aa56L,0x07b0e9190574606L,0x144474384fbc30cL, + 0x1f3500a2bb621a1L,0x1e6f35013afb295L,0x050c6032fe2129aL, + 0x0f25f394c1e2041L,0x0c6eedeacefa39dL,0x06596c318e51306L, + 0x013f59c4a4d31a0L,0x16a7b0f11b6ec2dL,0x15c5c576fb38d17L, + 0x1d7af74f5599a3cL,0x0a1138c58da64a1L,0x04494b6879e8d77L }, + { 0x165288fcca82c97L,0x160968a13f46e58L,0x1c1d30fb76a49b1L, + 0x1dd5403d7ccd529L,0x10f5e86d94600e1L,0x02b5188a55e73e1L, + 0x10b09d075c0832dL,0x0d1560b54264f3eL,0x070b60fafd42384L, + 0x0c77f6098c69cf3L,0x1fc6b22482cc628L,0x1751b0733c07d60L, + 0x0e3c81a30101e3cL,0x066333ec32fc499L,0x1a181f2ba2f29f7L, + 0x142599dc35cf344L,0x0543182e64ccac0L,0x04919d17b958d26L } }, + /* 183 */ + { { 0x17e8df60acbee17L,0x0ace12e127e6e38L,0x021f953ff2c03c2L, + 0x15a50a22d68de13L,0x1ba1fa51b993decL,0x190c1f05fd527c5L, + 0x1dde6724927bf43L,0x043f27966b12d08L,0x1284bfb7f2322d4L, + 0x066384d6a157804L,0x1c89d26ec758550L,0x1674e2f878d58d3L, + 0x05bb9c5eeb76f50L,0x123c1dafc590f4cL,0x1870f9d63ec66baL, + 0x035900990d736a5L,0x091aca59092f297L,0x015d9353490f6c1L }, + { 0x0a3443515f81416L,0x13973d57fadda4cL,0x13780c5c987021bL, + 0x18b81439fc7a3ecL,0x1368340131c0786L,0x1cda66aa17526c5L, + 0x09fc4bddc9ce868L,0x1b829fcfdc397deL,0x1ee7fc09e16bb27L, + 0x06e660ba0872ee3L,0x199d08650ecf770L,0x16c07e63836f468L, + 0x19c22c107092934L,0x1ccfcb3580c36f6L,0x06c224e8dfba2e9L, + 0x1a9bc1e77f96849L,0x108bae614472e92L,0x049be59fc70cb75L } }, + /* 184 */ + { { 0x1c0e77c16fbfdceL,0x1a664e4c6a6602bL,0x15c9095cb483a80L, + 0x1800335079cec0dL,0x115971629861b55L,0x107ebdc05d1401fL, + 0x0aa883d05077416L,0x1d910cb2276961bL,0x0e6685746aa3848L, + 0x168ad2d1f0242e9L,0x031dd0eda417745L,0x16fb0315e575038L, + 0x14d2b74b78cec31L,0x0a1f1794406c78cL,0x0c1f073299676c9L, + 0x09180637074fb3fL,0x01186537fdc1f10L,0x026abdd83bc2c35L }, + { 0x04b768a53b396b6L,0x1926249da8ed65eL,0x07ae8c2b86cef22L, + 0x0b28a28f8a67ca2L,0x179fe3ce893bbd9L,0x0905ea366430188L, + 0x18580d2c2859cfeL,0x107665225d6d64aL,0x0bc69a2a49d168dL, + 0x04a4f3d7786e894L,0x0d066a1c9a6786dL,0x08ef7e426ed64c2L, + 0x09a4f9714706c58L,0x1dcdba2ff2ad8c8L,0x17cf2158f5badd5L, + 0x1f5c76a6cb65211L,0x0a80e257e4355fcL,0x00833e08c4bcf95L } }, + /* 185 */ + { { 0x045508432bf8883L,0x0943537e83333e4L,0x1e3ddf08cd751d5L, + 0x145e945929ae161L,0x1118acf5678e60dL,0x0dc86cd2346c566L, + 0x044133a4e0c2efdL,0x149d49638e9da9dL,0x0ac67316d27776eL, + 0x0c56bae1b0dd589L,0x0f520a64489146eL,0x0440a614875d864L, + 0x0e3292d5a526440L,0x0ff678de1d22299L,0x19ee2e36d21a52dL, + 0x0d5bdc9c0a2dd8cL,0x125b3aa595fa430L,0x03f27b848f9a74bL }, + { 0x13816e9b7f70919L,0x10b768b5801fa9fL,0x1fd1de326795d94L, + 0x10614a30208d8d9L,0x05e728dbe6a5abeL,0x0677eb77b7a4f32L, + 0x1cfddbf75cfab2bL,0x187d8729cdf186fL,0x173320802b6407fL, + 0x04747bd4b312e5eL,0x048d8df2afec026L,0x13be80fe6b35065L, + 0x05ccbfae50258baL,0x1f128c09ff80d77L,0x1c72e87efabab3bL, + 0x19b6b38d3e2c307L,0x0bd512c58ad9eadL,0x015724e6a366674L } }, + /* 186 */ + { { 0x039b0e3c40849f2L,0x15266d22084c609L,0x0a67951fd92544dL, + 0x08f537758cc2a6bL,0x13547af692e4bdcL,0x03d3a50cad0b232L, + 0x08aca17b2cc662dL,0x05a4f0aa7f93bcdL,0x1471c038a0e2ba5L, + 0x15d0dc41ade5d49L,0x1d4369bcc7b2884L,0x07ed0056658da97L, + 0x113c64c8c4d146eL,0x1769094b864e009L,0x1a14c3eb4c3c4b7L, + 0x1bca336eb7ff738L,0x1b723c0ad3e8918L,0x00c074ea9539bb8L }, + { 0x116542f29ab77b0L,0x08ece7bd7731461L,0x1a14d4f0bd03750L, + 0x089615c99e08980L,0x15fc266f638dc7eL,0x17f5bed04920c2cL, + 0x05e618e7699c7f4L,0x054ad0b1daabd47L,0x17a694f3158f383L, + 0x0a119e3698b6c18L,0x0b2c98c28d69eeaL,0x0fbbe3fee2765f9L, + 0x0559eee2f3fef8fL,0x0ab6832545cda29L,0x173f3f346d3e46cL, + 0x1d6822ef0cd845eL,0x1b412bc25663777L,0x010e5379e6c55c2L } }, + /* 187 */ + { { 0x0162b13a3e66635L,0x10515954fbb5787L,0x08c11b6ccd587bcL, + 0x0ef005771b568e7L,0x0699b44c0840bd7L,0x1103f8adb5d7af5L, + 0x004171b8464006cL,0x009cbbc2d52f216L,0x122b12f15db67f0L, + 0x02fd6a2c5012e92L,0x1da54f7c2845086L,0x0537e8a06981799L, + 0x001c277bff4c421L,0x14054f0c07ba020L,0x0aa8ad1b9102d30L, + 0x1b29eecfbd1eb08L,0x0353de20ab805e8L,0x02d7fac2c90113bL }, + { 0x05acd20a8458e40L,0x0abec0a4b995ec0L,0x04c57c729cb5695L, + 0x192a56a6478e0e8L,0x0494fadf7f2e269L,0x1e93332e2c92ab3L, + 0x0a19454edeb3469L,0x0d74dbe0c7b0dfcL,0x11e91db1357d53bL, + 0x0caddc4f49f5680L,0x0786bca58eff9a4L,0x1385104f110c7aeL, + 0x123b859b6ffab2bL,0x1b814ee8bbc1b34L,0x0611585b9a545d3L, + 0x1b0938f30f0ecf7L,0x17764fb4f1d5907L,0x01f55bf0e446c54L } }, + /* 188 */ + { { 0x13a94b652e5718bL,0x17d2a7a6770f4e3L,0x198d54fbb7ab8ebL, + 0x16be759434ca9d3L,0x0d083316f2541e1L,0x1fca876b894a448L, + 0x0f929e596bd8fedL,0x179b1f93c1b8e9cL,0x0b4ee48d2eaf79eL, + 0x02c543545bbc3f3L,0x1d887fdf33abc29L,0x1dffbecf301bb18L, + 0x02f91067278228eL,0x183f1b149086a3aL,0x1c78a7647d8d406L, + 0x1714a882ec38cf2L,0x144c0ccc65f03a3L,0x01a48ed279c704aL }, + { 0x106d046cb062eaeL,0x0db9aae843bb6b3L,0x0148a48c574bb9fL, + 0x05880577b701bd0L,0x06ed33374078566L,0x0b4769afc9a92e1L, + 0x02c79b3a85359f5L,0x0eb22d42312cd11L,0x00fbd52055dc716L, + 0x19e883bf22baef9L,0x0c402bb0248cd60L,0x1a02d9b0a7129d2L, + 0x05432263682f9e1L,0x0dd267ebf75e9b9L,0x13160e100745cacL, + 0x02fbc6efb573aaeL,0x018aeaa695880d5L,0x006421efeb568adL } }, + /* 189 */ + { { 0x15811ffc9373300L,0x099954cfee18022L,0x0070d4f2d95470eL, + 0x152d507a4fc3377L,0x12ee3f1a774b924L,0x06ab63e5fe47e5dL, + 0x0bde6bc9e3b1004L,0x17edfbcd05fc157L,0x07566d0727339aeL, + 0x09ad6aeb8902edbL,0x0f9a51c1472742fL,0x0901a7460cf96b7L, + 0x14572d7530577dbL,0x1036c29e96387faL,0x0afed77a1856bb3L, + 0x11daee33339960bL,0x169eeefc96bea0aL,0x016e6234e9afb6fL }, + { 0x0a6cd06c65f0e77L,0x03cc05eb8d8a566L,0x1e2cf24f3003773L, + 0x075d197eaf6c443L,0x16f8e63fddfcd5bL,0x10995bde494b9fbL, + 0x1278ba61228d01bL,0x034998b3407aa3dL,0x19c9d32bb3a3308L, + 0x009082940742335L,0x000ca86ef9ca540L,0x0ae449270891856L, + 0x0eb6bba0ffdbfc6L,0x0054a40174b9506L,0x0762f1fd830293fL, + 0x14171ec588398b3L,0x1fc820c96ee312dL,0x02d0d32ede6defcL } }, + /* 190 */ + { { 0x1ba691a42485684L,0x08b5c94e23864dfL,0x05c798a8146584cL, + 0x0cbfe933b569603L,0x05238efff3245aaL,0x0eaa8ae177c3fa5L, + 0x0b2b305b71aeb32L,0x196b4fe44fc5b7bL,0x18dedaac4a9bbaeL, + 0x1984536973e4c42L,0x1cbf0b9a25564ffL,0x050a2efc0c2298dL, + 0x06300b1bee3655fL,0x09e0bdaa531f468L,0x05d098afb4339e4L, + 0x0806f94957c6b89L,0x1d9f4b44a17bc4eL,0x02d74a84cf7f2fdL }, + { 0x02e5ee7804f7455L,0x124cb9103334109L,0x10c5de578cccd06L, + 0x19c91df9db2fa49L,0x19fbc21c12f4123L,0x11d1d77439c6c90L, + 0x09b6eecef718419L,0x0ea6c07b1850b27L,0x1926227f2e3c1acL, + 0x15495602f55728cL,0x05bc2ff5a04ab3fL,0x1089f85505b8b6bL, + 0x1a63522b273ce7eL,0x09433c4a9c20240L,0x1621a220d8222c5L, + 0x0f95843ff6f984cL,0x0980ca331612f4aL,0x02088333f51f6e9L } }, + /* 191 */ + { { 0x1830357c2d04b63L,0x0d1a6fa494d0c40L,0x1b688b46577cff1L, + 0x13968648e78e77eL,0x0997f13814df2f8L,0x0b027a1a2d7f2e7L, + 0x02b97638fd7e62eL,0x1e75af285d2a182L,0x0cefd5447eed25fL, + 0x1b4728f0739e066L,0x0b5646ad53e932fL,0x020a256c3918b63L, + 0x13b5abf7608bbc1L,0x00f3cb24ddc9948L,0x0332f9f6c48c6f8L, + 0x0db73a1507d2208L,0x1ea3dde426f90a9L,0x00e675b229a6f88L }, + { 0x1210c4f0c6d0f55L,0x0fb0dce339e4e96L,0x0466a738feedb2bL, + 0x192760c7c9baff3L,0x145a93be135f494L,0x0977be2c05ed9e0L, + 0x0eda9361c8cc83dL,0x1dce9b0edd11029L,0x14f6f723ac7a97dL, + 0x0f15c781f1e6c19L,0x0bc20ab9c809c1fL,0x05a9bbf490dcc2cL, + 0x198d3a17c6e88ecL,0x1cc00b8d6cb2e42L,0x1bdac898b967950L, + 0x16406156c50bb77L,0x0a33cf451954d48L,0x00f8ba919a7512fL } }, + /* 192 */ + { { 0x08a765b3467ea91L,0x119777e96ce22c0L,0x11b673caf1bcfd1L, + 0x006b30275cf6ebbL,0x044cbd8defc8d24L,0x092b1111f65904fL, + 0x1866966e8438c85L,0x1eff429b2687e3dL,0x1df97c21bfb0c48L, + 0x073144875186a1bL,0x1b8a919451d70b1L,0x03c824cce54b650L, + 0x1c31aab3b8291f0L,0x10be91764e37ed2L,0x13c2eb6dc9de96bL, + 0x125c37b11db0722L,0x02bd0b05d1b6a23L,0x0265c57c832c49eL }, + { 0x0b02057bb4b1953L,0x045a27acbfb7751L,0x166d79904b21338L, + 0x1b679a92330a9ebL,0x0e42bb5d1913262L,0x073fb04813b1723L, + 0x105b20d57239b5eL,0x0311df55048716dL,0x0d0173790e550f6L, + 0x0c57a3172bebbc7L,0x0b57a1c56d1c504L,0x0d8683bd49f342dL, + 0x12280ca61090059L,0x1ba632d0954abe1L,0x0201050bebba000L, + 0x01f43b620a24ea0L,0x0fc8c1db931ff08L,0x024352e12ebcc3cL } }, + /* 193 */ + { { 0x121e213941b4f36L,0x07d8a7c01da7c82L,0x08b94a952ea2eabL, + 0x151fc8f2d9fbe3cL,0x18dbacb6acfabbbL,0x0efd28d703c46daL, + 0x05bbb7e635cdb06L,0x0362ab850d46b4eL,0x0be7d46769c8646L, + 0x05b1c07b1d3252fL,0x1064527d8249894L,0x0fa145bf8b66296L, + 0x15cef466ac0919aL,0x14c35576622a6d2L,0x09273b64fe92891L, + 0x0eb5aa12162e2e3L,0x054602f1d6cc1faL,0x02e934fc4bc7260L }, + { 0x074030c14920419L,0x0ec34484b439c9dL,0x1313badc3e98211L, + 0x1bb3f8b79703732L,0x158f8f2dabcaa06L,0x0e29550329ca13fL, + 0x06ea8d7217d9ec7L,0x068b4fb1ae45922L,0x14041005caec2d8L, + 0x0c345223d4729a3L,0x18602e37944b0edL,0x0dca4222d1d609dL, + 0x0b2317cd8a4daa6L,0x108b26fb605eaedL,0x0eb5f2687506175L, + 0x04d0759db944c3bL,0x10f0fe4b5ac09b0L,0x04564ccad136caaL } }, + /* 194 */ + { { 0x0c8dc9b2640a39dL,0x1859c76f064fcd9L,0x06f687b2e82887fL, + 0x1a101a082ee9e8dL,0x149946048a902ccL,0x1b558af4ab7d197L, + 0x1d248d23e173e5dL,0x0cf843f8ddc00cdL,0x135b1ebfefeeef3L, + 0x0022c0e2309f2f6L,0x1fa39ba9ae81c5eL,0x14652a1ae7db97bL, + 0x161da48889ddfcaL,0x0dd7fde8e4ba3c9L,0x0ebab9f3a19f233L, + 0x02591a4ce863e39L,0x04d682550458979L,0x0063e0eee6bf50fL }, + { 0x1aa30cc1ce963a7L,0x17b266262fd6f29L,0x0be0a0a2befdcd4L, + 0x0d9442420e57354L,0x05a576dc64273c5L,0x1ae3be556ebb2a4L, + 0x1ce6d865ab0fa42L,0x18841a87d3fa355L,0x1fc392062cd05cbL, + 0x00b1c392607f97eL,0x0ae360aba087985L,0x12867f4f47e19e6L, + 0x0df644ca925f58fL,0x0c8c53afd75f8e9L,0x01d84603018558cL, + 0x04882f3136bdad7L,0x1abbf342445ad41L,0x0127fe4d70efb19L } }, + /* 195 */ + { { 0x1fcdc0593c7cb2bL,0x01dcaac8029fdc4L,0x0f3d8608d0f3049L, + 0x1ecd8314c6c03bdL,0x0c913287364546eL,0x1c4618d2948380fL, + 0x1df5f0d6e009be5L,0x0510a570c5525a3L,0x11809cb050aa797L, + 0x0bea33e51e59002L,0x11df027bd6e51a2L,0x1885e4483309e41L, + 0x0df35bb206c3372L,0x14e0a05aed029f0L,0x15beccef09b1b42L, + 0x072d0c39f981996L,0x1a41c3cf9ef299bL,0x044f269e8a0310dL }, + { 0x15e80e7a45a9be3L,0x152bc039ab7dee9L,0x18bae59ef0bf136L, + 0x1c8f9a2dc6030daL,0x1f30ce9ba702679L,0x0327a865178e012L, + 0x0759bc4816d187eL,0x13cffadaf2f0a0cL,0x047edc4f68a0880L, + 0x0d60224cd269d71L,0x119929b47e76a17L,0x1d09af5074e3f08L, + 0x0ceaac33f19f30cL,0x0a431155f49c15dL,0x1a07ac87c0ce0c6L, + 0x16b8f606f4975eeL,0x0fbd156a90899a1L,0x033ae9f37f378e8L } }, + /* 196 */ + { { 0x1767ffd707193e5L,0x05548c081ac72ecL,0x07fcca363bdf91eL, + 0x10db77b34eac69fL,0x1e215686913a0eeL,0x0ced1c1bcd94b43L, + 0x0d34a40fd042a27L,0x16bb3f1af723626L,0x09fe74229bd82efL, + 0x1ab45b11c01e3bcL,0x068d434f494d136L,0x0b60e4892fd127dL, + 0x16a169e23b559c3L,0x062da634e2396a1L,0x11fd4c4261918cbL, + 0x0f1113edaeb3b07L,0x04ba91cf1db1e49L,0x02fbfc97f30578dL }, + { 0x18a1cc60545167eL,0x1170157fd447078L,0x1d450ca9ef3d57bL, + 0x054ea210cc499bfL,0x00511af77382da4L,0x178a11f44a608faL, + 0x14abaa93938c4aaL,0x06b187a6de1ec7bL,0x1fc5c9550d76606L, + 0x0929b989bf53f55L,0x135660e6e543d80L,0x0c0281cc688454bL, + 0x0ef2ac704595a0fL,0x023587b9c82f11cL,0x1215e2912eb3039L, + 0x0f00699a840dd88L,0x18d367b1aaaa5bdL,0x012df676c8515a2L } }, + /* 197 */ + { { 0x19a73820c33a8fbL,0x1b6688792ee0e83L,0x0fe31b520adb3efL, + 0x180f7f08949ff8eL,0x199162f03e51f18L,0x009c08d3b2891b2L, + 0x06282b1669d3850L,0x1632af4d0cbcaa0L,0x1e1ec51bde3ca09L, + 0x0063f59d4b0129fL,0x0ff451f780fe12fL,0x1da2a5f7b613d07L, + 0x1dcea15ec1c0540L,0x05930983b5d2976L,0x0e5c81bcf4c3b55L, + 0x0e75537af75d1d0L,0x163f20d86920963L,0x00530b525e1d85fL }, + { 0x075f3ed6e1339c9L,0x150395fc5805310L,0x120af3366d1debeL, + 0x1e0194a98fbf5fdL,0x18bc31ae4713158L,0x06fe45224881789L, + 0x15352be63c560c4L,0x18993de40eab3d2L,0x1e8021af9c527a0L, + 0x140093bbd0c9011L,0x1d4e31fec08dddbL,0x0e9fd193d2a2c6bL, + 0x0d15cc90975df19L,0x1bd288ae0143fd7L,0x0b188f7e81ca3c3L, + 0x1741321b7f7cc1fL,0x04ca8d40fd40311L,0x043b68aa703e323L } }, + /* 198 */ + { { 0x1a4d6d2c2d3ea8aL,0x1340dd421300769L,0x0037901c19c8dafL, + 0x1cd4faf4f78a7e2L,0x1d5e1a83e3e5b6fL,0x04be153734ca7caL, + 0x040441f2b3489d8L,0x04825b31b754cf2L,0x0ddfc4461102e0eL, + 0x00aede16a499395L,0x03992ea50d9a592L,0x163465657f20fc7L, + 0x05d928e28b4960eL,0x1503be4f6d22ba9L,0x1587401cbdd6ce4L, + 0x028ac4eec1976ffL,0x100af235d1b0f4bL,0x01820611df3b68bL }, + { 0x10dc55b4efa9a70L,0x120a7a9f4330858L,0x044c27e289ff537L, + 0x0a0ccc3a787b2b8L,0x00eb513e505109aL,0x1e99c5e5514ca53L, + 0x19c7cfb9054dc79L,0x1689fa28bf88ca3L,0x051bbf838cbc313L, + 0x01cf03c0f5c90a8L,0x05ad1052fd6b1ecL,0x031117c1a919d0dL, + 0x15dd8f2b6f2d667L,0x15c53fc55f49d97L,0x1dd4717077f479fL, + 0x0e97d0c567bb321L,0x1a21eb1ad58a32aL,0x02a436bcd0f5de4L } }, + /* 199 */ + { { 0x12e34ffa1359e13L,0x0c6df940cb028e5L,0x08f48d592d7880bL, + 0x0c85ed5825d2bc0L,0x1653725dfb1340bL,0x123356aa1dd4295L, + 0x1ca2e06bb735a34L,0x0cb7ef00448a8f8L,0x1559f8a119569fbL, + 0x02dbd316fd91764L,0x01d5027bb579494L,0x0510533ede220e2L, + 0x013db6f8c79c899L,0x19e53cd4d3eb493L,0x08582c0c3adfeceL, + 0x0813595733771f6L,0x18bd2012568d28bL,0x01c078d87ad622fL }, + { 0x0b99e6be6a0068fL,0x1e79564539ba9e0L,0x1522cbebadf12d9L, + 0x126804c1874d934L,0x0c0f739e7f417f9L,0x04a4ed4772b42aeL, + 0x1bbffc22d443de0L,0x17762ee1f851ab8L,0x0b4f5abeefd96a7L, + 0x03d889b79332d15L,0x0e0292d80773e68L,0x0c282c57d98c5f6L, + 0x16ee6b83b3cc803L,0x1460bf759a4c7dcL,0x1dfbf0baa6c3f5aL, + 0x0167cb0696b7542L,0x05e929044f55b11L,0x0255f6ef6f5eb94L } }, + /* 200 */ + { { 0x155e1b9700ef376L,0x12ecd3366d5ff99L,0x15d51fa1d91b55bL, + 0x1401ef26d367b84L,0x00c52e2928f44b8L,0x14d9c90461958f5L, + 0x08e7569e37848dcL,0x0d68308a33564daL,0x123f6b4b7e0ce4aL, + 0x1afb7c5565954fcL,0x0f1153881929648L,0x006837e60c5d771L, + 0x1b94dff6f937efdL,0x0553fd0335d6341L,0x02cdd170cd92c7aL, + 0x1f61e0c2cee559cL,0x0d346f08d08d1e3L,0x0351055d98c7099L }, + { 0x08310166a85cbc7L,0x084a349a7cd53f5L,0x02239de3c6cf426L, + 0x1e448f6f3384422L,0x054484ce7ea4ff8L,0x0c61b2598b8eb8aL, + 0x05160a500e5253eL,0x02cbb5223e72fbeL,0x0a6b58093094391L, + 0x0fca84d0ba11c5eL,0x1460860825d635dL,0x004348f24ba1fd6L, + 0x14af8a315eae0c6L,0x15d6825b874a334L,0x1c911f6b9ebe28dL, + 0x0dffc8982bcffe0L,0x1775184668aa545L,0x022f1a9d3df9b5cL } }, + /* 201 */ + { { 0x005676493092f71L,0x15b617adc96b8bbL,0x126f8b22db17ad9L, + 0x1441806c7d3b662L,0x03cd7097f62f583L,0x1c8b56344566998L, + 0x06c3a174303e3aeL,0x1a237ee8c590983L,0x1c76ed5f97c4a6aL, + 0x045c45d688cf9b4L,0x00dc6faf942e0fbL,0x0a110cce0d4cb37L, + 0x03f8373d2c0cc69L,0x152d017da98e3adL,0x0e6874138734e8cL, + 0x0667dd04e8ef1b4L,0x136edfc5bbb75daL,0x00aca0f92653cdeL }, + { 0x0e8c0f8a77dd512L,0x1acd38ee1b2fb21L,0x133421d4e18aa46L, + 0x1ba4e5f595d01a2L,0x0027cb5a1624230L,0x17cf81f751f60b2L, + 0x0523705c02d6707L,0x1e3a823824e1b46L,0x1801ee448c4181aL, + 0x0f942accf1d4805L,0x1ec2f43426bff7bL,0x1f2d166e0048bacL, + 0x00e6f836b8d839dL,0x1e9900e49db183fL,0x0740aed4e0b9622L, + 0x083d2c6db14d6f4L,0x10370b7db769686L,0x0368be1a508c7d6L } }, + /* 202 */ + { { 0x1608841c181c99bL,0x0e480e43dee57e7L,0x111cdc836afad97L, + 0x0ca6eea2b768c16L,0x0a96c2774c79c39L,0x007a206a23f9170L, + 0x00eb4365484c0abL,0x141066164d7920bL,0x0e25e977a928904L, + 0x0f57fecc2e2858cL,0x16f2de96b57da87L,0x00339146fdab9e9L, + 0x101e9850b6cbcd0L,0x185c7302bc236ecL,0x04cbe406b20652aL, + 0x1c51772e50ae268L,0x14e4ce9f149f56eL,0x00d5cdad21f4f0eL }, + { 0x06dab92314fa7a3L,0x1787823c7fcb190L,0x1c4e41367f6f312L, + 0x1625808bfc999c2L,0x1d8f6d7dac20a2eL,0x1db7fd227e2a3c7L, + 0x1dd6221b9cb1729L,0x1aaff48a536dfadL,0x14df1d1b192a820L, + 0x0c097cf93c4f8a4L,0x0bc20eaaed4f48fL,0x073654075665308L, + 0x10b151250226485L,0x198fb5eab18e704L,0x0db98d384a53455L, + 0x0cd5f64526c3b28L,0x1ed8c4281c43ca9L,0x01259a4ab610d59L } }, + /* 203 */ + { { 0x1bdcb86659824e2L,0x067242709f3a624L,0x0899aef87ba9b71L, + 0x0e3c7d88af49803L,0x0f5a8e4b47b2b8eL,0x19a986bf458af01L, + 0x1480ba07adb9b8cL,0x13f59746d3c2f48L,0x081241431d70e4cL, + 0x0c857a59f095f5cL,0x1c148c47d21bf70L,0x03c253f6579ca64L, + 0x0bb70f6c089f6c4L,0x1ff5a23bdf3143fL,0x13c62ec51e61428L, + 0x1a081f9fbf62337L,0x1f9925c292fda80L,0x01096b2f2bf1e2dL }, + { 0x1adb386ca15cf08L,0x1256240f0b97591L,0x1e4d350b430137eL, + 0x06e8809b8f3a3b7L,0x0932bfcdd9cf607L,0x14154c30284220fL, + 0x073026ba4432871L,0x0612a51f8308358L,0x0e6a120aedbbed6L, + 0x07070f618667928L,0x12e953962efcbe5L,0x169f3f54882bfd0L, + 0x07ecee7ce5c66d0L,0x17d3439d062c78fL,0x07c4d21e8750fadL, + 0x0f56f2d8d8b4073L,0x047e6ef9aaae672L,0x03357d2aa4d2e12L } }, + /* 204 */ + { { 0x05aaba8c980e91dL,0x07a84b564c77d6dL,0x182a368c998aa4fL, + 0x0001028a7d61321L,0x1d71de8401d2153L,0x0cd00915d8699f1L, + 0x0e39d197db600f8L,0x118b205fe98f150L,0x174e2afb7193134L, + 0x04993abce7d82bdL,0x1a9908eb40fe3e9L,0x048ab1ff4814ec3L, + 0x1977a87e30b7d4cL,0x04e426935af4e06L,0x0658e834717b6ebL, + 0x17e1bd95107347aL,0x1dfbc6f2f35ebf6L,0x000f7831886ac55L }, + { 0x1f903163ecdcbb0L,0x16b9413e0e4aa95L,0x00c255d724c0678L, + 0x132d3072613ca4eL,0x1cd082df0dc1c5aL,0x0bf028f7cfc07fbL, + 0x06d57364541d77eL,0x189e50dfffd398cL,0x1352db38f80f24cL, + 0x0cdccf61b291d71L,0x0a32a042c412a7bL,0x1fce60a4075a213L, + 0x0e769400f5c2700L,0x170622961517712L,0x1c0a90756574e67L, + 0x0616e156ebad5efL,0x002341080990db7L,0x00727affeaf4689L } }, + /* 205 */ + { { 0x11c64440ff14c38L,0x1acfd576708f95eL,0x169c8abd8cc2696L, + 0x15055e49dd548c0L,0x0b9a1159ddc9f65L,0x142757fa7725ff7L, + 0x0ab38918f41d9d3L,0x1971197c3c01c17L,0x17ca568ead5fabdL, + 0x0c06a9262bf5cceL,0x195cb3a6fa61cefL,0x1b9ae60170bd388L, + 0x1240f54176918a1L,0x1ad8a11b2491098L,0x0d3c5abdf8c93feL, + 0x1b2f881bb4a0248L,0x02008833421a133L,0x019ea08b0843b78L }, + { 0x131a36b9878e5ecL,0x1f190a348c1193aL,0x08cf428c1191778L, + 0x0f542e6cb3a2bf3L,0x1925d4fe734c1b8L,0x11587a56104a517L, + 0x172f10f25968709L,0x000eb39207c88faL,0x092af215e052393L, + 0x1fdb6af8fac9f9aL,0x10ed2f0f376d7ffL,0x05397fbaa810cb2L, + 0x0b198d76c09d03aL,0x00793dacc7be6d3L,0x0d6333f01e4288bL, + 0x09fb974aaf50919L,0x0665922052d76c5L,0x0169ef3d523db5aL } }, + /* 206 */ + { { 0x0de746265add3b7L,0x0479ad5f9261555L,0x072b8695f64f962L, + 0x1c58edef7fa82a9L,0x1e3202b30e22e18L,0x0e878533f944755L, + 0x0b462de699ae874L,0x1d21c156e925103L,0x17d424086c7adb0L, + 0x186196294210997L,0x11dfc563e6827a1L,0x06e5d804ab130b0L, + 0x1ca5098777422a9L,0x0bb3002c5f21462L,0x1fcdf3d16de5591L, + 0x0c512d8ff8c632aL,0x0a68b7023ddd631L,0x023801ddb2d8e09L }, + { 0x19401c1c91c1c96L,0x0e6fc93d094b86cL,0x185f0f0a441ea97L, + 0x0f47fc8e2075725L,0x0ee998ee26fce8fL,0x1d20fc58684eaf2L, + 0x0941abe98881238L,0x0a56380254b44d9L,0x12c6f734c99b572L, + 0x049ebcfa897bff0L,0x0241bab3b866984L,0x07020ada3d4c5e6L, + 0x16eff35f216bff8L,0x00d6911230e3ac2L,0x083f7a1b81fa5e3L, + 0x1d0365994d942d6L,0x0e6ab4d6d2d633fL,0x039effa82583516L } }, + /* 207 */ + { { 0x1615805d8e20fb8L,0x039f2415a99f845L,0x00055aa15329f1aL, + 0x19966d2422a40beL,0x07f092b787fec6aL,0x02ff260fd1e0766L, + 0x1c4496cd991fba1L,0x0dfa8f03d0bf163L,0x0c65268398b0f1aL, + 0x175c6366e5c75c9L,0x1c3ab6397db54b3L,0x1c4791b269b8267L, + 0x1d428ac45a31883L,0x0ddfe54290a76adL,0x196b84fddf2924bL, + 0x00bf7be8227fc0fL,0x13563e4a0d272abL,0x03aa2685bb8a47aL }, + { 0x1e8d13480797aceL,0x0b55057c36cbf27L,0x1a23bd69a3f085bL, + 0x0b3f364d09b7e14L,0x0999d2fc18b26f4L,0x011caaa97f7e7d4L, + 0x0de0356be360989L,0x15f1e2468d3ec74L,0x12933454fdcd4feL, + 0x1400c5bd39dae84L,0x07c9db9554b062eL,0x0e7bfe4d763935eL, + 0x1006dd4f44c5d47L,0x0f9cdd24cf7a4a0L,0x1b293cab63c4be5L, + 0x1eb34aecfedb9ecL,0x149ba8773f17922L,0x0110040f560f216L } }, + /* 208 */ + { { 0x043d573ba37a0baL,0x018de6e8bb6fb18L,0x13f31081c3dc169L, + 0x1ccf85a21206645L,0x0bf8bcfa5cabd30L,0x03d8859b164aef6L, + 0x179935d9f49dddeL,0x01cc25922bcdd80L,0x19e669631ce69c3L, + 0x1e4eec7b417131aL,0x087c4a57ff30e09L,0x1cf31455b944f20L, + 0x044b5d500a06a8eL,0x06c06b62c70073cL,0x17c43321dd1bf1eL, + 0x0dfb048c0a77d22L,0x133844e328b219fL,0x03102a0d608de9bL }, + { 0x17fd382509e5a29L,0x06be85a19298f07L,0x0d5334e20ee61d2L, + 0x0917f762f51ee92L,0x05f2d2c5c6b8ac7L,0x058dc1d230b5330L, + 0x0996acf6598946fL,0x0b19eea62085fdcL,0x0c70d73fbdb2250L, + 0x108ea1a78616aabL,0x01876152c966cc4L,0x00db88567efb0c4L, + 0x05e86a4949ffe46L,0x0b0776d6262e42cL,0x03890801377322cL, + 0x02cac30099cceadL,0x09791f3855a4214L,0x03f9bc0cc7c995fL } }, + /* 209 */ + { { 0x0374bdadfa6639aL,0x0a46a0155b9c8cdL,0x08d91c0c78b432fL, + 0x19a0b33a3eb8bdeL,0x00d38443b49ee2bL,0x09c9746942f5b07L, + 0x14e3f6efaa4bc9aL,0x0d1228abf7f7178L,0x0ae259ff1e469b7L, + 0x0e7658fa0ef2b41L,0x1bc1c6654b46bb0L,0x0303cf7ee88d90eL, + 0x06282ad2f11ce25L,0x15d277b3e5c9d6cL,0x01ea8fa3e8f34c5L, + 0x16c11f9cd1409caL,0x0d0ced74170a61bL,0x036f38b59fb5608L }, + { 0x0e58d04172d6dc5L,0x166f331cbe32e6aL,0x1860327ad3a2fb4L, + 0x10ebf45db6f5cefL,0x091e67385627546L,0x0e4597259819275L, + 0x0a21d808ea1588dL,0x16b3bedad8551f2L,0x0ec2c185ff6f5e8L, + 0x04970959d6aba45L,0x0ed3cb552bbef1eL,0x0891dd0d1042f5dL, + 0x11b1d9bd5b14915L,0x17f806fbd1362fbL,0x16c77bb97334598L, + 0x1eee9d7933e2f72L,0x1b0909836163fe1L,0x028fc84185d9e92L } }, + /* 210 */ + { { 0x1376fa1f2922461L,0x0d8e18b286868a4L,0x10cc376182376ecL, + 0x166d71320d25723L,0x1f5600523e612c4L,0x1512a2f0cbbd85eL, + 0x0f63be2bffdc18dL,0x1759b4fa4f022e4L,0x00b0bc4bb81bde7L, + 0x058405976952bc7L,0x0834345c6cb808fL,0x119f2837735cb7bL, + 0x1bc14a65c5f6df3L,0x00ceecc742eec0eL,0x081be4dfe6320b7L, + 0x17cf18c26e8fea4L,0x1e79e13a2c25f5bL,0x02f7690c70551a5L }, + { 0x156575401d4dc0bL,0x12f93fab35d83f0L,0x0faee088975686bL, + 0x182313d8d7d30bdL,0x0cce4d9d5f3ad21L,0x1b2dac8bed28c67L, + 0x1dc732128b4fb5aL,0x0f4ff3102eb1ff4L,0x150d6ae122ac69aL, + 0x1bf9858e3734236L,0x08e9816f42ec4f2L,0x1d9bae7e480f180L, + 0x0ce5f0a9969a10fL,0x1ec7ac034628ac6L,0x1691b8749afd856L, + 0x1a6115e65d50f22L,0x054eaf74e810287L,0x0460a5d03531321L } }, + /* 211 */ + { { 0x0877895b17ee201L,0x15238c472bd3b86L,0x1d8e5e08915b016L, + 0x019387743a3387cL,0x14389ebe0be6f8cL,0x13fddb7f42fa7fdL, + 0x1b1914e2f333833L,0x0850edd5654ca4cL,0x15c9ac690cf9a38L, + 0x1ae79d8e6647cc0L,0x1ef9aa73da1f7a7L,0x01f90706b82bf42L, + 0x1b150ef2ebfcfc1L,0x04252973043587eL,0x1347ae27e5fb366L, + 0x0077482dcdf4561L,0x05ee2bd15993eccL,0x0322e052ef55d8bL }, + { 0x14c420550aa7e31L,0x06f8617c28ed2ecL,0x0424f1c9b9aabb2L, + 0x0c4c337f3532c8dL,0x0253fbd572dbdc3L,0x184f030da130707L, + 0x1b16e5f0967ee31L,0x1d3f57ef9779bb5L,0x1b4d5e8b1e4b703L, + 0x18372b7039a77eeL,0x1293e47d57e2946L,0x11747eacb91a05aL, + 0x12816d1d947f860L,0x0e73d89b4117a3eL,0x1410908330d8559L, + 0x0cfedc8ddcbde63L,0x091b2a65f706835L,0x013f4ffa0697d36L } }, + /* 212 */ + { { 0x1251893d7e952e7L,0x182c1e39adf8c3aL,0x064a5bf8124456cL, + 0x1100da5f94e656bL,0x1b885ed92745185L,0x0faaf638d5bb500L, + 0x0ea72f73a765db6L,0x0567b4c164091e5L,0x16977c086592b13L, + 0x16e54e584c828ebL,0x0aac8f4622b896dL,0x1e7fc4155e7bb38L, + 0x0f5aad74d09f469L,0x1154f59dede8fbeL,0x1c04310f57bf970L, + 0x004c118bdbf4426L,0x176ada2217b5787L,0x027f772b39ed64bL }, + { 0x0e18d52b5d3d780L,0x0dae9838b33a218L,0x01b969d0855936bL, + 0x1d1ad7770c641a7L,0x0d263dd15d8c290L,0x0c231b4c0d21919L, + 0x0b2c4cf439f2a62L,0x1fea270f09b4a33L,0x0832e3fabdddc81L, + 0x013c2ca18ccd21dL,0x12af3cc9d0c58ffL,0x017ae9f29f4eb69L, + 0x1d5694a6279fa01L,0x05b2bd1261453a1L,0x1a897ab074aa223L, + 0x0c3fefdde4a07d0L,0x00eed11a5d304c5L,0x027f40c73ce4f6fL } }, + /* 213 */ + { { 0x0252c9d7fc1c7ffL,0x0a0cecfd44d6880L,0x09290193a732a6fL, + 0x1087285d9992742L,0x0749695b384cbcbL,0x08b2df802610fecL, + 0x04409a720767d08L,0x09bc464ac51bbc0L,0x1ec9374575a9b00L, + 0x199a35ffb6e7e10L,0x16992d34dcb1f7eL,0x15a7e40929c5589L, + 0x15e867c150cecb7L,0x015b91ec2b1620dL,0x194c8c4a64e573bL, + 0x0cb2f9235bf8afdL,0x1fce06f1161f10bL,0x040c8aa94dba69fL }, + { 0x0c124316ed9d4eeL,0x1d0aa344d7f80c7L,0x127caa268fd0f7fL, + 0x05a8cfdf6495746L,0x039102e22db1e8eL,0x1784158c6f51aa0L, + 0x1751d08aae14f94L,0x1dce2614583da6dL,0x1ca60e86d0295d1L, + 0x15634043e3fad69L,0x0f3b3f7a1919639L,0x18428c3a24ca1f0L, + 0x10bd38509972e66L,0x13319144ff77a0aL,0x0b71e543c60fceaL, + 0x0ee044ea8a97cf2L,0x0f32744c11b1136L,0x03e835e63f47537L } }, + /* 214 */ + { { 0x12859427090212fL,0x1bea62a90f42244L,0x108af8b6ee49a46L, + 0x1b7b03f10098070L,0x0c89bc36317721eL,0x078026e09b65f75L, + 0x02ae13dc6d82deeL,0x09a4d2265a09c43L,0x1b0e2496ee6cc81L, + 0x196718bbafd6e0aL,0x0f02119b488f142L,0x154c98c25f1705cL, + 0x0ba4b653559721cL,0x03e9ece8acd3a8fL,0x0350918d0ceab57L, + 0x079543cc373a5d0L,0x192149f655ffc67L,0x0245a95cce87ce5L }, + { 0x1915399efdc05beL,0x06d8c09f04af4d1L,0x0ba7376cff6b79cL, + 0x04340128a288f0cL,0x03920ea3a2b0316L,0x1dc7f5a593cc061L, + 0x05b52b14e53c688L,0x1342c7ee4ac7cacL,0x0aa0ff93fb71421L, + 0x137cb6949eb123aL,0x04baa1f73f89db4L,0x1e5e8e071a2bba4L, + 0x05f418168eab27bL,0x19954c4d72c6419L,0x127c4ef8dc1088aL, + 0x1095b46d287217fL,0x0ecf16e26060d06L,0x00be06f43cec63bL } }, + /* 215 */ + { { 0x0a5f453dcc01958L,0x02caa0e7441c9deL,0x0285587d6db5f65L, + 0x0cfc5a6d78bcc6aL,0x05ac3a6c291c3c8L,0x000366fb63f6c25L, + 0x1b0ede44f102f66L,0x153ef17610eace3L,0x11c928f6eb43e89L, + 0x0f946f9d70f50f6L,0x0e96c6e492cad7fL,0x0e0a3422dc0ac57L, + 0x17167ed3e3491d2L,0x0de058230476015L,0x175fd678a473dedL, + 0x1336e61ca02d318L,0x1d70c7c350df5c7L,0x034315cf1056370L }, + { 0x0c6f4e79ffa1f64L,0x1548d50f121a4abL,0x183336dd48cbfb5L, + 0x0e0645ac0fd341dL,0x062fef87bfc90b3L,0x1fe79a14a405692L, + 0x18e3ff08525a70aL,0x138dca423c14a73L,0x02a59ec2612a514L, + 0x0aff1096b835a99L,0x1ec423a67210a46L,0x1d46bb900905eefL, + 0x0bbd92d29874ceaL,0x15750af752d3018L,0x01c4272b50b7296L, + 0x1ec93ad58778e93L,0x06cc64e1c40290aL,0x02849fd16a8fc6fL } }, + /* 216 */ + { { 0x0cf32804c2d553bL,0x15f111dcb3614e2L,0x12708a5a452b706L, + 0x0b3332ed92aad4aL,0x176e83f3d8c9f8bL,0x02f62be1162bdebL, + 0x187d53ca50aadf2L,0x091de680fcadc58L,0x1f005e8caf213dbL, + 0x186429ef9934c63L,0x12235f2b02952d1L,0x17dac16ea03dcdeL, + 0x06714a4bd9b6bd6L,0x1704c44a7808188L,0x1e4a8014a16f0edL, + 0x1e495d80ce835ebL,0x03832f16426ef7eL,0x0097ce226b63bd2L }, + { 0x151e96483313a1cL,0x0e9ed19e2c59b8cL,0x1d4b1eb1011263bL, + 0x0e1b96bdd09db77L,0x0dd422f8866ca6fL,0x10f6177605747abL, + 0x148f041def15019L,0x07cda732275a844L,0x1d105e1e858e7cbL, + 0x1e49cbfe4bcdda2L,0x0752a4265ed6491L,0x1147d12a5fce644L, + 0x074e9462410ef62L,0x0cbc07a06846ac1L,0x18443b1932fb43dL, + 0x1634627af844e11L,0x118d186d8667679L,0x0017baf2713570eL } }, + /* 217 */ + { { 0x1637ebf47f307d7L,0x02535680a0a3b8dL,0x1594b816a031ad9L, + 0x07fda0f66305467L,0x1696e597c8f1a0fL,0x1fe00f604f73fc9L, + 0x1cee736a9fb0f1fL,0x112a93f11fdf1e6L,0x1c88d1961c3bb89L, + 0x09527f4efe553dbL,0x1e7b88eb92ac836L,0x0c83ebd9634a25fL, + 0x1fe32fb47df5aeaL,0x12e842e073b491bL,0x11d568a5a971080L, + 0x12e47b9224ab04dL,0x141580b985f9bceL,0x03958dab331cb0cL }, + { 0x1708a08790e5558L,0x1b0208344d7c04eL,0x0e2908c4ed7e614L, + 0x04ab493a35d0bcfL,0x0c371b0be6ba129L,0x07370caf3b62585L, + 0x0688561413ce64eL,0x19d1ba82844c15dL,0x1d8b04e9b968485L, + 0x0a625d2c43f7f21L,0x1a399fc47179cfeL,0x1c519ed73388224L, + 0x087a0a966292623L,0x06501769f968555L,0x18ed546c999dca9L, + 0x16b6ad1dd1c9c5aL,0x1adcdebb2992e78L,0x02ef8c90b70b912L } }, + /* 218 */ + { { 0x0027e1e8df2e7e3L,0x1e6346c6d03ef10L,0x09a52d2b9a52c60L, + 0x1e794c5d119c6b7L,0x12efed2c896d97dL,0x1e84279ef2389daL, + 0x048ef401b10389aL,0x1603d36e377f903L,0x09991c7b61aacc6L, + 0x08649b247b2b420L,0x1587461fd1d4919L,0x16237ffa7944270L, + 0x0ffa191418610f2L,0x0aaf2984cb48afdL,0x01cb5e63c48db7aL, + 0x14916c2797dd543L,0x0327f7b44ea66a2L,0x0229132e170544eL }, + { 0x0d5ec7925430010L,0x1c37ff5e8486025L,0x13fc82a74fd72b1L, + 0x0547db8cbf4bf3eL,0x0cf3eb11fcbf411L,0x12db80441241ce0L, + 0x02ae2e375b53a2aL,0x01dc44e3bfb6eadL,0x0e43ec373b74456L, + 0x0757c930e7ba94bL,0x06b838fea5b66deL,0x1a5bb84bbfaa301L, + 0x146bab77110b312L,0x1af678f235c7bc5L,0x07fb2a81a7bf236L, + 0x17bc3832a575cc1L,0x15543e302ed5f4dL,0x00a5815fc8f03c2L } }, + /* 219 */ + { { 0x071c768b87e5b57L,0x03c7bfa98d2ab96L,0x1e2fdd65f7202f3L, + 0x1a273c2ebe9ff27L,0x0b94ca6cb28e026L,0x1cfbfe35c1db93eL, + 0x145c0babf8ec801L,0x0d85594a9bd9e77L,0x017c4133c6af0dcL, + 0x150f332e67af1afL,0x046920d154171afL,0x17a1cc2017134cdL, + 0x06c17d03882633aL,0x0d067c864b36338L,0x0b75931ebbffef8L, + 0x1548c9b08f7cfa1L,0x0a5d49bcdfbaea2L,0x042f03f3a1663e8L }, + { 0x1aae0a60bc25bcaL,0x12af8f227b27611L,0x1b62d81eddcdba3L, + 0x0da600b213c3cd2L,0x0cbc4990aa90a74L,0x0717ae83958e669L, + 0x03b24343f9b1b1aL,0x183241d8be0a7c5L,0x179b21fb4f0040cL, + 0x19bade9fe625163L,0x177be786eb1f769L,0x1af26b81f1a7ebeL, + 0x102cacd318dc315L,0x14937b8e388be0bL,0x00bce69bca08f13L, + 0x1264671b6b177daL,0x030e5b492317db6L,0x004b201cfc6a4faL } }, + /* 220 */ + { { 0x1774f1656999ebaL,0x17143d8ef318290L,0x1c9b782c99a4f63L, + 0x127f128543b035eL,0x0a03e13c3744693L,0x1139e7de7b5b0afL, + 0x1715b4c3030d653L,0x1449fa674ad8ce4L,0x1a57534ada8be97L, + 0x0c921533e115128L,0x06f6d674317125eL,0x0d998d484ed09caL, + 0x0cd426bf59d7cd7L,0x1374df5948a04bdL,0x05b8fa5650128b1L, + 0x0cda08e71fd30b9L,0x056bcbb3e0eaad6L,0x0313587e931de2fL }, + { 0x1217dbae1a1ec42L,0x173edd5ad662823L,0x0c7a194cc746a9aL, + 0x007a6024df6fc35L,0x1ee61851b845307L,0x144aa2140324f06L, + 0x1d8ca201bd28fa9L,0x09e977c875b96adL,0x0036b9bdabcaff9L, + 0x0ca0f32de831bdfL,0x1e7511a1bceaec3L,0x025955ad5fad042L, + 0x1eff7e153414869L,0x15c37ecb4d1dc48L,0x1e4a30e23109b3bL, + 0x13c016adcd50222L,0x0c1933e71359639L,0x004ddeeecd0bdb5L } }, + /* 221 */ + { { 0x1e39c1de4fd3673L,0x06ce8d32e4703baL,0x0771ca271ffbe20L, + 0x1c6a53a4008e4b8L,0x1c747af35b6735eL,0x177efae0fc79769L, + 0x070e573ce663e44L,0x0bbdae44c30930bL,0x123793a2f0e6979L, + 0x1355c6b4358e953L,0x0057788aa20b922L,0x0df9f3b71afc019L, + 0x1202267547be77dL,0x04e0876e04437d9L,0x00fb532d89a1f51L, + 0x0cdd53e387c2ef9L,0x124e6d5d7f05af3L,0x0175500dc68f7d6L }, + { 0x047fb701f357c74L,0x02e2554f1dbca2fL,0x1ccdba16a4164c2L, + 0x1f7c0489929e130L,0x03b5660df53808fL,0x1caf6b48eeefc9dL, + 0x083522dd8ddefceL,0x1e72372236f7672L,0x07ccf08bf86a13cL, + 0x1f6c7cbf500c72cL,0x090d0de31546514L,0x1bd3c1a5ab4d63dL, + 0x0f9b96259a8e6adL,0x1778beeefe15924L,0x1fe72165baf3abbL, + 0x17751ed296886aaL,0x06b48cd150f07d5L,0x001698ef4da60ccL } }, + /* 222 */ + { { 0x0bb9e1ede79499dL,0x147fc7e87e156d3L,0x03a069f64d5bdb2L, + 0x1fd1e0c64f7d81fL,0x1b300bebbc3d1c9L,0x1e0c0dc02e390b9L, + 0x074040108282104L,0x1ad3d342cfde195L,0x0076c909d1aeeddL, + 0x050ccbfc71d4539L,0x1fde9e9ded0a799L,0x17e8b929a7d279cL, + 0x07e6d48407aac0fL,0x148c90f3f9bb4a5L,0x076ef5bd599e78aL, + 0x1f533e47fc1e7dcL,0x165c7917566cbf9L,0x04b2c3079707a6bL }, + { 0x134702b7fa5f79cL,0x1ea132d796936f3L,0x0e61b1cf833a4c2L, + 0x1a9dc8945a8b7b1L,0x156c8a1a7dbe7beL,0x06fc076094f0124L, + 0x0966dbf7016b1dfL,0x15ee14d7456b139L,0x0fc484021999825L, + 0x09425aa3d11f85bL,0x084290a282a2bc7L,0x16625655edb163bL, + 0x1a33935ee3b1eb1L,0x077fd3767828a21L,0x1899531e81fac9aL, + 0x1dc982ddc810dacL,0x0527a7bc5014549L,0x0328408190fd4c5L } }, + /* 223 */ + { { 0x1f0e460b67ed9b2L,0x107e861b6c9e924L,0x0fa6231d7870336L, + 0x06c297819376b2cL,0x1a768605757bbe9L,0x16e2a24d4dc400cL, + 0x16616a2df8abd23L,0x0993cefdb3d6a34L,0x0dd025274ebbf02L, + 0x0c5b1440aa2e31bL,0x16bb4120036e816L,0x027303c54474737L, + 0x1c550cb4f27fc20L,0x1a903463ee337eaL,0x1a7e856b49c0cbeL, + 0x151459341795d02L,0x12f60606f213a7cL,0x04c14a8234c3132L }, + { 0x03746002e11c128L,0x1d72e8736e53f1fL,0x1b8b65548992037L, + 0x051016e287c8802L,0x126b881cf65f88fL,0x1c357f651e946a2L, + 0x1e563e71677477eL,0x09ea910c18498e9L,0x0d06ea43c9cb69fL, + 0x1a1e4d7399a7676L,0x0b3358d4ca5c4d4L,0x0806be74d818b98L, + 0x0cb372653ba95ffL,0x1128291e9700d0eL,0x089fac8c5443f7eL, + 0x19a21ddca71c54cL,0x14beadfc8a0ca23L,0x025bf370d9f3c7aL } }, + /* 224 */ + { { 0x1c9076fdb5f928bL,0x085db5b9a3e763cL,0x1e62b003b107989L, + 0x153b2c338ea96ceL,0x19e4343f900d20bL,0x0c9aebf6a160682L, + 0x00738f7ce7a1514L,0x1584c722304c9eeL,0x0ce8f2554e1f87aL, + 0x0eeb3c4b2fc8d55L,0x1458fe8c914e7ffL,0x1e589759d32b2d9L, + 0x0aa94f9ea55c815L,0x1792722aebc6461L,0x17709a9eacabfd3L, + 0x05045e1dac81239L,0x058954a420b00caL,0x00308e262e994bbL }, + { 0x192001ca9e81829L,0x199900451416678L,0x17863e77b66f7b4L, + 0x1b6f11200617fafL,0x1577a5dd6793ac0L,0x169e15dd806c8e9L, + 0x0405385e88e9e00L,0x00fff2bf119f6a9L,0x17cd1bf4bc71b6eL, + 0x11d925011ac4645L,0x0cd6e2904481d8bL,0x00bd880ada6136aL, + 0x0ce916a1b52481cL,0x0280bcfa2ae3a08L,0x1344822ef80c9c6L, + 0x1fca02bcd82ef67L,0x166509a24c090cbL,0x04103ca948e0842L } }, + /* 225 */ + { { 0x12d3cff1c7d353eL,0x1f666bef0671daeL,0x1d7db2a1d8d7579L, + 0x004bf35a7d69620L,0x005cb5aeda8404eL,0x1910d0b5cb1f449L, + 0x0b292797b836027L,0x069ac990bb3d483L,0x06a46c4e934442aL, + 0x037fcbf1e7b2ad2L,0x19707b9505f5f2bL,0x1353dd7f3898ecaL, + 0x1988da638868100L,0x1b5a39634adb0e9L,0x1fc45c5900ad1abL, + 0x00bc63fbca2ca16L,0x0a794f8f273be0cL,0x03a43d81b5441a2L }, + { 0x060e5759c3e2370L,0x0c0c9fc02438cd4L,0x1cf29b8be6a8675L, + 0x12c288e336741b7L,0x1effec21b6c7e95L,0x08675fd4824e3a6L, + 0x178562e8192c8fdL,0x1e5625045809343L,0x0b654b7d9b1d527L, + 0x03842ce87fe8218L,0x1d299d3c1511af1L,0x0a37475bb32a6f8L, + 0x0be33533b5e5532L,0x13f20ce7251f6b6L,0x146e5e4bcbd1340L, + 0x14d3e5b09dd054bL,0x1ddcc76b123db6fL,0x041a7c2e290fd1dL } }, + /* 226 */ + { { 0x09347c12ce9b31aL,0x029157f1fd9db99L,0x0d354bfe43f4762L, + 0x0c5634103a979dfL,0x0a411f0853b1738L,0x0db01d29c608dd1L, + 0x15d05e256e4f050L,0x10c532773556217L,0x1ccbbd046099129L, + 0x14fd7d8775055d2L,0x111888d598625d9L,0x11386cfff4a9a90L, + 0x1d1c3478da4a63bL,0x15301a7be5d6ae8L,0x06c4e4714ce489eL, + 0x1ea2a1cdae0bfccL,0x14cdd14b660f74fL,0x031cec58529995aL }, + { 0x0423162162217cdL,0x12515408e14737dL,0x186085d9b700b83L, + 0x1208d40dded1b39L,0x1de921015126373L,0x014c69a2775118eL, + 0x15fa4181f23c845L,0x1c24fe4e574c7b2L,0x1e7ce80cca5e8caL, + 0x00b75f1127bd31fL,0x13969e259cf8d16L,0x1444a6d757a89bdL, + 0x0ee3bf77af13756L,0x15e7cc5e3226b0dL,0x1ea58b182cafdb8L, + 0x000467616b3e653L,0x02cb0769a1aabb5L,0x02048189b063aa0L } }, + /* 227 */ + { { 0x0d2873a1670433fL,0x0a6fb12a49efe42L,0x066a03f3e27b24eL, + 0x01b652ec2dd60b4L,0x19e63046e39e431L,0x14e54f283a16e4eL, + 0x07437cc6b632077L,0x1a30d557f29f6f6L,0x036cda27a1b3c82L, + 0x18d177a1cb816c2L,0x0ff77118204a67eL,0x091ba472c470501L, + 0x137b3c9353e4b2bL,0x097dc53496d9617L,0x06011d356d6cc5cL, + 0x04af1f370f47610L,0x1c8d85909861e95L,0x040334776f9bd15L }, + { 0x0edcd35b39a0249L,0x1866a597c575771L,0x1791c88f7c16bc8L, + 0x15c1d26fe852b62L,0x0cbc9162bb66982L,0x04ee5080ce95b94L, + 0x01ed17144aba73dL,0x1d22369234ec61eL,0x148d4f34ca03874L, + 0x0fe87532265ba19L,0x1e6b87e56cc30f0L,0x1a9bdb16c15827eL, + 0x1f61ead81c40362L,0x04c61e944f418a7L,0x1485c0bb5803751L, + 0x03e66bf96383384L,0x0e9592329fc3a9cL,0x00233baa40def36L } }, + /* 228 */ + { { 0x03de56e39233c96L,0x0204e4039bf57f7L,0x06f4806af1a21a3L, + 0x165690c40b595c2L,0x0f19056c0f2cea9L,0x0e1520f191c3f0bL, + 0x0fa1ba9d4d96a97L,0x09aed8535982569L,0x0a01fcab78d6329L, + 0x0edf4458655cf92L,0x11b96fd05301520L,0x1127972d6f54eccL, + 0x117664e097fe111L,0x09fe7ad4db24fadL,0x1ffd8d2865908b9L, + 0x1312ab2f1937a16L,0x056b5feb38e3c22L,0x001c524fd8419e2L }, + { 0x1e3818c13e93257L,0x15e4ed3093a0d9aL,0x0925f2ab01ac533L, + 0x067b54222c9edd2L,0x0de2034a82278e3L,0x0dd31873e62b2f2L, + 0x1bef6edf7257c28L,0x1ad03bb3e46cd2aL,0x1c63e6319bb132dL, + 0x11158117e12099bL,0x12064dfa2fac71bL,0x129bb1927158470L, + 0x0aa6bb564483b19L,0x037c8c03daa67d6L,0x1e367cc69f35138L, + 0x151cc3ba8737751L,0x060660c2a787f74L,0x025dbb711090dabL } }, + /* 229 */ + { { 0x0151e8ae6354817L,0x04a75781c5a1c3dL,0x1a2216562618cf5L, + 0x0e3b975824990d8L,0x00edad067215382L,0x0072eb7a43d7c66L, + 0x1fd56b4cc147f94L,0x1aa14e23637adc8L,0x0a68709a78c746aL, + 0x1f8b931320179afL,0x023bebecc304c09L,0x008380d8e92f8daL, + 0x0edcc3e2da9ef1cL,0x04970839e863a76L,0x084add0c317e5b8L, + 0x1d6041e27279e55L,0x18b245840162107L,0x04421e92fbdbb7cL }, + { 0x01501dcedb2a83eL,0x147d815dc6b9227L,0x196764977d8af3fL, + 0x1e8556df8612040L,0x00f09dfd3c715dcL,0x0c857539e0282adL, + 0x1d278499d17638dL,0x0c6a705e9b0edfeL,0x0fc69feefa920c6L, + 0x10b0108cfeb88e5L,0x070ef641d713577L,0x17a27bdad7e4843L, + 0x0b6263a1163800cL,0x1e93261bc63f507L,0x1672630d6f5e561L, + 0x0e76aadc45c8ae2L,0x14971bf2a2dfa73L,0x00281fc9cc49ae4L } }, + /* 230 */ + { { 0x1addc6671dad4f6L,0x124448125f50db2L,0x038bd8174f748e3L, + 0x1d61b2d713f6ed9L,0x0601b2cb13d5f5dL,0x11e92a705add1abL, + 0x03a9f8df524760fL,0x175d10c08464819L,0x1374182f3e91c99L, + 0x161657cd43d6c8cL,0x0c102bd5d3ca549L,0x1da328800146962L, + 0x1e06df42e75b9bcL,0x05e8844ea6662bdL,0x16ed4008ba3b141L, + 0x1d5b618a62ef5bbL,0x0f9690d31d29ecfL,0x039abbc7f0bb334L }, + { 0x186ee3e843c1137L,0x0217d1f85b9e687L,0x1e762ac838e8f07L, + 0x082c485f5c1ceacL,0x19b092e46f95f1fL,0x11b5603dc4708e1L, + 0x00b9858a500f930L,0x064cc20be825b58L,0x174dc28a7862e06L, + 0x08c7fd979d91e46L,0x0905f01d17fefc8L,0x1408980ae23c230L, + 0x14cefbe4de49b55L,0x0bdfb88396332dbL,0x13c19d873130076L, + 0x1a1f165940db58aL,0x0a1fc599daa7450L,0x029731bd30d18c1L } }, + /* 231 */ + { { 0x01700f16bebc6dbL,0x1a2edfca81ec924L,0x14f17454e46529aL, + 0x0bcb5a55798e2b9L,0x0b7b466f942a1c0L,0x09c8c59b541219dL, + 0x19b3ae904efb6e8L,0x194d314ac4921e9L,0x1bb720da6f3f1f3L, + 0x08b6a0eb1a38d59L,0x14889cc0f4d8248L,0x18008c774d3dc01L, + 0x0d62845fd17fd4cL,0x0056e4e3d6304f2L,0x1ebef298d80ecb2L, + 0x129577e2df9348bL,0x09841007f7fc4bcL,0x03e48b5a7d3a58bL }, + { 0x1026f9178bac2d4L,0x1404c1300d43ae0L,0x1db801cf590228bL, + 0x09f983f7115a5e4L,0x0a6b291f443610cL,0x16307e2b93dc116L, + 0x1522c19154cb223L,0x006a3c91133db35L,0x1841b48b5f543f1L, + 0x16658df6ac8e775L,0x0b7c3e773d6a2e9L,0x0041668fbb69f89L, + 0x02cb44c5213a7caL,0x0293e062550d666L,0x08f3d41dceda0a0L, + 0x1924d546e9820e0L,0x07c733d10006b74L,0x00ff9c8b7bbd468L } }, + /* 232 */ + { { 0x0218fe4f997939dL,0x0fdddbc8ac1d9d5L,0x176a1fdd582cf53L, + 0x02bb525931674f6L,0x06666f4aa9c0280L,0x074eebf0f5a556aL, + 0x0c1d8bac5e94453L,0x0dde8d4cd49df1eL,0x1900b45c6810e54L, + 0x1d7912c25d7826eL,0x0721c9721350bfdL,0x044b1c9907bc798L, + 0x01170d88b23093fL,0x1603b722317d6f2L,0x174506f86584b92L, + 0x069b5e91ae68c65L,0x0c9c1b1f759925eL,0x00cf68d2b0395c8L }, + { 0x0f7fcde6c735473L,0x04733b001de1f4eL,0x12f3ec666ee2aaeL, + 0x033599997a2430fL,0x10f65459bb73044L,0x09314110a57f9e5L, + 0x082e1abb2068dbeL,0x121550596653f3aL,0x182f3f90f5773ccL, + 0x17b0735fb112bf0L,0x0d12fef51d8b7d2L,0x0253b72e0ea7e31L, + 0x097c22c18e3948bL,0x0bdf4bd6e374907L,0x0d8dfe4e4f58821L, + 0x1a3abd1ae70588dL,0x199f6625ccbf1feL,0x03798f07cb4340aL } }, + /* 233 */ + { { 0x05afe5582b8f204L,0x020db69ac5aa562L,0x1efeb357d7b6b01L, + 0x1627379b26e427cL,0x16dbcbb01914c70L,0x09ae90b8a5a2c0cL, + 0x07c83a4a5f4d47bL,0x00b1ec8106ed47cL,0x1150a8a9d2f3cd7L, + 0x19b7400ee6ecfb6L,0x13ad9573d5b60beL,0x00192554b442b4aL, + 0x023b089f0376105L,0x0215b3746886857L,0x1ba3521246c81e7L, + 0x0de8a95e35c7a1dL,0x1e6137e4c284155L,0x043af198431ec53L }, + { 0x080fddcaf6c0accL,0x08f335d8f3e046eL,0x0b860a1616b756bL, + 0x004eb8fb4db8e2fL,0x126b9e15bdc5434L,0x02fd287a5a64296L, + 0x12cc97c287efda8L,0x03b8df03c8f02f7L,0x02cbd432870ff2eL, + 0x112480b33e3fbfeL,0x16b2ded6169b122L,0x15a88ccd80afa08L, + 0x0fe6d7d63d2e972L,0x0713a0a263a6c3eL,0x09612bbdc19f61cL, + 0x1fbd765942af516L,0x009495c5bfb75f0L,0x02d5d82c0f9c370L } }, + /* 234 */ + { { 0x1e62d2bf0c97f57L,0x02438cb179463c5L,0x119d1ed42aec3f8L, + 0x0689f413db8a914L,0x0b05a96ef6b26e0L,0x1357417ea26371dL, + 0x02677b6c00cb1c3L,0x184517a8057afc9L,0x043f2e9639b7c11L, + 0x161fe0767489b8bL,0x0e2f240bf43e303L,0x0754f9578758ed3L, + 0x1206924cc99d9cbL,0x0130480a7445444L,0x0b9e782945186a9L, + 0x07d018fe955172cL,0x0bc4ef0210a8b1bL,0x0382a23400dff72L }, + { 0x0b3d713121901c1L,0x11313ff56aa557dL,0x0a16f022e88fa42L, + 0x0a6dd844fcc9edaL,0x06c191ab8d99301L,0x04e7164cd0b55c8L, + 0x0ea021ac73d6fd9L,0x1e0b240ceb2cd7cL,0x018836279ccba2cL, + 0x00abdc3f7fa9a43L,0x1262592c88ebc8bL,0x09e0155cf4af7f5L, + 0x0063218a80cd0fdL,0x0fc478a76d6edcaL,0x07b67f4e112ede7L, + 0x0a06d8367c7a96eL,0x06b6c634a13d620L,0x037ab5767dc3405L } }, + /* 235 */ + { { 0x01dc803d9205c5dL,0x0afbeb3891c94d8L,0x1ff6766d9595a25L, + 0x1da76359fc7bd77L,0x0094eeffb844395L,0x0c8ff582194590bL, + 0x141d598c7fea08aL,0x00a1bbccdcc321bL,0x175b03c55e8577cL, + 0x048e72fc8b91203L,0x0229023aece8fdbL,0x1f140b14272d345L, + 0x179a6e06761d376L,0x1db8e94479d2ca2L,0x130c30040c0a715L, + 0x017381087e85168L,0x0add8e6aff8730eL,0x03db5f408a76b22L }, + { 0x0c38e4a3d3aa54eL,0x19ca1ec1ea84d1fL,0x188490e55788408L, + 0x0fea3a7a89f0954L,0x1eca4e372910471L,0x1d2aef316922163L, + 0x086d6316948f617L,0x0d18deb99b50a3bL,0x0044bcaa8200014L, + 0x1a80f34700b8170L,0x064d679a82b3b3dL,0x0d5b581de165e10L, + 0x08fd964f0133ddaL,0x0985c86c4bd776eL,0x1048bad236b3439L, + 0x143bc98bf5adf70L,0x0742284ec1ed700L,0x0437cd41aede52aL } }, + /* 236 */ + { { 0x01d9055450cc69fL,0x18a5e64f6fcc787L,0x19dfb9fae80543aL, + 0x0f331f1ca637729L,0x1b16eef05f7a673L,0x0e2f0aac41c2718L, + 0x14aaaee4a1c8f61L,0x0e9fca3c68b97b2L,0x0c5d0ee287e2416L, + 0x0e0a3778800c178L,0x0e7a4b9fd6f8b3fL,0x075f6cad7a7c1eeL, + 0x1e5168e289501abL,0x1c77082558aa96eL,0x0c111d65037f8c6L, + 0x1522685246c0788L,0x1869306f114c460L,0x02dfd4fd781da8fL }, + { 0x023f52c107b258eL,0x1415deb31a0ee15L,0x1b6208f3fc6a627L, + 0x08e336923ea9479L,0x0433dfb8f45b779L,0x09287744c6110c1L, + 0x1d9543e77647312L,0x08aa185455c9f42L,0x1f7aa1ce42c327fL, + 0x1d0ad6b2c1d8f20L,0x03569686feb6784L,0x14511c3f7b9b354L, + 0x16915f7f879b1caL,0x03f40d0f57c941dL,0x0034a5b04393832L, + 0x0b7b009fb94ac21L,0x0da6acc96161275L,0x00d8933554147f7L } }, + /* 237 */ + { { 0x0bc0a00774ee49cL,0x1b42965b11beba7L,0x12b177e4e28dddbL, + 0x116df7f77bf80a8L,0x145f2eaec3388ecL,0x16749bc25645e6bL, + 0x1e84ea7159826c7L,0x0e2cadf6d58fbd1L,0x15f8ded74a532b8L, + 0x186a145d5444f84L,0x09fca042debb0aaL,0x1c3dfdd96698876L, + 0x0b9e89c2db26426L,0x1c90884822218dbL,0x1604162ab12f174L, + 0x1ec1d24dee6d09fL,0x023452fa691471eL,0x019a8bfed90c6bdL }, + { 0x1c33f46593c4a36L,0x0eb8c1b58d4f754L,0x107509defbb2b1aL, + 0x1cfc9e2f38ab441L,0x146d88a23e8ca24L,0x03817c2b9b99b4eL, + 0x155d1c73ac731ccL,0x18516309b2e6bddL,0x17f4517a20704ceL, + 0x1894e8c6b831529L,0x115c6ec75df871fL,0x061306a1b1640f4L, + 0x1f61fab8ef774acL,0x1aeec00d93d948cL,0x0d1647e9f13304eL, + 0x12567cfcc4ab628L,0x149349937b85a35L,0x018fd631e9863baL } }, + /* 238 */ + { { 0x0e8cf1b04913fb6L,0x009a80bb4d35997L,0x0dc5e0f987c1f90L, + 0x13c4fe5ffcf21d7L,0x0daf89bf1e5107fL,0x06f3468925d33ffL, + 0x0afb86248038796L,0x1552c4e6546dbebL,0x072cc37cfacbeb4L, + 0x062fd4b749e2d3bL,0x08c5f3798ce4eecL,0x1ccf06165ad8985L, + 0x041be5b96a97f65L,0x19867336a57e1a8L,0x103613c2fd02981L, + 0x0d6112d4374f326L,0x1f53ee182540762L,0x000ed9aedbd5865L }, + { 0x00fbc2dac0efee2L,0x175e6eb8edda2b7L,0x18f866da6afa101L, + 0x026fc03045ce57bL,0x11458b4c49cb7e6L,0x1e2eb1e5dc600e0L, + 0x19dd9082d211da1L,0x030308fbf428a98L,0x0bede911dd1839dL, + 0x1cee4e493c6f823L,0x0f58ae2068cdb06L,0x10f327cef5b8529L, + 0x0543ce3ba77f096L,0x1bb2777e3d64833L,0x111973c521a57f5L, + 0x19b63c1841e1735L,0x01d636e8d28a6e2L,0x03db5d4c66baa9aL } }, + /* 239 */ + { { 0x11d9e03c1881ab4L,0x12eaad98b464465L,0x151ca08d9338670L, + 0x01e2c35449505a7L,0x01ebb2c99599439L,0x163d3abc1c5e007L, + 0x0882a3f577f32f7L,0x0909ba407849feeL,0x15ec173b30efeffL, + 0x0f8e9598b21459aL,0x0f679415ba04fe6L,0x0575816633e380dL, + 0x04fd223b1592917L,0x0c6848f6b57071cL,0x151923af404167aL, + 0x1cf30d662d1c94cL,0x1082211447f3375L,0x023f4080cb8f5a2L }, + { 0x045d45abc8c290dL,0x089aac087d99d38L,0x02491beefcbe8cfL, + 0x1670b8f9b2575e0L,0x0161985cacff3f1L,0x0443a462d8a8767L, + 0x173231bb829fcaaL,0x0873b11191cbd11L,0x04dd735f2ccb864L, + 0x00f09db9e207b79L,0x0897ffcffb5a473L,0x162e4afdcb8ff87L, + 0x13f32db1354cb43L,0x016ff969d532a7cL,0x1298e5113d63428L, + 0x0cd2ef1c7e31151L,0x07b39646ccef3e8L,0x03c2d8c81706e74L } }, + /* 240 */ + { { 0x0ce2361a92f9a20L,0x0e543ceb22a077eL,0x0a1474035f16defL, + 0x185d2f924da8e73L,0x18da6a8b067ac8dL,0x028db495751fff3L, + 0x05069a0a2fd518fL,0x020ede388f2e2aaL,0x0f4bcbef63977d8L, + 0x0de24a4aa0de73dL,0x1d019b45c10695dL,0x0b7b0eeabd5fc03L, + 0x1d59e7ae80d282dL,0x1c1559b7b71083eL,0x14758d2a95b8598L, + 0x1b088cbdd1ded73L,0x02799a2160ace4eL,0x032abe1b3dbb896L }, + { 0x01b0268d75b6e52L,0x09b2008c68744abL,0x0cc1a8bac6bac20L, + 0x0cda1211299fea6L,0x15fc1d484e46222L,0x118316dd9a8913dL, + 0x0b7164d97a81d5eL,0x10e995946f7acdcL,0x1220d7d23b90958L, + 0x007e9c9c62239dfL,0x1cdc299e1f693e7L,0x1799a0afe9715bfL, + 0x0c1173f33aef0aeL,0x092d135a102f3a2L,0x0beeff6e347c296L, + 0x1a509526c9e92e4L,0x0b4c891ae778227L,0x00ae20682507045L } }, + /* 241 */ + { { 0x1af169a2a0e18d1L,0x0e00ba60193e14dL,0x08fdef098b3a65cL, + 0x1b031fe6f3b0346L,0x0cd3c3302099db8L,0x0d02a9b31fb31eaL, + 0x091c3bd4c970c04L,0x0e139ae17b9f301L,0x1e64452d11c9ed0L, + 0x1dfa1fa5633b709L,0x1b029aba170a96bL,0x0aa08e0921892f7L, + 0x07491e6ba92faaeL,0x157d4c8a055cbd4L,0x1c9955d0157d4deL, + 0x1ad7ff92b5b766cL,0x037646343b9d119L,0x03c474a504e9a0fL }, + { 0x13a6fe59c53461aL,0x044bf0471db7682L,0x0bcc1da364e5d7bL, + 0x0d98427a9f51ebaL,0x05b0147c9bd6bffL,0x1dc0b4ac863da08L, + 0x1e3a4828d8a2df1L,0x11f8cd410dcb79cL,0x13dd4d2824dec1dL, + 0x08567a260cee674L,0x0b61d7610d69fa2L,0x0f83d4c70364cc6L, + 0x17f0dcc12859016L,0x037c6a31d912cbcL,0x17be8e646984ad1L, + 0x0cf108430baf182L,0x093df55ec37119fL,0x048d8ce633c06f5L } }, + /* 242 */ + { { 0x1f2709dcb5d8b80L,0x0b0c17e1ab30775L,0x0644157be5a40eeL, + 0x1bc8f8868570e7bL,0x154f8867d1ea4b4L,0x06bbf7e625c9226L, + 0x1d58e4ec68b2bf6L,0x0ac0d1a49cfd183L,0x15f5fabb6499730L, + 0x192462802a11ba7L,0x178ad4fce3a44e0L,0x11d6f76d017d86dL, + 0x17d8f313b5ed07eL,0x17e969c94b2409eL,0x1228c69eeda81a6L, + 0x1864b80db091c10L,0x1af6867fb2fe4f0L,0x01e15d41a0339a1L }, + { 0x162d7759d3ad63bL,0x055cbacf0758fd5L,0x098ce217845cfe7L, + 0x1dc4165f3ce0665L,0x09eca947f22cafcL,0x146c46da94dd3f2L, + 0x055849255085988L,0x08901d447d87247L,0x01b8907e7d43706L, + 0x1bfd22aab1f2722L,0x060a7aca92c3e92L,0x0148900c0f25995L, + 0x0c246991ced0a72L,0x1a468435c666ed0L,0x02bb84cde88c96cL, + 0x04a7eacddaa13ecL,0x1d83d30e091147fL,0x00fd313d2e0839dL } }, + /* 243 */ + { { 0x11222a242478fd4L,0x06378b385900050L,0x013e0d671b7ab3dL, + 0x12f7279b79ee376L,0x030db60b618e282L,0x0d9d94cb70dd719L, + 0x15777c5ff4ed259L,0x0ff4b0c738d78e0L,0x0c3ea92ed4b817dL, + 0x0415953691d8452L,0x048a2b705c043a4L,0x1c8c41d13b2f08eL, + 0x1703ff77c9753b9L,0x15df3072e7bf27cL,0x03805f5b0fe0914L, + 0x0bdb73c86597970L,0x03e150a5acdc0a4L,0x033dc5e82a3cc3aL }, + { 0x06079b4f4797cf7L,0x04cc5681fef0173L,0x18e9532abbc78c7L, + 0x1deec92e22b546eL,0x0f29b1a764d9a1fL,0x136549be706e39dL, + 0x1a9e19986c20fedL,0x0c37e9ae9fc65f6L,0x125f6ef09df00a5L, + 0x1e21c1fc18e88acL,0x1304314daf78dcaL,0x1f3f10598cb6dabL, + 0x13451a99b8d4945L,0x15d608d240fa478L,0x029282850058735L, + 0x150493b29a9dbe3L,0x0df65363165a467L,0x03a14bd54d264d7L } }, + /* 244 */ + { { 0x09758a4e21124baL,0x0c0cc543ffde962L,0x1744f598e2a266fL, + 0x102bef7eec8bf79L,0x04e6d57e94645ffL,0x130edcafd339b7eL, + 0x051287ab991d64bL,0x0e8f2aeb81997bfL,0x0a3d1304725b31dL, + 0x040ef912655ad73L,0x1f4a6468a21fc9eL,0x0b2144d588b31b7L, + 0x12d8661d4a23d07L,0x0500a07b972c4c2L,0x0cde0a8ded704eeL, + 0x09d201f28333c7fL,0x112722aa0591bc1L,0x044d55bdd6aadddL }, + { 0x1345a96d656bdc7L,0x0e457f0bb669dc5L,0x02d8cb59310d0efL, + 0x0ef3705683ad2a3L,0x1fb0cf82fcf364aL,0x00943dc83d9a277L, + 0x043bfcf4320f144L,0x0b9d3e4d4b2699bL,0x1e5f5aaf207082bL, + 0x15b963af673e0b2L,0x042a06fa61b3593L,0x131ffe2a6d55d2bL, + 0x03a8263d5efeef4L,0x0a574395822b012L,0x081da1a502f853dL, + 0x09af57dcf7993c6L,0x146d496a27dc1bcL,0x00016e14baca055L } }, + /* 245 */ + { { 0x0533937b69d60c3L,0x1f2a97f4b93aaf7L,0x1e37031c9698982L, + 0x1d9565cf85623f6L,0x0e2322cb6982c27L,0x13827ba5e776ecfL, + 0x1859654ac67b448L,0x10a5be9850b0a94L,0x0ba40b5bf7b1924L, + 0x05e54a8008cfa95L,0x1f472f96b761bffL,0x0df7b3a1e582e8cL, + 0x14b8d4ebc99bf53L,0x02d4098b9e14b71L,0x0cd7dd81257e3d0L, + 0x0424518b3d1ace6L,0x0730b53d324e054L,0x026ab229a9e1dedL }, + { 0x122f8007e5c0877L,0x1a1f30654d3b239L,0x1d2e8b049c59206L, + 0x0fda626d84463e9L,0x18db30de0959685L,0x08475e574131911L, + 0x08c7994beb50266L,0x092171a30295e1aL,0x02680c54b09cbc3L, + 0x0a2b179a5f9dfc7L,0x14242c24ad657ffL,0x1948bc2bf868530L, + 0x11bc378168e6f39L,0x022d2543b80ba8cL,0x085506a41a512ceL, + 0x19169598dae9505L,0x062adc9bab3b155L,0x00f97c4e73b9836L } }, + /* 246 */ + { { 0x053ef419affefdfL,0x1f672a67c92b5c1L,0x0bcad113920c175L, + 0x1f974a8e3e6ee00L,0x15cbe015b189755L,0x05c214e44241e5eL, + 0x1d874953df1a5a8L,0x0ae310a17a8c3e7L,0x17ba210890a2471L, + 0x0d5de176c977586L,0x1b2afa5977b224dL,0x0e4978aad095f6aL, + 0x0f6a7a74929da23L,0x177a5d236c5d1cbL,0x026c9ebf2e436dcL, + 0x06cddba469fc132L,0x147bdf3c16476f4L,0x004e404bf8bf286L }, + { 0x004b14060050c07L,0x1418c21d471bf35L,0x06caed57907f0a7L, + 0x1459cc1c7597285L,0x1b9d82f4ed2fea5L,0x1e9bfd6e3d8ff9eL, + 0x1d4e523afb30da1L,0x124f22a7c65d960L,0x06a60054f570756L, + 0x038e6864003acddL,0x1ce1bcc248b7c4eL,0x0b3d066af6f82f4L, + 0x09394151864e9fcL,0x09a6dc448e9359dL,0x1f36dc644a8088bL, + 0x0606ccce5f9e8b3L,0x16c5a3f268d44ffL,0x037889f69b488f0L } }, + /* 247 */ + { { 0x0a9df591836f1c9L,0x08cfaa119183ea9L,0x1c0577b4a16be99L, + 0x155ec4feeb080d8L,0x0ce0417d0a1545cL,0x089a21d70888f75L, + 0x12f2feca2f7da98L,0x0b1bd3de156a5b7L,0x1e9dc181b7813e6L, + 0x18ed5edcc893912L,0x16638c8a0531642L,0x0cddb269dcfcbe0L, + 0x1ab99ba4bf5c3b9L,0x1e0daaf3a75c276L,0x0aa183eca4668d0L, + 0x03fed535bb69329L,0x1e21b7220dff681L,0x0331b511de8d0c1L }, + { 0x15d5a2d20587283L,0x01164f783fe2eefL,0x15543bdb78e02ceL, + 0x0e4ba2ce3a2f0d7L,0x1cdb1def163cf90L,0x017e253a5fcb8f8L, + 0x153dd5d27a0c021L,0x1961c5db78e4ff0L,0x1bb27bbdabce24aL, + 0x0d8ce7602df6846L,0x0848fbdf2412f30L,0x1e37b13305b755bL, + 0x0e65f6e63202429L,0x172cfe9924e9b0bL,0x07ca7d68de27ea3L, + 0x0f1402c174775fdL,0x0f80f2d3b61af53L,0x03d77663b39e153L } }, + /* 248 */ + { { 0x1a4757cdc43b0dbL,0x12742cc08ce56f9L,0x0fd9185b0558f62L, + 0x189ea67d2ff012bL,0x19cfc5ad3e2a07bL,0x14029654c121b39L, + 0x1b198629ae8eb35L,0x12b7ac1cb211439L,0x1ae3841a502b1b6L, + 0x036ff890c850cadL,0x0afab2b4c7f66e6L,0x044998e51ef65beL, + 0x180cf0a9927d893L,0x0c35227561c7539L,0x057c0f2a10e6a01L, + 0x1f10bdbcfefe02cL,0x0454824990827a1L,0x0147620035bc53bL }, + { 0x1820c2ea2fe0009L,0x1d2e9789c3a74f0L,0x115314936d4b846L, + 0x0cffdbca532ea44L,0x1b2500d44d47742L,0x14922580e9a0cd4L, + 0x186e73822924861L,0x1c1742d2047ba37L,0x0242c3e5432a301L, + 0x1ab7bdd384833c4L,0x14a8271d2a33126L,0x1083aedf2873e15L, + 0x0b621fb60e99cd1L,0x1e1cbb1a76ed7f0L,0x1fc2a1015afb952L, + 0x1815e8ca7f0c1feL,0x1c36bd4876f2011L,0x009a7a663864a92L } }, + /* 249 */ + { { 0x021a3ece938dff4L,0x00d3da4353cd1cbL,0x1e5f7a5414ddf44L, + 0x13ccbb0fb7e589dL,0x173b8cfaf318409L,0x0148b75c4e3ffd9L, + 0x09d91a2ea9417a1L,0x0574f21fa129d7dL,0x1679df6d4e59289L, + 0x011998e7e7f6ba0L,0x13bf4a6203fc848L,0x1bbba0688a0217eL, + 0x0b342858c87ca78L,0x12baa43d16584f6L,0x12c1246797adb70L, + 0x1a8e2a0ceb42bd7L,0x0f409d2e74f7381L,0x03751bc14c1e9ebL }, + { 0x05c094b4e5cc40aL,0x11fb50d79befde3L,0x1a77e409b911e8bL, + 0x0b27101ea7decefL,0x1f644aa9b7878c9L,0x10461e25518583bL, + 0x198ee83145a0cbcL,0x060f804ef5ccb1aL,0x0ef0b3c38ae1d91L, + 0x0179bd3b4ae1f52L,0x130715a8317834cL,0x0b8841979f3fc00L, + 0x1d568a0e7c9fd49L,0x0c94322a3836adcL,0x069c2722c8977fdL, + 0x11ad0a4fa88cb1bL,0x07d47c558da87c0L,0x0303773735da778L } }, + /* 250 */ + { { 0x0d99fc757c621f6L,0x12060bff41ea401L,0x1e867bc666c0a4bL, + 0x05cc58eccc37bf8L,0x0673875378a0410L,0x1d32d78b66d1b87L, + 0x18826f2065d3478L,0x18c32e84091ef1fL,0x1c83a058abf5981L, + 0x135921a4e44b816L,0x0cbc7a74699e2bcL,0x1361fe535c53311L, + 0x181d7cf5ec472bfL,0x19346eec50a1f1cL,0x113fdda7275f916L, + 0x0ece62cd9b4aabfL,0x1076044cdf0a4aaL,0x024edd37bf48a43L }, + { 0x0e47fb2a758e37aL,0x198eb96c757b310L,0x17e5be708842bdaL, + 0x0f21df86566a55aL,0x01e4b2640093f72L,0x18abcaa1ae4cee2L, + 0x0d5d6fea1e38016L,0x0b3338a41481cceL,0x1ca68259487eea7L, + 0x14fbdc0f8951a45L,0x1f3060aa8b38d40L,0x0e97d5abc58b4a8L, + 0x1b55682cdfa11d8L,0x05df47334d781a4L,0x14e52afe1baffaaL, + 0x1d71e7b570f05eaL,0x18c458bf797ebc8L,0x0244853d24dbef3L } }, + /* 251 */ + { { 0x12996898da995f6L,0x15573f630ab77ebL,0x1030d5aa0b574e7L, + 0x03826b79fcd2b20L,0x0f595c78b2046b2L,0x02fda0753905b20L, + 0x0eff00a093beb9fL,0x17d2fb1fa981db6L,0x112f0290579f24eL, + 0x17e23e78c3f535cL,0x07f49de275708c5L,0x16d9124c7d99843L, + 0x128b6d30a6233a6L,0x04d99b40411b1a5L,0x11dd15b28d4b897L, + 0x00cb72711ad9481L,0x076f8e55b0b3c92L,0x02e0ba3a58121cdL }, + { 0x088e7c28aaccab5L,0x13c1b5567682decL,0x1df733b03d94600L, + 0x1824b8510430b70L,0x07fdc54c93cadc1L,0x1c4519a2efaa053L, + 0x1e8b13cf21b8b09L,0x19e7d0e88d3c741L,0x1c59daa47273983L, + 0x031e245a54b6c52L,0x14af3f0b962454cL,0x170f09c85187871L, + 0x0cf0c4fd5390e78L,0x0a0f3002c805149L,0x094e872dfe4b6deL, + 0x01f4f2acf2482d9L,0x08c35f6f31db1abL,0x02eb3af5a3dac20L } }, + /* 252 */ + { { 0x0ee1a77870c6025L,0x111dbc8d16fe557L,0x0310e1ad9313f12L, + 0x1bcb5ce562f61ccL,0x1eefa212d5d5b17L,0x01c5cb36fe44564L, + 0x0bb313fabbefb50L,0x00e133586ad1c5aL,0x0548ea612012af2L, + 0x1ff6cedc4e1890cL,0x1a47138399ccc53L,0x0c9f5f0601c0383L, + 0x1c6773c3be009bbL,0x00410cfd43c0280L,0x06c1bff8335bb7bL, + 0x166def80abc0ff0L,0x0a382b63f9ce080L,0x0017e65d7854ff6L }, + { 0x191d4d1b47cac61L,0x08b43d5c370964cL,0x17b0ae53c108ba7L, + 0x1291cc91cb18d0aL,0x0f89ac57ca40051L,0x13c966cdd48fd97L, + 0x078553d0648186fL,0x03305a443977a1eL,0x0062eb13bfc4440L, + 0x1d4be194cbc87eeL,0x05b651819e992fcL,0x0600da46eeb49cfL, + 0x15ed7f0f23c46ddL,0x1da7b1ebc339626L,0x189cfca08614770L, + 0x01edea1475c19a4L,0x145800e58fceac6L,0x02b78f22b09c22aL } }, + /* 253 */ + { { 0x1ccb3f632c24f3bL,0x18e3f836c0bf300L,0x02edaa899dda67aL, + 0x1c108babc11b8c8L,0x181a79a87838affL,0x140cd879a7f658fL, + 0x092e1a8b8a0b4f9L,0x0738972ef9d046fL,0x10f46b3db876364L, + 0x032faa04bcb824bL,0x021d8a1e46f90e9L,0x16d868331d8dafcL, + 0x17093d94bb00220L,0x14eb48592bd9c31L,0x0ab46921004b858L, + 0x069c605d93b6a41L,0x0f8afee2fc685dcL,0x0488e8c9b12a806L }, + { 0x1b1bd58f5e5af5bL,0x1131dbdb5115389L,0x1137cebcab729f2L, + 0x134088417b56d7dL,0x0ba36c1116651e5L,0x0121881da2459daL, + 0x1b2ecf18aff37fdL,0x101bc2b894be352L,0x0be0ad8a1e4d1f9L, + 0x095e8a71b339d1dL,0x00ebda484ab3760L,0x1738aec12b9c806L, + 0x0a107f5ca58f6daL,0x044b51d83ef8c41L,0x18ecfc2e40f98f2L, + 0x10fbdea090a89b0L,0x0655e5019b9c098L,0x015f3a27f507a9cL } }, + /* 254 */ + { { 0x14cd05f5b50f324L,0x0f5920f51e3d102L,0x0971ffe39adee6cL, + 0x1dd8081104950b1L,0x10cba9bdd83902fL,0x0e4f0f3959324a6L, + 0x16e07405dbe42caL,0x1f80ba9d6059d75L,0x0874405b1372b8bL, + 0x0209440bcf568c8L,0x08f74fb0ad23357L,0x14ee7e9aa067a89L, + 0x0d564c3a0984499L,0x1a17401dd9bd9c6L,0x1d462ca03a6525fL, + 0x1fbc980f68f4171L,0x07ac710e3c53568L,0x039afaa17e75687L }, + { 0x0a9a17138380039L,0x17f0bfba68ce465L,0x04fb32f06a2eb7eL, + 0x13fc052e0b25a87L,0x130e9b363c5dbf3L,0x1ea4a522a95ad5cL, + 0x0b10dfb98c0c8abL,0x13104d535ae7e05L,0x198c53562993562L, + 0x0434fc3b9a15d9cL,0x04008393e6de683L,0x0349a68f1353aeaL, + 0x1acfa856376361dL,0x045603f2786f6adL,0x1bc72f501fb9cfeL, + 0x0b75bf58fa07e13L,0x19e25d697cb4d47L,0x00f4c264e8a5e9cL } }, + /* 255 */ + { { 0x16d05614850c817L,0x12d8c9a44c096e3L,0x055179632efac22L, + 0x1497cc3cb4e4e7aL,0x17aeb8e18900b5fL,0x0d1ea5d5044348eL, + 0x1f4f799999abf4dL,0x0b871458332afd8L,0x0a0648e8f668d6fL, + 0x1cfe4963d6e0ba3L,0x045b0210c1970c7L,0x1440c3cd5cd2474L, + 0x162aa47e7336370L,0x0f7fb6c231361b9L,0x0fb4b51503097cbL, + 0x12925300904999bL,0x0014b5bfce0039aL,0x03623a52b3b4a17L }, + { 0x0eb9a417d88e3a1L,0x09e4462423a151dL,0x0344ff9844c4417L, + 0x16350d3d17cb3bdL,0x0a75d90a148f5b6L,0x0a3009bd455e2cdL, + 0x13364bc326f1d88L,0x12487f54e8f8704L,0x081763a186a5d0bL, + 0x1e1a0de4de5d75eL,0x04c583dd174776eL,0x0a5b6eb9cbe9c30L, + 0x0cd50de4c2a53ceL,0x1aebb2b68af5733L,0x12954a97b6265b1L, + 0x00b69c9feae2389L,0x0ce215e985a3c53L,0x03592c4aa7d0dd1L } }, +}; + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^128, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_base_18(sp_point_1024* r, const sp_digit* k, + int map, int ct, void* heap) +{ + return sp_1024_ecc_mulmod_stripe_18(r, &p1024_base, p1024_table, + k, map, ct, heap); +} + +#endif + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_1024(const mp_int* km, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_digit kd[18]; +#endif + sp_point_1024* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_18(heap, p, point); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 18, km); + + err = sp_1024_ecc_mulmod_base_18(point, k, map, 1, heap); + } + if (err == MP_OKAY) { + err = sp_1024_point_to_ecc_point_18(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_18(point, 0, heap); + + return err; +} + +/* Multiply the base point of P1024 by the scalar, add point a and return + * the result. If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_add_1024(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_point_1024 a; + sp_digit kd[18]; + sp_digit t[18 * 2 * 5]; +#endif + sp_point_1024* point; + sp_point_1024* addP = NULL; + sp_digit* tmp = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_18(heap, p, point); + if (err == MP_OKAY) { + err = sp_1024_point_new_18(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (18 + 18 * 2 * 5), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 18; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 18, km); + sp_1024_point_from_ecc_point_18(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_1024_mod_mul_norm_18(addP->x, addP->x, p1024_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_1024_mod_mul_norm_18(addP->y, addP->y, p1024_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_1024_mod_mul_norm_18(addP->z, addP->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_ecc_mulmod_base_18(point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_1024_proj_point_add_18(point, point, addP, tmp); + + if (map) { + sp_1024_map_18(point, point, tmp); + } + + err = sp_1024_point_to_ecc_point_18(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_18(addP, 0, heap); + sp_1024_point_free_18(point, 0, heap); + + return err; +} + +#ifndef WOLFSSL_SP_SMALL +/* Generate a pre-computation table for the point. + * + * gm Point to generate table for. + * table Buffer to hold pre-computed points table. + * len Length of table. + * heap Heap to use for allocation. + * returns BAD_FUNC_ARG when gm or len is NULL, LENGTH_ONLY_E when table is + * NULL and length is returned, BUFFER_E if length is too small and 0 otherwise. + */ +int sp_ecc_gen_table_1024(const ecc_point* gm, byte* table, word32* len, + void* heap) +{ + int err = 0; +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; +#endif + sp_point_1024* point = NULL; + sp_digit t[5 * 2 * 18]; + + if ((gm == NULL) || (len == NULL)) { + err = BAD_FUNC_ARG; + } + + if ((err == 0) && (table == NULL)) { + *len = sizeof(sp_table_entry_1024) * 256; + err = LENGTH_ONLY_E; + } + if ((err == 0) && (*len < (int)(sizeof(sp_table_entry_1024) * 256))) { + err = BUFFER_E; + } + + if (err == 0) { + err = sp_1024_point_new_18(heap, p, point); + } + if (err == 0) { + sp_1024_point_from_ecc_point_18(point, gm); + err = sp_1024_gen_stripe_table_18(point, + (sp_table_entry_1024*)table, t, heap); + } + if (err == 0) { + *len = sizeof(sp_table_entry_1024) * 256; + } + + sp_1024_point_free_18(point, 0, heap); + + return err; +} +#else +/* Generate a pre-computation table for the point. + * + * gm Point to generate table for. + * table Buffer to hold pre-computed points table. + * len Length of table. + * heap Heap to use for allocation. + * returns BAD_FUNC_ARG when gm or len is NULL, LENGTH_ONLY_E when table is + * NULL and length is returned, BUFFER_E if length is too small and 0 otherwise. + */ +int sp_ecc_gen_table_1024(const ecc_point* gm, byte* table, word32* len, + void* heap) +{ + int err = 0; + + if ((gm == NULL) || (len == NULL)) { + err = BAD_FUNC_ARG; + } + + if ((err == 0) && (table == NULL)) { + *len = 0; + err = LENGTH_ONLY_E; + } + if ((err == 0) && (*len != 0)) { + err = BUFFER_E; + } + if (err == 0) { + *len = 0; + } + + (void)heap; + + return err; +} +#endif +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * gm Point to multiply. + * table Pre-computed points. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_table_1024(const mp_int* km, const ecc_point* gm, byte* table, + ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_digit kd[18]; +#endif + sp_point_1024* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_18(heap, p, point); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18, heap, DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 18, km); + sp_1024_point_from_ecc_point_18(point, gm); + +#ifndef WOLFSSL_SP_SMALL + err = sp_1024_ecc_mulmod_stripe_18(point, point, + (const sp_table_entry_1024*)table, k, map, 0, heap); +#else + (void)table; + err = sp_1024_ecc_mulmod_18(point, point, k, map, 0, heap); +#endif + } + if (err == MP_OKAY) { + err = sp_1024_point_to_ecc_point_18(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_18(point, 0, heap); + + return err; +} + +/* Multiply p* in projective co-ordinates by q*. + * + * r.x = p.x - (p.y * q.y) + * r.y = (p.x * q.y) + p.y + * + * px [in,out] A single precision integer - X ordinate of number to multiply. + * py [in,out] A single precision integer - Y ordinate of number to multiply. + * q [in] A single precision integer - multiplier. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_mul_qx1_18(sp_digit* px, sp_digit* py, + const sp_digit* q, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 18; + + /* t1 = p.x * q.y */ + sp_1024_mont_mul_18(t1, px, q, p1024_mod, p1024_mp_mod); + /* t2 = p.y * q.y */ + sp_1024_mont_mul_18(t2, py, q, p1024_mod, p1024_mp_mod); + /* r.x = p.x - (p.y * q.y) */ + sp_1024_mont_sub_18(px, px, t2, p1024_mod); + /* r.y = (p.x * q.y) + p.y */ + sp_1024_mont_add_18(py, t1, py, p1024_mod); +} + +/* Square p* in projective co-ordinates. + * + * px' = (p.x + p.y) * (p.x - p.y) = p.x^2 - p.y^2 + * py' = 2 * p.x * p.y + * + * px [in,out] A single precision integer - X ordinate of number to square. + * py [in,out] A single precision integer - Y ordinate of number to square. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_sqr_18(sp_digit* px, sp_digit* py, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 18; + + /* t1 = p.x + p.y */ + sp_1024_mont_add_18(t1, px, py, p1024_mod); + /* t2 = p.x - p.y */ + sp_1024_mont_sub_18(t2, px, py, p1024_mod); + /* r.y = p.x * p.y */ + sp_1024_mont_mul_18(py, px, py, p1024_mod, p1024_mp_mod); + /* r.x = (p.x + p.y) * (p.x - p.y) */ + sp_1024_mont_mul_18(px, t1, t2, p1024_mod, p1024_mp_mod); + /* r.y = (p.x * p.y) * 2 */ + sp_1024_mont_dbl_18(py, py, p1024_mod); +} + +#ifdef WOLFSSL_SP_SMALL +/* Perform the modular exponentiation in Fp* for SAKKE. + * + * Simple square and multiply when expontent bit is one algorithm. + * Square and multiply performed in Fp*. + * + * base [in] Base. MP integer. + * exp [in] Exponent. MP integer. + * res [out] Result. MP integer. + * returns 0 on success and MEMORY_E if memory allocation fails. + */ +int sp_ModExp_Fp_star_1024(const mp_int* base, mp_int* exp, mp_int* res) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td; + sp_digit* t; + sp_digit* tx; + sp_digit* ty; + sp_digit* b; + sp_digit* e; +#else + sp_digit t[4 * 2 * 18]; + sp_digit tx[2 * 18]; + sp_digit ty[2 * 18]; + sp_digit b[2 * 18]; + sp_digit e[2 * 18]; +#endif + sp_digit* r; + int err = MP_OKAY; + int bits; + int i; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8 * 18 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + tx = td + 4 * 18 * 2; + ty = td + 5 * 18 * 2; + b = td + 6 * 18 * 2; + e = td + 7 * 18 * 2; +#endif + r = ty; + + bits = mp_count_bits(exp); + sp_1024_from_mp(b, 18, base); + sp_1024_from_mp(e, 18, exp); + + XMEMCPY(tx, p1024_norm_mod, sizeof(sp_digit) * 18); + sp_1024_mul_18(b, b, p1024_norm_mod); + err = sp_1024_mod_18(b, b, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(ty, b, sizeof(sp_digit) * 18); + + for (i = bits - 2; i >= 0; i--) { + sp_1024_proj_sqr_18(tx, ty, t); + if ((e[i / 57] >> (i % 57)) & 1) { + sp_1024_proj_mul_qx1_18(tx, ty, b, t); + } + } + } + + if (err == MP_OKAY) { + sp_1024_mont_inv_18(tx, tx, t); + + XMEMSET(tx + 18, 0, sizeof(sp_digit) * 18); + sp_1024_mont_reduce_18(tx, p1024_mod, p1024_mp_mod); + XMEMSET(ty + 18, 0, sizeof(sp_digit) * 18); + sp_1024_mont_reduce_18(ty, p1024_mod, p1024_mp_mod); + + sp_1024_mul_18(r, tx, ty); + err = sp_1024_mod_18(r, r, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + return err; +} + +#else +/* Pre-computed table for exponentiating g. + * Striping: 8 points at a distance of (128 combined for + * a total of 256 points. + */ +static const sp_digit sp_1024_g_table[256][18] = { + { 0x000000000000000L, 0x000000000000000L, 0x000000000000000L, + 0x000000000000000L, 0x000000000000000L, 0x000000000000000L, + 0x000000000000000L, 0x000000000000000L, 0x000000000000000L, + 0x000000000000000L, 0x000000000000000L, 0x000000000000000L, + 0x000000000000000L, 0x000000000000000L, 0x000000000000000L, + 0x000000000000000L, 0x000000000000000L, 0x000000000000000L }, + { 0x10a46d2335c1685L, 0x0f4b8f0803d2c0bL, 0x0f7d0f2929cfab2L, + 0x0b04c848ea81d1eL, 0x136576d12646f81L, 0x1f8d7d9d7a4dda5L, + 0x1479b6278b451caL, 0x0f84f7d10585fa2L, 0x1addedc858f8871L, + 0x16c2cdf8b563637L, 0x10686cb63ab9635L, 0x1400c383e61a1ceL, + 0x1a9b67e0966faf7L, 0x1e9da7beb36de84L, 0x09f263887c47019L, + 0x16442c2a574058eL, 0x0f4afd58891e86cL, 0x02cf49e3535e9ddL }, + { 0x14dd36f71dd4594L, 0x0e64f805778f372L, 0x113a867d94c2ef2L, + 0x127ea412513d4b4L, 0x0f5c14188588aa9L, 0x09ccfd4ba9bca64L, + 0x1aad4462f5e4b04L, 0x0a5737a75fbeb96L, 0x1813d1cb22ecb96L, + 0x0a2b133a01c4c09L, 0x1c466d2b210c73fL, 0x152214301d6ca3eL, + 0x179f7bfa2edd9f6L, 0x0854e86c89ca368L, 0x00dcf4c5bc618c5L, + 0x0a572be33841adfL, 0x003be85ac6a9b6aL, 0x031f78c3dba7b17L }, + { 0x0376b7f016f45e7L, 0x1edab95f6417c3eL, 0x1d07390a6d80706L, + 0x058f5fb03ae725eL, 0x1241098b6fdbf0aL, 0x107c67ded20d8fbL, + 0x0f1356d01d1d2edL, 0x17d267c1a836661L, 0x1ae182830733fa3L, + 0x07694cd87ae3668L, 0x0cd538fe6183228L, 0x130c2aab3882ffeL, + 0x1c129f85cbb1360L, 0x03b42fdf55865b1L, 0x06658cda0bb3125L, + 0x059b4a0bd1d85d6L, 0x02390dcc794ddacL, 0x027f33c8e78c96dL }, + { 0x0a423d505e8733cL, 0x02f328eab8be0caL, 0x1a23a586cc8b321L, + 0x0db683039846f8fL, 0x113bd7210c4471cL, 0x00bd8480643af13L, + 0x1abda77f7a7b6cbL, 0x14c8614dbcbd119L, 0x1aaa7a61a7b81ceL, + 0x1296813119fcc6aL, 0x1bf74181a26a6baL, 0x0f9cb95895576abL, + 0x148e95076130cfaL, 0x074d0f297d26d88L, 0x01005c0c255c311L, + 0x1b3a431843ec234L, 0x097555d1ffebe78L, 0x00224150c2b0ed9L }, + { 0x1758ac273d486d8L, 0x0fca330e6e0f3f3L, 0x07f08622ad3e05aL, + 0x05e66e6c60e4793L, 0x1d8c2260a0e54f0L, 0x18de302b05f712dL, + 0x1fad4a3f0c1f114L, 0x06fade43e34fc89L, 0x1c8e4499c57128dL, + 0x11d829f6bd97522L, 0x09e810ca8f488a5L, 0x0a9a6a8b2cd0818L, + 0x1fd73557e95b518L, 0x034903bd3370d24L, 0x0d09c083499ff66L, + 0x1b689f426a1a7ceL, 0x09f1a9c3f2568ccL, 0x0419d07fc6f6dfcL }, + { 0x0c419c7ab376b76L, 0x14a7993e8786654L, 0x078aa4314534edcL, + 0x1d4c4aeb4dcad77L, 0x098c0a88931ba51L, 0x00b5152b7f703d8L, + 0x0982c12f96bbad3L, 0x0e1ca266a17cdd6L, 0x1339edad6a1d5c2L, + 0x1b376acf4edd6e8L, 0x0efa20b741bb03cL, 0x139196230fb6842L, + 0x01d8a1058a22d63L, 0x115ba2788ff64afL, 0x1c170300fdcfa9aL, + 0x02340e83faa35e9L, 0x05f2e2df95a85f8L, 0x034959e71f5924bL }, + { 0x0e6cb72d2a127b4L, 0x03752c7c940b786L, 0x118d1e8dd8599a9L, + 0x03c1572ddc87d9eL, 0x12edbe8c163d9a0L, 0x127332e40a2e36dL, + 0x14be4bd09b2b937L, 0x0622e9a1680e9c4L, 0x054c240d77d2af8L, + 0x00fd1cb9eb2949bL, 0x05247282751a556L, 0x0a66a8a4c8780b7L, + 0x11d41283278c4e8L, 0x181b0f92996b219L, 0x1bc27c9911e40e1L, + 0x0bfc0ee83236313L, 0x0d6c0cf0aaf81deL, 0x0199f21857a0021L }, + { 0x1f04de4cf26d3b7L, 0x1b9835a9fbcdf2eL, 0x117c6022d9915e9L, + 0x090a06e6c148027L, 0x0b061037ef291eaL, 0x0489dd8ffe4ebe8L, + 0x0161f6741376597L, 0x0ab29146f5fe277L, 0x0b5443483fe3ee7L, + 0x1e10f3a023189c3L, 0x041397377ad630fL, 0x10c4cae59aa5674L, + 0x0115aaa40894fe1L, 0x02cf523175cd38dL, 0x1ac0a8e2b71bf95L, + 0x123a37631a2ea95L, 0x108ae1276362f77L, 0x00874598eeb5debL }, + { 0x07f03e53ed9f1afL, 0x0923bab33b0b35cL, 0x18c1d33856e00ebL, + 0x004d63d0b671b9aL, 0x1af99c151877e2bL, 0x012a3d58b2a68b8L, + 0x17bd65e0ba7924eL, 0x098db8ff8f84daaL, 0x19038f95d2fbeb5L, + 0x12c86ff01b601abL, 0x0dbab93f70fdfffL, 0x18a9e6bc35119f9L, + 0x12da0a5568cb1fbL, 0x0db7aaab9e470edL, 0x0b0281a6a1ce4fdL, + 0x12b5670c8d665cfL, 0x0bcfd261c832a84L, 0x03242a926066e62L }, + { 0x0bfb3e2c4a6ff2aL, 0x01fdd1ad321450dL, 0x1fc226bfdd08aa8L, + 0x1574bb7b2710844L, 0x12a182cb2337883L, 0x100f829c0c3574eL, + 0x079eae7c1d93526L, 0x0b724823fd722f6L, 0x0700b1903570cbbL, + 0x0a8c0eadc8a5f3eL, 0x1110dc660460b57L, 0x1a48ae97332e26bL, + 0x15632d28b232758L, 0x1d1c1f84d328547L, 0x08cf600901e2eb3L, + 0x16892ca8d4c1801L, 0x03ca4061c7a2df8L, 0x00fbb79f9791a2bL }, + { 0x0a2c14344c436b0L, 0x182ab0fb4e43d4dL, 0x05ed7db6cb7de41L, + 0x03daad75046be62L, 0x1d0afa4885761f4L, 0x0e738f7c18a327bL, + 0x1d222a67ca454ebL, 0x07564f7ed2622d6L, 0x0a98a5a8c9bb944L, + 0x1c3c0131772fef4L, 0x1e4f74604ab2ddfL, 0x0999b909792474dL, + 0x0ff1d4995aaf92aL, 0x0276c4ce9e12b15L, 0x14a94e3f67f0cf0L, + 0x14e4d805195289dL, 0x005d0f367bb049eL, 0x0024927fd9e8847L }, + { 0x0548e3dc673562fL, 0x19812f175724603L, 0x0cad7871a5df4ecL, + 0x08dd7caaf7cc3faL, 0x01d6e18e424e206L, 0x0bf4adbb39c8e02L, + 0x06e312e3aee3853L, 0x1a695d16fa84132L, 0x0f8a0df66e01290L, + 0x0bf1251c92f2fa7L, 0x1ecb2c54209cab2L, 0x0e5c4a0e4cc2f34L, + 0x029062fa49b40b0L, 0x19e29de76d6cf0cL, 0x0509e661e029e13L, + 0x1084cb15056ed3eL, 0x03508cd849cc146L, 0x026fe7404e1c057L }, + { 0x1069cb2d527b780L, 0x0d00acbbc986ea2L, 0x002f89f4098f54bL, + 0x0d765a36562198cL, 0x154adf3c34102c2L, 0x187fa3a6329311aL, + 0x1b9f35a244e0917L, 0x11507f5198b9522L, 0x11e10f139d15c8dL, + 0x0b9ee1740ee2b59L, 0x1b2c11713b66ebcL, 0x0fb08fa02450ff9L, + 0x139f3a532f307fdL, 0x110a9e111252b8aL, 0x0a2902167a7a077L, + 0x17a478ac4b2bbc8L, 0x002dc7daff89339L, 0x00683ac845c5034L }, + { 0x10af2a7de085f2aL, 0x06927df4cd972c3L, 0x0985672904ee23fL, + 0x090ab3f0a31181aL, 0x1622da0d1f02a2eL, 0x051b0ac1dcb010fL, + 0x11a0970170bd5b7L, 0x17c02919e38f221L, 0x0392f2896272695L, + 0x01e85dad46b277bL, 0x14891073f2f14a2L, 0x19d8a4c22fcbde1L, + 0x19f04928e9f5dafL, 0x1c9f97155b43095L, 0x0304544a0fdd134L, + 0x01bfdf7ddafdae0L, 0x15af2cde215a436L, 0x0127d4b0e178429L }, + { 0x167db3f616df7f6L, 0x02bec7dec819303L, 0x0a41ba0b551190cL, + 0x0ad12c87b62e9b5L, 0x0c89a0602284f34L, 0x013e890c58c8efeL, + 0x14516ead1abd35bL, 0x13cb4afe90d9312L, 0x0c03214e9cc942fL, + 0x19f0e47a0ca80acL, 0x0dd67ce6b50eac9L, 0x16ffca1dc2e719dL, + 0x1c8f4d7d4e5e1b8L, 0x1aab01f9fb1ad8fL, 0x14be9823bfddf8dL, + 0x16dc2403ec3a2eeL, 0x11494d7a03d4a6fL, 0x01b8e611efe2780L }, + { 0x09b115dda90c351L, 0x0b75f9b26ce0314L, 0x080bd942cc6db46L, + 0x08deaec85eef512L, 0x08100127cc28c16L, 0x06403dee27bf1b0L, + 0x103ca20db342371L, 0x0a62501e2adc004L, 0x03f9a6d7899cb39L, + 0x0524a699d40101cL, 0x05fa47a1f4d1d10L, 0x1a0e4dbbc4948adL, + 0x0d7640c30e70d97L, 0x0dd37363037b52cL, 0x0f04fa00f0b03a1L, + 0x1af1e661ed4f5e3L, 0x17f3e602e4fc9f4L, 0x0495b5e5006407dL }, + { 0x03d5c835f00822eL, 0x12b895c58b78917L, 0x07124ac28cc03a0L, + 0x1b4f9832a903865L, 0x1bb1413f6b4e32aL, 0x09651385f74e770L, + 0x0454fb7edeea92aL, 0x1f39a8e55f5d477L, 0x0e8f09e7e00f0c0L, + 0x070ec392e6f5db8L, 0x0eb8212a6d8eda9L, 0x03707fab1ecbfc5L, + 0x1aa3b62759f4014L, 0x1c8718446bf62f6L, 0x09df8c66abdb99dL, + 0x10e3842b5b0603eL, 0x09de7db4b98cf33L, 0x038ffb164a7817cL }, + { 0x04c71022a4a84d9L, 0x12566af5e38f355L, 0x0297c73595e38bbL, + 0x1fffe2414a76235L, 0x09e6503383f5ef9L, 0x0220c05262cc708L, + 0x0a30787a7e64328L, 0x0d717065a8deb30L, 0x0753f28a033af53L, + 0x176e258db6a7b45L, 0x19a4a9cb3347c24L, 0x1efba444c865dbbL, + 0x1ea3d2661cd3aa0L, 0x1ee1beed1c6ddb1L, 0x1bdad33c7867f1bL, + 0x174d2d83166a109L, 0x073e6a83fe9df1bL, 0x0207ea3f3afcac1L }, + { 0x188b746267140a4L, 0x1fe0f755b797dadL, 0x0239a6189521b6eL, + 0x025d6ddf85bb3d9L, 0x0ac8ff8869beebaL, 0x110ca867e110a54L, + 0x1eda6575725bad6L, 0x06f2671380a82e3L, 0x02d85d4521b4683L, + 0x06b45042089a12eL, 0x1004e7b1b085d05L, 0x172fee60109bca5L, + 0x061f578aa320cf0L, 0x1cdb57218d60b51L, 0x1529a5462e7eacfL, + 0x1c50cd1b04223b0L, 0x18c0b334d98dffbL, 0x02d8e08abf31c99L }, + { 0x0edaab172b6bb8fL, 0x12769017e496148L, 0x0f17f9a531ce371L, + 0x1f96a9b9c9e8574L, 0x032420dc316dc65L, 0x16e7ca6596b351bL, + 0x0b2745b9c1b9c15L, 0x15050138ec949e6L, 0x1ab18d830ea6edcL, + 0x1e8d67340e32fabL, 0x059471f684b0413L, 0x1acd8ef234903f2L, + 0x14785e67a30ac3bL, 0x0d07eac8db568e7L, 0x0718d13934ff113L, + 0x015679c2c9002dcL, 0x0f484de9cb833e5L, 0x04b1d5c1d53ab77L }, + { 0x04b47d8df4ea5a3L, 0x1440aae7f22ff4aL, 0x156228f0d592595L, + 0x1dcf933c2ba2dcfL, 0x155071bc84e55b3L, 0x02bee71ff71026fL, + 0x155c1c401bca410L, 0x159fd18721b774eL, 0x03645bcb63319adL, + 0x0c4f4583e105fecL, 0x1425a5f5f655e20L, 0x0643733e9c771caL, + 0x01a60cfb6a037d1L, 0x01b9c16d008d929L, 0x107701d99652aaaL, + 0x13109913723fb07L, 0x1586b82b899076bL, 0x0221a407e5f22e2L }, + { 0x0ffffb49114221aL, 0x027971f42bd3d7cL, 0x03903e951e1d2bbL, + 0x03adf2c2a485c5aL, 0x1bfe9b77ef3e6b3L, 0x01d4355914b29bfL, + 0x0ab1b0aa743cbedL, 0x0f6482509da48aeL, 0x1a3868917e721baL, + 0x1f7be00608bd3c6L, 0x1241c74c5816b36L, 0x153c0cb51dd2702L, + 0x18c442be82c2dadL, 0x1b6b95ac6ad89c6L, 0x0c0f9b66db0892fL, + 0x006e373a6ab9f1dL, 0x1ebab6d1eb0a170L, 0x04b88c54467fd53L }, + { 0x19c59a2cdecb5d8L, 0x1e40dd49d34335fL, 0x160411dd3efe020L, + 0x154040e16849c1bL, 0x0fbfb781e779a3cL, 0x1950e24e9a97dd8L, + 0x19406a2c36080fbL, 0x1e570b0c6f62967L, 0x15ba70a498a882fL, + 0x13980419d8377d2L, 0x100bd040bfb8aa8L, 0x05331404474b485L, + 0x0685c3fc72e4e76L, 0x1f297573edd15d1L, 0x03d17d9553f9d8fL, + 0x070f8616a80b44eL, 0x082d56a177aa573L, 0x00be03bc6a5b8fdL }, + { 0x06dff1d2735e37bL, 0x0272b32b762b907L, 0x12767aeea5e3262L, + 0x117413e78945eb5L, 0x15b0437740fa451L, 0x1d1765461fd0bbfL, + 0x0f50286877b3659L, 0x094ed1794e00a51L, 0x1f224952b18691cL, + 0x1709622f436afeaL, 0x16455cde1669a85L, 0x061341ff9c1cf41L, + 0x1ba96cc9a3723f4L, 0x0d691d1c2d46dbcL, 0x0fd7611b744ab80L, + 0x1dacd3ffd8743c5L, 0x0c6d6ce84e1a452L, 0x0090ceae42b8ff2L }, + { 0x1eaa67f262969ebL, 0x159ce9781f3b9a1L, 0x19455eec2424e8eL, + 0x1b1a2a04e9cc24fL, 0x0580bdbd0f82b0eL, 0x1a1f35ffffe56c7L, + 0x04759474f41d6a5L, 0x11029097b631758L, 0x095cd9990eb24c3L, + 0x0b530e83fd633e3L, 0x03dd8a8139ae1c8L, 0x1ac3974af990861L, + 0x0dd234a07a2865dL, 0x1d03c9fc9e14b58L, 0x18a7b39dbe4a0e4L, + 0x0de84e16afc3e17L, 0x0301314a82f7e62L, 0x01646bd596b2bf9L }, + { 0x1cf58920825e4d6L, 0x0f552b77c1da233L, 0x17604c4042377d4L, + 0x0b1ba12c7ec7cccL, 0x1df6436a229f89fL, 0x0f5dd3c6258a6ecL, + 0x1ce06676b91a751L, 0x1d6231556eeb49bL, 0x1da8978bd29e37fL, + 0x0e76ad556516bf7L, 0x03417719f5aa29aL, 0x1e1aeff09468d93L, + 0x0eed8cd59a7474bL, 0x08e9cc7dea21459L, 0x0882c46c3f47357L, + 0x09888b2c027b729L, 0x15896eb705a1b40L, 0x0114ce93ba584ecL }, + { 0x19cd58dc64397e6L, 0x0c78f5fb6e98f2dL, 0x0384fa7c76cab06L, + 0x0f1f9b8d18b0cdbL, 0x053c01fd405ae28L, 0x0edafb52594066fL, + 0x1e2837258fcb504L, 0x117dabaa3137d89L, 0x0336fd13d916ee9L, + 0x092d8d98216fa47L, 0x158a46b3801d39aL, 0x16904a62fd2a19eL, + 0x0b821c446be8d38L, 0x185b2c9a63d68e9L, 0x1283541c71104d7L, + 0x0d84d2e36e6dea5L, 0x18eaf9ffa5727b4L, 0x010d633bc8c9b30L }, + { 0x1420e3f2d7fbcd2L, 0x11239cbdefe0c55L, 0x0fe137d752d049cL, + 0x0c700f6fa692406L, 0x133c36256fcd423L, 0x19140a6fe0cd84dL, + 0x066e04f5bcdd683L, 0x138e12f14b206f8L, 0x14f3989970ff27bL, + 0x0070d22b0ad21c4L, 0x0d25a8f980bdd3fL, 0x086364c39439ff4L, + 0x1bee0164cdc3f1cL, 0x13fbdf4fb09108eL, 0x10b86ecc118fb93L, + 0x074ac02befcf125L, 0x1d8663d88d62448L, 0x0074760f387316cL }, + { 0x08ccc298a0878ddL, 0x00baeb320038d54L, 0x0082945cd85e66bL, + 0x1dbab1462b20689L, 0x08d221a1316d023L, 0x0e2471983c2dea4L, + 0x09dc6dd2cf79e56L, 0x0a685dc070498cfL, 0x159ef6cdde0b914L, + 0x01857144d91bf48L, 0x11e93125760c95eL, 0x02fda0ee6ccdc30L, + 0x06a294a32567b12L, 0x0326c1932c0c964L, 0x0c4f96ddaa83d5aL, + 0x0e7fbc5457a25e9L, 0x035d850c1c01b6bL, 0x0329d3cafae881bL }, + { 0x1e2898550dcb199L, 0x1c72f3fd015b067L, 0x1f0f25d80f42cd6L, + 0x1a4fe2636b794faL, 0x02b12d52b0e5288L, 0x1b92e39d53826f7L, + 0x0c44f881ac76076L, 0x0c6162507358ba3L, 0x014f970cbdb45d7L, + 0x0cbfc9f59092f47L, 0x15ce73b9f6a89b2L, 0x1a7e3fde41d37aeL, + 0x147c6a42b146ecbL, 0x13fd87e8fcca508L, 0x103692f4a27ad3cL, + 0x0f2ec2230da6334L, 0x15e083f65a5fb9dL, 0x0186fe23dea2233L }, + { 0x0fc5ae29eaadfe8L, 0x13f2a5a6a74095eL, 0x0b7e2d4cd584940L, + 0x08ad4d4429560e0L, 0x1059068ea2b9c20L, 0x018887d8d1efbd1L, + 0x038728d452c8662L, 0x1096f7c466d896fL, 0x017073ce63e2f69L, + 0x1708a5316efbd63L, 0x064afc1f5f0f221L, 0x1c17d635c5124ecL, + 0x15251849395da69L, 0x003d1d504c1d78bL, 0x03f88626b14a935L, + 0x04a022a6b8fb55cL, 0x0cfe16fe872397fL, 0x02b952c8faa6109L }, + { 0x166841909a5553aL, 0x0a18c193b99de24L, 0x12c8fbbf5a40fc1L, + 0x17e4424da9f39d6L, 0x0fed9578bd3cbf9L, 0x01836c36cb38e01L, + 0x13f96ee965f3b28L, 0x0ed6e0bdac27aceL, 0x1f1d3622b67f33fL, + 0x0de79e308e5c618L, 0x119f7394f46aa45L, 0x1253f2115687470L, + 0x1d8d15767a902feL, 0x0857e83db71f24cL, 0x02c643a050b6d72L, + 0x1349c2418df78d9L, 0x03c80c865532491L, 0x032e165f0ec6416L }, + { 0x04cda20a660bb63L, 0x01d8543743122b4L, 0x13d9ae83bb5c9f7L, + 0x0acf3ba2b0ec8e5L, 0x08452d4479c162eL, 0x1fabcf5b44213b8L, + 0x05dc20a6f1acd04L, 0x10725d42bd92a02L, 0x15e34e300477381L, + 0x01e51a4b9f0e978L, 0x13c7708a6f4f7a3L, 0x1e3729defda74b8L, + 0x0ddfae7a1a783efL, 0x0d04cc29236db9cL, 0x173d2ad0d4f5cb8L, + 0x111724a675ab141L, 0x166d80550160e78L, 0x0418a206a9dd3bfL }, + { 0x03e2e32f611b2daL, 0x13714e87d23567aL, 0x0fa2082cf035741L, + 0x0c3a7c89e1d12feL, 0x1fd27a66c45c28eL, 0x0f428bc94ebfb36L, + 0x1e375cd6e182840L, 0x035d47f9d307bc0L, 0x1c9977db5638ce1L, + 0x0441c17a429b59dL, 0x11e8f1932b7f181L, 0x1eff0428f6e2fc1L, + 0x0c1b411e3e3cd17L, 0x0c2fda36f4ab31eL, 0x1c467295ce6b23eL, + 0x0502a70a7339b79L, 0x1664a985a70e15aL, 0x028261d4536afa2L }, + { 0x0b55283b8fa53c7L, 0x07f9c284a3a7180L, 0x10710df3897e617L, + 0x01cb4253da469a4L, 0x0abcc6742983243L, 0x140f70b569c4ab5L, + 0x09c0a8b700075fbL, 0x17698478d6cce16L, 0x0b35e567ea6e8a3L, + 0x03859e7534b39f5L, 0x1ea70f9b8a3ab2fL, 0x09bcaa6f6fb50b4L, + 0x056de937dc2ae68L, 0x1c2182112f6561fL, 0x1f71482fcba9b27L, + 0x0d5ba7195efa0efL, 0x1d2c27af0b169f5L, 0x024b7234ce38e90L }, + { 0x014fc829fa93467L, 0x1bb420759530a5dL, 0x1ebd20cf826f0b8L, + 0x046d0d7b98cb379L, 0x01f3216abc85975L, 0x0040dc205fe8404L, + 0x1e4ef118ef6985fL, 0x18b7a03f50d7608L, 0x05a21ece62cd640L, + 0x1dfb52a1101eae2L, 0x103b7254459ede5L, 0x195eecb744d19d6L, + 0x09aeab51f9d67aaL, 0x186b431d45d06cfL, 0x1c1a54b052c857aL, + 0x0896a6a99b9b7cbL, 0x1e84f2b5ccfcb37L, 0x0099c48b98981bfL }, + { 0x068064045003cd1L, 0x00bde2257156377L, 0x067f7a394c53f6bL, + 0x138f9d52b8979a8L, 0x18f37e0181e34ebL, 0x04c8645dabbb169L, + 0x129efb3133ec098L, 0x1de178927f2a146L, 0x068074172543304L, + 0x1607e5935e45515L, 0x0a6d18ed17fa96bL, 0x0a5cabf7b7593cfL, + 0x060485dff44bb29L, 0x06f523cb2878605L, 0x178e8080b144135L, + 0x1e68ba59df412d2L, 0x1bd4c8102b46da1L, 0x021175ab9f9c19fL }, + { 0x0592eb6a6ad3f47L, 0x10fb6cb8a5d0756L, 0x04641ca05166c21L, + 0x04c9d4b006af83dL, 0x14b12723cf7c94eL, 0x1db9b53929bb562L, + 0x0f373ca9ae9076bL, 0x15b913d12419740L, 0x0f2e20cb45b0fd3L, + 0x1752d2a6b302cffL, 0x0fea2e2277e2f09L, 0x0fc2cd47e57fdccL, + 0x1c747312e140f1cL, 0x193cccff84ff5e4L, 0x1f4ac15f466e709L, + 0x05b8d53f776996fL, 0x182cfba27d7a0daL, 0x01b42a0e7961292L }, + { 0x10d3c9e22799d37L, 0x1bef2d67d199d28L, 0x063c203de56c6d9L, + 0x155f91bf849cd5cL, 0x0e842dc269b53c2L, 0x033ff43cbaa0db0L, + 0x161df569bcabeb0L, 0x1e5a04114077a0fL, 0x034b473f0654be2L, + 0x13e08157a8af11fL, 0x16fe74ab06bd239L, 0x14836d427a01601L, + 0x0a97e94c11e264fL, 0x0352c37a0b34bc3L, 0x1e49fa427633cb6L, + 0x14acc0e77f0d38fL, 0x134b89778802241L, 0x02cd2dfac911309L }, + { 0x1d1c91e81347191L, 0x00d5e75cb4cb974L, 0x1d9ea751a9fc61bL, + 0x19b54fa72e0f110L, 0x191b9aa0da93cfcL, 0x0e9e36045f74f8eL, + 0x00402099ff5e3e3L, 0x1f7f270c1a12845L, 0x06a6a71aadadb47L, + 0x055035bd30ab7c5L, 0x0c1780e6122f267L, 0x046e5555226b543L, + 0x19b13f3bd136ddcL, 0x05662fa6bbf3f03L, 0x133f4da342d72f9L, + 0x1c1f009b48bf130L, 0x19cf14ef618d3d3L, 0x0233ab260a1f5bcL }, + { 0x1725904b6fff5d7L, 0x199d7c96e23a946L, 0x15d5b482e2a80dfL, + 0x028775d873212baL, 0x08a2b9b032235fcL, 0x09ae30d17f5a57bL, + 0x1d21987140c6253L, 0x1e759256d45d50eL, 0x08eb48b15011bc6L, + 0x147f09463cf6e59L, 0x06f032974a801a8L, 0x0e645e2b70a13eeL, + 0x0c7a036218f3167L, 0x07c0f04f7f46b94L, 0x1f143641a3ce72dL, + 0x03c062ee7e02cf6L, 0x0d50d0f7adbed6aL, 0x04506f70b2774c2L }, + { 0x04991bf47366e6fL, 0x026cff4361802a8L, 0x1d46903338dae02L, + 0x0c7e32c3c429898L, 0x00445e43bbb46aaL, 0x0f10afab53c2fcaL, + 0x002376e346d5f24L, 0x118d51c8a7d8fddL, 0x1c0367ef8bbaa1eL, + 0x086c8f8f1f0c084L, 0x13f439f8828b0ccL, 0x1908aa9984eff2fL, + 0x1d7b628403f1e80L, 0x1ff050be744dde0L, 0x1c001cddde2a598L, + 0x17da53d3b633f83L, 0x0232ce7fe7db6f6L, 0x03d825ae9774be7L }, + { 0x1546bc782c5faf8L, 0x1a62f475c084badL, 0x01879de1478069cL, + 0x07d2adaa3e7aacdL, 0x03c3c37c833a101L, 0x00a476639a8b98eL, + 0x1bd0581dce3ef83L, 0x0ae5d8de177c377L, 0x00aa2ac6ecfa518L, + 0x194816bb371d6f8L, 0x154227188b5b8c1L, 0x16474dbb005f9a9L, + 0x15338863723ae21L, 0x146c0c1172a32d2L, 0x01a5deb61446682L, + 0x04e589e29a0646fL, 0x11c515b081c9c7bL, 0x00e354ad264cdf1L }, + { 0x0b14ad5c2821363L, 0x00c11a68bef0e53L, 0x0b1332b7a1220a7L, + 0x1304913c4f5debaL, 0x1081d927f412ab3L, 0x05d68fc964e04c7L, + 0x07ec5be1ef7d1d7L, 0x0ede955b570343bL, 0x0475a7923b75f3bL, + 0x0ee856b6dddd47fL, 0x1d85912dc2ad166L, 0x1102697b35e306dL, + 0x0eba9abda32a464L, 0x132b12fdae48913L, 0x06392f933b21c27L, + 0x10f39a967233c10L, 0x0c9a5c09c8414f6L, 0x039384501185432L }, + { 0x133c0b1f34a466cL, 0x1704e3fcea2dd27L, 0x1fb838a1e17286eL, + 0x0d21101103ae1e1L, 0x1b043da3824c714L, 0x037a197120b6155L, + 0x0f871ccf69c4f3bL, 0x0ca56b20c9392f2L, 0x0db62d5b0b35c93L, + 0x0af5b711f2e0d95L, 0x02d73aec5ad454dL, 0x10d3ee12d2399fdL, + 0x1b61a85bd59e081L, 0x1d7081fbe432fcfL, 0x119fa77c5a74f33L, + 0x0a2272a4b88e6e6L, 0x1217db55c0b4369L, 0x03a48e3a639932eL }, + { 0x12ed5bf80d2b94dL, 0x16319dd25930598L, 0x1633588866846e2L, + 0x175d70591d590d8L, 0x19ef9ced317ccf6L, 0x15e6ad16fd94f72L, + 0x0c8076a9f626390L, 0x1b927c52b90b2e9L, 0x069e75784d9fc5aL, + 0x162384f809551ddL, 0x0a7cdf2174f2e75L, 0x1c4ba7ba957a3fbL, + 0x010b3ba22ee5487L, 0x03746e5d807ea58L, 0x19a19932d64524fL, + 0x0d6ed6e653f5779L, 0x0416829d1c26890L, 0x045e7e9f2ba0bb4L }, + { 0x0882734d3c8c314L, 0x0597888c3841983L, 0x1f0f01a2e85a57cL, + 0x10ef248f0f726feL, 0x1f9922275365e0dL, 0x0ffea78aa93f2f0L, + 0x18e24281a59209fL, 0x15bab167be45eb0L, 0x183446b896af20eL, + 0x0ebcb85a83a312bL, 0x034819008a9a442L, 0x115ece3d86f3b3dL, + 0x09057fe91ed1e5fL, 0x0944820c37aa128L, 0x0e4cab7c5376a05L, + 0x126f17af0021c3bL, 0x1493e18d1e4905aL, 0x029e56e7bde9bd5L }, + { 0x1b5edf75e53d0ffL, 0x1303644455fb38dL, 0x03e04881b457621L, + 0x0bc456d466c9236L, 0x1173b317b301834L, 0x04f2cad5d33ca5dL, + 0x093463079619df7L, 0x0a69c20c904472cL, 0x061752e59da55ddL, + 0x0c5a755cf2143ceL, 0x19e12d247cafb40L, 0x13a43cf2853d95eL, + 0x0510f262243dcdbL, 0x1328762e1b4a0a4L, 0x06a5d8041bc642aL, + 0x0208cea854b5d6dL, 0x0b169bd75e9c32dL, 0x048424cb25fc631L }, + { 0x1390cf65a93c661L, 0x031324edaf82b58L, 0x0a7694685e20612L, + 0x1ecee5bd3525527L, 0x1c71487c1b0cbb8L, 0x11211f3733ff5ebL, + 0x10be3e6d0e0b539L, 0x1e52dfb4a1d76b4L, 0x0c921b3376089a4L, + 0x0e996bdc3af628bL, 0x1b4b2b1040492d2L, 0x04138843f6f57b0L, + 0x0bf6b7de33f6862L, 0x149e49341f0ca4dL, 0x171330337b863c3L, + 0x01a45a9db7abc11L, 0x1e8c2b75be47358L, 0x01ebfb7fd23466bL }, + { 0x07b290cdffbd5d1L, 0x0ced34b819c6ff5L, 0x0c2243fbb72675dL, + 0x0a85b9cd1cacd01L, 0x12ae4d82bc690afL, 0x0cadb0428cef95dL, + 0x087d1584919fdfcL, 0x066cb346859b078L, 0x055771bf5556516L, + 0x1e3449aaa45d2b1L, 0x06480e524bc8e97L, 0x11c73938c02f6a8L, + 0x14511e601956752L, 0x0e8b52aa9f83276L, 0x152afb8c0fe7ae4L, + 0x09cf87c3189fa44L, 0x0e640994d6ffd43L, 0x047d8969fb6ef3aL }, + { 0x06381a2293cb7a4L, 0x104f85c3dbf26b6L, 0x008c1e2b0fbd14fL, + 0x00af195d229e425L, 0x116ba4dde89ffadL, 0x1ac0502515b4b53L, + 0x04c1c51a06853dbL, 0x11226b1f2f6985eL, 0x1878969962932fbL, + 0x0eec28513452d7bL, 0x1c7db7f88e7e0caL, 0x1a5c9e8e933b5eeL, + 0x17867ca0e95f20fL, 0x1bacc0f64db21f3L, 0x0ac725f9e163b34L, + 0x068a77d28d4b233L, 0x1b14f9303a206ffL, 0x01fe63398bae91bL }, + { 0x09debd5df21f920L, 0x1870fe0a00dc828L, 0x0ff656992abfebdL, + 0x0a586f424448539L, 0x1deb926bf212085L, 0x19f8ee0ea649fa3L, + 0x0f1184bcf93027eL, 0x1a4ac10b4b2b6a3L, 0x02a2f5d62f10fdbL, + 0x06eb167ef8659e1L, 0x10928dac3c952d8L, 0x00baac8c256e2a8L, + 0x0fa1f5249cc3a5aL, 0x1f3150c45f5f186L, 0x10a64e493b1a40dL, + 0x10d0aebe1f7595eL, 0x034d41345dcb3faL, 0x03228a37ee38a8eL }, + { 0x0ec633aba1924f9L, 0x1789b00319370f6L, 0x1eb1f943f05eee9L, + 0x13de7b1c00406eaL, 0x11dc5a74ca53191L, 0x0a095c4aa2d3552L, + 0x14001b887563f4cL, 0x1860378600af763L, 0x0f1789c696ed1a9L, + 0x17969afcc2c7d24L, 0x1426e6065efa15eL, 0x0eaa53544cba869L, + 0x07c058fa801dc07L, 0x0a5d0a6765681dfL, 0x01429d24b5c2a7dL, + 0x0bbb4db8f0a0ad8L, 0x12e2a7ca4a94d00L, 0x022469eb955fdcfL }, + { 0x056f14529b33989L, 0x1a8de54d740ad6eL, 0x184d2c1d10521a0L, + 0x1479b3e67767e8aL, 0x1ff6e4a3955ce42L, 0x07554889d6f2762L, + 0x1bf7f4eab1c5694L, 0x01418c3d932accdL, 0x1108a28b8f6a447L, + 0x0177ac272a42264L, 0x16c58b438bccdd0L, 0x063f68def979704L, + 0x0c96f2fd893dcd1L, 0x12c9463c1040bc7L, 0x18f11653631759cL, + 0x0613e50b467bf32L, 0x1a572497175d92aL, 0x03b440a3ce5b80cL }, + { 0x043a11491767eedL, 0x0dcd6c95fb2edddL, 0x13800e978869784L, + 0x025466a82bd1445L, 0x0a9ead626360442L, 0x195772e162b1da2L, + 0x1875d2f01899282L, 0x0baeb71aaeb17e5L, 0x11cff0ee7d08a26L, + 0x1c8a70ed85b8953L, 0x0497412c61a4b45L, 0x1e98ad99d02b86bL, + 0x1c9fff0e3ade253L, 0x0ed5f68cd23c920L, 0x1eb941942e741bbL, + 0x1c300ce26a4c0b3L, 0x026f37600fb532cL, 0x03387580e2f2d43L }, + { 0x173c0af73cdbb43L, 0x07662bf9218d6efL, 0x1504a868e1173c2L, + 0x052449bbe322f00L, 0x1eac7eff69a104fL, 0x16899121a979c6dL, + 0x0d1dbf0eced39f0L, 0x1e14d3d28616bc9L, 0x07d932340975a46L, + 0x049c4cf2eb27767L, 0x0849436c8d17a60L, 0x1264fe96f2d6f70L, + 0x154bb90b1f23552L, 0x08897beb1774e60L, 0x0eab8c87ea723d6L, + 0x02cd45a1e5f3039L, 0x127b77f03660075L, 0x028242973b1aeffL }, + { 0x10f3ce5a2f392faL, 0x003b57636483c17L, 0x1a4a12eaabd8c9bL, + 0x0797d1d3275a03bL, 0x0d950908b01b16dL, 0x09d79c38982e121L, + 0x0a68319bf585ce1L, 0x04eee6a281da788L, 0x18a31b12a1fabf0L, + 0x029800102c598bbL, 0x1f67f2a71f7ae68L, 0x0d37d0ccfa6157fL, + 0x08e9a9e13fd05efL, 0x1c8f574e179d398L, 0x0339b10fd326866L, + 0x1f160a1a19dcec3L, 0x0c4fb24dc405240L, 0x04c97f0a8fbf486L }, + { 0x054db3138f197aaL, 0x16b4ec3c397cc22L, 0x1ec113c2a0a2937L, + 0x1d463c918d2f684L, 0x1d98efec9821e1aL, 0x0659d771c6584feL, + 0x155cc82e13ea120L, 0x0d774b769508e8eL, 0x0a9be080acd50e9L, + 0x0228f4e77881aa8L, 0x1b9d7f1104c9731L, 0x1d30714bc67ac4dL, + 0x19a2b0abd26eea5L, 0x0db04154b990df5L, 0x0af30ab2a4b9212L, + 0x173f63b902d1532L, 0x1e0134ecf4b9c8eL, 0x02d345fd4262db8L }, + { 0x0ff3b45ff0a2bfbL, 0x0fffcaa817c585aL, 0x02156c70309b441L, + 0x161a773a0829bcbL, 0x026d3917ed16865L, 0x0d9e0717ad12298L, + 0x03cb9a88bd24fd3L, 0x0c290e2a915c483L, 0x06ab363a8509befL, + 0x0e50f1d5c65ddf6L, 0x03726100468e5a4L, 0x1c141ab94aeee3cL, + 0x0581897bc1ff982L, 0x042d6af3f5a0582L, 0x0cdedf12f092918L, + 0x0c51fa2b91f414cL, 0x03956ce6ef7bef1L, 0x03c567efccfaf7aL }, + { 0x1bf7f15f8520189L, 0x1015063bfb0e222L, 0x1ae77e88b86e550L, + 0x0e3e94690e73db8L, 0x0814cc52d2d6026L, 0x14f891e6c99c94aL, + 0x0dbdf79da849017L, 0x1c1c460dd415c6dL, 0x053815218b83a58L, + 0x0315dbb5020918dL, 0x0894f2fcc6f9c66L, 0x06646fbd0c3fd1bL, + 0x1690ae48902dfc5L, 0x05d53769792e49fL, 0x02d28a59af2e3c2L, + 0x19292de215c1f21L, 0x1668cb4b48cb061L, 0x0056c96b9e83ad1L }, + { 0x1b95fedc2ca548aL, 0x063104066c4d5dfL, 0x152cd19b0a011deL, + 0x07a97d12057d322L, 0x13e681edea3be09L, 0x1a00b0c23dbcca8L, + 0x1ffa3c8aa3d2c0bL, 0x1ec7de5969a95d6L, 0x19adc5151b3aed5L, + 0x00e67e8cc6188b1L, 0x0b05ee8f5f623fbL, 0x09a68c84212fb85L, + 0x1794b90bcf08fa6L, 0x05a854f5af5fc05L, 0x06a99ac6de2d2e8L, + 0x079da349fd2684fL, 0x1ae8ef4dcaf075bL, 0x04addec50385374L }, + { 0x1f92495e614bbd0L, 0x1d443dc11f1b1acL, 0x07b3f06f5a9dd59L, + 0x0f1d06b885c48f9L, 0x0ade066a2bfaaf4L, 0x0b699b18a77a705L, + 0x18e241caea98d70L, 0x01ff48538e3c5e1L, 0x0cac1e5d0bd07d9L, + 0x0ff9af528a7ae02L, 0x014ff301553b05aL, 0x0d6e546b28ff126L, + 0x002aebe487ab1d8L, 0x0fdce790f14fd83L, 0x037f3d6828435b7L, + 0x0f4555a28e0b3e4L, 0x119480dc66fb886L, 0x01bad4427e092d4L }, + { 0x18cbe2e1217f7eaL, 0x10f1543ae36d58bL, 0x1b006f6c6950685L, + 0x01c9fae795eee0fL, 0x113a0d86678864aL, 0x0983345d75e3326L, + 0x1654100c97e6723L, 0x0cf727db3925e38L, 0x1fdf36763541e06L, + 0x0cbfdd85c8d33b1L, 0x09a7a981e72683fL, 0x19003d55188e4d5L, + 0x01afa63c55c7303L, 0x07e8956def63ae4L, 0x1a20e2807373789L, + 0x0a6f33fc1bb4e32L, 0x0ec66bb093b3841L, 0x01346c0c58465c2L }, + { 0x1dae35841580555L, 0x19733a39e881db9L, 0x004efb3306ad3f0L, + 0x05649dd3bc48182L, 0x1fa8e066da4099fL, 0x1c6bf71bd865adcL, + 0x00502d6b8139190L, 0x0f0fefa62c856e4L, 0x186ef4edb339e4aL, + 0x0f3bf769d3ec1baL, 0x1eb4def5c1f0ba9L, 0x06741f2f2313107L, + 0x0a2e7a208e816b6L, 0x021aa8b57126014L, 0x17cafd445c7f8f1L, + 0x074ac7d7276669eL, 0x04b8419ed4b01b5L, 0x0458139ae02b652L }, + { 0x09bb464e1019195L, 0x0601379fe1460dcL, 0x19b8aff0ec84779L, + 0x15237bf25f58241L, 0x0d995bc9ec71bc5L, 0x048fff242ebd5a0L, + 0x189965f19da3b99L, 0x185b2aa5a335f79L, 0x1bae6c7fe8e1b76L, + 0x13ec140ebf1d68dL, 0x126be57a625cd05L, 0x0499141903047c2L, + 0x1bc3006c0dd1f00L, 0x0c3b9ea67ab8ffeL, 0x0d50362ccbb3df9L, + 0x0a084b0454f05faL, 0x1fe5ab45c3f0436L, 0x020071d5025a6c2L }, + { 0x13216495e46e4a2L, 0x176b21209b03a23L, 0x0ec7183b1df4de8L, + 0x07cbc1585ccb244L, 0x05107ab75e13aacL, 0x0129eded0be20deL, + 0x08a5996c8bb25cfL, 0x137fe70cf714a02L, 0x1fed660d50621a9L, + 0x1e14283644fe1faL, 0x0d42e7c591469e8L, 0x0064cf96b0de7daL, + 0x19967185b127c3eL, 0x0509804de403e3bL, 0x0bc7d3427055f51L, + 0x143306c5eec8f5bL, 0x0394a42b9acf3a6L, 0x0098e1ed146d370L }, + { 0x0785ff1a7da83baL, 0x0da12e827a21b25L, 0x06f7b00fe04bd05L, + 0x1501ebe944f8113L, 0x1da251b9c58d411L, 0x1d97991e996b087L, + 0x020f266ed141334L, 0x1fa33188897e984L, 0x060c261af730e83L, + 0x106526fe5816dc8L, 0x1e0e2e77c79f201L, 0x1f2f898d21921feL, + 0x175d75f1546b79cL, 0x0e58747f898a8a6L, 0x105d8569f01d3c4L, + 0x01fe17241558365L, 0x0e9de8098ad44aaL, 0x038e8d2351a2a2eL }, + { 0x0178f76fa1b382eL, 0x07661bb96ed06bbL, 0x0cab175344c2836L, + 0x091ae4c45954b55L, 0x0a3bed0627d38baL, 0x1e7667e2a086db6L, + 0x18f5fd8de9621e4L, 0x0823ecbb5fadccbL, 0x1c3b44a8560a456L, + 0x1a3d9d427bc2a05L, 0x1f6b75793583d83L, 0x12182fa76dab049L, + 0x1f325fc13ad8ccfL, 0x1b247d5c804755eL, 0x114b52cfa435c58L, + 0x0159672c9fe7449L, 0x121b95cc416533dL, 0x0366934cf88b3faL }, + { 0x18c0b3b12f4f3acL, 0x0e7f14ce8defd96L, 0x13e0c3cdcc9ac0fL, + 0x06f8b51904a8006L, 0x0d8f144222dd689L, 0x0ba17975b849e86L, + 0x16b76249e569d61L, 0x0bdc2be505810f5L, 0x07bbdc74916ab7bL, + 0x187f205d2c565daL, 0x105faf8aeb0e6f4L, 0x134d8c3409781bcL, + 0x0df27355694b4b1L, 0x18558cb7c99c61aL, 0x0232597a3c0dd08L, + 0x1704df45df970d9L, 0x1c219eee274c7eeL, 0x0193e031fed1a2eL }, + { 0x1399eff5b47cd53L, 0x0c34e8ca1d77f55L, 0x11ec500aa19aefaL, + 0x156384b42dcc9d9L, 0x022de271c3e7c2aL, 0x16b52fe210b5bc8L, + 0x0ccdb9637f320d9L, 0x0f9a2b2a13db502L, 0x0370400f2130bfbL, + 0x1f2702cc9da43c0L, 0x0e87f8e7cf34886L, 0x0565dd969f0e0c4L, + 0x166c27b83b72aa2L, 0x0d2fd2df8d7a624L, 0x0c06bc9e90aa52fL, + 0x0225935f7504491L, 0x056eb6b9d2a3670L, 0x001078ce8e06fb4L }, + { 0x1051a86a4dbba20L, 0x075e36d8ef2e29bL, 0x086799496102d86L, + 0x1ba579989b34f01L, 0x10285a249440302L, 0x04313474ff811e8L, + 0x0451cee4dfb8ce9L, 0x19fc6fdc5e499acL, 0x079fbbfd3a3d057L, + 0x1dd0b69e66ef7e7L, 0x0163b16c8c5c9d7L, 0x1d7ce41875b722cL, + 0x068b4f6bba47699L, 0x18c503b81313a1cL, 0x128458152c024abL, + 0x11ec133a121d759L, 0x144f757e1ff0c88L, 0x03cf39390580282L }, + { 0x12acf252820a239L, 0x1cba75573598831L, 0x1ae92302877ec68L, + 0x12b47dcf55ac3faL, 0x1980446dd2453c3L, 0x0b33b7aa422ad05L, + 0x1d6867ca765ef78L, 0x10be4a59418f126L, 0x1e961af3e7743a9L, + 0x063ce2b3366dec6L, 0x0e153b2f14e3e5cL, 0x0e75424d0a38294L, + 0x052a9f558c58daaL, 0x1de8af02f4daddaL, 0x0864e74debdfe0fL, + 0x140ad4890f24e71L, 0x06de428b2b59511L, 0x0000e9e71b80ac2L }, + { 0x0be36b9e145b1d7L, 0x1c9c5004e2b326bL, 0x19f79f03db6fcf8L, + 0x0d8687ea725cac5L, 0x190897b1951044eL, 0x17bcbe52d5b15c6L, + 0x0a392c687dc2d44L, 0x0bb239baea8ea1eL, 0x1b4c80e2fffb816L, + 0x0f69ce3aca68159L, 0x0a92755a0cfb719L, 0x0979e6d27431982L, + 0x0afcd2c404e7369L, 0x08ea00ca1a6609aL, 0x16179181c6f57f0L, + 0x0f4080aeb208ff8L, 0x084b3280360790bL, 0x025dc637e2057e3L }, + { 0x120e2ddfd0f8796L, 0x05206d899e4ef18L, 0x1b02a4da71b9a5aL, + 0x0cc00e4e77fd46cL, 0x0cb8143937e5b6dL, 0x15e0029cf276784L, + 0x0d4f121ffa7367fL, 0x1d7d715e8880333L, 0x02f124e3b293519L, + 0x10610c564164e0bL, 0x075bc9c27716421L, 0x0a8a6daa0a5359aL, + 0x1959120bfc5696dL, 0x087fd348601faefL, 0x10ca09e668fa234L, + 0x0bb13a9f39f4ad8L, 0x0782e8fea9e9a13L, 0x01b4cd440db53bfL }, + { 0x1ca33721eb1c64dL, 0x19d16f8e940aa2dL, 0x06cd94dc41bfa73L, + 0x029ef97e9b6fc5dL, 0x0058b37f06c1715L, 0x1a74e2e5ef20b71L, + 0x0e9d60b14e9fa20L, 0x00529b7bfc5d358L, 0x1795ec6cbc5e67cL, + 0x011e12f8a135406L, 0x134835aa353e7e3L, 0x14a9a76f846bdc5L, + 0x003d7a4d52838daL, 0x1c0e5a39dcf0476L, 0x10c72ab2a51d7a5L, + 0x0a30ee4e3e73cbdL, 0x18b1df08e9f8253L, 0x0279d258190457fL }, + { 0x17b81071ed095f8L, 0x1bfd36d1136a707L, 0x014abecdb4748f8L, + 0x1c0fb1c623161f3L, 0x03e0f16eb114634L, 0x0f761bdcb1a54bfL, + 0x087049152ee7108L, 0x0f969d9abb7ae56L, 0x0f96038686df20dL, + 0x1a9acfeefc37051L, 0x1553e96b1222aa7L, 0x0957a2093be9887L, + 0x1eb020607a56d71L, 0x1d01192f098a959L, 0x0ba136d26f87061L, + 0x0f70089e49e94a5L, 0x1fd9e525c030b5aL, 0x036c3a2235368bcL }, + { 0x09d07aabe9a42f5L, 0x098b61bc0e66469L, 0x09b6771a7a847f5L, + 0x1f11fdd234e34ebL, 0x18d44f124e19e0dL, 0x174a724ce15a6e7L, + 0x1330817db7e48c6L, 0x1d64ff750ed9e51L, 0x06e1a0f01f57f7cL, + 0x01f8f9a79fe9dbaL, 0x17129d0b07484f8L, 0x04e0fbd70b0141dL, + 0x1faf0848bc5caacL, 0x03d63ace87aebc8L, 0x13f14c45fd452b4L, + 0x01e7b2b472e6920L, 0x00995a4aca97bb7L, 0x01e79c264ffce2bL }, + { 0x00506bace1fc9e3L, 0x10ba133b581ccb8L, 0x0e379cafdecd25cL, + 0x10f36413ee56943L, 0x0e26a8e1ca8602aL, 0x1279cd482c05c86L, + 0x18b847bcce6dff8L, 0x1e96d8bb322c526L, 0x151174e1a577b24L, + 0x1c07e5a82f228f4L, 0x05ebec520c86f7cL, 0x0d76e8fcba55e9bL, + 0x05be99a60809980L, 0x0a2af41042a92ebL, 0x15829949920a367L, + 0x00ee11918a80bb0L, 0x1263c67e73c7103L, 0x0159244287739efL }, + { 0x173cde68541159fL, 0x1260c27da085910L, 0x18647cb2871de08L, + 0x0d51647c800f450L, 0x06b2344a52c207dL, 0x1694a2838d01085L, + 0x131b36c3961f2d7L, 0x172d8ad71df021fL, 0x11248c58f62d843L, + 0x1c81b1eba6334baL, 0x03dfcb99b19bd92L, 0x0883824d797cc69L, + 0x0373ce49e8b2f9dL, 0x140d86f85603f95L, 0x118874549219d63L, + 0x0943942116a9a3aL, 0x01517261ece7441L, 0x049c59de6351d61L }, + { 0x1e4a16be4ded340L, 0x0fd954074401b54L, 0x181b735ceb2e399L, + 0x09554caf532e112L, 0x09101b061c3a043L, 0x05db2679827e2c2L, + 0x0b7d7983ed86b68L, 0x0bf031855d9eaa8L, 0x17402057656f76dL, + 0x0b35bc849299ecbL, 0x195795d35bad7edL, 0x036b4ab6896f5c8L, + 0x1b93747ea560f7aL, 0x196d672b3cb80bcL, 0x1a0f01a2b9f83a3L, + 0x0e683308e8c0f09L, 0x16b24e8c9ed1530L, 0x0367fac52ecf44eL }, + { 0x08c01b003e51f68L, 0x0f9128e97f3eb28L, 0x142c26f62017874L, + 0x1407c82b6fef331L, 0x007d9798255e907L, 0x029c4b68a4233ebL, + 0x143d01570ec7a6dL, 0x1b86a002027013eL, 0x0fbbb2fa6d0233fL, + 0x1b405857f8c105cL, 0x101370e34c5f802L, 0x088999918fbf63aL, + 0x066ec13f84133d5L, 0x023717243fd423fL, 0x18eceb30cfe0f60L, + 0x0d5ee78c4ff8a90L, 0x1275f67f8aaeb93L, 0x02ff2564798dbc9L }, + { 0x01aa4bf8b6f401eL, 0x18951d6ae3f6a2cL, 0x1c99bec1ed28176L, + 0x09384579a8f6030L, 0x09371c95fdd11f0L, 0x123757aa2a53ea3L, + 0x05b4019b157ee66L, 0x0b830c6f8f8ffdfL, 0x0bafc1d346b83e9L, + 0x0e1c2c9805da16eL, 0x17b0acd39f9c495L, 0x1f6163099dd1bb1L, + 0x0249a2786469c9cL, 0x10087973c6e6062L, 0x1de9080a43657c8L, + 0x17b5b0dc4a992d2L, 0x14820931c89eb2aL, 0x0409bb8b2090e02L }, + { 0x066b25e9c5a8edfL, 0x1c461083c53d6b1L, 0x0df521dbbb7db84L, + 0x12c4e88c2ebe04eL, 0x1385382a242fa7fL, 0x1b8df79f167decdL, + 0x02a4aeb6b5ec40bL, 0x068ac5579f4cefaL, 0x0573ebd1751fdffL, + 0x1fb2c293e12863cL, 0x1c5bbb11f2a25b5L, 0x1360cec4593dc19L, + 0x02f8f2c0758ccd7L, 0x1300428a98fe2c4L, 0x1a316ea48cacdfaL, + 0x08dfc9af766c305L, 0x198bf24735cd2f1L, 0x03ce140774e696dL }, + { 0x1cc8203f2b48122L, 0x0248b582562475eL, 0x13727f12217aa30L, + 0x0f0582003959e0cL, 0x076de250ab83899L, 0x0d5c10399cf390bL, + 0x12cb85ea96baa38L, 0x06049a51940d782L, 0x0570c5bb7816b62L, + 0x02891ae67735b03L, 0x0fe27c60fab909bL, 0x078d38cc4e96365L, + 0x06b51e38bc3e3afL, 0x19f2071df058221L, 0x0f96f909b6f1639L, + 0x1e8107f3baaf16bL, 0x14f9fd9f79152c8L, 0x03ac039d254f1ffL }, + { 0x127b0578691ca22L, 0x15feb09d150db3eL, 0x0e16b1e5504fc81L, + 0x14eaa6cc0fd097aL, 0x08a0e24cc5d18a2L, 0x03a6de970b36f3eL, + 0x010e95b55d430f1L, 0x065bde8898226cdL, 0x114646e53cf4b84L, + 0x1e0681854fecbc1L, 0x132090a5fb880d2L, 0x017ffaf7cd8f7b4L, + 0x1608c7f3ff3d0b1L, 0x1a7ea6229690b23L, 0x1a784101b949666L, + 0x1a65bf7573f4293L, 0x0a89342a7fa8661L, 0x01f9f1a2c7d7b35L }, + { 0x1ec35af951597aaL, 0x1ea5624efb275a8L, 0x16726fd3bfd6d9dL, + 0x12a2b4526a04ed9L, 0x1d9bb9c3423eca4L, 0x10f84e4534b2a9fL, + 0x17e63e67ba77fb7L, 0x06571f452ac333cL, 0x1b763875835292cL, + 0x19a76ee7e20740dL, 0x157a7d9515f6561L, 0x047c618f1a57b05L, + 0x0cc1433d67c8ee3L, 0x1e418a5773bd972L, 0x038bd8d5b67e01cL, + 0x052bc883ddbc454L, 0x0ef1e9e17ed6c48L, 0x0320690621a614aL }, + { 0x09a0b8e3284d513L, 0x01aa2f98a829d27L, 0x101d16b354a81d3L, + 0x183bca1b6f66dceL, 0x0549fc46d80bdcfL, 0x1f83d446cea3ee1L, + 0x15308a6dbbc4cc0L, 0x0e69c8c3594da95L, 0x1ca8e351dfc9f1bL, + 0x1e204a6aba30732L, 0x00accc3ccb4d9e2L, 0x096c50ae85d16c6L, + 0x11876c29c369a07L, 0x0895e8bd6ff2958L, 0x06a98e7ce791826L, + 0x00b831dc81acc69L, 0x016b968902ac72eL, 0x007ce0e54606c94L }, + { 0x0bbaab367433df3L, 0x129a38ae9b1460fL, 0x03625fc31732daaL, + 0x16cbc811f227464L, 0x1537345172c918cL, 0x06e504a5b1c42a6L, + 0x04c99cc4e668c2dL, 0x1119e4ace601476L, 0x15ea60dfa6608b3L, + 0x056ba583d9486feL, 0x009e275da53e6d6L, 0x1b716cc61f63064L, + 0x10c65e3eaf48593L, 0x1f3931fc1eda3fbL, 0x19bfccd8e527244L, + 0x1048137359d8dcdL, 0x0c534bd9ba7098aL, 0x03f18e097a2e9b7L }, + { 0x0281d680dfd2dd7L, 0x165801255b0ec5fL, 0x017e510c7e5c7beL, + 0x152b39677973860L, 0x0ffbb406660c8dfL, 0x14d086feeafe186L, + 0x1f46de918c6f9e5L, 0x0ec66dc613dbc27L, 0x176b3bfadfc9470L, + 0x148c92eee639111L, 0x1c35cc55b13b87eL, 0x1c821c566e8ee83L, + 0x13efc4d93c4f64eL, 0x1e27dd97435f496L, 0x1f286ef14edf80fL, + 0x174c15832d9ea66L, 0x1574de41a307e23L, 0x00d10ce229936a9L }, + { 0x1cf7ef8aa4db0bcL, 0x18c033db64cb1feL, 0x019cf62864bcb88L, + 0x05ffb8eee384c72L, 0x02fc0edbc0cec2eL, 0x063021ccbe471adL, + 0x00481e3843b060bL, 0x11dfa1bc5965619L, 0x14d6c457f69e57fL, + 0x09f34d92da9f8e1L, 0x08cc2b13e272e25L, 0x06532aacd7cc845L, + 0x0d437442d192ff2L, 0x1f534a01b9e6a81L, 0x00c198bc1339642L, + 0x17f26d582a6fdf0L, 0x12fe02bcf77b6d0L, 0x00bd554ccde480cL }, + { 0x13d56438e55db2eL, 0x0f7219dca342886L, 0x03956e2118be0d7L, + 0x0bd42fc4f834288L, 0x1d95f7a9a6ff3b3L, 0x0b396791fcce1b6L, + 0x11701c85ff766f7L, 0x04be801583dba40L, 0x094b55c874ff06bL, + 0x1225072872524dfL, 0x097a46d0eda04c2L, 0x1bc2429f2d8bd12L, + 0x0c0f97fa9778bedL, 0x12dfe93387a2b52L, 0x1d823be8a3f61aeL, + 0x0e97876965b1f7cL, 0x04afbd5ff8c2264L, 0x03594157852f9d9L }, + { 0x0fc025f6341a595L, 0x01c6b5222f1463cL, 0x18f7ad11a109647L, + 0x06eaa8f066e57adL, 0x083e16c43f9466dL, 0x13d65a488a0a698L, + 0x1ed905176519a56L, 0x162205bbe131fa5L, 0x02a2b2d2d0bfd87L, + 0x0f4df2e2ca2a844L, 0x1e2fd2a0091779aL, 0x1ad16460d61ddc6L, + 0x06c2be9f3d80b0bL, 0x04016122bb52a2eL, 0x104b7ed0a7459edL, + 0x12ec427cc884e56L, 0x0bfb664f529ee8dL, 0x036a7ae91aa3837L }, + { 0x1c8f2b600ba9f88L, 0x003f03ddb685f9aL, 0x150acee0796ff72L, + 0x1d4f58f03c1424dL, 0x137dcba6335ce6cL, 0x04b2439f184737fL, + 0x10d340a3729898fL, 0x04ce5d74afd1030L, 0x1a9e3d59f79b78aL, + 0x17853ee9783d751L, 0x1919e093417dd34L, 0x02e0022dbd6dc1fL, + 0x1258f37580b2085L, 0x1a0385d9ce152f4L, 0x05df6439e2f5e95L, + 0x10368aa3f90e573L, 0x0ad6eda93c440dbL, 0x0255785a7eb2e9aL }, + { 0x1ef25063514c7afL, 0x13ed6de0c0f56cdL, 0x1a1e3e8fb162c27L, + 0x0a2e770d0bde795L, 0x121d32ddd8dbfabL, 0x0ce233592487e04L, + 0x16f6d3bbce1ae2fL, 0x1b7839baa5f40c3L, 0x064de989a25bc04L, + 0x17cc1b5c2b9431bL, 0x16a0122f912a801L, 0x1c9c12e0318e234L, + 0x17b2c11fb116dedL, 0x1390f66cb95762bL, 0x1afcea45136b786L, + 0x029aff338a4d7adL, 0x137a1d4165b1c2eL, 0x045965e9cc15e31L }, + { 0x0ec1bf28a52e991L, 0x1017b67cea17614L, 0x04c318d3a9142e8L, + 0x078aec5739060faL, 0x087c2a2d3fc257bL, 0x0ca4455e994c68aL, + 0x01b4b2853c69e8cL, 0x1138e1952760d74L, 0x19aa3f4b3ee405eL, + 0x03277599aef7573L, 0x17d5e00efc75333L, 0x016a8ac2d7fba2aL, + 0x06086e33f6041ecL, 0x18121e7a91efc07L, 0x1333560e669e723L, + 0x190630d85049d0eL, 0x070220eeaec8fc5L, 0x02bf141823edf1bL }, + { 0x060b698fbcdf666L, 0x0354cc5f5d8e937L, 0x16ea012610daf74L, + 0x1ca457911a80895L, 0x08423b20d76bf75L, 0x1cc53932ae25cd9L, + 0x1d8059703d2494cL, 0x0b4eda9e56e1946L, 0x1469899252030faL, + 0x159bf43db02a382L, 0x1bdcc54f786cbe5L, 0x19195aa9de0bdf2L, + 0x0aa93617b05ecbbL, 0x1e5d10bef5944e8L, 0x1528b5ceb03ef55L, + 0x0c0c7a1a796ac33L, 0x1a6e8bee9d4c91dL, 0x02789701bb4b7feL }, + { 0x0cfa42215f1a610L, 0x12e2a9bc328cd26L, 0x1151ce0e04d2012L, + 0x0896509c54248d4L, 0x146d1320fa15b48L, 0x14507d1b2326328L, + 0x0013bedaea231c2L, 0x0d4e9cf9dcf2789L, 0x18c34d22cb95ae1L, + 0x0cf6c4ffce0ea6eL, 0x0219b4c8094dc67L, 0x056537ac8894c34L, + 0x0cf277bab145b23L, 0x14a245817c44749L, 0x1487b2dcf9a71baL, + 0x15f643492dd52b6L, 0x191a8f78ea75858L, 0x041e9199f589337L }, + { 0x063328867b478d7L, 0x10d70a8517e4e0eL, 0x0cc06348906e87bL, + 0x111279ad2c0b6d5L, 0x08117a8769f1f28L, 0x139ebb8aceb3305L, + 0x17c2ba0480465c3L, 0x164a51fde0127eaL, 0x1b3978db8d854dfL, + 0x15a1f7b7a2ecfddL, 0x192ffb56fb8e5f5L, 0x1eb2d7eedb5a2fbL, + 0x0e3d40754ca01e0L, 0x1c7437799459140L, 0x147961a3b6d848bL, + 0x14ab7044d6d5f6fL, 0x021463532152f40L, 0x039b1789f62d18bL }, + { 0x12eb27c73c0c430L, 0x0532fd28e1b2bbcL, 0x1b3b48653c6e330L, + 0x110296928ea14b9L, 0x0b6fbbf41894568L, 0x1543045df8540d2L, + 0x1e578ddbd3d63c2L, 0x1abb26c3ad0730eL, 0x1b6510cd8e3a8d0L, + 0x1f17edfdb60d22aL, 0x04553abb2247e58L, 0x0e2bfead1ec8592L, + 0x172f2b399e0eb1eL, 0x04f85f85f3d7ce6L, 0x060da547f0e6eb2L, + 0x04151e10c3b2521L, 0x0add9b16f02da0aL, 0x01788349fd1c607L }, + { 0x1a6ce910c06ded2L, 0x0421797ec843d83L, 0x1f5aa7d8d69be5dL, + 0x023dac0c4dc8d17L, 0x169ee54804b6189L, 0x0b51008fd97c4f9L, + 0x0ceb272f4444f72L, 0x13cceb359fc21acL, 0x164ba66fc8faa62L, + 0x1435724a3f9c141L, 0x10e81756736a669L, 0x162811d45edd051L, + 0x04af3953c87c7afL, 0x0ed54f2792a8e47L, 0x1bc65016d4f49e6L, + 0x0f9b63dfed1a95aL, 0x0432775dbdd9643L, 0x04c2fc1f227f3d0L }, + { 0x1603c16eaf45294L, 0x188b06125aba8c4L, 0x0060e75ad4b5c04L, + 0x05db28668098224L, 0x14f41b687079cf0L, 0x0560f0862d8145bL, + 0x13c38f70fc1da72L, 0x044b58bdd47f164L, 0x0ee6684bae34c5cL, + 0x092cf31cd5e2295L, 0x14b347a77d17329L, 0x1926348879f560fL, + 0x0992c003b307019L, 0x06c65e17347eed5L, 0x1e0729cb67c5e70L, + 0x18f3377e2b4de3cL, 0x0f154d779d550dcL, 0x0064472a007f4b1L }, + { 0x0f71a6ae8f44357L, 0x1a5fb1d1e55b542L, 0x16796baf1a03dd6L, + 0x0914ea7de466993L, 0x075e3c8ececaf08L, 0x07c69d71400a608L, + 0x0cabaee7568e3ddL, 0x124eb3108c9701cL, 0x17b328e6ff2bc37L, + 0x1dd8fd7f76870cbL, 0x1ab25568cc196baL, 0x1b1f245b79d0ce9L, + 0x05987b907a8c19fL, 0x1d9d166bc60bd74L, 0x01ddcbe27ccd89cL, + 0x19dadd75d4033f5L, 0x1154e5de4993a25L, 0x04712b05c578883L }, + { 0x0d3746c3141aba6L, 0x083cfdd5967cf2bL, 0x00c673749f1d168L, + 0x053bfb2a1d6c705L, 0x1a9408ff2223763L, 0x0b008c0f058ae69L, + 0x0ee9d26a00802c4L, 0x1aa4e33b6bb4707L, 0x16078340a651046L, + 0x094ea6f4ba91d8fL, 0x00d1723828a2ae2L, 0x158415be138e808L, + 0x052331d61161275L, 0x09c8e5285a0d593L, 0x0488c548c331df1L, + 0x13453117c19251fL, 0x0e5fef3d92b92fdL, 0x02c802f91419279L }, + { 0x1b1750c3c4c1c74L, 0x1d56074b37dbcb5L, 0x16499b165cfef9cL, + 0x04750cad6d0b4ebL, 0x10446cde8c97f93L, 0x19c4bf95b821d8aL, + 0x1cac952245bdcffL, 0x1cd227ba0396316L, 0x0d0a751f1488c0dL, + 0x08bab8a42ac652cL, 0x050c0512998f686L, 0x015961c10c312eeL, + 0x0cf39ead9c2df19L, 0x0b9c16d080407e0L, 0x18a8ce00216b1b8L, + 0x15d1bd2f230a264L, 0x16ee4495936b43bL, 0x02bd3c7136bc1efL }, + { 0x01b346f40dbddd8L, 0x0d493ca0861d60bL, 0x1e0c621b3cecad2L, + 0x0467727bd718a84L, 0x00df579d72df323L, 0x077a804e46acfaaL, + 0x0190f975e99f708L, 0x18788d67230cfe1L, 0x0ecfa2445ad96adL, + 0x0c7ac4d8622a268L, 0x124c0782105f5d9L, 0x1ed588a9c511cddL, + 0x0fac0f462d6ca5eL, 0x046c501b20c8824L, 0x14d6dfa14901f60L, + 0x1b50f698a674fedL, 0x0e83251e4128f6aL, 0x00e51b862c0e239L }, + { 0x0bd5171a801b68aL, 0x143ce7e8ccc59caL, 0x0afd0458c809cc4L, + 0x09eb603fb6920b5L, 0x1cda128bb5fe87fL, 0x1e98fbbc6f291d4L, + 0x130d42fc586871eL, 0x05b6bbd9fa04720L, 0x0224b2882e188f1L, + 0x0e9400efcced73aL, 0x119ed4233473483L, 0x187b810cfc7395aL, + 0x002b4250726c311L, 0x177ec801b8d08b9L, 0x0f4ec0e0efd1938L, + 0x0b754a7a089143bL, 0x07932db52f4e626L, 0x012c259a62619d6L }, + { 0x0b863892aeec688L, 0x1a05d22fdf2919eL, 0x07dff582d7e2979L, + 0x1890e9227a845ceL, 0x1a17d80d455d185L, 0x02a29202615d9b7L, + 0x0995cfc9c6152b0L, 0x190edba608b5173L, 0x02e42c3e162ee7cL, + 0x013338326fb63e8L, 0x1f754771f2d2200L, 0x157c30f12fc0b24L, + 0x0ef2d5737c6b3faL, 0x1fa8d4ffff35691L, 0x001eeaabed809a7L, + 0x14935c3906a8ad3L, 0x085acddb6ff951cL, 0x03f4089ba1fcd58L }, + { 0x1722a8b830a88b1L, 0x0c75467088bf0d6L, 0x02e01026d1f6464L, + 0x06d88da3a67c05aL, 0x0589669cb53812dL, 0x1866af17e84ed87L, + 0x1114e6117341856L, 0x19618382ab4470dL, 0x1da774de5f5ff43L, + 0x183b5cc71c8e066L, 0x1c7bfd4013ca1aeL, 0x08d95dd817fd2faL, + 0x0732a1ad9423e0bL, 0x1cb6d2117229c33L, 0x16caffbf8327e04L, + 0x1f522c6ed8344c7L, 0x1a6001c7918ba56L, 0x021b5c6326fc242L }, + { 0x0117e9d8ab764bcL, 0x10f4a503befc244L, 0x174c3063baf77e9L, + 0x1ff928a3b8b4eecL, 0x071a347a548916aL, 0x1da0ef80d297198L, + 0x10a198cee577ac8L, 0x0d1bafad1928791L, 0x1e4f9d41e18d970L, + 0x0c845c846493cceL, 0x10523b51ce528deL, 0x0a2f9aa3ca7fcc2L, + 0x1e0243dcb6e5018L, 0x0bcaa202a83003aL, 0x1f697ff97737988L, + 0x196ccdef921c2a6L, 0x1e11df7aae40768L, 0x02933654f36df4aL }, + { 0x0ddee6d1386b3dbL, 0x057ad3e1c72a042L, 0x1103ac13d277e79L, + 0x11fbcb49fb66830L, 0x10257cfc2138a1eL, 0x1eb8609f3734921L, + 0x07fc0d4671b8c67L, 0x1d11e69c2e90d86L, 0x0f1e298fd940ce1L, + 0x1dc658e8a4b06beL, 0x104d1cacbceffdbL, 0x016828ddf1fe40fL, + 0x0b7bd3e220899a2L, 0x1135f513bef61b1L, 0x0d32d9ea5d41139L, + 0x0e0741e6568929fL, 0x02bc17a09201fc6L, 0x020f992dcce6c25L }, + { 0x12ed513ce2843a4L, 0x024c70039457e18L, 0x0089361933979d2L, + 0x094c40107751de5L, 0x0bed338d3406470L, 0x1f3d9c2c82f0ecaL, + 0x1eee4a95e32d418L, 0x083304edb2c513cL, 0x0dfe2dc47f17b73L, + 0x091a90f8ed644a2L, 0x1b4a348d002a9d6L, 0x00bd4ec374867b6L, + 0x0d9bfd07ddc6477L, 0x1216547ec4a3dd3L, 0x030d1a003cb8eb0L, + 0x031fa93de8ce1d7L, 0x09e7db3d37bd9aaL, 0x02b5987db72c675L }, + { 0x1ecdcaacd80a428L, 0x0916e4399644883L, 0x1e60eb69107debeL, + 0x092496011441b10L, 0x12e81c3a3bed9a4L, 0x1c03e99091a99e5L, + 0x0bb2f0d3901d597L, 0x11a17f5df4a3e5fL, 0x178b634a5ade8a8L, + 0x0705bfc4a1c9548L, 0x088dde42ec73631L, 0x09f5f0e4095c612L, + 0x1585d3cd83dea9bL, 0x03291d3c9f6fc0fL, 0x10365a563e23147L, + 0x0fe0fc8e5f7162fL, 0x146899081e5dccfL, 0x009a9e62bac5ee8L }, + { 0x0a5649739bf6e18L, 0x05ad1324dc4e394L, 0x128373a2e39d67aL, + 0x02408e08191b286L, 0x0a7b8e82d935bf5L, 0x1c094a1559d0b23L, + 0x1ca5fc560fb589fL, 0x057082d4fc0e5acL, 0x149685d86cd39e4L, + 0x13cbfe3cac6edd6L, 0x03e4a055739b7a2L, 0x0ae1f146c46b4abL, + 0x0052877ae575f4eL, 0x1358b75ede34e7eL, 0x07307c63d064ea6L, + 0x1cf131a3be87976L, 0x158723a830e5a21L, 0x01f610c2efa28efL }, + { 0x1d4c7d71f0bc2d7L, 0x163663728ea095cL, 0x164e827e03d9a60L, + 0x0a08f5c13925c05L, 0x17f351f9b7dd2d2L, 0x1c285f1a818a4f9L, + 0x14b21a75273871dL, 0x13ac048559625e1L, 0x0ba188c567bc28bL, + 0x1203090835e02a8L, 0x012c7e35f50ca63L, 0x15cfa712a3c161bL, + 0x1b8bc97607b4a67L, 0x0a4bd5395a93e2bL, 0x0f7599af24f17cdL, + 0x08f46be3bd19873L, 0x1e53087dc5ce9d4L, 0x044d9ab5b5108d5L }, + { 0x16db0afdfdcc837L, 0x005d55438dbd4f6L, 0x1f2470752dc83eeL, + 0x0f5b593cb882757L, 0x0b8657a3f5b56bfL, 0x00eca72b32516d4L, + 0x0d96046c13dc839L, 0x1d4c7c23a4c6e86L, 0x0ee628ecef426daL, + 0x08b0ce4e58b16e1L, 0x1605fe1d92190c0L, 0x0e04ab09790d39eL, + 0x0f00bf7928e1bb9L, 0x0e30777296613e7L, 0x0b70be53bcea03bL, + 0x09ea4fc24057d0fL, 0x126656f18e08a0dL, 0x01ce27886abe2e8L }, + { 0x1a9b68ce88aecd3L, 0x1848c528c554ed9L, 0x16b52f53b951556L, + 0x0e040d1b09db839L, 0x011ac72d79b68b6L, 0x0d053c3ed640684L, + 0x18a0db479b4d6a0L, 0x0899083d3d477a2L, 0x0a7bc1775894c44L, + 0x15b1b92f8d50901L, 0x1dd9fb1f53155bcL, 0x1767a8dfea377d8L, + 0x0d73f7e3392817eL, 0x0d7692627ef2df4L, 0x195e73d131b25ddL, + 0x1f79817342e0f6dL, 0x100cff164789069L, 0x020a5aa16a48a95L }, + { 0x1c31e58606e173bL, 0x1a70dc873389d19L, 0x144b7aec82bd6dfL, + 0x0e0a241ce084bf6L, 0x1013e4ecc788c61L, 0x03736b9f782b014L, + 0x1a42a7e74d6b207L, 0x05dc263d11f28a0L, 0x1708f9b3244af08L, + 0x1726b360dd15754L, 0x1d29b9d036ca72cL, 0x0491a308600f5e3L, + 0x18ed556a6c74ab9L, 0x13868bd30999c77L, 0x023d6ffd23988f8L, + 0x10a2a78e6c5f52cL, 0x12a43977874444eL, 0x02933c6b57005c5L }, + { 0x1ff1c59df36aeb4L, 0x1329e5495e055aeL, 0x125a49e97e054b5L, + 0x085bfa923e1c07eL, 0x0571f89b8509d41L, 0x19a24292c616295L, + 0x07824af5860124cL, 0x00c3467d29e7efbL, 0x0fab418d32c1bf9L, + 0x1ce24872d52b4aeL, 0x0465bbdb4b5fffcL, 0x00ea1ef291521c8L, + 0x12d3053b4f3ecd4L, 0x0eccba64a5ac7cdL, 0x08bda0ae3ba10a9L, + 0x19d4c474b383b7eL, 0x0dd045ac614c8efL, 0x038205d2de08677L }, + { 0x0364f81515a1a96L, 0x11a818c2193f016L, 0x19406b64f53cc69L, + 0x024e76c2e61412cL, 0x12cda9d29d7694fL, 0x0a60bbc4436c3b6L, + 0x1a5ac78069d08a0L, 0x00c69244ed70cceL, 0x02fd4f0c65b25f0L, + 0x0939a4ffd94a625L, 0x18362b7874cdbd9L, 0x07d1cfc70c1d83fL, + 0x01b774c31eaf9a2L, 0x01b2bc254be95b9L, 0x1d3aa8feb0f9609L, + 0x06491fe5bfe9ce1L, 0x1c13d281e1afe87L, 0x04821d36b05e8e4L }, + { 0x111a0fe766c7937L, 0x0f6ae55de1df18aL, 0x0333802222b06cbL, + 0x1ac2c401e65582cL, 0x14a2ea06928754bL, 0x1f0837dc00e41e9L, + 0x136522b5e80ea72L, 0x10132d610459dbfL, 0x1c3c3463ae40698L, + 0x1897526facbfb31L, 0x14e0d10324abe7eL, 0x0b8c9d1b42a8591L, + 0x02db4e801a79bc8L, 0x0f1abcd94abb8fdL, 0x0ab41e1ef4b04e0L, + 0x1588dc8b8ebbfffL, 0x135b0760a3cb73eL, 0x0131b15a41d092fL }, + { 0x1c68d28eefc3e89L, 0x1743bb4f4f73892L, 0x0e1abd792dd4b43L, + 0x05970d6667160f7L, 0x1f552bacdb70907L, 0x06d0f4fe9e90757L, + 0x1c51697bacac530L, 0x10a723ed11489f2L, 0x121fbd3101e06d4L, + 0x0f27952df54e6a4L, 0x0351929efc87691L, 0x11900a9aa8e2f6cL, + 0x11bee0f2e9193f8L, 0x00a1c939ad6729eL, 0x11ad7ba4b09958fL, + 0x0b375390dc1652dL, 0x15e452fe23109ffL, 0x0174a95902aae49L }, + { 0x0846bcad75f886eL, 0x12edf6a1efe2c15L, 0x16d801ec6e1b9a2L, + 0x126abfe56a207c8L, 0x0263ecc9580e2ecL, 0x0f2f19de3817935L, + 0x081d8a0d6ce1860L, 0x0da04a227d8d824L, 0x1a5c26e3a7fbd85L, + 0x17c1fd9ceb75e58L, 0x094fca9134bea23L, 0x1e66a763f52ef55L, + 0x1117559a307c14eL, 0x1849bbf07fb0250L, 0x0bc09ccaf365ac2L, + 0x1de0d4b82912db6L, 0x04b1c0a84c9eb53L, 0x0091b680b981bc7L }, + { 0x1481c8fc084373bL, 0x123b432304bd76bL, 0x1e8184ef0d2ca6bL, + 0x19269785602601bL, 0x0e2be7e23712714L, 0x008400432923148L, + 0x115d9553eee7fb4L, 0x105e1d816708462L, 0x165baf594330a32L, + 0x1eef0d438377c0bL, 0x11c9f6e9d4c3a4eL, 0x1acce9992b96fa5L, + 0x052438906dbb0c5L, 0x08a32c79d9fe69bL, 0x05fc3a466206507L, + 0x18fd5cc2deaaad9L, 0x16e353c2d854b9eL, 0x00152400a31065aL }, + { 0x1d6d23d506ccd38L, 0x10e2a482cdd5308L, 0x109da74047148a6L, + 0x0db05126fae2f93L, 0x03835083e87e1b4L, 0x0d612c7aeb1dddcL, + 0x1347fc29ed09eabL, 0x1fb33564d7b3e2aL, 0x0dec0ffbf8ec955L, + 0x14abe33a4fe5c40L, 0x0577b87804537bbL, 0x096e6d3e8d8e647L, + 0x0091eb2599192a6L, 0x117461ed2182233L, 0x155b462f8b6a21eL, + 0x0ebe7489c584b86L, 0x1e031390414b55fL, 0x00ec5ef37c790bfL }, + { 0x1cd39f8a2028924L, 0x078ce583765cf81L, 0x12df5bc16119b95L, + 0x0cb40c0eed0c577L, 0x110fec10dbe0671L, 0x0ddb2e49cbe4bd5L, + 0x0e8e3d084e099bcL, 0x1cc829bd9974ce5L, 0x1594d4d43f88b05L, + 0x0c9fabd564a6a68L, 0x10a9aafec5d8e1eL, 0x16b76df8cab4e9fL, + 0x04ee8d2139d8196L, 0x1b069d136e1bae4L, 0x0e4ee1ee6c02808L, + 0x0413d66dda6b9bdL, 0x1c1f565b28bcc83L, 0x01a4e34a1e30809L }, + { 0x1b394444de6c88aL, 0x16238a380103f68L, 0x0288870ade03570L, + 0x0810a1327d6de8bL, 0x1aef0c18749f756L, 0x1e38782005d2bcdL, + 0x1fafcb5d0a4e1cdL, 0x0a78b51c5d8428cL, 0x0243a666e5337f4L, + 0x0c8f8e3f685ea85L, 0x1cfa43d2f47e472L, 0x1d14be1c253674fL, + 0x170738963596089L, 0x138c1564e869d0bL, 0x05f170a73e10b54L, + 0x0aed24232a53210L, 0x0faa32f327e8725L, 0x002b2c3d5c4e16cL }, + { 0x08562ed1ce4733dL, 0x1fbe5cc728a2200L, 0x087ea6ad1ae57ebL, + 0x1d6c351826be060L, 0x16b3597689494c5L, 0x01697b2be4a81b1L, + 0x1c0f9afa1323cabL, 0x1761cb669b137a4L, 0x1c4ad918f7e872aL, + 0x1544f4fe2029770L, 0x0bb8fcc642d47b0L, 0x086edffe4a9f859L, + 0x08883e097258fd1L, 0x07d8aa1c379e06bL, 0x12ab8018f4283a4L, + 0x01ed98870ec97edL, 0x1de815f15653f1dL, 0x00dc3f976dc366dL }, + { 0x1792bbb2b0b15b1L, 0x05ad3e735d3bc9aL, 0x1f67763cdde68f9L, + 0x1b8531a3dff759fL, 0x047031c6005450bL, 0x0b4033071faaab6L, + 0x14b081dc3c1ea57L, 0x0a99c7d09c05a20L, 0x1b050791e7aa8ccL, + 0x0b10f39dd1911d1L, 0x06e534e58ca6413L, 0x168efd700adb0f7L, + 0x08edfca0cc8df9cL, 0x0b895065712186fL, 0x0122a64dd2fd05aL, + 0x1cb3d7c7e78ef11L, 0x023b22b87b1c4a3L, 0x0470113e21f4adeL }, + { 0x00e22a83210964dL, 0x0aefaff82b77580L, 0x087f6bc7ab5f733L, + 0x00cf9b95c6042e7L, 0x0bdcc90cd02833eL, 0x125a7a8e62ba65cL, + 0x00a621bb29c50c8L, 0x1d7a01cc075767fL, 0x1b98ece1b0c1a8dL, + 0x14523721bc6130eL, 0x077436985979748L, 0x113296fde1c58dfL, + 0x13bda9f306b3ae3L, 0x1c50426d9d1e0b5L, 0x053a5417a689b4cL, + 0x00d78a51cb326a7L, 0x16e848ecb114ea2L, 0x00a58ad5aa02a2eL }, + { 0x16d86c9664c59a2L, 0x115f0b07ebd5287L, 0x15a641cb2e38f7fL, + 0x1302ed4fc067f36L, 0x0587080b5f2325dL, 0x0ea702bcd06a73aL, + 0x0a38693b837bc35L, 0x1dd815b3ff590f6L, 0x1d6f18d2f3f09b4L, + 0x044b57394974ec3L, 0x0254f58251d8f33L, 0x0f5031f7f3f5951L, + 0x094b63d701dbee9L, 0x03f53917ef90707L, 0x0ad5c7f2ee9b8c1L, + 0x0abeb9cafc394c2L, 0x02e1e16ac76009aL, 0x03a15df6c621c4fL }, + { 0x1ea86dcc1dc2c73L, 0x1feade0b21d5f91L, 0x087c9363287d2eeL, + 0x01196b958e0ff1fL, 0x14e66a7dde68a6eL, 0x1bd6bc3eaa6325aL, + 0x0ae51e276e88aa6L, 0x0229b11aa81c6c9L, 0x0c8c2e02d1f72e0L, + 0x041302ba371513cL, 0x0d6ecd2c61f1f53L, 0x1bfdd71fc193cd8L, + 0x087d11e415ed8b3L, 0x1c32e3fcdb5e1a7L, 0x1b305f2ce422efeL, + 0x1ad36e2fa39cdc3L, 0x124151e3308f7cdL, 0x04bdead0a5ae4a0L }, + { 0x01c62fe81e82861L, 0x0a5b6eea1620770L, 0x156f997a4795c0fL, + 0x08b5777fbafca5cL, 0x072a45f4b8b4937L, 0x0794ec5a78afa96L, + 0x19d7f3a10d6a154L, 0x12d3beed736b05bL, 0x052e84c5fa20c8bL, + 0x1bbe9688545057aL, 0x06ef6329804f0ebL, 0x13744df060be071L, + 0x080cec8b9ab0d9bL, 0x1fd5ed0c7829f42L, 0x10930a9358cd9ebL, + 0x1745ca1ea77c94cL, 0x069f892c58c864fL, 0x018be3698a4662aL }, + { 0x03525b02cb7d42bL, 0x005e49887d65706L, 0x008bfc81023d549L, + 0x1fc1821d411aba4L, 0x118eb23d6b01402L, 0x12950cbfdf7b453L, + 0x035ba8051ad6904L, 0x102b35f9c90221cL, 0x0e9a1d27f022de1L, + 0x0dcb68b6e1fa4edL, 0x0b8fd7bef90021bL, 0x0c83d9978239f83L, + 0x19525f8636f9d70L, 0x013b1e182481113L, 0x0418c2cdda5e5abL, + 0x07e2f398690783bL, 0x0fd451651f0ee3dL, 0x03572cb9cced05cL }, + { 0x1b13bc7bff4d2eeL, 0x0a1149858b9ec2bL, 0x0f541e524db081dL, + 0x14bdfaab7d6c4a9L, 0x0e0c33891d5f232L, 0x10fca26037a542aL, + 0x01edf3cb16d6639L, 0x0998ac90c3ffabfL, 0x0ee261fb15a2afaL, + 0x07fb91316cbd3baL, 0x06b88b5b3c01eacL, 0x0a69a68de428351L, + 0x1f97b6497e28880L, 0x1d157ffe47f39dfL, 0x1469c9a2a1656cbL, + 0x170573df39e7de2L, 0x072a84ee5f1e744L, 0x033248246de31ffL }, + { 0x1b7bb781e8b760dL, 0x185ec12d56d5048L, 0x167fead489bf51eL, + 0x0d7ff8291d02927L, 0x029be3db4a6dd22L, 0x185585ad0197c55L, + 0x121a0c636f1c0d2L, 0x08db9997f6afacaL, 0x08506ab379c581eL, + 0x089b53714187671L, 0x1e4d5b3db2031c2L, 0x06efded63d0c916L, + 0x0183f0f1c9fa176L, 0x0b55f6ee964e0e6L, 0x0ec37925bc149b4L, + 0x10e747c1d31c552L, 0x1ec6f2d7ada0f13L, 0x0275c9dae79fd24L }, + { 0x189f7e5e11fae32L, 0x0ba7ae2011fa8deL, 0x137d2470fdbf44fL, + 0x0eaaa4f36e36002L, 0x05ba00681d849a5L, 0x1e51655dcf444b8L, + 0x19dbe0888906704L, 0x0555f776d0bfa66L, 0x1931c3f5275878aL, + 0x15777f7f79ea8b9L, 0x097322f629a1e04L, 0x1b67b33e182c313L, + 0x06a19d48b682cffL, 0x14e362705fab2a0L, 0x00105c95817888fL, + 0x03990a7cf03bd0dL, 0x168cdf5c90bc700L, 0x015ac16c9be021fL }, + { 0x1165c8281abc2aeL, 0x1c07af15b4f6550L, 0x0f481fffd9be9ccL, + 0x0ca8eeca0d812f6L, 0x157fa21c5d60382L, 0x06deeaee5d64f9dL, + 0x1cca9e1d436d326L, 0x0390bc42207b3dfL, 0x1ceed172c2f11c4L, + 0x071c9324f1a4604L, 0x0e4dae0c7b77eeaL, 0x1a0dea10c946e39L, + 0x0de93acfcd915c3L, 0x19f97bd57f4719eL, 0x1f3ba692fb8435eL, + 0x095fb83b1d691d6L, 0x0c04fa49ce3fa57L, 0x03c30a884c316daL }, + { 0x1e3f4807ae72c21L, 0x150a27e8786d29fL, 0x07a3e30e91518c6L, + 0x08a369e3578eddcL, 0x17cdbb24379ae09L, 0x1eafe6951d21cbeL, + 0x1bd69e8533ffa0aL, 0x19f77c9da25e84fL, 0x09b0a43ee284d3cL, + 0x1dbc5c9c776370fL, 0x1013919ee3a1ed5L, 0x180a686e984031aL, + 0x055428deb50c8adL, 0x01d7d167b21b9b0L, 0x0a55be6d3603b03L, + 0x038d0daa3f27875L, 0x0259f9a28ab8416L, 0x02a05b5dbb5e4e0L }, + { 0x0e1734c321d315dL, 0x0b3096c3702e802L, 0x0516eea336053bdL, + 0x1359b8f135d5f5cL, 0x1877570f1fb07a4L, 0x1e29ef3510f4d6aL, + 0x063acb92a0dfae6L, 0x08a86db65263ac5L, 0x143afbc78ea362fL, + 0x14b9ecbd55fb2c2L, 0x1f6af832493580aL, 0x11e0f95be1d3b9cL, + 0x0175020538f69d9L, 0x0230e694f05a82dL, 0x083a060f6df468dL, + 0x0a1edc3850eecbcL, 0x08c2ca2586752ddL, 0x044be558a49701cL }, + { 0x1ed38130d8bab8aL, 0x09b26521c10052cL, 0x1cb101605057047L, + 0x14f5912ce80d0f7L, 0x197411a086ad0d3L, 0x019b8e22494082dL, + 0x00c79d2612c47ceL, 0x1c0e1a5db081a35L, 0x0d883628b6c912fL, + 0x07c7bfd8a7d4469L, 0x1ca9373c2b24f91L, 0x13554d849f4cac9L, + 0x03bf6cd94982f62L, 0x10528c16d5c835dL, 0x1ae4e94b208b99cL, + 0x0e7545fe8fb5861L, 0x0c5dc62c4a4fff6L, 0x0325803b1a3b587L }, + { 0x03f533eb3c9a404L, 0x1bfb9dbf7cca90fL, 0x18a5b094da4ec76L, + 0x080e71dda98fe27L, 0x0e26cad07ce7f4cL, 0x162e78e67e9d99eL, + 0x1380761e124d407L, 0x19e7f1f813bb810L, 0x0217cab32c39b5aL, + 0x16d785dcf7aaa8eL, 0x1dbd5b8485ea550L, 0x1625846e0055f78L, + 0x1fb070a29380178L, 0x0bb654b205a961cL, 0x15a38db8e49454dL, + 0x01d084aab284833L, 0x18c291fb82c09e5L, 0x03ee91753330c76L }, + { 0x1fe844b49cbb3bfL, 0x063822ab17d92bfL, 0x14de7d6a116b783L, + 0x0dca24eff83cddcL, 0x10635718956d7f2L, 0x0abf9a163aea5c9L, + 0x1d0ace685224a5aL, 0x0e519e9d66505caL, 0x16b0d3ddd83247bL, + 0x1d4fb19900d211bL, 0x100f04505292159L, 0x088f6ded522c82cL, + 0x10dac6f79060afdL, 0x1e9dcec14afca49L, 0x12b7c3da17fe52eL, + 0x0e912b91f31f8a3L, 0x0c89559c88ab13bL, 0x0189bbe332f8c7eL }, + { 0x1c5de097dcfb35fL, 0x0654f80e61b7c1aL, 0x0175d5db2d8cb73L, + 0x15ef6966eafd27dL, 0x109a19b50c2dd48L, 0x1ff303cecae6a7dL, + 0x16b49d4bb4565c6L, 0x0de8731019e4b2dL, 0x0e52efb5369e90aL, + 0x004bb3181e9f305L, 0x0d93eaa541c3811L, 0x076c0ac49ba5f9eL, + 0x0400d5e467d8f99L, 0x0647a29259ad4c1L, 0x02805e78a274090L, + 0x1b57bde8a8478c9L, 0x0713a5fd695587eL, 0x01ed66286508f29L }, + { 0x13e4f946499ae4cL, 0x0e5f0b829e293e5L, 0x13a6f9e0ba2a91bL, + 0x11b0903c8b00febL, 0x0a286fd0b6c64d2L, 0x0e6da4f9af228c5L, + 0x0fabfdedee6eb7cL, 0x1f7e7f6c4215d84L, 0x00a9ba385b9bfd2L, + 0x08d06a9c403f9d0L, 0x091012c5eca10b9L, 0x0d0ff3bb3e14f56L, + 0x14f3e9df646fd57L, 0x106f8ca6e68f7edL, 0x1a77c15774b7de9L, + 0x114637da7e587c0L, 0x0f7469b75612324L, 0x04334a4f0b4a3a2L }, + { 0x09a0da53f4ab07aL, 0x17999faa537df9dL, 0x0486c8f3ca40b35L, + 0x1d091c7ab01925dL, 0x13b218abc9581c3L, 0x165a6bc9d78fdeeL, + 0x00e80e1663a8419L, 0x16aa002729d3218L, 0x13b664b1e7d0877L, + 0x1ced8ddeba63848L, 0x1510d538b577435L, 0x08366653b7050a5L, + 0x107b96d4800d2b8L, 0x014aee237d42275L, 0x1dfb138de9415a7L, + 0x062ef85a706e729L, 0x198dc3884ff5b08L, 0x02ba1a95c458fd2L }, + { 0x12193f70d5d7ce9L, 0x0fe9305a43f57f6L, 0x0d65ef997f40f06L, + 0x00f04e1aacf8895L, 0x1aa70198dd9da86L, 0x0cc2efc54276005L, + 0x0a360bb09f924a1L, 0x03b32d995e1bc40L, 0x14e7648c761c220L, + 0x0b19ade048e0cf5L, 0x08e9a7c359e0aeaL, 0x0681a528c9264a7L, + 0x01099f68733f204L, 0x14cb008d222290dL, 0x14ea5397f2f3025L, + 0x147427109abb1f0L, 0x04f2418c624d3b6L, 0x01f218d7903571eL }, + { 0x167d93983d381f1L, 0x00d57686019e1fcL, 0x134151041da0d94L, + 0x10a1274da77e75eL, 0x192f2900a86d159L, 0x185baaa1d703a0eL, + 0x1b5bffacabe98dbL, 0x08da1214d47548aL, 0x1336a4fdaaefdb6L, + 0x08dff220d4a17beL, 0x0a8fb6147b907bfL, 0x0d0c23d26b8aff8L, + 0x0653bbb3434f1c9L, 0x16c4b61566abbb3L, 0x0efe907c9a4c6eaL, + 0x19de3141f77a30dL, 0x1351c3d7d82a203L, 0x036d69f8af13326L }, + { 0x1940b7d12ec35a1L, 0x0e2db73efd89468L, 0x031bc4cc8755886L, + 0x14678b1d6c5984fL, 0x19903c435e76904L, 0x0cb50c8a8487aaeL, + 0x12e9c186f249b0fL, 0x0372e953e071815L, 0x17a4140217198b2L, + 0x034accefc4ac637L, 0x1cbc76faf404a6cL, 0x0c27be751b86a2fL, + 0x08672375c51109aL, 0x09c1e9698472c22L, 0x1fe0df159642e92L, + 0x1aabff87dcf8c17L, 0x03fc87a539027d2L, 0x0121c74ea2fa8bdL }, + { 0x0a453088815af3cL, 0x18d1979e4df6ae2L, 0x17265ed9777f957L, + 0x0825ca3d6b5de39L, 0x063f249061c61d9L, 0x19f118de86d62a7L, + 0x18041bc510a7342L, 0x163ee6f8785e3b4L, 0x17150e04b6bbc4fL, + 0x02da6448df140e5L, 0x118cf35dc07d6c8L, 0x1e8c54a26921e36L, + 0x1368f1f7f28b33eL, 0x1ea0b5b3eeda3e3L, 0x1e56ecfd2b69446L, + 0x01ccf3a552f9bfeL, 0x00100a8b7b29620L, 0x009f9c808d7f187L }, + { 0x1d296ef7bd0c827L, 0x08879a514ffa31eL, 0x01a072694569418L, + 0x0a4d1794eff0f26L, 0x198045dfde8d804L, 0x0072c265dc18124L, + 0x18188fe435c41a3L, 0x016550719504c76L, 0x0293bb5e7535c5dL, + 0x1754ceaab20a888L, 0x046b406ef680173L, 0x017f49b1a031fc6L, + 0x001cf2b8662497eL, 0x0c625d4599eebbdL, 0x0adef26f01d6dcfL, + 0x036165308cda8e4L, 0x1b617a7ce24cbdaL, 0x022c6a5b5b40381L }, + { 0x026a20e4d54d8b2L, 0x0b4b726990506c5L, 0x0163e653dc00169L, + 0x185eca9350d316bL, 0x1694d00d7a4adc3L, 0x02015e8c09740c9L, + 0x190411ae6c001ccL, 0x041c21428934366L, 0x1eae95ea5992302L, + 0x17e174d8da41061L, 0x0d72d61727ae28fL, 0x06332f08e0c9fcbL, + 0x108f27d49f21ae0L, 0x17b92ab5b47785bL, 0x136c068c967bc60L, + 0x1f2b8015c08aec4L, 0x191628e3b065668L, 0x02f89fafd5b7ddfL }, + { 0x06ed9ae3a9b0dc6L, 0x0def4b7c41f643eL, 0x1e23aa2cd9deba8L, + 0x1934cdc757d4cd7L, 0x08217ffddefa6abL, 0x06f82e626998bdbL, + 0x19d3bdd0723c8a4L, 0x1943e1fbe2efa22L, 0x1fdf0ece7c35989L, + 0x176c96fb5ce2416L, 0x04f99956fc729c3L, 0x05204b9d9338e6eL, + 0x02e803e69c90acbL, 0x0bb89d0d1be4f1dL, 0x1685d35f028f14cL, + 0x005ec6a1b8acadeL, 0x0a211625a4405f8L, 0x010cb24aed1bdd2L }, + { 0x0cb2fd313142680L, 0x148ebb2e8a67a00L, 0x1aaf7f899a7aae7L, + 0x1015c4578b8d419L, 0x0b6ec250beefce5L, 0x1c78ff9e15bcc36L, + 0x123b212b6c68b5cL, 0x16b2e137850a2ddL, 0x1f36931298e8f7dL, + 0x0477e35cad8cbfcL, 0x04254a6aaa90131L, 0x197a2882a9613feL, + 0x03427f34352c3c8L, 0x090c4be099f7bdeL, 0x19522801285e503L, + 0x1f4c4b54188fad9L, 0x1082971cea73d56L, 0x049d687580223afL }, + { 0x00b6967988a9963L, 0x03bfbb28af46ebdL, 0x0e18edad43c9879L, + 0x0ba67245bcc4e9cL, 0x087a5b3d63a9b8dL, 0x0171919e1c69fdbL, + 0x1333c63dbc2704cL, 0x1ee4a980b87c05fL, 0x1c04ed0b726e662L, + 0x0ab235c0a1ff03cL, 0x0a51232405b2307L, 0x1897f047af2fdf1L, + 0x0fbccde451e5674L, 0x020bf56f02c37b9L, 0x1b9623717f22355L, + 0x1a3f2572a4412aeL, 0x0344408dd425844L, 0x039fc61f87520e0L }, + { 0x1534fc85df763ddL, 0x013f99d638c1b44L, 0x185dba3c5680ec5L, + 0x099641111c1b6b7L, 0x057caea61d39094L, 0x0fbdf9bc0264d6cL, + 0x0a33ea96110a146L, 0x02ac4ddd9e25275L, 0x1749e0d98ea36a0L, + 0x1ffb6d71990f6e6L, 0x17ba98a2de4733bL, 0x0aa45a2dc6c32c7L, + 0x1cb15ae206a14e0L, 0x1e5192f251702c7L, 0x0d06a283c9a1d17L, + 0x0a370f9f3a80e42L, 0x175dfed25d97caaL, 0x00084571cd6df6eL }, + { 0x0d178f3a9e88f63L, 0x0d88f55863992aaL, 0x0f9b8987629aa81L, + 0x1d1a172390ee74aL, 0x09bb004d24db7daL, 0x118485ef085839fL, + 0x07227f22fbf9d53L, 0x0342d5e0b32198dL, 0x0ddc838039d5951L, + 0x1fb2dcca362ed7eL, 0x192fa07b8296670L, 0x1c6df675362ff77L, + 0x15445dad0088891L, 0x0a84bf0f864d56bL, 0x01693877ff11aafL, + 0x0a4671090113759L, 0x1df348bb42fa0c4L, 0x0403e036c7589e0L }, + { 0x0a969ec98ee0ef6L, 0x0aa41c5dbdbd780L, 0x124a80be3f6eea7L, + 0x1516e0aaf848909L, 0x00ad1af27bdb201L, 0x064afdf2c9a1f23L, + 0x074ed4ea6a50a66L, 0x01d2e9b67bdb50cL, 0x1ce1525c9ed399cL, + 0x0dab440fb9084deL, 0x1df456660846922L, 0x1675de1e4eb411fL, + 0x17fa2f358b5df76L, 0x01cd831a49f8c07L, 0x160ed4eab13ff3fL, + 0x133f84d258c4c2eL, 0x061b2fdfa36b553L, 0x00b2126364cb03dL }, + { 0x1d65c55dd2744a9L, 0x060e17f1d7a0c2eL, 0x1a67bfa2c224951L, + 0x0b53bed23465905L, 0x1be9967430b7ab2L, 0x1968914c1c22a84L, + 0x1c9caf3b349632bL, 0x019115c8131798eL, 0x0d43961414b8efaL, + 0x07fb3dcf6b26896L, 0x195790b9fcd0111L, 0x188a8b61d3d753cL, + 0x14f03ded283d16fL, 0x16665c2e23a51f0L, 0x14e946e8f26b7feL, + 0x063627bfcd782e4L, 0x18adddaf4b9fb58L, 0x02aa27301527a23L }, + { 0x17c5313baa80b4fL, 0x138b7b1dee477c4L, 0x0b6ded0b16a0048L, + 0x12110661195c4e8L, 0x0d341ab1e9d9e1eL, 0x0a2c381a96461f9L, + 0x1676058f41403b6L, 0x0530693bae78521L, 0x02053c5e01f6c7dL, + 0x1883a2365a1019eL, 0x022f4827426bc60L, 0x1cdd64f28d02ed9L, + 0x1e19b1b540d0f70L, 0x114ca5a1b905aceL, 0x1b14f3e02dfb370L, + 0x01e8583499b9c5bL, 0x061dd7d3edd1ed6L, 0x02b9accae7120e9L }, + { 0x04ba3fba0237056L, 0x160b219d599c46eL, 0x0ef49c7b1849a15L, + 0x07c60637d9803ddL, 0x0118a1f5abdeb03L, 0x100799a777220cbL, + 0x01dcfb125d0856dL, 0x1fa36e30b9e110dL, 0x17b0c46cd7c1b7dL, + 0x0a1d96d25262f44L, 0x096612ec7fe5374L, 0x09c9939e68cbb73L, + 0x00eace64c9ac390L, 0x1b456ccd7c394deL, 0x05503097308a085L, + 0x0d22f77a7610315L, 0x0f0e468ed5f049aL, 0x0442a436f9f622fL }, + { 0x0942c934bdff464L, 0x138cf92d3da28b5L, 0x1c2cc96f8c90f6cL, + 0x1633fc667399600L, 0x041ee8ff2055a31L, 0x17c6f7d6534d741L, + 0x1cf19d81f742157L, 0x0213c492c1e3436L, 0x1bcb0e8a271d368L, + 0x0f08d513442f35cL, 0x1742ac617ab864aL, 0x0dc81f03f239316L, + 0x0f994fc5031a0b9L, 0x188ceb70268745eL, 0x0933830cf605a5fL, + 0x1f3ae5210650f55L, 0x02dc5dd4d3ec91fL, 0x018e767f46a55cbL }, + { 0x17bfd9afc8b21e8L, 0x09959d8ca1b6fa1L, 0x0b524870da83977L, + 0x1b47a1f521fcb20L, 0x1bb523bd8e9de84L, 0x06b4bacb31f356aL, + 0x0d672600288febbL, 0x1e2201381b369f7L, 0x1839aa7bdc9d20fL, + 0x0817b36f66b7d1eL, 0x1b53ef1545b2a7dL, 0x0becd8e85588901L, + 0x05ff3252f865ffaL, 0x1aece59e95be3caL, 0x15bc749cbfbf015L, + 0x09d8623610c77adL, 0x1b35d8f3cf09a6aL, 0x034b0da356d12a3L }, + { 0x07b587ecb35e2acL, 0x0aa35abd78a6ce8L, 0x096f6ca281307b5L, + 0x08e13aa9e1d942fL, 0x1c6f400ea1f91d4L, 0x0670c853738cfecL, + 0x0ff49392e23b7eeL, 0x0bbf2f03dba48dcL, 0x1d67120e6b655afL, + 0x13c168ec9a09e53L, 0x18828a5c1fe8876L, 0x1e64a9d08246d2fL, + 0x1e36051f9f1eb51L, 0x19e72df49712a6cL, 0x0fde53f76bb10adL, + 0x155b31353465d9aL, 0x0121964e22f0781L, 0x03531d48629baa9L }, + { 0x0554e003d7acbbbL, 0x0b3455ba7b0843bL, 0x19c8e231466cb00L, + 0x087d729a9fc9452L, 0x0cd6d2f60166771L, 0x1b87bf84351e6f8L, + 0x0f9f3e1960085ecL, 0x142cb110182b49aL, 0x1d6ed58165ba3f4L, + 0x1e63c09ae5238eeL, 0x0fc1d3a11295daaL, 0x0366dd4a05d5013L, + 0x070e021ed3a53a8L, 0x030bf8b2e105c98L, 0x0d7342e309fe24aL, + 0x052c34a8ec88d04L, 0x10effc89ffd8255L, 0x028f6a51168a8ecL }, + { 0x1d6963a449701b4L, 0x0c8d1dd93e5791bL, 0x1856d5ca597faa3L, + 0x0bb6a17efa7df37L, 0x0e643b9b75a7a05L, 0x15aeaf7eb3a4076L, + 0x1225fca9834b5b3L, 0x0bed1f86418bdafL, 0x041c53cf628ce68L, + 0x114b88fb88330afL, 0x1c84e08d403b303L, 0x04c0d853fc90f50L, + 0x0ae1ef9712af0a9L, 0x0968b4dfc9ef9f9L, 0x0a5e4f0357dbec7L, + 0x124add6f5fc4ce9L, 0x0e54173d94ae9f4L, 0x016b4a8de15c5aeL }, + { 0x1007d9f904e222eL, 0x19247c37a7084eeL, 0x1a2e3d0a7bb8ccfL, + 0x0b9f8eea31a9329L, 0x0b0f42f12957341L, 0x1a1a8cb73ff51d0L, + 0x1c6831e572df709L, 0x0ab04151ecce23cL, 0x183d95d9c2b874fL, + 0x05b26bc73870b13L, 0x0d4fd62e4a9d0b5L, 0x116288f6bcdb248L, + 0x0cbcf931a032204L, 0x13d7913405d6b98L, 0x0ee4fe5d7134226L, + 0x075dc8c92098370L, 0x1f0a24eba02165bL, 0x032e2473c704662L }, + { 0x01c73cede222c22L, 0x1ec66fe7511da0dL, 0x0c52c850ec195a0L, + 0x1eb3f9d8ee06039L, 0x11204cef284adf8L, 0x19a883fd8e2c0e1L, + 0x02303d534fbba51L, 0x025b7ecfe169a63L, 0x176a3f2d110f18dL, + 0x004fd1403e9f009L, 0x1c2918979fb380eL, 0x0fdb6512ba5de0dL, + 0x0908b0553ad8286L, 0x17922a22f0837a4L, 0x1668f2f88a03e9bL, + 0x1745a805aaf0b51L, 0x06ff63dd9ffd438L, 0x01b5ae6963d3591L }, + { 0x1ff4e20545679a7L, 0x005a0a29063a843L, 0x1fea6d167361936L, + 0x1390b5e3472146aL, 0x0d935a5ea19eaf3L, 0x0d33c506a3aebccL, + 0x1a041d140660de0L, 0x088e9072ef21985L, 0x1c6a21d112f4122L, + 0x08742fc9b528d1bL, 0x00547baa9d37e23L, 0x054f279f3389feaL, + 0x11376a9ab614e18L, 0x0911c4ffa2ac9efL, 0x1117a2863dcf2bdL, + 0x03b91a4f992c1eeL, 0x1d80692f4c539a5L, 0x0046be0a26d9cdfL }, + { 0x09c0d963ecca773L, 0x148c96a4610ab40L, 0x15d36daf59061faL, + 0x0854cf19bfe1d99L, 0x11587b7e7731237L, 0x1852633d4b36c5eL, + 0x05ef7cf06840584L, 0x148f98dd070bf9cL, 0x195e95bb8a8de7aL, + 0x1f0f45ac4c18471L, 0x1c90fb8d1da528fL, 0x18857619a57e032L, + 0x040f9b2b49f3fe9L, 0x039b3e8fdac8293L, 0x1b851ed30e17a2fL, + 0x095b23a60a15d6bL, 0x0028e2c38790400L, 0x02f9554775d5b81L }, + { 0x008d4641266524bL, 0x19c406850cfb371L, 0x017b6841bafedefL, + 0x07cc85ba8d4b54dL, 0x0682e4d60a69e8dL, 0x05a9a6779a4e30eL, + 0x19ee09bdbb8ec3fL, 0x1ecfb57424e0bd6L, 0x12babb27e18be05L, + 0x0cd7e5d4716c2e8L, 0x1cb46b8b674e1a5L, 0x05cc3d4de0dddb9L, + 0x14866e5ae859dc5L, 0x015e69e3e1413c5L, 0x12fa0bf67fc0d00L, + 0x1e449d10958ecf0L, 0x149a316498083c9L, 0x031280d4c5a37fcL }, + { 0x03f7d9aad264086L, 0x119edd2f0725eabL, 0x000a3234f59f29aL, + 0x108dcc9633d04a6L, 0x00aa4536a288dacL, 0x0a9f567d1e48cb9L, + 0x0af4e04c326c3b5L, 0x0eec4500dc05d51L, 0x052fbf54dceccfeL, + 0x0cd4718a7868db8L, 0x1484cf566c5d06fL, 0x003934dfd514a33L, + 0x00b5c4eb10fd741L, 0x08fced2f68d67bdL, 0x17a9619e1266dceL, + 0x0a6355754989381L, 0x065cc9c5f73a1f3L, 0x024bd8aff7e9fe3L }, + { 0x056cbaaf45568e9L, 0x0d07f638c9537c5L, 0x174e6ac94e6bd24L, + 0x109586fb53b7607L, 0x02a0f5b4c86522fL, 0x0e29cfc6466dd10L, + 0x1c0ba0427f1d68aL, 0x17f39a0da639521L, 0x18f31f0443e216dL, + 0x0d534565d1f5ec8L, 0x0343490b001fd26L, 0x1f7f0d536f9c550L, + 0x04d6308edcdd8dfL, 0x03400965202e9f4L, 0x1a841c76be8cff8L, + 0x06fcd85dd7a27dbL, 0x0b7b7ae7e5c2ff6L, 0x00c6a35364f28a6L }, + { 0x08cbb22a78b7802L, 0x0eed924be5d7a43L, 0x1cf90aba2b741d1L, + 0x15699d69c989d65L, 0x0325fd40ac0abcdL, 0x1639a29706c192dL, + 0x1c6e5b3f815c44eL, 0x056e80f4f116282L, 0x070eb06036da7a5L, + 0x1859b7cec28bb56L, 0x0274a5f0a553ceaL, 0x1391b9ae0b5a282L, + 0x0d7bb5e751370deL, 0x103738461f86daeL, 0x04c143517e4f506L, + 0x1fdf221aa9f14fdL, 0x04069e6f8e45a38L, 0x02a822300e9fb17L }, + { 0x1c5c91006cb9cc9L, 0x03a6ba0e8000a68L, 0x18f8448dbee1508L, + 0x1c535abf04f9b0cL, 0x0951fc8339721ffL, 0x068a278e90fdfd1L, + 0x0b9ac73781b9d00L, 0x0cd2084b2d722f2L, 0x03365c8e529ad51L, + 0x1110742cd777f4cL, 0x14c625c30abb8f8L, 0x07b73fe20179796L, + 0x16f532973f477caL, 0x0d15e80d9383a0bL, 0x15e7e4e848462b2L, + 0x1afb7e684a4127bL, 0x04f563a8ff7c6f5L, 0x006d189fe6bd876L }, + { 0x1125a8c15aa2557L, 0x0eb8600449f4e1bL, 0x06519ee2a08f288L, + 0x08f960085490e27L, 0x09e2ce180d3e9a7L, 0x0d75611695fa7feL, + 0x01983554c683412L, 0x0009a534c2de07aL, 0x0473d50d61f1b7fL, + 0x178765de51ef286L, 0x166fa8270a3c9ceL, 0x1d41f0e08cc9c52L, + 0x01731083ef6d7c2L, 0x0a0e12aa56fd727L, 0x058b40d4250309aL, + 0x0521c882ce82142L, 0x0cc620230d81e82L, 0x031b185f46da0a5L }, + { 0x18d52228a7d2e41L, 0x1ac11f5b17c3cdfL, 0x0f75b100b625279L, + 0x0dbc58b35a369a6L, 0x09b9dc38883e04dL, 0x1b86265f9f9c7a2L, + 0x081167665f462d2L, 0x0da3ed36418279dL, 0x1ca3d702558e260L, + 0x0a7ecbb930e8dbcL, 0x1abea16850dbe8fL, 0x1d317688780ead5L, + 0x0ce558f6be369b3L, 0x1c5647c4fe728c3L, 0x196a9cbac3351e3L, + 0x09d60d00e9e6fabL, 0x0ed295845c06854L, 0x018354c38f8b344L }, + { 0x0451e9d634ec136L, 0x193e50737b2c7deL, 0x054b036d04807b7L, + 0x018b7fdccf537c0L, 0x1a2d602387b6ef2L, 0x17dc4c9a94191c4L, + 0x10b79839593631eL, 0x05695e457801593L, 0x128e6f63182a9d2L, + 0x03ae380fa99380dL, 0x1063e2081d7e470L, 0x051a37d54a23edaL, + 0x176e72a13df9fa6L, 0x1bfa600e2a8f3d0L, 0x12756224c18856dL, + 0x0f9a8e3574e6327L, 0x0376443ebe058e5L, 0x01419d620f4081fL }, + { 0x0564b868da5ec5cL, 0x0ced40e046d923fL, 0x1c2e315e9ca2b0fL, + 0x0f3a687b853af83L, 0x1dc603393512afeL, 0x1d0ca0da1c7267fL, + 0x01125f5689c0373L, 0x1cdabe647f04e64L, 0x11b87a58e1393c6L, + 0x05b45e8825d5218L, 0x1071691c8ad35fbL, 0x152e40d6bf55813L, + 0x169976327ef42faL, 0x043bc3ecf0ee5e6L, 0x1700645956ea790L, + 0x06a717ab38eafbcL, 0x103673020ed0bcfL, 0x009066a2a524eb1L }, + { 0x1fdb8f4cab0f9eeL, 0x01f7816672c7775L, 0x01056a341996f00L, + 0x0d372aeee936d4dL, 0x0721ab5c642ed3aL, 0x1278699ef243f82L, + 0x17737bcbfce0086L, 0x1e57a2deab053b7L, 0x12ef05b4b0e93dfL, + 0x10fd50905e4d760L, 0x0b8b0b519fea4b7L, 0x1ec8bd667c68cdbL, + 0x168f0103cb758daL, 0x0df01218533d6cfL, 0x10152f0547da4eaL, + 0x066ddaad3092dd6L, 0x03e8ef1677e7019L, 0x0010e7e8b3fef75L }, + { 0x073715fdf5c36f3L, 0x1ef1beb25692a2eL, 0x1443cb3ddc4dc0eL, + 0x0e1e732790aa6d1L, 0x104ae4ca1e5ec7bL, 0x1dd8c5fed8b3bb1L, + 0x0f568363dc5f8f4L, 0x16aa4ce0e7ecc68L, 0x1faeb52ef156008L, + 0x0bd6afc91252387L, 0x1b8e47b4aad46aeL, 0x1caf32e860595f0L, + 0x17fd0ae28adc0c7L, 0x1fc76ace6447d40L, 0x04a2eda01f08b7eL, + 0x12b46bbdb8463d6L, 0x18e71edcd9ca205L, 0x003932da3639e7bL }, + { 0x1dd99f0bd66232fL, 0x157c4e2013b8b39L, 0x17e96e183f13166L, + 0x14f5287e775f04dL, 0x123c428d239ea8aL, 0x19dcad07070d8d2L, + 0x1d4ed57a838e9a5L, 0x03fd47339544aaeL, 0x0f8adf72f06957bL, + 0x1c4f9a09de9a181L, 0x1c9f43e290ea5c0L, 0x18115b5ef2de667L, + 0x1b49c12aa2cd9c0L, 0x1d056374b6e6524L, 0x110203b76237bb9L, + 0x1e97b1e8eaeba0cL, 0x16c6e9d667d0cc2L, 0x01b62baa598e8a4L }, + { 0x120046ef323d84bL, 0x088913f3c4e27c8L, 0x1d3a486e01569a6L, + 0x1500f32e9c961d5L, 0x140f8c796339844L, 0x16f7a4e482a3353L, + 0x192e8706343df35L, 0x18aa52fb4d69647L, 0x11c09dff3c41800L, + 0x02483ad9bf7b3bbL, 0x10e9014144f7b5bL, 0x05d2d6162e0b529L, + 0x14c48af5ae3d674L, 0x04ac116f603c224L, 0x193653d030054cbL, + 0x0bd6b45bb5bcb82L, 0x04efc8a8ac9a297L, 0x0037dfc308ca34aL }, + { 0x165338e3f45aa97L, 0x1ac640e8207f596L, 0x166c3f7be2e760eL, + 0x15c9ae82f80bfdeL, 0x130a1a237beb071L, 0x12de81cc15b0fadL, + 0x1afcd317ca8abedL, 0x14bc815793ab97eL, 0x0422c326df06612L, + 0x090f34ecab8d714L, 0x02c42c8f4d0d3b2L, 0x12af3b40f266f91L, + 0x013619cf4d96d2eL, 0x0caf77d0c19ea35L, 0x0fa3c3b6746594fL, + 0x0b56254fb082340L, 0x1ea5e64295304bbL, 0x02f4e507e8f87d4L }, + { 0x1d54571197c5dc4L, 0x1205ff3c54ad12dL, 0x1bf3ff6c3acb8b6L, + 0x181a2e8cf8cbf73L, 0x0758c6a3e952dc2L, 0x01a54d60fe4e3deL, + 0x12d5bf1e558b350L, 0x1164dc6df7cc3ecL, 0x06adc4b9e1e8472L, + 0x18b2fe9d47cd645L, 0x04e9140f8f804dfL, 0x0a26cac8f1c6f79L, + 0x17064ddc77eacc5L, 0x1b49b48a699c8b8L, 0x0909299d6cc6371L, + 0x0be68d363e38e6cL, 0x0f88cc2045b4995L, 0x04a031159e341b5L }, + { 0x110ccb70d997973L, 0x0b12ee9fc788aa3L, 0x13556e5eaf54ecaL, + 0x14ce7c294b19e18L, 0x1d262246c6321e0L, 0x041d8882a0d7ce9L, + 0x14a9379b61d51bfL, 0x16c8fd2fb51e02cL, 0x00f82b3a6ad9802L, + 0x0d5203ad74e2259L, 0x1d778b3b4afdddaL, 0x151492f481b55e7L, + 0x083c23ba9c1ef1eL, 0x18c851641707c30L, 0x178cda362a66293L, + 0x17ae3c56939199fL, 0x1b6b9f49824bde6L, 0x0405d8b323c2df6L }, + { 0x1e575fefd145cb5L, 0x172b0d62f344182L, 0x033e1e4ec9cc557L, + 0x1c267646708c3ceL, 0x02a7ba079f1553dL, 0x18437d17dcf061dL, + 0x12e4f0eff5aa0f9L, 0x17b6d750a011769L, 0x10b66d78976f82dL, + 0x0ad37fb2a75a4ffL, 0x1748dc7c82cc89fL, 0x1384a9c539b99acL, + 0x03cb118ff979ea4L, 0x062c0005b24bacbL, 0x031de725a566377L, + 0x0b46b2a20f23022L, 0x150edfc154863b8L, 0x003bdd2f5209091L }, + { 0x13a38d3cdd86f61L, 0x10a228281505585L, 0x171601b409c90c4L, + 0x111465e21e3225dL, 0x0e80c76001dc1f9L, 0x127459dd8e98e88L, + 0x127bb51bb1f97d1L, 0x0efaad35e6d357eL, 0x09d286ea72cdadeL, + 0x1f38106a2d6ac90L, 0x148db98a66b9fcaL, 0x137ba7eab80f57cL, + 0x1a52350e80c9317L, 0x17f83ac3409c4caL, 0x1ce594c24049972L, + 0x0fa42b6790365e8L, 0x0e2baf7581d9bc7L, 0x03590036fa2c8d1L }, + { 0x0fe50a8965b1bc1L, 0x1a9b54b15da7ed9L, 0x14cc0039fe664c7L, + 0x0aa7aa24bdaae31L, 0x12125caf84728f2L, 0x1fb3cf27c530c26L, + 0x1016953c69c04d5L, 0x0eae153e8182a63L, 0x110d0cb976fa8b7L, + 0x03b7a0f4ee09674L, 0x15e9d49d57e252dL, 0x1c20c4ae8348b91L, + 0x18c917b16cd6c12L, 0x1c6b5850131537dL, 0x10e3a0c93445b98L, + 0x115f9092a818065L, 0x150855b911c6686L, 0x02990bf535e935aL }, + { 0x0840473259f52b4L, 0x0d4e5f3108a367eL, 0x017b2b2f49ba5a3L, + 0x1bc94a86892c9d7L, 0x181a4ff7ab7daa2L, 0x040af7b6e1dc241L, + 0x0c78681ea5acd07L, 0x15189f5d3d187a9L, 0x10f938d1e42ce9eL, + 0x193ed661ae60297L, 0x180727a681bc1e9L, 0x1b9694dacb43903L, + 0x136044a9a6a9e08L, 0x195e94adfc7168bL, 0x1e06c4a6624f743L, + 0x01585411a66f3f2L, 0x0ef64bd60016183L, 0x001c3498f6cd6dfL }, + { 0x0d7abb3d09885a5L, 0x095b3f1aadd83e8L, 0x033d4dbaebb7b67L, + 0x10d339c9ac77847L, 0x111594cd61ca2e7L, 0x18b5691aa7fa238L, + 0x1d711572f9c240cL, 0x080830cf3fa93ffL, 0x075bacd750f9c6cL, + 0x1bf6e4414b9390dL, 0x05a21f97bd40bd9L, 0x06cf7e641c1d04bL, + 0x0f8bbdccb2459e9L, 0x1bb3431ec0e71b7L, 0x031b6e06e825ff2L, + 0x0e9179a7443adabL, 0x0200e4967cdb4a8L, 0x016557ba48a820eL }, + { 0x0f980066ed20424L, 0x0751191238aa2a2L, 0x0695e06a321acf9L, + 0x0af5cb6e164d1daL, 0x156d398248d0ab7L, 0x198fd2365459901L, + 0x173ca73a39a04b7L, 0x1bd7213a465b24bL, 0x1302c8f78f56723L, + 0x0b92eb4d5d64b7cL, 0x091f295f4685c04L, 0x0a23831457cecadL, + 0x11ad50d9d96bb5dL, 0x18582a8c5ab722fL, 0x163fe44dba21b89L, + 0x06c3d8f8e3e7a13L, 0x1d865a1bbe29350L, 0x0436bfa9922ff1dL }, + { 0x1f16eb6b0bf719aL, 0x1a84c45e1ec89ccL, 0x19489b3406d2da5L, + 0x0921131a39f5ca1L, 0x087ec666d3e3ac5L, 0x1522dc26d1dcedcL, + 0x0c16160c01913efL, 0x0266d3e77b306abL, 0x10fb239a8579bccL, + 0x1ada29cb715ec08L, 0x1ceebc90663f493L, 0x0db7106faa3a00fL, + 0x02eae75b1668a67L, 0x1edb041e3477753L, 0x00db1697ff97e50L, + 0x1ff0aa5929a1efbL, 0x0dd5a4c3c6fcbc1L, 0x034152af1c3605aL }, + { 0x0f235a4587495aaL, 0x101361a63922ee4L, 0x1316dd691b8c89dL, + 0x0bd987cbcfad5c1L, 0x14296629890d396L, 0x03b9138d899a178L, + 0x09a2f22649f9a2aL, 0x0342a87e4fc4649L, 0x06c44768449cdc2L, + 0x1e3fea78a296856L, 0x0c28c7fd2c11726L, 0x0d410a5eec22598L, + 0x12c6fdd7a6415d4L, 0x1da63e48d6b9b82L, 0x0235c3373b30eadL, + 0x0720ba59be036edL, 0x1cd054f2542e40dL, 0x001113fd37f7f26L }, + { 0x005efd9b751948bL, 0x176a37efe912e8cL, 0x18253cb22c8a3bfL, + 0x1f2def8bcb96251L, 0x14cbeca09d1090bL, 0x04658204ace8225L, + 0x13f38872557e638L, 0x135783e4f3ad1f4L, 0x0b021e14e0710aeL, + 0x068b74fc408b3faL, 0x1708baef27c6959L, 0x0dbfc6841dd5eb4L, + 0x15d5c4e8435f371L, 0x147fdd40cb8f5c8L, 0x14dd5e193f157f0L, + 0x18fa0684fca9afbL, 0x178446e6a6215ebL, 0x02a3f124d14934bL }, + { 0x106868aa1ffda27L, 0x166e63caae7a823L, 0x0784298fcf62d39L, + 0x153bcbce15eca2aL, 0x193428235b4127eL, 0x17bea89e9604dd7L, + 0x100946326760ea8L, 0x19d418b763bbbddL, 0x07ffddf8403dcf1L, + 0x0bf2694b0b7ef6dL, 0x1595a5e4ca87c39L, 0x01d06323a9c7a48L, + 0x01c220218b7475eL, 0x05e592829a3cdf5L, 0x184cb9bf3ad7242L, + 0x183d638d0b9d478L, 0x0eac42dc745bfe6L, 0x022d20e60695847L }, + { 0x0a9b2c74dbbf0e1L, 0x1cb17d0be7b871fL, 0x1d617bad319907fL, + 0x05537d62fdb83d4L, 0x0285741a4f5412dL, 0x07e88f964f27a95L, + 0x0613a4f7df69261L, 0x0eb655f7bb81be6L, 0x096323d252421e3L, + 0x03df0f224efbc0fL, 0x1807b4f5626fab2L, 0x137a51ffedba28aL, + 0x148a0f298c0f0bdL, 0x0c4734a216992ceL, 0x0b0abd8d8b5e9dfL, + 0x1b40550980d6d6dL, 0x0c8ba850ac9d087L, 0x00943b1e4a17720L }, + { 0x1a80f07acbac178L, 0x100221a5847b714L, 0x1451c3fb7b49f30L, + 0x070cc2aecfd2c63L, 0x0b088548b2115daL, 0x174701be3afae26L, + 0x05d496ca7484e68L, 0x179fd3fb4cd1710L, 0x13f1d8d88c1de7eL, + 0x03b2b2f0190c091L, 0x195586c72657cedL, 0x1631627d6e360e6L, + 0x1399b3a0eb2160cL, 0x1907e6ba3f46d28L, 0x049b5c97a3287e6L, + 0x0c6fed4fc00cf68L, 0x0d21e8204b768bbL, 0x03af4b5e67e27baL }, + { 0x09d1fdc0d19716eL, 0x0282c3e1c22928cL, 0x1b47aa61f4ab7d6L, + 0x06d80e2a1ec9508L, 0x0d6fd5b712b6bf8L, 0x09faafc8ec2ea32L, + 0x044a6a5e220d93dL, 0x090c01077b102a1L, 0x1a7672683ea876fL, + 0x005973d60ad9244L, 0x1be3490b47664baL, 0x00539e7bc92530bL, + 0x1cb14876279c57bL, 0x0572db43ff017c1L, 0x1ae065abae93f92L, + 0x0a47b150de136baL, 0x149d88f566ba16eL, 0x0184d374d5d1344L }, + { 0x127ee50bdfbe97aL, 0x1f387dc628626f7L, 0x0c05ff827d70697L, + 0x0b7da6d98b98f7dL, 0x1550ed3a8fa15a8L, 0x084340e061d66dbL, + 0x1732f1607be1faeL, 0x1d142b666c5893aL, 0x00fbb17141fa264L, + 0x13fc6c7c70f7744L, 0x133f58870ad8f49L, 0x1cfaa77cfdfba63L, + 0x1fdb2a358a924dbL, 0x1aeb4560ea1743bL, 0x13fa9573e59cf1dL, + 0x16405c6b2f1fae2L, 0x189eeb366535769L, 0x0022c12c56bac9bL }, + { 0x1f71a74a042dbdfL, 0x02c2babbcefd12eL, 0x0e9c34b9995cb50L, + 0x0b945d125c1ccd9L, 0x0f0e6b5f285d674L, 0x03b3e1fab546f78L, + 0x1ae7383ba14768cL, 0x0853180acb08668L, 0x0b35fce26d6b3c7L, + 0x044adff9cbbbf00L, 0x03da9b9edb621b0L, 0x10869e052097079L, + 0x1b2e84ec34bee14L, 0x0b6884c8bfba48aL, 0x07eb302eabd98f2L, + 0x1805200970eafc8L, 0x158a2b880e56f86L, 0x029fa51f04adbb9L }, + { 0x1bb08ce89fc48e7L, 0x062bbd7d5ad7588L, 0x0fe283072d6ae98L, + 0x14f2eaf96de0d79L, 0x163191607d2efaeL, 0x1bdbd4f136c858bL, + 0x1cafd0aa86ad8adL, 0x1e071dd819a50bbL, 0x1d35947f5f3a8f7L, + 0x1e46e077e0e5adaL, 0x0332831161173e5L, 0x1312493c4de5fd7L, + 0x0d483ed89a16e8dL, 0x08ec8839be13273L, 0x17a67c04e8fc515L, + 0x1aac70a02ac5c60L, 0x036aaf98d746908L, 0x0054cf329eb91e9L }, + { 0x1536f46abbc0559L, 0x1833dcd50d0b011L, 0x08a4305a06d7058L, + 0x0226f1d20e453faL, 0x0b793a2d61254beL, 0x12a96de307fabd5L, + 0x028da9bcb7e2d19L, 0x13535a63127182eL, 0x1c5cd9abe29b74dL, + 0x1ba3939fbc24291L, 0x1aa4e83438c18f3L, 0x03c68491c7b1824L, + 0x0e8323ddfafe202L, 0x19931cf3ecb9a1fL, 0x0c955227dda1dd4L, + 0x1efd52ca1f862eaL, 0x1c0b595dbd13eebL, 0x01d4ae5a28087e5L }, + { 0x14e68cb39d7ff2eL, 0x0e5a5e0eae247caL, 0x11ddc5a50e2a374L, + 0x012395b19c05525L, 0x12cd08d27965c0bL, 0x0815ed062bcc559L, + 0x14860696f0f0e9aL, 0x1b6a8ba124aa30dL, 0x0f0077cdbd27e64L, + 0x0abe5524668496dL, 0x1e8e80914caacc0L, 0x073683995746545L, + 0x014744aee6a5fb6L, 0x06dd49ed00b816eL, 0x05e13c5216ed0dbL, + 0x0e58726b2fecc65L, 0x0455d713c1ddad6L, 0x01b3691170185b9L }, + { 0x10b4875573ea5b2L, 0x1200dd486d226eaL, 0x0995e8680c403f3L, + 0x0b9e2288c0f6a7fL, 0x0538bf49722a80aL, 0x15669085c75f82dL, + 0x141f6b850451f4cL, 0x00ecd24e258f6b5L, 0x06dc5fee73f48caL, + 0x0768a4c95c53c6cL, 0x0cc51774bc5d666L, 0x1bc2bf2e371c9d1L, + 0x1dadf1b36843408L, 0x12c995bf02af536L, 0x0224ff52eddb9cfL, + 0x17fb48850e2a7a6L, 0x125173dccd20661L, 0x048395d4cbcef7eL }, + { 0x14de4dd9620ea39L, 0x0b24fe418e77423L, 0x0ec734ea710fefcL, + 0x1e7e7be3aa161d1L, 0x0f0ec9b36a38286L, 0x0e04f1a7683959cL, + 0x0890a9b93261dcaL, 0x175d47d158d15a2L, 0x06ae0e22bfbdfa5L, + 0x10b8f67d8507ac9L, 0x0a21b5ae1c7e355L, 0x1d526bc237b4676L, + 0x007f0f153f6b19bL, 0x1eb6017726c0ad2L, 0x0a23d19f982365dL, + 0x02ca8fd1e47b36dL, 0x02926ac9652439dL, 0x046c9635e9aaa36L }, + { 0x1e0d7ceabeb0ff7L, 0x1a92a1f07217c59L, 0x089b7a021267ef8L, + 0x1e39a89786afa36L, 0x035cfee19ece2e1L, 0x1fac0e0922d6de2L, + 0x0e51e1d3ba103e4L, 0x01522d4ef397b41L, 0x0abcc815afa57aeL, + 0x1d6f616f85310d8L, 0x0940ae07e42f725L, 0x1bc2a77bcc7b7cdL, + 0x1f78884c2554bf9L, 0x05ddaa385447ed5L, 0x014fbd4c2a94ac7L, + 0x04fd5f00a72d852L, 0x1c08d43d8988dd8L, 0x02725f60bae0d72L }, + { 0x18483a2fcc09676L, 0x0251f8cf54d4a5fL, 0x1bcf5c0a977515fL, + 0x05087fcfb14d0a5L, 0x16e35158e7915fdL, 0x0ba3783225dd4c0L, + 0x1c2d6346e57427bL, 0x0bc8ee08b037215L, 0x10bd4bc6bd4fd13L, + 0x16e7033da7419d2L, 0x1a3cc3fd5aa6869L, 0x1001d858c7fc581L, + 0x0598f508a8a9c80L, 0x1949409d224e105L, 0x1fa06880ae532ccL, + 0x0eceec8fc7a51d8L, 0x12472e67d1ab487L, 0x03d2551fab7cef6L }, + { 0x19ef1bae27a0045L, 0x096a7d92165a82aL, 0x0390e73e3493720L, + 0x0b367f38a84748fL, 0x0ffa1fcf97544fcL, 0x11641dad6340995L, + 0x12eddd3e3fb80d2L, 0x14d2d98c81f9a7eL, 0x0775dce9db0512eL, + 0x1ee50cee6e71c0fL, 0x1acfcea74ff9559L, 0x1e8434324e9f83dL, + 0x1428d69b1238e0bL, 0x0fe84efc0acc97dL, 0x06ad77d23f3af7aL, + 0x0d38bb93bf49f68L, 0x1e10cbd7dc8c0a2L, 0x03014153dfbf856L }, + { 0x007e538dceea2e7L, 0x191641e21030ebeL, 0x03e53c7d9458e28L, + 0x178eeed420ced05L, 0x15e6b405f21b69fL, 0x13db21631d1a0bdL, + 0x051013267c96246L, 0x19a70d25950595aL, 0x0f1e82ffe00869bL, + 0x185b8a70b7f2335L, 0x1d0be4640644e30L, 0x0da01f4a2d5cbf6L, + 0x0cd8c73a43e9016L, 0x1de2e1b92aa87bdL, 0x130e7b4b5a901f7L, + 0x17ce1c8f4ea72d1L, 0x1423fd286d94a5fL, 0x02fa574e391e35cL }, + { 0x16a2dda53f4d561L, 0x0a2e80b6d0cc96cL, 0x07eff752c144a1bL, + 0x1b3e432bd489340L, 0x037661b325488a0L, 0x12f701620a8d855L, + 0x0205ee6311c7be7L, 0x015497950dd50cbL, 0x1bbcadb877a68fcL, + 0x059a324b5b9b354L, 0x1a6350559870b62L, 0x098d9202841865dL, + 0x152f2752aff5b3bL, 0x088726ce511a939L, 0x092aa00bd9339cdL, + 0x14a072734fe4d59L, 0x1d29cd3e291401aL, 0x049500a11ee2357L }, + { 0x1f24be11c2f7dbdL, 0x04807dbea93fd74L, 0x16ee1923c4a36a3L, + 0x04902832832c7c4L, 0x1a6756fb9ab713eL, 0x06c85ef43fbe80bL, + 0x1aaf49d37617816L, 0x12b047fdcf504acL, 0x09f6230d7742401L, + 0x02bcf96565af237L, 0x09898c5a9321f81L, 0x1487b33610ae544L, + 0x03e488789e9ca19L, 0x0a0361dec36e15dL, 0x18255fbe582d6e6L, + 0x0a2b6de58851712L, 0x19b90748706161cL, 0x007e47f0f554465L }, + { 0x0ae1bedfeb90f2dL, 0x1dd9e52458aacb4L, 0x1e73d93a58d7ce4L, + 0x01f17ceb8457cc5L, 0x1e6f7529354c241L, 0x165598debf5381aL, + 0x1cfff09921a3858L, 0x0fd62723ce190c1L, 0x1df367c751d8983L, + 0x0a85b5a15f994a0L, 0x03d1b9e304c63f8L, 0x1b57458962c12bdL, + 0x0e701afbf32b3f1L, 0x0f443a62e3667aeL, 0x11b72f8eb49d4c1L, + 0x125ba7250bca2bbL, 0x09f3c954d86d998L, 0x01685d4316fe9bcL }, + { 0x0cd8ee8b472e1afL, 0x0a7575bb55de675L, 0x0fe34364fef7acdL, + 0x0ffcdf8e0d36a41L, 0x04ee2f39fccd60dL, 0x00f28f549a9eef5L, + 0x19ddd7ac2497a6aL, 0x0d3dc669b43a26cL, 0x0c1d28c9fd5354dL, + 0x0bb8baac952f6aaL, 0x18d9fedfdc3606eL, 0x1d9552675cf4ba7L, + 0x19e23cfbb77be7eL, 0x04a4bb40932678fL, 0x0d88d6c344a7d2aL, + 0x0edb4e0a6eb4813L, 0x1fcccf64c7548a3L, 0x04b1e438926a0edL }, + { 0x0e290cbde36a814L, 0x180cab99d895addL, 0x019fddff83866f6L, + 0x1a52e419d41d75bL, 0x1029ec720a7d19fL, 0x08c88f21a6bb28cL, + 0x1fd8215abfc5eedL, 0x00da144bb35b014L, 0x0ffca86aff848c1L, + 0x1f45efca1d6ba4eL, 0x180a138f9a5aed4L, 0x0615dddc842bf73L, + 0x1e2ecf3c633eb66L, 0x070060604ec7ddcL, 0x15efab1c7693fe9L, + 0x18fdf652d7cb2baL, 0x1bd1751fbada8ceL, 0x01681f59e7faaebL }, + { 0x116925f04f2ec1dL, 0x0793b068a3f7175L, 0x1812ab676782a1eL, + 0x167ee206b6885beL, 0x0cb95d5b891df44L, 0x147691e1413959cL, + 0x1cf8dbc53bed57bL, 0x0bde7888c1e2761L, 0x0889f9bd76bd733L, + 0x04f73b8fbaadd37L, 0x0613fbb4866db22L, 0x0e6fd85dc822c4dL, + 0x0263efcd372d44cL, 0x131bc135dca1c2dL, 0x19ade9f6424c86dL, + 0x0c36f849f14f27dL, 0x0d9a3ca8d24a7cfL, 0x042172060e2a5d6L }, + { 0x0268ed6a661d843L, 0x1466527ad9866adL, 0x1b444c4785dc08cL, + 0x098cd2b2ce2dcdfL, 0x17b2e280690decbL, 0x1f21685ed62dfb2L, + 0x128be09fe0b287bL, 0x00d8aa9d81594bfL, 0x1ac5276c1dde455L, + 0x1fa65847183ba89L, 0x1db66b321e5f32dL, 0x10281b2665a5195L, + 0x17285a409fd5964L, 0x1111e849e635714L, 0x0a3f025ddcf0a95L, + 0x1fcd85aa4cd58a2L, 0x128a596b7cbbc31L, 0x0073198cd656489L }, + { 0x1cd2fadf0360ac2L, 0x1306f142f302d5aL, 0x1c43896e6c521adL, + 0x1b55358aa9058d9L, 0x126c070e9d5fa38L, 0x0662969efe78dc2L, + 0x11fd40de6a5acffL, 0x143c6cb385217f9L, 0x15b1a3db569d3e6L, + 0x00a945acdbda16aL, 0x17be92708a801adL, 0x00313699c76d269L, + 0x04b3abaf3290f38L, 0x1fc1c4f15839de0L, 0x0968d6c9e96888bL, + 0x14f8416f53aa3ffL, 0x05a4939ecef28e1L, 0x04441ced10c3938L }, + { 0x0b66c30701ce29aL, 0x178932c4c0ea82bL, 0x1030417e7c84eb2L, + 0x0c6e7c7a27a9b5fL, 0x1a2ee3cafee571eL, 0x101c2d73934e437L, + 0x1a6b3d732992b74L, 0x1de42fe4eae6001L, 0x0c934db470e7273L, + 0x14a7a7b9aadb3bbL, 0x08dae5bf0146010L, 0x03b760a432163f5L, + 0x10e9eaef528f88bL, 0x0db40dc81abc8dcL, 0x0570da7cdfecbafL, + 0x0439273a14a3a88L, 0x026fc59cca71d2eL, 0x03209467f50fa86L }, + { 0x03678a2e8f5b0b5L, 0x1124e69a0782cf8L, 0x11064f29f3b171fL, + 0x0d79075f3082880L, 0x1aa8bbb0075ca34L, 0x01187bf9cf8019fL, + 0x1cd14f463c3b7ceL, 0x0eaf1bfe019a891L, 0x1849228c0d51aa4L, + 0x0a7138418649468L, 0x0e9a1a3c4b3f4f7L, 0x13b71167440d8cdL, + 0x19016dae0109104L, 0x1129f1beec32e82L, 0x1a61c6d1667a417L, + 0x0265c6459e184f9L, 0x1da014f54da174aL, 0x049b1a504ded5e5L }, + { 0x0826b27a9a2e304L, 0x10c3360d2609231L, 0x00c888e05c4315fL, + 0x0b5308f9fd22757L, 0x0b5f46fd7e9b6b8L, 0x1c733694b2ae789L, + 0x17aadca555cae00L, 0x103c9974c02df52L, 0x0bbc11071b9dedaL, + 0x1f8004d1f8e7b0fL, 0x09ddecdcf833ee5L, 0x0139a273ac76a6eL, + 0x1a4f87d78e302f9L, 0x1a0243b18f6b396L, 0x1308ac8d881de8eL, + 0x1ddcf8811865b3bL, 0x17e4b4c5bf226deL, 0x013365a33de031aL }, + { 0x1aa4154b56363e8L, 0x1e83c1e0d526db7L, 0x1778ae79965d2d3L, + 0x1df4009708286b1L, 0x119911a65b34ae3L, 0x1b5fbc67a259767L, + 0x17255572aa0ce94L, 0x03ac0dc3d7310e1L, 0x0e3c3287d09f351L, + 0x0597a75ceae79b2L, 0x13a2498eae3279aL, 0x051d86d56c2382aL, + 0x0ba1b7d12015488L, 0x098adc6b84995feL, 0x11ceb05fb9ed6f1L, + 0x055e6f05fa1a3eeL, 0x0e1bcb029a83c8fL, 0x0258ead0da922a7L }, + { 0x0fe517463d52c0cL, 0x0a92f0c4604ce89L, 0x158cd838e558dcdL, + 0x1559f4b486b8c42L, 0x197e810788b3f1cL, 0x0f040548091d053L, + 0x16b6ae8c7dad6c5L, 0x191afbcbc25f947L, 0x03287361b0df511L, + 0x064006a32babea7L, 0x043cf5481fb245fL, 0x0de261dd41c6210L, + 0x133ea5a2ec0d4e5L, 0x1f355de85dfbf70L, 0x02fd865bf01dd8aL, + 0x1a8559063fb9c24L, 0x127e07439fab622L, 0x040c35c9fa84725L }, + { 0x019d15409312867L, 0x01602dfd7beda63L, 0x19a07d7d7769f81L, + 0x0f49f87b05839e2L, 0x0e68b8fe50aa505L, 0x1a6b22769876b2eL, + 0x0125fb2c0702efaL, 0x038f6bb88890638L, 0x1351e6a009b7d9bL, + 0x1dc31dceca3be48L, 0x196244175044292L, 0x19e886b016f5574L, + 0x1690be357e30086L, 0x13da90a7589ce03L, 0x10ead5c4afffc68L, + 0x137f4f39f8dae45L, 0x12a4743de57f34aL, 0x005fcbf4be4f715L }, + { 0x0ec4ec8dda19e96L, 0x10c7536183745cbL, 0x04ad97da4629533L, + 0x161b341b32fd06cL, 0x02fdcc091ac6f68L, 0x1e1f09cc534bd23L, + 0x05cc1973897c656L, 0x00c312dd9b56727L, 0x19eb81a0f32f128L, + 0x1eba0b70e96e3efL, 0x11e5dab51cd6674L, 0x15353ebde873c45L, + 0x0b9e69d94e3de37L, 0x054e85e435bd605L, 0x1dbc4839afea780L, + 0x1847eaed50e1aacL, 0x0bb3bd91bb4feaaL, 0x047f2a4161f2055L }, + { 0x1ae67c2ce9a4d1eL, 0x15c01a78e901c42L, 0x1ce89741864930fL, + 0x1a611f6838b8d91L, 0x071c294e803de0aL, 0x17586d4cb0fade7L, + 0x1a2db71881e37c0L, 0x11f90fdea2b6c95L, 0x169679f1e50b4d1L, + 0x0e004d0a90ccfa1L, 0x1212f83d90297f1L, 0x176247b56acd4faL, + 0x0c64275d2c4c918L, 0x05696f6b533e08aL, 0x12d723656a44ee7L, + 0x077ec313da316d6L, 0x03f4aeb6206b42dL, 0x01c946334dde45eL }, + { 0x04bea4adacb4b64L, 0x115227930bcd0efL, 0x0539ea444a900fdL, + 0x1ba6de663de7559L, 0x007b85c490448fbL, 0x10dbbda130215e2L, + 0x1a6116b62965884L, 0x01a62ce949ecf9dL, 0x17fae8bbe4e3b2fL, + 0x00efb6ed3e49875L, 0x1bea6309674351aL, 0x13cd7d4383fb5bdL, + 0x0b21d405d11b14dL, 0x19c493aa1dd56e4L, 0x1c73793c077fe4dL, + 0x1a1b30386b67de0L, 0x0f61704d2e19150L, 0x0366644479aa89aL }, + { 0x0d36f0e7ad7504cL, 0x1932ffbcaceeefcL, 0x1b7bfb799eaaf28L, + 0x1d75d7e65e1b9a3L, 0x014edcfc1276f4cL, 0x16c75bb412d3730L, + 0x138782e306a0a66L, 0x034624049521371L, 0x0cb8fd98b9cbd35L, + 0x04209bc7d58f45fL, 0x143d74e5cf2b3e9L, 0x09084b3aa4a82fdL, + 0x0374b91393a17e1L, 0x0d651e74a9eadc2L, 0x103e0563de4ac84L, + 0x1af7a06bfe22191L, 0x0f96afa6357ad4eL, 0x0178a8cc05937d7L }, + { 0x08631da29d2d439L, 0x1dde15e01ccaa86L, 0x1e49b016dd6c487L, + 0x016d9c8fd87cb52L, 0x1d88c6586d6cf4cL, 0x1aad0bdd550bb3cL, + 0x16a140c76e79fccL, 0x1bf0703c7b015deL, 0x1c71db29015a31bL, + 0x1c7b5ba4a4c7ebeL, 0x17cfe44efbbbd98L, 0x04e3e956cf6689dL, + 0x10fd22df11e6173L, 0x102e27491d10163L, 0x1ae6483def80e24L, + 0x095543843210b51L, 0x1656c805ce8beb5L, 0x01aa582db8562c6L }, + { 0x171e2367a9170e9L, 0x16216a656a866b8L, 0x093cf37733ec07bL, + 0x074cd95c35ff7d0L, 0x165c7d01a73e8ceL, 0x1ecb8f5b89c53fcL, + 0x09cac001638fd70L, 0x0dea4b235865fe1L, 0x0a32fb5bcbbbce7L, + 0x1920d5c54fc0d0cL, 0x14cccbb29a18c3cL, 0x13f88905e277e63L, + 0x17a4681be2847afL, 0x12af7e7cb0cb710L, 0x0b31c1664e3e4cbL, + 0x1f5847cfb5970e1L, 0x1a1d41be893cf09L, 0x0246e2ae2571a91L }, + { 0x0623826a5092193L, 0x161b1344c4b8647L, 0x1abc9727ad0791bL, + 0x01078fa48a5e26aL, 0x17d00e384178064L, 0x090a8e4c16f7b3cL, + 0x021a4e0badb9e94L, 0x0042a9c20ef15ebL, 0x0187070758a51cfL, + 0x0f5d4fbb8989e2cL, 0x1ee5cee85564133L, 0x1e963a1af674bacL, + 0x118b8af2cd851c9L, 0x0c35c6b10cf94ebL, 0x0ee70cf2e5333feL, + 0x118d10e4bc49772L, 0x021405ce4c566e3L, 0x02fb5476e85b6e0L }, + { 0x1704ca58f9a8690L, 0x14bb317bb5203c1L, 0x1631a48040a0fcdL, + 0x0d79c7499ff7825L, 0x04aab26d4cd58f1L, 0x122bd43c0233250L, + 0x05e500173eee93aL, 0x072a6f2a367714bL, 0x14ca2b9e44fe1f7L, + 0x0214566ef992bcbL, 0x168d083a890f6f9L, 0x0c57e879c03cc91L, + 0x01f27db490cce65L, 0x05fdbe784207821L, 0x01e5f4c55b32dc2L, + 0x029773666901ab5L, 0x1ac2e12e07a9eb8L, 0x00e532839653fc3L }, + { 0x1b321cf2b9d25a0L, 0x1fee52053a36dfdL, 0x0c39678da2d59abL, + 0x08fb000d1f8382aL, 0x1647dd6856ed1eaL, 0x1bc6d44dba6c7f2L, + 0x0ce44765ad41e26L, 0x0be736ea487177cL, 0x0ef8d443e0d858cL, + 0x0e96da4cb23551aL, 0x14ef47999d50f13L, 0x0180d130130aff5L, + 0x1249facabad0d71L, 0x0a7cd0c94fbd7f9L, 0x0cc1e841577b070L, + 0x1fec9594cc7323fL, 0x0eeac44fd9135ffL, 0x0231657db65d69eL }, + { 0x060a647de3237ddL, 0x19ae6415c3a020bL, 0x1d6777e957e257dL, + 0x1ce4d72295ef0f3L, 0x1c93e29815ef043L, 0x18c1988c3a9c9e8L, + 0x084ae868af9d1bbL, 0x0fe9cfd1bf84b53L, 0x1dfefc97da9c391L, + 0x043ae8185175f20L, 0x1748d69ccb4732fL, 0x0ffdb3754da61eeL, + 0x0b65f4857606feeL, 0x089fc1e0553c27dL, 0x03e744c8c557889L, + 0x1d5fba5f6ee307dL, 0x0082a291503b546L, 0x00949e4c6366c9bL }, + { 0x078125149d53b77L, 0x1a01ecb757d63b9L, 0x1f6d28dadc469aaL, + 0x110fcee3836faf8L, 0x13b375228238c70L, 0x03a986a4afb55f9L, + 0x0446ac2c0a27232L, 0x13d9507970dcef6L, 0x1be1c0fb8a1bd18L, + 0x067d97d8d74ebe3L, 0x108f1525030fa16L, 0x1c82e95b220fa0bL, + 0x05064e714216e79L, 0x1efeb0a7d0523f8L, 0x11a622f1a4a7353L, + 0x11f63db64b09872L, 0x0ba73e4b5f3e46fL, 0x029dbcd50b4754aL }, + { 0x16fafce44bbb6a1L, 0x0ddd033c10b9410L, 0x0cc2a7764e6b4e9L, + 0x1be33df5fdde3c9L, 0x1b4ec014022eaf3L, 0x16339c7f6ad5e73L, + 0x02689925a3b9944L, 0x00a462330d253fdL, 0x00d539d8d47397cL, + 0x0005e2a11a2cb62L, 0x01fd614d1984759L, 0x120793abb41f725L, + 0x17c83af2a804099L, 0x1940a8f0f2f7a4cL, 0x10044132277006cL, + 0x0593a2a1f6952b0L, 0x03340a6f7d5f387L, 0x041486b68ab6174L }, + { 0x04637c6d8546946L, 0x1a51cb4f62bfd7cL, 0x06935e2401fb684L, + 0x1c1b8f7013a846bL, 0x0d6784a9b42557fL, 0x056daff31572969L, + 0x1f29689c532982fL, 0x02398411bcc6755L, 0x02380ed5ced9678L, + 0x135aaf4ed990b30L, 0x0b40b299d48d69bL, 0x1df3667f41c237dL, + 0x06f06a2a0851cc6L, 0x1623d9e7fe911f1L, 0x0aa613803cccb87L, + 0x05c288b3e52f741L, 0x1b06fa1d969ee95L, 0x0283778d59827d5L }, + { 0x1b4eb2735bff163L, 0x05cb7f54fd4c208L, 0x0cfe77ac9f39c4cL, + 0x0b3ba387aacd59dL, 0x073075aaa2daf1aL, 0x038dac7a84853f5L, + 0x0b670da9abce78cL, 0x02d451ac67bbee7L, 0x0dd354cacbdc89aL, + 0x1f51a11ea6e5e1eL, 0x11d348de764b477L, 0x0adf1ddacecadddL, + 0x03fa8feb1fe14a4L, 0x1cc7e5e3fd5f3baL, 0x069c1b8501333e2L, + 0x18cf0d99a5f7feeL, 0x144daaf3fdb4d85L, 0x020adbedf8a9001L }, + { 0x10105867d8377a7L, 0x11eb465c019394bL, 0x0a27c0e930c81a2L, + 0x1b2791e521facfaL, 0x09e5a2b84bc7095L, 0x15cf9db897d09e7L, + 0x1530bf1ab1b183fL, 0x00219b46db2dc1cL, 0x14549975186320aL, + 0x098c648cbf80788L, 0x1130ff9a4d9423eL, 0x1df30be0d15403bL, + 0x10a2b5511c769a2L, 0x1a0917029a91677L, 0x1d750fc01a597b6L, + 0x03ab3f9c1f5f982L, 0x19d525dc9bdec83L, 0x00f618a78d7ac43L }, + { 0x063feef2c8310c2L, 0x10a6d22bf1fba03L, 0x03f394d1a21ea9fL, + 0x1ec6fd858a72562L, 0x1542f8dfcde4a38L, 0x0f0b88a83b99905L, + 0x06f18d04c0be7dfL, 0x0de031638c75c97L, 0x0f001c46edd2f9eL, + 0x1dd854b937667d0L, 0x06e675dd1b831f4L, 0x0defeb0eb5d9526L, + 0x1c96939c82e0c8bL, 0x1ef2d3325d9978bL, 0x0afe9add944d748L, + 0x00bbce326d968a5L, 0x188ad5cc08f2dc1L, 0x00bf48e893fffabL }, + { 0x092ced3b7e051caL, 0x06a7e8ce3bb6a5fL, 0x0d480219e12f191L, + 0x0f9d3ad66391569L, 0x1289e9c73ea6622L, 0x150cf71ca924d1eL, + 0x16bb15142799744L, 0x01d4f7a8d25186cL, 0x1354997e477963eL, + 0x0bb2cabdaccb996L, 0x012bae47528ed83L, 0x1d483bd67c5132bL, + 0x0d572571df6e653L, 0x18c570fce53e4c7L, 0x1dee5fbcc068e3eL, + 0x141aa2c53ef84c7L, 0x001df242282afc4L, 0x008c79da59eee86L }, + { 0x0a0a0a87ad4762bL, 0x1c26d462c68babaL, 0x058133ddb6186bbL, + 0x0cfcc1b3162dfe9L, 0x1ecc1dbac0be878L, 0x0b0a3d41b1bffd9L, + 0x11b970912982577L, 0x00b47c2f068b610L, 0x1735eb686e77a4cL, + 0x1e0c5a7efbac34aL, 0x06342c6f7f94bd6L, 0x181a00e2b7422acL, + 0x1ac2dd617f878ecL, 0x10db0b880edede8L, 0x1d64f08874ad8c4L, + 0x0e048459d14f289L, 0x1273b9b536a44f1L, 0x000e8533e4681f3L }, + { 0x19642361e46533cL, 0x1bcc87dc461573dL, 0x145a90b12863a51L, + 0x1bb078f48a0336bL, 0x0cb663e37135e81L, 0x1606b1ba534deeaL, + 0x03699ed9fb36f9dL, 0x01407aa8a4223cdL, 0x1596cceb5d2e865L, + 0x0ab96fe95781d9bL, 0x192e87eaf5654b3L, 0x08ad69db0ad2a46L, + 0x12c950d5d47f47dL, 0x043717c22d6c5abL, 0x1aec1132b74b7e9L, + 0x011cdbaa4f6878aL, 0x00fc9adba24997cL, 0x00db12d833ed319L }, + { 0x0dfaa7b4fd8446dL, 0x19780d7b7f5f5a2L, 0x0e23fa20e2d7006L, + 0x1f7752eb177e888L, 0x07156bc9f33c434L, 0x0484c595cb8e5d4L, + 0x11775ac9179707dL, 0x1af0fb96a685683L, 0x0db1f80c634d852L, + 0x0b7192c1219ed1aL, 0x008194fdf7c309bL, 0x0cf86c1966cbecdL, + 0x029826656ac4ca5L, 0x1f834bb4190fd56L, 0x01d98e44fd729beL, + 0x0e6dc2a72f2434eL, 0x08dbdf143288400L, 0x0199f654b0cfe4aL }, + { 0x1337948ac775d81L, 0x128c7ea0edde511L, 0x093ef3f3a520e30L, + 0x0ca8e07fcec478fL, 0x13fb3b5baad3623L, 0x0e00f8159d09d20L, + 0x0598576cd5969fdL, 0x123ae4811b8a46bL, 0x15a17f8e51d616eL, + 0x060b775e592dcccL, 0x1a33c4ce4dd0fa4L, 0x0e95ca96c94fe6bL, + 0x0a65cd449d987daL, 0x1bf3d8aeaabd991L, 0x1344d3dd9420a94L, + 0x00e8c9a4b8e85e5L, 0x135ae9d9c074ccfL, 0x0397e1088439468L }, + { 0x106b203f96004c8L, 0x1cae7a2c02affd4L, 0x019d57cd642760fL, + 0x17caa191ddaefabL, 0x15a060814a9ea6fL, 0x14103148e46654aL, + 0x1e179287fb9e2f3L, 0x0cdd735bc0d347bL, 0x1fbbdcf0c7d3de6L, + 0x1451c8dae99b6a8L, 0x1e34a170bff0f08L, 0x1bc65ef62cb6ec1L, + 0x04561770401ee48L, 0x0ef7fcd001c01ecL, 0x1f8d69395cfd922L, + 0x14d8dc344e71d42L, 0x12d238ef17c8840L, 0x02404a37c588f6cL }, + { 0x0c747a8fd71f119L, 0x12e2f29f59b4ac2L, 0x1e198a6161e8679L, + 0x135631ade81c5ecL, 0x0630b8c048a4889L, 0x157c4950d4c8126L, + 0x15892125d4258b2L, 0x1a9910d3575c41fL, 0x03b72b04d6c2b7dL, + 0x13baf5b04c97be8L, 0x0701b9f41b9a138L, 0x06c3c977a00e011L, + 0x0b4ba846e4cb3b4L, 0x032326cf50d7333L, 0x1e14e7f0070bac9L, + 0x15f8ff0de57cd83L, 0x10216e8e8aecf68L, 0x046d5b0fee39c34L }, + { 0x0a5c903d54d1d45L, 0x014bf7fa7cdd121L, 0x1480d351e2d2b35L, + 0x161188c4345b116L, 0x1486540235b2ba2L, 0x0f997369e91cdd9L, + 0x1f708779dabb644L, 0x0050eff179e7e0dL, 0x1802714c19ec515L, + 0x0822275d2c83806L, 0x108a7cc773255e8L, 0x0f57702d3fdb0d2L, + 0x152caf080e5ece7L, 0x05ebe778aadf450L, 0x0e5fb84fac86c53L, + 0x0d2193bdef5a2cfL, 0x1e7e03ca879118fL, 0x037bbf316fccd94L }, + { 0x071bdede40bbf59L, 0x1d229b200d56b51L, 0x00d5cd5073445deL, + 0x0c96e3605e2eabcL, 0x0813359f3465b46L, 0x1c75639175b889dL, + 0x1ced65e4aa3f5bcL, 0x17e2354025ffe77L, 0x099aafabff85c3fL, + 0x0f0517783606621L, 0x15755ddcedecea4L, 0x1cedacd30814629L, + 0x132e5a8be6ae5e2L, 0x00e7aac04309b03L, 0x0fb440bb9b5d5e3L, + 0x1e1d64689c01ed1L, 0x180799d78868184L, 0x031c0ce48e1e967L }, + { 0x05392e17884b073L, 0x1d0fe758933f565L, 0x17c241c0e29e7b0L, + 0x19c988f6e07a0feL, 0x1bf96b91cb2ac07L, 0x1527dffcb332770L, + 0x19403afd5d624abL, 0x008b557e723f5bcL, 0x0c5b3376f171d12L, + 0x1fb0628d069ec0dL, 0x0b3f9e5daa112c7L, 0x19357b4c24b4216L, + 0x134ebd453ee131cL, 0x0825b5e0f07e0b6L, 0x0be32af0340c669L, + 0x1368fc87417ce14L, 0x1eec80afeec55e4L, 0x033ea46894132ebL }, + { 0x08d59a7ea2d56d6L, 0x15e8713a4053183L, 0x16c2b9cd9b375c6L, + 0x140e409d78d7a23L, 0x177e6293fbb639cL, 0x1d461ec4d12173fL, + 0x1e6a37b9f28add6L, 0x0208e5bb87ac945L, 0x084229df47561a0L, + 0x0fb1642e2db24eaL, 0x15ac6d37249f365L, 0x0240bdcc0b2dfbaL, + 0x10abf29401fe8bbL, 0x0868e0c21f7e552L, 0x0c077d75240343cL, + 0x087ea59e2275251L, 0x1c7a3d7ebc31f0eL, 0x013ca871c741c26L }, + { 0x0b21ff0e1d0fa79L, 0x1e8198245aef4f5L, 0x1a24bf8dd32d2e7L, + 0x149d643ed699268L, 0x0925e7e7bb4827fL, 0x0a6298a338b7bcdL, + 0x1b77c510afcd9f7L, 0x11240e72a99a5d2L, 0x14e0141ae8502aaL, + 0x170070d4777b664L, 0x1a1245620336be3L, 0x14b8d2c5008cab9L, + 0x185d15dfbfff3abL, 0x0fb4279299ae627L, 0x0796f629fc11032L, + 0x04b575d008a7f76L, 0x171a1c99813ff22L, 0x02a7fbc423cd92eL }, + { 0x1c6ee30de40b068L, 0x1232df379d28f13L, 0x1813e8ec87da489L, + 0x1b8083022bc4948L, 0x0df90d2b50a5a5aL, 0x186007f1942a20cL, + 0x0238eedd3963f72L, 0x1938d1e36769458L, 0x1339df0810ccd9eL, + 0x0a9b16e5bc3754fL, 0x1178c72556bab64L, 0x003b16d4d8d6512L, + 0x1c3678a427d6a2cL, 0x14649816034f416L, 0x08407985e1d5400L, + 0x1650d159b52cb3fL, 0x0fe4e4e4573ee30L, 0x0456dd6c29f8c18L }, + { 0x00ae11f0969d524L, 0x1ed7bf9cde63c83L, 0x1d99f307f30bd0bL, + 0x05c466da9e79d8cL, 0x0e1c0f7f456b9cfL, 0x027d873550faef4L, + 0x12ca336f0ab4826L, 0x1de81219f4c368cL, 0x140d86f301243f3L, + 0x0d8b66666af43f3L, 0x1c5a30c09b35065L, 0x0d9702d80e60807L, + 0x1358407a1ddbe38L, 0x0b8bf0d78a75c37L, 0x12f25b3d622d3e0L, + 0x0e3836eb8834ccdL, 0x05ff342c1aa027eL, 0x039c9801b604a2fL }, + { 0x14f757d22cdaf42L, 0x1ac8efa0c0d55caL, 0x0067d5453c95e22L, + 0x11e31fab791730dL, 0x022ceb9169642e0L, 0x07b4c2c95982e88L, + 0x072b85c5640f9a9L, 0x15497afad3ac22fL, 0x0dacdfd5dd29c01L, + 0x02eeead6c888466L, 0x0b1ec592b23c55cL, 0x09c36a48c65e869L, + 0x1b731fc44761a51L, 0x104b0d98a2dcf30L, 0x1abc88f3d584d23L, + 0x133a7385152cee7L, 0x1e25bd10182aa7cL, 0x045e376257214b2L }, + { 0x096e5c0e7f2a32bL, 0x04006049c451868L, 0x0df10078d833fd5L, + 0x1976c0a94c0dfc8L, 0x0457aa6e6655fc9L, 0x14d95ba8870c304L, + 0x1698682b3f288acL, 0x194e64907c6a36fL, 0x1e31471ee6be6c8L, + 0x0b2a18e45b2e4d0L, 0x0b0ee5235972ef9L, 0x18435d365551f93L, + 0x0daa60aa6ad308fL, 0x0c17e06a6b53ef8L, 0x11e935ca11365aaL, + 0x112ab56025858b0L, 0x0152b3c8f71dcebL, 0x04742a1bedf4e3fL }, +}; + +/* Perform the modular exponentiation in Fp* for SAKKE. + * + * Base is fixed to be the g parameter - a precomputed table is used. + * + * Striping: 128 points at a distance of 8 combined. + * Total of 256 points in table. + * Square and multiply performed in Fp*. + * + * base [in] Base. MP integer. + * exp [in] Exponent. MP integer. + * res [out] Result. MP integer. + * returns 0 on success, MP_READ_E if there are too many bytes in an array + * and MEMORY_E if memory allocation fails. + */ +int sp_ModExp_Fp_star_1024(const mp_int* base, mp_int* exp, mp_int* res) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td; + sp_digit* t; + sp_digit* tx; + sp_digit* ty; +#else + sp_digit t[4 * 2 * 18]; + sp_digit tx[2 * 18]; + sp_digit ty[2 * 18]; +#endif + sp_digit* r = NULL; + unsigned char e[128]; + int err = MP_OKAY; + int i; + int y; + + (void)base; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6 * 18 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + tx = td + 4 * 18 * 2; + ty = td + 5 * 18 * 2; +#endif + r = ty; + + (void)mp_to_unsigned_bin_len(exp, e, 128); + + XMEMCPY(tx, p1024_norm_mod, sizeof(sp_digit) * 18); + y = e[112] >> 7; + y |= (e[96] >> 7) << 1; + y |= (e[80] >> 7) << 2; + y |= (e[64] >> 7) << 3; + y |= (e[48] >> 7) << 4; + y |= (e[32] >> 7) << 5; + y |= (e[16] >> 7) << 6; + y |= (e[0] >> 7) << 7; + XMEMCPY(ty, sp_1024_g_table[y], sizeof(sp_digit) * 18); + for (i = 126; i >= 0; i--) { + y = (e[127 - (i / 8)] >> (i & 0x7)) & 1; + y |= ((e[111 - (i / 8)] >> (i & 0x7)) & 1) << 1; + y |= ((e[95 - (i / 8)] >> (i & 0x7)) & 1) << 2; + y |= ((e[79 - (i / 8)] >> (i & 0x7)) & 1) << 3; + y |= ((e[63 - (i / 8)] >> (i & 0x7)) & 1) << 4; + y |= ((e[47 - (i / 8)] >> (i & 0x7)) & 1) << 5; + y |= ((e[31 - (i / 8)] >> (i & 0x7)) & 1) << 6; + y |= ((e[15 - (i / 8)] >> (i & 0x7)) & 1) << 7; + + sp_1024_proj_sqr_18(tx, ty, t); + sp_1024_proj_mul_qx1_18(tx, ty, sp_1024_g_table[y], t); + } + } + + if (err == MP_OKAY) { + sp_1024_mont_inv_18(tx, tx, t); + sp_1024_mont_mul_18(r, tx, ty, p1024_mod, p1024_mp_mod); + XMEMSET(r + 18, 0, sizeof(sp_digit) * 18); + sp_1024_mont_reduce_18(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Multiply p* by q* in projective co-ordinates. + * + * p.x' = (p.x * q.x) - (p.y * q.y) + * p.y' = (p.x * q.y) + (p.y * q.x) + * But applying Karatsuba: + * v0 = p.x * q.x + * v1 = p.y * q.y + * p.x' = v0 - v1 + * p.y' = (px + py) * (qx + qy) - v0 - v1 + * + * px [in,out] A single precision integer - X ordinate of number to multiply. + * py [in,out] A single precision integer - Y ordinate of number to multiply. + * qx [in] A single precision integer - X ordinate of number of + * multiplier. + * qy [in] A single precision integer - Y ordinate of number of + * multiplier. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_mul_18(sp_digit* px, sp_digit* py, + const sp_digit* qx, const sp_digit* qy, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 18; + + /* t1 = px + py */ + sp_1024_mont_add_18(t1, px, py, p1024_mod); + /* t2 = qx + qy */ + sp_1024_mont_add_18(t2, qx, qy, p1024_mod); + /* t2 = (px + py) * (qx + qy) */ + sp_1024_mont_mul_18(t2, t1, t2, p1024_mod, p1024_mp_mod); + /* t1 = py * qy */ + sp_1024_mont_mul_18(t1, py, qy, p1024_mod, p1024_mp_mod); + /* t2 = (px + py) * (qx + qy) - (py * qy) */ + sp_1024_mont_sub_18(t2, t2, t1, p1024_mod); + /* px = px * qx */ + sp_1024_mont_mul_18(px, px, qx, p1024_mod, p1024_mp_mod); + /* py = (px + py) * (qx + qy) - (py * qy) - (px * qx) */ + sp_1024_mont_sub_18(py, t2, px, p1024_mod); + /* px = (px * qx) - (py * qy)*/ + sp_1024_mont_sub_18(px, px, t1, p1024_mod); +} + +#ifndef WOLFSSL_SP_SMALL +/* + * Convert point from projective to affine but keep in Montgomery form. + * + * p [in,out] Point to convert. + * t [in] Temporary numbers: 2. + */ +static void sp_1024_mont_map_18(sp_point_1024* p, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 18; + + sp_1024_mont_inv_18(t1, p->z, t2); + sp_1024_mont_sqr_18(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(t1, t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(p->x, p->x, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_18(p->y, p->y, t1, p1024_mod, p1024_mp_mod); + XMEMCPY(p->z, p1024_norm_mod, sizeof(sp_digit) * 18); +} + +#endif /* WOLFSSL_SP_SMALL */ +/* + * Calculate gradient of line through P, P and [-2]P, accumulate line and + * double P. + * + * Calculations: + * l = 3 * (p.x^2 - p.z^4) = 3 * (p.x - p.z^2) * (p.x + p.z^2) + * r.x = l * (p.x + q.x * p.z^2) - 2 * p.y^2 + * r.y = 2 * p.y * p.z^3 * q.y (= p'.z * p.z^2 * q.y) + * v* = v*^2 * r* + * p'.x = l^2 - 8 * p.y^2 * p.x + * p'.y = (4 * p.y^2 * p.x - p'.x) * l - 8 * p.y^4 + * p'.z = 2 * p.y * p.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] p ECC point - point on E(F_p^2) to double. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_dbl_18(sp_digit* vx, sp_digit* vy, + sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 18; + sp_digit* pz2 = t + 2 * 18; + sp_digit* rx = t + 4 * 18; + sp_digit* ry = t + 6 * 18; + sp_digit* l = t + 8 * 18; + sp_digit* ty = t + 10 * 18; + + /* v = v^2 */ + sp_1024_proj_sqr_18(vx, vy, t); + /* pz2 = p.z^2 */ + sp_1024_mont_sqr_18(pz2, p->z, p1024_mod, p1024_mp_mod); + /* t1 = p.x + p.z^2 */ + sp_1024_mont_add_18(ty, p->x, pz2, p1024_mod); + /* l = p.x - p.z^2 */ + sp_1024_mont_sub_18(l, p->x, pz2, p1024_mod); + /* t1 = (p.x + p.z^2) * (p.x - p.z^2) = p.x^2 - p.z^4 */ + sp_1024_mont_mul_18(t1, l, ty, p1024_mod, p1024_mp_mod); + /* l = 3 * (p.x^2 - p.z^4) */ + sp_1024_mont_tpl_18(l, t1, p1024_mod); + /* t1 = q.x * p.z^2 */ + sp_1024_mont_mul_18(t1, q->x, pz2, p1024_mod, p1024_mp_mod); + /* t1 = p.x + q.x * p.z^2 */ + sp_1024_mont_add_18(t1, p->x, t1, p1024_mod); + /* r.x = l * (p.x + q.x * p.z^2) */ + sp_1024_mont_mul_18(rx, l, t1, p1024_mod, p1024_mp_mod); + /* r.y = 2 * p.y */ + sp_1024_mont_dbl_18(ry, p->y, p1024_mod); + /* ty = 4 * p.y ^ 2 */ + sp_1024_mont_sqr_18(ty, ry, p1024_mod, p1024_mp_mod); + /* t1 = 2 * p.y ^ 2 */ + sp_1024_div2_18(t1, ty, p1024_mod); + /* r.x -= 2 * (p.y ^ 2) */ + sp_1024_mont_sub_18(rx, rx, t1, p1024_mod); + /* p'.z = p.y * 2 * p.z */ + sp_1024_mont_mul_18(p->z, p->z, ry, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 */ + sp_1024_mont_mul_18(t1, p->z, pz2, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 * q.y */ + sp_1024_mont_mul_18(ry, t1, q->y, p1024_mod, p1024_mp_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_18(vx, vy, rx, ry, t); + + /* Double point using previously calculated values + * l = 3 * (p.x - p.z^2).(p.x + p.z^2) + * ty = 4 * p.y^2 + * p'.z = 2 * p.y * p.z + */ + /* t1 = (4 * p.y^2) ^ 2 = 16 * p.y^4 */ + sp_1024_mont_sqr_18(t1, ty, p1024_mod, p1024_mp_mod); + /* t1 = 16 * p.y^4 / 2 = 8 * p.y^4 */ + sp_1024_div2_18(t1, t1, p1024_mod); + /* p'.y = 4 * p.y^2 * p.x */ + sp_1024_mont_mul_18(p->y, ty, p->x, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 */ + sp_1024_mont_sqr_18(p->x, l, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 - 4 * p.y^2 * p.x */ + sp_1024_mont_sub_18(p->x, p->x, p->y, p1024_mod); + /* p'.x = l^2 - 8 * p.y^2 * p.x */ + sp_1024_mont_sub_18(p->x, p->x, p->y, p1024_mod); + /* p'.y = 4 * p.y^2 * p.x - p.x' */ + sp_1024_mont_sub_18(ty, p->y, p->x, p1024_mod); + /* p'.y = (4 * p.y^2 * p.x - p'.x) * l */ + sp_1024_mont_mul_18(p->y, ty, l, p1024_mod, p1024_mp_mod); + /* p'.y = (4 * p.y^2 * p.x - p'.x) * l - 8 * p.y^4 */ + sp_1024_mont_sub_18(p->y, p->y, t1, p1024_mod); +} + +#ifdef WOLFSSL_SP_SMALL +/* + * Calculate gradient of line through C, P and -C-P, accumulate line and + * add P to C. + * + * Calculations: + * r.x = (q.x + p.x) * c.y - (q.x * c.z^2 + c.x) * p.y * c.z + * r.y = (c.x - p.x * c.z^2) * q.y * c.z + * v* = v* * r* + * r = p.y * c.z^3 - c.y + * c'.x = r^2 + h^3 - 2 * c.x * h^2 + * c'.y = r * (c'.x - c.x * h^2) - c.y * h^3 + * c'.z = (c.x - p.x * c.z^2) * c.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] c ECC point - current point on E(F_p^2) to be added + * to. + * @param [in] p ECC point - point on E(F_p^2) to add. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] qx_px SP that is a constant value across adds. + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_add_one_18(sp_digit* vx, sp_digit* vy, + sp_point_1024* c, sp_point_1024* p, sp_point_1024* q, sp_digit* qx_px, + sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 18; + sp_digit* rx = t + 4 * 18; + sp_digit* ry = t + 6 * 18; + sp_digit* h = t + 8 * 18; + sp_digit* r = t + 10 * 18; + + /* r.x = (q.x + p.x) * c.y */ + sp_1024_mont_mul_18(rx, qx_px, c->y, p1024_mod, p1024_mp_mod); + /* t2 = c.z^2 */ + sp_1024_mont_sqr_18(t2, c->z, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 */ + sp_1024_mont_mul_18(t1, q->x, t2, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 + c.x */ + sp_1024_mont_add_18(h, t1, c->x, p1024_mod); + /* r = p.y * c.z */ + sp_1024_mont_mul_18(ry, p->y, c->z, p1024_mod, p1024_mp_mod); + /* t1 = (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_mul_18(t1, h, ry, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z * c.z^2 = p.y * c.z^3 */ + sp_1024_mont_mul_18(r, ry, t2, p1024_mod, p1024_mp_mod); + /* r.x -= (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_sub_18(rx, rx, t1, p1024_mod); + /* t1 = p.x * c.z^2 */ + sp_1024_mont_mul_18(t1, p->x, t2, p1024_mod, p1024_mp_mod); + /* h = c.x - p.x * c.z^2 */ + sp_1024_mont_sub_18(h, c->x, t1, p1024_mod); + /* c'.z = (c.x - p.x * c.z^2) * c.z */ + sp_1024_mont_mul_18(c->z, h, c->z, p1024_mod, p1024_mp_mod); + /* r.y = (c.x - p.x * c.z^2) * c.z * q.y */ + sp_1024_mont_mul_18(ry, c->z, q->y, p1024_mod, p1024_mp_mod); + /* v = v * r */ + sp_1024_proj_mul_18(vx, vy, rx, ry, t); + + /* Add p to c using previously calculated values. + * h = c.x - p.x * c.z^2 + * r = p.y * c.z^3 + * c'.z = (c.x - p.x * c.z^2) * c.z + */ + + /* r = p.y * c.z^3 - c.y */ + sp_1024_mont_sub_18(r, r, c->y, p1024_mod); + /* t1 = r^2 */ + sp_1024_mont_sqr_18(t1, r, p1024_mod, p1024_mp_mod); + /* t2 = h^2 */ + sp_1024_mont_sqr_18(rx, h, p1024_mod, p1024_mp_mod); + /* ry = c.x * h^2 */ + sp_1024_mont_mul_18(ry, c->x, rx, p1024_mod, p1024_mp_mod); + /* t2 = h^3 */ + sp_1024_mont_mul_18(t2, rx, h, p1024_mod, p1024_mp_mod); + /* c->x = r^2 + h^3 */ + sp_1024_mont_add_18(c->x, t1, t2, p1024_mod); + /* t1 = 2 * c.x * h^2 */ + sp_1024_mont_dbl_18(t1, ry, p1024_mod); + /* c'.x = r^2 + h^3 - 2 * c.x * h^2 */ + sp_1024_mont_sub_18(c->x, c->x, t1, p1024_mod); + /* ry = c'.x - c.x * h^2 */ + sp_1024_mont_sub_18(t1, c->x, ry, p1024_mod); + /* ry = r * (c'.x - c.x * h^2) */ + sp_1024_mont_mul_18(ry, t1, r, p1024_mod, p1024_mp_mod); + /* t2 = c.y * h^3 */ + sp_1024_mont_mul_18(t1, t2, c->y, p1024_mod, p1024_mp_mod); + /* c'.y = r * (c'.x - c.x * h^2) - c.y * h^3 */ + sp_1024_mont_sub_18(c->y, ry, t1, p1024_mod); +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * @param [in] key SAKKE key. + * @param [in] p First point on E(F_p)[q]. + * @param [in] q Second point on E(F_p)[q]. + * @param [in] r Result of calculation. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +int sp_Pairing_1024(const ecc_point* pm, const ecc_point* qm, mp_int* res) +{ + int err = MP_OKAY; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit* qx_px; +#else + sp_digit t[6 * 2 * 18]; + sp_digit vx[2 * 18]; + sp_digit vy[2 * 18]; + sp_digit qx_px[2 * 18]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + + err = sp_1024_point_new_18(NULL, pd, p); + if (err == MP_OKAY) { + err = sp_1024_point_new_18(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_18(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 9 * 18 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 18 * 2; + vy = td + 7 * 18 * 2; + qx_px = td + 8 * 18 * 2; +#endif + r = vy; + + sp_1024_point_from_ecc_point_18(p, pm); + sp_1024_point_from_ecc_point_18(q, qm); + + err = sp_1024_mod_mul_norm_18(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_18(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_18(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_18(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_18(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 18); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 18); + + sp_1024_mont_add_18(qx_px, q->x, p->x, p1024_mod); + + for (i = 1020; i >= 0; i--) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_dbl_18(vx, vy, c, q, t); + + if ((i > 0) && ((p1024_order[i / 57] >> (i % 57)) & 1)) { + /* Accumulate line into v and add P into C. */ + sp_1024_accumulate_line_add_one_18(vx, vy, c, p, q, qx_px, t); + } + } + + /* Final exponentiation */ + sp_1024_proj_sqr_18(vx, vy, t); + sp_1024_proj_sqr_18(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_18(vx, vx, t); + sp_1024_mont_mul_18(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 18, 0, sizeof(sp_digit) * 18); + sp_1024_mont_reduce_18(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_18(c, 1, NULL); + sp_1024_point_free_18(q, 1, NULL); + sp_1024_point_free_18(p, 1, NULL); + return err; +} + +#else +/* + * Calculate gradient of line through C, P and -C-P, accumulate line and + * add P to C. + * + * Both C and P have z ordinates to use in the calculation. + * + * Calculations: + * r.x = (q.x * c.z^2 + c.x) * p.y * c.z - (q.x * p.z^2 + p.x) * c.y * p.z + * r.y = (p.x * c.z^2 - c.x * p.z^2) * q.y * p.z * c.z + * v* = v* * r* + * h = p.x * c.z^2 - c.x * p.z^2 + * r = p.y * c.z^3 - c.y * p.z^3 + * c'.x = r^2 - h^3 - 2 * c.x * p.z^2 * h^2 + * c'.y = r * (c.x * p.z^2 * h^2 - c'.x) - c.y * p.z^3 * h^3 + * c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] c ECC point - current point on E(F_p^2) to be added + * to. + * @param [in,out] p ECC point - point on E(F_p^2) to add. + * @param [in,out] q ECC point - second point on E(F_P^2). + * @param [in,out] t SP temporaries (6 used). + * @param [in,out] neg Indicates to use negative P. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static void sp_1024_accumulate_line_add_n_18(sp_digit* vx, sp_digit* vy, + const sp_point_1024* p, const sp_point_1024* q, + sp_point_1024* c, sp_digit* t, int neg) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 18; + sp_digit* rx = t + 4 * 18; + sp_digit* ry = t + 6 * 18; + sp_digit* h = t + 8 * 18; + sp_digit* r = t + 10 * 18; + + /* h = p.z^2 */ + sp_1024_mont_sqr_18(h, p->z, p1024_mod, p1024_mp_mod); + /* rx = q.x * p.z^2 */ + sp_1024_mont_mul_18(rx, q->x, h, p1024_mod, p1024_mp_mod); + /* rx = q.x * p.z^2 + p.x */ + sp_1024_mont_add_18(t2, rx, p->x, p1024_mod); + /* c.y = c.y * p.z */ + sp_1024_mont_mul_18(t1, c->y, p->z, p1024_mod, p1024_mp_mod); + /* r.x = (q.x * p.z^2 + p.x) * c.y * p.z */ + sp_1024_mont_mul_18(rx, t2, t1, p1024_mod, p1024_mp_mod); + /* c.y = c.y * p.z^3 */ + sp_1024_mont_mul_18(c->y, t1, h, p1024_mod, p1024_mp_mod); + /* t2 = c.z^2 */ + sp_1024_mont_sqr_18(t2, c->z, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 */ + sp_1024_mont_mul_18(t1, q->x, t2, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 + c.x */ + sp_1024_mont_add_18(t1, t1, c->x, p1024_mod); + /* c.x = c.x * p.z^2 */ + sp_1024_mont_mul_18(c->x, c->x, h, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z */ + sp_1024_mont_mul_18(r, p->y, c->z, p1024_mod, p1024_mp_mod); + if (neg) { + /* r = -p.y * c.z */ + sp_1024_mont_sub_18(r, p1024_mod, r, p1024_mod); + } + /* t1 = (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_mul_18(ry, t1, r, p1024_mod, p1024_mp_mod); + /* r.x -= (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_sub_18(rx, ry, rx, p1024_mod); + /* t1 = p.x * c.z^2 */ + sp_1024_mont_mul_18(t1, p->x, t2, p1024_mod, p1024_mp_mod); + /* h = p.x * c.z^2 - c.x * p.z^2 */ + sp_1024_mont_sub_18(h, t1, c->x, p1024_mod); + /* c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z */ + sp_1024_mont_mul_18(t1, h, c->z, p1024_mod, p1024_mp_mod); + /* c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z * p.z */ + sp_1024_mont_mul_18(c->z, t1, p->z, p1024_mod, p1024_mp_mod); + /* r.y = (p.x * c.z^2 - c.x * p.z^2) * c.z * p.z * q.y */ + sp_1024_mont_mul_18(ry, c->z, q->y, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z^3 */ + sp_1024_mont_mul_18(t1, r, t2, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z^3 - c.y * p.z^3 */ + sp_1024_mont_sub_18(r, t1, c->y, p1024_mod); + /* v = v * r */ + sp_1024_proj_mul_18(vx, vy, rx, ry, t); + + /* Add p to c using previously calculated values. + * h = p.x * c.z^2 - c.x * p.z^2 + * r = p.y * c.z^3 - c.y * p.z^3 + * c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z + */ + + /* t1 = r^2 */ + sp_1024_mont_sqr_18(t1, r, p1024_mod, p1024_mp_mod); + /* t2 = h^2 */ + sp_1024_mont_sqr_18(rx, h, p1024_mod, p1024_mp_mod); + /* ry = c.x * p.z^2 * h^2 */ + sp_1024_mont_mul_18(ry, rx, c->x, p1024_mod, p1024_mp_mod); + /* t2 = h^3 */ + sp_1024_mont_mul_18(t2, rx, h, p1024_mod, p1024_mp_mod); + /* c'.x = r^2 - h^3 */ + sp_1024_mont_sub_18(c->x, t1, t2, p1024_mod); + /* t1 = 2 * c.x * p.z^2 * h^2 */ + sp_1024_mont_dbl_18(t1, ry, p1024_mod); + /* c'.x = r^2 - h^3 - 2 * c.x * p.z^2 * h^2 */ + sp_1024_mont_sub_18(c->x, c->x, t1, p1024_mod); + /* ry = c.x * p.z^2 * h^2 - c'.x */ + sp_1024_mont_sub_18(t1, ry, c->x, p1024_mod); + /* ry = r * (c.x * p.z^2 * h^2 - c'.x) */ + sp_1024_mont_mul_18(ry, t1, r, p1024_mod, p1024_mp_mod); + /* t2 = c.y * p.z^3 * h^3 */ + sp_1024_mont_mul_18(t1, t2, c->y, p1024_mod, p1024_mp_mod); + /* c'.y = r * (c.x * p.z^2 * h^2 - c'.x) - c.y * p.z^3 * h^3 */ + sp_1024_mont_sub_18(c->y, ry, t1, p1024_mod); +} + +/* + * Perform n accumulate doubles and doubles of P. + * + * py = 2 * p.y + * + * For each double: + * Calculate gradient of line through P, P and [-2]P, accumulate line and + * double P. + * + * Calculations: + * l = 3 * (p.x^2 - p.z^4) = 3 * (p.x - p.z^2) * (p.x + p.z^2) + * r.x = l * (p.x + q.x * p.z^2) - py^2 / 2 + * r.y = py * p.z^3 * q.y (= p'.z * p.z^2 * q.y) + * v* = v*^2 * r* + * p'.x = l^2 - 2 * py^2 * p.x + * py' = (py^2 * p.x - p'.x) * l - py^4 (= 2 * p'.y) + * p'.z = py * p.z + * + * Finally: + * p'.y = py' / 2 + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] p ECC point - point on E(F_p^2) to double. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] n Number of times to double. + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_dbl_n_18(sp_digit* vx, sp_digit* vy, + sp_point_1024* p, const sp_point_1024* q, int n, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 18; + sp_digit* pz2 = t + 2 * 18; + sp_digit* rx = t + 4 * 18; + sp_digit* ry = t + 6 * 18; + sp_digit* l = t + 8 * 18; + sp_digit* ty = t + 10 * 18; + int i; + + /* py = 2 * p.y */ + sp_1024_mont_dbl_18(p->y, p->y, p1024_mod); + + for (i = 0; i < n; i++) { + /* v = v^2 */ + sp_1024_proj_sqr_18(vx, vy, t); + /* pz2 = p.z^2 */ + sp_1024_mont_sqr_18(pz2, p->z, p1024_mod, p1024_mp_mod); + /* t1 = p.x + p.z^2 */ + sp_1024_mont_add_18(t1, p->x, pz2, p1024_mod); + /* l = p.x - p.z^2 */ + sp_1024_mont_sub_18(l, p->x, pz2, p1024_mod); + /* t1 = (p.x + p.z^2) * (p.x - p.z^2) = p.x^2 - p.z^4 */ + sp_1024_mont_mul_18(ty, l, t1, p1024_mod, p1024_mp_mod); + /* l = 3 * (p.x^2 - p.z^4) */ + sp_1024_mont_tpl_18(l, ty, p1024_mod); + /* t1 = q.x * p.z^2 */ + sp_1024_mont_mul_18(t1, q->x, pz2, p1024_mod, p1024_mp_mod); + /* t1 = p.x + q.x * p.z^2 */ + sp_1024_mont_add_18(t1, p->x, t1, p1024_mod); + /* r.x = l * (p.x + q.x * p.z^2) */ + sp_1024_mont_mul_18(rx, l, t1, p1024_mod, p1024_mp_mod); + /* ty = py ^ 2 */ + sp_1024_mont_sqr_18(ty, p->y, p1024_mod, p1024_mp_mod); + /* t1 = py ^ 2 / 2 */ + sp_1024_div2_18(t1, ty, p1024_mod); + /* r.x -= py ^ 2 / 2 */ + sp_1024_mont_sub_18(rx, rx, t1, p1024_mod); + /* p'.z = py * pz */ + sp_1024_mont_mul_18(p->z, p->z, p->y, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 */ + sp_1024_mont_mul_18(t1, p->z, pz2, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 * q.y */ + sp_1024_mont_mul_18(ry, t1, q->y, p1024_mod, p1024_mp_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_18(vx, vy, rx, ry, t); + + /* Double point using previously calculated values + * l = 3 * (p.x - p.z^2).(p.x + p.z^2) + * ty = py^2 + * p'.z = py * p.z + */ + /* t1 = py^2 ^ 2 = py^4 */ + sp_1024_mont_sqr_18(t1, ty, p1024_mod, p1024_mp_mod); + /* py' = py^2 * p. x */ + sp_1024_mont_mul_18(p->y, ty, p->x, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 */ + sp_1024_mont_sqr_18(p->x, l, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 - py^2 * p.x */ + sp_1024_mont_sub_18(p->x, p->x, p->y, p1024_mod); + /* p'.x = l^2 - 2 * p.y^2 * p.x */ + sp_1024_mont_sub_18(p->x, p->x, p->y, p1024_mod); + /* py' = py^2 * p.x - p.x' */ + sp_1024_mont_sub_18(ty, p->y, p->x, p1024_mod); + /* py' = (p.y^2 * p.x - p'.x) * l */ + sp_1024_mont_mul_18(p->y, ty, l, p1024_mod, p1024_mp_mod); + /* py' = (p.y^2 * p.x - p'.x) * l * 2 */ + sp_1024_mont_dbl_18(p->y, p->y, p1024_mod); + /* py' = (p.y^2 * p.x - p'.x) * l * 2 - p.y^4 */ + sp_1024_mont_sub_18(p->y, p->y, t1, p1024_mod); + } + + /* p'.y = py' / 2 */ + sp_1024_div2_18(p->y, p->y, p1024_mod); +} + +/* Operations to perform based on order - 1. + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * Pairs: #dbls, add/subtract window value + */ +static const signed char sp_1024_order_op[] = { + 5, 6, -13, 9, -21, 6, -5, 8, 31, 6, 3, 6, -27, 6, 25, 9, + -1, 6, -11, 6, -13, 6, -7, 6, -15, 6, -29, 7, 25, 6, -9, 6, + -19, 7, 3, 6, 11, 9, -23, 6, 1, 6, 27, 6, 1, 7, -25, 8, + 13, 7, -13, 7, -23, 10, 19, 7, 7, 7, -3, 7, 27, 6, -7, 7, + -21, 7, 11, 7, 31, 8, 1, 7, -23, 6, -17, 6, -3, 10, 11, 6, + -21, 7, -27, 11, -29, 6, -1, 10, 15, 8, 27, 7, 17, 6, 17, 7, + -13, 8, 13, 6, 21, 7, -29, 6, 19, 7, -25, 6, 11, 9, 29, 7, + -7, 8, 27, 7, 29, 10, -1, 8, -7, 8, 17, 6, 17, 7, -27, 7, + -21, 6, -9, 6, -27, 12, -23, 6, 19, 6, 13, 6, -11, 7, 27, 6, + 17, 6, -7, 6, -25, 7, -29, 6, 9, 7, 7, 6, 13, 6, -25, 6, + -19, 6, 13, 6, -11, 6, 5, 8, 19, 6, -21, 8, 23, 7, 27, 6, + -13, 6, -19, 11, 29, 7, -15, 6, -9, 7, -21, 10, -3, 7, 21, 10, + 25, 6, -15, 6, -23, 6, 21, 6, 1, 6, 21, 7, -3, 6, -3, 7, + -7, 6, -23, 7, 7, 8, 15, 9, 5, 6, -11, 6, 21, 11, -27, 7, + 27, 6, -11, 6, 31, 6, -21, 6, 19, 6, -7, 8, -7, 13, -3, 6, + -7, 7, -3, 6, 1, 6, 7, 8, 19, 8, 11, 9, -9, 7, -31, 12, + 25, 6, -17, 9, -15, 7, 5, 6, 25, 7, -5, 7, -25, 6, 17, 8, + -19, 6, -13, 6, 27, 8, 1, 7, -5, 7, -1, 6, 21, 6, 3, 10, + -3, 1, +}; +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int sp_Pairing_1024(const ecc_point* pm, const ecc_point* qm, mp_int* res) +{ + int err; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit (*pre_vx)[36]; + sp_digit (*pre_vy)[36]; + sp_digit (*pre_nvy)[36]; + sp_point_1024* pre_p; +#else + sp_digit t[6 * 2 * 18]; + sp_digit vx[2 * 18]; + sp_digit vy[2 * 18]; + sp_digit pre_vx[16][36]; + sp_digit pre_vy[16][36]; + sp_digit pre_nvy[16][36]; + sp_point_1024 pre_p[16]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + int j; + + err = sp_1024_point_new_18(NULL, pd, p); + if (err == MP_OKAY) { + err = sp_1024_point_new_18(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_18(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 56 * 18 * 2 + 16 * sizeof(sp_point_1024), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 18 * 2; + vy = td + 7 * 18 * 2; + pre_vx = (sp_digit(*)[36])(td + 8 * 18 * 2); + pre_vy = (sp_digit(*)[36])(td + 24 * 18 * 2); + pre_nvy = (sp_digit(*)[36])(td + 40 * 18 * 2); + pre_p = (sp_point_1024*)(td + 56 * 18 * 2); +#endif + r = vy; + + sp_1024_point_from_ecc_point_18(p, pm); + sp_1024_point_from_ecc_point_18(q, qm); + + err = sp_1024_mod_mul_norm_18(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_18(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_18(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_18(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_18(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMCPY(&pre_p[0], p, sizeof(sp_point_1024)); + XMEMSET(pre_vx[0], 0, sizeof(sp_digit) * 2 * 18); + pre_vx[0][0] = 1; + XMEMSET(pre_vy[0], 0, sizeof(sp_digit) * 2 * 18); + sp_1024_mont_sub_18(pre_nvy[0], p1024_mod, pre_vy[0], p1024_mod); + + /* [2]P for adding */ + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 18); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 18); + sp_1024_accumulate_line_dbl_18(vx, vy, c, q, t); + + /* 3, 5, ... */ + for (i = 1; i < 16; i++) { + XMEMCPY(&pre_p[i], &pre_p[i-1], sizeof(sp_point_1024)); + XMEMCPY(pre_vx[i], pre_vx[i-1], sizeof(sp_digit) * 2 * 18); + XMEMCPY(pre_vy[i], pre_vy[i-1], sizeof(sp_digit) * 2 * 18); + sp_1024_proj_mul_18(pre_vx[i], pre_vy[i], vx, vy, t); + sp_1024_accumulate_line_add_n_18(pre_vx[i], pre_vy[i], c, + q, &pre_p[i], t, 0); + sp_1024_mont_sub_18(pre_nvy[i], p1024_mod, pre_vy[i], p1024_mod); + } + + j = sp_1024_order_op[0] / 2; + XMEMCPY(c, &pre_p[j], sizeof(sp_point_1024)); + XMEMCPY(vx, pre_vx[j], sizeof(sp_digit) * 2 * 18); + XMEMCPY(vy, pre_vy[j], sizeof(sp_digit) * 2 * 18); + + /* Accumulate line into v and double point n times. */ + sp_1024_accumulate_line_dbl_n_18(vx, vy, c, q, + sp_1024_order_op[1], t); + + for (i = 2; i < 290; i += 2) { + j = sp_1024_order_op[i]; + if (j > 0) { + j /= 2; + /* Accumulate line into v and add P into C. */ + sp_1024_proj_mul_18(vx, vy, pre_vx[j], pre_vy[j], t); + sp_1024_accumulate_line_add_n_18(vx, vy, &pre_p[j], q, c, + t, 0); + } + else { + j = -j / 2; + /* Accumulate line into v and add P into C. */ + sp_1024_proj_mul_18(vx, vy, pre_vx[j], pre_nvy[j], t); + sp_1024_accumulate_line_add_n_18(vx, vy, &pre_p[j], q, c, + t, 1); + } + + /* Accumulate line into v and double point n times. */ + sp_1024_accumulate_line_dbl_n_18(vx, vy, c, q, + sp_1024_order_op[i + 1], t); + } + + /* Final exponentiation */ + sp_1024_proj_sqr_18(vx, vy, t); + sp_1024_proj_sqr_18(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_18(vx, vx, t); + sp_1024_mont_mul_18(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 18, 0, sizeof(sp_digit) * 18); + sp_1024_mont_reduce_18(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_18(c, 1, NULL); + sp_1024_point_free_18(q, 1, NULL); + sp_1024_point_free_18(p, 1, NULL); + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* + * Generate table for pairing. + * + * Small implementation does not use a table - returns 0 length. + * + * pm [in] Point to generate table for. + * table [in] Generated table. + * len [in,out] On in, the size of the buffer. + * On out, length of table generated. + * @return 0 on success. + * LENGTH_ONLY_E when table is NULL and only length returned. + * BUFFER_E when len is too small. + */ +int sp_Pairing_gen_precomp_1024(const ecc_point* pm, byte* table, + word32* len) +{ + int err = 0; + + if (table == NULL) { + *len = 0; + err = LENGTH_ONLY_E; + } + else if (*len != 0) { + err = BUFFER_E; + } + + (void)*pm; + + return err; +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Small implementation does not use a table - use the normal implementation. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @param [in] table Precomputed table of values. + * @param [in] len Length of precomputed table of values in bytes. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int sp_Pairing_precomp_1024(const ecc_point* pm, const ecc_point* qm, + mp_int* res, const byte* table, word32 len) +{ + (void)table; + (void)len; + return sp_Pairing_1024(pm, qm, res); +} + +#else +/* + * Calc l and c for the point when doubling p. + * + * l = 3 * (p.x^2 - 1) / (2 * p.y) + * c = l * p.x - p.y + * + * @param [out] lr Gradient result - table entry. + * @param [out] cr Constant result - table entry. + * @param [in] px X-ordinate of point to double. + * @param [in] py Y-ordinate of point to double. + * @param [in] t SP temporaries (3 used). + */ +static void sp_1024_accum_dbl_calc_lc_18(sp_digit* lr, sp_digit* cr, + const sp_digit* px, const sp_digit* py, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 2 * 18; + sp_digit* t2 = t + 2 * 2 * 18; + sp_digit* l = t + 4 * 2 * 18; + + + /* l = 1 / 2 * p.y */ + sp_1024_mont_dbl_18(l, py, p1024_mod); + sp_1024_mont_inv_18(l, l, t); + + /* t1 = p.x^2 */ + sp_1024_mont_sqr_18(t1, px, p1024_mod, p1024_mp_mod); + /* t1 = p.x - 1 */ + sp_1024_mont_sub_18(t1, t1, p1024_norm_mod, p1024_mod); + /* t1 = 3 * (p.x^2 - 1) */ + sp_1024_mont_dbl_18(t2, t1, p1024_mod); + sp_1024_mont_add_18(t1, t1, t2, p1024_mod); + /* t1 = 3 * (p.x^2 - 1) / (2 * p.y) */ + sp_1024_mont_mul_18(l, l, t1, p1024_mod, p1024_mp_mod); + /* t2 = l * p.x */ + sp_1024_mont_mul_18(t2, l, px, p1024_mod, p1024_mp_mod); + /* c = t2 = l * p.x - p.y */ + sp_1024_mont_sub_18(t2, t2, py, p1024_mod); + + XMEMCPY(lr, l, sizeof(sp_digit) * 18); + XMEMCPY(cr, t2, sizeof(sp_digit) * 18); +} + +/* + * Calc l and c when adding p and c. + * + * l = (c.y - p.y) / (c.x - p.x) + * c = (p.x * c.y - cx * p.y) / (cx - p.x) + * + * @param [out] lr Gradient result - table entry. + * @param [out] cr Constant result - table entry. + * @param [in] px X-ordinate of point to add. + * @param [in] py Y-ordinate of point to add. + * @param [in] cx X-ordinate of current point. + * @param [in] cy Y-ordinate of current point. + * @param [in] t SP temporaries (3 used). + */ +static void sp_1024_accum_add_calc_lc_18(sp_digit* lr, sp_digit* cr, + const sp_digit* px, const sp_digit* py, const sp_digit* cx, + const sp_digit* cy, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 2 * 18; + sp_digit* c = t + 2 * 2 * 18; + sp_digit* l = t + 4 * 2 * 18; + + + /* l = 1 / (c.x - p.x) */ + sp_1024_mont_sub_18(l, cx, px, p1024_mod); + sp_1024_mont_inv_18(l, l, t); + + /* c = p.x * c.y */ + sp_1024_mont_mul_18(c, px, cy, p1024_mod, p1024_mp_mod); + /* t1 = c.x * p.y */ + sp_1024_mont_mul_18(t1, cx, py, p1024_mod, p1024_mp_mod); + /* c = (p.x * c.y) - (c.x * p.y) */ + sp_1024_mont_sub_18(c, c, t1, p1024_mod); + /* c = ((p.x * c.y) - (c.x * p.y)) / (c.x - p.x) */ + sp_1024_mont_mul_18(c, c, l, p1024_mod, p1024_mp_mod); + /* t1 = c.y - p.y */ + sp_1024_mont_sub_18(t1, cy, py, p1024_mod); + /* l = (c.y - p.y) / (c.x - p.x) */ + sp_1024_mont_mul_18(l, t1, l, p1024_mod, p1024_mp_mod); + + XMEMCPY(lr, l, sizeof(sp_digit) * 18); + XMEMCPY(cr, c, sizeof(sp_digit) * 18); +} + +/* + * Calculate vx and vy given gradient l and constant c and point q. + * + * l is a the gradient and is multiplied by q->x. + * c is a the constant that is added to the multiplicative result. + * q->y is the y-ordinate in result to multiply. + * + * if dbl + * v* = v*^2 + * r.x = l * q.x + c + * r.y = q->y + * v* = v* * r* + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in] l Gradient to multiply with. + * @param [in] c Constant to add with. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] t SP temporaries (3 used). + * @param [in] dbl Indicates whether this is for doubling. Otherwise + * adding. + */ +static void sp_1024_accumulate_line_lc_18(sp_digit* vx, sp_digit* vy, + const sp_digit* l, const sp_digit* c, const sp_point_1024* q, + sp_digit* t, int dbl) +{ + sp_digit* rx = t + 4 * 2 * 18; + + /* v = v^2 */ + if (dbl) { + sp_1024_proj_sqr_18(vx, vy, t); + } + /* rx = l * q.x + c */ + sp_1024_mont_mul_18(rx, l, q->x, p1024_mod, p1024_mp_mod); + sp_1024_mont_add_18(rx, rx, c, p1024_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_18(vx, vy, rx, q->y, t); +} + +/* Operations to perform based on order - 1. + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * Pairs: #dbls, add/subtract window value + */ +static const signed char sp_1024_order_op_pre[] = { + 5, 6, -13, 9, -21, 6, -5, 8, 31, 6, 3, 6, -27, 6, 25, 9, + -1, 6, -11, 6, -13, 6, -7, 6, -15, 6, -29, 7, 25, 6, -9, 6, + -19, 7, 3, 6, 11, 9, -23, 6, 1, 6, 27, 6, 1, 7, -25, 8, + 13, 7, -13, 7, -23, 10, 19, 7, 7, 7, -3, 7, 27, 6, -7, 7, + -21, 7, 11, 7, 31, 8, 1, 7, -23, 6, -17, 6, -3, 10, 11, 6, + -21, 7, -27, 11, -29, 6, -1, 10, 15, 8, 27, 7, 17, 6, 17, 7, + -13, 8, 13, 6, 21, 7, -29, 6, 19, 7, -25, 6, 11, 9, 29, 7, + -7, 8, 27, 7, 29, 10, -1, 8, -7, 8, 17, 6, 17, 7, -27, 7, + -21, 6, -9, 6, -27, 12, -23, 6, 19, 6, 13, 6, -11, 7, 27, 6, + 17, 6, -7, 6, -25, 7, -29, 6, 9, 7, 7, 6, 13, 6, -25, 6, + -19, 6, 13, 6, -11, 6, 5, 8, 19, 6, -21, 8, 23, 7, 27, 6, + -13, 6, -19, 11, 29, 7, -15, 6, -9, 7, -21, 10, -3, 7, 21, 10, + 25, 6, -15, 6, -23, 6, 21, 6, 1, 6, 21, 7, -3, 6, -3, 7, + -7, 6, -23, 7, 7, 8, 15, 9, 5, 6, -11, 6, 21, 11, -27, 7, + 27, 6, -11, 6, 31, 6, -21, 6, 19, 6, -7, 8, -7, 13, -3, 6, + -7, 7, -3, 6, 1, 6, 7, 8, 19, 8, 11, 9, -9, 7, -31, 12, + 25, 6, -17, 9, -15, 7, 5, 6, 25, 7, -5, 7, -25, 6, 17, 8, + -19, 6, -13, 6, 27, 8, 1, 7, -5, 7, -1, 6, 21, 6, 3, 10, + -3, 1, +}; + +/* + * Generate table for pairing. + * + * Calculate the graident (l) and constant (c) at each step of the way. + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * + * pm [in] Point to generate table for. + * table [in] Generated table. + * len [in,out] On in, the size of the buffer. + * On out, length of table generated. + * @return 0 on success. + * LENGTH_ONLY_E when table is NULL and only length returned. + * BUFFER_E when len is too small. + * MEMORY_E when dynamic memory allocation fauls. + */ +int sp_Pairing_gen_precomp_1024(const ecc_point* pm, byte* table, + word32* len) +{ + int err = 0; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_point_1024* pre_p; +#else + sp_digit t[6 * 2 * 18]; + sp_point_1024 pre_p[16]; + sp_point_1024 pd; + sp_point_1024 cd; + sp_point_1024 negd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* c = NULL; + sp_point_1024* neg = NULL; + int i; + int j; + int k; + sp_table_entry_1024* precomp = (sp_table_entry_1024*)table; + + if (table == NULL) { + *len = sizeof(sp_table_entry_1024) * 1167; + err = LENGTH_ONLY_E; + } + + if ((err == MP_OKAY) && + (*len < (int)(sizeof(sp_table_entry_1024) * 1167))) { + err = BUFFER_E; + } + + if (err == MP_OKAY) { + err = sp_1024_point_new_18(NULL, pd, p); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_18(NULL, cd, c); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_18(NULL, negd, neg); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6 * 18 * 2 + 16 * sizeof(sp_point_1024), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + pre_p = (sp_point_1024*)(td + 6 * 18 * 2); +#endif + + sp_1024_point_from_ecc_point_18(p, pm); + + err = sp_1024_mod_mul_norm_18(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_18(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(p->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + neg->infinity = 0; + c->infinity = 0; + + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMCPY(&pre_p[0], p, sizeof(sp_point_1024)); + /* [2]P for adding */ + sp_1024_proj_point_dbl_18(c, p, t); + + /* 1, 3, ... */ + for (i = 1; i < 16; i++) { + sp_1024_proj_point_add_18(&pre_p[i], &pre_p[i-1], c, t); + sp_1024_mont_map_18(&pre_p[i], t); + } + + k = 0; + j = sp_1024_order_op_pre[0] / 2; + XMEMCPY(c, &pre_p[j], sizeof(sp_point_1024)); + + for (j = 0; j < sp_1024_order_op_pre[1]; j++) { + sp_1024_accum_dbl_calc_lc_18(precomp[k].x, precomp[k].y, c->x, c->y, t); + k++; + sp_1024_proj_point_dbl_18(c, c, t); + sp_1024_mont_map_18(c, t); + } + + for (i = 2; i < 290; i += 2) { + j = sp_1024_order_op_pre[i]; + if (j > 0) { + sp_1024_accum_add_calc_lc_18(precomp[k].x, precomp[k].y, + pre_p[j/2].x, pre_p[j/2].y, c->x, c->y, t); + k++; + sp_1024_proj_point_add_18(c, c, &pre_p[j/2], t); + sp_1024_mont_map_18(c, t); + } + else { + XMEMCPY(neg->x, pre_p[-j / 2].x, sizeof(pre_p->x)); + sp_1024_mont_sub_18(neg->y, p1024_mod, pre_p[-j / 2].y, + p1024_mod); + XMEMCPY(neg->z, pre_p[-j / 2].z, sizeof(pre_p->z)); + + sp_1024_accum_add_calc_lc_18(precomp[k].x, precomp[k].y, + neg->x, neg->y, c->x, c->y, t); + k++; + sp_1024_proj_point_add_18(c, c, neg, t); + sp_1024_mont_map_18(c, t); + } + + for (j = 0; j < sp_1024_order_op_pre[i + 1]; j++) { + sp_1024_accum_dbl_calc_lc_18(precomp[k].x, precomp[k].y, c->x, c->y, t); + k++; + sp_1024_proj_point_dbl_18(c, c, t); + sp_1024_mont_map_18(c, t); + } + } + + *len = sizeof(sp_table_entry_1024) * 1167; + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_18(neg, 1, NULL); + sp_1024_point_free_18(c, 1, NULL); + sp_1024_point_free_18(p, 1, NULL); + return err; +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * Pre-generate values in window (1, 3, ...) - only V. + * Table contains all gradient l and a constant for each point on the path. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @param [in] table Precomputed table of values. + * @param [in] len Length of precomputed table of values in bytes. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int sp_Pairing_precomp_1024(const ecc_point* pm, const ecc_point* qm, + mp_int* res, const byte* table, word32 len) +{ + int err = 0; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit (*pre_vx)[36]; + sp_digit (*pre_vy)[36]; + sp_digit (*pre_nvy)[36]; +#else + sp_digit t[6 * 2 * 18]; + sp_digit vx[2 * 18]; + sp_digit vy[2 * 18]; + sp_digit pre_vx[16][36]; + sp_digit pre_vy[16][36]; + sp_digit pre_nvy[16][36]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + int j; + int k; + const sp_table_entry_1024* precomp = (const sp_table_entry_1024*)table; + + if (len < (int)(sizeof(sp_table_entry_1024) * 1167)) { + err = BUFFER_E; + } + + if (err == MP_OKAY) { + err = sp_1024_point_new_18(NULL, pd, p); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_18(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_18(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 56 * 18 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 18 * 2; + vy = td + 7 * 18 * 2; + pre_vx = (sp_digit(*)[36])(td + 8 * 18 * 2); + pre_vy = (sp_digit(*)[36])(td + 24 * 18 * 2); + pre_nvy = (sp_digit(*)[36])(td + 40 * 18 * 2); +#endif + r = vy; + + sp_1024_point_from_ecc_point_18(p, pm); + sp_1024_point_from_ecc_point_18(q, qm); + + err = sp_1024_mod_mul_norm_18(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_18(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_18(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_18(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_18(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMSET(pre_vx[0], 0, sizeof(sp_digit) * 2 * 18); + pre_vx[0][0] = 1; + XMEMSET(pre_vy[0], 0, sizeof(sp_digit) * 2 * 18); + sp_1024_mont_sub_18(pre_nvy[0], p1024_mod, pre_vy[0], p1024_mod); + + /* [2]P for adding */ + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 18); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 18); + sp_1024_accumulate_line_dbl_18(vx, vy, c, q, t); + + /* 3, 5, ... */ + for (i = 1; i < 16; i++) { + XMEMCPY(pre_vx[i], pre_vx[i-1], sizeof(sp_digit) * 2 * 18); + XMEMCPY(pre_vy[i], pre_vy[i-1], sizeof(sp_digit) * 2 * 18); + sp_1024_proj_mul_18(pre_vx[i], pre_vy[i], vx, vy, t); + sp_1024_accumulate_line_add_n_18(pre_vx[i], pre_vy[i], c, + q, p, t, 0); + sp_1024_mont_sub_18(pre_nvy[i], p1024_mod, pre_vy[i], + p1024_mod); + } + + XMEMCPY(c->z, p1024_norm_mod, sizeof(sp_digit) * 18); + c->infinity = 0; + j = sp_1024_order_op_pre[0] / 2; + XMEMCPY(vx, pre_vx[j], sizeof(sp_digit) * 2 * 18); + XMEMCPY(vy, pre_vy[j], sizeof(sp_digit) * 2 * 18); + + k = 0; + for (j = 0; j < sp_1024_order_op_pre[1]; j++) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_lc_18(vx, vy, precomp[k].x, + precomp[k].y, q, t, 1); + k++; + } + + for (i = 2; i < 290; i += 2) { + sp_1024_accumulate_line_lc_18(vx, vy, precomp[k].x, + precomp[k].y, q, t, 0); + k++; + + j = sp_1024_order_op_pre[i]; + if (j > 0) { + j /= 2; + /* Accumulate line into v. */ + sp_1024_proj_mul_18(vx, vy, pre_vx[j], pre_vy[j], t); + } + else { + j = -j / 2; + /* Accumulate line into v. */ + sp_1024_proj_mul_18(vx, vy, pre_vx[j], pre_nvy[j], t); + } + + for (j = 0; j < sp_1024_order_op_pre[i + 1]; j++) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_lc_18(vx, vy, precomp[k].x, + precomp[k].y, q, t, 1); + k++; + } + } + + /* Final exponentiation */ + sp_1024_proj_sqr_18(vx, vy, t); + sp_1024_proj_sqr_18(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_18(vx, vx, t); + sp_1024_mont_mul_18(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 18, 0, sizeof(sp_digit) * 18); + sp_1024_mont_reduce_18(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_18(c, 1, NULL); + sp_1024_point_free_18(q, 1, NULL); + sp_1024_point_free_18(p, 1, NULL); + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Returns 1 if the number of zero. + * Implementation is constant time. + * + * a Number to check. + * returns 1 if the number is zero and 0 otherwise. + */ +static int sp_1024_iszero_18(const sp_digit* a) +{ + return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6] | a[7] | + a[8] | a[9] | a[10] | a[11] | a[12] | a[13] | a[14] | a[15] | + a[16] | a[17]) == 0; +} + +#ifdef HAVE_ECC_CHECK_KEY +/* Read big endian unsigned byte array into r. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a Byte array. + * n Number of bytes in array to read. + */ +static void sp_1024_from_bin(sp_digit* r, int size, const byte* a, int n) +{ + int i; + int j = 0; + word32 s = 0; + + r[0] = 0; + for (i = n-1; i >= 0; i--) { + r[j] |= (((sp_digit)a[i]) << s); + if (s >= 49U) { + r[j] &= 0x1ffffffffffffffL; + s = 57U - s; + if (j + 1 >= size) { + break; + } + r[++j] = (sp_digit)a[i] >> s; + s = 8U - s; + } + else { + s += 8U; + } + } + + for (j++; j < size; j++) { + r[j] = 0; + } +} + +/* Check that the x and y oridinates are a valid point on the curve. + * + * point EC point. + * heap Heap to use if dynamically allocating. + * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is + * not on the curve and MP_OKAY otherwise. + */ +static int sp_1024_ecc_is_point_18(const sp_point_1024* point, + void* heap) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* d = NULL; +#else + sp_digit t1d[2*18]; + sp_digit t2d[2*18]; +#endif + sp_digit* t1; + sp_digit* t2; + int64_t n; + int err = MP_OKAY; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18 * 4, heap, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + (void)heap; + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t1 = d + 0 * 18; + t2 = d + 2 * 18; +#else + t1 = t1d; + t2 = t2d; +#endif + + sp_1024_sqr_18(t1, point->y); + (void)sp_1024_mod_18(t1, t1, p1024_mod); + sp_1024_sqr_18(t2, point->x); + (void)sp_1024_mod_18(t2, t2, p1024_mod); + sp_1024_mul_18(t2, t2, point->x); + (void)sp_1024_mod_18(t2, t2, p1024_mod); + (void)sp_1024_sub_18(t2, p1024_mod, t2); + sp_1024_mont_add_18(t1, t1, t2, p1024_mod); + + sp_1024_mont_add_18(t1, t1, point->x, p1024_mod); + sp_1024_mont_add_18(t1, t1, point->x, p1024_mod); + sp_1024_mont_add_18(t1, t1, point->x, p1024_mod); + + n = sp_1024_cmp_18(t1, p1024_mod); + sp_1024_cond_sub_18(t1, t1, p1024_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_18(t1); + if (!sp_1024_iszero_18(t1)) { + err = MP_VAL; + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (d != NULL) { + XFREE(d, heap, DYNAMIC_TYPE_ECC); + } +#endif + + return err; +} + +/* Check that the x and y oridinates are a valid point on the curve. + * + * pX X ordinate of EC point. + * pY Y ordinate of EC point. + * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is + * not on the curve and MP_OKAY otherwise. + */ +int sp_ecc_is_point_1024(const mp_int* pX, const mp_int* pY) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 pubd; +#endif + sp_point_1024* pub; + byte one[1] = { 1 }; + int err; + + err = sp_1024_point_new_18(NULL, pubd, pub); + if (err == MP_OKAY) { + sp_1024_from_mp(pub->x, 18, pX); + sp_1024_from_mp(pub->y, 18, pY); + sp_1024_from_bin(pub->z, 18, one, (int)sizeof(one)); + + err = sp_1024_ecc_is_point_18(pub, NULL); + } + + sp_1024_point_free_18(pub, 0, NULL); + + return err; +} + +/* Check that the private scalar generates the EC point (px, py), the point is + * on the curve and the point has the correct order. + * + * pX X ordinate of EC point. + * pY Y ordinate of EC point. + * privm Private scalar that generates EC point. + * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is + * not on the curve, ECC_INF_E if the point does not have the correct order, + * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and + * MP_OKAY otherwise. + */ +int sp_ecc_check_key_1024(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_digit privd[18]; + sp_point_1024 pubd; + sp_point_1024 pd; +#endif + sp_digit* priv = NULL; + sp_point_1024* pub; + sp_point_1024* p = NULL; + byte one[1] = { 1 }; + int err; + + err = sp_1024_point_new_18(heap, pubd, pub); + if (err == MP_OKAY) { + err = sp_1024_point_new_18(heap, pd, p); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY && privm) { + priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18, heap, + DYNAMIC_TYPE_ECC); + if (priv == NULL) { + err = MEMORY_E; + } + } +#endif + + /* Quick check the lengs of public key ordinates and private key are in + * range. Proper check later. + */ + if ((err == MP_OKAY) && ((mp_count_bits(pX) > 1024) || + (mp_count_bits(pY) > 1024) || + ((privm != NULL) && (mp_count_bits(privm) > 1024)))) { + err = ECC_OUT_OF_RANGE_E; + } + + if (err == MP_OKAY) { +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + priv = privd; +#endif + + sp_1024_from_mp(pub->x, 18, pX); + sp_1024_from_mp(pub->y, 18, pY); + sp_1024_from_bin(pub->z, 18, one, (int)sizeof(one)); + if (privm) + sp_1024_from_mp(priv, 18, privm); + + /* Check point at infinitiy. */ + if ((sp_1024_iszero_18(pub->x) != 0) && + (sp_1024_iszero_18(pub->y) != 0)) { + err = ECC_INF_E; + } + } + + /* Check range of X and Y */ + if ((err == MP_OKAY) && + ((sp_1024_cmp_18(pub->x, p1024_mod) >= 0) || + (sp_1024_cmp_18(pub->y, p1024_mod) >= 0))) { + err = ECC_OUT_OF_RANGE_E; + } + + if (err == MP_OKAY) { + /* Check point is on curve */ + err = sp_1024_ecc_is_point_18(pub, heap); + } + + if (err == MP_OKAY) { + /* Point * order = infinity */ + err = sp_1024_ecc_mulmod_18(p, pub, p1024_order, 1, 1, heap); + } + /* Check result is infinity */ + if ((err == MP_OKAY) && ((sp_1024_iszero_18(p->x) == 0) || + (sp_1024_iszero_18(p->y) == 0))) { + err = ECC_INF_E; + } + + if (privm) { + if (err == MP_OKAY) { + /* Base * private = point */ + err = sp_1024_ecc_mulmod_base_18(p, priv, 1, 1, heap); + } + /* Check result is public key */ + if ((err == MP_OKAY) && + ((sp_1024_cmp_18(p->x, pub->x) != 0) || + (sp_1024_cmp_18(p->y, pub->y) != 0))) { + err = ECC_PRIV_KEY_E; + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (priv != NULL) { + XFREE(priv, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_18(p, 0, heap); + sp_1024_point_free_18(pub, 0, heap); + + return err; +} +#endif +#endif /* WOLFSSL_SP_1024 */ #endif /* WOLFSSL_HAVE_SP_ECC */ #endif /* SP_WORD_SIZE == 64 */ #endif /* !WOLFSSL_SP_ASM */ -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH || WOLFSSL_HAVE_SP_ECC */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH | WOLFSSL_HAVE_SP_ECC */ diff --git a/wolfcrypt/src/sp_cortexm.c b/wolfcrypt/src/sp_cortexm.c index 45310f711..ff357fdb5 100644 --- a/wolfcrypt/src/sp_cortexm.c +++ b/wolfcrypt/src/sp_cortexm.c @@ -1,6 +1,6 @@ /* sp.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -67,7 +67,8 @@ */ static void sp_2048_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -109,7 +110,8 @@ static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 32 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -143,7 +145,9 @@ static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -182,7 +186,10 @@ static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a) */ static void sp_2048_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; j = 2048 / 8 - 1; a[j] = 0; @@ -1277,7 +1284,9 @@ SP_NOINLINE static void sp_2048_mul_16(sp_digit* r, const sp_digit* a, sp_digit a1[8]; sp_digit b1[8]; sp_digit z2[16]; - sp_digit u, ca, cb; + sp_digit u; + sp_digit ca; + sp_digit cb; ca = sp_2048_add_8(a1, a, &a[8]); cb = sp_2048_add_8(b1, b, &b[8]); @@ -1570,7 +1579,9 @@ SP_NOINLINE static void sp_2048_mul_32(sp_digit* r, const sp_digit* a, sp_digit a1[16]; sp_digit b1[16]; sp_digit z2[32]; - sp_digit u, ca, cb; + sp_digit u; + sp_digit ca; + sp_digit cb; ca = sp_2048_add_16(a1, a, &a[16]); cb = sp_2048_add_16(b1, b, &b[16]); @@ -2023,7 +2034,9 @@ SP_NOINLINE static void sp_2048_mul_64(sp_digit* r, const sp_digit* a, sp_digit a1[32]; sp_digit b1[32]; sp_digit z2[64]; - sp_digit u, ca, cb; + sp_digit u; + sp_digit ca; + sp_digit cb; ca = sp_2048_add_32(a1, a, &a[32]); cb = sp_2048_add_32(b1, b, &b[32]); @@ -2692,7 +2705,7 @@ SP_NOINLINE static void sp_2048_sqr_32(sp_digit* r, const sp_digit* a) } #endif /* WOLFSSL_SP_SMALL */ -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ /* Caclulate the bottom digit of -1/a mod 2^n. * @@ -2701,7 +2714,8 @@ SP_NOINLINE static void sp_2048_sqr_32(sp_digit* r, const sp_digit* a) */ static void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho) { - sp_digit x, b; + sp_digit x; + sp_digit b; b = a[0]; x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ @@ -2710,7 +2724,7 @@ static void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho) x *= 2 - b * x; /* here x*a==1 mod 2**32 */ /* rho = -1/m mod b */ - *rho = -x; + *rho = (sp_digit)0 - x; } /* Mul a by digit b into r. (r = a * b) @@ -2922,8 +2936,8 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_2048_mont_mul_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_2048_mul_32(r, a, b); sp_2048_mont_reduce_32(r, m, mp); @@ -2936,8 +2950,8 @@ static void sp_2048_mont_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_sqr_32(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_2048_mont_sqr_32(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_2048_sqr_32(r, a); sp_2048_mont_reduce_32(r, m, mp); @@ -3159,7 +3173,8 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -3225,34 +3240,34 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 32); for (; i>=0 || c>=4; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 28); + y = (byte)(n >> 28); n <<= 4; c = 28; } else if (c < 4) { - y = (int)(n >> 28); + y = (byte)(n >> 28); n = e[i--]; c = 4 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 28) & 0xf); + y = (byte)((n >> 28) & 0xf); n <<= 4; c -= 4; } @@ -3304,7 +3319,8 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -3386,34 +3402,34 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 32); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -3444,7 +3460,7 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, } #endif /* WOLFSSL_SP_SMALL */ -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) /* r = 2^n mod m where n is the number of bits to reduce by. @@ -3461,7 +3477,7 @@ static void sp_2048_mont_norm_64(sp_digit* r, const sp_digit* m) sp_2048_sub_in_place_64(r, m); } -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */ /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -3615,8 +3631,8 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_mul_64(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_2048_mont_mul_64(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_2048_mul_64(r, a, b); sp_2048_mont_reduce_64(r, m, mp); @@ -3629,8 +3645,8 @@ static void sp_2048_mont_mul_64(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_sqr_64(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_2048_mont_sqr_64(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_2048_sqr_64(r, a); sp_2048_mont_reduce_64(r, m, mp); @@ -3894,7 +3910,8 @@ static int sp_2048_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -3960,34 +3977,34 @@ static int sp_2048_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 64); for (; i>=0 || c>=4; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 28); + y = (byte)(n >> 28); n <<= 4; c = 28; } else if (c < 4) { - y = (int)(n >> 28); + y = (byte)(n >> 28); n = e[i--]; c = 4 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 28) & 0xf); + y = (byte)((n >> 28) & 0xf); n <<= 4; c -= 4; } @@ -4039,7 +4056,8 @@ static int sp_2048_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -4121,34 +4139,34 @@ static int sp_2048_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 64); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -4193,11 +4211,13 @@ static int sp_2048_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPublic_2048(const byte* in, word32 inLen, const mp_int* em, + const mp_int* mm, byte* out, word32* outLen) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_digit a[128], m[64], r[128]; + sp_digit a[128]; + sp_digit m[64]; + sp_digit r[128]; #else sp_digit* d = NULL; sp_digit* a = NULL; @@ -4375,9 +4395,9 @@ SP_NOINLINE static sp_digit sp_2048_cond_add_32(sp_digit* r, const sp_digit* a, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_2048(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM) sp_digit* a = NULL; @@ -4441,8 +4461,11 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, #else #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit a[64 * 2]; - sp_digit p[32], q[32], dp[32]; - sp_digit tmpa[64], tmpb[64]; + sp_digit p[32]; + sp_digit q[32]; + sp_digit dp[32]; + sp_digit tmpa[64]; + sp_digit tmpb[64]; #else sp_digit* t = NULL; sp_digit* a = NULL; @@ -4539,7 +4562,7 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, XMEMSET(q, 0, sizeof(q)); XMEMSET(dp, 0, sizeof(dp)); #endif -#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */ +#endif /* SP_RSA_PRIVATE_EXP_D | RSA_LOW_MEM */ return err; } #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -4562,17 +4585,19 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->used = 64; mp_clamp(r); #elif DIGIT_BIT < 32 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 64; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -4585,14 +4610,16 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 64; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 32 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -4619,10 +4646,13 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_2048(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[128], e[64], m[64]; + sp_digit b[128]; + sp_digit e[64]; + sp_digit m[64]; sp_digit* r = b; int expBits = mp_count_bits(exp); @@ -5081,10 +5111,12 @@ static int sp_2048_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits, sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -5119,34 +5151,34 @@ static int sp_2048_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } - sp_2048_lshift_64(r, norm, (byte)y); + sp_2048_lshift_64(r, norm, y); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -5157,7 +5189,7 @@ static int sp_2048_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits, sp_2048_mont_sqr_64(r, r, m, mp); sp_2048_mont_sqr_64(r, r, m, mp); - sp_2048_lshift_64(r, r, (byte)y); + sp_2048_lshift_64(r, r, y); sp_2048_mul_d_64(tmp, norm, r[64]); r[64] = 0; o = sp_2048_add_64(r, r, tmp); @@ -5193,11 +5225,13 @@ static int sp_2048_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, - mp_int* mod, byte* out, word32* outLen) +int sp_DhExp_2048(const mp_int* base, const byte* exp, word32 expLen, + const mp_int* mod, byte* out, word32* outLen) { int err = MP_OKAY; - sp_digit b[128], e[64], m[64]; + sp_digit b[128]; + sp_digit e[64]; + sp_digit m[64]; sp_digit* r = b; word32 i; @@ -5232,6 +5266,7 @@ int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, sp_2048_to_bin(r, out); *outLen = 256; for (i=0; i<256 && out[i] == 0; i++) { + /* Search for first non-zero. */ } *outLen -= i; XMEMMOVE(out, out + i, *outLen); @@ -5253,10 +5288,13 @@ int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_1024(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[64], e[32], m[32]; + sp_digit b[64]; + sp_digit e[32]; + sp_digit m[32]; sp_digit* r = b; int expBits = mp_count_bits(exp); @@ -5293,7 +5331,7 @@ int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) return err; } -#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */ +#endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */ #endif /* !WOLFSSL_SP_NO_2048 */ @@ -5307,7 +5345,8 @@ int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) */ static void sp_3072_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -5349,7 +5388,8 @@ static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 32 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -5383,7 +5423,9 @@ static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -5422,7 +5464,10 @@ static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a) */ static void sp_3072_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; j = 3072 / 8 - 1; a[j] = 0; @@ -5920,7 +5965,9 @@ SP_NOINLINE static void sp_3072_mul_24(sp_digit* r, const sp_digit* a, sp_digit a1[12]; sp_digit b1[12]; sp_digit z2[24]; - sp_digit u, ca, cb; + sp_digit u; + sp_digit ca; + sp_digit cb; ca = sp_3072_add_12(a1, a, &a[12]); cb = sp_3072_add_12(b1, b, &b[12]); @@ -6293,7 +6340,9 @@ SP_NOINLINE static void sp_3072_mul_48(sp_digit* r, const sp_digit* a, sp_digit a1[24]; sp_digit b1[24]; sp_digit z2[48]; - sp_digit u, ca, cb; + sp_digit u; + sp_digit ca; + sp_digit cb; ca = sp_3072_add_24(a1, a, &a[24]); cb = sp_3072_add_24(b1, b, &b[24]); @@ -6906,7 +6955,9 @@ SP_NOINLINE static void sp_3072_mul_96(sp_digit* r, const sp_digit* a, sp_digit a1[48]; sp_digit b1[48]; sp_digit z2[96]; - sp_digit u, ca, cb; + sp_digit u; + sp_digit ca; + sp_digit cb; ca = sp_3072_add_48(a1, a, &a[48]); cb = sp_3072_add_48(b1, b, &b[48]); @@ -7589,7 +7640,7 @@ SP_NOINLINE static void sp_3072_sqr_48(sp_digit* r, const sp_digit* a) } #endif /* WOLFSSL_SP_SMALL */ -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ /* Caclulate the bottom digit of -1/a mod 2^n. * @@ -7598,7 +7649,8 @@ SP_NOINLINE static void sp_3072_sqr_48(sp_digit* r, const sp_digit* a) */ static void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho) { - sp_digit x, b; + sp_digit x; + sp_digit b; b = a[0]; x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ @@ -7607,7 +7659,7 @@ static void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho) x *= 2 - b * x; /* here x*a==1 mod 2**32 */ /* rho = -1/m mod b */ - *rho = -x; + *rho = (sp_digit)0 - x; } /* Mul a by digit b into r. (r = a * b) @@ -7819,8 +7871,8 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_mul_48(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_3072_mont_mul_48(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_3072_mul_48(r, a, b); sp_3072_mont_reduce_48(r, m, mp); @@ -7833,8 +7885,8 @@ static void sp_3072_mont_mul_48(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_sqr_48(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_3072_mont_sqr_48(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_3072_sqr_48(r, a); sp_3072_mont_reduce_48(r, m, mp); @@ -8056,7 +8108,8 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -8122,34 +8175,34 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 48); for (; i>=0 || c>=4; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 28); + y = (byte)(n >> 28); n <<= 4; c = 28; } else if (c < 4) { - y = (int)(n >> 28); + y = (byte)(n >> 28); n = e[i--]; c = 4 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 28) & 0xf); + y = (byte)((n >> 28) & 0xf); n <<= 4; c -= 4; } @@ -8201,7 +8254,8 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -8283,34 +8337,34 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 48); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -8341,7 +8395,7 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, } #endif /* WOLFSSL_SP_SMALL */ -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) /* r = 2^n mod m where n is the number of bits to reduce by. @@ -8358,7 +8412,7 @@ static void sp_3072_mont_norm_96(sp_digit* r, const sp_digit* m) sp_3072_sub_in_place_96(r, m); } -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */ /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -8513,8 +8567,8 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_mul_96(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_3072_mont_mul_96(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_3072_mul_96(r, a, b); sp_3072_mont_reduce_96(r, m, mp); @@ -8527,8 +8581,8 @@ static void sp_3072_mont_mul_96(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_sqr_96(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_3072_mont_sqr_96(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_3072_sqr_96(r, a); sp_3072_mont_reduce_96(r, m, mp); @@ -8794,7 +8848,8 @@ static int sp_3072_mod_exp_96(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -8860,34 +8915,34 @@ static int sp_3072_mod_exp_96(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 96); for (; i>=0 || c>=4; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 28); + y = (byte)(n >> 28); n <<= 4; c = 28; } else if (c < 4) { - y = (int)(n >> 28); + y = (byte)(n >> 28); n = e[i--]; c = 4 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 28) & 0xf); + y = (byte)((n >> 28) & 0xf); n <<= 4; c -= 4; } @@ -8939,7 +8994,8 @@ static int sp_3072_mod_exp_96(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -9021,34 +9077,34 @@ static int sp_3072_mod_exp_96(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 96); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -9093,11 +9149,13 @@ static int sp_3072_mod_exp_96(sp_digit* r, const sp_digit* a, const sp_digit* e, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPublic_3072(const byte* in, word32 inLen, const mp_int* em, + const mp_int* mm, byte* out, word32* outLen) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_digit a[192], m[96], r[192]; + sp_digit a[192]; + sp_digit m[96]; + sp_digit r[192]; #else sp_digit* d = NULL; sp_digit* a = NULL; @@ -9275,9 +9333,9 @@ SP_NOINLINE static sp_digit sp_3072_cond_add_48(sp_digit* r, const sp_digit* a, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_3072(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM) sp_digit* a = NULL; @@ -9341,8 +9399,11 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, #else #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit a[96 * 2]; - sp_digit p[48], q[48], dp[48]; - sp_digit tmpa[96], tmpb[96]; + sp_digit p[48]; + sp_digit q[48]; + sp_digit dp[48]; + sp_digit tmpa[96]; + sp_digit tmpb[96]; #else sp_digit* t = NULL; sp_digit* a = NULL; @@ -9439,7 +9500,7 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, XMEMSET(q, 0, sizeof(q)); XMEMSET(dp, 0, sizeof(dp)); #endif -#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */ +#endif /* SP_RSA_PRIVATE_EXP_D | RSA_LOW_MEM */ return err; } #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -9462,17 +9523,19 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->used = 96; mp_clamp(r); #elif DIGIT_BIT < 32 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 96; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -9485,14 +9548,16 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 96; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 32 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -9519,10 +9584,13 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_3072(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[192], e[96], m[96]; + sp_digit b[192]; + sp_digit e[96]; + sp_digit m[96]; sp_digit* r = b; int expBits = mp_count_bits(exp); @@ -10177,10 +10245,12 @@ static int sp_3072_mod_exp_2_96(sp_digit* r, const sp_digit* e, int bits, sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -10215,34 +10285,34 @@ static int sp_3072_mod_exp_2_96(sp_digit* r, const sp_digit* e, int bits, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } - sp_3072_lshift_96(r, norm, (byte)y); + sp_3072_lshift_96(r, norm, y); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -10253,7 +10323,7 @@ static int sp_3072_mod_exp_2_96(sp_digit* r, const sp_digit* e, int bits, sp_3072_mont_sqr_96(r, r, m, mp); sp_3072_mont_sqr_96(r, r, m, mp); - sp_3072_lshift_96(r, r, (byte)y); + sp_3072_lshift_96(r, r, y); sp_3072_mul_d_96(tmp, norm, r[96]); r[96] = 0; o = sp_3072_add_96(r, r, tmp); @@ -10289,11 +10359,13 @@ static int sp_3072_mod_exp_2_96(sp_digit* r, const sp_digit* e, int bits, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, - mp_int* mod, byte* out, word32* outLen) +int sp_DhExp_3072(const mp_int* base, const byte* exp, word32 expLen, + const mp_int* mod, byte* out, word32* outLen) { int err = MP_OKAY; - sp_digit b[192], e[96], m[96]; + sp_digit b[192]; + sp_digit e[96]; + sp_digit m[96]; sp_digit* r = b; word32 i; @@ -10328,6 +10400,7 @@ int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, sp_3072_to_bin(r, out); *outLen = 384; for (i=0; i<384 && out[i] == 0; i++) { + /* Search for first non-zero. */ } *outLen -= i; XMEMMOVE(out, out + i, *outLen); @@ -10349,10 +10422,13 @@ int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_1536(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[96], e[48], m[48]; + sp_digit b[96]; + sp_digit e[48]; + sp_digit m[48]; sp_digit* r = b; int expBits = mp_count_bits(exp); @@ -10389,7 +10465,7 @@ int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) return err; } -#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */ +#endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */ #endif /* !WOLFSSL_SP_NO_3072 */ @@ -10403,7 +10479,8 @@ int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) */ static void sp_4096_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -10445,7 +10522,8 @@ static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 32 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -10479,7 +10557,9 @@ static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -10518,7 +10598,10 @@ static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a) */ static void sp_4096_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; j = 4096 / 8 - 1; a[j] = 0; @@ -11245,7 +11328,9 @@ SP_NOINLINE static void sp_4096_mul_128(sp_digit* r, const sp_digit* a, sp_digit a1[64]; sp_digit b1[64]; sp_digit z2[128]; - sp_digit u, ca, cb; + sp_digit u; + sp_digit ca; + sp_digit cb; ca = sp_2048_add_64(a1, a, &a[64]); cb = sp_2048_add_64(b1, b, &b[64]); @@ -11609,7 +11694,8 @@ SP_NOINLINE static void sp_4096_sqr_128(sp_digit* r, const sp_digit* a) */ static void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho) { - sp_digit x, b; + sp_digit x; + sp_digit b; b = a[0]; x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ @@ -11618,7 +11704,7 @@ static void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho) x *= 2 - b * x; /* here x*a==1 mod 2**32 */ /* rho = -1/m mod b */ - *rho = -x; + *rho = (sp_digit)0 - x; } /* Mul a by digit b into r. (r = a * b) @@ -11678,7 +11764,7 @@ static void sp_4096_mont_norm_128(sp_digit* r, const sp_digit* m) sp_4096_sub_in_place_128(r, m); } -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */ /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -11832,8 +11918,8 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_4096_mont_mul_128(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_4096_mont_mul_128(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_4096_mul_128(r, a, b); sp_4096_mont_reduce_128(r, m, mp); @@ -11846,8 +11932,8 @@ static void sp_4096_mont_mul_128(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_4096_mont_sqr_128(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_4096_mont_sqr_128(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_4096_sqr_128(r, a); sp_4096_mont_reduce_128(r, m, mp); @@ -12113,7 +12199,8 @@ static int sp_4096_mod_exp_128(sp_digit* r, const sp_digit* a, const sp_digit* e sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -12179,34 +12266,34 @@ static int sp_4096_mod_exp_128(sp_digit* r, const sp_digit* a, const sp_digit* e if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 128); for (; i>=0 || c>=4; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 28); + y = (byte)(n >> 28); n <<= 4; c = 28; } else if (c < 4) { - y = (int)(n >> 28); + y = (byte)(n >> 28); n = e[i--]; c = 4 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 28) & 0xf); + y = (byte)((n >> 28) & 0xf); n <<= 4; c -= 4; } @@ -12258,7 +12345,8 @@ static int sp_4096_mod_exp_128(sp_digit* r, const sp_digit* a, const sp_digit* e sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -12340,34 +12428,34 @@ static int sp_4096_mod_exp_128(sp_digit* r, const sp_digit* a, const sp_digit* e if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 128); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -12412,11 +12500,13 @@ static int sp_4096_mod_exp_128(sp_digit* r, const sp_digit* a, const sp_digit* e * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPublic_4096(const byte* in, word32 inLen, const mp_int* em, + const mp_int* mm, byte* out, word32* outLen) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_digit a[256], m[128], r[256]; + sp_digit a[256]; + sp_digit m[128]; + sp_digit r[256]; #else sp_digit* d = NULL; sp_digit* a = NULL; @@ -12595,9 +12685,9 @@ SP_NOINLINE static sp_digit sp_4096_cond_add_64(sp_digit* r, const sp_digit* a, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_4096(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM) sp_digit* a = NULL; @@ -12661,8 +12751,11 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, #else #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit a[128 * 2]; - sp_digit p[64], q[64], dp[64]; - sp_digit tmpa[128], tmpb[128]; + sp_digit p[64]; + sp_digit q[64]; + sp_digit dp[64]; + sp_digit tmpa[128]; + sp_digit tmpb[128]; #else sp_digit* t = NULL; sp_digit* a = NULL; @@ -12759,7 +12852,7 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, XMEMSET(q, 0, sizeof(q)); XMEMSET(dp, 0, sizeof(dp)); #endif -#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */ +#endif /* SP_RSA_PRIVATE_EXP_D | RSA_LOW_MEM */ return err; } #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -12782,17 +12875,19 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->used = 128; mp_clamp(r); #elif DIGIT_BIT < 32 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 128; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -12805,14 +12900,16 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 128; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 32 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -12839,10 +12936,13 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_4096(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[256], e[128], m[128]; + sp_digit b[256]; + sp_digit e[128]; + sp_digit m[128]; sp_digit* r = b; int expBits = mp_count_bits(exp); @@ -13693,10 +13793,12 @@ static int sp_4096_mod_exp_2_128(sp_digit* r, const sp_digit* e, int bits, sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -13731,34 +13833,34 @@ static int sp_4096_mod_exp_2_128(sp_digit* r, const sp_digit* e, int bits, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 32 - c; } - sp_4096_lshift_128(r, norm, (byte)y); + sp_4096_lshift_128(r, norm, y); for (; i>=0 || c>=5; ) { if (c == 0) { n = e[i--]; - y = (int)(n >> 27); + y = (byte)(n >> 27); n <<= 5; c = 27; } else if (c < 5) { - y = (int)(n >> 27); + y = (byte)(n >> 27); n = e[i--]; c = 5 - c; - y |= (int)(n >> (32 - c)); + y |= (byte)(n >> (32 - c)); n <<= c; c = 32 - c; } else { - y = (int)((n >> 27) & 0x1f); + y = (byte)((n >> 27) & 0x1f); n <<= 5; c -= 5; } @@ -13769,7 +13871,7 @@ static int sp_4096_mod_exp_2_128(sp_digit* r, const sp_digit* e, int bits, sp_4096_mont_sqr_128(r, r, m, mp); sp_4096_mont_sqr_128(r, r, m, mp); - sp_4096_lshift_128(r, r, (byte)y); + sp_4096_lshift_128(r, r, y); sp_4096_mul_d_128(tmp, norm, r[128]); r[128] = 0; o = sp_4096_add_128(r, r, tmp); @@ -13805,11 +13907,13 @@ static int sp_4096_mod_exp_2_128(sp_digit* r, const sp_digit* e, int bits, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, - mp_int* mod, byte* out, word32* outLen) +int sp_DhExp_4096(const mp_int* base, const byte* exp, word32 expLen, + const mp_int* mod, byte* out, word32* outLen) { int err = MP_OKAY; - sp_digit b[256], e[128], m[128]; + sp_digit b[256]; + sp_digit e[128]; + sp_digit m[128]; sp_digit* r = b; word32 i; @@ -13844,6 +13948,7 @@ int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, sp_4096_to_bin(r, out); *outLen = 512; for (i=0; i<512 && out[i] == 0; i++) { + /* Search for first non-zero. */ } *outLen -= i; XMEMMOVE(out, out + i, *outLen); @@ -13856,19 +13961,23 @@ int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, } #endif /* WOLFSSL_HAVE_SP_DH */ -#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */ +#endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */ #endif /* WOLFSSL_SP_4096 */ -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */ #ifdef WOLFSSL_HAVE_SP_ECC #ifndef WOLFSSL_SP_NO_256 /* Point structure to use. */ typedef struct sp_point_256 { + /* X ordinate of point. */ sp_digit x[2 * 8]; + /* Y ordinate of point. */ sp_digit y[2 * 8]; + /* Z ordinate of point. */ sp_digit z[2 * 8]; + /* Indicates point is at infinity. */ int infinity; } sp_point_256; @@ -13938,7 +14047,1056 @@ static const sp_digit p256_b[8] = { }; #endif -static int sp_256_point_new_ex_8(void* heap, sp_point_256* sp, sp_point_256** p) +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static void sp_256_mul_8(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit tmp_arr[8]; + sp_digit* tmp = tmp_arr; + + __asm__ __volatile__ ( + /* A[0] * B[0] */ + "ldr r6, [%[a], #0]\n\t" + "ldr r8, [%[b], #0]\n\t" + "umull r3, r4, r6, r8\n\t" + "mov r5, #0\n\t" + "str r3, [%[tmp], #0]\n\t" + "mov r3, #0\n\t" + /* A[0] * B[1] */ + "ldr r8, [%[b], #4]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adc r5, r5, r8\n\t" + /* A[1] * B[0] */ + "ldr r6, [%[a], #4]\n\t" + "ldr r8, [%[b], #0]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + "str r4, [%[tmp], #4]\n\t" + "mov r4, #0\n\t" + /* A[0] * B[2] */ + "ldr r6, [%[a], #0]\n\t" + "ldr r8, [%[b], #8]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + /* A[1] * B[1] */ + "ldr r6, [%[a], #4]\n\t" + "ldr r8, [%[b], #4]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + /* A[2] * B[0] */ + "ldr r6, [%[a], #8]\n\t" + "ldr r8, [%[b], #0]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + "str r5, [%[tmp], #8]\n\t" + "mov r5, #0\n\t" + /* A[0] * B[3] */ + "ldr r6, [%[a], #0]\n\t" + "ldr r8, [%[b], #12]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + /* A[1] * B[2] */ + "ldr r6, [%[a], #4]\n\t" + "ldr r8, [%[b], #8]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + /* A[2] * B[1] */ + "ldr r6, [%[a], #8]\n\t" + "ldr r8, [%[b], #4]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + /* A[3] * B[0] */ + "ldr r6, [%[a], #12]\n\t" + "ldr r8, [%[b], #0]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + "str r3, [%[tmp], #12]\n\t" + "mov r3, #0\n\t" + /* A[0] * B[4] */ + "ldr r6, [%[a], #0]\n\t" + "ldr r8, [%[b], #16]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + /* A[1] * B[3] */ + "ldr r6, [%[a], #4]\n\t" + "ldr r8, [%[b], #12]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + /* A[2] * B[2] */ + "ldr r6, [%[a], #8]\n\t" + "ldr r8, [%[b], #8]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + /* A[3] * B[1] */ + "ldr r6, [%[a], #12]\n\t" + "ldr r8, [%[b], #4]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + /* A[4] * B[0] */ + "ldr r6, [%[a], #16]\n\t" + "ldr r8, [%[b], #0]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + "str r4, [%[tmp], #16]\n\t" + "mov r4, #0\n\t" + /* A[0] * B[5] */ + "ldr r6, [%[a], #0]\n\t" + "ldr r8, [%[b], #20]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + /* A[1] * B[4] */ + "ldr r6, [%[a], #4]\n\t" + "ldr r8, [%[b], #16]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + /* A[2] * B[3] */ + "ldr r6, [%[a], #8]\n\t" + "ldr r8, [%[b], #12]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + /* A[3] * B[2] */ + "ldr r6, [%[a], #12]\n\t" + "ldr r8, [%[b], #8]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + /* A[4] * B[1] */ + "ldr r6, [%[a], #16]\n\t" + "ldr r8, [%[b], #4]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + /* A[5] * B[0] */ + "ldr r6, [%[a], #20]\n\t" + "ldr r8, [%[b], #0]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + "str r5, [%[tmp], #20]\n\t" + "mov r5, #0\n\t" + /* A[0] * B[6] */ + "ldr r6, [%[a], #0]\n\t" + "ldr r8, [%[b], #24]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + /* A[1] * B[5] */ + "ldr r6, [%[a], #4]\n\t" + "ldr r8, [%[b], #20]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + /* A[2] * B[4] */ + "ldr r6, [%[a], #8]\n\t" + "ldr r8, [%[b], #16]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + /* A[3] * B[3] */ + "ldr r6, [%[a], #12]\n\t" + "ldr r8, [%[b], #12]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + /* A[4] * B[2] */ + "ldr r6, [%[a], #16]\n\t" + "ldr r8, [%[b], #8]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + /* A[5] * B[1] */ + "ldr r6, [%[a], #20]\n\t" + "ldr r8, [%[b], #4]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + /* A[6] * B[0] */ + "ldr r6, [%[a], #24]\n\t" + "ldr r8, [%[b], #0]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + "str r3, [%[tmp], #24]\n\t" + "mov r3, #0\n\t" + /* A[0] * B[7] */ + "ldr r6, [%[a], #0]\n\t" + "ldr r8, [%[b], #28]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + /* A[1] * B[6] */ + "ldr r6, [%[a], #4]\n\t" + "ldr r8, [%[b], #24]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + /* A[2] * B[5] */ + "ldr r6, [%[a], #8]\n\t" + "ldr r8, [%[b], #20]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + /* A[3] * B[4] */ + "ldr r6, [%[a], #12]\n\t" + "ldr r8, [%[b], #16]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + /* A[4] * B[3] */ + "ldr r6, [%[a], #16]\n\t" + "ldr r8, [%[b], #12]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + /* A[5] * B[2] */ + "ldr r6, [%[a], #20]\n\t" + "ldr r8, [%[b], #8]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + /* A[6] * B[1] */ + "ldr r6, [%[a], #24]\n\t" + "ldr r8, [%[b], #4]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + /* A[7] * B[0] */ + "ldr r6, [%[a], #28]\n\t" + "ldr r8, [%[b], #0]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + "str r4, [%[tmp], #28]\n\t" + "mov r4, #0\n\t" + /* A[1] * B[7] */ + "ldr r6, [%[a], #4]\n\t" + "ldr r8, [%[b], #28]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + /* A[2] * B[6] */ + "ldr r6, [%[a], #8]\n\t" + "ldr r8, [%[b], #24]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + /* A[3] * B[5] */ + "ldr r6, [%[a], #12]\n\t" + "ldr r8, [%[b], #20]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + /* A[4] * B[4] */ + "ldr r6, [%[a], #16]\n\t" + "ldr r8, [%[b], #16]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + /* A[5] * B[3] */ + "ldr r6, [%[a], #20]\n\t" + "ldr r8, [%[b], #12]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + /* A[6] * B[2] */ + "ldr r6, [%[a], #24]\n\t" + "ldr r8, [%[b], #8]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + /* A[7] * B[1] */ + "ldr r6, [%[a], #28]\n\t" + "ldr r8, [%[b], #4]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + "str r5, [%[r], #32]\n\t" + "mov r5, #0\n\t" + /* A[2] * B[7] */ + "ldr r6, [%[a], #8]\n\t" + "ldr r8, [%[b], #28]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + /* A[3] * B[6] */ + "ldr r6, [%[a], #12]\n\t" + "ldr r8, [%[b], #24]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + /* A[4] * B[5] */ + "ldr r6, [%[a], #16]\n\t" + "ldr r8, [%[b], #20]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + /* A[5] * B[4] */ + "ldr r6, [%[a], #20]\n\t" + "ldr r8, [%[b], #16]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + /* A[6] * B[3] */ + "ldr r6, [%[a], #24]\n\t" + "ldr r8, [%[b], #12]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + /* A[7] * B[2] */ + "ldr r6, [%[a], #28]\n\t" + "ldr r8, [%[b], #8]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + "str r3, [%[r], #36]\n\t" + "mov r3, #0\n\t" + /* A[3] * B[7] */ + "ldr r6, [%[a], #12]\n\t" + "ldr r8, [%[b], #28]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + /* A[4] * B[6] */ + "ldr r6, [%[a], #16]\n\t" + "ldr r8, [%[b], #24]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + /* A[5] * B[5] */ + "ldr r6, [%[a], #20]\n\t" + "ldr r8, [%[b], #20]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + /* A[6] * B[4] */ + "ldr r6, [%[a], #24]\n\t" + "ldr r8, [%[b], #16]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + /* A[7] * B[3] */ + "ldr r6, [%[a], #28]\n\t" + "ldr r8, [%[b], #12]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + "str r4, [%[r], #40]\n\t" + "mov r4, #0\n\t" + /* A[4] * B[7] */ + "ldr r6, [%[a], #16]\n\t" + "ldr r8, [%[b], #28]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + /* A[5] * B[6] */ + "ldr r6, [%[a], #20]\n\t" + "ldr r8, [%[b], #24]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + /* A[6] * B[5] */ + "ldr r6, [%[a], #24]\n\t" + "ldr r8, [%[b], #20]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + /* A[7] * B[4] */ + "ldr r6, [%[a], #28]\n\t" + "ldr r8, [%[b], #16]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + "str r5, [%[r], #44]\n\t" + "mov r5, #0\n\t" + /* A[5] * B[7] */ + "ldr r6, [%[a], #20]\n\t" + "ldr r8, [%[b], #28]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + /* A[6] * B[6] */ + "ldr r6, [%[a], #24]\n\t" + "ldr r8, [%[b], #24]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + /* A[7] * B[5] */ + "ldr r6, [%[a], #28]\n\t" + "ldr r8, [%[b], #20]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + "str r3, [%[r], #48]\n\t" + "mov r3, #0\n\t" + /* A[6] * B[7] */ + "ldr r6, [%[a], #24]\n\t" + "ldr r8, [%[b], #28]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + /* A[7] * B[6] */ + "ldr r6, [%[a], #28]\n\t" + "ldr r8, [%[b], #24]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + "str r4, [%[r], #52]\n\t" + "mov r4, #0\n\t" + /* A[7] * B[7] */ + "ldr r6, [%[a], #28]\n\t" + "ldr r8, [%[b], #28]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adc r3, r3, r8\n\t" + "str r5, [%[r], #56]\n\t" + "str r3, [%[r], #60]\n\t" + /* Transfer tmp to r */ + "ldr r3, [%[tmp], #0]\n\t" + "ldr r4, [%[tmp], #4]\n\t" + "ldr r5, [%[tmp], #8]\n\t" + "ldr r6, [%[tmp], #12]\n\t" + "str r3, [%[r], #0]\n\t" + "str r4, [%[r], #4]\n\t" + "str r5, [%[r], #8]\n\t" + "str r6, [%[r], #12]\n\t" + "ldr r3, [%[tmp], #16]\n\t" + "ldr r4, [%[tmp], #20]\n\t" + "ldr r5, [%[tmp], #24]\n\t" + "ldr r6, [%[tmp], #28]\n\t" + "str r3, [%[r], #16]\n\t" + "str r4, [%[r], #20]\n\t" + "str r5, [%[r], #24]\n\t" + "str r6, [%[r], #28]\n\t" + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [tmp] "r" (tmp) + : "memory", "r3", "r4", "r5", "r6", "r8" + ); +} + +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_256_sqr_8(sp_digit* r, const sp_digit* a) +{ + sp_digit tmp_arr[8]; + sp_digit* tmp = tmp_arr; + __asm__ __volatile__ ( + /* A[0] * A[0] */ + "ldr r6, [%[a], #0]\n\t" + "umull r3, r4, r6, r6\n\t" + "mov r5, #0\n\t" + "str r3, [%[tmp], #0]\n\t" + "mov r3, #0\n\t" + /* A[0] * A[1] */ + "ldr r8, [%[a], #4]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adc r5, r5, r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + "str r4, [%[tmp], #4]\n\t" + "mov r4, #0\n\t" + /* A[0] * A[2] */ + "ldr r6, [%[a], #0]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adc r3, r3, r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + /* A[1] * A[1] */ + "ldr r6, [%[a], #4]\n\t" + "umull r6, r8, r6, r6\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + "str r5, [%[tmp], #8]\n\t" + "mov r5, #0\n\t" + /* A[0] * A[3] */ + "ldr r6, [%[a], #0]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r9, r10, r6, r8\n\t" + "mov r11, #0\n\t" + /* A[1] * A[2] */ + "ldr r6, [%[a], #4]\n\t" + "ldr r8, [%[a], #8]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r9, r9, r6\n\t" + "adcs r10, r10, r8\n\t" + "adc r11, r11, #0\n\t" + "adds r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adc r11, r11, r11\n\t" + "adds r3, r3, r9\n\t" + "adcs r4, r4, r10\n\t" + "adc r5, r5, r11\n\t" + "str r3, [%[tmp], #12]\n\t" + "mov r3, #0\n\t" + /* A[0] * A[4] */ + "ldr r6, [%[a], #0]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r9, r10, r6, r8\n\t" + "mov r11, #0\n\t" + /* A[1] * A[3] */ + "ldr r6, [%[a], #4]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r9, r9, r6\n\t" + "adcs r10, r10, r8\n\t" + "adc r11, r11, #0\n\t" + /* A[2] * A[2] */ + "ldr r6, [%[a], #8]\n\t" + "umull r6, r8, r6, r6\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + "adds r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adc r11, r11, r11\n\t" + "adds r4, r4, r9\n\t" + "adcs r5, r5, r10\n\t" + "adc r3, r3, r11\n\t" + "str r4, [%[tmp], #16]\n\t" + "mov r4, #0\n\t" + /* A[0] * A[5] */ + "ldr r6, [%[a], #0]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r9, r10, r6, r8\n\t" + "mov r11, #0\n\t" + /* A[1] * A[4] */ + "ldr r6, [%[a], #4]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r9, r9, r6\n\t" + "adcs r10, r10, r8\n\t" + "adc r11, r11, #0\n\t" + /* A[2] * A[3] */ + "ldr r6, [%[a], #8]\n\t" + "ldr r8, [%[a], #12]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r9, r9, r6\n\t" + "adcs r10, r10, r8\n\t" + "adc r11, r11, #0\n\t" + "adds r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adc r11, r11, r11\n\t" + "adds r5, r5, r9\n\t" + "adcs r3, r3, r10\n\t" + "adc r4, r4, r11\n\t" + "str r5, [%[tmp], #20]\n\t" + "mov r5, #0\n\t" + /* A[0] * A[6] */ + "ldr r6, [%[a], #0]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r9, r10, r6, r8\n\t" + "mov r11, #0\n\t" + /* A[1] * A[5] */ + "ldr r6, [%[a], #4]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r9, r9, r6\n\t" + "adcs r10, r10, r8\n\t" + "adc r11, r11, #0\n\t" + /* A[2] * A[4] */ + "ldr r6, [%[a], #8]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r9, r9, r6\n\t" + "adcs r10, r10, r8\n\t" + "adc r11, r11, #0\n\t" + /* A[3] * A[3] */ + "ldr r6, [%[a], #12]\n\t" + "umull r6, r8, r6, r6\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + "adds r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adc r11, r11, r11\n\t" + "adds r3, r3, r9\n\t" + "adcs r4, r4, r10\n\t" + "adc r5, r5, r11\n\t" + "str r3, [%[tmp], #24]\n\t" + "mov r3, #0\n\t" + /* A[0] * A[7] */ + "ldr r6, [%[a], #0]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r9, r10, r6, r8\n\t" + "mov r11, #0\n\t" + /* A[1] * A[6] */ + "ldr r6, [%[a], #4]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r9, r9, r6\n\t" + "adcs r10, r10, r8\n\t" + "adc r11, r11, #0\n\t" + /* A[2] * A[5] */ + "ldr r6, [%[a], #8]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r9, r9, r6\n\t" + "adcs r10, r10, r8\n\t" + "adc r11, r11, #0\n\t" + /* A[3] * A[4] */ + "ldr r6, [%[a], #12]\n\t" + "ldr r8, [%[a], #16]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r9, r9, r6\n\t" + "adcs r10, r10, r8\n\t" + "adc r11, r11, #0\n\t" + "adds r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adc r11, r11, r11\n\t" + "adds r4, r4, r9\n\t" + "adcs r5, r5, r10\n\t" + "adc r3, r3, r11\n\t" + "str r4, [%[tmp], #28]\n\t" + "mov r4, #0\n\t" + /* A[1] * A[7] */ + "ldr r6, [%[a], #4]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r9, r10, r6, r8\n\t" + "mov r11, #0\n\t" + /* A[2] * A[6] */ + "ldr r6, [%[a], #8]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r9, r9, r6\n\t" + "adcs r10, r10, r8\n\t" + "adc r11, r11, #0\n\t" + /* A[3] * A[5] */ + "ldr r6, [%[a], #12]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r9, r9, r6\n\t" + "adcs r10, r10, r8\n\t" + "adc r11, r11, #0\n\t" + /* A[4] * A[4] */ + "ldr r6, [%[a], #16]\n\t" + "umull r6, r8, r6, r6\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + "adds r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adc r11, r11, r11\n\t" + "adds r5, r5, r9\n\t" + "adcs r3, r3, r10\n\t" + "adc r4, r4, r11\n\t" + "str r5, [%[r], #32]\n\t" + "mov r5, #0\n\t" + /* A[2] * A[7] */ + "ldr r6, [%[a], #8]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r9, r10, r6, r8\n\t" + "mov r11, #0\n\t" + /* A[3] * A[6] */ + "ldr r6, [%[a], #12]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r9, r9, r6\n\t" + "adcs r10, r10, r8\n\t" + "adc r11, r11, #0\n\t" + /* A[4] * A[5] */ + "ldr r6, [%[a], #16]\n\t" + "ldr r8, [%[a], #20]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r9, r9, r6\n\t" + "adcs r10, r10, r8\n\t" + "adc r11, r11, #0\n\t" + "adds r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adc r11, r11, r11\n\t" + "adds r3, r3, r9\n\t" + "adcs r4, r4, r10\n\t" + "adc r5, r5, r11\n\t" + "str r3, [%[r], #36]\n\t" + "mov r3, #0\n\t" + /* A[3] * A[7] */ + "ldr r6, [%[a], #12]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r9, r10, r6, r8\n\t" + "mov r11, #0\n\t" + /* A[4] * A[6] */ + "ldr r6, [%[a], #16]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r9, r9, r6\n\t" + "adcs r10, r10, r8\n\t" + "adc r11, r11, #0\n\t" + /* A[5] * A[5] */ + "ldr r6, [%[a], #20]\n\t" + "umull r6, r8, r6, r6\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + "adds r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adc r11, r11, r11\n\t" + "adds r4, r4, r9\n\t" + "adcs r5, r5, r10\n\t" + "adc r3, r3, r11\n\t" + "str r4, [%[r], #40]\n\t" + "mov r4, #0\n\t" + /* A[4] * A[7] */ + "ldr r6, [%[a], #16]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + /* A[5] * A[6] */ + "ldr r6, [%[a], #20]\n\t" + "ldr r8, [%[a], #24]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + "adds r5, r5, r6\n\t" + "adcs r3, r3, r8\n\t" + "adc r4, r4, #0\n\t" + "str r5, [%[r], #44]\n\t" + "mov r5, #0\n\t" + /* A[5] * A[7] */ + "ldr r6, [%[a], #20]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + /* A[6] * A[6] */ + "ldr r6, [%[a], #24]\n\t" + "umull r6, r8, r6, r6\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + "str r3, [%[r], #48]\n\t" + "mov r3, #0\n\t" + /* A[6] * A[7] */ + "ldr r6, [%[a], #24]\n\t" + "ldr r8, [%[a], #28]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r3, r3, #0\n\t" + "str r4, [%[r], #52]\n\t" + "mov r4, #0\n\t" + /* A[7] * A[7] */ + "ldr r6, [%[a], #28]\n\t" + "umull r6, r8, r6, r6\n\t" + "adds r5, r5, r6\n\t" + "adc r3, r3, r8\n\t" + "str r5, [%[r], #56]\n\t" + "str r3, [%[r], #60]\n\t" + /* Transfer tmp to r */ + "ldr r3, [%[tmp], #0]\n\t" + "ldr r4, [%[tmp], #4]\n\t" + "ldr r5, [%[tmp], #8]\n\t" + "ldr r6, [%[tmp], #12]\n\t" + "str r3, [%[r], #0]\n\t" + "str r4, [%[r], #4]\n\t" + "str r5, [%[r], #8]\n\t" + "str r6, [%[r], #12]\n\t" + "ldr r3, [%[tmp], #16]\n\t" + "ldr r4, [%[tmp], #20]\n\t" + "ldr r5, [%[tmp], #24]\n\t" + "ldr r6, [%[tmp], #28]\n\t" + "str r3, [%[r], #16]\n\t" + "str r4, [%[r], #20]\n\t" + "str r5, [%[r], #24]\n\t" + "str r6, [%[r], #28]\n\t" + : + : [r] "r" (r), [a] "r" (a), [tmp] "r" (tmp) + : "memory", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11" + ); +} + +#ifdef WOLFSSL_SP_SMALL +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r6, %[a]\n\t" + "mov r8, #0\n\t" + "add r6, r6, #32\n\t" + "sub r8, r8, #1\n\t" + "\n1:\n\t" + "adds %[c], %[c], r8\n\t" + "ldr r4, [%[a]]\n\t" + "ldr r5, [%[b]]\n\t" + "adcs r4, r4, r5\n\t" + "str r4, [%[r]]\n\t" + "mov %[c], #0\n\t" + "adc %[c], %[c], %[c]\n\t" + "add %[a], %[a], #4\n\t" + "add %[b], %[b], #4\n\t" + "add %[r], %[r], #4\n\t" + "cmp %[a], r6\n\t" +#ifdef __GNUC__ + "bne 1b\n\t" +#else + "bne.n 1b\n\t" +#endif /* __GNUC__ */ + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6", "r8" + ); + + return c; +} + +#else +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "mov %[c], #0\n\t" + "adc %[c], %[c], %[c]\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6", "r8" + ); + + return c; +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r6, %[a]\n\t" + "add r6, r6, #32\n\t" + "\n1:\n\t" + "mov r5, #0\n\t" + "subs r5, r5, %[c]\n\t" + "ldr r4, [%[a]]\n\t" + "ldr r5, [%[b]]\n\t" + "sbcs r4, r4, r5\n\t" + "str r4, [%[r]]\n\t" + "sbc %[c], %[c], %[c]\n\t" + "add %[a], %[a], #4\n\t" + "add %[b], %[b], #4\n\t" + "add %[r], %[r], #4\n\t" + "cmp %[a], r6\n\t" +#ifdef __GNUC__ + "bne 1b\n\t" +#else + "bne.n 1b\n\t" +#endif /* __GNUC__ */ + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6" + ); + + return c; +} + +#else +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldr r4, [%[a], #0]\n\t" + "ldr r5, [%[a], #4]\n\t" + "ldr r6, [%[b], #0]\n\t" + "ldr r8, [%[b], #4]\n\t" + "subs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #0]\n\t" + "str r5, [%[r], #4]\n\t" + "ldr r4, [%[a], #8]\n\t" + "ldr r5, [%[a], #12]\n\t" + "ldr r6, [%[b], #8]\n\t" + "ldr r8, [%[b], #12]\n\t" + "sbcs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #8]\n\t" + "str r5, [%[r], #12]\n\t" + "ldr r4, [%[a], #16]\n\t" + "ldr r5, [%[a], #20]\n\t" + "ldr r6, [%[b], #16]\n\t" + "ldr r8, [%[b], #20]\n\t" + "sbcs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #16]\n\t" + "str r5, [%[r], #20]\n\t" + "ldr r4, [%[a], #24]\n\t" + "ldr r5, [%[a], #28]\n\t" + "ldr r6, [%[b], #24]\n\t" + "ldr r8, [%[b], #28]\n\t" + "sbcs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #24]\n\t" + "str r5, [%[r], #28]\n\t" + "sbc %[c], %[c], %[c]\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6", "r8" + ); + + return c; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Create a new point. + * + * heap [in] Buffer to allocate dynamic memory from. + * sp [in] Data for point - only if not allocating. + * p [out] New point. + * returns MEMORY_E when dynamic memory allocation fails and 0 otherwise. + */ +static int sp_256_point_new_ex_8(void* heap, sp_point_256* sp, + sp_point_256** p) { int ret = MP_OKAY; (void)heap; @@ -13963,6 +15121,12 @@ static int sp_256_point_new_ex_8(void* heap, sp_point_256* sp, sp_point_256** p) #endif +/* Free the point. + * + * p [in,out] Point to free. + * clear [in] Indicates whether to zeroize point. + * heap [in] Buffer from which dynamic memory was allocate from. + */ static void sp_256_point_free_8(sp_point_256* p, int clear, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -13975,7 +15139,7 @@ static void sp_256_point_free_8(sp_point_256* p, int clear, void* heap) } #else /* Clear point data if requested. */ - if (clear != 0) { + if ((p != NULL) && (clear != 0)) { XMEMSET(p, 0, sizeof(*p)); } #endif @@ -14234,7 +15398,8 @@ static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 32 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -14268,7 +15433,9 @@ static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -14304,7 +15471,8 @@ static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) * p Point of type sp_point_256 (result). * pm Point of type ecc_point. */ -static void sp_256_point_from_ecc_point_8(sp_point_256* p, const ecc_point* pm) +static void sp_256_point_from_ecc_point_8(sp_point_256* p, + const ecc_point* pm) { XMEMSET(p->x, 0, sizeof(p->x)); XMEMSET(p->y, 0, sizeof(p->y)); @@ -14331,17 +15499,19 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) r->used = 8; mp_clamp(r); #elif DIGIT_BIT < 32 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 8; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -14354,14 +15524,16 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 8; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 32 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -15594,7 +16766,7 @@ static void sp_256_mont_sqr_n_8(sp_digit* r, const sp_digit* a, int n, } } -#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */ +#endif /* !WOLFSSL_SP_SMALL | HAVE_COMP_KEY */ #ifdef WOLFSSL_SP_SMALL /* Mod-2 for the P256 curve. */ static const uint32_t p256_mod_minus_2[8] = { @@ -15998,7 +17170,8 @@ SP_NOINLINE static void sp_256_mont_reduce_order_8(sp_digit* a, const sp_digit* * p Montgomery form projective coordinate point. * t Temporary ordinate data. */ -static void sp_256_map_8(sp_point_256* r, const sp_point_256* p, sp_digit* t) +static void sp_256_map_8(sp_point_256* r, const sp_point_256* p, + sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2*8; @@ -16034,92 +17207,6 @@ static void sp_256_map_8(sp_point_256* r, const sp_point_256* p, sp_digit* t) } -#ifdef WOLFSSL_SP_SMALL -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "mov r6, %[a]\n\t" - "mov r8, #0\n\t" - "add r6, r6, #32\n\t" - "sub r8, r8, #1\n\t" - "\n1:\n\t" - "adds %[c], %[c], r8\n\t" - "ldr r4, [%[a]]\n\t" - "ldr r5, [%[b]]\n\t" - "adcs r4, r4, r5\n\t" - "str r4, [%[r]]\n\t" - "mov %[c], #0\n\t" - "adc %[c], %[c], %[c]\n\t" - "add %[a], %[a], #4\n\t" - "add %[b], %[b], #4\n\t" - "add %[r], %[r], #4\n\t" - "cmp %[a], r6\n\t" -#ifdef __GNUC__ - "bne 1b\n\t" -#else - "bne.n 1b\n\t" -#endif /* __GNUC__ */ - : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) - : - : "memory", "r4", "r5", "r6", "r8" - ); - - return c; -} - -#else -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "ldm %[a]!, {r4, r5}\n\t" - "ldm %[b]!, {r6, r8}\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "stm %[r]!, {r4, r5}\n\t" - "ldm %[a]!, {r4, r5}\n\t" - "ldm %[b]!, {r6, r8}\n\t" - "adcs r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "stm %[r]!, {r4, r5}\n\t" - "ldm %[a]!, {r4, r5}\n\t" - "ldm %[b]!, {r6, r8}\n\t" - "adcs r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "stm %[r]!, {r4, r5}\n\t" - "ldm %[a]!, {r4, r5}\n\t" - "ldm %[b]!, {r6, r8}\n\t" - "adcs r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "stm %[r]!, {r4, r5}\n\t" - "mov %[c], #0\n\t" - "adc %[c], %[c], %[c]\n\t" - : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) - : - : "memory", "r4", "r5", "r6", "r8" - ); - - return c; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Add two Montgomery form numbers (r = a + b % m). * * r Result of addition. @@ -16681,101 +17768,6 @@ static void sp_256_proj_point_dbl_8(sp_point_256* r, const sp_point_256* p, sp_d sp_256_mont_sub_8(y, y, t2, p256_mod); } -#ifdef WOLFSSL_SP_SMALL -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "mov r6, %[a]\n\t" - "add r6, r6, #32\n\t" - "\n1:\n\t" - "mov r5, #0\n\t" - "subs r5, r5, %[c]\n\t" - "ldr r4, [%[a]]\n\t" - "ldr r5, [%[b]]\n\t" - "sbcs r4, r4, r5\n\t" - "str r4, [%[r]]\n\t" - "sbc %[c], %[c], %[c]\n\t" - "add %[a], %[a], #4\n\t" - "add %[b], %[b], #4\n\t" - "add %[r], %[r], #4\n\t" - "cmp %[a], r6\n\t" -#ifdef __GNUC__ - "bne 1b\n\t" -#else - "bne.n 1b\n\t" -#endif /* __GNUC__ */ - : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) - : - : "memory", "r4", "r5", "r6" - ); - - return c; -} - -#else -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "ldr r4, [%[a], #0]\n\t" - "ldr r5, [%[a], #4]\n\t" - "ldr r6, [%[b], #0]\n\t" - "ldr r8, [%[b], #4]\n\t" - "subs r4, r4, r6\n\t" - "sbcs r5, r5, r8\n\t" - "str r4, [%[r], #0]\n\t" - "str r5, [%[r], #4]\n\t" - "ldr r4, [%[a], #8]\n\t" - "ldr r5, [%[a], #12]\n\t" - "ldr r6, [%[b], #8]\n\t" - "ldr r8, [%[b], #12]\n\t" - "sbcs r4, r4, r6\n\t" - "sbcs r5, r5, r8\n\t" - "str r4, [%[r], #8]\n\t" - "str r5, [%[r], #12]\n\t" - "ldr r4, [%[a], #16]\n\t" - "ldr r5, [%[a], #20]\n\t" - "ldr r6, [%[b], #16]\n\t" - "ldr r8, [%[b], #20]\n\t" - "sbcs r4, r4, r6\n\t" - "sbcs r5, r5, r8\n\t" - "str r4, [%[r], #16]\n\t" - "str r5, [%[r], #20]\n\t" - "ldr r4, [%[a], #24]\n\t" - "ldr r5, [%[a], #28]\n\t" - "ldr r6, [%[b], #24]\n\t" - "ldr r8, [%[b], #28]\n\t" - "sbcs r4, r4, r6\n\t" - "sbcs r5, r5, r8\n\t" - "str r4, [%[r], #24]\n\t" - "str r5, [%[r], #28]\n\t" - "sbc %[c], %[c], %[c]\n\t" - : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) - : - : "memory", "r4", "r5", "r6", "r8" - ); - - return c; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Compare two numbers to determine if they are equal. * Constant time implementation. * @@ -16999,8 +17991,8 @@ static int sp_256_proj_point_add_8_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r, } #endif /* WOLFSSL_SP_NONBLOCK */ -static void sp_256_proj_point_add_8(sp_point_256* r, const sp_point_256* p, const sp_point_256* q, - sp_digit* t) +static void sp_256_proj_point_add_8(sp_point_256* r, + const sp_point_256* p, const sp_point_256* q, sp_digit* t) { const sp_point_256* ap[2]; sp_point_256* rp[2]; @@ -17155,9 +18147,11 @@ static void sp_256_get_point_16_8(sp_point_256* r, const sp_point_256* table, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Simple, smaller code size and memory size, of windowing. - * Calculate uindow of 4 bits. - * Only add points from table. + * Fast implementation that generates a pre-computation table. + * 4 bits of window (no sliding!). + * Uses add and double for calculating table. + * 256 doubles. + * 76 adds. * * r Resulting point. * g Point to multiply. @@ -17186,7 +18180,8 @@ static int sp_256_ecc_mulmod_fast_8(sp_point_256* r, const sp_point_256* g, cons sp_digit* tmp; sp_digit n; int i; - int c, y; + int c; + int y; int err; /* Constant time used for cache attack resistance implementation. */ @@ -17259,7 +18254,7 @@ static int sp_256_ecc_mulmod_fast_8(sp_point_256* r, const sp_point_256* g, cons i = 6; n = k[i+1] << 0; c = 28; - y = n >> 28; + y = (int)(n >> 28); #ifndef WC_NO_CACHE_RESISTANT if (ct) { sp_256_get_point_16_8(rt, t, y); @@ -17324,12 +18319,6 @@ static int sp_256_ecc_mulmod_fast_8(sp_point_256* r, const sp_point_256* g, cons return err; } -/* A table entry for pre-computed points. */ -typedef struct sp_table_entry_256 { - sp_digit x[8]; - sp_digit y[8]; -} sp_table_entry_256; - #ifdef FP_ECC /* Double the Montgomery form projective point p a number of times. * @@ -17338,7 +18327,8 @@ typedef struct sp_table_entry_256 { * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_8(sp_point_256* p, int n, sp_digit* t) +static void sp_256_proj_point_dbl_n_8(sp_point_256* p, int n, + sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*8; @@ -17441,6 +18431,14 @@ static void sp_256_proj_to_affine_8(sp_point_256* a, sp_digit* t) XMEMCPY(a->z, p256_norm_mod, sizeof(p256_norm_mod)); } +#endif /* FP_ECC */ +/* A table entry for pre-computed points. */ +typedef struct sp_table_entry_256 { + sp_digit x[8]; + sp_digit y[8]; +} sp_table_entry_256; + +#ifdef FP_ECC #endif /* FP_ECC */ /* Add two Montgomery form projective points. The second point has a q value of * one. @@ -17527,6 +18525,10 @@ static void sp_256_proj_point_add_qz1_8(sp_point_256* r, const sp_point_256* p, #ifdef WOLFSSL_SP_SMALL #ifdef FP_ECC /* Generate the pre-computed table of points for the base point. + * + * width = 4 + * 16 entries + * 64 bits between * * a The base point. * table Place to store generated point data. @@ -17537,12 +18539,15 @@ static int sp_256_gen_stripe_table_8(const sp_point_256* a, sp_table_entry_256* table, sp_digit* tmp, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_point_256 td, s1d, s2d; + sp_point_256 td; + sp_point_256 s1d; + sp_point_256 s2d; #endif sp_point_256* t; sp_point_256* s1 = NULL; sp_point_256* s2 = NULL; - int i, j; + int i; + int j; int err; (void)heap; @@ -17661,8 +18666,10 @@ static void sp_256_get_entry_16_8(sp_point_256* r, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Implementation uses striping of bits. - * Choose bits 4 bits apart. + * Stripe implementation. + * Pre-generated: 2^0, 2^64, ... + * Pre-generated: products of all combinations of above. + * 4 doubles and adds (with qz=1) * * r Resulting point. * k Scalar to multiply by. @@ -17684,8 +18691,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, sp_point_256* rt; sp_point_256* p = NULL; sp_digit* t; - int i, j; - int y, x; + int i; + int j; + int y; + int x; int err; (void)g; @@ -17713,8 +18722,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod)); y = 0; - for (j=0,x=63; j<4; j++,x+=64) { + x = 63; + for (j=0; j<4; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 64; } #ifndef WC_NO_CACHE_RESISTANT if (ct) { @@ -17728,8 +18739,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, rt->infinity = !y; for (i=62; i>=0; i--) { y = 0; - for (j=0,x=i; j<4; j++,x+=64) { + x = i; + for (j=0; j<4; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 64; } sp_256_proj_point_dbl_8(rt, rt, t); @@ -17771,16 +18784,25 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, #define FP_ENTRIES 16 #endif +/* Cache entry - holds precomputation tables for a point. */ typedef struct sp_cache_256_t { + /* X ordinate of point that table was generated from. */ sp_digit x[8]; + /* Y ordinate of point that table was generated from. */ sp_digit y[8]; + /* Precomputation table for point. */ sp_table_entry_256 table[16]; + /* Count of entries in table. */ uint32_t cnt; + /* Point and table set in entry. */ int set; } sp_cache_256_t; +/* Cache of tables. */ static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES]; +/* Index of last entry in cache. */ static THREAD_LS_T int sp_cache_256_last = -1; +/* Cache has been initialized. */ static THREAD_LS_T int sp_cache_256_inited = 0; #ifndef HAVE_THREAD_LS @@ -17788,9 +18810,15 @@ static THREAD_LS_T int sp_cache_256_inited = 0; static wolfSSL_Mutex sp_cache_256_lock; #endif +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache) { - int i, j; + int i; + int j; uint32_t least; if (sp_cache_256_inited == 0) { @@ -17899,6 +18927,10 @@ static int sp_256_ecc_mulmod_8(sp_point_256* r, const sp_point_256* g, const sp_ #else #ifdef FP_ECC /* Generate the pre-computed table of points for the base point. + * + * width = 8 + * 256 entries + * 32 bits between * * a The base point. * table Place to store generated point data. @@ -17909,12 +18941,15 @@ static int sp_256_gen_stripe_table_8(const sp_point_256* a, sp_table_entry_256* table, sp_digit* tmp, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_point_256 td, s1d, s2d; + sp_point_256 td; + sp_point_256 s1d; + sp_point_256 s2d; #endif sp_point_256* t; sp_point_256* s1 = NULL; sp_point_256* s2 = NULL; - int i, j; + int i; + int j; int err; (void)heap; @@ -18033,8 +19068,10 @@ static void sp_256_get_entry_256_8(sp_point_256* r, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Implementation uses striping of bits. - * Choose bits 8 bits apart. + * Stripe implementation. + * Pre-generated: 2^0, 2^32, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) * * r Resulting point. * k Scalar to multiply by. @@ -18056,8 +19093,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, sp_point_256* rt; sp_point_256* p = NULL; sp_digit* t; - int i, j; - int y, x; + int i; + int j; + int y; + int x; int err; (void)g; @@ -18085,8 +19124,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod)); y = 0; - for (j=0,x=31; j<8; j++,x+=32) { + x = 31; + for (j=0; j<8; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 32; } #ifndef WC_NO_CACHE_RESISTANT if (ct) { @@ -18100,8 +19141,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, rt->infinity = !y; for (i=30; i>=0; i--) { y = 0; - for (j=0,x=i; j<8; j++,x+=32) { + x = i; + for (j=0; j<8; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 32; } sp_256_proj_point_dbl_8(rt, rt, t); @@ -18143,16 +19186,25 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, #define FP_ENTRIES 16 #endif +/* Cache entry - holds precomputation tables for a point. */ typedef struct sp_cache_256_t { + /* X ordinate of point that table was generated from. */ sp_digit x[8]; + /* Y ordinate of point that table was generated from. */ sp_digit y[8]; + /* Precomputation table for point. */ sp_table_entry_256 table[256]; + /* Count of entries in table. */ uint32_t cnt; + /* Point and table set in entry. */ int set; } sp_cache_256_t; +/* Cache of tables. */ static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES]; +/* Index of last entry in cache. */ static THREAD_LS_T int sp_cache_256_last = -1; +/* Cache has been initialized. */ static THREAD_LS_T int sp_cache_256_inited = 0; #ifndef HAVE_THREAD_LS @@ -18160,9 +19212,15 @@ static THREAD_LS_T int sp_cache_256_inited = 0; static wolfSSL_Mutex sp_cache_256_lock; #endif +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache) { - int i, j; + int i; + int j; uint32_t least; if (sp_cache_256_inited == 0) { @@ -18279,8 +19337,8 @@ static int sp_256_ecc_mulmod_8(sp_point_256* r, const sp_point_256* g, const sp_ * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, - void* heap) +int sp_ecc_mulmod_256(const mp_int* km, const ecc_point* gm, ecc_point* r, + int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_256 p; @@ -18321,7 +19379,94 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, return err; } +/* Multiply the point by the scalar, add point a and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * p Point to multiply. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_add_256(const mp_int* km, const ecc_point* gm, + const ecc_point* am, int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_256 p; + sp_point_256 a; + sp_digit kd[8]; + sp_digit t[8 * 2 * 5]; +#endif + sp_point_256* point; + sp_point_256* addP = NULL; + sp_digit* k = NULL; + sp_digit* tmp = NULL; + int err = MP_OKAY; + + err = sp_256_point_new_8(heap, p, point); + if (err == MP_OKAY) { + err = sp_256_point_new_8(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (8 + 8 * 2 * 5), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 8; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_256_from_mp(k, 8, km); + sp_256_point_from_ecc_point_8(point, gm); + sp_256_point_from_ecc_point_8(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_8(addP->x, addP->x, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_8(addP->y, addP->y, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_8(addP->z, addP->z, p256_mod); + } + if (err == MP_OKAY) { + err = sp_256_ecc_mulmod_8(point, point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_256_proj_point_add_8(point, point, addP, tmp); + + if (map) { + sp_256_map_8(point, point, tmp); + } + + err = sp_256_point_to_ecc_point_8(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_256_point_free_8(addP, 0, heap); + sp_256_point_free_8(point, 0, heap); + + return err; +} + #ifdef WOLFSSL_SP_SMALL +/* Striping precomputation table. + * 4 points combined into a table of 16 points. + * Distance of 64 between points. + */ static const sp_table_entry_256 p256_table[16] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -18406,6 +19551,11 @@ static const sp_table_entry_256 p256_table[16] = { /* Multiply the base point of P256 by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Stripe implementation. + * Pre-generated: 2^0, 2^64, ... + * Pre-generated: products of all combinations of above. + * 4 doubles and adds (with qz=1) + * * r Resulting point. * k Scalar to multiply by. * map Indicates whether to convert result to affine. @@ -18421,6 +19571,10 @@ static int sp_256_ecc_mulmod_base_8(sp_point_256* r, const sp_digit* k, } #else +/* Striping precomputation table. + * 8 points combined into a table of 256 points. + * Distance of 32 between points. + */ static const sp_table_entry_256 p256_table[256] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -19705,6 +20859,11 @@ static const sp_table_entry_256 p256_table[256] = { /* Multiply the base point of P256 by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Stripe implementation. + * Pre-generated: 2^0, 2^32, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * * r Resulting point. * k Scalar to multiply by. * map Indicates whether to convert result to affine. @@ -19730,7 +20889,7 @@ static int sp_256_ecc_mulmod_base_8(sp_point_256* r, const sp_digit* k, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) +int sp_ecc_mulmod_base_256(const mp_int* km, ecc_point* r, int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_256 p; @@ -19771,6 +20930,87 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) return err; } +/* Multiply the base point of P256 by the scalar, add point a and return + * the result. If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_add_256(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_256 p; + sp_point_256 a; + sp_digit kd[8]; + sp_digit t[8 * 2 * 5]; +#endif + sp_point_256* point; + sp_point_256* addP = NULL; + sp_digit* tmp = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_256_point_new_8(heap, p, point); + if (err == MP_OKAY) { + err = sp_256_point_new_8(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (8 + 8 * 2 * 5), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 8; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_256_from_mp(k, 8, km); + sp_256_point_from_ecc_point_8(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_8(addP->x, addP->x, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_8(addP->y, addP->y, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_8(addP->z, addP->z, p256_mod); + } + if (err == MP_OKAY) { + err = sp_256_ecc_mulmod_base_8(point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_256_proj_point_add_8(point, point, addP, tmp); + + if (map) { + sp_256_map_8(point, point, tmp); + } + + err = sp_256_point_to_ecc_point_8(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_256_point_free_8(addP, 0, heap); + sp_256_point_free_8(point, 0, heap); + + return err; +} + #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \ defined(HAVE_ECC_VERIFY) /* Returns 1 if the number of zero. @@ -19784,7 +21024,7 @@ static int sp_256_iszero_8(const sp_digit* a) return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6] | a[7]) == 0; } -#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN | HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ /* Add 1 to a. (a = a + 1) * * a A single precision integer. @@ -19833,7 +21073,8 @@ SP_NOINLINE static void sp_256_add_one_8(sp_digit* a) */ static void sp_256_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -19977,7 +21218,10 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) */ static void sp_256_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; j = 256 / 8 - 1; a[j] = 0; @@ -20018,7 +21262,7 @@ static void sp_256_to_bin(sp_digit* r, byte* a) * returns BUFFER_E if the buffer is to small for output size, * MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, +int sp_ecc_secret_gen_256(const mp_int* priv, const ecc_point* pub, byte* out, word32* outLen, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) @@ -20069,515 +21313,6 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, #endif /* HAVE_ECC_DHE */ #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) -/* Multiply a and b into r. (r = a * b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static void sp_256_mul_8(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit tmp_arr[8]; - sp_digit* tmp = tmp_arr; - - __asm__ __volatile__ ( - /* A[0] * B[0] */ - "ldr r6, [%[a], #0]\n\t" - "ldr r8, [%[b], #0]\n\t" - "umull r3, r4, r6, r8\n\t" - "mov r5, #0\n\t" - "str r3, [%[tmp], #0]\n\t" - "mov r3, #0\n\t" - /* A[0] * B[1] */ - "ldr r8, [%[b], #4]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adc r5, r5, r8\n\t" - /* A[1] * B[0] */ - "ldr r6, [%[a], #4]\n\t" - "ldr r8, [%[b], #0]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - "str r4, [%[tmp], #4]\n\t" - "mov r4, #0\n\t" - /* A[0] * B[2] */ - "ldr r6, [%[a], #0]\n\t" - "ldr r8, [%[b], #8]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - /* A[1] * B[1] */ - "ldr r6, [%[a], #4]\n\t" - "ldr r8, [%[b], #4]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - /* A[2] * B[0] */ - "ldr r6, [%[a], #8]\n\t" - "ldr r8, [%[b], #0]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - "str r5, [%[tmp], #8]\n\t" - "mov r5, #0\n\t" - /* A[0] * B[3] */ - "ldr r6, [%[a], #0]\n\t" - "ldr r8, [%[b], #12]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - /* A[1] * B[2] */ - "ldr r6, [%[a], #4]\n\t" - "ldr r8, [%[b], #8]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - /* A[2] * B[1] */ - "ldr r6, [%[a], #8]\n\t" - "ldr r8, [%[b], #4]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - /* A[3] * B[0] */ - "ldr r6, [%[a], #12]\n\t" - "ldr r8, [%[b], #0]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - "str r3, [%[tmp], #12]\n\t" - "mov r3, #0\n\t" - /* A[0] * B[4] */ - "ldr r6, [%[a], #0]\n\t" - "ldr r8, [%[b], #16]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - /* A[1] * B[3] */ - "ldr r6, [%[a], #4]\n\t" - "ldr r8, [%[b], #12]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - /* A[2] * B[2] */ - "ldr r6, [%[a], #8]\n\t" - "ldr r8, [%[b], #8]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - /* A[3] * B[1] */ - "ldr r6, [%[a], #12]\n\t" - "ldr r8, [%[b], #4]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - /* A[4] * B[0] */ - "ldr r6, [%[a], #16]\n\t" - "ldr r8, [%[b], #0]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - "str r4, [%[tmp], #16]\n\t" - "mov r4, #0\n\t" - /* A[0] * B[5] */ - "ldr r6, [%[a], #0]\n\t" - "ldr r8, [%[b], #20]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - /* A[1] * B[4] */ - "ldr r6, [%[a], #4]\n\t" - "ldr r8, [%[b], #16]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - /* A[2] * B[3] */ - "ldr r6, [%[a], #8]\n\t" - "ldr r8, [%[b], #12]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - /* A[3] * B[2] */ - "ldr r6, [%[a], #12]\n\t" - "ldr r8, [%[b], #8]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - /* A[4] * B[1] */ - "ldr r6, [%[a], #16]\n\t" - "ldr r8, [%[b], #4]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - /* A[5] * B[0] */ - "ldr r6, [%[a], #20]\n\t" - "ldr r8, [%[b], #0]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - "str r5, [%[tmp], #20]\n\t" - "mov r5, #0\n\t" - /* A[0] * B[6] */ - "ldr r6, [%[a], #0]\n\t" - "ldr r8, [%[b], #24]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - /* A[1] * B[5] */ - "ldr r6, [%[a], #4]\n\t" - "ldr r8, [%[b], #20]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - /* A[2] * B[4] */ - "ldr r6, [%[a], #8]\n\t" - "ldr r8, [%[b], #16]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - /* A[3] * B[3] */ - "ldr r6, [%[a], #12]\n\t" - "ldr r8, [%[b], #12]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - /* A[4] * B[2] */ - "ldr r6, [%[a], #16]\n\t" - "ldr r8, [%[b], #8]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - /* A[5] * B[1] */ - "ldr r6, [%[a], #20]\n\t" - "ldr r8, [%[b], #4]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - /* A[6] * B[0] */ - "ldr r6, [%[a], #24]\n\t" - "ldr r8, [%[b], #0]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - "str r3, [%[tmp], #24]\n\t" - "mov r3, #0\n\t" - /* A[0] * B[7] */ - "ldr r6, [%[a], #0]\n\t" - "ldr r8, [%[b], #28]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - /* A[1] * B[6] */ - "ldr r6, [%[a], #4]\n\t" - "ldr r8, [%[b], #24]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - /* A[2] * B[5] */ - "ldr r6, [%[a], #8]\n\t" - "ldr r8, [%[b], #20]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - /* A[3] * B[4] */ - "ldr r6, [%[a], #12]\n\t" - "ldr r8, [%[b], #16]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - /* A[4] * B[3] */ - "ldr r6, [%[a], #16]\n\t" - "ldr r8, [%[b], #12]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - /* A[5] * B[2] */ - "ldr r6, [%[a], #20]\n\t" - "ldr r8, [%[b], #8]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - /* A[6] * B[1] */ - "ldr r6, [%[a], #24]\n\t" - "ldr r8, [%[b], #4]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - /* A[7] * B[0] */ - "ldr r6, [%[a], #28]\n\t" - "ldr r8, [%[b], #0]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - "str r4, [%[tmp], #28]\n\t" - "mov r4, #0\n\t" - /* A[1] * B[7] */ - "ldr r6, [%[a], #4]\n\t" - "ldr r8, [%[b], #28]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - /* A[2] * B[6] */ - "ldr r6, [%[a], #8]\n\t" - "ldr r8, [%[b], #24]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - /* A[3] * B[5] */ - "ldr r6, [%[a], #12]\n\t" - "ldr r8, [%[b], #20]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - /* A[4] * B[4] */ - "ldr r6, [%[a], #16]\n\t" - "ldr r8, [%[b], #16]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - /* A[5] * B[3] */ - "ldr r6, [%[a], #20]\n\t" - "ldr r8, [%[b], #12]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - /* A[6] * B[2] */ - "ldr r6, [%[a], #24]\n\t" - "ldr r8, [%[b], #8]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - /* A[7] * B[1] */ - "ldr r6, [%[a], #28]\n\t" - "ldr r8, [%[b], #4]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - "str r5, [%[r], #32]\n\t" - "mov r5, #0\n\t" - /* A[2] * B[7] */ - "ldr r6, [%[a], #8]\n\t" - "ldr r8, [%[b], #28]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - /* A[3] * B[6] */ - "ldr r6, [%[a], #12]\n\t" - "ldr r8, [%[b], #24]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - /* A[4] * B[5] */ - "ldr r6, [%[a], #16]\n\t" - "ldr r8, [%[b], #20]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - /* A[5] * B[4] */ - "ldr r6, [%[a], #20]\n\t" - "ldr r8, [%[b], #16]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - /* A[6] * B[3] */ - "ldr r6, [%[a], #24]\n\t" - "ldr r8, [%[b], #12]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - /* A[7] * B[2] */ - "ldr r6, [%[a], #28]\n\t" - "ldr r8, [%[b], #8]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - "str r3, [%[r], #36]\n\t" - "mov r3, #0\n\t" - /* A[3] * B[7] */ - "ldr r6, [%[a], #12]\n\t" - "ldr r8, [%[b], #28]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - /* A[4] * B[6] */ - "ldr r6, [%[a], #16]\n\t" - "ldr r8, [%[b], #24]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - /* A[5] * B[5] */ - "ldr r6, [%[a], #20]\n\t" - "ldr r8, [%[b], #20]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - /* A[6] * B[4] */ - "ldr r6, [%[a], #24]\n\t" - "ldr r8, [%[b], #16]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - /* A[7] * B[3] */ - "ldr r6, [%[a], #28]\n\t" - "ldr r8, [%[b], #12]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - "str r4, [%[r], #40]\n\t" - "mov r4, #0\n\t" - /* A[4] * B[7] */ - "ldr r6, [%[a], #16]\n\t" - "ldr r8, [%[b], #28]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - /* A[5] * B[6] */ - "ldr r6, [%[a], #20]\n\t" - "ldr r8, [%[b], #24]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - /* A[6] * B[5] */ - "ldr r6, [%[a], #24]\n\t" - "ldr r8, [%[b], #20]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - /* A[7] * B[4] */ - "ldr r6, [%[a], #28]\n\t" - "ldr r8, [%[b], #16]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - "str r5, [%[r], #44]\n\t" - "mov r5, #0\n\t" - /* A[5] * B[7] */ - "ldr r6, [%[a], #20]\n\t" - "ldr r8, [%[b], #28]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - /* A[6] * B[6] */ - "ldr r6, [%[a], #24]\n\t" - "ldr r8, [%[b], #24]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - /* A[7] * B[5] */ - "ldr r6, [%[a], #28]\n\t" - "ldr r8, [%[b], #20]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - "str r3, [%[r], #48]\n\t" - "mov r3, #0\n\t" - /* A[6] * B[7] */ - "ldr r6, [%[a], #24]\n\t" - "ldr r8, [%[b], #28]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - /* A[7] * B[6] */ - "ldr r6, [%[a], #28]\n\t" - "ldr r8, [%[b], #24]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - "str r4, [%[r], #52]\n\t" - "mov r4, #0\n\t" - /* A[7] * B[7] */ - "ldr r6, [%[a], #28]\n\t" - "ldr r8, [%[b], #28]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adc r3, r3, r8\n\t" - "str r5, [%[r], #56]\n\t" - "str r3, [%[r], #60]\n\t" - /* Transfer tmp to r */ - "ldr r3, [%[tmp], #0]\n\t" - "ldr r4, [%[tmp], #4]\n\t" - "ldr r5, [%[tmp], #8]\n\t" - "ldr r6, [%[tmp], #12]\n\t" - "str r3, [%[r], #0]\n\t" - "str r4, [%[r], #4]\n\t" - "str r5, [%[r], #8]\n\t" - "str r6, [%[r], #12]\n\t" - "ldr r3, [%[tmp], #16]\n\t" - "ldr r4, [%[tmp], #20]\n\t" - "ldr r5, [%[tmp], #24]\n\t" - "ldr r6, [%[tmp], #28]\n\t" - "str r3, [%[r], #16]\n\t" - "str r4, [%[r], #20]\n\t" - "str r5, [%[r], #24]\n\t" - "str r6, [%[r], #28]\n\t" - : - : [r] "r" (r), [a] "r" (a), [b] "r" (b), [tmp] "r" (tmp) - : "memory", "r3", "r4", "r5", "r6", "r8" - ); -} - #endif #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) #ifdef WOLFSSL_SP_SMALL @@ -20837,357 +21572,6 @@ static WC_INLINE int sp_256_mod_8(sp_digit* r, const sp_digit* a, const sp_digit #endif #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) -/* Square a and put result in r. (r = a * a) - * - * r A single precision integer. - * a A single precision integer. - */ -SP_NOINLINE static void sp_256_sqr_8(sp_digit* r, const sp_digit* a) -{ - sp_digit tmp_arr[8]; - sp_digit* tmp = tmp_arr; - __asm__ __volatile__ ( - /* A[0] * A[0] */ - "ldr r6, [%[a], #0]\n\t" - "umull r3, r4, r6, r6\n\t" - "mov r5, #0\n\t" - "str r3, [%[tmp], #0]\n\t" - "mov r3, #0\n\t" - /* A[0] * A[1] */ - "ldr r8, [%[a], #4]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adc r5, r5, r8\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - "str r4, [%[tmp], #4]\n\t" - "mov r4, #0\n\t" - /* A[0] * A[2] */ - "ldr r6, [%[a], #0]\n\t" - "ldr r8, [%[a], #8]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adc r3, r3, r8\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - /* A[1] * A[1] */ - "ldr r6, [%[a], #4]\n\t" - "umull r6, r8, r6, r6\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - "str r5, [%[tmp], #8]\n\t" - "mov r5, #0\n\t" - /* A[0] * A[3] */ - "ldr r6, [%[a], #0]\n\t" - "ldr r8, [%[a], #12]\n\t" - "umull r9, r10, r6, r8\n\t" - "mov r11, #0\n\t" - /* A[1] * A[2] */ - "ldr r6, [%[a], #4]\n\t" - "ldr r8, [%[a], #8]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r9, r9, r6\n\t" - "adcs r10, r10, r8\n\t" - "adc r11, r11, #0\n\t" - "adds r9, r9, r9\n\t" - "adcs r10, r10, r10\n\t" - "adc r11, r11, r11\n\t" - "adds r3, r3, r9\n\t" - "adcs r4, r4, r10\n\t" - "adc r5, r5, r11\n\t" - "str r3, [%[tmp], #12]\n\t" - "mov r3, #0\n\t" - /* A[0] * A[4] */ - "ldr r6, [%[a], #0]\n\t" - "ldr r8, [%[a], #16]\n\t" - "umull r9, r10, r6, r8\n\t" - "mov r11, #0\n\t" - /* A[1] * A[3] */ - "ldr r6, [%[a], #4]\n\t" - "ldr r8, [%[a], #12]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r9, r9, r6\n\t" - "adcs r10, r10, r8\n\t" - "adc r11, r11, #0\n\t" - /* A[2] * A[2] */ - "ldr r6, [%[a], #8]\n\t" - "umull r6, r8, r6, r6\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - "adds r9, r9, r9\n\t" - "adcs r10, r10, r10\n\t" - "adc r11, r11, r11\n\t" - "adds r4, r4, r9\n\t" - "adcs r5, r5, r10\n\t" - "adc r3, r3, r11\n\t" - "str r4, [%[tmp], #16]\n\t" - "mov r4, #0\n\t" - /* A[0] * A[5] */ - "ldr r6, [%[a], #0]\n\t" - "ldr r8, [%[a], #20]\n\t" - "umull r9, r10, r6, r8\n\t" - "mov r11, #0\n\t" - /* A[1] * A[4] */ - "ldr r6, [%[a], #4]\n\t" - "ldr r8, [%[a], #16]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r9, r9, r6\n\t" - "adcs r10, r10, r8\n\t" - "adc r11, r11, #0\n\t" - /* A[2] * A[3] */ - "ldr r6, [%[a], #8]\n\t" - "ldr r8, [%[a], #12]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r9, r9, r6\n\t" - "adcs r10, r10, r8\n\t" - "adc r11, r11, #0\n\t" - "adds r9, r9, r9\n\t" - "adcs r10, r10, r10\n\t" - "adc r11, r11, r11\n\t" - "adds r5, r5, r9\n\t" - "adcs r3, r3, r10\n\t" - "adc r4, r4, r11\n\t" - "str r5, [%[tmp], #20]\n\t" - "mov r5, #0\n\t" - /* A[0] * A[6] */ - "ldr r6, [%[a], #0]\n\t" - "ldr r8, [%[a], #24]\n\t" - "umull r9, r10, r6, r8\n\t" - "mov r11, #0\n\t" - /* A[1] * A[5] */ - "ldr r6, [%[a], #4]\n\t" - "ldr r8, [%[a], #20]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r9, r9, r6\n\t" - "adcs r10, r10, r8\n\t" - "adc r11, r11, #0\n\t" - /* A[2] * A[4] */ - "ldr r6, [%[a], #8]\n\t" - "ldr r8, [%[a], #16]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r9, r9, r6\n\t" - "adcs r10, r10, r8\n\t" - "adc r11, r11, #0\n\t" - /* A[3] * A[3] */ - "ldr r6, [%[a], #12]\n\t" - "umull r6, r8, r6, r6\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - "adds r9, r9, r9\n\t" - "adcs r10, r10, r10\n\t" - "adc r11, r11, r11\n\t" - "adds r3, r3, r9\n\t" - "adcs r4, r4, r10\n\t" - "adc r5, r5, r11\n\t" - "str r3, [%[tmp], #24]\n\t" - "mov r3, #0\n\t" - /* A[0] * A[7] */ - "ldr r6, [%[a], #0]\n\t" - "ldr r8, [%[a], #28]\n\t" - "umull r9, r10, r6, r8\n\t" - "mov r11, #0\n\t" - /* A[1] * A[6] */ - "ldr r6, [%[a], #4]\n\t" - "ldr r8, [%[a], #24]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r9, r9, r6\n\t" - "adcs r10, r10, r8\n\t" - "adc r11, r11, #0\n\t" - /* A[2] * A[5] */ - "ldr r6, [%[a], #8]\n\t" - "ldr r8, [%[a], #20]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r9, r9, r6\n\t" - "adcs r10, r10, r8\n\t" - "adc r11, r11, #0\n\t" - /* A[3] * A[4] */ - "ldr r6, [%[a], #12]\n\t" - "ldr r8, [%[a], #16]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r9, r9, r6\n\t" - "adcs r10, r10, r8\n\t" - "adc r11, r11, #0\n\t" - "adds r9, r9, r9\n\t" - "adcs r10, r10, r10\n\t" - "adc r11, r11, r11\n\t" - "adds r4, r4, r9\n\t" - "adcs r5, r5, r10\n\t" - "adc r3, r3, r11\n\t" - "str r4, [%[tmp], #28]\n\t" - "mov r4, #0\n\t" - /* A[1] * A[7] */ - "ldr r6, [%[a], #4]\n\t" - "ldr r8, [%[a], #28]\n\t" - "umull r9, r10, r6, r8\n\t" - "mov r11, #0\n\t" - /* A[2] * A[6] */ - "ldr r6, [%[a], #8]\n\t" - "ldr r8, [%[a], #24]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r9, r9, r6\n\t" - "adcs r10, r10, r8\n\t" - "adc r11, r11, #0\n\t" - /* A[3] * A[5] */ - "ldr r6, [%[a], #12]\n\t" - "ldr r8, [%[a], #20]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r9, r9, r6\n\t" - "adcs r10, r10, r8\n\t" - "adc r11, r11, #0\n\t" - /* A[4] * A[4] */ - "ldr r6, [%[a], #16]\n\t" - "umull r6, r8, r6, r6\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - "adds r9, r9, r9\n\t" - "adcs r10, r10, r10\n\t" - "adc r11, r11, r11\n\t" - "adds r5, r5, r9\n\t" - "adcs r3, r3, r10\n\t" - "adc r4, r4, r11\n\t" - "str r5, [%[r], #32]\n\t" - "mov r5, #0\n\t" - /* A[2] * A[7] */ - "ldr r6, [%[a], #8]\n\t" - "ldr r8, [%[a], #28]\n\t" - "umull r9, r10, r6, r8\n\t" - "mov r11, #0\n\t" - /* A[3] * A[6] */ - "ldr r6, [%[a], #12]\n\t" - "ldr r8, [%[a], #24]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r9, r9, r6\n\t" - "adcs r10, r10, r8\n\t" - "adc r11, r11, #0\n\t" - /* A[4] * A[5] */ - "ldr r6, [%[a], #16]\n\t" - "ldr r8, [%[a], #20]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r9, r9, r6\n\t" - "adcs r10, r10, r8\n\t" - "adc r11, r11, #0\n\t" - "adds r9, r9, r9\n\t" - "adcs r10, r10, r10\n\t" - "adc r11, r11, r11\n\t" - "adds r3, r3, r9\n\t" - "adcs r4, r4, r10\n\t" - "adc r5, r5, r11\n\t" - "str r3, [%[r], #36]\n\t" - "mov r3, #0\n\t" - /* A[3] * A[7] */ - "ldr r6, [%[a], #12]\n\t" - "ldr r8, [%[a], #28]\n\t" - "umull r9, r10, r6, r8\n\t" - "mov r11, #0\n\t" - /* A[4] * A[6] */ - "ldr r6, [%[a], #16]\n\t" - "ldr r8, [%[a], #24]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r9, r9, r6\n\t" - "adcs r10, r10, r8\n\t" - "adc r11, r11, #0\n\t" - /* A[5] * A[5] */ - "ldr r6, [%[a], #20]\n\t" - "umull r6, r8, r6, r6\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - "adds r9, r9, r9\n\t" - "adcs r10, r10, r10\n\t" - "adc r11, r11, r11\n\t" - "adds r4, r4, r9\n\t" - "adcs r5, r5, r10\n\t" - "adc r3, r3, r11\n\t" - "str r4, [%[r], #40]\n\t" - "mov r4, #0\n\t" - /* A[4] * A[7] */ - "ldr r6, [%[a], #16]\n\t" - "ldr r8, [%[a], #28]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - /* A[5] * A[6] */ - "ldr r6, [%[a], #20]\n\t" - "ldr r8, [%[a], #24]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - "adds r5, r5, r6\n\t" - "adcs r3, r3, r8\n\t" - "adc r4, r4, #0\n\t" - "str r5, [%[r], #44]\n\t" - "mov r5, #0\n\t" - /* A[5] * A[7] */ - "ldr r6, [%[a], #20]\n\t" - "ldr r8, [%[a], #28]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - /* A[6] * A[6] */ - "ldr r6, [%[a], #24]\n\t" - "umull r6, r8, r6, r6\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, #0\n\t" - "str r3, [%[r], #48]\n\t" - "mov r3, #0\n\t" - /* A[6] * A[7] */ - "ldr r6, [%[a], #24]\n\t" - "ldr r8, [%[a], #28]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r3, r3, #0\n\t" - "str r4, [%[r], #52]\n\t" - "mov r4, #0\n\t" - /* A[7] * A[7] */ - "ldr r6, [%[a], #28]\n\t" - "umull r6, r8, r6, r6\n\t" - "adds r5, r5, r6\n\t" - "adc r3, r3, r8\n\t" - "str r5, [%[r], #56]\n\t" - "str r3, [%[r], #60]\n\t" - /* Transfer tmp to r */ - "ldr r3, [%[tmp], #0]\n\t" - "ldr r4, [%[tmp], #4]\n\t" - "ldr r5, [%[tmp], #8]\n\t" - "ldr r6, [%[tmp], #12]\n\t" - "str r3, [%[r], #0]\n\t" - "str r4, [%[r], #4]\n\t" - "str r5, [%[r], #8]\n\t" - "str r6, [%[r], #12]\n\t" - "ldr r3, [%[tmp], #16]\n\t" - "ldr r4, [%[tmp], #20]\n\t" - "ldr r5, [%[tmp], #24]\n\t" - "ldr r6, [%[tmp], #28]\n\t" - "str r3, [%[r], #16]\n\t" - "str r4, [%[r], #20]\n\t" - "str r5, [%[r], #24]\n\t" - "str r6, [%[r], #28]\n\t" - : - : [r] "r" (r), [a] "r" (a), [tmp] "r" (tmp) - : "memory", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11" - ); -} - #ifdef WOLFSSL_SP_SMALL /* Order-2 for the P256 curve. */ static const uint32_t p256_order_minus_2[8] = { @@ -21196,7 +21580,7 @@ static const uint32_t p256_order_minus_2[8] = { }; #else /* The low half of the order-2 of the P256 curve. */ -static const uint32_t p256_order_low[4] = { +static const sp_int_digit p256_order_low[4] = { 0xfc63254fU,0xf3b9cac2U,0xa7179e84U,0xbce6faadU }; #endif /* WOLFSSL_SP_SMALL */ @@ -21342,7 +21726,7 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6 */ for (i=127; i>=112; i--) { sp_256_mont_sqr_order_8(t2, t2); - if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_256_mont_mul_order_8(t2, t2, a); } } @@ -21352,7 +21736,7 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84 */ for (i=107; i>=64; i--) { sp_256_mont_sqr_order_8(t2, t2); - if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_256_mont_mul_order_8(t2, t2, a); } } @@ -21362,7 +21746,7 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2 */ for (i=59; i>=32; i--) { sp_256_mont_sqr_order_8(t2, t2); - if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_256_mont_mul_order_8(t2, t2, a); } } @@ -21372,7 +21756,7 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a, /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254 */ for (i=27; i>=0; i--) { sp_256_mont_sqr_order_8(t2, t2); - if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_256_mont_mul_order_8(t2, t2, a); } } @@ -21383,12 +21767,63 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a, #endif /* WOLFSSL_SP_SMALL */ } -#endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ #ifdef HAVE_ECC_SIGN #ifndef SP_ECC_MAX_SIG_GEN #define SP_ECC_MAX_SIG_GEN 64 #endif +/* Calculate second signature value S from R, k and private value. + * + * s = (r * x + e) / k + * + * s Signature value. + * r First signature value. + * k Ephemeral private key. + * x Private key as a number. + * e Hash of message as a number. + * tmp Temporary storage for intermediate numbers. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_256_calc_s_8(sp_digit* s, const sp_digit* r, sp_digit* k, + sp_digit* x, const sp_digit* e, sp_digit* tmp) +{ + int err; + sp_digit carry; + int32_t c; + sp_digit* kInv = k; + + /* Conv k to Montgomery form (mod order) */ + sp_256_mul_8(k, k, p256_norm_order); + err = sp_256_mod_8(k, k, p256_order); + if (err == MP_OKAY) { + sp_256_norm_8(k); + + /* kInv = 1/k mod order */ + sp_256_mont_inv_order_8(kInv, k, tmp); + sp_256_norm_8(kInv); + + /* s = r * x + e */ + sp_256_mul_8(x, x, r); + err = sp_256_mod_8(x, x, p256_order); + } + if (err == MP_OKAY) { + sp_256_norm_8(x); + carry = sp_256_add_8(s, e, x); + sp_256_cond_sub_8(s, s, p256_order, 0 - carry); + sp_256_norm_8(s); + c = sp_256_cmp_8(s, p256_order); + sp_256_cond_sub_8(s, s, p256_order, 0L - (sp_digit)(c >= 0)); + sp_256_norm_8(s); + + /* s = s * k^-1 mod order */ + sp_256_mont_mul_order_8(s, s, kInv); + sp_256_norm_8(s); + } + + return err; +} + /* Sign the hash using the private key. * e = [hash, 256 bits] from binary * r = (k.G)->x mod order @@ -21423,8 +21858,8 @@ typedef struct sp_ecc_sign_256_ctx { int i; } sp_ecc_sign_256_ctx; -int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, + mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_sign_256_ctx* ctx = (sp_ecc_sign_256_ctx*)sp_ctx->data; @@ -21564,8 +21999,8 @@ int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, W } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, + const mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -21583,11 +22018,9 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit* r = NULL; sp_digit* tmp = NULL; sp_point_256* point = NULL; - sp_digit carry; sp_digit* s = NULL; - sp_digit* kInv = NULL; - int err = MP_OKAY; int32_t c; + int err = MP_OKAY; int i; (void)heap; @@ -21618,7 +22051,6 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, tmp = td; #endif s = e; - kInv = k; if (hashLen > 32U) { hashLen = 32U; @@ -21626,8 +22058,6 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, } for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) { - sp_256_from_mp(x, 8, priv); - /* New random point. */ if (km == NULL || mp_iszero(km)) { err = sp_256_ecc_gen_k_8(rng, k); @@ -21637,7 +22067,7 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, mp_zero(km); } if (err == MP_OKAY) { - err = sp_256_ecc_mulmod_base_8(point, k, 1, 1, NULL); + err = sp_256_ecc_mulmod_base_8(point, k, 1, 1, heap); } if (err == MP_OKAY) { @@ -21648,38 +22078,15 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_256_cond_sub_8(r, r, p256_order, 0L - (sp_digit)(c >= 0)); sp_256_norm_8(r); - /* Conv k to Montgomery form (mod order) */ - sp_256_mul_8(k, k, p256_norm_order); - err = sp_256_mod_8(k, k, p256_order); - } - if (err == MP_OKAY) { - sp_256_norm_8(k); - /* kInv = 1/k mod order */ - sp_256_mont_inv_order_8(kInv, k, tmp); - sp_256_norm_8(kInv); - - /* s = r * x + e */ - sp_256_mul_8(x, x, r); - err = sp_256_mod_8(x, x, p256_order); - } - if (err == MP_OKAY) { - sp_256_norm_8(x); + sp_256_from_mp(x, 8, priv); sp_256_from_bin(e, 8, hash, (int)hashLen); - carry = sp_256_add_8(s, e, x); - sp_256_cond_sub_8(s, s, p256_order, 0 - carry); - sp_256_norm_8(s); - c = sp_256_cmp_8(s, p256_order); - sp_256_cond_sub_8(s, s, p256_order, 0L - (sp_digit)(c >= 0)); - sp_256_norm_8(s); - /* s = s * k^-1 mod order */ - sp_256_mont_mul_order_8(s, s, kInv); - sp_256_norm_8(s); + err = sp_256_calc_s_8(s, r, k, x, e, tmp); + } - /* Check that signature is usable. */ - if (sp_256_iszero_8(s) == 0) { - break; - } + /* Check that signature is usable. */ + if ((err == MP_OKAY) && (sp_256_iszero_8(s) == 0)) { + break; } #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP i = 1; @@ -21707,7 +22114,6 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, XMEMSET(x, 0, sizeof(sp_digit) * 2U * 8U); XMEMSET(k, 0, sizeof(sp_digit) * 2U * 8U); XMEMSET(r, 0, sizeof(sp_digit) * 2U * 8U); - XMEMSET(r, 0, sizeof(sp_digit) * 2U * 8U); XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 8U); #endif sp_256_point_free_8(point, 1, heap); @@ -22001,6 +22407,96 @@ static int sp_256_mod_inv_8(sp_digit* r, const sp_digit* a, const sp_digit* m) } #endif /* WOLFSSL_SP_SMALL */ + +/* Add point p1 into point p2. Handles p1 == p2 and result at infinity. + * + * p1 First point to add and holds result. + * p2 Second point to add. + * tmp Temporary storage for intermediate numbers. + */ +static void sp_256_add_points_8(sp_point_256* p1, const sp_point_256* p2, + sp_digit* tmp) +{ + + sp_256_proj_point_add_8(p1, p1, p2, tmp); + if (sp_256_iszero_8(p1->z)) { + if (sp_256_iszero_8(p1->x) && sp_256_iszero_8(p1->y)) { + sp_256_proj_point_dbl_8(p1, p2, tmp); + } + else { + /* Y ordinate is not used from here - don't set. */ + p1->x[0] = 0; + p1->x[1] = 0; + p1->x[2] = 0; + p1->x[3] = 0; + p1->x[4] = 0; + p1->x[5] = 0; + p1->x[6] = 0; + p1->x[7] = 0; + XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod)); + } + } +} + +/* Calculate the verification point: [e/s]G + [r/s]Q + * + * p1 Calculated point. + * p2 Public point and temporary. + * s Second part of signature as a number. + * u1 Temporary number. + * u2 Temproray number. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_256_calc_vfy_point_8(sp_point_256* p1, sp_point_256* p2, + sp_digit* s, sp_digit* u1, sp_digit* u2, sp_digit* tmp, void* heap) +{ + int err; + +#ifndef WOLFSSL_SP_SMALL + { + sp_256_mod_inv_8(s, s, p256_order); + } +#endif /* !WOLFSSL_SP_SMALL */ + { + sp_256_mul_8(s, s, p256_norm_order); + } + err = sp_256_mod_8(s, s, p256_order); + if (err == MP_OKAY) { + sp_256_norm_8(s); +#ifdef WOLFSSL_SP_SMALL + { + sp_256_mont_inv_order_8(s, s, tmp); + sp_256_mont_mul_order_8(u1, u1, s); + sp_256_mont_mul_order_8(u2, u2, s); + } + +#else + { + sp_256_mont_mul_order_8(u1, u1, s); + sp_256_mont_mul_order_8(u2, u2, s); + } + +#endif /* WOLFSSL_SP_SMALL */ + err = sp_256_ecc_mulmod_base_8(p1, u1, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_256_iszero_8(p1->z)) { + p1->infinity = 1; + } + if (err == MP_OKAY) { + err = sp_256_ecc_mulmod_8(p2, p2, u2, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_256_iszero_8(p2->z)) { + p2->infinity = 1; + } + + if (err == MP_OKAY) { + sp_256_add_points_8(p1, p2, tmp); + } + + return err; +} + #ifdef HAVE_ECC_VERIFY /* Verify the signature values with the hash and public key. * e = Truncate(hash, 256) @@ -22019,8 +22515,7 @@ static int sp_256_mod_inv_8(sp_digit* r, const sp_digit* a, const sp_digit* m) * rm First part of result as an mp_int. * sm Sirst part of result as an mp_int. * heap Heap to use for allocation. - * returns RNG failures, MEMORY_E when memory allocation fails and - * MP_OKAY on success. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ #ifdef WOLFSSL_SP_NONBLOCK typedef struct sp_ecc_verify_256_ctx { @@ -22039,8 +22534,9 @@ typedef struct sp_ecc_verify_256_ctx { sp_point_256 p2; } sp_ecc_verify_256_ctx; -int sp_ecc_verify_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, + word32 hashLen, const mp_int* pX, const mp_int* pY, const mp_int* pZ, + const mp_int* r, const mp_int* sm, int* res, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_verify_256_ctx* ctx = (sp_ecc_verify_256_ctx*)sp_ctx->data; @@ -22194,8 +22690,9 @@ int sp_ecc_verify_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_256(const byte* hash, word32 hashLen, const mp_int* pX, + const mp_int* pY, const mp_int* pZ, const mp_int* r, const mp_int* sm, + int* res, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -22214,7 +22711,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_point_256* p1; sp_point_256* p2 = NULL; sp_digit carry; - int32_t c; + int32_t c = 0; int err; err = sp_256_point_new_8(heap, p1d, p1); @@ -22255,66 +22752,9 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_256_from_mp(p2->y, 8, pY); sp_256_from_mp(p2->z, 8, pZ); -#ifndef WOLFSSL_SP_SMALL - { - sp_256_mod_inv_8(s, s, p256_order); - } -#endif /* !WOLFSSL_SP_SMALL */ - { - sp_256_mul_8(s, s, p256_norm_order); - } - err = sp_256_mod_8(s, s, p256_order); + err = sp_256_calc_vfy_point_8(p1, p2, s, u1, u2, tmp, heap); } if (err == MP_OKAY) { - sp_256_norm_8(s); -#ifdef WOLFSSL_SP_SMALL - { - sp_256_mont_inv_order_8(s, s, tmp); - sp_256_mont_mul_order_8(u1, u1, s); - sp_256_mont_mul_order_8(u2, u2, s); - } - -#else - { - sp_256_mont_mul_order_8(u1, u1, s); - sp_256_mont_mul_order_8(u2, u2, s); - } - -#endif /* WOLFSSL_SP_SMALL */ - err = sp_256_ecc_mulmod_base_8(p1, u1, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_256_iszero_8(p1->z)) { - p1->infinity = 1; - } - if (err == MP_OKAY) { - err = sp_256_ecc_mulmod_8(p2, p2, u2, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_256_iszero_8(p2->z)) { - p2->infinity = 1; - } - - if (err == MP_OKAY) { - { - sp_256_proj_point_add_8(p1, p1, p2, tmp); - if (sp_256_iszero_8(p1->z)) { - if (sp_256_iszero_8(p1->x) && sp_256_iszero_8(p1->y)) { - sp_256_proj_point_dbl_8(p1, p2, tmp); - } - else { - /* Y ordinate is not used from here - don't set. */ - p1->x[0] = 0; - p1->x[1] = 0; - p1->x[2] = 0; - p1->x[3] = 0; - p1->x[4] = 0; - p1->x[5] = 0; - p1->x[6] = 0; - p1->x[7] = 0; - XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod)); - } - } - } - /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */ /* Reload r and convert to Montgomery form. */ sp_256_from_mp(u2, 8, r); @@ -22336,16 +22776,16 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, /* Compare with mod and if greater or equal then not valid. */ c = sp_256_cmp_8(u2, p256_mod); - if (c < 0) { - /* Convert to Montogomery form */ - err = sp_256_mod_mul_norm_8(u2, u2, p256_mod); - if (err == MP_OKAY) { - /* u1 = (r + 1*order).z'.z' mod prime */ - sp_256_mont_mul_8(u1, u2, p1->z, p256_mod, - p256_mp_mod); - *res = (int)(sp_256_cmp_8(p1->x, u1) == 0); - } - } + } + } + if ((*res == 0) && (c < 0)) { + /* Convert to Montogomery form */ + err = sp_256_mod_mul_norm_8(u2, u2, p256_mod); + if (err == MP_OKAY) { + /* u1 = (r + 1*order).z'.z' mod prime */ + sp_256_mont_mul_8(u1, u2, p1->z, p256_mod, + p256_mp_mod); + *res = (sp_256_cmp_8(p1->x, u1) == 0); } } } @@ -22369,7 +22809,8 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -static int sp_256_ecc_is_point_8(sp_point_256* point, void* heap) +static int sp_256_ecc_is_point_8(const sp_point_256* point, + void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -22432,7 +22873,7 @@ static int sp_256_ecc_is_point_8(sp_point_256* point, void* heap) * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) +int sp_ecc_is_point_256(const mp_int* pX, const mp_int* pY) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_256 pubd; @@ -22466,7 +22907,8 @@ int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and * MP_OKAY otherwise. */ -int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) +int sp_ecc_check_key_256(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit privd[8]; @@ -22520,12 +22962,11 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) } } - if (err == MP_OKAY) { - /* Check range of X and Y */ - if (sp_256_cmp_8(pub->x, p256_mod) >= 0 || - sp_256_cmp_8(pub->y, p256_mod) >= 0) { - err = ECC_OUT_OF_RANGE_E; - } + /* Check range of X and Y */ + if ((err == MP_OKAY) && + ((sp_256_cmp_8(pub->x, p256_mod) >= 0) || + (sp_256_cmp_8(pub->y, p256_mod) >= 0))) { + err = ECC_OUT_OF_RANGE_E; } if (err == MP_OKAY) { @@ -22537,12 +22978,10 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Point * order = infinity */ err = sp_256_ecc_mulmod_8(p, pub, p256_order, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is infinity */ - if ((sp_256_iszero_8(p->x) == 0) || - (sp_256_iszero_8(p->y) == 0)) { - err = ECC_INF_E; - } + /* Check result is infinity */ + if ((err == MP_OKAY) && ((sp_256_iszero_8(p->x) == 0) || + (sp_256_iszero_8(p->y) == 0))) { + err = ECC_INF_E; } if (privm) { @@ -22550,12 +22989,11 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Base * private = point */ err = sp_256_ecc_mulmod_base_8(p, priv, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is public key */ - if (sp_256_cmp_8(p->x, pub->x) != 0 || - sp_256_cmp_8(p->y, pub->y) != 0) { - err = ECC_PRIV_KEY_E; - } + /* Check result is public key */ + if ((err == MP_OKAY) && + ((sp_256_cmp_8(p->x, pub->x) != 0) || + (sp_256_cmp_8(p->y, pub->y) != 0))) { + err = ECC_PRIV_KEY_E; } } @@ -22745,7 +23183,7 @@ int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ) sp_256_from_mp(p->y, 8, pY); sp_256_from_mp(p->z, 8, pZ); - sp_256_map_8(p, p, tmp); + sp_256_map_8(p, p, tmp); } if (err == MP_OKAY) { @@ -22925,9 +23363,13 @@ int sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym) /* Point structure to use. */ typedef struct sp_point_384 { + /* X ordinate of point. */ sp_digit x[2 * 12]; + /* Y ordinate of point. */ sp_digit y[2 * 12]; + /* Z ordinate of point. */ sp_digit z[2 * 12]; + /* Indicates point is at infinity. */ int infinity; } sp_point_384; @@ -22997,336 +23439,6 @@ static const sp_digit p384_b[12] = { }; #endif -static int sp_384_point_new_ex_12(void* heap, sp_point_384* sp, sp_point_384** p) -{ - int ret = MP_OKAY; - (void)heap; -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - (void)sp; - *p = (sp_point_384*)XMALLOC(sizeof(sp_point_384), heap, DYNAMIC_TYPE_ECC); -#else - *p = sp; -#endif - if (*p == NULL) { - ret = MEMORY_E; - } - return ret; -} - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) -/* Allocate memory for point and return error. */ -#define sp_384_point_new_12(heap, sp, p) sp_384_point_new_ex_12((heap), NULL, &(p)) -#else -/* Set pointer to data and return no error. */ -#define sp_384_point_new_12(heap, sp, p) sp_384_point_new_ex_12((heap), &(sp), &(p)) -#endif - - -static void sp_384_point_free_12(sp_point_384* p, int clear, void* heap) -{ -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) -/* If valid pointer then clear point data if requested and free data. */ - if (p != NULL) { - if (clear != 0) { - XMEMSET(p, 0, sizeof(*p)); - } - XFREE(p, heap, DYNAMIC_TYPE_ECC); - } -#else -/* Clear point data if requested. */ - if (clear != 0) { - XMEMSET(p, 0, sizeof(*p)); - } -#endif - (void)heap; -} - -/* Multiply a number by Montogmery normalizer mod modulus (prime). - * - * r The resulting Montgomery form number. - * a The number to convert. - * m The modulus (prime). - * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. - */ -static int sp_384_mod_mul_norm_12(sp_digit* r, const sp_digit* a, const sp_digit* m) -{ -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - int64_t* t; -#else - int64_t t[12]; -#endif - int64_t o; - int err = MP_OKAY; - - (void)m; - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - t = (int64_t*)XMALLOC(sizeof(int64_t) * 12, NULL, DYNAMIC_TYPE_ECC); - if (t == NULL) { - err = MEMORY_E; - } -#endif - - if (err == MP_OKAY) { - /* 1 0 0 0 0 0 0 0 1 1 0 -1 */ - t[0] = 0 + (uint64_t)a[0] + (uint64_t)a[8] + (uint64_t)a[9] - (uint64_t)a[11]; - /* -1 1 0 0 0 0 0 0 -1 0 1 1 */ - t[1] = 0 - (uint64_t)a[0] + (uint64_t)a[1] - (uint64_t)a[8] + (uint64_t)a[10] + (uint64_t)a[11]; - /* 0 -1 1 0 0 0 0 0 0 -1 0 1 */ - t[2] = 0 - (uint64_t)a[1] + (uint64_t)a[2] - (uint64_t)a[9] + (uint64_t)a[11]; - /* 1 0 -1 1 0 0 0 0 1 1 -1 -1 */ - t[3] = 0 + (uint64_t)a[0] - (uint64_t)a[2] + (uint64_t)a[3] + (uint64_t)a[8] + (uint64_t)a[9] - (uint64_t)a[10] - (uint64_t)a[11]; - /* 1 1 0 -1 1 0 0 0 1 2 1 -2 */ - t[4] = 0 + (uint64_t)a[0] + (uint64_t)a[1] - (uint64_t)a[3] + (uint64_t)a[4] + (uint64_t)a[8] + 2 * (uint64_t)a[9] + (uint64_t)a[10] - 2 * (uint64_t)a[11]; - /* 0 1 1 0 -1 1 0 0 0 1 2 1 */ - t[5] = 0 + (uint64_t)a[1] + (uint64_t)a[2] - (uint64_t)a[4] + (uint64_t)a[5] + (uint64_t)a[9] + 2 * (uint64_t)a[10] + (uint64_t)a[11]; - /* 0 0 1 1 0 -1 1 0 0 0 1 2 */ - t[6] = 0 + (uint64_t)a[2] + (uint64_t)a[3] - (uint64_t)a[5] + (uint64_t)a[6] + (uint64_t)a[10] + 2 * (uint64_t)a[11]; - /* 0 0 0 1 1 0 -1 1 0 0 0 1 */ - t[7] = 0 + (uint64_t)a[3] + (uint64_t)a[4] - (uint64_t)a[6] + (uint64_t)a[7] + (uint64_t)a[11]; - /* 0 0 0 0 1 1 0 -1 1 0 0 0 */ - t[8] = 0 + (uint64_t)a[4] + (uint64_t)a[5] - (uint64_t)a[7] + (uint64_t)a[8]; - /* 0 0 0 0 0 1 1 0 -1 1 0 0 */ - t[9] = 0 + (uint64_t)a[5] + (uint64_t)a[6] - (uint64_t)a[8] + (uint64_t)a[9]; - /* 0 0 0 0 0 0 1 1 0 -1 1 0 */ - t[10] = 0 + (uint64_t)a[6] + (uint64_t)a[7] - (uint64_t)a[9] + (uint64_t)a[10]; - /* 0 0 0 0 0 0 0 1 1 0 -1 1 */ - t[11] = 0 + (uint64_t)a[7] + (uint64_t)a[8] - (uint64_t)a[10] + (uint64_t)a[11]; - - t[1] += t[0] >> 32; t[0] &= 0xffffffff; - t[2] += t[1] >> 32; t[1] &= 0xffffffff; - t[3] += t[2] >> 32; t[2] &= 0xffffffff; - t[4] += t[3] >> 32; t[3] &= 0xffffffff; - t[5] += t[4] >> 32; t[4] &= 0xffffffff; - t[6] += t[5] >> 32; t[5] &= 0xffffffff; - t[7] += t[6] >> 32; t[6] &= 0xffffffff; - t[8] += t[7] >> 32; t[7] &= 0xffffffff; - t[9] += t[8] >> 32; t[8] &= 0xffffffff; - t[10] += t[9] >> 32; t[9] &= 0xffffffff; - t[11] += t[10] >> 32; t[10] &= 0xffffffff; - o = t[11] >> 32; t[11] &= 0xffffffff; - t[0] += o; - t[1] -= o; - t[3] += o; - t[4] += o; - t[1] += t[0] >> 32; t[0] &= 0xffffffff; - t[2] += t[1] >> 32; t[1] &= 0xffffffff; - t[3] += t[2] >> 32; t[2] &= 0xffffffff; - t[4] += t[3] >> 32; t[3] &= 0xffffffff; - t[5] += t[4] >> 32; t[4] &= 0xffffffff; - t[6] += t[5] >> 32; t[5] &= 0xffffffff; - t[7] += t[6] >> 32; t[6] &= 0xffffffff; - t[8] += t[7] >> 32; t[7] &= 0xffffffff; - t[9] += t[8] >> 32; t[8] &= 0xffffffff; - t[10] += t[9] >> 32; t[9] &= 0xffffffff; - t[11] += t[10] >> 32; t[10] &= 0xffffffff; - - r[0] = t[0]; - r[1] = t[1]; - r[2] = t[2]; - r[3] = t[3]; - r[4] = t[4]; - r[5] = t[5]; - r[6] = t[6]; - r[7] = t[7]; - r[8] = t[8]; - r[9] = t[9]; - r[10] = t[10]; - r[11] = t[11]; - } - -#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) - if (t != NULL) - XFREE(t, NULL, DYNAMIC_TYPE_ECC); -#endif - - return err; -} - -/* Convert an mp_int to an array of sp_digit. - * - * r A single precision integer. - * size Maximum number of bytes to convert - * a A multi-precision integer. - */ -static void sp_384_from_mp(sp_digit* r, int size, const mp_int* a) -{ -#if DIGIT_BIT == 32 - int j; - - XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); - - for (j = a->used; j < size; j++) { - r[j] = 0; - } -#elif DIGIT_BIT > 32 - int i, j = 0; - word32 s = 0; - - r[0] = 0; - for (i = 0; i < a->used && j < size; i++) { - r[j] |= ((sp_digit)a->dp[i] << s); - r[j] &= 0xffffffff; - s = 32U - s; - if (j + 1 >= size) { - break; - } - /* lint allow cast of mismatch word32 and mp_digit */ - r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ - while ((s + 32U) <= (word32)DIGIT_BIT) { - s += 32U; - r[j] &= 0xffffffff; - if (j + 1 >= size) { - break; - } - if (s < (word32)DIGIT_BIT) { - /* lint allow cast of mismatch word32 and mp_digit */ - r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ - } - else { - r[++j] = 0L; - } - } - s = (word32)DIGIT_BIT - s; - } - - for (j++; j < size; j++) { - r[j] = 0; - } -#else - int i, j = 0, s = 0; - - r[0] = 0; - for (i = 0; i < a->used && j < size; i++) { - r[j] |= ((sp_digit)a->dp[i]) << s; - if (s + DIGIT_BIT >= 32) { - r[j] &= 0xffffffff; - if (j + 1 >= size) { - break; - } - s = 32 - s; - if (s == DIGIT_BIT) { - r[++j] = 0; - s = 0; - } - else { - r[++j] = a->dp[i] >> s; - s = DIGIT_BIT - s; - } - } - else { - s += DIGIT_BIT; - } - } - - for (j++; j < size; j++) { - r[j] = 0; - } -#endif -} - -/* Convert a point of type ecc_point to type sp_point_384. - * - * p Point of type sp_point_384 (result). - * pm Point of type ecc_point. - */ -static void sp_384_point_from_ecc_point_12(sp_point_384* p, const ecc_point* pm) -{ - XMEMSET(p->x, 0, sizeof(p->x)); - XMEMSET(p->y, 0, sizeof(p->y)); - XMEMSET(p->z, 0, sizeof(p->z)); - sp_384_from_mp(p->x, 12, pm->x); - sp_384_from_mp(p->y, 12, pm->y); - sp_384_from_mp(p->z, 12, pm->z); - p->infinity = 0; -} - -/* Convert an array of sp_digit to an mp_int. - * - * a A single precision integer. - * r A multi-precision integer. - */ -static int sp_384_to_mp(const sp_digit* a, mp_int* r) -{ - int err; - - err = mp_grow(r, (384 + DIGIT_BIT - 1) / DIGIT_BIT); - if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ -#if DIGIT_BIT == 32 - XMEMCPY(r->dp, a, sizeof(sp_digit) * 12); - r->used = 12; - mp_clamp(r); -#elif DIGIT_BIT < 32 - int i, j = 0, s = 0; - - r->dp[0] = 0; - for (i = 0; i < 12; i++) { - r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; - s = DIGIT_BIT - s; - r->dp[++j] = (mp_digit)(a[i] >> s); - while (s + DIGIT_BIT <= 32) { - s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; - if (s == SP_WORD_SIZE) { - r->dp[j] = 0; - } - else { - r->dp[j] = (mp_digit)(a[i] >> s); - } - } - s = 32 - s; - } - r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; - mp_clamp(r); -#else - int i, j = 0, s = 0; - - r->dp[0] = 0; - for (i = 0; i < 12; i++) { - r->dp[j] |= ((mp_digit)a[i]) << s; - if (s + 32 >= DIGIT_BIT) { - #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; - #endif - s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; - s = 32 - s; - } - else { - s += 32; - } - } - r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; - mp_clamp(r); -#endif - } - - return err; -} - -/* Convert a point of type sp_point_384 to type ecc_point. - * - * p Point of type sp_point_384. - * pm Point of type ecc_point (result). - * returns MEMORY_E when allocation of memory in ecc_point fails otherwise - * MP_OKAY. - */ -static int sp_384_point_to_ecc_point_12(const sp_point_384* p, ecc_point* pm) -{ - int err; - - err = sp_384_to_mp(p->x, pm->x); - if (err == MP_OKAY) { - err = sp_384_to_mp(p->y, pm->y); - } - if (err == MP_OKAY) { - err = sp_384_to_mp(p->z, pm->z); - } - - return err; -} - /* Multiply a and b into r. (r = a * b) * * r A single precision integer. @@ -23412,6 +23524,689 @@ SP_NOINLINE static void sp_384_mul_12(sp_digit* r, const sp_digit* a, XMEMCPY(r, tmp_arr, sizeof(tmp_arr)); } +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_384_sqr_12(sp_digit* r, const sp_digit* a) +{ + __asm__ __volatile__ ( + "mov r3, #0\n\t" + "mov r4, #0\n\t" + "mov r5, #0\n\t" + "mov r9, r3\n\t" + "mov r12, %[r]\n\t" + "mov r6, #96\n\t" + "neg r6, r6\n\t" + "add sp, sp, r6\n\t" + "mov r11, sp\n\t" + "mov r10, %[a]\n\t" + "\n1:\n\t" + "mov %[r], #0\n\t" + "mov r6, #44\n\t" + "mov %[a], r9\n\t" + "subs %[a], %[a], r6\n\t" + "sbc r6, r6, r6\n\t" + "mvn r6, r6\n\t" + "and %[a], %[a], r6\n\t" + "mov r2, r9\n\t" + "sub r2, r2, %[a]\n\t" + "add %[a], %[a], r10\n\t" + "add r2, r2, r10\n\t" + "\n2:\n\t" + "cmp r2, %[a]\n\t" +#ifdef __GNUC__ + "beq 4f\n\t" +#else + "beq.n 4f\n\t" +#endif /* __GNUC__ */ + /* Multiply * 2: Start */ + "ldr r6, [%[a]]\n\t" + "ldr r8, [r2]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, %[r]\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, %[r]\n\t" + /* Multiply * 2: Done */ +#ifdef __GNUC__ + "bal 5f\n\t" +#else + "bal.n 5f\n\t" +#endif /* __GNUC__ */ + "\n4:\n\t" + /* Square: Start */ + "ldr r6, [%[a]]\n\t" + "umull r6, r8, r6, r6\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, %[r]\n\t" + /* Square: Done */ + "\n5:\n\t" + "add %[a], %[a], #4\n\t" + "sub r2, r2, #4\n\t" + "mov r6, #48\n\t" + "add r6, r6, r10\n\t" + "cmp %[a], r6\n\t" +#ifdef __GNUC__ + "beq 3f\n\t" +#else + "beq.n 3f\n\t" +#endif /* __GNUC__ */ + "cmp %[a], r2\n\t" +#ifdef __GNUC__ + "bgt 3f\n\t" +#else + "bgt.n 3f\n\t" +#endif /* __GNUC__ */ + "mov r8, r9\n\t" + "add r8, r8, r10\n\t" + "cmp %[a], r8\n\t" +#ifdef __GNUC__ + "ble 2b\n\t" +#else + "ble.n 2b\n\t" +#endif /* __GNUC__ */ + "\n3:\n\t" + "mov %[r], r11\n\t" + "mov r8, r9\n\t" + "str r3, [%[r], r8]\n\t" + "mov r3, r4\n\t" + "mov r4, r5\n\t" + "mov r5, #0\n\t" + "add r8, r8, #4\n\t" + "mov r9, r8\n\t" + "mov r6, #88\n\t" + "cmp r8, r6\n\t" +#ifdef __GNUC__ + "ble 1b\n\t" +#else + "ble.n 1b\n\t" +#endif /* __GNUC__ */ + "mov %[a], r10\n\t" + "str r3, [%[r], r8]\n\t" + "mov %[r], r12\n\t" + "mov %[a], r11\n\t" + "mov r3, #92\n\t" + "\n4:\n\t" + "ldr r6, [%[a], r3]\n\t" + "str r6, [%[r], r3]\n\t" + "subs r3, r3, #4\n\t" +#ifdef __GNUC__ + "bge 4b\n\t" +#else + "bge.n 4b\n\t" +#endif /* __GNUC__ */ + "mov r6, #96\n\t" + "add sp, sp, r6\n\t" + : + : [r] "r" (r), [a] "r" (a) + : "memory", "r2", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12" + ); +} + +#ifdef WOLFSSL_SP_SMALL +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_384_add_12(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r6, %[a]\n\t" + "mov r8, #0\n\t" + "add r6, r6, #48\n\t" + "sub r8, r8, #1\n\t" + "\n1:\n\t" + "adds %[c], %[c], r8\n\t" + "ldr r4, [%[a]]\n\t" + "ldr r5, [%[b]]\n\t" + "adcs r4, r4, r5\n\t" + "str r4, [%[r]]\n\t" + "mov %[c], #0\n\t" + "adc %[c], %[c], %[c]\n\t" + "add %[a], %[a], #4\n\t" + "add %[b], %[b], #4\n\t" + "add %[r], %[r], #4\n\t" + "cmp %[a], r6\n\t" +#ifdef __GNUC__ + "bne 1b\n\t" +#else + "bne.n 1b\n\t" +#endif /* __GNUC__ */ + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6", "r8" + ); + + return c; +} + +#else +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_384_add_12(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "mov %[c], #0\n\t" + "adc %[c], %[c], %[c]\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6", "r8" + ); + + return c; +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_384_sub_12(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r6, %[a]\n\t" + "add r6, r6, #48\n\t" + "\n1:\n\t" + "mov r5, #0\n\t" + "subs r5, r5, %[c]\n\t" + "ldr r4, [%[a]]\n\t" + "ldr r5, [%[b]]\n\t" + "sbcs r4, r4, r5\n\t" + "str r4, [%[r]]\n\t" + "sbc %[c], %[c], %[c]\n\t" + "add %[a], %[a], #4\n\t" + "add %[b], %[b], #4\n\t" + "add %[r], %[r], #4\n\t" + "cmp %[a], r6\n\t" +#ifdef __GNUC__ + "bne 1b\n\t" +#else + "bne.n 1b\n\t" +#endif /* __GNUC__ */ + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6" + ); + + return c; +} + +#else +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_384_sub_12(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldr r4, [%[a], #0]\n\t" + "ldr r5, [%[a], #4]\n\t" + "ldr r6, [%[b], #0]\n\t" + "ldr r8, [%[b], #4]\n\t" + "subs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #0]\n\t" + "str r5, [%[r], #4]\n\t" + "ldr r4, [%[a], #8]\n\t" + "ldr r5, [%[a], #12]\n\t" + "ldr r6, [%[b], #8]\n\t" + "ldr r8, [%[b], #12]\n\t" + "sbcs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #8]\n\t" + "str r5, [%[r], #12]\n\t" + "ldr r4, [%[a], #16]\n\t" + "ldr r5, [%[a], #20]\n\t" + "ldr r6, [%[b], #16]\n\t" + "ldr r8, [%[b], #20]\n\t" + "sbcs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #16]\n\t" + "str r5, [%[r], #20]\n\t" + "ldr r4, [%[a], #24]\n\t" + "ldr r5, [%[a], #28]\n\t" + "ldr r6, [%[b], #24]\n\t" + "ldr r8, [%[b], #28]\n\t" + "sbcs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #24]\n\t" + "str r5, [%[r], #28]\n\t" + "ldr r4, [%[a], #32]\n\t" + "ldr r5, [%[a], #36]\n\t" + "ldr r6, [%[b], #32]\n\t" + "ldr r8, [%[b], #36]\n\t" + "sbcs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #32]\n\t" + "str r5, [%[r], #36]\n\t" + "ldr r4, [%[a], #40]\n\t" + "ldr r5, [%[a], #44]\n\t" + "ldr r6, [%[b], #40]\n\t" + "ldr r8, [%[b], #44]\n\t" + "sbcs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #40]\n\t" + "str r5, [%[r], #44]\n\t" + "sbc %[c], %[c], %[c]\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6", "r8" + ); + + return c; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Create a new point. + * + * heap [in] Buffer to allocate dynamic memory from. + * sp [in] Data for point - only if not allocating. + * p [out] New point. + * returns MEMORY_E when dynamic memory allocation fails and 0 otherwise. + */ +static int sp_384_point_new_ex_12(void* heap, sp_point_384* sp, + sp_point_384** p) +{ + int ret = MP_OKAY; + (void)heap; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + (void)sp; + *p = (sp_point_384*)XMALLOC(sizeof(sp_point_384), heap, DYNAMIC_TYPE_ECC); +#else + *p = sp; +#endif + if (*p == NULL) { + ret = MEMORY_E; + } + return ret; +} + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* Allocate memory for point and return error. */ +#define sp_384_point_new_12(heap, sp, p) sp_384_point_new_ex_12((heap), NULL, &(p)) +#else +/* Set pointer to data and return no error. */ +#define sp_384_point_new_12(heap, sp, p) sp_384_point_new_ex_12((heap), &(sp), &(p)) +#endif + + +/* Free the point. + * + * p [in,out] Point to free. + * clear [in] Indicates whether to zeroize point. + * heap [in] Buffer from which dynamic memory was allocate from. + */ +static void sp_384_point_free_12(sp_point_384* p, int clear, void* heap) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* If valid pointer then clear point data if requested and free data. */ + if (p != NULL) { + if (clear != 0) { + XMEMSET(p, 0, sizeof(*p)); + } + XFREE(p, heap, DYNAMIC_TYPE_ECC); + } +#else +/* Clear point data if requested. */ + if ((p != NULL) && (clear != 0)) { + XMEMSET(p, 0, sizeof(*p)); + } +#endif + (void)heap; +} + +/* Multiply a number by Montogmery normalizer mod modulus (prime). + * + * r The resulting Montgomery form number. + * a The number to convert. + * m The modulus (prime). + * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. + */ +static int sp_384_mod_mul_norm_12(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + int64_t* t; +#else + int64_t t[12]; +#endif + int64_t o; + int err = MP_OKAY; + + (void)m; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = (int64_t*)XMALLOC(sizeof(int64_t) * 12, NULL, DYNAMIC_TYPE_ECC); + if (t == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { + /* 1 0 0 0 0 0 0 0 1 1 0 -1 */ + t[0] = 0 + (int64_t)a[0] + (int64_t)a[8] + (int64_t)a[9] - (int64_t)a[11]; + /* -1 1 0 0 0 0 0 0 -1 0 1 1 */ + t[1] = 0 - (int64_t)a[0] + (int64_t)a[1] - (int64_t)a[8] + (int64_t)a[10] + (int64_t)a[11]; + /* 0 -1 1 0 0 0 0 0 0 -1 0 1 */ + t[2] = 0 - (int64_t)a[1] + (int64_t)a[2] - (int64_t)a[9] + (int64_t)a[11]; + /* 1 0 -1 1 0 0 0 0 1 1 -1 -1 */ + t[3] = 0 + (int64_t)a[0] - (int64_t)a[2] + (int64_t)a[3] + (int64_t)a[8] + (int64_t)a[9] - (int64_t)a[10] - (int64_t)a[11]; + /* 1 1 0 -1 1 0 0 0 1 2 1 -2 */ + t[4] = 0 + (int64_t)a[0] + (int64_t)a[1] - (int64_t)a[3] + (int64_t)a[4] + (int64_t)a[8] + 2 * (int64_t)a[9] + (int64_t)a[10] - 2 * (int64_t)a[11]; + /* 0 1 1 0 -1 1 0 0 0 1 2 1 */ + t[5] = 0 + (int64_t)a[1] + (int64_t)a[2] - (int64_t)a[4] + (int64_t)a[5] + (int64_t)a[9] + 2 * (int64_t)a[10] + (int64_t)a[11]; + /* 0 0 1 1 0 -1 1 0 0 0 1 2 */ + t[6] = 0 + (int64_t)a[2] + (int64_t)a[3] - (int64_t)a[5] + (int64_t)a[6] + (int64_t)a[10] + 2 * (int64_t)a[11]; + /* 0 0 0 1 1 0 -1 1 0 0 0 1 */ + t[7] = 0 + (int64_t)a[3] + (int64_t)a[4] - (int64_t)a[6] + (int64_t)a[7] + (int64_t)a[11]; + /* 0 0 0 0 1 1 0 -1 1 0 0 0 */ + t[8] = 0 + (int64_t)a[4] + (int64_t)a[5] - (int64_t)a[7] + (int64_t)a[8]; + /* 0 0 0 0 0 1 1 0 -1 1 0 0 */ + t[9] = 0 + (int64_t)a[5] + (int64_t)a[6] - (int64_t)a[8] + (int64_t)a[9]; + /* 0 0 0 0 0 0 1 1 0 -1 1 0 */ + t[10] = 0 + (int64_t)a[6] + (int64_t)a[7] - (int64_t)a[9] + (int64_t)a[10]; + /* 0 0 0 0 0 0 0 1 1 0 -1 1 */ + t[11] = 0 + (int64_t)a[7] + (int64_t)a[8] - (int64_t)a[10] + (int64_t)a[11]; + + t[1] += t[0] >> 32; t[0] &= 0xffffffff; + t[2] += t[1] >> 32; t[1] &= 0xffffffff; + t[3] += t[2] >> 32; t[2] &= 0xffffffff; + t[4] += t[3] >> 32; t[3] &= 0xffffffff; + t[5] += t[4] >> 32; t[4] &= 0xffffffff; + t[6] += t[5] >> 32; t[5] &= 0xffffffff; + t[7] += t[6] >> 32; t[6] &= 0xffffffff; + t[8] += t[7] >> 32; t[7] &= 0xffffffff; + t[9] += t[8] >> 32; t[8] &= 0xffffffff; + t[10] += t[9] >> 32; t[9] &= 0xffffffff; + t[11] += t[10] >> 32; t[10] &= 0xffffffff; + o = t[11] >> 32; t[11] &= 0xffffffff; + t[0] += o; + t[1] -= o; + t[3] += o; + t[4] += o; + t[1] += t[0] >> 32; t[0] &= 0xffffffff; + t[2] += t[1] >> 32; t[1] &= 0xffffffff; + t[3] += t[2] >> 32; t[2] &= 0xffffffff; + t[4] += t[3] >> 32; t[3] &= 0xffffffff; + t[5] += t[4] >> 32; t[4] &= 0xffffffff; + t[6] += t[5] >> 32; t[5] &= 0xffffffff; + t[7] += t[6] >> 32; t[6] &= 0xffffffff; + t[8] += t[7] >> 32; t[7] &= 0xffffffff; + t[9] += t[8] >> 32; t[8] &= 0xffffffff; + t[10] += t[9] >> 32; t[9] &= 0xffffffff; + t[11] += t[10] >> 32; t[10] &= 0xffffffff; + + r[0] = t[0]; + r[1] = t[1]; + r[2] = t[2]; + r[3] = t[3]; + r[4] = t[4]; + r[5] = t[5]; + r[6] = t[6]; + r[7] = t[7]; + r[8] = t[8]; + r[9] = t[9]; + r[10] = t[10]; + r[11] = t[11]; + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (t != NULL) + XFREE(t, NULL, DYNAMIC_TYPE_ECC); +#endif + + return err; +} + +/* Convert an mp_int to an array of sp_digit. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a A multi-precision integer. + */ +static void sp_384_from_mp(sp_digit* r, int size, const mp_int* a) +{ +#if DIGIT_BIT == 32 + int j; + + XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); + + for (j = a->used; j < size; j++) { + r[j] = 0; + } +#elif DIGIT_BIT > 32 + int i; + int j = 0; + word32 s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i] << s); + r[j] &= 0xffffffff; + s = 32U - s; + if (j + 1 >= size) { + break; + } + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + while ((s + 32U) <= (word32)DIGIT_BIT) { + s += 32U; + r[j] &= 0xffffffff; + if (j + 1 >= size) { + break; + } + if (s < (word32)DIGIT_BIT) { + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + } + else { + r[++j] = 0L; + } + } + s = (word32)DIGIT_BIT - s; + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#else + int i; + int j = 0; + int s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i]) << s; + if (s + DIGIT_BIT >= 32) { + r[j] &= 0xffffffff; + if (j + 1 >= size) { + break; + } + s = 32 - s; + if (s == DIGIT_BIT) { + r[++j] = 0; + s = 0; + } + else { + r[++j] = a->dp[i] >> s; + s = DIGIT_BIT - s; + } + } + else { + s += DIGIT_BIT; + } + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#endif +} + +/* Convert a point of type ecc_point to type sp_point_384. + * + * p Point of type sp_point_384 (result). + * pm Point of type ecc_point. + */ +static void sp_384_point_from_ecc_point_12(sp_point_384* p, + const ecc_point* pm) +{ + XMEMSET(p->x, 0, sizeof(p->x)); + XMEMSET(p->y, 0, sizeof(p->y)); + XMEMSET(p->z, 0, sizeof(p->z)); + sp_384_from_mp(p->x, 12, pm->x); + sp_384_from_mp(p->y, 12, pm->y); + sp_384_from_mp(p->z, 12, pm->z); + p->infinity = 0; +} + +/* Convert an array of sp_digit to an mp_int. + * + * a A single precision integer. + * r A multi-precision integer. + */ +static int sp_384_to_mp(const sp_digit* a, mp_int* r) +{ + int err; + + err = mp_grow(r, (384 + DIGIT_BIT - 1) / DIGIT_BIT); + if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ +#if DIGIT_BIT == 32 + XMEMCPY(r->dp, a, sizeof(sp_digit) * 12); + r->used = 12; + mp_clamp(r); +#elif DIGIT_BIT < 32 + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 12; i++) { + r->dp[j] |= (mp_digit)(a[i] << s); + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + s = DIGIT_BIT - s; + r->dp[++j] = (mp_digit)(a[i] >> s); + while (s + DIGIT_BIT <= 32) { + s += DIGIT_BIT; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; + if (s == SP_WORD_SIZE) { + r->dp[j] = 0; + } + else { + r->dp[j] = (mp_digit)(a[i] >> s); + } + } + s = 32 - s; + } + r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#else + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 12; i++) { + r->dp[j] |= ((mp_digit)a[i]) << s; + if (s + 32 >= DIGIT_BIT) { + #if DIGIT_BIT != 32 && DIGIT_BIT != 64 + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + #endif + s = DIGIT_BIT - s; + r->dp[++j] = a[i] >> s; + s = 32 - s; + } + else { + s += 32; + } + } + r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#endif + } + + return err; +} + +/* Convert a point of type sp_point_384 to type ecc_point. + * + * p Point of type sp_point_384. + * pm Point of type ecc_point (result). + * returns MEMORY_E when allocation of memory in ecc_point fails otherwise + * MP_OKAY. + */ +static int sp_384_point_to_ecc_point_12(const sp_point_384* p, ecc_point* pm) +{ + int err; + + err = sp_384_to_mp(p->x, pm->x); + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, pm->y); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, pm->z); + } + + return err; +} + /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -23566,137 +24361,13 @@ SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_384_mont_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_384_mont_mul_12(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_384_mul_12(r, a, b); sp_384_mont_reduce_12(r, m, mp); } -/* Square a and put result in r. (r = a * a) - * - * r A single precision integer. - * a A single precision integer. - */ -SP_NOINLINE static void sp_384_sqr_12(sp_digit* r, const sp_digit* a) -{ - __asm__ __volatile__ ( - "mov r3, #0\n\t" - "mov r4, #0\n\t" - "mov r5, #0\n\t" - "mov r9, r3\n\t" - "mov r12, %[r]\n\t" - "mov r6, #96\n\t" - "neg r6, r6\n\t" - "add sp, sp, r6\n\t" - "mov r11, sp\n\t" - "mov r10, %[a]\n\t" - "\n1:\n\t" - "mov %[r], #0\n\t" - "mov r6, #44\n\t" - "mov %[a], r9\n\t" - "subs %[a], %[a], r6\n\t" - "sbc r6, r6, r6\n\t" - "mvn r6, r6\n\t" - "and %[a], %[a], r6\n\t" - "mov r2, r9\n\t" - "sub r2, r2, %[a]\n\t" - "add %[a], %[a], r10\n\t" - "add r2, r2, r10\n\t" - "\n2:\n\t" - "cmp r2, %[a]\n\t" -#ifdef __GNUC__ - "beq 4f\n\t" -#else - "beq.n 4f\n\t" -#endif /* __GNUC__ */ - /* Multiply * 2: Start */ - "ldr r6, [%[a]]\n\t" - "ldr r8, [r2]\n\t" - "umull r6, r8, r6, r8\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, %[r]\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, %[r]\n\t" - /* Multiply * 2: Done */ -#ifdef __GNUC__ - "bal 5f\n\t" -#else - "bal.n 5f\n\t" -#endif /* __GNUC__ */ - "\n4:\n\t" - /* Square: Start */ - "ldr r6, [%[a]]\n\t" - "umull r6, r8, r6, r6\n\t" - "adds r3, r3, r6\n\t" - "adcs r4, r4, r8\n\t" - "adc r5, r5, %[r]\n\t" - /* Square: Done */ - "\n5:\n\t" - "add %[a], %[a], #4\n\t" - "sub r2, r2, #4\n\t" - "mov r6, #48\n\t" - "add r6, r6, r10\n\t" - "cmp %[a], r6\n\t" -#ifdef __GNUC__ - "beq 3f\n\t" -#else - "beq.n 3f\n\t" -#endif /* __GNUC__ */ - "cmp %[a], r2\n\t" -#ifdef __GNUC__ - "bgt 3f\n\t" -#else - "bgt.n 3f\n\t" -#endif /* __GNUC__ */ - "mov r8, r9\n\t" - "add r8, r8, r10\n\t" - "cmp %[a], r8\n\t" -#ifdef __GNUC__ - "ble 2b\n\t" -#else - "ble.n 2b\n\t" -#endif /* __GNUC__ */ - "\n3:\n\t" - "mov %[r], r11\n\t" - "mov r8, r9\n\t" - "str r3, [%[r], r8]\n\t" - "mov r3, r4\n\t" - "mov r4, r5\n\t" - "mov r5, #0\n\t" - "add r8, r8, #4\n\t" - "mov r9, r8\n\t" - "mov r6, #88\n\t" - "cmp r8, r6\n\t" -#ifdef __GNUC__ - "ble 1b\n\t" -#else - "ble.n 1b\n\t" -#endif /* __GNUC__ */ - "mov %[a], r10\n\t" - "str r3, [%[r], r8]\n\t" - "mov %[r], r12\n\t" - "mov %[a], r11\n\t" - "mov r3, #92\n\t" - "\n4:\n\t" - "ldr r6, [%[a], r3]\n\t" - "str r6, [%[r], r3]\n\t" - "subs r3, r3, #4\n\t" -#ifdef __GNUC__ - "bge 4b\n\t" -#else - "bge.n 4b\n\t" -#endif /* __GNUC__ */ - "mov r6, #96\n\t" - "add sp, sp, r6\n\t" - : - : [r] "r" (r), [a] "r" (a) - : "memory", "r2", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12" - ); -} - /* Square the Montgomery form number. (r = a * a mod m) * * r Result of squaring. @@ -23704,8 +24375,8 @@ SP_NOINLINE static void sp_384_sqr_12(sp_digit* r, const sp_digit* a) * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_384_mont_sqr_12(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_384_mont_sqr_12(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_384_sqr_12(r, a); sp_384_mont_reduce_12(r, m, mp); @@ -23729,7 +24400,7 @@ static void sp_384_mont_sqr_n_12(sp_digit* r, const sp_digit* a, int n, } } -#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */ +#endif /* !WOLFSSL_SP_SMALL | HAVE_COMP_KEY */ #ifdef WOLFSSL_SP_SMALL /* Mod-2 for the P384 curve. */ static const uint32_t p384_mod_minus_2[12] = { @@ -23882,7 +24553,8 @@ SP_NOINLINE static int32_t sp_384_cmp_12(const sp_digit* a, const sp_digit* b) * p Montgomery form projective coordinate point. * t Temporary ordinate data. */ -static void sp_384_map_12(sp_point_384* r, const sp_point_384* p, sp_digit* t) +static void sp_384_map_12(sp_point_384* r, const sp_point_384* p, + sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2*12; @@ -23918,102 +24590,6 @@ static void sp_384_map_12(sp_point_384* r, const sp_point_384* p, sp_digit* t) } -#ifdef WOLFSSL_SP_SMALL -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static sp_digit sp_384_add_12(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "mov r6, %[a]\n\t" - "mov r8, #0\n\t" - "add r6, r6, #48\n\t" - "sub r8, r8, #1\n\t" - "\n1:\n\t" - "adds %[c], %[c], r8\n\t" - "ldr r4, [%[a]]\n\t" - "ldr r5, [%[b]]\n\t" - "adcs r4, r4, r5\n\t" - "str r4, [%[r]]\n\t" - "mov %[c], #0\n\t" - "adc %[c], %[c], %[c]\n\t" - "add %[a], %[a], #4\n\t" - "add %[b], %[b], #4\n\t" - "add %[r], %[r], #4\n\t" - "cmp %[a], r6\n\t" -#ifdef __GNUC__ - "bne 1b\n\t" -#else - "bne.n 1b\n\t" -#endif /* __GNUC__ */ - : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) - : - : "memory", "r4", "r5", "r6", "r8" - ); - - return c; -} - -#else -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static sp_digit sp_384_add_12(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "ldm %[a]!, {r4, r5}\n\t" - "ldm %[b]!, {r6, r8}\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "stm %[r]!, {r4, r5}\n\t" - "ldm %[a]!, {r4, r5}\n\t" - "ldm %[b]!, {r6, r8}\n\t" - "adcs r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "stm %[r]!, {r4, r5}\n\t" - "ldm %[a]!, {r4, r5}\n\t" - "ldm %[b]!, {r6, r8}\n\t" - "adcs r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "stm %[r]!, {r4, r5}\n\t" - "ldm %[a]!, {r4, r5}\n\t" - "ldm %[b]!, {r6, r8}\n\t" - "adcs r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "stm %[r]!, {r4, r5}\n\t" - "ldm %[a]!, {r4, r5}\n\t" - "ldm %[b]!, {r6, r8}\n\t" - "adcs r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "stm %[r]!, {r4, r5}\n\t" - "ldm %[a]!, {r4, r5}\n\t" - "ldm %[b]!, {r6, r8}\n\t" - "adcs r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "stm %[r]!, {r4, r5}\n\t" - "mov %[c], #0\n\t" - "adc %[c], %[c], %[c]\n\t" - : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) - : - : "memory", "r4", "r5", "r6", "r8" - ); - - return c; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Add two Montgomery form numbers (r = a + b % m). * * r Result of addition. @@ -24060,117 +24636,6 @@ SP_NOINLINE static void sp_384_mont_tpl_12(sp_digit* r, const sp_digit* a, const sp_384_cond_sub_12(r, r, m, 0 - o); } -#ifdef WOLFSSL_SP_SMALL -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static sp_digit sp_384_sub_12(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "mov r6, %[a]\n\t" - "add r6, r6, #48\n\t" - "\n1:\n\t" - "mov r5, #0\n\t" - "subs r5, r5, %[c]\n\t" - "ldr r4, [%[a]]\n\t" - "ldr r5, [%[b]]\n\t" - "sbcs r4, r4, r5\n\t" - "str r4, [%[r]]\n\t" - "sbc %[c], %[c], %[c]\n\t" - "add %[a], %[a], #4\n\t" - "add %[b], %[b], #4\n\t" - "add %[r], %[r], #4\n\t" - "cmp %[a], r6\n\t" -#ifdef __GNUC__ - "bne 1b\n\t" -#else - "bne.n 1b\n\t" -#endif /* __GNUC__ */ - : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) - : - : "memory", "r4", "r5", "r6" - ); - - return c; -} - -#else -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -SP_NOINLINE static sp_digit sp_384_sub_12(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "ldr r4, [%[a], #0]\n\t" - "ldr r5, [%[a], #4]\n\t" - "ldr r6, [%[b], #0]\n\t" - "ldr r8, [%[b], #4]\n\t" - "subs r4, r4, r6\n\t" - "sbcs r5, r5, r8\n\t" - "str r4, [%[r], #0]\n\t" - "str r5, [%[r], #4]\n\t" - "ldr r4, [%[a], #8]\n\t" - "ldr r5, [%[a], #12]\n\t" - "ldr r6, [%[b], #8]\n\t" - "ldr r8, [%[b], #12]\n\t" - "sbcs r4, r4, r6\n\t" - "sbcs r5, r5, r8\n\t" - "str r4, [%[r], #8]\n\t" - "str r5, [%[r], #12]\n\t" - "ldr r4, [%[a], #16]\n\t" - "ldr r5, [%[a], #20]\n\t" - "ldr r6, [%[b], #16]\n\t" - "ldr r8, [%[b], #20]\n\t" - "sbcs r4, r4, r6\n\t" - "sbcs r5, r5, r8\n\t" - "str r4, [%[r], #16]\n\t" - "str r5, [%[r], #20]\n\t" - "ldr r4, [%[a], #24]\n\t" - "ldr r5, [%[a], #28]\n\t" - "ldr r6, [%[b], #24]\n\t" - "ldr r8, [%[b], #28]\n\t" - "sbcs r4, r4, r6\n\t" - "sbcs r5, r5, r8\n\t" - "str r4, [%[r], #24]\n\t" - "str r5, [%[r], #28]\n\t" - "ldr r4, [%[a], #32]\n\t" - "ldr r5, [%[a], #36]\n\t" - "ldr r6, [%[b], #32]\n\t" - "ldr r8, [%[b], #36]\n\t" - "sbcs r4, r4, r6\n\t" - "sbcs r5, r5, r8\n\t" - "str r4, [%[r], #32]\n\t" - "str r5, [%[r], #36]\n\t" - "ldr r4, [%[a], #40]\n\t" - "ldr r5, [%[a], #44]\n\t" - "ldr r6, [%[b], #40]\n\t" - "ldr r8, [%[b], #44]\n\t" - "sbcs r4, r4, r6\n\t" - "sbcs r5, r5, r8\n\t" - "str r4, [%[r], #40]\n\t" - "str r5, [%[r], #44]\n\t" - "sbc %[c], %[c], %[c]\n\t" - : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) - : - : "memory", "r4", "r5", "r6", "r8" - ); - - return c; -} - -#endif /* WOLFSSL_SP_SMALL */ /* Conditionally add a and b using the mask m. * m is -1 to add and 0 when not. * @@ -24718,8 +25183,8 @@ static int sp_384_proj_point_add_12_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r, } #endif /* WOLFSSL_SP_NONBLOCK */ -static void sp_384_proj_point_add_12(sp_point_384* r, const sp_point_384* p, const sp_point_384* q, - sp_digit* t) +static void sp_384_proj_point_add_12(sp_point_384* r, + const sp_point_384* p, const sp_point_384* q, sp_digit* t) { const sp_point_384* ap[2]; sp_point_384* rp[2]; @@ -24898,9 +25363,11 @@ static void sp_384_get_point_16_12(sp_point_384* r, const sp_point_384* table, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Simple, smaller code size and memory size, of windowing. - * Calculate uindow of 4 bits. - * Only add points from table. + * Fast implementation that generates a pre-computation table. + * 4 bits of window (no sliding!). + * Uses add and double for calculating table. + * 384 doubles. + * 108 adds. * * r Resulting point. * g Point to multiply. @@ -24929,7 +25396,8 @@ static int sp_384_ecc_mulmod_fast_12(sp_point_384* r, const sp_point_384* g, con sp_digit* tmp; sp_digit n; int i; - int c, y; + int c; + int y; int err; /* Constant time used for cache attack resistance implementation. */ @@ -25002,7 +25470,7 @@ static int sp_384_ecc_mulmod_fast_12(sp_point_384* r, const sp_point_384* g, con i = 10; n = k[i+1] << 0; c = 28; - y = n >> 28; + y = (int)(n >> 28); #ifndef WC_NO_CACHE_RESISTANT if (ct) { sp_384_get_point_16_12(rt, t, y); @@ -25067,12 +25535,6 @@ static int sp_384_ecc_mulmod_fast_12(sp_point_384* r, const sp_point_384* g, con return err; } -/* A table entry for pre-computed points. */ -typedef struct sp_table_entry_384 { - sp_digit x[12]; - sp_digit y[12]; -} sp_table_entry_384; - #ifdef FP_ECC /* Double the Montgomery form projective point p a number of times. * @@ -25081,7 +25543,8 @@ typedef struct sp_table_entry_384 { * n Number of times to double * t Temporary ordinate data. */ -static void sp_384_proj_point_dbl_n_12(sp_point_384* p, int n, sp_digit* t) +static void sp_384_proj_point_dbl_n_12(sp_point_384* p, int n, + sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*12; @@ -25184,6 +25647,14 @@ static void sp_384_proj_to_affine_12(sp_point_384* a, sp_digit* t) XMEMCPY(a->z, p384_norm_mod, sizeof(p384_norm_mod)); } +#endif /* FP_ECC */ +/* A table entry for pre-computed points. */ +typedef struct sp_table_entry_384 { + sp_digit x[12]; + sp_digit y[12]; +} sp_table_entry_384; + +#ifdef FP_ECC #endif /* FP_ECC */ /* Add two Montgomery form projective points. The second point has a q value of * one. @@ -25270,6 +25741,10 @@ static void sp_384_proj_point_add_qz1_12(sp_point_384* r, const sp_point_384* p, #ifdef WOLFSSL_SP_SMALL #ifdef FP_ECC /* Generate the pre-computed table of points for the base point. + * + * width = 4 + * 16 entries + * 96 bits between * * a The base point. * table Place to store generated point data. @@ -25280,12 +25755,15 @@ static int sp_384_gen_stripe_table_12(const sp_point_384* a, sp_table_entry_384* table, sp_digit* tmp, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_point_384 td, s1d, s2d; + sp_point_384 td; + sp_point_384 s1d; + sp_point_384 s2d; #endif sp_point_384* t; sp_point_384* s1 = NULL; sp_point_384* s2 = NULL; - int i, j; + int i; + int j; int err; (void)heap; @@ -25420,8 +25898,10 @@ static void sp_384_get_entry_16_12(sp_point_384* r, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Implementation uses striping of bits. - * Choose bits 4 bits apart. + * Stripe implementation. + * Pre-generated: 2^0, 2^96, ... + * Pre-generated: products of all combinations of above. + * 4 doubles and adds (with qz=1) * * r Resulting point. * k Scalar to multiply by. @@ -25443,8 +25923,10 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, sp_point_384* rt; sp_point_384* p = NULL; sp_digit* t; - int i, j; - int y, x; + int i; + int j; + int y; + int x; int err; (void)g; @@ -25472,8 +25954,10 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, XMEMCPY(rt->z, p384_norm_mod, sizeof(p384_norm_mod)); y = 0; - for (j=0,x=95; j<4; j++,x+=96) { + x = 95; + for (j=0; j<4; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 96; } #ifndef WC_NO_CACHE_RESISTANT if (ct) { @@ -25487,8 +25971,10 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, rt->infinity = !y; for (i=94; i>=0; i--) { y = 0; - for (j=0,x=i; j<4; j++,x+=96) { + x = i; + for (j=0; j<4; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 96; } sp_384_proj_point_dbl_12(rt, rt, t); @@ -25530,16 +26016,25 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, #define FP_ENTRIES 16 #endif +/* Cache entry - holds precomputation tables for a point. */ typedef struct sp_cache_384_t { + /* X ordinate of point that table was generated from. */ sp_digit x[12]; + /* Y ordinate of point that table was generated from. */ sp_digit y[12]; + /* Precomputation table for point. */ sp_table_entry_384 table[16]; + /* Count of entries in table. */ uint32_t cnt; + /* Point and table set in entry. */ int set; } sp_cache_384_t; +/* Cache of tables. */ static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES]; +/* Index of last entry in cache. */ static THREAD_LS_T int sp_cache_384_last = -1; +/* Cache has been initialized. */ static THREAD_LS_T int sp_cache_384_inited = 0; #ifndef HAVE_THREAD_LS @@ -25547,9 +26042,15 @@ static THREAD_LS_T int sp_cache_384_inited = 0; static wolfSSL_Mutex sp_cache_384_lock; #endif +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache) { - int i, j; + int i; + int j; uint32_t least; if (sp_cache_384_inited == 0) { @@ -25658,6 +26159,10 @@ static int sp_384_ecc_mulmod_12(sp_point_384* r, const sp_point_384* g, const sp #else #ifdef FP_ECC /* Generate the pre-computed table of points for the base point. + * + * width = 8 + * 256 entries + * 48 bits between * * a The base point. * table Place to store generated point data. @@ -25668,12 +26173,15 @@ static int sp_384_gen_stripe_table_12(const sp_point_384* a, sp_table_entry_384* table, sp_digit* tmp, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_point_384 td, s1d, s2d; + sp_point_384 td; + sp_point_384 s1d; + sp_point_384 s2d; #endif sp_point_384* t; sp_point_384* s1 = NULL; sp_point_384* s2 = NULL; - int i, j; + int i; + int j; int err; (void)heap; @@ -25808,8 +26316,10 @@ static void sp_384_get_entry_256_12(sp_point_384* r, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Implementation uses striping of bits. - * Choose bits 8 bits apart. + * Stripe implementation. + * Pre-generated: 2^0, 2^48, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) * * r Resulting point. * k Scalar to multiply by. @@ -25831,8 +26341,10 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, sp_point_384* rt; sp_point_384* p = NULL; sp_digit* t; - int i, j; - int y, x; + int i; + int j; + int y; + int x; int err; (void)g; @@ -25860,8 +26372,10 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, XMEMCPY(rt->z, p384_norm_mod, sizeof(p384_norm_mod)); y = 0; - for (j=0,x=47; j<8; j++,x+=48) { + x = 47; + for (j=0; j<8; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 48; } #ifndef WC_NO_CACHE_RESISTANT if (ct) { @@ -25875,8 +26389,10 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, rt->infinity = !y; for (i=46; i>=0; i--) { y = 0; - for (j=0,x=i; j<8; j++,x+=48) { + x = i; + for (j=0; j<8; j++) { y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 48; } sp_384_proj_point_dbl_12(rt, rt, t); @@ -25918,16 +26434,25 @@ static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, #define FP_ENTRIES 16 #endif +/* Cache entry - holds precomputation tables for a point. */ typedef struct sp_cache_384_t { + /* X ordinate of point that table was generated from. */ sp_digit x[12]; + /* Y ordinate of point that table was generated from. */ sp_digit y[12]; + /* Precomputation table for point. */ sp_table_entry_384 table[256]; + /* Count of entries in table. */ uint32_t cnt; + /* Point and table set in entry. */ int set; } sp_cache_384_t; +/* Cache of tables. */ static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES]; +/* Index of last entry in cache. */ static THREAD_LS_T int sp_cache_384_last = -1; +/* Cache has been initialized. */ static THREAD_LS_T int sp_cache_384_inited = 0; #ifndef HAVE_THREAD_LS @@ -25935,9 +26460,15 @@ static THREAD_LS_T int sp_cache_384_inited = 0; static wolfSSL_Mutex sp_cache_384_lock; #endif +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache) { - int i, j; + int i; + int j; uint32_t least; if (sp_cache_384_inited == 0) { @@ -26054,8 +26585,8 @@ static int sp_384_ecc_mulmod_12(sp_point_384* r, const sp_point_384* g, const sp * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_384(mp_int* km, ecc_point* gm, ecc_point* r, int map, - void* heap) +int sp_ecc_mulmod_384(const mp_int* km, const ecc_point* gm, ecc_point* r, + int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_384 p; @@ -26096,7 +26627,94 @@ int sp_ecc_mulmod_384(mp_int* km, ecc_point* gm, ecc_point* r, int map, return err; } +/* Multiply the point by the scalar, add point a and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * p Point to multiply. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_add_384(const mp_int* km, const ecc_point* gm, + const ecc_point* am, int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_384 p; + sp_point_384 a; + sp_digit kd[12]; + sp_digit t[12 * 2 * 6]; +#endif + sp_point_384* point; + sp_point_384* addP = NULL; + sp_digit* k = NULL; + sp_digit* tmp = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_12(heap, p, point); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (12 + 12 * 2 * 6), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 12; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 12, km); + sp_384_point_from_ecc_point_12(point, gm); + sp_384_point_from_ecc_point_12(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_12(addP->x, addP->x, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_12(addP->y, addP->y, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_12(addP->z, addP->z, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_12(point, point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_384_proj_point_add_12(point, point, addP, tmp); + + if (map) { + sp_384_map_12(point, point, tmp); + } + + err = sp_384_point_to_ecc_point_12(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(addP, 0, heap); + sp_384_point_free_12(point, 0, heap); + + return err; +} + #ifdef WOLFSSL_SP_SMALL +/* Striping precomputation table. + * 4 points combined into a table of 16 points. + * Distance of 96 between points. + */ static const sp_table_entry_384 p384_table[16] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -26181,6 +26799,11 @@ static const sp_table_entry_384 p384_table[16] = { /* Multiply the base point of P384 by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Stripe implementation. + * Pre-generated: 2^0, 2^96, ... + * Pre-generated: products of all combinations of above. + * 4 doubles and adds (with qz=1) + * * r Resulting point. * k Scalar to multiply by. * map Indicates whether to convert result to affine. @@ -26196,6 +26819,10 @@ static int sp_384_ecc_mulmod_base_12(sp_point_384* r, const sp_digit* k, } #else +/* Striping precomputation table. + * 8 points combined into a table of 256 points. + * Distance of 48 between points. + */ static const sp_table_entry_384 p384_table[256] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -27480,6 +28107,11 @@ static const sp_table_entry_384 p384_table[256] = { /* Multiply the base point of P384 by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Stripe implementation. + * Pre-generated: 2^0, 2^48, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * * r Resulting point. * k Scalar to multiply by. * map Indicates whether to convert result to affine. @@ -27505,7 +28137,7 @@ static int sp_384_ecc_mulmod_base_12(sp_point_384* r, const sp_digit* k, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_base_384(mp_int* km, ecc_point* r, int map, void* heap) +int sp_ecc_mulmod_base_384(const mp_int* km, ecc_point* r, int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_384 p; @@ -27546,6 +28178,87 @@ int sp_ecc_mulmod_base_384(mp_int* km, ecc_point* r, int map, void* heap) return err; } +/* Multiply the base point of P384 by the scalar, add point a and return + * the result. If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_add_384(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_384 p; + sp_point_384 a; + sp_digit kd[12]; + sp_digit t[12 * 2 * 6]; +#endif + sp_point_384* point; + sp_point_384* addP = NULL; + sp_digit* tmp = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_12(heap, p, point); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (12 + 12 * 2 * 6), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 12; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 12, km); + sp_384_point_from_ecc_point_12(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_12(addP->x, addP->x, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_12(addP->y, addP->y, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_12(addP->z, addP->z, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_base_12(point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_384_proj_point_add_12(point, point, addP, tmp); + + if (map) { + sp_384_map_12(point, point, tmp); + } + + err = sp_384_point_to_ecc_point_12(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(addP, 0, heap); + sp_384_point_free_12(point, 0, heap); + + return err; +} + #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \ defined(HAVE_ECC_VERIFY) /* Returns 1 if the number of zero. @@ -27560,7 +28273,7 @@ static int sp_384_iszero_12(const sp_digit* a) a[8] | a[9] | a[10] | a[11]) == 0; } -#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN | HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ /* Add 1 to a. (a = a + 1) * * a A single precision integer. @@ -27621,7 +28334,8 @@ SP_NOINLINE static void sp_384_add_one_12(sp_digit* a) */ static void sp_384_from_bin(sp_digit* r, int size, const byte* a, int n) { - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -27765,7 +28479,10 @@ int sp_ecc_make_key_384(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) */ static void sp_384_to_bin(sp_digit* r, byte* a) { - int i, j, s = 0, b; + int i; + int j; + int s = 0; + int b; j = 384 / 8 - 1; a[j] = 0; @@ -27806,7 +28523,7 @@ static void sp_384_to_bin(sp_digit* r, byte* a) * returns BUFFER_E if the buffer is to small for output size, * MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_secret_gen_384(mp_int* priv, ecc_point* pub, byte* out, +int sp_ecc_secret_gen_384(const mp_int* priv, const ecc_point* pub, byte* out, word32* outLen, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) @@ -28140,7 +28857,6 @@ static const uint32_t p384_order_minus_2[12] = { /* The low half of the order-2 of the P384 curve. */ static const uint32_t p384_order_low[6] = { 0xccc52971U,0xecec196aU,0x48b0a77aU,0x581a0db2U,0xf4372ddfU,0xc7634d81U - }; #endif /* WOLFSSL_SP_SMALL */ @@ -28288,7 +29004,7 @@ static void sp_384_mont_inv_order_12(sp_digit* r, const sp_digit* a, sp_384_mont_mul_order_12(t2, t2, t); for (i=191; i>=1; i--) { sp_384_mont_sqr_order_12(t2, t2); - if (((sp_digit)p384_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p384_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_384_mont_mul_order_12(t2, t2, a); } } @@ -28297,12 +29013,63 @@ static void sp_384_mont_inv_order_12(sp_digit* r, const sp_digit* a, #endif /* WOLFSSL_SP_SMALL */ } -#endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ #ifdef HAVE_ECC_SIGN #ifndef SP_ECC_MAX_SIG_GEN #define SP_ECC_MAX_SIG_GEN 64 #endif +/* Calculate second signature value S from R, k and private value. + * + * s = (r * x + e) / k + * + * s Signature value. + * r First signature value. + * k Ephemeral private key. + * x Private key as a number. + * e Hash of message as a number. + * tmp Temporary storage for intermediate numbers. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_calc_s_12(sp_digit* s, const sp_digit* r, sp_digit* k, + sp_digit* x, const sp_digit* e, sp_digit* tmp) +{ + int err; + sp_digit carry; + int32_t c; + sp_digit* kInv = k; + + /* Conv k to Montgomery form (mod order) */ + sp_384_mul_12(k, k, p384_norm_order); + err = sp_384_mod_12(k, k, p384_order); + if (err == MP_OKAY) { + sp_384_norm_12(k); + + /* kInv = 1/k mod order */ + sp_384_mont_inv_order_12(kInv, k, tmp); + sp_384_norm_12(kInv); + + /* s = r * x + e */ + sp_384_mul_12(x, x, r); + err = sp_384_mod_12(x, x, p384_order); + } + if (err == MP_OKAY) { + sp_384_norm_12(x); + carry = sp_384_add_12(s, e, x); + sp_384_cond_sub_12(s, s, p384_order, 0 - carry); + sp_384_norm_12(s); + c = sp_384_cmp_12(s, p384_order); + sp_384_cond_sub_12(s, s, p384_order, 0L - (sp_digit)(c >= 0)); + sp_384_norm_12(s); + + /* s = s * k^-1 mod order */ + sp_384_mont_mul_order_12(s, s, kInv); + sp_384_norm_12(s); + } + + return err; +} + /* Sign the hash using the private key. * e = [hash, 384 bits] from binary * r = (k.G)->x mod order @@ -28337,8 +29104,8 @@ typedef struct sp_ecc_sign_384_ctx { int i; } sp_ecc_sign_384_ctx; -int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, + mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_sign_384_ctx* ctx = (sp_ecc_sign_384_ctx*)sp_ctx->data; @@ -28478,8 +29245,8 @@ int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, W } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, + const mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -28497,11 +29264,9 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit* r = NULL; sp_digit* tmp = NULL; sp_point_384* point = NULL; - sp_digit carry; sp_digit* s = NULL; - sp_digit* kInv = NULL; - int err = MP_OKAY; int32_t c; + int err = MP_OKAY; int i; (void)heap; @@ -28532,7 +29297,6 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, tmp = td; #endif s = e; - kInv = k; if (hashLen > 48U) { hashLen = 48U; @@ -28540,8 +29304,6 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, } for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) { - sp_384_from_mp(x, 12, priv); - /* New random point. */ if (km == NULL || mp_iszero(km)) { err = sp_384_ecc_gen_k_12(rng, k); @@ -28551,7 +29313,7 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, mp_zero(km); } if (err == MP_OKAY) { - err = sp_384_ecc_mulmod_base_12(point, k, 1, 1, NULL); + err = sp_384_ecc_mulmod_base_12(point, k, 1, 1, heap); } if (err == MP_OKAY) { @@ -28562,38 +29324,15 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_384_cond_sub_12(r, r, p384_order, 0L - (sp_digit)(c >= 0)); sp_384_norm_12(r); - /* Conv k to Montgomery form (mod order) */ - sp_384_mul_12(k, k, p384_norm_order); - err = sp_384_mod_12(k, k, p384_order); - } - if (err == MP_OKAY) { - sp_384_norm_12(k); - /* kInv = 1/k mod order */ - sp_384_mont_inv_order_12(kInv, k, tmp); - sp_384_norm_12(kInv); - - /* s = r * x + e */ - sp_384_mul_12(x, x, r); - err = sp_384_mod_12(x, x, p384_order); - } - if (err == MP_OKAY) { - sp_384_norm_12(x); + sp_384_from_mp(x, 12, priv); sp_384_from_bin(e, 12, hash, (int)hashLen); - carry = sp_384_add_12(s, e, x); - sp_384_cond_sub_12(s, s, p384_order, 0 - carry); - sp_384_norm_12(s); - c = sp_384_cmp_12(s, p384_order); - sp_384_cond_sub_12(s, s, p384_order, 0L - (sp_digit)(c >= 0)); - sp_384_norm_12(s); - /* s = s * k^-1 mod order */ - sp_384_mont_mul_order_12(s, s, kInv); - sp_384_norm_12(s); + err = sp_384_calc_s_12(s, r, k, x, e, tmp); + } - /* Check that signature is usable. */ - if (sp_384_iszero_12(s) == 0) { - break; - } + /* Check that signature is usable. */ + if ((err == MP_OKAY) && (sp_384_iszero_12(s) == 0)) { + break; } #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP i = 1; @@ -28621,7 +29360,6 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, XMEMSET(x, 0, sizeof(sp_digit) * 2U * 12U); XMEMSET(k, 0, sizeof(sp_digit) * 2U * 12U); XMEMSET(r, 0, sizeof(sp_digit) * 2U * 12U); - XMEMSET(r, 0, sizeof(sp_digit) * 2U * 12U); XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 12U); #endif sp_384_point_free_12(point, 1, heap); @@ -28959,6 +29697,100 @@ static int sp_384_mod_inv_12(sp_digit* r, const sp_digit* a, const sp_digit* m) } #endif /* WOLFSSL_SP_SMALL */ + +/* Add point p1 into point p2. Handles p1 == p2 and result at infinity. + * + * p1 First point to add and holds result. + * p2 Second point to add. + * tmp Temporary storage for intermediate numbers. + */ +static void sp_384_add_points_12(sp_point_384* p1, const sp_point_384* p2, + sp_digit* tmp) +{ + + sp_384_proj_point_add_12(p1, p1, p2, tmp); + if (sp_384_iszero_12(p1->z)) { + if (sp_384_iszero_12(p1->x) && sp_384_iszero_12(p1->y)) { + sp_384_proj_point_dbl_12(p1, p2, tmp); + } + else { + /* Y ordinate is not used from here - don't set. */ + p1->x[0] = 0; + p1->x[1] = 0; + p1->x[2] = 0; + p1->x[3] = 0; + p1->x[4] = 0; + p1->x[5] = 0; + p1->x[6] = 0; + p1->x[7] = 0; + p1->x[8] = 0; + p1->x[9] = 0; + p1->x[10] = 0; + p1->x[11] = 0; + XMEMCPY(p1->z, p384_norm_mod, sizeof(p384_norm_mod)); + } + } +} + +/* Calculate the verification point: [e/s]G + [r/s]Q + * + * p1 Calculated point. + * p2 Public point and temporary. + * s Second part of signature as a number. + * u1 Temporary number. + * u2 Temproray number. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_calc_vfy_point_12(sp_point_384* p1, sp_point_384* p2, + sp_digit* s, sp_digit* u1, sp_digit* u2, sp_digit* tmp, void* heap) +{ + int err; + +#ifndef WOLFSSL_SP_SMALL + { + sp_384_mod_inv_12(s, s, p384_order); + } +#endif /* !WOLFSSL_SP_SMALL */ + { + sp_384_mul_12(s, s, p384_norm_order); + } + err = sp_384_mod_12(s, s, p384_order); + if (err == MP_OKAY) { + sp_384_norm_12(s); +#ifdef WOLFSSL_SP_SMALL + { + sp_384_mont_inv_order_12(s, s, tmp); + sp_384_mont_mul_order_12(u1, u1, s); + sp_384_mont_mul_order_12(u2, u2, s); + } + +#else + { + sp_384_mont_mul_order_12(u1, u1, s); + sp_384_mont_mul_order_12(u2, u2, s); + } + +#endif /* WOLFSSL_SP_SMALL */ + err = sp_384_ecc_mulmod_base_12(p1, u1, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_384_iszero_12(p1->z)) { + p1->infinity = 1; + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_12(p2, p2, u2, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_384_iszero_12(p2->z)) { + p2->infinity = 1; + } + + if (err == MP_OKAY) { + sp_384_add_points_12(p1, p2, tmp); + } + + return err; +} + #ifdef HAVE_ECC_VERIFY /* Verify the signature values with the hash and public key. * e = Truncate(hash, 384) @@ -28977,8 +29809,7 @@ static int sp_384_mod_inv_12(sp_digit* r, const sp_digit* a, const sp_digit* m) * rm First part of result as an mp_int. * sm Sirst part of result as an mp_int. * heap Heap to use for allocation. - * returns RNG failures, MEMORY_E when memory allocation fails and - * MP_OKAY on success. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ #ifdef WOLFSSL_SP_NONBLOCK typedef struct sp_ecc_verify_384_ctx { @@ -28997,8 +29828,9 @@ typedef struct sp_ecc_verify_384_ctx { sp_point_384 p2; } sp_ecc_verify_384_ctx; -int sp_ecc_verify_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, + word32 hashLen, const mp_int* pX, const mp_int* pY, const mp_int* pZ, + const mp_int* r, const mp_int* sm, int* res, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_verify_384_ctx* ctx = (sp_ecc_verify_384_ctx*)sp_ctx->data; @@ -29152,8 +29984,9 @@ int sp_ecc_verify_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_384(const byte* hash, word32 hashLen, const mp_int* pX, + const mp_int* pY, const mp_int* pZ, const mp_int* r, const mp_int* sm, + int* res, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -29172,7 +30005,7 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, sp_point_384* p1; sp_point_384* p2 = NULL; sp_digit carry; - int32_t c; + int32_t c = 0; int err; err = sp_384_point_new_12(heap, p1d, p1); @@ -29213,70 +30046,9 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, sp_384_from_mp(p2->y, 12, pY); sp_384_from_mp(p2->z, 12, pZ); -#ifndef WOLFSSL_SP_SMALL - { - sp_384_mod_inv_12(s, s, p384_order); - } -#endif /* !WOLFSSL_SP_SMALL */ - { - sp_384_mul_12(s, s, p384_norm_order); - } - err = sp_384_mod_12(s, s, p384_order); + err = sp_384_calc_vfy_point_12(p1, p2, s, u1, u2, tmp, heap); } if (err == MP_OKAY) { - sp_384_norm_12(s); -#ifdef WOLFSSL_SP_SMALL - { - sp_384_mont_inv_order_12(s, s, tmp); - sp_384_mont_mul_order_12(u1, u1, s); - sp_384_mont_mul_order_12(u2, u2, s); - } - -#else - { - sp_384_mont_mul_order_12(u1, u1, s); - sp_384_mont_mul_order_12(u2, u2, s); - } - -#endif /* WOLFSSL_SP_SMALL */ - err = sp_384_ecc_mulmod_base_12(p1, u1, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_384_iszero_12(p1->z)) { - p1->infinity = 1; - } - if (err == MP_OKAY) { - err = sp_384_ecc_mulmod_12(p2, p2, u2, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_384_iszero_12(p2->z)) { - p2->infinity = 1; - } - - if (err == MP_OKAY) { - { - sp_384_proj_point_add_12(p1, p1, p2, tmp); - if (sp_384_iszero_12(p1->z)) { - if (sp_384_iszero_12(p1->x) && sp_384_iszero_12(p1->y)) { - sp_384_proj_point_dbl_12(p1, p2, tmp); - } - else { - /* Y ordinate is not used from here - don't set. */ - p1->x[0] = 0; - p1->x[1] = 0; - p1->x[2] = 0; - p1->x[3] = 0; - p1->x[4] = 0; - p1->x[5] = 0; - p1->x[6] = 0; - p1->x[7] = 0; - p1->x[8] = 0; - p1->x[9] = 0; - p1->x[10] = 0; - p1->x[11] = 0; - XMEMCPY(p1->z, p384_norm_mod, sizeof(p384_norm_mod)); - } - } - } - /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */ /* Reload r and convert to Montgomery form. */ sp_384_from_mp(u2, 12, r); @@ -29298,16 +30070,16 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, /* Compare with mod and if greater or equal then not valid. */ c = sp_384_cmp_12(u2, p384_mod); - if (c < 0) { - /* Convert to Montogomery form */ - err = sp_384_mod_mul_norm_12(u2, u2, p384_mod); - if (err == MP_OKAY) { - /* u1 = (r + 1*order).z'.z' mod prime */ - sp_384_mont_mul_12(u1, u2, p1->z, p384_mod, - p384_mp_mod); - *res = (int)(sp_384_cmp_12(p1->x, u1) == 0); - } - } + } + } + if ((*res == 0) && (c < 0)) { + /* Convert to Montogomery form */ + err = sp_384_mod_mul_norm_12(u2, u2, p384_mod); + if (err == MP_OKAY) { + /* u1 = (r + 1*order).z'.z' mod prime */ + sp_384_mont_mul_12(u1, u2, p1->z, p384_mod, + p384_mp_mod); + *res = (sp_384_cmp_12(p1->x, u1) == 0); } } } @@ -29331,7 +30103,8 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -static int sp_384_ecc_is_point_12(sp_point_384* point, void* heap) +static int sp_384_ecc_is_point_12(const sp_point_384* point, + void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -29394,7 +30167,7 @@ static int sp_384_ecc_is_point_12(sp_point_384* point, void* heap) * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -int sp_ecc_is_point_384(mp_int* pX, mp_int* pY) +int sp_ecc_is_point_384(const mp_int* pX, const mp_int* pY) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_384 pubd; @@ -29428,7 +30201,8 @@ int sp_ecc_is_point_384(mp_int* pX, mp_int* pY) * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and * MP_OKAY otherwise. */ -int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) +int sp_ecc_check_key_384(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit privd[12]; @@ -29482,12 +30256,11 @@ int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) } } - if (err == MP_OKAY) { - /* Check range of X and Y */ - if (sp_384_cmp_12(pub->x, p384_mod) >= 0 || - sp_384_cmp_12(pub->y, p384_mod) >= 0) { - err = ECC_OUT_OF_RANGE_E; - } + /* Check range of X and Y */ + if ((err == MP_OKAY) && + ((sp_384_cmp_12(pub->x, p384_mod) >= 0) || + (sp_384_cmp_12(pub->y, p384_mod) >= 0))) { + err = ECC_OUT_OF_RANGE_E; } if (err == MP_OKAY) { @@ -29499,12 +30272,10 @@ int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Point * order = infinity */ err = sp_384_ecc_mulmod_12(p, pub, p384_order, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is infinity */ - if ((sp_384_iszero_12(p->x) == 0) || - (sp_384_iszero_12(p->y) == 0)) { - err = ECC_INF_E; - } + /* Check result is infinity */ + if ((err == MP_OKAY) && ((sp_384_iszero_12(p->x) == 0) || + (sp_384_iszero_12(p->y) == 0))) { + err = ECC_INF_E; } if (privm) { @@ -29512,12 +30283,11 @@ int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) /* Base * private = point */ err = sp_384_ecc_mulmod_base_12(p, priv, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is public key */ - if (sp_384_cmp_12(p->x, pub->x) != 0 || - sp_384_cmp_12(p->y, pub->y) != 0) { - err = ECC_PRIV_KEY_E; - } + /* Check result is public key */ + if ((err == MP_OKAY) && + ((sp_384_cmp_12(p->x, pub->x) != 0) || + (sp_384_cmp_12(p->y, pub->y) != 0))) { + err = ECC_PRIV_KEY_E; } } @@ -29707,7 +30477,7 @@ int sp_ecc_map_384(mp_int* pX, mp_int* pY, mp_int* pZ) sp_384_from_mp(p->y, 12, pY); sp_384_from_mp(p->z, 12, pZ); - sp_384_map_12(p, p, tmp); + sp_384_map_12(p, p, tmp); } if (err == MP_OKAY) { @@ -29920,6 +30690,11981 @@ int sp_ecc_uncompress_384(mp_int* xm, int odd, mp_int* ym) } #endif #endif /* WOLFSSL_SP_384 */ +#ifdef WOLFSSL_SP_1024 + +/* Point structure to use. */ +typedef struct sp_point_1024 { + /* X ordinate of point. */ + sp_digit x[2 * 32]; + /* Y ordinate of point. */ + sp_digit y[2 * 32]; + /* Z ordinate of point. */ + sp_digit z[2 * 32]; + /* Indicates point is at infinity. */ + int infinity; +} sp_point_1024; + +#ifndef WOLFSSL_SP_SMALL +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static void sp_1024_mul_16(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit tmp_arr[16 * 2]; + sp_digit* tmp = tmp_arr; + __asm__ __volatile__ ( + "mov r3, #0\n\t" + "mov r4, #0\n\t" + "mov r9, r3\n\t" + "mov r12, %[r]\n\t" + "mov r10, %[a]\n\t" + "mov r11, %[b]\n\t" + "mov r6, #64\n\t" + "add r6, r6, r10\n\t" + "mov r14, r6\n\t" + "\n1:\n\t" + "mov %[r], #0\n\t" + "mov r5, #0\n\t" + "mov r6, #60\n\t" + "mov %[a], r9\n\t" + "subs %[a], %[a], r6\n\t" + "sbc r6, r6, r6\n\t" + "mvn r6, r6\n\t" + "and %[a], %[a], r6\n\t" + "mov %[b], r9\n\t" + "sub %[b], %[b], %[a]\n\t" + "add %[a], %[a], r10\n\t" + "add %[b], %[b], r11\n\t" + "\n2:\n\t" + /* Multiply Start */ + "ldr r6, [%[a]]\n\t" + "ldr r8, [%[b]]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, %[r]\n\t" + /* Multiply Done */ + "add %[a], %[a], #4\n\t" + "sub %[b], %[b], #4\n\t" + "cmp %[a], r14\n\t" +#ifdef __GNUC__ + "beq 3f\n\t" +#else + "beq.n 3f\n\t" +#endif /* __GNUC__ */ + "mov r6, r9\n\t" + "add r6, r6, r10\n\t" + "cmp %[a], r6\n\t" +#ifdef __GNUC__ + "ble 2b\n\t" +#else + "ble.n 2b\n\t" +#endif /* __GNUC__ */ + "\n3:\n\t" + "mov %[r], r12\n\t" + "mov r8, r9\n\t" + "str r3, [%[r], r8]\n\t" + "mov r3, r4\n\t" + "mov r4, r5\n\t" + "add r8, r8, #4\n\t" + "mov r9, r8\n\t" + "mov r6, #120\n\t" + "cmp r8, r6\n\t" +#ifdef __GNUC__ + "ble 1b\n\t" +#else + "ble.n 1b\n\t" +#endif /* __GNUC__ */ + "str r3, [%[r], r8]\n\t" + "mov %[a], r10\n\t" + "mov %[b], r11\n\t" + : + : [r] "r" (tmp), [a] "r" (a), [b] "r" (b) + : "memory", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12", "r14" + ); + + XMEMCPY(r, tmp_arr, sizeof(tmp_arr)); +} + +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_1024_sqr_16(sp_digit* r, const sp_digit* a) +{ + __asm__ __volatile__ ( + "mov r3, #0\n\t" + "mov r4, #0\n\t" + "mov r5, #0\n\t" + "mov r9, r3\n\t" + "mov r12, %[r]\n\t" + "mov r6, #128\n\t" + "neg r6, r6\n\t" + "add sp, sp, r6\n\t" + "mov r11, sp\n\t" + "mov r10, %[a]\n\t" + "\n1:\n\t" + "mov %[r], #0\n\t" + "mov r6, #60\n\t" + "mov %[a], r9\n\t" + "subs %[a], %[a], r6\n\t" + "sbc r6, r6, r6\n\t" + "mvn r6, r6\n\t" + "and %[a], %[a], r6\n\t" + "mov r2, r9\n\t" + "sub r2, r2, %[a]\n\t" + "add %[a], %[a], r10\n\t" + "add r2, r2, r10\n\t" + "\n2:\n\t" + "cmp r2, %[a]\n\t" +#ifdef __GNUC__ + "beq 4f\n\t" +#else + "beq.n 4f\n\t" +#endif /* __GNUC__ */ + /* Multiply * 2: Start */ + "ldr r6, [%[a]]\n\t" + "ldr r8, [r2]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, %[r]\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, %[r]\n\t" + /* Multiply * 2: Done */ +#ifdef __GNUC__ + "bal 5f\n\t" +#else + "bal.n 5f\n\t" +#endif /* __GNUC__ */ + "\n4:\n\t" + /* Square: Start */ + "ldr r6, [%[a]]\n\t" + "umull r6, r8, r6, r6\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, %[r]\n\t" + /* Square: Done */ + "\n5:\n\t" + "add %[a], %[a], #4\n\t" + "sub r2, r2, #4\n\t" + "mov r6, #64\n\t" + "add r6, r6, r10\n\t" + "cmp %[a], r6\n\t" +#ifdef __GNUC__ + "beq 3f\n\t" +#else + "beq.n 3f\n\t" +#endif /* __GNUC__ */ + "cmp %[a], r2\n\t" +#ifdef __GNUC__ + "bgt 3f\n\t" +#else + "bgt.n 3f\n\t" +#endif /* __GNUC__ */ + "mov r8, r9\n\t" + "add r8, r8, r10\n\t" + "cmp %[a], r8\n\t" +#ifdef __GNUC__ + "ble 2b\n\t" +#else + "ble.n 2b\n\t" +#endif /* __GNUC__ */ + "\n3:\n\t" + "mov %[r], r11\n\t" + "mov r8, r9\n\t" + "str r3, [%[r], r8]\n\t" + "mov r3, r4\n\t" + "mov r4, r5\n\t" + "mov r5, #0\n\t" + "add r8, r8, #4\n\t" + "mov r9, r8\n\t" + "mov r6, #120\n\t" + "cmp r8, r6\n\t" +#ifdef __GNUC__ + "ble 1b\n\t" +#else + "ble.n 1b\n\t" +#endif /* __GNUC__ */ + "mov %[a], r10\n\t" + "str r3, [%[r], r8]\n\t" + "mov %[r], r12\n\t" + "mov %[a], r11\n\t" + "mov r3, #124\n\t" + "\n4:\n\t" + "ldr r6, [%[a], r3]\n\t" + "str r6, [%[r], r3]\n\t" + "subs r3, r3, #4\n\t" +#ifdef __GNUC__ + "bge 4b\n\t" +#else + "bge.n 4b\n\t" +#endif /* __GNUC__ */ + "mov r6, #128\n\t" + "add sp, sp, r6\n\t" + : + : [r] "r" (r), [a] "r" (a) + : "memory", "r2", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12" + ); +} + +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_1024_add_16(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "mov %[c], #0\n\t" + "adc %[c], %[c], %[c]\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6", "r8" + ); + + return c; +} + +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_1024_sub_in_place_32(sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldm %[a], {r3, r4}\n\t" + "ldm %[b]!, {r5, r6}\n\t" + "subs r3, r3, r5\n\t" + "sbcs r4, r4, r6\n\t" + "stm %[a]!, {r3, r4}\n\t" + "ldm %[a], {r3, r4}\n\t" + "ldm %[b]!, {r5, r6}\n\t" + "sbcs r3, r3, r5\n\t" + "sbcs r4, r4, r6\n\t" + "stm %[a]!, {r3, r4}\n\t" + "ldm %[a], {r3, r4}\n\t" + "ldm %[b]!, {r5, r6}\n\t" + "sbcs r3, r3, r5\n\t" + "sbcs r4, r4, r6\n\t" + "stm %[a]!, {r3, r4}\n\t" + "ldm %[a], {r3, r4}\n\t" + "ldm %[b]!, {r5, r6}\n\t" + "sbcs r3, r3, r5\n\t" + "sbcs r4, r4, r6\n\t" + "stm %[a]!, {r3, r4}\n\t" + "ldm %[a], {r3, r4}\n\t" + "ldm %[b]!, {r5, r6}\n\t" + "sbcs r3, r3, r5\n\t" + "sbcs r4, r4, r6\n\t" + "stm %[a]!, {r3, r4}\n\t" + "ldm %[a], {r3, r4}\n\t" + "ldm %[b]!, {r5, r6}\n\t" + "sbcs r3, r3, r5\n\t" + "sbcs r4, r4, r6\n\t" + "stm %[a]!, {r3, r4}\n\t" + "ldm %[a], {r3, r4}\n\t" + "ldm %[b]!, {r5, r6}\n\t" + "sbcs r3, r3, r5\n\t" + "sbcs r4, r4, r6\n\t" + "stm %[a]!, {r3, r4}\n\t" + "ldm %[a], {r3, r4}\n\t" + "ldm %[b]!, {r5, r6}\n\t" + "sbcs r3, r3, r5\n\t" + "sbcs r4, r4, r6\n\t" + "stm %[a]!, {r3, r4}\n\t" + "ldm %[a], {r3, r4}\n\t" + "ldm %[b]!, {r5, r6}\n\t" + "sbcs r3, r3, r5\n\t" + "sbcs r4, r4, r6\n\t" + "stm %[a]!, {r3, r4}\n\t" + "ldm %[a], {r3, r4}\n\t" + "ldm %[b]!, {r5, r6}\n\t" + "sbcs r3, r3, r5\n\t" + "sbcs r4, r4, r6\n\t" + "stm %[a]!, {r3, r4}\n\t" + "ldm %[a], {r3, r4}\n\t" + "ldm %[b]!, {r5, r6}\n\t" + "sbcs r3, r3, r5\n\t" + "sbcs r4, r4, r6\n\t" + "stm %[a]!, {r3, r4}\n\t" + "ldm %[a], {r3, r4}\n\t" + "ldm %[b]!, {r5, r6}\n\t" + "sbcs r3, r3, r5\n\t" + "sbcs r4, r4, r6\n\t" + "stm %[a]!, {r3, r4}\n\t" + "ldm %[a], {r3, r4}\n\t" + "ldm %[b]!, {r5, r6}\n\t" + "sbcs r3, r3, r5\n\t" + "sbcs r4, r4, r6\n\t" + "stm %[a]!, {r3, r4}\n\t" + "ldm %[a], {r3, r4}\n\t" + "ldm %[b]!, {r5, r6}\n\t" + "sbcs r3, r3, r5\n\t" + "sbcs r4, r4, r6\n\t" + "stm %[a]!, {r3, r4}\n\t" + "ldm %[a], {r3, r4}\n\t" + "ldm %[b]!, {r5, r6}\n\t" + "sbcs r3, r3, r5\n\t" + "sbcs r4, r4, r6\n\t" + "stm %[a]!, {r3, r4}\n\t" + "ldm %[a], {r3, r4}\n\t" + "ldm %[b]!, {r5, r6}\n\t" + "sbcs r3, r3, r5\n\t" + "sbcs r4, r4, r6\n\t" + "stm %[a]!, {r3, r4}\n\t" + "sbc %[c], %[c], %[c]\n\t" + : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r3", "r4", "r5", "r6" + ); + + return c; +} + +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_1024_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "ldm %[a]!, {r4, r5}\n\t" + "ldm %[b]!, {r6, r8}\n\t" + "adcs r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "stm %[r]!, {r4, r5}\n\t" + "mov %[c], #0\n\t" + "adc %[c], %[c], %[c]\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6", "r8" + ); + + return c; +} + +/* AND m into each word of a and store in r. + * + * r A single precision integer. + * a A single precision integer. + * m Mask to AND against each digit. + */ +static void sp_1024_mask_16(sp_digit* r, const sp_digit* a, sp_digit m) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i=0; i<16; i++) { + r[i] = a[i] & m; + } +#else + int i; + + for (i = 0; i < 16; i += 8) { + r[i+0] = a[i+0] & m; + r[i+1] = a[i+1] & m; + r[i+2] = a[i+2] & m; + r[i+3] = a[i+3] & m; + r[i+4] = a[i+4] & m; + r[i+5] = a[i+5] & m; + r[i+6] = a[i+6] & m; + r[i+7] = a[i+7] & m; + } +#endif +} + +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static void sp_1024_mul_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit* z0 = r; + sp_digit z1[32]; + sp_digit a1[16]; + sp_digit b1[16]; + sp_digit z2[32]; + sp_digit u; + sp_digit ca; + sp_digit cb; + + ca = sp_1024_add_16(a1, a, &a[16]); + cb = sp_1024_add_16(b1, b, &b[16]); + u = ca & cb; + sp_1024_mul_16(z1, a1, b1); + sp_1024_mul_16(z2, &a[16], &b[16]); + sp_1024_mul_16(z0, a, b); + sp_1024_mask_16(r + 32, a1, 0 - cb); + sp_1024_mask_16(b1, b1, 0 - ca); + u += sp_1024_add_16(r + 32, r + 32, b1); + u += sp_1024_sub_in_place_32(z1, z2); + u += sp_1024_sub_in_place_32(z1, z0); + u += sp_1024_add_32(r + 16, r + 16, z1); + r[48] = u; + XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1)); + (void)sp_1024_add_32(r + 32, r + 32, z2); +} + +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_1024_sqr_32(sp_digit* r, const sp_digit* a) +{ + sp_digit* z0 = r; + sp_digit z2[32]; + sp_digit z1[32]; + sp_digit a1[16]; + sp_digit u; + + u = sp_1024_add_16(a1, a, &a[16]); + sp_1024_sqr_16(z1, a1); + sp_1024_sqr_16(z2, &a[16]); + sp_1024_sqr_16(z0, a); + sp_1024_mask_16(r + 32, a1, 0 - u); + u += sp_1024_add_16(r + 32, r + 32, r + 32); + u += sp_1024_sub_in_place_32(z1, z2); + u += sp_1024_sub_in_place_32(z1, z0); + u += sp_1024_add_32(r + 16, r + 16, z1); + r[48] = u; + XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1)); + (void)sp_1024_add_32(r + 32, r + 32, z2); +} + +#else +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static void sp_1024_mul_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit tmp_arr[32 * 2]; + sp_digit* tmp = tmp_arr; + __asm__ __volatile__ ( + "mov r3, #0\n\t" + "mov r4, #0\n\t" + "mov r9, r3\n\t" + "mov r12, %[r]\n\t" + "mov r10, %[a]\n\t" + "mov r11, %[b]\n\t" + "mov r6, #128\n\t" + "add r6, r6, r10\n\t" + "mov r14, r6\n\t" + "\n1:\n\t" + "mov %[r], #0\n\t" + "mov r5, #0\n\t" + "mov r6, #124\n\t" + "mov %[a], r9\n\t" + "subs %[a], %[a], r6\n\t" + "sbc r6, r6, r6\n\t" + "mvn r6, r6\n\t" + "and %[a], %[a], r6\n\t" + "mov %[b], r9\n\t" + "sub %[b], %[b], %[a]\n\t" + "add %[a], %[a], r10\n\t" + "add %[b], %[b], r11\n\t" + "\n2:\n\t" + /* Multiply Start */ + "ldr r6, [%[a]]\n\t" + "ldr r8, [%[b]]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, %[r]\n\t" + /* Multiply Done */ + "add %[a], %[a], #4\n\t" + "sub %[b], %[b], #4\n\t" + "cmp %[a], r14\n\t" +#ifdef __GNUC__ + "beq 3f\n\t" +#else + "beq.n 3f\n\t" +#endif /* __GNUC__ */ + "mov r6, r9\n\t" + "add r6, r6, r10\n\t" + "cmp %[a], r6\n\t" +#ifdef __GNUC__ + "ble 2b\n\t" +#else + "ble.n 2b\n\t" +#endif /* __GNUC__ */ + "\n3:\n\t" + "mov %[r], r12\n\t" + "mov r8, r9\n\t" + "str r3, [%[r], r8]\n\t" + "mov r3, r4\n\t" + "mov r4, r5\n\t" + "add r8, r8, #4\n\t" + "mov r9, r8\n\t" + "mov r6, #248\n\t" + "cmp r8, r6\n\t" +#ifdef __GNUC__ + "ble 1b\n\t" +#else + "ble.n 1b\n\t" +#endif /* __GNUC__ */ + "str r3, [%[r], r8]\n\t" + "mov %[a], r10\n\t" + "mov %[b], r11\n\t" + : + : [r] "r" (tmp), [a] "r" (a), [b] "r" (b) + : "memory", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12", "r14" + ); + + XMEMCPY(r, tmp_arr, sizeof(tmp_arr)); +} + +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_1024_sqr_32(sp_digit* r, const sp_digit* a) +{ + __asm__ __volatile__ ( + "mov r3, #0\n\t" + "mov r4, #0\n\t" + "mov r5, #0\n\t" + "mov r9, r3\n\t" + "mov r12, %[r]\n\t" + "mov r6, #1\n\t" + "lsl r6, r6, #8\n\t" + "neg r6, r6\n\t" + "add sp, sp, r6\n\t" + "mov r11, sp\n\t" + "mov r10, %[a]\n\t" + "\n1:\n\t" + "mov %[r], #0\n\t" + "mov r6, #124\n\t" + "mov %[a], r9\n\t" + "subs %[a], %[a], r6\n\t" + "sbc r6, r6, r6\n\t" + "mvn r6, r6\n\t" + "and %[a], %[a], r6\n\t" + "mov r2, r9\n\t" + "sub r2, r2, %[a]\n\t" + "add %[a], %[a], r10\n\t" + "add r2, r2, r10\n\t" + "\n2:\n\t" + "cmp r2, %[a]\n\t" +#ifdef __GNUC__ + "beq 4f\n\t" +#else + "beq.n 4f\n\t" +#endif /* __GNUC__ */ + /* Multiply * 2: Start */ + "ldr r6, [%[a]]\n\t" + "ldr r8, [r2]\n\t" + "umull r6, r8, r6, r8\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, %[r]\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, %[r]\n\t" + /* Multiply * 2: Done */ +#ifdef __GNUC__ + "bal 5f\n\t" +#else + "bal.n 5f\n\t" +#endif /* __GNUC__ */ + "\n4:\n\t" + /* Square: Start */ + "ldr r6, [%[a]]\n\t" + "umull r6, r8, r6, r6\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, %[r]\n\t" + /* Square: Done */ + "\n5:\n\t" + "add %[a], %[a], #4\n\t" + "sub r2, r2, #4\n\t" + "mov r6, #128\n\t" + "add r6, r6, r10\n\t" + "cmp %[a], r6\n\t" +#ifdef __GNUC__ + "beq 3f\n\t" +#else + "beq.n 3f\n\t" +#endif /* __GNUC__ */ + "cmp %[a], r2\n\t" +#ifdef __GNUC__ + "bgt 3f\n\t" +#else + "bgt.n 3f\n\t" +#endif /* __GNUC__ */ + "mov r8, r9\n\t" + "add r8, r8, r10\n\t" + "cmp %[a], r8\n\t" +#ifdef __GNUC__ + "ble 2b\n\t" +#else + "ble.n 2b\n\t" +#endif /* __GNUC__ */ + "\n3:\n\t" + "mov %[r], r11\n\t" + "mov r8, r9\n\t" + "str r3, [%[r], r8]\n\t" + "mov r3, r4\n\t" + "mov r4, r5\n\t" + "mov r5, #0\n\t" + "add r8, r8, #4\n\t" + "mov r9, r8\n\t" + "mov r6, #248\n\t" + "cmp r8, r6\n\t" +#ifdef __GNUC__ + "ble 1b\n\t" +#else + "ble.n 1b\n\t" +#endif /* __GNUC__ */ + "mov %[a], r10\n\t" + "str r3, [%[r], r8]\n\t" + "mov %[r], r12\n\t" + "mov %[a], r11\n\t" + "mov r3, #252\n\t" + "\n4:\n\t" + "ldr r6, [%[a], r3]\n\t" + "str r6, [%[r], r3]\n\t" + "subs r3, r3, #4\n\t" +#ifdef __GNUC__ + "bge 4b\n\t" +#else + "bge.n 4b\n\t" +#endif /* __GNUC__ */ + "mov r6, #1\n\t" + "lsl r6, r6, #8\n\t" + "add sp, sp, r6\n\t" + : + : [r] "r" (r), [a] "r" (a) + : "memory", "r2", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12" + ); +} + +#endif /* !WOLFSSL_SP_SMALL */ +/* The modulus (prime) of the curve P1024. */ +static const sp_digit p1024_mod[32] = { + 0xfea85feb,0x666d807a,0xac7ace87,0x80c5df10,0x89857db0,0xfce3e823, + 0x56971f1f,0x9f94d6af,0x1c3c09aa,0xa7cf3c52,0x31852a82,0xb6aff4a8, + 0x65681ce1,0x512ac5cd,0x326b4cd4,0xe26c6487,0xa666a6d0,0x356d27f4, + 0xf7c88a19,0xe791b39f,0x31a59cb0,0x228730d5,0xe2fc0f1b,0xf40aab27, + 0xb3e01a2e,0xbe9ae358,0x9cb48261,0x416c0ce1,0xdad0657a,0x65c61198, + 0x0a563fda,0x997abb1f +}; +/* The Montogmery normalizer for modulus of the curve P1024. */ +static const sp_digit p1024_norm_mod[32] = { + 0x0157a015,0x99927f85,0x53853178,0x7f3a20ef,0x767a824f,0x031c17dc, + 0xa968e0e0,0x606b2950,0xe3c3f655,0x5830c3ad,0xce7ad57d,0x49500b57, + 0x9a97e31e,0xaed53a32,0xcd94b32b,0x1d939b78,0x5999592f,0xca92d80b, + 0x083775e6,0x186e4c60,0xce5a634f,0xdd78cf2a,0x1d03f0e4,0x0bf554d8, + 0x4c1fe5d1,0x41651ca7,0x634b7d9e,0xbe93f31e,0x252f9a85,0x9a39ee67, + 0xf5a9c025,0x668544e0 +}; +/* The Montogmery multiplier for modulus of the curve P1024. */ +static sp_digit p1024_mp_mod = 0x7c8f2f3d; +#if defined(WOLFSSL_SP_SMALL) || defined(HAVE_ECC_CHECK_KEY) +/* The order of the curve P1024. */ +static const sp_digit p1024_order[32] = { + 0xbfaa17fb,0xd99b601e,0x2b1eb3a1,0x203177c4,0xe2615f6c,0xff38fa08, + 0xd5a5c7c7,0xa7e535ab,0x870f026a,0xa9f3cf14,0x0c614aa0,0x6dabfd2a, + 0x595a0738,0x144ab173,0xcc9ad335,0x389b1921,0x2999a9b4,0x4d5b49fd, + 0xfdf22286,0x39e46ce7,0x4c69672c,0xc8a1cc35,0xf8bf03c6,0xbd02aac9, + 0x2cf8068b,0x6fa6b8d6,0x672d2098,0x905b0338,0x36b4195e,0x99718466, + 0xc2958ff6,0x265eaec7 +}; +#endif +/* The base point of curve P1024. */ +static const sp_point_1024 p1024_base = { + /* X ordinate */ + { + 0xeae63895,0x880dc8ab,0x967e0979,0x80ec46c4,0xb63f73ec,0xee9163a5, + 0x80728d87,0xd5cfb4cc,0xba66910d,0xa7c1514d,0x7a60de74,0xa702c339, + 0x8b72f2e1,0x337c8654,0x5dd5bccb,0x9760af76,0x406ce890,0x718bd9e7, + 0xdb9dfa55,0x43d5f22c,0x30b09e10,0xab10db90,0xf6ce2308,0xb5edb6c0, + 0xb6ff7cbf,0x98b2f204,0x0aec69c6,0x2b1a2fd6,0x3ed9b52a,0x0a799005, + 0x332c29ad,0x53fc09ee, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* Y ordinate */ + { + 0x1bef16d7,0x75573fd7,0x6a67dcde,0xadb9b570,0xd5bb4636,0x80bdad5a, + 0xe9cb99a9,0x13515ad7,0xc5a4d5f2,0x492d979f,0x164aa989,0xac6f1e80, + 0xb7652fe0,0xcad696b5,0xad547c6c,0x70dae117,0xa9e032b9,0x416cff0c, + 0x9a140b2e,0x6b598ccf,0xf0de55f6,0xe7f7f5e5,0x654ec2b9,0xf5ea69f4, + 0x1e141178,0x3d778d82,0x02990696,0xd3e82016,0x3634a135,0xf9f1f053, + 0x3f6009f1,0x0a824906, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* Z ordinate */ + { + 0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* infinity */ + 0 +}; + +#ifdef WOLFSSL_SP_SMALL +/* Sub b from a into a. (a -= b) + * + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_1024_sub_in_place_32(sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + __asm__ __volatile__ ( + "mov r8, %[a]\n\t" + "add r8, r8, #128\n\t" + "\n1:\n\t" + "mov r5, #0\n\t" + "subs r5, r5, %[c]\n\t" + "ldr r3, [%[a]]\n\t" + "ldr r4, [%[a], #4]\n\t" + "ldr r5, [%[b]]\n\t" + "ldr r6, [%[b], #4]\n\t" + "sbcs r3, r3, r5\n\t" + "sbcs r4, r4, r6\n\t" + "str r3, [%[a]]\n\t" + "str r4, [%[a], #4]\n\t" + "sbc %[c], %[c], %[c]\n\t" + "add %[a], %[a], #8\n\t" + "add %[b], %[b], #8\n\t" + "cmp %[a], r8\n\t" +#ifdef __GNUC__ + "bne 1b\n\t" +#else + "bne.n 1b\n\t" +#endif /* __GNUC__ */ + : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r3", "r4", "r5", "r6", "r8" + ); + + return c; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Conditionally subtract b from a using the mask m. + * m is -1 to subtract and 0 when not copying. + * + * r A single precision number representing condition subtract result. + * a A single precision number to subtract from. + * b A single precision number to subtract. + * m Mask value to apply. + */ +SP_NOINLINE static sp_digit sp_1024_cond_sub_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r5, #128\n\t" + "mov r9, r5\n\t" + "mov r8, #0\n\t" + "\n1:\n\t" + "ldr r6, [%[b], r8]\n\t" + "and r6, r6, %[m]\n\t" + "mov r5, #0\n\t" + "subs r5, r5, %[c]\n\t" + "ldr r5, [%[a], r8]\n\t" + "sbcs r5, r5, r6\n\t" + "sbcs %[c], %[c], %[c]\n\t" + "str r5, [%[r], r8]\n\t" + "add r8, r8, #4\n\t" + "cmp r8, r9\n\t" +#ifdef __GNUC__ + "blt 1b\n\t" +#else + "blt.n 1b\n\t" +#endif /* __GNUC__ */ + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "r5", "r6", "r8", "r9" + ); + + return c; +} + +#ifdef WOLFSSL_SP_SMALL +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_1024_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r6, %[a]\n\t" + "mov r8, #0\n\t" + "add r6, r6, #128\n\t" + "sub r8, r8, #1\n\t" + "\n1:\n\t" + "adds %[c], %[c], r8\n\t" + "ldr r4, [%[a]]\n\t" + "ldr r5, [%[b]]\n\t" + "adcs r4, r4, r5\n\t" + "str r4, [%[r]]\n\t" + "mov %[c], #0\n\t" + "adc %[c], %[c], %[c]\n\t" + "add %[a], %[a], #4\n\t" + "add %[b], %[b], #4\n\t" + "add %[r], %[r], #4\n\t" + "cmp %[a], r6\n\t" +#ifdef __GNUC__ + "bne 1b\n\t" +#else + "bne.n 1b\n\t" +#endif /* __GNUC__ */ + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6", "r8" + ); + + return c; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Mul a by digit b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision digit. + */ +SP_NOINLINE static void sp_1024_mul_d_32(sp_digit* r, const sp_digit* a, + sp_digit b) +{ + __asm__ __volatile__ ( + "add r9, %[a], #128\n\t" + /* A[0] * B */ + "ldr r6, [%[a]], #4\n\t" + "umull r5, r3, r6, %[b]\n\t" + "mov r4, #0\n\t" + "str r5, [%[r]], #4\n\t" + /* A[0] * B - Done */ + "\n1:\n\t" + "mov r5, #0\n\t" + /* A[] * B */ + "ldr r6, [%[a]], #4\n\t" + "umull r6, r8, r6, %[b]\n\t" + "adds r3, r3, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc r5, r5, #0\n\t" + /* A[] * B - Done */ + "str r3, [%[r]], #4\n\t" + "mov r3, r4\n\t" + "mov r4, r5\n\t" + "cmp %[a], r9\n\t" +#ifdef __GNUC__ + "blt 1b\n\t" +#else + "blt.n 1b\n\t" +#endif /* __GNUC__ */ + "str r3, [%[r]]\n\t" + : [r] "+r" (r), [a] "+r" (a) + : [b] "r" (b) + : "memory", "r3", "r4", "r5", "r6", "r8", "r9" + ); +} + +/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) + * + * d1 The high order half of the number to divide. + * d0 The low order half of the number to divide. + * div The dividend. + * returns the result of the division. + * + * Note that this is an approximate div. It may give an answer 1 larger. + */ +SP_NOINLINE static sp_digit div_1024_word_32(sp_digit d1, sp_digit d0, + sp_digit div) +{ + sp_digit r = 0; + + __asm__ __volatile__ ( + "lsr r6, %[div], #16\n\t" + "add r6, r6, #1\n\t" + "udiv r4, %[d1], r6\n\t" + "lsl r8, r4, #16\n\t" + "umull r4, r5, %[div], r8\n\t" + "subs %[d0], %[d0], r4\n\t" + "sbc %[d1], %[d1], r5\n\t" + "udiv r5, %[d1], r6\n\t" + "lsl r4, r5, #16\n\t" + "add r8, r8, r4\n\t" + "umull r4, r5, %[div], r4\n\t" + "subs %[d0], %[d0], r4\n\t" + "sbc %[d1], %[d1], r5\n\t" + "lsl r4, %[d1], #16\n\t" + "orr r4, r4, %[d0], lsr #16\n\t" + "udiv r4, r4, r6\n\t" + "add r8, r8, r4\n\t" + "umull r4, r5, %[div], r4\n\t" + "subs %[d0], %[d0], r4\n\t" + "sbc %[d1], %[d1], r5\n\t" + "lsl r4, %[d1], #16\n\t" + "orr r4, r4, %[d0], lsr #16\n\t" + "udiv r4, r4, r6\n\t" + "add r8, r8, r4\n\t" + "umull r4, r5, %[div], r4\n\t" + "subs %[d0], %[d0], r4\n\t" + "sbc %[d1], %[d1], r5\n\t" + "udiv r4, %[d0], %[div]\n\t" + "add r8, r8, r4\n\t" + "mov %[r], r8\n\t" + : [r] "+r" (r) + : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div) + : "r4", "r5", "r6", "r8" + ); + return r; +} + +/* AND m into each word of a and store in r. + * + * r A single precision integer. + * a A single precision integer. + * m Mask to AND against each digit. + */ +static void sp_1024_mask_32(sp_digit* r, const sp_digit* a, sp_digit m) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i=0; i<32; i++) { + r[i] = a[i] & m; + } +#else + int i; + + for (i = 0; i < 32; i += 8) { + r[i+0] = a[i+0] & m; + r[i+1] = a[i+1] & m; + r[i+2] = a[i+2] & m; + r[i+3] = a[i+3] & m; + r[i+4] = a[i+4] & m; + r[i+5] = a[i+5] & m; + r[i+6] = a[i+6] & m; + r[i+7] = a[i+7] & m; + } +#endif +} + +/* Compare a with b in constant time. + * + * a A single precision integer. + * b A single precision integer. + * return -ve, 0 or +ve if a is less than, equal to or greater than b + * respectively. + */ +SP_NOINLINE static int32_t sp_1024_cmp_32(const sp_digit* a, const sp_digit* b) +{ + sp_digit r = 0; + + + __asm__ __volatile__ ( + "mov r3, #0\n\t" + "mvn r3, r3\n\t" + "mov r6, #124\n\t" + "\n1:\n\t" + "ldr r8, [%[a], r6]\n\t" + "ldr r5, [%[b], r6]\n\t" + "and r8, r8, r3\n\t" + "and r5, r5, r3\n\t" + "mov r4, r8\n\t" + "subs r8, r8, r5\n\t" + "sbc r8, r8, r8\n\t" + "add %[r], %[r], r8\n\t" + "mvn r8, r8\n\t" + "and r3, r3, r8\n\t" + "subs r5, r5, r4\n\t" + "sbc r8, r8, r8\n\t" + "sub %[r], %[r], r8\n\t" + "mvn r8, r8\n\t" + "and r3, r3, r8\n\t" + "sub r6, r6, #4\n\t" + "cmp r6, #0\n\t" +#ifdef __GNUC__ + "bge 1b\n\t" +#else + "bge.n 1b\n\t" +#endif /* __GNUC__ */ + : [r] "+r" (r) + : [a] "r" (a), [b] "r" (b) + : "r3", "r4", "r5", "r6", "r8" + ); + + return r; +} + +/* Divide d in a and put remainder into r (m*d + r = a) + * m is not calculated as it is not needed at this time. + * + * a Number to be divided. + * d Number to divide with. + * m Multiplier result. + * r Remainder from the division. + * returns MP_OKAY indicating success. + */ +static WC_INLINE int sp_1024_div_32(const sp_digit* a, const sp_digit* d, sp_digit* m, + sp_digit* r) +{ + sp_digit t1[64], t2[33]; + sp_digit div, r1; + int i; + + (void)m; + + div = d[31]; + XMEMCPY(t1, a, sizeof(*t1) * 2 * 32); + for (i=31; i>=0; i--) { + sp_digit hi = t1[32 + i] - (t1[32 + i] == div); + r1 = div_1024_word_32(hi, t1[32 + i - 1], div); + + sp_1024_mul_d_32(t2, d, r1); + t1[32 + i] += sp_1024_sub_in_place_32(&t1[i], t2); + t1[32 + i] -= t2[32]; + sp_1024_mask_32(t2, d, t1[32 + i]); + t1[32 + i] += sp_1024_add_32(&t1[i], &t1[i], t2); + sp_1024_mask_32(t2, d, t1[32 + i]); + t1[32 + i] += sp_1024_add_32(&t1[i], &t1[i], t2); + } + + r1 = sp_1024_cmp_32(t1, d) >= 0; + sp_1024_cond_sub_32(r, t1, d, (sp_digit)0 - r1); + + return MP_OKAY; +} + +/* Reduce a modulo m into r. (r = a mod m) + * + * r A single precision number that is the reduced result. + * a A single precision number that is to be reduced. + * m A single precision number that is the modulus to reduce with. + * returns MP_OKAY indicating success. + */ +static WC_INLINE int sp_1024_mod_32(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + return sp_1024_div_32(a, m, NULL, r); +} + +/* Multiply a number by Montogmery normalizer mod modulus (prime). + * + * r The resulting Montgomery form number. + * a The number to convert. + * m The modulus (prime). + * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. + */ +static int sp_1024_mod_mul_norm_32(sp_digit* r, const sp_digit* a, + const sp_digit* m) +{ + sp_1024_mul_32(r, a, p1024_norm_mod); + return sp_1024_mod_32(r, r, m); +} + +/* Create a new point. + * + * heap [in] Buffer to allocate dynamic memory from. + * sp [in] Data for point - only if not allocating. + * p [out] New point. + * returns MEMORY_E when dynamic memory allocation fails and 0 otherwise. + */ +static int sp_1024_point_new_ex_32(void* heap, sp_point_1024* sp, + sp_point_1024** p) +{ + int ret = MP_OKAY; + (void)heap; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + (void)sp; + *p = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024), heap, DYNAMIC_TYPE_ECC); +#else + *p = sp; +#endif + if (*p == NULL) { + ret = MEMORY_E; + } + return ret; +} + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* Allocate memory for point and return error. */ +#define sp_1024_point_new_32(heap, sp, p) sp_1024_point_new_ex_32((heap), NULL, &(p)) +#else +/* Set pointer to data and return no error. */ +#define sp_1024_point_new_32(heap, sp, p) sp_1024_point_new_ex_32((heap), &(sp), &(p)) +#endif + + +/* Free the point. + * + * p [in,out] Point to free. + * clear [in] Indicates whether to zeroize point. + * heap [in] Buffer from which dynamic memory was allocate from. + */ +static void sp_1024_point_free_32(sp_point_1024* p, int clear, void* heap) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* If valid pointer then clear point data if requested and free data. */ + if (p != NULL) { + if (clear != 0) { + XMEMSET(p, 0, sizeof(*p)); + } + XFREE(p, heap, DYNAMIC_TYPE_ECC); + } +#else +/* Clear point data if requested. */ + if ((p != NULL) && (clear != 0)) { + XMEMSET(p, 0, sizeof(*p)); + } +#endif + (void)heap; +} + +/* Convert an mp_int to an array of sp_digit. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a A multi-precision integer. + */ +static void sp_1024_from_mp(sp_digit* r, int size, const mp_int* a) +{ +#if DIGIT_BIT == 32 + int j; + + XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); + + for (j = a->used; j < size; j++) { + r[j] = 0; + } +#elif DIGIT_BIT > 32 + int i; + int j = 0; + word32 s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i] << s); + r[j] &= 0xffffffff; + s = 32U - s; + if (j + 1 >= size) { + break; + } + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + while ((s + 32U) <= (word32)DIGIT_BIT) { + s += 32U; + r[j] &= 0xffffffff; + if (j + 1 >= size) { + break; + } + if (s < (word32)DIGIT_BIT) { + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + } + else { + r[++j] = 0L; + } + } + s = (word32)DIGIT_BIT - s; + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#else + int i; + int j = 0; + int s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i]) << s; + if (s + DIGIT_BIT >= 32) { + r[j] &= 0xffffffff; + if (j + 1 >= size) { + break; + } + s = 32 - s; + if (s == DIGIT_BIT) { + r[++j] = 0; + s = 0; + } + else { + r[++j] = a->dp[i] >> s; + s = DIGIT_BIT - s; + } + } + else { + s += DIGIT_BIT; + } + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#endif +} + +/* Convert a point of type ecc_point to type sp_point_1024. + * + * p Point of type sp_point_1024 (result). + * pm Point of type ecc_point. + */ +static void sp_1024_point_from_ecc_point_32(sp_point_1024* p, + const ecc_point* pm) +{ + XMEMSET(p->x, 0, sizeof(p->x)); + XMEMSET(p->y, 0, sizeof(p->y)); + XMEMSET(p->z, 0, sizeof(p->z)); + sp_1024_from_mp(p->x, 32, pm->x); + sp_1024_from_mp(p->y, 32, pm->y); + sp_1024_from_mp(p->z, 32, pm->z); + p->infinity = 0; +} + +/* Convert an array of sp_digit to an mp_int. + * + * a A single precision integer. + * r A multi-precision integer. + */ +static int sp_1024_to_mp(const sp_digit* a, mp_int* r) +{ + int err; + + err = mp_grow(r, (1024 + DIGIT_BIT - 1) / DIGIT_BIT); + if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ +#if DIGIT_BIT == 32 + XMEMCPY(r->dp, a, sizeof(sp_digit) * 32); + r->used = 32; + mp_clamp(r); +#elif DIGIT_BIT < 32 + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 32; i++) { + r->dp[j] |= (mp_digit)(a[i] << s); + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + s = DIGIT_BIT - s; + r->dp[++j] = (mp_digit)(a[i] >> s); + while (s + DIGIT_BIT <= 32) { + s += DIGIT_BIT; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; + if (s == SP_WORD_SIZE) { + r->dp[j] = 0; + } + else { + r->dp[j] = (mp_digit)(a[i] >> s); + } + } + s = 32 - s; + } + r->used = (1024 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#else + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 32; i++) { + r->dp[j] |= ((mp_digit)a[i]) << s; + if (s + 32 >= DIGIT_BIT) { + #if DIGIT_BIT != 32 && DIGIT_BIT != 64 + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + #endif + s = DIGIT_BIT - s; + r->dp[++j] = a[i] >> s; + s = 32 - s; + } + else { + s += 32; + } + } + r->used = (1024 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#endif + } + + return err; +} + +/* Convert a point of type sp_point_1024 to type ecc_point. + * + * p Point of type sp_point_1024. + * pm Point of type ecc_point (result). + * returns MEMORY_E when allocation of memory in ecc_point fails otherwise + * MP_OKAY. + */ +static int sp_1024_point_to_ecc_point_32(const sp_point_1024* p, ecc_point* pm) +{ + int err; + + err = sp_1024_to_mp(p->x, pm->x); + if (err == MP_OKAY) { + err = sp_1024_to_mp(p->y, pm->y); + } + if (err == MP_OKAY) { + err = sp_1024_to_mp(p->z, pm->z); + } + + return err; +} + +/* Reduce the number back to 1024 bits using Montgomery reduction. + * + * a A single precision number to reduce in place. + * m The single precision number representing the modulus. + * mp The digit representing the negative inverse of m mod 2^n. + */ +SP_NOINLINE static void sp_1024_mont_reduce_32(sp_digit* a, const sp_digit* m, + sp_digit mp) +{ + sp_digit ca = 0; + + __asm__ __volatile__ ( + "mov r9, %[mp]\n\t" + "mov r12, %[m]\n\t" + "mov r10, %[a]\n\t" + "mov r4, #0\n\t" + "add r11, r10, #128\n\t" + "\n1:\n\t" + /* mu = a[i] * mp */ + "mov %[mp], r9\n\t" + "ldr %[a], [r10]\n\t" + "mul %[mp], %[mp], %[a]\n\t" + "mov %[m], r12\n\t" + "add r14, r10, #120\n\t" + "\n2:\n\t" + /* a[i+j] += m[j] * mu */ + "ldr %[a], [r10]\n\t" + "mov r5, #0\n\t" + /* Multiply m[j] and mu - Start */ + "ldr r8, [%[m]], #4\n\t" + "umull r6, r8, %[mp], r8\n\t" + "adds %[a], %[a], r6\n\t" + "adc r5, r5, r8\n\t" + /* Multiply m[j] and mu - Done */ + "adds r4, r4, %[a]\n\t" + "adc r5, r5, #0\n\t" + "str r4, [r10], #4\n\t" + /* a[i+j+1] += m[j+1] * mu */ + "ldr %[a], [r10]\n\t" + "mov r4, #0\n\t" + /* Multiply m[j] and mu - Start */ + "ldr r8, [%[m]], #4\n\t" + "umull r6, r8, %[mp], r8\n\t" + "adds %[a], %[a], r6\n\t" + "adc r4, r4, r8\n\t" + /* Multiply m[j] and mu - Done */ + "adds r5, r5, %[a]\n\t" + "adc r4, r4, #0\n\t" + "str r5, [r10], #4\n\t" + "cmp r10, r14\n\t" +#ifdef __GNUC__ + "blt 2b\n\t" +#else + "blt.n 2b\n\t" +#endif /* __GNUC__ */ + /* a[i+30] += m[30] * mu */ + "ldr %[a], [r10]\n\t" + "mov r5, #0\n\t" + /* Multiply m[j] and mu - Start */ + "ldr r8, [%[m]], #4\n\t" + "umull r6, r8, %[mp], r8\n\t" + "adds %[a], %[a], r6\n\t" + "adc r5, r5, r8\n\t" + /* Multiply m[j] and mu - Done */ + "adds r4, r4, %[a]\n\t" + "adc r5, r5, #0\n\t" + "str r4, [r10], #4\n\t" + /* a[i+31] += m[31] * mu */ + "mov r4, %[ca]\n\t" + "mov %[ca], #0\n\t" + /* Multiply m[31] and mu - Start */ + "ldr r8, [%[m]]\n\t" + "umull r6, r8, %[mp], r8\n\t" + "adds r5, r5, r6\n\t" + "adcs r4, r4, r8\n\t" + "adc %[ca], %[ca], #0\n\t" + /* Multiply m[31] and mu - Done */ + "ldr r6, [r10]\n\t" + "ldr r8, [r10, #4]\n\t" + "adds r6, r6, r5\n\t" + "adcs r8, r8, r4\n\t" + "adc %[ca], %[ca], #0\n\t" + "str r6, [r10]\n\t" + "str r8, [r10, #4]\n\t" + /* Next word in a */ + "sub r10, r10, #120\n\t" + "cmp r10, r11\n\t" +#ifdef __GNUC__ + "blt 1b\n\t" +#else + "blt.n 1b\n\t" +#endif /* __GNUC__ */ + "ldr r6, [%[m]]\n\t" + "subs r6, r6, r8\n\t" + "neg %[ca], %[ca]\n\t" + "sbc r6, r6, r6\n\t" + "orr %[ca], %[ca], r6\n\t" + "mov %[a], r10\n\t" + "mov %[m], r12\n\t" + : [ca] "+r" (ca), [a] "+r" (a) + : [m] "r" (m), [mp] "r" (mp) + : "memory", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12", "r14" + ); + + sp_1024_cond_sub_32(a - 32, a, m, ca); +} + +/* Multiply two Montogmery form numbers mod the modulus (prime). + * (r = a * b mod m) + * + * r Result of multiplication. + * a First number to multiply in Montogmery form. + * b Second number to multiply in Montogmery form. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_1024_mont_mul_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) +{ + sp_1024_mul_32(r, a, b); + sp_1024_mont_reduce_32(r, m, mp); +} + +/* Square the Montgomery form number. (r = a * a mod m) + * + * r Result of squaring. + * a Number to square in Montogmery form. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_1024_mont_sqr_32(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) +{ + sp_1024_sqr_32(r, a); + sp_1024_mont_reduce_32(r, m, mp); +} + +/* Mod-2 for the P1024 curve. */ +static const uint8_t p1024_mod_minus_2[] = { + 6,0x06, 7,0x0f, 7,0x0b, 6,0x0c, 7,0x1e, 9,0x09, 7,0x0c, 7,0x1f, + 6,0x16, 6,0x06, 7,0x0e, 8,0x10, 6,0x03, 8,0x11, 6,0x0d, 7,0x14, + 9,0x12, 6,0x0f, 7,0x04, 9,0x0d, 6,0x00, 7,0x13, 6,0x01, 6,0x07, + 8,0x0d, 8,0x00, 6,0x06, 9,0x17, 6,0x14, 6,0x15, 6,0x11, 6,0x0b, + 9,0x0c, 6,0x1e, 13,0x14, 7,0x0e, 6,0x1d, 12,0x0a, 6,0x0b, 8,0x07, + 6,0x18, 6,0x0f, 6,0x10, 8,0x1c, 7,0x16, 7,0x02, 6,0x01, 6,0x13, + 10,0x15, 7,0x06, 8,0x14, 6,0x0c, 6,0x19, 7,0x10, 6,0x19, 6,0x19, + 9,0x16, 7,0x19, 6,0x1f, 6,0x17, 6,0x12, 8,0x02, 6,0x01, 6,0x04, + 6,0x15, 7,0x16, 6,0x04, 6,0x1f, 6,0x09, 7,0x06, 7,0x13, 7,0x09, + 6,0x0d, 10,0x18, 6,0x06, 6,0x11, 6,0x04, 6,0x01, 6,0x13, 8,0x06, + 6,0x0d, 8,0x13, 7,0x08, 6,0x08, 6,0x05, 7,0x0c, 7,0x0e, 7,0x15, + 6,0x05, 7,0x14, 10,0x19, 6,0x10, 6,0x16, 6,0x15, 7,0x1f, 6,0x14, + 6,0x0a, 10,0x11, 6,0x01, 7,0x05, 7,0x08, 8,0x0a, 7,0x1e, 7,0x1c, + 6,0x1c, 7,0x09, 10,0x18, 7,0x1c, 10,0x06, 6,0x0a, 6,0x07, 6,0x19, + 7,0x06, 6,0x0d, 7,0x0f, 7,0x0b, 7,0x05, 6,0x11, 6,0x1c, 7,0x1f, + 6,0x1e, 7,0x18, 6,0x1e, 6,0x00, 6,0x03, 6,0x02, 7,0x10, 6,0x0b, + 6,0x1b, 7,0x10, 6,0x00, 8,0x11, 7,0x1b, 6,0x18, 6,0x01, 7,0x0c, + 7,0x1d, 7,0x13, 6,0x08, 7,0x1b, 8,0x13, 7,0x16, 13,0x1d, 7,0x1f, + 6,0x0a, 6,0x01, 7,0x1f, 6,0x14, 1,0x01 +}; + +/* Invert the number, in Montgomery form, modulo the modulus (prime) of the + * P1024 curve. (r = 1 / a mod m) + * + * r Inverse result. + * a Number to invert. + * td Temporary data. + */ +static void sp_1024_mont_inv_32(sp_digit* r, const sp_digit* a, + sp_digit* td) +{ + sp_digit* t = td; + int i; + int j; + sp_digit table[32][2 * 32]; + + XMEMCPY(table[0], a, sizeof(sp_digit) * 32); + for (i = 1; i < 6; i++) { + sp_1024_mont_sqr_32(table[0], table[0], p1024_mod, p1024_mp_mod); + } + for (i = 1; i < 32; i++) { + sp_1024_mont_mul_32(table[i], table[i-1], a, p1024_mod, p1024_mp_mod); + } + + XMEMCPY(t, table[p1024_mod_minus_2[1]], sizeof(sp_digit) * 32); + for (i = 2; i < (int)sizeof(p1024_mod_minus_2) - 2; i += 2) { + for (j = 0; j < p1024_mod_minus_2[i]; j++) { + sp_1024_mont_sqr_32(t, t, p1024_mod, p1024_mp_mod); + } + sp_1024_mont_mul_32(t, t, table[p1024_mod_minus_2[i+1]], p1024_mod, + p1024_mp_mod); + } + sp_1024_mont_sqr_32(t, t, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(r, t, a, p1024_mod, p1024_mp_mod); +} + +/* Normalize the values in each word to 32. + * + * a Array of sp_digit to normalize. + */ +#define sp_1024_norm_32(a) + +/* Map the Montgomery form projective coordinate point to an affine point. + * + * r Resulting affine coordinate point. + * p Montgomery form projective coordinate point. + * t Temporary ordinate data. + */ +static void sp_1024_map_32(sp_point_1024* r, const sp_point_1024* p, + sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*32; + int32_t n; + + sp_1024_mont_inv_32(t1, p->z, t + 2*32); + + sp_1024_mont_sqr_32(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t1, t2, t1, p1024_mod, p1024_mp_mod); + + /* x /= z^2 */ + sp_1024_mont_mul_32(r->x, p->x, t2, p1024_mod, p1024_mp_mod); + XMEMSET(r->x + 32, 0, sizeof(r->x) / 2U); + sp_1024_mont_reduce_32(r->x, p1024_mod, p1024_mp_mod); + /* Reduce x to less than modulus */ + n = sp_1024_cmp_32(r->x, p1024_mod); + sp_1024_cond_sub_32(r->x, r->x, p1024_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_32(r->x); + + /* y /= z^3 */ + sp_1024_mont_mul_32(r->y, p->y, t1, p1024_mod, p1024_mp_mod); + XMEMSET(r->y + 32, 0, sizeof(r->y) / 2U); + sp_1024_mont_reduce_32(r->y, p1024_mod, p1024_mp_mod); + /* Reduce y to less than modulus */ + n = sp_1024_cmp_32(r->y, p1024_mod); + sp_1024_cond_sub_32(r->y, r->y, p1024_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_32(r->y); + + XMEMSET(r->z, 0, sizeof(r->z)); + r->z[0] = 1; + +} + +/* Add two Montgomery form numbers (r = a + b % m). + * + * r Result of addition. + * a First number to add in Montogmery form. + * b Second number to add in Montogmery form. + * m Modulus (prime). + */ +SP_NOINLINE static void sp_1024_mont_add_32(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + __asm__ __volatile__ ( + "mov r12, #0\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "adds r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldr r14, [%[m], #124]\n\t" + "adc r12, r12, #0\n\t" + "subs r14, r14, r7\n\t" + "neg r12, r12\n\t" + "sbc r14, r14, r14\n\t" + "sub %[r], %[r], #128\n\t" + "orr r12, r14\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "subs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbc r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "sub %[r], %[r], #128\n\t" + : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) + : + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + ); +} + +/* Double a Montgomery form number (r = a + a % m). + * + * r Result of doubling. + * a Number to double in Montogmery form. + * m Modulus (prime). + */ +SP_NOINLINE static void sp_1024_mont_dbl_32(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + __asm__ __volatile__ ( + "mov r12, #0\n\t" + "ldm %[a]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "adds r4, r4, r4\n\t" + "adcs r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adcs r7, r7, r7\n\t" + "adcs r8, r8, r8\n\t" + "adcs r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adcs r14, r14, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "adcs r4, r4, r4\n\t" + "adcs r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adcs r7, r7, r7\n\t" + "adcs r8, r8, r8\n\t" + "adcs r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adcs r14, r14, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "adcs r4, r4, r4\n\t" + "adcs r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adcs r7, r7, r7\n\t" + "adcs r8, r8, r8\n\t" + "adcs r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adcs r14, r14, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "adcs r4, r4, r4\n\t" + "adcs r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adcs r7, r7, r7\n\t" + "adcs r8, r8, r8\n\t" + "adcs r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adcs r14, r14, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "ldr r4, [%[m], #124]\n\t" + "adc r12, r12, #0\n\t" + "subs r4, r4, r14\n\t" + "neg r12, r12\n\t" + "sbc r4, r4, r4\n\t" + "sub %[r], %[r], #128\n\t" + "orr r12, r4\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "subs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbc r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "sub %[r], %[r], #128\n\t" + : [r] "+r" (r), [a] "+r" (a), [m] "+r" (m) + : + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + ); +} + +/* Triple a Montgomery form number (r = a + a + a % m). + * + * r Result of Tripling. + * a Number to triple in Montogmery form. + * m Modulus (prime). + */ +SP_NOINLINE static void sp_1024_mont_tpl_32(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + __asm__ __volatile__ ( + "mov r12, #0\n\t" + "ldm %[a]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "adds r4, r4, r4\n\t" + "adcs r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adcs r7, r7, r7\n\t" + "adcs r8, r8, r8\n\t" + "adcs r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adcs r14, r14, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "adcs r4, r4, r4\n\t" + "adcs r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adcs r7, r7, r7\n\t" + "adcs r8, r8, r8\n\t" + "adcs r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adcs r14, r14, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "adcs r4, r4, r4\n\t" + "adcs r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adcs r7, r7, r7\n\t" + "adcs r8, r8, r8\n\t" + "adcs r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adcs r14, r14, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "adcs r4, r4, r4\n\t" + "adcs r5, r5, r5\n\t" + "adcs r6, r6, r6\n\t" + "adcs r7, r7, r7\n\t" + "adcs r8, r8, r8\n\t" + "adcs r9, r9, r9\n\t" + "adcs r10, r10, r10\n\t" + "adcs r14, r14, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7, r8, r9, r10, r14}\n\t" + "ldr r4, [%[m], #124]\n\t" + "adc r12, r12, #0\n\t" + "subs r4, r4, r14\n\t" + "neg r12, r12\n\t" + "sbc r4, r4, r4\n\t" + "sub %[r], %[r], #128\n\t" + "orr r12, r4\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "subs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbc r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "sub %[r], %[r], #128\n\t" + "sub %[m], %[m], #128\n\t" + "sub %[a], %[a], #128\n\t" + "mov r12, #0\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "adds r8, r8, r4\n\t" + "adcs r9, r9, r5\n\t" + "adcs r10, r10, r6\n\t" + "adcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "adcs r8, r8, r4\n\t" + "adcs r9, r9, r5\n\t" + "adcs r10, r10, r6\n\t" + "adcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "adcs r8, r8, r4\n\t" + "adcs r9, r9, r5\n\t" + "adcs r10, r10, r6\n\t" + "adcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "adcs r8, r8, r4\n\t" + "adcs r9, r9, r5\n\t" + "adcs r10, r10, r6\n\t" + "adcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "adcs r8, r8, r4\n\t" + "adcs r9, r9, r5\n\t" + "adcs r10, r10, r6\n\t" + "adcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "adcs r8, r8, r4\n\t" + "adcs r9, r9, r5\n\t" + "adcs r10, r10, r6\n\t" + "adcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "adcs r8, r8, r4\n\t" + "adcs r9, r9, r5\n\t" + "adcs r10, r10, r6\n\t" + "adcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "adcs r8, r8, r4\n\t" + "adcs r9, r9, r5\n\t" + "adcs r10, r10, r6\n\t" + "adcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldr r7, [%[m], #124]\n\t" + "adc r12, r12, #0\n\t" + "subs r7, r7, r14\n\t" + "neg r12, r12\n\t" + "sbc r7, r7, r7\n\t" + "sub %[r], %[r], #128\n\t" + "orr r12, r7\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "ldm %[m]!, {r4, r5, r6, r7}\n\t" + "and r4, r4, r12\n\t" + "and r5, r5, r12\n\t" + "and r6, r6, r12\n\t" + "and r7, r7, r12\n\t" + "subs r8, r8, r4\n\t" + "sbcs r9, r9, r5\n\t" + "sbcs r10, r10, r6\n\t" + "sbcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "ldm %[m]!, {r4, r5, r6, r7}\n\t" + "and r4, r4, r12\n\t" + "and r5, r5, r12\n\t" + "and r6, r6, r12\n\t" + "and r7, r7, r12\n\t" + "sbcs r8, r8, r4\n\t" + "sbcs r9, r9, r5\n\t" + "sbcs r10, r10, r6\n\t" + "sbcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "ldm %[m]!, {r4, r5, r6, r7}\n\t" + "and r4, r4, r12\n\t" + "and r5, r5, r12\n\t" + "and r6, r6, r12\n\t" + "and r7, r7, r12\n\t" + "sbcs r8, r8, r4\n\t" + "sbcs r9, r9, r5\n\t" + "sbcs r10, r10, r6\n\t" + "sbcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "ldm %[m]!, {r4, r5, r6, r7}\n\t" + "and r4, r4, r12\n\t" + "and r5, r5, r12\n\t" + "and r6, r6, r12\n\t" + "and r7, r7, r12\n\t" + "sbcs r8, r8, r4\n\t" + "sbcs r9, r9, r5\n\t" + "sbcs r10, r10, r6\n\t" + "sbcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "ldm %[m]!, {r4, r5, r6, r7}\n\t" + "and r4, r4, r12\n\t" + "and r5, r5, r12\n\t" + "and r6, r6, r12\n\t" + "and r7, r7, r12\n\t" + "sbcs r8, r8, r4\n\t" + "sbcs r9, r9, r5\n\t" + "sbcs r10, r10, r6\n\t" + "sbcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "ldm %[m]!, {r4, r5, r6, r7}\n\t" + "and r4, r4, r12\n\t" + "and r5, r5, r12\n\t" + "and r6, r6, r12\n\t" + "and r7, r7, r12\n\t" + "sbcs r8, r8, r4\n\t" + "sbcs r9, r9, r5\n\t" + "sbcs r10, r10, r6\n\t" + "sbcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "ldm %[m]!, {r4, r5, r6, r7}\n\t" + "and r4, r4, r12\n\t" + "and r5, r5, r12\n\t" + "and r6, r6, r12\n\t" + "and r7, r7, r12\n\t" + "sbcs r8, r8, r4\n\t" + "sbcs r9, r9, r5\n\t" + "sbcs r10, r10, r6\n\t" + "sbcs r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "ldm %[r], {r8, r9, r10, r14}\n\t" + "ldm %[m]!, {r4, r5, r6, r7}\n\t" + "and r4, r4, r12\n\t" + "and r5, r5, r12\n\t" + "and r6, r6, r12\n\t" + "and r7, r7, r12\n\t" + "sbcs r8, r8, r4\n\t" + "sbcs r9, r9, r5\n\t" + "sbcs r10, r10, r6\n\t" + "sbc r14, r14, r7\n\t" + "stm %[r]!, {r8, r9, r10, r14}\n\t" + "sub %[r], %[r], #128\n\t" + : [r] "+r" (r), [a] "+r" (a), [m] "+r" (m) + : + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + ); +} + +/* Subtract two Montgomery form numbers (r = a - b % m). + * + * r Result of subtration. + * a Number to subtract from in Montogmery form. + * b Number to subtract with in Montogmery form. + * m Modulus (prime). + */ +SP_NOINLINE static void sp_1024_mont_sub_32(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + __asm__ __volatile__ ( + "mov r12, #0\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "subs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[a]!, {r4, r5, r6, r7}\n\t" + "ldm %[b]!, {r8, r9, r10, r14}\n\t" + "sbcs r4, r4, r8\n\t" + "sbcs r5, r5, r9\n\t" + "sbcs r6, r6, r10\n\t" + "sbcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "sbc r12, r12, r12\n\t" + "sub %[r], %[r], #128\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "adds r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adcs r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "ldm %[r], {r4, r5, r6, r7}\n\t" + "ldm %[m]!, {r8, r9, r10, r14}\n\t" + "and r8, r8, r12\n\t" + "and r9, r9, r12\n\t" + "and r10, r10, r12\n\t" + "and r14, r14, r12\n\t" + "adcs r4, r4, r8\n\t" + "adcs r5, r5, r9\n\t" + "adcs r6, r6, r10\n\t" + "adc r7, r7, r14\n\t" + "stm %[r]!, {r4, r5, r6, r7}\n\t" + "sub %[r], %[r], #128\n\t" + : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) + : + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r14", "r12" + ); +} + +/* Conditionally add a and b using the mask m. + * m is -1 to add and 0 when not. + * + * r A single precision number representing conditional add result. + * a A single precision number to add with. + * b A single precision number to add. + * m Mask value to apply. + */ +SP_NOINLINE static sp_digit sp_1024_cond_add_32(sp_digit* r, const sp_digit* a, const sp_digit* b, + sp_digit m) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r5, #128\n\t" + "mov r9, r5\n\t" + "mov r8, #0\n\t" + "\n1:\n\t" + "ldr r6, [%[b], r8]\n\t" + "and r6, r6, %[m]\n\t" + "adds r5, %[c], #-1\n\t" + "ldr r5, [%[a], r8]\n\t" + "adcs r5, r5, r6\n\t" + "mov %[c], #0\n\t" + "adcs %[c], %[c], %[c]\n\t" + "str r5, [%[r], r8]\n\t" + "add r8, r8, #4\n\t" + "cmp r8, r9\n\t" +#ifdef __GNUC__ + "blt 1b\n\t" +#else + "blt.n 1b\n\t" +#endif /* __GNUC__ */ + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "r5", "r6", "r8", "r9" + ); + + return c; +} + +static void sp_1024_rshift1_32(sp_digit* r, sp_digit* a) +{ + __asm__ __volatile__ ( + "ldr r2, [%[a]]\n\t" + "ldr r3, [%[a], #4]\n\t" + "lsr r2, r2, #1\n\t" + "orr r2, r2, r3, lsl #31\n\t" + "lsr r3, r3, #1\n\t" + "ldr r4, [%[a], #8]\n\t" + "str r2, [%[r], #0]\n\t" + "orr r3, r3, r4, lsl #31\n\t" + "lsr r4, r4, #1\n\t" + "ldr r2, [%[a], #12]\n\t" + "str r3, [%[r], #4]\n\t" + "orr r4, r4, r2, lsl #31\n\t" + "lsr r2, r2, #1\n\t" + "ldr r3, [%[a], #16]\n\t" + "str r4, [%[r], #8]\n\t" + "orr r2, r2, r3, lsl #31\n\t" + "lsr r3, r3, #1\n\t" + "ldr r4, [%[a], #20]\n\t" + "str r2, [%[r], #12]\n\t" + "orr r3, r3, r4, lsl #31\n\t" + "lsr r4, r4, #1\n\t" + "ldr r2, [%[a], #24]\n\t" + "str r3, [%[r], #16]\n\t" + "orr r4, r4, r2, lsl #31\n\t" + "lsr r2, r2, #1\n\t" + "ldr r3, [%[a], #28]\n\t" + "str r4, [%[r], #20]\n\t" + "orr r2, r2, r3, lsl #31\n\t" + "lsr r3, r3, #1\n\t" + "ldr r4, [%[a], #32]\n\t" + "str r2, [%[r], #24]\n\t" + "orr r3, r3, r4, lsl #31\n\t" + "lsr r4, r4, #1\n\t" + "ldr r2, [%[a], #36]\n\t" + "str r3, [%[r], #28]\n\t" + "orr r4, r4, r2, lsl #31\n\t" + "lsr r2, r2, #1\n\t" + "ldr r3, [%[a], #40]\n\t" + "str r4, [%[r], #32]\n\t" + "orr r2, r2, r3, lsl #31\n\t" + "lsr r3, r3, #1\n\t" + "ldr r4, [%[a], #44]\n\t" + "str r2, [%[r], #36]\n\t" + "orr r3, r3, r4, lsl #31\n\t" + "lsr r4, r4, #1\n\t" + "ldr r2, [%[a], #48]\n\t" + "str r3, [%[r], #40]\n\t" + "orr r4, r4, r2, lsl #31\n\t" + "lsr r2, r2, #1\n\t" + "ldr r3, [%[a], #52]\n\t" + "str r4, [%[r], #44]\n\t" + "orr r2, r2, r3, lsl #31\n\t" + "lsr r3, r3, #1\n\t" + "ldr r4, [%[a], #56]\n\t" + "str r2, [%[r], #48]\n\t" + "orr r3, r3, r4, lsl #31\n\t" + "lsr r4, r4, #1\n\t" + "ldr r2, [%[a], #60]\n\t" + "str r3, [%[r], #52]\n\t" + "orr r4, r4, r2, lsl #31\n\t" + "lsr r2, r2, #1\n\t" + "ldr r3, [%[a], #64]\n\t" + "str r4, [%[r], #56]\n\t" + "orr r2, r2, r3, lsl #31\n\t" + "lsr r3, r3, #1\n\t" + "ldr r4, [%[a], #68]\n\t" + "str r2, [%[r], #60]\n\t" + "orr r3, r3, r4, lsl #31\n\t" + "lsr r4, r4, #1\n\t" + "ldr r2, [%[a], #72]\n\t" + "str r3, [%[r], #64]\n\t" + "orr r4, r4, r2, lsl #31\n\t" + "lsr r2, r2, #1\n\t" + "ldr r3, [%[a], #76]\n\t" + "str r4, [%[r], #68]\n\t" + "orr r2, r2, r3, lsl #31\n\t" + "lsr r3, r3, #1\n\t" + "ldr r4, [%[a], #80]\n\t" + "str r2, [%[r], #72]\n\t" + "orr r3, r3, r4, lsl #31\n\t" + "lsr r4, r4, #1\n\t" + "ldr r2, [%[a], #84]\n\t" + "str r3, [%[r], #76]\n\t" + "orr r4, r4, r2, lsl #31\n\t" + "lsr r2, r2, #1\n\t" + "ldr r3, [%[a], #88]\n\t" + "str r4, [%[r], #80]\n\t" + "orr r2, r2, r3, lsl #31\n\t" + "lsr r3, r3, #1\n\t" + "ldr r4, [%[a], #92]\n\t" + "str r2, [%[r], #84]\n\t" + "orr r3, r3, r4, lsl #31\n\t" + "lsr r4, r4, #1\n\t" + "ldr r2, [%[a], #96]\n\t" + "str r3, [%[r], #88]\n\t" + "orr r4, r4, r2, lsl #31\n\t" + "lsr r2, r2, #1\n\t" + "ldr r3, [%[a], #100]\n\t" + "str r4, [%[r], #92]\n\t" + "orr r2, r2, r3, lsl #31\n\t" + "lsr r3, r3, #1\n\t" + "ldr r4, [%[a], #104]\n\t" + "str r2, [%[r], #96]\n\t" + "orr r3, r3, r4, lsl #31\n\t" + "lsr r4, r4, #1\n\t" + "ldr r2, [%[a], #108]\n\t" + "str r3, [%[r], #100]\n\t" + "orr r4, r4, r2, lsl #31\n\t" + "lsr r2, r2, #1\n\t" + "ldr r3, [%[a], #112]\n\t" + "str r4, [%[r], #104]\n\t" + "orr r2, r2, r3, lsl #31\n\t" + "lsr r3, r3, #1\n\t" + "ldr r4, [%[a], #116]\n\t" + "str r2, [%[r], #108]\n\t" + "orr r3, r3, r4, lsl #31\n\t" + "lsr r4, r4, #1\n\t" + "ldr r2, [%[a], #120]\n\t" + "str r3, [%[r], #112]\n\t" + "orr r4, r4, r2, lsl #31\n\t" + "lsr r2, r2, #1\n\t" + "ldr r3, [%[a], #124]\n\t" + "str r4, [%[r], #116]\n\t" + "orr r2, r2, r3, lsl #31\n\t" + "lsr r3, r3, #1\n\t" + "str r2, [%[r], #120]\n\t" + "str r3, [%[r], #124]\n\t" + : + : [r] "r" (r), [a] "r" (a) + : "memory", "r2", "r3", "r4" + ); +} + +/* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m) + * + * r Result of division by 2. + * a Number to divide. + * m Modulus (prime). + */ +SP_NOINLINE static void sp_1024_div2_32(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_digit o; + + o = sp_1024_cond_add_32(r, a, m, 0 - (a[0] & 1)); + sp_1024_rshift1_32(r, r); + r[31] |= o << 31; +} + +/* Double the Montgomery form projective point p. + * + * r Result of doubling point. + * p Point to double. + * t Temporary ordinate data. + */ +#ifdef WOLFSSL_SP_NONBLOCK +typedef struct sp_1024_proj_point_dbl_32_ctx { + int state; + sp_digit* t1; + sp_digit* t2; + sp_digit* x; + sp_digit* y; + sp_digit* z; +} sp_1024_proj_point_dbl_32_ctx; + +static int sp_1024_proj_point_dbl_32_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r, const sp_point_1024* p, sp_digit* t) +{ + int err = FP_WOULDBLOCK; + sp_1024_proj_point_dbl_32_ctx* ctx = (sp_1024_proj_point_dbl_32_ctx*)sp_ctx->data; + + typedef char ctx_size_test[sizeof(sp_1024_proj_point_dbl_32_ctx) >= sizeof(*sp_ctx) ? -1 : 1]; + (void)sizeof(ctx_size_test); + + switch (ctx->state) { + case 0: + ctx->t1 = t; + ctx->t2 = t + 2*32; + ctx->x = r->x; + ctx->y = r->y; + ctx->z = r->z; + + /* Put infinity into result. */ + if (r != p) { + r->infinity = p->infinity; + } + ctx->state = 1; + break; + case 1: + /* T1 = Z * Z */ + sp_1024_mont_sqr_32(ctx->t1, p->z, p1024_mod, p1024_mp_mod); + ctx->state = 2; + break; + case 2: + /* Z = Y * Z */ + sp_1024_mont_mul_32(ctx->z, p->y, p->z, p1024_mod, p1024_mp_mod); + ctx->state = 3; + break; + case 3: + /* Z = 2Z */ + sp_1024_mont_dbl_32(ctx->z, ctx->z, p1024_mod); + ctx->state = 4; + break; + case 4: + /* T2 = X - T1 */ + sp_1024_mont_sub_32(ctx->t2, p->x, ctx->t1, p1024_mod); + ctx->state = 5; + break; + case 5: + /* T1 = X + T1 */ + sp_1024_mont_add_32(ctx->t1, p->x, ctx->t1, p1024_mod); + ctx->state = 6; + break; + case 6: + /* T2 = T1 * T2 */ + sp_1024_mont_mul_32(ctx->t2, ctx->t1, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 7; + break; + case 7: + /* T1 = 3T2 */ + sp_1024_mont_tpl_32(ctx->t1, ctx->t2, p1024_mod); + ctx->state = 8; + break; + case 8: + /* Y = 2Y */ + sp_1024_mont_dbl_32(ctx->y, p->y, p1024_mod); + ctx->state = 9; + break; + case 9: + /* Y = Y * Y */ + sp_1024_mont_sqr_32(ctx->y, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 10; + break; + case 10: + /* T2 = Y * Y */ + sp_1024_mont_sqr_32(ctx->t2, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 11; + break; + case 11: + /* T2 = T2/2 */ + sp_1024_div2_32(ctx->t2, ctx->t2, p1024_mod); + ctx->state = 12; + break; + case 12: + /* Y = Y * X */ + sp_1024_mont_mul_32(ctx->y, ctx->y, p->x, p1024_mod, p1024_mp_mod); + ctx->state = 13; + break; + case 13: + /* X = T1 * T1 */ + sp_1024_mont_sqr_32(ctx->x, ctx->t1, p1024_mod, p1024_mp_mod); + ctx->state = 14; + break; + case 14: + /* X = X - Y */ + sp_1024_mont_sub_32(ctx->x, ctx->x, ctx->y, p1024_mod); + ctx->state = 15; + break; + case 15: + /* X = X - Y */ + sp_1024_mont_sub_32(ctx->x, ctx->x, ctx->y, p1024_mod); + ctx->state = 16; + break; + case 16: + /* Y = Y - X */ + sp_1024_mont_sub_32(ctx->y, ctx->y, ctx->x, p1024_mod); + ctx->state = 17; + break; + case 17: + /* Y = Y * T1 */ + sp_1024_mont_mul_32(ctx->y, ctx->y, ctx->t1, p1024_mod, p1024_mp_mod); + ctx->state = 18; + break; + case 18: + /* Y = Y - T2 */ + sp_1024_mont_sub_32(ctx->y, ctx->y, ctx->t2, p1024_mod); + ctx->state = 19; + /* fall-through */ + case 19: + err = MP_OKAY; + break; + } + + if (err == MP_OKAY && ctx->state != 19) { + err = FP_WOULDBLOCK; + } + + return err; +} +#endif /* WOLFSSL_SP_NONBLOCK */ + +static void sp_1024_proj_point_dbl_32(sp_point_1024* r, const sp_point_1024* p, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*32; + sp_digit* x; + sp_digit* y; + sp_digit* z; + + x = r->x; + y = r->y; + z = r->z; + /* Put infinity into result. */ + if (r != p) { + r->infinity = p->infinity; + } + + /* T1 = Z * Z */ + sp_1024_mont_sqr_32(t1, p->z, p1024_mod, p1024_mp_mod); + /* Z = Y * Z */ + sp_1024_mont_mul_32(z, p->y, p->z, p1024_mod, p1024_mp_mod); + /* Z = 2Z */ + sp_1024_mont_dbl_32(z, z, p1024_mod); + /* T2 = X - T1 */ + sp_1024_mont_sub_32(t2, p->x, t1, p1024_mod); + /* T1 = X + T1 */ + sp_1024_mont_add_32(t1, p->x, t1, p1024_mod); + /* T2 = T1 * T2 */ + sp_1024_mont_mul_32(t2, t1, t2, p1024_mod, p1024_mp_mod); + /* T1 = 3T2 */ + sp_1024_mont_tpl_32(t1, t2, p1024_mod); + /* Y = 2Y */ + sp_1024_mont_dbl_32(y, p->y, p1024_mod); + /* Y = Y * Y */ + sp_1024_mont_sqr_32(y, y, p1024_mod, p1024_mp_mod); + /* T2 = Y * Y */ + sp_1024_mont_sqr_32(t2, y, p1024_mod, p1024_mp_mod); + /* T2 = T2/2 */ + sp_1024_div2_32(t2, t2, p1024_mod); + /* Y = Y * X */ + sp_1024_mont_mul_32(y, y, p->x, p1024_mod, p1024_mp_mod); + /* X = T1 * T1 */ + sp_1024_mont_sqr_32(x, t1, p1024_mod, p1024_mp_mod); + /* X = X - Y */ + sp_1024_mont_sub_32(x, x, y, p1024_mod); + /* X = X - Y */ + sp_1024_mont_sub_32(x, x, y, p1024_mod); + /* Y = Y - X */ + sp_1024_mont_sub_32(y, y, x, p1024_mod); + /* Y = Y * T1 */ + sp_1024_mont_mul_32(y, y, t1, p1024_mod, p1024_mp_mod); + /* Y = Y - T2 */ + sp_1024_mont_sub_32(y, y, t2, p1024_mod); +} + +#ifdef WOLFSSL_SP_SMALL +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_1024_sub_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r6, %[a]\n\t" + "add r6, r6, #128\n\t" + "\n1:\n\t" + "mov r5, #0\n\t" + "subs r5, r5, %[c]\n\t" + "ldr r4, [%[a]]\n\t" + "ldr r5, [%[b]]\n\t" + "sbcs r4, r4, r5\n\t" + "str r4, [%[r]]\n\t" + "sbc %[c], %[c], %[c]\n\t" + "add %[a], %[a], #4\n\t" + "add %[b], %[b], #4\n\t" + "add %[r], %[r], #4\n\t" + "cmp %[a], r6\n\t" +#ifdef __GNUC__ + "bne 1b\n\t" +#else + "bne.n 1b\n\t" +#endif /* __GNUC__ */ + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6" + ); + + return c; +} + +#else +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static sp_digit sp_1024_sub_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldr r4, [%[a], #0]\n\t" + "ldr r5, [%[a], #4]\n\t" + "ldr r6, [%[b], #0]\n\t" + "ldr r8, [%[b], #4]\n\t" + "subs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #0]\n\t" + "str r5, [%[r], #4]\n\t" + "ldr r4, [%[a], #8]\n\t" + "ldr r5, [%[a], #12]\n\t" + "ldr r6, [%[b], #8]\n\t" + "ldr r8, [%[b], #12]\n\t" + "sbcs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #8]\n\t" + "str r5, [%[r], #12]\n\t" + "ldr r4, [%[a], #16]\n\t" + "ldr r5, [%[a], #20]\n\t" + "ldr r6, [%[b], #16]\n\t" + "ldr r8, [%[b], #20]\n\t" + "sbcs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #16]\n\t" + "str r5, [%[r], #20]\n\t" + "ldr r4, [%[a], #24]\n\t" + "ldr r5, [%[a], #28]\n\t" + "ldr r6, [%[b], #24]\n\t" + "ldr r8, [%[b], #28]\n\t" + "sbcs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #24]\n\t" + "str r5, [%[r], #28]\n\t" + "ldr r4, [%[a], #32]\n\t" + "ldr r5, [%[a], #36]\n\t" + "ldr r6, [%[b], #32]\n\t" + "ldr r8, [%[b], #36]\n\t" + "sbcs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #32]\n\t" + "str r5, [%[r], #36]\n\t" + "ldr r4, [%[a], #40]\n\t" + "ldr r5, [%[a], #44]\n\t" + "ldr r6, [%[b], #40]\n\t" + "ldr r8, [%[b], #44]\n\t" + "sbcs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #40]\n\t" + "str r5, [%[r], #44]\n\t" + "ldr r4, [%[a], #48]\n\t" + "ldr r5, [%[a], #52]\n\t" + "ldr r6, [%[b], #48]\n\t" + "ldr r8, [%[b], #52]\n\t" + "sbcs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #48]\n\t" + "str r5, [%[r], #52]\n\t" + "ldr r4, [%[a], #56]\n\t" + "ldr r5, [%[a], #60]\n\t" + "ldr r6, [%[b], #56]\n\t" + "ldr r8, [%[b], #60]\n\t" + "sbcs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #56]\n\t" + "str r5, [%[r], #60]\n\t" + "ldr r4, [%[a], #64]\n\t" + "ldr r5, [%[a], #68]\n\t" + "ldr r6, [%[b], #64]\n\t" + "ldr r8, [%[b], #68]\n\t" + "sbcs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #64]\n\t" + "str r5, [%[r], #68]\n\t" + "ldr r4, [%[a], #72]\n\t" + "ldr r5, [%[a], #76]\n\t" + "ldr r6, [%[b], #72]\n\t" + "ldr r8, [%[b], #76]\n\t" + "sbcs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #72]\n\t" + "str r5, [%[r], #76]\n\t" + "ldr r4, [%[a], #80]\n\t" + "ldr r5, [%[a], #84]\n\t" + "ldr r6, [%[b], #80]\n\t" + "ldr r8, [%[b], #84]\n\t" + "sbcs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #80]\n\t" + "str r5, [%[r], #84]\n\t" + "ldr r4, [%[a], #88]\n\t" + "ldr r5, [%[a], #92]\n\t" + "ldr r6, [%[b], #88]\n\t" + "ldr r8, [%[b], #92]\n\t" + "sbcs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #88]\n\t" + "str r5, [%[r], #92]\n\t" + "ldr r4, [%[a], #96]\n\t" + "ldr r5, [%[a], #100]\n\t" + "ldr r6, [%[b], #96]\n\t" + "ldr r8, [%[b], #100]\n\t" + "sbcs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #96]\n\t" + "str r5, [%[r], #100]\n\t" + "ldr r4, [%[a], #104]\n\t" + "ldr r5, [%[a], #108]\n\t" + "ldr r6, [%[b], #104]\n\t" + "ldr r8, [%[b], #108]\n\t" + "sbcs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #104]\n\t" + "str r5, [%[r], #108]\n\t" + "ldr r4, [%[a], #112]\n\t" + "ldr r5, [%[a], #116]\n\t" + "ldr r6, [%[b], #112]\n\t" + "ldr r8, [%[b], #116]\n\t" + "sbcs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #112]\n\t" + "str r5, [%[r], #116]\n\t" + "ldr r4, [%[a], #120]\n\t" + "ldr r5, [%[a], #124]\n\t" + "ldr r6, [%[b], #120]\n\t" + "ldr r8, [%[b], #124]\n\t" + "sbcs r4, r4, r6\n\t" + "sbcs r5, r5, r8\n\t" + "str r4, [%[r], #120]\n\t" + "str r5, [%[r], #124]\n\t" + "sbc %[c], %[c], %[c]\n\t" + : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r4", "r5", "r6", "r8" + ); + + return c; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Compare two numbers to determine if they are equal. + * Constant time implementation. + * + * a First number to compare. + * b Second number to compare. + * returns 1 when equal and 0 otherwise. + */ +static int sp_1024_cmp_equal_32(const sp_digit* a, const sp_digit* b) +{ + return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) | (a[3] ^ b[3]) | + (a[4] ^ b[4]) | (a[5] ^ b[5]) | (a[6] ^ b[6]) | (a[7] ^ b[7]) | + (a[8] ^ b[8]) | (a[9] ^ b[9]) | (a[10] ^ b[10]) | (a[11] ^ b[11]) | + (a[12] ^ b[12]) | (a[13] ^ b[13]) | (a[14] ^ b[14]) | (a[15] ^ b[15]) | + (a[16] ^ b[16]) | (a[17] ^ b[17]) | (a[18] ^ b[18]) | (a[19] ^ b[19]) | + (a[20] ^ b[20]) | (a[21] ^ b[21]) | (a[22] ^ b[22]) | (a[23] ^ b[23]) | + (a[24] ^ b[24]) | (a[25] ^ b[25]) | (a[26] ^ b[26]) | (a[27] ^ b[27]) | + (a[28] ^ b[28]) | (a[29] ^ b[29]) | (a[30] ^ b[30]) | (a[31] ^ b[31])) == 0; +} + +/* Add two Montgomery form projective points. + * + * r Result of addition. + * p First point to add. + * q Second point to add. + * t Temporary ordinate data. + */ + +#ifdef WOLFSSL_SP_NONBLOCK +typedef struct sp_1024_proj_point_add_32_ctx { + int state; + sp_1024_proj_point_dbl_32_ctx dbl_ctx; + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1; + sp_digit* t2; + sp_digit* t3; + sp_digit* t4; + sp_digit* t5; + sp_digit* x; + sp_digit* y; + sp_digit* z; +} sp_1024_proj_point_add_32_ctx; + +static int sp_1024_proj_point_add_32_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r, + const sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + int err = FP_WOULDBLOCK; + sp_1024_proj_point_add_32_ctx* ctx = (sp_1024_proj_point_add_32_ctx*)sp_ctx->data; + + /* Ensure only the first point is the same as the result. */ + if (q == r) { + const sp_point_1024* a = p; + p = q; + q = a; + } + + typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_32_ctx) >= sizeof(*sp_ctx) ? -1 : 1]; + (void)sizeof(ctx_size_test); + + switch (ctx->state) { + case 0: /* INIT */ + ctx->t1 = t; + ctx->t2 = t + 2*32; + ctx->t3 = t + 4*32; + ctx->t4 = t + 6*32; + ctx->t5 = t + 8*32; + + ctx->state = 1; + break; + case 1: + /* Check double */ + (void)sp_1024_sub_32(ctx->t1, p1024_mod, q->y); + sp_1024_norm_32(ctx->t1); + if ((sp_1024_cmp_equal_32(p->x, q->x) & sp_1024_cmp_equal_32(p->z, q->z) & + (sp_1024_cmp_equal_32(p->y, q->y) | sp_1024_cmp_equal_32(p->y, ctx->t1))) != 0) + { + XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx)); + ctx->state = 2; + } + else { + ctx->state = 3; + } + break; + case 2: + err = sp_1024_proj_point_dbl_32_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, r, p, t); + if (err == MP_OKAY) + ctx->state = 27; /* done */ + break; + case 3: + { + int i; + ctx->rp[0] = r; + + /*lint allow cast to different type of pointer*/ + ctx->rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(ctx->rp[1], 0, sizeof(sp_point_1024)); + ctx->x = ctx->rp[p->infinity | q->infinity]->x; + ctx->y = ctx->rp[p->infinity | q->infinity]->y; + ctx->z = ctx->rp[p->infinity | q->infinity]->z; + + ctx->ap[0] = p; + ctx->ap[1] = q; + for (i=0; i<32; i++) { + r->x[i] = ctx->ap[p->infinity]->x[i]; + } + for (i=0; i<32; i++) { + r->y[i] = ctx->ap[p->infinity]->y[i]; + } + for (i=0; i<32; i++) { + r->z[i] = ctx->ap[p->infinity]->z[i]; + } + r->infinity = ctx->ap[p->infinity]->infinity; + + ctx->state = 4; + break; + } + case 4: + /* U1 = X1*Z2^2 */ + sp_1024_mont_sqr_32(ctx->t1, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 5; + break; + case 5: + sp_1024_mont_mul_32(ctx->t3, ctx->t1, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 6; + break; + case 6: + sp_1024_mont_mul_32(ctx->t1, ctx->t1, ctx->x, p1024_mod, p1024_mp_mod); + ctx->state = 7; + break; + case 7: + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_32(ctx->t2, ctx->z, p1024_mod, p1024_mp_mod); + ctx->state = 8; + break; + case 8: + sp_1024_mont_mul_32(ctx->t4, ctx->t2, ctx->z, p1024_mod, p1024_mp_mod); + ctx->state = 9; + break; + case 9: + sp_1024_mont_mul_32(ctx->t2, ctx->t2, q->x, p1024_mod, p1024_mp_mod); + ctx->state = 10; + break; + case 10: + /* S1 = Y1*Z2^3 */ + sp_1024_mont_mul_32(ctx->t3, ctx->t3, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 11; + break; + case 11: + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_32(ctx->t4, ctx->t4, q->y, p1024_mod, p1024_mp_mod); + ctx->state = 12; + break; + case 12: + /* H = U2 - U1 */ + sp_1024_mont_sub_32(ctx->t2, ctx->t2, ctx->t1, p1024_mod); + ctx->state = 13; + break; + case 13: + /* R = S2 - S1 */ + sp_1024_mont_sub_32(ctx->t4, ctx->t4, ctx->t3, p1024_mod); + ctx->state = 14; + break; + case 14: + /* Z3 = H*Z1*Z2 */ + sp_1024_mont_mul_32(ctx->z, ctx->z, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 15; + break; + case 15: + sp_1024_mont_mul_32(ctx->z, ctx->z, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 16; + break; + case 16: + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_1024_mont_sqr_32(ctx->x, ctx->t4, p1024_mod, p1024_mp_mod); + ctx->state = 17; + break; + case 17: + sp_1024_mont_sqr_32(ctx->t5, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 18; + break; + case 18: + sp_1024_mont_mul_32(ctx->y, ctx->t1, ctx->t5, p1024_mod, p1024_mp_mod); + ctx->state = 19; + break; + case 19: + sp_1024_mont_mul_32(ctx->t5, ctx->t5, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 20; + break; + case 20: + sp_1024_mont_sub_32(ctx->x, ctx->x, ctx->t5, p1024_mod); + ctx->state = 21; + break; + case 21: + sp_1024_mont_dbl_32(ctx->t1, ctx->y, p1024_mod); + ctx->state = 22; + break; + case 22: + sp_1024_mont_sub_32(ctx->x, ctx->x, ctx->t1, p1024_mod); + ctx->state = 23; + break; + case 23: + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_1024_mont_sub_32(ctx->y, ctx->y, ctx->x, p1024_mod); + ctx->state = 24; + break; + case 24: + sp_1024_mont_mul_32(ctx->y, ctx->y, ctx->t4, p1024_mod, p1024_mp_mod); + ctx->state = 25; + break; + case 25: + sp_1024_mont_mul_32(ctx->t5, ctx->t5, ctx->t3, p1024_mod, p1024_mp_mod); + ctx->state = 26; + break; + case 26: + sp_1024_mont_sub_32(ctx->y, ctx->y, ctx->t5, p1024_mod); + ctx->state = 27; + /* fall-through */ + case 27: + err = MP_OKAY; + break; + } + + if (err == MP_OKAY && ctx->state != 27) { + err = FP_WOULDBLOCK; + } + return err; +} +#endif /* WOLFSSL_SP_NONBLOCK */ + +static void sp_1024_proj_point_add_32(sp_point_1024* r, + const sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*32; + sp_digit* t3 = t + 4*32; + sp_digit* t4 = t + 6*32; + sp_digit* t5 = t + 8*32; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Ensure only the first point is the same as the result. */ + if (q == r) { + const sp_point_1024* a = p; + p = q; + q = a; + } + + /* Check double */ + (void)sp_1024_mont_sub_32(t1, p1024_mod, q->y, p1024_mod); + sp_1024_norm_32(t1); + if ((sp_1024_cmp_equal_32(p->x, q->x) & sp_1024_cmp_equal_32(p->z, q->z) & + (sp_1024_cmp_equal_32(p->y, q->y) | sp_1024_cmp_equal_32(p->y, t1))) != 0) { + sp_1024_proj_point_dbl_32(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_1024)); + x = rp[p->infinity | q->infinity]->x; + y = rp[p->infinity | q->infinity]->y; + z = rp[p->infinity | q->infinity]->z; + + ap[0] = p; + ap[1] = q; + for (i=0; i<32; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<32; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<32; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U1 = X1*Z2^2 */ + sp_1024_mont_sqr_32(t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t3, t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t1, t1, x, p1024_mod, p1024_mp_mod); + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_32(t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t4, t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t2, t2, q->x, p1024_mod, p1024_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_1024_mont_mul_32(t3, t3, y, p1024_mod, p1024_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_32(t4, t4, q->y, p1024_mod, p1024_mp_mod); + /* H = U2 - U1 */ + sp_1024_mont_sub_32(t2, t2, t1, p1024_mod); + /* R = S2 - S1 */ + sp_1024_mont_sub_32(t4, t4, t3, p1024_mod); + /* Z3 = H*Z1*Z2 */ + sp_1024_mont_mul_32(z, z, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(z, z, t2, p1024_mod, p1024_mp_mod); + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_1024_mont_sqr_32(x, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_32(t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(y, t1, t5, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t5, t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_32(x, x, t5, p1024_mod); + sp_1024_mont_dbl_32(t1, y, p1024_mod); + sp_1024_mont_sub_32(x, x, t1, p1024_mod); + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_1024_mont_sub_32(y, y, x, p1024_mod); + sp_1024_mont_mul_32(y, y, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t5, t5, t3, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_32(y, y, t5, p1024_mod); + } +} + +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Fast implementation that generates a pre-computation table. + * 4 bits of window (no sliding!). + * Uses add and double for calculating table. + * 1024 doubles. + * 268 adds. + * + * r Resulting point. + * g Point to multiply. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_fast_32(sp_point_1024* r, const sp_point_1024* g, const sp_digit* k, + int map, int ct, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 td[16]; + sp_point_1024 rtd; + sp_digit tmpd[2 * 32 * 5]; +#endif + sp_point_1024* t; + sp_point_1024* rt; + sp_digit* tmp; + sp_digit n; + int i; + int c; + int y; + int err; + + /* Constant time used for cache attack resistance implementation. */ + (void)ct; + (void)heap; + + err = sp_1024_point_new_32(heap, rtd, rt); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +#ifndef WC_NO_CACHE_RESISTANT + t = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) * 17, heap, DYNAMIC_TYPE_ECC); +#else + t = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) * 16, heap, DYNAMIC_TYPE_ECC); +#endif + if (t == NULL) + err = MEMORY_E; + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 32 * 5, heap, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) + err = MEMORY_E; +#else + t = td; + tmp = tmpd; +#endif + + if (err == MP_OKAY) { + /* t[0] = {0, 0, 1} * norm */ + XMEMSET(&t[0], 0, sizeof(t[0])); + t[0].infinity = 1; + /* t[1] = {g->x, g->y, g->z} * norm */ + (void)sp_1024_mod_mul_norm_32(t[1].x, g->x, p1024_mod); + (void)sp_1024_mod_mul_norm_32(t[1].y, g->y, p1024_mod); + (void)sp_1024_mod_mul_norm_32(t[1].z, g->z, p1024_mod); + t[1].infinity = 0; + sp_1024_proj_point_dbl_32(&t[ 2], &t[ 1], tmp); + t[ 2].infinity = 0; + sp_1024_proj_point_add_32(&t[ 3], &t[ 2], &t[ 1], tmp); + t[ 3].infinity = 0; + sp_1024_proj_point_dbl_32(&t[ 4], &t[ 2], tmp); + t[ 4].infinity = 0; + sp_1024_proj_point_add_32(&t[ 5], &t[ 3], &t[ 2], tmp); + t[ 5].infinity = 0; + sp_1024_proj_point_dbl_32(&t[ 6], &t[ 3], tmp); + t[ 6].infinity = 0; + sp_1024_proj_point_add_32(&t[ 7], &t[ 4], &t[ 3], tmp); + t[ 7].infinity = 0; + sp_1024_proj_point_dbl_32(&t[ 8], &t[ 4], tmp); + t[ 8].infinity = 0; + sp_1024_proj_point_add_32(&t[ 9], &t[ 5], &t[ 4], tmp); + t[ 9].infinity = 0; + sp_1024_proj_point_dbl_32(&t[10], &t[ 5], tmp); + t[10].infinity = 0; + sp_1024_proj_point_add_32(&t[11], &t[ 6], &t[ 5], tmp); + t[11].infinity = 0; + sp_1024_proj_point_dbl_32(&t[12], &t[ 6], tmp); + t[12].infinity = 0; + sp_1024_proj_point_add_32(&t[13], &t[ 7], &t[ 6], tmp); + t[13].infinity = 0; + sp_1024_proj_point_dbl_32(&t[14], &t[ 7], tmp); + t[14].infinity = 0; + sp_1024_proj_point_add_32(&t[15], &t[ 8], &t[ 7], tmp); + t[15].infinity = 0; + + i = 30; + n = k[i+1] << 0; + c = 28; + y = (int)(n >> 28); + XMEMCPY(rt, &t[y], sizeof(sp_point_1024)); + n <<= 4; + for (; i>=0 || c>=4; ) { + if (c < 4) { + n |= k[i--]; + c += 32; + } + y = (n >> 28) & 0xf; + n <<= 4; + c -= 4; + + sp_1024_proj_point_dbl_32(rt, rt, tmp); + sp_1024_proj_point_dbl_32(rt, rt, tmp); + sp_1024_proj_point_dbl_32(rt, rt, tmp); + sp_1024_proj_point_dbl_32(rt, rt, tmp); + sp_1024_proj_point_add_32(rt, rt, &t[y], tmp); + } + + if (map != 0) { + sp_1024_map_32(r, rt, tmp); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_1024)); + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (tmp != NULL) { + XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 32 * 5); + XFREE(tmp, heap, DYNAMIC_TYPE_ECC); + } + if (t != NULL) { + XMEMSET(t, 0, sizeof(sp_point_1024) * 16); + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#else + ForceZero(tmpd, sizeof(tmpd)); + ForceZero(td, sizeof(td)); +#endif + sp_1024_point_free_32(rt, 1, heap); + + return err; +} + +#if defined(FP_ECC) || !defined(WOLFSSL_SP_SMALL) +/* Double the Montgomery form projective point p a number of times. + * + * r Result of repeated doubling of point. + * p Point to double. + * n Number of times to double + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_dbl_n_32(sp_point_1024* p, int n, + sp_digit* t) +{ + sp_digit* w = t; + sp_digit* a = t + 2*32; + sp_digit* b = t + 4*32; + sp_digit* t1 = t + 6*32; + sp_digit* t2 = t + 8*32; + sp_digit* x; + sp_digit* y; + sp_digit* z; + + x = p->x; + y = p->y; + z = p->z; + + /* Y = 2*Y */ + sp_1024_mont_dbl_32(y, y, p1024_mod); + /* W = Z^4 */ + sp_1024_mont_sqr_32(w, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_32(w, w, p1024_mod, p1024_mp_mod); + +#ifndef WOLFSSL_SP_SMALL + while (--n > 0) +#else + while (--n >= 0) +#endif + { + /* A = 3*(X^2 - W) */ + sp_1024_mont_sqr_32(t1, x, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_32(t1, t1, w, p1024_mod); + sp_1024_mont_tpl_32(a, t1, p1024_mod); + /* B = X*Y^2 */ + sp_1024_mont_sqr_32(t1, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(b, t1, x, p1024_mod, p1024_mp_mod); + /* X = A^2 - 2B */ + sp_1024_mont_sqr_32(x, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_32(t2, b, p1024_mod); + sp_1024_mont_sub_32(x, x, t2, p1024_mod); + /* Z = Z*Y */ + sp_1024_mont_mul_32(z, z, y, p1024_mod, p1024_mp_mod); + /* t2 = Y^4 */ + sp_1024_mont_sqr_32(t1, t1, p1024_mod, p1024_mp_mod); +#ifdef WOLFSSL_SP_SMALL + if (n != 0) +#endif + { + /* W = W*Y^4 */ + sp_1024_mont_mul_32(w, w, t1, p1024_mod, p1024_mp_mod); + } + /* y = 2*A*(B - X) - Y^4 */ + sp_1024_mont_sub_32(y, b, x, p1024_mod); + sp_1024_mont_mul_32(y, y, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_32(y, y, p1024_mod); + sp_1024_mont_sub_32(y, y, t1, p1024_mod); + } +#ifndef WOLFSSL_SP_SMALL + /* A = 3*(X^2 - W) */ + sp_1024_mont_sqr_32(t1, x, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_32(t1, t1, w, p1024_mod); + sp_1024_mont_tpl_32(a, t1, p1024_mod); + /* B = X*Y^2 */ + sp_1024_mont_sqr_32(t1, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(b, t1, x, p1024_mod, p1024_mp_mod); + /* X = A^2 - 2B */ + sp_1024_mont_sqr_32(x, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_32(t2, b, p1024_mod); + sp_1024_mont_sub_32(x, x, t2, p1024_mod); + /* Z = Z*Y */ + sp_1024_mont_mul_32(z, z, y, p1024_mod, p1024_mp_mod); + /* t2 = Y^4 */ + sp_1024_mont_sqr_32(t1, t1, p1024_mod, p1024_mp_mod); + /* y = 2*A*(B - X) - Y^4 */ + sp_1024_mont_sub_32(y, b, x, p1024_mod); + sp_1024_mont_mul_32(y, y, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_32(y, y, p1024_mod); + sp_1024_mont_sub_32(y, y, t1, p1024_mod); +#endif + /* Y = Y/2 */ + sp_1024_div2_32(y, y, p1024_mod); +} + +/* Convert the projective point to affine. + * Ordinates are in Montgomery form. + * + * a Point to convert. + * t Temporary data. + */ +static void sp_1024_proj_to_affine_32(sp_point_1024* a, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 32; + sp_digit* tmp = t + 4 * 32; + + sp_1024_mont_inv_32(t1, a->z, tmp); + + sp_1024_mont_sqr_32(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t1, t2, t1, p1024_mod, p1024_mp_mod); + + sp_1024_mont_mul_32(a->x, a->x, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(a->y, a->y, t1, p1024_mod, p1024_mp_mod); + XMEMCPY(a->z, p1024_norm_mod, sizeof(p1024_norm_mod)); +} + +#endif /* FP_ECC || !WOLFSSL_SP_SMALL */ +/* A table entry for pre-computed points. */ +typedef struct sp_table_entry_1024 { + sp_digit x[32]; + sp_digit y[32]; +} sp_table_entry_1024; + +#ifdef FP_ECC +#endif /* FP_ECC */ +/* Add two Montgomery form projective points. The second point has a q value of + * one. + * Only the first point can be the same pointer as the result point. + * + * r Result of addition. + * p First point to add. + * q Second point to add. + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_add_qz1_32(sp_point_1024* r, const sp_point_1024* p, + const sp_point_1024* q, sp_digit* t) +{ + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*32; + sp_digit* t3 = t + 4*32; + sp_digit* t4 = t + 6*32; + sp_digit* t5 = t + 8*32; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Check double */ + (void)sp_1024_mont_sub_32(t1, p1024_mod, q->y, p1024_mod); + sp_1024_norm_32(t1); + if ((sp_1024_cmp_equal_32(p->x, q->x) & sp_1024_cmp_equal_32(p->z, q->z) & + (sp_1024_cmp_equal_32(p->y, q->y) | sp_1024_cmp_equal_32(p->y, t1))) != 0) { + sp_1024_proj_point_dbl_32(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_1024)); + x = rp[p->infinity | q->infinity]->x; + y = rp[p->infinity | q->infinity]->y; + z = rp[p->infinity | q->infinity]->z; + + ap[0] = p; + ap[1] = q; + for (i=0; i<32; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<32; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<32; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_32(t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t4, t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t2, t2, q->x, p1024_mod, p1024_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_32(t4, t4, q->y, p1024_mod, p1024_mp_mod); + /* H = U2 - X1 */ + sp_1024_mont_sub_32(t2, t2, x, p1024_mod); + /* R = S2 - Y1 */ + sp_1024_mont_sub_32(t4, t4, y, p1024_mod); + /* Z3 = H*Z1 */ + sp_1024_mont_mul_32(z, z, t2, p1024_mod, p1024_mp_mod); + /* X3 = R^2 - H^3 - 2*X1*H^2 */ + sp_1024_mont_sqr_32(t1, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_32(t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t3, x, t5, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t5, t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_32(x, t1, t5, p1024_mod); + sp_1024_mont_dbl_32(t1, t3, p1024_mod); + sp_1024_mont_sub_32(x, x, t1, p1024_mod); + /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */ + sp_1024_mont_sub_32(t3, t3, x, p1024_mod); + sp_1024_mont_mul_32(t3, t3, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t5, t5, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_32(y, t3, t5, p1024_mod); + } +} + +#ifdef WOLFSSL_SP_SMALL +#if defined(FP_ECC) || !defined(WOLFSSL_SP_SMALL) +/* Generate the pre-computed table of points for the base point. + * + * width = 4 + * 16 entries + * 256 bits between + * + * a The base point. + * table Place to store generated point data. + * tmp Temporary data. + * heap Heap to use for allocation. + */ +static int sp_1024_gen_stripe_table_32(const sp_point_1024* a, + sp_table_entry_1024* table, sp_digit* tmp, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 td; + sp_point_1024 s1d; + sp_point_1024 s2d; +#endif + sp_point_1024* t; + sp_point_1024* s1 = NULL; + sp_point_1024* s2 = NULL; + int i; + int j; + int err; + + (void)heap; + + err = sp_1024_point_new_32(heap, td, t); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, s1d, s1); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, s2d, s2); + } + + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(t->x, a->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(t->y, a->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(t->z, a->z, p1024_mod); + } + if (err == MP_OKAY) { + t->infinity = 0; + sp_1024_proj_to_affine_32(t, tmp); + + XMEMCPY(s1->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + s1->infinity = 0; + XMEMCPY(s2->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + s2->infinity = 0; + + /* table[0] = {0, 0, infinity} */ + XMEMSET(&table[0], 0, sizeof(sp_table_entry_1024)); + /* table[1] = Affine version of 'a' in Montgomery form */ + XMEMCPY(table[1].x, t->x, sizeof(table->x)); + XMEMCPY(table[1].y, t->y, sizeof(table->y)); + + for (i=1; i<4; i++) { + sp_1024_proj_point_dbl_n_32(t, 256, tmp); + sp_1024_proj_to_affine_32(t, tmp); + XMEMCPY(table[1<x, sizeof(table->x)); + XMEMCPY(table[1<y, sizeof(table->y)); + } + + for (i=1; i<4; i++) { + XMEMCPY(s1->x, table[1<x)); + XMEMCPY(s1->y, table[1<y)); + for (j=(1<x, table[j-(1<x)); + XMEMCPY(s2->y, table[j-(1<y)); + sp_1024_proj_point_add_qz1_32(t, s1, s2, tmp); + sp_1024_proj_to_affine_32(t, tmp); + XMEMCPY(table[j].x, t->x, sizeof(table->x)); + XMEMCPY(table[j].y, t->y, sizeof(table->y)); + } + } + } + + sp_1024_point_free_32(s2, 0, heap); + sp_1024_point_free_32(s1, 0, heap); + sp_1024_point_free_32( t, 0, heap); + + return err; +} + +#endif /* FP_ECC || !WOLFSSL_SP_SMALL */ +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^256, ... + * Pre-generated: products of all combinations of above. + * 4 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * table Pre-computed table. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_stripe_32(sp_point_1024* r, const sp_point_1024* g, + const sp_table_entry_1024* table, const sp_digit* k, int map, + int ct, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 rtd; + sp_point_1024 pd; + sp_digit td[2 * 32 * 5]; +#endif + sp_point_1024* rt; + sp_point_1024* p = NULL; + sp_digit* t; + int i; + int j; + int y; + int x; + int err; + + (void)g; + /* Constant time used for cache attack resistance implementation. */ + (void)ct; + (void)heap; + + + err = sp_1024_point_new_32(heap, rtd, rt); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, pd, p); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 32 * 5, heap, + DYNAMIC_TYPE_ECC); + if (t == NULL) { + err = MEMORY_E; + } +#else + t = td; +#endif + + if (err == MP_OKAY) { + XMEMCPY(p->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + XMEMCPY(rt->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + + y = 0; + x = 255; + for (j=0; j<4; j++) { + y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 256; + } + XMEMCPY(rt->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(rt->y, table[y].y, sizeof(table[y].y)); + rt->infinity = !y; + for (i=254; i>=0; i--) { + y = 0; + x = i; + for (j=0; j<4; j++) { + y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 256; + } + + sp_1024_proj_point_dbl_32(rt, rt, t); + XMEMCPY(p->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(p->y, table[y].y, sizeof(table[y].y)); + p->infinity = !y; + sp_1024_proj_point_add_qz1_32(rt, rt, p, t); + } + + if (map != 0) { + sp_1024_map_32(r, rt, t); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_1024)); + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (t != NULL) { + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_32(p, 0, heap); + sp_1024_point_free_32(rt, 0, heap); + + return err; +} + +#ifdef FP_ECC +#ifndef FP_ENTRIES + #define FP_ENTRIES 16 +#endif + +/* Cache entry - holds precomputation tables for a point. */ +typedef struct sp_cache_1024_t { + /* X ordinate of point that table was generated from. */ + sp_digit x[32]; + /* Y ordinate of point that table was generated from. */ + sp_digit y[32]; + /* Precomputation table for point. */ + sp_table_entry_1024 table[16]; + /* Count of entries in table. */ + uint32_t cnt; + /* Point and table set in entry. */ + int set; +} sp_cache_1024_t; + +/* Cache of tables. */ +static THREAD_LS_T sp_cache_1024_t sp_cache_1024[FP_ENTRIES]; +/* Index of last entry in cache. */ +static THREAD_LS_T int sp_cache_1024_last = -1; +/* Cache has been initialized. */ +static THREAD_LS_T int sp_cache_1024_inited = 0; + +#ifndef HAVE_THREAD_LS + static volatile int initCacheMutex_1024 = 0; + static wolfSSL_Mutex sp_cache_1024_lock; +#endif + +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ +static void sp_ecc_get_cache_1024(const sp_point_1024* g, sp_cache_1024_t** cache) +{ + int i; + int j; + uint32_t least; + + if (sp_cache_1024_inited == 0) { + for (i=0; ix, sp_cache_1024[i].x) & + sp_1024_cmp_equal_32(g->y, sp_cache_1024[i].y)) { + sp_cache_1024[i].cnt++; + break; + } + } + + /* No match. */ + if (i == FP_ENTRIES) { + /* Find empty entry. */ + i = (sp_cache_1024_last + 1) % FP_ENTRIES; + for (; i != sp_cache_1024_last; i=(i+1)%FP_ENTRIES) { + if (!sp_cache_1024[i].set) { + break; + } + } + + /* Evict least used. */ + if (i == sp_cache_1024_last) { + least = sp_cache_1024[0].cnt; + for (j=1; jx, sizeof(sp_cache_1024[i].x)); + XMEMCPY(sp_cache_1024[i].y, g->y, sizeof(sp_cache_1024[i].y)); + sp_cache_1024[i].set = 1; + sp_cache_1024[i].cnt = 1; + } + + *cache = &sp_cache_1024[i]; + sp_cache_1024_last = i; +} +#endif /* FP_ECC */ + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * r Resulting point. + * g Point to multiply. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_32(sp_point_1024* r, const sp_point_1024* g, const sp_digit* k, + int map, int ct, void* heap) +{ +#ifndef FP_ECC + return sp_1024_ecc_mulmod_fast_32(r, g, k, map, ct, heap); +#else + sp_digit tmp[2 * 32 * 5]; + sp_cache_1024_t* cache; + int err = MP_OKAY; + +#ifndef HAVE_THREAD_LS + if (initCacheMutex_1024 == 0) { + wc_InitMutex(&sp_cache_1024_lock); + initCacheMutex_1024 = 1; + } + if (wc_LockMutex(&sp_cache_1024_lock) != 0) + err = BAD_MUTEX_E; +#endif /* HAVE_THREAD_LS */ + + if (err == MP_OKAY) { + sp_ecc_get_cache_1024(g, &cache); + if (cache->cnt == 2) + sp_1024_gen_stripe_table_32(g, cache->table, tmp, heap); + +#ifndef HAVE_THREAD_LS + wc_UnLockMutex(&sp_cache_1024_lock); +#endif /* HAVE_THREAD_LS */ + + if (cache->cnt < 2) { + err = sp_1024_ecc_mulmod_fast_32(r, g, k, map, ct, heap); + } + else { + err = sp_1024_ecc_mulmod_stripe_32(r, g, cache->table, k, + map, ct, heap); + } + } + + return err; +#endif +} + +#else +#if defined(FP_ECC) || !defined(WOLFSSL_SP_SMALL) +/* Generate the pre-computed table of points for the base point. + * + * width = 8 + * 256 entries + * 128 bits between + * + * a The base point. + * table Place to store generated point data. + * tmp Temporary data. + * heap Heap to use for allocation. + */ +static int sp_1024_gen_stripe_table_32(const sp_point_1024* a, + sp_table_entry_1024* table, sp_digit* tmp, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 td; + sp_point_1024 s1d; + sp_point_1024 s2d; +#endif + sp_point_1024* t; + sp_point_1024* s1 = NULL; + sp_point_1024* s2 = NULL; + int i; + int j; + int err; + + (void)heap; + + err = sp_1024_point_new_32(heap, td, t); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, s1d, s1); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, s2d, s2); + } + + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(t->x, a->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(t->y, a->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(t->z, a->z, p1024_mod); + } + if (err == MP_OKAY) { + t->infinity = 0; + sp_1024_proj_to_affine_32(t, tmp); + + XMEMCPY(s1->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + s1->infinity = 0; + XMEMCPY(s2->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + s2->infinity = 0; + + /* table[0] = {0, 0, infinity} */ + XMEMSET(&table[0], 0, sizeof(sp_table_entry_1024)); + /* table[1] = Affine version of 'a' in Montgomery form */ + XMEMCPY(table[1].x, t->x, sizeof(table->x)); + XMEMCPY(table[1].y, t->y, sizeof(table->y)); + + for (i=1; i<8; i++) { + sp_1024_proj_point_dbl_n_32(t, 128, tmp); + sp_1024_proj_to_affine_32(t, tmp); + XMEMCPY(table[1<x, sizeof(table->x)); + XMEMCPY(table[1<y, sizeof(table->y)); + } + + for (i=1; i<8; i++) { + XMEMCPY(s1->x, table[1<x)); + XMEMCPY(s1->y, table[1<y)); + for (j=(1<x, table[j-(1<x)); + XMEMCPY(s2->y, table[j-(1<y)); + sp_1024_proj_point_add_qz1_32(t, s1, s2, tmp); + sp_1024_proj_to_affine_32(t, tmp); + XMEMCPY(table[j].x, t->x, sizeof(table->x)); + XMEMCPY(table[j].y, t->y, sizeof(table->y)); + } + } + } + + sp_1024_point_free_32(s2, 0, heap); + sp_1024_point_free_32(s1, 0, heap); + sp_1024_point_free_32( t, 0, heap); + + return err; +} + +#endif /* FP_ECC || !WOLFSSL_SP_SMALL */ +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^128, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * table Pre-computed table. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_stripe_32(sp_point_1024* r, const sp_point_1024* g, + const sp_table_entry_1024* table, const sp_digit* k, int map, + int ct, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 rtd; + sp_point_1024 pd; + sp_digit td[2 * 32 * 5]; +#endif + sp_point_1024* rt; + sp_point_1024* p = NULL; + sp_digit* t; + int i; + int j; + int y; + int x; + int err; + + (void)g; + /* Constant time used for cache attack resistance implementation. */ + (void)ct; + (void)heap; + + + err = sp_1024_point_new_32(heap, rtd, rt); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, pd, p); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 32 * 5, heap, + DYNAMIC_TYPE_ECC); + if (t == NULL) { + err = MEMORY_E; + } +#else + t = td; +#endif + + if (err == MP_OKAY) { + XMEMCPY(p->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + XMEMCPY(rt->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + + y = 0; + x = 127; + for (j=0; j<8; j++) { + y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 128; + } + XMEMCPY(rt->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(rt->y, table[y].y, sizeof(table[y].y)); + rt->infinity = !y; + for (i=126; i>=0; i--) { + y = 0; + x = i; + for (j=0; j<8; j++) { + y |= (int)(((k[x / 32] >> (x % 32)) & 1) << j); + x += 128; + } + + sp_1024_proj_point_dbl_32(rt, rt, t); + XMEMCPY(p->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(p->y, table[y].y, sizeof(table[y].y)); + p->infinity = !y; + sp_1024_proj_point_add_qz1_32(rt, rt, p, t); + } + + if (map != 0) { + sp_1024_map_32(r, rt, t); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_1024)); + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (t != NULL) { + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_32(p, 0, heap); + sp_1024_point_free_32(rt, 0, heap); + + return err; +} + +#ifdef FP_ECC +#ifndef FP_ENTRIES + #define FP_ENTRIES 16 +#endif + +/* Cache entry - holds precomputation tables for a point. */ +typedef struct sp_cache_1024_t { + /* X ordinate of point that table was generated from. */ + sp_digit x[32]; + /* Y ordinate of point that table was generated from. */ + sp_digit y[32]; + /* Precomputation table for point. */ + sp_table_entry_1024 table[256]; + /* Count of entries in table. */ + uint32_t cnt; + /* Point and table set in entry. */ + int set; +} sp_cache_1024_t; + +/* Cache of tables. */ +static THREAD_LS_T sp_cache_1024_t sp_cache_1024[FP_ENTRIES]; +/* Index of last entry in cache. */ +static THREAD_LS_T int sp_cache_1024_last = -1; +/* Cache has been initialized. */ +static THREAD_LS_T int sp_cache_1024_inited = 0; + +#ifndef HAVE_THREAD_LS + static volatile int initCacheMutex_1024 = 0; + static wolfSSL_Mutex sp_cache_1024_lock; +#endif + +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ +static void sp_ecc_get_cache_1024(const sp_point_1024* g, sp_cache_1024_t** cache) +{ + int i; + int j; + uint32_t least; + + if (sp_cache_1024_inited == 0) { + for (i=0; ix, sp_cache_1024[i].x) & + sp_1024_cmp_equal_32(g->y, sp_cache_1024[i].y)) { + sp_cache_1024[i].cnt++; + break; + } + } + + /* No match. */ + if (i == FP_ENTRIES) { + /* Find empty entry. */ + i = (sp_cache_1024_last + 1) % FP_ENTRIES; + for (; i != sp_cache_1024_last; i=(i+1)%FP_ENTRIES) { + if (!sp_cache_1024[i].set) { + break; + } + } + + /* Evict least used. */ + if (i == sp_cache_1024_last) { + least = sp_cache_1024[0].cnt; + for (j=1; jx, sizeof(sp_cache_1024[i].x)); + XMEMCPY(sp_cache_1024[i].y, g->y, sizeof(sp_cache_1024[i].y)); + sp_cache_1024[i].set = 1; + sp_cache_1024[i].cnt = 1; + } + + *cache = &sp_cache_1024[i]; + sp_cache_1024_last = i; +} +#endif /* FP_ECC */ + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * r Resulting point. + * g Point to multiply. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_32(sp_point_1024* r, const sp_point_1024* g, const sp_digit* k, + int map, int ct, void* heap) +{ +#ifndef FP_ECC + return sp_1024_ecc_mulmod_fast_32(r, g, k, map, ct, heap); +#else + sp_digit tmp[2 * 32 * 5]; + sp_cache_1024_t* cache; + int err = MP_OKAY; + +#ifndef HAVE_THREAD_LS + if (initCacheMutex_1024 == 0) { + wc_InitMutex(&sp_cache_1024_lock); + initCacheMutex_1024 = 1; + } + if (wc_LockMutex(&sp_cache_1024_lock) != 0) + err = BAD_MUTEX_E; +#endif /* HAVE_THREAD_LS */ + + if (err == MP_OKAY) { + sp_ecc_get_cache_1024(g, &cache); + if (cache->cnt == 2) + sp_1024_gen_stripe_table_32(g, cache->table, tmp, heap); + +#ifndef HAVE_THREAD_LS + wc_UnLockMutex(&sp_cache_1024_lock); +#endif /* HAVE_THREAD_LS */ + + if (cache->cnt < 2) { + err = sp_1024_ecc_mulmod_fast_32(r, g, k, map, ct, heap); + } + else { + err = sp_1024_ecc_mulmod_stripe_32(r, g, cache->table, k, + map, ct, heap); + } + } + + return err; +#endif +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * p Point to multiply. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_1024(const mp_int* km, const ecc_point* gm, ecc_point* r, + int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_digit kd[32]; +#endif + sp_point_1024* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_32(heap, p, point); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 32, km); + sp_1024_point_from_ecc_point_32(point, gm); + + err = sp_1024_ecc_mulmod_32(point, point, k, map, 1, heap); + } + if (err == MP_OKAY) { + err = sp_1024_point_to_ecc_point_32(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_32(point, 0, heap); + + return err; +} + +#ifdef WOLFSSL_SP_SMALL +/* Striping precomputation table. + * 4 points combined into a table of 16 points. + * Distance of 256 between points. + */ +static const sp_table_entry_1024 p1024_table[16] = { + /* 0 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 */ + { { 0xe0162bc2,0xbf9c7ec6,0x10a89289,0xddecc6e3,0x9e499d81,0x5d599df0, + 0x6d358218,0x9a96ea28,0x70c5f8db,0x01aec7d3,0x8cf5d066,0xe72e4995, + 0x3e91d7f8,0xc2e7297d,0xda9f2f5a,0x8621db92,0x5a5679ed,0x4b26c867, + 0x2c56aac1,0x233385df,0xc6a13f99,0xb88e74d4,0xffa8ec11,0x1214b173, + 0x1f3f9fef,0xa0386a27,0xc0e7b44e,0xbd9b1b4e,0xeecd3496,0xafe528dc, + 0x1c49f80b,0x8dfff96a }, + { 0xc03c0c83,0xb4a4753a,0xabcdcd75,0x68e69d18,0xf775b649,0xe3839b88, + 0xbf58f352,0x803f949a,0xbd0bc15c,0x5f702679,0x8ff298c2,0x85bf5d16, + 0xc6c7976e,0x3f6ebd98,0x45e3e1b4,0x20618af4,0x54e64093,0x67d5598e, + 0x504fed9e,0xb047283b,0x70d87517,0x450cabfd,0x3f5addbe,0x47d628bf, + 0x78cb4cca,0x0037ef30,0x6b1c4908,0x4e148d3c,0x4fcfd837,0xe256d329, + 0xde3c01f3,0x2aa1207b } }, + /* 2 */ + { { 0x755c2a27,0xcf3e0bb2,0x59585c44,0xd38e42f9,0x19285e60,0x46b13e0f, + 0x76273d0f,0xc3ecd0c0,0x193c569a,0x7800f085,0x4351818a,0xf04e74ab, + 0x8496363b,0x9258aa38,0xb8c894fe,0x8456617c,0x2af969a0,0x8bc62aaa, + 0x5a4668d9,0x66c2280b,0xa992f4fa,0xbc9df58e,0x3f401e99,0x5db0b7d9, + 0xc4c38c0e,0xe0614fe1,0x2ccdf6b3,0xd531151c,0xe143b618,0x1c7575ec, + 0xdf9398a4,0x40247985 }, + { 0x8f055746,0xfba25178,0x0ab1e6e0,0xc5ba0040,0xac292697,0xe1b194fb, + 0x5b4f4740,0x77152119,0x9bb7ba54,0x250091d0,0xb9a139a4,0x7a674861, + 0xf353aa7e,0xba8413b3,0x2443ceee,0xafe77192,0x3847bbd0,0x14468d36, + 0x3da4942d,0x61f79ff6,0xd425b456,0x1563a1c1,0x75ff4630,0x3c270fcd, + 0xeb2802c9,0x42072090,0xc85c7004,0x68f0cdcb,0xfa032e74,0xca4372fb, + 0xc8b79d80,0x1a6fd1e6 } }, + /* 3 */ + { { 0x8d5116a3,0x967a901a,0xb2f5f47f,0x0b844394,0x60ebaf3b,0xe39ad452, + 0x60ccfc0c,0x1e1be617,0xcc3f53f2,0xac07e3d2,0x1ed11bb6,0xdd838e0e, + 0x1c15b0c2,0x45475307,0x920fe5b8,0x70dd4748,0xe471896d,0x1a20be2d, + 0x59276c7c,0x3c3fad8a,0xc886ee07,0x026a1cc3,0x6e831ac4,0x9fdb6f37, + 0xac501d65,0x26a35d1a,0x40da8574,0x0ae98905,0xabd734e5,0x65dde0a4, + 0x15614750,0x29b7d4dc }, + { 0xcbf4e20b,0x44b3c2cb,0x58cc44c5,0x1c3f548f,0x5b0cac1f,0x39809b54, + 0x00f80621,0x0c0f02b5,0x066905e0,0xe612b890,0x8350188c,0x8f158ed7, + 0x3f5576b2,0xc01dc458,0xa45492e0,0x29803272,0x0ff92443,0x77a5623a, + 0x29d0dc41,0xd12a2b00,0x2780e87a,0xb4125459,0x0d53f272,0x1ebcf903, + 0x24301e8d,0xbae6ea40,0xa37d0798,0x1e5f3f2f,0x22b4126c,0x9342c310, + 0x5382497e,0x5d092802 } }, + /* 4 */ + { { 0x4b59213a,0xf5b495d0,0x8d70200e,0xca672039,0x2b6771c1,0x4bcb09a6, + 0x2b9eb0cb,0x26adeed4,0x8cdba212,0xeb544754,0xf08890d1,0x0e1abfcd, + 0x698e46b4,0x52509963,0x82e9c138,0xe1bff0b0,0x51099a71,0xa189e4cd, + 0xc9b91cc7,0x2360c9bc,0x137ec4be,0x9bd4d7dc,0xd1519f6e,0xd0356521, + 0xcf832503,0xbf5f6d78,0x8deea2b4,0xe4301031,0xef4c319c,0xc3132494, + 0x0f1fa7d7,0x2ab3bd47 }, + { 0x922c9fbb,0x5753b680,0x0f16c6d1,0x869e7dc8,0xbac16efc,0x83445135, + 0x846d1d9b,0x4326a3b4,0xb2d62c21,0xb517fee3,0x0b292ad5,0x6905afa2, + 0x2cadac13,0x2a57131a,0xebdbca8d,0xcd904d8f,0x3f365fb2,0xdfeda86f, + 0xdc7eaa1c,0x7097b208,0xa45e77c0,0x89a35a84,0xcf5d118e,0x417a062c, + 0x1f6e99e8,0x3c0c04a8,0xba7a087d,0xc44704b0,0x3ea22ad2,0x6f8a27d1, + 0x4c27d229,0x93a4b416 } }, + /* 5 */ + { { 0x1f1efb7a,0xd4271bc1,0x33fccc0d,0xae4e68e6,0xb11f50a8,0x9d9bc8f1, + 0xaf076089,0x5430398f,0x443d0e03,0x45e242fb,0xf6e3d4c1,0x73ec2519, + 0xba9bad09,0xab70f790,0xf9add10f,0xde612ad5,0x14e942b4,0xb837e54e, + 0xddb8b68a,0x175a56d3,0x1ac2a408,0xe85b233c,0xf0c80f94,0xf8ff6c30, + 0x898db4f9,0x4b7f3fb7,0x45a7dcdd,0xa2c6044f,0xfe3d3895,0xf3abb2f6, + 0x32ee7763,0x342ce0d7 }, + { 0xcf491b1f,0xeb261394,0x1909e395,0xdcaaeed7,0x9fe4dbea,0xdcc4055a, + 0x493d604d,0x17a6611d,0x1ce5ebef,0xba445a3a,0xe3989cb5,0xe82e2858, + 0x83f58406,0xb96f4282,0xa156cf55,0x99877b99,0x4e166a0e,0xaf906a66, + 0xb2976d13,0xcea1d353,0x36c61a01,0xefc16f27,0xb0f55d86,0xdb04c433, + 0x8eb34c01,0x3cb4b269,0x2ae60280,0x38d07f78,0x43be3ec5,0x43ac3bcb, + 0xe156fd20,0x455f4af3 } }, + /* 6 */ + { { 0x95532833,0x2e6fe0a6,0xd626d067,0xabca228e,0x649e73bd,0x22aef3d9, + 0xf03c4c0c,0x2083a87a,0x35169b45,0xe954e75d,0x74506a89,0x577509ee, + 0x2aeacf90,0x49cb276e,0xfa409f91,0x08275d77,0xf0bbd6b9,0x61eb6f3d, + 0xe4132704,0x948202cb,0xb1c498b1,0x35f3fc21,0x361fee59,0x76c68ba8, + 0x50e051f3,0xa18cbbd9,0x318e7042,0x2384a879,0x80dd1e8b,0x292abead, + 0x5c37c334,0x65713c29 }, + { 0xceb77b9a,0xdccca8e9,0x23b69469,0x2f97e727,0xa01d6b28,0xc76abee6, + 0x5abecdfe,0x3925203d,0x29290d70,0x89448082,0xb0314438,0xf9931424, + 0x7cd447c3,0x04209df1,0xc855c827,0x7c6f2059,0x56c0e069,0xd97d7862, + 0x412d94c4,0x5a9db6fe,0x994c41dd,0x19a64591,0xc89e21a3,0x12348aa1, + 0xc6a03f0e,0xd6904b50,0xa616feac,0x55c15156,0x7cc7693b,0x4e36d1b5, + 0x3bae3c38,0x6b0e996c } }, + /* 7 */ + { { 0xcceced00,0x32789fab,0xe5b7aa66,0x3237e71a,0x2ddebcdf,0x87b2e269, + 0xb61dad8f,0xb7245120,0xd35f803c,0xe11e5e48,0x98e50f0d,0xfb4df5d7, + 0xbcd2ab92,0x60ee68b4,0x1ce3363d,0x98ab2f5c,0x7cd42647,0x15ba39da, + 0x83f4fb3f,0x1a6572eb,0xe56f08db,0x0f77de88,0x172562c2,0x1743761e, + 0x8a58f0f4,0xbe349ff8,0x84d1d6e2,0xe04da71b,0x9e9ff3b4,0x368f0342, + 0x678223f8,0x4022a205 }, + { 0x83847375,0x527bbd05,0x3f451af0,0x3ae56b62,0x4b2c7f18,0x6198f24d, + 0x4525b98d,0xee323f5b,0x0e0884b5,0xa9d8d39a,0xfb12c776,0xd005d7f6, + 0x708bc154,0xd71c483e,0x742541bc,0x8ca6fd28,0xf8397ddb,0x0af3dccd, + 0x3eccf243,0xb80d3125,0x58d81b8d,0xc743a108,0x71391f68,0x3f48eb21, + 0x33bb657f,0x493aff88,0x07e47e31,0x1d15ed66,0xe08279f6,0x10159b11, + 0x24a6a956,0x312179cb } }, + /* 8 */ + { { 0xfb99cfe6,0x950323d3,0xc9334178,0x7b09bc26,0x7cbdfb6f,0x64111e41, + 0x89a75760,0x91141744,0x10919cb0,0x4c633df9,0x396bfd2f,0x715fc7c7, + 0x8cab62db,0x8ca19512,0x4db81aac,0x30672473,0xb4c4c54a,0xe67a246b, + 0xbf229646,0xd77ea0fa,0xfa5b5d70,0x5bed15f1,0xc2f192f3,0xa5686da5, + 0x7f6690ad,0xdecac72a,0xcaa50b7d,0x0c4af2a2,0x6049ad2f,0xf44631c1, + 0x04ecf056,0x325d2796 }, + { 0x4848c144,0xee11fb55,0xb6a7af32,0x4e062925,0x369e0f9a,0x125b68e1, + 0xca53b21e,0xad9bdae6,0x2e98ea1b,0xf50d605c,0x9f2fa395,0xbdb9e153, + 0xe91532f5,0x4570e32d,0x46a250d7,0x810698ae,0xad9d9145,0x7fd9546c, + 0x11e97a5e,0xabf67721,0x249f82e9,0xca29f7d5,0x9851df63,0xa9c539a9, + 0x71d0e3e5,0xfd84d54b,0x041d2b56,0xd1e0459c,0xfd80096a,0xceb3eb6e, + 0xe32a79d3,0x19d48546 } }, + /* 9 */ + { { 0xb540f5e5,0xfe19ee8f,0x04e68d17,0x86d2a52f,0xadbdc871,0xd2320db0, + 0xd03a7fc8,0xa83ad5a8,0x08bcb916,0x54bf83c7,0x2e51e840,0x092133ea, + 0xcb52dddf,0xbce38424,0x31063583,0xd5c7be40,0x458e3176,0xc1ebb9df, + 0xbc4dabbf,0xafb19639,0xc05725a8,0x36350fe4,0x84e1cd24,0xac4a0634, + 0xc145b8de,0xadf73154,0xb3483237,0x0aa6dd9e,0xcbff2720,0xa3345c3d, + 0xb4e453b0,0x1b3ace6c }, + { 0x90a8bdc5,0x0343e5e9,0x6306a089,0xa203bf9d,0x8e48520e,0x98489a35, + 0xde7d1d06,0xbd17debe,0x5f795d3f,0x8fafa6d7,0x387b0a3f,0xa4ceb630, + 0xffddeafa,0xe0166b32,0x7e764e02,0xa2fe2054,0xe871f304,0x55ab9824, + 0x952ec45e,0xa2bd36bb,0xa90d20ca,0x7b4c1484,0x75bcfb53,0x5319f387, + 0x6982c4e5,0x34238a4a,0xa102921d,0xa2bb61c7,0xdb3ab17e,0x1e061b64, + 0x192f0a14,0x538ec33e } }, + /* 10 */ + { { 0x576374c2,0xe53c7785,0x84727040,0xe60526d1,0x228ca044,0x8a066dc8, + 0xf1ce1313,0x1fe1c1b2,0xcdeb0c5d,0x2aeec832,0x9cbf826f,0xa7596699, + 0xde77a589,0xcd188e81,0x118d1254,0xe5ce0fe0,0x0790b86a,0xa142a984, + 0x39ac28ce,0xe28f043f,0x87de5804,0x4eef8290,0xf639a8c5,0x83c31b32, + 0x5887794f,0xd70454a7,0x18b1b391,0xca635d50,0x31d9c795,0xcefea076, + 0xb6f8aa25,0x13cbee76 }, + { 0x8d3f34f3,0x79cabe0f,0xa3617fe3,0xbda9c31c,0xdd9426a1,0xb26dee23, + 0xf29c9104,0xe9dd9627,0xe2c6cd3b,0x033eb169,0xfcba2196,0x8a73f492, + 0xb858c83c,0x92e37e0b,0x23b3fbb7,0xe4f2aca6,0x64be00a2,0x8101fb1e, + 0x948f6448,0x91a7826a,0x907260e7,0x414067b4,0xe30bb835,0xf774aa50, + 0xc999c06e,0xf922ca80,0x0ba08511,0x6b8635b9,0x25fa04f0,0xbf936b5c, + 0xe02e8967,0x4e0a1ada } }, + /* 11 */ + { { 0x8ba29c4d,0x00ca6670,0x22988094,0xc08240ce,0x16dda752,0x21c5ca67, + 0xabbbfa34,0x689c0e45,0x3ed28b72,0x1d7545fd,0xd7c56ab4,0x5f221198, + 0x38759d65,0x4b3d8f74,0x8fe50b89,0x93490dfb,0xe80eba16,0xb641f5d7, + 0x79acb537,0x7b0da5eb,0x0c1d5e5e,0xab6b1497,0xa5da429a,0x2338e68d, + 0x2f6d2f25,0xe010c437,0x6530f3a7,0x226f16d2,0xcbef08bc,0xefb0f7b6, + 0x9f99c999,0x733e30d9 }, + { 0xa42a38f9,0xecfe1582,0x4730b500,0xaec2d58e,0xde976b2c,0x2ee2f2a7, + 0xa969c1bb,0xf0539db5,0xfcecdb4a,0x31954168,0xe7a8e902,0xf2f7348a, + 0x3121541f,0x1d58d7cc,0x2202ae52,0x5d25b75c,0xf40835a7,0xdea9965a, + 0x529b4e46,0x3feb6a41,0xbd27ad9b,0x5c97fb6f,0x261f900b,0xd87554c0, + 0x04d5b19e,0xb43031d9,0xcb219b9c,0x33d5e9b8,0x3ee00bcf,0x7a43d492, + 0xb79a5c0c,0x56facb39 } }, + /* 12 */ + { { 0x7c834915,0x667eaed6,0xbc5eb64d,0x9f77aa6a,0x25d62011,0x729ebcb6, + 0x699fd9c2,0x0aee24f2,0x2b8d4f6c,0xe1eb5874,0x14c976d6,0x7f12710c, + 0xf6d9ea65,0x91390335,0x06b50064,0x668b7049,0x0876ee4f,0x65969a0e, + 0x2f9d9360,0xf901bf3f,0xb499e3ce,0xfb1a8651,0xf2dbcaaa,0x80b953fb, + 0x973b06b6,0x312cc566,0x3af36c64,0x3534d9c3,0x10ffd815,0xe4463a52, + 0xf18c2b91,0x57ea2b4b }, + { 0x8aa0f2f2,0x00f5e162,0x0e46bcaa,0x8c7e75c5,0xa4a2c42d,0x97ab479a, + 0x14baa202,0xb4f308ea,0x6943cc2e,0xa901bd14,0xeed58804,0xbb125fee, + 0x9d180f7c,0x6502c8f9,0x1580c61c,0xe5353919,0x27101ee3,0x7e278069, + 0xfaa72717,0x7a0a40a1,0x4c75b153,0x32edce02,0x538f1c22,0xda23660b, + 0xbe307d2e,0x4d511e98,0x9baee0b4,0x24276e40,0x7ff1f307,0xa78c3927, + 0xea7935c9,0x60480b46 } }, + /* 13 */ + { { 0x3872ece3,0x31087d66,0x955b70f8,0x5f29be7d,0x9cf95bb8,0xb50b4fc7, + 0xdbffa621,0xbae3b58d,0xe022ba5d,0x0e61d280,0x4181449c,0x78ae5117, + 0xcf555485,0x0b132840,0xb8ce0b0e,0x800ed1b6,0x78d5de3d,0x35dffdd5, + 0x69a56b47,0xf7e42374,0x8d910ae7,0xd5e32369,0x6313c7c7,0xb6ff52a0, + 0xa92de9e5,0x5a2fe20d,0xd12110bb,0x41b347d3,0x40c16f23,0xc5905edb, + 0x9a8f88cc,0x0774a0d3 }, + { 0xe3b6c106,0x3ae181ab,0x8de150b7,0x4ebe163f,0x6f354836,0xcf75b82f, + 0x3ac7ac16,0xaa0d2063,0x291722af,0x5c680668,0x11545553,0x73941e61, + 0xbf5de3f7,0x17127e38,0x1afb41da,0x32cfdf03,0x87bc8663,0xc6893c91, + 0xa62c9c99,0x75046744,0x962c1947,0x96866e2d,0x378cdf4c,0x489ec8df, + 0x3407fa32,0x3a60709b,0x551290d1,0xd37d2159,0xbab92273,0x9623d303, + 0x2432014b,0x08151954 } }, + /* 14 */ + { { 0xb05f2b26,0x569044f3,0x80b9f76c,0xb35a294a,0x4290f6ae,0x8839fe28, + 0x026a5877,0x761cfb23,0x2e5ff9c3,0x768926b6,0x0b11c576,0xbae6cd20, + 0x72a03efe,0xdc857756,0xe1bad63a,0x0cae074a,0xd709d99c,0x3fe491a1, + 0x6501d9c1,0x76c5ded6,0xc32aeff7,0x1da6eca1,0xc57683e8,0x50849d55, + 0xdf98d847,0x9e392e9c,0x64d9a564,0xfad7982f,0xa37b98b2,0xf7c3bdb7, + 0xf0860497,0x1fe09f94 }, + { 0x7648cc63,0x49a7eaae,0x67cfa714,0x13ea2511,0x653f4559,0xfc8b923c, + 0x81a16e86,0xd957619b,0x3c864674,0x0c7e804b,0x1616599a,0xfc88134a, + 0x0a652328,0x366ea969,0x4bc9029e,0x41532960,0xae2aad2b,0xef9e1994, + 0x7f10bef5,0x9e2a8c52,0xc67bf860,0x73dcb586,0x844cc25d,0xf61a43fa, + 0x74eb3653,0xd74e7eea,0xdd240f02,0xf3356706,0xfd83bcb4,0xeec7694c, + 0xdb62526a,0x4de95786 } }, + /* 15 */ + { { 0x3deac2f7,0x4867d315,0xb61d9a8e,0xa084778a,0x0ab7b2d5,0xf3b76f96, + 0xcfdf4f79,0x00b30056,0x31ab8f4b,0xd0701e15,0x9c779d01,0x07f948d5, + 0x82675371,0x7c994ebc,0x48bad4c0,0x1104d4ee,0xbfc9d058,0x798ce0b5, + 0x309fa80b,0xc7ca898d,0xacb33eaf,0x0244f225,0x5b2f3175,0xd51e8dfc, + 0xa4d7be34,0x3e49ba6b,0xbda02b43,0x1760f4c7,0x4435275a,0x37e36a7e, + 0xe636980c,0x1c94418b }, + { 0x09dc1414,0x43a21313,0x43c93537,0x060765fc,0xdf5f79ce,0x6ff3207a, + 0x85d4cfca,0x6f18b1fa,0x63e995ab,0xf5c4272e,0xa82b3002,0x121a09e4, + 0x97147f16,0x82b65d1b,0x20a7fe26,0x4993c20c,0xe6716726,0x99c9cb98, + 0xfeb440a0,0x5a02d673,0x251b4bc5,0x3f3fa9e1,0xa05338ea,0x75dbc474, + 0x7b09f6cb,0x3cb4044b,0x80434609,0x6767da18,0x098ceac2,0x97851422, + 0xb55235ba,0x611bfbb2 } }, +}; + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^256, ... + * Pre-generated: products of all combinations of above. + * 4 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_base_32(sp_point_1024* r, const sp_digit* k, + int map, int ct, void* heap) +{ + return sp_1024_ecc_mulmod_stripe_32(r, &p1024_base, p1024_table, + k, map, ct, heap); +} + +#else +/* Striping precomputation table. + * 8 points combined into a table of 256 points. + * Distance of 128 between points. + */ +static const sp_table_entry_1024 p1024_table[256] = { + /* 0 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 */ + { { 0xe0162bc2,0xbf9c7ec6,0x10a89289,0xddecc6e3,0x9e499d81,0x5d599df0, + 0x6d358218,0x9a96ea28,0x70c5f8db,0x01aec7d3,0x8cf5d066,0xe72e4995, + 0x3e91d7f8,0xc2e7297d,0xda9f2f5a,0x8621db92,0x5a5679ed,0x4b26c867, + 0x2c56aac1,0x233385df,0xc6a13f99,0xb88e74d4,0xffa8ec11,0x1214b173, + 0x1f3f9fef,0xa0386a27,0xc0e7b44e,0xbd9b1b4e,0xeecd3496,0xafe528dc, + 0x1c49f80b,0x8dfff96a }, + { 0xc03c0c83,0xb4a4753a,0xabcdcd75,0x68e69d18,0xf775b649,0xe3839b88, + 0xbf58f352,0x803f949a,0xbd0bc15c,0x5f702679,0x8ff298c2,0x85bf5d16, + 0xc6c7976e,0x3f6ebd98,0x45e3e1b4,0x20618af4,0x54e64093,0x67d5598e, + 0x504fed9e,0xb047283b,0x70d87517,0x450cabfd,0x3f5addbe,0x47d628bf, + 0x78cb4cca,0x0037ef30,0x6b1c4908,0x4e148d3c,0x4fcfd837,0xe256d329, + 0xde3c01f3,0x2aa1207b } }, + /* 2 */ + { { 0x01900955,0xa95b6dae,0xceb4656d,0xa5dc9cc1,0xe72fe95b,0x50c78907, + 0xa040c334,0xa1ae5447,0x7952ea6e,0x91191370,0x6d097305,0x54ff7343, + 0xbda4d10f,0xa4db0074,0x91644070,0xfd5306f1,0x8b24522c,0x14b9fe73, + 0x7849f762,0x1468dad6,0xb0dcd2e4,0x87b29a18,0x5e1ad492,0xadd7f1a1, + 0xdbba2a1a,0x9ac63a81,0x81223379,0x01379c5b,0xb0e53bc8,0xf402b2f0, + 0x0bf13b61,0x8c3eb27f }, + { 0xe513696f,0x9a4ad3e1,0x18c81ffa,0x0350ba5c,0x3c033d13,0x1e2fc136, + 0x17a531bc,0x53da6e71,0x1aed610d,0x42ec6490,0xe99ff567,0xd33e8df7, + 0x3deed12a,0xe4aad73e,0x180f4deb,0xd983b465,0x502f30b4,0x99365269, + 0xa8918d7f,0x7e2799ab,0x700fc79a,0x0ffe84b6,0x40bfd8c2,0x7b4400d6, + 0x5d2641bd,0xc3a21d21,0xc32621cb,0x79839442,0xb1401e83,0xace6500b, + 0x251c4310,0x7bf4163e } }, + /* 3 */ + { { 0xe3fd589e,0x1c174f88,0xdf974a03,0xdb501790,0x3e70549f,0xd09623e3, + 0x15924f34,0x8d091eff,0xf9b65ac5,0xeef79cad,0x3f69c2cf,0xd2cc4262, + 0x52cd82bc,0x817d9032,0xa5f1dddd,0xacf4f4d9,0x5011b6bd,0xd0612635, + 0x2ed140c9,0x9f74490d,0x4db686d2,0x64092e8c,0x776b0fcc,0x225eef16, + 0xdf16aeb6,0x0e8c01e9,0x84bbd82a,0x62836741,0x8956e337,0x757574e2, + 0x705a7f07,0x9871edc6 }, + { 0x776535f7,0xbd0b76d5,0x2635b3b8,0x5214d602,0x9d216f64,0xc0c25ad9, + 0x5515bf75,0xfd4df3a7,0x5e9f1675,0x24a625bc,0x406873e7,0x3c35efb7, + 0xbb2e5c4a,0xef5c9a33,0x806b198a,0xa971b35e,0xa3c690ed,0x9f5c0ca5, + 0x8e1e2341,0xa8d5dd89,0x955ad9e4,0x4cecbcce,0x248d3416,0x2ecf4407, + 0x45c0af6e,0x1abb3811,0x1c780fff,0x3f4bee82,0xc272ed57,0xd14df768, + 0x371637ad,0x397ed10a } }, + /* 4 */ + { { 0x755c2a27,0xcf3e0bb2,0x59585c44,0xd38e42f9,0x19285e60,0x46b13e0f, + 0x76273d0f,0xc3ecd0c0,0x193c569a,0x7800f085,0x4351818a,0xf04e74ab, + 0x8496363b,0x9258aa38,0xb8c894fe,0x8456617c,0x2af969a0,0x8bc62aaa, + 0x5a4668d9,0x66c2280b,0xa992f4fa,0xbc9df58e,0x3f401e99,0x5db0b7d9, + 0xc4c38c0e,0xe0614fe1,0x2ccdf6b3,0xd531151c,0xe143b618,0x1c7575ec, + 0xdf9398a4,0x40247985 }, + { 0x8f055746,0xfba25178,0x0ab1e6e0,0xc5ba0040,0xac292697,0xe1b194fb, + 0x5b4f4740,0x77152119,0x9bb7ba54,0x250091d0,0xb9a139a4,0x7a674861, + 0xf353aa7e,0xba8413b3,0x2443ceee,0xafe77192,0x3847bbd0,0x14468d36, + 0x3da4942d,0x61f79ff6,0xd425b456,0x1563a1c1,0x75ff4630,0x3c270fcd, + 0xeb2802c9,0x42072090,0xc85c7004,0x68f0cdcb,0xfa032e74,0xca4372fb, + 0xc8b79d80,0x1a6fd1e6 } }, + /* 5 */ + { { 0x8d5116a3,0x967a901a,0xb2f5f47f,0x0b844394,0x60ebaf3b,0xe39ad452, + 0x60ccfc0c,0x1e1be617,0xcc3f53f2,0xac07e3d2,0x1ed11bb6,0xdd838e0e, + 0x1c15b0c2,0x45475307,0x920fe5b8,0x70dd4748,0xe471896d,0x1a20be2d, + 0x59276c7c,0x3c3fad8a,0xc886ee07,0x026a1cc3,0x6e831ac4,0x9fdb6f37, + 0xac501d65,0x26a35d1a,0x40da8574,0x0ae98905,0xabd734e5,0x65dde0a4, + 0x15614750,0x29b7d4dc }, + { 0xcbf4e20b,0x44b3c2cb,0x58cc44c5,0x1c3f548f,0x5b0cac1f,0x39809b54, + 0x00f80621,0x0c0f02b5,0x066905e0,0xe612b890,0x8350188c,0x8f158ed7, + 0x3f5576b2,0xc01dc458,0xa45492e0,0x29803272,0x0ff92443,0x77a5623a, + 0x29d0dc41,0xd12a2b00,0x2780e87a,0xb4125459,0x0d53f272,0x1ebcf903, + 0x24301e8d,0xbae6ea40,0xa37d0798,0x1e5f3f2f,0x22b4126c,0x9342c310, + 0x5382497e,0x5d092802 } }, + /* 6 */ + { { 0xff2f780d,0x583a2b7e,0xd7d76b1d,0x34d26820,0x86f74aec,0xe3c32847, + 0x10823feb,0x0fd42212,0xfb5e7bf4,0x227e417e,0xa568f8cd,0x510d49b6, + 0x1781bbec,0x53bce7d6,0x2f3718b7,0x9cfe3f22,0xd9de6c1f,0x7f44e89f, + 0x3fac9b55,0xf1cc553f,0xe6f300bc,0x9d2d0846,0x9f0ae6b1,0x976c82a2, + 0x24b8bbe0,0xe63dbf5e,0x973a5aa7,0x4cac7f45,0x84dd33c7,0xc6eb6237, + 0x142fee5d,0x0a26e434 }, + { 0xacaa9a08,0x8081339f,0x5246ece1,0x40f31105,0x61393747,0x892c8170, + 0x242f02e1,0x8d8d4103,0x3b5de98a,0x482bfd20,0x5abbe952,0x89ef946b, + 0x37698249,0xb8d218b9,0x66617c7a,0xd5268e89,0x8b7d2b91,0x962e7551, + 0xfe8d67c3,0x2c5c7973,0x2b017c51,0x42e3150a,0xc1a29469,0x6f4e5ebc, + 0x531c7083,0xa39910ce,0xb77b9e50,0xaf4f6eb4,0xda120ad0,0x68cbb175, + 0xb92636ec,0x19497c61 } }, + /* 7 */ + { { 0x417659a8,0x6920b0c6,0x92cb28ff,0xc77ab9c7,0xb687797f,0x55b67180, + 0xe7759363,0x4caf58c1,0x5561b186,0x5155bdb6,0x780f4946,0x2e64e355, + 0x229a8b20,0xeb0ac9b7,0x2571bd60,0x88594d78,0xe3fa78f9,0x5dcc0939, + 0x2ac2d379,0x7b8b4830,0xb90f1444,0x505fbf60,0x3ce4b3c1,0xac610e81, + 0xd59b5c18,0x39a4f27a,0x7cea0222,0x5fa33973,0x8dff1c7b,0xe578730b, + 0x517bf7a6,0x96b91b8b }, + { 0x9aac087c,0xc1a991f4,0x6cfdb28d,0xce62f74e,0x5f7600d6,0x08d6ff9a, + 0xf917f9c9,0xd781cd04,0x3de52dbf,0x7796f5f6,0x2ed72180,0xe7db64e0, + 0x6fa4137d,0x0f0876f6,0x3ca1f716,0x3271ee64,0x7c4ab8a3,0xcb9b2058, + 0x39481047,0xcba17107,0x598c5c37,0xdf9a190d,0x6f20e125,0x0cb6e72a, + 0xf4f2902d,0xa3142204,0x7ce2dcfb,0x42d28cb9,0xa3d3c351,0xdf261b8a, + 0xcffc249d,0x73f3d315 } }, + /* 8 */ + { { 0xe6fd3673,0x5d86855b,0x9d214b7b,0x309b70af,0xdcc46cd3,0x8d332f90, + 0x595510de,0xe553c015,0x38c1251c,0x5746a096,0x85cc1bc9,0xcd7cea5b, + 0x002eba8f,0x4ffa1468,0x22fcd77c,0x10a3cb70,0xc4ea05e3,0xb6999dfb, + 0x4efa756e,0x3375a0d0,0xdced5fd8,0x4d90279e,0x251fd56e,0x48192403, + 0x82a4c5f1,0xe87633a4,0x1b34105b,0x3170d130,0x7247e578,0x93998b0f, + 0x436ba1fa,0x88934f64 }, + { 0x4713eabc,0xf09f43b0,0xaccdc517,0x4ca7dd91,0xef13ca7c,0x27daa63b, + 0x2588184b,0x8b2e5a7a,0xd95dc269,0x0a8cb612,0xe1f2f14c,0x346975a2, + 0xe172935c,0x1f29b8ed,0xd40bc1e3,0xc3cbfd6e,0x132623da,0xd3f46b3f, + 0xfb0b7681,0xc115be6d,0x56da4344,0x5e31c345,0xa8e43d98,0xa7c63f18, + 0x4bddb4ea,0x55cb2083,0x4a54f58c,0xb16a0c38,0x46fd69d9,0x74eacca2, + 0x153548e1,0x0d1898bb } }, + /* 9 */ + { { 0xe35ef043,0x4ea73461,0x3496b564,0x107b67d9,0xd0f83a3c,0xd62c173b, + 0x51d29c35,0xfad4b038,0x71b1c1a4,0x3f42882a,0x54b43b9e,0x5d2bcf66, + 0x2abdf543,0xc77b15aa,0xdabe3dc1,0x5cb38a80,0xa481673b,0x15fda0ae, + 0xe7b90ebe,0x86996b4d,0x2bc8f3d8,0x84f87e25,0x37c4e424,0xaded03d6, + 0xd7a7afd8,0xe5ede666,0xa1ccb93a,0x80dd95a2,0x46fba391,0xa55cfd25, + 0x46f82e60,0x2bdab1dc }, + { 0xfa6fed61,0x7a4de22b,0xcc8dd94e,0xca458aa5,0x071222f5,0x3e372df1, + 0xe5aff377,0x06a4b44f,0x4a738e6d,0xbc2d0ba7,0x5f31f136,0x1a470e1d, + 0xe102a911,0x77ff933a,0x310c7885,0x8b380a50,0x783fc5ac,0x9f3c0228, + 0x44725d06,0xec668925,0x5ac84221,0x878f0e16,0xcfda6e8a,0x9a3af1af, + 0x78cd2aba,0x0183ed37,0x826d0eae,0x32cdbd60,0xcbee6415,0xb3234661, + 0xb9c10120,0x353eb892 } }, + /* 10 */ + { { 0x10b5521e,0xc8fdcad6,0x52e702f0,0x1a11b440,0x8ffda49c,0x6302680d, + 0xcbf36bad,0xcdb9654a,0x4c10a2d7,0x7b58ce11,0xe630e7e0,0x1e5d1f7d, + 0x6760a813,0x8cbe3d7d,0x6480d77f,0xeb35866b,0x7f036219,0x58728cf3, + 0x42a8a757,0xdd5865ed,0x906a2870,0x283f1f1d,0xa51f906b,0x79e23fa4, + 0x543b20a8,0xf2ac6e83,0xb81e7754,0x4f0b6379,0x840016ee,0x57fbc0d4, + 0xe621b67d,0x8da20771 }, + { 0xecce65ec,0x3c855004,0xb748185e,0x76d10d1f,0x78797ad2,0x64be7bca, + 0x77e54aad,0x43444db0,0xbe0df0ff,0x17b6b0c9,0x055086a4,0x8fc4256c, + 0xfd74d5a3,0xf952c43b,0x01c4edb8,0x501e005a,0x4a57e328,0xd5172dfc, + 0x535d6ee3,0xdb40ce4e,0x0c650918,0xbaef1e5c,0x857561fc,0xe85145e7, + 0x34a224c6,0xe468536a,0x0ec0e0a2,0x69a8e227,0x242b03fc,0xb3f52247, + 0xc3bebd5f,0x862f55e2 } }, + /* 11 */ + { { 0x226049fe,0x2d6a390f,0xdcbbc9fb,0xcc92a578,0x97634fb7,0xa52feca4, + 0x3dea5893,0x2b340cb6,0x2a49e916,0xa39f338a,0x949e41f3,0x26b2df3d, + 0x065a7e40,0xc71c7cdb,0x468281a2,0x4a9b84a0,0x731eeeca,0x63eeb503, + 0x76cbb725,0xe6d09134,0xb94a678c,0x0cf979a9,0x808fd9f1,0xb44d8c3b, + 0xe0afc5b9,0xe60da613,0x3ea5be69,0x52dce7de,0xdc1ee74f,0x3a5d6864, + 0x3bc80790,0x71ab2891 }, + { 0x3b5b60ad,0xcf618fc4,0x4a0c3184,0x0afb5e30,0xbc403302,0xd22381cc, + 0xdb1c0c66,0x33cf8953,0xa6112a8d,0x9c994e4d,0xd1967a86,0xd7aae2c3, + 0x5b7acd29,0xc28d5493,0x6c9a57fb,0x8075bd13,0x9c8427f9,0xc9c0373e, + 0x193225f5,0x2cbca18d,0x442c018c,0x73777d13,0xfbb3a727,0xebe5ed47, + 0x1962dc18,0x70437d49,0x2dc08806,0xf39c1e09,0x15fff35c,0x03e9c6f7, + 0x5e360a65,0x8d087bb6 } }, + /* 12 */ + { { 0x3fdc1844,0xbe212302,0x105eac56,0x6eca27ef,0xf168a348,0x2183a606, + 0xe1d7a4cb,0x295f807d,0x7ef5d43e,0x7246a632,0xc77025c7,0xae143205, + 0xf3484e3e,0x4bdfc7ca,0xdf52c075,0xec939895,0xd7a9cac0,0x82e655f6, + 0x8baeddb0,0x985dfe20,0x527de731,0x79c817e4,0x313de1ea,0x30ce0fbc, + 0xcc4f6cbb,0x9df95b89,0xf5bb20cd,0xf2aedf1e,0x1a8cfb01,0xfc1e0a89, + 0x63edb7ec,0x225ed34a }, + { 0xbabb1a85,0x3e13154d,0x1e6a565a,0xd3d8dae7,0xab4b100f,0xd3217d56, + 0xebc78e1a,0xd44d934e,0x48e73d37,0x0215321b,0x201e43cb,0xbbc90bfa, + 0x27500905,0x3c23f1d0,0xc86691a1,0x2a2e5000,0x6065841c,0x08b2bad2, + 0x30026b60,0x15d41caf,0x5276ce61,0x1712c2f4,0x15932ffb,0x01c4c3e7, + 0x6a74caf2,0x7894e13d,0x0c0537a4,0x02d6f5df,0xc2b1c97e,0xa8fb7602, + 0xd0887c7b,0x612b60e5 } }, + /* 13 */ + { { 0xba245d6b,0xefd495cf,0xa2ce3ff6,0x5cf0cbb7,0xdff5feee,0x24da2ac0, + 0xcf28c6a3,0x90c914f8,0x4308a56b,0x72fdb50d,0x13d72034,0x03dbf779, + 0x822ac9e9,0xcfa5ec91,0x3aea3e81,0x0dde73c8,0x66289139,0x545ba962, + 0xca6acbd3,0xa52f648b,0x98a0683a,0xff6f276e,0xa378ed52,0x2536d3ac, + 0x885ac1d9,0x353c2c54,0x00bc84a7,0xcaff52da,0x37684167,0x3971f81c, + 0xd2d7986e,0x0f7334e1 }, + { 0x6596067e,0xafbb5c83,0x38c19806,0x33e54e19,0x39cb0dcc,0x8285d967, + 0x424035f9,0x2b53f43d,0xdfef9095,0x38c531f8,0xdb0f571a,0x90fbe8e4, + 0xa39ca787,0x9a0c1ed2,0x606f2620,0x2fecc1d6,0x72b7cb4a,0x9dc890b1, + 0xccbb7868,0xc33ca6fb,0xfe73ee49,0xd1b11082,0xfcb66c48,0x590b7d17, + 0x86e14573,0x9356b0a6,0x053ead85,0x75d682c4,0xc54d30fb,0xb2ae55fa, + 0xf8aee949,0x67636a72 } }, + /* 14 */ + { { 0xb91d6bea,0x638063bc,0x923ecb96,0xae263a2e,0xc627aca6,0x9d7b0992, + 0x77af9e7e,0xc6ed001a,0x24aafebb,0x9214accf,0x78055a90,0xa3564b96, + 0xe027499d,0x00999b1c,0xe46a06a5,0xe413a4e1,0x2e51efe7,0xa05d13f6, + 0x9ba843be,0x35e87d34,0x3183159e,0x0a633825,0x54601923,0x6023e8ba, + 0xb7fd1cf2,0x9b107721,0xfdf2fd53,0x46b5542b,0x1c18af38,0xb314f4f8, + 0x60ac8965,0x086f9876 }, + { 0x8cbb9850,0x76701954,0xa20d2c8c,0x6210b730,0x5335670c,0x4084d057, + 0x0324baea,0x3ecdc595,0xc76ee9b4,0x607fc5f2,0x440ffa64,0xf393d00f, + 0x2dc1463c,0xe0111796,0x9c7725e7,0xf00b8251,0x5bd1d186,0x35e60736, + 0x2cf72aac,0xf3d8554c,0xefa3497d,0xb4dd0fde,0xf646ad11,0xd712268c, + 0x9f7b8ead,0x07c20afb,0xfc06dfe5,0x630969d4,0x7245549a,0x76b7df1c, + 0xe61ae810,0x681f9403 } }, + /* 15 */ + { { 0xc9a0623b,0x7cad5163,0x67fab8d4,0xdbf82957,0x81af7c7c,0x2ccab0ec, + 0xe966d5c2,0x469e38c8,0xf0d4e41c,0x34430d52,0xa52b359c,0x426075a2, + 0x33bd0127,0x242dd3e3,0x9fed2341,0xcda3f635,0xd7d52ffa,0x4df33730, + 0x7640c3ef,0x5fff56f0,0x1bbde57c,0x4783c21c,0xeb8bb336,0xd8784a2a, + 0xead08405,0x1ec7c533,0xf9b62bd4,0x4b7f1423,0x7075d4af,0x5543145c, + 0xba60590a,0x0c9de94a }, + { 0x95d5682b,0x8ed72735,0x2ec276ed,0x711c4283,0x8b36a0d2,0xd1f4aed5, + 0x8498a88f,0x62ab40c4,0x4480f451,0x58c8fc62,0xb79cffe2,0x8bc8ca4b, + 0x701a359d,0x90ab583c,0x3fd5d15d,0xaee31a73,0xc912333c,0x02a5597b, + 0xb6c3e3c2,0x1019cae4,0x29938088,0xe513042c,0xf47c8199,0x0e00283d, + 0xf2a00e92,0x90d68e58,0xa775ae3b,0x69e2df41,0x871c30b2,0xb8d2eca5, + 0xbb1de396,0x733dca0e } }, + /* 16 */ + { { 0x4b59213a,0xf5b495d0,0x8d70200e,0xca672039,0x2b6771c1,0x4bcb09a6, + 0x2b9eb0cb,0x26adeed4,0x8cdba212,0xeb544754,0xf08890d1,0x0e1abfcd, + 0x698e46b4,0x52509963,0x82e9c138,0xe1bff0b0,0x51099a71,0xa189e4cd, + 0xc9b91cc7,0x2360c9bc,0x137ec4be,0x9bd4d7dc,0xd1519f6e,0xd0356521, + 0xcf832503,0xbf5f6d78,0x8deea2b4,0xe4301031,0xef4c319c,0xc3132494, + 0x0f1fa7d7,0x2ab3bd47 }, + { 0x922c9fbb,0x5753b680,0x0f16c6d1,0x869e7dc8,0xbac16efc,0x83445135, + 0x846d1d9b,0x4326a3b4,0xb2d62c21,0xb517fee3,0x0b292ad5,0x6905afa2, + 0x2cadac13,0x2a57131a,0xebdbca8d,0xcd904d8f,0x3f365fb2,0xdfeda86f, + 0xdc7eaa1c,0x7097b208,0xa45e77c0,0x89a35a84,0xcf5d118e,0x417a062c, + 0x1f6e99e8,0x3c0c04a8,0xba7a087d,0xc44704b0,0x3ea22ad2,0x6f8a27d1, + 0x4c27d229,0x93a4b416 } }, + /* 17 */ + { { 0x1f1efb7a,0xd4271bc1,0x33fccc0d,0xae4e68e6,0xb11f50a8,0x9d9bc8f1, + 0xaf076089,0x5430398f,0x443d0e03,0x45e242fb,0xf6e3d4c1,0x73ec2519, + 0xba9bad09,0xab70f790,0xf9add10f,0xde612ad5,0x14e942b4,0xb837e54e, + 0xddb8b68a,0x175a56d3,0x1ac2a408,0xe85b233c,0xf0c80f94,0xf8ff6c30, + 0x898db4f9,0x4b7f3fb7,0x45a7dcdd,0xa2c6044f,0xfe3d3895,0xf3abb2f6, + 0x32ee7763,0x342ce0d7 }, + { 0xcf491b1f,0xeb261394,0x1909e395,0xdcaaeed7,0x9fe4dbea,0xdcc4055a, + 0x493d604d,0x17a6611d,0x1ce5ebef,0xba445a3a,0xe3989cb5,0xe82e2858, + 0x83f58406,0xb96f4282,0xa156cf55,0x99877b99,0x4e166a0e,0xaf906a66, + 0xb2976d13,0xcea1d353,0x36c61a01,0xefc16f27,0xb0f55d86,0xdb04c433, + 0x8eb34c01,0x3cb4b269,0x2ae60280,0x38d07f78,0x43be3ec5,0x43ac3bcb, + 0xe156fd20,0x455f4af3 } }, + /* 18 */ + { { 0x754ec21c,0xc057f262,0xe3a1ba38,0x3eacd4c9,0x116c1fe9,0x3a0210d1, + 0xeacc8ab6,0xe4ea4e94,0xea6f32ca,0x31c00c9a,0x86b975ce,0x5cb6239d, + 0xa14ea1e9,0x654d5d8c,0x5067fc8b,0x230d31f4,0x6355fecb,0x48bb90cb, + 0xdc172e8e,0x78f81ece,0xcb006737,0x288380a8,0xe162d012,0x19b02e01, + 0xc5af145c,0x0e087a06,0xb72dc354,0xf04dc8b7,0x8de3c066,0xf70ef214, + 0x13009fb7,0x4f148243 }, + { 0x6e2055e2,0x5e004fce,0x86c32067,0x89e247ea,0x5f9daaa2,0x4ebcbd95, + 0xceb7f63b,0xd15f212f,0x863784a0,0x5ecc5c1f,0x75760251,0x53b3800b, + 0x8a6a2954,0xeb9301c3,0xa13cdd19,0x0f16ba18,0x887c2d24,0x8313d251, + 0x9a9413f6,0xf9923585,0xfe3fd7c5,0x423405e6,0x16e0ee05,0x678aeb34, + 0x3fadaab0,0x1f3be7bb,0x82884471,0x7901fa2c,0x4d662ff6,0xc950db30, + 0x3c01170b,0x74d5d2d4 } }, + /* 19 */ + { { 0x2b5bfe11,0xa3002dc0,0x52d321e7,0x0733410d,0x9679ba89,0x15920f65, + 0x685b236e,0x0e248c14,0x346f6040,0x8cfab594,0x40c717f0,0x9f57afb7, + 0x66044576,0x0dbab28c,0x9cdc3247,0x0fa09968,0xc230ed05,0x41e02ae2, + 0xe45bef74,0x0d961554,0xce4d7b6f,0x9688a982,0x5e62d22e,0xfadefac7, + 0xbd2cba28,0xaf1512a6,0xbe7c749f,0x78868e62,0xae9f5a6b,0x88048d81, + 0xc5857a29,0x6b1a5442 }, + { 0x43242066,0x9f5ab9ad,0x2ccca2ae,0x0afef1b5,0x988edc4e,0xb1b43ec7, + 0x0341b0d5,0x0d0c00f1,0xb50aab37,0x4d68b8f7,0xf3a64a99,0x9a8e4e6f, + 0x7f1a684e,0x198338fb,0x351a0f5c,0x8bc0e748,0xdac44515,0x2cacf2cd, + 0x5e9ff76b,0xc14d3999,0x16393055,0x54a01b3f,0x888d8376,0x6ac3eea5, + 0x723277b1,0xb84d9a9a,0xe11dbbbf,0x99132691,0xabb67178,0x597717ae, + 0x8bb14ac8,0x4c213526 } }, + /* 20 */ + { { 0x95532833,0x2e6fe0a6,0xd626d067,0xabca228e,0x649e73bd,0x22aef3d9, + 0xf03c4c0c,0x2083a87a,0x35169b45,0xe954e75d,0x74506a89,0x577509ee, + 0x2aeacf90,0x49cb276e,0xfa409f91,0x08275d77,0xf0bbd6b9,0x61eb6f3d, + 0xe4132704,0x948202cb,0xb1c498b1,0x35f3fc21,0x361fee59,0x76c68ba8, + 0x50e051f3,0xa18cbbd9,0x318e7042,0x2384a879,0x80dd1e8b,0x292abead, + 0x5c37c334,0x65713c29 }, + { 0xceb77b9a,0xdccca8e9,0x23b69469,0x2f97e727,0xa01d6b28,0xc76abee6, + 0x5abecdfe,0x3925203d,0x29290d70,0x89448082,0xb0314438,0xf9931424, + 0x7cd447c3,0x04209df1,0xc855c827,0x7c6f2059,0x56c0e069,0xd97d7862, + 0x412d94c4,0x5a9db6fe,0x994c41dd,0x19a64591,0xc89e21a3,0x12348aa1, + 0xc6a03f0e,0xd6904b50,0xa616feac,0x55c15156,0x7cc7693b,0x4e36d1b5, + 0x3bae3c38,0x6b0e996c } }, + /* 21 */ + { { 0xcceced00,0x32789fab,0xe5b7aa66,0x3237e71a,0x2ddebcdf,0x87b2e269, + 0xb61dad8f,0xb7245120,0xd35f803c,0xe11e5e48,0x98e50f0d,0xfb4df5d7, + 0xbcd2ab92,0x60ee68b4,0x1ce3363d,0x98ab2f5c,0x7cd42647,0x15ba39da, + 0x83f4fb3f,0x1a6572eb,0xe56f08db,0x0f77de88,0x172562c2,0x1743761e, + 0x8a58f0f4,0xbe349ff8,0x84d1d6e2,0xe04da71b,0x9e9ff3b4,0x368f0342, + 0x678223f8,0x4022a205 }, + { 0x83847375,0x527bbd05,0x3f451af0,0x3ae56b62,0x4b2c7f18,0x6198f24d, + 0x4525b98d,0xee323f5b,0x0e0884b5,0xa9d8d39a,0xfb12c776,0xd005d7f6, + 0x708bc154,0xd71c483e,0x742541bc,0x8ca6fd28,0xf8397ddb,0x0af3dccd, + 0x3eccf243,0xb80d3125,0x58d81b8d,0xc743a108,0x71391f68,0x3f48eb21, + 0x33bb657f,0x493aff88,0x07e47e31,0x1d15ed66,0xe08279f6,0x10159b11, + 0x24a6a956,0x312179cb } }, + /* 22 */ + { { 0x07615ac2,0xa94cc3ca,0x121ad581,0x85865e64,0xa7986b79,0xae47616f, + 0x9d5e0f1d,0x395a40eb,0x3d9457ea,0xa9143264,0xfa2865d9,0x8de6d6a3, + 0x1014ae8c,0x0771db96,0x976a87cb,0x77a7cce6,0x143a0f60,0xa7de42e1, + 0xd993d934,0xe203cc09,0x98ec4c3d,0x92018693,0x3a25df4b,0xd77546d8, + 0x62b02d6b,0x0ad9eb47,0xd05a7189,0xfaaaf208,0x431221bb,0x5238181f, + 0x733511ea,0x417d6c78 }, + { 0x0e91e9a8,0x3cbd81b7,0xc370d6b3,0x73340418,0x8eaa2373,0x825db10a, + 0x6c7d6756,0x8f2b09e4,0x94c33ded,0xe288ee9b,0x1695e3fb,0xcd8426bb, + 0xdce9e888,0xa6176c86,0x6165e362,0x3f4c8922,0x6063fb09,0x514e411f, + 0xc8f9e04c,0x6907ac20,0xdfd2ad61,0xcef7469c,0x8452199a,0xba30bae4, + 0x12ac3462,0x30681293,0xc92d482d,0x011be873,0xe8330995,0xff4cbf89, + 0xd1470a0a,0x02189d52 } }, + /* 23 */ + { { 0x92599c69,0x73e419dd,0x7fec32ca,0x5b94221b,0x09bbfbfd,0xb2bf9bd2, + 0x63ed895b,0x61ea97a4,0x3f486f79,0x6609146b,0xfd141a39,0xbd1c7a05, + 0x83d64135,0xc79ec8cf,0x9883507b,0x7f8fd42f,0x17b3d027,0xafcb53b7, + 0x67ca5a21,0x86658dcd,0xcd149786,0xa6a6c0ac,0x34b95067,0x16f3d70e, + 0xdf44958c,0x371208e3,0xec280212,0xd2dd64e6,0x30782c71,0x33b2c4ab, + 0x521176fa,0x7bbf8abd }, + { 0xa78b981a,0xbe9e4aaf,0x304ec828,0x788b4e36,0x3959dea3,0x0c45cf39, + 0x240b39c7,0x70a9bdd3,0x28383b7d,0x499cd7dd,0x307a1026,0x30690b2e, + 0xee92f1b3,0x2262d598,0xb4725a48,0xc62d77de,0x7bc3aa0e,0xa16f25bc, + 0xd15ef7fa,0x62dd8b65,0x0b96d68f,0xd979221d,0xa00f1906,0xb92885c3, + 0xeb74c740,0xfa476b9b,0xc7576222,0x217ddbb5,0x5788504f,0xc2782c30, + 0xf812716b,0x860d096c } }, + /* 24 */ + { { 0x4d79bbf9,0xfebc337d,0x69f74f80,0x5d53eab8,0x33104d53,0xff36a095, + 0x196f8b97,0x2ab820da,0x75ce6909,0x961d3d1f,0x04683754,0xb197ec04, + 0x93a6cb9b,0xa68ce1bf,0xc5f021a3,0x503456ff,0x8940ffdb,0xb50a2db1, + 0xef004209,0x77c50f8f,0x04965875,0xd635d177,0x8bb8770a,0x725766d9, + 0xa078e53e,0x8e19b028,0xf9fc8378,0x364d4cca,0xf0dd39a0,0x1a3df411, + 0x03adf920,0x7e80e442 }, + { 0x539a1ddf,0x4b5f8a57,0xee486562,0xd248e7ae,0x816021e1,0x1c7b491d, + 0xfd36d2c4,0x2e7b871b,0x0aec00d9,0xda38b504,0x6193f1b3,0xf2827612, + 0xfb1f78d6,0x69c3fe86,0xe827ac33,0x56c8b786,0x3487c8f7,0x1687f6c7, + 0x19dee5bc,0xab8f2217,0xff399418,0x04e8473f,0xa9027c80,0xf384c014, + 0xaa1d2e28,0x9967be9a,0xe065eef1,0x869686d3,0xc7bd837c,0x737c6b08, + 0x9e8bd863,0x5dcab5d1 } }, + /* 25 */ + { { 0x9a7d772b,0x0784283a,0xe540959b,0x6b49e525,0x86414ab5,0x546bb008, + 0x9d74b2a9,0xd4448162,0x203b0b1b,0x267890ad,0xc8d3f86b,0x1e7a82bc, + 0xd85a83c7,0x1352bfb5,0xfad07ccf,0xf29f16e3,0x41e0c43f,0xc02a63b8, + 0x6b379fef,0x904f22c5,0xb1244f26,0x19d8a653,0x3a28bdea,0x6635b6df, + 0xf6d455ce,0x18b68851,0x9cff3735,0x74ac2818,0x8b2cbdab,0xad40f9df, + 0xadc9d498,0x08cc2d9e }, + { 0xc170c84b,0x2e6a6866,0x5a49a484,0xbb989e8b,0xd04c8992,0x7b0e00e0, + 0x61b3a423,0x55ad3478,0xb0d01899,0x3c952450,0xe3100cb3,0xe3922155, + 0xf03276d0,0x19265b6e,0x76d42b53,0x0fe8595a,0xfc6353b6,0x0a96dee0, + 0x246f893e,0x761e0dc8,0xf0a74cba,0x4ec902be,0x3fdfad9b,0x61008684, + 0x4fdb6975,0x5d6a60e4,0x7ef7590a,0x3f53aac8,0x12870a37,0xd29e6be0, + 0x55aa55b0,0x991fadc1 } }, + /* 26 */ + { { 0xb4844ffe,0x82bc4b0f,0x60f8b871,0x73922714,0x4ce3f1f3,0x8ac000e2, + 0x163519ec,0xf0d548b4,0x88288b5f,0x7aaf842b,0x2bdc9a70,0x9e8b0c4c, + 0x4ba5fd67,0xa06d5152,0xf93cdec3,0xd0b1afa0,0xdf89f8f0,0x280955ba, + 0xeea32c92,0x86cbe92d,0x3fe05be4,0x0cae3f99,0xfa6919aa,0xf2607095, + 0x6e0f1b8b,0x0f54741e,0x30ecf988,0x2aed1f74,0x734991d7,0x9296f76b, + 0x259f0fe9,0x66cf8d28 }, + { 0x226f5868,0x9b01905b,0x16909e9e,0xc102e88c,0x4a37eb54,0x2bd08916, + 0xc9816323,0xf72253e8,0x86bac53c,0x37f84e9d,0xafeaaaf7,0x2e352454, + 0x2ca0046e,0x67c86f77,0x6663372e,0x86bce50e,0xb6950a04,0xf6a3a960, + 0xfc1aba93,0x61f994d7,0xc1326e6e,0x1957c12b,0x2e56b005,0x9b658fe4, + 0x8592740c,0x9cd297fc,0x177f26a5,0x7654ce9b,0xa79d2ebb,0xaaa699db, + 0x0ecb6448,0x5fca0c5a } }, + /* 27 */ + { { 0x569a6663,0xe26e25f3,0xe6aa4ca7,0x09597ee7,0x8d18b80c,0x25a4cda6, + 0x22926730,0x450602b5,0x07387209,0x9af5f650,0x26733a53,0xfeeedb34, + 0x86572951,0x0f5ce768,0x8398ae9a,0x872a360b,0x2b30f6c3,0x60347a80, + 0x1a162158,0xd2113b23,0xee6c6dec,0x6fd9cf92,0x5cbcf9e6,0x85f0a5a8, + 0x2ba3fe84,0xd7a5a6e4,0x51ecd727,0xaafe6720,0xa2081a10,0xe09c6bb2, + 0xb973b0b4,0x657acbf0 }, + { 0xc274c8d4,0x3130466f,0x30a994d1,0x42765176,0x7079435f,0x217258ca, + 0xeb897a06,0x44850406,0x561ee130,0xf38dfeee,0xaa1778bb,0x11f4facf, + 0xb9abb9e9,0x765c6617,0xd8f10932,0xb135499b,0xa73b9159,0xc0eb6337, + 0x6f7e8b6a,0xf2c1ccf1,0x187def53,0x5b32c03a,0x830b9c62,0x89ad1d49, + 0x2f10e538,0x1735eae3,0x9d5f55bc,0xb1cbd9c2,0xe539db0d,0x42428c47, + 0xc852b3bb,0x3d2da412 } }, + /* 28 */ + { { 0x871f2865,0x97702b6e,0x142920d6,0x56cb639f,0x45b58611,0x328522a0, + 0xf3b13812,0xf3943ad1,0x712206e8,0xe6c2200a,0xa34d59ea,0xc2890e5a, + 0xf6b7f759,0xab52fd40,0x180bf567,0xf522c8de,0xaccee396,0x181e97b2, + 0xc4ea5cbb,0xe0375819,0xab51d3ef,0x0d9985e8,0xbcb50fd8,0xe26c96ca, + 0x97e1c80d,0xfb9d6b13,0xf796357d,0x582b1814,0x07f4c7fb,0x89a78221, + 0xc0357e61,0x02aeef2d }, + { 0x2c7ec9be,0x2ba7926f,0x7258b201,0x292f307e,0xc6fa6b4a,0x74e62a10, + 0xe2bcc5ab,0x80c08549,0x7bb8c073,0xb4160db8,0x329f194d,0xd5ef0529, + 0x6dda4a9c,0x0eb8da14,0x15ea23d1,0x0b5d43d2,0xfc34bfae,0x6cebef02, + 0x848757a7,0xacd364d0,0x2d34cca3,0xc1401368,0x1d2d95e2,0x09ca6742, + 0x786eaa28,0xc3fd1d6e,0xa2965fec,0x9eb1136d,0xc0779203,0x48871baa, + 0x4b15aeb0,0x6b446c01 } }, + /* 29 */ + { { 0x25e8fe80,0xc819eb2e,0x98238a17,0x2b5f7906,0x81e41849,0xd6f1e996, + 0x98ea6d45,0x58ad8ad6,0xbfd02e40,0x5bae5ad4,0xa812416d,0x016dc327, + 0xa3347ca1,0x8b31a985,0x82a65391,0x0b4da610,0xb48c35fb,0x1cb91b2d, + 0xd2aaf8c4,0x9e96817c,0xcdfdcdc0,0x1a630483,0x12b69254,0x70559361, + 0xf8a2a097,0x5fdcd712,0x35cc5281,0x59ab623a,0x932b6095,0x30c8ebe0, + 0xb08e052f,0x8613424b }, + { 0xb2231d8a,0x28902063,0xd9a61667,0xb0f62329,0x071a9f27,0xaafa0fe7, + 0x603f047e,0x6bcd8960,0xfd92a1c3,0x118cca76,0x71d483b6,0x3414e62b, + 0xba705262,0xa123ccdd,0xfd9b5c5a,0x1a576437,0x4c8d0fa3,0xa5301bc2, + 0x102427cd,0x96f0ad44,0xd3aa6c02,0x0e6fb5e0,0x072a3996,0xcd8c4880, + 0x840d3fad,0x4dafca12,0xde91d541,0x29f4ca3d,0x8441734d,0x0037c598, + 0x9ccfe57c,0x86333a99 } }, + /* 30 */ + { { 0xecf53b40,0xd213a751,0x2f78a542,0xcff2c6f2,0xf13ae56d,0x0f59f0e2, + 0x0e61748e,0x91f8ccbf,0xd72c4145,0x0aadecb9,0x4c9cdcb7,0x6b2ed852, + 0x1eaffc70,0x8e00b72c,0xaa728102,0x89b24285,0xb679cafa,0xaa7ea7e0, + 0x4f0a6f6f,0x5d2b8c26,0x0e804397,0x7ed7b173,0xc8573049,0x5a93eb45, + 0x0986e93e,0xc92bf5d4,0x6a20c0af,0x526b5a9c,0xb99dc3af,0x0adf47c9, + 0xba202cc9,0x12b25fe2 }, + { 0x33eea395,0x09b8d78a,0xf633fc5c,0xc7a93618,0x270eceef,0x7e821629, + 0xc628ed0c,0x524779b8,0xa1d68939,0x91db5ca1,0x586edc90,0x8626e18e, + 0xfeb3f3bf,0xfe023e8b,0x0250171c,0x6279fde1,0x55e172de,0xe52ec7dc, + 0xc6d4ca45,0x445e8695,0xbdbc10f1,0x42de3878,0x6fc3835e,0x2b114de8, + 0x7e10b652,0x9faba456,0x390e78fe,0x4111d82a,0xaedf0aca,0x576b61c2, + 0x74accb74,0x216279a9 } }, + /* 31 */ + { { 0x4047f747,0xc14cdabf,0xc1315a1e,0x03ca233d,0x40e5d0a7,0x59e7cbd3, + 0xbb413869,0x1fd0c4e9,0x0f01fbd8,0x189d08b1,0xa76b823d,0x50449c42, + 0x398b00a1,0x81c224a1,0x8e8179e4,0x08084e4f,0x698e41e9,0xfd8af994, + 0x5610bf2e,0x1e30e37c,0xa7d2790f,0x4e6a043f,0xb3195388,0x9d96e60c, + 0x03799dfd,0xe75f986d,0xf8ff902f,0x3b4a8f11,0x7588416e,0xfa945378, + 0x9827535e,0x20683e3f }, + { 0xd0378878,0xcb582e26,0xa7945787,0x9e214c23,0x8f6688b3,0x13d000bf, + 0x40515270,0x7548d4f5,0x40111f5d,0x7113c15d,0xa8bff902,0x3bf5a526, + 0x9b4945cc,0xbda6b010,0xbc2f3a05,0x83dcc74e,0x43efdfa1,0x2aef6284, + 0x565c5bf4,0xd2e60ee9,0x592f243a,0x4f0fa10d,0x1bc3bf51,0x6ae58b32, + 0x60576a74,0x813b0868,0x4d73081a,0x0bc023f8,0x32dcee59,0x9fd03aa0, + 0x27d6c795,0x5e416bf5 } }, + /* 32 */ + { { 0x026cc23c,0x24313760,0xb5b29058,0xf819aaee,0xc5d2ee17,0xa92272f8, + 0xee5cc402,0x8048e7cb,0x77def07d,0xdbc7d6ee,0xf6af821e,0x61d69244, + 0x996cbb89,0x5f7966ed,0x96a155a4,0xf81b17ea,0x03f3ed56,0xb2d9ef70, + 0xe882a5b2,0x5e6e5906,0xae947180,0x86fa1072,0x658c76f4,0x34d9fc51, + 0xcb035aa0,0x9f603dc0,0x75be6481,0xb7b39feb,0xcf04a9ef,0xca87554a, + 0x87b4fde3,0x4ff682ec }, + { 0xd0a10ad5,0x3125627f,0x968e6f45,0x7fd45c72,0x806a1163,0x2981bd6b, + 0xde5033e3,0xb92de1cd,0xbf4f8988,0x3b44b45e,0xdae7e1dc,0xca1b9896, + 0x0778d878,0x52166e5a,0xa5116847,0x82d472be,0xf2895445,0xfbdd382a, + 0x5d6ec4c9,0x22ed1602,0xb6552b02,0x3614eb1c,0xa1e6210f,0x63c5df73, + 0x021a74a7,0xe9160285,0xc65cbd4d,0xa44ca400,0x0f15e299,0x48cb187e, + 0x3402507c,0x51eb818e } }, + /* 33 */ + { { 0xb92100ab,0x1fc1d178,0x9605b839,0xdf2e3d60,0xb71e59d0,0x12a7c255, + 0x14fcbe04,0x3f8b6675,0x59fd06af,0x0e8a3935,0x12020d07,0x56326502, + 0x528e7be5,0x6696fcd1,0x0c7b7654,0x6588514b,0x5912a5b5,0x0cd80f8c, + 0xf324cb7f,0x8bafef04,0xc6da3d75,0x6b53eecf,0x31d1df2f,0xedef48d8, + 0x73812b6d,0xf336b965,0xee626031,0xc82eae4a,0xd244f09b,0x300abd32, + 0x31d9647f,0x8b0af955 }, + { 0x2e603544,0xb770180a,0x221acd9e,0x2b573ac3,0x62407032,0x3a17f665, + 0xb89abc3d,0xad3e74ad,0xd793225a,0x8a3d2e3a,0xef02564b,0x457bba04, + 0xfc2dd2b5,0x8875652f,0xe67143e8,0xd2905d15,0x02e48d70,0x6d884b42, + 0xc7636a57,0x06f99219,0x35e378df,0xa8dc3421,0x10c64a02,0x95c1d73d, + 0xcc157a66,0xcd6a4ece,0x8e24a354,0xbadcc1c8,0x9839329d,0x8024f1b2, + 0x4da48ad0,0x5363e549 } }, + /* 34 */ + { { 0xe23fc641,0x1f5523b7,0x86667063,0xfe54e72f,0x8e009d2f,0x294a15f5, + 0x8c57f5e1,0xf203997f,0xb16d64dc,0xa229724c,0x4baa2ffb,0x697be4fd, + 0x0a6e8ed6,0x3f507e46,0x78508536,0x0afe3a5d,0x95408208,0xeeef6cdd, + 0xf2c4237c,0x701fd889,0x5c385253,0x496d883a,0x72a212f1,0xe25c67ed, + 0x1ff78fcd,0x4b416783,0xc16f4146,0xe9967004,0xc45b0697,0xfa45c3a1, + 0x3fbd30c3,0x63334018 }, + { 0xa2fbbbce,0x39c9a0cc,0xaa0cb744,0x876f6e5c,0x3438ece3,0x9ce6010e, + 0x13802d82,0x0aad148e,0x9cd45a1b,0x9c3e5c60,0x7bcfc1e0,0x875cb859, + 0xd8584dd0,0xb19ff790,0xd81c2a2b,0x2598b81e,0x02be07e3,0x118bdf2f, + 0xb9765ce9,0x074fc8ee,0xb24f95ae,0x125e9d88,0x0c98f09d,0x3bb12cdc, + 0xa0b74b27,0x4a6aee07,0xc08077ce,0x4723d2f9,0xbea8026f,0x959447d6, + 0x16280b73,0x93a7075c } }, + /* 35 */ + { { 0x715b27f9,0x26bbefe2,0x2a280923,0xa935a5e2,0xfd58a26a,0x5ddf23af, + 0x7c138694,0x54c83e16,0x892a2153,0x44799bc9,0x9b8d09f5,0x4e6e4710, + 0xd588ea68,0xc63af616,0x883ab1b6,0x5e896706,0x3d209336,0x3c1393a0, + 0x92c23dda,0xd02f2921,0xdcf6ea43,0xab70cb7a,0x791559e1,0x12434ea8, + 0x6d70ff0b,0x040680db,0x2832ba45,0x1a10fe52,0xe5f0cb8f,0xd69f9c08, + 0x44b141fd,0x1a7422ac }, + { 0x9f40b675,0xc3a9dd2e,0xfcc71f39,0x2a7c6603,0x1948e342,0x18939a61, + 0xed0ab484,0x8f3b6158,0xee31ca6b,0xa3aa7d97,0xf7a8db63,0xbc1e865e, + 0x2c7c62e4,0x315f8c09,0x9f5c6d0f,0xa260788f,0x4b6f3ec5,0xb1833129, + 0x36b4d849,0x73adbcd6,0xbc699a9b,0x66e14890,0x2a1175e7,0xbf3790d8, + 0xfc53ca4f,0x7f43605a,0x87ff6091,0x577f6c47,0x600c82b6,0x827c7552, + 0x9d25599c,0x0944d630 } }, + /* 36 */ + { { 0xe6ab9620,0xcfdeb63e,0x786cd808,0xdff4fa6d,0x456320b3,0x145edd82, + 0xc4943915,0x2ae5f862,0xb73b3f87,0x9508e813,0xe52f97a9,0x3bd805f3, + 0xc9829b62,0xf71b5c28,0x86e0cefc,0xb394c70e,0x23bdb36e,0x534fb1a9, + 0xdbe27e5a,0xd64f5862,0x83ab6169,0xbae23df3,0x27c828cb,0xdd6df1b1, + 0x3a307a8a,0x1901899f,0x811ddf66,0x36cc8659,0x79943b77,0xa3cb7774, + 0x6fd86576,0x7d89f383 }, + { 0xc9f92b2b,0xf8564242,0xc46e32bd,0x700c6a75,0x7f99a5c5,0x93e768b7, + 0x03149568,0xb6efe858,0xc2ce6709,0xbbfe8a19,0xee6ec493,0x721a3b1b, + 0xc371c28d,0x26eeeea9,0x15177e1d,0xd798115e,0xb068a5a5,0xd7bf3bce, + 0x46d2b4b2,0xdf8da220,0x59be9dfc,0x3df0995b,0x77640b79,0xc96897bc, + 0x5a2bd3c5,0xce0cf4c2,0x89afe744,0x16f45d6e,0x3a8509bb,0xb53f3acb, + 0x63f2a6e6,0x449af81f } }, + /* 37 */ + { { 0xa16d9377,0xc2fcf132,0x7e1a2f9e,0x9ab377b3,0x86d19ae5,0x72e1a12e, + 0xd013bbb1,0xd2b12e66,0xcb5f66ba,0x0972e055,0x399eab50,0xd11de1c0, + 0xc65f5ec2,0xc1f314fd,0x8a9ff593,0xfc311841,0xe05246e6,0xdf73c1ec, + 0x1625056d,0xc28d1363,0x6fb25e19,0x30a9dbd7,0x845cd2d7,0x049ed244, + 0xd36e852d,0xc779b83f,0xf68c8a83,0x85a35fc7,0xc95e8033,0x299bf1e1, + 0x20891af5,0x0e8617c3 }, + { 0x67c81b5c,0x53720602,0xe737873c,0x2fa89dcd,0xa8144fd0,0x2a7430b0, + 0x26208c83,0x3006c5a7,0xd8ea40f5,0x4e066660,0x896413a4,0x9dd025f9, + 0x46b9149f,0xbdf380cc,0x0a125cc2,0x80156619,0x52793c37,0x04d6a3b7, + 0x6b7a62f2,0xb6001374,0x585d5978,0xa9cfe268,0x8395fe66,0xdcad0cb8, + 0x46b261f6,0xbab468fc,0x9d9d9218,0xca0ef5ef,0x5e452402,0xc507d4a8, + 0x326cf687,0x6f4404f1 } }, + /* 38 */ + { { 0x4febd3ff,0xa3e1920b,0xfdfd2bba,0xca6234d8,0xe19a9829,0xb7d1af2a, + 0xc6f5bc20,0x23de1610,0xdaa39ca9,0xe204dbf3,0x6d8c70ab,0x2a2de9b8, + 0x7c9d370b,0x272e0c37,0xe565510e,0x80914c06,0x57cbb6b0,0xb611e7a8, + 0xd8266a6e,0x076fc6ef,0x3095801c,0xdfac34ee,0xb9e24063,0x69ff40a2, + 0x787aa5c5,0xa7ba31a9,0x33c70cd2,0x0e4d1fdf,0x6895f074,0x903e3132, + 0x7fb671e2,0x905771f8 }, + { 0xa4062bee,0x5199ba0d,0x94d7d9f9,0x18e7238c,0x1e0922c0,0xf53f29bc, + 0xb12d855f,0xde9b2a81,0x6d68ca29,0x649f3eed,0xc50c097f,0x64adfc34, + 0x9db398a0,0x81964ab9,0x7a587224,0x00d59c47,0x74c5903a,0x09fea396, + 0x15043dd0,0x6aafd8ee,0x5f1ecc20,0xc5721a6e,0x0db9b7b4,0xb6d6a483, + 0x66c8d52a,0x06ffc617,0xacc82a27,0x3de241d6,0x27f2f7a8,0x0605f052, + 0x6404decc,0x6a22953b } }, + /* 39 */ + { { 0x74fce389,0x92452d8f,0x2afa5564,0x059634c0,0xf0ed7825,0x9377ccbb, + 0x37718e0d,0x89f4045b,0x9fa69a4d,0x11074e7d,0x7295b0ba,0x5d70bb07, + 0xf107ede6,0xb22d54ad,0xa1a29c7b,0x5c39a3d8,0xd795e3ab,0x37236c02, + 0x2b589951,0xf7282d00,0x5790bee2,0x5e2265be,0xa8e65ea2,0x91e0ea11, + 0x6001cebd,0x0e71a708,0x2c1c5402,0x16900f5a,0x357f6981,0xc3b2d5c0, + 0x619e3427,0x528c9ea0 }, + { 0x5f26c577,0x1edc86b4,0x9438bd45,0xf8074708,0x792582a7,0x2dfe1013, + 0xde1e569f,0xe08eaca0,0x9a55a356,0x5f952efa,0xe4976216,0xa4d80b53, + 0xcd5d71f2,0xd2b65855,0x66cea3f0,0x246704bf,0x492323ca,0x193f641f, + 0x9adb1325,0xa681855c,0x2d19d652,0x86d522ce,0x5b82ed7b,0x53609f10, + 0x8e150d29,0x3b0f0094,0x0b13e891,0x23ad8bfb,0xf794b449,0xcbb1556c, + 0x738bcf57,0x200f9093 } }, + /* 40 */ + { { 0x8388387f,0xf9b22fc5,0x28e883c5,0xcf26f170,0xd1b7973c,0x447cab90, + 0xf6ec9171,0x8d5d4ea2,0xc30cdbc0,0x2e16f498,0x48623c2b,0xdc92910c, + 0x30dbc545,0xeb1491b0,0x14de21b0,0x631deb2e,0x2fe830f4,0x04a21066, + 0x379c1f3f,0xa4c6979c,0xfb06a795,0x8a732b68,0x1619dfa9,0x3a44327a, + 0x8dbe2c9b,0x91a307d3,0x03989fea,0x939bc8d2,0x0f4a331f,0x3daabaf2, + 0xdd0f55dc,0x5c307e98 }, + { 0x35b233da,0xbbc4e0c4,0x22f6f985,0xe3d29085,0xa8b02468,0x99dd2d21, + 0xa96916e7,0x978f40e9,0x614bcced,0x0327d86c,0xb290762c,0x95e95502, + 0xa879f2ed,0x0ffd2197,0x50e0bd33,0xc4365137,0x0827c4c4,0x26c3148a, + 0x3fcfc0b2,0xc79812a8,0x31928589,0xc3d8d17e,0x8830f42d,0x8b572cfe, + 0x4b07f83f,0x7cd9ff92,0x0a51148f,0x331ca950,0x4c59f9ac,0xd0c53968, + 0xc1434785,0x1df16dfa } }, + /* 41 */ + { { 0x68bcacc3,0xcc7bb4ac,0x430f58cf,0x06ded34f,0xd461855a,0xc59f9f4f, + 0x45c9f0bc,0xf5491994,0x4375c892,0xdc5f7ec6,0x3c85983a,0x1b8708f1, + 0x82fcd087,0xb32a5cc4,0x2d6b4c0f,0xefdcdc35,0x8ac6fb2d,0x4bb24f04, + 0x33906471,0x5982d4f5,0xb83a3ac4,0x162eb52f,0x2337a223,0x7130df28, + 0xcbc3dbd3,0xdce7b802,0x2467ac0e,0x8b395959,0x1b56717e,0x21d3d2e8, + 0x46512617,0x729a7f50 }, + { 0x8420f90a,0x874ed1aa,0x0fe4c855,0x6368e19e,0xb0be74af,0xb62d4aaa, + 0x8ca60ca9,0x76fcc480,0x7645a867,0xf310b5a5,0xddb1b24c,0x131bac9b, + 0x2dea5b44,0xef77d71d,0x72fcc64e,0x4706d210,0x673d77f0,0x29b92691, + 0xe89e0663,0x22e00bf3,0x74077d40,0x472d0cd3,0x829232e2,0x3e21040d, + 0x38dc8533,0x2f916dfb,0x14b8f667,0x48bbb59b,0xd44be19d,0x19de9f4a, + 0x232d9d5c,0x7f6d3649 } }, + /* 42 */ + { { 0x6e794819,0x3bd064de,0xf82ebda1,0x5a6b694e,0xb91e2804,0x1f017fe0, + 0x07a43cd2,0x190d31f3,0x630433e9,0x6c26f226,0x0abfdcb4,0xba488aa7, + 0xa46411c0,0x418d9085,0xbffb5880,0x1b934fe6,0xe200f849,0x75d1e237, + 0xa55413db,0xdf04d63f,0xe23b3f77,0xe216ed75,0x0f91bd30,0xa05866cb, + 0x7729c509,0x84c395d9,0x452ab2d7,0xec97e188,0x0093d686,0x8cb7c1f9, + 0x628f086c,0x2d032395 }, + { 0x4a44b4c5,0xa81c9407,0xcc702c98,0xb9846879,0xceb0dc97,0xcb502287, + 0x6e3aa321,0x30301126,0xe4c256c2,0xc0ac8763,0xe55b4845,0x65034d20, + 0xf240f35b,0xaa96a040,0x7cf7eedc,0x046d26d3,0x3b810656,0x62a5a8e1, + 0x83d70c2b,0x86044b97,0x59e4da8f,0x2fbaff88,0x5457f5d1,0x929d901a, + 0xb531b757,0xd29e1eb2,0x9e4e9739,0x214dabdc,0x4eaa9bd9,0x5bd724fc, + 0x1ef9bb9b,0x734c12b3 } }, + /* 43 */ + { { 0x92f9b086,0x98fe3c2e,0xb3fd4544,0x4641b93e,0x5c02c65c,0x47ce208b, + 0xc4f03242,0x8a52dca1,0x679d29f6,0xb5ec17d9,0x9406f5f4,0x11d2fed0, + 0x0d9ba811,0x260f63dc,0x15472a3f,0xde2b056f,0x007290e6,0x1b170d9f, + 0xb6b5c8f9,0xa2e23e8d,0xcf34c3ee,0x345a2839,0x1b973ee2,0x9bdc5461, + 0xbb24d1c5,0x65bda6c2,0x3c6141a1,0x97d52ba3,0x9d2eb201,0x47bb1612, + 0x21fbe49f,0x7c558a87 }, + { 0x3f350fec,0xb9485a52,0x6a38d4c0,0x016678c5,0x0d5aa64d,0x8ef346a2, + 0xd96da2e4,0xb85daa02,0x4f647b3c,0x845ec4ea,0x0d5e946c,0xc0d1a6ca, + 0x4fa9f4ab,0x41d8d1c1,0x9c8b1303,0x43972cc5,0x434ffbfb,0x67e1f48d, + 0x819d2318,0x350ce93a,0x6ddef23f,0x49f53090,0x200cf12c,0x3c2e6cf9, + 0x640432fc,0x42691cc1,0x72496b52,0xbfff74b4,0x020a97be,0x44527c9f, + 0x7b3c4348,0x34cd7dca } }, + /* 44 */ + { { 0x59e7fe87,0xf031761a,0x0047cd72,0xb1eae31a,0xfae30f62,0x27902e68, + 0xb71db143,0xa666f48d,0x0e0038f4,0x75ee6678,0x02bdd76d,0x3b45ac67, + 0xa0d6cd5c,0x0d2fb828,0x9d8c5b11,0x27ce7f1d,0x120b5e96,0x141fe0e4, + 0xb9267c37,0x95a1b984,0xd60312cd,0x5206e589,0xda549356,0x1867342e, + 0x070c74ac,0x374520b9,0x9557b0b3,0x2703cbb5,0xa6ed8c14,0xf621f59c, + 0xabf7b887,0x7ceb1cc2 }, + { 0xdb7fd65b,0x0647a5bb,0x36c9457c,0xd8d45cc0,0x9e12718a,0xc6da99db, + 0xe93a7fb1,0xed1dbbf4,0xbd1566a1,0x4512c95c,0xdbc0c919,0x4861ba00, + 0x9e7f5269,0x3c6cc298,0x0941aaae,0x67196150,0xc8c538e3,0xbfcf5d0f, + 0xa25a551f,0xad6e9929,0x17ca0f26,0x90710985,0xfa89ef7e,0x743b78ea, + 0x71ab4549,0x39d5ea31,0xe6d1c36d,0x7442f3f3,0x059d568d,0x25a683e0, + 0x227ced5c,0x1f629a99 } }, + /* 45 */ + { { 0xe45a1c3e,0x8925ddac,0x41f7545f,0x72d29365,0x37e7f828,0x45622fcb, + 0x3e4c79d2,0x88234513,0x9c2645d6,0x5dffaf84,0x994802b9,0x3078f4dd, + 0x9d339fa0,0x566927f0,0x9fd91dcc,0x9a500a1e,0x0ab0abd7,0xce008180, + 0x8194e5df,0xd97135a3,0x98adf088,0x9e876307,0x9a45a2a7,0x3baf01b8, + 0x788b4399,0x6fed6154,0xe77a997d,0x980e5722,0x2a378eed,0xaac90ffa, + 0x8bd805a2,0x4a75fda2 }, + { 0x55e74cbc,0xd09a8fbb,0xfab18f25,0x737738ce,0x9764ec3a,0x0fc23ad6, + 0xe7e0ad31,0xc5a7d35b,0xe481cc9b,0xe75e068e,0x3d4aec34,0xf0c2ea99, + 0x0d4a63c4,0xf1324fe8,0x99b0592c,0x5dbb7c16,0xa7e0f46b,0x442d674d, + 0xa300faea,0x5a5d66c7,0x3333ac83,0xe83dc821,0x8c408496,0x70ef812e, + 0x99ef5fc1,0x96e1dcb6,0x1734e862,0x6e2b771b,0x583507d8,0x04629cdc, + 0x23d8179a,0x5819f9ae } }, + /* 46 */ + { { 0x6aa78811,0xd9969121,0x2103e7c3,0xf64ee8f4,0x22b9e698,0xddf01070, + 0x4f582cde,0xe6001f9e,0x2ecfac1a,0x24a608af,0x06393009,0x6ef4c784, + 0xebf72911,0x5262eae6,0x8c4ee5a0,0xddbd0af5,0xecd87bc7,0x875aff90, + 0x6f24f114,0x2fddb34c,0xe865f172,0x48104281,0x886c1b9a,0x95692426, + 0x9ef4231f,0x6f5f3208,0xd0a7e82e,0xaf587acf,0x9ac395c8,0xd6571917, + 0x1364a750,0x7459603c }, + { 0xf41ae519,0x1c2475bf,0x4af8f251,0x34401fb1,0xaefb2c3d,0x70ddfcd2, + 0x51cdaf08,0x9b2d385b,0x8208bb19,0x8531c256,0x4c33f3f6,0x16c89df6, + 0x24571769,0xc23cfa99,0x86d010ba,0x2339b51e,0x22638313,0x08db0e8d, + 0x00fedeb7,0xf769e179,0xa3687ef1,0x3fd96dcb,0x91476475,0xcd046b23, + 0x0c45c8dd,0xf3ff2064,0xb8343d78,0xefd167bd,0x4b77ee90,0x493ccb6d, + 0xb3cf7b45,0x33025513 } }, + /* 47 */ + { { 0x35eaaca1,0x36f00469,0x89119102,0x0c384b75,0xe6d2954c,0xcb375665, + 0xb1e9d6d7,0xcb9199b9,0xc29c2757,0x75852349,0xb8e738d0,0x89cbd1ba, + 0x5923a427,0x9b8dbe90,0x18fe1889,0xa237793e,0xa742e083,0xa4271757, + 0x4eebd613,0x8c4979d2,0xd4f2cf77,0x40325054,0x958705de,0xa3b8a091, + 0x33d999ba,0x1b191bd9,0x3b0fee1e,0xbafefba4,0x3facdf14,0xb3bad184, + 0x4387561c,0x9328adb0 }, + { 0xf906b872,0xabe84e80,0x78262665,0x705523a0,0x3398ccf7,0xd89c6a7e, + 0xf55b5323,0x2fab551d,0x0554dea8,0xa0578eca,0x375589cd,0xef26523d, + 0x864ad750,0xd8fd6242,0x178fe1fe,0x93f27fc5,0x9df87422,0x7b3e6f30, + 0x3750d054,0x2862e49e,0x5dc038a1,0x7d90c6b2,0x84db682b,0xc1a1ae22, + 0x9881930a,0x47f3dab7,0xbaf3e0a4,0x30e6bd52,0xf62d25c5,0x0680025b, + 0xadd0d5e7,0x0aa1f3cf } }, + /* 48 */ + { { 0x22a10453,0xa9822190,0x2a03a10b,0xdd1eb91c,0x96646f3b,0xafbb5d95, + 0xf38b6fc6,0xa58de344,0xb8cfca1d,0xce47c3e5,0x0f70da04,0xfcd8e16d, + 0xda262ed6,0xac44349b,0xc56e2f8e,0x9320d87b,0x19138e58,0x9ce3ea08, + 0xa2b236c0,0xa5862dff,0x8e7efb0d,0x6b0f9a5c,0x16ac78eb,0x4b53432b, + 0x709b51af,0x6ff43105,0x8f519628,0x08e236f8,0xeed403ad,0x1f93f176, + 0x9636545e,0x559337e0 }, + { 0xd8fd807a,0x30ddf738,0xab131222,0xf4e0ec9d,0x625afbc3,0x14a2f4db, + 0x9f12f895,0xd5b70604,0xac3044fd,0xb46f3c23,0xf540148f,0x1b232d1f, + 0x39b4e554,0x61b458f5,0x0dd70b75,0xf694b24a,0x289581d9,0x0fc64299, + 0xee5fe22d,0xc05d49be,0x6a18bf63,0x7af3447f,0x7f1929d6,0xe96a1dc2, + 0xc1551e8c,0x6afe6028,0x2b5d4fa2,0x27dacaf3,0x545c2cb4,0x4a1631bc, + 0xb0c914d3,0x930070f9 } }, + /* 49 */ + { { 0x69a9bc05,0xd2f32c5e,0x589c4b73,0x0a5c19c6,0x94665f9c,0x095c9e5e, + 0xbcfb4c39,0x8ab0f293,0x1ddb7c31,0xb9070877,0x66b38048,0x894e9658, + 0x606bd9bd,0xf19a90cf,0xb6fd2d69,0xcc1d58df,0x461d8a69,0x886dcc4e, + 0xf9ce4831,0xc455c277,0x765f8a82,0x749a5996,0xc3badc8d,0x2ffc668c, + 0x9112cdab,0x38018396,0xb243c7cb,0xa98795c3,0x010a2224,0x8775f310, + 0x587b5e14,0x043a2141 }, + { 0x3a873752,0x7bbe9dbc,0x2f442fee,0xee1493f4,0xc18c2181,0x981ca2c8, + 0xe29769e7,0x00ce3090,0xde768c5f,0xb4626ac8,0x34d7677e,0x33e9ce46, + 0xe0fa94e6,0xf89c2cad,0x41f5b5bf,0x04f5cc11,0x2228c12c,0x2565f736, + 0x0c05cce5,0xf1bf706a,0xbe487c4f,0x5d07ffff,0xa499f1a4,0x3ec43c09, + 0x98d94800,0x4f4e79bb,0x073f12f8,0x8a335a16,0x0f970d6d,0x4bb5eaf7, + 0xf24d0ae8,0x18d0747b } }, + /* 50 */ + { { 0x84601faf,0x58d3c77c,0xaf1c1f72,0xc9465be2,0xd116d806,0xff626798, + 0xd5b0d93c,0x3996c0c6,0x5ec6723a,0x2fa1ad75,0x03ba5349,0x966a8144, + 0x2ac34d8a,0xdc4c9422,0xed675865,0xddf471de,0x953d528f,0xd8aca597, + 0x24ebf67d,0xb2e463b5,0x7e25b4d3,0x25824871,0x43159daa,0x23c5adba, + 0x83357540,0x5458f9c6,0xf938b1a6,0xcf685da7,0xcefed231,0x981a4fda, + 0x08bb5e59,0x711093ed }, + { 0x401f161a,0x12aa3fc6,0x974c5e87,0xf7358560,0x17b5df82,0x4aa252fb, + 0xa48e6299,0xb0b82b07,0x29dd847d,0x00234157,0x4529c5a6,0xf1e54d00, + 0x6d98f538,0xcc1c539e,0x28d3abcb,0x36162b53,0x2a84f0cd,0x75a37938, + 0x4dee7484,0xf717a81b,0x4c23bf1b,0x16cf35fb,0x787e8b3e,0x7fd1c29f, + 0x59b79ab0,0xb7da7e68,0x85f6c60b,0x072100a0,0xe7ed48b5,0x31840159, + 0x4d9c97d4,0x17898bda } }, + /* 51 */ + { { 0xae1b8cf8,0xcd8483d8,0xe9a28856,0x323d4b42,0x204a4bc2,0x7633584f, + 0xca7a69fa,0x4e0b2228,0xf757bab2,0x8afbda8b,0x6cc5f9ca,0x85b24088, + 0xd41a95c3,0x47fb4813,0xc2aabe6b,0x3f1bc53c,0x1ad1599d,0xf22cda3f, + 0xc31ea9b1,0x1b2ec081,0x01614ac1,0x048f304b,0xc6afa7ab,0xce31cee9, + 0x4140dc3d,0x55af7633,0xdce8abba,0x84b7ab37,0xc7cf3efe,0x50de7648, + 0x15356ab2,0x73a88dcf }, + { 0x06e83b39,0x3f868288,0x9f44037d,0x477a4413,0x17dbc841,0xf9058b0f, + 0x54d17549,0x2db64f4f,0xf2307ffe,0xa23cea6a,0x4f126261,0x393efd55, + 0x10f37f26,0x2f4e658a,0xf4ee1e35,0xa4437ce3,0xa93cde8b,0x64ef42a7, + 0x939aa901,0x1debc9f4,0x3d7b5cd4,0x44223d6a,0xf88a3acc,0x789a6a11, + 0x2c608a2d,0x56fb9df8,0xbbf56c06,0xe79db8e3,0x668fa300,0x73c56af2, + 0xae396a1e,0x52f32b17 } }, + /* 52 */ + { { 0xe714f71a,0x56f524c1,0x9add8519,0xc1be1262,0x65cadbe3,0xad9189d8, + 0x5a0fb649,0xd88bf5c8,0x21d192d9,0x9efa6a92,0x6f724b6f,0xe3fe8389, + 0xb250119c,0xec3fae24,0x2ae0d3c0,0x4b6af9f6,0xd619624d,0x8fceba0b, + 0x2fdb6e3a,0x7dc3092b,0x3263cd29,0xc91da376,0xf95c43bd,0x30c0761e, + 0xcdeb44d9,0x89136400,0x43c0d31d,0xfd7dce84,0x9871899f,0x78fec3b1, + 0xefdf58c1,0x79e14d28 }, + { 0x9bb40c55,0xe3822235,0x0ed07a42,0x0a27202d,0x4838c1f4,0x48e6c1a9, + 0xd864a78e,0x2b5f24a7,0x0c6c55c9,0x7e7f140a,0xce12d508,0xe62c104a, + 0xc11b1e10,0x9b0a1a7e,0xafbb3dd5,0xfd8a275f,0x9a3b6b30,0xdff354fe, + 0x46602a01,0x5a105d9e,0x93bb65f7,0x3d371b4d,0x0f82fdeb,0xda5cbf0b, + 0xde468545,0x4601229b,0xc73d517e,0x505e10b9,0x672ff492,0x77cfa541, + 0x99566ce2,0x0d8ec28a } }, + /* 53 */ + { { 0xcbeee995,0x014cf73e,0xd491e80c,0xb2eb88bc,0xd9aba5d4,0x615a6cad, + 0x9304c84d,0x2f7d4633,0x8ab03c9a,0xba0501d2,0x91babb94,0xc8f723de, + 0x50405772,0xc885f977,0xc7fcb094,0xb5e1d2b3,0xdf96c71a,0x61ee7995, + 0x3464499e,0xb8c8daab,0x5f607932,0xdb425ddd,0xb1243587,0x70251ca1, + 0x9fc74340,0x26d7d3be,0xc902ac89,0x8c179310,0x4559a74f,0x72522c15, + 0xc3734afc,0x86001e27 }, + { 0xe7693947,0x13b00ba5,0x012c062b,0x6478641e,0xe85490a8,0xe1a438e0, + 0xd9574d5e,0x5173dbbf,0x9bd3ba61,0x9532eb8c,0x5f3ea075,0x1f41bcb8, + 0x8cbb92b9,0xac1cc247,0x1ef901b4,0x0f34648e,0xd2b3b2ee,0xdd929d1e, + 0xc3d75bfc,0x470f1eab,0x139cf4d2,0x5cdbc6f7,0xf0424953,0xcd86454d, + 0x47fcb383,0x1e079812,0x17df930c,0xb9f209b4,0x114ebc00,0x4225fc31, + 0x347946c1,0x020591cb } }, + /* 54 */ + { { 0x275e0af4,0xe3003721,0xe78a4a4b,0x721141ef,0xd1757485,0x666cfcf6, + 0x168e659e,0x5fa1d737,0x0e2842ee,0x263e3e54,0x948bd5f6,0xadecc3d4, + 0x246b104a,0x019de03d,0xf343d818,0xf8a9e903,0x5b0c0d31,0xcb57ba4a, + 0x51e2765f,0x8246c506,0x6519bf67,0x80c5751f,0xf2119a01,0x5f05c200, + 0x7821d4f4,0x7e6487b8,0x261c3a06,0x262f94aa,0x72146052,0x56cfe489, + 0xa1df05ef,0x5119985f }, + { 0xb18586c0,0x5819497d,0xc6eeaa62,0x004415d6,0x97cda28b,0x7c6a46b6, + 0x7c194594,0x9a149b28,0x4ed3a506,0xb56369fa,0x43c94cb4,0x7092aa66, + 0xa9e9eee2,0x55bce73a,0x77893509,0x34bb2870,0x06eb5326,0x8af95fb0, + 0x9638f485,0x87cd0323,0x5ba75bf8,0x29376268,0x9d42d581,0xf32d6f3d, + 0x65c6d64d,0xa4cad574,0xb2cded41,0x985f50fb,0x9006a067,0xcf34ce0e, + 0x58a57f9a,0x59eaf265 } }, + /* 55 */ + { { 0x6ec3876f,0x7b407efb,0xf0f48648,0x780c6123,0xbf893039,0x2abb56ff, + 0x45a91ab0,0x9592eaa0,0x78811b82,0xce5b84d7,0x1f9f3fc9,0x86a71a34, + 0xf0e7e13b,0xc17fdd86,0x655a0880,0x88ed8297,0x81d5e666,0x75d6dc74, + 0x1d171797,0xeffc9df6,0xe3f79e1f,0x36ad4c8d,0x2046192e,0xdb15317d, + 0x274fda62,0x78c9fa7a,0x82dd9914,0x04ec924f,0x3a64971c,0x059d1e38, + 0x2620bbfb,0x3b4450ea }, + { 0xc776dcdb,0x3db7a955,0x81c8ba47,0x35c4a57c,0x505760fb,0xae285003, + 0xb3aec353,0xe3e80691,0x47117be5,0x380335be,0x056ccf61,0xe1c47e3a, + 0x33977916,0x253cfdeb,0xf5cb7ee1,0x3decdfba,0x7cf4b704,0xf3c9794f, + 0x9ff81462,0x2401680c,0xbe3daa9f,0x4e440e11,0x69f91d8a,0xc5d04377, + 0xcb5e9c5d,0x4106c7a8,0x33b7d24d,0x191909a1,0x3764b4a2,0xe893c838, + 0xc429b614,0x4a7fe30c } }, + /* 56 */ + { { 0x2455c7c5,0xe78f3a70,0x70157754,0x5b7636e8,0x7623262c,0xf32c4524, + 0x1bc780c7,0x2c98b11e,0x915ed877,0xd48eaeac,0x199265f4,0xbb04d3c0, + 0xcfa5200f,0x6b52b19b,0x93ea3fe8,0xc46a0981,0xba758059,0xd82c733d, + 0x1896aacc,0xd324bbd6,0xce8ecd51,0xac09a2fc,0x02fc44b3,0x529918fd, + 0xaaa1784b,0xf0c45e4a,0xfe22085c,0x35626340,0xc50c7d61,0x53cbb676, + 0x65126b23,0x83fa1ea3 }, + { 0x10ccc646,0x60ac86da,0x7b0451e9,0x2ce0637f,0x8a088610,0xbbbcf630, + 0x20349982,0x23c19019,0xfc0bcda0,0x707fc39c,0x1bd4fd7d,0x7f4d1f15, + 0x44713bbb,0xd6a64e74,0xc5ac9e60,0x57bdc676,0x37b61169,0x456c5303, + 0xdcf40a1d,0xd3451396,0x4997d2c7,0xf3edec25,0xc2c4a739,0x534ae9a4, + 0x6a6ad2e2,0x1401397e,0x23e95f81,0x20769d4d,0xde98fabf,0xcee007c6, + 0x931c51e0,0x61409779 } }, + /* 57 */ + { { 0x15156623,0x3ddb32db,0xab7a67c2,0x68137fbc,0x6f19e3c2,0x26011f50, + 0x89924c61,0x34218b02,0xc6804c1c,0x492a0b0f,0xafaae6a7,0xd65be706, + 0x0d01be61,0x3b13d23e,0xf87f4c69,0x44545b47,0x04dc1aa3,0xd42236e2, + 0x3c5161ec,0x6135261d,0xbd88bc07,0x1eb46a63,0x1599d720,0x78c6d836, + 0x69baf0f3,0xf6955fe1,0x17072820,0x467eebd6,0x3e3a340a,0x2f1b8a2a, + 0x2d0b5f88,0x636dac76 }, + { 0xb4c80af3,0x94280db9,0x4e3892ab,0x9a189cd1,0xd1477ddc,0x26e702e0, + 0x68f9f14f,0xe91aee38,0x80baa0b2,0x2864f63a,0x8b714a29,0xacd81f73, + 0xc5fe7cb6,0x30e1b870,0xb10837fd,0x883ea1c3,0x6b20489f,0x2da27953, + 0x58a2da5f,0x3aeb2a68,0x03a8fa14,0xe2330bf2,0xdc70b1c4,0xb5c488b5, + 0x299678f4,0x0a78c4d9,0x25df675c,0x233bd098,0x7b67d368,0x37b5c076, + 0x4d0bef3f,0x2f6dbdfe } }, + /* 58 */ + { { 0x2e4da7c7,0x2f8472fd,0xae677932,0x708cfc91,0x3dc268e2,0x364af08a, + 0x799a2424,0x0f10dfe0,0x71d58bff,0xef912d58,0x988962e6,0x6bf35dfc, + 0x5f47ea0a,0x28b96fa9,0xaad308c1,0x734a79ea,0x9f437bba,0x95730337, + 0x6cf54f75,0x002cbd8e,0xe7632eec,0x47606dcf,0x53193104,0x404b5ecb, + 0x0acf729d,0x0ae0897c,0x3bddf1de,0x89628b86,0xf87d7448,0xeced154e, + 0x458d5d4e,0x5cb6e197 }, + { 0x008c75ed,0x98cef197,0xf6eeaaf8,0x7cf49d3e,0x1875e96d,0x1d6f9e02, + 0xdd9b0d8a,0xfcec2cfe,0xb9576daa,0x38a61cfe,0x36a7dbb8,0x10003f39, + 0x23b814f4,0xb37c3868,0xb80e3153,0x9fb66dcb,0x059847a8,0x9e7e2eba, + 0x35a72770,0xa4ec63fd,0xfc9e0ed0,0x311f3d91,0xd515baa4,0x3c1dc094, + 0xa08cd4e3,0x75a06ebc,0x2ed5eeaa,0xab617238,0xe1f52c1f,0x2e82bbb0, + 0x5175d6e5,0x2149d630 } }, + /* 59 */ + { { 0x5f9311f6,0xee1a8e6f,0xbabc1f85,0xc97e3c9f,0xb494209a,0x4fa7c52e, + 0x19774fe1,0x04c2f51c,0x8555844f,0x5cefd122,0xb5873ab3,0xb53862a3, + 0xcbed19fc,0x768efdd6,0xee58469a,0xcdc12479,0x3d80c09c,0x11237e31, + 0xc044c28c,0xdd74a290,0xbd47e287,0x9ee6517a,0xad0ffeef,0xc2421228, + 0x818d281f,0x4273088f,0x43ec0de1,0xebc744bc,0xb415bd73,0x5b26eccf, + 0xcb07c26c,0x14e2f350 }, + { 0x4216946b,0x548d2a10,0x7a4bd92d,0x6e801f07,0x43695160,0x5996d0a3, + 0x63a197c9,0x0f1b5c2f,0x061f77c9,0x79da3c4f,0x93ff7b22,0x1c1cd634, + 0xa234123f,0x5e61b650,0xf284033c,0x826b34c5,0xc2f34214,0x718b90e8, + 0xae806ec5,0xa5f35620,0xe324a9b4,0xa2fae345,0x8b53cb51,0x8c0bb95e, + 0xf9965778,0xc94f6ac2,0x6b9def32,0x07ec607d,0xd0ed8f27,0x63bf1dba, + 0xdcb61e4f,0x58537e02 } }, + /* 60 */ + { { 0x64f80ba2,0x1f64b064,0x0559a45b,0xe8e055e7,0xf1f4b634,0xc3262b34, + 0xde8c8482,0xef4f7d5f,0xc30c780a,0x9d55dea0,0xcfa1e693,0x1740afb9, + 0x7460c34b,0x2cfe6a66,0x1187c1ee,0xf6695941,0x5f974d94,0x1382f277, + 0x004549eb,0x1ca0ace4,0xbabded02,0xf8244b3f,0x4e3653ea,0xc36f4d06, + 0xc55c5f83,0xeab9f0dc,0xacebce90,0xd93b9cef,0x19061425,0x16658e72, + 0x82d7970d,0x4857835f }, + { 0xd2576210,0xdcd525bc,0xd51b5443,0x9f378aa7,0x1bd83994,0xfe97bf17, + 0xf38ac621,0x930d0f63,0x818408cc,0xaf8f2c17,0x260f53f6,0x2692c87e, + 0xdb0a75e4,0x0ee45407,0xffdb1b37,0x0ec47ae5,0x7aa6a44b,0x769129dc, + 0x2e40b75d,0xb6f932b2,0x95ef3b77,0xe06764d0,0x68bc63e8,0x28fd47f5, + 0x9c0014c0,0xd1810494,0xd7995d8e,0x90e2d3fd,0x6c2a85af,0xeb39a05d, + 0xa21f3128,0x6c0277bd } }, + /* 61 */ + { { 0xb509e7ef,0xe41b7086,0x3d7f9f91,0x8842ec7b,0x5526b88b,0xcd285f94, + 0x051dd0ab,0x6e44e064,0x774f1ceb,0x90198c10,0x123e661b,0x6ecabe98, + 0x32f647d9,0x44811136,0x26c52aee,0x1dd82b45,0x939dc9d5,0xd650907f, + 0xfcd455bf,0xbd5eeef2,0x8d2e5d7c,0x7815a4dd,0x88bc9f2a,0x5ad4ec92, + 0x57a3b322,0xc6f10d0b,0x20b9cbdb,0xe8d0c1e7,0x9b774ee8,0x5a0b071a, + 0xf22fcf8f,0x3067bc9a }, + { 0xb7ca9326,0xe0e589f2,0xb1224f63,0x17a106fd,0x747a57bd,0xb2354521, + 0x62b0882e,0x2614982d,0x4391ffcf,0x7f3af544,0xa84e440d,0x1aaa337b, + 0x941bb071,0x28ea37b0,0x2e4a7f54,0xa957dcb4,0x1a6ad5fb,0xe7ab662c, + 0xf7c36a20,0xd135e381,0x9baa0b6b,0x42e7980c,0x94e4671f,0x4237030c, + 0x8b0922e3,0x24cc63ff,0x445a589f,0xd10d5279,0xa870ff6c,0xbb99d316, + 0xa996c195,0x390c83ca } }, + /* 62 */ + { { 0xffc4a73f,0x50d3fa82,0x3bd53303,0x2665d635,0x264bb77d,0x80a06f8a, + 0x22d73d84,0x81c04a6e,0x0323b8aa,0x2409cff5,0x8c4c4d5a,0x31dce217, + 0x0c0f9c19,0x374aa80e,0x00186bb8,0x0b25a387,0xaaf1487f,0xd0b77a10, + 0xab498de1,0x15f39ad5,0x1aa0c116,0x92e32da6,0x96e25ce8,0x228e3dbd, + 0x5e8646d1,0xb57c88dc,0x267b1c68,0x672b1164,0x600bdec5,0x5d0d807f, + 0x223e573a,0x3ea4007d }, + { 0xa595d0a3,0xd76debd0,0xaff0b3b4,0xa6bd76cb,0x9b1bdb97,0xbf2c154f, + 0x4c714c71,0x62b19ab4,0x221af663,0xc9bf33b9,0x8c941ef6,0x23d87c49, + 0xd79f0f6d,0x255804c3,0x2a7acbc1,0x6f1a1005,0x550528af,0x5dab79d9, + 0xc8d16213,0xfd77a6f0,0xde5e1029,0x40508b6d,0xf95da12b,0xd95ac0f2, + 0x758a8ba1,0x8860af71,0x7160c8fb,0x0b194c83,0xce004d34,0xa40e6c80, + 0x6b14aaa0,0x09f82a17 } }, + /* 63 */ + { { 0xc21366dc,0x60abe588,0xaf75daf9,0x729c0a4f,0xacb93ed4,0x70501fd9, + 0x87a16d70,0xb97e744e,0x98e7361b,0xa42e0a7a,0x28b54cf3,0x1acdaff2, + 0xb7bd9078,0xf087ccbb,0x663250e7,0xda6f3983,0xbaf07c09,0x66d693ee, + 0x8cbaf157,0x79baf4c3,0xdfca99d0,0x5a984e07,0xf26d8dab,0xab4d3247, + 0x7eba36f9,0x4d0be701,0x0e8dd216,0x37bb9e65,0x531c4f03,0x72aa4e24, + 0xb753d85a,0x77d1e984 }, + { 0xd8e62367,0xd9373239,0xb9820cf1,0x3361848b,0x5a9c97c4,0x00c7e344, + 0x14f960fc,0x9a0ec9ae,0x740474b5,0xcf41f0cf,0xece065d5,0xa5eede8f, + 0x9e808610,0xb1de5a4e,0xae0cf75d,0x17c44ae4,0x6b148d0b,0x2fa56323, + 0xd29ff2dc,0x64fa740f,0x88cb212e,0xc605eb8a,0x6a863016,0xf2c771ad, + 0x607b4c17,0x6d6112e7,0x40d49785,0xfe90ec07,0xe256e0e5,0x599be18b, + 0xca54adb0,0x4e6eabec } }, + /* 64 */ + { { 0xfb99cfe6,0x950323d3,0xc9334178,0x7b09bc26,0x7cbdfb6f,0x64111e41, + 0x89a75760,0x91141744,0x10919cb0,0x4c633df9,0x396bfd2f,0x715fc7c7, + 0x8cab62db,0x8ca19512,0x4db81aac,0x30672473,0xb4c4c54a,0xe67a246b, + 0xbf229646,0xd77ea0fa,0xfa5b5d70,0x5bed15f1,0xc2f192f3,0xa5686da5, + 0x7f6690ad,0xdecac72a,0xcaa50b7d,0x0c4af2a2,0x6049ad2f,0xf44631c1, + 0x04ecf056,0x325d2796 }, + { 0x4848c144,0xee11fb55,0xb6a7af32,0x4e062925,0x369e0f9a,0x125b68e1, + 0xca53b21e,0xad9bdae6,0x2e98ea1b,0xf50d605c,0x9f2fa395,0xbdb9e153, + 0xe91532f5,0x4570e32d,0x46a250d7,0x810698ae,0xad9d9145,0x7fd9546c, + 0x11e97a5e,0xabf67721,0x249f82e9,0xca29f7d5,0x9851df63,0xa9c539a9, + 0x71d0e3e5,0xfd84d54b,0x041d2b56,0xd1e0459c,0xfd80096a,0xceb3eb6e, + 0xe32a79d3,0x19d48546 } }, + /* 65 */ + { { 0xb540f5e5,0xfe19ee8f,0x04e68d17,0x86d2a52f,0xadbdc871,0xd2320db0, + 0xd03a7fc8,0xa83ad5a8,0x08bcb916,0x54bf83c7,0x2e51e840,0x092133ea, + 0xcb52dddf,0xbce38424,0x31063583,0xd5c7be40,0x458e3176,0xc1ebb9df, + 0xbc4dabbf,0xafb19639,0xc05725a8,0x36350fe4,0x84e1cd24,0xac4a0634, + 0xc145b8de,0xadf73154,0xb3483237,0x0aa6dd9e,0xcbff2720,0xa3345c3d, + 0xb4e453b0,0x1b3ace6c }, + { 0x90a8bdc5,0x0343e5e9,0x6306a089,0xa203bf9d,0x8e48520e,0x98489a35, + 0xde7d1d06,0xbd17debe,0x5f795d3f,0x8fafa6d7,0x387b0a3f,0xa4ceb630, + 0xffddeafa,0xe0166b32,0x7e764e02,0xa2fe2054,0xe871f304,0x55ab9824, + 0x952ec45e,0xa2bd36bb,0xa90d20ca,0x7b4c1484,0x75bcfb53,0x5319f387, + 0x6982c4e5,0x34238a4a,0xa102921d,0xa2bb61c7,0xdb3ab17e,0x1e061b64, + 0x192f0a14,0x538ec33e } }, + /* 66 */ + { { 0xa19b56cf,0x193496fe,0x7bb99acd,0x663d77f4,0x57d0a881,0x8f04afa8, + 0x082835fd,0xcced3da2,0x5d82cec7,0x7e21faed,0xf8009c85,0x6e175b99, + 0x2d05a307,0xd9c6e31b,0x81487d82,0x96948d4a,0xd46f6655,0x86ebd3f2, + 0x773ccc49,0x86851aa8,0x8b1640a6,0x3e220f22,0x41a20b75,0x9f06e3a8, + 0x90ac0a6f,0x2cfffe5e,0x8ebeb3fb,0xf5a9b1da,0x6e08e2c9,0x2587d997, + 0x03e9f401,0x6fd60298 }, + { 0x8eb7516a,0x54709f8d,0xbdc598ab,0x83058a74,0x87e801ce,0xd234dd98, + 0xd17b8a96,0xfd0f9d90,0x6e90f6ab,0xaa1e549f,0x5a7ed55b,0x2496ff80, + 0x6c254c19,0x0d9f657a,0xb8962575,0x3cdea49c,0x2dff27de,0xb685a3f0, + 0xdb8bc04b,0x3c50e7fd,0x987236b0,0x904ff0ff,0xbb0d5055,0x494298fd, + 0xe14be8d0,0x34b3386d,0x7c3d30d6,0x7ad34e9c,0xe159fdd9,0x1f2b32bd, + 0xc761e5c0,0x84cfa23c } }, + /* 67 */ + { { 0x8b99b964,0x13bc11eb,0x58e2fc47,0x8e280c0a,0xd4c9a54b,0x870fbc49, + 0xbf6e20fa,0x37a334a2,0xd7c88cfa,0xee583d0d,0xef4af1da,0x05e029a8, + 0x0c2ef8a6,0x6d55e234,0x209e9b62,0x61b6fdfe,0xbb8e080f,0x3b1dad26, + 0x9392fc1a,0x5adbc162,0x0aae3f4e,0x02ac0fe6,0xc2bf4d5b,0x8d99801a, + 0xc282fed2,0x2333f93f,0xb52db33f,0x16dcb10c,0xc55752e7,0x09f90f84, + 0xc84a0d8e,0x287d4c51 }, + { 0x0e9867da,0x5fa58201,0x1a874cda,0x614589b3,0xfbdee22e,0x005e27c5, + 0xe612bda8,0xe357fef5,0x2d3635f9,0x4e0dbedf,0x6f125a86,0x62be70e4, + 0x0d94a2e5,0xa09b9884,0x28b5e5d1,0x7eb99a15,0x751028b5,0x21b9416e, + 0xe06d2cc4,0x1b137fd7,0xfea09845,0x6fa1f517,0xffcecbd7,0x3ba1e966, + 0x832f453e,0xd4c89a4a,0xeca68fa1,0x07b1e2af,0x4bd395a3,0xd0fb4453, + 0xd8ef9e13,0x0132a3dc } }, + /* 68 */ + { { 0x576374c2,0xe53c7785,0x84727040,0xe60526d1,0x228ca044,0x8a066dc8, + 0xf1ce1313,0x1fe1c1b2,0xcdeb0c5d,0x2aeec832,0x9cbf826f,0xa7596699, + 0xde77a589,0xcd188e81,0x118d1254,0xe5ce0fe0,0x0790b86a,0xa142a984, + 0x39ac28ce,0xe28f043f,0x87de5804,0x4eef8290,0xf639a8c5,0x83c31b32, + 0x5887794f,0xd70454a7,0x18b1b391,0xca635d50,0x31d9c795,0xcefea076, + 0xb6f8aa25,0x13cbee76 }, + { 0x8d3f34f3,0x79cabe0f,0xa3617fe3,0xbda9c31c,0xdd9426a1,0xb26dee23, + 0xf29c9104,0xe9dd9627,0xe2c6cd3b,0x033eb169,0xfcba2196,0x8a73f492, + 0xb858c83c,0x92e37e0b,0x23b3fbb7,0xe4f2aca6,0x64be00a2,0x8101fb1e, + 0x948f6448,0x91a7826a,0x907260e7,0x414067b4,0xe30bb835,0xf774aa50, + 0xc999c06e,0xf922ca80,0x0ba08511,0x6b8635b9,0x25fa04f0,0xbf936b5c, + 0xe02e8967,0x4e0a1ada } }, + /* 69 */ + { { 0x8ba29c4d,0x00ca6670,0x22988094,0xc08240ce,0x16dda752,0x21c5ca67, + 0xabbbfa34,0x689c0e45,0x3ed28b72,0x1d7545fd,0xd7c56ab4,0x5f221198, + 0x38759d65,0x4b3d8f74,0x8fe50b89,0x93490dfb,0xe80eba16,0xb641f5d7, + 0x79acb537,0x7b0da5eb,0x0c1d5e5e,0xab6b1497,0xa5da429a,0x2338e68d, + 0x2f6d2f25,0xe010c437,0x6530f3a7,0x226f16d2,0xcbef08bc,0xefb0f7b6, + 0x9f99c999,0x733e30d9 }, + { 0xa42a38f9,0xecfe1582,0x4730b500,0xaec2d58e,0xde976b2c,0x2ee2f2a7, + 0xa969c1bb,0xf0539db5,0xfcecdb4a,0x31954168,0xe7a8e902,0xf2f7348a, + 0x3121541f,0x1d58d7cc,0x2202ae52,0x5d25b75c,0xf40835a7,0xdea9965a, + 0x529b4e46,0x3feb6a41,0xbd27ad9b,0x5c97fb6f,0x261f900b,0xd87554c0, + 0x04d5b19e,0xb43031d9,0xcb219b9c,0x33d5e9b8,0x3ee00bcf,0x7a43d492, + 0xb79a5c0c,0x56facb39 } }, + /* 70 */ + { { 0xa3018bfa,0x019165a2,0x9ffad984,0x100c6b24,0x55341a9b,0xbbf1b1f6, + 0x25dc4cc9,0xe6bd1d97,0x2bfffe60,0x52850ed5,0x7e5509ab,0x24e992cc, + 0x4ceb59f1,0xff6c502e,0x1aa7d148,0x2f0b3573,0xe7e3aa46,0xe90c1ddd, + 0xd1142880,0xbaec9f45,0x65be5dd5,0x475cfd26,0x1febce13,0x83abb14e, + 0x80942d30,0x6aba4829,0x297e82c8,0x1e1b235d,0x50d8218d,0xb771cdbe, + 0xd94d6cbb,0x88599266 }, + { 0x155ccaf2,0x08847290,0x7c5b773e,0x8679ebc7,0xb2dd08ed,0xa88b2dd1, + 0x87d475db,0x960a180e,0x6694d02a,0x80fdb6b7,0x3f3f9e96,0x3e8758c9, + 0x4ad836c4,0xbda3f6fa,0x32fb387d,0x9400c581,0x2550200f,0x25a78542, + 0x776ecf18,0x2a97c351,0x566db59a,0x03ebf46e,0x26545eda,0x4743a280, + 0xcf74ab44,0xed169d84,0x88cb3f69,0xbaab931d,0xd8257196,0x70ae932c, + 0xa0c09719,0x797224a6 } }, + /* 71 */ + { { 0x441f3567,0x632923f8,0x2e24bf1d,0xc11c3168,0xb7671fff,0x4b97726b, + 0x7a5e1a22,0x601746a7,0x3addb417,0x53dddea0,0x7f59b846,0x57867a3c, + 0x56cd7ff7,0xb012a987,0xf19ba9a8,0x1bd5fec9,0xf8306748,0x750379a2, + 0xab8c05d1,0x7763445d,0x7903f42a,0x5d7f441b,0xa903e46d,0xc011674d, + 0xadd126c1,0x1b1d3c4d,0x61455b40,0xa2752aac,0x555c356e,0x4da42a68, + 0xd820852c,0x3ff09c15 }, + { 0xf9cb7784,0x4c0a1bce,0x2422f305,0xaec539bc,0x0c414aa7,0x5f40f9fd, + 0xffd42bc4,0xd3aa316c,0x2f358e15,0x42f5a4c3,0xd6e27682,0x00bdcd9e, + 0xf8a5ecee,0x069f789f,0x05e14f5d,0x8078018e,0x8b40c741,0x2bb3e493, + 0x7917f72d,0x5dbc8c1d,0xcc57150c,0xe0eea664,0xc3fa8920,0xa25ecc5a, + 0x1c797164,0x3c21b0f5,0x634ad16b,0x8f09a2f2,0x58391d9a,0x8e730fc5, + 0x4fdfae4c,0x47ef1805 } }, + /* 72 */ + { { 0x3da285e4,0x9965f3d1,0x3a01e3f4,0xba7d4dba,0x61214ad0,0x4738413a, + 0x22397549,0xd3b7d535,0x5a730b92,0xa53dbdcf,0x332d165d,0x3130d92b, + 0x82f97ef4,0x44a28541,0x44dce1b6,0xbf62221c,0x7e2a0ec9,0xbba13858, + 0xcbfad998,0x33f32c8d,0xb5fed44b,0x409e5f3f,0xc66217bb,0x5c328c65, + 0xfcdf71a9,0xb00db69f,0xb8920788,0xa23c2a21,0x3ae6464b,0xf8ab28e6, + 0xb8de0861,0x1a6b6e9c }, + { 0x06af77aa,0xaf6ec2b6,0xa887f065,0x2e60f5cd,0x9f498c56,0x87d21400, + 0xfcbaaf4b,0xdb595b59,0x271ab855,0x0fb592a1,0xd4349b0c,0xa0ce10e5, + 0x887d8c9c,0x9d6187d8,0x154bd6db,0x03ee95f9,0x5d06c999,0x8fe53213, + 0xfb6a64d0,0xf4a7bc30,0x66a4cb60,0x3d22af0d,0x5d37367c,0x16952cef, + 0x997d8e55,0x6f0ea734,0x731732d0,0xb447c70f,0xa9cb3942,0x00ab3034, + 0x28510fd0,0x79dd0180 } }, + /* 73 */ + { { 0x3ac7424e,0x04e0033a,0x60fda4d0,0xdb06b688,0xbcb772fb,0x236a9766, + 0xf297cda4,0x294a8e2b,0xdb013c6e,0x4b0aab85,0x8723a3ad,0x3d2aec98, + 0x13c84a6b,0x0cae32cd,0x70ec169e,0x21888f5e,0x42a88262,0x739633bd, + 0x7b60d9b8,0x68ac792e,0x10769fe1,0x89f2b722,0xd24bed34,0x8f3fcfe6, + 0xa3eb24aa,0xd35efb88,0x484c706b,0xddecfa3f,0x929ece0d,0x7cc119a9, + 0x8d405436,0x87e5ad45 }, + { 0x7d1000a7,0xba99aa9d,0xae823833,0x8b94affc,0xdfb83dc5,0xc8229628, + 0x845a418d,0x2f59fe11,0x5d417054,0xa8b970f8,0x72b71581,0x8918c265, + 0xc0d1dd17,0xe4ef477d,0x3afad7c0,0xb50b4cf3,0x01870a5b,0x21baea79, + 0xbb3a2868,0xc77087f9,0x124a59cd,0x7857531e,0x57f43239,0xed74c26f, + 0x0164c94a,0xd5f5ae25,0xf094bf74,0x6608b7e2,0xfdceea32,0xf4cdb5ba, + 0x990cc045,0x0b712519 } }, + /* 74 */ + { { 0x88d5c64d,0x5a290ca1,0xa7492534,0x0596d749,0x2a00e925,0xa04b0d3d, + 0xcaf7b66b,0x082cd02c,0xecdded83,0x912b50c2,0xff31646e,0x813ce9de, + 0xc75fff95,0x62ae70c7,0x7e2a4615,0x6f6852e0,0x03804fd1,0x320fd7d0, + 0x8218e8d9,0xb1a2a4dd,0xafc645d7,0x4918a6fb,0xe8d9fdbe,0xfb080fa1, + 0x4470b6ee,0x33d4d08a,0x6d974ef7,0xd2ba2077,0x69dae5d2,0x8ecb95a7, + 0x7d69596d,0x7a3f423a }, + { 0x9a929387,0x362d2ca6,0xcb1c1fff,0xabdb7581,0x7e51b6cb,0xd892ec9f, + 0x3a4e131f,0xee8d8632,0x5bd87561,0x4680e3f1,0xd4e7e732,0xe3a597e1, + 0x5581fefe,0x3cc72b7c,0xca8cae0b,0xf3e77f8a,0x5e2fd4af,0xfcc7d7dc, + 0x21355b79,0xdd3a4552,0xa2c07177,0x546b24f2,0x0689621f,0x415b532d, + 0x3f78163e,0x2be9af51,0x33d7ed21,0x27d63b9b,0x96802943,0xab019ef2, + 0x1623faf4,0x2da5fc55 } }, + /* 75 */ + { { 0xc8a5c600,0x62429cf3,0x3fe33e7c,0xa7a80c22,0x0a57ddcb,0x9ffda740, + 0x925b0c74,0xd1ae156d,0x6b100eb0,0x097a43f9,0xef943c81,0x169e945c, + 0x1128cf24,0xa1f734e5,0x419f0133,0x04387c4a,0x01044024,0xc007868b, + 0x90359cf2,0xe5416abf,0x478d54e3,0xf9c76fee,0x42a2173e,0x66219da6, + 0x9fe30141,0x61e03156,0x93ef247e,0xa0ff5ce3,0x072b6592,0x811792ba, + 0x70c854d3,0x855f0219 }, + { 0x847314c4,0x61fbfb6c,0xeb45b96a,0x97906155,0x6ba2afac,0x7102e146, + 0xab949781,0xed51f975,0xc110c4fe,0x9d2f5b17,0xaff57667,0x7ac8ce70, + 0x6eb244e7,0xe7366a21,0x551c65c7,0xdd1bbcec,0xe1a859de,0xb525060a, + 0x8ba7d2e7,0x7a048174,0xab8ea8c4,0xe1a2c541,0x6fdff078,0x6e7824c3, + 0x14874b04,0x79b49fc7,0x06b1f733,0x22ae337f,0x6f8fe6cf,0x1c352192, + 0x525d0797,0x292236cf } }, + /* 76 */ + { { 0x7d8b29dc,0xcdb8d80a,0x08ea648a,0xd17a2024,0xae92be91,0x7db12c5e, + 0xfda72fbc,0x1f347d18,0x9e760c6f,0x11374b40,0xd8e38d91,0x7361e8f1, + 0x739ac1f4,0x7714be9d,0xb4df5c4e,0xc1f9701c,0x6f72cae1,0xd9138ed8, + 0x6ad180c4,0x1c7fe1f7,0x9e2dbf9c,0xf8c185be,0x7c70c44d,0x835db269, + 0xb0d15b5f,0xf997cfea,0x61e6545e,0x5101445a,0x25184e5e,0x16b06884, + 0x7521e7aa,0x7cfac359 }, + { 0x3c0bc53a,0x81182167,0x7e751367,0x84b5ede3,0xa3657a18,0x3ca255fd, + 0xba1fdd98,0x096abbf4,0xc5da77d8,0x9ce8369f,0xaab342c5,0xf27b9ae7, + 0x972059f1,0x06c91bd6,0x914ecfe9,0xee0dab30,0x93f53f12,0xbb647fbb, + 0xffa57e0e,0x30c38a7a,0x9f2ad607,0x517d06ef,0xbb99dcc9,0x49728d87, + 0x446080a1,0xb0034af1,0x12b9c17d,0xcc810c3f,0x772a22a0,0x7225f14f, + 0x1ddf82bd,0x6ce3dc7f } }, + /* 77 */ + { { 0xa4397830,0xc07cd835,0xf4733306,0x4dd9290c,0x29989e8c,0xdd35d3a8, + 0x563d8152,0x79902559,0xe87de61b,0xf278d911,0x1024e35c,0x9c7340c7, + 0x4a0d0e59,0x2d444461,0xf32626a1,0x63e7608f,0xc4c9baa9,0x627a37e9, + 0x76fffd25,0x0c56dc51,0xcef2a1cd,0xcb6defc8,0xefc559d9,0xcbcc0d56, + 0x041cb692,0xe45f3fc5,0xe5161e09,0xcd05c239,0x5c3b559c,0x2a731ee9, + 0xa3d0a16d,0x85151122 }, + { 0x86ff19e2,0x782d0335,0x1da28603,0xc2c60daa,0x557c7eed,0xb2e78cfe, + 0x1bc4e8b0,0xa8f6f984,0x3df35c67,0xcc1f9b4b,0x4764462a,0x96e13603, + 0x7c7ae0b0,0xbf910b97,0x51435956,0x27c7f305,0xf631eae5,0xc14db15c, + 0x7e69b34c,0xa51d6142,0x5fc12ff2,0xdec82851,0xfb887162,0xfcceae13, + 0xde1488bd,0xda332ac1,0x2ee3e74c,0xa20374e2,0xf0ae069c,0x597ea1a1, + 0x77bdec04,0x8b1159f2 } }, + /* 78 */ + { { 0x2f961d30,0x4af71a44,0x7ac7248f,0xbdf968a8,0xb1a906cd,0xd32df87c, + 0x04abf925,0x00c10e26,0xb9f04d4c,0xb8711759,0x939705da,0x00d54e60, + 0xc9f80849,0xf7587433,0x6a7a2375,0x2e9abade,0x94ac17ac,0x5676d478, + 0xc202d99c,0x4ca0525b,0xabfae73d,0x95b8bcad,0x3405991b,0x2371ed38, + 0x458a99c3,0x2b69e47a,0x2b78c866,0x7cac0b18,0xe0232c7c,0x6ceaa79b, + 0x588f7459,0x0bd86433 }, + { 0x7e734189,0xdea1a8b4,0xcfe5fa17,0x52c5ac88,0x11437664,0x444a4d4e, + 0xaf9e9750,0xc2522308,0xd30c6b3b,0x78b1d0c3,0x4c6df477,0x2edae5f0, + 0x2ee88dd7,0x53131d9a,0xacc93e34,0xc4e380ee,0xa8db0e8e,0xd499b1ac, + 0x7f5d49d7,0x77348c16,0x1556ccd7,0xc9663257,0x2611d13d,0x65ce0e8c, + 0xb5a2fdcc,0x2c95fe66,0x8658faa1,0x26698832,0x31c32c98,0xda87d1f4, + 0xfcd91907,0x46650598 } }, + /* 79 */ + { { 0x6b4a5efa,0x4c6c13cc,0x1d07b265,0xc481989b,0x8bdc69c0,0x10b966ce, + 0x2c2531d4,0xf54cfaa2,0xcad0a100,0xcb5f1808,0xee5da449,0xbeb52538, + 0xbedd83cc,0xa6240085,0xd6255c78,0xe792dacf,0x2062058f,0x88371906, + 0xed1658c1,0x96615e83,0x7d28d542,0x4b549b27,0x83b75df3,0xeaf127db, + 0x17fbb942,0x4f60df6d,0xf6f7c930,0xd08631db,0x6018789f,0x17c38f98, + 0xb9a9280c,0x0c43574a }, + { 0x1d20cad0,0x76eb324c,0x8c61108a,0x90decb09,0x6f06d36d,0xa6e9d39c, + 0xbc0da197,0x6cd978ba,0x507ac5ce,0x5948b1c0,0xc5497eb5,0x2bd47164, + 0x4d5914e3,0x2a9c4c0f,0xa759f03c,0x772c5046,0x69ac847e,0xe7d7328a, + 0x3048b330,0xa8d57d0c,0x40f7bace,0xe60034e0,0xa85f1790,0x823d9193, + 0x5c859736,0xa6e9b66c,0x679e1022,0x22ca2c7a,0x09023fa4,0x00e7a19c, + 0x2726d5b9,0x324999f1 } }, + /* 80 */ + { { 0x7c834915,0x667eaed6,0xbc5eb64d,0x9f77aa6a,0x25d62011,0x729ebcb6, + 0x699fd9c2,0x0aee24f2,0x2b8d4f6c,0xe1eb5874,0x14c976d6,0x7f12710c, + 0xf6d9ea65,0x91390335,0x06b50064,0x668b7049,0x0876ee4f,0x65969a0e, + 0x2f9d9360,0xf901bf3f,0xb499e3ce,0xfb1a8651,0xf2dbcaaa,0x80b953fb, + 0x973b06b6,0x312cc566,0x3af36c64,0x3534d9c3,0x10ffd815,0xe4463a52, + 0xf18c2b91,0x57ea2b4b }, + { 0x8aa0f2f2,0x00f5e162,0x0e46bcaa,0x8c7e75c5,0xa4a2c42d,0x97ab479a, + 0x14baa202,0xb4f308ea,0x6943cc2e,0xa901bd14,0xeed58804,0xbb125fee, + 0x9d180f7c,0x6502c8f9,0x1580c61c,0xe5353919,0x27101ee3,0x7e278069, + 0xfaa72717,0x7a0a40a1,0x4c75b153,0x32edce02,0x538f1c22,0xda23660b, + 0xbe307d2e,0x4d511e98,0x9baee0b4,0x24276e40,0x7ff1f307,0xa78c3927, + 0xea7935c9,0x60480b46 } }, + /* 81 */ + { { 0x3872ece3,0x31087d66,0x955b70f8,0x5f29be7d,0x9cf95bb8,0xb50b4fc7, + 0xdbffa621,0xbae3b58d,0xe022ba5d,0x0e61d280,0x4181449c,0x78ae5117, + 0xcf555485,0x0b132840,0xb8ce0b0e,0x800ed1b6,0x78d5de3d,0x35dffdd5, + 0x69a56b47,0xf7e42374,0x8d910ae7,0xd5e32369,0x6313c7c7,0xb6ff52a0, + 0xa92de9e5,0x5a2fe20d,0xd12110bb,0x41b347d3,0x40c16f23,0xc5905edb, + 0x9a8f88cc,0x0774a0d3 }, + { 0xe3b6c106,0x3ae181ab,0x8de150b7,0x4ebe163f,0x6f354836,0xcf75b82f, + 0x3ac7ac16,0xaa0d2063,0x291722af,0x5c680668,0x11545553,0x73941e61, + 0xbf5de3f7,0x17127e38,0x1afb41da,0x32cfdf03,0x87bc8663,0xc6893c91, + 0xa62c9c99,0x75046744,0x962c1947,0x96866e2d,0x378cdf4c,0x489ec8df, + 0x3407fa32,0x3a60709b,0x551290d1,0xd37d2159,0xbab92273,0x9623d303, + 0x2432014b,0x08151954 } }, + /* 82 */ + { { 0xfb7b2108,0xf9236d89,0xad75f9aa,0x3ecc83cc,0xb4e1da11,0xf7c72b15, + 0x0315c362,0x552aeaef,0xf272fe3f,0x11e140ed,0x87843ee8,0x99d79bf6, + 0x1d9bb25b,0xce6b54fd,0x5b1bad74,0xb20b0e21,0x5b84c90d,0x54a0214f, + 0xfca6cec9,0x459bbf52,0x9e4df76f,0xe363c48d,0xd64cf17e,0x3045f84e, + 0xf62ada48,0x8402a167,0x6a74ca01,0x2c9e1bf3,0xf691c42d,0xe8cf9d41, + 0xc2c4b874,0x5abf2178 }, + { 0xf3b3bccd,0x4777966b,0xbe3e0caa,0x0047e0f0,0x8c7d5043,0xcb8383b3, + 0x946fd5fc,0xe77e3baf,0xe9ec0e87,0x79baa785,0xc8a18d25,0xd83c557c, + 0x25befcfe,0x9b96e5af,0x98c71b61,0x4f05d15e,0x77e62da1,0x081f991a, + 0xcbaa3821,0x1c6ec781,0xe54d9bfb,0x7522f65d,0x44ed1430,0xf5d05573, + 0x95cafdda,0x3035b31f,0x6378f5bf,0x47e67f43,0x5270b9d9,0x029f7cad, + 0x4d916a48,0x15ad1587 } }, + /* 83 */ + { { 0xaa588ae4,0x00de2ece,0xa371a232,0x552ebc58,0x71230444,0xd00ea934, + 0xe4b1832d,0xafbfa67d,0xb689e843,0x29216341,0x61f4e2e8,0x1f96bbbd, + 0x04c29dc5,0x95420684,0x42317fd1,0xc7fe3827,0x63483162,0xe0a0aec6, + 0x0700184f,0xfc2b94d1,0xfe1fbd85,0x07219973,0xfb074352,0x648b6ab1, + 0xc46e5392,0x23bbdaad,0x00fa56ff,0x0db8dd1f,0x866725f6,0x104815eb, + 0x52e81963,0x3f9c4cca }, + { 0x32ce637e,0xff36b297,0xf5d25cdd,0x81a15f2d,0x8b02ad97,0x1a1d052d, + 0xcfbab3e9,0x2e5f3bbc,0x614eeb75,0x60d2cbd7,0xcd5a793a,0xd4491843, + 0xcdba2144,0x2242cf75,0x88b99766,0xa20705e7,0xec77e132,0x64e12cc0, + 0xb61a9b05,0xb1c14df6,0x74825b5a,0x8fd97f04,0x3da31223,0x95604821, + 0x4d30c70d,0xde486727,0x1c12ee69,0xbcab8f15,0x668d893d,0x5dc638b4, + 0x223f574b,0x6479dad6 } }, + /* 84 */ + { { 0xb05f2b26,0x569044f3,0x80b9f76c,0xb35a294a,0x4290f6ae,0x8839fe28, + 0x026a5877,0x761cfb23,0x2e5ff9c3,0x768926b6,0x0b11c576,0xbae6cd20, + 0x72a03efe,0xdc857756,0xe1bad63a,0x0cae074a,0xd709d99c,0x3fe491a1, + 0x6501d9c1,0x76c5ded6,0xc32aeff7,0x1da6eca1,0xc57683e8,0x50849d55, + 0xdf98d847,0x9e392e9c,0x64d9a564,0xfad7982f,0xa37b98b2,0xf7c3bdb7, + 0xf0860497,0x1fe09f94 }, + { 0x7648cc63,0x49a7eaae,0x67cfa714,0x13ea2511,0x653f4559,0xfc8b923c, + 0x81a16e86,0xd957619b,0x3c864674,0x0c7e804b,0x1616599a,0xfc88134a, + 0x0a652328,0x366ea969,0x4bc9029e,0x41532960,0xae2aad2b,0xef9e1994, + 0x7f10bef5,0x9e2a8c52,0xc67bf860,0x73dcb586,0x844cc25d,0xf61a43fa, + 0x74eb3653,0xd74e7eea,0xdd240f02,0xf3356706,0xfd83bcb4,0xeec7694c, + 0xdb62526a,0x4de95786 } }, + /* 85 */ + { { 0x3deac2f7,0x4867d315,0xb61d9a8e,0xa084778a,0x0ab7b2d5,0xf3b76f96, + 0xcfdf4f79,0x00b30056,0x31ab8f4b,0xd0701e15,0x9c779d01,0x07f948d5, + 0x82675371,0x7c994ebc,0x48bad4c0,0x1104d4ee,0xbfc9d058,0x798ce0b5, + 0x309fa80b,0xc7ca898d,0xacb33eaf,0x0244f225,0x5b2f3175,0xd51e8dfc, + 0xa4d7be34,0x3e49ba6b,0xbda02b43,0x1760f4c7,0x4435275a,0x37e36a7e, + 0xe636980c,0x1c94418b }, + { 0x09dc1414,0x43a21313,0x43c93537,0x060765fc,0xdf5f79ce,0x6ff3207a, + 0x85d4cfca,0x6f18b1fa,0x63e995ab,0xf5c4272e,0xa82b3002,0x121a09e4, + 0x97147f16,0x82b65d1b,0x20a7fe26,0x4993c20c,0xe6716726,0x99c9cb98, + 0xfeb440a0,0x5a02d673,0x251b4bc5,0x3f3fa9e1,0xa05338ea,0x75dbc474, + 0x7b09f6cb,0x3cb4044b,0x80434609,0x6767da18,0x098ceac2,0x97851422, + 0xb55235ba,0x611bfbb2 } }, + /* 86 */ + { { 0xf00ad2a1,0xbdbaa55e,0x14a290d7,0x29efa85e,0xe92b1694,0x3b4a4768, + 0x11ec8130,0x67111bcd,0x88bd27b2,0x0e425702,0xd9a03c06,0xf28cf2a3, + 0xf318884a,0xbb7c8d2d,0xe3aaeb20,0xe2ea1462,0x43b85d77,0x33535804, + 0x554ee9bd,0x81ee4482,0xe6aa198f,0xeb2eee9e,0xc26c5944,0x7a5aa804, + 0x82ab167c,0xa0ef2da5,0x02fe21a5,0x5a2ab476,0x3370298e,0x169cb3b8, + 0x0eb3aa8d,0x86e6c544 }, + { 0x0b793d9b,0xede03321,0x1ddb5ece,0xf79fade1,0x68930b64,0xf73fda92, + 0xfe4fd1b2,0x06aad97d,0x92a4dc88,0x073a5b1d,0xbc976d75,0x8af8cbd8, + 0x63ce26c0,0x60b4abb1,0xdcb1fb06,0x9c8300a9,0xda95b3d3,0x335a594c, + 0xb37eac87,0x1f97d7d4,0x20eefaab,0xa3d2eba2,0xf3e828c8,0x3258c906, + 0x85ab7781,0xc832616f,0x8c28b617,0x72597192,0x3233b82d,0xcd7196bc, + 0x19fa126d,0x83867eb9 } }, + /* 87 */ + { { 0x22474edb,0x774fe73e,0x1a84e1ae,0x2a766394,0x9c6dd6e3,0x270329ad, + 0x14f8bf5d,0x00c4a415,0xd2267b90,0x3ce2ea37,0x11d24fae,0x12753015, + 0x263a1b78,0x7c14d854,0x1ae0b206,0x20c8401b,0x081f49fc,0xf32a011b, + 0x959c6df8,0x1e8123fb,0x800e1d06,0xa328dc7c,0x24259a9a,0x5876a378, + 0xb7ef6c37,0x23ada8b5,0xa93d4c9f,0x023f6b6e,0xffb6389f,0x89f5414d, + 0xe628b39e,0x4b26bba2 }, + { 0x5d318454,0xd30b1cb4,0xd7436cb6,0x123b749f,0x568a7461,0x3110c726, + 0x1c84fd1e,0xc85de123,0x08403d55,0xa5f8d6e6,0x9b1fabf8,0x395b6e13, + 0x3cfedce0,0xfe6d68c3,0x94b91110,0x1d90381f,0x2dcc6eb7,0xf0a8ea81, + 0x7e90ca2b,0x59e80413,0xc8a25c5a,0xbeb5fc07,0x5d84663c,0x009c253a, + 0x910b6a7c,0x00b15073,0x4108f8d5,0x8607da4c,0xcb901e65,0x02c3d9c3, + 0x2c9615c6,0x4d697bc5 } }, + /* 88 */ + { { 0xefa8fb40,0xe0db1ef0,0x5ba3989c,0x29021c5b,0x809d19df,0xa8d6fb15, + 0x4c1219e1,0x6b787b73,0x14ef05e2,0x6417e168,0x8f9796e2,0x449342db, + 0xbf84421b,0x2f878a5e,0xe94a4536,0xe71916d7,0xae119693,0x9818bba3, + 0x5768804e,0xec674be9,0xf8424f8a,0x0a26074c,0x466ce6ab,0xdbc93b9d, + 0xc920078b,0xb3f15a98,0x3870f1a3,0x9d10fd0d,0xe4e785a7,0xa61241d9, + 0xe6c8cd80,0x76ca87a1 }, + { 0xe02e48b7,0x4357fb56,0xcc09e9c6,0xfbd14b13,0x24069cf0,0xdb5f2435, + 0x2c3b01a9,0xf878165c,0xe6956dad,0xe549e7c4,0xbbd60b68,0xf2fe9538, + 0x059dc653,0x952f856b,0xb377fe9b,0xd3f60225,0xbfe908c4,0x6a0c7328, + 0xbc8f5f2d,0xce6aa2d3,0x24425050,0xf7213443,0x3d3b3ce5,0x17e1266a, + 0xc1677512,0x75b5e43f,0x37fb894a,0x15927062,0x2be3e375,0x15260753, + 0x6da3b7be,0x27e7f2c6 } }, + /* 89 */ + { { 0xe6a15883,0x638f65ad,0x66afdb33,0xd4a7e68c,0xd3f12de5,0x6207b6ab, + 0x37b87810,0x1c6ff950,0x64acf6d3,0xc0d44cb2,0xf2be78c2,0x163ac601, + 0x1636980e,0x1c63cc5a,0x95c9349b,0x3e92cfe8,0x41ec7220,0x7738e0d8, + 0x2d5fa961,0x6169d764,0xc3e028e9,0x2aa776c1,0xb16d5409,0x93dc5646, + 0x706df4d9,0xa0b27fb5,0xce9c6b97,0x9e991170,0x53c85f40,0xea8e42be, + 0x83246528,0x02e96437 }, + { 0xae78ea1f,0x91540add,0x7b670e96,0x51a1b74d,0xf7006826,0xf9936441, + 0x7d7520c7,0x8f97d6ea,0x69ce12e1,0x0faa6a02,0x79208342,0x2590aca8, + 0x75614436,0x7a483863,0xf381408f,0x07c6149e,0xd7853406,0x733bf584, + 0x9abbb6f7,0x8761b010,0xf528a09a,0xe4eb249f,0x2e00ae3c,0x08781ed8, + 0x2178effa,0x864c1b25,0x9d513a7e,0xcc1e62a2,0x1919062f,0xedb8b94e, + 0x4f16527d,0x739f53da } }, + /* 90 */ + { { 0x924adc5f,0x7a5f4a88,0xa818f56d,0x95646c16,0x7795f954,0x0ec49129, + 0xd19c5400,0x2b48753d,0x205912b4,0x16fa236b,0xe87a4946,0x6b3d65f3, + 0x045fd066,0xa7174a01,0x12a5e140,0xb6350313,0xa96b8623,0xa79c4b44, + 0x9ab003d5,0x7a339d65,0x3826f31a,0xc72f30c6,0x6f7090cd,0xb4e7390c, + 0x906ebe24,0x59ac6c36,0xbba4505a,0x39a7f06d,0xc58c413a,0x839991e1, + 0xa20e0e84,0x020c23ff }, + { 0xafc74661,0x120e4ada,0x277fc065,0x37bbcf63,0xb6dce799,0x41049cf6, + 0x7b161ba1,0x5b8d6b53,0xa9610fb2,0x22218431,0xdfdde769,0xde9ec9d1, + 0x42d80630,0xd32bfa4d,0x6244df4b,0x3885702a,0x45592dfb,0xcdedd1ed, + 0xfb4e01b8,0x0e1df45b,0x86e215b0,0x8f4bded2,0x6a937e6a,0x80935487, + 0x8130f723,0x415278ba,0x38a821f8,0xc6dc4692,0xfd8b4f8a,0x2207b119, + 0xf9269cef,0x76e7bf53 } }, + /* 91 */ + { { 0x27ebd187,0x5f128428,0xb65aadbb,0x8d3320ab,0x72258695,0xb042765a, + 0x8f0986ab,0xda3f33f9,0xaebff503,0x411807a7,0x825f71a5,0x25c776ca, + 0xff7df24b,0xc0de7bed,0x165f1fb4,0xda8b0f42,0x731f3ae3,0x5f3ff737, + 0x193e0a52,0x4cd1d7e7,0xb6b3ba46,0x8df84aa3,0xaa1f3782,0xba84b897, + 0xe7733ac7,0x6e7960cc,0x50981a21,0x4d46d6ab,0x7cbb80ed,0x1ec12c25, + 0x2b96ef09,0x79e7ad27 }, + { 0x8f30caae,0x3cd970dc,0x0a6ebef4,0x85cabcf1,0xc714616d,0x63c1863e, + 0x519e3a98,0x1c50db0b,0x64cb13d6,0xf39b8963,0x22547b69,0xdf67d81f, + 0xd67db0cc,0x7157abb9,0x889491b7,0xccca25ba,0x7a27e0dc,0xf689207c, + 0x0fd43281,0x34ae8fbe,0x5720ec09,0xa5d91f73,0xcdfd7bed,0xb2f61909, + 0x4a039e32,0x1ec10232,0xdb0d8fdc,0xd3c3d65e,0x4fe5005d,0x32c916c8, + 0x4c0bea94,0x7f8c37ac } }, + /* 92 */ + { { 0x43ac05e5,0x33ec1e54,0xcd8d3825,0xda4a4da4,0x88bf9e2b,0x86d88c0b, + 0xb53811dc,0x34d71dd0,0xa3c3aba4,0x655040d2,0xb61611be,0x2bc40949, + 0x279a4fa0,0x1c2d426e,0x3b065ac3,0x535a5aa2,0xc52ea890,0xdaa8a32f, + 0x9fddad22,0x5a5deca7,0x2ab3b26f,0x911f05fd,0xf37cd81e,0x5dace7db, + 0x90d16b8c,0x0e0e44e7,0xe4f5894e,0x15e68aed,0xfc92a74f,0xafe04999, + 0x970e7c2f,0x1d7703aa }, + { 0x3f0062a9,0xa8a4c81d,0xd96a20ba,0xe31eb2b8,0x864bd101,0x66dd98df, + 0x4413b614,0xba05f592,0xe9a555f8,0x51a67a0d,0x2e4b52d1,0xacc2f097, + 0x7184ab23,0xab5daaec,0x7c7f691b,0xce08b43e,0x76c427f4,0x520e530b, + 0xe423ebdc,0x7d352069,0x34df14ce,0x6b5e39e8,0x446305ac,0x3dcbf295, + 0xfe34cdc1,0x682cb2e1,0x111f5afb,0xd4ac45d1,0x47f296f9,0xc5ef63cd, + 0x93c20871,0x0a2c40ec } }, + /* 93 */ + { { 0xaf5747db,0x09bc384f,0xc06ab86b,0x3bad6086,0x9e7c1547,0xa406882e, + 0x55977abf,0x2d5326d1,0xda81deb0,0x063a9a05,0x524b6111,0x9a86e4a7, + 0x4ab2eb90,0x1402f87a,0xd5c600ba,0x7d0721d4,0xf289fdbf,0x1a2fd9a9, + 0xecde6f07,0xf5dce66d,0xdab9fa73,0x62171277,0x6c474bab,0x6d2dc49f, + 0x76eed033,0xdc017e1f,0x4da825d3,0xb97175c0,0x54b05e43,0x6c297e3d, + 0x56c9c87e,0x2efb4546 }, + { 0x8b21c064,0xa4712b00,0x4a70629e,0xd186fe42,0x9b74f0af,0x6435b340, + 0x7ec9e629,0x6965aa43,0xc4c60d08,0xdda14673,0xbf3057aa,0x0b656670, + 0x3ce86f60,0x7f05e840,0x04401a16,0xc05073a9,0x294e607e,0x16b1e638, + 0x69cf7046,0x20783252,0xe8ce7d3a,0x2941141b,0x7577053d,0xd38ad8d3, + 0xcaa6630d,0xdba68fb3,0xe9504350,0xecbeaff1,0x1d2d760b,0x9f5166d5, + 0x462891e4,0x337532ce } }, + /* 94 */ + { { 0x3a00bb9b,0x3f111853,0x45f66685,0x2d2ffbae,0xd4aee24d,0x9ae11a85, + 0x0341856e,0x18ba1e1b,0x2731349f,0xa9ac8178,0x545715b5,0xc13dfd4a, + 0x5daad2ea,0xa5f7423c,0x535b76a7,0x30a483b9,0xff873e9b,0x92e9ada4, + 0x723a1055,0x15662d84,0x8edac4e0,0xb935497b,0x39d8fa70,0x61b6441a, + 0x40d1589f,0x1541d756,0xf0a05f0a,0x62994237,0x6bb28908,0xfd8b0034, + 0xd4cd32bf,0x192a2b5d }, + { 0x365ced07,0x63576628,0x05de1d1f,0x029f32fb,0xbf40a7aa,0x6d17b9bc, + 0x9bb50a47,0x1b1b2a08,0x795a6278,0x9389abbb,0xb34fc19b,0x52cff60f, + 0x387d8739,0xf3ab9492,0x6920ccd6,0xa8f053e6,0x63a9b4f0,0x3ef2dd4b, + 0x51e82129,0x9ab0ede1,0x0838bfa1,0xafba0c0b,0x9ffc11be,0x2bd5a7ac, + 0x95cc0878,0x058bfd95,0xf8c2f0c6,0x686d48a3,0x1d9b31ba,0xc33abaaf, + 0x3bc0c268,0x632e2289 } }, + /* 95 */ + { { 0x15a1ccca,0x1c851d20,0x7e522bc3,0x4efe290c,0x18eab053,0x0b741d55, + 0xbc85e217,0xae656197,0x01cf8b29,0xae13141e,0x66948478,0x2e2cb593, + 0xc31bd8ae,0xeb57bb0f,0xc264e788,0xdecef5d6,0x9cb96d86,0x6fa856cc, + 0x279183da,0x2db16813,0x383d796a,0xf03f3820,0x1d0c6fed,0x58a456ff, + 0x8a6abd9b,0x25589805,0x83f96f19,0x339f52c5,0xda7e9ea7,0xcf6ded8f, + 0x5d1ccd45,0x68c3d9c1 }, + { 0xe6b392b7,0x67e26265,0x775d9509,0xcec1d9bf,0xd76514f7,0xe16abcd4, + 0x0de72e1c,0xd86f59b2,0x1adfb033,0xa66e43cd,0x05e457cc,0xdb344340, + 0x5681daa2,0xb67a7916,0xf0114731,0xc32e7bab,0xd3b1e961,0x066fe16e, + 0xf63d26e6,0x924e298e,0x541add6d,0x9bea0dd8,0x9982f971,0xef9500df, + 0xc5f076ac,0x5c876e63,0xb23d396b,0x55e12ae5,0x2ec6747a,0x09efbb36, + 0x233286a5,0x8f2055ee } }, + /* 96 */ + { { 0xb82c1af0,0x4a4ab9e3,0xf2cae264,0xfc65e9e7,0x60187d46,0x4feaac0a, + 0xe393b363,0x27d3f335,0x819bacce,0x9c9f7c00,0xb8aa6611,0x3f7418b5, + 0x372aae95,0xffa94557,0x8db38589,0x937d7804,0x6f1fbc1c,0xd10c86df, + 0xa2f0a0ce,0x48aebd89,0x367439eb,0xae5d5fa2,0x3f17d2d8,0x103a6a0b, + 0x411d9894,0xf233f68a,0x218b67a2,0x7fece8b3,0x2319bf06,0x0422540f, + 0x340d322e,0x1292c8c9 }, + { 0x0386463d,0xf5eb5587,0x0371d97f,0xd4bbc2b2,0x0b819c5a,0x1b364571, + 0xcf04ad41,0x0cbb42d6,0x66939ec1,0x5d819c76,0xa01847e7,0x8745ac13, + 0x1c7232e4,0x4f704b02,0xacb05780,0x2c9e58a0,0xb561e295,0x9523b8b3, + 0x79f9ba35,0x3384df00,0x1eaa9628,0x78231fc2,0x8aea2b90,0xa2eac54f, + 0x30d1c263,0x8075ed77,0xfb339000,0xacb44ed5,0xf011293a,0x92546ac2, + 0xeb821764,0x7c78762b } }, + /* 97 */ + { { 0x067902b6,0xb8f7d6fb,0xd1735980,0xb2823a43,0x59741ddd,0x062cfb12, + 0x4033f95c,0x6e391b07,0x68589b8c,0x3831d0a3,0x522290f2,0xe3474d49, + 0x222e1f3a,0x4dab14d6,0x53f08d39,0x8f00fcde,0x707f28f5,0x559917ae, + 0x068e607c,0x166aa0ba,0xd7e1f824,0x602713e7,0x4d6a328f,0x7c255540, + 0x9890cd2a,0x0d2e3264,0xeca0b20a,0xf2207944,0x52f4e09c,0x5c98dc07, + 0xd84de81d,0x69403504 }, + { 0xe5407206,0xf8b7b366,0x0d88fa8c,0x1ecf54cf,0xf7272e6f,0x6fefe548, + 0x81ab4468,0xd6531372,0x4e474408,0x52cb5f0e,0x6490737f,0x9e426b3a, + 0x4980d071,0x2576c19b,0x0f272caf,0x91f34628,0x468f31c9,0x78e60a4f, + 0x90844d89,0x8776a329,0xb951582b,0x8a55700c,0x14b1adbf,0xab1af365, + 0xfbd343ef,0x22ebff92,0xb7d81f34,0x32f9fb01,0xba6b30e1,0xad850e06, + 0xbc5f9546,0x6da9e027 } }, + /* 98 */ + { { 0x5c9490ce,0x21eee4c2,0x0df68381,0xa96ec4a3,0xa4a9368e,0xe6c607e0, + 0x4bc262f3,0xd8b0492a,0x460c34ff,0x0846a210,0x28df33cd,0xf7ff7a64, + 0x21827612,0x10c55044,0x149bcd01,0x9d25fce9,0xcfc613dc,0x725611cd, + 0x97f51ce5,0x159f7e88,0x4e8c08b5,0x3fa3bf31,0x75e7538f,0xea156115, + 0x91c84020,0xd1e0a951,0xcf02ad0a,0x0d2268ba,0x058b8e5f,0xa04c6ac4, + 0xb3515912,0x773b40b9 }, + { 0x3631cfd2,0x00ff2cdc,0x807737bc,0x14c4c2d3,0x338a5270,0xd600616a, + 0xb32cabde,0xd0e3306d,0xa70b17ca,0x336738ea,0x79f353ee,0xf2f4aa8d, + 0x576f3ad3,0x712f6ad9,0x89b2bce0,0xe4279852,0xda92ca30,0x05d8f94d, + 0xd8492dd9,0x9891d475,0x4d15e4bd,0x3e06a5ca,0x254eabbd,0x4725d4eb, + 0xc0ed513c,0x31394ace,0xbbfaae6c,0x7e0f9859,0x833fd137,0xdc125546, + 0xc56c4f75,0x12b46385 } }, + /* 99 */ + { { 0x932951de,0x810dbebd,0x5aa69c94,0x96959d42,0xecb2f08d,0x5fc49c04, + 0x2250b82c,0xac74f0cc,0x3aec4e1d,0x96a439a5,0x90499acd,0xc33cab9a, + 0x54d9b3af,0x2fccde66,0x3863ae8b,0xf4af285c,0x46febf88,0x2373373e, + 0x3c9ab7ed,0x751d672c,0xfe12020c,0xc1c51130,0x52f3e56e,0xad82402f, + 0xa4a64a81,0x3489ab7a,0xd9f163f2,0x0a1fb661,0x0e553317,0x17c69be1, + 0x7d88d417,0x61c1935e }, + { 0x3492ae43,0x2e722d9b,0x0538f05a,0x1ef89d95,0x200aab63,0xae77e588, + 0xeba4b117,0x2872c120,0x3a461cb8,0x5c2432c8,0xcb938f26,0x315b3434, + 0x8c4c7dc0,0x05bf2ac5,0x596b378d,0xd2e501dd,0xcb890c30,0xa8506c9f, + 0x7c361f0c,0x3d0af461,0x5a35cbae,0x21f7b718,0xf3fc0138,0xbd1035f1, + 0x8b248edf,0x74628af5,0x48c9cae0,0x8d6421d0,0x2ca18773,0x75e3da39, + 0x71d3db94,0x27ad0df2 } }, + /* 100 */ + { { 0x305b5aed,0x9e3bda79,0x5998d6a7,0x2c67d4a4,0x0f7eb700,0xc855e1d3, + 0x147d1c44,0xc18a7e9e,0xc89540ed,0x3ea99618,0x7e6bfd20,0xa53be20a, + 0xecc14437,0xc9487e64,0x34ef85c6,0x72979207,0xd5e1ebd5,0xfa0d4e71, + 0x4d48d6b6,0xfda2b1e6,0x66e200d4,0x782a1e05,0x5a5366a1,0x2a3c70da, + 0x1a473738,0xfe3fbd2b,0x7fe020e8,0xd7ef8c06,0xeacfb665,0xec686fde, + 0x6dd1542f,0x5d9b5e27 }, + { 0xcb3e472e,0x3637c5a5,0x30a1405e,0x2153d927,0xb4498558,0x009992e5, + 0xf39a0851,0x18f00ccd,0xb5c6c560,0x26237c11,0x1343540e,0x418ed408, + 0x7e7f3184,0xfef7cbf0,0xbf48576b,0xecd92366,0xbc94c91a,0x1b75be1a, + 0x4a162276,0x8e1778de,0xc5c6bcb8,0xc52e57d3,0x5ab71858,0x5cc382c7, + 0x3f6e39f9,0xe12c2c28,0xd62735fc,0x4c7e0ef2,0x835a5996,0xe071deb1, + 0xcbb8c766,0x24f891cd } }, + /* 101 */ + { { 0x6778c1e2,0x24ef60bf,0x00d5be5c,0xff49c03d,0x2f01a09f,0xec11986e, + 0xae096e58,0x59a728a4,0x7077984c,0xaabbcedb,0x870ca5a5,0xfb473bd2, + 0x4de30e3d,0x8c928c61,0x4f67abca,0x3fae7f9a,0xec21a9cf,0x83c2b2eb, + 0x9cd9b5de,0xafa70d62,0xc60b18df,0xadeaea59,0x4049b54c,0xd5fef7be, + 0x6dd310e3,0xfceebc76,0x8f6321cc,0x7748efe3,0x18ee8af5,0xfe9c32b1, + 0xd42df612,0x863ac3cf }, + { 0xb85a2fe2,0x0a36fca7,0xee429dc6,0xf3e70d08,0x141c3944,0x8c9ba209, + 0x67272a0a,0x306a8106,0xf968bd06,0xe69a1555,0x153c603d,0xb86f7e47, + 0xef56e4fa,0x9706614a,0x98780b4c,0xc0dc36b8,0x3a1d3263,0x43657fe2, + 0x435522c9,0x01f97a86,0xedfef679,0xd91897f6,0x6daa17a0,0xebbe31d4, + 0x85accfbd,0x6f179100,0x8f9fc1de,0xe0da6e32,0xe1e7142c,0x1c9d53db, + 0x8b86725a,0x3e3f1b1e } }, + /* 102 */ + { { 0x7b7fbf05,0xb7ea15c0,0x1f1a3882,0x992f11b6,0xd1dcd1bc,0xc9ddd95a, + 0xad0f7e8b,0x31f5b7fa,0xfca7ab79,0x2936e5eb,0x19a55be6,0x30f417dc, + 0x43cde554,0x1f6f4e43,0x82f044bf,0x971f5e65,0x4288c408,0x73c3b8e4, + 0xb807f575,0x61aac59f,0x818b58f0,0xa64ee2dd,0x97a3b0d3,0x6f7a0a60, + 0x0394b058,0x8b85ecc8,0xbfb3517d,0x9a059474,0xa79c3f06,0x89ad5977, + 0x700a8025,0x81208ed8 }, + { 0x14c4ce37,0x10935099,0xa1aa48a6,0xf34bb843,0x580d58e8,0x86007024, + 0xb375b8ba,0x6db42c49,0xed3bde83,0xac365524,0x649233b6,0x5521e1b4, + 0x64dd946f,0xbc7cc5d5,0xbfb5b6ae,0x9c14b035,0x0146c1a3,0x7f22ba18, + 0x872214f5,0x0b62fbbc,0xb4921764,0x3acfd7f7,0xcb4d6df1,0x5ff10da1, + 0x62600a91,0x660e2620,0x81d9167f,0x7ac7da9d,0xb6e7a199,0x6e8e260c, + 0x80deb3c2,0x44383fb8 } }, + /* 103 */ + { { 0xe44f9af6,0xe107f01d,0x8cb1fa1c,0x36381a4d,0xfb7dd493,0xe65be3ec, + 0x26a8839f,0xd0b8435a,0x3ec789d8,0xee60f915,0x2bcc5e1f,0xe25fea50, + 0x7e44a81c,0x0477c0c5,0x230ba5b8,0x349e9f83,0xde180dd9,0xdd42f32f, + 0x64a3d11c,0x8b039eaf,0xbeb7083a,0x80ef884e,0xf12742cb,0x288e60c4, + 0x720a0262,0x44156cc5,0x7253b77f,0xcd547de6,0xa6013a59,0x9829a6ec, + 0x0d548445,0x8aee708f }, + { 0x32c54409,0x18f22d9c,0x75ebaac4,0xa9ebfa46,0x86284981,0x90e2e928, + 0x6b3a8e0c,0xd0201f6f,0xbd77641e,0xc973016c,0x70170575,0xf926f2f0, + 0xfec0ce01,0x4984048f,0xf319d304,0xbf696211,0xc91a88c4,0x74b5c844, + 0xe0030a82,0x4c40fbce,0xe4f6d521,0xbed67525,0x29d67d1e,0xaf7e47cc, + 0xc21d3536,0xfa307db8,0xbbb29405,0x56b6c46a,0x033e805f,0xf059a7e3, + 0x6096a5a0,0x970f61fe } }, + /* 104 */ + { { 0x1bec8e4a,0x1bc53d23,0x35a6034c,0x8809ac14,0x509e464d,0x4ee081da, + 0x8a488235,0x496ae1fd,0x325864b6,0xa1ae9863,0x74cd069f,0xbaca13e9, + 0xb1d8a6b4,0x3738cc58,0xe76b9da4,0x5fa71f58,0xc7eb16fb,0xc919be88, + 0xad4e429d,0xf5c8f13f,0x2499f9ed,0x4583b671,0xa10d8bd7,0xbce20115, + 0x5790bb7e,0xf66d7605,0x482b78dd,0x9316aede,0x75f855fa,0xe0d8fb2d, + 0x5a7dcca7,0x404b5b94 }, + { 0x517a15c7,0xf9ee682a,0xef880202,0xaae4cfbc,0x5106a354,0xcee2c139, + 0x170febe7,0x5de60192,0x73d0c54b,0x589e39fd,0x8c9092b7,0x195c7135, + 0x0a7bfe5f,0xcb7ed53f,0xf61cc979,0x2bd9242a,0x5395f7d9,0x8d2ef16c, + 0x70b32f09,0x0d4ac1ca,0x52d185c1,0xa587526d,0x942d6195,0x2932b04a, + 0xa500b0ac,0xfe25a979,0x562fd230,0x5fa1f4ae,0x20da253c,0x60f55af2, + 0x83146002,0x7faa11b5 } }, + /* 105 */ + { { 0x6e402149,0xb0ba4f0c,0x963cc119,0x3584cc1d,0xa6527476,0x7740dc1a, + 0xc95715f2,0x3f77ff75,0x3f89fb0e,0xb2f234ad,0xef9be3ff,0x55159032, + 0x04237e82,0xfc9fb21d,0xa153ed93,0xeb2eff38,0x10041d13,0x89d53ae0, + 0x7f1bd828,0xcf2e545b,0x43953ea5,0xdd4a27ce,0xd85e75c8,0x00d2e5d4, + 0x241be1c3,0xeb93ed62,0x0242032d,0x1e53f25f,0xc3a4e701,0xb9957636, + 0xed98febf,0x14b63a52 }, + { 0x71c43336,0x7610b553,0x23a4824b,0x19dfd4a6,0x0286051b,0x7b97a2e0, + 0x8f5f1edb,0x86abbb9c,0x9b67daad,0x67a57d77,0xcd5ffafb,0x8ace506d, + 0x89ac3c63,0x85da9f95,0x75a3d150,0x081cbaa8,0xe9346ed2,0x03353d8f, + 0xa1f9a02d,0xb2ab61f1,0x3a659c71,0xb0cb0937,0x4f5df8a1,0xb7e0e30b, + 0xeb7d5a1d,0x77c4c741,0x728e5cf0,0x8f046c9c,0xf7c171ac,0x32dd0bc7, + 0x836d2655,0x02485873 } }, + /* 106 */ + { { 0x75a4cd8d,0xcd40dd23,0x97bcba78,0x132ca433,0x258d61f5,0x30c5cd84, + 0xda1e8e68,0x0a7ec059,0x1d65d40a,0x07a8f171,0xf4350d76,0x869e655e, + 0x5983ae42,0xb98ce6f0,0x9d8bebd0,0x7b61391d,0xb1ba5d49,0x3a529e25, + 0x1f6b2cf6,0x46f732e9,0x3fa3b629,0xbd66ec6a,0xc3ef0ed2,0x397950ec, + 0x5f08b476,0xee9008cb,0x965a0e2e,0xfd6be425,0x1177bc87,0x78ed513c, + 0xfe512dae,0x6798cedf }, + { 0x1b97c5c6,0x49e3f8fd,0x78c3b33f,0x39fbab3e,0x40f595ba,0x44274412, + 0x5d7d4376,0x174225b9,0x79c44777,0x880b3fcc,0x3296b245,0xdc3aca83, + 0x1734e184,0x55913df7,0x9c934472,0xa4db23d3,0xd1420a11,0xcebb3733, + 0xf3608bdc,0xb9d20cf9,0x30cfe13f,0xa618acf6,0x5f30874c,0x75f06b31, + 0x9f0005a5,0x506efe7f,0x01bfc9db,0x8aaea78c,0xf78e7c41,0xf9179255, + 0x52e96395,0x3ea7aed2 } }, + /* 107 */ + { { 0x5b06ae25,0x98617e04,0xcb5750ef,0xbcac148d,0x604c2ba2,0x91ea2f0e, + 0x76b78975,0x00c19f6b,0x651da181,0x79b9b6d0,0xc945705b,0xf3225beb, + 0x5c005bf1,0x30b435f3,0xbc24d86d,0x440b4482,0xd6373777,0x2b8f0996, + 0x1c44b4dc,0x65fd6c56,0x30906999,0xe9405ee6,0x08aa1ec1,0x19ff0924, + 0x3d2f2895,0xeef3246a,0xbc746797,0x016c3765,0xd0705f7e,0x62d2569f, + 0x05250044,0x6a8ad39c }, + { 0x46be7282,0xe45f020d,0x21380f12,0x9405afed,0xd5da6ad0,0x4cdca5bd, + 0x7f8be61e,0xc2d6f184,0x596b8178,0x20132953,0x7a8df954,0x8d3b1e7b, + 0x39572b4d,0x757c61bb,0x80cc3b56,0xd749b57b,0x37b3ffec,0x9590ff93, + 0x145dc94d,0x39bbb653,0x2335e573,0x70c1c606,0xf763feba,0x9c2e72d7, + 0xcc61b732,0x4768e424,0xaa73f2ca,0x777d2fa6,0xc5cb58cd,0xdee4dbaa, + 0x9cfae1aa,0x1a181179 } }, + /* 108 */ + { { 0x77575ed0,0x6f6ff62f,0x7d1da99b,0x18f14fa9,0x69efd7f6,0x2e72aefb, + 0xddc28633,0xc45ab4cb,0x586c5834,0xb0e20d48,0x39775dd8,0xd397011a, + 0xf4134498,0x0130c808,0xf5115ed8,0x2d408eba,0x0260ded9,0xc506a05c, + 0x19cab911,0x9e5b7362,0xe8693a86,0x4cf508c6,0xcc773617,0x4e71245f, + 0x95d89ca3,0x2f71aa1f,0x607bbc98,0x4bba7c6a,0x212b7fd2,0xf3a515e7, + 0x9230f5a8,0x7d2ddc75 }, + { 0x4ed2cae8,0x3d05816d,0xb9c00377,0x4cf6bc7d,0x646b08d4,0xc23e98e6, + 0x4b9c0180,0xf9ee6c61,0xef9179c1,0xe11c9a13,0x8ed9688a,0xa5b6147e, + 0xd06670a7,0x7afeb648,0x17685275,0xd670333c,0x75f9e8f2,0xa89dd969, + 0x37a68ade,0xbb57228d,0x454cb186,0x21a05d5e,0x063dd550,0x4810158f, + 0x4cb6caf3,0x92dd4f08,0x7854abe7,0x70c4d852,0x6e729d76,0x845969dc, + 0xb1bf40ba,0x5a52f87a } }, + /* 109 */ + { { 0x09ecacbd,0xed019e91,0x7b89bdea,0x6544023d,0x5707371e,0x7cc51f0b, + 0x16c8e217,0x14832b04,0x81259ab5,0xb1aa6682,0x23e361d4,0x6e100f92, + 0xe3a95c2a,0xe593eee9,0x16c10e26,0x699b6bbd,0x9473a13f,0xad487873, + 0xb274987c,0xf1c14dc5,0x2559e2e9,0x57dc0075,0xc3d47ad2,0x8449849d, + 0xdd527793,0x83df278a,0xeefd5b99,0x770e3ec8,0x76bd02a0,0x2ae58446, + 0x3e705ffe,0x17f02764 }, + { 0x29abea1f,0xdda4010d,0x2407ac4c,0x636b9695,0x0433218b,0x96a60129, + 0x163d534a,0xf221fc3b,0xccc20565,0x05ba15be,0x96285577,0x1238e54d, + 0x878804d3,0x1b144257,0xa89a9fe4,0x96fbf304,0x4be642b1,0xc8a7f06c, + 0x6e2b085e,0xdd1a20e8,0xff4a591d,0x8f7f27c2,0xa4a343b8,0xc17b0753, + 0xbb173d4d,0x684b1e88,0x3dc07bbe,0x3accea44,0x4c441d77,0xdb15c88d, + 0x53e5957e,0x0ef0309a } }, + /* 110 */ + { { 0xfa8e5b60,0x4fc25721,0x691c0bb2,0x646938ad,0x0b0a2248,0xe46d4b76, + 0x7de16877,0x863f9ac2,0x2721c630,0x503bb6ef,0x0b67fb02,0xf8c199df, + 0xe07abd39,0x78c1ed72,0xb32f0dda,0xcf9deb7b,0x6c3c89f3,0xaff726f0, + 0x1972225a,0xb7008b2d,0x4f145f5c,0x8f5a6117,0x457c4f37,0x4e0e6f8c, + 0x1c453c64,0x8bbdaa44,0xa6e92c80,0x57be326d,0x5d773561,0xa9bc3fd9, + 0xbb37b72a,0x3d3b6cc6 }, + { 0x9722c880,0x6e6f12cc,0x286b6889,0x3a1b6ae7,0xad2fafec,0xba1cc09b, + 0x43bb8bef,0xad64ad7a,0x97c3f4c3,0xa5af6a00,0xc353a91b,0x2afcb0d9, + 0x69ccbf6b,0xca13fcab,0xf2abc190,0x699a1391,0x23a247e5,0x2dbd5542, + 0x95488d9a,0xe206180f,0x1244cc3c,0xba9e7bff,0x87d3a365,0x29297abe, + 0xfa4ca5e2,0x4054fa38,0x67be1b6c,0xb390623d,0x78f41a44,0x1fa67c57, + 0xc7b544e7,0x2e946e43 } }, + /* 111 */ + { { 0xc60934ae,0x2980fddf,0x164206d1,0x2c3e7eff,0x416ed75a,0xf75e7f96, + 0x5cd0b2dc,0xfac60cf3,0x1faad87b,0xddc4bece,0x9849e5dd,0x753fa87c, + 0x2c1bf1ae,0xc5d516a3,0x14732b4b,0x565dbea8,0xce48696b,0x007ebe3a, + 0xcdb97694,0x40ca74d6,0x65e4e7be,0x3f5cd270,0x3aac4ebc,0x74847c01, + 0x43d6c3a1,0x6762e034,0x467a076a,0x690d8c95,0x1eda677d,0x768d78d6, + 0x0181d8c2,0x0997ce55 }, + { 0x965a0b81,0x9297746c,0xe5e12dfa,0x48b58be6,0x715f437f,0x5573b3c4, + 0xb565c459,0xe425e907,0x1582797c,0x4f43f512,0x8ea5474f,0xe5dafa6f, + 0x13de04ac,0x2aeb8fbe,0xe8a07c83,0xed7f95f0,0x662c09fe,0x3e012a6e, + 0xc742cf17,0xbf96e9b8,0xe28a1c45,0x8ea5759a,0x5cf4e2f3,0x475941b4, + 0xf901a019,0x7dd3c02d,0x70916b2e,0xe7a4deea,0x2fa9b988,0x50b272b5, + 0xd0917fe6,0x96f9f09f } }, + /* 112 */ + { { 0x2c310a96,0x78e8aac4,0xf7a2a734,0x32a98303,0x23962207,0xc46ca83d, + 0xd9541280,0xad131e6e,0x2cabe911,0x5791fc5e,0x841b6c68,0x50cb77eb, + 0x3d3c8878,0xaff93dea,0xf1007bce,0x06541f1d,0x55cdf1fd,0x4ee729c2, + 0x323e3972,0xe0f71317,0xad4d08c1,0xa2de7a41,0xa35e22bf,0xa9912abf, + 0x89b03325,0xa050122b,0x06514d4e,0x8b9e51f4,0x79d3e0ab,0x423c7aad, + 0x40b8fea5,0x71998e26 }, + { 0xceb6ed78,0x40140fcd,0x18534516,0x653cf377,0xe8d60dcc,0x0450b65a, + 0x9dac55f8,0xce6c1a76,0xae05686c,0x8a96a92d,0x12712562,0x2fe44762, + 0xa4f39425,0x747bcb50,0xfc531fc2,0xf0ec6ff2,0x10fe9ff0,0xc97c3447, + 0x9c792cff,0xfb488783,0x026fb019,0x552c5248,0xd804c290,0x4001a29c, + 0x35c8ca73,0x742b5ad8,0x6ee5dfa0,0xc3781f17,0x3dfa4ab1,0xca6b85f0, + 0x0b0d32ac,0x8389941a } }, + /* 113 */ + { { 0xde067dff,0xc0f062a2,0xbcb80162,0xd4f32690,0x0707a2bd,0x98cd990d, + 0xfae4a391,0x5afc63b8,0xb32ad814,0x684f1b7b,0xf199dfb1,0xb0a2dce2, + 0x48f25848,0x2260e17f,0xc2d5e862,0x7393db00,0x338cf171,0x9e88f854, + 0x02acf522,0x00679429,0x6835af3d,0x19157cb8,0xb8a2614c,0x2faa6f92, + 0x134ec46c,0x04ff95f5,0xfb7a8135,0xcf00626e,0xb37a4704,0x454b3d05, + 0x2694ec25,0x1fbfda31 }, + { 0xc8f69c77,0xfdebb657,0xa3df88fa,0x92a8278b,0xc1fb78b4,0x463b5571, + 0x11c71a33,0xd2066a1a,0x089958b0,0x10c88143,0xcf9d67a6,0xb975c7e0, + 0x73037b8f,0xdaa5d208,0x40bf5861,0x5ee5005d,0x7dba69a9,0x300e6ce7, + 0xc962cc74,0x893c3cb3,0x4cf84055,0x0ac98629,0x225c9d70,0x0a7ef63a, + 0xb91e47e8,0xfe184869,0x8c2f84be,0x1b9d7deb,0xc0e278bf,0x67788915, + 0xc426f19e,0x4f9488ca } }, + /* 114 */ + { { 0xdd51b8ce,0x610dfcd4,0x36230e80,0x08579278,0x36599562,0xedc7ff1c, + 0xe2cae877,0x905ead4b,0xe7967608,0xa1c325d9,0xbd38926c,0x3e39eddd, + 0x5f6f0a4e,0xda92c868,0xf47a0fa4,0xe16f800a,0xe5f60aab,0x50b4db5b, + 0x983853d3,0x3665412f,0x9b79789c,0x64b62250,0x4e0e72b2,0xea560058, + 0xe555c2bb,0xabbd4901,0x17292e11,0x378419a7,0xe174218f,0x6e0b5aaa, + 0x8f796b92,0x688e0684 }, + { 0x313b8f64,0xcdfef641,0x942c7462,0xaef11b7b,0x5c0d8abd,0x067cfb77, + 0xaf4041a9,0x608ea5f0,0x6935210f,0x23d5bd82,0x27917a08,0x5ab904fc, + 0x45d22d21,0x85dbb1fe,0x4d36159f,0xc3d5e509,0x1d39b8f2,0xaebb528e, + 0xf44acef0,0xdd5ca828,0x20c57a54,0x24209adf,0x78f95f44,0x5742b433, + 0xa9337d37,0xd11fa7d9,0xc64cfdb7,0xd66a0c09,0x9bb817ec,0x56e55b8f, + 0xe4c41265,0x1723c7e3 } }, + /* 115 */ + { { 0xdc8b43f3,0x9a6486d8,0x26409e68,0xfc3e0e61,0xd9b46003,0x1889c437, + 0x6284ec7b,0x3a850335,0x6a9dbaea,0x5a3665c4,0xe978933c,0x7bf6941d, + 0x69341490,0x1ed5a510,0x8cb8002d,0x664a7b7a,0x60ed0a59,0x603f76e4, + 0x1f4ebf27,0xc3e06ba3,0xf2c38a7f,0x296ced41,0xcf1db08a,0x2ac18f79, + 0xcde7a3b6,0xc919e882,0xdbf68b06,0x15e77d29,0x4e947cb5,0x21978baa, + 0x7630993a,0x84bf542b }, + { 0xe364f21e,0xc1decda9,0x012e557e,0x0d6cf345,0x588f90e1,0xba246848, + 0xe3b104b8,0x9f6dda4b,0xe3aef57a,0x6bf7a346,0xe8327ea9,0x210299fe, + 0xda95e6c7,0xaa99f487,0xd2cdf645,0x24ff813e,0x8bd414b8,0xd1dbb2d2, + 0xcafa1a61,0x065101af,0x9cdebda4,0x7d9f4b9a,0xe41039e4,0xaf41b395, + 0xc50adf42,0xe3e9e6ba,0x341e9e49,0x4f2133ae,0xcb157f23,0x4968c0f3, + 0xda068153,0x383f827b } }, + /* 116 */ + { { 0x6583ff4c,0x2ec46a21,0x4ad709e7,0x4e645a29,0xc04ca12a,0xdc66e9cf, + 0x9160a7e5,0x82f128f4,0x569c762e,0xbfb227b1,0xc2edb8e7,0xf80c7963, + 0x49a0f688,0xa7dafe06,0x2d14b8cc,0xb7e41754,0x86de40be,0x3a0c5c53, + 0x1db79331,0xf0d05286,0xfbfe071b,0xb902ce69,0x210e9903,0x61e46956, + 0xf703ebb8,0xfaef874e,0xdd5f78b6,0xf668947e,0x5af5ea3a,0x6fe86547, + 0x43f94625,0x3b121f15 }, + { 0x659275e9,0x5b26e847,0x6d0fce50,0x47581cfd,0x8aa3f1ef,0x55f5cbfd, + 0xe484e60e,0x1e7be315,0xfe9698e4,0xd8f1a20f,0x7ab04784,0x25d46da9, + 0x834cdb3e,0xa526db75,0x8d08a009,0x1fd408d9,0x5b5ca816,0xfc004b20, + 0x65e4bbe8,0x5b3e3bb3,0x759bb6ef,0xf50cc125,0xc2fac737,0xf05fa817, + 0xd273951a,0x9ee102d2,0xfecb3367,0x2a8e540b,0x2a6a515f,0x673446fb, + 0x37290c83,0x5505e1d1 } }, + /* 117 */ + { { 0xd15e68a6,0x0c3014a1,0x64dd35e5,0x6f9f0b26,0x03ad67f9,0x18c3742d, + 0xd2c14484,0x74818c0e,0x0d41a3cb,0xc5181169,0xc49f3e9e,0x65c8c83f, + 0x2c279386,0x9b260c61,0xced04e9c,0xf6086fae,0xfd7c4758,0xa7b2cceb, + 0x90297fd8,0x4b3c3133,0x09701ac8,0xca8264e8,0x508b3762,0x9f976a87, + 0x983a8dfe,0x5d582714,0xd9d598e9,0x350d2669,0x0f6fd348,0x85cb89cb, + 0xa574317c,0x617d80d4 }, + { 0x70022b67,0x4cef267e,0x3768b94a,0x80536bb5,0xd2784462,0x3153a566, + 0x38243919,0x49054d44,0x5df78c4a,0x8d11e172,0xd5a1e35a,0x9b252a71, + 0x8171e31d,0x07866c80,0x1b38a00e,0x0a8501db,0xce770236,0x2ed932b8, + 0x8edaf7d0,0xa2d77609,0xb93006e9,0x3aee5dab,0xbbfeb036,0xfaffc8c4, + 0x4e21b38b,0x077b9678,0xdca8e069,0x491fc59f,0x0e938471,0x3f624f55, + 0x7cd1780b,0x5156f508 } }, + /* 118 */ + { { 0x0206e8d0,0x58234e22,0x7f15af32,0xf5f6f5d4,0xd638950f,0xafab7289, + 0x7d4495f4,0x66ec4d09,0x68da80a9,0xad890c5d,0x64f8a36b,0xe4aa0920, + 0x0f4d5c5f,0x799e257e,0x24495e31,0x44c677ae,0xa5b8e352,0x720387b3, + 0x75a287b9,0x703790f4,0xc3c1f2f7,0x54895cc5,0x41a7fa41,0xb8680f9b, + 0xb00b008b,0xfcd47458,0xba6473cb,0x149cc838,0xac9be19a,0x78ed5f7a, + 0xb33765ba,0x5254599c }, + { 0xa21b54c4,0x08739679,0xb6497d9d,0x029ece2a,0xc8488640,0xf14f1a92, + 0xe9fa79d9,0xae48dcff,0x46c208db,0x14b911c2,0xdae3f69e,0x5ab0fbf2, + 0xd1edb838,0x180ac87e,0x188586bb,0x146fd718,0x5467cbd0,0x210eb654, + 0x1667cfee,0xaa239408,0xb73d1a60,0xdb125c1a,0x881c1cbe,0xde685300, + 0x37c30232,0xfe34c713,0x6f3c8d18,0xc6c6070e,0xb4af4e83,0x07e365ba, + 0xdcf82b45,0x22f0a7ed } }, + /* 119 */ + { { 0xea7f1b7f,0xe262791f,0xdcff09d4,0x9c3d8c5d,0x39c7dc58,0x86c2a9c3, + 0x4276e8c0,0x4dad4017,0xe9fe1d56,0x0a918f59,0x2aa810c9,0xb8d79670, + 0x4aa5cdc4,0xeb7a8836,0xe7afa72e,0xfc4c23bb,0x4ac86908,0x4dbb5c9e, + 0x6a0c7e6f,0x37e39013,0x49c218d2,0x855d7001,0x94b324a2,0xe475bc67, + 0x6287a071,0xc98a8dc6,0x5fb4323c,0x395a299b,0x0c0389e9,0xe186c3ee, + 0x16734c46,0x79f81e6f }, + { 0x364f3c4e,0x83f2c1f3,0x1367e14b,0x536b2ac5,0x5933e43d,0x44a6dcfc, + 0x10d961fe,0x34e59475,0x7e3f2aae,0x08234ece,0xbdea7f25,0xcb92e00a, + 0xa791a124,0x1efba4f0,0x1192d53a,0xc2086fd2,0xb51c8af6,0xfec0d0fc, + 0xdc0f1b5f,0x48d1b2ca,0x812dbe19,0xb07a388f,0xdedbdd45,0x40873a6a, + 0xd702589a,0xbc2a1268,0x17e27b64,0xbbf6e3a8,0x6d386e85,0x73ee5663, + 0x9de7c000,0x442ecd37 } }, + /* 120 */ + { { 0x8a2f90a6,0xb4cd1ae6,0x6f5ad0cc,0xf277d41d,0x401d4b8e,0x6a3828c4, + 0xd8376631,0xe817a134,0xf5e1124b,0x142b758d,0xfd6b95e4,0x25fbc69d, + 0xd74a9e3e,0xa30c9f5f,0xd89663ce,0x5ac0f163,0x0ce6386d,0x32a9eef7, + 0xd8ed5544,0x7a690ea5,0x9889427a,0x5de23ff0,0xeaaced58,0x75ad36a5, + 0xd3e18465,0x3514a6c1,0x7f093910,0x3d9162c3,0xe33d56e8,0x5c10add9, + 0x06aa691e,0x85176b73 }, + { 0x28a21e38,0xa32110fa,0x5773d538,0x97b6379d,0x2d020dc4,0xd3697bbf, + 0x961833cd,0x59177593,0xe5fa8516,0x6d7045fa,0x786ab5d2,0x3390f29a, + 0xdc4f5b70,0xac0bda30,0xdcc615c6,0xcca0240a,0xc5146d91,0x8e1f1702, + 0xa72cef87,0xceb472d0,0x0b669ba1,0x84840708,0x7e61aa0a,0x79b08f9d, + 0x4669560b,0x388160be,0x948eb71e,0x23935c2d,0x9431590c,0xd7fd83c0, + 0x6e5768b3,0x8ab154bb } }, + /* 121 */ + { { 0x353c4a96,0x28686003,0x905cd835,0x4e5c60e8,0x8f66f8cc,0xbd591364, + 0x9faccf9e,0xb6b80b98,0xe32639e5,0xbc1c1fae,0x278aadeb,0x2f6396d2, + 0x1898202d,0x00a796d0,0x3a474835,0x18ab548f,0xb31b0e3e,0xacd056c3, + 0x0164512d,0x15ba68dd,0x4b03f3bc,0x203836d9,0xd8f206c5,0xd64eca6b, + 0x9f1779b6,0x931a361e,0x52ab34a8,0xd82690fc,0x92922e22,0x342bb8e0, + 0xe00b02a9,0x1bfcdd84 }, + { 0x75a365d9,0x310b9a43,0x08d8fb03,0xd4ade15e,0xd742df83,0x9c9753d7, + 0xde318742,0xcf7309d4,0x3360ace0,0x1228e212,0xf7669643,0x1043d238, + 0xf90f5a53,0xfc2adbed,0x7b5f9397,0x41d64cb7,0xc446d010,0x5200b30a, + 0x231720fe,0xc3c8642d,0xb9aa2075,0xfcc0122d,0x041eae47,0x856e3b12, + 0x68c876a4,0x45864455,0x233606b1,0x1a1c7842,0x227757bf,0x9b766d1f, + 0xf7b9d4f1,0x25b78a3b } }, + /* 122 */ + { { 0x156707ce,0x90835718,0x4314f90a,0x9bdc2398,0x8be57dbd,0x017c885a, + 0xad63a4b8,0xd4bba225,0x15aacffd,0x5ce71b86,0x72954722,0x5f266475, + 0x4f0ad3dd,0x0a80f1f7,0xfc352ed7,0x010538a3,0x4203c6ca,0xf8a64045, + 0x330c73b4,0x2b2c7a88,0x02dcac1b,0xb3433ee6,0xed2b17c7,0x2e0499cf, + 0xbd6329c7,0x9f8681a4,0x36fadc37,0x38979946,0x92b7895b,0xdc5650c8, + 0x65a51cf0,0x70ab9570 }, + { 0x7b585d93,0x46778ec4,0xa633fe4e,0xca6d3610,0x4ea0311a,0x21da154e, + 0xbd64002f,0xaf22190b,0xd91cb7a9,0x9e633ac7,0xee6837d7,0xed13c31f, + 0x1616ee8a,0xda4a07d7,0x3afcd616,0xd78a2732,0xba14d694,0xc06696e5, + 0x4df58420,0x733754d7,0x2778e3c9,0xe85e504e,0x55b5a5c2,0x3055aa0c, + 0x8a3acb5c,0x313df538,0x2a088eda,0x5896acb5,0x84c85dde,0xfc8842a0, + 0x51dde6be,0x5fec9f79 } }, + /* 123 */ + { { 0xfe519f99,0x5ebc2c7c,0xe5410353,0xe396bd80,0x8a3988f3,0xaded9402, + 0xd601bda1,0x1c03b735,0x14ce64ac,0xfd302036,0x01240290,0x5837ebe9, + 0xa554097d,0xcaaea1a3,0xb0b88139,0xdce73d25,0xecb090b9,0x35ed412b, + 0xd63dab3c,0x99029ff7,0x062db071,0x555437d9,0x42a4c11d,0x277d2f56, + 0x24fc9109,0x477fa645,0x2799254d,0x7b12e9b7,0xd84c618c,0x7ad2ae22, + 0xce8ed195,0x0a8d5663 }, + { 0x0a21fde1,0x43ac5163,0x6903d849,0xcfcf5dd6,0x5fdd6281,0x6d2499ee, + 0x77a49a34,0x4dedc6f0,0x2875c06f,0x46bda2c0,0x347b8046,0xd0e0e0f6, + 0x5e67836f,0x1058169b,0xde8a8042,0xc961912a,0xa93b3d32,0xdf3fea0a, + 0x0c576bc5,0x9f138edb,0xd8d37e47,0x7971ad6e,0xcce5e7cb,0xeab85739, + 0x1d202b40,0x88a4b434,0xe3a1fd26,0x5d842557,0xb3a86f91,0x872fabd5, + 0x6aa4629f,0x95b93493 } }, + /* 124 */ + { { 0x99f951de,0x9998a701,0xf058db45,0x8fade596,0xf3d03dd3,0x4d479c1e, + 0x33b141d3,0x6e928d5d,0xacfe8a40,0x9a465800,0xc1cefa3d,0xd108ad2f, + 0xe013726e,0x64b96921,0x8e83bb9f,0xb9b6a6b6,0x1242e544,0x29f1e6dc, + 0x2f65966b,0xd3f8f676,0x5e105b41,0xa34dd096,0x16011e1c,0xd4e9139a, + 0x2515541b,0xeea4dc68,0xc822166d,0x6f8030ac,0x31d16124,0xbdc7ae1d, + 0x621afa7d,0x2e25ef51 }, + { 0xdd8e7357,0x2533cf8f,0xeaceddb8,0x333ba218,0x0784d2ac,0x68e3e31d, + 0xf2804ae2,0x1c927f36,0x77e7ad7e,0x01433d22,0x587f78a0,0x0b401cf0, + 0xaa0027ae,0x9dfcf036,0x1d9a46b5,0xc9e46c8b,0x1f288d32,0xaa6de486, + 0x1b8a043d,0xdd56da2f,0xf2d0bb56,0x346230e5,0x19defb56,0x19f0b6e4, + 0x21d2c874,0x55ec37cd,0xb70e45b3,0x3dbf0397,0xac7ce852,0xf0862a8d, + 0xe141f3d6,0x87979ea7 } }, + /* 125 */ + { { 0x7f1c747f,0x9b7e7b3f,0xc6e63369,0x151a4c1d,0xb372dba0,0x4273ff70, + 0xd3ee54fe,0xca6d2234,0xd33cae0f,0x12fc8e0c,0x5dd6f10c,0x27328538, + 0xf01a9cf9,0xc86f3fbd,0xe36cae91,0x5322677f,0x2fefea44,0x39a70033, + 0xce8af217,0x2c9ca328,0xf6a731f4,0xc0256776,0x66a96813,0xc687b3df, + 0x8db2eda8,0x194aab12,0xeec4febd,0xde30dc5a,0x979241b2,0xc052236a, + 0xc23d4c16,0x3ec98802 }, + { 0x4072f74d,0x0f9e760c,0xab594059,0xe78eb0de,0xc9b009c2,0xdb3dea40, + 0x38b59ae5,0x47e875f0,0x2b4daa06,0xf40eb436,0x090f3788,0x9a6a4f92, + 0xedbfaf8b,0xefebe9af,0x9867e256,0xf87f96a5,0x75ab6aeb,0x1e6fed23, + 0x3fdb13cb,0x17f2782a,0x70fa2621,0x5102c71e,0xfd4c0dbe,0x5d2b06ec, + 0x30347297,0x537cc268,0x2b67e780,0x8dbf5e2b,0xba25da32,0x2f633f3a, + 0xefaec914,0x3e9315e8 } }, + /* 126 */ + { { 0x239a9ea9,0x9255cfa5,0x0be33a62,0x20f3c690,0x9cb642bd,0x759eeb4b, + 0x00bae718,0x3316c546,0xf3410f84,0x874a76d5,0x90f129b6,0x123b502e, + 0x12851f1c,0xadc8f9a8,0x1b62408c,0xf57b764a,0x1a80777b,0x116ec01f, + 0x1f0ddc5c,0x746ecef2,0xe5a6a5a7,0x3c49d47c,0x06e955ba,0x1e15dbe7, + 0xb45d79b0,0x629c0c79,0x778d1087,0x11278308,0x8c6a22d7,0x22585dc7, + 0x0a682791,0x2ed02a0d }, + { 0x4daa2682,0x53043416,0x01359625,0x0e26d32b,0xbd867097,0x449c834a, + 0xee77ae2e,0x11a19d2b,0x3af6c169,0x39bd529a,0x5cd61054,0x36cca5c0, + 0xdc6c0fe1,0x6370a59b,0xb93d5135,0xca420d27,0x554c451a,0xd8730d45, + 0x96cdebf2,0xebd258c9,0xa50f9a05,0x0cb1b990,0x7b0f0151,0x69a8c97a, + 0x11d217e1,0x2cc36d34,0x752f75e8,0xf117688a,0xa09b2a61,0x1db01394, + 0xa9efd7dd,0x14627844 } }, + /* 127 */ + { { 0x232803cf,0x6bca3aed,0x9a96ff34,0xc1e4398b,0x74ab788b,0xcaf6757f, + 0x7e68c04d,0xc3a53e00,0x5cb7cd20,0x5f969c19,0xdc068bca,0xf28b65a6, + 0x1d863032,0xe3ca01d3,0x87808e14,0x9b733b81,0xefe618be,0xb5d704d9, + 0xb01b946d,0x276f3542,0xfbedddbf,0xe057e19e,0x903275ce,0x7d182f2b, + 0x880f7bc6,0x3cdc5f77,0x78476c14,0xd6f03d3f,0xa9ba5072,0x035f5557, + 0xb4029628,0x7acb57b6 }, + { 0x44e6b07c,0xd2413569,0xe1c7345d,0x451c4cc9,0xe273b9fb,0x407444d8, + 0xb88e34fc,0xfe496079,0xf152776d,0x77d184cf,0xc742299c,0x6d1033b9, + 0x77bf2897,0x29a0a684,0xee8f0420,0x59ffdf10,0x44bb56d6,0x4e17146c, + 0xfb9ae855,0x831d06c2,0xd93e7cd5,0xb2cb82db,0x3c96b607,0x83381c46, + 0x7549e2a8,0x06aed251,0x774a21d4,0xef97891c,0x8675fbdd,0xae9807c7, + 0x6363516c,0x6a5a05b9 } }, + /* 128 */ + { { 0x6a8f4f33,0x92e71ea6,0x4dea8f4a,0xf2fc6fc6,0xfee88461,0xd356252c, + 0x08954d08,0x59b0a83e,0x468ab766,0x5bd68c23,0x900f8d04,0x40281357, + 0x52b867ae,0x181c19c0,0x18764c41,0x986a5169,0x13575d24,0xcb01dfae, + 0x593677b7,0x17269ae5,0x46dc9b19,0xf6d17025,0xc40097c8,0x8de68499, + 0x259c407b,0x76df0032,0x17d29d8b,0x4091aad9,0x4a7ab5f6,0xa7f46d21, + 0x70ece48c,0x688054b4 }, + { 0x51a5b86c,0xf0d168aa,0x95777247,0x2437e4d8,0xf1720329,0xae844076, + 0x9647a54e,0x0a7ac87d,0x0405622c,0x1e597a4b,0xf0a79f2f,0xedefe5c6, + 0x4d55156d,0xaf3ef0c2,0xef047cf6,0x917fb04e,0x54b62137,0x3792799f, + 0x314be0b8,0x875ea32f,0x0c466b0c,0xe157c65b,0x7e218978,0xd28c90ce, + 0xcde587af,0xb90fc3ba,0x8b877bed,0xdd32d71c,0xca8e10cd,0x3b432200, + 0xd94f6e53,0x0021f419 } }, + /* 129 */ + { { 0x43519d26,0x2191122c,0x40a51845,0xbdafac1d,0x548bb89f,0xcc6f71e9, + 0x16844bf9,0x9ef3375c,0x178e8d55,0xe7789f79,0x1f8be1c5,0x04f599b6, + 0x2cbbde40,0x8088c99a,0x893206c9,0x8939a260,0xfcd30851,0xa1ae4bff, + 0xe08feafe,0x664cb3fe,0xff14aabc,0x61f38099,0x2a841ef9,0x0d8394cc, + 0x17f01db6,0x75fad8ad,0x6debb773,0x6fc34576,0xa4252512,0x1e716b05, + 0x29e1ed9f,0x79855880 }, + { 0x95106473,0xa2cb3aaa,0x5a61da04,0x95fafa41,0x539563c0,0xfd3c9362, + 0x95312b87,0xbaa48091,0xbf885c76,0x6c7e7582,0x230c78d5,0x70f6dab6, + 0x7747440d,0x8ce3051c,0xffdb6186,0x6dbebd14,0x190e4096,0xb0e041fa, + 0x6ee62e2a,0xba10c466,0x74f333d6,0x93d57e2a,0xfe7b9b66,0x006aadc4, + 0x06d2837d,0xfaf72f6c,0x910741ea,0x318cc5e6,0x65692477,0x9c502609, + 0x1d0fb08d,0x95d823c3 } }, + /* 130 */ + { { 0x140528a5,0x6aeebd86,0x53979bc8,0xf268c2ba,0x4ec144ab,0xb1bc9b8a, + 0x82a7d7ed,0x1efabb0d,0x4e0118d8,0xf12c70d1,0xa1c1558e,0x31607168, + 0xe4b7e73e,0x33e428b7,0x83aec9dd,0x63176637,0xe12ac35c,0x5172ffbe, + 0xbc17b2a4,0x37df0bfb,0x741f812a,0x4212f870,0xe2888f9c,0x3dcecbdb, + 0x756ca55d,0xa9dc15aa,0xb9028e41,0xf31918ec,0x6aeadb03,0x7ede0285, + 0x78654f54,0x0e2708d5 }, + { 0xcde20f88,0x2270cc53,0x5f5b1039,0x9338272c,0x5dcb1dbf,0x5042e19e, + 0xb72d74c1,0x4b3de219,0x2aaaaa55,0x16c49a8b,0xbba86ba6,0x008443e5, + 0x20cf1695,0xee6bcd72,0xa89abd11,0x59ffac6b,0xf115639d,0x2831217b, + 0xf34cba52,0xe4d28af2,0x0727a906,0xf27f03e7,0x69017766,0x6842c79f, + 0x7a81123e,0xcb3469bd,0xa42973b8,0x48c0f346,0x23990dbd,0xfc5784a6, + 0xfb299678,0x0d3dab3b } }, + /* 131 */ + { { 0xce29c3cc,0x8f8376e6,0xf016cbc6,0xcb0507ec,0x5e394ce1,0xdebff996, + 0x73c50d41,0x24fc526f,0x2d16ce3d,0x4edd5a54,0x91c13141,0xbb37bdd9, + 0xe33a8606,0xe3442ef2,0xc0629da8,0x2ae90337,0x592ab331,0x57faec64, + 0xd82b857b,0x1a938997,0xa3373176,0xad6c8cb9,0x9086751f,0x82595de2, + 0x18c17196,0xa81e97fb,0xbf697357,0xe4f48a13,0x5cb89f69,0xa1387c2e, + 0x5874b426,0x530b4eeb }, + { 0xbab7b5ae,0xe9f275a1,0x03a57bf4,0xbb69dc4d,0xa45c505b,0xc974dc4a, + 0x416ac402,0x726369f3,0xaed985dc,0x735e4e78,0xcdd446a1,0x0548d879, + 0x9e16b02a,0x84ceb069,0x789b11a6,0xf73f6fa4,0xb2a4e784,0x6aa0c41f, + 0x93a9b697,0xb1f76902,0xf03a8ab2,0x814cce00,0x844d66c1,0x64cb255b, + 0x30952201,0xb794e7d6,0x3da32271,0xe052d4e4,0x08b6a4d9,0x5278b2e7, + 0x80c6577f,0x90942552 } }, + /* 132 */ + { { 0x0d5b4c2f,0xd269a14d,0x5c8a649c,0x2b8fc59b,0xb0e37d4a,0x95becb3a, + 0x9111037e,0xfda1a768,0x94e35322,0x5810e05a,0xa178fafc,0xa24dcc12, + 0x8e3dce62,0x5c2c63b2,0x9452c444,0x995c3f17,0x42d45161,0x35330ec3, + 0xb4ef8129,0xa025a60a,0x8bae9c13,0x85493252,0xe2e3caf8,0x25d1a606, + 0x3649bf47,0xd44091ab,0x704ec5f1,0xc7d0afbf,0xbd8b3333,0x27bd1d62, + 0xcfe616f5,0x50570111 }, + { 0xf534356b,0xd0084ace,0x4b4b0fbc,0x9df1de05,0xcee04dc1,0x021afe05, + 0x361b78e1,0x64bde688,0xef78d38b,0xa324fcc7,0xeb0a5e4e,0xfeb372ce, + 0x65811996,0xef04fcb3,0x5eb0ab4e,0x7dce5d50,0x238c586e,0x1e29b588, + 0xbcd80037,0xde5e3197,0x4806b9cf,0x8bf5e451,0xd18e67ab,0x4330968b, + 0xf9f63fad,0x26a7d04e,0xb5c18bb4,0xa1c7f123,0x25dce22c,0x485b8482, + 0xd540e79f,0x8ff0b36f } }, + /* 133 */ + { { 0x3ff42cff,0x99f2e2f4,0x1c35317c,0xa3c19f9d,0xaba1b545,0xdb749392, + 0x4afa9a32,0x84232b05,0xd7dcd436,0x0b855d46,0x45cf9915,0x8ac35e20, + 0xf001a218,0xd7cf22c7,0xed408305,0x057d35ae,0x553ccfcd,0x25a4a519, + 0x93e2b939,0x5e565793,0x3422ec27,0xa20332b0,0x3ac53958,0x9b09005e, + 0x79e9b163,0x628051a3,0xfc6618d6,0xb4a0dc09,0x6748e7af,0x9e0e857f, + 0xc577d63e,0x71b28eee }, + { 0x99726bf8,0x4942b0cd,0x1c208f3c,0x1290a3b9,0xb0598eaa,0xfd7290e7, + 0xa25a9128,0xc6a7791f,0xc037d7da,0x2d33db24,0x70e2837b,0xc21efeb0, + 0xe3dae2a0,0xbf70d96e,0x85076027,0x43ed8191,0x4d4ad7e3,0x4aeb0aa8, + 0xe8c5b74c,0xbc75101f,0xad26ebdd,0xdbfb2a6e,0x6b78aa4e,0xba812068, + 0xe1159848,0xc94aa8f2,0x3eba5c4e,0x0d10d9db,0x6318295a,0xce7fec47, + 0x330d925a,0x7294711a } }, + /* 134 */ + { { 0x32bbd495,0xfce45904,0xbe54973f,0x330f4dd1,0x5d9c3f4e,0x006bee1d, + 0x59ba7204,0x40ee6078,0x42c2c768,0xc194fd3f,0xe9fe88be,0xa0e76b12, + 0xec2b0210,0x17cddddb,0x00811ec7,0x689d436b,0x284be9e4,0xa6a6ba37, + 0x007d4114,0xabc395b2,0x0f11e744,0xf8cdf9f3,0xe9396402,0xc5febec8, + 0xeeb46285,0x8a751743,0xc6e0d137,0x99bf8782,0xbeb292e3,0x3965e170, + 0x5801fd5f,0x001c39d8 }, + { 0xda4a0912,0xf4805cb9,0x4410bca4,0xd27cb76a,0xec71d65b,0xef3dcb8e, + 0x4816849a,0x780fbb2b,0xa8b24635,0xef6a7026,0x12c44e68,0x15625c88, + 0x4d7a74a8,0x624c232c,0x4b1631e4,0x81a77037,0xdb917c2e,0x04e4f7f1, + 0x1f61ed95,0x1d0465fd,0xcbde6e3d,0xb1048049,0xd7131fcf,0x637ce0c1, + 0x8ada4715,0x22e4dbc2,0xace99726,0xf7530c5c,0xee287450,0xa0160dcc, + 0xbb91af13,0x9132e670 } }, + /* 135 */ + { { 0x7996099d,0x8057efe2,0xa06e608c,0xb72344db,0xd0958588,0xeb4a8740, + 0x79e5aee9,0xe53daf06,0x908a2fad,0xc9560a9a,0x107e706a,0x7f4be131, + 0x2830246a,0x6d5f3d9b,0x27cca3e6,0xa5f8e8da,0x4c28f292,0xeb51dca6, + 0xf31dfd78,0x4cfa310e,0x2ca073e5,0x92e0c7c2,0xa40da683,0x102f1694, + 0x750d38fc,0x16bb07cc,0xbadae035,0x703e83e2,0xb4d3c9dd,0xea93c066, + 0x79940ed1,0x7d0b03e5 }, + { 0x4dd94c63,0x5fe7ea30,0x738b0b3a,0x57ef01c5,0xa14e6b4b,0x9534a78c, + 0xa5353276,0x07622cde,0x7c22d006,0xaf696a07,0x7d46b209,0x733c1886, + 0x626c2b4a,0x9654ccbb,0xa84f3c4c,0xa098d3a1,0x2d734b74,0x3596f9ed, + 0x5d551c90,0xdfd3021a,0x1ec5123f,0xe2ba7d2f,0xb2c1aa39,0xf9726925, + 0xf8eb2927,0xd2e75d0e,0x19192a6f,0xfaba712e,0x9b83e50e,0xa606b43a, + 0xdab5de60,0x31b1782f } }, + /* 136 */ + { { 0x4034db92,0x878dba45,0x8f34dc4d,0xa3977901,0xdf754c33,0x8d004f2e, + 0xcd563a88,0xeaa5954a,0xbb5ffad1,0xa29d6c89,0xb0d8bdb8,0xa8adf655, + 0x8cdbdb47,0xf7fb842d,0x80d3205b,0xb72e3a03,0x7cac7ca9,0xc335b0b2, + 0xd8a5475d,0xffc60bcb,0xeba4d25f,0x736f7719,0x0c50fca6,0x3d901c38, + 0x80c01900,0x1fdacf7b,0x5681f84d,0x75cf658f,0x5cefbbc1,0x57a7e634, + 0x3e07ed1f,0x6fc0fbe5 }, + { 0xb81b0e5f,0x496d116b,0x2ac853b8,0xd82dd2a5,0x327387f0,0x357e22d4, + 0xba912c59,0x3e332a84,0x49d5dcc1,0x8b71c643,0x438d85d3,0x0c982ee9, + 0xbf7fcd4e,0x90b9553c,0x38fed5e3,0x2cb39bbc,0x5ac42903,0xa2c67c9c, + 0xbf07da55,0xebf21217,0xa0b9e4ee,0x55ac05ad,0x8ee9e0c6,0x10bb12c2, + 0x48bb6e3f,0x5cf3aee5,0x8b046e91,0x4ae7269c,0xaa0e553f,0xcb266012, + 0xa94c8fc8,0x701935a1 } }, + /* 137 */ + { { 0xa4626dea,0xde58d41d,0x15b9039f,0x25ef66ca,0x3164e65b,0x99a810a4, + 0x748cfccf,0x9fe6daad,0x2f142fa9,0x7ab9a6bd,0x5d471796,0xa4cba168, + 0x6bc3a39b,0x12d30b36,0x8bf45076,0x1f46a5dc,0x1421ac0e,0xb868e529, + 0x59bba1c4,0x7a686206,0xda698b90,0x2b4b552e,0xe5453707,0x5039dcd4, + 0x9e90165f,0x42a07a9e,0xd7d45dfc,0xa838fff3,0x3b5ceb30,0x41991e5a, + 0x969ca600,0x6c961ec8 }, + { 0xc4e7eb46,0x703bdc1b,0x596c7b48,0xd6bac557,0x66afd74d,0x4f9917cd, + 0x656ce6f3,0x56355105,0x32497175,0x3d1fb50c,0x63effb2d,0xfda6783e, + 0xeefaa2bd,0xbd79f1f3,0x17af9ef7,0xa4efbe54,0x5a55b7a4,0x6cef6462, + 0x1a713304,0x116f3238,0xb95625a3,0xdb2a2a7f,0x0b027e96,0x6a0aa43a, + 0x4832b3bc,0x458fe5d2,0x5adfaac0,0x523418df,0xc49e7f9a,0xc05a89cb, + 0x69e24b53,0x830883d8 } }, + /* 138 */ + { { 0x02557389,0x959b1c62,0xadefc0bc,0x5fe5ce97,0x8330f383,0x893bbe7f, + 0x16cfb81e,0x27e0c6af,0xd04428fd,0x6f64e65b,0xb79e6182,0x53de9245, + 0x487e11ca,0x08a313c1,0x445bce93,0x65cec3b9,0xd67ed49e,0x33bc0314, + 0x30782352,0x69f36b24,0x93ad31d2,0xd78e5daf,0xc780890c,0xf2682b70, + 0x9e45efe9,0x7015c34f,0xe6cbafea,0x135d4ba4,0x7e3fcc6c,0x43a378a4, + 0x96638f8c,0x2376f97f }, + { 0xae575b99,0x0a6e1ec0,0x81b970dc,0x7e14cb4f,0xd3a73947,0xf00a3824, + 0xfb235a9d,0x0b4b9c81,0x5bf62944,0x8d15115f,0x1e165d7a,0xcfd35b43, + 0xb2ee3e3b,0x5d12fea2,0xf5182e7b,0x629984a6,0xc365d08e,0x4e43e2f3, + 0x30f36e72,0x99327091,0xfd345401,0x698b4a00,0xbaf96dce,0x23c4fd0e, + 0x23675554,0xa60ba0ae,0xb0325784,0x51bdac2d,0x215464a1,0x8ab4190a, + 0x6bf10296,0x8c461661 } }, + /* 139 */ + { { 0x2d1f36a5,0xeffca258,0x894c5f2d,0x0eded2b2,0x43ced84f,0x35a5cdb8, + 0xdb0e3b9b,0x290f8982,0x0719a112,0xcce0eaf0,0x39a362d6,0xd0e657e4, + 0x62697e47,0x5516a55d,0x8e636514,0x269e1f77,0xd50269bc,0x5e3dedcb, + 0x441c57c5,0xecec2300,0xc705578d,0xdb83f31c,0x1e489eab,0x1bdefb73, + 0x395fcdb4,0x20b678cf,0xff9db001,0x908cf91c,0x55f52cc8,0xcbebc6f4, + 0xb4c61162,0x155ea622 }, + { 0x876fa42e,0x94be2f1f,0x7fadeee7,0xab5e8749,0x38c865af,0x692e70f5, + 0xdf8059b0,0x16e99b84,0x8b5a7ac9,0x0ceb606e,0x2d463d2b,0xced23357, + 0x2a9a09a0,0x2d0f2623,0x3861fbdf,0x2529998c,0xc1be310b,0x711888a7, + 0x0d8aade3,0x9b1229c5,0x3b13533d,0xdbcf9b78,0xff029708,0x3ca746f8, + 0xda83ef88,0xa5a013a1,0x4ab28444,0x8e904d18,0xbcbd4aba,0x2fe84b3d, + 0x259058c3,0x8f570f24 } }, + /* 140 */ + { { 0x2ca9c508,0xdeb66c8a,0x69d6b780,0x2dc5bec2,0x88ead600,0x16d61266, + 0x49d72614,0x61841b97,0xce472e6f,0x41e40e6c,0x1fa7a876,0xada24264, + 0xcc3997a0,0x45b9fd33,0x7c15dcf4,0xb25e8fa9,0x12e9629d,0x0124ceb2, + 0x7db3d956,0x3a8c72c6,0x7c1a7844,0x8e2ded2b,0x6dd027ff,0x94ab09c6, + 0x7e7a2bc6,0xf89a057d,0xcf70c763,0xad8bf226,0xc8a26212,0x4cb268e7, + 0xb2c44c1d,0x3d171e87 }, + { 0x8ce49820,0x382ac16e,0xc0c44dc9,0x24ee45e2,0x73e858c4,0x0ec67912, + 0x46327cf9,0x918cb25c,0xc6159c1f,0x43e3876b,0x37545cb3,0xb6b6e0e0, + 0x5d12347e,0x64b839ab,0xa300d541,0x72e09274,0x881c1169,0x26ab28e6, + 0xeb75a843,0x4a580fff,0x359120df,0x0a5802ca,0x3209f4a3,0x7fee82d0, + 0x8e6a9380,0xb518016b,0xc2ee11ca,0xb99c6c70,0xab9d4ec7,0x16105af1, + 0x34cd9004,0x234e98f8 } }, + /* 141 */ + { { 0x14db9cda,0xff435208,0x96adec90,0x99cfdc47,0xaf458b6d,0x843aaa6f, + 0x743eaa31,0x3f1f7415,0x61735d81,0x915e192e,0x0ac595d5,0x3441a22d, + 0xc044bc8d,0x704bbf67,0xbe23a236,0x2f960471,0x15d1d557,0xcc326388, + 0x76b1dd94,0x9410230b,0x0c1c8a67,0xf2e5439f,0x833c910d,0x56b141ac, + 0x865b84df,0x467c999f,0x21f02b7b,0x1b0251fa,0x96216950,0xde5b5260, + 0xce3a1e93,0x6a2130e3 }, + { 0x4b3ca1a7,0xd21b67a0,0x00c0ce80,0xaf42ed53,0x932cf07a,0x22ccd368, + 0x5c25c35a,0x36523a81,0x8dd04d06,0xecdd3958,0xb2f93a3b,0x73da3502, + 0xd5e5b530,0x4c5e0c3c,0x13268777,0xef9f5486,0x1e742292,0xed87fefc, + 0xa24e5ede,0x6d9ac29e,0x33849f1a,0x08abc9f0,0x40f23905,0xb09b2292, + 0x7f934353,0x6791072c,0xe6aeb550,0x102a6381,0x96feb870,0x3ee07409, + 0x9c4d2830,0x34f06faa } }, + /* 142 */ + { { 0x2348f005,0x869dc79f,0xdf4920b1,0x9b5c5d71,0x6dee64a4,0xfd1b57ca, + 0xe82a4fb4,0x21b7f734,0xb9578366,0x637cb834,0x7d287d96,0xc934101b, + 0x0392ecab,0x1590f8ac,0x7f75f4e3,0x280dc373,0x6a61ac62,0x8b36f50f, + 0xa65568da,0x74f58304,0xd930870a,0x80d792a9,0xfc8895cc,0x6d17b192, + 0x4914939f,0x498392fa,0xd41d5b9e,0xaf36027d,0x5caa82b5,0x452d79e2, + 0xf4115d1a,0x764d47b1 }, + { 0xa2ee8b9c,0x5df22303,0x85dfcd48,0x1b9f72d3,0x10813a37,0x6b42b983, + 0x3de741f5,0xe28c523b,0xf303bb5b,0x0857625a,0xac9bf9af,0x926f299a, + 0x0d445b34,0x21beac08,0xd6ba2c0e,0x6a523a02,0x7fce2864,0xe302a1b1, + 0xe300c1ea,0x4516a235,0x7b4a9311,0x4543736a,0xc0cc89f7,0xd3c0b9e8, + 0x40ed88de,0x0481904f,0x3cb7fc70,0x4f269b56,0x321b9738,0x09a1d53a, + 0x230a3810,0x1c0dd9c3 } }, + /* 143 */ + { { 0xc46a7d9a,0xffaa1f67,0xbedf91cc,0x64743334,0x47a42f2e,0x45833a74, + 0x241ffaa9,0x67980051,0x335efe6b,0x70979a84,0xf08b2403,0x5f0613f5, + 0x64f211dc,0x6bb22fcd,0xa0572cfc,0xe1b8b2a3,0x7950a14a,0x19e0eb41, + 0x3eb6cd4c,0xe634bb29,0x470a25ff,0x31a04b25,0xa3d15a0a,0xa41f7ac9, + 0xbf2fede9,0xefed85ec,0x81b94a00,0x1f581f5f,0x9ef4a15c,0xaa3996b0, + 0xb06041bc,0x52d8be39 }, + { 0xfd631a2f,0xbd1536f6,0xb351a8dc,0x91fae7f0,0x9b126212,0xd1a590c7, + 0x2bd0f435,0x52d4875f,0x92b0ea70,0x9aedb6d3,0xb83ab89e,0x0bd0abdc, + 0x89fe192c,0x827a1062,0x102a0bda,0x6566a960,0xce036814,0xda083037, + 0x58639405,0x30bed79f,0xdbca8df9,0x972019b6,0xefdaa3f5,0x89201286, + 0x5236b892,0xb337b996,0x28fc2e73,0x11d3e38e,0x880e8da3,0x70787f41, + 0xdae4a45d,0x6cff6367 } }, + /* 144 */ + { { 0xf89a8bb4,0xbd3d0433,0x93b98f71,0x42144c33,0x03470a2d,0x82b616c8, + 0xe5da089e,0x98fcc757,0x7bf5fda6,0x542354ef,0x9ebd34cc,0x1885c253, + 0xbec5dd0d,0x2e20b285,0x782a1bca,0xe71bbbe1,0x9b854ef0,0x959ded30, + 0x8997fa6a,0x17249979,0xd81f3c45,0x50cf8fa8,0x60c11152,0xa9a3b517, + 0xecf845ea,0xc9b0ef7d,0xb9fed11b,0xc9339e23,0x28256080,0xc93e9c5c, + 0x613ec1e7,0x1d2c8217 }, + { 0x987cfc93,0x7381347d,0xf187f810,0x047603bb,0x1250ca31,0x3fa6bc9d, + 0xbb055bf3,0x480091e0,0x3a3af87c,0xbdf95f1a,0x140540ab,0xe2687770, + 0xd7fe045b,0x998df730,0xb723bc2d,0xb398135f,0x15ebec46,0xac230f8c, + 0x5f5561c0,0xe08e1830,0xda60a47f,0x7c0fbf4c,0xe16d4bfc,0x06e95c24, + 0x74617e92,0x74163495,0x4ae0c20e,0x39719869,0x2131e2b6,0xfe269312, + 0x0a537722,0x25486e36 } }, + /* 145 */ + { { 0x53572806,0x618795ca,0x656968e1,0xb2c89449,0x3fb323ae,0x149c2c97, + 0x409bc7d6,0xfb15de26,0xc79121b3,0xa90cda72,0x204cabbb,0x6d2fa14e, + 0x91604125,0xcbcda6f7,0xb435f947,0x25086261,0xc282eb10,0xdb686c38, + 0xf1a791cb,0x51016d62,0x61a2266c,0x6b1c7ed1,0x271d74a6,0x26780666, + 0x824287a4,0xb5ffeda1,0xbbe4f0f3,0xcbe503ff,0xb9482a74,0xd7f7f0be, + 0x088493f1,0x751b2358 }, + { 0xe9c9be68,0xd597b9d6,0x67d10c6c,0x1794b5c4,0x7762b2f4,0xa88cdc3d, + 0xa1b44e11,0x6d94a63a,0xaaa8eca8,0xfb0bbbb9,0xc963d87f,0xf4b0f2d0, + 0x5dc7075d,0xb753062c,0x49933989,0xfed726ac,0x57f9ccde,0x5da60638, + 0x75f8c766,0x221c392a,0x5dc672ca,0xcd264d95,0xb66ecc8d,0x7004ff22, + 0x18a458ba,0xfb1aa9ae,0x8babd653,0xea9644df,0x2ba0de7c,0xa9378e80, + 0xca2c6c75,0x144cc12d } }, + /* 146 */ + { { 0x2989aa3a,0x593a0a1d,0x59e6e64d,0xd83f2283,0xd32e732e,0xe938b0cb, + 0x3c3cb249,0xf4c464c5,0xf89ea6ac,0x9750a5f8,0x346cfc32,0x467e5bbf, + 0x37b2b809,0xc9bfab9d,0x3b339c6d,0xf8eb7453,0x3b766dee,0x3fe01fbe, + 0xef6aea27,0xb3154254,0x7be61b10,0x555c3df2,0xdd818488,0x70fb6d81, + 0xbbe714f9,0xda1af3a4,0x9d18f693,0x575f2017,0x2465b839,0xdc08fc6b, + 0x6b84a951,0x874ecf33 }, + { 0xbbb3f6be,0x624af83e,0x08bb423d,0xf578fbb9,0xd7873527,0x5623b0ba, + 0xa62e0442,0xc3659bd8,0xfe236f79,0x2903b167,0xe53f26a6,0x55a430c6, + 0x3ad712cf,0x222547ae,0x76eb272b,0xb73890d7,0x3d628df9,0x95b4f70b, + 0x53eae4ac,0x9f0e13b0,0xe7f2174e,0x5b4f5138,0x98dbae17,0x75482cf9, + 0x44518480,0x2b69bbde,0xcafef15c,0x4f279652,0xb6bcaf19,0xa0a3ef2b, + 0xce4c634f,0x31fb8581 } }, + /* 147 */ + { { 0x615cd607,0x398306d1,0xaa32c3a6,0x680c9faa,0x7779131d,0xe87a705b, + 0x36708b00,0x1031013a,0x9445297f,0x814fa0e1,0xa6a79b56,0x70c5583a, + 0x4b16bed4,0x03039cbf,0xaaaaf8d3,0x18a7ca8d,0x5cdb68a5,0xf33159e7, + 0xd23814fa,0xdea0e738,0x8d0f4f9f,0xeb352718,0xdcdff032,0xb0b76609, + 0x3d48338b,0x65ba8ea9,0x55dd507a,0x18044d82,0x4a4a50b4,0x844a223e, + 0x18e19e54,0x98323000 }, + { 0x57f3d5a6,0x28a21027,0x6e8cadcd,0xffce5648,0x02551f3b,0x9590381b, + 0x935ebdf1,0xb26cc64f,0xc083aa6e,0x60611291,0x88e4cf41,0xcd988a66, + 0xdd53b1b5,0x581c3f73,0x77fc621d,0x78c804a9,0xfadca2fa,0x31874330, + 0xc83ccf02,0xf7008da4,0xa79a4707,0xc4122a1d,0x4a915eb5,0x9a8e0d3f, + 0xd0123660,0xa2de157d,0x65ead2a0,0x45ef43b2,0x188db285,0xd0a22ade, + 0x922e0caa,0x8abbe39e } }, + /* 148 */ + { { 0x3a2d2f01,0xb4446905,0x5dc6685c,0xd27c3193,0x1d74a027,0x6a908bbf, + 0x5b50ec1d,0x01da350f,0x3f3c2e26,0x1d3dd45e,0xb836ee92,0xf66e11d0, + 0x474b979c,0x7e03908f,0x98b87834,0x19e7c5b9,0xbd3d1de9,0xa741d3fe, + 0x1ef6059b,0x63c68e8d,0x3674e247,0x9b9ff939,0x3e7e67f6,0x1d7d53e7, + 0xaee9e248,0x698dc326,0xb3bd984c,0x52f23eda,0x6f8fe8a7,0xf95e31b0, + 0xc3d0ba95,0x0f15b4d0 }, + { 0x790a8d85,0x8f2f6635,0xe2595af1,0x51bffbae,0x24b51287,0xd15b7ec6, + 0x3234715d,0x7639b6ab,0x2bc5441d,0x0cdd5299,0xf6d05833,0x54800ea4, + 0xf6d6e360,0x21efd752,0x19290613,0xc0b7ffe5,0xeea898cd,0xb68a5825, + 0x22982266,0xecedba92,0xbbd06bb2,0x678a91b0,0x4bb6b0cb,0xb2436dc0, + 0xcaf8ea98,0xcf7a99e7,0x71aa05bb,0xb92d0e6e,0xf5993eb1,0xbf8d0471, + 0x20385ddb,0x515db378 } }, + /* 149 */ + { { 0x6f5bef22,0xee43eaaa,0x20348712,0x952d2698,0x7a3af6c6,0x1e4c484e, + 0x9a8c9403,0x18d434c6,0x5001899a,0x63e5d741,0xfe8ea40c,0x5238dbbc, + 0x96798721,0xca6cc8d2,0x04acbde8,0x73db6aee,0xb7f993ce,0xbf69328d, + 0xad45e334,0xa3f79bbf,0x7c1f1630,0x8c51ec93,0x9b00a6de,0x4907325f, + 0x12d82bc3,0x49e6acb4,0x0ec59fc9,0x5901b36d,0x9cf34e3b,0xcb09b710, + 0x1abf4c02,0x2de0487e }, + { 0x8dd9d484,0x18b722f3,0x7c77bacc,0x83349393,0x93d92b8a,0x58dbb8f1, + 0x8e3fac25,0x80d78d50,0x745f4a7d,0xf0500981,0x877cc29d,0xd072bfed, + 0xc30a89f8,0x67abf8f2,0x9a0820d7,0x92c567ea,0x8a3a5738,0x425ab12e, + 0xf055521b,0xc162faeb,0xb94ea5e9,0xee1c4f26,0x3d71e546,0x1e414994, + 0x43e8be1d,0x258183b8,0xef9eae0b,0x44917c82,0x73874a30,0x6813a457, + 0xcc42f86e,0x6f6ac071 } }, + /* 150 */ + { { 0x4dd6e3b1,0xd38822ad,0xad620869,0xfc78e1cc,0x2cacde80,0xe7843845, + 0xa8469fe3,0x121cc14a,0xe67e8ef2,0x8e8f3da7,0x4d347448,0xdb83d16e, + 0x798631f4,0x3ba1dd98,0x0a4c4c17,0xdfab5977,0x3edc701f,0x1f0a1306, + 0x6cd8ff28,0x4649d601,0xbcc55bc9,0x2267230b,0x5760412a,0x02a19c60, + 0x328faef6,0xc719d5f1,0xf67eaad9,0x27cb969e,0x719bafb5,0xf342530e, + 0xff5a82cb,0x6e2c24cc }, + { 0xadaf8793,0x6313024b,0x035c948e,0x944bccf1,0x953500bf,0xe9a066b7, + 0x1d116765,0x7991a946,0x9fd93c78,0x95addb2e,0xe92e5495,0x05d2c037, + 0x9f03e5cf,0xcb145b18,0x95aa1f72,0x81ae48ca,0x135a6e4f,0x203f2702, + 0x49b2a7d5,0x2bcef5a2,0x02d7f2a3,0x0687a900,0x6c6745b0,0x2f7d3228, + 0x86507305,0x3da8a875,0x2e8dc58f,0xbe38b884,0xdbf11185,0x6b48bf34, + 0x97c08f91,0x5af7fd0d } }, + /* 151 */ + { { 0xf4a224a5,0x55f9b950,0xcc50273a,0x41904574,0x643f1fd5,0x34f81330, + 0x0e50f783,0x996801bb,0x89581712,0x866d7403,0xa4091d36,0xdb9a405d, + 0x16a46fe7,0xf1e379df,0x83bf9168,0x8d04a93f,0x32b20bca,0xae4c8335, + 0xf72a1c10,0x99d334b1,0xd8195db4,0x8fbc9977,0xfba14b5d,0xcaeb3dff, + 0x76daf476,0x60fef022,0xdb5b72f4,0x4b948dfe,0xb6dfb062,0x5185c925, + 0x9609d4ae,0x27a9c381 }, + { 0xf12a93af,0x73c37346,0x5536634d,0x028b707c,0x498193d1,0x8efa58d5, + 0xef21b69d,0x4f83a5cc,0xa788a0e2,0x05cbb0a3,0x65b13c98,0x01031781, + 0x2b73784c,0xfea20e58,0xe50361f2,0xdf9713a0,0xd0cc22d9,0x31449a0f, + 0x7c5e2e1b,0x183752e7,0xb67044cf,0x6e44d6bd,0x733e177a,0x012dde95, + 0x08ee2c23,0x68b49669,0x1f5f1949,0xd9bb0541,0x6acd886f,0x95182c71, + 0xfbde9244,0x1c690694 } }, + /* 152 */ + { { 0x3a880026,0x5db67d17,0x125d95f2,0x89c4f0a0,0x3f6cb7a4,0x29050551, + 0x5cbbdca5,0x3eb231d1,0x972bcbd3,0xf8cffc99,0xad55a03a,0xcb4ef4d4, + 0x22867c2f,0x944d47ca,0x0ead1aa5,0x96d88548,0xcbc8b045,0x76a57cf8, + 0x005e55a0,0xdfe5844b,0x1d18a097,0x5e9e7e19,0x52923c74,0x957a26e8, + 0x7f5db339,0xd0867b79,0x63bed0c8,0x2553408e,0x689ad23c,0x1596e5d5, + 0xa504c339,0x7b8c13d6 }, + { 0x52fb6901,0x2fc43aad,0x16ca253b,0x1c0313f9,0x515aadc6,0x1475830a, + 0x7f577dc2,0xc93d1926,0xf723c0dd,0x26e52e8e,0x3eb9f6da,0x2f1e0eb8, + 0xf180376d,0x9979de82,0xb0834939,0x43e28ecb,0xa39c38e7,0x9a2d51dc, + 0xa8e3f6b5,0x6e6063a9,0x4b9b3270,0x4cf1da3a,0xd2f8915d,0x6e5348a2, + 0x50507912,0x5e75e3e0,0x20d383fa,0xaeffce57,0x8fd2fb29,0x1d6d53cc, + 0x696f4cd0,0x0e3c3ef6 } }, + /* 153 */ + { { 0x21ee1d83,0x3bc337c1,0x787b7788,0x97e08f6d,0x138fa4ce,0xbf709fcc, + 0xa0348e58,0xbaf77647,0xa55e672d,0x04f8babc,0x7d5ec5dd,0x0ed2919d, + 0x33e99218,0x8ce64bff,0x24b059af,0xac09fc57,0xdc5e32ba,0x506831f9, + 0x465af6a9,0x26a22677,0xc97f1ff8,0x3c5efe66,0xbc6087fd,0x1515e0d6, + 0xaa8edc6b,0xb1a39c5e,0x0e79ed29,0x3dd816bb,0xbc3788b8,0x6cc13769, + 0xc092a51c,0x463098e3 }, + { 0xc8bd0fa7,0x3a6408c7,0xce6bde49,0xd1764311,0x283ef7be,0xe315e108, + 0x99b5d938,0x8213cc77,0x45a49a6b,0xaf7f1581,0xe529e4d1,0xd00fdb0f, + 0xce66c9d6,0x55d38f77,0x1bd4b952,0xb4f7ccc0,0xaf71f986,0x8d975b49, + 0xcd64d00a,0x12b59fcb,0xa5a3bad7,0x1860e504,0x2b5c89f1,0x6d976044, + 0x7a3e231f,0xfed0c659,0x178cba92,0x58114c33,0x6698e11e,0xe2e74c06, + 0xa348b85a,0x7f8fd093 } }, + /* 154 */ + { { 0xc19428af,0xf24592ca,0x3a308665,0x192a1c81,0xe30bbd7f,0x42589812, + 0x836c6bb9,0x10db0723,0x598e4987,0x9c7a41e9,0x6ead6f4b,0x8aff179e, + 0x75862c44,0x70f8f9b9,0x6f21983e,0x6b3b0237,0x98e65152,0x25d83e9b, + 0xd751218a,0x3b2d26a8,0x9d6f1da6,0x9508281a,0xa5a81f74,0x8df78d05, + 0xe4687471,0xd79ee559,0x6787d8cc,0x2060ca57,0xa8476c95,0x427a84ff, + 0xe6435131,0x87b64c51 }, + { 0x4b30d3c4,0x87f46f65,0x23b4ef14,0xcdec4c5c,0x63ca4d68,0xb3b74766, + 0xcf3fb56d,0x1df34269,0x0fd7d46a,0xd4f139c4,0x6a69a8bd,0xa3b7c7c7, + 0xcbadd7d2,0xee56b4c9,0xac942334,0xb28ff342,0x786f1da3,0x0046fdfa, + 0xb700c82e,0xce5d149c,0x50966597,0xca30ef81,0xfcff4bdd,0x44a20609, + 0x44925268,0x0f2f65e7,0xd4021f38,0xe5b6552c,0x042dbbd0,0x77ea9c2a, + 0xd9c062f5,0x8c95267c } }, + /* 155 */ + { { 0x5fc1abb1,0x6655032e,0x12fe4743,0x2215af54,0x29f05ef5,0xfd657560, + 0xdc191be9,0xb0e73325,0xc08639b0,0x7ab3c65e,0x1c3e6673,0x67507f51, + 0xc8615555,0x638befc3,0x42f0c4ad,0x5d0188cf,0xd896186d,0x843a301c, + 0xb2c6741e,0x045603f7,0xfa3cd1d0,0xf7545c0c,0x4a40672e,0xf612affd, + 0x45b9e8dd,0x56197c9f,0x87922d74,0xb453237d,0x4b2d59bf,0xbf132e3a, + 0xb84a6a16,0x8afa1b73 }, + { 0xe793ac70,0x6b3596ea,0xeef6dd10,0x4c94ef8e,0x70422e40,0x926b4fa2, + 0xe9e5d763,0xc8c71dce,0xf512aadf,0x352fcb70,0xa883975f,0x1b7ba138, + 0x058c3b13,0x57991390,0x97740fd1,0x9692092a,0x160b0697,0x19ad945b, + 0x10837ab2,0xbc634388,0xf174bb71,0x76ee11c4,0xab1b80eb,0x6111bfc1, + 0x70ec458a,0xbc82bac8,0x312d3325,0xeee60127,0xb240adc8,0xb4118b1a, + 0x2b5a093c,0x67211191 } }, + /* 156 */ + { { 0xf55cf9bf,0x91e99306,0xa46b96d9,0x9b045308,0x9e7a65df,0xae3c1e1d, + 0xc731bcbb,0x453cb151,0xa4d58a61,0x14be5227,0x97c74cc2,0x39dac922, + 0x822e00d6,0x4d0f7a45,0xc62b03df,0xafeb1d51,0xbaa18b2d,0xbb1dc3a4, + 0xdf2b74f0,0x7f3c7178,0x896b6a33,0xfcd328a6,0x1dce055f,0xe95ed454, + 0x6a4e2b87,0x97fbc76b,0xfa59dce9,0xe5ec67f1,0xcc0367c1,0x052368ac, + 0x54e4a3fe,0x7c863916 }, + { 0xca7388cf,0x55e94b5e,0xc0335d38,0x17cc0a60,0x616f85ba,0x9b69b78b, + 0x10122980,0x705d02ef,0x1cfd0a79,0x565a6e80,0x7d1ee352,0xeb74a96d, + 0x427b9dad,0x5c8832ed,0xe6d5330f,0x96ea8528,0x18d24ee8,0x30d8862b, + 0x9ff939f7,0x9cd38ed5,0x01060252,0x690fc9a2,0x2303b3ff,0xc62d88b8, + 0xdd52b469,0xfc42d7a4,0x8cad2d93,0x06f8dfa2,0x60920438,0x50236090, + 0xfce855ad,0x32582758 } }, + /* 157 */ + { { 0x359e8c60,0xeb20e45f,0x364ca186,0xc71bb8a5,0xdff8e110,0x02b15071, + 0x4c93e578,0x074e91d3,0xb829d0d8,0xc0326e00,0x626a83fa,0x3c192258, + 0xfb29a09e,0x387a64d5,0xe5ac5c82,0xcaaa3d34,0xada2da29,0x8ed685e5, + 0xeb29650e,0x92720267,0x763802f3,0xf7184b19,0xdf6b1aea,0x23f5dd0e, + 0x25e6125d,0xbe1fa347,0x0c872a1a,0xd6287f9d,0xac57c3af,0x49aa93d2, + 0x5bda7656,0x1a4e6a71 }, + { 0x554d1267,0x1a126ede,0x1cd02b48,0x37f94533,0xce31fb1d,0xd70af04c, + 0x097dc012,0xcf410b0b,0x36c7b6c5,0x930e1d17,0xc6891085,0x902fee41, + 0x79fb638f,0x349ba4a7,0xacd6f8df,0xa16c5821,0x2e076ace,0xfb3b83c1, + 0xe501d14d,0x6b8d033b,0x20f2d2da,0x0593d452,0x99df1880,0x3752526d, + 0x9feb33a6,0xca32351c,0x1f6ef456,0xd91343bc,0x35b9dc8a,0xc74857db, + 0x85b4e832,0x856a7c93 } }, + /* 158 */ + { { 0x0d0a5583,0xa007d002,0xeda4658a,0x2f1301dd,0x34d939be,0x91c07964, + 0xa70c0836,0xa0cb6780,0xbe81e540,0xc0b4df95,0x5d4ac8b8,0x6cbbcd34, + 0x54756239,0x57c52ed0,0x1805ceb6,0xcac2dca4,0x79344255,0x915ee6ab, + 0x24c9a2a6,0x366def31,0x8c12c674,0xbd3b962f,0x7dbb7c3b,0xaab64f1b, + 0xe22bb95b,0x3c0e4553,0xc4c63b74,0x2408feba,0x2a4da631,0x3ca77312, + 0xc636da40,0x62889084 }, + { 0x8cb8d208,0xa457fd53,0x543f06d4,0x7a8f8009,0xf2eff2ab,0xb66de154, + 0xf72517e7,0xfddb28eb,0xf9389d2c,0x0149fe66,0xd85b88ce,0x79e8773f, + 0x0ba543f7,0x452e090b,0xb0b03fc0,0xdeb9b5cf,0x6c5ed77b,0x3113448a, + 0x8ffc0372,0x3609f3cf,0x5c1b4c4a,0x2bc9c46d,0x8fa59be9,0xe66f3bf3, + 0xcdb02691,0x1396bf5f,0x009f88f9,0xf1ec59d4,0x2ad9dfe3,0xc2903456, + 0x5ada4d58,0x79d8122c } }, + /* 159 */ + { { 0xaa529507,0x14d4e4ce,0x74655d00,0x056a0814,0x4f0fc474,0xc0d30a38, + 0x3443cb8e,0x8a8203ea,0x97f1728d,0x33c62fb0,0xb520ef52,0x8a38dcfd, + 0x7cac9d3e,0xa0f90d5d,0x873cea50,0x28a7b0bf,0x6c6c41cb,0xd115ae3a, + 0xa13812c1,0xa35171da,0x624d507e,0x25d4bba5,0x7e98f42f,0x91dad289, + 0x96a41371,0xffd6b1e9,0xb69e5b77,0xd46c2125,0x20c4f707,0xc7d2b424, + 0x8142557a,0x2ab3af95 }, + { 0x6a5372a6,0x86ca074c,0x56292ba7,0x728fb83e,0x77741cf5,0x745596dc, + 0x520ef49d,0x70b4cea1,0x61e46472,0x1472fe34,0x3fb8ac5d,0xf4d6bd66, + 0xc10bc071,0x46e52cc9,0x371a3461,0x28794efe,0x276fe877,0xa4850718, + 0x9bef5ab4,0xedad5773,0x3f15c815,0x24c2d9ff,0x8f8395c3,0x188950e5, + 0x80b6a855,0xbae40996,0x8a8803e1,0x4f53e22c,0x039d25ee,0xaf233f61, + 0x250409ca,0x07db2c35 } }, + /* 160 */ + { { 0x037d4703,0xc7f3b8db,0xc5f488b9,0xe83708df,0x8471d402,0x1fba830f, + 0x5a2faae9,0xa55ee8d2,0x5404fc1e,0xc2e5bf10,0xaa2d5651,0x647d5027, + 0x7ebaf5f9,0x37a53c0c,0x95b30abf,0x7adf0bb2,0xd64c93ba,0x5a62e1fe, + 0xe2ef4a78,0x7ffc18c0,0x4d2cd04f,0x139dd9d9,0x5ea0af02,0x253fbab7, + 0x0fef9acf,0x7c8100ea,0xc8615aa7,0x74c5384d,0x9fe52069,0xcb28682d, + 0xcf7dd759,0x08b6ca8f }, + { 0x036c3b5a,0xe04e5bea,0x7f9f2b4b,0x38726102,0x29797c0f,0xa9fca570, + 0x82879ea3,0x1656180b,0x607f0ddf,0x153389bb,0x67b0e087,0x99a1223c, + 0x9d897fc7,0x0d1808ec,0x916edf19,0x9470711a,0x07217118,0xf8f52f2b, + 0xd18888b6,0x5d8b29ff,0x4cc6f900,0xef1e22c5,0xeb24877f,0xc4036165, + 0x35479525,0xfda95233,0x6861468a,0xd622a421,0x74faba08,0x5d043b07, + 0x0d31a7d2,0x2c337b02 } }, + /* 161 */ + { { 0xea22fa65,0x7b2305bc,0xd159f63a,0xbe183ef4,0x3f35923f,0x3473d87d, + 0xc11d7753,0xb27fb306,0x2a054cff,0x702e7e6b,0xaf185619,0x3ce9f97c, + 0x4e7d51c5,0x83550243,0xf356ac5b,0xa63e3d82,0xd7645131,0x867b7caa, + 0xa671fc9d,0xee85e6af,0x2b07cd77,0x3b985ede,0xffda5193,0x07d598b0, + 0xa942dc36,0xb10eca39,0x506218a9,0x17f3dcee,0x06b7d5ca,0x3d94e8d1, + 0xed8831c9,0x509b2634 }, + { 0x48caed54,0xb1b9414e,0xcbf51e97,0x77a78c6c,0x4de9b258,0xa4688c8d, + 0x91ee3d78,0x0024137c,0xe30ee64c,0xa68f9234,0x88190d78,0x573255bc, + 0xba80690b,0x41e8e05f,0xec354f4c,0x50038d84,0xdfa52816,0xb18f02d6, + 0xccb63fda,0xc47f9007,0xe98ae455,0x29d480fb,0x5d0e319d,0x4ac45d22, + 0x026db719,0xd06f3575,0x2c3587b9,0x733b9e20,0x2c317727,0x22483992, + 0x54bb8752,0x1592d5a7 } }, + /* 162 */ + { { 0xcf7453f0,0x5778d9a2,0xed83c1f0,0xaffb899a,0xe0a82ba7,0xae6506d3, + 0xea3d5081,0x32c84e1a,0x810aa38b,0x9ad528c0,0xbd37d041,0xb1fdb020, + 0xd06ce41f,0x78d6cbe1,0x2e74b7f6,0xd287f0f0,0xc43bb022,0xf5cd2575, + 0xf81a71b3,0x6d28f2f3,0xc633e7f4,0xe65bb1f5,0xc4fc580e,0x32e5fc1c, + 0xbb7b07a5,0xcd55539f,0xc3caaf3a,0xb5a94471,0x4cc22d2d,0xb958bdf4, + 0x77a2777c,0x1614bdbd }, + { 0xed0ab04d,0x4c1f0230,0x6e2082ea,0xae347b00,0xc42c5b5f,0x9f10bc63, + 0xde019935,0xb0539e6f,0x65dd0825,0xd89bd4e7,0xbbceda16,0x92260fef, + 0xe62aca32,0x8aaa755c,0x5ec82c5f,0xed762fa9,0x18650768,0x99e64c01, + 0xc92e348c,0x57dd6245,0x31ea6d68,0x0db88a77,0x07b44736,0xef0012ab, + 0x171d70fe,0xb9356b94,0x03f891b0,0xe68b0628,0xb79c20a2,0x3a54a53a, + 0xb00b0728,0x489656c7 } }, + /* 163 */ + { { 0x71353c25,0xe43649ba,0x13f67e24,0x517f27a1,0x1c1eb9e3,0x10bd333a, + 0x78e29bf9,0x94e1c05c,0x4743f15d,0x84fe7d97,0x90da2df0,0x9c874908, + 0x53673be1,0x82403fa7,0x1baea1b1,0x7ebf5db4,0x24180ead,0xcfe0ae35, + 0xc2f50c3f,0x1d15873f,0x70661cd9,0x16851ad6,0xa51e8c2c,0x802968d9, + 0xe0161099,0xe7d1a9cd,0xa8a7ea56,0x2b153c89,0x06e3c498,0x6d41b789, + 0xd6769dcb,0x082bb2e9 }, + { 0xc4d6615f,0x6180ef46,0x01b9829c,0xfc629dc1,0x0fb264ca,0xde222ec0, + 0x10ecc2c4,0xc5457e06,0x1eea2c4d,0x95ce599f,0x8f9c5b2c,0x0433fa72, + 0xcd6310f9,0xee035462,0xce2e2253,0x84c57c3b,0x96d87e44,0x6c8ec31a, + 0xa452c5a7,0x30bfe393,0xa047b235,0xc592b140,0xc018545e,0x7bd8be18, + 0x5c178c46,0x794e0107,0x2e23005b,0x48471946,0x622a54f3,0x2665e237, + 0x901c9042,0x36451a46 } }, + /* 164 */ + { { 0x19893e71,0x17802d18,0x539a2082,0xa1765d8b,0x2302ecfc,0xfc6aea01, + 0x365bf59d,0x8d4cf51b,0x0d232a80,0x87741d72,0x18e80427,0xac343eb3, + 0xe74739ec,0x553ecb2f,0x1a8b07ca,0xaeca79a8,0x56f4ab3a,0x089ff322, + 0x3fa1d1f7,0x5e95d729,0xf62a9a16,0x260569ae,0xaa08ddc2,0x5e776232, + 0x1b7bb54a,0x93fabec3,0x743d56e7,0x48a20956,0xeb0ebeff,0x749cdb12, + 0x69b8fcf1,0x705307a4 }, + { 0xe488310b,0x7a8e4c04,0x5325cd7b,0x12726e32,0x4983efac,0x5d0fd8b0, + 0x02ddb913,0x796e552c,0x77b9685c,0x0eeca3f7,0xb15f24a3,0x9b766e89, + 0x48efc979,0x7c2736d6,0xa8021c6c,0x3d619685,0xa0b2f1ea,0xfe33e278, + 0xb676d6b0,0x95c69879,0x1af4e0be,0xa0747319,0x36c4ee55,0xa2fab5f1, + 0x59e5f3b9,0x6938b8ff,0x39cafe6e,0x1e114da4,0x6a6ad120,0xc9595ec3, + 0x57e62aec,0x80f79bd0 } }, + /* 165 */ + { { 0x60af09b3,0x3cef42a7,0x933dfe14,0x3c016ebd,0xed85eaa8,0x720cf1e0, + 0xceaa3bc9,0xd4f5e99f,0xb7106f97,0x7216b9d2,0xc9668ad2,0x65f34c36, + 0x5b0c651f,0xa8fb82bc,0xf2fda4de,0x20f42f1c,0xd21f659e,0xeb31ab2c, + 0xa13d1618,0xb7a776c7,0x38662be5,0xec441022,0xcad08e0b,0xc825da70, + 0x022c0180,0x99299079,0x2aef9ffd,0x7623bda0,0xf5c58b50,0xde84f4f3, + 0xd824ff19,0x5f5a5da4 }, + { 0x7e8311dc,0x5737257e,0x466cf136,0xdef94f51,0xb05ca21a,0xa73e1645, + 0x02e4ab37,0x38ea9b3c,0x8579165b,0x7760eac9,0xc24b01a4,0xdffdd047, + 0x3fb95584,0x188d4fd1,0x25548bda,0xfaac38b8,0x59e9dcac,0x1a79a6f0, + 0x09a2700f,0x983f720f,0xfb8a7e48,0x8cbba554,0x47a1fad5,0x38a19968, + 0x5abd6b5e,0x11856547,0xf3716ec2,0x75113d31,0x4212907b,0x1391e781, + 0x0dc15889,0x5319c801 } }, + /* 166 */ + { { 0x6b61c3af,0x2320136e,0x07b4bb68,0x1d40f2de,0x380c97f0,0x651dee7f, + 0x6a8c313a,0xa978ba70,0x2011ca10,0x22c587d6,0xab1f445b,0x48bba218, + 0xe50444e6,0x8c5eaf07,0x442fccf9,0x5549f02a,0x3d80493d,0x2564746f, + 0x79c04591,0x42d24f61,0xabdc8887,0x1600fa18,0xded38f8f,0x5cb8600a, + 0x923aeb46,0xa4bf9b90,0x1e1c578a,0xd63fee35,0xebb9ea14,0xf3c9c5ac, + 0xf11a4ff0,0x3d13314d }, + { 0xb4513d1e,0xe5cc662d,0xd55952bd,0xde78a8c5,0xe7f86d0a,0xe8a37a3f, + 0x7a04f0c5,0xca2d12a4,0x2e25d06c,0x4c6696e4,0xb2136071,0x52614698, + 0x89f6e1cb,0xf4d2701b,0x80efd95e,0xaafd6177,0xc5bb6907,0xe6d73ac4, + 0x420db35a,0x49e874ac,0xf2751fa0,0x11631de4,0xa1fa2edd,0xb29f7336, + 0xb7fd794d,0x4c406864,0xe22f92a6,0x73cb21d3,0x2043cc76,0xeae904e6, + 0xb322c6ad,0x67f28a9f } }, + /* 167 */ + { { 0xca148ab5,0x7c17b258,0xb3c60051,0xb9a1976f,0xc8f28df9,0xea260698, + 0xe8d45017,0x87b2cc74,0x0578a422,0x37257329,0x17bec732,0x81d5ee25, + 0x1d48bbc4,0xd7411fcf,0x487f5cfe,0x46217e6b,0x41eb8e1b,0xcb007ac5, + 0xe05a00c8,0xc41c57a6,0xd2f9fa99,0x1f954d2b,0x40941cad,0x370bd5db, + 0x3829509d,0xe487879c,0x5ceca5ee,0x4c137552,0xfd3efb9e,0xe8ef7fa4, + 0x1bd1bdb2,0x5ff09174 }, + { 0x579c6632,0x791912a4,0xb8a20815,0xbb19a44f,0x535639d3,0xf4f97b84, + 0xbc3c9bce,0xe57e2bcb,0xf19e6410,0x122b3f2b,0x1357d9ad,0x1f0189da, + 0x79e5ff66,0x675573bb,0xef2f3c4c,0x444e5c98,0x04d10731,0xd6f61e20, + 0xac75d635,0x0dfa366f,0x2c854f23,0x9fc47c86,0x0ad0850b,0xc04ae43e, + 0x2f720c32,0x5ce94f64,0xa753bc9d,0x67efae65,0xb0373a63,0xc27d30d3, + 0x29721646,0x6681013a } }, + /* 168 */ + { { 0xe84509df,0x1385d913,0xcf339376,0xe978bedd,0x3423a148,0x2df425d3, + 0xee8cb579,0x43fa0ae3,0x31c4553c,0xf015369d,0xdfbf1d48,0x05cf08bb, + 0x9444244a,0xadff4be6,0xa35dda33,0x01635f81,0xe76fab7c,0x085c8949, + 0x16737783,0x4bd7fcde,0xa254f8d2,0xfd8cb52c,0x413ec985,0x62168a66, + 0x7a9026cc,0xf2db9741,0x50e1e1b7,0x3962ee56,0xd3beffde,0xbee0a346, + 0x0bdfab1f,0x3b35b72f }, + { 0x535c3749,0xbff8de9f,0x8add9c48,0x23c1f20f,0xc8f8f663,0xa975b37b, + 0xe8f3ae49,0x2529e475,0x1d5e2628,0xc32f10d5,0x67862f1d,0x5ac0d297, + 0x854cbe36,0x13c79338,0x4b67e462,0x48f004ef,0xe5d10ee1,0xfa37a150, + 0xd28288a0,0x4974778d,0xcfb73f4d,0x96830a66,0x07804952,0x9f444013, + 0x9760b694,0x8233c709,0x25b75c99,0x8340cca5,0xc771f99c,0x3f62e40b, + 0xcd95c685,0x47d0a1eb } }, + /* 169 */ + { { 0x652811f1,0x266f4fff,0x62ef3002,0xeaacaa93,0x50cba0ca,0x6c387a55, + 0x007f5467,0xa350142a,0x202f2673,0xc7fd102a,0x33dc6e65,0x5daee570, + 0x064a63d9,0x60682ec3,0x462b251e,0x46cf0bb0,0x5da936e7,0x0e030ca5, + 0x434265b5,0xc87a60f2,0x69b4e8f5,0x9637b2bb,0x7ad7770a,0x601fb58c, + 0xed3a15a6,0x1f2147f6,0x2995e961,0x05b47d5e,0x83213a16,0xcb0ca9b3, + 0x4995a85c,0x8f4b614a }, + { 0x4b4eb3c1,0x5aa8ec19,0x20323a70,0x8c549ac4,0x4f6cc6aa,0x00d49322, + 0x45f9a5a3,0x0e53b9bb,0x0897abbb,0xe46ef110,0xd7acd7d0,0xfe873e57, + 0x0f7cb588,0x7cfccfe5,0xc85557d1,0x0ea53d65,0x7288f2e2,0xfdd9eb44, + 0xc0eb68a8,0xab2dedfa,0x08603a0c,0x58221470,0x00feb06c,0x69464689, + 0x25e5caac,0x804cf5bf,0x9fc91ae9,0xd8559858,0x73c45eae,0xed9378b1, + 0x524c9801,0x8f942d02 } }, + /* 170 */ + { { 0x8e845808,0x1f1ec302,0xb77abfc5,0xc302bffa,0xf8d97dc7,0x26afd4b9, + 0x3aac594b,0x3d3a83c4,0x674d94dc,0xe3b74bd1,0xcaa5911c,0x4464b737, + 0x871c2cd2,0x62925773,0x3b4440fe,0x419f2485,0xe052ad7d,0xdda6a0f3, + 0x846c86c0,0x645280d6,0xf8324f42,0xa25689fa,0x07cf117a,0xc74ad1e8, + 0x8ddc9db7,0x5626dea0,0x966fc85d,0x52620373,0xf3b1eb53,0xe0ad57c3, + 0x949c1acb,0x38300252 }, + { 0x5e744723,0xa0ef5a40,0x1ae08481,0xdb5bcf75,0xfec1f76f,0xabfad8cc, + 0xfab37fc6,0xfba5d831,0xc8fedb78,0xbe39e248,0xad93f310,0xa5cfad5f, + 0x913d5c24,0x747fdb1e,0x4518b7f5,0x052a47c9,0x7cfb4327,0x9e208d6c, + 0x70e538be,0xb135cb9c,0x5bb17916,0x36352759,0x5b3106c7,0xa2c07880, + 0xc209bb06,0xd2d42a06,0xd3c504ad,0xb525b471,0x822ce034,0xc9f4b368, + 0xeb4185a5,0x15f18796 } }, + /* 171 */ + { { 0x0aee4684,0x094dea06,0x7cdbdbc8,0x42b21f06,0xb1931319,0xa439e149, + 0x81a7dba6,0xea4bdd41,0x3c2ae80f,0xc6213706,0x12823dc2,0xb58b0967, + 0x832611b1,0x7443d515,0x13c20384,0x2e16f831,0x2bd992d2,0x0ce204d6, + 0xf419388b,0x499dbcd6,0x1d3778c7,0x492ded1d,0xc5ddae73,0x9d5bd74f, + 0x994b6259,0xd4813d52,0x0e86ca68,0x191d9cf6,0xf3e9c2ac,0x562179ea, + 0x9fee1238,0x6146f1f3 }, + { 0x078e2aa6,0xbd06d33e,0x9dee9265,0x693af7f7,0xdaa40e84,0xd56e0f81, + 0x9b9a407e,0x05fbbb88,0xede99519,0xdcf44adc,0x092dba39,0x7f71f8d3, + 0x4231774b,0x675b5da5,0xa5f605eb,0x7456a251,0x87a39a9e,0x9031d4af, + 0x05b474bd,0xdb430006,0xb665aa91,0xbda5dbf2,0x6631eeb4,0x5d1a3df5, + 0x62377c58,0x028149ef,0x685d0bff,0x2e1af4e9,0x82a465de,0xe0ea0875, + 0x06bd0050,0x95543f9e } }, + /* 172 */ + { { 0x85d7c6ef,0xf7cbc6f4,0x63b1bc24,0xcad8084d,0xbf8cba62,0xdf90ce88, + 0xb455c192,0x98e4b686,0x774fc6ed,0x6146b8d5,0x7ae20077,0x70e2389e, + 0x61c22529,0x5241c479,0x3884e5f5,0x7d221510,0x17e28273,0xd6d20ce2, + 0x4f2674f8,0xe3119f51,0x70c011db,0x85459055,0xfcfb760e,0xdfab75d9, + 0x9e8c2a19,0x9546362a,0x4a7d4b27,0x4b6d3f8a,0xee5d698c,0xa5c87104, + 0x2ba296ff,0x6db43478 }, + { 0x5c3f0d95,0x06486493,0x4e748895,0x8917db82,0x6b2f3e44,0xf73fdf62, + 0x2b7f574b,0xc60edc54,0xaf732723,0xbe1c09a2,0x7cad114c,0x7d34669d, + 0x321aaff9,0x9646600a,0xed0cd61c,0xb94e2bba,0xdec4750e,0x866e1a41, + 0xb1a89f58,0xa1be990d,0xf2759693,0xc39e4d6c,0xc0e0dddf,0x11cfb780, + 0xd99c8a41,0xf0afcd7f,0x6e1c3050,0xcebffadb,0x96d2c6e4,0x4f3981b0, + 0x2ae27a94,0x07a791e7 } }, + /* 173 */ + { { 0x1e9f0300,0xe70e9047,0xbccdf904,0xe0253ad9,0xff053078,0x51c0289d, + 0xae893462,0xf1ef092e,0xa4846845,0x2c90a91a,0xf1dad4b4,0x1946eda0, + 0x33df67b2,0xf07650f3,0x0b15a014,0xc6e988db,0xb542f0f9,0x72e0c66e, + 0xe0c0378f,0x5d4b6311,0xae86950d,0x548badaa,0xb35f1c8f,0x6801638d, + 0x944d1ad4,0x129e3216,0x40471d32,0x9951bac8,0x85e94dde,0x03cc29f3, + 0x4543ecac,0x6d6acc2e }, + { 0x57b2d299,0xeb999e95,0xe3d721cd,0x3a2bcd9b,0xbb4cb444,0x2e60384f, + 0xdc060faa,0xae177709,0x8c987cde,0x74f0e6d3,0x1076fbed,0x9a237cf8, + 0x7983fbff,0x69af1513,0x323f9584,0x6c3f7a1d,0x6db64398,0x3e21cacf, + 0x96703d92,0x7cd8134f,0xb8393f76,0x0755898f,0x2e825222,0x1b5b28bc, + 0x7924aa7c,0xb78799c1,0x81427a8a,0x1db378f2,0xff289492,0xd5a451b1, + 0x3d3c46ee,0x79d18212 } }, + /* 174 */ + { { 0x109d5589,0x1a3edff9,0x029b4499,0xded52eb4,0xb4b54adf,0x13eb9d30, + 0xa27bff67,0x4f9214c1,0x67f0f460,0x4c817ee7,0xc3a50e28,0xbadf8d83, + 0x94026237,0xc5dc03c9,0x966647c1,0x5f29581b,0x8a0687f3,0x10b6a089, + 0x31634517,0xae787cec,0x62e75188,0x2001dba5,0x45e2c3fb,0x55d4e1a7, + 0xb67d3395,0xbfcacdeb,0xbc6842ee,0xa1a0af9c,0x3e88580b,0x50590a2b, + 0xa784cdc8,0x73104491 }, + { 0x2648d676,0x44ca2cdf,0x4f1b12b1,0x9a85eca5,0x2980e1eb,0x1b9dac94, + 0x1ac8aa89,0xf30d3709,0xc719e195,0x73072ab7,0x2f703797,0xba518c82, + 0xac0067f6,0xac090e14,0x8dcd2927,0x0e6cfc70,0x21e7da63,0x4f5889e2, + 0x8371c7c6,0xb4aaa40b,0x8f7878c9,0x1f9dabe2,0xd84caf3f,0xf78aed6b, + 0x9e0e1d92,0x3c39dd07,0x122424dc,0x680be5fb,0x0bdc0099,0xf41b214d, + 0x5180c54f,0x6a8f8fc9 } }, + /* 175 */ + { { 0x53235132,0x62a1ed63,0x59dba88b,0x1db233f1,0x291efdd8,0x85625452, + 0xb25111ae,0xc7505297,0x1d701bd8,0xb5921af9,0x9774f45d,0xb4d05d72, + 0xf18e73ff,0x6e3d4c5e,0x899b3038,0x897d985f,0xc89b1558,0x8a9c30fb, + 0x4d13181c,0x3c92d1a3,0x2223320e,0x292e86ba,0x01ceed02,0xcf2454c2, + 0x583f309f,0x27a45f74,0xad0fd1a3,0x75a6102c,0xcb9c7538,0xdb4f45d2, + 0xdb283fd7,0x4752d8c1 }, + { 0xd5dff4d5,0x514d6cea,0x45a827f4,0x74cd5fdb,0x4fc7135e,0x1070a60c, + 0x1be5778e,0xdec0bb78,0x58dc6b08,0x271e12cd,0x54bc2496,0xb765089b, + 0x619098ac,0x6ddf2c63,0x67528832,0xfd6ebac6,0xc2508af1,0xeaa2d025, + 0x4dcfc1f0,0x13c2cda8,0x45510be0,0x1c7836a8,0x1a886801,0x3904688d, + 0xafaf2545,0x643132aa,0x2830a88d,0x49685577,0x8744b470,0x569491ca, + 0x75fb8552,0x3a6518f3 } }, + /* 176 */ + { { 0x224042a0,0xaaa8ed50,0x2452f1e6,0x6cb4e3b0,0x768211d8,0xedca5f4c, + 0xef4d5d3f,0x4e0fe3f9,0x522d46e5,0x33a8e2a4,0xf1446775,0x5998e21f, + 0xf592d01b,0x1496c50e,0x83a67739,0x69104c2f,0x472bbf00,0x28670bcb, + 0x503177bd,0x8ea883b2,0x7d2712a2,0xc5d8bc05,0xb439c994,0x41ef9317, + 0xdcda1aff,0x9801d3a8,0x7038f6fb,0xd686eeb5,0xfbfbf820,0xe80c5cd0, + 0xedc25817,0x540ac363 }, + { 0xfe7f43df,0xa71969a9,0x2c1b9e4c,0xe6653808,0x859c2917,0xad9677d8, + 0x96aa4404,0xbaca9545,0xff1297da,0x0e9d855f,0x22aea7de,0x1f61897b, + 0x36f13f8e,0x96edccfd,0x16e200df,0x627d3070,0xc98988a4,0x729f0736, + 0x97f231d2,0x95e25e60,0xf6048752,0xaf7f221b,0x4019b299,0xd6682609, + 0x26b4b1d9,0x1d99de09,0x1acdd7a3,0xec47cf66,0x6ebe15e9,0x4de9f2b3, + 0xfa16974f,0x17db32ec } }, + /* 177 */ + { { 0x6cf40599,0x75ef6919,0x00c020ea,0x7ea10dfb,0xfcaaf679,0x3da5ae7b, + 0x88ddd678,0x0d663ca3,0x255bcfcd,0x5a21f8fe,0xe344bc7e,0xe9c3f538, + 0x548e0632,0x35f62b1d,0x43c6e64d,0x654f2425,0x26993627,0xc755a7a6, + 0xb0f41324,0xa3b7c5f7,0x3a2180f3,0x05697f79,0x1e81675b,0x6cf85fb1, + 0xe53428f5,0x6d3cdb35,0x52d28b02,0xe3aa1591,0xf7a3fb78,0xa8470255, + 0xa194445d,0x460bd01b }, + { 0xc24d8077,0xbc34dc23,0x4c720d2c,0x82f4b580,0x6f5d1ffe,0xa29da911, + 0x92783ce2,0x578af520,0xb5904af3,0xe29f51ab,0xf7aa1190,0x46c570d7, + 0x571bddf0,0x4a522fba,0xae89bb51,0xbf4e2a06,0x59f3444d,0x799b35cc, + 0x26cc2557,0xc3028367,0xafcec177,0x94a4e985,0x7c36cbd0,0xadaf7dcb, + 0x75d39077,0xed31b787,0x2d3e24bc,0x52d6904f,0x1f95421b,0xc5ca2669, + 0x1734878d,0x7d342c3c } }, + /* 178 */ + { { 0x11fd127f,0xe5cf2c0a,0x119e4c5e,0x66d36bb8,0x6ef56ac3,0x621ab252, + 0xe5430675,0x30cfeaee,0xac3e9619,0x2ede27d2,0xf8fce671,0x6413513a, + 0x075f4c3d,0x6159c61b,0x59069d98,0xd447efe9,0xea76aea9,0xaf8d6f68, + 0x0f5bd164,0xac5dc61b,0x1e88bb98,0xdbab446e,0x1ba92320,0x618b8b16, + 0x78989865,0xa0eafb3c,0xc08b7e82,0x0c7abcc2,0x20d160bb,0x10f09b6e, + 0x8e4c63a7,0x5be0afa6 }, + { 0x1bbbf49c,0x82ab6d38,0x8c0703fe,0x3e09ce49,0xe10f4263,0xeca58b5d, + 0xda5a4532,0xd9cc6581,0xf618f7b7,0x07e18876,0x250f7fe7,0x0419a5e3, + 0xde6b86be,0xbb1a9e90,0x37359169,0x584a7deb,0x5149db2c,0x38eb3489, + 0xb0ebabb8,0x14546a33,0xc2f88a92,0x0067f0b0,0x0a2db019,0xbde0dfe7, + 0xc63e6f3e,0xba51b06c,0xe9206fad,0xa19127b9,0xfe80dc0a,0xe4eb5e87, + 0xd4de30ae,0x1e6fccf5 } }, + /* 179 */ + { { 0xaa8ac924,0xb57dff66,0xc298b3e8,0x06e9ad31,0x65fb080c,0xd140e329, + 0x1d95c93f,0x7dab211d,0x8a180caa,0x6d68d842,0xa20ded69,0x1a929408, + 0x38df461f,0xa8151753,0x60eae932,0xff5604ae,0x7dae4c0b,0x901b9e49, + 0xde262e89,0x4573a97f,0xf1084983,0xed69d9a4,0x64724f1d,0x8ffa022f, + 0xea85a15f,0xd5f1c2e4,0x01453794,0x4c626ce9,0xbf0907dd,0x80440cd6, + 0x5ddaa837,0x4522d461 }, + { 0xebfbe7c5,0x8895f079,0x84ef3446,0x30ea1ded,0xd4a1ab96,0x716a9eb6, + 0x50a30c68,0x1a4a5d22,0x0043bbaa,0x5a16631c,0x5010e5f5,0xbd107502, + 0x3d8c0556,0xbffe3e9d,0x07772419,0x31b30b18,0x84b82297,0x90ff7ef0, + 0xf21a18c3,0x00c37d75,0x565bb8f8,0x18d0a635,0x45e3bceb,0xbac1da2a, + 0x23f0b08d,0x1c38e90c,0x5fbc5ac5,0xf1ba1aa2,0xdda71fc6,0x09d5256b, + 0x6d7e40ba,0x346501a9 } }, + /* 180 */ + { { 0xcc2b0f1d,0x86be448c,0xac4c3703,0xe3eb45c9,0x9fc96bbf,0x5387f65d, + 0x5ae27fda,0xcef3c4e9,0x1bc18089,0xa008f776,0x22ca18a1,0xf374a084, + 0x53b73371,0xee882842,0x7cc09354,0xcb6fc6d8,0x61496d6b,0x8489ec1b, + 0x49e325c4,0xa92c29b9,0x7bdec166,0x15c6ca52,0xdcea2813,0x95444eee, + 0x3a21154f,0x34683eb3,0xd39061cf,0x8fb26f98,0x06c940bb,0xc3b08aa8, + 0xe554c96d,0x7c1d42cf }, + { 0xdc110aa7,0x766e703f,0xf362e378,0xab7b79d7,0x5aadca3c,0xd259c75d, + 0x60be3373,0x2a6eca79,0x06c4e8ff,0xf4744a4b,0xf3b705bf,0xb2842cce, + 0xae304b53,0x1a3af5aa,0x1b2d31b8,0x7bbfa201,0x4bee88d9,0xc4ba6eba, + 0x565cb839,0x2d3565ce,0xdaf7ece8,0x24808696,0xe6959745,0x2c7ccce7, + 0xe94f9837,0xefd6eb3c,0x3811a326,0x0a33b4cf,0xfffa93a6,0x14203f43, + 0x73c31d90,0x031e9828 } }, + /* 181 */ + { { 0x765a17ff,0x4fefecfc,0xd1290a65,0xa09f3888,0x938da038,0xbf265c46, + 0xa169ad46,0x4bb6145d,0x23a62fe8,0x33cf8214,0xabc860a5,0x562df571, + 0x815c38c4,0xbf2a90fa,0x17eda875,0x45ba1d6e,0x946fa5e1,0x799d881a, + 0xb90f5a3b,0x6c1be784,0xb10ff52a,0x0910a37c,0xa4f4fd36,0xc38c1fe4, + 0x8e2d3ba0,0xc3180fc5,0xb17a6187,0x3e2ff050,0x943a35c2,0x3a00059b, + 0xa28cc51c,0x494d3645 }, + { 0x4ba021f8,0x398426b6,0x796deb6c,0xd14c9083,0x7e36c762,0x6d2e5395, + 0x751cf216,0x8f556eca,0x19b24a19,0xdaca1e00,0x4b20c2ae,0x47887da4, + 0xff41a733,0x93ed4ccd,0x5c7c0cd7,0x8d717c44,0x91bf7009,0xcc48634a, + 0x3b59bbaf,0xa1f146f9,0xe5624f15,0xdd38bb39,0x303f8443,0x96d41aad, + 0x4bf104fc,0x6b670f03,0x29706582,0x0503f9ed,0xb34200f5,0x768e1f47, + 0xbbd4c6f3,0x3cfdcc5e } }, + /* 182 */ + { { 0xb523e13d,0x536c2a86,0x2920d0a0,0x1014a458,0xe7571296,0x3d52b478, + 0x7eb51bea,0x05746066,0x87b0e919,0x709f7861,0x686888e8,0x028aed88, + 0xd94afcd4,0x79a809d7,0xe2129af3,0x50c6032f,0x983c4082,0x75e4be72, + 0x7ab3be8e,0x98331bbb,0xb618c728,0xd31a032c,0x3f59c4a4,0x36dd85a1, + 0xed4f61e2,0xdbece345,0x1e571715,0xba7aaccd,0x64a1ebd7,0x138c58da, + 0x3d1aeea1,0x89296d0f }, + { 0xcca82c97,0xb165288f,0x1427e8dc,0x26c6c12d,0x4c3edda9,0x66a94f07, + 0xeaa01ebe,0x94600e1e,0x30f5e86d,0x14abce7c,0xcb456a31,0x741d7020, + 0x279f42c2,0xab05aa13,0xd4238468,0x70b60faf,0x318d39e6,0xa18efec1, + 0x8920b318,0xeb07f1ac,0xd8399e03,0x01e3cba8,0x3c81a301,0x65f8932e, + 0xccc667d8,0xae8bca7d,0xa268607c,0xcee1ae79,0xcac0a12c,0x3182e64c, + 0x2b1a4c54,0x9233a2f7 } }, + /* 183 */ + { { 0x0acbee17,0x717e8df6,0x5c24fcdc,0x0f0959c2,0xe54ffcb0,0x46f09887, + 0xd285116b,0xb993deca,0xbba1fa51,0x0bfaa4f8,0xd0f2183e,0x9c9249ef, + 0x96847779,0xf93cb358,0x2322d421,0x284bfb7f,0xd42af009,0x40cc709a, + 0x9bb1d615,0xc69f2274,0x717c3c6a,0x76f50b3a,0xbb9c5eeb,0x8b21e985, + 0xa4783b5f,0x58fb19ae,0x52e1c3e7,0x04c86b9b,0xf2971ac8,0xaca59092, + 0x21ed8291,0x2bb26a69 }, + { 0x15f81416,0x98a34435,0xaaff5bb4,0x086e72e7,0x0317261c,0x3d1f64de, + 0x5c0a1cfe,0x31c0786c,0xb3683401,0x542ea4d8,0x1a39b4cd,0x2f77273a, + 0xcbef27f1,0x14fe7ee1,0x16bb27dc,0xee7fc09e,0x410e5dc7,0xc0dccc17, + 0x1943b3dd,0xa3466742,0x3f31c1b7,0x92934b60,0xc22c1070,0x0186ded9, + 0x799f966b,0xa37ee8ba,0x249b0893,0x0f3bfcb4,0x2e92d4de,0xbae61447, + 0xe196eb08,0x937cb3f8 } }, + /* 184 */ + { { 0x16fbfdce,0x57c0e77c,0xc98d4cc0,0xea034cc9,0x42572d20,0xe7606d72, + 0x0019a83c,0x9861b55c,0xf1597162,0x80ba2803,0x05a0fd7b,0x0f4141dd, + 0x4b0daaa2,0x8865913b,0xaa3848ec,0xe6685746,0x3e0485d2,0x16d15a5a, + 0x3b6905dd,0x81c0c774,0x818af2ba,0xcec31b7d,0xd2b74b78,0x80d8f194, + 0x543e2f28,0xca659db2,0x9fb07c1c,0x31b83a7d,0x1f1048c0,0x86537fdc, + 0x78586a11,0x4d57bb07 }, + { 0x53b396b6,0xbc4b768a,0x93b51dac,0xbc8b24c4,0xa30ae1b3,0x33e511eb, + 0x945147c5,0x893bbd95,0x179fe3ce,0x6cc86031,0x3f920bd4,0x34b0a167, + 0x6b256160,0xb32912eb,0x9d168d83,0xbc69a2a4,0xef0dd128,0xb4949e7a, + 0x872699e1,0x2613419a,0xbf21376b,0x06c58477,0xa4f97147,0xe55b1909, + 0x7b9b745f,0x63d6eb75,0x08df3c85,0xb5365b29,0x55fcfae3,0x0e257e43, + 0x979f2aa8,0x1067c118 } }, + /* 185 */ + { { 0x32bf8883,0xc8455084,0x6fd06667,0x4755286a,0x77c2335d,0xd70b0f8f, + 0x2f4a2c94,0x678e60da,0xd118acf5,0xa468d8ac,0xbf5b90d9,0xce93830b, + 0xed4e9104,0xea4b1c74,0x27776ea4,0xac67316d,0x361bab12,0xb98ad75c, + 0x99122451,0xc323d482,0x530a43ae,0x26440220,0x3292d5a5,0x3a44532e, + 0x5fecf1bc,0xdb48694b,0xc667b8b8,0xe4e0516e,0xa4306ade,0xb3aa595f, + 0xf34e9725,0x7e4f7091 }, + { 0xb7f70919,0x3f3816e9,0x16b003f5,0x765216ed,0x778c99e5,0x46c6cff4, + 0x30a51810,0xe6a5abe8,0x45e728db,0xef6f49e6,0xcaccefd6,0x6fdd73ea, + 0x8c37f3f7,0xec394e6f,0xb6407fc3,0x73320802,0x96625cbd,0x988e8f7a, + 0x7cabfb00,0x83292363,0x407f359a,0x258ba9df,0xccbfae50,0xff01aee5, + 0xfe251813,0xfbeaeace,0x83f1cba1,0x9c69f161,0x9eadcdb5,0x512c58ad, + 0x6ccce8bd,0x2ae49cd4 } }, + /* 186 */ + { { 0xc40849f2,0x1239b0e3,0xa441098c,0x5136a4cd,0xe547f649,0x61535a99, + 0x7a9bbac6,0x92e4bdc4,0x53547af6,0x195a1646,0x8b47a74a,0x85ecb319, + 0x9de6a2b2,0x278553fc,0x0e2ba52d,0x471c038a,0x35bcba93,0x12ba1b88, + 0x6f31eca2,0xd4bf50da,0x802b32c6,0xd146e3f6,0x3c64c8c4,0x0c9c0131, + 0xeed21297,0xad30f12d,0x9c68530f,0x9b75bffb,0x8918de51,0x23c0ad3e, + 0xa73771b7,0x180e9d52 }, + { 0x29ab77b0,0xc316542f,0xf7aee628,0xdd411d9c,0x353c2f40,0x044c0685, + 0x4b0ae4cf,0x638dc7e4,0x95fc266f,0xa0924185,0xfd2feb7d,0x639da671, + 0x5ea39798,0x56858ed5,0x58f3832a,0x7a694f31,0xd316d831,0xa94233c6, + 0x30a35a7b,0x2fcacb26,0xf1ff713b,0xfef8f7dd,0x59eee2f3,0x8b9b4525, + 0x156d064a,0xd1b4f91b,0x2f5cfcfc,0x177866c2,0x3777eb41,0x12bc2566, + 0xd8ab85b4,0x21ca6f3c } }, + /* 187 */ + { { 0xa3e66635,0x0e162b13,0x2a9f76af,0x1ef20a2b,0x46db3356,0xab473a30, + 0x7802bb8d,0x0840bd77,0xa699b44c,0x5b6baf5e,0x1b2207f1,0xc6e11900, + 0x790b0105,0xe5de16a9,0xdb67f004,0x22b12f15,0x8a025d25,0x185fad45, + 0xdf0a1142,0xbccf6953,0xf45034c0,0x4c42129b,0x1c277bff,0x0f740400, + 0x280a9e18,0x6e440b4c,0x842aa2b4,0x767de8f5,0x05e8d94f,0x3de20ab8, + 0x20227635,0x5aff5859 }, + { 0xa8458e40,0x805acd20,0x149732bd,0x5a5557d8,0x5f1ca72d,0xc7074131, + 0x952b5323,0x7f2e269c,0x6494fadf,0x5c592556,0x1a7d2666,0x153b7acd, + 0x86fe2865,0xa6df063d,0x57d53b6b,0x1e91db13,0xe93ead01,0x9195bb89, + 0x2963bfe6,0x3d71e1af,0x88278886,0xfab2b9c2,0x3b859b6f,0x77836692, + 0xf7029dd1,0x6e695174,0x7b984561,0xc7987876,0x5907d849,0x64fb4f1d, + 0x88d8a977,0x3eab7e1c } }, + /* 188 */ + { { 0x52e5718b,0xc73a94b6,0xf4cee1e9,0xe3aefa54,0x553eedea,0x654e9e63, + 0x5f3aca1a,0xf2541e1b,0x0d083316,0xd7129489,0xfb7f950e,0x7965af63, + 0xc74e3e4a,0xd8fc9e0d,0xeaf79ebc,0xb4ee48d2,0x8b7787e6,0xa458a86a, + 0xf7cceaf0,0xd8c7621f,0xdf67980d,0x8228eeff,0xf9106727,0x210d4742, + 0xb07e3629,0x91f63501,0x7971e29d,0x441761c6,0x03a3b8a5,0xc0ccc65f, + 0x38e09544,0x3491da4f }, + { 0xcb062eae,0x6706d046,0x5d08776d,0xee7db735,0x292315d2,0x80de8052, + 0xc402bbdb,0x40785662,0x26ed3337,0x5f93525c,0x7d568ed3,0x6cea14d6, + 0x66888b1e,0x916a1189,0x5dc71675,0x0fbd5205,0xe4575df2,0x833d1077, + 0xec092335,0x4e93100a,0x6cd85389,0x2f9e1d01,0x43226368,0xeebd3725, + 0x1ba4cfd7,0x401d172b,0x574c5838,0x377dab9d,0x80d517de,0xaeaa6958, + 0x6ad15a18,0x0c843dfd } }, + /* 189 */ + { { 0xc9373300,0x455811ff,0x99fdc300,0x1c39332a,0x353cb655,0xe19bb81c, + 0x96a83d27,0x774b924a,0xb2ee3f1a,0xcbfc8fcb,0x010d56c7,0xaf278ec4, + 0xe0abaf79,0x6fde682f,0x7339aebf,0x7566d072,0x71205db6,0xbd35ad5d, + 0x7051c9d0,0xb5bbe694,0xd3a3067c,0x577db480,0x572d7530,0x2c70ff54, + 0xe06d853d,0xe8615aec,0x05abfb5d,0x71999ccb,0xea0a8ed7,0xeeefc96b, + 0x35f6df69,0x2dcc469d }, + { 0xc65f0e77,0xcca6cd06,0xbd71b14a,0xddcc7980,0x3c93cc00,0xb6221f8b, + 0xae8cbf57,0xddfcd5b3,0x76f8e63f,0xbc92973f,0x06e132b7,0xe9848a34, + 0xd51ec9e2,0x4cc59a03,0x3a33081a,0x9c9d32bb,0x80e8466b,0x00121052, + 0x1bbe7295,0xc2b0032a,0x24938448,0xdbfc6572,0xb6bba0ff,0xe972a0ce, + 0xc0a94802,0xf60c0a4f,0x599d8bc7,0xf62c41cc,0x312da0b8,0x820c96ee, + 0xcdbdf9fc,0x5a1a65db } }, + /* 190 */ + { { 0x42485684,0xbfba691a,0x29c470c9,0x613116b9,0xe62a0519,0xb4b01971, + 0x5ff499da,0xf3245aa6,0xa5238eff,0xc2ef87f4,0xcc9d5515,0xc16dc6ba, + 0x2dbdacac,0x5a7f227e,0xa9bbaecb,0x8dedaac4,0x2e7c9885,0xff308a6d, + 0xe6895593,0x4c6f2fc2,0x177e0611,0x3655f285,0x300b1bee,0xa63e8d06, + 0x13c17b54,0xbed0ce79,0xc4974262,0xca4abe35,0xbc4e4037,0xf4b44a17, + 0xefe5fbd9,0x5ae95099 }, + { 0x804f7455,0x122e5ee7,0x22066682,0x341a4997,0x7795e333,0x97d24c31, + 0xe48efced,0x12f4123c,0x19fbc21c,0xe8738d92,0x0663a3ae,0xbb3bdc61, + 0x8593a6db,0x3603d8c2,0xe3c1ac75,0x926227f2,0x5eaae519,0xfea92ac0, + 0xfd6812ac,0x5b596f0b,0xfc2a82dc,0x3ce7e844,0x63522b27,0x3840481a, + 0x52867895,0x836088b1,0x26588688,0x21ffb7cc,0x2f4a7cac,0x0ca33161, + 0xa3edd298,0x4110667e } }, + /* 191 */ + { { 0xc2d04b63,0x81830357,0xf4929a18,0x3fc5a34d,0x22d195df,0xc73bf6da, + 0xcb432473,0x14df2f89,0xe997f138,0x345afe5c,0x8b9604f4,0xd8e3f5f9, + 0x50c10ae5,0xad7942e9,0xeed25ff3,0xcefd5447,0x0e73c0cc,0xbf68e51e, + 0xab54fa4c,0x5b1ad591,0x12b61c8c,0x8bbc1105,0xb5abf760,0xbb932913, + 0x01e79649,0xdb1231be,0x040ccbe7,0xd0a83e91,0x90a96db9,0x3dde426f, + 0x34df11ea,0x1cceb645 }, + { 0x0c6d0f55,0x2d210c4f,0x9c673c9d,0x6cadf61b,0xa9ce3fbb,0xdd7f9919, + 0x93b063e4,0x135f494c,0x145a93be,0x580bdb3c,0x0f52ef7c,0x4d872332, + 0x8814bb6a,0x74d876e8,0xc7a97dee,0x4f6f723a,0x3e3cd833,0x7de2b8f0, + 0xae720270,0x6162f082,0xddfa486e,0xe88ec2d4,0x8d3a17c6,0xd965c859, + 0x3980171a,0x62e59e54,0xbbef6b22,0x0ab6285d,0x4d48b203,0x3cf45195, + 0x4ea25ea3,0x1f175233 } }, + /* 192 */ + { { 0x3467ea91,0x808a765b,0xfd2d9c45,0x3f4632ee,0x9cf2bc6f,0x7b75dc6d, + 0x359813ae,0xefc8d240,0xe44cbd8d,0x23ecb209,0x21525622,0x59ba10e3, + 0x3f1ee19a,0xfa14d934,0xfb0c48f7,0xdf97c21b,0xea30d437,0xc4e62890, + 0x651475c2,0xb286e2a4,0x126672a5,0x291f01e4,0x31aab3b8,0x9c6fda5c, + 0xe17d22ec,0xb7277a5a,0x914f0bad,0xbd88ed83,0x6a2392e1,0xd0b05d1b, + 0x65893c2b,0x4cb8af90 }, + { 0xbb4b1953,0xa2b02057,0xf597f6ee,0x4ce08b44,0x5e6412c8,0x854f5d9b, + 0xb3cd4919,0x1913262d,0x6e42bb5d,0x902762e4,0xd78e7f60,0x8355c8e6, + 0x38b6c16c,0x8efaa824,0xe550f618,0xd0173790,0xe57d778e,0x118af462, + 0x715b4714,0xa16ad5e8,0x41dea4f9,0x900596c3,0x280ca610,0x2a957c32, + 0x374c65a1,0x2faee800,0x50080414,0xdb105127,0xff080fa1,0x8c1db931, + 0xd79878fc,0x486a5c25 } }, + /* 193 */ + { { 0x941b4f36,0x0521e213,0xf803b4f9,0xbaacfb14,0x52a54ba8,0xfdf1e22e, + 0x8fe4796c,0xacfabbba,0x58dbacb6,0xae0788db,0xc19dfa51,0xdf98d736, + 0x35a716ee,0x155c286a,0x9c86461b,0xbe7d4676,0x63a64a5e,0x50b6380f, + 0x9f609262,0x14b41914,0xa2dfc5b3,0x0919a7d0,0xcef466ac,0xc454da55, + 0x6986aaec,0x93fa4a24,0x71a49ced,0x5090b171,0xc1fa75ad,0x602f1d6c, + 0x78e4c054,0x5d269f89 }, + { 0x14920419,0x3a74030c,0x90968739,0x0845d868,0xeeb70fa6,0x81b994c4, + 0xd9fc5bcb,0xabcaa06d,0xf58f8f2d,0x06539427,0xb1dc52aa,0x35c85f67, + 0x2c911baa,0x5a7d8d72,0xaec2d834,0x4041005c,0x7a8e5347,0xb5868a44, + 0x8de512c3,0x04ee180b,0x211168eb,0x4daa66e5,0x2317cd8a,0xc0bd5dab, + 0x61164df6,0xa1d4185d,0x1dbad7c9,0xacedca26,0x09b02683,0x0fe4b5ac, + 0x26d9550f,0x8ac9995a } }, + /* 194 */ + { { 0x2640a39d,0xb2c8dc9b,0xede0c9f9,0x21ff0b38,0xa1ecba0a,0x74f469bd, + 0x080d0417,0x8a902ccd,0xf4994604,0xe956fa32,0x9776ab15,0x348f85cf, + 0x0066f492,0xc21fc6ee,0xfeeef367,0x35b1ebfe,0x4613e5ed,0x7804581c, + 0xea6ba071,0xcbdfe8e6,0x950d73ed,0xddfcaa32,0x1da48889,0xc9747936, + 0xdbaffbd1,0xce867c8c,0x1cbaeae7,0xd267431f,0x897912c8,0x68255045, + 0xd7ea1e4d,0x0c7c1ddc }, + { 0x1ce963a7,0x53aa30cc,0xc4c5fade,0x7352f64c,0x2828afbf,0x2b9aa2f8, + 0xca212107,0x64273c56,0x85a576dc,0xaadd7654,0x90b5c77c,0x6196ac3e, + 0xd1aaf39b,0x20d43e9f,0xcd05cbc4,0xfc392062,0x4c0ff2fd,0x14163872, + 0x2ae821e6,0xcf32b8d8,0x3fa7a3f0,0x5f58f943,0xf644ca92,0xaebf1d2d, + 0x1918a75f,0x0c061563,0x6b876118,0x7989b5ed,0xad412441,0xbf342445, + 0x1df633ab,0x24ffc9ae } }, + /* 195 */ + { { 0x93c7cb2b,0x89fcdc05,0x590053fb,0xc1243b95,0x6182343c,0x601debcf, + 0x66c18a63,0x364546ef,0xec913287,0xa5290701,0xf9788c31,0xc35b8026, + 0x92d1f7d7,0x852b862a,0x0aa79728,0x1809cb05,0xa3cb2005,0x897d467c, + 0x9ef5b946,0xf20c77c0,0xf2241984,0xc3372c42,0xf35bb206,0xda053e0d, + 0xa9c140b5,0xbc26c6d0,0xcb56fb33,0x61cfcc0c,0x299b3968,0x1c3cf9ef, + 0x40621ba4,0x89e4d3d1 }, + { 0xa45a9be3,0xd35e80e7,0x07356fbd,0xc4daa578,0xb967bc2f,0x0186d62e, + 0x47cd16e3,0xa702679e,0x5f30ce9b,0xca2f1c02,0x1f864f50,0xf1205b46, + 0x85061d66,0x7fd6d797,0x8a08809e,0x47edc4f6,0x9a4d3ae2,0x5dac0449, + 0x6d1f9da8,0xf844664a,0xd7a83a71,0x9f30ce84,0xeaac33f1,0xe9382bac, + 0x948622ab,0x1f033831,0xf7681eb2,0xb037a4ba,0x99a1b5c7,0xd156a908, + 0xe6f1d0fb,0x675d3e6f } }, + /* 196 */ + { { 0x707193e5,0xd9767ffd,0x810358e5,0xe478aa91,0x328d8ef7,0x5634f9ff, + 0x6dbbd9a7,0x913a0ee8,0x7e215686,0x379b2968,0x89d9da38,0x903f410a, + 0x1b1334d2,0xd9f8d7b9,0xbd82efb5,0x9fe74229,0x3803c778,0xdb568b62, + 0xd3d25344,0x93e9a350,0x724497e8,0x559c35b0,0xa169e23b,0xc472d436, + 0xcc5b4c69,0x09864632,0x83c7f531,0x9f6d759d,0x1e497888,0xa91cf1db, + 0x60af1a4b,0x5f7f92fe }, + { 0x0545167e,0xf18a1cc6,0xaffa88e0,0x55ee2e02,0x432a7bcf,0x24cdff51, + 0xa7510866,0x7382da42,0x40511af7,0xe894c11f,0x2aaf1423,0xaa4e4e31, + 0xf63dd2ae,0x8c3d36f0,0xd7660635,0xfc5c9550,0x37ea7eab,0x01253731, + 0x39b950f6,0x2a5cd598,0x40e63442,0x95a0f601,0xf2ac7045,0x905e238e, + 0x446b0f73,0x44bacc0e,0xc448578a,0x4cd4206e,0xa5bd7803,0x367b1aaa, + 0x0a2b458d,0x25beced9 } }, + /* 197 */ + { { 0x0c33a8fb,0x079a7382,0x0f25dc1d,0xcfbf6cd1,0xc6d482b6,0x4ffc73f8, + 0x07bf844a,0x3e51f18c,0x599162f0,0xa7651236,0x14013811,0xac59a74e, + 0xe55018a0,0x957a6865,0xe3ca09b1,0xe1ec51bd,0xa960253f,0xbc0c7eb3, + 0x7de03f84,0xe83bfd14,0x52fbdb09,0xc0540ed1,0xcea15ec1,0x6ba52edd, + 0x4b261307,0xf3d30ed5,0xe8397206,0x9bd7bae8,0x096373aa,0xf20d8692, + 0xc3b0bf63,0x0a616a4b }, + { 0x6e1339c9,0x2075f3ed,0xbf8b00a6,0x7afaa072,0xbccd9b47,0xdfafec82, + 0x00ca54c7,0x4713158f,0x38bc31ae,0x449102f1,0x310dfc8a,0xaf98f158, + 0x59e954d4,0xc9ef2075,0xc527a0c4,0xe8021af9,0x7a192023,0x6e801277, + 0x7fb02377,0x635f538c,0xe8c9e951,0x5df1974f,0x15cc9097,0x0287faed, + 0xf7a5115c,0xfa0728f0,0x0fac623d,0x90dbfbe6,0x0311ba09,0xa8d40fd4, + 0x07c6464c,0x876d154e } }, + /* 198 */ + { { 0xc2d3ea8a,0xd3a4d6d2,0xa842600e,0x36be681b,0xe4070672,0xc53f100d, + 0x6a7d7a7b,0xe3e5b6fe,0x5d5e1a83,0x6e6994f9,0x76097c2a,0x07cacd22, + 0xa6791011,0x12d98dba,0x102e0e24,0xddfc4461,0xd493272a,0x4815dbc2, + 0xa9436696,0x7e38e64b,0x32b2bf90,0x4960eb1a,0xd928e28b,0xda457525, + 0x2a077c9e,0x72f75b39,0x7fd61d00,0x27760cbb,0x0f4b1456,0xaf235d1b, + 0xe76d1700,0x3040c23b }, + { 0x4efa9a70,0xb10dc55b,0x53e86610,0xd4de414f,0x09f8a27f,0x3d95c113, + 0x06661d3c,0x505109a5,0x60eb513e,0xcaa2994a,0x1e7d338b,0x3ee41537, + 0x4651e71f,0x4fd145fc,0xcbc313b4,0x51bbf838,0x1eb92150,0xb039e078, + 0x14bf5ac7,0xe8696b44,0x8be0d48c,0x2d667188,0xdd8f2b6f,0xbe93b2f5, + 0xeb8a7f8a,0xc1dfd1e7,0x90f751c5,0x862b3dd9,0xa32a74be,0x1eb1ad58, + 0x1ebbc9a2,0x5486d79a } }, + /* 199 */ + { { 0xa1359e13,0xcb2e34ff,0x28196051,0x202d8dbf,0x23564b5e,0xe95e023d, + 0x42f6ac12,0xfb1340b6,0xb653725d,0x543ba852,0x8d2466ad,0x81aedcd6, + 0x547c728b,0xbf780224,0x9569fb65,0x559f8a11,0xdfb22ec9,0x505b7a62, + 0x9eed5e52,0x07107540,0x299f6f11,0x9c899288,0x3db6f8c7,0xa7d69261, + 0xb3ca79a9,0x30eb7fb3,0xfb2160b0,0xcab99bb8,0xd28b409a,0xd2012568, + 0x5ac45f8b,0x380f1b0f }, + { 0xe6a0068f,0xc0b99e6b,0xc8a73753,0x4b67cf2a,0xb2faeb7c,0xa6c9a548, + 0x340260c3,0x7f417f99,0xcc0f739e,0x8ee56855,0x780949da,0xf08b510f, + 0x8d5c6eff,0xb1770fc2,0xfd96a7bb,0xb4f5abee,0xf2665a2a,0xa07b1136, + 0xb601dcf9,0x2fb380a4,0x162becc6,0xcc803614,0xee6b83b3,0x3498fb96, + 0xa8c17eeb,0xea9b0fd6,0xa177efc2,0x5834b5ba,0x5b110b3e,0x929044f5, + 0xebd7285e,0x4abedded } }, + /* 200 */ + { { 0x700ef376,0x3355e1b9,0x66cdabff,0xd56e5d9a,0x47e87646,0xb3dc2575, + 0x00f79369,0x28f44b8a,0xa0c52e29,0x08c32b1e,0x3729b392,0x5a78de12, + 0xb26d239d,0x4184519a,0xe0ce4a6b,0x23f6b4b7,0xacb2a9f9,0x235f6f8a, + 0xe2064a59,0xbb8bc454,0x1bf3062e,0x37efd034,0x94dff6f9,0x6bac683b, + 0x8aa7fa06,0xc3364b1e,0xce0b3745,0x0616772a,0xd1e3fb0f,0x46f08d08, + 0x18e132d3,0x6a20abb3 }, + { 0x6a85cbc7,0xea831016,0x934f9aa7,0xd0990946,0xe778f1b3,0xc2211088, + 0x2247b799,0x7ea4ff8f,0x454484ce,0xb3171d71,0x4f98c364,0x29403949, + 0x97df1458,0x5da911f3,0x09439116,0xa6b58093,0x174238bc,0x75f9509a, + 0x8209758d,0xfeb51821,0xa47925d0,0xae0c6021,0xaf8a315e,0x0e946694, + 0x6bad04b7,0xae7af8a3,0xf072447d,0x44c15e7f,0xa5456ffe,0x5184668a, + 0xbf36b977,0x45e353a7 } }, + /* 201 */ + { { 0x93092f71,0x76056764,0xf5b92d71,0xeb66b6c2,0xe2c8b6c5,0x9db3149b, + 0x20c0363e,0xf62f583a,0x03cd7097,0x688acd33,0xebb916ac,0x85d0c0f8, + 0x84c19b0e,0x1bf7462c,0x7c4a6ad1,0xc76ed5f9,0xd119f369,0xec8b88ba, + 0xebe50b83,0x59b8371b,0x866706a6,0x0cc69508,0xf8373d2c,0x531c75a3, + 0x2a5a02fb,0x4e1cd3a3,0xda39a1d0,0xe8274778,0x75da333e,0xedfc5bbb, + 0xca79bd36,0x15941f24 }, + { 0xa77dd512,0x42e8c0f8,0x1dc365f6,0xa91b59a7,0x08753862,0xe80d14cd, + 0xd272faca,0x1624230d,0x4027cb5a,0xeea3ec16,0xc1ef9f03,0xc1700b59, + 0x0da3148d,0xd411c127,0xc4181af1,0x801ee448,0x9e3a900b,0xedf28559, + 0x0d09affd,0x5d67b0bd,0x8b370024,0xd839df96,0xe6f836b8,0x3b6307e0, + 0xbd3201c9,0x5382e588,0x7a1d02bb,0x636d8a6b,0x968641e9,0x70b7db76, + 0x118fad03,0x6d17c34a } }, + /* 202 */ + { { 0xc181c99b,0xcf608841,0xc87bdcaf,0xb65dc901,0x3720dabe,0xb460b447, + 0x5377515b,0x4c79c396,0x0a96c277,0xd447f22e,0x2ac0f440,0x0d952130, + 0xc90583ad,0x8330b26b,0x928904a0,0xe25e977a,0x85c50b18,0x1deaffd9, + 0xa5ad5f6a,0xcf4dbcb7,0xc8a37ed5,0xcbcd0019,0x1e9850b6,0x7846dd90, + 0xb0b8e605,0x1ac8194a,0x34132f90,0xb9728571,0xf56ee28b,0x4ce9f149, + 0x3e9e1d4e,0x1ab9b5a4 }, + { 0x314fa7a3,0x206dab92,0x478ff963,0xcc4af0f0,0x904d9fdb,0x4cce1713, + 0x12c045fe,0xac20a2eb,0xfd8f6d7d,0x44fc5478,0xca7b6ffa,0x886e72c5, + 0x6fd6f758,0x7fa4529b,0x92a820d5,0x4df1d1b1,0x2789f149,0x3d812f9f, + 0xaabb53d2,0x9842f083,0x2a03ab32,0x2648539b,0xb1512502,0x631ce090, + 0x731f6bd5,0xe1294d15,0x9436e634,0xb229361d,0x3ca966af,0x8c4281c4, + 0xc21ab3ed,0x24b34956 } }, + /* 203 */ + { { 0x659824e2,0x49bdcb86,0x4e13e74c,0x6dc4ce48,0x6bbe1eea,0xa4c01a26, + 0x1e3ec457,0x47b2b8e7,0x2f5a8e4b,0x7e8b15e0,0xe333530d,0xe81eb6e6, + 0x17a45202,0xacba369e,0xd70e4c9f,0x81241431,0x3e12beb8,0xc190af4b, + 0x11f486fd,0x53270523,0x29fb2bce,0x9f6c41e1,0xb70f6c08,0xbe6287eb, + 0x3feb4477,0x1479850a,0x9bcf18bb,0xfcfdfb11,0xda80d040,0x925c292f, + 0x7e3c5bf9,0x212d65e5 }, + { 0xca15cf08,0x23adb386,0x81e172eb,0x4dfa4ac4,0x4d42d0c0,0x9d1dbf93, + 0x74404dc7,0xd9cf6073,0xe932bfcd,0x60508441,0x1c682a98,0x9ae910ca, + 0x41ac1cc0,0x9528fc18,0xdbbed630,0xe6a120ae,0x30ccf250,0x94e0e1ec, + 0xe58bbf2f,0xfe84ba54,0x9faa4415,0xc66d0b4f,0xecee7ce5,0x0c58f1e7, + 0x6fa6873a,0x7a1d43eb,0x399f1348,0x96c6c5a0,0xe6727ab7,0xe6ef9aaa, + 0x9a5c2447,0x66afa554 } }, + /* 204 */ + { { 0xc980e91d,0xda5aaba8,0x6ac98efa,0xa93cf509,0x8da32662,0xb0990e0a, + 0x0081453e,0x01d21530,0x3d71de84,0x2bb0d33e,0x3e19a012,0x465f6d80, + 0x78a838e7,0x5902ff4c,0x1931348c,0x74e2afb7,0x9cfb057b,0xa4932757, + 0x3ad03f8f,0x761ea642,0x58ffa40a,0xb7d4c245,0x77a87e30,0xb5e9c0d9, + 0xc9c84d26,0xd1c5edba,0x3d1963a0,0xeca8839a,0xebf6bf0d,0xbc6f2f35, + 0x0d58abdf,0x01ef0631 }, + { 0x3ecdcbb0,0x2bf90316,0x27c1c955,0x19e2d728,0x9575c930,0x9e527030, + 0x96983930,0x0dc1c5a9,0x7cd082df,0xef9f80ff,0xdf97e051,0xcd915075, + 0x9cc61b55,0xf286fffe,0x80f24cc4,0x352db38f,0x36523ae3,0xed9b99ec, + 0x10b104a9,0x109a8ca8,0x305203ad,0xc2700fe7,0x769400f5,0x2a2ee24e, + 0xee0c452c,0xd595d399,0xf7f02a41,0x0ab75d6a,0x0db730b7,0x34108099, + 0x5e8d1202,0x0e4f5ffd } }, + /* 205 */ + { { 0x0ff14c38,0xbd1c6444,0xaece11f2,0x9a5b59fa,0x22af6330,0xaa4605a7, + 0x82af24ee,0xddc9f65a,0xeb9a1159,0xf4ee4bfe,0x74e84eaf,0x2463d076, + 0x0e0baace,0x88cbe1e0,0xd5fabdcb,0x7ca568ea,0xc57eb99d,0xbd80d524, + 0xe9be9873,0x9c46572c,0x7300b85e,0x918a1dcd,0x40f54176,0x49221312, + 0xb5b14236,0xf7e324ff,0x2434f16a,0x40dda501,0xa133d97c,0x08833421, + 0x0876f020,0x33d41161 }, + { 0x9878e5ec,0x7531a36b,0x46918232,0x5de3e321,0xd0a30464,0xd15f9a33, + 0xaa173659,0x734c1b87,0xf925d4fe,0xac2094a2,0xc262b0f4,0x43c965a1, + 0x447d5cbc,0x759c903e,0x05239300,0x92af215e,0x1f593f34,0xfffb6d5f, + 0xc3cddb5f,0x65943b4b,0xbfdd5408,0x9d03a29c,0x198d76c0,0x8f7cda6b, + 0xc0f27b59,0xc0790a22,0x8cb58ccf,0xba557a84,0x76c54fdc,0x5922052d, + 0x47b6b466,0x2d3de7aa } }, + /* 206 */ + { { 0x65add3b7,0xaade7462,0xabf24c2a,0xe5888f35,0xe1a57d93,0xd41549ca, + 0x2c76f7bf,0x0e22e18e,0xbe3202b3,0x67f288ea,0x1d1d0f0a,0xb79a66ba, + 0x2881ad18,0x0e0ab749,0xc7adb0e9,0x7d424086,0x2842132f,0x870c32c5, + 0x58f9a09e,0x858477f1,0xec025589,0x422a9372,0xa5098777,0xbe428c5c, + 0x57660058,0x45b79564,0x957f37cf,0x6c7fc631,0xd6316289,0x8b7023dd, + 0x5b1c12a6,0x47003bb6 }, + { 0xc91c1c96,0xd99401c1,0x27a12970,0xaa5dcdf9,0xc3c29107,0x3ab92e17, + 0xa3fe4710,0x26fce8f7,0x4ee998ee,0xb0d09d5e,0x8e3a41f8,0xafa62204, + 0xa26ca506,0xb1c012a5,0x99b57252,0x2c6f734c,0x512f7fe1,0x1093d79f, + 0xacee19a6,0x2f30906e,0x056d1ea6,0x6bff8381,0xeff35f21,0x61c75856, + 0xc1ad2224,0x6e07e978,0x6b20fde8,0x2cca6ca1,0x633fe81b,0xab4d6d2d, + 0xb06a2ce6,0x73dff504 } }, + /* 207 */ + { { 0xd8e20fb8,0x8b615805,0x82b533f0,0x7c6873e4,0x56a854ca,0x5205f001, + 0xcb369211,0x87fec6ac,0xc7f092b7,0x1fa3c0ec,0xe845fe4c,0x5b36647e, + 0xf8b1f112,0xd4781e85,0x8b0f1a6f,0xc6526839,0xdcb8eb92,0xceeb8c6c, + 0x8e5f6d52,0x133f0ead,0xc8d934dc,0x31883e23,0x428ac45a,0x214ed5bd, + 0xdbbfca85,0xf77ca492,0x07e5ae13,0xdf4113fe,0x72ab05fb,0x63e4a0d2, + 0x7148f535,0x7544d0b7 }, + { 0x80797ace,0x4fe8d134,0xaf86d97e,0x216d6aa0,0xef5a68fc,0xdbf0a688, + 0x9f9b2684,0x18b26f45,0x8999d2fc,0x52fefcfa,0x62423955,0xd5af8d82, + 0xf63a3780,0x8f123469,0xdcd4feaf,0x2933454f,0xa73b5d09,0xba8018b7, + 0xe5552c18,0x9af1f276,0xff26bb1c,0xc5d4773d,0x06dd4f44,0x9ef49410, + 0x5f39ba49,0xad8f12f9,0xf66ca4f2,0x5767f6dc,0x7922f59a,0xba8773f1, + 0xc1e42d49,0x220081ea } }, + /* 208 */ + { { 0xba37a0ba,0x3043d573,0xdd176df6,0x05a431bc,0xc42070f7,0x03322cfc, + 0x67c2d109,0x5cabd30e,0xcbf8bcfa,0x362c95de,0x7787b10b,0xd767d277, + 0x6ec05e64,0x612c915e,0xce69c30e,0x9e669631,0x682e2635,0x27c9dd8f, + 0x95ffcc38,0x79021f12,0x8a2adca2,0x06a8ee79,0x4b5d500a,0x8e00e784, + 0x8d80d6c5,0x87746fc7,0x915f10cc,0x246053be,0x219f6fd8,0x844e328b, + 0x11bd3733,0x620541ac }, + { 0x509e5a29,0x0f7fd382,0xb432531e,0x8748d7d0,0xcd3883b9,0x8f749354, + 0x8bfbb17a,0xc6b8ac74,0x05f2d2c5,0xa4616a66,0x1bcb1b83,0xb3d96625, + 0x2fee265a,0xcf753104,0xdb225058,0xc70d73fb,0xf0c2d556,0x1211d434, + 0x54b259b3,0x862061d8,0xc42b3f7d,0xffe4606d,0xe86a4949,0x4c5c8585, + 0x160eedac,0x04ddcc8b,0x568e2420,0x1804ce67,0x42141656,0x91f3855a, + 0xf932be97,0x7f378198 } }, + /* 209 */ + { { 0xdfa6639a,0x9a374bda,0x02ab7391,0x0cbd48d4,0x47031e2d,0x5c5ef236, + 0xd0599d1f,0xb49ee2bc,0xe0d38443,0xd285eb60,0x269392e8,0xdbbea92f, + 0xb8bc538f,0x91455fbf,0xe469b768,0xae259ff1,0x41de5682,0xc1cecb1f, + 0x9952d1ae,0xc876f071,0xe7bf7446,0x1ce25181,0x282ad2f1,0xcb93ad86, + 0x6ba4ef67,0x8fa3cd31,0xe507aa3e,0xfce68a04,0xa61bb608,0xced74170, + 0xf6ac10d0,0x6de716b3 }, + { 0x172d6dc5,0xd4e58d04,0x6397c65c,0xbed2cde6,0x0c9eb4e8,0x7ae77e18, + 0x75fa2edb,0x56275468,0xa91e6738,0x4b30324e,0x235c8b2e,0x6023a856, + 0xa8f92887,0x9df6d6c2,0xf6f5e8b5,0xec2c185f,0x3ad5748a,0x7892e12b, + 0xd54aefbc,0x7aebb4f2,0xee868821,0x14915448,0xb1d9bd5b,0xa26c5f71, + 0x2ff00df7,0xe5ccd166,0xb95b1dee,0xebc99f17,0x3fe1f774,0x90983616, + 0xbb3d25b0,0x51f90830 } }, + /* 210 */ + { { 0xf2922461,0x49376fa1,0x1650d0d1,0xdbb1b1c3,0x0dd8608d,0x92b91c33, + 0x36b89906,0x3e612c4b,0xdf560052,0xe1977b0b,0x636a2545,0xf8afff70, + 0x11723d8e,0xcda7d278,0x81bde7ba,0x0b0bc4bb,0xed2a578e,0x3cb080b2, + 0x171b2e02,0x5bda0d0d,0x941bb9ae,0xf6df38cf,0xc14a65c5,0x85dd81db, + 0xc19dd98e,0x7f98c82d,0x52206f93,0xc613747f,0x5f5bbe78,0x9e13a2c2, + 0x0aa34be7,0x5eed218e }, + { 0x01d4dc0b,0xe1565754,0xf566bb07,0xa1ae5f27,0xb82225d5,0xe985ebeb, + 0x1189ec6b,0x5f3ad21c,0xecce4d9d,0x17da518c,0xd6b65b59,0xc84a2d3e, + 0x8ffa771c,0x7f988175,0x2ac69a7a,0x50d6ae12,0xc6e6846d,0xcb7f30b1, + 0x5bd0bb13,0x8c023a60,0xd73f2407,0x9a10fecd,0xe5f0a996,0x8c5158cc, + 0xbd8f5806,0xd26bf615,0x915a46e1,0xaf32ea87,0x0287d308,0xeaf74e81, + 0xa6264254,0x8c14ba06 } }, + /* 211 */ + { { 0xb17ee201,0x0c877895,0x88e57a77,0xc05aa471,0x97822456,0x19c3e763, + 0xc9c3ba1d,0x0be6f8c0,0xb4389ebe,0xfe85f4ff,0x0ce7fbb6,0x538bccce, + 0x65266c64,0x876eab2a,0xcf9a3842,0x5c9ac690,0xccc8f981,0x9f5cf3b1, + 0x9cf687de,0xfa17be6a,0x83835c15,0xfcfc10fc,0x150ef2eb,0x086b0fdb, + 0x884a52e6,0x9f97ecd9,0xb0cd1eb8,0x416e6fa2,0x3ecc03ba,0xe2bd1599, + 0xeabb165e,0x645c0a5d }, + { 0x50aa7e31,0xd94c4205,0x2f851da5,0xaec8df0c,0x3c726e6a,0x99646909, + 0x2619bf9a,0x72dbdc36,0xe253fbd5,0x1b4260e0,0x8c709e06,0x97c259fb, + 0xcddaec5b,0xfabf7cbb,0xe4b703e9,0xb4d5e8b1,0x0734efdd,0x1b06e56e, + 0x1f55f8a5,0x02d4a4f9,0x3f565c8d,0x7f8608ba,0x816d1d94,0x822f47d2, + 0x5ce7b136,0x0cc36156,0x31d04242,0xe46ee5ef,0x683567f6,0xb2a65f70, + 0xd2fa6c91,0x27e9ff40 } }, + /* 212 */ + { { 0xd7e952e7,0x75251893,0xc735bf18,0x15b30583,0x96fe0491,0x732b5992, + 0x806d2fca,0x27451858,0x1b885ed9,0x71ab76a0,0x6d9f55ec,0xbdce9d97, + 0x48f2ba9c,0x3da60b20,0x592b132b,0x6977c086,0x099051d7,0xb6dca9cb, + 0xd188ae25,0xd9c2ab23,0xe20aaf3d,0x9f469f3f,0x5aad74d0,0xdbd1f7cf, + 0x22a9eb3b,0x3d5efe5c,0x137010c4,0x8c5edfa2,0x57870260,0xada2217b, + 0x3dac9776,0x4feee567 }, + { 0xb5d3d780,0x30e18d52,0x07166744,0x4dadb5d3,0x5a742156,0x320d386e, + 0x8d6bbb86,0x5d8c290e,0x2d263dd1,0x981a4323,0x98984636,0x33d0e7ca, + 0xa519acb1,0x5138784d,0xdddc81ff,0x832e3fab,0x3199a43a,0xfc278594, + 0x32743163,0x5b4cabcf,0x74f94fa7,0x9fa010bd,0x5694a627,0xc28a743d, + 0xcb657a24,0xc1d2a888,0xe86a25ea,0x7eef2503,0x04c561ff,0xed11a5d3, + 0x9c9ede0e,0x4fe818e7 } }, + /* 213 */ + { { 0x7fc1c7ff,0x00252c9d,0x9fa89ad1,0xa9bd419d,0x4064e9cc,0xc93a124a, + 0x43942ecc,0x384cbcb8,0x8749695b,0x004c21fd,0x421165bf,0x69c81d9f, + 0xdde01102,0xe2325628,0x5a9b004d,0xec937457,0xf6dcfc21,0xfb3346bf, + 0x4d372c7d,0xac4da64b,0xf20494e2,0xcecb7ad3,0xe867c150,0x562c41b5, + 0xc2b723d8,0x299395ce,0x7ee53231,0xc91adfc5,0xf10b6597,0xe06f1161, + 0xb74d3ffc,0x81915529 }, + { 0x6ed9d4ee,0x8ec12431,0x689aff01,0x3dffa154,0x2a89a3f4,0x4aba349f, + 0xd467efb2,0x2db1e8e2,0x039102e2,0x18dea354,0xe52f082b,0x422ab853, + 0xed36dd47,0x7130a2c1,0x0295d1ee,0xca60e86d,0x7c7f5ad3,0xe6ac6808, + 0xde864658,0x0f83cecf,0x461d1265,0x72e66c21,0xbd385099,0xfeef4150, + 0xa6632289,0x0f183f3a,0x792dc795,0x275454be,0x11367702,0x2744c11b, + 0xe8ea6ef3,0x7d06bcc7 } }, + /* 214 */ + { { 0x7090212f,0x89285942,0x5521e844,0x691b7d4c,0xbe2dbb92,0x4c038422, + 0xbd81f880,0x317721ed,0xac89bc36,0xc136cbee,0x7b8f004d,0x4f71b60b, + 0x4e218ab8,0x269132d0,0xe6cc814d,0xb0e2496e,0x75fadc15,0x0b2ce317, + 0x66d223c5,0x82e3c084,0x4c612f8b,0x9721caa6,0xa4b65355,0x59a751eb, + 0xc7d3d9d1,0x3433aad5,0xe80d4246,0x1e61b9d2,0xfc673caa,0x149f655f, + 0xd0f9cb92,0x48b52b99 }, + { 0xefdc05be,0xa3915399,0x13e095e9,0xde70db18,0xcddb3fda,0x447862e9, + 0x1a009451,0xa2b03162,0x23920ea3,0x4b27980c,0xa23b8feb,0xac5394f1, + 0x3e5616d4,0x163f7256,0xb714219a,0xaa0ff93f,0x93d62474,0xd26f96d2, + 0x7dcfe276,0xdd212ea8,0x47038d15,0xab27bf2f,0xf418168e,0xe58c8325, + 0xb32a989a,0xe3704222,0xbfc9f13b,0xa3694390,0x0d0684ad,0xf16e2606, + 0x9d8c76ec,0x17c0de87 } }, + /* 215 */ + { { 0xdcc01958,0xbca5f453,0x1ce88393,0x7d945954,0x561f5b6d,0x5e6350a1, + 0x7e2d36bc,0x291c3c86,0xa5ac3a6c,0xf6c7ed84,0xd98006cd,0x7913c40b, + 0x5671ec3b,0xf78bb087,0xb43e89a9,0x1c928f6e,0xae1ea1ed,0xfdf28df3, + 0xb924b2b5,0x62bba5b1,0x1a116e05,0x491d2705,0x167ed3e3,0x08ec02b7, + 0x5bc0b046,0xe291cf7b,0x8c5d7f59,0x30e50169,0xf5c799b7,0x0c7c350d, + 0x0ac6e1d7,0x6862b9e2 }, + { 0x9ffa1f64,0x56c6f4e7,0xa1e24349,0xfed6a91a,0xcdb75232,0xe9a0ee0c, + 0x0322d607,0xbfc90b37,0x462fef87,0x29480ad2,0xc2bfcf34,0xfc214969, + 0xa539e38f,0x6e5211e0,0x12a5149c,0x2a59ec26,0xd706b532,0x195fe212, + 0xe99c8429,0xf77fb108,0x5dc80482,0x74ceaea3,0xbd92d298,0xa5a6030b, + 0xaaea15ee,0xad42dca5,0x4987109c,0xd6ac3bc7,0x290af649,0xc64e1c40, + 0x51f8de6c,0x5093fa2d } }, + /* 216 */ + { { 0x4c2d553b,0xc4cf3280,0x3b966c29,0xdc1abe22,0x2296914a,0x556a549c, + 0x999976c9,0xd8c9f8b5,0x776e83f3,0xc22c57bd,0x7c85ec57,0x4f2942ab, + 0x6e2c61f5,0xef3407e5,0xf213db48,0xf005e8ca,0xf32698c7,0x470c853d, + 0xcac0a54b,0xe6f488d7,0x60b7501e,0xb6bd6bed,0x714a4bd9,0xf0103106, + 0x6e098894,0x5285bc3b,0xf5f92a00,0xec06741a,0xef7ef24a,0x32f16426, + 0x6c77a438,0x12f9c44d }, + { 0x83313a1c,0x1951e964,0x33c58b37,0x98edd3da,0xc7ac4044,0x4edbbf52, + 0x0dcb5ee8,0x866ca6f7,0x6dd422f8,0xec0ae8f5,0x0661ec2e,0x1077bc54, + 0xd422523c,0x6d39913a,0x58e7cb3e,0xd105e1e8,0xc979bb45,0x47c9397f, + 0x0997b592,0x3221d4a9,0xe8952fe7,0x0ef628a3,0x4e946241,0xd08d5827, + 0x59780f40,0x64cbed0f,0x08e110ec,0x13d7c227,0x7679b1a3,0xd186d866, + 0x26ae1d18,0x02f75e4e } }, + /* 217 */ + { { 0x47f307d7,0x1b637ebf,0xd0141477,0x6b644a6a,0x2e05a80c,0x82a33d65, + 0xfed07b31,0xc8f1a0f3,0x3696e597,0xc09ee7f9,0xc7ffc01e,0xcdaa7ec3, + 0xf8f373b9,0x549f88fe,0xc3bb8989,0xc88d1961,0xdfcaa7b7,0xd92a4fe9, + 0x3ae4ab20,0x12ff9ee2,0xf5ecb1a5,0xf5aea641,0xe32fb47d,0xe769237f, + 0x25d085c0,0x96a5c420,0x26c755a2,0xdc912558,0x9bce9723,0x580b985f, + 0x63961941,0x72b1b566 }, + { 0x790e5558,0x9d708a08,0x0689af80,0x98536041,0x42313b5f,0xe85e7b8a, + 0x55a49d1a,0xe6ba1292,0xac371b0b,0x5e76c4b0,0x938e6e19,0x58504f39, + 0x60ae9a21,0x8dd41422,0x968485ce,0xd8b04e9b,0x887efe43,0xf94c4ba5, + 0xf11c5e73,0x11268e67,0xcf6b99c4,0x92623e28,0x7a0a9662,0xf2d0aaa8, + 0x4ca02ed3,0xb266772a,0x2d63b551,0x68ee8e4e,0x2e78b5b5,0xcdebb299, + 0xe17225ad,0x5df19216 } }, + /* 218 */ + { { 0x8df2e7e3,0x20027e1e,0xd8da07de,0xb183cc68,0x4b4ae694,0xce35ba69, + 0x3ca62e88,0x896d97df,0x52efed2c,0x3de4713b,0x26bd084f,0xd006c40e, + 0xfc81923b,0x1e9b71bb,0x1aacc6b0,0x9991c7b6,0x8f656840,0x650c9364, + 0x87f47524,0x138561d1,0xbffd3ca2,0x610f2b11,0xfa191418,0x96915faf, + 0x955e5309,0x8f1236de,0xa1872d79,0x613cbeea,0x66a2a48b,0x7f7b44ea, + 0xe0a89c32,0x452265c2 }, + { 0x25430010,0x4ad5ec79,0xebd090c0,0xcac786ff,0x20a9d3f5,0xa5f9f4ff, + 0xa3edc65f,0xfcbf4112,0x0cf3eb11,0x8824839c,0x8aa5b700,0xb8dd6d4e, + 0xb7568ab8,0xe2271dfd,0xb744560e,0xe43ec373,0x1cf75296,0x78eaf926, + 0x3fa96d9b,0x1809ae0e,0xdc25dfd5,0x0b312d2d,0x6bab7711,0x6b8f78b4, + 0xb5ecf1e4,0x069efc8d,0x609fecaa,0xc1952bae,0x5f4dbde1,0x43e302ed, + 0x1e078555,0x14b02bf9 } }, + /* 219 */ + { { 0xb87e5b57,0x2c71c768,0xf531a557,0x0bcc78f7,0xf7597dc8,0x4ff93f8b, + 0x139e175f,0xb28e026d,0xcb94ca6c,0x6b83b727,0x0079f7fc,0x2eafe3b2, + 0xcf3bd170,0x2aca54de,0x6af0dc6c,0x17c4133c,0xccf5e35e,0xbea1e665, + 0x345505c6,0xa6691a48,0xe6100b89,0x2633abd0,0xc17d0388,0x966c6706, + 0x1a0cf90c,0x7aefffbe,0xd0add64c,0x4d847be7,0xaea2aa46,0xd49bcdfb, + 0x2cc7d0a5,0x85e07e74 }, + { 0x0bc25bca,0x23aae0a6,0xe44f64ec,0x6e8e55f1,0xb607b773,0xe1e696d8, + 0xd3005909,0xaa90a746,0x2cbc4990,0x072b1ccd,0xc68e2f5d,0x0d0fe6c6, + 0x53e28ec9,0x920ec5f0,0xf0040cc1,0x79b21fb4,0xfcc4a2c7,0xa7375bd3, + 0xe1bac7dd,0xf5f5def9,0x35c0f8d3,0xdc315d79,0x2cacd318,0x7117c170, + 0xe926f71c,0x6f2823c4,0xed02f39a,0x38db58bb,0x7db69323,0xe5b49231, + 0x8d49f430,0x0964039f } }, + /* 220 */ + { { 0x56999eba,0x21774f16,0xb1de6305,0x3d8ee287,0xde0b2669,0xd81af726, + 0x3f8942a1,0x37446939,0xea03e13c,0xbcf6b615,0x94e273cf,0xd30c0c35, + 0xc6725c56,0x4fd33a56,0xa8be97a2,0xa57534ad,0x7c22a251,0x799242a6, + 0x9d0c5c49,0x4e51bdb5,0xc6a42768,0xd7cd76cc,0xd426bf59,0x914097ac, + 0x66e9beb2,0x59404a2c,0x5c96e3e9,0x4738fe98,0xaad666d0,0xbcbb3e0e, + 0x63bc5e56,0x626b0fd2 }, + { 0xe1a1ec42,0x47217dba,0xab5acc50,0xaa6ae7db,0x865331d1,0xb7e1ab1e, + 0x3d30126f,0xb8453070,0xdee61851,0x280649e0,0xea689544,0x8806f4a3, + 0xcb56f632,0x4bbe43ad,0xbcaff94f,0x036b9bda,0xbd0637be,0x0d941e65, + 0x686f3abb,0x82179d44,0xaad6afd6,0x1486912c,0xff7e1534,0x9a3b891e, + 0xeb86fd96,0x88c426ce,0x117928c3,0xb56e6a81,0x96399e00,0x933e7135, + 0xa17b6ac1,0x09bbddd9 } }, + /* 221 */ + { { 0xe4fd3673,0x75e39c1d,0xa65c8e07,0xf880d9d1,0x7289c7fe,0x4725c1dc, + 0x3529d200,0x5b6735ee,0x3c747af3,0xc1f8f2ed,0x912efdf5,0x5cf3998f, + 0x49859c39,0xed722618,0x0e69795d,0x23793a2f,0x86b1d2a7,0x8a6ab8d6, + 0x22a882e4,0x00c815de,0xf9db8d7e,0xbe77d6fc,0x02267547,0x0886fb32, + 0x49c10edc,0xb62687d4,0x7c83ed4c,0x9f1c3e17,0x5af366ea,0xe6d5d7f0, + 0xd1efad24,0x2eaa01b8 }, + { 0x1f357c74,0x5e47fb70,0xa9e3b794,0x93085c4a,0x6e85a905,0x4f098733, + 0xbe0244c9,0xf53808ff,0xa3b5660d,0x91dddf93,0xf3b95ed6,0x8b76377b, + 0xbb3920d4,0x91b911b7,0x86a13cf3,0x7ccf08bf,0xea018e58,0x53ed8f97, + 0x78c55194,0xb1ea4343,0xe0d2d5a6,0x8e6adde9,0x9b96259a,0xfc2b248f, + 0xeef17ddd,0x96ebceae,0x557f9c85,0xf694b443,0x07d5bba8,0x48cd150f, + 0xb4c1986b,0x02d31de9 } }, + /* 222 */ + { { 0xde79499d,0xa6bb9e1e,0xfd0fc2ad,0xf6ca8ff8,0x1a7d9356,0xbec0f8e8, + 0xe8f06327,0xbc3d1c9f,0x3b300beb,0x805c7217,0x413c181b,0x00420a08, + 0xf0ca9d01,0x9e9a167e,0x1aeeddd6,0x076c909d,0x8e3a8a72,0x64a1997f, + 0xa77b429e,0x3ce7f7a7,0x5c94d3e9,0xaac0fbf4,0xe6d48407,0xf37694a7, + 0xa91921e7,0xf56679e2,0xee1dbbd6,0xf23fe0f3,0xcbf9fa99,0xc7917566, + 0xe0f4d765,0x965860f2 }, + { 0x7fa5f79c,0xe734702b,0x5af2d26d,0x930bd426,0x6c73e0ce,0x45bd8b98, + 0x4ee44a2d,0x7dbe7bed,0x956c8a1a,0xc129e024,0x77cdf80e,0x6fdc05ac, + 0x589ca59b,0x70a6ba2b,0x999825af,0xfc484021,0x7a23f0b6,0x1d284b54, + 0x28a0a8af,0xb1da10a4,0x2b2af6d8,0xb1eb1b31,0x33935ee3,0xf051443a, + 0x8effa6ec,0x7a07eb26,0xd662654c,0x16ee4086,0x4549ee4c,0x7a7bc501, + 0x1fa98a52,0x65081032 } }, + /* 223 */ + { { 0xb67ed9b2,0x49f0e460,0xc36d93d2,0x0cda0fd0,0x88c75e1c,0xbb5963e9, + 0x614bc0c9,0x757bbe93,0x9a768605,0x9a9b8801,0x48edc544,0xa8b7e2af, + 0xb51a5985,0x9e77ed9e,0xebbf024c,0xdd025274,0x1545c636,0x598b6288, + 0x4800dba0,0x39bdaed0,0x81e2a23a,0x7fc20139,0x550cb4f2,0xdc66fd5c, + 0xb52068c7,0xad27032f,0x8169fa15,0xc9a0bcae,0x3a7ca8a2,0x60606f21, + 0x9862652f,0x98295046 }, + { 0x2e11c128,0x3e374600,0x0e6dca7e,0x80dfae5d,0xd9552264,0xe44016e2, + 0x880b7143,0xf65f88f2,0x526b881c,0xca3d28d4,0xdfb86afe,0xf9c59dd1, + 0x4c74f958,0x548860c2,0x9cb69f4f,0xd06ea43c,0x7334ecec,0x5343c9ae, + 0x35329713,0x5cc2ccd6,0x5f3a6c0c,0xa95ff403,0xb372653b,0x2e01a1cc, + 0xa250523d,0x31510fdf,0xa6227eb2,0xeee538e2,0xca23cd10,0xeadfc8a0, + 0x3e78f54b,0x4b7e6e1b } }, + /* 224 */ + { { 0xdb5f928b,0x79c9076f,0xb7347cec,0xe6250bb6,0xac00ec41,0x54b67798, + 0x9d9619c7,0x900d20ba,0x59e4343f,0xed42c0d0,0x451935d7,0x3df39e85, + 0x64f701ce,0x26391182,0xe1f87aac,0xce8f2554,0x65f91aaa,0xfddd6789, + 0xa324539f,0x96cd163f,0x4bace995,0x5c815f2c,0xa94f9ea5,0xd78c8c2a, + 0xef24e455,0x7ab2aff4,0x1cddc26a,0xf0ed6409,0x00ca2822,0x954a420b, + 0xd3297658,0x0611c4c5 }, + { 0xa9e81829,0xf192001c,0x08a282cc,0xded33320,0x8f9ded9b,0x0bfd7de1, + 0xb7889003,0x6793ac0d,0x3577a5dd,0xbb00d91d,0x802d3c2b,0xe17a23a7, + 0xfb549014,0xff95f88c,0xc71b6e07,0x7cd1bf4b,0x23588c8b,0x2e3b24a0, + 0xa4112076,0x9b5335b8,0xc4056d30,0x2481c05e,0xe916a1b5,0x55c7410c, + 0x850179f4,0xbbe03271,0xb3cd1208,0x15e6c177,0x90cbfe50,0x509a24c0, + 0x1c108566,0x82079529 } }, + /* 225 */ + { { 0x1c7d353e,0x5d2d3cff,0x7de0ce3b,0xd5e7eccd,0x6ca87635,0xb4b1075f, + 0x25f9ad3e,0xda8404e0,0x205cb5ae,0x6b963e89,0x09f221a1,0x9e5ee0d8, + 0xea41aca4,0xd64c85d9,0x34442a34,0x6a46c4e9,0x3cf655a4,0xac6ff97e, + 0xe5417d7c,0x76565c1e,0xeebf9c4c,0x681009a9,0x88da6388,0x95b61d39, + 0xf6b472c6,0x6402b46a,0x0b7f1171,0x1fde5165,0xbe0c05e3,0x94f8f273, + 0xa88344a7,0x7487b036 }, + { 0x9c3e2370,0xa860e575,0xf8048719,0x19d58193,0xa6e2f9aa,0x3a0dbf3c, + 0x6144719b,0xb6c7e959,0xdeffec21,0xa9049c74,0x3f50cebf,0x8ba064b2, + 0x49a1de15,0xb12822c0,0xb1d527f2,0xb654b7d9,0x0ffd0430,0xc470859d, + 0x4f05446b,0x37c74a67,0xa3add995,0xe553251b,0xe33533b5,0x4a3ed6cb, + 0x27e419ce,0x2f2f44d0,0xa5d1b979,0x2d84ee82,0xdb6fa69f,0xcc76b123, + 0x21fa3bdd,0x834f85c5 } }, + /* 226 */ + { { 0x2ce9b31a,0x329347c1,0xfe3fb3b7,0x1d88522a,0x52ff90fd,0x4bcefb4d, + 0x2b1a081d,0x53b17386,0x2a411f08,0x538c11ba,0x141b603a,0x7895b93c, + 0xb10bd741,0x2993b9aa,0x09912986,0xccbbd046,0xeea0aba5,0x669fafb0, + 0x35661897,0xd4844622,0x367ffa54,0x4a63b89c,0x1c3478da,0xcbad5d1d, + 0xaa6034f7,0xc5339227,0xe61b1391,0x0e6d705f,0xf74ff515,0xdd14b660, + 0x5332b54c,0x639d8b0a }, + { 0x162217cd,0xfa423162,0x811c28e6,0x2e0e4a2a,0x21766dc0,0x68d9ce18, + 0x046a06ef,0x51263739,0xdde92101,0x44eea231,0x114298d3,0x0607c8f2, + 0x63d957e9,0x27f272ba,0xa5e8cae1,0xe7ce80cc,0x24f7a63f,0x5816ebe2, + 0x89673e34,0x4dece5a7,0x536babd4,0x13756a22,0xe3bf77af,0x644d61ae, + 0x2bcf98bc,0x60b2bf6e,0x29fa962c,0x3b0b59f3,0xabb50023,0xb0769a1a, + 0x0c75402c,0x40903136 } }, + /* 227 */ + { { 0x1670433f,0x84d2873a,0x25493dfc,0xc9394df6,0x80fcf89e,0xeb05a19a, + 0xdb297616,0xe39e4310,0xd9e63046,0x50742dc9,0x1de9ca9e,0xf31ad8c8, + 0xfb7b1d0d,0x86aabf94,0x1b3c82d1,0x36cda27a,0x39702d84,0xfb1a2ef4, + 0x46081299,0x280bfddc,0xd2396238,0xe4b2b48d,0x7b3c9353,0x2db2c2f3, + 0x12fb8a69,0xd5b5b317,0x08180474,0xf9b87a3b,0x1e952578,0xd8590986, + 0xf37a2bc8,0x80668eed }, + { 0xb39a0249,0xe2edcd35,0xb2f8aeae,0xaf230cd4,0x7223df05,0x295b15e4, + 0xe0e937f4,0xbb66982a,0x8cbc9162,0x019d2b72,0xcf49dca1,0x5c512ae9, + 0x630f07b4,0x11b491a7,0xa03874e9,0x48d4f34c,0x44cb7433,0xc1fd0ea6, + 0xf95b30c3,0x13f79ae1,0xed8b60ac,0x40362d4d,0x61ead81c,0x9e8314ff, + 0x498c3d28,0xed600dd4,0xc2521702,0x5fcb1c19,0x3a9c1f33,0x592329fc, + 0x1bde6ce9,0x04677548 } }, + /* 228 */ + { { 0x39233c96,0xee3de56e,0x80737eaf,0x868c409c,0x201abc68,0xacae11bd, + 0x2b486205,0x0f2cea9b,0x6f19056c,0xe32387e1,0xa5dc2a41,0xea75365a, + 0x12b4be86,0x76c29acc,0x8d63294d,0xa01fcab7,0x0cab9f24,0x81dbe88b, + 0xf414c054,0x76646e5b,0xcb96b7aa,0xfe111893,0x7664e097,0xb649f5b1, + 0x53fcf5a9,0xa196422e,0x0b7ff634,0x5978c9bd,0x3c229895,0xb5feb38e, + 0x0833c456,0x038a49fb }, + { 0x13e93257,0x35e3818c,0xa612741b,0x14cebc9d,0x7caac06b,0x4f6e9249, + 0x3daa1116,0x82278e33,0x4de2034a,0xe7cc565e,0x0a1ba630,0xbb7dc95f, + 0x66956fbd,0x81dd9f23,0xbb132dd6,0xc63e6319,0xfc241337,0x6e22b022, + 0x7e8beb1c,0x23848193,0xd8c938ac,0x83b1994d,0xa6bb5644,0xb54cfaca, + 0x06f91807,0x1a7cd44e,0xa8f8d9f3,0x1dd439bb,0x7f74a8e6,0x660c2a78, + 0x121b5660,0x4bb76e22 } }, + /* 229 */ + { { 0xe6354817,0x7a151e8a,0xf038b438,0x33d494ea,0x85958986,0x4c86c688, + 0x1dcbac12,0x72153827,0xc0edad06,0xf487af8c,0xe500e5d6,0xad33051f, + 0xd6e47f55,0x0a711b1b,0x8c746ad5,0xa68709a7,0x6402f35e,0x27f17262, + 0xfb30c130,0xc6d08efa,0xc06c7497,0x9ef1c041,0xdcc3e2da,0xd0c74ece, + 0x092e1073,0x30c5f96e,0x2aa12b74,0x0f1393cf,0x2107eb02,0x24584016, + 0x7b76f98b,0x8843d25f }, + { 0xedb2a83e,0x4e1501dc,0x2bb8d724,0xbcfe8fb0,0xd925df62,0x09020659, + 0x42ab6fc3,0x3c715dcf,0xa0f09dfd,0x73c05055,0xe3590aea,0x126745d8, + 0x76ff749e,0x5382f4d8,0xa920c663,0xfc69feef,0x9fd711ca,0xde160211, + 0x9075c4d5,0x4219c3bd,0x3ded6bf2,0x3800cbd1,0x6263a116,0x8c7ea0eb, + 0x7d264c37,0x35bd7958,0x7159c98c,0x56e22e45,0xfa7373b5,0x71bf2a2d, + 0x8935c949,0x0503f939 } }, + /* 230 */ + { { 0x71dad4f6,0x65addc66,0x024bea1b,0x238e4889,0xf605d3dd,0xfb76c8e2, + 0xb0d96b89,0x13d5f5de,0x6601b2cb,0xe0b5ba35,0x83e3d254,0xe37d491d, + 0x240c8ea7,0xe8860423,0xe91c99ba,0x374182f3,0xa87ad919,0x26c2caf9, + 0xf574f295,0x4b13040a,0x944000a3,0x5b9bced1,0x06df42e7,0x4ccc57be, + 0x4bd1089d,0x22e8ec50,0xdddbb500,0x0c53177a,0x9ecfeadb,0x690d31d2, + 0x176668f9,0x735778fe }, + { 0x843c1137,0x0f86ee3e,0x3f0b73cd,0x3c1c42fa,0x8ab20e3a,0x0e75679d, + 0x16242fae,0x6f95f1f4,0x39b092e4,0x7b88e11c,0x4c236ac0,0x1629403e, + 0x2dac02e6,0x66105f41,0x862e0632,0x74dc28a7,0xf3b23c8d,0x2118ffb2, + 0x0745ffbf,0x1182417c,0x4c05711e,0x49b55a04,0xcefbe4de,0x2c665b74, + 0x97bf7107,0x1cc4c01d,0xc54f0676,0xb2ca06da,0x7450d0f8,0xfc599daa, + 0x1a3182a1,0x52e637a6 } }, + /* 231 */ + { { 0x6bebc6db,0x481700f1,0xf9503d92,0x4a6b45db,0x5d153919,0xc715cd3c, + 0xe5ad2abc,0x942a1c05,0xab7b466f,0x36a82433,0xba13918b,0xba413bed, + 0x90f4e6ce,0x698a5624,0xf3f1f3ca,0xbb720da6,0x63471ab3,0x2116d41d, + 0x303d3609,0xe00d2227,0x463ba69e,0x7fd4cc00,0x62845fd1,0xac609e4d, + 0x80adc9c7,0x63603b2c,0x45fafbca,0xbf16fc9a,0xc4bc94ab,0x41007f7f, + 0xa74b1698,0x7c916b4f }, + { 0x78bac2d4,0xc1026f91,0x2601a875,0x8a2e8098,0x0073d640,0xad2f276e, + 0xfcc1fb88,0x443610c4,0xca6b291f,0x5727b822,0x88ec60fc,0x0645532c, + 0xed9ad48b,0x51e48899,0xf543f103,0x841b48b5,0xd591ceeb,0xa6ccb1be, + 0x9dcf5a8b,0xfc4adf0f,0xb347ddb4,0x3a7ca020,0xcb44c521,0xaa1accc2, + 0x0527c0c4,0x773b6828,0x7023cf50,0xaa374c10,0x6b74c926,0x733d1000, + 0x77a8d07c,0x1ff3916f } }, + /* 232 */ + { { 0xf997939d,0xaa218fe4,0x791583b3,0x3d4dfbbb,0x87f7560b,0xb3a7b5da, + 0x5da92c98,0xa9c02801,0x46666f4a,0xe1eb4aad,0x14ce9dd7,0x2eb17a51, + 0xef8f3076,0xf46a66a4,0x810e546e,0x900b45c6,0x4baf04dd,0xf7af2258, + 0x5c84d42f,0x3cc1c872,0x8e4c83de,0x3093f225,0x170d88b2,0x62fade41, + 0xac076e44,0xe19612e4,0x32dd141b,0xf48d7346,0x925e34da,0xc1b1f759, + 0x072b90c9,0x19ed1a56 }, + { 0x6c735473,0x9cf7fcde,0x6003bc3e,0xaab88e67,0xfb199bb8,0x12187cbc, + 0x9accccbd,0xbb730441,0xb0f65459,0x214aff3c,0x6f926282,0x6aec81a3, + 0x9f9d20b8,0xaa82cb32,0x5773cc90,0x82f3f90f,0xf62257e1,0x4af60e6b, + 0xbd4762df,0xf18b44bf,0xdb970753,0x3948b129,0x7c22c18e,0xc6e920e9, + 0x57be97ad,0x393d6208,0x46b637f9,0xe8d7382c,0xf1fed1d5,0xf6625ccb, + 0x68681599,0x6f31e0f9 } }, + /* 233 */ + { { 0x82b8f204,0xc45afe55,0xd358b54a,0xac0441b6,0xacd5f5ed,0x7213e7bf, + 0x139bcd93,0x1914c70b,0x96dbcbb0,0x714b4581,0x1ed35d21,0xe9297d35, + 0x6a3e1f20,0x8f640837,0x2f3cd705,0x150a8a9d,0xdcdd9f6d,0xfb36e801, + 0x5cf56d82,0x5a54eb65,0x92aa5a21,0x7610500c,0x3b089f03,0xd10d0ae2, + 0xc42b66e8,0x491b2079,0x0eee8d48,0x4af1ae3d,0x41556f45,0x137e4c28, + 0x63d8a7e6,0x875e3308 }, + { 0xaf6c0acc,0xdc80fddc,0xbb1e7c08,0xd5ad1e66,0x828585ad,0xdc717ae1, + 0x275c7da6,0xbdc54340,0xd26b9e15,0xf4b4c852,0x6a05fa50,0x5f0a1fbf, + 0x817bcb32,0xc6f81e47,0x70ff2e1d,0x2cbd4328,0x67c7f7fc,0x8a249016, + 0xb585a6c4,0xd045acb7,0x4666c057,0x2e972ad4,0xe6d7d63d,0xc74d87cf, + 0x0e274144,0xf7067d87,0x8b2584ae,0xb2ca157a,0x75f0fdeb,0x495c5bfb, + 0xf386e009,0x5abb0581 } }, + /* 234 */ + { { 0xf0c97f57,0x8be62d2b,0x962f28c7,0x0fe04871,0x47b50abb,0xc548a467, + 0x44fa09ed,0xf6b26e03,0xab05a96e,0xfd44c6e3,0x70e6ae82,0xedb0032c, + 0xd7e4899d,0x28bd402b,0x9b7c11c2,0x43f2e963,0xce913716,0x0ec3fc0e, + 0x02fd0f8c,0x769b8bc9,0x7cabc3ac,0x9d9cb3aa,0x06924cc9,0xe88a8892, + 0x42609014,0xa51461aa,0x962e79e0,0xc7f4aa8b,0x8b1b3e80,0x4ef0210a, + 0x1bfee4bc,0x70544680 }, + { 0x121901c1,0xfab3d713,0xfead54aa,0xe90a2627,0xbc08ba23,0x64f6d285, + 0x36ec227e,0x8d993015,0x06c191ab,0x99a16ab9,0xf649ce2c,0x86b1cf5b, + 0x66be3a80,0x59206759,0xccba2cf0,0x18836279,0xeff53486,0x2c157b87, + 0x4b223af2,0xbfac9896,0x0aae7a57,0xcd0fd4f0,0x63218a80,0xdaddb940, + 0xdf88f14e,0x3844bb79,0xb71ed9fd,0xc1b3e3d4,0xd6205036,0x6c634a13, + 0xb8680a6b,0x6f56aecf } }, + /* 235 */ + { { 0xd9205c5d,0xb01dc803,0x67123929,0x68955f7d,0x9d9b6565,0x3debbffd, + 0xd3b1acfe,0xb844395e,0x6094eeff,0x04328b21,0x22991feb,0x6631ffa8, + 0x190dd075,0x0dde66e6,0xe8577c05,0x75b03c55,0x91722407,0x6c91ce5f, + 0x8ebb3a3f,0x9a288a40,0x058a1396,0x1d376f8a,0x9a6e0676,0xf3a59457, + 0x7b71d288,0x103029c5,0xb44c30c0,0x0843f428,0x730e0b9c,0xd8e6aff8, + 0x4ed644ad,0x7b6be811 }, + { 0x3d3aa54e,0x3ec38e4a,0xd83d509a,0x10233943,0x243955e2,0xf84aa621, + 0xf51d3d44,0x29104717,0x7eca4e37,0x62d2442c,0x85fa55de,0x8c5a523d, + 0x851da1b5,0xc6f5ccda,0x20001468,0x044bcaa8,0xe01702e0,0xf7501e68, + 0xe6a0acec,0xf0819359,0xac0ef0b2,0x33dda6ad,0xfd964f01,0x97aeedc8, + 0x530b90d8,0x48dacd0e,0xb84122eb,0x4c5fad6f,0xd700a1de,0x2284ec1e, + 0xdbca5474,0x86f9a835 } }, + /* 236 */ + { { 0x450cc69f,0x0e1d9055,0xc9edf98f,0x50eb14bc,0xee7eba01,0x1bb94e77, + 0x998f8e53,0x5f7a6737,0x1b16eef0,0x588384e3,0xd85c5e15,0xbb928723, + 0xcbd952aa,0xfe51e345,0x7e241674,0xc5d0ee28,0x100182f0,0xfdc146ef, + 0xe7f5be2c,0x0f739e92,0xb656bd3e,0x501ab3af,0x5168e289,0xb1552dde, + 0xb8ee104a,0x940dfe31,0xc4304475,0x42923603,0xc460a913,0x9306f114, + 0x03b51f86,0x5bfa9faf }, + { 0x107b258e,0x2a23f52c,0xd66341dc,0x989e82bb,0x823cff1a,0x54a3ced8, + 0x719b491f,0xf45b7794,0x2433dfb8,0x898c2218,0xc49250ee,0x0f9dd91c, + 0x4fa17655,0x50c2a2ae,0x2c327f45,0xf7aa1ce4,0x583b1e41,0x13a15ad6, + 0xa1bfad9e,0x9aa0d5a5,0x8e1fbdcd,0x9b1caa28,0x915f7f87,0xaf9283b6, + 0x87e81a1e,0xc10e4e0c,0x1080d296,0x04fdca56,0x12755bd8,0x6acc9616, + 0x828feeda,0x1b1266aa } }, + /* 237 */ + { { 0x774ee49c,0x4ebc0a00,0xcb6237d7,0x776f6852,0x5df938a3,0xfc0544ac, + 0xb6fbfbbd,0xc3388ec8,0x745f2eae,0x84ac8bcd,0xb1ece937,0xa9c56609, + 0x7de8fa13,0x656fb6ac,0xa532b871,0x5f8ded74,0xaa889f09,0xab0d428b, + 0x10b7aec2,0x43b27f28,0xfeecb34c,0x26426e1e,0x9e89c2db,0x44431b6b, + 0x39211090,0xaac4bc5d,0x4fd81058,0x926f7368,0x471ef60e,0x452fa691, + 0x218d7a23,0x33517fdb }, + { 0x593c4a36,0xa9c33f46,0x36b1a9ee,0xac69d718,0x4277beec,0x55a20c1d, + 0x7e4f179c,0x3e8ca24e,0xd46d88a2,0x57373369,0x730702f8,0x71ceb1cc, + 0x35eed574,0x8b184d97,0x0704cec2,0x7f4517a2,0xd7062a53,0x7f129d18, + 0xb1d77e1c,0x07a4571b,0x8350d8b2,0x774ac309,0x61fab8ef,0x27b2919f, + 0xb5dd801b,0xa7c4cc13,0x1434591f,0xe7e6255b,0x5a3592b3,0x349937b8, + 0x30c77549,0x31fac63d } }, + /* 238 */ + { { 0x04913fb6,0x2ee8cf1b,0x1769a6b3,0x7e401350,0x783e61f0,0x790ebb71, + 0xe27f2ffe,0x1e5107f9,0xedaf89bf,0x124ba67f,0xe58de68d,0x189200e1, + 0x6df5abee,0x962732a3,0xacbeb4aa,0x72cc37cf,0xe93c5a76,0xb0c5fa96, + 0xde63393b,0x4c2a317c,0x830b2d6c,0x97f65e67,0x1be5b96a,0x4afc3504, + 0x730ce66d,0x0bf40a60,0x9340d84f,0x96a1ba79,0x07626b08,0x3ee18254, + 0x7ab0cbf5,0x01db35db }, + { 0xac0efee2,0x6e0fbc2d,0xd71dbb45,0x8406ebcd,0x19b69abe,0xe72bde3e, + 0x37e01822,0x49cb7e61,0x11458b4c,0xcbb8c01c,0x687c5d63,0x420b4847, + 0x454c6776,0x1847dfa1,0xd1839d18,0xbede911d,0x278df046,0x1b9dc9c9, + 0x881a336c,0x294bd62b,0x93e77adc,0x7f096879,0x43ce3ba7,0x7ac90665, + 0x7764eefc,0x148695fd,0x9ac465cf,0xe0c20f0b,0xa6e2cdb1,0x636e8d28, + 0xd755341d,0x7b6ba98c } }, + /* 239 */ + { { 0xc1881ab4,0xcb1d9e03,0xb3168c88,0x19c25d55,0x282364ce,0xa82d3d47, + 0xf161aa24,0x95994390,0xe1ebb2c9,0x7838bc00,0xbdec7a75,0x8fd5dfcc, + 0x4ff7220a,0x4dd203c2,0x0efeff48,0x5ec173b3,0x16428b35,0x99f1d2b3, + 0x056e813f,0xc06bd9e5,0xc0b319f1,0x929172ba,0xfd223b15,0x6ae0e384, + 0x98d091ed,0xbd01059e,0xa654648e,0x6b3168e4,0x3375e798,0x2211447f, + 0x71eb4508,0x47e81019 }, + { 0xbc8c290d,0x7045d45a,0x810fb33a,0xa33d1355,0x46fbbf2f,0x2baf0092, + 0x385c7cd9,0xacff3f1b,0xe161985c,0xc5b150ec,0x2a888748,0xc6ee0a7f, + 0x5e88dcc8,0x9d888c8e,0xccb86443,0x4dd735f2,0x3c40f6f2,0xcc1e13b7, + 0xf3fed691,0xfc3a25ff,0x257ee5c7,0x4cb43b17,0xf32db135,0xaa654f93, + 0x02dff2d3,0x44f58d0a,0xa8ca6394,0x78e3f188,0xf3e86697,0x39646cce, + 0xe0dce87b,0x785b1902 } }, + /* 240 */ + { { 0xa92f9a20,0xfcce2361,0x9d64540e,0xb7bdca87,0x1d00d7c5,0xd4739a85, + 0x2e97c926,0x067ac8dc,0x78da6a8b,0x2aea3ffe,0x63c51b69,0x6828bf54, + 0x7155141a,0x76f1c479,0x3977d810,0xf4bcbef6,0x541bce7a,0x75bc4949, + 0xd17041a5,0xe01f4066,0x87755eaf,0xd282d5bd,0x59e7ae80,0x6e2107dd, + 0x382ab36f,0xaa56e166,0xb9d1d634,0x65ee8ef6,0xce4ed844,0x99a2160a, + 0xb7712c27,0x6557c367 }, + { 0xd75b6e52,0x561b0268,0x118d0e89,0xb0813640,0x6a2eb1ae,0xcff53330, + 0x6d090894,0x4e462226,0xb5fc1d48,0xbb351227,0x57a3062d,0x9365ea07, + 0xd66e2dc5,0x4caca37b,0xb9095887,0x220d7d23,0x8c4473bf,0x9c0fd393, + 0x6787da4f,0xadff370a,0xd057f4b8,0xef0aebcc,0x1173f33a,0x205e744c, + 0x925a26b4,0xb8d1f0a5,0x722fbbfd,0xa9364f49,0x8227d284,0xc891ae77, + 0xa0e08ab4,0x15c40d04 } }, + /* 241 */ + { { 0x2a0e18d1,0x9baf169a,0x4c0327c2,0x9971c017,0x7bc262ce,0xd81a323f, + 0x818ff379,0x2099db8d,0x4cd3c330,0x663f663d,0x011a0553,0xef5325c3, + 0xf980a470,0x9cd70bdc,0x1c9ed070,0xe64452d1,0xac676e13,0xafbf43f4, + 0xae85c2a5,0x97bec0a6,0x470490c4,0x2faae550,0x491e6ba9,0x0ab97a87, + 0xaafa9914,0x4055f537,0x36726557,0xfc95adbb,0xd119d6bf,0x646343b9, + 0x9d341e37,0x788e94a0 }, + { 0x9c53461a,0x053a6fe5,0x08e3b6ed,0x75ec897e,0x0768d939,0xa8f5d2f3, + 0xcc213d4f,0x9bd6bff6,0x05b0147c,0x590c7b41,0x7c7b8169,0x20a3628b, + 0x5bce78e9,0xc66a086e,0x4dec1d8f,0x3dd4d282,0xc19dcce9,0x890acf44, + 0xd8435a7e,0x6632d875,0xea6381b2,0x590167c1,0xf0dcc128,0xb2259797, + 0x46f8d463,0x91a612b4,0xc15efa39,0x42185d78,0x119f6788,0xdf55ec37, + 0x780dea93,0x91b19cc6 } }, + /* 242 */ + { { 0xcb5d8b80,0xebf2709d,0xfc35660e,0x03b96182,0x055ef969,0xb873d991, + 0xe47c4342,0xd1ea4b4d,0xd54f8867,0xcc4b9244,0xfd8d77ef,0x93b1a2ca, + 0xe8c1f563,0x068d24e7,0x49973056,0x5f5fabb6,0x0542374f,0x83248c50, + 0x3f38e913,0xc36de2b5,0x7bb680be,0xed07e8eb,0xd8f313b5,0x964813d7, + 0xafd2d392,0x7bb6a069,0x0848a31a,0xc06d848e,0xe4f0c325,0x6867fb2f, + 0x067343af,0x3c2ba834 }, + { 0x9d3ad63b,0xab62d775,0x59e0eb1f,0x3f9cab97,0x3885e117,0x70332a63, + 0xe20b2f9e,0xf22cafce,0x49eca947,0xb529ba7e,0x6228d88d,0x24954216, + 0x39239561,0x80ea23ec,0xd4370644,0x1b8907e7,0x563e4e44,0x4b7fa455, + 0xb2a4b0fa,0xcca9829e,0x48060792,0xd0a720a4,0x246991ce,0x8ccdda0c, + 0x348d086b,0x37a2325b,0xf60aee13,0x566ed509,0x147f253f,0x3d30e091, + 0xc1073bd8,0x1fa627a5 } }, + /* 243 */ + { { 0x42478fd4,0xa11222a2,0x670b2000,0xacf4c6f1,0x8359c6de,0xf71bb04f, + 0x7b93cdbc,0x618e2829,0x230db60b,0x96e1bae3,0x965b3b29,0xf17fd3b4, + 0xbc7055dd,0xa58639c6,0x4b817d7f,0xc3ea92ed,0xd23b08a4,0x9082b2a6, + 0xdc17010e,0x8471228a,0x20e89d97,0x753b9e46,0x03ff77c9,0xcf7e4f97, + 0x2bbe60e5,0x6c3f8245,0xb80e017d,0x9e432cbc,0xc0a45edb,0x150a5acd, + 0x4798743e,0x67b8bd05 }, + { 0xf4797cf7,0xe66079b4,0xd03fde02,0xe31c998a,0x54caaef1,0x5aa3763a, + 0xf7649711,0x64d9a1fe,0xaf29b1a7,0x7ce0dc73,0xfb66ca93,0x6661b083, + 0x32fb6a78,0xbf4d74fe,0xdf00a561,0x25f6ef09,0x831d1159,0x2bc4383f, + 0x536bde37,0x6d5cc10c,0x882cc65b,0xd4945f9f,0x451a99b8,0x81f48f13, + 0x6bac11a4,0x140161cd,0xf18a4a0a,0x9d94d4ed,0xa467a824,0x65363165, + 0xa4c9aedf,0x74297aa9 } }, + /* 244 */ + { { 0xe21124ba,0xc49758a4,0xa87ffbd2,0x99bd8198,0x3d6638a8,0x45fbcdd1, + 0x15f7bf76,0x94645ff8,0xc4e6d57e,0x5fa6736f,0x92e61db9,0x1eae6475, + 0xcbdf944a,0x79575c0c,0x25b31d74,0xa3d13047,0x4cab5ae6,0x7881df22, + 0x1a2887f2,0x8dbfd299,0xa26ac459,0x23d07590,0xd8661d4a,0x2e589852, + 0x8a0140f7,0x37b5c13b,0x3fb3782a,0x0f94199e,0x1bc14e90,0x722aa059, + 0xd55bbb12,0x89aab7ba }, + { 0xd656bdc7,0x8b345a96,0xe176cd3b,0x43bdc8af,0x32d64c43,0xd69518b6, + 0x79b82b41,0xfcf364a7,0xffb0cf82,0x907b344e,0x5101287b,0xf3d0c83c, + 0x34cd90ef,0xe9f26a59,0x07082b5c,0xe5f5aaf2,0xece7c165,0x4eb72c75, + 0xbe986cd6,0xe9590a81,0xff1536aa,0xfeef498f,0xa8263d5e,0x04560243, + 0x54ae872b,0x940be14f,0xe3207686,0xbee7bcc9,0xc1bc4d7a,0xd496a27d, + 0x5940ab46,0x002dc297 } }, + /* 245 */ + { { 0xb69d60c3,0xee533937,0xfe972755,0x260be552,0xc0c725a6,0xb11fb78d, + 0xcab2e7c2,0x6982c27e,0xee2322cb,0x4bceedd9,0x122704f7,0x952b19ed, + 0x854a6165,0x2df4c285,0x7b192485,0xba40b5bf,0x0119f52a,0xfcbca950, + 0xe5add86f,0x7467d1cb,0xd9d0f2c1,0x9bf536fb,0xb8d4ebc9,0x3c296e34, + 0x05a81317,0x0495f8f4,0x73335f76,0x8c59e8d6,0xe0542122,0x0b53d324, + 0x3c3bda73,0x4d564535 }, + { 0x7e5c0877,0x7322f800,0x0ca9a764,0x481b43e6,0xa2c12716,0x231f4f4b, + 0xed3136c2,0x09596857,0x38db30de,0xae826322,0x99908ebc,0x652fad40, + 0xaf0d231e,0x0b8d1814,0x09cbc349,0x2680c54b,0x4bf3bf8e,0xfd4562f3, + 0x092b595f,0x2985090b,0x5e15fc34,0xe6f39ca4,0xbc378168,0x70175191, + 0x845a4a87,0x906944b3,0x82a1541a,0xacc6d74a,0xb155c8b4,0xadc9bab3, + 0x77306c62,0x1f2f89ce } }, + /* 246 */ + { { 0x9affefdf,0x8253ef41,0x4cf9256b,0x05d7ece5,0xb444e483,0x377002f2, + 0xcba5471f,0xb189755f,0xd5cbe015,0xc88483cb,0x6a0b8429,0x254f7c69, + 0x61f3f61d,0x18850bd4,0x0a247157,0x7ba21089,0xd92eeb0d,0x35abbc2e, + 0x965dec89,0xfb56cabe,0xbc55684a,0x9da23724,0x6a7a7492,0xd8ba396f, + 0x2ef4ba46,0xfcb90db7,0x9909b27a,0xdd234fe0,0x76f4366e,0xbdf3c164, + 0x17e50d47,0x09c8097f }, + { 0x60050c07,0x6a04b140,0x43a8e37e,0xc29e8318,0xbb55e41f,0xcb9429b2, + 0x2ce60e3a,0xed2fea5a,0xdb9d82f4,0xdc7b1ff3,0x687d37fa,0x48ebecc3, + 0xecb07539,0x79153e32,0x57075692,0x6a60054f,0x800759ba,0x3871cd0c, + 0x30922df1,0x17a7386f,0x83357b7c,0x4e9fc59e,0x39415186,0x1d26b3a9, + 0xd34db889,0x912a0222,0x59fcdb71,0x6672fcf4,0x44ff3036,0x5a3f268d, + 0x6911e16c,0x6f113ed3 } }, + /* 247 */ + { { 0x1836f1c9,0x52a9df59,0x4232307d,0xfa6519f5,0x5ded285a,0x8406c701, + 0xaf627f75,0x0a1545ca,0xace0417d,0xae1111ee,0xa6113443,0xfb28bdf6, + 0x52dbcbcb,0xde9ef0ab,0x7813e658,0xe9dc181b,0x99127225,0x0b1dabdb, + 0x22814c59,0x5f0598e3,0xd934ee7e,0x5c3b966e,0xb99ba4bf,0x4eb84eda, + 0x3c1b55e7,0xb2919a34,0x94aa860f,0xa9addb49,0xf6811ff6,0x1b7220df, + 0xd1a183e2,0x6636a23b }, + { 0x20587283,0xdf5d5a2d,0xef07fc5d,0x0b3822c9,0x0ef6de38,0x1786bd55, + 0x25d1671d,0x163cf907,0x1cdb1def,0x74bf971f,0x0842fc4a,0x5749e830, + 0x27f854f7,0x0e2edbc7,0xbce24acb,0xbb27bbda,0x05bed08d,0xc1b19cec, + 0xf7c904bc,0xaada123e,0xd89982db,0x02429f1b,0x65f6e632,0x49d3616e, + 0xee59fd32,0xa3789fa8,0xfe9f29f5,0x160ba3ba,0xaf5378a0,0x0f2d3b61, + 0x73c2a6f8,0x7aeecc76 } }, + /* 248 */ + { { 0xdc43b0db,0xf3a4757c,0x98119cad,0x3d8a4e85,0x4616c156,0xf8095bf6, + 0x4f533e97,0x3e2a07bc,0x39cfc5ad,0xa9824367,0xcd68052c,0x18a6ba3a, + 0x8a1cec66,0xbd60e590,0x02b1b695,0xae3841a5,0x190a195b,0x986dff12, + 0xad31fd9b,0x2df2beac,0xcc728f7b,0x7d893224,0x0cf0a992,0xc38ea738, + 0x586a44ea,0xa8439a80,0x1615f03c,0xede7f7f0,0x27a1f885,0x48249908, + 0xb78a7645,0x28ec4006 }, + { 0xa2fe0009,0xe1820c2e,0xf13874e9,0xe11ba5d2,0xc524db52,0x97522454, + 0x7fede529,0x4d477426,0x9b2500d4,0x01d3419a,0x1869244b,0xce08a492, + 0xdd1be1b9,0xba169023,0x32a301e0,0x242c3e54,0x70906788,0x9b56f7ba, + 0xc74a8cc4,0xf0ad2a09,0xd76f9439,0x99cd1841,0x621fb60e,0xeddafe0b, + 0xbc397634,0x056bee54,0xff7f0a84,0x4653f860,0x2011c0af,0x6bd4876f, + 0x0c9525c3,0x134f4cc7 } }, + /* 249 */ + { { 0xe938dff4,0x9621a3ec,0x486a79a3,0x7d101a7b,0xde950537,0xf2c4ef97, + 0xe65d87db,0xf3184099,0x373b8cfa,0xb89c7ffb,0xe842916e,0x68baa505, + 0x4ebea764,0xa790fd09,0xe592892b,0x679df6d4,0xfcfed741,0x2023331c, + 0x9880ff21,0x0bf4efd2,0xd0344501,0x7ca78ddd,0x342858c8,0x2cb09ecb, + 0x2575487a,0x9e5eb6dc,0xebcb0491,0x50675a15,0x7381d471,0x09d2e74f, + 0x83d3d6f4,0x6ea37829 }, + { 0x4e5cc40a,0xc65c094b,0x1af37dfb,0x7a2e3f6a,0xf9026e44,0xef677e9d, + 0x93880f53,0xb7878c95,0x7f644aa9,0x4aa30b07,0x2f208c3c,0xa0c51683, + 0x658d663b,0x7c0277ae,0xae1d9130,0xef0b3c38,0x695c3ea4,0x302f37a7, + 0x6a0c5e0d,0xe004c1c5,0x20cbcf9f,0x9fd495c4,0x568a0e7c,0x706d5b9d, + 0x59286454,0x8b225dff,0x8d9a709c,0x527d4465,0x87c08d68,0x47c558da, + 0xbb4ef07d,0x606ee6e6 } }, + /* 250 */ + { { 0x57c621f6,0x02d99fc7,0x7fe83d48,0x292e40c1,0x9ef199b0,0x1bdfc7a1, + 0xe62c7666,0x78a04102,0xe6738753,0x16cda370,0x1e3a65af,0xbc81974d, + 0xf78fe209,0x19742048,0xbf5981c6,0xc83a058a,0x9c89702d,0xf26b2434, + 0x9d1a678a,0x988b2f1e,0xff29ae29,0x472bf9b0,0x1d7cf5ec,0xa143e398, + 0xb268ddd8,0x9c9d7e45,0x5fc4ff76,0x166cda55,0xa4aa7673,0x6044cdf0, + 0xe9148707,0x49dba6f7 }, + { 0xa758e37a,0x20e47fb2,0x2d8eaf66,0xaf6b31d7,0x6f9c2210,0x352ad5f9, + 0x90efc32b,0x0093f727,0x41e4b264,0x435c99dc,0x05b15795,0xbfa878e0, + 0x0e673575,0x99c520a4,0x87eea759,0xca682594,0xf12a348b,0x029f7b81, + 0x2aa2ce35,0xa547cc18,0xead5e2c5,0xa11d874b,0x55682cdf,0x9af0349b, + 0x8bbe8e66,0xf86ebfea,0xf55394ab,0x3dab8782,0xebc8eb8f,0x458bf797, + 0x9b7de78c,0x4890a7a4 } }, + /* 251 */ + { { 0x8da995f6,0xd7299689,0xec6156ef,0xd39eaae7,0x356a82d5,0x6959040c, + 0xc135bcfe,0xb2046b21,0x0f595c78,0xea720b64,0xe7c5fb40,0x02824efa, + 0x0edb3bfc,0x97d8fd4c,0x79f24ebe,0x12f02905,0x187ea6b9,0x16fc47cf, + 0x789d5c23,0xc219fd27,0x89263ecc,0x233a6b6c,0x8b6d30a6,0x823634b2, + 0xc9b33680,0xca352e25,0x40c77456,0x9388d6ca,0x3c92065b,0xf8e55b0b, + 0x02439a76,0x5c17474b }, + { 0x8aaccab5,0xd888e7c2,0xaaced05b,0x18027836,0xccec0f65,0x185b877d, + 0x125c2882,0x93cadc1c,0x67fdc54c,0x45df540a,0xc2788a33,0x4f3c86e2, + 0xe3a0fa2c,0x3e874469,0x273983cf,0xc59daa47,0x4a96d8a5,0x3063c48b, + 0xc2e58915,0xc38d2bcf,0x84e428c3,0x90e78b87,0xf0c4fd53,0x900a292c, + 0x941e6005,0xb7f92db7,0x6ca53a1c,0x95679241,0xb1ab0fa7,0x35f6f31d, + 0x7b58408c,0x5d675eb4 } }, + /* 252 */ + { { 0x870c6025,0xaeee1a77,0x91a2dfca,0xfc4a23b7,0x386b64c4,0x7b0e60c4, + 0xe5ae72b1,0xd5d5b17d,0x9eefa212,0x6dfc88ac,0xd4038b96,0x4feaefbe, + 0x8e2d2ecc,0x099ac356,0x012af207,0x548ea612,0x89c31218,0x4ffed9db, + 0xe0e67331,0x1c1e91c4,0xaf8300e0,0x009bb64f,0x6773c3be,0x8780501c, + 0xc08219fa,0xe0cd6ede,0xf81b06ff,0x7c055e07,0xe080b36f,0x82b63f9c, + 0x0a9feca3,0x02fccbaf }, + { 0xb47cac61,0x9991d4d1,0xab86e12c,0x2e9d1687,0x2b94f042,0x8c6855ec, + 0x48e648e5,0xca400519,0xef89ac57,0x9ba91fb2,0x1be792cd,0x4f419206, + 0xbd0f1e15,0x82d221cb,0xfc444019,0x062eb13b,0x99790fdc,0xf3a97c32, + 0x6067a64b,0x4e796d94,0x6d23775a,0xc46dd300,0xed7f0f23,0x8672c4d5, + 0x3b4f63d7,0x821851dc,0xd26273f2,0x50a3ae0c,0xeac60f6f,0x800e58fc, + 0x13845545,0x56f1e456 } }, + /* 253 */ + { { 0x32c24f3b,0x01ccb3f6,0x06d817e6,0x99eb1c7f,0x6aa26776,0x8dc640bb, + 0x0845d5e0,0x7838affe,0xf81a79a8,0xf34fecb1,0x3e6819b0,0x6a2e282d, + 0x8237a4b8,0xc4b977ce,0x87636439,0x0f46b3db,0x97970497,0xa465f540, + 0x8791be43,0xd7e08762,0x34198ec6,0x00220b6c,0x093d94bb,0x57b38637, + 0x29d690b2,0x84012e16,0x20aad1a4,0x02ec9db5,0x85dc34e3,0xafee2fc6, + 0x25500cf8,0x911d1936 }, + { 0xf5e5af5b,0x13b1bd58,0x7b6a22a7,0xa7ca263b,0xf3af2adc,0xab6bec4d, + 0xa04420bd,0x16651e59,0x4ba36c11,0x3b448b3b,0xff424310,0x3c62bfcd, + 0xf1a96cbb,0xde15c4a5,0xe4d1f980,0xbe0ad8a1,0x36673a3a,0x812bd14e, + 0x9212acdd,0x40303af6,0x576095ce,0x8f6dab9c,0x107f5ca5,0x7df1882a, + 0x8896a3b0,0xb903e63c,0xd863b3f0,0xf5048544,0xc09887de,0x5e5019b9, + 0xa0f53865,0x2be744fe } }, + /* 254 */ + { { 0x5b50f324,0x054cd05f,0x1ea3c7a2,0xb9b1eb24,0x7ff8e6b7,0x4a858a5c, + 0xec040882,0xd83902fe,0xd0cba9bd,0x72b26494,0xb29c9e1e,0xd0176f90, + 0xcebadb81,0x05d4eb02,0x372b8bfc,0x874405b1,0x79ead190,0x5c412881, + 0xec2b48cd,0xd44a3dd3,0x3f4d5033,0x84499a77,0x564c3a09,0xb37b38cd, + 0xf42e803b,0x80e99497,0xb8f518b2,0xc07b47a0,0x3568fde4,0xc710e3c5, + 0xcead0e7a,0x735f542f }, + { 0x38380039,0xcaa9a171,0xf74d19c8,0xadfafe17,0xccbc1a8b,0x92d4393e, + 0xfe029705,0x3c5dbf39,0x930e9b36,0x4552b5ab,0x2afd494a,0x7ee63032, + 0x3f02ac43,0x826a9ad7,0x99356298,0x98c53562,0x7342bb39,0x0c869f87, + 0xe4f9b79a,0xd7510020,0xd34789a9,0x6361d1a4,0xcfa85637,0xf0ded5ba, + 0x88ac07e4,0x407ee73f,0x09ef1cbd,0xfac7d03f,0x4d475bad,0x25d697cb, + 0x14bd399e,0x1e984c9d } }, + /* 255 */ + { { 0x4850c817,0xc76d0561,0x3489812d,0xb08a5b19,0x5e58cbbe,0x7273d154, + 0x4be61e5a,0x8900b5fa,0xd7aeb8e1,0xaa088691,0xd35a3d4b,0xe66666af, + 0x57ec7d3d,0x38a2c199,0x668d6f5c,0xa0648e8f,0x7adc1746,0x1f9fc92c, + 0x843065c3,0x23a116c0,0x61e6ae69,0x36370a20,0x2aa47e73,0x626c3736, + 0xdeff6d84,0x540c25f2,0xcdbed2d4,0x9804824c,0x039a9492,0x4b5bfce0, + 0x76942e01,0x6c474a56 }, + { 0x7d88e3a1,0x3aeb9a41,0xc484742a,0x105d3c88,0x3fe61131,0xe59de8d1, + 0x1a869e8b,0x148f5b6b,0xaa75d90a,0x7a8abc59,0x62146013,0x2f0c9bc7, + 0xc3824cd9,0x43faa747,0x6a5d0b92,0x81763a18,0x9bcbaebc,0xbbc341bc, + 0xf745d1dd,0xe1813160,0xb75ce5f4,0xa53ce52d,0xd50de4c2,0x15eae66c, + 0x75d7656d,0x5ed8996c,0xc4ca552a,0xe4ff5711,0x3c5305b4,0x215e985a, + 0xfa1ba2ce,0x6b258954 } }, +}; + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^128, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_base_32(sp_point_1024* r, const sp_digit* k, + int map, int ct, void* heap) +{ + return sp_1024_ecc_mulmod_stripe_32(r, &p1024_base, p1024_table, + k, map, ct, heap); +} + +#endif + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_1024(const mp_int* km, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_digit kd[32]; +#endif + sp_point_1024* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_32(heap, p, point); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 32, km); + + err = sp_1024_ecc_mulmod_base_32(point, k, map, 1, heap); + } + if (err == MP_OKAY) { + err = sp_1024_point_to_ecc_point_32(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_32(point, 0, heap); + + return err; +} + +/* Multiply the base point of P1024 by the scalar, add point a and return + * the result. If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_add_1024(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_point_1024 a; + sp_digit kd[32]; + sp_digit t[32 * 2 * 5]; +#endif + sp_point_1024* point; + sp_point_1024* addP = NULL; + sp_digit* tmp = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_32(heap, p, point); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (32 + 32 * 2 * 5), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 32; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 32, km); + sp_1024_point_from_ecc_point_32(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_1024_mod_mul_norm_32(addP->x, addP->x, p1024_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_1024_mod_mul_norm_32(addP->y, addP->y, p1024_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_1024_mod_mul_norm_32(addP->z, addP->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_ecc_mulmod_base_32(point, k, 0, 0, heap); + } + if (err == MP_OKAY) { + sp_1024_proj_point_add_32(point, point, addP, tmp); + + if (map) { + sp_1024_map_32(point, point, tmp); + } + + err = sp_1024_point_to_ecc_point_32(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_32(addP, 0, heap); + sp_1024_point_free_32(point, 0, heap); + + return err; +} + +#ifndef WOLFSSL_SP_SMALL +/* Generate a pre-computation table for the point. + * + * gm Point to generate table for. + * table Buffer to hold pre-computed points table. + * len Length of table. + * heap Heap to use for allocation. + * returns BAD_FUNC_ARG when gm or len is NULL, LENGTH_ONLY_E when table is + * NULL and length is returned, BUFFER_E if length is too small and 0 otherwise. + */ +int sp_ecc_gen_table_1024(const ecc_point* gm, byte* table, word32* len, + void* heap) +{ + int err = 0; +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; +#endif + sp_point_1024* point = NULL; + sp_digit t[5 * 2 * 32]; + + if ((gm == NULL) || (len == NULL)) { + err = BAD_FUNC_ARG; + } + + if ((err == 0) && (table == NULL)) { + *len = sizeof(sp_table_entry_1024) * 256; + err = LENGTH_ONLY_E; + } + if ((err == 0) && (*len < (int)(sizeof(sp_table_entry_1024) * 256))) { + err = BUFFER_E; + } + + if (err == 0) { + err = sp_1024_point_new_32(heap, p, point); + } + if (err == 0) { + sp_1024_point_from_ecc_point_32(point, gm); + err = sp_1024_gen_stripe_table_32(point, + (sp_table_entry_1024*)table, t, heap); + } + if (err == 0) { + *len = sizeof(sp_table_entry_1024) * 256; + } + + sp_1024_point_free_32(point, 0, heap); + + return err; +} +#else +/* Generate a pre-computation table for the point. + * + * gm Point to generate table for. + * table Buffer to hold pre-computed points table. + * len Length of table. + * heap Heap to use for allocation. + * returns BAD_FUNC_ARG when gm or len is NULL, LENGTH_ONLY_E when table is + * NULL and length is returned, BUFFER_E if length is too small and 0 otherwise. + */ +int sp_ecc_gen_table_1024(const ecc_point* gm, byte* table, word32* len, + void* heap) +{ + int err = 0; + + if ((gm == NULL) || (len == NULL)) { + err = BAD_FUNC_ARG; + } + + if ((err == 0) && (table == NULL)) { + *len = 0; + err = LENGTH_ONLY_E; + } + if ((err == 0) && (*len != 0)) { + err = BUFFER_E; + } + if (err == 0) { + *len = 0; + } + + (void)heap; + + return err; +} +#endif +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * gm Point to multiply. + * table Pre-computed points. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_table_1024(const mp_int* km, const ecc_point* gm, byte* table, + ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_digit kd[32]; +#endif + sp_point_1024* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_1024_point_new_32(heap, p, point); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32, heap, DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 32, km); + sp_1024_point_from_ecc_point_32(point, gm); + +#ifndef WOLFSSL_SP_SMALL + err = sp_1024_ecc_mulmod_stripe_32(point, point, + (const sp_table_entry_1024*)table, k, map, 0, heap); +#else + (void)table; + err = sp_1024_ecc_mulmod_32(point, point, k, map, 0, heap); +#endif + } + if (err == MP_OKAY) { + err = sp_1024_point_to_ecc_point_32(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_32(point, 0, heap); + + return err; +} + +/* Multiply p* in projective co-ordinates by q*. + * + * r.x = p.x - (p.y * q.y) + * r.y = (p.x * q.y) + p.y + * + * px [in,out] A single precision integer - X ordinate of number to multiply. + * py [in,out] A single precision integer - Y ordinate of number to multiply. + * q [in] A single precision integer - multiplier. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_mul_qx1_32(sp_digit* px, sp_digit* py, + const sp_digit* q, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 32; + + /* t1 = p.x * q.y */ + sp_1024_mont_mul_32(t1, px, q, p1024_mod, p1024_mp_mod); + /* t2 = p.y * q.y */ + sp_1024_mont_mul_32(t2, py, q, p1024_mod, p1024_mp_mod); + /* r.x = p.x - (p.y * q.y) */ + sp_1024_mont_sub_32(px, px, t2, p1024_mod); + /* r.y = (p.x * q.y) + p.y */ + sp_1024_mont_add_32(py, t1, py, p1024_mod); +} + +/* Square p* in projective co-ordinates. + * + * px' = (p.x + p.y) * (p.x - p.y) = p.x^2 - p.y^2 + * py' = 2 * p.x * p.y + * + * px [in,out] A single precision integer - X ordinate of number to square. + * py [in,out] A single precision integer - Y ordinate of number to square. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_sqr_32(sp_digit* px, sp_digit* py, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 32; + + /* t1 = p.x + p.y */ + sp_1024_mont_add_32(t1, px, py, p1024_mod); + /* t2 = p.x - p.y */ + sp_1024_mont_sub_32(t2, px, py, p1024_mod); + /* r.y = p.x * p.y */ + sp_1024_mont_mul_32(py, px, py, p1024_mod, p1024_mp_mod); + /* r.x = (p.x + p.y) * (p.x - p.y) */ + sp_1024_mont_mul_32(px, t1, t2, p1024_mod, p1024_mp_mod); + /* r.y = (p.x * p.y) * 2 */ + sp_1024_mont_dbl_32(py, py, p1024_mod); +} + +#ifdef WOLFSSL_SP_SMALL +/* Perform the modular exponentiation in Fp* for SAKKE. + * + * Simple square and multiply when expontent bit is one algorithm. + * Square and multiply performed in Fp*. + * + * base [in] Base. MP integer. + * exp [in] Exponent. MP integer. + * res [out] Result. MP integer. + * returns 0 on success and MEMORY_E if memory allocation fails. + */ +int sp_ModExp_Fp_star_1024(const mp_int* base, mp_int* exp, mp_int* res) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td; + sp_digit* t; + sp_digit* tx; + sp_digit* ty; + sp_digit* b; + sp_digit* e; +#else + sp_digit t[4 * 2 * 32]; + sp_digit tx[2 * 32]; + sp_digit ty[2 * 32]; + sp_digit b[2 * 32]; + sp_digit e[2 * 32]; +#endif + sp_digit* r; + int err = MP_OKAY; + int bits; + int i; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8 * 32 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + tx = td + 4 * 32 * 2; + ty = td + 5 * 32 * 2; + b = td + 6 * 32 * 2; + e = td + 7 * 32 * 2; +#endif + r = ty; + + bits = mp_count_bits(exp); + sp_1024_from_mp(b, 32, base); + sp_1024_from_mp(e, 32, exp); + + XMEMCPY(tx, p1024_norm_mod, sizeof(sp_digit) * 32); + sp_1024_mul_32(b, b, p1024_norm_mod); + err = sp_1024_mod_32(b, b, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(ty, b, sizeof(sp_digit) * 32); + + for (i = bits - 2; i >= 0; i--) { + sp_1024_proj_sqr_32(tx, ty, t); + if ((e[i / 32] >> (i % 32)) & 1) { + sp_1024_proj_mul_qx1_32(tx, ty, b, t); + } + } + } + + if (err == MP_OKAY) { + sp_1024_mont_inv_32(tx, tx, t); + + XMEMSET(tx + 32, 0, sizeof(sp_digit) * 32); + sp_1024_mont_reduce_32(tx, p1024_mod, p1024_mp_mod); + XMEMSET(ty + 32, 0, sizeof(sp_digit) * 32); + sp_1024_mont_reduce_32(ty, p1024_mod, p1024_mp_mod); + + sp_1024_mul_32(r, tx, ty); + err = sp_1024_mod_32(r, r, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + return err; +} + +#else +/* Pre-computed table for exponentiating g. + * Striping: 8 points at a distance of (128 combined for + * a total of 256 points. + */ +static const sp_digit sp_1024_g_table[256][32] = { + { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000 }, + { 0x335c1685, 0x170a46d2, 0xe1007a58, 0xeac9e971, 0x43ca4a73, + 0x40e8f3df, 0x82642475, 0x2646f815, 0xb36576d1, 0x3af49bb4, + 0x72bf1afb, 0xd89e2d14, 0x2fd151e6, 0x27be882c, 0x8f88717c, + 0xaddedc85, 0x16ac6c6f, 0xd6d859bf, 0x2d8eae58, 0x0e741a1b, + 0x61c1f30d, 0x6faf7a00, 0x9b67e096, 0x66dbd09a, 0x7d3b4f7d, + 0x21f11c06, 0xc727c98e, 0x6152ba02, 0xe86cb221, 0xafd58891, + 0x6bd3baf4, 0x59e93c6a }, + { 0x71dd4594, 0xe54dd36f, 0x00aef1e6, 0xbbc9cc9f, 0xa19f6530, + 0x9ea5a44e, 0x3f520928, 0x8588aa99, 0x8f5c1418, 0x9753794c, + 0xc11399fa, 0x118bd792, 0xf5cb6ab5, 0xb9bd3afd, 0x2ecb9652, + 0x813d1cb2, 0x40389813, 0xfd456267, 0x4ac8431c, 0x51f7119b, + 0x0a180eb6, 0xdd9f6a91, 0x9f7bfa2e, 0x13946d17, 0x50a9d0d9, + 0x16f18631, 0x6f8373d3, 0x5f19c20d, 0x9b6a52b9, 0xbe85ac6a, + 0x74f62e03, 0x63ef187b }, + { 0x016f45e7, 0x7c376b7f, 0x2bec82f8, 0x1c1bdb57, 0xce429b60, + 0x7392f741, 0xc7afd81d, 0x6fdbf0a2, 0x7241098b, 0xbda41b1f, + 0xbb60f8cf, 0x5b407474, 0xb330bc4d, 0x933e0d41, 0x733fa3be, + 0xae182830, 0x0f5c6cd1, 0xa0ed299b, 0x3f9860c8, 0x7ff3354e, + 0x15559c41, 0xb1360986, 0x129f85cb, 0xab0cb63c, 0x47685fbe, + 0x682ecc49, 0xeb199633, 0x505e8ec2, 0xddac2cda, 0x90dcc794, + 0xf192da23, 0x4fe6791c }, + { 0x05e8733c, 0x94a423d5, 0x1d5717c1, 0xcc845e65, 0xe961b322, + 0x237c7e88, 0xdb4181cc, 0x0c4471c6, 0x713bd721, 0x00c875e2, + 0xb2c17b09, 0x9dfde9ed, 0xe88ceaf6, 0x430a6de5, 0x7b81cea6, + 0xaaa7a61a, 0x233f98d5, 0xea52d026, 0x60689a9a, 0xb55efdd0, + 0x5cac4aab, 0x30cfa7ce, 0x8e950761, 0xfa4db114, 0x4e9a1e52, + 0x309570c4, 0x1a040170, 0x18c21f61, 0xbe78d9d2, 0x555d1ffe, + 0x561db297, 0x04482a18 }, + { 0x73d486d8, 0xe7758ac2, 0x61cdc1e7, 0x8169f946, 0x2188ab4f, + 0x723c99fc, 0xf3373630, 0xa0e54f02, 0xbd8c2260, 0x560bee25, + 0x4531bc60, 0x28fc307c, 0x7e44feb5, 0xd6f21f1a, 0x57128d37, + 0xc8e4499c, 0xd7b2ea45, 0x963b053e, 0x32a3d222, 0x40c27a04, + 0x35459668, 0x5b51854d, 0xd73557e9, 0x66e1a49f, 0x8692077a, + 0x0d267fd9, 0xe7342702, 0xfa1350d3, 0x68ccdb44, 0x1a9c3f25, + 0xdedbf89f, 0x833a0ff8 }, + { 0xab376b76, 0xa8c419c7, 0x27d0f0cc, 0x3b7294f3, 0xa90c514d, + 0xe56bb9e2, 0xa62575a6, 0x931ba51e, 0x098c0a88, 0x56fee07b, + 0xb4c16a2a, 0x04be5aee, 0xe6eb260b, 0xe513350b, 0xa1d5c270, + 0x339edad6, 0xe9dbadd1, 0xf366ed59, 0x2dd06ec0, 0x4213be88, + 0xcb1187db, 0x22d639c8, 0xd8a1058a, 0x1fec95e1, 0xa2b744f1, + 0x03f73ea6, 0xf4f05c0c, 0x741fd51a, 0x85f811a0, 0x2e2df95a, + 0xeb24965f, 0x692b3ce3 }, + { 0xd2a127b4, 0x0ce6cb72, 0x8f92816f, 0x66a46ea5, 0x47a37616, + 0x43ecf463, 0xe0ab96ee, 0x163d9a01, 0xb2edbe8c, 0xc8145c6d, + 0x4de4e665, 0x2f426cae, 0x74e252f9, 0x174d0b40, 0x7d2af831, + 0x54c240d7, 0x3d652936, 0x581fa397, 0xa09d4695, 0x05b9491c, + 0x5452643c, 0x8c4e8533, 0xd4128327, 0x32d64331, 0x70361f25, + 0x64479038, 0x89ef09f2, 0x774191b1, 0x81de5fe0, 0xc0cf0aaf, + 0xf40042d6, 0x333e430a }, + { 0xcf26d3b7, 0x5df04de4, 0xb53f79be, 0x57a77306, 0x1808b664, + 0xa4013c5f, 0x85037360, 0xef291ea4, 0x0b061037, 0x1ffc9d7d, + 0x65c913bb, 0xd9d04dd9, 0xf13b8587, 0x948a37af, 0xfe3ee755, + 0xb5443483, 0x04631386, 0x3fc21e74, 0xcddeb58c, 0xb3a104e5, + 0x6572cd52, 0x94fe1862, 0x15aaa408, 0xeb9a71a1, 0x459ea462, + 0x8adc6fe5, 0x4aeb02a3, 0xbb18d175, 0x2f7791d1, 0xae127636, + 0xd6bbd708, 0x10e8b31d }, + { 0x3ed9f1af, 0xb87f03e5, 0x56676166, 0x03ad2477, 0x74ce15b8, + 0x38dcd630, 0x26b1e85b, 0x1877e2b0, 0x1af99c15, 0xb1654d17, + 0x9382547a, 0x9782e9e4, 0x26d55ef5, 0x6dc7fc7c, 0x2fbeb54c, + 0x9038f95d, 0x036c0357, 0xfe590dfe, 0x4fdc3f7f, 0xcfcb6eae, + 0xf35e1a88, 0xcb1fbc54, 0xda0a5568, 0x3c8e1db2, 0x5b6f5557, + 0x9a87393f, 0xe7ac0a06, 0x38646b32, 0x2a8495ab, 0xfd261c83, + 0x0cdcc4bc, 0x6485524c }, + { 0xc4a6ff2a, 0x1abfb3e2, 0x35a6428a, 0x2aa03fba, 0x89aff742, + 0x884227f0, 0xba5dbd93, 0x2337883a, 0xd2a182cb, 0x38186ae9, + 0x49a01f05, 0xb9f0764d, 0x917b1e7a, 0x92411feb, 0x570cbb5b, + 0x700b1903, 0xb914be7c, 0x5d5181d5, 0x1981182d, 0x135c4437, + 0x574b9997, 0x32758d24, 0x632d28b2, 0xa650a8f5, 0xfa383f09, + 0x24078bac, 0x00a33d80, 0x6546a60c, 0x2df8b449, 0xa4061c7a, + 0xf234563c, 0x1f76f3f2 }, + { 0x44c436b0, 0x9aa2c143, 0x1f69c87a, 0x79070556, 0x5f6db2df, + 0x35f3117b, 0xed56ba82, 0x85761f41, 0x7d0afa48, 0xf831464f, + 0x3adce71e, 0xa99f2915, 0x116b7488, 0xb27bf693, 0x9bb9443a, + 0xa98a5a8c, 0x2ee5fde8, 0x7f878026, 0x1812acb7, 0x3a6f93dd, + 0xdc84bc92, 0xaf92a4cc, 0xf1d4995a, 0x3c2562af, 0x04ed899d, + 0xfd9fc33c, 0x4ed2a538, 0xc028ca94, 0x049ea726, 0xd0f367bb, + 0x3d108e05, 0x04924ffb }, + { 0xc673562f, 0x06548e3d, 0xe2eae48c, 0xd3b33025, 0x5e1c6977, + 0xe61fd32b, 0x6ebe557b, 0x424e2064, 0x41d6e18e, 0x767391c0, + 0x14d7e95b, 0x4b8ebb8e, 0x20991b8c, 0x4ae8b7d4, 0xe01290d3, + 0xf8a0df66, 0x925e5f4e, 0xc97e24a3, 0x1508272a, 0x79a7b2cb, + 0x25072661, 0xb40b072e, 0x9062fa49, 0xdad9e182, 0xf3c53bce, + 0x8780a784, 0x9f142799, 0x58a82b76, 0xc1468426, 0x08cd849c, + 0xc380ae35, 0x4dfce809 }, + { 0xd527b780, 0x45069cb2, 0x977930dd, 0xd52da015, 0xe27d0263, + 0x10cc600b, 0xbb2d1b2b, 0x34102c26, 0x554adf3c, 0x4c652623, + 0x45f0ff47, 0xd6891382, 0xca916e7c, 0x83fa8cc5, 0xd15c8d8a, + 0x1e10f139, 0x81dc56b3, 0xf173dc2e, 0x5c4ed9ba, 0x7fcecb04, + 0x47d01228, 0x307fd7d8, 0x9f3a532f, 0x24a57153, 0xe2153c22, + 0x59e9e81d, 0xe428a408, 0xc562595d, 0x9339bd23, 0xdc7daff8, + 0xb8a06802, 0x0d075908 }, + { 0xde085f2a, 0x870af2a7, 0xbe99b2e5, 0x88fcd24f, 0x59ca413b, + 0x88c0d261, 0x8559f851, 0x1f02a2e4, 0xf622da0d, 0x83b96021, + 0x6dca3615, 0x5c05c2f5, 0x7910c682, 0x0148cf1c, 0x272695be, + 0x392f2896, 0xa8d64ef6, 0x883d0bb5, 0x1cfcbc52, 0xef0d2244, + 0x526117e5, 0xf5dafcec, 0xf04928e9, 0xb68612b9, 0x393f2e2a, + 0x283f744d, 0x700c1151, 0xfbeed7ed, 0xa4360dfe, 0xf2cde215, + 0x2f08535a, 0x24fa961c }, + { 0x616df7f6, 0x0767db3f, 0xfbd90326, 0x643057d8, 0x6e82d544, + 0x174daa90, 0x689643db, 0x2284f345, 0xcc89a060, 0x18b191df, + 0xd6c27d12, 0xbab46af4, 0xc9895145, 0x5a57f486, 0xcc942f9e, + 0xc03214e9, 0x41950158, 0x273e1c8f, 0x39ad43ab, 0x8ceb759f, + 0xe50ee173, 0x5e1b8b7f, 0x8f4d7d4e, 0xf635b1fc, 0x755603f3, + 0x8eff77e3, 0x7752fa60, 0x201f61d1, 0x4a6fb6e1, 0x94d7a03d, + 0xfc4f0114, 0x371cc23d }, + { 0xda90c351, 0x289b115d, 0x364d9c06, 0x6d196ebf, 0xf650b31b, + 0x77a89202, 0x6f57642f, 0xcc28c164, 0x08100127, 0xdc4f7e36, + 0xdc4c807b, 0x8836cd08, 0xe00240f2, 0x1280f156, 0x99cb3953, + 0x3f9a6d78, 0x3a802038, 0x40a494d3, 0xe87d3474, 0x45697e91, + 0x26dde24a, 0x70d97d07, 0x7640c30e, 0x06f6a58d, 0x5ba6e6c6, + 0x03c2c0e8, 0xf1bc13e8, 0x330f6a7a, 0xc9f4d78f, 0x3e602e4f, + 0x0c80fb7f, 0x92b6bca0 }, + { 0x5f00822e, 0x2e3d5c83, 0xb8b16f12, 0x0e825712, 0x92b0a330, + 0x81c329c4, 0xa7cc1954, 0x6b4e32ad, 0x1bb1413f, 0x0bee9cee, + 0x4a92ca27, 0xedfb7baa, 0xea3b9153, 0xcd472afa, 0x00f0c0f9, + 0xe8f09e7e, 0x5cdebb70, 0xa4e1d872, 0x4a9b63b6, 0xfe2bae08, + 0x3fd58f65, 0xf40141b8, 0xa3b62759, 0xd7ec5eda, 0x790e3088, + 0x9aaf6e67, 0x1f277e31, 0x215ad830, 0xcf33871c, 0xe7db4b98, + 0x4f02f89d, 0x71ff62c9 }, + { 0x2a4a84d9, 0xaa4c7102, 0x5ebc71e6, 0xe2ee4acd, 0xf1cd6578, + 0x3b11a8a5, 0xfff120a5, 0x83f5ef9f, 0x09e65033, 0xa4c598e1, + 0xca044180, 0xe1e9f990, 0xf59828c1, 0x8b832d46, 0x33af536b, + 0x753f28a0, 0xb6d4f68a, 0x92edc4b1, 0x72ccd1f0, 0xedde692a, + 0xd2226432, 0xd3aa0f7d, 0xa3d2661c, 0x38dbb63e, 0xfdc37dda, + 0xf1e19fc6, 0x84ef6b4c, 0x6c18b350, 0xdf1bba69, 0xe6a83fe9, + 0x5f958273, 0x40fd47e7 }, + { 0x267140a4, 0x5b88b746, 0xeab6f2fb, 0x6dbbfc1e, 0x69862548, + 0xdd9ec88e, 0x2eb6efc2, 0x69beeba1, 0x8ac8ff88, 0xcfc2214a, + 0xb5a21950, 0x95d5c96e, 0x4171fb69, 0x93389c05, 0x1b468337, + 0x2d85d452, 0x4113425c, 0x14d68a08, 0xec6c2174, 0xe52c0139, + 0xf730084d, 0x20cf0b97, 0x1f578aa3, 0x1ac16a26, 0xf9b6ae43, + 0x18b9fab3, 0xd854a695, 0x68d82111, 0xdffbe286, 0x0b334d98, + 0xe639338c, 0x5b1c1157 }, + { 0x72b6bb8f, 0x90edaab1, 0x02fc92c2, 0x8dc64ed2, 0xfe694c73, + 0xf42ba3c5, 0xcb54dce4, 0x316dc65f, 0x632420dc, 0xcb2d66a3, + 0x056dcf94, 0x16e706e7, 0xa4f32c9d, 0x2809c764, 0xea6edca8, + 0xab18d830, 0x81c65f57, 0x4fd1ace6, 0x7da12c10, 0x1f91651c, + 0xc7791a48, 0x0ac3bd66, 0x785e67a3, 0xb6ad1cf4, 0xda0fd591, + 0xe4d3fc44, 0x6e1c6344, 0xce164801, 0x33e50ab3, 0x84de9cb8, + 0xa756eef4, 0x963ab83a }, + { 0xdf4ea5a3, 0x944b47d8, 0x5cfe45fe, 0x96568815, 0x8a3c3564, + 0xd16e7d58, 0xe7c99e15, 0x84e55b3e, 0xf55071bc, 0x3fee204d, + 0x04057dce, 0x71006f29, 0xbba75570, 0xfe8c390d, 0x3319adac, + 0x3645bcb6, 0x7c20bfd8, 0x8189e8b0, 0x7d7d9578, 0x8e550969, + 0xb99f4e3b, 0x037d1321, 0xa60cfb6a, 0x011b2521, 0x837382da, + 0x66594aaa, 0x83c1dc07, 0xc89b91fd, 0x076b9884, 0x6b82b899, + 0xbe45c558, 0x443480fc }, + { 0x9114221a, 0xf8ffffb4, 0x3e857a7a, 0x4aec4f2e, 0x0fa54787, + 0x42e2d0e4, 0xd6f96152, 0xef3e6b31, 0xfbfe9b77, 0xb2296537, + 0xfb43a86a, 0xc2a9d0f2, 0x24572ac6, 0x241284ed, 0xe721ba7b, + 0xa3868917, 0xc117a78d, 0xdbef7c00, 0xd31605ac, 0x38149071, + 0x065a8ee9, 0xc2dada9e, 0xc442be82, 0xd5b138d8, 0xf6d72b58, + 0x9b6c224b, 0x8eb03e6d, 0xb9d355cf, 0xa1700371, 0xab6d1eb0, + 0xcffaa7eb, 0x97118a88 }, + { 0xcdecb5d8, 0xbf9c59a2, 0xa93a6866, 0x8083c81b, 0x04774fbf, + 0x24e0dd81, 0xa02070b4, 0xe779a3ca, 0x0fbfb781, 0x9d352fbb, + 0x3ef2a1c4, 0xa8b0d820, 0x14b3e501, 0xb858637b, 0x8a882ff2, + 0x5ba70a49, 0x3b06efa5, 0xa2730083, 0x102fee2a, 0xa42c02f4, + 0x8a0223a5, 0xe4e76299, 0x85c3fc72, 0xdba2ba26, 0xfe52eae7, + 0x554fe763, 0x270f45f6, 0x30b5405a, 0xa573387c, 0xd56a177a, + 0x4b71fa82, 0x17c0778d }, + { 0x2735e37b, 0x0e6dff1d, 0x656ec572, 0xc9884e56, 0x9ebba978, + 0xa2f5ac9d, 0xba09f3c4, 0x40fa4518, 0xf5b04377, 0x8c3fa177, + 0x967a2eca, 0xa1a1decd, 0x0528bd40, 0x768bca70, 0x18691c4a, + 0xf224952b, 0xe86d5fd5, 0x16e12c45, 0x37859a6a, 0x7a0d9157, + 0xa0ffce0e, 0x723f4309, 0xa96cc9a3, 0x5a8db79b, 0x1ad23a38, + 0x6dd12ae0, 0xe2bf5d84, 0x9ffec3a1, 0xa452ed66, 0xd6ce84e1, + 0x571fe4c6, 0x1219d5c8 }, + { 0x262969eb, 0x43eaa67f, 0x2f03e773, 0x3a3ab39d, 0x57bb0909, + 0xe6127e51, 0x8d150274, 0x0f82b0ed, 0xe580bdbd, 0xffffcad8, + 0xa9743e6b, 0x51d3d075, 0x8bac11d6, 0x1484bdb1, 0xeb24c388, + 0x95cd9990, 0x7fac67c6, 0x216a61d0, 0xa04e6b87, 0x4308f762, + 0xcba57cc8, 0x2865dd61, 0xd234a07a, 0x3c296b0d, 0x3a0793f9, + 0x76f92839, 0x0be29ece, 0x70b57e1f, 0x7e626f42, 0x1314a82f, + 0xd657f230, 0x2c8d7ab2 }, + { 0x0825e4d6, 0x67cf5892, 0x6ef83b44, 0xdf51eaa5, 0x1310108d, + 0x63e665d8, 0x8dd0963f, 0x229f89f5, 0x9df6436a, 0x8c4b14dd, + 0xd45ebba7, 0x99dae469, 0x5a4df381, 0x118aab77, 0x29e37feb, + 0xda8978bd, 0xaca2d7ef, 0x69ced5aa, 0xc67d6a8a, 0x6c98d05d, + 0x77f84a34, 0x7474bf0d, 0xed8cd59a, 0xd4428b2e, 0xd1d398fb, + 0xb0fd1cd5, 0x94a20b11, 0x596013db, 0x1b404c44, 0x96eb705a, + 0x4b09d958, 0x2299d277 }, + { 0xc64397e6, 0x5b9cd58d, 0xbf6dd31e, 0xac198f1e, 0x3e9f1db2, + 0x5866d8e1, 0x8fcdc68c, 0x405ae287, 0xe53c01fd, 0xa4b280cd, + 0x411db5f6, 0xdc963f2d, 0xbec4f8a0, 0xed5d5189, 0x916ee98b, + 0x336fd13d, 0x042df48e, 0x6925b1b3, 0xace0074e, 0x0cf56291, + 0x25317e95, 0xe8d38b48, 0x821c446b, 0xc7ad1d2b, 0xf0b65934, + 0x71c44135, 0x52ca0d50, 0x971b736f, 0x27b46c26, 0xaf9ffa57, + 0x1936618e, 0x21ac6779 }, + { 0x2d7fbcd2, 0xab420e3f, 0x97bdfc18, 0x12722473, 0x4df5d4b4, + 0x492033f8, 0x3807b7d3, 0x6fcd4236, 0xb33c3625, 0xdfc19b09, + 0xa0f22814, 0x13d6f375, 0x037c19b8, 0x70978a59, 0x0ff27b9c, + 0x4f398997, 0x615a4389, 0xfc0e1a45, 0x3e602f74, 0xffa3496a, + 0xb261ca1c, 0xc3f1c431, 0xee0164cd, 0x612211db, 0xe7f7be9f, + 0x30463ee4, 0x92c2e1bb, 0x015f7e78, 0x24483a56, 0x663d88d6, + 0x0e62d9d8, 0x0e8ec1e7 }, + { 0x8a0878dd, 0xa88ccc29, 0x6640071a, 0x99ac175d, 0xa5173617, + 0x90344820, 0xdd58a315, 0x316d023e, 0x88d221a1, 0x30785bd4, + 0x959c48e3, 0xb74b3de7, 0x4c67a771, 0x42ee0382, 0xe0b91453, + 0x59ef6cdd, 0x9b237e91, 0x7830ae28, 0x495d8325, 0xe1847a4c, + 0xd0773666, 0x67b1217e, 0xa294a325, 0x58192c86, 0x864d8326, + 0x76aa0f56, 0xf4b13e5b, 0xe2a2bd12, 0x1b6b73fd, 0xd850c1c0, + 0x5d103635, 0x653a795f }, + { 0x50dcb199, 0xcfe28985, 0x7fa02b60, 0xb35b8e5e, 0xc97603d0, + 0xbca7d7c3, 0x27f131b5, 0xb0e5288d, 0xe2b12d52, 0x3aa704de, + 0x1db725c7, 0xe206b1d8, 0xc5d1b113, 0x0b12839a, 0xdb45d763, + 0x14f970cb, 0xb2125e8e, 0xc997f93e, 0xee7daa26, 0xbd75739c, + 0x1fef20e9, 0x46ecbd3f, 0x7c6a42b1, 0xf994a114, 0x27fb0fd1, + 0xd289eb4f, 0x9a40da4b, 0x11186d31, 0xfb9d7976, 0x083f65a5, + 0xd444675e, 0x30dfc47b }, + { 0x9eaadfe8, 0xbcfc5ae2, 0xb4d4e812, 0x25027e54, 0x8b533561, + 0xab0702df, 0x56a6a214, 0xa2b9c204, 0x3059068e, 0xb1a3df7a, + 0x9883110f, 0xa3514b21, 0xc4b78e1c, 0xb7be2336, 0x3e2f6984, + 0x17073ce6, 0x2ddf7ac6, 0x86e114a6, 0x07d7c3c8, 0x276192bf, + 0xeb1ae289, 0x5da69e0b, 0x25184939, 0x983af175, 0x407a3aa0, + 0x9ac52a4d, 0xae0fe218, 0x1535c7da, 0x397f2501, 0xe16fe872, + 0x54c212cf, 0x572a591f }, + { 0x09a5553a, 0x49668419, 0x327733bc, 0x3f054318, 0x3eefd690, + 0xf9ceb4b2, 0xf22126d4, 0xbd3cbf9b, 0x2fed9578, 0x6d9671c0, + 0xca0306d8, 0xbba597ce, 0x3d674fe5, 0xb705ed61, 0x67f33f76, + 0xf1d3622b, 0x11cb8c31, 0x15bcf3c6, 0xe53d1aa9, 0xa38467dc, + 0xf908ab43, 0x902fe929, 0x8d15767a, 0x6e3e499d, 0x90afd07b, + 0x8142db5c, 0x6c8b190e, 0x120c6fbc, 0x24919a4e, 0x80c86553, + 0xd8c82c3c, 0x65c2cbe1 }, + { 0xa660bb63, 0x684cda20, 0x86e86245, 0x27dc3b0a, 0x6ba0eed7, + 0x76472cf6, 0x679dd158, 0x79c162e5, 0x08452d44, 0xb6884277, + 0x413f579e, 0x829bc6b3, 0x95011770, 0x92ea15ec, 0x47738183, + 0x5e34e300, 0x73e1d2f1, 0x8c3ca349, 0x229bd3de, 0xa5c4f1dc, + 0x94ef7ed3, 0x783eff1b, 0xdfae7a1a, 0x46db738d, 0x1a099852, + 0x4353d72e, 0xa0dcf4ab, 0x2533ad58, 0x0e7888b9, 0xd8055016, + 0x3ba77f66, 0x831440d5 }, + { 0xf611b2da, 0xf43e2e32, 0xd0fa46ac, 0x5d066e29, 0x820b3c0d, + 0xe897f3e8, 0x1d3e44f0, 0xc45c28e6, 0xdfd27a66, 0x929d7f66, + 0x101e8517, 0x735b860a, 0x3de078dd, 0xea3fce98, 0x638ce11a, + 0xc9977db5, 0x48536b3b, 0x0488382f, 0x64cadfc6, 0x7e0c7a3c, + 0x82147b71, 0x3cd17f7f, 0x1b411e3e, 0xe95663cc, 0x985fb46d, + 0x5739ac8f, 0xbcf119ca, 0x385399cd, 0xe15a2815, 0x4a985a70, + 0x6d5f4566, 0x504c3a8a }, + { 0xb8fa53c7, 0x00b55283, 0x509474e3, 0x985cff38, 0x437ce25f, + 0x234d241c, 0xe5a129ed, 0x29832430, 0xaabcc674, 0x6ad38956, + 0x7ee81ee1, 0xa2dc001d, 0x670b2702, 0x4c23c6b6, 0xa6e8a3bb, + 0xb35e567e, 0xa69673ea, 0xbc70b3ce, 0xe6e28eac, 0x85a7a9c3, + 0x5537b7da, 0x2ae684de, 0x6de937dc, 0x5ecac3e5, 0xf8430422, + 0xbf2ea6c9, 0x77fdc520, 0x38caf7d0, 0x69f56add, 0xc27af0b1, + 0xc71d21d2, 0x496e4699 }, + { 0x9fa93467, 0xba14fc82, 0x0eb2a614, 0xc2e37684, 0x4833e09b, + 0x659bcfaf, 0x3686bdcc, 0xbc859752, 0x81f3216a, 0x40bfd080, + 0x17c081b8, 0xc463bda6, 0xbb04793b, 0xbd01fa86, 0x2cd640c5, + 0x5a21ece6, 0x2203d5c4, 0x97bf6a54, 0x951167b7, 0xceb40edc, + 0x765ba268, 0xd67aacaf, 0xaeab51f9, 0x8ba0d9e9, 0xb0d6863a, + 0xc14b215e, 0xe5f06952, 0x354cdcdb, 0xcb3744b5, 0x4f2b5ccf, + 0x13037fe8, 0x13389173 }, + { 0x45003cd1, 0xee680640, 0x44ae2ac6, 0xfdac17bc, 0xde8e5314, + 0x4bcd419f, 0xc7cea95c, 0x81e34eb9, 0x38f37e01, 0xbb57762d, + 0x260990c8, 0xecc4cfb0, 0x50a34a7b, 0x0bc493f9, 0x543304ef, + 0x68074172, 0x6bc8aa2a, 0xaec0fcb2, 0x3b45fea5, 0x9e7a9b46, + 0x55fbdbac, 0x4bb2952e, 0x0485dff4, 0x50f0c0a6, 0x4dea4796, + 0x02c5104d, 0x695e3a02, 0xd2cefa09, 0x6da1f345, 0x4c8102b4, + 0xf3833fbd, 0x422eb573 }, + { 0xa6ad3f47, 0xac592eb6, 0x9714ba0e, 0xb0861f6d, 0x07281459, + 0x57c1e919, 0x64ea5803, 0xcf7c94e2, 0x54b12723, 0x725376ac, + 0xdafb736a, 0xf2a6ba41, 0xcba03cdc, 0xc89e8920, 0x5b0fd3ad, + 0xf2e20cb4, 0xd66059fe, 0x26ea5a54, 0x889df8bc, 0xee63fa8b, + 0x66a3f2bf, 0x40f1c7e1, 0x747312e1, 0x09febc9c, 0x727999ff, + 0x7d19b9c2, 0xb7fd2b05, 0xa9fbbb4c, 0xa0da2dc6, 0xcfba27d7, + 0x2c252582, 0x368541cf }, + { 0x22799d37, 0x510d3c9e, 0xacfa333a, 0x1b677de5, 0x080f795b, + 0x4e6ae18f, 0xafc8dfc2, 0x69b53c2a, 0x0e842dc2, 0x797541b6, + 0xac067fe8, 0xd5a6f2af, 0xbd07d877, 0xd0208a03, 0x654be2f2, + 0x34b473f0, 0xf515e23e, 0xe67c102a, 0x2ac1af48, 0xb00dbf9d, + 0xb6a13d00, 0xe264fa41, 0x97e94c11, 0x1669786a, 0x86a586f4, + 0x09d8cf2d, 0xc7f927e9, 0x073bf869, 0x2241a566, 0xb8977880, + 0x22261334, 0x59a5bf59 }, + { 0x81347191, 0xe9d1c91e, 0xeb969972, 0x186c1abc, 0xa9d46a7f, + 0x07888767, 0xdaa7d397, 0xda93cfcc, 0xd91b9aa0, 0x08bee9f1, + 0xf8dd3c6c, 0x8267fd78, 0x94228100, 0xf93860d0, 0xdadb47fb, + 0x6a6a71aa, 0xa6156f8a, 0x9caa06b7, 0x39848bc9, 0xaa1b05e0, + 0x2aaa9135, 0x36ddc237, 0xb13f3bd1, 0x77e7e079, 0x4acc5f4d, + 0x8d0b5cbe, 0x984cfd36, 0x04da45f8, 0xd3d3e0f8, 0xf14ef618, + 0x43eb799c, 0x467564c1 }, + { 0xb6fff5d7, 0x8d725904, 0x92dc4752, 0x037f33af, 0x6d20b8aa, + 0x9095d575, 0x43baec39, 0x32235fc1, 0x68a2b9b0, 0xa2feb4af, + 0x94d35c61, 0x61c50318, 0xea877486, 0xac92b6a2, 0x011bc6f3, + 0x8eb48b15, 0xc79edcb2, 0xa28fe128, 0xa5d2a006, 0x9f71bc0c, + 0x2f15b850, 0xf3167732, 0x7a036218, 0xfe8d728c, 0x4f81e09e, + 0x068f39cb, 0x7b7c50d9, 0x1773f016, 0xed6a1e03, 0x0d0f7adb, + 0x4ee984d5, 0x8a0dee16 }, + { 0x47366e6f, 0x504991bf, 0xe86c3005, 0xb8084d9f, 0xa40cce36, + 0x14c4c751, 0x3f1961e2, 0xbbb46aa6, 0x40445e43, 0x56a785f9, + 0xc91e215f, 0xdb8d1b57, 0xc7ee808d, 0x6a8e453e, 0xbbaa1e8c, + 0xc0367ef8, 0xe3e18109, 0x310d91f1, 0x7e20a2c3, 0xf97cfd0e, + 0x554cc277, 0xf1e80c84, 0x7b628403, 0xe89bbc1d, 0x3fe0a17c, + 0x7778a966, 0xc1f00073, 0x9e9db19f, 0xb6f6bed2, 0x2ce7fe7d, + 0xee97ce23, 0x7b04b5d2 }, + { 0x82c5faf8, 0x5b546bc7, 0x8eb81097, 0x1a734c5e, 0xe77851e0, + 0x3d566861, 0xe956d51f, 0x833a1013, 0xc3c3c37c, 0xc7351731, + 0xe0c148ec, 0x607738fb, 0xe1bbef41, 0x2ec6f0bb, 0xcfa51857, + 0x0aa2ac6e, 0x66e3adf0, 0x072902d7, 0xc622d6e3, 0xcd4d5089, + 0xa6dd802f, 0x3ae21b23, 0x33886372, 0xe5465a55, 0xa8d81822, + 0xd85119a0, 0x3786977a, 0x4f14d032, 0x9c7b272c, 0x515b081c, + 0xc99be31c, 0x1c6a95a4 }, + { 0xc2821363, 0xa6b14ad5, 0x4d17de1c, 0x829c1823, 0xccade848, + 0xaef5d2c4, 0x82489e27, 0xf412ab39, 0xf081d927, 0x92c9c098, + 0x75cbad1f, 0x6f87bdf4, 0x1a1d9fb1, 0xf4aadab8, 0xb75f3b76, + 0x475a7923, 0xdbbba8fe, 0x99dd0ad6, 0x4b70ab45, 0x836f6164, + 0x34bd9af1, 0x2a464881, 0xba9abda3, 0x5c91226e, 0xe65625fb, + 0x4cec8709, 0x0818e4be, 0xd4b3919e, 0x14f6879c, 0xa5c09c84, + 0x30a864c9, 0x72708a02 }, + { 0xf34a466c, 0x4f33c0b1, 0x7f9d45ba, 0xa1bae09c, 0x0e28785c, + 0xd70f0fee, 0x90880881, 0x824c7146, 0xbb043da3, 0xe2416c2a, + 0xcec6f432, 0x733da713, 0xc9793e1c, 0x2b590649, 0xb35c9365, + 0xdb62d5b0, 0x3e5c1b2a, 0x355eb6e2, 0xbb16b515, 0xcfe8b5ce, + 0xf709691c, 0x9e081869, 0x61a85bd5, 0xc865f9fb, 0xfae103f7, + 0xf169d3cc, 0x73467e9d, 0x9525c473, 0x43695113, 0x7db55c0b, + 0x73265d21, 0x7491c74c }, + { 0x80d2b94d, 0x312ed5bf, 0xba4b260b, 0x1b8ac633, 0xd62219a1, + 0xac86c58c, 0xaeb82c8e, 0x317ccf6b, 0x59ef9ced, 0x2dfb29ee, + 0xe42bcd5a, 0xdaa7d898, 0x5974b201, 0x93e295c8, 0xd9fc5adc, + 0x69e75784, 0x012aa3ba, 0xd6c4709f, 0xc85d3cb9, 0x1fda9f37, + 0xd3dd4abd, 0xe5487e25, 0x0b3ba22e, 0x00fd4b01, 0xc6e8dcbb, + 0xcb591493, 0xbce68664, 0xb7329fab, 0x68906b76, 0x6829d1c2, + 0x74176841, 0x8bcfd3e5 }, + { 0xd3c8c314, 0x06882734, 0x11870833, 0x95f0b2f1, 0xc068ba16, + 0xb937f7c3, 0x77924787, 0x5365e0d8, 0x1f992227, 0x15527e5e, + 0x27dffd4f, 0x0a069648, 0x2f586389, 0xd58b3df2, 0x6af20ead, + 0x83446b89, 0x50746257, 0x09d7970b, 0x4022a691, 0xd9e8d206, + 0x671ec379, 0xd1e5f8af, 0x057fe91e, 0x6f542509, 0x52890418, + 0xf14dda81, 0x1db932ad, 0xbd78010e, 0x905a9378, 0x3e18d1e4, + 0xbd37ab49, 0x53cadcf7 }, + { 0x5e53d0ff, 0x1bb5edf7, 0x888abf67, 0xd886606c, 0x12206d15, + 0x6491b0f8, 0xe22b6a33, 0xb3018345, 0xb173b317, 0xaba6794b, + 0x7dc9e595, 0x8c1e5867, 0x239624d1, 0x4e106482, 0xda55dd53, + 0x61752e59, 0x9e42879c, 0x018b4eab, 0x491f2bed, 0xcaf6784b, + 0x1e79429e, 0x3dcdb9d2, 0x10f26224, 0x36941485, 0xa650ec5c, + 0x106f190a, 0xb69a9760, 0x7542a5ae, 0xc32d1046, 0x69bd75e9, + 0xbf8c62b1, 0x90849964 }, + { 0x5a93c661, 0xb1390cf6, 0x9db5f056, 0x18486264, 0xa51a1788, + 0x92a93a9d, 0x6772de9a, 0x1b0cbb8f, 0x7c71487c, 0x6e67febd, + 0x4e62423e, 0xf9b4382d, 0xbb5a42f8, 0x96fda50e, 0x6089a4f2, + 0xc921b337, 0x875ec516, 0x49d32d7b, 0xc410124b, 0xbd86d2ca, + 0xc421fb7a, 0xf6862209, 0xf6b7de33, 0x3e1949ab, 0xe93c9268, + 0xcdee18f0, 0x08dc4cc0, 0xd4edbd5e, 0x73580d22, 0xc2b75be4, + 0x468cd7e8, 0x3d7f6ffa }, + { 0xdffbd5d1, 0xea7b290c, 0x970338df, 0x9d759da6, 0x90feedc9, + 0x56680b08, 0x42dce68e, 0xbc690af5, 0xb2ae4d82, 0x8519df2b, + 0x7f195b60, 0x5612467f, 0xd83c21f4, 0x659a342c, 0x55651633, + 0x55771bf5, 0x548ba562, 0x5fc68935, 0x9492f23a, 0xb5419203, + 0x9c9c6017, 0x567528e3, 0x511e6019, 0x3f064ed4, 0x1d16a555, + 0x303f9eb9, 0x2254abee, 0x3e18c4fd, 0xfd434e7c, 0x40994d6f, + 0x6dde74e6, 0x8fb12d3f }, + { 0x293cb7a4, 0x6c6381a2, 0xb87b7e4d, 0x453e09f0, 0x078ac3ef, + 0x4f212823, 0x578cae91, 0xe89ffad0, 0x716ba4dd, 0x4a2b696a, + 0xf6f580a0, 0x14681a14, 0x4c2f1307, 0x1358f97b, 0x2932fb89, + 0x87896996, 0x268a5af7, 0x29dd850a, 0xfe239f83, 0xaf771f6d, + 0x4f47499d, 0x5f20fd2e, 0x867ca0e9, 0x9b643e77, 0x375981ec, + 0xe7858ecd, 0x19ab1c97, 0xbe946a59, 0x06ff3453, 0x4f9303a2, + 0x75d237b1, 0x3fcc6731 }, + { 0xdf21f920, 0x509debd5, 0xc1401b90, 0xfaf70e1f, 0x95a64aaf, + 0x2429cbfd, 0x2c37a122, 0xf2120855, 0x7deb926b, 0x1d4c93f4, + 0x9fb3f1dc, 0x12f3e4c0, 0x5b51bc46, 0x56085a59, 0xf10fdbd2, + 0x2a2f5d62, 0xdf0cb3c2, 0x60dd62cf, 0x6b0f254b, 0x154424a3, + 0x564612b7, 0xc3a5a05d, 0xa1f5249c, 0xbebe30cf, 0x7e62a188, + 0x24ec6903, 0xaf429939, 0x75f0fbac, 0xb3fa8685, 0xd41345dc, + 0xc7151c34, 0x645146fd }, + { 0xba1924f9, 0xecec633a, 0x006326e1, 0xbba6f136, 0x7e50fc17, + 0x203757ac, 0xef3d8e00, 0xca531919, 0x51dc5a74, 0x9545a6aa, + 0xd31412b8, 0x6e21d58f, 0x7bb1d000, 0x01bc3005, 0x6ed1a9c3, + 0xf1789c69, 0x9858fa48, 0x7af2d35f, 0x8197be85, 0x434d09b9, + 0x29aa265d, 0x1dc07755, 0xc058fa80, 0xcad03be7, 0x54ba14ce, + 0x92d70a9f, 0x6c050a74, 0x6dc78505, 0x4d005dda, 0x2a7ca4a9, + 0xabfb9f2e, 0x448d3d72 }, + { 0x29b33989, 0xdc56f145, 0xa9ae815a, 0x868351bc, 0x4b074414, + 0xb3f45613, 0x3cd9f33b, 0x955ce42a, 0x5ff6e4a3, 0x13ade4ec, + 0xa50eaa91, 0xd3aac715, 0x5666efdf, 0x0c61ec99, 0xf6a4470a, + 0x108a28b8, 0xe54844c9, 0x402ef584, 0xd0e2f337, 0xb825b162, + 0xb46f7cbc, 0x3dcd131f, 0x96f2fd89, 0x208178ec, 0x25928c78, + 0x4d8c5d67, 0x9963c459, 0x285a33df, 0xd92a309f, 0x72497175, + 0xcb7019a5, 0x76881479 }, + { 0x91767eed, 0xba43a114, 0x92bf65db, 0x5e11b9ad, 0x03a5e21a, + 0xe8a22ce0, 0x2a335415, 0x63604421, 0x4a9ead62, 0xc2c563b4, + 0xa0b2aee5, 0x4bc06264, 0x8bf2e1d7, 0x75b8d575, 0xd08a265d, + 0x1cff0ee7, 0xb0b712a7, 0x17914e1d, 0x4b18692d, 0xc35925d0, + 0x56cce815, 0xde253f4c, 0x9fff0e3a, 0xa479241c, 0xddabed19, + 0x50b9d06e, 0x59fae506, 0x67135260, 0x532ce180, 0xf37600fb, + 0x5e5a8626, 0x670eb01c }, + { 0x73cdbb43, 0xdf73c0af, 0x7f2431ad, 0xcf08ecc5, 0x2a1a3845, + 0x91780541, 0x9224ddf1, 0x69a104f2, 0xbeac7eff, 0x4352f38d, + 0x7c2d1322, 0xfc3b3b4e, 0xb5e4b476, 0xa69e9430, 0x975a46f0, + 0x7d932340, 0x5d64eece, 0x8093899e, 0xdb2345e9, 0x7b821250, + 0x7f4b796b, 0x23552932, 0x4bb90b1f, 0x2ee9cc15, 0x9112f7d6, + 0x1fa9c8f5, 0x1cbaae32, 0x2d0f2f98, 0x0075166a, 0xb77f0366, + 0x635dff27, 0x504852e7 }, + { 0xa2f392fa, 0x2f0f3ce5, 0xec6c9078, 0x326c076a, 0x84baaaf6, + 0xad01de92, 0xcbe8e993, 0xb01b16d3, 0x2d950908, 0x71305c24, + 0x3853af38, 0xc66fd617, 0xd3c429a0, 0x7735140e, 0x1fabf027, + 0x8a31b12a, 0x058b3177, 0xa0530002, 0xa9c7deb9, 0xabffd9fc, + 0xe8667d30, 0xd05ef69b, 0xe9a9e13f, 0x2f3a7308, 0xb91eae9c, + 0x3f4c9a19, 0x618ce6c4, 0x50d0cee7, 0x5240f8b0, 0xfb24dc40, + 0xf7e90cc4, 0x992fe151 }, + { 0x38f197aa, 0x4454db31, 0x87872f98, 0xa4ded69d, 0x44f0a828, + 0x97b427b0, 0xa31e48c6, 0x9821e1ae, 0xdd98efec, 0xe38cb09f, + 0x480cb3ae, 0x20b84fa8, 0x47475573, 0xba5bb4a8, 0xcd50e96b, + 0xa9be080a, 0xef103550, 0xc4451e9c, 0xc441325c, 0x626ee75f, + 0x38a5e33d, 0x6eea5e98, 0xa2b0abd2, 0x7321beb9, 0x9b6082a9, + 0xca92e484, 0x992bcc2a, 0x1dc8168a, 0x9c8eb9fb, 0x134ecf4b, + 0x4c5b71e0, 0x5a68bfa8 }, + { 0xff0a2bfb, 0xb4ff3b45, 0x5502f8b0, 0xd105fff9, 0x5b1c0c26, + 0x14de5885, 0x0d3b9d04, 0xed16865b, 0x026d3917, 0x2f5a2453, + 0xf4db3c0e, 0x6a22f493, 0xe2418f2e, 0x4871548a, 0x509bef61, + 0x6ab363a8, 0xb8cbbbec, 0x91ca1e3a, 0x4011a396, 0x71e0dc98, + 0x0d5ca577, 0xff982e0a, 0x81897bc1, 0xeb40b045, 0x085ad5e7, + 0x4bc24a46, 0xa6337b7c, 0xd15c8fa0, 0xbef1628f, 0x56ce6ef7, + 0x9f5ef439, 0x78acfdf9 }, + { 0xf8520189, 0x45bf7f15, 0xc77f61c4, 0x954202a0, 0xdfa22e1b, + 0x39edc6b9, 0x1f4a3487, 0xd2d60267, 0x4814cc52, 0xcd933929, + 0x05e9f123, 0xde76a124, 0xae36b6f7, 0xe2306ea0, 0xb83a58e0, + 0x53815218, 0xa041231a, 0x9862bb76, 0xbf31be71, 0xe8da253c, + 0x37de861f, 0x2dfc5332, 0x90ae4890, 0xf25c93f6, 0x8baa6ed2, + 0x66bcb8f0, 0x908b4a29, 0x6f10ae0f, 0xb061c949, 0x8cb4b48c, + 0xd075a366, 0x0ad92d73 }, + { 0xc2ca548a, 0xbfb95fed, 0x80cd89ab, 0x4778c620, 0x3466c280, + 0xbe99154b, 0xd4be8902, 0xea3be093, 0x13e681ed, 0x847b7995, + 0x02f40161, 0xf22a8f4b, 0x4aeb7fe8, 0x3ef2cb4d, 0xb3aed5f6, + 0x9adc5151, 0x98c31163, 0xec1ccfd1, 0xa3d7d88f, 0xdc2ac17b, + 0x46421097, 0x08fa64d3, 0x94b90bcf, 0x5ebf80b7, 0x0b50a9eb, + 0x1b78b4ba, 0x279aa66b, 0x1a4fe934, 0x075b3ced, 0x8ef4dcaf, + 0x70a6e9ae, 0x95bbd8a0 }, + { 0xe614bbd0, 0x59f92495, 0xb823e363, 0x7567a887, 0xfc1bd6a7, + 0xe247c9ec, 0x8e835c42, 0x2bfaaf47, 0xaade066a, 0x314ef4e0, + 0x5c16d336, 0x072baa63, 0xe2f0e389, 0xfa429c71, 0xbd07d90f, + 0xcac1e5d0, 0x514f5c04, 0x69ff35ea, 0xc0554ec1, 0x893053fc, + 0x2a35947f, 0xab1d86b7, 0x2aebe487, 0xe29fb060, 0xdfb9cf21, + 0xa0a10d6d, 0xf20dfcf5, 0xad147059, 0xb8867a2a, 0x480dc66f, + 0xc125a919, 0x375a884f }, + { 0x1217f7ea, 0x178cbe2e, 0x875c6dab, 0x1a161e2a, 0x1bdb1a54, + 0xf7707ec0, 0xe4fd73ca, 0x678864a0, 0xd13a0d86, 0xbaebc664, + 0xc8d30668, 0x40325f99, 0x2f1c5950, 0xb93ed9c9, 0x541e0667, + 0xfdf36763, 0xb91a6763, 0xfd97fbb0, 0x6079c9a0, 0x26aa69ea, + 0x1eaa8c47, 0xc7303c80, 0xafa63c55, 0xdec75c81, 0x4fd12adb, + 0x01cdcde2, 0x1968838a, 0x9fe0dda7, 0x38415379, 0x66bb093b, + 0x08cb84ec, 0x268d818b }, + { 0x41580555, 0x73dae358, 0x473d103b, 0x4fc32e67, 0xbeccc1ab, + 0x240c1013, 0xb24ee9de, 0xda4099f2, 0x9fa8e066, 0x37b0cb5b, + 0x6438d7ee, 0xb5ae04e4, 0x2b720140, 0x7f7d3164, 0x339e4a78, + 0x86ef4edb, 0x3a7d8375, 0xa5e77eed, 0xbd707c2e, 0x883fad37, + 0x0f979189, 0x816b633a, 0x2e7a208e, 0xe24c028a, 0x4435516a, + 0x1171fe3c, 0x4f5f2bf5, 0x3eb93b33, 0x01b53a56, 0x8419ed4b, + 0x056ca44b, 0x8b02735c }, + { 0xe1019195, 0xb89bb464, 0xf3fc28c1, 0x1de4c026, 0x2bfc3b21, + 0xac120e6e, 0x91bdf92f, 0xec71bc5a, 0x0d995bc9, 0x485d7ab4, + 0xe6491ffe, 0x97c6768e, 0xafbce265, 0xd9552d19, 0x8e1b76c2, + 0xbae6c7fe, 0xd7e3ad1b, 0x167d8281, 0x5e989734, 0x3e149af9, + 0x8a0c8182, 0xd1f0024c, 0xc3006c0d, 0xf571ffdb, 0x58773d4c, + 0xb32ecf7e, 0xfd3540d8, 0x5822a782, 0x04365042, 0x5ab45c3f, + 0x4b4d85fe, 0x400e3aa0 }, + { 0x5e46e4a2, 0x47321649, 0x24136074, 0x37a2ed64, 0xc60ec77d, + 0x659223b1, 0xe5e0ac2e, 0x5e13aac3, 0xc5107ab7, 0xda17c41b, + 0x73c253db, 0x65b22ec9, 0xa5012296, 0xff3867b8, 0x0621a99b, + 0xfed660d5, 0xc89fc3f5, 0xa3c28506, 0xf16451a7, 0x3ed350b9, + 0x67cb586f, 0x27c3e032, 0x967185b1, 0xc807c779, 0x4a13009b, + 0x09c157d4, 0xadaf1f4d, 0x362f7647, 0xf3a6a198, 0x4a42b9ac, + 0x8da6e039, 0x131c3da2 }, + { 0xa7da83ba, 0x4a785ff1, 0xd04f4436, 0xf415b425, 0xec03f812, + 0x7c0899bd, 0x80f5f4a2, 0xc58d411a, 0xfda251b9, 0x3d32d610, + 0xcd3b2f32, 0x99bb4504, 0xf4c2083c, 0x198c444b, 0x730e83fd, + 0x60c261af, 0xcb02db90, 0x060ca4df, 0x9df1e7c8, 0x0ff7838b, + 0xc4c690c9, 0x6b79cf97, 0x5d75f154, 0x131514d7, 0x1cb0e8ff, + 0xa7c074f1, 0xb2c17615, 0xb920aac1, 0x44aa0ff0, 0xde8098ad, + 0x34545ce9, 0x71d1a46a }, + { 0xfa1b382e, 0x76178f76, 0x772dda0d, 0xa0d8ecc3, 0xc5d4d130, + 0xaa5aab2a, 0x8d72622c, 0x27d38ba4, 0xca3bed06, 0xc5410db6, + 0x793ceccf, 0xf637a588, 0x6e65e3d7, 0x1f65dafd, 0x60a45641, + 0xc3b44a85, 0x4f78540b, 0x0f47b3a8, 0x5e4d60f6, 0x824fdadd, + 0x17d3b6d5, 0xd8ccf90c, 0x325fc13a, 0x008eabdf, 0x3648fab9, + 0x3e90d716, 0x24c52d4b, 0x3964ff3a, 0x533d0acb, 0xb95cc416, + 0x1167f521, 0x6cd2699f }, + { 0x12f4f3ac, 0x2d8c0b3b, 0x99d1bdfb, 0xb03dcfe2, 0x30f37326, + 0x540034f8, 0x7c5a8c82, 0x22dd6893, 0xcd8f1442, 0xeb7093d0, + 0x585742f2, 0x892795a7, 0x087adadd, 0xe15f282c, 0x16ab7b5e, + 0x7bbdc749, 0xa58acbb4, 0xd30fe40b, 0xe2bac39b, 0x0de417eb, + 0xc61a04bc, 0x4b4b19a6, 0xf2735569, 0x9338c34d, 0x30ab196f, + 0xe8f03742, 0x6c88c965, 0xfa2efcb8, 0xc7eeb826, 0x19eee274, + 0xda345dc2, 0x327c063f }, + { 0x5b47cd53, 0xab399eff, 0x1943aefe, 0xbbe9869d, 0x1402a866, + 0xe64ecc7b, 0xb1c25a16, 0xc3e7c2aa, 0x022de271, 0xc4216b79, + 0x366d6a5f, 0xe58dfcc8, 0xda813336, 0xd159509e, 0x130bfb7c, + 0x370400f2, 0x93b48780, 0x1be4e059, 0x39f3cd22, 0x0623a1fe, + 0xeecb4f87, 0x72aa22b2, 0x6c27b83b, 0x1af4c496, 0xda5fa5bf, + 0x7a42a94b, 0x48b01af2, 0x9afba822, 0x3670112c, 0xeb6b9d2a, + 0xc0df6856, 0x020f19d1 }, + { 0xa4dbba20, 0x37051a86, 0xdb1de5c5, 0xb618ebc6, 0xe6525840, + 0x9a780a19, 0xd2bccc4d, 0x9440302d, 0x10285a24, 0xe9ff023d, + 0x3a486268, 0x3b937ee3, 0x4cd61147, 0xe37ee2f2, 0xa3d057cf, + 0x79fbbfd3, 0xccddefce, 0x5fba16d3, 0x5b231727, 0x916058ec, + 0x720c3adb, 0x47699ebe, 0x8b4f6bba, 0x26274386, 0xf18a0770, + 0x54b0092a, 0xacca1160, 0x99d090eb, 0x0c888f60, 0xf757e1ff, + 0xb0050544, 0x79e72720 }, + { 0x2820a239, 0x632acf25, 0xaae6b310, 0xb1a3974e, 0x48c0a1df, + 0xd61fd6ba, 0x5a3ee7aa, 0xd2453c39, 0xb980446d, 0x548455a0, + 0xde16676f, 0x9f29d97b, 0x789375a1, 0xf252ca0c, 0x7743a985, + 0xe961af3e, 0x66cdbd8d, 0x70c79c56, 0xcbc538f9, 0x14a3854e, + 0xa126851c, 0x58daa73a, 0x2a9f558c, 0xe9b5bb45, 0xfbd15e05, + 0x37af7f83, 0x38a1939d, 0xa4487927, 0x9511a056, 0xe428b2b5, + 0x7015846d, 0x001d3ce3 }, + { 0xe145b1d7, 0xd6be36b9, 0x009c5664, 0xf3e3938a, 0xe7c0f6db, + 0x2e562e7d, 0xc343f539, 0x951044e6, 0xd90897b1, 0xa5ab62b8, + 0x512f797c, 0xb1a1f70b, 0x750f28e4, 0x91cdd754, 0xffb8165d, + 0xb4c80e2f, 0x594d02b3, 0x65ed39c7, 0x56833edc, 0xcc12a49d, + 0xf3693a18, 0xe73694bc, 0xfcd2c404, 0x34cc134a, 0x11d40194, + 0x071bd5fc, 0xfc585e46, 0x05759047, 0x790b7a04, 0xb3280360, + 0x40afc684, 0x4bb8c6fc }, + { 0xfd0f8796, 0x3120e2dd, 0xb133c9de, 0x6968a40d, 0xa9369c6e, + 0xfea366c0, 0x6007273b, 0x37e5b6d6, 0x8cb81439, 0x39e4ecf0, + 0x9febc005, 0x487fe9cd, 0x0199b53c, 0xeb8af444, 0x293519eb, + 0x2f124e3b, 0xc82c9c16, 0x860c218a, 0x709dc590, 0xacd1d6f2, + 0x36d50529, 0x5696d545, 0x59120bfc, 0xc03f5df9, 0x10ffa690, + 0x99a3e88d, 0x6c432827, 0xd4f9cfa5, 0x9a135d89, 0x2e8fea9e, + 0xb6a77e78, 0x3699a881 }, + { 0x1eb1c64d, 0x5bca3372, 0xf1d28154, 0xe9cf3a2d, 0x6537106f, + 0xb7e2e9b3, 0x4f7cbf4d, 0x06c17151, 0x2058b37f, 0xcbde416e, + 0x8834e9c5, 0x82c53a7e, 0xe9ac3a75, 0x94dbdfe2, 0xc5e67c02, + 0x795ec6cb, 0x1426a80d, 0x8c23c25f, 0x6a8d4f9f, 0xee2cd20d, + 0xd3b7c235, 0x838daa54, 0x3d7a4d52, 0xb9e08ec0, 0x781cb473, + 0xca9475e9, 0x5ec31caa, 0x7271f39e, 0x82535187, 0x1df08e9f, + 0x208aff8b, 0x4f3a4b03 }, + { 0x1ed095f8, 0x0f7b8107, 0xda226d4e, 0x23e37fa6, 0xafb36d1d, + 0x8b0f9852, 0x07d8e311, 0xb114634e, 0xe3e0f16e, 0xb9634a97, + 0x421eec37, 0x2454bb9c, 0xd72b21c1, 0xb4ecd5db, 0x6df20d7c, + 0xf9603868, 0xdf86e0a2, 0x9f5359fd, 0x5ac488aa, 0xc43d54fa, + 0xd1049df4, 0x56d714ab, 0xb020607a, 0x13152b3e, 0x7a02325e, + 0x49be1c18, 0x52ae84db, 0x44f24f4a, 0x0b5a7b80, 0x9e525c03, + 0xa6d179fd, 0x6d874446 }, + { 0xbe9a42f5, 0xd29d07aa, 0x3781ccc8, 0x1fd5316c, 0x9dc69ea1, + 0x71a75a6d, 0x88fee91a, 0x4e19e0df, 0xf8d44f12, 0x99c2b4dc, + 0x31ae94e4, 0x05f6df92, 0xcf28ccc2, 0x27fba876, 0xf57f7ceb, + 0x6e1a0f01, 0xf3fd3b74, 0xe03f1f34, 0x42c1d213, 0xa0edc4a7, + 0x7deb8580, 0x5caac270, 0xaf0848bc, 0x0f5d791f, 0x07ac759d, + 0x17f514ad, 0x904fc531, 0x95a39734, 0x7bb70f3d, 0x95a4aca9, + 0xff9c5609, 0x3cf384c9 }, + { 0xce1fc9e3, 0x700506ba, 0x676b0399, 0x49721742, 0xe72bf7b3, + 0x2b4a1b8d, 0x79b209f7, 0xca8602a8, 0xce26a8e1, 0x90580b90, + 0xfe24f39a, 0x1ef339b7, 0x629362e1, 0xb6c5d991, 0x577b24f4, + 0x51174e1a, 0x05e451e9, 0xf380fcb5, 0x148321bd, 0xf4d97afb, + 0x747e5d2a, 0x099806bb, 0xbe99a608, 0x85525d65, 0xd455e820, + 0x264828d9, 0xd8560a65, 0x8c8c5405, 0x71030770, 0x3c67e73c, + 0xee73df26, 0x2b248850 }, + { 0x8541159f, 0x2173cde6, 0x4fb410b2, 0x78224c18, 0x1f2ca1c7, + 0x07a28619, 0xa8b23e40, 0x52c207d6, 0xa6b2344a, 0x071a0210, + 0xb5ed2945, 0xdb0e587c, 0x810fcc6c, 0x6c56b8ef, 0x62d843b9, + 0x1248c58f, 0x74c66975, 0x4b90363d, 0xe66c66f6, 0x6348f7f2, + 0xc126bcbe, 0xb2f9d441, 0x73ce49e8, 0xac07f2a3, 0xe81b0df0, + 0x52486758, 0x1d4621d1, 0xa108b54d, 0x74414a1c, 0x17261ece, + 0x6a3ac215, 0x938b3bcc }, + { 0xe4ded340, 0xa9e4a16b, 0x80e88036, 0x8e65fb2a, 0xdcd73acb, + 0x97089606, 0xaaa657a9, 0x1c3a0434, 0x49101b06, 0xf304fc58, + 0xda0bb64c, 0xe60fb61a, 0xf5542df5, 0x818c2aec, 0x56f76d5f, + 0x74020576, 0x92533d97, 0xb566b790, 0x74d6eb5f, 0xae4655e5, + 0xa55b44b7, 0x60f7a1b5, 0x93747ea5, 0x7970179b, 0xf2dace56, + 0x8ae7e0e8, 0x84e83c06, 0x98474607, 0x15307341, 0x24e8c9ed, + 0xd9e89d6b, 0x6cff58a5 }, + { 0x03e51f68, 0x508c01b0, 0x1d2fe7d6, 0xe1d1f225, 0x09bd8805, + 0xf7998d0b, 0x03e415b7, 0x255e907a, 0x607d9798, 0xd148467d, + 0x9b453896, 0x055c3b1e, 0x809f50f4, 0x35001013, 0xd0233fdc, + 0xfbbb2fa6, 0xff1820b8, 0x0b680b0a, 0x38d317e0, 0xb1d404dc, + 0xccc8c7df, 0x133d5444, 0x6ec13f84, 0x7fa847e6, 0x046e2e48, + 0xc33f83d8, 0x4863b3ac, 0x3c627fc5, 0xeb936af7, 0x5f67f8aa, + 0x31b79327, 0x5fe4ac8f }, + { 0x8b6f401e, 0x581aa4bf, 0xad5c7ed4, 0x05db12a3, 0x6fb07b4a, + 0x7b018726, 0x9c22bcd4, 0xfdd11f04, 0x69371c95, 0x5454a7d4, + 0x99a46eaf, 0x066c55fb, 0x7fef96d0, 0x18637c7c, 0x6b83e95c, + 0xbafc1d34, 0x00bb42dc, 0x55c38593, 0x34e7e712, 0xdd8dec2b, + 0xb184cee8, 0x69c9cfb0, 0x49a27864, 0x8dcc0c42, 0x2010f2e7, + 0x290d95f2, 0x6977a420, 0x86e254c9, 0xeb2abdad, 0x20931c89, + 0x121c0548, 0x81377164 }, + { 0x9c5a8edf, 0x6266b25e, 0x1078a7ad, 0x6e1388c2, 0x4876eedf, + 0x5f02737d, 0x62744617, 0x242fa7f9, 0xb385382a, 0x3e2cfbd9, + 0x02f71bef, 0xbadad7b1, 0x677d0a92, 0x562abcfa, 0x51fdff34, + 0x573ebd17, 0x7c250c78, 0xd7f65852, 0xc47ca896, 0xe0cf16ee, + 0x67622c9e, 0x8ccd79b0, 0xf8f2c075, 0x31fc5882, 0xa6008515, + 0x9232b37e, 0x82e8c5ba, 0x4d7bb361, 0xd2f146fe, 0xbf24735c, + 0x9cd2db98, 0x79c280ee }, + { 0xf2b48122, 0xbdcc8203, 0xb04ac48e, 0xa8c04916, 0x9fc4885e, + 0xacf064dc, 0x82c1001c, 0xab838997, 0x676de250, 0x7339e721, + 0x8e1ab820, 0x17aa5aea, 0x6bc14b2e, 0x24d28ca0, 0x816b6230, + 0x570c5bb7, 0xcee6b606, 0x6c51235c, 0x183eae42, 0x1b2bf89f, + 0x9c66274b, 0x3e3af3c6, 0xb51e38bc, 0xe0b04426, 0x73e40e3b, + 0x26dbc58e, 0xb5be5be4, 0x3f9dd578, 0x52c8f408, 0x9fd9f791, + 0xa9e3ff4f, 0x758073a4 }, + { 0x8691ca22, 0x7d27b057, 0x13a2a1b6, 0xf206bfd6, 0xac795413, + 0xe84bd385, 0x75536607, 0xc5d18a2a, 0xc8a0e24c, 0x2e166de7, + 0x3c474dbd, 0x56d5750c, 0x1366843a, 0xdef444c1, 0xcf4b8432, + 0x14646e53, 0xa9fd9783, 0x4bc0d030, 0x297ee203, 0xbda4c824, + 0xfd7be6c7, 0x3d0b10bf, 0x08c7f3ff, 0x2d216476, 0xb4fd4c45, + 0x06e52599, 0x49e9e104, 0xfbab9fa1, 0x8661d32d, 0x9342a7fa, + 0xfaf66aa8, 0x3f3e3458 }, + { 0x951597aa, 0x51ec35af, 0x49df64eb, 0xb677d4ac, 0x9bf4eff5, + 0x0276cd9c, 0x515a2935, 0x423eca49, 0xfd9bb9c3, 0x8a696553, + 0xede1f09c, 0xf99ee9df, 0x199e5f98, 0xb8fa2956, 0x35292c32, + 0xb7638758, 0xfc40e81b, 0x8734eddc, 0x65457d95, 0xd82d5e9f, + 0x30c78d2b, 0xc8ee323e, 0xc1433d67, 0xe77b2e4c, 0x3c8314ae, + 0x56d9f807, 0x2a0e2f63, 0x441eede2, 0x6c48295e, 0x1e9e17ed, + 0x34c294ef, 0x640d20c4 }, + { 0x3284d513, 0x4e9a0b8e, 0xf315053a, 0x074c3545, 0x45acd52a, + 0xb36e7407, 0x1de50db7, 0xd80bdcfc, 0x2549fc46, 0x8d9d47dc, + 0x303f07a8, 0x29b6ef13, 0x6d4ad4c2, 0x4e461aca, 0xfc9f1b73, + 0xca8e351d, 0x57460e65, 0x8bc4094d, 0x0f32d367, 0xb6302b33, + 0x285742e8, 0x69a074b6, 0x876c29c3, 0xdfe52b11, 0x912bd17a, + 0xf39e4609, 0x349aa639, 0x8ee40d66, 0xc72e05c1, 0xb968902a, + 0xc0d92816, 0x0f9c1ca8 }, + { 0x67433df3, 0x1ebbaab3, 0x15d3628c, 0xb6aa5347, 0x97f0c5cc, + 0x13a320d8, 0x65e408f9, 0x72c918cb, 0xd5373451, 0x4b638854, + 0x0b4dca09, 0x731399a3, 0x0a3b1326, 0xcf256730, 0x6608b388, + 0x5ea60dfa, 0x7b290dfd, 0x58ad74b0, 0xd7694f9b, 0x83202789, + 0xb6630fb1, 0x48593db8, 0xc65e3eaf, 0x3db47f70, 0x3e7263f8, + 0x63949c91, 0xe6e6ff33, 0x9b9acec6, 0x098a8240, 0x34bd9ba7, + 0x45d36ec5, 0x7e31c12f }, + { 0x0dfd2dd7, 0xbe281d68, 0x24ab61d8, 0x1efacb00, 0x94431f97, + 0xb9c3005f, 0x959cb3bc, 0x660c8dfa, 0xcffbb406, 0xfdd5fc30, + 0x7969a10d, 0x7a4631be, 0xde13fd1b, 0x336e309e, 0xfc947076, + 0x76b3bfad, 0xdcc72223, 0xfa91925d, 0x156c4ee1, 0x741f0d73, + 0x0e2b3747, 0x4f64ee41, 0xefc4d93c, 0x86be92d3, 0xfc4fbb2e, + 0xc53b7e03, 0x337ca1bb, 0xac196cf5, 0x7e23ba60, 0x4de41a30, + 0x326d5357, 0x1a219c45 }, + { 0xaa4db0bc, 0xfdcf7ef8, 0x7b6c9963, 0x2e231806, 0x3d8a192f, + 0xc2639067, 0xffdc7771, 0xc0cec2e2, 0xa2fc0edb, 0x997c8e35, + 0x82cc6043, 0x78e10ec1, 0x2b0c8120, 0xfd0de2cb, 0x69e57f8e, + 0x4d6c457f, 0x5b53f1c3, 0x953e69b2, 0xc4f89cb8, 0x422a330a, + 0x95566be6, 0x92ff2329, 0x437442d1, 0x73cd502d, 0xbea69403, + 0xf04ce590, 0xf8030662, 0x6ac1537e, 0xb6d0bf93, 0xe02bcf77, + 0xbc90192f, 0x17aaa999 }, + { 0x8e55db2e, 0x0d3d5643, 0x3b946851, 0x835dee43, 0x5b88462f, + 0x1a1440e5, 0xea17e27c, 0xa6ff3b35, 0xdd95f7a9, 0x23f99c36, + 0xbdd672cf, 0x7217fdd9, 0xdd2045c0, 0xf400ac1e, 0x4ff06b25, + 0x94b55c87, 0x0e4a49be, 0x0a44a0e5, 0xb43b6813, 0xe8925e91, + 0x214f96c5, 0x78bedde1, 0x0f97fa97, 0x0f456a4c, 0xa5bfd267, + 0xa28fd86b, 0xbe7608ef, 0x3b4b2d8f, 0x226474bc, 0xfbd5ff8c, + 0xa5f3b24a, 0x6b282af0 }, + { 0x6341a595, 0x78fc025f, 0xa445e28c, 0x591c38d6, 0xeb446842, + 0x72bd6e3d, 0x75547833, 0x3f9466d3, 0x083e16c4, 0x911414d3, + 0x95a7acb4, 0x145d9466, 0x8fd2fb64, 0x102ddf09, 0x0bfd87b1, + 0x2a2b2d2d, 0x59455088, 0x69e9be5c, 0xa80245de, 0xee378bf4, + 0xb2306b0e, 0x80b0bd68, 0xc2be9f3d, 0x76a545c6, 0x4802c245, + 0x429d167b, 0x2b412dfb, 0x13e64427, 0xee8d9762, 0xb664f529, + 0x54706ebf, 0x6d4f5d23 }, + { 0x00ba9f88, 0x35c8f2b6, 0x7bb6d0bf, 0xfdc807e0, 0xb3b81e5b, + 0x0a126d42, 0xa7ac781e, 0x335ce6ce, 0xf37dcba6, 0x3e308e6f, + 0x63c96487, 0x028dca62, 0x8818434d, 0x72eba57e, 0x79b78a26, + 0xa9e3d59f, 0x2f07aea3, 0xd2f0a7dd, 0x24d05f74, 0xe0fe4678, + 0x0116deb6, 0xb2085170, 0x58f37580, 0x9c2a5e92, 0x74070bb3, + 0xe78bd7a5, 0xb9977d90, 0x551fc872, 0x40db81b4, 0x6eda93c4, + 0xd65d34ad, 0x4aaf0b4f }, + { 0x3514c7af, 0x9bef2506, 0xbc181ead, 0xb09e7dad, 0x8fa3ec58, + 0xef3cae87, 0x173b8685, 0xd8dbfab5, 0x921d32dd, 0xb2490fc0, + 0x8bd9c466, 0x4eef386b, 0xa061dbdb, 0xc1cdd52f, 0x25bc04db, + 0x64de989a, 0x85728636, 0x06f9836b, 0x8be44aa0, 0x11a5a804, + 0x097018c7, 0x16dede4e, 0xb2c11fb1, 0x72aec577, 0xa721ecd9, + 0x144dade1, 0xd6ebf3a9, 0xf99c526b, 0x1c2e14d7, 0xa1d4165b, + 0x82bc6337, 0x8b2cbd39 }, + { 0x8a52e991, 0x28ec1bf2, 0xcf9d42ec, 0x0ba202f6, 0xc634ea45, + 0x8307d130, 0xc5762b9c, 0x3fc257b3, 0x487c2a2d, 0xbd3298d1, + 0xa319488a, 0xca14f1a7, 0x06ba06d2, 0xc70ca93b, 0xee405e89, + 0x9aa3f4b3, 0x35deeae7, 0xcc64eeb3, 0x03bf1d4c, 0xd155f578, + 0x45616bfd, 0x041ec0b5, 0x086e33f6, 0x23df80e6, 0xf0243cf5, + 0x399a79c8, 0x874ccd58, 0x86c2824e, 0x8fc5c831, 0x220eeaec, + 0x7dbe3670, 0x57e28304 }, + { 0xfbcdf666, 0x6e60b698, 0x8bebb1d2, 0xbdd06a99, 0x80498436, + 0x4044adba, 0x522bc88d, 0xd76bf75e, 0x28423b20, 0x655c4b9b, + 0x53398a72, 0x65c0f492, 0x0ca37601, 0x76d4f2b7, 0x2030fa5a, + 0x46989925, 0xb6054705, 0x96b37e87, 0x53de1b2f, 0xef96f731, + 0xad54ef05, 0x5ecbbc8c, 0xa93617b0, 0xeb289d0a, 0x7cba217d, + 0x3ac0fbd5, 0x19d4a2d7, 0xd0d3cb56, 0xc91d6063, 0xe8bee9d4, + 0x696ffda6, 0x4f12e037 }, + { 0x15f1a610, 0x4ccfa422, 0x3786519a, 0x804a5c55, 0x73838134, + 0x1246a454, 0x4b284e2a, 0xfa15b484, 0x146d1320, 0x36464c65, + 0x70a8a0fa, 0xfb6ba88c, 0x93c4804e, 0x74e7cee7, 0xb95ae16a, + 0x8c34d22c, 0xf9c1d4dd, 0x9d9ed89f, 0x32025371, 0x61a0866d, + 0x9bd6444a, 0x45b232b2, 0xf277bab1, 0xf888e92c, 0xa9448b02, + 0x73e69c6e, 0x5b521ecb, 0x1a496ea9, 0x5858afb2, 0xa8f78ea7, + 0xb1266f91, 0x83d2333e }, + { 0x67b478d7, 0x1c633288, 0x50a2fc9c, 0xa1ee1ae1, 0x18d2241b, + 0x05b6ab30, 0x893cd696, 0x69f1f288, 0xa8117a87, 0x159d6660, + 0x70e73d77, 0xe8120119, 0x93f55f0a, 0x528fef00, 0xd854dfb2, + 0xb3978db8, 0xf45d9fbb, 0xd6b43ef6, 0xd5bee397, 0x17de4bfe, + 0x6bf76dad, 0xa01e0f59, 0x3d40754c, 0x28b2280e, 0xf8e86ef3, + 0x8edb6122, 0xb7d1e586, 0x8226b6af, 0x2f40a55b, 0x46353215, + 0xc5a31621, 0x7362f13e }, + { 0x73c0c430, 0x792eb27c, 0xa51c3657, 0x8cc0a65f, 0xd2194f1b, + 0x50a5cece, 0x814b4947, 0x18945688, 0x4b6fbbf4, 0xbbf0a81a, + 0xf0aa8608, 0x376f4f58, 0x3987795e, 0xd9361d68, 0xe3a8d0d5, + 0xb6510cd8, 0xb6c1a455, 0x63e2fdbf, 0xaec891f9, 0x2c91154e, + 0xff568f64, 0x0eb1e715, 0x2f2b399e, 0xe7af9cd7, 0x89f0bf0b, + 0x1fc39bac, 0x90983695, 0xf0861d92, 0xda0a20a8, 0xd9b16f02, + 0xa38c0ead, 0x2f10693f }, + { 0x0c06ded2, 0x07a6ce91, 0x2fd9087b, 0xf974842f, 0xa9f635a6, + 0xe468bfd6, 0x1ed60626, 0x04b61891, 0x369ee548, 0x1fb2f89f, + 0xdc96a201, 0x9cbd1113, 0x10d633ac, 0x6759acfe, 0x8faa629e, + 0x64ba66fc, 0x47f38283, 0xa686ae49, 0xd59cda99, 0x828c3a05, + 0x08ea2f6e, 0x7c7afb14, 0xaf3953c8, 0x2551c8e4, 0x9daa9e4f, + 0x5b53d279, 0xad6f1940, 0x1eff68d4, 0x96437cdb, 0x2775dbdd, + 0x4fe7a043, 0x985f83e4 }, + { 0xeaf45294, 0x89603c16, 0xc24b5751, 0x70131160, 0x39d6b52d, + 0x4c112018, 0xed943340, 0x7079cf02, 0x74f41b68, 0x0c5b028b, + 0x9c8ac1e1, 0x3dc3f076, 0xf8b24f0e, 0x5ac5eea3, 0xe34c5c22, + 0xee6684ba, 0x9abc452a, 0xa5259e63, 0xe9df45cc, 0xb07d2cd1, + 0x1a443cfa, 0x07019c93, 0x92c003b3, 0x68fddaa9, 0x0d8cbc2e, + 0x2d9f179c, 0x1e781ca7, 0xbbf15a6f, 0x50dcc799, 0x54d779d5, + 0x0fe962f1, 0x0c88e540 }, + { 0xe8f44357, 0x84f71a6a, 0x3a3cab6a, 0xf75b4bf6, 0x5aebc680, + 0x334c9d9e, 0x8a753ef2, 0xcecaf084, 0x075e3c8e, 0xe28014c1, + 0xf74f8d3a, 0xbb9d5a38, 0xb80e32ae, 0x75988464, 0xf2bc3792, + 0x7b328e6f, 0xeed0e197, 0xebbb1faf, 0x5a33065a, 0x674eac95, + 0x922dbce8, 0x8c19fd8f, 0x987b907a, 0x8c17ae85, 0x3b3a2cd7, + 0x89f33627, 0xfa87772f, 0xebaea019, 0x3a25ced6, 0x4e5de499, + 0xaf110715, 0x8e2560b8 }, + { 0x3141aba6, 0x56d3746c, 0xbab2cf9e, 0x45a1079f, 0x9cdd27c7, + 0xb6382831, 0x9dfd950e, 0x22237632, 0x3a9408ff, 0x1e0b15cd, + 0xb1160118, 0x49a80200, 0xa383bba7, 0x2719db5d, 0x651046d5, + 0x6078340a, 0x97523b1f, 0x8929d4de, 0x8e0a28ab, 0x4040345c, + 0x0adf09c7, 0x61275ac2, 0x2331d611, 0xb41ab265, 0x5391ca50, + 0x230cc77c, 0x8f922315, 0x88be0c92, 0x92fd9a29, 0xfef3d92b, + 0x8324f2e5, 0x59005f22 }, + { 0x3c4c1c74, 0x6bb1750c, 0xe966fb79, 0xbe73aac0, 0x66c5973f, + 0x85a75d92, 0x3a8656b6, 0x8c97f932, 0x50446cde, 0x2b7043b1, + 0x3ff3897f, 0x548916f7, 0xb18b72b2, 0x913dd01c, 0x488c0de6, + 0xd0a751f1, 0x8558ca58, 0x19175714, 0x44a663da, 0x97714301, + 0xb0e08618, 0x2df190ac, 0xf39ead9c, 0x0080fc0c, 0x17382da1, + 0x0085ac6e, 0x3262a338, 0xe9791851, 0xb43bae8d, 0xe4495936, + 0xd783df6e, 0x57a78e26 }, + { 0x40dbddd8, 0x161b346f, 0x9410c3ac, 0x2b49a927, 0x1886cf3b, + 0x8c542783, 0x33b93deb, 0x72df3232, 0x40df579d, 0x9c8d59f5, + 0xc20ef500, 0xe5d7a67d, 0x67f08643, 0xc46b3918, 0xad96adc3, + 0xecfa2445, 0x0c4544d0, 0x658f589b, 0xe08417d7, 0xe6ec9301, + 0xc454e288, 0x6ca5ef6a, 0xac0f462d, 0x4191048f, 0x08d8a036, + 0x852407d8, 0xf6d35b7e, 0xb4c533a7, 0x8f6ada87, 0x3251e412, + 0x81c472e8, 0x1ca370c5 }, + { 0xa801b68a, 0x94bd5171, 0xfd1998b3, 0x7312879c, 0x41163202, + 0x4905aabf, 0xf5b01fdb, 0xb5fe87f4, 0x9cda128b, 0x78de523a, + 0xc7bd31f7, 0x0bf161a1, 0x23904c35, 0xb5decfd0, 0xe188f12d, + 0x224b2882, 0xf99dae74, 0x0dd2801d, 0x08cd1cd2, 0xcad467b5, + 0xc0867e39, 0x6c311c3d, 0x2b425072, 0x71a11720, 0x2efd9003, + 0x83bf464e, 0x1dbd3b03, 0x53d0448a, 0xe6265baa, 0x32db52f4, + 0x4c33ac79, 0x2584b34c }, + { 0x2aeec688, 0x3cb86389, 0x45fbe523, 0xa5e740ba, 0xfd60b5f8, + 0x422e71f7, 0x4874913d, 0x455d185c, 0xfa17d80d, 0x04c2bb36, + 0xac054524, 0x3f271854, 0xa8b9a657, 0x76dd3045, 0x62ee7cc8, + 0x2e42c3e1, 0x4df6c7d0, 0x00266706, 0xdc7cb488, 0x5927dd51, + 0x187897e0, 0x6b3faabe, 0xf2d5737c, 0xfe6ad22e, 0xff51a9ff, + 0xafb60269, 0x69807baa, 0xe1c83545, 0x951ca49a, 0xacddb6ff, + 0x3f9ab085, 0x7e811374 }, + { 0x830a88b1, 0xad722a8b, 0xce1117e1, 0x91918ea8, 0x0409b47d, + 0x3e02d0b8, 0x6c46d1d3, 0xb53812d3, 0xe589669c, 0x2fd09db0, + 0x15b0cd5e, 0x9845cd06, 0x2386c453, 0x0c1c155a, 0xf5ff43cb, + 0xda774de5, 0xe391c0cd, 0xbb076b98, 0x5004f286, 0x97d71eff, + 0xaeec0bfe, 0x23e0b46c, 0x32a1ad94, 0xe4538667, 0x396da422, + 0xfe0c9f81, 0x63db2bfe, 0x6376c1a2, 0xba56fa91, 0x001c7918, + 0xdf8485a6, 0x436b8c64 }, + { 0x8ab764bc, 0x88117e9d, 0xa077df84, 0xdfa61e94, 0x0c18eebd, + 0x5a7765d3, 0xfc9451dc, 0x548916af, 0x071a347a, 0x01a52e33, + 0xb23b41df, 0x633b95de, 0x43c8c286, 0xdd7d68c9, 0x18d97068, + 0xe4f9d41e, 0x8c92799d, 0x79908b90, 0xd47394a3, 0xe614148e, + 0xcd51e53f, 0xe5018517, 0x0243dcb6, 0x5060075e, 0x17954405, + 0xe5dcde62, 0x537da5ff, 0x6f7c90e1, 0x0768cb66, 0x1df7aae4, + 0x6dbe95e1, 0x5266ca9e }, + { 0x1386b3db, 0x84ddee6d, 0x7c38e540, 0xf9e4af5a, 0xeb04f49d, + 0xb3418440, 0xfde5a4fd, 0x2138a1e8, 0x30257cfc, 0x3e6e6924, + 0x19fd70c1, 0x3519c6e3, 0x86c31ff0, 0x8f34e174, 0x940ce1e8, + 0xf1e298fd, 0x14960d7c, 0x6fb8cb1d, 0x2b2f3bff, 0x207c1347, + 0x146ef8ff, 0x899a20b4, 0x7bd3e220, 0x7dec362b, 0x626bea27, + 0xa975044e, 0x4fb4cb67, 0x0f32b449, 0x1fc6703a, 0xc17a0920, + 0x9cd84a2b, 0x41f325b9 }, + { 0xce2843a4, 0x312ed513, 0x00728afc, 0xe748498e, 0x4d864ce5, + 0xa8ef2822, 0xa620083b, 0x34064704, 0x4bed338d, 0x5905e1d9, + 0x063e7b38, 0x2a578cb5, 0x289e7bb9, 0x98276d96, 0xf17b7341, + 0xdfe2dc47, 0x1dac8944, 0x5923521f, 0x23400aa7, 0x3db6d28d, + 0xa761ba43, 0xc647705e, 0x9bfd07dd, 0x8947ba6d, 0x242ca8fd, + 0x00f2e3ac, 0xeb8c3468, 0x49ef4670, 0xd9aa18fd, 0x7db3d37b, + 0xe58cea9e, 0x56b30fb6 }, + { 0xcd80a428, 0x07ecdcaa, 0x8732c891, 0x7af922dc, 0x3ada441f, + 0x20d88798, 0x924b008a, 0x3bed9a44, 0xb2e81c3a, 0x2123533c, + 0x65f807d3, 0xc34e4075, 0x1f2faecb, 0x0bfaefa5, 0xade8a88d, + 0x78b634a5, 0x94392a91, 0xc4e0b7f8, 0x90bb1cd8, 0x30922377, + 0xf87204ae, 0xdea9b4fa, 0x85d3cd83, 0x3edf81f5, 0xc6523a79, + 0x58f88c51, 0x17c0d969, 0xe472fb8b, 0xdccf7f07, 0x899081e5, + 0x58bdd146, 0x1353cc57 }, + { 0x39bf6e18, 0x28a56497, 0x649b89c7, 0x59e8b5a2, 0xdce8b8e7, + 0x8d9434a0, 0x2047040c, 0xd935bf51, 0x6a7b8e82, 0x2ab3a164, + 0x27f81294, 0xf1583ed6, 0x72d67297, 0x8416a7e0, 0xcd39e42b, + 0x49685d86, 0x958ddbad, 0x8a797fc7, 0x155ce6de, 0xa558f928, + 0xf8a36235, 0x75f4e570, 0x52877ae5, 0xbc69cfc0, 0xa6b16ebd, + 0x8f4193a9, 0xbb1cc1f1, 0x8d1df43c, 0x5a21e789, 0x723a830e, + 0xf451df58, 0x3ec2185d }, + { 0x1f0bc2d7, 0xb9d4c7d7, 0x6e51d412, 0x6982c6cc, 0xa09f80f6, + 0x92e02d93, 0x047ae09c, 0xb7dd2d25, 0x37f351f9, 0x3503149f, + 0xc77850be, 0x69d49ce1, 0x12f0d2c8, 0x60242acb, 0x7bc28b9d, + 0xba188c56, 0x06bc0550, 0x8e406121, 0x8d7d4329, 0xb0d84b1f, + 0xd38951e0, 0xb4a67ae7, 0x8bc97607, 0xb527c57b, 0x5497aa72, + 0xbc93c5f3, 0x39bdd666, 0x5f1de8cc, 0xe9d447a3, 0x3087dc5c, + 0xa211abe5, 0x89b356b6 }, + { 0xdfdcc837, 0xed6db0af, 0xa871b7a9, 0x0fb80baa, 0x1c1d4b72, + 0x413abfc9, 0xadac9e5c, 0xf5b56bf7, 0x8b8657a3, 0x5664a2da, + 0x0e41d94e, 0x11b04f72, 0x37433658, 0x63e11d26, 0xf426daea, + 0xee628ece, 0xcb162dc2, 0x011619c9, 0x87648643, 0x9cf5817f, + 0x5584bc86, 0xe1bb9702, 0x00bf7928, 0x2cc27cef, 0xdc60eee5, + 0x4ef3a80e, 0x87adc2f9, 0x7e1202be, 0x8a0d4f52, 0x656f18e0, + 0x57c5d126, 0x39c4f10d }, + { 0xe88aecd3, 0xb3a9b68c, 0xa518aa9d, 0x555b0918, 0x4bd4ee54, + 0xedc1cdad, 0x02068d84, 0x79b68b67, 0x811ac72d, 0x7dac80d0, + 0xa81a0a78, 0x6d1e6d35, 0x3bd16283, 0xc841e9ea, 0x894c4444, + 0xa7bc1775, 0xf1aa1202, 0xf2b63725, 0xc7d4c556, 0xbec7767e, + 0xd46ff51b, 0x2817ebb3, 0x73f7e339, 0xfde5be8d, 0x5aed24c4, + 0x44c6c977, 0xb6e579cf, 0x0b9a1707, 0x9069fbcc, 0xcff16478, + 0x49152b00, 0x414b542d }, + { 0x606e173b, 0x33c31e58, 0x90e6713a, 0x5b7f4e1b, 0xdebb20af, + 0x425fb512, 0x05120e70, 0xc788c617, 0x9013e4ec, 0x3ef05602, + 0x81c6e6d7, 0x9f9d35ac, 0x9450690a, 0xe131e88f, 0x44af082e, + 0x708f9b32, 0x1ba2aea9, 0xb2e4d66c, 0x740db29c, 0xaf1f4a6e, + 0xd1843007, 0x74ab9248, 0xed556a6c, 0x13338ef8, 0x270d17a6, + 0xf48e623e, 0x9608f5bf, 0x3c7362fa, 0x444e8515, 0x43977874, + 0xe00b8b2a, 0x52678d6a }, + { 0xdf36aeb4, 0x5dff1c59, 0xa92bc0ab, 0x52d6653c, 0x927a5f81, + 0x0e03f496, 0x2dfd491f, 0x8509d414, 0xa571f89b, 0x258c2c52, + 0x93334485, 0x2bd61804, 0x3f7d9e09, 0x1a33e94f, 0x2c1bf906, + 0xfab418d3, 0x5aa5695c, 0xf39c490e, 0xf6d2d7ff, 0x0e41196e, + 0x0f7948a9, 0x3ecd4075, 0xd3053b4f, 0x4b58f9b2, 0x5d9974c9, + 0xb8ee842a, 0xbf22f682, 0x23a59c1d, 0xc8efcea6, 0x045ac614, + 0xc10ceedd, 0x7040ba5b }, + { 0x515a1a96, 0x2c364f81, 0x184327e0, 0x31a63503, 0x1ad93d4f, + 0x0a096650, 0x273b6173, 0x9d7694f1, 0xd2cda9d2, 0x8886d876, + 0x2814c177, 0x1e01a742, 0x8667696b, 0x3492276b, 0x5b25f006, + 0x2fd4f0c6, 0xfb294c4a, 0x6527349f, 0xde1d336f, 0xc1fe0d8a, + 0xe7e3860e, 0xaf9a23e8, 0xb774c31e, 0x97d2b721, 0x4365784a, + 0xfac3e582, 0x70f4eaa3, 0xff2dff4e, 0xfe873248, 0x3d281e1a, + 0x0bd1c9c1, 0x9043a6d6 }, + { 0x766c7937, 0x1511a0fe, 0xabbc3be3, 0x1b2ded5c, 0xe00888ac, + 0x2ac160cc, 0x616200f3, 0x928754bd, 0x34a2ea06, 0xb801c83d, + 0x9cbe106f, 0x8ad7a03a, 0xcedfcd94, 0x996b0822, 0xe4069880, + 0xc3c3463a, 0xf597f663, 0xfb12ea4d, 0x40c92af9, 0x2c8d3834, + 0x4e8da154, 0x79bc85c6, 0xdb4e801a, 0x95771fa2, 0x1e3579b2, + 0x7bd2c138, 0xffaad078, 0xe45c75df, 0xb73eac46, 0xb0760a3c, + 0x3a125f35, 0x26362b48 }, + { 0xeefc3e89, 0x25c68d28, 0x69e9ee71, 0x2d0ee877, 0xaf5e4b75, + 0x8b07bb86, 0xcb86b333, 0xdb709072, 0xff552bac, 0xfd3d20ea, + 0x4c0da1e9, 0xa5eeb2b1, 0x44f97145, 0x391f688a, 0x1e06d485, + 0x21fbd310, 0xbea9cd49, 0x45e4f2a5, 0xa7bf21da, 0x7b60d464, + 0x054d5471, 0x193f88c8, 0xbee0f2e9, 0x5ace53d1, 0xc1439273, + 0x92c26563, 0x96c6b5ee, 0x9c86e0b2, 0x09ff59ba, 0x452fe231, + 0x555c935e, 0x2e952b20 }, + { 0xd75f886e, 0x2a846bca, 0xd43dfc58, 0xe68a5dbe, 0x007b1b86, + 0x103e45b6, 0x355ff2b5, 0x580e2ec9, 0xa263ecc9, 0xbc702f26, + 0x181e5e33, 0x2835b386, 0x6c122076, 0x025113ec, 0x7fbd856d, + 0xa5c26e3a, 0x9d6ebcb1, 0x8ef83fb3, 0xa44d2fa8, 0x7aaa53f2, + 0x53b1fa97, 0x7c14ef33, 0x17559a30, 0xff604a11, 0xb09377e0, + 0x2bcd96b0, 0xdb2f0273, 0xa5c14896, 0xeb53ef06, 0x1c0a84c9, + 0x30378e4b, 0x1236d017 }, + { 0xc084373b, 0xd7481c8f, 0x646097ae, 0x29ae4768, 0x613bc34b, + 0x1300dfa0, 0x934bc2b0, 0x3712714c, 0x0e2be7e2, 0x86524629, + 0xed010800, 0x554fbb9f, 0x42314576, 0xf0ec0b38, 0x330a3282, + 0x65baf594, 0x706ef817, 0x3bdde1a8, 0xba7530e9, 0x7d2c727d, + 0x74cc95cb, 0xbb0c5d66, 0x2438906d, 0xb3fcd365, 0xd14658f3, + 0x19881941, 0x6c97f0e9, 0xe616f555, 0x4b9ec7ea, 0x353c2d85, + 0x620cb56e, 0x02a48014 }, + { 0x506ccd38, 0x11d6d23d, 0x9059baa6, 0x229a1c54, 0x69d011c5, + 0x717c9c27, 0xd828937d, 0xe87e1b46, 0x83835083, 0xf5d63bbb, + 0xaadac258, 0xf0a7b427, 0x9f154d1f, 0x99ab26bd, 0x8ec955fd, + 0xdec0ffbf, 0x49fcb880, 0xee957c67, 0x1e0114de, 0x32395dee, + 0x369f46c7, 0x192a64b7, 0x91eb2599, 0x43044660, 0xa2e8c3da, + 0xbe2da887, 0xc3556d18, 0xa44e2c25, 0xb55f75f3, 0x31390414, + 0x8f217fe0, 0x1d8bde6f }, + { 0xa2028924, 0x03cd39f8, 0xb06ecb9f, 0x6e54f19c, 0xd6f05846, + 0x862bbcb7, 0x5a060776, 0xdbe06716, 0xb10fec10, 0x9397c97a, + 0x6f1bb65c, 0xf4213826, 0xa672ba38, 0x414deccb, 0xf88b05e6, + 0x594d4d43, 0xac94d4d1, 0x7993f57a, 0xbfb17638, 0x74fc2a6a, + 0xb6fc655a, 0xd8196b5b, 0xee8d2139, 0xdc375c84, 0x360d3a26, + 0xb9b00a02, 0xdeb93b87, 0xb36ed35c, 0xcc83209e, 0xf565b28b, + 0xc61013c1, 0x349c6943 }, + { 0x4de6c88a, 0xd1b39444, 0x4700207e, 0xd5c2c471, 0x21c2b780, + 0xb6f458a2, 0x0850993e, 0x749f7564, 0xbaef0c18, 0x400ba579, + 0x737c70f0, 0x2d742938, 0x21467ebf, 0xc5a8e2ec, 0x5337f453, + 0x243a666e, 0xed0bd50a, 0xc991f1c7, 0xf4bd1f91, 0x3a7f3e90, + 0x5f0e129b, 0x96089e8a, 0x07389635, 0xd0d3a177, 0x27182ac9, + 0x9cf842d5, 0x0817c5c2, 0x21195299, 0x87255769, 0xa32f327e, + 0x89c2d8fa, 0x056587ab }, + { 0x1ce4733d, 0x008562ed, 0x98e51444, 0x5faff7cb, 0xa9ab46b9, + 0x5f03021f, 0xb61a8c13, 0x89494c5e, 0x36b35976, 0x57c95036, + 0x2ac2d2f6, 0x6be84c8f, 0x9bd2703e, 0x0e5b34d8, 0x7e872abb, + 0xc4ad918f, 0xc4052ee1, 0xc2a89e9f, 0x3190b51e, 0xc2caee3f, + 0x6fff254f, 0x58fd1437, 0x883e0972, 0x6f3c0d68, 0x0fb15438, + 0x63d0a0e9, 0xf6caae00, 0xc438764b, 0x3f1d0f6c, 0x815f1565, + 0xb86cdbde, 0x1b87f2ed }, + { 0x2b0b15b1, 0x35792bbb, 0xce6ba779, 0xa3e4b5a7, 0xdd8f3779, + 0xfbacffd9, 0xc298d1ef, 0x005450bd, 0xc47031c6, 0x0e3f5556, + 0x95d68066, 0x0770f07a, 0x2d1052c2, 0xce3e84e0, 0x7aa8cc54, + 0xb050791e, 0xba3223a3, 0x4d621e73, 0x39632990, 0x87b9b94d, + 0x7eb8056d, 0x8df9cb47, 0xedfca0cc, 0xe2430de8, 0x9712a0ca, + 0x374bf416, 0x88848a99, 0xbe3f3c77, 0xc4a3e59e, 0xb22b87b1, + 0x3e95bc23, 0x8e0227c4 }, + { 0x3210964d, 0x000e22a8, 0xff056eeb, 0xdccd5df5, 0xdaf1ead7, + 0x02173a1f, 0x67cdcae3, 0xd02833e0, 0x8bdcc90c, 0x1cc574cb, + 0x3224b4f5, 0x86eca714, 0xbb3f8298, 0xd00e603a, 0x0c1a8deb, + 0xb98ece1b, 0x378c261d, 0x228a46e4, 0xa6165e5d, 0xc6f9dd0d, + 0x4b7ef0e2, 0xb3ae3899, 0xbda9f306, 0x3a3c16b3, 0x38a084db, + 0x5e9a26d3, 0x5394e950, 0x528e5993, 0x4ea206bc, 0x848ecb11, + 0x40545d6e, 0x14b15ab5 }, + { 0x664c59a2, 0x0f6d86c9, 0x60fd7aa5, 0x3dfe2be1, 0x9072cb8e, + 0x33f9b569, 0x8176a7e0, 0x5f2325d9, 0x4587080b, 0x79a0d4e7, + 0x0d5d4e05, 0xa4ee0def, 0xc87b28e1, 0xc0ad9ffa, 0x3f09b4ee, + 0xd6f18d2f, 0x292e9d87, 0xcc896ae7, 0x6094763c, 0xca88953d, + 0x18fbf9fa, 0xdbee97a8, 0x4b63d701, 0xdf20e0e9, 0x47ea722f, + 0xcbba6e30, 0x612b571f, 0xce57e1ca, 0x009a55f5, 0x1e16ac76, + 0xc4389e2e, 0x742bbed8 }, + { 0xc1dc2c73, 0x23ea86dc, 0xc1643abf, 0x4bbbfd5b, 0x24d8ca1f, + 0x07f8fa1f, 0x8cb5cac7, 0xde68a6e0, 0x54e66a7d, 0x7d54c64b, + 0xa9b7ad78, 0x789dba22, 0xe364ab94, 0x4d88d540, 0x1f72e011, + 0xc8c2e02d, 0x46e2a278, 0x4c826057, 0x4b187c7d, 0xe6c35bb3, + 0xeb8fe0c9, 0xed8b3dfe, 0x7d11e415, 0xb6bc34e8, 0xb865c7f9, + 0xb3908bbf, 0xe1ecc17c, 0x717d1ce6, 0xf7cdd69b, 0x151e3308, + 0xb5c94124, 0x97bd5a14 }, + { 0x81e82861, 0xe01c62fe, 0xdd42c40e, 0x703d4b6d, 0xe65e91e5, + 0x7e52e55b, 0x5abbbfdd, 0xb8b49374, 0xc72a45f4, 0xb4f15f52, + 0x550f29d8, 0xce8435a8, 0x582de75f, 0x9df76b9b, 0xa20c8b96, + 0x52e84c5f, 0x0a8a0af4, 0xaf77d2d1, 0xca6013c3, 0x0389bbd8, + 0x26f8305f, 0xb0d9b9ba, 0x0cec8b9a, 0xf053e848, 0xffabda18, + 0x4d63367a, 0xa6424c2a, 0x50f53be4, 0x864fba2e, 0xf892c58c, + 0x48cc5469, 0x317c6d31 }, + { 0x2cb7d42b, 0x0c3525b0, 0x310facae, 0x55240bc9, 0xff20408f, + 0x8d5d2022, 0xe0c10ea0, 0x6b01402f, 0x718eb23d, 0x7fbef68a, + 0x41252a19, 0xa0146b5a, 0x110e0d6e, 0x59afce48, 0x022de181, + 0xe9a1d27f, 0xdc3f49da, 0x6db96d16, 0xefbe4008, 0xfc1ae3f5, + 0xeccbc11c, 0xf9d70641, 0x525f8636, 0x49022279, 0xc2763c30, + 0x3769796a, 0x1d90630b, 0x9cc3483c, 0xee3d3f17, 0x451651f0, + 0x9da0b8fd, 0x6ae59739 }, + { 0xbff4d2ee, 0x57b13bc7, 0x30b173d8, 0x20754229, 0x0794936c, + 0xb6254bd5, 0x5efd55be, 0x1d5f232a, 0x4e0c3389, 0xc06f4a85, + 0x8e61f944, 0xcf2c5b59, 0xfd5f87b7, 0xc564861f, 0x5a2afa4c, + 0xee261fb1, 0x2d97a774, 0xb0ff7226, 0xd6cf007a, 0x1a89ae22, + 0xd346f214, 0x28880534, 0x97b6497e, 0x8fe73bff, 0xfa2afffc, + 0x8a8595b2, 0xf151a726, 0x9ef9cf3e, 0xe744b82b, 0xa84ee5f1, + 0xbc63fe72, 0x6649048d }, + { 0x1e8b760d, 0x91b7bb78, 0x25aadaa0, 0xd47b0bd8, 0xfab5226f, + 0x81493d9f, 0xbffc148e, 0x4a6dd226, 0xa29be3db, 0x5a032f8a, + 0x34b0ab0b, 0x318dbc70, 0x7d654868, 0xdcccbfb5, 0x9c581e46, + 0x8506ab37, 0x2830ece2, 0x09136a6e, 0xcf6c80c7, 0x48b79356, + 0xef6b1e86, 0xfa176377, 0x83f0f1c9, 0x2c9c1cc1, 0x16abeddd, + 0x96f0526d, 0xa93b0de4, 0x3e0e98e2, 0x0f13873a, 0x6f2d7ada, + 0xf3fa49ec, 0x4eb93b5c }, + { 0xe11fae32, 0xbd89f7e5, 0xc4023f51, 0xd13d74f5, 0x491c3f6f, + 0x1b0014df, 0x555279b7, 0x1d849a57, 0x05ba0068, 0xbb9e8897, + 0xc13ca2ca, 0x82222419, 0xfd33676f, 0xafbbb685, 0x75878a2a, + 0x931c3f52, 0xef3d5173, 0x12aeefef, 0xbd8a6878, 0x189a5cc8, + 0xd99f0c16, 0x82cffdb3, 0xa19d48b6, 0xbf565406, 0xe9c6c4e0, + 0x5605e223, 0x86804172, 0x53e781de, 0xc7001cc8, 0xcdf5c90b, + 0x7c043f68, 0x2b582d93 }, + { 0x81abc2ae, 0xa1165c82, 0xe2b69eca, 0xa73380f5, 0x07fff66f, + 0xc097b3d2, 0x54776506, 0x5d603826, 0xb57fa21c, 0xdcbac9f3, + 0xc98dbdd5, 0x78750db4, 0xd9eff32a, 0x85e21103, 0x2f11c41c, + 0xceed172c, 0x9e348c09, 0xa8e39264, 0x831eddfb, 0x71cb936b, + 0xf50864a3, 0x915c3d06, 0xe93acfcd, 0xfe8e33cd, 0xb3f2f7aa, + 0x4bee10d7, 0xeb7cee9a, 0xc1d8eb48, 0xfa574afd, 0x4fa49ce3, + 0x862db4c0, 0x78615109 }, + { 0x7ae72c21, 0x3fe3f480, 0xfd0f0da5, 0x631aa144, 0xf8c3a454, + 0xc76ee1e8, 0x51b4f1ab, 0x379ae094, 0xd7cdbb24, 0x2a3a4397, + 0x82bd5fcd, 0x7a14cffe, 0xf427ef5a, 0xbbe4ed12, 0x284d3ccf, + 0x9b0a43ee, 0x8eec6e1e, 0x57b78b93, 0x67b8e87b, 0x18d404e4, + 0x34374c20, 0x0c8adc05, 0x5428deb5, 0x64373605, 0xc3afa2cf, + 0xb4d80ec0, 0x3aa956f9, 0x6d51f93c, 0x84161c68, 0x9f9a28ab, + 0x6bc9c025, 0x540b6bb7 }, + { 0x321d315d, 0x04e1734c, 0xd86e05d0, 0x4ef56612, 0xbba8cd81, + 0xeafae145, 0xacdc789a, 0x1fb07a49, 0x5877570f, 0x6a21e9ad, + 0xb9bc53de, 0x2e4a837e, 0x1d6298eb, 0x436db293, 0xea362f45, + 0x43afbc78, 0xaabf6585, 0x2a973d97, 0x0c924d60, 0xdce7dabe, + 0x7cadf0e9, 0xf69d98f0, 0x75020538, 0xe0b505a1, 0x4461cd29, + 0x3db7d1a3, 0x5e20e818, 0xe1c28776, 0x52dd50f6, 0x2ca25867, + 0x92e0388c, 0x897cab14 }, + { 0x0d8bab8a, 0x59ed3813, 0xa438200a, 0xc11d364c, 0x40581415, + 0x0687bf2c, 0x7ac89674, 0x86ad0d3a, 0xb97411a0, 0x44928105, + 0xf383371c, 0x74984b11, 0x0d1a831e, 0x70d2ed84, 0x6c912fe0, + 0xd883628b, 0x14fa88d2, 0x44f8f7fb, 0xcf0ac93e, 0x564f2a4d, + 0xa6c24fa6, 0x82f629aa, 0xbf6cd949, 0xab906ba3, 0x20a5182d, + 0x2c822e67, 0x30eb93a5, 0x2ff47dac, 0xfff673aa, 0xdc62c4a4, + 0x476b0ec5, 0x64b00763 }, + { 0xb3c9a404, 0x1e3f533e, 0xb7ef9952, 0xb1db7f73, 0x6c253693, + 0xc7f13e29, 0x0738eed4, 0x7ce7f4c4, 0xce26cad0, 0xccfd3b33, + 0x01ec5cf1, 0xd8784935, 0xdc084e01, 0x3f8fc09d, 0xc39b5acf, + 0x217cab32, 0x9ef5551c, 0x42daf0bb, 0xe1217a95, 0xfbc76f56, + 0xc237002a, 0x80178b12, 0xb070a293, 0x0b52c39f, 0x576ca964, + 0xe3925153, 0x19d68e36, 0x25559424, 0x09e50e84, 0x291fb82c, + 0x6618ed8c, 0x7dd22ea6 }, + { 0x49cbb3bf, 0x7ffe844b, 0x5562fb25, 0xde0cc704, 0x9f5a845a, + 0x1e6ee537, 0xe51277fc, 0x956d7f26, 0x30635718, 0x2c75d4b9, + 0x96957f34, 0x39a14892, 0x82e5742b, 0x8cf4eb32, 0x83247b72, + 0x6b0d3ddd, 0x201a4237, 0x67a9f633, 0x1414a485, 0x416403c1, + 0xb6f6a916, 0x60afd447, 0xdac6f790, 0x95f94930, 0xbd3b9d82, + 0x685ff94b, 0x51cadf0f, 0x5c8f98fc, 0xb13b7489, 0x9559c88a, + 0x5f18fcc8, 0x31377c66 }, + { 0x7dcfb35f, 0x35c5de09, 0x01cc36f8, 0x2dccca9f, 0x7576cb63, + 0x7e93e85d, 0xf7b4b375, 0x0c2dd48a, 0xb09a19b5, 0x9d95cd4f, + 0x71bfe607, 0x752ed159, 0x2596dad2, 0x439880cf, 0x69e90a6f, + 0xe52efb53, 0x03d3e60a, 0x44097663, 0xa95070e0, 0xfcf364fa, + 0x05624dd2, 0xd8f993b6, 0x00d5e467, 0xb35a9824, 0x0c8f4524, + 0xe289d024, 0x648a0179, 0xef45423c, 0x587edabd, 0x3a5fd695, + 0xa11e5271, 0x3dacc50c }, + { 0x6499ae4c, 0xcb3e4f94, 0x7053c527, 0xa46dcbe1, 0xbe782e8a, + 0x807f5ce9, 0xd8481e45, 0xb6c64d28, 0xaa286fd0, 0xf35e4518, + 0xdf1cdb49, 0xf7b7b9ba, 0xaec23eaf, 0xf3fb6210, 0xb9bfd2fb, + 0x0a9ba385, 0x8807f3a0, 0xe51a0d53, 0xb17b2842, 0x7ab24404, + 0xf9dd9f0a, 0x6fd57687, 0xf3e9df64, 0xcd1efdb4, 0x60df194d, + 0x5dd2df7a, 0xe069df05, 0xbed3f2c3, 0x23248a31, 0x469b7561, + 0x694744f7, 0x866949e1 }, + { 0x3f4ab07a, 0x3a9a0da5, 0xf54a6fbf, 0x2cd6f333, 0xb23cf290, + 0x0c92e921, 0x848e3d58, 0xc9581c3e, 0xd3b218ab, 0x93af1fbd, + 0x066cb4d7, 0x38598ea1, 0x990c03a0, 0x5001394e, 0x7d0877b5, + 0x3b664b1e, 0xd74c7091, 0xd79db1bb, 0x4e2d5dd0, 0x852d4435, + 0x3329db82, 0x0d2b841b, 0x7b96d480, 0xfa844eb0, 0xc295dc46, + 0x37a50569, 0x94f7ec4e, 0xc2d38373, 0x5b083177, 0xdc3884ff, + 0x8b1fa598, 0x574352b8 }, + { 0x0d5d7ce9, 0xed2193f7, 0x0b487eaf, 0x3c19fd26, 0x7be65fd0, + 0x7c44ab59, 0x78270d56, 0xdd9da860, 0xbaa70198, 0x8a84ec00, + 0x285985df, 0x2ec27e49, 0xde2028d8, 0x996ccaf0, 0x61c2201d, + 0x4e7648c7, 0x091c19eb, 0xa96335bc, 0xf0d6782b, 0x253a3a69, + 0xd2946493, 0x3f204340, 0x099f6873, 0x444521a1, 0x6996011a, + 0x5fcbcc09, 0xf853a94e, 0x3884d5d8, 0xd3b6a3a1, 0x2418c624, + 0x06ae3c4f, 0x3e431af2 }, + { 0x83d381f1, 0xf967d939, 0xd0c033c3, 0x36501aae, 0x54410768, + 0xbf3af4d0, 0x5093a6d3, 0xa86d1598, 0xd92f2900, 0x43ae0741, + 0x36f0b755, 0xfeb2afa6, 0xaa456d6f, 0xd090a6a3, 0xaefdb646, + 0x336a4fda, 0x1a942f7d, 0xfd1bfe44, 0x851ee41e, 0x7fc2a3ed, + 0x11e935c5, 0x4f1c9686, 0x53bbb343, 0xcd577666, 0xad896c2a, + 0xf26931ba, 0x86bbfa41, 0x8a0fbbd1, 0xa203cef1, 0x1c3d7d82, + 0xe2664d35, 0x6dad3f15 }, + { 0x12ec35a1, 0xd1940b7d, 0xe7dfb128, 0x6219c5b6, 0xf13321d5, + 0x2cc278c6, 0x33c58eb6, 0x5e76904a, 0xd9903c43, 0x15090f55, + 0xc3d96a19, 0x061bc926, 0x8c0acba7, 0x974a9f03, 0x7198b21b, + 0x7a414021, 0xf8958c6f, 0xb069599d, 0xbebd0129, 0x517f2f1d, + 0xdf3a8dc3, 0x1109a613, 0x672375c5, 0x08e58448, 0x9383d2d3, + 0x56590ba4, 0x0bff837c, 0xfc3ee7c6, 0x27d2d55f, 0xc87a5390, + 0x5f517a3f, 0x2438e9d4 }, + { 0x8815af3c, 0xc4a45308, 0xf3c9bed5, 0xe55f1a32, 0x97b65ddf, + 0xaef1cdc9, 0x12e51eb5, 0x61c61d94, 0xe63f2490, 0xbd0dac54, + 0xd0b3e231, 0x6f14429c, 0xf1da6010, 0xf737c3c2, 0x6bbc4fb1, + 0x7150e04b, 0x1be281cb, 0x205b4c89, 0xd7701f5b, 0xf1b4633c, + 0x2a513490, 0x8b33ef46, 0x68f1f7f2, 0xddb47c73, 0xbd416b67, + 0xf4ada511, 0xff795bb3, 0x9d2a97cd, 0x96200e67, 0x00a8b7b2, + 0xafe30e01, 0x13f39011 }, + { 0x7bd0c827, 0x3dd296ef, 0x4a29ff46, 0x506110f3, 0x1c9a515a, + 0xf8793068, 0x268bca77, 0xde8d8045, 0x998045df, 0xcbb83024, + 0x68c0e584, 0x3f90d710, 0x263b6062, 0x2a838ca8, 0x535c5d0b, + 0x293bb5e7, 0x56415110, 0xceea99d5, 0x1bbda005, 0xfe311ad0, + 0xa4d8d018, 0x2497e0bf, 0x1cf2b866, 0x33dd77a0, 0xd8c4ba8b, + 0xbc075b73, 0x722b7bc9, 0x298466d4, 0xcbda1b0b, 0x17a7ce24, + 0x680703b6, 0x458d4b6b }, + { 0x4d54d8b2, 0x8a26a20e, 0x4d320a0d, 0x05a5696e, 0xf994f700, + 0x698b5858, 0x2f6549a8, 0x7a4adc3c, 0x3694d00d, 0x1812e819, + 0x730402bd, 0x46b9b000, 0xa1b36410, 0xe10a1449, 0x99230220, + 0xeae95ea5, 0x1b4820c3, 0x3efc2e9b, 0x85c9eb8a, 0xfe5b5cb5, + 0x97847064, 0x21ae0319, 0x8f27d49f, 0x68ef0b70, 0x2f72556b, + 0x3259ef18, 0x624db01a, 0x00ae0457, 0x5668f95c, 0x628e3b06, + 0xb6fbbf91, 0x5f13f5fa }, + { 0x3a9b0dc6, 0x7c6ed9ae, 0x6f883ec8, 0xaea1bde9, 0xea8b3677, + 0xea66bf88, 0x9a66e3ab, 0xdefa6abc, 0x68217ffd, 0xc4d3317b, + 0x290df05c, 0xf741c8f2, 0x7d11674e, 0x1f0fdf17, 0xc35989ca, + 0xfdf0ece7, 0x6b9c482d, 0x0eed92df, 0x55bf1ca7, 0x73713e66, + 0x25cec99c, 0x90acb290, 0xe803e69c, 0x37c9e3a2, 0x17713a1a, + 0x7c0a3c53, 0x6f5a174d, 0x350dc565, 0x05f802f6, 0x11625a44, + 0xa37ba4a2, 0x2196495d }, + { 0x13142680, 0x00cb2fd3, 0x65d14cf4, 0xab9e91d7, 0xdfe2669e, + 0xc6a0ceab, 0x0ae22bc5, 0xbeefce58, 0xcb6ec250, 0x3c2b7986, + 0xd738f1ff, 0x84adb1a2, 0x516ec8ec, 0x9709bc28, 0x8e8f7db5, + 0xf3693129, 0x95b197f9, 0xc48efc6b, 0x9aaaa404, 0x9ff10952, + 0x144154b0, 0x2c3c8cbd, 0x427f3435, 0x33ef7bc3, 0xd21897c1, + 0x04a17940, 0x6ce548a0, 0x5aa0c47d, 0x3d56fa62, 0x2971cea7, + 0x04475f08, 0x93ad0eb0 }, + { 0x988a9963, 0x7a0b6967, 0x6515e8dd, 0x61e477f7, 0x3b6b50f2, + 0x6274e386, 0xd33922de, 0x63a9b8d5, 0x687a5b3d, 0x3c38d3fb, + 0x1302e323, 0x18f6f09c, 0xe02fcccf, 0x254c05c3, 0x26e662f7, + 0xc04ed0b7, 0x143fe079, 0x1d5646b8, 0xc9016c8c, 0xef8a9448, + 0xf823d797, 0xe5674c4b, 0xbccde451, 0x0586f72f, 0x4417eade, + 0xc5fc88d5, 0x576e588d, 0x2b952209, 0x5844d1f9, 0x4408dd42, + 0xea41c034, 0x73f8c3f0 }, + { 0x5df763dd, 0x89534fc8, 0x3ac71836, 0x3b1427f3, 0x6e8f15a0, + 0x0db5be17, 0xcb20888e, 0x1d390944, 0x857caea6, 0x7804c9ad, + 0x519f7bf3, 0xaa584428, 0x293aa8cf, 0x626eecf1, 0xea36a015, + 0x749e0d98, 0x3321edcd, 0xefff6dae, 0x28b791cc, 0x963deea6, + 0x2d16e361, 0xa14e0552, 0xb15ae206, 0xa2e058fc, 0xfca325e4, + 0x0f268745, 0x21341a8a, 0x7cf9d407, 0x7caa51b8, 0xdfed25d9, + 0xadbedd75, 0x0108ae39 }, + { 0xa9e88f63, 0x54d178f3, 0xab0c7325, 0xaa05b11e, 0xe261d8a6, + 0x773a53e6, 0x8d0b91c8, 0x24db7dae, 0xe9bb004d, 0xde10b073, + 0x54e3090b, 0xfc8befe7, 0x0cc69c89, 0x16af0599, 0x9d59511a, + 0xddc83803, 0x46c5dafc, 0xc3f65b99, 0x1ee0a599, 0xfbbe4be8, + 0xfb3a9b17, 0x88891e36, 0x445dad00, 0x0c9aad75, 0xd5097e1f, + 0xdffc46ab, 0xac85a4e1, 0x8848089b, 0xa0c45233, 0x348bb42f, + 0xeb13c1df, 0x807c06d8 }, + { 0x98ee0ef6, 0x00a969ec, 0x8bb7b7af, 0xba9d5483, 0xa02f8fdb, + 0x24484c92, 0x8b70557c, 0x7bdb201a, 0x60ad1af2, 0xe59343e4, + 0x998c95fb, 0x53a9a942, 0xda861d3b, 0x974db3de, 0xed399c0e, + 0xce1525c9, 0xf72109bd, 0x89b56881, 0x998211a4, 0x08ff7d15, + 0xef0f275a, 0x5df76b3a, 0xfa2f358b, 0x93f180f7, 0xc39b0634, + 0xaac4ffcf, 0x17583b53, 0x2692c626, 0xb55399fc, 0xb2fdfa36, + 0x99607a61, 0x16424c6c }, + { 0xdd2744a9, 0x5dd65c55, 0xfe3af418, 0x2544c1c2, 0xefe8b089, + 0x32c82e99, 0xa9df691a, 0x30b7ab25, 0x9be99674, 0x98384550, + 0xcaf2d122, 0xbcecd258, 0xbcc77272, 0x88ae4098, 0x4b8efa0c, + 0xd4396141, 0xed64d12c, 0x44ff67b9, 0x2e7f3404, 0xa9e655e4, + 0x45b0e9eb, 0x3d16fc45, 0xf03ded28, 0x474a3e14, 0xacccb85c, + 0xa3c9adff, 0x7253a51b, 0x3dfe6bc1, 0xfb5831b1, 0xdddaf4b9, + 0xa4f4478a, 0x5544e602 }, + { 0xbaa80b4f, 0x897c5313, 0x63bdc8ef, 0x0122716f, 0x7b42c5a8, + 0xae2742db, 0x0883308c, 0xe9d9e1e9, 0x2d341ab1, 0x352c8c3f, + 0xed945870, 0x163d0500, 0xc290d9d8, 0x8349dd73, 0x1f6c7d29, + 0x2053c5e0, 0xcb42033c, 0x83107446, 0x09d09af1, 0x76c88bd2, + 0xb2794681, 0xd0f70e6e, 0x19b1b540, 0x720b59de, 0x22994b43, + 0x80b7ecdc, 0x2dec53cf, 0xc1a4cdce, 0x1ed60f42, 0xdd7d3edd, + 0xe241d261, 0x5735995c }, + { 0xa0237056, 0xdc4ba3fb, 0x33ab3388, 0x6856c164, 0x271ec612, + 0xc01eebbd, 0xe3031bec, 0xabdeb033, 0x6118a1f5, 0x4eee4419, + 0x5b600f33, 0xec497421, 0x08868773, 0x1b7185cf, 0x7c1b7dfd, + 0x7b0c46cd, 0x4a4c5e89, 0xd143b2da, 0xbb1ff94d, 0xdb9a5984, + 0xc9cf3465, 0xac3904e4, 0xeace64c9, 0xf8729bc0, 0x768ad99a, + 0x5cc22821, 0x8a9540c2, 0xbbd3b081, 0x049a6917, 0xe468ed5f, + 0x3ec45ef0, 0x885486df }, + { 0x4bdff464, 0x6a942c93, 0x25a7b451, 0x3db2719f, 0x325be324, + 0xccb0070b, 0x19fe3339, 0x2055a31b, 0x241ee8ff, 0xaca69ae8, + 0x55ef8def, 0x7607dd08, 0x1a1b73c6, 0x9e24960f, 0x71d36810, + 0xbcb0e8a2, 0x6885e6b9, 0x29e11aa2, 0x185eae19, 0x98b5d0ab, + 0x0f81f91c, 0x1a0b96e4, 0x994fc503, 0x4d0e8bcf, 0xf119d6e0, + 0x33d81697, 0xaaa4ce0c, 0x29083287, 0xc91ff9d7, 0xc5dd4d3e, + 0xd4ab962d, 0x31cecfe8 }, + { 0xfc8b21e8, 0x437bfd9a, 0xb19436df, 0xe5dd32b3, 0x921c36a0, + 0xfe5902d4, 0xa3d0fa90, 0x8e9de84d, 0x5bb523bd, 0x9663e6ad, + 0xaecd6975, 0x9800a23f, 0xb4fbb59c, 0x1009c0d9, 0xc9d20ff1, + 0x839aa7bd, 0xecd6fa3d, 0xf502f66d, 0xc5516ca9, 0x480ed4fb, + 0x6c742ac4, 0x65ffa5f6, 0xff3252f8, 0x2b7c7945, 0x75d9cb3d, + 0x72fefc05, 0xd6d6f1d2, 0x11b0863b, 0x9a6a4ec3, 0x5d8f3cf0, + 0xda2547b3, 0x6961b46a }, + { 0xcb35e2ac, 0xd07b587e, 0x57af14d9, 0x1ed5546b, 0xdb28a04c, + 0xeca17a5b, 0x709d54f0, 0xa1f91d44, 0x9c6f400e, 0xa6e719fd, + 0xfb8ce190, 0x4e4b88ed, 0x246e3fd2, 0xf9781edd, 0xb655af5d, + 0xd67120e6, 0x93413ca7, 0xda782d1d, 0x9707fa21, 0x697e20a2, + 0x54e84123, 0x1eb51f32, 0x36051f9f, 0x2e254d9e, 0x73ce5be9, + 0xddaec42b, 0xcd3f794f, 0x89a9a32e, 0x0781aad9, 0x1964e22f, + 0x53755212, 0x6a63a90c }, + { 0x3d7acbbb, 0x76554e00, 0xb74f6108, 0x2c01668a, 0x388c519b, + 0xe4a29672, 0x3eb94d4f, 0x01667714, 0x0cd6d2f6, 0x086a3cdf, + 0x7b370f7f, 0xf8658021, 0x5a4d3e7c, 0x658880c1, 0x5ba3f4a1, + 0xd6ed5816, 0x5ca471dd, 0xabcc7813, 0xe844a576, 0x809bf074, + 0x6ea502ea, 0xa53a81b3, 0x0e021ed3, 0xc20b9307, 0x8617f165, + 0x8c27f892, 0x8235cd0b, 0xa5476446, 0x82552961, 0xffc89ffd, + 0xd151d90e, 0x51ed4a22 }, + { 0x449701b4, 0x37d6963a, 0xbb27caf2, 0xea8d91a3, 0xb572965f, + 0x3ef9be15, 0xdb50bf7d, 0x75a7a055, 0xce643b9b, 0xfd67480e, + 0x6ceb5d5e, 0xf2a60d2d, 0x5ed7c897, 0x68fc320c, 0x28ce685f, + 0x41c53cf6, 0x7106615e, 0x0e29711f, 0x23500ecc, 0x7a872138, + 0x6c29fe48, 0xaf0a9260, 0xe1ef9712, 0x93df3f2a, 0xd2d169bf, + 0x0d5f6fb1, 0x74a9793c, 0xeb7afe26, 0xe9f49256, 0x4173d94a, + 0x2b8b5ce5, 0x2d6951bc }, + { 0x904e222e, 0xdd007d9f, 0x86f4e109, 0x333f248f, 0x8f429eee, + 0xd4994e8b, 0xcfc77518, 0x29573415, 0x0b0f42f1, 0x6e7fea3a, + 0xc2743519, 0xc795cb7d, 0x711e71a0, 0x820a8f66, 0x2b874f55, + 0x83d95d9c, 0xe70e1627, 0xd4b64d78, 0x8b92a742, 0x924353f5, + 0x447b5e6d, 0x322048b1, 0xbcf931a0, 0x0bad730c, 0xa7af2268, + 0x75c4d089, 0xb83b93f9, 0x464904c1, 0x165b3aee, 0xa24eba02, + 0xe08cc5f0, 0x65c48e78 }, + { 0xde222c22, 0x1a1c73ce, 0xfcea23b4, 0x5683d8cd, 0xb2143b06, + 0x0301cb14, 0x59fcec77, 0x284adf8f, 0x31204cef, 0xfb1c581c, + 0x94735107, 0xf54d3eee, 0x4d3188c0, 0xdbf67f0b, 0x10f18d12, + 0x76a3f2d1, 0x07d3e013, 0x3809fa28, 0x25e7ece0, 0xf06f0a46, + 0xb2895d2e, 0xd82867ed, 0x08b0553a, 0xe106f489, 0xef245445, + 0xe2280fa6, 0xa8d9a3cb, 0x402d5785, 0xd438ba2d, 0xf63dd9ff, + 0x7a6b226f, 0x36b5cd2c }, + { 0x545679a7, 0x87ff4e20, 0x4520c750, 0x64d80b41, 0x9b459cd8, + 0x90a357fa, 0xc85af1a3, 0xa19eaf39, 0x8d935a5e, 0x0d475d79, + 0x781a678a, 0x74501983, 0x0cc2e810, 0x74839779, 0x2f412244, + 0xc6a21d11, 0x36a51a37, 0x8d0e85f9, 0xeaa74df8, 0xff50151e, + 0x93cf99c4, 0x14e182a7, 0x376a9ab6, 0x45593df1, 0x522389ff, + 0x18f73caf, 0xf7445e8a, 0xd27cc960, 0x39a51dc8, 0x0692f4c5, + 0xdb39bfd8, 0x08d7c144 }, + { 0x3ecca773, 0x809c0d96, 0xd48c2156, 0x87ea9192, 0xdb6bd641, + 0xf0eccd74, 0x2a678cdf, 0x77312374, 0xd1587b7e, 0x7a966d8b, + 0x6130a4c6, 0xf3c1a101, 0x5fce17bd, 0x7cc6e838, 0xa8de7aa4, + 0x95e95bb8, 0x898308e3, 0x3fe1e8b5, 0xe347694a, 0x0197243e, + 0xbb0cd2bf, 0xf3fe9c42, 0x0f9b2b49, 0xb5905264, 0xc7367d1f, + 0x4c385e8b, 0xb5ee147b, 0x1d3050ae, 0x04004ad9, 0x8e2c3879, + 0xbab70202, 0x5f2aa8ee }, + { 0x1266524b, 0xe208d464, 0xd0a19f66, 0xb7bf3880, 0xda106ebf, + 0xa5aa685e, 0xe642dd46, 0x0a69e8d3, 0xc682e4d6, 0xef349c61, + 0x0fcb534c, 0x26f6ee3b, 0x05eb67b8, 0x7daba127, 0x18be05f6, + 0x2babb27e, 0x8e2d85d1, 0x959afcba, 0xe2d9d386, 0xedcf2d1a, + 0x1ea6f06e, 0x59dc52e6, 0x866e5ae8, 0xc28278b4, 0x02bcd3c7, + 0xd9ff0340, 0x784be82f, 0xe884ac76, 0x83c9f224, 0xa3164980, + 0xb46ff949, 0x62501a98 }, + { 0xad264086, 0x563f7d9a, 0xa5e0e4bd, 0xca6a33db, 0x8c8d3d67, + 0xe8253002, 0x46e64b19, 0xa288dac8, 0x20aa4536, 0xfa3c9197, + 0xed553eac, 0x8130c9b0, 0x2ea8abd3, 0x622806e0, 0xceccfe77, + 0x52fbf54d, 0x4f0d1b70, 0xbd9a8e31, 0xd59b1741, 0x519d2133, + 0x9a6fea8a, 0xfd74101c, 0xb5c4eb10, 0xd1acf7a0, 0x91f9da5e, + 0x78499b73, 0xc0dea586, 0xabaa4c49, 0xa1f3531a, 0xcc9c5f73, + 0xfd3fc665, 0x497b15fe }, + { 0xf45568e9, 0x8a56cbaa, 0xc7192a6f, 0xf491a0fe, 0x9ab2539a, + 0xdbb03dd3, 0x4ac37da9, 0xc86522f8, 0x02a0f5b4, 0x8c8cdba2, + 0xa29c539f, 0x8109fc75, 0xca90f02e, 0x9cd06d31, 0x3e216dbf, + 0x8f31f044, 0xba3ebd91, 0x99aa68ac, 0x42c007f4, 0x2a80d0d2, + 0x86a9b7ce, 0xdd8dffbf, 0xd6308edc, 0x405d3e84, 0x068012ca, + 0xdafa33fe, 0xedea1071, 0xc2eebd13, 0x2ff637e6, 0xb7ae7e5c, + 0x9e514cb7, 0x18d46a6c }, + { 0xa78b7802, 0x868cbb22, 0x497cbaf4, 0x0745ddb2, 0x42ae8add, + 0xc4eb2f3e, 0xb4ceb4e4, 0xac0abcda, 0xa325fd40, 0x2e0d8325, + 0x13ac7345, 0x6cfe0571, 0xb14171b9, 0x7407a788, 0x6da7a52b, + 0x70eb0603, 0xd85176ac, 0xab0b36f9, 0x7c2954f3, 0x14109d29, + 0xdcd705ad, 0x370de9c8, 0x7bb5e751, 0x3f0db5cd, 0xa06e708c, + 0x45f93d41, 0x7e93050d, 0x10d54f8a, 0x5a38fef9, 0x69e6f8e4, + 0xd3f62e40, 0x55044601 }, + { 0x06cb9cc9, 0xd1c5c910, 0x41d00014, 0x542074d7, 0x11236fb8, + 0x7cd8663e, 0x29ad5f82, 0x39721ffe, 0x2951fc83, 0x1d21fbfa, + 0x400d144f, 0x1cde06e7, 0x91792e6b, 0x9042596b, 0x29ad5166, + 0x3365c8e5, 0x9aeefe98, 0xe2220e85, 0x70c2aee3, 0xbcb53189, + 0x9ff100bc, 0x477ca3db, 0xf532973f, 0x27074176, 0x9a2bd01b, + 0xa12118ac, 0x3dd79f93, 0xf3425209, 0xc6f5d7db, 0x563a8ff7, + 0xd7b0ec4f, 0x0da313fc }, + { 0x15aa2557, 0x37125a8c, 0x00893e9c, 0xca21d70c, 0x67b8a823, + 0x48713994, 0x7cb0042a, 0x0d3e9a74, 0xc9e2ce18, 0x2d2bf4ff, + 0x049aeac2, 0xd5531a0d, 0xf03d0660, 0x4d29a616, 0x1f1b7f00, + 0x473d50d6, 0xca3de50c, 0x3af0ecbb, 0x09c28f27, 0xe2959bea, + 0xf8704664, 0x6d7c2ea0, 0x731083ef, 0xadfae4e1, 0x941c2554, + 0x50940c26, 0xa1162d03, 0x44167410, 0x1e82290e, 0x620230d8, + 0xdb414acc, 0x63630be8 }, + { 0x8a7d2e41, 0xbf8d5222, 0xeb62f879, 0x49e75823, 0x6c402d89, + 0x1b4d33dd, 0xde2c59ad, 0x883e04d6, 0x49b9dc38, 0xbf3f38f4, + 0xb4b70c4c, 0x9d997d18, 0x13cea045, 0x1f69b20c, 0x58e2606d, + 0xca3d7025, 0x261d1b79, 0x3d4fd977, 0x5a1436fa, 0x56aeafa8, + 0xbb443c07, 0x369b3e98, 0xe558f6be, 0xfce5186c, 0xf8ac8f89, + 0xeb0cd478, 0xd5e5aa72, 0x68074f37, 0x68544eb0, 0x295845c0, + 0xf16688ed, 0x306a9871 }, + { 0x634ec136, 0xbc451e9d, 0x0e6f658f, 0x1edf27ca, 0xc0db4120, + 0xa9be0152, 0xc5bfee67, 0x87b6ef20, 0x9a2d6023, 0x35283238, + 0xc7afb899, 0x60e564d8, 0x0ac9c2de, 0x4af22bc0, 0x82a9d22b, + 0x28e6f631, 0xf532701b, 0xc075c701, 0x82075f91, 0xf6d418f8, + 0x1beaa511, 0xf9fa628d, 0x6e72a13d, 0x551e7a17, 0x77f4c01c, + 0x9306215b, 0x93c9d588, 0x71aba731, 0x58e57cd4, 0x6443ebe0, + 0xe8103e37, 0x2833ac41 }, + { 0x8da5ec5c, 0x7e564b86, 0x1c08db24, 0xac3d9da8, 0x8c57a728, + 0x9d7c1f0b, 0x9d343dc2, 0x3512afe7, 0xfdc60339, 0xb438e4cf, + 0xdcfa1941, 0x7d5a2700, 0x27320449, 0xd5f323f8, 0x1393c6e6, + 0x1b87a58e, 0x04baa431, 0xecb68bd1, 0x4722b4d7, 0xc09c1c5a, + 0x206b5faa, 0xf42faa97, 0x9976327e, 0xe1dcbcd6, 0x087787d9, + 0x655ba9e4, 0xde5c0191, 0xbd59c757, 0x0bcf3538, 0x673020ed, + 0xa49d6303, 0x120cd454 }, + { 0xcab0f9ee, 0xebfdb8f4, 0x2cce58ee, 0xbc003ef0, 0x5a8d0665, + 0x9b6a6841, 0x9b957774, 0x642ed3a6, 0x4721ab5c, 0x3de487f0, + 0x21a4f0d3, 0xef2ff380, 0x29dbddcd, 0xbd16f558, 0x0e93dff2, + 0x2ef05b4b, 0x0bc9aec1, 0xde1faa12, 0xd467fa92, 0x66dae2c2, + 0x5eb33e34, 0x758daf64, 0x8f0103cb, 0xa67ad9f6, 0x9be02430, + 0x151f693a, 0xeb4054bc, 0xd5698496, 0x7019336e, 0x8ef1677e, + 0x7fdeea3e, 0x021cfd16 }, + { 0xdf5c36f3, 0x5c73715f, 0xd64ad254, 0x703bde37, 0xf2cf7713, + 0x55368d10, 0x0f3993c8, 0x1e5ec7b7, 0x304ae4ca, 0xfdb16776, + 0x3d3bb18b, 0x0d8f717e, 0x66343d5a, 0x5267073f, 0x156008b5, + 0xfaeb52ef, 0x224a470f, 0xb97ad5f9, 0xed2ab51a, 0xaf86e391, + 0x9974302c, 0xdc0c7e57, 0xfd0ae28a, 0xc88fa817, 0xbf8ed59c, + 0x807c22df, 0xeb128bb6, 0x5dedc231, 0xa20595a3, 0x71edcd9c, + 0xc73cf78e, 0x07265b46 }, + { 0xbd66232f, 0x73dd99f0, 0xc4027716, 0xc59aaf89, 0x5b860fc4, + 0xaf826dfa, 0x7a943f3b, 0x239ea8aa, 0x523c428d, 0x0e0e1b1a, + 0x6973b95a, 0x55ea0e3a, 0x2557753b, 0xea399caa, 0x06957b1f, + 0xf8adf72f, 0x3bd34302, 0x0389f341, 0xf8a43a97, 0x333f27d0, + 0xadaf796f, 0xcd9c0c08, 0x49c12aa2, 0x6dcca49b, 0x7a0ac6e9, + 0xdd88deee, 0x0644080e, 0x8f47575d, 0x0cc2f4bd, 0x6e9d667d, + 0x31d1496c, 0x36c5754b }, + { 0xf323d84b, 0x9120046e, 0x7e789c4f, 0xa6991122, 0x921b8055, + 0x4b0eaf4e, 0x8079974e, 0x6339844a, 0x740f8c79, 0xc905466a, + 0xcd6def49, 0x1c18d0f7, 0x4b23e4ba, 0x5297da6b, 0xc41800c5, + 0x1c09dff3, 0x37ef6777, 0x6c49075b, 0x50513ded, 0xa94c3a40, + 0x6b0b1705, 0x3d6742e9, 0xc48af5ae, 0xc0784494, 0xc95822de, + 0x40c01532, 0xc164d94f, 0xa2ddade5, 0xa2975eb5, 0xfc8a8ac9, + 0x1946944e, 0x06fbf861 }, + { 0x3f45aa97, 0x2d65338e, 0x1d040feb, 0xd83b58c8, 0x0fdef8b9, + 0x05fef59b, 0xe4d7417c, 0x7beb071a, 0xb30a1a23, 0x982b61f5, + 0xfb65bd03, 0x4c5f2a2a, 0x5cbf6bf3, 0xe40abc9d, 0xf06612a5, + 0x422c326d, 0x9571ae28, 0xc921e69d, 0x23d3434e, 0x7c88b10b, + 0x9da07933, 0x96d2e957, 0x3619cf4d, 0x833d46a1, 0xd95eefa1, + 0xd9d19653, 0xa03e8f0e, 0x2a7d8411, 0x04bb5ab1, 0x5e642953, + 0x1f0fa9ea, 0x5e9ca0fd }, + { 0x197c5dc4, 0x5bd54571, 0xe78a95a2, 0xe2da40bf, 0xffdb0eb2, + 0x65fb9efc, 0x0d17467c, 0xe952dc2c, 0xc758c6a3, 0xc1fc9c7b, + 0xd4034a9a, 0xfc79562c, 0x61f64b56, 0x26e36fbe, 0x1e84728b, + 0x6adc4b9e, 0xa8f9ac8a, 0x7f165fd3, 0x03e3e013, 0x7bc93a45, + 0x656478e3, 0xeacc5513, 0x064ddc77, 0xd3391717, 0x76936914, + 0x75b318dc, 0x362424a6, 0x69b1f1c7, 0x49955f34, 0x8cc2045b, + 0xc6836af8, 0x940622b3 }, + { 0x0d997973, 0x4710ccb7, 0xd3f8f115, 0x3b29625d, 0x5b97abd5, + 0x8cf0c4d5, 0x673e14a5, 0xc6321e0a, 0x3d262246, 0x0541af9d, + 0x6fc83b11, 0xde6d8754, 0xf01652a4, 0x47e97da8, 0xad9802b6, + 0x0f82b3a6, 0xae9c44b2, 0x69aa4075, 0xced2bf77, 0xaf3f5de2, + 0x497a40da, 0x1ef1ea8a, 0x3c23ba9c, 0x2e0f8608, 0xf190a2c8, + 0xd8a998a4, 0xcfde3368, 0xe2b49c8c, 0xbde6bd71, 0xb9f49824, + 0x785bedb6, 0x80bb1664 }, + { 0xfd145cb5, 0x05e575fe, 0xac5e6883, 0x155ee561, 0x8793b273, + 0x461e70cf, 0x133b2338, 0x9f1553de, 0xa2a7ba07, 0x2fb9e0c3, + 0x3e7086fa, 0xc3bfd6a8, 0x8bb4cb93, 0xb6ba8500, 0x76f82dbd, + 0x0b66d789, 0x54eb49ff, 0x7d5a6ff6, 0x1f20b322, 0xcd65d237, + 0x54e29cdc, 0x79ea49c2, 0xcb118ff9, 0x64975963, 0xcc58000b, + 0x969598dd, 0x110c779c, 0x95107918, 0x63b85a35, 0xedfc1548, + 0x41212350, 0x077ba5ea }, + { 0xcdd86f61, 0x0b3a38d3, 0x0502a0ab, 0x43121445, 0x806d0272, + 0x1912edc5, 0x8a32f10f, 0x01dc1f98, 0x0e80c760, 0xbb1d31d1, + 0xf464e8b3, 0xd46ec7e5, 0x9abf49ee, 0xd569af36, 0x2cdade77, + 0x9d286ea7, 0x45ad5920, 0x2be7020d, 0x6299ae7f, 0xabe5236e, + 0xd3f55c07, 0xc93179bd, 0x52350e80, 0x8138995a, 0xaff07586, + 0x0901265c, 0xf4739653, 0x5b3c81b2, 0x9bc77d21, 0xbaf7581d, + 0x4591a2e2, 0x6b2006df }, + { 0x965b1bc1, 0xb2fe50a8, 0x962bb4fd, 0x931f536a, 0x000e7f99, + 0xd5718d33, 0x53d5125e, 0x84728f25, 0xd2125caf, 0x4f8a6184, + 0x357f679e, 0x54f1a701, 0x1531c05a, 0x70a9f40c, 0x6fa8b775, + 0x10d0cb97, 0x9dc12ce9, 0xb476f41e, 0x2755f894, 0x5c8d7a75, + 0x625741a4, 0xd6c12e10, 0xc917b16c, 0x262a6fb8, 0x38d6b0a0, + 0x24d116e6, 0x32c38e83, 0x849540c0, 0x66868afc, 0x855b911c, + 0xbd26b550, 0x53217ea6 }, + { 0x259f52b4, 0xfc840473, 0xe621146c, 0x968da9cb, 0xcacbd26e, + 0x964eb85e, 0xe4a54344, 0xab7daa2d, 0x381a4ff7, 0x6dc3b848, + 0x41c815ef, 0xa07a96b3, 0xc3d4b1e1, 0xc4fae9e8, 0x42ce9ea8, + 0x0f938d1e, 0x35cc052f, 0xa727dacc, 0xe9a06f07, 0xc81e01c9, + 0x4a6d65a1, 0xa9e08dcb, 0x6044a9a6, 0xf8e2d173, 0xf2bd295b, + 0x99893dd0, 0xf9781b12, 0xa08d3379, 0x61830ac2, 0x64bd6001, + 0xd9adbeef, 0x0386931e }, + { 0xd09885a5, 0xd0d7abb3, 0xe355bb07, 0xed9d2b67, 0x536ebaed, + 0x3bc238cf, 0x699ce4d6, 0x61ca2e78, 0x111594cd, 0x354ff447, + 0x03316ad2, 0x55cbe709, 0x49fff5c4, 0x418679fd, 0x0f9c6c40, + 0x75bacd75, 0x2972721a, 0x677edc88, 0xe5ef502f, 0x82596887, + 0xbf320e0e, 0x459e9367, 0x8bbdccb2, 0x81ce36ef, 0xb766863d, + 0x1ba097fc, 0xd58c6db8, 0xcd3a21d6, 0xb4a8748b, 0x0e4967cd, + 0x15041c20, 0x2caaf749 }, + { 0x6ed20424, 0x44f98006, 0x22471545, 0xb3e4ea23, 0x781a8c86, + 0x268ed1a5, 0x7ae5b70b, 0x48d0ab75, 0x356d3982, 0x6ca8b320, + 0x2df31fa4, 0x9ce8e681, 0xd925dcf2, 0xb909d232, 0xf56723de, + 0x302c8f78, 0xabac96f9, 0x11725d69, 0x57d1a170, 0x656a47ca, + 0xc18a2be7, 0x6bb5d511, 0xad50d9d9, 0xb56e45f1, 0x70b05518, + 0x36e886e2, 0x09d8ff91, 0xc7c71f3d, 0x9350361e, 0x65a1bbe2, + 0x45fe3bd8, 0x86d7f532 }, + { 0xb0bf719a, 0x99f16eb6, 0x8bc3d913, 0xb6975098, 0x26cd01b4, + 0xfae50e52, 0x90898d1c, 0xd3e3ac54, 0x887ec666, 0x4da3b9db, + 0xfbea45b8, 0x58300644, 0x8355b058, 0x369f3bd9, 0x579bcc13, + 0x0fb239a8, 0x6e2bd811, 0x4f5b4539, 0x24198fd2, 0x007f3baf, + 0x8837d51d, 0x68a676db, 0xeae75b16, 0x68eeea62, 0x3db6083c, + 0x5ffe5f94, 0x7d836c5a, 0x52c94d0f, 0xcbc1ff85, 0x5a4c3c6f, + 0x86c0b4dd, 0x682a55e3 }, + { 0x587495aa, 0xc8f235a4, 0x34c7245d, 0x2276026c, 0xb75a46e3, + 0xd6ae0cc5, 0xecc3e5e7, 0x890d3965, 0x14296629, 0x1b13342f, + 0x8a877227, 0xc89927e6, 0x2324a68b, 0x1543f27e, 0x49cdc21a, + 0x6c447684, 0x1452d0ac, 0x9bc7fd4f, 0xff4b045c, 0x2cc30a31, + 0x852f7611, 0x415d46a0, 0xc6fdd7a6, 0xad737052, 0x7b4c7c91, + 0xdcecc3ab, 0x7688d70c, 0xd2cdf01b, 0xe40d3905, 0x054f2542, + 0xfefe4dcd, 0x02227fa6 }, + { 0xb751948b, 0x1805efd9, 0xfdfd225d, 0x8efeed46, 0x4f2c8b22, + 0xcb128e09, 0x96f7c5e5, 0x9d1090bf, 0xb4cbeca0, 0x0959d044, + 0x8e08cb04, 0x21c955f9, 0x68fa4fce, 0xbc1f279d, 0x0710ae9a, + 0xb021e14e, 0x881167f4, 0x64d16e9f, 0xbbc9f1a5, 0xf5a5c22e, + 0xe3420eea, 0x5f3716df, 0xd5c4e843, 0x971eb915, 0x28ffba81, + 0x64fc55fc, 0x7dd37578, 0x3427e54d, 0x15ebc7d0, 0x446e6a62, + 0x29269778, 0x547e249a }, + { 0xa1ffda27, 0x4706868a, 0x7955cf50, 0xb4e6cdcc, 0x0a63f3d8, + 0xf65151e1, 0x9de5e70a, 0x5b4127ea, 0xf9342823, 0x3d2c09ba, + 0xaa2f7d51, 0x18c99d83, 0xddeec025, 0xa0c5bb1d, 0x03dcf1ce, + 0x7ffddf84, 0x616fdeda, 0xe57e4d29, 0x7932a1f0, 0xd2456569, + 0x3191d4e3, 0x7475e0e8, 0xc220218b, 0x3479bea1, 0x8bcb2505, + 0xfceb5c90, 0x3c6132e6, 0x1c685cea, 0xbfe6c1eb, 0xc42dc745, + 0xd2b08eea, 0x45a41cc0 }, + { 0x4dbbf0e1, 0x3ea9b2c7, 0xa17cf70e, 0x41ff962f, 0x5eeb4c66, + 0xdc1ea758, 0xa9beb17e, 0x4f5412d2, 0xa285741a, 0x2c9e4f52, + 0x984fd11f, 0x93df7da4, 0x0df3184e, 0xb2afbddc, 0x2421e375, + 0x96323d25, 0x49df781e, 0xc87be1e4, 0x3d589bea, 0x145601ed, + 0x28fff6dd, 0x0f0bd9bd, 0x8a0f298c, 0x2d3259d4, 0xd88e6944, + 0x362d7a77, 0xb6ac2af6, 0xa84c06b6, 0xd087da02, 0xba850ac9, + 0x42ee40c8, 0x128763c9 }, + { 0xacbac178, 0x29a80f07, 0x34b08f6e, 0x7cc20044, 0x70feded2, + 0xe9631d14, 0x86615767, 0xb2115da3, 0xcb088548, 0x7c75f5c4, + 0x9a2e8e03, 0x5b29d213, 0x8b881752, 0xfe9fda66, 0xc1de7ebc, + 0x3f1d8d88, 0x03218123, 0xb476565e, 0xb1c995f3, 0x07365561, + 0xb13eb71b, 0x2160cb18, 0x99b3a0eb, 0x7e8da513, 0xb20fcd74, + 0x5e8ca1f9, 0xb4126d72, 0x6a7e0067, 0x68bb637f, 0x1e8204b7, + 0xfc4f74d2, 0x75e96bcc }, + { 0x0d19716e, 0x189d1fdc, 0x7c384525, 0xdf585058, 0xea987d2a, + 0x64a846d1, 0x6c07150f, 0x12b6bf83, 0x4d6fd5b7, 0x91d85d46, + 0x4f53f55f, 0xa9788836, 0x81509129, 0x60083bd8, 0xea876f48, + 0xa7672683, 0xc15b2489, 0xe80b2e7a, 0x42d1d992, 0x985ef8d2, + 0xcf3de492, 0x9c57b029, 0xb1487627, 0xfe02f83c, 0x8ae5b687, + 0xaeba4fe4, 0x5d6b8196, 0x8a86f09b, 0xa16e523d, 0xd88f566b, + 0xba268949, 0x309a6e9a }, + { 0xbdfbe97a, 0xef27ee50, 0xb8c50c4d, 0x1a5fe70f, 0x7fe09f5c, + 0xcc7beb01, 0xbed36cc5, 0x8fa15a85, 0x7550ed3a, 0xc0c3acdb, + 0xeb908681, 0xc581ef87, 0xc49d5ccb, 0xa15b3362, 0x1fa264e8, + 0x0fbb1714, 0x8e1eee88, 0x267f8d8f, 0x21c2b63d, 0xd31ccfd6, + 0x53be7efd, 0x924dbe7d, 0xdb2a358a, 0xd42e877f, 0x75d68ac1, + 0xcf9673c7, 0x714fea55, 0xe35978fd, 0x5769b202, 0xeeb36653, + 0xd7593789, 0x0458258a }, + { 0xa042dbdf, 0x5df71a74, 0x5779dfa2, 0x2d405857, 0x0d2e6657, + 0x0e66cba7, 0xca2e892e, 0x285d6745, 0x0f0e6b5f, 0xf56a8def, + 0xa30767c3, 0xe0ee851d, 0x43346b9c, 0x98c05658, 0xd6b3c742, + 0xb35fce26, 0x39777e00, 0xc0895bff, 0xe7b6d886, 0x83c8f6a6, + 0x4f02904b, 0xbee14843, 0x2e84ec34, 0x7f74915b, 0x96d10991, + 0xbaaf663c, 0xe41facc0, 0x004b8757, 0x6f86c029, 0xa2b880e5, + 0x95b77358, 0x53f4a3e0 }, + { 0x89fc48e7, 0x11bb08ce, 0xafab5aeb, 0xba60c577, 0xa0c1cb5a, + 0xf06bcbf8, 0x79757cb6, 0x7d2efaea, 0x76319160, 0xe26d90b1, + 0x2b77b7a9, 0x42aa1ab6, 0x285df2bf, 0x38eec0cd, 0xf3a8f7f0, + 0xd35947f5, 0xfc1cb5b5, 0x97c8dc0e, 0xc45845cf, 0xfeb8cca0, + 0x249e26f2, 0x16e8d989, 0x483ed89a, 0x7c264e6d, 0x51d91073, + 0x13a3f145, 0x305e99f0, 0x8501562e, 0x6908d563, 0xaaf98d74, + 0xd723d236, 0x0a99e653 }, + { 0xabbc0559, 0x23536f46, 0x9aa1a160, 0xc163067b, 0x0c1681b5, + 0x229fd229, 0x1378e907, 0x61254be1, 0xab793a2d, 0xc60ff57a, + 0x466552db, 0xa6f2df8b, 0x8c170a36, 0x9ad31893, 0x29b74d9a, + 0xc5cd9abe, 0xf7848523, 0xcf747273, 0x0d0e3063, 0xc126a93a, + 0x4248e3d8, 0xfe2021e3, 0x8323ddfa, 0xd97343ee, 0x332639e7, + 0x9f768775, 0x75325548, 0x9650fc31, 0x3eebf7ea, 0xb595dbd1, + 0x010fcbc0, 0x3a95cb45 }, + { 0x39d7ff2e, 0x954e68cb, 0xc1d5c48f, 0x8dd1cb4b, 0x7169438a, + 0x02a92c77, 0x91cad8ce, 0x7965c0b0, 0x32cd08d2, 0x0c5798ab, + 0xa6902bda, 0x1a5bc3c3, 0x5186d218, 0x545d0925, 0xd27e64db, + 0xf0077cdb, 0x8cd092da, 0x0157caa4, 0x24532ab3, 0x2a2fa3a0, + 0x41ccaba3, 0xa5fb639b, 0x4744aee6, 0x01702dc1, 0xcdba93da, + 0x485bb436, 0x329784f1, 0x93597f66, 0xdad672c3, 0x5d713c1d, + 0x030b7245, 0x366d222e }, + { 0x573ea5b2, 0xd50b4875, 0xa90da44d, 0x0fce401b, 0x7a1a0310, + 0x7b53fa65, 0xcf114460, 0x722a80a5, 0xa538bf49, 0x0b8ebf05, + 0xd32acd21, 0xae141147, 0x7b5ad07d, 0x6692712c, 0x3f48ca07, + 0x6dc5fee7, 0x2b8a78d8, 0x98ed1499, 0xdd2f1759, 0x4e8b3145, + 0x5f971b8e, 0x43408de1, 0xadf1b368, 0x055ea6dd, 0xe5932b7e, + 0x4bb76e73, 0xd30893fd, 0x44287153, 0x0661bfda, 0x173dccd2, + 0x79defd25, 0x9072ba99 }, + { 0x9620ea39, 0x474de4dd, 0xc831cee8, 0xfbf1649f, 0xcd3a9c43, + 0x0b0e8bb1, 0x3f3df1d5, 0x6a38286f, 0x8f0ec9b3, 0x4ed072b3, + 0x729c09e3, 0xa6e4c987, 0x8ad12242, 0xea3e8ac6, 0xfbdfa5ba, + 0x6ae0e22b, 0xb0a0f592, 0x56171ecf, 0x6b871f8d, 0x33b2886d, + 0x35e11bda, 0x6b19bea9, 0x7f0f153f, 0x4d815a40, 0x7d6c02ee, + 0x7e608d97, 0xb6a88f46, 0x7e8f23d9, 0x439d1654, 0x26ac9652, + 0x35546c29, 0x8d92c6bd }, + { 0xabeb0ff7, 0xb3e0d7ce, 0x3e0e42f8, 0xfbe35254, 0xde808499, + 0x57d1b226, 0x1cd44bc3, 0x9ece2e1f, 0x435cfee1, 0x1245adbc, + 0xf93f581c, 0x874ee840, 0xbda0b947, 0x916a779c, 0xfa57ae0a, + 0xabcc815a, 0xf0a621b0, 0x97adec2d, 0x81f90bdc, 0xbe6a502b, + 0x53bde63d, 0x54bf9de1, 0x78884c25, 0xa88fdabf, 0xcbbb5470, + 0x30aa52b1, 0x29053ef5, 0xf805396c, 0x8dd827ea, 0x8d43d898, + 0x5c1ae5c0, 0x4e4bec17 }, + { 0xfcc09676, 0xbf8483a2, 0x19ea9a94, 0x457c4a3f, 0xd702a5dd, + 0xa6852ef3, 0x843fe7d8, 0xe7915fd2, 0x16e35158, 0x644bba98, + 0x9ed746f0, 0x8d1b95d0, 0xb90af0b5, 0x47704581, 0xd4fd135e, + 0x0bd4bc6b, 0xb4e833a5, 0xa6dce067, 0xff56a9a1, 0x2c0e8f30, + 0xec2c63fe, 0xa9c80800, 0x98f508a8, 0x449c20a5, 0x3292813a, + 0x02b94cb3, 0xec7e81a2, 0x647e3d28, 0xb4877677, 0x72e67d1a, + 0x6f9ded24, 0x7a4aa3f5 }, + { 0xe27a0045, 0x559ef1ba, 0xb242cb50, 0xdc812d4f, 0x39cf8d24, + 0x23a478e4, 0x9b3f9c54, 0x97544fc5, 0xaffa1fcf, 0x5ac68132, + 0x34a2c83b, 0x74f8fee0, 0xcd3f4bb7, 0x96cc640f, 0xb0512ea6, + 0x775dce9d, 0xcdce381e, 0x67dca19d, 0xa9d3fe55, 0xc1eeb3f3, + 0x1a19274f, 0x38e0bf42, 0x28d69b12, 0x15992fb4, 0x9fd09df8, + 0x48fcebde, 0xb41ab5df, 0xdc9dfa4f, 0xc0a269c5, 0x0cbd7dc8, + 0xf7f0ade1, 0x60282a7b }, + { 0xdceea2e7, 0x7c07e538, 0x3c42061d, 0x38a322c8, 0x4f1f6516, + 0x676828f9, 0xc7776a10, 0xf21b69fb, 0xb5e6b405, 0xc63a3417, + 0x91a7b642, 0x4c99f258, 0x2cad1440, 0x38692ca8, 0x00869bcd, + 0xf1e82ffe, 0x16fe466a, 0xc30b714e, 0x19019138, 0x5fb742f9, + 0x0fa516ae, 0xe90166d0, 0xd8c73a43, 0x5550f7ac, 0xfbc5c372, + 0x2d6a407d, 0x68cc39ed, 0xe47a7539, 0x4a5fbe70, 0x3fd286d9, + 0x23c6b942, 0x5f4ae9c7 }, + { 0x53f4d561, 0xd96a2dda, 0x16da1992, 0x286d45d0, 0xfdd4b051, + 0x449a01fb, 0x9f2195ea, 0x25488a0d, 0xa37661b3, 0xc4151b0a, + 0xf9e5ee02, 0xb98c471e, 0xa8658817, 0xa4bca86e, 0x7a68fc0a, + 0xbbcadb87, 0x6b7366a9, 0x88b34649, 0x15661c2d, 0x32ee98d4, + 0xc901420c, 0xf5b3b4c6, 0x2f2752af, 0xa2352735, 0x510e4d9c, + 0x2f64ce73, 0xaca4aa80, 0x939a7f26, 0x401aa503, 0x9cd3e291, + 0xdc46afd2, 0x92a01423 }, + { 0x1c2f7dbd, 0xe9f24be1, 0xb7d527fa, 0xda8c900f, 0x8648f128, + 0x963e25bb, 0x48141941, 0x9ab713e2, 0x7a6756fb, 0xe87f7d01, + 0x058d90bd, 0x274dd85e, 0x82566abd, 0x823fee7a, 0x74240195, + 0x9f6230d7, 0xacb5e46e, 0x04579f2c, 0x16a4c87e, 0x2a226263, + 0xd99b0857, 0x9ca19a43, 0xe488789e, 0x86dc2ba3, 0x9406c3bd, + 0xf960b5b9, 0x8960957e, 0x6f2c428b, 0x161c515b, 0x90748706, + 0xaa88cb9b, 0x0fc8fe1e }, + { 0xfeb90f2d, 0x68ae1bed, 0xa48b1559, 0xf393bb3c, 0xf64e9635, + 0x2be62f9c, 0xf8be75c2, 0x354c2410, 0x5e6f7529, 0xbd7ea703, + 0x162cab31, 0xc264868e, 0xc860f3ff, 0xb1391e70, 0x1d89837e, + 0xdf367c75, 0x2bf32941, 0xe150b6b4, 0x78c1318f, 0x95e8f46e, + 0xa2c4b160, 0x2b3f1dab, 0x701afbf3, 0xc6ccf5ce, 0x5e8874c5, + 0x3ad27530, 0x5dc6dcbe, 0x39285e51, 0xd99892dd, 0x3c954d86, + 0xdfd3789f, 0x2d0ba862 }, + { 0xb472e1af, 0xeacd8ee8, 0xb76abbcc, 0xeb354eae, 0xd0d93fbd, + 0x9b520bf8, 0xfe6fc706, 0xfccd60d7, 0xa4ee2f39, 0xa9353dde, + 0x9a81e51e, 0x5eb0925e, 0xd1366777, 0xee334da1, 0xd5354d69, + 0xc1d28c9f, 0x92a5ed54, 0xb9771755, 0xb7f70d81, 0x5d3e367f, + 0xa933ae7a, 0x7be7eeca, 0xe23cfbb7, 0x264cf1f9, 0x89497681, + 0x0d129f4a, 0x09b6235b, 0x705375a4, 0x48a376da, 0xccf64c75, + 0x4d41dbfc, 0x963c8712 }, + { 0xde36a814, 0xbae290cb, 0x733b12b5, 0x9bdb0195, 0xf77fe0e1, + 0x0ebad867, 0x29720cea, 0x0a7d19fd, 0x9029ec72, 0x434d7651, + 0xbb51911e, 0x856aff17, 0xd80a7f60, 0xd0a25d9a, 0xf848c106, + 0xffca86af, 0x43ad749c, 0x53e8bdf9, 0xe3e696bb, 0xfb9e0284, + 0xeeee4215, 0x3eb6630a, 0x2ecf3c63, 0x9d8fbb9e, 0x4e00c0c0, + 0x71da4ffa, 0x5d57beac, 0xb296be59, 0xa8cec7ef, 0x1751fbad, + 0xff55d7bd, 0x2d03eb3c }, + { 0x04f2ec1d, 0xeb16925f, 0x0d147ee2, 0xa878f276, 0xaad9d9e0, + 0x442df604, 0x3f71035b, 0x891df44b, 0x8cb95d5b, 0xc28272b3, + 0x5ee8ed23, 0x6f14efb5, 0x13b0f3e3, 0xf3c4460f, 0x6bd7335e, + 0x889f9bd7, 0xf755ba6e, 0x889ee771, 0xed219b6c, 0x626984fe, + 0xec2ee411, 0x2d44c737, 0x63efcd37, 0xb94385a2, 0x6637826b, + 0xd909321b, 0x3ee6b7a7, 0xc24f8a79, 0xa7cf61b7, 0xa3ca8d24, + 0xc54bacd9, 0x842e40c1 }, + { 0xa661d843, 0x5a268ed6, 0x4f5b30cd, 0x02328cca, 0x1311e177, + 0x16e6fed1, 0xc6695967, 0x690decb4, 0x57b2e280, 0xbdac5bf6, + 0x1efe42d0, 0x827f82ca, 0xca5fca2f, 0xc554ec0a, 0xdde45506, + 0xac5276c1, 0xe3077513, 0xb7f4cb08, 0xcc8797cc, 0x8caf6d9a, + 0x0d9332d2, 0xd5964814, 0x285a409f, 0xcc6ae297, 0x6223d093, + 0x7773c2a5, 0x5128fc09, 0x2d5266ac, 0xbc31fe6c, 0xa596b7cb, + 0xcac91328, 0x0e63319a }, + { 0xf0360ac2, 0xb5cd2fad, 0x285e605a, 0x86b660de, 0xe25b9b14, + 0x82c6cf10, 0xaa9ac554, 0x9d5fa38d, 0x526c070e, 0x3dfcf1b8, + 0x3fccc52d, 0x0379a96b, 0x0bfcc7f5, 0xe3659c29, 0x69d3e6a1, + 0x5b1a3db5, 0x9b7b42d5, 0xb41528b5, 0x9c22a006, 0x934defa4, + 0x9b4ce3b6, 0x90f38018, 0xb3abaf32, 0xb073bc04, 0xff8389e2, + 0x27a5a222, 0xffa5a35b, 0x0b7a9d51, 0x28e1a7c2, 0x4939ecef, + 0x1872705a, 0x88839da2 }, + { 0x701ce29a, 0x56b66c30, 0x58981d50, 0x3acaf126, 0x105f9f21, + 0xd4dafc0c, 0x373e3d13, 0xfee571e6, 0xfa2ee3ca, 0xe7269c86, + 0xdd20385a, 0xf5cca64a, 0x3000e9ac, 0x217f2757, 0x0e7273ef, + 0xc934db47, 0x355b6776, 0x4294f4f7, 0x6fc05180, 0x1faa36b9, + 0xb052190b, 0x8f88b1db, 0xe9eaef52, 0x35791b90, 0xdb681b90, + 0xf37fb2eb, 0x4415c369, 0x39d0a51d, 0x1d2e21c9, 0xfc59cca7, + 0xa1f50c26, 0x64128cfe }, + { 0xe8f5b0b5, 0xf03678a2, 0xd340f059, 0x5c7e249c, 0x93ca7cec, + 0x41440441, 0xbc83af98, 0x075ca346, 0xfaa8bbb0, 0xf39f0033, + 0xf38230f7, 0x3d18f0ed, 0xd448f345, 0x78dff00c, 0xd51aa475, + 0x849228c0, 0x30c928d1, 0xdd4e2708, 0x8f12cfd3, 0xc66ba686, + 0x88b3a206, 0x091049db, 0x016dae01, 0xd865d059, 0xe253e37d, + 0x4599e905, 0x7ce9871b, 0x322cf0c2, 0x174a132e, 0x014f54da, + 0xbdabcbda, 0x93634a09 }, + { 0xa9a2e304, 0x62826b27, 0xc1a4c124, 0xc57e1866, 0x22381710, + 0x913ab832, 0xa9847cfe, 0x7e9b6b85, 0x2b5f46fd, 0x29655cf1, + 0x8038e66d, 0x7295572b, 0x6fa95eab, 0xe4cba601, 0xb9deda81, + 0xbbc11071, 0x3f1cf61e, 0x97f0009a, 0x373e0cfb, 0x5372777b, + 0xd139d63b, 0x302f909c, 0x4f87d78e, 0x1ed672da, 0xb4048763, + 0x362077a3, 0x9dcc22b2, 0xc408c32d, 0x26deeee7, 0x4b4c5bf2, + 0xbc06357e, 0x266cb467 }, + { 0xb56363e8, 0x6faa4154, 0x3c1aa4db, 0x4b4fd078, 0x2b9e6597, + 0x14358dde, 0xfa004b84, 0x5b34ae3e, 0xf19911a6, 0xcf44b2ec, + 0xa536bf78, 0x55caa833, 0x8870dc95, 0x606e1eb9, 0x09f3511d, + 0xe3c3287d, 0x9d5cf364, 0x68b2f4eb, 0x63ab8c9e, 0xc154e892, + 0xc36ab611, 0x1548828e, 0xa1b7d120, 0x0932bfcb, 0x5315b8d7, + 0x7ee7b5bc, 0xf7473ac1, 0x782fd0d1, 0x3c8f2af3, 0xbcb029a8, + 0x52454ee1, 0x4b1d5a1b }, + { 0x63d52c0c, 0x12fe5174, 0x188c099d, 0x3735525e, 0x360e3956, + 0x5c621563, 0xacfa5a43, 0x88b3f1ca, 0x797e8107, 0x90123a0a, + 0xb15e080a, 0xba31f6b5, 0xfca3dada, 0xd7de5e12, 0x0df511c8, + 0x3287361b, 0x65757d4e, 0x7cc800d4, 0x5207ec91, 0x10810f3d, + 0x30eea0e3, 0x0d4e56f1, 0x3ea5a2ec, 0xbbf7ee13, 0xbe6abbd0, + 0x6fc07762, 0x120bf619, 0xc831fdce, 0xb622d42a, 0xe07439fa, + 0x508e4b27, 0x8186b93f }, + { 0x09312867, 0xc619d154, 0xbfaf7db4, 0x7e042c05, 0x1f5f5dda, + 0xc1cf1668, 0xa4fc3d82, 0x50aa5057, 0xce68b8fe, 0xed30ed65, + 0xbeb4d644, 0xecb01c0b, 0x831c0497, 0x7b5dc444, 0x9b7d9b1c, + 0x351e6a00, 0xd9477c91, 0x4bb863b9, 0x05d4110a, 0xaba65891, + 0x43580b7a, 0x30086cf4, 0x90be357e, 0xb139c076, 0x27b5214e, + 0x12bfff1a, 0x22c3ab57, 0x79cfc6d7, 0xf34a9bfa, 0x4743de57, + 0xc9ee2b2a, 0x0bf97e97 }, + { 0xdda19e96, 0x96ec4ec8, 0x6c306e8b, 0x54ce18ea, 0x65f6918a, + 0x7e83612b, 0x0d9a0d99, 0x1ac6f68b, 0x62fdcc09, 0x98a697a4, + 0x95bc3e13, 0x65ce25f1, 0xb3939730, 0x1896ecda, 0x32f12806, + 0x9eb81a0f, 0x1d2dc7df, 0xd3d7416e, 0xad473599, 0xe22c7976, + 0x9f5ef439, 0x3de37a9a, 0x9e69d94e, 0x6b7ac0ab, 0x0a9d0bc8, + 0xe6bfa9e0, 0x5676f120, 0x576a870d, 0xfeaac23f, 0x3bd91bb4, + 0x3e40aabb, 0x8fe5482c }, + { 0xce9a4d1e, 0x85ae67c2, 0x4f1d2038, 0x4c3eb803, 0x25d06192, + 0x5c6c8f3a, 0x308fb41c, 0x803de0ad, 0xe71c294e, 0x9961f5bc, + 0xf02eb0da, 0xdc62078d, 0xb64ae8b6, 0xc87ef515, 0x50b4d18f, + 0x69679f1e, 0x52199f43, 0xc5c009a1, 0x0f640a5f, 0xa7d484be, + 0x23dab566, 0x4c918bb1, 0x64275d2c, 0xa67c114c, 0xcad2ded6, + 0x95a913b9, 0x6b4b5c8d, 0x189ed18b, 0xb42d3bf6, 0x4aeb6206, + 0xbbc8bc3f, 0x3928c669 }, + { 0xdacb4b64, 0xde4bea4a, 0xf26179a1, 0x03f62a44, 0x7a9112a4, + 0xf3aac94e, 0xd36f331e, 0x90448fbd, 0x407b85c4, 0x426042bc, + 0x2121b77b, 0x5ad8a596, 0x67cee984, 0x31674a4f, 0x4e3b2f0d, + 0x7fae8bbe, 0xa7c930eb, 0x681df6dd, 0xc259d0d4, 0xadeefa98, + 0xbea1c1fd, 0x1b14d9e6, 0x21d405d1, 0x3baadc8b, 0x73892754, + 0xf01dff93, 0xf071cde4, 0x81c35b3e, 0x9150d0d9, 0x1704d2e1, + 0x355134f6, 0x6ccc888f }, + { 0x7ad7504c, 0xf8d36f0e, 0xf7959ddd, 0xbca3265f, 0xfede67aa, + 0x0dcd1ede, 0xbaebf32f, 0x1276f4ce, 0x014edcfc, 0x6825a6e6, + 0x99ad8eb7, 0x0b8c1a82, 0x09b8ce1e, 0x312024a9, 0x9cbd351a, + 0xcb8fd98b, 0xfab1e8be, 0xa4841378, 0x3973cacf, 0x17ed0f5d, + 0x259d5254, 0xa17e1484, 0x74b91393, 0x53d5b843, 0x1aca3ce9, + 0x8f792b21, 0xc8c0f815, 0x035ff110, 0xad4ed7bd, 0x6afa6357, + 0xb26faef9, 0x2f151980 }, + { 0x29d2d439, 0x0c8631da, 0xbc039955, 0x121fbbc2, 0x6c05b75b, + 0x3e5a9792, 0xb6ce47ec, 0x6d6cf4c0, 0x9d88c658, 0xbaaa1767, + 0xf3355a17, 0x031db9e7, 0x0aef5a85, 0x8381e3d8, 0x15a31bdf, + 0xc71db290, 0x9498fd7d, 0x638f6b74, 0x13beeef6, 0x44edf3f9, + 0xf4ab67b3, 0xe6173271, 0xfd22df11, 0x3a202c70, 0x205c4e92, + 0xf7be0389, 0xa8eb9920, 0x1c219085, 0xbeb54aaa, 0x6c805ce8, + 0x0ac58d65, 0x354b05b7 }, + { 0x7a9170e9, 0x7171e236, 0x4cad50cd, 0x01eec42d, 0x3cddccfb, + 0xffbe824f, 0xa66cae1a, 0xa73e8ce3, 0x965c7d01, 0xb7138a7f, + 0x5c3d971e, 0x00058e3f, 0x2ff0a72b, 0x52591ac3, 0xbbbce76f, + 0xa32fb5bc, 0xa9f81a18, 0xf3241ab8, 0xeca68630, 0xf31d3332, + 0x4482f13b, 0x847af9fc, 0xa4681be2, 0x6196e217, 0xe55efcf9, + 0x9938f932, 0x70acc705, 0x3e7dacb8, 0xcf09fac2, 0xd41be893, + 0xae3523a1, 0x48dc55c4 }, + { 0xa5092193, 0x8e623826, 0x6898970c, 0xe46ec362, 0x25c9eb41, + 0x2f1356af, 0x83c7d245, 0x41780640, 0x97d00e38, 0x982def67, + 0xa512151c, 0x382eb6e7, 0x8af58869, 0x154e1077, 0x8a51cf02, + 0x18707075, 0x71313c58, 0xcdeba9f7, 0xba155904, 0x5d67b973, + 0x1d0d7b3a, 0x851c9f4b, 0x8b8af2cd, 0x19f29d71, 0x986b8d62, + 0xcb94ccff, 0xb93b9c33, 0x8725e24b, 0x66e38c68, 0x405ce4c5, + 0x0b6dc021, 0x5f6a8edd }, + { 0x8f9a8690, 0x83704ca5, 0x2f76a407, 0x3f369766, 0x69201028, + 0xfbc12d8c, 0xbce3a4cf, 0x4cd58f16, 0x04aab26d, 0x7804664a, + 0x4ea457a8, 0x005cfbba, 0xb8a59794, 0x537951b3, 0x4fe1f739, + 0x4ca2b9e4, 0xdf325797, 0xe4428acd, 0x0ea243db, 0x648da342, + 0xf43ce01e, 0xcce6562b, 0xf27db490, 0x840f0421, 0x8bfb7cf0, + 0x156ccb70, 0x5a8797d3, 0x9b33480d, 0x9eb814bb, 0x2e12e07a, + 0xca7f87ac, 0x1ca65072 }, + { 0x2b9d25a0, 0xfbb321cf, 0x40a746db, 0x66affdca, 0x59e368b5, + 0xc1c1530e, 0x7d80068f, 0x56ed1ea4, 0x5647dd68, 0x9b74d8fe, + 0x89b78da8, 0x1d96b507, 0x8bbe3391, 0x39b75243, 0x0d858c5f, + 0xef8d443e, 0x9646aa34, 0x4dd2db49, 0xe667543c, 0x7fad3bd1, + 0x68980985, 0xd0d710c0, 0x49facaba, 0x9f7aff32, 0x14f9a192, + 0x055dec1c, 0x1fb307a1, 0xaca66399, 0x35ffff64, 0xac44fd91, + 0xcbad3cee, 0x462cafb6 }, + { 0xde3237dd, 0x1660a647, 0x82b87404, 0x95f735cc, 0xddfa55f8, + 0xf7879f59, 0x726b914a, 0x15ef043e, 0x1c93e298, 0x1875393d, + 0x6ef18331, 0xa1a2be74, 0x25a9a12b, 0x4e7e8dfc, 0xa9c3917f, + 0xdfefc97d, 0x0a2ebe41, 0xbc875d03, 0xa732d1cc, 0x0f75d235, + 0xd9baa6d3, 0x06fee7fe, 0x65f48576, 0xaa784fab, 0x513f83c0, + 0x23155e22, 0x3e8f9d13, 0xd2fb7718, 0xb546eafd, 0x2a291503, + 0x6cd93608, 0x1293c98c }, + { 0x49d53b77, 0x72781251, 0x96eafac7, 0xa6ab403d, 0x4a36b711, + 0xb7d7c7db, 0x87e771c1, 0x8238c708, 0x33b37522, 0x495f6abf, + 0x8c87530d, 0xb0b0289c, 0xe77b111a, 0xca83cb86, 0xa1bd189e, + 0xbe1c0fb8, 0x1ae9d7c7, 0x58cfb2fb, 0x4940c3e8, 0xd05c23c5, + 0x74ad9107, 0x16e79e41, 0x064e7142, 0xa0a47f05, 0xfdfd614f, + 0xc6929cd4, 0x3946988b, 0xedb2584c, 0xe46f8fb1, 0x73e4b5f3, + 0x68ea94ba, 0x53b79aa1 }, + { 0x44bbb6a1, 0x216fafce, 0x67821728, 0xd3a5bba0, 0xa9dd939a, + 0xef1e4b30, 0xf19efafe, 0x022eaf3d, 0x7b4ec014, 0xfed5abce, + 0x512c6738, 0x64968ee6, 0x29fe89a2, 0x23119869, 0x47397c05, + 0x0d539d8d, 0x234596c4, 0x6400bc54, 0x5346611d, 0xb9287f58, + 0xc9d5da0f, 0x04099903, 0xc83af2a8, 0xe5ef4997, 0x328151e1, + 0xc89dc01b, 0x58401104, 0x150fb4a9, 0xf3872c9d, 0x40a6f7d5, + 0x56c2e833, 0x8290d6d1 }, + { 0xd8546946, 0xf84637c6, 0x69ec57fa, 0xda134a39, 0xd789007e, + 0xd42359a4, 0x0dc7b809, 0xb42557fe, 0x2d6784a9, 0xe62ae52d, + 0x0bcadb5f, 0xa2714ca6, 0x33aafca5, 0xcc208de6, 0xed967811, + 0x2380ed5c, 0xdb321660, 0x6e6b55e9, 0xa675235a, 0x1bead02c, + 0xb33fa0e1, 0x51cc6ef9, 0xf06a2a08, 0xfd223e26, 0xec47b3cf, + 0x00f332e1, 0xa0aa984e, 0x459f297b, 0xee952e14, 0x6fa1d969, + 0x304fabb0, 0x506ef1ab }, + { 0x35bff163, 0x11b4eb27, 0xea9fa984, 0x7130b96f, 0x9deb27ce, + 0x66aceb3f, 0x9dd1c3d5, 0xa2daf1a5, 0xa73075aa, 0xf5090a7e, + 0xe3071b58, 0x36a6af39, 0xdf73ad9c, 0xa28d633d, 0xbdc89a16, + 0xdd354cac, 0xd4dcbc3c, 0xdfea3423, 0x379d92d1, 0x6eec74d2, + 0x8eed6765, 0xe14a456f, 0xfa8feb1f, 0xfabe7743, 0xb98fcbc7, + 0x1404ccf8, 0xf71a706e, 0x6ccd2fbf, 0x4d85c678, 0xdaaf3fdb, + 0x15200344, 0x415b7dbf }, + { 0x7d8377a7, 0x97010586, 0xcb803272, 0x068a3d68, 0xf03a4c32, + 0xfd67d289, 0x93c8f290, 0x4bc7095d, 0xe9e5a2b8, 0x712fa13c, + 0x0feb9f3b, 0xfc6ac6c6, 0x6e0e54c2, 0x0cda36d9, 0x86320a01, + 0x45499751, 0x97f00f11, 0xf9318c91, 0xe6936508, 0x01dc4c3f, + 0x85f068aa, 0x769a2ef9, 0xa2b5511c, 0x3522cef0, 0xb4122e05, + 0x006965ed, 0xc175d43f, 0xfce0fafc, 0xec831d59, 0x525dc9bd, + 0xaf58879d, 0x1ec314f1 }, + { 0x2c8310c2, 0x0663feef, 0x457e3f74, 0xaa7e14da, 0xe5346887, + 0x392b10fc, 0x637ec2c5, 0xcde4a38f, 0xb542f8df, 0x50773320, + 0xf7de1711, 0x341302f9, 0xae4b9bc6, 0x018b1c63, 0xdd2f9e6f, + 0xf001c46e, 0x26eccfa0, 0xd3bb0a97, 0x7746e0c7, 0xa931b99d, + 0xf5875aec, 0xe0c8b6f7, 0x96939c82, 0xbb32f17c, 0x3de5a664, + 0x765135d2, 0x52abfa6b, 0x71936cb4, 0x2dc105de, 0xad5cc08f, + 0x7fff5788, 0x17e91d12 }, + { 0xb7e051ca, 0xbe92ced3, 0x19c776d4, 0xc644d4fd, 0x0086784b, + 0xc8ab4b52, 0xce9d6b31, 0x3ea66227, 0xd289e9c7, 0x395249a3, + 0xd12a19ee, 0x54509e65, 0x8c365aec, 0xa7bd4692, 0x77963e0e, + 0x354997e4, 0xb599732d, 0x0d765957, 0x91d4a3b6, 0x99584aeb, + 0x1deb3e28, 0x6e653ea4, 0x572571df, 0xca7c98ed, 0xb18ae1f9, + 0xf301a38f, 0x63f7b97e, 0x1629f7c2, 0xafc4a0d5, 0xdf242282, + 0x3ddd0c01, 0x118f3b4b }, + { 0x7ad4762b, 0x74a0a0a8, 0x8c58d175, 0x1aef84da, 0x4cf76d86, + 0x16ff4960, 0x7e60d98b, 0xc0be8786, 0x3ecc1dba, 0x83637ffb, + 0x5dd6147a, 0xc244a609, 0x5b0846e5, 0xa3e17834, 0xe77a4c05, + 0x735eb686, 0xdf758695, 0x5bc18b4f, 0x1bdfe52f, 0x15618d0b, + 0x00715ba1, 0x878ecc0d, 0xc2dd617f, 0x1dbdbd1a, 0x21b61710, + 0x21d2b631, 0x44f593c2, 0x22ce8a79, 0x44f17024, 0x3b9b536a, + 0x8d03e727, 0x01d0a67c }, + { 0x1e46533c, 0x7b964236, 0xfb88c2ae, 0xe9477990, 0xa42c4a18, + 0x019b5d16, 0xd83c7a45, 0x7135e81d, 0x4cb663e3, 0x74a69bdd, + 0xe76c0d63, 0x7b67ecdb, 0x11e68da6, 0x03d54521, 0xd2e8650a, + 0x596cceb5, 0x2af03b37, 0xcd572dfd, 0xfabd5952, 0x52364ba1, + 0xb4ed8569, 0x7f47d456, 0xc950d5d4, 0x5ad8b572, 0x486e2f84, + 0xcadd2dfa, 0xc56bb044, 0xdd527b43, 0x997c08e6, 0xc9adba24, + 0x7da6320f, 0x1b625b06 }, + { 0x4fd8446d, 0x44dfaa7b, 0xaf6febeb, 0xc01b2f01, 0xfe8838b5, + 0xbf444388, 0xbba9758b, 0xf33c434f, 0x87156bc9, 0x2b971cba, + 0x1f49098b, 0x6b245e5c, 0x2b41c5dd, 0x87dcb534, 0x34d852d7, + 0xdb1f80c6, 0x2433da34, 0x6d6e3258, 0x3f7df0c2, 0xf6682065, + 0x360cb365, 0xc4ca567c, 0x9826656a, 0x321faac2, 0xbf069768, + 0x13f5ca6f, 0xa7076639, 0x15397921, 0x8400736e, 0xbdf14328, + 0x19fc948d, 0x333eca96 }, + { 0xac775d81, 0x23337948, 0xd41dbbca, 0x38c2518f, 0xbcfce948, + 0x623c7a4f, 0x54703fe7, 0xaad36236, 0x13fb3b5b, 0x2b3a13a4, + 0x7f5c01f0, 0x5db3565a, 0x52359661, 0xd72408dc, 0x1d616e91, + 0x5a17f8e5, 0xcb25b999, 0x90c16eeb, 0x3393743e, 0xf35e8cf1, + 0xe54b64a7, 0x987da74a, 0x65cd449d, 0x557b322a, 0x37e7b15d, + 0x765082a5, 0xf2cd134f, 0x4d25c742, 0x4ccf0746, 0xae9d9c07, + 0x8728d135, 0x72fc2110 }, + { 0xf96004c8, 0xa906b203, 0x458055ff, 0xd83f95cf, 0x55f35909, + 0xd77d5867, 0xe550c8ee, 0x4a9ea6fb, 0x55a06081, 0x91c8cca9, + 0xbce82062, 0x4a1fee78, 0x9a3df85e, 0xeb9ade06, 0x7d3de666, + 0xfbbdcf0c, 0x5d336d51, 0x228a391b, 0x5c2ffc3c, 0x760f8d28, + 0x2f7b165b, 0x1ee48de3, 0x56177040, 0x03803d84, 0x9deff9a0, + 0xe573f648, 0xa17e35a4, 0xe1a2738e, 0x8840a6c6, 0x238ef17c, + 0xb11ed92d, 0x480946f8 }, + { 0xfd71f119, 0x84c747a8, 0x53eb3695, 0x19e65c5e, 0x6298587a, + 0x0e2f6786, 0xab18d6f4, 0x48a48899, 0xc630b8c0, 0xa1a99024, + 0x2caaf892, 0x84975096, 0xe20fd624, 0xc8869aba, 0x6c2b7dd4, + 0x3b72b04d, 0x0992f7d0, 0xe2775eb6, 0x7d06e684, 0x0089c06e, + 0xe4bbd007, 0xcb3b4361, 0x4ba846e4, 0xa1ae666b, 0x46464d9e, + 0xc01c2eb2, 0xc1f8539f, 0xf86f2be6, 0xcf68afc7, 0x16e8e8ae, + 0xc7386902, 0x8dab61fd }, + { 0xd54d1d45, 0x42a5c903, 0xff4f9ba2, 0xacd4297e, 0x34d478b4, + 0x2d88b520, 0x08c4621a, 0x35b2ba2b, 0x34865402, 0xd3d239bb, + 0x911f32e6, 0x1de76aed, 0x3f06fdc2, 0x877f8bcf, 0x9ec51502, + 0x802714c1, 0xa590700d, 0xa10444eb, 0x31dcc957, 0x8694229f, + 0xb8169fed, 0x5ece77ab, 0x2caf080e, 0x55be8a15, 0xcbd7cef1, + 0x3eb21b14, 0x67b97ee1, 0x9def7ad1, 0x118f690c, 0xe03ca879, + 0xf99b29e7, 0x6f77e62d }, + { 0xe40bbf59, 0xa271bded, 0x6401aad6, 0x177ba453, 0x73541cd1, + 0x1755e035, 0x4b71b02f, 0x3465b466, 0xa813359f, 0x22eb7113, + 0x6f38eac7, 0x9792a8fd, 0xff3bf3b5, 0x11aa012f, 0xf85c3fbf, + 0x99aafabf, 0x06c0cc42, 0x91e0a2ef, 0x773b7b3a, 0x314d5d57, + 0xd669840a, 0xae5e2e76, 0x2e5a8be6, 0x86136073, 0xc1cf5580, + 0xee6d7578, 0x68bed102, 0x2344e00f, 0x8184f0eb, 0x799d7886, + 0xc3d2cf80, 0x63819c91 }, + { 0x7884b073, 0xca5392e1, 0xeb1267ea, 0x9ec3a1fc, 0x907038a7, + 0x3d07f5f0, 0xe4c47b70, 0xcb2ac07c, 0x1bf96b91, 0xf96664ee, + 0x2aea4fbf, 0xebf57589, 0xfade6500, 0x5aabf391, 0x171d1204, + 0xc5b3376f, 0xa0d3d81a, 0x1ff60c51, 0x976a844b, 0x10b2cfe7, + 0xbda6125a, 0xe131cc9a, 0x4ebd453e, 0xe0fc16d3, 0x504b6bc1, + 0xc0d0319a, 0x0a2f8cab, 0xe43a0be7, 0x55e49b47, 0xc80afeec, + 0x8265d7ee, 0x67d48d12 }, + { 0xea2d56d6, 0x068d59a7, 0x27480a63, 0xd71abd0e, 0xae7366cd, + 0x6bd11db0, 0x07204ebc, 0xfbb639ca, 0xf77e6293, 0x89a242e7, + 0x75ba8c3d, 0xdee7ca2b, 0x64a2f9a8, 0x472ddc3d, 0x7561a010, + 0x84229df4, 0xc5b649d4, 0x95f62c85, 0x4dc927cd, 0xfdd56b1b, + 0x5ee60596, 0xfe8bb120, 0xabf29401, 0x3efcaa50, 0x10d1c184, + 0xd4900d0f, 0x28b01df5, 0x2cf113a9, 0x1f0e43f5, 0xa3d7ebc3, + 0xe8384dc7, 0x27950e38 }, + { 0xe1d0fa79, 0xeab21ff0, 0x048b5de9, 0x4b9fd033, 0x2fe374cb, + 0x4c934689, 0x4eb21f6b, 0xbb4827fa, 0xa925e7e7, 0x46716f79, + 0x7dd4c531, 0x1442bf36, 0xd2e96ddf, 0x2073954c, 0x8502aa89, + 0x4e0141ae, 0x8eef6cc9, 0x8ee00e1a, 0x5880cdaf, 0x55ce8491, + 0x69628046, 0xff3aba5c, 0x5d15dfbf, 0x335cc4f8, 0x9f684f25, + 0xa7f0440c, 0xbb1e5bd8, 0xae80453f, 0xff2225ab, 0xa1c99813, + 0x79b25d71, 0x54ff7884 }, + { 0xde40b068, 0x27c6ee30, 0xe6f3a51e, 0x9226465b, 0xfa3b21f6, + 0xe24a4604, 0xc0418115, 0x50a5a5ad, 0x8df90d2b, 0xe3285441, + 0xdcb0c00f, 0xbb74e58f, 0x4a2c08e3, 0xc68f1b3b, 0x0ccd9ec9, + 0x339df081, 0xb786ea9f, 0x915362dc, 0xc955aead, 0x28945e31, + 0x8b6a6c6b, 0xd6a2c01d, 0x3678a427, 0x069e82dc, 0x28c9302c, + 0x17875500, 0x9fa101e6, 0x8acda965, 0xee30b286, 0x4e4e4573, + 0x3f1830fe, 0x8adbad85 }, + { 0x0969d524, 0x060ae11f, 0xf39bcc79, 0xf42fdaf7, 0x7cc1fcc2, + 0x3cec6766, 0xe2336d4f, 0x456b9cf2, 0x8e1c0f7f, 0x6aa1f5de, + 0x0984fb0e, 0xcdbc2ad2, 0x1b464b28, 0x4090cfa6, 0x1243f3ef, + 0x40d86f30, 0xcd5e87e7, 0x95b16ccc, 0x3026cd41, 0x403f168c, + 0x816c0730, 0xdbe386cb, 0x58407a1d, 0x14eb86f3, 0x1717e1af, + 0xf588b4f8, 0x66cbc96c, 0xb75c41a6, 0x027e71c1, 0xf342c1aa, + 0xc0945e5f, 0x73930036 }, + { 0x22cdaf42, 0x954f757d, 0xf4181aab, 0x788b591d, 0xf5514f25, + 0x8b986819, 0xf18fd5bc, 0x69642e08, 0x022ceb91, 0x92b305d1, + 0x6a4f6985, 0x1715903e, 0x61179cae, 0x4bd7d69d, 0xd29c01aa, + 0xdacdfd5d, 0xd91108cc, 0x705ddd5a, 0x64ac8f15, 0x434ac7b1, + 0xb524632f, 0x61a514e1, 0x731fc447, 0x45b9e61b, 0xe0961b31, + 0xcf561348, 0x73eaf223, 0x9c28a967, 0xaa7c99d3, 0x5bd10182, + 0xe42965e2, 0x8bc6ec4a }, + { 0xe7f2a32b, 0xd096e5c0, 0x09388a30, 0xff54800c, 0x401e360c, + 0x06fe437c, 0xbb6054a6, 0x6655fc9c, 0x8457aa6e, 0x510e1860, + 0x2b29b2b7, 0xa0acfca2, 0x51b7da61, 0x732483e3, 0x6be6c8ca, + 0xe31471ee, 0x8b65c9a1, 0xe565431c, 0x48d65cbb, 0xfc9ac3b9, + 0xae9b2aa8, 0xd308fc21, 0xaa60aa6a, 0xd6a7df0d, 0x982fc0d4, + 0x2844d96a, 0x5847a4d7, 0xab012c2c, 0xdceb8955, 0x2b3c8f71, + 0xbe9c7e15, 0x8e85437d }, +}; + +/* Perform the modular exponentiation in Fp* for SAKKE. + * + * Base is fixed to be the g parameter - a precomputed table is used. + * + * Striping: 128 points at a distance of 8 combined. + * Total of 256 points in table. + * Square and multiply performed in Fp*. + * + * base [in] Base. MP integer. + * exp [in] Exponent. MP integer. + * res [out] Result. MP integer. + * returns 0 on success, MP_READ_E if there are too many bytes in an array + * and MEMORY_E if memory allocation fails. + */ +int sp_ModExp_Fp_star_1024(const mp_int* base, mp_int* exp, mp_int* res) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td; + sp_digit* t; + sp_digit* tx; + sp_digit* ty; +#else + sp_digit t[4 * 2 * 32]; + sp_digit tx[2 * 32]; + sp_digit ty[2 * 32]; +#endif + sp_digit* r = NULL; + unsigned char e[128]; + int err = MP_OKAY; + int i; + int y; + + (void)base; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6 * 32 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + tx = td + 4 * 32 * 2; + ty = td + 5 * 32 * 2; +#endif + r = ty; + + (void)mp_to_unsigned_bin_len(exp, e, 128); + + XMEMCPY(tx, p1024_norm_mod, sizeof(sp_digit) * 32); + y = e[112] >> 7; + y |= (e[96] >> 7) << 1; + y |= (e[80] >> 7) << 2; + y |= (e[64] >> 7) << 3; + y |= (e[48] >> 7) << 4; + y |= (e[32] >> 7) << 5; + y |= (e[16] >> 7) << 6; + y |= (e[0] >> 7) << 7; + XMEMCPY(ty, sp_1024_g_table[y], sizeof(sp_digit) * 32); + for (i = 126; i >= 0; i--) { + y = (e[127 - (i / 8)] >> (i & 0x7)) & 1; + y |= ((e[111 - (i / 8)] >> (i & 0x7)) & 1) << 1; + y |= ((e[95 - (i / 8)] >> (i & 0x7)) & 1) << 2; + y |= ((e[79 - (i / 8)] >> (i & 0x7)) & 1) << 3; + y |= ((e[63 - (i / 8)] >> (i & 0x7)) & 1) << 4; + y |= ((e[47 - (i / 8)] >> (i & 0x7)) & 1) << 5; + y |= ((e[31 - (i / 8)] >> (i & 0x7)) & 1) << 6; + y |= ((e[15 - (i / 8)] >> (i & 0x7)) & 1) << 7; + + sp_1024_proj_sqr_32(tx, ty, t); + sp_1024_proj_mul_qx1_32(tx, ty, sp_1024_g_table[y], t); + } + } + + if (err == MP_OKAY) { + sp_1024_mont_inv_32(tx, tx, t); + sp_1024_mont_mul_32(r, tx, ty, p1024_mod, p1024_mp_mod); + XMEMSET(r + 32, 0, sizeof(sp_digit) * 32); + sp_1024_mont_reduce_32(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Multiply p* by q* in projective co-ordinates. + * + * p.x' = (p.x * q.x) - (p.y * q.y) + * p.y' = (p.x * q.y) + (p.y * q.x) + * But applying Karatsuba: + * v0 = p.x * q.x + * v1 = p.y * q.y + * p.x' = v0 - v1 + * p.y' = (px + py) * (qx + qy) - v0 - v1 + * + * px [in,out] A single precision integer - X ordinate of number to multiply. + * py [in,out] A single precision integer - Y ordinate of number to multiply. + * qx [in] A single precision integer - X ordinate of number of + * multiplier. + * qy [in] A single precision integer - Y ordinate of number of + * multiplier. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_mul_32(sp_digit* px, sp_digit* py, + const sp_digit* qx, const sp_digit* qy, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 32; + + /* t1 = px + py */ + sp_1024_mont_add_32(t1, px, py, p1024_mod); + /* t2 = qx + qy */ + sp_1024_mont_add_32(t2, qx, qy, p1024_mod); + /* t2 = (px + py) * (qx + qy) */ + sp_1024_mont_mul_32(t2, t1, t2, p1024_mod, p1024_mp_mod); + /* t1 = py * qy */ + sp_1024_mont_mul_32(t1, py, qy, p1024_mod, p1024_mp_mod); + /* t2 = (px + py) * (qx + qy) - (py * qy) */ + sp_1024_mont_sub_32(t2, t2, t1, p1024_mod); + /* px = px * qx */ + sp_1024_mont_mul_32(px, px, qx, p1024_mod, p1024_mp_mod); + /* py = (px + py) * (qx + qy) - (py * qy) - (px * qx) */ + sp_1024_mont_sub_32(py, t2, px, p1024_mod); + /* px = (px * qx) - (py * qy)*/ + sp_1024_mont_sub_32(px, px, t1, p1024_mod); +} + +#ifndef WOLFSSL_SP_SMALL +/* + * Convert point from projective to affine but keep in Montgomery form. + * + * p [in,out] Point to convert. + * t [in] Temporary numbers: 2. + */ +static void sp_1024_mont_map_32(sp_point_1024* p, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 32; + + sp_1024_mont_inv_32(t1, p->z, t2); + sp_1024_mont_sqr_32(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(t1, t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(p->x, p->x, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_32(p->y, p->y, t1, p1024_mod, p1024_mp_mod); + XMEMCPY(p->z, p1024_norm_mod, sizeof(sp_digit) * 32); +} + +#endif /* WOLFSSL_SP_SMALL */ +/* + * Calculate gradient of line through P, P and [-2]P, accumulate line and + * double P. + * + * Calculations: + * l = 3 * (p.x^2 - p.z^4) = 3 * (p.x - p.z^2) * (p.x + p.z^2) + * r.x = l * (p.x + q.x * p.z^2) - 2 * p.y^2 + * r.y = 2 * p.y * p.z^3 * q.y (= p'.z * p.z^2 * q.y) + * v* = v*^2 * r* + * p'.x = l^2 - 8 * p.y^2 * p.x + * p'.y = (4 * p.y^2 * p.x - p'.x) * l - 8 * p.y^4 + * p'.z = 2 * p.y * p.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] p ECC point - point on E(F_p^2) to double. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_dbl_32(sp_digit* vx, sp_digit* vy, + sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 32; + sp_digit* pz2 = t + 2 * 32; + sp_digit* rx = t + 4 * 32; + sp_digit* ry = t + 6 * 32; + sp_digit* l = t + 8 * 32; + sp_digit* ty = t + 10 * 32; + + /* v = v^2 */ + sp_1024_proj_sqr_32(vx, vy, t); + /* pz2 = p.z^2 */ + sp_1024_mont_sqr_32(pz2, p->z, p1024_mod, p1024_mp_mod); + /* t1 = p.x + p.z^2 */ + sp_1024_mont_add_32(ty, p->x, pz2, p1024_mod); + /* l = p.x - p.z^2 */ + sp_1024_mont_sub_32(l, p->x, pz2, p1024_mod); + /* t1 = (p.x + p.z^2) * (p.x - p.z^2) = p.x^2 - p.z^4 */ + sp_1024_mont_mul_32(t1, l, ty, p1024_mod, p1024_mp_mod); + /* l = 3 * (p.x^2 - p.z^4) */ + sp_1024_mont_tpl_32(l, t1, p1024_mod); + /* t1 = q.x * p.z^2 */ + sp_1024_mont_mul_32(t1, q->x, pz2, p1024_mod, p1024_mp_mod); + /* t1 = p.x + q.x * p.z^2 */ + sp_1024_mont_add_32(t1, p->x, t1, p1024_mod); + /* r.x = l * (p.x + q.x * p.z^2) */ + sp_1024_mont_mul_32(rx, l, t1, p1024_mod, p1024_mp_mod); + /* r.y = 2 * p.y */ + sp_1024_mont_dbl_32(ry, p->y, p1024_mod); + /* ty = 4 * p.y ^ 2 */ + sp_1024_mont_sqr_32(ty, ry, p1024_mod, p1024_mp_mod); + /* t1 = 2 * p.y ^ 2 */ + sp_1024_div2_32(t1, ty, p1024_mod); + /* r.x -= 2 * (p.y ^ 2) */ + sp_1024_mont_sub_32(rx, rx, t1, p1024_mod); + /* p'.z = p.y * 2 * p.z */ + sp_1024_mont_mul_32(p->z, p->z, ry, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 */ + sp_1024_mont_mul_32(t1, p->z, pz2, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 * q.y */ + sp_1024_mont_mul_32(ry, t1, q->y, p1024_mod, p1024_mp_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_32(vx, vy, rx, ry, t); + + /* Double point using previously calculated values + * l = 3 * (p.x - p.z^2).(p.x + p.z^2) + * ty = 4 * p.y^2 + * p'.z = 2 * p.y * p.z + */ + /* t1 = (4 * p.y^2) ^ 2 = 16 * p.y^4 */ + sp_1024_mont_sqr_32(t1, ty, p1024_mod, p1024_mp_mod); + /* t1 = 16 * p.y^4 / 2 = 8 * p.y^4 */ + sp_1024_div2_32(t1, t1, p1024_mod); + /* p'.y = 4 * p.y^2 * p.x */ + sp_1024_mont_mul_32(p->y, ty, p->x, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 */ + sp_1024_mont_sqr_32(p->x, l, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 - 4 * p.y^2 * p.x */ + sp_1024_mont_sub_32(p->x, p->x, p->y, p1024_mod); + /* p'.x = l^2 - 8 * p.y^2 * p.x */ + sp_1024_mont_sub_32(p->x, p->x, p->y, p1024_mod); + /* p'.y = 4 * p.y^2 * p.x - p.x' */ + sp_1024_mont_sub_32(ty, p->y, p->x, p1024_mod); + /* p'.y = (4 * p.y^2 * p.x - p'.x) * l */ + sp_1024_mont_mul_32(p->y, ty, l, p1024_mod, p1024_mp_mod); + /* p'.y = (4 * p.y^2 * p.x - p'.x) * l - 8 * p.y^4 */ + sp_1024_mont_sub_32(p->y, p->y, t1, p1024_mod); +} + +#ifdef WOLFSSL_SP_SMALL +/* + * Calculate gradient of line through C, P and -C-P, accumulate line and + * add P to C. + * + * Calculations: + * r.x = (q.x + p.x) * c.y - (q.x * c.z^2 + c.x) * p.y * c.z + * r.y = (c.x - p.x * c.z^2) * q.y * c.z + * v* = v* * r* + * r = p.y * c.z^3 - c.y + * c'.x = r^2 + h^3 - 2 * c.x * h^2 + * c'.y = r * (c'.x - c.x * h^2) - c.y * h^3 + * c'.z = (c.x - p.x * c.z^2) * c.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] c ECC point - current point on E(F_p^2) to be added + * to. + * @param [in] p ECC point - point on E(F_p^2) to add. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] qx_px SP that is a constant value across adds. + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_add_one_32(sp_digit* vx, sp_digit* vy, + sp_point_1024* c, sp_point_1024* p, sp_point_1024* q, sp_digit* qx_px, + sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 32; + sp_digit* rx = t + 4 * 32; + sp_digit* ry = t + 6 * 32; + sp_digit* h = t + 8 * 32; + sp_digit* r = t + 10 * 32; + + /* r.x = (q.x + p.x) * c.y */ + sp_1024_mont_mul_32(rx, qx_px, c->y, p1024_mod, p1024_mp_mod); + /* t2 = c.z^2 */ + sp_1024_mont_sqr_32(t2, c->z, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 */ + sp_1024_mont_mul_32(t1, q->x, t2, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 + c.x */ + sp_1024_mont_add_32(h, t1, c->x, p1024_mod); + /* r = p.y * c.z */ + sp_1024_mont_mul_32(ry, p->y, c->z, p1024_mod, p1024_mp_mod); + /* t1 = (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_mul_32(t1, h, ry, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z * c.z^2 = p.y * c.z^3 */ + sp_1024_mont_mul_32(r, ry, t2, p1024_mod, p1024_mp_mod); + /* r.x -= (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_sub_32(rx, rx, t1, p1024_mod); + /* t1 = p.x * c.z^2 */ + sp_1024_mont_mul_32(t1, p->x, t2, p1024_mod, p1024_mp_mod); + /* h = c.x - p.x * c.z^2 */ + sp_1024_mont_sub_32(h, c->x, t1, p1024_mod); + /* c'.z = (c.x - p.x * c.z^2) * c.z */ + sp_1024_mont_mul_32(c->z, h, c->z, p1024_mod, p1024_mp_mod); + /* r.y = (c.x - p.x * c.z^2) * c.z * q.y */ + sp_1024_mont_mul_32(ry, c->z, q->y, p1024_mod, p1024_mp_mod); + /* v = v * r */ + sp_1024_proj_mul_32(vx, vy, rx, ry, t); + + /* Add p to c using previously calculated values. + * h = c.x - p.x * c.z^2 + * r = p.y * c.z^3 + * c'.z = (c.x - p.x * c.z^2) * c.z + */ + + /* r = p.y * c.z^3 - c.y */ + sp_1024_mont_sub_32(r, r, c->y, p1024_mod); + /* t1 = r^2 */ + sp_1024_mont_sqr_32(t1, r, p1024_mod, p1024_mp_mod); + /* t2 = h^2 */ + sp_1024_mont_sqr_32(rx, h, p1024_mod, p1024_mp_mod); + /* ry = c.x * h^2 */ + sp_1024_mont_mul_32(ry, c->x, rx, p1024_mod, p1024_mp_mod); + /* t2 = h^3 */ + sp_1024_mont_mul_32(t2, rx, h, p1024_mod, p1024_mp_mod); + /* c->x = r^2 + h^3 */ + sp_1024_mont_add_32(c->x, t1, t2, p1024_mod); + /* t1 = 2 * c.x * h^2 */ + sp_1024_mont_dbl_32(t1, ry, p1024_mod); + /* c'.x = r^2 + h^3 - 2 * c.x * h^2 */ + sp_1024_mont_sub_32(c->x, c->x, t1, p1024_mod); + /* ry = c'.x - c.x * h^2 */ + sp_1024_mont_sub_32(t1, c->x, ry, p1024_mod); + /* ry = r * (c'.x - c.x * h^2) */ + sp_1024_mont_mul_32(ry, t1, r, p1024_mod, p1024_mp_mod); + /* t2 = c.y * h^3 */ + sp_1024_mont_mul_32(t1, t2, c->y, p1024_mod, p1024_mp_mod); + /* c'.y = r * (c'.x - c.x * h^2) - c.y * h^3 */ + sp_1024_mont_sub_32(c->y, ry, t1, p1024_mod); +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * @param [in] key SAKKE key. + * @param [in] p First point on E(F_p)[q]. + * @param [in] q Second point on E(F_p)[q]. + * @param [in] r Result of calculation. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +int sp_Pairing_1024(const ecc_point* pm, const ecc_point* qm, mp_int* res) +{ + int err = MP_OKAY; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit* qx_px; +#else + sp_digit t[6 * 2 * 32]; + sp_digit vx[2 * 32]; + sp_digit vy[2 * 32]; + sp_digit qx_px[2 * 32]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + + err = sp_1024_point_new_32(NULL, pd, p); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 9 * 32 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 32 * 2; + vy = td + 7 * 32 * 2; + qx_px = td + 8 * 32 * 2; +#endif + r = vy; + + sp_1024_point_from_ecc_point_32(p, pm); + sp_1024_point_from_ecc_point_32(q, qm); + + err = sp_1024_mod_mul_norm_32(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 32); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 32); + + sp_1024_mont_add_32(qx_px, q->x, p->x, p1024_mod); + + for (i = 1020; i >= 0; i--) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_dbl_32(vx, vy, c, q, t); + + if ((i > 0) && ((p1024_order[i / 32] >> (i % 32)) & 1)) { + /* Accumulate line into v and add P into C. */ + sp_1024_accumulate_line_add_one_32(vx, vy, c, p, q, qx_px, t); + } + } + + /* Final exponentiation */ + sp_1024_proj_sqr_32(vx, vy, t); + sp_1024_proj_sqr_32(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_32(vx, vx, t); + sp_1024_mont_mul_32(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 32, 0, sizeof(sp_digit) * 32); + sp_1024_mont_reduce_32(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_32(c, 1, NULL); + sp_1024_point_free_32(q, 1, NULL); + sp_1024_point_free_32(p, 1, NULL); + return err; +} + +#else +/* + * Calculate gradient of line through C, P and -C-P, accumulate line and + * add P to C. + * + * Both C and P have z ordinates to use in the calculation. + * + * Calculations: + * r.x = (q.x * c.z^2 + c.x) * p.y * c.z - (q.x * p.z^2 + p.x) * c.y * p.z + * r.y = (p.x * c.z^2 - c.x * p.z^2) * q.y * p.z * c.z + * v* = v* * r* + * h = p.x * c.z^2 - c.x * p.z^2 + * r = p.y * c.z^3 - c.y * p.z^3 + * c'.x = r^2 - h^3 - 2 * c.x * p.z^2 * h^2 + * c'.y = r * (c.x * p.z^2 * h^2 - c'.x) - c.y * p.z^3 * h^3 + * c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] c ECC point - current point on E(F_p^2) to be added + * to. + * @param [in,out] p ECC point - point on E(F_p^2) to add. + * @param [in,out] q ECC point - second point on E(F_P^2). + * @param [in,out] t SP temporaries (6 used). + * @param [in,out] neg Indicates to use negative P. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static void sp_1024_accumulate_line_add_n_32(sp_digit* vx, sp_digit* vy, + const sp_point_1024* p, const sp_point_1024* q, + sp_point_1024* c, sp_digit* t, int neg) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 32; + sp_digit* rx = t + 4 * 32; + sp_digit* ry = t + 6 * 32; + sp_digit* h = t + 8 * 32; + sp_digit* r = t + 10 * 32; + + /* h = p.z^2 */ + sp_1024_mont_sqr_32(h, p->z, p1024_mod, p1024_mp_mod); + /* rx = q.x * p.z^2 */ + sp_1024_mont_mul_32(rx, q->x, h, p1024_mod, p1024_mp_mod); + /* rx = q.x * p.z^2 + p.x */ + sp_1024_mont_add_32(t2, rx, p->x, p1024_mod); + /* c.y = c.y * p.z */ + sp_1024_mont_mul_32(t1, c->y, p->z, p1024_mod, p1024_mp_mod); + /* r.x = (q.x * p.z^2 + p.x) * c.y * p.z */ + sp_1024_mont_mul_32(rx, t2, t1, p1024_mod, p1024_mp_mod); + /* c.y = c.y * p.z^3 */ + sp_1024_mont_mul_32(c->y, t1, h, p1024_mod, p1024_mp_mod); + /* t2 = c.z^2 */ + sp_1024_mont_sqr_32(t2, c->z, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 */ + sp_1024_mont_mul_32(t1, q->x, t2, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 + c.x */ + sp_1024_mont_add_32(t1, t1, c->x, p1024_mod); + /* c.x = c.x * p.z^2 */ + sp_1024_mont_mul_32(c->x, c->x, h, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z */ + sp_1024_mont_mul_32(r, p->y, c->z, p1024_mod, p1024_mp_mod); + if (neg) { + /* r = -p.y * c.z */ + sp_1024_mont_sub_32(r, p1024_mod, r, p1024_mod); + } + /* t1 = (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_mul_32(ry, t1, r, p1024_mod, p1024_mp_mod); + /* r.x -= (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_sub_32(rx, ry, rx, p1024_mod); + /* t1 = p.x * c.z^2 */ + sp_1024_mont_mul_32(t1, p->x, t2, p1024_mod, p1024_mp_mod); + /* h = p.x * c.z^2 - c.x * p.z^2 */ + sp_1024_mont_sub_32(h, t1, c->x, p1024_mod); + /* c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z */ + sp_1024_mont_mul_32(t1, h, c->z, p1024_mod, p1024_mp_mod); + /* c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z * p.z */ + sp_1024_mont_mul_32(c->z, t1, p->z, p1024_mod, p1024_mp_mod); + /* r.y = (p.x * c.z^2 - c.x * p.z^2) * c.z * p.z * q.y */ + sp_1024_mont_mul_32(ry, c->z, q->y, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z^3 */ + sp_1024_mont_mul_32(t1, r, t2, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z^3 - c.y * p.z^3 */ + sp_1024_mont_sub_32(r, t1, c->y, p1024_mod); + /* v = v * r */ + sp_1024_proj_mul_32(vx, vy, rx, ry, t); + + /* Add p to c using previously calculated values. + * h = p.x * c.z^2 - c.x * p.z^2 + * r = p.y * c.z^3 - c.y * p.z^3 + * c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z + */ + + /* t1 = r^2 */ + sp_1024_mont_sqr_32(t1, r, p1024_mod, p1024_mp_mod); + /* t2 = h^2 */ + sp_1024_mont_sqr_32(rx, h, p1024_mod, p1024_mp_mod); + /* ry = c.x * p.z^2 * h^2 */ + sp_1024_mont_mul_32(ry, rx, c->x, p1024_mod, p1024_mp_mod); + /* t2 = h^3 */ + sp_1024_mont_mul_32(t2, rx, h, p1024_mod, p1024_mp_mod); + /* c'.x = r^2 - h^3 */ + sp_1024_mont_sub_32(c->x, t1, t2, p1024_mod); + /* t1 = 2 * c.x * p.z^2 * h^2 */ + sp_1024_mont_dbl_32(t1, ry, p1024_mod); + /* c'.x = r^2 - h^3 - 2 * c.x * p.z^2 * h^2 */ + sp_1024_mont_sub_32(c->x, c->x, t1, p1024_mod); + /* ry = c.x * p.z^2 * h^2 - c'.x */ + sp_1024_mont_sub_32(t1, ry, c->x, p1024_mod); + /* ry = r * (c.x * p.z^2 * h^2 - c'.x) */ + sp_1024_mont_mul_32(ry, t1, r, p1024_mod, p1024_mp_mod); + /* t2 = c.y * p.z^3 * h^3 */ + sp_1024_mont_mul_32(t1, t2, c->y, p1024_mod, p1024_mp_mod); + /* c'.y = r * (c.x * p.z^2 * h^2 - c'.x) - c.y * p.z^3 * h^3 */ + sp_1024_mont_sub_32(c->y, ry, t1, p1024_mod); +} + +/* + * Perform n accumulate doubles and doubles of P. + * + * py = 2 * p.y + * + * For each double: + * Calculate gradient of line through P, P and [-2]P, accumulate line and + * double P. + * + * Calculations: + * l = 3 * (p.x^2 - p.z^4) = 3 * (p.x - p.z^2) * (p.x + p.z^2) + * r.x = l * (p.x + q.x * p.z^2) - py^2 / 2 + * r.y = py * p.z^3 * q.y (= p'.z * p.z^2 * q.y) + * v* = v*^2 * r* + * p'.x = l^2 - 2 * py^2 * p.x + * py' = (py^2 * p.x - p'.x) * l - py^4 (= 2 * p'.y) + * p'.z = py * p.z + * + * Finally: + * p'.y = py' / 2 + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] p ECC point - point on E(F_p^2) to double. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] n Number of times to double. + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_dbl_n_32(sp_digit* vx, sp_digit* vy, + sp_point_1024* p, const sp_point_1024* q, int n, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 32; + sp_digit* pz2 = t + 2 * 32; + sp_digit* rx = t + 4 * 32; + sp_digit* ry = t + 6 * 32; + sp_digit* l = t + 8 * 32; + sp_digit* ty = t + 10 * 32; + int i; + + /* py = 2 * p.y */ + sp_1024_mont_dbl_32(p->y, p->y, p1024_mod); + + for (i = 0; i < n; i++) { + /* v = v^2 */ + sp_1024_proj_sqr_32(vx, vy, t); + /* pz2 = p.z^2 */ + sp_1024_mont_sqr_32(pz2, p->z, p1024_mod, p1024_mp_mod); + /* t1 = p.x + p.z^2 */ + sp_1024_mont_add_32(t1, p->x, pz2, p1024_mod); + /* l = p.x - p.z^2 */ + sp_1024_mont_sub_32(l, p->x, pz2, p1024_mod); + /* t1 = (p.x + p.z^2) * (p.x - p.z^2) = p.x^2 - p.z^4 */ + sp_1024_mont_mul_32(ty, l, t1, p1024_mod, p1024_mp_mod); + /* l = 3 * (p.x^2 - p.z^4) */ + sp_1024_mont_tpl_32(l, ty, p1024_mod); + /* t1 = q.x * p.z^2 */ + sp_1024_mont_mul_32(t1, q->x, pz2, p1024_mod, p1024_mp_mod); + /* t1 = p.x + q.x * p.z^2 */ + sp_1024_mont_add_32(t1, p->x, t1, p1024_mod); + /* r.x = l * (p.x + q.x * p.z^2) */ + sp_1024_mont_mul_32(rx, l, t1, p1024_mod, p1024_mp_mod); + /* ty = py ^ 2 */ + sp_1024_mont_sqr_32(ty, p->y, p1024_mod, p1024_mp_mod); + /* t1 = py ^ 2 / 2 */ + sp_1024_div2_32(t1, ty, p1024_mod); + /* r.x -= py ^ 2 / 2 */ + sp_1024_mont_sub_32(rx, rx, t1, p1024_mod); + /* p'.z = py * pz */ + sp_1024_mont_mul_32(p->z, p->z, p->y, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 */ + sp_1024_mont_mul_32(t1, p->z, pz2, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 * q.y */ + sp_1024_mont_mul_32(ry, t1, q->y, p1024_mod, p1024_mp_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_32(vx, vy, rx, ry, t); + + /* Double point using previously calculated values + * l = 3 * (p.x - p.z^2).(p.x + p.z^2) + * ty = py^2 + * p'.z = py * p.z + */ + /* t1 = py^2 ^ 2 = py^4 */ + sp_1024_mont_sqr_32(t1, ty, p1024_mod, p1024_mp_mod); + /* py' = py^2 * p. x */ + sp_1024_mont_mul_32(p->y, ty, p->x, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 */ + sp_1024_mont_sqr_32(p->x, l, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 - py^2 * p.x */ + sp_1024_mont_sub_32(p->x, p->x, p->y, p1024_mod); + /* p'.x = l^2 - 2 * p.y^2 * p.x */ + sp_1024_mont_sub_32(p->x, p->x, p->y, p1024_mod); + /* py' = py^2 * p.x - p.x' */ + sp_1024_mont_sub_32(ty, p->y, p->x, p1024_mod); + /* py' = (p.y^2 * p.x - p'.x) * l */ + sp_1024_mont_mul_32(p->y, ty, l, p1024_mod, p1024_mp_mod); + /* py' = (p.y^2 * p.x - p'.x) * l * 2 */ + sp_1024_mont_dbl_32(p->y, p->y, p1024_mod); + /* py' = (p.y^2 * p.x - p'.x) * l * 2 - p.y^4 */ + sp_1024_mont_sub_32(p->y, p->y, t1, p1024_mod); + } + + /* p'.y = py' / 2 */ + sp_1024_div2_32(p->y, p->y, p1024_mod); +} + +/* Operations to perform based on order - 1. + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * Pairs: #dbls, add/subtract window value + */ +static const signed char sp_1024_order_op[] = { + 5, 6, -13, 9, -21, 6, -5, 8, 31, 6, 3, 6, -27, 6, 25, 9, + -1, 6, -11, 6, -13, 6, -7, 6, -15, 6, -29, 7, 25, 6, -9, 6, + -19, 7, 3, 6, 11, 9, -23, 6, 1, 6, 27, 6, 1, 7, -25, 8, + 13, 7, -13, 7, -23, 10, 19, 7, 7, 7, -3, 7, 27, 6, -7, 7, + -21, 7, 11, 7, 31, 8, 1, 7, -23, 6, -17, 6, -3, 10, 11, 6, + -21, 7, -27, 11, -29, 6, -1, 10, 15, 8, 27, 7, 17, 6, 17, 7, + -13, 8, 13, 6, 21, 7, -29, 6, 19, 7, -25, 6, 11, 9, 29, 7, + -7, 8, 27, 7, 29, 10, -1, 8, -7, 8, 17, 6, 17, 7, -27, 7, + -21, 6, -9, 6, -27, 12, -23, 6, 19, 6, 13, 6, -11, 7, 27, 6, + 17, 6, -7, 6, -25, 7, -29, 6, 9, 7, 7, 6, 13, 6, -25, 6, + -19, 6, 13, 6, -11, 6, 5, 8, 19, 6, -21, 8, 23, 7, 27, 6, + -13, 6, -19, 11, 29, 7, -15, 6, -9, 7, -21, 10, -3, 7, 21, 10, + 25, 6, -15, 6, -23, 6, 21, 6, 1, 6, 21, 7, -3, 6, -3, 7, + -7, 6, -23, 7, 7, 8, 15, 9, 5, 6, -11, 6, 21, 11, -27, 7, + 27, 6, -11, 6, 31, 6, -21, 6, 19, 6, -7, 8, -7, 13, -3, 6, + -7, 7, -3, 6, 1, 6, 7, 8, 19, 8, 11, 9, -9, 7, -31, 12, + 25, 6, -17, 9, -15, 7, 5, 6, 25, 7, -5, 7, -25, 6, 17, 8, + -19, 6, -13, 6, 27, 8, 1, 7, -5, 7, -1, 6, 21, 6, 3, 10, + -3, 1, +}; +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int sp_Pairing_1024(const ecc_point* pm, const ecc_point* qm, mp_int* res) +{ + int err; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit (*pre_vx)[64]; + sp_digit (*pre_vy)[64]; + sp_digit (*pre_nvy)[64]; + sp_point_1024* pre_p; +#else + sp_digit t[6 * 2 * 32]; + sp_digit vx[2 * 32]; + sp_digit vy[2 * 32]; + sp_digit pre_vx[16][64]; + sp_digit pre_vy[16][64]; + sp_digit pre_nvy[16][64]; + sp_point_1024 pre_p[16]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + int j; + + err = sp_1024_point_new_32(NULL, pd, p); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 56 * 32 * 2 + 16 * sizeof(sp_point_1024), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 32 * 2; + vy = td + 7 * 32 * 2; + pre_vx = (sp_digit(*)[64])(td + 8 * 32 * 2); + pre_vy = (sp_digit(*)[64])(td + 24 * 32 * 2); + pre_nvy = (sp_digit(*)[64])(td + 40 * 32 * 2); + pre_p = (sp_point_1024*)(td + 56 * 32 * 2); +#endif + r = vy; + + sp_1024_point_from_ecc_point_32(p, pm); + sp_1024_point_from_ecc_point_32(q, qm); + + err = sp_1024_mod_mul_norm_32(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMCPY(&pre_p[0], p, sizeof(sp_point_1024)); + XMEMSET(pre_vx[0], 0, sizeof(sp_digit) * 2 * 32); + pre_vx[0][0] = 1; + XMEMSET(pre_vy[0], 0, sizeof(sp_digit) * 2 * 32); + sp_1024_mont_sub_32(pre_nvy[0], p1024_mod, pre_vy[0], p1024_mod); + + /* [2]P for adding */ + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 32); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 32); + sp_1024_accumulate_line_dbl_32(vx, vy, c, q, t); + + /* 3, 5, ... */ + for (i = 1; i < 16; i++) { + XMEMCPY(&pre_p[i], &pre_p[i-1], sizeof(sp_point_1024)); + XMEMCPY(pre_vx[i], pre_vx[i-1], sizeof(sp_digit) * 2 * 32); + XMEMCPY(pre_vy[i], pre_vy[i-1], sizeof(sp_digit) * 2 * 32); + sp_1024_proj_mul_32(pre_vx[i], pre_vy[i], vx, vy, t); + sp_1024_accumulate_line_add_n_32(pre_vx[i], pre_vy[i], c, + q, &pre_p[i], t, 0); + sp_1024_mont_sub_32(pre_nvy[i], p1024_mod, pre_vy[i], p1024_mod); + } + + j = sp_1024_order_op[0] / 2; + XMEMCPY(c, &pre_p[j], sizeof(sp_point_1024)); + XMEMCPY(vx, pre_vx[j], sizeof(sp_digit) * 2 * 32); + XMEMCPY(vy, pre_vy[j], sizeof(sp_digit) * 2 * 32); + + /* Accumulate line into v and double point n times. */ + sp_1024_accumulate_line_dbl_n_32(vx, vy, c, q, + sp_1024_order_op[1], t); + + for (i = 2; i < 290; i += 2) { + j = sp_1024_order_op[i]; + if (j > 0) { + j /= 2; + /* Accumulate line into v and add P into C. */ + sp_1024_proj_mul_32(vx, vy, pre_vx[j], pre_vy[j], t); + sp_1024_accumulate_line_add_n_32(vx, vy, &pre_p[j], q, c, + t, 0); + } + else { + j = -j / 2; + /* Accumulate line into v and add P into C. */ + sp_1024_proj_mul_32(vx, vy, pre_vx[j], pre_nvy[j], t); + sp_1024_accumulate_line_add_n_32(vx, vy, &pre_p[j], q, c, + t, 1); + } + + /* Accumulate line into v and double point n times. */ + sp_1024_accumulate_line_dbl_n_32(vx, vy, c, q, + sp_1024_order_op[i + 1], t); + } + + /* Final exponentiation */ + sp_1024_proj_sqr_32(vx, vy, t); + sp_1024_proj_sqr_32(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_32(vx, vx, t); + sp_1024_mont_mul_32(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 32, 0, sizeof(sp_digit) * 32); + sp_1024_mont_reduce_32(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_32(c, 1, NULL); + sp_1024_point_free_32(q, 1, NULL); + sp_1024_point_free_32(p, 1, NULL); + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_SMALL +/* + * Generate table for pairing. + * + * Small implementation does not use a table - returns 0 length. + * + * pm [in] Point to generate table for. + * table [in] Generated table. + * len [in,out] On in, the size of the buffer. + * On out, length of table generated. + * @return 0 on success. + * LENGTH_ONLY_E when table is NULL and only length returned. + * BUFFER_E when len is too small. + */ +int sp_Pairing_gen_precomp_1024(const ecc_point* pm, byte* table, + word32* len) +{ + int err = 0; + + if (table == NULL) { + *len = 0; + err = LENGTH_ONLY_E; + } + else if (*len != 0) { + err = BUFFER_E; + } + + (void)*pm; + + return err; +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Small implementation does not use a table - use the normal implementation. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @param [in] table Precomputed table of values. + * @param [in] len Length of precomputed table of values in bytes. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int sp_Pairing_precomp_1024(const ecc_point* pm, const ecc_point* qm, + mp_int* res, const byte* table, word32 len) +{ + (void)table; + (void)len; + return sp_Pairing_1024(pm, qm, res); +} + +#else +/* + * Calc l and c for the point when doubling p. + * + * l = 3 * (p.x^2 - 1) / (2 * p.y) + * c = l * p.x - p.y + * + * @param [out] lr Gradient result - table entry. + * @param [out] cr Constant result - table entry. + * @param [in] px X-ordinate of point to double. + * @param [in] py Y-ordinate of point to double. + * @param [in] t SP temporaries (3 used). + */ +static void sp_1024_accum_dbl_calc_lc_32(sp_digit* lr, sp_digit* cr, + const sp_digit* px, const sp_digit* py, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 2 * 32; + sp_digit* t2 = t + 2 * 2 * 32; + sp_digit* l = t + 4 * 2 * 32; + + + /* l = 1 / 2 * p.y */ + sp_1024_mont_dbl_32(l, py, p1024_mod); + sp_1024_mont_inv_32(l, l, t); + + /* t1 = p.x^2 */ + sp_1024_mont_sqr_32(t1, px, p1024_mod, p1024_mp_mod); + /* t1 = p.x - 1 */ + sp_1024_mont_sub_32(t1, t1, p1024_norm_mod, p1024_mod); + /* t1 = 3 * (p.x^2 - 1) */ + sp_1024_mont_dbl_32(t2, t1, p1024_mod); + sp_1024_mont_add_32(t1, t1, t2, p1024_mod); + /* t1 = 3 * (p.x^2 - 1) / (2 * p.y) */ + sp_1024_mont_mul_32(l, l, t1, p1024_mod, p1024_mp_mod); + /* t2 = l * p.x */ + sp_1024_mont_mul_32(t2, l, px, p1024_mod, p1024_mp_mod); + /* c = t2 = l * p.x - p.y */ + sp_1024_mont_sub_32(t2, t2, py, p1024_mod); + + XMEMCPY(lr, l, sizeof(sp_digit) * 32); + XMEMCPY(cr, t2, sizeof(sp_digit) * 32); +} + +/* + * Calc l and c when adding p and c. + * + * l = (c.y - p.y) / (c.x - p.x) + * c = (p.x * c.y - cx * p.y) / (cx - p.x) + * + * @param [out] lr Gradient result - table entry. + * @param [out] cr Constant result - table entry. + * @param [in] px X-ordinate of point to add. + * @param [in] py Y-ordinate of point to add. + * @param [in] cx X-ordinate of current point. + * @param [in] cy Y-ordinate of current point. + * @param [in] t SP temporaries (3 used). + */ +static void sp_1024_accum_add_calc_lc_32(sp_digit* lr, sp_digit* cr, + const sp_digit* px, const sp_digit* py, const sp_digit* cx, + const sp_digit* cy, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 2 * 32; + sp_digit* c = t + 2 * 2 * 32; + sp_digit* l = t + 4 * 2 * 32; + + + /* l = 1 / (c.x - p.x) */ + sp_1024_mont_sub_32(l, cx, px, p1024_mod); + sp_1024_mont_inv_32(l, l, t); + + /* c = p.x * c.y */ + sp_1024_mont_mul_32(c, px, cy, p1024_mod, p1024_mp_mod); + /* t1 = c.x * p.y */ + sp_1024_mont_mul_32(t1, cx, py, p1024_mod, p1024_mp_mod); + /* c = (p.x * c.y) - (c.x * p.y) */ + sp_1024_mont_sub_32(c, c, t1, p1024_mod); + /* c = ((p.x * c.y) - (c.x * p.y)) / (c.x - p.x) */ + sp_1024_mont_mul_32(c, c, l, p1024_mod, p1024_mp_mod); + /* t1 = c.y - p.y */ + sp_1024_mont_sub_32(t1, cy, py, p1024_mod); + /* l = (c.y - p.y) / (c.x - p.x) */ + sp_1024_mont_mul_32(l, t1, l, p1024_mod, p1024_mp_mod); + + XMEMCPY(lr, l, sizeof(sp_digit) * 32); + XMEMCPY(cr, c, sizeof(sp_digit) * 32); +} + +/* + * Calculate vx and vy given gradient l and constant c and point q. + * + * l is a the gradient and is multiplied by q->x. + * c is a the constant that is added to the multiplicative result. + * q->y is the y-ordinate in result to multiply. + * + * if dbl + * v* = v*^2 + * r.x = l * q.x + c + * r.y = q->y + * v* = v* * r* + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in] l Gradient to multiply with. + * @param [in] c Constant to add with. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] t SP temporaries (3 used). + * @param [in] dbl Indicates whether this is for doubling. Otherwise + * adding. + */ +static void sp_1024_accumulate_line_lc_32(sp_digit* vx, sp_digit* vy, + const sp_digit* l, const sp_digit* c, const sp_point_1024* q, + sp_digit* t, int dbl) +{ + sp_digit* rx = t + 4 * 2 * 32; + + /* v = v^2 */ + if (dbl) { + sp_1024_proj_sqr_32(vx, vy, t); + } + /* rx = l * q.x + c */ + sp_1024_mont_mul_32(rx, l, q->x, p1024_mod, p1024_mp_mod); + sp_1024_mont_add_32(rx, rx, c, p1024_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_32(vx, vy, rx, q->y, t); +} + +/* Operations to perform based on order - 1. + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * Pairs: #dbls, add/subtract window value + */ +static const signed char sp_1024_order_op_pre[] = { + 5, 6, -13, 9, -21, 6, -5, 8, 31, 6, 3, 6, -27, 6, 25, 9, + -1, 6, -11, 6, -13, 6, -7, 6, -15, 6, -29, 7, 25, 6, -9, 6, + -19, 7, 3, 6, 11, 9, -23, 6, 1, 6, 27, 6, 1, 7, -25, 8, + 13, 7, -13, 7, -23, 10, 19, 7, 7, 7, -3, 7, 27, 6, -7, 7, + -21, 7, 11, 7, 31, 8, 1, 7, -23, 6, -17, 6, -3, 10, 11, 6, + -21, 7, -27, 11, -29, 6, -1, 10, 15, 8, 27, 7, 17, 6, 17, 7, + -13, 8, 13, 6, 21, 7, -29, 6, 19, 7, -25, 6, 11, 9, 29, 7, + -7, 8, 27, 7, 29, 10, -1, 8, -7, 8, 17, 6, 17, 7, -27, 7, + -21, 6, -9, 6, -27, 12, -23, 6, 19, 6, 13, 6, -11, 7, 27, 6, + 17, 6, -7, 6, -25, 7, -29, 6, 9, 7, 7, 6, 13, 6, -25, 6, + -19, 6, 13, 6, -11, 6, 5, 8, 19, 6, -21, 8, 23, 7, 27, 6, + -13, 6, -19, 11, 29, 7, -15, 6, -9, 7, -21, 10, -3, 7, 21, 10, + 25, 6, -15, 6, -23, 6, 21, 6, 1, 6, 21, 7, -3, 6, -3, 7, + -7, 6, -23, 7, 7, 8, 15, 9, 5, 6, -11, 6, 21, 11, -27, 7, + 27, 6, -11, 6, 31, 6, -21, 6, 19, 6, -7, 8, -7, 13, -3, 6, + -7, 7, -3, 6, 1, 6, 7, 8, 19, 8, 11, 9, -9, 7, -31, 12, + 25, 6, -17, 9, -15, 7, 5, 6, 25, 7, -5, 7, -25, 6, 17, 8, + -19, 6, -13, 6, 27, 8, 1, 7, -5, 7, -1, 6, 21, 6, 3, 10, + -3, 1, +}; + +/* + * Generate table for pairing. + * + * Calculate the graident (l) and constant (c) at each step of the way. + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * + * pm [in] Point to generate table for. + * table [in] Generated table. + * len [in,out] On in, the size of the buffer. + * On out, length of table generated. + * @return 0 on success. + * LENGTH_ONLY_E when table is NULL and only length returned. + * BUFFER_E when len is too small. + * MEMORY_E when dynamic memory allocation fauls. + */ +int sp_Pairing_gen_precomp_1024(const ecc_point* pm, byte* table, + word32* len) +{ + int err = 0; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_point_1024* pre_p; +#else + sp_digit t[6 * 2 * 32]; + sp_point_1024 pre_p[16]; + sp_point_1024 pd; + sp_point_1024 cd; + sp_point_1024 negd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* c = NULL; + sp_point_1024* neg = NULL; + int i; + int j; + int k; + sp_table_entry_1024* precomp = (sp_table_entry_1024*)table; + + if (table == NULL) { + *len = sizeof(sp_table_entry_1024) * 1167; + err = LENGTH_ONLY_E; + } + + if ((err == MP_OKAY) && + (*len < (int)(sizeof(sp_table_entry_1024) * 1167))) { + err = BUFFER_E; + } + + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, pd, p); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, cd, c); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, negd, neg); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6 * 32 * 2 + 16 * sizeof(sp_point_1024), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + pre_p = (sp_point_1024*)(td + 6 * 32 * 2); +#endif + + sp_1024_point_from_ecc_point_32(p, pm); + + err = sp_1024_mod_mul_norm_32(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(p->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + neg->infinity = 0; + c->infinity = 0; + + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMCPY(&pre_p[0], p, sizeof(sp_point_1024)); + /* [2]P for adding */ + sp_1024_proj_point_dbl_32(c, p, t); + + /* 1, 3, ... */ + for (i = 1; i < 16; i++) { + sp_1024_proj_point_add_32(&pre_p[i], &pre_p[i-1], c, t); + sp_1024_mont_map_32(&pre_p[i], t); + } + + k = 0; + j = sp_1024_order_op_pre[0] / 2; + XMEMCPY(c, &pre_p[j], sizeof(sp_point_1024)); + + for (j = 0; j < sp_1024_order_op_pre[1]; j++) { + sp_1024_accum_dbl_calc_lc_32(precomp[k].x, precomp[k].y, c->x, c->y, t); + k++; + sp_1024_proj_point_dbl_32(c, c, t); + sp_1024_mont_map_32(c, t); + } + + for (i = 2; i < 290; i += 2) { + j = sp_1024_order_op_pre[i]; + if (j > 0) { + sp_1024_accum_add_calc_lc_32(precomp[k].x, precomp[k].y, + pre_p[j/2].x, pre_p[j/2].y, c->x, c->y, t); + k++; + sp_1024_proj_point_add_32(c, c, &pre_p[j/2], t); + sp_1024_mont_map_32(c, t); + } + else { + XMEMCPY(neg->x, pre_p[-j / 2].x, sizeof(pre_p->x)); + sp_1024_mont_sub_32(neg->y, p1024_mod, pre_p[-j / 2].y, + p1024_mod); + XMEMCPY(neg->z, pre_p[-j / 2].z, sizeof(pre_p->z)); + + sp_1024_accum_add_calc_lc_32(precomp[k].x, precomp[k].y, + neg->x, neg->y, c->x, c->y, t); + k++; + sp_1024_proj_point_add_32(c, c, neg, t); + sp_1024_mont_map_32(c, t); + } + + for (j = 0; j < sp_1024_order_op_pre[i + 1]; j++) { + sp_1024_accum_dbl_calc_lc_32(precomp[k].x, precomp[k].y, c->x, c->y, t); + k++; + sp_1024_proj_point_dbl_32(c, c, t); + sp_1024_mont_map_32(c, t); + } + } + + *len = sizeof(sp_table_entry_1024) * 1167; + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_32(neg, 1, NULL); + sp_1024_point_free_32(c, 1, NULL); + sp_1024_point_free_32(p, 1, NULL); + return err; +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * Pre-generate values in window (1, 3, ...) - only V. + * Table contains all gradient l and a constant for each point on the path. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @param [in] table Precomputed table of values. + * @param [in] len Length of precomputed table of values in bytes. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int sp_Pairing_precomp_1024(const ecc_point* pm, const ecc_point* qm, + mp_int* res, const byte* table, word32 len) +{ + int err = 0; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit (*pre_vx)[64]; + sp_digit (*pre_vy)[64]; + sp_digit (*pre_nvy)[64]; +#else + sp_digit t[6 * 2 * 32]; + sp_digit vx[2 * 32]; + sp_digit vy[2 * 32]; + sp_digit pre_vx[16][64]; + sp_digit pre_vy[16][64]; + sp_digit pre_nvy[16][64]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + int j; + int k; + const sp_table_entry_1024* precomp = (const sp_table_entry_1024*)table; + + if (len < (int)(sizeof(sp_table_entry_1024) * 1167)) { + err = BUFFER_E; + } + + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, pd, p); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_32(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 56 * 32 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 32 * 2; + vy = td + 7 * 32 * 2; + pre_vx = (sp_digit(*)[64])(td + 8 * 32 * 2); + pre_vy = (sp_digit(*)[64])(td + 24 * 32 * 2); + pre_nvy = (sp_digit(*)[64])(td + 40 * 32 * 2); +#endif + r = vy; + + sp_1024_point_from_ecc_point_32(p, pm); + sp_1024_point_from_ecc_point_32(q, qm); + + err = sp_1024_mod_mul_norm_32(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_32(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMSET(pre_vx[0], 0, sizeof(sp_digit) * 2 * 32); + pre_vx[0][0] = 1; + XMEMSET(pre_vy[0], 0, sizeof(sp_digit) * 2 * 32); + sp_1024_mont_sub_32(pre_nvy[0], p1024_mod, pre_vy[0], p1024_mod); + + /* [2]P for adding */ + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 32); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 32); + sp_1024_accumulate_line_dbl_32(vx, vy, c, q, t); + + /* 3, 5, ... */ + for (i = 1; i < 16; i++) { + XMEMCPY(pre_vx[i], pre_vx[i-1], sizeof(sp_digit) * 2 * 32); + XMEMCPY(pre_vy[i], pre_vy[i-1], sizeof(sp_digit) * 2 * 32); + sp_1024_proj_mul_32(pre_vx[i], pre_vy[i], vx, vy, t); + sp_1024_accumulate_line_add_n_32(pre_vx[i], pre_vy[i], c, + q, p, t, 0); + sp_1024_mont_sub_32(pre_nvy[i], p1024_mod, pre_vy[i], + p1024_mod); + } + + XMEMCPY(c->z, p1024_norm_mod, sizeof(sp_digit) * 32); + c->infinity = 0; + j = sp_1024_order_op_pre[0] / 2; + XMEMCPY(vx, pre_vx[j], sizeof(sp_digit) * 2 * 32); + XMEMCPY(vy, pre_vy[j], sizeof(sp_digit) * 2 * 32); + + k = 0; + for (j = 0; j < sp_1024_order_op_pre[1]; j++) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_lc_32(vx, vy, precomp[k].x, + precomp[k].y, q, t, 1); + k++; + } + + for (i = 2; i < 290; i += 2) { + sp_1024_accumulate_line_lc_32(vx, vy, precomp[k].x, + precomp[k].y, q, t, 0); + k++; + + j = sp_1024_order_op_pre[i]; + if (j > 0) { + j /= 2; + /* Accumulate line into v. */ + sp_1024_proj_mul_32(vx, vy, pre_vx[j], pre_vy[j], t); + } + else { + j = -j / 2; + /* Accumulate line into v. */ + sp_1024_proj_mul_32(vx, vy, pre_vx[j], pre_nvy[j], t); + } + + for (j = 0; j < sp_1024_order_op_pre[i + 1]; j++) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_lc_32(vx, vy, precomp[k].x, + precomp[k].y, q, t, 1); + k++; + } + } + + /* Final exponentiation */ + sp_1024_proj_sqr_32(vx, vy, t); + sp_1024_proj_sqr_32(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_32(vx, vx, t); + sp_1024_mont_mul_32(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 32, 0, sizeof(sp_digit) * 32); + sp_1024_mont_reduce_32(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_32(c, 1, NULL); + sp_1024_point_free_32(q, 1, NULL); + sp_1024_point_free_32(p, 1, NULL); + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +/* Returns 1 if the number of zero. + * Implementation is constant time. + * + * a Number to check. + * returns 1 if the number is zero and 0 otherwise. + */ +static int sp_1024_iszero_32(const sp_digit* a) +{ + return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6] | a[7] | + a[8] | a[9] | a[10] | a[11] | a[12] | a[13] | a[14] | a[15] | + a[16] | a[17] | a[18] | a[19] | a[20] | a[21] | a[22] | a[23] | + a[24] | a[25] | a[26] | a[27] | a[28] | a[29] | a[30] | a[31]) == 0; +} + +#ifdef HAVE_ECC_CHECK_KEY +/* Read big endian unsigned byte array into r. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a Byte array. + * n Number of bytes in array to read. + */ +static void sp_1024_from_bin(sp_digit* r, int size, const byte* a, int n) +{ + int i; + int j = 0; + word32 s = 0; + + r[0] = 0; + for (i = n-1; i >= 0; i--) { + r[j] |= (((sp_digit)a[i]) << s); + if (s >= 24U) { + r[j] &= 0xffffffff; + s = 32U - s; + if (j + 1 >= size) { + break; + } + r[++j] = (sp_digit)a[i] >> s; + s = 8U - s; + } + else { + s += 8U; + } + } + + for (j++; j < size; j++) { + r[j] = 0; + } +} + +/* Check that the x and y oridinates are a valid point on the curve. + * + * point EC point. + * heap Heap to use if dynamically allocating. + * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is + * not on the curve and MP_OKAY otherwise. + */ +static int sp_1024_ecc_is_point_32(const sp_point_1024* point, + void* heap) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* d = NULL; +#else + sp_digit t1d[2*32]; + sp_digit t2d[2*32]; +#endif + sp_digit* t1; + sp_digit* t2; + int32_t n; + int err = MP_OKAY; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 4, heap, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + (void)heap; + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t1 = d + 0 * 32; + t2 = d + 2 * 32; +#else + t1 = t1d; + t2 = t2d; +#endif + + sp_1024_sqr_32(t1, point->y); + (void)sp_1024_mod_32(t1, t1, p1024_mod); + sp_1024_sqr_32(t2, point->x); + (void)sp_1024_mod_32(t2, t2, p1024_mod); + sp_1024_mul_32(t2, t2, point->x); + (void)sp_1024_mod_32(t2, t2, p1024_mod); + (void)sp_1024_sub_32(t2, p1024_mod, t2); + sp_1024_mont_add_32(t1, t1, t2, p1024_mod); + + sp_1024_mont_add_32(t1, t1, point->x, p1024_mod); + sp_1024_mont_add_32(t1, t1, point->x, p1024_mod); + sp_1024_mont_add_32(t1, t1, point->x, p1024_mod); + + n = sp_1024_cmp_32(t1, p1024_mod); + sp_1024_cond_sub_32(t1, t1, p1024_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_32(t1); + if (!sp_1024_iszero_32(t1)) { + err = MP_VAL; + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (d != NULL) { + XFREE(d, heap, DYNAMIC_TYPE_ECC); + } +#endif + + return err; +} + +/* Check that the x and y oridinates are a valid point on the curve. + * + * pX X ordinate of EC point. + * pY Y ordinate of EC point. + * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is + * not on the curve and MP_OKAY otherwise. + */ +int sp_ecc_is_point_1024(const mp_int* pX, const mp_int* pY) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 pubd; +#endif + sp_point_1024* pub; + byte one[1] = { 1 }; + int err; + + err = sp_1024_point_new_32(NULL, pubd, pub); + if (err == MP_OKAY) { + sp_1024_from_mp(pub->x, 32, pX); + sp_1024_from_mp(pub->y, 32, pY); + sp_1024_from_bin(pub->z, 32, one, (int)sizeof(one)); + + err = sp_1024_ecc_is_point_32(pub, NULL); + } + + sp_1024_point_free_32(pub, 0, NULL); + + return err; +} + +/* Check that the private scalar generates the EC point (px, py), the point is + * on the curve and the point has the correct order. + * + * pX X ordinate of EC point. + * pY Y ordinate of EC point. + * privm Private scalar that generates EC point. + * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is + * not on the curve, ECC_INF_E if the point does not have the correct order, + * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and + * MP_OKAY otherwise. + */ +int sp_ecc_check_key_1024(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_digit privd[32]; + sp_point_1024 pubd; + sp_point_1024 pd; +#endif + sp_digit* priv = NULL; + sp_point_1024* pub; + sp_point_1024* p = NULL; + byte one[1] = { 1 }; + int err; + + err = sp_1024_point_new_32(heap, pubd, pub); + if (err == MP_OKAY) { + err = sp_1024_point_new_32(heap, pd, p); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY && privm) { + priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32, heap, + DYNAMIC_TYPE_ECC); + if (priv == NULL) { + err = MEMORY_E; + } + } +#endif + + /* Quick check the lengs of public key ordinates and private key are in + * range. Proper check later. + */ + if ((err == MP_OKAY) && ((mp_count_bits(pX) > 1024) || + (mp_count_bits(pY) > 1024) || + ((privm != NULL) && (mp_count_bits(privm) > 1024)))) { + err = ECC_OUT_OF_RANGE_E; + } + + if (err == MP_OKAY) { +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + priv = privd; +#endif + + sp_1024_from_mp(pub->x, 32, pX); + sp_1024_from_mp(pub->y, 32, pY); + sp_1024_from_bin(pub->z, 32, one, (int)sizeof(one)); + if (privm) + sp_1024_from_mp(priv, 32, privm); + + /* Check point at infinitiy. */ + if ((sp_1024_iszero_32(pub->x) != 0) && + (sp_1024_iszero_32(pub->y) != 0)) { + err = ECC_INF_E; + } + } + + /* Check range of X and Y */ + if ((err == MP_OKAY) && + ((sp_1024_cmp_32(pub->x, p1024_mod) >= 0) || + (sp_1024_cmp_32(pub->y, p1024_mod) >= 0))) { + err = ECC_OUT_OF_RANGE_E; + } + + if (err == MP_OKAY) { + /* Check point is on curve */ + err = sp_1024_ecc_is_point_32(pub, heap); + } + + if (err == MP_OKAY) { + /* Point * order = infinity */ + err = sp_1024_ecc_mulmod_32(p, pub, p1024_order, 1, 1, heap); + } + /* Check result is infinity */ + if ((err == MP_OKAY) && ((sp_1024_iszero_32(p->x) == 0) || + (sp_1024_iszero_32(p->y) == 0))) { + err = ECC_INF_E; + } + + if (privm) { + if (err == MP_OKAY) { + /* Base * private = point */ + err = sp_1024_ecc_mulmod_base_32(p, priv, 1, 1, heap); + } + /* Check result is public key */ + if ((err == MP_OKAY) && + ((sp_1024_cmp_32(p->x, pub->x) != 0) || + (sp_1024_cmp_32(p->y, pub->y) != 0))) { + err = ECC_PRIV_KEY_E; + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (priv != NULL) { + XFREE(priv, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_32(p, 0, heap); + sp_1024_point_free_32(pub, 0, heap); + + return err; +} +#endif +#endif /* WOLFSSL_SP_1024 */ #endif /* WOLFSSL_HAVE_SP_ECC */ #endif /* WOLFSSL_SP_ARM_CORTEX_M_ASM */ -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH || WOLFSSL_HAVE_SP_ECC */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH | WOLFSSL_HAVE_SP_ECC */ diff --git a/wolfcrypt/src/sp_dsp32.c b/wolfcrypt/src/sp_dsp32.c index 38d6dc721..b132e5a40 100644 --- a/wolfcrypt/src/sp_dsp32.c +++ b/wolfcrypt/src/sp_dsp32.c @@ -1,6 +1,6 @@ /* sp_cdsp_signed.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index 77a59b3ae..cc6d89915 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -1,6 +1,6 @@ /* sp_int.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -77,6 +77,8 @@ This library provides single precision (SP) integer math functions. * called again until complete. * WOLFSSL_SP_FAST_NCT_EXPTMOD Enables the faster non-constant time modular * exponentation implementation. + * WOLFSSL_SP_INT_DIGIT_ALIGN Enable when unaligned access of sp_int_digit + * pointer is not allowed. */ #if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) @@ -2364,7 +2366,7 @@ void sp_forcezero(sp_int* a) * * @return MP_OKAY on success. */ -int sp_copy(sp_int* a, sp_int* r) +int sp_copy(const sp_int* a, sp_int* r) { int err = MP_OKAY; @@ -2686,7 +2688,7 @@ int sp_is_bit_set(sp_int* a, unsigned int b) * * @return The number of bits in the number. */ -int sp_count_bits(sp_int* a) +int sp_count_bits(const sp_int* a) { int r = 0; @@ -2997,7 +2999,8 @@ int sp_cmp_d(sp_int* a, sp_int_digit d) #if defined(WOLFSSL_SP_INT_NEGATIVE) || !defined(NO_PWDBASED) || \ defined(WOLFSSL_KEY_GEN) || !defined(NO_DH) || \ - (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) + ((defined(WOLFSSL_SP_MATH_ALL) || !defined(NO_RSA)) && \ + !defined(WOLFSSL_RSA_VERIFY_ONLY)) /* Add a one digit number to the multi-precision number. * * @param [in] a SP integer be added to. @@ -3487,7 +3490,7 @@ static void _sp_div_small(sp_int* a, sp_int_digit d, sp_int* r, #if (defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \ defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) -/* Divide a multi-precision number by a digit size number and calcualte +/* Divide a multi-precision number by a digit size number and calculate * remainder. * r = a / d; rem = a % d * @@ -3958,7 +3961,8 @@ int sp_sub(sp_int* a, sp_int* b, sp_int* r) ****************************/ #if (defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \ - (!defined(WOLFSSL_SP_MATH) && defined(WOLFSSL_CUSTOM_CURVES)) + (!defined(WOLFSSL_SP_MATH) && defined(WOLFSSL_CUSTOM_CURVES)) || \ + defined(WOLFCRYPT_HAVE_ECCSI) || defined(WOLFCRYPT_HAVE_SAKKE) /* Add two value and reduce: r = (a + b) % m * * @param [in] a SP integer to add. @@ -4002,7 +4006,8 @@ int sp_addmod(sp_int* a, sp_int* b, sp_int* m, sp_int* r) FREE_SP_INT(t, NULL); return err; } -#endif /* WOLFSSL_SP_MATH_ALL || (!WOLFSSL_SP_MATH && WOLFSSL_CUSTOM_CURVES) */ +#endif /* WOLFSSL_SP_MATH_ALL || WOLFSSL_CUSTOM_CURVES) || + * WOLFCRYPT_HAVE_ECCSI || WOLFCRYPT_HAVE_SAKKE */ #if defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY) /* Sub b from a and reduce: r = (a - b) % m @@ -4696,7 +4701,7 @@ int sp_mod(sp_int* a, sp_int* m, sp_int* r) err = sp_div(a, m, NULL, r); } #else - ALLOC_SP_INT(t, m->used, err, NULL); + ALLOC_SP_INT(t, a->used + 1, err, NULL); if (err == MP_OKAY) { sp_init_size(t, a->used + 1); err = sp_div(a, m, NULL, t); @@ -7679,7 +7684,8 @@ int sp_mul(sp_int* a, sp_int* b, sp_int* r) } /* END SP_MUL implementations. */ -#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) || \ + defined(WOLFCRYPT_HAVE_ECCSI) /* Multiply a by b mod m and store in r: r = (a * b) mod m * * @param [in] a SP integer to multiply. @@ -11667,7 +11673,8 @@ int sp_sqrmod(sp_int* a, sp_int* m, sp_int* r) * Montogmery functions **********************/ -#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) || \ + defined(WOLFCRYPT_HAVE_ECCSI) || defined(WOLFCRYPT_HAVE_SAKKE) /* Reduce a number in montgomery form. * * Assumes a and m are not NULL and m is not 0. @@ -12063,7 +12070,8 @@ int sp_mont_norm(sp_int* norm, sp_int* m) return err; } -#endif +#endif /* WOLFSSL_SP_MATH_ALL || WOLFSSL_HAVE_SP_DH || + * WOLFCRYPT_HAVE_ECCSI || WOLFCRYPT_HAVE_SAKKE */ /********************************* * To and from binary and strings. @@ -12078,7 +12086,7 @@ int sp_mont_norm(sp_int* norm, sp_int* m) * * @return The count of 8-bit values. */ -int sp_unsigned_bin_size(sp_int* a) +int sp_unsigned_bin_size(const sp_int* a) { int cnt = 0; @@ -12118,9 +12126,29 @@ int sp_read_unsigned_bin(sp_int* a, const byte* in, word32 inSz) int j; int s; + #ifndef WOLFSSL_SP_INT_DIGIT_ALIGN for (i = inSz-1,j = 0; i > SP_WORD_SIZEOF-1; i -= SP_WORD_SIZEOF,j++) { a->dp[j] = *(sp_int_digit*)(in + i - (SP_WORD_SIZEOF - 1)); } + #else + for (i = inSz-1, j = 0; i >= SP_WORD_SIZEOF - 1; i -= SP_WORD_SIZEOF) { + a->dp[j] = ((sp_int_digit)in[i - 0] << 0); + #if SP_WORD_SIZE >= 16 + a->dp[j] |= ((sp_int_digit)in[i - 1] << 8); + #endif + #if SP_WORD_SIZE >= 32 + a->dp[j] |= ((sp_int_digit)in[i - 2] << 16) | + ((sp_int_digit)in[i - 3] << 24); + #endif + #if SP_WORD_SIZE >= 64 + a->dp[j] |= ((sp_int_digit)in[i - 4] << 32) | + ((sp_int_digit)in[i - 5] << 40) | + ((sp_int_digit)in[i - 6] << 48) | + ((sp_int_digit)in[i - 7] << 56); + #endif + j++; + } + #endif a->dp[j] = 0; for (s = 0; i >= 0; i--,s += 8) { a->dp[j] |= ((sp_int_digit)in[i]) << s; diff --git a/wolfcrypt/src/sp_x86_64.c b/wolfcrypt/src/sp_x86_64.c index fd8a9897e..060114fb5 100644 --- a/wolfcrypt/src/sp_x86_64.c +++ b/wolfcrypt/src/sp_x86_64.c @@ -1,6 +1,6 @@ /* sp.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -60,12 +60,15 @@ extern void sp_2048_from_bin_movbe(sp_digit* r, int size, const byte* a, int n); */ static void sp_2048_from_bin(sp_digit* r, int size, const byte* a, int n) { +#ifndef NO_MOVBE_SUPPORT word32 cpuid_flags = cpuid_get_flags(); if (IS_INTEL_MOVBE(cpuid_flags)) { sp_2048_from_bin_movbe(r, size, a, n); } - else { + else +#endif + { sp_2048_from_bin_bswap(r, size, a, n); } } @@ -87,7 +90,8 @@ static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 64 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -121,7 +125,9 @@ static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -162,12 +168,15 @@ extern void sp_2048_to_bin_movbe(sp_digit* r, byte* a); */ static void sp_2048_to_bin(sp_digit* r, byte* a) { +#ifndef NO_MOVBE_SUPPORT word32 cpuid_flags = cpuid_get_flags(); if (IS_INTEL_MOVBE(cpuid_flags)) { sp_2048_to_bin_movbe(r, a); } - else { + else +#endif + { sp_2048_to_bin_bswap(r, a); } } @@ -184,16 +193,13 @@ extern void sp_2048_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* b); extern sp_digit sp_2048_dbl_16(sp_digit* r, const sp_digit* a); extern void sp_2048_sqr_32(sp_digit* r, const sp_digit* a); -#ifdef HAVE_INTEL_AVX2 extern void sp_2048_mul_avx2_32(sp_digit* r, const sp_digit* a, const sp_digit* b); -#endif /* HAVE_INTEL_AVX2 */ -#ifdef HAVE_INTEL_AVX2 extern void sp_2048_sqr_avx2_32(sp_digit* r, const sp_digit* a); -#endif /* HAVE_INTEL_AVX2 */ #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH) -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +extern sp_digit sp_2048_sub_in_place_16(sp_digit* a, const sp_digit* b); +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ /* Caclulate the bottom digit of -1/a mod 2^n. * @@ -202,7 +208,8 @@ extern void sp_2048_sqr_avx2_32(sp_digit* r, const sp_digit* a); */ static void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho) { - sp_digit x, b; + sp_digit x; + sp_digit b; b = a[0]; x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ @@ -212,12 +219,11 @@ static void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho) x *= 2 - b * x; /* here x*a==1 mod 2**64 */ /* rho = -1/m mod b */ - *rho = -x; + *rho = (sp_digit)0 - x; } extern void sp_2048_mul_d_32(sp_digit* r, const sp_digit* a, sp_digit b); #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH) -extern sp_digit sp_2048_sub_in_place_16(sp_digit* a, const sp_digit* b); /* r = 2^n mod m where n is the number of bits to reduce by. * Given m must be 2048 bits, just need to subtract. * @@ -243,8 +249,8 @@ extern void sp_2048_mont_reduce_16(sp_digit* a, const sp_digit* m, sp_digit mp); * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_mul_16(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_2048_mont_mul_16(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_2048_mul_16(r, a, b); sp_2048_mont_reduce_16(r, m, mp); @@ -257,8 +263,8 @@ static void sp_2048_mont_mul_16(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_sqr_16(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_2048_mont_sqr_16(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_2048_sqr_16(r, a); sp_2048_mont_reduce_16(r, m, mp); @@ -267,6 +273,27 @@ static void sp_2048_mont_sqr_16(sp_digit* r, const sp_digit* a, const sp_digit* extern sp_digit sp_2048_cond_sub_avx2_16(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m); extern void sp_2048_mul_d_16(sp_digit* r, const sp_digit* a, sp_digit b); extern void sp_2048_mul_d_avx2_16(sp_digit* r, const sp_digit* a, const sp_digit b); +#ifdef _WIN64 +#if _MSC_VER < 1920 +extern sp_digit div_2048_word_asm_16(sp_digit d1, sp_digit d0, sp_digit div); +#endif /* _MSC_VER < 1920 */ +/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) + * + * d1 The high order half of the number to divide. + * d0 The low order half of the number to divide. + * div The dividend. + * returns the result of the division. + */ +static WC_INLINE sp_digit div_2048_word_16(sp_digit d1, sp_digit d0, + sp_digit div) +{ +#if _MSC_VER >= 1920 + return _udiv128(d1, d0, div, NULL); +#else + return div_2048_word_asm_16(d1, d0, div); +#endif +} +#else /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) * * d1 The high order half of the number to divide. @@ -286,6 +313,7 @@ static WC_INLINE sp_digit div_2048_word_16(sp_digit d1, sp_digit d0, ); return r; } +#endif /* _WIN64 */ /* AND m into each word of a and store in r. * * r A single precision integer. @@ -329,8 +357,10 @@ extern int64_t sp_2048_cmp_16(const sp_digit* a, const sp_digit* b); static WC_INLINE int sp_2048_div_16(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_digit* r) { - sp_digit t1[32], t2[17]; - sp_digit div, r1; + sp_digit t1[32]; + sp_digit t2[17]; + sp_digit div; + sp_digit r1; int i; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); @@ -383,7 +413,8 @@ static WC_INLINE int sp_2048_div_16(const sp_digit* a, const sp_digit* d, sp_dig * m A single precision number that is the modulus to reduce with. * returns MP_OKAY indicating success. */ -static WC_INLINE int sp_2048_mod_16(sp_digit* r, const sp_digit* a, const sp_digit* m) +static WC_INLINE int sp_2048_mod_16(sp_digit* r, const sp_digit* a, + const sp_digit* m) { return sp_2048_div_16(a, m, NULL, r); } @@ -406,13 +437,14 @@ static int sp_2048_mod_exp_16(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit td[(33 * 32) + 32]; #endif sp_digit* t[32]; - sp_digit* rt; + sp_digit* rt = NULL; sp_digit* norm; sp_digit mp = 1; sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -499,34 +531,34 @@ static int sp_2048_mod_exp_16(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 16); for (; i>=0 || c>=5; ) { if (c >= 5) { - y = (int)((n >> 59) & 0x1f); + y = (byte)((n >> 59) & 0x1f); n <<= 5; c -= 5; } else if (c == 0) { n = e[i--]; - y = (int)(n >> 59); + y = (byte)(n >> 59); n <<= 5; c = 59; } else { - y = (int)(n >> 59); + y = (byte)(n >> 59); n = e[i--]; c = 5 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } @@ -572,8 +604,8 @@ extern void sp_2048_mont_reduce_avx2_16(sp_digit* a, const sp_digit* m, sp_digit * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_mul_avx2_16(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_2048_mont_mul_avx2_16(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_2048_mul_avx2_16(r, a, b); sp_2048_mont_reduce_avx2_16(r, m, mp); @@ -588,8 +620,8 @@ static void sp_2048_mont_mul_avx2_16(sp_digit* r, const sp_digit* a, const sp_di * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_sqr_avx2_16(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_2048_mont_sqr_avx2_16(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_2048_sqr_avx2_16(r, a); sp_2048_mont_reduce_avx2_16(r, m, mp); @@ -615,13 +647,14 @@ static int sp_2048_mod_exp_avx2_16(sp_digit* r, const sp_digit* a, const sp_digi sp_digit td[(33 * 32) + 32]; #endif sp_digit* t[32]; - sp_digit* rt; + sp_digit* rt = NULL; sp_digit* norm; sp_digit mp = 1; sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -708,34 +741,34 @@ static int sp_2048_mod_exp_avx2_16(sp_digit* r, const sp_digit* a, const sp_digi if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 16); for (; i>=0 || c>=5; ) { if (c >= 5) { - y = (int)((n >> 59) & 0x1f); + y = (byte)((n >> 59) & 0x1f); n <<= 5; c -= 5; } else if (c == 0) { n = e[i--]; - y = (int)(n >> 59); + y = (byte)(n >> 59); n <<= 5; c = 59; } else { - y = (int)(n >> 59); + y = (byte)(n >> 59); n = e[i--]; c = 5 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } @@ -771,7 +804,7 @@ static int sp_2048_mod_exp_avx2_16(sp_digit* r, const sp_digit* a, const sp_digi } #endif /* HAVE_INTEL_AVX2 */ -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) /* r = 2^n mod m where n is the number of bits to reduce by. @@ -788,7 +821,7 @@ static void sp_2048_mont_norm_32(sp_digit* r, const sp_digit* m) sp_2048_sub_in_place_32(r, m); } -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */ extern sp_digit sp_2048_cond_sub_32(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m); extern void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, sp_digit mp); /* Multiply two Montogmery form numbers mod the modulus (prime). @@ -800,8 +833,8 @@ extern void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, sp_digit mp); * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_2048_mont_mul_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_2048_mul_32(r, a, b); sp_2048_mont_reduce_32(r, m, mp); @@ -814,8 +847,8 @@ static void sp_2048_mont_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_sqr_32(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_2048_mont_sqr_32(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_2048_sqr_32(r, a); sp_2048_mont_reduce_32(r, m, mp); @@ -824,6 +857,27 @@ static void sp_2048_mont_sqr_32(sp_digit* r, const sp_digit* a, const sp_digit* #if defined(WOLFSSL_HAVE_SP_DH) || !defined(WOLFSSL_RSA_PUBLIC_ONLY) extern sp_digit sp_2048_cond_sub_avx2_32(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m); extern void sp_2048_mul_d_avx2_32(sp_digit* r, const sp_digit* a, const sp_digit b); +#ifdef _WIN64 +#if _MSC_VER < 1920 +extern sp_digit div_2048_word_asm_32(sp_digit d1, sp_digit d0, sp_digit div); +#endif /* _MSC_VER < 1920 */ +/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) + * + * d1 The high order half of the number to divide. + * d0 The low order half of the number to divide. + * div The dividend. + * returns the result of the division. + */ +static WC_INLINE sp_digit div_2048_word_32(sp_digit d1, sp_digit d0, + sp_digit div) +{ +#if _MSC_VER >= 1920 + return _udiv128(d1, d0, div, NULL); +#else + return div_2048_word_asm_32(d1, d0, div); +#endif +} +#else /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) * * d1 The high order half of the number to divide. @@ -843,6 +897,7 @@ static WC_INLINE sp_digit div_2048_word_32(sp_digit d1, sp_digit d0, ); return r; } +#endif /* _WIN64 */ /* AND m into each word of a and store in r. * * r A single precision integer. @@ -886,8 +941,10 @@ extern int64_t sp_2048_cmp_32(const sp_digit* a, const sp_digit* b); static WC_INLINE int sp_2048_div_32(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_digit* r) { - sp_digit t1[64], t2[33]; - sp_digit div, r1; + sp_digit t1[64]; + sp_digit t2[33]; + sp_digit div; + sp_digit r1; int i; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); @@ -940,7 +997,8 @@ static WC_INLINE int sp_2048_div_32(const sp_digit* a, const sp_digit* d, sp_dig * m A single precision number that is the modulus to reduce with. * returns MP_OKAY indicating success. */ -static WC_INLINE int sp_2048_mod_32(sp_digit* r, const sp_digit* a, const sp_digit* m) +static WC_INLINE int sp_2048_mod_32(sp_digit* r, const sp_digit* a, + const sp_digit* m) { return sp_2048_div_32(a, m, NULL, r); } @@ -959,8 +1017,10 @@ extern sp_digit sp_2048_sub_32(sp_digit* r, const sp_digit* a, const sp_digit* b static WC_INLINE int sp_2048_div_32_cond(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_digit* r) { - sp_digit t1[64], t2[33]; - sp_digit div, r1; + sp_digit t1[64]; + sp_digit t2[33]; + sp_digit div; + sp_digit r1; int i; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); @@ -1017,7 +1077,8 @@ static WC_INLINE int sp_2048_div_32_cond(const sp_digit* a, const sp_digit* d, s * m A single precision number that is the modulus to reduce with. * returns MP_OKAY indicating success. */ -static WC_INLINE int sp_2048_mod_32_cond(sp_digit* r, const sp_digit* a, const sp_digit* m) +static WC_INLINE int sp_2048_mod_32_cond(sp_digit* r, const sp_digit* a, + const sp_digit* m) { return sp_2048_div_32_cond(a, m, NULL, r); } @@ -1041,13 +1102,14 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit td[(33 * 64) + 64]; #endif sp_digit* t[32]; - sp_digit* rt; + sp_digit* rt = NULL; sp_digit* norm; sp_digit mp = 1; sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -1134,34 +1196,34 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 32); for (; i>=0 || c>=5; ) { if (c >= 5) { - y = (int)((n >> 59) & 0x1f); + y = (byte)((n >> 59) & 0x1f); n <<= 5; c -= 5; } else if (c == 0) { n = e[i--]; - y = (int)(n >> 59); + y = (byte)(n >> 59); n <<= 5; c = 59; } else { - y = (int)(n >> 59); + y = (byte)(n >> 59); n = e[i--]; c = 5 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } @@ -1208,8 +1270,8 @@ extern void sp_2048_mont_reduce_avx2_32(sp_digit* a, const sp_digit* m, sp_digit * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_mul_avx2_32(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_2048_mont_mul_avx2_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_2048_mul_avx2_32(r, a, b); sp_2048_mont_reduce_avx2_32(r, m, mp); @@ -1224,8 +1286,8 @@ static void sp_2048_mont_mul_avx2_32(sp_digit* r, const sp_digit* a, const sp_di * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_2048_mont_sqr_avx2_32(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_2048_mont_sqr_avx2_32(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_2048_sqr_avx2_32(r, a); sp_2048_mont_reduce_avx2_32(r, m, mp); @@ -1252,13 +1314,14 @@ static int sp_2048_mod_exp_avx2_32(sp_digit* r, const sp_digit* a, const sp_digi sp_digit td[(33 * 64) + 64]; #endif sp_digit* t[32]; - sp_digit* rt; + sp_digit* rt = NULL; sp_digit* norm; sp_digit mp = 1; sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -1345,34 +1408,34 @@ static int sp_2048_mod_exp_avx2_32(sp_digit* r, const sp_digit* a, const sp_digi if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 32); for (; i>=0 || c>=5; ) { if (c >= 5) { - y = (int)((n >> 59) & 0x1f); + y = (byte)((n >> 59) & 0x1f); n <<= 5; c -= 5; } else if (c == 0) { n = e[i--]; - y = (int)(n >> 59); + y = (byte)(n >> 59); n <<= 5; c = 59; } else { - y = (int)(n >> 59); + y = (byte)(n >> 59); n = e[i--]; c = 5 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } @@ -1422,11 +1485,13 @@ static int sp_2048_mod_exp_avx2_32(sp_digit* r, const sp_digit* a, const sp_digi * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPublic_2048(const byte* in, word32 inLen, const mp_int* em, + const mp_int* mm, byte* out, word32* outLen) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_digit ad[64], md[32], rd[64]; + sp_digit ad[64]; + sp_digit md[32]; + sp_digit rd[64]; #else sp_digit* d = NULL; #endif @@ -1595,12 +1660,14 @@ int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_2048(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm,const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_digit a[64], d[32], m[32]; + sp_digit a[64]; + sp_digit d[32]; + sp_digit m[32]; #else sp_digit* d = NULL; sp_digit* a; @@ -1693,14 +1760,17 @@ extern sp_digit sp_2048_cond_add_avx2_16(sp_digit* r, const sp_digit* a, const s * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_2048(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit ad[32 * 2]; - sp_digit pd[16], qd[16], dpd[16]; - sp_digit tmpad[32], tmpbd[32]; + sp_digit pd[16]; + sp_digit qd[16]; + sp_digit dpd[16]; + sp_digit tmpad[32]; + sp_digit tmpbd[32]; #else sp_digit* t = NULL; #endif @@ -1840,7 +1910,7 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, return err; } -#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */ +#endif /* SP_RSA_PRIVATE_EXP_D | RSA_LOW_MEM */ #endif /* WOLFSSL_HAVE_SP_RSA */ #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \ !defined(WOLFSSL_RSA_PUBLIC_ONLY)) @@ -1860,17 +1930,19 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->used = 32; mp_clamp(r); #elif DIGIT_BIT < 64 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 32; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 64) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -1883,14 +1955,16 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 32; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 64 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -1917,10 +1991,13 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_2048(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[64], e[32], m[32]; + sp_digit b[64]; + sp_digit e[32]; + sp_digit m[32]; sp_digit* r = b; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); @@ -1980,10 +2057,12 @@ static int sp_2048_mod_exp_2_avx2_32(sp_digit* r, const sp_digit* e, int bits, sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -2022,34 +2101,34 @@ static int sp_2048_mod_exp_2_avx2_32(sp_digit* r, const sp_digit* e, int bits, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } sp_2048_lshift_32(r, norm, y); - for (; i>=0 || c>=6; ) { + while ((i >= 0) || (c >= 6)) { if (c == 0) { n = e[i--]; - y = (int)(n >> 58); + y = (byte)(n >> 58); n <<= 6; c = 58; } else if (c < 6) { - y = (int)(n >> 58); + y = (byte)(n >> 58); n = e[i--]; c = 6 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)((n >> 58) & 0x3f); + y = (byte)((n >> 58) & 0x3f); n <<= 6; c -= 6; } @@ -2103,10 +2182,12 @@ static int sp_2048_mod_exp_2_32(sp_digit* r, const sp_digit* e, int bits, sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -2145,34 +2226,34 @@ static int sp_2048_mod_exp_2_32(sp_digit* r, const sp_digit* e, int bits, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } sp_2048_lshift_32(r, norm, y); - for (; i>=0 || c>=6; ) { + while ((i >= 0) || (c >= 6)) { if (c == 0) { n = e[i--]; - y = (int)(n >> 58); + y = (byte)(n >> 58); n <<= 6; c = 58; } else if (c < 6) { - y = (int)(n >> 58); + y = (byte)(n >> 58); n = e[i--]; c = 6 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)((n >> 58) & 0x3f); + y = (byte)((n >> 58) & 0x3f); n <<= 6; c -= 6; } @@ -2220,11 +2301,13 @@ static int sp_2048_mod_exp_2_32(sp_digit* r, const sp_digit* e, int bits, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, - mp_int* mod, byte* out, word32* outLen) +int sp_DhExp_2048(const mp_int* base, const byte* exp, word32 expLen, + const mp_int* mod, byte* out, word32* outLen) { int err = MP_OKAY; - sp_digit b[64], e[32], m[32]; + sp_digit b[64]; + sp_digit e[32]; + sp_digit m[32]; sp_digit* r = b; word32 i; #ifdef HAVE_INTEL_AVX2 @@ -2269,6 +2352,7 @@ int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, sp_2048_to_bin(r, out); *outLen = 256; for (i=0; i<256 && out[i] == 0; i++) { + /* Search for first non-zero. */ } *outLen -= i; XMEMMOVE(out, out + i, *outLen); @@ -2288,10 +2372,13 @@ int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_1024(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[32], e[16], m[16]; + sp_digit b[32]; + sp_digit e[16]; + sp_digit m[16]; sp_digit* r = b; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); @@ -2329,7 +2416,7 @@ int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) return err; } -#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */ +#endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */ #endif /* !WOLFSSL_SP_NO_2048 */ @@ -2345,12 +2432,15 @@ extern void sp_3072_from_bin_movbe(sp_digit* r, int size, const byte* a, int n); */ static void sp_3072_from_bin(sp_digit* r, int size, const byte* a, int n) { +#ifndef NO_MOVBE_SUPPORT word32 cpuid_flags = cpuid_get_flags(); if (IS_INTEL_MOVBE(cpuid_flags)) { sp_3072_from_bin_movbe(r, size, a, n); } - else { + else +#endif + { sp_3072_from_bin_bswap(r, size, a, n); } } @@ -2372,7 +2462,8 @@ static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 64 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -2406,7 +2497,9 @@ static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -2447,12 +2540,15 @@ extern void sp_3072_to_bin_movbe(sp_digit* r, byte* a); */ static void sp_3072_to_bin(sp_digit* r, byte* a) { +#ifndef NO_MOVBE_SUPPORT word32 cpuid_flags = cpuid_get_flags(); if (IS_INTEL_MOVBE(cpuid_flags)) { sp_3072_to_bin_movbe(r, a); } - else { + else +#endif + { sp_3072_to_bin_bswap(r, a); } } @@ -2469,13 +2565,9 @@ extern void sp_3072_mul_24(sp_digit* r, const sp_digit* a, const sp_digit* b); extern sp_digit sp_3072_dbl_12(sp_digit* r, const sp_digit* a); extern void sp_3072_sqr_24(sp_digit* r, const sp_digit* a); -#ifdef HAVE_INTEL_AVX2 extern void sp_3072_mul_avx2_24(sp_digit* r, const sp_digit* a, const sp_digit* b); -#endif /* HAVE_INTEL_AVX2 */ -#ifdef HAVE_INTEL_AVX2 extern void sp_3072_sqr_avx2_24(sp_digit* r, const sp_digit* a); -#endif /* HAVE_INTEL_AVX2 */ extern sp_digit sp_3072_sub_in_place_48(sp_digit* a, const sp_digit* b); extern sp_digit sp_3072_add_48(sp_digit* r, const sp_digit* a, const sp_digit* b); @@ -2484,16 +2576,12 @@ extern void sp_3072_mul_48(sp_digit* r, const sp_digit* a, const sp_digit* b); extern sp_digit sp_3072_dbl_24(sp_digit* r, const sp_digit* a); extern void sp_3072_sqr_48(sp_digit* r, const sp_digit* a); -#ifdef HAVE_INTEL_AVX2 extern void sp_3072_mul_avx2_48(sp_digit* r, const sp_digit* a, const sp_digit* b); -#endif /* HAVE_INTEL_AVX2 */ -#ifdef HAVE_INTEL_AVX2 extern void sp_3072_sqr_avx2_48(sp_digit* r, const sp_digit* a); -#endif /* HAVE_INTEL_AVX2 */ #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH) -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ /* Caclulate the bottom digit of -1/a mod 2^n. * @@ -2502,7 +2590,8 @@ extern void sp_3072_sqr_avx2_48(sp_digit* r, const sp_digit* a); */ static void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho) { - sp_digit x, b; + sp_digit x; + sp_digit b; b = a[0]; x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ @@ -2512,7 +2601,7 @@ static void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho) x *= 2 - b * x; /* here x*a==1 mod 2**64 */ /* rho = -1/m mod b */ - *rho = -x; + *rho = (sp_digit)0 - x; } extern void sp_3072_mul_d_48(sp_digit* r, const sp_digit* a, sp_digit b); @@ -2542,8 +2631,8 @@ extern void sp_3072_mont_reduce_24(sp_digit* a, const sp_digit* m, sp_digit mp); * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_mul_24(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_3072_mont_mul_24(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_3072_mul_24(r, a, b); sp_3072_mont_reduce_24(r, m, mp); @@ -2556,8 +2645,8 @@ static void sp_3072_mont_mul_24(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_sqr_24(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_3072_mont_sqr_24(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_3072_sqr_24(r, a); sp_3072_mont_reduce_24(r, m, mp); @@ -2566,6 +2655,27 @@ static void sp_3072_mont_sqr_24(sp_digit* r, const sp_digit* a, const sp_digit* extern sp_digit sp_3072_cond_sub_avx2_24(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m); extern void sp_3072_mul_d_24(sp_digit* r, const sp_digit* a, sp_digit b); extern void sp_3072_mul_d_avx2_24(sp_digit* r, const sp_digit* a, const sp_digit b); +#ifdef _WIN64 +#if _MSC_VER < 1920 +extern sp_digit div_3072_word_asm_24(sp_digit d1, sp_digit d0, sp_digit div); +#endif /* _MSC_VER < 1920 */ +/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) + * + * d1 The high order half of the number to divide. + * d0 The low order half of the number to divide. + * div The dividend. + * returns the result of the division. + */ +static WC_INLINE sp_digit div_3072_word_24(sp_digit d1, sp_digit d0, + sp_digit div) +{ +#if _MSC_VER >= 1920 + return _udiv128(d1, d0, div, NULL); +#else + return div_3072_word_asm_24(d1, d0, div); +#endif +} +#else /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) * * d1 The high order half of the number to divide. @@ -2585,6 +2695,7 @@ static WC_INLINE sp_digit div_3072_word_24(sp_digit d1, sp_digit d0, ); return r; } +#endif /* _WIN64 */ /* AND m into each word of a and store in r. * * r A single precision integer. @@ -2628,8 +2739,10 @@ extern int64_t sp_3072_cmp_24(const sp_digit* a, const sp_digit* b); static WC_INLINE int sp_3072_div_24(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_digit* r) { - sp_digit t1[48], t2[25]; - sp_digit div, r1; + sp_digit t1[48]; + sp_digit t2[25]; + sp_digit div; + sp_digit r1; int i; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); @@ -2682,7 +2795,8 @@ static WC_INLINE int sp_3072_div_24(const sp_digit* a, const sp_digit* d, sp_dig * m A single precision number that is the modulus to reduce with. * returns MP_OKAY indicating success. */ -static WC_INLINE int sp_3072_mod_24(sp_digit* r, const sp_digit* a, const sp_digit* m) +static WC_INLINE int sp_3072_mod_24(sp_digit* r, const sp_digit* a, + const sp_digit* m) { return sp_3072_div_24(a, m, NULL, r); } @@ -2705,13 +2819,14 @@ static int sp_3072_mod_exp_24(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit td[(33 * 48) + 48]; #endif sp_digit* t[32]; - sp_digit* rt; + sp_digit* rt = NULL; sp_digit* norm; sp_digit mp = 1; sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -2798,34 +2913,34 @@ static int sp_3072_mod_exp_24(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 24); for (; i>=0 || c>=5; ) { if (c >= 5) { - y = (int)((n >> 59) & 0x1f); + y = (byte)((n >> 59) & 0x1f); n <<= 5; c -= 5; } else if (c == 0) { n = e[i--]; - y = (int)(n >> 59); + y = (byte)(n >> 59); n <<= 5; c = 59; } else { - y = (int)(n >> 59); + y = (byte)(n >> 59); n = e[i--]; c = 5 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } @@ -2871,8 +2986,8 @@ extern void sp_3072_mont_reduce_avx2_24(sp_digit* a, const sp_digit* m, sp_digit * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_mul_avx2_24(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_3072_mont_mul_avx2_24(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_3072_mul_avx2_24(r, a, b); sp_3072_mont_reduce_avx2_24(r, m, mp); @@ -2887,8 +3002,8 @@ static void sp_3072_mont_mul_avx2_24(sp_digit* r, const sp_digit* a, const sp_di * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_sqr_avx2_24(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_3072_mont_sqr_avx2_24(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_3072_sqr_avx2_24(r, a); sp_3072_mont_reduce_avx2_24(r, m, mp); @@ -2914,13 +3029,14 @@ static int sp_3072_mod_exp_avx2_24(sp_digit* r, const sp_digit* a, const sp_digi sp_digit td[(33 * 48) + 48]; #endif sp_digit* t[32]; - sp_digit* rt; + sp_digit* rt = NULL; sp_digit* norm; sp_digit mp = 1; sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -3007,34 +3123,34 @@ static int sp_3072_mod_exp_avx2_24(sp_digit* r, const sp_digit* a, const sp_digi if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 24); for (; i>=0 || c>=5; ) { if (c >= 5) { - y = (int)((n >> 59) & 0x1f); + y = (byte)((n >> 59) & 0x1f); n <<= 5; c -= 5; } else if (c == 0) { n = e[i--]; - y = (int)(n >> 59); + y = (byte)(n >> 59); n <<= 5; c = 59; } else { - y = (int)(n >> 59); + y = (byte)(n >> 59); n = e[i--]; c = 5 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } @@ -3070,7 +3186,7 @@ static int sp_3072_mod_exp_avx2_24(sp_digit* r, const sp_digit* a, const sp_digi } #endif /* HAVE_INTEL_AVX2 */ -#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */ +#endif /* (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) | WOLFSSL_HAVE_SP_DH */ #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) /* r = 2^n mod m where n is the number of bits to reduce by. @@ -3087,7 +3203,7 @@ static void sp_3072_mont_norm_48(sp_digit* r, const sp_digit* m) sp_3072_sub_in_place_48(r, m); } -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */ extern sp_digit sp_3072_cond_sub_48(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m); extern void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, sp_digit mp); /* Multiply two Montogmery form numbers mod the modulus (prime). @@ -3099,8 +3215,8 @@ extern void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, sp_digit mp); * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_mul_48(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_3072_mont_mul_48(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_3072_mul_48(r, a, b); sp_3072_mont_reduce_48(r, m, mp); @@ -3113,8 +3229,8 @@ static void sp_3072_mont_mul_48(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_sqr_48(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_3072_mont_sqr_48(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_3072_sqr_48(r, a); sp_3072_mont_reduce_48(r, m, mp); @@ -3123,6 +3239,27 @@ static void sp_3072_mont_sqr_48(sp_digit* r, const sp_digit* a, const sp_digit* #if defined(WOLFSSL_HAVE_SP_DH) || !defined(WOLFSSL_RSA_PUBLIC_ONLY) extern sp_digit sp_3072_cond_sub_avx2_48(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m); extern void sp_3072_mul_d_avx2_48(sp_digit* r, const sp_digit* a, const sp_digit b); +#ifdef _WIN64 +#if _MSC_VER < 1920 +extern sp_digit div_3072_word_asm_48(sp_digit d1, sp_digit d0, sp_digit div); +#endif /* _MSC_VER < 1920 */ +/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) + * + * d1 The high order half of the number to divide. + * d0 The low order half of the number to divide. + * div The dividend. + * returns the result of the division. + */ +static WC_INLINE sp_digit div_3072_word_48(sp_digit d1, sp_digit d0, + sp_digit div) +{ +#if _MSC_VER >= 1920 + return _udiv128(d1, d0, div, NULL); +#else + return div_3072_word_asm_48(d1, d0, div); +#endif +} +#else /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) * * d1 The high order half of the number to divide. @@ -3142,6 +3279,7 @@ static WC_INLINE sp_digit div_3072_word_48(sp_digit d1, sp_digit d0, ); return r; } +#endif /* _WIN64 */ /* AND m into each word of a and store in r. * * r A single precision integer. @@ -3185,8 +3323,10 @@ extern int64_t sp_3072_cmp_48(const sp_digit* a, const sp_digit* b); static WC_INLINE int sp_3072_div_48(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_digit* r) { - sp_digit t1[96], t2[49]; - sp_digit div, r1; + sp_digit t1[96]; + sp_digit t2[49]; + sp_digit div; + sp_digit r1; int i; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); @@ -3239,7 +3379,8 @@ static WC_INLINE int sp_3072_div_48(const sp_digit* a, const sp_digit* d, sp_dig * m A single precision number that is the modulus to reduce with. * returns MP_OKAY indicating success. */ -static WC_INLINE int sp_3072_mod_48(sp_digit* r, const sp_digit* a, const sp_digit* m) +static WC_INLINE int sp_3072_mod_48(sp_digit* r, const sp_digit* a, + const sp_digit* m) { return sp_3072_div_48(a, m, NULL, r); } @@ -3258,8 +3399,10 @@ extern sp_digit sp_3072_sub_48(sp_digit* r, const sp_digit* a, const sp_digit* b static WC_INLINE int sp_3072_div_48_cond(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_digit* r) { - sp_digit t1[96], t2[49]; - sp_digit div, r1; + sp_digit t1[96]; + sp_digit t2[49]; + sp_digit div; + sp_digit r1; int i; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); @@ -3316,7 +3459,8 @@ static WC_INLINE int sp_3072_div_48_cond(const sp_digit* a, const sp_digit* d, s * m A single precision number that is the modulus to reduce with. * returns MP_OKAY indicating success. */ -static WC_INLINE int sp_3072_mod_48_cond(sp_digit* r, const sp_digit* a, const sp_digit* m) +static WC_INLINE int sp_3072_mod_48_cond(sp_digit* r, const sp_digit* a, + const sp_digit* m) { return sp_3072_div_48_cond(a, m, NULL, r); } @@ -3340,13 +3484,14 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit td[(33 * 96) + 96]; #endif sp_digit* t[32]; - sp_digit* rt; + sp_digit* rt = NULL; sp_digit* norm; sp_digit mp = 1; sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -3433,34 +3578,34 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 48); for (; i>=0 || c>=5; ) { if (c >= 5) { - y = (int)((n >> 59) & 0x1f); + y = (byte)((n >> 59) & 0x1f); n <<= 5; c -= 5; } else if (c == 0) { n = e[i--]; - y = (int)(n >> 59); + y = (byte)(n >> 59); n <<= 5; c = 59; } else { - y = (int)(n >> 59); + y = (byte)(n >> 59); n = e[i--]; c = 5 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } @@ -3507,8 +3652,8 @@ extern void sp_3072_mont_reduce_avx2_48(sp_digit* a, const sp_digit* m, sp_digit * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_mul_avx2_48(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_3072_mont_mul_avx2_48(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_3072_mul_avx2_48(r, a, b); sp_3072_mont_reduce_avx2_48(r, m, mp); @@ -3523,8 +3668,8 @@ static void sp_3072_mont_mul_avx2_48(sp_digit* r, const sp_digit* a, const sp_di * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_3072_mont_sqr_avx2_48(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_3072_mont_sqr_avx2_48(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_3072_sqr_avx2_48(r, a); sp_3072_mont_reduce_avx2_48(r, m, mp); @@ -3551,13 +3696,14 @@ static int sp_3072_mod_exp_avx2_48(sp_digit* r, const sp_digit* a, const sp_digi sp_digit td[(33 * 96) + 96]; #endif sp_digit* t[32]; - sp_digit* rt; + sp_digit* rt = NULL; sp_digit* norm; sp_digit mp = 1; sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -3644,34 +3790,34 @@ static int sp_3072_mod_exp_avx2_48(sp_digit* r, const sp_digit* a, const sp_digi if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 48); for (; i>=0 || c>=5; ) { if (c >= 5) { - y = (int)((n >> 59) & 0x1f); + y = (byte)((n >> 59) & 0x1f); n <<= 5; c -= 5; } else if (c == 0) { n = e[i--]; - y = (int)(n >> 59); + y = (byte)(n >> 59); n <<= 5; c = 59; } else { - y = (int)(n >> 59); + y = (byte)(n >> 59); n = e[i--]; c = 5 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } @@ -3721,11 +3867,13 @@ static int sp_3072_mod_exp_avx2_48(sp_digit* r, const sp_digit* a, const sp_digi * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPublic_3072(const byte* in, word32 inLen, const mp_int* em, + const mp_int* mm, byte* out, word32* outLen) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_digit ad[96], md[48], rd[96]; + sp_digit ad[96]; + sp_digit md[48]; + sp_digit rd[96]; #else sp_digit* d = NULL; #endif @@ -3894,12 +4042,14 @@ int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_3072(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm,const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_digit a[96], d[48], m[48]; + sp_digit a[96]; + sp_digit d[48]; + sp_digit m[48]; #else sp_digit* d = NULL; sp_digit* a; @@ -3992,14 +4142,17 @@ extern sp_digit sp_3072_cond_add_avx2_24(sp_digit* r, const sp_digit* a, const s * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_3072(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit ad[48 * 2]; - sp_digit pd[24], qd[24], dpd[24]; - sp_digit tmpad[48], tmpbd[48]; + sp_digit pd[24]; + sp_digit qd[24]; + sp_digit dpd[24]; + sp_digit tmpad[48]; + sp_digit tmpbd[48]; #else sp_digit* t = NULL; #endif @@ -4139,7 +4292,7 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, return err; } -#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */ +#endif /* SP_RSA_PRIVATE_EXP_D | RSA_LOW_MEM */ #endif /* WOLFSSL_HAVE_SP_RSA */ #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \ !defined(WOLFSSL_RSA_PUBLIC_ONLY)) @@ -4159,17 +4312,19 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->used = 48; mp_clamp(r); #elif DIGIT_BIT < 64 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 48; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 64) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -4182,14 +4337,16 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 48; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 64 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -4216,10 +4373,13 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_3072(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[96], e[48], m[48]; + sp_digit b[96]; + sp_digit e[48]; + sp_digit m[48]; sp_digit* r = b; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); @@ -4279,10 +4439,12 @@ static int sp_3072_mod_exp_2_avx2_48(sp_digit* r, const sp_digit* e, int bits, sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -4321,34 +4483,34 @@ static int sp_3072_mod_exp_2_avx2_48(sp_digit* r, const sp_digit* e, int bits, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } sp_3072_lshift_48(r, norm, y); - for (; i>=0 || c>=6; ) { + while ((i >= 0) || (c >= 6)) { if (c == 0) { n = e[i--]; - y = (int)(n >> 58); + y = (byte)(n >> 58); n <<= 6; c = 58; } else if (c < 6) { - y = (int)(n >> 58); + y = (byte)(n >> 58); n = e[i--]; c = 6 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)((n >> 58) & 0x3f); + y = (byte)((n >> 58) & 0x3f); n <<= 6; c -= 6; } @@ -4402,10 +4564,12 @@ static int sp_3072_mod_exp_2_48(sp_digit* r, const sp_digit* e, int bits, sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -4444,34 +4608,34 @@ static int sp_3072_mod_exp_2_48(sp_digit* r, const sp_digit* e, int bits, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } sp_3072_lshift_48(r, norm, y); - for (; i>=0 || c>=6; ) { + while ((i >= 0) || (c >= 6)) { if (c == 0) { n = e[i--]; - y = (int)(n >> 58); + y = (byte)(n >> 58); n <<= 6; c = 58; } else if (c < 6) { - y = (int)(n >> 58); + y = (byte)(n >> 58); n = e[i--]; c = 6 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)((n >> 58) & 0x3f); + y = (byte)((n >> 58) & 0x3f); n <<= 6; c -= 6; } @@ -4519,11 +4683,13 @@ static int sp_3072_mod_exp_2_48(sp_digit* r, const sp_digit* e, int bits, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, - mp_int* mod, byte* out, word32* outLen) +int sp_DhExp_3072(const mp_int* base, const byte* exp, word32 expLen, + const mp_int* mod, byte* out, word32* outLen) { int err = MP_OKAY; - sp_digit b[96], e[48], m[48]; + sp_digit b[96]; + sp_digit e[48]; + sp_digit m[48]; sp_digit* r = b; word32 i; #ifdef HAVE_INTEL_AVX2 @@ -4568,6 +4734,7 @@ int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, sp_3072_to_bin(r, out); *outLen = 384; for (i=0; i<384 && out[i] == 0; i++) { + /* Search for first non-zero. */ } *outLen -= i; XMEMMOVE(out, out + i, *outLen); @@ -4587,10 +4754,13 @@ int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_1536(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[48], e[24], m[24]; + sp_digit b[48]; + sp_digit e[24]; + sp_digit m[24]; sp_digit* r = b; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); @@ -4628,7 +4798,7 @@ int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) return err; } -#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */ +#endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */ #endif /* !WOLFSSL_SP_NO_3072 */ @@ -4644,12 +4814,15 @@ extern void sp_4096_from_bin_movbe(sp_digit* r, int size, const byte* a, int n); */ static void sp_4096_from_bin(sp_digit* r, int size, const byte* a, int n) { +#ifndef NO_MOVBE_SUPPORT word32 cpuid_flags = cpuid_get_flags(); if (IS_INTEL_MOVBE(cpuid_flags)) { sp_4096_from_bin_movbe(r, size, a, n); } - else { + else +#endif + { sp_4096_from_bin_bswap(r, size, a, n); } } @@ -4671,7 +4844,8 @@ static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 64 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -4705,7 +4879,9 @@ static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -4746,12 +4922,15 @@ extern void sp_4096_to_bin_movbe(sp_digit* r, byte* a); */ static void sp_4096_to_bin(sp_digit* r, byte* a) { +#ifndef NO_MOVBE_SUPPORT word32 cpuid_flags = cpuid_get_flags(); if (IS_INTEL_MOVBE(cpuid_flags)) { sp_4096_to_bin_movbe(r, a); } - else { + else +#endif + { sp_4096_to_bin_bswap(r, a); } } @@ -4763,13 +4942,9 @@ extern void sp_4096_mul_64(sp_digit* r, const sp_digit* a, const sp_digit* b); extern sp_digit sp_2048_dbl_32(sp_digit* r, const sp_digit* a); extern void sp_4096_sqr_64(sp_digit* r, const sp_digit* a); -#ifdef HAVE_INTEL_AVX2 extern void sp_4096_mul_avx2_64(sp_digit* r, const sp_digit* a, const sp_digit* b); -#endif /* HAVE_INTEL_AVX2 */ -#ifdef HAVE_INTEL_AVX2 extern void sp_4096_sqr_avx2_64(sp_digit* r, const sp_digit* a); -#endif /* HAVE_INTEL_AVX2 */ /* Caclulate the bottom digit of -1/a mod 2^n. * @@ -4778,7 +4953,8 @@ extern void sp_4096_sqr_avx2_64(sp_digit* r, const sp_digit* a); */ static void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho) { - sp_digit x, b; + sp_digit x; + sp_digit b; b = a[0]; x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ @@ -4788,7 +4964,7 @@ static void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho) x *= 2 - b * x; /* here x*a==1 mod 2**64 */ /* rho = -1/m mod b */ - *rho = -x; + *rho = (sp_digit)0 - x; } extern void sp_4096_mul_d_64(sp_digit* r, const sp_digit* a, sp_digit b); @@ -4807,7 +4983,7 @@ static void sp_4096_mont_norm_64(sp_digit* r, const sp_digit* m) sp_4096_sub_in_place_64(r, m); } -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */ extern sp_digit sp_4096_cond_sub_64(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m); extern void sp_4096_mont_reduce_64(sp_digit* a, const sp_digit* m, sp_digit mp); /* Multiply two Montogmery form numbers mod the modulus (prime). @@ -4819,8 +4995,8 @@ extern void sp_4096_mont_reduce_64(sp_digit* a, const sp_digit* m, sp_digit mp); * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_4096_mont_mul_64(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_4096_mont_mul_64(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_4096_mul_64(r, a, b); sp_4096_mont_reduce_64(r, m, mp); @@ -4833,8 +5009,8 @@ static void sp_4096_mont_mul_64(sp_digit* r, const sp_digit* a, const sp_digit* * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_4096_mont_sqr_64(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_4096_mont_sqr_64(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_4096_sqr_64(r, a); sp_4096_mont_reduce_64(r, m, mp); @@ -4843,6 +5019,27 @@ static void sp_4096_mont_sqr_64(sp_digit* r, const sp_digit* a, const sp_digit* #if defined(WOLFSSL_HAVE_SP_DH) || !defined(WOLFSSL_RSA_PUBLIC_ONLY) extern sp_digit sp_4096_cond_sub_avx2_64(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m); extern void sp_4096_mul_d_avx2_64(sp_digit* r, const sp_digit* a, const sp_digit b); +#ifdef _WIN64 +#if _MSC_VER < 1920 +extern sp_digit div_4096_word_asm_64(sp_digit d1, sp_digit d0, sp_digit div); +#endif /* _MSC_VER < 1920 */ +/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) + * + * d1 The high order half of the number to divide. + * d0 The low order half of the number to divide. + * div The dividend. + * returns the result of the division. + */ +static WC_INLINE sp_digit div_4096_word_64(sp_digit d1, sp_digit d0, + sp_digit div) +{ +#if _MSC_VER >= 1920 + return _udiv128(d1, d0, div, NULL); +#else + return div_4096_word_asm_64(d1, d0, div); +#endif +} +#else /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) * * d1 The high order half of the number to divide. @@ -4862,6 +5059,7 @@ static WC_INLINE sp_digit div_4096_word_64(sp_digit d1, sp_digit d0, ); return r; } +#endif /* _WIN64 */ /* AND m into each word of a and store in r. * * r A single precision integer. @@ -4905,8 +5103,10 @@ extern int64_t sp_4096_cmp_64(const sp_digit* a, const sp_digit* b); static WC_INLINE int sp_4096_div_64(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_digit* r) { - sp_digit t1[128], t2[65]; - sp_digit div, r1; + sp_digit t1[128]; + sp_digit t2[65]; + sp_digit div; + sp_digit r1; int i; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); @@ -4959,7 +5159,8 @@ static WC_INLINE int sp_4096_div_64(const sp_digit* a, const sp_digit* d, sp_dig * m A single precision number that is the modulus to reduce with. * returns MP_OKAY indicating success. */ -static WC_INLINE int sp_4096_mod_64(sp_digit* r, const sp_digit* a, const sp_digit* m) +static WC_INLINE int sp_4096_mod_64(sp_digit* r, const sp_digit* a, + const sp_digit* m) { return sp_4096_div_64(a, m, NULL, r); } @@ -4978,8 +5179,10 @@ extern sp_digit sp_4096_sub_64(sp_digit* r, const sp_digit* a, const sp_digit* b static WC_INLINE int sp_4096_div_64_cond(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_digit* r) { - sp_digit t1[128], t2[65]; - sp_digit div, r1; + sp_digit t1[128]; + sp_digit t2[65]; + sp_digit div; + sp_digit r1; int i; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); @@ -5036,7 +5239,8 @@ static WC_INLINE int sp_4096_div_64_cond(const sp_digit* a, const sp_digit* d, s * m A single precision number that is the modulus to reduce with. * returns MP_OKAY indicating success. */ -static WC_INLINE int sp_4096_mod_64_cond(sp_digit* r, const sp_digit* a, const sp_digit* m) +static WC_INLINE int sp_4096_mod_64_cond(sp_digit* r, const sp_digit* a, + const sp_digit* m) { return sp_4096_div_64_cond(a, m, NULL, r); } @@ -5060,13 +5264,14 @@ static int sp_4096_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, sp_digit td[(33 * 128) + 128]; #endif sp_digit* t[32]; - sp_digit* rt; + sp_digit* rt = NULL; sp_digit* norm; sp_digit mp = 1; sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -5153,34 +5358,34 @@ static int sp_4096_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 64); for (; i>=0 || c>=5; ) { if (c >= 5) { - y = (int)((n >> 59) & 0x1f); + y = (byte)((n >> 59) & 0x1f); n <<= 5; c -= 5; } else if (c == 0) { n = e[i--]; - y = (int)(n >> 59); + y = (byte)(n >> 59); n <<= 5; c = 59; } else { - y = (int)(n >> 59); + y = (byte)(n >> 59); n = e[i--]; c = 5 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } @@ -5227,8 +5432,8 @@ extern void sp_4096_mont_reduce_avx2_64(sp_digit* a, const sp_digit* m, sp_digit * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_4096_mont_mul_avx2_64(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_4096_mont_mul_avx2_64(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_4096_mul_avx2_64(r, a, b); sp_4096_mont_reduce_avx2_64(r, m, mp); @@ -5243,8 +5448,8 @@ static void sp_4096_mont_mul_avx2_64(sp_digit* r, const sp_digit* a, const sp_di * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_4096_mont_sqr_avx2_64(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_4096_mont_sqr_avx2_64(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_4096_sqr_avx2_64(r, a); sp_4096_mont_reduce_avx2_64(r, m, mp); @@ -5271,13 +5476,14 @@ static int sp_4096_mod_exp_avx2_64(sp_digit* r, const sp_digit* a, const sp_digi sp_digit td[(33 * 128) + 128]; #endif sp_digit* t[32]; - sp_digit* rt; + sp_digit* rt = NULL; sp_digit* norm; sp_digit mp = 1; sp_digit n; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -5364,34 +5570,34 @@ static int sp_4096_mod_exp_avx2_64(sp_digit* r, const sp_digit* a, const sp_digi if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } XMEMCPY(r, t[y], sizeof(sp_digit) * 64); for (; i>=0 || c>=5; ) { if (c >= 5) { - y = (int)((n >> 59) & 0x1f); + y = (byte)((n >> 59) & 0x1f); n <<= 5; c -= 5; } else if (c == 0) { n = e[i--]; - y = (int)(n >> 59); + y = (byte)(n >> 59); n <<= 5; c = 59; } else { - y = (int)(n >> 59); + y = (byte)(n >> 59); n = e[i--]; c = 5 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } @@ -5441,11 +5647,13 @@ static int sp_4096_mod_exp_avx2_64(sp_digit* r, const sp_digit* a, const sp_digi * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPublic_4096(const byte* in, word32 inLen, const mp_int* em, + const mp_int* mm, byte* out, word32* outLen) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_digit ad[128], md[64], rd[128]; + sp_digit ad[128]; + sp_digit md[64]; + sp_digit rd[128]; #else sp_digit* d = NULL; #endif @@ -5614,12 +5822,14 @@ int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_4096(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm,const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_digit a[128], d[64], m[64]; + sp_digit a[128]; + sp_digit d[64]; + sp_digit m[64]; #else sp_digit* d = NULL; sp_digit* a; @@ -5712,14 +5922,17 @@ extern sp_digit sp_4096_cond_add_avx2_32(sp_digit* r, const sp_digit* a, const s * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when * an array is too long and MEMORY_E when dynamic memory allocation fails. */ -int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, - mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, - byte* out, word32* outLen) +int sp_RsaPrivate_4096(const byte* in, word32 inLen, const mp_int* dm, + const mp_int* pm, const mp_int* qm, const mp_int* dpm, const mp_int* dqm, + const mp_int* qim, const mp_int* mm, byte* out, word32* outLen) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit ad[64 * 2]; - sp_digit pd[32], qd[32], dpd[32]; - sp_digit tmpad[64], tmpbd[64]; + sp_digit pd[32]; + sp_digit qd[32]; + sp_digit dpd[32]; + sp_digit tmpad[64]; + sp_digit tmpbd[64]; #else sp_digit* t = NULL; #endif @@ -5859,7 +6072,7 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, return err; } -#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */ +#endif /* SP_RSA_PRIVATE_EXP_D | RSA_LOW_MEM */ #endif /* WOLFSSL_HAVE_SP_RSA */ #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \ !defined(WOLFSSL_RSA_PUBLIC_ONLY)) @@ -5879,17 +6092,19 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->used = 64; mp_clamp(r); #elif DIGIT_BIT < 64 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 64; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 64) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -5902,14 +6117,16 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 64; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 64 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -5936,10 +6153,13 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) +int sp_ModExp_4096(const mp_int* base, const mp_int* exp, const mp_int* mod, + mp_int* res) { int err = MP_OKAY; - sp_digit b[128], e[64], m[64]; + sp_digit b[128]; + sp_digit e[64]; + sp_digit m[64]; sp_digit* r = b; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); @@ -5999,10 +6219,12 @@ static int sp_4096_mod_exp_2_avx2_64(sp_digit* r, const sp_digit* e, int bits, sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -6041,34 +6263,34 @@ static int sp_4096_mod_exp_2_avx2_64(sp_digit* r, const sp_digit* e, int bits, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } sp_4096_lshift_64(r, norm, y); - for (; i>=0 || c>=6; ) { + while ((i >= 0) || (c >= 6)) { if (c == 0) { n = e[i--]; - y = (int)(n >> 58); + y = (byte)(n >> 58); n <<= 6; c = 58; } else if (c < 6) { - y = (int)(n >> 58); + y = (byte)(n >> 58); n = e[i--]; c = 6 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)((n >> 58) & 0x3f); + y = (byte)((n >> 58) & 0x3f); n <<= 6; c -= 6; } @@ -6122,10 +6344,12 @@ static int sp_4096_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits, sp_digit* norm; sp_digit* tmp; sp_digit mp = 1; - sp_digit n, o; + sp_digit n; + sp_digit o; sp_digit mask; int i; - int c, y; + int c; + byte y; int err = MP_OKAY; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -6164,34 +6388,34 @@ static int sp_4096_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits, if (c < 0) { /* Number of bits in top word is less than number needed. */ c = -c; - y = (int)(n << c); + y = (byte)(n << c); n = e[i--]; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)(n >> c); + y = (byte)(n >> c); n <<= 64 - c; } sp_4096_lshift_64(r, norm, y); - for (; i>=0 || c>=6; ) { + while ((i >= 0) || (c >= 6)) { if (c == 0) { n = e[i--]; - y = (int)(n >> 58); + y = (byte)(n >> 58); n <<= 6; c = 58; } else if (c < 6) { - y = (int)(n >> 58); + y = (byte)(n >> 58); n = e[i--]; c = 6 - c; - y |= (int)(n >> (64 - c)); + y |= (byte)(n >> (64 - c)); n <<= c; c = 64 - c; } else { - y = (int)((n >> 58) & 0x3f); + y = (byte)((n >> 58) & 0x3f); n <<= 6; c -= 6; } @@ -6239,11 +6463,13 @@ static int sp_4096_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits, * returns 0 on success, MP_READ_E if there are too many bytes in an array * and MEMORY_E if memory allocation fails. */ -int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, - mp_int* mod, byte* out, word32* outLen) +int sp_DhExp_4096(const mp_int* base, const byte* exp, word32 expLen, + const mp_int* mod, byte* out, word32* outLen) { int err = MP_OKAY; - sp_digit b[128], e[64], m[64]; + sp_digit b[128]; + sp_digit e[64]; + sp_digit m[64]; sp_digit* r = b; word32 i; #ifdef HAVE_INTEL_AVX2 @@ -6288,6 +6514,7 @@ int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, sp_4096_to_bin(r, out); *outLen = 512; for (i=0; i<512 && out[i] == 0; i++) { + /* Search for first non-zero. */ } *outLen -= i; XMEMMOVE(out, out + i, *outLen); @@ -6298,19 +6525,23 @@ int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, return err; } #endif -#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */ +#endif /* WOLFSSL_HAVE_SP_DH | (WOLFSSL_HAVE_SP_RSA & !WOLFSSL_RSA_PUBLIC_ONLY) */ #endif /* WOLFSSL_SP_4096 */ -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH */ #ifdef WOLFSSL_HAVE_SP_ECC #ifndef WOLFSSL_SP_NO_256 /* Point structure to use. */ typedef struct sp_point_256 { + /* X ordinate of point. */ sp_digit x[2 * 4]; + /* Y ordinate of point. */ sp_digit y[2 * 4]; + /* Z ordinate of point. */ sp_digit z[2 * 4]; + /* Indicates point is at infinity. */ int infinity; } sp_point_256; @@ -6382,7 +6613,19 @@ static const sp_digit p256_b[4] = { }; #endif -static int sp_256_point_new_ex_4(void* heap, sp_point_256* sp, sp_point_256** p) +extern void sp_256_mul_4(sp_digit* r, const sp_digit* a, const sp_digit* b); +extern void sp_256_sqr_4(sp_digit* r, const sp_digit* a); +extern sp_digit sp_256_add_4(sp_digit* r, const sp_digit* a, const sp_digit* b); +extern sp_digit sp_256_sub_4(sp_digit* r, const sp_digit* a, const sp_digit* b); +/* Create a new point. + * + * heap [in] Buffer to allocate dynamic memory from. + * sp [in] Data for point - only if not allocating. + * p [out] New point. + * returns MEMORY_E when dynamic memory allocation fails and 0 otherwise. + */ +static int sp_256_point_new_ex_4(void* heap, sp_point_256* sp, + sp_point_256** p) { int ret = MP_OKAY; (void)heap; @@ -6407,6 +6650,12 @@ static int sp_256_point_new_ex_4(void* heap, sp_point_256* sp, sp_point_256** p) #endif +/* Free the point. + * + * p [in,out] Point to free. + * clear [in] Indicates whether to zeroize point. + * heap [in] Buffer from which dynamic memory was allocate from. + */ static void sp_256_point_free_4(sp_point_256* p, int clear, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -6419,7 +6668,7 @@ static void sp_256_point_free_4(sp_point_256* p, int clear, void* heap) } #else /* Clear point data if requested. */ - if (clear != 0) { + if ((p != NULL) && (clear != 0)) { XMEMSET(p, 0, sizeof(*p)); } #endif @@ -6510,7 +6759,8 @@ static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 64 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -6544,7 +6794,9 @@ static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -6580,7 +6832,8 @@ static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) * p Point of type sp_point_256 (result). * pm Point of type ecc_point. */ -static void sp_256_point_from_ecc_point_4(sp_point_256* p, const ecc_point* pm) +static void sp_256_point_from_ecc_point_4(sp_point_256* p, + const ecc_point* pm) { XMEMSET(p->x, 0, sizeof(p->x)); XMEMSET(p->y, 0, sizeof(p->y)); @@ -6607,17 +6860,19 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) r->used = 4; mp_clamp(r); #elif DIGIT_BIT < 64 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 4; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 64) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -6630,14 +6885,16 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 4; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 64 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -6698,7 +6955,7 @@ static void sp_256_mont_sqr_n_4(sp_digit* r, const sp_digit* a, int n, } } -#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */ +#endif /* !WOLFSSL_SP_SMALL | HAVE_COMP_KEY */ #ifdef WOLFSSL_SP_SMALL /* Mod-2 for the P256 curve. */ static const uint64_t p256_mod_minus_2[4] = { @@ -6784,7 +7041,6 @@ extern int64_t sp_256_cmp_4(const sp_digit* a, const sp_digit* b); #define sp_256_norm_4(a) extern sp_digit sp_256_cond_sub_4(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m); -extern sp_digit sp_256_sub_4(sp_digit* r, const sp_digit* a, const sp_digit* b); #define sp_256_mont_reduce_order_4 sp_256_mont_reduce_4 extern void sp_256_mont_reduce_4(sp_digit* a, const sp_digit* m, sp_digit mp); @@ -6794,7 +7050,8 @@ extern void sp_256_mont_reduce_4(sp_digit* a, const sp_digit* m, sp_digit mp); * p Montgomery form projective coordinate point. * t Temporary ordinate data. */ -static void sp_256_map_4(sp_point_256* r, const sp_point_256* p, sp_digit* t) +static void sp_256_map_4(sp_point_256* r, const sp_point_256* p, + sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2*4; @@ -6831,7 +7088,7 @@ static void sp_256_map_4(sp_point_256* r, const sp_point_256* p, sp_digit* t) } extern void sp_256_mont_add_4(sp_digit* r, const sp_digit* a, const sp_digit* b, const sp_digit* m); -extern void sp_256_mont_dbl_4(const sp_digit* r, const sp_digit* a, const sp_digit* m); +extern void sp_256_mont_dbl_4(sp_digit* r, const sp_digit* a, const sp_digit* m); extern void sp_256_mont_tpl_4(sp_digit* r, const sp_digit* a, const sp_digit* m); extern void sp_256_mont_sub_4(sp_digit* r, const sp_digit* a, const sp_digit* b, const sp_digit* m); extern void sp_256_div2_4(sp_digit* r, const sp_digit* a, const sp_digit* m); @@ -7037,7 +7294,8 @@ static void sp_256_proj_point_dbl_4(sp_point_256* r, const sp_point_256* p, sp_d * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_4(sp_point_256* p, int n, sp_digit* t) +static void sp_256_proj_point_dbl_n_4(sp_point_256* p, int n, + sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*4; @@ -7340,8 +7598,8 @@ static int sp_256_proj_point_add_4_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r, } #endif /* WOLFSSL_SP_NONBLOCK */ -static void sp_256_proj_point_add_4(sp_point_256* r, const sp_point_256* p, const sp_point_256* q, - sp_digit* t) +static void sp_256_proj_point_add_4(sp_point_256* r, + const sp_point_256* p, const sp_point_256* q, sp_digit* t) { const sp_point_256* ap[2]; sp_point_256* rp[2]; @@ -7434,8 +7692,8 @@ static void sp_256_proj_point_add_4(sp_point_256* r, const sp_point_256* p, cons * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_store_4(sp_point_256* r, const sp_point_256* p, - int n, int m, sp_digit* t) +static void sp_256_proj_point_dbl_n_store_4(sp_point_256* r, + const sp_point_256* p, int n, int m, sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*4; @@ -7446,6 +7704,7 @@ static void sp_256_proj_point_dbl_n_store_4(sp_point_256* r, const sp_point_256* sp_digit* y = r[(1<x[i]; @@ -7462,7 +7721,10 @@ static void sp_256_proj_point_dbl_n_store_4(sp_point_256* r, const sp_point_256* /* W = Z^4 */ sp_256_mont_sqr_4(w, z, p256_mod, p256_mp_mod); sp_256_mont_sqr_4(w, w, p256_mod, p256_mp_mod); + j = m; for (i=1; i<=n; i++) { + j *= 2; + /* A = 3*(X^2 - W) */ sp_256_mont_sqr_4(t1, x, p256_mod, p256_mp_mod); sp_256_mont_sub_4(t1, t1, w, p256_mod); @@ -7470,14 +7732,14 @@ static void sp_256_proj_point_dbl_n_store_4(sp_point_256* r, const sp_point_256* /* B = X*Y^2 */ sp_256_mont_sqr_4(t2, y, p256_mod, p256_mp_mod); sp_256_mont_mul_4(b, t2, x, p256_mod, p256_mp_mod); - x = r[(1<y); + sp_256_norm_4(negy); sp_256_cond_copy_4(p->y, negy, (sp_digit)0 - v[i].neg); sp_256_proj_point_add_4(rt, rt, p, tmp); } @@ -7794,6 +8060,7 @@ static int sp_256_ecc_mulmod_win_add_sub_4(sp_point_256* r, const sp_point_256* } #ifdef HAVE_INTEL_AVX2 +#define sp_256_mod_mul_norm_avx2_4 sp_256_mod_mul_norm_4 extern void sp_256_mont_mul_avx2_4(sp_digit* r, const sp_digit* a, const sp_digit* b, const sp_digit* m, sp_digit mp); extern void sp_256_mont_sqr_avx2_4(sp_digit* r, const sp_digit* a, const sp_digit* m, sp_digit mp); #if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY) @@ -7814,7 +8081,7 @@ static void sp_256_mont_sqr_n_avx2_4(sp_digit* r, const sp_digit* a, int n, } } -#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */ +#endif /* !WOLFSSL_SP_SMALL | HAVE_COMP_KEY */ /* Invert the number, in Montgomery form, modulo the modulus (prime) of the * P256 curve. (r = 1 / a mod m) @@ -7885,13 +8152,18 @@ static void sp_256_mont_inv_avx2_4(sp_digit* r, const sp_digit* a, sp_digit* td) #endif /* WOLFSSL_SP_SMALL */ } +extern sp_digit sp_256_cond_sub_avx2_4(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m); +#define sp_256_mont_reduce_order_avx2_4 sp_256_mont_reduce_avx2_4 + +extern void sp_256_mont_reduce_avx2_4(sp_digit* a, const sp_digit* m, sp_digit mp); /* Map the Montgomery form projective coordinate point to an affine point. * * r Resulting affine coordinate point. * p Montgomery form projective coordinate point. * t Temporary ordinate data. */ -static void sp_256_map_avx2_4(sp_point_256* r, const sp_point_256* p, sp_digit* t) +static void sp_256_map_avx2_4(sp_point_256* r, const sp_point_256* p, + sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2*4; @@ -7905,7 +8177,7 @@ static void sp_256_map_avx2_4(sp_point_256* r, const sp_point_256* p, sp_digit* /* x /= z^2 */ sp_256_mont_mul_avx2_4(r->x, p->x, t2, p256_mod, p256_mp_mod); XMEMSET(r->x + 4, 0, sizeof(r->x) / 2U); - sp_256_mont_reduce_4(r->x, p256_mod, p256_mp_mod); + sp_256_mont_reduce_avx2_4(r->x, p256_mod, p256_mp_mod); /* Reduce x to less than modulus */ n = sp_256_cmp_4(r->x, p256_mod); sp_256_cond_sub_4(r->x, r->x, p256_mod, 0 - ((n >= 0) ? @@ -7915,10 +8187,10 @@ static void sp_256_map_avx2_4(sp_point_256* r, const sp_point_256* p, sp_digit* /* y /= z^3 */ sp_256_mont_mul_avx2_4(r->y, p->y, t1, p256_mod, p256_mp_mod); XMEMSET(r->y + 4, 0, sizeof(r->y) / 2U); - sp_256_mont_reduce_4(r->y, p256_mod, p256_mp_mod); + sp_256_mont_reduce_avx2_4(r->y, p256_mod, p256_mp_mod); /* Reduce y to less than modulus */ n = sp_256_cmp_4(r->y, p256_mod); - sp_256_cond_sub_4(r->y, r->y, p256_mod, 0 - ((n >= 0) ? + sp_256_cond_sub_avx2_4(r->y, r->y, p256_mod, 0 - ((n >= 0) ? (sp_digit)1 : (sp_digit)0)); sp_256_norm_4(r->y); @@ -7927,6 +8199,11 @@ static void sp_256_map_avx2_4(sp_point_256* r, const sp_point_256* p, sp_digit* } +#define sp_256_mont_add_avx2_4 sp_256_mont_add_4 +#define sp_256_mont_dbl_avx2_4 sp_256_mont_dbl_4 +#define sp_256_mont_tpl_avx2_4 sp_256_mont_tpl_4 +#define sp_256_mont_sub_avx2_4 sp_256_mont_sub_4 +extern void sp_256_div2_avx2_4(sp_digit* r, const sp_digit* a, const sp_digit* m); /* Double the Montgomery form projective point p. * * r Result of doubling point. @@ -8089,37 +8366,37 @@ static void sp_256_proj_point_dbl_avx2_4(sp_point_256* r, const sp_point_256* p, /* Z = Y * Z */ sp_256_mont_mul_avx2_4(z, p->y, p->z, p256_mod, p256_mp_mod); /* Z = 2Z */ - sp_256_mont_dbl_4(z, z, p256_mod); + sp_256_mont_dbl_avx2_4(z, z, p256_mod); /* T2 = X - T1 */ - sp_256_mont_sub_4(t2, p->x, t1, p256_mod); + sp_256_mont_sub_avx2_4(t2, p->x, t1, p256_mod); /* T1 = X + T1 */ - sp_256_mont_add_4(t1, p->x, t1, p256_mod); + sp_256_mont_add_avx2_4(t1, p->x, t1, p256_mod); /* T2 = T1 * T2 */ sp_256_mont_mul_avx2_4(t2, t1, t2, p256_mod, p256_mp_mod); /* T1 = 3T2 */ - sp_256_mont_tpl_4(t1, t2, p256_mod); + sp_256_mont_tpl_avx2_4(t1, t2, p256_mod); /* Y = 2Y */ - sp_256_mont_dbl_4(y, p->y, p256_mod); + sp_256_mont_dbl_avx2_4(y, p->y, p256_mod); /* Y = Y * Y */ sp_256_mont_sqr_avx2_4(y, y, p256_mod, p256_mp_mod); /* T2 = Y * Y */ sp_256_mont_sqr_avx2_4(t2, y, p256_mod, p256_mp_mod); /* T2 = T2/2 */ - sp_256_div2_4(t2, t2, p256_mod); + sp_256_div2_avx2_4(t2, t2, p256_mod); /* Y = Y * X */ sp_256_mont_mul_avx2_4(y, y, p->x, p256_mod, p256_mp_mod); /* X = T1 * T1 */ sp_256_mont_sqr_avx2_4(x, t1, p256_mod, p256_mp_mod); /* X = X - Y */ - sp_256_mont_sub_4(x, x, y, p256_mod); + sp_256_mont_sub_avx2_4(x, x, y, p256_mod); /* X = X - Y */ - sp_256_mont_sub_4(x, x, y, p256_mod); + sp_256_mont_sub_avx2_4(x, x, y, p256_mod); /* Y = Y - X */ - sp_256_mont_sub_4(y, y, x, p256_mod); + sp_256_mont_sub_avx2_4(y, y, x, p256_mod); /* Y = Y * T1 */ sp_256_mont_mul_avx2_4(y, y, t1, p256_mod, p256_mp_mod); /* Y = Y - T2 */ - sp_256_mont_sub_4(y, y, t2, p256_mod); + sp_256_mont_sub_avx2_4(y, y, t2, p256_mod); } /* Double the Montgomery form projective point p a number of times. @@ -8129,7 +8406,8 @@ static void sp_256_proj_point_dbl_avx2_4(sp_point_256* r, const sp_point_256* p, * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_avx2_4(sp_point_256* p, int n, sp_digit* t) +static void sp_256_proj_point_dbl_n_avx2_4(sp_point_256* p, int n, + sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*4; @@ -8145,7 +8423,7 @@ static void sp_256_proj_point_dbl_n_avx2_4(sp_point_256* p, int n, sp_digit* t) z = p->z; /* Y = 2*Y */ - sp_256_mont_dbl_4(y, y, p256_mod); + sp_256_mont_dbl_avx2_4(y, y, p256_mod); /* W = Z^4 */ sp_256_mont_sqr_avx2_4(w, z, p256_mod, p256_mp_mod); sp_256_mont_sqr_avx2_4(w, w, p256_mod, p256_mp_mod); @@ -8158,15 +8436,15 @@ static void sp_256_proj_point_dbl_n_avx2_4(sp_point_256* p, int n, sp_digit* t) { /* A = 3*(X^2 - W) */ sp_256_mont_sqr_avx2_4(t1, x, p256_mod, p256_mp_mod); - sp_256_mont_sub_4(t1, t1, w, p256_mod); - sp_256_mont_tpl_4(a, t1, p256_mod); + sp_256_mont_sub_avx2_4(t1, t1, w, p256_mod); + sp_256_mont_tpl_avx2_4(a, t1, p256_mod); /* B = X*Y^2 */ sp_256_mont_sqr_avx2_4(t1, y, p256_mod, p256_mp_mod); sp_256_mont_mul_avx2_4(b, t1, x, p256_mod, p256_mp_mod); /* X = A^2 - 2B */ sp_256_mont_sqr_avx2_4(x, a, p256_mod, p256_mp_mod); - sp_256_mont_dbl_4(t2, b, p256_mod); - sp_256_mont_sub_4(x, x, t2, p256_mod); + sp_256_mont_dbl_avx2_4(t2, b, p256_mod); + sp_256_mont_sub_avx2_4(x, x, t2, p256_mod); /* Z = Z*Y */ sp_256_mont_mul_avx2_4(z, z, y, p256_mod, p256_mp_mod); /* t2 = Y^4 */ @@ -8179,35 +8457,35 @@ static void sp_256_proj_point_dbl_n_avx2_4(sp_point_256* p, int n, sp_digit* t) sp_256_mont_mul_avx2_4(w, w, t1, p256_mod, p256_mp_mod); } /* y = 2*A*(B - X) - Y^4 */ - sp_256_mont_sub_4(y, b, x, p256_mod); + sp_256_mont_sub_avx2_4(y, b, x, p256_mod); sp_256_mont_mul_avx2_4(y, y, a, p256_mod, p256_mp_mod); - sp_256_mont_dbl_4(y, y, p256_mod); - sp_256_mont_sub_4(y, y, t1, p256_mod); + sp_256_mont_dbl_avx2_4(y, y, p256_mod); + sp_256_mont_sub_avx2_4(y, y, t1, p256_mod); } #ifndef WOLFSSL_SP_SMALL /* A = 3*(X^2 - W) */ sp_256_mont_sqr_avx2_4(t1, x, p256_mod, p256_mp_mod); - sp_256_mont_sub_4(t1, t1, w, p256_mod); - sp_256_mont_tpl_4(a, t1, p256_mod); + sp_256_mont_sub_avx2_4(t1, t1, w, p256_mod); + sp_256_mont_tpl_avx2_4(a, t1, p256_mod); /* B = X*Y^2 */ sp_256_mont_sqr_avx2_4(t1, y, p256_mod, p256_mp_mod); sp_256_mont_mul_avx2_4(b, t1, x, p256_mod, p256_mp_mod); /* X = A^2 - 2B */ sp_256_mont_sqr_avx2_4(x, a, p256_mod, p256_mp_mod); - sp_256_mont_dbl_4(t2, b, p256_mod); - sp_256_mont_sub_4(x, x, t2, p256_mod); + sp_256_mont_dbl_avx2_4(t2, b, p256_mod); + sp_256_mont_sub_avx2_4(x, x, t2, p256_mod); /* Z = Z*Y */ sp_256_mont_mul_avx2_4(z, z, y, p256_mod, p256_mp_mod); /* t2 = Y^4 */ sp_256_mont_sqr_avx2_4(t1, t1, p256_mod, p256_mp_mod); /* y = 2*A*(B - X) - Y^4 */ - sp_256_mont_sub_4(y, b, x, p256_mod); + sp_256_mont_sub_avx2_4(y, b, x, p256_mod); sp_256_mont_mul_avx2_4(y, y, a, p256_mod, p256_mp_mod); - sp_256_mont_dbl_4(y, y, p256_mod); - sp_256_mont_sub_4(y, y, t1, p256_mod); + sp_256_mont_dbl_avx2_4(y, y, p256_mod); + sp_256_mont_sub_avx2_4(y, y, t1, p256_mod); #endif /* Y = Y/2 */ - sp_256_div2_4(y, y, p256_mod); + sp_256_div2_avx2_4(y, y, p256_mod); } /* Add two Montgomery form projective points. @@ -8420,8 +8698,8 @@ static int sp_256_proj_point_add_avx2_4_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r } #endif /* WOLFSSL_SP_NONBLOCK */ -static void sp_256_proj_point_add_avx2_4(sp_point_256* r, const sp_point_256* p, const sp_point_256* q, - sp_digit* t) +static void sp_256_proj_point_add_avx2_4(sp_point_256* r, + const sp_point_256* p, const sp_point_256* q, sp_digit* t) { const sp_point_256* ap[2]; sp_point_256* rp[2]; @@ -8447,7 +8725,7 @@ static void sp_256_proj_point_add_avx2_4(sp_point_256* r, const sp_point_256* p, sp_256_norm_4(t1); if ((sp_256_cmp_equal_4(p->x, q->x) & sp_256_cmp_equal_4(p->z, q->z) & (sp_256_cmp_equal_4(p->y, q->y) | sp_256_cmp_equal_4(p->y, t1))) != 0) { - sp_256_proj_point_dbl_4(r, p, t); + sp_256_proj_point_dbl_avx2_4(r, p, t); } else { rp[0] = r; @@ -8485,9 +8763,9 @@ static void sp_256_proj_point_add_avx2_4(sp_point_256* r, const sp_point_256* p, /* S2 = Y2*Z1^3 */ sp_256_mont_mul_avx2_4(t4, t4, q->y, p256_mod, p256_mp_mod); /* H = U2 - U1 */ - sp_256_mont_sub_4(t2, t2, t1, p256_mod); + sp_256_mont_sub_avx2_4(t2, t2, t1, p256_mod); /* R = S2 - S1 */ - sp_256_mont_sub_4(t4, t4, t3, p256_mod); + sp_256_mont_sub_avx2_4(t4, t4, t3, p256_mod); /* Z3 = H*Z1*Z2 */ sp_256_mont_mul_avx2_4(z, z, q->z, p256_mod, p256_mp_mod); sp_256_mont_mul_avx2_4(z, z, t2, p256_mod, p256_mp_mod); @@ -8496,14 +8774,14 @@ static void sp_256_proj_point_add_avx2_4(sp_point_256* r, const sp_point_256* p, sp_256_mont_sqr_avx2_4(t5, t2, p256_mod, p256_mp_mod); sp_256_mont_mul_avx2_4(y, t1, t5, p256_mod, p256_mp_mod); sp_256_mont_mul_avx2_4(t5, t5, t2, p256_mod, p256_mp_mod); - sp_256_mont_sub_4(x, x, t5, p256_mod); - sp_256_mont_dbl_4(t1, y, p256_mod); - sp_256_mont_sub_4(x, x, t1, p256_mod); + sp_256_mont_sub_avx2_4(x, x, t5, p256_mod); + sp_256_mont_dbl_avx2_4(t1, y, p256_mod); + sp_256_mont_sub_avx2_4(x, x, t1, p256_mod); /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ - sp_256_mont_sub_4(y, y, x, p256_mod); + sp_256_mont_sub_avx2_4(y, y, x, p256_mod); sp_256_mont_mul_avx2_4(y, y, t4, p256_mod, p256_mp_mod); sp_256_mont_mul_avx2_4(t5, t5, t3, p256_mod, p256_mp_mod); - sp_256_mont_sub_4(y, y, t5, p256_mod); + sp_256_mont_sub_avx2_4(y, y, t5, p256_mod); } } @@ -8514,8 +8792,8 @@ static void sp_256_proj_point_add_avx2_4(sp_point_256* r, const sp_point_256* p, * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_store_avx2_4(sp_point_256* r, const sp_point_256* p, - int n, int m, sp_digit* t) +static void sp_256_proj_point_dbl_n_store_avx2_4(sp_point_256* r, + const sp_point_256* p, int n, int m, sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*4; @@ -8526,6 +8804,7 @@ static void sp_256_proj_point_dbl_n_store_avx2_4(sp_point_256* r, const sp_point sp_digit* y = r[(1<x[i]; @@ -8538,26 +8817,29 @@ static void sp_256_proj_point_dbl_n_store_avx2_4(sp_point_256* r, const sp_point } /* Y = 2*Y */ - sp_256_mont_dbl_4(y, y, p256_mod); + sp_256_mont_dbl_avx2_4(y, y, p256_mod); /* W = Z^4 */ sp_256_mont_sqr_avx2_4(w, z, p256_mod, p256_mp_mod); sp_256_mont_sqr_avx2_4(w, w, p256_mod, p256_mp_mod); + j = m; for (i=1; i<=n; i++) { + j *= 2; + /* A = 3*(X^2 - W) */ sp_256_mont_sqr_avx2_4(t1, x, p256_mod, p256_mp_mod); - sp_256_mont_sub_4(t1, t1, w, p256_mod); - sp_256_mont_tpl_4(a, t1, p256_mod); + sp_256_mont_sub_avx2_4(t1, t1, w, p256_mod); + sp_256_mont_tpl_avx2_4(a, t1, p256_mod); /* B = X*Y^2 */ sp_256_mont_sqr_avx2_4(t2, y, p256_mod, p256_mp_mod); sp_256_mont_mul_avx2_4(b, t2, x, p256_mod, p256_mp_mod); - x = r[(1<y, p256_mod, p256_mp_mod); /* H = U2 - U1 */ - sp_256_mont_sub_4(t2, t2, t1, p256_mod); + sp_256_mont_sub_avx2_4(t2, t2, t1, p256_mod); /* RS = S2 + S1 */ - sp_256_mont_add_4(t6, t4, t3, p256_mod); + sp_256_mont_add_avx2_4(t6, t4, t3, p256_mod); /* R = S2 - S1 */ - sp_256_mont_sub_4(t4, t4, t3, p256_mod); + sp_256_mont_sub_avx2_4(t4, t4, t3, p256_mod); /* Z3 = H*Z1*Z2 */ /* ZS = H*Z1*Z2 */ sp_256_mont_mul_avx2_4(z, z, q->z, p256_mod, p256_mp_mod); @@ -8637,21 +8920,21 @@ static void sp_256_proj_point_add_sub_avx2_4(sp_point_256* ra, sp_point_256* rs, sp_256_mont_sqr_avx2_4(t5, t2, p256_mod, p256_mp_mod); sp_256_mont_mul_avx2_4(y, t1, t5, p256_mod, p256_mp_mod); sp_256_mont_mul_avx2_4(t5, t5, t2, p256_mod, p256_mp_mod); - sp_256_mont_sub_4(x, x, t5, p256_mod); - sp_256_mont_sub_4(xs, xs, t5, p256_mod); - sp_256_mont_dbl_4(t1, y, p256_mod); - sp_256_mont_sub_4(x, x, t1, p256_mod); - sp_256_mont_sub_4(xs, xs, t1, p256_mod); + sp_256_mont_sub_avx2_4(x, x, t5, p256_mod); + sp_256_mont_sub_avx2_4(xs, xs, t5, p256_mod); + sp_256_mont_dbl_avx2_4(t1, y, p256_mod); + sp_256_mont_sub_avx2_4(x, x, t1, p256_mod); + sp_256_mont_sub_avx2_4(xs, xs, t1, p256_mod); /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ /* YS = -RS*(U1*H^2 - XS) - S1*H^3 */ - sp_256_mont_sub_4(ys, y, xs, p256_mod); - sp_256_mont_sub_4(y, y, x, p256_mod); + sp_256_mont_sub_avx2_4(ys, y, xs, p256_mod); + sp_256_mont_sub_avx2_4(y, y, x, p256_mod); sp_256_mont_mul_avx2_4(y, y, t4, p256_mod, p256_mp_mod); sp_256_sub_4(t6, p256_mod, t6); sp_256_mont_mul_avx2_4(ys, ys, t6, p256_mod, p256_mp_mod); sp_256_mont_mul_avx2_4(t5, t5, t3, p256_mod, p256_mp_mod); - sp_256_mont_sub_4(y, y, t5, p256_mod); - sp_256_mont_sub_4(ys, ys, t5, p256_mod); + sp_256_mont_sub_avx2_4(y, y, t5, p256_mod); + sp_256_mont_sub_avx2_4(ys, ys, t5, p256_mod); } /* Multiply the point by the scalar and return the result. @@ -8677,7 +8960,8 @@ static int sp_256_ecc_mulmod_win_add_sub_avx2_4(sp_point_256* r, const sp_point_ { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_256 td[33]; - sp_point_256 rtd, pd; + sp_point_256 rtd; + sp_point_256 pd; sp_digit tmpd[2 * 4 * 6]; #endif sp_point_256* t; @@ -8715,13 +8999,13 @@ static int sp_256_ecc_mulmod_win_add_sub_avx2_4(sp_point_256* r, const sp_point_ XMEMSET(&t[0], 0, sizeof(t[0])); t[0].infinity = 1; /* t[1] = {g->x, g->y, g->z} * norm */ - err = sp_256_mod_mul_norm_4(t[1].x, g->x, p256_mod); + err = sp_256_mod_mul_norm_avx2_4(t[1].x, g->x, p256_mod); } if (err == MP_OKAY) { - err = sp_256_mod_mul_norm_4(t[1].y, g->y, p256_mod); + err = sp_256_mod_mul_norm_avx2_4(t[1].y, g->y, p256_mod); } if (err == MP_OKAY) { - err = sp_256_mod_mul_norm_4(t[1].z, g->z, p256_mod); + err = sp_256_mod_mul_norm_avx2_4(t[1].z, g->z, p256_mod); } if (err == MP_OKAY) { @@ -8777,6 +9061,7 @@ static int sp_256_ecc_mulmod_win_add_sub_avx2_4(sp_point_256* r, const sp_point_ XMEMCPY(p, &t[v[i].i], sizeof(sp_point_256)); } sp_256_sub_4(negy, p256_mod, p->y); + sp_256_norm_4(negy); sp_256_cond_copy_4(p->y, negy, (sp_digit)0 - v[i].neg); sp_256_proj_point_add_avx2_4(rt, rt, p, tmp); } @@ -8809,7 +9094,7 @@ typedef struct sp_table_entry_256 { } sp_table_entry_256; #if defined(FP_ECC) || defined(WOLFSSL_SP_SMALL) -#endif /* FP_ECC || WOLFSSL_SP_SMALL */ +#endif /* FP_ECC | WOLFSSL_SP_SMALL */ /* Add two Montgomery form projective points. The second point has a q value of * one. * Only the first point can be the same pointer as the result point. @@ -8916,6 +9201,10 @@ static void sp_256_proj_to_affine_4(sp_point_256* a, sp_digit* t) } /* Generate the pre-computed table of points for the base point. + * + * width = 6 + * 64 entries + * 42 bits between * * a The base point. * table Place to store generated point data. @@ -8926,12 +9215,15 @@ static int sp_256_gen_stripe_table_4(const sp_point_256* a, sp_table_entry_256* table, sp_digit* tmp, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_point_256 td, s1d, s2d; + sp_point_256 td; + sp_point_256 s1d; + sp_point_256 s2d; #endif sp_point_256* t; sp_point_256* s1 = NULL; sp_point_256* s2 = NULL; - int i, j; + int i; + int j; int err; (void)heap; @@ -9003,8 +9295,10 @@ extern void sp_256_get_entry_64_avx2_4(sp_point_256* r, const sp_table_entry_256 /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Implementation uses striping of bits. - * Choose bits 6 bits apart. + * Stripe implementation. + * Pre-generated: 2^0, 2^42, ... + * Pre-generated: products of all combinations of above. + * 6 doubles and adds (with qz=1) * * r Resulting point. * k Scalar to multiply by. @@ -9026,8 +9320,10 @@ static int sp_256_ecc_mulmod_stripe_4(sp_point_256* r, const sp_point_256* g, sp_point_256* rt; sp_point_256* p = NULL; sp_digit* t; - int i, j; - int y, x; + int i; + int j; + int y; + int x; int err; (void)g; @@ -9055,8 +9351,10 @@ static int sp_256_ecc_mulmod_stripe_4(sp_point_256* r, const sp_point_256* g, XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod)); y = 0; - for (j=0,x=42; j<6 && x<256; j++,x+=43) { + x = 42; + for (j=0; j<6 && x<256; j++) { y |= (int)(((k[x / 64] >> (x % 64)) & 1) << j); + x += 43; } #ifndef WC_NO_CACHE_RESISTANT if (ct) { @@ -9070,8 +9368,10 @@ static int sp_256_ecc_mulmod_stripe_4(sp_point_256* r, const sp_point_256* g, rt->infinity = !y; for (i=41; i>=0; i--) { y = 0; - for (j=0,x=i; j<6 && x<256; j++,x+=43) { + x = i; + for (j=0; j<6 && x<256; j++) { y |= (int)(((k[x / 64] >> (x % 64)) & 1) << j); + x += 43; } sp_256_proj_point_dbl_4(rt, rt, t); @@ -9108,22 +9408,31 @@ static int sp_256_ecc_mulmod_stripe_4(sp_point_256* r, const sp_point_256* g, return err; } -#endif /* FP_ECC || WOLFSSL_SP_SMALL */ +#endif /* FP_ECC | WOLFSSL_SP_SMALL */ #ifdef FP_ECC #ifndef FP_ENTRIES #define FP_ENTRIES 16 #endif +/* Cache entry - holds precomputation tables for a point. */ typedef struct sp_cache_256_t { + /* X ordinate of point that table was generated from. */ sp_digit x[4]; + /* Y ordinate of point that table was generated from. */ sp_digit y[4]; + /* Precomputation table for point. */ sp_table_entry_256 table[64]; + /* Count of entries in table. */ uint32_t cnt; + /* Point and table set in entry. */ int set; } sp_cache_256_t; +/* Cache of tables. */ static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES]; +/* Index of last entry in cache. */ static THREAD_LS_T int sp_cache_256_last = -1; +/* Cache has been initialized. */ static THREAD_LS_T int sp_cache_256_inited = 0; #ifndef HAVE_THREAD_LS @@ -9131,9 +9440,15 @@ static THREAD_LS_T int sp_cache_256_inited = 0; static wolfSSL_Mutex sp_cache_256_lock; #endif +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache) { - int i, j; + int i; + int j; uint32_t least; if (sp_cache_256_inited == 0) { @@ -9241,7 +9556,7 @@ static int sp_256_ecc_mulmod_4(sp_point_256* r, const sp_point_256* g, const sp_ #ifdef HAVE_INTEL_AVX2 #if defined(FP_ECC) || defined(WOLFSSL_SP_SMALL) -#endif /* FP_ECC || WOLFSSL_SP_SMALL */ +#endif /* FP_ECC | WOLFSSL_SP_SMALL */ /* Add two Montgomery form projective points. The second point has a q value of * one. * Only the first point can be the same pointer as the result point. @@ -9271,7 +9586,7 @@ static void sp_256_proj_point_add_qz1_avx2_4(sp_point_256* r, const sp_point_256 sp_256_norm_4(t1); if ((sp_256_cmp_equal_4(p->x, q->x) & sp_256_cmp_equal_4(p->z, q->z) & (sp_256_cmp_equal_4(p->y, q->y) | sp_256_cmp_equal_4(p->y, t1))) != 0) { - sp_256_proj_point_dbl_4(r, p, t); + sp_256_proj_point_dbl_avx2_4(r, p, t); } else { rp[0] = r; @@ -9303,9 +9618,9 @@ static void sp_256_proj_point_add_qz1_avx2_4(sp_point_256* r, const sp_point_256 /* S2 = Y2*Z1^3 */ sp_256_mont_mul_avx2_4(t4, t4, q->y, p256_mod, p256_mp_mod); /* H = U2 - X1 */ - sp_256_mont_sub_4(t2, t2, x, p256_mod); + sp_256_mont_sub_avx2_4(t2, t2, x, p256_mod); /* R = S2 - Y1 */ - sp_256_mont_sub_4(t4, t4, y, p256_mod); + sp_256_mont_sub_avx2_4(t4, t4, y, p256_mod); /* Z3 = H*Z1 */ sp_256_mont_mul_avx2_4(z, z, t2, p256_mod, p256_mp_mod); /* X3 = R^2 - H^3 - 2*X1*H^2 */ @@ -9313,14 +9628,14 @@ static void sp_256_proj_point_add_qz1_avx2_4(sp_point_256* r, const sp_point_256 sp_256_mont_sqr_avx2_4(t5, t2, p256_mod, p256_mp_mod); sp_256_mont_mul_avx2_4(t3, x, t5, p256_mod, p256_mp_mod); sp_256_mont_mul_avx2_4(t5, t5, t2, p256_mod, p256_mp_mod); - sp_256_mont_sub_4(x, t1, t5, p256_mod); - sp_256_mont_dbl_4(t1, t3, p256_mod); - sp_256_mont_sub_4(x, x, t1, p256_mod); + sp_256_mont_sub_avx2_4(x, t1, t5, p256_mod); + sp_256_mont_dbl_avx2_4(t1, t3, p256_mod); + sp_256_mont_sub_avx2_4(x, x, t1, p256_mod); /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */ - sp_256_mont_sub_4(t3, t3, x, p256_mod); + sp_256_mont_sub_avx2_4(t3, t3, x, p256_mod); sp_256_mont_mul_avx2_4(t3, t3, t4, p256_mod, p256_mp_mod); sp_256_mont_mul_avx2_4(t5, t5, y, p256_mod, p256_mp_mod); - sp_256_mont_sub_4(y, t3, t5, p256_mod); + sp_256_mont_sub_avx2_4(y, t3, t5, p256_mod); } } @@ -9348,6 +9663,10 @@ static void sp_256_proj_to_affine_avx2_4(sp_point_256* a, sp_digit* t) } /* Generate the pre-computed table of points for the base point. + * + * width = 6 + * 64 entries + * 42 bits between * * a The base point. * table Place to store generated point data. @@ -9358,12 +9677,15 @@ static int sp_256_gen_stripe_table_avx2_4(const sp_point_256* a, sp_table_entry_256* table, sp_digit* tmp, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_point_256 td, s1d, s2d; + sp_point_256 td; + sp_point_256 s1d; + sp_point_256 s2d; #endif sp_point_256* t; sp_point_256* s1 = NULL; sp_point_256* s2 = NULL; - int i, j; + int i; + int j; int err; (void)heap; @@ -9377,13 +9699,13 @@ static int sp_256_gen_stripe_table_avx2_4(const sp_point_256* a, } if (err == MP_OKAY) { - err = sp_256_mod_mul_norm_4(t->x, a->x, p256_mod); + err = sp_256_mod_mul_norm_avx2_4(t->x, a->x, p256_mod); } if (err == MP_OKAY) { - err = sp_256_mod_mul_norm_4(t->y, a->y, p256_mod); + err = sp_256_mod_mul_norm_avx2_4(t->y, a->y, p256_mod); } if (err == MP_OKAY) { - err = sp_256_mod_mul_norm_4(t->z, a->z, p256_mod); + err = sp_256_mod_mul_norm_avx2_4(t->z, a->z, p256_mod); } if (err == MP_OKAY) { t->infinity = 0; @@ -9433,8 +9755,10 @@ static int sp_256_gen_stripe_table_avx2_4(const sp_point_256* a, /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. * - * Implementation uses striping of bits. - * Choose bits 6 bits apart. + * Stripe implementation. + * Pre-generated: 2^0, 2^42, ... + * Pre-generated: products of all combinations of above. + * 6 doubles and adds (with qz=1) * * r Resulting point. * k Scalar to multiply by. @@ -9456,8 +9780,10 @@ static int sp_256_ecc_mulmod_stripe_avx2_4(sp_point_256* r, const sp_point_256* sp_point_256* rt; sp_point_256* p = NULL; sp_digit* t; - int i, j; - int y, x; + int i; + int j; + int y; + int x; int err; (void)g; @@ -9485,8 +9811,10 @@ static int sp_256_ecc_mulmod_stripe_avx2_4(sp_point_256* r, const sp_point_256* XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod)); y = 0; - for (j=0,x=42; j<6 && x<256; j++,x+=43) { + x = 42; + for (j=0; j<6 && x<256; j++) { y |= (int)(((k[x / 64] >> (x % 64)) & 1) << j); + x += 43; } #ifndef WC_NO_CACHE_RESISTANT if (ct) { @@ -9500,8 +9828,10 @@ static int sp_256_ecc_mulmod_stripe_avx2_4(sp_point_256* r, const sp_point_256* rt->infinity = !y; for (i=41; i>=0; i--) { y = 0; - for (j=0,x=i; j<6 && x<256; j++,x+=43) { + x = i; + for (j=0; j<6 && x<256; j++) { y |= (int)(((k[x / 64] >> (x % 64)) & 1) << j); + x += 43; } sp_256_proj_point_dbl_avx2_4(rt, rt, t); @@ -9538,7 +9868,7 @@ static int sp_256_ecc_mulmod_stripe_avx2_4(sp_point_256* r, const sp_point_256* return err; } -#endif /* FP_ECC || WOLFSSL_SP_SMALL */ +#endif /* FP_ECC | WOLFSSL_SP_SMALL */ /* Multiply the base point of P256 by the scalar and return the result. * If map is true then convert result to affine coordinates. * @@ -9602,8 +9932,8 @@ static int sp_256_ecc_mulmod_avx2_4(sp_point_256* r, const sp_point_256* g, cons * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, - void* heap) +int sp_ecc_mulmod_256(const mp_int* km, const ecc_point* gm, ecc_point* r, + int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_256 p; @@ -9652,7 +9982,112 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, return err; } +/* Multiply the point by the scalar, add point a and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * p Point to multiply. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_add_256(const mp_int* km, const ecc_point* gm, + const ecc_point* am, int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_256 p; + sp_point_256 a; + sp_digit kd[4]; + sp_digit t[4 * 2 * 5]; +#endif + sp_point_256* point; + sp_point_256* addP = NULL; + sp_digit* k = NULL; + sp_digit* tmp = NULL; + int err = MP_OKAY; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + + err = sp_256_point_new_4(heap, p, point); + if (err == MP_OKAY) { + err = sp_256_point_new_4(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 + 4 * 2 * 5), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 4; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_256_from_mp(k, 4, km); + sp_256_point_from_ecc_point_4(point, gm); + sp_256_point_from_ecc_point_4(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_4(addP->x, addP->x, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_4(addP->y, addP->y, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_4(addP->z, addP->z, p256_mod); + } + if (err == MP_OKAY) { +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + err = sp_256_ecc_mulmod_avx2_4(point, point, k, 0, 0, heap); + else +#endif + err = sp_256_ecc_mulmod_4(point, point, k, 0, 0, heap); + } + if (err == MP_OKAY) { +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_256_proj_point_add_avx2_4(point, point, addP, tmp); + else +#endif + sp_256_proj_point_add_4(point, point, addP, tmp); + + if (map) { +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_256_map_avx2_4(point, point, tmp); + else +#endif + sp_256_map_4(point, point, tmp); + } + + err = sp_256_point_to_ecc_point_4(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_256_point_free_4(addP, 0, heap); + sp_256_point_free_4(point, 0, heap); + + return err; +} + #ifdef WOLFSSL_SP_SMALL +/* Striping precomputation table. + * 6 points combined into a table of 64 points. + * Distance of 43 between points. + */ static const sp_table_entry_256 p256_table[64] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00 }, @@ -9977,6 +10412,11 @@ static const sp_table_entry_256 p256_table[64] = { /* Multiply the base point of P256 by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Stripe implementation. + * Pre-generated: 2^0, 2^42, ... + * Pre-generated: products of all combinations of above. + * 6 doubles and adds (with qz=1) + * * r Resulting point. * k Scalar to multiply by. * map Indicates whether to convert result to affine. @@ -9995,6 +10435,11 @@ static int sp_256_ecc_mulmod_base_4(sp_point_256* r, const sp_digit* k, /* Multiply the base point of P256 by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Stripe implementation. + * Pre-generated: 2^0, 2^42, ... + * Pre-generated: products of all combinations of above. + * 6 doubles and adds (with qz=1) + * * r Resulting point. * k Scalar to multiply by. * map Indicates whether to convert result to affine. @@ -10045,7 +10490,8 @@ static const uint8_t recode_neg_4_7[130] = { */ static void sp_256_ecc_recode_7_4(const sp_digit* k, ecc_recode_256* v) { - int i, j; + int i; + int j; uint8_t y; int carry = 0; int o; @@ -22118,6 +22564,7 @@ static int sp_256_ecc_mulmod_add_only_4(sp_point_256* r, const sp_point_256* g, } p->infinity = !v[i].i; sp_256_sub_4(negy, p256_mod, p->y); + sp_256_norm_4(negy); sp_256_cond_copy_4(p->y, negy, 0 - v[i].neg); sp_256_proj_point_add_qz1_4(rt, rt, p, tmp); } @@ -22242,6 +22689,7 @@ static int sp_256_ecc_mulmod_add_only_avx2_4(sp_point_256* r, const sp_point_256 } p->infinity = !v[i].i; sp_256_sub_4(negy, p256_mod, p->y); + sp_256_norm_4(negy); sp_256_cond_copy_4(p->y, negy, 0 - v[i].neg); sp_256_proj_point_add_qz1_avx2_4(rt, rt, p, tmp); } @@ -22295,7 +22743,7 @@ static int sp_256_ecc_mulmod_base_avx2_4(sp_point_256* r, const sp_digit* k, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) +int sp_ecc_mulmod_base_256(const mp_int* km, ecc_point* r, int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_256 p; @@ -22344,6 +22792,105 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) return err; } +/* Multiply the base point of P256 by the scalar, add point a and return + * the result. If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_add_256(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_256 p; + sp_point_256 a; + sp_digit kd[4]; + sp_digit t[4 * 2 * 5]; +#endif + sp_point_256* point; + sp_point_256* addP = NULL; + sp_digit* tmp = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + + err = sp_256_point_new_4(heap, p, point); + if (err == MP_OKAY) { + err = sp_256_point_new_4(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 + 4 * 2 * 5), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 4; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_256_from_mp(k, 4, km); + sp_256_point_from_ecc_point_4(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_4(addP->x, addP->x, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_4(addP->y, addP->y, p256_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_256_mod_mul_norm_4(addP->z, addP->z, p256_mod); + } + if (err == MP_OKAY) { +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + err = sp_256_ecc_mulmod_base_avx2_4(point, k, 0, 0, heap); + else +#endif + err = sp_256_ecc_mulmod_base_4(point, k, 0, 0, heap); + } + if (err == MP_OKAY) { +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_256_proj_point_add_avx2_4(point, point, addP, tmp); + else +#endif + sp_256_proj_point_add_4(point, point, addP, tmp); + + if (map) { +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_256_map_avx2_4(point, point, tmp); + else +#endif + sp_256_map_4(point, point, tmp); + } + + err = sp_256_point_to_ecc_point_4(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_256_point_free_4(addP, 0, heap); + sp_256_point_free_4(point, 0, heap); + + return err; +} + #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \ defined(HAVE_ECC_VERIFY) /* Returns 1 if the number of zero. @@ -22357,7 +22904,7 @@ static int sp_256_iszero_4(const sp_digit* a) return (a[0] | a[1] | a[2] | a[3]) == 0; } -#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN | HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ extern void sp_256_add_one_4(sp_digit* a); extern void sp_256_from_bin_bswap(sp_digit* r, int size, const byte* a, int n); extern void sp_256_from_bin_movbe(sp_digit* r, int size, const byte* a, int n); @@ -22370,12 +22917,15 @@ extern void sp_256_from_bin_movbe(sp_digit* r, int size, const byte* a, int n); */ static void sp_256_from_bin(sp_digit* r, int size, const byte* a, int n) { +#ifndef NO_MOVBE_SUPPORT word32 cpuid_flags = cpuid_get_flags(); if (IS_INTEL_MOVBE(cpuid_flags)) { sp_256_from_bin_movbe(r, size, a, n); } - else { + else +#endif + { sp_256_from_bin_bswap(r, size, a, n); } } @@ -22516,12 +23066,15 @@ extern void sp_256_to_bin_movbe(sp_digit* r, byte* a); */ static void sp_256_to_bin(sp_digit* r, byte* a) { +#ifndef NO_MOVBE_SUPPORT word32 cpuid_flags = cpuid_get_flags(); if (IS_INTEL_MOVBE(cpuid_flags)) { sp_256_to_bin_movbe(r, a); } - else { + else +#endif + { sp_256_to_bin_bswap(r, a); } } @@ -22538,7 +23091,7 @@ static void sp_256_to_bin(sp_digit* r, byte* a) * returns BUFFER_E if the buffer is to small for output size, * MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, +int sp_ecc_secret_gen_256(const mp_int* priv, const ecc_point* pub, byte* out, word32* outLen, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) @@ -22597,19 +23150,35 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, #endif /* HAVE_ECC_DHE */ #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) -extern sp_digit sp_256_add_4(sp_digit* r, const sp_digit* a, const sp_digit* b); -#endif -#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) -extern void sp_256_mul_4(sp_digit* r, const sp_digit* a, const sp_digit* b); #ifdef HAVE_INTEL_AVX2 extern void sp_256_mul_avx2_4(sp_digit* r, const sp_digit* a, const sp_digit* b); #endif /* HAVE_INTEL_AVX2 */ #endif #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) extern sp_digit sp_256_sub_in_place_4(sp_digit* a, const sp_digit* b); -extern sp_digit sp_256_cond_sub_avx2_4(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m); extern void sp_256_mul_d_4(sp_digit* r, const sp_digit* a, sp_digit b); extern void sp_256_mul_d_avx2_4(sp_digit* r, const sp_digit* a, const sp_digit b); +#ifdef _WIN64 +#if _MSC_VER < 1920 +extern sp_digit div_256_word_asm_4(sp_digit d1, sp_digit d0, sp_digit div); +#endif /* _MSC_VER < 1920 */ +/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) + * + * d1 The high order half of the number to divide. + * d0 The low order half of the number to divide. + * div The dividend. + * returns the result of the division. + */ +static WC_INLINE sp_digit div_256_word_4(sp_digit d1, sp_digit d0, + sp_digit div) +{ +#if _MSC_VER >= 1920 + return _udiv128(d1, d0, div, NULL); +#else + return div_256_word_asm_4(d1, d0, div); +#endif +} +#else /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) * * d1 The high order half of the number to divide. @@ -22629,6 +23198,7 @@ static WC_INLINE sp_digit div_256_word_4(sp_digit d1, sp_digit d0, ); return r; } +#endif /* _WIN64 */ /* AND m into each word of a and store in r. * * r A single precision integer. @@ -22663,8 +23233,10 @@ static void sp_256_mask_4(sp_digit* r, const sp_digit* a, sp_digit m) static WC_INLINE int sp_256_div_4(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_digit* r) { - sp_digit t1[8], t2[5]; - sp_digit div, r1; + sp_digit t1[8]; + sp_digit t2[5]; + sp_digit div; + sp_digit r1; int i; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); @@ -22717,14 +23289,14 @@ static WC_INLINE int sp_256_div_4(const sp_digit* a, const sp_digit* d, sp_digit * m A single precision number that is the modulus to reduce with. * returns MP_OKAY indicating success. */ -static WC_INLINE int sp_256_mod_4(sp_digit* r, const sp_digit* a, const sp_digit* m) +static WC_INLINE int sp_256_mod_4(sp_digit* r, const sp_digit* a, + const sp_digit* m) { return sp_256_div_4(a, m, NULL, r); } #endif #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) -extern void sp_256_sqr_4(sp_digit* r, const sp_digit* a); #ifdef WOLFSSL_SP_SMALL /* Order-2 for the P256 curve. */ static const uint64_t p256_order_minus_2[4] = { @@ -23100,12 +23672,86 @@ static void sp_256_mont_inv_order_avx2_4(sp_digit* r, const sp_digit* a, } #endif /* HAVE_INTEL_AVX2 */ -#endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ #ifdef HAVE_ECC_SIGN #ifndef SP_ECC_MAX_SIG_GEN #define SP_ECC_MAX_SIG_GEN 64 #endif +/* Calculate second signature value S from R, k and private value. + * + * s = (r * x + e) / k + * + * s Signature value. + * r First signature value. + * k Ephemeral private key. + * x Private key as a number. + * e Hash of message as a number. + * tmp Temporary storage for intermediate numbers. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_256_calc_s_4(sp_digit* s, const sp_digit* r, sp_digit* k, + sp_digit* x, const sp_digit* e, sp_digit* tmp) +{ + int err; + sp_digit carry; + int64_t c; + sp_digit* kInv = k; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + + /* Conv k to Montgomery form (mod order) */ +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_256_mul_avx2_4(k, k, p256_norm_order); + else +#endif + sp_256_mul_4(k, k, p256_norm_order); + err = sp_256_mod_4(k, k, p256_order); + if (err == MP_OKAY) { + sp_256_norm_4(k); + + /* kInv = 1/k mod order */ +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_256_mont_inv_order_avx2_4(kInv, k, tmp); + else +#endif + sp_256_mont_inv_order_4(kInv, k, tmp); + sp_256_norm_4(kInv); + + /* s = r * x + e */ +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_256_mul_avx2_4(x, x, r); + else +#endif + sp_256_mul_4(x, x, r); + err = sp_256_mod_4(x, x, p256_order); + } + if (err == MP_OKAY) { + sp_256_norm_4(x); + carry = sp_256_add_4(s, e, x); + sp_256_cond_sub_4(s, s, p256_order, 0 - carry); + sp_256_norm_4(s); + c = sp_256_cmp_4(s, p256_order); + sp_256_cond_sub_4(s, s, p256_order, 0L - (sp_digit)(c >= 0)); + sp_256_norm_4(s); + + /* s = s * k^-1 mod order */ +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_256_mont_mul_order_avx2_4(s, s, kInv); + else +#endif + sp_256_mont_mul_order_4(s, s, kInv); + sp_256_norm_4(s); + } + + return err; +} + /* Sign the hash using the private key. * e = [hash, 256 bits] from binary * r = (k.G)->x mod order @@ -23140,8 +23786,8 @@ typedef struct sp_ecc_sign_256_ctx { int i; } sp_ecc_sign_256_ctx; -int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, + mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_sign_256_ctx* ctx = (sp_ecc_sign_256_ctx*)sp_ctx->data; @@ -23281,8 +23927,8 @@ int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, W } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, + const mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -23300,11 +23946,9 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit* r = NULL; sp_digit* tmp = NULL; sp_point_256* point = NULL; - sp_digit carry; sp_digit* s = NULL; - sp_digit* kInv = NULL; - int err = MP_OKAY; int64_t c; + int err = MP_OKAY; int i; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); @@ -23338,7 +23982,6 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, tmp = td; #endif s = e; - kInv = k; if (hashLen > 32U) { hashLen = 32U; @@ -23346,8 +23989,6 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, } for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) { - sp_256_from_mp(x, 4, priv); - /* New random point. */ if (km == NULL || mp_iszero(km)) { err = sp_256_ecc_gen_k_4(rng, k); @@ -23362,7 +24003,7 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, err = sp_256_ecc_mulmod_base_avx2_4(point, k, 1, 1, heap); else #endif - err = sp_256_ecc_mulmod_base_4(point, k, 1, 1, NULL); + err = sp_256_ecc_mulmod_base_4(point, k, 1, 1, heap); } if (err == MP_OKAY) { @@ -23373,58 +24014,15 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_256_cond_sub_4(r, r, p256_order, 0L - (sp_digit)(c >= 0)); sp_256_norm_4(r); - /* Conv k to Montgomery form (mod order) */ -#ifdef HAVE_INTEL_AVX2 - if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) - sp_256_mul_avx2_4(k, k, p256_norm_order); - else -#endif - sp_256_mul_4(k, k, p256_norm_order); - err = sp_256_mod_4(k, k, p256_order); - } - if (err == MP_OKAY) { - sp_256_norm_4(k); - /* kInv = 1/k mod order */ -#ifdef HAVE_INTEL_AVX2 - if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) - sp_256_mont_inv_order_avx2_4(kInv, k, tmp); - else -#endif - sp_256_mont_inv_order_4(kInv, k, tmp); - sp_256_norm_4(kInv); - - /* s = r * x + e */ -#ifdef HAVE_INTEL_AVX2 - if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) - sp_256_mul_avx2_4(x, x, r); - else -#endif - sp_256_mul_4(x, x, r); - err = sp_256_mod_4(x, x, p256_order); - } - if (err == MP_OKAY) { - sp_256_norm_4(x); + sp_256_from_mp(x, 4, priv); sp_256_from_bin(e, 4, hash, (int)hashLen); - carry = sp_256_add_4(s, e, x); - sp_256_cond_sub_4(s, s, p256_order, 0 - carry); - sp_256_norm_4(s); - c = sp_256_cmp_4(s, p256_order); - sp_256_cond_sub_4(s, s, p256_order, 0L - (sp_digit)(c >= 0)); - sp_256_norm_4(s); - /* s = s * k^-1 mod order */ -#ifdef HAVE_INTEL_AVX2 - if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) - sp_256_mont_mul_order_avx2_4(s, s, kInv); - else -#endif - sp_256_mont_mul_order_4(s, s, kInv); - sp_256_norm_4(s); + err = sp_256_calc_s_4(s, r, k, x, e, tmp); + } - /* Check that signature is usable. */ - if (sp_256_iszero_4(s) == 0) { - break; - } + /* Check that signature is usable. */ + if ((err == MP_OKAY) && (sp_256_iszero_4(s) == 0)) { + break; } #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP i = 1; @@ -23452,7 +24050,6 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, XMEMSET(x, 0, sizeof(sp_digit) * 2U * 4U); XMEMSET(k, 0, sizeof(sp_digit) * 2U * 4U); XMEMSET(r, 0, sizeof(sp_digit) * 2U * 4U); - XMEMSET(r, 0, sizeof(sp_digit) * 2U * 4U); XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 4U); #endif sp_256_point_free_4(point, 1, heap); @@ -23465,6 +24062,147 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, extern void sp_256_mod_inv_4(sp_digit* r, const sp_digit* a, const sp_digit* m); extern void sp_256_mod_inv_avx2_4(sp_digit* r, const sp_digit* a, const sp_digit* m); #endif /* WOLFSSL_SP_SMALL */ + +/* Add point p1 into point p2. Handles p1 == p2 and result at infinity. + * + * p1 First point to add and holds result. + * p2 Second point to add. + * tmp Temporary storage for intermediate numbers. + */ +static void sp_256_add_points_4(sp_point_256* p1, const sp_point_256* p2, + sp_digit* tmp) +{ +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { + sp_256_proj_point_add_avx2_4(p1, p1, p2, tmp); + } + else +#endif + sp_256_proj_point_add_4(p1, p1, p2, tmp); + if (sp_256_iszero_4(p1->z)) { + if (sp_256_iszero_4(p1->x) && sp_256_iszero_4(p1->y)) { +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { + sp_256_proj_point_dbl_avx2_4(p1, p2, tmp); + } + else +#endif + sp_256_proj_point_dbl_4(p1, p2, tmp); + } + else { + /* Y ordinate is not used from here - don't set. */ + p1->x[0] = 0; + p1->x[1] = 0; + p1->x[2] = 0; + p1->x[3] = 0; + XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod)); + } + } +} + +/* Calculate the verification point: [e/s]G + [r/s]Q + * + * p1 Calculated point. + * p2 Public point and temporary. + * s Second part of signature as a number. + * u1 Temporary number. + * u2 Temproray number. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_256_calc_vfy_point_4(sp_point_256* p1, sp_point_256* p2, + sp_digit* s, sp_digit* u1, sp_digit* u2, sp_digit* tmp, void* heap) +{ + int err; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + +#ifndef WOLFSSL_SP_SMALL +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { + sp_256_mod_inv_avx2_4(s, s, p256_order); + } + else +#endif + { + sp_256_mod_inv_4(s, s, p256_order); + } +#endif /* !WOLFSSL_SP_SMALL */ +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { + sp_256_mul_avx2_4(s, s, p256_norm_order); + } + else +#endif + { + sp_256_mul_4(s, s, p256_norm_order); + } + err = sp_256_mod_4(s, s, p256_order); + if (err == MP_OKAY) { + sp_256_norm_4(s); +#ifdef WOLFSSL_SP_SMALL +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { + sp_256_mont_inv_order_avx2_4(s, s, tmp); + sp_256_mont_mul_order_avx2_4(u1, u1, s); + sp_256_mont_mul_order_avx2_4(u2, u2, s); + } + else +#endif + { + sp_256_mont_inv_order_4(s, s, tmp); + sp_256_mont_mul_order_4(u1, u1, s); + sp_256_mont_mul_order_4(u2, u2, s); + } + +#else +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { + sp_256_mont_mul_order_avx2_4(u1, u1, s); + sp_256_mont_mul_order_avx2_4(u2, u2, s); + } + else +#endif + { + sp_256_mont_mul_order_4(u1, u1, s); + sp_256_mont_mul_order_4(u2, u2, s); + } + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + err = sp_256_ecc_mulmod_base_avx2_4(p1, u1, 0, 0, heap); + else +#endif + err = sp_256_ecc_mulmod_base_4(p1, u1, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_256_iszero_4(p1->z)) { + p1->infinity = 1; + } + if (err == MP_OKAY) { +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + err = sp_256_ecc_mulmod_avx2_4(p2, p2, u2, 0, 0, heap); + else +#endif + err = sp_256_ecc_mulmod_4(p2, p2, u2, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_256_iszero_4(p2->z)) { + p2->infinity = 1; + } + + if (err == MP_OKAY) { + sp_256_add_points_4(p1, p2, tmp); + } + + return err; +} + #ifdef HAVE_ECC_VERIFY /* Verify the signature values with the hash and public key. * e = Truncate(hash, 256) @@ -23483,8 +24221,7 @@ extern void sp_256_mod_inv_avx2_4(sp_digit* r, const sp_digit* a, const sp_digit * rm First part of result as an mp_int. * sm Sirst part of result as an mp_int. * heap Heap to use for allocation. - * returns RNG failures, MEMORY_E when memory allocation fails and - * MP_OKAY on success. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ #ifdef WOLFSSL_SP_NONBLOCK typedef struct sp_ecc_verify_256_ctx { @@ -23503,8 +24240,9 @@ typedef struct sp_ecc_verify_256_ctx { sp_point_256 p2; } sp_ecc_verify_256_ctx; -int sp_ecc_verify_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, + word32 hashLen, const mp_int* pX, const mp_int* pY, const mp_int* pZ, + const mp_int* r, const mp_int* sm, int* res, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_verify_256_ctx* ctx = (sp_ecc_verify_256_ctx*)sp_ctx->data; @@ -23658,8 +24396,9 @@ int sp_ecc_verify_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_256(const byte* hash, word32 hashLen, const mp_int* pX, + const mp_int* pY, const mp_int* pZ, const mp_int* r, const mp_int* sm, + int* res, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -23678,11 +24417,8 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_point_256* p1; sp_point_256* p2 = NULL; sp_digit carry; - int64_t c; + int64_t c = 0; int err; -#ifdef HAVE_INTEL_AVX2 - word32 cpuid_flags = cpuid_get_flags(); -#endif err = sp_256_point_new_4(heap, p1d, p1); if (err == MP_OKAY) { @@ -23722,118 +24458,9 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_256_from_mp(p2->y, 4, pY); sp_256_from_mp(p2->z, 4, pZ); -#ifndef WOLFSSL_SP_SMALL -#ifdef HAVE_INTEL_AVX2 - if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { - sp_256_mod_inv_avx2_4(s, s, p256_order); - } - else -#endif - { - sp_256_mod_inv_4(s, s, p256_order); - } -#endif /* !WOLFSSL_SP_SMALL */ -#ifdef HAVE_INTEL_AVX2 - if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { - sp_256_mul_avx2_4(s, s, p256_norm_order); - } - else -#endif - { - sp_256_mul_4(s, s, p256_norm_order); - } - err = sp_256_mod_4(s, s, p256_order); + err = sp_256_calc_vfy_point_4(p1, p2, s, u1, u2, tmp, heap); } if (err == MP_OKAY) { - sp_256_norm_4(s); -#ifdef WOLFSSL_SP_SMALL -#ifdef HAVE_INTEL_AVX2 - if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { - sp_256_mont_inv_order_avx2_4(s, s, tmp); - sp_256_mont_mul_order_avx2_4(u1, u1, s); - sp_256_mont_mul_order_avx2_4(u2, u2, s); - } - else -#endif - { - sp_256_mont_inv_order_4(s, s, tmp); - sp_256_mont_mul_order_4(u1, u1, s); - sp_256_mont_mul_order_4(u2, u2, s); - } - -#else -#ifdef HAVE_INTEL_AVX2 - if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { - sp_256_mont_mul_order_avx2_4(u1, u1, s); - sp_256_mont_mul_order_avx2_4(u2, u2, s); - } - else -#endif - { - sp_256_mont_mul_order_4(u1, u1, s); - sp_256_mont_mul_order_4(u2, u2, s); - } - -#endif /* WOLFSSL_SP_SMALL */ -#ifdef HAVE_INTEL_AVX2 - if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) - err = sp_256_ecc_mulmod_base_avx2_4(p1, u1, 0, 0, heap); - else -#endif - err = sp_256_ecc_mulmod_base_4(p1, u1, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_256_iszero_4(p1->z)) { - p1->infinity = 1; - } - if (err == MP_OKAY) { -#ifdef HAVE_INTEL_AVX2 - if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) - err = sp_256_ecc_mulmod_avx2_4(p2, p2, u2, 0, 0, heap); - else -#endif - err = sp_256_ecc_mulmod_4(p2, p2, u2, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_256_iszero_4(p2->z)) { - p2->infinity = 1; - } - - if (err == MP_OKAY) { -#ifdef HAVE_INTEL_AVX2 - if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { - sp_256_proj_point_add_avx2_4(p1, p1, p2, tmp); - if (sp_256_iszero_4(p1->z)) { - if (sp_256_iszero_4(p1->x) && sp_256_iszero_4(p1->y)) { - sp_256_proj_point_dbl_avx2_4(p1, p2, tmp); - } - else { - /* Y ordinate is not used from here - don't set. */ - p1->x[0] = 0; - p1->x[1] = 0; - p1->x[2] = 0; - p1->x[3] = 0; - XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod)); - } - } - } - else -#endif - { - sp_256_proj_point_add_4(p1, p1, p2, tmp); - if (sp_256_iszero_4(p1->z)) { - if (sp_256_iszero_4(p1->x) && sp_256_iszero_4(p1->y)) { - sp_256_proj_point_dbl_4(p1, p2, tmp); - } - else { - /* Y ordinate is not used from here - don't set. */ - p1->x[0] = 0; - p1->x[1] = 0; - p1->x[2] = 0; - p1->x[3] = 0; - XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod)); - } - } - } - /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */ /* Reload r and convert to Montgomery form. */ sp_256_from_mp(u2, 4, r); @@ -23855,16 +24482,16 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, /* Compare with mod and if greater or equal then not valid. */ c = sp_256_cmp_4(u2, p256_mod); - if (c < 0) { - /* Convert to Montogomery form */ - err = sp_256_mod_mul_norm_4(u2, u2, p256_mod); - if (err == MP_OKAY) { - /* u1 = (r + 1*order).z'.z' mod prime */ - sp_256_mont_mul_4(u1, u2, p1->z, p256_mod, - p256_mp_mod); - *res = (int)(sp_256_cmp_4(p1->x, u1) == 0); - } - } + } + } + if ((*res == 0) && (c < 0)) { + /* Convert to Montogomery form */ + err = sp_256_mod_mul_norm_4(u2, u2, p256_mod); + if (err == MP_OKAY) { + /* u1 = (r + 1*order).z'.z' mod prime */ + sp_256_mont_mul_4(u1, u2, p1->z, p256_mod, + p256_mp_mod); + *res = (sp_256_cmp_4(p1->x, u1) == 0); } } } @@ -23888,7 +24515,8 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -static int sp_256_ecc_is_point_4(sp_point_256* point, void* heap) +static int sp_256_ecc_is_point_4(const sp_point_256* point, + void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -23951,7 +24579,7 @@ static int sp_256_ecc_is_point_4(sp_point_256* point, void* heap) * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) +int sp_ecc_is_point_256(const mp_int* pX, const mp_int* pY) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_256 pubd; @@ -23985,7 +24613,8 @@ int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and * MP_OKAY otherwise. */ -int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) +int sp_ecc_check_key_256(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit privd[4]; @@ -24042,12 +24671,11 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) } } - if (err == MP_OKAY) { - /* Check range of X and Y */ - if (sp_256_cmp_4(pub->x, p256_mod) >= 0 || - sp_256_cmp_4(pub->y, p256_mod) >= 0) { - err = ECC_OUT_OF_RANGE_E; - } + /* Check range of X and Y */ + if ((err == MP_OKAY) && + ((sp_256_cmp_4(pub->x, p256_mod) >= 0) || + (sp_256_cmp_4(pub->y, p256_mod) >= 0))) { + err = ECC_OUT_OF_RANGE_E; } if (err == MP_OKAY) { @@ -24064,12 +24692,10 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) #endif err = sp_256_ecc_mulmod_4(p, pub, p256_order, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is infinity */ - if ((sp_256_iszero_4(p->x) == 0) || - (sp_256_iszero_4(p->y) == 0)) { - err = ECC_INF_E; - } + /* Check result is infinity */ + if ((err == MP_OKAY) && ((sp_256_iszero_4(p->x) == 0) || + (sp_256_iszero_4(p->y) == 0))) { + err = ECC_INF_E; } if (privm) { @@ -24082,12 +24708,11 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) #endif err = sp_256_ecc_mulmod_base_4(p, priv, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is public key */ - if (sp_256_cmp_4(p->x, pub->x) != 0 || - sp_256_cmp_4(p->y, pub->y) != 0) { - err = ECC_PRIV_KEY_E; - } + /* Check result is public key */ + if ((err == MP_OKAY) && + ((sp_256_cmp_4(p->x, pub->x) != 0) || + (sp_256_cmp_4(p->y, pub->y) != 0))) { + err = ECC_PRIV_KEY_E; } } @@ -24275,6 +24900,9 @@ int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ) sp_digit* tmp = NULL; sp_point_256* p; int err; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif err = sp_256_point_new_4(NULL, pd, p); #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -24293,7 +24921,12 @@ int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ) sp_256_from_mp(p->y, 4, pY); sp_256_from_mp(p->z, 4, pZ); - sp_256_map_4(p, p, tmp); +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_256_map_avx2_4(point, point, tmp); + else +#endif + sp_256_map_4(p, p, tmp); } if (err == MP_OKAY) { @@ -24520,9 +25153,13 @@ int sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym) /* Point structure to use. */ typedef struct sp_point_384 { + /* X ordinate of point. */ sp_digit x[2 * 6]; + /* Y ordinate of point. */ sp_digit y[2 * 6]; + /* Z ordinate of point. */ sp_digit z[2 * 6]; + /* Indicates point is at infinity. */ int infinity; } sp_point_384; @@ -24560,8 +25197,9 @@ static const sp_digit p384_norm_order[6] = { #endif #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) /* The Montogmery multiplier for order of the curve P384. */ -static sp_digit p384_mp_order = 0x6ed46089e88fdc45l; +static sp_digit p384_mp_order = 0x6ed46089e88fdc45L; #endif +#ifdef WOLFSSL_SP_SMALL /* The base point of curve P384. */ static const sp_point_384 p384_base = { /* X ordinate */ @@ -24585,6 +25223,7 @@ static const sp_point_384 p384_base = { /* infinity */ 0 }; +#endif /* WOLFSSL_SP_SMALL */ #if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY) static const sp_digit p384_b[6] = { 0x2a85c8edd3ec2aefL,0xc656398d8a2ed19dL,0x0314088f5013875aL, @@ -24592,7 +25231,19 @@ static const sp_digit p384_b[6] = { }; #endif -static int sp_384_point_new_ex_6(void* heap, sp_point_384* sp, sp_point_384** p) +extern void sp_384_mul_6(sp_digit* r, const sp_digit* a, const sp_digit* b); +extern void sp_384_sqr_6(sp_digit* r, const sp_digit* a); +extern sp_digit sp_384_add_6(sp_digit* r, const sp_digit* a, const sp_digit* b); +extern sp_digit sp_384_sub_6(sp_digit* r, const sp_digit* a, const sp_digit* b); +/* Create a new point. + * + * heap [in] Buffer to allocate dynamic memory from. + * sp [in] Data for point - only if not allocating. + * p [out] New point. + * returns MEMORY_E when dynamic memory allocation fails and 0 otherwise. + */ +static int sp_384_point_new_ex_6(void* heap, sp_point_384* sp, + sp_point_384** p) { int ret = MP_OKAY; (void)heap; @@ -24617,6 +25268,12 @@ static int sp_384_point_new_ex_6(void* heap, sp_point_384* sp, sp_point_384** p) #endif +/* Free the point. + * + * p [in,out] Point to free. + * clear [in] Indicates whether to zeroize point. + * heap [in] Buffer from which dynamic memory was allocate from. + */ static void sp_384_point_free_6(sp_point_384* p, int clear, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -24629,7 +25286,7 @@ static void sp_384_point_free_6(sp_point_384* p, int clear, void* heap) } #else /* Clear point data if requested. */ - if (clear != 0) { + if ((p != NULL) && (clear != 0)) { XMEMSET(p, 0, sizeof(*p)); } #endif @@ -24773,7 +25430,8 @@ static void sp_384_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #elif DIGIT_BIT > 64 - int i, j = 0; + int i; + int j = 0; word32 s = 0; r[0] = 0; @@ -24807,7 +25465,9 @@ static void sp_384_from_mp(sp_digit* r, int size, const mp_int* a) r[j] = 0; } #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r[0] = 0; for (i = 0; i < a->used && j < size; i++) { @@ -24843,7 +25503,8 @@ static void sp_384_from_mp(sp_digit* r, int size, const mp_int* a) * p Point of type sp_point_384 (result). * pm Point of type ecc_point. */ -static void sp_384_point_from_ecc_point_6(sp_point_384* p, const ecc_point* pm) +static void sp_384_point_from_ecc_point_6(sp_point_384* p, + const ecc_point* pm) { XMEMSET(p->x, 0, sizeof(p->x)); XMEMSET(p->y, 0, sizeof(p->y)); @@ -24870,17 +25531,19 @@ static int sp_384_to_mp(const sp_digit* a, mp_int* r) r->used = 6; mp_clamp(r); #elif DIGIT_BIT < 64 - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 6; i++) { r->dp[j] |= (mp_digit)(a[i] << s); - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; s = DIGIT_BIT - s; r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 64) { s += DIGIT_BIT; - r->dp[j++] &= (1L << DIGIT_BIT) - 1; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; if (s == SP_WORD_SIZE) { r->dp[j] = 0; } @@ -24893,14 +25556,16 @@ static int sp_384_to_mp(const sp_digit* a, mp_int* r) r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT; mp_clamp(r); #else - int i, j = 0, s = 0; + int i; + int j = 0; + int s = 0; r->dp[0] = 0; for (i = 0; i < 6; i++) { r->dp[j] |= ((mp_digit)a[i]) << s; if (s + 64 >= DIGIT_BIT) { #if DIGIT_BIT != 32 && DIGIT_BIT != 64 - r->dp[j] &= (1L << DIGIT_BIT) - 1; + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; #endif s = DIGIT_BIT - s; r->dp[++j] = a[i] >> s; @@ -24941,7 +25606,6 @@ static int sp_384_point_to_ecc_point_6(const sp_point_384* p, ecc_point* pm) } extern void sp_384_cond_copy_6(sp_digit* r, const sp_digit* a, sp_digit m); -extern void sp_384_mul_6(sp_digit* r, const sp_digit* a, const sp_digit* b); extern sp_digit sp_384_cond_sub_6(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m); extern void sp_384_mont_reduce_6(sp_digit* a, const sp_digit* m, sp_digit mp); extern void sp_384_mont_reduce_order_6(sp_digit* a, const sp_digit* m, sp_digit mp); @@ -24954,14 +25618,13 @@ extern void sp_384_mont_reduce_order_6(sp_digit* a, const sp_digit* m, sp_digit * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_384_mont_mul_6(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_384_mont_mul_6(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_384_mul_6(r, a, b); sp_384_mont_reduce_6(r, m, mp); } -extern void sp_384_sqr_6(sp_digit* r, const sp_digit* a); /* Square the Montgomery form number. (r = a * a mod m) * * r Result of squaring. @@ -24969,8 +25632,8 @@ extern void sp_384_sqr_6(sp_digit* r, const sp_digit* a); * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_384_mont_sqr_6(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_384_mont_sqr_6(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_384_sqr_6(r, a); sp_384_mont_reduce_6(r, m, mp); @@ -24994,7 +25657,7 @@ static void sp_384_mont_sqr_n_6(sp_digit* r, const sp_digit* a, int n, } } -#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */ +#endif /* !WOLFSSL_SP_SMALL | HAVE_COMP_KEY */ #ifdef WOLFSSL_SP_SMALL /* Mod-2 for the P384 curve. */ static const uint64_t p384_mod_minus_2[6] = { @@ -25101,7 +25764,8 @@ extern int64_t sp_384_cmp_6(const sp_digit* a, const sp_digit* b); * p Montgomery form projective coordinate point. * t Temporary ordinate data. */ -static void sp_384_map_6(sp_point_384* r, const sp_point_384* p, sp_digit* t) +static void sp_384_map_6(sp_point_384* r, const sp_point_384* p, + sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2*6; @@ -25137,7 +25801,6 @@ static void sp_384_map_6(sp_point_384* r, const sp_point_384* p, sp_digit* t) } -extern sp_digit sp_384_add_6(sp_digit* r, const sp_digit* a, const sp_digit* b); /* Add two Montgomery form numbers (r = a + b % m). * * r Result of addition. @@ -25185,7 +25848,6 @@ static void sp_384_mont_tpl_6(sp_digit* r, const sp_digit* a, const sp_digit* m) sp_384_cond_sub_6(r, r, m, 0 - o); } -extern sp_digit sp_384_sub_6(sp_digit* r, const sp_digit* a, const sp_digit* b); extern sp_digit sp_384_cond_add_6(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m); /* Subtract two Montgomery form numbers (r = a - b % m). * @@ -25406,7 +26068,8 @@ static void sp_384_proj_point_dbl_6(sp_point_384* r, const sp_point_384* p, sp_d * n Number of times to double * t Temporary ordinate data. */ -static void sp_384_proj_point_dbl_n_6(sp_point_384* p, int n, sp_digit* t) +static void sp_384_proj_point_dbl_n_6(sp_point_384* p, int n, + sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*6; @@ -25710,8 +26373,8 @@ static int sp_384_proj_point_add_6_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r, } #endif /* WOLFSSL_SP_NONBLOCK */ -static void sp_384_proj_point_add_6(sp_point_384* r, const sp_point_384* p, const sp_point_384* q, - sp_digit* t) +static void sp_384_proj_point_add_6(sp_point_384* r, + const sp_point_384* p, const sp_point_384* q, sp_digit* t) { const sp_point_384* ap[2]; sp_point_384* rp[2]; @@ -25804,8 +26467,8 @@ static void sp_384_proj_point_add_6(sp_point_384* r, const sp_point_384* p, cons * n Number of times to double * t Temporary ordinate data. */ -static void sp_384_proj_point_dbl_n_store_6(sp_point_384* r, const sp_point_384* p, - int n, int m, sp_digit* t) +static void sp_384_proj_point_dbl_n_store_6(sp_point_384* r, + const sp_point_384* p, int n, int m, sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*6; @@ -25816,6 +26479,7 @@ static void sp_384_proj_point_dbl_n_store_6(sp_point_384* r, const sp_point_384* sp_digit* y = r[(1<x[i]; @@ -25832,7 +26496,10 @@ static void sp_384_proj_point_dbl_n_store_6(sp_point_384* r, const sp_point_384* /* W = Z^4 */ sp_384_mont_sqr_6(w, z, p384_mod, p384_mp_mod); sp_384_mont_sqr_6(w, w, p384_mod, p384_mp_mod); + j = m; for (i=1; i<=n; i++) { + j *= 2; + /* A = 3*(X^2 - W) */ sp_384_mont_sqr_6(t1, x, p384_mod, p384_mp_mod); sp_384_mont_sub_6(t1, t1, w, p384_mod); @@ -25840,14 +26507,14 @@ static void sp_384_proj_point_dbl_n_store_6(sp_point_384* r, const sp_point_384* /* B = X*Y^2 */ sp_384_mont_sqr_6(t2, y, p384_mod, p384_mp_mod); sp_384_mont_mul_6(b, t2, x, p384_mod, p384_mp_mod); - x = r[(1<y); + sp_384_norm_6(negy); sp_384_cond_copy_6(p->y, negy, (sp_digit)0 - v[i].neg); sp_384_proj_point_add_6(rt, rt, p, tmp); } @@ -26164,6 +26835,7 @@ static int sp_384_ecc_mulmod_win_add_sub_6(sp_point_384* r, const sp_point_384* } #ifdef HAVE_INTEL_AVX2 +#define sp_384_mod_mul_norm_avx2_6 sp_384_mod_mul_norm_6 #ifdef HAVE_INTEL_AVX2 extern void sp_384_mul_avx2_6(sp_digit* r, const sp_digit* a, const sp_digit* b); #define sp_384_mont_reduce_avx2_6 sp_384_mont_reduce_6 @@ -26177,8 +26849,8 @@ extern void sp_384_mont_reduce_order_avx2_6(sp_digit* a, const sp_digit* m, sp_d * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_384_mont_mul_avx2_6(sp_digit* r, const sp_digit* a, const sp_digit* b, - const sp_digit* m, sp_digit mp) +static void sp_384_mont_mul_avx2_6(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) { sp_384_mul_avx2_6(r, a, b); sp_384_mont_reduce_avx2_6(r, m, mp); @@ -26194,8 +26866,8 @@ extern void sp_384_sqr_avx2_6(sp_digit* r, const sp_digit* a); * m Modulus (prime). * mp Montogmery mulitplier. */ -static void sp_384_mont_sqr_avx2_6(sp_digit* r, const sp_digit* a, const sp_digit* m, - sp_digit mp) +static void sp_384_mont_sqr_avx2_6(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) { sp_384_sqr_avx2_6(r, a); sp_384_mont_reduce_avx2_6(r, m, mp); @@ -26220,7 +26892,7 @@ static void sp_384_mont_sqr_n_avx2_6(sp_digit* r, const sp_digit* a, int n, } } -#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */ +#endif /* !WOLFSSL_SP_SMALL | HAVE_COMP_KEY */ /* Invert the number, in Montgomery form, modulo the modulus (prime) of the * P384 curve. (r = 1 / a mod m) @@ -26307,13 +26979,15 @@ static void sp_384_mont_inv_avx2_6(sp_digit* r, const sp_digit* a, sp_digit* td) #endif /* WOLFSSL_SP_SMALL */ } +extern sp_digit sp_384_cond_sub_avx2_6(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m); /* Map the Montgomery form projective coordinate point to an affine point. * * r Resulting affine coordinate point. * p Montgomery form projective coordinate point. * t Temporary ordinate data. */ -static void sp_384_map_avx2_6(sp_point_384* r, const sp_point_384* p, sp_digit* t) +static void sp_384_map_avx2_6(sp_point_384* r, const sp_point_384* p, + sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2*6; @@ -26327,7 +27001,7 @@ static void sp_384_map_avx2_6(sp_point_384* r, const sp_point_384* p, sp_digit* /* x /= z^2 */ sp_384_mont_mul_avx2_6(r->x, p->x, t2, p384_mod, p384_mp_mod); XMEMSET(r->x + 6, 0, sizeof(r->x) / 2U); - sp_384_mont_reduce_6(r->x, p384_mod, p384_mp_mod); + sp_384_mont_reduce_avx2_6(r->x, p384_mod, p384_mp_mod); /* Reduce x to less than modulus */ n = sp_384_cmp_6(r->x, p384_mod); sp_384_cond_sub_6(r->x, r->x, p384_mod, 0 - ((n >= 0) ? @@ -26337,10 +27011,10 @@ static void sp_384_map_avx2_6(sp_point_384* r, const sp_point_384* p, sp_digit* /* y /= z^3 */ sp_384_mont_mul_avx2_6(r->y, p->y, t1, p384_mod, p384_mp_mod); XMEMSET(r->y + 6, 0, sizeof(r->y) / 2U); - sp_384_mont_reduce_6(r->y, p384_mod, p384_mp_mod); + sp_384_mont_reduce_avx2_6(r->y, p384_mod, p384_mp_mod); /* Reduce y to less than modulus */ n = sp_384_cmp_6(r->y, p384_mod); - sp_384_cond_sub_6(r->y, r->y, p384_mod, 0 - ((n >= 0) ? + sp_384_cond_sub_avx2_6(r->y, r->y, p384_mod, 0 - ((n >= 0) ? (sp_digit)1 : (sp_digit)0)); sp_384_norm_6(r->y); @@ -26349,6 +27023,11 @@ static void sp_384_map_avx2_6(sp_point_384* r, const sp_point_384* p, sp_digit* } +#define sp_384_mont_add_avx2_6 sp_384_mont_add_6 +#define sp_384_mont_dbl_avx2_6 sp_384_mont_dbl_6 +#define sp_384_mont_tpl_avx2_6 sp_384_mont_tpl_6 +#define sp_384_mont_sub_avx2_6 sp_384_mont_sub_6 +extern void sp_384_div2_avx2_6(sp_digit* r, const sp_digit* a, const sp_digit* m); /* Double the Montgomery form projective point p. * * r Result of doubling point. @@ -26511,37 +27190,37 @@ static void sp_384_proj_point_dbl_avx2_6(sp_point_384* r, const sp_point_384* p, /* Z = Y * Z */ sp_384_mont_mul_avx2_6(z, p->y, p->z, p384_mod, p384_mp_mod); /* Z = 2Z */ - sp_384_mont_dbl_6(z, z, p384_mod); + sp_384_mont_dbl_avx2_6(z, z, p384_mod); /* T2 = X - T1 */ - sp_384_mont_sub_6(t2, p->x, t1, p384_mod); + sp_384_mont_sub_avx2_6(t2, p->x, t1, p384_mod); /* T1 = X + T1 */ - sp_384_mont_add_6(t1, p->x, t1, p384_mod); + sp_384_mont_add_avx2_6(t1, p->x, t1, p384_mod); /* T2 = T1 * T2 */ sp_384_mont_mul_avx2_6(t2, t1, t2, p384_mod, p384_mp_mod); /* T1 = 3T2 */ - sp_384_mont_tpl_6(t1, t2, p384_mod); + sp_384_mont_tpl_avx2_6(t1, t2, p384_mod); /* Y = 2Y */ - sp_384_mont_dbl_6(y, p->y, p384_mod); + sp_384_mont_dbl_avx2_6(y, p->y, p384_mod); /* Y = Y * Y */ sp_384_mont_sqr_avx2_6(y, y, p384_mod, p384_mp_mod); /* T2 = Y * Y */ sp_384_mont_sqr_avx2_6(t2, y, p384_mod, p384_mp_mod); /* T2 = T2/2 */ - sp_384_div2_6(t2, t2, p384_mod); + sp_384_div2_avx2_6(t2, t2, p384_mod); /* Y = Y * X */ sp_384_mont_mul_avx2_6(y, y, p->x, p384_mod, p384_mp_mod); /* X = T1 * T1 */ sp_384_mont_sqr_avx2_6(x, t1, p384_mod, p384_mp_mod); /* X = X - Y */ - sp_384_mont_sub_6(x, x, y, p384_mod); + sp_384_mont_sub_avx2_6(x, x, y, p384_mod); /* X = X - Y */ - sp_384_mont_sub_6(x, x, y, p384_mod); + sp_384_mont_sub_avx2_6(x, x, y, p384_mod); /* Y = Y - X */ - sp_384_mont_sub_6(y, y, x, p384_mod); + sp_384_mont_sub_avx2_6(y, y, x, p384_mod); /* Y = Y * T1 */ sp_384_mont_mul_avx2_6(y, y, t1, p384_mod, p384_mp_mod); /* Y = Y - T2 */ - sp_384_mont_sub_6(y, y, t2, p384_mod); + sp_384_mont_sub_avx2_6(y, y, t2, p384_mod); } /* Double the Montgomery form projective point p a number of times. @@ -26551,7 +27230,8 @@ static void sp_384_proj_point_dbl_avx2_6(sp_point_384* r, const sp_point_384* p, * n Number of times to double * t Temporary ordinate data. */ -static void sp_384_proj_point_dbl_n_avx2_6(sp_point_384* p, int n, sp_digit* t) +static void sp_384_proj_point_dbl_n_avx2_6(sp_point_384* p, int n, + sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*6; @@ -26567,7 +27247,7 @@ static void sp_384_proj_point_dbl_n_avx2_6(sp_point_384* p, int n, sp_digit* t) z = p->z; /* Y = 2*Y */ - sp_384_mont_dbl_6(y, y, p384_mod); + sp_384_mont_dbl_avx2_6(y, y, p384_mod); /* W = Z^4 */ sp_384_mont_sqr_avx2_6(w, z, p384_mod, p384_mp_mod); sp_384_mont_sqr_avx2_6(w, w, p384_mod, p384_mp_mod); @@ -26580,15 +27260,15 @@ static void sp_384_proj_point_dbl_n_avx2_6(sp_point_384* p, int n, sp_digit* t) { /* A = 3*(X^2 - W) */ sp_384_mont_sqr_avx2_6(t1, x, p384_mod, p384_mp_mod); - sp_384_mont_sub_6(t1, t1, w, p384_mod); - sp_384_mont_tpl_6(a, t1, p384_mod); + sp_384_mont_sub_avx2_6(t1, t1, w, p384_mod); + sp_384_mont_tpl_avx2_6(a, t1, p384_mod); /* B = X*Y^2 */ sp_384_mont_sqr_avx2_6(t1, y, p384_mod, p384_mp_mod); sp_384_mont_mul_avx2_6(b, t1, x, p384_mod, p384_mp_mod); /* X = A^2 - 2B */ sp_384_mont_sqr_avx2_6(x, a, p384_mod, p384_mp_mod); - sp_384_mont_dbl_6(t2, b, p384_mod); - sp_384_mont_sub_6(x, x, t2, p384_mod); + sp_384_mont_dbl_avx2_6(t2, b, p384_mod); + sp_384_mont_sub_avx2_6(x, x, t2, p384_mod); /* Z = Z*Y */ sp_384_mont_mul_avx2_6(z, z, y, p384_mod, p384_mp_mod); /* t2 = Y^4 */ @@ -26601,35 +27281,35 @@ static void sp_384_proj_point_dbl_n_avx2_6(sp_point_384* p, int n, sp_digit* t) sp_384_mont_mul_avx2_6(w, w, t1, p384_mod, p384_mp_mod); } /* y = 2*A*(B - X) - Y^4 */ - sp_384_mont_sub_6(y, b, x, p384_mod); + sp_384_mont_sub_avx2_6(y, b, x, p384_mod); sp_384_mont_mul_avx2_6(y, y, a, p384_mod, p384_mp_mod); - sp_384_mont_dbl_6(y, y, p384_mod); - sp_384_mont_sub_6(y, y, t1, p384_mod); + sp_384_mont_dbl_avx2_6(y, y, p384_mod); + sp_384_mont_sub_avx2_6(y, y, t1, p384_mod); } #ifndef WOLFSSL_SP_SMALL /* A = 3*(X^2 - W) */ sp_384_mont_sqr_avx2_6(t1, x, p384_mod, p384_mp_mod); - sp_384_mont_sub_6(t1, t1, w, p384_mod); - sp_384_mont_tpl_6(a, t1, p384_mod); + sp_384_mont_sub_avx2_6(t1, t1, w, p384_mod); + sp_384_mont_tpl_avx2_6(a, t1, p384_mod); /* B = X*Y^2 */ sp_384_mont_sqr_avx2_6(t1, y, p384_mod, p384_mp_mod); sp_384_mont_mul_avx2_6(b, t1, x, p384_mod, p384_mp_mod); /* X = A^2 - 2B */ sp_384_mont_sqr_avx2_6(x, a, p384_mod, p384_mp_mod); - sp_384_mont_dbl_6(t2, b, p384_mod); - sp_384_mont_sub_6(x, x, t2, p384_mod); + sp_384_mont_dbl_avx2_6(t2, b, p384_mod); + sp_384_mont_sub_avx2_6(x, x, t2, p384_mod); /* Z = Z*Y */ sp_384_mont_mul_avx2_6(z, z, y, p384_mod, p384_mp_mod); /* t2 = Y^4 */ sp_384_mont_sqr_avx2_6(t1, t1, p384_mod, p384_mp_mod); /* y = 2*A*(B - X) - Y^4 */ - sp_384_mont_sub_6(y, b, x, p384_mod); + sp_384_mont_sub_avx2_6(y, b, x, p384_mod); sp_384_mont_mul_avx2_6(y, y, a, p384_mod, p384_mp_mod); - sp_384_mont_dbl_6(y, y, p384_mod); - sp_384_mont_sub_6(y, y, t1, p384_mod); + sp_384_mont_dbl_avx2_6(y, y, p384_mod); + sp_384_mont_sub_avx2_6(y, y, t1, p384_mod); #endif /* Y = Y/2 */ - sp_384_div2_6(y, y, p384_mod); + sp_384_div2_avx2_6(y, y, p384_mod); } /* Add two Montgomery form projective points. @@ -26842,8 +27522,8 @@ static int sp_384_proj_point_add_avx2_6_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r } #endif /* WOLFSSL_SP_NONBLOCK */ -static void sp_384_proj_point_add_avx2_6(sp_point_384* r, const sp_point_384* p, const sp_point_384* q, - sp_digit* t) +static void sp_384_proj_point_add_avx2_6(sp_point_384* r, + const sp_point_384* p, const sp_point_384* q, sp_digit* t) { const sp_point_384* ap[2]; sp_point_384* rp[2]; @@ -26869,7 +27549,7 @@ static void sp_384_proj_point_add_avx2_6(sp_point_384* r, const sp_point_384* p, sp_384_norm_6(t1); if ((sp_384_cmp_equal_6(p->x, q->x) & sp_384_cmp_equal_6(p->z, q->z) & (sp_384_cmp_equal_6(p->y, q->y) | sp_384_cmp_equal_6(p->y, t1))) != 0) { - sp_384_proj_point_dbl_6(r, p, t); + sp_384_proj_point_dbl_avx2_6(r, p, t); } else { rp[0] = r; @@ -26907,9 +27587,9 @@ static void sp_384_proj_point_add_avx2_6(sp_point_384* r, const sp_point_384* p, /* S2 = Y2*Z1^3 */ sp_384_mont_mul_avx2_6(t4, t4, q->y, p384_mod, p384_mp_mod); /* H = U2 - U1 */ - sp_384_mont_sub_6(t2, t2, t1, p384_mod); + sp_384_mont_sub_avx2_6(t2, t2, t1, p384_mod); /* R = S2 - S1 */ - sp_384_mont_sub_6(t4, t4, t3, p384_mod); + sp_384_mont_sub_avx2_6(t4, t4, t3, p384_mod); /* Z3 = H*Z1*Z2 */ sp_384_mont_mul_avx2_6(z, z, q->z, p384_mod, p384_mp_mod); sp_384_mont_mul_avx2_6(z, z, t2, p384_mod, p384_mp_mod); @@ -26918,14 +27598,14 @@ static void sp_384_proj_point_add_avx2_6(sp_point_384* r, const sp_point_384* p, sp_384_mont_sqr_avx2_6(t5, t2, p384_mod, p384_mp_mod); sp_384_mont_mul_avx2_6(y, t1, t5, p384_mod, p384_mp_mod); sp_384_mont_mul_avx2_6(t5, t5, t2, p384_mod, p384_mp_mod); - sp_384_mont_sub_6(x, x, t5, p384_mod); - sp_384_mont_dbl_6(t1, y, p384_mod); - sp_384_mont_sub_6(x, x, t1, p384_mod); + sp_384_mont_sub_avx2_6(x, x, t5, p384_mod); + sp_384_mont_dbl_avx2_6(t1, y, p384_mod); + sp_384_mont_sub_avx2_6(x, x, t1, p384_mod); /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ - sp_384_mont_sub_6(y, y, x, p384_mod); + sp_384_mont_sub_avx2_6(y, y, x, p384_mod); sp_384_mont_mul_avx2_6(y, y, t4, p384_mod, p384_mp_mod); sp_384_mont_mul_avx2_6(t5, t5, t3, p384_mod, p384_mp_mod); - sp_384_mont_sub_6(y, y, t5, p384_mod); + sp_384_mont_sub_avx2_6(y, y, t5, p384_mod); } } @@ -26936,8 +27616,8 @@ static void sp_384_proj_point_add_avx2_6(sp_point_384* r, const sp_point_384* p, * n Number of times to double * t Temporary ordinate data. */ -static void sp_384_proj_point_dbl_n_store_avx2_6(sp_point_384* r, const sp_point_384* p, - int n, int m, sp_digit* t) +static void sp_384_proj_point_dbl_n_store_avx2_6(sp_point_384* r, + const sp_point_384* p, int n, int m, sp_digit* t) { sp_digit* w = t; sp_digit* a = t + 2*6; @@ -26948,6 +27628,7 @@ static void sp_384_proj_point_dbl_n_store_avx2_6(sp_point_384* r, const sp_point sp_digit* y = r[(1<x[i]; @@ -26960,26 +27641,29 @@ static void sp_384_proj_point_dbl_n_store_avx2_6(sp_point_384* r, const sp_point } /* Y = 2*Y */ - sp_384_mont_dbl_6(y, y, p384_mod); + sp_384_mont_dbl_avx2_6(y, y, p384_mod); /* W = Z^4 */ sp_384_mont_sqr_avx2_6(w, z, p384_mod, p384_mp_mod); sp_384_mont_sqr_avx2_6(w, w, p384_mod, p384_mp_mod); + j = m; for (i=1; i<=n; i++) { + j *= 2; + /* A = 3*(X^2 - W) */ sp_384_mont_sqr_avx2_6(t1, x, p384_mod, p384_mp_mod); - sp_384_mont_sub_6(t1, t1, w, p384_mod); - sp_384_mont_tpl_6(a, t1, p384_mod); + sp_384_mont_sub_avx2_6(t1, t1, w, p384_mod); + sp_384_mont_tpl_avx2_6(a, t1, p384_mod); /* B = X*Y^2 */ sp_384_mont_sqr_avx2_6(t2, y, p384_mod, p384_mp_mod); sp_384_mont_mul_avx2_6(b, t2, x, p384_mod, p384_mp_mod); - x = r[(1<y, p384_mod, p384_mp_mod); /* H = U2 - U1 */ - sp_384_mont_sub_6(t2, t2, t1, p384_mod); + sp_384_mont_sub_avx2_6(t2, t2, t1, p384_mod); /* RS = S2 + S1 */ - sp_384_mont_add_6(t6, t4, t3, p384_mod); + sp_384_mont_add_avx2_6(t6, t4, t3, p384_mod); /* R = S2 - S1 */ - sp_384_mont_sub_6(t4, t4, t3, p384_mod); + sp_384_mont_sub_avx2_6(t4, t4, t3, p384_mod); /* Z3 = H*Z1*Z2 */ /* ZS = H*Z1*Z2 */ sp_384_mont_mul_avx2_6(z, z, q->z, p384_mod, p384_mp_mod); @@ -27059,21 +27744,21 @@ static void sp_384_proj_point_add_sub_avx2_6(sp_point_384* ra, sp_point_384* rs, sp_384_mont_sqr_avx2_6(t5, t2, p384_mod, p384_mp_mod); sp_384_mont_mul_avx2_6(y, t1, t5, p384_mod, p384_mp_mod); sp_384_mont_mul_avx2_6(t5, t5, t2, p384_mod, p384_mp_mod); - sp_384_mont_sub_6(x, x, t5, p384_mod); - sp_384_mont_sub_6(xs, xs, t5, p384_mod); - sp_384_mont_dbl_6(t1, y, p384_mod); - sp_384_mont_sub_6(x, x, t1, p384_mod); - sp_384_mont_sub_6(xs, xs, t1, p384_mod); + sp_384_mont_sub_avx2_6(x, x, t5, p384_mod); + sp_384_mont_sub_avx2_6(xs, xs, t5, p384_mod); + sp_384_mont_dbl_avx2_6(t1, y, p384_mod); + sp_384_mont_sub_avx2_6(x, x, t1, p384_mod); + sp_384_mont_sub_avx2_6(xs, xs, t1, p384_mod); /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ /* YS = -RS*(U1*H^2 - XS) - S1*H^3 */ - sp_384_mont_sub_6(ys, y, xs, p384_mod); - sp_384_mont_sub_6(y, y, x, p384_mod); + sp_384_mont_sub_avx2_6(ys, y, xs, p384_mod); + sp_384_mont_sub_avx2_6(y, y, x, p384_mod); sp_384_mont_mul_avx2_6(y, y, t4, p384_mod, p384_mp_mod); sp_384_sub_6(t6, p384_mod, t6); sp_384_mont_mul_avx2_6(ys, ys, t6, p384_mod, p384_mp_mod); sp_384_mont_mul_avx2_6(t5, t5, t3, p384_mod, p384_mp_mod); - sp_384_mont_sub_6(y, y, t5, p384_mod); - sp_384_mont_sub_6(ys, ys, t5, p384_mod); + sp_384_mont_sub_avx2_6(y, y, t5, p384_mod); + sp_384_mont_sub_avx2_6(ys, ys, t5, p384_mod); } /* Multiply the point by the scalar and return the result. @@ -27099,7 +27784,8 @@ static int sp_384_ecc_mulmod_win_add_sub_avx2_6(sp_point_384* r, const sp_point_ { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_384 td[33]; - sp_point_384 rtd, pd; + sp_point_384 rtd; + sp_point_384 pd; sp_digit tmpd[2 * 6 * 6]; #endif sp_point_384* t; @@ -27137,13 +27823,13 @@ static int sp_384_ecc_mulmod_win_add_sub_avx2_6(sp_point_384* r, const sp_point_ XMEMSET(&t[0], 0, sizeof(t[0])); t[0].infinity = 1; /* t[1] = {g->x, g->y, g->z} * norm */ - err = sp_384_mod_mul_norm_6(t[1].x, g->x, p384_mod); + err = sp_384_mod_mul_norm_avx2_6(t[1].x, g->x, p384_mod); } if (err == MP_OKAY) { - err = sp_384_mod_mul_norm_6(t[1].y, g->y, p384_mod); + err = sp_384_mod_mul_norm_avx2_6(t[1].y, g->y, p384_mod); } if (err == MP_OKAY) { - err = sp_384_mod_mul_norm_6(t[1].z, g->z, p384_mod); + err = sp_384_mod_mul_norm_avx2_6(t[1].z, g->z, p384_mod); } if (err == MP_OKAY) { @@ -27199,6 +27885,7 @@ static int sp_384_ecc_mulmod_win_add_sub_avx2_6(sp_point_384* r, const sp_point_ XMEMCPY(p, &t[v[i].i], sizeof(sp_point_384)); } sp_384_sub_6(negy, p384_mod, p->y); + sp_384_norm_6(negy); sp_384_cond_copy_6(p->y, negy, (sp_digit)0 - v[i].neg); sp_384_proj_point_add_avx2_6(rt, rt, p, tmp); } @@ -27230,8 +27917,8 @@ typedef struct sp_table_entry_384 { sp_digit y[6]; } sp_table_entry_384; -#ifdef FP_ECC -#endif /* FP_ECC */ +#if defined(FP_ECC) || defined(WOLFSSL_SP_SMALL) +#endif /* FP_ECC | WOLFSSL_SP_SMALL */ /* Add two Montgomery form projective points. The second point has a q value of * one. * Only the first point can be the same pointer as the result point. @@ -27338,6 +28025,10 @@ static void sp_384_proj_to_affine_6(sp_point_384* a, sp_digit* t) } /* Generate the pre-computed table of points for the base point. + * + * width = 6 + * 64 entries + * 64 bits between * * a The base point. * table Place to store generated point data. @@ -27348,12 +28039,15 @@ static int sp_384_gen_stripe_table_6(const sp_point_384* a, sp_table_entry_384* table, sp_digit* tmp, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_point_384 td, s1d, s2d; + sp_point_384 td; + sp_point_384 s1d; + sp_point_384 s2d; #endif sp_point_384* t; sp_point_384* s1 = NULL; sp_point_384* s2 = NULL; - int i, j; + int i; + int j; int err; (void)heap; @@ -27390,14 +28084,14 @@ static int sp_384_gen_stripe_table_6(const sp_point_384* a, XMEMCPY(table[1].x, t->x, sizeof(table->x)); XMEMCPY(table[1].y, t->y, sizeof(table->y)); - for (i=1; i<8; i++) { - sp_384_proj_point_dbl_n_6(t, 48, tmp); + for (i=1; i<6; i++) { + sp_384_proj_point_dbl_n_6(t, 64, tmp); sp_384_proj_to_affine_6(t, tmp); XMEMCPY(table[1<x, sizeof(table->x)); XMEMCPY(table[1<y, sizeof(table->y)); } - for (i=1; i<8; i++) { + for (i=1; i<6; i++) { XMEMCPY(s1->x, table[1<x)); XMEMCPY(s1->y, table[1<y)); for (j=(1<z, p384_norm_mod, sizeof(p384_norm_mod)); y = 0; - for (j=0,x=47; j<8; j++,x+=48) { + x = 63; + for (j=0; j<6; j++) { y |= (int)(((k[x / 64] >> (x % 64)) & 1) << j); + x += 64; } #ifndef WC_NO_CACHE_RESISTANT if (ct) { - sp_384_get_entry_256_6(rt, table, y); + sp_384_get_entry_64_6(rt, table, y); } else #endif { @@ -27489,16 +28190,18 @@ static int sp_384_ecc_mulmod_stripe_6(sp_point_384* r, const sp_point_384* g, XMEMCPY(rt->y, table[y].y, sizeof(table[y].y)); } rt->infinity = !y; - for (i=46; i>=0; i--) { + for (i=62; i>=0; i--) { y = 0; - for (j=0,x=i; j<8; j++,x+=48) { + x = i; + for (j=0; j<6; j++) { y |= (int)(((k[x / 64] >> (x % 64)) & 1) << j); + x += 64; } sp_384_proj_point_dbl_6(rt, rt, t); #ifndef WC_NO_CACHE_RESISTANT if (ct) { - sp_384_get_entry_256_6(p, table, y); + sp_384_get_entry_64_6(p, table, y); } else #endif @@ -27529,21 +28232,31 @@ static int sp_384_ecc_mulmod_stripe_6(sp_point_384* r, const sp_point_384* g, return err; } +#endif /* FP_ECC | WOLFSSL_SP_SMALL */ #ifdef FP_ECC #ifndef FP_ENTRIES #define FP_ENTRIES 16 #endif +/* Cache entry - holds precomputation tables for a point. */ typedef struct sp_cache_384_t { + /* X ordinate of point that table was generated from. */ sp_digit x[6]; + /* Y ordinate of point that table was generated from. */ sp_digit y[6]; - sp_table_entry_384 table[256]; + /* Precomputation table for point. */ + sp_table_entry_384 table[64]; + /* Count of entries in table. */ uint32_t cnt; + /* Point and table set in entry. */ int set; } sp_cache_384_t; +/* Cache of tables. */ static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES]; +/* Index of last entry in cache. */ static THREAD_LS_T int sp_cache_384_last = -1; +/* Cache has been initialized. */ static THREAD_LS_T int sp_cache_384_inited = 0; #ifndef HAVE_THREAD_LS @@ -27551,9 +28264,15 @@ static THREAD_LS_T int sp_cache_384_inited = 0; static wolfSSL_Mutex sp_cache_384_lock; #endif +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache) { - int i, j; + int i; + int j; uint32_t least; if (sp_cache_384_inited == 0) { @@ -27660,8 +28379,8 @@ static int sp_384_ecc_mulmod_6(sp_point_384* r, const sp_point_384* g, const sp_ } #ifdef HAVE_INTEL_AVX2 -#ifdef FP_ECC -#endif /* FP_ECC */ +#if defined(FP_ECC) || defined(WOLFSSL_SP_SMALL) +#endif /* FP_ECC | WOLFSSL_SP_SMALL */ /* Add two Montgomery form projective points. The second point has a q value of * one. * Only the first point can be the same pointer as the result point. @@ -27691,7 +28410,7 @@ static void sp_384_proj_point_add_qz1_avx2_6(sp_point_384* r, const sp_point_384 sp_384_norm_6(t1); if ((sp_384_cmp_equal_6(p->x, q->x) & sp_384_cmp_equal_6(p->z, q->z) & (sp_384_cmp_equal_6(p->y, q->y) | sp_384_cmp_equal_6(p->y, t1))) != 0) { - sp_384_proj_point_dbl_6(r, p, t); + sp_384_proj_point_dbl_avx2_6(r, p, t); } else { rp[0] = r; @@ -27723,9 +28442,9 @@ static void sp_384_proj_point_add_qz1_avx2_6(sp_point_384* r, const sp_point_384 /* S2 = Y2*Z1^3 */ sp_384_mont_mul_avx2_6(t4, t4, q->y, p384_mod, p384_mp_mod); /* H = U2 - X1 */ - sp_384_mont_sub_6(t2, t2, x, p384_mod); + sp_384_mont_sub_avx2_6(t2, t2, x, p384_mod); /* R = S2 - Y1 */ - sp_384_mont_sub_6(t4, t4, y, p384_mod); + sp_384_mont_sub_avx2_6(t4, t4, y, p384_mod); /* Z3 = H*Z1 */ sp_384_mont_mul_avx2_6(z, z, t2, p384_mod, p384_mp_mod); /* X3 = R^2 - H^3 - 2*X1*H^2 */ @@ -27733,14 +28452,14 @@ static void sp_384_proj_point_add_qz1_avx2_6(sp_point_384* r, const sp_point_384 sp_384_mont_sqr_avx2_6(t5, t2, p384_mod, p384_mp_mod); sp_384_mont_mul_avx2_6(t3, x, t5, p384_mod, p384_mp_mod); sp_384_mont_mul_avx2_6(t5, t5, t2, p384_mod, p384_mp_mod); - sp_384_mont_sub_6(x, t1, t5, p384_mod); - sp_384_mont_dbl_6(t1, t3, p384_mod); - sp_384_mont_sub_6(x, x, t1, p384_mod); + sp_384_mont_sub_avx2_6(x, t1, t5, p384_mod); + sp_384_mont_dbl_avx2_6(t1, t3, p384_mod); + sp_384_mont_sub_avx2_6(x, x, t1, p384_mod); /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */ - sp_384_mont_sub_6(t3, t3, x, p384_mod); + sp_384_mont_sub_avx2_6(t3, t3, x, p384_mod); sp_384_mont_mul_avx2_6(t3, t3, t4, p384_mod, p384_mp_mod); sp_384_mont_mul_avx2_6(t5, t5, y, p384_mod, p384_mp_mod); - sp_384_mont_sub_6(y, t3, t5, p384_mod); + sp_384_mont_sub_avx2_6(y, t3, t5, p384_mod); } } @@ -27768,6 +28487,10 @@ static void sp_384_proj_to_affine_avx2_6(sp_point_384* a, sp_digit* t) } /* Generate the pre-computed table of points for the base point. + * + * width = 6 + * 64 entries + * 64 bits between * * a The base point. * table Place to store generated point data. @@ -27778,12 +28501,15 @@ static int sp_384_gen_stripe_table_avx2_6(const sp_point_384* a, sp_table_entry_384* table, sp_digit* tmp, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) - sp_point_384 td, s1d, s2d; + sp_point_384 td; + sp_point_384 s1d; + sp_point_384 s2d; #endif sp_point_384* t; sp_point_384* s1 = NULL; sp_point_384* s2 = NULL; - int i, j; + int i; + int j; int err; (void)heap; @@ -27797,13 +28523,13 @@ static int sp_384_gen_stripe_table_avx2_6(const sp_point_384* a, } if (err == MP_OKAY) { - err = sp_384_mod_mul_norm_6(t->x, a->x, p384_mod); + err = sp_384_mod_mul_norm_avx2_6(t->x, a->x, p384_mod); } if (err == MP_OKAY) { - err = sp_384_mod_mul_norm_6(t->y, a->y, p384_mod); + err = sp_384_mod_mul_norm_avx2_6(t->y, a->y, p384_mod); } if (err == MP_OKAY) { - err = sp_384_mod_mul_norm_6(t->z, a->z, p384_mod); + err = sp_384_mod_mul_norm_avx2_6(t->z, a->z, p384_mod); } if (err == MP_OKAY) { t->infinity = 0; @@ -27820,14 +28546,14 @@ static int sp_384_gen_stripe_table_avx2_6(const sp_point_384* a, XMEMCPY(table[1].x, t->x, sizeof(table->x)); XMEMCPY(table[1].y, t->y, sizeof(table->y)); - for (i=1; i<8; i++) { - sp_384_proj_point_dbl_n_avx2_6(t, 48, tmp); + for (i=1; i<6; i++) { + sp_384_proj_point_dbl_n_avx2_6(t, 64, tmp); sp_384_proj_to_affine_avx2_6(t, tmp); XMEMCPY(table[1<x, sizeof(table->x)); XMEMCPY(table[1<y, sizeof(table->y)); } - for (i=1; i<8; i++) { + for (i=1; i<6; i++) { XMEMCPY(s1->x, table[1<x)); XMEMCPY(s1->y, table[1<y)); for (j=(1<z, p384_norm_mod, sizeof(p384_norm_mod)); y = 0; - for (j=0,x=47; j<8; j++,x+=48) { + x = 63; + for (j=0; j<6; j++) { y |= (int)(((k[x / 64] >> (x % 64)) & 1) << j); + x += 64; } #ifndef WC_NO_CACHE_RESISTANT if (ct) { - sp_384_get_entry_256_avx2_6(rt, table, y); + sp_384_get_entry_64_avx2_6(rt, table, y); } else #endif { @@ -27917,16 +28650,18 @@ static int sp_384_ecc_mulmod_stripe_avx2_6(sp_point_384* r, const sp_point_384* XMEMCPY(rt->y, table[y].y, sizeof(table[y].y)); } rt->infinity = !y; - for (i=46; i>=0; i--) { + for (i=62; i>=0; i--) { y = 0; - for (j=0,x=i; j<8; j++,x+=48) { + x = i; + for (j=0; j<6; j++) { y |= (int)(((k[x / 64] >> (x % 64)) & 1) << j); + x += 64; } sp_384_proj_point_dbl_avx2_6(rt, rt, t); #ifndef WC_NO_CACHE_RESISTANT if (ct) { - sp_384_get_entry_256_avx2_6(p, table, y); + sp_384_get_entry_64_avx2_6(p, table, y); } else #endif @@ -27957,6 +28692,7 @@ static int sp_384_ecc_mulmod_stripe_avx2_6(sp_point_384* r, const sp_point_384* return err; } +#endif /* FP_ECC | WOLFSSL_SP_SMALL */ /* Multiply the base point of P384 by the scalar and return the result. * If map is true then convert result to affine coordinates. * @@ -28020,8 +28756,8 @@ static int sp_384_ecc_mulmod_avx2_6(sp_point_384* r, const sp_point_384* g, cons * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_384(mp_int* km, ecc_point* gm, ecc_point* r, int map, - void* heap) +int sp_ecc_mulmod_384(const mp_int* km, const ecc_point* gm, ecc_point* r, + int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_384 p; @@ -28070,7 +28806,113 @@ int sp_ecc_mulmod_384(mp_int* km, ecc_point* gm, ecc_point* r, int map, return err; } -static const sp_table_entry_384 p384_table[256] = { +/* Multiply the point by the scalar, add point a and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * p Point to multiply. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_add_384(const mp_int* km, const ecc_point* gm, + const ecc_point* am, int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_384 p; + sp_point_384 a; + sp_digit kd[6]; + sp_digit t[6 * 2 * 6]; +#endif + sp_point_384* point; + sp_point_384* addP = NULL; + sp_digit* k = NULL; + sp_digit* tmp = NULL; + int err = MP_OKAY; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + + err = sp_384_point_new_6(heap, p, point); + if (err == MP_OKAY) { + err = sp_384_point_new_6(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (6 + 6 * 2 * 6), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 6; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 6, km); + sp_384_point_from_ecc_point_6(point, gm); + sp_384_point_from_ecc_point_6(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_6(addP->x, addP->x, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_6(addP->y, addP->y, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_6(addP->z, addP->z, p384_mod); + } + if (err == MP_OKAY) { +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + err = sp_384_ecc_mulmod_avx2_6(point, point, k, 0, 0, heap); + else +#endif + err = sp_384_ecc_mulmod_6(point, point, k, 0, 0, heap); + } + if (err == MP_OKAY) { +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_384_proj_point_add_avx2_6(point, point, addP, tmp); + else +#endif + sp_384_proj_point_add_6(point, point, addP, tmp); + + if (map) { +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_384_map_avx2_6(point, point, tmp); + else +#endif + sp_384_map_6(point, point, tmp); + } + + err = sp_384_point_to_ecc_point_6(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_6(addP, 0, heap); + sp_384_point_free_6(point, 0, heap); + + return err; +} + +#ifdef WOLFSSL_SP_SMALL +/* Striping precomputation table. + * 6 points combined into a table of 64 points. + * Distance of 64 between points. + */ +static const sp_table_entry_384 p384_table[64] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, @@ -28080,1280 +28922,325 @@ static const sp_table_entry_384 p384_table[256] = { { 0x23043dad4b03a4feL,0xa1bfa8bf7bb4a9acL,0x8bade7562e83b050L, 0xc6c3521968f4ffd9L,0xdd8002263969a840L,0x2b78abc25a15c5e9L } }, /* 2 */ - { { 0x298647532b0c535bL,0x90dd695370506296L,0x038cd6b4216ab9acL, - 0x3df9b7b7be12d76aL,0x13f4d9785f347bdbL,0x222c5c9c13e94489L }, - { 0x5f8e796f2680dc64L,0x120e7cb758352417L,0x254b5d8ad10740b8L, - 0xc38b8efb5337dee6L,0xf688c2e194f02247L,0x7b5c75f36c25bc4cL } }, + { { 0xa54768dab1b43eefL,0x13e41f47e14fda22L,0x774df203faef6863L, + 0xf795a034bd7471b3L,0xf0958718b47de2e9L,0xc92f7888e1160cffL }, + { 0x86ded97b0146c790L,0x015918f5480a4b7bL,0x05588920424e8459L, + 0x37455914eecf8b2bL,0xe7d3df1fb968a6faL,0x07a0ffd6bad0719fL } }, /* 3 */ - { { 0xe26a3cc39edffea5L,0x35bbfd1c37d7e9fcL,0xf0e7700d9bde3ef6L, - 0x0380eb471a538f5aL,0x2e9da8bb05bf9eb3L,0xdbb93c731a460c3eL }, - { 0x37dba260f526b605L,0x95d4978efd785537L,0x24ed793aed72a04aL, - 0x2694837776005b1aL,0x99f557b99e681f82L,0xae5f9557d64954efL } }, + { { 0xda37cd535c54db6fL,0x0e37890a91f06c5cL,0x1730ef7be7ae7db5L, + 0x2b3dcd51ff045f54L,0xf5db3c3c72cc8451L,0x3165d6efcf0c185cL }, + { 0x177c4f6bf5958d78L,0xcb29d22f8d676a9fL,0x3bcf0068792ac96dL, + 0x60d1c6b719df5641L,0x426e412a68a099f8L,0xf9ca0c5c9f74d52bL } }, /* 4 */ - { { 0x24480c57f26feef9L,0xc31a26943a0e1240L,0x735002c3273e2bc7L, - 0x8c42e9c53ef1ed4cL,0x028babf67f4948e8L,0x6a502f438a978632L }, - { 0xf5f13a46b74536feL,0x1d218babd8a9f0ebL,0x30f36bcc37232768L, - 0xc5317b31576e8c18L,0xef1d57a69bbcb766L,0x917c4930b3e3d4dcL } }, + { { 0xf186d6bcc88d568aL,0x872bc4c7528535ddL,0xc9e7432edfe64dc3L, + 0xd9fc4832d795ea57L,0xf4ffdb81c845af2bL,0x66d7e7882b670517L }, + { 0xa7c1be04d7b7a1c6L,0xbed88479d5b2a249L,0x62ff8aba03f2ef6dL, + 0x60ecaac420dc701dL,0x9f4b559f4ff10119L,0x0582c9313cd54fd0L } }, /* 5 */ - { { 0x11426e2ee349ddd0L,0x9f117ef99b2fc250L,0xff36b480ec0174a6L, - 0x4f4bde7618458466L,0x2f2edb6d05806049L,0x8adc75d119dfca92L }, - { 0xa619d097b7d5a7ceL,0x874275e5a34411e9L,0x5403e0470da4b4efL, - 0x2ebaafd977901d8fL,0x5e63ebcea747170fL,0x12a369447f9d8036L } }, + { { 0x394fb84de86e3f64L,0xfe4a36e7ff13314eL,0xa1e44b14dc261ec2L, + 0x3924e50a7420408fL,0x637e330242ed7626L,0xeb657b10fd711ba4L }, + { 0xc16d01c5340949bbL,0x30e043267f1f42c7L,0xe7465819b056d872L, + 0x3386f1c6886fb3dbL,0x5be463a5be56f774L,0xa96fd3b74694e15aL } }, /* 6 */ - { { 0x28f9c07a4fc52870L,0xce0b37481a53a961L,0xd550fa180e1828d9L, - 0xa24abaf76adb225aL,0xd11ed0a56e58a348L,0xf3d811e6948acb62L }, - { 0x8618dd774c61ed22L,0x0bb747f980b47c9dL,0x22bf796fde6b8559L, - 0xfdfd1c6d680a21e9L,0xc0db15772af2c9ddL,0xa09379e6c1e90f3dL } }, + { { 0x95dd5ee5a98b4254L,0xea328205aa845e67L,0x98640fb5a1e36348L, + 0xd1bc5c251add5ee7L,0xc3158a423d11b799L,0x5feb68ed47c83d54L }, + { 0x7c5a1204963a207bL,0x2f2b2c7eee4671f8L,0xb63d291cd42867a6L, + 0x0b073620139530f4L,0xbe149492abb05b99L,0x21417da455accd2aL } }, /* 7 */ - { { 0x386c66efe085c629L,0x5fc2a461095bc89aL,0x1353d631203f4b41L, - 0x7ca1972b7e4bd8f5L,0xb077380aa7df8ce9L,0xd8a90389ee7e4ea3L }, - { 0x1bc74dc7e7b14461L,0xdc2cb0140c9c4f78L,0x52b4b3a684ef0a10L, - 0xbde6ea5d20327fe2L,0xb71ec435660f9615L,0xeede5a04b8ad8173L } }, + { { 0x9408555e9e5eba15L,0x416250137b7572c5L,0xfa53ee50bfff6ea7L, + 0x3d682de1e7b178c3L,0xb3e8769dec329f53L,0x1ab8c82e9eb524f4L }, + { 0x5bbd538dde2f1eb9L,0x1d1b0bea2b19c51eL,0xf785f9b98cb06eeeL, + 0x5cff29c6f58f21d5L,0x44aaa52245cbaef3L,0xd60c19427de40246L } }, /* 8 */ - { { 0x5584cbb3893b9a2dL,0x820c660b00850c5dL,0x4126d8267df2d43dL, - 0xdd5bbbf00109e801L,0x85b92ee338172f1cL,0x609d4f93f31430d9L }, - { 0x1e059a07eadaf9d6L,0x70e6536c0f125fb0L,0xd6220751560f20e7L, - 0xa59489ae7aaf3a9aL,0x7b70e2f664bae14eL,0x0dd0370176d08249L } }, - /* 9 */ - { { 0x4cc13be88510521fL,0x87315ba9f724cc17L,0xb49d83bb353dc263L, - 0x8b677efe0c279257L,0x510a1c1cc93c9537L,0x33e30cd8a4702c99L }, - { 0xf0ffc89d2208353fL,0x0170fa8dced42b2bL,0x090851ed26e2a5f5L, - 0x81276455ecb52c96L,0x0646c4e17fe1adf4L,0x513f047eb0868eabL } }, - /* 10 */ - { { 0xc07611f4df5bdf53L,0x45d331a758b11a6dL,0x58965daf1c4ee394L, - 0xba8bebe75a5878d1L,0xaecc0a1882dd3025L,0xcf2a3899a923eb8bL }, - { 0xf98c9281d24fd048L,0x841bfb598bbb025dL,0xb8ddf8cec9ab9d53L, - 0x538a4cb67fef044eL,0x092ac21f23236662L,0xa919d3850b66f065L } }, - /* 11 */ - { { 0x3db03b4085d480d8L,0x8cd9f4791b287a7dL,0x8f24dc754a8f3baeL, - 0x482eb8003db41892L,0x38bf9eb39c56e0f5L,0x8b9773209a91dc6fL }, - { 0xa31b05b27209cfc2L,0x4c49bf8505b2db70L,0x56462498d619527bL, - 0x3fe510391fac51baL,0xfb04f55eab4b8342L,0xc07c10dc04c6eabfL } }, - /* 12 */ - { { 0xad22fe4cdb32f048L,0x5f23bf91475ed6dfL,0xa50ce0c0aa66b6cbL, - 0xdf627a89f03405c0L,0x3674837df95e2d6aL,0x081c95b6ba42e64eL }, - { 0xeba3e036e71d6cebL,0xb45bcccf6c6b0271L,0x67b47e630684701dL, - 0x60f8f942e712523fL,0x824234725cd47adcL,0x83027d7987649cbbL } }, - /* 13 */ - { { 0xb3929ea63615b0b8L,0xb41441fda54dac41L,0x8995d556b5b6a368L, - 0xa80d4529167ef05eL,0xf6bcb4a16d25a27fL,0x210d6a4c7bd55b68L }, - { 0xf3804abb25351130L,0x1d2df699903e37ebL,0x5f201efc084c25c8L, - 0x31a28c87a1c68e91L,0x81dad253563f62a5L,0x5dd6de70d6c415d4L } }, - /* 14 */ - { { 0x29f470fd846612ceL,0x986f3eecda18d997L,0x6b84c1612f34af86L, - 0x5ef0a40846ddaf8bL,0x14405a00e49e795fL,0x5f491b16aa2f7a37L }, - { 0xc7f07ae4db41b38dL,0xef7d119e18fbfcaaL,0x3a18e07614443b19L, - 0x4356841a79a19926L,0x91f4a91ce2226fbeL,0xdc77248c3cc88721L } }, - /* 15 */ - { { 0xd570ff1ae4b1ec9dL,0x21d23e0ee7eef706L,0x3cde40f4ca19e086L, - 0x7d6523c4cd4bb270L,0x16c1f06cbf13aa6cL,0x5aa7245ad14c4b60L }, - { 0x37f8146744b74de8L,0x839e7a17620a934eL,0xf74d14e8de8b1aa1L, - 0x8789fa51f30d75e2L,0x09b24052c81c261eL,0x654e267833c565eeL } }, - /* 16 */ { { 0x378205de2f9fbe67L,0xc4afcb837f728e44L,0xdbcec06c682e00f1L, 0xf2a145c3114d5423L,0xa01d98747a52463eL,0xfc0935b17d717b0aL }, { 0x9653bc4fd4d01f95L,0x9aa83ea89560ad34L,0xf77943dcaf8e3f3fL, 0x70774a10e86fe16eL,0x6b62e6f1bf9ffdcfL,0x8a72f39e588745c9L } }, - /* 17 */ + /* 9 */ { { 0x73ade4da2341c342L,0xdd326e54ea704422L,0x336c7d983741cef3L, 0x1eafa00d59e61549L,0xcd3ed892bd9a3efdL,0x03faf26cc5c6c7e4L }, { 0x087e2fcf3045f8acL,0x14a65532174f1e73L,0x2cf84f28fe0af9a7L, 0xddfd7a842cdc935bL,0x4c0f117b6929c895L,0x356572d64c8bcfccL } }, + /* 10 */ + { { 0x984a6aed6420bc66L,0x6d90e0e0896a24a6L,0xe0adb93a18713003L, + 0xf00d424c1a8369fcL,0x636ebf14712ae802L,0xee39ff8ebe9d739aL }, + { 0xb330dd3e94f6d1dcL,0x6ba6780eb7731cf8L,0x4e569408198be5a2L, + 0x6639523b0193a22cL,0x6978cc9d91aa1455L,0x62062d8f329f9763L } }, + /* 11 */ + { { 0x7159107d80efff78L,0xf8ed5f8e8e4c39d5L,0x64a2265cc15e679cL, + 0xfc514e17a6d96c81L,0x59c86545f093e0a8L,0x804b0a588b5a336aL }, + { 0x94c32118cb9dcbcaL,0x2deb0e385d45251dL,0xd1092b0986869572L, + 0x073bf838fb2e9f97L,0x76b6d7d6de700fcbL,0xd2a6d110f2ddce5fL } }, + /* 12 */ + { { 0x6da7ccd0229de19eL,0x5050d45df0aa039dL,0xf9f01d68d9e7a861L, + 0x6d8b9f2000aa05f2L,0xae3d9698742cd4d9L,0x43e477abd560c394L }, + { 0x73d594991cb6dd81L,0x689162b2fac3f62eL,0xd6187ca864d1d0d5L, + 0xe8421a0d2f067457L,0x9b266acbea7c3a8dL,0x707e0e6e44df5cb3L } }, + /* 13 */ + { { 0x604b2a1a026511a0L,0xd4f6cf16256f4076L,0x7d823347b315a642L, + 0x8f805833786aa438L,0x9883df85f04bb4b3L,0x02bc10305bba6d84L }, + { 0xfe39a024a72c03acL,0xa980db635f2dbfd0L,0xcd53149f4f259ec6L, + 0xe969079b43f53f97L,0xd3849fdb42f9f27cL,0xd2cfd3f842653dc9L } }, + /* 14 */ + { { 0xbf69fe6a6abe7d80L,0x4932288192bb50e2L,0xc9e2f7fb61e8b18dL, + 0x24c74788f6c82421L,0xe79e5e3011c0b244L,0xd6612c70e0484571L }, + { 0x7863ff927ef82d17L,0x692790feb0a1b01cL,0xa2d6ffb5afe51546L, + 0xacdb43f26cf550c6L,0x3b3243dfaecfaf8fL,0x9557335ac233bcd9L } }, + /* 15 */ + { { 0x25e08c8faff5b387L,0x112c11e2d06208ceL,0x61031c1765234214L, + 0xba06f5550514764dL,0xfaacf6f39bd197d0L,0xe4b032321464a57fL }, + { 0x00c19adfe35dcd69L,0x81b75730a1c2646cL,0x47baa4fee0c50e32L, + 0xe9297832bcaddb3bL,0x1768d2f9d712c6cfL,0xfcef29fdb82e9eeaL } }, + /* 16 */ + { { 0xdbe04c3044ce3ad8L,0x995fbb1b4ce8aad5L,0xdbf8b54670911457L, + 0x9e683b5b3f7a1757L,0x7b89a08a9c7bd62cL,0x448865a40b3fc97eL }, + { 0x0ac9abfc3bb01e94L,0xa07760421e756124L,0x0aa6c335d9deed97L, + 0xe270580f72603e08L,0x70857a946c783bb2L,0xa0047774caa929aeL } }, + /* 17 */ + { { 0x56211190a353e889L,0x052917c3190eb198L,0xadfd85b03eee3d12L, + 0xde1d761779fd9c91L,0x05be51b7bf500159L,0x271f07178fcb87f1L }, + { 0x02673e273a75ac71L,0xb1b7246eda12da8dL,0xb25647928f5fb8c0L, + 0x0a22cbe1063b1d7fL,0xb0d7a7365649976eL,0x8f8e6e289e96b15dL } }, /* 18 */ - { { 0x7ecbac017d8c1bbaL,0x6058f9c390b0f3d5L,0xaee116e3f6197d0fL, - 0xc4dd70684033b128L,0xf084dba6c209b983L,0x97c7c2cf831dbc4aL }, - { 0x2f4e61ddf96010e8L,0xd97e4e20529faa17L,0x4ee6666069d37f20L, - 0xccc139ed3d366d72L,0x690b6ee213488e0fL,0x7cad1dc5f3a6d533L } }, + { { 0x8fc113f98312351cL,0xe837b9e0c5eff002L,0x7cb9ef074dad72fcL, + 0x18a8d43eb5eb7ee3L,0x2cf3ae844925efdbL,0x376e9e857756ec6aL }, + { 0xf77a79c8a3e3705fL,0x2d590b7d6c5fbab3L,0xa59713e27a4766c3L, + 0xb5da6a6861544174L,0xadb04a8adab1fe76L,0x03b6138d375143b4L } }, /* 19 */ - { { 0x660a9a81da57a41fL,0xe74a0412ec0039b6L,0x42343c6b5e1dad15L, - 0x284f3ff546681d4cL,0xb51087f163749e89L,0x070f23cc6f9f2f13L }, - { 0x542211da5d186e14L,0x84748f37fddb0dffL,0x41a3aab4db1f4180L, - 0x25ed667ba6402d0eL,0x2f2924a902f58355L,0x5844ee7cfa44a689L } }, + { { 0x20d88a80c1bfa043L,0x88806999672583ceL,0x195a89eaaea9b605L, + 0x0b9b4e8532bac07bL,0x8279965683868df6L,0x83c58afab52711a9L }, + { 0xb895c13d1c869283L,0x00f98d046206dde6L,0x76caaa22884bf311L, + 0x22b2137f995b29a5L,0x7f645809b098b07bL,0xa540c8a6050e2552L } }, /* 20 */ - { { 0xfab086073f3b236fL,0x19e9d41d81e221daL,0xf3f6571e3927b428L, - 0x4348a9337550f1f6L,0x7167b996a85e62f0L,0x62d437597f5452bfL }, - { 0xd85feb9ef2955926L,0x440a561f6df78353L,0x389668ec9ca36b59L, - 0x052bf1a1a22da016L,0xbdfbff72f6093254L,0x94e50f28e22209f3L } }, + { { 0x47980509e562d904L,0xe736f89d031e112cL,0xbc6bfb0765d8ae25L, + 0xe9ed4cc4ca459646L,0xf540e90e2fff67ffL,0x836280eb1a314e11L }, + { 0xa710b25041610627L,0xefc22b1573a9f9a2L,0x60f20789456498c0L, + 0x417920438052f4e7L,0x5c850903d5c0e80dL,0x52df5275bf1d8815L } }, /* 21 */ - { { 0x90b2e5b33062e8afL,0xa8572375e8a3d369L,0x3fe1b00b201db7b1L, - 0xe926def0ee651aa2L,0x6542c9beb9b10ad7L,0x098e309ba2fcbe74L }, - { 0x779deeb3fff1d63fL,0x23d0e80a20bfd374L,0x8452bb3b8768f797L, - 0xcf75bb4d1f952856L,0x8fe6b40029ea3faaL,0x12bd3e4081373a53L } }, + { { 0x25539de98ece218dL,0xb36574a8dca420baL,0x9d1812680e0d07feL, + 0xea79a5f5ad3ed34fL,0x8b739ad57c9277cfL,0xd88659886ee9a930L }, + { 0xaf07bfb621591a3eL,0xe0138c6508f3524fL,0xd3128f1297ee315eL, + 0x67f8641e21045f63L,0x3e1a96b140c73a2dL,0x8976b70305f51122L } }, /* 22 */ - { { 0xc023780d104cbba5L,0x6207e747fa35dd4cL,0x35c239281ca9b6a3L, - 0x4ff19be897987b10L,0xb8476bbf8022eee8L,0xaa0a4a14d3bbe74dL }, - { 0x20f94331187d4543L,0x3215387079f6e066L,0x83b0f74eac7e82e1L, - 0xa7748ba2828f06abL,0xc5f0298ac26ef35fL,0x0f0c50708e9a7dbdL } }, + { { 0xdeaf635731960db4L,0x680b054e5948d7f7L,0x0841e40fd272bb5cL, + 0x94d37db26e36117dL,0xaf2d001547f63ec8L,0x82665cdc47493309L }, + { 0xfe90e844abbe3851L,0x8357709afb79bc0cL,0x811a64d2b6bcc044L, + 0x1937c988882b3415L,0xe8b28724e267b271L,0x84d1eed0af89ed33L } }, /* 23 */ - { { 0x0c5c244cdef029ddL,0x3dabc687850661b8L,0x9992b865fe11d981L, - 0xe9801b8f6274dbadL,0xe54e6319098da242L,0x9929a91a91a53d08L }, - { 0x37bffd7235285887L,0xbc759425f1418102L,0x9280cc35fd2e6e20L, - 0x735c600cfbc42ee5L,0xb7ad28648837619aL,0xa3627231a778c57bL } }, + { { 0x52b8234f54c894a7L,0xfe54146fa2d11b70L,0x6412b5eb0aab6097L, + 0xa62499906a13a9daL,0xd2b1eb50adc448caL,0xe7ab51f9b115ab92L }, + { 0x4638ee62e76551d8L,0x74c3c1e1afe9c98dL,0x59000ad060d77322L, + 0x0a4b105ba06adc9aL,0xcdaeb4a496a6f616L,0x8c79c4a1864b49dcL } }, /* 24 */ - { { 0xae799b5c91361ed8L,0x47d71b756c63366cL,0x54cdd5211b265a6aL, - 0xe0215a5998d77b74L,0x4424d9b7bab29db0L,0x8b0ffacc7fd9e536L }, - { 0x46d85d1237b5d9efL,0x5b106d62bfa91747L,0xed0479f85f99ba2dL, - 0x0e6f39231d104de4L,0x83a84c8425e8983fL,0xa9507e0af8105a70L } }, + { { 0xc09c32d1c0b1bf15L,0x005d510f88d74e44L,0x031f9a9afc2c089eL, + 0x08aac7294ba183f0L,0xf227a7ceaf2245ebL,0xb4ec33cbb3a864ffL }, + { 0xdb76decd570a24f3L,0xea59387a12283a9eL,0x81b7c569341ef9a4L, + 0xad7c98bd8d77833aL,0x2182133b49ca80ffL,0x1de1d456085802b7L } }, /* 25 */ - { { 0xf6c68a6e14cf381cL,0xaf9d27bdc22e31ccL,0x23568d4daa8a5ccbL, - 0xe431eec0e338e4d2L,0xf1a828fe8f52ad1fL,0xdb6a0579e86acd80L }, - { 0x2885672e4507832aL,0x73fc275f887e5289L,0x65f8027805610d08L, - 0x8d9b4554075ff5b0L,0x3a8e8fb109f712b5L,0x39f0ac862ebe9cf2L } }, + { { 0xeead25b2e1c02860L,0xb2ae43694ff42d2eL,0x4b39a2ddfd61c1b0L, + 0x29c826ea968718a5L,0x877fdf15d9751a0aL,0x00b321dfb54affdfL }, + { 0x3c7c0778d4d5dbf7L,0x858a0fdccfc47423L,0xbd8e6544185b3063L, + 0xa22c3ef62da46a04L,0x5c2d84016a6c0ce1L,0x260246eddd6329aeL } }, /* 26 */ - { { 0xd8fabf784c52edf5L,0xdcd737e5a589ae53L,0x94918bf0d791ab17L, - 0xb5fbd956bcff06c9L,0xf6d3032edca46d45L,0x2cdff7e141a3e486L }, - { 0x6674b3ba61f47ec8L,0x8a882163eef84608L,0xa257c7054c687f90L, - 0xe30cb2edf6cdf227L,0x2c4c64ca7f6ea846L,0x186fa17ccc6bcd3cL } }, + { { 0x71753fc00c6463f6L,0x7ec14c015c6c9e33L,0x28b9ab9441ce6153L, + 0x3a1ac251a6702c8dL,0x2b124bc49ed6cb1fL,0x7a11c4be4fc7383fL }, + { 0x1414913509fac991L,0xf7c188d3cb1ee336L,0x754bc47391c3f406L, + 0x71d34587cad39500L,0x213dd1a7dd0399a1L,0x8457a8f671d05899L } }, /* 27 */ - { { 0x48a3f5361dfcb91eL,0x83595e13646d358aL,0xbd15827b91128798L, - 0x3ce612b82187757aL,0x873150a161bd7372L,0xf4684530b662f568L }, - { 0x8833950b401896f6L,0xe11cb89a77f3e090L,0xb2f12cac48e7f4a5L, - 0x313dd769f606677eL,0xfdcf08b316579f93L,0x6429cec946b8f22bL } }, + { { 0xa921ca662e9c06d3L,0x1d8974e89ba6521fL,0xbb465c775f79f791L, + 0x8f983f083a3954c8L,0x8492f8398b3935dcL,0x2b87d9c290c04426L }, + { 0xcec76ea403e60a28L,0x648e9830aa631308L,0x7b542f791eb86b73L, + 0xfc8cc9a3150d854dL,0x2be86940bfcc83feL,0x2e58a13ac88c7585L } }, /* 28 */ - { { 0x4984dd54bb75f9a4L,0x4aef06b929d3b570L,0xb5f84ca23d6e4c1eL, - 0x24c61c11b083ef35L,0xce4a7392392ca9ffL,0x865d65176730a800L }, - { 0xca3dfe76722b4a2bL,0x12c04bf97b083e0eL,0x803ce5b51b86b8a5L, - 0x3fc7632d6a7e3e0cL,0xc89970c2c81adbe4L,0x3cbcd3ad120e16b1L } }, + { { 0x19249a8fd1bc237fL,0xdec1c6a563505555L,0xc8256977bad2a93bL, + 0x78533659fc598170L,0x888a6578ee7e53cbL,0x28783b0e33766db3L }, + { 0xcf791e56e42c28f2L,0xfbf8dde8f9c37f4cL,0xf0ffaf1712c05395L, + 0xd27d21e9daf2f012L,0xf90432da9a7be009L,0xa459c036a8012f28L } }, /* 29 */ - { { 0xfbfb4cc7ec30ce93L,0x10ed6c7db72720a2L,0xec675bf747b55500L, - 0x90725903333ff7c3L,0xc7c3973e5075bfc0L,0xb049ecb007acf31bL }, - { 0xb4076eaf4f58839cL,0x101896daa2b05e4fL,0x3f6033b0ab40c66eL, - 0x19ee9eebc8d864baL,0xeb6cf15547bf6d2aL,0x8e5a9663f826477dL } }, + { { 0x4d99a7cac8b1c6d4L,0x8088818825c899c0L,0xbd27e9be2ebdeb3dL, + 0x73c3e0aa054e77c1L,0x180c848498534ce5L,0x750d52f754ffa9cdL }, + { 0x5f26eeb16f702f4cL,0x427fc6e4cc76d8f4L,0x93126b8d026b631dL, + 0x5356b93917e145a7L,0xc79ca872c0be7c84L,0x3fca7cad4b615fb7L } }, /* 30 */ - { { 0x69e62fddf7fbd5e1L,0x38ecfe5476912b1dL,0x845a3d56d1da3bfbL, - 0x0494950e1c86f0d4L,0x83cadbf93bc36ce8L,0x41fce5724fccc8d1L }, - { 0x05f939c28332c144L,0xb17f248b0871e46eL,0x3d8534e266e8aff6L, - 0x1d06f1dc3b85c629L,0xdb06a32ea3131b73L,0xf295184d8b3f64e5L } }, + { { 0xed48fe78d0241021L,0x252b14a0142f7f8eL,0x19ab85c6db573a09L, + 0x546c3960f3df906fL,0xc688f4b22c810ea8L,0xbccf0cca5ff9e108L }, + { 0x34f4609e3f2cc69bL,0xf3b1efe414afe4f4L,0x5d809cef37a8ef74L, + 0xa8d1978a176ba328L,0x75dde11fdf59ecb9L,0x34eeeaffa9916ee2L } }, /* 31 */ - { { 0xd9653ff736ddc103L,0x25f43e3795ef606fL,0x09e301fcfe06dce8L, - 0x85af234130b6eebfL,0x79b12b530ff56b20L,0x9b4fb499fe9a3c6bL }, - { 0x0154f89251d27ac2L,0xd33167e356ca5389L,0x7828ec1fafc065a6L, - 0x0959a2587f746c9bL,0xb18f1be30c44f837L,0xa7946117c4132fdbL } }, + { { 0xe7f603f248e83c85L,0xa94a539cfa581815L,0x5a61a596dba360b7L, + 0x6cc51dd16a77ef79L,0x4ff36ae0fdbceb9dL,0xfcff65323e8a9c07L }, + { 0x0ba0ce5436d4d0b8L,0x98087a452464efc2L,0xd456843bcc1a2ba7L, + 0x677384a53853e04cL,0x625d32d56c7971deL,0x86882509f724b331L } }, /* 32 */ - { { 0xc0426b775e3c647bL,0xbfcbd9398cf05348L,0x31d312e3172c0d3dL, - 0x5f49fde6ee754737L,0x895530f06da7ee61L,0xcf281b0ae8b3a5fbL }, - { 0xfd14973541b8a543L,0x41a625a73080dd30L,0xe2baae07653908cfL, - 0xc3d01436ba02a278L,0xa0d0222e7b21b8f8L,0xfdc270e9d7ec1297L } }, + { { 0xc20fb9111a42e5e7L,0x075a678b81d12863L,0x12bcbc6a5cc0aa89L, + 0x5279c6ab4fb9f01eL,0xbc8e178911ae1b89L,0xae74a706c290003cL }, + { 0x9949d6ec79df3f45L,0xba18e26296c8d37fL,0x68de6ee2dd2275bfL, + 0xa9e4fff8c419f1d5L,0xbc759ca4a52b5a40L,0xff18cbd863b0996dL } }, /* 33 */ - { { 0x00873c0cbc7f41d6L,0xd976113e1b7ad641L,0x2a536ff4238443fbL, - 0x030d00e241e62e45L,0x532e98675f545fc6L,0xcd0331088e91208cL }, - { 0xd1a04c999797612cL,0xd4393e02eea674e2L,0xd56fa69ee19742a1L, - 0xdd2ab48085f0590eL,0xa5cefc5248a2243dL,0x48cc67b654383f41L } }, + { { 0x684a681892a5eeeaL,0x1f5b193242a09264L,0x30bd8695d98a2f34L, + 0x6e775e019a8601fcL,0x8126bdc24ca956f8L,0x149e73d9e5595daaL }, + { 0x876428401f851e83L,0x4b8863dbd3a7c4a0L,0xe1e43b3d8c95d7d9L, + 0x7f1e307ea60fd528L,0xbf2fa5d134341610L,0x11ad4a8181c502d3L } }, /* 34 */ - { { 0x4e50430efc14ab48L,0x195b7f4f26706a74L,0x2fe8a228cc881ff6L, - 0xb1b968e2d945013dL,0x936aa5794b92162bL,0x4fb766b7364e754aL }, - { 0x13f93bca31e1ff7fL,0x696eb5cace4f2691L,0xff754bf8a2b09e02L, - 0x58f13c9ce58e3ff8L,0xb757346f1678c0b0L,0xd54200dba86692b3L } }, + { { 0xc7df022e782dd401L,0xd15aa9a9a7bcc543L,0x6aa42774b94df1d0L, + 0xab2660c30592a13eL,0xaf4e40809ffc40c7L,0x01152c8d9cd52b10L }, + { 0x649de1d99034a33aL,0x2b9d0ef0d758abfcL,0xdddd0bc2d458adddL, + 0xe5366ac9c09837f8L,0xa003abbb7b1ae35fL,0x880062887ab1fddeL } }, /* 35 */ - { { 0x9a030bbd6dda1265L,0xf7b4f3fce89718ddL,0xa6a4931f936065b8L, - 0xbce72d875f72241cL,0x6cbb51cb65775857L,0xc71618154e993675L }, - { 0xe81a0f792ee32189L,0xef2fab26277dc0b2L,0x9e64f6feb71f469fL, - 0xb448ce33dfdaf859L,0x3f5c1c4cbe6b5df1L,0xfb8dfb001de45f7bL } }, + { { 0x6b6c8f055288f1b4L,0xba05407c033738b4L,0x26cac3a941a955e3L, + 0x28f1692f8e0e0601L,0x2032cb36842c4887L,0x6adeba457d76b20fL }, + { 0xd282c2ce654c6f5cL,0x30584ca5be9ba4f1L,0x45d766a01b2c528bL, + 0xe918bad7c0c6f8ccL,0x1e050b2a0560f070L,0x4fc95de12d6dd010L } }, /* 36 */ - { { 0xc7345fa74d5bb921L,0x5c7e04be4d2b667eL,0x47ed3a80282d7a3eL, - 0x5c2777f87e47b2a4L,0x89b3b10008488e2eL,0x9aad77c2b2eb5b45L }, - { 0xd681bca7daac34aeL,0x2452e4e526afb326L,0x0c88792441a1ee14L, - 0x743b04d4c2407adeL,0xcb5e999bfc17a2acL,0x4dca2f824a701a06L } }, + { { 0x2bb26072150191d5L,0xea2617618108dcf6L,0x4dfa1303e6083c63L, + 0xfa4e0709e2876fb8L,0xf901fed0b1668763L,0xf01c53aeb82c967aL }, + { 0xb43e59d39ed827e8L,0xb58e157e57774eefL,0x57ee54e31b83dceeL, + 0x3d896f32613aa922L,0x69d40667b5c7bfc5L,0xd402b5cb77a2c0d8L } }, /* 37 */ - { { 0x68e31ca61127bc1aL,0xa3edd59b17ead3beL,0x67b6b645e25f5a15L, - 0x76221794a420e15eL,0x794fd83b4b1e872eL,0x7cab3f03b2dece1bL }, - { 0x7119bf15ca9b3586L,0xa55459244d250bd7L,0x173633eacc6bcf24L, - 0x9bd308c2b1b6f884L,0x3bae06f5447d38c3L,0x54dcc135f341fe1cL } }, + { { 0xabeb70127d3c9923L,0x412ada8dd7ecb93aL,0xeb64dc910b71ae2fL, + 0x52ef537aa9ab061aL,0x0863970fc1b55faeL,0xfaff5fb9b1182dbdL }, + { 0x5551d6fed0abaa17L,0x7bb3e02072d641f6L,0x939d7793aa9d288cL, + 0x1450f8bf9078e2c2L,0x24ccd102a086b6aeL,0x57d1796f6a3f8a5fL } }, /* 38 */ - { { 0x56d3598d943caf0dL,0xce044ea9225ff133L,0x9edf6a7c563fadeaL, - 0x632eb94473e8dc27L,0x814b467e3190dcabL,0x2d4f4f316dbb1e31L }, - { 0x8d69811ca143b7caL,0x4ec1ac32de7cf950L,0x223ab5fd37b5fe82L, - 0xe82616e49390f1d9L,0xabff4b2075804610L,0x11b9be15875b08f0L } }, + { { 0x1023120683ce1f76L,0xd16d4b9f03ee406fL,0x9d39c39883caa4b7L, + 0x875732f5ce299b93L,0x1e6a425d2f121f4aL,0x4b1f1d835d8c3279L }, + { 0xe655f58856dd6a6cL,0x23f106475843fd34L,0x932b7d942bad6ce2L, + 0x70a0580e6772a52eL,0x3240118ac88537afL,0x9ccb2ca9d2407224L } }, /* 39 */ - { { 0x4ae31a3d3bbe682cL,0xbc7c5d2674eef2ddL,0x92afd10a3c47dd40L, - 0xec7e0a3bc14ab9e1L,0x6a6c3dd1b2e495e4L,0x085ee5e9309bcd85L }, - { 0xf381a9088c2e67fdL,0x32083a80e261eaf2L,0x0fcd6a4996deee15L, - 0xe3b8fb035e524c79L,0x8dc360d91d5b08b9L,0x3a06e2c87f26719fL } }, + { { 0xa6a40db8710f2324L,0xb3567518c2a8a09aL,0x8816442841b5650aL, + 0x2a352ed27570ba50L,0x23ee46b94c85d77eL,0x643aceffd858a8c3L }, + { 0xe067908de3f02e82L,0x8d5869f2ffb8cf81L,0x4713f0820bc8ad7eL, + 0xe1ee44c780057c40L,0xb34395087d2cf34eL,0x4307b0e10336a207L } }, /* 40 */ - { { 0x5cd9f5a87237cac0L,0x93f0b59d43586794L,0x4384a764e94f6c4eL, - 0x8304ed2bb62782d3L,0x0b8db8b3cde06015L,0x4336dd535dbe190fL }, - { 0x5744355392ab473aL,0x031c7275be5ed046L,0x3e78678c21909aa4L, - 0x4ab7e04f99202ddbL,0x2648d2066977e635L,0xd427d184093198beL } }, + { { 0xe9c1e45746e4d003L,0xa23978c394332057L,0x0e2f300829575db6L, + 0x50a51ff490441e9eL,0x38ce3ed0508d4a07L,0x6a997411cfd7224eL }, + { 0x4d147c31da6b1e1dL,0xedf604b2da8a3547L,0x7a1b8cf0d5e9ceedL, + 0xd74e501213544e6aL,0xcc49f8da4ad968f9L,0xfb87e604cc69ada9L } }, /* 41 */ - { { 0x822848f50f9b5a31L,0xbb003468baadb62aL,0x233a04723357559cL, - 0x49ef688079aee843L,0xa89867a0aeb9e1e3L,0xc151931b1f6f9a55L }, - { 0xd264eb0bad74251eL,0x37b9b2634abf295eL,0xb600921b04960d10L, - 0x0de53dbc4da77dc0L,0x01d9bab3d2b18697L,0xad54ec7af7156ddfL } }, + { { 0xde79409bdf166882L,0xd645b836d46cc527L,0xda4a02f3b6c3eb28L, + 0x845e3c5900e7cf86L,0x733bdc9b604c6d80L,0xe3a1244b847acd97L }, + { 0x421312d6d128842cL,0x81f71feaa1c598efL,0xc619465545eaf796L, + 0x1ffb85121f338b6cL,0xe7aed7106632f064L,0xf8d1ffb7f5b6e510L } }, /* 42 */ - { { 0x8e74dc3579efdc58L,0x456bd3694ff68ddbL,0x724e74ccd32096a5L, - 0xe41cff42386783d0L,0xa04c7f217c70d8a4L,0x41199d2fe61a19a2L }, - { 0xd389a3e029c05dd2L,0x535f2a6be7e3fda9L,0x26ecf72d7c2b4df8L, - 0x678275f4fe745294L,0x6319c9cc9d23f519L,0x1e05a02d88048fc4L } }, + { { 0x7d3f031f3eace851L,0xef43ab7025923624L,0xbae811881af6cdecL, + 0xb7e93b49ea862112L,0xe35a4fc6af23aba2L,0xc52e1fc0aecc593eL }, + { 0xbffa292428148b99L,0xd08040fc89e3d795L,0x7da320032db47b3aL, + 0xe78b44e5a0eb7aa3L,0xd1648ec8f0ec090bL,0x4048dba7740fe871L } }, /* 43 */ - { { 0x75cc8e2ed4d5ffe8L,0xf8bb4896dbea17f2L,0x35059790cee3cb4aL, - 0x4c06ee85a47c6165L,0xf98fff2592935d2fL,0x34c4a57232ffd7c7L }, - { 0xc4b14806ea0376a2L,0x2ea5e7504f115e02L,0x532d76e21e55d7c0L, - 0x68dc9411f31044daL,0x9272e46571b77993L,0xadaa38bb93a8cfd5L } }, + { { 0x6fddb89fa00a14acL,0x844f991508aa06e7L,0x6d5ac4a9f76aca7dL, + 0xfba1ba85e9fa4d51L,0x159633bbb2ea0fc7L,0xa2eb0e4b76ba2854L }, + { 0x8a858155c11f5398L,0x30a96e535e8ea044L,0x696210c197e05a47L, + 0x86e55f9415036f4bL,0x0c93ea9c6a96d9d7L,0xb7ba506179eba3daL } }, /* 44 */ - { { 0x4bf0c7127d4ed72aL,0xda0e9264ba1f79a3L,0x48c0258bf4c39ea4L, - 0xa5394ed82a715138L,0x4af511cebf06c660L,0xfcebceefec5c37cdL }, - { 0xf23b75aa779ae8c1L,0xdeff59ccad1e606eL,0xf3f526fd22755c82L, - 0x64c5ab44bb32cefdL,0xa96e11a2915bdefdL,0xab19746a1143813eL } }, + { { 0xd305c733cd94d7b2L,0x9ea33e363e7955b2L,0x78a98855bc73812fL, + 0xfb1b791d48a3a9a0L,0x6e5107ee04014aafL,0x0412b2c00ea07de0L }, + { 0xdd3a2408ddcaca68L,0x5d18e69ae3344f29L,0x3ce65481f9017408L, + 0x50abb4568cbd64fbL,0x442fa5098916a9ebL,0x16b3ddc7c538c410L } }, /* 45 */ - { { 0x43c78585ec837d7dL,0xca5b6fbcb8ee0ba4L,0x34e924d9d5dbb5eeL, - 0x3f4fa104bb4f1ca5L,0x15458b72398640f7L,0x4231faa9d7f407eaL }, - { 0x53e0661ef96e6896L,0x554e4c69d03b0f9dL,0xd4fcb07b9c7858d1L, - 0x7e95279352cb04faL,0x5f5f15748974e7f7L,0x2e3fa5586b6d57c8L } }, + { { 0x6757dbfd25e331abL,0x0efde50ba3eaafbcL,0x1cd46222d531d29cL, + 0x1b713ca93561cb2bL,0x7d07334bfb5bc99dL,0x95dba43e885a417dL }, + { 0x1c9c3f3f77823a59L,0x43533ba83220cb7fL,0x1b918bc182e3e401L, + 0x66a039aacd3fec87L,0x1d39dbb02dad36d5L,0x554025959dc04be4L } }, /* 46 */ - { { 0x42cd48036a9951a8L,0xa8b15b8842792ad0L,0x18e8bcf9abb29a73L, - 0xbfd9a092409933e8L,0x760a3594efb88dc4L,0x1441886340724458L }, - { 0x162a56ee99caedc7L,0x8fb12ecd91d101c9L,0xea671967393202daL, - 0x1aac8c4aa4ccd796L,0x7db050361cf185a8L,0x0c9f86cd8cfd095aL } }, + { { 0xdf39920847744933L,0x4264f7ea82524dd6L,0xdb57ec08e5182c6dL, + 0x2d6778e705c5e7bfL,0x3f37793f96f53ea2L,0x6472cbae05c47e48L }, + { 0x9e6dd60fbf78067cL,0xa2817ec2cef34088L,0xde4715b8168edde9L, + 0x6c57105146bf31e1L,0x98113fbbc4272bc0L,0x03bb7922cc3b90c3L } }, /* 47 */ - { { 0x9a72814710b2a556L,0x767ca964327b70b2L,0x04ed9e125e3799b7L, - 0x6781d2dc22a3eb2aL,0x5bd116eb0d9450acL,0xeccac1fca7ebe08aL }, - { 0xde68444fdc2d6e94L,0x3621f42935ecf21bL,0x14e2d54329e03a2cL, - 0x53e42cd57d3e7f0aL,0xbba26c0973ed00b9L,0x00297c39c57d2272L } }, + { { 0xe0f23be157d88fefL,0x4125c55b0ca27a01L,0xeadf527e14a71262L, + 0x1f2e803ccc4e9a04L,0x32e07b47d68c4fcfL,0x1577fab79db5070bL }, + { 0xd786d6e57831990aL,0xf64ff4b154fbde40L,0x4bac5b034f9450aeL, + 0x06ae25e055116af9L,0x33d84ea2d7b4fcfcL,0x44a92e73569c3b9eL } }, /* 48 */ - { { 0x3aaaab10b8243a7dL,0x6eeef93e8fa58c5bL,0xf866fca39ae7f764L, - 0x64105a2661ab04d3L,0xa3578d8a03945d66L,0xb08cd3e4791b848cL }, - { 0x45edc5f8756d2411L,0xd4a790d9a755128cL,0xc2cf096349e5f6a0L, - 0xc66d267df649beaaL,0x3ce6d9688467039eL,0x50046c6b42f7816fL } }, + { { 0xf5bdccbabad0cb7fL,0x370f43ca958edd05L,0x3dd8232b04904a26L, + 0x3f8106682f4458e8L,0xdfcb67b99b3ace7eL,0x54e42f2d3e1241fcL }, + { 0xe30f3fb0db889300L,0x4ca0184b483e51fcL,0x5a32d097a638dac6L, + 0x567a2b5ec62a1db0L,0x2a756ba3c446456cL,0x6919026dd9f8d5c0L } }, /* 49 */ - { { 0x92ae160266425043L,0x1ff66afdf08db890L,0x386f5a7f8f162ce5L, - 0x18d2dea0fcf5598fL,0x78372b3a1a8ca18eL,0xdf0d20eb8cd0e6f7L }, - { 0x7edd5e1d75bb4045L,0x252a47ceb96d94b7L,0xbdb293582c626776L, - 0x853c394340dd1031L,0x9dc9becf7d5f47fdL,0x27c2302fbae4044aL } }, + { { 0x7f6493fc4fec874aL,0x8bb8a674d47a0770L,0x90bad2a652bd4f0cL, + 0x16badbe2f5733b07L,0x93be07cf93a1f802L,0x1e37a01541c395f7L }, + { 0xfe2c0fd6216582b3L,0xdcd98bc81627180dL,0x41e037268e8c9f1eL, + 0x93dbc22cfe8f45afL,0x5728c8a6ff45e059L,0x4f2f15cfca4a98cdL } }, /* 50 */ - { { 0x2d1d208a8f2d49ceL,0x0d91aa02162df0a2L,0x9c5cce8709a07f65L, - 0xdf07238b84339012L,0x5028e2c8419442cdL,0x2dcbd35872062abaL }, - { 0xb5fbc3cbe4680967L,0x2a7bc6459f92d72cL,0x806c76e1116c369dL, - 0x5c50677a3177e8d8L,0x753739eb4569df57L,0x2d481ef636c3f40bL } }, + { { 0xdbe2ec5d656e7d76L,0x84ad1b4bae2757bbL,0xc9297e7a0d4fec75L, + 0xfcc673eecad3ba87L,0xb0f77621dfd1671aL,0x5c386e449704a8c7L }, + { 0xce78f03f3e29256dL,0x0b185938c3a6ed2fL,0x7b1e2fae7824819bL, + 0x5a85d7f1f2d9313cL,0x238bd27973595b0fL,0x5fbf6b675c1cd2dcL } }, /* 51 */ - { { 0x1a2d39fdfea1103eL,0xeaae559295f81b17L,0xdbd0aa18f59b264aL, - 0x90c39c1acb592ee0L,0xdf62f80d9750cca3L,0xda4d8283df97cc6cL }, - { 0x0a6dd3461e201067L,0x1531f85969fb1f6bL,0x4895e5521d60121fL, - 0x0b21aab04c041c91L,0x9d896c46bcc1ccf8L,0xd24da3b33141bde7L } }, + { { 0x84d1ffb88a3e2412L,0xf01605926515f2feL,0x0e26ea9889905340L, + 0xbfd7a1b7203bd3d4L,0x5301273a88ea0bdaL,0x2f424475b28dd43eL }, + { 0x31014a2b33c28afaL,0xffbdea0c01e220eaL,0x681c64e8460b81d5L, + 0xdbe6f7286a91e1d5L,0x068bf36332619ad5L,0x4946291f27976c74L } }, /* 52 */ - { { 0x575a053753b0a354L,0x392ff2f40c6ddcd8L,0x0b8e8cff56157b94L, - 0x073e57bd3b1b80d1L,0x2a75e0f03fedee15L,0x752380e4aa8e6f19L }, - { 0x1f4e227c6558ffe9L,0x3a34861819ec5415L,0xab382d5ef7997085L, - 0x5e6deaffddc46ac2L,0xe5144078fc8d094cL,0xf674fe51f60e37c6L } }, + { { 0xa081a9462068e4b0L,0x1a8f5df609bfdad0L,0x5fbba5bcef28dd35L, + 0xa3e60d4f031ff71eL,0x2d47689b702ca18eL,0xd283f247c9b8e66bL }, + { 0x63e65dd7859ea140L,0x123da61f42aacdc3L,0xa8a9e893336f680cL, + 0x1cc4e12ac23d43acL,0x421e80d586a1fff8L,0x833d60d543deecc9L } }, /* 53 */ - { { 0x6fb87ae5af63408fL,0xa39c36a9cd75a737L,0x7833313fcf4c618dL, - 0xfbcd4482f034c88dL,0x4469a76139b35288L,0x77a711c566b5d9c9L }, - { 0x4a695dc7944f8d65L,0xe6da5f65161aaba8L,0x8654e9c324601669L, - 0xbc8b93f528ae7491L,0x5f1d1e838f5580d8L,0x8ccf9a1acea32cc8L } }, + { { 0x3c25b57c29014f8fL,0xa19fcb1e35d8e122L,0x916c0e3ceda32ac8L, + 0x9a23d289f36b6096L,0x5099038439a39871L,0xdc5b77b661c64196L }, + { 0x5a7d9917942bf2b6L,0xd21853934f41cf6dL,0x90ff1016fcc45c2fL, + 0x9891093deb8938aaL,0xe3c49b1baac4e6e9L,0x0f21a1d1d7a8e91eL } }, /* 54 */ - { { 0x28ab110c7196fee2L,0x75799d63874c8945L,0xa262934829aedaddL, - 0x9714cc7b2be88ff4L,0xf71293cfd58d60d6L,0xda6b6cb332a564e9L }, - { 0xf43fddb13dd821c2L,0xf2f2785f90dd323dL,0x91246419048489f8L, - 0x61660f26d24c6749L,0x961d9e8cc803c15cL,0x631c6158faadc4c9L } }, + { { 0x3a808e336f364b7eL,0x6a96d1b8bfa17359L,0x3387ec8552b36545L, + 0x2fde350af712180cL,0x9219d6f4703a2183L,0x8ba27e0086457946L }, + { 0x7446bca0ed80a9afL,0xbaf78b6f7203637aL,0x0304129d497c9d0fL, + 0x6df1e0356a883b68L,0x93ea2bb5e8018c47L,0xc86fd77cdb46443cL } }, /* 55 */ - { { 0xacf2ebe0fd752366L,0xb93c340e139be88bL,0x98f664850f20179eL, - 0x14820254ff1da785L,0x5278e2764f85c16eL,0xa246ee457aab1913L }, - { 0x43861eb453763b33L,0xc49f03fc45c0bc0dL,0xafff16bcad6b1ea1L, - 0xce33908b6fd49c99L,0x5c51e9bff7fde8c3L,0x076a7a39ff142c5eL } }, + { { 0x8de865d255dc2427L,0x74f7f83d6f72d126L,0xee1111786c7e665aL, + 0x272a8b3dddf44f12L,0xad3546449164eb4fL,0x2ffbdb586859d68fL }, + { 0xbefd36c509701865L,0x63c256162c983d01L,0x15a7ba0b2eb68703L, + 0x3318a82b5bb0fafcL,0x8e930fa9a0804f38L,0xb7459eb6be60ed1dL } }, /* 56 */ - { { 0x04639dfe9e338d10L,0x8ee6996ff42b411bL,0x960461d1a875cef2L, - 0x1057b6d695b4d0baL,0x27639252a906e0bcL,0x2c19f09ae1c20f8aL }, - { 0x5b8fc3f0eef4c43dL,0xe2e1b1a807a84aa9L,0x5f455528835d2bdbL, - 0x0f4aee4d207132ddL,0xe9f8338c3907f675L,0x7a874dc90e0531f0L } }, + { { 0xace01c514260b948L,0x04a6080f49210f78L,0x0d1eef6b2241b00dL, + 0x85a25069ef63912aL,0xcc96c4ec13dd8bc2L,0x90f14d1140d7e234L }, + { 0xae33f18ca69c8dc3L,0x76921f2a9adfa431L,0x18158ccf048c9f49L, + 0x90bcf7fbfb8fb345L,0x0d50b4dc38b3ff5dL,0x3914ea0b59ef84a8L } }, /* 57 */ - { { 0x84b22d4597c27050L,0xbd0b8df759e70bf8L,0xb4d6740579738b9bL, - 0x47f4d5f5cd917c4fL,0x9099c4ce13ce6e33L,0x942bfd39521d0f8bL }, - { 0x5028f0f6a43b566dL,0xaf6e866921bff7deL,0x83f6f856c44232cdL, - 0x65680579f915069aL,0xd12095a2ecfecb85L,0xcf7f06aedb01ba16L } }, + { { 0x4929d3f9d4e37cf3L,0x622183d1b24c24c0L,0x65cec0675f904d34L, + 0x65f9931a8a6f76faL,0xeed975b0e73282f2L,0xa045552a5e1625fdL }, + { 0xfd6b3e02f8fe8e42L,0x5f9f40256203907cL,0x8307eedb42b2c264L, + 0x2fb3ee719f757e92L,0x4502f2ecdc157ea8L,0xd976e7755d1cc0d5L } }, /* 58 */ - { { 0x0f56e3c48ef96c80L,0xd521f2b33ddb609cL,0x2be941027dc1450dL, - 0x2d21a07102a91fe2L,0x2e6f74fa1efa37deL,0x9a9a90b8156c28a1L }, - { 0xc54ea9ea9dc7dfcbL,0xc74e66fc2c2c1d62L,0x9f23f96749d3e067L, - 0x1c7c3a4654dd38adL,0xc70058845946cee3L,0x8985636845cc045dL } }, + { { 0xe46fb9a28fe1946eL,0xe91df3ed63bdde6eL,0x2e995306e9c28432L, + 0x7b3a6fe10988235bL,0xc55199f077f92a71L,0x47dd034853cb7950L }, + { 0xead52de2b727a6d1L,0xb87c9f75eea9c8daL,0xf3e2f3280d944f21L, + 0xce82734edd751eddL,0xfb83225ce616cedcL,0x15850e4b4a31eb49L } }, /* 59 */ - { { 0x29da7cd4fce73946L,0x8f697db523168563L,0x8e235e9ccba92ec6L, - 0x55d4655f9f91d3eaL,0xf3689f23aa50a6cdL,0xdcf21c2621e6a1a0L }, - { 0xcffbc82e61b818bfL,0xc74a2f96da47a243L,0x234e980a8bc1a0cfL, - 0xf35fd6b57929cb6dL,0x81468e12efe17d6cL,0xddea6ae558b2dafbL } }, + { { 0x92c4b6d50196ad3aL,0x0205ea484e1205e4L,0x8e08a97c0afc5affL, + 0xda8687c6727827ebL,0x2eace83106e398aaL,0x3a086c0f6d69e4e8L }, + { 0x5ff9b7aaf286e62aL,0xc428503962aae55eL,0x4ebd4258d9530a3fL, + 0x57ea313a8afc7fcbL,0x6d30a67522c18879L,0xd3c00cc994afb659L } }, /* 60 */ - { { 0x294de8877e787b2eL,0x258acc1f39a9310dL,0x92d9714aac14265dL, - 0x18b5591c708b48a0L,0x27cc6bb0e1abbf71L,0xc0581fa3568307b9L }, - { 0x9e0f58a3f24d4d58L,0xfebe9bb8e0ce2327L,0x91fd6a419d1be702L, - 0x9a7d8a45facac993L,0xabc0a08c9e50d66dL,0x02c342f706498201L } }, + { { 0x53ee47c5dee0d48bL,0xbd9e84ad9dfa2397L,0x2d581e12f81ba5e2L, + 0x26269f4f132cd325L,0x9e6224df58860a5fL,0x9306c607ff55522aL }, + { 0xb48af6d4146950e5L,0x09920ed00436805eL,0x3a1bc276cdce7eaeL, + 0x55ba728ac39a425eL,0x6a04d4e6d961d03eL,0x13891c66736e684aL } }, /* 61 */ - { { 0xccd71407157bdbc2L,0x72fa89c6ad0e1605L,0xb1d3da2bb92a015fL, - 0x8ad9e7cda0a3fe56L,0x160edcbd24f06737L,0x79d4db3361275be6L }, - { 0xd3d31fd95f3497c4L,0x8cafeaee04192fb0L,0xe13ca74513a50af3L, - 0x188261678c85aae5L,0xce06cea89eb556ffL,0x2eef1995bdb549f3L } }, + { { 0x7c75175a04cd04d6L,0xb76f9bd909c27a17L,0xa0cff6d408e5fe36L, + 0xc9097695dcd5ef90L,0x26bea24585e28054L,0x658e03c61580f068L }, + { 0x0da9f75e811eed27L,0x086e5e04aca0d2eeL,0xd4c157faa53a6787L, + 0x2e9266d2b40a595cL,0x8f1cb52698fa0820L,0x32a74240a1aef514L } }, /* 62 */ - { { 0x8ed7d3eb50596edcL,0xaa359362905243a2L,0xa212c2c2a4b6d02bL, - 0x611fd727c4fbec68L,0x8a0b8ff7b84f733dL,0xd85a6b905f0daf0eL }, - { 0x60e899f5d4091cf7L,0x4fef2b672eff2768L,0xc1f195cb10c33964L, - 0x8275d36993626a8fL,0xc77904f40d6c840aL,0x88d8b7fd7a868acdL } }, + { { 0xeb42e3d91ae86e7cL,0xd6956c8ce04a5026L,0x4c0b8b980f4302ebL, + 0xde43c938b37211fdL,0x9fa6a158e7090f80L,0x5f3c9afc73c47fb6L }, + { 0x2dc4f109f850a4d0L,0x56e63a4b6fd49d6aL,0x8e80a0694cbff048L, + 0x18d8b8cf2284afb0L,0x61dd086dc89363a1L,0x034c2202c37342a4L } }, /* 63 */ - { { 0x85f237237bd98425L,0xd4463992c70b154eL,0xcbb00ee296687a2eL, - 0x905fdbf7c83214fdL,0x2019d29313593684L,0x0428c393ef51218eL }, - { 0x40c7623f981e909aL,0x925133857be192daL,0x48fe480f4010907eL, - 0xdd7a187c3120b459L,0xc9d7702da1fd8f3cL,0x66e4753be358efc5L } }, - /* 64 */ - { { 0x070d34e116973cf4L,0x20aee08b7e4f34f7L,0x269af9b95eb8ad29L, - 0xdde0a036a6a45ddaL,0xa18b528e63df41e0L,0x03cc71b2a260df2aL }, - { 0x24a6770aa06b1dd7L,0x5bfa9c119d2675d3L,0x73c1e2a196844432L, - 0x3660558d131a6cf0L,0xb0289c832ee79454L,0xa6aefb01c6d8ddcdL } }, - /* 65 */ - { { 0xba1464b401ab5245L,0x9b8d0b6dc48d93ffL,0x939867dc93ad272cL, - 0xbebe085eae9fdc77L,0x73ae5103894ea8bdL,0x740fc89a39ac22e1L }, - { 0x5e28b0a328e23b23L,0x2352722ee13104d0L,0xf4667a18b0a2640dL, - 0xac74a72e49bb37c3L,0x79f734f0e81e183aL,0xbffe5b6c3fd9c0ebL } }, - /* 66 */ - { { 0xb1a358f5c6a2123fL,0x927b2d95fe28df6dL,0x89702753f199d2f9L, - 0x0a73754c1a3f82dcL,0x063d029d777affe1L,0x5439817edae6d34dL }, - { 0xf7979eef6b8b83c4L,0x615cb2149d945682L,0x8f0e4facc5e57eaeL, - 0x042b89b8113047ddL,0x888356dc93f36508L,0xbf008d185fd1f32fL } }, - /* 67 */ - { { 0x8012aa244e8068dbL,0xc72cc641a5729a47L,0x3c33df2c43f0691dL, - 0xfa0573471d92145fL,0xaefc0f2fb97f7946L,0x813d75cb2f8121bfL }, - { 0x05613c724383bba6L,0xa924ce70a4224b3fL,0xe59cecbe5f2179a6L, - 0x78e2e8aa79f62b61L,0x3ac2cc3b53ad8079L,0x55518d71d8f4fa96L } }, - /* 68 */ - { { 0x03cf292200623f3bL,0x095c71115f29ebffL,0x42d7224780aa6823L, - 0x044c7ba17458c0b0L,0xca62f7ef0959ec20L,0x40ae2ab7f8ca929fL }, - { 0xb8c5377aa927b102L,0x398a86a0dc031771L,0x04908f9dc216a406L, - 0xb423a73a918d3300L,0x634b0ff1e0b94739L,0xe29de7252d69f697L } }, - /* 69 */ - { { 0x744d14008435af04L,0x5f255b1dfec192daL,0x1f17dc12336dc542L, - 0x5c90c2a7636a68a8L,0x960c9eb77704ca1eL,0x9de8cf1e6fb3d65aL }, - { 0xc60fee0d511d3d06L,0x466e2313f9eb52c7L,0x743c0f5f206b0914L, - 0x42f55bac2191aa4dL,0xcefc7c8fffebdbc2L,0xd4fa6081e6e8ed1cL } }, - /* 70 */ - { { 0xb5e405d3b0ab9645L,0xaeec7f98d5f1f711L,0x8ad42311585c2a6eL, - 0x045acb9e512c6944L,0xae106c4ea90db1c6L,0xb89f33d5898e6563L }, - { 0x43b07cd97fed2ce4L,0xf9934e17dd815b20L,0x6778d4d50a81a349L, - 0x9e616ade52918061L,0xfa06db06d7e67112L,0x1da23cf188488091L } }, - /* 71 */ - { { 0x821c46b342f2c4b5L,0x931513ef66059e47L,0x7030ae4366f50cd1L, - 0x43b536c943e7b127L,0x006258cf5fca5360L,0xe4e3ee796b557abfL }, - { 0xbb6b390024c8b22fL,0x2eb5e2c1fcbf1054L,0x937b18c9567492afL, - 0xf09432e4acf53957L,0x585f5a9d1dbf3a56L,0xf86751fdbe0887cfL } }, - /* 72 */ - { { 0x157399cb9d10e0b2L,0x1c0d595660dc51b7L,0x1d496b8a1f583090L, - 0x6658bc2688590484L,0x88c08ab703213f28L,0x8d2e0f737ae58de4L }, - { 0x9b79bc95486cfee6L,0x036a26c7e9e5bc57L,0x1ad03601cd8ae97aL, - 0x06907f87ff3a0494L,0x078f4bbf2c7eb584L,0xe3731bf57e8d0a5aL } }, - /* 73 */ - { { 0x72f2282be1cd0abeL,0xd4f9015e87efefa2L,0x9d1898066c3834bdL, - 0x9c8cdcc1b8a29cedL,0x0601b9f4fee82ebcL,0x371052bc7206a756L }, - { 0x76fa109246f32562L,0xdaad534c17351bb4L,0xc3d64c37b3636bb5L, - 0x038a8c5145d54e00L,0x301e618032c09e7cL,0x9764eae795735151L } }, - /* 74 */ - { { 0x8791b19fcbd5256aL,0x4007e0f26ca13a3bL,0x03b794604cf06904L, - 0xb18a9c22b6c17589L,0xa1cb7d7d81d45908L,0x6e13fa9d21bb68f1L }, - { 0x47183c62a71e6e16L,0x5cf0ef8ee18749edL,0x2c9c7f9b2e5ed409L, - 0x042eeacce6e117e1L,0xb86d481613fb5a7fL,0xea1cf0edc9e5feb1L } }, - /* 75 */ - { { 0x6e6573c9cea4cc9bL,0x5417961dafcec8f3L,0x804bf02aa438b6f6L, - 0xb894b03cdcd4ea88L,0xd0f807e93799571fL,0x3466a7f5862156e8L }, - { 0x51e59acd56515664L,0x55b0f93ca3c5eb0bL,0x84a06b026a4279dbL, - 0x5c850579c5fae08eL,0xcf07b8dba663a1a2L,0x49a36bbcf46ffc8dL } }, - /* 76 */ - { { 0xe47f5acc46d93106L,0x65b7ade0aa897c9cL,0x37cf4c9412d7e4beL, - 0xa2ae9b80d4b2caa9L,0x5e7ce09ce60357a3L,0x29f77667c8ecd5f9L }, - { 0xdf6868f5a8a0b1c5L,0x240858cf62978ad8L,0x0f7ac101dc0002a1L, - 0x1d28a9d7ffe9aa05L,0x744984d65b962c97L,0xa8a7c00b3d28c8b2L } }, - /* 77 */ - { { 0x7c58a852ae11a338L,0xa78613f1d1af96e7L,0x7e9767d25355cc73L, - 0x6ba37009792a2de6L,0x7d60f618124386b2L,0xab09b53111157674L }, - { 0x95a0484198eb9dd0L,0xe6c17acc15070328L,0xafc6da45489c6e49L, - 0xab45a60abb211530L,0xc58d65927d7ea933L,0xa3ef3c65095642c6L } }, - /* 78 */ - { { 0x89d420e9df010879L,0x9d25255d39576179L,0x9cdefd50e39513b6L, - 0xe4efe45bd5d1c313L,0xc0149de73f7af771L,0x55a6b4f4340ab06bL }, - { 0xf1325251ebeaf771L,0x2ab44128878d4288L,0xfcd5832e18e05afeL, - 0xef52a348cc1fb62bL,0x2bd08274c1c4792aL,0x345c5846877c6dc7L } }, - /* 79 */ - { { 0xde15ceb0bea65e90L,0x0987f72b2416d99cL,0x44db578dfd863decL, - 0xf617b74bac6a3578L,0x9e62bd7adb48e999L,0x877cae61eab1a1beL }, - { 0x23adddaa3a358610L,0x2fc4d6d1325e2b07L,0x897198f51585754eL, - 0xf741852cb392b584L,0x9927804cb55f7de1L,0xe9e6c4ed1aa8efaeL } }, - /* 80 */ - { { 0x867db63998683186L,0xfb5cf424ddcc4ea9L,0xcc9a7ffed4f0e7bdL, - 0x7c57f71c7a779f7eL,0x90774079d6b25ef2L,0x90eae903b4081680L }, - { 0xdf2aae5e0ee1fcebL,0x3ff1da24e86c1a1fL,0x80f587d6ca193edfL, - 0xa5695523dc9b9d6aL,0x7b84090085920303L,0x1efa4dfcba6dbdefL } }, - /* 81 */ - { { 0xfbd838f9e0540015L,0x2c323946c39077dcL,0x8b1fb9e6ad619124L, - 0x9612440c0ca62ea8L,0x9ad9b52c2dbe00ffL,0xf52abaa1ae197643L }, - { 0xd0e898942cac32adL,0xdfb79e4262a98f91L,0x65452ecf276f55cbL, - 0xdb1ac0d27ad23e12L,0xf68c5f6ade4986f0L,0x389ac37b82ce327dL } }, - /* 82 */ - { { 0x511188b4f8e60f5bL,0x7fe6701548aa2adaL,0xdb333cb8381abca2L, - 0xb15e6d9ddaf3fc97L,0x4b24f6eb36aabc03L,0xc59789df72a748b4L }, - { 0x26fcb8a529cf5279L,0x7a3c6bfc01ad9a6cL,0x866cf88d4b8bac9bL, - 0xf4c899899c80d041L,0xf0a0424170add148L,0x5a02f47945d81a41L } }, - /* 83 */ - { { 0xfa5c877cc1c90202L,0xd099d440f8ac7570L,0x428a5b1bd17881f7L, - 0x61e267db5b2501d7L,0xf889bf04f2e4465bL,0x4da3ae0876aa4cb8L }, - { 0x3ef0fe26e3e66861L,0x5e7729533318b86dL,0xc3c35fbc747396dfL, - 0x5115a29c439ffd37L,0xbfc4bd97b2d70374L,0x088630ea56246b9dL } }, - /* 84 */ - { { 0xcd96866db8a9e8c9L,0xa11963b85bb8091eL,0xc7f90d53045b3cd2L, - 0x755a72b580f36504L,0x46f8b39921d3751cL,0x4bffdc9153c193deL }, - { 0xcd15c049b89554e7L,0x353c6754f7a26be6L,0x79602370bd41d970L, - 0xde16470b12b176c0L,0x56ba117540c8809dL,0xe2db35c3e435fb1eL } }, - /* 85 */ - { { 0xd71e4aab6328e33fL,0x5486782baf8136d1L,0x07a4995f86d57231L, - 0xf1f0a5bd1651a968L,0xa5dc5b2476803b6dL,0x5c587cbc42dda935L }, - { 0x2b6cdb32bae8b4c0L,0x66d1598bb1331138L,0x4a23b2d25d7e9614L, - 0x93e402a674a8c05dL,0x45ac94e6da7ce82eL,0xeb9f8281e463d465L } }, - /* 86 */ - { { 0x34e0f9d1fecf5b9bL,0xa115b12bf206966aL,0x5591cf3b1eaa0534L, - 0x5f0293cbfb1558f9L,0x1c8507a41bc703a5L,0x92e6b81c862c1f81L }, - { 0xcc9ebc66cdaf24e3L,0x68917ecd72fcfc70L,0x6dc9a9308157ba48L, - 0x5d425c08b06ab2b2L,0x362f8ce736e929c4L,0x09f6f57c62e89324L } }, - /* 87 */ - { { 0x1c7d6b78d29375fbL,0xfabd851ee35d1157L,0xf6f62dcd4243ea47L, - 0x1dd924608fe30b0fL,0x08166dfaffc6e709L,0xc6c4c6930881e6a7L }, - { 0x20368f87d6a53fb0L,0x38718e9f9eb4d1f9L,0x03f08acdafd7e790L, - 0x0835eb4472fe2a1cL,0x7e05090388076e5dL,0x538f765ea638e731L } }, - /* 88 */ - { { 0x0e0249d9c2663b4bL,0xe700ab5b47cd38ddL,0xb192559d2c46559fL, - 0x8f9f74a84bcde66dL,0xad1615233e2aced5L,0xc155c0473dd03a5bL }, - { 0x346a87993be454ebL,0x66ee94db83b7dccdL,0x1f6d8378ab9d2abeL, - 0x4a396dd27733f355L,0x419bd40af53553c2L,0xd0ead98d731dd943L } }, - /* 89 */ - { { 0x908e0b0eec142408L,0x98943cb94114b310L,0x03dbf7d81742b1d7L, - 0xd270df6b693412f4L,0xc50654948f69e20cL,0xa76a90c3697e43a1L }, - { 0xe0fa33844624825aL,0x82e48c0b8acc34c2L,0x7b24bd14e9a14f2bL, - 0x4f5dd5e24db30803L,0x0c77a9e7932da0a3L,0x20db90f274c653dcL } }, - /* 90 */ - { { 0x261179b70e6c5fd9L,0xf8bec1236c982eeaL,0x47683338d4957b7eL, - 0xcc47e6640a72f66aL,0xbd54bf6a1bad9350L,0xdfbf4c6af454e95aL }, - { 0x3f7a7afa6907f4faL,0x7311fae0865ca735L,0x24737ab82a496adaL, - 0x13e425f115feb79bL,0xe9e97c50a1b93c21L,0xb26b6eac4ddd3eb5L } }, - /* 91 */ - { { 0x81cab9f52a2e5f2bL,0xf93caf29bf385ac4L,0xf4bf35c3c909963aL, - 0x081e730074c9143cL,0x3ea57fa8c281b4c5L,0xe497905c9b340741L }, - { 0xf556dd8a55ab3cfbL,0xd444b96b518db6adL,0x34f5425a5ef4b955L, - 0xdda7a3acecd26aa3L,0xb57da11bda655e97L,0x02da3effc2024c70L } }, - /* 92 */ - { { 0xe24b00366481d0d9L,0x3740dbe5818fdfe2L,0xc1fc1f45190fda00L, - 0x329c92803cf27fdeL,0x7435cb536934f43eL,0x2b505a5d7884e8feL }, - { 0x6cfcc6a6711adcc9L,0xf034325c531e21e1L,0xa2f4a9679b2a8a99L, - 0x9d5f38423c21bdffL,0xb25c781131b57d66L,0xdb5344d80b8093b9L } }, - /* 93 */ - { { 0x0d72e667ae50a2f5L,0x9b7f8d8ae4a861d1L,0xa129f70f330df1cbL, - 0xe90aa5d7e04fefc3L,0xff561ecbe72c3ae1L,0x0d8fb428cdb955faL }, - { 0xd2235f73d7663784L,0xc05baec67e2c456aL,0xe5c292e42adbfcccL, - 0x4fd17988efb110d5L,0x27e57734d19d49f3L,0x188ac4ce84f679feL } }, - /* 94 */ - { { 0x7ee344cfa796c53eL,0xbbf6074d0868009bL,0x1f1594f7474a1295L, - 0x66776edcac11632dL,0x1862278b04e2fa5aL,0x52665cf2c854a89aL }, - { 0x7e3764648104ab58L,0x167759137204fd6dL,0x86ca06a544ea1199L, - 0xaa3f765b1c9240ddL,0x5f8501a924746149L,0x7b982e30dcd251d7L } }, - /* 95 */ - { { 0xe44e9efcc15f3060L,0x5ad62f2ea87ebbe6L,0x36499d41c79500d4L, - 0xa66d6dc0336fa9d1L,0xf8afc4955afd3b1fL,0x1d8ccb24e5c9822bL }, - { 0x4031422b79d7584bL,0xc54a0580ea3f20ddL,0x3f837c8f958468c5L, - 0x3d82f110fbea7735L,0x679a87787dffe2fcL,0x48eba63b20704803L } }, - /* 96 */ - { { 0x89b10d41df46e2f6L,0x13ab57f819514367L,0x067372b91d469c87L, - 0x0c195afa4f6c5798L,0xea43a12a272c9acfL,0x9dadd8cb678abdacL }, - { 0xcce56c6be182579aL,0x86febadb2d26c2d8L,0x1c668ee12a44745cL, - 0x580acd8698dc047aL,0x5a2b79cc51b9ec2dL,0x007da6084054f6a0L } }, - /* 97 */ - { { 0x9e3ca35217b00dd0L,0x046779cb0e81a7a6L,0xb999fef3d482d871L, - 0xe6f38134d9233fbcL,0x112c3001f48cd0e0L,0x934e75763c6c66aeL }, - { 0xb44d4fc3d73234dcL,0xfcae2062864eafc1L,0x843afe2526bef21aL, - 0x61355107f3b75fdfL,0x8367a5aa794c2e6bL,0x3d2629b18548a372L } }, - /* 98 */ - { { 0x6230618f437cfaf8L,0x5b8742cb2032c299L,0x949f72472293643aL, - 0xb8040f1a09464f79L,0x049462d24f254143L,0xabd6b522366c7e76L }, - { 0x119b392bd5338f55L,0x1a80a9ce01495a0cL,0xf3118ca7f8d7537eL, - 0xb715adc26bf4b762L,0x24506165a8482b6cL,0xd958d7c696a7c84dL } }, - /* 99 */ - { { 0x9ad8aa87bdc21f31L,0xadb3cab48063e58cL,0xefd86283b07dd7b8L, - 0xc7b9b7621be7c6b4L,0x2ef58741015582deL,0xc970c52e299addf3L }, - { 0x78f02e2a22f24d66L,0xefec1d1074cc100aL,0xaf2a6a3909316e1aL, - 0xce7c22055849dd49L,0x9c1fe75c96bffc4cL,0xcad98fd27ba06ec0L } }, - /* 100 */ - { { 0xed76e2d0b648b73eL,0xa9f92ce51cfd285eL,0xa8c86c062ed13de1L, - 0x1d3a574ea5191a93L,0x385cdf8b1ad1b8bfL,0xbbecc28a47d2cfe3L }, - { 0x98d326c069cec548L,0x4f5bc1ddf240a0b2L,0x241a706229057236L, - 0x0fc6e9c5c68294a4L,0x4d04838ba319f17aL,0x8b612cf19ffc1c6fL } }, - /* 101 */ - { { 0x9bb0b5014c3830ebL,0x3d08f83c8ee0d0c5L,0xa4a6264279ba9389L, - 0x5d5d40449cbc2914L,0xae9eb83e074c46f0L,0x63bb758f74ead7d6L }, - { 0x1c40d2eac6bb29e0L,0x95aa2d874b02f41eL,0x9298917553cb199aL, - 0xdd91bafe51584f6dL,0x3715efb931a1aaecL,0xc1b6ae5b46780f9eL } }, - /* 102 */ - { { 0xcded3e4b42772f41L,0x3a700d5d3bcb79d1L,0x4430d50e80feee60L, - 0x444ef1fcf5e5d4bbL,0xc660194fe6e358ffL,0xe68a2f326a91b43cL }, - { 0x5842775c977fe4d2L,0x78fdef5c7e2a41ebL,0x5f3bec02ff8df00eL, - 0xf4b840cd5852525dL,0x0870483a4e6988bdL,0x39499e39cc64b837L } }, - /* 103 */ - { { 0xfc05de80b08df5feL,0x0c12957c63ba0362L,0xea379414d5cf1428L, - 0xc559132a54ef6216L,0x33d5f12fb9e65cf8L,0x09c602781695d663L }, - { 0x3ac1ced461f7a2fbL,0xdd838444d4f5eeb8L,0x82a38c6c8318fcadL, - 0x315be2e5e9f1a864L,0x317b5771442daf47L,0x81b5904a95aa5f9eL } }, - /* 104 */ - { { 0x6b6b1c508b21d232L,0x87f3dbc08c2cba75L,0xa7e74b46ae9f0fafL, - 0x036a0985bb7b8079L,0x4f185b908d974a25L,0x5aa7cef0d9af5ec9L }, - { 0xe0566a7057dcfffcL,0x6ea311dab8453225L,0x72ea1a8d23368aa9L, - 0xed9b208348cd552dL,0xb987967cc80ea435L,0xad735c756c104173L } }, - /* 105 */ - { { 0xaea85ab3cee76ef4L,0x44997444af1d2b93L,0x0851929beacb923fL, - 0xb080b59051e3bc0cL,0xc4ee1d8659be68a2L,0xf00de21964b26cdaL }, - { 0x8d7fb5c0f2e90d4dL,0x00e219a777d9ec64L,0xc4e6febd5d1c491cL, - 0x080e37541a8f4585L,0x4a9b86c848d2af9cL,0x2ed70db6b6679851L } }, - /* 106 */ - { { 0xaee44116586f25cbL,0xf7b6861fa0fcf70fL,0x55d2cd2018a350e8L, - 0x861bf3e592dc286fL,0x9ab18ffa6226aba7L,0xd15827bea9857b03L }, - { 0x26c1f54792e6acefL,0x422c63c8ac1fbac3L,0xa2d8760dfcbfd71dL, - 0x35f6a539b2511224L,0xbaa88fa1048d1a21L,0x49f1abe9ebf999dbL } }, - /* 107 */ - { { 0x16f9f4f4f7492b73L,0xcf28ec1ecb392b1aL,0x45b130d469ca6ffcL, - 0x28ba8d40b72efa58L,0xace987c75ca066f5L,0x3e3992464ad022ebL }, - { 0x63a2d84e752555bbL,0xaaa93b4a9c2ae394L,0xcd80424ec89539caL, - 0x6d6b5a6daa119a99L,0xbd50334c379f2629L,0x899e925eef3cc7d3L } }, - /* 108 */ - { { 0xb7ff3651bf825dc4L,0x0f741cc440b9c462L,0x771ff5a95cc4fb5bL, - 0xcb9e9c9b47fd56feL,0xbdf053db5626c0d3L,0xa97ce675f7e14098L }, - { 0x68afe5a36c934f5eL,0x6cd5e148ccefc46fL,0xc7758570d7a88586L, - 0x49978f5edd558d40L,0xa1d5088a64ae00c1L,0x58f2a720f1d65bb2L } }, - /* 109 */ - { { 0x66fdda4a3e4daedbL,0x38318c1265d1b052L,0x28d910a24c4bbf5cL, - 0x762fe5c478a9cd14L,0x08e5ebaad2cc0aeeL,0xd2cdf257ca0c654cL }, - { 0x48f7c58b08b717d2L,0x3807184a386cd07aL,0x3240f626ae7d0112L, - 0x03e9361bc43917b0L,0xf261a87620aea018L,0x53f556a47e1e6372L } }, - /* 110 */ - { { 0xc84cee562f512a90L,0x24b3c0041b0ea9f1L,0x0ee15d2de26cc1eaL, - 0xd848762cf0c9ef7dL,0x1026e9c5d5341435L,0x8f5b73dcfdb16b31L }, - { 0x1f69bef2d2c75d95L,0x8d33d581be064ddaL,0x8c024c1257ed35e6L, - 0xf8d435f9c309c281L,0xfd295061d6960193L,0x66618d78e9e49541L } }, - /* 111 */ - { { 0x571cfd458ce382deL,0x175806eede900ddeL,0x6184996534aba3b5L, - 0xe899778ade7aec95L,0xe8f00f6eff4aa97fL,0xae971cb5010b0c6dL }, - { 0x1827eebc3af788f1L,0xd46229ffe413fe2dL,0x8a15455b4741c9b4L, - 0x5f02e690f8e424ebL,0x40a1202edae87712L,0x49b3bda264944f6dL } }, - /* 112 */ - { { 0xd63c6067035b2d69L,0xb507150d6bed91b0L,0x1f35f82f7afb39b2L, - 0xb9bd9c0116012b66L,0x00d97960ed0a5f50L,0xed7054512716f7c9L }, - { 0x1576eff4127abdb4L,0x6850d698f01e701cL,0x9fa7d7493fc87e2fL, - 0x0b6bcc6fb0ce3e48L,0xf4fbe1f5f7d8c1c0L,0xcf75230e02719cc6L } }, - /* 113 */ - { { 0x6761d6c2722d94edL,0xd1ec3f213718820eL,0x65a40b7025d0e7c6L, - 0xd67f830ebaf3cf31L,0x633b3807b93ea430L,0x17faa0ea0bc96c69L }, - { 0xe6bf3482df866b98L,0x205c1ee9a9db52d4L,0x51ef9bbdff9ab869L, - 0x3863dad175eeb985L,0xef216c3bd3cf442aL,0x3fb228e3f9c8e321L } }, - /* 114 */ - { { 0x94f9b70c0760ac07L,0xf3c9ccae9d79bf4dL,0x73cea084c5ffc83dL, - 0xef50f943dc49c38eL,0xf467a2aebc9e7330L,0x5ee534b644ea7fbaL }, - { 0x20cb627203609e7fL,0x0984435562fdc9f0L,0xaf5c8e580f1457f7L, - 0xd1f50a6cb4b25941L,0x77cb247c2ec82395L,0xa5f3e1e5da3dca33L } }, - /* 115 */ - { { 0x023489d67d85fa94L,0x0ba405372db9ce47L,0x0fdf7a1faed7aad1L, - 0xa57b0d739a4ccb40L,0x48fcec995b18967cL,0xf30b5b6eb7274d24L }, - { 0x7ccb4773c81c5338L,0xb85639e6a3ed6bd0L,0x7d9df95f1d56eadaL, - 0xe256d57f0a1607adL,0x6da7ffdc957574d6L,0x65f8404601c7a8c4L } }, - /* 116 */ - { { 0x8d45d0cbcba1e7f1L,0xef0a08c002b55f64L,0x771ca31b17e19892L, - 0xe1843ecb4885907eL,0x67797ebc364ce16aL,0x816d2b2d8df4b338L }, - { 0xe870b0e539aa8671L,0x9f0db3e4c102b5f5L,0x342966591720c697L, - 0x0ad4c89e613c0d2aL,0x1af900b2418ddd61L,0xe087ca72d336e20eL } }, - /* 117 */ - { { 0x222831ffaba10079L,0x0dc5f87b6d64fff2L,0x445479073e8cb330L, - 0xe815aaa2702a33fbL,0x338d6b2e5fba3215L,0x0f7535cb79f549c8L }, - { 0x471ecd972ee95923L,0x1e868b37c6d1c09fL,0x2bc7b8ecc666ef4eL, - 0xf5416589808a4bfcL,0xf23e9ee23fbc4d2eL,0x4357236c2d75125bL } }, - /* 118 */ - { { 0xfe176d95ba9cdb1bL,0x45a1ca012f82791eL,0x97654af24de4cca2L, - 0xbdbf9d0e5cc4bcb9L,0xf6a7df50ad97ac0aL,0xc52112b061359fd6L }, - { 0x696d9ce34f05eae3L,0x903adc02e943ac2bL,0xa90753470848be17L, - 0x1e20f1702a3973e5L,0xe1aacc1c6feb67e9L,0x2ca0ac32e16bc6b9L } }, - /* 119 */ - { { 0xffea12e4ef871eb5L,0x94c2f25da8bf0a7aL,0x4d1e4c2a78134eaaL, - 0x11ed16fb0360fb10L,0x4029b6db85fc11beL,0x5e9f7ab7f4d390faL }, - { 0x5076d72f30646612L,0xa0afed1ddda1d0d8L,0x2902225785a1d103L, - 0xcb499e174e276bcdL,0x16d1da7151246c3dL,0xc72d56d3589a0443L } }, - /* 120 */ - { { 0xdf5ffc74dae5bb45L,0x99068c4a261bd6dcL,0xdc0afa7aaa98ec7bL, - 0xedd2ee00f121e96dL,0x163cc7be1414045cL,0xb0b1bbce335af50eL }, - { 0xd440d78501a06293L,0xcdebab7c6552e644L,0x48cb8dbc8c757e46L, - 0x81f9cf783cabe3cbL,0xddd02611b123f59aL,0x3dc7b88eeeb3784dL } }, - /* 121 */ - { { 0xe1b8d398c4741456L,0xa9dfa9026032a121L,0x1cbfc86d1263245bL, - 0xf411c7625244718cL,0x96521d5405b0fc54L,0x1afab46edbaa4985L }, - { 0xa75902ba8674b4adL,0x486b43ad5ad87d12L,0x72b1c73636e0d099L, - 0x39890e07bb6cd6d6L,0x8128999c59bace4eL,0xd8da430b7b535e33L } }, - /* 122 */ - { { 0x39f65642c6b75791L,0x050947a621806bfbL,0x0ca3e3701362ef84L, - 0x9bc60aed8c3d2391L,0x9b488671732e1ddcL,0x12d10d9ea98ee077L }, - { 0xb6f2822d3651b7dcL,0x6345a5ba80abd138L,0x62033262472d3c84L, - 0xd54a1d40acc57527L,0x6ea46b3a424447cbL,0x5bc410572fb1a496L } }, - /* 123 */ - { { 0xe70c57a3a751cd0eL,0x190d8419eba3c7d6L,0xb1c3bee79d47d55aL, - 0xda941266f912c6d8L,0x12e9aacc407a6ad6L,0xd6ce5f116e838911L }, - { 0x063ca97b70e1f2ceL,0xa3e47c728213d434L,0xa016e24184df810aL, - 0x688ad7b0dfd881a4L,0xa37d99fca89bf0adL,0xd8e3f339a23c2d23L } }, - /* 124 */ - { { 0xbdf53163750bed6fL,0x808abc3283e68b0aL,0x85a366275bb08a33L, - 0xf72a3a0f6b0e4abeL,0xf7716d19faf0c6adL,0x22dcc0205379b25fL }, - { 0x7400bf8df9a56e11L,0x6cb8bad756a47f21L,0x7c97176f7a6eb644L, - 0xe8fd84f7d1f5b646L,0x98320a9444ddb054L,0x07071ba31dde86f5L } }, - /* 125 */ - { { 0x6fdfa0e598f8fcb9L,0x89cec8e094d0d70cL,0xa0899397106d20a8L, - 0x915bfb9aba8acc9cL,0x1370c94b5507e01cL,0x83246a608a821ffbL }, - { 0xa8273a9fbe3c378fL,0x7e54478935a25be9L,0x6cfa49724dd929d7L, - 0x987fed9d365bd878L,0x4982ac945c29a7aeL,0x4589a5d75ddd7ec5L } }, - /* 126 */ - { { 0x9fabb174a95540a9L,0x7cfb886f0162c5b0L,0x17be766bea3dee18L, - 0xff7da41fe88e624cL,0xad0b71eb8b919c38L,0x86a522e0f31ff9a9L }, - { 0xbc8e6f72868bc259L,0x6130c6383ccef9e4L,0x09f1f4549a466555L, - 0x8e6c0f0919b2bfb4L,0x945c46c90ca7bb22L,0xacd871684dafb67bL } }, - /* 127 */ - { { 0x090c72ca10c53841L,0xc20ae01b55a4fcedL,0x03f7ebd5e10234adL, - 0xb3f42a6a85892064L,0xbdbc30c0b4a14722L,0x971bc4378ca124ccL }, - { 0x6f79f46d517ff2ffL,0x6a9c96e2ecba947bL,0x5e79f2f462925122L, - 0x30a96bb16a4e91f1L,0x1147c9232d4c72daL,0x65bc311f5811e4dfL } }, - /* 128 */ - { { 0x87c7dd7d139b3239L,0x8b57824e4d833baeL,0xbcbc48789fff0015L, - 0x8ffcef8b909eaf1aL,0x9905f4eef1443a78L,0x020dd4a2e15cbfedL }, - { 0xca2969eca306d695L,0xdf940cadb93caf60L,0x67f7fab787ea6e39L, - 0x0d0ee10ff98c4fe5L,0xc646879ac19cb91eL,0x4b4ea50c7d1d7ab4L } }, - /* 129 */ - { { 0x19e409457a0db57eL,0xe6017cad9a8c9702L,0xdbf739e51be5cff9L, - 0x3646b3cda7a938a2L,0x0451108568350dfcL,0xad3bd6f356e098b5L }, - { 0x935ebabfee2e3e3eL,0xfbd01702473926cbL,0x7c735b029e9fb5aaL, - 0xc52a1b852e3feff0L,0x9199abd3046b405aL,0xe306fcec39039971L } }, - /* 130 */ - { { 0xd6d9aec823e4712cL,0x7ca8376cc3c198eeL,0xe6d8318731bebd8aL, - 0xed57aff3d88bfef3L,0x72a645eecf44edc7L,0xd4e63d0b5cbb1517L }, - { 0x98ce7a1cceee0ecfL,0x8f0126335383ee8eL,0x3b879078a6b455e8L, - 0xcbcd3d96c7658c06L,0x721d6fe70783336aL,0xf21a72635a677136L } }, - /* 131 */ - { { 0x19d8b3cd9586ba11L,0xd9e0aeb28a5c0480L,0xe4261dbf2230ef5cL, - 0x095a9dee02e6bf09L,0x8963723c80dc7784L,0x5c97dbaf145157b1L }, - { 0x97e744344bc4503eL,0x0fb1cb3185a6b370L,0x3e8df2becd205d4bL, - 0x497dd1bcf8f765daL,0x92ef95c76c988a1aL,0x3f924baa64dc4cfaL } }, - /* 132 */ - { { 0x6bf1b8dd7268b448L,0xd4c28ba1efd79b94L,0x2fa1f8c8e4e3551fL, - 0x769e3ad45c9187a9L,0x28843b4d40326c0dL,0xfefc809450d5d669L }, - { 0x30c85bfd90339366L,0x4eeb56f15ccf6c3aL,0x0e72b14928ccd1dcL, - 0x73ee85b5f2ce978eL,0xcdeb2bf33165bb23L,0x8106c9234e410abfL } }, - /* 133 */ - { { 0xc8df01617d02f4eeL,0x8a78154718e21225L,0x4ea895eb6acf9e40L, - 0x8b000cb56e5a633dL,0xf31d86d57e981ffbL,0xf5c8029c4475bc32L }, - { 0x764561ce1b568973L,0x2f809b81a62996ecL,0x9e513d64da085408L, - 0xc27d815de61ce309L,0x0da6ff99272999e0L,0xbd284779fead73f7L } }, - /* 134 */ - { { 0x6033c2f99b1cdf2bL,0x2a99cf06bc5fa151L,0x7d27d25912177b3bL, - 0xb1f15273c4485483L,0x5fd57d81102e2297L,0x3d43e017c7f6acb7L }, - { 0x41a8bb0b3a70eb28L,0x67de2d8e3e80b06bL,0x09245a4170c28de5L, - 0xad7dbcb1a7b26023L,0x70b08a352cbc6c1eL,0xb504fb669b33041fL } }, - /* 135 */ - { { 0xa8e85ab5f97a27c2L,0x6ac5ec8bc10a011bL,0x55745533ffbcf161L, - 0x01780e8565790a60L,0xe451bf8599ee75b0L,0x8907a63b39c29881L }, - { 0x76d46738260189edL,0x284a443647bd35cbL,0xd74e8c4020cab61eL, - 0x6264bf8c416cf20aL,0xfa5a6c955fd820ceL,0xfa7154d0f24bb5fcL } }, - /* 136 */ - { { 0x18482cec9b3f5034L,0x962d445acd9e68fdL,0x266fb1d695746f23L, - 0xc66ade5a58c94a4bL,0xdbbda826ed68a5b6L,0x05664a4d7ab0d6aeL }, - { 0xbcd4fe51025e32fcL,0x61a5aebfa96df252L,0xd88a07e231592a31L, - 0x5d9d94de98905517L,0x96bb40105fd440e7L,0x1b0c47a2e807db4cL } }, - /* 137 */ - { { 0x5c2a6ac808223878L,0xba08c269e65a5558L,0xd22b1b9b9bbc27fdL, - 0x919171bf72b9607dL,0x9ab455f9e588dc58L,0x6d54916e23662d93L }, - { 0x8da8e9383b1de0c1L,0xa84d186a804f278fL,0xbf4988ccd3461695L, - 0xf5eae3bee10eb0cbL,0x1ff8b68fbf2a66edL,0xa68daf67c305b570L } }, - /* 138 */ - { { 0xc1004cff44b2e045L,0x91b5e1364b1c05d4L,0x53ae409088a48a07L, - 0x73fb2995ea11bb1aL,0x320485703d93a4eaL,0xcce45de83bfc8a5fL }, - { 0xaff4a97ec2b3106eL,0x9069c630b6848b4fL,0xeda837a6ed76241cL, - 0x8a0daf136cc3f6cfL,0x199d049d3da018a8L,0xf867c6b1d9093ba3L } }, - /* 139 */ - { { 0xe4d42a5656527296L,0xae26c73dce71178dL,0x70a0adac6c251664L, - 0x813483ae5dc0ae1dL,0x7574eacddaab2dafL,0xc56b52dcc2d55f4fL }, - { 0x872bc16795f32923L,0x4be175815bdd2a89L,0x9b57f1e7a7699f00L, - 0x5fcd9c723ac2de02L,0x83af3ba192377739L,0xa64d4e2bfc50b97fL } }, - /* 140 */ - { { 0x2172dae20e552b40L,0x62f49725d34d52e8L,0x7930ee4007958f98L, - 0x56da2a90751fdd74L,0xf1192834f53e48c3L,0x34d2ac268e53c343L }, - { 0x1073c21813111286L,0x201dac14da9d9827L,0xec2c29dbee95d378L, - 0x9316f1191f3ee0b1L,0x7890c9f0544ce71cL,0xd77138af27612127L } }, - /* 141 */ - { { 0x78045e6d3b4ad1cdL,0xcd86b94e4aa49bc1L,0x57e51f1dfd677a16L, - 0xd9290935fa613697L,0x7a3f959334f4d893L,0x8c9c248b5d5fcf9bL }, - { 0x9f23a4826f70d4e9L,0x1727345463190ae9L,0x4bdd7c135b081a48L, - 0x1e2de38928d65271L,0x0bbaaa25e5841d1fL,0xc4c18a79746772e5L } }, - /* 142 */ - { { 0x10ee2681593375acL,0x4f3288be7dd5e113L,0x9a97b2fb240f3538L, - 0xfa11089f1de6b1e2L,0x516da5621351bc58L,0x573b61192dfa85b5L }, - { 0x89e966836cba7df5L,0xf299be158c28ab40L,0xe91c9348ad43fcbfL, - 0xe9bbc7cc9a1cefb3L,0xc8add876738b2775L,0x6e3b1f2e775eaa01L } }, - /* 143 */ - { { 0x0365a888b677788bL,0x634ae8c43fd6173cL,0x304987619e498dbeL, - 0x08c43e6dc8f779abL,0x068ae3844c09aca9L,0x2380c70b2018d170L }, - { 0xcf77fbc3a297c5ecL,0xdacbc853ca457948L,0x3690de04336bec7eL, - 0x26bbac6414eec461L,0xd1c23c7e1f713abfL,0xf08bbfcde6fd569eL } }, - /* 144 */ - { { 0x5f8163f484770ee3L,0x0e0c7f94744a1706L,0x9c8f05f7e1b2d46dL, - 0x417eafe7d01fd99aL,0x2ba15df511440e5bL,0xdc5c552a91a6fbcfL }, - { 0x86271d74a270f721L,0x32c0a075a004485bL,0x9d1a87e38defa075L, - 0xb590a7acbf0d20feL,0x430c41c28feda1f5L,0x454d287958f6ec24L } }, - /* 145 */ - { { 0x52b7a6357c525435L,0x3d9ef57f37c4bdbcL,0x2bb93e9edffcc475L, - 0xf7b8ba987710f3beL,0x42ee86da21b727deL,0x55ac3f192e490d01L }, - { 0x487e3a6ec0c1c390L,0x036fb345446cde7bL,0x089eb276496ae951L, - 0xedfed4d971ed1234L,0x661b0dd5900f0b46L,0x11bd6f1b8582f0d3L } }, - /* 146 */ - { { 0x5cf9350f076bc9d1L,0x15d903becf3cd2c3L,0x21cfc8c225af031cL, - 0xe0ad32488b1cc657L,0xdd9fb96370014e87L,0xf0f3a5a1297f1658L }, - { 0xbb908fbaf1f703aaL,0x2f9cc4202f6760baL,0x00ceec6666a38b51L, - 0x4deda33005d645daL,0xb9cf5c72f7de3394L,0xaeef65021ad4c906L } }, - /* 147 */ - { { 0x0583c8b17a19045dL,0xae7c3102d052824cL,0x2a234979ff6cfa58L, - 0xfe9dffc962c733c0L,0x3a7fa2509c0c4b09L,0x516437bb4fe21805L }, - { 0x9454e3d5c2a23ddbL,0x0726d887289c104eL,0x8977d9184fd15243L, - 0xc559e73f6d7790baL,0x8fd3e87d465af85fL,0xa2615c745feee46bL } }, - /* 148 */ - { { 0xc8d607a84335167dL,0x8b42d804e0f5c887L,0x5f9f13df398d11f9L, - 0x5aaa508720740c67L,0x83da9a6aa3d9234bL,0xbd3a5c4e2a54bad1L }, - { 0xdd13914c2db0f658L,0x29dcb66e5a3f373aL,0xbfd62df55245a72bL, - 0x19d1802391e40847L,0xd9df74dbb136b1aeL,0x72a06b6b3f93bc5bL } }, - /* 149 */ - { { 0x6da19ec3ad19d96fL,0xb342daa4fb2a4099L,0x0e61633a662271eaL, - 0x3bcece81ce8c054bL,0x7cc8e0618bd62dc6L,0xae189e19ee578d8bL }, - { 0x73e7a25ddced1eedL,0xc1257f0a7875d3abL,0x2cb2d5a21cfef026L, - 0xd98ef39bb1fdf61cL,0xcd8e6f6924e83e6cL,0xd71e7076c7b7088bL } }, - /* 150 */ - { { 0x339368309d4245bfL,0x22d962172ac2953bL,0xb3bf5a8256c3c3cdL, - 0x50c9be910d0699e8L,0xec0944638f366459L,0x6c056dba513b7c35L }, - { 0x687a6a83045ab0e3L,0x8d40b57f445c9295L,0x0f345048a16f5954L, - 0x64b5c6393d8f0a87L,0x106353a29f71c5e2L,0xdd58b475874f0dd4L } }, - /* 151 */ - { { 0x67ec084f62230c72L,0xf14f6cca481385e3L,0xf58bb4074cda7774L, - 0xe15011b1aa2dbb6bL,0xd488369d0c035ab1L,0xef83c24a8245f2fdL }, - { 0xfb57328f9fdc2538L,0x79808293191fe46aL,0xe28f5c4432ede548L, - 0x1b3cda99ea1a022cL,0x39e639b73df2ec7fL,0x77b6272b760e9a18L } }, - /* 152 */ - { { 0x2b1d51bda65d56d5L,0x3a9b71f97ea696e0L,0x95250ecc9904f4c4L, - 0x8bc4d6ebe75774b7L,0x0e343f8aeaeeb9aaL,0xc473c1d1930e04cbL }, - { 0x282321b1064cd8aeL,0xf4b4371e5562221cL,0xc1cc81ecd1bf1221L, - 0xa52a07a9e2c8082fL,0x350d8e59ba64a958L,0x29e4f3de6fb32c9aL } }, - /* 153 */ - { { 0x0aa9d56cba89aaa5L,0xf0208ac0c4c6059eL,0x7400d9c6bd6ddca4L, - 0xb384e475f2c2f74aL,0x4c1061fcb1562dd3L,0x3924e2482e153b8dL }, - { 0xf38b8d98849808abL,0x29bf3260a491aa36L,0x85159ada88220edeL, - 0x8b47915bbe5bc422L,0xa934d72ed7300967L,0xc4f303982e515d0dL } }, - /* 154 */ - { { 0xe3e9ee421b1de38bL,0xa124e25a42636760L,0x90bf73c090165b1aL, - 0x21802a34146434c5L,0x54aa83f22e1fa109L,0x1d4bd03ced9c51e9L }, - { 0xc2d96a38798751e6L,0xed27235f8c3507f5L,0xb5fb80e2c8c24f88L, - 0xf873eefad37f4f78L,0x7229fd74f224ba96L,0x9dcd91999edd7149L } }, - /* 155 */ - { { 0xee9f81a64e94f22aL,0xe5609892f71ec341L,0x6c818ddda998284eL, - 0x9fd472953b54b098L,0x47a6ac030e8a7cc9L,0xde684e5eb207a382L }, - { 0x4bdd1ecd2b6b956bL,0x09084414f01b3583L,0xe2f80b3255233b14L, - 0x5a0fec54ef5ebc5eL,0x74cf25e6bf8b29a2L,0x1c757fa07f29e014L } }, - /* 156 */ - { { 0x1bcb5c4aeb0fdfe4L,0xd7c649b3f0899367L,0xaef68e3f05bc083bL, - 0x57a06e46a78aa607L,0xa2136ecc21223a44L,0x89bd648452f5a50bL }, - { 0x724411b94455f15aL,0x23dfa97008a9c0fdL,0x7b0da4d16db63befL, - 0x6f8a7ec1fb162443L,0xc1ac9ceee98284fbL,0x085a582b33566022L } }, - /* 157 */ - { { 0x15cb61f9ec1f138aL,0x11c9a230668f0c28L,0xac829729df93f38fL, - 0xcef256984048848dL,0x3f686da02bba8fbfL,0xed5fea78111c619aL }, - { 0x9b4f73bcd6d1c833L,0x5095160686e7bf80L,0xa2a73508042b1d51L, - 0x9ef6ea495fb89ec2L,0xf1008ce95ef8b892L,0x78a7e6849ae8568bL } }, - /* 158 */ - { { 0x3fe83a7c10470cd8L,0x92734682f86df000L,0xb5dac06bda9409b5L, - 0x1e7a966094939c5fL,0xdec6c1505cc116dcL,0x1a52b40866bac8ccL }, - { 0x5303a3656e864045L,0x45eae72a9139efc1L,0x83bec6466f31d54fL, - 0x2fb4a86f6e958a6dL,0x6760718e4ff44030L,0x008117e3e91ae0dfL } }, - /* 159 */ - { { 0x5d5833ba384310a2L,0xbdfb4edc1fd6c9fcL,0xb9a4f102849c4fb8L, - 0xe5fb239a581c1e1fL,0xba44b2e7d0a9746dL,0x78f7b7683bd942b9L }, - { 0x076c8ca1c87607aeL,0x82b23c2ed5caaa7eL,0x6a581f392763e461L, - 0xca8a5e4a3886df11L,0xc87e90cf264e7f22L,0x04f74870215cfcfcL } }, - /* 160 */ - { { 0x5285d116141d161cL,0x67cd2e0e93c4ed17L,0x12c62a647c36187eL, - 0xf5329539ed2584caL,0xc4c777c442fbbd69L,0x107de7761bdfc50aL }, - { 0x9976dcc5e96beebdL,0xbe2aff95a865a151L,0x0e0a9da19d8872afL, - 0x5e357a3da63c17ccL,0xd31fdfd8e15cc67cL,0xc44bbefd7970c6d8L } }, - /* 161 */ - { { 0x703f83e24c0c62f1L,0x9b1e28ee4e195572L,0x6a82858bfe26ccedL, - 0xd381c84bc43638faL,0x94f72867a5ba43d8L,0x3b4a783d10b82743L }, - { 0xee1ad7b57576451eL,0xc3d0b59714b6b5c8L,0x3dc30954fcacc1b8L, - 0x55df110e472c9d7bL,0x97c86ed702f8a328L,0xd043341388dc098fL } }, - /* 162 */ - { { 0x1a60d1522ca8f2feL,0x61640948491bd41fL,0x6dae29a558dfe035L, - 0x9a615bea278e4863L,0xbbdb44779ad7c8e5L,0x1c7066302ceac2fcL }, - { 0x5e2b54c699699b4bL,0xb509ca6d239e17e8L,0x728165feea063a82L, - 0x6b5e609db6a22e02L,0x12813905b26ee1dfL,0x07b9f722439491faL } }, - /* 163 */ - { { 0x1592ec1448ff4e49L,0x3e4e9f176d644129L,0x7acf82881156acc0L, - 0x5aa34ba8bb092b0bL,0xcd0f90227d38393dL,0x416724ddea4f8187L }, - { 0x3c4e641cc0139e73L,0xe0fe46cf91e4d87dL,0xedb3c792cab61f8aL, - 0x4cb46de4d3868753L,0xe449c21d20f1098aL,0x5e5fd059f5b8ea6eL } }, - /* 164 */ - { { 0x7fcadd4675856031L,0x89c7a4cdeaf2fbd0L,0x1af523ce7a87c480L, - 0xe5fc109561d9ae90L,0x3fb5864fbcdb95f5L,0xbeb5188ebb5b2c7dL }, - { 0x3d1563c33ae65825L,0x116854c40e57d641L,0x11f73d341942ebd3L, - 0x24dc5904c06955b3L,0x8a0d4c83995a0a62L,0xfb26b86d5d577b7dL } }, - /* 165 */ - { { 0xc53108e7c686ae17L,0x9090d739d1c1da56L,0x4583b0139aec50aeL, - 0xdd9a088ba49a6ab2L,0x28192eeaf382f850L,0xcc8df756f5fe910eL }, - { 0x877823a39cab7630L,0x64984a9afb8e7fc1L,0x5448ef9c364bfc16L, - 0xbbb4f871c44e2a9aL,0x901a41ab435c95e9L,0xc6c23e5faaa50a06L } }, - /* 166 */ - { { 0xb78016c19034d8ddL,0x856bb44b0b13e79bL,0x85c6409ab3241a05L, - 0x8d2fe19a2d78ed21L,0xdcc7c26d726eddf2L,0x3ccaff5f25104f04L }, - { 0x397d7edc6b21f843L,0xda88e4dde975de4cL,0x5273d3964f5ab69eL, - 0x537680e39aae6cc0L,0xf749cce53e6f9461L,0x021ddbd9957bffd3L } }, - /* 167 */ - { { 0x7b64585f777233cfL,0xfe6771f60942a6f0L,0x636aba7adfe6eef0L, - 0x63bbeb5686038029L,0xacee5842de8fcf36L,0x48d9aa99d4a20524L }, - { 0xcff7a74c0da5e57aL,0xc232593ce549d6c9L,0x68504bccf0f2287bL, - 0x6d7d098dbc8360b5L,0xeac5f1495b402f41L,0x61936f11b87d1bf1L } }, - /* 168 */ - { { 0xaa9da167b8153a9dL,0xa49fe3ac9e83ecf0L,0x14c18f8e1b661384L, - 0x61c24dab38434de1L,0x3d973c3a283dae96L,0xc99baa0182754fc9L }, - { 0x477d198f4c26b1e3L,0x12e8e186a7516202L,0x386e52f6362addfaL, - 0x31e8f695c3962853L,0xdec2af136aaedb60L,0xfcfdb4c629cf74acL } }, - /* 169 */ - { { 0x6b3ee958cca40298L,0xc3878153f2f5d195L,0x0c565630ed2eae5bL, - 0xd089b37e3a697cf2L,0xc2ed2ac7ad5029eaL,0x7e5cdfad0f0dda6aL }, - { 0xf98426dfd9b86202L,0xed1960b14335e054L,0x1fdb02463f14639eL, - 0x17f709c30db6c670L,0xbfc687ae773421e1L,0x13fefc4a26c1a8acL } }, - /* 170 */ - { { 0xe361a1987ffa0a5fL,0xf4b26102c63fe109L,0x264acbc56c74e111L, - 0x4af445fa77abebafL,0x448c4fdd24cddb75L,0x0b13157d44506eeaL }, - { 0x22a6b15972e9993dL,0x2c3c57e485e5ecbeL,0xa673560bfd83e1a1L, - 0x6be23f82c3b8c83bL,0x40b13a9640bbe38eL,0x66eea033ad17399bL } }, - /* 171 */ - { { 0x49fc6e95b4c6c693L,0xefc735de36af7d38L,0xe053343d35fe42fcL, - 0xf0aa427c6a9ab7c3L,0xc79f04364a0fcb24L,0x1628724393ebbc50L }, - { 0x5c3d6bd016927e1eL,0x40158ed2673b984cL,0xa7f86fc84cd48b9aL, - 0x1643eda660ea282dL,0x45b393eae2a1beedL,0x664c839e19571a94L } }, - /* 172 */ - { { 0x5774575027eeaf94L,0x2875c925ea99e1e7L,0xc127e7ba5086adeaL, - 0x765252a086fe424fL,0x1143cc6c2b6c0281L,0xc9bb2989d671312dL }, - { 0x880c337c51acb0a5L,0xa3710915d3c60f78L,0x496113c09262b6edL, - 0x5d25d9f89ce48182L,0x53b6ad72b3813586L,0x0ea3bebc4c0e159cL } }, - /* 173 */ - { { 0xcaba450ac5e49beaL,0x684e54157c05da59L,0xa2e9cab9de7ac36cL, - 0x4ca79b5f2e6f957bL,0xef7b024709b817b1L,0xeb3049907d89df0fL }, - { 0x508f730746fe5096L,0x695810e82e04eaafL,0x88ef1bd93512f76cL, - 0x776613513ebca06bL,0xf7d4863accf158b7L,0xb2a81e4494ee57daL } }, - /* 174 */ - { { 0xff288e5b6d53e6baL,0xa90de1a914484ea2L,0x2fadb60ced33c8ecL, - 0x579d6ef328b66a40L,0x4f2dd6ddec24372dL,0xe9e33fc91d66ec7dL }, - { 0x110899d2039eab6eL,0xa31a667a3e97bb5eL,0x6200166dcfdce68eL, - 0xbe83ebae5137d54bL,0x085f7d874800acdfL,0xcf4ab1330c6f8c86L } }, - /* 175 */ - { { 0x03f65845931e08fbL,0x6438551e1506e2c0L,0x5791f0dc9c36961fL, - 0x68107b29e3dcc916L,0x83242374f495d2caL,0xd8cfb6636ee5895bL }, - { 0x525e0f16a0349b1bL,0x33cd2c6c4a0fab86L,0x46c12ee82af8dda9L, - 0x7cc424ba71e97ad3L,0x69766ddf37621eb0L,0x95565f56a5f0d390L } }, - /* 176 */ - { { 0xe0e7bbf21a0f5e94L,0xf771e1151d82d327L,0x10033e3dceb111faL, - 0xd269744dd3426638L,0xbdf2d9da00d01ef6L,0x1cb80c71a049ceafL }, - { 0x17f183289e21c677L,0x6452af0519c8f98bL,0x35b9c5f780b67997L, - 0x5c2e1cbe40f8f3d4L,0x43f9165666d667caL,0x9faaa059cf9d6e79L } }, - /* 177 */ - { { 0x8ad246180a078fe6L,0xf6cc73e6464fd1ddL,0x4d2ce34dc3e37448L, - 0x624950c5e3271b5fL,0x62910f5eefc5af72L,0x8b585bf8aa132bc6L }, - { 0x11723985a839327fL,0x34e2d27d4aac252fL,0x402f59ef6296cc4eL, - 0x00ae055c47053de9L,0xfc22a97228b4f09bL,0xa9e86264fa0c180eL } }, - /* 178 */ - { { 0x0b7b6224bc310eccL,0x8a1a74f167fa14edL,0x87dd09607214395cL, - 0xdf1b3d09f5c91128L,0x39ff23c686b264a8L,0xdc2d49d03e58d4c5L }, - { 0x2152b7d3a9d6f501L,0xf4c32e24c04094f7L,0xc6366596d938990fL, - 0x084d078f94fb207fL,0xfd99f1d7328594cbL,0x36defa64cb2d96b3L } }, - /* 179 */ - { { 0x4619b78113ed7cbeL,0x95e500159784bd0eL,0x2a32251c2c7705feL, - 0xa376af995f0dd083L,0x55425c6c0361a45bL,0x812d2cef1f291e7bL }, - { 0xccf581a05fd94972L,0x26e20e39e56dc383L,0x0093685d63dbfbf0L, - 0x1fc164cc36b8c575L,0xb9c5ab81390ef5e7L,0x40086beb26908c66L } }, - /* 180 */ - { { 0xe5e54f7937e3c115L,0x69b8ee8cc1445a8aL,0x79aedff2b7659709L, - 0xe288e1631b46fbe6L,0xdb4844f0d18d7bb7L,0xe0ea23d048aa6424L }, - { 0x714c0e4ef3d80a73L,0x87a0aa9e3bd64f98L,0x8844b8a82ec63080L, - 0xe0ac9c30255d81a3L,0x86151237455397fcL,0x0b9794642f820155L } }, - /* 181 */ - { { 0x127a255a4ae03080L,0x232306b4580a89fbL,0x04e8cd6a6416f539L, - 0xaeb70dee13b02a0eL,0xa3038cf84c09684aL,0xa710ec3c28e433eeL }, - { 0x77a72567681b1f7dL,0x86fbce952fc28170L,0xd3408683f5735ac8L, - 0x3a324e2a6bd68e93L,0x7ec74353c027d155L,0xab60354cd4427177L } }, - /* 182 */ - { { 0x32a5342aef4c209dL,0x2ba7527408d62704L,0x4bb4af6fc825d5feL, - 0x1c3919ced28e7ff1L,0x1dfc2fdcde0340f6L,0xc6580baf29f33ba9L }, - { 0xae121e7541d442cbL,0x4c7727fd3a4724e4L,0xe556d6a4524f3474L, - 0x87e13cc7785642a2L,0x182efbb1a17845fdL,0xdcec0cf14e144857L } }, - /* 183 */ - { { 0x1cb89541e9539819L,0xc8cb3b4f9d94dbf1L,0x1d353f63417da578L, - 0xb7a697fb8053a09eL,0x8d841731c35d8b78L,0x85748d6fb656a7a9L }, - { 0x1fd03947c1859c5dL,0x6ce965c1535d22a2L,0x1966a13e0ca3aadcL, - 0x9802e41d4fb14effL,0xa9048cbb76dd3fcdL,0x89b182b5e9455bbaL } }, - /* 184 */ - { { 0xd777ad6a43360710L,0x841287ef55e9936bL,0xbaf5c67004a21b24L, - 0xf2c0725f35ad86f1L,0x338fa650c707e72eL,0x2bf8ed2ed8883e52L }, - { 0xb0212cf4b56e0d6aL,0x50537e126843290cL,0xd8b184a198b3dc6fL, - 0xd2be9a350210b722L,0x407406db559781eeL,0x5a78d5910bc18534L } }, - /* 185 */ - { { 0x4d57aa2ad748b02cL,0xbe5b3451a12b3b95L,0xadca7a4564711258L, - 0x597e091a322153dbL,0xf327100632eb1eabL,0xbd9adcba2873f301L }, - { 0xd1dc79d138543f7fL,0x00022092921b1fefL,0x86db3ef51e5df8edL, - 0x888cae049e6b944aL,0x71bd29ec791a32b4L,0xd3516206a6d1c13eL } }, - /* 186 */ - { { 0x2ef6b95255924f43L,0xd2f401ae4f9de8d5L,0xfc73e8d7adc68042L, - 0x627ea70c0d9d1bb4L,0xc3bb3e3ebbf35679L,0x7e8a254ad882dee4L }, - { 0x08906f50b5924407L,0xf14a0e61a1ad444aL,0xaa0efa2165f3738eL, - 0xd60c7dd6ae71f161L,0x9e8390faf175894dL,0xd115cd20149f4c00L } }, - /* 187 */ - { { 0x2f2e2c1da52abf77L,0xc2a0dca554232568L,0xed423ea254966dccL, - 0xe48c93c7cd0dd039L,0x1e54a225176405c7L,0x1efb5b1670d58f2eL }, - { 0xa751f9d994fb1471L,0xfdb31e1f67d2941dL,0xa6c74eb253733698L, - 0xd3155d1189a0f64aL,0x4414cfe4a4b8d2b6L,0x8d5a4be8f7a8e9e3L } }, - /* 188 */ - { { 0x5c96b4d452669e98L,0x4547f9228fd42a03L,0xcf5c1319d285174eL, - 0x805cd1ae064bffa0L,0x50e8bc4f246d27e7L,0xf89ef98fd5781e11L }, - { 0xb4ff95f6dee0b63fL,0xad850047222663a4L,0x026918604d23ce9cL, - 0x3e5309ce50019f59L,0x27e6f72269a508aeL,0xe9376652267ba52cL } }, - /* 189 */ - { { 0xa04d289cc0368708L,0xc458872f5e306e1dL,0x76fa23de33112feaL, - 0x718e39746efde42eL,0xf0c98cdc1d206091L,0x5fa3ca6214a71987L }, - { 0xeee8188bdcaa9f2aL,0x312cc732589a860dL,0xf9808dd6c63aeb1fL, - 0x70fd43db4ea62b53L,0x2c2bfe34890b6e97L,0x105f863cfa426aa6L } }, - /* 190 */ - { { 0x0b29795db38059adL,0x5686b77e90647ea0L,0xeff0470edb473a3eL, - 0x278d2340f9b6d1e2L,0xebbff95bbd594ec7L,0xf4b72334d3a7f23dL }, - { 0x2a285980a5a83f0bL,0x0786c41a9716a8b3L,0x138901bd22511812L, - 0xd1b55221e2fede6eL,0x0806e264df4eb590L,0x6c4c897e762e462eL } }, - /* 191 */ - { { 0xd10b905fb4b41d9dL,0x826ca4664523a65bL,0x535bbd13b699fa37L, - 0x5b9933d773bc8f90L,0x9332d61fcd2118adL,0x158c693ed4a65fd0L }, - { 0x4ddfb2a8e6806e63L,0xe31ed3ecb5de651bL,0xf9460e51819bc69aL, - 0x6229c0d62c76b1f8L,0xbb78f231901970a3L,0x31f3820f9cee72b8L } }, - /* 192 */ - { { 0xe931caf2c09e1c72L,0x0715f29812990cf4L,0x33aad81d943262d8L, - 0x5d292b7a73048d3fL,0xb152aaa4dc7415f6L,0xc3d10fd90fd19587L }, - { 0xf76b35c575ddadd0L,0x9f5f4a511e7b694cL,0x2f1ab7ebc0663025L, - 0x01c9cc87920260b0L,0xc4b1f61a05d39da6L,0x6dcd76c4eb4a9c4eL } }, - /* 193 */ - { { 0x0ba0916ffdc83f01L,0x354c8b449553e4f9L,0xa6cc511affc5e622L, - 0xb954726ae95be787L,0xcb04811575b41a62L,0xfa2ae6cdebfde989L }, - { 0x6376bbc70f24659aL,0x13a999fd4c289c43L,0xc7134184ec9abd8bL, - 0x28c02bf6a789ab04L,0xff841ebcd3e526ecL,0x442b191e640893a8L } }, - /* 194 */ - { { 0x4cac6c62fa2b6e20L,0x97f29e9bf6d69861L,0x228ab1dbbc96d12dL, - 0x6eb913275e8e108dL,0xd4b3d4d140771245L,0x61b20623ca8a803aL }, - { 0x2c2f3b41a6a560b1L,0x879e1d403859fcf4L,0x7cdb5145024dbfc3L, - 0x55d08f153bfa5315L,0x2f57d773aa93823aL,0xa97f259cc6a2c9a2L } }, - /* 195 */ - { { 0xc306317be58edbbbL,0x25ade51c79dfdf13L,0x6b5beaf116d83dd6L, - 0xe8038a441dd8f925L,0x7f00143cb2a87b6bL,0xa885d00df5b438deL }, - { 0xe9f76790cf9e48bdL,0xf0bdf9f0a5162768L,0x0436709fad7b57cbL, - 0x7e151c12f7c15db7L,0x3514f0225d90ee3bL,0x2e84e8032c361a8dL } }, - /* 196 */ - { { 0x2277607d563ec8d8L,0xa661811fe3934cb7L,0x3ca72e7af58fd5deL, - 0x7989da0462294c6aL,0x88b3708bf6bbefe9L,0x0d524cf753ed7c82L }, - { 0x69f699ca2f30c073L,0xf0fa264b9dc1dcf3L,0x44ca456805f0aaf6L, - 0x0f5b23c7d19b9bafL,0x39193f41eabd1107L,0x9e3e10ad2a7c9b83L } }, - /* 197 */ - { { 0xa90824f0d4ae972fL,0x43eef02bc6e846e7L,0x7e46061229d2160aL, - 0x29a178acfe604e91L,0x23056f044eb184b2L,0x4fcad55feb54cdf4L }, - { 0xa0ff96f3ae728d15L,0x8a2680c6c6a00331L,0x5f84cae07ee52556L, - 0x5e462c3ac5a65dadL,0x5d2b81dfe2d23f4fL,0x6e47301bc5b1eb07L } }, - /* 198 */ - { { 0x77411d68af8219b9L,0xcb883ce651b1907aL,0x25c87e57101383b5L, - 0x9c7d9859982f970dL,0xaa6abca5118305d2L,0x725fed2f9013a5dbL }, - { 0x487cdbafababd109L,0xc0f8cf5687586528L,0xa02591e68ad58254L, - 0xc071b1d1debbd526L,0x927dfe8b961e7e31L,0x55f895f99263dfe1L } }, - /* 199 */ - { { 0xf899b00db175645bL,0x51f3a627b65b4b92L,0xa2f3ac8db67399efL, - 0xe717867fe400bc20L,0x42cc90201967b952L,0x3d5967513ecd1de1L }, - { 0xd41ebcdedb979775L,0x99ba61bc6a2e7e88L,0x039149a5321504f2L, - 0xe7dc231427ba2fadL,0x9f556308b57d8368L,0x2b6d16c957da80a7L } }, - /* 200 */ - { { 0x84af5e76279ad982L,0x9bb4c92d9c8b81a6L,0xd79ad44e0e698e67L, - 0xe8be9048265fc167L,0xf135f7e60c3a4cccL,0xa0a10d38b8863a33L }, - { 0xe197247cd386efd9L,0x0eefd3f9b52346c2L,0xc22415f978607bc8L, - 0xa2a8f862508674ceL,0xa72ad09ec8c9d607L,0xcd9f0ede50fa764fL } }, - /* 201 */ - { { 0x063391c7d1a46d4dL,0x2df51c119eb01693L,0xc5849800849e83deL, - 0x48fd09aa8ad08382L,0xa405d873aa742736L,0xee49e61ee1f9600cL }, - { 0xd76676be48c76f73L,0xd9c100f601274b2aL,0x110bb67c83f8718dL, - 0xec85a42002fc0d73L,0xc0449e1e744656adL,0x28ce737637d9939bL } }, - /* 202 */ - { { 0x97e9af7244544ac7L,0xf2c658d5ba010426L,0x732dec39fb3adfbdL, - 0xd12faf91a2df0b07L,0x8ac267252171e208L,0xf820cdc85b24fa54L }, - { 0x307a6eea94f4cf77L,0x18c783d2944a33c6L,0x4b939d4c0b741ac5L, - 0x1d7acd153ffbb6e4L,0x06a248587a255e44L,0x14fbc494ce336d50L } }, - /* 203 */ - { { 0x9b920c0c51584e3cL,0xc7733c59f7e54027L,0xe24ce13988422bbeL, - 0x11ada812523bd6abL,0xde068800b88e6defL,0x7b872671fe8c582dL }, - { 0x4e746f287de53510L,0x492f8b99f7971968L,0x1ec80bc77d928ac2L, - 0xb3913e48432eb1b5L,0xad08486632028f6eL,0x122bb8358fc2f38bL } }, - /* 204 */ - { { 0x0a9f3b1e3b0b29c3L,0x837b64324fa44151L,0xb9905c9217b28ea7L, - 0xf39bc93798451750L,0xcd383c24ce8b6da1L,0x299f57db010620b2L }, - { 0x7b6ac39658afdce3L,0xa15206b33d05ef47L,0xa0ae37e2b9bb02ffL, - 0x107760ab9db3964cL,0xe29de9a067954beaL,0x446a1ad8431c3f82L } }, - /* 205 */ - { { 0xc6fecea05c6b8195L,0xd744a7c5f49e71b9L,0xa8e96acc177a7ae7L, - 0x1a05746c358773a7L,0xa416214637567369L,0xaa0217f787d1c971L }, - { 0x61e9d15877fd3226L,0x0f6f2304e4f600beL,0xa9c4cebc7a6dff07L, - 0xd15afa0109f12a24L,0x2bbadb228c863ee9L,0xa28290e4e5eb8c78L } }, - /* 206 */ - { { 0x55b87fa03e9de330L,0x12b26066195c145bL,0xe08536e0a920bef0L, - 0x7bff6f2c4d195adcL,0x7f319e9d945f4187L,0xf9848863f892ce47L }, - { 0xd0efc1d34fe37657L,0x3c58de825cf0e45aL,0x626ad21a8b0ccbbeL, - 0xd2a31208af952fc5L,0x81791995eb437357L,0x5f19d30f98e95d4fL } }, - /* 207 */ - { { 0x72e83d9a0e6865bbL,0x22f5af3bf63456a6L,0x409e9c73463c8d9eL, - 0x40e9e578dfe6970eL,0x876b6efa711b91caL,0x895512cf942625a3L }, - { 0x84c8eda8cb4e462bL,0x84c0154a4412e7c8L,0x04325db1ceb7b71fL, - 0x1537dde366f70877L,0xf3a093991992b9acL,0xa7316606d498ae77L } }, - /* 208 */ - { { 0x13990d2fcad260f5L,0x76c3be29eec0e8c0L,0x7dc5bee00f7bd7d5L, - 0x9be167d2efebda4bL,0xcce3dde69122b87eL,0x75a28b0982b5415cL }, - { 0xf6810bcde84607a6L,0xc6d581286f4dbf0dL,0xfead577d1b4dafebL, - 0x9bc440b2066b28ebL,0x53f1da978b17e84bL,0x0459504bcda9a575L } }, - /* 209 */ - { { 0x13e39a02329e5836L,0x2c9e7d51f717269dL,0xc5ac58d6f26c963bL, - 0x3b0c6c4379967bf5L,0x60bbea3f55908d9dL,0xd84811e7f07c9ad1L }, - { 0xfe7609a75bd20e4aL,0xe4325dd20a70baa8L,0x3711f370b3600386L, - 0x97f9562fd0924302L,0x040dc0c34acc4436L,0xfd6d725cde79cdd4L } }, - /* 210 */ - { { 0xb3efd0e3cf13eafbL,0x21009cbb5aa0ae5fL,0xe480c55379022279L, - 0x755cf334b2fc9a6dL,0x8564a5bf07096ae7L,0xddd649d0bd238139L }, - { 0xd0de10b18a045041L,0x6e05b413c957d572L,0x5c5ff8064e0fb25cL, - 0xd933179b641162fbL,0x42d48485e57439f9L,0x70c5bd0a8a8d72aaL } }, - /* 211 */ - { { 0xa767173897bdf646L,0xaa1485b4ab329f7cL,0xce3e11d6f8f25fdfL, - 0x76a3fc7ec6221824L,0x045f281ff3924740L,0x24557d4e96d13a9aL }, - { 0x875c804bdd4c27cdL,0x11c5f0f40f5c7feaL,0xac8c880bdc55ff7eL, - 0x2acddec51103f101L,0x38341a21f99faa89L,0xc7b67a2cce9d6b57L } }, - /* 212 */ - { { 0x9a0d724f8e357586L,0x1d7f4ff5df648da0L,0x9c3e6c9bfdee62a5L, - 0x0499cef00389b372L,0xe904050d98eab879L,0xe8eef1b66c051617L }, - { 0xebf5bfebc37e3ca9L,0x7c5e946da4e0b91dL,0x790973142c4bea28L, - 0x81f6c109ee67b2b7L,0xaf237d9bdafc5edeL,0xd2e602012abb04c7L } }, - /* 213 */ - { { 0x6156060c8a4f57bfL,0xf9758696ff11182aL,0x8336773c6296ef00L, - 0x9c054bceff666899L,0xd6a11611719cd11cL,0x9824a641dbe1acfaL }, - { 0x0b7b7a5fba89fd01L,0xf8d3b809889f79d8L,0xc5e1ea08f578285cL, - 0x7ac74536ae6d8288L,0x5d37a2007521ef5fL,0x5ecc4184b260a25dL } }, - /* 214 */ - { { 0xddcebb19a708c8d3L,0xe63ed04fc63f81ecL,0xd045f5a011873f95L, - 0x3b5ad54479f276d5L,0x81272a3d425ae5b3L,0x8bfeb50110ce1605L }, - { 0x4233809c888228bfL,0x4bd82acfb2aff7dfL,0x9c68f1800cbd4a7fL, - 0xfcd771246b44323dL,0x60c0fcf6891db957L,0xcfbb4d8904da8f7fL } }, - /* 215 */ - { { 0x9a6a5df93b26139aL,0x3e076a83b2cc7eb8L,0x47a8e82d5a964bcdL, - 0x8a4e2a39b9278d6bL,0x93506c98e4443549L,0x06497a8ff1e0d566L }, - { 0x3dee8d992b1efa05L,0x2da63ca845393e33L,0xa4af7277cf0579adL, - 0xaf4b46393236d8eaL,0x6ccad95b32b617f5L,0xce76d8b8b88bb124L } }, - /* 216 */ - { { 0x63d2537a083843dcL,0x89eb35141e4153b4L,0x5175ebc4ea9afc94L, - 0x7a6525808ed1aed7L,0x67295611d85e8297L,0x8dd2d68bb584b73dL }, - { 0x237139e60133c3a4L,0x9de838ab4bd278eaL,0xe829b072c062fcd9L, - 0x70730d4f63ba8706L,0x6080483fd3cd05ecL,0x872ab5b80c85f84dL } }, - /* 217 */ - { { 0xfc0776d3999d4d49L,0xa3eb59deec3f45e7L,0xbc990e440dae1fc1L, - 0x33596b1ea15371ffL,0xd447dcb29bc7ab25L,0xcd5b63e935979582L }, - { 0xae3366fa77d1ff11L,0x59f28f05edee6903L,0x6f43fed1a4433bf2L, - 0x15409c9bdf9ce00eL,0x21b5cdedaca9c5dcL,0xf9f3359582d7bdb4L } }, - /* 218 */ - { { 0x959443789422c792L,0x239ea923c958b8bfL,0x4b61a247df076541L, - 0x4d29ce85bb9fc544L,0x9a692a670b424559L,0x6e0ca5a00e486900L }, - { 0x6b79a78285b3beceL,0x41f35e39c61f9892L,0xff82099aae747f82L, - 0x58c8ae3fd0ca59d6L,0x4ac930e299406b5fL,0x2ce04eb99df24243L } }, - /* 219 */ - { { 0x4366b9941ac37b82L,0xff0c728d25b04d83L,0x1f55136119c47b7cL, - 0xdbf2d5edbeff13e7L,0xf78efd51e12a683dL,0x82cd85b9989cf9c4L }, - { 0xe23c6db6e0cb5d37L,0x818aeebd72ee1a15L,0x8212aafd28771b14L, - 0x7bc221d91def817dL,0xdac403a29445c51fL,0x711b051712c3746bL } }, - /* 220 */ - { { 0x0ed9ed485ea99eccL,0xf799500db8cab5e1L,0xa8ec87dcb570cbdcL, - 0x52cfb2c2d35dfaecL,0x8d31fae26e4d80a4L,0xe6a37dc9dcdeabe5L }, - { 0x5d365a341deca452L,0x09a5f8a50d68b44eL,0x59238ea5a60744b1L, - 0xf2fedc0dbb4249e9L,0xe395c74ea909b2e3L,0xe156d1a539388250L } }, - /* 221 */ - { { 0xd796b3d047181ae9L,0xbaf44ba844197808L,0xe693309434cf3facL, - 0x41aa6adec3bd5c46L,0x4fda75d8eed947c6L,0xacd9d4129ea5a525L }, - { 0x65cc55a3d430301bL,0x3c9a5bcf7b52ea49L,0x22d319cf159507f0L, - 0x2ee0b9b5de74a8ddL,0x20c26a1e877ac2b6L,0x387d73da92e7c314L } }, - /* 222 */ - { { 0x13c4833e8cd3fdacL,0x76fcd473332e5b8eL,0xff671b4be2fe1fd3L, - 0x4d734e8b5d98d8ecL,0xb1ead3c6514bbc11L,0xd14ca8587b390494L }, - { 0x95a443af5d2d37e9L,0x73c6ea7300464622L,0xa44aeb4b15755044L, - 0xba3f8575fab58feeL,0x9779dbc9dc680a6fL,0xe1ee5f5a7b37ddfcL } }, - /* 223 */ - { { 0xcd0b464812d29f46L,0x93295b0b0ed53137L,0xbfe2609480bef6c9L, - 0xa656578854248b00L,0x69c43fca80e7f9c4L,0x2190837bbe141ea1L }, - { 0x875e159aa1b26cfbL,0x90ca9f877affe852L,0x15e6550d92ca598eL, - 0xe3e0945d1938ad11L,0xef7636bb366ef937L,0xb6034d0bb39869e5L } }, - /* 224 */ - { { 0x4d255e3026d8356eL,0xf83666edd314626fL,0x421ddf61d0c8ed64L, - 0x96e473c526677b61L,0xdad4af7e9e9b18b3L,0xfceffd4aa9393f75L }, - { 0x843138a111c731d5L,0x05bcb3a1b2f141d9L,0x20e1fa95617b7671L, - 0xbefce81288ccec7bL,0x582073dc90f1b568L,0xf572261a1f055cb7L } }, - /* 225 */ - { { 0xf314827736973088L,0xc008e70886a9f980L,0x1b795947e046c261L, - 0xdf1e6a7dca76bca0L,0xabafd88671acddf0L,0xff7054d91364d8f4L }, - { 0x2cf63547e2260594L,0x468a5372d73b277eL,0xc7419e24ef9bd35eL, - 0x2b4a1c2024043cc3L,0xa28f047a890b39cdL,0xdca2cea146f9a2e3L } }, - /* 226 */ - { { 0xab78873653277538L,0xa734e225cf697738L,0x66ee1d1e6b22e2c1L, - 0x2c615389ebe1d212L,0xf36cad4002bb0766L,0x120885c33e64f207L }, - { 0x59e77d5690fbfec2L,0xf9e781aad7a574aeL,0x801410b05d045e53L, - 0xd3b5f0aaa91b5f0eL,0xb3d1df007fbb3521L,0x11c4b33ec72bee9aL } }, - /* 227 */ - { { 0xd32b983283c3a7f3L,0x8083abcf88d8a354L,0xdeb1640450f4ec5aL, - 0x18d747f0641e2907L,0x4e8978aef1bbf03eL,0x932447dc88a0cd89L }, - { 0x561e0febcf3d5897L,0xfc3a682f13600e6dL,0xc78b9d73d16a6b73L, - 0xe713feded29bf580L,0x0a22522308d69e5cL,0x3a924a571ff7fda4L } }, - /* 228 */ - { { 0xfb64554cb4093beeL,0xa6d65a25a58c6ec0L,0x4126994d43d0ed37L, - 0xa5689a5155152d44L,0xb8e5ea8c284caa8dL,0x33f05d4fd1f25538L }, - { 0xe0fdfe091b615d6eL,0x2ded7e8f705507daL,0xdd5631e517bbcc80L, - 0x4f87453e267fd11fL,0xc6da723fff89d62dL,0x55cbcae2e3cda21dL } }, - /* 229 */ - { { 0x336bc94e6b4e84f3L,0x728630314ef72c35L,0x6d85fdeeeeb57f99L, - 0x7f4e3272a42ece1bL,0x7f86cbb536f0320aL,0xf09b6a2b923331e6L }, - { 0x21d3ecf156778435L,0x2977ba998323b2d2L,0x6a1b57fb1704bc0fL, - 0xd777cf8b389f048aL,0x9ce2174fac6b42cdL,0x404e2bff09e6c55aL } }, - /* 230 */ - { { 0x9b9b135e204c5ddbL,0x9dbfe0443eff550eL,0x35eab4bfec3be0f6L, - 0x8b4c3f0d0a43e56fL,0x4c1c66730e73f9b3L,0x92ed38bd2c78c905L }, - { 0xc7003f6aa386e27cL,0xb9c4f46faced8507L,0xea024ec859df5464L, - 0x4af96152429572eaL,0x279cd5e2e1fc1194L,0xaa376a03281e358cL } }, - /* 231 */ - { { 0x078592233cdbc95cL,0xaae1aa6aef2e337aL,0xc040108d472a8544L, - 0x80c853e68d037b7dL,0xd221315c8c7eee24L,0x195d38568ee47752L }, - { 0xd4b1ba03dacd7fbeL,0x4b5ac61ed3e0c52bL,0x68d3c0526aab7b52L, - 0xf0d7248c660e3feaL,0xafdb3f893145efb4L,0xa73fd9a38f40936dL } }, - /* 232 */ - { { 0x891b9ef3bb1b17ceL,0x14023667c6127f31L,0x12b2e58d305521fdL, - 0x3a47e449e3508088L,0xe49fc84bff751507L,0x4023f7225310d16eL }, - { 0xa608e5edb73399faL,0xf12632d8d532aa3eL,0x13a2758e845e8415L, - 0xae4b6f851fc2d861L,0x3879f5b1339d02f2L,0x446d22a680d99ebdL } }, - /* 233 */ - { { 0x0f5023024be164f1L,0x8d09d2d688b81920L,0x514056f1984aceffL, - 0xa5c4ddf075e9e80dL,0x38cb47e6df496a93L,0x899e1d6b38df6bf7L }, - { 0x69e87e88b59eb2a6L,0x280d9d639b47f38bL,0x599411ea3654e955L, - 0xcf8dd4fd969aa581L,0xff5c2baf530742a7L,0xa43915361a373085L } }, - /* 234 */ - { { 0x6ace72a3a8a4bdd2L,0xc656cdd1b68ef702L,0xd4a33e7e90c4dad8L, - 0x4aece08a9d951c50L,0xea8005ae085d68e6L,0xfdd7a7d76f7502b8L }, - { 0xce6fb0a698d6fa45L,0x228f86721104eb8cL,0xd23d8787da09d7dcL, - 0x5521428b2ae93065L,0x95faba3dea56c366L,0xedbe50390a88aca5L } }, - /* 235 */ - { { 0xd64da0adbfb26c82L,0xe5d70b3c952c2f9cL,0xf5e8f365f7e77f68L, - 0x7234e00208f2d695L,0xfaf900eed12e7be6L,0x27dc69344acf734eL }, - { 0x80e4ff5ec260a46aL,0x7da5ebce2dc31c28L,0x485c5d73ca69f552L, - 0xcdfb6b2969cc84c2L,0x031c5afeed6d4ecaL,0xc7bbf4c822247637L } }, - /* 236 */ - { { 0x9d5b72c749fe01b2L,0x34785186793a91b8L,0xa3ba3c54cf460438L, - 0x73e8e43d3ab21b6fL,0x50cde8e0be57b8abL,0x6488b3a7dd204264L }, - { 0xa9e398b3dddc4582L,0x1698c1a95bec46feL,0x7f1446ef156d3843L, - 0x3fd25dd8770329a2L,0x05b1221a2c710668L,0x65b2dc2aa72ee6cfL } }, - /* 237 */ - { { 0x21a885f7cd021d63L,0x3f344b15fea61f08L,0xad5ba6ddc5cf73e6L, - 0x154d0d8f227a8b23L,0x9b74373cdc559311L,0x4feab71598620fa1L }, - { 0x5098938e7d9ec924L,0x84d54a5e6d47e550L,0x1a2d1bdc1b617506L, - 0x99fe1782615868a4L,0x171da7803005a924L,0xa70bf5ed7d8f79b6L } }, - /* 238 */ - { { 0x0bc1250dfe2216c5L,0x2c37e2507601b351L,0xb6300175d6f06b7eL, - 0x4dde8ca18bfeb9b7L,0x4f210432b82f843dL,0x8d70e2f9b1ac0afdL }, - { 0x25c73b78aae91abbL,0x0230dca3863028f2L,0x8b923ecfe5cf30b7L, - 0xed754ec25506f265L,0x8e41b88c729a5e39L,0xee67cec2babf889bL } }, - /* 239 */ - { { 0xe183acf51be46c65L,0x9789538fe7565d7aL,0x87873391d9627b4eL, - 0xbf4ac4c19f1d9187L,0x5db99f634691f5c8L,0xa68df80374a1fb98L }, - { 0x3c448ed1bf92b5faL,0xa098c8413e0bdc32L,0x8e74cd5579bf016cL, - 0x5df0d09c115e244dL,0x9418ad013410b66eL,0x8b6124cb17a02130L } }, - /* 240 */ - { { 0x425ec3afc26e3392L,0xc07f8470a1722e00L,0xdcc28190e2356b43L, - 0x4ed97dffb1ef59a6L,0xc22b3ad1c63028c1L,0x070723c268c18988L }, - { 0x70da302f4cf49e7dL,0xc5e87c933f12a522L,0x74acdd1d18594148L, - 0xad5f73abca74124cL,0xe72e4a3ed69fd478L,0x615938687b117cc3L } }, - /* 241 */ - { { 0x7b7b9577a9aa0486L,0x6e41fb35a063d557L,0xb017d5c7da9047d7L, - 0x8c74828068a87ba9L,0xab45fa5cdf08ad93L,0xcd9fb2174c288a28L }, - { 0x595446425747843dL,0x34d64c6ca56111e3L,0x12e47ea14bfce8d5L, - 0x17740e056169267fL,0x5c49438eeed03fb5L,0x9da30add4fc3f513L } }, - /* 242 */ - { { 0xc4e85282ccfa5200L,0x2707608f6a19b13dL,0xdcb9a53df5726e2fL, - 0x612407c9e9427de5L,0x3e5a17e1d54d582aL,0xb99877de655ae118L }, - { 0x6f0e972b015254deL,0x92a56db1f0a6f7c5L,0xd297e4e1a656f8b2L, - 0x99fe0052ad981983L,0xd3652d2f07cfed84L,0xc784352e843c1738L } }, - /* 243 */ - { { 0x6ee90af07e9b2d8aL,0xac8d701857cf1964L,0xf6ed903171f28efcL, - 0x7f70d5a96812b20eL,0x27b557f4f1c61eeeL,0xf1c9bd57c6263758L }, - { 0x5cf7d0142a1a6194L,0xdd614e0b1890ab84L,0x3ef9de100e93c2a6L, - 0xf98cf575e0cd91c5L,0x504ec0c614befc32L,0xd0513a666279d68cL } }, - /* 244 */ - { { 0xa8eadbada859fb6aL,0xcf8346e7db283666L,0x7b35e61a3e22e355L, - 0x293ece2c99639c6bL,0xfa0162e256f241c8L,0xd2e6c7b9bf7a1ddaL }, - { 0xd0de625340075e63L,0x2405aa61f9ec8286L,0x2237830a8fe45494L, - 0x4fd01ac7364e9c8cL,0x4d9c3d21904ba750L,0xd589be14af1b520bL } }, - /* 245 */ - { { 0x13576a4f4662e53bL,0x35ec2f51f9077676L,0x66297d1397c0af97L, - 0xed3201fe9e598b58L,0x49bc752a5e70f604L,0xb54af535bb12d951L }, - { 0x36ea4c2b212c1c76L,0x18f5bbc7eb250dfdL,0xa0d466cc9a0a1a46L, - 0x52564da4dac2d917L,0x206559f48e95fab5L,0x7487c1909ca67a33L } }, - /* 246 */ - { { 0x75abfe37dde98e9cL,0x99b90b262a411199L,0x1b410996dcdb1f7cL, - 0xab346f118b3b5675L,0x04852193f1f8ae1eL,0x1ec4d2276b8b98c1L }, - { 0xba3bc92645452baaL,0x387d1858acc4a572L,0x9478eff6e51f171eL, - 0xf357077d931e1c00L,0xffee77cde54c8ca8L,0xfb4892ff551dc9a4L } }, - /* 247 */ - { { 0x5b1bdad02db8dff8L,0xd462f4fd5a2285a2L,0x1d6aad8eda00b461L, - 0x43fbefcf41306d1bL,0x428e86f36a13fe19L,0xc8b2f11817f89404L }, - { 0x762528aaf0d51afbL,0xa3e2fea4549b1d06L,0x86fad8f2ea3ddf66L, - 0x0d9ccc4b4fbdd206L,0xcde97d4cc189ff5aL,0xc36793d6199f19a6L } }, - /* 248 */ - { { 0xea38909b51b85197L,0xffb17dd0b4c92895L,0x0eb0878b1ddb3f3fL, - 0xb05d28ffc57cf0f2L,0xd8bde2e71abd57e2L,0x7f2be28dc40c1b20L }, - { 0x6554dca2299a2d48L,0x5130ba2e8377982dL,0x8863205f1071971aL, - 0x15ee62827cf2825dL,0xd4b6c57f03748f2bL,0xa9e3f4da430385a0L } }, - /* 249 */ - { { 0x33eb7cec83fbc9c6L,0x24a311c74541777eL,0xc81377f74f0767fcL, - 0x12adae364ab702daL,0xb7fcb6db2a779696L,0x4a6fb28401cea6adL }, - { 0x5e8b1d2acdfc73deL,0xd0efae8d1b02fd32L,0x3f99c190d81d8519L, - 0x3c18f7fafc808971L,0x41f713e751b7ae7bL,0x0a4b3435f07fc3f8L } }, - /* 250 */ - { { 0x7dda3c4c019b7d2eL,0x631c8d1ad4dc4b89L,0x5489cd6e1cdb313cL, - 0xd44aed104c07bb06L,0x8f97e13a75f000d1L,0x0e9ee64fdda5df4dL }, - { 0xeaa99f3b3e346910L,0x622f6921fa294ad7L,0x22aaa20d0d0b2fe9L, - 0x4fed2f991e5881baL,0x9af3b2d6c1571802L,0x919e67a8dc7ee17cL } }, - /* 251 */ - { { 0xc724fe4c76250533L,0x8a2080e57d817ef8L,0xa2afb0f4172c9751L, - 0x9b10cdeb17c0702eL,0xbf3975e3c9b7e3e9L,0x206117df1cd0cdc5L }, - { 0xfb049e61be05ebd5L,0xeb0bb55c16c782c0L,0x13a331b8ab7fed09L, - 0xf6c58b1d632863f0L,0x6264ef6e4d3b6195L,0x92c51b639a53f116L } }, - /* 252 */ - { { 0xa57c7bc8288b364dL,0x4a562e087b41e5c4L,0x699d21c6698a9a11L, - 0xa4ed9581f3f849b9L,0xa223eef39eb726baL,0x13159c23cc2884f9L }, - { 0x73931e583a3f4963L,0x965003890ada6a81L,0x3ee8a1c65ab2950bL, - 0xeedf4949775fab52L,0x63d652e14f2671b6L,0xfed4491c3c4e2f55L } }, - /* 253 */ - { { 0x335eadc3f4eb453eL,0x5ff74b63cadd1a5bL,0x6933d0d75d84a91aL, - 0x9ca3eeb9b49ba337L,0x1f6faccec04c15b8L,0x4ef19326dc09a7e4L }, - { 0x53d2d3243dca3233L,0x0ee40590a2259d4bL,0x18c22edb5546f002L, - 0x9242980109ea6b71L,0xaada0addb0e91e61L,0x5fe53ef499963c50L } }, - /* 254 */ - { { 0x372dd06b90c28c65L,0x1765242c119ce47dL,0xc041fb806b22fc82L, - 0x667edf07b0a7ccc1L,0xc79599e71261beceL,0xbc69d9ba19cff22aL }, - { 0x009d77cd13c06819L,0x635a66aee282b79dL,0x4edac4a6225b1be8L, - 0x57d4f4e4524008f9L,0xee299ac5b056af84L,0xcc38444c3a0bc386L } }, - /* 255 */ - { { 0x490643b1cd4c2356L,0x740a4851750547beL,0x643eaf29d4944c04L, - 0xba572479299a98a0L,0x48b29f16ee05fdf9L,0x33fb4f61089b2d7bL }, - { 0x86704902a950f955L,0x97e1034dfedc3ddfL,0x211320b605fbb6a2L, - 0x23d7b93f432299bbL,0x1fe1a0578590e4a3L,0x8e1d0586f58c0ce6L } }, + { { 0x1ae0c4e11c718580L,0x303f48a6bf99a0bfL,0xa5551e4491ae219fL, + 0xdc41d9bd55a05287L,0xd5aa73e36872b123L,0x6fd94b0ce6395bf6L }, + { 0xbb95fdbac00afbc1L,0x9cd96208497cac10L,0x8adbd8c1ca51afeaL, + 0x94fedafbf3bc5f5fL,0x29c0217bdf9f5371L,0x5c13eb4bd9024634L } }, }; /* Multiply the base point of P384 by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Stripe implementation. + * Pre-generated: 2^0, 2^64, ... + * Pre-generated: products of all combinations of above. + * 6 doubles and adds (with qz=1) + * * r Resulting point. * k Scalar to multiply by. * map Indicates whether to convert result to affine. @@ -29372,6 +29259,11 @@ static int sp_384_ecc_mulmod_base_6(sp_point_384* r, const sp_digit* k, /* Multiply the base point of P384 by the scalar and return the result. * If map is true then convert result to affine coordinates. * + * Stripe implementation. + * Pre-generated: 2^0, 2^64, ... + * Pre-generated: products of all combinations of above. + * 6 doubles and adds (with qz=1) + * * r Resulting point. * k Scalar to multiply by. * map Indicates whether to convert result to affine. @@ -29387,6 +29279,18099 @@ static int sp_384_ecc_mulmod_base_avx2_6(sp_point_384* r, const sp_digit* k, } #endif /* HAVE_INTEL_AVX2 */ +#else /* WOLFSSL_SP_SMALL */ +/* The index into pre-computation table to use. */ +static const uint8_t recode_index_6_7[130] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, + 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, + 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, + 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, + 0, 1, +}; + +/* Whether to negate y-ordinate. */ +static const uint8_t recode_neg_6_7[130] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, +}; + +/* Recode the scalar for multiplication using pre-computed values and + * subtraction. + * + * k Scalar to multiply by. + * v Vector of operations to perform. + */ +static void sp_384_ecc_recode_7_6(const sp_digit* k, ecc_recode_384* v) +{ + int i; + int j; + uint8_t y; + int carry = 0; + int o; + sp_digit n; + + j = 0; + n = k[j]; + o = 0; + for (i=0; i<55; i++) { + y = (int8_t)n; + if (o + 7 < 64) { + y &= 0x7f; + n >>= 7; + o += 7; + } + else if (o + 7 == 64) { + n >>= 7; + if (++j < 6) + n = k[j]; + o = 0; + } + else if (++j < 6) { + n = k[j]; + y |= (uint8_t)((n << (64 - o)) & 0x7f); + o -= 57; + n >>= o; + } + + y += (uint8_t)carry; + v[i].i = recode_index_6_7[y]; + v[i].neg = recode_neg_6_7[y]; + carry = (y >> 7) + v[i].neg; + } +} + +extern void sp_384_get_entry_65_6(sp_point_384* r, const sp_table_entry_384* table, int idx); +extern void sp_384_get_entry_65_avx2_6(sp_point_384* r, const sp_table_entry_384* table, int idx); +static const sp_table_entry_384 p384_table[3575] = { + /* 0 << 0 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 0 */ + { { 0x3dd0756649c0b528L,0x20e378e2a0d6ce38L,0x879c3afc541b4d6eL, + 0x6454868459a30effL,0x812ff723614ede2bL,0x4d3aadc2299e1513L }, + { 0x23043dad4b03a4feL,0xa1bfa8bf7bb4a9acL,0x8bade7562e83b050L, + 0xc6c3521968f4ffd9L,0xdd8002263969a840L,0x2b78abc25a15c5e9L } }, + /* 2 << 0 */ + { { 0xc8229e55783dde91L,0x8e6c8f2e022b53f0L,0x3504e6f0ff9d48a1L, + 0xda821495f0687f50L,0x9c90a4fd2de4b506L,0xdb93b776427460c3L }, + { 0x42ea84633140bfdaL,0xe8e8e4a8c2aaccd8L,0x15e4f18bdc588258L, + 0x09f1fe415172bad9L,0x070d430900b0e684L,0xe34947f7123df0c2L } }, + /* 3 << 0 */ + { { 0x05e4dbe6c1dc4073L,0xc54ea9fff04f779cL,0x6b2034e9a170ccf0L, + 0x3a48d732d51c6c3eL,0xe36f7e2d263aa470L,0xd283fe68e7c1c3acL }, + { 0x7e284821c04ee157L,0x92d789a77ae0e36dL,0x132663c04ef67446L, + 0x68012d5ad2e1d0b4L,0xf6db68b15102b339L,0x465465fc983292afL } }, + /* 4 << 0 */ + { { 0x0aae8477ebb68f2cL,0x30594ccbee0421e3L,0x2e4f153b0aecac46L, + 0x078358d4736400adL,0xfb40f647d685d979L,0xcfeee6dd34179228L }, + { 0x54f3e8e79b3a03b2L,0xe74bb7f17bfec97eL,0x8e3e61a34c542ad1L, + 0x147162d30418c693L,0xe607b9e33820017dL,0x50946875303df319L } }, + /* 5 << 0 */ + { { 0xbb595eba68f1f0dfL,0xc185c0cbcc873466L,0x7f1eb1b5293c703bL, + 0x60db2cf5aacc05e6L,0xc676b987e2e8e4c6L,0xe1bb26b11d178ffbL }, + { 0x2b694ba07073fa21L,0x22c16e2e72f34566L,0x80b61b3101c35b99L, + 0x4b237faf982c0411L,0xe6c5944024de236dL,0x4db1c9d6e209e4a3L } }, + /* 6 << 0 */ + { { 0x7eb5c9317d56dad8L,0xcb2454b339d3413aL,0xec52930f580d57f2L, + 0x2a33f6661bdf6015L,0x4f0f6a962b02d33bL,0xc482e189f0430c40L }, + { 0x3f62b16ea7b08203L,0x739ac69d5b3d4dceL,0x8bd4bffcb79e33b0L, + 0x93c9e5f61b546f05L,0x586d8ededf21559aL,0xc9962152af2a9ebaL } }, + /* 7 << 0 */ + { { 0xdf13b9d17d69222bL,0x4ce6415f874774b1L,0x731edcf8211faa95L, + 0x5f4215d1659753edL,0xf893db589db2df55L,0x932c9f811c89025bL }, + { 0x0996b2207706a61eL,0x135349d5a8641c79L,0x65aad76f50130844L, + 0x0ff37c0401fff780L,0xf57f238e693b0706L,0xd90a16b6af6c9b3eL } }, + /* 8 << 0 */ + { { 0x23f60a05dd9bcbbaL,0x9e336de5ae9b587aL,0x1c5c2e7193d7e30fL, + 0x1d9aebd64f3ddb37L,0x1c7b5fe116b66423L,0x5db4f184349cd9b1L }, + { 0x0d2cfe83e6655a44L,0x836dbb36b7e55e87L,0x701754bf7d8686e4L, + 0xe9923263a42dbba2L,0x7008d943c48ecf0eL,0x3c0c6dd70d27ef61L } }, + /* 9 << 0 */ + { { 0x2f5d200e2353b92fL,0xe35d87293fd7e4f9L,0x26094833a96d745dL, + 0xdc351dc13cbfff3fL,0x26d464c6dad54d6aL,0x5cab1d1d53636c6aL }, + { 0xf2813072b18ec0b0L,0x3777e270d742aa2fL,0x27f061c7033ca7c2L, + 0xa6ecaccc68ead0d8L,0x7d9429f4ee69a754L,0xe770633431e8f5c6L } }, + /* 10 << 0 */ + { { 0x845539d3c8d99c02L,0x2a15a9a6e58d6787L,0xe9f6368eab225fa3L, + 0x54a612d7eb32cabeL,0xc2f646025c4845ecL,0xa91a5280db1c212eL }, + { 0xbb971f78e67b5fceL,0x03a530eb13b9e85cL,0x592ac0ba794eabfdL, + 0x81961b8ccfd7fd1dL,0x3e03370a47a9b8aaL,0x6eb995bec80174e8L } }, + /* 11 << 0 */ + { { 0xc7708b19b68b8c7dL,0x4532077c44377abaL,0x0dcc67706cdad64fL, + 0x01b8bf56147b6602L,0xf8d89885f0561d79L,0x9c19e9fc7ba9c437L }, + { 0x764eb146bdc4ba25L,0x604fe46bac144b83L,0x3ce813298a77e780L, + 0x2e070f36fe9e682eL,0x41821d0c3a53287aL,0x9aa62f9f3533f918L } }, + /* 12 << 0 */ + { { 0x3db8477270313de0L,0xd4258cc55d970420L,0x03aced26c8edfee1L, + 0xf67eb42235d77d83L,0x523c40dbcf9ab45cL,0x627b415f9c35b26dL }, + { 0xfacc45e48be55ed8L,0x80d60af627aa651aL,0x8c79848fd0e102acL, + 0x40c64a4e66bed5afL,0x0329eab1f7942f0eL,0x0c6e430ef9c4af3dL } }, + /* 13 << 0 */ + { { 0x9b7aeb7e75ccbdfbL,0xb25e28c5f6749a95L,0x8a7a8e4633b7d4aeL, + 0xdb5203a8d9c1bd56L,0xd2657265ed22df97L,0xb51c56e18cf23c94L }, + { 0xf4d394596c3d812dL,0xd8e88f1a87cae0c2L,0x789a2a48cf4d0fe3L, + 0xb7feac2dfec38d60L,0x81fdbd1c3b490ec3L,0x4617adb7cc6979e1L } }, + /* 14 << 0 */ + { { 0x5865e5018f75244cL,0xd02225fb01ec909fL,0xca6b1af8b1f85c2aL, + 0x44ce05ff88957166L,0x8058994c5710c0c9L,0x46d227c432f6b1baL }, + { 0xbe4b4a9003cb68e5L,0x540b8b82730a99d1L,0x1ecc8585e11dbbbfL, + 0x72445345d9c3b691L,0x647d24db13690a74L,0x4429839ddefbadf5L } }, + /* 15 << 0 */ + { { 0x446ad8884709f4a9L,0x2b7210e2ec3dabd8L,0x83ccf19550e07b34L, + 0x59500917789b3075L,0x0fc01fd4eb085993L,0xfb62d26f4903026bL }, + { 0x2309cc9d6fe989bbL,0x61609cbd144bd586L,0x4b23d3a0de06610cL, + 0xdddc2866d898f470L,0x8733fc41400c5797L,0x5a68c6fed0bc2716L } }, + /* 16 << 0 */ + { { 0xda6e8a7f7c33ed91L,0x992afb5b0ecdd2d8L,0x37cf65517917652aL, + 0x317b63ea2887d5ffL,0x37065f5313bdc3faL,0xa10896aa435abaa1L }, + { 0x9b21615fefabca26L,0xeb07ddea230cf00dL,0x914871dc154d410fL, + 0xb333bdfbc88ee148L,0x51c305c6a72d1967L,0x659db48181ef2513L } }, + /* 17 << 0 */ + { { 0x8903e1304b4a3cd0L,0x3ea4ea4c8ff1f43eL,0xe6fc3f2af655a10dL, + 0x7be3737d524ffefcL,0x9f6928555330455eL,0x524f166ee475ce70L }, + { 0x3fcc69cd6c12f055L,0x4e23b6ffd5b9c0daL,0x49ce6993336bf183L, + 0xf87d6d854a54504aL,0x25eb5df1b3c2677aL,0xac37986f55b164c9L } }, + /* 18 << 0 */ + { { 0x5dfee73ce5b82700L,0x198fd3f0f38f6662L,0x3bd1c8f62edb0dbdL, + 0x55a96a6879909f08L,0x68a2324355671693L,0x57505d8d67497030L }, + { 0x8a60717f75c64513L,0x54b867b7f78aa7deL,0xc266eb8441129858L, + 0x6ffcfc7ca4cfd9bbL,0x9bdd6a092945a757L,0x91700b247eb1be63L } }, + /* 19 << 0 */ + { { 0x82a2ed4abaa84c08L,0x22c4cc5f41a8c912L,0xca109c3b154aad5eL, + 0x23891298fc38538eL,0xb3b6639c539802aeL,0xfa0f1f450390d706L }, + { 0x46b78e5db0dc21d0L,0xa8c72d3cc3da2eacL,0x9170b3786ff2f643L, + 0x3f5a799bb67f30c3L,0x15d1dc778264b672L,0xa1d47b23e9577764L } }, + /* 20 << 0 */ + { { 0xad610a2d94a70ec1L,0xcd96f20591e71d16L,0x713466708cbaffc7L, + 0xf78cff0cd467f03aL,0x98ca8dd42d96c936L,0x1d1cdf7b5f223465L }, + { 0xe27a189460d4db60L,0x25f546ab321828ffL,0x9933fb25dccd4df3L, + 0x422da643ffe6132bL,0x5e01b72b4718bbc7L,0xab9dd81052ebfb01L } }, + /* 21 << 0 */ + { { 0x08265e510422ce2fL,0x88e0d496dd2f9e21L,0x30128aa06177f75dL, + 0x2e59ab62bd9ebe69L,0x1b1a0f6c5df0e537L,0xab16c626dac012b5L }, + { 0x8014214b008c5de7L,0xaa740a9e38f17beaL,0x262ebb498a149098L, + 0xb454111e8527cd59L,0x266ad15aacea5817L,0x21824f411353ccbaL } }, + /* 22 << 0 */ + { { 0x4f595351262bb775L,0x981b788d16f325b8L,0xccd57831927ed783L, + 0xc382472ebe0e1fdbL,0xfd7a8b13f0681fcaL,0xe082882d69059095L }, + { 0x4d1c3049faa71fdcL,0xf9d62fd9c9576c69L,0x7b1ab489cbf837b7L, + 0xc764edf840d0fcf7L,0x50fc847215809cddL,0x671d69c98fcd8418L } }, + /* 23 << 0 */ + { { 0xd1b4e74d12e3683bL,0x990ed20b569b8ef6L,0xb9d3dd25429c0a18L, + 0x1c75b8ab2a351783L,0x61e4ca2b905432f0L,0x80826a69eea8f224L }, + { 0x7fc33a6bec52abadL,0x0bcca3f0a65e4813L,0x7ad8a132a527cebeL, + 0xf0138950eaf22c7eL,0x282d2437566718c1L,0x9dfccb0de2212559L } }, + /* 24 << 0 */ + { { 0x259f272cfab816a7L,0x20c1b8e0d809afcdL,0x540c045a409c930bL, + 0x563361909bd5c2f7L,0x38076e8fca77d74fL,0x4f13f901fc55723fL }, + { 0x890932d7bd3d10c3L,0x98d82ad1da247ec8L,0xdf5579fa4bea82ddL, + 0xe8277439a0f9ad3aL,0x1395a87966a4e904L,0x150808e625a302c9L } }, + /* 25 << 0 */ + { { 0x1e93722758ce3b83L,0xbb280dfa3cb3fb36L,0x57d0f3d2e2be174aL, + 0x9bd51b99208abe1eL,0x3809ab50de248024L,0xc29c6e2ca5bb7331L }, + { 0x9944fd2e61124f05L,0x83ccbc4e9009e391L,0x01628f059424a3ccL, + 0xd6a2f51dea8e4344L,0xda3e1a3d4cebc96eL,0x1fe6fb42e97809dcL } }, + /* 26 << 0 */ + { { 0x6423197d2afd473dL,0xb0391b37897b93f5L,0x6efedb8023bf0b90L, + 0x808497b7b0bba4a7L,0xf14b309f03fa90f2L,0x37a45bdb091cbb80L }, + { 0xedda4ae48a8f5dcbL,0xdb3f422d95e16d6eL,0x25c7b9146f5f24c7L, + 0x5d512df99d42a727L,0xbf2c0862697c08fdL,0x47d98a9df092241cL } }, + /* 27 << 0 */ + { { 0xa04482d2467d66e4L,0xcf1912934d78291dL,0x8e0d4168482396f9L, + 0x7228e2d5d18f14d0L,0x2f7e8d509c6a58feL,0xe8ca780e373e5aecL }, + { 0x42aad1d61b68e9f8L,0x58a6d7f569e2f8f4L,0xd779adfe31da1beaL, + 0x7d26540638c85a85L,0x67e67195d44d3cdfL,0x17820a0bc5134ed7L } }, + /* 28 << 0 */ + { { 0xc76afaa373b64643L,0x4169b4117b3c1220L,0x550e0bee8ff22c6fL, + 0x8fb0c597a4da3e15L,0xd8232f8b4e492aa8L,0x55be5764d37da1a2L }, + { 0xf1bc89b628e77f9eL,0x9ff769c4875fee0fL,0x184bd4733ad6983aL, + 0xc48ee6f3b033c112L,0x792377fbf8eb8319L,0x05cdca3fe7988176L } }, + /* 29 << 0 */ + { { 0x019d6ac5d3021470L,0x25846b66780443d6L,0xce3c15ed55c97647L, + 0x3dc22d490e3feb0fL,0x2065b7cba7df26e4L,0xc8b00ae8187cea1fL }, + { 0x1a5284a0865dded3L,0x293c164920c83de2L,0xab178d26cce851b3L, + 0x8e6db10b404505fbL,0xf6f57e7190c82033L,0x1d2a1c015977f16cL } }, + /* 30 << 0 */ + { { 0x6a7a3464d0cbcea0L,0x76aad8b813126388L,0x519b9fd50a183232L, + 0x15f9abe1feb6b100L,0x7002990485ba4143L,0x92cea8f4c4360dd8L }, + { 0xdc6c5d1dc12748a1L,0x1846eefcdd3eb156L,0x3117dd04d47a41dcL, + 0x96c21b29f6a167f2L,0xf569446a27555692L,0x941292e500f88cb2L } }, + /* 31 << 0 */ + { { 0xa39c89317c8906a4L,0xb6e7ecdd9e821ee6L,0x2ecf8340f0df4fe6L, + 0xd42f7dc953c14965L,0x1afb51a3e3ba8285L,0x6c07c4040a3305d1L }, + { 0xdab83288127fc1daL,0xbc0a699b374c4b08L,0x402a9bab42eb20ddL, + 0xd7dd464f045a7a1cL,0x5b3d0d6d36beecc4L,0x475a3e756398a19dL } }, + /* 32 << 0 */ + { { 0xad852b878c0a64a4L,0x0d784cf208f779d5L,0x1896b9fcc651b1ddL, + 0xba8953d612e8dc87L,0x3a9865baa631cfb0L,0x5dd2a4a0626b3d79L }, + { 0x1148bc72687c20bbL,0xa372dfc2f2a52bfdL,0x77315f9e9448fd08L, + 0x4bcb06f00a2377b6L,0x73b42725b35b4ff0L,0xc510ad93aabca99fL } }, + /* 33 << 0 */ + { { 0x61333a382fb3ba63L,0xdf330d9d5b943c86L,0xbbc7c7ee955ef3afL, + 0xda631fc160f09efbL,0x68af622641d5c400L,0xcc9e97a46c833e9dL }, + { 0x7fd73e8e3a625e76L,0x13bf6124c209e55eL,0x08467cea48b90b91L, + 0x8a416eb9bb6f0abaL,0x6fcc93a1b8c31072L,0xa7fd2b619057dad7L } }, + /* 34 << 0 */ + { { 0x80b309dd2ada5bf4L,0x0648c2cd2d668c41L,0x45700722abb9102fL, + 0x9d6ac102b4e25201L,0x7ec2bc1cd50b3e6dL,0xcdb55e6ba07b7caeL }, + { 0xebcbda0786da3943L,0x470ddc68f8a57f48L,0x9e1418a4554557c3L, + 0x02d00cfb8a76b2d6L,0x03c050a061520726L,0xa964eefbfdadd24eL } }, + /* 35 << 0 */ + { { 0x58a5b5433720ec9bL,0xbb3800d52d7c2fb4L,0x4a508620dde6bd0aL, + 0x65f16273a02583fdL,0x832bd8e34fc78523L,0xd6149f75e9417bc6L }, + { 0xfeb026e93deeb52aL,0x0ce18088a55e0956L,0x50018998988092a2L, + 0x22f19fab28f35eeeL,0xac8a877f52ccd35cL,0xb13a8ad830e23f26L } }, + /* 36 << 0 */ + { { 0xf216aa2531238ed0L,0x4a13260770b1b757L,0xa39180d45c2c7ce1L, + 0x9f82b7fbab52606cL,0x6f01faee26946e78L,0x1608643883061d37L }, + { 0x597edf370fb077bcL,0x1d11bc5ed6e28138L,0x10209418c167fd20L, + 0x6a3258ec33f55675L,0xdf33eed7b73401b1L,0xf699887b806085b7L } }, + /* 37 << 0 */ + { { 0x0202d57de44f61a3L,0x4027704bb5630ef2L,0xa129e2dff5b54a5dL, + 0xacb60a7597482b86L,0x9261ede87ef27114L,0x1eba28f3defc58b5L }, + { 0x6c91c0c98be5589eL,0x2f1643d514594beeL,0x2ea912435d2ca034L, + 0xb50649a894047d1fL,0x284fcbb5638ca337L,0xfa0e07b7fe85bf85L } }, + /* 38 << 0 */ + { { 0x4703cd85891f8ffeL,0x018843c01c0d7702L,0xf3d752f5ad6cbeacL, + 0x479ecf018173fb32L,0x6b464412bc9a48c7L,0x47ba96091da7b147L }, + { 0x91af26eaabc13488L,0x87c183c3e1a0e06cL,0xdae2479844956b93L, + 0xf300e1c648347f9aL,0x129be314974320a4L,0x1f466694520618f2L } }, + /* 39 << 0 */ + { { 0x7d894f80506e0e42L,0xd984244a8e3d2c46L,0x6d7edf642b7f006fL, + 0x36a1cd6dde9b6230L,0xc9985040b76c0665L,0x587df4d6b89b1fc2L }, + { 0x4c0638476a71ae7aL,0x7b2b0ab3e8294747L,0x345c553ab53153b8L, + 0xb646e453436d9fe2L,0x1a95355f1cd60340L,0x2d7bc128074968fbL } }, + /* 40 << 0 */ + { { 0x6048c6949399c38aL,0x43a53ff21beb359eL,0x86fcfe4760be3ebcL, + 0xae78bc3a3134216cL,0x3b021cf316d7a9adL,0x51c4b1b36a4d6e81L }, + { 0x54b9cd8db593d816L,0x1df8cc84a69ea3a3L,0x98ff87f7370eb744L, + 0x63a00a0a60e0aa2aL,0xdbb22c9ddeb46e6cL,0xdfd92b6da914bb01L } }, + /* 41 << 0 */ + { { 0xad148e87bca6d14cL,0x41dfd24d456a201eL,0x73a82933a80d68f3L, + 0x89746c8d852ca035L,0xe3bc778895fd71aeL,0x8764cd2cda92245dL }, + { 0xa2fe2c4782eb23e2L,0x5ac762e00f3c9d6eL,0x57860ce121646f31L, + 0xbdc9d6c34f9f589aL,0x679952c7d193272eL,0x82ea702eeb18f1c5L } }, + /* 42 << 0 */ + { { 0x18ef56cd5d76b881L,0x31b22efc5df46c66L,0x4b21c4f3eb6c7e62L, + 0x3fd72a308f234c86L,0xe983e169ffff96c7L,0x7438b4933c1e593cL }, + { 0x863a23a3a553e8e3L,0x0d959ba9796d9129L,0x25d0caaeda1eadf4L, + 0xe739fb61eaa67763L,0x50029568472a7175L,0xdb6829c2f002bb6eL } }, + /* 43 << 0 */ + { { 0x37fa935500846d44L,0x09112fc50578bc8cL,0xdad9f5b239c4943dL, + 0x7314f5f0416dbd86L,0x5cf095a901fefb56L,0x35178bad22dab393L }, + { 0xcf79fc1b36baf1a7L,0x1b7ee42d749e5498L,0xbce78aa9ede314bbL, + 0xaaf8e0f6bd0628dfL,0xa974b09415cbf948L,0x8f3f1f63c9632b78L } }, + /* 44 << 0 */ + { { 0x1c5f0e5b36a400d3L,0xae97af8bf240b30aL,0x767b4ad7f8f99b51L, + 0xd50a288981ea36c2L,0x04ce2a21986c5ce6L,0x9c7e7754a320d352L }, + { 0xc3336331bbad8346L,0x7cc82a4df1698fb2L,0xc680176505c7ad6cL, + 0x47678afb27dda8e5L,0xade6096d02e543aeL,0x5fb28e322a1dd73bL } }, + /* 45 << 0 */ + { { 0xd4c411564fddda5bL,0xd4af65c673ad9112L,0xffe8e0bb39eb8f59L, + 0xb0040c0e8d6fcf13L,0x99e1c0c61f2bb599L,0x9c94c858b2ac3405L }, + { 0x8f8878d76eeed85dL,0x62b2f54351fcca3fL,0xeb3b44a9e5b56918L, + 0x16f96676b7234e93L,0x17477722bd2af19eL,0x42eb2979db83a485L } }, + /* 46 << 0 */ + { { 0xa618d7479fc4f435L,0x9f24fba649ddd10eL,0x60976b01b472d789L, + 0x9266634957719f54L,0xd9c79db800541257L,0x374aa9069481ed0dL }, + { 0x60efb1147fdc2d7aL,0xa1590c30ecf58643L,0xd7a198a4185a849cL, + 0x19ab802314eb4ab9L,0xc82d5998ec090d06L,0xfc539eb3e259c7dbL } }, + /* 47 << 0 */ + { { 0x6f888f7df0c668caL,0x65c788785f0dc66cL,0xbfb185125f5b07a0L, + 0x780abff7d878acd0L,0x504f21b1570cf950L,0xea5b37c5da233371L }, + { 0x487ae8bd22437ed1L,0x9c701758249cf9b7L,0xf86562a898fb34ffL, + 0xdfeea1a265e0fc91L,0xeef006912e20fc23L,0xac9dfec7dfa72a8bL } }, + /* 48 << 0 */ + { { 0x3ccf806ab35bf6cfL,0x2d368d48e7f30c2bL,0x4f504e06ea52bef9L, + 0x40d01ff53a7d2f3cL,0x62e5c5d3e73a1bc9L,0x66e4794bae7d7400L }, + { 0x3d30625e5ffef312L,0x4580609da766ddf1L,0x5c3ca10d04bab985L, + 0x2605ca009da2a2caL,0x48eab00eb5c9462cL,0x271e42a12624a583L } }, + /* 49 << 0 */ + { { 0xfa5c3aef697136c6L,0x8ea5af63a5ea6fb8L,0xa669156542e365a4L, + 0x47c56c115b6e3386L,0x1197832bcea03f56L,0x0b470bb250e4ea9eL }, + { 0x3113c74313b25712L,0x8d6c174ed2497d48L,0xfc4486ee49c9ebe8L, + 0x2487edd57f82bdd3L,0x771e64415b57be2fL,0x2d1cc518e28b2bdbL } }, + /* 50 << 0 */ + { { 0xa96763d2fba32d1fL,0x172cfe4ecb5af900L,0x510bd675cb2ec3f1L, + 0xbeabb91ac3c90051L,0x9cbf755b46f97ac7L,0xa820e8303a5d50d1L }, + { 0x83a9f17e308c4545L,0xdf7dc7053048461aL,0x6124642f0f32b151L, + 0xc1b444139333e405L,0x6f7bfa7e13a4f7d6L,0x6f58fa8b7181c2a1L } }, + /* 51 << 0 */ + { { 0x2c4ccac72070ac8dL,0x1947c0caec4a22b8L,0xa5e0fb598c5a78d9L, + 0x464ae8d241a84de7L,0x3dba16e9daaabc27L,0x16634a504f35cb3cL }, + { 0xadc18bf9b16ec84fL,0x324d067e7359dd35L,0xdaeac0c3570543f0L, + 0x0b2240003c887d36L,0xc69489e2373f1a0dL,0x518b047dcbaa0d97L } }, + /* 52 << 0 */ + { { 0x8f6468656f9201b9L,0x8a944b316b326232L,0x5687d1dca6ccfd35L, + 0x0bedaa85e5377c00L,0x252b48f5cd8d7d77L,0x4b820d9b31d83660L }, + { 0xa9e5af3ccae07f15L,0x0a8930fc1208b9faL,0x6d0a166ced3c3b7aL, + 0x90e2aead7f78aaf8L,0x222465866e5ede76L,0xc5cc339dcba1fd4bL } }, + /* 53 << 0 */ + { { 0x3b1bddc6fbde49efL,0xdaed7c268a0915ccL,0x0b0110610f0422a2L, + 0xcf485c74a7c54b16L,0x642ec4e615c3aae2L,0xa8ba8f10e0f383eaL }, + { 0x2a2054b495618501L,0xebec6442089efa8bL,0x5786a19a4e2fa83eL, + 0xd2c71ad139069963L,0xadc93d9a481765e2L,0xedf2e3eb7ecc9485L } }, + /* 54 << 0 */ + { { 0x11853add834e6c54L,0xab2f15202175fbf4L,0xcff00bd23c9b5a41L, + 0x075134ebabd64a6aL,0x48c075daaadd6150L,0x4576a6497cb89442L }, + { 0x340a767034adeda3L,0x8dbb571c77fcd1f4L,0x0bf879d693b44ea6L, + 0x1ae1dd97d13444bbL,0x6e9e86bb7b1eb77aL,0x420eb673906a2949L } }, + /* 55 << 0 */ + { { 0xbcab5f60069f3367L,0xfd6622bc1718ec3cL,0xa4fb7867e3a142d6L, + 0x6078d8bf085faeb3L,0xfa5cbfda60f4554fL,0xb3fcd5d1690cd408L }, + { 0x4ebdee7d281f7884L,0x82af23aa180a63a7L,0x8de3107c3d079f61L, + 0x17c6b5cbbe2334f8L,0x6a91e73997d0fa06L,0x7460257314ceeed4L } }, + /* 56 << 0 */ + { { 0x483350a5ebb8cdadL,0xd4215b4fc7a8baa1L,0x8b6fc785e692fdd2L, + 0x2629ba4fd1deca25L,0xe9981ea6820da79fL,0x7772a913e6436cc1L }, + { 0xd141235c553fb41dL,0x28179e6cc852f64bL,0xb623a1aeeb8cc21cL, + 0x05826192490bb572L,0x56fefff326f349ceL,0x31ff648e0f88b82dL } }, + /* 57 << 0 */ + { { 0xb14ba61cf97f865cL,0x73bae4c1694b8b0dL,0xa14967dfac4bbf62L, + 0x1e9dd1509bf446e0L,0xc052f3eb1c99ceefL,0x814d7fa07a78c189L }, + { 0xa101a483ab74b05dL,0x7788c258a1737b65L,0x0d60bab7e809a13cL, + 0x8f427bc473c81d5bL,0xd2e130552952c1fcL,0x0a823b9a4b26df63L } }, + /* 58 << 0 */ + { { 0x941c5c257d0be180L,0x341cf9d9c46785afL,0xdab9dc0015b0fa13L, + 0xa58db4ea4f96af4fL,0x9e9520bf57acc87aL,0x104cec0666ac72e0L }, + { 0x9f3f7baa1929e675L,0xb8b4ac9ffa80380aL,0xb5f157aa569b57d8L, + 0xe11699e909fa58a1L,0xc08595e35548fbeaL,0x2b51995f794da901L } }, + /* 59 << 0 */ + { { 0xaf467ce227bf64c9L,0xdfca6897f929974cL,0x64473b595c322738L, + 0x96a917cf1ed0e315L,0x3703435b0de64db9L,0x9ba039679267b646L }, + { 0xdf0c2aae3a522fbeL,0x41bdb741b335eff0L,0xaccf2edd7b059703L, + 0x6fb34b3028463cceL,0x96d9ba0bd9e3ca19L,0xff336f12504655c1L } }, + /* 60 << 0 */ + { { 0xc711d5d1c425543eL,0xa61fada6fb4f60e8L,0x0402d5c4eb809f85L, + 0x84b7c2fed74cccd4L,0x61bba736a55b5277L,0x95bb80cece47968cL }, + { 0x09f92adc16eb7b95L,0xf0e0f4f7e682aa29L,0xacd70b86ad2a20fcL, + 0xbb45a51f948a8375L,0x29fc3b284892e676L,0x8dd21bf0b4ea4f51L } }, + /* 61 << 0 */ + { { 0x48da1fd3fc60a6e0L,0x54fb5a34222241e8L,0x6035e34f772ae080L, + 0x5ff77ff2332982d0L,0x2366467300fe51fdL,0xc93ea049ef6ba006L }, + { 0x6640f1177d381266L,0x394d32cd6ae9f4acL,0xe6a7885370d303ebL, + 0x0dda19ffe5275767L,0xb0a6c77201466d23L,0xc4cc11451fc69829L } }, + /* 62 << 0 */ + { { 0x49a04dc0f5acf772L,0x1e659730c1fb476eL,0x0c7d749907dbb9afL, + 0x03b9f1cebfec21daL,0xd194b7054b14d117L,0xcb4c0a54561fedf2L }, + { 0xaf623d3f21da4d42L,0x5f5e9b1fd630c145L,0x65609e59d9ff0abaL, + 0x3d2508922ba9239bL,0xcac324ec82c4faa7L,0x0902cc23149446b8L } }, + /* 63 << 0 */ + { { 0xc5c0e6d7aaed89c0L,0x6ce8ead6149a1896L,0x7a50f7458c949f8fL, + 0xcd7e35f76e2b71aaL,0xf6159e519a049f7aL,0x1c9bf0b0f1e52d1eL }, + { 0x3bb6c1f518202c80L,0x8d3a5f621ecd7b1aL,0x3bb034e888d17f19L, + 0xdc89bd4997d4048dL,0xf5af7b8e3735df22L,0x52bb3712a0a689e8L } }, + /* 64 << 0 */ + { { 0xed4de4f88e89b258L,0x957c980f297a9a37L,0xe04b3d30f8a0580dL, + 0xa309199dca57b7bdL,0xfc8e87cf3be44d56L,0x4f5d5ab6d1b30e5cL }, + { 0xb213c6a030a9325bL,0x0fd1c52df091bc01L,0xfe51bbbf1090fedeL, + 0x6d97cabc301fe259L,0x3ee127895ecd3fe8L,0x888b708b9404ca51L } }, + /* 0 << 7 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 7 */ + { { 0xe484fd9f8258030fL,0x0f4fa5eff21af80aL,0xc0dd449e7c1c3984L, + 0xf313389118eb5195L,0x0336aab8777a16d2L,0xa6661cc4c241720aL }, + { 0x678db970a7efacd0L,0x228968656461e382L,0x5d85a0e4a022c7a4L, + 0xb01f1e0434a02a6bL,0x2657eedda5791ce3L,0x239dcab2a277ac5bL } }, + /* 2 << 7 */ + { { 0x9a7a5b426ae54da1L,0xcfcadaab7040b022L,0x7539438e3d9f0e61L, + 0x013c6719e328c2e2L,0x7f4a706ccccbf891L,0xa335ab82735a2d28L }, + { 0x46694ef03d984124L,0x0e0bdfabc166b337L,0x9d54ed8b423d47e4L, + 0x8075a8cbf44c9180L,0xd4f5b184abe9b384L,0x424dd00b41abdc75L } }, + /* 3 << 7 */ + { { 0x99a710b1400f1d87L,0xec3ca386ee47be8bL,0x3a00dcad37168feeL, + 0x1a69d6741765a0dfL,0x85233afe917c4909L,0xa3aa97a4e9bd6210L }, + { 0x01010526310885f3L,0x21c5de3fb5007b08L,0x5df0c6efee8ddabdL, + 0x5d17d45a0f6dfdefL,0xb73d831a251c9f79L,0x397779e6cb1df19dL } }, + /* 4 << 7 */ + { { 0x5e2cb07fd7801edfL,0xf9fa2c0b3adc065aL,0xa296c53fd4de1f25L, + 0xd408060c838f7169L,0x68e19d7b2e8a6ce7L,0x2cc6e06c94b58671L }, + { 0x93d02a07c1cb6151L,0xa10fb4cf35003126L,0x6aa069f51aa3bc4eL, + 0x0e44fbf0dd09b142L,0xe264f343832e5945L,0x5dca2adc1fc166acL } }, + /* 5 << 7 */ + { { 0x5f63e391d7afb4c6L,0x85208bcd2bcb4a76L,0x10022d53c3da8fd7L, + 0x607538c007e50047L,0xdbdb0e7212793242L,0x8e6b9f6135eb668fL }, + { 0xbe5632887e1da455L,0x5e73e1a06e544e82L,0x0c28a5d29a2da4deL, + 0x62b30a8822326300L,0x470764f16013086eL,0xcbe2c34cd3ef5fbbL } }, + /* 6 << 7 */ + { { 0x9ee4f522b0f6c604L,0x5b8a689d52736e58L,0x0d5f396db7edb07cL, + 0x09b3457c2e829063L,0xf1d28188f83495daL,0xba2511e6cce559b8L }, + { 0x17cbaf57d8f90669L,0x3ba19a1c514eacf0L,0x298208995145b8fdL, + 0x92cb5da81a33b1a7L,0xca49fe334c5149e9L,0x5c499b661772b4c0L } }, + /* 7 << 7 */ + { { 0xb98266b132508180L,0xf5008b926719d49dL,0x50c513f98069ffe6L, + 0x99ceb828a7c6f38eL,0x375b8a8225e2a436L,0xb8197f6c416c073dL }, + { 0x01663a25eadf09ddL,0xfa2ca1571d7ff230L,0xf3b65b2545284aa4L, + 0x144dbefe648bd565L,0x6095ed8ab4c24e35L,0xe1f1fa3696ff2020L } }, + /* 8 << 7 */ + { { 0x56ad7582a0eb176aL,0x085b5a366e19aa00L,0x85f2c6ffe2c8b036L, + 0x55c6d357fcd7336bL,0xb1ecc56d22a46acdL,0x8e0f976736277ac7L }, + { 0xa4ed11e901878921L,0xd38355667f4fb650L,0x5fdaba45266158aaL, + 0x6f0b27fd89e0dff0L,0x32ef7ae2eb6b02d0L,0x2f145871cc1b46e1L } }, + /* 9 << 7 */ + { { 0xc7698dfd4b449cfeL,0x78aacb7bd1517720L,0xaf0f6ef574cd5f32L, + 0x026f1826f17954e3L,0x33ef67ab2453185bL,0x82f0fcc90a420c0fL }, + { 0x5b444b3645f154b1L,0xb27c4ece70d17f90L,0x6417e0d039282194L, + 0xebfb5fa001aa4f4fL,0x9cc5d0b573932754L,0xe8b56699704ffd85L } }, + /* 10 << 7 */ + { { 0xc112733b9d4075dcL,0x349281c187737549L,0xbb7d8e0181009785L, + 0x7640a3e2bfe16c4fL,0x4e34813ec1d9f810L,0x61985fbc8d2605d7L }, + { 0x2a544cd8e3f66442L,0x48879af56a7c9e94L,0x9e6157bacec18a7eL, + 0xa555fc9511b882d6L,0x4305a4dd04f86563L,0xc58ed7631d0fd96eL } }, + /* 11 << 7 */ + { { 0xaaeec0f9b726e2edL,0x243ba6614493d146L,0xd799c3408980a9fbL, + 0x886e4f44ed060f57L,0x52126b82c1f83f6eL,0x8b4978441df301ceL }, + { 0xeb2a98abcdc4e434L,0x87dec119474e2c77L,0xcbbc613092eb1528L, + 0xb0b0bcf7c454f37eL,0x404d97a7e1a919d3L,0x26d1baa825e62c30L } }, + /* 12 << 7 */ + { { 0xf04145e82d2696b3L,0xaffb66acf4fb2928L,0x9ffcba4e12aa299fL, + 0xcc5ec24991b3b517L,0x9edcd4616f81c747L,0x0a96090a77a883ebL }, + { 0x9b0bab58a2aa4badL,0x76359a5e8f9b84e7L,0xfe8cd81e438a9d43L, + 0xf40e2b5e25ca8b3cL,0x4254030067bc720cL,0x883002a46b2446a3L } }, + /* 13 << 7 */ + { { 0x4b43bd3206c3aa7bL,0x83ca2db60a470b08L,0x07c1036c06f22f37L, + 0x312e04d7bbb46ed2L,0x6a1d70a40193e5f6L,0xc69720e8ba8a3f38L }, + { 0x2c003429468a04b1L,0x885c43bfbc83fe25L,0x65a65259393e00e8L, + 0x7154c7ac2af17741L,0x682224d331dda744L,0x6183dd8bc80b57f5L } }, + /* 14 << 7 */ + { { 0x80e1cd16c496089aL,0x7a59f4c06ec2000fL,0x67a019d509ddce06L, + 0x52573e3e70c4b032L,0x16d253e14d3ba57eL,0xa43c6d42162504f7L }, + { 0xa237bbf952ff95e4L,0x81187e659acb7273L,0x4b13531a1f384daeL, + 0x39067f3398125165L,0xe98fb141672dccc1L,0x594baca0a75e27b5L } }, + /* 15 << 7 */ + { { 0x85e12293c205465bL,0x57bbcfb1b71cbe44L,0x201ed45c1bc85881L, + 0xccbc39d5ccbe7dacL,0xc509b77f9277f310L,0x171b603aca1b70efL }, + { 0x9b99605504d2dbbeL,0x986d6323451c918dL,0x75ad922f63c6fb03L, + 0x69e2cca49630182fL,0x1389a2b7f7b34d1fL,0xa66a80323d4f7c7fL } }, + /* 16 << 7 */ + { { 0xe65245cef6e9f82cL,0x9e234dfff6da7b5aL,0x5677c121bad2c806L, + 0xc52dec32060fcf24L,0x78d070675d78cccaL,0x630002ea1bc8b6fbL }, + { 0xc5cb86beeb2e99aeL,0xf13981e78551d16fL,0xfbb7cdf2c92a70d7L, + 0x5a9ff1f1f53cd2a1L,0xfdbe6b7a984f1139L,0x4403d046a470a9f1L } }, + /* 17 << 7 */ + { { 0xdf8c9325efcc63faL,0xe0d35cd966563147L,0x140b9a8bc144d7b9L, + 0x492bfbd70c17c75fL,0x3cbc2b644c5c4d8bL,0xfecfaf47ff8a3328L }, + { 0xaf341aa179b8c3d5L,0x5e72713ff04f29e6L,0x652219fb9f5b6fb6L, + 0x9deeba3f0764460fL,0xb8c2bfa5fa069d0fL,0x5d3e6fefe57be3e2L } }, + /* 18 << 7 */ + { { 0x52c9b94decd84cacL,0x34c2d0ad446dc59bL,0x5563701d951878ceL, + 0x92e2fc1c843c9b1cL,0x2309a5f13dfc7a98L,0xdaf117dc0c57a156L }, + { 0x5739190d359fb843L,0xd433e9bb4b88e3a8L,0x4d6bb0e2c47a1f45L, + 0x511eaa33d7b59627L,0x42ef82c5e389e532L,0x641a0bdcd75f4c08L } }, + /* 19 << 7 */ + { { 0x3ae32dbdc7e30cc3L,0x0c970135af5d0ea3L,0x8fc38e50bd9a0528L, + 0xdb0506791bfa634aL,0xf3514fbd245cb0dcL,0x3a3c8c6982319ddeL }, + { 0x92136baf6426632fL,0xabc3e24aabdd5641L,0x8ccae1429cc004baL, + 0x6c9834d8b3ee0d66L,0xa807ab63e1f7e8d7L,0xb4598e2a220aea7cL } }, + /* 20 << 7 */ + { { 0x19821469d678d1a3L,0xf9fa42e60df2f58dL,0x1177daf49f284ba0L, + 0x6dd2ad3d2a201dafL,0x667b0e383d427075L,0x39b76d1d4212b65aL }, + { 0xc6720ae0bf3612fcL,0x72559d98775f8137L,0x466e8e4476c48a09L, + 0xa05f8eb07fb5428aL,0x7fa1fbce5e36b7d3L,0x13bab84f8d1fdcd1L } }, + /* 21 << 7 */ + { { 0xf1876140ed6f3524L,0x47171ee5cb94b2adL,0x56d836abcb8de844L, + 0x346e80890d3b4271L,0x0110df1fdabf6a02L,0x6850fba1f571cb92L }, + { 0x490cd9af6209f064L,0x41f32d5f1cf5636cL,0x558bb7ddc328f9dcL, + 0x44abd0b9d32e3e4dL,0x2c42a5607fc2ff0eL,0x8b1dc5e12c9931f5L } }, + /* 22 << 7 */ + { { 0x6a35f6efdca1ce69L,0x04216d3184de3658L,0x3c3010df732f31b1L, + 0xe4421a872c1444b8L,0x17c987a3c59c1ccbL,0xd67159dba297df1bL }, + { 0xd13aa7a0bc96041dL,0x686d7b77f44c3d8fL,0x6c2e505f09b2b933L, + 0x8c04eb8256161b34L,0x61785cb4b344bec6L,0x60b4d06cbf8b0b45L } }, + /* 23 << 7 */ + { { 0xe5b055481883c1bcL,0xd5bc37684597b8afL,0xa71ae49adb2fae11L, + 0xc1ac1b3e050327f0L,0xd990b2a668f3cb1aL,0x566e5175b74a3228L }, + { 0x348d382957909fe3L,0xe849dd8dd03c2374L,0x4f31a278150fb5b4L, + 0xbfe265cf168c0798L,0x2737c156ce6a34beL,0x4478d6ae4aa6b73fL } }, + /* 24 << 7 */ + { { 0xb5b16cd48d040c69L,0xfdaba315f95a2dc4L,0xc9fef34961ce4704L, + 0x5fe87a0ddbb53ed6L,0x3f0ccc7973d70f93L,0x4601d1bc46724a1aL }, + { 0x5c4a15ae24f08565L,0x5eda1e8aaa577320L,0xe31ebb35bb32d307L, + 0xcdc6f13bdc770a0eL,0xbe3ae514c434c2f8L,0x57c7fdf63a0ef0d1L } }, + /* 25 << 7 */ + { { 0x85165ea2d71c01a5L,0x3935171c99a29e59L,0x2aa1b5837d326190L, + 0xb1d702f8e79f3959L,0x94100c65c6ddffd0L,0xd1d56d626a9c54c6L }, + { 0x5c93b4cf7ce12b66L,0xfc28574bb32a90caL,0xcd654a96e755969cL, + 0xa06f436cd1bec664L,0x9b27c110ffb6f3e6L,0x529b77d317b476c4L } }, + /* 26 << 7 */ + { { 0x04c3d9e162ccecd4L,0x6050bc1221cb59a1L,0xb33847543cbb7e07L, + 0xef2201ac4cf1be50L,0x99c3dda42d2ac886L,0xad19cb0ab776eff3L }, + { 0xd326dd7f5a3d9036L,0x9fe56af2e5b27667L,0x3d849fc072cea4d1L, + 0x262a0cbcd6aa9e3cL,0x8286211885401b09L,0x8ec71d4b98fe8047L } }, + /* 27 << 7 */ + { { 0x9b769cc43c6b2de7L,0x433d4c26acb13b6dL,0x52878f517530ef4fL, + 0xd0e7ce94b0c5354aL,0x5b094d461d92dbc1L,0x75f681449e4ffb31L }, + { 0xb9b9e97351b9d1e1L,0xc147ba4698661569L,0x2a06f4cb7a239309L, + 0xd5cb5ad420928958L,0xbde0283bd5bdf5c6L,0xb91664a082e43c18L } }, + /* 28 << 7 */ + { { 0x8fc0cfa6e51d078aL,0x431d9dd5744ca779L,0x37a4f3120e96e887L, + 0x9c3624fa03ea5144L,0x47d5ecda0b1127f4L,0x018ad424807cf96dL }, + { 0x58ba530f586b16b9L,0xec7271ed72f47883L,0x8d2918da0281ac88L, + 0x6d0f14ef002330c9L,0x1a90a01591dc35caL,0xeb8e71e9c81607dcL } }, + /* 29 << 7 */ + { { 0x2eab9c5ee6d01fd3L,0xe030e6d23fa77f57L,0xff41311877edc0e9L, + 0x7817766bb47ca351L,0x70c987e36cb15abaL,0xc3c867ace19c5aa4L }, + { 0xc24ec23ea05c3810L,0x3965a165c4f0f350L,0x52af99cf7c0d8e5bL, + 0x2d95d23c106e0b12L,0x27507b297f6d44d3L,0x33da846858b191f9L } }, + /* 30 << 7 */ + { { 0x8e5785629aa664e0L,0xf3a1cfc329a97c9bL,0x91ce3b404037bd09L, + 0x34c447b07f9f2482L,0xebe360164010c2a6L,0x7b8b9b3afdc0a861L }, + { 0x0e60c49199c4ff9fL,0xf1cf53b1053e703bL,0xabeae550dd974a16L, + 0x28ac5a34994ea50eL,0x9384617d27329793L,0xd04db83ddad0aec7L } }, + /* 31 << 7 */ + { { 0xcb0ec2bd4b1537bcL,0xd0de683cbac6569bL,0x0688dbee5c96afb7L, + 0x7c7d192f3324ab6fL,0x1455b1e6165fe655L,0x32d135a1ccfe9e1cL }, + { 0x05a80a2af9e1a86fL,0xdc946c70479c71f1L,0xf8b9ad985aaa0ff3L, + 0x78cf198ef195bbceL,0xadbc082dfcee6b59L,0xe6e1fa844cd19e25L } }, + /* 32 << 7 */ + { { 0xeb06571c0f547ebaL,0xf292c38d6246c0dcL,0xa185966726eed224L, + 0x8d9e56e46100e387L,0x470506b9dc6298d1L,0xb19e084cf3350ad0L }, + { 0x83eb62a812abd898L,0x70f152cc2222342cL,0xb089e880e1bd4a82L, + 0xd4d1e70fcaf3b3fcL,0xd0b1ec6395ffd65cL,0x79f27f3a9b184ebbL } }, + /* 33 << 7 */ + { { 0xb4a7435231a3e816L,0xba8a0af2fd4ada3aL,0x1622289dd8fed2e4L, + 0xb71e579e31d3745cL,0xb090650704a50576L,0xc98b5f20123f900fL }, + { 0x3799ee82d3587b21L,0xafdd6dc79d9abe55L,0x4053ee2aba64b9d7L, + 0xa816246657b3f258L,0xd9b5c4c4690b1169L,0x32c1d3afd091d158L } }, + /* 34 << 7 */ + { { 0xff5a9c58de97d0d7L,0xec086138feede4acL,0x55b14035ebf47cecL, + 0xc0b3e061c619fe18L,0x5644c092ead4ebe9L,0xa1a4f7a41e5e0a61L }, + { 0x8698da06d179219cL,0x86f560bc3f88f732L,0x6ad10b3f1e34a23dL, + 0xd4326bb71307ede6L,0xc93cd2a19b3045adL,0x5a0b733dd8a5160aL } }, + /* 35 << 7 */ + { { 0x68ef87cdeaedf10dL,0x5ce97a07bed10cb6L,0x9b8dbd896ed762c1L, + 0x1a72b05333c1dcd8L,0x6718eff90f97cfa6L,0x02f886e57dda698bL }, + { 0x9db378a8c724f4c7L,0x5b55b8383fa6548aL,0x9935a70ecb24bdf9L, + 0xf5da6936e9de8ae0L,0x3b3a10a79b0c4bcfL,0xe4e6a6e86361c492L } }, + /* 36 << 7 */ + { { 0xb37fc581c634a8f8L,0x06f06c93de1d01acL,0x0f2dac8452fed4ccL, + 0x1673c81bda53f81fL,0x963e500e61e11c94L,0xe86ff87e2144d55fL }, + { 0x343ddf389bbaec76L,0x16a13527806df1edL,0x1361b5ac0a9edd65L, + 0xf20507fe33c0124fL,0xdf64ec1e4e8e0d18L,0x3f6a42e27860a8f2L } }, + /* 37 << 7 */ + { { 0xe6db1c43d38266a7L,0x55bee1a3adec0d4dL,0xe41c403ed56d2f9dL, + 0x5fb703f24d3cd93cL,0x4d7ae8c53d2a7ccaL,0x65c8ac50ffa5fff2L }, + { 0x128814ec264dfa80L,0x08d1372ea642513fL,0xfc5ea1615343a57bL, + 0xc70a6f2f9a2f3f3cL,0xfe61c499df4963f1L,0x2b711eee5cea1508L } }, + /* 38 << 7 */ + { { 0xfc3e9fb252f9a4f3L,0x8bbeeff32180cd36L,0x274312dbd6438c99L, + 0xbd30984a55612a57L,0x344006d609381db3L,0xd9b696f62bcac509L }, + { 0x481e4ea3bef646d0L,0x213033d430561b68L,0xf46bf9a05453f623L, + 0x2af3c4a46d848d97L,0xc35e55a543efa02eL,0x8da254342462874dL } }, + /* 39 << 7 */ + { { 0x1f7fda656a12b927L,0xf628cfac876b9303L,0x1904a0b5d0d0d0b2L, + 0x46d486f6f2894b1dL,0xd35cb5610d243bfeL,0xe759579b851a568eL }, + { 0xb99572e2c1aeda5cL,0x872e16fb1c54cd1eL,0xf5ec9e42a60fdc40L, + 0x59b03a6201a4b019L,0x9c5e7f87e272e064L,0x6240282f24c918a2L } }, + /* 40 << 7 */ + { { 0xc2467f9ab92a9a13L,0x0c3ee8eb6add349aL,0x59250eda45e99644L, + 0x22ce0635c8a2df27L,0xec7b643e312e8698L,0x334ccf2eaebd1587L }, + { 0x0c1c68736bca2900L,0x00beb4c209826cb1L,0x12dbb586cde6b725L, + 0x8d7cee6c66dfed41L,0xc38deba2014de4c8L,0xa3ba6ec76248442dL } }, + /* 41 << 7 */ + { { 0x870be3ebef38abf3L,0x6e0cf541f74dc605L,0x499976bcda4bc168L, + 0x5513c6122548b3b8L,0x5b9a054c3f647360L,0xa47f9f8bde929154L }, + { 0xa2ae9ccbb8ec35b4L,0x934c5c0a4d9857e3L,0xc9dd66cc4b4f01ffL, + 0x42a1afa2e5b5e147L,0xc284e464f3d9b380L,0x67845404e21bbe63L } }, + /* 42 << 7 */ + { { 0x9ec1ed3342ec772dL,0xa77e1ecf5501609bL,0xb059e214a02906f8L, + 0x35b2ebceb28e4d14L,0xb8453ec22cf036eaL,0xe621234b2518fe75L }, + { 0x079d7d11f03cd158L,0x357492f91b2f011aL,0x3c2186da0661992aL, + 0x7adc1c0fe5df978aL,0x88d329db5300cdccL,0xd915c2444c0d644dL } }, + /* 43 << 7 */ + { { 0x1b9797a8f0ff03f6L,0x00dafe43f41c9284L,0x1e565c33f2bdc817L, + 0x63b77ad9784b1a5dL,0x3304540e74aa6079L,0x630524f3d7181d2bL }, + { 0xb4fe5fcca2804658L,0x1e48e50b9e393a6eL,0xb5bccd49397a94a5L, + 0x95394743eef17accL,0x4d67ba5226dd1687L,0x80965c3432349d9fL } }, + /* 44 << 7 */ + { { 0x1d70669e49f1216eL,0x8645472fa5fca474L,0x9242e8ddfc400357L, + 0xe7ac31548623996fL,0x37b9e68ce61aecb5L,0x7d2e10fdb997e4c9L }, + { 0xc0cb59a6c2086dc9L,0xb38e2032d7952172L,0x78eaecf6eebac939L, + 0xece490b42f5dbaaeL,0xdb17501dcdc32565L,0x59bd392ab133bf99L } }, + /* 45 << 7 */ + { { 0x71554fae07de21a7L,0x3dd66b8bcc42db25L,0x9da85c0f0636e9a4L, + 0x61fef273904930d8L,0xcc8f527b73369e81L,0x4207dfab7caeacd8L }, + { 0x99e5d1404fc763d7L,0x5cc6a3739f4e8947L,0x9ef14ec1cde33eaeL, + 0x25eb3aa8095872d2L,0x0db8268d7d9e6dd9L,0x38846510c2ccfe92L } }, + /* 46 << 7 */ + { { 0xce6197e822d0a502L,0x69df7f8e09d45970L,0x0274f48b7eb4718dL, + 0x47461334a8c22b75L,0x89cebf17bf25b9abL,0x57c042f6fdfea412L }, + { 0xb19c338644346b96L,0xdba17de06ba014c4L,0x6697687a5f844d69L, + 0xf16dee4c1a66c6faL,0x7f916e47fdafd0d7L,0x1c3842d2340f158cL } }, + /* 47 << 7 */ + { { 0x417c9ab760efab2aL,0x1745d5c2f0065f75L,0x1a7d86f2ed71b350L, + 0x6d4d504feee5c850L,0x4ae7ee0da657b859L,0x1f72ded53c302a3fL }, + { 0x08779fdae7b22e51L,0xb04c1c0446d90bfdL,0x4dc97219712f96d0L, + 0xb15e8c0041a6be82L,0x384a02cca3804090L,0xcea45861babd1ee5L } }, + /* 48 << 7 */ + { { 0x3c686079d42aeb95L,0xc162e5e985e3ea0fL,0x34cf58611bbb2455L, + 0x7650de1d8773b064L,0x3b7562c6d2bab35dL,0x83191b4433d0741bL }, + { 0x4b604db03a6bd9cfL,0x87cd84db074aed21L,0x02a042d2d4f91f9cL, + 0x5a5d52e5e42c2a67L,0x31291acd1d5f216aL,0x9c3971bccd6203c8L } }, + /* 49 << 7 */ + { { 0xec931d6599e9ec3fL,0xe9d780c64bd554d9L,0xa580534502eca45cL, + 0x84701f1ac1276ca3L,0xcb7ba786d5f9438bL,0xf3a27508c85f663aL }, + { 0x044df512118c9421L,0x1109fd431039871bL,0x7865443de2378386L, + 0x7a5e2d49e70297abL,0x112763ca6824d2b3L,0x8a05f2c90e84bba5L } }, + /* 50 << 7 */ + { { 0xde3bfdebff044924L,0xd7f2a5181a0458f9L,0xc03df0c00139d557L, + 0x7a958c60cd3ad0d4L,0xec9f2f9759a43584L,0x5e0fbba950d8b4b6L }, + { 0x5fbc5e3888245837L,0x17235805a267a54aL,0xdc24a508db55d65bL, + 0x431e4d5623c704d1L,0xb1f85b2277585f9cL,0xb288f25ed0b1c374L } }, + /* 51 << 7 */ + { { 0xd8fd5b405a37c029L,0x5c9d827fe4d37effL,0xe024d7952e046275L, + 0x0661277f913c55c6L,0x21ee10eb904b3679L,0x32c582e066778adfL }, + { 0xc353ab1fba8d17daL,0x1d4ab06b5658ea17L,0xb908cb88a2d70bb4L, + 0xfc215909a98daaebL,0x7aea6c8777000e24L,0x19e0acbe38446e20L } }, + /* 52 << 7 */ + { { 0x1bc3803e2f98532bL,0x39d0c3258754d142L,0xa7b035c5d739eaefL, + 0xd36ddeb8fbfdea2dL,0x7df72a94bdf64f2aL,0xab4ad6b880bc3c47L }, + { 0xdf386df3877fa482L,0x4b94260470519bc3L,0xa3399d91d20e1e04L, + 0x7f5208b797cf58ccL,0x528f6a2814424c00L,0x83d74730bd900d10L } }, + /* 53 << 7 */ + { { 0x501c657f34ded7f1L,0x9071027e12fa53bbL,0x395e16aedff079ccL, + 0xea95dc84770ac4b2L,0x4d2aa60a41355974L,0xe04effa507f12473L }, + { 0x38ca98385cd1c738L,0x3c067a0b683c0dbaL,0x55ad2dec67589842L, + 0xe51550f7dfdae3c8L,0x21a56717214d51aeL,0x75b6a4a012a0fdcdL } }, + /* 54 << 7 */ + { { 0xd63605266a4ea95bL,0x180f72d403e67090L,0x7faf4529751c8c9fL, + 0x1ab7b50d00e4252aL,0xc0e69adf34811274L,0x5c4c83495e99c6ccL }, + { 0xcc9467f29a9e02a9L,0x5402c2da5c4fc719L,0x1dff8c5d3f6d5bddL, + 0x88a7d27a2c653c3cL,0x067f31183a050dc7L,0xca0f7dafc4f0236eL } }, + /* 55 << 7 */ + { { 0xa09306e9ca177c3bL,0xea84f03ed0552a4dL,0x7ae9024f3c00d359L, + 0xe189ebc33aa619faL,0x4adeefac8354579bL,0x90168ef9699db1ebL }, + { 0x75319141ad87490aL,0x7b48fe7629c1bf84L,0x00ae82c7a2235f2aL, + 0x6292c9cf68562b59L,0x0b6500943935ca20L,0x39f22cb027f33addL } }, + /* 56 << 7 */ + { { 0x92e4c851aa1ef488L,0x4f91fc22846528a9L,0xaa2f5d2d5dc13a84L, + 0xba06aa68f1072d4dL,0xf4f3b17c5e3a2ba9L,0xff36a5355e4dde77L }, + { 0xe8ef143aae17dddcL,0xcc82631ba1fcd4ecL,0x97db807ec7d3963bL, + 0xe4aff04521d85ce2L,0x2d6480e674667392L,0xc8ce97f3a55d0b3fL } }, + /* 57 << 7 */ + { { 0x1a32b8457962a675L,0xd78efd71723d217dL,0x9b03d6573b41a2c5L, + 0x1116f33589a380b1L,0x2c0359af931ee15bL,0x8a53744f239ba4c4L }, + { 0x4801397dc78cdc83L,0xc43b9f0434ae4453L,0x9cc8f6cec356a35bL, + 0xd5a74c2a648b39e6L,0xa54d668c0d5e78fbL,0x36257047cfcb8f6aL } }, + /* 58 << 7 */ + { { 0xabeef3461549c215L,0xfec59db2ce4aee45L,0xa1743a0f5305df83L, + 0x9d598abdf211bacfL,0xd14609dd52a513fdL,0xd3dc446be00d4ad0L }, + { 0xbd8883e9b272211aL,0xe991e57757879fd6L,0x5a093d372b732171L, + 0xdd901071f55f18dbL,0x87f04c0034fecfd1L,0x2c07df27c94f6a5bL } }, + /* 59 << 7 */ + { { 0x518e3ced1c17df0cL,0xf8971149ff5dbc4eL,0x5fec8bfe0ac9d27cL, + 0x41d68852489eed7dL,0xf48ef4bf3c3c4725L,0x3b8d9eee7681eceaL }, + { 0x7743ededdaae4bdcL,0xb9665ef5d1bcf697L,0x9d77f535471bb958L, + 0xb5db5b96d752b2ddL,0x2cd3c919c368982dL,0xf8297660e9cff6d7L } }, + /* 60 << 7 */ + { { 0x39e7da1028946a2eL,0x4e628a96c3a76f7cL,0x43b8b808e9f6000aL, + 0x86cbd25ca48bbb79L,0x5ce825e273092951L,0x43a6031df0cbee32L }, + { 0x6d685a594923485dL,0x8d4483ed81a17f47L,0xf61d329bbc379719L, + 0x9deef7d0f6596ee8L,0x0314a572541b1222L,0xe2b34d387ea7d376L } }, + /* 61 << 7 */ + { { 0x05ff6faa31f43d37L,0xfb83f23211b801f6L,0x238792d519b223a4L, + 0x28edadcce004f601L,0xf77747b3bdeb7597L,0x2178dbe21e6575d4L }, + { 0xd48ec49842870ba2L,0x7733661d15dca6dfL,0x08212e2f83393416L, + 0xffa1bfe2614c545cL,0xfaf4ab8494254145L,0xd8f9eb48000d250cL } }, + /* 62 << 7 */ + { { 0x9ff4f289a66132a2L,0xc54fb8001e098994L,0x09d3cd6624cc2471L, + 0x6d0f74167838e14bL,0x7438cd2dc540cbdaL,0x193b16817d6fa8b4L }, + { 0x487a7dedab33c6f3L,0x625eb8cf02f5aa09L,0xd8039682501323bdL, + 0x9de122e38e216951L,0x40a8fbde0711c51aL,0xf192b5c283a474c3L } }, + /* 63 << 7 */ + { { 0x3782cbda57e04e9cL,0xec639886e41b30dfL,0x4cd14afd12d2f686L, + 0x0aa093ee8b768113L,0x6cfc12cdad598f9dL,0xe4a62f1194bcce0fL }, + { 0xd5035fab150ad4f2L,0xb3cd4871ae2e8da4L,0x49c9e78271ad9c3dL, + 0xdcafeb34825690cdL,0xc05fb7a38c246f85L,0xefe16be3a82cc013L } }, + /* 64 << 7 */ + { { 0xd42777314c14ee0eL,0xda8146d15e881c3fL,0x6b0746b099f1867cL, + 0x1ec73d72602dd4ccL,0x27fae51538081120L,0x6a677bdc2f8b2f2dL }, + { 0xb924af64d60544e9L,0x1439e183dcfc6b16L,0x4e88e9ae068565acL, + 0x8a3dbd25a9a4f146L,0xdb4a3e483f93f734L,0xb1971c058f1d33bcL } }, + /* 0 << 14 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 14 */ + { { 0x721bb8363a7f43c3L,0xab5b3108c12dca0fL,0x9cc9a78934853870L, + 0x78b604a7af598c4fL,0xd370375e476f27c8L,0x9f0415b80b15cba5L }, + { 0x2bcfd9a4d400dc1fL,0x2a6fe03b4bc62dddL,0xb05a6464a211b19fL, + 0xce059d419990b504L,0x011c5f87d94951d3L,0x13cec08900d9c7b0L } }, + /* 2 << 14 */ + { { 0xf365419f9b280fd9L,0x13e3b12746365672L,0x8a91c165c41880aaL, + 0x3eb27a97f9712fbdL,0xa6587aec76c55678L,0x7c3a04b702cd79cfL }, + { 0xfc878f9cda712eb8L,0x076e61170fca3e02L,0x09a184d8caf6df5eL, + 0xd32bf232aabcde75L,0xf601d0de03de597aL,0x85d2b5fcc5da2858L } }, + /* 3 << 14 */ + { { 0x3075a7636c888df8L,0x6305c20472e21527L,0x6b1d683e8798aad9L, + 0x0d09624680706369L,0x91db5e7f7b854739L,0x0e63cc6e02d72332L }, + { 0xe929e3ea1f7ff6ccL,0xd53a18a145595925L,0x867916cb93af8be1L, + 0x757e9f56c5c305eeL,0x3f9071c75c83063cL,0xccc0f92d7f6d5bb7L } }, + /* 4 << 14 */ + { { 0xb6029961ae899afaL,0x8eedd66e681b6e1bL,0x82db693b4df3e5b1L, + 0xb5131488a0c3e357L,0xbfb01ff3ccb2f577L,0x28ea947027a72cc3L }, + { 0x26170928e39e325eL,0x42d4876b84f80188L,0x0bec6a634c872d76L, + 0xa0a7cc90b14d9c9fL,0x8a32d2c44f6c7778L,0xe7cd346e3b889a4cL } }, + /* 5 << 14 */ + { { 0xab35a14f5a4a3753L,0x1d0d5a142bbbd563L,0x54cfffc5998d4514L, + 0x1c02f381a77ed59bL,0xe4a7a6ab21c9c190L,0x50059df54a9adb60L }, + { 0x2d0383ba34bd7008L,0x894889bedf1a4f41L,0xe541c62612ac407dL, + 0xcc0e417964c3b62bL,0xdb8ca1f33a0978b2L,0x4ef45a2d287e8c6cL } }, + /* 6 << 14 */ + { { 0xea95b5c9437f2efbL,0x67d3e9b58e52ce8eL,0xfb33102488ff5455L, + 0x883ec9fcc3101dedL,0x056218e20ca5f1f9L,0x4c9b2483bccc65d8L }, + { 0x13199b26123db2ecL,0xbc1d82479aff90dbL,0xc4a9311d367516f6L, + 0x3b40c867cb6e90d6L,0xff674ff84034415cL,0x2787db45a1821e7eL } }, + /* 7 << 14 */ + { { 0xacc263fcadeb8508L,0xb52ebcd719854c90L,0x3d54e7805f2ce0aaL, + 0x2fc056a97e02e760L,0x47e7173e32da5f93L,0x1d468de3fa893134L }, + { 0x9adc877dd73396b5L,0x430826afeeb00c82L,0xfde2c3da96a673caL, + 0x467575ad33e43f9cL,0xc3b2c3a1ec1df2f0L,0xf0348e6f2252a8a6L } }, + /* 8 << 14 */ + { { 0x860ef794609683acL,0xf0631ad39af1c522L,0x322c83662ee7f522L, + 0x58ccd95f54122af0L,0x7454880c2bbb2d80L,0xea173d8286d8d577L }, + { 0xd5a3057cea1cc801L,0xfd08d482bbb2a189L,0x26aac99ec3c512f8L, + 0xc3eac036556d891eL,0x866c3aa7bf9f6112L,0x7c4c8fb9c144f7e9L } }, + /* 9 << 14 */ + { { 0x989eef73a9109d83L,0xbe43bd378edd17dfL,0x14a63abd1b17029bL, + 0xfd14ae365ff76860L,0x689dd0a6b8730632L,0x01eb37f147342f9aL }, + { 0x619bab45e6c446a3L,0x93d26fc97abddba4L,0xda6c120486ffa4cdL, + 0xc608937548758279L,0xaf074ea3034a7230L,0xf220244b82ce176dL } }, + /* 10 << 14 */ + { { 0xc0c1eb0f8343f5ddL,0xa205e66a0126fa2dL,0x37530a3244fd8be4L, + 0x3c7af6f696ab64cfL,0x1f04305076657202L,0x2c59d31c828f3fb1L }, + { 0xa61cba51e7f5926eL,0xb2de427391ebeb81L,0x976f2c34bb855476L, + 0x0c6c02c3269e4f86L,0xc69bed8fe2e01fffL,0x19aa421c480bf7b4L } }, + /* 11 << 14 */ + { { 0xb32e8e229affa929L,0x69ebb533bb7db327L,0x10ac3360a8a8d088L, + 0x066cffa7c485517fL,0x2393e74c12b8eebaL,0xb3a8825a596c8412L }, + { 0xe2b99fc3bc8b6b92L,0xd7716da085ca802dL,0x92f6693f4de5101fL, + 0xe8b0442304be34eaL,0x05b44ef648324966L,0xa89d9499413df57fL } }, + /* 12 << 14 */ + { { 0xad0d24c7b617206bL,0xb8be483f9dd13f59L,0xa55134ff7655aa29L, + 0xa3d103857a5e217eL,0xfbb9eeb53a21b295L,0x1de71555c84a136dL }, + { 0x7579398e0b7487b3L,0xc6ca9575a14dce87L,0x99b32e1e46452257L, + 0x99d54955479d8f2cL,0xc2a8a6a1930b80efL,0x58d9db81656c850bL } }, + /* 13 << 14 */ + { { 0x0c8fe2e04d89b43aL,0xe4d923e77a04e492L,0x49ecb701617df01cL, + 0x6d80f249bff9a819L,0xf01e604acb7f86c1L,0xd6d3a6664b7f1455L }, + { 0x657801c19188fb17L,0x339d79450dc92875L,0xca798cf57ec0b757L, + 0xc0808852a62301c2L,0x2dda13558266c908L,0x22bcde8f5e55da21L } }, + /* 14 << 14 */ + { { 0x6c85a0eda682508cL,0x8350b515edcce6c8L,0xa84a67656f95898dL, + 0x55b0ae971e419847L,0x11115c6edd6a885dL,0x6f0beaf64fb174a4L }, + { 0xaaae44b2815af3afL,0xcf0697b9927a2c1cL,0x37639d62d7d645eeL, + 0x157b7eda2effec37L,0xb55e50759b9c66e6L,0x33a66a1f85f597ecL } }, + /* 15 << 14 */ + { { 0x8260c5339b49bb46L,0x3f3df9d6437cac27L,0xd0723229d972d2a8L, + 0xe544a216d0dd92abL,0xeea4a0f5a03588f6L,0x54006166b218dec0L }, + { 0x0fae2be85778113bL,0xbb9618d68d570227L,0x3ba87360297a47aaL, + 0x9483a8399a76dd6eL,0xa803edaf6eb061b7L,0x6790050cf8067cf4L } }, + /* 16 << 14 */ + { { 0x171898aa8f7782b6L,0x8b7a706b499b3a81L,0xbc0e835ffdb2c1baL, + 0x4ee30281591f5aafL,0xfd71de3bcc272c6aL,0x532800c46e93f68aL }, + { 0x35ee08048365c576L,0x6c2bcc94cd4c0221L,0x49f37ff5957b2ff6L, + 0x315d8e7e5ec029c0L,0x33230602ef324c12L,0xf5847f9b966b2578L } }, + /* 17 << 14 */ + { { 0xed88aa550bf098d0L,0xbc9888fd75f90180L,0x9040919207713428L, + 0x38922bbc1a1f71ddL,0xa430fb65bfbf0f55L,0xa258b9ba867c1998L }, + { 0xa7f69b03b7294c58L,0x2ec0c5de84dbc1e5L,0x41c9e5207dba8d62L, + 0x545573f1795d8285L,0x1c24a375d3075041L,0x687e1cc8fb6b88dcL } }, + /* 18 << 14 */ + { { 0xc29b123e1453b1e1L,0xefb0778820059b44L,0x15554ade9291671eL, + 0xeb5a1980429dea37L,0xf96dacbb6c4b867dL,0x4f5563d6abab4d68L }, + { 0xb5b0ecffcbe76297L,0x5a22996a51d6bd43L,0x0088ec95b7e5cfc6L, + 0x4863a5a1fe373e05L,0x42b7925bc244d93dL,0x85bad13540117113L } }, + /* 19 << 14 */ + { { 0x01725fbe8201fae2L,0xee4d7d382dc34bbbL,0xaddf878afd7c35bdL, + 0x56522d5865536719L,0x595c3dd8f772d4cfL,0xd87c5b6045af30b9L }, + { 0x9cc20b9de7992d5dL,0xdfd53d58d56f1964L,0xaf2947bdc7d42a68L, + 0x9322b73dd19e8ad3L,0xa73a9e843243a6d7L,0x9c7dc57992c203d3L } }, + /* 20 << 14 */ + { { 0x86283e21f9daa551L,0x47fd23f81f696f1bL,0x7d029b1bb9784a9aL, + 0x7c7798bea0c0acb5L,0x41241c716d7c682bL,0x11c6c1131d33c2b0L }, + { 0x5d469ca23565cf32L,0xa949f022bad4bdbfL,0x3d054cc2a13cf4cdL, + 0x13bd21669e3ce279L,0x01bc70e68a4beafcL,0xb39e351d8aba087eL } }, + /* 21 << 14 */ + { { 0x92efa2ebfa6cb068L,0x934209b29235050bL,0xc446ee28d5000c05L, + 0xd4e51912862fb7ecL,0xa53940f111193db0L,0x5f2ef2aa82a7fc57L }, + { 0x1a6b30ecb0210f49L,0x4ab1dac73899548aL,0xb116cc3186737a03L, + 0x56cb33809ebfa5b6L,0x8ac3b61fdfd918b2L,0x65867e3ca102e1feL } }, + /* 22 << 14 */ + { { 0x26072a5d82357232L,0x3762764e9f0fd2f1L,0x9c5813f60c16733eL, + 0xea2e0e03718951d4L,0xae195bd469e63818L,0x241a4afcfa2f9a6eL }, + { 0x0e97519f9165d59aL,0x416bd37358e5af1bL,0xc4e811288197b7ecL, + 0x4145be2c9c6ba0d0L,0xc82cb2a17d40b98aL,0xc3c28487bccfa8b8L } }, + /* 23 << 14 */ + { { 0x920949a810476d2fL,0x5b387bbe2502c026L,0xd1d61a9acd7f026bL, + 0x81003d7ceea9a3f8L,0x6191c15fba5b78aaL,0xacbed41e30ad7befL }, + { 0x1427f1fd6740f72cL,0xb4b5e7c93c475735L,0x6a374d1773029d5dL, + 0xc1e4bfdacd622400L,0x670b9e36c2686dccL,0x1bb236e08dd4085dL } }, + /* 24 << 14 */ + { { 0x84aa863ea4ee10a1L,0x24d805a687919ccdL,0x553f3206b5c399b2L, + 0x775b92173cc109bdL,0x25c01263fe384088L,0xa3c4418bd5f743cfL }, + { 0x3d69705ddf91f1f0L,0x547d46269ebddad1L,0x0198ab1a2626cebdL, + 0xaf8320f285b1afe8L,0xb9c0968ce17e6efdL,0xfedc75c290215bb6L } }, + /* 25 << 14 */ + { { 0x1d375f7dcee34c76L,0x2295f8dbaa486096L,0xd18577928285cb84L, + 0x53fe6bd5e8c46c3bL,0x6f6cb6c068ba071dL,0x654ab4e8964e0f1bL }, + { 0xc70857a9edf6aa40L,0xc313c7852fd26360L,0xd705a86a995998d9L, + 0x413d35efd6989c8dL,0xddc0b2070df131bbL,0x21f64be59c7d70f8L } }, + /* 26 << 14 */ + { { 0x8061d340143ff74dL,0x59e94fc6a23aa7b3L,0xf7c79a0b914c3b81L, + 0x5a836211702c6ae7L,0x2570d63c718123c3L,0x7e86d11ec9f5ce3cL }, + { 0x80f03f9717bcce3bL,0x073975b1465a7446L,0x29f66de7cb357aceL, + 0xe87bd12c04894fb0L,0xfc501a2651a0b5aeL,0x20a3170c02207a3bL } }, + /* 27 << 14 */ + { { 0xaab1f0fa2785a18eL,0xa50192fdb37c657aL,0xe7073b27f0c8a908L, + 0xf3e0451b2c82fce1L,0x8237e128c290240fL,0xc1c631621bbf66cdL }, + { 0x9bbcc2afb6639b7cL,0x07643d299bf0e0c6L,0xf7f070c7671c5be5L, + 0xb09a423a9870ac6aL,0x324503506656cda2L,0x4f404be80584abc2L } }, + /* 28 << 14 */ + { { 0x3ee52d8f5fe63bd4L,0x09f8405c7a7da77cL,0x35ce95c61881a757L, + 0x0a8cf9d9c13e3707L,0xe71258d548d2d3f6L,0xcf4fd6910bbe7c0dL }, + { 0xbd6496e1fb9479f1L,0x711c669aab8cb3a2L,0xcbe8501358cfdfb4L, + 0x655c902b59275b4aL,0x7e0ff05b20f722baL,0xcb00031d42b17aadL } }, + /* 29 << 14 */ + { { 0xc568cee0cef0ae1dL,0x1b3422ca7a55aae0L,0x8dcce5058bb536b8L, + 0x12df74bee92759c9L,0x029abaf02ef962c4L,0x5d30b4359bb1240fL }, + { 0xc62fe8e7d03a850eL,0x67da35b5b08dcab6L,0x6f4d4e75e8ca1131L, + 0x53d6fbf81bd5bf97L,0x596d850ceaa0b2c6L,0x32e918240e8d39b5L } }, + /* 30 << 14 */ + { { 0x3360ff11d54bf1a4L,0xbab994cb5c79494bL,0x953ad553757d7771L, + 0xf17f14f068b58ed5L,0x223615317523c422L,0xf0f05f965ebf0d49L }, + { 0x3386676549182267L,0xf87eccc1ad71c3ebL,0xd7708e18913d8dcaL, + 0x27fe27e1b193eef9L,0x33376365cc45e65dL,0x599b4778d700ac20L } }, + /* 31 << 14 */ + { { 0xb118f73509ebb3c5L,0x7299c7844d0d36efL,0x409ef9cde10b249fL, + 0x040f91d0156401b9L,0x6b9fa5b107467a49L,0x2ede334334415300L }, + { 0x0b3abc9c0edc8055L,0x58f850958ca04aa2L,0xeb0d3202e568b6a6L, + 0x5e57bb1a159dce4cL,0x8d3780e03b68641eL,0x78eb21a0d9f50517L } }, + /* 32 << 14 */ + { { 0xda643272ed068028L,0x86b52135a91fb87fL,0x23865a7c35b43943L, + 0x6ac015884606bbf2L,0x9660ab721559fb9aL,0x1fcb09e73ce2f1a5L }, + { 0x62af29ab793d2f0cL,0xad5aaef53aee7efcL,0xee9f29b744c11037L, + 0xb2a19cf1d36c2571L,0xb87d88e265b552b7L,0xd8b4f172beb253d4L } }, + /* 33 << 14 */ + { { 0x6776241470c50124L,0x157c591f57d0eb9bL,0x99e1e2d769b4bcc2L, + 0x81c2b923a9d94ed3L,0xbdd9294fecbf3becL,0x3825c29a4c4fb135L }, + { 0x431d9f26e915cc2eL,0xc4fb48afec1a4835L,0x97f426c09ada831dL, + 0x0be0cf81d5c48eddL,0x166ee4243d02771fL,0x810bb518b09de508L } }, + /* 34 << 14 */ + { { 0x9f4dd8185038ba67L,0x5ff1572801111ed1L,0x900d44f163de4d57L, + 0xa36c1a67d5db5e67L,0x2f01142e2bf5cea7L,0x1519ae1f59aefbf4L }, + { 0x7b963d1f6d989fcaL,0xa5bb3cb85fce44e1L,0x61087c9672fd3285L, + 0xfb2fc6c1c597ef26L,0x5548e25c81e70a6aL,0xa6c53d67a229d7bbL } }, + /* 35 << 14 */ + { { 0x9d11a26ab9678e36L,0x8142106fbe07b082L,0x3c31548b322fda75L, + 0xa87215ceb7299565L,0xb5229b119ea80113L,0x7221a40f43ae700eL }, + { 0x1ad48de8cc00aef7L,0xc4573660d266daa8L,0x1cb020a65761657bL, + 0x9e799be24588c895L,0x3d209df968561484L,0xa0fb323295fec6d8L } }, + /* 36 << 14 */ + { { 0x9292138a3acde05fL,0x7b23f51a50f9e7f0L,0x6ad891a1af59b585L, + 0xbd394db79654da39L,0xcb8c47315f7c6edbL,0x367bbb5d6d2d6e5aL }, + { 0x8df2c759f51dd55eL,0xce0924d8e6c3517dL,0x49c46188097a8072L, + 0x47169f40980170a7L,0x56198937b96df7ebL,0x09572534531fb3b6L } }, + /* 37 << 14 */ + { { 0x04c18873d2eef240L,0x5752cce75106879cL,0x4b7fbe6bd9736e37L, + 0x7c7f1de4c85990afL,0x0cda6f07a2324ca7L,0x0894eafa4d80c28eL }, + { 0x24bd95890ae7e6d9L,0x050d526aaba494a3L,0x4b05455ee583fb5dL, + 0x3b5fb27c6049bb23L,0xc7c9da6ecb5b411eL,0xc1f2528ebc38336dL } }, + /* 38 << 14 */ + { { 0x8b177119d62ff4b1L,0xb0c02e2783150269L,0xdbeee1f8428f9e51L, + 0x2a55661225ff00dbL,0xb4ebcf98cd0d526aL,0xc69f721fc0efa6abL }, + { 0x0ceeceb516e29d31L,0x0bf4510127d1c530L,0xad942f1f42a7383dL, + 0x2cf389eb03b8fa98L,0x1aa647651ec6acf0L,0xf7ac647c202433b9L } }, + /* 39 << 14 */ + { { 0x880bfb2caa7fcbf4L,0x18c2b739731cd693L,0xd093ada3ae39b46eL, + 0xd48a288796c6fb7cL,0xed7c405daf96bbfcL,0x6b63b9ee256335e4L }, + { 0xfd4795ec7ee8e89cL,0x4f3fa1ccb07320d6L,0xe16c594206b0078dL, + 0xb8c95b563a0b2914L,0x2b5b5ab42b337970L,0xcf612b4cb9f75ea9L } }, + /* 40 << 14 */ + { { 0xbfe63081596eecd6L,0x20eb6fb0a3a194fbL,0x4497ec2b8751a73eL, + 0xf90e9e4cf88ba0e5L,0xd5a9c5d55974eca2L,0x9fc120ade4f3e171L }, + { 0x9ae058a633330640L,0xbda3227855bc8aaaL,0x7851cdbc1c9688a9L, + 0xf68d7d9e1d950edfL,0xc89c645074e06425L,0x62406f3b6116d386L } }, + /* 41 << 14 */ + { { 0x1094390070e509fdL,0x0a8e3db09af61ad1L,0xa487a61538d7aa57L, + 0xa9d56bc5ed020b3bL,0x7ed2294f638b35f8L,0x53d6870dc95fb42eL }, + { 0x85e828494c2207d7L,0xf88831baf0556be9L,0x64a547979fe416c3L, + 0xd61b652e779bebaeL,0xd3f43e2f2c0ccce6L,0xd5119f341f680ab7L } }, + /* 42 << 14 */ + { { 0x466f42a1191938bdL,0x95ec31c036f1dae5L,0xa7f350d2feaa8b55L, + 0x66434577555c505cL,0x0c668e73f55d1ca4L,0xd6af5ba4a7bd7449L }, + { 0x581e14ac1a79d8c9L,0x9761d9763054e915L,0x928e7415d69220a6L, + 0xc5bf4bb405bc4a22L,0xad033b7c45d52313L,0x4e67962c75d66dc7L } }, + /* 43 << 14 */ + { { 0xc60e17b2e2300049L,0x731c2fa54107f308L,0x848f6db7cc2982b3L, + 0xf251c21085275d38L,0xf5cac5b2128c8a96L,0x3c012933405b27f0L }, + { 0x9b0a61520b8b15b7L,0xb1c32dc691fa4548L,0xbe7b7654f366d677L, + 0x7e1f33277147a660L,0x11e31a0eeae310bcL,0x3edef63c1b86b525L } }, + /* 44 << 14 */ + { { 0x6f7e7259c6334c8cL,0xe34cba49b4f2333bL,0x157bf099211d08c5L, + 0x9e39c5442988a4daL,0x796ed9f17a998311L,0x3f4da896d8d349e6L }, + { 0x8ab75656fab28acaL,0x3e215d5342d14b21L,0x50008fd7bec23301L, + 0xd6ee4853446e2c56L,0x203ff1c880da14bcL,0x27a4bfbbc333ba74L } }, + /* 45 << 14 */ + { { 0x745e69dfb3d54e52L,0x1ab2a03e7c405cbfL,0xda71141e0bc431b5L, + 0xb3a47e71aafa7c19L,0x5329594fa88a4905L,0x489b5928973aba07L }, + { 0xbe31a4d37350ad6dL,0x177e5285478a42a4L,0x45a101bf848eba6aL, + 0x4287dfd949936d31L,0xbc4c491dc82823c9L,0x87c816aaeb8b8055L } }, + /* 46 << 14 */ + { { 0x66f5337cf309ced6L,0x897cbcb9eb5ed3cbL,0xeffb601762c35fd5L, + 0xb4b702f081fd31f3L,0xd5203833f66f6120L,0x1d2d5ef318a84d91L }, + { 0x22f9fae70edb3857L,0x034197b3cef00765L,0x16d8c6b493643908L, + 0x90ac59e16c51708bL,0xbed18da32edffd9dL,0xc90ac893e750df1eL } }, + /* 47 << 14 */ + { { 0x4a0af827bdb07e48L,0x5588631e131f46ebL,0xda550ce1e503169dL, + 0x0e16b540f2cf2f14L,0xea19a70dc79930abL,0x5654aa5fa8925651L }, + { 0x2f1a14906104f9c7L,0x98420d6c654cf319L,0xf967467f3ca96df3L, + 0x6abe4e32dee1fc07L,0x913bdf2bbd07d17cL,0xf96f70eda8ef9068L } }, + /* 48 << 14 */ + { { 0xa0096d10b7f8286aL,0x493e88563015be8dL,0xa221d57c17f70125L, + 0x4f932f4fe425eb77L,0xf0fa00df78ddfe95L,0x68165f257866f01fL }, + { 0x01345af4b1693425L,0x3fc8d3a6bad5603fL,0x4269006f0bf46cf5L, + 0x96e3b6b77e340ce9L,0x2a4bda69df7c68b7L,0x9649d8b91b6574c2L } }, + /* 49 << 14 */ + { { 0x98f55e59112ef290L,0xa5516c3568909cdaL,0x40407393235165f1L, + 0x6eeeae510991970cL,0xae79ce1faaa6d26fL,0x8bc719b441d43f67L }, + { 0x4a7af92a39cc89a3L,0xf6d14f9a85c8ab12L,0xb9bfca97eb8d4851L, + 0x926b8155cd52b2f3L,0xdd17dbd48fa94f9fL,0xaf68726447cac5cbL } }, + /* 50 << 14 */ + { { 0x39d7c1729517c2c0L,0x6f795181166e2f50L,0x9f6ecb5dc0ad8b54L, + 0xb480afac8e75ce4bL,0xf51569203dd5ad07L,0x87c855e73799b80dL }, + { 0xea8c34d9538ebc9eL,0x67bebb6a957b303aL,0xc6511b7b4dfc6d7bL, + 0x9a40cf5885b02ee1L,0xf4fffbbdecc59a6fL,0xe85a7c115cebfbcaL } }, + /* 51 << 14 */ + { { 0xffa0118c4a33265cL,0x4c4051d583e0bb83L,0xcde22f8d7007d078L, + 0xae9ebbc2932cba29L,0x297c2252f7a82223L,0x662814f41a09fbdaL }, + { 0x3bfd965640be805aL,0xe49901e592acce09L,0x4e201930bbb6bb43L, + 0xfe94eb4dcc018aa2L,0x454d8c611dcf97a5L,0x11d8e3a230f1011dL } }, + /* 52 << 14 */ + { { 0xe745ee2c36cc8b1bL,0xb40c94e6e328c813L,0x4144aecd8bd107b9L, + 0xc35567890ea88fd2L,0x017460e30492a810L,0x0c63cd4410b8bea1L }, + { 0x9123e9a3c890f74cL,0x940fe6590cea499cL,0xbe306232c82e1bdeL, + 0x40544f6bc041d7ecL,0x46de1f3b477a7dafL,0x336551f6951f1295L } }, + /* 53 << 14 */ + { { 0x2a61217a09b3b9a1L,0x0736704635b71125L,0xfddbf1933df24d57L, + 0x33ddabcb4592d748L,0x2fa9ff8a25309e3aL,0xdca2dd2892a0e76aL }, + { 0x706350255dfbd02cL,0xe01c2553b6306b8dL,0xb14132905e91ddecL, + 0xf45221866f6de6fbL,0x2d48d001b440319aL,0x926e9b64fe67f843L } }, + /* 54 << 14 */ + { { 0x5580401264e2c160L,0xe154925a9a6c256bL,0xce2df32922260b79L, + 0x74824410c546d756L,0x2a1d0a5f79887083L,0xa2c040c5da3f7d48L }, + { 0x74058ecbc14f96b8L,0xe69c09d73415e476L,0xe5a93bb47a443fc0L, + 0xe1bb24800c31d7b0L,0x4701d669f4ab0610L,0x0ad815841eeb23e9L } }, + /* 55 << 14 */ + { { 0x823cd737d72b5925L,0xee09efb9fa38cb06L,0x6828dced4a21e81eL, + 0xab67b37bf365e481L,0x3995edd2b5a7c630L,0x4c24ac8806930b7cL }, + { 0xfd7264d36dedce0eL,0xdcab1e333e76fe1aL,0x6b40889a89a94f97L, + 0x7a1fd432b2a3b0e3L,0x121efaea3ffe933eL,0xa81f6c6f843c3553L } }, + /* 56 << 14 */ + { { 0x26301455e5488aceL,0xdf39099881a20dc7L,0xac7d6049ee06c7f3L, + 0x547e8df33f248fe7L,0x5fc4b74213743dceL,0xa97721bc4c398630L }, + { 0x6b7877cc258aea47L,0x1cedce562d5c28d6L,0x7e930e419428d66eL, + 0x42c80757b97faf54L,0x091fe5ab3812e632L,0x2c29fd42e2e359bbL } }, + /* 57 << 14 */ + { { 0x2d9e65a61d7b990aL,0x8a9ab4bee2a8a6a9L,0x8658c36985e3eea6L, + 0xf352787df0de0b23L,0x872db1de1161aa92L,0xf2648c972190acbfL }, + { 0x9a34f1d09de72e41L,0x13860f846c086516L,0x2e9211b824127c21L, + 0x4e1623bba3697c37L,0x41d71f1df579c733L,0x33f0ebf7ca9f68aeL } }, + /* 58 << 14 */ + { { 0x9b51f4ca9f5a40c2L,0x38b59573682e2132L,0x5765e89dc556998cL, + 0x102fe894698a4a8cL,0x0bbcae977c6964d6L,0x8548f2c6dd7bb12cL }, + { 0x32c11ed9e49848d9L,0x1ee1b525135aefc2L,0xade5d14e812a5e4bL, + 0x0e122e7e15bb167bL,0x321594d4ec5c3594L,0xbcea8723a7c02afeL } }, + /* 59 << 14 */ + { { 0xdbf91edcaf87c75aL,0x9710003266582706L,0xb10cb32b1133a7b3L, + 0x70f5d71767e068daL,0x8d937e56b8e0c9a2L,0xd8a2652ee2a9afd7L }, + { 0x94d6cae9cc90c6ccL,0x3512f3abe94f68ffL,0x931ea6f09331ad40L, + 0x71621013daa3d4f1L,0x591c40bfb668a992L,0x5494cc174c6868e5L } }, + /* 60 << 14 */ + { { 0x7981826070ececc7L,0x8cc0b6e071cfc0e1L,0x998df6590276a6bcL, + 0xffb5bec11a43be05L,0xb93b1543f2beb640L,0x337703d456f3719bL }, + { 0xce74c17cd40a7375L,0x6aef79cab1aece94L,0xc5bdfb388876d218L, + 0xf71ce9cccea91445L,0x471cdbd1ed6e5f5dL,0xe0cc79cf10e56c08L } }, + /* 61 << 14 */ + { { 0x2b17e181794ebe48L,0x6111c897f28cdd32L,0x4d59199062dfeee5L, + 0x7b9d070241b14904L,0xa1ad534d5fea4804L,0xc08915d953b16c22L }, + { 0xa57c883e8ac9ddedL,0x589474dcda1d1bf0L,0x31cbf32ce9aa8e7dL, + 0x2abe9b60f0930d84L,0x604731b0cbdd031aL,0xbc35b1e4e9e1b3c1L } }, + /* 62 << 14 */ + { { 0x39300d55efeff954L,0xa9cf57f34fe9cffdL,0xe3315321b15aebbdL, + 0x26354c57b840b080L,0x2c690488476abf35L,0xa7303fe6d480cf33L }, + { 0xa50865295706c3b1L,0x4c26034eed0b2342L,0xf08d67be9ae9c452L, + 0xd4dbb9f5046c7d0dL,0x4435f1a3f9e5393bL,0xf47aae68cd4d5de8L } }, + /* 63 << 14 */ + { { 0xce9e5ddc06d5f48bL,0x22c1cd3e0ef642baL,0x2ad48eb9e9b8a960L, + 0x330074883ce26679L,0x495e62428d2de642L,0xcba5bf37e03b1a77L }, + { 0x9382c92de716624dL,0x410d212350a33e4fL,0xe55ee116e953e7edL, + 0x27e9a0584b840616L,0x560a5e4939473bd8L,0xbc1e795b382f3a95L } }, + /* 64 << 14 */ + { { 0x31bdb48372876ae8L,0xe3325d98961ed1bfL,0x18c042469b6fc64dL, + 0x0dcc15fa15786b8cL,0x81acdb068e63da4aL,0xd3a4b643dada70fbL }, + { 0x46361afedea424ebL,0xdc2d2cae89b92970L,0xf389b61b615694e6L, + 0x7036def1872951d2L,0x40fd3bdad93badc7L,0x45ab6321380a68d3L } }, + /* 0 << 21 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 21 */ + { { 0xc5cf8997ce0b5b72L,0x350adde19d7154baL,0x8139681e307b254aL, + 0xcc87fb5775cd94d7L,0x90e7027478684954L,0xc4fdf4c095ceb991L }, + { 0x91bbc0ab8762c84cL,0x5e09e226ce09e8adL,0x1cb83d704b93d45fL, + 0xe2299024f541da1fL,0x3eef7ce14b7ffd10L,0x53ee63bbb3fc1b9aL } }, + /* 2 << 21 */ + { { 0xe5004e8003682f59L,0xccdb9cb7f642ac0fL,0x405f50d1bd869f77L, + 0xecffa54de7ebea2cL,0x3354dc22d87620baL,0x01bb2988b1c01ff4L }, + { 0xd9370076e16477fdL,0x45303d2a2e71ba4bL,0xc0de76273291e5c5L, + 0x5cfebd87f0a7ca55L,0xde1162809e592a30L,0xdd26e577a78ebce4L } }, + /* 3 << 21 */ + { { 0x1e9b23b9ff1735a8L,0xc3bf3d5b2b0e4b7bL,0xd4cc00fe59b7721cL, + 0xd5c36f9c9e2f4cebL,0xdeca06bac90af70eL,0x42676f12416ee799L }, + { 0x0d7afe1b6f748c6fL,0x0b7a6de539c39d55L,0x11e43d6ee6eaed18L, + 0x5baf8602496087e0L,0xf833634fb1a3a66eL,0x25098c8a79398677L } }, + /* 4 << 21 */ + { { 0xe141e763d4720770L,0xb9739e70ddb3b450L,0x46e6cde496131446L, + 0x0458a5d5cb6c2ef7L,0xb7747634532f9fd8L,0xf62d372116544457L }, + { 0xbfacb4ded3100854L,0x70788a31b39d3f62L,0x9b543220f22d92e4L, + 0xaa4590f655723258L,0xc7b6730e01ddb8bcL,0xae252cf869e1e7bdL } }, + /* 5 << 21 */ + { { 0xc618cf0ddd4b8d8dL,0x471cda8640dcfbfbL,0xba0dd7ac08882ce6L, + 0x58e5d2f56cd336e7L,0xcdda8301af096540L,0xf6d268463cf31600L }, + { 0x6150cd982197efd5L,0x4440fbfa55fb0877L,0xca31871c90757f1dL, + 0xc4a1faacbdd756c8L,0xc9d4ac1bcbb8421eL,0x3c0c2914b17c43beL } }, + /* 6 << 21 */ + { { 0x46fdb65caa6fe9eaL,0xe0d48e5e05494cd9L,0x5adef5704afbf837L, + 0xc96ba4b91c9e2cadL,0x1e8158f7054a158cL,0x47be73209e38b88dL }, + { 0x9b99971e6d2993ecL,0xac9b0bfadf980eccL,0x9da09642d96ca391L, + 0xd67105369bf4305cL,0x40cc1adfa0dfafaeL,0xe27e32f8a209699bL } }, + /* 7 << 21 */ + { { 0xeaaddeb836e87d82L,0xc12587a71ffd7210L,0xf93d2f5c731f6838L, + 0xb96594e8f7097a65L,0x08d6717ab016e8d3L,0x9c378de81984d825L }, + { 0x627d41e7cb2a0c26L,0x1f447501c697ceb1L,0x8dc40831c760550bL, + 0x70ad48707fac97b0L,0x5ac7f22e7021c170L,0xa6f730e4929d5931L } }, + /* 8 << 21 */ + { { 0x7d27d71fd186cb09L,0x67cb7f4e3bc213c7L,0x418cafeb6075b2cfL, + 0xc0d691e6d93a06f7L,0xc16a95259dd001b9L,0xa0583230026f17b9L }, + { 0x4c1041b07845900bL,0x2874079147a22aaeL,0x8d08efd62c1758e9L, + 0x9cc6f207e6c3229aL,0xec69e902082d8924L,0x9cfa1deaf331dfe7L } }, + /* 9 << 21 */ + { { 0x7b5ab2afbce81cd9L,0xd25fa34b12028b49L,0xf9d65e6b63a659beL, + 0x6f88f1ddfffb943cL,0x38eb0d02b871cd5fL,0x732afedc558ad949L }, + { 0x4093ab05367d424eL,0xf73b23ad29de1be7L,0xce1c0093e7a50181L, + 0x6d05cbbe1e412cb9L,0xd3c1148b773a394cL,0xe04b5fdd38e50316L } }, + /* 10 << 21 */ + { { 0x1793535b8d0ce0f4L,0xe9b054b1ab73f7daL,0xd82a3ac1ee7bc6e2L, + 0xb28ad846b847f39eL,0x40975fa2fc10c012L,0x8de998619aafe68eL }, + { 0xa73f442584878534L,0xbe3118cb7a36a0d7L,0x3763a49e8fa37fc9L, + 0xf3f8ef82361f32b9L,0xea66f9978c1aebc4L,0x88600d648d9d024cL } }, + /* 11 << 21 */ + { { 0x11f842ca150a3325L,0xbae115c3185a385fL,0xddf9643637561bb0L, + 0xecea0cd9a4115fe4L,0x297720665893a694L,0x837e6880df408cfbL }, + { 0xfeb8f511e0a7fb68L,0xd21869dfa062b60fL,0xe2b60f46ca6a5e72L, + 0x64bbec184931d188L,0xfb09c90fe3ef3378L,0x67cbeffacd767337L } }, + /* 12 << 21 */ + { { 0xd35832381b289f6eL,0x10dac54a0aeb3bcaL,0x4df1c08d6692339aL, + 0x2968edec20054647L,0x34072618d74235a4L,0x00b4a7ae71d6064aL }, + { 0x23a8900e25c23f8fL,0xda0cb7fad7d0f1b5L,0x266211c56c8ecdbbL, + 0x0a4351b97bc27e4dL,0x98d54c97fc234258L,0x5ba534071e1a4dfaL } }, + /* 13 << 21 */ + { { 0xf07cfcdd77f083bdL,0x89bcae29d46712c6L,0x2089c3ab0f09bb8bL, + 0x3ede5a2a6b9a4028L,0x27ee18fe013066deL,0xc2bebbb416fcdda3L }, + { 0x6b3926af3a87cd68L,0xf52f0ef9f9a7b831L,0x4a39660a1ffc01b2L, + 0xe98f718d91aa6719L,0x8b0626f111d48e8dL,0x4a6a2e5b2bd93db3L } }, + /* 14 << 21 */ + { { 0xc3ddb6123ef24470L,0x98b66569bb3f99edL,0xccc537153a97a015L, + 0x0d9a6b4d04937b8cL,0x854d081ad9a575f7L,0x347bf0c0127fbd90L }, + { 0x6baa47a5c30987f1L,0x164b390dbfd0b503L,0x6672d1afe6a1f565L, + 0x9a50ee5828d5bb14L,0x2e23ab480d0226fcL,0x33eb052365cdbdbaL } }, + /* 15 << 21 */ + { { 0xa32d1a27d904eb73L,0x6fcad8d0c43c978dL,0x8cf1e7a19c0842f5L, + 0x2a6fa6d800328ae2L,0xa5905f67a1e3b06dL,0x458c8badaa8df96aL }, + { 0xee5b20c0b0d4b89bL,0x352ae0c4815c1af8L,0x546a7d7e6dd73b70L, + 0xa99882225f753229L,0xa38eb5d7efde47e2L,0x8290aaed92635ab1L } }, + /* 16 << 21 */ + { { 0x8ec4335fabe7c60eL,0x01f198c10a6a9fb5L,0x3ff96de001141ab6L, + 0xb21acc2c2eca98a1L,0x6154849010fdf648L,0x2c01a99cd1403e8bL }, + { 0xf1a35f306fa509d7L,0xf7715fe3e3f08e9fL,0x89c26c077fc9a752L, + 0x8d2535fe420d48a0L,0x80ec5ddd52fe2e73L,0x041b8df071704f39L } }, + /* 17 << 21 */ + { { 0x96882074659a0a12L,0xdb0d63032a6bb752L,0x2a1fb2d740c2194dL, + 0xeb6b45ba2c184444L,0x10ee44368c179d33L,0x906d0e509391917fL }, + { 0x11bead88ca3bcba2L,0x25914dae4253fb99L,0x0445b31013c25404L, + 0x2a2eac6d515f53baL,0xa746a1d662bf0a11L,0xc7576a4c6573c4f1L } }, + /* 18 << 21 */ + { { 0xec159ed060c5bee9L,0x80282ff007746414L,0x8d53f05f40a97a54L, + 0xc92d8789f5d4eedeL,0x1edd798132344c09L,0x3bb9a444a92c7b36L }, + { 0xbf130f5cdd6c8903L,0xd270e7cf676fcab9L,0xac49744bdc5ae6f9L, + 0xbd0ccfcb40e39281L,0x222efa16a981b3f7L,0x92bcd2d700aeeadfL } }, + /* 19 << 21 */ + { { 0xecfdb91489c73e10L,0x83a5168becffe79cL,0x6a0d57c123e97ffbL, + 0x774121ca4b130cc3L,0x8556fdc5486967a6L,0x1249448d5fe4a7f5L }, + { 0x8c2c14440e93c114L,0xcde258573bc68985L,0x697ba7b0952758a2L, + 0x0d962b377aee19e3L,0xdb31fe8582c4c640L,0x6ecfaf36c89b4b85L } }, + /* 20 << 21 */ + { { 0xf1e8c5a0e06b40eeL,0xa55909fe59836af3L,0x77a13be8a3a4ed95L, + 0x47408650bbbcde0aL,0x95b455c2b4fba7b7L,0x4983f5ca4321117aL }, + { 0x37bab5d1e18d304fL,0x0edf3733f1d29206L,0xe23e4db4dab91670L, + 0x602a5265923ab7c4L,0x53ee98c6eb920a03L,0x1b592b626f25489cL } }, + /* 21 << 21 */ + { { 0x66c981d9d3543689L,0x20500cd7bb8f53bdL,0x807d43605179af77L, + 0x7280a7b27c286404L,0x75a74e630976a65fL,0x2ba9ad9df11c3bdfL }, + { 0x23f38f950ec6c760L,0xcad599102b858cc1L,0x4d9adb7efec23c19L, + 0xbabb6e45095e85c5L,0xfab66a97e5dac2e4L,0xcde4b15a08baf1f4L } }, + /* 22 << 21 */ + { { 0x148aad3207089d6aL,0x3ab5b0790303c267L,0x7d13995bc3153026L, + 0xeba27c192287f305L,0x5faa453367ae45bdL,0xbbb561db2f4e9488L }, + { 0x254d8977c8493163L,0x60d468fc5c544164L,0x0b6309a3a2758037L, + 0x8480e16b1f9add24L,0xf1d99fd2902ec661L,0xd32df254cb6dd6f4L } }, + /* 23 << 21 */ + { { 0x9a17f5c3610178b9L,0x75dded80bada5aadL,0x158249c23dbeb289L, + 0x1d0671cac300cf49L,0xa1649bd0886902f2L,0x79b0d6ed7d13be62L }, + { 0x78253e7549e2327aL,0x5629cc509af110ecL,0x4373a20059f8765cL, + 0x739f33289d9c5f3aL,0x3c7d5cfe9a5f997eL,0xf044d90d0559357eL } }, + /* 24 << 21 */ + { { 0x20aa15d97ab838e6L,0x6cefdd5a0c827ed1L,0xe2f205caef579e8fL, + 0xad27e38b325981bfL,0x087b8284c3438be8L,0x2095dfcf422360d9L }, + { 0x87cdf5ad76d096bfL,0xf1b97ce1e022adc3L,0xa71240c189104665L, + 0xeb5a175c9c1578e8L,0xbd66910ad150ffa2L,0xac277af811459a28L } }, + /* 25 << 21 */ + { { 0x7db4df62417fb54dL,0xf6c1e7f04dfb7c05L,0xfdcbd3777aa8ceb5L, + 0x0364b3bd89c24333L,0x8a721718fdd3dcafL,0x9a6015dcec2848f1L }, + { 0xd6571930d35ad1a9L,0x154a929199369196L,0xf3be7e228e514732L, + 0xfa3eef28b7fd3aacL,0x0bc3b2a69f60d298L,0xf6327920febfca58L } }, + /* 26 << 21 */ + { { 0x3b9de1baf8dc6030L,0xacc4224a2107fd1eL,0xa7d32fe86dcef0d2L, + 0x353d5e88dd83fb28L,0xd552c3ce50bfb0b2L,0x69bc0e686cc8ee7dL }, + { 0x965c0ca21d9c74d9L,0x5cd163a406ac3ecdL,0x57910a828e98b581L, + 0x1d0fa7523d992afbL,0x862d3184e7d12701L,0xab6a288c6c7d161aL } }, + /* 27 << 21 */ + { { 0x04caa9caf4f2b3e9L,0xcdb896141af43dd4L,0xb09444fd4e74ee8bL, + 0x9428849fec05d35cL,0xe29bb0e94765c0e5L,0x138c45f176d25d2eL }, + { 0xbf041131a0184d83L,0xaf321573991ddc4cL,0x058760a8ef31df7dL, + 0xe0b94b57f80dcf5fL,0x75572221850a4a6eL,0xc735580c104a4a1fL } }, + /* 28 << 21 */ + { { 0x9ba102f1a6b735daL,0xe073232edfbe7d06L,0xa8ac24ba57266a16L, + 0x07458ea42d5c4bb0L,0xfbdd0f0574868e1bL,0x73fa612a3921fe7aL }, + { 0x26f6714b0b32d8e2L,0x7a3cb2b48bceb95eL,0x756a68c6290f204aL, + 0x148fbb787fdf2b7eL,0x639ece6c57fe0da0L,0x315aee1e9a92b7e7L } }, + /* 29 << 21 */ + { { 0x22dc170769d10661L,0x8d89cd1c71fd40f7L,0xa22f11bfa2545040L, + 0x1247d019d44c2446L,0x8d17daaba08235c7L,0x7e6863b9fae7874dL }, + { 0x6d57431c0490d338L,0xc1459e61809d1f9aL,0x4eb14dce95b64852L, + 0x8d3a04e6a7b5a861L,0xfed631ee7bfa24a7L,0xf8f86f27af11723bL } }, + /* 30 << 21 */ + { { 0xb43b14146e63c833L,0x497a5f98c1ec160aL,0x112223de83eb3709L, + 0x293964a88d100b9bL,0x6db1d1931e3b2db3L,0x264bc83d71eced39L }, + { 0x8418eb43aa89c967L,0x51d41bff76f8620aL,0xa4017ee5cc416467L, + 0x1cc527231e216e36L,0x76ba536ce8069a6fL,0xa239b54acb77b981L } }, + /* 31 << 21 */ + { { 0xa05f2dbc37544476L,0xf18dbcd71b797f65L,0xc78131376d50cd5eL, + 0x2b509a4d6dee11daL,0xfc0f0584beba1b6aL,0x3282624a9d53bd6bL }, + { 0xa0944e5c16b7187bL,0x468a79b8aa2f99e9L,0x32e4644b38bc4ed9L, + 0x5bc375d7e7cf71feL,0xe18e3c0956617861L,0xbce9ccbce69255bfL } }, + /* 32 << 21 */ + { { 0x498808edc65fafceL,0x3676a7cc4e806bc3L,0x796e25f176c6b964L, + 0x1aced64bac474261L,0xa62470fc29a460c1L,0x77501dce5e751e48L }, + { 0xcc00053b6d9e3641L,0x2b5bc4ae9a3f5a0bL,0xddaccc2e3f9ca178L, + 0xad33f34a0b80d1b0L,0x6a76df9364642225L,0xc145f36f778e761bL } }, + /* 33 << 21 */ + { { 0x377fc5ac575e74f6L,0xfefeb2327736739fL,0x62ba076a9fc2d5c5L, + 0x6f3c6084baf0269aL,0xce2917688fa7c145L,0xa60bb8905b3f2333L }, + { 0xa811055dd900095aL,0x92d95e7b385bd4f2L,0xba54f444d33c2a43L, + 0xc1b131327d12754fL,0xdcdb54821556f5e3L,0x55377fc539ca4b94L } }, + /* 34 << 21 */ + { { 0x455f65d1a0cbee78L,0x554eccb566225edbL,0x306400b47a4e014fL, + 0xef3e02eb7b67025aL,0x7d4efbaa997a633aL,0xd43c6eb8672c90b2L }, + { 0x0ed2d88d7519da07L,0x864377854b9d51e8L,0xd5900a2e2e3ab57cL, + 0xc02f046b69bb0a39L,0x06d825a6bff12faaL,0xa12e5b0d5d3ac267L } }, + /* 35 << 21 */ + { { 0x1716be5ba10508b4L,0x8706acbe7e37fbebL,0x3881f54e44e3d127L, + 0x54e20622a864d77dL,0x26a194616b83325eL,0x0d57be814c15a8f4L }, + { 0xb10c0cd07b53b476L,0x3d016ea097d39c64L,0x4d7df7c15315bdadL, + 0x6fe5a1acf060cf4dL,0xd5e3d05396846b79L,0xebc878f79e3c8028L } }, + /* 36 << 21 */ + { { 0x5b849ed8d0d193acL,0xe983abf773950501L,0x5ca162770854a569L, + 0xb0b284d26904bdceL,0x9c769d269d4fadecL,0x98e5e9b912677284L }, + { 0xd9246836b557f2cfL,0xbd47433069d46374L,0xbce8b27b9b063a22L, + 0x08da2eca37c5ba26L,0x9e742de8d4b26479L,0x643b752c102aa36cL } }, + /* 37 << 21 */ + { { 0xb72fae566fad22d5L,0x1e921426cf2fd62bL,0x9f31293d4c225102L, + 0x78d43a621975afbbL,0xce2787303cfee30eL,0xb88590d77a82613eL }, + { 0x42f86567560b932aL,0xc2d98915a7c9ed68L,0xe70e41fb349a9750L, + 0x7e7fdd2c79f9582bL,0xf3d6ab07da737c0bL,0xba247c0b9f3cf823L } }, + /* 38 << 21 */ + { { 0x4bebaf153dffdbd3L,0xc37d4a04fcc967a6L,0xeabab9aca0435a65L, + 0xf23d1d58f9ae9c52L,0xce229a798cc8f7b6L,0x4a61e6ebf5e11e61L }, + { 0x770e1dc6b20f2d8bL,0x199d20e8cfb9e820L,0x9fd709c4c381a22bL, + 0x6f53a358b1d52a98L,0x4b1a018c66f511faL,0xc7d2d49375d3a666L } }, + /* 39 << 21 */ + { { 0x3b2db5e5550791d3L,0x034ed5665bbb686eL,0xf019f161e033e3eeL, + 0x33198653acd2f0b5L,0x368d89e41ee8273cL,0xa7ac3b507f26daffL }, + { 0x73d8d7df006c0037L,0x98b5937de73cf271L,0xc3bc340be917247dL, + 0x799ea890e45f37afL,0x27be0f5a25e8dd2fL,0xd70ec41c3bb16923L } }, + /* 40 << 21 */ + { { 0xd30302352679072fL,0x73dfdc0f95dad4c8L,0x53649b575c4630f1L, + 0x60197fc08d098d74L,0x9c295d54647f5cbcL,0xfa5f1bc6c0813efcL }, + { 0xf6e08007d2e49417L,0x4f7d4b3dab579569L,0x7af3e08e11d9b388L, + 0x073ec38a5db61c65L,0x9b480cb89db4dc4dL,0x9be2ce7e372fa82aL } }, + /* 41 << 21 */ + { { 0xd87c0b55ed1b6d83L,0x3b47443adfae29cdL,0x16c5b0e52147bfdeL, + 0x98812fd0663cbdbcL,0xe3cea04955ffe911L,0xfc1e9d9cc5df31caL }, + { 0x7ffa90f9902c4ab1L,0x2cf973c3669a857fL,0x89243cfc94b109adL, + 0x222d6fdb536ee544L,0xa48b1b15fd488c22L,0x7120e3f0f318ba27L } }, + /* 42 << 21 */ + { { 0xfbb8a3cd47813054L,0xa2d7255d462ac3f3L,0x341bc10babdfa7adL, + 0x01efa884ceb9ea50L,0x30fa0f903f5bd09cL,0x8aa309453abd108aL }, + { 0x0ab7fe23f9ecab6fL,0x0585f72a5ec032bcL,0x686a7d71cf9f4fcdL, + 0x096bbf04f769be8dL,0xa309931250b64584L,0x67be53402e216060L } }, + /* 43 << 21 */ + { { 0x4e14fa6eef252e90L,0x2ca968579b7db6f2L,0xf80772e3653f1662L, + 0x4f89e666cd28bb05L,0x7fa800cc77eef62eL,0xa3f6ef5963b2f3e2L }, + { 0x438d564bc81e600aL,0x8978912de14c1434L,0x33732892ea695891L, + 0xaf6aef0b1dc8caceL,0xcbf9580b7c509cb1L,0x2db9fbc11ed6fbdfL } }, + /* 44 << 21 */ + { { 0x408805a1fa7052bdL,0xe4eb27f75f825c13L,0x0a0cc8fa37ee34a7L, + 0x737b99a40c59156fL,0x78c2a5d8e1b55c30L,0x89d70b62bcbb2196L }, + { 0x07ad36911e862a0fL,0xaa1c9118c41cc693L,0x7e6f544c4e1f7359L, + 0xa5f4f5891bf9474fL,0xa711efd9ef56df82L,0x0428edb7e3de91fcL } }, + /* 45 << 21 */ + { { 0x67f403610905be0fL,0xffe68b80c12178bcL,0x41bef79ec6a673aeL, + 0x347e8ba81bc77376L,0xd49956d60e589da2L,0xadd54508fed84dabL }, + { 0x18868a4a462749f4L,0x2048cd88ed323e71L,0x7b27932aa28d1f02L, + 0x3cf6107412e4ddccL,0x0f6198631360ecc5L,0x40e5e08b1330d33bL } }, + /* 46 << 21 */ + { { 0x79b68071e3ad573bL,0xcb070412723966f5L,0xf4610fd1964b453fL, + 0xfdc9dbbc8bcee838L,0x3e191f3bb5ca4f20L,0x90d85084c02e0af0L }, + { 0x4e3f57a70ee64025L,0x63f339acdea07a5cL,0xf255b5045eb4081aL, + 0xe42bd241b4cbb0bbL,0xafa58985ff68c5c3L,0xd36cf7175b55e6e5L } }, + /* 47 << 21 */ + { { 0xf2b06f4b95d37e50L,0x7da1d2af3747c79eL,0x18a37dad6ad0092cL, + 0x9f4a6f081a8f207bL,0xeb1fd3f2cf0fed15L,0xfb9911e4384eb46bL }, + { 0x5f07c680b87cb035L,0xc49935d189e1531aL,0x718f6bd09ea02056L, + 0xadafb67b18a4ca31L,0x26cb0f368477f396L,0xec7775df62ec2172L } }, + /* 48 << 21 */ + { { 0xdffb03aec10b43aeL,0x39b1266e9433a54bL,0x4c262521b19fe0dbL, + 0x0ec1e54f3d5c7feeL,0x2856510b05e68e1eL,0x49382c1edc80b8a6L }, + { 0x80a509312471bdd5L,0xe8cde18581974aa9L,0xca6112ee28235c52L, + 0xd28a0eb8301f9653L,0x22b11e26e11fcdf8L,0x97e6fc5de4d735f3L } }, + /* 49 << 21 */ + { { 0x7fc264d35b253506L,0x1a11dd9cdfe2be8fL,0x2cbcf79c711185a3L, + 0x2208200a46806ddcL,0xf2764b6524e75d8aL,0x71a71bcdfcb43c25L }, + { 0xddd0cd3586a895caL,0x5ec28b469e2caf5dL,0xeb749df9f6614957L, + 0xdae1dd77eddd371fL,0x7ce493b556dde554L,0xc1627c06d6e5653cL } }, + /* 50 << 21 */ + { { 0x7926553cdea7472aL,0xe1e9480d3ba7f351L,0x242a641b1b6a2fe5L, + 0xf4af10091f790122L,0x5a2e2f95967810a0L,0xf1eaec6e2ed57598L }, + { 0x34a32da96b9f2421L,0xdc32daa8dd820372L,0x8b2539fc37a067ecL, + 0x2a495112820969ffL,0xea7c1829a699c283L,0xb4a1083dc2c58cbbL } }, + /* 51 << 21 */ + { { 0x1bcc30812e59d7a4L,0x557be0b2fac34690L,0x5b2868db673254faL, + 0x62e150a49e1302c3L,0xe29e9b445772138eL,0xc76bf4fd7ccb31daL }, + { 0x8d687bbb34c905c9L,0xf4f207030786eeb2L,0xe56a494c38deb469L, + 0x759e75e2cc6bbfa8L,0xb11903aaa59eb766L,0x3f6928c5c68b3bf8L } }, + /* 52 << 21 */ + { { 0x27fa09ebcdded185L,0x763b655c36d090e3L,0xbc586674dd864c93L, + 0xa1f84ff34c7074b8L,0xdf5261d17cf08435L,0xc57860f6fbdaff3fL }, + { 0xfa49af22252d7f08L,0x2367bf8c8db5f89fL,0xad6443ce6dade92dL, + 0xdc5265138d1af3f1L,0x62a282ecc720ce46L,0x1769b74c9808b416L } }, + /* 53 << 21 */ + { { 0x4ee11333ec598f02L,0x4613ba038c7eaad5L,0x48e0bfe61b1ccd1dL, + 0x6e115b6b507b705aL,0xc4d38e4992874d89L,0x30460a066dc59fc4L }, + { 0x75de8dcba0f7ea87L,0xba96718125101367L,0x9d7b03314a742660L, + 0xb4ca381d8c304133L,0xb87b896d65846055L,0x8dd96f0513d381dfL } }, + /* 54 << 21 */ + { { 0x43716f0c3e25b7b3L,0x00caad210aeb5d75L,0xbfee232559a6cb66L, + 0x06c1d812ad059aaaL,0x42d0af57c8bcc046L,0x37968ef70e409a85L }, + { 0xc5c3812ee3be328eL,0xaaa74bf166547ad7L,0xb292af92a15a0db1L, + 0xc0645385e5d5cdbcL,0x2dcf4ca937ec2c28L,0x3f75d089f0cb1694L } }, + /* 55 << 21 */ + { { 0x7e71fba26c0204d3L,0x6191ad249a40b4aeL,0xe2c7ab6bdda24cecL, + 0x5a8fc77e95b26a2dL,0xa6d8b2e43f1c7e44L,0x42d485e4e0a0e08bL }, + { 0x8697386ed7e3b896L,0x5b960d76ee7e58caL,0xda950e9a3fce610cL, + 0xb85c7842803c67dbL,0xed8a53535e62ff2aL,0xfe6b0e2c4d674e7fL } }, + /* 56 << 21 */ + { { 0x46a2a08be26d822eL,0x63537bc689d6d6deL,0x28c556a2b3df9fbcL, + 0x81d3161eb121d512L,0x4e27ce0b123bc86cL,0x1ebadb85bfb240d1L }, + { 0x86edb71a1156314dL,0xf8ac56fd113961bdL,0x2f6bc6d8067f586fL, + 0xf558b8833fe8e532L,0xe9433e2321a7997fL,0xb86f039c87e53b9bL } }, + /* 57 << 21 */ + { { 0xc022a16d78329681L,0xc3da7bf76b1226d5L,0x47ef18daa85c69e3L, + 0x4614f0ee45cecdbaL,0x9126fc2640f19d1eL,0xcdecb2693f5ca09aL }, + { 0xb62a831257a020e3L,0x5f9a8ddc8330d472L,0x37e58ab3eb208a24L, + 0xe64ed285ee4b8687L,0x752fa22a74a82625L,0xa67e24609b25fbafL } }, + /* 58 << 21 */ + { { 0x89e3d770e6b94044L,0x50f50d1675a1a8c9L,0xe73c51d95344c139L, + 0x97a8dd8411723e9bL,0xba0663c57de5dcf2L,0xf26eee6c3a6b588fL }, + { 0x6275b2a9211b989eL,0x32ab4b311608f16eL,0x9e47b2943fdde5b5L, + 0x63c50a50614bae9eL,0xffe4ef05e31c05e7L,0x2fea9142b7db4ba7L } }, + /* 59 << 21 */ + { { 0x27f286db0874c6f6L,0x26de6376e6ec0054L,0x56458a082ca84fc7L, + 0x07bcd4011fccf1b2L,0xb8548e74bae6f486L,0x0ea5857a0de2964fL }, + { 0x8e8df866e50fd2a4L,0x3b07d1a8710fc74aL,0x3e4cc4f5a1fe92b9L, + 0x7380d0836e52d244L,0x4d75e1c12796278bL,0x9eb279258d33f4d5L } }, + /* 60 << 21 */ + { { 0xce7abd1ba225f084L,0x696e1eaff803ee75L,0x66f2789989415775L, + 0x14df21a29eb4991eL,0x012a6413fe2a0769L,0x022cf1c8626f421cL }, + { 0xd4644d0460ab4299L,0xa43cc1732a8d453fL,0x7c4ab8c20ed14031L, + 0xd5854b98e14605f7L,0xd9a98c51fa7ff2cdL,0x7dbe8cbc46baf2c0L } }, + /* 61 << 21 */ + { { 0xf26574593c42ae9eL,0x7c3e5c13bbc289fcL,0xb815fe3fe096e7bfL, + 0x3eb67095da54264eL,0xbf5ca7c4ff3f8128L,0x8fc4a3f865db4dd4L }, + { 0x3af47b17ee382cfdL,0x8854132fd95520f4L,0x3387b11d33c5588eL, + 0x5d7eb66c0c662f93L,0xcad581933b18885eL,0x8d1c069a6f23c209L } }, + /* 62 << 21 */ + { { 0xa9498fb5212ee678L,0xa8824b696ade4a39L,0x422c074e0a406cc2L, + 0x7d38de650a2beef0L,0x482d16f81eed5bbfL,0x1c882006f18380a1L }, + { 0xf90f6c2bb98445e2L,0x36aa980b2c738d70L,0x4caff65b6785ad58L, + 0x1c282becf95863f8L,0x59ad267c5350b79fL,0x53ea042721cedec9L } }, + /* 63 << 21 */ + { { 0x5cc362909fa3481cL,0x1321acdd7292ac86L,0xcc30550378f4d6abL, + 0xf7917237e7d9154eL,0x591e5ba81fb39377L,0x0a387e4f7c541c76L }, + { 0x99685212a38570cfL,0x5cce35c8624cd61bL,0x375c68133aed79d0L, + 0xf72d4b068197e487L,0xcd672f7d129775c5L,0x944ef37f1cd768f6L } }, + /* 64 << 21 */ + { { 0x9c66a32becc5f6daL,0xe4ff40431719ba2cL,0x8c6cfab721e716efL, + 0x32c8fccb96ed74e6L,0x475890dd0b110c83L,0xdfada95f5cb4eefeL }, + { 0x9d7b89a693240fe1L,0x6afdb2d0210b776fL,0xc3f0b55bca7a7d52L, + 0xa6e56a0655d04585L,0x818e221c4257acc5L,0x05207b63fcb8d39eL } }, + /* 0 << 28 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 28 */ + { { 0x0a74da82d8ada6ccL,0xc6b98a3cbea55457L,0x896c26bb57c2f5acL, + 0x981e2f72845d45e4L,0xca152b877e9a7d36L,0x49666d457b582e8fL }, + { 0xea3b9bda49fc20b9L,0x5bcbc84a7c71f153L,0xd346fc5d5748a654L, + 0x7ac2f217622665eeL,0xbb5efe7fb6f16e27L,0xb1810a70644c9dc8L } }, + /* 2 << 28 */ + { { 0x98d089819bc5917bL,0x9f90885d187fac5dL,0x651b18287cfc13dbL, + 0x2d606e4c8655a658L,0xba64d3c563c91b71L,0x36c7d7d8b82a5090L }, + { 0x2d1dff02cab1d598L,0xa95788d7be78f90dL,0x1ac2ee6b0ea1fe01L, + 0xc100b60cd5c1273cL,0x4496084ceae603e7L,0x7fcaaf5f77c2fdfbL } }, + /* 3 << 28 */ + { { 0xa93fec0861b06e05L,0x0bebc26b7dfe6802L,0xc00b45a5cce5662fL, + 0x2e8a0a7f83a9a4a9L,0x6e0cdebbc0bbeb63L,0xc56a20fe63ccd80fL }, + { 0xfc10fa08b51f1f89L,0x4848392020ad9243L,0xfda69cc66bf53af8L, + 0x474b7440f10bb6c9L,0xcda9db3b1e7625e1L,0xe2f62c1e1dc7f3cbL } }, + /* 4 << 28 */ + { { 0xe8e3225a6abdd842L,0x8c85f18f3b367b02L,0xf147a4219f42edb9L, + 0x6d4bc00d0d411d4dL,0xa1a13a2770014bb4L,0xb896d97bfa10166fL }, + { 0xb2a1dfa70c302c6dL,0x0a24bd5d808a63a4L,0x8409a3a2f88c7359L, + 0x071f3838347726a0L,0xd18a551c27507bb9L,0xe0c4cc34b359b167L } }, + /* 5 << 28 */ + { { 0xeaaaf4602a44610fL,0x94d330b10392ac47L,0x989b9b673fe123f1L, + 0xe2ca56ddd8fd0129L,0x77d6d0cd624982a4L,0x55d4b2c371e1fec7L }, + { 0x3e9a04a0360e013cL,0x1d227ea9c9cde585L,0xac2b08e24fed8f86L, + 0xa1d1357ce199e8dbL,0x7cf06ec8e99cc964L,0xd9bc3a7fd85ec63bL } }, + /* 6 << 28 */ + { { 0x7d111c67017c633cL,0xadd9e9bd7d128a9cL,0x4cd8730c6db857e9L, + 0x3c9c03e9f4b46d12L,0xd42f0242a78472dcL,0x3fc0bcb2260841bbL }, + { 0x6332b11a8783f828L,0x65229d2af7be37ddL,0x402f28eee7e8944aL, + 0x3d1bab505ab28372L,0x6944e82cad5e1ff3L,0x65a94c0de8c75729L } }, + /* 7 << 28 */ + { { 0xa151dcbc2f7f3633L,0x4305312a98969226L,0x947afc00604d46e1L, + 0xc3c9d57572f3e28cL,0xce4c1cbd14b1cd1dL,0x8fe9a81df80dea45L }, + { 0x50920f3a9685f603L,0x51d380f00b80d89eL,0x19978ba13f798e32L, + 0x1294aaa6c5edde47L,0x280002c2be714a1eL,0xd998669ef212603cL } }, + /* 8 << 28 */ + { { 0xa44f6ef880e9d9f3L,0xaa7621e91d14d618L,0xcb0e4ed80eaf6671L, + 0x2bf485f8181514a2L,0x74670e180a2927eaL,0xe1b5461612c14645L }, + { 0x4068c0742a67ed61L,0xd10c7a57739063caL,0x391b651d698b2816L, + 0xf310d1696da14fa8L,0xa089be6bd8a578b1L,0xa314b3a844389ad7L } }, + /* 9 << 28 */ + { { 0x688ce85068fd73ecL,0x2cfb41040db1f500L,0x5d943b8d5b9bbc41L, + 0x861867f5403f3973L,0xc331110a2c766363L,0xb28a6bc153aaceeeL }, + { 0x2ab6e7aaadbee7a4L,0x316ca45c2f2b9569L,0xcac646e561d2428aL, + 0x6fd28dadc7cb6291L,0x2e28f68741e20ff4L,0x8cfe90eebd189d34L } }, + /* 10 << 28 */ + { { 0x09b8ed53339da6adL,0xe40727af26f54b8eL,0xc4a105979990fdb2L, + 0xb808656b5108236aL,0xb4411363aa4bd584L,0x19e90149288a0328L }, + { 0x5795d8a8fb0592f8L,0x313c68833213c929L,0x62eecb5b48f79d47L, + 0x3afcfdbab29ca224L,0x0072847d40075b08L,0x078eef3dd1fe0c8fL } }, + /* 11 << 28 */ + { { 0x719b51f20ca20aaeL,0x01ad630824b47b92L,0xd32460c2d3c807deL, + 0x8497786b0a1785f5L,0x8bd521355d714ee5L,0xc267724ed00f741eL }, + { 0xe5578dca9c266820L,0x97ff60085b62d484L,0x84c70e92e3bd1869L, + 0x412759e34dfa679fL,0x6bccc33fce497e18L,0xfb92405669056198L } }, + /* 12 << 28 */ + { { 0x664ff05368ed0760L,0xc3cdc99138fae9feL,0x3fe057aaf1f30a86L, + 0xbae990222d08c72aL,0x4f5faf3f6f09e13fL,0x44461a4413d26b29L }, + { 0xc2504c1bf95418edL,0x12766ea7db3ff26cL,0x2f956e9507a22399L, + 0x2716e70f5a00cdd3L,0x80c020140e9fba99L,0xbe587ac30519875dL } }, + /* 13 << 28 */ + { { 0x5e4bb6b83b23d2a1L,0x819a7c7705c9888cL,0x59e4c48ad0fec7f7L, + 0x4b212b21d6bb71abL,0x370cb90bcbf213f2L,0xf1ea07e0817549b0L }, + { 0x20e3115351a37b92L,0x30f9e70158d444c0L,0x7ac3a37b0b791ab7L, + 0xe456fd475265e4cfL,0x3e3f27ca29580ae8L,0x5d68a40daa2a1654L } }, + /* 14 << 28 */ + { { 0x14203d8720cbb917L,0x284e0c9db2a7424eL,0x99eb2911cefe7139L, + 0xa709c50f42925411L,0xa5a7543e5c79a13aL,0xe262025c6f45f023L }, + { 0x3966fd18828b9f40L,0xc660846913693115L,0xd7dfbcf644373027L, + 0x8e73fe6bbade7645L,0x88267c7b1de0dbd8L,0x1231ac99ce4e8c9eL } }, + /* 15 << 28 */ + { { 0xfd928bd90ba99806L,0x799ac97d1a864172L,0x5436a8cd129682b9L, + 0x4bcacda54e96fecbL,0x453af995c5db1451L,0x8fd382e07073b98fL }, + { 0x17165b8a644a7bbdL,0xd17d2d80b6118620L,0x2a4bf1b2c8cd1bcfL, + 0xdc7aad959ccc119aL,0x6d34084c3bcdbeadL,0xcbc5c5557e0663c8L } }, + /* 16 << 28 */ + { { 0xba86aec170128295L,0x83a09b65c12f35ceL,0x8978ff0789df2f80L, + 0x85750cfd97a773d5L,0x806bb730fc3f35f6L,0x04503422fed868c9L }, + { 0xdc0fcde086ffdbaeL,0x8f4297e11860f43bL,0xfefb7d028d3ad6cdL, + 0x5c652b5997293550L,0x32e12942ed5cfbbaL,0x06192aaf98800d22L } }, + /* 17 << 28 */ + { { 0x9bb8cf660002f389L,0x217219af51505913L,0xfea1388999ef8797L, + 0xad1b2383235597c4L,0x85ffabb70a3e3536L,0xd8235d9da00c725aL }, + { 0xfa9b0f4ba704dac0L,0x99d76ddc2f57fb9aL,0x5ed3683b18428507L, + 0x9e42bc54435307f2L,0x3167de67b4f36896L,0x8a0f99a0d539d713L } }, + /* 18 << 28 */ + { { 0xf0b92b8a4642d9b2L,0xce97828a3f50c883L,0xa33d62936f0b1194L, + 0x23417e0f3692f5b5L,0xc79b9491fb0b95bdL,0x5410e8c95e836b2aL }, + { 0x2b84078d29798fc7L,0xa8732e78d6628695L,0x39da93f898c766aaL, + 0x0797832d305e464bL,0x246069ab163f9f4bL,0xb867dcef53fb6170L } }, + /* 19 << 28 */ + { { 0x949c63730ced5c37L,0x6f8cd6e4fdb6464eL,0xbea902ae2e056dd4L, + 0x43871371fa0d560cL,0x162128e9e9ec2208L,0x84deda5c25060c6aL }, + { 0xa8a8a27c14160ed1L,0xf24bf3dda33b53cdL,0xd12038a976a6d272L, + 0xe64d6384ee8f2b15L,0xc404d580d3e91d69L,0x62cdb886a4888d17L } }, + /* 20 << 28 */ + { { 0xccf0fb423c9eb0caL,0x8703c6694aa03b40L,0x44c735a74001af07L, + 0x9616dd932e874ed1L,0x5c2e8520474ba621L,0xddf13cd3fa93d8b4L }, + { 0xd68c9b4575df1b67L,0x4cd242288f80d389L,0x0f1a16bcc09f47fcL, + 0xc414dc6a9cd4842aL,0xbb0fa94f1f353c6dL,0x405124551950d073L } }, + /* 21 << 28 */ + { { 0xbfe176f2dfb520a6L,0xf51917bced96d0abL,0x8131985078b11135L, + 0x6397f1288f006a55L,0x9877f30e576b5132L,0xe0cd103bec781571L }, + { 0xb4bf74e5bcfd5046L,0x04333aa4be9cc561L,0xc6dd1dbc1e066ca1L, + 0x03c926e1d3718e62L,0x13bf83d404309072L,0x79649ba0ba28ac51L } }, + /* 22 << 28 */ + { { 0xcb1a73c55abfe8a1L,0xe9e2e220deae1d92L,0x2d953d00514befaeL, + 0x74024df9b7940bcaL,0x9a2cad0cd13f4a3aL,0x8790b699360795fcL }, + { 0x63957f3b5e9982eaL,0x491bf3155b7d256eL,0x5708bd4dd23324e7L, + 0x9f11ddd397c4c8c2L,0x1823762f5b7f5162L,0xc45a3976cbfc9dd2L } }, + /* 23 << 28 */ + { { 0x806134cd30731f5cL,0x04522c23487c778cL,0x99b6e6a1651640a5L, + 0xe2d20ed87e9898d1L,0xcad25762069e56d9L,0xd4184f6e29ddfc7bL }, + { 0x1017badcc1aeaa34L,0x7d3700e7f3c62e08L,0x203dcf8d5e42399bL, + 0x05986c66b72795c7L,0x0b56ad9cc0925f02L,0x1f0e895bfe0e3bd3L } }, + /* 24 << 28 */ + { { 0x935b9e244d2edd5fL,0xfeb46fb5efb287b8L,0xa51700a3f5018b92L, + 0xc328beba23864e2aL,0x113b5c9a995f70c1L,0xc0b11c22da1b5d51L }, + { 0x9b99b907f4a360cbL,0xf4ee9995adf0b094L,0xf67c7cf2f94b3f0eL, + 0x664a51a1dcaf10ccL,0xa3709ccce937a669L,0xea97bace4862f098L } }, + /* 25 << 28 */ + { { 0x62c7dd9ed537ed6bL,0x8a82ae7ccc168feeL,0x96fcf8d19d00a4a9L, + 0xfeef6ec205096874L,0xc828c68969f4485fL,0xdc4903a6322563f0L }, + { 0x5339cad7d3280a32L,0x42ae434909ff15cfL,0x94cdb7790bbb6af4L, + 0x480f8a5515721529L,0xc2f9c4dc0ff28eb2L,0x9d2a405e1ff6e3d5L } }, + /* 26 << 28 */ + { { 0xfeebe7d29309e729L,0xd322c38aa30a4eb9L,0x18cb0ce12f4f5c8eL, + 0x08a073a04262105eL,0x6ca92585933f888aL,0xf4a080c903ca1489L }, + { 0x5e678c7949c8daf0L,0xcd6ef6ba5abfcf82L,0x61faba612a4fc564L, + 0x7cacb3dcee0b306eL,0x9fcfafadb5aae2a9L,0x193e841c4b8fb04bL } }, + /* 27 << 28 */ + { { 0x4db6f5f07ed99ce4L,0x1257bd9c2456059bL,0x546c764b43d3590eL, + 0x6d5062adebba72d6L,0x6858f04e2e8d99fcL,0x46554047b4eeee5fL }, + { 0xff433f63535f2da3L,0xd76777542b76d2e8L,0xeb6be9c88e838a3fL, + 0xb7a2d2c1145f8bf4L,0xf3ba128703bb278aL,0xd88cd51530c4a1a4L } }, + /* 28 << 28 */ + { { 0x51758334c942a3f5L,0x7cc01e8832182ba6L,0x772af25774de4fe6L, + 0xb1b3c448e9667bf8L,0x71cb27388079caf6L,0x48890c641d823a40L }, + { 0x47a5887b0e9edbdaL,0x916dfb0cbe089e5aL,0x3185090e1eb42ddfL, + 0x3c7eaa13b7f3af26L,0x940ed8c79e9963b2L,0xd85e77db3426ac10L } }, + /* 29 << 28 */ + { { 0xf21b47bfd7bbbfa1L,0xf757cb309ea0ea77L,0x6df7f53783b2a6dbL, + 0xb0808cf99eb8ed81L,0xc526bb6b64edb3b6L,0x24f1612068f72d82L }, + { 0x3e2e6af8f01cee94L,0xd2e01f947847ca60L,0x079dac3539e68ac2L, + 0xc30720b270cedeaaL,0x2f97f968fa6bf057L,0x2dba403babf6a743L } }, + /* 30 << 28 */ + { { 0xed99932452c802f1L,0x99f6864c5cb78b2eL,0x8f8a0a709b9c3693L, + 0x0b931016e2f598bbL,0x7edbb1b3a614fc15L,0xa0321b50e79f74c2L }, + { 0x834f3ee994bfa457L,0x5ffa9613006907b4L,0xa37e9b83d779b46cL, + 0x7a21743cf33b791eL,0x6646b89dcc28a011L,0x9b975ef8e2ba76f8L } }, + /* 31 << 28 */ + { { 0x166c7151ec72cbfcL,0x3d1f2450c9e519ceL,0xfdcc648e7efc0fa1L, + 0x3f5f90cf6db6d516L,0x8a5dd3df145830f8L,0x4d9938da4e5858e6L }, + { 0xe598f9d4dede1584L,0x2de5a26cf5c8f4e4L,0x495b750f364e20f6L, + 0x29291c445b718188L,0xe560d9ee3733ce27L,0x99b9d27d5b9d206cL } }, + /* 32 << 28 */ + { { 0x162cdf342efffd95L,0x92111fdad59086e8L,0x4478d114454eb977L, + 0x8ce403d8dea38a67L,0xd459633b7435728aL,0x3a7be4e3a63b0504L }, + { 0x0c74066b335dba3eL,0x4e8fb1d7c6ea6ee5L,0x3398b588a99690edL, + 0x4949517c3ad77562L,0xf9824f09cbbb60eeL,0x9fdcafdf85660becL } }, + /* 33 << 28 */ + { { 0x368bea127aa62889L,0x6096730506e1046fL,0xe69be05e564f219cL, + 0x064b9d7c01eab75cL,0xf16ccc9e0152981dL,0x708827acb178a3deL }, + { 0x320f6a8a93248b89L,0x532acc568084908eL,0xe494cd1f6ab586d3L, + 0x59c74cacabbdcde3L,0x3ccf84a62259abeeL,0x6657d1fad96bd141L } }, + /* 34 << 28 */ + { { 0x5d3a8252aa0a9dcdL,0x540e037af97fe26aL,0x4cbb768ca3f68f56L, + 0xf9608732652d7058L,0x5fae0f9f72cea8b9L,0x1a7edfd97d980da5L }, + { 0x9f00ee611791c34dL,0x6c95404c2bc25810L,0xabb1089e043a9faeL, + 0xe36fe9e1a7881ae0L,0xf163dc460fc04e9dL,0xb6955f2f129c7940L } }, + /* 35 << 28 */ + { { 0xa22ebfc7c23bcd94L,0xa653b119684fe9f2L,0xe469e28646b59d70L, + 0x0720daf3dad96b47L,0x5066df7871288c07L,0x7648d7d82905b5a2L }, + { 0xc6ab9c5c0a30a65aL,0xa00539f34930712aL,0x6a64738c7e894bdeL, + 0xd7f3a7459e8eafdfL,0x652a58ff8ce9f7b2L,0x7c9d02e4cb3782bdL } }, + /* 36 << 28 */ + { { 0xf26bd8618875d9e8L,0x22e2380dbea9c273L,0x5f15183791995508L, + 0xb97f40a6648aa1c6L,0x7478f5f83977d848L,0x21e876ae35b57de6L }, + { 0xf620b180a93fc7f6L,0xf49bd07e1b148996L,0xfb0857261c4f60e1L, + 0x6a6653af7ad6b84dL,0x913a2d022e05b686L,0x94746629407dda9aL } }, + /* 37 << 28 */ + { { 0xc662b0f68a97c714L,0x69fbf7d1b8fbbb02L,0xf3bb5a9c5cdff85dL, + 0xfade6eb036ee44f3L,0x6eb4b8266d0905c8L,0x6ab3e4a4391a34d6L }, + { 0xf490046478e7bdb1L,0x8bcd4bf23272c400L,0xdf9a81b78d2c9573L, + 0xb9a0ea166af43695L,0x3298a5d071fe768aL,0x53eeeb4333e87bd2L } }, + /* 38 << 28 */ + { { 0x87cdbfe6bb531d08L,0x384bcd0357957992L,0xc654e2c942008cffL, + 0xd12b50285002e06aL,0x41a34286a67db410L,0x31a109d99d6b2c01L }, + { 0x14d642da2ed35f38L,0xa06a846048ffd04fL,0x8291190cbdbeef68L, + 0xc8106239e43bb0c9L,0x4d7aa992c4bea448L,0x107b86efba3dd9b5L } }, + /* 39 << 28 */ + { { 0x3d870c3144fc1cd3L,0x34409eec0085e7b3L,0x67d5c1340d0395e6L, + 0x9c30dedae3f36689L,0x988ac951d268cc91L,0xdb05825bd2c9dfdfL }, + { 0x30ccc3b75d349fd5L,0x63383c0f60c3a79bL,0x4f45c81732c71964L, + 0x456679642fef028cL,0x82454c12cf4053f0L,0x7c1310fbed8077f0L } }, + /* 40 << 28 */ + { { 0xb8465d16da684157L,0xdadde1abb238faaeL,0xe2cd45e7c6b9bea8L, + 0x7251d4a15cf413d5L,0x615cea8baae1765bL,0x75aa831813f36885L }, + { 0x7d5b0bf7b8767cc1L,0xec38a8ff8022968cL,0x034805b62a07faebL, + 0x916f9eb033b7321eL,0x34963633c0c577ceL,0x8ee07efdabb8d3ceL } }, + /* 41 << 28 */ + { { 0x498606fc2d15a409L,0x2398e109d5fdcb60L,0x8ed8fcbc36540c3cL, + 0x94404e2bc1db3193L,0xe62b808b28db1c38L,0x545b60871ad1d686L }, + { 0xe8bf6489740f4264L,0x7ee76fe71809505cL,0xaa95b8c86f45a011L, + 0x9bd6111b55c715c3L,0xc5c736bc33165913L,0xf1e8cdf282f6c7a9L } }, + /* 42 << 28 */ + { { 0xeb09e7fa949d05b5L,0x49394c1b8d014014L,0x644874d73eb7abd7L, + 0x89c666e5679d2a01L,0x6ea98cbbd315bc8eL,0xd919142a37fa5a26L }, + { 0x042fbac56d0239b6L,0xbff2b086837c510fL,0x21e4d279d9883ed7L, + 0x6416e0239713c2b2L,0x3742c6d14ea05144L,0xff591d8fd5b00fb2L } }, + /* 43 << 28 */ + { { 0x0ae21b83c138ed42L,0xf1b0895a2ff30df8L,0x4d5d634d9559c6e1L, + 0xfd02f3a3098e5c4aL,0x7bc6b63152bb211dL,0x498a68fffb69f0ecL }, + { 0xd6fd5f443e69b479L,0x5ea1877d8c740d2eL,0xfaaff5f0ca605f02L, + 0xb3022f9839a03f5bL,0x3feb7c13aa253725L,0x119097a89dc33a73L } }, + /* 44 << 28 */ + { { 0xa0bd6c0da8a29345L,0xc676b6c55d7f5ef9L,0x303b6d7c20ad7259L, + 0x06542a19d8fe09a7L,0x5a06653ca959014aL,0xf45fd79a5bcfe0cbL }, + { 0x29058d984e583468L,0xf1bd25e60cd7afc0L,0x2a88246ef7dbe54cL, + 0x680eaff835e0ef3dL,0x5942c97f726e59b9L,0x43e971398d5c0825L } }, + /* 45 << 28 */ + { { 0x6656b318f7378bf8L,0xf9a838df182f1a29L,0x0d62dc5ede475756L, + 0x97564544585bcab5L,0x3e99f44c857a13cfL,0x8c3a0a940cbdde00L }, + { 0xa7be375833dd2d24L,0x629040f1bbb1c7eeL,0x0bb2ced27f0eab7aL, + 0xb86f1e1e9f474277L,0x60539a544a14ac4eL,0x9860f986aa90977fL } }, + /* 46 << 28 */ + { { 0x143fdef1fe944aacL,0xfd6700fdd24f606cL,0x5dad2e41737404a9L, + 0xb16c5d42953abdccL,0x132b5cd995be01c9L,0x2bf605d86fd01c6bL }, + { 0xed62526c8803881dL,0x3429579201788c26L,0x553f8e0f8d62ab25L, + 0x3b2df9cf9850ff9bL,0xb320ec40acb513b3L,0x86d61c988875dfe7L } }, + /* 47 << 28 */ + { { 0xe5fbda4daab3cc32L,0x556fcd2535d469a0L,0x414673d91c02fb7bL, + 0xc14ee9fd8bfe6a4cL,0x8ba0959d1133d9f3L,0x086a7c94e94338ddL }, + { 0x92c2f484cdd5a1b9L,0x97bb21f6ea0e0f9eL,0x99756b285411da59L, + 0x4b79c4663be739b3L,0x73502d3e706078fdL,0x6bb794100da7aea4L } }, + /* 48 << 28 */ + { { 0x2daddb11a406d4d7L,0xb02b5da5a2a33d81L,0xb73ce82721a6aa89L, + 0x10919587467506deL,0x0927724c428d8daaL,0x0ede991f7c17adfdL }, + { 0x8518dab1bf7ddb3dL,0x04b091c42a54e1b8L,0x5943c37f89e7a398L, + 0x8e63f5e8e273f6f3L,0xc6d0352b83143d22L,0x30e43182ebd1628eL } }, + /* 49 << 28 */ + { { 0x9bc5af5aedf58e50L,0x31a3beeeb0d51722L,0x5789fcf98cd467aaL, + 0x85d974897793faafL,0xcf09224ecc18f367L,0x4f293783ec7957b4L }, + { 0xb044c854c0be350cL,0x027caaf72a63996cL,0x5341b3f3cb85de2fL, + 0x0d261d80b106359aL,0xf63bfe7a8456af12L,0xa954c4400174c82cL } }, + /* 50 << 28 */ + { { 0xaf752854b02aceb3L,0x000c5c4222c194b3L,0x7e953b78ebd2e61aL, + 0x44dd61b4b9d68960L,0x282ef4216d454ed1L,0xffed862aa402ca61L }, + { 0x5fffddeed3e189e2L,0xf36379990daffe3dL,0x1b09a625857a8a00L, + 0x3e64ff63c1ced62aL,0x9acc484d10b63647L,0x5a470aef3afc8675L } }, + /* 51 << 28 */ + { { 0xe21acfec09ebdbaeL,0x512c66a729b064faL,0x15c08e1191835db7L, + 0x78fff5d665203a4aL,0x99259d961c73615cL,0x85b444b9f36024bbL }, + { 0x4909772df16932deL,0xcc4a526899a3863bL,0xe54557bd2ebff8faL, + 0x1a9b05b709bee4c1L,0x0d2ce396bdb2b785L,0xbd15bcec8ce7ef40L } }, + /* 52 << 28 */ + { { 0x606658a99991167eL,0xb8773e1572c4b43dL,0x6cb364cde025abceL, + 0xafa58e9b0c5a653eL,0xa7e35a54134a68bfL,0xcb831d42ba4d9db6L }, + { 0xae37348ede83ef97L,0x4ac64a6a62ddd553L,0x5feb5e0d715bb6b4L, + 0xf876efae043424b2L,0x7b56a291ad91a9efL,0x817c7053356f3adeL } }, + /* 53 << 28 */ + { { 0x0dbd99249e88115fL,0xecb57472bc568c61L,0xfa4f4a47c1058746L, + 0xb19006014d92c079L,0xe693577091026a8cL,0xebde8e65eefe8740L }, + { 0xe8bc6b3480a93b35L,0xc1c8fc0635518beeL,0xf7f4b448a47cdd36L, + 0xe4d040e0db4f3e42L,0x025fbdfb88345042L,0xfe6cc10f3fbe045dL } }, + /* 54 << 28 */ + { { 0x63ba344a1c20cb4fL,0x55f11c207e8cccf6L,0xe66e1641b5b1046cL, + 0x51cf6dbe758a460bL,0xe786a81e91bb5101L,0x6f4a976209cd4365L }, + { 0xe88b4d03fc565022L,0x46006d0ebfdf8ec6L,0x10a3e85781f4e635L, + 0x28ea91360a4a2e82L,0xf890ea9e757b38dcL,0x89c6789261312e2aL } }, + /* 55 << 28 */ + { { 0x8ce54e2a65d9fc54L,0x4776c1f13bfc0c09L,0x5d15fced99476b22L, + 0x2c5399bc1142dc7bL,0x6faef9d96c6ad87bL,0x4f238e48ca5126cbL }, + { 0xbc7136d607849dc2L,0xc840ccb1e30377a8L,0x30e0f0373a371bafL, + 0x5b8eef9bdfce4735L,0x1662184e514bb217L,0x010ebb8579e0918dL } }, + /* 56 << 28 */ + { { 0x3d6e8d6d8dff7dffL,0x6b6c194ad5be4ad1L,0x57b93f2db6fcd08bL, + 0x99f09948f3761f23L,0x4062f3d6ac8b018fL,0x4b58ac05a27af72cL }, + { 0x4abcc81504d0cdfdL,0xa50043e0bda4b02fL,0xe11297e527a9c083L, + 0x2b2d8d529779c5b3L,0x3de3d330dfdecfedL,0xfe2487caae7fc522L } }, + /* 57 << 28 */ + { { 0xc510bb0b7e7a66ceL,0x54a3e0111332f2c3L,0x6331badedc885f5cL, + 0x1a73c8aedc47d8b2L,0xc657edbb95d4e933L,0x30994aa335dc3ccdL }, + { 0x832d586fafe5be42L,0x3392b07ad44de522L,0x1bcea9a62982450cL, + 0x8237bf2b3709f75bL,0xfa4f2501ea9d03f0L,0xcf492df7bdacd276L } }, + /* 58 << 28 */ + { { 0x2d0f7f28af4ecf83L,0xc2863ae4d48229efL,0xc989ff3d7001268dL, + 0x7f07adb6ba225adeL,0x1564c1db450a15ddL,0x3bfea98c6524d417L }, + { 0xee3cd3ef2cc20833L,0x055c569dba767b1aL,0xef2eaf51351b1279L, + 0x4e02b1d163b809d2L,0xf0e943d00a14c115L,0x2bb3bc3f32f55210L } }, + /* 59 << 28 */ + { { 0x8f577dd79ed385ffL,0xdbcf0548a1fdcac6L,0x38555497c2352ff2L, + 0x33e2ed85eb9edab2L,0xbe4bd6db9e649ecbL,0xea3668f72c6e7488L }, + { 0x841627b8f4b91b7bL,0x2d61a0f7d487c7a7L,0x1932b198142d1dc2L, + 0x06dbb39a1a792783L,0x5be16e570bede1faL,0x4d3b197bdffceb55L } }, + /* 60 << 28 */ + { { 0x1c2fc5088f7a83e5L,0xa7c56233b9970c92L,0x949c71738bafa66fL, + 0x1e299b2d5bbb0490L,0xb9a79e7c18fcb9e8L,0xe6372ce69cb5cc50L }, + { 0x114fc628f465c6aaL,0xc55395208cb797f6L,0x7df94ed7a73ad211L, + 0x41eb8e1f8e0cd008L,0xb028725a004cbb0dL,0x1340186d372c1656L } }, + /* 61 << 28 */ + { { 0x5162886c203a829aL,0x60dbd8d464416392L,0x60589a51b5a10685L, + 0xa79ca259113476a8L,0xbf4f71100d7b37dcL,0x1a1b3fdf78bbb029L }, + { 0x2954d3454799a0bdL,0x7459eac788c256efL,0x61ac72653800707cL, + 0xd861f7764cc84f7dL,0x29f4e5bf84faae3aL,0x7975c9555aa1236cL } }, + /* 62 << 28 */ + { { 0x65f28419238c3c84L,0xf07d83ed90f1ecd1L,0x10307e1bf6567704L, + 0xa94dddb389d17845L,0xaa56f72788f39175L,0x01cf57e2a7aa55f7L }, + { 0x98f4340e77f21e8cL,0x8cd3e0a2adb036c0L,0x5c49ebf4af6b46ddL, + 0x312a2c32455f6897L,0x52fb4f488b517f06L,0xb0f373d442beff4bL } }, + /* 63 << 28 */ + { { 0xd9694bd9af44f9ceL,0xaf2cfbbc1ee29f43L,0xaf352b1c880f80ddL, + 0x3fdabd2142297787L,0xf5a2acc21c7916b3L,0x6154b3f2cc0d85f0L }, + { 0xb9ff2bea0bc58e86L,0x359eb0750561c3d1L,0xbb5a318fb93be593L, + 0x34af9320bff0b3b3L,0x3cbe89341d967c37L,0xd08e5f46a8e9a750L } }, + /* 64 << 28 */ + { { 0x4074ee27978029bbL,0xa9394bdabae0d0c0L,0xaa01d53972cecb4bL, + 0x4b0cf1279a7dd9c4L,0x3e3e3f165bc787cfL,0xdf48f7e1942de53fL }, + { 0x0cc69719567b9d0eL,0x631e33158d0d2750L,0x9fedc1e292314a09L, + 0x7547d22614a1adcbL,0x405561a48662b86aL,0x149fa2b1f5480b7dL } }, + /* 0 << 35 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 35 */ + { { 0x923d0b44bda4aaa7L,0xced14ce4fee29f7bL,0x1656be009cf5b87dL, + 0x13a37d0d1d61103dL,0x1d705880fb652393L,0x870a31bbed712ed8L }, + { 0x15ad02e6ad7c21e3L,0xf004e447c36c2831L,0x56aa376cba2b3ffdL, + 0xc3be2b2f9745443cL,0x47c8a870eb903660L,0x976c303e6c6c192dL } }, + /* 2 << 35 */ + { { 0x148bd39cf4fb80d4L,0x469b208cfff04e65L,0xf397fbe2ce548415L, + 0x441e5c2c87fdde9fL,0x6366b49ffee9c179L,0x38d02bd32938dc71L }, + { 0x26d450fac49c5444L,0x4569f95d2b23d3d7L,0x5f68bf4d298fd876L, + 0xe86df047544768b6L,0x40b69a32f8491267L,0xcbf3adf9f917c71aL } }, + /* 3 << 35 */ + { { 0x32498d4d8125489cL,0x965e8d07a5a46ae0L,0x6cea5e47e96a7e29L, + 0xf78293a4668039ffL,0x62548a96f63edd32L,0xe8e6af95a83e8256L }, + { 0x76e60c3b0db6263bL,0xa1ee4b0621b3d668L,0xa17dbf8b9e49b0b5L, + 0x4b29ba127eb366fdL,0x5e0ed781d29b565fL,0x8cb50d53199b36f9L } }, + /* 4 << 35 */ + { { 0xa66c703529aa3150L,0xd038a5ab479e61fcL,0xdee33e96b5ab5410L, + 0xd068929c7c57d123L,0x0839a208f1d6ad37L,0x8f523dab123f8178L }, + { 0xb3e5e524a67d3840L,0x88bda75e52eb59dfL,0x513a0ab7389f2dd3L, + 0x3197a145890bba6fL,0x61add75b6f66bf09L,0x5c9dfc154eef1722L } }, + /* 5 << 35 */ + { { 0x66dc285007769b1bL,0xe07fb7414d71fac4L,0x5ae688a6c2abbe60L, + 0x08ae92fadcbfd296L,0xbc291256b43044d1L,0x0e1d71ed9fcdf213L }, + { 0xf0c5b28102485685L,0x5d3f9302e3f68f42L,0xbbbfac50ffe4f036L, + 0xb5b5f26174fdba44L,0x4ebe1d070d746760L,0xbb0f7812c37f04b7L } }, + /* 6 << 35 */ + { { 0x810b6ab36df1199dL,0xc229308bb4f293b7L,0x3cf838dd89897750L, + 0x3e391e4e7a336c9aL,0x70148337176f89c0L,0x54b15bacbc4f1e22L }, + { 0x32b104f92c0f2885L,0x2c39cefa67034f2aL,0xb8310437bf178ac1L, + 0x722299f5c99370d5L,0x0a493cf0332b93a8L,0x00e0ab41a420f719L } }, + /* 7 << 35 */ + { { 0xf25925434cab24daL,0x52be9bbce7c3b9c5L,0xaab7a8b64660d1a0L, + 0x09738b819a9600f4L,0x58f0c86637de9e3cL,0x0aea5cc15db31f4fL }, + { 0xe480406f499868beL,0x0d8fc7f0f6913a44L,0x7282364435f2e14eL, + 0xb147b31045e37a93L,0xb1e7aa5bf15c1af7L,0xa8685068b03e7713L } }, + /* 8 << 35 */ + { { 0x21feb7fc21c34c2bL,0xab6a553addb0140eL,0x03a6557624b04e6fL, + 0x2531f186342cb0adL,0x088c4d54a24f6426L,0x9a0ee15c06a873eaL }, + { 0xdbe0253fd33bc748L,0xdad3339f5db8ac9eL,0xeaaf368173e65901L, + 0x71f1fab2ccbfa504L,0xb7b845224b0e163eL,0xe0fca8373c779f3bL } }, + /* 9 << 35 */ + { { 0x710988eb46baf373L,0x8cceb935b57d5018L,0x1864603fa45fdf17L, + 0x3dcaae73ef48e6d0L,0xadd9420b590322c5L,0x947783e39b135f67L }, + { 0xfde763688bf5049fL,0xf00e4c182caa4023L,0x4d3b0f23d355b3d6L, + 0x181fabcc20d5799dL,0x29499b40ab2ad0afL,0xf6e66328f9a938aaL } }, + /* 10 << 35 */ + { { 0xcd7b3c42bcbe922dL,0x2fe02b3b95dd1a5cL,0xeb66bcbd24ef5c38L, + 0x7edcc21ce579c309L,0x7b19d49116f6c900L,0x36019ecdb6317c2cL }, + { 0x554ba55391d9001cL,0xa5e30b9814f31e44L,0x3d1fe33bffda4032L, + 0x5dfec4782306675cL,0xbe59305e000c91e7L,0x3c4e52a325a6b879L } }, + /* 11 << 35 */ + { { 0x02fcc14ec5ea88acL,0xca29bb6d56d093b6L,0x876aeda90e6fe94dL, + 0xfa11a142d7225a9dL,0xfea3ca053d03fed8L,0x435854c6c54d5962L }, + { 0xd770737454a6dfd5L,0xb8960017a3e55d02L,0xd4015a0c04d65c3eL, + 0x397f93d1e98a1204L,0xb0efa2e55f3ed850L,0x18f244698a3ec67bL } }, + /* 12 << 35 */ + { { 0xa35802f5d62cd9f9L,0x0ca9c15d4148436eL,0x261a991d472b9d21L, + 0xd81a1ed6a2f8e875L,0x942f213a699b6d63L,0x041a12fc0ae57758L }, + { 0x61191c82bd70aabbL,0x3776eb8bee4c23b3L,0xabe23e8652511222L, + 0x66dd967d30dabb91L,0x77650c597ed27424L,0x08ea2ebdab25a050L } }, + /* 13 << 35 */ + { { 0xa410ba3ab6cb5a02L,0x6eb40d15d07c5c6bL,0x0de81e9107dcc811L, + 0x996f46eb2631b7afL,0x5a350ba75b7a22f3L,0xf42b24e7634159afL }, + { 0x07bae0abc30952fdL,0x3488cda2d644e0b0L,0x23ae40d0e2111e12L, + 0x650af54ec80cdb56L,0x0f33a30b7d4aa2a8L,0x4e8d3e98442a00e8L } }, + /* 14 << 35 */ + { { 0xa624ab3759a8bc95L,0x4b7e3fa61c971228L,0xe8229c4273aa694bL, + 0x0cc31029779288abL,0xf8eff30f57575e0eL,0xee5e01947d52803eL }, + { 0x32d87e558a78f632L,0x48a06031e454904eL,0xaa2cb8dd16c6e626L, + 0xadd098ac2c140452L,0xd25f285d2d3031b1L,0xfb5fbbe175b59543L } }, + /* 15 << 35 */ + { { 0x2297041fd7a21503L,0xfe7738c2657f03f0L,0x994a8deb168fa34aL, + 0x0c772e02a53c4fdbL,0x67f835d150124cd3L,0x0e0d26356993cbbeL }, + { 0x9857ed845257f11dL,0xdc23a728ac556942L,0xf0e1bb29deb32a7fL, + 0xb8c3c43fee0d70f4L,0xc294b0efc60ad214L,0xa4d438dc679067caL } }, + /* 16 << 35 */ + { { 0x520b0bb905c755e4L,0xa2c2c59bf89f0048L,0x85c1c73a73c23975L, + 0x6e4dec49783aabbaL,0x69f0c69bb0463155L,0x61a42b949c97b17bL }, + { 0x55af24a945d331a3L,0x4b0e63f8f5fe81fdL,0x4034283d708671c4L, + 0x200ddab35fd9001aL,0xe45f28e4342eaf3bL,0x3e8375b41ba936c4L } }, + /* 17 << 35 */ + { { 0xcde014bbc613b1faL,0x5ad97babcdf992c2L,0x9fe05b9fea13e2d8L, + 0x93b553e290c4031fL,0xd62bc0818c727bebL,0x284fb61f888306caL }, + { 0xa63f8dcd1101abd6L,0xfe02dc120e962b27L,0xab169958115301e7L, + 0x8822f954462209baL,0xb3ba3e721198428aL,0x9a73ed38d74c88f8L } }, + /* 18 << 35 */ + { { 0x7db497e17da2f887L,0x0995648b683f3507L,0x50e3ff74f5935bd2L, + 0xdec083e2708c88dcL,0xbcc3bc3125129bccL,0x7a3fd7a80a407b41L }, + { 0x46ab826c25e0ab93L,0x28e891ec54944cfcL,0x637be168f55c6cbfL, + 0xfa34e9942a65216eL,0xd23e99afe3a43c84L,0x6d09d189e6fd958bL } }, + /* 19 << 35 */ + { { 0x8aa6ca1381bbd283L,0x3a0633f4ee167a15L,0x7f297c8b9e3b18e6L, + 0xbead8a50c71fea64L,0xa11b2fdd457aebbfL,0xd7fc286f85bc7bd2L }, + { 0x2922ae5bad1c9d9dL,0xa07741c2ef9ac174L,0x24dab2d457fa8f9fL, + 0xd7078d946116a870L,0x4b45107834117a37L,0x19a4dd21c73c857dL } }, + /* 20 << 35 */ + { { 0xa2f9b4e4bac5d14bL,0x9f904a3eb8699164L,0x63585978fec79b4fL, + 0xbcc9b60ebff45cd8L,0x2e515592a5d63de5L,0xc47a048c3bcc637aL }, + { 0x0523810643aba777L,0xf6818e4c77e67aacL,0x9d5827d238f962b3L, + 0x28a904c6a003988dL,0xc06bc833551f4575L,0x61f6bcc2221cffefL } }, + /* 21 << 35 */ + { { 0xf7cfbbe5055a5623L,0x1f8af775e66d2a5bL,0x0cac440268831d8cL, + 0xd25185890d0e6f2fL,0xf17838a3182f90f1L,0xefdf6f20737f163dL }, + { 0xc3198af0542242e9L,0xf77c3d28209efb0bL,0x1df6d0da8de7be08L, + 0x22ef7367901a6590L,0xfa9b4af44b776d27L,0xdc49102c88ace4f6L } }, + /* 22 << 35 */ + { { 0x60c7d148bafa9cc9L,0x0afc5fe2516b87fbL,0x02e20acff795ff60L, + 0xd1ba069151f32975L,0x8547e7f757be2399L,0x4bdf6abfa0d1b33eL }, + { 0xc793832fa06077f9L,0xad55cccb2d874993L,0x5e217b27314387d8L, + 0x744d7b06e7f2ec4cL,0x761aa86d24fa58b1L,0x41400d9657dd313dL } }, + /* 23 << 35 */ + { { 0xd17f68da759d20f0L,0xc141ca6827b7eaa7L,0x3796db8bdaff5c66L, + 0x067119dca1e5220bL,0x174f11777158ddbbL,0xa80365d8cf8bf75eL }, + { 0x0a79f74933567f05L,0x8c2826123c99bb4fL,0xe448c2bdcd6ae726L, + 0x1ae05aac2ad4b0e0L,0xf90dddcb16442420L,0x37465a1ea75c28e3L } }, + /* 24 << 35 */ + { { 0xf58e05c53178468fL,0xa17c8b868328a2efL,0x1bb22cb44ce0c2f8L, + 0x1ab807b51aab9089L,0x2aafa8c91e76fafdL,0x58cdf95fb4801546L }, + { 0x2c1e4ef8d5d699f1L,0x1583a2aa4cd433bdL,0x571dcaec7f4f9b10L, + 0xf62b696b27156c5eL,0x77d2443448820bb9L,0x94e4cfcc11dd3e55L } }, + /* 25 << 35 */ + { { 0xc3fd1feac00e6c7fL,0xf4e42ddabd322507L,0x1ce3e0da023469ebL, + 0xf81769d2d788b1c2L,0x505cec4c62353342L,0xd4049907ba759922L }, + { 0x9ff98f06618ee939L,0xfa63b3606bd55f31L,0x3fcce488cc4d2515L, + 0xeb6e92e91d629e19L,0xcae4190bff892af7L,0x3e7b780dca80cb44L } }, + /* 26 << 35 */ + { { 0xbc923fdfaf54b58bL,0x2aef31d88767acdeL,0xfbebb8f07f28a3d4L, + 0xce5feafe694fe977L,0x606afb0ac9da1ee5L,0x559866a0b74f7c42L }, + { 0xd935191fdc85f22cL,0x5c3002d7c8ce3240L,0xecd278c198452214L, + 0x665b3176821a3606L,0xce05a914baf26fb7L,0xa178860b60e4e8b8L } }, + /* 27 << 35 */ + { { 0x135c82b55000cc19L,0x34537edf8b2c55b4L,0xfcb6aac2b37acc8cL, + 0xa882e25e8ce8d7f5L,0x531756e98c7ff1eeL,0xdcdaced9ad6312b0L }, + { 0x309a469b7f3aef9dL,0xf306e32588d8772fL,0xe7e6f3abd4dc0d90L, + 0x816b01ae49878940L,0x1cb084e84ba5e2c8L,0x395af25b005d08b3L } }, + /* 28 << 35 */ + { { 0x3832cfd59093efcaL,0x3fda8380ed8b34d7L,0x874ec122e2bd4004L, + 0x3761e9c44270b9ccL,0x6eb2fb1166e640d5L,0x2a45ad23e6dfd0fdL }, + { 0xdcb3272bf8dd082cL,0x7d84341f17486485L,0x0f46b1fda4ca2644L, + 0x81a1ab1e82baf37dL,0xbb1d72713b322f65L,0x1571e326f4038252L } }, + /* 29 << 35 */ + { { 0x4e00aa41d9acdec7L,0xb2b701bf9f80dff4L,0xc366ce97d5e71e0eL, + 0x28c2b4e9ed09255bL,0xef54a1a535086ba6L,0xee2e43f2a1c8b39eL }, + { 0x346f22f5d9143a78L,0x71fc5c06f1053377L,0x1789f7644737b5bfL, + 0xc9f83ee8b0df2648L,0xf91a29e9073ee793L,0x18eb801e3ab450a1L } }, + /* 30 << 35 */ + { { 0x1c3df0914085f0b6L,0xc60c47f5cede211bL,0x7bdead8650b6e857L, + 0xc68645be2cf9aad6L,0x8d970a94d01540f6L,0x9346f253782ec6a1L }, + { 0x3da31263c1b23981L,0x53076158dbabfb68L,0x22947b9f743dfba4L, + 0x872e60061c56f47aL,0xe973d81c2b3b8417L,0xb98216184b1fed56L } }, + /* 31 << 35 */ + { { 0x29fa699b8873de48L,0x64f9e1124932447fL,0x4fb0e009e4c20d43L, + 0x748a0cdf78016262L,0x4891badb7bd23ea8L,0xf1300a437f56368cL }, + { 0x178efa9de8f1f8bbL,0xc31cdb4098a31dd6L,0xc2d5bfbad2c43f9cL, + 0xf377e2cc8678d990L,0xd42d274808d19833L,0x2d72fd4de5ad5e63L } }, + /* 32 << 35 */ + { { 0xb083ba6aec074aeaL,0x46fac5ef7f0b505bL,0x95367a21fc82dc03L, + 0x227be26a9d3679d8L,0xc70f6d6c7e9724c0L,0xcd68c757f9ebec0fL }, + { 0x29dde03e8ff321b2L,0xf84ad7bb031939dcL,0xdaf590c90f602f4bL, + 0x17c5288849722bc4L,0xa8df99f0089b22b6L,0xc21bc5d4e59b9b90L } }, + /* 33 << 35 */ + { { 0x44e6089f006e422dL,0xb4a99bc45b029c6eL,0xd14bd00e6f289edcL, + 0x8ebbedfa25c50773L,0x5bdad80851d3ade5L,0xe4e70c3094727960L }, + { 0x29b759e863ab2622L,0xe20ad36b134d5982L,0x27c8387f4070e06eL, + 0x9fae222556593896L,0x299a0f0c3b199172L,0x476fe70977a39ca4L } }, + /* 34 << 35 */ + { { 0xc91a3d2ef4d0d8a4L,0x450193a819e05a78L,0x0e59e0b89eec69eeL, + 0x2ba20f00138fbf46L,0x5c9fea780e8ae694L,0x62c81c8cc6b73372L }, + { 0x2a1df446ff0997a2L,0x929364ab692bb930L,0x4c4a956436cb618cL, + 0xc55020a0526be5dbL,0x151f18a02c64c026L,0x2ec5becd61724143L } }, + /* 35 << 35 */ + { { 0x139c7d788713439bL,0x46f7bd4b1e19b1caL,0x74259a28b47977d7L, + 0x89a912cb8ab1817aL,0x4428e45f06419142L,0x11b9c4836b34a2d5L }, + { 0xb613563a29487118L,0x81f4502ab6249a60L,0xe28685843d4ddecfL, + 0x138c97297bd250dfL,0x733f2201aaac4593L,0xee6b85ad5d061887L } }, + /* 36 << 35 */ + { { 0xbff288ed74006fd8L,0x388c5a34ded657eeL,0x47d400a2d61a2995L, + 0x54c684af1eba1f65L,0xd1ba6975b1b4452bL,0xb23dda26f2f8283aL }, + { 0x6bff7acf86803147L,0x839571e5e8ea5923L,0xc89e1048dbc4ccc5L, + 0x1fa0221120102232L,0xbf7b8f902d4e4406L,0x14c5de43576aba0eL } }, + /* 37 << 35 */ + { { 0x6c55807bfd2f9b11L,0xb01d9f7239e338efL,0x94f6531135628879L, + 0xae51cf0b0ec6f5b4L,0x387223cfd36b9719L,0xeeb02cc6f2fb192cL }, + { 0x867611ec43c9e89cL,0x5b15785f97930887L,0xb792b88b57ab078bL, + 0x0c54de110bdc03cdL,0x5785811a30d0eee3L,0xb73bb98436b88b00L } }, + /* 38 << 35 */ + { { 0x0d0ba3c06fba6f94L,0x7f7e0f5cf29713c2L,0xa8cce53ba6b94d6cL, + 0xbea99382df40fd27L,0xb3ff1c56bcd4f8b2L,0x19124644418f108fL }, + { 0x6fc5260727c26f18L,0xbc5e23d682c7c8f9L,0x12aa5e8e099b8cb3L, + 0x9d94d88614c579f9L,0x5c629d7a47395f32L,0x9cd280633efbbea0L } }, + /* 39 << 35 */ + { { 0xf0bbf8e88edb7b56L,0x9a76ad71adeb43ccL,0xd99a92528643e982L, + 0x6468ff05cf17f5b5L,0xe6589476d56b985eL,0xdca4273cbe446b3dL }, + { 0xd430e3a47b9dbac1L,0xe075c00f4cfe735dL,0x3ba43fef12395845L, + 0x6895f0c3dcb49ce9L,0xd868006aa92843dbL,0x968a8ceec0d5bc9eL } }, + /* 40 << 35 */ + { { 0xc0387b57f440fe92L,0xce8bad38e291c443L,0x022052e5f9e88be0L, + 0x6f949fe261615c9cL,0xf4874e2d84725fc1L,0x06fb244b73a394ebL }, + { 0xb70553c678208bd8L,0xab1829c028704d28L,0x1453ee1a807b160bL, + 0xa1da80c34649d33aL,0x072e02e056c32ee1L,0x79baa98f3f590646L } }, + /* 41 << 35 */ + { { 0x1613a710b0fef3f2L,0x9ae438012edeec54L,0x07824d08579c3130L, + 0xc2beaf806ba2b1fbL,0x7df3c459fc9e85e5L,0x8debf613dbd63acbL }, + { 0x2774ab78f04f3526L,0x36e7ff55a5285219L,0xf2adccaf4ab04c77L, + 0x14add3d8aa43fbfeL,0x387e4965e3026ac4L,0x154801a1c77391ddL } }, + /* 42 << 35 */ + { { 0x28687291933bc404L,0x6a13b0cc9ba35fa8L,0xd3d1746931c5d126L, + 0x1c81ce5df9727cfbL,0x14f66be860b464eaL,0x0bbdefb8c10ea9f6L }, + { 0x5679a0e5e8d06c95L,0x380161d83dbfd6e3L,0x6cdd31f20523e6d1L, + 0x2ff419e0c4b4c439L,0xc7439153e217782cL,0xb1b74383f6dc5d95L } }, + /* 43 << 35 */ + { { 0xcf0d1d2d03746e38L,0x8476c982916e077eL,0x93de41516dfdc6d3L, + 0x15010d26b78cf13fL,0xbab5a5de97cb08c0L,0x37f0673014a31939L }, + { 0x777c709f6819b0f4L,0xe3c2d2f7114a32e7L,0xf0227e19ec047092L, + 0xe1416f34b817e1e1L,0x4d7db41419c6c3f6L,0xf12a13a9d01aecb1L } }, + /* 44 << 35 */ + { { 0xa09e68e61f023abeL,0xbc432449aae2d6c8L,0x61e22f727cb683dfL, + 0x0b5bbc0fd81a0e89L,0x18ea4e774581f128L,0x28df9961cd70a12aL }, + { 0xb0d3b19f8b8bc10bL,0x0805d1439844e7f8L,0xe3ed3d40675ab6a9L, + 0x026d1200f75e2859L,0x1802457b8bb10969L,0xf94c62b3eadab8caL } }, + /* 45 << 35 */ + { { 0x518e9c4220d03ce7L,0x6c44676187811010L,0x07ff38f99d9be611L, + 0x5c2bac105cf0cfd2L,0x4e5cc677d5881c2dL,0x02dc395f08e39281L }, + { 0xc3ef99142044f4e9L,0x0203508c20c8c831L,0xd1276c030e0524c9L, + 0x5525c0af5402f999L,0x5c9a43aa49c2371bL,0x6d7b6700d28cbb59L } }, + /* 46 << 35 */ + { { 0xdec3ab0f7bae55e1L,0x6bae4baf56152625L,0x1d597c0c839b5d6aL, + 0x243692a966b3b169L,0x37f2ca8eb01c6d34L,0x5baa355aae5c05baL }, + { 0xe0b84c28af384b13L,0x6a2c9386667cd513L,0xc361a75d78319608L, + 0x0c317ac596ca528dL,0xe243aa8672f0a5e0L,0xedcf9f5fa1d1677eL } }, + /* 47 << 35 */ + { { 0x88e5cf3f74a0a7d2L,0xa25a3883cac23d4fL,0x7be2fc2ba6eb3d72L, + 0x188be28d391326cdL,0xeca6aa726f3db24fL,0x237cd6f70b9a11a1L }, + { 0xafeca5436fecffeaL,0xa32291510e6d18f3L,0x46699e2500dd8b76L, + 0x5edb4b1a331eaa12L,0xecf6d8a472ce0658L,0xd91af8da6b80e9e2L } }, + /* 48 << 35 */ + { { 0x7af5da7b63ec62d4L,0x74dc387261dbdee2L,0x7d08dbd360b519a4L, + 0x4e785f79459ef257L,0xe3e7d5a485fa9e7fL,0xea60c815e9b5665fL }, + { 0x2e570d18c209caf9L,0x7bae108371818d1eL,0x5db42a0a398d749aL, + 0x149740ff4f555604L,0x72e4f06bbcee0abdL,0x0ecc0cb581ad0830L } }, + /* 49 << 35 */ + { { 0x43550eea0a34451dL,0x8b0b97e9c3aa33e3L,0xdd974528da22dbdeL, + 0x0337c64dabff3ed2L,0xb50da9e9230cc211L,0x931f891c004d17d0L }, + { 0x8b7f9ccbff366019L,0x5483938033d76a4bL,0x52fceec1950ef740L, + 0x5b19b50cd18125d1L,0xbbb661f55b9011c7L,0xfbf0ec747beda7fdL } }, + /* 50 << 35 */ + { { 0xebca6bbec047276bL,0xcda078e05c3018c5L,0x4620dedda223af10L, + 0x962f389ad02fd60cL,0x901fab93baab3894L,0x5ecbbd7506eab11eL }, + { 0x865dc95e62203b9cL,0x04a599844acf85edL,0x877e94647607236eL, + 0x09592a5684609563L,0x6535176ace76d699L,0x44f2d997ce8812e9L } }, + /* 51 << 35 */ + { { 0xa09c9ab62285b330L,0x6058d94a9b145627L,0x7b4b4141da3c3571L, + 0xc9347a16033b665cL,0x95e9b4f01a33d052L,0x35520f3cd46c67b1L }, + { 0x24938cb136042a9aL,0x5eeaec9de73b7354L,0xed47914931f08616L, + 0xb0187b2b713a2114L,0x03c49947e3b76d73L,0x79b5778a2e94fc7eL } }, + /* 52 << 35 */ + { { 0x6bb19d2162de1ccfL,0x3810bdb3339162c2L,0xeb56c72b6aa09df6L, + 0xac66c58d1d415050L,0x922cd7e74ad9cc85L,0x09e3585f91168090L }, + { 0xffc9a98d31b918a6L,0xc273e186c73c7513L,0xd506753f12a77342L, + 0xe288a471e5edd613L,0x0f358d310cacf05eL,0xfbadfa2d9a63fcfcL } }, + /* 53 << 35 */ + { { 0x020e282989cf155bL,0xa1fa6eaac7f481edL,0xba422e09c5c89724L, + 0x43da4df7cad8186eL,0x1bea459cba3ca738L,0xe9f0afdd0c64bc9bL }, + { 0x4c3b3b8e3592686eL,0x7e6938a7b43ea3f7L,0x8e01a54e7ba7dad8L, + 0x33ecd36ea9c68839L,0x1abd6e125e7e993bL,0x29947e126531feb6L } }, + /* 54 << 35 */ + { { 0xb0fe9b7912a193a0L,0xfa19ad4be4bbd264L,0xd5bf0e5409918851L, + 0xd07d8e5729cf45b0L,0x228e67cc7744259dL,0x786ea24843ed0fc4L }, + { 0x7f700231873cd08dL,0x394db4a70ef49109L,0x699047c06a8197f7L, + 0xf5b168443021ff8fL,0x4c8bb55026621cabL,0x6f28b013065208f1L } }, + /* 55 << 35 */ + { { 0x2fb3a7601f809545L,0x8006902ae93849c6L,0x37cc848c9bd9e1bcL, + 0xf4cd31559d0f6340L,0x357772ac4baef442L,0x0f46d0f77d533f1bL }, + { 0x4121411fd9c12bd0L,0x304083dedb70e364L,0xff6b7a1ccecbeb3dL, + 0xb444b5972aadc899L,0x29ec79bfdb8b3731L,0x864d8d917fbd8982L } }, + /* 56 << 35 */ + { { 0xa79feacac241c5bfL,0xc86df4c017861e6dL,0xaecd1722a699282eL, + 0xcce5e345a0464190L,0x0a79c23deca4f6d4L,0x64603ff16a6e7967L }, + { 0x02e24234aa7312c2L,0xa9e1fc7791a1b587L,0x1daef29f94526a4bL, + 0xa7db710a62ead861L,0xb387fec78869446bL,0xee2171015db19f08L } }, + /* 57 << 35 */ + { { 0x79a0feabe64fb245L,0x5799eea096a4e94cL,0x2592e7a333b063a6L, + 0x2cac3c2ef1063574L,0xb9cea04a7f4755d4L,0xb8e40abaa0bf858dL }, + { 0xe1723d963ffa32a3L,0x6547b4402701eb1eL,0x16ec552a4da9b337L, + 0x75f7f4a8fe0555eeL,0xf97e465014f1c2b2L,0x5495fce3d9ccf8a2L } }, + /* 58 << 35 */ + { { 0xffd160fb62c1b457L,0x62efe01fc4d91f7fL,0xc54f75b5208dd413L, + 0x089514d3e78124d0L,0x752a9ae8c2945054L,0x466636fbdbffa78bL }, + { 0x32936281a265949eL,0xd657c0f084b4d11fL,0x199d8641af455a47L, + 0x1eb24cc7dbd9852aL,0xd2ce80f856bfbbafL,0x1b31b23ceb862890L } }, + /* 59 << 35 */ + { { 0xc866d2a5fcd5aaf4L,0x4ac2b7f57e21250eL,0xa78cd3cbc50b4a92L, + 0x2485c3435a5c541bL,0x555db4dc7ef371eeL,0xcd9d6d9c1304f782L }, + { 0xae86a22974b4d57aL,0x68c93bc8dd4cdd8fL,0x7b95411098b9fd49L, + 0x0dd480b9399d8d4bL,0x0e27be29f2665c52L,0xce8a1ef9d920a5c8L } }, + /* 60 << 35 */ + { { 0x10a6bd0cfc0395b9L,0xe30bf6d06a5e8107L,0xc8aa2483167930d4L, + 0xee75885006e7e1c2L,0x4ee64cfcedcb7788L,0x9498e9bbf2f1d7ecL }, + { 0x084d2350ae0fcdb4L,0x4398ee677f4d25ccL,0xc1ddca395db85bfaL, + 0xefd4819747961197L,0xbd16037f2265195cL,0x1c61a6fc56daae6dL } }, + /* 61 << 35 */ + { { 0x640cf6b17f7c8c50L,0xdffddf2209d44051L,0x837275314e3c038eL, + 0x3164d1875aa8d8a1L,0xb37590bcfceb1066L,0x5e4fab4200d489f6L }, + { 0xc1e5dca3f8105ea2L,0xfdd1b0751c7f8679L,0x571d7dd14f14ac54L, + 0x84cc453155cfb741L,0x49d0b1be48823448L,0x8365f1f3f798b5d9L } }, + /* 62 << 35 */ + { { 0x9f2409cb6a564a3cL,0x9266799ae5134e54L,0x39aa3697fac47921L, + 0xdf3db1f32c0b4dbdL,0xfa37a085f096ec03L,0xb99cfe05afaa0f3fL }, + { 0xc9e00e43df458860L,0xbeb7e60ace2bb0b0L,0xdfe2be57cac8d7e0L, + 0x6ec03d799162b2ffL,0xdfe3a6225d1122dcL,0x9f04dcc8b6014310L } }, + /* 63 << 35 */ + { { 0x30471bf9b42ba5c0L,0x19073fd0c9d26763L,0x92817e8059c1017cL, + 0x29248f743da195b3L,0x029d7e7be928767bL,0xf1a3a08a049a0080L }, + { 0x8ec4f3e6e20c1d68L,0xae815a11f3ad30feL,0xdd0a6083f76f43afL, + 0x197d29fe49465bebL,0xf1a40ae996316f4bL,0xec47d65e59bafbc0L } }, + /* 64 << 35 */ + { { 0x6f57752951c2bb65L,0x4a0c1c284b874bdbL,0x19a1842778b96c6dL, + 0xa674f9922f593505L,0x5abeeec46b7209d6L,0x42d15d0147cf5fffL }, + { 0xe24509b7b49e3b4eL,0x81be939c639ee6e8L,0x7f7daf595761e8e3L, + 0xed5cfcb8d420a288L,0x365b29eb7a0ff696L,0x7d14680599a1ac8fL } }, + /* 0 << 42 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 42 */ + { { 0x9ee1ec3aadcdaa68L,0xd98c498fdcbb6548L,0x32b9737588102ac0L, + 0xdd296cf9c08527f4L,0xb74f8145fae3dfbeL,0x84131eb96cd7cc4fL }, + { 0xa0f2fe7a927ff15bL,0x6b0ade4deee1a4b4L,0x6e7df2d40eeb90a7L, + 0xe2f46e20be4de684L,0xcd28feba3fdd06bcL,0x8e4205aee6d6d9f6L } }, + /* 2 << 42 */ + { { 0x35d47426f78d33efL,0x4af25db28440c42cL,0xbd6a15e22e91bf5eL, + 0xe366a84cc08b6b1aL,0x759c122f55b97de8L,0xecec558f08a03f29L }, + { 0xdcc9fca2ea9d2060L,0xb3e49b8e9f361fe1L,0xdeae39029b59cd04L, + 0xf532ede06f5e5bd4L,0x84fbeeb936099f4dL,0x73576b1f088d2052L } }, + /* 3 << 42 */ + { { 0xee43828c6b512bc6L,0xf73dc9f550b91e60L,0x68f23f30f5dbde6bL, + 0xaf2fe9e3ddd15e00L,0xfbf34dae86578d49L,0x689796556c130010L }, + { 0x137a5fc309942897L,0xff1f0bfe9959f06dL,0x2dd0a04abd7ee14bL, + 0x59c46072e54e2161L,0xf470bdaeea7518adL,0xce556e4340c471cdL } }, + /* 4 << 42 */ + { { 0x2ba8c79022b25f2eL,0xf4670a511af0f4a8L,0x6842f36a2fc2451eL, + 0xfc5c9558bb91e1e3L,0x035d1dfcc3ead762L,0x3d0721cb031e5556L }, + { 0x3af0cc813af18a2eL,0x7888cee2bd11a363L,0x80c3de0a6ade1d12L, + 0xe8c3a5bd93b2dcb5L,0xe3adbd7c90a2214dL,0xfe8646d51192948dL } }, + /* 5 << 42 */ + { { 0x9214cd4bf1c7ed94L,0x4887c7c63738f386L,0xa72ba72bf623e542L, + 0x3c52a464f67d6004L,0xcdb6171d09b9a4ffL,0xe5eb77d160aba627L }, + { 0x7aa9836f39d6afdcL,0xa3fa3a520e0a1e18L,0xe90bd925dee3a4c4L, + 0x47e8eeafd9a94dcfL,0x34302a4921e16feaL,0xe32a62eb8ae23949L } }, + /* 6 << 42 */ + { { 0xd1d70db31df1d1f2L,0x22ebc9bd9fec1f42L,0xde5ac585d11d3205L, + 0x0e4584ab282d4d6eL,0xc87607928f78b85bL,0x48a85682af1fbb6dL }, + { 0x64d012ceae0947bfL,0xab792bbf25e22366L,0x250d40d4a3a030deL, + 0xe9b49f0877e26b9cL,0xe7d30c828c0f2249L,0x2b77b40b97c676a2L } }, + /* 7 << 42 */ + { { 0xa89144b89efc8fe2L,0x23625c36e13b79c9L,0x4fdea1d3a047ad35L, + 0xd0b0ee0d4ae78e01L,0xc224b3f3eac4e606L,0x4360e8acfa41bd81L }, + { 0xb2c69238062437e7L,0x86ce8de0decd1245L,0x2ce4be3dfa9d07bdL, + 0xfd09aa853d268d06L,0x4cd874264a162aafL,0x1b28f72e9d45e849L } }, + /* 8 << 42 */ + { { 0x65026297ba958101L,0xbeb4adf98eef151dL,0x623763a460c8bbf7L, + 0xfa8f5ad78b2a7120L,0xfd744bdf085497e7L,0xf9b6f97e2ba35618L }, + { 0x0cebfe9df8a15e86L,0x47a6d01329576088L,0x655817a3fcf19627L, + 0x30ab44f7c2f11261L,0xbb001c9dddf2c850L,0xb45c7eff073260c3L } }, + /* 9 << 42 */ + { { 0x609a02d031716f88L,0xdff6246c45421ce4L,0x544f3162142838d9L, + 0x8842dcbe36b57d38L,0x2818919c57f561e2L,0x87f5acca318373aeL }, + { 0x42773fb72edf1501L,0xff92c38648e9d8a3L,0x21a81668ccd5a860L, + 0xbac5cf837328cee1L,0x7441f749ddc53a05L,0x987d3a1cb5abe243L } }, + /* 10 << 42 */ + { { 0x3b7c44f8fb90e50fL,0xeafeda047cc384fbL,0x9a33e377de65e34eL, + 0x303f568095094a58L,0x4c0f2e932292809cL,0x920c9c12160b30f2L }, + { 0x31d14e1414b268d4L,0x9964173f1eadb1dcL,0x8e22b362eccb0f39L, + 0x81dccdf83bf9ece1L,0x8e2fda43a40503b1L,0xdb647ac13e112199L } }, + /* 11 << 42 */ + { { 0x9c23216f096c21adL,0xae259a6d41fa37f2L,0xefe0a8c9efe96f6aL, + 0x5631701dd6a27744L,0xed8d0219b3017563L,0xbe2723bca0867a0cL }, + { 0xe02bcb56687b62cfL,0xf26c0f77b96f66a9L,0x43e46251fd16fa3bL, + 0x206a180a44033302L,0xcfa96b556121888eL,0x50567a7789dabe7fL } }, + /* 12 << 42 */ + { { 0xb08fb1175cf3e702L,0x7379b1978023df0aL,0x73aefc7b6f954966L, + 0xc0fb886f76bd243cL,0x871eacc5ce09d5a8L,0x9f55b0a4e773f049L }, + { 0x92945c84415d725dL,0xcd57391f0112ad84L,0x4762bc1d0509d73fL, + 0x15cf97f10f1af175L,0x1f855695328c160fL,0x32cb87263b439f0cL } }, + /* 13 << 42 */ + { { 0xb27e344ae6361abdL,0xa53690eb474027a8L,0x500db02d683a8ef4L, + 0x547ecd17819df66cL,0xc35cd4cc91360e21L,0x6ea003a16026dfedL }, + { 0x45e77cda22395207L,0x1e8e103f91264683L,0x130f2d2b3bd6328eL, + 0x6ae25c819af8973dL,0x6b0f90a0d32d7134L,0x0280a95755c62195L } }, + /* 14 << 42 */ + { { 0x23781958cd8bb5aeL,0xe3d30c5417dd827aL,0xf974e0076bedf762L, + 0xd8154b6273264accL,0xf10fd9bb167b9396L,0x967c5acbe9652a0cL }, + { 0x46775025a28fa76cL,0x17ac7cb32ece9d3cL,0x5fd8968ce04a833eL, + 0x96ed5b49fcd20a43L,0x1d209e85289f9c68L,0x4d7473518ce51950L } }, + /* 15 << 42 */ + { { 0x6f5c8f3475214c1eL,0x3d5560bae192d11eL,0xd8a63ff0d7af2e6fL, + 0x5fb858be9069fe09L,0x83956dcd8cc663f9L,0x52d30c3b838bce30L }, + { 0xf354f6d75569122aL,0xfcef54d1fa68f566L,0xc75b01e79020dfe9L, + 0xaac66895774b952bL,0xb2a58a299468cebeL,0xa994a3b487c81a42L } }, + /* 16 << 42 */ + { { 0xfa7d1236e2319f38L,0x9ba1a1c0a551d3feL,0x9ea27288beb1282bL, + 0x1c069efa07fee8a9L,0x5749c7b55870fee9L,0xbedca76fafcec6faL }, + { 0xa3f8f1b14c63c5e2L,0xaa1bb15694758ac3L,0x753329a9b59dc06eL, + 0xfa8e5f5b98a92c38L,0x6b6f46fd3c2b4662L,0x716f41a1ec04c6c6L } }, + /* 17 << 42 */ + { { 0xa882aa6389201dffL,0x3441fde55bfcde3fL,0x220cca60cb543f54L, + 0x2af1cb29d764d74bL,0x47ae56d0517617c6L,0x05b98dee0342bf55L }, + { 0x214f4b11b4e28cfaL,0xa6ebcdf5093691ffL,0xe49ca185f61d29acL, + 0xd304ac40fd8c9018L,0x196161a0f889b7c7L,0x3b704d52dcfc6c91L } }, + /* 18 << 42 */ + { { 0xb405aff88886500aL,0xd88008bebeeabe24L,0x9457cdf30bc931b2L, + 0x8e5fd378f4c5aac1L,0xdec408107bc2bb98L,0xf86424c598b16f6eL }, + { 0xb6af27b634df75d8L,0x1bd3082125943a31L,0x51176cfcec993c24L, + 0xcfc1433accbd192dL,0x324a5e1e2993be83L,0x34169fc1d06215adL } }, + /* 19 << 42 */ + { { 0x41aa181ad260133aL,0x627dbe0346e236d2L,0x717fba9cfb8cc72bL, + 0x6e21d03d69bbc9e7L,0xd903e845241abdecL,0xd17879fa3c20cb6eL }, + { 0xe6141bd463a360b8L,0xa784a651e86cdcb9L,0x80fe8dd11f9147fdL, + 0x641241c6de155420L,0x1caef32ba71f3546L,0x28c3a51a79fdf82aL } }, + /* 20 << 42 */ + { { 0xaa16c27a84a3d033L,0xc207a4990c11c9caL,0x7ae2d193aae87c9cL, + 0x125ab459916d634eL,0x02ded714cfa65b4bL,0x6efe84944e212e22L }, + { 0x97c48a1888766168L,0x663ccc9dd9c85b9aL,0x6fe8b77b2652f501L, + 0x1daa602d078efd38L,0x35885364dbcb8299L,0x25bd1826b8240626L } }, + /* 21 << 42 */ + { { 0x6621d504af748cb6L,0x3940e5e08dacbf89L,0x9fdd8eeaf546daffL, + 0x18fc70d4b42f9507L,0x09bc4af9a3fcc42cL,0x9199b08f4165304cL }, + { 0x039d45bed3d0e9eaL,0x0963ede2a6464c2bL,0x77f47a62b5215830L, + 0x3a0ce54c3e540cdeL,0x34cf6031b2be8f77L,0xeb143e60201083efL } }, + /* 22 << 42 */ + { { 0x21404da5442467a1L,0xe73047597f7023e0L,0x836439a8213ff492L, + 0x105fe0e37ca0fc37L,0x73835ac85b303c34L,0xe29d830e0057ac8cL }, + { 0x457d083e3b5f41bdL,0x228b26c357341890L,0x8e8f194c4109bf9dL, + 0xd032cf2b6e4a39e3L,0x012e9515d88f9292L,0xd1a4cd32e957e163L } }, + /* 23 << 42 */ + { { 0xec56b72f4ab23680L,0x7cb58e727f22217eL,0x6e98647bd045d18dL, + 0x2b7c9caa9a73b956L,0xc414eabef120122aL,0x45d9036bb6e1b134L }, + { 0xe963c88388abd93fL,0x257f3b619180cb9aL,0x915fee5cb6ca7abdL, + 0x2166402cdb7b1bb1L,0x636f85f6541614e4L,0x81f91a1849d9e527L } }, + /* 24 << 42 */ + { { 0x0430af7759b11c7aL,0xf71cc5b1d4f47acaL,0xe1a7905f12e9190fL, + 0x1c689b7012db9e14L,0x6bdd3dc90abaeeacL,0x97f1c244504f0319L }, + { 0x874afd61a7a54b51L,0xd4604ecbe3d979b8L,0x0d33eee1ebf4aab1L, + 0xa3631cac1aa49fe6L,0x0d8340fbf2217cfdL,0xf6373284423b7e77L } }, + /* 25 << 42 */ + { { 0xc6cdb5ba6f7972d7L,0x7ac7d438907d281eL,0x9160a8f5c01044ddL, + 0x3d74d7eac19ba8f9L,0xf7c7f93f112433e5L,0x2ab355a2012236d3L }, + { 0x1168ce913009447eL,0xbefde8dba26e3458L,0x6f9837db49ec8169L, + 0xb4d1e35c86782931L,0x41440a76d711e5f4L,0x8fc7a5aeacb5cd89L } }, + /* 26 << 42 */ + { { 0x73719fe8286e8aa5L,0xff8663419982a4a4L,0x684511702fb2db95L, + 0x4f1c0eab01d80ea1L,0x2bc50da5530af14eL,0x00d1d5b506071a95L }, + { 0xdb618990a6b374b1L,0x06ad90084e79ebe5L,0x281d01a424a63b70L, + 0x87dbd6d5348625fbL,0xdc90f0bef576b1a9L,0x1a9ef270987747a3L } }, + /* 27 << 42 */ + { { 0x135e416ed651b9b0L,0xe55f7f104a5e7979L,0xe55df2550f0729d2L, + 0x666f2744e33ada22L,0x4968bb982cbcb4a8L,0x7ad4e7811028dd81L }, + { 0x0e59f0dcd7ca8b60L,0xd71628cdd2a600b2L,0x7eaf6d308b0af99cL, + 0x6224b6452900105cL,0xe0513f4388650f12L,0x2a63822a6f6c5234L } }, + /* 28 << 42 */ + { { 0xf8c07373078a045eL,0x998b2d52a81724d2L,0x2b97faf1a6305a28L, + 0x5bc61f67f3e0f93dL,0x7238583cd7aeb8c1L,0x851ecc4b39f5f24bL }, + { 0x1cc8b4689992c20cL,0x73168a863c8553dbL,0x1b9a5f95ba2641adL, + 0x87a0c362ce9d565bL,0x07fb51b2e1eedc62L,0xdb300ac6a973903dL } }, + /* 29 << 42 */ + { { 0x789ca390f33e8516L,0x6a7f594cdee7f1caL,0xb4b6b9ca988005a6L, + 0x14f7b4806cad024bL,0x682a86285a576b68L,0xf188c74e40e1984dL }, + { 0x3584b5e6bf6f19c6L,0xa350b1d2b7467bf3L,0x3b3bb966aa3d1266L, + 0xebbd2c782804d8a3L,0x91a272d36a9caf4eL,0x553ada4158fa7041L } }, + /* 30 << 42 */ + { { 0xb564a0d9807e30a8L,0xaba07b1534a637ccL,0x010e76c5840d8e37L, + 0xb6dcb9ac95f6765eL,0x2f5f8fe103b3ec08L,0x10c5a24fb48363efL }, + { 0x5ddacb2709c4dc1eL,0x8e2884b1e03bafc5L,0x84d56df3cfc2d599L, + 0xc8e2da84ab78ec0dL,0xace4663f900084c6L,0x98d9a1df5d49f42eL } }, + /* 31 << 42 */ + { { 0xb10ca6eea690d9c8L,0x0b8b39efd5e0d490L,0x2685d320e63807d4L, + 0xca40d0ee83116ce2L,0xe1e1434fca51b48dL,0x178a91afeddde4a9L }, + { 0x64f59e3fd0dace59L,0x57b33c26278b1820L,0x2ca13b041550875aL, + 0xb21f675a4e0db4aaL,0x2bbb3edb0216d3c8L,0x7f39955b96ec8017L } }, + /* 32 << 42 */ + { { 0x78a53b5a9563e3bbL,0x19c75eb286af355cL,0x3520f427019a6f8eL, + 0xde6fcad6dc3ad0baL,0xfec96e4f79745b7cL,0x5e566bbdb133f2dcL }, + { 0x50088a2b26561be7L,0x16275b4cc5fddfc7L,0xf21332ff23ae4b9dL, + 0x8cbc659e85246712L,0x27fa9c8df50b515eL,0x25ecf745494ac8b7L } }, + /* 33 << 42 */ + { { 0x7cb130e0837ab43fL,0x8a1f00127b9f6c17L,0xbf827f6d17fa5e12L, + 0xc181b1264914a231L,0x8ce70fb6986288a8L,0x9832863fcd1c276eL }, + { 0x738e99819622ecd1L,0xdfc1b43cb73807abL,0x7254b4cf1b673290L, + 0x2d689f38fb20f902L,0x86460de83c34960eL,0x8453896aed8f62e0L } }, + /* 34 << 42 */ + { { 0x9f74efc606f4904cL,0xa280e4c26d3bc556L,0x974f9bdb75975ee2L, + 0x1bc0e7fb6dacde9fL,0x2a110d4c49649375L,0x045432c09090d834L }, + { 0x84295a20195083cbL,0x92ea17cac7dcf71bL,0x3acced0be70be8c7L, + 0x3703dfc007e28816L,0x37fbf2d1e869fb8eL,0x8c6b0bbef9c35ff8L } }, + /* 35 << 42 */ + { { 0x04a991812f1d2778L,0x0d78573685b91ae0L,0x8c32d6046a5252a0L, + 0x12b043131a0df85eL,0x40c4db631ee669b6L,0x0f499408f18f5f9cL }, + { 0x0dcdefabbfe9a187L,0xbd371c45ca650d7dL,0x33819eb00a36748bL, + 0x82d1af1f29034844L,0x301f906d96257b2fL,0x862728ea9395c666L } }, + /* 36 << 42 */ + { { 0x33a2194f40175152L,0x0f7ddc1dbb13f08bL,0x7c08860850b54274L, + 0x7ebb2c11e41f0795L,0xf915683fbe20d37fL,0xcbcc14889daacec5L }, + { 0xfb02c20fea459050L,0xe964d76ad5815aa3L,0x0e009be9496bbf2dL, + 0x8233690eb42d0f7fL,0x98ee83d49168eb0eL,0x34c3b6f3621fa292L } }, + /* 37 << 42 */ + { { 0x29555d79b0221994L,0x1dd689dd4c9e8f29L,0xcb83ed2c853f5261L, + 0x04b1475e0d9b0670L,0xa28b15e7df2ec34eL,0x094409b5e60a168eL }, + { 0xe4b9fd0e16ed42fdL,0x02f97e84a138f2f6L,0x91dc216ce13520dfL, + 0x59564eda7a245e5dL,0x825278be8478befaL,0x69daadd20328c4d1L } }, + /* 38 << 42 */ + { { 0x6ffade389995db43L,0x88974055790f4b92L,0x082e5add525d19e1L, + 0x002c414897bd9931L,0x3f093b3b5461cff7L,0xafc95b0042b8d3f2L }, + { 0x0a8f7687a993155dL,0x1edfdf616c2bb58aL,0xb5be2d4fc44049e4L, + 0x6fd505bb8dfdf4e7L,0x5386f02a41af5871L,0x8178817569121027L } }, + /* 39 << 42 */ + { { 0x1deada722706171eL,0x1baf4c9aee773c6cL,0x458efac06977d673L, + 0x1f2c2f38646e29b5L,0x36ece91a53323300L,0xab51a49bc4d598e8L }, + { 0x7802760ed8e41d8aL,0x2996f790587425a5L,0x227165b73ca21bedL, + 0x0d9e5c5283536ec3L,0x6232f2e089701806L,0xc55e80a2894e2577L } }, + /* 40 << 42 */ + { { 0x437b7224641e3bd1L,0x84e39f7980a58460L,0x68e5292709759523L, + 0x0176a3ace77f5904L,0xde92fb15e151e242L,0x79965c9aeb1438d4L }, + { 0x318a810a596700b9L,0xa8a6ec57c2198cbeL,0xd7709aaabf030fd2L, + 0xb432023472f5d326L,0xc9945214b03bce50L,0x0bc06d9bd4ecba09L } }, + /* 41 << 42 */ + { { 0x30630eefaadf21b4L,0x94896f68042fb57aL,0xe678fc3eb312e7daL, + 0x325cd2bc5c94c991L,0xd4eece20bea4e518L,0x9d9d65e925eab2abL }, + { 0x5439c348676454e8L,0x9eb68953be1e48ccL,0xbeea9da27b625a31L, + 0xbd82c6ee48cc200eL,0xba9fc94444b9dc77L,0xb31bdebe1eb9283aL } }, + /* 42 << 42 */ + { { 0x1ac1a09d07abf58bL,0x7372e532b5770f9dL,0xe1716687c12fe180L, + 0xd91f4d36c715009eL,0x5d8885cfd6fe1cd3L,0xc0ab5a13aea65e52L }, + { 0xa5fe05a0838e5e05L,0x590cc325971fb33fL,0x3bd8234a4653bf57L, + 0xb83300373708c1aaL,0x27453d3b0e84e8fdL,0x9dd3f05399cf918fL } }, + /* 43 << 42 */ + { { 0xaf6f26c3a36468a3L,0xcab875f28d9fc8deL,0x0209b1ad52f4479dL, + 0xc9941cb5459542cdL,0x91603260a0212b68L,0x98018317345673edL }, + { 0x2b02a35ef98b810fL,0x15953f78b714fb32L,0xf9f9c61eb71a4b4aL, + 0x959b1473a8505b7aL,0x331d32cb4c6ec97cL,0xb1d2dd44e49f189aL } }, + /* 44 << 42 */ + { { 0xdfb0508345c0a2acL,0xd13790035eacfb2fL,0xe9872d766a2e126cL, + 0xd2a89cbd39a02d27L,0xf45baf72d754b7c2L,0x37985ef8c6c61bafL }, + { 0xbbcd3ef2da1c46b1L,0x5af5dda43a355d83L,0x9f7ce4281d67a984L, + 0xf19526926fa33654L,0x2abccb55567b3b71L,0x1b3704f3300cf29fL } }, + /* 45 << 42 */ + { { 0x9dcfaf21712af69cL,0x26de8fb05291cd70L,0xc778294742072171L, + 0x889b9fbc8c617e24L,0x5971e60cc2926862L,0xdd8e70bddc022533L }, + { 0xc783e1e30a369db0L,0x37f562ab07b2bb92L,0x5043f3d40c060f44L, + 0xa9650f47a3e17ac4L,0x3b8cd7ad18010ceaL,0xeed5de39969849e7L } }, + /* 46 << 42 */ + { { 0xf93c3ccb6044ade6L,0xd14a13f8fd376746L,0x1fc20e6fd718a98eL, + 0x9f63c6673e31573eL,0xe99b7693a8e0c66cL,0xdad4615c1e5b5f5dL }, + { 0xcbdb7200ac98f5a3L,0x31414469668ab045L,0x82e92df9bacf0ac7L, + 0xa61f4e8371bfdf94L,0xce8cb699d1bc5deeL,0x42da8ac72f2f837cL } }, + /* 47 << 42 */ + { { 0x0b6252fc32a4e8a0L,0xac1e457dd7170402L,0x76faaffeb121e40fL, + 0xd2dc3cb84ddebd9aL,0x303e47cf362348a1L,0xe37e824a829d9806L }, + { 0x419cc2cc7c2ec135L,0x3eab37024cecfdceL,0xf0c9f19088403d18L, + 0x73c8984daf61b6a3L,0xa2d44d9e00c232a1L,0x61fdf4883cf1cecdL } }, + /* 48 << 42 */ + { { 0xa1972c2196fffb94L,0xbe04093099d7633bL,0xb116ff407e23d66eL, + 0xcb12b2bb949a19f1L,0x75df10ee79e49e91L,0xa3bf90764890bcf4L }, + { 0xcbaa76a609a30252L,0x17c224a90ee5728eL,0xcbc56e5cf4f3f4cbL, + 0x8a07110f4fe868a5L,0x23289f2125e110a2L,0x0289c12bd7693c45L } }, + /* 49 << 42 */ + { { 0x4a9c6f8bea96a0f4L,0x78262a3499e3aaa3L,0x513a8e2028b2634bL, + 0x5ba40287d85d74b0L,0x5702d11d440fcbbfL,0x1933c88a0df91fbdL }, + { 0x642247909a0aff2aL,0x85dc2ca13734398cL,0x1009884fd7aa787aL, + 0xc666a62a0e73f4f5L,0x491bb941cce66210L,0xda8e896bcd173443L } }, + /* 50 << 42 */ + { { 0xdc9b37a7c6e32022L,0x158cd4bb342a148aL,0xd62d371cf06287a0L, + 0xba027eb6e9fe0a01L,0x8e7c6f5372017d09L,0x13c5d6ce9381d9c7L }, + { 0xbd0bc2d46e32f045L,0x52cf0f2554ab7f2aL,0x2e674e50085643f2L, + 0x77bc15aef1662819L,0x57f9e3c4f2ebe66eL,0x839aaebadd284956L } }, + /* 51 << 42 */ + { { 0x752bc171ed9d735cL,0x76d96d3419ad5c26L,0x9549ad3e25c1d83aL, + 0x8f6fed53cd460d20L,0x04504f7c7b619b69L,0x68265559c566f393L }, + { 0x5e39e108804598edL,0xace859b01f4538edL,0x4b8503070c85e5daL, + 0x9f087821abcd4ecaL,0x126d3850c8d0def4L,0x66971fe5263457b2L } }, + /* 52 << 42 */ + { { 0xa82ac9983a4bc15bL,0x28697435c930e4f1L,0x191ebdb6b0c9cef3L, + 0xff05f8e875748872L,0x5b86940237343b20L,0xa7bce94beedfe44fL }, + { 0xfc271e2778f4e1fdL,0x652c5a187734db66L,0x108f61c87efc9a9cL, + 0x01db328970ed1dc1L,0x2bc509afd249f61cL,0x0d2e6b4cfeed393dL } }, + /* 53 << 42 */ + { { 0x691199d77a477295L,0x1f0679a661746b75L,0xf3a51493c9f936d7L, + 0x1fcb336a445af5f6L,0x9880cdebb94ce08fL,0x784fa04a22a6b57aL }, + { 0xc85fe18caa97c3bbL,0x27294a3baabe9b50L,0x9418a5b7b673c915L, + 0x686cd97a15dceed5L,0x6d1c9dc70f22ae6aL,0xed88e02dc02212d3L } }, + /* 54 << 42 */ + { { 0xa62c358dcf616234L,0x85402ffad40aae7cL,0x315ce9f151a7614aL, + 0x6f7e796f5d0c7d7dL,0x73bf57faf3444d22L,0xb5e71e7a224b77c0L }, + { 0x94c40681541ee741L,0x40c97253d6837e1bL,0x1058fe7bb1f1c742L, + 0x3206256f9b24d65cL,0x0abb12a78169ba8dL,0x01fcdb7beae85db9L } }, + /* 55 << 42 */ + { { 0x868f294309fdbd8aL,0xd9c11e7ebdd6c274L,0x3be4d8e7fdcb4fb7L, + 0xcd8c40ad17305d10L,0xf12c97642abde5eaL,0xc9e16d8256776e80L }, + { 0x279c0248df05235cL,0x4bdd8b136d8e4b89L,0xab8bbe8d7c47d2c5L, + 0x12ba8b9e255c665cL,0xd585ce64d140a518L,0x55947e69eb4d353dL } }, + /* 56 << 42 */ + { { 0x06ba6db1f184c91fL,0x3c0a348a45fd0382L,0x0d535b6e4434b527L, + 0x7bbfa2c8692bae0bL,0x5c59a08ebe7fe51cL,0xbaa7d2be36e80cb8L }, + { 0x8a42d8d1bed3cae8L,0xd9e0bc0d15ff4962L,0xe51fce93644c75ffL, + 0x40222561b9392d63L,0x8ab1d286023b4787L,0xfa85c220a1b3190dL } }, + /* 57 << 42 */ + { { 0x294845c28ed1d81eL,0xc0402af2dbe7fdbaL,0xbb56d86d67abe6a1L, + 0x2e61f65b2ed330e4L,0x2893eaebffdf0fd1L,0x06cff97a75fb77dcL }, + { 0x2911ebac1c90fe64L,0xd9c40d77e5ee3458L,0xf5b8b1d4b355f191L, + 0x5be71a4ef365bc6bL,0xe2db432f5277b244L,0x3272a28327235b87L } }, + /* 58 << 42 */ + { { 0xe5105755e6b16cbfL,0xba9fb47b536a49f0L,0x03ac0c10c75ad751L, + 0x9090bc328a2d65a0L,0xcecc7202852b3d23L,0xd214f70128f67958L }, + { 0x379899b1f3695cabL,0x8f3d02e9bd3342c2L,0x9870a7f9e24e7bc1L, + 0x7277e115f723893eL,0x6932ceef0f6f1936L,0xd0bf06dde171306dL } }, + /* 59 << 42 */ + { { 0x815cabeb17832ce7L,0x65afc856a2a4864cL,0x9fe4ae1aa4939a4dL, + 0x7005cbd90729a3c0L,0x887f0cca791e8ad6L,0x55cad97a85aca45aL }, + { 0x3e89d294493c7dcfL,0xf4ae5277ae8ed154L,0x507a3fd0a08fbcdbL, + 0x4df3c552f86677fdL,0x6529f9ace3a82131L,0x09efe1fba53a7c67L } }, + /* 60 << 42 */ + { { 0xbbcfa42d21fe8f67L,0x82983012de2be980L,0x88bb9704aa8e17a0L, + 0x100ad5e784772203L,0x2867168965479d29L,0x0334f9c5c2d9d5d3L }, + { 0x49032c1a83a6cf83L,0xc257b0901dad479aL,0xf64177dea7e3636cL, + 0xb2b5747874a315abL,0x210b11cda170ccbcL,0x80509b7480d80177L } }, + /* 61 << 42 */ + { { 0xe98ad30696993a74L,0xa7dc8330f0484940L,0xc30319fdd61b83d0L, + 0x76e2755809873771L,0x33f4f43ecaedda98L,0x68d5ffe3639c8d3eL }, + { 0xe3cf3b850059b2d9L,0x7f3ecb2f6a3d057eL,0xb569c24b9b8b7466L, + 0xeed92f2ac38ccd58L,0xc16a4e8ce765a2f7L,0xa3a7b6552de9cb38L } }, + /* 62 << 42 */ + { { 0x496de6fa0640df83L,0xa4e500a36c77c97dL,0x45609036947aed3cL, + 0x0edb9422423fc5d8L,0xd0c01b2e68f70746L,0xae44ae0e6d77f3a3L }, + { 0x7cc7e90635adba9cL,0x107a3b46a8413303L,0x9e3eeab98916817eL, + 0x1a99dab86fb74601L,0xb4e8466c1064b039L,0x249149146fcbadeeL } }, + /* 63 << 42 */ + { { 0x89643fa624798452L,0x179b3bd76ee52833L,0x343096e54430c6b3L, + 0x589dba3323461536L,0x59073225c3433575L,0x540f9ce317d80d42L }, + { 0xcd04b14d3aea6c82L,0x9be179b0efc9f455L,0x0ad6fb0791e57cbaL, + 0x33894fa262706b10L,0x2cbc270886bf6926L,0x2cf067e64ea48c6bL } }, + /* 64 << 42 */ + { { 0x298647532b0c535bL,0x90dd695370506296L,0x038cd6b4216ab9acL, + 0x3df9b7b7be12d76aL,0x13f4d9785f347bdbL,0x222c5c9c13e94489L }, + { 0x5f8e796f2680dc64L,0x120e7cb758352417L,0x254b5d8ad10740b8L, + 0xc38b8efb5337dee6L,0xf688c2e194f02247L,0x7b5c75f36c25bc4cL } }, + /* 0 << 49 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 49 */ + { { 0x36c9dbbefda8520eL,0x573507ce6ae3ea98L,0x1ab38db696a8f9f1L, + 0xe031d2356b01e6bcL,0x10466ae68afc4adaL,0x3b35df41ed9c44e4L }, + { 0x61272c12c7bd99e8L,0x6a4ae7b4805afd79L,0xf4c47a910ecc49ebL, + 0xeb95dfeccbe84d5cL,0x43f3b71c8ee497d7L,0x2547af524c6fece4L } }, + /* 2 << 49 */ + { { 0xe323ed0cced45039L,0x04ce0b67a90aa713L,0x9c092f06e8d68e4eL, + 0xd8f5555ad0742e5dL,0xe2d175bf00d3df92L,0x8ca55f154f71aeabL }, + { 0xd1762d72642d391dL,0x0dfdd3c2aec466bdL,0x2caacb4c6281f2a7L, + 0x635ba4703603e53aL,0x94a9811d49fecf29L,0x3a42cf09466bf361L } }, + /* 3 << 49 */ + { { 0xe63fbb10b5356889L,0x5995a0a92e73aba2L,0x5cea30677afd4bf7L, + 0x4494e39dfd37120dL,0x8c572c7249d718a7L,0xfe159c275fa305fbL }, + { 0x751c217fc276c40fL,0x44d0643c45e40857L,0x9a996e6efe7a6486L, + 0x1a4f6d10f53b0e47L,0x651390ecd15fd593L,0xe0c1181d739ee9eeL } }, + /* 4 << 49 */ + { { 0x0f05710b11bccf2fL,0x7113085a7aec1bc6L,0x137da67a46b8d0e2L, + 0x454b89fc698b78ccL,0xf2a6e1de258a9393L,0x5f1804e716488e69L }, + { 0x7c6c550215b3bf35L,0x3b0e09a5b05c2ec1L,0x4b9de30e92f15247L, + 0x09d4ca9327e70a0aL,0x9c8b16340d149363L,0x54a8287cce642137L } }, + /* 5 << 49 */ + { { 0x3a05e7d5ca2af43fL,0x068953f975009801L,0xd6c8a76c06740141L, + 0x7e1df1038a831fa9L,0xfe06e2bae39046f3L,0xda5264a0e1807c29L }, + { 0x1be4ffedff5d4808L,0x299d6537c52be83cL,0x1b38adba11834a9cL, + 0x6074a60b1248fd42L,0xd9a0bd2e041b5430L,0xf222ba84a7b76b03L } }, + /* 6 << 49 */ + { { 0x49ecd6f3346a764eL,0xe46847f14105e657L,0xce9cb2b57550f608L, + 0x45f1a1f7f4cf062eL,0xcdb19a112c27d38aL,0x36d375b284e50b19L }, + { 0xf43691540dba6405L,0x4c9dc863040354dcL,0x7229e70ea24d09cfL, + 0xe72aa86c7cf6831bL,0x487fb68425392838L,0xe88bed04430b9b47L } }, + /* 7 << 49 */ + { { 0x9f77b8c5d1164788L,0x45bcd4c1d7b5c5dcL,0xed22ecf3d88c2357L, + 0x330272ad07de1cf8L,0xd9749f7f4ca13a48L,0x4964ce5d1383ce08L }, + { 0xc033d516b0d0dbb3L,0x056ae73bf51943c3L,0x495cf7e057105e88L, + 0x08ced52e56462560L,0xe9578aa713ca1a7dL,0xe9b045c5a9717f7eL } }, + /* 8 << 49 */ + { { 0xf8a8499b666fa8a8L,0xd0f9401571bba84aL,0xb85e1b1d515e1328L, + 0x88a2636ba941e788L,0xa045241d2b5dd8d8L,0x161be476332f0350L }, + { 0x96c4b205a18fac6bL,0x5cbe8d5e73fc5337L,0x6fc33fc6d00b6029L, + 0x07a914ee89aa3b79L,0x35353eb7a4d4dd00L,0xc026bdc0673e8956L } }, + /* 9 << 49 */ + { { 0x1e551f9bce0b6f8cL,0x1fe7ea4618495e1dL,0x3f6f28742dc0e878L, + 0xb778c12844c43f20L,0xbddc28eb8a250230L,0xd8571a4aac6c3d17L }, + { 0xb9dcaec9730c8a1eL,0x512cee9993fbcf87L,0x0df3a1379bafe001L, + 0x8530e501e2a2b9bbL,0x6d38ba8995ebf91fL,0x704b81a7792cef7aL } }, + /* 10 << 49 */ + { { 0xccda372167103852L,0xf78d22470c54de53L,0xebd16036afa44aa5L, + 0x7b88024864a24ab9L,0x86b38e961c2bc78eL,0xd0aa0d058d63b295L }, + { 0x24912955c62fcbf1L,0x77a68156b9ac435cL,0x432401c71b360b26L, + 0x091f19f34c58ef8cL,0x3a4a61f483d46c9dL,0xad0e5c72e8d616cdL } }, + /* 11 << 49 */ + { { 0x668d598ad1666826L,0x6ffed334fba0ba63L,0xe71e3359d7cddc30L, + 0xa9c15c2d9fb9998eL,0x6966d350612230b9L,0xbca3ed23ae4fe0edL }, + { 0x537cac1b3caa3edfL,0x4f4a737ef33c180cL,0xf8d8f796f8807a7bL, + 0x5c7cf072d1aab3e2L,0x7f0ccb9dfff736e4L,0x71bf0732ef11266aL } }, + /* 12 << 49 */ + { { 0x33b029bccdaa6831L,0x2548552d4c1f9cedL,0x35f1a002dece1c8cL, + 0xc6b87fd7acc23aa5L,0x0b8bb275bab029a4L,0xf07bc06730bfb42dL }, + { 0x1688ff5d1f69ce9dL,0xeedb7b5edb10585eL,0xb7a88cf0d432c197L, + 0x20731bdd015a350aL,0x5fa1835463223f5cL,0xe392e1318024693fL } }, + /* 13 << 49 */ + { { 0x61ada737c3449cb3L,0x071062504ca876ffL,0xcd98a39001d1403eL, + 0x197c845096ded881L,0xd060160568cacebbL,0x7e1b37d1dc3ddff4L }, + { 0xfdc1bcb5d1725e92L,0x11cbe941bf0856d2L,0x63fd35d050199657L, + 0x208a1047b9790d10L,0x52790ce61af4301dL,0x75e6d83beff28b69L } }, + /* 14 << 49 */ + { { 0xdfaeea0a0154731eL,0x9e53419de15a0388L,0x2ad6a83c25a992c8L, + 0xa2ba020fe125501aL,0x894ebaf8d4dd04dcL,0xd48cb95850765559L }, + { 0xf9b58d0980dec92bL,0x2a0e11659da299d7L,0x3c081853efe9cb11L, + 0xb9f3b702a511c5e0L,0xa8f7a25f70486180L,0xc0358b25591b3e2fL } }, + /* 15 << 49 */ + { { 0x00333fa6fa806947L,0x7e4dcfb3504b3e19L,0x8326b0acad4a5dfdL, + 0x9ffc65eac7b12e49L,0xed3b7c0258d16eeeL,0x79fccfb434a4222eL }, + { 0x4a8070a0e556357fL,0x554fe2c9ec97769eL,0xcc405a57da691714L, + 0x12927897856f590eL,0xd4805b93ba198dcbL,0x2649be2e4b18444bL } }, + /* 16 << 49 */ + { { 0xf36e8398eaddf274L,0xe41553a16a5e4ddbL,0x36ab07464efc5b0cL, + 0xb211e59ad316c434L,0x2515ec9f16ccf839L,0x6ecb746503dc6a07L }, + { 0x842b7275c65c1b07L,0xf7ceeec535750ab6L,0x967d711ccef5255dL, + 0xcd3bfb075108cb92L,0xe50c0d8aec1b9740L,0x9e8d56611a9e6308L } }, + /* 17 << 49 */ + { { 0xfcb12ba3aae18c46L,0xb55e959c6e21d463L,0xf720d19f4a4f6f21L, + 0x1c2ff60ed4320c5fL,0x4ce5e1ac1a1b40b8L,0xfdebfb81ff6fb9a0L }, + { 0xd6c37d8a9c67c07eL,0x55167952012fc09fL,0x5dc722b52c306c4dL, + 0x1efad8d2bc1f65e1L,0xa1478f3da52556ecL,0x54cbfb884a795dd5L } }, + /* 18 << 49 */ + { { 0x84f8ea13ccb8a36aL,0x5f7aeeffa05709a2L,0x4942d04e60574f37L, + 0x855b13e9e048b400L,0x747e4067a6b59c09L,0xc349fb05074d3990L }, + { 0x398e6afaec2c7e03L,0xce361865ec2d5a4cL,0xfc04bf8eb6f57d22L, + 0xf0e0b84c759ce6c6L,0xb65141235ee7e528L,0x8ca144bdf5c0f9b9L } }, + /* 19 << 49 */ + { { 0x5868449bc6e0124eL,0xdd65ffc1e68ad5eaL,0xe126665f4f577466L, + 0x8ade5cee2defe8deL,0x7c1cf7f07beddf87L,0x0e0e066a362c5956L }, + { 0xac2aff4e15563b47L,0xa28ab875620d1299L,0x91f67b3fd8caa497L, + 0x91bef53394fc08a3L,0x0fa27d9cd99918f5L,0x205b6c1f60b67bd9L } }, + /* 20 << 49 */ + { { 0xc1370daef6a58536L,0x6f2e5b37c56b0ae9L,0x5511d68292f6b6a3L, + 0x2e9e5034ae575249L,0x3e5a32f81d14bed7L,0xa346a86f75efd17aL }, + { 0x4f2510a60309fd7aL,0x689ecd74d0b1425eL,0x9e9bebe19f771e24L, + 0x20188045adc5b48cL,0xe49811b6b845230bL,0x420855ec5a8687f8L } }, + /* 21 << 49 */ + { { 0x705a9ab30aa1a423L,0xcb01466fb49830c4L,0x1db1768581a75897L, + 0xcaacb855e341f157L,0x9b13cd497a0d3c38L,0x119b4d47e177fcb3L }, + { 0x0d8f7c2639788712L,0xbda0f3180642bd4aL,0xdd4bd88bd4616239L, + 0x9a3ecf978df1b895L,0xd0d54caf4a6dc07fL,0xa7ed6bfb31810203L } }, + /* 22 << 49 */ + { { 0xe650e49abae1b94dL,0xb6b162e6e3199794L,0xdc706859b4ec0480L, + 0x28b618c24b1a06caL,0x0929a001403acdc2L,0x796dfd972da3aefdL }, + { 0x16389072ef4c1673L,0x600d8bd7fc94a4f5L,0xf003214de5f386a9L, + 0xa7af0499e62cbb48L,0x750a3b00de82bad5L,0x6c615b838e7dc8eeL } }, + /* 23 << 49 */ + { { 0xe1916cb4eae432e5L,0x81f3e48acc193889L,0x54d58685ba922a4fL, + 0xeffcc528bf11b76bL,0x2f70d38f8171c971L,0x547ce8ccb3a5669aL }, + { 0x3acd91b878e6d0beL,0x372dbf2c689c2913L,0x9fceb5bbd0aae543L, + 0xc601f9622830a977L,0xd55e74509f874dffL,0x77ff8ab4822878caL } }, + /* 24 << 49 */ + { { 0x283eec26d71543a6L,0x98fa08bea7627841L,0x269a83b827ad302dL, + 0x225f2f12bde3fdd0L,0x046fcf380130b3a6L,0xea733c1ac3ed9043L }, + { 0xf870f14d70aa08d1L,0x643d18b834391e0bL,0xf3e1d5f4847be772L, + 0xa9498223d0ed73a0L,0x6933ccf014b3babbL,0xc2439ae437f08f70L } }, + /* 25 << 49 */ + { { 0x503414d0f2cb5475L,0x51b9497cb24cbf9eL,0x57359dee2f4c7746L, + 0xee7125c3f3118a94L,0x2f0db706e4ea33d6L,0x885e8c3eddff7f63L }, + { 0x752f594b628432f0L,0xcfadea7779852e2bL,0x4f733b8ba2ba4b7fL, + 0x163c8c2e530f763eL,0xf95a7b57ff05a7e9L,0xd4768d242d7be01fL } }, + /* 26 << 49 */ + { { 0xb643f4e0f88d049bL,0x5e0ac1fb12682fcfL,0xeaf7874d9f981c8fL, + 0x9c2adfd2b1af779dL,0x9a7abeaddaa8c275L,0x09ad552124cacec4L }, + { 0x069cd5c40ead1646L,0x5186bf190a6157d1L,0xcc222a9396503506L, + 0xfeaa7bdebd29686eL,0xb0d65b0da7257c8dL,0xc31c0a8898aa227fL } }, + /* 27 << 49 */ + { { 0x5495f21c9fe88a48L,0x01f580ac590c1966L,0x1ad433ba39810166L, + 0xecbc67003a5187f6L,0x38d36c3bd4216887L,0x49653585e27b615cL }, + { 0x2a70a1d9e773db7eL,0xe36d967a63c1c048L,0x51cba60d26d15862L, + 0xb633839fd5a6b746L,0xa6a756a2ec1fc364L,0x37fef8d24cfccb6fL } }, + /* 28 << 49 */ + { { 0xb4b7651f5be1d45bL,0x0425200a7f0cf680L,0x200d12b48960be95L, + 0x02fdd1a14945b193L,0xedd70e3e27d046d8L,0xc1cc086a83f14e12L }, + { 0x1580e72b2629396eL,0xc87439dbf9ed73c1L,0x5debdf30a90c5128L, + 0x0b6c020e9fbe14efL,0x168da56a0149a0b0L,0xc66a4dbd79c58ac6L } }, + /* 29 << 49 */ + { { 0x6ecd9c41596b8890L,0xd25172fe210d9613L,0x1ce8abf872b97aa5L, + 0x355899d610faa675L,0x003b69adf4ddf011L,0x6736cd40ec2d1af9L }, + { 0x8069a0ad4f85ac72L,0x5c31d68b5836cfd3L,0x8e9486eaa5ec1473L, + 0x8e175c4a1468cebdL,0x58b3d2b1ffaf2f77L,0x4fd21681a17a3e00L } }, + /* 30 << 49 */ + { { 0x800aec84330b8e2eL,0x1a2c033e335837bfL,0xf1a91551fe6f6dd9L, + 0x326c42b21de7360aL,0x300e740b7b66f9d5L,0x53bcc70068ce95d4L }, + { 0xc9e225ac3d80f228L,0x64b2ad4e6977dfdbL,0xac863b0801f23221L, + 0x0517a648df11e5f7L,0xbf7aedcb68d11050L,0x2607e33777b3029cL } }, + /* 31 << 49 */ + { { 0xcb1955e44f4706b2L,0x0821d4663acaed1fL,0xbe822db07f8b43deL, + 0x3d11573f9b1c83a1L,0x6c052118201eab83L,0x294c5060dfe340d7L }, + { 0x994a4bde0644005bL,0xf1519f3258fa0552L,0x9077bf5bd4d0d39bL, + 0xebde1ff0e6204ea0L,0x58a68e09829130a7L,0xda64eb8596961bb6L } }, + /* 32 << 49 */ + { { 0x1afa6aa6206add5dL,0x66cfbbae150ea4c9L,0x07fb920b5d36da4fL, + 0x144d51f9291e774fL,0x26c2c134f40d87a8L,0xc8cf3524a932f1a0L }, + { 0x35bb2a425aeb0bdeL,0x5cfcc1dac4be960aL,0x5c40cabfaa1838edL, + 0xea0c05ffe2855f1fL,0x931ebb02fd525934L,0x31a7b78f16246fd4L } }, + /* 33 << 49 */ + { { 0xbe055fead42b36aeL,0x733a05ed819ddf8eL,0xa00fa0a15c9a6102L, + 0x0ed363273c0af634L,0x5b5a62b4d5970a32L,0x9d7557dfca954cd8L }, + { 0x30314f0c6daf871bL,0xaa7c42a96267b2abL,0xc5d1f0d6132bc62dL, + 0x77ac94df7ed26084L,0x0d256fdada34e1f6L,0xf0259d1caa4b4dd6L } }, + /* 34 << 49 */ + { { 0xf576c69e86ccb00bL,0xc870c07f5781803eL,0x91d4c0c6b1869e56L, + 0x9c2729397d940416L,0xdad33f73c4d0269bL,0xe2baf5b8838c9198L }, + { 0xd8bb9613218414e4L,0x5e9f7b67c980ca07L,0x1e2d4e63165079fbL, + 0x6ae5b17f983b3fadL,0x1e66b8380c24e22dL,0x80cdaec2136e0be8L } }, + /* 35 << 49 */ + { { 0x98cb12d93fc277f4L,0x81def3ee160b8743L,0xa1f07ebb11711fb6L, + 0xba17dd15a95b3ba0L,0xb25f1c78bc158f33L,0x1bb83cf27841e8bcL }, + { 0x57ad928abf49233cL,0xc94fd746bdad3f2aL,0xf7c716ae4a4c6600L, + 0xdd0e3117060a78b4L,0x85e8851a860764b0L,0x3342d974bce0d787L } }, + /* 36 << 49 */ + { { 0x2bc4e37a719793feL,0x1543af2aa68ceea3L,0xc99cb391aabdea45L, + 0xc890e546f0b8eea7L,0x8b75b91feb4173d7L,0x9d52d04bef46f637L }, + { 0x0929f25d878ff734L,0x7377235fb6c43342L,0x657835cf6eca900cL, + 0x7b752665098bb5e2L,0x320d09b6b8a61442L,0xec4f8182cf5b8023L } }, + /* 37 << 49 */ + { { 0xfc5f8feffc788160L,0x7d552625f73f48a3L,0x4eea435145c02498L, + 0xb5f5de5bf8f8af26L,0x78f1c499067b1610L,0x6e0d1b14eac18a29L }, + { 0xf8be2f6c052af916L,0xd8cee5668876af81L,0x99a27ec31577bd90L, + 0x3ac529d242919f4fL,0x1215428c7fc05dd4L,0x99ef01e450f67e87L } }, + /* 38 << 49 */ + { { 0x145902629d671094L,0x7fef49c166ce858bL,0x2a7ea540c2f21eadL, + 0x1226b04fc1d5a636L,0x4fb54e4e535efb9bL,0x6c51cdb91d72bed3L }, + { 0x94162e44938efaf6L,0x166013cfaf6f5697L,0xfa9495bddf95f9c6L, + 0xc05441cb0d7f8406L,0x7e5c89763a233ca6L,0xbc75dc6493fe8e42L } }, + /* 39 << 49 */ + { { 0xe1885cf128ed669eL,0x6e9f40dfb428b3cdL,0x412388a61626f8d0L, + 0xb8201f047cbcd192L,0x642ecfad70ba644bL,0xd43be1cb43c76bb7L }, + { 0xafafffc388f4bd51L,0x8c40e2787052eea6L,0xc1a84e866a4c8776L, + 0xf0201f292fe7075dL,0x132f80e4576af421L,0xe0831b7f4731dddbL } }, + /* 40 << 49 */ + { { 0xecfabd2742dbb68aL,0xad43a2c43eb546d1L,0xcf4e64ccfe2691c9L, + 0xe3889e258347566aL,0x48da354885b8c733L,0xcb7fe0679d9c9f57L }, + { 0x8c26a8d668223280L,0xc1e8ff623065705aL,0x181ca70a3f8db9f8L, + 0x25aa6450e758213eL,0xa4898f9169b2653eL,0x5e5c9fb4ccd8303aL } }, + /* 41 << 49 */ + { { 0x640b6946b03aa213L,0x6b99e84d00c068f7L,0xed4f1d2d99c5c461L, + 0xcec88724b20eaffaL,0xdf2b79a95dbbc32cL,0x2f7397054f3a1c5bL }, + { 0x1594a54946eb52edL,0x55f11aad39c4c43eL,0x0fcdb331f46500f2L, + 0x0d66be885ceb8dbfL,0x4d977349886dbbf1L,0x238f4617797d1b41L } }, + /* 42 << 49 */ + { { 0xfc8c7320721034d4L,0x48b389db60264280L,0xac246988649cbd88L, + 0xb7f52891a50bb658L,0xc0a812e50a7f279dL,0x6593175967fb2cffL }, + { 0xd31a77c6661ab439L,0xabadcea00ceb4aceL,0x201d98f6a3702dddL, + 0xcec1e83e7c9463aeL,0xc64e44fbc55e6856L,0x421f3e3148aa0d81L } }, + /* 43 << 49 */ + { { 0x4f0b251871a07c6dL,0xbfe652edaf3a2fbdL,0x5f68dc667bc2053fL, + 0x445df84f6040a7cdL,0xbdda2132180dc0a9L,0xd8627401d6c7a92fL }, + { 0xba350cb190cd2c73L,0xaf4c1e5929886ab4L,0xee8fdff2d677399cL, + 0x3ce35c6edaecf83fL,0x44df0a300f114062L,0x1b633b4647f29868L } }, + /* 44 << 49 */ + { { 0x48483f6af58ae2c1L,0x70ba34635e1cce49L,0x5f7a1c6d33907532L, + 0xa0fab701875a5f3fL,0xf2e8b0ff85d387e1L,0x0076aa68ff349689L }, + { 0x6e392b02747e2fffL,0x5e1ea320e788d577L,0xba705bd7713a0b03L, + 0x04ef192f2dc2cbc5L,0xa5a14eed38aef8a2L,0xf9682bbe30a268faL } }, + /* 45 << 49 */ + { { 0xc04f2cf540244a00L,0x00c90c3bb8dc0ad2L,0xac5b1060601d76f6L, + 0xad97c5c1a7ff84ecL,0x7919a06dd2328101L,0x62d5b7a4ca8a69c5L }, + { 0x75607148de5a2cc9L,0x1afff7f79a75fd24L,0xe62efc8083a22367L, + 0xad08258a10e05e36L,0x22666e06c0e4b549L,0x15f62c613f4c48c2L } }, + /* 46 << 49 */ + { { 0x751affadc7b8da09L,0xc052109dbd8e45d5L,0x7d11aaad87c14560L, + 0xa0410b2a6b690121L,0xcabad9853e10a103L,0x4d19bd3e785f1bfeL }, + { 0x8f32c6b84b6167a4L,0xb21d4ec297b4f546L,0x2e26df99c008f7c7L, + 0x63825597eb347720L,0x6a05b375afe39fc8L,0x19790b92131201a3L } }, + /* 47 << 49 */ + { { 0x149347ff7780729eL,0x076b4edc62e2dd48L,0xbf0de9d7cdcec866L, + 0x9d75deab8fa1e18cL,0x10931716eecb1f4fL,0xa8765dd3a385eb7fL }, + { 0xfd26f39c4d70651cL,0xc501caf48834c723L,0x1d263a83a65e5093L, + 0x57ee2fb96f709deaL,0xdae3dcc645091321L,0xba0665a906a60a48L } }, + /* 48 << 49 */ + { { 0x517d13b1784d0621L,0x2db4ef27d77b84beL,0x6e2e26866d752aaaL, + 0x95da9fa1cab02667L,0xbe8d91ad423163c3L,0x8f3d59dba69953c9L }, + { 0xf728b1d2d6e635aeL,0x5c4c177deeea663eL,0x97a900a82e75d9c2L, + 0x136c6b1e3ad09defL,0x4bab14a6dd8a2be8L,0xa4ee903025cf1447L } }, + /* 49 << 49 */ + { { 0x05f93697a5235c12L,0x434f91026943a0d0L,0x92696b701a4d3169L, + 0x0a9da44b8c3b1ee5L,0x327f9f79d295521bL,0xf605cb83afd8aa40L }, + { 0xe3bd4ab5d365fb37L,0x6c6a470ce984ea2dL,0x7ad01e6b392af60dL, + 0xbef2dffd5ff8ee6bL,0x4e56deb722efc2ebL,0x1b90570ae14ff270L } }, + /* 50 << 49 */ + { { 0x70718d8e333cd9e2L,0x858c880c6b03a371L,0x5b7f69a5926a3dd4L, + 0xedbed135572f420fL,0x740a21e6332aaa09L,0x665aff63fecf1e3dL }, + { 0xd884a3c1214490e9L,0xed70c29a63cdab1fL,0xc92dfa58786e274bL, + 0xa5395591d7fd529dL,0xacdf81ac3b95b61fL,0x07f801df40cb45a0L } }, + /* 51 << 49 */ + { { 0x4f863ad59230d44fL,0xd176d2764a099825L,0x4a6868745a43a7d8L, + 0xbcab3548fff3e8dfL,0x15028cfccab2c7e6L,0xad077a8874a91fb2L }, + { 0x015700d39eee3e32L,0x524ef9c7386e489aL,0x3be1771b60285f8bL, + 0xe4a5353cf9c33beeL,0x0aa0f2ab244ad683L,0x04e846f98a4c0ed6L } }, + /* 52 << 49 */ + { { 0x326a204790f55f13L,0x194d24db53017b29L,0xa26db785cd4368c3L, + 0xd58943e8238d7518L,0x8e06f8cc3527387eL,0xebc6dc9e071846d4L }, + { 0xbfc08dccc541e098L,0x3dcf0713e4fbc9a4L,0x44e9ba7869fedb43L, + 0xd867cf784fa012a0L,0xc618b2b88733ddf2L,0x4149fd48a737fd5cL } }, + /* 53 << 49 */ + { { 0x5c4c2183179b1928L,0xc54d315d0439876cL,0x07d22792f7495bceL, + 0xd378185e3bc32c4aL,0x8539aab65b31c5c9L,0xc72b1ac640dffb35L }, + { 0x46bb918a2e8d6ae2L,0x102c49f9e8a1d7a1L,0x7c622793cd2764d3L, + 0x5bbc6f023c7aafcaL,0xa41f383bcff71b4dL,0xc8a0e1a9aa99bf83L } }, + /* 54 << 49 */ + { { 0x323aad4991d6b8f3L,0x91b678c0f3d9154eL,0xc141e2424ce74f67L, + 0xb7c38aef65659ca0L,0x5b5f89b174a937e1L,0x739fad71abc55012L }, + { 0x315ed44ccee5f4fbL,0xb0731455360a61eaL,0x39235ff0ee93ce5aL, + 0x6352556fd203baf9L,0x3c22dc6a0ea06b93L,0x195638cb591bbfa0L } }, + /* 55 << 49 */ + { { 0x8bd5a15359ad0688L,0x827e82d8a7323070L,0x9ea55b3af70686e5L, + 0x511c8c3f34c2d054L,0x9364d28aa14a3c61L,0xc4dff9c461374139L }, + { 0x947c3ec9a39c01c0L,0xead11d42108440bbL,0xcc6d893569677f79L, + 0xb1d632710b9b4823L,0x2cec325e63b154e0L,0x45e97c3814a85b9cL } }, + /* 56 << 49 */ + { { 0x11b59f3e92acd14cL,0x188c1bb1d7aea098L,0x5cadf0a19365958fL, + 0x8fef04fcca0b1b0eL,0xbcb4d9fb0c274a5eL,0xe97eb41cba78427eL }, + { 0xc49f0bc55cf06378L,0x2681f12a281b669dL,0x200e9e583f796b81L, + 0x5bbea92b17964262L,0x86b3c15756db0039L,0xe4477c5eead482baL } }, + /* 57 << 49 */ + { { 0x1340e22c050fc1faL,0xd5cc5445bd062615L,0x03ad31601f494b03L, + 0x612919142af1b95eL,0xdb31a06d53705ac5L,0xf590433ad07ae464L }, + { 0xed52363421bbbd72L,0x1f032ad2f1cc7842L,0x212b1d5536a7164aL, + 0xc2cedab7dd973183L,0x29aeeee05e74ada3L,0x579984d8bb666836L } }, + /* 58 << 49 */ + { { 0xbbe5db83e13d34d3L,0xbae5ae959a8a3344L,0x55d2f0ac797d6e35L, + 0x75e78c017cd0abb0L,0xb757f72cbad96294L,0xe52493895d556f25L }, + { 0xc02293538e7675dbL,0xc363c5255c8beec5L,0x7ac23c0b7c87ee00L, + 0x9c5f22b4a7de93f8L,0xc6f0ea64d9644b5fL,0x3fa718d4d161f87eL } }, + /* 59 << 49 */ + { { 0xe8496c463f356cf8L,0x25b5b8742da1b81cL,0xa35ec06330efa9c9L, + 0x7497d85ffdaeb348L,0x312ad677e83f49d7L,0xcb5c346cfe8aece3L }, + { 0x19d7332d61cd4ebcL,0xb03dece0d0967141L,0x47dcb81af5455addL, + 0xbef0e70389ca68d4L,0xf7abbeb9c987400fL,0xbda81c65a1521da1L } }, + /* 60 << 49 */ + { { 0x535f3e4b86882341L,0x5af1c6322e22600fL,0x0403b6e0584a13abL, + 0xa64de86661f59ce9L,0xd22106f738501b92L,0x2932f808ab6ffd04L }, + { 0x8da4cc6e232967f2L,0x4b8fdd9ef3644670L,0xe8cb6ef31e0c51bcL, + 0x20b7b734230c6897L,0x5009176453d9339aL,0x5f5c8c67ca637277L } }, + /* 61 << 49 */ + { { 0x23e333d467232358L,0x3c2807bdea037380L,0x9439cc4626f1dc2fL, + 0x8c87dde53ac29173L,0x601b7245766897a1L,0x9e0b1a4559350e3cL }, + { 0x0818b6cb301db407L,0xbdc4584676b6fbf3L,0xeeca553431bdd954L, + 0x1dfabc033f9be3bfL,0xdf0415dc68851bd8L,0x33be32a67aa9dfa8L } }, + /* 62 << 49 */ + { { 0x8c9017dd4b4e4b5eL,0x02f435dd7b892b2eL,0xe9af9efd292e0f2dL, + 0xa32124c75c4d315dL,0x5c6fde76b31a390dL,0xf1fdcefaa6e46d3eL }, + { 0x5f39dbfe9e9e84b6L,0x574d647d19aab6b7L,0xd5a234cdad1a2987L, + 0xeab841c7dab59c81L,0x5155898db3137b90L,0xc52e9ddd06db2fd0L } }, + /* 63 << 49 */ + { { 0x8617f0d490660ff7L,0x00d73d108b35743eL,0x433e42d68a6ca67eL, + 0x575ecb9beab5cff6L,0x4c64bcddf258960aL,0xb8ffb7f32c23405dL }, + { 0xa98c06691261b0c7L,0xf2701f4a6b9bf7c6L,0x3abe44c41c68efc3L, + 0xdb5ac9cbf12c7a25L,0xf5b4616651120981L,0xf8058f7074d518f3L } }, + /* 64 << 49 */ + { { 0xcd92906c6d6ae962L,0x628356159807d881L,0x0d6929781fdc1915L, + 0x45d01a8c269d611eL,0xe7bd1e709665b00aL,0x086385349bcaa388L }, + { 0x8f189e882dd24299L,0x5f643392b82fb270L,0xca65bf16c633b111L, + 0xc6adc9c9d6f1dac8L,0x0df2c293a3c3381dL,0xdd6ae97d8388cd12L } }, + /* 0 << 56 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 56 */ + { { 0xffdbd0eb3863db02L,0x8b8256832f57e10fL,0xc11acead35e7a3a2L, + 0x4998cf8c67833028L,0x8f3a346b844c7976L,0x0a9d872cdb9b1a1cL }, + { 0x8735dabcb98d445dL,0x93790d80305fa0a9L,0x7c0add49d267a01aL, + 0x2b46c913ffa20d11L,0xf2acef26d8ab2d4aL,0x71b701b93d926080L } }, + /* 2 << 56 */ + { { 0xe9d2a98a5133de8eL,0x37083b60b81b8b00L,0xf399325dceaf86aeL, + 0x03b17c888f161525L,0xd8ac35c984211b9dL,0x220837849050ca48L }, + { 0xa818c44bc9fab832L,0x8882bccee5aea7daL,0x633aaf35f8715b04L, + 0x5463e1b99d8829a9L,0xb18df52d84a820f1L,0x9d5ef891d096675dL } }, + /* 3 << 56 */ + { { 0xd54e2c7cac60496dL,0xc06d5e5d04cd50a4L,0xcb4105e8e60f7f59L, + 0x705db308427483adL,0xf73ba98bf2bff383L,0xa945611a0220e6e9L }, + { 0xc01c46b8d957e12bL,0x458897b7acb1f371L,0xf738dc0bfa3403e6L, + 0x098bc687d2202896L,0xec0c217a5f882e5eL,0x8f25af77a1f4eb13L } }, + /* 4 << 56 */ + { { 0x2615c78259ee4124L,0x4dc2824c76532b4bL,0x9c3b1d771c84a04bL, + 0xb6fc203fcb9f9e34L,0xbed65464c64f7846L,0x04f520a2eb004248L }, + { 0x5c0177274a58fd22L,0x25958482c10d9472L,0xb78c6666aceb0e3aL, + 0x18d3c188fc046f0aL,0x7f3e2f301baa9595L,0xa574f8cd8a2844e8L } }, + /* 5 << 56 */ + { { 0xc899eba381c2d81fL,0xb27267d6f3f0a431L,0x607c8629da55568eL, + 0x6b5472282b1dc1d9L,0x23232311c9c001ffL,0x207a2eb2488f8b85L }, + { 0x3867ac9adac37a28L,0xa36d14d32584a5f0L,0x7398c647a74488ffL, + 0xf6ed920fbe087640L,0x72beddc76319a571L,0x55c2cd826a244aebL } }, + /* 6 << 56 */ + { { 0xb7da79c625f8a53bL,0x6b950bdfd331ad8eL,0x3481b7b54aa36d18L, + 0x6efeaf88ed0e3091L,0xeb017bddc993074cL,0x8431a6d6529dd654L }, + { 0xf5177231bd069585L,0x6d753b103ce85096L,0x194d82d34ca26741L, + 0xeaeffe15adcd1650L,0x4dcec3d9af7758b7L,0xf5fdf6664cc2c819L } }, + /* 7 << 56 */ + { { 0x94bdc7f4a9810744L,0x464195daf045d859L,0x27e2dab0d654cb57L, + 0x1d4e1e537a491956L,0xa1ef570c31d5d099L,0x01cd21ee295f3de7L }, + { 0x8681b00db8249038L,0x17c31bce93781b71L,0x4324e90c6a1b5748L, + 0x44f9324c1222e554L,0xe30ba10fffd53dd0L,0x2e5817a8b48eeef0L } }, + /* 8 << 56 */ + { { 0xa349bb66c8fccaa9L,0x7888755f31a53ee7L,0xa6e1d891c18d3750L, + 0x9985aa4dae8d2bfbL,0x8baec9ae31b33078L,0xee68295a98750e94L }, + { 0x0d834bf8d6ddf305L,0xab33dff39762126cL,0x0c22faaa0c51d098L, + 0x32404042b887a10fL,0x31f6a614248bed32L,0x311f86301ce0d662L } }, + /* 9 << 56 */ + { { 0x5c95cf080d844b0dL,0xe09a8352c98650c9L,0xc1b106c5d089058eL, + 0x2b3cf101eb0c6107L,0x1993fdba3ce6ee18L,0x7234eb6425fc4d24L }, + { 0x8345acfe05f46dfeL,0x07fccf68a2d87d38L,0x14494cea85da7852L, + 0x8737500acecdd9f1L,0x72b1490ca39068ffL,0xce28271acfa4469aL } }, + /* 10 << 56 */ + { { 0xc872326f55c6c00aL,0x6a5f0fa3f912decaL,0xf4ef0ca5a7d1bdb1L, + 0x1dee685b37dc6bebL,0xdad4cf52f1b09b88L,0xc7199f0277f1db84L }, + { 0x7099ef00a3f00491L,0xd8fbbbfa6d8804e3L,0x2a00b8e50ae1e360L, + 0x8a8c9d03fe9be5dfL,0x06e0585b8b1faf6fL,0x19542ee7ae29c502L } }, + /* 11 << 56 */ + { { 0x36cad867e2aa1c5eL,0x7ef21e51317f9078L,0x68efbb84c82e925fL, + 0x973b36769fe751e0L,0x09c4e0c1177d36a7L,0x9c0b7e048a753c5eL }, + { 0x8414cdab15ccad5cL,0xeea2134ed50c1678L,0xd9c1dae8f6585d5fL, + 0x82fd04ab4e5c3d96L,0x868cddf7da3812d3L,0x32a65aeafda07e68L } }, + /* 12 << 56 */ + { { 0x73292e6a60720858L,0xe046a79953160855L,0xf74d56c9ed3b94c1L, + 0x0e371167c67863e1L,0x19b3a9f43f6636cfL,0xe624798d898a25b0L }, + { 0x2ed1fc4dfde2cd6eL,0xd9a7ab519fd15ee5L,0xb6b8d551c487b1cdL, + 0x9fec705ae8936c54L,0x4b779dde1a50e094L,0xfb5100c2c3a4ef5bL } }, + /* 13 << 56 */ + { { 0xb35a7b102704c525L,0x8a77fa5b44276cbcL,0xb4a9cd235ff1a12cL, + 0xc74a017c88a37997L,0x84e26eea9af37476L,0x8a6b8c0e7bbf737bL }, + { 0x90ab7c948f05bd3eL,0x31749075464f3a2cL,0x32f7873c1dcfbd25L, + 0xc0af73d343bc2054L,0x556c4798171d825eL,0x2c84b5b6081542f8L } }, + /* 14 << 56 */ + { { 0xa5907e5c59ab2507L,0x12b86e04cf7df60eL,0x0a14bed18af4bc50L, + 0x462863b20c11bac5L,0x98dde284126958dcL,0x8877e7695625eb29L }, + { 0x869f7214f4fe19e5L,0x29867e51ec0f8c1aL,0xbf498bc078b85f03L, + 0x9dda400e8973a94eL,0x8d8b998ae6e51b1aL,0xedb0957c557ac00eL } }, + /* 15 << 56 */ + { { 0x84b6d5143b7d43f2L,0xcb84c823afb7a2b9L,0x892e8c4c56d2b161L, + 0x52ea7426214fdc0aL,0x07f3d57679763557L,0x9f95fd585a828bb3L }, + { 0x2c7f03d550e14019L,0xab723de7d7eae7b3L,0x4c08189317f4ea6eL, + 0x64cc5bc0ec367246L,0x73077b5ddf11c3b7L,0xfa34b540e08eb4bbL } }, + /* 16 << 56 */ + { { 0xac6dbdf6edc9ce62L,0xa58f5b440f9c006eL,0x16694de3dc28e1b0L, + 0x2d039cf2a6647711L,0xa13bbe6fc5b08b4bL,0xe44da93010ebd8ceL }, + { 0xcd47208719649a16L,0xe18f4e44683e5df1L,0xb3f66303929bfa28L, + 0x7c378e43818249bfL,0x76068c80847f7cd9L,0xee3db6d1987eba16L } }, + /* 17 << 56 */ + { { 0x254ed267050f46f1L,0x36786ff864daa83cL,0xb4a89efc802a3ae6L, + 0xe0027b3486b77d59L,0xb7147905f48d0de6L,0x00733ca710cf7c60L }, + { 0x87efbe387b3ab776L,0x3db10898de9730f4L,0x61f21e1386b7a40dL, + 0x5541873648455b6aL,0x0de378f9a88587deL,0x42dead7a766d18f1L } }, + /* 18 << 56 */ + { { 0x42b8ef51e15ad876L,0x498886e5082e110aL,0x3144e8c964edbd73L, + 0x4b08cf86f79e6724L,0x42d06d53ddfdb6a5L,0x4c9dce336d8b1f33L }, + { 0xbb8913ae4be29e97L,0xe944c922166fdcc4L,0x83913b963c494e9bL, + 0x529d57ac633a0018L,0x632a7cfd242e7d9cL,0xf0e2434dd9b51d08L } }, + /* 19 << 56 */ + { { 0x74768ab044ff52cdL,0xa590ac7eead09902L,0xdc408c53f52c0f5fL, + 0x614a22d6f853efbfL,0x61f391c425126427L,0xb61adcfcbf462fbbL }, + { 0x7b753aaaaffdbe78L,0xce12b2247bea939dL,0xca21f73e95baf09bL, + 0x2a82915e43ca9ebeL,0x67ba04f57936a38cL,0x1c1964f1616b0b87L } }, + /* 20 << 56 */ + { { 0x4dc628c67cb2ec48L,0xc896f99c0cb1e9d2L,0x399ac2e85cc6134bL, + 0x5ac36de184ba73d0L,0x66a334a3e1803832L,0x394af7ea59b770c1L }, + { 0x3df19e55b46f793eL,0x97aaec84bf770a95L,0xf52068b8f8c54408L, + 0xb6f7649f49e05f0fL,0x54d8db0583360826L,0x24748fdf71af722fL } }, + /* 21 << 56 */ + { { 0x68f4dd4956c29111L,0x391ac9910dac9352L,0xb0a8a54206dc9d58L, + 0xb5058ed8fbe70330L,0x8b5e9d4076b593bfL,0x769fb99cd7f2b261L }, + { 0xcdcbb60ec67cce8aL,0xe01a5d5d75da36dfL,0x7e831d0ef7c6e5cbL, + 0x0f6bf54bccdeef00L,0xed49ad3998ba4d8dL,0x8d512c83614d70c2L } }, + /* 22 << 56 */ + { { 0xc1910b2545b4f6e5L,0x54c6ee8489fb712dL,0x80b6fd47f5747ba2L, + 0x3d81e7efd6d4f856L,0x8b9e87418031f1bdL,0xc591d451f2327316L }, + { 0x4830d9971e0f1c1fL,0xeabe29bd86e92024L,0x2f2053a1b8c68d7eL, + 0xff4eb9e879d00ad6L,0xa0c93249f4b4cd89L,0xe127d9d3cb9e0761L } }, + /* 23 << 56 */ + { { 0xeb947df3492d73ebL,0x5474817b0d32c2ddL,0xeb01bef7a9440e93L, + 0xf604581d8085d1f8L,0xf69daa189f69ec8aL,0xc79ac48e71748716L }, + { 0x5141c75ad4beef28L,0xf7dfaf89901c44a6L,0x7bcbe4812e81ed85L, + 0x57ed0e6f0c5a4423L,0x7cf189651cec85a5L,0x8ddfe8a5beef12b0L } }, + /* 24 << 56 */ + { { 0x60ee08b46bc0b979L,0xa31cfd961aba7f4eL,0x66c05a6358bedf51L, + 0x2ae6ec3854df9266L,0xe7dbda332771b08aL,0x44455d312a09fb28L }, + { 0xaaba39171cec98a5L,0x9b2b12258cb543d0L,0xf47a9cd16af6495aL, + 0xe207f3aac6cd8a16L,0xf98952878ae828b6L,0x37e2475725844053L } }, + /* 25 << 56 */ + { { 0x7c8137d8f93723a2L,0x78fa2e03cf552846L,0x3becd2627d11977eL, + 0xdbc8e9b34e9a700eL,0xb2c7798d20decdccL,0xecae57179523bb6dL }, + { 0xc0fec0677fa2f633L,0xe270b10702aab6a8L,0xda280b374dcc797bL, + 0x50a163b86c42945dL,0x4a3fd6bd363e44ceL,0x0aa7e33d38bca4e6L } }, + /* 26 << 56 */ + { { 0x19c7f098a693d0aaL,0xb79d84244bd22a29L,0x19d91d12a9b3c2ebL, + 0x2ae96bfdde735665L,0x2f9c9a773d8a85bcL,0xa74bdd46cbab80f5L }, + { 0x25a2486cdd9f70f0L,0xada155c9754513d5L,0x8aecd7db4c3e9494L, + 0x9c3951ad2cf6665eL,0xd35780d44a9ec29eL,0x064983964cfd7821L } }, + /* 27 << 56 */ + { { 0x23407aac0834f890L,0xad7b7b5599bb065fL,0x3254aa7e4ba2b4ccL, + 0x37f37fd1663f9213L,0x0c72c3111c5a51d4L,0x6e6df84b9989820bL }, + { 0x576a320e1ae2f321L,0xa5fc617c3c62888eL,0xc4f1be4df6c40362L, + 0x01b21892dbfaa5b3L,0x6fc0442390b9a5e3L,0x22a70c8791495c30L } }, + /* 28 << 56 */ + { { 0x365e1382183aee81L,0xe9f2245275d289c8L,0x543cb5c7b70962e2L, + 0x853971711cea2e37L,0x8b31cf530adfc82cL,0xf9a458bf3b67c705L }, + { 0x13b1cb3334a9b3a8L,0xa4325b403732f6b5L,0x39e997ba04e9df8eL, + 0x24c0d6ebf1d542f8L,0x9cb3f1abd82901bbL,0xbbaef37a4cb34763L } }, + /* 29 << 56 */ + { { 0xc4881080b08dd648L,0x21869be8f1fe4e15L,0x63e158b112501ea3L, + 0x48a909ce32408693L,0x77fd2cf062b24495L,0xf7d1e134db9322a5L }, + { 0x4c02c8bcbdb19eedL,0xe03cd00e8a20b335L,0xe04271c530632562L, + 0x549e5dba603e1681L,0xf01b38f95503b61fL,0x244c81920b3fb785L } }, + /* 30 << 56 */ + { { 0xb423030c4b0c7247L,0x242d409f149f8cbcL,0x6094885e9c1f518eL, + 0x6d299dffe04d97ebL,0x152d05bb09903069L,0xf5656895fe235dddL }, + { 0x801e7f736b22ac0eL,0x73aa6df46ba6dc97L,0xba498bc0d66e5d8cL, + 0x8054e17d36b8c78eL,0x241bd2e21137fdf1L,0x8e79a943b97dec15L } }, + /* 31 << 56 */ + { { 0x94e617abeb64269eL,0x39aef936b410ae02L,0xdbb744c325fcc976L, + 0x5072bfab38a5b366L,0x3998aefea3f5d715L,0x0bdbf555a74e281dL }, + { 0x50d2feece24dd239L,0x835925ef46324c5cL,0x53c4eece7a4dad08L, + 0x340fef207c358d83L,0x9e2189da30f04396L,0x2bc748d727e322cfL } }, + /* 32 << 56 */ + { { 0x1238e097ae658422L,0xb4631ddb568df55fL,0x451254e7f74c5c50L, + 0x238b16d28805813bL,0x23987b28925e7a6eL,0x93b72e2d2a1a10bcL }, + { 0x944c784d05e44b7fL,0x7d70fd098c8e3120L,0x6bf1ab2aead45716L, + 0xd5f8f0e631c04205L,0xac062526a10b8881L,0xa1a83cf0fe5505a8L } }, + /* 33 << 56 */ + { { 0xe1e05ff89ea47326L,0x88219a1ffbfc7f61L,0x9cbd0b387dcd3008L, + 0x751d03847671a68eL,0xd73ed70d28e0387fL,0xf66f9cfea9485256L }, + { 0xac68aae1ae153e0cL,0x92eb6542e81b1282L,0x9617d45464541adfL, + 0x81b4d94a9d489e95L,0xafd5cd4620f31ba0L,0x35700392e5a38941L } }, + /* 34 << 56 */ + { { 0x52296be3b71ea9c4L,0x82b05a43424cadf9L,0xb6d329e8842699e3L, + 0x9dfb91bf9370f2c1L,0x0188b738994ecc71L,0xa9a7b03b5ce8b100L }, + { 0x99198b2a25c33035L,0x772795a7e21895d5L,0x37dafa4c42173e01L, + 0xd37f03933ab27d91L,0xf3500a7d2afad1f3L,0xa433b5fd87eac06eL } }, + /* 35 << 56 */ + { { 0xdc193cb5243a97bfL,0xe367f27ff5715184L,0xc4bb95c6fd9120c6L, + 0xd2bd176bbc5f7ba2L,0xf2c0f86de966c1deL,0xc69ab26e811e70cfL }, + { 0x95756460e87c55f0L,0x6b62ab136a59c832L,0x6e971c6c128448a0L, + 0xca72482e91ea44a3L,0x2602d4795dca0f8bL,0x8dadd3e25519433bL } }, + /* 36 << 56 */ + { { 0xfe0553be23246f68L,0xccc1d774d8ad4128L,0xbec668d8cc155edaL, + 0x7a80e9b44231506cL,0x579cb5f42aa1740aL,0x3a61b84fd8b35a2bL }, + { 0x0478c05ba3b519f8L,0xf518ac09acfe39aeL,0xabc15e9076c956e6L, + 0xff35db67dd55d268L,0xbe066679bdbba89fL,0xf7385df12062b845L } }, + /* 37 << 56 */ + { { 0x279d7ffdfc12078dL,0xeb14155eb8f302e9L,0x5f1b11e165b3c14dL, + 0x08510b461bd36b3fL,0xa7f5b2ffc9d73b4fL,0xe5e831557aa09e40L }, + { 0xbed67135cc3d88d8L,0x7b2775f7017a43d2L,0x9ce22ff24c58cb64L, + 0xab88d04849ede1eeL,0xcac13762da63daa8L,0x70662331b1dbfc4eL } }, + /* 38 << 56 */ + { { 0xe4f7022200a8a9adL,0x8d1bbab7d42fffcbL,0xe024970e368ad5edL, + 0x231ef631b4c0c9f8L,0xb47ca0386760b411L,0xe1f297ff179e6d44L }, + { 0x2e5ec77d3e071736L,0x90e20be915b29c93L,0x33961b6dbb7e7237L, + 0xa854df5b42176851L,0x67d223e4a8f4bac8L,0x5464a46f0dee39fcL } }, + /* 39 << 56 */ + { { 0x525a553b32230b65L,0x7bbde6b816bb6a4eL,0x2f5bc6d229f12292L, + 0x5d86858045fbcff9L,0x6ce4fb249f932964L,0xd7cd175098e05ef6L }, + { 0x794b0248e1366d8eL,0xa37afa66332098a0L,0x2dcc1888d9aac70cL, + 0xa01ba83ec15b9fb8L,0xd34ddf851df4b59cL,0x92289e954f829510L } }, + /* 40 << 56 */ + { { 0xdec879d51c9d09f1L,0xdfa9e7d61b371576L,0x8c705c7937fb3410L, + 0xd770153e1f2a02bfL,0x208fc8f18043ba69L,0x58aebe6e25aa3453L }, + { 0x191b69e512941f03L,0x27dbb050d7966e0eL,0xa5196bb7d16bc20bL, + 0x5b6bae47f22b30b2L,0xbddcabda8ce7b419L,0x6e3cfd373b9f5a39L } }, + /* 41 << 56 */ + { { 0x605d4b83330c07f8L,0x4dbe47646a0ed45fL,0x1e715823d7e4163dL, + 0xe337a67dcea3306dL,0x55abf0684f18a604L,0xaaf69d5ea9f57370L }, + { 0xddd09e8129784840L,0x17fd42b9a4fff5e9L,0xe99859e55acee616L, + 0x41d691203b927ed5L,0x35cc99675168f505L,0xfc311c24431d7d60L } }, + /* 42 << 56 */ + { { 0x415f7f0da581c54dL,0x67c678244509f31fL,0x36fb92eb988f449dL, + 0x22d41b1a94181fe4L,0xacc68410df896026L,0x4a10e46f9ccc4df6L }, + { 0xf805a1191969cf2dL,0x7230a26b32ad355cL,0x9d200562e9abd845L, + 0x2db90c3b5cb55349L,0x80b59daa29bcc42cL,0x81272ebc53d32149L } }, + /* 43 << 56 */ + { { 0x6aaf15f27756bcffL,0x5391bc009b645589L,0x46cc4480a6fc61a0L, + 0x6fde9d53293d676dL,0xd6c35628d7618399L,0xdda13a0853daac23L }, + { 0xb6e6c20c0fe7995dL,0x32eb3468d8d41d55L,0x8927d508c19c5995L, + 0x3907eeed3c229e66L,0x509af79f27972057L,0x8a7f44f750e2f170L } }, + /* 44 << 56 */ + { { 0xb91ffd21c87b3fe1L,0x0fe8389b34fe2825L,0xe22d45d74bf4c8cdL, + 0xb575ae4cd6d8308aL,0xa7fa552e82994ba8L,0xfb67a86fecb08870L }, + { 0xc3bebdf8e6dabcb1L,0xef18b357b5bcf114L,0xed518499a4b8eca5L, + 0x0fec83c5df16ed99L,0x5d353a5856b5649eL,0xc858c1d1cec900e0L } }, + /* 45 << 56 */ + { { 0x7a65d2660d85e627L,0x96170bb90bc010a3L,0xaa6e0055da030ad9L, + 0xa75ab280ff4e4a8fL,0xec14e68c0be864a3L,0x05424b9cc17723b6L }, + { 0x9ed54bb218ca85d6L,0x035edc14b78b34bbL,0xc116914929617416L, + 0x0a00e0086cb0d801L,0xba40f1207d4a638fL,0x54b1e8cc9d8bd0e9L } }, + /* 46 << 56 */ + { { 0xbbab4ab54c88db57L,0x68dbee6f9ee9558aL,0x31b988e140da802fL, + 0x9d117c37e90b2221L,0x443ae099025b66c7L,0x8568bd6f2538a654L }, + { 0xf806d8636720df01L,0xe390adf2b649ad8fL,0x7851f8e039d1c315L, + 0x8185ae1a5e650f1bL,0x3dccfc4c9b562532L,0xae99ae835f427c40L } }, + /* 47 << 56 */ + { { 0x99542ca7564c7ad5L,0x682eace49a96f25dL,0x2d01b2488d933a6cL, + 0xf96916ddb8604277L,0xad3259d12e4d7419L,0x9085251fc26981e5L }, + { 0x848219363d2ec970L,0x723ea6a5392351c7L,0x3fae69a55e5448c8L, + 0xf6eee650dfb03d49L,0xe2e1df1ef8c58715L,0xc603b61f1a369206L } }, + /* 48 << 56 */ + { { 0xcbbd8576c42a2f52L,0x9acc6f709d2b06bbL,0xe5cb56202e6b72a4L, + 0x5738ea0e7c024443L,0x8ed06170b55368f3L,0xe54c99bb1aeed44fL }, + { 0x3d90a6b2e2e0d8b2L,0x21718977cf7b2856L,0x089093dcc5612aecL, + 0xc272ef6f99c1baccL,0x47db3b43dc43eaadL,0x730f30e40832d891L } }, + /* 49 << 56 */ + { { 0x7f3a3e5f4447ed08L,0xa6302f7bf94d49d0L,0x94fd2ad33b2abc46L, + 0x98ffc01fe4249c1dL,0x6f3a53bf8db4549fL,0xfbae12df25566cceL }, + { 0x63fc92d3c2e84d15L,0xc355b46c4f5abdebL,0xb50b43a05678d0cfL, + 0xf4d4b0b15681d628L,0xc9f11d63fb3bac7dL,0x444b748cda461eb1L } }, + /* 50 << 56 */ + { { 0xafe9adafc9845a07L,0x484a9eb9df6a1305L,0xec32f0bdb0f111dbL, + 0x742b41cddc7b100cL,0x5a7ea89d23c5f849L,0x1ea8801fa298aa82L }, + { 0x183e1750cb001f26L,0x66ec5daa49da5bbbL,0x8071ff322d05ab57L, + 0xaea9e694e1944e0eL,0xc993754437b85438L,0x2c2467b4faaf4f22L } }, + /* 51 << 56 */ + { { 0x38f87acce602c278L,0x72c79590515854dfL,0x9d466a765e7e2f6dL, + 0xe5f6704772081935L,0xb4b56288ad958812L,0x7f4d9e1395b08242L }, + { 0xb38d0ddb962f0f6bL,0x969d4327e5f76463L,0xf7c7c799f6ac01f8L, + 0x494066673e6ff230L,0xa81fa10dc7e9c1b6L,0x2fcf26bf8093c2d3L } }, + /* 52 << 56 */ + { { 0xcca6e9cfa754256bL,0xfdd79280347723f7L,0x8179d6f52d69c6bdL, + 0x156a53fa94cc8567L,0xb819d70324655f28L,0xf86872e2ebfb198bL }, + { 0xb158e73939ccd668L,0x655db8248de67826L,0x54399a79c621cf3aL, + 0xc55900d498a09c9dL,0x5423edbf20278b3aL,0x06a625b280ba89cbL } }, + /* 53 << 56 */ + { { 0x0f152d69869c4f68L,0x0ed4205a9f0068fcL,0xda68af4f25d4490eL, + 0x715fcc60745c00afL,0x70ab559aad63dff1L,0x7d0a7b6a9b8a37ebL }, + { 0x82ab7a068bca8498L,0x4f012fb4297d954aL,0x8b139e6ed5f6a4b7L, + 0x597316e4b856ac26L,0xeb64b5894387367aL,0xcc92eeabbacb7e74L } }, + /* 54 << 56 */ + { { 0xb53560e968fdcf87L,0x4ed638bd3cbd0887L,0x57f3f38f6080d1cdL, + 0x50370e0c1e4e3ae8L,0x14c87fad184a1ecfL,0x3d06f78d0af7b2ceL }, + { 0xd9370e24fd595621L,0x1e462483c9fbb559L,0x1ee5d81ca0aa5c0aL, + 0xdb2524557419564dL,0x782ba91b57585be7L,0xb2d14bcc5c431c72L } }, + /* 55 << 56 */ + { { 0x9cb9de6fd62ebed6L,0xb7f23b1916c6d571L,0x69b4a8dfa8b307b5L, + 0x78a7f74e19dc7e39L,0x423405152f47c94bL,0xf1c2a5bc31ff2d82L }, + { 0x98c1c3f7b145387eL,0xdd9d24d885e635ccL,0xeaaececa07397bc4L, + 0x6bf6a8469b0cd4c6L,0x68052950680dbd05L,0x81a071b60ce07df9L } }, + /* 56 << 56 */ + { { 0xf3fa8bec0c61d5a5L,0x98f772fc0dedaa77L,0x45a382161146d42bL, + 0xebef5d4a58821ebdL,0x21498af30c1f0e6aL,0x3d8699144758014aL }, + { 0x6f2276ecb625c7e0L,0x68d6a144fb55d708L,0x0bc836e0ad56b494L, + 0x72b6d8850f58ef70L,0x0e0be2887bd7c1d1L,0x70549a879c277d39L } }, + /* 57 << 56 */ + { { 0x39a445d2dbb2bb75L,0xda2a211b1ac42cd1L,0x934bee9a8e4cf8f9L, + 0x5d0dde6a24801bc1L,0xb2d4261d23da4ea7L,0x5fa9059a7187cde8L }, + { 0x49298bb651f05f9aL,0xff0c4a0422a7bee4L,0xf466232da6a29be3L, + 0xff2e157a995c1904L,0x3a4ee4537b31bdffL,0xb4a736d7e41f6eeaL } }, + /* 58 << 56 */ + { { 0xaed55c123fa96c0eL,0x8f90803f6e08adf2L,0x349e5807015b7cb4L, + 0xdb3f05e314656b3cL,0x9289bbecde8b2d9aL,0x3cad12e0c7f28356L }, + { 0x7a68fa54959fe89aL,0x2e7135d0a77f956fL,0xa0285cbabbe35884L, + 0xc547ffe7131ab269L,0x82a902bebe33b425L,0x5a793a790c71b02aL } }, + /* 59 << 56 */ + { { 0x2bb2a929c645c6eeL,0xfc6cbd471e651728L,0x4ec3f630c07af98fL, + 0x118231588e4a8ad5L,0x99a2b5de1303f68aL,0xcc280b182ec9b8f7L }, + { 0x3d7b406ad7298d55L,0x63941bceb9f83957L,0xfeeb132c463a64c6L, + 0x243a2e2bf76a6c8bL,0xae72bf2fdad18d64L,0x774423431987a4caL } }, + /* 60 << 56 */ + { { 0x06de549d78dc1526L,0xa27fc0c1f52c5766L,0xee5ff3d8e9485b1eL, + 0x7af2fbc64bc530dbL,0xa266d6c810f9dc58L,0x866abeed8bfa4d74L }, + { 0x50356d7fcb7c7018L,0x4ae502e07c962af2L,0xb98b449cf011990cL, + 0xfcc8446b59e8535fL,0x25964ab0088776ebL,0x3848aba2ab6cfe8eL } }, + /* 61 << 56 */ + { { 0x9f2c62cbe14a2c5dL,0xcd182e386b113f03L,0x2275ad4f525a15aaL, + 0xd5b7d1d9eb373133L,0xd3c47b9b07929822L,0x60b043cd8fa8e8e0L }, + { 0x603a3403d3958f57L,0xefa36ad67b79c263L,0xfe33dd9f3742ac39L, + 0x30f40b3bb249f9bbL,0x9d2902d20a3b2e7fL,0x173f7d1a899684f0L } }, + /* 62 << 56 */ + { { 0xdcbeff5bf33bdff0L,0x963ae65ee9684a3bL,0xe03586882bcd272bL, + 0x756695068942f107L,0x14319d19262e422fL,0x5c0ef45a2265b294L }, + { 0xeb897bd8a9f64203L,0xa3b259d742b1640bL,0xdc34ee2dce66355cL, + 0x2fab125eb4e13438L,0x1b93a820443420b7L,0x79c46f97b4ba8382L } }, + /* 63 << 56 */ + { { 0xafd8cb2006e55b9cL,0xc88f38ea2530a11aL,0x628d10bfe4efe221L, + 0x00df0da42a8d983fL,0xed45860508a2fce0L,0xcd7882b86a01efecL }, + { 0x93ebd86c7efcbf7bL,0x578f9fe7e3db504aL,0x3c584008aa5e83e8L, + 0x5bf38b4ca8368754L,0xcb4a9cf905c05ca7L,0xf77ab684c634f28fL } }, + /* 64 << 56 */ + { { 0xac92ee1537d83369L,0xc968c187fecec65cL,0x29a7ca876e7a3265L, + 0x0f2b7e7a8456c9afL,0x7471824e9754326fL,0x498687bf364d2ec8L }, + { 0x86d8aacd3c6ee351L,0x01ee6823f6f41e85L,0x9805fc881d79f7ebL, + 0x377ac3a40040547dL,0xd39215d461b4e90bL,0x2547416e4c5fd81bL } }, + /* 0 << 63 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 63 */ + { { 0xa10292b907a6fbf8L,0x292c1a203fa6235bL,0x7a36f18f73ad7a1fL, + 0x8b2c7b0c5897b11fL,0xf7b9a272cb664c61L,0xb6d366af8f81e22cL }, + { 0x3b99b2118e342bbaL,0x03ce158bb06ced2bL,0x3af1175d001db74bL, + 0x526f08467159cb8aL,0x6a3c6e1febde4601L,0xfad5963b8c232eacL } }, + /* 2 << 63 */ + { { 0xa54768dab1b43eefL,0x13e41f47e14fda22L,0x774df203faef6863L, + 0xf795a034bd7471b3L,0xf0958718b47de2e9L,0xc92f7888e1160cffL }, + { 0x86ded97b0146c790L,0x015918f5480a4b7bL,0x05588920424e8459L, + 0x37455914eecf8b2bL,0xe7d3df1fb968a6faL,0x07a0ffd6bad0719fL } }, + /* 3 << 63 */ + { { 0xf13f55e619f6ebccL,0x63720df2a266b368L,0xdbcc937f3bf1a890L, + 0xd3faff625f326fa4L,0x8b33bae9019730d0L,0x7879782af9961795L }, + { 0xec7e75bc93735e44L,0xfbbf6d225d5702d0L,0x26b6e1d53bc2ddc5L, + 0x00345bf714941d10L,0xdd719676a745c77cL,0x2869b11881c523dbL } }, + /* 4 << 63 */ + { { 0x2566021f98d23f6fL,0xfb883e1234ca97caL,0x34e047a5d9f51b69L, + 0x0b50d91df8efa646L,0xc2bbcbb2971f584fL,0x4136f0e40907c91cL }, + { 0xa7ebeb0de735cc48L,0xa7d1bedce113c8faL,0xc04d9a073f5c962aL, + 0x95c155e53ff74a2fL,0x923c65a53df0749dL,0x10d5f81227ae35d0L } }, + /* 5 << 63 */ + { { 0xc08cf7a1a128747dL,0xeb34a1c02eca6776L,0xff6e7cdfb596491aL, + 0x17024305eddd8bbcL,0xab92b54cf3c46414L,0x2a995b7759134eb8L }, + { 0x97525904e48cb259L,0xeac065ed1e1da01aL,0x16cab74a14c5bf38L, + 0xcd3e2516c14eda8fL,0x3ff38094a8de7a9eL,0xb7340214359d653eL } }, + /* 6 << 63 */ + { { 0x4d37c2663e7a369aL,0x092dc32c3ae62c55L,0x566da2e928ca9d67L, + 0xa9771c1a79beb236L,0xaf6b97a976f801e7L,0x3afd62e771259358L }, + { 0xc23a5e32cd541e77L,0xae4c90a301660ff9L,0x3f3a233b1911ccf2L, + 0x93e4664cfa3b3aceL,0x4bdc14832d4c5f5cL,0xfe03d3c36abf13c0L } }, + /* 7 << 63 */ + { { 0x9649468631b26990L,0x55222e9fe3fd62f4L,0xc8eaba742ee74b8eL, + 0xfa43617834d198efL,0x475b688e892748f5L,0xc6eb426541b9822dL }, + { 0x535695bebdae951fL,0x45e69033e909cce4L,0x40354e72b1829154L, + 0x1005ee6d5c56c3cfL,0x61b36a754a3fec51L,0xae644f3872f2f56eL } }, + /* 8 << 63 */ + { { 0xd5469c7becee6e87L,0x056180bc33a4c917L,0xf881ca21a16caa7aL, + 0x221de182e6cc7f39L,0x10d61ab531378723L,0xfb763bd9520c9660L }, + { 0x145214cd0d6b1541L,0xd9f7ff2dd70223e7L,0x9fce59e30cb1fe69L, + 0x2e6e77fa3e299fe7L,0x3a0cf652d5af78cfL,0x50cc42c53e852159L } }, + /* 9 << 63 */ + { { 0xd2536452b8da85a2L,0x5c15dabe331197daL,0xf5a89366aecccec9L, + 0x8f998baf2d8352fdL,0xb10e6c80f56159d2L,0xf61ceff379eb9affL }, + { 0x05bcb93d1c4283a2L,0x4e1abc521d8cd941L,0x898c9a49b46b343dL, + 0xcf352f3c6e423ae6L,0xb1db207f6fd42c89L,0x08f36a1edab295b4L } }, + /* 10 << 63 */ + { { 0xebbe18b7ed31fabaL,0x046e248dd74971d3L,0x3ddf5a2a0b24f97bL, + 0xf9a400c262fc6124L,0x9ad9b0bc6b03b73aL,0x9fa97c56153c8fdeL }, + { 0x1b6477da00b73ea7L,0xec59f64a21b2f3f3L,0x4428712895306955L, + 0x4b5db01db9e77579L,0x237edf0bde05e0d1L,0xac904b01855332f5L } }, + /* 11 << 63 */ + { { 0x6a37fc505cf708c5L,0x8de4dd7c30497ceaL,0x6978648161b8bf39L, + 0x3cb303375d7362eeL,0x0e24d09237ed25e6L,0xd474f3dc2f69ce20L }, + { 0xe15d98a0edb40541L,0x5e4a87c91466f464L,0xc3cefc9eb68923cbL, + 0x66f10920f22c9de2L,0x3c18f9ea9a51b3f2L,0x706237bef40e6204L } }, + /* 12 << 63 */ + { { 0x0791dfa1df764716L,0x31bf68768c66da07L,0x49f25b77ccedf4f3L, + 0x05170ccd5d965c05L,0x37d9521bd49e6727L,0x1548251286a00176L }, + { 0xdab444936c00eb48L,0x102c6b95e00c5c5dL,0x43660c3e4c2506baL, + 0xb2fb26165ec6f132L,0xccc4221a99ac7691L,0x05b29758a576deb5L } }, + /* 13 << 63 */ + { { 0xee84fe05a5731e27L,0x3251ded005713149L,0xbfeeaf3c7c5e7260L, + 0x3db0b6b2f048907aL,0x38728debb4a6b923L,0x853997d9d1142e10L }, + { 0xc636e3874b641cd1L,0x69b10f43c629f4f7L,0x6f10a95c7deddd0fL, + 0x85b5a7a317f56374L,0x28cd59435c329333L,0xb37621f7d1e476a1L } }, + /* 14 << 63 */ + { { 0x3a17f86d48341ba2L,0x558ef6e8ba6375bcL,0xa86ea3f0927935e2L, + 0x2f43742ac04d4fb0L,0x32a30bce38769421L,0x5a6d6a62d8d3912fL }, + { 0x34154b19c20e3fd9L,0xe95d3843fc85f907L,0x26cfbe0f9f7a13c0L, + 0x50d50b3a531736e5L,0x81849773b2cfa2c2L,0xc81523e63ba8ae5fL } }, + /* 15 << 63 */ + { { 0xac9b0573c2f899caL,0xd9c4fc1ff747ef78L,0xbc205571c7714e62L, + 0x726bbf311919f8c8L,0xfff68adaaedc0450L,0x9f4bc0b9f4001089L }, + { 0x5d10a660fc5dcfeeL,0x1ea644fbaa9f25adL,0x4f5cf102e5a144d4L, + 0x4275b6021521f249L,0x9c62750522d8bcdeL,0x3ebbfc5bb7df57afL } }, + /* 16 << 63 */ + { { 0x4a873076ad8c49b7L,0x891598ce7146575fL,0xc1d3042f427ea198L, + 0xdc592111ed259219L,0x0abdbd16234850caL,0x26b9412643b6fe8dL }, + { 0xd3c79d1736a1cfe9L,0x576386219a2b3bafL,0xa736535d5a98bf65L, + 0xacb3b7ddab2cdb2bL,0x37d3743adaaf89eeL,0xf19d9aba0b348532L } }, + /* 17 << 63 */ + { { 0x013b49753e09dc4bL,0xe548f7bc2d034deaL,0x65ffcd710b861c72L, + 0x80f4d7a2e07dac01L,0xd1889dcf56c1a8b1L,0x14ad62d4789b133bL }, + { 0x082e3c082e80532bL,0x0562a7d80b9d17e2L,0x4f8613095d57e2a7L, + 0x79f21d7255f93514L,0x22c4f68c595c0f33L,0x91d9bd5ba22c0c33L } }, + /* 18 << 63 */ + { { 0x30539655b29eff74L,0x7ba206ebe723167cL,0xe20c3ce488110a02L, + 0x52b406b97c124481L,0x050111c68c74a728L,0x3d594a6bc57cd9feL }, + { 0xd4b2a271e5f952d9L,0x7e52d63b080da0c9L,0xa6463d65f53a6cffL, + 0x9ebcffcfcc678e26L,0xa657f27b2f2b9424L,0x850bd2b871da5c9aL } }, + /* 19 << 63 */ + { { 0x9f3c395b7d4e1a14L,0x2f99aa23bd7301efL,0x50eee34e3017f166L, + 0x88c951ff4c9cbb4dL,0x90c0422ad8dda2f4L,0xe8361775d49cae19L }, + { 0x654db0d250da6138L,0xe4ada30ee03c34a3L,0xde0d3787832ccf4bL, + 0xd1bf435641b94c86L,0x347531c37db87eb5L,0x6942e7e30fb51863L } }, + /* 20 << 63 */ + { { 0xafad01a0d93c54b2L,0x659bff9695536c49L,0x7b91aac2b9734c15L, + 0x55c7f08224e02f59L,0xebcb71e73a26e551L,0x5b7225f76c6343ebL }, + { 0x021c48fb17d5e775L,0x57536a42bd859c87L,0x24852cc0ae2b63e9L, + 0x21515020c0ce0ef1L,0x2ac7336c8fed825eL,0x4bc87feea0152819L } }, + /* 21 << 63 */ + { { 0x7f9813e94b82bbd5L,0xc01f14624e697d08L,0xf02d9eb293de010eL, + 0x290c503c50db5ea8L,0x339341f033edb639L,0x962abf5f7cd7f6c1L }, + { 0xbb1041ae95fb9e8cL,0xb8c9f9d6dbd8525fL,0x8658a54f0f5244b2L, + 0xe9326e455b84eea8L,0x9ebdfe4f54f11de8L,0x3c90b0cedc740440L } }, + /* 22 << 63 */ + { { 0xde6973e22683ad60L,0x35fe4650eebceb58L,0xbcdbbabf7c719a33L, + 0x8bce8111c076ca95L,0x8f7176deeb6bd711L,0xd04e9769d240a56fL }, + { 0xdef7d8fac8e218daL,0x04cff5976df28152L,0x2a1af6e24bd1cca2L, + 0x9397014edcb911e2L,0xa251339038677b96L,0x0dc48a8fb61b462dL } }, + /* 23 << 63 */ + { { 0x42eab6610197a8d2L,0xdc4a557ade082468L,0x4cf68d6090495f66L, + 0x6dba8de79032929eL,0x304b38cc827b5d7bL,0x8e57275cf32f5063L }, + { 0x4b555a0337280c95L,0x49c1e532ef8ddd18L,0xa2d8eed45459adc1L, + 0x2b353217bba3cf41L,0x11f3c90cefe8f005L,0xb3367fa0d55916c4L } }, + /* 24 << 63 */ + { { 0xe7c396d64654712cL,0x1fa5ea507a26e994L,0xaa98768709012b83L, + 0xf1ef9792e9b17e98L,0x2c22bcb06dc2db10L,0xae42ddf6ed4be80eL }, + { 0x672080f62e743405L,0xa15a7f975b7821d1L,0x0cd912f247adbf07L, + 0x6919c0dcb6c4ae8fL,0x62b13edd14c6253cL,0x66f35919f8032287L } }, + /* 25 << 63 */ + { { 0xc992f6fe05f3b31fL,0xcdcf59b56a3d4522L,0x69901b3815df24b8L, + 0x4b9874029f6153b3L,0xeb09cbc1bca86176L,0xbe78cd7d446289c4L }, + { 0xd4aced42b933fd58L,0xe0dc6f306a326de3L,0x4bef32960542a5f8L, + 0x3eb8d14106f537c3L,0xbb45a994b6f0d0a9L,0x340c025d3f4a01b8L } }, + /* 26 << 63 */ + { { 0xdfcb3255fa371ffbL,0x3fb4a22c92bb6b01L,0xd96efc1605396353L, + 0x2ce2228ce5d2bc25L,0x59483843212c7eecL,0xdca7173882996047L }, + { 0x44dad56d8de87b1dL,0x622f88910b6222d5L,0x1abbc501d5d3a9ccL, + 0xdbed73a5ebe52e80L,0xa7f785b1c98c56efL,0xa32471d3d343aeacL } }, + /* 27 << 63 */ + { { 0x65d39f8ae510cee9L,0xcc60cd118dc5e825L,0x3b6ac6627ed7198aL, + 0x5d7fc001f33edc87L,0x0218ffc453e978eaL,0xecb762e57bdfcf16L }, + { 0x8e7122047966b202L,0x1c502404e6b99602L,0x0acb73f1131cc36dL, + 0x81d1132ed4369a1eL,0xbca89fe8377271a4L,0x1353a883262a2e18L } }, + /* 28 << 63 */ + { { 0x2713b58c9d628e1dL,0x3729960afaa8ba1eL,0xc3438130ab53bc93L, + 0xcef9eda5e9c165e7L,0x9bacd1c3fd02650bL,0xbb300334540ece72L }, + { 0x21f5a5d3d9c4f0edL,0x1ba32e4ff7c19269L,0x8f073beb2cf320fbL, + 0xb49766c45599646fL,0x68180d6649e4f200L,0x8203d8aeeaeddb36L } }, + /* 29 << 63 */ + { { 0x7b19780fdbbbf57eL,0xc094d6d9c2207635L,0x241898ac6bb652d6L, + 0xb61b25724923ce29L,0x26ecd97508000048L,0xd08c54e5f5f96b8fL }, + { 0x19019968c1604cc5L,0xa9940e9edc3f31b9L,0xbad2d245c3614a9aL, + 0x7d3cdb2d411e63b3L,0x88d842c3223638ffL,0xbc5427d0cfba2b48L } }, + /* 30 << 63 */ + { { 0xe6d78b7f60085b20L,0x0aa1d62bf318d226L,0xaaa4391df6461e64L, + 0xb15ee4a7213c949bL,0x183f043be4bd3dbbL,0xa1a87996ca49f456L }, + { 0x6030ed2ef6ed22bbL,0xa2002784fab7f7a2L,0xfc40914dd850cdbaL, + 0xe63edc4c7df80ba3L,0x8fa35ab57b27ddfbL,0x3bdaec795096ea04L } }, + /* 31 << 63 */ + { { 0xf33cc5ee452881ddL,0x89c144a38966d47fL,0xbfa8395149156a93L, + 0x0069bff358707b05L,0x2caf814cca12a0b5L,0x1ea71ce71794450aL }, + { 0x08fd2b1c63d22a26L,0xdb08594eb3876737L,0xf459049a57b3669bL, + 0xf64ecaeefee0d4ccL,0x9da2177c63f233a4L,0x042fcca84e54f053L } }, + /* 32 << 63 */ + { { 0xa68295da2caf088bL,0x23d6439a5c8709feL,0x8deba0cffe0c3df0L, + 0x5b4d037b3cd00a1aL,0xe9edc429aa0f9088L,0x6f5827e35847def7L }, + { 0x9739d03d306ad966L,0x7c6b18afaed51d04L,0xdc3d34ff1759060aL, + 0x029e9aa9a7e94dbbL,0x2a3cdfa0f7e8b7f3L,0x42f87bf0bbd8f6f4L } }, + /* 33 << 63 */ + { { 0xe36941004ef8cf5dL,0xcb4dbddf4d8bb768L,0x0610858e828c717eL, + 0xb4cf22cb2bf53239L,0x938e49f16a3e7a71L,0x1dbbb837e73c7a10L }, + { 0x26ea3108db1b58d0L,0x1ca340abad2929faL,0x1d4601938ecb1f6aL, + 0x060543510424fd93L,0xdbfc403f0303dc50L,0x142ad48dfc0f4007L } }, + /* 34 << 63 */ + { { 0x8a8258eee6a52970L,0xf2d13a33a3882954L,0xd312768c38d48e32L, + 0x78a70e03e9369eb8L,0x02ba8d2b69228d48L,0x7f957a33b3bfeb28L }, + { 0xafb22cd20ab2d0bfL,0x335304ccf8cd44d9L,0x0587a6f256009a3dL, + 0xc0bc7278023b2530L,0xe85f2ec5f37c6727L,0x045f156003f5a081L } }, + /* 35 << 63 */ + { { 0x6d71a45274ec55c2L,0x0d064bdfed33da75L,0x1aa4d77ab503afc6L, + 0xec08340c5cb136e7L,0xf096fed6ed11d9faL,0xf232d1b82f81e148L }, + { 0x71cc9b78ae9b3374L,0xd80ce28668bcc1baL,0xe8f4bd170274926cL, + 0xa7ac120f100da329L,0x9f071c6352a482f2L,0x76d85a8e842d6ef1L } }, + /* 36 << 63 */ + { { 0x516f138bed210253L,0x5ec2fa324433461aL,0x0dbe2c66cdaf1280L, + 0x086b91e59fbf3318L,0xfb0223ee399a1ca6L,0xd6f86d9b0db5b20fL }, + { 0xec02bca25752d618L,0x952fafcaaf69f3f1L,0xf304cb7533c4d294L, + 0x78085727dac65608L,0x22f302ef840a4466L,0x33fb889dc371c31fL } }, + /* 37 << 63 */ + { { 0x4aa2f1c36abdcdf4L,0x80963f8251da8d8cL,0x5647a356ac008cf0L, + 0x40a78c45fc10452fL,0x2a3b9da1ca2d6a31L,0xa4d177760f0db94fL }, + { 0xcfd600d9939941acL,0x256e44c142c3fd25L,0x85bccd42ab3f9d41L, + 0x83e93e44d018298cL,0x569f54d474a5fb37L,0xad2c613af2ffcf8dL } }, + /* 38 << 63 */ + { { 0xc63e6f7c22d515abL,0x3fabfef42ad30174L,0xf13a0126b1c65411L, + 0xe269e956dce87183L,0x44136834a83e0249L,0x554e731831958850L }, + { 0xd287755696569aeeL,0x5af275e9274bf4dfL,0x7056f958197dbfdfL, + 0x699f5a672169811cL,0xd9a857d92c1c7c3aL,0x62cf7431843bdac1L } }, + /* 39 << 63 */ + { { 0x974fcf5529d0c948L,0x104d7df0693c5379L,0x4f851c397dadfb28L, + 0xcd5bc87c233c02c8L,0xf7fa16e82c8c1c04L,0xed42de484dc18a19L }, + { 0x213db3a5b4366736L,0xf6eb5c9517da3d1dL,0x4d04ef1213b304ecL, + 0xba7bd9afaf74e164L,0x956a5f7bab319f50L,0xe733891ce2a4932dL } }, + /* 40 << 63 */ + { { 0xaa4711f54f890542L,0x862421d9eba822c4L,0x2f667179848280fcL, + 0x4de16d87c201ed75L,0xd20e1399c5e61b5dL,0x3f7114b49ed67ec7L }, + { 0x561fd4979b5a88f9L,0xb202eb86d84db2c1L,0x67d8fb90c8637d3dL, + 0x3d1d78a1032b1853L,0xe07bf775ef1af9acL,0x691e1deea57d6adaL } }, + /* 41 << 63 */ + { { 0xe236e42b2a6045fcL,0x4a6b7be7613f1c5eL,0x14136ccbf57b1aefL, + 0xc3a8a6b9c7b34813L,0x63b0998c5f5cee69L,0x311bfe2c3481a229L }, + { 0x4dd2325ff0aba408L,0x1b8a3f739a2fdff6L,0x4845cde0dbafe0d2L, + 0xd092bb22cd37b02dL,0x35436f9d600fe0efL,0x63c580cb065f379eL } }, + /* 42 << 63 */ + { { 0x38f98360f48948b5L,0x1a1d67a97ae3ad67L,0x79966318ab91b44aL, + 0xb69a75b8dfea0b1eL,0xbb18e5fa05d4d71dL,0x80a14dfe03b1280aL }, + { 0xe549c8f14c17cf7fL,0x91da31098969b5c4L,0x1e3e8f08ccfc1732L, + 0xf1cfb3ad0c85444eL,0x6854b52a628bebbeL,0x8a5e2d85075f04d3L } }, + /* 43 << 63 */ + { { 0xd428f75c5aaa1da4L,0xf192162dd224691bL,0xc30f5ccfd3a50718L, + 0x82e2b585e9e0f738L,0xc7fb4dc15cf3fd23L,0x8a52eb37e4e2b37dL }, + { 0xd5bb892bf1702cd4L,0x64b8ccd056b92a51L,0x98ab053f8988e2e6L, + 0xd56b34022f104643L,0xf09017be073886d7L,0x0283e9eebf6eaea0L } }, + /* 44 << 63 */ + { { 0x834701da3801c65dL,0x5bb35c48955aa27dL,0x0ef0f375db7ad387L, + 0xd25e337f06cd1d53L,0x757a1f9d90cd91deL,0x1604f153d61bbd60L }, + { 0x6a01e8cf8bb95dc4L,0x34b7be6275bbdb13L,0x0a96b3a121e9b029L, + 0x25615c3b2946df44L,0x5eda7d1919d04842L,0x08317975fba84668L } }, + /* 45 << 63 */ + { { 0x4a4dd7bf2bb5fba0L,0x0ebc07f3c84c2304L,0x054f2e448daa5099L, + 0xbf8949da3ec362f1L,0x2e4a677c1d7d73f5L,0x405e3ad24dc70fbeL }, + { 0x2958e956c7e46fb3L,0x34e0d7f1b2522e5dL,0xc44b95e25e371e3dL, + 0x62e348a4d91baea4L,0x8d9e89e24c09e110L,0x8cb886f6b1c1e356L } }, + /* 46 << 63 */ + { { 0x66b16f6033e8683dL,0x3435ab2560b41c5eL,0xd5b89f51d452e049L, + 0x4b5253a73aac0092L,0x01cae436f9d2e2c2L,0x789de14637e8ce97L }, + { 0x8f50541701a1c2e8L,0x8c77dbdd798a8404L,0x5a264906b6e91e68L, + 0x36761ccc3c6aafe2L,0x5809baa37e50f9e7L,0x0b50904e28fac969L } }, + /* 47 << 63 */ + { { 0xb6360372308785eeL,0x0c9913a68cf10e55L,0xe82b0f470e67c99aL, + 0x0bf2d24825399082L,0x7aa3edfca86fe16eL,0xf534ec4e731a4956L }, + { 0xb71d5d4eff26e993L,0x320eb7ac7bd58ef3L,0xe5e4c5f30cafd658L, + 0xeb6b8e0a21a06cedL,0x037d0faf6f76acb1L,0x39c76a6ed6f13f81L } }, + /* 48 << 63 */ + { { 0x12474bd8a55a3a4dL,0xe326aaf19e471af4L,0xf201a9308caadaa6L, + 0x546821f835304341L,0x7fe452c3088353e1L,0x8f1ff628fc82566aL }, + { 0x49526f46d99f8967L,0xb19c80c0a4009690L,0xeccf97591cbc0716L, + 0x2e13ae2caf4cbc8bL,0x12b0df13f32e29adL,0xa2005d6e0b1565f0L } }, + /* 49 << 63 */ + { { 0x9260321bde788968L,0x4aaf1752886ccc74L,0xf94ae636c06b1d9bL, + 0xf0c858854954ae43L,0xaaa735866c42a104L,0xcab59d914e782db7L }, + { 0xfd12f9ee01ff3a1fL,0x35eb6104b546d3c5L,0x97d839e075ca1425L, + 0xa77712f452428003L,0xf5dda4e8bd9f30e2L,0x0c3ab97091d6f540L } }, + /* 50 << 63 */ + { { 0x58734b3ca68716ccL,0xacdcfdd2acfb5719L,0x97074bac7084cf23L, + 0xf8d4f285d0c81b66L,0x5ea926e2ef541e44L,0x65a8e25da2c04e0fL }, + { 0x67e2380f06258485L,0xdc00f2ed9691a57dL,0xd37b23fd6b80274eL, + 0x57f1604f2fe10aecL,0xcc21a4aeffb33ceaL,0xf33a344bf75eaa02L } }, + /* 51 << 63 */ + { { 0x24ca6fc56969f55cL,0x6fe18be29a7a9753L,0x5e9a7ed36af8da90L, + 0xf6c261b7ed493388L,0xbe9ac24beef2b77fL,0x0357ab559f244e49L }, + { 0x5f7953375f1b5b9bL,0x27dfdecaa9bc503dL,0x0b2091b55c0e3ee9L, + 0x1f4f7866d68cb87fL,0x336c2c127a442a9cL,0x88267fd1d3f2ab78L } }, + /* 52 << 63 */ + { { 0xdb891eedd06014e0L,0x69685d6103e9970aL,0x3a612db402838113L, + 0xc1cd7b3adcdef0b0L,0x612b299da41d6c1eL,0x982161ed0ed386a0L }, + { 0xb36bbe2f3ea1bf1eL,0x0d8c3752ceb2a5ecL,0xc02cd7f6ec03bdddL, + 0xa87977c152631d9eL,0x7b546cc37e398d7eL,0x5b1218a804845671L } }, + /* 53 << 63 */ + { { 0x52cd86c68a62f0a0L,0xc437c2af4d29c896L,0x722a337a45aebfe3L, + 0x03b13844d8a9de8bL,0x41a005bb8510aae9L,0xf42399ffc63af92cL }, + { 0x004d29cfcd93390eL,0x472de98741dcfa34L,0x2c71ae744e7cdcc4L, + 0x11a5c2f8409816ccL,0x320ca246a96cef60L,0x72de4287f3d57621L } }, + /* 54 << 63 */ + { { 0xe3e7a3eb3771a0aeL,0x781156e9b6dd5304L,0xbaee3a8323e31e6aL, + 0x66d1569a08985bf0L,0x56161e202d75cba3L,0xf9c23c102a944de4L }, + { 0x27ac8f454e129ea5L,0x8b991ba788050aaaL,0x600c96ffa5d052f6L, + 0x0fbe944df244984bL,0x3801026fa204c36aL,0xc4bfa1994d55a584L } }, + /* 55 << 63 */ + { { 0x11b200c6a32f5c81L,0xc4ab4cf43eabe341L,0xa21468f06f339f5aL, + 0xf20c2c5a729438aeL,0x3e68031e3a067c3dL,0x3962a92f062c8371L }, + { 0x389b22835b000f3dL,0x98f3b679250b8666L,0xe283c2b4eea91464L, + 0xd35b14de1e1f4c08L,0x9ae72567d79d8683L,0x2c37b162a3b2a840L } }, + /* 56 << 63 */ + { { 0xfa3e43e56cb173d1L,0x2502258d4591b5a5L,0xae8c4b558ca9682aL, + 0x8cb1ffb4ec81a288L,0xd11ae888bfc84fd1L,0xa3b083a0d774577cL }, + { 0x119b41c11da9afc5L,0x44bc77622934e22bL,0xa04694f37c639d6cL, + 0xd5e1ce5732c5b8eaL,0xd507c39b9749e8b6L,0x16cc0b5755255b63L } }, + /* 57 << 63 */ + { { 0x66fe7a39c4955e7aL,0x25b0b3e5bb11a1baL,0xb82c2cdefc573bf3L, + 0xed33c0e8281a3927L,0xd068c8901ad799d4L,0x052801ec9cbc73edL }, + { 0x614e4aba0faf5c5dL,0x50d7b0a89f66d391L,0x7bdfbf5fc18e88a8L, + 0x1fc93e1f4380d2a2L,0x8241dd5f27d952d0L,0x44944d9c3a3f79d5L } }, + /* 58 << 63 */ + { { 0x808e2693c0edcf36L,0x4725b5aa87c254c0L,0xd1e464644d317973L, + 0x3e59efc2393049d2L,0xa4c9f340d3e0d17dL,0x69b40727abdf3022L }, + { 0xa1d85395317058c8L,0x2cec2a040cfa7c13L,0xe3c16f7634236cd1L, + 0x566b403a3e52fe3eL,0xfd6065bdd6923cb6L,0xe769a89a5019f94eL } }, + /* 59 << 63 */ + { { 0x9b1f6e9042a1cce9L,0xc6c870270511f865L,0xc924caa72a3c29f6L, + 0xcb674fb068e604f8L,0xe997b0b8330c2dedL,0xf5b315a04ddab219L }, + { 0x6fa1dde6575d3ac3L,0x32ad27f735e65e56L,0xfe723ec2e81b1ce4L, + 0x149983f8985d7286L,0xa1d350a0492ecc9aL,0x12a51f8c36a0707aL } }, + /* 60 << 63 */ + { { 0x71e5df78614f6f37L,0x5cf0e08da0b80beeL,0x1f8dae171e32051fL, + 0x54ae365d83bc233bL,0x97ea005b1b84aaa6L,0xf4766d9264c75139L }, + { 0x9b93bbf241215701L,0xb18f042d8cf8a865L,0x5dfb96dd0867556fL, + 0xe9fafbb8597fd6a1L,0x729b2f50fe48bbc6L,0x2cf85f6b7f37ff9bL } }, + /* 61 << 63 */ + { { 0x3e7c871024d197f2L,0xb635595bafe9c29cL,0x302f4fff194e084cL, + 0xd497ce7c18edf332L,0x4081c7aa062672a4L,0xe886a5b28afa97daL }, + { 0xa7e922b5786e1bfeL,0xabd9a18bbd7ffb7aL,0x1f4f5b9356341b58L, + 0x1726484344969ab1L,0xc4a0b557e668a479L,0x5ad1c062bf4f3343L } }, + /* 62 << 63 */ + { { 0x4ff86eb693d2b958L,0x4513fe1b784f628bL,0x45f4712573b5bb80L, + 0x25aa3d36c987bb15L,0x12b1e65bb48163f0L,0x9d0cb4aa9801592bL }, + { 0x02c0c2aa3718bc98L,0x79b03df99c306353L,0x097d8d8daee5144cL, + 0xebed60774621d7abL,0xa8edf06e4b52e72cL,0x40c86f181dbca7d2L } }, + /* 63 << 63 */ + { { 0x65c7144a5e84482aL,0xba6f92644d4f7553L,0xf4dfe807d9c2524eL, + 0x1333dd7c054403b1L,0x44557e880156451fL,0x5dbda4d80824c813L }, + { 0x59e204959857fec6L,0x42f4068f1b1eeb99L,0x067c3aa21d59bde9L, + 0xa9c4c3eeef27419aL,0x99fc994b2ec87652L,0x4f1607581578a996L } }, + /* 64 << 63 */ + { { 0xcd8c2ec9378ef62bL,0x7f4a3c5491a7c4b9L,0xe12386d4db83e1abL, + 0x9a792032bb549bb5L,0xaf81cba62807c0f1L,0xd4ad7d87abf2008eL }, + { 0x9d7a72307e9ad6cdL,0xb30636b08b517b2aL,0x47c324daec900516L, + 0x408cd0d37193eb30L,0x8f0bcce2d315c655L,0x540ad4e0869d6c22L } }, + /* 0 << 70 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 70 */ + { { 0x4b5e753ddae0ff8bL,0xe55c83e4da3d97b5L,0x4034d75f42fa905bL, + 0x89b85edac33e462bL,0x31f413c3058de3bbL,0x66c01c806ba75391L }, + { 0x3f500202373e28deL,0x5090b33b4b9be739L,0x7297aa10efa2adddL, + 0x3e8ccdbe1a6566aaL,0x4dfda07fd7b4f214L,0xa659bd1e7cb1cae7L } }, + /* 2 << 70 */ + { { 0x31796c2387d11691L,0x02991ea2a9de506cL,0x4ff0cb716cb0c301L, + 0xdd0cdbd7d1702ca9L,0x470a26c8e1a02a90L,0xb705b7bad7054625L }, + { 0xfadc2e86d4a1a268L,0x0fd9764668e9f923L,0x042b5ebb2951a8feL, + 0xe4af9d0364197a76L,0xdd2c6bb3249c1b5dL,0x60af89bdf01932b1L } }, + /* 3 << 70 */ + { { 0x4374145d41afcd64L,0x98b72d6049d21198L,0xc0ff394bdfde8a41L, + 0xed1112e5ee1ff7a5L,0x87a920e8cb5036fcL,0x437123f62deb225eL }, + { 0x37e527afb9ad8c58L,0x3e3c9998abfaef38L,0xb656bcc550b2b4e2L, + 0xfacc8a193bf5699dL,0x98cec74fe616307aL,0x34af333dd3ef8babL } }, + /* 4 << 70 */ + { { 0x9ded9b0d744ec273L,0x5bdfe5472e79e4d5L,0x94f3aaf539393728L, + 0x22136862a438413eL,0x449286da373c7de3L,0xa709d85d29aa1540L }, + { 0x1bd13e410284a4f6L,0x37b54d69f0799c8bL,0xd43b558f6bcd0cb2L, + 0xf5757c0e9e610369L,0x15c80b23c16e0651L,0xacb2cf64001820aaL } }, + /* 5 << 70 */ + { { 0x0629e4ddeec37f48L,0x3f7556a2da7de716L,0xcacd8f27661662bcL, + 0x65d8bc2ceaf01690L,0x83ac66477c39c893L,0x353f60dbf59440e1L }, + { 0x2597b0d6852c575aL,0x410885f73a40c2b3L,0x953ab3472fcc2488L, + 0x9f753e5eef4cc6d8L,0xfc32bb4d97f69e63L,0x461c1b0c87e8c264L } }, + /* 6 << 70 */ + { { 0x2bea7e75ac4b62f5L,0xcf255dcdc6297871L,0xdd88db8781b25c72L, + 0x77ad90b3b617dc04L,0x65ee13820ed4a7d6L,0x4c08df9cd9644c8fL }, + { 0x072d3784525a023fL,0x1aef69cefce399fbL,0xb07fd78ed7f29044L, + 0xa3754e1443043fa7L,0x97bdae92ff9fe4d9L,0xad63ba6a700fe6b8L } }, + /* 7 << 70 */ + { { 0xa571929ba1ca17dbL,0xce7a12f545e146b8L,0x39df1446d9eb426dL, + 0x1e48b3f8dc27f268L,0xa2d7dfa1ff548455L,0x750068b86ef1cc82L }, + { 0x4d699306667fce62L,0x98540b9d131c5412L,0xf8a62cd347c580b0L, + 0x2b55460f73795005L,0x3206c0257b8db337L,0x2280934bd0dda5a2L } }, + /* 8 << 70 */ + { { 0x10a8aabd2352478cL,0x599d9dfa1364c40fL,0xa009df1a076945a2L, + 0xf869152c03861f02L,0xc405226e9f866a3cL,0x93bd737d8b41ecbbL }, + { 0xb5c9ed1033901eedL,0x90e4ce8f99312b80L,0x1a9ef22e57589279L, + 0x83ef607d7fe2d6aaL,0xf2da84543473dbfaL,0x14f36d3a57879066L } }, + /* 9 << 70 */ + { { 0x2c780f220ea3ce34L,0x240a211e4b8aac72L,0x7a266e5dc2625a99L, + 0x1cb15d3e3b30c878L,0x8cd8ccab0e1b21d3L,0x53c64279adc1a6b3L }, + { 0xe60d15b960bf708dL,0x6e431c1b0cb5ad4bL,0xec874c3e82033111L, + 0x88054a1d9141eae5L,0x98438a5addf53a28L,0x168f0b0ffa12c657L } }, + /* 10 << 70 */ + { { 0xd621ce26629d7a57L,0xbf571de7cc1f8af1L,0x2c5cfaf9304adaa3L, + 0x950addbd3f283b49L,0x622dc27cee6d1cd1L,0x26d920041f0863fbL }, + { 0xe243b2a2a41ec585L,0x0dbd9adf2bea6235L,0xcb083c4d6f0820f5L, + 0x809ecbafd5493931L,0x9647067414b7ffa8L,0x2cdfe22e53fc2224L } }, + /* 11 << 70 */ + { { 0xc8b1333c7cd74a06L,0x7d5ac4dc271006bfL,0xe9377d9fc14e0e56L, + 0xaa8651db7a92ab1fL,0x77cee8145fc11fb5L,0x1e7c5ca027870b14L }, + { 0xdeef4b3f6f959698L,0x7c59f26e5daa9bdaL,0x4d0d5aecfd312368L, + 0x5247a6f3b738de68L,0x1c4e8ba990c04807L,0x0554b41bcce126caL } }, + /* 12 << 70 */ + { { 0x3df98ea9a81cc26aL,0x982ed56883b2c6f3L,0xc9cbd1b5ea6d6976L, + 0x3f9f23197e25ffbcL,0xbca8e0567da6280eL,0x7abd316635cda713L }, + { 0x46ef321d740ae011L,0xb17f6c75db214a33L,0x37b73b4b51de4044L, + 0x5bccf3ccccd9ba8dL,0xa2ca080dd0f7045bL,0x79caf90668cf4dccL } }, + /* 13 << 70 */ + { { 0xcc3605a9a7b07d22L,0x4370eb18b4ebe4e7L,0xbe393039248867c1L, + 0xc8e4851ecb1a75ffL,0x215f3fbe39cb6da4L,0x6f2102eee41f9a34L }, + { 0x61d484abdfae7c27L,0xf5143bd26f1260fcL,0xa70b6c067514bcccL, + 0xe71ca833d23506f5L,0xe2f50ba8eae03a8eL,0x2ac3b50883c33359L } }, + /* 14 << 70 */ + { { 0xe94b930f3655cabdL,0x6ef6aac4a342443cL,0x2feb8005bae255daL, + 0x4625a15cac6e2095L,0x75c6311d0ec76c1eL,0x896a07409b81c6f2L }, + { 0xbad3e2f9073378bbL,0x2984a10629266ec0L,0xa68a5351a788010aL, + 0x321aa113017cd052L,0xecfb61752f34db5cL,0xfe080cedca2b51dfL } }, + /* 15 << 70 */ + { { 0xba29690803360c88L,0x3fb087c036311812L,0xec5fb10ad9ff6a48L, + 0x52f7077f207dd8e1L,0x8e65cfb844c02fbcL,0x4f4fcde2fbf4bfd5L }, + { 0xd1ff54156cc74320L,0xf989d544f68b036aL,0xafedc2db973bd9beL, + 0x7bdc35694785e26aL,0x0df36796751ae9baL,0xfebde691ccdabd95L } }, + /* 16 << 70 */ + { { 0x3499b44bc77488ccL,0xde000e01aa8f3c10L,0x30140406c1f517d7L, + 0xd4b3c8eb82a174e8L,0xc8835b13af2c9b3aL,0x2cd7626e443716f4L }, + { 0x336c4f4b9c22de71L,0x9dd2b277f2529f60L,0x6ffba2dc828c34d3L, + 0x257a345c34d0d1f7L,0xbc1eff056ca4fbceL,0x05b335620768349fL } }, + /* 17 << 70 */ + { { 0xb142febb692e076aL,0x10cfaa6b9a654721L,0x5b7ba30c8d4917c1L, + 0x44be3089dfe4056bL,0xb7530ae6ae6307f4L,0x47c519c45b5f381fL }, + { 0xa80648d8c3078009L,0xfde72e30dcb021b4L,0x8a89a51bdc2659e8L, + 0xb9e0efa6306adefcL,0xc671c060c754a7bfL,0x703c698e18f14248L } }, + /* 18 << 70 */ + { { 0x25c86ad43c47783aL,0xb1f94a9650f85a4dL,0xb9472e3ac023a02fL, + 0x91033d1b26f0fcdfL,0x95d775c1ab7b4ee3L,0xbe17daffdf3a5cb7L }, + { 0xaeaecd2ce78395f6L,0x0e3abb0953b5da8cL,0x5f729f858ee774afL, + 0x1acccfb3aeca7a6eL,0xd066fccb37e4af11L,0x24c832ab84fc3259L } }, + /* 19 << 70 */ + { { 0xca547b680ca4864eL,0xea40fe17c7d49f27L,0xb5e68bab87227475L, + 0x6ba2bfaf8ce485f7L,0x4d2747acb72684f4L,0x5fabffc670aa6087L }, + { 0x2d4ded5679c67c9dL,0xaf3b4eedc8a4f22fL,0xbef6128ebfa6ca86L, + 0x7ce412bbd4381632L,0x518e6ecfe670d99fL,0xaba6518dfa5f426bL } }, + /* 20 << 70 */ + { { 0x5ebdc79cd41b2401L,0xf0cd8598c498e0f1L,0x93f6efe79c8b7f7dL, + 0xb2f1e40ac469aa57L,0x882f0e943433c455L,0x0add72adaea0712aL }, + { 0xb13578c399af96d0L,0x43c28dc621177663L,0x83aca2d854e09133L, + 0xae03943cc6ad8532L,0xce0a61917104f75cL,0x7dec8786f9838c37L } }, + /* 21 << 70 */ + { { 0xb0b41b8ec5abaef9L,0x43f59aee8ff5d1f2L,0xe58f78c9234d3d34L, + 0x0e1948d029a7f49eL,0x722f8e54c6cd8941L,0x75a4ebcfbaf24424L }, + { 0xec8954982d7dc6d9L,0x8df2feee5261e4e2L,0xdf2820b825dfb96eL, + 0x4b89c4dcff651949L,0x27c871a527bacbe1L,0xfdc70cf7329a52bcL } }, + /* 22 << 70 */ + { { 0x37d58766fdb3f3fbL,0x49d9a762ad64fa66L,0xf80423918cfdbbc2L, + 0x22e60ca36400f7eeL,0xfab8ea7568210629L,0x91267753963e5b6fL }, + { 0x5988d7f56b8e7ec9L,0xe43e762a5899e718L,0x842dbdcc40ae8b99L, + 0xa7ced3f19869739fL,0x1ccc1e8a6d54b9f5L,0xaa3a91adbd32e710L } }, + /* 23 << 70 */ + { { 0x306d662c6d4c255fL,0xf32aa48101fa367cL,0x29a71e02f16b3197L, + 0x653f7d88513a6079L,0xde93d6e74541b4adL,0x4d284acd8c54d3b1L }, + { 0xfc9d462be106ed07L,0x6e3818d07e355468L,0x2ad523859400c515L, + 0x287af41d5ecd3b52L,0x1162162351e1fb02L,0xd696d01f17bd4584L } }, + /* 24 << 70 */ + { { 0x9db114e3715aa8daL,0x596c2dc25c2fee22L,0x04df016bd2f3080eL, + 0x0cb3f7cfb9b72037L,0xadb877c7814fe2abL,0xb2d5ec5c37761ec1L }, + { 0xb5d6068e55d45831L,0x5fab1dffb7c52c04L,0x39b4aa5457d36d41L, + 0xec1de467423cc8cbL,0x280e02dafda6566dL,0xc70c3c383ca55f55L } }, + /* 25 << 70 */ + { { 0x27a866e7c6b03391L,0x980b0a42bfa32fc0L,0xd27856910c105df7L, + 0xf3def8c77103a2b3L,0x6c4ff04bdffea913L,0x57b1003e121140ddL }, + { 0xf47bb2826d0e3170L,0xa44d6ab1e6abdfedL,0x67114b8a2a4b69d1L, + 0x7605714d52d7c65cL,0x3734795ef60b81deL,0x277f9816ebf91959L } }, + /* 26 << 70 */ + { { 0xe57c2ed902b3b70bL,0xcec67da99dbc076aL,0xcaf66725b0644881L, + 0xdea4f6608a3a3f96L,0x5215f097609df5ceL,0x6d828267010193e3L }, + { 0x5971ff31a156565bL,0x44f7e4037b64e465L,0x2145ea9ab5486d75L, + 0x47b04066758e7ec5L,0xc181833a9c93cbe9L,0xcac07a9fe8443292L } }, + /* 27 << 70 */ + { { 0xead7cd3d041326e8L,0x721785f26092e605L,0x760864024ba91a6fL, + 0xb7b9b9fa335e8522L,0x6ba9c85387bb3ea9L,0x9c9f1f6f89b2ae0fL }, + { 0x952bb995aae2014dL,0xf8e74d80c538cfa1L,0xb21ca840b55b7e72L, + 0x22565ec4ad982191L,0xf9547aa1f569c537L,0x8d3cb14648596bcaL } }, + /* 28 << 70 */ + { { 0x340d77c2f3b6cbc6L,0xe09ae22c80f4f690L,0x3e915b028b74d32cL, + 0xae7101ca3cc1117eL,0x3c36152b526c5939L,0xdad8aedbd3ec0caaL }, + { 0x34de058e351bde13L,0x2fa75fd4582726d1L,0x27c030efc214ac0eL, + 0x2a216d1cc7100acbL,0x3b730043309097b7L,0x162ada747afd8aafL } }, + /* 29 << 70 */ + { { 0x43893d328c216eacL,0x475a3466349d7334L,0xf9f259866114fbc4L, + 0x96a22d2f0410b54eL,0xc60b69a53f3d951aL,0x152416e7fb400ddeL }, + { 0x3904dd2e8f682dbfL,0x5459272368383eeaL,0x0092554ee8c998faL, + 0xc80f28512c602ce9L,0xab2f8533b197386fL,0x8c302dbc91094b32L } }, + /* 30 << 70 */ + { { 0x853d994eea2026d9L,0x18734b04a1b927d7L,0xd4815747ce88d009L, + 0x0265742f01b856bfL,0x05fd8b1e205d4e15L,0x0f4c8be0f1da4808L }, + { 0x2652b76c456d62abL,0x0d3d1a29cbb8d818L,0xf350487453048509L, + 0xe393ef54e89ae4a5L,0x19ed8f0cc4b1306cL,0xfd72388da1aabd6dL } }, + /* 31 << 70 */ + { { 0x8a7e1494289e6aa7L,0xc69223e65c955385L,0x2bcbad5c087b8c7aL, + 0xc08008a531fed020L,0x9d38f5b2dc117c3bL,0xd84158bee4ad6b36L }, + { 0x2c2583eb92fe5b21L,0xebc847bf557ce949L,0x4c1b54ff4fc0fd57L, + 0xe437eba325ff2f8cL,0x79a4c3cb383caa3dL,0x38a34856e08356edL } }, + /* 32 << 70 */ + { { 0x5d7afe9a10fa53ceL,0xe2415b501ff49021L,0xe39a067dc6523492L, + 0x3458527527557f5dL,0x756b8d86930e9f9dL,0x88df6219040d52d8L }, + { 0x606eb60b5362b045L,0xd179818c9e383cbeL,0xa6215748e068d293L, + 0x73fbdca22fce158dL,0x9cfee07dcb183c8fL,0xc0bf2beba5e03c98L } }, + /* 33 << 70 */ + { { 0x36702d091bf9acc2L,0x1efceaebc9c9dddfL,0x31f9f5599b9afc1aL, + 0x359d4ff33e61a0e4L,0x33b3a707f3772327L,0xd990af318ac1c7ceL }, + { 0x5ee060b7e736ad45L,0x83dbe8b2f653ac2aL,0x30a1e38b407f054bL, + 0x0ec6c70bd9326ac9L,0xeb37ad09d7358ab4L,0xaf36143030551ef3L } }, + /* 34 << 70 */ + { { 0x7b05d8e56edd5c74L,0x268edfac5443acbdL,0x73e0d693ce1ee52cL, + 0x67c67914120a1270L,0x54a897cb6f1c5007L,0xe817914a8d540dbaL }, + { 0x85c1fa1958fc091bL,0x4f4989f4cf2698feL,0xbb2d5091168c08b4L, + 0xa6143388768cdd46L,0x69ec7a265e62ddc5L,0xc08749ae2654f4b2L } }, + /* 35 << 70 */ + { { 0x0a9882b37409bdbeL,0xfad3899cf8b6543eL,0x01c183f9f7e9893fL, + 0xe6438cf708ac9a25L,0xec22dc81aa0f2794L,0x3b641c02aa277a09L }, + { 0x686b1fbd0975c891L,0x4f7e1b680070ce2bL,0xdc343dd7487e3f1dL, + 0x8825d9c230f35abaL,0xda5a77a413b91384L,0xf09d958459e405faL } }, + /* 36 << 70 */ + { { 0x76b242b31cf2ab8eL,0xceb190e697edb12bL,0xd39b41b7089fc439L, + 0x6ee54e750892be51L,0x128fbcfcde414849L,0x4462539007fce5faL }, + { 0x9d12e04513709b9bL,0xc2c49737d95b22a3L,0x0bcd670be4b34d6cL, + 0x78d7b8cd768d7c8aL,0x7cf9382e16a0f402L,0x9b84311d17238fa2L } }, + /* 37 << 70 */ + { { 0x6b7faaf8c19b849bL,0x24aa5d54a5bec317L,0x991aeb14e7c06172L, + 0x52dc7da883e65aebL,0xda8998497696dd56L,0x3844a54e94cea131L }, + { 0xc9fb72ac55f69169L,0xe2f7bfc821893ab6L,0x44220c2edc4057f9L, + 0x9f4f0c3812d5fedeL,0x5725b2b05c913be6L,0xfa08c56c02d8668fL } }, + /* 38 << 70 */ + { { 0x9aff9f0c009b3e1dL,0xed7936d97a3c8c8fL,0x0bc8e46fdefbd340L, + 0x7b508ef231540ba4L,0x9bcd9108005388f2L,0xa25cfa07c089f35dL }, + { 0x9ec7cf81733bccfcL,0xf8a1993a249006d6L,0x1e68981a96d81923L, + 0x27b6199adce834d6L,0x2ddccfcfacffb035L,0xf62d7a534fe0126cL } }, + /* 39 << 70 */ + { { 0xc800c1d5af76895bL,0xc86db45c43f2a94eL,0xf77322fbdbb144cbL, + 0xb2607dc8f7da8df6L,0xaf666055b6cc1047L,0xf1db6416375619d4L }, + { 0xf6103c8c4b0fbd9eL,0xea8e979fb4f5b85aL,0xb0307d41fd16f61eL, + 0x26bf96c58cadf61eL,0xb56c53a3bd348a61L,0xd1a5aa4f8a01388dL } }, + /* 40 << 70 */ + { { 0xa29d231edda802baL,0xde8d0d510ec3c1e2L,0x0ee56eae117033bdL, + 0x4dc9491998bf860cL,0xa08919cd775cd56fL,0x609a30dc1332bfc2L }, + { 0x2c337f181a41db0dL,0x27fb0072c974824bL,0x34292c1bfaf28976L, + 0x242fcd73ef8c4fccL,0x553723b27473c603L,0xb2191ee9a06a0bc1L } }, + /* 41 << 70 */ + { { 0xd10b7b7c10bf3427L,0x16f9ebc505321572L,0x057692f6db5fde44L, + 0xf45d4d268f047704L,0xe3f8784e25584db0L,0x753764cb9f548980L }, + { 0x4239bd4858f5360dL,0x9dc993da98296063L,0x0fbb0c419ffd05b9L, + 0xa6a87d50610c3493L,0x99f5669df10f18abL,0x5a03f02ba4224a18L } }, + /* 42 << 70 */ + { { 0x3c6839e5bf733207L,0xc2f380899c6d106bL,0x43155630e39a7559L, + 0x28d6cb546f2b8d34L,0x19738cdf09183c75L,0xa71ec595dcee5a08L }, + { 0x8e9c1cc3c70db659L,0x1333d7b38beff6a6L,0xb263d91e036a5aa8L, + 0x72728714ee4f858bL,0xd65fcffbb885ceecL,0x08193f585aaaac96L } }, + /* 43 << 70 */ + { { 0x264006e1b53b4c8dL,0xd3748c0bdea2f9ceL,0x019408d34e580011L, + 0x381bcc70b1342807L,0xb904a17191eb1a0aL,0x13ddf3af6151a1cdL }, + { 0x13827129bc228909L,0x3378b4834cdbebd9L,0x25806f7ed56635c1L, + 0xd1a3fb1c54327e55L,0xb2b8895c69d94817L,0x0779752d7150c16cL } }, + /* 44 << 70 */ + { { 0x228437506ce71a1fL,0x39c6fd9abf0956a5L,0xd34a4be8c8d29ce5L, + 0x41dc15356fbf8fb0L,0xdce277034c950de0L,0x1ad7192f90c75c28L }, + { 0x5b3df71e27766767L,0xba85ec629ca80b5fL,0xfadae6e5095938d8L, + 0x5ce3ffc24d286159L,0x60f771fdc7b977e5L,0x7a764991b38c0c70L } }, + /* 45 << 70 */ + { { 0x3e4440b7469f6406L,0xdba02dea247657bcL,0xa551a570a46227e5L, + 0x278bd5a06e58b15cL,0xbbc5f8edc53eb694L,0x50e6bf5b855a2c7cL }, + { 0xa80af271d231f3b9L,0x6c22008bc139b010L,0x04e9a337ba1e27e1L, + 0xcfb75909677a28ccL,0x95c59b55f967af35L,0x70d24fe88d3c6ddbL } }, + /* 46 << 70 */ + { { 0x0117cabbaedcb5a3L,0xb70a95d52e7bc67aL,0xdc2e07d1ad7e7cffL, + 0xf507941825b9a6b4L,0xf953a962bc8b2f61L,0x390a630d181fda94L }, + { 0xc833598d1fbdd233L,0x0213e633ac4763dfL,0xe822febbcabd2713L, + 0x522864e71d2a409eL,0x49d778a81f904f3aL,0x0dd980e15912be0aL } }, + /* 47 << 70 */ + { { 0x97f993f46621ff1cL,0x3bdcc1ea7d30ef87L,0x931c624585386384L, + 0xd17a7b6a8cb593e3L,0x1b25176da0912f55L,0x323cf7ac2faa4d72L }, + { 0xababa6c58683a7f8L,0xa99ebbda4a71606cL,0xb5375f6b0cd8fd0cL, + 0xce43e2e08ae372b7L,0x957af3cb9e69c105L,0x167c4fca772d0c74L } }, + /* 48 << 70 */ + { { 0x0934812574503f05L,0xcd6a64b217bf8ab4L,0x791e72fa1fd4057dL, + 0x033abed8f0697964L,0x1085ac930d58690cL,0x8acd49d69c8874cfL }, + { 0x929e4c39ff1a5286L,0x9704e80ff28395abL,0xfa69fce54c3d9f8dL, + 0xdeb56555fc83a6c4L,0xd375fa037dc04c5eL,0xab2f12f156a58cdcL } }, + /* 49 << 70 */ + { { 0x381d144f8119fa7dL,0xda3aa4a73c6cf64eL,0x3db4cf0a74cc1520L, + 0xe8148941c1cf3514L,0xbc6c7398a22977daL,0x75e26d4982bbdc63L }, + { 0x17a626a4c9594c3cL,0x766fc21a60d71273L,0x547331241c7653a3L, + 0xdbe3a9f1502617a8L,0xe41acd19a33d622dL,0x4d24cbd5e15d69d6L } }, + /* 50 << 70 */ + { { 0xdde0a062dbbb9d08L,0xb5676d14153211e7L,0x747247f6f97b1468L, + 0x93a6de79b2ada501L,0xf9d4e652518ce913L,0xefb0de76702b82fcL }, + { 0x2c54ffd9d68961fbL,0xa6a2d1a384f04f81L,0x88167488d74b91adL, + 0xf20bba56a7d73a78L,0x9af1df5ae1afc672L,0xd79ded4543c26afeL } }, + /* 51 << 70 */ + { { 0x24011535a223c19bL,0x38b55f0a19c719f3L,0x369f86b4d343ce98L, + 0x6516fca318288db7L,0xad32d4699e4aa0a4L,0xb6c80dd50480429cL }, + { 0x890d73f3b659b787L,0x2d1f888be15362aeL,0xd26a84bf7a9d8c3bL, + 0xd79b764460bc6435L,0xecd0272f07b0abadL,0x3ab2390382d7c63cL } }, + /* 52 << 70 */ + { { 0x3ec1874496d87afbL,0xb02425b5aeea74b1L,0x47cfacea954bb89eL, + 0xd8d6ff40cd26918aL,0xf2dbcbb19fd4dea6L,0xc481a4fe370fea30L }, + { 0x60df9f99a334a5a1L,0xeacebd61e6fbc823L,0x21932e6ba0140a5cL, + 0x6504deb051206cceL,0xaa4b43a350560eecL,0xaf965e7b6535123bL } }, + /* 53 << 70 */ + { { 0x25ce17e7be01690fL,0x82bd07fc216f7549L,0x26f98cddac6e021cL, + 0x815367ff3403972eL,0x01b1cf87cd89d71dL,0xe777db14ae24f544L }, + { 0x8081a692f628a076L,0x663adf4498b98423L,0x4a31e0bfbfb25b73L, + 0x5b42f193427be5b2L,0x24b1369118ae7408L,0xf13654a6e9998e84L } }, + /* 54 << 70 */ + { { 0xf8ec0a9e1b64a70aL,0xa1042bbb45fc54dcL,0x3ac4a936b7cbec0bL, + 0x0c2db54708eb7d93L,0x3f16e7c961ae36d2L,0xde25381b4611083aL }, + { 0xc1680ae3cf5edeb7L,0x7c86d74ce2b3398eL,0xa3ec4cde9945710dL, + 0x303d28ce864e3b4fL,0xd5b9730012956ac7L,0x9ad973be3c0763b2L } }, + /* 55 << 70 */ + { { 0x526c03ba1979515aL,0xe6492299cde06e58L,0x2215e3fb93ec91d0L, + 0xa086161bf783b7caL,0x89e39ff44ef0015eL,0x42c6ccc595e90587L }, + { 0x7577d689a81ec775L,0x272e4578daf4d896L,0x6d43c717cf01d7aaL, + 0x583814cffd5253d6L,0xee692f0666f7a3b9L,0x54048fe4e99bc633L } }, + /* 56 << 70 */ + { { 0x2afba531c0b9171aL,0x687dbe4cf2d75c55L,0x7c1c73f7fa17ba3dL, + 0x7886dd45063787eaL,0x14f59a18abd0a109L,0x1819df3c873bb66cL }, + { 0x76c969dfe01183f5L,0x486a120b1a78b6bcL,0xdfd702fac5686aa4L, + 0x2f74157bf3457569L,0x66c8c73e01964800L,0x0a2f6114def25ca0L } }, + /* 57 << 70 */ + { { 0x841838a8227220dfL,0x39eb77e2cd45ff3bL,0x7140aa47f5a060cdL, + 0x9fae5937b55bc3a6L,0x243390ea09b711c4L,0x69db2ace867a3eedL }, + { 0x14ee853a152860b0L,0xe3389c4edae0dae9L,0x4fa55ed1248a496aL, + 0xda6803e00ef304bbL,0xd19f48bcd04c2823L,0xe76b8d82a61773d1L } }, + /* 58 << 70 */ + { { 0x2e3a6332f7ae9a8aL,0x89f1576f78a12a00L,0x9597b2b245ab254dL, + 0x2017d6306309a625L,0x0385c02719adbe9fL,0x26c84f2014606336L }, + { 0x3808a31a3584dd47L,0x0fd2bd1b4e1da791L,0x70c2827fb894be27L, + 0xac97e84547d1faecL,0xa63c56fe9b01c835L,0x19c3b18067ca7507L } }, + /* 59 << 70 */ + { { 0x975dbe423a07930bL,0xf03fc9da8f7975f3L,0x94209a2522662e65L, + 0xf5b20e6b9619dcdbL,0xa95e2188ed5ee020L,0x2301e35abe7fb828L }, + { 0x4216b05b9caa0bceL,0x0534eef625cdec7bL,0x81f5c5f8613aa24bL, + 0x8705662951451a5fL,0xffafb623df15645dL,0xe19276fe79c497c5L } }, + /* 60 << 70 */ + { { 0x461bb6e1d118ef5cL,0x277e378d1f4bf653L,0x3b4138849ccaab1cL, + 0xa5979a3ecea9c61fL,0xdc2a23c09dbfe67dL,0x5f7e32f5335cb2d7L }, + { 0xeefe71a87accbd69L,0x65d961341df58e12L,0x17bafa56538145d8L, + 0x2a723472695df807L,0x132b5320394ec082L,0x96219e617d0ed426L } }, + /* 61 << 70 */ + { { 0xf08ee7071ec12e08L,0xb9a51fc40c4917aaL,0x1aa9b778aa085b77L, + 0x3b3e40d72e62193aL,0x3700217fdc211bb4L,0xed03eaf4fbea2fdcL }, + { 0x82e00364c55111e0L,0x3be15019e3cbc07cL,0xf142d230055b597bL, + 0xf68837b1a063deb9L,0xf1368df622e72e40L,0xfc712c67ab522f37L } }, + /* 62 << 70 */ + { { 0x02ca4c0dc3c8ee2fL,0x1962366a0d75f552L,0x6354ab90a43c43e7L, + 0x9f46429f7668d14eL,0x70ffaa6d0ca59472L,0x231fdb485a95ad7eL }, + { 0x82ae5f0acb2ebd5dL,0x2dc8417ce51b1d3bL,0x5052133a2fb456dfL, + 0xad3b4cf2bad61a16L,0x59f283a48d76344dL,0x5f15465772b18fdcL } }, + /* 63 << 70 */ + { { 0xe0ef0c3cc73a7131L,0x8a4e0cdd43ea81fdL,0xceb5fcb8d6d6ce6eL, + 0x941179893535781dL,0x20f5e952b37d4531L,0x5e77f33364c25699L }, + { 0xb6645e8fa6d3ff57L,0x6dac30cb5b9bfdc0L,0xb29648e73ebb655aL, + 0xe1bf3f4005ebc1d1L,0x1b12288514025fdcL,0xe15fab026c5adaabL } }, + /* 64 << 70 */ + { { 0x86230934f14a99d9L,0x1cf9c66e97c1c092L,0x01e186ba6f595ed3L, + 0xd3291c3de2284a58L,0x03dee2311b9e5e25L,0xf2e9b4ad15cc9f53L }, + { 0x4fba15679770c29dL,0xbf7d673650c4ae2fL,0x86901eb92532d015L, + 0x4396fd784e7455deL,0x2fbcea8fbcf811c9L,0x3981ad15ae952b37L } }, + /* 0 << 77 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 77 */ + { { 0x6bd2c54d4cb89afaL,0xe78c8bfa36527751L,0x27f52654e3eee747L, + 0x56f205839598d907L,0x5f91c2d027cb3712L,0xc501819fa3e33c5bL }, + { 0x248490aa4eded738L,0xde7ac94427789065L,0x20138b3d74f7d38bL, + 0xae791f602fb60214L,0x6b4fb300bd033d4eL,0xc69c25d9bdfd1f17L } }, + /* 2 << 77 */ + { { 0x0c3d2056be21a890L,0x1c1ffbfb8fcfba99L,0x1b68a98b1fbf56caL, + 0x56fd85ff396e31cdL,0xd2ca58444382c03bL,0xc442030a7d3ef917L }, + { 0x4129a731426afafaL,0xacff17ff5eaae9c6L,0x9e854180653f3b23L, + 0xe65a1a149ee066bdL,0x3420084e362ea5feL,0x6fe58801c7911e2eL } }, + /* 3 << 77 */ + { { 0x43f0ae676c4be6a0L,0xabc6a17a504bffebL,0xd5be6c25dbb4492eL, + 0x7efc9ee884bff97fL,0x54fbd9d7062da2e2L,0x1befeb61c6d2ac32L }, + { 0x14cf6dc0cbafef5bL,0x8e640e4771d12192L,0xd0566543d9a16800L, + 0x9cc2ade9beb1e28dL,0xcbfeb45038e65833L,0x3852eaacd0f5acb2L } }, + /* 4 << 77 */ + { { 0x5e930d65c4650b85L,0xbe96b2ae6350da54L,0xcfac4f7efa08bd49L, + 0x277e8456a6e10f64L,0x41be3067407ac162L,0xcfd1d03252a9b68bL }, + { 0x8d8d216a9c337e0bL,0xace044dc4e1b9cf5L,0xad9a4102c60d54c3L, + 0xb09420f028815187L,0x881179c60b3b8e59L,0x872685ed5b09aba1L } }, + /* 5 << 77 */ + { { 0x26d43085ee64924eL,0x5eb54d1c4bd6a77fL,0x69a69ccfd1ca022fL, + 0xaad92723a3342720L,0x51e27b54421d836cL,0x15e83917fc72a1adL }, + { 0x183e75d14ddea73eL,0x73fe3b9fbafcecfeL,0x0197e0925daefd64L, + 0x2fa89f60f85b8249L,0x95411aafd23cd465L,0xb7dbe7485d9a459eL } }, + /* 6 << 77 */ + { { 0xab146c207dfc66eeL,0xa7250dcebb6869efL,0xaeba44439d7ad5f8L, + 0x919f877ec48059f0L,0x780ecd232c6b5c11L,0x586daa8e38625f8dL }, + { 0x46a46c789911c031L,0xf56f74fc65303d34L,0x825bb06d4f384eabL, + 0xd147719ad6aa2bc2L,0x745fd7460750e1acL,0x2ef411494b3ec757L } }, + /* 7 << 77 */ + { { 0xdb24cd1af10ea702L,0xf393de57461f8ebdL,0xf56f414e5cfaefecL, + 0x758c8d854690230cL,0x6740c974433d2594L,0x69d92a620aa6bb20L }, + { 0x17be342e9b0bb191L,0xc1cd309fdbf5c97bL,0x089134df8998140aL, + 0x33809a7e82afcb85L,0x409d2a481db47b21L,0x1d54e86ccdb1bccfL } }, + /* 8 << 77 */ + { { 0x22313dee5852b59bL,0x6f56c8e8b6a0b37fL,0x43d6eeaea76ec380L, + 0xa16551360275ad36L,0xe5c1b65adf095bdaL,0xbd1ffa8d367c44b0L }, + { 0xe2b419c26b48af2bL,0x57bbbd973da194c8L,0xb5fbe51fa2baff05L, + 0xa0594d706269b5d0L,0x0b07b70523e8d667L,0xae1976b563e016e7L } }, + /* 9 << 77 */ + { { 0x47de66da62a200a6L,0x67b0ce0d65186fb7L,0x8e8f0248238d23a2L, + 0x5a44a886c1114a6eL,0x36383e5be8ec166bL,0xd36077d8ca7d2e43L }, + { 0x332f98267c45e8c6L,0xcec2ba1355d968faL,0xdca664a84a56f7abL, + 0x954652467b03621aL,0x471f66259b6e55d4L,0x401a6a5efb0714e4L } }, + /* 10 << 77 */ + { { 0x2fee0c6d6046896eL,0xde64c4e0466a90efL,0xb0c9755a55395f3aL, + 0xdfe2dfd6ae3879d6L,0x979853c2d656c53dL,0x58bb6121757f381fL }, + { 0xdfae5707980db8b8L,0x6d4c7cd7d7752f7fL,0xdfb77382c5dacfccL, + 0xd0fca93104177fbbL,0x9ef6d3e4b67891ffL,0xb599dfcb26024609L } }, + /* 11 << 77 */ + { { 0x79bf86761cc06935L,0x6bbc2d3fd44fe6bdL,0x092678c486f9f728L, + 0x05631aaf54c3fe18L,0x217adbbe95eec92fL,0xdcdbfdfb955bcba3L }, + { 0xf938779c01bafb04L,0x67f599e73ab755e0L,0x793b591fb00c1315L, + 0x7ea2dbae3f2d0909L,0x05436dce46614955L,0x02b988888060d145L } }, + /* 12 << 77 */ + { { 0x795df21ba1ebf7c0L,0xa98f2466681b5da4L,0xea18a2ab413b507dL, + 0x9243326688324aa8L,0x2b91dcc2f74d83edL,0x95054b471f411a13L }, + { 0x50869778e3c621f2L,0xb950f3a9427faf54L,0x8949bf7dae29f080L, + 0x7c16cd020ef3a3c8L,0x7883c719b122cd0aL,0xa2cad71fc03bd749L } }, + /* 13 << 77 */ + { { 0x60c794125b3ad53bL,0x91c62ac783981a98L,0xa6f30f473dcd7196L, + 0x55417e7598b4c589L,0x2ce067cb345b89bbL,0x4787f0db71936e38L }, + { 0x208cb360331d7de3L,0x4b0347aa15022254L,0xc66e58865e8af235L, + 0xdefed4c591a68080L,0x0b8dbd336eeb47a1L,0xb6d44d36f732c8d2L } }, + /* 14 << 77 */ + { { 0xce0b1700d3aa7741L,0x13cc58a90df0cefcL,0xa96149c7da3a1816L, + 0xd387d361561277fbL,0x2294f77cf2c363c6L,0xc8d19d51355a8a93L }, + { 0x926dd80092affccbL,0x70c59253686afd1eL,0xe4826f2370c4d8b5L, + 0x948d43dba2226c34L,0x6ffed99e2a097aaeL,0x80e7a99a2ce18037L } }, + /* 15 << 77 */ + { { 0x070c3f39b7f01551L,0x21b249434512844eL,0x46e33e16e2e2a68cL, + 0xd79daf0ca549dcb0L,0x634fa53966a7b9bfL,0xe856d0a8702990f4L }, + { 0x246e5858e466abdbL,0x3f3ad441edfc851eL,0x9ab3db2c2e397554L, + 0x6c5b1a39b5cabd32L,0x695649b2427c5cefL,0x6179fa0f82ab4f68L } }, + /* 16 << 77 */ + { { 0x022aa09d236b71dcL,0xb1ce6a0ea65a7640L,0x317344c5b38b417aL, + 0x29a74cdb436451ecL,0xd898eb6ca8b1c876L,0xf0134f99b74eeffdL }, + { 0x0d9eab64225d71f7L,0x9679b453ceb3cc2dL,0x37c894ce14dbff2fL, + 0x3704d34927065280L,0x9ee435d8ba29a0cdL,0x675bea1409c11c4fL } }, + /* 17 << 77 */ + { { 0xa8454e2b63263ee1L,0xf4c8a384cc42ffc3L,0xb260754916bf086cL, + 0x610d299cfa46a481L,0x21777897ce41a4d1L,0xdfc04bb321573cdeL }, + { 0xac7d9433ced06177L,0xfdce0356a281b9ceL,0x22abd67970d48fc7L, + 0x1e4ebf7750514178L,0x7f0869ef21a255c8L,0x80ae565c29bf477cL } }, + /* 18 << 77 */ + { { 0x607cfaa1a38a18a2L,0xb29ae9c760bd3f91L,0x4991432d76a4c22dL, + 0x4fe8dcd380e75452L,0x7aeea8150925ed79L,0xa0cc6823b7abca08L }, + { 0x647b164fb0a555dbL,0x60545cd3d6076f3bL,0x7e801133807a2045L, + 0x74b2200743ac7e22L,0xdfb58fd1716d3e5dL,0x369ad09947772c45L } }, + /* 19 << 77 */ + { { 0xb6c5dc0635ba2007L,0x6543c6307921115fL,0xa7e5a662eb6c493cL, + 0x728159f54a0b8d6dL,0x8cb07ef1b943fa72L,0x4a2c5cc923c46a98L }, + { 0xea078b478c26221eL,0x68ef5015ce2be601L,0x3048b5de5239f8d2L, + 0x00a98cd419bbe0e5L,0x0a34161caa94a375L,0x879a9a7aac8a411aL } }, + /* 20 << 77 */ + { { 0x2d968968e3f6217fL,0x60b781ad1fb91fc9L,0x44ce23514a84e6ecL, + 0xe8f5627d00a3d089L,0x45211a094a980480L,0x11029b7263274860L }, + { 0x44601cfcae0477aaL,0xa05a67df269ca043L,0x9dc3938fb758fbd0L, + 0x43d5d89abaa35f8cL,0xa38dfa1f2ab3436aL,0xa29653bc529b7061L } }, + /* 21 << 77 */ + { { 0x6ab2e32b982cd162L,0xdd690ed7794d6da0L,0x8fee0b461862f33eL, + 0xbf9aeee210d244fdL,0xe485aac27dbb57d7L,0x7f7ee4bc0ff23849L }, + { 0xfb3c6255171ba49eL,0x089b9986133e45deL,0xb6c033106d04b924L, + 0x216af9223ea88efcL,0xe646a49b5fd52347L,0xbb495d2ee404b86bL } }, + /* 22 << 77 */ + { { 0xe24934ba07fd5fcfL,0x4840e1a6a1027598L,0x4c2294d245eead89L, + 0x7717bb604fda652dL,0xe809c21878370655L,0x417853499151e578L }, + { 0x8bfe121cede554c7L,0x96037a33952c153cL,0x80458ed86a5b30f0L, + 0xba331cf9ca28472aL,0x31b5f463e6c177aaL,0x68c5dc9183ec14fcL } }, + /* 23 << 77 */ + { { 0x8b78d2bff13dc6a5L,0xacd7e0902285c2a2L,0x6aa7866cb47e9427L, + 0x7c2483474d9fa3f2L,0x2e668396f0661aafL,0xf491cd6d08cacae4L }, + { 0x772a131158f9a617L,0xf372dcd6b2011823L,0x790a5ae54e6bd2a9L, + 0x035ff238fee0c8c9L,0xcbbe828cb0b8c53dL,0x9edba1a40af83ca1L } }, + /* 24 << 77 */ + { { 0x2fde4893fbecaaaeL,0x444346de30332229L,0x157b8a5b09456ed5L, + 0x73606a7925797c6cL,0xa9d0f47c33c14c06L,0x7bc8962cfaf971caL }, + { 0x6e763c5165909dfdL,0x1bbbe41b14a9bf42L,0xd95b7ecbc49e9efcL, + 0x0c317927b38f2b59L,0x97912b53b3c397dbL,0xcb3879aa45c7abc7L } }, + /* 25 << 77 */ + { { 0x62ecc0cc429bdc1fL,0x6a8000add447c01bL,0xc2dd42354f23e5d2L, + 0xe6c1790a01b4a0dcL,0x2497e53c24393079L,0x0a113afeb2a00faaL }, + { 0x96c1bd5011151480L,0xded805425aad86dbL,0x639f24cb76720e92L, + 0xf17703b7d825eb92L,0x10f8924e82d2657eL,0x6edc843c627c5236L } }, + /* 26 << 77 */ + { { 0x472226adf80911c2L,0xfb50c3a5e087a3d8L,0xb194551441848a6fL, + 0x61f4fbba9f17504bL,0x8c59b2c48e33924bL,0xa7641127ac7a8608L }, + { 0x79feb7fc164a2330L,0x9e0fd67253a44e7aL,0x9c5c973081953c30L, + 0x25d6932c3f6342f8L,0x29e8b7664b574a69L,0x02f90a46a5de3639L } }, + /* 27 << 77 */ + { { 0xe2d1e2a3465ab77bL,0x2ca0f6a3cf45823cL,0xa1b12306dbdce9d8L, + 0x820470e7b4b39ca0L,0xe48956c76e847681L,0xc8ed8fc8fbf6970dL }, + { 0x52cb109419ba40aaL,0x08136d091efbaaa2L,0x99dd1ad27d71e1c4L, + 0x10001f97a3a59a3bL,0x79d229e460e4cad9L,0x6d443d8756732312L } }, + /* 28 << 77 */ + { { 0x8d6b28b4d7cfe9f0L,0x6ee5407a4dce4904L,0x7acee5e7ba0b67f6L, + 0xd4cf6bd2abf447aeL,0xc085e8e2e7330268L,0x23edbd5a145689d8L }, + { 0xd2ae9bd21d7b0e7bL,0x3196410ec4fe6ecbL,0x964bef26ec2cd59dL, + 0x09c6d07dd5e0bf03L,0x379f131ea65b646bL,0x0439c37964849830L } }, + /* 29 << 77 */ + { { 0x8afc9a5eae562537L,0xde81bbaab2d4172aL,0xa272c6d53db07247L, + 0x08b903ffd86ec6f8L,0x3373041f835aa84aL,0x02e8ecfdc8f18f48L }, + { 0xed6b2784ccc11e64L,0x03e45e15842a8292L,0xfcfcc54b653b86efL, + 0x9678fe7ed9ea2f91L,0xee5bf4584efceafdL,0x188e49d59fcc4be9L } }, + /* 30 << 77 */ + { { 0xeb0098cf67a224f8L,0x14e486c90991108dL,0x0dad68314b397687L, + 0xf2a4f6cb9d089000L,0x3fcc8803509f7376L,0xdbdf06dddb5d6f8fL }, + { 0x2cbf342806ef3e46L,0x4a4bd5eee432ca41L,0xdcb8bdb70e2d391dL, + 0x941b9a4ec1710ac3L,0x25cea4333d62c34aL,0x9136e5cd881a70b7L } }, + /* 31 << 77 */ + { { 0x9bfdb9b310c3ed1eL,0xc9a225ec0cd146c3L,0x1fec4316573c4414L, + 0xe11a408f2fa8323cL,0x198c760ac3e988bcL,0x3f8a5a1caf0fda3cL }, + { 0x91e89f11f6e78264L,0x3cee0165264eebfdL,0xf9412b049898eaa0L, + 0x3c67991a382e46e3L,0x8d833d7a80acd219L,0x746a696c9d233f20L } }, + /* 32 << 77 */ + { { 0x8b3269a2714a10e8L,0x64cef040a4a2727eL,0xbc5ac714e428865cL, + 0x531dd17ffdaba094L,0x86d2405718d657f2L,0xe807b0d92f99dbbfL }, + { 0xc428a80f6848ef88L,0xb3ef0709d0b73ce5L,0xa752691922a5d255L, + 0xbfe6392318a18586L,0x28a0c772fcf633b3L,0xad22b4ec3f3c5298L } }, + /* 33 << 77 */ + { { 0x8b6a2f1ae6c40f85L,0xf0f44c54f44cf3f0L,0xda635b687b25d4b6L, + 0xee59c00f8cdc9d5dL,0x36509f58cc4876afL,0xe37564484e2c550cL }, + { 0x20f965b565974809L,0x26481694e3fe3a63L,0x6778b20becd272eeL, + 0x9b6bbf39c9072853L,0x4f61f192b0436bdeL,0x98bf7dafd0221263L } }, + /* 34 << 77 */ + { { 0xa06a4b56e0442513L,0x6537e117dd513547L,0x89e38ccd2a654224L, + 0x2fe734bd005ee292L,0x54d6933498cfece0L,0x85de5c9d85a79bf2L }, + { 0x21e072bdcd3da6a9L,0x7a5d707b8c16b8a1L,0x43654d0142d04cd4L, + 0x07d589b94a88c151L,0x5bfe9ea2df726b52L,0x877c46ffcf728e4eL } }, + /* 35 << 77 */ + { { 0xe338f606fa009c33L,0xce596aafa351fe32L,0x8ae0e06123968387L, + 0xcdaaaa9465c98e2dL,0xec6b8a818acb9355L,0xc2c67e7facbee162L }, + { 0x7068df85517df4beL,0xc34a6ecb7c5c076aL,0xf4193aab6250f0baL, + 0xe0cd2f3fa6c9ea47L,0x23a57ccc6488135aL,0x044d73e6c12b842eL } }, + /* 36 << 77 */ + { { 0x9d8a78808078c8bdL,0x6ea07982076d44f1L,0xc58fc94eeb3bfda0L, + 0x0b9e72200dd11b13L,0x8bd58e3aa74a005dL,0x7a30aeda115b7d33L }, + { 0xeb0037e6ef2491ffL,0x0fa2d1a7fb39ecbcL,0xb75aac645ac598f7L, + 0x2c3c103341f61b42L,0x5a330bf01f7eb885L,0x1c96124d33d5e27bL } }, + /* 37 << 77 */ + { { 0x3f157ea1b28d1640L,0xa41c98f2c96806ecL,0xef261c3bb099566bL, + 0x11d88be30aa23f1eL,0x9a721a2c47ed1540L,0x214cb5b0e4431563L }, + { 0x36a95c20250f6b19L,0x6b44f01d30eb0249L,0x141777dc5c67e2beL, + 0x6926b32ebbe7bb63L,0xb72fd3bf756cbae7L,0x226661a279dfb835L } }, + /* 38 << 77 */ + { { 0xc25a44e3300b8f91L,0x08aa9d5691ad1a78L,0x130c561ffdd2a064L, + 0x36f0b4608c05f94eL,0x748166e158a351b3L,0xe408976147d40ed6L }, + { 0xa0ba5e5d1b2e3400L,0x94aea3b6687f6492L,0xf4975167ea262235L, + 0x8014e81143e800d6L,0x635a3c516e5df6dcL,0x71207caf2eb20366L } }, + /* 39 << 77 */ + { { 0xc00364013638e940L,0x24baf83bbb70e3cfL,0xc08a99b865dca079L, + 0xc070152e0d40622bL,0x44880b191697468aL,0xcf95519bfebc1644L }, + { 0x7bdc41d7911a74efL,0xb88180314ad83219L,0x53c523185ad49f95L, + 0x4e59a29f6d112b66L,0xb2707b9c7515de9eL,0x8322492c150c9bdbL } }, + /* 40 << 77 */ + { { 0xcd81bdcf24359b81L,0x6fd326e2db4c321cL,0x4cb0228bf8ebe39cL, + 0x496a9dceb2cdd852L,0x0f115a1ad0e9b3afL,0xaa08bf36d8eeef8aL }, + { 0x5232a51506e5e739L,0x21fae9d58407a551L,0x289d18b08994b4e8L, + 0xb4e346a809097a52L,0xc641510f324621d0L,0xc567fd4a95a41ab8L } }, + /* 41 << 77 */ + { { 0x966f961d46ff607bL,0x7e52ad9bb29278c3L,0x5b9b84b9bc6835b8L, + 0x00e4a35ad834701fL,0x53aa139866b8f484L,0xc397f087de063112L }, + { 0xb811a9a24e81b980L,0x8d9c38ef8d680c4eL,0x0a7e66ef1c8db33aL, + 0x1c7e636bf4e17483L,0x25c0a690ae9acf11L,0x5b0a435985966d63L } }, + /* 42 << 77 */ + { { 0x3d4a4ee0a3bb186fL,0x84de7765082c283bL,0x499bf10a8fc8baddL, + 0x85191faa2db59e7bL,0xc5964c20ccc587a2L,0xfa59313b9cf52cfeL }, + { 0xe614ce878da8cf4eL,0x7d8aa381d60e91b6L,0x054dfc4a0d5c0a8dL, + 0xbcd89aef28a15c79L,0x2af1121efecbc916L,0x6aa49bcb44f30755L } }, + /* 43 << 77 */ + { { 0x7953c7ec7b7dc4cdL,0xb709542edbdd99baL,0x7a2afc3eb30b5c70L, + 0x7669020fcd0cc804L,0xb57c1d949fade8f7L,0x5ae7d78cb2eef81bL }, + { 0xdd5457edca354c1bL,0xa531d85c8f5ac058L,0x5fdca829009e0aabL, + 0x8df732f6f2bced0fL,0x3ee658627faf57d5L,0xf7a265735c2f3bc2L } }, + /* 44 << 77 */ + { { 0xe1ce7f3725a64849L,0x760847744da790f0L,0x4638f287cf5f319fL, + 0xe36f3c5308c3786fL,0x07042ce1985513cbL,0xfb955cbf73d9cf3aL }, + { 0x3e68a2cacde0774bL,0x321f49b76dc2c816L,0x9bfed81fd76c4d3bL, + 0x985b34fefd49fa62L,0x2a3de945ebb8fa9fL,0xcaa616f0405da5afL } }, + /* 45 << 77 */ + { { 0xf3fa1924bc6d86f1L,0xbcf9d3cbb41dde67L,0xf96431168057ef19L, + 0x09315fc52177ef64L,0x1ae99958fcf594a7L,0x7c4baeefaa4dd788L }, + { 0xff1ed168a2bb1bf3L,0x9c697d19b4a651c5L,0x5fe29bcc0df8c999L, + 0x16446aa446c45428L,0x3a51398061700e83L,0xf34133593f034bc9L } }, + /* 46 << 77 */ + { { 0x9cc126b8cbf28cbfL,0xf3f8aa7c1e6d63ffL,0x533e48d2b7f80225L, + 0x8fea0d204749d781L,0xd8ea614b326f8185L,0x9cf3e07753c541abL }, + { 0x09040b60d95c9367L,0xc1b19940f5eabd9dL,0x80b0793cd8f8bd1eL, + 0x95fafd6fadff120cL,0x071b1841ce155f8bL,0xa85dfc8cd29d9d9aL } }, + /* 47 << 77 */ + { { 0xf38e0fdea761048aL,0xd9d5a22c88a93773L,0xbd58470841a99bddL, + 0xa31ef1edebb412e0L,0xd5c4fd5a0274ea16L,0xaaf215f380c1f0f8L }, + { 0xe842a4537d3dfd08L,0xb5c877ae5a904548L,0x3dadd2eb9c6ddbebL, + 0x7f97c541e84e54d9L,0x6183b6ce1b8d8829L,0x2a20c212f50534a5L } }, + /* 48 << 77 */ + { { 0xc8c9b0ae7176dd90L,0xa95604542917d487L,0xb03b7946e62c508eL, + 0x60425926e9fe2321L,0x73b10bba80c1d136L,0xc30a847d9d218c9cL }, + { 0x6ed0c8ef2073859fL,0xa176eabf432dd97fL,0x3078096ab9e96167L, + 0xb28f0e6cc473e377L,0xb44e4995683a3bc8L,0x483512eed3523796L } }, + /* 49 << 77 */ + { { 0x7ff5827f22adab31L,0xa7e859ad43ee005aL,0xfc2387f402c9629eL, + 0x6f39e84add12b107L,0xd1378037c097d3daL,0xc677b554d70d107fL }, + { 0xec15469fe4943084L,0x1f0b13b19d412b76L,0x3b3b49b48a265a31L, + 0x45f28cc7dbe97ff2L,0x33f0e31f4efa0f0aL,0x6b22b99e37a5591bL } }, + /* 50 << 77 */ + { { 0x0a751d3eae0538e1L,0xd51b039af14135e9L,0x92eae0f6e8bdf562L, + 0xf253bd5c66557b17L,0xc1ff9054ef26b81bL,0x9d586d39eafd711eL }, + { 0xd2b05d3d4f431502L,0x847d727f5823cfe5L,0x2c4e236a8e99840dL, + 0xa407e2d87c5981c6L,0x989dd28c69ca34b5L,0x2e8ec6b09fe586e7L } }, + /* 51 << 77 */ + { { 0x43161b5c40bda312L,0x8fd476b8a10fbb2fL,0x84cbf7579e5d9a4bL, + 0x19bb5926a9a31956L,0x66ed993aea9db48aL,0xd7897780ffb0361eL }, + { 0xb031e035adfa3661L,0x1be83caf2296b4d8L,0x8802c98b0024cc48L, + 0x73adb0c0bac1aa5eL,0x17df92e1bef75b41L,0xd753e99903d800bbL } }, + /* 52 << 77 */ + { { 0x24940b868733c1c1L,0xf5dd77ce2ac072e1L,0xc248ad6bf7bdb8d2L, + 0x423e0cc9d9a8b926L,0x4318d600e6da05dcL,0x3e557e08ca27dfc9L }, + { 0x8dc551cdc5dc822bL,0x160da94cbc8fb392L,0x4ffebd2aa6d4d363L, + 0x8190c17db1ce15a6L,0x1abcd1361e9dc500L,0xae3a477c9ee52a47L } }, + /* 53 << 77 */ + { { 0x67ab01575ed80bdfL,0xc77067b69aeb4a86L,0xe6e26abdf7880a93L, + 0x782248db1e43049cL,0xa902c41016d78616L,0xc6fa899fbf309f15L }, + { 0x81e1532d672d951bL,0x84280ba386556a0dL,0x83190bfb55199078L, + 0xbc11e8c25a1c4691L,0x8ac60c7f21152509L,0x4211923ec775dcd0L } }, + /* 54 << 77 */ + { { 0xa63b33f6746418acL,0x62085e0eb7359443L,0x3b43ea7b5fb598dbL, + 0xf4a0f4442b365528L,0x7f4d2ff3eb55a5ddL,0x012cd591f189eadeL }, + { 0x3fbdad99f58c8f84L,0x71dc1b0093bf34dfL,0xfb63f09ce062a588L, + 0xd5f0f0ad6f24b66fL,0x940e23c91813cd9dL,0xeff8580b55f241dcL } }, + /* 55 << 77 */ + { { 0xb30719d8b7fb5f3aL,0x8f74305b43275030L,0x2fdb613bf23628bbL, + 0x75d9868ad945ccdcL,0xbfae46f4f0b73348L,0x48ad8bafe26679b3L }, + { 0x3aeb4743d0b389bdL,0xd2463ca37916297eL,0x3a6f37c820f52fd1L, + 0x7bfade4495ffa348L,0x1e3f6282a25cb79cL,0xac3320d5229bd2a3L } }, + /* 56 << 77 */ + { { 0x261578c7d57c8de9L,0xb9bc491f3836c5c8L,0x993266b414c8038fL, + 0xbacad755faa7cc39L,0x418c4defd69b7e27L,0x53fdc5cdae751533L }, + { 0x6f3bd329c3eea63aL,0xa7a22091e53dd29eL,0xb7164f73dc4c54ecL, + 0xca66290d44d3d74eL,0xf77c62424c9ea511L,0x34337f551f714c49L } }, + /* 57 << 77 */ + { { 0xd1f879197700d61cL,0x21728fe49a89dc22L,0xdd3a475be6d93642L, + 0x3f8554d6e095363fL,0x4b8b712463e1bb11L,0x75db57e6c6da541dL }, + { 0xfdeb9e46ac8342fdL,0x8ab4875114905993L,0x48150a06b2efd023L, + 0x9f5f513df415bff5L,0x39b1234eee9d7915L,0x735570a7dda66da5L } }, + /* 58 << 77 */ + { { 0x3a79a1756e3d4ec1L,0xde0ee6c79936b689L,0x37a7d9ec7fb84ee0L, + 0xe82810d38fe1f44fL,0xbe433c7253049e9eL,0xe72ef4f5fb49e274L }, + { 0x525b72094b4ad28dL,0x37bfb857164f5f0cL,0x60327e31ac68d566L, + 0xdb027619bb71f137L,0x8abc8026abb6e829L,0x99702ff15e838117L } }, + /* 59 << 77 */ + { { 0x974be1d30696f1a5L,0xf884616dd3832430L,0x6997c37ce9dce1acL, + 0xf4bad00e2e5cfbc4L,0x7727adf8e327a9a4L,0x15315bf16aeeb305L }, + { 0xe697c0af09fbffceL,0xe4291f7589f86a5fL,0x765f1904487b12f9L, + 0x752c58a5b7f8ca88L,0x9f9563d473716bf7L,0x48803cdbfd032783L } }, + /* 60 << 77 */ + { { 0xa0d935ce9050c5cdL,0xc1e062d03e9b902aL,0x212d0e5dc3054c00L, + 0xdc9c3f2de70ad96bL,0xa2182ffbc2742144L,0x4680d472a716993fL }, + { 0x9852bb00677f3756L,0x2bb3d78435e6213fL,0xadfdbfe07377fdc7L, + 0x41db795d708afddfL,0x6848cef57727ed86L,0xb24e416aa6c1dd1aL } }, + /* 61 << 77 */ + { { 0x36d76f2f2edc95c2L,0xbdf2a67810b0670fL,0x49fc8c43b63877a1L, + 0x23182ed3a87c8615L,0x94c21da96c011a44L,0x3bc0b86860d3c162L }, + { 0xca6a158244815192L,0x4bd1ce04fd97b78bL,0x1d0074cddc750023L, + 0x40cf8233cdfb0c7cL,0xe4e28aa8bbbfbf3dL,0x72656155b6eec7d2L } }, + /* 62 << 77 */ + { { 0x5b1be65b912b364dL,0xe6369ca1e0335426L,0x249740d58420e7daL, + 0xff13a26f1ac1acf4L,0x0ecee744b9634fb2L,0xbaa77d57d664ceb1L }, + { 0xadfa7625914f3f7eL,0x17c75e99bbcffe16L,0xcf557911d64aedb0L, + 0x8a4b7b49c3644ba0L,0x115240401eb7bb97L,0xb823c21a70fc7b5eL } }, + /* 63 << 77 */ + { { 0x45db2c038727c0fcL,0xf5aeeb7bbae2c896L,0xfad1cc32eed15b82L, + 0x65d4440a8609b00eL,0x35698d956b4dbd25L,0x861615bd0f6cda68L }, + { 0x578efdaa8aec1e99L,0x87ddae76fcf67480L,0x5ff5a1304669ccb0L, + 0x5fd2f31a0b98ee60L,0xccad491a3cc4c003L,0x6dcf25bbccbc46e0L } }, + /* 64 << 77 */ + { { 0x93a62e7cfa43699cL,0xdad738901bc422d9L,0x265e3cbb10cc9544L, + 0x28cceb062f37154cL,0x6b79b0713bf2e08bL,0x88e025df3ab39091L }, + { 0x50a8d04d126522bdL,0xeabbc1b7b779bacfL,0x3db4336ac21cc62eL, + 0x4747f0a36fc00450L,0x067cbf1c544b2d95L,0x2480b7d8fd2be7a7L } }, + /* 0 << 84 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 84 */ + { { 0x0233e423d52eb122L,0xc28483521154b0c9L,0x2ca09cef6349e35bL, + 0x3b70afc3ded2ec54L,0xc813474d52dded3dL,0x2d3f21bf12f00ee0L }, + { 0xa0908f7692f215c6L,0xb97d60e94e9c0440L,0x84ad10c134b6a8e0L, + 0x6f37fd956e7c163eL,0x7caae8c8d057e0c3L,0x534f52c2553721a2L } }, + /* 2 << 84 */ + { { 0xa354c1de72a041b2L,0xe83df25929d1330aL,0x676610999d532bbdL, + 0xb7c2f4cf52011751L,0x6945d34ff659e35eL,0x6217d20ba1303b7bL }, + { 0xa200ddba25751badL,0xa74a729001d3566dL,0x3018445faa82b46fL, + 0xc3e6a3acfccedc1bL,0xe86ae8703353e29fL,0x1c8085bbfd7e8547L } }, + /* 3 << 84 */ + { { 0x728c8e145d1a678fL,0xf944da572ac89a2dL,0x3016c2da4796df72L, + 0xf6d79e4e00a55efcL,0x4fced269526b1cb8L,0x4a93e47791f165a9L }, + { 0x528b8572f84f90d3L,0x3b30376e5e725561L,0x4f903520e07bb990L, + 0x07ddb97f4ea8ae6bL,0x29c01e70b3b735bbL,0x825c7f6e5000dd4aL } }, + /* 4 << 84 */ + { { 0x306b63e3b4dcea78L,0x4b10209213636935L,0x36bb68898bdeddeaL, + 0x9331655d67a329acL,0x14c7fe26ba92ccceL,0x4e7d6929be0519b4L }, + { 0x0dc39dbd164d50e2L,0xd4c430a0b1679cc5L,0xc7f78818fa8682baL, + 0x43396eadb60aad97L,0x751784d7ff2c64ccL,0xd37928be866af43eL } }, + /* 5 << 84 */ + { { 0x3742b61e0475f547L,0x48b2a2c2477722acL,0xf52c6787abce3401L, + 0x4749711ea4cb41b4L,0x7ce0dfb03fca817eL,0x1c1e3bf996e85048L }, + { 0xcd65250e40faa8e9L,0xa8edce7017d9b93aL,0x73523cb2b4dd5619L, + 0x15ba773abb5379f5L,0xcc5e62d6c0a847baL,0x7efe5c7c04d852deL } }, + /* 6 << 84 */ + { { 0xf0a69e685a91c9aaL,0x0304d20105c13197L,0x773a3ab7cd14af1dL, + 0xc0b88edd558d555dL,0xeb12d197d2e63dd6L,0x4a8e849fbcd9cdb3L }, + { 0x06432985965eaa14L,0x453d93861a5a6f43L,0xbd28f6164171b9bcL, + 0x37781639bbfcf90aL,0x1f93898f3a36084dL,0x1fefd8b7dd00ca75L } }, + /* 7 << 84 */ + { { 0x3b8d8e495e456124L,0x967ed511967c17b7L,0x1d72430c2aad8c67L, + 0xe8c5d506b82c1673L,0x989978868a0fb41dL,0xa9d478f70f81234fL }, + { 0xa0c941cf44cc0614L,0xc033c99024ad30f5L,0xaa7de296101f89aeL, + 0x4cadd8e3ca6a3227L,0x3b4db51f2764ec0cL,0xcbfe70fc09256db4L } }, + /* 8 << 84 */ + { { 0xb9207dbc2b2f1bccL,0x6afd6871a3e83ef7L,0x49924e5534ba150bL, + 0x2935ebf1dfec9972L,0x34bf5e94b76f870dL,0x22d0f32b4c20385cL }, + { 0xc78ac1728ccc8e72L,0x7b45b8220ccecb0aL,0x76c67ee4cfb4b8baL, + 0xecfaefb2cd8724b6L,0xe9bc3d67340bc1efL,0xed40b2b9ca5541b5L } }, + /* 9 << 84 */ + { { 0x5d1bd16518f8e17dL,0x754986b7405f822bL,0x420b1b24d8753fafL, + 0xab038e0608ff680cL,0x33621a0fa3649f49L,0xe24b84db78918eb6L }, + { 0x0e669672c8bf4168L,0xcb7fab33171eab20L,0xa097d2cc4808be42L, + 0x4f4e395f5842b80bL,0xddcb1e51a579145cL,0xa635d0cdf330ae0cL } }, + /* 10 << 84 */ + { { 0x9b8a3eb3069e6432L,0x43aaa7fc721397f7L,0x46e23c6ca7e83a71L, + 0x71b261d593fa3c25L,0x4a47a1050f523a72L,0x31919e898dcad752L }, + { 0x4c8b06e70c5dd2adL,0x677ec5f38bdc55e7L,0x4372d55dcb1b5828L, + 0x7bf054c1f04dd321L,0x4e8c1a992e44584eL,0x6807803751d35d78L } }, + /* 11 << 84 */ + { { 0xa6d78a3d754377feL,0xcc17c26ac72ae5e6L,0x2f0ab93b1c05fc24L, + 0x1645c369d64c9d40L,0x7c37b12c563e7e9bL,0xb70d292d58b477cbL }, + { 0xc283aca993a2d5a6L,0x759e9118354c183fL,0x8a031f6fdd8f4125L, + 0xfa8b17ad56edbe3aL,0x6e0f96eb63c651ffL,0x40361942b5085541L } }, + /* 12 << 84 */ + { { 0x25ae349981d311b3L,0x8640f52a3b16037bL,0xac0839941d947065L, + 0x3723c75ee2e693d2L,0x65040a51b66f429eL,0x7f582b0b035a3a53L }, + { 0x20eca9e10a166da6L,0x45b37e202c4cc565L,0xeab882957a8a96e3L, + 0x99e771dab60a1a1bL,0x2cdd778c23b03965L,0x8d4d7a7291052478L } }, + /* 13 << 84 */ + { { 0xb57b345e4ff33506L,0xc1a3092a31d23fc3L,0xc16b501e905e1f58L, + 0xa36a3b1f29067b85L,0x7cfabd23c214dd5aL,0xbd5f7ab726ad949eL }, + { 0x8f64595987363816L,0x49c1a3e679d12d59L,0xcc8f3e2c32d771abL, + 0x008d900e6bde16d1L,0x60428a0f60165966L,0xd4f8d9eda7383ab9L } }, + /* 14 << 84 */ + { { 0xa52d3c2d7e8f73b5L,0x86d8063351842657L,0x58f01253b3949ebaL, + 0x97689f15e79367d0L,0x918bf9a30d820328L,0x2d4bc99441c959dfL }, + { 0x37392f6e8c16ee54L,0x9f726d58e6f0849bL,0x497de1e4b8208f08L, + 0x60c51233d51a29b3L,0x0f61fb03c9e1d465L,0x09494bd0fbe2613cL } }, + /* 15 << 84 */ + { { 0x100ef5d0a2bd7bd4L,0x89efecf5f45e2a66L,0x63bc210b653786bbL, + 0xc7748dba0a0e47c4L,0xaf8122ae110d1ba0L,0x6695bfbf797c78bfL }, + { 0x9b0e6fb1d7dbff69L,0x106799703f53040eL,0x22d9ed52fcaf4ed1L, + 0x1e27bafdcc1b2d4cL,0x839f9c019f1c88e6L,0x1112fe541321ad66L } }, + /* 16 << 84 */ + { { 0x4f293478154d0f99L,0x1b82320dd07a24b3L,0x1bf7c94f64d55f6fL, + 0x4489b57d725c5125L,0x3aa4d43ab1b6a091L,0x054842bdcf7a60faL }, + { 0xaa918a4d2aeb4cb6L,0xcbdaff99ac7d317bL,0xed0e00a16812a03cL, + 0xb09acf270b0a1e4bL,0xc73a41f7ac28386bL,0x43134dbdf4cd1321L } }, + /* 17 << 84 */ + { { 0xe5f746af6e001a20L,0xdc975b02d6a9925fL,0x6d13e266e57f9100L, + 0xe013661396a9c4c9L,0xb483162850a66d45L,0xe3b0f96d4ee8439aL }, + { 0xf2a2c08d3e074501L,0x987b2b6b2be498e4L,0x605aad24a15b815aL, + 0x5bf2186f8529ad68L,0x1413b3d7885ad25dL,0x3de23959807efaabL } }, + /* 18 << 84 */ + { { 0x08336ffed8c33924L,0x15b56cbf5140b253L,0x38dcd310306caedbL, + 0x04ecd49647944afdL,0x1280d23f68a48f95L,0xf414220434363c6eL }, + { 0xd0a397eacaa8717fL,0xb51a1669c3994b80L,0xa02eed916c56808bL, + 0xc3ab55c583545c3cL,0x8b835820fd26114aL,0xe0cfa4a6ffff324cL } }, + /* 19 << 84 */ + { { 0x4db4bfb788b45f19L,0x130252bbe0d5fd16L,0xe44c97b22808bff6L, + 0x885e4555b03405caL,0x3b7ce036be9af81eL,0xebe17cf58c552276L }, + { 0x6eb946c977f4158fL,0x36c23a9c74a5e642L,0x466ff55f2e70a453L, + 0x327fd5fd28ea7af7L,0xc96bfbec6e658256L,0xaf194fe8c0a3b932L } }, + /* 20 << 84 */ + { { 0xcf63d27951c0d95eL,0x3b170a0bac86a014L,0xc21eaaa9881095e1L, + 0xed2fda116069a3ebL,0x536264b9bd2f1c5aL,0x819e1cffde312c2cL }, + { 0x6c30f983dfd6ce38L,0x2f32cc4c980b439eL,0x9fab10b63b9c03b2L, + 0xdfebe34e011ab74aL,0x587360e3b80963f6L,0x3db1f6108692e352L } }, + /* 21 << 84 */ + { { 0xf262f2379765908aL,0x76f8d0017d03cdcbL,0xdbcadfb22f35de21L, + 0x88d5bf592a73815aL,0xc4f4e3b02b1bab82L,0xf5cce885b9635dcbL }, + { 0x110a785875a416dbL,0xfe7e6c360adb01feL,0xa02642c01374d779L, + 0x9010758753bb5898L,0x0c764ed2a363fcf2L,0x24a2a5541700e551L } }, + /* 22 << 84 */ + { { 0x63a094c5fe3d070bL,0xf769b91988515eb1L,0xafe86e1450d1131dL, + 0x6bf277886774d3d4L,0x7231d699ffd805d0L,0x05132e5b6304116eL }, + { 0x3d5e255be34ce5bcL,0xfd9c3bd0c95e3089L,0x22a24023b83cbac9L, + 0xfb6d2b6fb0b3b98aL,0x74af1115f7e36fcdL,0xcfe15eaff9da3bf0L } }, + /* 23 << 84 */ + { { 0xb242ffd61da39f60L,0xd0ed946320cac1b3L,0x9ebd5e46e25f809fL, + 0xc7df7e5a07f5aa4eL,0x5eea38d791a5f85dL,0x6240f01d6080442fL }, + { 0x72ec0a5e251d866fL,0xd3e4acbebf2c0037L,0x0d4f47c90fd962d7L, + 0xece7c047b8de2dfbL,0x841050b96df17f0fL,0x567c3df7e933a4d5L } }, + /* 24 << 84 */ + { { 0x266d2c1cbb2fcdaeL,0xb538d4a252be93f2L,0x774c88ba73bd0094L, + 0x65283a9b81a7e042L,0xe1438bbfd0381625L,0x450e1f644d0db206L }, + { 0xb38ae9ef4e60fc4aL,0x14ce87e112719817L,0x831d41ec570303f0L, + 0x7172917028850444L,0x2077ea32ccd609f5L,0x091d1166cd273fdcL } }, + /* 25 << 84 */ + { { 0xaf5916f49412edcbL,0x9ccc0dc08f01b2d9L,0xbed1fdd42dd737c8L, + 0x29d26cab95a21501L,0xff38bf18c70f1364L,0x0bdb055876879b06L }, + { 0x706031e2a14164d8L,0xe229fce1fc39648bL,0x5ebc640878e97c8bL, + 0x26039bda822de18fL,0xab992da4b9f090d7L,0xf409432d53eb438eL } }, + /* 26 << 84 */ + { { 0xdf216dd84b2ca517L,0xb3eec4b9c6b74c4dL,0xf564e6c81c14e77bL, + 0xcde25f1c2c2c9395L,0x7e31f7a5049fcc83L,0x6913707b9284c753L }, + { 0xb92a6f2458e6eb5fL,0x85b0cab595148292L,0xeaad036d7449be92L, + 0x2f6a2888eb94a702L,0xd7d8773d47d59fb0L,0x612d257303c0bf25L } }, + /* 27 << 84 */ + { { 0x805ece910ea742f6L,0x54486a6ffb5dba94L,0xaceb0eebbae52f76L, + 0x2200fd85e98794f0L,0x44bd993ef305af19L,0x28f256738eb8baceL }, + { 0x5d3fabbadc5f9c18L,0x4338f79c1b003ed1L,0xaf4b0566bc20c65aL, + 0xded9407c3045d1bbL,0xe8713d7506391eb2L,0x557d62c971307365L } }, + /* 28 << 84 */ + { { 0xb872a10584d2c3bbL,0x44bca57139196026L,0x857327d84e352e5dL, + 0xa6c6004ad925f99fL,0x48aaf266bab79eadL,0x213ad923adab2a3fL }, + { 0x3be29b6df371cc48L,0xe732b9062385c9f4L,0x562e0be123f0a84eL, + 0xbb6b017228c4b0dbL,0x71a93ae5f4c6d8beL,0x76b8bb16551f1fe9L } }, + /* 29 << 84 */ + { { 0xd028d9b5242002c2L,0xea105054823783caL,0x01cf8a491d45c34fL, + 0x1035835e42457869L,0x0a95049661cc1e05L,0x9dce5bd3b439afc2L }, + { 0x8552f02003b18e4fL,0x4973e3bde6144805L,0x29fb98d8d8514c4eL, + 0x0ce0e8d83ca27b39L,0x7aaf3f5284bbc6caL,0x0572bf40d78c7c5bL } }, + /* 30 << 84 */ + { { 0xbbfaaa94c39926a8L,0xb9a59fdb60a138aaL,0x217a1aa2947e30e9L, + 0xcac988c9c52c9fffL,0x5676473a3bae3c39L,0x7d84b353857f04c9L }, + { 0xdeded30cdd324e24L,0xf07c678a9c242899L,0x956d05538cb64f3bL, + 0x9d34e2f5502cb2b0L,0x99e1054a51dd03b3L,0x86b8bfa54d60a593L } }, + /* 31 << 84 */ + { { 0x3dcd2df9c8870c4eL,0x7cfdd05f1699cd0fL,0x19e9ccf027e79e0fL, + 0x56e997027b85d75eL,0x407b5b74ccadcf9cL,0xc961a336297dda7aL }, + { 0x350c34d56d12d17bL,0xe37de9a93bc6afe9L,0xd2c7339e0d641d3fL, + 0x2700f39cf7dfa063L,0x2916f9ad8ddef077L,0xffec6230547cdbebL } }, + /* 32 << 84 */ + { { 0x10a53b90754d15e9L,0x6cde9a0c5f4c7218L,0x740d513fabef2b96L, + 0xff6cc47cd3f802fdL,0x1be6825beb0627afL,0xdb21ede55886c2dcL }, + { 0xb6cfb2c6f5daaed7L,0x68b61aa8fae29a9cL,0x7a1e16f53a5a485bL, + 0x16b60b92e7b2223eL,0x332f33d836a13a9bL,0x4567c313876cd1a2L } }, + /* 33 << 84 */ + { { 0x7663402de62014a2L,0xbffe1e7fc4efd224L,0x2080eb02c38f766dL, + 0x6c95529ba9641db9L,0x24dc13a5c68de8e5L,0xca219b3fbbc3016bL }, + { 0xb83450e310b634e0L,0x8cd26d775b097a34L,0xb912c34564c9884fL, + 0x3d1f28be5bd75f1eL,0xdcba2b479466ea59L,0x4077e017ca9948e3L } }, + /* 34 << 84 */ + { { 0xb4b2c65df91c7972L,0xabe915496b689013L,0x4eb7afa8d506333bL, + 0xc2f2ac1d648e7c0aL,0xc6bc96b1213cc243L,0x0b827c2189e44025L }, + { 0x2e866601cadee87dL,0x8ee85356b4719ce3L,0xefda7427b4fc0081L, + 0x0d5c33c4c802c92dL,0x4c8635ab58515f01L,0x9d7ed87edd0ab04fL } }, + /* 35 << 84 */ + { { 0x9a660794cda4cadfL,0x70784fff2484a3b3L,0x8ed664ad2de7de13L, + 0xbaff5937030d906eL,0x884407034ab43a4fL,0x86dfdd53ee09795bL }, + { 0xcffa6852fb0e889cL,0xd94373e1e8c9fb95L,0xecc0ea249b0e3ac1L, + 0xe88eda6eaa89e492L,0xbb049803da19207cL,0xfbb0c3874bbb5be6L } }, + /* 36 << 84 */ + { { 0x3e2bdd9b5a5f6b4dL,0x30cf4762ab005a55L,0x8736f5188bacd78cL, + 0x8a5a647b09dc21fdL,0xfba40c38ca06c1fcL,0x63d53fb64a4e1524L }, + { 0xe77d07a19a2bd706L,0x54144ea7bbe30e86L,0x8eb606220bd955a4L, + 0xf689cc80b3c26cafL,0xc70fe95c9fefcbbfL,0x67f9e8e2495b5bdeL } }, + /* 37 << 84 */ + { { 0x04361e6b2e4d2cf9L,0xdbd3cc13ade11ba7L,0x93dc1d1df47d8ae0L, + 0x7d46bba6fbb2d65dL,0x797ea0df92e97abdL,0x09eb3975a712e8cdL }, + { 0x9ab3a54e0380cf8fL,0xcd1a9574c96710b1L,0x6abcd1a1dc13dbfaL, + 0x1be0db71c2ee67f9L,0xee8ec8d0c2ac89a5L,0xbc363f407da201f5L } }, + /* 38 << 84 */ + { { 0xc86c049bbbef377cL,0x43df6f3703de56a7L,0x01eced2b558e516fL, + 0x18fca0bdb43c1cc0L,0xd8c6f7ff62121c68L,0xb2f1f1ac36f90713L }, + { 0x5f876328ea1bbd95L,0x9f22dd535ac4ce8cL,0x7e052acc7df88002L, + 0xedf21fb7068d46a4L,0x349130a21d7d0220L,0xcccc79beaaa68eebL } }, + /* 39 << 84 */ + { { 0x9c955b5eb4100632L,0x8d6dd2d3ccd99a0eL,0x700f827c265dd397L, + 0x5540bc0cfc85a2c1L,0x6d4b8e7adfb81661L,0xfbfe1ebe1d5c1485L }, + { 0x322c2883c9dc1b6cL,0xc7c897cdfd7e0f34L,0xe70b0586030e41aeL, + 0x4263e06e26a728b7L,0x0ee2b93392387542L,0xae708ccaf6220511L } }, + /* 40 << 84 */ + { { 0x05ff8b9cbc15ae37L,0x94dc2e85d06d62edL,0xea1d1c8b4b02607dL, + 0x1fc202a224da757cL,0xbd5180bb35440e69L,0x0263dd51698ee7a5L }, + { 0xbe93f27654013d74L,0xa7c041c464e81695L,0xbb170ac13ba5336fL, + 0x1aadf302af84dfa1L,0xeda58747c960788fL,0xb456070e5eefc35eL } }, + /* 41 << 84 */ + { { 0xa905d421800ed69aL,0xdb8a643813622898L,0xd003affbdaab0769L, + 0x467bc051f0aed9d3L,0xed1e6951b11085d3L,0x7a1d1152d3f54fc5L }, + { 0x8cb243b6dc8dd008L,0xf9c690d1f409210dL,0x9a3195399461aee0L, + 0xf580724dbc2e4de0L,0x52f648e4e759556fL,0x235a79f2697885d6L } }, + /* 42 << 84 */ + { { 0xb293d3fe8220ceb2L,0xace20e7e049a33a9L,0xa584ad52af4198d6L, + 0x49c5cde64aa0a5c6L,0xc4f7877ecee2e664L,0xe1557968bb98ed87L }, + { 0x69b0cd713066000dL,0x1af188cbc7399f29L,0x5b88b85c306188a3L, + 0xcffa28eb4097182dL,0xdb01149ec80d0aa9L,0x9f8e6d59402bc397L } }, + /* 43 << 84 */ + { { 0xa646077bd5b97d37L,0x618df84461cfbd95L,0x3a9fe2f447c62894L, + 0x7f2760eb4e0f1612L,0x50c08fdb36e5acf1L,0xac799584675d2aabL }, + { 0x3eba6f54917dd606L,0xf585fa5075119ed9L,0xb047abfca32016bcL, + 0x61c03e51aca118f0L,0xef9fcc526dc13766L,0xd849eca5e8a3fb72L } }, + /* 44 << 84 */ + { { 0x11ac1ff4147faf46L,0x5dd8913882b818f4L,0xe439f66fb15fe5a2L, + 0xadf913a5fe8fb45aL,0x3dc708404a6bbdb0L,0xe8e1204da4af4ac5L }, + { 0x4be549318ba70502L,0x945d9a765883b39bL,0x99cb1c721a76198bL, + 0x96fbed479a7949e2L,0x30ee96ebf0299bc4L,0xb7dc5e76d3dd160cL } }, + /* 45 << 84 */ + { { 0x85eca39b0c88d5feL,0x96000863af9e0158L,0xbb13f99c4509590eL, + 0x50033c18034e2499L,0x1e9346f87b86cb33L,0x917d88b4aca548e0L }, + { 0x0c422c2e9e2a7e15L,0x6751c95c5e37fb06L,0x631361b8c40d21b7L, + 0xe231858ec9958deeL,0xae86abc54d9936e3L,0x60c78d1137bf9213L } }, + /* 46 << 84 */ + { { 0xa0bcb7c6283190a9L,0x36c884ffc53fe76eL,0x071d4acab23f0865L, + 0xd44e3c20e14a82f5L,0x704dadd8968d28bbL,0xb40d2b948e88ad61L }, + { 0x4a29142ff3de62f8L,0xdd071910bd7292a8L,0x5b12c32d5b3571c9L, + 0xe9886262943c6aecL,0xc49b7506cb1e0a33L,0x87f6c2d3de95886cL } }, + /* 47 << 84 */ + { { 0x44ba232e010f465cL,0xb82486c69ac91d38L,0xcd1a6bf75de743f5L, + 0xe050232838acbc4bL,0x8de9c29631fb87b5L,0x9c8029250450c4efL }, + { 0x19ee1607635e64a6L,0xeff5478c69ed7f8eL,0x311201a027001c21L, + 0xfc0382a78beb55ecL,0x494b623ce9dea7f8L,0x926a3f756767f769L } }, + /* 48 << 84 */ + { { 0x802f495cee46f99bL,0x0f3ad0ee43b91cbbL,0xeaf3b294e9b3f0f6L, + 0x82cc760033cbdcd1L,0x1a5642278e83fce5L,0xcf1b2edaffa0e4ccL }, + { 0x7d93e9769b1f5706L,0xe4eb843cf873d68eL,0xcb53dd79eafe5f35L, + 0xcbbed8f0fcaafabbL,0x570472705f053efeL,0x2c71a95f1ebfeb7aL } }, + /* 49 << 84 */ + { { 0x02d4717ddd7a5499L,0x3bc8bdcb9966236bL,0x13f08015fd27be15L, + 0xe05236f6baaff392L,0xf73bab3f7b4cc522L,0x8ad26d4552ccc027L }, + { 0x79f8e79e9e9ccd7fL,0x8011b92aab2f22d9L,0x6aef576e729662e5L, + 0x7d5194d05e568f55L,0x2947d63a1a40860bL,0xe9890f1440305b54L } }, + /* 50 << 84 */ + { { 0x8085614c0fa9602eL,0x9ee1b9b26651c4ffL,0x65dd9c94ec048f1bL, + 0x10b4a62f6d6c0fd7L,0x61469fb7d391dcd2L,0xdf751399edc3d431L }, + { 0xe3901315c913acbbL,0x31581d7a90976644L,0xf20809634aee5cecL, + 0xaa716eafe5408c5dL,0x9e356989b9a60ad7L,0x2d6e7733a6a3c977L } }, + /* 51 << 84 */ + { { 0xd6d99f54f19b8464L,0x3322a0b8a0be5c3bL,0x6cff730557e98725L, + 0x786709c7953a357dL,0x3864d278a1013652L,0xf7471f111738f6e6L }, + { 0x0377a923984c465aL,0x4a24b9e14ba970e2L,0xe53dd9f21c01d248L, + 0xf422b754fbffc0d5L,0xae25dc0ec6a956b0L,0x3c3fef96ce806445L } }, + /* 52 << 84 */ + { { 0x6a69d207b5906d71L,0xf3c757ed8964e1b1L,0xdae255af5f98821fL, + 0x6c801ed4db1af96aL,0xd12430343d109b86L,0x4b2aa65fa091f98dL }, + { 0xd9bb4c2132dcb5f9L,0xe5a5979bf190a1e0L,0x0861e5de40117a91L, + 0x8753c9adc39120e4L,0xfdcb09f4aeb4a18fL,0xdbda38746bd1fd08L } }, + /* 53 << 84 */ + { { 0x1bd8e8c0304f7045L,0x8ffcf24eedbd2dd0L,0x13c9441de6ae4dadL, + 0x5efb70aab418c02dL,0x9d0fede1b8cf6949L,0x613545cf41f5aec0L }, + { 0x4e3342244b98bddeL,0x7d0c11110fd8aaf9L,0x30c2bedcdfb8643cL, + 0x875d386aa83e493fL,0x85b32632d6cd0825L,0x9f1ef3a01445507dL } }, + /* 54 << 84 */ + { { 0x2b70440e54f6b8d9L,0x355e692430eddda5L,0x354e7cfbc9199910L, + 0x7e8933bfdc7de946L,0xc5692fa981b9eaabL,0x2eb58fff98cf5f21L }, + { 0xd0d8f9bb96b19d59L,0x779aad414d1a6285L,0x0cee1a9b5eb87c49L, + 0x676e36ff786c4c81L,0x6618c8f112d34964L,0x2061186dd03e9562L } }, + /* 55 << 84 */ + { { 0xa5ae40977da39b54L,0x98e4d1d9f1d40635L,0x40d97af126154fc6L, + 0xf18041d4e9ae28c3L,0xdca9487555978c61L,0x4aaddec43638b9b6L }, + { 0x1e615a2eab925f91L,0x5cfbbe9ded8a50faL,0x0f26d3ffb2034aa1L, + 0xb2f9cee2c4813646L,0x2195af47957b6709L,0xa55dac537e7fc45fL } }, + /* 56 << 84 */ + { { 0xe44a8ed7630816b2L,0x5fb9b643cca34310L,0x07826148a3b5d2e2L, + 0x0f890db16e65c2efL,0xe9feebe288283844L,0x8e56c6760368a9f4L }, + { 0x8f0cc9c93e4ce874L,0x646ede9b09f1beffL,0xe92d6bda014e3d19L, + 0x27e620c5520c921fL,0xfd9b2ae1eed78555L,0x68684615816a603eL } }, + /* 57 << 84 */ + { { 0xcf54e9e89ded00c7L,0x8dff0130abbf7765L,0xf12773fb10c5f8d0L, + 0x7435ac767382e4eaL,0x93092b16f61d443fL,0xc1554fa846eb45cdL }, + { 0x0896852c30957ca5L,0xc0d91e3effe60944L,0xce8aee57a1b7c75eL, + 0x4d24f07007cd1a9eL,0x3d8e381094456b11L,0xed6fba6b9dbc9d0dL } }, + /* 58 << 84 */ + { { 0x1b1de3ed8b5b8f82L,0xf542399d64252363L,0x23f34cccd206f26fL, + 0x54c48d9fbd941d6fL,0x3859eb56202e757bL,0xedcb4729ae0eaf7aL }, + { 0xf08753c512360fceL,0xf37ece765f697cd4L,0x073cae01c98a7c8bL, + 0x6e298559df664bdaL,0xe8cefd27194b103cL,0x56301e2a811f6a71L } }, + /* 59 << 84 */ + { { 0x8103c6053d3fe586L,0x472885b3999bb4caL,0x3759d2d492a2834aL, + 0xaa4eb3acd46cca1bL,0xcb99aaba633e579dL,0xf9369b033d6dc569L }, + { 0x55fdb1fe8398c067L,0xd7aab8b47e6826ceL,0x7f5497bd8b525561L, + 0x2e0e1e9c2cd0e3beL,0x3142a6e2c47caf5aL,0xe78cb1840f4b802fL } }, + /* 60 << 84 */ + { { 0x0a1577baf455f6bcL,0xaeeea79094df32b3L,0x1af3ba0f6bbb15ceL, + 0xaab92a74e8522659L,0x84087a8f7efa0a4fL,0x83c6991b84596065L }, + { 0x11f7829d29fbb626L,0x32b04b2f86031974L,0xf3a5b8722c1291deL, + 0x2ffcc97e8bd2be43L,0x575400d10a206f7cL,0xbb4583de0befbce6L } }, + /* 61 << 84 */ + { { 0xd448eafaab983fd7L,0x2622336c7a18a7e0L,0x36632e221c274b3cL, + 0xe64e8f89bf086fcfL,0x1dced08fef72ebd9L,0x61249c25ea295d31L }, + { 0x7433743d3755632aL,0x9d766243ff32ed08L,0xc36e816a977b1d9aL, + 0x1069fc0820ccec81L,0xbd4af7bef65a0cd8L,0xd04127fc92e31836L } }, + /* 62 << 84 */ + { { 0x39560937ea57ca46L,0xe1f2b7198229d346L,0x462b28d4dd02dcbfL, + 0x510fce98a333d609L,0x795fbd38fefa05beL,0xd6e34c231bcb029dL }, + { 0xf33291fc838f7ec3L,0x2a01a1f5f16e7247L,0xf9737722c0bcb3cdL, + 0xc53ef57ecc8a6c77L,0x219372afc750f1a7L,0x3e6a97c3d14e60bcL } }, + /* 63 << 84 */ + { { 0x87278f062db3d752L,0x64c65f5cd106b7a8L,0x04ccc14d41ee7aebL, + 0x72d1189e71952b60L,0x2e88f851080e9ea8L,0x625a6d32913e8df4L }, + { 0xd943de73900ee95dL,0x6c12b3b3ecb8b3a0L,0x6209daf2c9b141e8L, + 0x81c02f71412da959L,0x222d17b747278f65L,0xaa338805789138e1L } }, + /* 64 << 84 */ + { { 0xa896d28e4aea3fa2L,0xc6137a456db06ee9L,0x1bbafe8c06fb15ccL, + 0x2daab2961cdffdadL,0x984defc8e1119b3aL,0x9cd44c3cde2a25a3L }, + { 0xa7f54ece54ed6d73L,0xd283017f50907054L,0x69130efc6a3b9442L, + 0x5d17f1276785163bL,0xc019911b172b1d0aL,0xa19c745f7e3e093cL } }, + /* 0 << 91 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 91 */ + { { 0xe185bdc2ab83d932L,0x0a75845dd7c4e754L,0x1f6f3397c3fe5695L, + 0x6c9f3a5f61f6a04fL,0x3c0f9d4bb390a92bL,0x9e3336b74793b454L }, + { 0x91ad0c341472f06bL,0x4110047a892cbdd7L,0xfa24d90565d53c83L, + 0xd63e58334176007dL,0x741089fd2cd1623cL,0x6b3d92022685d345L } }, + /* 2 << 91 */ + { { 0x1d510157c9cb7f6dL,0x532a077346ab7372L,0x2ea07e2fc6dde9e2L, + 0xceed9ad937d5bb1fL,0x3121994b98cc6e28L,0x67d2fbb567ad8fc4L }, + { 0x34707fb3dc9f195dL,0x6a601f481fd5a013L,0xfe939b8d81ef6cb5L, + 0x5c51e8ab1223a9a1L,0x8f6d7993db74cf37L,0x0b81c5b7972808e1L } }, + /* 3 << 91 */ + { { 0xcb4e85123bf921afL,0x28fc6332532e81d3L,0x682d8637f69f907dL, + 0xbd9fa8f45f759a16L,0x091ea9fa51f03716L,0xd685a14132c630e9L }, + { 0x7600c9ac3d249cf4L,0x687e2022002cd2b5L,0x7ec205ab55334058L, + 0x9d0d86b13ecf1368L,0xb3fc17a7fc7baf6dL,0x57939961361c91cdL } }, + /* 4 << 91 */ + { { 0x0db33228010c0754L,0x10635ffa8eca7c59L,0x6efd85380e8a38faL, + 0xc1812ea5769360d8L,0x505723dc76f27ef5L,0xd0358e02f35af2e8L }, + { 0x9f7bb7fed99419eeL,0x87c66e83430a0e2dL,0x01187549773eaf7fL, + 0x05bbbba489d51bdaL,0x52cabb06640ccde6L,0x0d5cb557e7ff387dL } }, + /* 5 << 91 */ + { { 0x709d61ca10e06f1aL,0xaa1e9fc578eba75cL,0xf85d062f914b2cfcL, + 0xe73b3baf9089d85cL,0x4ac05feac4a284b9L,0x92c78a433acb7268L }, + { 0x7b5586f8ee45bb4dL,0xc39a0d0e6ac0a9e7L,0xe4bbe3d54d6f9ab8L, + 0x1489463f1fd46a08L,0x3ba3182529dba364L,0x94f000d68138511bL } }, + /* 6 << 91 */ + { { 0x70187dfbc39c1cefL,0xa785216e0c50c71eL,0x30188b816a6c0d60L, + 0xeaeda67d6a27e97bL,0x4a5192826ba389aaL,0xb96c7c7ea2bf1273L }, + { 0x8ff10657267fe714L,0xdff4a271996d91b7L,0xe34ba3e11dc7aed4L, + 0xc457048b38853d61L,0xe89825db1ccbf658L,0x68c7b4556b255eddL } }, + /* 7 << 91 */ + { { 0xdc14cb2a74871e18L,0x017b1340fcb8974aL,0xea5cb0546e93c20fL, + 0xa7c078ada9e2ad1fL,0xa37207d4beb26838L,0xcd8b3b25de7ee8eeL }, + { 0xdca6606a2801a7ffL,0xad2fedcf0f8af3faL,0xf27d30b49b530c05L, + 0x071fc1c36b2a4613L,0x363aaa99b72cea9fL,0x7a33ed8f3d350374L } }, + /* 8 << 91 */ + { { 0xc377b373bb20fabfL,0x68d3aa52f986b847L,0xd9c2f2adf39b6894L, + 0x1bbff106bd6da22eL,0x3f7e5b8e7e09678eL,0xad6a87897ed3ee78L }, + { 0x689e6b31af9807b9L,0xeca87778bd1f6ef2L,0x17d3277edda78c54L, + 0xe686caccefb65cb7L,0x758aa1ab19a30f0cL,0xb40df97fb11f071eL } }, + /* 9 << 91 */ + { { 0x43b379f71a54cd32L,0xd61fe6c948817fa8L,0x6d7b0acc49ab7a6cL, + 0xee23b4a0eb6bb45fL,0x340da1f1a2bda931L,0xfdff68411750ea8dL }, + { 0x890346b8a96c7df8L,0x551993aed4fafc31L,0x2830b98890de711fL, + 0x4d23863cfb5b5286L,0x327161a0d636d67cL,0xf99dded9733e1725L } }, + /* 10 << 91 */ + { { 0x0bef2d2517da64c9L,0xb94dfc85470bbc15L,0x2c2417cedd4af7aeL, + 0x52b5b3bbc8e88ca4L,0xc00328c44f20d154L,0x024290f730af5d4bL }, + { 0xe8bacbebeefc7350L,0x89eed6ebb72abd15L,0xb67d1da61d9e7030L, + 0x2ddefcbc0e70a331L,0x7d09bc6d61e32577L,0xc2073cc95b52e979L } }, + /* 11 << 91 */ + { { 0x585939298b806bfaL,0x608ddfbfbce6a08aL,0x674545a08eb27b54L, + 0x4b57a947c8fba762L,0xcf960113cbd8c683L,0x7b5a479a4fef1937L }, + { 0xe26eb960450e97f1L,0xf04b36b9d8605a37L,0xb208c832ee5af2b3L, + 0x3578d3a71fa337e3L,0x22547fca93509939L,0xd93dcb50e848508aL } }, + /* 12 << 91 */ + { { 0xd40f36e6276f2576L,0xd37455c46405cfe4L,0xe34094d7cc51dbaeL, + 0x20f93f0f0edf8bf9L,0x534b75aa23b5e165L,0x438e4dd1dc1b73a8L }, + { 0x9dd48c413bddb435L,0xc49867a0996b4932L,0x4212f8a2a9ffa0daL, + 0x8d5236c4d94ed9bdL,0x81bec489f169cb19L,0x71cc1d7e6104edfcL } }, + /* 13 << 91 */ + { { 0x31a94a7f22771941L,0xa277284b39867dc3L,0xc66bd88b1a52f0f1L, + 0xd2e2707b1aa21ee8L,0x78e4f280248d61e2L,0x33df48c7596a31f9L }, + { 0xb9bf2baab1bb1e89L,0xe1bbcdb4038f10e2L,0x81f674a877b89305L, + 0x8b2ec6ee16f08a86L,0xa07239c29db97ceaL,0x9f4ae6647ef8ecbcL } }, + /* 14 << 91 */ + { { 0x9cb21b57012eaba3L,0xcfce54821347a83aL,0xe3f3a67100d7b34bL, + 0xd4bcb3d1a6c1b0c3L,0x6ebd26fb9f3c3e31L,0xd01746532dc79be8L }, + { 0xe7cf9a0ad4156cfdL,0x2757cb0416face21L,0x8b0e320e69e1f08bL, + 0x2a8caf9b946f83d7L,0x6daff0ba98a399adL,0xb4dfea0938ed6086L } }, + /* 15 << 91 */ + { { 0x90ed8b41e2bcf8ceL,0xa464972be8dcc1a6L,0x5a3d0b80ba496081L, + 0xb636435569f85ac8L,0x0a2765b1a25bdd8aL,0x87a6c18f0d1516bcL }, + { 0x9344081ae3b01522L,0xcef8e12e608f0145L,0x6f3566a52155e7deL, + 0xcfc1be9c4d033a3eL,0xfc836eeaab97bf98L,0xbdf53718ba7dd059L } }, + /* 16 << 91 */ + { { 0x16f3708b953b9223L,0x0d3780f8770e7cf3L,0x97a615b227bb71a8L, + 0xa8b9a864162f8b55L,0x80ee8362d91e3fb9L,0xb2009a09f83a4ff6L }, + { 0x07a7873ac1696281L,0x17ff00c223095ddcL,0x427f683d860d60baL, + 0xea9959271f87d32aL,0xb2ac69faa050319dL,0x30c362b9d2d0b9ceL } }, + /* 17 << 91 */ + { { 0xe05c6a88783508b6L,0xa5569c8ee1779a78L,0xa1e0ca30cc1e84ceL, + 0x12ecb540337cca76L,0xafb5e2fb344d729fL,0x558db4e132c8f80bL }, + { 0x5aa3c39523128383L,0x9f04757cee1ee2fbL,0x41132bd215356deaL, + 0x4e9af313ae07ca78L,0xdfc14c0100c6b589L,0x54fdb4f3dc16a1f1L } }, + /* 18 << 91 */ + { { 0x71e663c234938279L,0x9a8f5ccdb05630f4L,0xd91ead12aad70096L, + 0x2b19b27e9e46cf72L,0x93348c7038e3932dL,0xeab6c03a5c7617b4L }, + { 0x57c13a97538eab27L,0x2624d17b2f5872f7L,0x77b63d9104b00f8eL, + 0x2e0582473c89db0fL,0x5d367277937d0d8aL,0x28c19068df60c252L } }, + /* 19 << 91 */ + { { 0x9867bc3d38cd6020L,0x5f341d8c5986f76cL,0x108a3c0d0dab2e32L, + 0xd127a7f989ab3654L,0x9d5018f468505cecL,0x51204da0a8fc94a4L }, + { 0x1751f30cf6da9840L,0xafe6a8d955ed1f74L,0x270a5d1180165ac5L, + 0x739f63e05de1e17bL,0xaa95f30735d2b566L,0xf20dd093650236a9L } }, + /* 20 << 91 */ + { { 0xd648dd79ee45d4b1L,0x0ceeaa64c2bc2f0aL,0x695f3a3f491a2862L, + 0x4c07e2e0ce497e3dL,0x5c53879969c766c2L,0x3f856a2e4c4a7c14L }, + { 0xbf8a6d81038032a9L,0xbeaadd7f45b7c960L,0x78b22e85d50b9d26L, + 0xac1c56fa7eaefe26L,0x21fbce54fc69f13dL,0x37be1b47512a3708L } }, + /* 21 << 91 */ + { { 0x12845d55689429afL,0x7e20f0f9082c8ac8L,0xe1615340249773b6L, + 0xf66c39638d0f35afL,0x4a20ce6d67d27093L,0x1d462f08e55802caL }, + { 0x66f209849ff4dd67L,0x6b86f8d8271c57b3L,0x8701a5cde766b85bL, + 0x50737ac2eea5fbfaL,0xb46ebb42a702f3d6L,0xf853091d999258bcL } }, + /* 22 << 91 */ + { { 0x0ce992198c9e7869L,0x653006be525c4adaL,0x783620e4330c402dL, + 0x185a6ac833b728b5L,0xa297c4a99d390886L,0x547d1db5db4b8123L }, + { 0xccf12f071acdb039L,0xe89c5866078ddc28L,0x3460cbb1e52c383fL, + 0x7a4d1beaad25b82cL,0x21e243fdb429be1bL,0x5aa85c25bdc0d798L } }, + /* 23 << 91 */ + { { 0x76cf73b9c0db9d16L,0x45e57cdc1970ace6L,0x3c6f5314c54a109aL, + 0xe32306f7da47cbfbL,0xb3787bdf93e76516L,0x68aa80084c6d4e22L }, + { 0xd9246ddcb3d37be7L,0x6de2bb4d7000f1abL,0xda02568b67e4751dL, + 0x3ed7a5615c7f88f4L,0x5f05c828ca5116caL,0x139cc5772a2ebb9aL } }, + /* 24 << 91 */ + { { 0xc983afb64cb8d897L,0x7f05e954b14cc152L,0x587fe71e0f4d02f5L, + 0xaaa43167531b0cd8L,0xf69452727a26def9L,0x7ecf1e563bab50e2L }, + { 0x04b6f5c94c6f20abL,0xbc6cec2b893b497bL,0x79e89567c9dc548aL, + 0xa39a0a567a40b749L,0xf1531e2644bd4efaL,0x14cdd759057c7c70L } }, + /* 25 << 91 */ + { { 0x30c49847d6d51bbbL,0x70b744feecdc6aeaL,0x38cdf36fe8671744L, + 0x5834286b8cf6461fL,0xf3414f7b2c09d632L,0x58425e4d5debb923L }, + { 0x8bd79117a6b96c6bL,0xecf9802680f56fa8L,0x5ae917d7e6dcbbf8L, + 0xf2d80fb169240a4bL,0x005ac47596e3aa3aL,0xe5196a3463536aa9L } }, + /* 26 << 91 */ + { { 0x5fb02929811d42bdL,0xd7d1b956289929b4L,0xfd3546947e531627L, + 0xa37c9b1e58c2b2e2L,0xf30ed0f902bf499bL,0x3fe80d240eb6df36L }, + { 0xf96270e57b148672L,0x47362483647f48d8L,0xc279ece6c29bc59cL, + 0xc05c1d9ffdd7e628L,0xef8fc92e17568a7eL,0xd65fe5a9ec0e7f00L } }, + /* 27 << 91 */ + { { 0x0ad31de68c93f010L,0x151b1405945ec54cL,0x325d132c3db6997cL, + 0xbed9cb3a335531e7L,0xa83932c34a578610L,0xd905abbf6f721147L }, + { 0x6dd45af086d1d919L,0x2b2ee3090195e91bL,0x3dc30d5edb70d257L, + 0xfb04b014481bde1aL,0xc2ac3ec82de2debeL,0xc9f161e090db691eL } }, + /* 28 << 91 */ + { { 0x8041f112afefdee1L,0x8cab3c86b891f668L,0x1f18774e2b61e754L, + 0xf0d81b2459df567cL,0x2cc25da41c95e1ecL,0x315b1b1ac735d39eL }, + { 0xd0a9b9fb010734cfL,0xeefc0398c79386daL,0x49ce859b11fb1917L, + 0x3d66fd6baf167239L,0x2522b0ef1fea6175L,0x1a27657d3ec4a52dL } }, + /* 29 << 91 */ + { { 0x89ec003abb2ca05dL,0x2290b5f403195ec6L,0x9989bd925f6b95b5L, + 0x1d6e6b2fad409cd9L,0x41f9b9ce3bfe7364L,0xb240f89570ec096cL }, + { 0xf8725a58b8d5a5d6L,0x3bfec6f1c581930dL,0xc93e290356235c98L, + 0x82af4269c7cdcb5cL,0xeb13fa40eea6fe91L,0x9247050097c80acdL } }, + /* 30 << 91 */ + { { 0x48dc23534ded5b58L,0x1b69590756e707caL,0xbbcb73927ec7794fL, + 0x3714dfa6e50dbcc8L,0x4f8083c8f27ec5d7L,0x6358d2273bc8c3e4L }, + { 0xe0c2a0e7656cf184L,0x3996e0a24244d801L,0xa46767b54e543c01L, + 0xbf55776d965f1e2fL,0xeb66845e6bc872eeL,0x6a73fef1b441895cL } }, + /* 31 << 91 */ + { { 0x21602e432b26bbf2L,0x6092d570d1bfd7e2L,0x2b48d74a30b38d1fL, + 0x4aab113c67c53791L,0xa6acbd3df57be611L,0x53b6509ebd3aae7eL }, + { 0x047e5ab4d8751f49L,0x978ed11b0cf25652L,0x763553d2153619c7L, + 0xc7e85e93d824d943L,0xb82cc9781048a7ebL,0x7beb9166e39cc777L } }, + /* 32 << 91 */ + { { 0x24480c57f26feef9L,0xc31a26943a0e1240L,0x735002c3273e2bc7L, + 0x8c42e9c53ef1ed4cL,0x028babf67f4948e8L,0x6a502f438a978632L }, + { 0xf5f13a46b74536feL,0x1d218babd8a9f0ebL,0x30f36bcc37232768L, + 0xc5317b31576e8c18L,0xef1d57a69bbcb766L,0x917c4930b3e3d4dcL } }, + /* 33 << 91 */ + { { 0xf6625ac0b9a038e8L,0x954056eb2a921e56L,0x7135295aeac07bc6L, + 0xedde9c39f1ba0ea8L,0x628324026b592655L,0x4603177aefb8aa66L }, + { 0x63e5ea16406a6c28L,0x5897fdee1c758382L,0x515e49fd415533c9L, + 0x0a0dd627d6701b21L,0xd7c06db1c93a312eL,0x4fe95e3da33d8df7L } }, + /* 34 << 91 */ + { { 0xf113d92c3336edc5L,0x0a201f3e8ce47278L,0x57492feb5c52562fL, + 0x18b73800f29da837L,0x2262089f649a1ee8L,0x076b07657c99bf48L }, + { 0xa95050bc09bfad20L,0x5aeaa9088c7e713cL,0x264283ed3cda06ccL, + 0x5d574b116079b43dL,0x0071495cced10a84L,0x97441fb0570d3063L } }, + /* 35 << 91 */ + { { 0x340831072b228335L,0x84ea0aba50fbd43dL,0xafde6098b3ec91e4L, + 0x4fd293ca1091ad93L,0xee085e23552a785bL,0x437d799ed7057200L }, + { 0x41f735628a611ff4L,0x707a7cb5d2ef6254L,0xa9a8f00092a30686L, + 0x901cc8e60cea8d1dL,0x1fbc9ca6d6da2ddcL,0x61bcee2176489604L } }, + /* 36 << 91 */ + { { 0x5f6ef134781a7f53L,0xbac4cf47b10a9d16L,0x48148ba110e69f4eL, + 0x40594360a9c615f0L,0x3141817ddfb3fc58L,0xb9579a9263c38d83L }, + { 0x0544b1bb6373b9aeL,0x718a5fb7007c8185L,0x48d4a4f77cfa392aL, + 0x9c16cb825d44ba38L,0xc83d2df42a8fa83fL,0x835aacccc08fef0cL } }, + /* 37 << 91 */ + { { 0x09ce1818af09fefdL,0xd1d2f95f5dd9d687L,0x94ed08b5495c4eaaL, + 0xd1afff464a0b95d2L,0xd51ba2b455347a75L,0x413126295e3866edL }, + { 0xeef2d7e3cdd37660L,0x50e6fbdfec2fe50dL,0x9d071e18a664e2eeL, + 0xe70e1d9ed6a8f467L,0x576d0cc4e13afc19L,0x67ced86da0efc220L } }, + /* 38 << 91 */ + { { 0xa26968cb26a963daL,0x461d1ab5cecbd96bL,0x8eaa1834b3e38516L, + 0x1e92730f05d2cd2bL,0x91112026b07cbf92L,0x26eb815062374314L }, + { 0xa904f1d08ab1b9d1L,0x52006594692b1905L,0xc9cc90ca6ba4717dL, + 0x4bd7300aaad1c74fL,0x67ba07a4c21c5832L,0xdebfd810fa56a1a8L } }, + /* 39 << 91 */ + { { 0x3bc5aaf484539b6bL,0x6ca9ac0c0d1249aeL,0xb59da22db4ee30c8L, + 0x6e62553e57149c9cL,0x46db0089786333cdL,0xe1e2ae523e4c12ceL }, + { 0xf828d2b537b3fd82L,0x31844a9d03af654cL,0x85dd8daaea5a4677L, + 0x0db99b8f3432e82fL,0x99383b874866e1b6L,0x52310054e325b0c2L } }, + /* 40 << 91 */ + { { 0x737cd387044854f9L,0x488b2fd667eb29c2L,0xe71d9bb7258c5a80L, + 0x21afb486ac71048eL,0x0252b540d4d39296L,0xe3e52cb87839d8fdL }, + { 0x5cb1100667ea0afbL,0x207637d1de82b12bL,0x77920933e93bcfcdL, + 0x65197f5df32f636dL,0x82179527b6c41411L,0x7696a479f410c989L } }, + /* 41 << 91 */ + { { 0x78307cd80e8d576cL,0x10d3b950fd9d6044L,0x2c2f9e2bf4b20445L, + 0x961343c72c5c7ea7L,0x931c52a0af640e61L,0x45557391470d420bL }, + { 0x4096a997317f4d26L,0x15210801cceb9be5L,0x228102195ff0759dL, + 0xc388a2d21d265932L,0xceb79d01e86dd99bL,0x23e8fc7b3311dcb3L } }, + /* 42 << 91 */ + { { 0x1a7d0e091d7743eeL,0x18720797d53e4a8dL,0x78465f1ea04dbaa1L, + 0xd4f064da9ce65723L,0xc0e7c035b496e8d4L,0x25657d2e6bb2f9ebL }, + { 0x45576ab49f4b6cb5L,0x83983c70ba33d6dfL,0xf699e84d1eca62a4L, + 0x35528636a13f5c31L,0x6a1b56b01f6b1739L,0x7906eccc6ea87942L } }, + /* 43 << 91 */ + { { 0x4e584a4fec1204a5L,0xd96b00e845a5b311L,0xea11fb03030badccL, + 0x9b2141b2a825a89aL,0x18bbc30bf8b2450dL,0x87bd93916513b2cdL }, + { 0xb3dbde552f0b304dL,0x762f3dd7c3c4817bL,0xe51e1733edd3fdd8L, + 0xddad4c515d8219a2L,0xf5a8c0b8796b6877L,0x34563a8989bf65c8L } }, + /* 44 << 91 */ + { { 0x93e2e3a2881c106eL,0xa227cc49fe82afd8L,0x6fee74a4748e81f3L, + 0xb212e8eaa5dd966cL,0x68d270efdc7d8883L,0xef2f3966fe757e9eL }, + { 0x0340098b7466881eL,0x7ab98a0575884bbfL,0x24783467a472f62fL, + 0xc73cb49f988637d9L,0x2b5e9d27dfb710c9L,0x503f9a2f788fcb18L } }, + /* 45 << 91 */ + { { 0xcba6f4631a52b729L,0x8874582cc8be34cfL,0x98a08e246a9a1eaaL, + 0x77094319d5693f71L,0x575a0938a8504e5cL,0x3f59910c226f888eL }, + { 0x5c3587990aeeb1f1L,0x7c32821d3613bbc5L,0x66f288e7cc17db95L, + 0x6f3221998724ac94L,0x4e3fa38981db3751L,0xa6e798c8420403baL } }, + /* 46 << 91 */ + { { 0x56672f2e2cbea2e8L,0xd1a02df9128bd636L,0xff6a3bc6d47a0025L, + 0x24124f30d38d0b42L,0x89ac3b8dda63df29L,0xf26d72994d0b6458L }, + { 0xfff0445f7d6880bcL,0xface90f52be76351L,0xbf10c6b8ebffb74fL, + 0x0e53c533a1fba003L,0x037baf09112f4980L,0xb8ae6312be960954L } }, + /* 47 << 91 */ + { { 0x8397b60917270d4aL,0xb4d0c38700e4caeaL,0x69c52bb3f4c58f86L, + 0x06e0e01157b1fd41L,0xc5dc2f25627873a2L,0x9af848ca0ae53974L }, + { 0xb5c957c06ad18335L,0x93b564154ef09e7bL,0xb5ba282450e2c5ccL, + 0x63f003a567d7b68bL,0x0bcb0dc820bcbca3L,0x8803b1ffe3d4296aL } }, + /* 48 << 91 */ + { { 0xff41d51faae4bfd4L,0xcf50b14117c44facL,0x078b808e657a1ea4L, + 0xc5aac1a893c00c55L,0xcb99cfd0cc4d1c0fL,0x1d1048933fa123a6L }, + { 0x49646059023ca92fL,0x5833e326f3982134L,0x2e0d4bc9c5781cddL, + 0x5f7f84ed8d5e75f5L,0xb6655f1fe1e8a383L,0xcc18514c296e4943L } }, + /* 49 << 91 */ + { { 0x5d3e5f8d8a407ff0L,0x9c713c8c7b42b11cL,0x7433a9921e387806L, + 0x5272b92a98cb43acL,0x6261dfc1b1018149L,0x229d2ba5d3b4adf4L }, + { 0x1f52e72989f0905fL,0x965e062925d4c79cL,0x42edaeeb33e6c016L, + 0x5ec492e8af1709adL,0xaad39616c5763619L,0x85a659098c666860L } }, + /* 50 << 91 */ + { { 0xec8fe7dc86009df6L,0x42dd3c37871b20a6L,0xe4388c920db643e4L, + 0xcc5dfdd481e06dbdL,0x3f1a3c6458ca7500L,0x987d7caa22c04e9dL }, + { 0xd0c91072bc5717e2L,0x3f605fd2e77e5509L,0xa1cc1404c0c3e95eL, + 0x4afaa9fdc6d0edd0L,0x2f3aba4e0d7d882dL,0x3f1f0349796c5ac0L } }, + /* 51 << 91 */ + { { 0x5dac93982eeb82e8L,0x2fe5ffb57536ce1eL,0x2bb120ac6926cfceL, + 0xe54ff20f2236dbf0L,0xaaf0d31edf8c5a87L,0x5262fb9fc8f5df7aL }, + { 0x0f833760467092bcL,0x50fa223d0a8dc0afL,0xd6a4847d35406966L, + 0xd17d6ce003b7f56bL,0x8067d8e2ee2d64bdL,0xe33e51bb9fa4fe9bL } }, + /* 52 << 91 */ + { { 0x52aa210770248e4eL,0x30cf7e773b6bf709L,0x36961c7b788e1836L, + 0xbe49de5f7595af2bL,0x86b49b619cbcba78L,0x1947db3790cf1117L }, + { 0x7d3f599de14b4287L,0x14546993f0ca62ebL,0x0f6c8872d0abde7aL, + 0x1531ceeaafe2260fL,0x36449624ae5ecf96L,0x6cfa12a5840bdc19L } }, + /* 53 << 91 */ + { { 0xb092ad68c1d612b5L,0x9f6052507af5c37dL,0xf48aa7c6c702b673L, + 0x380144215cd29c3bL,0x7b09e407121867ecL,0xf71443d391e59047L }, + { 0xea51e1a6b6d16a51L,0x041fa7650f33e2ccL,0x3a6d50c73750dce3L, + 0xeebf5c2e97cb7a7dL,0x2530de228f39e771L,0x9af217c18f37f863L } }, + /* 54 << 91 */ + { { 0x38793fd0c683085cL,0x49cc5934dc436d16L,0x94c708e4175e770eL, + 0x41bfb65d059c2682L,0xf6b83eb75f004ddeL,0xe1881929f6864410L }, + { 0xfaa77fe0b438f937L,0x97a856069997e90dL,0x78366a9108de889aL, + 0x6c28ef64553229cdL,0xfce82c2fe9381854L,0xae98117146f70bb1L } }, + /* 55 << 91 */ + { { 0x3f77410e9aacedd8L,0x0e34bd7d453813e4L,0xc5818436825d6b0dL, + 0x0e30f037b4d0ac73L,0x70f6bc9b69b559c5L,0x68d3d71eaed15484L }, + { 0xd0254e5414fbae1eL,0x6ddaad42ae0d3df6L,0xefb91a545a6e98d0L, + 0xde3fcefc854ee5fdL,0xb2f0f3a1dfa2a8a0L,0xb656f97ad00ded3aL } }, + /* 56 << 91 */ + { { 0x01acfa7e0a90e37fL,0xf47e5946366d0ba0L,0x8e37db7b54c11845L, + 0x5742d8bd50a62064L,0x27dc9a33ed6d096cL,0x2246d73016deb724L }, + { 0x203c08da2c8f1a85L,0x210cda3a56fea379L,0xea6b1bbf2bf9ed67L, + 0xe5a1e5552395cc4bL,0x458a7e19de2d6b2fL,0xa7199a86734942a3L } }, + /* 57 << 91 */ + { { 0x53684c23d44cad85L,0xd23613f8940779a5L,0xf485c7a3940bd34cL, + 0x64c66a1f3f673b5eL,0xec29c76f1d6dd63cL,0xe10f56272f191435L }, + { 0xc054f9a7325d5759L,0xe6740d3f974edaf5L,0x2723ac6103f3b640L, + 0x0a2315a4576e0bbeL,0xf8156e1e4a3ec903L,0xa307bc249bbc8c52L } }, + /* 58 << 91 */ + { { 0x78579ca212a1687aL,0x208b7494268a02a2L,0x61708a002c1c5243L, + 0xca366915a760461eL,0x0e9038fe3ca1e167L,0x2cfd6fe3a58e2c57L }, + { 0x97c16e34fe79a49cL,0x1575244ef08e4037L,0xc1407fa08e2283edL, + 0x38ae77621b057919L,0xcec574a5e68a366dL,0xafdfdce03eff00d4L } }, + /* 59 << 91 */ + { { 0xdad0dca9162d80c6L,0x554141f8b888ea0fL,0x1e471b24d4036218L, + 0xafca22cfb36102d0L,0x437c51bff280dfa8L,0xc2c8bc8b50c9c30cL }, + { 0xe7bacc372a9fdf6dL,0xd01dc65cf0472f2dL,0xaca59cf983d7be3eL, + 0xf7c935425d9ec484L,0xc22046c6015a08a1L,0xa71b3c64cecdf816L } }, + /* 60 << 91 */ + { { 0x4b7d0b277abe7856L,0xe566f4567acdb39cL,0x70c6cdf20047ae7dL, + 0xd27f831233ed0392L,0x498f0ad0358a429dL,0xed97c4668e6ee95dL }, + { 0x3d11cd69f3018515L,0xedd460344c1b367bL,0xd75660e3b3ac8ec6L, + 0xc80dfc0fa541e6e1L,0x80026f005c091a6eL,0x62b86784c426f2bbL } }, + /* 61 << 91 */ + { { 0x417408e529ee8eb4L,0xe92f18c2917f9951L,0x1f471f0eb38b6210L, + 0x53cb14264df240f3L,0xeaf7fc0067c29b25L,0xbbf46fd3d99cb613L }, + { 0x05cd552eb465b50dL,0x136b8e675e136733L,0xd7d50f61ccf61776L, + 0x90187ec5a32b01f4L,0x21548ec523ba232aL,0x6c8266c0748e558aL } }, + /* 62 << 91 */ + { { 0x762f413d7650470dL,0x9b4af5d018c9ad5dL,0x85fe90460ea625a0L, + 0x4af4511b2200cadbL,0x4c16980defec2921L,0x42ae5d5d60dbe1a0L }, + { 0x0785260bbb2ceb1bL,0xd181ea3242f1fb7bL,0xc34f02b13a47672bL, + 0xb0bc79f770e58634L,0x6e7967098a8509aaL,0x05870e6f3c3e6d44L } }, + /* 63 << 91 */ + { { 0x46d4fef752f7c595L,0x5f35083a8a07819cL,0xbba477ca591233ddL, + 0x4e66309358e307deL,0x65c3e2b9ef827537L,0xcf7b7adb09ee9adaL }, + { 0x00a82d4b5f5e1434L,0xd6aecb8032e50afcL,0xffdce7ce6b034271L, + 0xa95d96ae036d5058L,0x61582ae24cb7d60bL,0x6a10577474139c1bL } }, + /* 64 << 91 */ + { { 0x53ebbaaeb475d8f3L,0x3d6ea31cff76bedaL,0x3c15f25d340986b4L, + 0xc5925d2e3365312aL,0xc35d3ee251641f96L,0x11eb2f75984128e4L }, + { 0xb41a21a83d04bc99L,0xf2d286006436c3d0L,0x4ffcf4c0faf5663cL, + 0x889d285a0a62c9dcL,0x0908665acb2d60c5L,0xe2f19c590a131be5L } }, + /* 0 << 98 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 98 */ + { { 0xc0de60f5091354ffL,0xd7cc38bba1bd1975L,0xf4122aa8e734e2dfL, + 0x08f40f63ef773db6L,0x0a7e9484ce2d71c5L,0xcc79173378a3f825L }, + { 0x0cac7a5bb47beec9L,0x1cbea0e4a3f7b5b6L,0xecf19a90d3e18145L, + 0x0d1b062a0aadf689L,0x42299f1ff3f0acf7L,0x63a645395ac252b9L } }, + /* 2 << 98 */ + { { 0x44bfd1665c1d4586L,0x46434e198d1d86d6L,0xe50fcf81c3936683L, + 0xc9b4eb068b08680fL,0xf90882c52832aab0L,0x42823cefecbf5ddaL }, + { 0xfd4d51c744ae08f0L,0xb54a08f1bbd21c1cL,0xb72953dbfb187c34L, + 0x166f7f26f8ed037fL,0xd2b1077a097bad45L,0x47794cdc790dd808L } }, + /* 3 << 98 */ + { { 0xfadb2ac4bac8b691L,0xf0c5a0361579c4d1L,0xa192474f79019224L, + 0x8c7a64574117a323L,0xe58122dd84d970a9L,0xc475893c0bf77208L }, + { 0x9518412f1bd45c95L,0x75bd0a72283f7a3bL,0xa9e871605fb7e6f1L, + 0x14d3c944df67acedL,0xbceea947d0348c22L,0x5331c192d021aba4L } }, + /* 4 << 98 */ + { { 0xa05c751cd1d1b007L,0x016c213b0213e478L,0x9c56e26cf4c98feeL, + 0x6084f8b9e7b3a7c7L,0xa0b042f6decc1646L,0x4a6f3c1afbf3a0bcL }, + { 0x94524c2c51c9f909L,0xf3b3ad403a6d3748L,0x18792d6e7ce1f9f5L, + 0x8ebc2fd7fc0c34faL,0x032a9f41780a1693L,0x34f9801e56a60019L } }, + /* 5 << 98 */ + { { 0x35df68ae1a504405L,0xe41d69508fc755b9L,0x420dc1cda6297243L, + 0x3011646b913fb68fL,0xc4b630465e141a27L,0x943b3b3bbd91fe5fL }, + { 0x3ca17d6b50c31708L,0xce88b5e74ffa8c71L,0x8b60038f4dacd2bcL, + 0xdf654d723c13cf9bL,0xb5353e281d871b40L,0xc2d27919226663d3L } }, + /* 6 << 98 */ + { { 0xa028d2fa9b87715fL,0x7cdd9b4a453625bdL,0xc8afb1890be3dacfL, + 0x40289a3a274c4e2eL,0x7f5f9f7677c6bbadL,0x577c0935bdfeaccaL }, + { 0x5f838f0404281989L,0x8650a974ebfa410dL,0x414fab6dcd56dea6L, + 0x6995cae292eed440L,0x3b474d27ab146e15L,0xe24262b2e9938f84L } }, + /* 7 << 98 */ + { { 0x649e18fba34fb18bL,0xa4883af898cc69d3L,0xff46285f3fd56e37L, + 0x2e28ccc4557c0c04L,0x8388dee821a9b46bL,0x0fd4fb807ba3a6deL }, + { 0x1d8e9da7c62bb315L,0xfa7bd70d06e44230L,0x2840122063320438L, + 0xeefabd47d06c0654L,0xf4387b08d4c8c10fL,0x8f2694624ff2142cL } }, + /* 8 << 98 */ + { { 0xa4b957d262c36887L,0xaf15a485fc24cff8L,0x11575e80a271d9e0L, + 0x0fff68d44b9367e5L,0xf55ba6732279779fL,0x9d72cca6d4d68f68L }, + { 0x01474ab1590ffe4cL,0xd20f44e1074d634bL,0x63903a8336111d25L, + 0x37342a5fab531cefL,0xd3c93fe7702ed867L,0x05d143696279f7e1L } }, + /* 9 << 98 */ + { { 0xcddf64873e942b27L,0x9e29835a2bc21472L,0x924c2bfb2d2195e3L, + 0xdf4a3cd38eca6d9bL,0x7fe6acd1c5be60c3L,0xa3abee9cfc38025fL }, + { 0x014f0d992f449934L,0x8d72657a78860127L,0x92514cb948d84cfcL, + 0x8bd4ac503aadd70cL,0x3c96ee00136620d7L,0xa0caeeb54efc5e57L } }, + /* 10 << 98 */ + { { 0x7a65cdf5bd200ed6L,0x72dc1b5f0e4b1c68L,0x9c09576a6ddf540bL, + 0x358dcd122b169da2L,0x6466f0e81639b734L,0xa1429a6ef14c6eb6L }, + { 0x4b3d781943221168L,0xfe3d2fdaf3b74fceL,0xb22bcec2ae26014bL, + 0xa8900e7ace7e789cL,0x9db9af67220bce88L,0x1f86d2e4fb8ee34dL } }, + /* 11 << 98 */ + { { 0x6f8e1c0bf8c65293L,0x66f44ea04d7a5dfbL,0x2c3cacac741fdc1fL, + 0x72e58aae239f5f16L,0x50dbaf192f72d8c8L,0x24ee526628c97b95L }, + { 0xdb5f7827ab3ecb17L,0x2c567337669b05c5L,0x78c97eb8ff76ccdcL, + 0x1de1b4a3f8d2c990L,0x5b183974e6138df5L,0x61b74177aa1a1019L } }, + /* 12 << 98 */ + { { 0xb398290cf0db3751L,0x01170580ba42c976L,0x3e71aa2956560b89L, + 0x80817aac50e6647bL,0x35c833ada0be42daL,0xfa3c6148f1baba4eL }, + { 0xc57be645cd8f6253L,0x77cee46bc657ad0dL,0x830077310defd908L, + 0x92fe9bce899cba56L,0x48450ec4bceffb5aL,0xe615148df2f5f4bfL } }, + /* 13 << 98 */ + { { 0xcc14267f6be1860dL,0x3de7f48b4ffedea1L,0x8252694e5b776b87L, + 0x478c877890dd427fL,0x913e19a675a21357L,0x882f2d5ac078bd79L }, + { 0xf442752184c565dcL,0xd772147e3ac3ed26L,0xf21abc752fa216b6L, + 0xab1804ad305ff0dfL,0x10d89a07920c977bL,0x0a2240dc4fda6075L } }, + /* 14 << 98 */ + { { 0x7068e6b98653bfadL,0x16b0da9b8f4397e8L,0x77b953b4946bb9c6L, + 0x08366ad749b036f5L,0xd219117b26a3913dL,0xbe3607949a5460d2L }, + { 0x1a4acf6dfadd462eL,0x1f7de879c32f3550L,0x11117132669c9b2eL, + 0x1deea7d1c87ca216L,0xa88c90c748a058d2L,0x0d8e6afff403ef36L } }, + /* 15 << 98 */ + { { 0x21f6c96c1ad77f33L,0xb5da9d34992e7807L,0x17fc994ba7192adfL, + 0x59f204fcbcc3f8b2L,0x3f4a970f10bd22f5L,0x42936bfcbaa1188dL }, + { 0x6239fea5eb985837L,0x5fde15e0b33d1158L,0xe0bbe9b800cf90b2L, + 0xf2c6d8b16b2b68a8L,0x58c331cd0f3a2341L,0xe951c48910dab1a4L } }, + /* 16 << 98 */ + { { 0xdccf68bccbaf4685L,0xb333e464270a2bccL,0xe43ae199254dd3e3L, + 0xe8526e26ddce5c84L,0x52bad815ea0b4258L,0x67c12c1b094574c4L }, + { 0xa5362fcb861545b7L,0x3e904c35c2b2eb62L,0x0f9312b5eeffc2cdL, + 0x5475657b14de4e5bL,0x746e67d4f0233fa5L,0xb5157d7f35471ec2L } }, + /* 17 << 98 */ + { { 0xcbaf92265315e83aL,0xcc6e9a972f15ff37L,0xcac446dde8c87fb1L, + 0x5fa37a5c672d7f92L,0xe66efc07b1380425L,0x2d8ed2e32c8e59ebL }, + { 0x8e3ab80461743725L,0xe59a87f825493349L,0xf6995fe16062fe7eL, + 0x5d7f8a646e8de27cL,0x4a5ecbbbebe084f2L,0x99fc5ea93f863156L } }, + /* 18 << 98 */ + { { 0x1ddede1b495fdc2eL,0x3dfcf56b039d6339L,0x54c423806a56c492L, + 0xe6bfd184def6446fL,0xfaa2fa123ac841beL,0x503e319a4f9330a4L }, + { 0xd9305d4654ad427eL,0x68d23497d95dfcc8L,0x2d935aad1e9602f5L, + 0xd7e74bf2e33174a9L,0xc8e4a0b17225e2b5L,0x5db7187cbcda5221L } }, + /* 19 << 98 */ + { { 0x9a0e0908b0ec0b27L,0x28894b2edd759131L,0x0107bb592b9d6f02L, + 0x318921deeea022f7L,0xa1a00f5882c73390L,0x877833129551b381L }, + { 0xff866039a3a9dd22L,0xa59235ffdf0fc09eL,0x530c2fe61ca647f4L, + 0x77b1ea2860f9428bL,0xeef2a9e6bba4bbabL,0xdbdbe037204f5ea3L } }, + /* 20 << 98 */ + { { 0xf55edabb90b86166L,0x27f7d784075430a2L,0xf53e822b9bf17161L, + 0x4a5b3b93afe808dcL,0x590bbbded7272f55L,0x233d63faeaea79a1L }, + { 0xd7042beafe1eba07L,0xd2b9aea010750d7eL,0xd8d1e69031078aa5L, + 0x9e837f187e37bc8bL,0x9558ff4f85008975L,0x93edb837421fe867L } }, + /* 21 << 98 */ + { { 0xf87a92375b2e5fa6L,0x88571e4452a3a605L,0xf85e9a330c8f5f55L, + 0xf99886c599dc2c97L,0x5866329d065261daL,0x9011f13912dd434cL }, + { 0x0cc67d535284c555L,0xf8f715274a4032caL,0x4b002683a9524bcaL, + 0x3c3c12910f63a7baL,0xd19e173e9124eb8cL,0x3431c51c54b7d85aL } }, + /* 22 << 98 */ + { { 0x7103ab4ae11cc85bL,0x2064ca41789cf87eL,0x592850ead5f13a08L, + 0x56b9ff066212e096L,0xa106455d6efa7445L,0x3e62aac92343c5efL }, + { 0x7edbf70dcb8ddf7dL,0x27f00a4a5f2687e4L,0x7d4ce32e44a08d11L, + 0xe97f0910890a57f1L,0x792597fb912cb027L,0x1fa7a1d2ad3492dfL } }, + /* 23 << 98 */ + { { 0xbf4e161c3cfad317L,0xda4e6bffa1998bc8L,0x6534ef622e890b99L, + 0xd10a3b24d272cc42L,0x3f81b0e5f1194dabL,0x8919caefec549c5cL }, + { 0x847ef47f68f5633dL,0x01cd59975468f4afL,0xc38bce29b6727408L, + 0x56a1cd1ea4c84268L,0x31a493f406b81088L,0x4461ce8531b37e73L } }, + /* 24 << 98 */ + { { 0x3503d9371f23a0d8L,0x64c598a8c321dde0L,0x67f101ef5b52e0f0L, + 0xb6b5b4c2f955b5faL,0xb5f03d53880e0569L,0x121c3ac1c99393efL }, + { 0x90755bd657330666L,0x70ae5793d4d71d3dL,0x326ffd519e9ce792L, + 0x1b772d7396ccfa14L,0x652710f4874a22deL,0x72768469db210342L } }, + /* 25 << 98 */ + { { 0xb2d85722b3413d7fL,0x4e41362092e55ea5L,0xad1a20c7ff7b3409L, + 0x743b31c0c6f98cbeL,0x1b5b0b5adab3810aL,0x628d9b212cea0428L }, + { 0xa3e24294b0335ba0L,0xa9c0e139487530a7L,0x54199640072e70eeL, + 0x0977586e64c0d563L,0x393878451c5cce35L,0x57acd85631ce1eeeL } }, + /* 26 << 98 */ + { { 0x63081bcf9b8d9f3aL,0xb09fe52b6f94e3e9L,0xc232e5d1e39c092bL, + 0xd61ddcccf5f072e4L,0xcdb3b4189a26a93cL,0x0c010c048de6f5c9L }, + { 0xad2473a5d238e823L,0x4120ab3632029ca0L,0xd6632edb639bb8ddL, + 0x3383f077a8b32fe4L,0x8afcbce5eacfbe80L,0xe28236212d2fff74L } }, + /* 27 << 98 */ + { { 0xccf2a24a0eb3829bL,0xdd8fe4421eae0751L,0xb685b073c9598d91L, + 0x025214ce8b308785L,0x11c3fb11d6433acdL,0xe40cf39c81794024L }, + { 0xa167651b1c0b1f54L,0x350cf3eb0bbde983L,0x69c93dd0b2a88c48L, + 0xf13afc37bee80b26L,0x0be7d05d776345e2L,0x1ccbc8ba7645b02bL } }, + /* 28 << 98 */ + { { 0xaa6489df83d55b5aL,0xea092e4986bf27f7L,0x4d8943a95fa2efecL, + 0xc9baae53720e1a8cL,0xc055444b95a4f8a3L,0x93bd01e8a7c1206bL }, + { 0xd97765b6714a27dfL,0xd622d954193f1b16L,0x115cc35af1503b15L, + 0x1dd5359fa9fa21f8L,0x197c32996dfed1f1L,0xdee8b7c9f77f2679L } }, + /* 29 << 98 */ + { { 0x2aa349975442c668L,0x4c5137130cd74444L,0x4f87be0f449300ecL, + 0x13e07b552bae04fdL,0x6aa575d11f75acf6L,0x4502e9e9852848a9L }, + { 0x3c246d38889666fcL,0xb6c0292b7c100867L,0x618f234aa2a280e0L, + 0xf983c834669afe62L,0xc51a15105d900a1fL,0x7d7ce31bc952f419L } }, + /* 30 << 98 */ + { { 0xe3dbb7483c3388dfL,0xc26a7d042c32f139L,0xc1b48180ed938dcdL, + 0x785b964d42e4c01cL,0x507cd16aa1f75e28L,0xfaabff8d1f323caaL }, + { 0xc6bc47ceadd5b649L,0x997dc0ee3c0aed28L,0xcef0c89bf3666cfeL, + 0xd8d7dfb426482ea7L,0x5f00e432d2348484L,0x09549b5a1dc66aa6L } }, + /* 31 << 98 */ + { { 0x702e450ef8464b1eL,0x52d20765a061c4c6L,0xe1c930b26519bfc6L, + 0xa9c0c8c6d17ea02dL,0x52bfc60ddac62461L,0xc325568f7c5f9a55L }, + { 0xe7413df9eb44b9d7L,0x461682265837e0d1L,0xfcb9628c15aa0c89L, + 0x83d6d0eebb57c6a3L,0x17bb82a56829c9fbL,0x342fe91c496861e0L } }, + /* 32 << 98 */ + { { 0x58d6998e171c1439L,0xfd4a98f401feedecL,0x420b2a0165739fceL, + 0x5c5db30822f7a073L,0x016c547805042f00L,0x5fc73ce2a12413d9L }, + { 0x8ceb2d70e932aa17L,0xb4d66b670537afafL,0x2638d012339c146bL, + 0x02fbb7b628ac0555L,0x7fcb0c8162d46e63L,0xeaa9ff4f066d088eL } }, + /* 33 << 98 */ + { { 0x45f53090b8b22c29L,0x155b8f8111e70d5aL,0x5ec118b25d3a7d83L, + 0xfe4c7eb39c4ddd1aL,0x8cdfb753f226d869L,0x20bb870779fc646bL }, + { 0x3c8c1d7a25d1308cL,0x5a976ae47116f347L,0x6af949a60faf9690L, + 0x7e6718fc07f3472fL,0x16ec7b45267b17cbL,0x80744641cebe1bd7L } }, + /* 34 << 98 */ + { { 0x45eded7ab2a5c8e3L,0x4308485969a0681bL,0x89b7510d90910e8bL, + 0x1c622d04d2066d92L,0xdc3b434bcd2f0d7cL,0x98bcb83b476ea5a3L }, + { 0x9195431d3dbf2be5L,0xfec7efd969275ac5L,0x6a4364f556a7da4dL, + 0xaf701bc579c177ccL,0xb77ef33e9ffc2a47L,0x2bc59331cc23c4e4L } }, + /* 35 << 98 */ + { { 0xedf4a85b9d43c51fL,0xc0afbcb6b59a7244L,0x3ede2f25626e0ca8L, + 0x45836582270f674dL,0x83c47048bf06d267L,0xbb1e994f3c68314eL }, + { 0x50d79cb4f2fe6c8fL,0x1a1d8aecdf7600f5L,0x216f5d2bef4e4857L, + 0x41361a90bdffb9e9L,0x8040f5c173d2f9caL,0xe6665f0dd1e9be4dL } }, + /* 36 << 98 */ + { { 0x5405179f394fd855L,0xc9d6e24449fdfb33L,0x70ebcab4bd903393L, + 0x0d3a3899a2c56780L,0x012c7256683d1a0aL,0xc688fc8880a48f3bL }, + { 0x180957546f7df527L,0x9e339b4b71315d16L,0x90560c28a956bb12L, + 0x2becea60d42eee8dL,0x82aeb9a750632653L,0xed34353edfa5cd6aL } }, + /* 37 << 98 */ + { { 0xb112fd7b36386e2dL,0x358e974a6a634bd7L,0x509814737faf640aL, + 0x1036bdacef39b3aeL,0x410c6448db5aceb0L,0x914671305bbebe92L }, + { 0x83fabd54e9e009e4L,0xb2da8eea9994d16cL,0x9d73da6356997acdL, + 0xea9158b97ec1b844L,0x8e6a6e3129714795L,0x23e98f57131243f9L } }, + /* 38 << 98 */ + { { 0x7105f727552664dcL,0x97cbfb6c5c589c8cL,0x1a7b110a70fc59b3L, + 0x46c39f2cc754c69dL,0xcda0e2c067b1f17cL,0x35fe45fab7ede210L }, + { 0x6b3ecb7d82e78b40L,0xa90eed4fdbc07241L,0xa73797895aacd533L, + 0x28120ba5f4fa89a2L,0x9c1fc09ee3055006L,0x71e665efc51653a4L } }, + /* 39 << 98 */ + { { 0xcf782247d28b5059L,0x15bef4cb1b89eb06L,0xbc182ed6bcb4afeaL, + 0xcf5b6dfde0e32b77L,0xeb61aff9d9446052L,0x5846f171c4bfc0abL }, + { 0x61d5ae1c6fc68422L,0xa282c56846e870afL,0xdb4859d16bca8fbdL, + 0xd4cd416e97caf135L,0x11217fa9c3debd59L,0x27702da6370758ddL } }, + /* 40 << 98 */ + { { 0x8273db992d189057L,0x4d1b05fce1b5f8ccL,0x5fec7c830a7c32d1L, + 0x28ddaf28ea9b4d45L,0xb6bb62aca2fc58beL,0xfc65b7aa4a41852dL }, + { 0x6e7651941c9e6045L,0x3acabf28fc116257L,0xc9d5e8054b5a4ba8L, + 0x9a072259cbdcf1ebL,0xc67cf643439fc8fcL,0x917ef6f8b4333aa8L } }, + /* 41 << 98 */ + { { 0xee6123cca6411227L,0x91372d080ee882bcL,0x2c30a840a638a4faL, + 0x1867421321e83d4fL,0xc6afa4cfc3fb9925L,0x19aec276e4fdc73fL }, + { 0x1ffec4510cf4e610L,0xac57292ede22d429L,0x62844d78e6cacbc1L, + 0x0eafcc554d2e497cL,0x39f1acc8e780f600L,0xfcf8d914fcff8c6aL } }, + /* 42 << 98 */ + { { 0x0734ab43ff2152d0L,0xe52c5dee930fea54L,0x9cac7efe940bddbfL, + 0x30d2610ddbd43391L,0x4beeb865921c124dL,0xa19fe6a4fca219fcL }, + { 0x588395628755cc47L,0xa7f301241324f2d1L,0x4fe38ee3b1ec5aacL, + 0x3583542eb16413ceL,0xfa92e2191733b7eeL,0xc0f30ba32b2001a4L } }, + /* 43 << 98 */ + { { 0x706b02c3febc7968L,0x6e45dc90c96a6b64L,0x34e5f890f95aa4c7L, + 0x8ae64d487683b855L,0x0fbb9c4a62e03ebaL,0xb32a965ce2cab115L }, + { 0x4a7084a8b33102b4L,0xe7fd9db3ebd1bd6aL,0x2fcb233cc7f32b61L, + 0x365896d5f2549734L,0xa3f18bfd25c7a1c4L,0x382950ef212b8daeL } }, + /* 44 << 98 */ + { { 0x82154d2c91aecce4L,0x312c60705041887fL,0xecf589f3fb9fbd71L, + 0x67660a7db524bde4L,0xe99b029d724acf23L,0xdf06e4af6d1cd891L }, + { 0x07806cb580ee304dL,0x0c70bb9f7443a8f8L,0x01ec341408b0830aL, + 0xfd7b63c35a81510bL,0xe90a0a39453b5f93L,0xab700f8f9bc71725L } }, + /* 45 << 98 */ + { { 0xee2b773e4ed17990L,0x499e83623faab7feL,0xa3925e2f71abb9efL, + 0xfee50406ce3b4a69L,0x71a15070bc10f803L,0x5b01e4a2c7bab10aL }, + { 0x806c590d99e51e36L,0x34adbaf6a7f88d5aL,0xd4a93ce9f6b30ac3L, + 0x39d2cf40dc33fdfbL,0x13e676f1d5e4e7ddL,0xbaa72ab9199690fbL } }, + /* 46 << 98 */ + { { 0x85017690e51b47daL,0x25919b58a2b476ceL,0x6f692de103ec5d55L, + 0xd6cf8ee5d022dcebL,0xaf3225238ba7076eL,0x917b373728c902d5L }, + { 0xac75fddc3fdf8590L,0xe83d9bbb64fc304cL,0x13550de2971f659aL, + 0x70bee07ee12b7bebL,0x9989d2fa0a855646L,0x8b6043aca576b3a1L } }, + /* 47 << 98 */ + { { 0x1bfd4f92fadf9017L,0x1e4509aa737bc67cL,0x88278c3699af1ffaL, + 0xbc47536f4678e22bL,0x69914cdb1b07c823L,0x56fc28ab97277358L }, + { 0x092d28efe752d2f7L,0x6a8286a691da62c5L,0x86b702778033c632L, + 0x57ef284e7672f41fL,0x9101ed302e54007bL,0x53e94cfed25d8d19L } }, + /* 48 << 98 */ + { { 0x311ebba2fc37efedL,0x8a6a42d660cfd6bcL,0xb4051b3af2a4871eL, + 0x66ce77b8c2f0ebf0L,0x84abc9480ad28477L,0xc82e5c6263d9d11aL }, + { 0x99ffc70c007dcf93L,0x5e974edfd964c822L,0x0fee3572513085e3L, + 0xbe67a88046ce8444L,0x136ceeb806d17129L,0x0da512ae662d86fdL } }, + /* 49 << 98 */ + { { 0xeae827d989e687ddL,0xb025f0723bdbdd9dL,0xfbddcecec3a575aaL, + 0x3fab33c1f80d12cbL,0xd0232142b32f0381L,0xf00e74bd3b6c3132L }, + { 0xb7c1311e0e44deffL,0xf3d790ae29b04d6bL,0x3d3744b846f72957L, + 0xc0890fb6ab2f13e6L,0xa669a34324461f0cL,0x35c9677ddd72fcb7L } }, + /* 50 << 98 */ + { { 0xc257ed518060a28fL,0x3a9d7e1cc72fafebL,0xa304a5e8332f435aL, + 0x96969bc234ccf343L,0x2aae4d8e7702ba84L,0x37f15631f203a7eaL }, + { 0xc0000f24c9666405L,0xa98eb834a537fb89L,0x8c0564cf7e36dd1aL, + 0xb5ca507b4e89615cL,0x9bfa209a9d80ef92L,0xe2ec1879a83f02e8L } }, + /* 51 << 98 */ + { { 0x73b4573c11dfdea9L,0xe5f208ee5c8cc81fL,0x5c240d3c769adf12L, + 0xbd3f8f33550c53acL,0x98171d16bb4f43acL,0xaf19d5fe84db9e13L }, + { 0xc589be0d2e53345eL,0x3184b540f114f6f3L,0xa35ed77e4946090fL, + 0x427b860afd3108fcL,0x7d0848c3867df76bL,0x353539e2a32ec485L } }, + /* 52 << 98 */ + { { 0x9401aec2b9f00793L,0x064ec4f4b997f0bfL,0xdc0cc1fd849240c8L, + 0x39a75f37b6e92d72L,0xaa43ca5d0224a4abL,0x9c4d632554614c47L }, + { 0x1767366fc6709da3L,0xa6b482d123479232L,0x54dc6ddc84d63e85L, + 0x0accb5adc99d3b9eL,0x211716bbe8aa3abfL,0xd0fe25ad69ec6406L } }, + /* 53 << 98 */ + { { 0xee174af2df740edcL,0x1bd8382c09233f0aL,0x34a7450e7d343006L, + 0x92259ddd3d463e61L,0xcd0bfe6fedbc3af2L,0x39627c4cfc8770f4L }, + { 0x7b7c688ddbabdf2bL,0xf459f0e64bef3558L,0xfa0e87becc88f7c8L, + 0x67beabac5fcc80feL,0xbdae52bfadeba16fL,0x4751724c5af5c9bbL } }, + /* 54 << 98 */ + { { 0x5627e0d016332364L,0x33839376fc57f01bL,0xe7fc2c489528e434L, + 0xa0ee39acb52b3757L,0xe49e383ee42e4832L,0xabfefdbb31359afbL }, + { 0x5dedb6f3b99ee196L,0x38abe58bc16aac17L,0xa300a1333ec06a07L, + 0x00e68eadc90d4659L,0x60412e8a8000a773L,0x6099b6a6a5830c94L } }, + /* 55 << 98 */ + { { 0x85364bd10d340c80L,0x14b89462be64bc9fL,0x16429134b542faa0L, + 0x0d4cf3ce73683e2bL,0xf9a3e443cb73ab7bL,0xa4c2d0afbb156b0dL }, + { 0x826123921bc77675L,0xaf2aad4a5f26c238L,0x6f6f5d9aef4656bdL, + 0x0e20425f90901f3eL,0x0e30bfef9943a673L,0x6cefc62847415a28L } }, + /* 56 << 98 */ + { { 0xe7acaa8457e0105dL,0x3c06d3bd3851fd57L,0x23cf3c612a9c631bL, + 0x13888aaa33863bf8L,0xf2396355717783eeL,0xf21e1a4836b300e1L }, + { 0xa734cb3b9d27b4cbL,0x0a7effed796e34b6L,0xfc5864773615cc7aL, + 0x1f98ed7788844a21L,0xd6e289407ad4c7bdL,0xa00d64ebe9331c7eL } }, + /* 57 << 98 */ + { { 0xcc6ce7dee1c1e159L,0x77982e4f03df6b56L,0xbd8307d1b82b5ebfL, + 0x43e25358ed881b82L,0xddba4f418e0eb034L,0xbe326c36f919800cL }, + { 0x97d03da7af52dfaeL,0x153bb17af4bf81c5L,0x29bbb9bed7ff322cL, + 0x7a7bd8c7232cca47L,0x7474c199c2830f03L,0x9f464a06f0065fc4L } }, + /* 58 << 98 */ + { { 0xca505cb553b876bfL,0x6fc27f553662cb5fL,0x891cbef432cb1636L, + 0x339743f16e27e2d9L,0xde76538f21dc4837L,0x9cea05020efe241cL }, + { 0x97b8deb65888d9acL,0x4d3c28cba4b6cc56L,0x88ca828f840910b3L, + 0x2e5727cfbfde6793L,0x05a4138302bbae6cL,0x2e72fd653fa8e23bL } }, + /* 59 << 98 */ + { { 0x5b88c5ae6d17fe02L,0xc9b14810d6dbe104L,0x170b8659873be863L, + 0xdc5946a6ae9111b4L,0x4cfa5f022819a4cdL,0x7653d06ae213bb7dL }, + { 0x324c41baabd7ee74L,0x4219968cdd1608f1L,0xa5e104704adc1561L, + 0x964a53ea5e16d818L,0x00ebd1d4980f4bd2L,0x23cbb80d3518144dL } }, + /* 60 << 98 */ + { { 0x0d5c1769df85c705L,0x7086c93da409dcd1L,0x9710839d0e8d75d8L, + 0x17b7db75ebdd4177L,0xaf69eb58f649a809L,0x6ef19ea28a84e220L }, + { 0x36eb5c6665c278b2L,0xd2a1512881ea9d65L,0x4fcba840769300adL, + 0xc2052ccdc8e536e5L,0x9caee014ac263b8fL,0x56f7ed7af9239663L } }, + /* 61 << 98 */ + { { 0xe6ece4b5dae76820L,0xd428354e95feec03L,0x43517722f8871f7bL, + 0x313fde11e84d0b7cL,0x7f02824b1cae0a45L,0xf9f560c1d6646bc4L }, + { 0x124d88bc903a0608L,0x950e8320370c7ff2L,0x29e6da714090a72dL, + 0xbc5a108c54547d89L,0x809330cd3e484deaL,0x1b04a8088bb00f0cL } }, + /* 62 << 98 */ + { { 0x2425c59c03e0a528L,0x49de96f425c2be3aL,0x30b52686fff4b610L, + 0x2ce573b0f2e5f7b1L,0x4ec05f07b606f0e6L,0xf2040886366ecbf4L }, + { 0xc7fd993460d404d3L,0x8a064992fc12227dL,0x9c6d64ec215492b1L, + 0x2793bd0903463ec1L,0x49523ebab7376e80L,0xb138dfbd35b14fd6L } }, + /* 63 << 98 */ + { { 0x5ed097b0df7363adL,0x21319edba5696d91L,0x17c46519c5d5313dL, + 0x341d46576c6cccedL,0x60d80713692bc704L,0x9477b6e907fb8e13L }, + { 0x2965720b532e0c6dL,0x2767b4ee87831d79L,0x3e2e67abd4b5ef14L, + 0x45ee89b5d2598521L,0xfc8f1e3ee6441648L,0x75c4db57567ed090L } }, + /* 64 << 98 */ + { { 0x17e3d0b8713b8541L,0xf372b048c6b5e839L,0xf8ef0261d0bb1848L, + 0x9b804ceec71a3bbeL,0x00b7d171542a88aeL,0xf2b8ed10e9097b9eL }, + { 0xdbad9f122c0a009aL,0x245fc1e9205fb1bfL,0xa8a4834fb83debf5L, + 0xc3ee226d637e449bL,0xe3070d93cab82664L,0x24b8094db37320e8L } }, + /* 0 << 105 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 105 */ + { { 0xb506b7b925059699L,0x349fd83f01ab02e5L,0x64b729ad3789281eL, + 0x69ae8f81f9af4561L,0x007befe156f91860L,0xb578c566edc250fbL }, + { 0x1c16d75a67ae4801L,0x04c35a7ea1d3f592L,0x5dc97da936881f89L, + 0xaddb603103a5b1eaL,0x7eb515b13e153a0fL,0xdc3a92192b4a1ee2L } }, + /* 2 << 105 */ + { { 0xe7365f9e512cc92aL,0x9efdcf8b5172a654L,0xbfb389ac8e611fc3L, + 0xce778fd5699c227dL,0xdc1f47b63ff2ef17L,0x2ae0f68302672ed4L }, + { 0x51c63806a8e879cbL,0xd3dfecf03909f526L,0x375b3d13e00e12a2L, + 0x91f9f750bf8df325L,0xf1ea0e421df5f21aL,0xaed73e7f32c60584L } }, + /* 3 << 105 */ + { { 0x03b07fb5e0728e6dL,0x9e0469201012234eL,0x272e644935637644L, + 0x2b6ad1c2a55bcadfL,0x86c527765c71c6afL,0xa25bd60bc1678806L }, + { 0x0cae829476bb32f8L,0x389ce4e633e03cb2L,0x504df8337513dfb6L, + 0x4260ee8e1b351ddaL,0xa473c5d9dbaf7cd0L,0x22cb7cb471e390fdL } }, + /* 4 << 105 */ + { { 0x1d9aa9fa26caebd8L,0x6b64686926b7a673L,0x7ebed6a17f167b47L, + 0x324c13f85bd9153dL,0xe9ea5b734c682ba6L,0x2961da7d7e3ff6e2L }, + { 0x1ed2b05001a83dadL,0xb232951dc4a2f60aL,0xafcea5d3d68b8ec6L, + 0x21dc058d1c6ce0d2L,0x0043de75e719410cL,0x4edd792ce15cf534L } }, + /* 5 << 105 */ + { { 0x0f45245f3babe09eL,0x0959326fa9f2fac5L,0x7629e7fb5cc136e5L, + 0x208bd5a6e48b7eb0L,0x637891d6b75a85cbL,0xf0ad9d8d9f27b57eL }, + { 0x437b6944e0454b05L,0x022c51d702ed3592L,0x0f79e2bd0dc0a769L, + 0x54ace1fdd9b81f9bL,0x38611d66f95ea8dcL,0x52443ca8f0e6147bL } }, + /* 6 << 105 */ + { { 0x857d68558bc272d0L,0x4583eeeeb5be2485L,0xb83586dafe0152ecL, + 0x8b0eb223e830294aL,0x757582b6a5b0e880L,0x5140c0169cca7fffL }, + { 0x07a00782e9228f12L,0xb96e2b5dd4973080L,0x3cceb9a6e88efbe6L, + 0x9955b63073fcdd25L,0x04f26ab02805d470L,0x90b38299424da086L } }, + /* 7 << 105 */ + { { 0x73f1ae48f4f6c5b4L,0xee5af13d4a477f01L,0x274614a2ddb93d52L, + 0x90b0c563c320aaf5L,0xee2303c8ef990b0bL,0x00d028e73061f140L }, + { 0xff705011cb3d8eafL,0xae1d990862594f4cL,0x22a27cecdafea438L, + 0xa78e12d5c5962ea9L,0x5bbe9d878e65f9cfL,0xa222580cf47cefa6L } }, + /* 8 << 105 */ + { { 0xf7aaa732959abb9eL,0x1222ad0a2ebf80b9L,0xa1a417372e0c286eL, + 0x3b6685025da3472dL,0xbc0d116b7576f2a2L,0xfdbcad95a36a27d4L }, + { 0xcdb3f4749d54f7eeL,0xe2e0f5f98a5643a3L,0xc70d11b969d4f171L, + 0xdf96d1366cca4ef7L,0x570693db2fc6afdfL,0x5059e67b567504daL } }, + /* 9 << 105 */ + { { 0x2c8107d47fe632a2L,0xfc46c745ede7bff8L,0x2d3b12864650025bL, + 0x815ef3cbe74cd65fL,0x5431b01ba256f01cL,0xe832ff1139915cfaL }, + { 0x2c106de607d7af84L,0x67303b786d4753e7L,0x5f886ffa6d75c8deL, + 0x932a6c20967131cfL,0x5bc94a9170aebbb0L,0xa85b3044fd56e06dL } }, + /* 10 << 105 */ + { { 0xc904558ae7eba799L,0x46b6031bb2fa7331L,0x6620e2b50653675cL, + 0xd1373a357d2218f7L,0x0f4b3ca3af55a5e7L,0x50774160714e70c2L }, + { 0xacc63d1469188455L,0x89a795fe043b8b30L,0xac2fd66ce1e4b9cfL, + 0xac7927021bf67f26L,0xb9513f0d1143d437L,0x02198050811f2931L } }, + /* 11 << 105 */ + { { 0x6d4acdba7b480776L,0x8b518cd466dffeb5L,0x8826c99451918859L, + 0xd2b6a7a038fad835L,0xd315417a6929a870L,0x05d85252c5a769e1L }, + { 0x2fa06335ec0d091eL,0xb0cc337287768c88L,0xacbda5ba58a2eb9dL, + 0x2a404fc976b7b057L,0x073abb71838c6135L,0xbdf89b135cfc4f3cL } }, + /* 12 << 105 */ + { { 0xd00eb9c53508675fL,0x92ec76a4a117dc95L,0xf58d6f85334ca15cL, + 0xeeb522169cee0544L,0x3eb9847ff21457c2L,0x547908bc5524c60dL }, + { 0xb5b49d225198709bL,0x718abce6324abc67L,0xdab8ff2f4abd54baL, + 0x98be59e67184d444L,0x45b74b54babeb4b0L,0xd8d8bb30ff71a5acL } }, + /* 13 << 105 */ + { { 0x8aedf7e28ec13e6fL,0x8b952620d950792dL,0x36e9dac204918f59L, + 0x5e49a5a2d3dd47edL,0xb17455bee863c2bdL,0x8caac6a9326a0d66L }, + { 0xb6c3f5e427bb72e1L,0x17566c9dee5fe09bL,0xfd6bbcc25e3db64dL, + 0xd437d07a3189319cL,0xad00dfc4cd3166a5L,0xab75927b0bd63003L } }, + /* 14 << 105 */ + { { 0xa7672a39afc43be8L,0xefc49015c72f97aaL,0x81c63c050e48f2edL, + 0x62f39f32833a22ccL,0xf7a3480172c0c0c4L,0x4711cd41a4158538L }, + { 0xa3c99a4d1d15f2f3L,0x4b82c1c17bee1b47L,0xc7d60b489d199f10L, + 0xd1d1f03d5f16fa95L,0x96c780c932fbeaf2L,0x0662e250376ff106L } }, + /* 15 << 105 */ + { { 0x728e334678571c8fL,0xd0a886b56cb339d3L,0xf4ea33380a5671baL, + 0x43823401a64850a4L,0xa7729cd533117b9dL,0x4dd457602b78cffbL }, + { 0xbe0571115a67d812L,0x7ec6cf925105a3fcL,0x5dbcb4bc0ccafeecL, + 0xa7587f15803092f8L,0x67ee61d5a884efadL,0xd4ced554ca47d9caL } }, + /* 16 << 105 */ + { { 0x02c6b6083b03dcbcL,0x2b20149e3b9d868aL,0xaf5ab01d4f57eb0cL, + 0x59935b94d750e515L,0x32721b408f89ad68L,0x673bd755a7e3ceffL }, + { 0xbd462fd8ef3b3393L,0x991422640e59a120L,0x4162da619263fa61L, + 0x2ed1f2deb6488eb3L,0xb0bd37a8725680c4L,0x17218bf029ec27b0L } }, + /* 17 << 105 */ + { { 0x444071ff84ff1ebcL,0x4b4171e87f789cbdL,0x4a832cca2db4e8daL, + 0xe229ffb6dc209c05L,0x9efbfd7eb5f0b3f4L,0x65e07fe774fbbe6bL }, + { 0x2892c8ac627b9d41L,0x01a20eb94297e7a9L,0x2f54e88646f29860L, + 0xc425accc188798ecL,0x6137251c85c80580L,0x6cc0f9c4f386581eL } }, + /* 18 << 105 */ + { { 0xf677bdd11cb61a7bL,0xfca1faf8932d6113L,0x1d5bbf97a531bbe2L, + 0x3d5e4860c849fc47L,0x388943cd95fe4da2L,0xffb7d5e073add43fL }, + { 0xc3166ae828fcc058L,0x89dc7faae0d6f6e4L,0xe6daf1a6f527ca01L, + 0x500a703a56ef1d8dL,0x3573d0a3fc914df4L,0xd780e745ef8dc2a4L } }, + /* 19 << 105 */ + { { 0x90a8f3380500afbcL,0x8c303270838ccf6fL,0x82cbdc98458254c6L, + 0xc2f24d03b367ddbcL,0x5d3daa0d6c882354L,0x824d313d376599d0L }, + { 0x6e5075df7b9dd1b6L,0x6871a3d4d69c9828L,0x8b3762f59cffa148L, + 0xf2184f67eef8c656L,0x437630c296a1537eL,0x92a0667c4cbf8249L } }, + /* 20 << 105 */ + { { 0x6e929912ef619478L,0xe7ddaf255ffc5939L,0xb71133cf96dbbca5L, + 0xee8bd53f17da5104L,0x7601ce6adc49be68L,0xa1ca3b3cc63f2a87L }, + { 0xebf388c2a0de1668L,0xa0f6c38dd0ec6bd7L,0xc8e0875ddac451ddL, + 0x179fbbe5a5afce85L,0x0727095673bfb06bL,0x992afcd047622925L } }, + /* 21 << 105 */ + { { 0xe3b0122624f262c3L,0xaa7a0925dae30b22L,0x36104c95a96a18f9L, + 0xdc6090f5539b6740L,0xd70270ba11040a88L,0x53997b57ea3342feL }, + { 0xaaf1d47d63393e4fL,0x9db8aa3fe8a99625L,0xed571a32c3926e1cL, + 0xd6e898526e565346L,0xb3984bbd873b2589L,0xaeb7bf3f3f5f68e1L } }, + /* 22 << 105 */ + { { 0x75a4a19a79ded4a8L,0x1368e269f688177dL,0xa24d67118581e23aL, + 0xae63d5a6746b3830L,0x0c68d3e314017304L,0x521a5e7de4d45dc9L }, + { 0x69d9adfaf77ca616L,0x1f8d37f4bfda67f3L,0xa2833ba1027e771dL, + 0xae49b00367141a63L,0x04e6f282ed6f1968L,0x65d7d88f060f9157L } }, + /* 23 << 105 */ + { { 0x5dc3137b512e4026L,0x43e189595d6ac980L,0xdb7dfef39eac06a4L, + 0xa8f3e2aea09b0650L,0x80a8594c575e047aL,0x9eba41bcf0c58bf3L }, + { 0xdc04cc7679812341L,0x716050eaeed1be66L,0xe559782099b77be8L, + 0xe543aef055183ad5L,0xbbddfb814c08a959L,0x6e54d86eb5368e8bL } }, + /* 24 << 105 */ + { { 0x170f8a74e7aba263L,0x6b4e1d7b986b151aL,0x5f65bd224b08921aL, + 0x1017ae3de6caca3aL,0x613f36b626cb9d5bL,0x8a1e2f2ded19d99bL }, + { 0x52c915a5c3c519c2L,0x3c9a33305902fa08L,0x2cd7f7c206a51a12L, + 0xfed60db66e0197ceL,0x4e5b2bb7d971b04cL,0xebebeebf2f45ab13L } }, + /* 25 << 105 */ + { { 0x43b10a0673220e06L,0xdf93af67777cf022L,0x830195efbeea9ed4L, + 0x0a36b71812353c9bL,0x520e2e8d1ec8c488L,0xdc985ffaadac5e16L }, + { 0x0ebac566f3f58ed7L,0xc7747562a2cd13a2L,0x6a5b4cbce3901864L, + 0x66634acaa374b634L,0x45e000877f4680dcL,0xb783d01f9fdbe92aL } }, + /* 26 << 105 */ + { { 0xcf6d51be36e1c05bL,0xf59b6665e1da0ad8L,0xaa8bfb9d727a701bL, + 0xb1680942e26e268bL,0x09d41407e518661bL,0x8b0dfbfb3757a993L }, + { 0x34ecb09f6cb33380L,0xfcd77efede342bf6L,0x9f8fa6c6e476c5eaL, + 0xde30410fb6257416L,0x416ea101bbd47b91L,0x86ebd19e4aeede80L } }, + /* 27 << 105 */ + { { 0xfe7562e00818226bL,0x922d8fe662b46275L,0x6216698b491adc2eL, + 0x5bdf7a59f6a38f2eL,0xc0640bf937710dfcL,0x06ad30a9df687f48L }, + { 0xc561dc7d3eb66e6dL,0x7444ac83d08616c3L,0xebfcccee84984618L, + 0x35a03bafbb15eb51L,0x7c907f9fc17a5de2L,0x2e48ddb5814634dfL } }, + /* 28 << 105 */ + { { 0xe466d7a7ea51a37aL,0x5203e990cdf97186L,0xf700953096c84ba0L, + 0x4e32fbe65f89d1adL,0xe530349aa9be221eL,0x0f7f9c2e50b31508L }, + { 0xa6796f5c3af5a574L,0xe220f6daa2a2df89L,0x99ec4811d8b65510L, + 0x4dfdac69ed373b27L,0x663f46b1bb55114cL,0x44236350d167e032L } }, + /* 29 << 105 */ + { { 0x1382e90ba65f6a57L,0x3557ab88e5c903e1L,0xcc0cc77f032067beL, + 0xdd8da09f67797328L,0xeb2979d45114c09bL,0xaaca95bcc4eb598eL }, + { 0x651a7ce5a2b776fbL,0xc20fe9315312ffc1L,0x842957357dcf479fL, + 0x022ba6e2ee5cc0a7L,0x6d27e37185b0ba5cL,0xe6f212bdbcd5f2c1L } }, + /* 30 << 105 */ + { { 0xb0c2ce87a9088f95L,0x47ec07e0acb11d2fL,0xfe84fba0d30ad231L, + 0xaa98e35f18a08eb1L,0x36adc3f2f6a27510L,0x622d202751fac4fcL }, + { 0x4be765cabb9b6ffcL,0x934193571cbfcbeaL,0x83542d9cbef14402L, + 0xf27504954612b4b4L,0x91aff597bb988ba6L,0x229031e51d61f6f9L } }, + /* 31 << 105 */ + { { 0x6b04a446ea29e65cL,0x9b6247a696c48a99L,0x95aa162f60c83930L, + 0xe387f544e30821eaL,0xbe1cdab306c51b7eL,0x40175d151fc7b8f8L }, + { 0x89df5ff36384d331L,0x02eb9aa4fe1aaf5eL,0xf24155f789675704L, + 0xbd2e8cdd87f72f4cL,0x2856b3c46de30f01L,0x2356f0a3ecf8af25L } }, + /* 32 << 105 */ + { { 0xfb09e7564bd044efL,0xdbc9fcdfbb964fb3L,0x451c5b01cdb1f4f5L, + 0xb02f9068f1dd1cf0L,0xd4765e7c0c687e41L,0x89b64981d1967bd3L }, + { 0x06a0e4ecf0439d65L,0x564c387da5abbcecL,0xc1e9d01ac651d806L, + 0x5e6ebd830618a96cL,0x9ce1aacec54ad8ceL,0xe5248a089953f90fL } }, + /* 33 << 105 */ + { { 0xd65f3b909b6ab239L,0xbc259a6d9ea8bf80L,0xc10d5c235944f964L, + 0xbd6b3f6f61eeac6fL,0xc4ef2d8383e92858L,0xb80d5ab0a3736bfeL }, + { 0x27bebd1176695c40L,0x4de92348ea4f5720L,0xd70d93e6070b892aL, + 0xfce03d0be626d5abL,0x2525e8ea81014bedL,0x6fa3df16a70e2799L } }, + /* 34 << 105 */ + { { 0x42b8350a7bbc41caL,0xd7861ad49af59bc9L,0x2453d07c5644d328L, + 0x2b92643ad7c8ec43L,0x7c14d3c7cd5f1fd2L,0xcee050463d373c7fL }, + { 0x17ff60bd0ab2b35bL,0x473925e0dbb7f655L,0xdbaa015aff3ee023L, + 0xbc1ff6d6087ecfbfL,0xc44e1c8c5fc66ca2L,0xc60a193850d6b257L } }, + /* 35 << 105 */ + { { 0x5ff44f3ed8f0983cL,0x9de50da0bb82cc15L,0x504f82ec94757c44L, + 0x72a4fc9dc8a07028L,0xd4d6e4cec3d5e64cL,0xc6148fe780008568L }, + { 0x71ba3fc525ef66d6L,0x969cc8694f6589f6L,0x5016c8c2d934ab25L, + 0xa78382f6959e8881L,0x28bcb8bea20eee18L,0x055ba80b37edd7c8L } }, + /* 36 << 105 */ + { { 0xbe389fef9c98ca3cL,0xdc3ab23b910370e5L,0x866cb37d5e8eb20dL, + 0x2f951ca9c1e32fc8L,0x54ef6ab15fe24e6cL,0x6038b5efcfcb8cfbL }, + { 0x362e076b6eec196dL,0x47bb3aefd398b505L,0x9f3128eb343711ccL, + 0x8dda2fa8d28e3269L,0x908c52c7eda48846L,0x65fb3a05d53b0917L } }, + /* 37 << 105 */ + { { 0xeae35c02ed711239L,0x16ab943fa97db2d7L,0x9770bb578f3b0599L, + 0xa88ffb95956d04f3L,0x3b937af5f4dcf6ffL,0x311ef2cc0bc41f56L }, + { 0x00e9214a2860ea2aL,0x2a64b18a7bd12d8fL,0x20a5b9da6a2b9dbcL, + 0x5c16a412fe1b8edaL,0x6fc306af7b9db98bL,0x964c35de25dc9363L } }, + /* 38 << 105 */ + { { 0x81f4739e6df16589L,0x2ea2fff11f8b8ac4L,0x3baff03d33e02c36L, + 0x7f07526874d77660L,0xa442d7fa758eed7dL,0x584cbe9866625864L }, + { 0xeed35d579d167ff6L,0x56627c2e3c7bf84fL,0x908df5aedd011153L, + 0x2694e54d242fc055L,0x25beed9a2f2d60c3L,0x29d3f22fe2ee5293L } }, + /* 39 << 105 */ + { { 0x14940dbc178f9859L,0x6e6e35b7329ec4a2L,0xd1f198096707db4aL, + 0x6eb310b79fe4233aL,0x8f92556eb41e1d8cL,0x2ab28e231d7ce522L }, + { 0xc5d0f5dfdd5c4d68L,0x3f5146d825101083L,0x3a04aa53de9ee4cfL, + 0xcf36f1e3d9357f64L,0x05a1896444889f68L,0x1096c87aa96a4137L } }, + /* 40 << 105 */ + { { 0xfa4b6697a8352657L,0xf5696452cad6ec30L,0x10aaba60986c84ffL, + 0x49bdfff4dae014e1L,0xe2a810bd0abc0e46L,0x1dc5b81462d1dd5fL }, + { 0x15d2f2c723bb4561L,0x5ac7b6421818e30cL,0x40c6b6f94c545f5bL, + 0x5875b6b2f99241e8L,0xfa3e88a9d6708293L,0x1c936920ad6d9344L } }, + /* 41 << 105 */ + { { 0x6516f6210e18ec42L,0xb967eb43df8c26bdL,0x624ee27e69addc2aL, + 0x34019d6339063252L,0xb317fdd3dcd99d7aL,0xc3d566825d314caaL }, + { 0x04992df3367506b8L,0x13e4ab2e547262b7L,0x35f130352e287d3eL, + 0x92e0a276211304d9L,0x94e7129417133d22L,0xb35302275fd71a28L } }, + /* 42 << 105 */ + { { 0xe1d9273c9ae60111L,0xe86aeac3d01243ecL,0xc7257b27fa5989f5L, + 0x57737dc89807d3ccL,0xe1ef78526937551aL,0x74ab9edb15dd2d58L }, + { 0xbc47b23cc59962fbL,0x376ff30fd3bba76dL,0xaf0035872788ab98L, + 0x1e475c68619b472cL,0xd79984c89c6a9835L,0x5ceafba510219a94L } }, + /* 43 << 105 */ + { { 0xc25ae81155d238d9L,0xf2a21fce4ba4456fL,0x4ebe44d0bd1a440cL, + 0xe821687f83d958beL,0xb4ce63423ba09f9dL,0xf271435d139048bcL }, + { 0x2a3db37c99c6412eL,0x50cba09ccb36dbd0L,0x9e5231aef6e65cf8L, + 0x48e9105d90118a6bL,0x2d58d372368144cbL,0x48702d59928575baL } }, + /* 44 << 105 */ + { { 0xc71ce040d1c9204cL,0x8ad09d7373f7686eL,0xbcc6d88dc6fcf31dL, + 0x22a0b71aaf428ad3L,0x7767944847721255L,0x2b720c7e316b808fL }, + { 0x3128a7cc5ed45b8bL,0x9744c6c0f79fa1c7L,0x738e94efd22728d7L, + 0x8a652496fff8f874L,0x0e4a5ade566c9751L,0xfcde62db64e3199bL } }, + /* 45 << 105 */ + { { 0xb068ec91aa63f5fcL,0x547e7e471a29ddfbL,0xe3e5de42b17b8e5dL, + 0xb5c84f27264d1361L,0xa68d10a426432715L,0x4f31e81c23e48e1dL }, + { 0xe32bea6116dbe185L,0xfaeab7256d1d34feL,0x0ee437cef3a8ca7bL, + 0x2b8657a2f458446bL,0x8779a3d4c52e3dcaL,0x243d7d0e71654165L } }, + /* 46 << 105 */ + { { 0xc4a346b2de23afe2L,0xf8e00f790fac7ba4L,0x22393604ab76b7d8L, + 0x109233d7a06efba8L,0x5bf89334c7bf56a4L,0x27ed4a28135d4cabL }, + { 0x07851ad2e32ca02fL,0x41b7ffa630c97f29L,0x383b3716e4457ccdL, + 0x6ce8645b0b43a50fL,0x73c82018fc5b907bL,0x79a1467381bbcf0dL } }, + /* 47 << 105 */ + { { 0xcf5331d35e092e41L,0x7e0b9fdeb43e3c15L,0x842a971182841f82L, + 0x2d837c810cb9d1ecL,0x6aff6d6873095ddeL,0x2a7f6f40c9478ef3L }, + { 0xb6e8ac80a9976e39L,0x3853fa5474e40024L,0x664b159a6d87c1d9L, + 0xaaedf4b4b20b5d11L,0x8a1ac277c5819de1L,0xf10276dc6450b97eL } }, + /* 48 << 105 */ + { { 0xa8d7901c7c16c09bL,0x628ff3be42e1948bL,0xb905d7c504e4bce1L, + 0xdfbf9c4e5ab0696fL,0x0f4e6e2ab6db9cd5L,0x4857e570482e40feL }, + { 0x5ccd9b421c3beed4L,0x171b085fae51a947L,0xcebe0dbe59065754L, + 0x4d052d3a461c1620L,0x396bac422fe541a7L,0x8e714cdb70bf32d8L } }, + /* 49 << 105 */ + { { 0xed82f15e6ca1cdcbL,0xc5ae5cde51b9a9cbL,0x3b2f78cec70c475eL, + 0x0f22d10b4243c675L,0x1db96885facac4c6L,0x2fb7884817df2f2cL }, + { 0x25fb9f4e990f3104L,0x1416733ecefa14f7L,0x3a33828384a5dc24L, + 0x6d75d3d02564288cL,0xf7bea8b69b93e62aL,0xa5ea8695349f1740L } }, + /* 50 << 105 */ + { { 0x38feea7115e711b8L,0x129aea564accd3eaL,0xc53e54c412b23539L, + 0xb15bf11a2b280c59L,0x5ea76f5782d44df5L,0xea79f833d4ac1af8L }, + { 0xe547deba08330c6dL,0xbaa89422663ef402L,0x17263762d215a5f5L, + 0xb9509a19c02b5f9eL,0x9bb99fcb025caaccL,0x43f4494b25f24089L } }, + /* 51 << 105 */ + { { 0xe55e592c98563c70L,0x4e62ace5d013c82aL,0xb6025ac16fcf7380L, + 0xac4a8157cfdff8b9L,0x1fa181344497acf6L,0xdcdf05c0ef09d3e9L }, + { 0x7a65490d83d8e716L,0x2aee0b35e98c46feL,0xe62381dc7d6d4035L, + 0xc7162b78203975c0L,0x1079d8b6aad2c021L,0xe3e1cb4370c98838L } }, + /* 52 << 105 */ + { { 0x3ca01799f04dd97aL,0xd6d1d41d3f9e03f3L,0xac2713eda55fa375L, + 0x2bd440556a89a5e5L,0x8582d98458f5c269L,0x7f9b3527fb31fc27L }, + { 0x23f91951d810580dL,0x99303919360a3debL,0xfaf10326b5e1eea8L, + 0xf96feb4838ba5ac8L,0x1508b1002a639622L,0x0766a1019dc93c78L } }, + /* 53 << 105 */ + { { 0x0c79d40679a0290cL,0xc09bca0c57eb7a00L,0xf7274ffc163c1dcdL, + 0xd64ec461bb2c83c4L,0xff3b83efe9ee350bL,0xa490157d01882c72L }, + { 0x626e1f3d3312310bL,0xd2097e03cdd5d62cL,0x705c3fcadbf659c5L, + 0x2dc1d7cc810fa413L,0x6313192ad67d58a8L,0x6e1e5bc3597f63a6L } }, + /* 54 << 105 */ + { { 0x6100535ea0d42639L,0xb126e939d921369dL,0x2d4c826e4999e42cL, + 0x159063c6f62f77e7L,0x063c42914e632555L,0x8d3ee387b35d8220L }, + { 0xbd951cff9b2bac3eL,0xd9b943f1bc248755L,0xeee7017ad3a6074cL, + 0xbcb9e0e6b0872a21L,0x26d80e0949dff656L,0x2ad7d4e335fbf620L } }, + /* 55 << 105 */ + { { 0x6ce5840df7f9503fL,0xb96f82996abf4f6bL,0xf71f33853ab55fcdL, + 0xe347e891e83a8109L,0x12c5dcdeeb48f0faL,0xb0f02553cd7183a9L }, + { 0xa7d74862c414f01fL,0xbea40c5cae369360L,0xbe9785e5022d5192L, + 0x1a3224a50d318251L,0x4d7200093fcbceebL,0x1fd71167c2976f6dL } }, + /* 56 << 105 */ + { { 0x03c88a8566d2ee47L,0xee8e5c34455ee428L,0xd90a3d393870d90eL, + 0x2fd78d14f2fdb976L,0x9472a6066a312a30L,0xea68e2283484af2fL }, + { 0x7cf25951ac9e5cf2L,0x024f07ee37a28e95L,0x5d479379e563a2bdL, + 0xe87b50a4b46e93d8L,0x9128fc11f137285cL,0xe46efdf77c67d7e6L } }, + /* 57 << 105 */ + { { 0x4050036c7cb0b9a1L,0x8560750c1161d7fdL,0x4d293a521b247ba9L, + 0x4b25e54c8f1b9d31L,0x91c89139c5baa0aaL,0xa2f75f9f2202b7e2L }, + { 0x6c0915dd4d2d1388L,0x575d90f703717fd7L,0xd90c059b03e0626dL, + 0x7004305ba4239e8cL,0x39fb4e2e989775e6L,0x20c31fc8d8a239c6L } }, + /* 58 << 105 */ + { { 0x4de318054ab51b84L,0x4a68443c6aa00707L,0x2c3637f05b317f3bL, + 0xb8ea6f87c0fc14a7L,0xcd0cb4fca2cc6af8L,0x6b5fc899317083fbL }, + { 0x1b8f160956e6dfa1L,0x698299ed92b77d20L,0xdb84ab7f14fc3fc1L, + 0x944666a35d5fe625L,0xe9a3448d7e064ab0L,0x53f62fa01abe1440L } }, + /* 59 << 105 */ + { { 0x04bc8a2bc8c676b8L,0x502a73144a577562L,0x494d01f11ff01f9dL, + 0xfe648df164d98f70L,0x80bed0d849719dd3L,0xb77a8f09c231e190L }, + { 0xc8aa8daecc011818L,0xf313be4f5918814eL,0xf28fcb74488b5bfeL, + 0x71e23b19b3345c98L,0x1cfb7c0596eba9beL,0xa88e73b941c61971L } }, + /* 60 << 105 */ + { { 0xdc7050459cfd4295L,0x1cc9648eedeea59eL,0x88f4af1c0e9ca92dL, + 0x45d0b53f69689317L,0xa122a6dd41c04186L,0x9df54c3a277fba1aL }, + { 0x1efc55a5017eb9ccL,0xb253f7b661d1ecd4L,0xd03f8ec6acfb7854L, + 0xf641e5f49f338dbaL,0x6b6a680a3a3addbcL,0xe80babb5b5cd058eL } }, + /* 61 << 105 */ + { { 0xb48da67307873319L,0x53309cdf3bf5db9bL,0x1bc510e64ee9dd11L, + 0xbb8e529a7388950aL,0xc9c0ce3c7f6e6175L,0xd75753f88a290784L }, + { 0xfebdd94ba80acc08L,0x942cdfebdc846b30L,0xbb64799f6ca7099fL, + 0x40f03362d1326fa8L,0x95b2d9db97b62e9eL,0x5ad9ce165301d9aaL } }, + /* 62 << 105 */ + { { 0xaa5fead9dfc59ef1L,0xc1348e98b2cc1e9aL,0x83dd617e77bda968L, + 0x0fdcc0837c8997dfL,0x9206ae234cc62b01L,0x88aec92f417678dfL }, + { 0x9d399af791fb8920L,0x399eebd13e8a22a0L,0x32f3bba735bebdf3L, + 0x354c1c5004c2f32aL,0xc2d6b5514052c926L,0x16a1f71f656a7eebL } }, + /* 63 << 105 */ + { { 0xd7a755bc14a8c57bL,0xa97b901341ebec55L,0x88b88459143a1a9bL, + 0x7aa178cc7e19e3e0L,0xb8359634635dfb65L,0x63fd26c7c169e28aL }, + { 0x89d9090d953272f5L,0x63e571196383845aL,0x0e26c0cf886a1f1fL, + 0xda56332db7057a29L,0x6b5d303f7a459c6fL,0x3c351b771bb704c3L } }, + /* 64 << 105 */ + { { 0xda2b0725bb296c27L,0x1f22ffa4d341171bL,0xc721e35a5b132756L, + 0xe5695e84fadb6907L,0xbc5a3bf4c283f546L,0x9182cb3edde128aeL }, + { 0x179c7fa66592e05eL,0x1e604790f38e8586L,0xaf7e83bea16bad55L, + 0x6f41231e9137ecd8L,0xac87543d8f30d1abL,0x630a9d87b1ee0ee8L } }, + /* 0 << 112 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 112 */ + { { 0x359cbfa05e4f1914L,0x6992cd48d922176aL,0x2fd5e90f630cbcb5L, + 0x2b0f61306ddbf238L,0x5070970a3af753e6L,0x433d009441727016L }, + { 0x2eb15b3b9dca97e2L,0x3a7379cd00d96875L,0x0d4374aee930a75cL, + 0x3cd36046849e7727L,0x9ac3117e336a19ffL,0x2d1373c9433ddc04L } }, + /* 2 << 112 */ + { { 0x985dcb43e4362d67L,0xecb860c2a939bea4L,0x40597f3055fbf1d5L, + 0xb6d166bf43fcd98aL,0x5932570915ec99caL,0xe05ae3b9c5bdd370L }, + { 0xc18f78270c7b943bL,0x84bde9c64dd572ccL,0x5d50a89df478e56bL, + 0x242c2f4864d29053L,0xcda12c6161cf7e0eL,0xf8b6890eac8d1d40L } }, + /* 3 << 112 */ + { { 0x7a9a9dd7b6b11af8L,0xac4c50dd16a42f8fL,0x1550267b6726c324L, + 0x12cfb2fd7f841afbL,0xa41b19052f046430L,0x8f5f5373b7d786cbL }, + { 0x7b61b39c729e09fbL,0x07a5415f2626da4cL,0x65d6efb84a348905L, + 0xf377862cf2e864b9L,0x3c94000dab96cdb2L,0x2176321a8efef0f6L } }, + /* 4 << 112 */ + { { 0x8c558000c1c1bc68L,0x9e48a67a83fd6ca6L,0xacf0d75ceb7a35cbL, + 0x0fbdce4cf0a93110L,0x82b2d13a9cc50c85L,0x696fd259cef70d6fL }, + { 0x1cc9be2e457b88c2L,0x0d58b34b1f04c0bcL,0x52bd479f195a532bL, + 0x769fe6ca1ab3605cL,0xba6a63e48a24c1e0L,0x86dea46299da5d7aL } }, + /* 5 << 112 */ + { { 0xdf2a6cecd24790f3L,0x37bfbba7b87ca06dL,0x7c8a7e4c0de8a6aaL, + 0x5c806b94be7b8f5dL,0xccca1c714fda3e7eL,0x3c1cbaf9cff788e5L }, + { 0x17a081a9565d0464L,0xc4eb995713ed1b82L,0x0d7c90549e4cfac7L, + 0x6fb74c629d53a200L,0x65b9ed6d5f977a8bL,0xe2279cec0ba2e7c4L } }, + /* 6 << 112 */ + { { 0x8435e2962d4412dcL,0xa36cbfef972350d8L,0xe2fe6e6fece5cb15L, + 0x6f249b095336f7ffL,0x5801feb9908ee267L,0x7649a837fc8f217bL }, + { 0xfc1adc3ea0ebc808L,0x1ef06bec94f08075L,0x4afb5404cc1d9b72L, + 0x75cabd61a1f2c5a4L,0x2bd797e1cd08f195L,0x4f1b5cdecbea0f49L } }, + /* 7 << 112 */ + { { 0xe9759aa9e7aa87e2L,0x2d54a5fbe5909f55L,0xe49a59aa2c80bb61L, + 0xdb89e21230c9b328L,0xf42b9adb004ebffcL,0x4471b983479678e4L }, + { 0x0dde5b0e97709e2dL,0x2f35c653a12bdb85L,0x9f8d7a5cd8c8285cL, + 0xd7cde5971d156206L,0xdbe765d7a8e126bcL,0x2e645b6de3f4e60bL } }, + /* 8 << 112 */ + { { 0x509abccb65682820L,0xfbfa1d094ff86137L,0x1ae371bd640bc2f6L, + 0xa155c2978f546c68L,0x8858cadcc08b8cbfL,0xafac5b0a1d96948bL }, + { 0x919cb22682e25016L,0xd147df4ab064ffc3L,0x25dd0f1ab4abe560L, + 0xc6bbe6369cb75bd1L,0xbb367cf947a778e4L,0x5714aa4dbde524b3L } }, + /* 9 << 112 */ + { { 0xce3c8218e61b1439L,0x8be5a9cb67f79d28L,0xb1bd1386d5164b35L, + 0x0bc24d96b9adbac7L,0xbcee4f0ec7482414L,0xac15b5b66ca5d49dL }, + { 0x79caa999f20f9a50L,0x89bfd652a911308cL,0x972fe26d15245a7dL, + 0xd44d0f6e1d0d2939L,0x6749beaedd439057L,0x02627a6ad4b6f416L } }, + /* 10 << 112 */ + { { 0x7e882e8cb437b791L,0x9afde25afbe334cfL,0x60184381da52f9fbL, + 0x935d33a1001df73cL,0x38f303df080682e5L,0xd9cf2c1f4e9a29b2L }, + { 0x889d265e00d9208eL,0xfc1cc2221fd8e817L,0xdd14f1a2ec71428aL, + 0xe81cc4f9d9e973aaL,0x26a154963696468cL,0x0620fe6409d546acL } }, + /* 11 << 112 */ + { { 0x06ed3e64166be92fL,0xe1da6e27c51ea53eL,0x784f2514acb2b245L, + 0xc544e50f8e24077fL,0xad449938c5c01787L,0x5d9ef8d527d41dd7L }, + { 0x37114064e15d4a96L,0x7f0c92aa1dd45321L,0xc1f11d56b9c72ee5L, + 0x91f3b3f7a78e6d3aL,0x0cf440b0c9488cf7L,0x14d3defd93df403aL } }, + /* 12 << 112 */ + { { 0x3fa4ea0225aa1d44L,0x22c68e17f74a6a3aL,0x351bcb80f489e72dL, + 0xdabdf118be0268edL,0xa3bf9e1984d2cd16L,0x318506a2d67393a4L }, + { 0xb0c6b2d8615ed517L,0x42ac507c3dcba0f9L,0x60570dfb51235e30L, + 0xc677628dedb033e4L,0x0290c22766e61f76L,0x1d8450d09888943fL } }, + /* 13 << 112 */ + { { 0x1b8f5ed7155a3daeL,0xc9d2433aa46ed72bL,0xe99c7fe38ca361fbL, + 0x606b08c19626fe7bL,0xe6447257c0ea792aL,0x5839e2c62e1156f3L }, + { 0xb73135dd5eab6d41L,0x200f2e488ef63584L,0x4c73885ddda1c49eL, + 0x8d606a75b5428ee9L,0x2a73cc7aa62699dcL,0x484a58941c6c8de5L } }, + /* 14 << 112 */ + { { 0x2365b4150decae0cL,0x9c8567ece8583741L,0x35d6cfae6d8842a7L, + 0x4e6c98e6dd0db8e4L,0x584524e767b34d02L,0x786ea52f554c6117L }, + { 0x8952ce169320725fL,0x8eb7f91854c4c8f2L,0xdd34f77afc799251L, + 0x76b8c3173e05d37fL,0x664cbddcebb4d365L,0x31ba98b90dfa1a98L } }, + /* 15 << 112 */ + { { 0xf113a7bd651c186fL,0x417bd7373737a50aL,0xddb40d201b858249L, + 0x62a60745345f5b45L,0xf0a03f5c2d4e221eL,0xcafde67cc64621a2L }, + { 0xbbbfaebcbc3c06c3L,0xadaf9a16b8383dc0L,0xcd21aa308f343ea2L, + 0x64cefec0d890128dL,0x2ed9b8f763b44054L,0xc0a49e2917c0ffcfL } }, + /* 16 << 112 */ + { { 0xc6307399166915dfL,0xb35545bc5da8a26eL,0x8e0126aae3a99321L, + 0x0fbfdf76da9308d1L,0x2163ed6b6168e505L,0x71f3d0087500d8bdL }, + { 0xf57159605ac13f65L,0xc1cd9a6755172d5bL,0x6b225f7e53d84c65L, + 0x9c031269025029daL,0x54c1edfa17d89aedL,0x5b0238786b435150L } }, + /* 17 << 112 */ + { { 0x96d69db1146abf28L,0xc924454924d221dbL,0x7881951c137bdfe1L, + 0xde2d490dda51f789L,0x6033c2c34b0a1e0aL,0xbe214d8c08dac13eL }, + { 0x3d5abfa9a5a1d055L,0x3433060f6fe02a62L,0x88608c7ba37f2833L, + 0xfd2da6f0e74dd6c1L,0x27c22c17fe000000L,0x04a1f15bcfbde005L } }, + /* 18 << 112 */ + { { 0x01204485f340b522L,0x588a9e1c9367a099L,0xb3d1a4b466005913L, + 0x522ac504d55cc36fL,0xa6c80e511b72eabaL,0x15025a7acaaa89b5L }, + { 0xc9166912bec1a986L,0xe78e9642f19044cfL,0x230d51ab4756908aL, + 0x6795942aac04cb90L,0xcd2cc9eca2a92818L,0xfccead967cf52961L } }, + /* 19 << 112 */ + { { 0x32fa291d52ccf481L,0xbb137ef901ac0eafL,0x13ce2183011746abL, + 0x7e64248677bfea0aL,0x67cbba0e5e7e5032L,0xc900998a1f2b69fbL }, + { 0x62ddd91aab3256afL,0x1f0f216911d7996fL,0xab2f2d540e4dd4feL, + 0x05b577a92ec64ec3L,0x8071e88708ef233aL,0x9be1f8d60e649a5cL } }, + /* 20 << 112 */ + { { 0x5f78334137732664L,0x625b85dc840b6f8eL,0x7dcb3d256cdf0959L, + 0x87a5ae19d4ce1845L,0x43bf0721b0dc016aL,0x6569ad52f6a5f6f3L }, + { 0xa2697f15560ab87aL,0x4c6fd1a0060dcd57L,0x652a7732c3167f56L, + 0xe355fef05294a5e0L,0xf7b3177dcc59c562L,0x511c96dddccf4b1fL } }, + /* 21 << 112 */ + { { 0xec768f587622c0b9L,0x7c9eb5490416afe7L,0x3c3d87f55795433eL, + 0x74eff3cba4611446L,0xb2c79249dc7037d3L,0x70062ebd8bb1fc42L }, + { 0xbd0d3532a4ad91c8L,0x42411c139f5ee0c3L,0x11c4ee91132470cbL, + 0x496438979fb2a135L,0x4c1df7e0ce2ec891L,0x689cda57e16f7413L } }, + /* 22 << 112 */ + { { 0x3b42838a2a0030a1L,0x3f37587ae05ba56eL,0x6382a86f44c16650L, + 0x6c1bc67da6f9f136L,0x7d152d907ada0f41L,0x9115319d5c40c0f5L }, + { 0x1143028632f58e3aL,0x5dcf7ec7eda5c5a2L,0xf04404a9f334a0b2L, + 0x75e0b4a84ec2cbd5L,0x86e89728d079dbf0L,0x796700799a99c605L } }, + /* 23 << 112 */ + { { 0x98456a79b1d2a3fdL,0x4e8ba91e6dd789e9L,0x8e0bfa33a435226eL, + 0x42bea2f48cfea5ccL,0x5ca5fb0321b14602L,0x73faac5826877b13L }, + { 0x0ddb6ea203905ebbL,0x67bc35f1698cd7abL,0x24da47d85d9af735L, + 0x1a2a7c1dd786000eL,0xb35fb29e23ccaceaL,0x1c063466bf1f51a7L } }, + /* 24 << 112 */ + { { 0x1e7ae1601e94d949L,0x177dc53ee78e6221L,0x8af29d8f7aeb9882L, + 0x2d9a60fd9e3f3906L,0x6979fcd6df962156L,0xdd2fe5887e1e54b8L }, + { 0x9cccf31076643453L,0x94ece1a84e0643d0L,0x745449cbc111d8cfL, + 0x872afa4ae6cfbd97L,0x5c27b7ca10dfb34eL,0x505e62bc533480feL } }, + /* 25 << 112 */ + { { 0x6dd2007363141676L,0xdb099810c5c4c657L,0x2bbbcbaf8c369f32L, + 0x339e3ded08794178L,0xcc362a32315c4cd7L,0x5d288ff37dbce794L }, + { 0xafd05d104d0cb6c6L,0x3a6dcee9d386c7dfL,0xa207dc17e311ee74L, + 0xc5794286abdc751cL,0xf45136e5d889b985L,0xb25e84638d8f32a3L } }, + /* 26 << 112 */ + { { 0x8711ebfd1dc32f77L,0xfc0e851f3933d758L,0x90b679fd64a859f3L, + 0x0914a975ef37a81eL,0xcef80495d675c502L,0x862d3b65be18c403L }, + { 0x0d53f957305b4aa2L,0xe404f2570e5bcb47L,0x833a8644854b6b63L, + 0x5709f53b99f8d3d9L,0xc400dc1f13893effL,0x75ca01714c65086eL } }, + /* 27 << 112 */ + { { 0xdaaf8e76eeceb904L,0xbce9ca54b9e31f92L,0x4442d0c88d06a58fL, + 0x5966e1e5eda0ee34L,0x043125f058edc555L,0x44d0311749cf0931L }, + { 0x292aea12a99ae5c2L,0x1e9be1702a2bade4L,0x003ec2826b21b444L, + 0xc158f3cffc41d601L,0x25a839f4c4b3f4c7L,0x4a36bec399e64264L } }, + /* 28 << 112 */ + { { 0x829bbe7e04e6bda7L,0xc52b64ded3e667dbL,0x98aa40ecaa2fc128L, + 0x2c6997d011fbef94L,0x70ca76aa97c8167eL,0x558f8ce7b1083886L }, + { 0x5c621e35d250f064L,0x757710f8f535b2c7L,0x5d118d8faa69ee95L, + 0x02ffe667b27cd9deL,0x65711ac7d13e51fcL,0xdbbf16278cb1a1c7L } }, + /* 29 << 112 */ + { { 0x3c2fcbceeab0bb77L,0x569d6c7e4e1b17adL,0x22e06899b0518730L, + 0xf8466d9d19f809e9L,0x372e254288359d10L,0x8074483532d5bb82L }, + { 0xc88727d566060945L,0x08e9246572a0d38fL,0x84ca145c9f84a861L, + 0x8363463c1c004212L,0x9debab72bd3ad87eL,0xce68c150a988e65dL } }, + /* 30 << 112 */ + { { 0x1c172e5ea71dbae0L,0xf7794eb19b80bf40L,0x3007c5705d7d2829L, + 0xa8d44d6fcc97cf00L,0x093a9784f6abea6bL,0x2ac4a67564cca46fL }, + { 0x14fcc56350d8fc8bL,0x53133983a11ccd07L,0x7cf09bf68e6b8f26L, + 0x49f864d57b06e3adL,0xd526a765c373fc6dL,0x7af297c6151305d5L } }, + /* 31 << 112 */ + { { 0x18f941bfcf7c1eb5L,0xda10720a130163b7L,0x3c4894f46bd9bb34L, + 0x7575087bc8ca64f1L,0x68c424852c8f3798L,0x986214eecf0e5839L }, + { 0x3723b713df2b0b90L,0xd81560d5d229bf8aL,0x0204ae5ff993078eL, + 0x55206d9186a14833L,0x8c7d09181557fc96L,0xe2cd5dcdddba9705L } }, + /* 32 << 112 */ + { { 0x009ef80aae238fa1L,0xb41d9b24486af6b5L,0xab4455ed685add95L, + 0x18f323f672c7dac8L,0xe7009790e372f168L,0x4d5bcba6067bea99L }, + { 0xf15bdbcc51a2a9a9L,0xde7e4f742fac9169L,0x2fd62c304bdbec36L, + 0x8b3ea93d1b3ac6c7L,0xce1c8e5c9c293889L,0x19664dda11564f8bL } }, + /* 33 << 112 */ + { { 0x207a738245406afaL,0x7c1c398d1675bc91L,0x2ae99d8ba1bb7a43L, + 0x63f134e8c5e176e5L,0x4a624a1c48364268L,0x471974f1de65c5deL }, + { 0x44932063ea90b0cfL,0x13ba5019d8fd7e30L,0x6281f71348510422L, + 0xdaba3f14bc1a523aL,0x333e5eff924cc5cdL,0x861ab150e9113d1dL } }, + /* 34 << 112 */ + { { 0x332d308dd9b9461cL,0x3e9b4a95b7014261L,0xc557f608c2beeb5cL, + 0x9ee927187c8531d6L,0x55ff3dfcc0002ff0L,0xed96119eccd9b325L }, + { 0xd779ba03fb92416bL,0x63b75d351416be79L,0x793cb1fbfc9ad27fL, + 0xcc762a5b87f1bc59L,0x6e7a23389bbb07d8L,0x99b6e278aa7bfa44L } }, + /* 35 << 112 */ + { { 0xeb142de02bcce03eL,0xcac04711577565e2L,0xa949c7350ab07328L, + 0x8f15874cd7d347ebL,0xade8c67a696dc9f3L,0x039e6b7c66a7bcadL }, + { 0x1260bd4acb8cb9d2L,0xdbf05496d4801bcfL,0x6b37a4d30ffb845eL, + 0xc3968fe150b50889L,0x261e82f4525c6a7dL,0x539f634912aad50bL } }, + /* 36 << 112 */ + { { 0xcb1a9d2ceae4d774L,0xfdec2ca998a0775cL,0xa538acbd0eab9e25L, + 0x6901ebfd04dd34b0L,0x998ab679ed4c6409L,0x69b1d7ee0235b865L }, + { 0x4f2e6e5723ac3be6L,0x2b2072aed4a00479L,0x5c12fcdc2ce2f059L, + 0xfc688c45ac329db8L,0x16d377a51f539427L,0xebe4e2cfa08ed9aeL } }, + /* 37 << 112 */ + { { 0xb394214715d60238L,0x60d8909bbe9d4febL,0x013827b78654e16cL, + 0x465b3078824fc55aL,0x361e6523e3fcd6c0L,0x2ef44d80ef88b307L }, + { 0xdca7809fbeb2db77L,0xe649d591da97468aL,0xad6079b77c28ff0aL, + 0x6a21ce1ac4897775L,0xde876f7b5a592fd5L,0xced421a585a1dd36L } }, + /* 38 << 112 */ + { { 0x9793bdf6a045a442L,0xdb3c60472713ed37L,0x9929d32261344a0bL, + 0xfb48c2dc831af45cL,0x730226df53a8a077L,0x3a5baf8a18876559L }, + { 0x99736e7d8e11f9edL,0x3e7663dd0c09dddfL,0x368a29ed89b8a23dL, + 0x5443d7f5d3a68663L,0x0b84b464c6302455L,0x235c6eb5cf088847L } }, + /* 39 << 112 */ + { { 0x13307013b8de0a3aL,0xfb10e919f592fd9eL,0xd09e5b2571401ec7L, + 0x6e8091c11d94cf0aL,0xb7d79fc74193b129L,0xb842a3695f2c05e5L }, + { 0xcf6fc6cbccdc7614L,0x77d6408180102a3aL,0xde4b9304f30c3488L, + 0x4fd9f8d89bd08e48L,0x58ac01245963b063L,0x1f11335c747fac66L } }, + /* 40 << 112 */ + { { 0x5f266f13175418b2L,0x6bd7a86903a626f9L,0xc7b532304a6f11caL, + 0xa216b056bfc8ccedL,0xa274d5d8b288cb7cL,0x6fc4a35d924897adL }, + { 0x1ea532eb81fc6940L,0x2fcd817e2acbbc45L,0x45eee93f67814fa3L, + 0x3b3da48c1229e035L,0xd049a976efd8e3d7L,0x8087dff7bf81f314L } }, + /* 41 << 112 */ + { { 0x9ccd802fbddea807L,0x08a64e86d93b97f6L,0x422c0f5602f04e3cL, + 0x25aecab133900990L,0xcdb2c5c15d4b4d2fL,0x849a6b1f5f43e42eL }, + { 0x4689b815446e7361L,0x49abaf6ca681fba0L,0x304d84b18289a564L, + 0xa6529d430b779df3L,0xca926da67b51b195L,0x3640dde5c829ae84L } }, + /* 42 << 112 */ + { { 0x747235495424e1d0L,0x3861ae65c85af64fL,0xc56ff12baab902c2L, + 0x9aeb9e154fbf264eL,0x14e3c13942ca40d2L,0x6c26da41c1ba0250L }, + { 0x97a6031df51a0967L,0x88fea7710e623393L,0xcafae4c778574eefL, + 0x2c4c281198119f28L,0xd190fc749276d971L,0x843f4baf9273f01cL } }, + /* 43 << 112 */ + { { 0x1b2d643de50ad79dL,0x1ceaee7ed3075486L,0x13a003f3ec287aabL, + 0x09a4a825e8c7aeddL,0x93babe5ad1d4c05cL,0x8115bfec95ab084cL }, + { 0x629e8e0a289ebb8aL,0x923167a9bd992f77L,0x440edf75ae16ce72L, + 0xa67dd37b0a0019d4L,0x174b341978b0df8dL,0x010746a5ad6e4c60L } }, + /* 44 << 112 */ + { { 0xed05e4bf8342da4aL,0x36d881f3b565f0f2L,0x3fbd04e1411e627fL, + 0x40ac13cb0411889aL,0x9f6006cab5b25fd6L,0x0e79d377e31404ccL }, + { 0x9fd6474a5af3ea01L,0x89d7ddcb2a27d905L,0x2c1beebada12e71dL, + 0x3ecb11e1833eb7deL,0xa348b2f6600eb1faL,0xc227192183f2657fL } }, + /* 45 << 112 */ + { { 0x2cfaf519e32ba792L,0xa99113d7f929b512L,0xd347f7d18f554e19L, + 0x18f0374f098a2ad8L,0x073855acc174e0b9L,0xf155c6c009324c23L }, + { 0x3388c39605d1e427L,0x144356a9d39221d1L,0xe3d4ffed492a84adL, + 0x519c65e6d1e53c29L,0x334f470a2813c717L,0x69aa0a1de0a400e7L } }, + /* 46 << 112 */ + { { 0xd8689c9c39e70b62L,0x2b87157e6cd86fe6L,0x53d55de887c0f35dL, + 0xb2d7141de09aa44bL,0x3499553084fe7c21L,0x4550096c16b19be0L }, + { 0xb0a8ce05b856dac0L,0x570223450e211887L,0x8d4a7431aca17401L, + 0x96bf439857400a0eL,0x1e849d365ffd5f34L,0x7e70f6253a6d23acL } }, + /* 47 << 112 */ + { { 0x511ad0024b4ecd64L,0xd2287a28f37bf796L,0x801d2c2dcbc1f22dL, + 0xf0d3a6944df568c8L,0xa7fec550af6836b0L,0xa27dd6e887a426c7L }, + { 0x2f730e5b59c6b695L,0x9df438ee93ee2b36L,0xc4def9eaf2cfc4c6L, + 0x82ddcca0a209814bL,0xb2e1de4f6dc916d3L,0xc6798e7453f81a55L } }, + /* 48 << 112 */ + { { 0x77faac22bd366155L,0x13cc4038282f11b5L,0x31ad1dd45fbd35abL, + 0x7e0de9da45d6d40eL,0xa16c5f1939749ef6L,0x761cd6cf85691cf2L }, + { 0x156536ad4d59b802L,0xee98dc4187c4b11dL,0x165a1eacd35088fcL, + 0xce8a733538fb995cL,0x34d0d3313293b3a5L,0xfcf548ca8b570e79L } }, + /* 49 << 112 */ + { { 0x4c4bddca99e8cb05L,0x2b900ed017c5be91L,0x0ba0201b40adbfc1L, + 0xb5098cf8534595ecL,0x356e23ff80f56f69L,0x8b3fa12e748555a0L }, + { 0x9063437677b8ebdbL,0xe3eb33fdf040b6a8L,0xcc5b699539b611ceL, + 0x20171523c693be7eL,0x5c4364d760849cf0L,0x30f3376372c4d303L } }, + /* 50 << 112 */ + { { 0x0757295022a8c8e0L,0x6e05715866ca81ecL,0x7e8e36890f804bc9L, + 0xcba813a191b99207L,0x3f11f7abe50ab65fL,0xaefe5479b6d05954L }, + { 0x48dd59a1eff5cf18L,0xa623b738bda11ecdL,0x586e755818870f08L, + 0xb2c471a50e38ba1aL,0x5b21c42c69ce8032L,0xaf040e6c7943d78eL } }, + /* 51 << 112 */ + { { 0x6364714c4852f979L,0x7ed7aa310700cd35L,0x9021e46d9376733cL, + 0xf2b65ed3b6de8d03L,0x0e3d00c16652346cL,0x6630fcb75d27e2d0L }, + { 0x69cc20ded79a1c20L,0xa6d77163be3745e6L,0xab36946379aacf14L, + 0x8bdffbf1b935a1daL,0xda8eb343b63096f6L,0xf61988f13c966345L } }, + /* 52 << 112 */ + { { 0x06f684ffd31f390eL,0xa1467be560ec98a8L,0x7cbdd03eaa80fddeL, + 0x0ae4d114e204ded1L,0xb8ebeb29a004c3e2L,0xd93cd70726009581L }, + { 0x3ff2ee49f1b9d3ccL,0x0e69e5ac753526ccL,0x8cb2243e8b13f47bL, + 0xe2c5ae8d7fbfc5aeL,0x8e9af723394a45d8L,0x0b1114dbd92ab8d0L } }, + /* 53 << 112 */ + { { 0x937d9d2a73f9ff5bL,0x07c8c147de0fd740L,0x3880ead73639b680L, + 0x879d6f836558cc89L,0xf32e14b975bc8c84L,0x278ea5e4bcf6f8cdL }, + { 0xd9f25ea94baca6cbL,0x676e4bdd44d0ceb2L,0x98042ac190868974L, + 0xdf227f370711b658L,0xcd6d29b46ef0e4f8L,0xd04f5bf88f817e92L } }, + /* 54 << 112 */ + { { 0xc7d62be78354f4ffL,0xd6fd9d590ac4d9b6L,0x13fbed772b50ab82L, + 0xc4c5be374362b766L,0x5d67bfdd6c59d059L,0x10c93cceac02f34cL }, + { 0x3bec1f3b72e35ca4L,0xb1cfade159f4820bL,0x679edbcf80fae051L, + 0x6762f5ba6671737cL,0x28b425db3fe77970L,0x4bd6d2ebe778aaaeL } }, + /* 55 << 112 */ + { { 0xdcbe0018aecd5ae8L,0x7f178b7aedb2a7b0L,0xedb5c805b427179cL, + 0x25fb6a084ba080fbL,0xeb6365165f1b263dL,0x814c520092acb04aL }, + { 0x936f97a988d94b88L,0x6d54f1768b45e4b7L,0x6321e3bdb0cc515cL, + 0x9118d0318eb5be13L,0x5be9188a8c574e96L,0xcdad43f3f281f19dL } }, + /* 56 << 112 */ + { { 0x7be5946ea85af34aL,0x420593c9da6fb0e0L,0x40b83c00987f9246L, + 0xac35f4e9a15d192bL,0x1979bd33776a678cL,0x0a7d973e8f6068d3L }, + { 0x71d322e87e6298feL,0xbb23a29936af9b65L,0x14e2b9706644c50cL, + 0x5f7f207373570bd3L,0x40215c569055538bL,0x91372e64365500c9L } }, + /* 57 << 112 */ + { { 0x2763961a303ef488L,0xc357c32fbf865ec3L,0x32ca1a943663e409L, + 0x9d9040217de506a9L,0x1f56e144249028bcL,0xd76402e61c5c7cecL }, + { 0x98dcac65b0dd9d4fL,0x887f6e97532facf6L,0xc0d5d2a123c2cfbeL, + 0x0566bd59d18d8b1aL,0x67404eb1297a071eL,0x10f24d9b26529285L } }, + /* 58 << 112 */ + { { 0x34808f5ca479ef4eL,0x60effdea9ff10abfL,0x471a077cdae34e0eL, + 0xf34df9562f9d1408L,0x4f8bbffbe46961b7L,0x6a80b0276336a6f4L }, + { 0x28e57309ca92e5dbL,0x27fbb139ce31cb10L,0xcea87ae28d24334bL, + 0x3781f438de6db765L,0x3328fc09edaf054bL,0xa8acdbcfa94396f8L } }, + /* 59 << 112 */ + { { 0xa05b72aa83a79820L,0x3210863ccdeeaedcL,0x192d5fdcb76fdabbL, + 0x25ec4568f10c17a7L,0xbd51e31fca556920L,0x8ab534f26a7e40f7L }, + { 0x2ecb28c041145d5bL,0x4e95843df9038557L,0x65605d17d783699cL, + 0xf728cb1178bddf7aL,0x2d823ae8bee2a60cL,0x02030edb8eb48325L } }, + /* 60 << 112 */ + { { 0xfe517758aa04facfL,0xa5216df44c421615L,0x4d87767d4f133b52L, + 0xdae81b7699757264L,0x53c1a0e3e3ad4323L,0x2c565bbd53b401bcL }, + { 0x94d2354fcd54a0e1L,0xf43d0f053f1a02a7L,0x52e7ee4af660b949L, + 0x563ec009bc208df4L,0x58c0b975bf21c4b1L,0x29a8e5adeb029e52L } }, + /* 61 << 112 */ + { { 0x4c07b3e4283bdd75L,0xcd94d2a385dd6177L,0xc1ab8a5cab097530L, + 0x90301468a5fd9ff7L,0x2a3e5b4064d0932dL,0x77e3b67e435e1c0fL }, + { 0x3b5d261c14f7bb4dL,0x1d67a760bab7bfc9L,0x507aad46d799621bL, + 0xf44567b5f4f3c3b9L,0xfaa97a3eae2bb6b2L,0x7d373b163594e2c9L } }, + /* 62 << 112 */ + { { 0x29ef2da9a15e6ea0L,0xf411e20dcd168689L,0x34944975049a4b24L, + 0x0effc2dfe035cd24L,0x5d77178b0a954cf7L,0x3504bc357ab2d8c0L }, + { 0xc3405000ec32219cL,0x00442630421a5a3cL,0x0548505c7f49819aL, + 0x6bdb281fc805d0e8L,0x03cb57ac97484e09L,0xcf0926da58a14cc1L } }, + /* 63 << 112 */ + { { 0x0715055cc85610a7L,0xd2642935fa6ca505L,0x87ef95128c361749L, + 0x89cd669a8c8156d2L,0x5cdcd266ed60d7ceL,0x99ccc96df59fb53fL }, + { 0x82400f4655df7f73L,0x2b6aa1d9af34f742L,0xa6cbca79c398aa8eL, + 0x7697bdea02b7325eL,0x1cb036b94fde4a79L,0xfe11ff96307fb964L } }, + /* 64 << 112 */ + { { 0x6a3a23279af0a75cL,0xf832a8159f1f250dL,0x17030c3322a82d3fL, + 0x24bf18ea14cbc835L,0x319dc4cab2da2727L,0x481df3606d020d4aL }, + { 0xaeebdd8a7fc22ba5L,0xbd0515c6a91e28abL,0xfc8a2978595f361dL, + 0xe60dd96c1ae8fa3cL,0x19c2109aa5341575L,0xfd6e92bb06a0ee48L } }, + /* 0 << 119 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 119 */ + { { 0x2e32f896cde5e785L,0xcd55ae7ab9db8f31L,0x278db1ad8f832885L, + 0x271d9078adcbd933L,0x2208fae34a64f863L,0x974046e039c89365L }, + { 0xcb46f272b3cd0cd3L,0x31f34e1a74e59edcL,0x3421d316edd50418L, + 0xb1d8a064cabe36edL,0xdb13e560362efcdaL,0x567c2b6cc71eb3eeL } }, + /* 2 << 119 */ + { { 0x2af8ed8170d4d7bcL,0xabc3e15fb632435cL,0x4c0e726f78219356L, + 0x8c1962a1b87254c4L,0x30796a71c9e7691aL,0xd453ef19a75a12eeL }, + { 0x535f42c213ae4964L,0x86831c3c0da9586aL,0xb7f1ef35e39a7a58L, + 0xa2789ae2d459b91aL,0xeadbca7f02fd429dL,0x94f215d465290f57L } }, + /* 3 << 119 */ + { { 0x94c3938b4c9324feL,0x0dea07003fe78a0eL,0x57ab9daa019e7dc6L, + 0xb0d7b14a9925b79fL,0x3c9a638b937a5daaL,0x3b14fd0de62943adL }, + { 0xbaafb635ed3ae4b5L,0x3060a090b2bcfaa2L,0x389d9e7f7aa8f217L, + 0xd7f987c6e9310a65L,0xec0927f993b69c0aL,0x9335e9102381a247L } }, + /* 4 << 119 */ + { { 0xc08550024b950889L,0xee99dbfe8ce24da0L,0xdda71d964318e860L, + 0x01d3d39604fe9b85L,0xda4bc065e25e7e20L,0xd3a50b87e076c81cL }, + { 0x5b9f821931e5f494L,0x6a140527a6a1b821L,0xf52683e4d8dd159bL, + 0xca9c888720b18043L,0x73c040fa08a0d8f5L,0x92e482e8179525c4L } }, + /* 5 << 119 */ + { { 0x8b9f650f3e776590L,0x41ba807f47703a5dL,0x8cc1a550fe907078L, + 0xd70cb76c8f00b84bL,0xcaee21566f3e6780L,0xfd6a51f595c2d03eL }, + { 0x2c897c5556ffa08fL,0x08589a6563d13d54L,0x6a1eed4287bbacf7L, + 0x66aed4f5ee709d78L,0x67c925bf1178ecabL,0x6870f4c8a29cf747L } }, + /* 6 << 119 */ + { { 0x37ed2be51cfb79acL,0x801946f3e7af84c3L,0xb061ad8ae77c2f00L, + 0xe87e1a9a44de16a8L,0xdf4f57c87ee490ffL,0x4e793b49005993edL }, + { 0xe1036387bccb593fL,0xf174941195e09b80L,0x59cb20d15ab42f91L, + 0xa738a18dac0ff033L,0xda501a2e2ac1e7f4L,0x1b67eda084d8a6e0L } }, + /* 7 << 119 */ + { { 0xe3a67b2d5e12e708L,0x3a4772e2ce48f234L,0x78f9dbc334794271L, + 0x9880053a3e6a61e7L,0x031c30b87c0f6e59L,0x8113df6cf7b972f8L }, + { 0x3625bdce18ee148cL,0x72c2b8efdb885158L,0x4c73c80c9a7f0df3L, + 0xbc2dd8a507b92470L,0x5a33e4dfdb005677L,0xc699cf5ea5ca9dd3L } }, + /* 8 << 119 */ + { { 0x3a828904a4d2313eL,0xbf4946b192e66888L,0xc574898ae5fa19d2L, + 0x0b13dbb65e1c5fa4L,0xf11343ba7c390fc2L,0x35b1418fd7d32187L }, + { 0xc92cb1bb83e7fe7bL,0x0b969455d78365c4L,0xda69dfe5672f2af7L, + 0x9c62d7b430932441L,0x165672ad94af02d6L,0xd2cc734dcde81c22L } }, + /* 9 << 119 */ + { { 0x6353420218d07dd6L,0xc7c0c8f128a3cb4eL,0xa41d4c55d7929131L, + 0xf1aaab3445d21f63L,0xd69a59545ec3e9feL,0x209732c1b8ddea2fL }, + { 0x368b9c59e1936916L,0xb011c662ab1f8585L,0xcce30a25474e57b4L, + 0xb79c76df7049c61dL,0x984739950ccf165bL,0x7c6f4ab40ce897baL } }, + /* 10 << 119 */ + { { 0x1d27efce1080e90bL,0xa28152463fd01dc6L,0x99a3fb83caa26d18L, + 0xd27e6133b82babbeL,0x61030dfdd783dd60L,0x295a291373c78cb8L }, + { 0x8707a2cf68be6a92L,0xc9c2fb98eeb3474aL,0x7c3fd412a2b176b8L, + 0xd5b52e2fc7202101L,0x24a63030f0a6d536L,0x05842de304648ec0L } }, + /* 11 << 119 */ + { { 0x907d88035a8432bdL,0x89232a5a2638fe30L,0xa120eecbe2089014L, + 0x3a5208cb5a2c9e97L,0xe163d29a3449eb4eL,0x3df984530eaba88fL }, + { 0x55d3b9afa1547443L,0x316aae18f2a60ceeL,0x64d0fd30d6e11a5aL, + 0x65de345808ef6002L,0xcede56fab4a3d1deL,0xa5bfa8d9a4bc1588L } }, + /* 12 << 119 */ + { { 0xd45e350133f4d416L,0xbb40233a4bf9131eL,0x1532a088e302483aL, + 0x3475e8b82c2485c0L,0x08f9ea56969cdbe6L,0x31928645253cd738L }, + { 0x1cf323a4ac9836beL,0xdf647ccf02b6e4deL,0x9a31e84fc06f3d09L, + 0xd326b86e39efe6d9L,0x77e3e1df14ac4decL,0xf2d5917af3e0c582L } }, + /* 13 << 119 */ + { { 0xf88238f1376216b2L,0x8c7522db7d15f653L,0x50aa7a74a21f74d8L, + 0xf7a964c8bc9e1a0cL,0x33ea64251387ca6bL,0xda84fe74e7be16a6L }, + { 0xdf0462d727867aaaL,0xeb7f0ab8ae6be1b3L,0x21abe5a5d9bdec8bL, + 0xdbb99199ac4bed1bL,0xf65c19d935d13c0dL,0xf966e22e4df74056L } }, + /* 14 << 119 */ + { { 0x67477cdc30577ac9L,0x51dd9775244f92a8L,0x31fd60b9917eec66L, + 0xacd95bd4d66c5c1dL,0x2e0551f3bf9508baL,0x121168e1688cb243L }, + { 0x8c0397404540d230L,0xc4ed3cf6009ecdf9L,0x191825e144db62afL, + 0x3ee8acabc4a030daL,0x8ab154a894081504L,0x1fe09e4b486c9cd0L } }, + /* 15 << 119 */ + { { 0x7b4e65ebae4219adL,0x2e424c441184a0d3L,0x10eeb898d32e179bL, + 0xadf05e2d8afa9a6dL,0xecd6c18bbeccd5f1L,0xe592115c39ac53e8L }, + { 0x9ccf231ac8c7b9b6L,0x1848b4fe678774bcL,0x2050856386782b91L, + 0xb7caf7cc74dc6018L,0xe80805485cf9273aL,0x9609897b246b4851L } }, + /* 16 << 119 */ + { { 0xe92b56c002cf37fdL,0xa75bbcb0f71b34deL,0x7754d0ef50f5c482L, + 0x850a9ef611fa89feL,0x97d74b1bba4ea7d8L,0xfc757c25aab7ba2eL }, + { 0x06f30ab0f2a67fddL,0xb10aba1412e72af8L,0x47580bca7a2e053dL, + 0x85795598dcf0e14cL,0xc3596781d6f55310L,0x8ab251b74c9b7e18L } }, + /* 17 << 119 */ + { { 0xdc56cff85279e5cfL,0xa33a6765fdbdf1adL,0xc122c0eee5077a4bL, + 0x44c3b190a98ab643L,0x334a6868b991d197L,0x598bbf185d6a0488L }, + { 0xd028bfdc5a0e6f96L,0xfd1a37f5e11c57b6L,0xe1240a3003f82183L, + 0x6afae98c390d8536L,0x554a42dcc244b181L,0xa3d422d75f4cb4b6L } }, + /* 18 << 119 */ + { { 0x512f82f9d113450bL,0x5878c9012dbc9197L,0xdb87412be13f355bL, + 0x0a0a4a9b935b8a5eL,0x818587bdf25a5351L,0xe807931031e3d9c7L }, + { 0x8b1d47c7611bc1b1L,0x51722b5872a823f2L,0x6f97ee8a53b36b3eL, + 0x6e085aac946dd453L,0x2ec5057de65e6533L,0xf82d9d714bb18801L } }, + /* 19 << 119 */ + { { 0xf113abe17d48bfe7L,0x51d77fa5213facecL,0x27bb373f21269089L, + 0x31e9850e7b188989L,0xd20a15f41d50a1c6L,0xb4887ed9d9746367L }, + { 0x8920a7e2325f19c5L,0x691352358ad74492L,0x713d1471d19a76a2L, + 0x952cb9e5873ab310L,0x5b359d1ffa8eb8cfL,0x55aab5ad8b9c9e7cL } }, + /* 20 << 119 */ + { { 0x4ab138504dbb8798L,0x0e7980d772d04cd2L,0x1755c5660b3271c6L, + 0x8414efb09d9d1468L,0x61a586301795ce66L,0xb6a8b393232924a1L }, + { 0xa992f0ceae031bd6L,0x6747fb5f2915acc1L,0x03daa26693e9c0d2L, + 0xc18fa3645400d554L,0xaf04ff8d9497e895L,0x86c3cfc250b6b339L } }, + /* 21 << 119 */ + { { 0xdf26f6605b26122cL,0xeb6c188c4d6b80ccL,0xae2efe59ccec172bL, + 0x5cdcd958f3f7d693L,0xa2ac2594c5f993f0L,0xb96ad8cf3f7cb591L }, + { 0x7e2f88f8446abbabL,0x3d1a5eb6f6051f2bL,0x7d882e82ad6f49daL, + 0xe32918e3c4e7bbffL,0x442a32789be81150L,0xa1d34da1bd14557eL } }, + /* 22 << 119 */ + { { 0xad81fa938ba5aa8eL,0x723e628e8f7aa69eL,0x0ba7c2deef35937cL, + 0x83a43ec56decfb40L,0xf520f849e60c4f2dL,0x8260e8ae457e3b5eL }, + { 0x7ce874f0bf1d9ed7L,0x5fde35537f1a5466L,0x5a63777c0c162dbbL, + 0x0fd04f8cdad87289L,0xca2d9e0e640761d5L,0x4615cff838501adbL } }, + /* 23 << 119 */ + { { 0x60c7e16cdf66a95cL,0x25b1078d5d0bd644L,0x77f8d872bd933e31L, + 0x5c4c382de2e1536cL,0x5b3b37c09295ee0dL,0xf94698d4ecce42b6L }, + { 0x947ef80c4db8f2c7L,0x34661f7dc70dd82fL,0x17b288a7f2311006L, + 0x1f1171a66815e1caL,0x0f71f66ce80d6235L,0x858c665a87fa5a59L } }, + /* 24 << 119 */ + { { 0x376b2a7f04e1e6e3L,0xea0dcb70a31774b4L,0xfc7fe4cc5cbdec2eL, + 0x8568499df03f459eL,0xe9fd8fb28b78900eL,0xd33c6e30e431bf97L }, + { 0xd904b8f5c896e766L,0xa8f577cf82748cefL,0x93dd921b87e044b3L, + 0x23d79837f76eebe9L,0x5e0a7493e569feebL,0xd0797549414dddb6L } }, + /* 25 << 119 */ + { { 0x9bf04f567781556aL,0x30be1e8953ebf7c6L,0x6f4899cf713fe432L, + 0x4f641fb7c9ef741fL,0x03560819002cc010L,0xfa51f8f7b4bbd339L }, + { 0xe09c5ef77f1dea5cL,0x39cb20d97255fec5L,0x407746862ea38859L, + 0x68ca598ecd7a29f3L,0xb8025dd67a9db4d9L,0x4feaeeaed9dfe491L } }, + /* 26 << 119 */ + { { 0x9422789b110b4a25L,0x5c26779f70ad8cc1L,0x4ee6a748ec4f1e14L, + 0xfb584a0d5c7ab5e0L,0xed1dcb0bfb21ee66L,0xdbed1f0011c6863cL }, + { 0xd2969269b1b1d187L,0xf7d0c3f2afe964e6L,0xe05ee93f12bb865eL, + 0x1afb7beeed79118eL,0x220af1380f0fe453L,0x1463aa1a52782ab9L } }, + /* 27 << 119 */ + { { 0x8cf42aa26b99ca6aL,0x696850242f091dbaL,0x9d887e6ad7d3270aL, + 0x627754fd5c9b735eL,0x3b8735a811d95df6L,0x74debd8b52443251L }, + { 0x1f8dd5b66181583eL,0xbd0ca92c8b570a9cL,0xc373a61a71ae3274L, + 0xf4b2c88d1c4c16cdL,0xd3e6ec3baf33efabL,0x8c54d2721bf6f0d0L } }, + /* 28 << 119 */ + { { 0xfd9e3542bfe5b1a7L,0xb42d2a4175938ceaL,0x74688a153befb760L, + 0x8daeeaa22e33dbe7L,0xc9c1ea083e677801L,0x68ecf4e434effe1eL }, + { 0x927700ccd294c321L,0x9e2e723de940afc5L,0xbcfac07a7cf6cd43L, + 0xa009ef94d1006bc3L,0xa02016b0373d13e3L,0x4e097adbabae5822L } }, + /* 29 << 119 */ + { { 0x7535175d48752720L,0xf51086ee850bdf07L,0xce322c33cb4c3f4dL, + 0xd863f7edb28965fbL,0xfe46a4e9885e4afaL,0x58b5c871136d7ddaL }, + { 0x126eddaf6ed07824L,0x084ce962844fcbb8L,0x9ac0787157dfb4c5L, + 0x97451fcc4d6b5910L,0x9f14b1ce0843c9c6L,0xf737f6c0a0e18596L } }, + /* 30 << 119 */ + { { 0x7c139d56d7dbe5f9L,0xfc16e6110b83685bL,0xfa723c029018463cL, + 0xc472458c840bf5d7L,0x4d8093590af07591L,0x418d88303308dfd9L }, + { 0x9b381e040c365ae3L,0x3780bf33f8190fd1L,0x45397418dd03e854L, + 0xa95d030f4e51e491L,0x87c8c686e3286ceaL,0x01c773bf900b5f83L } }, + /* 31 << 119 */ + { { 0x0028dcae855a0b90L,0x74c1e36026f0d718L,0x34f80e3ca059f144L, + 0x85b5d8e3f2bfe1b4L,0xe124601f453de099L,0x8b164ad6221b3efdL }, + { 0x636f45ebbe004ab0L,0xa23093e99f231a8aL,0x48e05e8e2287b992L, + 0xefec5e5b4477cb8bL,0x45a65afa8ba0231bL,0x92d38bd88b1af6baL } }, + /* 32 << 119 */ + { { 0x8db8b78cc898b8bcL,0x686896da502940cdL,0x67e50f022dde2e3cL, + 0x2e2461f38cbf406cL,0x32182781e1f7ff60L,0x26934b05e30e2688L }, + { 0x95adc204fc4494f6L,0x4c7f30c5161b7499L,0xd5caf060b7341737L, + 0xed93187fd128d46cL,0x3f2819cb20fc1e04L,0x48c4086f2b7f70a1L } }, + /* 33 << 119 */ + { { 0x45693c00a92ca9faL,0x046b218d63bd525dL,0x40f1d6cc6b1d6a68L, + 0xfc5807c5c54dc1f0L,0x2875d4d98b5690f6L,0x7a753543d0f72a83L }, + { 0x01f2c35ae28b5309L,0x38fb5f121bcef323L,0xd6ea6896256a9bffL, + 0x4380fb2c44d65badL,0xb587d641c3556fb6L,0x74c5ec1905167f32L } }, + /* 34 << 119 */ + { { 0xdabe347578673b02L,0x4f0f25cef6e7395eL,0x3117abb9d181ad45L, + 0x4b559f88aa13de0bL,0xfd8efe78ea7c9745L,0x080600475dd21682L }, + { 0xc0f5de4bd4c86ffcL,0x4bb14b1ef21ab6a2L,0xacb53a6cf50c1d12L, + 0x46aac4505cc9162eL,0x049c51e02de240b6L,0xbb2dc016e383c3b0L } }, + /* 35 << 119 */ + { { 0xa1e3cb2255b7f121L,0xc9183b13dd01db7dL,0xfe26aa801469dae6L, + 0x7318df7fd9ecfe2bL,0xade0a24d56dd4acfL,0x6e521c2222d1ba14L }, + { 0xa039800a40afa1deL,0x9c7da49d5c6af72aL,0xf7ae921cd3fcc7c6L, + 0x76af2407dcab63e2L,0xdc1618dbb6dd49ceL,0xebc65c4d362cc88bL } }, + /* 36 << 119 */ + { { 0xd847939132202bd3L,0x1dacde87d6631ac1L,0x99d2e71f905a94f4L, + 0xd3c21f5a7e67dd7fL,0x3605c28e3c43cf23L,0xb6cd5ac74d3b3070L }, + { 0x8bf748ba246298d7L,0x9e939fbd0f053664L,0x3bb3e7b8cc303783L, + 0x359bd3e56189c417L,0x299d0ce1f609ae34L,0xd7221cc7b9ca801dL } }, + /* 37 << 119 */ + { { 0xb7c823506b73c5a6L,0x7fea0d95fefee640L,0x6d5dd775f68b6be6L, + 0x4a5576147cbfa333L,0x6cad79c2fcd9b17dL,0x49aec3d405c4dd35L }, + { 0x3b1f3754c3792470L,0x351ef2ccbe00cffcL,0x44a248916a71f45eL, + 0x1e7a6013b8640d08L,0xf0f476154efcd556L,0xc82171444fe15dd3L } }, + /* 38 << 119 */ + { { 0xa3c56ad28e438c92L,0x7c43f98fb2ceaf1aL,0x397c44f7e2150778L, + 0x48d17ab771a24131L,0xcc5138631e2acda9L,0x2c76a55ef0c9bac9L }, + { 0x4d74cdce7ea4bb7bL,0x834bd5bfb1b3c2baL,0x46e2911eccc310a4L, + 0xd3de84aa0fc1bf13L,0x27f2892f80a03ad3L,0x85b476203bd2f08bL } }, + /* 39 << 119 */ + { { 0x85f9b301218642acL,0xb3f3b36f8728ef66L,0x4a833bea2ebb8181L, + 0x7d3bca9d8541a662L,0xd3be6d0ac5a0ecffL,0xaf52a2a9528da950L }, + { 0x4b431910131f72caL,0xe2708d36933d5550L,0x195340a469abf146L, + 0x84ca66e4e4e2e131L,0xd9402ca7e16c39bfL,0x5beedce343ca6041L } }, + /* 40 << 119 */ + { { 0x87c5915395523a22L,0x56686f525ac5146eL,0x9ec69ec718ccf766L, + 0x13f36d4ff6e21a4aL,0xa0841e94098691f4L,0xbd9d52d2bd91dd2eL }, + { 0xa8765981b3fa43eaL,0xb0cd17cd600b9761L,0x02dd9d71b5abe842L, + 0x63df33a63689a53bL,0xab4b85bb9d9baad7L,0xce2d31c1eb74e549L } }, + /* 41 << 119 */ + { { 0x8d69a654f2472426L,0x91a4b6a3ff7aeff0L,0x51dd8e76fdcc7cb4L, + 0x5f7d42a273731cd7L,0xc127401aa99c9d9aL,0x8ede9330c92561d7L }, + { 0x86057a56784c3cf2L,0x8afcf32cb5a7755eL,0xa0a5b561c71cd3d9L, + 0x0a5d805e36d3f5a4L,0x25a39acd7432a384L,0xd574a6b7b226e9ecL } }, + /* 42 << 119 */ + { { 0xab1cb818567af533L,0x273b4537bac2705aL,0x133066c422c84ab6L, + 0xc3590de64830bfc1L,0xea2978695e4742d0L,0xf6d8c6944f3164c0L }, + { 0x09e85f3dc1249588L,0x6c2bb05d4ec64df7L,0xd267115e8b78000fL, + 0x07c5d7aec7e4a316L,0xcb1187ba4619e5bdL,0x57b1d4efa43f7eeeL } }, + /* 43 << 119 */ + { { 0x886e3f30b29f5916L,0xa419d2c6625f29a0L,0xb4f89fc49bf07dc4L, + 0x86c137a1a165ed88L,0x6fa241a9e5d6280dL,0x08be9b0cd11576f2L }, + { 0x5735aeb7e376b03dL,0xf4639e6d182ce9b9L,0xb6948499cc688f57L, + 0xfde146636552009eL,0x3eeeae350a2e8553L,0x50447f1b659dfe2eL } }, + /* 44 << 119 */ + { { 0xefccd67ed15c33c0L,0x33393846146d5e96L,0x015e97da9ca7354eL, + 0x729b69bac143e795L,0xd4440ecfd4c5d0e2L,0x78c042bb697a80e7L }, + { 0x9361ad1d08602f75L,0xaa354166af489794L,0xe60e5a274966d3cdL, + 0x8346995e2394f9f3L,0x2de33256590f6a15L,0xb14427bb43298ac1L } }, + /* 45 << 119 */ + { { 0x38fee83a74680d2cL,0xd8019e5c0e700c8dL,0xcfaf5614475da1b8L, + 0x11893fc58f0159e3L,0x4c101127553813c2L,0xd273055208f82a6aL }, + { 0x8728834c74a3ce9aL,0x66b939a891906488L,0x42ac7c07b88d36bcL, + 0x663d7411d989bb72L,0x650e5d6eb284c066L,0x052b7f6710d8f124L } }, + /* 46 << 119 */ + { { 0x3618891fc8176a96L,0x62c4b084e5808b97L,0xde5585464dd95d6eL, + 0x27a8133e730b2ea4L,0xe07ceec36af318a0L,0x0acc1286ce24fd2cL }, + { 0x8a48fe4add4d307cL,0x71a9ba9c18cde0daL,0x655e2b66d5d79747L, + 0x409fe856a79aedc7L,0xc5a9f244d287e5cfL,0xcce103844e82ec39L } }, + /* 47 << 119 */ + { { 0x2a8cb0a56ad833c5L,0xe8fab8b844962dd6L,0x31166fd63ee1dfefL, + 0x3aba85a1e1230449L,0xf9f8da66bd1f502eL,0xe4a72d82e3c17ccaL }, + { 0xfa3d661d6070d587L,0x51d10b73c33ed08aL,0x3b0f515cb29f2d0bL, + 0xd82a11d7e1986e91L,0xcf24f81a2201f05bL,0xa94ec1e0d25f8417L } }, + /* 48 << 119 */ + { { 0xc7807daa081ed51dL,0xb7dfabf0e5d2d963L,0x3f78ae2e80d386d0L, + 0xd66275254bbfd04bL,0x238c8eb76d074f92L,0xfe51ec8a5bc5f9b5L }, + { 0x6ba47430cc03177bL,0xe72efda6400b29e0L,0xb905701becbffe88L, + 0x5c61bdb47cf89933L,0xf1eb3084c914aa6aL,0xa3ead71e8245998bL } }, + /* 49 << 119 */ + { { 0xc58ee3013c7eb5a9L,0x02c177220a1172baL,0x8620118394c7c5b3L, + 0x66292bc4e1668debL,0xf51b48f4caf39937L,0x9cca60f43eaea578L }, + { 0xf8e8004a5c2adccaL,0xce7ceeb1ebf49ac7L,0x36346357371d1c54L, + 0x8799e408d99ff07dL,0x3226181d8c3b2cbfL,0x3b4ff42ba437c2c6L } }, + /* 50 << 119 */ + { { 0x00675ba7f25d364cL,0x7a7f162968d36bdfL,0x35ec468aa9e23f29L, + 0xf797ac502d926e6cL,0x639ba4534b4f4376L,0xd71b430f51ff9519L }, + { 0xb8c439ec2cf5635cL,0x0ce4c8d181980393L,0x4c5362a964123b15L, + 0x6e0421e0ffdcf096L,0x624a855f10d1f914L,0x7d8f3ab7614dcd29L } }, + /* 51 << 119 */ + { { 0x235ba8b565868390L,0x853c9346ea936e81L,0x967ff132700bb25aL, + 0xb26d9778561a136cL,0x8b775c4fe3f7e41dL,0xae8f6b2ebd390b2cL }, + { 0x80959adc4fc7224dL,0xd9c913c12eaccf8cL,0xa9a278c79e96f769L, + 0xbc6be3038f26856dL,0xb039caf295d04cdeL,0x42ba0510a91bf5dcL } }, + /* 52 << 119 */ + { { 0x77870665cfbe0653L,0xab84c4b3523d814dL,0x72839d8897cd2bc0L, + 0xb966e521d25b1476L,0x4255d18451fd86a0L,0xadaf9b76dd54be7aL }, + { 0xada6ff627f285e0bL,0xb76e26f46d42400bL,0x1d9fe676958bee25L, + 0xfcd7be9edb59965cL,0x897a90834bcf6e75L,0x64b26f02aabd21e8L } }, + /* 53 << 119 */ + { { 0xee46626beb1a8ce6L,0x2de20371b672fc49L,0xa0fb11b8bd2d9256L, + 0x5b49f70ac2a8dcd4L,0x98935fc9e5dc0ee3L,0xaddbae423bc00993L }, + { 0xbd0bd9e19207f0e9L,0xe86c5365b393bcdcL,0x32184c832d0a9282L, + 0x8fe996d1df34532eL,0x3b33f151c6f45172L,0xd9def9a7b84545e4L } }, + /* 54 << 119 */ + { { 0xd9219adab3493ce0L,0x971b243a52f09ae5L,0xc16c9bf8e24e3674L, + 0x026d408dce68c7cdL,0xf9b33dd9358209e3L,0x02d0595df3b2a206L }, + { 0xbf99427160d15640L,0x6da7a04e15b5466aL,0x03aa4ed81cadb50dL, + 0x1548f029129a4253L,0x41741f7eb842865aL,0x859fe0a4a3f88c98L } }, + /* 55 << 119 */ + { { 0x66bb66f5f56b17ccL,0xdce0bf2cba8958f8L,0xd814318f9ff85781L, + 0x41dce823edd1ad96L,0x71bb754bb59c6580L,0x9c5efb70de594c3bL }, + { 0xf7b4ce5eb0053788L,0x9c26b0342770b6deL,0xe6967b1c8d131e8fL, + 0xfda0efdccf21bf28L,0x2366d47e09cbeeacL,0x62e9ee556629680eL } }, + /* 56 << 119 */ + { { 0xdaff980ff8e06359L,0xb4e0c9e2ead8a883L,0xe3e262023da6e94fL, + 0x37410ed03303c9d6L,0xc044d77b91fb5d82L,0x3559d9ac9ea34d26L }, + { 0xf51a120be21beda5L,0xdd2eef8a3f7befa4L,0x46a26ccd8c79fca1L, + 0x3fb21a682a046572L,0x3624a47adad7c7c9L,0xb9b77ffd4b4174f5L } }, + /* 57 << 119 */ + { { 0xae19a097c9f8c462L,0x477be49917a9d8a9L,0x4a0c41c9d2154c45L, + 0x39313aba1b0d985bL,0x3a70f65cc051b643L,0x0725dabf2d0be160L }, + { 0x29eefc94a69867d4L,0x6acc4cd49d02bce2L,0x0606ab725d4dca50L, + 0xcce81133bfecdcbaL,0x604df3def23b2239L,0xa644b430d20a7529L } }, + /* 58 << 119 */ + { { 0x80de085a05fd7553L,0x4a4ab91eb897566bL,0x33bcd4752f1c173fL, + 0x4e238896c100c013L,0x1c88500dd614b34bL,0x0401c5f6c3ba9e23L }, + { 0x8e8003c4d0af0de5L,0x19b1dfb59d0dcbb9L,0x4a3640a9ebef7ab6L, + 0xedafd65b959b15f6L,0x8092ef7f7fb95821L,0xab8dd52ece2e45d1L } }, + /* 59 << 119 */ + { { 0x43f9a415259ac609L,0xcd6c7aaa0ff5722cL,0xb4689e75b29973caL, + 0x78a43571b690c0acL,0x90dc4ac0a6d3ba1fL,0x38af00a2b773932aL }, + { 0xc13aebdda5e2c9edL,0xfab3a128cf3fed2dL,0xb3b7d29d32eb8ccfL, + 0x9ae1430b6986db5cL,0x35d18edf5365c21eL,0x88f8356e038471ccL } }, + /* 60 << 119 */ + { { 0x45587a7c0794dad2L,0x660833899e9c1cdcL,0x60e7ae4ad242a6b9L, + 0xb5f96b521009df3cL,0xc2d405092e30445aL,0xfa53ba4ec250a29eL }, + { 0xf6a247855d98c6ceL,0xf873653c207dd110L,0x2aebc3c6c634cbd0L, + 0x84b8016ce5cdbafeL,0xbda81fcace00b206L,0x837dc69484b55f2cL } }, + /* 61 << 119 */ + { { 0x61bdc5cab308f1f0L,0x7763c97d8898d3c2L,0xc02324e60434de23L, + 0x7f5c565e4ba696e9L,0x06f27a3e66914b66L,0x64a975ee05052cf5L }, + { 0x98b2f703bb38b14eL,0xbacbd113371e495cL,0xe54451acdd14cc9dL, + 0x8575cfdf87d141b3L,0xbd183a03d0996091L,0x947555579360264cL } }, + /* 62 << 119 */ + { { 0xd1f2d6b8b9cfe6bfL,0x6358810b00073f6fL,0x5fce5993d712106eL, + 0x5ee6b2711c024c91L,0xd0248ff5453db663L,0xd6d81cb2adb835e8L }, + { 0x8696cfecfdfcb4c7L,0x696b7fcb53bc9045L,0xab4d3807dda56981L, + 0x2f9980521e4b943bL,0x8aa76adb166b7f18L,0x6393430152a2d7edL } }, + /* 63 << 119 */ + { { 0xc89db4eb4595ca55L,0x48921c735f1a73a2L,0xfc513c904afe7cbaL, + 0x6d3f988bff8322eeL,0x17d0d4f0e59b7cdcL,0x292f4757f4bb5588L }, + { 0x3037e11151c14623L,0x3e113343dce98277L,0x0be229341e20dc8fL, + 0x0ebd1fbfcd6ff82aL,0x304bd69ed01fa90fL,0x402a457577f1862fL } }, + /* 64 << 119 */ + { { 0xd74d09c10ece13aeL,0x5e59d9e057a6bd95L,0xdb1ccfdce132b940L, + 0xa0e5309c843d3c66L,0x1fbd03a5f9cb3ef4L,0xcdc9ef0a00ea5177L }, + { 0x1ebf5a15cb784a6bL,0xa67382af8a0d109aL,0x3256c37aa0d34d15L, + 0xee40efa50fca43afL,0xc299bbd4b9841bdeL,0x6df68f603bef4a0bL } }, + /* 0 << 126 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 126 */ + { { 0xe01295fdd9d7c50aL,0xaf31b4ea67f8ef0dL,0x2ec9689f9eaf8eb7L, + 0x327b96c5c622acc5L,0xae918f81b2757f2aL,0x74927d684fd6606eL }, + { 0x09bb7fce18574215L,0xfea383bce8e68b72L,0xdf2a6f125fb47511L, + 0xbe88faa18e399520L,0x0166d57e3fb1c3a2L,0x5907ef2fe525f81fL } }, + /* 2 << 126 */ + { { 0xdefe3a7b8a37f660L,0x7898db8c858f5765L,0x7366c26a73d1f9b4L, + 0x35d5d718237ae8b7L,0x3efb20feb4478259L,0xccd0fed7aa545ee3L }, + { 0x750edd05ed22d152L,0x4f8020f9ee20d4c6L,0x16e60f370a9e29dcL, + 0x9cf0a136bfbec7f6L,0xb430a34b2e47e143L,0x2e2560bbc6cdd1a9L } }, + /* 3 << 126 */ + { { 0x799352dae4161a65L,0xe5cf7ad856253ce6L,0xf606bf796de32775L, + 0xddc0f3a357fce8dbL,0x1075fc2316cf4a47L,0x078f0e04b27c5ad8L }, + { 0x9fc477953f7100aaL,0x3ac489254673ffa2L,0xb8263f42f9cd8348L, + 0x5bdfde3068cc92d5L,0x2250927b1ac37f9cL,0x26ec8328b33da359L } }, + /* 4 << 126 */ + { { 0xf186d6bcc88d568aL,0x872bc4c7528535ddL,0xc9e7432edfe64dc3L, + 0xd9fc4832d795ea57L,0xf4ffdb81c845af2bL,0x66d7e7882b670517L }, + { 0xa7c1be04d7b7a1c6L,0xbed88479d5b2a249L,0x62ff8aba03f2ef6dL, + 0x60ecaac420dc701dL,0x9f4b559f4ff10119L,0x0582c9313cd54fd0L } }, + /* 5 << 126 */ + { { 0xea9da8f012bbaeb6L,0x3fba06b18c9f8360L,0xc11bd7abb28c0ac3L, + 0x1e05af2faa8a01bdL,0xae1e99c5f000b1c3L,0x93ee806453d79930L }, + { 0x5728089e4c4f5513L,0x755351f3b1f70b76L,0x187ac651675f77efL, + 0x5cf7bfb553067d84L,0x629290838174b5c0L,0x720e20798d5be74dL } }, + /* 6 << 126 */ + { { 0xab8cc09ff5eb9ad1L,0x97a4de76132edbfeL,0xa2e11c548baf6347L, + 0xcee54229683cfcf6L,0xe1e993b8dcfc6555L,0x333bf16abe9df066L }, + { 0x5207e093060d62dfL,0xfa32324d69b0f5faL,0xef16fbcfd3243d2dL, + 0x540a2e59f04f8e45L,0xb5e70f9c48317bbaL,0x00dbe9b25b35baa1L } }, + /* 7 << 126 */ + { { 0x0eaed675ebb512eeL,0x347e0756058efbd5L,0xadf792ca296d3d47L, + 0x57f00c0a4654d012L,0xa1e08a04bccc5803L,0x610677f05b2f11d1L }, + { 0x0d9393d7b81acfd2L,0xb258e1570587c219L,0x372a1857b4ceba47L, + 0xe1ce8bb53ecc1c5dL,0x7efdf301922cecd0L,0xcab8cb170d8aa653L } }, + /* 8 << 126 */ + { { 0x31954a5679d05497L,0xc12520b6fe76d4d8L,0x8c433ec5e37ef1d2L, + 0xcd0f203575bc3b66L,0x3723f145249cd98bL,0x1356e0d2ea3b42a3L }, + { 0xf607fee0f174c7b5L,0x318afc5e0127be39L,0xd47b5d74cea5417fL, + 0x6891940a10fca22bL,0x5cea41332b635e8bL,0x93db2ed6b5934fefL } }, + /* 9 << 126 */ + { { 0xf87cfaaac8972b7dL,0x2b8f9874e090800fL,0xdb88cd4f52efde36L, + 0x7b977f6e80776de8L,0xd047fc8ffb4b19c4L,0x33f3e43578b8135fL }, + { 0xb4cdb352da33eff8L,0x217f9e2deb89d325L,0x1bb5a004c99feec5L, + 0x98ce5a7fdb45c845L,0x458904681d87e964L,0xb9253873d151ad80L } }, + /* 10 << 126 */ + { { 0x5d7c767de39edca9L,0xe4a700e7a7f8de0cL,0x5816e1f93c9eec33L, + 0xa975c933d32fe465L,0x979beff968466a5eL,0xe308c135cc067721L }, + { 0xe0e733b41839b88dL,0xda3e3e6c298dc2ebL,0x414c3f0e8fb70e3eL, + 0x5ebaefa7ed7ca91cL,0x5c283310ae3b0f3eL,0x20353d5df3b1d44eL } }, + /* 11 << 126 */ + { { 0xd50767a9790325feL,0xe2ceddb9358c50eeL,0x60be64bdbbf03ae5L, + 0xe70c7e90f053328fL,0x6ba6af9e51543f0aL,0x470941f3b413e069L }, + { 0x0b569fd4ddf63d13L,0xf94b22634a2125d6L,0xaa45ab62a5c1acedL, + 0x2b797175defa5a30L,0x3eb30067ead1d440L,0xcadb54e90b691af2L } }, + /* 12 << 126 */ + { { 0x365a4a431630b133L,0x9ecef631068d7863L,0xa330c8b4b7205a6fL, + 0x4858eab357df815cL,0x6e522afaf1a92674L,0xa7cff3d9f41365d7L }, + { 0x00dd34615a0e4626L,0xa695feff48f9d094L,0xf427103f7c082301L, + 0x14a2a1876b092b71L,0x210f632130037a33L,0x21cca09639340e14L } }, + /* 13 << 126 */ + { { 0x58355ba0f60ad6c1L,0xc63fbcff56022afaL,0xa6a770d54e7ef19fL, + 0xf42b2024a09e9378L,0x153aa3200330f774L,0x268aaee55dc02c97L }, + { 0xa7e13b42828f7ab7L,0xc0ccce09c303bfcaL,0x23169daae3ccb6ddL, + 0xf7f763fd786774e9L,0xb15a5ef150021488L,0x52f408fd5f3ea885L } }, + /* 14 << 126 */ + { { 0x53e84021177346c2L,0x4ee451dde20af475L,0xd7642453c14f393eL, + 0x7eaa215331662516L,0x1217a1b4c1d486c9L,0x7d32427569860f20L }, + { 0x3813c95f14c2837eL,0xb8f0713d4e0c056aL,0x398c218cf6dec37bL, + 0x5bfa2eefa4ad1eedL,0x53cb0fd29f97a05dL,0x59fa132f6a9f492bL } }, + /* 15 << 126 */ + { { 0x6d5dff381fc2c16aL,0x5dec7ae2b1fe149eL,0xa9eed62c85088ceaL, + 0x5878fdf7996174baL,0x2cf65bb935517a73L,0x80844bcacff96d13L }, + { 0x0f55c8bfed53f49dL,0x35815fb0fbd8cec6L,0x23e7d5c53b6fa7d9L, + 0x3ee04c0146ce1733L,0x180e25553f5c4a27L,0x61263ea7280e6363L } }, + /* 16 << 126 */ + { { 0xb1f4fead41b959b5L,0x6edb53a9e71890c0L,0x48b47efe2e28aa2aL, + 0x70dad2e9b3151d67L,0x87a8178b436a3460L,0x0f86f9f5801f7af7L }, + { 0xfab462e3a982fc14L,0xe29126bacb03e978L,0xb4696b3fe6681282L, + 0x3bd9910a6a3fdc1dL,0x4409128449e37dacL,0x3b4bfabccf605fb3L } }, + /* 17 << 126 */ + { { 0x605fae7ece9d1372L,0xb2623a79f9b7e06eL,0xfab9b2742d37357eL, + 0xffdf9246461417f3L,0xc04b15d7bdd0e922L,0x767bcee54b2dbc0eL }, + { 0x74c4ea4ed45efc88L,0x32d3d85491a534a8L,0x88967078554b2691L, + 0xe8256015e336a410L,0x166469624b9f978bL,0xb433f06ca104f01fL } }, + /* 18 << 126 */ + { { 0x8906d815457e1e82L,0x96abb1aa4c8a2c68L,0x2e63f37927ab2fb1L, + 0xe092e15f5446dfaaL,0xa3a3f0926615c65cL,0x8b31116747c3f259L }, + { 0xfe2038782e5c658cL,0x38903cf526215773L,0x0039fca7237f1bd4L, + 0x75dbcc016058ff17L,0x67ee6226a65aeb9eL,0x96999fa75cedcba5L } }, + /* 19 << 126 */ + { { 0x04c6fd475ac4d191L,0x0067e474c825a897L,0x4a37c931404810c5L, + 0x072d30e5c4a56380L,0xbaf3428dc897ba23L,0x9899935b53724382L }, + { 0xda5cc13ff4d41a62L,0x063047a0c6271baaL,0x49790bdc5cf48302L, + 0xd8c34e5384c5a9abL,0x6cf28e83db5bc36aL,0x430dbb1497da9d42L } }, + /* 20 << 126 */ + { { 0x59470e49c37acc2eL,0xc9e0f73611b85596L,0x47613c1e0fb30eccL, + 0x1fbeffa3b62892f1L,0xddfeef49f8eefa16L,0x6f82acd9daeff719L }, + { 0xff1872cdacb41007L,0x06fe556c82d64c6dL,0x52a63a387695218aL, + 0xa0d413a720802b88L,0x233f1f3118f4a473L,0x22ef7d6fc9d7da4aL } }, + /* 21 << 126 */ + { { 0xeba1db6910dad9abL,0xddb62dacde3a5a42L,0x209c472cfdf5ad86L, + 0x14a7ee4b37214540L,0xcaf70ce08339c9dfL,0xa95744554eb9189bL }, + { 0x90d7f241e9b39189L,0xf5edfd09af7f3eddL,0xc9a3444deb7ed52aL, + 0x30d9e2f80085d9d1L,0xeb412daa4dc24fefL,0x55c0000b27786649L } }, + /* 22 << 126 */ + { { 0xa9f34fa9518118e5L,0x430db0a51a22e790L,0x64b443a5d5a16ca1L, + 0xaa3b64f4d8adbe45L,0xb49435fae0f0873aL,0xb8d67ce4a635d1e3L }, + { 0xad843f8a8a612b29L,0xa416ec7fd84a210aL,0x8b4dc6930984b23fL, + 0x29a1b71b24640dcfL,0x8f2d7507911892adL,0x0ce384105bd4d518L } }, + /* 23 << 126 */ + { { 0x1e1bef926c42e1bcL,0x91259dd60e04d449L,0xc029961e8875d346L, + 0xfde51012a9e38f43L,0xdeaa1dc18892643aL,0x67e3b913217e08d8L }, + { 0x889a28c269b92b7eL,0x004c0f87b7446c21L,0xea812f67a2f98e77L, + 0x42fc7bbe22c40b8cL,0x5e7f5f5a8722e381L,0xf8f209d932099e41L } }, + /* 24 << 126 */ + { { 0x867379134a2965f5L,0x34724dcde67b3546L,0x2efe185ee92c712dL, + 0x8b908f86c201e327L,0x3ab5528894f6b078L,0xb9b2b784ce0a5bf3L }, + { 0x5eab37ac879f6a41L,0x74271f672f2360f3L,0xf3a3edff304f1cf9L, + 0x8992ecd8f6fd3e90L,0xff24d7c69f16e5edL,0x0844ab25def9a5c4L } }, + /* 25 << 126 */ + { { 0x35cbf2191e14f235L,0x9ef33f3c4cdc1b46L,0xfd5cedd0299f7f13L, + 0xf57b9bbf99379e17L,0xae25d3e3cd3d59a8L,0x72f9fc84f58cb31eL }, + { 0x87950fd84c94b63bL,0x15b52b4f7a4560a8L,0x382d36ec943e44baL, + 0x567ce2e9337b0f11L,0x8136e9ce2fa44901L,0x7e43a7289b15eeaeL } }, + /* 26 << 126 */ + { { 0xd1c8ed8814fb95f4L,0xc302e0aa29602659L,0x67abcce005cd67baL, + 0x7a234cc022f8ae25L,0x7074face39f44e4fL,0x84a08afc7a9d3fb2L }, + { 0xfd149c88f56c1f32L,0x5b12cc15219e494aL,0x242fc50c9ea3c0e3L, + 0x196cdba555b23034L,0xfd8cfa5e87b75206L,0x915e706488d55f47L } }, + /* 27 << 126 */ + { { 0xb59480ba876145beL,0xd8f8fbbe8e1075ddL,0x0ba10292b5d9baf0L, + 0x3a4b7f65e39a8754L,0x1b3a044c0f3c6520L,0x6b8b3397b1dff4f8L }, + { 0x40cef2285c182eb3L,0xbef82aec1b1cb92fL,0x5c4d2bfc2a97c5dfL, + 0x41d2a046536ad077L,0x94ef34a8c497505dL,0x14e9aef48e0b35ffL } }, + /* 28 << 126 */ + { { 0x2edaaaaaacaf1f3fL,0x9e3af72c80ebcc10L,0x3542fc42bcb1618fL, + 0x6c04ec246709d851L,0x5fe9768ea9af4ce0L,0xe739d50eeb6ebe2eL }, + { 0x7b7da4ac876586e0L,0xb0869f1d64f5f956L,0x7f691c51fd563c80L, + 0xea990d6926c775e1L,0x2cd96f1321b58889L,0xbc8074720f1aac2cL } }, + /* 29 << 126 */ + { { 0x8e1fa5f8eb3283cdL,0x0107a3ba20e69342L,0xf99a511cb045b8dfL, + 0x172d0c8933b51876L,0xb11efc2b9636d0f9L,0x16b2197c41570483L }, + { 0x49df27edacfdfd1aL,0xd9d2cedc366b9b28L,0x0289a75cab028c0fL, + 0x522f567a4879464fL,0x3313728225f64030L,0xfa28cb1558d6753fL } }, + /* 30 << 126 */ + { { 0xe5252210c6cd33f0L,0x6ba7f51f3f085202L,0xd2a87fb38f52e312L, + 0xa5e082cff25f35efL,0x786a93c2b9df2f20L,0x68c7e1299a19bf27L }, + { 0x13a971ab8d710915L,0x3ca4f8c6939443c6L,0x8554699c70522446L, + 0xdf42b7768e14e6bcL,0xc7969fa5f7f3dadeL,0x135b6b77350ded88L } }, + /* 31 << 126 */ + { { 0x39e54aa472546076L,0xc0003f7f13e312beL,0x71106a4ffea91274L, + 0x3868f957819851cfL,0x713b96e75c85bbc6L,0xfda8c2df610403a8L }, + { 0x0ea806c3a008cf78L,0x0ef9708353c0d1bdL,0x536950211e592838L, + 0xea3773d5e9023982L,0x6eee3c0d4195754cL,0x95df7b568c4bead3L } }, + /* 32 << 126 */ + { { 0x57edf71edf9a9f18L,0xbf834240627a0b79L,0xb37aba1aa6934160L, + 0xd45b3d2c5e639a54L,0x62c6b9ad70bce957L,0x16bc35a75d7e87f3L }, + { 0xb021698266b4a982L,0xb56050dd0e51c9bcL,0x15aa692b478e4b91L, + 0xdd67cf29be3fe25aL,0xf1ef75b006bdd4a8L,0xf71a285b41df627aL } }, + /* 33 << 126 */ + { { 0xba6be58993032120L,0xea6dd691db99740eL,0xad8679463154648dL, + 0xd1a36f4c28c0668cL,0x09a28c234dd76e88L,0x93fef0c7dc665bb7L }, + { 0xa78dfeb4860a0016L,0x06d2f868e21a9e02L,0x333a25a38486ade7L, + 0x12aa13130e398a80L,0x04a44a5848d5b3e3L,0xe59293d47a7ec12eL } }, + /* 34 << 126 */ + { { 0x6cdfb5faea2c1632L,0x6799cfcd7865f931L,0x4e1e5d25bf420a7cL, + 0x7d4597db05d22ddaL,0x7548db12fceda1e1L,0xb4523ccdcb473578L }, + { 0x3d8dbad0ff889f03L,0xc591bb1118a9a222L,0xfac2b914a2cfcc57L, + 0xbb67601abec9d9bfL,0x18dff42ceb55218dL,0xb36ef9ba7d2b6320L } }, + /* 35 << 126 */ + { { 0x5b007ad1f3edf67dL,0xfaee9cada25fcfafL,0x18fc784a4d62e5c2L, + 0x98deda878acb5f8eL,0xe9cfd10a6f888d8fL,0xbb0d729b053db2efL }, + { 0x7b09fa4f2aecece4L,0x3f72187cd4c44cc3L,0xf646aba05b8175a5L, + 0xf213caeba5686ca7L,0xf5ce777badc5d40dL,0x15ff85d660eb9357L } }, + /* 36 << 126 */ + { { 0xcdd18aee24e6df19L,0xa08ab968bbb3303eL,0xd5eb039cbab4f1a3L, + 0x040d03a8fa7a48d1L,0x767c0ed23d66628bL,0x0c6bd388b1a6809aL }, + { 0x793aff3f029eeb91L,0x6db32d13bca798a8L,0x6aef5c1cc3816cf7L, + 0xcfb25ea45fd2cd2aL,0x0715a7899f8e3312L,0x4a9ad4782a6b1a6bL } }, + /* 37 << 126 */ + { { 0xa9f360a5d134c919L,0x10dba223dcfd0715L,0x7444b191dc9b4394L, + 0x9a16a971e2f288e0L,0x0d05c511f6a49999L,0xca34eae26b65e956L }, + { 0x692febc418a83b76L,0xf3468c7b0b5f3511L,0xd8d3ce48b8e1ed80L, + 0xbe8c5c302a6de231L,0x9c0468b74e680d8bL,0x773ebb63f57b88d3L } }, + /* 38 << 126 */ + { { 0x9c2c33a5b726729dL,0xa86ab4ea5db2af56L,0xe987c5e3b0a36ffeL, + 0xa6dba84da5fe8bdaL,0xe1fefa4b8ff617a5L,0x561cdb88a91ad714L }, + { 0xeb58f7fce145ddc0L,0x7b0e560a29c5ad50L,0xf8d6626593da0e76L, + 0x7769b479db39fb92L,0x9149f1e3a3c49033L,0xb706057f3ac49c35L } }, + /* 39 << 126 */ + { { 0xa678ba3fa527d157L,0x922aab268856a8b2L,0x936d3e85690b4771L, + 0xed78dccee114e472L,0x9694ccb1d315fbc1L,0x8b1cf4482822d968L }, + { 0x336e670c4aca5441L,0xece24fb58f0e2824L,0x28d1578d05b758adL, + 0x0a1be96a40c3f019L,0xed1586e30b659cd6L,0xdef180009f860dd6L } }, + /* 40 << 126 */ + { { 0xc2885af90fe0f372L,0x2c756bef5fa6b808L,0x52b7f7b6068926bfL, + 0xc9399c1ddb143b68L,0x0e77c689e4c61211L,0x7d01e37f15ad7fa0L }, + { 0x712fc61f188b2a01L,0x103685ec55a4100eL,0x721f9c02e5fdce96L, + 0x61c8a0c5e784397bL,0x34d478351c686ed2L,0xc697c89cd155bbe9L } }, + /* 41 << 126 */ + { { 0xc26dbc34f06a2cffL,0x4f10297631a80712L,0x758e33eda7c54effL, + 0x44b5e4ff3682d103L,0xef05034722a05e6cL,0x9170365c48ff372fL }, + { 0xee49b61d66a15a71L,0xb5fd487995c2045dL,0x5940487160ad67caL, + 0xdcd2d5f586388c40L,0x0b41a8e54cbd1f71L,0x8152c17040236ae0L } }, + /* 42 << 126 */ + { { 0xf05b99d0995e9809L,0x036248a70295fceaL,0x7b70cf8f558e6ec4L, + 0xe882639c7c48ce34L,0x4cc86feaf4f47d38L,0x976799cf6d81aef1L }, + { 0xdb202bfe8043cb43L,0x4c761cc5cef4f017L,0xe124bbc161f0c89eL, + 0x77d1cbf55b5a3d20L,0x26e549fcff346940L,0xc6040a4c2325466bL } }, + /* 43 << 126 */ + { { 0x1ed4d238e940e32aL,0x29d99c20139efcd6L,0x4cb7ef50c172b412L, + 0x8a9c438931957225L,0x5d8872af60be4612L,0x7bffbb1be7e79e0eL }, + { 0x75bd89c1fc7d4e66L,0x723f9ae86bcc0379L,0x88f673b599c1b827L, + 0x8d45d139ecf5148fL,0xf12e605ff97ad1e0L,0x567dec052f09c370L } }, + /* 44 << 126 */ + { { 0xfb33b987b0be5055L,0x9864f903bcce94dbL,0x99b8da36aea9d09bL, + 0x19e326113b622d3dL,0x6abde501dc38f903L,0xb1fe3f1867cb2161L }, + { 0xb053ec831e08cd7cL,0xba503b563298d32fL,0x220e98c8c2a79e86L, + 0x66ac99511e1cba68L,0xf9520e1e644ab527L,0x3f222b9b4eb8abf3L } }, + /* 45 << 126 */ + { { 0xae0cf2ff705cfc45L,0xf9d5dfb65a0449b1L,0xd0300b2cd4697fe0L, + 0x4ac80d7e4dc665b0L,0x84fbd38d72c1677cL,0xea8306f08e683a0cL }, + { 0xe2381e65a469e337L,0x36b565d0b3ec173fL,0xc67689c700f3007aL, + 0x9f0108992abcc81fL,0x867a5f8dbb9bf584L,0xef789cdd5a436b38L } }, + /* 46 << 126 */ + { { 0xf8cdc9ecee11fa1bL,0xa78c73ed4c90edb9L,0xf6703453bbbddb82L, + 0xd268b4e23020e294L,0x214cdd54958eb8cdL,0x2acbd31d4d7214e5L }, + { 0xf7c60c89cc733351L,0xb8c5cc642fa201fdL,0xaae1ca7f4c2acb10L, + 0xf7e33be56d7f598fL,0x982c012fd920c3c8L,0xaa98a69b86751ef1L } }, + /* 47 << 126 */ + { { 0xf5f548eb915ed5cdL,0x657ca09ce30f448bL,0x8750c4a44a30850dL, + 0x1b329c4108edb075L,0x8c261df8ccbcdaeeL,0xa81720bbedd44638L }, + { 0x602fc21f0b91ee05L,0x6241265db7e8bc28L,0x1daefe5b106ac444L, + 0x93fe5bd42c9deae2L,0xedc229e17f1ba35cL,0xd99244977e0da1f9L } }, + /* 48 << 126 */ + { { 0x3176a43ab7a3ce87L,0x9fa09e975f130e73L,0x971cc37b9368e156L, + 0x2cabf535b8981792L,0xaec2862e4d0f0bc0L,0xa1a48c183ce8c100L }, + { 0x288f4e694af2eae9L,0x778845f21f9339bdL,0x1ef5fdfd17dfaa6aL, + 0xc784117e3483a6fcL,0xe8c82f05f3c5c19eL,0xf39b3c1d1da87ab6L } }, + /* 49 << 126 */ + { { 0xa2539d4cc4ac73e9L,0x0308f91891488ba1L,0xa3e72f4459fae934L, + 0xb6bbcc37f8c9c402L,0x345a2debc6edee3eL,0x0352f023b0df87b5L }, + { 0x67c9e7b8818c4f8dL,0x3a8714cc70f44977L,0x37b96e1295066bfaL, + 0x617d9737c95d7f70L,0x60bb06ef759a360aL,0x97689b3f34f59fe1L } }, + /* 50 << 126 */ + { { 0x17d0667fb2dd1febL,0xbfb92fe48862b2ccL,0xcfa0c8e9d5438a69L, + 0x7bdbd4b1d9cf9ef5L,0x7616acddf373c87eL,0x0603d2b0cf8fd5b6L }, + { 0x6a80f25d46e31aacL,0xea8c0ad0fd424755L,0x9e2e5a5b3ffd5a2fL, + 0x8882d271f3b143caL,0xe6fc9ad7904e1740L,0x98d1620af428ad20L } }, + /* 51 << 126 */ + { { 0xc8c991a63292054aL,0xc90b11618ce93455L,0xdfa32238e200d1c6L, + 0xa9c578d5303004b3L,0x9dd2c3881609e5f8L,0x068ec35d24b69108L }, + { 0x47e8183b2d1a3b7fL,0x6200d70efe3db580L,0x76012f3fafc089b0L, + 0xba06dbf4bddea8a2L,0xd83b4af5da01a49bL,0xa3d4334ce16e87e6L } }, + /* 52 << 126 */ + { { 0xb2fff4035b43e58fL,0xe80bd5740727be41L,0x048a59cbf9b52541L, + 0xb79084e7f38d0b47L,0x763b0c95938935d7L,0x7cfc6180336b8735L }, + { 0x118d2a6f929b0200L,0x7e5789775a31948cL,0x9085999326009509L, + 0x330533a33ad633c6L,0x28bdb910733f4c3eL,0x82c88f148fdca27cL } }, + /* 53 << 126 */ + { { 0x1c346bb04ef444e7L,0x40a50060e6c22e57L,0x5eb02aa6c7a773b4L, + 0xd748a0a0d23b190eL,0xb6ff7f02cfedb7dfL,0x3f8fb35b30f8bb4aL }, + { 0x245b1c232dc31174L,0xa1e156579af25f59L,0x1ad1a2315e2393daL, + 0x9430ed2dfd7c7073L,0xc4161d4f580fbc0fL,0xa2bebd3fa0f1dadcL } }, + /* 54 << 126 */ + { { 0xace743b6baff35ebL,0x84ac3ce8ac6f38f8L,0x81d41297106b44f5L, + 0x33f6bbbbaed20aa3L,0xae4dd66ceb420ee5L,0x87553aac994f0777L }, + { 0x26275ebff1e3647dL,0x3b574c4fd9eeb474L,0x58fe2a16929721c5L, + 0x748480df932030d0L,0x3a30032641bb5f68L,0x0797fad92c06d1adL } }, + /* 55 << 126 */ + { { 0x65356242c7caa811L,0x780fe23f4506bbd7L,0xa741a51042407c02L, + 0xb8ccd27f5ef9eac3L,0x137f4a573ecf5766L,0xd495be0d15936fdbL }, + { 0x5a419656109c93f3L,0xd2f7b65dcb12affdL,0x2305a070ff830421L, + 0x6d00f1e9684d5a6fL,0x3de9d1de91aa391fL,0x0b5148c10acb6de9L } }, + /* 56 << 126 */ + { { 0x209fa6e68ca7ec95L,0x17808b0c107a1047L,0x99bbeb5edfd270cbL, + 0xe3d57c1dc25e2d6eL,0xb90b0c107ba1237aL,0xa7e1b8dc4a0d6856L }, + { 0x97d5b46136a9a07eL,0x931251e9125ea29cL,0x4177fd10fc8868a8L, + 0x1d3538b7b7cdcdf4L,0x889008c8ed3ff9dfL,0x30573ad2229b9413L } }, + /* 57 << 126 */ + { { 0x11596662924d413fL,0xe797d0a70e5d7bf1L,0xaa05dcd28452ee62L, + 0x6e10e77f5d5ddf1cL,0x46b72cda5fbd184aL,0x3adc1edb5b25c0c6L }, + { 0x640de5b05c732e3aL,0xa7d4f0f5c6739747L,0xbc11978d1426527cL, + 0x979276eccbee0053L,0xc44347a7304e8811L,0x016c01e11f5ececdL } }, + /* 58 << 126 */ + { { 0x78b2f1a15ee57666L,0x28060d1576a2c09eL,0xaf0cb38df632a5deL, + 0x93ce93eea284cd43L,0xe3670d0af35dc1f5L,0x3b8deea527971072L }, + { 0x3b88b1158eea4303L,0x43ff3b22aabde038L,0x8d69e180c813d623L, + 0x218f5b853aa7a08eL,0x6ee1544adf74f239L,0x0d7abf20fb8772f7L } }, + /* 59 << 126 */ + { { 0x1d881d4eb7716840L,0xdf83a03b86bdef07L,0xd534c4e4dc7ee69bL, + 0x1169f1cc6e264c79L,0x85c812d1b7690d17L,0xcc3164adec5f2ed1L }, + { 0xb91a14180674e87eL,0x5dfaa279969188fbL,0x434acad5e242b969L, + 0xa51b5c63751c4e51L,0xaa9089b7874f9aa2L,0x8758f9e51b8397e5L } }, + /* 60 << 126 */ + { { 0x422ad88e57fd35feL,0xd4564b96b99a11cbL,0x78939992238baebbL, + 0xe66ddcaf4b30a709L,0x00873d5f7812ea50L,0x7317f9dc6784aabcL }, + { 0xf94afbdbe0608ba4L,0xfff893618896d745L,0xa3348af5cad62808L, + 0x13ed4507f349f51bL,0xa73d4bec1186324eL,0xf0b48189a20022d2L } }, + /* 61 << 126 */ + { { 0x87d117858b8efa4cL,0x724439d6e9c2ee6aL,0x33ab2a03606fa0c8L, + 0x6ede5b55f9779d87L,0x858b7dd0759445cdL,0x33683c817a5ef23aL }, + { 0x0f093175221c3443L,0xedcf2aaf889195a5L,0x9f189ebc814abec7L, + 0x6a64999c40235b9eL,0xf98dc212984438ebL,0x97e2d102ba86e7caL } }, + /* 62 << 126 */ + { { 0x337b9cbce3db0718L,0x1f2f55833d1796feL,0xa522b76f68c2a69dL, + 0x4c1da7cf5375cb22L,0x690a2e7f50bb0d7fL,0xa734d4756689b6eaL }, + { 0x918592d5867ca0a3L,0x64d1c147c4d15e28L,0x4d8c3e22656f8219L, + 0x5e028bb2170f59c3L,0x41e8b84449875858L,0x1d928cc90c599178L } }, + /* 63 << 126 */ + { { 0x736dee2cf44db09cL,0xfb5035c07257b4e5L,0x3e3a7bf6bf0b702aL, + 0x4910a0165f257c0fL,0xd80b891d98437b4eL,0xf9e55d55076d8587L }, + { 0x4e4ed7a79b4fcf4cL,0xaaf417f5581acfe3L,0xb1ae2a7ca3b3f920L, + 0xa666bb6263ee4781L,0x2fba297e63684f04L,0xd6e662658d83bd6bL } }, + /* 64 << 126 */ + { { 0xa58a27c58a541be6L,0xaf66949954fd7683L,0x2431826600079a25L, + 0x113f6fcf2606caf5L,0xf6ff2be316cb28c8L,0x8f7fc60e3c17caa6L }, + { 0x8ea577e07d35e26cL,0xc3e744c0f0628903L,0x4b28eff4592a57eeL, + 0x76e1f87c5e3f67b2L,0x40d7a676fb008902L,0x68a9dc764b6e6b7eL } }, + /* 0 << 133 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 133 */ + { { 0x76e2751a12575913L,0x2c6059914a5f8c4aL,0x58322dfb71fba662L, + 0x228aec085e0886afL,0x8d83b6276aee544cL,0x338f5fb6e29f9639L }, + { 0x1ba4cfe0bf5e19faL,0x2eea84c5b9e4f8f6L,0x7e0eed58cee95d92L, + 0x2d29282abe535540L,0x866638b607a9a1f4L,0x915999776ab8dc82L } }, + /* 2 << 133 */ + { { 0xa16c79cfaf4d260bL,0xfe853f6cfab3c3c8L,0xb8bd6aa0c2f47e68L, + 0x277d590f2c9b4914L,0xb6d1c810097242a8L,0xcf2f3d8e45f75512L }, + { 0x2176162b74a20c3bL,0xeee8bcb82b2bcddaL,0xfcf8c0d1a503aee7L, + 0x5d1f94a57af4dd78L,0x8f0bc1a62ab43be4L,0xd22dbf16ba9e071bL } }, + /* 3 << 133 */ + { { 0xbf87f30e3790b47cL,0xd3d3f1e25ab52ae8L,0xd5fd32bd50ec0ba3L, + 0x7de8fe0ae60d1e72L,0x52d77fe0e14ff2d3L,0x9b6937db55ca47e4L }, + { 0x39e3d19f53e94fa3L,0x8d962a4fbd7827e4L,0x3bd70c7afe92c6cfL, + 0xa3fbc06869a82904L,0xe263f00ed96d1d9eL,0xe6c9781f75c0c24bL } }, + /* 4 << 133 */ + { { 0x705bfe37b4e814b3L,0x22f0de61702013c6L,0x811e77a9bc456797L, + 0x4f52c4e617081a2fL,0x87405d819fe1640eL,0x53fa82b7707711d7L }, + { 0xdc6fff830ee4aea6L,0x8413e22ffd60373dL,0x0ecb66bea9cf3eadL, + 0x7418372e87139b8bL,0x6aaccf295e42b4d7L,0xb6dc592531fc932eL } }, + /* 5 << 133 */ + { { 0xf1c8d00de460fe00L,0x5692bfee528da7c6L,0x9e4dd700ac8620dfL, + 0xcc43e73d9d6fe740L,0xc94060d3e76dcba2L,0xfcdf8ba6d398914fL }, + { 0x540942e7502f8587L,0x5def85040de058fbL,0x63e0c7855292b0c8L, + 0xe90405282e558983L,0xe25727a16baf4a31L,0xb9bf28f0acf64d7cL } }, + /* 6 << 133 */ + { { 0xc7c8364f09d26382L,0xe16988737bf32d9fL,0x97bac2feb726391cL, + 0x521426364a7c0b57L,0xe3e596482cdec222L,0x4ee7238cf44e0a98L }, + { 0xa6d05a21f61cfea8L,0xa1059fb7efe6a26fL,0x482a65b342416fa4L, + 0xdc5727e1c71e7a94L,0xe6b0fb6ec4767f1eL,0x3d0d626d6510599eL } }, + /* 7 << 133 */ + { { 0x59f5df1b2a8f9f78L,0x6bb161d992257e60L,0x2cf060beb7b2eb14L, + 0x98e72799aec169b0L,0xdde683927045fdb9L,0xee5e0aaf461b27e8L }, + { 0x80250c744c0ee047L,0xdd3881f597f0677bL,0x0ea56921a4459b6cL, + 0xf7793cee26df8d7dL,0x33bfa09be42d1913L,0x9f0636f74ccf5139L } }, + /* 8 << 133 */ + { { 0xfa3b4c8eb88ee8f9L,0x1f288e60b521ab57L,0x06aa39562e8c4d8cL, + 0x4981c3e5cf89935bL,0xbdbd0c4745fa071eL,0xa78f831c496073beL }, + { 0x09a72986a4e5c001L,0xac527731709cb728L,0x9a64b5b3988f2781L, + 0x6ac9440d73b1719dL,0x58ad54c7e3d2e807L,0x1c1574488f06742bL } }, + /* 9 << 133 */ + { { 0x3220a099a5e437e6L,0x11a1b1734dc5bdaeL,0x1ad9e736b64c9b8bL, + 0x82b6a3d4ce40acadL,0x54e1eef8915aaa8aL,0xff19be481f3a1f54L }, + { 0xadc4c5250b64a2b6L,0x6637bc8e12caf63dL,0x970d08b01206a661L, + 0x97c9b9bde57cf6c2L,0x228ee4712b89b7b7L,0xfeed19ca837cb79fL } }, + /* 10 << 133 */ + { { 0xcd36c981a816f4d4L,0xc99316c27712a72bL,0xd32cb20339e671aeL, + 0x79ff1889f67f6215L,0xf9fe7448cd08e91eL,0xdc9b277776f3e605L }, + { 0x8af30c2e7c1609a6L,0xed3224a3e54cdd0bL,0xe73f56ded1dea6acL, + 0xb836eb783e37a390L,0x9f0dcdb2c78a0510L,0xc37e67a39e6109f0L } }, + /* 11 << 133 */ + { { 0xab419eb852e0d552L,0x86c76ef8ae3d06ebL,0x219662b4f7c6342fL, + 0x2820299e548f6717L,0xc4d0d47a8a2aeebaL,0x4c98069895536593L }, + { 0x3644e55ff42cd505L,0xe109b64ae47e0b0bL,0x91f520a6c89788aeL, + 0x35f6dc577699087aL,0x3484f5b6b77deb8dL,0xc22a63a47f3c09e6L } }, + /* 12 << 133 */ + { { 0x6b5b7b2a75c953b2L,0x927ed77ca7f1cd5bL,0x2e8c53994cba0e5eL, + 0x03aeb14a3f4a941bL,0xedbad9a0a1385c8aL,0x925a49c167fd2258L }, + { 0xe7e368ee3365ffedL,0xcc4aad2dd106eb87L,0x4ce908daa980b53bL, + 0xd3f4954016929ac8L,0x613c804dd5c05c32L,0xa42290ccd7973344L } }, + /* 13 << 133 */ + { { 0xe7437974c464c24fL,0x70c04156d36bdfecL,0xd94c80fcb2d5d96fL, + 0x4a1fcf19d2cfea9cL,0x443478592f6df796L,0x0c908d0159743bd2L }, + { 0x78949087d165a62bL,0x6c3f9021632f4e1cL,0x3917b925a94bb004L, + 0xe153ef092b3f87e3L,0x6aee1027ea706338L,0x953ab2959733bd02L } }, + /* 14 << 133 */ + { { 0xad49cad49855d008L,0x23442cf94b273d85L,0x3a3c8752e3dd8f65L, + 0x0ca5d24bedf84ed0L,0x3d0580938b4f8f96L,0x1cea59acf9b9ae03L }, + { 0xf17cbbe23a06567eL,0x49cf5294f090338fL,0xcf8cbe0da93562c1L, + 0x66683f21b986b71cL,0x3c96750cc87c9e10L,0x38e62db63dcf2f32L } }, + /* 15 << 133 */ + { { 0x807a519047f99946L,0x49e03dcf01615a37L,0xe813287c99590bf6L, + 0xc9caf30ddb62835cL,0x0733c49d4df78781L,0x4fde30fd4815d3adL }, + { 0x2809b853f9a2610dL,0xf2b139b9dc050142L,0x52a40a413c23a4edL, + 0x9333086b0a104df2L,0x04a90c11e2a65950L,0x4c6a15c4dc24341aL } }, + /* 16 << 133 */ + { { 0x33952177a98cf218L,0x841d9e1f579ee53aL,0x1084d61e0a285bd5L, + 0x3935a84e71171b1cL,0x8ac2433cf29b29f9L,0x5dd868b56dd1e9bdL }, + { 0x88da04788d102390L,0x1140735a657400d1L,0xa792a25f9d5b19e1L, + 0x9ee015cb6a27fa79L,0xea3bf8b57ba16a8eL,0xc5f0cc26c15fde67L } }, + /* 17 << 133 */ + { { 0x033708d2e02e9feaL,0x2b588d1e222f437dL,0x998442d6c6b47013L, + 0x4033d62fb8ac1fc6L,0x9b8fd348877c726cL,0x1a2125fa5bea5a49L }, + { 0x04a2c1d680b8afd9L,0x3d52c9d2a40195c1L,0x56b204e6655c0b30L, + 0x55ee14ef520b3464L,0x23fc52e6b5bdd96bL,0x445cfd7a56f4b269L } }, + /* 18 << 133 */ + { { 0xc8985c2c5fee6426L,0x8be749496bb7bb8dL,0x12967576659363b4L, + 0xd1b6ded9b969b221L,0x586f28929819fc04L,0xec6b03e5addd6307L }, + { 0x3f0e96cad4da6627L,0xc866c95c14860d00L,0xb038867c9725f9a8L, + 0x60cd3afa1caf2547L,0x6f2cc04411dddfafL,0x49551f249d0af0faL } }, + /* 19 << 133 */ + { { 0x04a68337177e2e7cL,0xe20b21c0adb79464L,0x9b30d3437e42ae4dL, + 0xac7a01d7f86c5767L,0x3ea34e385381db5cL,0x3005a0c39235f5bcL }, + { 0x853eb43167b4a5c5L,0x92f26a35584e4b8aL,0xa3d25e5879bb470fL, + 0x7963d90a5eacbb13L,0x08ca7969212e3aefL,0xb5ec6582df92bfffL } }, + /* 20 << 133 */ + { { 0x2e152d95ee2c3290L,0x8437df2e4a9ceda4L,0x4151754e3c7ebfd1L, + 0x556c59a888f80aeaL,0x8d099c5d8de44dbcL,0x9ecce7fc77abeeccL }, + { 0x5e0a0f383aa311cfL,0x99ff1eecb8f2bff5L,0x5ae0b483b5dcf488L, + 0x11212c4591483a02L,0x99fe0738312134a1L,0x3b855db0a72745efL } }, + /* 21 << 133 */ + { { 0xb70bf73230261470L,0x8c9b7c4bc74a180fL,0x4c648aef88a9d9acL, + 0x3d9f7540a10f98bfL,0x8ec2a3a3120d55f5L,0x1707c1b0baa5a600L }, + { 0xacba8da9103f2f0bL,0x96926dc0c7194236L,0x00358df7584499dcL, + 0x74c27d0e538c0a15L,0xc675d079de960a77L,0x575b042e89f41f6bL } }, + /* 22 << 133 */ + { { 0xd17d99529703d919L,0xb25ecc411477faebL,0xa5c66a58a9aea2fcL, + 0x83754d683accb00cL,0x6a9ae76a25901044L,0xe437981b2565e035L }, + { 0x441ec0d96f45fa01L,0x35e40d126a697636L,0xba2fbab59bb3c2fcL, + 0xc038be03e94b245fL,0x366b4bcc0c1672eeL,0xa14a2c10f1ce6d55L } }, + /* 23 << 133 */ + { { 0xef32d94febe1dfe2L,0xdbf53d4271494ea6L,0x72dc5fad24cf0c2dL, + 0xa9247adc66dbc21bL,0xe31ff66ab130da59L,0x8cb97c09e86ab63aL }, + { 0x204020e2f59ebb80L,0x56f6d8b7cfd0f965L,0x7522a692b1518dadL, + 0x8e7c999f5f231e2eL,0x2eff5904b4406177L,0x8440cee87bfe2363L } }, + /* 24 << 133 */ + { { 0x37f50e43892c8eecL,0xf06a2f047d85a7e2L,0x3916af85e1d11150L, + 0xf56e852f6785ae1cL,0xbf8c72adae6ada8cL,0x1fcd53e3e13285b2L }, + { 0x5327920cbd56d348L,0x82a394fb445658a8L,0xa71328573caf3792L, + 0xb15ab34b550ffe1cL,0x818980666a5d4e4fL,0x0bda153b2f854f9dL } }, + /* 25 << 133 */ + { { 0xf664f44407aa3d00L,0xcf8901664704e2d6L,0x1802f662f8c2fc8dL, + 0xd52496b8a47f0da6L,0x37f71d8c75001c8eL,0x7ad8e8c29cad3ba7L }, + { 0x666afc25825515f7L,0x3a871c76a729e498L,0x5dc21f1108479e3eL, + 0x78ff145966c4331eL,0x8d01e2352dd3deb2L,0xc68445e9dbc91fc3L } }, + /* 26 << 133 */ + { { 0x8f2d9aae98ea13f6L,0x3e75ba40ab97bfb0L,0x14dd24e635e1fe35L, + 0x14abb0735f88d9b9L,0x74b2c6a801d4fcd6L,0x4905dfe7744a09bbL }, + { 0x349348c077cd538aL,0xdec247f5f7b6d035L,0x737e248dc455d417L, + 0x608a5529b6fe5d92L,0xce0ba0bccd7dca64L,0x022bcb18c21175c6L } }, + /* 27 << 133 */ + { { 0x79fe5372881b120aL,0x4878428aae98aeeaL,0x5c6a7f7d09511acbL, + 0xb7be08de3b046481L,0xfb91990b8b35f13bL,0xab734f604ebdd374L }, + { 0x3d4955f1197690e1L,0xfc82767c7b376dc4L,0x7cf3db85b8c659c7L, + 0x4cfb6f4b03202723L,0x8b79311746141d27L,0x94c6ee67867292c4L } }, + /* 28 << 133 */ + { { 0x77a31009722730feL,0x93707ac4d5cdd297L,0xa290be39d3811e8cL, + 0x831a9b9592a5cdb7L,0xc74cda84e7342270L,0x964661903f48affcL }, + { 0xb0496cca5520b0f0L,0xc8742cd9bae930ffL,0x3a30737aeaea703aL, + 0x0a8e6fb7fb758854L,0x9ab9523e6796f4d1L,0x36e6c05dfdf7140fL } }, + /* 29 << 133 */ + { { 0x4c8ec1a3ccedff1fL,0x8fc58987ca74bd5fL,0x70a6b71cf768abcdL, + 0xb9971cf5ed60a02dL,0xbb2aedc8af2f9a41L,0x4ebf90c76032c98aL }, + { 0x8e69b4c4d3752262L,0x350f201474ba8e8aL,0x7a164f6724d0052dL, + 0x5aeb80db61d7eee0L,0x626a6c9da63583bdL,0x6246637fc3f2196dL } }, + /* 30 << 133 */ + { { 0x2077dfa1817d444bL,0xdda9c7fcdf855b15L,0x577603be04b31d38L, + 0xc6beacae7a140cabL,0x8cd9dc019ecbed91L,0x6ea8591295ae114eL }, + { 0x6fb29a33fd47f1b5L,0x6203bca6223cb96aL,0x2459d85a7c1a3580L, + 0xbab5922d6410a3c0L,0x543be274cc7750f8L,0x1a653e1c42baea3aL } }, + /* 31 << 133 */ + { { 0x616abd271dbeeea7L,0x0684c14fe2189d8aL,0x0d2bf3687354d862L, + 0x8b0cfc06a8bdcb0bL,0x187147b49661e548L,0x07509bc358edde6dL }, + { 0x7b2a33bca78c2782L,0x5f41b8379ec5fa24L,0xa6df5de574539201L, + 0x3510f650093f8f7eL,0xe4d1c06ed14aaa71L,0x4d1b1ca2b0470581L } }, + /* 32 << 133 */ + { { 0x3b62315064ef6a95L,0x97645381aaa5b792L,0x4bc2c31c56471100L, + 0x4a0e73bb1bae8d2aL,0xbfc0770a8df1f76aL,0x5089916fa7bb16caL }, + { 0x2afe5b1cf31fe82eL,0x0b06831df0119977L,0x97caa333a1af2a82L, + 0x93cb92c5dafed6cdL,0x09553e7e92c3b2e3L,0x3d9c4b7d61af2956L } }, + /* 33 << 133 */ + { { 0xe56c89b06910185fL,0x1cd06d19ac47667cL,0xb35e6ae5fe41a4ffL, + 0xdc2fbaf959e8be08L,0xa9e6df08f8cec40bL,0xcab91f8ffe63ad2cL }, + { 0x1e3bd193ca2cc678L,0xe1830cae06bb40f2L,0x3b8b33d6d69985abL, + 0xb6b7e8433895d8a8L,0xec3882909fbf6b31L,0x012bec2ac37d64cfL } }, + /* 34 << 133 */ + { { 0xff2e88fd33941b4bL,0xa2d9730a8d85cccaL,0xa23f8cfa16f7d7a1L, + 0x82013193d39a250eL,0x3b119882ca0fd8a8L,0xcff642ac1a438706L }, + { 0xe4a3a95f65e5688cL,0xb2a6c836c31243d2L,0x1b7ec5d2194d1f42L, + 0x51ab34f814e4f7a2L,0xa3e3f135d3583ca0L,0xbca6ecbade9b91f2L } }, + /* 35 << 133 */ + { { 0xc85820c3002f07caL,0x090365320e00dca7L,0x0f3b3166f4e4d8c2L, + 0xe694eb4479460f00L,0x50d0ed14c15e04ecL,0x8c9998abcc86e3bcL }, + { 0xb82581624aefa561L,0x6351aca610050c0eL,0x4e60399acc8d2342L, + 0x96da3af7f633dc88L,0x1af763ec09202348L,0x76b0e49d3f0d5f76L } }, + /* 36 << 133 */ + { { 0xd83f574a08f84746L,0x48fc9715ca07f5f8L,0xb3d5d0d2dcc51638L, + 0xc2a5e3356153bdcdL,0x8242cd9a8aa4ef74L,0xe71ba25b0bdaa0d0L }, + { 0x4342d4bba4ff172dL,0x81db10dffc1341a2L,0xdd93dd877dacb140L, + 0x6f8a4e81d12d347fL,0x0d4e7e461bc369beL,0x3ce10a771fafd0c5L } }, + /* 37 << 133 */ + { { 0x2fdaa3bb8cb896a3L,0x2fb82dfd913bb303L,0x5d814a50ba9ca09aL, + 0xc3de6aa426112215L,0xd0d5c98b25a0c9fdL,0x54004b3e0eaae4a8L }, + { 0x410e2cc209358663L,0xf7e3d08a501c4ef5L,0x3d86434dd334aa19L, + 0xf70ea577772fc0cdL,0xa0eded5aa607c4f2L,0xba0bf1bc36222b2dL } }, + /* 38 << 133 */ + { { 0x8d901e759632c4d6L,0x0ed9a7ebbbd94698L,0xfd2169dbbf7bcbc1L, + 0x2b4d168d5b302c66L,0xd42f9dd73e65f24dL,0x73e0c22c0eed0022L }, + { 0xf9091588f5d2dcfbL,0x81c7c01eb8715b78L,0x2be06165dde6a9d6L, + 0x64b5902dcacd6ca2L,0xdcd510d70159d3bcL,0x5b71995b42b5e30aL } }, + /* 39 << 133 */ + { { 0xa9c474eae7a211edL,0xc7bcdd20d8170f76L,0xd9aa8d9734a15487L, + 0x26235292933c16b6L,0x289d47d5d8238fc0L,0x39f10fb3ae27ca16L }, + { 0x822e187f1c016ae1L,0x8e93b15f2be46859L,0xe2ba61a60b0a055bL, + 0xd8f33ddecb8de893L,0x016652d6379657efL,0xf4eb08f9e7d9eab8L } }, + /* 40 << 133 */ + { { 0x5559dd31e67145b6L,0xf2d905b45b2427e7L,0x0d840fabcaf57d0cL, + 0x9625866578742ab6L,0xc85482ad409c1c8eL,0xdca2a058adaa6167L }, + { 0xec26ad9a0c8885fdL,0x1b93b8a22a600cb2L,0x340aa7fc2539986bL, + 0xd7674876a23dee41L,0xa948a9292e1a9837L,0x9ae67d2a71438da9L } }, + /* 41 << 133 */ + { { 0xe753114a8d6a98f5L,0xb2d7d1e1f6ad93e4L,0xfbcfe0cf1935714dL, + 0x9dc2d293e859e729L,0x674c170889a703f2L,0x87744b0252063099L }, + { 0xa1721de04b25966bL,0x059292573a285fcaL,0x5b02ca39e8ce75e0L, + 0xbfdf0fb939e57da4L,0x554378cd6388a964L,0xc53fc5c8f853d7faL } }, + /* 42 << 133 */ + { { 0xcd3b60e352f51554L,0x6292fafab44ad7eeL,0x670561c79513741fL, + 0x95defdf3b9ba16a7L,0x6c0beac1adae36cdL,0xef05c24a3e8aabd6L }, + { 0x74208a02b23efc25L,0x71930e02c22172d1L,0xbdb1f1c6f5ccbffbL, + 0x358b483c504d9cb3L,0x48b5887a9a48a4baL,0x289256b4e48f09e7L } }, + /* 43 << 133 */ + { { 0x671bf1eebc2f256aL,0x530faa653984ca7eL,0x0a6d18955c05da6eL, + 0x219de918118fe96cL,0x289b9645bb7eded4L,0xe905c4729588f006L }, + { 0x56d0cd9ac9d61133L,0x8879550079a4f743L,0xd05e910199c2aff3L, + 0x7e91f7c985e52c8bL,0x7fd02f83b5c5d473L,0x4b43b6453c59330aL } }, + /* 44 << 133 */ + { { 0xeac6f447d56bdf1fL,0xb22e8425c2b502ffL,0xe1cc9d3dfca5a501L, + 0x8192bc29b64baf39L,0xeb2c901a52ce849eL,0x7f5f38b11dd506f1L }, + { 0xfb3684b10f0a1d68L,0x16c4aacde9240ff8L,0xffa682435a4d8995L, + 0x27264ab554e4c95dL,0x9aa40cdc4f34ffaaL,0xcb8a30a35fd818eeL } }, + /* 45 << 133 */ + { { 0x912f0a7dfa88792fL,0x2ad9249f5090716eL,0x4b828a6fb96e6e31L, + 0xe805f0588d7f2095L,0x72e95cb956e00978L,0xc95354667651815fL }, + { 0xc877181a08df5b53L,0xae055dd8779c3302L,0x3f9e6dd90b4e68d2L, + 0xdeb15f1308fbb2f8L,0x5f129c1cc5802a96L,0x7482e4af3cc51022L } }, + /* 46 << 133 */ + { { 0x98904777ab695f56L,0x6dc472c18989e518L,0x6749d25c82031d40L, + 0x5c465922c36202f1L,0xb3b5b9aff31fe542L,0x855263bdf98bc09dL }, + { 0x40ee01747eb4789fL,0xd64ae0d4de4e92bcL,0xbaea76a38995e69fL, + 0x3f22b2e3d972751eL,0x5a197daa2461f1b4L,0xbd15682a5097b93eL } }, + /* 47 << 133 */ + { { 0x7f251143534f8547L,0x213baf14222a161aL,0xae993737ad1e6005L, + 0xdc70867ff8b1cc7eL,0x41e880f3bb22e11bL,0xe36f54cbd2d6bc45L }, + { 0xa42e819d4d65ae97L,0xdc57be4de8592604L,0x8a89777fabe73b50L, + 0x435fedec72e26f5bL,0xe8d3cd8251ec79f0L,0x9574d6ea67f407b0L } }, + /* 48 << 133 */ + { { 0x39038863f7f35053L,0x421a17f3328787d2L,0x38aa682ef3d8310fL, + 0xb52d41e8f4123153L,0x4fbef3dd7026310bL,0x0c6bd7adf6ff5692L }, + { 0x3831c6b2a9be5d0cL,0xb5c9ae85e8d328b8L,0x76d26abc6516bba4L, + 0xc237f9a5446d35a8L,0xb2b16c0ff012a8d0L,0xddf2b7fe0ee0315bL } }, + /* 49 << 133 */ + { { 0xf401366a7dd4243fL,0x7db92881f434ba76L,0x5b5bacd737ffc502L, + 0xa53fe0e802cb994eL,0xf6db539ffb00cb96L,0x0bb288b379878966L }, + { 0x275c108c0c3d4b7fL,0xe57222d267236ba2L,0xc754d31890683aa1L, + 0x883a41ef2345460fL,0x8e6b7ce8b572fd14L,0x7649c29237d21925L } }, + /* 50 << 133 */ + { { 0x46302515c4af281fL,0xe2a9633c3513ea87L,0x1175276fb3e96864L, + 0xda377e32f4ed1228L,0xacf223a1fa6be904L,0xf442c41abc01057bL }, + { 0x83d766c38a69db33L,0x933dd0974cef397cL,0x094b21b575fe43cdL, + 0xf16ee57ab3141dd5L,0x4a8d0d6cb981d196L,0x6bd246c3730075deL } }, + /* 51 << 133 */ + { { 0xd9ae9faa91eab3f7L,0x8520bebba2bcdfc1L,0xc681d5a0ee94353aL, + 0x980871dd316ee7acL,0x7d70b82bcb401c4eL,0x150706c1bc6885efL }, + { 0x11709bbed3d8663aL,0xad69df943ace1806L,0xf889daef1a36f12cL, + 0x6ba376b2560bb749L,0x5342cd7a0d95f8b9L,0x5d14201273b4554aL } }, + /* 52 << 133 */ + { { 0xbb85b640056ad6c2L,0x7c51ef96ac074372L,0x1c7ce31cf10b43fcL, + 0x08e4101b26f4d3a4L,0xd18511c43968459fL,0x00e20c3fd6d07839L }, + { 0xd5bcd598e4fcdc11L,0x99e9a4d0c877f6a2L,0x9c5dd9d0bd491646L, + 0x83918f609bfd7a1aL,0x4bc130cd7e2b95a3L,0x668825fbfbc31c83L } }, + /* 53 << 133 */ + { { 0x7e8947bd5568b75cL,0x43419ecbdab8f822L,0xeb52a83a7b8fa996L, + 0xbc674ff32d1a32c6L,0xdc086f84ce405eeaL,0xebe3e087f8918ddfL }, + { 0x476099ecdb152bc4L,0x0cb491c52d3718c3L,0xa7c49cd69da8517fL, + 0xc736fcf51ab8fbadL,0xa00b403ba24fe115L,0x01f6e5bfd976f549L } }, + /* 54 << 133 */ + { { 0xef8e12edf15ad86eL,0x216be9828c20441dL,0x10ccd4f85c45e821L, + 0x8a12f6037c9745e9L,0x56212b09da6f1b2fL,0x5a81d69338115f05L }, + { 0x5aead3330a4405a8L,0x7024a76c03221eddL,0x9c101d0250e6a610L, + 0x6bcb22ffc1b6d54aL,0xf96cef62cf787e89L,0x9c9bde7b79341d83L } }, + /* 55 << 133 */ + { { 0xe9c61fa744058dc9L,0x59efcc8f1581d690L,0x1ea73467513aba4bL, + 0xf0fda8a69d03d72aL,0xcc1f3f22c6f30a01L,0xb632daa3ddf8dea8L }, + { 0x58563188fe8e2f89L,0xf053b9f67b45cf5eL,0x1ab51b07f9bda4b1L, + 0x37850e9789dc0050L,0x1bf5e41e8f6a1daaL,0x4abb4f82d94c0fd8L } }, + /* 56 << 133 */ + { { 0x817d77b106a9ad54L,0x3a999d7d89a25ecaL,0xd3ac4107da68b768L, + 0x6904bcddbebc4c4dL,0xb0d2103ca53d39e9L,0xdba86bd230a5e950L }, + { 0xb09256804f52208eL,0x37c3156a28495b2cL,0x2389ab34c15855aeL, + 0xc14dfd963017194fL,0x420e07191146b838L,0x1a9f909b8fb4b6fcL } }, + /* 57 << 133 */ + { { 0x73af3d1fa24985f4L,0x4fa27db444a1f9a8L,0x6deb02455cfbfa45L, + 0x4803e0342813c996L,0x24715fe80e4116ddL,0xa2e8258d38d8e902L }, + { 0x3321e112dd7d8ebfL,0xab8d5b2b272ee6a4L,0x2994fac34eb10fd9L, + 0xe007d0a4a9c611ccL,0x29db5aa974d194e3L,0x9e76e3ddcf7409b9L } }, + /* 58 << 133 */ + { { 0xf12a3eeab577f6b9L,0xe666e002b6db2206L,0x95aa0d03375229b4L, + 0xebd05140ef0772beL,0x9d5b5e9e48580b17L,0x960906b3a77ceceeL }, + { 0xca869663e50422f8L,0x150e844199d481b2L,0xadd97d7c3418b00dL, + 0x9908a23e68244f02L,0x5357ea61d3eac131L,0x0af5423d9778902dL } }, + /* 59 << 133 */ + { { 0x11aa3582d8e62251L,0x108ec170aa1560a5L,0x8423663e2b5b6ea9L, + 0x3f4ad292d8718329L,0xf8e3e7bd04f8daadL,0xed310c3a11b81211L }, + { 0x718db302edac9282L,0x7866f1c1e434544bL,0x1052133c568b195aL, + 0x8ca61965c0e37cbbL,0xdd28fbd32cfac1c2L,0xf4062b33dce29660L } }, + /* 60 << 133 */ + { { 0x2926ef17dd63404dL,0x0e89c4d41399cc68L,0x6507fedef7ec20b8L, + 0x1ac084ff88c751d6L,0x31bc08bedefe29e6L,0xd42199714f0692c5L }, + { 0x4d6ee74236069bc0L,0x3868ef6aff80f3d7L,0x6df02d7c5a9c6f4bL, + 0x2c3096bb101abf69L,0x0c2b01ec8eaacaebL,0x65914c20eb2e687aL } }, + /* 61 << 133 */ + { { 0x78d5ab7b34a8173eL,0xa34b72ac9230c3b2L,0x379453e13538b39dL, + 0x1764c4420f3789b0L,0x5b4bbe77a3f2ba4eL,0x3bd35b796f86338dL }, + { 0xf2fcdf04f02fa7e3L,0x6b4522f420d23feaL,0x966fb8fa01be16a5L, + 0xf2a56e96e0d705feL,0x494aa4553872e429L,0x68432d9181921587L } }, + /* 62 << 133 */ + { { 0x0ae47d1e3dba277aL,0x54607ac99832d90cL,0xd4cec32eecbcdeacL, + 0xe54b3033b9ccdfa9L,0x5b3a8a56fb920449L,0x831ec8f955eefd3aL }, + { 0x59ba32a3a02dca96L,0xb421e4b01decf837L,0x52e70a88a88636d2L, + 0x3b75ed073086667eL,0x7a4a46b3b877cd6bL,0x3825c80b59c99207L } }, + /* 63 << 133 */ + { { 0x3bc3f0e069bdc53fL,0x7e0bd730d9d7def4L,0x71a577e6844ede6bL, + 0x06d47f4981705712L,0x83bdb1a6ef108ea6L,0x853a3ce0c8a8ff41L }, + { 0xa6f114b8f408ec44L,0xe0ce4267e2d72d33L,0x405f6ddda2a0b613L, + 0x22ce3daa8d253ad3L,0x2fd738094aa1de25L,0x28a2001b27363597L } }, + /* 64 << 133 */ + { { 0x13722ab079ed523aL,0x33b29bec249d5624L,0xd3d0f467f76fdaf7L, + 0x7ce072f912ddfd9aL,0xce918a5747bdefd3L,0x14d38ab4750e5315L }, + { 0x08bbb20e3346f647L,0x428b917f05b26894L,0xc8fb5c21ca865ba6L, + 0xee6e41e02e6e8e6fL,0xd00ae6214c608b60L,0x659756396ff685cdL } }, + /* 0 << 140 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 140 */ + { { 0xbbccce39a368eff6L,0xd8caabdf8ceb5c43L,0x9eae35a5d2252fdaL, + 0xa8f4f20954e7dd49L,0xa56d72a6295100fdL,0x20fc1fe856767727L }, + { 0xbf60b2480bbaa5abL,0xa4f3ce5a313911f2L,0xc2a67ad4b93dab9cL, + 0x18cd0ed022d71f39L,0x04380c425f304db2L,0x26420cbb6729c821L } }, + /* 2 << 140 */ + { { 0xca07923c0eb008c8L,0xab79402d9985912eL,0x41e379e83cb02510L, + 0xfabac005beb383efL,0x24d12d9a1076dd0dL,0x95afd46fb208f127L }, + { 0x9cc38a60b1031e46L,0x93e21e977009f6bcL,0x6f6360d98ac219efL, + 0x1edaab3faf284c80L,0x9c3b5281019e366aL,0x6475c579bc9e9726L } }, + /* 3 << 140 */ + { { 0x26bd07d6bdfbcae8L,0x10b5173fdf01a80aL,0xd831c5466798b96cL, + 0x1d6b41081d3f3859L,0x501d38ec991b9ec7L,0x26319283d78431a9L }, + { 0x8b85baf7118b343cL,0x4696cddd58def7d0L,0xefc7c1107acdcf58L, + 0xd9af415c848d5842L,0x6b5a06bc0ac7fdacL,0x7d623e0da344319bL } }, + /* 4 << 140 */ + { { 0x8410d8298d85a25aL,0x48ee01354af81a14L,0xae460d0d18c25348L, + 0x5d0279a07eb035a3L,0x87e7c1289a114414L,0x17c08a8ec0744f79L }, + { 0xb7b2b4f1025cdbe3L,0x9a74f15d82d1af60L,0x124a7395b51ee685L, + 0xf2937c4bf6122422L,0xb4ec133207f1a7ffL,0xad801112f886032eL } }, + /* 5 << 140 */ + { { 0x4c0d78060c9d3547L,0x993f048dcf2aed47L,0x5217c453e4b57e22L, + 0xb4669e35f4172b28L,0x509a3cd049f999f8L,0xd19f863287c69d41L }, + { 0xe14d01e84c8fded0L,0x342880fdeafd9e1cL,0x0e17bff270dc2bf0L, + 0x46560b7bc0186400L,0xe28c7b9c49a4dd34L,0x182119160f325d06L } }, + /* 6 << 140 */ + { { 0xdd4eb3d07bb5346eL,0x9a46ad01382e7db7L,0x1200285ddc1973c7L, + 0xfd342beaa0046b98L,0xd19173491219a7fcL,0x5383d319b7caffe5L }, + { 0xea5a0c4e2e0fa118L,0x1cc2de3ca5457b28L,0x5b2a16dc6046eeeaL, + 0x1755e1fecc8e64b1L,0x51e4946e9e7faddaL,0xf805422ffcbf4ec2L } }, + /* 7 << 140 */ + { { 0x46d70888d7e02e18L,0x7c806954d9f11fd9L,0xe4948fca4fbea271L, + 0x7d6c7765bd80a9dfL,0x1b470ea6f3871c71L,0xd62de2448330a570L }, + { 0xdaecddc1c659c3a7L,0x8621e513077f7afcL,0x56c7cd84caeeef13L, + 0xc60c910fc685a356L,0xe68bc5c59dd93ddcL,0xd904e89ffeb64895L } }, + /* 8 << 140 */ + { { 0xf877e8c6bd08ffafL,0x24718fefaf23012fL,0x19ff269f2b004cfeL, + 0x8adc5d7795450f8bL,0x688ce8bce2a7d458L,0x74d7445b97bd7fdcL }, + { 0x1b9f4ad641e6abadL,0x6652ed05f00e4bf5L,0xabee1f7e71d83d86L, + 0xe693c76d25ffc219L,0x1c9a84afc873f553L,0x84d2718766d77a55L } }, + /* 9 << 140 */ + { { 0x75d874fb8ba7917aL,0x18fa7f53fd043bd4L,0x212a0ad71fc3979eL, + 0x5703a7d95d6eac0eL,0x222f7188017dead5L,0x1ec687b70f6c1817L }, + { 0x23412fc3238bacb6L,0xb85d70e954ced154L,0xd4e06722bda674d0L, + 0x3ea5f17836f5a0c2L,0x7e7d79cff5c6d2caL,0x1fff94643dbb3c73L } }, + /* 10 << 140 */ + { { 0xe566dc057e5f7121L,0xccac74e22ed07bc3L,0xaabfdfcdc70401b4L, + 0xac9fc4496254e0dbL,0x358d885f11c7de05L,0xb8e6a4a9d60772b4L }, + { 0x884272a5cfe917ceL,0xdfbe98689a3d347aL,0x06b90848c9d1baccL, + 0xc4ccedb6db8c6288L,0x892878b979e5683eL,0x1b521829243273e3L } }, + /* 11 << 140 */ + { { 0x916e19d0f163e4a8L,0x1e6740e71489df17L,0x1eaf9723339f3a47L, + 0x22f0ed1a124b8dadL,0x39c9166c49c3dd04L,0x628e7fd4ce1e9accL }, + { 0x124ddf2740031676L,0x002569391eddb9beL,0xd39e25e7d360b0daL, + 0x6e3015a84aa6c4c9L,0xc6a2f643623eda09L,0xbeff2d1250aa99fbL } }, + /* 12 << 140 */ + { { 0x099369c4bf0c6fbeL,0x976f78b2fe7d5727L,0x32feb503d18267a9L, + 0x162c41501a7dd0feL,0x3141e37726b8e969L,0x50497a643b53a94aL }, + { 0x96159f41607b4cfcL,0x1999b7042f111babL,0x3254987c760f2eaeL, + 0x5308075b841014faL,0xc634127e4e7adad8L,0x32a70a6059ffbfe6L } }, + /* 13 << 140 */ + { { 0x1feef7ce93ee8089L,0xc6b180bc252dd7bdL,0xa16fb20b1788f051L, + 0xd86fd392e046ed39L,0xda0a36119378ce1dL,0x121ef3e7a5f7a61dL }, + { 0x94d2206192d13caeL,0x5076046a77c72e08L,0xf18bc2337d2308b9L, + 0x004db3c517f977b1L,0xd05ae3990471c11dL,0x86a2a55785cd1726L } }, + /* 14 << 140 */ + { { 0x7279c369a1f857e6L,0x029d30ef27fb373aL,0xe82cbc806827358bL, + 0x2bfe09aaa18f57abL,0x63bf3145e5503492L,0x7ea15beafb28ee43L }, + { 0x8e6d428f5eec91b8L,0x215e03e9611b1799L,0xb995737161d476deL, + 0x2320c764e76726a5L,0xc5de88178e5e26f5L,0x24aae0699161e0b7L } }, + /* 15 << 140 */ + { { 0xb8d9b28672107804L,0xb5a7c4133303b79bL,0x927eef785fa37dedL, + 0xa1c5cf1ead67dabaL,0xaa5e3fb27360e7c7L,0x8354e61a0a0c0993L }, + { 0x2ec73af97f5458ccL,0xde4cb48848474325L,0x2dd134c77209bc69L, + 0xb70c5567451a2abeL,0x2cd1b2008e293018L,0x15f8da7ad33c0d72L } }, + /* 16 << 140 */ + { { 0x5584cbb3893b9a2dL,0x820c660b00850c5dL,0x4126d8267df2d43dL, + 0xdd5bbbf00109e801L,0x85b92ee338172f1cL,0x609d4f93f31430d9L }, + { 0x1e059a07eadaf9d6L,0x70e6536c0f125fb0L,0xd6220751560f20e7L, + 0xa59489ae7aaf3a9aL,0x7b70e2f664bae14eL,0x0dd0370176d08249L } }, + /* 17 << 140 */ + { { 0x5dc386d0a8790657L,0xa4fdf676bc4d88bbL,0x1b21f38f48bc6c49L, + 0xcdcc7faa543a7003L,0xea97e7aa8c9cf72cL,0xa6b883f450d938a8L }, + { 0x51936f3aa3a10f27L,0x0170785fdecc76bfL,0x7539ece1908c578aL, + 0x5d9c8a8e0f3e8c25L,0x8681b43b9e4717a7L,0x94f42507a9d83e39L } }, + /* 18 << 140 */ + { { 0xaeac64c96f089b59L,0xecfdc92b65f9d762L,0xddde5024f750daffL, + 0x82c01c1c0f707e73L,0xc70aa9d4ee20adb5L,0x27f6799dbeb0e60fL }, + { 0x918ad262520aa514L,0x2bb1362f8d13eae0L,0x21b60b46a9d1d43bL, + 0xf449e2d4767ab86eL,0xf42b09948a5a496eL,0x3b26006b853f2a3bL } }, + /* 19 << 140 */ + { { 0xbbe11ca8a55adde7L,0x39e6f5cf3bc0896bL,0x1447314e1d2d8d94L, + 0x45b481255b012f8aL,0x41ad23fa08ad5283L,0x837243e241d13774L }, + { 0x1fc0bd9dbadcaa46L,0x8df164ed26e84caeL,0x8ff70ec041017176L, + 0x23ad4bce5c848ba7L,0x89246fde97a19cbbL,0xa5ef987b78397991L } }, + /* 20 << 140 */ + { { 0x364d5dfda6140b89L,0x30e4a48efdc9105dL,0x13f6276018a47151L, + 0x18ad84cfa17a2853L,0x5f315c93988cb37bL,0x90f9cb701af64ce3L }, + { 0x020c67db029b6ffdL,0x8989ccc62ce3528dL,0x9bb4f9844d00ee63L, + 0x0b052413a70b4ca9L,0x7dee36dcc96b4a07L,0x226db70ea7888508L } }, + /* 21 << 140 */ + { { 0x111af1b74757964dL,0x1d25d351ddbbf258L,0x4161e7767d2b06d6L, + 0x6efd26911cac0c5bL,0x633b95db211bfaebL,0x9bedfa5ae2bdf701L }, + { 0xadac2b0b73e099c8L,0x436f0023bfb16bffL,0xb91b100230f55854L, + 0xaf6a2097f4c6c8b7L,0x3ff65ced3ad7b3d9L,0x6fa2626f330e56dfL } }, + /* 22 << 140 */ + { { 0xcd9b76b6a92f4e61L,0xa464f5225a00d902L,0xb64774e68a583f92L, + 0xc7dc2030bee842a8L,0x594743ea5d2f27ddL,0x4c0ed28ef3c54609L }, + { 0xd763346d4b1dfb93L,0x8ea291dde1bed2eeL,0xf26d4adbd6d34ae1L, + 0x74b8d24e54ea3529L,0xe20490e150062077L,0xf67b7a9092d6c19cL } }, + /* 23 << 140 */ + { { 0x3d28bf2dffccfd07L,0x0514f6ffd989603bL,0xb95196295514787aL, + 0xa1848121c3db4e9cL,0x47fe2e392a3d4595L,0x506f5d8211b73ed4L }, + { 0xa2257ae7a600d8bbL,0xd659dbd10f9f122cL,0xdb0fdc6764df160fL, + 0xff3793397cb19690L,0xdf4366b898e72ec1L,0x97e72becdf437eb8L } }, + /* 24 << 140 */ + { { 0x67bf4c98e11df408L,0x8e105c66d299b156L,0xfde3922e901b63c7L, + 0x7fd57218c184ac91L,0x6dd2ea5cebcdc105L,0x1c4956c0aef7653fL }, + { 0xd6fac6429c1c11a1L,0xeda44f663d230d5dL,0xecca2241e6902ccbL, + 0x85962a1f2700870fL,0xc5ca32c97864a291L,0xe55e974af6c8d3d9L } }, + /* 25 << 140 */ + { { 0x81dcea271c81e5d9L,0x7e1b6cda6717fc49L,0xaa36b3b511eae80dL, + 0x1306687c3cd7cbb3L,0xed670235c4e89064L,0x9d3b000958a94760L }, + { 0x5a64e158e6a6333cL,0x1a8b4a3649453203L,0xf1cad7241f77cc21L, + 0x693ebb4b70518ef7L,0xfb47bd810f39c91aL,0xcfe63da2fa4bc64bL } }, + /* 26 << 140 */ + { { 0x0af51a2025f7b355L,0x35fc45d58d8081bfL,0x0cf3036d0ab30d16L, + 0x2bd47f919109cf76L,0x8be09360ec7f12beL,0x99fc291be8dcdca9L }, + { 0x385b89868135b12fL,0x272ac288f4ec52dcL,0xe7ca370cce09b043L, + 0x94655816251f4c4eL,0x5c1dea972d40a755L,0xe8977234a4b10406L } }, + /* 27 << 140 */ + { { 0x82c1c684eaa66108L,0xe32262184cfe79fcL,0x3f28b72b849c720eL, + 0x137fb3558fee1ca8L,0x4d18a9cde4f90c4eL,0xc0344227cc3e46faL }, + { 0x4fd5c08e79cda392L,0x65db20db8adc87b5L,0x86f95d5b916c1b84L, + 0x7eda387117bb2b7cL,0x18ccf7e7669a533bL,0x5e92421cecad0e06L } }, + /* 28 << 140 */ + { { 0x240fde37b21b2632L,0x6b878ae68ca0f16fL,0x072d9ded0bc32ebeL, + 0x8c2552bc29840743L,0xb58327b003b34f8aL,0xa51598ea71dabbfdL }, + { 0x337361f7d4f461c6L,0xae88972dda1de4b2L,0x9ec86d7ade7e8c2eL, + 0x607de383f23f19e0L,0x0cb144c27d234103L,0x00878a228f0c3411L } }, + /* 29 << 140 */ + { { 0x26063e124174b08bL,0xe621d9be70de8e4dL,0xaea0fd0f5ecdf350L, + 0x0d9f69e49c20e5c9L,0xd3dadeb90bbe2918L,0xd7b9b5db58aa2f71L }, + { 0x7a971dd73364caf8L,0x702616a3c25d4be4L,0xa30f0fa1a9e30071L, + 0x98ab24385573bc69L,0xcbc63cdf6fec2e22L,0x965f90edcc901b9bL } }, + /* 30 << 140 */ + { { 0x265f7236e22b29caL,0xe36c3c3daa62691aL,0x73410e6ed2e1bad1L, + 0xa182a579a5743cecL,0x2ca67274c22b0453L,0xc698fe35546e52e6L }, + { 0x60b3a519890e9155L,0x24312c3c2b91dbc3L,0xa6d45050282911d9L, + 0x3781933efd249e1eL,0x2e0cbb93e26d023aL,0xfb479267bf27687aL } }, + /* 31 << 140 */ + { { 0xd53b592d71e15bb3L,0x1f03c0e98820e0d0L,0xce93947d3cccb726L, + 0x2790fee01d547590L,0x4401d847c59cdd7aL,0x72d69120a926dd9dL }, + { 0x38b8f21d4229f289L,0x9f412e407fe978afL,0xae07901bcdb59af1L, + 0x1e6be5ebd1d4715eL,0x3715bd8b18c96befL,0x4b71f6e6e11b3798L } }, + /* 32 << 140 */ + { { 0xaff4782231cb94c9L,0xf1b5a0b7803c1af4L,0xbeb85f8d2ef696a9L, + 0x8ce5baab4fa94fcaL,0x0a32f96200d41a43L,0x0f69ad5774f6e772L }, + { 0xbe0221af6ccb5157L,0xcb83969a2a4f91ffL,0x78ff85d6a7e49f39L, + 0x63006589cb5d3c63L,0xe8e4383596eb65f5L,0x79f59da9ff8adbdfL } }, + /* 33 << 140 */ + { { 0x3cc0df125df9b6ecL,0x3c18f44e286d6ef1L,0x55a3939e517d0f7dL, + 0x42626a32607e97bbL,0x6168e7b2e26ad78aL,0xdcf8e74b9145583aL }, + { 0xa7c541a52db84a71L,0x680532c7119210a6L,0x3252035d0a3315e5L, + 0x06dc2d5befe7c8b6L,0x940175894e720570L,0xb16e635f2f6a3ec6L } }, + /* 34 << 140 */ + { { 0x0bd0ed3803e13ce1L,0x44a148bb5868069cL,0x2a79ab57aa5095e6L, + 0x943416faffffcf22L,0x98434e8756a1365cL,0x2493315d196dc354L }, + { 0x1f89d911b79a3a1eL,0x937140a841dfdd23L,0x05ad36e43b220b8bL, + 0xff5e810333594e3aL,0x3119775f893edb80L,0x1fad811627eee584L } }, + /* 35 << 140 */ + { { 0x55c4377e204f30b9L,0x63550549a1ebd2bdL,0xdd86ee0c5e44f5f1L, + 0x8b9d1d9b5d84d999L,0x9ea95a58dda7a075L,0xa465b4a50977e81fL }, + { 0xcb491e5558421fadL,0x4617f31c280709d6L,0x5e2751c382e0195dL, + 0x698155856f8eefd1L,0x6702166cd16dc160L,0xfc14545c84c85b2fL } }, + /* 36 << 140 */ + { { 0x27c961f6e8fc35abL,0x1e0c26923a596fe7L,0xc75c7cb804351be8L, + 0xfb92bfeb1c425d80L,0xb01d1c909f0bde61L,0x273d1f0c512f7817L }, + { 0x4375000df0d71796L,0xc1655874cf53d529L,0xe157b358abddc21cL, + 0xb0f91e3e40cedc30L,0x48e26c7272260452L,0x9794a6bf0713f667L } }, + /* 37 << 140 */ + { { 0x78befaede72c6f0dL,0xc80584210bb2a3ceL,0xcee67a5d52748e21L, + 0x08d4a9e8de8ed124L,0xc0393271b5fb9514L,0x39b1df6b20942000L }, + { 0x831fd8cfc3d961afL,0x1bb097e3e752daceL,0x279b3924cf2c8143L, + 0xa9f8a939b8f5cad9L,0x2b566813bfb8009cL,0xab37ee1df58f0927L } }, + /* 38 << 140 */ + { { 0xc17f21f5134d8bd8L,0xc75fc638a90a9a1aL,0x032a6f382a22527bL, + 0x3c77a72bd20fefb2L,0x559d8a52196e2921L,0x760a3a2c9afcb6caL }, + { 0xa3bf5802f162d871L,0xb6b367a5c594d2adL,0x4d440c523daa48dbL, + 0xb2a8acafd5b2c18aL,0x50d85d6adc349ddaL,0x3c2e67718a707475L } }, + /* 39 << 140 */ + { { 0x8254a39d5e1656cdL,0xff457dcaa595e153L,0xf0ddc1936bf62398L, + 0x45e1f91a558f9337L,0x8a424d9d91480b33L,0x019f0a412bf61189L }, + { 0x66badaa6d49e7b98L,0xb0674512dad636faL,0xc767eceff4c49695L, + 0xbe16e6b5ddc80ea0L,0x2bd0bb87febd1ba6L,0x69c9f485fe60eb32L } }, + /* 40 << 140 */ + { { 0x08cf7d82bff4b684L,0x6abbf429ac4a9329L,0x2454c15ab0c8e0ffL, + 0x4782035a70bdb03dL,0x89ff6a41448199cdL,0x07969c9ffd0bf1e5L }, + { 0x19d1cc6a83406dc9L,0x4054cab9b4980267L,0xf0f5594e1887d258L, + 0x039249e4e09dd987L,0x2b0cd4f9857ddb1eL,0x54ceb29fd8418075L } }, + /* 41 << 140 */ + { { 0x562693d30843729fL,0xd703202122648488L,0xd7c40e82ec6d0799L, + 0x8eacb2496eb6fb6bL,0xddf7074885a5ec47L,0xd70524bf891d5de5L }, + { 0x4d17c237c4d01055L,0x4793c6e4b4203cc0L,0xf247d0df1d1bf37aL, + 0x406994fa93b007feL,0x4062c29902940092L,0xedc0d949f558c1e8L } }, + /* 42 << 140 */ + { { 0x9fb3630606ab1fc5L,0x2726c1acc0de4e26L,0x8b2fb5130ec7b070L, + 0xf3581a6907bacd4aL,0x97db622c164bf5a5L,0x8103517962327e3eL }, + { 0xad3637b0b1d635c2L,0xb894adf949832ec3L,0x0ab5381725685b12L, + 0x73ceb46069720ce8L,0xdbd1b68ef5e445dfL,0x57659059c8961eb8L } }, + /* 43 << 140 */ + { { 0xbd1272a5f73a7cfcL,0x30d3c078de0828e1L,0x5dc0244e1a8f36a1L, + 0x87c80cdf585ec2acL,0x46c88d277944584cL,0x588d14d8b2dbe1a9L }, + { 0xb42327a7afe7d55aL,0x58add8f98775409eL,0xa45db2fd10590c68L, + 0xb98e10bca972b84dL,0xbf5c0ee0a737aeb6L,0x26424f3def199fa1L } }, + /* 44 << 140 */ + { { 0xb7bb774603c4cd27L,0x5bfe638ad9723678L,0x47d8b4c24a04d064L, + 0xdba309383faa45d7L,0xb0fb4308b39dd043L,0x5eeaa33f23ebfa1dL }, + { 0xaa5a0ce0ba100837L,0xae025cf6d7667d17L,0x610baf5df480cf99L, + 0x8ba0039ead025771L,0x0ff4f75174785f24L,0x910736ef8b7c30b7L } }, + /* 45 << 140 */ + { { 0x0496b77ac04b7e7fL,0x6f7ea5bbdf8163a1L,0x87a8e8f18f415876L, + 0x6e5b6f2e3ee22085L,0x5ae860ca6f529471L,0xc54c8667eb624447L }, + { 0xdd06be3de1c7766aL,0x8a8e48ecd2189d23L,0xa4076d3564245444L, + 0xc4973a5deb651a4bL,0x3b3e2fd52c4f2747L,0xe9a16a24abde2ecbL } }, + /* 46 << 140 */ + { { 0xb7f146b890973714L,0x2277873f288ed67fL,0xe6da9d9ee5182317L, + 0xa446f9d3562475b3L,0xc5291f9756755d91L,0xe762c5f3c104c2b6L }, + { 0x542f90b3dde83d53L,0x758aaddddace5f42L,0x1c8b9775e673f002L, + 0x8899c11f74ec42bdL,0xfd9e300a2dbc0dedL,0x6de1c8e4d281f6adL } }, + /* 47 << 140 */ + { { 0x5ddafb1b2a2f98cbL,0x8dc2bdc429ec504fL,0x27c51b3cc9f43826L, + 0xcfd609fccacf5becL,0x642ff85c30dd9f71L,0xcab498e5b6b00ffdL }, + { 0x9c7ef286652ca743L,0xda291ae0ab95d7aeL,0xe6f4d2badfbff466L, + 0x34afffef9835d482L,0x41a2cfc050db295cL,0x51a08859e6ee400eL } }, + /* 48 << 140 */ + { { 0xf6fd26cc487925bdL,0xd9b751eef5ef44e9L,0x694a788be372817eL, + 0x85f3dc1ae8c90c31L,0x8c90c6bf15aa0ce5L,0xb52a5d83f01bb223L }, + { 0xbdae01dddf9c3315L,0x941fa6b663ddfc56L,0x50ddff4ec2548f24L, + 0x54a49868d12802a7L,0xcd922fb6404d9240L,0x88d7f41f957f6d1aL } }, + /* 49 << 140 */ + { { 0xbfd0a17e4c4c87cdL,0xc6c76ebb10b614bfL,0x721d8b4fd1c594a9L, + 0x1ff70b2daff65d09L,0x2698f57ce50ad026L,0xf4ac3f5627a92e38L }, + { 0x1114d3392c143ba0L,0x7fafa6b97f8e9b0bL,0x506f11edd82a2500L, + 0x4df1087fe0ad9ca2L,0x85509ad9fdfecaa2L,0x733c4f8293bd022dL } }, + /* 50 << 140 */ + { { 0x3b9de3494233d6cdL,0x9a360917a8f55d63L,0xbe79cdfd90662136L, + 0xbb3d8fd7cbf3f02aL,0x5d0d4eb81d61e485L,0x85b485215484cd65L }, + { 0x77580c810fc5cbb1L,0x4b36441bd8e70ff2L,0x50ccdec1b2107a8bL, + 0x6b7f97c945a45893L,0xb818859b9572a173L,0x864dc632d94bd9beL } }, + /* 51 << 140 */ + { { 0x13bb6b113fee0074L,0x4c02520ed1059617L,0x5beb793ccf71f07aL, + 0x15a8d28d46d4c54bL,0x9889a8948b89fab6L,0xd00fdcb492623b75L }, + { 0x1c7963572939a84cL,0x4b85d94d6221a244L,0xcc66b5bad1fd506dL, + 0x866271042a06ca91L,0x4295fc6a49bb18c1L,0x05a81eea341d93e4L } }, + /* 52 << 140 */ + { { 0x895dbf20df8111ccL,0xec8297be2906fb2aL,0x4ddd6f22b94c3f53L, + 0xec55cc738ecbd552L,0x549d3145ef343a0bL,0x9b19220c3b4858d8L }, + { 0xd5bbf954bd0c2f11L,0x9cacae0cce8c221fL,0x87e6cbc1f6a3dbc5L, + 0x7ce5c9b6e37ebcb2L,0x654339ef50eb3c8fL,0xeac7f343f3674f55L } }, + /* 53 << 140 */ + { { 0x723969a3dd8d5580L,0x4f6dd5c4a30edd79L,0x5b29f3f5a4d7ed53L, + 0xe17a12bd11869af9L,0x63d01e02dc4c4c1cL,0xb43b904466a691e9L }, + { 0xab58d45ad1bbbcbeL,0x1e9b166322e8a57bL,0x88b6d3bb6684cdd9L, + 0xb944dee1ddaf3976L,0x70a4a121c347c41fL,0x7e93fa26fd1c217fL } }, + /* 54 << 140 */ + { { 0x5df68a1b584da350L,0xf378c367d72cd093L,0x5908ac0033dc31a6L, + 0x89bb976b7ca65b9cL,0xefdadfe237dcf670L,0xce22b5ba0011f3e7L }, + { 0x94d2c115b7d27bc7L,0x2e6763498761afbfL,0x3c0477829eb8185fL, + 0x634c8c5531f7635fL,0xf8fb5494d4d0fc53L,0x5a905615530ee2c3L } }, + /* 55 << 140 */ + { { 0xd28e59a0940c9809L,0xc208ae4f01b9f39fL,0xae1cb420b3630002L, + 0x739950501289d72bL,0xec24392805fcbd8eL,0x5b592df51f843891L }, + { 0x0d7602303f59f374L,0x32b6e643cae9f3ecL,0x94a25696e3dcc436L, + 0x657ae6aa8a059dadL,0x0df91017edd1505eL,0xfb1ae06f7b518d81L } }, + /* 56 << 140 */ + { { 0xf5bd119ad84c8a53L,0x36c5410f26928a6dL,0xf340f2bc0eb42b83L, + 0x8d93a66cffeffe84L,0xff59141d64310b9eL,0x2d509d7aaf69e00fL }, + { 0xf0f034ae1390628dL,0xf9089c720c38b563L,0x7462988e4e8df0daL, + 0xe6041dcaa7985905L,0x86295326d3b7274cL,0x5c8bf249075aa31aL } }, + /* 57 << 140 */ + { { 0xb08d098b9e423b93L,0x8ae94622029d192bL,0x05335f68fd67f1c4L, + 0xf3cb831f6e8c1e57L,0xf84a7a54a50a776bL,0x99930a48dc49c28bL }, + { 0xdac2ef8f1b833418L,0x87a4ca7829fda2f2L,0xf47f23079c0e9e7bL, + 0xebc1c2de46aeb3c7L,0x544f76836408bfc4L,0xa01b094b86c6cd44L } }, + /* 58 << 140 */ + { { 0x8e81bd1c06841f10L,0x3fc24a346c045063L,0xbb2be2dc85bc7ebfL, + 0x32523efbc341fe12L,0x1ac9f6b116508a41L,0xb6b7fa1df6ac4426L }, + { 0x2614c995fb685157L,0xe452b94dace46bbcL,0xccda1adabc453b4aL, + 0x32d32574fb4fac48L,0x7e43920c9d7d90fdL,0x9d6e959417a08456L } }, + /* 59 << 140 */ + { { 0x2c90f95bdb1f005dL,0x801089a2e16444a3L,0x2f2944ed7a724ad8L, + 0x0dfdd065de135e95L,0x510ab3eaafed3817L,0xdba075380855fbb5L }, + { 0x905f78bda10dde49L,0x63786348956a4057L,0x3d420ff0441530aeL, + 0x7a9968bfd1488ff0L,0x97479bfbca4dce2eL,0xf371985356f76255L } }, + /* 60 << 140 */ + { { 0x8102fa85bbda55a7L,0x6cbafe0de96c5eb3L,0x517720eb26aa52c7L, + 0x0ee110a98c030e47L,0x5a058569d4afe2c1L,0x29965b44262bbc0dL }, + { 0xda017ec04996daf5L,0x1781e7b84dfb810cL,0xdbe148350c8a5cf6L, + 0xd151055dd92ff62eL,0x5e4f48ba2932a708L,0x77e163d95f28bb43L } }, + /* 61 << 140 */ + { { 0xf6c5998c48bc9bc9L,0xb25ae99e2db132d7L,0x17f29131fb934e7dL, + 0x31b96a79d7fb5430L,0x3fad00391971cabaL,0x7f809e56cf3d5e33L }, + { 0x1a4f705a9ede6055L,0x3cab6c6149c2d054L,0xb616adc47945b589L, + 0x842b8652f342ee03L,0xa22fc6a67bc36a4eL,0xffdfee262c89a4fbL } }, + /* 62 << 140 */ + { { 0xac6b2727dab13b10L,0x8b4fa7807351ac35L,0x48243c245692808aL, + 0x724897f01fbc5d24L,0xb635fe5e2c69bd93L,0xab26453338d5d5b2L }, + { 0x368b2c07bc578c97L,0x94e02c9226fecf25L,0x768de4d41f473908L, + 0x58feaadee445d405L,0x1f1380d6e42a2218L,0x2904b4542154dd5eL } }, + /* 63 << 140 */ + { { 0x4e28b938ca2ec0f3L,0xd4af48d795b1c113L,0x33ffb9c222f2275aL, + 0x2a734af97b57b2e0L,0x1555ba38d08a45d3L,0xd0cae6c57a05837cL }, + { 0xed04c869c4e78884L,0xa7ba74726f3d56d3L,0xdb7b831ef6d68485L, + 0x225798677e7d0a4dL,0xd2d702a94c3eef8cL,0xdaba503869a83e29L } }, + /* 64 << 140 */ + { { 0x082ea61d10eeed24L,0x7c9d5ade143fd59dL,0x7d33df962e54f5cfL, + 0x340b0d36e39dc6abL,0xd97a8b848d179b13L,0x88184bb0288d388cL }, + { 0x2237e507e116ae6dL,0x3e97b063211b2cf0L,0x645f8bcb42be7459L, + 0xce2b0f54de2176b6L,0xaf570a09d1e2f09cL,0x110adf5657fdc001L } }, + /* 0 << 147 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 147 */ + { { 0x158bfe27bcb6db29L,0x967212410054d963L,0xf07b153b8e71aca1L, + 0x5e67698171b11643L,0x77b7dd7dd04e2f90L,0x07814aa6f0dcf109L }, + { 0xd3bab2a4fe1d0b1eL,0x50abba31be69e691L,0x54fe99afc6f53cd9L, + 0x071f2a4f628039e4L,0xf1f44181b183aa16L,0xdf0138e05010f6f9L } }, + /* 2 << 147 */ + { { 0xb1e365019c77ca60L,0xfe084a2301018e14L,0xbf451d2ca4bfdcecL, + 0xd210892fb29cdcfeL,0x5b12bcd894514871L,0xd03ca18c1809b1e3L }, + { 0x09b243115858e4eaL,0x37b30d50e57524b4L,0xcef0a16b5de334b5L, + 0xfe0bd1e20b116076L,0x54e4b48289ae2bf4L,0xfbcc5e1a68c8a937L } }, + /* 3 << 147 */ + { { 0xa5023e1364be0f56L,0x6a7310e00046f45cL,0xe0af09aeec8700d3L, + 0xdea5fb7ceb2d38f0L,0xc038eae6859852e6L,0xd515fb4c8c34f04cL }, + { 0x546b778e1488c207L,0x8cf4f1146258d8baL,0x474e60d85182c96cL, + 0xcd0387303dbde757L,0x387232f876ab01ffL,0x277614f628231392L } }, + /* 4 << 147 */ + { { 0x309b1eb33ef5a413L,0xa7607981a81f43fbL,0x87c2b81ebf8a894cL, + 0x27a40bce0d293293L,0x7f4c315be4bf3714L,0x03fdc14e01236895L }, + { 0x319c88f8dff053feL,0x146bb448ea3fa121L,0xfcc2a05df0dd1380L, + 0xc8d55b024acba9faL,0x871358de5927313eL,0xfd1d81d317ce294aL } }, + /* 5 << 147 */ + { { 0xa135970c7361138aL,0xd67eddb5b7d50260L,0x313c6e9bc4d5311bL, + 0x4f503bf28423e5b4L,0x17dc4b6f44f3fe83L,0x15b7bdb9ccf1bbcdL }, + { 0x0ce4d64ea11b9896L,0x050b0edebbb6b0eaL,0x85531293bf5db990L, + 0x9db3b964520d095eL,0xb45ec235bd2d4e88L,0xf88a9e6215ee5ba1L } }, + /* 6 << 147 */ + { { 0x10777189c1a21254L,0x7d8d3966ca593a6cL,0x261ab515120380e6L, + 0x453c858fe13577d1L,0xb1f6bb58f3862db1L,0xf8ff48b8b9529e1cL }, + { 0x03f63a417b60b400L,0xdc248d96bba66b3bL,0x8423048b756e5af2L, + 0x4d978ed31c984befL,0xa06242995ba00f3eL,0x0bed7b454f4d19e7L } }, + /* 7 << 147 */ + { { 0x9ef52e3d6524f389L,0xc5b157c5f6ac19eeL,0xdca7a72ab5d42f7aL, + 0x2d2e8d72fa0051dbL,0x3a6ff9243f4a4f60L,0x0ae997af340e7977L }, + { 0x33dd395e269db4e9L,0xf95c3683616b9dc3L,0xb86a066122d516a7L, + 0xd50c582cad913df8L,0xac8b8efef550afbfL,0xf34fcab01d88728cL } }, + /* 8 << 147 */ + { { 0xd3797831ff63ae69L,0xa753de02ce4c7eafL,0x2ff7a6a611a4e339L, + 0x904f86f05328043aL,0xe29d31c012e9f7ddL,0x8825a639c0a51904L }, + { 0x070c2696ebfc2cc7L,0xc03ce643c5f7a943L,0x5b970d0c12c8a1f5L, + 0x572aaaa1ab352a83L,0x63df45a90c5eb0c7L,0x95c951e1d4977599L } }, + /* 9 << 147 */ + { { 0xf5aefd5572ba3741L,0x7ab81965f5fe816dL,0x597d15d546752cefL, + 0xaa79a0822a3c142bL,0x038ddfdd3af5dfe9L,0x9f4dc166755c9e07L }, + { 0xf34224dfb9165297L,0x96e7ff6e4e3fd907L,0x5d7f3c821727beb6L, + 0x7098493dd6af73ceL,0x6b9358fbe00dfa4dL,0xefb2634a96e74870L } }, + /* 10 << 147 */ + { { 0xe35daffe2e4c6299L,0x1f9e33935915cd16L,0x93f05a40f009a48aL, + 0xa4a801fd308a81c6L,0x75e5dc467e885426L,0xf0bc7d5d4629ff05L }, + { 0x356b879bdbd812c2L,0xdb5eb60001629849L,0x11c9856eec2dd55aL, + 0x20f0443880f0c804L,0xc0b5e3e21801b217L,0x7ceba67d6ea097b8L } }, + /* 11 << 147 */ + { { 0x7a1bc5d85d08d3f0L,0x9ecce2a8385ef3a8L,0xae93d42b3c1b2927L, + 0x81a3a60719ce9447L,0x8d6b2d3d0eda597cL,0x5baabad60eea6dc5L }, + { 0x2cb372642741608aL,0x3b1148d6f0202a01L,0x6e85272f52931f5dL, + 0x49bf47596a2e601aL,0x5ec0418443279ddcL,0x7d052cac6ec080ddL } }, + /* 12 << 147 */ + { { 0x01c2df8d3bb02d0eL,0x874e43afe26f388dL,0xe198341c8360fa6aL, + 0xe67f8092c52bb2d6L,0xf944dc63a02efba5L,0x9a9c02d92c12332aL }, + { 0x39684f6ca8cb6bd5L,0xbcc1828e26bc9535L,0xb7fb8eb646594725L, + 0xbb4f5f05793c32ddL,0x3ef3c33845f94b55L,0x228e0e7d09eac277L } }, + /* 13 << 147 */ + { { 0x80d9bd388aeae732L,0x2be676dccbeb6443L,0xef4d056bded9ad31L, + 0xc4fea44f349e5d0eL,0xb66c35d28d95db86L,0x210c3d4aae9f5d3aL }, + { 0x5c0c5b9c1582982bL,0x50a529be93aed9a4L,0x88f769a384c77818L, + 0xc0970b4269776a3eL,0xbf3e5ee022a1cad4L,0x705c0b29b80187eeL } }, + /* 14 << 147 */ + { { 0xefd26dca727cacdeL,0x6290fedb5fcdb147L,0x9f108a89e1830a96L, + 0x7e8e36813e039a02L,0x1747b3e9256fbb3bL,0x5aa0ebffabb3b2f1L }, + { 0xcac5818c9fbb9b49L,0x037d66114a94b74eL,0x4081fd4d7a548536L, + 0xfe2d8e79aa364507L,0xe86ce00ea81a5f81L,0x77b95e9477a9bdb4L } }, + /* 15 << 147 */ + { { 0x3eadfde5bf06a49eL,0xca88828b33787c62L,0xde6f765022070f63L, + 0xcb4e54dc438f649aL,0x24957c77169727d0L,0xa2e7781cdd2a92a3L }, + { 0x17a1d7ddc38885f4L,0xb75716717605c408L,0xfdbbcffc8a2323f5L, + 0x11666bd2c955456cL,0xf8b94fa2517f27f5L,0xe101927fee002499L } }, + /* 16 << 147 */ + { { 0x2c5b0e42bca07a42L,0xbe57f3597a0dffa1L,0xace485959aa90727L, + 0x32be886af658699bL,0xce75d6c6da3b18e6L,0x9d563e4f69caf667L }, + { 0xc17c66cf065eb772L,0xfbe123814df9f6efL,0xceb80041623db4efL, + 0xe75615b2c74762e1L,0xade8a5438671c52fL,0xb713c401cacaf2ecL } }, + /* 17 << 147 */ + { { 0xc740669ab01b20dcL,0xd873f3f1abecc3f3L,0x0d8290402db73d1cL, + 0x147aaafb99198d33L,0xca66e755d4e7d7e4L,0x8747298cb2cb752bL }, + { 0xd9d58d29c43762aaL,0xa3801a4a15e45d57L,0xa747fa3f454eaf2aL, + 0x26c79cdd0c067c77L,0xf15404cea24fe6b4L,0xe2add5ec77fec1c9L } }, + /* 18 << 147 */ + { { 0xc45064dbd71a7744L,0x1900bb8f04a6f3cbL,0xd592585a76c2dd6cL, + 0xabbbd6d862b95d26L,0xb0db482b1d2e180aL,0xf459430184c9dea5L }, + { 0xd30b162a6e5ec460L,0x90838e57e4b35476L,0xab4b7c80f9356687L, + 0x72c2c009719f347aL,0xd5d01fcf920d187dL,0x47426f1e0afe06abL } }, + /* 19 << 147 */ + { { 0xe6473aeaafb2f584L,0xd5395475c44ab7a2L,0xcba2c240bc27e864L, + 0x201735cc742c1c9bL,0x8cb4886951263febL,0xb52706ba4fd2cd5bL }, + { 0x028445755a2dec94L,0x978e79d6a4be7b6dL,0x5a68d8103c4742f8L, + 0x9c917f48b301ad64L,0xa6a7d5bd684a6ea6L,0x251d61327c978749L } }, + /* 20 << 147 */ + { { 0xdc7e39ee0ae2a7caL,0xcdd3c235e6b7dee9L,0xf9624c299368c8a3L, + 0x2086bc904b21951fL,0xf7990a1f57e0e6a3L,0xf170dd75e686da8cL }, + { 0x4a82719a06da9714L,0x3a78e35e24274685L,0x1c3965e1c67712f8L, + 0xc6c26eb62f164e3aL,0x1129a467381fb91fL,0x896022108443ffddL } }, + /* 21 << 147 */ + { { 0x25e561bd808c4ff9L,0x08c9f2758c0cf1c7L,0x9af6165b59599115L, + 0x59f06a4bb4b415f7L,0x3a9d8ca5236e2650L,0xc8fa3bc61b48ebdfL }, + { 0x5e1896193404846eL,0x6d1d803b378a5a46L,0x672fe2bab812d5dfL, + 0x3ec27a7f04c6ddc1L,0x9c5ff08c0cee3357L,0x9f465babae8d37d3L } }, + /* 22 << 147 */ + { { 0x0057f60756a0b6bbL,0x46a6e9949c1e24daL,0x1c283f859baaf618L, + 0xd75e731be878a354L,0xf9db13388bf2ca71L,0x0f14adeea9022f59L }, + { 0x309f04aa6c14666fL,0xe6cec2aa552d2da7L,0x9f27eaba218d8659L, + 0x9b3165d3c268561eL,0xc7e3afcb90ae19efL,0xb840170bcb329e68L } }, + /* 23 << 147 */ + { { 0xf6b9a32fab95aa95L,0x1a1e06c387e1c3c5L,0xcfb7ecc5317f1c2bL, + 0x12953ce7999d2bcdL,0xcaf5f0229e3c5a01L,0x0c9db571305ac94cL }, + { 0xa423d26cafbc860aL,0x82fbbd3dfe98409dL,0x455aa9926652ac17L, + 0x6916e7d6f9428029L,0xdcfbd65099822714L,0x5de152a13f3c72d2L } }, + /* 24 << 147 */ + { { 0xe6d039ef467eb167L,0xa7e0959d74696cf9L,0xf3a19b9d7078d8a0L, + 0x5d4ec99c07cdc6f6L,0x4842d0f98386eed8L,0x48f5ab80545fc0d5L }, + { 0x8906fc626d39c2f7L,0x1c050d691bf5366aL,0xac506c579f54d0d6L, + 0x9a356a6ef9e4b94cL,0x62632c5108a75e61L,0xfc1b9fa5c6951dc2L } }, + /* 25 << 147 */ + { { 0x84ba4069d034ec62L,0xd55b42f6f169349eL,0x78dce88d17de2b22L, + 0xdadae679204ec730L,0xfad5ec6b5357f5e5L,0x330bba18ccc0d0afL }, + { 0x8419755c4a566c71L,0x29c56c5fbfe57083L,0xe42a7c52598cad77L, + 0x9d81623f5fcf1dc0L,0x978eb12864615869L,0xc837262a9c2a6f35L } }, + /* 26 << 147 */ + { { 0x917747f99ee0628bL,0x5d711303566cf048L,0x206d53f15b77f58dL, + 0xe104bc12667a86ddL,0x158f8d253505380fL,0xf5b32ad4616e821eL }, + { 0xdb67191a3cdfe797L,0x61b58589147e1756L,0xb7927e12625d0efcL, + 0x48d999d008bca937L,0x335c6f5b7b02689bL,0x4f0994a9d8149b7eL } }, + /* 27 << 147 */ + { { 0xe7ba0870df6ae3beL,0x661373f0166cd7d9L,0x369d361d8627f3fcL, + 0xca06d544cf6ceb36L,0xc819e0ea34b5d425L,0x80c1ab716ffd2827L }, + { 0x3fb8c0b520b4161cL,0x3647e67b3734b87eL,0x9c3a14b203e6c9cbL, + 0x320ed1c1c3620486L,0x6d77d46b5286a22fL,0xbd6036c1bc74a266L } }, + /* 28 << 147 */ + { { 0x125951a52e6d5433L,0x7d672aee6a6013d4L,0x6ed23f2560831997L, + 0xb0e219ae438c75c3L,0x6851dd4bace91d00L,0x84704f7d30f19991L }, + { 0xd744cb32d0107170L,0x15f51a63b0cb6796L,0xe14712cf5a5807d8L, + 0xff89f0c5dbfd612cL,0x0c314718bd021483L,0xf9ccd3b11b4b76d5L } }, + /* 29 << 147 */ + { { 0x36121d0909b6398fL,0xd9ad591369069016L,0xd3a08c8469cdcfebL, + 0xd92ae9b2b03e1e4cL,0x1620c549e9b6284bL,0x5860431227ab9432L }, + { 0x4e1d3134aa314da8L,0x89207aad70910cbcL,0xacee236badff9190L, + 0xe6390f7cf6eb6df2L,0x0dfc5a5cffa91d75L,0x3474104aa0e7f48dL } }, + /* 30 << 147 */ + { { 0x00b75b851871749cL,0x063b748ea00faa20L,0xa516e09f90257503L, + 0x9ffc43981c800098L,0x49f011f871b00fa1L,0x6fc80517443268bfL }, + { 0x2802e2bf24a24acaL,0x96fdc71edde88ab9L,0xe3eff1f997e661a4L, + 0xae5c34e13cb321f8L,0xf863263e301c8ba0L,0x3c3eeb7b093e186cL } }, + /* 31 << 147 */ + { { 0xc0f51229e7aa3325L,0x3abde561fa93ec80L,0xd7e5317f4e6df2b2L, + 0x4eefcc76bc832652L,0x9dce52905d054a1dL,0xee2939da2a6f52e2L }, + { 0x8faa1d3e092b5422L,0x77f55f7f9ca6338cL,0x6dadad8f6546d37aL, + 0x0ef4922ef3bf7cb1L,0xfcf41c23200ccc57L,0x591e208362aa0372L } }, + /* 32 << 147 */ + { { 0xa933aaf7a4886619L,0x9ec1915f4af13c7fL,0x25a9dff8854de496L, + 0xa8b31d9b247bec15L,0x468a25c84661e58dL,0x8989c046786a0707L }, + { 0x282db8cabb66922eL,0x73bf240d45ca29ffL,0xa2c40faaeaeda06eL, + 0x69632929add94b47L,0xc72354f6b0069076L,0x8d197fbf7878e92cL } }, + /* 33 << 147 */ + { { 0x7bd8195662267b63L,0x9352be73894a4ed8L,0x62568211d0bfdfdbL, + 0x7974999285698b05L,0x897ccd584412ea21L,0xe4cc4ddcb2f25225L }, + { 0x808539bdb4a1d924L,0x619fee34bdebf750L,0x47ed5b3473aea42aL, + 0x91e07a9b94ba376aL,0x218f6885edb27e08L,0x4feb09e6c4214344L } }, + /* 34 << 147 */ + { { 0x24bf9fbbf3e4bc93L,0x8973b72471151bfcL,0x8e33b753a85eb707L, + 0x13eba76e50adc461L,0xe445e8e144dd9d2fL,0x8729ec22b1592a0fL }, + { 0x9a13bf315ec24808L,0xe6ae840c2e95cabbL,0x634f3416e28cdf4aL, + 0x34d3349b9278cd7bL,0xd74990c542b912b5L,0xaf94b104b2430c71L } }, + /* 35 << 147 */ + { { 0x6d26cd01580b15a5L,0x5af25c06dcd849aaL,0x05b00800ffef39f8L, + 0x8cc59e06f9e0208bL,0x920f69540bc19bf9L,0xc06c4df97faa5ddeL }, + { 0x9a26a3f4770351d4L,0xda015bd3443f40d9L,0x1afd829c740f1942L, + 0xb108a8a6566e6158L,0x118e50a9a35e5d37L,0x94cac90eab72a3b3L } }, + /* 36 << 147 */ + { { 0x01f7968e60cb465cL,0x4efeffb796e0af3aL,0x6f9016e7066ad6aaL, + 0xa8ae30e88743aa97L,0x7b77d3e0b7d55766L,0xe1773661c6b3fadeL }, + { 0xa52fa7bc88f5270bL,0x4de08cb39f7f811cL,0x6021536f9bc34254L, + 0x47bd18cf4068e3d2L,0xc91bc312ce16889dL,0x468659ea929b71f5L } }, + /* 37 << 147 */ + { { 0xa5a2a3b3225b532aL,0x5ed77864167f7874L,0x2b5d475037ae42d7L, + 0x9bd62f14433b243fL,0xe8dca1b2eea90992L,0x1ce44e53ef5e0624L }, + { 0xd92c7bf61d3d7173L,0x83c1e65424c19a94L,0x59dce036eafe8941L, + 0x23478c50d81014b0L,0xb89214bbe65a18e9L,0xf9fd325ea05d9fb6L } }, + /* 38 << 147 */ + { { 0x2c4bbee73965ed81L,0x58b6a8766c1a47beL,0x7c8d94f71a67dfabL, + 0x865c9e42ac6ae9e4L,0xa63a0e42a3114c18L,0x7432c6c92bcf8169L }, + { 0x1927723c7532bd7aL,0x20b75c7201e5781eL,0x1963e16919d57f9cL, + 0x05427a3cb10e3798L,0x31bbc661cebc82a9L,0xdd88383ac3862997L } }, + /* 39 << 147 */ + { { 0xa0ef513d4adce457L,0x942aea7df9f906d8L,0xe52a2bb5fe22c5a3L, + 0xfd9fff1f8dec9ca1L,0x19b0e7a27913f99aL,0x58c45dd205660e97L }, + { 0x6722c47ff06d3c2dL,0xe4927a002a4d127fL,0xdc647c1ef40f46a1L, + 0x538c8cda7ab7a21bL,0x90227d6cc8015ae8L,0xe62f52dc2d4ec8a5L } }, + /* 40 << 147 */ + { { 0x69a9ebd8a83bbb88L,0xcbab0b5a29f98875L,0x325e487e4e7611f0L, + 0x90aa24b1d955cc3bL,0x840e70a13c264d53L,0x15bcf88bad7f4f81L }, + { 0xe47552cc2cf0df0aL,0xcb99973379205ea9L,0x25dc58bd10d5ca45L, + 0x0947d7151228b978L,0x9a0204da4f2c7c4aL,0x4377ea4a4690052cL } }, + /* 41 << 147 */ + { { 0x35da16d16bc7d7afL,0x098c4b0271de4ac2L,0xdaa2407c3655dd94L, + 0x5136884c90380d70L,0x3f47052e762f61abL,0xf715107a8dcd6ddfL }, + { 0x862a4a6e5d76615aL,0x2b546e1b2128a6f9L,0x5297a3cf40490672L, + 0xef2cbdf1b9c765a6L,0x52e71cb4426562baL,0x34d0e3237a84f9b1L } }, + /* 42 << 147 */ + { { 0x6cd4098d74e7c67bL,0x3bf4193123d2b418L,0x598710ad682135ccL, + 0x26ccbfe0172d648cL,0x0c4918c5d84dc9afL,0x346e8b6385065417L }, + { 0xcbc7f2efd353219fL,0x93637eea3c4e4863L,0xb18fc69c2dbbd39bL, + 0x20614dd45a4b5b0cL,0xcdac0383547adce3L,0xedcdd64842ac8be3L } }, + /* 43 << 147 */ + { { 0x76ac6c94b4559439L,0x09090af620319667L,0xef433d73a742e3beL, + 0xb7ec99eb7cbd7090L,0xcde2579dcb782be1L,0x2a2fb807e75552fcL }, + { 0x083f9e982f1eee15L,0xe20f65c167779c98L,0x73c044ff5f23e998L, + 0x5fce594269488208L,0x3e4ca86ccace7ba3L,0x5e3f43b8f32c1acaL } }, + /* 44 << 147 */ + { { 0x3ab171a237b42b60L,0x6501afcc4f20e50dL,0x4f9e22413e3a4298L, + 0x3c5834d9be3b3d3cL,0x9607b8cb9be25af0L,0xcc5f6b6f81c723a5L }, + { 0x11b9b5d199227bacL,0x2bc5dd9f322cc499L,0x0c3884a0cdbc3a55L, + 0x018a8ebefd4f004aL,0xa858ee7ce08741d9L,0xb5bbfa2b5d69b3ffL } }, + /* 45 << 147 */ + { { 0x57069b4a1b0611b3L,0x24b5421c89da55d7L,0x6433c29dcf9b2fb2L, + 0xda9382c67869a1cdL,0x67fbb7a343514903L,0xb3429e35e8b224f8L }, + { 0x4058ef1e7ac51191L,0x56283b0cfd4e6114L,0x4eff0caca16fadd1L, + 0xe6088db7b6ee634eL,0x94e68bd0ca7bd1b7L,0x0e98796b965ff86eL } }, + /* 46 << 147 */ + { { 0xf3176014bbd74a95L,0x5dfe36b51bc6c763L,0x4c463aa27d3d0366L, + 0xcbd7106cff3b113bL,0x2d660f5a0b6edee3L,0x92d79c864db04c30L }, + { 0xfd1067cfd2236e55L,0x1ae21f2d90925a83L,0x8419072ca952c451L, + 0x2f268b473d946980L,0x04831991b709ab5aL,0x0d622a70bf72efd6L } }, + /* 47 << 147 */ + { { 0xec468aecf0440b85L,0xaae6041369cea78eL,0x5a88145d12a30f40L, + 0x438c6e3f37a52bfcL,0x41bf603894749b6eL,0x3d38b86267edc2d1L }, + { 0xe379125a020a32abL,0x68a6b13a198c3944L,0xed1fb3258be252d2L, + 0x76dc8df6e15c37cfL,0x5a6592cb6453b542L,0x372b1998b3347c65L } }, + /* 48 << 147 */ + { { 0x015c325eb8e79179L,0xf4fc61335b57dce6L,0x27a51e5d78d6858fL, + 0x13babcab4dd5f180L,0xfaa19cb1847e499eL,0xe2688ae608aaea61L }, + { 0xe20d7edce86100d5L,0xa9b0d46bed2fedacL,0x5e99cc0c1d357dedL, + 0x4c1263ab723cac89L,0xad5f3e6ff15e22f4L,0xf25f3950d77dae65L } }, + /* 49 << 147 */ + { { 0xf3814fdba1c6fb06L,0xbfde395d8d71559aL,0x6e4b2b1c07e00f72L, + 0xac0d1aef1e12b111L,0xa4041ea0387dc52cL,0x8004ef4893c80d7dL }, + { 0xb311b5c29a770d6eL,0xd4a340bbaf41a540L,0xe96d1dbd9a5391ccL, + 0xcd4b19fb45ebf6ffL,0x142556a5dcb6dbe8L,0xf68968ff092f898aL } }, + /* 50 << 147 */ + { { 0x540a2e35c854356eL,0x6d0eab45f5002153L,0xb8f542bd9a6c488cL, + 0xd572d282c6201f12L,0x260bc62781a3eedaL,0x508621af06eaa5beL }, + { 0x754eeb205eadc8d5L,0xfe33248f42d4b0dbL,0xf44a1c7ac5529222L, + 0x9079ccb574396eeeL,0x6c4bc87db9cbdc41L,0x1ee8982431ee3f18L } }, + /* 51 << 147 */ + { { 0xb64fc90ed811f25aL,0x310214a2c82c8f68L,0xee559209b5052420L, + 0x6055c5b45c1bf95eL,0x414f7c8dedce3bc7L,0xd3438b8a66d3cfb4L }, + { 0x687b9f70d3935eeeL,0x553b15ddd3e179f1L,0xccc9961e21ff232bL, + 0x3729ac207d322041L,0xf1537630094907c9L,0x3e87f4f903153dccL } }, + /* 52 << 147 */ + { { 0x2c21e48c7dae4b17L,0xe842930a07ca1575L,0x3a3d6d361cc47ab4L, + 0x749dba405fcd07bcL,0x55a538a6f306a498L,0xe85c60be633d42bcL }, + { 0x777595f2dafa94a7L,0x1c690529a0400ef6L,0x41485f886bfa23bbL, + 0xdead14a1256d9204L,0x74f1a820bbda2f9fL,0xc86554f65fe54284L } }, + /* 53 << 147 */ + { { 0x03ee764b978ad2dbL,0xec253b0f01c9282dL,0x028e7873fb26c425L, + 0x3e1da0436504ba10L,0x68369881531961f1L,0x0365ea56ee435146L }, + { 0xf5505ae80c00a6b4L,0xc1ac097403f34fe3L,0x7327b391b5922f68L, + 0xe561cedd1845ef9bL,0xaa82258c6a44b29dL,0x23e39cedc4d56159L } }, + /* 54 << 147 */ + { { 0xf5a07dedd14a3ce3L,0xeda454ec9c47615fL,0x01d6b1562775730fL, + 0x3ec02f95fe4d93f4L,0x335806e4dcbd0ceaL,0x3f498d1b51a19d96L }, + { 0x9949c853374b7210L,0xb255d34b25980320L,0x3b681db4307b513eL, + 0x4137053add10a78aL,0xd9c0f2728dcaae0cL,0xcbeb6b7216031955L } }, + /* 55 << 147 */ + { { 0xd1b13e72c709af4cL,0xb4b99796c12f27fcL,0x9e56569a05e2c06eL, + 0xd8c880631212ba12L,0x8da1a6704e7f8fe4L,0x3bbb314f875bb39eL }, + { 0xc56ef7088fbc8a3fL,0x39b3cef2300d21bbL,0x5e755398458e347eL, + 0x9f7b84b16c1b2162L,0x278ffd26b08d0c52L,0x7c8a442a9ec7febfL } }, + /* 56 << 147 */ + { { 0x3c0e2b9737e8e6b2L,0xa2037913575da8b7L,0xeedf0a75b925cbb2L, + 0x4f28ec1bc561b405L,0x368fb2742901931cL,0x52b54eee2f26221fL }, + { 0x381845b6247812a9L,0xf9bcc9619115a0dfL,0xef127dfecb84d25bL, + 0x4256afe5fa10e0a7L,0x0c08a532353a15ebL,0xbbd15b176a91e61eL } }, + /* 57 << 147 */ + { { 0x3c573b2655574ae4L,0xd3f12e8f2c0be823L,0x5954b69fde9ce60eL, + 0xc433991bcedfd1eaL,0x35696716718e950bL,0xce4318664e9cc107L }, + { 0xee16b6347359991cL,0x8f05851b1818a113L,0x257a228c3b494b59L, + 0x4239f98e156f91f6L,0x2382157c72efdcc4L,0xc82b652cff7b7ac1L } }, + /* 58 << 147 */ + { { 0x072eee036b7a9a38L,0x42a680cbaef9b327L,0x67311eb8b56fb35eL, + 0xf320acf3c7de3776L,0x09c89cc3ed15e895L,0x368501713232345cL }, + { 0x5a5fe1104822f90eL,0x64f7ef18c6077b89L,0xbbc5748c8bdfb971L, + 0xdf5488334b6209deL,0x02268bf676e7f595L,0x1c7971b447779e75L } }, + /* 59 << 147 */ + { { 0x90d308b495c9497fL,0x277535b782c903f6L,0x443cd37fc5d7b4c3L, + 0x48ebf0acfcaff8a7L,0x8ee8c79e579f25f6L,0xb825ccd8360ffd90L }, + { 0x6327be1599fe4be2L,0xc94c68cf59ec2909L,0x0dbf8d4456660ce7L, + 0xbb31989b5d510edaL,0x43c8c365c4a2e601L,0x100de78314dcf793L } }, + /* 60 << 147 */ + { { 0x635ee0f3d33ac52aL,0x609c328dd1970e1aL,0xf28ddf0a09426902L, + 0x2a94d4decbbcbbe8L,0x15890cf4ab7ecf5cL,0xb14a405df2dd4135L }, + { 0x64659a4fa6d01554L,0x1d1b2c43cc966f9bL,0xb02ee871df0e48b3L, + 0x0bd13e47f4dc3ebaL,0xb4763547bb4fc529L,0x868650044068ab72L } }, + /* 61 << 147 */ + { { 0xe3d60dfac22bda56L,0x021411ba6be2f502L,0xc1dd4d55b35e750fL, + 0x708b62cd4d5e1648L,0x234a80c6347b8b8dL,0x53b6fa80f3ba912dL }, + { 0x4041b8007b92c92bL,0x636c12524b6dbceaL,0x4ea250d08a1aa141L, + 0x9ffa7e35a2ae7be0L,0x765c809cd2844e61L,0x5bcabd922d56de12L } }, + /* 62 << 147 */ + { { 0x48d594e522205fbdL,0x79c78f1c0862eb11L,0x02a3becdf7798099L, + 0xbfe574a8b1ef2ae5L,0x1bfb7779c4781f34L,0x7211dfcf044da23cL }, + { 0xe4c3fd7dc3686ef9L,0x14c6e5b5e74210f7L,0xc40a0a0275ab746fL, + 0xd2033594621f6369L,0x6bdbbe3d66241d44L,0x014b089ee47f00e9L } }, + /* 63 << 147 */ + { { 0x93e3a89108e65849L,0xf90a376ba1a712fcL,0x6555d6dff1a48fcdL, + 0x984ec5c86a763e90L,0x7a7fe565e55d6b14L,0x12550fe809b2e8b7L }, + { 0x21736c048e41210eL,0x72ae44d448ce08f6L,0x02755a2871fecc50L, + 0x379da24beb485ee5L,0x394cb7ba66d7b659L,0x49fc9d60ab638c33L } }, + /* 64 << 147 */ + { { 0x854b05846150771aL,0x35fdd9b4d9ca9868L,0xec8293894c32fc71L, + 0x882fad4c9ec8f90dL,0x2d39990dc6c7b9c0L,0x7fbc201bd71a25e5L }, + { 0x6b852e655166da7dL,0xc6bde23a3d8c6e36L,0x370011545857f048L, + 0x746621fc1ccb9bc8L,0x97e44e63612bb853L,0xabc3b450758da4edL } }, + /* 0 << 154 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 154 */ + { { 0xd25f650804926a41L,0x7236b475514045daL,0x0b36031108b9b08bL, + 0x16477aff3fe92e91L,0x6e5f6cb103189ddcL,0x81ff008ec698a38fL }, + { 0x02a09218c93adb23L,0x71fcecd3445d8faeL,0x55a15eac8fd6b76cL, + 0x1e37ec3611ef96b4L,0xd1b3b3fc30e433b5L,0x4951873351d174c3L } }, + /* 2 << 154 */ + { { 0x7914213db8c9f82eL,0x7a3e4e38fc038e90L,0x6edae5a126a34238L, + 0xe566bf50701ce8c7L,0x3562e87555656e02L,0x48325ebfb4e8efbfL }, + { 0x5f10a50466505ec3L,0xd8b9834b8da78aecL,0x49d1fc25cc2f2e40L, + 0xe973bb1caf5718c1L,0x9b8825dad2d6b890L,0x7de7885ee2f00f12L } }, + /* 3 << 154 */ + { { 0xfb0fa0e6494fe64fL,0x4ea468b59a907f37L,0x9bb6d672cbabb7ccL, + 0x523c7c6ea5be2b38L,0x4065adbb361c2e41L,0xffa1299925c13172L }, + { 0x0eb29793f80d5e2dL,0x862fe1ae8e4efeffL,0xd485483e948895c4L, + 0x513977300d80d5bfL,0xb4731ffc348782f2L,0x42543c76e1a7f6aaL } }, + /* 4 << 154 */ + { { 0xe37211be7ef79898L,0xa810387721344d16L,0xfdcd7e26a1b9f8b4L, + 0x5641e45d7d7f72d5L,0x5377c1bec449c920L,0xd3edcb0cefc7b2a1L }, + { 0xc657a9ffe14b42fcL,0xc8f858c800831b07L,0x6bfcd1bcd020eaa8L, + 0x17534b0a3f6860c7L,0x8ce5722284c7c806L,0xa1d40eaf2bd7456bL } }, + /* 5 << 154 */ + { { 0x28b88cbb1a7093caL,0x09275152080a85ebL,0x0bee7d979c1dcc32L, + 0x43698f5f5ed033a5L,0x4f142867b0f0acc1L,0x6e6202ecf62960deL }, + { 0xe95a607ff005b671L,0xfeee8ea060cae478L,0x456bb6e90e8ec6e5L, + 0xc1c0319a9d088a59L,0x29c6898bbe3d2379L,0xd7049b2af8a8628fL } }, + /* 6 << 154 */ + { { 0xe0c93007c9aa57eeL,0xebb2d47b8895a604L,0xb8aebc49c4fd6ffeL, + 0x2c06e1e573f300b6L,0xa019070d81628b8bL,0x2db1690bbaf8c1eaL }, + { 0xb3fce6c8cc94ccd2L,0xf301463885bcdf4fL,0xb1e62616e2f82c32L, + 0x85581e2468295a54L,0x0f2e2ff5bf51f8faL,0x940716f1155c1f6fL } }, + /* 7 << 154 */ + { { 0x15b2dd270c6bd5f1L,0x07b5bd91eb086d0eL,0xe701742e97c5f5caL, + 0x3ce5f3f6eea06ea6L,0x51a81a6aa9cee784L,0x2bd404c1c7182fa7L }, + { 0x27deca74d5b8bde4L,0x2c1931c595385e4aL,0x04fcb34e3a79d65fL, + 0xdf3357edad1babceL,0x8bc628ffa31af476L,0x42ce1d91e5cc9e78L } }, + /* 8 << 154 */ + { { 0xaed02b6b4e623856L,0x7a6d2bef3e1d74cbL,0x82226ec4654e7c30L, + 0x008ac003e7034bfdL,0xe343c5407fd6b555L,0xca1b29071b429d44L }, + { 0xe0702a339c3ceea2L,0x48079aa9732694c3L,0x7e6d72f6d4652401L, + 0xd92655ed35f60043L,0xa0dbaac6273e8cc4L,0x0bb8f0f93c3ffb40L } }, + /* 9 << 154 */ + { { 0xc3134781a91940b2L,0x37579fc9e9b90620L,0xa506227a08acd6f1L, + 0x603ecce0270da73cL,0x8a53b67d7fdd70cfL,0xe29b7df299640bd6L }, + { 0x7bb4fa877569105dL,0x6ee80ae8567bb5e9L,0xf394bd02baccabefL, + 0xe854b3a6309c944fL,0x1271a131f06246e9L,0xbc1c205531580147L } }, + /* 10 << 154 */ + { { 0xb41b87b6c95cd23bL,0xb99714ba55e371a4L,0xb138ee8f6f571cebL, + 0x09c42be480146ec7L,0x275ee21eee9aa125L,0x0cef4d6f3a878b59L }, + { 0xd436eb1ca801068dL,0xe2c5448c762b8a80L,0x243beee1f3640ecaL, + 0xf979458b32bbba7aL,0x6bc26cfea63407d3L,0xd3b6e132392dd1d3L } }, + /* 11 << 154 */ + { { 0x123ae65005d0072fL,0x9f101624f0656bbeL,0x762bd4f4344e283fL, + 0xd1f70d5161b6863bL,0xcd99382592ef9a38L,0x53aaa0c3ac2bf9bbL }, + { 0x13904fb521ef9a43L,0x0470a8ba2beb8f44L,0xf3733943fcfe9ecdL, + 0x10b8881a79d776dcL,0x89b94c67b82b7139L,0x7af5147aeb962922L } }, + /* 12 << 154 */ + { { 0xbc06ecab3de4ba2eL,0xf51ca0639e491bcdL,0xa6fc6fa0453c94beL, + 0x5460f943ed1a6731L,0xeb11656a4ec3f1fbL,0x2fcb2cabff1e7d4eL }, + { 0x595264678fea2286L,0x838117a34e0bee38L,0x7bdf588824fd2ce5L, + 0x13df0c839f2c2925L,0x1bf621e6dee97f30L,0xb43b2558ebea6641L } }, + /* 13 << 154 */ + { { 0xf49a97d80a33b97cL,0x4e68d71512ab9bcaL,0xc0d361c04bdb65a3L, + 0x5fba9fb86cfb0cafL,0x222e12ca2a716589L,0xaea01502731f5099L }, + { 0xf322ddf7e97b37f1L,0x050e82a5e55c844dL,0x01ef972ba11d664bL, + 0xab30502882c737b6L,0x43aa811185e39769L,0x766a9350937c1456L } }, + /* 14 << 154 */ + { { 0x246c86608e729329L,0x39fcc41dd693dac8L,0x48a65b54c062a6c0L, + 0x368a57706a5a3101L,0xd143600f47ed1988L,0x48466d92a764ce3dL }, + { 0xb05006135a22cb6bL,0xf1d77247edea070cL,0xb1ddd151617f2464L, + 0x7905069828b83fd9L,0x021abb26d70bf93eL,0x590b3c42ab5a5e1eL } }, + /* 15 << 154 */ + { { 0xe86c737b728b8438L,0x21f45a22acf1dd66L,0x6f29f2d7abd4de3cL, + 0xa223154576d4435eL,0xad902927f5fcafadL,0x272cceeb04f30557L }, + { 0xc2e4e0017ebbb2d6L,0x73954580bb873ec3L,0xadf5ec7ac7fa9088L, + 0xc036da0464006dd7L,0x9c3545b5e8274f69L,0x6e153c2552325f50L } }, + /* 16 << 154 */ + { { 0x5906a35c1cfb991fL,0xb62a4f80740a7744L,0x65c8ac9136f84763L, + 0xf73b3debbe0f1dd3L,0x40358868a2d26c21L,0xd907e90a76792ae7L }, + { 0x3ecea167668c3d5fL,0x731068f26754b49cL,0x6db891090e006243L, + 0xd29106e6dd94681bL,0xb40b8694a85a3de2L,0xc80c7bf1936b86ccL } }, + /* 17 << 154 */ + { { 0xd735de6b91f7c76aL,0xd89aa1d4b054837aL,0x47c1a397271e94c4L, + 0x8d91f3f9dcb7c071L,0x4cf9be2db4cc209dL,0x4fb6842ec08190d4L }, + { 0x926423a1d7b2aaedL,0x5bbfc08957a1cb44L,0x44438c56021defb3L, + 0x8b9a2b1ba09863cfL,0xc9d5c170e37e339fL,0xa8994d5dabb18c7aL } }, + /* 18 << 154 */ + { { 0x003d45d011913575L,0x866cb2dd87e1186bL,0x692f630146b69a22L, + 0xd296a55c8174c1d1L,0x77ef6fbe9f17af00L,0x6b588be93aa922e1L }, + { 0x99ecb44f033e6dd7L,0x32edea2c1d22b7cdL,0x3122b027ba7006f3L, + 0x8950054bbb6ebc5cL,0x4f6d606182dab805L,0xc12055181bae5f1bL } }, + /* 19 << 154 */ + { { 0xeca71515ad7edd2dL,0x3f9c330e9bf56567L,0xd0b62d6749104bb1L, + 0xde92596410cc8d89L,0xc7a083f4287fc898L,0x8ba176e712d15d2bL }, + { 0x2cee62f7b4c8c4c1L,0xc15966c2ef79aeb2L,0x9b449522427c11a6L, + 0xcc850028eb49b2fcL,0x0966a06d3a22720dL,0xfd511944a1e78c8dL } }, + /* 20 << 154 */ + { { 0x28d33e79e08c180fL,0x768c7794f6aec9ceL,0x5a749f3bce683c5bL, + 0x717629d98371fe75L,0x5e828fc057712c1dL,0xb46c6ed17e4c61aaL }, + { 0x5d927bad5bccf95cL,0x55d6fc80d72f68ecL,0x560a99a398591dc2L, + 0xc885fe8a4836664cL,0xd18acd4226d79298L,0x05e4cd17185df1d7L } }, + /* 21 << 154 */ + { { 0x9c1e5db3ab34fbbeL,0x0d4b1e742f7eaa94L,0x106b0b5c86de1289L, + 0xd2c6c1aab691a830L,0x2e55cff9b9717593L,0x4522b37d075e5e95L }, + { 0xc6ee67ea3abfeb96L,0x35844bbd890b04eaL,0x0246545a55d6f65bL, + 0xc66bad2b13594e25L,0xaff4c6b35d6aa7d1L,0xebb7d2b5a3f42a84L } }, + /* 22 << 154 */ + { { 0xebc60e21fcc83355L,0xc94dbc02d9119b77L,0xceb05a312f18ae9aL, + 0xa8462962b8f69016L,0x58dde5a48f67b5f4L,0xb8bdf9c9af3c234dL }, + { 0xe95c069f80e85df8L,0x9d525e1bab3aa0e5L,0x73c8a92f76276d8bL, + 0x7feb4abd163530efL,0x8ca949b35ef5ad73L,0xe129431e2e3d057bL } }, + /* 23 << 154 */ + { { 0xa263d726c129d188L,0x89da948e9d526adbL,0xc7319a5a6b8a9149L, + 0xd85d382d8816f421L,0xfad69eb1844032eaL,0xf668901a4233122fL }, + { 0x246cc0de210ddea0L,0x26d8ccb70bc07dbaL,0xfc1b558470e6708cL, + 0x853802b775fa0b44L,0x215ccb88bb75a5b2L,0xff50f0cf24e60054L } }, + /* 24 << 154 */ + { { 0x9d8a925b60dec308L,0xb72e3efa6b3ea363L,0x4f53ca6ddfb534b8L, + 0x4e64874c6dd78a32L,0x336e5b46c2a146d5L,0x07c76d6398395201L }, + { 0xa4c095228fe3e815L,0x887e659d3221cc26L,0x0ff92f64c36286ecL, + 0x57b1b903c3ebb08cL,0xc6bdc9b665f00c30L,0x826242269a46d36eL } }, + /* 25 << 154 */ + { { 0xe054597768bbf4f6L,0x17bb77edb6e2cc19L,0x0cc551d89ae950f7L, + 0x3490778d761763a4L,0x1c36044a32647ceeL,0xa6e083223f9d2938L }, + { 0xea392a153a656a51L,0x4d51161ba083cb54L,0x15c01e792c690757L, + 0xc7bf5d7c5cc62636L,0x1b00cddab2ccd76aL,0x68f49fa995313f8cL } }, + /* 26 << 154 */ + { { 0xc782c16c1a0b619aL,0x8643d42bbe316086L,0x49d2966bc0daa421L, + 0x080b1cafb7b487e0L,0x1d33bb53144de273L,0x8bafce2d6faf7ed9L }, + { 0xdafbe3cf408d4636L,0xf10527df7ee8835bL,0xe1123f3ee2e75522L, + 0xb388c64bebe27d60L,0x2cb38dc1e3f1f55eL,0x57ff8e43e34524d8L } }, + /* 27 << 154 */ + { { 0x557dc1cbea28398bL,0x34d5709a208996b9L,0x94470993e97a3306L, + 0x0343320772b117f3L,0x66c4e442f056525fL,0x27753c526d11dd35L }, + { 0xf0aa7658b26a70d7L,0x95608b19543cd7ebL,0x618b2e17bac19156L, + 0xe7e42948cae64ba1L,0x2016a9d59657ec93L,0xa38f67e03d7ea46cL } }, + /* 28 << 154 */ + { { 0xd67dc92b85653dc8L,0x8e0970af0bc93ab9L,0xb6f09baa8b87c0afL, + 0x5a8a903052760ef4L,0x2e2ae7561047bf85L,0xd049078f85bd4e74L }, + { 0xced11ff83729f708L,0xdd21cbebd91068a6L,0x83d488ff24b3e911L, + 0x6e166fda1afd2196L,0x66a912114f0d2128L,0xd11078ed05c9f39cL } }, + /* 29 << 154 */ + { { 0x69aef6f919c64bddL,0xe7d4f909598ab592L,0x48952e280e55124fL, + 0x637693f6290b558bL,0x3afb2e7b421e60e9L,0x00d1dbac79aac8a9L }, + { 0x45156c5cc08563d5L,0x8cc201be4519c881L,0x2e36c0d7bd616581L, + 0x595fe0164ee16dffL,0xeebec40ae4889c65L,0x23b6dfd7d35b94e7L } }, + /* 30 << 154 */ + { { 0xd87003d3bdbdf0cfL,0xe9750b5b56c298f1L,0xc256c3a2b73ad05dL, + 0xe0779a192ee94279L,0x31d8b3c6279626a3L,0x469056bb90163bc8L }, + { 0xe6aeabc623755853L,0x9fffdfe2896a6f4cL,0x15c1ce78a36cf41bL, + 0xd4c8c025eee41941L,0xf7a917ee7653be9dL,0xfa3cba9659d52222L } }, + /* 31 << 154 */ + { { 0xa02f08586d8c610fL,0x9819c563ad4af3cfL,0x085d4439b95d17eaL, + 0x9df256ea616f532aL,0x5e9c5419cebd249cL,0xdd5ffbf451062a22L }, + { 0xb8910ea5c8b33577L,0x5e8b7ff7ff8e63d7L,0x5e4f3926b24e230dL, + 0x163eb51eacd851d7L,0x9bda95f2ea2aef8eL,0x3d6887755aefa290L } }, + /* 32 << 154 */ + { { 0x913f92075f8ab132L,0xd5b6792c5c14080fL,0xefab4e2c787c3594L, + 0xa55d465fe7b7b7ddL,0x921aaad834e28e6aL,0xc4f3a35e12d6a7bcL }, + { 0x109803c46115a5aeL,0xc023098ce709f9a1L,0x1a8c8bdb99c5bb66L, + 0x1cd1c2b6bc7c2da7L,0x50189c975f927eefL,0x493823d1229f9410L } }, + /* 33 << 154 */ + { { 0x34ec4dc840dedfb0L,0x1109ddb93aa89063L,0x93d9db278c218bb9L, + 0x07131b6e0b6007ddL,0xf90570ddcc4690f0L,0xa6a9a634afa26a59L }, + { 0xbd0c25194292e2b7L,0x92b99706a6d44b7eL,0x89481adf4942c03bL, + 0xff5e56b98a0c30d5L,0xdfd8939591c80fafL,0xed9d140840663594L } }, + /* 34 << 154 */ + { { 0xcc22db55c41e42fcL,0xc90ec77e4c9f2411L,0x419b9f46e4c02557L, + 0x156ed30ccee45c60L,0xf2c1340a72e4a938L,0x4a9cda8a204775a8L }, + { 0x900fd58713952b75L,0xa82ec2b812461145L,0x9f1875d41db68028L, + 0xaaa6af31308475acL,0xa11f379442d4b884L,0x1f1fcbe3d087882aL } }, + /* 35 << 154 */ + { { 0xa32d5a80a292fbecL,0xe0b10099d7091eabL,0xcb99bf7b4bfe6956L, + 0xfd806d4c61955461L,0x7124b1bf931066fdL,0x29fad019649ccbf7L }, + { 0xd1fe7911049609e7L,0xb568e167592f93c1L,0xabe7d10398ba066cL, + 0x0cd22c9668d7ac2cL,0x0ccd0c21427522d3L,0x97ba199ba503b4a4L } }, + /* 36 << 154 */ + { { 0xa0f2da0c78a2cbf7L,0xd1611acbd163d80dL,0x1af6ee1bf2cd3795L, + 0xc4993e08307d6105L,0x84c3b8f8560b5f12L,0x4f52c56347869733L }, + { 0x8fd9e3f728d28bc6L,0xdbf34576e5d44bd9L,0xf7e3a6da10d14cb5L, + 0xb93870990fe051ffL,0xf6363a48f15d43d5L,0x4bc358fcf434d1acL } }, + /* 37 << 154 */ + { { 0x35bac9471eae6dacL,0x4244697e39d6fe97L,0x16ec7f64fe017230L, + 0x393856d10493823cL,0x0782fbb55b7cbbfeL,0x4c399e3f5820f9f9L }, + { 0x86311cd9c08fe816L,0x057d4cbbc3ac958bL,0x63f09d484bdb0531L, + 0xab0b582b0b89ea02L,0x19c52243beb30331L,0xafa64f25ca87ff6dL } }, + /* 38 << 154 */ + { { 0x0d28a67859b1f4aaL,0x79b04589c52d40f4L,0x443b7fa5219303d9L, + 0x5be78d9663972eceL,0x0ccb969e7d984869L,0x7d8738077f81916fL }, + { 0x3502b3e426d9f292L,0xda1de7a82c90b612L,0x5605f5dc434f27c0L, + 0xa50d3328df89c616L,0x5a80cf84e7082731L,0x2c89e4b6f7ce953aL } }, + /* 39 << 154 */ + { { 0x7a46cd0d01fdf1e6L,0x86868e74e8690fbeL,0xf038771d8a8fc3b2L, + 0x30135b3084303d90L,0xa7ecb9ded562d20bL,0x7a6d1f37884cd233L }, + { 0xa30ca0bb07dfad3bL,0x1690d6018e09fa7fL,0xe582449f6c744551L, + 0x0b0030a21b935d17L,0x6b46681272bdb78cL,0xe40d4e5f56d4f328L } }, + /* 40 << 154 */ + { { 0xa29978fc62a8b8b4L,0x4cc216310fa130a9L,0xe4b51c6bf15e04c8L, + 0x453cf4d23f815420L,0x1257c751c6282b9dL,0xcd15b03c8af1af36L }, + { 0xe3596240514ef6e8L,0x72a6691708ab83d9L,0xca0a62d710e44b2dL, + 0xcde068128a9b8a8dL,0xd492b261ba470875L,0x5c7ea67cc6d7aeb8L } }, + /* 41 << 154 */ + { { 0x6acd945fc0995487L,0x06d5b2e47abac4fbL,0x42cddd75aaf3d12bL, + 0xca7d2363de1b9632L,0xbb1a1990dfbbb30fL,0xb0beb43139fd7bd4L }, + { 0x9ceb36884fa796e7L,0xb4d2bc4ba3266ab8L,0x79bda9d6e02df012L, + 0x414636bbf6faf7c4L,0x0a6603b9d1ab23f9L,0x2bc60c848db14f7bL } }, + /* 42 << 154 */ + { { 0x1b36ef27007ff90fL,0x394fe8095111399dL,0xaf4f246cb758e748L, + 0x794e4b151a7139a2L,0x40869a49eb527db3L,0xf2e15106f46d1b34L }, + { 0x46619f0352ac96e6L,0x40f556de49caf0c4L,0xa36b11d693072befL, + 0x871919b4ab2dad50L,0xf44b8084792dcefdL,0xe051823dbc31b021L } }, + /* 43 << 154 */ + { { 0x56293d8dcfd7432bL,0xdedf8dfd1d5f72c4L,0x743f4a71ae604fb4L, + 0xfb35ab43730caf7fL,0xcaacce6b20fc2167L,0x21ec3a0daa8ac71aL }, + { 0x4fdf5890c21ac9baL,0xbdc41ecfd6149328L,0xb1ac4d519b381c55L, + 0xc4cc08fd63f10a98L,0x2b9f0d3a4913a671L,0x9ce9949cbc36a952L } }, + /* 44 << 154 */ + { { 0x5049a7d3f758b1b2L,0x60beb74f14ab97b8L,0xdfc47828a9ff8ad3L, + 0x303a0cde8bb99766L,0x53f4b45a43b9a7a6L,0xe467aec8ca6e8c43L }, + { 0xb8e7db7b3f573855L,0x5fee5a5481e760f1L,0xe928b23385b0fed4L, + 0x72f02728ebae0b7cL,0xe32abf70bb5897d3L,0x103e8b859c572995L } }, + /* 45 << 154 */ + { { 0xf321278c2dc1a02cL,0x06ca03865dd09f91L,0x3c28640b7bac9e7aL, + 0xe3a7f9b527b1a011L,0x9137ad0407ccedd3L,0x3a2976a8cb6b447aL }, + { 0xab1c39248225c1ecL,0x30703f108f9022a8L,0x212f0f1bb0b2a64bL, + 0x76ad924b3e73862fL,0x47253a5c84842ac8L,0x33a03a17755af95eL } }, + /* 46 << 154 */ + { { 0x97c371fc5a274b61L,0xc7362cdbb14c680bL,0xa8cdd929efbd49afL, + 0xdfb2d5f075325f06L,0xf62d10e2b905531bL,0xbdfbfd8462ed0c3aL }, + { 0x252061599d07d2daL,0x1376775152491224L,0x165637057413313cL, + 0x642a7911a2b88eb1L,0x42d9dc6806ffe363L,0xe81d3403017bcc9fL } }, + /* 47 << 154 */ + { { 0xa68ce9db93d57f06L,0x4d1fa86a31dba07dL,0xf11603178c4822abL, + 0xc2243680633c26f5L,0x6b4e91cd10f1da80L,0x4358155734827d78L }, + { 0xbf54e87400c19817L,0xf52b94c4f2bad957L,0xcc85de8144e71756L, + 0x4f7d8ca365b7a8c2L,0xff76efa579d7c36eL,0x50a444025952932aL } }, + /* 48 << 154 */ + { { 0x87c0ef84172784bdL,0x023128267a5f2d07L,0xeae5c0cec9901fa3L, + 0x6ea74133a11144e5L,0x740c3d2ed8e89beeL,0x88e06131f9bb1801L }, + { 0x47f253754356fd51L,0x8e2ca6ce38e45ea1L,0xf0afe990c2ef8066L, + 0x91b7263d8ea03d0fL,0x37b01664880ca591L,0x61306f09790c8ed7L } }, + /* 49 << 154 */ + { { 0x084c4f92b24a5736L,0xf3d01da90a3c3859L,0xd37c47ed7468b812L, + 0xeb539a939567c798L,0xd852f502acfdc072L,0xd8e5454996245975L }, + { 0x42ec3948db5e323dL,0xdbebd1c7002d3fadL,0x9cc5db55d7c62d0aL, + 0x22af02388afa4c07L,0xbdcb68fc6979eb74L,0x33763dd544dc11baL } }, + /* 50 << 154 */ + { { 0x4734465f87c2e496L,0xbafe4fb4eb7d82c4L,0x940b168521837f17L, + 0x790d7041345a66c3L,0xe9973cfd65ea596cL,0x45fc95df058b3350L }, + { 0xc63bf91405d08638L,0x36e6af6476465a92L,0x7fe09193f1eb3701L, + 0x364f64f06468e2aaL,0x83108431f7129cc9L,0x3ac117205606bf94L } }, + /* 51 << 154 */ + { { 0xe6a85c7d34dcecd9L,0xc14437fe338cdc1aL,0xa5eeb471b3a9233eL, + 0xf230947c71349a62L,0xe704a95686308ebbL,0x0ef4d4da4a362a8dL }, + { 0xae9be4394b634c67L,0xf736c07c569f0039L,0x7356f3010f5f07d9L, + 0xc86c4000823c9cecL,0xc43b3489951ab5faL,0xa7a3b3a6b46bb659L } }, + /* 52 << 154 */ + { { 0xb1d6cb737337af87L,0x09a59a6908638c3cL,0x4ecc3fd25d94c727L, + 0xa7b57269e274ba87L,0x909cd824a61a0590L,0xcbe63cfe3c11751dL }, + { 0x9574de8347c46efaL,0xee334cda539b7e03L,0x245bc6a2e3ef3599L, + 0x13a570fee88d0da7L,0x88ede26d90ef4a21L,0xa0c5953b01fccebcL } }, + /* 53 << 154 */ + { { 0x855ff0f7657121c2L,0x18754814f94c7402L,0x720f1e3c32ce8340L, + 0x7ecd080ee8e49d3dL,0x2838e642f0bee412L,0x69cad618209f8e60L }, + { 0x5730f2dba983a4cbL,0x74957697f43896a1L,0x68de04373dc55d4aL, + 0xa2fbb915628698bbL,0xc8279c975cace19dL,0x7df557465fd52bc0L } }, + /* 54 << 154 */ + { { 0x1cb1c2f378c3f521L,0xa425f99b63116c7dL,0xc86b48c36f7c0e71L, + 0x9e92e82dc76a73ddL,0x8c0414657e7d6df8L,0x99e7884d38c02d8eL }, + { 0x6c53c0cfb78a7e50L,0xcbcb5114481d60ebL,0x1eed68ed035b4441L, + 0xdc95269f755f18efL,0x3ad7f32a3fe51f12L,0x981782d017296245L } }, + /* 55 << 154 */ + { { 0x7743ef2655fcd15eL,0xa73944a4d07f3cc0L,0x3161d6a32438cf14L, + 0xad193a9b14e8938aL,0xe1de190e872dac01L,0xb165da2fc4795b10L }, + { 0x1eb89d519e155bfeL,0xc8b97d94c9c552d5L,0xea7d3edb108c4c82L, + 0xafb60b29c10acbb5L,0x331b316b82c7b642L,0xa53c4b3d719fa342L } }, + /* 56 << 154 */ + { { 0xc8dc34f36b3bcbdfL,0x952d337b24d72806L,0x28b8ec817e56e8c8L, + 0x98e78abdbe861aebL,0x521773ddcf3bd040L,0x582ffcb2b7ca45d2L }, + { 0x70962c0a04202ac8L,0x31b6ac909f29381fL,0x3b4cd403355715a7L, + 0xffbbd1a7399a071cL,0xac669b08e50f02d7L,0x0f568c89b2cf0565L } }, + /* 57 << 154 */ + { { 0x2d2afc2daae7e637L,0x840e47c782a818efL,0xfe26a67c879f2451L, + 0xd41d289810f54247L,0x36040f4877119f14L,0x741859a983f240ccL }, + { 0x15f9607a8fa720c8L,0x8eb70f6df7b8e32dL,0x755394229b98d670L, + 0x80a4a127750c4e62L,0xbe88d03195ca3a50L,0xfadeb53dc6411eb6L } }, + /* 58 << 154 */ + { { 0x19f29da06b824028L,0xa5cfd12b7bd354a7L,0x1cb5d74caeb59b3aL, + 0xec9a8ccc47211999L,0xd7f2a1c17852f167L,0x134629209a1859cdL }, + { 0xdd65f7ac9e3a339fL,0xccaa968075437831L,0x25772f9b7f502bb0L, + 0xa64cd12f6fa0aa66L,0xd2f46ac62af2c3d4L,0x58433d963f262a2fL } }, + /* 59 << 154 */ + { { 0x747757c6715ba7e6L,0xc01b73c1f9cbefd2L,0xf1d96de501bbc017L, + 0xad554e91a1087f55L,0xd9b74be65a6cc716L,0xad2f2c0320317019L }, + { 0x42ef19c207893532L,0x7f3624c40858fdc1L,0xc104bde7078936c6L, + 0x99af706682b5f95eL,0xa40e02625a13a9a0L,0x6c0251c40a318574L } }, + /* 60 << 154 */ + { { 0xedb3abb1fe36eed2L,0xbb2cc1e6a038298aL,0xfa0ac06fe5adc3beL, + 0x7cbcef3eae73ebe1L,0x41596590cd676b87L,0x6cc8c0ae214391d7L }, + { 0x826e2e16fcb3f244L,0x1ed7837e1be22058L,0x83052d0d1a9912b3L, + 0xa2cb410c8ac3dbf5L,0x279d555a7faa6bc7L,0x870e7132f52b439cL } }, + /* 61 << 154 */ + { { 0x5957428e385308d3L,0x49ba20b3bfdae187L,0x4e1281c3adb44defL, + 0xebe93dc4e75c6cf9L,0x81d1d1cff675fc6eL,0xbe01bcecfe0e371cL }, + { 0x713f294d336bc7caL,0x1beb1508e26a1903L,0xbb5feab4b6819961L, + 0x28bede2741bfc7efL,0xb0a5108bb3365719L,0x81a8c9255ccd21a3L } }, + /* 62 << 154 */ + { { 0x4f3d90af2bea6870L,0xfebb0de2ca26ca46L,0x109d96e5d58bd9d2L, + 0x4b42928cd9882c8aL,0x5238cb7a8c73adcaL,0x9d79d72a4adfc913L }, + { 0xba58929d1f0bf201L,0x0b7790a505f52baeL,0x361949aae45fda0bL, + 0x21b2d006af3f732cL,0x1ed05dc33aa84bf8L,0x2322b7f72405980cL } }, + /* 63 << 154 */ + { { 0x4a38b5b2c7151e42L,0x1d5dd94894550168L,0xf2adeb5b7b3d1d93L, + 0xe15c42fa36661a89L,0x7d55a3f27a3aee90L,0xbe1b5c39d9d350a4L }, + { 0x9c4d6fa2610f16b8L,0x7b96051da60fb18eL,0x539762fa496c018bL, + 0x048ffa39168a8f22L,0x33486ccada1c0a58L,0xe216d6be9fd687a1L } }, + /* 64 << 154 */ + { { 0x11a8fde5f0ce2df4L,0xbc70ca3efa8d26dfL,0x6818c275c74dfe82L, + 0x2b0294ac38373a50L,0x584c4061e8e5f88fL,0x1c05c1ca7342383aL }, + { 0x263895b3911430ecL,0xef9b0032a5171453L,0x144359da84da7f0cL, + 0x76e3095a924a09f2L,0x612986e3d69ad835L,0x70e03ada392122afL } }, + /* 0 << 161 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 161 */ + { { 0x3ee0a31c6754f492L,0x02636c6b96769ff5L,0x90a64f4ff0fbfa96L, + 0x513f054efafea65aL,0x796ba7479cf4b9f9L,0x3198c068932a9590L }, + { 0x93af8a65549ee095L,0xb8b6f72ca212760fL,0x23bc71e9c1a46c8fL, + 0x000643af4c9bca72L,0xb6d967c7848cea30L,0xe06b6b4e73312ec2L } }, + /* 2 << 161 */ + { { 0x52ec99561d85a725L,0x0f9be000f3208012L,0xe881337c6dcc7816L, + 0xe4e7b6d9791f7cf1L,0xfaa717aa59885a42L,0xb1bbb5c7f9c01e41L }, + { 0xcf208d58a0361880L,0x24426e4020afa350L,0x7261871b264ce04aL, + 0x66be4a86cd42026aL,0xc5397b77829f99feL,0xffe4a6bc24578e2bL } }, + /* 3 << 161 */ + { { 0x0733667af822d5f9L,0xd7f81b9e18339700L,0x7ca29b27a7bc265fL, + 0x9fefa698eb4f0c7aL,0x7b6f351301f27630L,0x72f0f152fcfb1133L }, + { 0x9928d9d05c81eb14L,0xa16ac36bed8ff6cbL,0x7fbd1acbe041bef3L, + 0x7d25159af8d99854L,0x2ec3a7d8db5a0dc5L,0xd86fc4cc87e3e933L } }, + /* 4 << 161 */ + { { 0xba8418f34c20e15fL,0x7eed2494fb54404eL,0x4e6438d7bce1e82dL, + 0x9e489b3eb397915bL,0xa9baea9ffb4cf659L,0x8bc5b2ba42ef4affL }, + { 0xae3fb5337e62a188L,0xcd648493496e8e35L,0x89728e28defe047bL, + 0x63a8c679d24e60feL,0xadacbf92470f710cL,0xd470aeb95e198d3cL } }, + /* 5 << 161 */ + { { 0x8e3807dd7a3e874aL,0xc4edb45b89ac3a99L,0x9ba9cdaf4bfd77d2L, + 0x31d33f59b540fffcL,0x404c87790c60028bL,0x7f89da7189688c81L }, + { 0xdd3390e5504b862bL,0xdf1e721be937efe3L,0x5833d0df63e6036fL, + 0x7712527a385fbab4L,0x6347236bd210c0d4L,0x12d7733c8d238e2dL } }, + /* 6 << 161 */ + { { 0x0ecb0723302e943fL,0xd180ca1e4a443e78L,0x39e7891123dd2c9eL, + 0xfa2a440401fe50bbL,0x4678e7ed154d39d1L,0x64ddaee1af513e01L }, + { 0x6d4c615a634904daL,0x937c6326ba5c900cL,0x70658f5feb6c8582L, + 0x2a04fd51f3d65166L,0xcefe7472b676eb47L,0xd3565a71f597d887L } }, + /* 7 << 161 */ + { { 0x299520f4e5dcba80L,0x522ad4b52b758045L,0x54eabe27193b36d4L, + 0xda4d3bff45e9e442L,0x44cb9252637311f3L,0x4cd620a971338ebfL }, + { 0xec908157cc9524fbL,0x2731a11ba8c955d7L,0x72a5e0545cb94009L, + 0x7eee8f3b9126cfe8L,0xc71e29203dd5d5ceL,0xe886f91a22069494L } }, + /* 8 << 161 */ + { { 0x294d29550db962c0L,0xd6994ef46d523ab0L,0xfa1a7f9158f95037L, + 0xb137981164420c94L,0x2b686e1e093caea8L,0xdef10944f9e1c340L }, + { 0xcd1beecf611d9bf5L,0x34696c50a1b5267bL,0xcecbc7192dfc2b16L, + 0x2cdb955dcee7e854L,0x9fefc321f2635cc8L,0x276d2e4f2936f7d3L } }, + /* 9 << 161 */ + { { 0xa9de8b87d38e86b2L,0xe0c2f232780d2fb9L,0x742d7fe9449e78b1L, + 0xc6946b7ef29efe3bL,0xbd59bcf985de7456L,0xb070ebfadb492e64L }, + { 0x5cda7ac8a0ff7c15L,0x6e0c0062c4f435c9L,0x4d8e5395974d4be8L, + 0xa0a0c5984e6d1681L,0x5debadbea14cbda0L,0xe176a772ae30b167L } }, + /* 10 << 161 */ + { { 0x25df81bce7b19019L,0x3058081aa6f45519L,0xccafbccabb3de1d7L, + 0x2b794710c515b1b0L,0x74b81bf87168d9ddL,0x92d5e462ec00571eL }, + { 0x865e29efdc670943L,0x2350537c7f6299c0L,0x9fdf787ea947c6f8L, + 0x9601cb21cabe0f8bL,0x2899d5f49313b000L,0x4873bc9f66a9e8e2L } }, + /* 11 << 161 */ + { { 0x2829add72f163a26L,0xf96dd91156909488L,0xc16d185f769ccb59L, + 0x13c4b566e9c6da4fL,0xfd68110bc423ac34L,0x64911819cfaa9fb6L }, + { 0xad7c7d2b12dd07e5L,0xbf7eea90abc19a50L,0x1db70ed108d6c57aL, + 0x01da2b41446deeabL,0x163a5a5fa4f6a367L,0xca9f4bcca10c8a53L } }, + /* 12 << 161 */ + { { 0x2132c32e68206a00L,0x20bc1bb483bab6d9L,0x99fa3be2bc4ef156L, + 0xe515cd05ebbd6c33L,0x9c06d7670d2c8ebcL,0x2fa7f3b68a79c884L }, + { 0xa4dad16a9137df25L,0xc4da20f833598c21L,0x32f5d9e3867cb117L, + 0x8f00fb54da7cf533L,0x428cf9e3870ef3b4L,0xa8b6c754521b8428L } }, + /* 13 << 161 */ + { { 0xe9b297be7be5e610L,0xd09f63c304b49303L,0x9110a9b381ebb814L, + 0xc32af8986bf19586L,0x5c4939571da2280fL,0x89e85cb41becc5f5L }, + { 0x1068cb528f1a396eL,0x49dde483440a6144L,0x51280400b5d6aaf0L, + 0x0e8ac4a53e8ea21aL,0x32f4a91d92582420L,0x5eb09649bc35e408L } }, + /* 14 << 161 */ + { { 0xea3a2f0c32f235f8L,0x8281bfe5bf4a8256L,0xf44e1319577b9e1fL, + 0x31732d1bab2d9ac7L,0x6e7682eff375c5cdL,0x7069fbaf0913ed09L }, + { 0x693257dcf690cb94L,0x576a85b2dfa6e07bL,0x72e00515447fe4e4L, + 0x00af617509a2cd8bL,0x05a61365902ae75fL,0x8310b16db5ecb690L } }, + /* 15 << 161 */ + { { 0x4d22c79cb00fd8f5L,0x432b09844c9ed8b2L,0x43da93b2a85b3f0aL, + 0x0522df2ac4163655L,0x2ea7210b77214019L,0x8280099b7051a9a3L }, + { 0xcd0a829bb11b9e80L,0x9bda76c7246ee656L,0x1ece801bad70a0faL, + 0x4f8162f096721d79L,0x341faae58e7c3b0aL,0x6914420b12e57cf4L } }, + /* 16 << 161 */ + { { 0x4962c02167141724L,0x5f81eabeabe7762fL,0x78549a79dd189c3fL, + 0x47675cdd6ce517a7L,0x5102294e32d6bb97L,0xb19500c66ed1a029L }, + { 0x3efb54e8b16a206cL,0x7dbdcc250dc135b8L,0x955bc2948967fb04L, + 0x373615c9be04e909L,0xf1fcf820111efad6L,0x8530f97d6fd2e97aL } }, + /* 17 << 161 */ + { { 0xdfff3aceb3b513d3L,0x569f9d42fdaed4c5L,0x8615a9cf71cdec34L, + 0x2e700c34ceeedc56L,0x9047d770a48d0682L,0x3fc845780ee5893fL }, + { 0xaaaf3d90ab5b432bL,0xc846365184cb412cL,0xd215030d928ec9bdL, + 0x237a710045b97accL,0x0f533045ff791353L,0x093a0d21a1899bf6L } }, + /* 18 << 161 */ + { { 0x5da20568b4bcee44L,0x878025840f5bd27dL,0xc76b965c1c06dbccL, + 0x89ea2cceb1492616L,0xaefc8746b460c4bdL,0x679e6edb994d1756L }, + { 0x4ff93a4a271f3218L,0xae496faf3b970a74L,0x062df3a7ba6c44f2L, + 0x1ede93021990ede1L,0xa797899af9a1e2adL,0x9b1bcf6d82599120L } }, + /* 19 << 161 */ + { { 0x63a38a51bd04f6ffL,0x2ddc958bffafb91aL,0x198895cdb19b2b08L, + 0x1bb494246f65b797L,0xf75df140f157b79eL,0xa188dc873d599990L }, + { 0x8b926eecaeac83c2L,0x55fe56f03b82900fL,0x10eb6dd33b11d061L, + 0x8b44c14c3aec5877L,0x294b83e8b486e651L,0x469e552f79524b3fL } }, + /* 20 << 161 */ + { { 0x69386f451a746ed1L,0x4319649bcc14bac3L,0x006292b3b647cefcL, + 0xc771b7cda20e2a37L,0x838714d2396bf329L,0xf263e66759c0823dL }, + { 0x7ee258f0725e3ecbL,0x37638f9934218254L,0x4d57db246fc6d0f6L, + 0x8c85ad7322c2dd47L,0x2300a9129c59cf13L,0x63971b0bee08c1bcL } }, + /* 21 << 161 */ + { { 0x180032d98c2e7698L,0x07d4d364a851f2faL,0x0070bbdeb50b5986L, + 0xba05ee28274eee7dL,0x28843675b0f482e5L,0xdcc9c09ff82b2229L }, + { 0xae0273e7f061df73L,0xa3856b6644e3a740L,0x4b13b141527b80ceL, + 0xfd83b7f0e1b7dabdL,0xa3b5a2f1536c04c3L,0xfd09c77bb29e2bf3L } }, + /* 22 << 161 */ + { { 0x05fe64c5436e7c2dL,0x5b9f0b83ebb1ee26L,0x13dcbfed2977d6f5L, + 0xbd16c6b7db552375L,0xaaeacc2342da342dL,0xe427d2ee0cfec89dL }, + { 0x3097ac7b038b280cL,0xa2b79d623aab3c43L,0x9771fff4a40f585aL, + 0xf50974e0b15aa16cL,0x114e51137a847284L,0x574ba8efb4fbe083L } }, + /* 23 << 161 */ + { { 0x3c8dfa3b05e37e4aL,0xeaf691b47408352aL,0x2e1ce9863c9a8610L, + 0x8d024a814acfb35fL,0x3766aa2184ba6baaL,0xc336f82eb91f5a27L }, + { 0xe2d46985412ab7b4L,0x397f0411ded6de53L,0x067241c3544768fdL, + 0x9206d3839b71e023L,0x8571fe1e3f51c3c9L,0x0abdb52e3ba345abL } }, + /* 24 << 161 */ + { { 0x85e1e4abd5281f9bL,0xc7e517ddc653b0c8L,0xc0b84da1a717e034L, + 0xf1a63b280f1bf3dfL,0x47b74201aba6fd41L,0x9cf3da633518fcabL }, + { 0xe12511fb23bb6e77L,0x13b2cb4438679d79L,0x20e0fb10db5665c0L, + 0xb5448a33b99f4d5aL,0xcb1847ad46b7dbceL,0x41f156b8fdcadb87L } }, + /* 25 << 161 */ + { { 0xd09b746793c8b2a8L,0x36c760204357f251L,0xa965d1771ac04cf1L, + 0xca49d59427740f18L,0xbba973ed76c53b33L,0x7f8c2d264c17d867L }, + { 0x389afbbb00966b80L,0x92f2097a55988387L,0x316a85393a47c746L, + 0x259ae094ac3a3a30L,0x337f1d3f0d61ee3cL,0x02d5a60ca9d928ebL } }, + /* 26 << 161 */ + { { 0xd9f370e42af77d78L,0xf9cb8d588bfa692fL,0xdc8a4c24fc9203d5L, + 0x499b6fda3b8138f4L,0x051a61f19118d3b8L,0x89207fa2cb251fb6L }, + { 0x32247676bbb0e12dL,0xaa1c59822900bce2L,0xe7beff9c7df4f6c1L, + 0x595fd551757c1449L,0x2fe91299650e8961L,0x2db30033f480bf30L } }, + /* 27 << 161 */ + { { 0xe796c05d110c4d7fL,0x12f87395d4af6817L,0x849cd9e6b5512cb8L, + 0x23b8d0a4adb71290L,0x28cc808bee64339fL,0x3072d46fcc27fd1cL }, + { 0x8d9183af47f675d2L,0x9959aa9102c84561L,0xdff7591708216e03L, + 0x868c237abd01b2f0L,0x4c00c229a53e639fL,0x2c0667fb07d69862L } }, + /* 28 << 161 */ + { { 0xb4d2324f9470e571L,0x3af515979ca353e5L,0x479a3a796ae5778bL, + 0x387958a7fb1d9c91L,0x4e606558cf91edc6L,0x428384ca495a3b00L }, + { 0xa49f67da10f7146fL,0xbda553e08e25f80fL,0x21b034c4cb919bc6L, + 0x1fb454bfa7930462L,0x1fb2ac9b255d7fd8L,0x491cceff8b197e6aL } }, + /* 29 << 161 */ + { { 0x0a0e0cd91f5a179fL,0x699d872713841e78L,0xfa93f774fc47f9cfL, + 0x8fd0019c02933131L,0x128efed95aa46834L,0xe20226fdf080cb8dL }, + { 0xf7b05fc3000445dcL,0xcc818da1f52f5ddbL,0x0fa803d07299267aL, + 0x99cf0ab4f9f172a0L,0xb5dd3c36b08d03a3L,0xfafa550ea1c2f73dL } }, + /* 30 << 161 */ + { { 0xdda52c89d2da4e36L,0x0348948d5c333386L,0xe3a5be8b37917590L, + 0x42488ae238e4aaacL,0xa6ecb5be7a44eb6aL,0x3bfd640ea9b27b56L }, + { 0x23b8d107bd05946aL,0x01018c45bb8034bdL,0x1ffc958cd2e058fbL, + 0xeadc93953fd43516L,0x0659b83ea0491dbcL,0xc36115008cdee521L } }, + /* 31 << 161 */ + { { 0xc0f3761c034b0a6eL,0x2c4ce5481fb66b85L,0x7a5d3143410698abL, + 0x4bc07a795d59e8c5L,0x176a10eb4d19ba85L,0xa8a68c5526dae045L }, + { 0x7eed57fb21625985L,0x33ef04ae16c62e63L,0x78d0acd4562454bcL, + 0x5878d7f2a44a1608L,0xa51a423a0cf11971L,0x1934e3f2f21fd6ecL } }, + /* 32 << 161 */ + { { 0x3f2b5bd4b4805410L,0x201ca7a9f96c5ee7L,0x532ef2db94256fe1L, + 0xacbfc459318ddb03L,0x2375f9fd5f24c8e1L,0xd27c479b370783dbL }, + { 0x1bd461e856541ae6L,0x78f054a77f7ea49aL,0xc9f8777d8845f315L, + 0x81aed29697fc92c7L,0x9f2f8d7949929540L,0x7531e78bff5ebfe0L } }, + /* 33 << 161 */ + { { 0xd4710d5a16ba6a11L,0xb172d8a0e056d27aL,0x01879d2b8301e5c0L, + 0x100c3e706f6a3396L,0x4a33d4a4e4e1cab1L,0x48016f0f08017d74L }, + { 0xbde9e0f18cec4fb8L,0xd8604899eb15c26dL,0x17ac5d884a21f615L, + 0xb8f1e7060cb0cddfL,0x0ead85644a0d51c2L,0x7bff69bdfd6bafa5L } }, + /* 34 << 161 */ + { { 0x028acd1cb6b73820L,0xc931f4bc815047a8L,0x22c6159f1ede2c60L, + 0x571dd40c99a4820fL,0xbaf08be0b450f472L,0x6475536aeb5bb639L }, + { 0x033568e4d984d0c7L,0x2ab7dd4885e910d4L,0xb0d76698d0c632ebL, + 0x954d00f3e3c34a46L,0x53e8772de651bc5eL,0x4910b07b6e3564f6L } }, + /* 35 << 161 */ + { { 0xe1550b37e758fcf6L,0xfea2446f763120abL,0x5db50b38124f80e6L, + 0x5cc28a7830c3301aL,0xa935846fd950d5b9L,0xae3e87f2ce43ebe3L }, + { 0xf033b25b7d0776a5L,0x941d186e882c5916L,0x0430c4503d6d4f7dL, + 0x4e0641c0726f30ccL,0xdfcdbd1626c66c27L,0x43c4590ceb00e495L } }, + /* 36 << 161 */ + { { 0xd8cbdd8b70435ca2L,0xede7fb3675af3a63L,0x6c1fa971090b36bcL, + 0xdd2292eb85455ed2L,0xf9c3889c7fbe5041L,0x2ec87c15506d605fL }, + { 0x2691b0a28b099c25L,0x27961c8b89944e21L,0x8e9e18a5147f5304L, + 0x6a82e35baf7dce25L,0x6745339c32a4bbc4L,0xe0bf0e0ee026676aL } }, + /* 37 << 161 */ + { { 0x3c6fd1ab352a43fbL,0xe57e7f8cbd68dbffL,0xa4a5b74e9ea30f41L, + 0xacea695d2d5a3a34L,0x183be19adc8fe4d3L,0x22fce6281b9f9d1cL }, + { 0x8b1ae75da5d35bc9L,0x213face52c673f82L,0xa879851d6568d549L, + 0x327c59937f8d8112L,0x56b982e2a7869b71L,0xc77afa6110bb8086L } }, + /* 38 << 161 */ + { { 0x1dcd57541ccadbe8L,0xd2d8c36512b37773L,0xc1a7a5b7d50e8680L, + 0xab1a00b3e19d155eL,0x58f4bcce7a9776b8L,0x1c02df3320d9d7aaL }, + { 0x24f00d31db8cea6fL,0x2680b029d4aa0785L,0xf3db2889c48587f5L, + 0x1811dd2521a7fabaL,0x5836964bbf820746L,0x3b118bab97aca83eL } }, + /* 39 << 161 */ + { { 0x14babe6321d76845L,0xf7b4c662c60f5934L,0xbf212c4434de5b23L, + 0x57c478a35bdf0a35L,0xddecc21535dc8714L,0x1609b7401571e91aL }, + { 0x41998697ba45b40aL,0x6ef382d468cf383aL,0x77a24c1488c0ec9cL, + 0x0a5e245297b377a4L,0x2b9d72bf18f9804bL,0xa4c21326f51ddaacL } }, + /* 40 << 161 */ + { { 0x397049f4c785c7baL,0xa87db27da1decf9dL,0xce6d5ec1e7862c0cL, + 0x17a98db834350bf1L,0x6ceccd8030ec8d74L,0x4790cc07bcab4aa8L }, + { 0x4378b1feb4f771a8L,0x3c54588b404dfcbbL,0xbddf0faa8d60f86dL, + 0x987583da3573271aL,0xb0afe4ec4b8f8032L,0xb5c44605b69d03f6L } }, + /* 41 << 161 */ + { { 0x7f69e8bfed7d4230L,0xfe54dca7d8ee8cbeL,0x6ec2b75f71b72d99L, + 0x97e2b30f8dd8338fL,0x9916dcdbbc75bf05L,0x22f4291aad5c114cL }, + { 0xb6af2e86f9ba5c98L,0xdd7d738dfd6fc5d8L,0xce7af7d544649034L, + 0x2979be5cd163b098L,0x5acd51858db8d84cL,0x82b0e4a5ca64d1c0L } }, + /* 42 << 161 */ + { { 0xf27f5f4f480ef46dL,0x2f49f44fcba811f7L,0xef40508d43961b6cL, + 0x0f6778e8df9fb37fL,0x97aff7e8446864b5L,0x29aeb86d4d264e1eL }, + { 0x48baa1984901daacL,0x91ade9db02b483cdL,0x00952a61cdb6abc4L, + 0xa1a51250de7f22c9L,0xe6adfaacc19ec8d5L,0xa7d2f066fc39838dL } }, + /* 43 << 161 */ + { { 0xfbe20a8e270bcf2fL,0x9882e7a0c35c60f9L,0x74d8e63f560e716aL, + 0xdc689649bae281e2L,0xd454571036d9b680L,0x0a0f1c681740ca0bL }, + { 0x228dd692dadf3782L,0x6ab0bede632d6e56L,0xae2f5535e1b7add3L, + 0x2ce1c6fece308fa6L,0x7a11b255db881355L,0x903007107bee5bb7L } }, + /* 44 << 161 */ + { { 0xdd55c21a9f1a57d6L,0xc9e1dcf9f6043ee3L,0x0385e3f36747e2baL, + 0x6511555a932e55b5L,0x7f4053b3700e73f6L,0x23adf65d992916a2L }, + { 0x4664bf231bfc40a3L,0x8400e8f27974d63fL,0xb70f104dcff08198L, + 0x4c44382f4d1710afL,0x5593a751374ec807L,0x6af17e84462c6112L } }, + /* 45 << 161 */ + { { 0xc1ad3eb7b8f1f38dL,0x74bb37c88d462e67L,0xd127b6e6246b0388L, + 0x3054aaf0824defffL,0x4e981d2e487809aeL,0xba76b7b805ead528L }, + { 0x0a167834a7a32c6dL,0x3451ee930268c370L,0xab4da0971b625d09L, + 0xdb94f9aa304e60b4L,0xf3bea685ab50c663L,0x8d929a0142d4c11eL } }, + /* 46 << 161 */ + { { 0xfce03e6eaa911497L,0x32cba5cf546ab5ecL,0x631123d0b1a71e10L, + 0x49f3a80906bcdeafL,0x783373bcfc538ca5L,0x3590890ee4b47edaL }, + { 0xb5c84fff39ab2df0L,0xf681be9ac737b24fL,0xf37bbc68b2b0052cL, + 0xd9f03cf6fde04d93L,0x23171bc2e43803e3L,0xeda51460040de801L } }, + /* 47 << 161 */ + { { 0x0e09a74d0bccf0d7L,0xfb429a675b58037aL,0x1f2660d2200b89ccL, + 0x489b332e04efc617L,0xb53d4f65f38ceeb4L,0xeaaf759546c4aa4aL }, + { 0xc6cff1fa714b9f97L,0x6a647072ec0dd5b7L,0xcbf59eb1637384bcL, + 0x043003cd2240993cL,0x134cab640497f9afL,0xcdb44a4ca9fcc655L } }, + /* 48 << 161 */ + { { 0xbd9a66d6543b3e41L,0x2948c0a62ae73774L,0xa75151dfef38e9b3L, + 0xa3348ae5754fb3fbL,0x1218fa8f13069b72L,0x532bb0510835dfafL }, + { 0x2121a98edf2be3c6L,0x85980de69e5199bcL,0x1b23a4be1a1eb6eeL, + 0xb5c48b92adeb3ae5L,0xeebd305dedea2b45L,0x20543f04c37198eaL } }, + /* 49 << 161 */ + { { 0x9eb2d599fa727a5dL,0x27cce415105643ccL,0x2face9e8c06035deL, + 0x967f70e4c5d916cfL,0x477224ece7cdc451L,0x70a3de4ea9a34198L }, + { 0x84ebd23a62628f21L,0x517cbb6097f55e75L,0xa4dc8d8ccbfaa795L, + 0x821d53c1a9c17b12L,0x04e94aea5124d5a4L,0xc72432c083efbc58L } }, + /* 50 << 161 */ + { { 0xb7a2090999f73a42L,0x019bf3a630db0901L,0xcf0c2a7281cfde4fL, + 0xf656a2117b0b04f8L,0x88cedc1896043e90L,0x4482c3786ae4c551L }, + { 0x169f25d3dc70c774L,0x0f8cc86cb552fbe4L,0x17d0556b88d2f3eeL, + 0xf5af9d6ff864ba64L,0xcd509d82f93dbf7fL,0xf00c76f51b98df35L } }, + /* 51 << 161 */ + { { 0x19fbeb37856e35a3L,0x1788055c88f36390L,0x9da657f165361c9fL, + 0xc9f327b7e35a36b1L,0xdc388bcb04b9174fL,0xa79bf7d3349a87c8L }, + { 0x865958b202289b24L,0x4096845ecebc4686L,0x1127085b42ce096dL, + 0x56f31d12735241bfL,0xe2239ab543b89a15L,0x477cc5b3a6a1f0f2L } }, + /* 52 << 161 */ + { { 0xc44c81525d54607fL,0xe742a6f35c9ab491L,0x50df96d9be8c2ed5L, + 0x3aa8c9b4e7f5cc4fL,0x577d534c3f12e8b5L,0x03f9573da33a57b1L }, + { 0x9172e1aec5c0c895L,0x64fa9822a2e19442L,0x17db2388178a10d5L, + 0xe75a6bdc2755ed55L,0x6a6d9dc3f9188333L,0xdd93a3b83eda0c41L } }, + /* 53 << 161 */ + { { 0x353d1f4bad0d960fL,0x6fbf4355846e07dcL,0x2156ae3c3a1bb429L, + 0xfa95a260442e6e21L,0x659a856ac2b31d7dL,0x9b56cd6563ecb2d0L }, + { 0xac9ec96823a787b7L,0x4102d82e320742deL,0x470ee0ea50a422a2L, + 0xd3ca8414af386491L,0x28d8994b1a0d8192L,0xe601e4e2b3f117dfL } }, + /* 54 << 161 */ + { { 0x906c071c4e9ab844L,0xeb1a5806f085a058L,0x2f14c3ac176e2f59L, + 0xfc1a3020bd19f909L,0x5e67d789ac060e45L,0x75dd23a7b707084eL }, + { 0xb9dec51a07e89974L,0x50c9cd0b38f97f3dL,0x368b0f53e14cd6fcL, + 0xea4c7f8b81ab93b2L,0x774ca31d1b7aeb66L,0x94c14607288f51a9L } }, + /* 55 << 161 */ + { { 0x18c41b62fe32b90aL,0x2e11c7e6be96e1aaL,0x72832e8c428b9d81L, + 0x93f63cc0058ca451L,0x603f18af7cc827f1L,0x31c8b8fee038eb26L }, + { 0x21158b24411cb335L,0x48dbbed70d9e953dL,0x445e244e4d62615cL, + 0x2f5309ac28ef4922L,0x12ee44c60d4dc305L,0x7dc0363f56f7677aL } }, + /* 56 << 161 */ + { { 0xf73471b5ef349ec5L,0x014dae75565aa6c7L,0x57cb497dae082cefL, + 0xdfcbf2b5c3e563bcL,0x22149c0fd1125f95L,0x529f419b425bc019L }, + { 0x049476deaee2094cL,0x3490c0490cbbb583L,0x56c5c62d1256424fL, + 0x0a118ee541bc66faL,0x0d8e9ff8296ada14L,0x34356e8b0134f8c5L } }, + /* 57 << 161 */ + { { 0x5e41ebd6eb28f97cL,0xe054a055d6a393f8L,0xc0a19e38db6555e3L, + 0x1b40c80fbabf4f9bL,0xfca17ae2780d5107L,0x89ae096f379701feL }, + { 0xd79be295b53ebb0cL,0x3112d3a5942b2247L,0x6c1f44d30de10f30L, + 0x2a17fffb0041f800L,0x13082de044552d55L,0x319aa9c0cd11c85aL } }, + /* 58 << 161 */ + { { 0x63ea1a6ae760373bL,0x00f2addd11742d8cL,0x46b17c9cafdd38eaL, + 0xf4121c5a4c7e78d7L,0xbeb70ef90048e4f0L,0x0b60c2b6bf7f7348L }, + { 0x4bbadf7632969689L,0xcb6a8a20e12708e4L,0xc43ad55b5638eb7aL, + 0x4a72b02b3d27bf7aL,0xecc95d92e5a54c30L,0xae52514bacc45d53L } }, + /* 59 << 161 */ + { { 0xbf5a2b5132d1f651L,0x6a2a74116e438838L,0xfa6353dd6c067d61L, + 0xf6918622b96ba12fL,0xf0fa254d45f595f3L,0xa0f0cb4b92f680a0L }, + { 0xf13ba734463e3f27L,0x7e3d4eb1a32d7f9aL,0x348baaf26f6502dfL, + 0x8021a9977b830e5eL,0x503f38ca55caf601L,0x27dde9e8f4bb74b6L } }, + /* 60 << 161 */ + { { 0xfd5a49310eb63b3cL,0xdb9f1a1510175713L,0x044d42c23e11c321L, + 0x5561f2e9b7961e8fL,0x70b3f7557ec7c597L,0x5dd9671235aed561L }, + { 0xc6cdc78ee1bcc2b1L,0xebcf6f87f1117aa5L,0xef470e0ae3669f78L, + 0x87b13e0fd38e0fe8L,0x01bff01439c755c7L,0xa66f2521c37529f8L } }, + /* 61 << 161 */ + { { 0xac56a8b223f78e49L,0x908c4be58708f0b5L,0xa63aa4191536f6b0L, + 0x8c08578fe5a95771L,0x5d2d1d6b9c2ae8daL,0xf3e4ef12f1527cc4L }, + { 0x46c1ac13920a90bcL,0xc0bc661d28ba758fL,0x9114e016585ef450L, + 0x8ab6a1f6e899a032L,0x57d4089606b658baL,0x2ef87621eb83235fL } }, + /* 62 << 161 */ + { { 0x033a4d4c4ebdc925L,0xff239a3efe1b346cL,0xd7ab2fb388d03949L, + 0x56ce2e41bd6e8e4dL,0x3826aff0e55da68dL,0xc9c7ba7451267f98L }, + { 0x5264a48ae6710c7cL,0x3635f1d4e7605975L,0x53a1849a94be903cL, + 0xe4fc3617128d5859L,0x7686804d7e4dd785L,0x6f04942d2dbcfe4fL } }, + /* 63 << 161 */ + { { 0xe80b7f5562927d6eL,0x92b98c350c0cc89fL,0x9522896d15117facL, + 0x7a224db5fdd3ffcdL,0x9502ecd8fbfc8908L,0x4e1dc71ac593105eL }, + { 0x052aade62f0536dfL,0x0c7cc371f324268aL,0xe7c62f2ccd843bb4L, + 0x77d48fa36df2c231L,0xb2c29803cb8f68c4L,0xad7ccf519bb9fddeL } }, + /* 64 << 161 */ + { { 0xd0960bd80fab968cL,0x6899e4faae028db0L,0x975ccc77a9850916L, + 0xb41bd531e5f81554L,0xbdf8ab57c8cff2c8L,0xea306a01f5822be3L }, + { 0x1f0ac0e7befbdbbeL,0x72f4b0e960519f87L,0x22bd8b82e3cc86abL, + 0xc43bde8d2b2beaeeL,0x8168781e412617ffL,0xc5610627b7ee7096L } }, + /* 0 << 168 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 168 */ + { { 0x0869457a01a8eb44L,0x522239857a7bedd7L,0x2c04b0c600057505L, + 0x468be6e80b09adebL,0x2f3bf32b6f81474fL,0xf54f949da712ccceL }, + { 0x292cee424cdd8f2aL,0x3d9fdf6b9c221be1L,0xe54da66156f47b2aL, + 0x2ca76835840b5d1bL,0xb52adb6a8a6e8cf6L,0x8b416a6bdade153eL } }, + /* 2 << 168 */ + { { 0x65f7d2c18565afc9L,0x764c897170fa7b82L,0xe268634c986436f2L, + 0x6334d8d133356165L,0xf17164269ec7957dL,0xae834331b8093983L }, + { 0xedb1fe5cd2dfcce7L,0x6195b86368463e5cL,0x746e5f4da691b665L, + 0x61171291e1e2727eL,0xbb4aa8f16f27b029L,0x1037657d7f42c197L } }, + /* 3 << 168 */ + { { 0x2af8bdfa970f96adL,0x19d09a6dd0c86e6dL,0xd57fd5ced7046d2eL, + 0x5ea025f7d545fd33L,0xe2ccb6f43161ffd7L,0x3ca5286209406242L }, + { 0xf3536d60b5c90905L,0xd086e3b9d5b290f6L,0xfd15b06a5cc55444L, + 0x61b0febf9a9e2a66L,0xdc3c0576653dfd02L,0x357774230a8ab51fL } }, + /* 4 << 168 */ + { { 0xfe19901b0d5b855aL,0x5facb9552f745022L,0x92fd012556c4ce5cL, + 0x23172d65938c89abL,0xa71f8a33aaa587b1L,0x511a3745b55c9c50L }, + { 0xec005f6a7185086eL,0x6dfc2761f894c6abL,0x98a4d67f9e26361fL, + 0x7f0a2b2321389c25L,0xd158820795ffbceeL,0x4d6b29ab9f36a888L } }, + /* 5 << 168 */ + { { 0x5ffec1d78c04bc6eL,0x35f052d16ca0dde2L,0xfbe3844c649c850bL, + 0x450263e610fa337dL,0x44f7c8f40280773dL,0x27de5d3ce896966cL }, + { 0x2587f47598d0378dL,0xbd49c97f4e4f6e49L,0x9e902f667071543aL, + 0x03398aae06577b74L,0x030926d6910bee13L,0x5576575bffa92cecL } }, + /* 6 << 168 */ + { { 0xe4ee33460562cd7eL,0xd1d385a3f01ba45eL,0xd817ca667ce11848L, + 0xda222cddcb69c7eaL,0x74ac74709d680afeL,0x3770357cd9596ca8L }, + { 0xdff57da7f7759bd6L,0x090426be20d5c726L,0x71c0ba28b7fbc1b0L, + 0x60faab1c13d4ed0fL,0x6fbe3567ea3a2ef2L,0x0dd3835c4e577dffL } }, + /* 7 << 168 */ + { { 0x9b758b512ce27e38L,0xe4148475a39855e3L,0x4669b3c39ee88a77L, + 0x3f36a671105e1ec0L,0xd0f30e5d9e88ea13L,0x6346df15baecbaadL }, + { 0xec65be65cf4c6510L,0x843efca194e1989fL,0xf7195d29942ce52bL, + 0x12201877d3ce28d4L,0x9c962aa1a97fc904L,0xc4fedb3465c5a55eL } }, + /* 8 << 168 */ + { { 0xeccb421ed0a701a5L,0xad4cb9a5b60cd286L,0xd344da9e05a53972L, + 0x3a8035e07bc99feaL,0xe0214485c0f77bf5L,0x50ada30ee54df78aL }, + { 0xdef45af64ec2d576L,0xa05d61845f9a8678L,0xa9b17db1c337e017L, + 0x026a4f66b84671d5L,0x606142343b7d696dL,0x71ed9aaf81cfd22aL } }, + /* 9 << 168 */ + { { 0x62805305695a3f30L,0x6ce27626e28e8fe0L,0x507386af6a54f410L, + 0xf8c5f738cd5c7effL,0x3ab2db9e347e85d7L,0xf5b635b0b2161b68L }, + { 0x99009791be2e80caL,0x6dff3030c13910ddL,0x2beeca057ee8700aL, + 0x12616fb11ac7e09dL,0x38c9ef9f9037c2e4L,0x39181fbf9c140344L } }, + /* 10 << 168 */ + { { 0xcdd6aee47aa54433L,0xf5ecb432b80336f5L,0x690bb949a1380829L, + 0x219d659ca9c9d720L,0x74abf2dd7e5a3260L,0x405ee136025c55d1L }, + { 0xc5c592cb1cc878a8L,0x119a38be88b31ecfL,0x4fb00f82e94e39e7L, + 0x66bf72e59412c068L,0x9337c8f30821142aL,0x477216340c24ab67L } }, + /* 11 << 168 */ + { { 0xa6c7953457fe953eL,0xd70d3d2f3c76ae58L,0xe1e047b52c531c84L, + 0xc71f3a9973735602L,0xd70bdb0f7ba0628eL,0x280fdd4e0e3e3c0cL }, + { 0xb5a3f5823e414e26L,0x55b2eda8f44dee7eL,0x8e1d024b2f5dd828L, + 0x21f054eb3b1bfdf9L,0x3d3ae74cc554e1cfL,0xa0a5863ffc42ec16L } }, + /* 12 << 168 */ + { { 0x1b76a3c5439ada39L,0x818829cf89236ae5L,0x2277cb7a750f8129L, + 0x44aa462a4d46502bL,0x7a12e1e164f06dc8L,0xb9a3300dba5630cfL }, + { 0xd2cc8d9c55b05f4bL,0x6d0b0b88a700be7aL,0xa7be99699617500cL, + 0x2b5b8deac03f8a50L,0x712f703e785b3dfdL,0x96a5a60accf93950L } }, + /* 13 << 168 */ + { { 0x9838155fbf9f72c6L,0x3ab3cb602c10e57dL,0x7ac228ef14bcd75eL, + 0x2c167e15027923fcL,0x678869d1267471c7L,0xeba35e857ec3582cL }, + { 0x22d290a9a3478eb3L,0x542092ca1309aa14L,0x8bb5c69be2e5d3acL, + 0xf83c5a0a81652736L,0x9cc576227280cd6dL,0x6653436f3b0f49a1L } }, + /* 14 << 168 */ + { { 0x7ad1f1bab497d900L,0x9d0512236c9dd5d7L,0x0ed27e5bffed3df8L, + 0x659028a775d2fa72L,0x69bd68154581f377L,0x142c2088e2faf671L }, + { 0xf9c1b8a499b000ffL,0xf31d01b18f408d3aL,0xa7aa142f42b9d35bL, + 0xeb8aa74ba0495da2L,0x824cc32a59a1da45L,0x3f1fbe0ff5173374L } }, + /* 15 << 168 */ + { { 0xec9071a634238c30L,0x6dd6c38b88a0f423L,0x3adace72992e7977L, + 0xc90b941b1ae5166eL,0x052aa3e9e3e43a68L,0xe9b1976da733a950L }, + { 0x0e1ca28e5ff6c9dbL,0xd1bd4350387409a2L,0x5943cc7089155117L, + 0x8e85794f5feae20cL,0x0d118fd669768ccbL,0xc647179d53120895L } }, + /* 16 << 168 */ + { { 0xfeb984b3ee828fbaL,0x8273f830e2bd188cL,0x177ef97e3ca0a99fL, + 0x76d4796dacc000acL,0xbad0fa6eb140f51aL,0xb275656706ebc810L }, + { 0xf89eb78fa18cb32fL,0xcfc37eaea65285b0L,0xe2b29cfbb25e9d1bL, + 0x9388ea8fb4e7aef3L,0xee606c12e267e845L,0x6b103c549f5806d7L } }, + /* 17 << 168 */ + { { 0xb9a40e78e31fd643L,0x648cc34a97950a34L,0x85c5ca405900be55L, + 0x2e519cf12abb843bL,0x6f9d0a7f27436edcL,0x2f569c9d6694f363L }, + { 0xf6d1b325f6f1bd24L,0x01103c0d4044b353L,0x2d3ce56f3138b549L, + 0x5379bcf71c28bc5bL,0x6768220d08ac00d1L,0x973f92ff0152746cL } }, + /* 18 << 168 */ + { { 0x5e992944b37b0486L,0x0a334b92001fa124L,0x6653cded9c9ab466L, + 0xd512612fabac4da9L,0x636bf431c502b860L,0xfca1c0c2c3d20db2L }, + { 0x7073f293f85c40c3L,0xfaabc77acfba9eddL,0x58842eb97f9b570dL, + 0xe8cd4f53702aec24L,0x8975f4e6e08113a1L,0xcc0d7f17767bedd6L } }, + /* 19 << 168 */ + { { 0x5163bb51ae315a65L,0xf82ec4cdbe405348L,0xffd381a46b1801a4L, + 0x33f9b8ad2f6ba570L,0xd88c58a58ecc0000L,0xc0b9a639cfdad25eL }, + { 0xc78cb70fe3bd808aL,0xf54b86e573ce5eadL,0x111208ed5610a761L, + 0xba3579b0e3c8e27aL,0xbadd918c63b85bb7L,0x9e10da0b71bcd972L } }, + /* 20 << 168 */ + { { 0xf418e3f63766f2aeL,0x4a3ad3c8053ef1c1L,0xd01e5b5b560db262L, + 0xa583edc7c02bf4c3L,0x7c9f706052f318d3L,0x0852556f1f5e1ffeL }, + { 0xe1c70aa7feb0e63cL,0x59f0a3f989a8c058L,0x4aa4cf021ffc0adeL, + 0xbb880e4138a78632L,0x35b0f7596f28f096L,0xf9c4fe17d5757d7dL } }, + /* 21 << 168 */ + { { 0x160303ded896adf7L,0x19a46b6c6beb8930L,0x33dfd962f010f74bL, + 0x03b699cc00e5610fL,0x17487b7595078dfeL,0x63bc614253f3479cL }, + { 0x43f3d994858d5b8bL,0x383349349483c0ffL,0x47c917a67977142bL, + 0xdc50fb80df7eead4L,0x4e3a1d3fb5b82be1L,0x091af8796d7317b7L } }, + /* 22 << 168 */ + { { 0x783e5066af151a9aL,0xec0a9c175466df17L,0xdecd12310174b0adL, + 0x654af66a3b2aaa45L,0x849d64e5b1fcdd11L,0x7e8e2ae6d05af56cL }, + { 0x12e887b7318a6184L,0x42d1445554ed59d8L,0x2eafeb48ee54ddc5L, + 0xd1f9e6b980c94a8eL,0x5ea691e3263696c0L,0x7f42f3796e03eed3L } }, + /* 23 << 168 */ + { { 0xeeb8accfd69b82b9L,0xb4c4988ae0b61d73L,0xb78becf19df9b59eL, + 0x13274f6236440c93L,0x33d287f5697d5a77L,0x391fe6129af4053eL }, + { 0x986c42b21c16e858L,0x23f5d1dffe04125aL,0x2f57ccb3af9541ffL, + 0xe5b4eec70f1a8bafL,0xaad23ce7646c1b6fL,0x69495ee5a6ff96abL } }, + /* 24 << 168 */ + { { 0x78b8879cfd6376ebL,0x22a76461c01e1edbL,0x6a44be39369cf0c4L, + 0x6653670d5ae54539L,0x257bd7516fb43ad0L,0xb3ac371512baffddL }, + { 0x48659d617548eabbL,0xd8f931f80cd468cbL,0x98f0241549e3b531L, + 0x90b0d71670df011fL,0x26d73c54ab98f066L,0x06591ec988475d5eL } }, + /* 25 << 168 */ + { { 0x6fa72e3518f18e71L,0x6c04fe2d8123ff14L,0xc48cb53a197481a9L, + 0xf059db349860e48cL,0x35e8341ace46ca7dL,0x880f4ea4b0400f7dL }, + { 0xb4c5ea9acc9cc40aL,0x6522c768e2555fa3L,0x95207f39ea2c32e6L, + 0x7b6fc09fa8be60e1L,0x772b829f29902652L,0xb7936b90af6a48dcL } }, + /* 26 << 168 */ + { { 0x409e3b1109758457L,0x59dd0a8c1dea73d9L,0x528906a58fb18a01L, + 0x6fa55967a17ffb33L,0x9523cc3d50edbcb2L,0x35600b3e44d43541L }, + { 0xc3a7d22c8f87dbc0L,0x5514c967c1b225abL,0x78e5701988304a74L, + 0xe9b417ba35f3b54dL,0xb72a243c48eea230L,0x4e173eaf291ee52dL } }, + /* 27 << 168 */ + { { 0x79b854ca2127c795L,0xd9457d8f86657844L,0xf8c9e6ef186668e8L, + 0x84c8855df913c2f6L,0xf207d36ad641cc12L,0x7be9b5736105ce0aL }, + { 0xe72cce1974ec078dL,0xc4f47413d09950c3L,0x640bf6eb3974554eL, + 0xf880dcfb844497baL,0x3744626999bbcfacL,0xcf1712f4316f4d64L } }, + /* 28 << 168 */ + { { 0x627f6328412b84c3L,0xd427e977a04545d2L,0x5b0145bc104f25c2L, + 0xa6931c4f2ac7ad62L,0x407611431f8d42f5L,0xfda5a76be7f8a0b3L }, + { 0x4f1ca5cffe0946b9L,0x6def7b9fbeb2d427L,0x984bd4bbc9a0d136L, + 0xb9a778235b3af1c1L,0x04ee66ae38ac2087L,0x63374ed926d9dbb9L } }, + /* 29 << 168 */ + { { 0x68088e9c3983deb9L,0x2c95ecaa2ed99988L,0x371af002917f200dL, + 0xff33aa5dbb4ff0dcL,0x1dd5fcf2e47bbd6eL,0x1624b973e75f73ecL }, + { 0xf6ce0e9db9722af3L,0x8bde5b8818226fcbL,0x243753fc5b5da478L, + 0x3b53e0e3bdf88daeL,0x59f8c86f325cedb2L,0xabd4076d70fb9681L } }, + /* 30 << 168 */ + { { 0x1996761db8759af1L,0xfb85cdd8e4a705f5L,0x2ea7aa0b35111725L, + 0x23245d4157a17f4bL,0xcbdb650e0d00eb9dL,0xb40823d9e23a4a3cL }, + { 0x041bfb67229163f8L,0x020ad3c16d47b83dL,0x3bc8975d344c8ebfL, + 0x287efd06d91ff408L,0x1ca5d75a2059106bL,0x4ff27af3b90c5d66L } }, + /* 31 << 168 */ + { { 0x416b7c61ded914e8L,0x1aeee7d007ad4237L,0x59d5852476c2b7a4L, + 0x427a102c98665f29L,0x8504aa8d2a1aefe4L,0xef2dbeadc183a736L }, + { 0x5cb5f222f533358cL,0xf2ebb47d36b0d678L,0x1de4a0e7f2c2cf99L, + 0x62613994ea95a161L,0x68a86f4012d66ed4L,0xeb12fe75b2af52f3L } }, + /* 32 << 168 */ + { { 0xcf947c0644ba39e6L,0xf5d5216cedfe78d7L,0xd00115c05f1835c9L, + 0xdf084152d8c79d90L,0xc0c3a6846db5f791L,0x40514451749b18cdL }, + { 0xd314b7d5734df3f1L,0xbccdd3f07f541415L,0x97ed5af06855a942L, + 0xea84ae9ee9d02ab9L,0xb87e90343238a5d0L,0xd12d25c3650a0eabL } }, + /* 33 << 168 */ + { { 0xc3747c584f9d2c34L,0x493a0adc95429c92L,0xf9b5916238a679ebL, + 0x04d500a16bac07f7L,0x8938f4f96a809676L,0x44ecbbf0c5b25a4dL }, + { 0x3b68705504768400L,0x6a432e14b4db3907L,0xff82fb56ad375d2bL, + 0x87f59f97944210c2L,0x2b680b2051445242L,0x1e0986466cd75962L } }, + /* 34 << 168 */ + { { 0xdd2eea82672e5a4cL,0xb05ef9ebccc68d94L,0x626ce368a3fa4215L, + 0x6e376f67fe46bd46L,0xaed7a0bc33c4f169L,0x4a92c6093af5c4fdL }, + { 0x6615245fa690fb49L,0x571d2d870d64f04dL,0x6a45df34641ce79bL, + 0x045ddbd02655d316L,0x2b6c574db4fbc42aL,0x41545fbc5b2dbbb8L } }, + /* 35 << 168 */ + { { 0x484996b97d8f1eb7L,0xf72f3a8110bd1585L,0x418e00e7b67eb27fL, + 0x354e56c97877c18fL,0x7f11f5040a8b37f9L,0x66591146ff58764dL }, + { 0x816ac849ed0bfc38L,0x85eaa6350a50a99eL,0x7fa62d9c5bf4995aL, + 0x77840d5003413385L,0xe4f023bde83f9fa1L,0x2c5f8e1d9cfa7578L } }, + /* 36 << 168 */ + { { 0x1473b55b86a515a9L,0xa9e3230a3b337c64L,0x7e8bf9049db668f1L, + 0x1db2c25ef27f9fc9L,0x0c1086072d9e467eL,0x4505579aa3f00d52L }, + { 0xe2ad661b240400a7L,0x8022294c11af4874L,0x29e9037078bba8e8L, + 0xbf0fbf08f6baca04L,0x2e46d2b74101fab0L,0x66065490c61089e6L } }, + /* 37 << 168 */ + { { 0x18b01aa935dde51dL,0xa7496997a7d044b8L,0xcd9c467f44c23d2dL, + 0x96211b86659e4a5bL,0xa2a9000f3e17b717L,0x7af9c312dd90459aL }, + { 0xf0d6c24394547203L,0xa76a23dbd77cc691L,0xe1b7fce10ef364deL, + 0xe08c1d0bb689c810L,0xb75bfacb0a43ca02L,0x1b7afea5408ac99aL } }, + /* 38 << 168 */ + { { 0x3b1abdb85a4a8a23L,0x8f52060c4d68bcf2L,0x7408306a00ab3146L, + 0x652ae3064b86b775L,0x276a14a0b0695b00L,0xcf8af11f1b771254L }, + { 0x3fafcc63b91118b3L,0x6c49000a73bacebcL,0x53852d084e3f3d6eL, + 0x78977e91fdfccca1L,0xe843cbca6ae9ea5eL,0xa99831896bb8271bL } }, + /* 39 << 168 */ + { { 0xf77b0a7387534a6cL,0xfff419f2f5b0c6dfL,0xde3c3b33357205eeL, + 0x867eb3a23c8ec9d6L,0xd28bed3263a99b18L,0xf5fc17e4c1573146L }, + { 0x30cf41e5821641feL,0x84b1970e225ab57fL,0x6bf707325a1e8ba0L, + 0x7bfb3bbce3cf38d6L,0x9f362787a661e876L,0x6d9137c86c0a16fdL } }, + /* 40 << 168 */ + { { 0x2131ce5b09f8a1cbL,0x7b373ed28ab129e2L,0x463cc8d677c1292aL, + 0xa9b7cf6594ffe9c5L,0x129125ceb99bfc4fL,0x819b42849820d323L }, + { 0x3f70976376541a41L,0xfd679ae5e32c7a7bL,0xc39a208df65b6b3cL, + 0x1c22ebc050002745L,0x268f19dde2bcd202L,0xfeac809c9c3d4266L } }, + /* 41 << 168 */ + { { 0xc5ad8903af14f8a1L,0xdfcd207c3993c99cL,0xf65f8260c7c1fd57L, + 0xa1573b3d41be66fdL,0xeeeb9ea476690f79L,0x6a6338437129849dL }, + { 0x22eeb38623a7bfcfL,0x258fc0743393e894L,0x008efb477ce9602aL, + 0x4bf127b699c7b279L,0x150da482fa1bfd7fL,0x7b84744d293754dbL } }, + /* 42 << 168 */ + { { 0x3af9919db2183277L,0x7f5990fb4f6182ccL,0x17603db034f716d2L, + 0x6b79f6538f135ad5L,0xad9189e68092d128L,0xa5f3ab8efc6628c1L }, + { 0xa36b978e84b6d30fL,0xf2a7e1c64c001f26L,0x2acbdfd676e79beeL, + 0x71b5faec86f6d6c6L,0x23d9b7c849b0e5d7L,0x36ea518212fd4cccL } }, + /* 43 << 168 */ + { { 0x14a4af0f59df1cf9L,0x37f8641dfd7cd2b4L,0xfb6aa5d0244434b2L, + 0xb85f8c8b5d5bbd63L,0x833e76baedb92f97L,0xbcd9d7b50d7a2dc2L }, + { 0xb233f07ff0e0f06cL,0x453f10c4fcc06efcL,0xa4e8f306128a167dL, + 0xbd6df4690d0c09cbL,0x2b5db66b7168ecc6L,0x7ec02c77f29bcecfL } }, + /* 44 << 168 */ + { { 0x0746783787dcdbdbL,0x4cce33be320493d8L,0x9ab08cbe713c7746L, + 0xd6f0c1de9c6dc5cbL,0x194005382ac03761L,0x3fc11f38d0547be5L }, + { 0x66b378ce819fe3fdL,0x6a590acc3700fe7eL,0x4c976a728924b396L, + 0xa5006d8d70b9b250L,0x2fdce1b212b85f9cL,0x5858f7ce495f8f1cL } }, + /* 45 << 168 */ + { { 0x3f2b5e295de2948eL,0x84554eaae1a4a962L,0xb4e55f1293db9addL, + 0x9260e3eb61b22484L,0x22a898997b1a6d10L,0x571bcd3af58d1ce3L }, + { 0xd62db0edecc88a76L,0x88352f634af2cf53L,0x8d279316b61c73adL, + 0x7f898e09ec74d6abL,0x39b2b0c05412a81bL,0x623a5ea30644b6a4L } }, + /* 46 << 168 */ + { { 0xe876b53bdb0f6565L,0xd0dc323c4650204bL,0x0e4af31b0201643fL, + 0x486173207e8a0e6cL,0xe09183d457643a1cL,0x3c55bcb5ae8359b1L }, + { 0xa06078cb7b467835L,0x4d3a35d901b6bb3cL,0xd4f1d8233963fd31L, + 0x9c1b06093d4cce05L,0x55e368d5da550340L,0x50c3feee12c4b7b3L } }, + /* 47 << 168 */ + { { 0x6de0fcdaf0f97e84L,0x1f225d818dfbc0ebL,0xe27a42efcd2c51d9L, + 0xeff56879c0cb033cL,0xe700cb87c82e38d4L,0xc89a02d589d244caL }, + { 0x0b464846ad9c718bL,0xf8d5ee1f8de96d61L,0x2cc33c3dfbfd0960L, + 0x3ef549f0e199b6fbL,0x29f83f686c1597b3L,0x54ca37a3731712ffL } }, + /* 48 << 168 */ + { { 0x357540ab903ff177L,0x225280b8276af514L,0x33d273ac14d7fed3L, + 0xfef6b9ffd186ee3dL,0xa94c207101a7b1d9L,0x4ea3627450bc8bc2L }, + { 0xc68959c9fa98a918L,0x8f5ecceec7bdc262L,0x7a73a4fce6861310L, + 0x19bcac90c828330fL,0x73e3b66f7ef74fdbL,0x60f7698352d8f2f4L } }, + /* 49 << 168 */ + { { 0xda57f1a65645cb9bL,0x3d5d3190f0840240L,0x6a0c6ab101bce275L, + 0x38993676ad23128aL,0x54f7b5d7ea0da248L,0xfee930b38b04ccb8L }, + { 0xadb9034e2cf3bf1aL,0x0488b71ae9b608daL,0xa3e51e303bd1172cL, + 0x56dffa5844993c1bL,0x6b3211fa4cdcaf10L,0x223b2a43834d4e17L } }, + /* 50 << 168 */ + { { 0xb31f934134e43ed1L,0x895c99973c6b7f58L,0x360021084c465126L, + 0x7eb0bf6b095df89fL,0xde3b2fa3ac534af6L,0xd9dd9f55c22477caL }, + { 0xf52cfffc2092e355L,0x4ba071ac8d8bffc6L,0xafb61137abefe750L, + 0x2887d0e4cb62210bL,0x0eb2be515f4fc157L,0x8c993039438fa2f7L } }, + /* 51 << 168 */ + { { 0xfd2a61093efae008L,0x60fa269552f57cafL,0x3591e64f481c36c1L, + 0xdc2b9993c908a87aL,0x76bd4dea5bffb50dL,0x913a0458f70fb0f5L }, + { 0x45ea6c4c097bbfc3L,0x3ebe29d3fa9e90c1L,0xc69532426479c087L, + 0xdd1d24509abc7a4eL,0xa497b072d0fc7791L,0x477d71f9388ab90cL } }, + /* 52 << 168 */ + { { 0xab3578047e03a14eL,0x0f4f28688caf673fL,0x919e661e66530425L, + 0x28da445c91ba47c5L,0xd6d0537566c394feL,0xfe1864a302e8ae91L }, + { 0xd34baca2a753aec4L,0x43b7ffe7a2c8d292L,0x496659eb04efb8f1L, + 0x310ec2a9e0252dfdL,0x98173d2f9168a80eL,0xa3e018d631497255L } }, + /* 53 << 168 */ + { { 0x39ee6439ddfa0ffcL,0xaea6f882c1d1d54dL,0x688feff654a65059L, + 0x17ee5aaa37f25ebaL,0x6c9b4f2932b345f2L,0xb883c0c75b4d62ebL }, + { 0xaf33e4ae3135aa7eL,0x28a7572c924146a2L,0x67dc5dd37e77ae8bL, + 0xe11cd9c5ff39b601L,0xa86f090b5e6f364aL,0x76f7517500b84247L } }, + /* 54 << 168 */ + { { 0x26d3a3e3fbae20ddL,0x5e9b73cee1dd2b25L,0x7008aefb0235d5b0L, + 0xa92af4ed2aaf208dL,0xab786c9bb1132040L,0x43250e6c9a91269dL }, + { 0x00a15294c9be00ceL,0x2d5782df1698dd42L,0x3f980bbe76e3d6e3L, + 0x5b602647496650fbL,0x461edc3271aca61bL,0x2516ab6c9805a01bL } }, + /* 55 << 168 */ + { { 0xb468fcf2967e2216L,0x97b840679ae47d05L,0xfcafaebc5cc15209L, + 0xaf7f6c8ccc83c3d4L,0xa74d4cd5cfa47e0fL,0xd8a51615474cb8b1L }, + { 0x4815ef52591462a6L,0x9c5b2cf74deb41ddL,0x39cb450b7e99d620L, + 0xfe8cacbaa7772019L,0x98b98210577dc69dL,0x5e02b90072423a96L } }, + /* 56 << 168 */ + { { 0x3266c887d9d9284aL,0x690f818b73646ab7L,0x67315ec6af7fc33bL, + 0x181e61abc30b1ccbL,0x1b81e6cd105a9e1cL,0x62a15daf5078b9bbL }, + { 0x74f9840f6fa8cc65L,0x356b777443388573L,0xba0f7d0506b3fd46L, + 0xb0ac864c92b4fdadL,0xcdeac253ef192cdeL,0x0c24810bc313b4a7L } }, + /* 57 << 168 */ + { { 0xfbcd4f77e748de9bL,0xb7d28cdfc25dcc94L,0x32f937a92e033c43L, + 0xb6289636d9da1f7aL,0xd774e97dd287865fL,0x8d013739e6243bf8L }, + { 0xee7ec1f856b9601dL,0x429017666afc90caL,0xc42d960ad2bef9afL, + 0x654ece7f5b430bf6L,0x02878c7f221440f4L,0xe575aa6474a4e1a5L } }, + /* 58 << 168 */ + { { 0xc96e763e71a449f9L,0xdeda66311a349fb0L,0x6f896aef3c4e8f44L, + 0x71ffe2d2e9eb36a3L,0xcbee21ab8f908a29L,0xaeb695f85be98708L }, + { 0xb6023803de61e1a9L,0x59f1ec96065ecca3L,0x2a1229f3637d0741L, + 0x5a9bca2c69441afeL,0xfc6daedbbbeaeed6L,0x950034954e2e31e0L } }, + /* 59 << 168 */ + { { 0xe59a827339859da4L,0x8720429fa7431a84L,0xfcab26e17ee3457cL, + 0xc13c1125da3b7833L,0x0bb1043fbc0b0da1L,0xdc2726ea84b526e8L }, + { 0x34049278a213a188L,0x400bb4a00a1a2553L,0x00e3eb25c92df398L, + 0xc0b7113f9c36a6ddL,0x719d185001e274bdL,0x86f08f2dcde338aaL } }, + /* 60 << 168 */ + { { 0xef8c40bf1adb09b7L,0x2efeb49c0b74992aL,0x3f0f8a412b79957fL, + 0x08927bfe87a06873L,0x1f63a4109288cb9aL,0x8c66fb70df2b373aL }, + { 0x98da4712980facaeL,0x15ce5b17d819d026L,0x097571a5749a671aL, + 0x85a40804894dd269L,0x3e89c13c34cb6797L,0x2d19d5e4d07119a4L } }, + /* 61 << 168 */ + { { 0x903eee85d90da9a7L,0x67723582de5ddbf9L,0xacf6898ad394eeeeL, + 0xa700fb8fabdb94f3L,0x1bcc4f947ac5624fL,0xee5cccff7e3b8ec5L }, + { 0x87d64d4d98e5a1baL,0x78727fc1ad9c4409L,0x55b4159b82310db7L, + 0xaff4eecea58d10efL,0x6d2ec94c11c958afL,0xf129bd1043db33faL } }, + /* 62 << 168 */ + { { 0xe1f6d71ed42eebf8L,0x46f825b9541ac0b2L,0xb01031b693ae2ab1L, + 0xfa4e1c357c589556L,0x65fb2504d273d1bbL,0x589d735447642bddL }, + { 0x7a5776adcf5e2d53L,0xab5c3544e5feda7eL,0x48e8442d32dea96cL, + 0x5f3e9c9e64d293daL,0x3f2df6a16b972a00L,0xfba58f5fa273832fL } }, + /* 63 << 168 */ + { { 0x5c9fe89240e9ce34L,0xfd9fb296633495d7L,0x0ae3c18a8c76cd7aL, + 0xb5ede1e3a6b77012L,0x5ac7a9d5a285822dL,0xe41de7da71ffe07bL }, + { 0x585f7e101b1bb4c5L,0x482794be74153077L,0x66f1c9d5a3e2a34bL, + 0x491d48f7c749830fL,0x3c0f3bcd5416d2bdL,0xaa3baada90b04986L } }, + /* 64 << 168 */ + { { 0x58225208ecbafb80L,0x4f212035aa73d6deL,0x1224e45562fe86dbL, + 0xa8c8a4782dc5b2f1L,0x8a957b8dc3096555L,0x6a3248b0b1591452L }, + { 0x1e563c58cb604c18L,0x32808cb59bf1045eL,0xf8f62de99462e7a2L, + 0x6b3dfe91c2489214L,0x6c1d8fc42174639cL,0xdfca11b8ef88d4b5L } }, + /* 0 << 175 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 175 */ + { { 0x5a4a5ce418690ad0L,0xd0f788e0fe27f51aL,0xd459388e4efe9a30L, + 0x3a45c11aef9d074bL,0xf68ab50b93ab9cb0L,0x62fbc397ecd9a566L }, + { 0xbfb79b7fcc587a7eL,0xfcf4d66f92870baeL,0x4f31aa21877390f0L, + 0x2de0c645e314cfb5L,0x56d904f6238eab12L,0x4d104a42ccb4d4f6L } }, + /* 2 << 175 */ + { { 0x3eb83a8729358cd3L,0xad741295b9c6d430L,0x57b8c77a53abe4e9L, + 0x0a14673ebb9feb82L,0xc0a6cbf7f26f922eL,0x213de299a32e526cL }, + { 0xca417e677b6ca858L,0x8d6ae0f7fc2e0900L,0x2bae0e7a62e135ddL, + 0x962bdcaea7ee82c7L,0x573d7f6ae5776c74L,0x9c4de6496ffbefebL } }, + /* 3 << 175 */ + { { 0x8c962fc809335d38L,0x26d1bc81eb38d176L,0xe1aeb295c47711edL, + 0x0812b9926cbe3e4eL,0xeecacaf90ab9805dL,0x82fefbaa3521a0adL }, + { 0x3a6948c0e2c31b9dL,0xb7d3905be82daf2bL,0xbd3ac90e25a34c37L, + 0x55afd99b61453063L,0x56d87cd190b99303L,0xc9bf82dd97ddb0a3L } }, + /* 4 << 175 */ + { { 0xcbc0bb1968916917L,0x0bbb9f921094bf88L,0xf62cb350d3806442L, + 0xe4d2f1cc397a7602L,0xa54bd48e43987d82L,0x77b6f8314f0a19faL }, + { 0xfa0c9a456e766443L,0x995ae0fff51ba70bL,0x8e242c5b9cbd8d33L, + 0x1671eb0813d97956L,0xccae388f40da55faL,0x97cc48faf376dce5L } }, + /* 5 << 175 */ + { { 0x1c2919bbe8c91718L,0x9dbb727a5097bde3L,0x23f87ae7f8ea2fb2L, + 0xe1bfffdcba310121L,0x5938c50c75329669L,0x716c63e00549855cL }, + { 0xe091b0c9654814f0L,0xa20535d10e43daeeL,0x16ce68b2593ddd04L, + 0x7813a49af59900bdL,0xef0d3eecd3e5d232L,0xe7d12cc40ee3fd4dL } }, + /* 6 << 175 */ + { { 0xe54d92cdef01fc5fL,0xc46c2ab8dda2e25aL,0x7c907fd2849f6142L, + 0xbb11dd2dacd0202dL,0xa4913a701d92d19aL,0xe9a26ae0cf610677L }, + { 0xfff1e1d5538943c5L,0x5943dcc4a47b2204L,0xcafcf33a92cabf71L, + 0xd571e13ce329d1adL,0x7626ad237a9a0e4cL,0xf0aa0d9f130d7f86L } }, + /* 7 << 175 */ + { { 0x09df3a4419e6aa7eL,0xe27ad0475841b1cdL,0x02d2a69fbde75934L, + 0xb0e05e53fd9ba435L,0x4732d88ae008c16eL,0xdebc4777ea72110dL }, + { 0xccb7d9932e3143adL,0x674f3753ea8cd06aL,0x56012a7a051562cfL, + 0x961df68425f74cd6L,0x26630e71214d8a95L,0x584e8d6365d92f84L } }, + /* 8 << 175 */ + { { 0x8a89daefebc5557cL,0x7ca71403275e1649L,0x48d923775b80bb4aL, + 0x0a587c52a45b3626L,0xdaff503cc75bfe91L,0xd845d3e6116d07d7L }, + { 0x6b5a4715a51eeca2L,0x34ac02bd74481991L,0x8f076cfc595abf8dL, + 0xc9de4ce9ed0391ceL,0xaaaad03ae1fcabd3L,0x8d48ec0087b199edL } }, + /* 9 << 175 */ + { { 0xbd0f2653ae5dd482L,0x59f968dd060032dcL,0x6bea33e067283310L, + 0xccce88cc012aa50cL,0xbb6d7f2f66838f46L,0xb764c95f05ec9bcbL }, + { 0xd097b60451477ccaL,0xc2fbda7b82b20a85L,0x75fe07a424e9ca8dL, + 0xfc4fa8240cc40d01L,0x0b17d5f90c0e95f7L,0x285e6e8a6e1e46dcL } }, + /* 10 << 175 */ + { { 0xb0641d09bc9b2654L,0xf9fcc2e68aa8fa35L,0xd12a5b4b00d5ec6eL, + 0x9be1a1115569d89aL,0x9c0566deffac7208L,0x7a9fd4ff7034edf1L }, + { 0x636aeb6b9571c375L,0x60d05aec55cdf187L,0xf4e2f898734e9d2fL, + 0xdaf742195ccdc6bcL,0x9d39249f608a4f28L,0xb5f1bb5e8820e2c3L } }, + /* 11 << 175 */ + { { 0xd02e9936d9589548L,0x8f1bf5755341402fL,0x1535a443057300aaL, + 0x3062478e65d29324L,0x4203351fc656a3f3L,0xbeb21b516569c4ffL }, + { 0x8113ce70e1f0f263L,0x59d1293903f9320cL,0x95061255d08f8936L, + 0x8be3c0f997d4b705L,0x0259742e827837c2L,0xf55ea28d95c65cdaL } }, + /* 12 << 175 */ + { { 0x62024812603dc3dcL,0x25dc5337efd67b57L,0x86b3eb38d7f033fdL, + 0xee3226b232646d6fL,0x8c4825f6f1dae596L,0xd2303055a5bcb8e5L }, + { 0x904a53493c0baa76L,0xe60f6125e08646a7L,0xaf6a329f21d45f89L, + 0xf20ad88a06605546L,0xcf7a0e9619a93d14L,0xf1eabcc891c97174L } }, + /* 13 << 175 */ + { { 0x72b76e9e8f02af51L,0xac94cbf1d580f95aL,0x2e9cd74801d854a4L, + 0x4ed4e9061f08a1bcL,0x0a2b28419d2bd936L,0xbf86350051c89ddaL }, + { 0x9407b0e7e3f00bf5L,0x6b1f71ff28b57ac1L,0xc1dfe03fcd28801fL, + 0xf3d83d64afa55309L,0x47aafba28af8f76fL,0x54eed45f6604b2e9L } }, + /* 14 << 175 */ + { { 0x59edd2640f3e541fL,0x318674b582b76ba8L,0xbf4a0d304e7f0716L, + 0x36fc0e4119b88200L,0x91db560240da801eL,0x638371ad2c72c2c7L }, + { 0xfe960c25d5822da7L,0x7a7571d14a7415e1L,0x5a6480febccc1576L, + 0x72f4e5e5c3c88f47L,0x224e7e749a7bd8ecL,0x3ebbf52c7631455eL } }, + /* 15 << 175 */ + { { 0xae3c2bc08608ab37L,0x35e3da8c39f336b6L,0x7413664281f44511L, + 0x21ce7c511d8506e7L,0x9b6718b3846165f1L,0x9e455007f5cabf6aL }, + { 0xec582a0e02611073L,0x269aa18d83bf042eL,0x7c54fb7c86306757L, + 0x453336021b948fafL,0xd3a5c508b7025d73L,0xcd6e555b428471e4L } }, + /* 16 << 175 */ + { { 0x42c9fad511a224e6L,0x6b6aeb8b69b2ac26L,0x0cf4c7fdb149854bL, + 0x4a7d90002fc359ebL,0x9ff0c3ea29ec8603L,0x157ae7859b24ee14L }, + { 0x638c809a8979e9bbL,0x347dfb2e7869d8c5L,0x2fb1e0f8a07ea547L, + 0x1e580d32aecdec3fL,0xbbf895730f74025bL,0xeb94d71bdd529164L } }, + /* 17 << 175 */ + { { 0x8670812a35d03250L,0x2f68343f1984cd59L,0x5fe890caf1ff97ecL, + 0xd47fff536f764b2aL,0x70fa44a4f8f7077bL,0x7b287efcb2c7fe02L }, + { 0x0718e70806dedcdeL,0x37193c827172c0f6L,0x47ad55f67b7f28a5L, + 0xaf83c4fe9c71a96fL,0x2d6075587c490626L,0xe647de1b933e9033L } }, + /* 18 << 175 */ + { { 0xdc5909e3f1687d4cL,0x4fe3be46d431c5a7L,0x28c41a035f9807beL, + 0x2c4203fd12f1f8daL,0x13f12da450a19620L,0xc32f881eae2e9835L }, + { 0x56328ef7622587d0L,0xcf785f038f209f66L,0xb562ea70a2697748L, + 0xa762289055598769L,0x9842bfa8fbf41fd3L,0x304c3057fa401ba0L } }, + /* 19 << 175 */ + { { 0xb8d685d1c56bc716L,0x1eceb18f1fccc358L,0xf94bedc82034cabdL, + 0xa9acaf11ad003472L,0x6fea0a55ad0786c6L,0x60f7f9a9581f6f52L }, + { 0xc4736494400bcca5L,0x221d8f8a3606b047L,0x533756fb6339c7fdL, + 0x1e068e987510c1a4L,0x9bf9abb6ededfa09L,0x96895ce548d54775L } }, + /* 20 << 175 */ + { { 0xc995b0171552c477L,0x6f92a95252351781L,0xa9d4bb6c4da25dafL, + 0x2b02828e3cf6aab7L,0x5f4febed11fa4d0bL,0x42f0e61ea12d9d37L }, + { 0x1ceef875d24610d0L,0xa7c85c485d4eeceeL,0x33fcfa3b79340a49L, + 0x3671e563b00b3491L,0x871f74e493eade0fL,0x1ed095182c546f3eL } }, + /* 21 << 175 */ + { { 0xc003b709a9a5c68eL,0x9441e7b26c84310aL,0x7ec3b652dd90f7c5L, + 0x17e601685b526324L,0xc5f77fee479573aeL,0xe89beed18453fe7eL }, + { 0x259a2b0364540cadL,0x8c2f13322b9a8053L,0x1db53ab7304940edL, + 0xcf780c5d1612763dL,0x2edd7285e19b62f9L,0x20ddc9874abdd7a5L } }, + /* 22 << 175 */ + { { 0xa70aa6781250954bL,0xe4a2f7cf2930f3edL,0x3e3dd26666fd719aL, + 0x500166cf792ff463L,0xeccd32cd75cf00a6L,0xb65f46a5c4526e56L }, + { 0xfc3a99c360aa8cd7L,0xe04a18b31290b20fL,0x957139a218cb9326L, + 0xf6b352ce11fc04a5L,0x9314b80778534e64L,0xd4a265c52d8f5015L } }, + /* 23 << 175 */ + { { 0x7078b4820dca1fd5L,0xec3192daeed504baL,0x144183332d06a63eL, + 0xaff9f7bd69c01ac1L,0xc5fb50475b74308fL,0x37846eeaa67e7ef4L }, + { 0x0fcea663976b931bL,0xd3407d42bb345b71L,0x925afc36a2deb11bL, + 0x12c271092207db49L,0x237500002e1c8fbeL,0x41427e0763f771cfL } }, + /* 24 << 175 */ + { { 0x9dafbe96491ddae9L,0x92c60b897741da5fL,0x1185b001b866ab14L, + 0x7a43b9cfca7f2f81L,0xaaeb5efc6ee8fdfcL,0x1f7cc70022beba9dL }, + { 0xa212724722e3e7cfL,0xb98dde1e9e723477L,0x87832183ac89706bL, + 0xdfb92ac1ff72f1d5L,0x5877fe6daade3804L,0x7ddde4a79170b9acL } }, + /* 25 << 175 */ + { { 0xdb147da0b7df600fL,0xbef5374660a8b100L,0xb4c7e404a1330d14L, + 0x152c6ae754f96693L,0x08884fecb25fd94dL,0x8ec186048ba59001L }, + { 0xdc245c0c9f8e77fcL,0x2be5aaebc0f0a83dL,0xd15bdecd1fd13525L, + 0x46b603f0821c9224L,0x6b335a7daf6dc128L,0x4cead4f94dc6b5bbL } }, + /* 26 << 175 */ + { { 0x239cccd8179fac91L,0xffa076063829d42eL,0x75b8589cbd42a0ecL, + 0x012f5e80d7f2292cL,0xdcee7efd99c14665L,0x4925256d23650737L }, + { 0x847c86ecf3cc64afL,0xdd34a75feabc04fcL,0xc2f73b3ac6a1f710L, + 0xe16e317565cbf6fcL,0x9cccffee351461d9L,0xe3d635543b4fe4b9L } }, + /* 27 << 175 */ + { { 0x6e27de1176ece8f1L,0x3ca873a79d5a3cb7L,0x7d65cdff7e424482L, + 0x023e5bcf69372216L,0xae601c2f2ffeb5a6L,0x8c8888cbde130b33L }, + { 0xcb8309485700ecc4L,0x5a1902ef9dfe1891L,0xe01f5fc558198380L, + 0x9d5d1c476c59f973L,0xacc64c98e34cc41fL,0x057d81f03065d870L } }, + /* 28 << 175 */ + { { 0xf3a1a9797aeefd73L,0x3fb166a09537abf7L,0x39e8c469d4c37607L, + 0x3efc85650e3f034eL,0xc955c2dff9c25655L,0xd6ce96ec260fa449L }, + { 0x5383a8b831d8e6d4L,0x3aed2e761a3595dbL,0xbd269c39e22a0f45L, + 0x4c82238694a7a83cL,0x362f08055731bd0cL,0x7dc1e7ee0527be95L } }, + /* 29 << 175 */ + { { 0x606ffedfd41ce228L,0xb87608d0ceb21740L,0x6fa23c0794a4354aL, + 0x587a7c54d5061d84L,0x75678bdb16b823ccL,0x2d2163c94ec818afL }, + { 0xa80b1e4e22c6fcaeL,0xc07cebee4d2a4b65L,0x64f303c7a895e2c9L, + 0x750079f5a768a2e6L,0x0665502c2d423133L,0xaf33176715135cdcL } }, + /* 30 << 175 */ + { { 0xda8f7878c715abf4L,0xc62292a5a5830c4dL,0xfcd30f7e4b46acb9L, + 0xb931f1ee39a73db2L,0xf838a5c84ee1afb0L,0x15609b57c202a921L }, + { 0x2e21871620bbba58L,0xe1d2fa14ae2615cdL,0x0a4dcf3543946185L, + 0x2e80d804730d2490L,0x5e43dc17794246b6L,0x7b3588c8dcb3be9bL } }, + /* 31 << 175 */ + { { 0x3e74f09c1bb8e6e2L,0xac587847584dba0dL,0x926415593f843324L, + 0x0033257729f3ed18L,0x4b7164e5d0089537L,0xc50542793e54c9a0L }, + { 0xbae7ff9808e58162L,0xc0707d03c1aa2fd9L,0x43524f717714dca8L, + 0xa202a0707255b169L,0x0a7867ab4249b2e0L,0x03f748656d6ec5e9L } }, + /* 32 << 175 */ + { { 0xfa2db51a8d688e31L,0x225b696ca09c88d4L,0x9f88af1d6059171fL, + 0x1c5fea5e782a0993L,0xe0fb15884ec710d3L,0xfaf372e5d32ce365L }, + { 0xd9f896ab26506f45L,0x8d3503388373c724L,0x1b76992dca6e7342L, + 0x76338fca6fd0c08bL,0xc3ea4c65a00f5c23L,0xdfab29b3b316b35bL } }, + /* 33 << 175 */ + { { 0xd2437a52eddd4b72L,0xe2cec2abf051b831L,0x845af98e482a4ea4L, + 0x75758ccfa43cae82L,0xa76733429260ea35L,0x77845b02b1dd602aL }, + { 0xb78bc4c047d5c450L,0xcb1f444550ad371bL,0x6bc01293d71cc417L, + 0x8538f638c1fcb367L,0x5d01d35919b313f3L,0xcd6b55bfcf67f6acL } }, + /* 34 << 175 */ + { { 0xc28000d6e3b03290L,0x4dd5064a5f2ddbcdL,0x4916f830338a1414L, + 0x3ffb8381aca74c22L,0xec073ee8e680f548L,0xa34e0693a0430cc3L }, + { 0xc6baf20dca03e6e7L,0x2a30df6e835fb88dL,0xbf3c9e9cc2092d6bL, + 0x391cb25c17bc2433L,0x9b7de7126c205c0aL,0xf25e1494cd2a5e62L } }, + /* 35 << 175 */ + { { 0x05ae44e9d21fdc9aL,0xc520657fce40ebbaL,0x6b8e25431270cb59L, + 0x24e6f9bff7f096d0L,0xc6ded76a3ed81f52L,0x729d05e75f7df798L }, + { 0x99e2636fe5468eb1L,0x6f3abd4c00419facL,0xfc61117a9cc41e09L, + 0xb16f106baa399a51L,0x05603bc845e52713L,0x612658aca5c36107L } }, + /* 36 << 175 */ + { { 0x107573b96defe8f4L,0x9a9edf0570545313L,0x5df43df0e54e8272L, + 0xac91bae8eeb4ae90L,0x241d54bd26006ab1L,0x0ba118a6c031de7dL }, + { 0x376214671f500d4fL,0xbbd6b318bc3596e4L,0x4b5532c85992277aL, + 0xb15165da16a4728bL,0xbd7986d45140abdfL,0xf4fe16df7386f38aL } }, + /* 37 << 175 */ + { { 0x8c5d305696aeee65L,0xe52e500ea79991dcL,0x3af4a3ef343fdde9L, + 0xc6d0389b248ad10cL,0xc3dbdb3f5014de53L,0x606b1352310a0cd8L }, + { 0x65af3f8479bde08fL,0xa6c7d968d82ab682L,0x7262c07d202a6508L, + 0xd0231bb64cd75fe0L,0x58a34ca5dcb1f7fbL,0xcc8b21b21b8cf7a1L } }, + /* 38 << 175 */ + { { 0x4cd6e61be824653dL,0xfa02c0c9f253dd65L,0xab198e41b1e84cedL, + 0x89ce6aff1928be7cL,0xf2a83f4895afb956L,0x5b5f195ddc73f3a5L }, + { 0x44220ff79328317bL,0x03d62cb7f5239616L,0x0e908d34b5d49415L, + 0x050b7651c1f7e665L,0x3610167089e1a98bL,0x564abb3418eb7644L } }, + /* 39 << 175 */ + { { 0x400b363b2eecacf6L,0xe2ae5bee1ed9fb9aL,0x23374b11831e99c6L, + 0x0a8382d82cb9de95L,0xf95b8e052dc02291L,0x63b05a0d2f752257L }, + { 0x9ec16f84b60d9df4L,0x6ed683ac3bda5171L,0x7206450813acca39L, + 0x6024af3cf8871ba1L,0xbf88040e2f9a4d56L,0x001054149fb100e5L } }, + /* 40 << 175 */ + { { 0xd52c606375ccd2e3L,0x4fa8e4df56ce654aL,0xcd905c9bce581d23L, + 0x51ce0eab24ff75eaL,0x1c1c0831432c6e5fL,0xb83307aec02f0e86L }, + { 0x0b7a0274fe2ee821L,0xae7dd7729c3d69faL,0x54745da5931ed75fL, + 0xc276d96f18caba13L,0x142571dd26dd9792L,0xc522dac16c0e3167L } }, + /* 41 << 175 */ + { { 0xa86fa630197b5b97L,0x749ea479fa21c176L,0x520c0e4871ce7101L, + 0x5c53d9ebe30a0b0aL,0xdc71b629ceb570feL,0xa30fc3d11fa3699eL }, + { 0x741321b579cbbfa4L,0x205ea0aae8d18119L,0x94556e92fc62e0eeL, + 0x5ba78d4e042b9c3cL,0x14de84103fa24a56L,0x6e57a9fbd6557bceL } }, + /* 42 << 175 */ + { { 0x2a5e716ff103d9c9L,0xda2f7e5cb9cd27ecL,0x317f74b8e047e5cbL, + 0xf1f496d33a4413feL,0x1a480a9cb8cc9fdeL,0x502b52d7575208d4L }, + { 0xf14fe00cd19c49a3L,0xf5c2367b269be5a9L,0x966a524f12d42690L, + 0x2786ff714dd03b95L,0x6fa1f891d69bf68dL,0x0f3d77579f67b3bfL } }, + /* 43 << 175 */ + { { 0x230c8d00c966c638L,0xde5c9e8e54673305L,0x618b0dd561bc99faL, + 0x669618048f3cb5c0L,0x7c653ca507141ba5L,0x454d54ff32ba155aL }, + { 0x82665a307df3e39fL,0x15eb1a65ca19cbb7L,0x4e7632a617330ab3L, + 0xc69235295a3221b4L,0xe23ee9382eb58e9dL,0xb320aa8e23bcf88cL } }, + /* 44 << 175 */ + { { 0x6ba15fe607a7ecf8L,0x93127926f831cc91L,0xfde2dbf41ff6264fL, + 0xdf7f22018413fdb2L,0xdd81d11487f66260L,0x87907f0e4a87133dL }, + { 0xeac1032cb1d47e23L,0xe2603119125a0918L,0xba680392f2259208L, + 0xb7c7f8ebf9bf06b7L,0x875a380fa56ba57cL,0x05a88a97460c939cL } }, + /* 45 << 175 */ + { { 0xfb2871b7d0dc771eL,0xd12b21fcbaf358c9L,0x30dbd412df616c16L, + 0x291bd90f9345e16bL,0x92f7534b8ee6bb6dL,0x7ebc5b0eb1c901a0L }, + { 0xc9e9c76151e1881aL,0x5ca52152756bfecbL,0xb0a9f5cb6affd506L, + 0x4c12f965669feb3eL,0x01d84b9ea6f1c529L,0x3870fa27e8433c92L } }, + /* 46 << 175 */ + { { 0xe4e9e72495bb5db0L,0x86babe3ffd616958L,0xc1520c280f93c1cbL, + 0xe393ded539cab777L,0x031a2af3e86a6ca3L,0xb26a19101e8466eeL }, + { 0xb16b746dbb64fd81L,0x4e96f0b65a97d50eL,0x7a12a611a793fac2L, + 0x8d729847db6482aeL,0xdd050ce812e72ce5L,0x915041366c54299aL } }, + /* 47 << 175 */ + { { 0x9e8018c06b63c4beL,0x49dde0c8fce47904L,0x1668de9c9bae36cdL, + 0x8dfb0d5f80ed18aeL,0xfd6739a791e1949dL,0x80353c9f8053d7d6L }, + { 0xa611699bdea54710L,0x5eacf16e6c6c1f5bL,0x5212fbd3c920323eL, + 0xaf75db75848d085fL,0xb58564b1babb45b8L,0xefa1958938bc491dL } }, + /* 48 << 175 */ + { { 0x0a43a76c2f95a081L,0x27eaf2bc38b1c395L,0x6ba3222c63da1d80L, + 0xd95ae17e6a78ce09L,0xa72d9812508f03b3L,0x9f36d02efa8ed359L }, + { 0x1716d1dcd5118f96L,0xd116339f489bbc53L,0x272153ef6f7e1d3dL, + 0xcb4a9e739e308d22L,0xcfa9d88b615a3646L,0x8b69bd6cde454569L } }, + /* 49 << 175 */ + { { 0x33ae0fec2b8f41feL,0xc45aac500762c46bL,0xa03bc6ddf228ec44L, + 0x82cb78cfea3d48c2L,0xbe7a02ed27126795L,0x1a44d1f830b3e3ddL }, + { 0xb414edc73be7b58cL,0xb3e6c7ce331bcbc9L,0x9f6fd0f2903b3508L, + 0x260c8b5736cc2930L,0x8581a05d0d59278dL,0xfac1817b189b3005L } }, + /* 50 << 175 */ + { { 0xbf4d4640cc9a69c3L,0x07b39b5d67d262dfL,0xcd4a6a4579526d6cL, + 0x4a04c430538143caL,0x6c3341b86639e3b0L,0xd490cab5ab7216d4L }, + { 0xedda2b64a2a93161L,0x04e309de644a06f3L,0x7cad728a8c4495fbL, + 0xe1744f3871dd61f4L,0x39cbd782e3201618L,0xbd66e1850ca18ab4L } }, + /* 51 << 175 */ + { { 0x69d8237f87dcb8beL,0x3f9a485b090e0237L,0x535371e1f117a1c5L, + 0x0d5ef52675430c29L,0xcb9c150898fdd18dL,0xc7c1a7b4108d9383L }, + { 0x6ba9fb4d98064eedL,0x07d205a9a3df31c8L,0x7a0be62e9be5da37L, + 0x03b21b1255a9e2c2L,0x3f4792263de80449L,0xb0160ee1ae3bf31cL } }, + /* 52 << 175 */ + { { 0xa22c084a7a3f8c5eL,0xeb7fe23f3ef30511L,0x161ca862819fa38aL, + 0xe5f014156d45762aL,0x37da6bb95718b789L,0xfcb682bbd837f453L }, + { 0xc49c7397275e5974L,0xbe908df5a1ed0925L,0x3dcd694615a13ea0L, + 0xdbe652e32596fa76L,0x6a3bcc93c55d376cL,0xa2f7611933a0f02bL } }, + /* 53 << 175 */ + { { 0xdfff9b9c6ed061ffL,0xa36aef2dec32b16cL,0x9f3b7ab6da61572dL, + 0x96e72a027ac2dac9L,0xb0e36e023aaf4fcdL,0x5f32a620503004cfL }, + { 0x6c91dacbadcd649aL,0xb25deea21ac02a32L,0x211a421ffb914c2cL, + 0x1ddbd60e149fde1dL,0x91c4cc0d7ce86ad3L,0x8be6f031b9ed909cL } }, + /* 54 << 175 */ + { { 0x62e773c4a0cb50ffL,0xe54fdbdd2e903681L,0xed2bce9e21c12ca9L, + 0x13aa4748c072bae6L,0xb290c0ad475f290eL,0xcbbc3f9b56698a85L }, + { 0xfb37611b1b7fff76L,0xe62a842260bc2e36L,0xb6a36c783bb20fd4L, + 0xdec045418dd69509L,0x67648b7798a1ad2aL,0x4fa2005d078fdea3L } }, + /* 55 << 175 */ + { { 0x757f249416307553L,0x865af9d0de6bcb49L,0x3943031a07b0104cL, + 0xe5fdb46168da2d33L,0x4937d614b5432b48L,0xb3fbbf2c0a29a5e5L }, + { 0xe7d3b12b8de89887L,0xc1a43c24e41258c3L,0x91ac7eabf7d9efe4L, + 0xfd90de0088385cb3L,0xead102e37674c39fL,0x7b9a2cc4fff118c5L } }, + /* 56 << 175 */ + { { 0x11f92678a1e598f5L,0xde8052491fbb882aL,0x3730b3261154d0aaL, + 0x0e279827da521670L,0xa03c8c702336f8c0L,0xae50e64ff0bd66d6L }, + { 0xfbfd665f7af4f681L,0x237a4f4e5c8d5680L,0x6527611ba409064fL, + 0x1f4eff6a99db9a94L,0x4a55d96ae53ba177L,0xd9dec234f002368aL } }, + /* 57 << 175 */ + { { 0xbb837d0ad193ebc0L,0xab1e3eccd09b24caL,0x229f36d81d848777L, + 0xee895edf0ab68c98L,0x67fc65f4dce31b92L,0x777ebe585db96c26L }, + { 0xca0893ae6047d0d6L,0x71a2ca0b550d6905L,0x35426866eac4c2e3L, + 0xb4d7e78e0c1b8eb0L,0x03cb0a9a84b384e4L,0xd8a99a5c7f7115b6L } }, + /* 58 << 175 */ + { { 0x07db8bfa5f25a74eL,0x97dd568a3dd8e706L,0xcf4c02a32fb59efaL, + 0xe2ae502616b291e4L,0x5499f3b20f9c10cfL,0x59abdcf5a7297ec7L }, + { 0xcec282671f4a3646L,0xc10ae0971e065cb1L,0x172f886319dbbaebL, + 0xb0c27f7d73dd068aL,0x764d185495086ceaL,0xb89923c732de9a97L } }, + /* 59 << 175 */ + { { 0xacd499ca093345e2L,0xfbdb3895f3c23800L,0x2584f8ca02f0fadbL, + 0x9f5dc96ec2f35eddL,0x4dd102ca1ba0266dL,0x13ee9c8aa9f26fabL }, + { 0x9e7467fa2a1e61daL,0x999764b6850191c5L,0xd053a575b70dd8dcL, + 0x697b856fd7065eb7L,0x9d5bb6aa695b4914L,0xc5cdd170e65001f1L } }, + /* 60 << 175 */ + { { 0xe87cf622e93495f0L,0x347b09c6bb43a802L,0x2a38f3b7a4e3ac34L, + 0x13353b959751c1c4L,0x753ec3ecb3947985L,0x3bf856dc12d3fa90L }, + { 0xbf4f6fa5ec35dbe0L,0xd099a15bf3b4fcf2L,0xb348462fbfe7245bL, + 0x508324b352a2d4f4L,0xec4bae05feee1315L,0x468fa9e404496618L } }, + /* 61 << 175 */ + { { 0xc57673257d5e7a94L,0x40c05da604cefc01L,0xba1fd6c6b921c681L, + 0x0d3e09f9c104cedfL,0x4b7cd83cc6586416L,0xb747d7f9adfa7bfaL }, + { 0x833f8e24a42be782L,0xd5f0421d06b2471fL,0xac87b17c22e4b84eL, + 0x85af6b063a10c7bbL,0x4e557cbf66e88e2aL,0xaff21b66d3751e40L } }, + /* 62 << 175 */ + { { 0xdbab25f4c4464538L,0x3c36560ba93d7f74L,0x8b9b15d39f86f410L, + 0x1237e35b0a1db237L,0xc9dad97994f49677L,0x390a3d8f15dff99eL }, + { 0x0a74dfaef82c19edL,0x3f8e958589c2dc55L,0x763448ce94a8e729L, + 0xc6349398625f0517L,0x1ca5f9e7523dd700L,0x45aa25317fe638dbL } }, + /* 63 << 175 */ + { { 0xe91af601aad04ed7L,0x6f86f323e897df2eL,0xf8c259564c7a0ab8L, + 0x6e793f3633845d15L,0x08937ef5e583d043L,0x92dafa5824d1fd96L }, + { 0x6458ae2a86c9aedbL,0x271823a026a4252fL,0xb119fe4c5a57ef16L, + 0xf41e13943a507289L,0x0cbf1da6bd1aa499L,0xa177ac9dc2465a51L } }, + /* 64 << 175 */ + { { 0x14f962e404a8313dL,0xc6e3e7c45f1f5a26L,0x2c0e11c079e777beL, + 0xa1705efb4657c31bL,0x02688fd23c494de3L,0x75664a84412a8718L }, + { 0x878fc7ad7a422f8aL,0xe5d581df7419bd0aL,0x7c813c4c704b70c0L, + 0x98553da87323c008L,0x4f63cec663089f1aL,0x9626d6fa9655d291L } }, + /* 0 << 182 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 182 */ + { { 0x10586ea7507f8b27L,0x1510deb9a261f7d7L,0xa42fc4d7dfbfa352L, + 0xbf38c3821e1c2291L,0x46e40ef60e11760aL,0xc24f6061dcb974d7L }, + { 0x755b105ba7619027L,0x8004bf09b8ffa759L,0xa630d0b00945db60L, + 0xa160ac9cf2809e1cL,0x38fc1113dc6c95c5L,0x01f540985d52574fL } }, + /* 2 << 182 */ + { { 0xcda68a7e698ee21cL,0xc7414d196a5e725eL,0x483be2dadce20b91L, + 0x7de1601cfc69dca6L,0x4bec17aaac4f9891L,0xe8741dd18d479a56L }, + { 0xc623cb8dac23a286L,0xe20a96b5166133f0L,0xda9bb7c030dcde61L, + 0xf84ea3273a1733fdL,0xd7afb6c3e82fac31L,0x37ea7d35d3897449L } }, + /* 3 << 182 */ + { { 0x120649b20370327bL,0x0e76555acd48cdc6L,0x4ed54decca01db03L, + 0x7be21319ac601d22L,0xf711661901b6576eL,0x7839fa064e73537fL }, + { 0x169d43ace46e860aL,0xde6d658c3078eed9L,0x8df731395032142bL, + 0x6be199b09b3c76c7L,0xc2f385f6f8bbffe5L,0x848df7f3d5ffd28cL } }, + /* 4 << 182 */ + { { 0xa189f30fc6a6d6d1L,0xdd674d3669665ab8L,0x307c9ec37d8da76dL, + 0xb3e1d006c1ea7c10L,0xc15e20b3b88c62d4L,0xb0000ec50bff3b3aL }, + { 0x9e330eb19ff9aa5cL,0x8663f9fddf578877L,0x157d3cb002e1eb2aL, + 0x638f297bf525e4d4L,0xa20f833234a3dff1L,0x748ea86b45a9c051L } }, + /* 5 << 182 */ + { { 0x978ed3abe664c066L,0x3f4a8e0d668361eaL,0x0ba610c753a25231L, + 0xa8b5b864189143c6L,0x0d7ccefca2841fc2L,0xa80dd8f3f8fea1e1L }, + { 0x2c24af232e19028cL,0x0e332b77919decaeL,0x44eae977f6089c76L, + 0x25e04dae53722e9aL,0xdd6f8b1f71ac4db0L,0x7c5b6ffd075e7bc4L } }, + /* 6 << 182 */ + { { 0x4c6299a7a1de1cc7L,0x362d293c02d9445bL,0x08f24df0399a9494L, + 0x33307792e37a1851L,0x1cc5e448760f680dL,0x70a6a8164a2efbefL }, + { 0xee939681246fc671L,0xfa7a26d1f70a9c14L,0xfae5ca89b826aab5L, + 0x6b8932c7e48176f9L,0x379f89bd9841c8e1L,0x46141d2fdb674190L } }, + /* 7 << 182 */ + { { 0xf4408485b4619d3aL,0x34b4f18160b4f44eL,0x369edc1b3532caf0L, + 0x2d0471ec6771abc2L,0xca4129311013266dL,0x02e636af617e2024L }, + { 0x1f93d60d3c69696cL,0x6aba7f2a1b99a172L,0x896873e1bf435ce6L, + 0x9649f08215b71e40L,0x730bedcfa02b024fL,0xb17e9cbd8df60bfbL } }, + /* 8 << 182 */ + { { 0xfe9fdde8bc266ee3L,0x91668688ba18e6c7L,0xa65349acddde6f6eL, + 0xc53c29c97e54356cL,0xee15ad945709f73cL,0x033b3940e5429277L }, + { 0xf52035cdd0c3475aL,0x9c5bef4d93f1f1f0L,0x26e0b0ceca319bd4L, + 0x4e7eb67b6951fd8dL,0xac3a6f4395c34d6fL,0x1f2769e600f60b59L } }, + /* 9 << 182 */ + { { 0x95188c136c4d0bedL,0x377a04901b5271e7L,0x60db30226a540165L, + 0x4be61fda3310c5b9L,0xbbb4fbe93f8bbf16L,0x5232fb46ac12f77fL }, + { 0x8d6f75ab255b569cL,0x09cc854d3bd39650L,0xec17a6e74b557c3eL, + 0xd6949f9d5c3d149fL,0x9a17a440494b18b2L,0xc10cb9d5d4a024acL } }, + /* 10 << 182 */ + { { 0x4520be6b8eddc97bL,0xeb8f2c317391f948L,0x18fcbbd772369418L, + 0xb8950ee217246882L,0x6b1e4b7a382e82c2L,0x9e2bb1eb7ea4c447L }, + { 0x5202d913c3c5bc54L,0x53ea78cd21352716L,0x7bd53ffb36e6b4ecL, + 0x8325bdf817387196L,0x33b2cd8af94d6a73L,0x206bdec5e13db4bcL } }, + /* 11 << 182 */ + { { 0x6e27ce2609c98c86L,0x8f87ec4c958002c2L,0x00b6897064ab26edL, + 0xd2b4037282e5e129L,0xbeae654c78c48327L,0xc0632b4341a54107L }, + { 0x7b1fc7f001562313L,0x01cd1b5c1fd6a56cL,0xa199a69835e71626L, + 0xb02b2692635fbcffL,0x1c0c4200a0632386L,0x637164f8d6c670e7L } }, + /* 12 << 182 */ + { { 0x2c47010d18e30ee3L,0xb7d4b1dbfdd5f040L,0x5c8abe509d930f6dL, + 0x6bcf875d5f56cf04L,0x1f6456c0062f1fc1L,0xc79597805304d710L }, + { 0xd76452e4db85dcecL,0xd531f73fa0cbf90cL,0xb5ae9fc89021bde6L, + 0x505c6b9f4babfae0L,0x99d943c17ea61fd6L,0x6ef4766159bf125aL } }, + /* 13 << 182 */ + { { 0x3a48020daa0b0a5dL,0x4a32d4d658bad0dfL,0xe013dbde2e4340ecL, + 0x99efac69a5fc51f3L,0x26acf7a669ee64c6L,0x36672d6566fdc9f2L }, + { 0x77426caedcb879feL,0x0166194676e3be96L,0xb6fe4709b2dac331L, + 0x1f3d8a63678ff3ebL,0x711c0ea447bd5865L,0x5fbe38e87c080adeL } }, + /* 14 << 182 */ + { { 0xd0891b2df4e61379L,0xea2c7ceb9941c391L,0x1441a2d099677e8aL, + 0xc29d88c8abcb3669L,0xecb1a21a06ce9bd9L,0x0663fa7cf5b11fc6L }, + { 0x440a5a1c0c44c2c8L,0x08d71bc39fdded3cL,0x62b53ca512d33d2eL, + 0x3fb8640e005e8adfL,0x2a9acaefaa2673a5L,0x356ae6f6695f8448L } }, + /* 15 << 182 */ + { { 0xcf3c9b318496d935L,0x7e849aff8ceefc78L,0xfc06a46e7a5d692dL, + 0x87248699e89463afL,0x4dc55e5e8e17af3cL,0x3378832fe41ec54cL }, + { 0x7578d6192816f87dL,0x505845612806d3cdL,0x7354f1022754c3d7L, + 0x61ca6cac08d64863L,0xecde4969eb9954ecL,0xe0c211b4a1a5dae0L } }, + /* 16 << 182 */ + { { 0xbd10b8bffb787270L,0x4f0b1566e43aaab6L,0x9a18be5ec0c90781L, + 0x3677f4c71ad167ceL,0xccb254e2a68c1c56L,0x392493e6e2c4d275L }, + { 0x44958cb1d5b63617L,0x178f141a4caa4e7cL,0x7445a767a2ffdbd5L, + 0x0e789c99b0b6c22dL,0x3ff8b6565dc92b2eL,0x1623e5c3eca98782L } }, + /* 17 << 182 */ + { { 0xcb013ff62c5c50daL,0x5e5550b70b256dd6L,0x38249ee1bfd47036L, + 0x984daee275379fbfL,0xfb35304588c6bc7fL,0x32379c955f9683aeL }, + { 0xbcb4ac531b5a8626L,0x1057d2a3bbaa0deaL,0x114ef8a7ffa8efb7L, + 0x553a34566da90cbaL,0xa2ced0b21a365fe6L,0xcec4d64bb1ccdb57L } }, + /* 18 << 182 */ + { { 0xe0312b66b81fe0eeL,0x11e0493b892c7b21L,0xb6a1d76e624ce73bL, + 0x38768ec0cd75cb6aL,0x425b091f2032c271L,0xa88d39f55b5d8338L }, + { 0x1496b9ed1916be43L,0x14468e3054549f3cL,0xd429c2c47248e206L, + 0x21a1c212fc9e892aL,0x0feb5822640c984dL,0x0cabfb472b7c0c66L } }, + /* 19 << 182 */ + { { 0xcda1c4cd1cc5a20fL,0x33d66a893f67814bL,0xbba50d5360ce82edL, + 0x9d34dc4d70553a53L,0xc926f498a8a1442fL,0x9dfe3cbccbb43feaL }, + { 0xd25887434fd3e4efL,0x7443a9a9a371d894L,0xb53e6afaa22bb4f9L, + 0xcef3fa347dfc9da4L,0xd079ded047403836L,0xc6c97c36d39aa93bL } }, + /* 20 << 182 */ + { { 0x6618fcae534f6370L,0x1635580da1a864a2L,0x90ad39947d7ce552L, + 0xbf8c45895257f24bL,0x5a9499202098768cL,0xec1eb621bb6d8830L }, + { 0xfae8f161f1f9ac16L,0xfc9184ca35704c99L,0xa72b1ea9139ea04fL, + 0x82229a912e39e1d8L,0x4153bf3e479c7bc2L,0x83325be4c5541825L } }, + /* 21 << 182 */ + { { 0x358a91badbea81d1L,0x4d1947d7c669c7a9L,0x4ca6d8f18eedbfcaL, + 0xf9eda237069b3b93L,0x9e1217e5a35ea963L,0xb7e16f08ab960c77L }, + { 0xf440d825fb313db7L,0x804c5262101c5424L,0xd236a0edab3c4f7aL, + 0xf8bdb2b1c2682459L,0xfaa7aacaf46c4d70L,0xcf6ce4adae83dd7cL } }, + /* 22 << 182 */ + { { 0x2c7756bcbd452842L,0x2c47593cd1783fd8L,0xa4f41583a7527697L, + 0x2fddafbbd1049934L,0xc087f3db6c71063fL,0x8f5a85c4c9b3ef6cL }, + { 0xbe178bc966a975d0L,0x2e2d825b94066514L,0x061dd919e0d42ba4L, + 0x964fdcfb227ca011L,0xcb915b2973d7ba7aL,0xaa7f2fa72af8338aL } }, + /* 23 << 182 */ + { { 0xbdbb3440734e8984L,0x8b9b7acb3d6f547aL,0xfc4f48ea0e76a07cL, + 0x49758a9f97da0c23L,0x13f4254a26958261L,0xdf1fdca2adb3ef57L }, + { 0xfafba40d699460e6L,0x71b2de39cd5c94c4L,0x52d76b76c21cdf0eL, + 0xbe75960760f3dfa3L,0x519d4fcb7078f5e0L,0x4bd8ca7f5191e1b3L } }, + /* 24 << 182 */ + { { 0xfadf9be978207cefL,0x97d5ba569cb5718eL,0xcbad24ec2f995393L, + 0x6236a26861203303L,0xe4bafc336589a4beL,0x6cba77185e23fa82L }, + { 0x8ccbc5774583e65aL,0xe5d88bca4bc2f415L,0xe6bc2d5841df8dd1L, + 0xec24e1d914d31fcdL,0xacaaf13efc26010bL,0x7e1da447e01b92f3L } }, + /* 25 << 182 */ + { { 0x2b3477ec1a29de39L,0x30a5c2190a8720eaL,0xf593ec729775bad0L, + 0xaaf607792af7dbbeL,0xaace90d4c7cc7b59L,0x6eadf21d40509cf4L }, + { 0xb9a5f138096d00fcL,0x3896d42625b206a0L,0x0f28f0f09dcaa5dcL, + 0x2ef6f9f9a8186106L,0xd212710fe25b4d04L,0x0cc6d2878b9847b2L } }, + /* 26 << 182 */ + { { 0xe7407327cdfb2baeL,0x06745198510c3039L,0x8a913ba74da758e9L, + 0xc882e7bb1a4797abL,0x0f0d8eb5dd7b375dL,0x90ac5223dcff3f3fL }, + { 0x8443b7cabbe341a3L,0xa7cba7f22f173bbcL,0x04669ff830e5c327L, + 0x0edd0eac09b777fcL,0x2a70898bd71e0cb2L,0x881c48929bd983bfL } }, + /* 27 << 182 */ + { { 0xe4847c654e7603f4L,0x826cd33c0bbea366L,0x95727caf2c4ced28L, + 0x580313dedb8ac1e8L,0x6745673701363cb0L,0x540c35ec0ff13cc9L }, + { 0x878c86fe3c4fc263L,0x4d81f8aed14e7c78L,0x6f7cf97e8355ef22L, + 0xa2aadbc848a0aef8L,0xe0200ecf4fc3c61bL,0x7e58e6e0c8094ab1L } }, + /* 28 << 182 */ + { { 0xc52789bbf2d3bdc6L,0xd38673fc3b23d7a0L,0x8b6df95aacafbbfaL, + 0x37afdcbdc7f6eb6dL,0x57775bdd6cb4c9d7L,0xc34e5a2711007453L }, + { 0x903e5ba1b5faf98eL,0x811e142a9d4a8a45L,0x046d18932d7ac9e4L, + 0xe2fe9d1543ce66a8L,0x44b5beb4d4956410L,0x7c5f1b9ebb147f72L } }, + /* 29 << 182 */ + { { 0xd51033f48312b074L,0xc98fe29456f898d7L,0xa8d6433be8eeebbaL, + 0x50bf170976fdbb84L,0xdd95f89d43c14baeL,0x13f9c7366307bca5L }, + { 0x3cd12e2855e7bc8fL,0xe2d7482c3a52581cL,0x12a2c6c7b59eeb8cL, + 0xf98f79124ae87ffcL,0x41eb808e80d7bf65L,0x589970f2015e20adL } }, + /* 30 << 182 */ + { { 0x200a764a6333b070L,0xa0acd8ecdf0d20d7L,0xbc1c589953269941L, + 0xed7c9192b439eca8L,0x057c50eeb789f0cdL,0x31dc2d36a9c794a3L }, + { 0xe3f2d38dd58ef984L,0xdb250da69235b084L,0xc2ff1b49da05b500L, + 0xf2ea6cc50387c539L,0x8250353a3d1004cfL,0x69103201aed0bf97L } }, + /* 31 << 182 */ + { { 0x495cd7fc878e97f8L,0x6397fa8b61120b1dL,0x20b9afddc8708907L, + 0x84f55bb97be2ee80L,0x996fcb9d8d075b5dL,0x2e94d95ead858627L }, + { 0xf786143e77113ebaL,0x6fec684f7b3fdb28L,0x4be44fb211d10d07L, + 0x4b3478e2372f16b6L,0xec8d61614697ca58L,0x097d241c3a45f335L } }, + /* 32 << 182 */ + { { 0x6f6a6104899ef333L,0x95496f6d39067165L,0x42fd9a6ab51989e5L, + 0x1b60ce0f68f5b168L,0x97324d8756f7fe67L,0x443812f7676815a8L }, + { 0x265ee994685a7260L,0x342c7b2f6c6515f0L,0xe909232334b4adb0L, + 0xddcd233e1e5a8d18L,0x3dc5b27c5f4f6456L,0x9664533a7f421d9bL } }, + /* 33 << 182 */ + { { 0xa55e8ab09a35f4aeL,0xf908fb35ebbadf5dL,0xf885d61b35fee31aL, + 0xb8047f4f82728fdbL,0xa6fe454d33c5bc34L,0xdc5266332ef52e54L }, + { 0xb2f524a931581251L,0xb9eeec91aba760f4L,0xa95d396624a9b423L, + 0xfd52f4d29d3d75acL,0x82719e78834d4c33L,0xeeca71fb3840ca62L } }, + /* 34 << 182 */ + { { 0x984658940f4c60e0L,0x3929d4c645ce7c0cL,0x7846d6c19c4f9b89L, + 0x2c38a9b20fbc695bL,0xeeb4799ad73d4bb2L,0x7c16e5ba4e3b5520L }, + { 0x11ce92e51cf310d2L,0x0910dcc91e037725L,0x159fcef85fc5af9fL, + 0x4944f8ee1dcb3ca5L,0xf5d9f8c0b9a4516fL,0x452f0fa2f1cfa6e0L } }, + /* 35 << 182 */ + { { 0x59b15b61c634aab2L,0xcca0742a620df0b6L,0x791d95720d345276L, + 0xb775b790cd3854baL,0x944e591a256c26fbL,0xc5fda2d0b8fe17d9L }, + { 0x7dba5830c0aff69dL,0x46f7164b0f7c6d60L,0xd767cd58549eeb83L, + 0x4498b4f51ff2da7cL,0xeef2caf8fc594b0eL,0x88dc39ec5f0a95b1L } }, + /* 36 << 182 */ + { { 0x1a57d3e1b3fe597eL,0x1a3ad06d18d1b6f0L,0xf70f27b32e4a4617L, + 0x55e8a0479a75b4adL,0x0b24d5beede15d86L,0x2b3c41d0fb2f56b5L }, + { 0xf6cf36aab1d36456L,0x418a72fe1d8ff434L,0x64149a0d156746bbL, + 0xae65897c4e3a26d6L,0xb75e87d21e68eefdL,0x5b81e0b01cb27c91L } }, + /* 37 << 182 */ + { { 0x2c3fa19b34b90671L,0x369c9e9aa7c9aae3L,0xd89dc03f3d236ad0L, + 0x280c47b9588ace95L,0x0ad071be57f25a96L,0x36ce641d8296279cL }, + { 0x321778128595511dL,0x51878842b52cb227L,0x720df7ab4156b413L, + 0xccc71e10fed25819L,0xc878554e3fde679bL,0x9c50ecbe3b565d48L } }, + /* 38 << 182 */ + { { 0xb2d66f1ffe23ba35L,0x82339e2914b273a4L,0x454a5f0b58c2be97L, + 0x0ebadaa68488ac1fL,0x3c635442517e9af1L,0xa87044c3a5b9fe2bL }, + { 0xb8214dbdb505ae0bL,0x05a9bfad60bf4393L,0xb7b64b42428a49ceL, + 0xcad71866bd2283f1L,0x5bcfe7fce33a3a22L,0x018a2121fd6c73c3L } }, + /* 39 << 182 */ + { { 0xc4471fb02510a1c7L,0x542e73bd2c1c35c1L,0x0bc8bcc4f028a46aL, + 0xdf87cd2bb5610f25L,0x0845e4d1df42b41fL,0xc0523e3593aba84dL }, + { 0xc9161e8ed14887b0L,0xa96f9b3aa68c235dL,0xba1427a46f94d5b5L, + 0x6a5fdbbc858e00f3L,0x8170bad6abfaf661L,0xb4b9dc0ec9f4abedL } }, + /* 40 << 182 */ + { { 0xc48bc829ff7543c0L,0xc0bda14c4d72bfaaL,0x2f470ec703be0af1L, + 0xc70f1e8e92d37eb4L,0x08abdd98418f410fL,0xe38c74ab35386176L }, + { 0x9c07cfdd8c00426cL,0xba74c310a998f1adL,0x76b45140b7d2dda8L, + 0xa52b5e584948330eL,0x9b7332348d8efb26L,0x5d1763735d19a312L } }, + /* 41 << 182 */ + { { 0x46950a441d38ade1L,0x377fdf593058c7a2L,0x5e2fa1681aa129f6L, + 0x2eae63dbc5fe1745L,0x9616fee275545475L,0x4073a79c8627b2cbL }, + { 0xf1ec69ea9a5198e4L,0xe9a906aebd2821d5L,0x193a9387bc22625bL, + 0xca468d717b6c67ccL,0xb4d11cb360f17a73L,0xcd801a0e3df1cabbL } }, + /* 42 << 182 */ + { { 0x1b80b9c386cf5a12L,0xa5bcd3a016349cfdL,0xcee36e8f00d1edb5L, + 0x9566e10a5b7bf29bL,0xd0db98cfd4ff0a0cL,0xb516605e7fe427d0L }, + { 0x099066c18e614e25L,0x63537fbbabe78647L,0x5601a8b420117e1aL, + 0xfd125e2f06df05acL,0xa7fcbd420948daeaL,0x55ad4ee28ff03220L } }, + /* 43 << 182 */ + { { 0x18d71671da2c6332L,0xb38bf94f98ee4e23L,0x9b90bf72ecc579e8L, + 0x5af93aab1bf6b8c5L,0xdad6e7909342613eL,0x5a1d49dc710ad0ccL }, + { 0x2013ed8801468036L,0xb8bd31cf2f0f6f9fL,0xf025eb2aaac961a6L, + 0x1e201f659e1adb43L,0x2755f3aeac7e5132L,0x72d8e1d0f5205d31L } }, + /* 44 << 182 */ + { { 0x80bba9170319fec4L,0x4ba44600aaef6debL,0x83285b613594f325L, + 0x8879183753b5765aL,0x651b4c6adaf1b02dL,0xccc17578825f609aL }, + { 0x0b4076b39fddc6ffL,0x286e2daddf2fa874L,0x46c45233c413b648L, + 0x4fa46969b7cfe0abL,0x835786f3e04f5e5bL,0x526292a90ce3f707L } }, + /* 45 << 182 */ + { { 0x9928e9eb83f17723L,0xc38d5de26c2306aaL,0x3dd3f371558b3989L, + 0xfa4b194877154d39L,0x89f437e4b89f5448L,0xd5531444a6437c9bL }, + { 0x65a6874092537cd4L,0x5f6d72281246fb09L,0x0db0b3be58539e37L, + 0x1f0dd43df50f4143L,0x1aa12daec215aab3L,0xf82820fb7fe7b225L } }, + /* 46 << 182 */ + { { 0x32c6bf5e56cb520dL,0x74dc46c41569fa1aL,0xcbee46391ba52541L, + 0x5e2f511a50ec4575L,0x90165e35032b6f53L,0x2b8f1f8a5544c780L }, + { 0x95baef65c6b50147L,0x4e9db41946b7fde6L,0xe2463226f7afa6feL, + 0x4d70932235409eb4L,0x8faad8937c20aa0aL,0xc8c95a85abc1ab65L } }, + /* 47 << 182 */ + { { 0xd5f54ce676d1f996L,0x55957500e595a0eaL,0x9b62e1fd92c72af4L, + 0xb4803bc3069bf052L,0xb7cdf59c686ebd16L,0x2d1fa780655ac6d2L }, + { 0x6c306d3edca404f5L,0x24e9d7a9a7b5fa9aL,0xe4c080ddc533c701L, + 0x71d16b63425e29e3L,0x81c00db32d993e49L,0xb59f87f577902ecaL } }, + /* 48 << 182 */ + { { 0x43b58def987cf64aL,0xc95b16c63d4bcd4eL,0x5d1b1373bcd9b923L, + 0xaf560542522e052bL,0xc2ff8f7583800352L,0x11723aa17fe2a4eaL }, + { 0x28de7668e94bd9bdL,0x0ce80e0f874018a5L,0x0fe3755d8d43e726L, + 0xa78296acf9b075c5L,0x76d58d9882207423L,0x5c5bc6971db99205L } }, + /* 49 << 182 */ + { { 0x9cbecc969e2aea70L,0x1a3fd38d7e4f2a84L,0xdc35e3c84b95e560L, + 0xd5e912a5aa21d2e2L,0x037866628d8cd601L,0x4b726855f2bb35e6L }, + { 0xa45a827a0d763ea2L,0x17d6e5ea057bceecL,0xdab2381d09a2a2a0L, + 0xf1880617e9aa76dbL,0xb86444dbb184c5ecL,0x23a0e4b767da7c23L } }, + /* 50 << 182 */ + { { 0x2d94a6f030df736bL,0xd1ce20050b3be2bdL,0x201352b55e288cc1L, + 0xdbd3dc57779644a7L,0x9f258b16d191db2bL,0xd83c827fd1c123efL }, + { 0x74c5126e17f04f0aL,0x06008f14966e620fL,0xa4406ba80aaa9e37L, + 0x27323f797faf87eeL,0x43380a672b1206a1L,0xab1ed1cfaf15ebedL } }, + /* 51 << 182 */ + { { 0xa3d2bad9bb22cc74L,0xfe6591a80e2b9221L,0x8c94c974d3cb4eefL, + 0x772694266beb6451L,0x2942737a010986e4L,0x920c9dda59c1ace3L }, + { 0xd31af336da61e1d3L,0x973997a118021018L,0x50a6c8425710575dL, + 0xd61d47c9ade9d8a0L,0x90abe8f8a85f458fL,0x23cc28a3ac4d474bL } }, + /* 52 << 182 */ + { { 0x283d5bb63e052e69L,0x149ac3d01bd300e4L,0xb4c7b96ce0582ccaL, + 0x66102883428cb7d7L,0xd3eea16b500958dfL,0xe1b6a74f74674893L }, + { 0xe3b284be3fb0522bL,0x74b0fe2dea983a60L,0xd4328e5c81e465d8L, + 0xecb534c7403173b3L,0x1721e22774144d34L,0xb7273c6aa88a5141L } }, + /* 53 << 182 */ + { { 0x0ea24ac64018877dL,0x265cbfe42acf249aL,0x811c17e61837d63aL, + 0xff453f5d6b3adf1aL,0x7add0621a3031529L,0x62105dc838af1d27L }, + { 0x2cd31a899b56ec62L,0x5f524be5ede7bbceL,0xc485b2ff66a044f5L, + 0xae28f5dc87a7b274L,0xd41989a93415b6c5L,0x3051ca44c9c43ad1L } }, + /* 54 << 182 */ + { { 0xc22046bcfb50bf2eL,0xee22fb7b78f7c548L,0x5c41c6bc2b5b4563L, + 0x56da674a8bf9259cL,0x3732f77433d8d4c7L,0xa90bf0472741046aL }, + { 0x5ee7f4396288c2e0L,0xa7a1fec99ae621c6L,0x523c0569b76e955cL, + 0xda0c2b378d1e8601L,0x9010bc349559b56dL,0x8d2fab0917b8d9b8L } }, + /* 55 << 182 */ + { { 0xb2caf938281b021cL,0xc61f3abf1404b0abL,0x24203e1cea26d902L, + 0xc84f07e10d34906fL,0x8ba3d589f0cf7520L,0x86b54f6d9a2a90caL }, + { 0x9f87234f3d77a667L,0x328941966e3fa8d0L,0x0921b4a6e994d49aL, + 0xe77e9f8b8b3495cbL,0x9e5b74798da1fe56L,0xcbc09ce7b070591eL } }, + /* 56 << 182 */ + { { 0x583ee7dfe3b7e746L,0x0b6659e4a4fab3a8L,0x34ee02751946db5dL, + 0x5ae3c0ba1a12eecaL,0x36756ed44ccb83e7L,0x973b0861a80eaf3aL }, + { 0x969e38f46982ca90L,0x9a9bcd10018d01fcL,0xb540e9533272476aL, + 0xcf91dd0a75ab7002L,0x2c7d363f39ceb983L,0x4369c221974747c7L } }, + /* 57 << 182 */ + { { 0x32c5b289642be172L,0xe5cc452e697e6a30L,0x344935e10aa6841fL, + 0x9eb2dc4faad907a7L,0xaf77d029e121d0c0L,0x2bcddeb08bb073b8L }, + { 0x3584dee5e40653fdL,0xe853b6337605f214L,0x4723f0add4bab900L, + 0x16dddd27fbf91322L,0x1f96d7e610c525b2L,0xdfba535200c998abL } }, + /* 58 << 182 */ + { { 0x701e8ab819df9ed7L,0x1a6d74c13e2159d1L,0xe82127e0fc61a470L, + 0xaa2e5f33dd15316fL,0x92b6ea927c42c081L,0xfd470a298522aef4L }, + { 0x0c54a067e5ccf152L,0x60c113eda1a079b5L,0xdd501a8389d6e6b9L, + 0x3dbf20d219792456L,0x633cd2b710bf70edL,0xace5327a0aa8e5e8L } }, + /* 59 << 182 */ + { { 0xed79a2de3b2a8a4aL,0x02851125cbf095c4L,0x6817ecd1880fd3bbL, + 0x72acb6ff066adfe0L,0x04fd696d66ce8257L,0xb644f098dc81958fL }, + { 0xcab55d1525218005L,0x1184b0a64de70465L,0x6248e1157aa96b53L, + 0xe30958630516ac32L,0x19f80cc0d07084ceL,0xfdf7ca2efde86c28L } }, + /* 60 << 182 */ + { { 0x9a8857568bc1783eL,0xb373e5a0a7cf2ee3L,0xdeb162fde46cc503L, + 0xd5d334601074ef35L,0x0030f98eea159a90L,0xc5ffbdde64e50d98L }, + { 0x85a6486a48195b26L,0xdbf56597b1b9f2d6L,0x5df2352ab8613aebL, + 0xc425807ebd0189a9L,0xcf5a34d4fa1f4f7bL,0x233e26c7628fd2ceL } }, + /* 61 << 182 */ + { { 0x6c4dd28313a1e482L,0x24bfc23bf803f1ceL,0xb8e795b2f426832fL, + 0x636d2d63b13fcb5fL,0x2dbca0b214a508ecL,0x1948c957c1ff2b70L }, + { 0xc9d7cd4ae3135c7aL,0x1bf41de75d7cfe18L,0xfff9428f2f6cd5fbL, + 0xa25d3e8294d640edL,0xecdea1583e4fec66L,0xff3b2b1555530798L } }, + /* 62 << 182 */ + { { 0x483565313178cbc6L,0x085a31143f3a1ff0L,0xee2a58b11dc7054eL, + 0xa9ce7c113287d5e6L,0xd283d22c8fa263a1L,0x9160bb8be77ff147L }, + { 0x21dabddf918caf34L,0x6921e987ad1a9f13L,0x47e45c7d3ba0ad41L, + 0xeaac63192bd18585L,0xb88881060818034aL,0x2d8e9c1b60be0a45L } }, + /* 63 << 182 */ + { { 0xad3e46af32f4625aL,0x5c2f95dd88371d5fL,0xfc7a9adef2415ac6L, + 0x77a23c424ad85440L,0xce7c63712f4dd730L,0xd65bdc45a5c9f380L }, + { 0x763d3990cf11ee6eL,0x7b2a927a9ffc522aL,0x65ccf351deead5c5L, + 0xef1fa99cce4d076bL,0xdb6f5cca6708ba8fL,0x361525a0f3bac7ffL } }, + /* 64 << 182 */ + { { 0xbfc40c30f893a2caL,0xdf96980e0623bad1L,0x4fd7b54dc027511cL, + 0xf4799284cf3484ceL,0x655ab811069beea5L,0x52588bc87392e280L }, + { 0x522e7b404f0c17cbL,0xc0d88acac705e9b2L,0x9cf1b95877f3913fL, + 0x3e06b9267dd52514L,0x992e920e2908cbcaL,0x13baced26d6ed529L } }, + /* 0 << 189 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 189 */ + { { 0x8a46c911bfc6c637L,0x8dc3d699e4fa4fe6L,0xd4ba64f15cf8e4c9L, + 0x01b3908a01cb3488L,0x69b1fa5d38bd7dedL,0x92ad483818b2eae1L }, + { 0x619324beb33955b6L,0xc7f373355c8a6df7L,0xa397f42e925b3f69L, + 0x32169a495f7e4d11L,0xc0fa9a548d0d9f01L,0xf52a1f2289d8f2e5L } }, + /* 2 << 189 */ + { { 0x9c0d5231ba8e0a52L,0x94d0509e93e465d7L,0x67df90dd98515454L, + 0x223e8b9c8dbfb46aL,0xf39529a36d757ce3L,0xffec9175b4648296L }, + { 0x330749e8f78aae7bL,0x19e5549645f93cc3L,0x8c320b3494083aa8L, + 0x1161f5a321e321c6L,0x0980deedde3e7892L,0x605aa9196ad76cccL } }, + /* 3 << 189 */ + { { 0x71191262062312e3L,0x84c82a94691f46faL,0xad4b344bdda57f44L, + 0x674b758ac4f0cfd2L,0x3bc058a077543efdL,0x3d7c765756618d06L }, + { 0x95107c744dba9e44L,0xe59c3180cfdf1923L,0x5dbeaf35e3f1d63cL, + 0x012029c643ab8726L,0x4f588a4ea256c6fdL,0x14a01b7a3e5d2e30L } }, + /* 4 << 189 */ + { { 0x73fa3508180660f7L,0x4cae013e2d24936fL,0xf64a549f58493d98L, + 0xd9ceae0adc79f602L,0x6569e37bd1512b84L,0x11e4c022151c9151L }, + { 0x075678c2b55c5813L,0xb26cdb5809d3cb16L,0x6334dca3a57fb969L, + 0x0ed90820223dc3ceL,0x74f9c3aebd11e277L,0xaeefed3679c0b8e2L } }, + /* 5 << 189 */ + { { 0x22195e48e57ac6a0L,0xba77c58214bd1913L,0x265f96b4323349b5L, + 0xc183196ea124d497L,0x99f1f78d2466d82eL,0x185a18bfc6263afcL }, + { 0x29a3d5b686cf8908L,0x81f3bc00f680511dL,0x5f6ffc81661d015aL, + 0x31c2ff64cd5eb082L,0xc3c37ad672776042L,0x49438769d9c6ac75L } }, + /* 6 << 189 */ + { { 0x0e2fc74c2a24c385L,0x836a474034679278L,0x25518f16817e2c41L, + 0x8b573a8eb4b7d3c1L,0x012797f94ab56adfL,0x9e0e56d0fa2ab690L }, + { 0x009ba1ee1c9f6f08L,0x8ebf4aac2f412e9eL,0xb143122a1cfb4e02L, + 0x988cf0eccbf2b783L,0x44a7ed9657f5be97L,0xbdcad87251804147L } }, + /* 7 << 189 */ + { { 0x969fcd982f60d1a0L,0xf0f4c9b2ef06b3ebL,0x8c6438cb49ec8f92L, + 0x746107773f1653daL,0xf7cbc899b574576aL,0x758de9008494795cL }, + { 0x73045065ab22cf9fL,0x9893653c9ff13e98L,0x6e8860264a58d64dL, + 0x387d6cc34e3bf554L,0x82a49da4a42b0008L,0xb28bd9b71b0b1c47L } }, + /* 8 << 189 */ + { { 0x378205de2f9fbe67L,0xc4afcb837f728e44L,0xdbcec06c682e00f1L, + 0xf2a145c3114d5423L,0xa01d98747a52463eL,0xfc0935b17d717b0aL }, + { 0x9653bc4fd4d01f95L,0x9aa83ea89560ad34L,0xf77943dcaf8e3f3fL, + 0x70774a10e86fe16eL,0x6b62e6f1bf9ffdcfL,0x8a72f39e588745c9L } }, + /* 9 << 189 */ + { { 0x97e6400574103b65L,0xdad518d6db50ac66L,0xaf96065961077d1bL, + 0x1335de0a5baab1f5L,0xd404db749e444a1cL,0xd3124c5027d5fe2fL }, + { 0x1f20c68a0bd49e9dL,0x44405e6aad6a1654L,0x287d565193c362a9L, + 0x301ec6a2e76661bfL,0x4900f9b54c6f9927L,0xca3dbc3464bf3909L } }, + /* 10 << 189 */ + { { 0xa96955b9b1bafbc4L,0x8dcb55a7646ece39L,0x2b62784feb00e541L, + 0x462f9d7d2693249bL,0x8b264697794c189dL,0xded6ff5563354e69L }, + { 0x7c8ea441eed1089fL,0xe355f75c1462f461L,0x87b691f61210fd5bL, + 0x7291bffb6983cb27L,0x9ed83afc92800095L,0x307a3dc81f24d923L } }, + /* 11 << 189 */ + { { 0x9f79814a45faaa0cL,0xc64a7ac93bb1b07eL,0xaad6ff897f2ad506L, + 0x43da948300b83699L,0x6a702b8d6617956dL,0xfcb1035a7981052bL }, + { 0x094acd48cb230926L,0x3c3249d05da96800L,0x934088079d7208c8L, + 0xe4f04014d738a48dL,0x49bc5f0bf18b06c2L,0xf854285f596b9befL } }, + /* 12 << 189 */ + { { 0x7cec60ead7804b2fL,0x0064464345c11441L,0x3c6de88b769cd685L, + 0x34709186c7f01232L,0xd9eef41eedd2bd0dL,0x3bafcccde427faa9L }, + { 0x33e5350ec07e701aL,0x9cb2eb47a87c1fd1L,0x9fa9a7790d5f5b28L, + 0xa2e7076b07ea2e53L,0x72f4da325c169cf4L,0xb7f192947e751588L } }, + /* 13 << 189 */ + { { 0x1a3b217d2f6d700dL,0xcbbe9349ed335d55L,0x428adbfb53ff169aL, + 0xbd74385214793b47L,0x2224e2569d9460a2L,0x8408600809982ac0L }, + { 0xae6c6f9934447242L,0x63c78b2b9b51fb67L,0x381c948a389593d4L, + 0xf4cdd09f6e79ee72L,0xc658428ba185a0b6L,0xcd7562a786fe4c6fL } }, + /* 14 << 189 */ + { { 0x47eb133532dd7a30L,0x9d058169a9db654dL,0x375c59df6e7a2b1aL, + 0x55d37c677a35f29fL,0xc78a3678493c4cdeL,0xe5f0e2d68d83e31bL }, + { 0xf7927002e9777bf9L,0xdd559324a5afdfc7L,0x077c6c48b81c08ccL, + 0xba1c98ccaa2ef694L,0x06c6c9544c02dd46L,0x211e50f37dd3145eL } }, + /* 15 << 189 */ + { { 0x7f985fa8a96aea53L,0x811f94dc480b38d4L,0x91fdd510f3d40c68L, + 0xc156312ccd763693L,0x24b544c3640057dbL,0xd7d5d4f5ad3b5a1bL }, + { 0x5e235a1e26cda8a4L,0x0cf7b7cd1d2c6f17L,0x17b1ccf0908d3107L, + 0xf32f2a06f555eb5cL,0x274f7c2cb3c278c6L,0xcf1eaf296af1b44dL } }, + /* 16 << 189 */ + { { 0x2a5f8ecf06616d0dL,0xca9b1cb8c7deb373L,0x9de31cedc59c4301L, + 0x1e0f40b10111d998L,0xd29d229f960d5b95L,0x10563249d1dabab8L }, + { 0x7b225cc9a05ecac9L,0xb02e689678f3b8a0L,0x009b52a1f5fb06b2L, + 0x8a575d3f842b9081L,0xfddb48afe9272512L,0xd39b8f1d0b452cb7L } }, + /* 17 << 189 */ + { { 0xb6efc7e167ba9cd3L,0x5a642c288e4f62a6L,0x214a63da364378edL, + 0x582c59944121c53cL,0x840277facc9a728fL,0xc6db3529f8f72d39L }, + { 0x9c5cc2760aca9955L,0x8558a58db8b6dcd6L,0x709226acf0701f24L, + 0x6ce95b21ed248b40L,0x32ea565b5487934aL,0xa75a688496f9ddd1L } }, + /* 18 << 189 */ + { { 0x0d6b9c7c67e09987L,0x261a564d0761ad52L,0xec4621749f60925bL, + 0x83ee0c1218529b03L,0x72972467fbcfff74L,0x37fc074c6abc4bfbL }, + { 0x8b6015bd54e65e89L,0xde8583eb991583cbL,0x379548e1b4d2c62aL, + 0x88024a9a9b24a5e5L,0x633aa869fc03abfcL,0xa27657b98fa35283L } }, + /* 19 << 189 */ + { { 0xb340993c5727e344L,0x2379f51d4f3295d5L,0xa5de3efce2929734L, + 0x7d2e2c82d8717e3eL,0x8f24abb67180db1fL,0xa5060d648a4ed876L }, + { 0x8d39e3a2761110d6L,0x38d30c93a3bb5b66L,0x07774ac3c12fb741L, + 0x7d4ae5a55f4425beL,0xb9848a2afa704922L,0xed9ab68c4cd00812L } }, + /* 20 << 189 */ + { { 0xde9703b461d9e770L,0x02d4091def4653efL,0xefd229aa576eb5e1L, + 0xc0b0b243f77eb987L,0xb11309b2eefe8f71L,0xfeeacf2f68478044L }, + { 0x8dfd8e8643ac3dd7L,0xc0a24181b07f95c3L,0x551ca09624be161cL, + 0x6cb2c1d4b098cdc3L,0xbfc74e9be74f84f8L,0xe58e14d9067e3388L } }, + /* 21 << 189 */ + { { 0xda121aae0ef98506L,0x435f28c6328e636eL,0x64b2170a720d40a3L, + 0x3ddb0e61cd24a844L,0x111442478797c7adL,0x624e7f73d589dd37L }, + { 0x3e7e0ed0a8efdd25L,0x8de031f116509a5aL,0x1330cff5873488c2L, + 0xa80c60b3342ecf75L,0x9d3742c8e62550ceL,0x8ec9b229e46475f9L } }, + /* 22 << 189 */ + { { 0x9eca6f94f025baa6L,0xb2db0741bcf9c741L,0xf8e2aab590bb8f56L, + 0x4772903208762829L,0x067a0c5ae2a266c8L,0x22b104c771b7d7d0L }, + { 0x4a48cd6953e406dbL,0xb85e44d524f0070bL,0x6168262fe10133ffL, + 0xdfc02315e4874e8fL,0x20dba2d7ca317e3bL,0x441c56d2e1d2c0c3L } }, + /* 23 << 189 */ + { { 0x9ebd10d6c444a2fcL,0xda7683e3f18ac11aL,0xdd42ed990fe8e59fL, + 0x9c867debee068909L,0x32df043fccc77aa3L,0x377423ce4aaa45acL }, + { 0x960940524a90c535L,0x48bfe83347d1799cL,0xe8cd1a55ccabd174L, + 0x2ee0a276682145c3L,0x4249297e8d606c00L,0x22021ce2fd7af6d3L } }, + /* 24 << 189 */ + { { 0xae10069e808dc4b1L,0x64df30e18fb3ba73L,0xbbe4caf27ebaad0bL, + 0x5907bf373dd6119cL,0x0a723dff9dfceefeL,0x59bff4ddf7cffc7eL }, + { 0x7bc95fa26a6f43c2L,0x9001d1d53ca0e2b3L,0x316a7ecd27b3335bL, + 0xbf08e6727b8d7d49L,0x4b209f93c619058fL,0x4c0ca01e59d8f9eaL } }, + /* 25 << 189 */ + { { 0x3c1e7f45bad772b1L,0x20f6f1732544af67L,0x14f491f9a7d6544dL, + 0x1451cc8e6acea162L,0x20c8ffa5d234ab89L,0x4b59bce1f5cd1002L }, + { 0x99da4c0ee63027acL,0x6290cb963fc1f75eL,0x3a51774524c4d85cL, + 0x3bf9929c1fd144e7L,0x9bcb97467068294bL,0xcb0b3e5d2e61a022L } }, + /* 26 << 189 */ + { { 0x18c452c4cae69c3bL,0xf45690acef0f00faL,0x3b363aa04f66a5ccL, + 0x9dd41c0a47718c52L,0xfa219d7e7e5cd370L,0x5d384db7b2196dfbL }, + { 0x5e14749b90b4d46bL,0x55796656d9db9481L,0x3bf13d0ac8cf353eL, + 0xb89a28a6a95c485aL,0x568fa3d05da29783L,0x4aa008eed182b1a4L } }, + /* 27 << 189 */ + { { 0x4f38667a179639e1L,0xca492d50ba7c7a16L,0x191e4a3478fe9dcdL, + 0xa3cddb2f03fc70b8L,0x57d90a90a751ec9fL,0xcf88357457a50cd6L }, + { 0x69abd86d7cc58687L,0xc73a00408466bc6cL,0xfbb99c755c495208L, + 0xdd5f1ab9c13347b8L,0x9ae6fb92060b93efL,0xd6bb56a3588e5369L } }, + /* 28 << 189 */ + { { 0xf7e1ed3bb09fa8f3L,0xbb4fe6f71da5be9eL,0xcbab0e01f4d1ba21L, + 0xb732741076a5f326L,0xd94d2349206092afL,0x739f3cd0728e0e4dL }, + { 0x568644aaf81fd823L,0x510cff6b6110e2f6L,0xef4cf1ac566c3598L, + 0x2c26f17162aae69bL,0x1e4360468964a2a5L,0x83c0bbf63e472c50L } }, + /* 29 << 189 */ + { { 0xc198c07064b2955aL,0xc32d41e1d8d43284L,0xfb6f0e2c9f4fc13eL, + 0xf4d5b60b41c61889L,0x5c79f500beb36946L,0x328b22408ca4beabL }, + { 0x64058e916697617eL,0x6bdf7409f43f7390L,0xf2afd208f5bd8512L, + 0xc0000aa0bd1ad6d6L,0x38b8e03bd9f6c1c2L,0x0a34680d665a2d06L } }, + /* 30 << 189 */ + { { 0x79c04804aabd965aL,0x9581aab443d0b660L,0x59bff0035ba71d23L, + 0x212ecd58b6a0cd80L,0x29bdcd33bf1ea5d6L,0x59fd2ff477a002e1L }, + { 0x3c9d21308d9cd247L,0x790e9dbcb1786da3L,0x967ee5e714464d04L, + 0xd6f7ebbd2b5373afL,0x1c0b22d539768d40L,0xdfb54983913f6cc3L } }, + /* 31 << 189 */ + { { 0x5c9808b78a42e002L,0x5cdb2b070f732854L,0xdc92b1676d6d4579L, + 0x789dbb8ebcc22c54L,0xd76b2d40716eb28fL,0x5cbaadea004affd8L }, + { 0x5d4d84dd08fcfe12L,0xd0f1d7ee20d4b893L,0xc98d77dfbbb90db6L, + 0xbce9a5a2b1e29a22L,0x71a6835d0b54e100L,0x0199594a55b1ac68L } }, + /* 32 << 189 */ + { { 0x167ec88a51b3f1ceL,0x19756ee0420024c8L,0x10f2e2443877e634L, + 0x6321bf2603462cb3L,0x1dbd10ee9d3afceeL,0x0726f5f22ca17dcdL }, + { 0x094652660bacf018L,0xc92a9f2de1feb969L,0x0043b0f95e1c5912L, + 0xa09b94d1757d3a63L,0x533956529fdef1e0L,0x9826886cd4fedd41L } }, + /* 33 << 189 */ + { { 0xd22bcbee51964ceeL,0x3ed80af3b0eea46eL,0x263cfa026b854aafL, + 0xfa4ad481b9ca3b51L,0xf8c569a0b4451297L,0xeafb78f8f48059a3L }, + { 0x86a9e3c037093acbL,0xcfb3bb63275ef52eL,0xc4672d3c7c924f03L, + 0xa87350871691be3bL,0xf124f3a52be289b7L,0xf45052dc6b80b6c1L } }, + /* 34 << 189 */ + { { 0x79c99f99a010db6dL,0xe83088a74ee93fc2L,0x76e8376d836b1a7dL, + 0x8cab091c4e24e127L,0x5c98a00f7283cd21L,0x1beaf4a084997647L }, + { 0x2cfb55b8d934088dL,0xca24052cee724d5fL,0x5d6e9db5bba84289L, + 0x133414b26fb26d72L,0x3e844eb9cb12a503L,0x5eac12dab53d6496L } }, + /* 35 << 189 */ + { { 0x79a098812cc6698bL,0x6d44e7577f383e02L,0x1969f93785b5f732L, + 0x3061f62792acecccL,0xa9428d60cc2a4752L,0x69a472af2cf58626L }, + { 0x63fde53cabd347d7L,0x138b5b6a1aed4fd3L,0xd93fce1f2bd48519L, + 0x957fe302e49cc436L,0x9b51657a2e21ad5fL,0x3b5c4cb6acbd3af6L } }, + /* 36 << 189 */ + { { 0xdcfa78b096dda000L,0x5b60dfe5be2303bdL,0x7a6bbd34c7c6ad6fL, + 0xd45c9cb57012b97dL,0x9a049e36812e1662L,0x723bc0b66a5483aeL }, + { 0x7fc03b6ad1c82e81L,0x02ddd6d2b23f6818L,0xe8914b2d30dae39aL, + 0xf4f0ae392f692056L,0x198a31bd45f1390eL,0x917ce4f4f542565eL } }, + /* 37 << 189 */ + { { 0xde39a4e6ca447864L,0x95a028f9f0b131ccL,0xba77ac314a39c4f7L, + 0x0c24d09614857939L,0xdeea56edfbfaa0fbL,0x79aa342f4c920bf1L }, + { 0x50228f48c7e9dc62L,0x0fd9d1dee0f0fba3L,0x3fc03993cd703f6bL, + 0x229a3bf4c5ff39fcL,0xa7456aa484f9cb20L,0xb01bb5a7d12fd7d9L } }, + /* 38 << 189 */ + { { 0xfb390be4539519d7L,0xbaa98a2a6ad44d22L,0xafd19a75ef89de1fL, + 0x1afaef2971e27781L,0x18b297d79887739fL,0x8fcff6048e6da42eL }, + { 0x17bfc1717e861a36L,0x1467800537a8843bL,0x2bc47afdeb16065dL, + 0xcc038e2fbab7b4fdL,0x9d8fc42a3eb9be7cL,0xfc2f0b295928da63L } }, + /* 39 << 189 */ + { { 0xa4e33ca261c14fbdL,0xebafe73fc0a87f99L,0x22fdf1d1f5abf7f4L, + 0xfc1da26549a6b956L,0xfd8c48e5be25dd72L,0x9fd6520ad31a25aaL }, + { 0xe0167d4ffd14dbbaL,0x8838d2ba7370153cL,0xe5f7d69b133fdda1L, + 0x31acbf8de1749b60L,0xc14ec9e2107558dbL,0xb06d0252b99553acL } }, + /* 40 << 189 */ + { { 0x34590975ed424438L,0x7c03ce744d11a200L,0xcc939a286ec406eeL, + 0x8d214276fee5454dL,0x66a0e1a56b257f70L,0x93761a8a006fb85eL }, + { 0xc44f9df2aa70b65aL,0x1dac524f91d9e2e8L,0x5894a8224fca1a81L, + 0x8586e418f3ed85bfL,0xd494dfb202899b5bL,0x7ea9f222ecb8e371L } }, + /* 41 << 189 */ + { { 0xd93ee716b0958516L,0xa91f39db3eb86888L,0xb472c1e2ac92105eL, + 0x4d88a307429ca094L,0xd3fd88027a8e87e1L,0x40c4cd50126a2cf2L }, + { 0x046ce3bf11cf2046L,0x412678ee05691999L,0xea0c78168d3a2921L, + 0xd24ae89924f3c66eL,0x2c4457f00bd144e9L,0x82005b4fd7a52270L } }, + /* 42 << 189 */ + { { 0xf1b3ec32924340e0L,0xe5430ea3b33a05abL,0xbf43b031807629b7L, + 0x53c9407d57014039L,0x6e67b52f2f195ce2L,0xc8cc645f1e48d8c1L }, + { 0xf2234275c08f2122L,0x9cfe3c74c2f233e0L,0x235e6b349c4e0af9L, + 0xb4e8ef5770de39d8L,0xba573a727f73d0a9L,0xe12c506a18587ed2L } }, + /* 43 << 189 */ + { { 0x6b9669c59cf3e4f6L,0xa472d5dbff677559L,0xde845b0c877e5590L, + 0x9f7ef5802d0e2350L,0x87ea99d4e78c1096L,0x213243e9abb68028L }, + { 0x0172c81595e71abaL,0xc2592a762ca34c65L,0x50749aee9dc286dcL, + 0xe37d10884055de3eL,0x3e5a93bb90d652baL,0x0cbb7a08c32aa3e6L } }, + /* 44 << 189 */ + { { 0xe0bf3d8a026c43cfL,0x091956cfeb702508L,0xfcd486c9a6b3203aL, + 0x94a6d52f365460ceL,0xefeb5400563bec77L,0xbe6baa9619b2659cL }, + { 0x116f71c34bf21a00L,0x83d1c99a86d21871L,0xff1ba96aca0bd547L, + 0x5eb0acf741b94afbL,0x1be5d66fb1aaad14L,0xb8ececc5e6cd6d4fL } }, + /* 45 << 189 */ + { { 0x65f6e29dec7d4de8L,0x082fa0560e938c79L,0x4cda3fc925a02f04L, + 0x77dbcf0d3bac5cadL,0x625f9bd859145bdbL,0x98b7fd64553a11f3L }, + { 0x621bfbe387dd8a45L,0x6519421d1c35176bL,0x89eabac6d5ead4c7L, + 0x45c68bfe54acfbd5L,0x87cd244a84f30b68L,0x83b5f6b27b39275cL } }, + /* 46 << 189 */ + { { 0xd43b1d3c0ed0ade8L,0xd60b1ae7640e7d37L,0x965489e6f88e06e5L, + 0x35398ac89653417dL,0xed1e89ac02cfcfc5L,0xd127f68dbb6f2bfeL }, + { 0xa569c59fe22bb079L,0x7933f14e4ca8e9deL,0x68b4964a30033c3eL, + 0xab438cf88f069045L,0xa64f3a1516163059L,0xf40499c14576fe42L } }, + /* 47 << 189 */ + { { 0x361c28da052567f7L,0x8a2c6aafe0db84b6L,0xa79eb10cabbc87d3L, + 0xeaf7bfff4141b3acL,0x90bba4a953aacaf8L,0xda577661c35f9564L }, + { 0xb2550d0dd4487a5fL,0x69d43c5199638269L,0x6d16973f7a1f8ac6L, + 0x3dfb2253c71e4a4aL,0xafd836aefa36168cL,0xba72fd1faae6dacdL } }, + /* 48 << 189 */ + { { 0x690c0cfeb449d1e2L,0x4a5e150b1b8e1577L,0x22508042204d98a6L, + 0xc87a97f5bad2eb08L,0xd307c59ed25823eeL,0x6ed083580df8b3f6L }, + { 0x280ae344314e7016L,0x6a55be876ef4e889L,0xea930e5a24d04e38L, + 0x0269d9a7309830fcL,0x41dc8f0ae4afeebcL,0xfd1bc660f14ee02dL } }, + /* 49 << 189 */ + { { 0xf81cc943631da366L,0x2e821eb85ab1a2caL,0x339e9e4765433883L, + 0x3dc14370e1f60c71L,0xbd6c79bebc25b506L,0x2bd3ad51a8a639f0L }, + { 0x7c168f13c700a293L,0x64fef4fc28b4ce88L,0x3ccdc3080c329c6aL, + 0xbfd78932b76a9452L,0xf0c123fbc684f4b5L,0x8bfad06432305ed6L } }, + /* 50 << 189 */ + { { 0x208a668feea1a9ddL,0x8af75caeab903f09L,0x356208b449265292L, + 0x57b24ebe53faced4L,0x9c8aaa7303694920L,0x1c06ef5ad2f90179L }, + { 0x794ead99df92de87L,0xad900c4e7a73fe9aL,0xdb66b9ae715d9f66L, + 0xd19dc46db1bc2950L,0xb0a5af5c24c82c0aL,0x7d83f950371d0ec7L } }, + /* 51 << 189 */ + { { 0x716071e3abd37656L,0xaa22858be6cab564L,0x6793a66f5aec00ccL, + 0xe2ea5401e025da6dL,0x3998ea5d2eb0059cL,0x4ff6f442e39abb77L }, + { 0x703eabdabdb6e0f9L,0xa33e6deb38522433L,0xe23c13f6ca83c2acL, + 0xcfb8e57c0cac836fL,0xd0f84bde7692714cL,0xb4fc3b01f3f41d29L } }, + /* 52 << 189 */ + { { 0x67842ab4d8f358a5L,0x70cab57540e2fb69L,0xdebc3046e5c458e4L, + 0xc3574cf47eb004d5L,0xbac261a1c86f20f9L,0xc1bcb661deccf7fcL }, + { 0x5b3b96dec5574e9dL,0x07b878b3e151fb0fL,0x2f2d126cd38bd5f2L, + 0x06c951e8319597c9L,0x5529be4424ed0027L,0x82dcacc2ba8d7acbL } }, + /* 53 << 189 */ + { { 0xc37eef0149311e82L,0x3d07aaad401d010cL,0x934e039e53417831L, + 0x70775653da895ec3L,0x206b80af625cbe49L,0x9e2a4ee1e53ccb36L }, + { 0xebeace45c8ca6ff7L,0xadb19bd9925302deL,0x951bfcc497dee154L, + 0xd09882da79b60e1fL,0xb1e9cf0cda5f2516L,0xc2b697295e4def97L } }, + /* 54 << 189 */ + { { 0x74ce542d04f860e6L,0xdc8adf8fa3c48075L,0xe19852232063f76fL, + 0xf651c9fd5cd9ff61L,0xd4cbea69bab39ea0L,0xb6d4749b28fe3443L }, + { 0xaa7747ec65e960ebL,0x1a1b7b65e132a213L,0xfa52901f402a50d4L, + 0x3e4d2da68d43700fL,0xbfc7322937d45181L,0x68a812f9008bb845L } }, + /* 55 << 189 */ + { { 0x226d4d233e4cbf5dL,0x36359f52576243e8L,0x032af38a39a1999eL, + 0x9b59120a687eb228L,0x85c56b78e68e1498L,0xa7a14bd4849d03d1L }, + { 0x9e7177b345c4c3f1L,0xad7e4975183bd846L,0x42418d9a42f69dc2L, + 0x218e8f8e4f52cac6L,0xafafa7649f1f3214L,0x32f6f72b747f7592L } }, + /* 56 << 189 */ + { { 0xefca7f7ba6c53c1bL,0xcb4bb33c524457a0L,0xc9eab87fe57d08dfL, + 0x48c01c2a7d9a1967L,0x11c97ed97dc27492L,0xd8c644861cf1f639L }, + { 0x541f8c0d8156576cL,0xdf5c8dff2384e299L,0x9806935ba6be190dL, + 0xec6c5de764494b4eL,0xf04e2d4cb83c00b6L,0x379af438c0b84f15L } }, + /* 57 << 189 */ + { { 0x64e6289d92bbc1f8L,0xe88b78c5a0620121L,0xd01bac79a0fbc373L, + 0xa2e7986af098f07cL,0xfcac4dbcc5911218L,0x2e2bf56db337ed26L }, + { 0x878d9819e89a73c6L,0xa7df4f5768df46d2L,0x74bf7e2f4b3c9568L, + 0x2f2b187aebcce535L,0x544f18139a4c2be3L,0x3a5fe300a5938f0eL } }, + /* 58 << 189 */ + { { 0x901a14cd70aa91aaL,0xf0b6e1ec7f0b0a70L,0x6fd1ee0156a8bf9cL, + 0xe7e53c6693fbdadbL,0x18ebae68e17de706L,0xf4107457ebecf636L }, + { 0x77a85ea4a9f6c696L,0x3ea193e17dd9e3adL,0x9497e0a9f151c8abL, + 0xcc9237497a1dbf14L,0x2e36740e8f9be59fL,0x1b1c7d7c4a249e51L } }, + /* 59 << 189 */ + { { 0x7a45af2242cdcc53L,0x3061d91b8682832dL,0x85e080f6c375030fL, + 0x3ea6dcd1418440c7L,0xe0559870d14b6537L,0x36619215d178b45eL }, + { 0x48a4b452dcb85a34L,0x79cf4529bd5504bdL,0x506215e9e9c34c8eL, + 0x961f74b6dbd00e2fL,0x473d1397cbc84ddbL,0x6c64f870a8d67cb5L } }, + /* 60 << 189 */ + { { 0x519a6edb91a9b99eL,0xc0ea29e0f19221eeL,0xde83e0f77dc193b2L, + 0xa7b33b6044be16f6L,0x7edcb49406c8e8d7L,0x9f9dbb86392c0ef6L }, + { 0x09aefe035726bd5eL,0x782d8350c4e80b7cL,0x14e41a49186b80e9L, + 0x9af13703499ef97fL,0x5752877f2cbcc336L,0xdd0f8583d2df624dL } }, + /* 61 << 189 */ + { { 0x1cd2be3f32f6b0a4L,0xfd5da4a90114bca5L,0xc322a6a198a39a66L, + 0xca411eeb10d64384L,0x7c5d3ed0c72d8b6eL,0xf20c76697481309fL }, + { 0xaa4e45dca155872dL,0x66e41d54b87c1e51L,0xbe2fe5e6a6bfe6b6L, + 0xf60ca33a08a4d3e7L,0x45c1ec8c7211b48cL,0xdf44d3b573b78f7bL } }, + /* 62 << 189 */ + { { 0x21eda67429a1e6acL,0x33118990422ce5aaL,0x236aa9ec27326810L, + 0xc42dff9e3be7b318L,0xbe4601281690755fL,0xa395509d8c1c60c6L }, + { 0xa36de79d05b991d2L,0x55f516a3632882d4L,0x4c8c5a4296d1d493L, + 0x56199648533cda6dL,0xf9c6897a603bbfeeL,0xae835160f9857cc4L } }, + /* 63 << 189 */ + { { 0x700bad58d6aa9618L,0x2ad7069c05d54c73L,0x7f3ff5992f6a8495L, + 0x39de751ee26e6720L,0x39126d97d4cecf54L,0x353e00e21523aca4L }, + { 0xee905af017a33178L,0xa30173d31daf2642L,0x24cbbcc728f9169dL, + 0x4e65bb13a7039e69L,0x004a11859121e44eL,0xd4efa5b91c1e60beL } }, + /* 64 << 189 */ + { { 0x2e75a26eec65b53eL,0xfeb630b270552fb3L,0x53dfd057ee7d8e4aL, + 0xb959110d8994f449L,0xb4a16596bb538367L,0xa70917bdef82f29cL }, + { 0x5a76430043bba6aeL,0xee207476cfbc194aL,0xc7eab23803a4184bL, + 0x60c67ef20f7fcd62L,0x41e05799dfa8a0c6L,0x5d7d05e604d352b0L } }, + /* 0 << 196 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 196 */ + { { 0xc97c01eb436b59f5L,0x1d15aca7ef1848abL,0xdba1ce807fa7d3c2L, + 0x69e6f96e81060874L,0x6e3e0df74d7eeeadL,0x8a3b5e85b0c87f3dL }, + { 0xc55ae3dbc8a23914L,0x5cdc2a92bf6d27d9L,0xa6008c591de7860aL, + 0x8202f8b66e546731L,0x652f2d07aa1e45d4L,0x146f214f6df5415aL } }, + /* 2 << 196 */ + { { 0x041c706cce5fb4d9L,0xddc78cb3b22a79a7L,0x7dc4cd27839e9d5aL, + 0xdfc9db83bf3c4c06L,0x85b8094138b7bd22L,0x1007dea2d0f4c2daL }, + { 0xd7b34006c633fba0L,0xa8880acf4476e55fL,0xa340b2c275236685L, + 0x5ddd05510113a85fL,0x7dfc7ab29cb32704L,0x9a334a33dabf22ffL } }, + /* 3 << 196 */ + { { 0x2fbce9bed7d1146bL,0xcec9e5d8b3980bd2L,0x48ea45939f4cbaf0L, + 0x56c540092574a3bdL,0x84a39630e792c39aL,0xe5c690f8eef81343L }, + { 0xf996760f17655bc9L,0x6009c2156c0c191cL,0xa0ca12e6966d7027L, + 0x92a6d5d52e6f7c63L,0x46809d269bd13eadL,0x3c11fa7967aac681L } }, + /* 4 << 196 */ + { { 0x3fc9b3cfabe2cc87L,0xfd8d64e3514e77feL,0x2003a58afe1ad535L, + 0xcec4be38cb39149fL,0x4d578c99bdedf470L,0xcd35d7a33a356519L }, + { 0x7a762f278b078d6bL,0x3b6891ed31ae2701L,0xdc0e817f270c508eL, + 0x5a7be2049fdb29c8L,0xfa1a0be3cb2711d3L,0x5865f55f3786a0c2L } }, + /* 5 << 196 */ + { { 0x1d0af6b52f641cffL,0xa932adeb3648c4a0L,0x67641951b1ea8fc4L, + 0xc0b90064b1fae482L,0x7012642f6623477bL,0x1cddc0245bf019ceL }, + { 0xca1f4675c2c32737L,0x11525a5e97d6b18cL,0x9c034ef2d3868de9L, + 0x0533d921044e0c18L,0xba6cf14ecb5e38c3L,0x438309f3509d7053L } }, + /* 6 << 196 */ + { { 0xe164268ec4ff9f0bL,0x6c8e9349e6c36e63L,0x734f979478ab17f3L, + 0x46d468de0179ed0eL,0x7e68f006dfa26867L,0xe4d4a85de3d0485dL }, + { 0x0913a1d7f84c0f8fL,0x4095c8c025a9c9cdL,0xeeb1a79e49eadd08L, + 0x433f5e417dd8f954L,0x70a6281430bb26d0L,0xad94d8f6ff5e8e29L } }, + /* 7 << 196 */ + { { 0x6a352b579e32c0a4L,0x5274a08277ec7a40L,0xee1f7c7a240e6dc5L, + 0x85d5be62d313b4a9L,0x1522c5d25c01a405L,0xcfa08aab960afd5aL }, + { 0xa3cb77f38e8a93dcL,0xaacb16766d1c98c7L,0x84090c7d3b93fa9dL, + 0xc77f1ee13c0383adL,0x461c93b776f7a220L,0x66d63a1d04ac0bfcL } }, + /* 8 << 196 */ + { { 0x3c7d6b644751207fL,0x65e1f96ae440c1a2L,0x8ed15d20aa0eaa1eL, + 0xe944ad2fc0eab490L,0x71525aa1f6d9f260L,0x5cd14c8816146ba3L }, + { 0xf940190814a41275L,0x3bb7ea742288618dL,0x6a4e1c37cab1060aL, + 0x357fe4d0c8cac96fL,0x97a8b8ab6a2466ecL,0xb6e83fdb9c01be70L } }, + /* 9 << 196 */ + { { 0xa55a7142cb09a69cL,0x0a39fa12896a9c24L,0xa7131a001f6c9c82L, + 0xdacbfae97509c912L,0x3793d4ef4232eb57L,0xb63d9fc0da02ac15L }, + { 0xf1ce48a09ab37492L,0xa388dbb5cf9ddedbL,0x7224ef47fd7b2aa4L, + 0xdfe18be82fd35ae0L,0x2286ae7b90a2e98dL,0xd06cfd71e0d3c2daL } }, + /* 10 << 196 */ + { { 0x7825df5c948663a4L,0xc8c093adeb4ec9ddL,0x677c51ebc1505989L, + 0x8c28421524041f43L,0x0f63f15ac9ef610bL,0xcb98841d257678c5L }, + { 0xc0560066c52c64acL,0xaf7417db954180e4L,0x935c08876fe1f0e7L, + 0x8fe556ba46d03a88L,0xec44271484a0c4a7L,0x431f8e8395be9544L } }, + /* 11 << 196 */ + { { 0xc1fc18cb3101ce6cL,0xff753902048e52fcL,0x768299554e58e21eL, + 0xac990acc32856d44L,0xaac4d5dc9f8a9da8L,0xca1740fdd4be9e8aL }, + { 0x59250846892d8bdaL,0x45f45cad19c97c71L,0xf29e2724e6ba5c87L, + 0xe441134473f6a778L,0x9f4f9027a0f278faL,0x11bb7ce02bdcef71L } }, + /* 12 << 196 */ + { { 0x0cc553bb9b3fd7ceL,0x2e0ff43ce103b562L,0x96c01f0328222a3fL, + 0x7dcc5593c10171c0L,0xc677366a4b3e5858L,0x872d4396bde4eebdL }, + { 0x5d0c5f3a7f83c0b6L,0xbf4274dcf7ba33d9L,0x1df6e4811a635f83L, + 0x24e2e8347d807292L,0x792203a8eee1e676L,0x20475f907ef4e8a4L } }, + /* 13 << 196 */ + { { 0x1b4db0579e37cd0dL,0x61b95bc9ebccdf79L,0x7d98d8537a57d7adL, + 0x58a3d639709b0194L,0x45fbd4417ce5bc31L,0x7684b71b5b3c856aL }, + { 0xb311f8f85bb6bd1aL,0xaeb8e44711eda59bL,0x1ad5b35fbf269cffL, + 0xc69651b4a0e2a640L,0x3713803bd83ad8b2L,0x613ca3af0e4b353cL } }, + /* 14 << 196 */ + { { 0x3ac59b1fff8cf495L,0x3f3726866b04c4dcL,0x2cdddf90da325f0cL, + 0x3ae79666444cabe5L,0x8222f6d6c7484b1fL,0x61fb08929ae328b9L }, + { 0x279aae392c575c0eL,0xac694019948508bfL,0x4931cc55b84056f1L, + 0x75927a688b50ad1dL,0x47ba72e945584371L,0xbea7e62ea79fe5e5L } }, + /* 15 << 196 */ + { { 0x990a6767faddc25dL,0xcd7650eb114eaf17L,0xf9d1d6409a44cda3L, + 0x70996b6871fb091aL,0x630ae9754ff80816L,0x59a9dc2f987b20e7L }, + { 0x9a39588ef65fbbc7L,0x71f4c8e598e7c78cL,0xad2f5a0138cd40acL, + 0x3c68fe575a837332L,0x7af44087155e6b4aL,0xd66f4cf8e99e31f2L } }, + /* 16 << 196 */ + { { 0x5b0b5d692a7aecedL,0x4c03450c01dc545fL,0x72ad0a4a404a3458L, + 0x1de8e2559f467b60L,0xa4b3570590634809L,0x76f30205706f0178L }, + { 0x588d21ab4454f0e5L,0xd22df54964134928L,0xf4e7e73d241bcd90L, + 0xb8d8a1d22facc7ccL,0x483c35a71d25d2a0L,0x7f8d25451ef9f608L } }, + /* 17 << 196 */ + { { 0x81e304c903b37e31L,0x21781e57925a6491L,0x4ecbad144b9250d9L, + 0xb395914345cae8feL,0xb894a39dbf775d4fL,0x8a2c1090d307e272L }, + { 0x49dfcee9408bf3cdL,0x08f0f33195b573dfL,0x23eb8a0b214bcd3bL, + 0x425e1cde7ccc4d82L,0x53f64095ac113d2bL,0x377a6cb3d88e0761L } }, + /* 18 << 196 */ + { { 0x9cd08431d360ae16L,0xbf5a73d211281e82L,0xfe25aadfcc34ff33L, + 0x8874984b84e3af16L,0x8dd38b596a65a2a7L,0x6c91112c68a26926L }, + { 0xb765168637554f46L,0x79558f04c78bf29bL,0x8bb14b1f03012b9dL, + 0xed7d03f9a0886ba3L,0x9a436ec3c2a93baaL,0x601babb740db0c78L } }, + /* 19 << 196 */ + { { 0xa7395eef391821d0L,0xb299378fc8b7b1e2L,0x53a37e3b7f3a58d4L, + 0x7d06fa4e3188c5adL,0xe65a94c063dd7462L,0x4daf74f39cfde2b0L }, + { 0x98f986b4fbe7198dL,0x8e96b1ee88176bffL,0x5f309f64eb91641eL, + 0x46bfe3352ffdca19L,0x1ea1bbe7ac8fbc08L,0xde8ca618b00f88eeL } }, + /* 20 << 196 */ + { { 0x0757ee852005631fL,0x60f484ea9d70cc3bL,0xaf131d246b011041L, + 0xe40711a1062e2e17L,0x05ccf1b94c27e2c2L,0x29e9910e43d43758L }, + { 0x54daa550ed000e45L,0xf00a312295d3674cL,0xdb006fe743ec424eL, + 0xbddf5473536162d2L,0x7b8a24b579d433bdL,0x3127a46f282297d3L } }, + /* 21 << 196 */ + { { 0xcd964573cd0585a7L,0x9c2fd35605b684aeL,0x7f600f4de4a47ec5L, + 0xcb4bcdf085fdd4feL,0x5b292292b4dcf5d1L,0x923c4331df33a2b8L }, + { 0x0fe13edfd6c1e73aL,0x0b35adc6c370821bL,0xa70061b08d405282L, + 0x98efb3fc6457af81L,0x8806ee7136e1041dL,0x8b56657faaaf0731L } }, + /* 22 << 196 */ + { { 0xe68b669189cb38d1L,0x250f59233456ed5dL,0x8928f1fe16188290L, + 0x8b24b1f734a837d4L,0x268c8c57d945d0b1L,0xa4190ceae002b3abL }, + { 0x4596e76e56dd74b1L,0x647c17871c307789L,0x0b945c7243b13a6cL, + 0x4904669552a58ee2L,0x7547a6b46e25b7e4L,0x8bc26f49e2b1b140L } }, + /* 23 << 196 */ + { { 0x95b3f4e75196d614L,0xc075bcfd5ea18aadL,0x15dc9dd41ae71f42L, + 0x75a769f289543f86L,0x06032d9ec392b4c4L,0xd6cc5c717d4df83bL }, + { 0x111fc63427ad6680L,0x770dfe7f781bda48L,0xabacb082fc0afb5cL, + 0xe3a463e771dca197L,0x390f21a89635b275L,0x3d3474b24ae094a6L } }, + /* 24 << 196 */ + { { 0x48f5588853666241L,0xb9fee3d39e6a068dL,0x8c50e3af0275e82dL, + 0xd490cf2dcab34005L,0x20b11f86bf0584c8L,0xd49714c18179e559L }, + { 0x89647b178ded6686L,0x6c4bac8cf16c93d4L,0x5401e4f8076ff71bL, + 0x577e73acb1ef9b0cL,0xa1b87e0ea46e7880L,0xab8d8bbb54fd28a7L } }, + /* 25 << 196 */ + { { 0x220161f0741396fcL,0xae14ce5817da16ecL,0x766e415bb828b19aL, + 0x1b3b239e610c7aabL,0xf1c7df4992d53419L,0x57e4cee59442c6cbL }, + { 0x546f73b5f85d33d3L,0x195116c74e041703L,0x5a71a96a5d668df5L, + 0x0adb7b16fe56c658L,0xf6be923deb563532L,0xa65ed113f2d45f4dL } }, + /* 26 << 196 */ + { { 0x8c6742e5bccd3be6L,0x5f0f7fdd378de702L,0x41236fec334aabb8L, + 0x4b15815b7e9d8aa9L,0xbb816e46e1c235bbL,0x8591cc45176c2fe0L }, + { 0xef00e3981d7104b1L,0x761d2c244012398bL,0xe4984f4ae81af247L, + 0xf923bb80c144dc64L,0xd51f27dd83988de3L,0x0ad5438d995dbbddL } }, + /* 27 << 196 */ + { { 0x0532790bd148314dL,0xb4862d9d5b6b4ad1L,0xab65bfc45beb3ac6L, + 0x72eac92d99331822L,0x2e09a69a6127632cL,0xaa1eaf0791ef9141L }, + { 0x79b923fe754ff12aL,0x19395a97f9a467ffL,0x7dcc91d49ef5cc4eL, + 0xb9019ff198a84090L,0x62616ed6d5bfd083L,0x95cbf9442b328615L } }, + /* 28 << 196 */ + { { 0x22ef6f606374afbeL,0x70e19fad26348f5cL,0x8bcd51a845f98ac6L, + 0xeeef7f7026b7ba04L,0x33aa0644544edcb9L,0x22d89a1244974c71L }, + { 0xecd08f5d0f8d90a5L,0x495a0403cf03513bL,0xe924feea27953ba9L, + 0xdfbe1f93eb5e7975L,0xd3c105a1285865dfL,0x87b8b6360886fc87L } }, + /* 29 << 196 */ + { { 0xc2da6d7a219d44f8L,0xe66364c555a9d970L,0xfb0936258611738aL, + 0x916fbfa844f7f35dL,0x7a4e0451774b1e2bL,0x7adaab9e80375e65L }, + { 0x2272b95c8ffdfda9L,0x41644b619ad42b25L,0x157026817f0c98fdL, + 0x25d4a00fffba1d85L,0x52e684c6c6c5545aL,0xba85bf2adabb7df5L } }, + /* 30 << 196 */ + { { 0x89a5b69dd282b12fL,0x63864e7ba7d28277L,0x36ac74d08c21f920L, + 0x7cfd291713a2f8d3L,0x50b63122c2ef5022L,0x23d454328ed33339L }, + { 0xf8696b2dc4880048L,0xb9605bd5792dcb6cL,0x4cdb5fc26fdeeb9bL, + 0x58ee2837f1a7f35eL,0x8956359ae2985ccfL,0x0cc6c4ab2c94cb32L } }, + /* 31 << 196 */ + { { 0x2fcac7d161a8254aL,0xc396583a05389aceL,0xc6f069cc3872ee52L, + 0x76f0e5b407180f5fL,0xc8b23b7a2dee0d6fL,0xc77b242613bf8fb2L }, + { 0xa8c625e66d5ae411L,0xc0c40a75b0723adfL,0xdee0ba8f380d9c67L, + 0x38b86a3b19920f24L,0xff2191b7d910e9cdL,0x8d01786734181894L } }, + /* 32 << 196 */ + { { 0xa704016022ec7eddL,0x19124972cc9c8ee8L,0x697f301f2ccb9417L, + 0x3ee877646f00d8aaL,0x2b5afaf88138a017L,0xf152b14c832d7543L }, + { 0x27c27ce2383052f9L,0x4746c5b5e1dae11bL,0x92dc5ac75b752008L, + 0xcf382e01e84fe5f1L,0x90e034197d5929ceL,0xafee3abb15ca3ffaL } }, + /* 33 << 196 */ + { { 0x299e0c5507f0e3a7L,0x75dac5c46cdebb44L,0x340b5479183c7e42L, + 0xfb1b03dd702672d4L,0x68f7222ec07cf89dL,0x67a471e422e7a8a4L }, + { 0x79dd4627b9ada93aL,0x774c53771c8ecca5L,0x95191e1a59db2e65L, + 0x3f6947f270abeeceL,0xb4934fe0885e4e00L,0xd082e49901728c2aL } }, + /* 34 << 196 */ + { { 0x86cd8083aaa82329L,0x74f0c5786e579dfcL,0xc2b68c4e3b436545L, + 0x8e66c648469d4a81L,0x4c5b05c5bef62bb0L,0xe558ff020bb6f865L }, + { 0x9f8ccb16f356a124L,0x1bb28d7c1279f8f4L,0x9b885f0ca8fc4e08L, + 0x2ec4cf69859d90eeL,0x9bef3c4d86d3b9d1L,0x5a98ce73eaad8d53L } }, + /* 35 << 196 */ + { { 0x6c716b179711b5d2L,0x396a4a4cb386c1d0L,0x5845f6861c157c12L, + 0xdcad516262c15d4eL,0xb6e0a6a02dadb218L,0xe4f6d5e5a342e785L }, + { 0x1eeea548c78980e9L,0x363c31be00a32adaL,0x01481fb7e660b445L, + 0xcbb61552999c1f5cL,0x20a73942f361d12aL,0x67fb89a11b8b4b3eL } }, + /* 36 << 196 */ + { { 0x1d57d639eb00e26fL,0xbeb198906985c10bL,0x38cd95a337b9b76aL, + 0x3b1d12e30304c87dL,0xdf42dc6f4734e191L,0x1ed1d9e397841989L }, + { 0xfb60e333859b577bL,0xfb026d16ed3db987L,0xa216b0e46f7855c8L, + 0x9501bae3539ebdf6L,0xd95a4a32dc8a1f6fL,0x76cb0b6b45307deaL } }, + /* 37 << 196 */ + { { 0x5607ab62a844b579L,0x8d3ed3db94f67d9fL,0x95390de8a9929b04L, + 0x4a6f6f7cc85397f3L,0xec5b73eff26eab04L,0x2543190b045699f9L }, + { 0x9a4896138cdbb723L,0x0e081e5b7a1c638bL,0x20f292c6596a7b1dL, + 0xa14d849794477dd3L,0xeeeca98064b0de1dL,0x75fdbae92c5135dcL } }, + /* 38 << 196 */ + { { 0x1202b5752b076f5bL,0x5ca1247edbd6c420L,0xb45ff9bfd8ccc5c6L, + 0x680fcfb28e061baaL,0x5a6e6342122a4212L,0x0ad12abc312fea8aL }, + { 0xd1dd8ae5665dc7b1L,0x30494dfdd9a22454L,0xc8aa9bc9da55ed09L, + 0x6ec643031b74b119L,0xf54574716b604639L,0xe2a214e59f8d83ceL } }, + /* 39 << 196 */ + { { 0xca698de5f5c96e8aL,0x352c89a3fd941919L,0x0e3de0a909812f23L, + 0xa74ba91667702fefL,0x6acfaa5a3863d479L,0x28d8932bb6bb15cbL }, + { 0xc62155704ba9718dL,0xc67a3eafa1edd692L,0xc86eeedaab31aa74L, + 0x2064ea632deb79c3L,0x813b84f51ff01adbL,0x994b9437458a1835L } }, + /* 40 << 196 */ + { { 0x1013c4f4fde3f7ccL,0xbad5415a838699b6L,0x2a8b4eac64cacc78L, + 0x3d10f949bf75d233L,0x5a9f7782fc84e55eL,0x209a18345ea7b274L }, + { 0xa66cb6d4f9e8d374L,0xf898d9479a20080eL,0xe7e4b91b1272df4cL, + 0x5b8507cc5dd136bbL,0xbe4b5262372a8e05L,0xa0cb170c2aa4a47bL } }, + /* 41 << 196 */ + { { 0x469180a38378217fL,0xd960bdde85ef6d61L,0xcc4e737d6654aa84L, + 0x28d440016ae51d69L,0xf13a0d9ac6187196L,0xe60851b392160f65L }, + { 0x41d98cf61cac48d1L,0xf37f003d1b57f2cbL,0x4829c60bce272603L, + 0x45991d4adcbdddc1L,0x17e591fe74601bf3L,0xf8a36b4fb3fe856cL } }, + /* 42 << 196 */ + { { 0x4410b773fe480323L,0x42ae32e3ea2f8b57L,0x6578a64b2886b9d9L, + 0xafcfa5fe4241ec91L,0xa7fa5afc16b4ef24L,0x4a6594bbbc16b610L }, + { 0xcb5845515e264fb6L,0x4b89955e2b9c3c70L,0x530426be21e11c1eL, + 0xb707abe9c9dab34dL,0xb5aab0bf5931cd78L,0xab6a2585f0ccfcdaL } }, + /* 43 << 196 */ + { { 0xe75761f716afd216L,0x8ff1cea3b8a4f008L,0x04b8b65e69889d77L, + 0x679bf7a586ad9fb5L,0xbe49be0b4c22b86bL,0xcc8905a16c026c1dL }, + { 0x17464e7e59ec1983L,0x50cb62832a03afe0L,0x8dadaf456ce4df91L, + 0x26cf59d1e0df6fddL,0x6ecc66119adaec45L,0x1be42e744ef67dacL } }, + /* 44 << 196 */ + { { 0xa01cb3bacb1957b9L,0x053693ccf50694c9L,0xf8a887ad527f3aedL, + 0x2f1a80ece9bf06f0L,0x74baeaa57d0eec9fL,0xce8e8b9ab0641cabL }, + { 0x91d1e84d128a1804L,0xbdcfcaec2d5fa43cL,0xfc5cff124106fa6dL, + 0x2ae3ffab01588ac1L,0xe9dcc9b44c067052L,0xd8e3d74bafa7d4c3L } }, + /* 45 << 196 */ + { { 0x64a134296d7b277bL,0x487080d8e9a50637L,0x02e5fe901c6c061bL, + 0x8fdaafc8ecabeb11L,0xb1e3960110720b13L,0xe7304bf77081f41eL }, + { 0x78a10af8c26f5cf8L,0xf52cbc155c032c15L,0x95a3c4558c0c2091L, + 0x1797b407abba6f79L,0x87c0cd05a96a3062L,0xdf75e2805f04a7e2L } }, + /* 46 << 196 */ + { { 0x47161e1f82779cd6L,0xa95afa08c8158458L,0x2cbefdbc40a80742L, + 0xd86e0bfaca420c9fL,0x08f5f8c29c79427eL,0xe8f88361da4d0d9eL }, + { 0x2195174d3eb78d14L,0x889b32c9ed6caecfL,0x1e679749c3c83ed3L, + 0xc27a8c84eddf8a29L,0x4a21af3af8e09f40L,0xf4b9797f1eb3b9b3L } }, + /* 47 << 196 */ + { { 0x58c2405baa44f11dL,0x86ffaa37ac0f7257L,0x373623cc4070f6e3L, + 0x142e62f9a36c73b3L,0x43bab2dd36a143fbL,0x4fbeb0b7aa50375cL }, + { 0xf9cc2e7b1f862294L,0x95a9be3c0abdcaa8L,0x70f050225cda074eL, + 0x152659db43e6bc89L,0x1790148727c6e01aL,0x544069354e083c21L } }, + /* 48 << 196 */ + { { 0xcb51f03954ebc926L,0xe235d356b8d4a7bbL,0x93c8fafab41fe1a6L, + 0x6297701da719f254L,0x6e9165bc644f5cdeL,0x6506329d0c11c542L }, + { 0xa2564809a92b4250L,0x0e9ac173889c2e3eL,0x286a592622b1d1beL, + 0x86a3d7526ecdd041L,0x4b867e0a649f9524L,0x1fe7d95a0629cb0fL } }, + /* 49 << 196 */ + { { 0x028bc25096c54946L,0xace5e7ad0f5fb7eeL,0xc820d7513350ab02L, + 0x4ae1f6d99c8d7635L,0x03d1f83a98e1ed80L,0xf014d45d5ad14550L }, + { 0xeb8f2c328cd6d0b6L,0x090a8f71770f586fL,0x1a8219f93eb7d3b7L, + 0x0d610d9febfc26dcL,0xfdb49980aa330297L,0x6396f218d81b3fbbL } }, + /* 50 << 196 */ + { { 0xb4ea3102eacb7b9bL,0x4aefb43d72af1d6eL,0x9a1a912d249a51d6L, + 0xddd0a5744d5e3a1fL,0xe252114708aa1f69L,0x4b235efe9de89d5dL }, + { 0x6fae47420d7f1aa7L,0x0434ae2ff200e13aL,0x75143dc192508b57L, + 0xc441a768055e177aL,0x84cd7adf2f142b2dL,0x56484f4161d9ad5aL } }, + /* 51 << 196 */ + { { 0xe3e9d0881beecd14L,0x4bd12b179093ab18L,0xa6908ddbc925d5dbL, + 0xfdc5f740832d1474L,0x1a35623696f831afL,0x0e39086808cde8c9L }, + { 0xab1c7cbda2206b32L,0x84d299c8b93ccf1fL,0x380fa432dabb6542L, + 0x59f01b5177c2cb3dL,0x9785c47b6e56c4bbL,0x047acc813a3f2b1aL } }, + /* 52 << 196 */ + { { 0x724210e61e42b4a7L,0xa8d536afe2dd968cL,0xc69936e683582c60L, + 0xd031f1abdd5d7f68L,0x7d31dcae8c4180d4L,0x117985f622bca188L }, + { 0x3b0a982537e38dc2L,0x1663fdc5896fe4b4L,0x55d18cc7fd707372L, + 0xfac2d7a40d2d8470L,0x994763391b04b1f6L,0x87cfbb5ee0bd72e4L } }, + /* 53 << 196 */ + { { 0xeac6a72ad5dd2841L,0xf1aa32524277e152L,0xe6c44e9b6ef7e947L, + 0xd03309fc54095378L,0x6fc5fb9ccdd06947L,0x10ed0e76d1e9a968L }, + { 0x42d5ab02dfb77b17L,0x4c54c381a53de8ccL,0x5fb4c256f2b1b5d8L, + 0x17d5ab28e12ed054L,0xd7c96ce1139da42aL,0xb32f63859919f459L } }, + /* 54 << 196 */ + { { 0x4bf5788312f4b0b3L,0xcd69d82ef46735faL,0xc397c8f9a1baa0efL, + 0xfce184c0fd1be398L,0x15021775fa54580eL,0x10bc85468f54397cL }, + { 0x6009a691eaa9d711L,0xc9c6a42fb7846417L,0xe9c305685627817dL, + 0xa1be66ff92abd5daL,0x9317838fcdea11c0L,0xace94ddcc85e7aa5L } }, + /* 55 << 196 */ + { { 0x3ef37821d4079bf4L,0xff78abebfcbdc3d0L,0x117414bc4733ea34L, + 0x7f181a3b9f50d0feL,0x9ea5f94eda897ea7L,0x01a996ceee8314ceL }, + { 0x0cac3c8b420e988dL,0x7ad66ac4bed3294aL,0x6bbf6dd800b62445L, + 0x590a57017a2fb4fdL,0xbf3b4e529ac11d81L,0x1bd453020d60c710L } }, + /* 56 << 196 */ + { { 0x8a43bba0902c32d8L,0xd8c69b74a3955e42L,0x413bf25d79c64afbL, + 0x3c39837584ac94cdL,0xfbfa9c53a08ccf5aL,0x9d8ac945e9d791d4L }, + { 0xfb9bb89e5e7a2553L,0x1442612bb039dd24L,0x8250ffe0a2e2344aL, + 0x5eae8b396426b985L,0xa1657768484741deL,0x05e52d4ac73cdf8cL } }, + /* 57 << 196 */ + { { 0x61c2417995c5e767L,0x7456380c3bdfef62L,0x62763f43d206cbb1L, + 0x1996e2c657871e44L,0xd0dbd290f220c06dL,0x6778e1e5d87743eaL }, + { 0x40e54caf16b8f046L,0xe834a1cb6bed77daL,0x7240befa3e9457c4L, + 0xd1b638dbac96cedcL,0xd1d7e814c9c0cd8cL,0xc73beaf14d38258eL } }, + /* 58 << 196 */ + { { 0xf1a6d776c05f40feL,0xb98c19b1c21ce471L,0x700b0bab7f9689eaL, + 0x861513a56f1d2e6eL,0xb7558b2292fe4456L,0x2d8f860704c66a25L }, + { 0x10ba7d6a7998347dL,0x72bf56093983b98dL,0x8d873c4f89238292L, + 0x5db0dca9a5e3c944L,0xf81fe37e0925aef0L,0xed6a13a4e4daae25L } }, + /* 59 << 196 */ + { { 0x49e2372711c3a930L,0xbf2ede34f5293b8eL,0x0abeeb3ca8e1cc9aL, + 0xb1db299440205cbcL,0x3252d29e52fb01d4L,0xa0b080c57dc91095L }, + { 0xb56fdae622a9ceb9L,0x6c3c3463b31f6f27L,0xcb510ec2ae3bd22aL, + 0x1efcd77b0b3db475L,0x1094bcc5ca766f9cL,0x688e940dfea48297L } }, + /* 60 << 196 */ + { { 0x3d95d26a99cde27aL,0xed608a89b99344f4L,0x7a70a8f09c0ab25cL, + 0x7740953c496552d8L,0x4da4ca0f4a366adcL,0xbf475c1b33274d4fL }, + { 0x5ac1d8288811b869L,0xed62e7b4d23446d4L,0x67d78571a0eab287L, + 0xa74ae3e98b0acc4dL,0xa63f91d64077c236L,0xe2c3f82a818a6889L } }, + /* 61 << 196 */ + { { 0x2bde7037b1d5fbeeL,0x477a4b51a80b92f2L,0x195ae0e06606b504L, + 0x7aaf3de57497785aL,0xb5581ee9290c5ef9L,0xcb303c30360c8ec2L }, + { 0xfb056f901b1fb602L,0xa38bc9f59931b7ceL,0xb0b74aeab2f453a8L, + 0x9a0e2ebf668cd68aL,0x8b7e0d73d7db7842L,0x21f29b74d1fa5433L } }, + /* 62 << 196 */ + { { 0x38321d7c4e11f824L,0x04dcd3a3e4a816e9L,0x382968ed07e09612L, + 0x6f7b2dbfa370e1d1L,0x5a8472348675d730L,0x88d974b0e59e984fL }, + { 0x89f7e2bce3f9e429L,0xd478eacfe3aebac2L,0x8df9f281ebef3488L, + 0xcbcb9fbeab5543b3L,0x2c8d19b0203f59e2L,0xbb98e4495287b0fcL } }, + /* 63 << 196 */ + { { 0x16c45f709aab81d7L,0x0f1310851795a4b7L,0x3c63d43af0ecd732L, + 0x22e2d1988628b683L,0x7d7482bab641d6d4L,0x6baef4a2ab69891aL }, + { 0x10989097e63c00d2L,0xbfd42ab0d93794ccL,0x9a1935f3e4165a41L, + 0x359701b35b600ca7L,0xbe7d69f983d1b54bL,0x99b0f35e3729bd4aL } }, + /* 64 << 196 */ + { { 0x11dd860e1c6d03b0L,0x30c1700809eec660L,0xd4f8aff635c0192fL, + 0x96a727b1e3a4a900L,0x1426daffde78c8baL,0xfacaa9bd8d1527c4L }, + { 0x0c0d5234cd072989L,0x1936c20d918550b5L,0x4828bee43d914fb3L, + 0x8324ea38f3ba26a6L,0x027590f3a94eb26fL,0xfd354295acd957bfL } }, + /* 0 << 203 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 203 */ + { { 0x3ede2484da756624L,0xb22da2ab73b13062L,0x56069e93962a667bL, + 0xc931266b130f2ceaL,0x4bd6a6fca7366a66L,0x23f30563aa5ac3b1L }, + { 0xa025d0efd7c2b26fL,0x597ce7d862129bc7L,0x4809927f2b3057f2L, + 0xb001c10a1499f884L,0x309d141c30b9a653L,0xadddce7dbf659d05L } }, + /* 2 << 203 */ + { { 0xa6c32900af2825c1L,0xb37c46c1d223a04eL,0x691e7d39063de7eaL, + 0x998df4e710daf9bdL,0xc7085b9e718b5d7aL,0xd41abcc816b3d4b8L }, + { 0x4dfce693f9bc4041L,0x383677ed659ec7a8L,0x2c1904bf4491fb34L, + 0x7c1bf1114552451cL,0x6562cc2c3c5e5e40L,0x1ecaa2a1fe0e4372L } }, + /* 3 << 203 */ + { { 0x9657d08ca9cb9ecbL,0xf69662363b75be69L,0x396a9344a31c2b8cL, + 0x1c50b1269767bc1fL,0x597223d0d1417e03L,0xe165ed5a12137153L }, + { 0x8bce29f926a24098L,0xc428a1fbe99e7bf8L,0x6fd4c906eea7f1d9L, + 0x94275713fceb2e05L,0x3555448b741dbd94L,0xc50e85459faffd4dL } }, + /* 4 << 203 */ + { { 0x84c3630bf3087bc8L,0x152691e674be6e26L,0x5abd125ff61af001L, + 0x69bca56fbfea3525L,0x384af19900e0cb6eL,0xb0b13cfed00475a6L }, + { 0xedafde495e394049L,0xd988b558daf2add6L,0xf14cf97a6c8ffcc9L, + 0x4d6cec23e5a9cc5cL,0xb0d678f88a104e05L,0x80a7fcba9fb527c1L } }, + /* 5 << 203 */ + { { 0x9ae12b902af1ffceL,0x082f30b95a30521dL,0x974099bdc304014bL, + 0xab1e27e444ccb6e5L,0x72db8f42290387a1L,0x3d1a461040f3ce18L }, + { 0xe939a3f2634ba10fL,0xe70a9cf517254c56L,0xd0f8692fa08ec3c5L, + 0x77edefcc7a7cbdf8L,0x04c4b18ebdf90f0bL,0xa890436a8aa36a59L } }, + /* 6 << 203 */ + { { 0x8618ffa79e30f8a0L,0x9961390cd12699bbL,0x5b1b0d744f61edfeL, + 0x33df67d9eb7a476fL,0x7f1a767ea92ee99bL,0xfab400e32223a2ccL }, + { 0x16f376f2f534dc3dL,0x6f36eaefcec17905L,0x8dc1516ca58765deL, + 0x893408262260ed6bL,0x060eb0afcf4b29baL,0x9cd0a9f11d252bbaL } }, + /* 7 << 203 */ + { { 0xd3c2a6a8ca413693L,0xcc56a8e932d5714cL,0xc72b73683c0da165L, + 0x5d236660db44e616L,0xa83b2ecce5c73667L,0x9d292f298aea900cL }, + { 0x67121215aaa2a7eaL,0x57dae96abf889191L,0x63bf7a81d296ae68L, + 0x9bf518758fd496c4L,0x5b4382fbc2f7308cL,0xf1215dfc9632aad7L } }, + /* 8 << 203 */ + { { 0x0d6cadbfc22137d2L,0xb5db59d3628a3298L,0x3b433c734ab19507L, + 0x4fc53405660086b3L,0x770ae903a1eb0f43L,0x31b5857ef6b5b58dL }, + { 0xe206e141d392868eL,0x8be6956f4b31de04L,0xcfbfca2f47449e07L, + 0xebaef25639fef8e1L,0x959e37b8c16fc80cL,0x8bb4bdd2e911d61bL } }, + /* 9 << 203 */ + { { 0xecfb851380fc41f3L,0xb0dc8823931843c4L,0x59decd6c1b93df03L, + 0x954103b72511e252L,0xe372f86a0f759de1L,0x04f5afd38f6f9ef3L }, + { 0xbd8e60affcba2e7cL,0x9b1cb1ed092315b0L,0x5f9e20a03fd05e36L, + 0xfcdcc44ded95f25eL,0x6baf401b6ac79cb5L,0xfe1a5a856894f651L } }, + /* 10 << 203 */ + { { 0x014a0907e51c6673L,0x28118ccd3e6e6a91L,0xdbbb7c4dc999acc0L, + 0x01b771075e7ab1e3L,0xa33fefbfcd8fb11eL,0x1df5b61fc0b8a5c2L }, + { 0x774dc2674478c5c6L,0xbfe1add422fb91a1L,0x5ac4dc694d9c8461L, + 0xbf6e002a1e772c5fL,0x4922120e0b83fe91L,0xa7747f4b3efbadceL } }, + /* 11 << 203 */ + { { 0x4b955beaddaf2e82L,0x3775ecde90fdc68aL,0x579c34f91713e763L, + 0x6c27f504fa509d74L,0xef6df04a3f8dbf4bL,0xc39f2e28b3ad7104L }, + { 0xe54042b3a5973cffL,0x4e594427f111f3d9L,0x53c7a2ba155fce57L, + 0x7b3c1c60e6e1d21fL,0x5e12db8d308ddf4dL,0x2c3c5e77a00e8976L } }, + /* 12 << 203 */ + { { 0xc483d4b24343bbf8L,0x42aca2e18a0fc95eL,0x5165df6fcbab1fb0L, + 0xeb284370f6cdfc0cL,0xab565c00994320fcL,0xc0d157fd62133e80L }, + { 0x7850cda55b69644aL,0xe37ae76a806ec8b8L,0xd14b805cc2c82eddL, + 0xcb5468b6cf244539L,0x97d43ee825dbe92dL,0x1442243689fb8f1eL } }, + /* 13 << 203 */ + { { 0xcfc8a945f361dc08L,0x383a5336491dc3abL,0x77580587c35cd376L, + 0x6604248ae2426904L,0x47c56025ffeb9d26L,0xc301edd8bae5d983L }, + { 0x7c6511a9e2e5cf33L,0xdc52c1dd221d41acL,0xdbdc8acada47503bL, + 0x01b406864bcedbbaL,0xca9cb9fd2d5496d5L,0x5768e0edb17e8400L } }, + /* 14 << 203 */ + { { 0x421afbe0431cb760L,0x9ae9ff985203e69bL,0x56cacf4db1a2705aL, + 0x6a3a4136d128bcd5L,0x2411c4b866191ad8L,0x39f26e1a15b45d24L }, + { 0x4cc82459c64ed153L,0x5c7a0dd58195b452L,0x9c88bb1c69f6298dL, + 0xfe567b031933fdb5L,0x8a6aea71881308c3L,0xc1268b55a2f0adfaL } }, + /* 15 << 203 */ + { { 0x312b777c1231c557L,0x3984f71be9971115L,0x0266b58294cc2d4bL, + 0xc3058419cdf5e5c1L,0xab3a1ae477bbf0d8L,0x7c2173a6d21603daL }, + { 0x61cca8cc747b092bL,0x70f77a53e376506aL,0x742c20692f1ccc85L, + 0xb1f2ceca2dc8844bL,0x5a73cff83a096c10L,0x28acb67d5c19cd11L } }, + /* 16 << 203 */ + { { 0xd7bf2ac6a0a85236L,0x2921b55c7194c46dL,0x162fabaa9afa9762L, + 0x7b7f1664b62b36abL,0x77b9f797296a84e9L,0xfcc1ad657dbd843dL }, + { 0xc6e9c1e1cd77b7f6L,0x9cf0e272917067c9L,0xfa7fa93d3bfa90bfL, + 0x55846fe9d050e46aL,0x473b9a0d35c56256L,0xadd29e332b656a65L } }, + /* 17 << 203 */ + { { 0x4698137f46fb8ae3L,0xb11a595f7b1c062dL,0x4a043b99ff023ef7L, + 0x2836d64d8ef0fa4dL,0x4067dbee8ea44a98L,0x9d1739c9f00ff4e1L }, + { 0xcbcf12fe133d2703L,0xd2923424016037cfL,0xda7543d68be5f666L, + 0x587d1920ac5e1847L,0x14662476f79e3462L,0x0120a1d8c810a1f3L } }, + /* 18 << 203 */ + { { 0xa4fc828ab18f9bb1L,0x06de4c9da27a787aL,0xfbb7c7d7b1b3a12bL, + 0xa7052b94b8583128L,0x173ec2d2e7b02fd8L,0x4b724682c776c664L }, + { 0x46ed9be5673183e5L,0x312191e83bd17c60L,0xe3ed6326efd56a9eL, + 0xb3ebc44c943a2278L,0x7ef62ba9ec9cf589L,0x754be6d389832cd7L } }, + /* 19 << 203 */ + { { 0xccb4b369dc992b32L,0x0ef84cc0922cee22L,0xda0058f1fc56e9e1L, + 0x208c57943f23632bL,0x3589a7338f77a82bL,0xee6cfa2c76ee99bdL }, + { 0x88cffafc418f7993L,0x0dde3f05f4be56d6L,0x5d088382a0472bf5L, + 0x872ca5aabd58d05dL,0x9c467c62e8f91f17L,0x38ab1b348c6b91ffL } }, + /* 20 << 203 */ + { { 0x926c2552ebc69b0bL,0x953a850fd4c7432eL,0x0ee85e14b9359035L, + 0x8b10b01abde090a5L,0xb2878dcaec423943L,0x2571a178f70bde20L }, + { 0x24ed159af5ebeee5L,0x60c202af043f6539L,0xdaaa76f4c8d4ffc3L, + 0x2fc1f1ba06eda10fL,0xddf159ee88ded556L,0xcfa71782e67b1ec4L } }, + /* 21 << 203 */ + { { 0x2596ee7409d3ed60L,0xd42551f474a46e37L,0x2e46a92e21061c90L, + 0x236299fa73ad22eaL,0xacdccd5214393ac2L,0x9a572130b56b4d5bL }, + { 0xddfc31781835e70bL,0x5dac0671d542048dL,0x2b0768d7a6dce17cL, + 0x6d447d4206c55342L,0x6b55b21525548478L,0x24e6483518d5310dL } }, + /* 22 << 203 */ + { { 0x3c58c5ea9b037c66L,0x08d0648e0d5c6ec5L,0x1bf90c53a4fa3f5aL, + 0x660cf61740381205L,0x63fd03081d44af3fL,0xe22b9c1a77175de7L }, + { 0x0b6044fc3556fc9dL,0xaefb6804fb55318eL,0x77045bce5c46e1ebL, + 0x29c4a3bc76e8f93aL,0xdf8aec699d697f5dL,0x5bd9552845a89080L } }, + /* 23 << 203 */ + { { 0x1bd61fbdc5756910L,0xcfcc6d5adeaca40dL,0x292867885dd80ac1L, + 0x7effe328d621c0a6L,0xc64ebb91ab22a2b5L,0x8954ab330c44a456L }, + { 0x7552a0b460e26218L,0x2e81d3a94136adbaL,0x96dc2451610d665eL, + 0x30859c62ab04e03fL,0xdb3726fd4c31fa3fL,0xbf4954d1d962a7c4L } }, + /* 24 << 203 */ + { { 0x31521f66d5d826b0L,0x0a63695240787844L,0xc0a3bd059c8f934eL, + 0x12c57dd42f0ce835L,0x847f6a9967064213L,0x1c9e1a7aa88bd71aL }, + { 0xc4060eb2171e8407L,0xdf78d8dfed106780L,0xa3d28ceb0d704729L, + 0x4f8e523246ca3912L,0x09e9f852017791f4L,0x594006631e6ea97dL } }, + /* 25 << 203 */ + { { 0xdd26fb79444827feL,0xbf78e076d3f5fa6bL,0x46d486e81a5475b5L, + 0x43e325a5faabc3f8L,0x1fef6b6ba6795d0cL,0x40e040666644d631L }, + { 0x16207bb9676c3322L,0x677c1c235811706bL,0xb686252e994e2a95L, + 0xa359e2a51b6f6a3eL,0x6d8f06cfb124f019L,0x3bcf778246266c42L } }, + /* 26 << 203 */ + { { 0xeaa3426b8eb929aaL,0x090924f2327bb35dL,0x4d23ba1276da394fL, + 0x05d98e56adecd43fL,0x83c7169f6b4af795L,0xc22560a7c8f26ae8L }, + { 0xb43aecc2d01ab5d8L,0xe7bcdc1f7257d7d1L,0x6f32d77650de3318L, + 0x6d736b279bf02c0aL,0x9534fa5865319235L,0x5a6a38493cfbeb3cL } }, + /* 27 << 203 */ + { { 0x3ddcb65828c50956L,0xb335f336bf1bdb4cL,0x7c18d2d0ac3b6194L, + 0x8748654bca324d11L,0x7c9c58dac2e85f94L,0xf1930a56d4f4f957L }, + { 0x9cacbdbbe410fee8L,0x0e292c2178e1312aL,0x6845b293906a6270L, + 0x842ded0f00c5401eL,0x747cd08f35e3ff9bL,0x8405540af48227feL } }, + /* 28 << 203 */ + { { 0x547b0d9583939224L,0x3a0823ff1e026769L,0x6016671525bd43acL, + 0xb6cf475e18ba5f64L,0xa22f9c92c8b6d09dL,0x730553683ccf50abL }, + { 0xa6de248eee6deefeL,0x32aaf8b2acc3ca20L,0x0e254c5bad44e674L, + 0x8aa73e6535f95f98L,0xe622600160a2dc1eL,0xdf9482109109020aL } }, + /* 29 << 203 */ + { { 0x7b24d7b056190aafL,0x0115cbdd0563b377L,0x5688526ca7ba4975L, + 0xd2971e28aee3100dL,0x57a6ff8a6fa24f61L,0x9cb571c4d8603be7L }, + { 0x09c01564a2cce6d5L,0x14f0902b89884939L,0xd71a5ff8a072ffecL, + 0xee7848b8fefeab69L,0x7b52a9577e40895aL,0xd1576be7e8c61be2L } }, + /* 30 << 203 */ + { { 0x4c4d454849d77b8eL,0x431f942f6a4c982dL,0xc8633d051cb39ce8L, + 0x23421f8caf516f9bL,0xc9db25d2aac876fbL,0x9f2669c5d882760eL }, + { 0x59dc4bf4c47d4bfaL,0x99ed0024c475f93cL,0x269d1ca4ebe07d37L, + 0x49ce3bdbbf88b1faL,0x515044053361e4ccL,0x207f0048735b3c96L } }, + /* 31 << 203 */ + { { 0x835fe90b5a516e82L,0x26f1f2a7abfcb383L,0x3dae65a8609c4ac0L, + 0x70b01d6e91f4054eL,0x22da015b581e3159L,0x2ad34f99329d1ebfL }, + { 0x7385aad60d09b845L,0x4cbafb0b0adf42f7L,0xd8727d26c02398cdL, + 0x58c261f590549db5L,0xd49b12e48ea70310L,0xb31eea047ef89773L } }, + /* 32 << 203 */ + { { 0x372798f02893f2f7L,0x4f62bfac9e5030caL,0x5e64f9a98a1e2567L, + 0x5870254ce70391c8L,0x2def81a341f02458L,0x25d4e4dc1d087bedL }, + { 0x3557d07d4fe24a13L,0x6da49186dc3112bcL,0x08c8c5675f73ba50L, + 0x5309050b9c7c6706L,0x2ab67da3bd985072L,0x9bafa8b1e5df4e96L } }, + /* 33 << 203 */ + { { 0x5acdcd216f77738eL,0x340710746cb67a3eL,0xd68c55cf4bf76bf7L, + 0x64c159200b4deda8L,0x1021d38ae242b1e0L,0x615f1f033bd3d95bL }, + { 0x2ae0245cc300c9c5L,0x3549605ba88d63e2L,0xfe0dd65ad5038849L, + 0xe67abfec63c6e4aeL,0xccd08ba528153bdfL,0x9be9f5bced4d76bbL } }, + /* 34 << 203 */ + { { 0x30fe00bb6e8423deL,0xe16ce94784e4d005L,0xaf0f8c283fed764cL, + 0x05ef9bf67d92b1efL,0xbf6570d4eb481da7L,0x39349e30468494ebL }, + { 0xe32b99a63fb36907L,0xd92386da2d35e71bL,0x74af8b79166a973dL, + 0xa0a177f94f72de6bL,0xfff3e19d5dd6c660L,0x15310d4d4b0d54f0L } }, + /* 35 << 203 */ + { { 0x692a561f15c15a11L,0x25abe85f26ca3ddbL,0x50fef4444caffa5fL, + 0x58472cfbed3f4aadL,0x7e9178f0092d2b83L,0x3afd364ff8dfaaa7L }, + { 0x4686ee5cbbf813a8L,0x6a62687d937cbae4L,0x56f22558a9b7b6c9L, + 0x9af1beae9c189e25L,0xfac4ad9f4d41f79eL,0xdecb57431f9c7a40L } }, + /* 36 << 203 */ + { { 0x3ac662895c02f173L,0x6a110e3876d566e5L,0xd9cc14e2b9577e26L, + 0x6f3d5df9fdfe617eL,0x8fac740f352bb2caL,0x50bc8a0cc28e6310L }, + { 0x6e572fc477ac93f7L,0x56277377605bb8e9L,0xad6d0637402b8c55L, + 0xdab377914509eda7L,0xae770abc0854e91bL,0x523bd278742b3de8L } }, + /* 37 << 203 */ + { { 0x8ede0eea2aa0da2eL,0x7015ee6e90cfeb90L,0xef33f3efd6b3227aL, + 0x6e332f1712ef9f4bL,0xcaa089898e7f9fe9L,0x001482ef8fa71529L }, + { 0x2522637907a5019aL,0x807faf01bed40fc9L,0x426002ab56710e12L, + 0xcdfffbc18d3949e6L,0xcc03f27861284379L,0xcd7dc2026d5edc82L } }, + /* 38 << 203 */ + { { 0x94f84d57cff31148L,0x9c567c7f6bf2a313L,0xc82e62353149ad8fL, + 0x81f69703c2a5d513L,0xb54e6fc756eea9acL,0x6799c7957c3aae62L }, + { 0x78e89c1edb280515L,0x3c5693066ac42925L,0xd984c86dab063cc4L, + 0x61754b5151d44ae3L,0x23af8ec0cebeef0fL,0xff67170bc618fe8aL } }, + /* 39 << 203 */ + { { 0x123b567195b58447L,0x7397316ad43aabd2L,0xcb65d69d9ddc7979L, + 0xf98be7bd91150e08L,0xa5388c79fc0ae5c7L,0xb115690215ed9074L }, + { 0xc2d01b9227e9afdeL,0x80d705ec2095a6ebL,0xbea901c7fab23079L, + 0xced8b2772346d712L,0xad5c45a92542a0ffL,0x87b2e4ac0455e90fL } }, + /* 40 << 203 */ + { { 0xc2cbd64417fecb90L,0x61616eb3b32dffdbL,0xdc4485a29f5d2095L, + 0xf78911246553371bL,0x4f06ba18bf9b20afL,0x136d4f291a2c4df1L }, + { 0xc04aca34fb8b685fL,0xeec83c20f2b657bbL,0x4da5d70a5925a36aL, + 0x8060874172ff2965L,0x2e0dd9ff9f352620L,0x5f0afa6746d1a7a8L } }, + /* 41 << 203 */ + { { 0xb76c722762c1e582L,0xbce1eb164ffefd05L,0xa574a9fe169e53fbL, + 0x77bf92b0c001628eL,0xd998172c04d60440L,0x62f35199ceae6bf7L }, + { 0xd81a563e93f1ff84L,0x5a7a0b4211598ad0L,0x884f2ca5ff11f3f8L, + 0x99f5aac2f3ac66cbL,0x58497c01f489c5afL,0x11277bc39566521cL } }, + /* 42 << 203 */ + { { 0xfb9670c26a770385L,0x5da887e1e9682174L,0x31fa9d6bedf922f3L, + 0x8de8814cf7a98d1eL,0x3935b9b27a019f08L,0x1f59d6f3ea6173caL }, + { 0x8732f39d5c638a66L,0x981a1b7a3d48d3e5L,0xea451b381ee0ab37L, + 0x31a8e9abf2708356L,0xa491944ee86cbfc1L,0xd747a885a97ddfcaL } }, + /* 43 << 203 */ + { { 0xa3460236aefd304aL,0xaac80f43c58719a0L,0x7d635c17d3ca5b1aL, + 0x986ac0a62119976aL,0x0d8a6e39f2538d36L,0x6a02af2f31849d5dL }, + { 0xecb6ef8f6719d4deL,0x6dd71ab674ff8880L,0x0d40ec0e9d225d93L, + 0x304cd88adf381d24L,0x2d6787380c5571fbL,0x03c23f547c03af94L } }, + /* 44 << 203 */ + { { 0xa995a95bf46aace5L,0x44ede5379eaa630aL,0x421f3b3500336e3bL, + 0xbf897478cf47c9edL,0xf360ae32259e0827L,0x04e0e3e82e6a9f6bL }, + { 0xb26eae5fa9136702L,0xd6cb15a1853674b4L,0xf81276e2748bcbc9L, + 0x7fc02e220a4ca1d7L,0xf650f48ecd82f330L,0xf4ea7c1dabaa8859L } }, + /* 45 << 203 */ + { { 0xe9f090b935caae35L,0xe04dff188dcf1e6bL,0x81b7de5eb8032e04L, + 0xba0d0b4e4b1e8070L,0xaa82dc8ad1a2aeb3L,0x5855ed1ded26f229L }, + { 0x8bce967ed1955233L,0xe6ed07f356ac7532L,0x4227c7fdbf0eff2dL, + 0xb1f4785fa5e213e4L,0xeedad0733ac30f4bL,0x503619889cf1e686L } }, + /* 46 << 203 */ + { { 0xeb252116ba5da79eL,0x51cc937edb691345L,0x1d5fec14077458c1L, + 0xaa304f7ba0808e6fL,0x4bed89f5abec4c09L,0xc67293cbd1a3b798L }, + { 0x0905f7d342122672L,0x83675b2da0d3a277L,0x7f422b7024bf5bcaL, + 0xe2144c6910495acfL,0xdac1c357a6a6ab5eL,0xd1a3b951c8b1d472L } }, + /* 47 << 203 */ + { { 0x0821017d60c0c248L,0xa17ce97a8540bdc8L,0xe0576ea986e6f45eL, + 0x1453268bf152c6eeL,0x1ea1937138edbed5L,0x970ad9c002343c23L }, + { 0x3a08a859af8a97afL,0x20caf7cab570d738L,0x6d82d863e2a89455L, + 0x30eb8d0724c76844L,0xb31d58c8d32b79f1L,0xe5df7cb9fe63e93cL } }, + /* 48 << 203 */ + { { 0x1ccd44ff95c746ecL,0xe18914b510405763L,0x50ed644321a3a927L, + 0x4f96a1b143ef8e8fL,0x7f5645e577952bf8L,0x4bc5c7ab66dbdf15L }, + { 0xacc1612623930a08L,0xbf5ed482504cf9b6L,0xdeb7a798d71ecbd7L, + 0xf62e63b14a4dd859L,0x668809a7daf714d9L,0xdd836382f3a4329eL } }, + /* 49 << 203 */ + { { 0xac0ef2cf383e038bL,0x848e3c1f91135098L,0x19e5a3ee3f15b241L, + 0x2d01f1a2dbea2ad2L,0x44ec32a799cb0bdfL,0x3e66fed4eab4d856L }, + { 0x3162a75af45c8656L,0x53ab74245a37ca4fL,0x1b81f1dc360bb395L, + 0xa7eb222e2b8a5267L,0x163bb0c804b0bcaaL,0x1cac5bc0ef5c417dL } }, + /* 50 << 203 */ + { { 0xb95e2d85e81d9e43L,0x8a92acdd1418f6d8L,0x5429140110ee43d7L, + 0x32a2933c625838dfL,0x801d57dd3d485868L,0x33bba67258af765dL }, + { 0x545fe2583f520eecL,0x900ed51a32d71974L,0xf21fefe6df3ed77cL, + 0x2f0df28c9deb2d81L,0x90898dd780856fb7L,0xeba82159bbba4771L } }, + /* 51 << 203 */ + { { 0x83ecc8f374df3780L,0x432e9807d3a89728L,0x3461c5297b5cb6e0L, + 0xee307c19030c25cbL,0xd72b60c7391ee616L,0x0c07bf462e9b4384L }, + { 0x9d791b0bd44acd49L,0xf3b3411c9f3b33caL,0x1bf55cb97f9b455fL, + 0x77e01607600f0a91L,0xdab95bf26bb7e977L,0x30d0f591fe4633e5L } }, + /* 52 << 203 */ + { { 0x894bdbd9c48f3ad5L,0x687ff8de09e167f6L,0xf06104a930371c43L, + 0x82fd34b7ce84dd10L,0xae122deb66ce5abdL,0x31f041d2fc4a90b2L }, + { 0x2589535c9a01c607L,0x231bcc85695bd7abL,0xc67c306262e3a31dL, + 0x31be44757af3e186L,0x1a2077a388efa7f1L,0xffe53e22815fad1aL } }, + /* 53 << 203 */ + { { 0x4ce41f69a3ee310bL,0x38fb07d09bf311ddL,0x5fd284d660985bd4L, + 0x2fe99a19e04d3dffL,0x21a352520b3ad853L,0xb0808a89012aa69cL }, + { 0x98219cf718c7c301L,0x429e08fc91254db8L,0xface2e53c41d54d0L, + 0x180651242decb2d7L,0xa9f65e3f26a9191cL,0x1dadd3deed42831cL } }, + /* 54 << 203 */ + { { 0x81ce91dd6327460aL,0x4cc880a0e2f22af0L,0x81aa9bb46a6d36f3L, + 0x8ad516741dd10657L,0x212267854253b30aL,0x530d1f6a8f161dd6L }, + { 0xe7eeb4c7e9ab63aeL,0x84f225bfb72d250eL,0xc81cb984458a8dc7L, + 0x39fbbe3bda68c1afL,0x8c6c99b3083cafd9L,0x4700ba37eb07d40bL } }, + /* 55 << 203 */ + { { 0x8980dd7cd8dcc7b4L,0x0179e9bc7ad18f8dL,0xa9e4fa6a08c60f0aL, + 0x4f0d76fa3cc7dd36L,0x53339e4c51a0e67eL,0x1acdaf24cebd80cbL }, + { 0x5aaebffcb5264b96L,0x3ebebb22858df87aL,0xb2f4c1cb092a95a1L, + 0x34932d51841b1a63L,0xe0631aab49074a2fL,0x71525c4fe3b7fd61L } }, + /* 56 << 203 */ + { { 0xdd15591366229776L,0x84093730f7882064L,0x6dddcb14e50ee337L, + 0xa8e6ec597a1f7e81L,0x8467f998f3738a6aL,0x70fcc6bcad3f1840L }, + { 0xf82eb4be723b3f4bL,0xf0f3935406beec1bL,0x1b181ea37ddcb539L, + 0x9c82c4faad6a81b9L,0xcc5ea5435c612c2bL,0x63ce7571bb258d6fL } }, + /* 57 << 203 */ + { { 0xc6c110ecd3b9416aL,0x254403ea024f63e5L,0x92d2965b68aa4a66L, + 0xa08bfaafbaed92aaL,0xe2194cd701ad3eb4L,0x7ba66e1da7552847L }, + { 0xf68c90ee44eb9bbbL,0xabe38c5c5f6438daL,0xe16d4aa68c38a6a1L, + 0xc2f8691bf6294db4L,0x9248492fba64da6fL,0x850c6a6865a3d6b7L } }, + /* 58 << 203 */ + { { 0xa794308d2599a1f7L,0x06bbefce3e72b328L,0x24f2c6f5420f6ae1L, + 0xedf67defaae894c0L,0xf66396eb2e8e9821L,0x21fbf5f7a701c8ceL }, + { 0x7fbb192401732f26L,0x3d0063a944f57696L,0xd6bcb1c3513dd8f7L, + 0x1fbb11b2c9f8c033L,0x122f94b17b57b3eaL,0x08edce19d24626c0L } }, + /* 59 << 203 */ + { { 0x06aa75398c3a1e9cL,0x3512ec3c1a08c7caL,0xfad0dddac5a92e6aL, + 0xa98059ee3b9022fdL,0xd67b6723103fbda5L,0xc1df32904762c170L }, + { 0xfd99ee58c734f81dL,0xa8de2a4b478b8a4fL,0x9e3ed58fb4b557c6L, + 0x14d353c571abd10cL,0x10ea798fe3fd4475L,0x157e16f97627f4d5L } }, + /* 60 << 203 */ + { { 0x1b5888550b96547fL,0x4539c9c065d1a59dL,0xd6c95fea26e15084L, + 0xf84ad9e286b96242L,0x92f57d6d451a5486L,0x0215cfcb06a9e87eL }, + { 0xe05b10eaf66e46f3L,0xe7b0e72f655a0642L,0x035032677b117f43L, + 0xf5b78105779ea4a1L,0x28ee00faa4adac77L,0x1ea67d716a93a2b1L } }, + /* 61 << 203 */ + { { 0x4b68a01cd6b3387eL,0xc79582a9e7c4c99aL,0xa4ad6429029fc3bcL, + 0xf260ad946b83c7adL,0x81360618b09c3b8eL,0xf66e00ccc661ba2bL }, + { 0xd064537de29a69e7L,0xe2764d389bb4095bL,0xa3f57eb0f2efdea7L, + 0x72c214f27ed3ac00L,0xf8cfa59de392e32bL,0xa5d995124ad99928L } }, + /* 62 << 203 */ + { { 0xd069a9971dec038dL,0x64401a3fd0b59bf0L,0x33eff74ce7ec5e85L, + 0xfef5a1c50d35b207L,0x731cfc17e766bc43L,0xf994c0d01328b6cbL }, + { 0x4f2a5eaa2d3cc024L,0x7f83c57036a6fa14L,0x915a126d65f71dbdL, + 0x588fdd68acfb54ebL,0x7de9d37b7f57b2afL,0xca52d27170e071ebL } }, + /* 63 << 203 */ + { { 0x9b9211ada283322cL,0x30c6fa27b7124c9fL,0xda8f88a7474cbf5fL, + 0xc2414ee338203749L,0xe5c65cc26b767731L,0x8bdb52952753781cL }, + { 0xc8fe770be051cd30L,0x6370ecc4f046aa97L,0x03c83c1cfa287e66L, + 0x935bd2052bccef4dL,0x87b2a49646012036L,0xbce6a91de3e6d6aeL } }, + /* 64 << 203 */ + { { 0x7be81fb126882c6cL,0xe2d5a251ecd25498L,0xbb3d40e27a8d1678L, + 0x1806c67ad520811eL,0xadd4bb6686f65d23L,0x3a62b1b3e20e23d7L }, + { 0x208b47006548b3ebL,0x0497f09ab7ec2809L,0xbd3964f8121c37e2L, + 0xd35ef301a598efbbL,0xbd76a276c5eef966L,0x64700a7f0af64e46L } }, + /* 0 << 210 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 210 */ + { { 0x169474a2d3812087L,0x9de300da6698ca7aL,0x8589de922ede425bL, + 0x50e03fea6df8a890L,0x0d8a5c1c4ba8b8e3L,0xf273aa673fffb91aL }, + { 0x21cf054475fc8236L,0x6ceafacf9799c242L,0xc3237eaed0962c81L, + 0x43d6ac34213f6004L,0x45e619b2d4148b6bL,0xfafa18b5ea5fb80aL } }, + /* 2 << 210 */ + { { 0x9a8580aa2f063b51L,0xa83c8ff71c216613L,0xb4da0970be07f781L, + 0x0ac2a260712f7b7cL,0xc9b8ee84436a7b97L,0xd758c20d11fb2f62L }, + { 0x5daabed9f170b799L,0x018d2fddc46bc387L,0x82d6b5b7d96cfb8eL, + 0x4d7d0d9344d9e843L,0xfa2a9ea991e7da3cL,0x8230c1a3d531b253L } }, + /* 3 << 210 */ + { { 0x82412f525ec31754L,0x42f462c89d32e890L,0x1e7b58cece897ff2L, + 0xcfef785241164628L,0x34ee0422d8bb22efL,0x6e0d44ac7d32f01bL }, + { 0x968251655a3cc196L,0xa26724dc99eb23d3L,0xdb575fafa75f7252L, + 0x778e333062a3e5b1L,0x8689884e84cccc80L,0x9883cd19b645502dL } }, + /* 4 << 210 */ + { { 0x4cc41f2834220e26L,0xb5937c6da49749c4L,0x705366640fa1ca24L, + 0xeeb40f3b91e5edafL,0xcdf98235f1d3de14L,0xa65e5b7eff018c43L }, + { 0xaa3228e7acee3a6eL,0xb63a6289e08f4ff1L,0x90e90425650b2daaL, + 0xe4a8cad26d875f17L,0xc212029c9ce8a46eL,0xce0512835ed7cfb5L } }, + /* 5 << 210 */ + { { 0xb0df226159b79436L,0x82bd0dafa195be26L,0xbc99a94b3398c317L, + 0xbeb44c903c96ee31L,0x3c39ad81664d2e46L,0x081787520a3e0585L }, + { 0x9a054b6b413e269aL,0xbe58891d98c3b62eL,0xe7fa4c4de5734974L, + 0x8ac535f4d0a846a8L,0xea0f95f1a651339cL,0xa255274fd96aa239L } }, + /* 6 << 210 */ + { { 0xe23b7b229534047eL,0xbd70aea83a3bd625L,0xf44b05fe238db60bL, + 0x9c46fb140293abcfL,0x12cab5d3bfd8875bL,0x1f38d4aa12dd0c65L }, + { 0x4bed41572adf9805L,0x3f87da928a56609dL,0x10b93363da02c903L, + 0x7ecc726621ce4786L,0x8ae366851e3da5bfL,0x196040ffd3edee12L } }, + /* 7 << 210 */ + { { 0x4805841fe81508e8L,0xe2a578d3a4808642L,0x6bbf10accd0b2555L, + 0xc5071effaf5cde28L,0x665e75439a7124a9L,0x157c11edc1437981L }, + { 0x2019367d7aeddd8bL,0x74a1e104386e3b8aL,0xe72d429bfbe09a42L, + 0xaca96fd9061b862eL,0xbb2d2bc8122595f8L,0xc90c6503c509d644L } }, + /* 8 << 210 */ + { { 0xadb5966fcff05adaL,0x8ed26c025c57284eL,0xa76e73e244693a95L, + 0x14da74355982bbd3L,0x46e982cd5d2ca132L,0x8f39074024938e76L }, + { 0x749206b30a89b09aL,0x429653c793b4a1e5L,0xbee3d1567025bb7cL, + 0xe23f0e1e19555c9eL,0x0dec3837751639baL,0xb36cb84405d43bd0L } }, + /* 9 << 210 */ + { { 0xae76a96e74f90b6eL,0x5fa8e94824c6789cL,0x2b3584bb03abbb81L, + 0xe19ce47c5c451f72L,0x35792fbad619ac7aL,0xfa0282a250059bf4L }, + { 0x562bfd14dabe692fL,0x1aaf542c47eeb6c2L,0x392d5bba045d0360L, + 0x4e7bb31bd80fe998L,0x08f62ef31111e14dL,0x4de917b04e9ee1b8L } }, + /* 10 << 210 */ + { { 0x8b9d2d5867166271L,0x658db4ea142bab7cL,0xdf84932fa4ad2849L, + 0x04b113355f6f86a7L,0x2de6b29c50cfcea7L,0x46d8f68a9be6a3a3L }, + { 0xfb88cda7af0204afL,0x3ece449126029d72L,0x69fef1e23f946dfdL, + 0x708532fb01ef7bb5L,0x78d5053deb3795a2L,0x819a63206b36d57bL } }, + /* 11 << 210 */ + { { 0xca07e0c1e509d19eL,0x6c7e42c39f6281b1L,0x0e2ff43977b66728L, + 0x1d740e7880e76251L,0x6bfae4c631a0eb23L,0xd78ca917aa9b0b3bL }, + { 0xe140c662991e1781L,0x6e396b5f0dd3cfeeL,0xf0a1d1976ce7f6c7L, + 0xbe10f8efd5b01564L,0x865cbd54101a5194L,0xf665885266861dedL } }, + /* 12 << 210 */ + { { 0xe4e52e865b28f7daL,0xeb43a6809a58683fL,0x73b951bfb49f2b38L, + 0x7b6cb7db3f8097cfL,0x9dfb8d0b328fbf05L,0x491635a5ebce6211L }, + { 0xa31a152390fdd577L,0x334120df1cd2f39cL,0x1d22834e6b563876L, + 0xfd91b30d10ee5a28L,0x3d7a282d59aee4eaL,0x36814c6b73300a76L } }, + /* 13 << 210 */ + { { 0x7b584add6621c251L,0x98da669d4233aba3L,0x4d652b7933aa2065L, + 0x901bcfb8df7b4ed4L,0xb2ce587948012f81L,0xc18e2cd63cb71b88L }, + { 0xadb0f2bdff86279dL,0x46d9e5d65bd15866L,0x11b1fb3ec635a4c0L, + 0x8bcd0ad201b1006aL,0x0f6f7502cbab210bL,0xd6cc3e560d6b3995L } }, + /* 14 << 210 */ + { { 0xa54a6420137264c5L,0xa6ef0e78f9c2e45eL,0xba8b5a73d58d850cL, + 0xc0209ed86ef6fc3eL,0xe39dd0f391f7518aL,0x74697b8942b3eda6L }, + { 0x2dccac36abfc9150L,0x80e4fba298b2f5a5L,0xe0e56fd2771018d5L, + 0xa31fd1684c22bb94L,0x8b0998f71a66ef21L,0xed483e55b5a53ddbL } }, + /* 15 << 210 */ + { { 0x95db1c0ef23978ebL,0x80ad1612f04011f4L,0xe76bd1824d7ae83dL, + 0x841d6e668fc3bd60L,0xb68e80796875e2d0L,0xe3965efcd5d9dee7L }, + { 0xc488bb7e58930931L,0x52f4de19a907aa24L,0x39aebbdd321cc197L, + 0xd2f5b1f967de5c66L,0x60f1a8c28efe3e76L,0xf40604a0af988831L } }, + /* 16 << 210 */ + { { 0x78b5c14c0acb5935L,0xd9ec715c4311d3beL,0xffa22ab209e1759eL, + 0x5a86263db4b2f68cL,0x71e77c516b5be7f4L,0xfb5bea3a19844f6dL }, + { 0x2519d0060890ffabL,0x426a03f0f0329ef0L,0x2c6d74a685b3c2a9L, + 0x9306f68fc294f449L,0x552e77c22c69fb46L,0x7c7337ad10bb9886L } }, + /* 17 << 210 */ + { { 0x61f8a505d2b9f25bL,0x1d33aafe4c8645ffL,0x26f3fab7bcd333e5L, + 0x8ff4fc51be95e40fL,0x11cd52c6b55bdd5aL,0xf2b4782a22d43de8L }, + { 0xfe66e399a4c0e1c4L,0x26c6d7fc17954032L,0x44c700f97f20d2caL, + 0xdf67c3927187cdc7L,0xe11a98f9da36414cL,0x0bc5763a04052276L } }, + /* 18 << 210 */ + { { 0xe75b564bcf95451bL,0xd5ed760cc01aac32L,0xccf14dc5980d2c06L, + 0x235b5034ce2a5c0cL,0x64dc86aa05fa6780L,0x1d2ea4877385590dL }, + { 0xb18696f636c3174eL,0xf530487b608215b4L,0xa073d0750a123172L, + 0x8ca24b5afde8666aL,0xd6dd589a9b716dc1L,0xcab7ea504a721d4aL } }, + /* 19 << 210 */ + { { 0x34dee42c1592ebceL,0x5b0eba2e417636d3L,0xba178703a97d7356L, + 0x16f6119f4123e8cfL,0xd2906a53ef179fa6L,0xac5530606b7ed572L }, + { 0x82a25857b600f5c8L,0xb1dc1309973d516aL,0x6d53a967245c6e34L, + 0x7ce90bf4f670b879L,0x727ad4129732b6ebL,0xf00fb0054411dfd5L } }, + /* 20 << 210 */ + { { 0xeba7daad2b14da6fL,0x8274d1a8cee90515L,0x985c18f885bdbc82L, + 0x86555ff094d43909L,0xb0b1b2b6539e108bL,0xa4f32c66c0bf1313L }, + { 0xbd4777c162080e0bL,0x73039da8dadfb23dL,0x85bc57374a27f1ddL, + 0x9a8ae24eeaaa58abL,0x161cb2f5e876fac2L,0x54d457e46636e377L } }, + /* 21 << 210 */ + { { 0x409b17487bece8c3L,0xee36a1d3b49f5c90L,0x8ed9eb2a619ecefcL, + 0xc50a917798ab7bb1L,0x1eb247cceee2ccffL,0x07a9566f084a0f69L }, + { 0x59bda805a7cbee61L,0xf588124ca4e7ecd7L,0x0f7d8c3dde5eed54L, + 0xd98894ddefcb791fL,0x2fd80439ab309d7dL,0x0c8bf15d3e6cf756L } }, + /* 22 << 210 */ + { { 0x076a19c70e68a69dL,0x4d01c94b24b3854fL,0x9f38c5eeea8a85b8L, + 0xea80422d9a56f9c3L,0x10d9ceec9ad36735L,0x42194df742261173L }, + { 0xc7332e70c285d22dL,0xf3a3d4be592ff9b0L,0x2fe712f7f59846abL, + 0xd6de5201e4362677L,0x16ce8f1d4f30006bL,0x1f3c324d11dba5edL } }, + /* 23 << 210 */ + { { 0xa5af9e1c0cb4335cL,0x00a46bc0f3d0dbe5L,0x852a18c99d734817L, + 0xc12d54a9986c0102L,0x184b407063ffe60dL,0xe05182437d99d723L }, + { 0x8d3886cb20ef7647L,0x7e9c618017b1ce8fL,0x194baf260f176141L, + 0x978015d3b4694945L,0x2603be2f1c135e8eL,0xbc0f5e72ba074e0aL } }, + /* 24 << 210 */ + { { 0x1674b959cfe7bcebL,0x62e1279fe7b66a28L,0x3962a32dc67c3648L, + 0x4949617368d720a6L,0x4e81df85a957a5b2L,0x28b5c45753123c0fL }, + { 0x5091dd347e239c67L,0x10b9c3f6160ef925L,0x5e7720f52c119dbeL, + 0xd584ae76c94d609aL,0x476c63ba86dccd1fL,0x70103a1a32508c6eL } }, + /* 25 << 210 */ + { { 0x64f4f4ee90a17a16L,0x31165bee7cb22fb7L,0x31da800b924825b0L, + 0xc2c169db0551e47cL,0xf9ca5e0e0d583789L,0x5e4fbdb53cd42f2cL }, + { 0x6ade1fce1d81000bL,0xa105df391d6603e5L,0xd659094da3139f95L, + 0x363a882851d01444L,0x13cd7cbb2dece086L,0xaeea2aa96ab9020aL } }, + /* 26 << 210 */ + { { 0xdcb31a931081405fL,0x200090dcf1326ecbL,0x773fe49cde99f0ddL, + 0xf6a7cb67fac2c511L,0x95c93429b40b014dL,0x967708d4198dd723L }, + { 0x74591cc184b90062L,0x2539ef20691d2550L,0x7d7290765a5d86c7L, + 0xa81f085475c6fdacL,0x103186d1c0f0d5cfL,0x5ae582e07eb3b8d9L } }, + /* 27 << 210 */ + { { 0x7df39eb2f9f3456cL,0x1e7ad4587be12020L,0xaee54df11fedfb79L, + 0x98f3a0879bf1dfe6L,0xdf958d371d13fb71L,0xa745249717dc809dL }, + { 0x9f2ec9dd02d4eb90L,0x9db5686e48b0c7a0L,0x7d064cbf72532eb0L, + 0xe204d56593a71a9cL,0x0c912346f1aecdecL,0x894224a3d25d243dL } }, + /* 28 << 210 */ + { { 0x6bbf77cb5a508291L,0x2af81442d35db82cL,0x357feb1a2b9febf8L, + 0x74240a81a25330ceL,0x7a9ab575b4917998L,0xa60288d5eda3ef5cL }, + { 0x360410d30aea9569L,0xef66acb5b9bf8c16L,0x7baeb466cc381b57L, + 0x024a98b8247a4904L,0x6e70b4c3e3c58130L,0x276e2420ae8a56d2L } }, + /* 29 << 210 */ + { { 0x3b4a25222c57f1f3L,0xf43d352ba8d1f53bL,0x169fb3cce198b03cL, + 0x92172ca923235a6eL,0x90b5953683f996e5L,0x32b1a34cb5ab11a0L }, + { 0xb944e4b7b9001351L,0x1084de3d28ab5cb2L,0x60f1dc93c70ec63dL, + 0x790e1d496cfa10f9L,0x79bcc2277c3cd865L,0x95007ac24fd31fd0L } }, + /* 30 << 210 */ + { { 0x6b5d8db5f75e17b5L,0xc5ab42961b45a230L,0x586f097b7486832aL, + 0x1ec456c14f289757L,0xd11773bb57b04a20L,0xc84dfacd0821d3dfL }, + { 0x580da8cd586e399cL,0x58c1355ae3bbec57L,0x0a476934d594a2e5L, + 0x0490ffd537e99427L,0xd41348386a4d8c4eL,0xd62cccb3c83d6e28L } }, + /* 31 << 210 */ + { { 0xe6071a3d57c9e219L,0x88728c47a93f38dbL,0x0426848b50eb1a01L, + 0x9df36972cada9a09L,0xf2ad4a2d4f494ec4L,0xae26577de1f34993L }, + { 0x72ec08cde3618d7aL,0xd1fb89013ea90c46L,0x915936173b94f996L, + 0x8703357705387745L,0xf1961ff818fd5199L,0x7f0b58d34c2aeed1L } }, + /* 32 << 210 */ + { { 0x3313a9d544b133d9L,0xdb85c25d2da910ddL,0xc0fdef915e4dd5cdL, + 0x902a2a93c565dd67L,0xd8eba4dc7fed05acL,0xd453995ce157dae9L }, + { 0xd655d0b3f250cb55L,0x4194a09e86119222L,0x5b7e525a0652872bL, + 0xaf7968efe68c0ddbL,0x2ec02930f51cb31cL,0x237f3ae4f2be071eL } }, + /* 33 << 210 */ + { { 0x696d84910dc943a1L,0x1f24fd7d9fe1d7d5L,0xea38c9e349413ad7L, + 0xe223996607c1cecaL,0x62094496ea7bd8dcL,0x9aba5bc7236dd525L }, + { 0xa138ed5851631b6fL,0xed724f20902f109aL,0x3ab594cccb28f1e8L, + 0x3424213b5916dae7L,0x07e5a6df18479651L,0x4c51f2e1c5b48e29L } }, + /* 34 << 210 */ + { { 0x6306564b6591a811L,0x734b2619fd463a13L,0xa795d0569d8019d8L, + 0x103d85004ffe5858L,0xe1962c31adab8484L,0x326b3351b2015dccL }, + { 0x2ad52b852ff36c73L,0x5874652308682fcaL,0xf544e162ea37824eL, + 0xd4a6b45ec208ce7cL,0x52d09045d2559ef2L,0xde1dfbbe57ebca65L } }, + /* 35 << 210 */ + { { 0x3a94aec3bb793f9aL,0xd0af44d4b5352511L,0x1d3f1c130b8930cdL, + 0x016cab225a729e0cL,0x092a7c11e31b549aL,0x80c462ed90ebfea4L }, + { 0x3dcb9606e5e4ae09L,0xad150903ab59a450L,0x1b58210c6c944727L, + 0x26599f6024572a80L,0xfce0ad40c0445075L,0xedca1ada54c4037dL } }, + /* 36 << 210 */ + { { 0x794593303801b021L,0xb19bb405c9a4cde4L,0xe20091667f9cdee9L, + 0x762c684f7636d30eL,0xbf2b29f20c215831L,0x4c0d1b651853fe90L }, + { 0x196ccb3157defc94L,0x9f3d66b7f6b9cc44L,0xb2328a0eea439deeL, + 0x82b3808d7b140e5bL,0x986210dd88e4a35cL,0x9b171fc838a2b7a7L } }, + /* 37 << 210 */ + { { 0xdc80e3ae91517233L,0xa219f65dc6f20d29L,0xd348a3d8be093f56L, + 0x63c233774d33113bL,0x587fd56257f2ce9bL,0x82cf3e3a4e9061c0L }, + { 0x0e41f59bee8dd928L,0x7a5641be8aaef52dL,0xa852a171984ff476L, + 0x3c37fd1c047457b6L,0x7f00d665972d4793L,0x29dab0fd97b27966L } }, + /* 38 << 210 */ + { { 0xb1d119c91e9d07c0L,0x2f973a09432c86afL,0x3505b6f05ded5546L, + 0x21814b958687f973L,0xc104d7fad3794ae9L,0x81614d707ea91311L }, + { 0xb7f3e6b600677961L,0x53fceb8bc0e6a90dL,0xa3a7485699ed4fb6L, + 0x07ad488421d4807bL,0x527b1ae6004e0c03L,0x437f306215146393L } }, + /* 39 << 210 */ + { { 0x917b4cf463e12603L,0x79e0b7363f838ecdL,0x57de4b3328b4f37eL, + 0x3085e4887f58fcfaL,0xb9301c4e958a3bc6L,0xef8d10578b044eddL }, + { 0x2123d284d6391459L,0xdfcc2be5e196d765L,0xb58216268184b993L, + 0x13e21d03937c6048L,0x39eb3d38460d11fdL,0xf8ef123e5bb23c30L } }, + /* 40 << 210 */ + { { 0xa6f8b354666eb2f0L,0x7fbf6d91f9c7b16eL,0x9b360814161b5e0bL, + 0x13726fbd921511a4L,0x37aa1b8013833a11L,0x53f01183407b9889L }, + { 0x8a83ea3fd147da9fL,0x25279241db0ad0b1L,0x78353bccd1a8d9aeL, + 0x1e33c10e271f7f0eL,0x136d9e7e9e67adc5L,0x11dcef95cc56ff8dL } }, + /* 41 << 210 */ + { { 0xae530580d84ba919L,0xac2e43ceb6d3ecd5L,0xf97b1afda4bc6a2dL, + 0x180d66d5bdfa96a0L,0x935b8a7d1ca12bf5L,0x1d4409a79e678225L }, + { 0xdd85bf4b19a2163cL,0xe34197bcddeeb22bL,0x1e33fc3e1210cde9L, + 0xc96212a98b9b5d0aL,0xa3ae81f303e4a12bL,0x531a7148ea262807L } }, + /* 42 << 210 */ + { { 0xf11ac5fd4ace8006L,0x898a388133c499a5L,0xcf27ab9f1d3368ffL, + 0xfb6019606cbd6e54L,0x5373c2a901fb58b6L,0x1489f5037cd1b888L }, + { 0xb3f0e0b85a238131L,0xd0e11e6e670858bdL,0x897f1584b65768f8L, + 0x9252aa72013b1f2dL,0x185842af0a1a5f8bL,0x49a978373d681a70L } }, + /* 43 << 210 */ + { { 0x8b65c6d23396eaf3L,0x2191764e50b9392fL,0x7a2363b72dcf6d0aL, + 0xa6a52402f0591553L,0xfaba81cd5ff7a071L,0xd6be926ae43e37aeL }, + { 0x7b34c578ccaacef2L,0x2bc5d248d5eec9b1L,0x9447aab3014c0048L, + 0x767309a3c02d54d0L,0x408c6eee1f92297dL,0xf7ad95f40072a2d4L } }, + /* 44 << 210 */ + { { 0xd0051ab940ee5098L,0x4861b2461d8311deL,0x6b7796e0f31e860fL, + 0xde8b243acfd543e3L,0xef9d0957a0161843L,0x70fd43ecefefcbaeL }, + { 0xd47392541931a5a6L,0x42e253300342623aL,0x90b33edd52ffbf5fL, + 0x0affda4ca015a550L,0x8716376b77e59672L,0x39d84b33fc0e9448L } }, + /* 45 << 210 */ + { { 0x71b55e7ea0415173L,0x5d0b5e01b10f3cd5L,0x0c35a1b63e3f9d84L, + 0x3c68cb5db794ba37L,0xa73356f0dfd6c999L,0xc59ed0650e5e221aL }, + { 0xc59443a90cd7d577L,0xa354296e283015a8L,0x202aee3ba7477107L, + 0x59f361392ee80330L,0xc52bdfaae875a886L,0x8ca39d9d07637e97L } }, + /* 46 << 210 */ + { { 0x95be10b8f3a1611dL,0x6db370f0d1f992c1L,0xb964029de8124b40L, + 0x618b26aadfc90473L,0xac65c9916f6d5553L,0x10d5b0f0a0a6fde8L }, + { 0x4bff23122d164911L,0x876db39d1f7293b1L,0xa2d3cd549de47789L, + 0xd8ca4f6eabc9a28eL,0x0bb3145fca7b5467L,0x4dce66338b37bf62L } }, + /* 47 << 210 */ + { { 0xcdd8ec4dec1b8d36L,0xf76258d888003e0cL,0x35a114e7262723f9L, + 0x12933142abb34bcaL,0xf55b84514c188a3bL,0xa0cfdb2c0ada78b6L }, + { 0xaf0b62f6ed36781cL,0x0c619486ea7e1ca1L,0x11fae38689162fc3L, + 0xe9bd7ae694828e92L,0x081c3acda84cedb9L,0xb34ceca8787a67e0L } }, + /* 48 << 210 */ + { { 0xd1b2af2f2bca651bL,0x2211e4f97404bc78L,0x787b1cc8fc5068f2L, + 0x73d6da299fcbb3f5L,0x6867fb7707d2142fL,0x36f277ae116ad6bdL }, + { 0x81c86073a7534943L,0x67188488c4033c7aL,0x13a8415ccc568123L, + 0xbc01db07f3f475deL,0x90b8af2e3aaeee1aL,0x320c4880175fa55bL } }, + /* 49 << 210 */ + { { 0x263afd7d2fcafc9aL,0x9b0c30ebcc9405d6L,0x713fdd27d6720896L, + 0xb07f8ec5f7df4a02L,0x05d62e5147ddd4e1L,0x6278227b8ae3b80aL }, + { 0x2ef5c81b0d4ab658L,0xe6ad5925016a434bL,0x6c0e30a2b85d8037L, + 0x254830037a9cd869L,0x78da543b2cc48c8aL,0x3a65b54e3edca4dbL } }, + /* 50 << 210 */ + { { 0xaf2a06c3d54b0072L,0x81621ebfaf0310c5L,0x6bd1fe41a8a7a9ecL, + 0x942cf6ba03e74289L,0x2a25f0f59f9822e8L,0x16654b13062edd3eL }, + { 0x2345a0b19de373cdL,0x425a59f80c0744acL,0xc6738fe96f0d620aL, + 0xaa479ef8ed67c1a9L,0x52540af87765b194L,0x17a3bd3bf2b96455L } }, + /* 51 << 210 */ + { { 0x5b1a1f075f01e608L,0x3c696f4e87b821c5L,0x4358a5243129700fL, + 0xfc9816a14be9d001L,0x905de48166744b96L,0x2ca5f8d8eeda3945L }, + { 0xb30eeb1aad207f4eL,0xbd113b2dbc66e6f7L,0x1b6c5c6cebaef81dL, + 0x6b3863998bfaf32bL,0x5f9f2a2432a83dffL,0xe8cc190e26ea39d1L } }, + /* 52 << 210 */ + { { 0x51e05f7d450535fbL,0xa5f5181effbe389fL,0xdf178fffaa2d5514L, + 0x89358810e51da035L,0x206e324f664d399cL,0xc148ae74c4477d4eL }, + { 0xe0c8d4377d6f38d5L,0x327aad6d8c8133e9L,0xa685a889d21cac4dL, + 0x1217c68d0ceb5770L,0xa4a09612d21f1d50L,0xab64b4dd889676afL } }, + /* 53 << 210 */ + { { 0xf263062aee202007L,0x95e90bbda2359019L,0x57740eb39f34e691L, + 0xa5f4fd0f355bef37L,0x484b97fb439f091dL,0x642776fe53ac871dL }, + { 0x5c8f9b1e494e0eddL,0xbc62c971ae25a6d7L,0x01981994a7d90290L, + 0x3cec43524602cdc1L,0x4bd29f5a14403ae2L,0xafaef08b921328d2L } }, + /* 54 << 210 */ + { { 0xd33e754a53ef149dL,0x82243def548034e6L,0x99c29a9b23ea2dcfL, + 0x724e4b5d214848afL,0xe43d4438dcf85b9aL,0xaf7241ea9d7b20dfL }, + { 0x60a10c30069edb1bL,0x1aaddd5e9874f484L,0xfc784ac073085538L, + 0xc998afe54d69703aL,0xb71f6fd7bf52139fL,0x28f994c46a45b089L } }, + /* 55 << 210 */ + { { 0x85084ec2eebd9e0bL,0x73e489c6cb9f1929L,0x91e47fd7ebe10e55L, + 0xeed6a3a1486a2704L,0xf63deae7e124d6e2L,0xca958204b48b3834L }, + { 0xe69cb5bb13185b44L,0x56be0e05868d97d0L,0xc48cb1e50181e64dL, + 0xfaa012ddfc7827cdL,0xf535b1c83488352fL,0xd1cce04e9fbf42d4L } }, + /* 56 << 210 */ + { { 0xa54436b6ba3403ffL,0x1fe4b1ecdcbc4822L,0xb3b351004c6846e2L, + 0x360278048d1cac7cL,0x9eff87327e86d5d1L,0x7f435326ba21993aL }, + { 0xb51a9da5adc24224L,0x111c19fcc8c14a71L,0x05aa2c86ab77e011L, + 0x81edc338ce72744dL,0x20fa8f528d882bc3L,0xc61c3e639d1696f3L } }, + /* 57 << 210 */ + { { 0xa66674ca0f41637cL,0xa01d08ac418487daL,0x2ce4258b6b593194L, + 0xd755220645024db4L,0xffb3366f626732ceL,0x802878f370ba2f1aL }, + { 0x80a3f41659b77372L,0xfbb411631a04b19cL,0x7d575112a346d265L, + 0x6c30421ffff87d4fL,0x1b62b93fdcb05f02L,0x98ba4397b72649e3L } }, + /* 58 << 210 */ + { { 0xcca45c1d135a7eb5L,0x2623e629b048126bL,0xada7326e926980f0L, + 0x64f334c276bf796eL,0xf0751596b4a562a8L,0x0baa14486f9d0079L }, + { 0x6c394aa32205ea70L,0x635b9d2d556172e9L,0xf418fe0cfd37b53bL, + 0xcf5fe2ac56b9791cL,0x9d855e67911c68ddL,0x9e40f75f734b57d8L } }, + /* 59 << 210 */ + { { 0x32c42482b5b8f846L,0xdefec599b61cc3cfL,0x4c3460996506a9b5L, + 0x0d9475a0263a6142L,0x1753cd92c80a6713L,0xc015412f420cf67eL }, + { 0x1c33f01b6a88d12bL,0xa49f038ef522f7d0L,0x232343decd25f260L, + 0x479bc742d6a833c3L,0x2f2ab294cee07b83L,0x02e69a143dec38b3L } }, + /* 60 << 210 */ + { { 0xbf7fea3aee1fee16L,0x31fb342ce0cde85bL,0x9a232ea51575924bL, + 0xc3132e6cbcc4cf26L,0xbc5b7a7102499a58L,0x3064a3b904d99836L }, + { 0x6f17475ff8b3bad1L,0xaeeb90c429271790L,0x7f442a13f8eca53dL, + 0x6d641eea08882274L,0x8dff43bf88ffaebaL,0xaa92827f5840b198L } }, + /* 61 << 210 */ + { { 0xf5ce3fca26d803acL,0x6927ddd9d4e1b6b5L,0xb509b5c609f48bc0L, + 0x2bc5d1749e35975aL,0xfba3024af570c98bL,0xeba15980aa27d6b0L }, + { 0x95abc07290abd2daL,0xd0e30e99232035cfL,0x3dc4e1bcd3f0ecb1L, + 0xa5a8c6e556de9d17L,0x878c7403ab73bd18L,0x5cce39260c474b0aL } }, + /* 62 << 210 */ + { { 0x86a3f001e93b6ee6L,0xa28984474fb3203aL,0xbca0d71e9b3550adL, + 0xc225759d0396d796L,0x208b9a02cbd949d8L,0x15b21ec9a550d2ddL }, + { 0x64aaed6a2a7dcffaL,0xb8cc7575ed5b6b47L,0x2b4a3aff022dbce3L, + 0xe85d690b86f51861L,0xe26a6c3d578f4d5fL,0x706d770a70e7ae76L } }, + /* 63 << 210 */ + { { 0x822467eb579c91a6L,0xe98a471531599272L,0x7baf0e9f1078d497L, + 0xd13f270e25fe439cL,0xae9d58adc0d95395L,0xc3beb60827693037L }, + { 0x4d9c4cf397f797e5L,0x4e26167db26d2e9dL,0x06092d5e86a167efL, + 0x9827a21128dceb29L,0x30423344552a55ccL,0xae07b37f3fa437afL } }, + /* 64 << 210 */ + { { 0x9b23ab4e94d0864fL,0x46356266009c9fc1L,0xdbe99e51e798edf9L, + 0x38547449307675c7L,0x23ffaf55628c0fb6L,0x56ccd2a31698c372L }, + { 0x39f45a578347ce95L,0xe0aaec744f2c6118L,0x2a89079e4af138fcL, + 0xb86371ea2ee4ecc0L,0x076d256a06bbf92fL,0x9073adb8ae3c4c51L } }, + /* 0 << 217 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 217 */ + { { 0xba2e9543743c15d9L,0x7d5812db1c99c984L,0xf94db95145bdc19eL, + 0x951d00ae382e77bdL,0x9940a5fbb220b29aL,0x6908d50e58fc91f1L }, + { 0x682e42eadd0940feL,0x2124e23aa1d32009L,0xbe15810016294d05L, + 0xaea13fe32e326d68L,0xc0dfe1ef15e64fceL,0x32dbc0b5b8237a8aL } }, + /* 2 << 217 */ + { { 0x6ee65a08c36d3f25L,0x7b6c811fe393e4d4L,0xc4a2cc382876e523L, + 0xab7aba26d3bf53aaL,0x5bf00871db7f290cL,0x3cb1cd131ee6d5bdL }, + { 0x4cafb218de998adaL,0xa1ecf36af6319101L,0xa1fe785520b281ccL, + 0xe457198e64d9c65eL,0xa3d1a6d0c5a0e67bL,0x69ddbc3290cc468aL } }, + /* 3 << 217 */ + { { 0xd4ee3f7f6dadc46fL,0xa1f3dc925d7febd6L,0x4c0bee1363ebab5bL, + 0x70e32d77005ec237L,0x302fc73dc52fb006L,0x1af84c0a8f159899L }, + { 0x42a5478f0686232aL,0xb4fc56348a308687L,0x042c4970c8378f0dL, + 0x70c195758e2c86c5L,0x61a95e6884c7c767L,0xd96a8216d6fb43a8L } }, + /* 4 << 217 */ + { { 0x0c62fd2d543c1255L,0x71ea9c6fef361a27L,0x76b0933dcef3f9e3L, + 0x51b1ec2d9889ffa2L,0x9e84b2ba9a3c88d2L,0xc8996b961913e52fL }, + { 0xbafc5e94cee43e36L,0xd9898d2470c658b7L,0x4e9bcc41bed17108L, + 0x0db5b7336c7a41c8L,0xd4be07a7795369cdL,0xb899f92f7bd3a934L } }, + /* 5 << 217 */ + { { 0x1fffcbc010e15fafL,0x8447bdb8910245acL,0x857d521e86476901L, + 0xcd1d5f87369ccfe9L,0x560b3277b3f1dbf1L,0x4ac02a1a47ea4266L }, + { 0x29ac98b6a8a929eeL,0x020ec6db5e5e70c0L,0xb0be38ba21291be6L, + 0xcbe9d362bdba40deL,0xc585450571535a89L,0xc21839de3d7a3235L } }, + /* 6 << 217 */ + { { 0x831541b39805497aL,0x2ceb5ac879c414cbL,0x86601fa616d2eb82L, + 0x373d19079338ce8eL,0x98151a90c1f5c87aL,0x966ebde6048a538cL }, + { 0x5c4a8c5ae180ff7cL,0x6d9065dff996d994L,0x4e0dd86e2460ab91L, + 0xfbe8b3ff309a8f5eL,0x33d7cb35856f7218L,0x62b2200a1ac59f2aL } }, + /* 7 << 217 */ + { { 0xb36ad750a460e53fL,0x727006d60df0f7b0L,0x6ca3ac348ee96a11L, + 0xb04f6ae930e75d1bL,0x9957738a3a24e9eeL,0xc0117a7d16521e18L }, + { 0x79fcea8872ad7e27L,0xcbe2c2d37281e3b5L,0x31915f1cc391fc60L, + 0x1c1c0082a13a92e1L,0x362663cc7ddca7acL,0x8021aad689689d35L } }, + /* 8 << 217 */ + { { 0x3f2eff53de1e4e55L,0x6b749943e4d3ecc4L,0xaf10b18a0dde190dL, + 0xf491b98da26b0409L,0x66080782a2b1d944L,0x59277dc697e8c541L }, + { 0xfdbfc5f6006f18aaL,0x435d165bfadd8be1L,0x8e5d263857645ef4L, + 0x31bcfda6a0258363L,0xf5330ab8d35d2503L,0xb71369f0c7cab285L } }, + /* 9 << 217 */ + { { 0xc19db6f05890e1cbL,0xc21587edfcac8d05L,0xa9e88798d86730edL, + 0xee3e6ee2c27441cfL,0xadb2c63ea23af57fL,0xb524b7da29ff5977L }, + { 0xab1ed847d3e4739dL,0x6592a0131cbfb581L,0x1f519c6ea1798195L, + 0xfe837a814c324a4dL,0x74fec4a85c813abcL,0x7b3b5351dce539b0L } }, + /* 10 << 217 */ + { { 0xb886a0c50c99e321L,0x4063d19576e924e9L,0xc03cca041a659dcbL, + 0x1e01abbc1bd3dab0L,0x9d7cf04fe9141cd8L,0x5f87dfa73ef58d85L }, + { 0xa579e76388d764b8L,0x381dec6a74b9e5b3L,0x354221f99a4c9a67L, + 0x8c2556d33f529346L,0xced3642bb4349eb7L,0x1527cec7fef5c92cL } }, + /* 11 << 217 */ + { { 0xf2e42ef7785ecd51L,0xca3438cf33d9c0d2L,0xeef9ec08c1c097f3L, + 0x9e438fa746682aa7L,0x53d0144531a7eefbL,0x04431241e6998a0bL }, + { 0x2c1bb2bd55bc7febL,0xed99e7afb44d4943L,0x7f37bc4a3c77d21eL, + 0x866c0978398e3997L,0xed7462305bde12b8L,0x24796f7c7194fd1fL } }, + /* 12 << 217 */ + { { 0x7e4450cd5e83d570L,0x0113cab242b394e7L,0xdf4062a08ee24413L, + 0xf8a0fd4931227510L,0x06b798f4b80f0d23L,0x33f17673b72bffa8L }, + { 0x4638602b5de9f490L,0xbe3a65834d905654L,0x446e0afaf406772cL, + 0xef68dfd7b4ec908aL,0xa6be004966ab5ebfL,0x56049360ff376531L } }, + /* 13 << 217 */ + { { 0xb47202b760b6ce82L,0x8129c1befe05e9faL,0xcb70cbdde861de07L, + 0xcf35fbc5af16b6d9L,0x60071beec9916116L,0x3aaa496ed057e63cL }, + { 0x1cb0bb12c356f065L,0x12dccccef4de0d26L,0xe3f59cf67ccc0d48L, + 0xd66f10b3d9569e26L,0x95f4d7e79d1853ccL,0x10313dfdbf651d5aL } }, + /* 14 << 217 */ + { { 0x779b55062a3d9774L,0x3785db08e0554291L,0x9b3a4eb8546c69dcL, + 0xfe36824dd22d8fc8L,0x037d9ac9471132a1L,0xc895e332a01e1c28L }, + { 0xe535ede71b5e2845L,0xdc90cd7c568743deL,0x3292b40b4691d367L, + 0x911fad21b4f16a4bL,0xb3c5f0eb455d018dL,0x2eb2def669033748L } }, + /* 15 << 217 */ + { { 0xfd1297a4307aa8fbL,0x021f242177952146L,0x17cc2d6f0ba72feeL, + 0xa265095d01a3a733L,0x2e12c2e7a07d5f8bL,0x27bb60341202224cL }, + { 0xb58b3fab8185dc12L,0x83467b977700f166L,0x98242e227ff9e1ccL, + 0x96b2a4d9f4b28f1dL,0x64113c3865ed82eaL,0x7dc9ab732ee160e8L } }, + /* 16 << 217 */ + { { 0xf16938f514c5969bL,0xde2e3cf0944b2271L,0x2d5095530b6490d6L, + 0x8432fef1a28a296aL,0x6f254dd08d26415cL,0x3780eeadd50c2865L }, + { 0x4f5bc455665b8794L,0xef31fb9e56cb7018L,0xbab8dd6e65e59340L, + 0x676baca2a56dc2eaL,0x38eea06beaa90e05L,0x26e64224174bada0L } }, + /* 17 << 217 */ + { { 0x309e9fbe109cdb79L,0xc2ed3566977d0e4eL,0x2891f30be6b944aeL, + 0x514bd4cf5022e070L,0xae9a22a98726a661L,0x1114a0c8c1916b06L }, + { 0xe1b4f8339795adecL,0xcc0f3824ed4dbf8cL,0x432c93c878096a66L, + 0xb9450e9da7d2ad83L,0x294b0c192c1e35ebL,0x791427038be5a953L } }, + /* 18 << 217 */ + { { 0x4d215132881faf35L,0x52171a5ceec736a8L,0x4788813e1ba561d5L, + 0x9ca022a7d35e399cL,0xbfcaab926c4b8d7eL,0xde62b2c007c7ec40L }, + { 0x7b46c2d96bb54e10L,0x2ce02e5a7d31e85aL,0xb757b699cd776c12L, + 0x08f122552c81b71bL,0xaca91e058aa6b02aL,0x35cf7bd37209279dL } }, + /* 19 << 217 */ + { { 0x24b5bc7086a04b9aL,0xd4d4c640612e0fbcL,0xb19ea7fcf732589aL, + 0xa18b6f4081fc63cbL,0xddd7211d84d88fe2L,0x7e8db6f72963130cL }, + { 0x8772908c500c491fL,0xa3bf747783fd8a41L,0xca54d0d34e3e9fe9L, + 0x9969471866b030d5L,0xc2f5fb98b1fd6736L,0x58d5a851d103fa45L } }, + /* 20 << 217 */ + { { 0xe4c16fcda97a5decL,0xcc4333092f1dd4b8L,0x8cac9da985d334dcL, + 0xb4deff204cda5a0cL,0x59eea4c9be70b1b9L,0x161e73a2ec5b7b58L }, + { 0x584c5e098b7fb4a6L,0x697fb795a3f7dd08L,0xc9e15f754bd4ba2cL, + 0x66d04f47c83df783L,0x0c03c2452efedf63L,0xa76a08c94a87dbb4L } }, + /* 21 << 217 */ + { { 0xde4e18c2da669a50L,0x0629350a480fb520L,0x84b3e68b7cac0748L, + 0xab718a12da3e1e9eL,0x3f5c5489cc26aed3L,0x81c6b6d42a57ab3bL }, + { 0xc4ded8ce15d23825L,0x2d753e6a20c6eb43L,0xbaa120ec555f3a83L, + 0xc72f9d3877e93abaL,0x4ce297d0373317cfL,0xf42b3e954845bc1fL } }, + /* 22 << 217 */ + { { 0xbf162c19d7480e46L,0xa7f45ea76403bf0fL,0x250e936c6c51cef8L, + 0x97ba086f1cd24b64L,0x271a22364cfb2889L,0x2685c98804dc4b48L }, + { 0x843bb75ac877f6a1L,0xe10cd5c799d5c7bcL,0xbe65eea1db60606aL, + 0x9019a9a7a10d0d74L,0x5614c0b987c62e5eL,0xaab2308d38240d05L } }, + /* 23 << 217 */ + { { 0xc908c6929a772e03L,0x73441df703928ce9L,0x36141b5bcf111c12L, + 0xf6b9e2f16c7c3e5dL,0x1f245a77722c5b57L,0x07e3f364635f65e0L }, + { 0x1aab7abf272597d8L,0x03954428d4fe8e71L,0x7dd58036ecae1b5cL, + 0x9b97c2f28c85b0f0L,0x68ed3dc6ace011e9L,0x8e4ab5ca1744a774L } }, + /* 24 << 217 */ + { { 0xe6a19dcc40acc5a8L,0x1c3a1ff1dbc6dbf8L,0xb4d89b9fc6455613L, + 0x6cb0fe44a7390d0eL,0xade197a459ea135aL,0xda6aa86520680982L }, + { 0x03db9be95a442c1bL,0x221a2d732bfb93f2L,0x44dee8d4753c196cL, + 0x59adcc700b7c6ff5L,0xc6260ec24ca1b142L,0x4c3cb5c646cbd4f2L } }, + /* 25 << 217 */ + { { 0x37daf7fd5a96d915L,0x1bba82e6d16a1332L,0x7558b642ce1135d0L, + 0xc9fcd6ce3abc5915L,0xc3762a20b93ad4d3L,0xef0cdb45e4e74f82L }, + { 0x809b91dcd26fbab6L,0x1264f72ea9b53697L,0x264699ffd7c827f1L, + 0x16d4f094d8c4976fL,0x244c90cd997df2caL,0x58eb3b1c76f77b3cL } }, + /* 26 << 217 */ + { { 0xb99e2dde1ed04268L,0x94247d202497b83fL,0x0c6c21d1fb833507L, + 0xa01e682fafab9c39L,0x4938108f4d84c3d5L,0x70b68c75347652d1L }, + { 0x458e814740e17747L,0xca752a14c3f8bb03L,0xaa537b4d8598d044L, + 0xeec3febb7ff102e0L,0x10ef3cad247fe4baL,0xe4de5b1b5673ac39L } }, + /* 27 << 217 */ + { { 0xbca2931378d0bb1aL,0xfcc237068e5c3fe4L,0x0f9d6b11dd0d67a3L, + 0x9aec22faae14bbd8L,0x75f8d86e5bda7184L,0x6bcad95759aeb4c1L }, + { 0xbb1224a5990a9309L,0x00edc04ef7193f45L,0x870c1647c17cbff7L, + 0x9855513c65031caeL,0xe5a2e2ded852b607L,0x540a4141e5671e25L } }, + /* 28 << 217 */ + { { 0xfb0e2f2e4d5efff4L,0xbf3b96e73a143fd6L,0xa18a037f18579946L, + 0xae02fd4ce48c8a51L,0x1cb139288745c177L,0x4991594a28c47832L }, + { 0xdce3b1d2fd51c1a2L,0x4e707213314cb09dL,0x5312de95ee323449L, + 0x4925c4e789389866L,0x2438fd9e28ca17acL,0x58fd2aad872dc0acL } }, + /* 29 << 217 */ + { { 0x75bcf0ef54ddedaeL,0x3cc75fc6f9077493L,0xc91b78df60f6b874L, + 0x7687a1d0622634c1L,0x57fdef4f82cabf32L,0x544819218e2671e5L }, + { 0x526cbb27a3c37afbL,0xe0db88340d1aec76L,0xa034badb73cdef1cL, + 0x165cdfad6281f26bL,0x5c90d4d1ce24a71aL,0xc404af1125f297a7L } }, + /* 30 << 217 */ + { { 0x6b21a0ea2fd5df44L,0x2da8dc6cb36e5b1dL,0xa683e08ac3688655L, + 0xfc5fbad3454bf878L,0x9d2fb9f12f73b749L,0x4612cf42f920b37dL }, + { 0x23da6b697035794dL,0x2763828adff7c198L,0xd320660522dd7eedL, + 0x6829994cd1316e68L,0xd732bc8f62831ed9L,0x69c6972c9303d789L } }, + /* 31 << 217 */ + { { 0xf5901854b0dcc28aL,0x81c92c1fcd18e579L,0x91a412ebc4b8e1cdL, + 0x35f00725891d6ab8L,0x10d6bad8ad7aa63dL,0x8cda809d09df2b47L }, + { 0xe856cfbfa489c233L,0x7ea921addf1ecf5aL,0x884cc717fd724c37L, + 0xe278f2457377136bL,0x240b142d9f3dc9ecL,0x80a384961139a645L } }, + /* 32 << 217 */ + { { 0xa35e411c2cb40964L,0xdd7d4f4cc331a3d6L,0x7c7c859e89a66f2bL, + 0x9908c37e0def8ecdL,0x8274124e344947b7L,0x0d279f7b568b0ce8L }, + { 0xe5291961866091ecL,0xb056e3bf3a08acc7L,0x60fb39e156bd3a7dL, + 0xe56a34d6268f8562L,0xb3a1fe1613fd8293L,0x6a41e1a967537fcbL } }, + /* 33 << 217 */ + { { 0x95c2bbfe021fc932L,0xc7e3399db2af7e0cL,0x1224bf06122670f7L, + 0xc9e4513ffcc1fe85L,0x8c82371ddb50fa7eL,0x017c5498bb76e4b5L }, + { 0x5467926c7fa89f61L,0xa4a65606f3a1204cL,0x22133acfa64b2e59L, + 0xab7896bce1247662L,0x75d35fb661780c9eL,0x99199644a91b33faL } }, + /* 34 << 217 */ + { { 0xf799c4638471104eL,0x43c122dd8b91c351L,0x9db6498616dc06f7L, + 0xf7e534410ebcf250L,0xa702c0f18373f9bbL,0x6ed8d39a1024e14eL }, + { 0x92913e436cabd9c4L,0xba906ef40dde6283L,0x06835e914a3972d8L, + 0xfbba3c7dfd99c4feL,0xf843e6f1b950909aL,0x7ec9866df5160b4eL } }, + /* 35 << 217 */ + { { 0x68f75bab06722bd4L,0xdeca718813066eeeL,0x4d658fa11152b8c6L, + 0xfae01e657257c9e2L,0x999445f923e4189cL,0x2cbe272cef6f0b1aL }, + { 0x5f60d9d735fff303L,0x4ca7a54696235360L,0xf506201598758f1fL, + 0xba81e7ad1dbaecbfL,0xd326e063c687425dL,0x8c46fa4b193484c5L } }, + /* 36 << 217 */ + { { 0xa97149cf3c1f5f12L,0x17b04a3d143d72b6L,0x174195ff17449a22L, + 0x851803960b136adfL,0x8d87d21f9a7adb22L,0xf9c9fc85a8f46d49L }, + { 0x7839f453a7ed1b7dL,0xe19d80ace9067ba5L,0xc387a6a0e41b8d6eL, + 0xd11611e1241d287aL,0x2561ed02636240beL,0x3bd8c57df0fba033L } }, + /* 37 << 217 */ + { { 0x7b5caacd3ea8ec1cL,0x221770e944624802L,0xafb1a4df5a32468aL, + 0xdec20eb62e295525L,0xe1cd4fb9e309c92dL,0x0331b9c0e7256005L }, + { 0x987d4c55246f2fddL,0xa392d27367f70f8fL,0xccba11994e214e5fL, + 0x789f0e4c9943562cL,0xf502ec237235c86bL,0x67403523987746d6L } }, + /* 38 << 217 */ + { { 0xdd02ced216c97e7cL,0x578d6912dc3347baL,0x760260da2134e993L, + 0xf96643dff34fb26aL,0xec214b767ea3285dL,0x19b135d4117733d1L }, + { 0x29a0e0636b037168L,0xb5df2bb95d1285eaL,0x5a2d3297796f0cc4L, + 0xfcee639f2090e0b9L,0xba11e8a4d93c091dL,0x5b6fc501492250e5L } }, + /* 39 << 217 */ + { { 0x6019d207263929d8L,0x9821d6e81f164aa2L,0x8f1b33f8d4924236L, + 0x389e482fb72de1b1L,0x398785a862554c10L,0xed31cf8408469265L }, + { 0xf9b99e158a09f334L,0x9ddfd4eba83df391L,0x28a5cdf4caa4f7d5L, + 0x32b9e3c68f68fd49L,0xbce64b93b6f52209L,0x72649c6fea7c4bdfL } }, + /* 40 << 217 */ + { { 0x8a15d6fea417111fL,0xfe4a16bd71d93fccL,0x7a7ee38c55bbe732L, + 0xeff146a51ff94a9dL,0xe572d13edd585ab5L,0xd879790e06491a5dL }, + { 0x9c84e1c52a58cb2eL,0xd79d13746c938630L,0xdb12cd9b385f06c7L, + 0x0c93eb977a7759c3L,0xf1f5b0fe683bd706L,0x541e4f7285ec3d50L } }, + /* 41 << 217 */ + { { 0x73bc200cfdd5504eL,0x73322fbf3825b0c3L,0xbf8bf1edd35c24d2L, + 0x54eba9f52e2bc29eL,0x80ffb5fff3aa841bL,0xbc676f62cc188be9L }, + { 0x2e2f79290383f0dcL,0x886c647e0d42059bL,0x673f0ea113eb7019L, + 0x630da63f3f9cd771L,0x2597592b3a0a42b2L,0xfd21fb21b83b8673L } }, + /* 42 << 217 */ + { { 0xd39ebb9fd2b34df5L,0x622bd0c3db873666L,0x546cc7f77b52738fL, + 0x0323cdd1c156c52eL,0x78b00818b5950f19L,0x8065a86a562bec17L }, + { 0x0b42eb1427ca5a49L,0x1791eaf1a457ac04L,0x3a2c93a6b2631402L, + 0x28b9cd6fcacec5dcL,0x6a0a8826d4535a3dL,0xeb08a884a83fcdcbL } }, + /* 43 << 217 */ + { { 0x16bae8925a940b6dL,0xfec394c1789562f0L,0x54349605ea412ea1L, + 0xccd57783cd18e2cbL,0x394bea1a1c813e61L,0xf11c566ff249dd67L }, + { 0x2cd679c112207f37L,0x7780918e83d16012L,0xe8bdbef4646c9987L, + 0x6e1882e5082dbbffL,0x811dd74777abe4acL,0x5bbbb740668380adL } }, + /* 44 << 217 */ + { { 0x0969263a7321c39dL,0xbd13b28bab7aefcaL,0x10e431f205377165L, + 0xbbb2a7d009442c57L,0xf935bc2d9cd156b7L,0x66c3d55e42406686L }, + { 0x4c529b76d20bdc50L,0x112e0f004d1c9f24L,0x414f1c65ed38dbc3L, + 0x63ade49c4eea65caL,0xbefd8af5fab697e8L,0x727bd3b45cc3b209L } }, + /* 45 << 217 */ + { { 0xb89d450a957925f4L,0xcb39b69c6e1e60f3L,0x55396e61ae3fffa3L, + 0xe89d97962986fdceL,0x5521d6b787fcd037L,0x6c20b2b0ec718024L }, + { 0xb1e0964bad6529c9L,0xe1bdaba3bc38493bL,0x6a9cf9d6f19b4690L, + 0xa2d035f7054466dcL,0x37df7fc07fa65c9fL,0x045b0b36106ef822L } }, + /* 46 << 217 */ + { { 0xe4fc833eda5c9577L,0x22afb5addfbbca7cL,0x215de02eb902e8d9L, + 0x215e4c900f1a6cb5L,0xf6d7e4a9d59e146cL,0xcd0c6c6e4912eb8cL }, + { 0xe0616976eae22897L,0xe2279d9f5d809d19L,0x2da1b7b3e282b2e5L, + 0x19327068ebf058b7L,0x9b23df0f5934492eL,0xabeb464fb1752d68L } }, + /* 47 << 217 */ + { { 0x6e754efc00d03f9bL,0x64aed0bd38b94393L,0x9d084ba16df2f6dfL, + 0xfe383a56c6abe8f3L,0xd23c6ca2bc7bac13L,0xde8ef161e326b691L }, + { 0xbb4e853342f96925L,0x1391974f6601dc73L,0x3a545ffb700480cdL, + 0x4d379c538884e214L,0x0fe40f66f713e900L,0xc7f202cbfff783ffL } }, + /* 48 << 217 */ + { { 0x89e48d8bc6bb5e5fL,0x0880ede01ea95a10L,0x60f033d7302c0daaL, + 0x15e4578a048eefe3L,0xfd6dec89b0a72244L,0x1f7cd75e309489cdL }, + { 0x7cdcc2a0e9aba7fdL,0xd18dc5c7f28ba00fL,0xa6300a455812b55fL, + 0x8fa5c4152ca31d8cL,0x36aa3c234f3a5b5aL,0xd128739ec86cf4e0L } }, + /* 49 << 217 */ + { { 0x7ac4712f660598aaL,0xe3f00c28aaba6261L,0xb71ac42e1a9b639bL, + 0x19674c28f69958d0L,0x3983abfec4e5c60fL,0x67f4583a5de58f9fL }, + { 0x83e0bbbaf7278c06L,0xd1883aaa19c5f96bL,0x8ec0f2848b3128afL, + 0xc88e07f49166e04cL,0xa515a9e44e3995c9L,0x0680a306b757ec2bL } }, + /* 50 << 217 */ + { { 0x5673b61e6d6f3aedL,0xcd1275e29524fd2dL,0xa8844f08cde12134L, + 0xeca3eb27b8366e0cL,0x5ce49d498bbe04b4L,0x0b7ab7a02882b056L }, + { 0x12fddcb840fee142L,0x99b7920b2895df5fL,0x35dd8d5a5829bb19L, + 0x271c6a4c46ee8dfbL,0xae09ba7536b594e4L,0x45502d0e1ae12c22L } }, + /* 51 << 217 */ + { { 0xa9e1b19ad95e0110L,0x6a419f8b2383280dL,0x6c35e8e16eb602a6L, + 0x966e0f44d71beeeeL,0xfc5cbdc0c8915585L,0xdce1c36583133b89L }, + { 0x3fbdd24289e6a35cL,0x8cd24d1760ff9dc3L,0xb9708c2729dd493fL, + 0xabbf39803cf807caL,0x62689ffe5410c80aL,0xf133928be8b31d13L } }, + /* 52 << 217 */ + { { 0x3645a1910d4bfc83L,0xa564ac85f2114b63L,0xf0647034cc6d9314L, + 0xb58e96d331d80285L,0x8b8222d9e269c964L,0xdee12adcd204b214L }, + { 0x82d2bfbae1d0a6e6L,0x4fd69d2e9da964eaL,0x1605d9e3200b3ac0L, + 0x5ab2886266d133eeL,0x938411c9f72f5353L,0x9fcdcb3a7d40dee7L } }, + /* 53 << 217 */ + { { 0xd65c1d6c501eb835L,0x37374dd14a0e5861L,0xa13f1070505f1fdeL, + 0xedd76943d1351805L,0x0f9501953673091dL,0x0dec24e308aa62f2L }, + { 0xec4962e7f50efefeL,0x0acccbdc9d227293L,0xc6c95d29d84fd828L, + 0xa4b214c540578ca4L,0x06963d3ba4d41991L,0xeb8c14c2fde0034cL } }, + /* 54 << 217 */ + { { 0x3d46a2317460e00fL,0xedce1c7dacce513cL,0x3d7b6f388cfdce74L, + 0x870082baacfa61deL,0xa86efef862ff847dL,0xc146218368c11d11L }, + { 0xb296eede9d21be2aL,0x9dc54e9e761451cfL,0xed1bb1fd53107f7bL, + 0x41f9efdb676bfbe4L,0xcdf43b904feb9a1eL,0xe81fcb6409d98782L } }, + /* 55 << 217 */ + { { 0x00639fa8642789c3L,0xf8e893a03c101e43L,0xc55439302730e33bL, + 0xe2967d30460970e2L,0xb33f1976ceacc128L,0x9bb0f896235e8c4cL }, + { 0x523f7bbb2fbbbc97L,0x127728a5dab215c1L,0x95dd23ca7ed6ab74L, + 0x69f1219feacf4ba8L,0x5ed12355e875dd6fL,0x7aa732dc95565bdeL } }, + /* 56 << 217 */ + { { 0x9a0e153581833608L,0x5cce871e6e2833acL,0xc17059eafb29777cL, + 0x7e40e5fae354cafdL,0x9cf594054d07c371L,0x64ce36b2a71c3945L }, + { 0x69309e9656caf487L,0x3d719e9f1ae3454bL,0xf2164070e25823b6L, + 0xead851bd0bc27359L,0x3d21bfe8b0925094L,0xa783b1e934a97f4eL } }, + /* 57 << 217 */ + { { 0x0a700190a5e41f7bL,0x2173e68dae9045b6L,0x28e9ac53f1669974L, + 0xcb00ff99d4b9fd98L,0x09c7b907ebe90d1bL,0xbf401f20385744c1L }, + { 0x0bb7ea7ae1292c18L,0x82aa43120b58f171L,0x5aa97bb2e3102d77L, + 0x1a71e7c570178b35L,0x9bbb9ade6ab76f59L,0x32da60c9dea7bcacL } }, + /* 58 << 217 */ + { { 0x3c3f113ab3726680L,0x27be1c406f5b5ab2L,0x5f51f684f6864a39L, + 0xfaf84229a60c4f39L,0xa788612d01df18c9L,0x65c9fd14951d5ea3L }, + { 0x4b2153cdaeeaf44fL,0x6b9e977ba567781fL,0x4dbca3609dbf3e39L, + 0x1ad43ad4fc65d7ddL,0x70a7a5e13d8dcf0cL,0xc11b1f4688b91e4dL } }, + /* 59 << 217 */ + { { 0x1ef5695b0868ad28L,0x09c9c06c2e3a9176L,0x2f2c19672c358e86L, + 0x4ff1af54da22d7e7L,0x5ea6716840fa2270L,0xd164b6874d31a3e9L }, + { 0xec036bb4345103d9L,0x6c6a130f26e17156L,0x2c491063d872b0d6L, + 0xa66be18c4123d04cL,0x8593de34a33fa919L,0x620d2970f025b880L } }, + /* 60 << 217 */ + { { 0xc194cc1664baf040L,0x8038f31fcc01f35cL,0xfcc82fa0ed2079c7L, + 0x1eb7571190d39b9cL,0xf1a89043c108e069L,0x10633334c020880fL }, + { 0x492a494086e262f8L,0xaa0208173383f1a7L,0xfbb4e5ba6d99cc07L, + 0xd6ccdc5cbde40478L,0x9e0b9d5867ee92c7L,0x5204bab7653eb14bL } }, + /* 61 << 217 */ + { { 0x721f44f0ef90c9bcL,0x6ebbecd8d55e653bL,0x9af325df6ccc5d5dL, + 0x265f0f6d827bd1aaL,0xb82453213487ea4bL,0x1642be42af6ba8d0L }, + { 0xb8c4168d4140e5f8L,0xdf5e32c13545d107L,0xf1301b9c2db68318L, + 0xb22e20472bf3c067L,0xf40af49ee56ba514L,0xf4090e795575f363L } }, + /* 62 << 217 */ + { { 0x980de58b1746f6bdL,0xa9e1f0089eb9511cL,0x8f53c6fd1bbdba34L, + 0xe6a867a6a1a41706L,0xd4cc48a5d2e48256L,0xd580559e05cb19d6L }, + { 0xc8983311e6466ae0L,0xeab62080174df01dL,0x710ebd184a0441d1L, + 0x0af69d9a9f653d0eL,0xef3a2510d789c932L,0xb5959cb992fbd39aL } }, + /* 63 << 217 */ + { { 0xdbbdd5fdccb1cc9bL,0x660110b98a26d874L,0xfa80d8b60fb9ff2cL, + 0xfeb5cd6b95040da7L,0xb526ae0c7366cf25L,0xf49d85fce3566146L }, + { 0x3b4107e699f505e5L,0x3c2d618f4302bbaeL,0xdaa09d150b199866L, + 0x3b65cb88c395abf5L,0xd2af1dedbd5ac4eaL,0x0586f5a5276533d1L } }, + /* 64 << 217 */ + { { 0xd927283013575004L,0x01a330d620b2275eL,0x58b9207f450db713L, + 0xae95338423e16d95L,0x4f10c6d4e60e349cL,0x541d03ecfeb122bcL }, + { 0x22548cd22c648211L,0x5c2dc84cd01354f5L,0xa1c6f912b6167b3cL, + 0x6967bab27902d2baL,0xebbe0b0836de34baL,0x6985b33a4b79625eL } }, + /* 0 << 224 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 224 */ + { { 0x9e857f33771560abL,0x4ae1ba22250f109dL,0xf8538d68ff4f6566L, + 0x35380f15ac339148L,0xfef0bfdd5ddfc12fL,0xf706c6bf1387d93eL }, + { 0x618ce77d5357e131L,0xf0921744236478c4L,0x24eaf06e00dc0da5L, + 0x049113be07603cc7L,0x5cf489088f6963c7L,0xbe5eb9e6ede4a300L } }, + /* 2 << 224 */ + { { 0x77e486f85d066c15L,0x0c05b6c24ed5307dL,0x322b28ab7df36628L, + 0x2d14d1316704dcd6L,0xd359977af29a3567L,0xc29bb132ec96d3b6L }, + { 0xfd6e400ae6bfa701L,0x03db99244c7e5101L,0x62d81c7d9b8533afL, + 0xefa638c28de66eb8L,0x7405a9d7e86784eeL,0xafaa74efa6c22223L } }, + /* 3 << 224 */ + { { 0x6909994f0572e536L,0x9d22f9157fed8954L,0x1505ca05884aaca9L, + 0xe4b6530996995a98L,0x30e00a5ed02c000eL,0xb9032350236e7b09L }, + { 0xe696f09e14f6c7bfL,0x2126b6277dc18d06L,0xa9ada7b401e1e2a4L, + 0x9630acb69d2d025aL,0x9fab2c6ed84ffeb1L,0xc1d0db26ab7584f6L } }, + /* 4 << 224 */ + { { 0xf9b2dba4b9d36e91L,0x5fb4f6cefda9b2c4L,0x7692a4f33b8104eeL, + 0x5da885b0e4e1896eL,0xc2a30fec73d2aa36L,0x7d06e6af86f60bcaL }, + { 0xbc8bf16d87287887L,0x6c3dd86a3d701becL,0x8e79e2f37e35610aL, + 0x981139f482f9d71cL,0xf8997ec424e62733L,0x330d989aa3518061L } }, + /* 5 << 224 */ + { { 0x6cf0e6ef9b7e3cc9L,0xb465be6b0320acbdL,0x02777783856111dcL, + 0x3a1d36f0c0e9f2b0L,0xfcf4f6365e7fe507L,0x36bf41827fa7c8f1L }, + { 0x09a02de8b0f4ce56L,0xa0bbf65ca9cdb353L,0x7211a9654b7f4e35L, + 0xa6b2ba79805b58bdL,0x418302c20957860cL,0x3c17ec02f99f9d58L } }, + /* 6 << 224 */ + { { 0x4e6ef410ca89fbadL,0xe0fc53ba53933b78L,0xa4f03403fd41d143L, + 0x3a507177e0774c37L,0x078e8c568ec7484aL,0xfb73c6b6fbb3f66bL }, + { 0x169c94753bfbdff6L,0x44d286060a232243L,0x3e8e968508303114L, + 0x7a9797b8fad0def2L,0x0ad14404efc1c8daL,0x6daae4e921ced721L } }, + /* 7 << 224 */ + { { 0xfde0d1b4cbfd18abL,0xa3c9917595850f83L,0x16d3ad79c9eb9de3L, + 0x2707ec8b0ffbcdacL,0xd7e6750fa220287cL,0xe51baf059c2e155aL }, + { 0x3018c309871e10faL,0x074f08e3f23221c2L,0x1aa323aecf15a4afL, + 0xf085d69cc1b8cca0L,0x47a3eaccb143a969L,0x56a04522f3a98430L } }, + /* 8 << 224 */ + { { 0xc7e9ddef88dd2dc2L,0x2c21a99819a0c0b5L,0x6bc0746db239bb82L, + 0xc811a8eb28ea1341L,0x5f714ca71d1309b0L,0x79eabd20d4eb9b34L }, + { 0xe0e5afdcdf0fb30fL,0x1b01a16d8c0814c6L,0x670e1e7b84334366L, + 0xc8c38f9a0eed1116L,0xf914fae2619bbd50L,0x1ed062cb51c1995aL } }, + /* 9 << 224 */ + { { 0xce64d065b711b4e9L,0x32760c2eefc4d25eL,0x9e5916caa6292c7bL, + 0xa90d40bff2a47deeL,0x90dc6681604933d2L,0x707270c60115cf42L }, + { 0x55b601ff6fe583abL,0xdd2fe842a039dafeL,0x602d8de34c2d3357L, + 0x7cc979bca7ab9014L,0x4b8dcf7e60118797L,0x7f1f2a04cbfaad32L } }, + /* 10 << 224 */ + { { 0xd4e60e15cb583422L,0xc6b1ef90320f296fL,0x0714bad0d9bfc834L, + 0x5ee2ca8c9050e2c2L,0x074a8ca824f7cf1dL,0xb975024910df8516L }, + { 0xecee8ab7c2636d2cL,0x308e5af13b4b7bbdL,0xfed4f27eee2ae021L, + 0x7cd4bb192065253bL,0x6b21a3f84de525b4L,0x0f10e7bdac27fddbL } }, + /* 11 << 224 */ + { { 0xb4f02d9dbb3bf37aL,0x69590395978aacc1L,0xdf99b1309c3def3fL, + 0x5c66391e12be0bceL,0x30ab382cb5eaf100L,0x9b84b2b4e0352249L }, + { 0x0c22e4e1af14e85aL,0xc29d3c592286ea0cL,0x6c7f8b6a40758aebL, + 0x7a91adccde68fd0bL,0x4d8554fec8e8fd4aL,0x9fa863d5bb5621e5L } }, + /* 12 << 224 */ + { { 0xd5068487870e29cbL,0xf9420b85fc52d5cbL,0x50c3265a496d000dL, + 0xe605414a166bd6b4L,0x4de8d724c62b2a6cL,0x16af06f2a1a11048L }, + { 0x5406bde945f43c4cL,0x5e15bf6c751ad18eL,0xa846e665b6a59587L, + 0xcdb28a7d1816ac55L,0x899b3551819b73f8L,0x2d46297bbc848d08L } }, + /* 13 << 224 */ + { { 0x76f5aedd44af60a1L,0xf7bd3b4651d1efd8L,0xdfbf3c6439a9721eL, + 0xf927fbf0ee9d2ab3L,0x628e9258c7e0779dL,0x062cb2fe4cf1dccfL }, + { 0xb2ff57dde2278f00L,0x3f0e140a2d199ca3L,0xe7161304342c0a9cL, + 0xe7ca734f0bdbe131L,0x7d070270870057d8L,0xf6f1a65daaa55860L } }, + /* 14 << 224 */ + { { 0xdc4cc720299127beL,0x5b34e762faab8165L,0x2289b2f7b39c120dL, + 0x687a78d06e52b913L,0xd2a091dd2a3ea6a5L,0xc61eced638eab329L }, + { 0x652231ea7887ff2bL,0x77a568750479db4eL,0x1ef471c8d43c5722L, + 0xf82bf436f3764c34L,0x962af4050445cafeL,0xed8b227f5ff47259L } }, + /* 15 << 224 */ + { { 0x30e045f4a73c3da0L,0x13d2527df36c6346L,0x3dffe56d3836fb9bL, + 0x9518276617c5d2bfL,0xa0ef38724dd0b240L,0xb45e19ebc39c675aL }, + { 0x65202bc603e95445L,0x41e2f0d19a2ec9dcL,0x51c719cf2a0d762bL, + 0x3bfb9729ecc6b9f8L,0xda8271705a261640L,0x65c2bbbcaeee5f3fL } }, + /* 16 << 224 */ + { { 0xde849cd1d89594abL,0x00e2d2b10ec4fb3aL,0x3fbd9e3dabe92fbaL, + 0x785414d43324900aL,0xdaead1abde20904eL,0xb493e121aa5f1ba8L }, + { 0xd60a4f2d6eaea0dcL,0x394746b56fca8596L,0x163dc78934efa243L, + 0x3067dccf216a8d8cL,0x116b6534a901617bL,0x8c4bd099bbabe51eL } }, + /* 17 << 224 */ + { { 0xbb9eb22a97ebad53L,0x791d4f90666f1428L,0xa3a896e06c5d5569L, + 0x322d566fdefbc26cL,0xaa581a083c039c26L,0x82d899be62790f0bL }, + { 0xeff4bb9a43a0c2f7L,0x60515c10a01df2c4L,0xdd1455a849312160L, + 0xc8a15052c4292265L,0xdb2970f97f68d081L,0x29c825b892594c4dL } }, + /* 18 << 224 */ + { { 0xc8c2df45ac3a082cL,0xc353d074c8d4c40eL,0xb214f9c05a3c2de7L, + 0x504bc42cf86b0214L,0xc82df5cbd1922a58L,0x40887948a5bc3267L }, + { 0x04bcd21788ba8bb2L,0xe21b3e7f046fd401L,0x8419c338616af5cfL, + 0x7f24760baedfce9dL,0xded8035bddbd519aL,0x1f1fb0d71693faabL } }, + /* 19 << 224 */ + { { 0x7a88376766117f71L,0x8d4e37815d261599L,0xc900e6dff770b193L, + 0xb7d1c06b12e9dda7L,0xa86d173a717cb0faL,0xa138b7ba51dfbeacL }, + { 0xe84468c57360a27cL,0x4acf8b412e9b82a2L,0x85fa386cb121d6faL, + 0xc794d9f283e6169cL,0x7b4cd3fc8c9293acL,0x3096ad868d082719L } }, + /* 20 << 224 */ + { { 0xbb067b49d02ffcf6L,0x7cedf8f93e657299L,0xc3829961406bbfe3L, + 0xefe4b5aa37c12472L,0x7dc01cf9fec7dee8L,0x70a9db2389472f50L }, + { 0x29c269f8b31bf737L,0xa26deac3ae3fa7dbL,0x0046e91233caca41L, + 0x3bf4bc8ab6e78b55L,0xca83bc6cd9eb5ef1L,0x73f25c62c0c5deffL } }, + /* 21 << 224 */ + { { 0x117bb83d3ff7d803L,0xe91098c539c56c0aL,0x7bf72fe91e347fa0L, + 0xa66201a31e174941L,0x1d069d4d6846a06bL,0x721cdbbdcda59bcfL }, + { 0x17d6683a17652893L,0xee1b28f505be2530L,0x2e70558697a69062L, + 0xd4b5798682b56c36L,0x1ccc5be09082e781L,0x42e0e429d6b05e30L } }, + /* 22 << 224 */ + { { 0x697dc47d44b4aae8L,0xb3525cc0782c331cL,0xff71cca40bd7c78cL, + 0x5f3d776610c0ab69L,0xbdc10267e2ba07e3L,0xc656f75ce6373f6eL }, + { 0x9e2938b4b5607b62L,0xa65017d410b0a0f7L,0x8dad31195cc6ac25L, + 0x00f8f2d18ba5d1e6L,0x608137bc43305aefL,0xddad34bbdcb81cb1L } }, + /* 23 << 224 */ + { { 0x9e46b17c20c78a64L,0x28db365d5c48e678L,0xbe4c3b8eac6ba470L, + 0xee737236b6617b28L,0x81c5b94a4f3422bcL,0x4d44c33076faa922L }, + { 0xd7a09a719be38835L,0x99d024e1410b382dL,0x103b67c36b15012eL, + 0x02b6e094d9808da4L,0x4f5d938a0a7f2fcdL,0xa43058b7e4c5073bL } }, + /* 24 << 224 */ + { { 0xe133d941b1f82ca5L,0x2af8b98bfdf115bfL,0xdc6179c857aaa6f3L, + 0xabaa83e9130ade06L,0x7836b6fb0e8bffd1L,0xc479751ffa103703L }, + { 0x0ff3c1299c89963bL,0xe64072560b84c24fL,0xa92a4ea2f34f6bc9L, + 0xba45b3053197989bL,0xd12b5a0199243aabL,0x3015772c442af625L } }, + /* 25 << 224 */ + { { 0x5362ac737e0a5c36L,0xc731132a8c4fbc07L,0x0ef7468d7ca0d4d0L, + 0xc43afef835d25de0L,0x096bde6a3fa1209bL,0x21f57eb566846236L }, + { 0x878b585cf04d23d7L,0x737f7e527315ed56L,0xb716462c811afdd1L, + 0x4d223734a571a3cbL,0x56460e2fa7db2c60L,0x0684d72c61f97485L } }, + /* 26 << 224 */ + { { 0xd95fca81e6f065c5L,0x45e886d5fc8655deL,0x3580957727cff79eL, + 0x92a39a34625877d9L,0xdda02684dfee17eeL,0x6354f871986f635bL }, + { 0xb3a6e9edd409c182L,0xf0b1c8d9c4fbbb3aL,0x28721c019b77adedL, + 0x3c356df1bf94f028L,0xff221bd229a81f1aL,0x20edf2e856b20b0dL } }, + /* 27 << 224 */ + { { 0xb8c636db31ac60c2L,0xf3830e72bd987402L,0xfe63957c30e6b969L, + 0x3508e67989eb2bc4L,0xc0837f8c9a987e3bL,0xd1d0ce7b3f9b2ef4L }, + { 0x08d8f99441fe62baL,0xe73f79d7e17669d4L,0x8801fabaee6d68feL, + 0x4ef814891a508a88L,0xcc851bb71fbc4512L,0x69f728704680b88aL } }, + /* 28 << 224 */ + { { 0x97fff124835fda9eL,0xa79ceb2f0bc68512L,0x70ba93d1a2fc3995L, + 0x62bd28ab9e51c5eeL,0xb95fa624d5bbbaa9L,0x0654dc458c1f571eL }, + { 0xb9a4edc665a45ed6L,0xbf5ed1bc21ad0612L,0x74adc1a1b1a3551bL, + 0x3dfa3dc8dbbd6cefL,0xce5dd40b2fa3afd2L,0x14894e0f30a746caL } }, + /* 29 << 224 */ + { { 0xe4544006ada9bf7dL,0x9e123b709b75770dL,0x903628d557cea95aL, + 0x6429e00c9e8cef6bL,0xafa2cce77b1adaa2L,0xf2f5771e15e488daL }, + { 0xda44962269820874L,0x5b20ef1b6e0fef81L,0x3150a8699507b4faL, + 0x901897add191de20L,0xf459da31c41dbb2dL,0xc2516dd077146754L } }, + /* 30 << 224 */ + { { 0x7e729c58b8ca2a2cL,0x0f32ea1ecaac04afL,0x47267f13bdd549e3L, + 0x35b9440690be3b50L,0xad0f2bb14b27f670L,0xd7e5874e92341803L }, + { 0x7dc841cf1f9ec462L,0xebeff994512b2a42L,0x22998a7f320dc858L, + 0xf08eb5c719946f59L,0x228c8dcda68ea75eL,0x40dc6dc37b20dee5L } }, + /* 31 << 224 */ + { { 0x23f40e331dd722adL,0x0a441bf4c54fc48fL,0xed6c026548b75f84L, + 0xc2d3972f3e0fff2bL,0x889b44c4db09b7d9L,0xeb6ccc6541a6a562L }, + { 0x5ef1162e8f04e03aL,0x25e2ea895d8102c5L,0x37b71631154644d5L, + 0xa9a1a8320446b1bbL,0xe3f58daefb342b20L,0xc6d19decb6d292c3L } }, + /* 32 << 224 */ + { { 0x929454f6b3952db4L,0x412142ec4d3f69f5L,0xf5b0a7c5ee25c0b0L, + 0x7d3372ff2e752295L,0xd6dadc7d6eacac68L,0x5f0076cca96a8e3cL }, + { 0xea831db671725b3aL,0x4a286c89c29ab454L,0x5ff817e572e3c00cL, + 0xb022e25d2a5fb6baL,0xb611c5bcbb392476L,0x062c14dc190485a0L } }, + /* 33 << 224 */ + { { 0x44730047ffdc9a7eL,0x44949bdcf078d5bbL,0x8c1a3e4bc486e2b1L, + 0x53088ba20801402cL,0x6e20a7cfeac83daeL,0x4407ea8436ec5443L }, + { 0x564fb733853f79d8L,0x59ea819afe809670L,0x1ac62174f1ec7e91L, + 0x0d7e065566a0b8c9L,0x0c4d072482958221L,0x80db0297a60f984eL } }, + /* 34 << 224 */ + { { 0x380823e7f3359d47L,0x8a60fb05f5efd39cL,0x78a940669425487dL, + 0x1da6abc3f199c67cL,0x7df00b2165f0a6b1L,0xdc0dea58017b1231L }, + { 0x9c529db079f4f22fL,0xc7043be3e5dd92b5L,0x10153ffb43661331L, + 0x51c459bf6ff02e8fL,0x451483bfa43aa005L,0x3313f903199cd1baL } }, + /* 35 << 224 */ + { { 0x2f66587e62e1ef1bL,0x942d4c739e3ae33fL,0x4a27ead5c0ab9c1eL, + 0x368d8dd89ca91b06L,0xb3f0cf92c4b6ed34L,0x28cc332673e62557L }, + { 0x2649e5527910986bL,0x635dcf9cdda049abL,0xbbde12f625d3f201L, + 0x5200c3d0a9384443L,0xd996573d51eb3c10L,0xb093c1792b8cd7e5L } }, + /* 36 << 224 */ + { { 0x15cd1d1cc3fe6fa4L,0xf260a739e2c3c686L,0xf7c2270eb08c65dbL, + 0x9ada2cb6ff69d971L,0x65fbbcac212bff0cL,0x40157d075646a735L }, + { 0x101d2b7d55de9e45L,0x0db580e83118b763L,0x3203baca8322a9cdL, + 0x2a3137ef22cac14dL,0xcc9092e291a14128L,0xbb269f6d98cc368fL } }, + /* 37 << 224 */ + { { 0x7c8946002ad7f66fL,0x6a8328bb99b438a7L,0x86d06fbbdb440d86L, + 0xb74ffe2d20ac5a42L,0xc3a6f01d91b1c82bL,0x606f8ce71d5efbddL }, + { 0x8c49c43a6338c99fL,0x50657f7216da7cb7L,0x7f204c8b84f22d9bL, + 0xa2612d80ca76978dL,0x80080d868a3e8e96L,0xd8841a1ac0bff9afL } }, + /* 38 << 224 */ + { { 0xc2a734cb962fa060L,0x2baa26c580a17874L,0xe27b21110b44efe6L, + 0xdc1244e531d2154cL,0xfcd86d4116c7742bL,0xf45230df32503138L }, + { 0x94a790f4812cf0afL,0x0ab2df23da3f24d7L,0x0c764df181571d54L, + 0x989ff71c68d68f74L,0x9896fe62cda535b3L,0xfe0502e05f4fa41bL } }, + /* 39 << 224 */ + { { 0xf1ffe852c2f58cf6L,0x2ec46d2546d64576L,0x95bfec93d602c51aL, + 0x349c58bf3907b766L,0x59cb12bb9b94bdfbL,0xfa95da9515dfcd87L }, + { 0x731a8535e1543bfbL,0x14844aeeca14187cL,0x0d73e58aba1f4928L, + 0xbb71009fc6bb67f2L,0x5e7c0e988b4142b9L,0x4866b5095f08f58bL } }, + /* 40 << 224 */ + { { 0xc8295c2fa234de87L,0x1cd7f3fd878e77dbL,0x309c1fefa2155b6cL, + 0x2a9bcfd9484afddeL,0x87ef7a56cc999775L,0x34336cb1970aa188L }, + { 0xd45eb83cc3e16ba1L,0xf9d72c72b9c1695bL,0xff117458cb980742L, + 0x438a7fcb67af836aL,0x5ffad086eb9a6c40L,0xdbd3e518513922a3L } }, + /* 41 << 224 */ + { { 0xde241983e42021b7L,0xaa70e834542873c1L,0x99c9d35f9daf2b99L, + 0x0bf712d549b40780L,0x202d9969d9ab6e97L,0x7f3382dac4932106L }, + { 0x1eb5f5d40849e319L,0xc1bdd1179f659546L,0x628ddd3d2329f977L, + 0x5944611d363ee601L,0x7b7a631463d5bd4dL,0xaf6c51a5631d21ecL } }, + /* 42 << 224 */ + { { 0x2d8f9e1db4100182L,0xa08ae2fe4f3d2c03L,0x7548c430589e99f8L, + 0x0f5ccee2aede8af9L,0xa21ace3343b34b25L,0xb120c569dee102e6L }, + { 0x1cb103ed36f13699L,0xf71ff0dfc91e8cb4L,0x88f141079b22460dL, + 0x050af75af509366aL,0xeec8a310fb179bc6L,0x069e7331c26efef6L } }, + /* 43 << 224 */ + { { 0x3e2a9c713be9cdabL,0x8f235d6f73ac08e6L,0x3de28a6b28832dabL, + 0x7d08b9f31ee82d6dL,0x67c3b88f915ddda9L,0xba8f18cc0f7c81a3L }, + { 0x38cebc31ca3c0936L,0x745f71aa7816a6e3L,0x00cb85a91a95fcd3L, + 0xb92742c6577dc22cL,0x1afdaab592029cbeL,0x0bb43c91278d3f7cL } }, + /* 44 << 224 */ + { { 0x3d77059d3ba02d27L,0x58e28671440b2d3dL,0xe2d4235726636fbcL, + 0xcc448a52c54605d5L,0x73c2902efc0269a6L,0x28a15ed57ea8c26bL }, + { 0xf666587a0cfc1a34L,0x8374f2cc1ae0377cL,0x5dca6ae828417437L, + 0x15a6d54c94bc87ffL,0x5bf187bbb344796cL,0xc629c14889574b2dL } }, + /* 45 << 224 */ + { { 0x06d43c6d87748b63L,0x2489a957a7f232edL,0x7aa9174afa407c3fL, + 0x8c8b8fd933a762e0L,0xe2e8f1e7adbe94a3L,0xd1e0c8c2bb723045L }, + { 0xcafd8f483df092d8L,0xbc89caebb174025cL,0x97595c5649f20c98L, + 0x6e520a968a77acefL,0xc3dbd3107a52a4e6L,0xf51db5a91284ff27L } }, + /* 46 << 224 */ + { { 0x406465742c74cb2cL,0x44eeb9e546c33df0L,0xd2a9f16ecb4c50b2L, + 0x68f912a01906a6ccL,0x2b81296d95211e94L,0xddb2988ec8575839L }, + { 0xb74d990d33b180c0L,0x290185567d319c48L,0xd3d2e40dac8de56fL, + 0x9ad42a60461f30e6L,0x265e4715292a0faaL,0x56c2626c8ac3b2a5L } }, + /* 47 << 224 */ + { { 0xb7580f2fd468adb8L,0x8e1fbf0388a6a587L,0x1b8c40ed8f4f6cddL, + 0x337414f56817b2b1L,0xd877ebafb744d563L,0x59eed3c6df5e18b2L }, + { 0x365e148dd33afa01L,0x82e70adc665702cdL,0xccd77955a5e390ebL, + 0xd86c343accc90cb2L,0x23bd948d6cd8a33bL,0xb1fc140cdc43a8cbL } }, + /* 48 << 224 */ + { { 0xefda99d9ce11b02eL,0x9017bd4a3f820083L,0x8b9e6cd1ad14ac6fL, + 0x1239ee331f413880L,0xd98e93d993dd7fb9L,0xc280d252894fcb12L }, + { 0x33a9201a5230b5eeL,0xc6aeee256e41de26L,0x845051280d0a320aL, + 0xc20551db4b607b53L,0x6e63c766ea228c2eL,0x883321aeac48f25cL } }, + /* 49 << 224 */ + { { 0xa5173910e15a530aL,0xaa2c88b83ac38ab2L,0xcbfbd31ec6a6ba9eL, + 0x0fa126cb49ed182dL,0xd6b38897cfc53c85L,0x98d5f6bacb9c2f41L }, + { 0x6694e8e5cbd150e9L,0xd470ef226a1fc551L,0x57a63765d5ea1c0aL, + 0x95f5eb4318078139L,0xbeaba00585d3e0dbL,0x6bbf010fd314dec7L } }, + /* 50 << 224 */ + { { 0x5941229729ee46d3L,0x39e5aaa0e66bdfabL,0x9ff1575001c815e1L, + 0x709706211f2de195L,0xaac904a968aa571aL,0x9cbefacd8f7625f9L }, + { 0xadfd215dfce3a501L,0xc04d09ddf20651b4L,0x688c1421d17b25f2L, + 0x3efde5d40073247cL,0x999b7f3a7432c699L,0x33c76487703fea50L } }, + /* 51 << 224 */ + { { 0xc720aeb10af6e1faL,0x1564b8d8e8771dc6L,0x5983eb44673d8ef2L, + 0x5dabb2070679ac65L,0x51a854cdbcdb681eL,0xe2b186a9364a3cb1L }, + { 0xfa189eff7222208bL,0xf7161d86477666f9L,0x0ffcc3e6192d1df5L, + 0x1523508e39cf5a4cL,0xf5e98687c43ecce8L,0xbf17b63261450309L } }, + /* 52 << 224 */ + { { 0x63293cb8adfbde28L,0x5df78fb3c6b18ec4L,0xad10da4ffd27e50dL, + 0x60202b357ade5c9aL,0x67b9d253c6c8c8b5L,0xdbacffefbc2b30bdL }, + { 0x508ff8a67494b1edL,0x87ef48be3769728fL,0x74d4f180ef98d036L, + 0xc5d9ef531799e8a9L,0x726d22206e850162L,0xd86d3414239f6b38L } }, + /* 53 << 224 */ + { { 0xfdde327b3e1f1b96L,0xb6272e94bb58615dL,0x2881350cfc2d8a47L, + 0xfcbe87031142ab9bL,0xaa5fccd0f48c7f97L,0x606be6ed29a74ba0L }, + { 0x545409ba3afc598bL,0x4779f54aa7d23f5dL,0x2811c0829d68e38eL, + 0x5b4646bd3f9c5842L,0xbcd3aa492586219aL,0x7345799313642e3fL } }, + /* 54 << 224 */ + { { 0x9a61f240ab638788L,0x519742162b0a8449L,0x9a5ec31d43b2abfbL, + 0x6f3075740563c9c9L,0xe465f7793ffa198fL,0x8876c5772957418eL }, + { 0x10e3d09c976e5875L,0xd66d334e592c2409L,0x3f0d5727b39b7897L, + 0x17ca7ad1e37fd300L,0x221d8436da530871L,0x4df38e4179d6b350L } }, + /* 55 << 224 */ + { { 0xe805096338b7a2cdL,0x9874cc734b8f05cdL,0xfc0821791b74a790L, + 0xe18a92f3293049a6L,0xabd525694dfdc13aL,0xb928cc300d843466L }, + { 0x12750aec348dc7c0L,0x3c8e205d87f12dbcL,0xa2c71091e0bdbd81L, + 0x895b56a0c1c1871cL,0x68dd7414b4c850f9L,0x45a948ecbe806596L } }, + /* 56 << 224 */ + { { 0xa88dbfe0f4fe35f4L,0x32de3a1c84283011L,0x8a3777bc39caea33L, + 0x673630dee4d49959L,0xf3ef842c59070317L,0x33e4bb031fab88a9L }, + { 0x88e4538e98ce8bc2L,0x870c2eb81a235c6bL,0x71f62c5640df0e92L, + 0xdb43b853f9627486L,0xfde9fcaa95cc473bL,0xe4c5b4bb4b677b11L } }, + /* 57 << 224 */ + { { 0xa6ebd946dd4091f8L,0xf0e11886dcf0741bL,0xd6267674d9533601L, + 0x571926506f74e49cL,0x18269c2f891d6717L,0x350a7869b45ddb53L }, + { 0x79ea6a4ac8f62777L,0xbad33c4cae7edec9L,0x14bed149ad7e5578L, + 0xb2f4190ba91af4fcL,0xbbd6f68be71dfd3bL,0x23fd3dc8f2fb7a21L } }, + /* 58 << 224 */ + { { 0x5e0f89e598fd044dL,0xb77180d97cc30e97L,0x64fbfb747f82a12dL, + 0xbeebb9ca77629636L,0xe164549feba83845L,0xe65a964a7079519dL }, + { 0x8b1bcc08ca88157cL,0x466399c3f7483338L,0x6e2726414b9efdc6L, + 0xff8c7027be922e96L,0x9baebf7d48374f59L,0x2a84a23ac18ee18bL } }, + /* 59 << 224 */ + { { 0x337484e0dca4b3b3L,0x82137cb9f5b27d3fL,0x12ae1d11bbf4c806L, + 0xa1e2873f2880c078L,0x9e6bd909058b9a0fL,0xacc5656d2dba5fb9L }, + { 0x7fe5467853fd2ce3L,0x2aa4af35452439efL,0x329989a5904ffc67L, + 0x007ea4c8520fd31bL,0x58988e2551816b44L,0x644f2469d8f186eaL } }, + /* 60 << 224 */ + { { 0xcd4d1a9e8890722fL,0xfa0b826b74142916L,0xa494dfa817ba8041L, + 0x3fb73e736de2b6c2L,0x156a6cf4344b57a7L,0xb197c8621e205448L }, + { 0xf453e348c214acf7L,0x665d7083e9061a73L,0x5ed59ec5ce9868a3L, + 0x9bab305f6ad777faL,0x752c490b35315de8L,0xabcfa35b5d5aaf26L } }, + /* 61 << 224 */ + { { 0x4059fc2f914d618dL,0x88e55ce6108380fdL,0x0c22b21bee61a4c1L, + 0x435ecbdb04788627L,0x3f8a5ec7a9f72788L,0xa31eff8a732d5d97L }, + { 0x119b6bf9d48d0af9L,0xde6d1de5af70a043L,0xac075ffd3368db4aL, + 0x23a33ec94a58603dL,0xd43ad120fe181a89L,0x386b90ed42f0b006L } }, + /* 62 << 224 */ + { { 0x8096824bf9bf1a24L,0xcdf69abc8260ebd7L,0xaf93b34de9ab190bL, + 0x676351ff841cbba0L,0x3db704d3eb6d6c60L,0x3b1b893fc09aebfdL }, + { 0xc06b9bfdbfc69f15L,0x28b1ffb8e9c688c6L,0x1607bc68d3c16455L, + 0x07d56bcc6d16d937L,0xac28e69f318afd9aL,0x7f4afeb7e77263b6L } }, + /* 63 << 224 */ + { { 0x796a530ab935875aL,0xd6700ec89dd1e51cL,0xc30301df4d9320e4L, + 0xe23090f357157f87L,0xdd3f68a74029113eL,0x566afc6de2709936L }, + { 0x830f952edbff8926L,0xe207eae5c7a39d27L,0x9210b3dfd9494592L, + 0x3be25582d8460831L,0xec2496575d58edd9L,0xebe8426fefd24738L } }, + /* 64 << 224 */ + { { 0x0372678dc419b0aaL,0xf95031d8c13fdf17L,0xebaebca4b79594c3L, + 0xe587850baf3b75cfL,0x534183ac2c1e09c6L,0x3f5b0bfdc08204cdL }, + { 0xdac2cf06e297cc77L,0x5e47d9c6d0487084L,0xf6f509f490b0f6c2L, + 0x3ffc3cd6c2c62207L,0xbb21eb1132ff1887L,0x2116a023e62ccc6fL } }, + /* 0 << 231 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 231 */ + { { 0x406a7e2116960728L,0xd03923f85597d8c4L,0xd4402eff020748eeL, + 0x7827442af39b58dbL,0x77e3f2768d8cfb04L,0xf6eb49c8e45a978fL }, + { 0x9db0829949247f6aL,0xce71a74706669fe5L,0xe434ce47b82775f5L, + 0xe84995ef63910016L,0xa35e8b971e47792fL,0xc779cb3d7c6aaeb9L } }, + /* 2 << 231 */ + { { 0x1fa064cfaf31ea1dL,0x2a9547a848e8d974L,0xda8102a1fa9d9453L, + 0x786aecabdc6bd7eaL,0xcaf91e3bca2f6044L,0x67d86ea78573f208L }, + { 0xd309fce9c505ae24L,0x67ddc5b17f86eb8eL,0x57791ae0f3d53056L, + 0x26b053f00d1fd61eL,0x91c962c0045ebfa6L,0xe95246de076ed979L } }, + /* 3 << 231 */ + { { 0x156eaf570746d174L,0xa2d4a83dcda35250L,0x60a9f48c0290fa02L, + 0x9855d26d5c33b4acL,0x06e379c697eb1c30L,0x4f2e2dbe6e219664L }, + { 0x6b7448f829006065L,0x237a1f31115062a9L,0x5c635a90ad92cb24L, + 0x2e857f8c2eed977eL,0x3d512df7856dc88aL,0xbde85263e597a27bL } }, + /* 4 << 231 */ + { { 0x49f24994e7c03ce4L,0x274a8c132aed9ba3L,0x897b9103d5e91bc0L, + 0x63db1efbcb404f68L,0x70efd9d842f7fc02L,0xd6e02921c6a230afL }, + { 0x8d5b199f11ae0a56L,0xc98287dece33da6aL,0xde583d34504dd889L, + 0x03756001f823686fL,0xf19ab86f95fc73dcL,0x300406c693f12f42L } }, + /* 5 << 231 */ + { { 0x2f73595f7759701cL,0x8dc2069a6fe0e0d9L,0xb7de7114c286a65dL, + 0xfecc429e84c0e487L,0x51061a2c14344c07L,0x4d70972596869e37L }, + { 0x8b02781f2be9403bL,0x6cb6aa02de3ab5d9L,0xb013508eff6bdc9aL, + 0x568d2e84e5438c58L,0x7b35a979e4206c3bL,0x0bb793c0b17a8bc7L } }, + /* 6 << 231 */ + { { 0x3f896ca9fa4dd561L,0x4b9a98abd2de2ecbL,0xd0741632600e4e2aL, + 0x87c7db5f69e702d5L,0x1f5a3b8053e0df2bL,0xe1e24b49f443dfbaL }, + { 0xeb90e2305eef3a1dL,0x8f3fc8a6d38f73fcL,0xfb1e8299a5aa335aL, + 0xd78504cd4197b32aL,0x0e7a79cc6755918eL,0xc7c98ae2883b1c72L } }, + /* 7 << 231 */ + { { 0x1a12727c03d2beccL,0x810a37dfc6741372L,0x44ac483fb7049f39L, + 0xab73e5e7a36fc614L,0x298d453feeff8aebL,0x2127dd167e1b586bL }, + { 0xeadc5c54e07bd60cL,0x67cdae00f5e2d2e2L,0x03fe0446c9d2f10aL, + 0x0784098795e38ed2L,0x5d348a7ce1a6306eL,0x4903f1b6562f5463L } }, + /* 8 << 231 */ + { { 0xbf66baa5b44b1d0cL,0xbbed18eda44f8edaL,0x80bc32abeaaa466cL, + 0x605b7897e5f2733bL,0xe9e7e3a1a2531afaL,0x25d66db33deb8369L }, + { 0x36212ea3b2f25d10L,0x52d6b3f4a08d303eL,0xefa54b31444e9e9fL, + 0x9c2229a169530c1bL,0x68feb9854b79bdd1L,0xd570e84f8b984cc3L } }, + /* 9 << 231 */ + { { 0xe141b86bde0560a3L,0x858bf4cdb2264bd1L,0x526fb104fabe5359L, + 0x95f9c43f185b8a70L,0xf8e3a3eb2d1f75e9L,0x71826067d93bc6b9L }, + { 0xf360e01799692f49L,0x00f4fd16c2dc3dd5L,0xeb7f40498b9454d3L, + 0x5cb0f3c426c3b393L,0xe8ab4e4357bdc4d7L,0x9abe36b00c123d67L } }, + /* 10 << 231 */ + { { 0x1df8d98c57b168fdL,0x042fd731b45da94eL,0xa54d64f91703e143L, + 0xa12198be9de0ab4cL,0x160e06241ddc4e0fL,0x15cae64a6695891fL }, + { 0x808565e70c2b2081L,0x6de4a393cc65040cL,0x6682cd934bac1768L, + 0x62e7ac2ca5be965fL,0xd33f6f8ad7a38e90L,0x9cafc4635b8b516eL } }, + /* 11 << 231 */ + { { 0x0541a391b685c547L,0xe86d35e091765999L,0x65aa03c51db4a2ecL, + 0xba53470e6b1c4784L,0x4f848cc8cceca1faL,0x89d0db0b8b18e350L }, + { 0xd03e452a7840d734L,0x6cebfa790ca24215L,0x288b4569e8f1d9e8L, + 0x18e405af8927ce0cL,0x5aad57e51abfb4c8L,0xbbd99091a197ed1eL } }, + /* 12 << 231 */ + { { 0xf041e421aa44f3e2L,0x47ed9e8eae6fd2b7L,0x4fea93751128ed62L, + 0x041a1c1acec6eae6L,0x1f32359415a65daeL,0x741fea0a0154e8e8L }, + { 0x309e9f289c32e224L,0x457d4ffa902ce57bL,0x7bb54dd5692420c2L, + 0x193a41aec4fa1a6aL,0x35f5f3b43d779e77L,0x31e84371046ebb8cL } }, + /* 13 << 231 */ + { { 0xe75a7c1d9d7e5551L,0xb73c987611635e3bL,0x3b07a071e09d29b3L, + 0x0a3cc0acc623023cL,0x15ec4a7a1e2ceb33L,0x09a01968c70eb27fL }, + { 0x2e5bb53c369d145aL,0x4c93330d9b7fb506L,0xbb10a2f358013308L, + 0x3d9da0c4e0b85fd4L,0x8b39c992ce0dc79bL,0x7e6d18b0bec905faL } }, + /* 14 << 231 */ + { { 0x3a5a366ea1554376L,0x0e1687c052a6ed9dL,0x3e16e4aafe5355beL, + 0x6d8bac03ced67666L,0x403eb33ed9344003L,0xd7b9ec0d333ab20cL }, + { 0x9fce1986d64c272cL,0x9d52d64bb1e23843L,0x8e689611921a58e5L, + 0x8f5f115620d5c61aL,0xb17f612fadc81b4eL,0x36e2db30e562f779L } }, + /* 15 << 231 */ + { { 0x98d0bcead01f8634L,0x6e9ba675bc5f825eL,0xfac2d3aa05e938c1L, + 0x434b712fb9c66adfL,0x81c29163a9a61d36L,0x80eade933be8eea9L }, + { 0x10fc6d75c04c45a8L,0xa2c9aa58fb9e8702L,0x9142afaeb200428bL, + 0x4fa28c8520eccf38L,0x3b5f63308209b3e7L,0xf74206ca8cd74accL } }, + /* 16 << 231 */ + { { 0xd6a4d25c845f26e4L,0x71e554ce1b039dffL,0x942059731cdedfc0L, + 0x0c4e385603d6502fL,0x981a4fc5e15ce8c8L,0x85d1b0f17aca30b7L }, + { 0xf2037ef777bb9e43L,0xc52804f4e87ae187L,0x9c98a23c71f3e4e3L, + 0xa73c8b89f47b504bL,0xb9e33f54023233aaL,0xf2bcfc17f92c9f68L } }, + /* 17 << 231 */ + { { 0xb3c1bc26707fc6ebL,0x0bb585b75ef6dac6L,0x70af297f5f707063L, + 0x3d86a8fa967a0ad8L,0x510dae4d4f956cc6L,0x1dbcb2e883c01ad0L }, + { 0x0e480cd28bfbb5edL,0x76498f813025fca2L,0xc015064ec5446cadL, + 0x4ddfe2af3616f51aL,0x76b0d690e6750b31L,0xc4502c050073f263L } }, + /* 18 << 231 */ + { { 0x9120912bb3081e59L,0x6c73c4a2f908b364L,0x408af8c94de763d6L, + 0x3d9e83084000add2L,0x65d197fddcb5a5a2L,0xbfd29f0b2bd82bb0L }, + { 0xa1243e63bdfe09e7L,0x91d90b54d556188cL,0x977dd4a18bc872fcL, + 0xa8e6e7bef4ea7805L,0x12c53bd80a467365L,0x9d7abca493b7f0a4L } }, + /* 19 << 231 */ + { { 0x5faf453a40eeb93eL,0x6801e0d1f1fe9307L,0xe92505d39ea9b800L, + 0x7e911f8108eb58c8L,0x5da7ffcc098143eeL,0xe023262056876057L }, + { 0x5354045bbfa99a91L,0xee660bbebb346841L,0x1dbf5c7cecb3099fL, + 0xe79c78d6a125d753L,0x2a356f10706fc013L,0xe50c50b725f88ebdL } }, + /* 20 << 231 */ + { { 0x663ca92723ca903aL,0x8a64a4dec7681937L,0xe3ec0966a2baa42fL, + 0x688328d7a2906226L,0xc2821e9c94790fd8L,0x7a295b62157501cdL }, + { 0x032cd57d3675c2f3L,0x91d66a57f42e6f95L,0xd75056961e97dcd0L, + 0x7e8ba3ed7d8b6f52L,0x8ddb72c420b0dccaL,0xe09e53bb6aea2d55L } }, + /* 21 << 231 */ + { { 0x3815b1028a009f19L,0x4f76d609f5418c34L,0x7a35cb332a9eabd9L, + 0x018d6c54ce89e886L,0xe00b99e859c9fab6L,0x4f10a0d9aaf6e7b8L }, + { 0xee51f8f0e722fce1L,0x03e8b63179bccac0L,0x66e540c26f327d2fL, + 0x31df4a35d22377e4L,0xba5b0029d5c71cedL,0x6a3e20553ed6aeeaL } }, + /* 22 << 231 */ + { { 0xe932d1aaaffc47ebL,0x75c9d4d8513f85a3L,0x50886fcdf9419cb0L, + 0x756a7d7d49081e9eL,0xe45fff1fe14aff77L,0x022b4ac339846230L }, + { 0xefc3e8dbe89adc78L,0x921bb1538c09ccecL,0xe4dc6aa17826d461L, + 0xa53aa6cefac8f0f4L,0x5d4e4d53954192c5L,0xda721828c722780fL } }, + /* 23 << 231 */ + { { 0x978609c67e4933daL,0x49fd5c5d2539c807L,0x072a911c6330373fL, + 0x40cfa61838177579L,0xf9a7aa4c81c51596L,0x7ba8e7a5b346724dL }, + { 0x79298c06d26ee66dL,0x243323702a9c2792L,0x585e8b9eb6aab53eL, + 0xa39596c6e14bee4eL,0x89b2758828a76dbfL,0x889fba0aa00dc1adL } }, + /* 24 << 231 */ + { { 0xd55a3eaf0a9a8ba4L,0x13b1406b2a8cd215L,0xcb44589a93943e1aL, + 0x91b5e3493a671a47L,0x488654f8efbe0256L,0x448bee4b392ba5e8L }, + { 0x228f478137e762caL,0xe21a2ca7e71b6c47L,0x0e809fe94900fcefL, + 0xb05e1db2815f6c76L,0x8cdf28815fa6fa0cL,0x2ed55c1c586fec8fL } }, + /* 25 << 231 */ + { { 0x7c3842eba210d4d9L,0xd656154e5f69a69bL,0x9e11c6db1f3a0483L, + 0xb0314a5e5a217444L,0xe17a274e34f4e54fL,0x6e41c20a9f79d6abL }, + { 0xd010d789dffef6dfL,0x704937f17e8915f0L,0x5072bf063d3460fbL, + 0xa30814ed5f08429dL,0xe5faf476207d2708L,0x46e56e14af448339L } }, + /* 26 << 231 */ + { { 0x5a049c8f94af3a35L,0x9ae89160d8b75bbcL,0x8b026d867ff40c5eL, + 0x90e54aa4fbddfd06L,0xc85349e7ee418640L,0xbf71e454beb7801bL }, + { 0x63f5e068ad912e83L,0x6252a4a4ada5341bL,0x25114b87b44529abL, + 0x9b80bea9eadb4f13L,0x7f071c0cfe050052L,0x4c9cd33418612061L } }, + /* 27 << 231 */ + { { 0xc6f50ed03c768ff6L,0x5b994b58b6de126aL,0x807ad19e2a1ac05aL, + 0x012fcb9ddfc66ad7L,0xf8706d5fefeb7d07L,0x132aa6697bfc5337L }, + { 0x56bd874310e28d18L,0x33bc53d96e9f8e26L,0x5885b63b152758edL, + 0xb8b1bd5e757e1471L,0xdbc689458c0d406cL,0xa664de3bfc605a11L } }, + /* 28 << 231 */ + { { 0x04df415ea6d4b6c2L,0xb8e33e71d254d2d4L,0x179df4f48b84c588L, + 0x8a2a0683d435793aL,0x6147a5a911eecec0L,0x0b8389793a0196ccL }, + { 0x855059ce81805693L,0x37babf9f3b27872fL,0xa2ac78b1769be5c3L, + 0x16260f0c0a8d267bL,0x31f48c42388266c1L,0x58fee495ead1f238L } }, + /* 29 << 231 */ + { { 0x5753ee0fc048300dL,0x307dfd57e048abc4L,0xc18bdfeca3ba6c56L, + 0xfb2d8daf10495489L,0xd93aebd4e0fd2d13L,0x4736efaf0518a5faL }, + { 0xa8ee4995eaa9fc77L,0x2620f08e008adc03L,0xf03981839f06991aL, + 0xd47b1eabe25a4f4cL,0x669cf09c79f95484L,0xf30191584a0f8b96L } }, + /* 30 << 231 */ + { { 0x047b0f0124b240a1L,0x959915dd46cecf58L,0xedf2e74b72980ca1L, + 0x6b7b7b4ef2cad32aL,0xf9f01c9d0b9ded1cL,0x009d3a5825e77e0aL }, + { 0x62314ab411a39c1cL,0xb3b0c5b2ad557b74L,0x6dbb75dd961619fcL, + 0xb8f2d198c934e1e0L,0x4401507542eb7fd5L,0x3a8552efea1be435L } }, + /* 31 << 231 */ + { { 0x08e3f0e2217de9abL,0x6bdec27bb6b4f789L,0x5b160334685af8e0L, + 0x31e651cc61738f6fL,0x37224bc4631989c0L,0x2dc8006ad39f9c4dL }, + { 0x2a5d585056c3d84eL,0xb2ef06cc5cc79193L,0x246d92869eaa50e7L, + 0x8cacbf7cea6a7cadL,0x109bddc629465ce6L,0xad2f492fb5744947L } }, + /* 32 << 231 */ + { { 0xba03ba3b7b3b336dL,0xe57ce50928c9c55dL,0xf96b8cfe4f0f60b2L, + 0xb908d77e6fcccd96L,0x7208ef7de79dd17aL,0x739095333ec3d048L }, + { 0x9c5ad2da1163fe78L,0x4e2a8685cd4a15c2L,0xac999449470eb938L, + 0xfaaf27fbee7d772fL,0xfbe402abd0b7ad09L,0x704d4f0e57db00a9L } }, + /* 33 << 231 */ + { { 0x8f2f736c6330607fL,0xaf4acf66c975432bL,0x838fd8cabd1dec99L, + 0x347088aa7c3d0499L,0x28008757e835ea86L,0x43e2fb30c03e1aa1L }, + { 0x06c66dabf0d10da1L,0x25d7aa1867321158L,0x215e483811dc063fL, + 0xd52dee1e288362f2L,0x790989a1fe300a0aL,0xe0452fa5f163e1ccL } }, + /* 34 << 231 */ + { { 0xd3eab3ae25e7c044L,0xa3712d11b6d22325L,0x5e3835999e8237ddL, + 0x2549047c9dc93a5fL,0x24b07617b546a113L,0xa50359ed2e7b82fdL }, + { 0xbbc3eb5889964effL,0x93d490b60d7ae172L,0x68cd6b3f774ac0e6L, + 0xf98f1df035e02fc6L,0xfd2625c560857c16L,0xd68f25e845dd06f6L } }, + /* 35 << 231 */ + { { 0x40dcb41018c1b3d8L,0x8af9a0bf954cc170L,0x9c40a17d5af27d6dL, + 0x6b20fa7d7137d35aL,0x7c46f6aaf07f5adfL,0x7caa6e3cafc2f780L }, + { 0xef03332694dfb637L,0xd8f330b38d0ac73cL,0xacbf571255d40a9fL, + 0x1b4ffafa3f4fde0eL,0xa17488e09fe6b04fL,0xd27808a103957cfcL } }, + /* 36 << 231 */ + { { 0x85e1de1e96569e6dL,0xc9545920d7ae52f9L,0x04ebc797bcd62008L, + 0xe142d0bc04a24db0L,0x5ed44b0d40e9fa80L,0x39fd679a48ddaba3L }, + { 0x91aba967ce7ee095L,0x76de8d3a0e97d0f4L,0x92e7a107a221785fL, + 0xb028f67e734283ffL,0x987f644168af2f42L,0x0ad882369d7f7102L } }, + /* 37 << 231 */ + { { 0xc5289301642f7d3cL,0x53ea584de508c45aL,0x86eb66e949337336L, + 0xa56d59d668fbc13aL,0x44c464ffe9e51562L,0xe5280ecd8200a27fL }, + { 0x92e2a9334cc73f23L,0xf59780325e7b858cL,0x399bd41e90d4b2efL, + 0x4faecb8bd0ead86aL,0x6ead9c530ce48b14L,0x941b4807ef74700cL } }, + /* 38 << 231 */ + { { 0xea281be94d522b69L,0xb6855d45694a08bcL,0x7c47ddc7aa7f4d28L, + 0x2028e22b6c36bba5L,0x206b63430c2dee0aL,0xfeb0b3dae68fdcd8L }, + { 0x6dda02a44603db5cL,0xa705d0defd786a39L,0xd356f6a426aadd38L, + 0xd34acb7d95ef6a00L,0x073ea16e14846402L,0x2cf7a82ab2df8bc5L } }, + /* 39 << 231 */ + { { 0x8fdcd309bffd7240L,0x6843dd76386e459bL,0x222fa67c0dee5740L, + 0xa3801343620d7d83L,0x96dfdbffe21b4af3L,0x017bd3d3dadd04beL }, + { 0x1b6adba2bca18337L,0x191b86f1300ed35aL,0x103a380cd73bbadaL, + 0xc2f3172f36f95dacL,0xa01a10e220767bf4L,0xda882ca6989ad766L } }, + /* 40 << 231 */ + { { 0x5bbc748b9cc47708L,0x16d796054026c772L,0xefc3ce3ea053df6bL, + 0x30ea7eab0713752fL,0x15b491b9dfd524b7L,0xa751d82010bcd34cL }, + { 0xf30c708abbd5da72L,0xf0c55aa86d16bd51L,0x1754060ba6215d84L, + 0x3a48d2cbb863542bL,0x992e8340261d8c45L,0x4096f65be8fd2113L } }, + /* 41 << 231 */ + { { 0x5532411e1045d8cfL,0x2d2f8d6b52bea60fL,0xa850b61825c556c2L, + 0x6547892fe8965d13L,0xa7bd4527184d0cffL,0x0e7f7daec25ba558L }, + { 0xfcfaf7b234343889L,0x9d6a23aeb82ba1d7L,0x2859023b60514faeL, + 0x4d51aeddc82da6b7L,0x6a060dc38273cd00L,0xf2f8923d78478c29L } }, + /* 42 << 231 */ + { { 0x0baa35154f08b278L,0x26baf331e57297c8L,0x3fef65cc04e27c13L, + 0x0f910ee0ca8430b6L,0xa27c5f5c2c445251L,0xc780142dccf3c637L }, + { 0x47dc4192e0f3fbbbL,0xf4d12bd6f2a91a33L,0xc1eb18b206352685L, + 0x111cc07f5b3db096L,0xbce0cddbcb95c815L,0x6b0bae7e14d28563L } }, + /* 43 << 231 */ + { { 0x40d16b7705897177L,0x4772a643953915adL,0xc6cfc1d23cabc7a9L, + 0x0641e96df80536c3L,0x6c297cd6be4c5454L,0x509a837c9c00216aL }, + { 0x17455153c01ce9a5L,0xee76da8a40b825e8L,0x1757a59cd23a37acL, + 0x5adcfbd10958248aL,0x043314525d01549bL,0x831f725ab0c42176L } }, + /* 44 << 231 */ + { { 0x28704bdcdf7d537bL,0xbcae2c15fa88f42cL,0xab32eecd3866ac4fL, + 0x446754a2128c4a7fL,0xc69309c1739ef781L,0x216e9f43bd160d81L }, + { 0xe0efa3ec6fefc0aeL,0xd179225086a604f5L,0xe43e13e260418c0fL, + 0x6f605146f100b9b7L,0x6c39828a6e994093L,0x99558f4706c019e9L } }, + /* 45 << 231 */ + { { 0xf541b3cd28df49eeL,0x0be75ef5cec2660fL,0xe73d18bb620c81f1L, + 0x42e81fef3c775c53L,0xd0a9dcdcbc012ed7L,0x570f5a1b8f292a58L }, + { 0x51f302e74c030819L,0x42e1903f50bb8a5bL,0x6d8105a98536e7d0L, + 0x66e2fdf1c1ca766dL,0xecaf4a316c5927fdL,0x347803cf96a14565L } }, + /* 46 << 231 */ + { { 0x794d90ab425d3a7fL,0xcae9008d93ecbe48L,0x211e38c3bd5f11b3L, + 0x6020ed2a6db1c1d7L,0xaa5695064437f020L,0xb2b93424235f4d6fL }, + { 0xa84a3c1d66ab2a3eL,0x171f9325712a14e0L,0x4a43cd6744d958d0L, + 0x53bea85ee95dc3cbL,0x1fba008769f2009dL,0xf0fbc48f31c13eb4L } }, + /* 47 << 231 */ + { { 0xefa3dea85fb2227aL,0x0160b031e098a97bL,0x92a554e3553377b1L, + 0x7b58c26258ccaac8L,0x666400171c3e0a47L,0x40e45f90ae2d7d8aL }, + { 0x660df3441ee18103L,0x5515cd66e9b64e55L,0xede93c59de059b3aL, + 0x874a0c90ca0e7acaL,0x840188abc8b1daa0L,0x9d49a02601e148a7L } }, + /* 48 << 231 */ + { { 0xe93ee31ae12b4e64L,0x2ab8e378662d17f4L,0x2544bd9969516582L, + 0x7bf80e4b2e1e5485L,0xf30f0b14729d9361L,0xb3ffb5d18268d40fL }, + { 0x34605055ac193a63L,0x9e5ca9a9f8e04d69L,0xcbbeebc1085ecbb2L, + 0xda03b75bf340eac4L,0x3bf9468a84436462L,0xdfa8b4c80f26f20cL } }, + /* 49 << 231 */ + { { 0x2e6520714aa497e2L,0x2b9358fd7ecd223cL,0x96efcbdc4f828e86L, + 0xa0f76679d2f096c9L,0x3887bef70690b78aL,0x2e7d9cae1a01b10dL }, + { 0x8b0cdf0e5656e5d0L,0x0a6ca92d48d3ec2cL,0xdcacbdd3b49e2ab8L, + 0x4d087ee0d7485e87L,0x4987078292cc57a7L,0xa1776bd47bb38b8aL } }, + /* 50 << 231 */ + { { 0x60c113bdb711e087L,0x28694ff4e257e115L,0xf81d5e054c18d716L, + 0xd1c04b67eb0af843L,0x16e6e46e40d8907dL,0xb73c3de91dd34d22L }, + { 0x9d7f282519825f92L,0xdf5d33edba486ce6L,0x288fafac21c223d3L, + 0x21c4df016d05007fL,0xccd9626b197c5badL,0x3a91743902c91b36L } }, + /* 51 << 231 */ + { { 0x6f950922340ebed2L,0x9e796894beddf06bL,0x5a8ea337cd9d7a07L, + 0x1c5dee115bd182ddL,0xba87dd1ae0c79b9dL,0xb16169f3b9002931L }, + { 0x68098da138c62518L,0xea7bf413417fdc6fL,0xa500a320b6fdf768L, + 0x7870c71c4550c202L,0x0874fd9f6121afb2L,0x49f0fd0cab7d0b6fL } }, + /* 52 << 231 */ + { { 0x7af3de47f6b7fedaL,0x19b8a51ba30b2296L,0x16886446150a0af8L, + 0xdada5aeeb2a4ecbbL,0x77105de8e8de3888L,0xc54d352c7d763f77L }, + { 0x754984ae72ff499aL,0x3de4b2785a5a25f4L,0x5df75ece818512a4L, + 0xd4fc8093ca7ccf3dL,0xff9bdf544a49f4fdL,0x45d23e77de0a5840L } }, + /* 53 << 231 */ + { { 0x8ef88682ca85a586L,0x12038785bff64885L,0x99670d8ac98cf695L, + 0xf7dc3dca6c3d5832L,0x1e836a59fd3e64d1L,0x8dbb13addd426c1aL }, + { 0x21867f0690f59314L,0x7adb6f707da5ce5dL,0x662422ae0da28987L, + 0x75a1486466766a41L,0x2d42bede6c8937b6L,0x559e168dff0c474cL } }, + /* 54 << 231 */ + { { 0xa07fdaa25af635feL,0x01d67fb36a0c8fd9L,0xa226f8dac9eb8d8aL, + 0x0795c27ce7fcfd0dL,0x84556c0553578294L,0x92b30a84b3e57574L }, + { 0xc8eb6ac0ca5dc890L,0x061a0a195c8b7d8aL,0x60f3351923177c06L, + 0x780755917d01bf6cL,0x63ec8a4421f48422L,0xddfcb2c0d804c7b0L } }, + /* 55 << 231 */ + { { 0xb186daffdb2e385aL,0x7589c9cd43aac848L,0x9b474a411fb053d7L, + 0x2f79556be1ada6c8L,0x694badc54d7d9ce8L,0x31ac06a84921f546L }, + { 0xacaf91c165666233L,0x6ea97c8ee45b62b3L,0x9c8f3fa66f0096c6L, + 0x2db7da39ac68f8baL,0x0ad2da0f19a3d1b2L,0x08c96b0ff80d426eL } }, + /* 56 << 231 */ + { { 0x07d63f07257d20b5L,0x25475a304e8c62caL,0x2469d661789ac15cL, + 0xd0d2ba1b3aae86a4L,0xc716202a4458dab6L,0xa011ca5ec4d5f90cL }, + { 0x53ce0273ca2430c9L,0x61040ecf96da6946L,0x6847dd034247c99cL, + 0x0c500b4519defda5L,0x263316db365796d4L,0xff9b99e7b982d89cL } }, + /* 57 << 231 */ + { { 0x725fc8f911591738L,0xe6c16db3f4030f65L,0x66c7622d441b6b17L, + 0xad8e4b9c69d93786L,0x732d597473093a4dL,0xa2136d85228f103bL }, + { 0x84f1d9397bcf76e0L,0x971a4c55e2531411L,0x9816371d15920fa7L, + 0x5515cbc594bbc17cL,0x8b8c76e859d52722L,0x3bfe618e9a240652L } }, + /* 58 << 231 */ + { { 0x18981da25cd1f7c3L,0x198a91bb09b22c3eL,0x48d11aafb23d71ebL, + 0xddaa6e071d31782aL,0xca7b812a39125babL,0xd89dcd825d963539L }, + { 0xc7012ed9e5a89eafL,0xbcf0d4c4af0ce61fL,0x6f65a246e6a9f404L, + 0xae6a489d51c1302bL,0xab43a2bcfc5ea651L,0xfdb73470293b1e58L } }, + /* 59 << 231 */ + { { 0x8e860629f5c9d835L,0xf91a0b5d04efe37dL,0xaa2acb55b1956d3dL, + 0xe295b30fb5bb48ddL,0xdfad64a7e8275e6fL,0x1e203bb7d41beeaaL }, + { 0x4aa2fd5836e64f60L,0xfb0b92a706e01818L,0x68e386d60d29ff89L, + 0x617981bc1802840aL,0x6d68ccf7ceb124f5L,0x19193c483b120ddaL } }, + /* 60 << 231 */ + { { 0x4d02098b8b5d9d67L,0xecb580503148dc75L,0x561545107d898600L, + 0x0213ef782d8be728L,0x4123671b1f11d90bL,0x8b9ff1b654c291beL }, + { 0x139ba95e52db185bL,0x83be41d0997b3eb4L,0x4a950c9a41e2e288L, + 0xdca0290c48916145L,0xf1eb9327cd073e77L,0x384ec5ddbd4f4ccbL } }, + /* 61 << 231 */ + { { 0x7e538f9036f4b7b0L,0xeb54e9e4ca25008eL,0x0054a07bf8af6eb2L, + 0xd96b712f5e3f61e9L,0xf01da03e29aa496dL,0xedbbc2d7d00faf95L }, + { 0x178c5bbd104f4dd3L,0x5cbd4783aa11b0d0L,0x4433fe6156eecea2L, + 0xdcc01bdcada7991aL,0x89ca41ba1addfa5bL,0xad64ee097a65ee64L } }, + /* 62 << 231 */ + { { 0x05a8a58d7e276915L,0xee28f77bf1582bf6L,0x6f308349285bd210L, + 0xb8b8ec47ab877186L,0x0436930e0ddb857fL,0x20a9973e5346b800L }, + { 0x756ab9b5848dd5b9L,0x33a220cfa12370ebL,0xdbd87c391f3d0386L, + 0x90c6879075429844L,0x5cc1a9736193f021L,0xf0b80f6543d46e24L } }, + /* 63 << 231 */ + { { 0x45e5f57bf79f5116L,0x14f02b229bcd30ecL,0xd989ee5426a39a1dL, + 0x497ad3c3d5854b85L,0xb61c15e50154364fL,0x5979941f502107d5L }, + { 0x0b99f087195934f6L,0x1f852baa605fbf71L,0x68ec80e47206f65bL, + 0x0392af1cea5bc3c0L,0xcebe56f81cb1d6bdL,0xdc6279d90f80b6b9L } }, + /* 64 << 231 */ + { { 0x10c082a63fc14a85L,0x59389ebc1c0b14c4L,0x785d935b4cb291a7L, + 0xfc2ae15313e9ce08L,0x3146fabf4df6f1c4L,0xa2a4a457c87dd24cL }, + { 0x85fdd8771deb49bbL,0x2b7843709b055934L,0xc81d05013e7e0297L, + 0xb56ddd1fb92df904L,0x4612df9f295ddccbL,0xc24bd4cf0e27cf1dL } }, + /* 0 << 238 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 238 */ + { { 0x7830460fd1944d1bL,0xc56f08e784350af2L,0x73bee2aa307d9c78L, + 0x1b02af1b5aad8b6cL,0x5e31882703848db5L,0x4785958bf230f476L }, + { 0x4ea6535d4f80e25dL,0x9958c9c7d23c7f72L,0x4c197b332fd33cabL, + 0x24c7b0b1c566914fL,0x956ce3c371952d3bL,0x8735694bfabae5f2L } }, + /* 2 << 238 */ + { { 0xca9872e1597bd10eL,0x6725cc9a4aed951fL,0x96b17cb84e05b280L, + 0x97987146fa234d45L,0xba78949ebb35a7d8L,0xb82e9b9f6fc59384L }, + { 0xa303e54a70f165c7L,0xfd6bb0dcb9c2cad9L,0xe57e2de8ee722045L, + 0xa05c106563e27035L,0xaa38e86602d2fe6fL,0x78e02fa8ee2f6aadL } }, + /* 3 << 238 */ + { { 0xd6256e7c62c627c2L,0x5571edfc3cbb10dfL,0xfedec45771cca8f4L, + 0x2e26ac5f8483eed6L,0x8e8c0671173508c2L,0xfd9f25d50f39bf76L }, + { 0x1cb080c3094cc1b1L,0xd367ca8c113e6552L,0x4ae2ca36bedb511cL, + 0x0de0c3e34707eeb6L,0x204cc610239d3097L,0xb235dbf0adb00383L } }, + /* 4 << 238 */ + { { 0xc0426b775e3c647bL,0xbfcbd9398cf05348L,0x31d312e3172c0d3dL, + 0x5f49fde6ee754737L,0x895530f06da7ee61L,0xcf281b0ae8b3a5fbL }, + { 0xfd14973541b8a543L,0x41a625a73080dd30L,0xe2baae07653908cfL, + 0xc3d01436ba02a278L,0xa0d0222e7b21b8f8L,0xfdc270e9d7ec1297L } }, + /* 5 << 238 */ + { { 0x9704cdc6a9c26f4fL,0x96808107908a6756L,0x73be47d40f1def2bL, + 0xd32c11d619215394L,0x1a59b9541842c2f2L,0xd64a70bb52c94807L }, + { 0x32b08c3e9dd262b3L,0x54d2cdc4440315a0L,0x671b3139425ace14L, + 0xd418542f2c7518e4L,0xce5e1712cc1bbdaaL,0xb3268403131f98adL } }, + /* 6 << 238 */ + { { 0xce4b39874e39e87dL,0x8e60a901966f4603L,0x1b95e4fd73c4a679L, + 0xae87f845b004310eL,0xcd50aedf815684c5L,0xa56805d343c77e38L }, + { 0x9a429abcf0588403L,0x77dd1a02009e699dL,0x27ad38fb52a417d6L, + 0x62591579fd8f6d00L,0xccb12126ea58f822L,0x3a009e76760a3ccfL } }, + /* 7 << 238 */ + { { 0x17688d3410023b42L,0x9bc8bd6f7cfadb6eL,0xe4cdf89f460aa255L, + 0xf709740a99eb21f8L,0x1ea8115cbd460bacL,0xbf7bafe8ac7e6629L }, + { 0xf8dc02bb096de741L,0x982f7becd2f6a583L,0xd971589a0f92bfeaL, + 0x662793afc02acbaaL,0x1b0f7d5eb771574eL,0xd9f71c4c66985cdaL } }, + /* 8 << 238 */ + { { 0x4f120aa7e2a07891L,0x9158bab3a25d3225L,0xc96bac5ecfe5f7a8L, + 0xd4e73d59bbf3cec6L,0xed8d233560361cd5L,0x9b1a252c562f444cL }, + { 0xbd37d3cfc70f23c2L,0xf13b3b6ea52ea19eL,0x7e35535a3d2f41edL, + 0x0353b52ee8b1743eL,0x31d89dfd7b5a2765L,0x2b7ac6848d9ea8b8L } }, + /* 9 << 238 */ + { { 0x3613afb361bd36b3L,0x85171aef3e0339eaL,0xdaf0c280c833abe6L, + 0xde566372e4500f09L,0x487dbef84a5bda73L,0x5cc00564e6e3f324L }, + { 0xbdf148cfb96abd01L,0xf8dbeda5ba9306ffL,0x05774d1a5ac0b828L, + 0x73ddc3248cf4a56dL,0xabc5af5232dc6125L,0x15ad6d2573294d7bL } }, + /* 10 << 238 */ + { { 0x7b5bbe51bd6086deL,0x7fbc95303816cee6L,0x60ac14fab3354bf6L, + 0x2b2abe43c9a6e793L,0x6ffae7342e19664bL,0x1d0e38b90064bd95L }, + { 0xc1303ba3fa9f23beL,0x6d5f4ea5d8f0a46cL,0xf8f472517a270649L, + 0x126c13ae723a5a0dL,0xe4d0a19e5e21273eL,0x18076170e83abb8cL } }, + /* 11 << 238 */ + { { 0xc21dc6946b771809L,0x2501f25600f85b8aL,0xb3a21dc347382df8L, + 0x25ede3c239dee18dL,0x39709b9db29b770cL,0x6eb314d510fa9c5aL }, + { 0x79140b1f508f5e59L,0xcce9f7cedeff2816L,0xa153c050400bc8a1L, + 0x052e03c4ff2c127fL,0xf8ffff1f841a03adL,0xc0c2626345896fb5L } }, + /* 12 << 238 */ + { { 0x06a67bd29f101e64L,0xcb6e0ac7e1733a4aL,0xee0b5d5197bc62d2L, + 0x52b1703924c51874L,0xfed1f42382a1a0d5L,0x55d90569db6270acL }, + { 0x36be4a9c5d73d533L,0xbe9266d6976ed4d5L,0xc17436d3b8f8074bL, + 0x3bb4d399718545c6L,0x8e1ea3555c757d21L,0xf7edbc978c474366L } }, + /* 13 << 238 */ + { { 0x905ad4bf3023ec1eL,0x8cc101ca16081c1eL,0xe0d47ec79cb74127L, + 0x1be5f86725da2dd4L,0xcba2ee4507ebac2eL,0xcee26667e22d87d1L }, + { 0xfc339af1c7c409ecL,0x112af9b47b7ef32fL,0xcc3e07898b821999L, + 0x4234433c222b3478L,0x55bcc87ddbce50c0L,0xcb6141cd7816f642L } }, + /* 14 << 238 */ + { { 0x8ae24e6b67f38eecL,0x61adae20ea14bc0dL,0x32737584c480c3fcL, + 0x44f61b79812ee744L,0xc8f607d5fe06d5d2L,0xfeaeb2bcea45267eL }, + { 0xe004522bb92c909eL,0x5171fe360ab3e854L,0x659936fe63ebc481L, + 0xdde6dbbff76649d4L,0xb38c160fe2295d0eL,0xba608b7e1e8f5c1bL } }, + /* 15 << 238 */ + { { 0x55616c4c86c2cb9cL,0xcfa8b484173526faL,0x096a09d90039a4c9L, + 0x6ccb4964f300a73bL,0x42dd78ac66819855L,0xa7c532c10941599cL }, + { 0xd15905f0b630220bL,0x9f4893ca5637e103L,0x768c09bf8a2115abL, + 0x5091f4399c52755bL,0x4ad1c0f6d38e7c50L,0xf6e6b2d054eb4439L } }, + /* 16 << 238 */ + { { 0x73457010c46db855L,0xccb68c43dd579fb8L,0x705b0e8c9c25fe5bL, + 0x40f36ea182dd0485L,0x3d55bc8527ac2805L,0x15177c6fad921b92L }, + { 0x51586cd55ab18cabL,0xf51b5296cbb4488cL,0xbb4e605e84f0abcaL, + 0x354ef8e3772dd0daL,0x7f1a8f795e4e1d41L,0x93461f09de5d8491L } }, + /* 17 << 238 */ + { { 0xe186b0b09cd7d54aL,0x0451cb0dd4303760L,0x90a8b0f84b38f082L, + 0x2357f03700b04fffL,0x8a4669f86d81dbd3L,0x2a5cb6f6bd94842aL }, + { 0xa13d19c4c498a572L,0xb7b8fe10cd937a76L,0xf8df355ed9842244L, + 0x64fc9d62b077c8feL,0xd4b2c3cce9dd337eL,0x7c63799ad3784edaL } }, + /* 18 << 238 */ + { { 0x39fe6673a780fd38L,0x8bc8d026a4b4cfa8L,0xcc339850801c44bcL, + 0xb5d80c4bc2dca07dL,0x745ffb5d91f1408bL,0xb55588f89017d1e7L }, + { 0xafef3cf1c3d76a1eL,0xe3a6e8058e1367ebL,0xd09ea1e2a642d2bbL, + 0xf303c613216e63e5L,0xe699e51cc98908e6L,0x835d4cefafeac3c2L } }, + /* 19 << 238 */ + { { 0xd1cbe55ee5000eceL,0xc1a074b01ff0f474L,0xc6681f48d7ffb89bL, + 0x7c68011d48d0bb4dL,0xf305627bdcef5e07L,0x0f0e0c36323ee3fbL }, + { 0xc5c6b61355f5f185L,0x6e4de5af52d6cc84L,0xa64ea548889fe8bfL, + 0xc4c5e4104d28350eL,0xef944a8f7dd3072dL,0x7ed579fa13356185L } }, + /* 20 << 238 */ + { { 0xec72c6506ea83242L,0xf7de7be51b2d237fL,0x3c5e22001819efb0L, + 0xdf5ab6d68cdde870L,0x75a44e9d92a87aeeL,0xbddc46f4bcf77f19L }, + { 0x8191efbd669b674dL,0x52884df9ed71768fL,0xe62be58265cf242cL, + 0xae99a3b180b1d17bL,0x48cbb44692de59a9L,0xd3c226cf2dcb3ce2L } }, + /* 21 << 238 */ + { { 0xe646281876ba99afL,0x1d53bd27818b5992L,0xc55e135d67e1d81bL, + 0x32b9e37023e211feL,0x91ea63dc130b1176L,0xd7e1cc51a34fbb3cL }, + { 0x5363fd962fee934dL,0xd19c50ba0b8fd289L,0x21257825a11c27b6L, + 0x19159a966792c1ccL,0x0ccc3cac39a08fbaL,0x841cb58a45512d8eL } }, + /* 22 << 238 */ + { { 0xae8532c3224ab492L,0x8bc92c85f6acd0ddL,0xc071ba92b796d21dL, + 0x1290162943797a3bL,0x8f4c5fb5ec950329L,0xfab6f950cf0578e3L }, + { 0xb7b8d211bb6aa75cL,0xb06279dc3d1147f9L,0x060db1a7591820cdL, + 0x0e691a412830f356L,0xac00664224b8bc33L,0x579f9c052f17441eL } }, + /* 23 << 238 */ + { { 0xd8b9dcd50c4cb7edL,0x2f59d64c7619cdf4L,0x7e83d18e284bc6f9L, + 0x49af25123e415166L,0x90388976ccd64d11L,0x4708fffdfe2580b6L }, + { 0x7a8d25ff17dd4d8bL,0xba7785fefd71355bL,0x7cceb111b9789cc6L, + 0xa8fd782ee98d6b78L,0x8d1b7fb66135d4a2L,0x78c2267d35e382beL } }, + /* 24 << 238 */ + { { 0xf38995589311182cL,0x1bee4c4bb657a7b7L,0x0b1c4fd32df8d1a7L, + 0xf16bcc2376d3fbbfL,0xd5888916f4fd52bcL,0x3de6cfb4d5cde1f0L }, + { 0x764ffffdd4a07dfdL,0x5e674426e2642182L,0x34f64762ccd57b85L, + 0x2233a4c329351062L,0xdf076095d9c642f3L,0xac917a2c59f0df34L } }, + /* 25 << 238 */ + { { 0xe588d5a8cf2f7d4dL,0xb45923ee86798c14L,0xffefd323f0623572L, + 0x24dd7019005f605aL,0xb9e833053a6edaecL,0x039ed04949923a44L }, + { 0x0f83a74360789fd2L,0xb4f91a8e9b001515L,0x37b856664261ad9eL, + 0xc291caa68b92b7afL,0xfa0f8a5e67ba28e0L,0x362a6808c5eefb98L } }, + /* 26 << 238 */ + { { 0x8aee939cc64e4ab3L,0x3baac0a844621bb2L,0x9094a09629da9bc3L, + 0xa92dc70806d2314fL,0x45c1cd0e34235918L,0x51aeb007c34021a4L }, + { 0x58267735a3492237L,0xe8d494bd375eb21bL,0x664dacf5a395bf8bL, + 0x2ef1feb612cec40eL,0x90c5f43fa7141e5bL,0x93e80dd03855169fL } }, + /* 27 << 238 */ + { { 0x2e550006211b2fb3L,0x8c82e59d6cab73baL,0x011bb2fb2bd326b9L, + 0xfbd519ff1e0efd69L,0x0fb2f266320cec7fL,0x879e28c03518fac3L }, + { 0xd0887775e01294eaL,0xf6e60efd1df5bb0aL,0xb2a5d3a404d04a96L, + 0x915eaa29a4f3500fL,0xcb6c03f70db6bde4L,0xfee081a405f30cc1L } }, + /* 28 << 238 */ + { { 0x9580cdfb9fd94ec4L,0xed273a6c28631ad9L,0x5d3d5f77c327f3e7L, + 0x05d5339c35353c5fL,0xc56fb5fe5c258eb1L,0xeff8425eedce1f79L }, + { 0xab7aa141cf83cf9cL,0xbd2a690a207d6d4fL,0xe1241491458d9e52L, + 0xdd2448ccaa7f0f31L,0xec58d3c7f0fda7abL,0x7b6e122dc91bba4dL } }, + /* 29 << 238 */ + { { 0x24e2801364ca563dL,0x6f06fde270f8f91eL,0x9abcca1bd2a65c0fL, + 0xc5728ffca5aa1e40L,0x654f0f56eb9d3e45L,0xe04ada2394161a0cL }, + { 0x001b25626ddbc960L,0x253b447aef93504dL,0x895ce21e2d6dc894L, + 0xefb987381c1b63deL,0x6adb6eecde8b806aL,0x9ea3884e0240e7bfL } }, + /* 30 << 238 */ + { { 0xe8387f68411ad563L,0x98a962eacc5f157bL,0x8093a8d296090321L, + 0x240a73083790052dL,0x6cb4a7382e7dcedfL,0xda65bf8481a60e8cL }, + { 0x420ce478c66c70aaL,0x0e7959ec42da3021L,0x44bc9d3c7e35aa20L, + 0x36e49d764e9df39bL,0x7281073a9b286287L,0xd9a068422524b62dL } }, + /* 31 << 238 */ + { { 0x00d6e0312546247eL,0xcc2851020fdaebdaL,0xb8a453f15601006fL, + 0x0afaa3f138be7068L,0xc87acb442c6cd9f1L,0x10dd5d031ffd5fbcL }, + { 0xbae0b62fddacbbd0L,0x1daadc18446bf2e2L,0xaeaf15317ef0facdL, + 0xe7b92b76c941808fL,0xda59af2ae6d0dffeL,0x1c09b783e612b888L } }, + /* 32 << 238 */ + { { 0x3bd258d8775f516fL,0x4bedebd5c715927fL,0x5b432512e3f966a0L, + 0x338bfca7709d0c2dL,0xd142cc1049658259L,0xfabc6138636b8023L }, + { 0xa9ef94014d4ef14dL,0xd5917ac1c54c570cL,0xfd2f63c55cb64487L, + 0xbae949b11cea475bL,0xa45446031e67a25fL,0xa547abc1dc6a7a6aL } }, + /* 33 << 238 */ + { { 0x6c7b4cf344b880b0L,0x29da87760a388eaeL,0xf434d173fe9617c9L, + 0xaf67cc2ea47abf28L,0xe211ad37249d0eb4L,0x88d156e538bce76fL }, + { 0x60320c6dd58fa585L,0x7b352c39ebf09a7bL,0x9305dae8a31ce734L, + 0x70c35be89361cc3bL,0x6b8b71f8bcd14255L,0xd1b7963572a457a7L } }, + /* 34 << 238 */ + { { 0xd8d04787ef8849e1L,0x58adf044148375e5L,0x5b613ac476623232L, + 0xbd274d2f95d7e359L,0xd97acbd271576bb6L,0xd20bb2c34c7fc4b7L }, + { 0xe15465315f837664L,0xddac59b5fb4ce79aL,0x33fef5214fb36e08L, + 0x0467811045108b22L,0x0de6c7766dbe57bfL,0x456d765a25fea77bL } }, + /* 35 << 238 */ + { { 0x4d9838a32922b715L,0x3cd9fc0a6a7bb3a7L,0xb1bf28fc2247e916L, + 0x92dd22006f206a16L,0x8ea87d67b51256caL,0x2c535730b5a4bf17L }, + { 0x34da42505f584954L,0x72326fb8fefca748L,0x40fd9d09da2844a2L, + 0xaadaf71c412da037L,0xa62329a9aa6f884aL,0x1b6165e6726a8f8cL } }, + /* 36 << 238 */ + { { 0x2a2dedafb1b48156L,0xa0a2c63abb93db87L,0xc655907808acd99eL, + 0x03ea42affe4ac331L,0x43d2c14aeb180ed6L,0xc2f293ddb1156a1aL }, + { 0x1fafabf5a9d81249L,0x39addead9a8eee87L,0x21e206f2119e2e92L, + 0xbc5dcc2ed74dceb6L,0x86647fa30a73a358L,0xead8bea42f53f642L } }, + /* 37 << 238 */ + { { 0x39de72e225e62213L,0xd885c406a03a58adL,0xa63964b527e76458L, + 0x93f83239637c0becL,0x8c9e29b4ba556e65L,0x7d746448a6183182L }, + { 0x6dee01aa09a8eb37L,0x97289f2e757ffa96L,0x367ec50fb4785102L, + 0x200f77cdb3d07cd8L,0xadc7c000a581946eL,0xa2dba5e52c0b32aeL } }, + /* 38 << 238 */ + { { 0x95a5a7f0b203f75fL,0x9b574cfcb5df11f0L,0xbf5fe3f2dba4b4e6L, + 0x347a7bd7d0987125L,0x858dea6b09377a2aL,0x87cb1e66eea85d5fL }, + { 0xe7619b666146a0c6L,0x0012585a8a0bc101L,0x738e6589ea0ce92aL, + 0xf23547979a39b3f0L,0x666f3f5d6dc81167L,0xe569cc82fb06b0b3L } }, + /* 39 << 238 */ + { { 0xef0e64399c7677d5L,0x052bf027efc398c2L,0xa5d253cc515e4198L, + 0x7b915f07a71ce047L,0x56880ea2e177dbf6L,0x735dc74f0b5741d9L }, + { 0xa108632f0161a0acL,0x0c68765705e7e09eL,0x694e651e211709e0L, + 0x334e15e51d879a41L,0x6191d34260c2a603L,0x3a8ce0e6224234d7L } }, + /* 40 << 238 */ + { { 0x158d814db12c4bb1L,0xe52f75d22f0cf4faL,0xf106023e6141b59cL, + 0x5eb8b8ebbeb9d941L,0x1dd3972990cf579cL,0xb273252e69ee6efaL }, + { 0xe43a3c593e9947a0L,0xd605124f6c19dd01L,0x8090fdbd05c578b0L, + 0x8e6c535a622ff18cL,0x3600b0c257d12071L,0x6d026e5c78d001d7L } }, + /* 41 << 238 */ + { { 0x6e515f3608e33ad5L,0x3e320c5283512d9bL,0x171ab26a5ca1c452L, + 0xfb3061e874c97139L,0x7944644c9cacf3aaL,0xedc724f03687cfceL }, + { 0x7252d7590db9b5beL,0x625f17ed0eeaf1d4L,0x6b0b4e5e82e3c58bL, + 0xf03d7bcef0f2ecc3L,0x4cbaa878139a7580L,0x982e471672203e07L } }, + /* 42 << 238 */ + { { 0xa533f574e335d60dL,0x102b66fb2aa6855fL,0x7a57420c49946287L, + 0xe3bb702286f393c2L,0x1892642d04a41c49L,0x2c47ba38d44969feL }, + { 0x9068650444388ef1L,0xd94f6f131eaf6b54L,0xf81d8782f0b872e8L, + 0x7ced5924d013f6eaL,0x76ef63d307cd721cL,0x888646b36cba783fL } }, + /* 43 << 238 */ + { { 0xd2c858157ec1660cL,0x6c8988a3ee73763cL,0xd6cc562d5e80aaeaL, + 0x48f399d975768c58L,0x3189bf68af50c1c3L,0xa3f8d2df27dc372fL }, + { 0x99d6b416b8c7c529L,0x531707944406b1e6L,0xafb57933e3ac044fL, + 0x530ad3bab2548505L,0x791a290a977590caL,0xb0d07228646fd1fbL } }, + /* 44 << 238 */ + { { 0x636225f591c09091L,0xccf5070a71bdcfdfL,0x0ef8d625b9668ee2L, + 0x57bdf6cdb5e04e4fL,0xfc6ab0a67c75ea43L,0xeb6b8afbf7fd6ef3L }, + { 0x5b2aeef02a3df404L,0x31fd3b48b9823197L,0x56226db683a7eb23L, + 0x3772c21e5bb1ed2fL,0x3e833624cd1aba6aL,0xbae58ffaac672dadL } }, + /* 45 << 238 */ + { { 0x86d2f71530cf85afL,0x8e1b053cf7e634e0L,0xe79592f43a4e466dL, + 0x26752e8506985331L,0xfd098e83dff73363L,0xaa158e2c505ffbc0L }, + { 0xe45fa1cba0fe759cL,0x6e2f5989bc0d1491L,0x4a804eacae7210a9L, + 0x0e252f758a63f67bL,0x0d7600cf362a7df7L,0x795069bf6d5b2b18L } }, + /* 46 << 238 */ + { { 0x25f9f0fc0649613bL,0x109521f05d3005d9L,0xcce1c5b41feba4c2L, + 0x6a27cfafacda6021L,0x37ff83303ab6382eL,0x53c7ccb715ca79f3L }, + { 0xdffa6c9633611dd4L,0x7555cfd4352d3916L,0x2354bec62cbd44f7L, + 0xaf0044c54b0b500cL,0xe4835df7ce9aade1L,0x14e57f6bcb218644L } }, + /* 47 << 238 */ + { { 0xb5e26899b1c22bd8L,0xde12b0b51aaf3460L,0xc269595c31ee049fL, + 0x8c7513c88a73ed74L,0x8273018450cd009eL,0xb2cd2dec4d130b5fL }, + { 0x1a9015521971a189L,0x6ce23544c6f39bc3L,0xd76133aa9467badeL, + 0xf91173cc071ee7a4L,0xe54d8f44b8267c73L,0x5725e0676dc9aee6L } }, + /* 48 << 238 */ + { { 0x00e0a003daff1807L,0xcb9d155992c94fd0L,0x3c2b5c3dcebbf905L, + 0x9c799ec7d338afa9L,0x60b9908c4e2cfcccL,0x4bfe1a57ae3c6f92L }, + { 0x480d310efb116150L,0xa1ed6c31e3e7888eL,0x841a11d9720b5196L, + 0xcc337d178adff37dL,0x08c668265faa86c5L,0x945c90d49dfcc7adL } }, + /* 49 << 238 */ + { { 0x0fcc0854f2b3622fL,0x3a9e218ab6833f04L,0x209125d4ee8fc062L, + 0x98b2c628a3c3bf2eL,0x7e051fda83ca6a6eL,0x81afd3933d87981cL }, + { 0x8f3beaff4baf556eL,0x0f1b27fdcc7e66c7L,0xbf0b08f59f4a4461L, + 0x8eb739fa141985e5L,0xdb5b46112da43947L,0x63bf81cbe5cabfddL } }, + /* 50 << 238 */ + { { 0x355e40d398ff85afL,0x19f2f3c2b08f836bL,0x0a62d254737cb5f7L, + 0x5d0ef7d9f8c50d82L,0x773a399ebbd70eb7L,0xac357974a70bea8bL }, + { 0x1de5a45cb3b5d794L,0x67c58b52a48b55b7L,0x724f56f4b02ebc8bL, + 0x03dc71e3154ad508L,0x9bcd3939cc84428aL,0x7fdba978158c4a0eL } }, + /* 51 << 238 */ + { { 0xac08e06e65b93d44L,0x2397625a5358c691L,0xfbc9285a8516e31aL, + 0x38ce0d3544ffe25eL,0x13381dd16414072bL,0xf782fddc170ecb4eL }, + { 0x78c71a716f815259L,0xb725870573659a85L,0xd37678008712d968L, + 0x153d8aee3eda5006L,0xda4fd94818f1439eL,0x6384135352dbfdf8L } }, + /* 52 << 238 */ + { { 0xce92224d31ba1705L,0x022c6ed2f0197f63L,0x21f18d99a4dc1113L, + 0x5cd04de803616bf1L,0x6f9006799ff12e08L,0xf59a331548e61ddfL }, + { 0x9474d42cb51bd024L,0x11a0a4139051e49dL,0x79c92705dce70edbL, + 0x113ce27834198426L,0x8978396fea8616d2L,0x9a2a14d0ea894c36L } }, + /* 53 << 238 */ + { { 0x06d57f2920514206L,0x61394b863a2cc1ebL,0x0ffdf49a86c7b2c1L, + 0x65334e9349f58f13L,0x180b10b8c08dfb05L,0xec352adef6c95b7aL }, + { 0xf9801dc0c4bde0faL,0x428c77f0dabf0c66L,0x2a7d1bb0c2eb80d4L, + 0x81774172fdb56fabL,0x7507481f1d965515L,0xee0693bb8ebfadebL } }, + /* 54 << 238 */ + { { 0xf4589418ac56a031L,0x21f3dec6f2718a10L,0x0ed08d9690f28b6fL, + 0x2624bd7a35c3a6a3L,0x1b3f02e8bba795f2L,0xe629b5aa3977fd17L }, + { 0x66c8cd7691e8df1aL,0xf36c4e2c1b2b5542L,0x7f6b742f7dff66a7L, + 0x00bc68b8242e0fc2L,0xdff5c73360119d9bL,0xe726260fb5c4dddfL } }, + /* 55 << 238 */ + { { 0x0242fa358eeaa549L,0x2d081bcf8abc93c6L,0xaa31813c55551d40L, + 0x1cf21c1271db3aecL,0x5a6dede7203880d9L,0x389c63cabe4aaa9aL }, + { 0xff4db7d4bf28086fL,0xd89c039b33146844L,0xc2b32bf06df6f790L, + 0x7f4e836b9f22fecaL,0x3f64d0fa0af51572L,0x681a1f5bc67aa565L } }, + /* 56 << 238 */ + { { 0x9f9ac9608e2941a6L,0x43e7ff902fc4fe1eL,0x5ec413596033e041L, + 0x5ce791c46f6ff0f3L,0x8d134b899d907343L,0x7bd15c7786304df2L }, + { 0x2cd2ebc777c4a913L,0xcd86a39d45f07153L,0xe7e12d2e88bc423bL, + 0x478e814b0b3163f4L,0x78bd9c8abe8ec766L,0x6a5763e87709ce48L } }, + /* 57 << 238 */ + { { 0xb503ac624329d7f4L,0x3a900374488e3ce4L,0x8a11addab0d8dc97L, + 0xbea3ea2c0873bdf8L,0x0f57130115bc7adeL,0xbc98d2070b2b69a0L }, + { 0xaefc4047639d182dL,0x0e6db26feb3c44eeL,0xaf0f8b392a68a48dL, + 0xde65a6b36bf1e593L,0xe48f8fc989dbd38aL,0xad18a43bd8d285b3L } }, + /* 58 << 238 */ + { { 0x249d86007e9d48c8L,0xec6109ba109a54bbL,0x64f688af5ac65ad4L, + 0xb12c85b4be1796baL,0xcc258d31c9940da0L,0x59590853ff2f151bL }, + { 0x9e9edc4d401c5d1dL,0xdd9ad117f230b458L,0xc2c752ac962334b6L, + 0x3fab66ce27327e6cL,0xa363d3643816a47eL,0xa6fc57bec180bbdeL } }, + /* 59 << 238 */ + { { 0xd72dd5893ff345d5L,0xf87c17ae41e1d287L,0xadadbf525964d55fL, + 0xecc7f27af8b07db1L,0xa2dacfce6f2aa320L,0xc7936da72aa3f228L }, + { 0x2e9e6058fa504b87L,0xf2df43279d0f0634L,0x90d5ee22a4b768c5L, + 0x1ea9bf0b5b46ea84L,0x792370f45cc41770L,0xfd17823176c1a3f5L } }, + /* 60 << 238 */ + { { 0x4f1e1254604f6e4aL,0x4513b0880187d585L,0x9022f25719e0f482L, + 0x51fb2a80e2239dbfL,0x49940d9e998ed9d5L,0x0583d2416c932c5dL }, + { 0x1188cec8f25b73f7L,0xa28788cb3b3d06cdL,0xdea194eca083db5aL, + 0xd93a4f7e22df4272L,0x8d84e4bf6a009c49L,0x893d8dd93e3e4a9eL } }, + /* 61 << 238 */ + { { 0x4c124a904190257aL,0x09002f52347e517bL,0x2e9b69a1e5760993L, + 0xbaa49e53e26672bcL,0x9468fc3bf7820190L,0x637bccfe1f955328L }, + { 0x16fd33f26e0aa088L,0x9391550757b2b2adL,0x85e98842e9a0ace2L, + 0x8e2bd52b4fa787afL,0x8a86bd85644aeeacL,0x63490956c2814734L } }, + /* 62 << 238 */ + { { 0x5e902fb3063b3517L,0x0cd006cae5a65212L,0x597bd7804591c4bcL, + 0xd853d81be17c1d3dL,0xbc4bf68156e5d24fL,0xbc801615d26b5ce5L }, + { 0x1ffa5cd5caeecbe7L,0x16ec32a4b0203156L,0xaaad43269a857672L, + 0x0606ebf9189c6f6dL,0xb90730bd57e476f2L,0xed8d82b1d492fb05L } }, + /* 63 << 238 */ + { { 0x69a2a9b6ff824814L,0xe7b716e7c35c5da3L,0xb6781a5e9a5fde1aL, + 0x08bf695dc072e1b5L,0xaadf71462590a817L,0x490297f9c755c83aL }, + { 0xbd9fad6191c29990L,0x87b3abc226b6cb9dL,0x6975d59865fd0b64L, + 0x0fdc5267f4257158L,0x9f3e10585877bbdeL,0xb7f4cfb04297a2d1L } }, + /* 64 << 238 */ + { { 0xd699ea2d8d095606L,0x3cd080c51e0ddd3aL,0x46604bad66a8b35bL, + 0x0c779b624233fccbL,0x578458acbfd3cf0cL,0x6820f66596bf57afL }, + { 0xa9724245bf1f302cL,0xbbde24da277a6c3eL,0x0980a5b8c6be8c14L, + 0x6230e3ec774d62c4L,0xda1467d84fbde24bL,0xd9d68d07cc862204L } }, + /* 0 << 245 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 245 */ + { { 0x67c516347378f90dL,0xbc201a7966647082L,0x77fcc8dc9ee450cfL, + 0x8dd2b318b41a3e2fL,0xdf6a935e93bf0689L,0x75edabf3a92e5464L }, + { 0x49afcd9f604d208aL,0x372f0ea7d465ca48L,0xcdbd8ad2c7ea7810L, + 0xfe61571e550822b2L,0x744a4f9386606adcL,0x6beb3c9cd9d4e110L } }, + /* 2 << 245 */ + { { 0x1fef389ce700b9f2L,0x63029466425bc8abL,0xbd770a1437f04a33L, + 0xc7438e29d0169369L,0x6b265742e2377cc3L,0xdf24bf96c369fa4fL }, + { 0xdfdbcf470ad94e08L,0xd101b8617f75a7dcL,0x5574a0b82a9c483cL, + 0x0563fe942de43228L,0x58ca0e8aead1fabeL,0xdc3d9a8466023966L } }, + /* 3 << 245 */ + { { 0x383bda07c3fd20e5L,0x9619b1df5c29449bL,0x6f3c717d369f39bfL, + 0x1bb593d11a5a3900L,0xd0f07ecc2aec6c2bL,0x9d72eb2a4240b202L }, + { 0x35342f6cc50e4a0cL,0x701b46626b93bf61L,0xfcd6eb09ccb6a888L, + 0xabb7a6f785aa42c5L,0x952f8824aa4e5895L,0x49860db85c406582L } }, + /* 4 << 245 */ + { { 0x3667a7203955812bL,0x0d73483b284d1dacL,0xe084535efc62f791L, + 0x5bc1652b389faf7fL,0x40cf51683a71b7f6L,0x8a4b19fad4f39703L }, + { 0x823e754a2a8eff13L,0xf01b2021bffa5afcL,0x5639ee027225b319L, + 0x7533bc86fc282f16L,0x710009d2c69f61aeL,0xe30c499dbf65e803L } }, + /* 5 << 245 */ + { { 0x0da7ac1b734b4ec3L,0xf47fc1d012a2afbeL,0xbbbc99be87dce4a2L, + 0xf7264b4edd5c6378L,0xe9409305f618ffdcL,0xafadda9bd1846ac1L }, + { 0xe734f9d0a21850d4L,0x199cb44f8722a316L,0xcfe8704b38cae89fL, + 0x2db1e56b6b151b57L,0x116ca5cf69ce7b2cL,0xe9b8625f57de97c8L } }, + /* 6 << 245 */ + { { 0x18811bd5af247c49L,0xbc180793e124dbdaL,0xed978d3a21234fc4L, + 0x516dd9a70616ae15L,0x8f80677774e430b8L,0x9094256906e8fc49L }, + { 0x4ca03fb5a4e61235L,0xb91de709b617f361L,0x0898d82d0ed08bc3L, + 0x2bd712368cb08146L,0x45b92d45e213176dL,0x05894791f2bf5b9cL } }, + /* 7 << 245 */ + { { 0x0d79cb892695ea2bL,0x2cb0f8dfc88e538aL,0xc1b8dc3da80f36feL, + 0xd756fa6684f00cc2L,0xa6f1cdec9cb9efb2L,0x5c3f15a8a6a21818L }, + { 0x9a7ee3516995d09fL,0x88885463d70434bfL,0x18cecc6d4f7d5d33L, + 0x3f0138866b353bd1L,0x53bf798b0d9ad368L,0xeffd465a28dbc3eeL } }, + /* 8 << 245 */ + { { 0xeb29e44cb5d98ac1L,0xe47e57f80e227a4fL,0xd09c04943d2bf688L, + 0x3ab7799a47428dd2L,0xdc558d6be9aafac8L,0xc042c4cd87f9f6e0L }, + { 0x93842bcd89fb4693L,0x62dbc82f7068fbf7L,0x164552687e6d47b5L, + 0xab304b7a4c37eeeeL,0xdbb3d4e13fc412ceL,0x4f65dad0a726a2c8L } }, + /* 9 << 245 */ + { { 0xb25e01b2605cdaeeL,0x74abec55bc57969dL,0x9c57bfabcdd9d41aL, + 0xa3330e3f4a9e32a3L,0x5929a0d8e5792fd8L,0x830b4ea271ea2cdeL }, + { 0x80065ac1fd06d246L,0xa2b416e632e64a25L,0x3950bde7c0c927a9L, + 0x9951f3bd679d9b8cL,0xc235a274651b6855L,0xbfe5e08e5ad97bc1L } }, + /* 10 << 245 */ + { { 0x4409a5b6744ae145L,0x5e83fa0b7f620908L,0xfc489bec2e140aa0L, + 0x5805a462e3cae337L,0xe56e9ff7c2211c21L,0xb722f2b40c955362L }, + { 0xb098a32f41371f33L,0xe6cceceabb4923d6L,0x1cfbe2b3d82a311cL, + 0xcf9428936b98f917L,0xd60dc62492ef848cL,0x34af446e5adb5228L } }, + /* 11 << 245 */ + { { 0x0eb7e743796ce1caL,0x138653e5d851377cL,0x69c7c86f2b11c8e0L, + 0x878ec1decdf2b205L,0x03e6688aae0e8562L,0x20810666935a36a8L }, + { 0xc8ab7c7f26635c50L,0xe75cdb06744a21dbL,0x4e26f32fd720e198L, + 0xa1c6395ad8cded81L,0xb75dc6ea6ce4fc04L,0x71750b33004623b5L } }, + /* 12 << 245 */ + { { 0xbdef84077e60c447L,0x88570f712a65accaL,0xef3d4a400bb6aa79L, + 0x5c9d189060212976L,0x80179ea21d96c43cL,0x3f002e6d53d2948eL }, + { 0x14b2cc9149d78183L,0x7a549c71b496c279L,0xf4beac3f44995f6dL, + 0x5a34239800bc78feL,0xa874dc1b60e42da0L,0x3a984010cf5824d5L } }, + /* 13 << 245 */ + { { 0xe514ee06dfb9760cL,0xb8862d7577b8951fL,0x0144676ef8ee1141L, + 0x49561a3002eb3e82L,0xb3541c154ff9f897L,0x1670edf0a7a99791L }, + { 0xd41d603564aea7f9L,0xf66ffd092b3463b4L,0x0784e015c3b26fb6L, + 0x88edce33ec46f8c8L,0x1b1e25a3b6381011L,0xbfaadc03ff95ab97L } }, + /* 14 << 245 */ + { { 0x727a59fe0c7be4e1L,0x75a7d5e3f58ced15L,0x146fc0d990f569e7L, + 0x94dbccd2b7f1dc54L,0x0df1ef90b75bf232L,0x2943a082a2568190L }, + { 0x75f2f80d67837b06L,0x07e3506f24b44b6eL,0x7c30829ad0d2231bL, + 0x9ce577ca93277abfL,0xa19d1868b17549ecL,0x0ad6ff5525e8c4d7L } }, + /* 15 << 245 */ + { { 0x16b38dfe1c24d075L,0x3acd4c36992959f6L,0xdaf2fe88ac2da7abL, + 0x76e8ff0e89644935L,0xb8547c26e85f7076L,0x9f149faa1cdea7ceL }, + { 0x181a60729e125d84L,0xc4aef9fa18751ce6L,0x451c84660e00f00aL, + 0x662b3e7ac4e3e6b8L,0x57b7114ec6b64507L,0x07aeb1980b37fb70L } }, + /* 16 << 245 */ + { { 0x79d88e004516234aL,0x98dd3cb931f9cedaL,0xb528000fce7d606eL, + 0xc773557e2fa27fd3L,0x55b53dd3e19436afL,0x675084b3e10b64c7L }, + { 0xe583266556d56374L,0xf8f7fd2a307e2e60L,0x7b93bf537af3e3dcL, + 0x94fafa2cf47d298cL,0x94c2ff9a21121369L,0xa41de95f33468ff6L } }, + /* 17 << 245 */ + { { 0xebbafd4720f25aa7L,0xe2becad71ac444bfL,0x323356a092a944b8L, + 0x32feccc0c9a3cec9L,0x15ec3aaf5f9e96c1L,0x852142b5c12c8e62L }, + { 0x098ffcbf2b6865f1L,0xcca470e8733d7741L,0x0f8c0f5271945bf5L, + 0xfb654f6a08068827L,0x3a9e7d742a0e2829L,0xb90742b04b687763L } }, + /* 18 << 245 */ + { { 0x145afb651fdb2a7bL,0x93315b684eff5eadL,0x0cad1d20e40ca999L, + 0xda9b517a379a8173L,0xacb665780ca018cdL,0x1e9d919f481969b4L }, + { 0x5c9a058d68130364L,0x872e26620a62ce5dL,0xca598848acaabe54L, + 0xdabfcee18aa048a0L,0x16198d034ac52a57L,0x72eb5ec632b6d102L } }, + /* 19 << 245 */ + { { 0x13f2e1726a0c96e0L,0x55aed9e02d6b6f05L,0x3c919ba3bdce76c0L, + 0x647a525ffdda39aaL,0x5c0dbecc01a9011fL,0xa537ba8d9fd9dcefL }, + { 0x8472e375cff62467L,0x57672311ed5adf05L,0xd1e178dc6a423de3L, + 0x3ebcfe18d3ad3ca4L,0xb8f341d7ae802c11L,0x3f14c424ecdfdb7bL } }, + /* 20 << 245 */ + { { 0x381e0a136e4d2e42L,0x2f2a4ee183c0d752L,0x50d4647fc8e6532eL, + 0x7e210aeeb4e7495dL,0xfd147710bcd142a6L,0xddddb07b06429213L }, + { 0x63e06fc64548a6b8L,0x05d9b825904f92a6L,0x4b63fdbf9988ee79L, + 0x6cfa412f9b3366bdL,0x0dd5fe3dc8c61f51L,0x3ec77027be8e047eL } }, + /* 21 << 245 */ + { { 0xea7d01cfc7d81791L,0xfa6c0fe6e2264afdL,0x53c7eea363651291L, + 0xe58f8411f2d90f92L,0x4919b4c61faf0e14L,0x0c7dcd07148e98a0L }, + { 0xf9ef44cebc8bd43dL,0x3acfb6686f83cfb4L,0x34130e18f883693cL, + 0xda9ed2ae2d236c3eL,0xf54da64cc75cabdfL,0x1c3df906cc01722bL } }, + /* 22 << 245 */ + { { 0x686796c68d8f2286L,0xe0efaf9334d7cd1aL,0x84f9237c93b23708L, + 0xcb50cc8ee47f5161L,0x498b81e71f597821L,0x3c3f33e1a491079fL }, + { 0xee300c6dc69d1bc8L,0x279760e734778389L,0xe00ac0eb2bb8ed78L, + 0x9bf9a10e765c8b5dL,0xc7e95c0cf8c1e909L,0x3721300ae6e63ea5L } }, + /* 23 << 245 */ + { { 0xc03ad784d8dfd7aaL,0x671384a64b065a2eL,0x9b21e9e7bed74e87L, + 0x153b606cf889f75bL,0x7345c62a2aab6562L,0x270e4f445960cb4cL }, + { 0x515909fb885f0f88L,0xe43ee4f7067a7928L,0x5f906fc8fc182e56L, + 0x297ad5770641d0d1L,0xdcc45aa1d1b188b4L,0x8c817fb2ef062a39L } }, + /* 24 << 245 */ + { { 0x91e8c992044637f0L,0x01f7838827ee8e8fL,0x7c5e3f6dd095f5b9L, + 0xed7522fcddf3cad2L,0x80bb87056c57aacfL,0x495480b00cc5ff51L }, + { 0x964def7f04da2565L,0x8b0d0fe3afa72140L,0xcc75192584de66a1L, + 0x9acaf7fe075f07c5L,0x6505c2f81eeade93L,0xa2f35aa00e3cf58fL } }, + /* 25 << 245 */ + { { 0x1ad38a2d80548b22L,0x4d6120df47a37b3aL,0x6d64ef8c23e33cb7L, + 0xa1b5f51723c14ca6L,0xd2cdd425039a8e83L,0xa0a359ae229dd2dbL }, + { 0xde0788166c2779afL,0xd960453362d2abc2L,0xc5c48b20707c0e4dL, + 0xe452debd691c5407L,0x35c37ca882b0a299L,0x5b263014da3cde7bL } }, + /* 26 << 245 */ + { { 0xde34fa4586330487L,0x8391248153f61e6bL,0xd3f8fe742d04958dL, + 0xdade250f6df77d09L,0x3a3a16175649d9ebL,0xf9b77847a23abc74L }, + { 0x31d45db63b2e2c8aL,0x311ecc24f61a7bf4L,0x206029f9c56eab17L, + 0xb9d9ff35878c672eL,0x0d268c160fbf2d91L,0x2474b527a45f58d0L } }, + /* 27 << 245 */ + { { 0xad8e84be8436beaaL,0x8f07eee4209eb5d3L,0x47cba1d83ee61bddL, + 0xa081f21f72018544L,0x5dffddf493d88d16L,0x539a79efcac3952aL }, + { 0x990af57791bc452eL,0xb139d7d5012f5c6aL,0xf818c9f3fb180417L, + 0xeeb2d08475566152L,0x287571253f5d4ec9L,0x5a26505daa959798L } }, + /* 28 << 245 */ + { { 0x6536834e11b0f7b6L,0xcaa5271aad46c10cL,0xb5b6ead1fab43763L, + 0x25bf402ff7f7d8fdL,0xf33fb223e19374b4L,0x183ae9b75f348172L }, + { 0x1783c235078862a0L,0x9981a6c33cd368fcL,0xf58d2274fd627f9fL, + 0x37ac9c265c5e71cfL,0x167c8d047b0f157eL,0x24f522f8eefc7d85L } }, + /* 29 << 245 */ + { { 0xd25aeab3926cc973L,0xb3e2cffbdfc2cfbeL,0xdd259ed1de742b6cL, + 0x9d77c94e7b98bf81L,0x90f9067cb0ead3d1L,0x148f2a192a93fec1L }, + { 0xbae3c543c2850153L,0x0d330d758910422eL,0x06f80a9efa670474L, + 0xac6cee9f038431a3L,0x4900d17f5c22ee99L,0x62de04aa275a9774L } }, + /* 30 << 245 */ + { { 0xb6eefcc55f87fb35L,0x9766873b4371415aL,0x308337bd16b058bbL, + 0x6d5b1ddae1ac3884L,0x9307aa0835c4630aL,0x22cfcc0c23e91988L }, + { 0xbeb3814c37db0207L,0x19ab212fc4bbaf5bL,0x0801a1cf21abf22dL, + 0x9e6862cb3bd07332L,0xaa12ba0e4319929aL,0x0da45831f540f97dL } }, + /* 31 << 245 */ + { { 0x67d8ac9484bbf927L,0x7dd04e4e4ea01d33L,0x24ea6386f13def66L, + 0xa8a1acbe28f7f5f0L,0x5f578ffecc84c93bL,0xda8fe295f4ad116aL }, + { 0x4b610ae48483347dL,0xcac5c5596255f9e4L,0x19a0e043abcfe47bL, + 0xcd0cc9493966784eL,0xcc59a36743279291L,0xaa504087802961b6L } }, + /* 32 << 245 */ + { { 0xbe45d81a1b270599L,0x50696e7d97d6c603L,0x63c5a516b078ea89L, + 0x9f3efe41b4464764L,0x84580e24101e5232L,0x00850a1ac8ae8220L }, + { 0xbff4077ded55c404L,0xd74de734f2e7bf50L,0x4df4eef207e1c03dL, + 0x4ab3d0396e654d58L,0xb20056cd086f1596L,0xe4d08a278acd7cd5L } }, + /* 33 << 245 */ + { { 0x5510cebfe354510aL,0x48925b9349998c9bL,0xa05fc961e6d707a0L, + 0x85bf38f866ebc93bL,0xea637045254e615dL,0xae25e2e740d8459aL }, + { 0xa98583176efafd1dL,0x863931fd5a51c4b6L,0x3810d732d4221708L, + 0x959a2f70762a30f3L,0x7bdbaff9420ad3acL,0xba41b20bebdfe90eL } }, + /* 34 << 245 */ + { { 0x5e4d3280d3171eb9L,0x3fb715851bc65c5bL,0x6558962a901a899cL, + 0x78b7cd3e7851462bL,0x21228419ca8f6495L,0xfd8d8f9b2d8be765L }, + { 0xe5e90b92bc562144L,0x4f1f7ca1ae3243edL,0xd20178cd0985f4e4L, + 0xe5be263304253cbdL,0x1e34141c0d348fadL,0x0073fa0dad0eef45L } }, + /* 35 << 245 */ + { { 0x922ddb84d403f20fL,0xf7bccbb54681def7L,0x81a1200f6b580442L, + 0x64901025dc2f9884L,0x3746675aabe78edaL,0x3e750369aa6f005aL }, + { 0x140477ceeb00658fL,0xc76a320ccf89be62L,0x00761f21658c127fL, + 0x669186dfb8b6b03cL,0xbcdf1c36dcb26a2aL,0x94a7aba5da876a56L } }, + /* 36 << 245 */ + { { 0x1872f65c26163265L,0x9fbaf44fda52ad9cL,0xbec7addeeda47d38L, + 0x6a04dc3078094f9cL,0x2c73b8f15f4498e1L,0x504909efd4fcfcb4L }, + { 0x747efbc6b6b3a63bL,0x856e276de0dadd96L,0xa22459aaae3be3a4L, + 0x9ef59e732294a854L,0x0717d4e5d0e36205L,0x5a6afa3eb734cdf4L } }, + /* 37 << 245 */ + { { 0x6bd8fd330e938950L,0x8b26d7fa0f20c4f3L,0xd29a1121e0604d4eL, + 0x23d1cae60711c191L,0x460af39d51914cb2L,0x9cd04208547463c1L }, + { 0xeb80d70e493b7a0bL,0x182568869171652bL,0x9f3007ad76ca8b21L, + 0xf9bdeb4664ac10c4L,0xdaddd584284ae80cL,0x5c7ea28a0022abfbL } }, + /* 38 << 245 */ + { { 0xaef75aa7dc3c897eL,0x98bab5852e6432a8L,0x522b383d83fb0ee5L, + 0xe0d8620f056a8589L,0xd63525dd39352633L,0x74362bbfaeb985dbL }, + { 0x11419f4e8c0f17feL,0x3ca918b0494ba972L,0x39f2bc3c6e074e25L, + 0x3bb66618fbbf0d60L,0xee60c8f88579fecbL,0x916f3fe92a9b905fL } }, + /* 39 << 245 */ + { { 0x14ed31b6482b668dL,0x8e3e10db5b65978bL,0x72ff92eee8011bafL, + 0x5183d0bde1143531L,0xdb628188f9c740d1L,0xd23cb9c57570e3d2L }, + { 0x9e893cacd2745832L,0x49762940ef4a2b31L,0x02f6f892324361bfL, + 0x332e089dd7a881bfL,0xe9303153f788f52dL,0xcd6d15564e7f1bd7L } }, + /* 40 << 245 */ + { { 0x8caa623d408b62b7L,0xa58aa0b0c0272b41L,0x089af856ee285bfdL, + 0x77b461f6d0674ecdL,0xbaa9d9b38d6f6612L,0xa8f26e12590669f8L }, + { 0xb164340c5ebb5e28L,0xfdc11f7401ea89a8L,0x73c03b9176e4346eL, + 0x6a678eb17caad5fcL,0x103ff0790a87803dL,0x25d6fd2af7430a94L } }, + /* 41 << 245 */ + { { 0x72cc0aba66116d84L,0x642c88681039c0fcL,0xaeded9e6d96a7423L, + 0x4ff4163ccc5fea03L,0x180e4d3616483ec5L,0xefde910a7f6332c1L }, + { 0x8042696283367060L,0x4edce3e8c28af356L,0x2452e4de965139daL, + 0x15129fd9547477a1L,0x7f628b5ed80998cdL,0x7c56d44541054b54L } }, + /* 42 << 245 */ + { { 0x4c3f81184d3d9da9L,0x332072f9e1e71487L,0x8cbf7284759ef371L, + 0x3d13d85cb98ce007L,0x507b467f980f4fd5L,0x9853b98bc74fdfdaL }, + { 0x94b81534993f5e19L,0x316b761beeca71adL,0x09820a2331c04080L, + 0xc71a9bd4420e3114L,0x569f813822ea67ddL,0xe3ec5d2b3a41b079L } }, + /* 43 << 245 */ + { { 0x6085b24a19bb6f27L,0xc2f18e8f64dcb82dL,0x8ff89ed91fd3888dL, + 0x9fbe31db0e525a5bL,0xd52dfb5df0527573L,0x90288a3f703193c3L }, + { 0x87bb5d30bb1ce380L,0xb6c9a4c9f0dcf59aL,0xcbc52966aeb86e7aL, + 0xd151178a9a1636eeL,0x48342994e4b48c74L,0xe5bced925af80bc2L } }, + /* 44 << 245 */ + { { 0x106882534918179cL,0xdeb69dde08143b36L,0xfb3c527b992363faL, + 0x11d05e93e9393832L,0xe3249558383a0f59L,0x2d0f3e11c234ab5dL }, + { 0xd50a30d95c599ae7L,0x6d7abc6ce9f98316L,0x3d190629060ab6ddL, + 0xfd58473c81d69afcL,0x841193d24b782d62L,0x4f72696da771226bL } }, + /* 45 << 245 */ + { { 0x288895d056e467a5L,0x78166a95e025a5b3L,0x89df640e895835dfL, + 0xdc2b61f483dcbc50L,0xbeaa7363110dd6a0L,0x2346a2a5e7fdbe3fL }, + { 0x379ae5fb6947a9c4L,0x9dcf01956370a372L,0x34c3c6c3d70d9a24L, + 0x98ee14b7fe6a3d0aL,0xdd37708bba8ce5baL,0x785adb86a15c3672L } }, + /* 46 << 245 */ + { { 0x4c93de89c5ff194aL,0x56aef366fdc94109L,0xc8cb2a0c5b0b23d4L, + 0xd73f1cef587ada16L,0x7138315a364b1463L,0x43940ef59f6bd411L }, + { 0xad068e490f4a533fL,0xe8a772a33c7dac91L,0x74b815fc107998b8L, + 0x4b8fa9db92699ee7L,0xfb2de4bf4cbb023dL,0xe5833a390f67c29cL } }, + /* 47 << 245 */ + { { 0xe985acae7fc4fa91L,0x7730e38ec66c4282L,0x4b971449f4bda67dL, + 0x55261be02b001f47L,0xccde0c7126d0d8e6L,0xa7ac56fd701f6febL }, + { 0x2488b28552642a53L,0xeada397c58fcfabbL,0xa3fc0452b679b0e3L, + 0xd0ef09ffec2e921aL,0x9fcfd991575fb70aL,0xf4adcbbb366cb10dL } }, + /* 48 << 245 */ + { { 0x517075af5faa0cb7L,0x400a22c1efaf68f4L,0x320ce9493b86f639L, + 0x511565717f296bf4L,0x0919607a96108276L,0x4fcc39a02f035900L }, + { 0x5d13de7cefb73f3fL,0x19d725c5081c38e3L,0xf1b28089c0f58697L, + 0x2adcd1a30ca7ca20L,0x96c07f42c21e1be5L,0x94d28cacbaa0aba0L } }, + /* 49 << 245 */ + { { 0x0ff4983fd64cfa4bL,0x2c49c4918c55942cL,0x6093eb7f98eb20baL, + 0x1b33296a060497baL,0x32776a53c92d7b47L,0xf367e6b25241de3dL }, + { 0x711119813b65228eL,0x2e5dc541e1394451L,0x940a4a0f98ef33e5L, + 0x1a395be32cd4315dL,0x4d49469f3c2e20e1L,0x5384f4b95c314f95L } }, + /* 50 << 245 */ + { { 0xdda2f3a0a256813fL,0x4363d190ee6cbae0L,0x61f4d607930d0094L, + 0x6767ff4817021739L,0x8450091bd2c5fadbL,0x144d02fe870710a8L }, + { 0x73f45d9035524b7bL,0xccc7856b04615373L,0x0eb5cd436f081dfcL, + 0x9c433cbfe3a70d59L,0x9ee70f509818349aL,0x16de27347241c634L } }, + /* 51 << 245 */ + { { 0x02a24c5cc47f7db6L,0x519242cd33d60e1cL,0x543f39cf7244a636L, + 0x4ae15d698deb181eL,0xbaec81ef44261806L,0xe5cb18bb5fbf13abL }, + { 0x7534787a032158e7L,0x770e1e34da0d9a6aL,0x251bfa7158f9baccL, + 0x12663214c8d39905L,0xb7bfa81b39c3d64aL,0xd6d439ffe3ee296cL } }, + /* 52 << 245 */ + { { 0x192ecf72d0aa048fL,0x23af774063e40c0fL,0xe4d98e41d804d367L, + 0xd868cc885405bfc3L,0x96909a5b6f6ece88L,0x16b05ad2bae60dabL }, + { 0x7382a1dbde621949L,0x569bb6c9c47cf6dcL,0x892da43e1f2d098bL, + 0x6bd959b9bfa25649L,0x90617c419cb48f9eL,0x36059b73f110b22dL } }, + /* 53 << 245 */ + { { 0x1817b140791af82aL,0xf4a44cde042870c5L,0x60b8414ab5c0405aL, + 0x3b00f5ddf4dc4a9cL,0xa61aa0cfea81dd5bL,0xd43c37422554907dL }, + { 0x3fa264a620569ecdL,0x2cc69c2ba5a46190L,0xecd4f6d3dddd072eL, + 0x41083b72dda8de01L,0x4bc047f110d6f156L,0x7164b432cac3203aL } }, + /* 54 << 245 */ + { { 0x7e7e08f401d45bfeL,0x04f9c9ed0e2d17e2L,0x3213556fa55bc148L, + 0xc58983c734449f0eL,0x463217afaf2bb219L,0xe08a51a2f8fba72dL }, + { 0x2f44991e974d51f0L,0x15f2171f3f12af56L,0xbcc919de24cf01f3L, + 0x9ea371f269399bd0L,0xae8a8eca3ccf4574L,0xf0535b83ae499429L } }, + /* 55 << 245 */ + { { 0xe9ad8928f72305e3L,0x4144b6b9fce1295cL,0x672732a0c3487eb9L, + 0xf19d09a6147f70b8L,0xf45f6a11362a7684L,0x84ce4f25adfbbdadL }, + { 0x31e4bb0ac3403b48L,0xefc861b9b478ab38L,0x3323df44a8320c49L, + 0xa2838aa1ed4f14abL,0xc80e30cc63bf7df7L,0xdd2d5ef9f15ec5ffL } }, + /* 56 << 245 */ + { { 0x3027c1698d6f8572L,0x89326850111e64d7L,0xe6eb6cd31b8b0179L, + 0x0d2d27ea6dd5a4a7L,0x41682c0007c82f11L,0x5a01c54c81075022L }, + { 0xf3903f51fe7220d0L,0x75daeaba1f8e66b2L,0x1b625eed470bd3b2L, + 0xa46398a7e85a6293L,0x8ff6ef8c805ad640L,0xb3430f6795bfa3a5L } }, + /* 57 << 245 */ + { { 0x55d31765bc9341b7L,0x6530526ba312d125L,0x57ad29c02e9eb238L, + 0x31658a8282292155L,0x4d3417b169301639L,0xb38d6199e48c3d1bL }, + { 0x4399d5ddcc5202eeL,0x4b1c293a5076cc08L,0xa46e87f5824171b0L, + 0x16f75919e4cb40e9L,0xd086562dac35d85bL,0xc2b41ad532713f5dL } }, + /* 58 << 245 */ + { { 0x2da6d2ca3248f02aL,0xae49d2fc675de73dL,0x4abb1a65cfbfee63L, + 0xc6cea22cf1246350L,0xdd510cf82d3faec5L,0x8b7d1b0865e7460bL }, + { 0xc5b39c802737b182L,0xeee61e0d8963c709L,0x9cf9da61793e7179L, + 0x630637e52a295ba6L,0x18b85c9fa3881ba2L,0xca091a9464a94fe2L } }, + /* 59 << 245 */ + { { 0xcb68739f0bdec121L,0xf4907b3cd3811dabL,0xcf1b079b8c5d7707L, + 0x9ef9002d2fc6a56bL,0xc4c9d069809e8b64L,0xaf86a3db90d0eef4L }, + { 0x30a52f994b24a04aL,0x03bcd7a958574ed0L,0x330ce8a1a5b52b8bL, + 0x632b3c2d5e6a8ed9L,0x7b080a2c18369382L,0x12173e5f65187ce1L } }, + /* 60 << 245 */ + { { 0x027f654feabe8ef1L,0xd9d327e481a51834L,0x9215df61980faa43L, + 0x76b4f8003ba045c1L,0x8f3ce587f400732cL,0x0abe1f34f133a3caL }, + { 0x2ec690526de4f504L,0xa297cee4cb7ff026L,0xa31a76e3cadaefe1L, + 0xb701391e1173a958L,0x0a4279b08c8768f1L,0xd58927c12f8ede03L } }, + /* 61 << 245 */ + { { 0x71ea38454e630b0aL,0x4f696b59119263abL,0x9e7cb293f9cbab69L, + 0xa448d591c60ea8d2L,0x5021d4ef7d89eb52L,0x1a1ea5e3787663b1L }, + { 0xa95af4eb05bedc8eL,0xfe72effcc2fba411L,0xa88b79bb19a2c6bdL, + 0xbed948fac84c78eeL,0x022dcf3d5ee7455eL,0x0c39c3689f56accbL } }, + /* 62 << 245 */ + { { 0xe0e818a8b77c9de2L,0x0dbaea885e07f77fL,0x6ece83b97b1f96f0L, + 0x3c02e59631733a5dL,0x44bcdfcdd14828ffL,0x2791ca54b66f6107L }, + { 0x1a051c5a6198f24dL,0x9cd5f09a17627301L,0x64323392004a0cb1L, + 0x75d6819b3cc13e05L,0xf5cab2874a58768cL,0xbe090e83e3ca9332L } }, + /* 63 << 245 */ + { { 0xd639e0f3ab9b278dL,0x57f3f8cafa2407b4L,0x6720549f6c11f6abL, + 0x6ad1c608e784308bL,0x62c31e4a196babbbL,0x764b4deed1d36447L }, + { 0xf44efcefaf4407bcL,0x7c1f45dbb3ca82a3L,0xf43e4a8773b952b3L, + 0x145cd2d6ff478bbeL,0x11ef2df450c8e708L,0xa2af06f044491734L } }, + /* 64 << 245 */ + { { 0x8cd6c9f7c90b13f5L,0xec0c187d52a9d469L,0x9c0db0f589b8ad2bL, + 0x692a8db70d9c999dL,0xa407fd03c9f84ab4L,0xa5742fd1cc9a906cL }, + { 0x4813a765c8e72867L,0x9c65943de2e9a10fL,0xca6bf2934fa0a23eL, + 0x1dfa3af7cb1f8d7aL,0x28036f5498d10c53L,0x7bfbcaf20e012c13L } }, + /* 0 << 252 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 252 */ + { { 0xa53f1a104ec177f6L,0x4a2ef9aa3faa5ca8L,0x30efed8532976d13L, + 0xcf5ada165ee692d1L,0x3ceda69d259e7cc1L,0x2aae29e99baab472L }, + { 0x7ee5baef737cc8bcL,0x1717af747fe68dedL,0x9e5c8ddacfdaff63L, + 0x575c8db9cec07693L,0x9afc8ae0fdfb509dL,0x27836d3685651697L } }, + /* 2 << 252 */ + { { 0xa7342f9517eb9264L,0x9264a6a00a8a6eefL,0x50e48bf07471c384L, + 0x729e5ab130827f34L,0x17199191ea779c23L,0xd13ab8539fa9fd58L }, + { 0x7d5799373b1d773eL,0x65f8e7c6d196c3dfL,0x253f7d51e8541725L, + 0x107a793dec720355L,0x1c14d0566aa16268L,0x9dc5fca38bbb231bL } }, + /* 3 << 252 */ + { { 0xf5689c5e12b09f53L,0xc1da32e19e87ff7dL,0x1af879d012eaa533L, + 0xdba775e6d9271e94L,0x60f8507310e63c34L,0x445f3e21a686a24bL }, + { 0xed5ca8fa15bc277eL,0x9839198a364ab7abL,0xe2ee39426d90a7d4L, + 0xe5b3e4cbccd37e76L,0x9013bd08f1412e0fL,0x82f5c532ce999048L } }, + /* 4 << 252 */ + { { 0x61d0e01bf3fe3441L,0x674e52332af47609L,0xd4a4e224b362902dL, + 0x45923c129e0a5d16L,0x4fc2bdd495e580e9L,0x6d1d974ca8c3d954L }, + { 0xaeff1135d0bbeaaaL,0x013ab5b31baafc9eL,0x80907d3eab8f9f31L, + 0xaf2c12166d566c15L,0x0082daba952e6fa7L,0xa46710032df9e03aL } }, + /* 5 << 252 */ + { { 0x91b379c63223d561L,0x8cb7b8cce203417cL,0xd0f44208176b3b81L, + 0xd18c2118aaba5cd3L,0x4aed5c9770794f9fL,0xfc540dc4f4c33894L }, + { 0xb8e6798a0153a8a8L,0x6537dcdf43c4b0c0L,0x1b7eef39ab557397L, + 0x175e3934b7103105L,0x943abf4a82ac89e4L,0xeb1a61f957ffcdb8L } }, + /* 6 << 252 */ + { { 0x99c2b4cd66476227L,0x576a4b0662850cd3L,0x067bb66b5a352b7aL, + 0x3c7d6fc43ec757edL,0x2f69291cb9d36adcL,0xc7c0f3257c9143a4L }, + { 0x768c3c400627fee2L,0xc214d81da8fde577L,0xd86e4b025299ea1aL, + 0xbe46b7e91a2d4005L,0xaf865a169317fa60L,0xfbc3268fcdce2fbeL } }, + /* 7 << 252 */ + { { 0x66fcba52d8fbe900L,0x9f16434c861b3e33L,0xa371b97241b4305fL, + 0xb2d858ce25b6af89L,0xbab07d53275f9e8cL,0x3b5951f8d525bef8L }, + { 0xebf79e3ca1755b0aL,0x4e6256e7b467b1c2L,0x7dbd8b66cba1a659L, + 0x88ea40138b1eb8b6L,0x210ac1b38fa6436aL,0xe93e22c23df40e33L } }, + /* 8 << 252 */ + { { 0x5f79f0df1fd64063L,0xd2d39dd381e118ecL,0xd631a68e11571c5bL, + 0x6d072b4e2474faf7L,0x5e043a6d862a924aL,0xcae58bd8b0fc8d7aL }, + { 0xf54bb7f3b1351f28L,0x4588b6280413275eL,0x81459f4c5909ec04L, + 0xd28cda25abd16460L,0xbb676d018db1c69eL,0xc0056e2dac5036f4L } }, + /* 9 << 252 */ + { { 0x1ce187bf323169baL,0x1dfaef8661ab5073L,0x1893dc7b2ae468b5L, + 0x0748ec86123848d4L,0x0d2877b46a96eb12L,0xb6063e75e9322495L }, + { 0x1cb17189d7d1828fL,0xde41f11944d1b318L,0x7ce0f87610f0b74dL, + 0x2c7c91ee7a98f86bL,0xb641418e750f3ea1L,0xae2cd2e280094054L } }, + /* 10 << 252 */ + { { 0x9f6c6ed598d8e086L,0xa9ad63ca2d3fad85L,0x055b8323fe016926L, + 0x039fbe287b3a8d68L,0x544a8bf5fb6b315aL,0x04b122fb647fed85L }, + { 0x1e9807fa98085b1aL,0xb78a36a771c12696L,0x4ccc1a2cdc22f95bL, + 0x6ff4997d54d1e818L,0xecb5bdc2f08c22dcL,0x6e07e2c146a27762L } }, + /* 11 << 252 */ + { { 0x602077aceaaec565L,0x9dacf68224568aeeL,0xa490fc1e9cfcce26L, + 0xb2ac94b3303218baL,0xc0208604ab33f9aeL,0x801663b6e39a6668L }, + { 0x1defbb42961b0927L,0x688b445e83e318b3L,0x34fe2830c11648e8L, + 0xed56e99360066dfaL,0xa5f30f9a07671eccL,0x02c40260a3222e8dL } }, + /* 12 << 252 */ + { { 0xfb2a11b4ea347db9L,0x2360667e03350681L,0x1aa6e720a02a1261L, + 0xac2bd2eba110bb21L,0x8ab2f9063c9b4568L,0x5f46263d5ace1f17L }, + { 0x97067801eae704c8L,0x35d2637ea715d313L,0x24cdc3d0c77573daL, + 0x6f97cd07e2562b2aL,0x27bcd62d5afb29e4L,0xc38ac1c55d29f5d3L } }, + /* 13 << 252 */ + { { 0xd9c38ba47c88f46aL,0xdd07c4d79946ebe4L,0x908731dcce0e5417L, + 0x43088d11e145839bL,0x9d37419d07b61543L,0x440cdbcd2c3c7c4cL }, + { 0xa6a6fed673216db4L,0x15ce171a198cd32bL,0x198c256974e6a085L, + 0x5fec853f3dc2a714L,0x329250bdd5923068L,0x1d82373c9f6195caL } }, + /* 14 << 252 */ + { { 0xa8e17be53777b2aeL,0x534e3a3bcc284224L,0x7f34ce458192cfa1L, + 0x0009a72966d0e03aL,0xc42053ba524ce1fcL,0x834e98fe6d092e58L }, + { 0x400c65a1c8b0f751L,0x268bfe6f107965ebL,0x0f141c0332e0bc69L, + 0x33bc6e64597a2264L,0x039a4ae9454a0d6bL,0x2cb0bf550b07ddaaL } }, + /* 15 << 252 */ + { { 0x69056cbe63769bb3L,0x710a67d385044d35L,0x971ccbdeea855332L, + 0xd655163a0fd0d210L,0x619c3f9adbb8a8b9L,0xd156f73d49a014e2L }, + { 0xd04ea0a5a129a598L,0xc9c04da6fa2f12eaL,0xc0ed654ae98b3187L, + 0xa254eef6a82f9ec4L,0xe537695fa386a72fL,0x170f1ed4a74eb453L } }, + /* 16 << 252 */ + { { 0xdbe04c3044ce3ad8L,0x995fbb1b4ce8aad5L,0xdbf8b54670911457L, + 0x9e683b5b3f7a1757L,0x7b89a08a9c7bd62cL,0x448865a40b3fc97eL }, + { 0x0ac9abfc3bb01e94L,0xa07760421e756124L,0x0aa6c335d9deed97L, + 0xe270580f72603e08L,0x70857a946c783bb2L,0xa0047774caa929aeL } }, + /* 17 << 252 */ + { { 0xf99a63c5e8c4a440L,0xc7fd1d1419d65168L,0xfb6c21d696d5e80bL, + 0xa4a7304944b833beL,0x093728d5127b1599L,0x9046cbe2c89e7195L }, + { 0x21e2863c146a80d3L,0xb1ac7e1bdd559c13L,0xbe5ba65c72c39063L, + 0x7da5feb87722cbc7L,0x122615d0f17c02c5L,0xd44f477179e5fcb6L } }, + /* 18 << 252 */ + { { 0x0d913830e2d28da9L,0x0465920a8a164385L,0x79959ce1b0ad65d5L, + 0x6c94690759a966d6L,0x4ccb0e5e832c24feL,0xa8c5bee5d6af2a10L }, + { 0x264dcc118c5791fdL,0x719f23ac5b58ce85L,0xfbff8a2f8e54b029L, + 0x0c9240be864e959cL,0x8f7c21733c37c665L,0xfda848d9f164d354L } }, + /* 19 << 252 */ + { { 0x203ea731f35d11f6L,0x90610383f9f9001bL,0xb9d3c302ed97e6f2L, + 0x4c529736c9a67e6cL,0x2e440b1781f6597dL,0xcc798f5616aabf20L }, + { 0x490f50642832ffc5L,0x585e462a7a19b125L,0x99d73e391b06d98bL, + 0xb817e97aab696d7bL,0x9df2f65ac28dffeaL,0xa48dad47045fddd7L } }, + /* 20 << 252 */ + { { 0x2878c20d62e5fc09L,0x419ed2ece7f012abL,0x3bbc853fbaa21e7eL, + 0x412bc3c54844c009L,0xc4b150508b012199L,0x9d160f4c310d5fbfL }, + { 0xcb61b69214f60becL,0x436348c064092943L,0xce8c136e3185cde0L, + 0x97b034f68be5dd85L,0x7697adf92701631aL,0x2ddd86361fa6e8a0L } }, + /* 21 << 252 */ + { { 0xde8c2c963e9ff7faL,0xfdf1e25d8b75bbeaL,0x28ba3be59c146264L, + 0xfc1df52e81fcb0c9L,0xf9341c43af3ba66aL,0xe81c22470d72188eL }, + { 0x2ff00f1069c62b9dL,0x1077962e71498d24L,0xdf35b17ecc34ece7L, + 0x3516c33687eab2daL,0xe71cf7ddc72b7911L,0x6c9233d92c286c56L } }, + /* 22 << 252 */ + { { 0x7ce6389d162754d7L,0x8f03eff514e0d8e5L,0x9fd2c896ef402e31L, + 0x4a4bf70a2195b0e6L,0xe6043a383c8d82dcL,0xd86b647e8bed7c65L }, + { 0x21bc56f4a4c87660L,0x8c99d6270c05564cL,0xd6b82e9014050ee2L, + 0x09bf6a3eb6b11f0bL,0x9704b36731dcd6b1L,0x871c85c85e3d44caL } }, + /* 23 << 252 */ + { { 0x93024430e5236badL,0x4c5872728b883d1aL,0xc265b94bba68d3bbL, + 0x7d8fc82a648d9b7eL,0x57086e6e75ac264cL,0x4b8a157102fc9ec8L }, + { 0x83ae238e86849a9bL,0x2eaad9b8a69acccfL,0x2d82c029d44eaa39L, + 0x8f5b9ed833d7a556L,0x05c83328eea8b609L,0x537069efc3c96005L } }, + /* 24 << 252 */ + { { 0x292f8874b25c4d4aL,0x54961fd87e79f526L,0x949a1fae008c6ec9L, + 0x6ae82f0d525524fdL,0xd1f6f4ef2edbcb1aL,0x41617a6d977ddffbL }, + { 0x6ae38fb71baf0668L,0xa79ea228d538ab3cL,0x70babb05fc44e273L, + 0x247384fbbca85910L,0xdc0e069b6a564959L,0x37a9c5521a7438adL } }, + /* 25 << 252 */ + { { 0xaf2c87828a4b7251L,0xcb5ebfd3c1bc7f72L,0x160b77e560579615L, + 0x297412e3c10f067cL,0x5ad0681ef7df86c8L,0x2e8c63529b3e3afbL }, + { 0x32372cc74cfd3266L,0xb7abc8baa820f8b5L,0x857d545519f34baeL, + 0x5c055ce920ed65beL,0x1d8a59ca537ad6b7L,0x1135adcf7ad88633L } }, + /* 26 << 252 */ + { { 0x47e6ed9530034df1L,0x1839f488321bed8dL,0xb6b67d452ac8a9f9L, + 0x2fe1efc6182e4a63L,0x2da34bde0c1185c7L,0x6e5d1621edfdf9aeL }, + { 0x3bae9db77120804cL,0xf094b0676d986ef3L,0x029c9246853e24ceL, + 0x3abacb1b25a82463L,0x58777e1389c5616aL,0xaedd003b5aeed714L } }, + /* 27 << 252 */ + { { 0x7494e4319da5fb0dL,0xc684d74bee3fd6f3L,0x12fc899403a87d91L, + 0xc4c55e692d6e3931L,0x63e1255896336788L,0x36c297a5f78371fdL }, + { 0x4cd3f9c4a63b313eL,0xd2825e17c543e507L,0xd37e36d06a4e64d0L, + 0xab9559ec11872774L,0xaf168b34880a5d00L,0xb0c916a10c0c3f42L } }, + /* 28 << 252 */ + { { 0xd389397c834eaa9fL,0x2271ea0d2a5532aeL,0x5e59a23ae1f92e9eL, + 0x9f179b8c1f7b91f5L,0x2a1c10028de2dc8bL,0x6ac83e58787a276dL }, + { 0x0facd4756d9d1571L,0xcceaae5e4bf118e2L,0x4e8008b7620fbecbL, + 0xff633fef7a1474cbL,0xfbefea80ce377357L,0xebb9a9460feb7724L } }, + /* 29 << 252 */ + { { 0x0bab441ae9803b71L,0x309ef14684e2e21eL,0x17ccd5b6851b6519L, + 0x8b5e7e300126f470L,0x0560cb9d847eca03L,0xc45850bf11ade256L }, + { 0x08603f5c3c33dbbdL,0x21887bc9708ae545L,0x3bd25ad480014ffcL, + 0x5eb0f89fd3a64409L,0xbca2726b4c3dd83dL,0x611afd2fe4259797L } }, + /* 30 << 252 */ + { { 0xd9cb4233c4f4e0e5L,0xcfc0576818e49029L,0x8e9c8360526f05a1L, + 0x8e83037aa56d6c3dL,0x33507065c47e6742L,0x5ca2c8d8788b5da3L }, + { 0xf355cee9cfb0b6feL,0x0e86fd73973ddafdL,0x27fc6c56d44fd889L, + 0xc9ab416ff7d93f3cL,0x778c3f160d063d62L,0x175e5d920b5085ddL } }, + /* 31 << 252 */ + { { 0xd62406873be63d8cL,0xe8c93b93b80059a6L,0x33bba7dfe065854fL, + 0xcb26543f36b34e45L,0xc17ee58dd2d0c3d5L,0x69752f49bae1bcadL }, + { 0x87e31b429b20106aL,0xc520424b06734eb5L,0x993240afa896d17eL, + 0x5238851bc2762a62L,0xce399f9d506d7dbfL,0xa4822d23040cc7d4L } }, + /* 32 << 252 */ + { { 0xf071c9878fa06859L,0x0083e5311a52390bL,0x845eb12a61483bc2L, + 0x17471d801caf6dd6L,0x7b603616ddc21b92L,0xd38fe0f6b992536dL }, + { 0x433f0652297c25a4L,0x03d4d8fcb1c4bf41L,0xdf617386a9adf49bL, + 0x4bfeb3992cb2944fL,0xbf288427b3d9c076L,0x17818c3e965b4576L } }, + /* 33 << 252 */ + { { 0xfbcff79f6df360c9L,0x342f9ded2bd94c22L,0x2dc5f999283f2300L, + 0xbea18d9893cc3330L,0xc197176269a7da4eL,0x72de17ee93ce69a3L }, + { 0x6c354a6184170a91L,0x031ce0debe47ef92L,0xbf256fd418658739L, + 0x0395088a0d037d9aL,0x61179c42c5a05970L,0x0d5a9f7db8b6ab64L } }, + /* 34 << 252 */ + { { 0x18be1d605a44a8dcL,0xb512d945f1d18ee0L,0xd2e1f6623af39ec0L, + 0x440469136c223676L,0xe7a860836a60a4d8L,0xaefcfc2dc7e09d3bL }, + { 0x175817fad685c9b7L,0xe20b6c9e4b9d0557L,0x9212e7bb51fe560dL, + 0x748aafb7608b53c4L,0x86186d4fd9b06850L,0x4cc6041376512c08L } }, + /* 35 << 252 */ + { { 0x2d5be3b00c127e46L,0x8c6f38fad9b04e47L,0x49c444098736f31bL, + 0x5469ae47f53aa908L,0xd84856f3492fd120L,0xd04b1fa20725e199L }, + { 0x50c2e80a8e7056f2L,0x415db04c9ba2e259L,0x8e4c56ae2eb201e0L, + 0x449e4d9e5082ce94L,0xb5ff077a7345459dL,0x96d10f1e07330e72L } }, + /* 36 << 252 */ + { { 0xac77126e3b3094b7L,0x7c1e7673bdcb616fL,0x90491f8176993114L, + 0xf17c08a8cc8da63bL,0x972a3bffaa050364L,0xdef45b7f65a9cd57L }, + { 0x105ec5ba2b9b889eL,0x7066821150f7a61eL,0x11daa9dbb1d63a40L, + 0x6065451007790568L,0xfaa219cebc2b6d2aL,0xb1b8ace93e5163dcL } }, + /* 37 << 252 */ + { { 0xf8042ae2859b0f22L,0xd8a5d3a200d8bb8cL,0xe85c596189faae14L, + 0xb7d636f906611c0aL,0x35b68bbdd2bc8957L,0xc86f5be5b7cf558cL }, + { 0xb602a00369c17e74L,0xc39479cfd8a1fc01L,0x6dca5c81f733237eL, + 0x9c8cefd41b2e2cccL,0x2e32a323caacb4b8L,0xf7406874ad639090L } }, + /* 38 << 252 */ + { { 0xea3a358e24c1bbfdL,0xfd32af33571400aaL,0x2ec3d44da413949aL, + 0xa0d8594a7bd121f8L,0xb32997a1d6b6153fL,0xa0f48d98b9469c6eL }, + { 0x236b7a18fba15481L,0x49dee3bd98ff970fL,0xbc27ac7a7ee97875L, + 0xd1acf2be28ac6279L,0x92e7ef02514c8328L,0xb2d7a8304f48b497L } }, + /* 39 << 252 */ + { { 0xcaad0554d95946a9L,0x992268c973ed1281L,0x6c0b1edf7b1b25e1L, + 0x4de2d9f81d6e73dbL,0xe12a4f1c5a2950a9L,0xe0cdf7af36ac18fdL }, + { 0x16e7332d1abcc9f5L,0x4dccc1505bac1c75L,0x1b48bbc141f8c231L, + 0x3702cc2693692a4aL,0x9e9e53dd311c5dabL,0x27bc006cfe5d9fd3L } }, + /* 40 << 252 */ + { { 0x2bb798ff689f43efL,0x5813e4415f26ec54L,0x51f64c495005c929L, + 0x60e213a54b42e417L,0xc152844262cc3734L,0x6ecd6c3b09d994e1L }, + { 0xa6e72f7183dd047fL,0x3836f663b0019803L,0xbcf1265b257493cbL, + 0x59b15ff09e62d78bL,0xaac5ed5b6cb92ecfL,0x37e6ad7d9662651cL } }, + /* 41 << 252 */ + { { 0x04743bf8b224f6c9L,0xec04b641ae33b1caL,0x6301f51623a76fccL, + 0xf1aa954675e15fe9L,0x878c64ecd95c1972L,0x033df5ee3ba7578aL }, + { 0xe5e9ff7c47f4721fL,0x9b3d93fa03eef7e9L,0xcd0be6ad573deaa6L, + 0xf377570f3bbc8a16L,0xffdc04c161c37393L,0xd9eee46dd26d659dL } }, + /* 42 << 252 */ + { { 0x33f933604d4b7317L,0xee44b3e02fe482ebL,0x5a96870480f1fde5L, + 0xdfd6293b5510952fL,0x2abdc1989cc0af6aL,0xe608e2769ff45aedL }, + { 0xf408670e3247e796L,0x3144153535fe07c4L,0xa941f96e2870053dL, + 0xbe908795ef6383adL,0x82b620a63560fdf0L,0x2c1cc1ae135de5c8L } }, + /* 43 << 252 */ + { { 0xa829397c727e5988L,0x305659bac6239b1bL,0x9b13701200392cb0L, + 0x4eb1ddf376091862L,0x68b64b19202bdd8aL,0x56c427c5228071e4L }, + { 0x354b1beac3375accL,0x94a45b4e54e1194bL,0xf528df0178095edbL, + 0x6fb0867146fb9ec8L,0x977efc84c555bd48L,0x8230d6f7c268a20dL } }, + /* 44 << 252 */ + { { 0x003d4004b8d81c0bL,0xd3d5048f4168a407L,0x7748ecacc6675bd9L, + 0x9dba4539e2612cf4L,0xa5ebbccfd8770b8fL,0x206b4a9aadd90558L }, + { 0xe446ed9c81b5c103L,0xcd2434184d2199dcL,0x0840f6eacb0d70d5L, + 0x6fbbf1b43107367bL,0xde9444f7d29335c8L,0x33ef004c66252eb6L } }, + /* 45 << 252 */ + { { 0x10eac97aa5a6546aL,0x6129392fe231f95cL,0xfd41bda100e2aae3L, + 0x5b1f93299d8c6288L,0xf1d2fc9246b7df40L,0xbc6fbacfc5df62bbL }, + { 0x64885d924b5af011L,0xe4f3ade883461896L,0x644ce7a7a4a62e43L, + 0x74c9d145337b2730L,0x69d714840f83222aL,0xbfbc594ec27c0fdbL } }, + /* 46 << 252 */ + { { 0x3263c0517ed92916L,0xc039b94884e3f519L,0x54aa433ede89de6dL, + 0x92f76292c0971a03L,0x8457b2312550a2e8L,0x46ab1f0f11cfcd9aL }, + { 0xd97b95c1c6d53077L,0xe8db11d159550599L,0x2092c81385ea4b32L, + 0x149b6b2cb7ced408L,0x2ada6fa482b9b22fL,0x53a5576a25877963L } }, + /* 47 << 252 */ + { { 0xa1e2c2a8195ad455L,0x65e90a3de7f61038L,0xb01eaa52ec623680L, + 0xfad0f9f110302efaL,0x9e544b5449274409L,0xfc9037de8c3a0925L }, + { 0xbcf196fcfd139cdaL,0x0a1f747c4f6a2cdcL,0x580a9abab879fe3eL, + 0x08a20f1c5ee74778L,0x7c9be7de464c5271L,0xa4a1972918e85a09L } }, + /* 48 << 252 */ + { { 0xce23a19aa17e560cL,0x6491b95f62550e2bL,0xc72000121d15a005L, + 0x15fde735f4355a1fL,0x3849761f607f7807L,0xcbe322d018204691L }, + { 0x75756e4ea95e8e91L,0x365959fe817a9b8eL,0x631232763d4ce3dcL, + 0xa769d2fef1d66e00L,0x8624ddbac28829e6L,0x03274297d2df06efL } }, + /* 49 << 252 */ + { { 0x2ad21bdadf3b1368L,0xf4f9d5270b3001abL,0x10182c5557ecb528L, + 0xe00db71565372a5bL,0x2018e0ed74f2bd83L,0xa11b47066175efb4L }, + { 0x3172264722d565cfL,0xb20c27ab2f0faac9L,0x4ca2982a6260f995L, + 0x3850ef89b7085c6fL,0x5b4a6e235f0d45a3L,0xde562df9b7523682L } }, + /* 50 << 252 */ + { { 0xb34ecab233bb63f6L,0xe6cd56a202944c4cL,0x2690cc39489a8d88L, + 0xcdfe368a4fe612dbL,0x23069ca5e9e9f7adL,0x7b87105cc07d742bL }, + { 0x5114645a8b58ea8eL,0xd31fb4821829e8aeL,0x5e235d95c4b28520L, + 0x2a1cda885c2292d2L,0x95d77447ee925b6aL,0xeec419a3df18845dL } }, + /* 51 << 252 */ + { { 0xb8903f10be9ffa75L,0x8bf7fc786432dcc3L,0xcf3f7cf15d028549L, + 0x7684baf29846f2d9L,0x4c580edbe9e063deL,0x0ac5c3edf2d70321L }, + { 0xb9ba10e184c5d96dL,0xbb854b39d7aaabafL,0xe29d66964793c87aL, + 0x7b0fe1d448285ae5L,0xa143454df0121733L,0xa286eb043aa5ddc8L } }, + /* 52 << 252 */ + { { 0x8e4dcfc88c93bc5fL,0x9f96d60a1b233295L,0xae5262e91d447dcbL, + 0xafe58396541d46c4L,0x3e733c2636ff8f80L,0xcb36a37748b81037L }, + { 0x9bcbfa9fc406ef17L,0x57a6e28006fb128aL,0xd86b44db9a771eb1L, + 0xc7ce106e62545a4dL,0xec6818a6b254c908L,0x4b8d3fc550feb342L } }, + /* 53 << 252 */ + { { 0x8faa39c8b609ef4cL,0x0209b3a7d8225cceL,0x11254c211feffc0fL, + 0x64930dcdc1e42ad3L,0xf5b058eb1cbb39fcL,0x2f870e3341cb5065L }, + { 0x61b3611cf7663f95L,0x981890b637941996L,0x00c42b0908dd6854L, + 0xac42af5de17da075L,0xaf3a394c282b8d53L,0xb53b3b245d8bab96L } }, + /* 54 << 252 */ + { { 0xe17c9d98d90f0c83L,0xdd4aa8ac6d984408L,0x94b6fc50f71aef46L, + 0x2e6b5d24f0a2009eL,0xcb9d9cd17d8d75e4L,0x5e732a5b962a1708L }, + { 0x9d774f1c7fd01089L,0x56bc35aded95094bL,0x6844220bb9c797d4L, + 0x40021d8e90ace48fL,0xddc769c5701baad0L,0xe23e8f9e333ac2deL } }, + /* 55 << 252 */ + { { 0x6cf6faf6e92e42bdL,0x759dc78b0d1e6a0eL,0x18fd55ff11532759L, + 0x04a306d7e9af0c07L,0xd7febf615ef7f82eL,0xaa04f1dca65cae01L }, + { 0xb084407c16442bc2L,0x17ab4f74f874f10aL,0x236368d40fb6cea7L, + 0x451ea8206f66813dL,0x4a61097b1760e6ecL,0xa8655cfba01bdd2aL } }, + /* 56 << 252 */ + { { 0x52fced3116f01d7bL,0x88c6b172daf046aaL,0x1a189403fe7a338eL, + 0x39741ecd61798b1eL,0x6a47b0712934b879L,0x3b1a5dd1828d1e9dL }, + { 0xd4bd48487f35a7efL,0x71774b5bc1eebaf8L,0xa86471e5d55344baL, + 0xfbf145f17b8a483aL,0x70f9b214aa53802cL,0x995af93010b066e1L } }, + /* 57 << 252 */ + { { 0xd2714b97aadf25ceL,0xb95c54162a7643f1L,0xae7dc619ba2f1939L, + 0x30e5d013b0db537eL,0xfcd1a456753f0813L,0x19f7117cef62925cL }, + { 0x40a22e35423d3c56L,0xb0271e9926a5534dL,0xc19f703cc76c9a1eL, + 0x9b8fe585560bee08L,0x48c7797d3cc772aeL,0xabd2148e10bd6393L } }, + /* 58 << 252 */ + { { 0x046fb36cc34a7ba2L,0xd42e56d42a61a8a6L,0x16b8fd2d3d4b1184L, + 0x6f9e85a26da29888L,0x1ff7324bdd683c49L,0xdb3746db27bb8e2aL }, + { 0xa7e586e684be7f99L,0xfbd0c0ee61740d6bL,0xb80509bab2071320L, + 0xb5bf09fea3f03641L,0xe872cd854971e39fL,0x9bed91c0ce2b2db2L } }, + /* 59 << 252 */ + { { 0x85177e7ca6bad7b2L,0xd5b1f0901425b611L,0x6b5f16223c4bfa24L, + 0xde34a692def66d8aL,0x96c0663ee8a1b7a0L,0x43eb91ed459c8bbbL }, + { 0x6cc7e78b7d3d8b92L,0x3c9da7efe0338ba8L,0x18d7ab00e21360b4L, + 0x0785ca897f9df01aL,0x5bcfb8302220f1efL,0x8c61a3bfa52bbf42L } }, + /* 60 << 252 */ + { { 0x4dcc3b82196c21d2L,0xef0e0e1e61071fd8L,0xa2a28c3b35a013f7L, + 0x7550d3d7f6b58f80L,0x0f1fc9d58101742bL,0x027874f055982d5dL }, + { 0x5a10b98c629bc409L,0xa28a1b2baf494679L,0x84afdbe1b96578d8L, + 0x201a8062d427238bL,0xe321ee2d89fffdb0L,0x0b304de4fb89f171L } }, + /* 61 << 252 */ + { { 0x5d8e16c0d7700dfdL,0x336e30fa24260211L,0x7ba72067ad557ce2L, + 0xcb388c3169621e0dL,0xcf6b7d813dbf7ba3L,0x7bfe43a91cbd216aL }, + { 0x6c40516adcffe0b5L,0xe77507f083b7ea33L,0x5b5cda074ba1fc8eL, + 0x46860dd296c6d2c6L,0x4716114f0eb5013cL,0x05bd136898c3642cL } }, + /* 62 << 252 */ + { { 0x7fac263852ca5d3bL,0x35e5d8d0f5a2a596L,0x4c7129210011a394L, + 0x400168f7a9c417e0L,0x220994b447b77b44L,0x01a7580af548c0adL }, + { 0x59870c2afe292ad7L,0xdda35a1a2abf8e7cL,0xa3082dc4f16d0c7cL, + 0xd4dcd5f38557c9e8L,0x38d45cc6ba7f0f99L,0xdefc0b1da7c18157L } }, + /* 63 << 252 */ + { { 0x5db2ed891c43e426L,0xeed247709adf4a50L,0x0b5e19765c8b90e1L, + 0xe9db695ffa18542dL,0xc16d3bfb8d043dc5L,0x5c5feb44f11d3430L }, + { 0xd44e3d57365593c0L,0x1338f26c8796edb5L,0x789b325e051ca644L, + 0xaa93b75d1579c2bbL,0xa39a8ec57842c0b2L,0x84225134550ddf11L } }, + /* 64 << 252 */ + { { 0x9ec1159727a28f9dL,0x96f2c44bb847cd83L,0xacf794e131fca111L, + 0x438b917896076f45L,0xad71035b51732588L,0x2db32f32a5d910daL }, + { 0xefaad0e8fe1cc184L,0x6f0360b52e00bbedL,0x99402426474ce326L, + 0xd53b687a2aa270daL,0x96c8bb78d78fa6ebL,0xd07f3bba6e699411L } }, + /* 0 << 259 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 259 */ + { { 0xfe1f11ad389283baL,0xc87e20b60cd91b22L,0x99d0015a3c5babf8L, + 0x7e795b4d5929ea0aL,0xc9cf68331dfb7b7eL,0xc1c07346a64992e8L }, + { 0x0b7e0dd89889746dL,0xa89d7b461c43ea4aL,0x64023cf034f02b96L, + 0xf7dd410a5662f0c8L,0xa3bb6088a1058ccaL,0xedb25dc34e7801edL } }, + /* 2 << 259 */ + { { 0x140a0f9fdd93d50aL,0x4799ffde83b7abacL,0x78ff7c2304a1f742L, + 0xc0568f51195ba34eL,0xe97183603b7f78b4L,0x9cfd1ff1f9efaa53L }, + { 0xe924d2c5bb06022eL,0x9987fa86faa2af6dL,0x4b12e73f6ee37e0fL, + 0x1836fdfa5e5a1ddeL,0x7f1b92259dcd6416L,0xcb2c1b4d677544d8L } }, + /* 3 << 259 */ + { { 0xb6f8d615a033cccdL,0x6aabb87cad75e31fL,0x30a03029a4646d1bL, + 0xfad497e6e6547805L,0x4b9d45c3ba291f12L,0x0f74909bca059918L }, + { 0xdece1fb0b5a181b7L,0x973f74413be1f21bL,0xcc919af36b06839aL, + 0x14427886ad57101fL,0xc63a79882bbc8022L,0x04cf807426742ccaL } }, + /* 4 << 259 */ + { { 0x279fd119da1c29abL,0xbd0688022b30d40cL,0xd8f57da4da44105dL, + 0xb1814b7a28223fe1L,0xcf2fd241e06f2d2eL,0x99003a0201dfde06L }, + { 0x876a31affded7e4bL,0x1efaf8272f725094L,0x5117d608493a6a0aL, + 0xdcec8088a88c03e7L,0xeae1d352ea916897L,0x8cdc28106e8b2c57L } }, + /* 5 << 259 */ + { { 0x52fb8e6f7041b903L,0xd7fc4b5b2ad368a3L,0xf16c61d2f890136fL, + 0xeee859dfbb52a90bL,0x1651b16b3f8396cdL,0xfbced93eb6462918L }, + { 0x1cb3126c4b6bfaa0L,0x65dfc76cc7c8fd16L,0x225b9c21bb46a3c9L, + 0x6c3457577f64f9ffL,0x6f65fadd57c297ecL,0x72a630eae5c5bbbdL } }, + /* 6 << 259 */ + { { 0x0254486d9c213d95L,0x68a9db56cb2f6e94L,0xfb5858ba000f5491L, + 0x1315bdd934009fb6L,0xb18a8e0ac42bde30L,0xfdcf93d1f1070358L }, + { 0xbeb1db753022937eL,0x9b9eca7acac20db4L,0x152214d4e4122b20L, + 0xd3e673f2aabccc7bL,0x94c50f64aed07571L,0xd767059ae66b4f17L } }, + /* 7 << 259 */ + { { 0x25cb1f44f4fefeeeL,0xe1a6b6c8bce660c7L,0xd25459a00d2118e4L, + 0x716532dafedf8f98L,0xaeff37d492cfb480L,0x45919f7da1453c41L }, + { 0x5100afe08d8836a6L,0x2ec20fd7b35d4fe0L,0xce8eefd1c00b7d66L, + 0x922d535d6b82c7ccL,0x5eb38f3fddd8d80aL,0x7eae5305213ae465L } }, + /* 8 << 259 */ + { { 0x09f8bb0654e93c1eL,0xb0045884ad81e27cL,0x26ebc7b6076e13ebL, + 0xbda0b5535d5ac07fL,0xbcb8132248ab69e6L,0xd3847d2e1c0f21faL }, + { 0x7a466528c834d740L,0x6c67a79ae0823ff2L,0x85dd11864c1d7cb8L, + 0x096f849f2d081301L,0xb4f503dd8a5ea0f0L,0x71ee0889d1bf69b2L } }, + /* 9 << 259 */ + { { 0xd7a5f9feaa074b9eL,0xbeda44032fd2468bL,0xca3956309c35ffcaL, + 0xb02a1f592de68348L,0x946b0250903b35c7L,0xe9984f24634e9c91L }, + { 0x4f70d22fe7303041L,0xf8a05d7fb68b0051L,0x0ce7af4fab5006afL, + 0x1011d1644a6bb502L,0xdf959199da4ad1a6L,0xc468cddf1e146f24L } }, + /* 10 << 259 */ + { { 0x40336b12dcd6d14bL,0xf6bcff5de3b4919cL,0xc337048d9c841f0cL, + 0x4ce6d0251d617f50L,0x00fef2198117d379L,0x18b7c4e9f95be243L }, + { 0x98de119e38df08ffL,0xdfd803bd8d772d20L,0x94125b720f9678bdL, + 0xfc5b57cd334ace30L,0x09486527b7e86e04L,0xfe9f8bcc6e552039L } }, + /* 11 << 259 */ + { { 0xffd4fd775b5c7501L,0xc43e409ee0600e93L,0xd2a18cba7d522993L, + 0xbc2e14dc17c84d1cL,0xe84deb43c1eee29dL,0xe65326f08d691cbfL }, + { 0x89760cdd77b726afL,0xb91c302a577b30acL,0xc6a742906e145891L, + 0x95bf3e913be85cc7L,0x2ec0285b9815e0edL,0x5b4be6da8aa3ec95L } }, + /* 12 << 259 */ + { { 0x4ab7a22c02a2d1e6L,0x967e19a31371d5a4L,0x20f59f95078de336L, + 0xfd28fa36f7869245L,0x1de42581cbf1d96fL,0x2e0127d7366e1f0fL }, + { 0xbc65fa9d2258c741L,0x1f2f3356dd6d65f8L,0x06384f3a4a0822a9L, + 0x1c81332bfd05a0aaL,0xbfb12361d95ee3ceL,0x180aaf0642016d00L } }, + /* 13 << 259 */ + { { 0x329ff57bf08c171eL,0x6cd8122a543af2a9L,0x5209a3d65b2f8d96L, + 0x0285b128ba90c881L,0xeb5971ef61b43c8fL,0xf1ec473ccfd759b8L }, + { 0xd2a79fb712d58e1eL,0x695f4877fdb6497bL,0x8bf5a4251f1a0f24L, + 0x3e79a0dea5c8a189L,0x9c8ada35908b7ae3L,0xd8b8622c5000f772L } }, + /* 14 << 259 */ + { { 0x3b75c45bd6f5a10eL,0xfd4680f4c1c35f38L,0x5450227df8e0a113L, + 0x5e69f1ae73ddba24L,0x2007b80e57f24645L,0xc63695dc3d159741L }, + { 0xcbe54d294530f623L,0x986ad5732869586bL,0xe19f70594cc39f73L, + 0x80f00ab32b1b8da9L,0xb765aaf973f68d26L,0xbc79a394e993f829L } }, + /* 15 << 259 */ + { { 0xdd01a72b6024f09fL,0x192c8254378d12e1L,0x03ec536bf5d8b8d0L, + 0xb0c4c01873806514L,0x7d3c5f5614d202b6L,0x7c2a7c5c6febb3e2L }, + { 0xf2fa07d4f9f2b562L,0x6f717b003ba2a4faL,0x1ff95d598f452226L, + 0xe4b3f6ba867c1cf1L,0x907a648a5d0944ecL,0x1ed480007f64f9b9L } }, + /* 16 << 259 */ + { { 0x0a159f6295b3287dL,0xb18f875948cecad0L,0x6d1ab8ee1661a23fL, + 0xcae7f40ec95c41b3L,0xbc3d20407c51eb56L,0xa7527283e8754250L }, + { 0x815610561f9e668aL,0xb8aa7296900f5912L,0xabdbc1bf6af2a00cL, + 0xe9a942542d0a56c0L,0x4774a7b77bc8959eL,0x0a837ff019cef2f3L } }, + /* 17 << 259 */ + { { 0xd9c3f4ea3c696c76L,0x3aff88caea5878bbL,0x2b01171b09dda122L, + 0xa61d5ca0f599cad4L,0xba0c19bef49772c7L,0x8ee9acc25001f977L }, + { 0x15fd3a172549a25aL,0x8f1a25d82263bc97L,0x372b88434db4af00L, + 0xa613b31f4f912925L,0x7d83041a0b64efd9L,0x897c521ca7d5f6a8L } }, + /* 18 << 259 */ + { { 0x9c441043f310d2a0L,0x2865ee58dc5eb106L,0x71a959229cb8065cL, + 0x8eb3a733a052af0fL,0x56009f42b09d716eL,0xa7f923c5abcbe6adL }, + { 0x263b7669fa375c01L,0x641c47e521ef27a2L,0xa89b474eb08ffd25L, + 0x5be8ec3ff0a239f3L,0x0e79957a242a6c5aL,0x1dfb26d00c6c75f5L } }, + /* 19 << 259 */ + { { 0x04c6a90ae75c82afL,0xe9183100f2488abdL,0xef4b378b111a46baL, + 0x77ad9ef502eaa62eL,0x61229a6205e81570L,0x06e26a2db474c367L }, + { 0x0bb2ea7e7113f2d4L,0x8ddc6f887f101386L,0x93fe2d7ef4de63abL, + 0xc3d038278f44e271L,0xe9f9f48ea94e641aL,0xb84b817b4962467dL } }, + /* 20 << 259 */ + { { 0x36f3a3d8a084fae6L,0x759835899a9b0d95L,0x70722186cc80fcb6L, + 0xf28ed0c796d84c04L,0x95a32263ffb63f90L,0xdd7d60a098766034L }, + { 0xe193a31f1d5c387cL,0x6c5eca7eb8310f8bL,0xfe61d523c083ff47L, + 0x90c832dbcb2944e9L,0xa9f3f293593334b7L,0xe6cde2e12d7d1c33L } }, + /* 21 << 259 */ + { { 0x5637d16b065096b9L,0xee3a2ad04770d39eL,0xae605cb56aa94587L, + 0xc2d71dae9b600c6eL,0x672ef30d76a87e0aL,0x74d5bebe567e0817L }, + { 0x38f591310eb8ca48L,0x92b74866031e099fL,0x654858ca785f77eeL, + 0x264b6b7b830be443L,0xb167203d57103903L,0xa73d5d545ce2b21aL } }, + /* 22 << 259 */ + { { 0x2fd97b9b9dfbf22aL,0xdec16cc85643532dL,0xdf0e6e3960fee7c3L, + 0xd09ad7b6545860c8L,0xcc16e98473fc3b7cL,0x6ce734c10d4e1555L }, + { 0xc6efe68b4b5f6032L,0x3a64f34c14f54073L,0x25da689cac44dc95L, + 0x990c477e5358ad8aL,0x00e958a5f36da7deL,0x902b7360c9b6f161L } }, + /* 23 << 259 */ + { { 0x5e8eb8f0636a77efL,0xe14290f8970c3a7fL,0xfe6f6acdfa1784c0L, + 0x98671d33de6a46b3L,0xe7fd88722ae5a76eL,0xed971ecbae4f7d60L }, + { 0x1d90dbd88461b895L,0x3f979ab4bfaaac13L,0xe06ccba1dbd3379aL, + 0xb53b04ba108c4487L,0xe42609dd38d2730dL,0x0638fe82e81c4594L } }, + /* 24 << 259 */ + { { 0xbd079cf1f144b6ccL,0x7f86e29bb4f4a764L,0x5b08b290f21f9cbfL, + 0xada0c85b75e3aeb9L,0xd0789f8b6666c2dfL,0xcf5d8a8cd71ec2ecL }, + { 0x6f7780c3e7e4364bL,0xdd9a652985d2eb75L,0x8222f66bd952a38eL, + 0x9dd5f7eb27260a29L,0xce49b34457947178L,0xaa215f82cdda7e39L } }, + /* 25 << 259 */ + { { 0xcb91619d1419a50fL,0x44a22eac65dc4c84L,0xc199f93701a92405L, + 0x3749a33198045324L,0xf1676e8abc57764dL,0x922f9460a00c33eeL }, + { 0xfde98e63d3766db4L,0xae08a82efd5ffb6aL,0x6a9834537c0c6ae7L, + 0x0e9a919a54f34cdbL,0xf37a95e8fd88d765L,0x927427d4228a1affL } }, + /* 26 << 259 */ + { { 0x454ab42c9347b90aL,0xcaebe64aa698b02bL,0x119cdc69fb86fa40L, + 0x2e5cb7adc3109281L,0x67bb1ec5cd0c3d00L,0x5d430bc783f25bbfL }, + { 0x69fd84a85cde0abbL,0x69da263e9816b688L,0xe52d93df0e53cbb8L, + 0x42cf6f25add2d5a7L,0x227ba59dc87ca88fL,0x7a1ca876da738554L } }, + /* 27 << 259 */ + { { 0x277c833f57c7bf99L,0xbbb84d1d0b301f02L,0x11435cb20713a92bL, + 0x8ae509702d02862bL,0x4edc66bdaa7b0660L,0x5bc0d893d6382c91L }, + { 0x7992c5d3b94a6343L,0x1cfee04147b19345L,0x57963034964ed646L, + 0xd7af0cac3de7b0e9L,0x5123dd8d481b940aL,0xe1d23ad8ad7d3567L } }, + /* 28 << 259 */ + { { 0xaa44b2863004db31L,0x86f43d7ad43e4430L,0xdc4874cdb0b0240dL, + 0x79986a23adc45a06L,0xbb275b443cee4631L,0x21daee8a63a217aaL }, + { 0x1e7c5397d7b25c02L,0xe677d3cbc5e668faL,0xc7c84e28ed51b4bfL, + 0x7ca19e99923e5408L,0xc6f8a595c3f832e7L,0x2d0a789c5fb049a3L } }, + /* 29 << 259 */ + { { 0x49702e622b82b466L,0x365d4f6afb8fe508L,0x2f5234e044884733L, + 0xcd527f345dd0a3d5L,0x371b02544bf4033eL,0x7d84ad677e3212e0L }, + { 0xaf48fd79e69d6b81L,0xd126f83a7a44bfc6L,0xbb8d2b57b2cc4e93L, + 0x5f62a3d5eb60ec5fL,0x7b37da33aa76c824L,0x7593d06b89a682dbL } }, + /* 30 << 259 */ + { { 0x3fa5c1051cac82c4L,0x23c760878a78c9beL,0xe98cdad61c5cfa42L, + 0x09c302520a6c0421L,0x149bac7c42fc61b9L,0x3a1c22ac3004a3e2L }, + { 0xde6b0d6e202c7fedL,0xb2457377e7e63052L,0x31725fd43706b3efL, + 0xe16a347d2b1afdbfL,0xbe4850c48c29cf66L,0x8f51cc4d2939f23cL } }, + /* 31 << 259 */ + { { 0xc342ed50dd305573L,0xe3055013de86c6c8L,0x0ae84d9776deedc4L, + 0xe8e70cbfd1274b52L,0x4bb51dce32e87f7fL,0x32de3672f3748177L }, + { 0x528af91681722d55L,0x459af071a5f2ce91L,0xf6883bbdc685a670L, + 0x398657f9eeb836b8L,0xa08a793eb9278bd7L,0xe786426bcc09e408L } }, + /* 32 << 259 */ + { { 0x114a25c844922386L,0xdd084d446d4e8b57L,0xc49b68411e7bd7deL, + 0x5b0359fad6da54dbL,0xa6e6e5f93f0da321L,0xb65ec55cd640a87eL }, + { 0xc1a4f6ceae64020eL,0x91e29cd2088e1337L,0xf44ceb8e3c0a631cL, + 0x0205b11db756445fL,0x04844e845bc8880eL,0xb630ddc0b85e00d3L } }, + /* 33 << 259 */ + { { 0xac512659c6ee46b6L,0x0c92e402ca82b384L,0x81d79049194fba3aL, + 0x9b68376c36b42b32L,0x6dc1c80cf6b410b0L,0x509fbe9196b2b328L }, + { 0x988fedd6fdc783b1L,0x9f34cd87436ed055L,0x29f243648bb8809fL, + 0x6962ca24b8dc8b68L,0x076cb7b931963ff9L,0xb609ad792b915093L } }, + /* 34 << 259 */ + { { 0x169e025b219ae6c1L,0x55ff526f116e1ca1L,0x01b810a3b191f55dL, + 0x2d98127229588a69L,0x53c9377048b92199L,0x8c7dd84e8a85236fL }, + { 0x293d48b6caacf958L,0x1f084acb43572b30L,0x628bfa2dfad91f28L, + 0x8d627b11829386afL,0x3ec1dd00d44a77beL,0x8d3b0d08649ac7f0L } }, + /* 35 << 259 */ + { { 0x4aeb3f870af947c6L,0x9ac9ff2791d090c1L,0xeaaa7e0fcf698277L, + 0x737ccc2ff09d6155L,0xd5d4bde86753cc31L,0x3b9063477146d4a3L }, + { 0x75106d8959e32369L,0x7a8ee281645999b3L,0x9184fb5cfc3f675aL, + 0xaeebd0423ad4e239L,0xcff8f73e12f449d1L,0x2771bec17339eb4bL } }, + /* 36 << 259 */ + { { 0xf783db44e6674091L,0x57d0eed31e12a3b7L,0x62d2762af3474f91L, + 0x3d122edf0562af71L,0xaf78dbf77f4bbcbbL,0x8fbbbd97e55f0654L }, + { 0x77e117b004bac36eL,0xbbf6bd463ec582aeL,0x553acd10017eb463L, + 0xfc521187fdfd820bL,0x73211103089b6829L,0x9d3fe7ad7e01e5c0L } }, + /* 37 << 259 */ + { { 0x12a8b7ac04c6babfL,0x7b23210557d2cf63L,0xe03831868f21ad0dL, + 0xd14c2b95acdc2184L,0xe7bd19fcadc9bae1L,0xe2dbabf2edea5c71L }, + { 0x009a3ab78f3f4266L,0x159691e17f8ff74fL,0x5ae666aa22f40f41L, + 0x72fcdc88512387bbL,0xa74e8fb841516c92L,0xd9cee7833b15bf07L } }, + /* 38 << 259 */ + { { 0x00a93daa177513bfL,0x2ef0b96f42ad79e1L,0x81f5aaf1a07129d9L, + 0xfc04b7ef923f2449L,0x855da79560cdb1b7L,0xb1eb5dabad5d61d4L }, + { 0xd2cef1ae353fd028L,0xc21d54399ee94847L,0x9ed552bb0380c1a8L, + 0xb156fe7a2bac328fL,0xbb7e01967213c6a4L,0x36002a331701ed5bL } }, + /* 39 << 259 */ + { { 0xd76b43661c8bd222L,0x041c2b87b97e5b19L,0x7b80f8d7b47c4282L, + 0xfec3d476d0dbc7d3L,0x84aa69712753a830L,0xe5f336079ec85e26L }, + { 0xa425d60cfe2374b3L,0xf88b90f14d953af2L,0x80370e7857ca6c43L, + 0xe07d07176f4d6d7eL,0xe60639401e61ab85L,0x171a2bf632a4c829L } }, + /* 40 << 259 */ + { { 0x38e4168d4f8b5073L,0xf1ddc53fc521849cL,0xd2bf515bab917df1L, + 0xab76b71a697d45c1L,0x20fdc6c7cb566a9dL,0x3843bf838a031cf4L }, + { 0x9a2d89a58a028b04L,0x52f3cb1922a908cdL,0xb5df9c2b7b8723baL, + 0x5142f51060374a3dL,0x949b719800bd9f30L,0x4b7cda16c9b86959L } }, + /* 41 << 259 */ + { { 0x22a32c50d154fc49L,0xe12242de66357eb7L,0x67571eb89f19ef9fL, + 0x2ed01f28b92b20e1L,0xd4fd6efb6cd439c0L,0xc4036cfc03b057fbL }, + { 0x605fab271cc48da5L,0x3cbd7a071416a3e7L,0x9cfe7161714bf173L, + 0xbd03d786a77eb0f8L,0x1423516678b8f5ccL,0xecc56e02f0523f3fL } }, + /* 42 << 259 */ + { { 0x20b1632addc9ef4dL,0x2a35ff4c272d082bL,0x30d39923f6cc9bd3L, + 0x6d879bc2e65c9d08L,0xce8274e16fa9983cL,0x652371e80eb7424fL }, + { 0x32b77503c5c35282L,0xd7306333c885a931L,0x8a16d71972955aa8L, + 0x5548f1637d51f882L,0xb311dc66baba59efL,0x773d54480db8f627L } }, + /* 43 << 259 */ + { { 0x2be2f1d67d64ddbbL,0x3afc2fad6edd7e04L,0x9a57c16d9e797442L, + 0x1efecfde9c16769bL,0x86523c3571b2940aL,0x1a9b30035825d17cL }, + { 0xa25e99beeefc4d7cL,0x8521b49fb50df9eaL,0x10bd2309bd8f3b06L, + 0x1f892e95ea82e80cL,0xf741621c93585741L,0x95687594f5e5087aL } }, + /* 44 << 259 */ + { { 0xbcdd3a3146f684c5L,0xbc8be436f700b0cdL,0x33005e370de75b7dL, + 0x527a8a2c3bd820caL,0x5e44854446997e4cL,0x40921fd93c3dafb0L }, + { 0xf3873a8ab7390d9bL,0x30999855495ba2fbL,0x005164f0813c8c76L, + 0x05bb04d7fe8da60cL,0xee7c38d503224ad1L,0x172018d615785ce5L } }, + /* 45 << 259 */ + { { 0xaaf786c0f6442534L,0x3f1344c1e56b44a5L,0x31199702ed073a36L, + 0x1f8ba0ec3df17e33L,0xf3e7b63493ceee0aL,0x568bdf39490fc4beL }, + { 0x364bdd11b1e1c439L,0xa1aa317ae5a63c82L,0xb12697034c02ee46L, + 0x0bc6d92e7eb64374L,0x87538fe740ed83f1L,0x862450abda74892aL } }, + /* 46 << 259 */ + { { 0x59b1b1347a62eb3bL,0x0f8ce157cceefb34L,0x3fe842a8a798cb2bL, + 0xd01bc6260bf4161dL,0x55ef6e554d016fdbL,0xcb561503b242b201L }, + { 0x076ebc73af4199c1L,0x39dedcbb697244f7L,0x9d184733040162bcL, + 0x902992c17f6b5fa6L,0xad1de754bb4952b5L,0x7acf1b93a121f6c8L } }, + /* 47 << 259 */ + { { 0x293ff71acc51318fL,0x69437a2e614149cfL,0xb12ea4613b48b348L, + 0x2f58020321f6cf90L,0x2e865f77178b53fbL,0xf4774d29231909a8L }, + { 0x0433e66bc4d8b703L,0x4fb6256b907097cfL,0x44a2a7fe004470f7L, + 0x7d3ebbb46dc5f10aL,0xe9b3af288f5526b4L,0x4bc0d9db1107bd75L } }, + /* 48 << 259 */ + { { 0x4865c0ffc0391d0bL,0x70d31470176740ffL,0xf44ca9a1ed506d00L, + 0xfaac86f6c981153aL,0x713ddaf4e3f86940L,0x64ec27093fc39de9L }, + { 0x04d413acac9a26b5L,0xde2052eebb21664bL,0xa6e04de8957b4f20L, + 0xd185b640d5487618L,0x1668b6a46fed1707L,0xeed37894c435ac3dL } }, + /* 49 << 259 */ + { { 0x1fa08a16f69cdfbbL,0xabba54dd0bf735a1L,0x37848c6a68a5cc20L, + 0x08e23c52a969298bL,0x48240306f965bddeL,0x48492deaf90bcff5L }, + { 0x416b9005bd994e22L,0xa6ce214ce6429f16L,0x5aaeec21f43f86d4L, + 0x202db9b7a0b1979fL,0xb2d97b4fdd7ae6d5L,0x4fedb6b9e12f04a1L } }, + /* 50 << 259 */ + { { 0x7a56867c325c9b9aL,0x1a143999f3dc3d6aL,0xce10959003f5bcb8L, + 0x034e9035d6eee5b7L,0x2afa81c8495df1bcL,0x5eab52dc08924d02L }, + { 0xee6aa014aa181904L,0xe62def09310ad621L,0x6c9792fcc7538a03L, + 0xa89d3e883e41d789L,0xd60fa11c9f94ae83L,0x5e16a8c2e0d6234aL } }, + /* 51 << 259 */ + { { 0x9c8e64869c85df60L,0xa84692a681e26100L,0x0350e1209c739462L, + 0xb6da4ebf99fa1f63L,0x857b534055e2bcd4L,0x7f4001dbdb209cf7L }, + { 0xbfa320378757800cL,0x2d56821fa6a562b5L,0xe56d810b6c3e775cL, + 0xeba244a6ba757f86L,0xb7ca8dbf80a17cb3L,0x8cbff4a22b7db57cL } }, + /* 52 << 259 */ + { { 0x650c31da9dff967dL,0xecd1e0f77ed949dbL,0xa7ff9becb20196fdL, + 0x5085c68d1e6259aaL,0x5759a166871a71e9L,0xba15e24c2b4d3bd2L }, + { 0x22c4f75912c51998L,0x6038fb0a7c8a9400L,0x64827d9c09625dacL, + 0xd8ce10c96ec4fb64L,0xe417ac30095686ccL,0x1e624aa88c723f44L } }, + /* 53 << 259 */ + { { 0x872d3dc953387fbaL,0xaaa0e1b4317ec17bL,0xa12b45519efb728cL, + 0x0b43907d45a3491eL,0xb7fa83befa4a239dL,0xbecdae00b59a4f3cL }, + { 0xe4e4c7c393407d23L,0x8278f336cf1d3cd8L,0x73dc9356610570a3L, + 0x5579653d688d933fL,0x208b96be5881d760L,0x4752a645d12f57bbL } }, + /* 54 << 259 */ + { { 0x87ec053da9242f3bL,0x99544637f0e03545L,0xea0633ff6b7019e9L, + 0x8cb8ae0768dddb5bL,0x892e7c841a811ac7L,0xc7ef19eb73664249L }, + { 0xd1b5819acd1489e3L,0xf9c80fb0de45d24aL,0x045c21a683bb7491L, + 0xa65325be73f7a47dL,0x08d09f0e9c394f0cL,0xe7fb21c6268d4f08L } }, + /* 55 << 259 */ + { { 0xe02aca87d4bba3cbL,0xd40ac486652fb181L,0xa1dcfe7ffaa3f999L, + 0x116323e0e9eded09L,0xaa3a0f0f07629d4fL,0x9f8e49f5e0dc53adL }, + { 0xbae96096742af22bL,0x6d7e24dd518862dbL,0x5c91ba30bb333cd7L, + 0xda8df051e65319b0L,0x2b9305ce9b3e43dbL,0xbf1d0e98fe783571L } }, + /* 56 << 259 */ + { { 0xf629fb233809aa31L,0xb3b66d77650bd2b8L,0xcb643126bd325d57L, + 0x29f46272ed41fa03L,0x374e734f406ef56cL,0xbb9ecd36da7428eeL }, + { 0x069694a61c06325aL,0x852b2912e40b9e8cL,0x6504bc90cc3d9695L, + 0xf1af43587e38707aL,0x552127dc239a0781L,0x0d1b3a6e8fe76173L } }, + /* 57 << 259 */ + { { 0x207e41f31d681018L,0x8883a6e417a7d540L,0xffc48332bc983c31L, + 0x729c4110c6b3de67L,0x5ef4680ad69a2499L,0x4544b58fe7afb2e7L }, + { 0xf5a2fb13480e063dL,0x8797357382054197L,0x5dd38cf7131d2df7L, + 0x635e91b8a9366742L,0xbd87a407e0d703c5L,0x6cc37be247251f16L } }, + /* 58 << 259 */ + { { 0xc4ccab956ca95c18L,0x563ffd56bc42e040L,0xfa3c64d8e701c604L, + 0xc88d4426b0abafeeL,0x1a353e5e8542e4c3L,0x9a2d8b7ced726186L }, + { 0xd61ce19042d097faL,0x6a63e280799a748bL,0x0f48d0633225486bL, + 0x848f8fe142a3c443L,0x2ccde2508493cef4L,0x5450a50845e77e7cL } }, + /* 59 << 259 */ + { { 0xaa129c0ddc428c57L,0xfe619b75aea19047L,0xd6287ecf12ea77aeL, + 0x4e6d070fdf7ce104L,0xd0df6788f097c79cL,0xd1c1f8a6ad8b1d07L }, + { 0x53eceba296519e66L,0x71670de3d6274109L,0xd2f21ea03f7a82b8L, + 0x41efbe939c8e45a5L,0xb5b153436ada3edfL,0x32ba22aca90038f8L } }, + /* 60 << 259 */ + { { 0xe1d195fad0cbe947L,0xd1fe0c4ef2ef1b72L,0x1451a0b206003fffL, + 0xda653fa08239341cL,0x5f834372f2508d75L,0xaeb245f507faeac3L }, + { 0x3eb3285b65fdf4ddL,0xfb335c0e84085970L,0x600ad6cae5efc0deL, + 0xc9c9f8910cf83e82L,0xf880ff84ad8cc14cL,0x54816725a016aae6L } }, + /* 61 << 259 */ + { { 0x22ce565ce1124375L,0x30ff1dc5edd968c9L,0x62d74c54e9148534L, + 0xf003f0d35de42774L,0xaf9448e6e57f8842L,0x55d5c9a3c5ff761bL }, + { 0x7da9398cc4c5edd8L,0x9643424e4ea0e099L,0x497eed480634fcb4L, + 0x09ffe2d07dea57cfL,0x30673ba73530a094L,0xfdbf8f24a251cff3L } }, + /* 62 << 259 */ + { { 0xd0f4e24803112816L,0xfcad9ddbccbe9e16L,0x177999bf5ae01ea0L, + 0xd20c78b9ce832dceL,0x3cc694fb50c8c646L,0x24d75968c93d4887L }, + { 0x9f06366a87bc08afL,0x59fab50e7fd0df2aL,0x5ffcc7f76c4cc234L, + 0x87198dd765f52d86L,0x5b9c94b0a855df04L,0xd8ba6c738a067ad7L } }, + /* 63 << 259 */ + { { 0xf9ae5fcedb877020L,0xd84ad42f703e5d09L,0xa6a5cc1fbfaed17eL, + 0x2099409829362fe9L,0x9f863bb0dd299c2dL,0x82bd3f61fa632197L }, + { 0xd3b14097ebe7ff51L,0x7c9e6ec4c719a6bcL,0xd3b46f3d70a51db6L, + 0xc8fa2f0692eb8243L,0x68e1f56e02155139L,0x0c35d135fd3b893dL } }, + /* 64 << 259 */ + { { 0xe76894c3ae7ce296L,0x87737ee2a6cafc34L,0x566dfcfbe55cd1e6L, + 0x5421a9f23a7ad5b9L,0xa005838a4687a4efL,0x3837219a23a2c423L }, + { 0x4b7800128a82cd1bL,0x401c07bec728b588L,0x2b5f69e937ced8f3L, + 0x306b621d8c1e1eaaL,0x8acbbe71d389cc4dL,0x922fa665f4ab7774L } }, + /* 0 << 266 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 266 */ + { { 0x2df6f242d35c2d80L,0xf65a99a93493ce97L,0x9e80232b372bcc87L, + 0x26ba13b86e428cc5L,0x2526ef1f13a1b763L,0xcef3edcddc97c5f3L }, + { 0x4954867fbde16b73L,0x9817813d368ff6cbL,0x7e39fa69be143027L, + 0x12329463cf54f28bL,0xcf0991dc7597c2daL,0x0cda396952e07099L } }, + /* 2 << 266 */ + { { 0x412f64a3f303955dL,0xe92bdca9bd692593L,0xfbe6cdc2c2e964e0L, + 0xe9a3b1fd0011cb01L,0x6c30762dcf228f23L,0x1270b84abe9199a1L }, + { 0x732711dfe3c9cbb1L,0xa3aabe37d91d9513L,0x8ee08ba0c6eceba7L, + 0xb1711531f3c3d31dL,0x65060b633c716948L,0x046b4ea12ff2caddL } }, + /* 3 << 266 */ + { { 0x25d1124fbab220c6L,0xcd1423c861524e3eL,0x75e4f45f0434fb51L, + 0xb5180a8f5180ab2bL,0x144e214e5b22e388L,0x6b16dad192263054L }, + { 0x3ea7590740863566L,0x372d5abddada3b46L,0xb3ff5a3a893d210fL, + 0x39f8d1ce5e29f3dcL,0x559186ce68200e82L,0xf48764541202cb66L } }, + /* 4 << 266 */ + { { 0x6f178dbf8b540904L,0x0264bccd8720472aL,0xa6e8b4b459b46611L, + 0xafce8267c72b4a58L,0x21142175a45985adL,0xd23401dfe649d733L }, + { 0x6bf42fe085dc7720L,0xc5c8ab9440e3f2f5L,0xb0c8a58acd029197L, + 0xa73ff329215492e1L,0x895c545eb1b5a5f0L,0x6dbc24456fcaf49bL } }, + /* 5 << 266 */ + { { 0x25ef32d60f2d76a3L,0x540650b9af4a7d46L,0x8979a4b8d991d7f4L, + 0xdaa706c299202400L,0x8a729680f19d281dL,0xde25bdc44ec44de2L }, + { 0x0fc50832c2054496L,0xfee72fb60aaf2941L,0xc8263e64b82ed4f0L, + 0x91a8cb736f49055cL,0xb7585458f2bb515cL,0x03d2b23ab855e6c6L } }, + /* 6 << 266 */ + { { 0x09ec1e3dcfd3f182L,0x1f1c30b5adae7af9L,0xf3a33f7c6b454164L, + 0x0318926f94647c4fL,0x8e37bdd787db14ecL,0x811cbd342ab364d3L }, + { 0x1dd1e5077c2b369dL,0x7a57bc46a28056bdL,0xfca5be4b089efe44L, + 0xb3bd84d76dc1290eL,0x40d7af098793e6aeL,0x4e08e11fa3723942L } }, + /* 7 << 266 */ + { { 0xca3709ad899ffebbL,0x1a87377877c00602L,0x5ff40c2aa99b4af0L, + 0x680464e5a80e870cL,0xd2f7f04494e10b1dL,0xee9b206c4e9aa1a7L }, + { 0xb536d67596cbe950L,0x841856899e8305f3L,0xae1b669c369fa255L, + 0x62e260267233e1eaL,0xac05c5136aa60c24L,0xdfc6814fd2691677L } }, + /* 8 << 266 */ + { { 0x8baef5df0a02b0fbL,0x58a2b06bc2b92b02L,0x268558d754c8267aL, + 0xf924f795ccf70393L,0xe3763f30f68ee021L,0xc1e856f05c01ba4bL }, + { 0xcc01a3e9722b6bffL,0xd2be4623ed5b3b02L,0x1ab3512e6c45e33fL, + 0xa978fe484ef433f6L,0x23e2ea018e21f5afL,0x49647d8811524a40L } }, + /* 9 << 266 */ + { { 0xd50abc94f5d3f437L,0xbf2ffcc546b7b738L,0x0bf53571f80edda5L, + 0x167908d4ab90ba5fL,0xad445b102303cf00L,0x9b537d4fb9e59406L }, + { 0xfac5e27cf43049a8L,0x05ccb32ebf9db100L,0xe662eeac4d1b535fL, + 0xbf21d6d78d27ca90L,0xb960bf652a684981L,0xe16bdaee49236475L } }, + /* 10 << 266 */ + { { 0x47a5958f92ad4720L,0x12c33193da3bf809L,0xf16493147da6d32cL, + 0x42eb4e687102deebL,0x0f8c4ce283088c86L,0xedf91c3bd693c9a2L }, + { 0x8a18a4761e8c310cL,0x5e8757c5dc3db0e8L,0xc48b820ef76a0affL, + 0x690d788d5c71e596L,0x2b0a00857cfe770dL,0x440ba06bd46505f0L } }, + /* 11 << 266 */ + { { 0x503f77906087d4d0L,0xc7243aeda1ebfb04L,0x203f0563ad8f14bdL, + 0xc20013b7cad73fcaL,0xbace8b323741a708L,0x0b376ff731bdeb56L }, + { 0x820b7f1282c22e57L,0x0c08133117830562L,0x306d178a8d0d30c2L, + 0x36a6efd1467a1510L,0x558fea1af55b7b97L,0x1e9152b784e546eeL } }, + /* 12 << 266 */ + { { 0x92a7fbcdac3ce531L,0xeb85f7f059498d99L,0x8e45db2d02a8feb5L, + 0x176c0cb2728cecbeL,0x33fcfbb0d1837662L,0x426e192dd6f2882cL }, + { 0x75a0f3450a2c9899L,0xd815dc6066148f9dL,0xf4ea90cefa0453afL, + 0x5108858ff54c96fbL,0x86b46b5731f77afcL,0x59df021f6bf7e2fcL } }, + /* 13 << 266 */ + { { 0x48d67f73dab6c0f4L,0x70cfc26cf0d49ef3L,0x25c95a68a65cce7bL, + 0x29a05632cf6ad228L,0xbcc2fb5a1a8128f5L,0x360d82a48c9defe0L }, + { 0x1c5c5d628d1531d8L,0x58fc4b9a149f6b4cL,0x8097cf56a3b625adL, + 0x8821ead7fd8e0e35L,0xb96c2b880d9e1df0L,0xfbf55ba72a243accL } }, + /* 14 << 266 */ + { { 0xef32e94d70e0d8fcL,0x33ec93dc6d63e65fL,0x134532fb1dc7156fL, + 0x98fb5b0c0e8d85b4L,0x05c28df9b64f7861L,0xa7e73afa4160e1a2L }, + { 0xbfe60a9b785f6e4bL,0xfcf998f12fec9ec5L,0xf673b8d15c12a44aL, + 0x85df3bc736d189a5L,0x4480a189dd83f6e0L,0x3216317ef3d3ab44L } }, + /* 15 << 266 */ + { { 0x221c1b7ffd3d7532L,0x40939c318bb4e719L,0x75182ce602f8f74eL, + 0xf508d6415395f9d8L,0x88fc89ea1fc81977L,0x861d8d0bcc8dc7d3L }, + { 0xd76e4f0cec07b0e2L,0xb0a4e2aa5819b99bL,0xa67bed0366a9c935L, + 0xce7c8241d2781f91L,0xe7c5c22512af0abdL,0xd1067dbcfde7de16L } }, + /* 16 << 266 */ + { { 0xe1d42d94d087b788L,0xfbfb221aba0e176aL,0x5f6698e783686966L, + 0xbb5e159474a30dbfL,0xef86bb5bcfd20230L,0xf055a1c5403b8f8bL }, + { 0xf249aac8d9d85ea7L,0x7318f7bc3d200198L,0x3b80960cefca9a90L, + 0xf28e33888f449c4bL,0x0cdfc61bf0cfe09eL,0x3b169c638b22cd26L } }, + /* 17 << 266 */ + { { 0xf4f13a49b81b45b0L,0xb77a67be3003fe1bL,0x70e648a318d52c97L, + 0x701ba8a1ee17ce93L,0x58a0ce0cf672226aL,0x2fcad147cebc3294L }, + { 0xf5cd118a104e8f68L,0x0015bc0bd15358e6L,0x75f0d28f1c662df4L, + 0xcd54f443a3e038f4L,0xa83507610804c717L,0x5fce0ce3f03bad08L } }, + /* 18 << 266 */ + { { 0x4c2e2bffa180a71cL,0x067f3e3baff551b9L,0x007610f1afa43e12L, + 0xe8a9ae79ef7b9a1cL,0xa558ef6cf9d3b397L,0x8d5229884f172f34L }, + { 0xafa906332d425e05L,0xc62c3914207b0bd8L,0xc84d197c059f7d66L, + 0x6cc1d8ce421a9172L,0x1d44a46929a7ebe3L,0x96ca4d0171c3c8b1L } }, + /* 19 << 266 */ + { { 0x31302e094d369fd6L,0x62fe210cf1b62d27L,0x496ac173bb37578cL, + 0xb4d3d065aa0907e0L,0x02317db27c822875L,0x60a01580f241ebc7L }, + { 0x81a5d5244e4f37d0L,0x5286f7289c3f2555L,0x14c8c7549a73ff08L, + 0xd8236689ff478877L,0xf62d426b08e09f00L,0x2ba1833c67a96517L } }, + /* 20 << 266 */ + { { 0x7013d596831f464aL,0xe57185fdd3cf6ca2L,0xbba7898e35915f51L, + 0x9fbe5f139fd967d4L,0x0aba8344d173558fL,0x4c0dd30dffeb6beaL }, + { 0x928f68cc5110e40fL,0x1589a327a58b6d60L,0x09b5c4e06abb0ac9L, + 0x01ef3f8a68957627L,0x55dbe9f79f4045a4L,0x91976aeeef178ac3L } }, + /* 21 << 266 */ + { { 0xd9c20a69b85e46d9L,0x1bda1163cdbda686L,0x5c0717f6c02427a9L, + 0x2a976c104d2a48afL,0xea276b15921a02e5L,0xf055b980ddb6315cL }, + { 0x0ab85663825f00efL,0x95377fd42053a392L,0xc51c245e23f463e8L, + 0xe1ae1e5da24c981fL,0xd6a0b44d9f5cfdbaL,0x1205754023c16002L } }, + /* 22 << 266 */ + { { 0xfe464ce116ac9150L,0xfd629551173ee9e8L,0xd0623ab1781696cfL, + 0x7a07cedd58529fa9L,0x831b4a9d449c33a0L,0xb7b7b72417b171a8L }, + { 0x0e1ff931f5a9aa41L,0xd43f33dfe356ba47L,0xd2abfc77f003b5d2L, + 0xc2909150882c0313L,0x83823f6c7ee111a6L,0x9d7a2d82f59cb72dL } }, + /* 23 << 266 */ + { { 0x52e712549b33f6fdL,0xd4d9b73f5c414babL,0x9834943177e93a9bL, + 0x848b53c99f283fc9L,0x86e48b6234c787efL,0x8b498e1cb3166045L }, + { 0xb2259559e5e456ddL,0x0316069fa2c2ca8cL,0x9a70e29ef6524ecfL, + 0x2477ffc9bfff600dL,0x80a9a5e081869e1cL,0x84f887e70a78f6a0L } }, + /* 24 << 266 */ + { { 0x7f89c2c40c9f23eaL,0x8fb025d4d6ec2b2aL,0xbe70e48b12d9f811L, + 0x703ac1bdc7a43dd0L,0xa4309a2c2118ca3aL,0x5a95d7b301943012L }, + { 0xd9597d87811f6c73L,0xf82e801596079992L,0xfcf8760df1561aa9L, + 0xe1e0306e2d91ee39L,0x99979031e0bbcb6dL,0x49259e54cfcc8746L } }, + /* 25 << 266 */ + { { 0x0de49373a38fb6dbL,0xda9e9036d6bf0a7dL,0xc99fe05fcba221c4L, + 0x45b51edd4cb730f8L,0x312670a3b064e142L,0x60dd1edecddb9ddeL }, + { 0x94be613b9291d75dL,0xbc49861ca00b9831L,0xccec7a08230320bdL, + 0xd1de7bd80ff967b1L,0x5a1164f105fda7e3L,0x864cfc4ce3004538L } }, + /* 26 << 266 */ + { { 0x06f76165385095a7L,0x3c73ac918514b2e0L,0x8ac1120a04b2dac0L, + 0xed6a74174382d5b3L,0x852a5a7864a32d50L,0x7ef5b84bbdc721acL }, + { 0x73dd18980480d271L,0x755b23e04ab0b11dL,0x2e78238982391e5aL, + 0x4957b5c948923446L,0x4ab9318f6921c1fdL,0x8e455abd3e46607bL } }, + /* 27 << 266 */ + { { 0x5c41aafbaf25d6b6L,0xe351f1df916b63f6L,0xe28e9ba98a6efd65L, + 0xcbca736356afe7b0L,0xa77d6077f7384e6aL,0xcc9ad74a738a90abL }, + { 0xe1071caa2333dc2cL,0x4415691000dfc2cbL,0x0ce43c16afd89eefL, + 0x0cfbb8767b812045L,0xe6da40fa6d916fc7L,0xe404b3436302af21L } }, + /* 28 << 266 */ + { { 0x4073f246d9915433L,0xc0149d5672e06203L,0x0abb06c18fcec6a1L, + 0x3a7d1295d75a73f1L,0x65fd8700f18c9488L,0xc3cc0b27732f7741L }, + { 0xd15d8c8025a261caL,0x518233510dc1fee5L,0x981607c7120e1266L, + 0x0e486b11f42cc9fdL,0xe606c16c01a888cfL,0x079dd0b31ea23249L } }, + /* 29 << 266 */ + { { 0x19c62d3c58624305L,0x44974c41b73eae15L,0x2df48b6dd023231aL, + 0x6a82c197c6fad2d0L,0x55758764c623fdceL,0x29f533fbadcebd90L }, + { 0xcfbe4155cfff7336L,0xb18415c7bfb609fcL,0xc23395ad8d411a6cL, + 0x25aebbcf0c92de60L,0xf4d3b1ebc5ccf268L,0x9646b4a79ac85de3L } }, + /* 30 << 266 */ + { { 0x0f423f3013d6cb61L,0x239b2baa66674aceL,0xa6f2ba39eda69340L, + 0xdbbd20eb43e6918cL,0xe6ce84a3e5e7248cL,0xd9184bb5e04c580cL }, + { 0xe4b76d96a0738aedL,0x98662b6090d480a8L,0xfb14bec72610b6c5L, + 0xdfcb01f6bb65837cL,0xd7f0b6ad4a97fb21L,0xe6d84f4bad59b2ceL } }, + /* 31 << 266 */ + { { 0xa79085eb1f7e921aL,0xe2737a08d0aeb41fL,0xa96d7e8169ead959L, + 0xbed1731b733b7c6aL,0x7768e32df508a48aL,0x6f73a08651ccc97aL }, + { 0xb7f94a4b9122db73L,0x1cd17ca257ec947eL,0x7c83fe278f8445f1L, + 0x661f5d82b520fe34L,0x495354942233d364L,0x0bf7abe663925ca2L } }, + /* 32 << 266 */ + { { 0x923e948c203bb368L,0x58e37a2b231a80e0L,0x345a011a6df27debL, + 0xba6784c1d57f4ca2L,0xf01b3703114196e9L,0x981a63eb1aab426dL }, + { 0x2ffdc97851770c1cL,0xddd19da6efa722fcL,0x5ca1c01216f09c1eL, + 0x612021de5b9cc0b6L,0x910e10e95e150569L,0xacace9dce2ab93eaL } }, + /* 33 << 266 */ + { { 0xf66601a7aae13423L,0x940bcd2882cf3308L,0x55de590974f632bdL, + 0xf677d9d4f183faeaL,0x54026b2828ab364cL,0x2a5353dc743469edL }, + { 0x15f02aadd46871d5L,0x4b3ec89b5a2100d1L,0xca85c3681eb9c381L, + 0x145cc7fd50e78466L,0x75fdac98c4b4cdf3L,0xb7cb9170796136f4L } }, + /* 34 << 266 */ + { { 0x6e89c0df54827957L,0xafb26b6d05805250L,0x0c0dc4ea37343465L, + 0x2d3c8b873daca876L,0x733b23d9554a2cd8L,0xd4f2936a6a04d38dL }, + { 0x0937611686f90d9aL,0xcd854d3211425591L,0xbaf9d4cab55b4bf3L, + 0x47259b95144676c2L,0x765cc4b55d7d2835L,0x36e47a8882b2cbafL } }, + /* 35 << 266 */ + { { 0x2070db373af8c96dL,0x4c2db2623b70e976L,0x7ed4d1e9c01f404aL, + 0x04a52764b39d2e07L,0x06e4a7984ebe3ac3L,0x35c9c1f68d7645a7L }, + { 0x2e0b48c75e9c295dL,0x5d44fafaf78e0717L,0x2fc27eba04213067L, + 0x9f3fb2ff2ab0f0e6L,0x374b32fd0c730af6L,0x06ec846129583945L } }, + /* 36 << 266 */ + { { 0x583a3272230be37eL,0x4d3298951c55f593L,0x3b3a2d8a350f0334L, + 0xec830170b25498abL,0xd65847d9b3a01571L,0x4605e739663f86fcL }, + { 0x971b8e115c4bf502L,0x651d179571a892b0L,0x57930832d2d1a4f9L, + 0xf97010745b09a4c4L,0x76b023e55ec2d1a6L,0x8648b8bcf49e1329L } }, + /* 37 << 266 */ + { { 0xc5a8884d6d5c7411L,0xad32aa97d098e2f2L,0xf99569e945d8ad00L, + 0x35801c1c0a232776L,0xe426fd65fb1a2cb2L,0x874b559ecb26ae10L }, + { 0xfa67c2ddf44461b8L,0xc58f8d229418e17cL,0x5998197169908eddL, + 0x8a4a14b8a1f78300L,0x4814c36e61f7fbc5L,0x0389dcc716a1c7adL } }, + /* 38 << 266 */ + { { 0x777e308fc072cf71L,0x4a2d66928c807ed5L,0xa4fe074124842689L, + 0xa3c2a867151ed7b1L,0x52ef24f24d22ee35L,0xe684ac76499053ddL }, + { 0x0b7c223b0582cb86L,0xa6c18539bb81f713L,0xb472da7f66d2aab9L, + 0x3592ab7b7916d4e5L,0xed651a05770c49a1L,0x7b879da1c0256420L } }, + /* 39 << 266 */ + { { 0x82eeaa1496f83e29L,0x586f3e8de5cae8eaL,0xb671eddbb298eb5aL, + 0x41efea86dd0da080L,0xfe9af019564a382eL,0xb2f370463027693bL }, + { 0x65466e5018789c0fL,0x5b0870ac2ebfe89eL,0x9093f416a59f3a53L, + 0xab0cd17251864c77L,0x8e3aa9864481457bL,0x46cfd207896346a5L } }, + /* 40 << 266 */ + { { 0x473bdac887cb6ae0L,0xbd3001b3f155c32bL,0x109643c20026e8a5L, + 0xc4f5f6cc188a568eL,0x630aecf64d2758e0L,0x4549949955b91872L }, + { 0xb10f19d4b6a09df6L,0xc537a4bb37f26d01L,0xd29f505c4d19a293L, + 0xf388a5d2cbb09b17L,0x462efffc6811a49bL,0x8a1cbc40b2f3aef2L } }, + /* 41 << 266 */ + { { 0xf7d94342b7b42998L,0xcdfd6e43629089abL,0x622e8d3cf7932661L, + 0x4818adca0b14b257L,0xcc1dcd1ccdb486bbL,0x58b6cb7ecce8b358L }, + { 0xca36c0b4e640cebeL,0xcc5598942d25f742L,0xdf4f2a9ed754d3eaL, + 0x072eb5e5f44a8604L,0xfa7b1a03cd5ca1c5L,0x6b6b4967d4779eceL } }, + /* 42 << 266 */ + { { 0x0f0233df8665f6f2L,0x8cd887463bd40f39L,0x23a41596eedf8d3aL, + 0x3f50e3f0b5ef5455L,0x935b24e0a50cd358L,0xfdd0e940d362a9a7L }, + { 0x6b00a6d154371aabL,0x2e707c4e1204bcf8L,0xb4d2d2dc30233f88L, + 0x470c3201783e58efL,0xf53987865ac21a16L,0x278487d626c3513eL } }, + /* 43 << 266 */ + { { 0xab5ac4df7d40427aL,0x0c4fb23b66ebdcedL,0xb02f8632b87df612L, + 0xebbd2e7f1801700cL,0xdd11de725b675e5bL,0x2adfb20662d7210fL }, + { 0xe3ba7c0e28667b70L,0x3e190a438fe31c22L,0x57908f2bc3390733L, + 0xe9e8714ccb6fefbbL,0xabba506dfd51c513L,0xd50f979f6b798860L } }, + /* 44 << 266 */ + { { 0xdf224cea1eed2b0bL,0x10205f438814572bL,0x8b99d85c02eb9b6cL, + 0x7a8a3d146c63a672L,0xc8822c6c96f45695L,0x0530f619c7f532f5L }, + { 0xb981e182310f8355L,0x49318290f201444cL,0xeaa4c406f9b76d19L, + 0x960fa2c7534a91c1L,0xf98966d1522b7d9dL,0x66912542c757dbd6L } }, + /* 45 << 266 */ + { { 0xe265972e1fe73a1aL,0x77e234c2987a1a34L,0x1814bdfe8c5789c0L, + 0x908f55c7df2ca0d7L,0xec207eb2a6a50ceeL,0x63cfeaffee916760L }, + { 0x808a758bf466a1b8L,0x2a48112d8383b0afL,0x5238922ef1a4ca6aL, + 0x5c422786778de666L,0xf5a8c6b5d2f549ecL,0xcac5d0c5242bbc9bL } }, + /* 46 << 266 */ + { { 0x33e0e005b34dbf06L,0x7bbdbe1e1fb341dbL,0x443fde882bab5425L, + 0x9db5bf1a86b57cdfL,0x72c535c309a93848L,0xf7aa9432b5f216ceL }, + { 0xc17dc7ae0242308dL,0xf1cb5dc5db0e4c0cL,0xb9d16d58a2b7112eL, + 0x486cda07ee4494b5L,0xeb46ab545d431adbL,0x3261dc5181ab565aL } }, + /* 47 << 266 */ + { { 0x476a4bfaa2a8a081L,0x43c5f841394f851bL,0x659baa591f5b22ddL, + 0x49a786aa65f680efL,0x091bd21608fcb9d8L,0x13f6953d984fe1f1L }, + { 0x7b5d9f4b6d6d40a3L,0x2f135dcf0d458d54L,0x2da18c3d3a71204aL, + 0x3d93edb97a3486d6L,0x026fec7261846af9L,0xa62197bcd5200dcdL } }, + /* 48 << 266 */ + { { 0x0cdd83725070e0a9L,0x7c5ad562ec550783L,0x9652b8474f3b8d2bL, + 0xfdd60d93e6e98d73L,0xd51cae2ca3479d0bL,0x11b93b6dee05c006L }, + { 0x9d72b82d8a3b40d5L,0xc6e996fea7d24855L,0x420672f7398603deL, + 0xd551b34a9a1af2ceL,0xdeb8c1d913bdce0cL,0x56ca926debbeba7aL } }, + /* 49 << 266 */ + { { 0xf63ec096bb85ca8aL,0xc149664173bc52f2L,0xba792560c02fc808L, + 0x9a6043e3533c6523L,0xa9d78f0aa8564390L,0x7fef67e494614bc7L }, + { 0xb4091b8fd389234dL,0x5913368e82db1d08L,0x178f7df0981cc6caL, + 0x19b1f2be725ec048L,0x852aad85012f9c44L,0xb07cac0dc894e777L } }, + /* 50 << 266 */ + { { 0x1c1709d02c7e0767L,0xec1013234d70b117L,0x95c57e678beb8e05L, + 0xdbf29e2e1133fa4aL,0x917f4a6c5139e020L,0xcf0be5098399735dL }, + { 0x83014c169c878b4aL,0xe0c14d2cf789b84fL,0x222aba39165a4aafL, + 0xe135f2b384441391L,0xb6f1cf7e19c3ee07L,0x2f918da9f810499eL } }, + /* 51 << 266 */ + { { 0x026ee35816bb2bddL,0x8c8953f8566d8470L,0xf0cd746d0fc63932L, + 0xddf3e54f060a07a3L,0x8da877a643b4e92dL,0x7ffd839dfdc9e34aL }, + { 0x5c3527445df04d9aL,0x3c5eb576b69f84e0L,0xf73cae300848d993L, + 0x3438f2bea0fe7fdbL,0xd4e7511f0eaf0168L,0xa7ffd167c768386aL } }, + /* 52 << 266 */ + { { 0xbb91877acfc74bb0L,0xbe742182a060a71eL,0x116e5a626ed7786cL, + 0x0a496b1bea669e56L,0x3a012174b8f02e6eL,0x6add760c106174f4L }, + { 0xaf2606e05e0292cbL,0x7800a495c7b7bad0L,0xca02c9320a1c5954L, + 0x904f23c6b245ad57L,0x28d6cc2172934de5L,0xbb7ed903283752cdL } }, + /* 53 << 266 */ + { { 0xc80288125e58122dL,0x7a5c65f1c4b089caL,0x4ddfd3663b980faaL, + 0xe8129f7f96a909a0L,0xc177aa042221ffacL,0xaf444ef78ff46e81L }, + { 0xa627f3d76b154996L,0x0f06fa7b115e2a5dL,0x2532b85d43fdb775L, + 0xb6d96b32eaacfb58L,0x898766304f834382L,0xfd2ffde9d5636b92L } }, + /* 54 << 266 */ + { { 0x318cf974973757d0L,0x12882d0a94ac73a2L,0x1fb74a53bc250843L, + 0xc612569eccd8d47dL,0x74cff8789d5f7c8cL,0x54e0e475375a7366L }, + { 0xe8322d23d0f57cd4L,0xb6ec5666d95a6e0fL,0xc8374b254a4bd084L, + 0x9459181b349d93ebL,0x7011f0a61368b9a8L,0xed57a19137eb2833L } }, + /* 55 << 266 */ + { { 0xd245d180fa5f79acL,0x44c331f35b41fcb3L,0x13188b6e27ee6c0eL, + 0x54ce984b23fdc742L,0x66d4e1303c81c213L,0x432174030ecb6fd8L }, + { 0xbbeb09fe111ae08bL,0xb22ca6b42e2df05cL,0x0e9d01dd0fec9be9L, + 0x9ac4523dfd2fc4abL,0x3d9e98c8fdc059f5L,0xd52e6dfb2d2cbde7L } }, + /* 56 << 266 */ + { { 0x80d7ef8598100f17L,0xb9795c7112db3f3aL,0x44473659296a7c44L, + 0xa46810f21e5bf539L,0x5621241814ee1e3bL,0xea8284e209931822L }, + { 0x424c613e42ac1e42L,0xe84a80afbccf9466L,0x21a8cdcc45132204L, + 0x9505a4148d58da62L,0x773e09837b3f47aaL,0x0ad0cc91e109bc6dL } }, + /* 57 << 266 */ + { { 0x98e2509bb527b250L,0x2dd30c824a9c762bL,0x54025da4cb2a00a2L, + 0x88ed00ff04d8e0e9L,0x5699890219ab1fadL,0x92fffc41697b0226L }, + { 0xb481d1ee7d08a39bL,0xea773f7f82be0803L,0x967e848a6de8ec6dL, + 0x6ea1e46380293472L,0x941cded72e988de3L,0x85f96b23399da6b5L } }, + /* 58 << 266 */ + { { 0xabd86572f1a62473L,0x9ec25d0bec274738L,0xd27d1a8c2052d4ccL, + 0x1f2a2a9ba95de3f0L,0xe3b8652ea2c91bcaL,0x1a4f6900822175deL }, + { 0xd9405d4662475a44L,0x4ecbe06cfe55c587L,0x30f8d199a4ac2f35L, + 0x2a5defd8d3c12844L,0x6d0fd9d673fe9b7eL,0xb0ae1019adf1a196L } }, + /* 59 << 266 */ + { { 0x6c9a378c30734f5eL,0xdf04359f6aaf7b42L,0x244422fc16f87409L, + 0x81dfb15b08bcd67cL,0x24b7d083a5e4a8e0L,0x557183410431786fL }, + { 0xc8feeb8c33f3ec2eL,0x360098cb2be371a0L,0xf4f3d992bdb874ceL, + 0x47b432ed87af8471L,0x5c4b1dbdf87535deL,0x6bb6d6dd8301f660L } }, + /* 60 << 266 */ + { { 0xafa9338759769f77L,0xe6c710cb49e502b3L,0xe6fd7b8d1514da98L, + 0xb5924c63aedf93caL,0x4cc36795c112b37bL,0x0ee30ce3231def42L }, + { 0xe1f436e7daf8a37eL,0xed54b7f56efa184aL,0x09ad65752c0dfe63L, + 0x5ed9da43ca530b38L,0xea2fa192ae156274L,0xbf096c54a4429edaL } }, + /* 61 << 266 */ + { { 0x41401b98f54490cfL,0x361a24a143b21183L,0xf0176431b6570f0cL, + 0x851bfe9d05c8bd3aL,0xe44f4ba74611e1b9L,0x587677dc28bf2c27L }, + { 0x3e3b67886d85341fL,0xad65a69468aa381bL,0xd269dc711aecf19bL, + 0xb94b64a2d98e6a2cL,0x6004b569a94661a0L,0x81713a8e689181d5L } }, + /* 62 << 266 */ + { { 0x55b1901d3649638eL,0x2e9929c416abaf64L,0x2d2b160ee9cd0090L, + 0xb5ef6525f55f13ccL,0x447aacbe11c3e8a5L,0x2c54e602630cf4c4L }, + { 0x3f6d99fc641d8eb3L,0x35386c1384877912L,0x7195db8973f31b6fL, + 0x63297cb2d3a22085L,0xa627593833fe97cbL,0x2f9a6f0da1eaef0aL } }, + /* 63 << 266 */ + { { 0xb70d7683c63d6dd3L,0x60ea781084acedf1L,0x7646260c40d62cd0L, + 0x687000b456142a6aL,0xce3c4728ccb9177bL,0x45377d059928c509L }, + { 0x75cc40bb1a78af0dL,0x43a1661cc69e59fdL,0xf9bbcbf8044a943cL, + 0x934fd40d7c372080L,0xb6edae96cb2eb940L,0xa02bb5fd6e063cc9L } }, + /* 64 << 266 */ + { { 0xac58c9e09db9ca19L,0xd308ea5d390054d0L,0x32ef4afc2cc42529L, + 0x08bd48b397c2bdf9L,0xac8a7803a849e19aL,0xcd51c0da75c31496L }, + { 0x733dc7def0e2d49fL,0x7c9caad1b44b8cc5L,0x6d9c5b0847be21a8L, + 0xfab0fdc55ebf426fL,0xd60748caf94e9e5bL,0x3072e59269366089L } }, + /* 0 << 273 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 273 */ + { { 0xb06c17a3f0ef77c5L,0xc144e7846df6bf59L,0x2440ae990038aeb2L, + 0x83bf711b58b402caL,0xb8763e00b577732aL,0x509e91eff651a932L }, + { 0xbe02ab9d00ac109eL,0xfbcb426c8dfd78f1L,0x7ed272f64283f80fL, + 0x098cf0572365da5eL,0xd90e6f1805dc6bebL,0x09ef177fcf7b9d72L } }, + /* 2 << 273 */ + { { 0x6f101762eeb791c4L,0x0d942184df261effL,0x2c58e2aaac1dc827L, + 0x51410e89f835a1b6L,0x981333a7629915a4L,0x371891b60c14148dL }, + { 0x4d20b3d3c0904446L,0xdda7ecc8949776d8L,0xa664b68c2a2645f7L, + 0x7a6bc857add082eaL,0xe7467dc63e5ff206L,0x40a6c34004e2dfccL } }, + /* 3 << 273 */ + { { 0x3d0efae3106ba1a1L,0x9c717ca192d7be5aL,0xa5cb5a253f00eeeeL, + 0xc2f9258cd86161ceL,0xd2b0865f5c4a389aL,0x8c06d7689b1f2159L }, + { 0x5a758a612753107fL,0x5ab6449d0a539c19L,0x88655a4949d301c8L, + 0x129647e61c4bb89bL,0x06f0665ec360259cL,0xcdba2f0b066197d1L } }, + /* 4 << 273 */ + { { 0xa235456903744726L,0xd2169e6dd8d275acL,0xab0c247b132c5689L, + 0x129a5c9dcc4760bbL,0x03eba46726ae821bL,0x67a33fda3df1cf83L }, + { 0x010813cfb8421b7aL,0x7b0f507098cd6d76L,0x907320b31fe4b600L, + 0xda3bfeb398dd3239L,0x23f1ed1641abb34cL,0x01b30f29946f85f1L } }, + /* 5 << 273 */ + { { 0x97c5f1c7d3970d9fL,0xd051c518ac8e6227L,0x3f67b3958e87edacL, + 0x3a5cbd287b9e4c17L,0x58c009e65671841dL,0x7bc5bddb518b3b39L }, + { 0xe7a8a6335e74a614L,0xf92e4c226ed89a92L,0xd0d6e80a118e663dL, + 0x33dba4f9dcbb4aecL,0x1d4cb3141f917417L,0xd8b17bfa3b0c5859L } }, + /* 6 << 273 */ + { { 0xc0fa0d21a093c3e0L,0xad34c41439e902a2L,0x81c8cd7599bc928bL, + 0xf7f8be14cdbbe4d8L,0xe46268b5c2339529L,0xcdc54e348283ba7dL }, + { 0x4c5cf62778904fe1L,0x056678c11b45e4d2L,0xb555ad6ad265abc2L, + 0xb8f8ca3f830306efL,0x48c8764681c20e1dL,0x5bb0a529737a7944L } }, + /* 7 << 273 */ + { { 0xbd4c2bfc9cf6fc5fL,0x888885140577af66L,0xb5aa2f05f9e3f7c5L, + 0xbd477bae64de6007L,0x1da5dcc9747e1224L,0xc2293d1732a15f5dL }, + { 0x4dd9daed029d6cbaL,0xf51362d62cf299c7L,0xe1a4b5c4279cd1e1L, + 0x4b129a5ea89acfffL,0x8292228ece1c8744L,0x5a440fa04fd12c86L } }, + /* 8 << 273 */ + { { 0x285248309666f8eaL,0xd579b3dfeff6502bL,0x3a66fa9900e4f78aL, + 0xfd8a65bb54a3f7a3L,0x505d3f631965a79aL,0x9524972c1891469aL }, + { 0x78367cbc3354da3aL,0xbfe1fe3de4941c6eL,0xe41bb3f6f5af173eL, + 0x57cb03ca5ca36597L,0x27f86cb87b99f795L,0x5cae6514ad4dcef1L } }, + /* 9 << 273 */ + { { 0x4b43f0aef1743346L,0x1700581944324c46L,0x86c77197e3603fcaL, + 0x230d516f4a6858aaL,0xee965b4ee7c56f7fL,0x4f4ed301dcefb75aL }, + { 0x610b138c4a740b23L,0xda3996a83ffc3599L,0x930698fcb2d1c304L, + 0xd55bdcd3702bf80dL,0xdf767c419e334726L,0x975352a9d0e819b6L } }, + /* 10 << 273 */ + { { 0xc117353b5e816653L,0x0c87bebe820641d5L,0xee588c6d9ecd29a1L, + 0xacdfe622c70edf9bL,0xe8b8024cebae414bL,0xd0c426dc9bd7ceccL }, + { 0x715cbc2efe735ce7L,0x8376edebc5e7017aL,0xe9b37efc07990dd5L, + 0xc89e384ed8d75238L,0xbc594d218438ffb3L,0xbe77e4d4d3628473L } }, + /* 11 << 273 */ + { { 0xc53720cdd1b4f3baL,0xb8ac3b4fadf2a330L,0xcef037f5fe179e70L, + 0x2743b382589d9147L,0x77a094d624423d58L,0x9e34c2e62a23d372L }, + { 0x641ea760983a5893L,0x2211e6a49a81548eL,0x56578a1a48735310L, + 0xedb91e03a57faa83L,0x4e14d5649b133629L,0x341f3ef957e82ff7L } }, + /* 12 << 273 */ + { { 0x4952a350d87a86c9L,0x08ed7da7034f45f9L,0x1e9ff8272bd716d0L, + 0x2471fd15f1d9331fL,0x0c708362d7370b75L,0xaddedde6fc1a1051L }, + { 0xf4475288db27b186L,0x5be4d46b3760bc11L,0xe44435d906d47ee1L, + 0x865cf7c8d0b7c8a2L,0xdb412be08d31a252L,0x4b90a9322f24d71cL } }, + /* 13 << 273 */ + { { 0x71b84eed8f7a3ab9L,0xf41d7edb2dc18004L,0xe408156dcc4a02cfL, + 0x0be155a25cd906caL,0xbf4b0f6991516399L,0x2ea85d434a7ff94dL }, + { 0xf199b31da26e9974L,0xc584df250b805ae3L,0xd4e7e8597a3634daL, + 0xf553f07770db4be9L,0x1cb1056fbf0dafa3L,0x235281b2a817d6edL } }, + /* 14 << 273 */ + { { 0xc3304e9260d2b80bL,0xab24dac9a38753bdL,0x40373d04cc1ebbf8L, + 0xa5a162d3437e68d2L,0xc8018b1257e8db12L,0x0c99c6de9bb52643L }, + { 0xafef0ff6ee24e63bL,0x329c46264bea9a14L,0x1b17d2e6effae4f9L, + 0xd25b93aaee300afdL,0xe83bfdcba0d62da4L,0x5e919538fd787740L } }, + /* 15 << 273 */ + { { 0xf5bbb4fe196c38e7L,0xe0011deca5c75baaL,0x2e29fe59b835aa49L, + 0xee22e2864230f17fL,0x8774214ff94c1060L,0x35bcca38e6d4c126L }, + { 0x18d984dbb7c9d255L,0xb1d5515c9b63dc4fL,0x425360f12a0cb854L, + 0x038c7f2317a1e286L,0x5e6b12ce951f18b2L,0xabfbde5ea65b1de3L } }, + /* 16 << 273 */ + { { 0x38a49bf555f0ad9fL,0x1a84c6b8f3618639L,0x5f709eca01b2f7c2L, + 0xc479a6505be8359fL,0x6b6a22bfd6646b3fL,0xcce78878cc5b711bL }, + { 0x8e7dbc63b446cc63L,0x231bd027218f800fL,0x2d3a7e04030271ebL, + 0xb08b5978e22fb3c7L,0x860d62789be0d46cL,0x253a31c21d49a915L } }, + /* 17 << 273 */ + { { 0xab4dbdf36ebc28e5L,0x56d5fec527be58b5L,0x6e9375d3cf3fd509L, + 0xfffea897ca4ddf48L,0x0a9542ae6a3757c5L,0xb9069a2e7d93911dL }, + { 0x3e74ac5f3dc967b8L,0x99c38796ea8f5a21L,0x27797b97a6ddea53L, + 0x9501e1c561dfcc1bL,0x568d3abe448e95c5L,0x021f8f4c0e7c186bL } }, + /* 18 << 273 */ + { { 0x98aa1f7a6e44f63dL,0x6451b170cb597ec9L,0xc0f6ee8721e13b78L, + 0x36c3b9c751cfd003L,0xc31718ed2f610040L,0xdddabc6688c48009L }, + { 0x5626f090a8369e4fL,0x0eccb1c06004a968L,0x2f0448035da2f1a4L, + 0x5390b6dd3846a726L,0x5c4caffea24f3083L,0x3c9baac8c4842995L } }, + /* 19 << 273 */ + { { 0x58c5fd1205c7a75dL,0xa98007fd10866935L,0x91369e874acd567eL, + 0xb7e05dc322c6145aL,0x24c949b4d949d8b2L,0xc5c574a590a6a437L }, + { 0x4306f0334798d1d5L,0x82af09f4520e01b3L,0x53fab41b81247f00L, + 0x3096ccf44ea93cbfL,0x9665e039f13ff09eL,0xb623f8b158e036d9L } }, + /* 20 << 273 */ + { { 0xbad6b669376bdc3fL,0xc4a8e7bc23a9ff38L,0x3f54d8c4555fb0a3L, + 0xfb3d5e1d2b23db1bL,0x6379f78af0d7eba9L,0x36004febfa0beffaL }, + { 0xdf0a373c334ff01aL,0x10314749dff12a1cL,0x1d52ddc7f184c1b3L, + 0x79431663ab02d404L,0x1a6488c17f4d3795L,0x3363660f7cca9102L } }, + /* 21 << 273 */ + { { 0x1e4595c6db3e57d9L,0x49e3d3d9bfb94ec5L,0x4c720de1a4f12881L, + 0x91a08340b06c64e6L,0x8e5c72f0ef0857deL,0x2c9b4cbc09bb76fcL }, + { 0xd4262fe4b0bba8bfL,0x64c5fa1439fcd07bL,0x518da4de62904ceeL, + 0x626182ebae4c9717L,0x900fe9f806351622L,0xf74aaa2241f9e4d7L } }, + /* 22 << 273 */ + { { 0x9d2c02839fabb29bL,0xb27ac46e172348cfL,0xddc6fb63de1f64b2L, + 0x532dc953bb097c87L,0xc7f5180cdaa34e27L,0xf96e4ad755438893L }, + { 0xc0b2eba324f54a0bL,0xeba396ce5b50d12eL,0x80b3a7f699772783L, + 0xe2fa82ff3ff7df4aL,0x55375369a2359baaL,0xa28388ed856c05bbL } }, + /* 23 << 273 */ + { { 0x4432fe8495a2d064L,0x4c6380747fec6057L,0xc33705bb33cfb533L, + 0x5e7fb7c976991cfeL,0x73d249bdb3ac1b6eL,0x963964c896aeddccL }, + { 0x8c1abe0e56b71636L,0x6ebb841f38693cd1L,0x00ef6a7b60e7cf67L, + 0x29ecded2c258bcb9L,0xb2d566a5e40fd26aL,0xa2910f4ed512abffL } }, + /* 24 << 273 */ + { { 0x56d6515604dc109cL,0xcd740cc809c1d307L,0xef9e049f10dfaeadL, + 0x19750b3ae30b70b8L,0x11ed860015c6a562L,0x53bdf97e12097026L }, + { 0x79559d056c0d908fL,0x8f1d75bab506d527L,0xd6fd7323ae8fb3c4L, + 0x834639c9a4111f88L,0xfc69a029a310a683L,0xa4467bbb255f2e9aL } }, + /* 25 << 273 */ + { { 0xa809a063e9e3953fL,0x09242dc960dc53fdL,0xa48f52d00080c436L, + 0x762a585dad2eb70dL,0xc6d52f047a3c6aa2L,0x1b6979dcbe60899cL }, + { 0x7a07af246d760794L,0xa5b1f912ef5c1118L,0x36367e4375bb329eL, + 0x594f349029e6bddbL,0x13cdc4aaa4a4f1edL,0xa7c3ff97b687a69dL } }, + /* 26 << 273 */ + { { 0x1e79881146f7c4c0L,0x25730855946abf8eL,0x1741fdeeaac2031eL, + 0xef34715b72ea60b6L,0x378eb680350ddcfbL,0xe72ac880ec237141L }, + { 0xb173251fff125bf8L,0x37ffb0cf4999b6daL,0x9eeb91a8817779f6L, + 0xa9edff0ae93ed1f3L,0x31f2ca241d7772d6L,0xd25c3f3b97f67b92L } }, + /* 27 << 273 */ + { { 0xb6c4144381478e46L,0x7b53d46350cf8795L,0xe96e7cb9ca5bf2d2L, + 0xc8fa39c695ac9ba6L,0x8ab037d12efc83d1L,0x0ccacbcc94bc2536L }, + { 0x45e7c7c774038e13L,0x47d5b7292f5e344eL,0x2e0ffb2cb1eed282L, + 0xfe88d3a88d5d0b37L,0x804b612e2487d971L,0x6f316d66c95d08faL } }, + /* 28 << 273 */ + { { 0x5f0a58a8a3526fecL,0x849c171b02f028c1L,0x34d77ce856a5d3b5L, + 0x9701621754d5a92bL,0x0cce35c12cc5b70bL,0xd9d5a00ae83f1f4aL }, + { 0x064223f826a0368bL,0x328a9f6940e16452L,0x3a6ac093d305ad2cL, + 0x759d9a16beba7c44L,0x86021de7637ce7c8L,0x276bed61cc80c1ccL } }, + /* 29 << 273 */ + { { 0x5d4a529ef9822e60L,0xc6f2702006edd801L,0xb2511d84efa3d8d6L, + 0x38cfba656a4c6598L,0x31a5779765c067a9L,0xcee558f387d2ca0aL }, + { 0xf22345cff844260aL,0x29b6352a63d2ae75L,0x59dad0ab6cc9f2bdL, + 0x615ad3599ae1bcb3L,0x3a29a237f692f42bL,0x543771c40f26163aL } }, + /* 30 << 273 */ + { { 0x427437e7d722576cL,0xc9d7ac7abb548ef5L,0x72f00f28c331a9e0L, + 0x5d9327b564949b48L,0xea75f3b54e2bb808L,0x28acdea068678f8bL }, + { 0xe9e787b20878223fL,0x213f47ff7e7b0a11L,0x5e967d39f277a3f7L, + 0xe6651015d2006de4L,0x49b87e4bc44eb1e0L,0xf461bb76222cd3a2L } }, + /* 31 << 273 */ + { { 0xd6b9341fde60d963L,0xb1a8dd0d5319a930L,0xc4f18dc0aa6b20b5L, + 0x787de2e7f23f4401L,0xc15b38eb28047029L,0x0bffc0b55c99d51aL }, + { 0xf0310f39740b5798L,0xf69ea1064ed8d3bfL,0x545a54d79f6722aaL, + 0xe5a9dee3af4017c2L,0x45efa2ec4a659592L,0xc5d64bedbed4e245L } }, + /* 32 << 273 */ + { { 0x66797f56bbe4bddaL,0xb92a369eda51b1a2L,0x18eef4a531adb034L, + 0xcf1cb5ee5d185cfcL,0xf596a59bbd53c27bL,0x1e1dd6f569002569L }, + { 0xd9433e797687e48aL,0x7d8d24c20cbcb9ceL,0x233cd7ed65d68ecdL, + 0x201bbe09fb2aded8L,0x987f4975ac9b750eL,0x949da385337f7f25L } }, + /* 33 << 273 */ + { { 0x31439e35b95fd11dL,0xf97e8fa4b691fb77L,0xcfdc02956d4ac378L, + 0xd31bc3b0d1a617c8L,0xd857098204bd015bL,0x30cca6efd6198f0dL }, + { 0x6a52650a805964edL,0xb656d7abd060eeb3L,0x5267f37ed38a9218L, + 0x5f28a2ecd3d6a193L,0xb7dc6e916d0d9c9eL,0xa7f84e4b219d45c6L } }, + /* 34 << 273 */ + { { 0x550ef2713398c3dfL,0xfe184954307631a8L,0x02cef50606e5cde4L, + 0x9687a39c10f11703L,0x02c35937acb10b97L,0x835b00fd13e3d219L }, + { 0x5828678b584d1abaL,0xbe55fb9cc9b40568L,0xe5a4a90e8fe19e84L, + 0x91e24c9248989b77L,0x094f9e7ae3d5f4fcL,0xfe9bdfb9759029b5L } }, + /* 35 << 273 */ + { { 0x43b1f8b9c1de72e9L,0xcbc8e0d4a3bdb164L,0x5c45d3dfbcc2e5bdL, + 0xb5137b69247bef53L,0x6d889f5673794e3cL,0x43e2fc9b1e2dfdc1L }, + { 0xda15dc5da995d3adL,0xa0db9f5ec43d86e0L,0xc42a144bcaac3bbfL, + 0x3c855fb174c43eddL,0x0731f33152688272L,0xc1f23e5643d7762aL } }, + /* 36 << 273 */ + { { 0x00c2ee1c9c7de99fL,0x28a7461d15e50391L,0x1bdc0e32a1c77952L, + 0xe98242c4d53d640dL,0x1a4724d2cf153c7dL,0x194e5dccba477d46L }, + { 0x871c8cfe3a0d4ccdL,0x62010af09af451fbL,0x9b354f9e6ddec75cL, + 0xe5db0a5d680e3511L,0x183d1270d247745bL,0x9910867aeecf52dcL } }, + /* 37 << 273 */ + { { 0xa970903e8bc2003aL,0x0f8bcfa4a3cf29bcL,0x7054f69e683a7ddaL, + 0x53928bf1ece30167L,0x2588bdf1ffffea87L,0x01683b5ed7172ad4L }, + { 0xa0ac85379de7e713L,0x217bcdfe9b0442bcL,0xba46b8f64d4adb3eL, + 0x320580990a9f8ecdL,0x0173b7bea504bdc5L,0x15321aeb82b1606fL } }, + /* 38 << 273 */ + { { 0x4f349e5f6e39d625L,0x37cbd935b80760d6L,0xb8657ee14b1e84c2L, + 0x502954064cb84bdeL,0x66d678cce8d23ef5L,0xcba173713ec3b79cL }, + { 0xed7ab3e526e3cee5L,0x34c68c516c44ef0cL,0xd704e724f8fdd226L, + 0x2fa0d2dd3a9b40a7L,0x373c5c70a23be590L,0x0beb611bda9f7f7dL } }, + /* 39 << 273 */ + { { 0xef506531913bc31bL,0x31210c5f8c320074L,0xb42faf19b861acc1L, + 0x26f09b89e041e774L,0x23fec89822f84c93L,0x9f8b9d708ec590bfL }, + { 0x604d7d2952644790L,0xb77e3136a2339c53L,0x17f1d7a920f2fc09L, + 0x8c6435d9e6bb96eaL,0x5cafeb5f3711b8a7L,0x1ec6c4edfa23ca24L } }, + /* 40 << 273 */ + { { 0x6fb6b7bc0410ca0bL,0x0e16eed2b3c13935L,0x98ad89d8316ff531L, + 0x4800ee179894d65fL,0x034ea3c448280170L,0x8126d12dc30be537L }, + { 0x43c2d27e5120e525L,0x96a5d498ee65df90L,0x654540105eaef29aL, + 0x1d8f07a17b678fc7L,0x54bc6f737b301270L,0xe58a8102e9473365L } }, + /* 41 << 273 */ + { { 0x1fa3a458aaaf79f6L,0x1d14ff613a1b7c64L,0x32c7da68f22ddb3cL, + 0x7b2345ac58cff63fL,0x214e6d9dce3c3af9L,0x36fba0b78b6691deL }, + { 0x69fd813cee1a30abL,0x50daffe91adf6215L,0x55b34de692871a84L, + 0x437f1b4b7ff3ea1aL,0xc3258ca580ff1c23L,0xdc220ffbc6d0b822L } }, + /* 42 << 273 */ + { { 0x93e56b47ad910b37L,0x8cbce4815d20d236L,0x25b50cac5872d763L, + 0xb50aa752d8505696L,0x02075e6d6f42b533L,0xf0b34a178f8d8352L }, + { 0x59f2feda5234531bL,0xb23e1da1751127c8L,0xe1f65e08b6759ccdL, + 0x47d8631c352e9500L,0xab10d299c13feb16L,0xf9e916a3e5c6a220L } }, + /* 43 << 273 */ + { { 0x55899ffdc06f1b65L,0x4f9ec6e011899630L,0x0df97edc50a29319L, + 0x5c4a10ea5e66f0adL,0xea7b4497aa3d14e9L,0x484d8f64d22cc470L }, + { 0xd7fd252240a61a0bL,0xebd9f49d42d04a79L,0xf18ba2ec312ddb99L, + 0x687273ec2dce1351L,0x68d8b052d0220e57L,0x2c0ecd6b05a7e3dcL } }, + /* 44 << 273 */ + { { 0x460c29904ac6cf02L,0x01482cfa420a35b7L,0xf793933a34680972L, + 0x2cd1f50017e2367bL,0x2411c3523944f060L,0x3d58b97411c06b05L }, + { 0x4552e369cddebb3bL,0xe1c38aec009aeab9L,0x9d34737c353b6e4fL, + 0xf2c99e2cb16d7b0cL,0x57029fa47bbba6a2L,0x0565d1bcd13ef64dL } }, + /* 45 << 273 */ + { { 0x93a50cc7eb0112a9L,0xa0d4419984a59bdbL,0x04b9538c82d01160L, + 0xdb1d33e163a8d5a3L,0xa710beff08d3effeL,0xc2f37326f9bf02f4L }, + { 0x606b6b5555d26856L,0xf528d22a427fe3d7L,0x31b20fac84fb5086L, + 0x27129aa592f7e7bcL,0xd88f0d4f44171b33L,0x9b045c897915ede1L } }, + /* 46 << 273 */ + { { 0x0b15ebebcbe014d6L,0xa4f1504e68d24086L,0xbcf475c979d7c8b6L, + 0xd61b92a8d00a6890L,0x78e096742ee24533L,0x6fe9fe6099656101L }, + { 0xc9542f53e5e63e28L,0x59ec39e12edf3a80L,0x8fe57ffe24ad9280L, + 0xbae0671bf4b9b024L,0x76e36c14d5816ae9L,0xe53256d4805f8688L } }, + /* 47 << 273 */ + { { 0x006956bfcf9e545bL,0x7829ed13e8fa2ee4L,0x1b108d77d4dd6f85L, + 0xf51217bb17045f1aL,0x48c4802986141bd6L,0x8d59b995f8820213L }, + { 0x8439949ffc298a9eL,0x967fdcb278188d77L,0x5bbdfd296f35c711L, + 0x25b37e5df8e62607L,0x18f5c4251795cccaL,0x260f075af0e35ff5L } }, + /* 48 << 273 */ + { { 0x3561b3fea329deb1L,0xfdca0e34f1c3c3e4L,0x4374831347fb79d6L, + 0xa7f497e1c48002edL,0x86221cce2c44dcb0L,0x65e3f04643785e06L }, + { 0x9ee9061fdf4cf461L,0xc7479e8cf022d27aL,0x1d8de85b76f7f52bL, + 0x39a713c90fd6c65fL,0xf74ca067711f8a39L,0xad1119ad8ebc640aL } }, + /* 49 << 273 */ + { { 0x43d9bcba57ec124eL,0xbce6aed98cc29801L,0x1dbb88c72632e757L, + 0xe88f49e891f550e5L,0x056f67da7b6e1b05L,0xa503271082a027bbL }, + { 0x8471fa55c91844a9L,0x882f25b628479daaL,0x96f606dfa9c23504L, + 0x6a42d307fb7fa83dL,0x531c8a5cea310e34L,0x7e2d20565b2e42f0L } }, + /* 50 << 273 */ + { { 0x547047862e8c467eL,0x26f5efc690e52377L,0x762d8f767f6e71afL, + 0x5fc1bd13917ff587L,0x487f6c63fb696a60L,0x889a1dcc3afd2aebL }, + { 0x7407d0a0adcf4b35L,0x8f6c9aef91024ecfL,0x3384f1c03e5d9da0L, + 0xf87acb00b846d122L,0x6d86aebddceb383aL,0x6a5a90cda8f2d076L } }, + /* 51 << 273 */ + { { 0xddff7aa3feb71de1L,0x431e106be44644a9L,0xafe96f8ed5190b4bL, + 0x31a4dfe40ab42a27L,0x0e2d0cc435762eccL,0x7c928cd91fefb256L }, + { 0x5f33c775daeb94f9L,0xa7a91f8894c239b7L,0x6bf418fb4deda3c9L, + 0x91ad6e99eefd4f99L,0x7aae05559c25448fL,0xfb7ed9df487b4deaL } }, + /* 52 << 273 */ + { { 0x59753bf68ba85dffL,0xec8b82efd1c89bceL,0xd7f1a651b8b6a683L, + 0x9c329bf36f84416dL,0xaecbf4b9e68db225L,0x94ec3b0f5a614d23L }, + { 0xbcb6672593a9543dL,0x90c46c46f19132edL,0x4767c73c950b080fL, + 0x0b9b143e971fd9e5L,0xbce6886f8ec8c68dL,0x167b0f8ad47f512eL } }, + /* 53 << 273 */ + { { 0x51517f9481819dd9L,0x2c2640a0fdd7cef9L,0x59283faabf98b8ffL, + 0x39713768a46ad877L,0x13d9c0e6834dcf0cL,0x38c85473cc7acaddL }, + { 0x7b58c7666971a512L,0xbe46a58c2a38e57eL,0x3d26d0a06972e213L, + 0x2341769b63cd0aabL,0x4a293dd0e86307eeL,0x8d1e338d264c81a1L } }, + /* 54 << 273 */ + { { 0x66eb8beab2d5b430L,0x50b4af4382136220L,0x6644e673e79d0b5bL, + 0xe64cdf10f9fa7610L,0xf1dea591132ff33dL,0x07791ab6b926c725L }, + { 0x6c41b4f383f60e02L,0x54bc9049977519c3L,0x618a6f3c2aef73a4L, + 0x42cfc9d26fa4ca2bL,0x2784db71a39a215dL,0x378071655cc85253L } }, + /* 55 << 273 */ + { { 0x9cc3ada3554a7f23L,0xa822f9f21c3d0003L,0xb1654da7303123f7L, + 0xbe33e388f0d8c4a1L,0xd8919c79be4366e8L,0x5a41c92cfe292117L }, + { 0xc4b02d0678c325c2L,0x89eaf4356d511c4aL,0x726fb6d65fda70a0L, + 0xaf7949a0183abdf1L,0x3410915d26f8f929L,0x36b3aeb281f0f83dL } }, + /* 56 << 273 */ + { { 0x1942c2ffcd74009dL,0x71c4d5f5e9c286a4L,0xf3c152b5771a5972L, + 0x4cfb1e74363c2048L,0xcd2ce8249ddb8da2L,0x5d97c8e0a5ee443dL }, + { 0x6fa84b3d68d7b3d5L,0x97eaa76d9ce14ec3L,0x2e4571368e13869dL, + 0x39ac6a0c96f0f8a1L,0xe24458ac42d93dc0L,0x7eb3689d5f60bec9L } }, + /* 57 << 273 */ + { { 0x75592736bce6ebe3L,0x84001a886777bd90L,0xe82739774a31ca6bL, + 0x6906baf0a8e0dd38L,0x92af56d0848d0c92L,0x7ae700c6501326d0L }, + { 0xce418817470339a9L,0x4354d7928e448dfeL,0xc8f593afa48e3148L, + 0xdd5fee34db1a96b2L,0x5974e81e357960c2L,0x7326bf016306fdabL } }, + /* 58 << 273 */ + { { 0x74183618de017cd9L,0x939c7975dcfe6dbfL,0xcad9f8a108ec41e5L, + 0xd9edb91d391afcddL,0xadf1f18c7c4a3f03L,0x0566d3e8ab477304L }, + { 0x32ae20464c19c62cL,0xfa15fdcb252c8c4eL,0x2ed4767e91de2794L, + 0x622e4f38507f8067L,0xd647242bc68ac330L,0x0650e0a9fc1ccf29L } }, + /* 59 << 273 */ + { { 0x6ecd68a086085cc3L,0xb463f4c165c0cc54L,0x3182cc5c480bc57dL, + 0x8f16f2038e6d9267L,0x8c92e446df0d0ee9L,0x7da6001ba4d09789L }, + { 0x596390ff976ee9d0L,0x12b8f9dee4c0fd5fL,0xad08673f297b10f2L, + 0xc8e9097c7b524a51L,0xd494f0d3009cf47cL,0xf535c07abcdd1b68L } }, + /* 60 << 273 */ + { { 0x29544fe8588360ecL,0xa1aa9b9fffb550eaL,0xe1f6cf994af4d28dL, + 0x723d48b00c6fd477L,0xf51f1b2f5c81b252L,0x88ec11c04f5a33eeL }, + { 0x7747f0432cd72de4L,0xcca69b0ad71c92c1L,0x9455d86e4e8cc763L, + 0xc9e0aa1bc08444e0L,0x93803b68e8fffa63L,0xc296af292d781b7dL } }, + /* 61 << 273 */ + { { 0xb1891a2b17329e31L,0x87c2a49056e36717L,0x8c2a50fafd26d8b3L, + 0x017e4e417e3c5a5fL,0xbeb4fad0506c382eL,0x5d3e8b16fc281ec9L }, + { 0x407f7598890e57a0L,0xda855e8b340cd6d6L,0xb9393129ff388d54L, + 0x41113ffdcf355d9eL,0x31d3bb09b357c28dL,0x975bdf00fd39e481L } }, + /* 62 << 273 */ + { { 0xbfb0c87e10a1b4f2L,0xfaf51153dc2fcc04L,0xd2588e39d6b98d81L, + 0x5de5b0eb4953133dL,0x6b65d8135b959ed6L,0x864511dc02eb45bdL }, + { 0xb1dcb4d3d7ce20bdL,0x917bcd0987587230L,0x0935790f83a79453L, + 0xdc65862e54b35d76L,0x4cd2332ba6d1eeeaL,0x0706fcd030d315b5L } }, + /* 63 << 273 */ + { { 0x7c91adb3adf2d8d1L,0xfe1549c24a212fd3L,0x8a7cc285c33213b3L, + 0x26643cfd3e56d17bL,0xcc007c15684c872fL,0x485643e009e554f3L }, + { 0x7f5e9a6ec6569206L,0x252b5393c2f596d6L,0xf7eef1dbbf9cdea5L, + 0x611ee7334dffab46L,0x8d93802a805e976cL,0xd07c0ac6f85c939cL } }, + /* 64 << 273 */ + { { 0x514cc1dcb08d2d0eL,0x4e6b379e30e93536L,0xf0e422ac2fc9230fL, + 0xaa50a1ad92e23e21L,0x70ac46d8676d1ac0L,0x698b9991f9f54493L }, + { 0x59a6b86a8649519fL,0xc1f11ad6e3511da4L,0xd3d9cff13192968cL, + 0x13e700b40b342dd8L,0xfd5dc7bb3b1da441L,0x02426e7c2c883760L } }, + /* 0 << 280 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 280 */ + { { 0x9e9af3151c4c9d90L,0x8665c5a9d12e0a89L,0x204abd9258286493L, + 0x79959889b2e09205L,0x0c727a3dfe56b101L,0xf366244c8b657f26L }, + { 0xde35d954cca65be2L,0x52ee1230b0fd41ceL,0xfa03261f36019feeL, + 0xafda42d966511d8fL,0xf63211dd821148b9L,0x7b56af7e6f13a3e1L } }, + /* 2 << 280 */ + { { 0x3997900ecc8998d6L,0x8fa564b7baa60da1L,0x71bf5b0a661f3c57L, + 0x44b13388aab1292bL,0xcbe80cb9d4d993f2L,0x0b19b4c92203f966L }, + { 0xbc82a6520080f259L,0x870ebc08ad96dea3L,0xa388c7e7502f0003L, + 0x9c704ef056a38f73L,0x93cde8a73487d9b0L,0x5e9148b0ec11a1f3L } }, + /* 3 << 280 */ + { { 0x47fe47995913e184L,0x5bbe584c82145900L,0xb76cfa8b9a867173L, + 0x9bc87bf0514bf471L,0x37392dce71dcf1fcL,0xec3efae03ad1efa8L }, + { 0xbbea5a3414876451L,0x96e5f5436217090fL,0x5b3d4ecd9b1665a9L, + 0xe7b0df26e329df22L,0x18fb438e0baa808dL,0x90757ebfdd516fafL } }, + /* 4 << 280 */ + { { 0x63f27a25a748b8f5L,0x68c8f3ec2cd246c4L,0x5d317cd965f9ce38L, + 0x162c92e0635ba300L,0x5259f64ffe343662L,0x4a6b2b668e614ac8L }, + { 0x97fb55bb01177c3bL,0xfb586c21a705cb01L,0xa57e732578061824L, + 0x892f6b386c1e6306L,0xf12e4c072367b14cL,0x580d5fe2c83a48c5L } }, + /* 5 << 280 */ + { { 0x1e6f9a95d5a98d68L,0x759ea7df849da828L,0x365d56256e8b4198L, + 0xe1b9c53b7a4a53f9L,0x55dc1d50e32b9b16L,0xa4657ebbbb6d5701L }, + { 0x4c270249eacc76e2L,0xbe49ec75162b1cc7L,0x19a95b610689902bL, + 0xdd5706bfa4cfc5a8L,0xd33bdb7314e5b424L,0x21311bd1e69eba87L } }, + /* 6 << 280 */ + { { 0x6897401cea2bafb3L,0x7b96ecc215c56fe4L,0xe511b32939e2b43bL, + 0x39522861bf809331L,0x815f6c1dc958f8f4L,0x2abbdf6bc213e727L }, + { 0xeb09ae59c39bc01fL,0xffe3b831676b56a5L,0x8f4815a2a20f86c6L, + 0x748a17669aa30807L,0xf1f46a211b758878L,0xbd421fe76f6fc3d7L } }, + /* 7 << 280 */ + { { 0x75ba2f9b72a21accL,0x356688d4a28edb4cL,0x3c339e0b610d080fL, + 0x614ac29333a99c2fL,0xa5e23af2aa580affL,0xa6bcb860e1fdba3aL }, + { 0xaa603365b43f9425L,0xae8d7126f7ee4635L,0xa2b2524456330a32L, + 0xc396b5bb9e025aa3L,0xabbf77faf8a0d5cfL,0xb322ee30ea31c83bL } }, + /* 8 << 280 */ + { { 0x300b04840d6ded89L,0x0b1092cbc3ab55edL,0x17d9c5420cc10a74L, + 0x7f637e84eff9d010L,0xd732aa1e27aa1285L,0xedb97340e2a77114L }, + { 0x62acf1585ef4dfb0L,0x1e94fc6eba1d7b81L,0x88bec5d22e6eb2dbL, + 0xaec272028d18263dL,0x4b687353e4bbd6acL,0x031be3510ff7e4c0L } }, + /* 9 << 280 */ + { { 0x048813847890e234L,0x387f1159672e70c6L,0x1468a6147b307f75L, + 0x56335b52ed85ec96L,0xda1bb60fd45bcae9L,0x4d94f3f0f9faeaddL }, + { 0x6c6a7183fc78d86bL,0xa425b5c73018dec6L,0xb1549c332d877399L, + 0x6c41c50c92b2bc37L,0x3a9f380c83ee0ddbL,0xded5feb6c4599e73L } }, + /* 10 << 280 */ + { { 0x6c00f388f086d06cL,0x17ee45035add0cf4L,0xf96984c707caf89cL, + 0x9d49d667648ed5e9L,0x3ef95015a0164881L,0x39e28e447d9c651fL }, + { 0xb13ad24059f37780L,0x08cee349b9522225L,0x9245ee6f2ba1b214L, + 0x12bedaa9a886d8d2L,0xe139ae08fcb8186fL,0x99203fb6fc2ef864L } }, + /* 11 << 280 */ + { { 0x14d34c210b7f8354L,0x1475a1cd9177ce45L,0x9f5f764a9b926e4bL, + 0x77260d1e05dd21feL,0x3c882480c4b937f7L,0xc92dcd39722372f2L }, + { 0xf636a1beec6f657eL,0xb0e6c3121d30dd35L,0xfe4b0528e4654efeL, + 0x1c4a682021d230d2L,0x615d2e4898fa45abL,0x1f35d6d801fdbabfL } }, + /* 12 << 280 */ + { { 0x3c29284764c9323dL,0x40115a890491f77dL,0xec141ade2d7a05f5L, + 0x0c35e4d9222a5f9fL,0x5ea51791442a3e9bL,0x17e68ecee51b841eL }, + { 0x415c0f6cd6ae9174L,0xe6df85f89ffd7595L,0x65fc694f8dedf59cL, + 0xc609503efee92718L,0x57d2592e97d565aeL,0xb761bf157e20862bL } }, + /* 13 << 280 */ + { { 0xa636eeb83a7b10d1L,0x4e1ae352f4a29e73L,0x01704f5fe6bb1ec7L, + 0x75c04f720ef020aeL,0x448d8cee5a31e6a6L,0xe40a9c29208f994bL }, + { 0x69e09a30fd8f9d5dL,0xe6a5f7eb449bab7eL,0xf25bc18a2aa1768bL, + 0x9449e4043c841234L,0x7a3bf43e016a7befL,0xf25803e82a150b60L } }, + /* 14 << 280 */ + { { 0xd443b26582376117L,0xb91087c11a1beb0dL,0x3fe62a6545cc5951L, + 0x49c754bce6e472d5L,0x7e60bb8177c424ebL,0xbcd4088e830cbb97L }, + { 0x3da5c94eba26df7bL,0x508b4f55f72b4338L,0x409c5c7469ad7784L, + 0x82e5f1b0fdf44d6aL,0x10654a1ceed2766fL,0xef1e65faa6e83f4aL } }, + /* 15 << 280 */ + { { 0xe44a2a57b215f9e0L,0x38b34dce19066f0aL,0x8bb91dad40bb1bfbL, + 0x64c9f775e67735fcL,0xde14241788d613cdL,0xc5014ff51901d88dL }, + { 0xa250341df38116b0L,0xf96b9dd49d6cbcb2L,0x15ec6c7276b3fac2L, + 0x88f1952f8124c1e9L,0x6b72f8ea975be4f5L,0x23d288ff061f7530L } }, + /* 16 << 280 */ + { { 0xa6e19d0a5f56dc3cL,0xe387e2690b88326aL,0xef7380950ee527a4L, + 0x78b7174b7c4278a6L,0xc133d867e70798ffL,0x9d0fef759e9230caL }, + { 0x7431eef01a955ab9L,0x3772e7038868d922L,0xf7a4306a8d6af3f7L, + 0x633bb5a0bbec076aL,0x6d07623e7a257ca3L,0xffb5e16521c00663L } }, + /* 17 << 280 */ + { { 0xebfe3e5fafb96ce3L,0x2275edfbb1979537L,0xc37ab9e8c97ba741L, + 0x446e4b1063d7c626L,0xb73e2dced025eb02L,0x1f952b517669eea7L }, + { 0xabdd00f66069a424L,0x1c0f9d9bdc298bfbL,0x831b1fd3eb757b33L, + 0xd7dbe18359d60b32L,0x663d1f369ef094b3L,0x1bd5732e67f7f11aL } }, + /* 18 << 280 */ + { { 0xfab0ce2bee1ae33dL,0x7bf9f90b4c5692e3L,0x131a4374d776d6caL, + 0x6ba40908a2b135afL,0x5c4ab997e1334bf8L,0x9eb442d07af584e9L }, + { 0xd764c506786391c1L,0x07f24c6bbcf6ab3aL,0xf73c7924fad8e1bbL, + 0x79f624acb7583623L,0x2b032021b44c14d3L,0x7cc0ae8dbf58ff99L } }, + /* 19 << 280 */ + { { 0x3c7fb3f5c75d8892L,0x2cff9a0cba68da69L,0x76455e8b60ec740bL, + 0x4b8d67ff167b88f0L,0xedec0c025a4186b1L,0x127c462dbebf35abL }, + { 0x9159c67e049430fcL,0x86b21dd2e7747320L,0x0e0e01520cf27b89L, + 0x705f28f5cd1316b6L,0x76751691beaea8a8L,0x4c73e282360c5b69L } }, + /* 20 << 280 */ + { { 0xe4d7c8b88929c133L,0xe5f96bef92a813c7L,0xdb8ab0af71c18e09L, + 0x0db6ff287dae63b4L,0x54d1fac49a1eaa73L,0xadbcfdf59180c980L }, + { 0xd3220f300b584314L,0xa24e4d1cca3697c7L,0x4ade8c7fa44f8067L, + 0xbd8bc81aca21ac17L,0x303a2f9fc1d361cfL,0x55648b65c71cf031L } }, + /* 21 << 280 */ + { { 0x46bcc0d5fd7b3d74L,0x6f13c20e0dc4f410L,0x98a1af7d72f11cdfL, + 0x6099fd837928881cL,0x66976356371bb94bL,0x673fba7219b945abL }, + { 0xe4d8fa6eaed00700L,0xea2313ec5c71a9f7L,0xf9ed8268f99d4aeaL, + 0xadd8916442ab59c7L,0xb37eb26f3f3a2d45L,0x0b39bd7aa924841eL } }, + /* 22 << 280 */ + { { 0x6f8135c7ce89e8daL,0x21ac20d9d6b5948eL,0x1dc4d48b31cefd7eL, + 0x3d34bc2a4a347926L,0xadcd11be8f614fd6L,0x77148b08a8ea116aL }, + { 0x7afc75fcfce1d3f5L,0xa9e0557d7d9a8ea3L,0x640cb5850cc864ecL, + 0x5811ba842eb332c7L,0xb6c10b6efdb668c4L,0x24d8b10f99f5f6c7L } }, + /* 23 << 280 */ + { { 0xd811eb32e03cdbbbL,0x12055f1d7cc3610eL,0x6b23a1a0a9046e3fL, + 0x4d7121229dd4a749L,0xb0c2aca1b1bf0ac3L,0x71eff575c1b0432fL }, + { 0x6cd814922b44e285L,0x3088bd9cd87e8d20L,0xace218e5f567e8faL, + 0xb3fa0424cf90cbbbL,0xadbda751770734d3L,0xbcd78bad5ad6569aL } }, + /* 24 << 280 */ + { { 0x391fa3cd8d075ec5L,0x54d45020c84c81e5L,0xdead561a79fad87cL, + 0x0ab3c8544e7ffc48L,0x5967f8ebff02706cL,0x8860de795d31ec98L }, + { 0x7476459c6c8a1c25L,0x8d9c484082f16117L,0x5c1b13b33b413429L, + 0x1962a435601b5906L,0x78b9d382e006929dL,0x1924e979e5897b16L } }, + /* 25 << 280 */ + { { 0xcadb31fa7f39641fL,0x3ef3e295825e5562L,0x4893c633f4094c64L, + 0x52f685f18addf432L,0x9fd887ab7fdc9373L,0x47a9ada0e8680e8bL }, + { 0x579313b7f0cd44f6L,0xac4b8668e188ae2eL,0x648f43698fb145bdL, + 0xe0460ab374629e31L,0xc25f28758ff2b05fL,0x4720c2b62d31eaeaL } }, + /* 26 << 280 */ + { { 0xef1001dfbdb22e61L,0x1626bd9af384bbf5L,0x33f42d385fe8ae07L, + 0x59646c42b7218d21L,0x5e27210e6a016f5dL,0x3e9ecf07094481c3L }, + { 0xf91609c1f50cc2dcL,0x8bf8c05ad0d43633L,0x9d508972e74ab746L, + 0xb625887a33f628b7L,0x557bd493e733952fL,0xd35f450b8981dcfbL } }, + /* 27 << 280 */ + { { 0x4603cdf413d48f80L,0x9adb50e2a49725daL,0x8cd3305065df63f0L, + 0x58d8b3bbcd643003L,0x170a4f4ab739826bL,0x857772b51ead0e17L }, + { 0x01b78152e65320f1L,0xa6b4d845b7503fc0L,0x0f5089b93dd50798L, + 0x488f200f5690b6beL,0x220b4adf9e096f36L,0x474d7c9f8ce5bc7cL } }, + /* 28 << 280 */ + { { 0x531c43cdb63f3d28L,0x01289772429708dfL,0xb0ee772ccdb60078L, + 0x4131f5cd5f1a6e72L,0xd9d0f8c6a0da0112L,0x58efddd204e957b1L }, + { 0x18857c0c32840c31L,0x00825340c4068b2cL,0x0a9217a771ff8800L, + 0x69b19e6415530b80L,0xa28e274ee125e3f2L,0xb471a91bc9bfc846L } }, + /* 29 << 280 */ + { { 0xfed8c058c745f8c9L,0xb683179e291262d1L,0x26abd367d15ee88cL, + 0x29e8eed3f60a6249L,0xed6008bb1e02d6e1L,0xd82ecf4ca6b12b8dL }, + { 0x9929d021aae4fa22L,0xbe4def14336a1ab3L,0x529b7e098c80a312L, + 0xb059188dee0eb0ceL,0x1e42979a16deab7fL,0x2411034984ee9477L } }, + /* 30 << 280 */ + { { 0x01d04fe04ce2d199L,0xf434bcfd0517c7ebL,0x82f3aca4a7659a94L, + 0xf436a7781ff015c9L,0xf5143391d6223e5cL,0xba66c6a2ecb5c340L }, + { 0x080f158a4b23a041L,0xb401094cb699acafL,0x1c57626c677491dbL, + 0xfb39e317d42d86dbL,0x19e2ca804f6b3354L,0xe919c4c3c1d41ef3L } }, + /* 31 << 280 */ + { { 0xd65246852be579ccL,0x849316f1c456fdedL,0xc51b7da42d1b67daL, + 0xc25b539e41bc6d6aL,0xe3b7cca3a9bf8bedL,0x813ef18c045c15e4L }, + { 0x5f3789a1697982c4L,0x4c1253698c435566L,0x00a7ae6edc0a92c6L, + 0x1abc929b2f64a053L,0xf4925c4c38666b44L,0xa81044b00f3de7f6L } }, + /* 32 << 280 */ + { { 0x35ae891bbb71e9b0L,0x1f6ce6ca522b77f0L,0xc2dab3cae63745c4L, + 0x55b8c185f218d139L,0x6ab039c889f3b0e2L,0xd9e25bfdc644c3faL }, + { 0xc8496f203e2ed47bL,0xc395ec028d67e17cL,0x5c67839292114918L, + 0xe962e52fef73f345L,0x3818baf354fcfb22L,0x4d75d65d9d4bc911L } }, + /* 33 << 280 */ + { { 0x10078824eb7ff5fdL,0x50c65328735ef75fL,0xdfc04d53ec980ba2L, + 0x4bfb260f2d519cf5L,0x1f03dff15c854667L,0xd1ad2231badb625cL }, + { 0x986064d0be9f7f03L,0xe5ff93e5c13f7d0dL,0x02682a1896e26a17L, + 0xc421567c817ec3cdL,0xb740652352615c25L,0x6800a8335d135eebL } }, + /* 34 << 280 */ + { { 0xde57575b17d8ec5cL,0x72e2257578aeb9bbL,0xce73fa7731605c27L, + 0x2f286b79ae77436cL,0x5e78fbb77f4e6997L,0xb03c888e474f23a7L }, + { 0x4bb302a3e38927ceL,0x39c6de5f6e1514ceL,0x9daa0ad349b2ddbdL, + 0x98fd2377d683dffdL,0xbefa4ae5933476edL,0x4ad53d01173f49edL } }, + /* 35 << 280 */ + { { 0xdfafc70e44b89837L,0xe0104b9c4935fa88L,0x7625d9d92fd702e2L, + 0x27461e6549af2219L,0x4a279383ad3f36edL,0xd87e246b9204e857L }, + { 0x8d832190ab1727d9L,0x59205cd82182e291L,0xb96a1d15a6513613L, + 0x1c7de3cc49cc8ddcL,0x637ea26af17ab785L,0xc098bb7a09a3ba58L } }, + /* 36 << 280 */ + { { 0xfb5383cc31bd4f68L,0x6fd5aee3d96a1899L,0x4e39d6eb01d5430eL, + 0x12679565ca5a2848L,0xa399e83f062b44fbL,0x3ee2432f3c166682L }, + { 0x57229c841de47708L,0x40a5d0cbba528a61L,0x4bae36be8239e7baL, + 0xddac65a2f8087427L,0xfd516d1a3cc61266L,0xc89542b5bcef98b1L } }, + /* 37 << 280 */ + { { 0x3fc8d1b2d49cc0eaL,0xfc591f7f7bca4d23L,0x5f48e27c41fefdf3L, + 0x5ca1d08a1039419dL,0xd450c1bddc8042ceL,0x6760e23fb436fc4bL }, + { 0xc5642797c06bb34bL,0xb787cd53fde06d4dL,0x2926360ccbf144b0L, + 0xb63756f4dce32421L,0x0878deab774abc4aL,0x2d97c7919a4e142aL } }, + /* 38 << 280 */ + { { 0xf58389ff105c818eL,0xfa29f1eb585fa7f0L,0xb6da09b5917e8924L, + 0x1375c3047e7a3f49L,0x9b4792b289cfa1c0L,0x92094a8535571cc7L }, + { 0xf986ccf6051e5e50L,0x55ea34d601df6babL,0xe65989eed1363333L, + 0xd94bbd918c84e20aL,0x9a4f71dc49e39b8aL,0x6d9fe495927d633eL } }, + /* 39 << 280 */ + { { 0x30b295f01fdc29e2L,0x71415daae2c2fab4L,0x205e957683c312beL, + 0x893c69fefab48afcL,0x8108f3f994ca2fdbL,0x37c860c314f99296L }, + { 0x1009a6d2e990ed34L,0xd5350c36ac26b611L,0xd03161102ce23d91L, + 0x82bb476e62189343L,0xe255965160ef0cbdL,0x6bab3f53cf5d2311L } }, + /* 40 << 280 */ + { { 0xcaa3b7a592fa460fL,0x92bb46b804dff174L,0xcd6949b3cf926a1fL, + 0x01f95e5559d1bb18L,0x21f90c08d4518f3cL,0x325dbfe920ee8bf5L }, + { 0xd0136f3feafb919eL,0x941190cc8e0ebcabL,0x599e91a287b557aaL, + 0x7fac4887dcbde1c7L,0x1dad481905a07040L,0x640493978b03d593L } }, + /* 41 << 280 */ + { { 0x65521bb85ebd3685L,0x16c68e79665d1619L,0xd6ab56bbc52b14c8L, + 0x312f1fb4c6d3067dL,0x5afef4f3d50587c0L,0xa3e79e94ace6e2feL }, + { 0x52c7fa0825f12a1eL,0x9c1c1ea20dec9f3dL,0xc418d4232e87a036L, + 0xa0a19fbb0283752fL,0x52e0a8830b804506L,0xc67fc71b3f7de2a1L } }, + /* 42 << 280 */ + { { 0x4d062d3d7dad8ca9L,0xb78c81581cf59756L,0xaccb38f8c6b5d9fcL, + 0x83436d3f7ddc66eaL,0x37115b6033adcb87L,0x49b74bd45a8b09abL }, + { 0x7b8bdb81675ae43bL,0x5284f5b3f0476428L,0x8f1521e7db38b0c7L, + 0x792ef9dea0c4b2f6L,0xa15880a162159fc6L,0x70b999e372b09b63L } }, + /* 43 << 280 */ + { { 0x6f47787d4e8ffde7L,0x19e9434574495a10L,0x8da6d55784f5be33L, + 0x110844811884e325L,0x621734c5a9f030baL,0x25cd0544d0e63f63L }, + { 0xea6729687e936833L,0x08297af784a34442L,0xb77dc3a342f9ed3eL, + 0x9f8908c8258e8d4fL,0xb8281bfc3299ba4bL,0x1f6412920a09849cL } }, + /* 44 << 280 */ + { { 0xd5d51e60ee9a7708L,0x2e8ab3effd2cfe78L,0x0af5c3bac8e71273L, + 0xbfd1b94091041652L,0x4c7c86ab52ce4582L,0x3ab72feff1d9bc29L }, + { 0xae89c3d51e1974b3L,0xd859c7ef70433caeL,0x762064c77edd1398L, + 0xc0b6a6b6072064a4L,0x3ba43b059bb1b3d0L,0x20f9aa85e47d79bbL } }, + /* 45 << 280 */ + { { 0xd1a45415c2d001cfL,0x40f3f05d848a480fL,0x03708da0ce554d5bL, + 0xd7090557c80f4254L,0x7e57d29907743393L,0x7db8a5e10f2f5903L }, + { 0xd0466a0b14e8ff8bL,0xa3c38f49e0cf88b0L,0xde47262e329f71adL, + 0x56b2a7935da6d0a1L,0x22e1f9b880ef44b0L,0xb9b96c617b2b6d4bL } }, + /* 46 << 280 */ + { { 0x3235bc494c500ee1L,0xce0f0b54da4a4f35L,0x628cb91c337ac7b7L, + 0xd8a6d4cd88a26e9dL,0xdcf40cba96e44349L,0x073a0f75b54e3fa9L }, + { 0xc9b95d29ca44e6e8L,0x42ad9afa2315f4beL,0xdf13a5ddf78617c7L, + 0x40aeb346d196504bL,0x9317d6f33d1fef90L,0xf94d308fe1708a79L } }, + /* 47 << 280 */ + { { 0x45bc768608835815L,0x700d93bc5798c507L,0xae3415b85362a822L, + 0xdbce01b33883d21dL,0xb9df7efbe56fb2aeL,0x5ed57d9427d341c0L }, + { 0xdc26916e7ee4dfa0L,0xcdb06a17147c075fL,0x0198b6a7fa9e7a63L, + 0xc9876c786355b62bL,0x9f4b8f12f565279dL,0xa03aeb619cb6ddb6L } }, + /* 48 << 280 */ + { { 0x3a35938779493f3dL,0x128301a91f06a9c0L,0xfcce0f82899d204cL, + 0x4ca41589158780b5L,0xc28f1bb73c4edd4fL,0xe08e48a87a6aec34L }, + { 0x6d4783dfd447c55eL,0xe7c2ecc857803027L,0xb7b8c2bcdf6d7f91L, + 0xf0a8d4700f356ca3L,0x229894bfdeb8e964L,0x555c9d40d3aa70e1L } }, + /* 49 << 280 */ + { { 0xa899a252e0ace851L,0x74b716c9bb9d8476L,0x2ba0bb00571bb175L, + 0xee01a9bf7ac2b619L,0x74f0b6d3502ee575L,0x7fdd7856cc45f810L }, + { 0x68c0beb1c0ae384dL,0x21955de8fe63d58fL,0x1b98e3951c08bbd2L, + 0x5ddaf7e9638701b3L,0xefc264f1b1242d62L,0xa9b8de5c81292443L } }, + /* 50 << 280 */ + { { 0xf0d713b7131a3bf1L,0x690ae8c147e9f09fL,0x1dc92a5f8cd8bf1eL, + 0xdf98927ad61f5445L,0x729b5469ae795eabL,0x939b391c5265675aL }, + { 0x5d916c6c7bd7e97aL,0x7c2a3de5d514e72bL,0x0660758379e9915fL, + 0x0554d5e543a4d2c7L,0x37eb7f82ca5bca41L,0x90e41b71b640109dL } }, + /* 51 << 280 */ + { { 0xfdd403b0e6f769aeL,0xa67f97f6906a7981L,0xc86c49be6aa83c6dL, + 0x6177820677ab6d8fL,0x60f77c49916933b2L,0xfa33c528fcb3fe39L }, + { 0x102ffca0783cb589L,0x6a37a394a96ce10eL,0xd17bf1f89eb4695fL, + 0x2a7623af2a53116eL,0x10601afe83af2e60L,0xceebada2582a1704L } }, + /* 52 << 280 */ + { { 0xcbfb50fa57004c05L,0x0d545f0ea7bea436L,0xb7e30eb77071e269L, + 0x435b3df73b845896L,0x48ba27f0b246365eL,0x9fbe883341344f12L }, + { 0xb763df280a87ef33L,0x4f9339d70b5288beL,0xc02770d6e722e3beL, + 0x6c69bfd918e32f03L,0x20c5c05e74c2845cL,0x09fa0928d6f9279dL } }, + /* 53 << 280 */ + { { 0x82f43866962fccc1L,0x92bc5f82278c9762L,0xc979a68b39a39a08L, + 0xfcae204b97c5a298L,0x78f55c7908676082L,0x210e036447c7b09dL }, + { 0x24512cef47d87769L,0xb4b0fdd7e4b53f4fL,0xc2a263fff6818efdL, + 0xfa160dc1985bc93fL,0x7b7f82961bf44affL,0xd6c75fb2a6407cdfL } }, + /* 54 << 280 */ + { { 0xea0b6ec35741c57bL,0x9b148c2668ba5fd0L,0x6206025166461969L, + 0x0726919f8cfc618eL,0xf66ac684c1954bcbL,0x160ad0260273adb4L }, + { 0x0ec10cffe6f6aac3L,0x232fc7adb4f64d98L,0x0707cb6e73564063L, + 0x76daa2c5487a29acL,0xe4ffd6e335768176L,0x4ab87262464d126eL } }, + /* 55 << 280 */ + { { 0xdbc1d21c553f05efL,0x16e950d0dc115e4cL,0xa727059a354480a5L, + 0x32df221efd6711f1L,0x06f9bc2e5c8aa9fcL,0x9f2449a67b15522cL }, + { 0xac14774bf498ee00L,0x02b5979f3ec7e0a2L,0xdce96e06e1e00abdL, + 0xd7a1bf5a1e00e8a9L,0x19b30fd3a8f42042L,0x29b08eb7e7c507ebL } }, + /* 56 << 280 */ + { { 0xe91477d3a66b2f3aL,0xf50d3bdfc4deb7f5L,0x19bf2857a1e45e44L, + 0x1c104e3270a2126aL,0x4636b4894357b9f5L,0xf65e5aa0962d684aL }, + { 0xfcc83a5fb7b52893L,0x8451d02b08adbd4dL,0xf0fb410c19f7a896L, + 0x6b90b0faff36caeeL,0x111710d0f5af8966L,0x00a4cfafbd2b8c59L } }, + /* 57 << 280 */ + { { 0xad9f11cb817bd227L,0xe4733a1465d27b5fL,0xeda46e8dbcf76526L, + 0x8db309ecad57a5a9L,0x4a863ec07f1487a8L,0xb0453ed210f1c4c1L }, + { 0x9b4df78af2dbfd76L,0x62af38b21525e18cL,0xe6bd0b0ade2c7f65L, + 0xad62bfb70b27fad4L,0xd21fd4346d6a8a5fL,0x07b606703e401a5eL } }, + /* 58 << 280 */ + { { 0xdd14c891e34b192cL,0x6ddfcc793aed3e36L,0xc89c3e6dc49a92e2L, + 0xa61954fd6fcf1ce9L,0x420c39a9bd297157L,0x57c20a8a406d3f2fL }, + { 0x7ccda02263faf545L,0xb01814a96cca4388L,0x88baf1dce5fb1fd0L, + 0x9e1183cfa0bae755L,0x3fe540badbc243c2L,0xe50d52305aeb26a3L } }, + /* 59 << 280 */ + { { 0x10145b3d52726a98L,0x7236036869e333fcL,0xce9a409323a6f608L, + 0x61c121dcddd11095L,0x3349b30a0d39f1daL,0xd07df9d4e3485e93L }, + { 0xb4c500a561159e84L,0xbc74918100561c03L,0x8f27e9f3904ad807L, + 0x7272786a0108ed01L,0xcf36a5d9c9365dd8L,0xe052fc9d7f859d87L } }, + /* 60 << 280 */ + { { 0x0e6cd863da97e11eL,0x5b058c6852a818a1L,0x7768c5e73de760b3L, + 0x898b7f608dfb4142L,0xd48130977efec180L,0xd7196cd758279538L }, + { 0x67c451fb816858a1L,0xbf0e88912ac699b2L,0x21fa74effcb126a5L, + 0x1f9dc10123b8df5aL,0x38aefff921136ffcL,0x3408874c47cb395aL } }, + /* 61 << 280 */ + { { 0xded9035213054567L,0xc61d0628c58c633dL,0x73ff2589f31143c3L, + 0xc43594ff0871b05cL,0xcf662dd64db0edf2L,0x6bac019d8d1f33b0L }, + { 0xcaa37cd8bb379461L,0x9b077a6934fc0269L,0x421e716788ecedf2L, + 0x2d422f95073284cdL,0x9a353114bbb2409cL,0x99e8c7a0dcbb79e7L } }, + /* 62 << 280 */ + { { 0xfca254cba21c40f0L,0x4945c838e0f4a032L,0x99318ff3fd6cb7fdL, + 0xc631e0644a85e726L,0x2e3ca11d9359e8cfL,0x433a0e5c06acf935L }, + { 0x665c54c996b37ea9L,0xe78865c4c2d52b81L,0x68596f6ffb27850aL, + 0x7e7272221277995eL,0x602b0f5c197344c2L,0x81ff2ad620a9ec11L } }, + /* 63 << 280 */ + { { 0xb2ce6cbe7c4c464fL,0xd7c11ef5741a4b1fL,0xf3f987f621a7eb17L, + 0x6b2812ef79f4e274L,0x3a0117ae38a7d5ddL,0x5d8c75a9cfab6bb5L }, + { 0x3827c04052394166L,0x897eb181e00e621dL,0x6693817f8aa19361L, + 0x67cac329959d81a8L,0x21e7133869a7ca51L,0xa02fd11269a46a87L } }, + /* 64 << 280 */ + { { 0x7f1f985c022ea83aL,0x90a22662a7584e7fL,0xb40a930a5188fcf6L, + 0x3fad79aba3a82904L,0x7bee8d22f3151027L,0x79a1a838c2c3e17bL }, + { 0x1fbe06e933cc3509L,0x629c56aa9abd5ccaL,0xfff290ec2d9cf7a5L, + 0x5d0dedaa9bd062c5L,0x080344abd7d35381L,0x0848373af5cf9edaL } }, + /* 0 << 287 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 287 */ + { { 0x31d31f7a7a0c0bc0L,0x7a37a84ab251d2bfL,0x1793362e52f04d67L, + 0x5808e70921c7b651L,0x33fe9123ed6f47f6L,0xdeb1dde958f71405L }, + { 0x821d3045ae56b472L,0x9f61f761e02043adL,0x932ddb145b2048a9L, + 0x17d989fed7811330L,0x032ae4cb128fd85fL,0x8f1956b47d1ef434L } }, + /* 2 << 287 */ + { { 0x070d34e116973cf4L,0x20aee08b7e4f34f7L,0x269af9b95eb8ad29L, + 0xdde0a036a6a45ddaL,0xa18b528e63df41e0L,0x03cc71b2a260df2aL }, + { 0x24a6770aa06b1dd7L,0x5bfa9c119d2675d3L,0x73c1e2a196844432L, + 0x3660558d131a6cf0L,0xb0289c832ee79454L,0xa6aefb01c6d8ddcdL } }, + /* 3 << 287 */ + { { 0xe5d473dc7521f457L,0xe9ef09bda00be577L,0xf6d0965fb6eaa640L, + 0xeb49486875726560L,0x452116d528817302L,0xf0424fdbfbde3597L }, + { 0xd6096da3bb454915L,0xde48280841422141L,0x7a1351972d19fac0L, + 0xdc9a5ec421393f6fL,0xcabcc1e3eb2c8adaL,0xd436643142d8c4f2L } }, + /* 4 << 287 */ + { { 0x0ed1082f89e4e449L,0xdb1fb471833f2378L,0xa35fef0eece77352L, + 0x76adaa464bf0c426L,0xfbab929aa011b2fbL,0x6f475d5b9d8cc4d3L }, + { 0xbe6d7f2174351480L,0x2d1362d193e4a7aeL,0xc7e2cba5106ceaabL, + 0xfe94528a45258697L,0x7109b17d075945b0L,0xfd395b2ccae17f7aL } }, + /* 5 << 287 */ + { { 0xdf534b80dece6d4dL,0xcfaa60a28737af46L,0x7d76a921b9ba3d56L, + 0x61490bd199338721L,0xc514e950ed25cfbdL,0x5041fbb2dc09b8b1L }, + { 0x2410310d46fbcbf0L,0x2c46bcd14f7e8aa4L,0x08ce31f5d0d5fe1dL, + 0xb11efdbebeac3c97L,0x406e1d05b01633e9L,0xde48cdba766391adL } }, + /* 6 << 287 */ + { { 0x68550299845e12c9L,0x979b5406361d027fL,0xf601d2b4a8e92e70L, + 0xfd02799f0cc9fca9L,0x89f99ca013bc2e96L,0x22a12c0bff9db9b8L }, + { 0x6ae7084a32efcea8L,0x5ddd3ee9a24b9376L,0x394d92a4e0945e8fL, + 0xddab6752ecea36f6L,0x650b74d60d18a069L,0x37f91cebad650860L } }, + /* 7 << 287 */ + { { 0xe3e559bd9d839b3aL,0x50e8d4e9719de3c7L,0xf7bb377cea70b986L, + 0x63753cace1b2707dL,0xeb239a870e585c4aL,0xec40a379b0e32380L }, + { 0x836ebcefc86d6685L,0x703c296a70d18b76L,0x47e2c004b94aa268L, + 0x33ef7d0cbaf14d61L,0x74aa00fcd315c72cL,0xf23c789eccf5d75aL } }, + /* 8 << 287 */ + { { 0xfc1faedc310404a8L,0xea339148d3bcb128L,0xf00485456416defdL, + 0x75de7770c58653e7L,0xdd2dcbebe2f6f99eL,0xa4380ef4d159ac07L }, + { 0x45dd713ce4173608L,0x44919b61446a6789L,0x3f73756b6b962b38L, + 0x3cb9f53bbffd3f0cL,0xd723c40b7f08ebaeL,0x998a9b170c3cddbaL } }, + /* 9 << 287 */ + { { 0x261c9fe6f21ae889L,0xa589147edf3cb243L,0xd09452f71976deecL, + 0xf80ee8bf2497f6b2L,0x0b5f1b19eee697d4L,0xce9b6b680de48ab7L }, + { 0x3ad3bbc4bbf29546L,0x544406a697f51becL,0x51d44dfac2e2e75cL, + 0xcfc8625d3da3f634L,0x0845ace6a1f5995dL,0x11850d8bf3b65c55L } }, + /* 10 << 287 */ + { { 0xa804b2f089ef2489L,0x06a2a805fb22f7d6L,0x31baf4fd353970beL, + 0x3481c8b712854a91L,0xb0424eecf3971398L,0x748ef3820f4ed94aL }, + { 0x92b74ad026722164L,0x23f71d5831b1302fL,0x6741b28070a5f0c9L, + 0x46c12cfb9f5101caL,0xe7014d7901d0f81eL,0x129bd87ad758c288L } }, + /* 11 << 287 */ + { { 0x6c43d8307b00cd09L,0xb794cb012141eb00L,0x95fe13a75cf23ec5L, + 0x3de5ad7b8f2c799eL,0xa378434a025de83bL,0x07f681bba3a14a3cL }, + { 0x8fa0b5d2983ba419L,0xe477bf361781bf08L,0x5b8162845e8ce6bdL, + 0xb36a78ee199ec8eeL,0x444fc01a6062d5d1L,0xc026ab4586ee9ac2L } }, + /* 12 << 287 */ + { { 0x6a565269a3e0c5b3L,0xaab7ec7104c6ae54L,0x0bda11a7d8c6ddb8L, + 0xb7ebfafb2332347bL,0xcf791881e99dff48L,0x81600214dc357c83L }, + { 0x2a264f8931d7495bL,0x8ca430004ec885a7L,0x6d478260bb47d417L, + 0x544de4ec3d817032L,0xac7150a9dc05f901L,0xffef225775c0963cL } }, + /* 13 << 287 */ + { { 0xacb83aadb65296f8L,0x04c96c3e18151422L,0x8913311e7a9f126aL, + 0x3baeaf8010b74e8aL,0x253c9dcbb7410105L,0x30a13e42da2d5437L }, + { 0xde31fd5533a2065eL,0xde2caf1ffe099595L,0x54c762fe795076b5L, + 0x8beb51fe635ed402L,0x369603c1e5c3d2a6L,0xc5083f0700a472b5L } }, + /* 14 << 287 */ + { { 0x58805ca8d2eaf294L,0x910d085ed7d5abb8L,0xf9cbc9a1349cfecfL, + 0x67bc7b417800a980L,0xe7e6dbc0f6847e9dL,0x7a0f22c4af379c48L }, + { 0x80b6fc04b1d2822fL,0xa1cae656d8517a70L,0xd2d11ed14e9dc24bL, + 0x48d74f173fab87e6L,0x1feca5af50c630aeL,0x263e04cc62d0620aL } }, + /* 15 << 287 */ + { { 0x7dd330ca16b2a52aL,0x25133c614157ae5bL,0xe6ee0e4edd606b2fL, + 0x700840423f2b59a7L,0x58d27587d03f54eaL,0x62ebc668d34605e9L }, + { 0xa764392ab3155e07L,0xf0810f3e3c6ae6c8L,0x1b32e5ae94614cd4L, + 0x45b49262b9cbf481L,0x0034db795b3d1184L,0x463237825b1b9ab9L } }, + /* 16 << 287 */ + { { 0xf6377e3bf6ba1469L,0xc334fb6c09c832d3L,0x7f85ac42c21c0cf1L, + 0x7a3e31c9857d8edbL,0x2eb1076327b77ed6L,0x2bfbbdbc38dae10bL }, + { 0xed7c6fb17bae3b4fL,0xc5911d9f36d04e6fL,0x4dc435504569e72fL, + 0xaa82fb97bedae3abL,0x06d37bef4f27e463L,0xd0dbce6df0c35a11L } }, + /* 17 << 287 */ + { { 0x4482c7b704414726L,0x72c9cb5b26d23eabL,0x3747b8cefd5cb171L, + 0xe4ecabc300312ffaL,0x5909f29b9cf10a38L,0x209bc3f4b8d0e5acL }, + { 0xd34c84db60fac147L,0xd64dea89f8938c89L,0xb18285f8b815267cL, + 0x719a7e355a2437d1L,0x45f8d9dab769c5a2L,0x2d0e4281a412cfccL } }, + /* 18 << 287 */ + { { 0x23c14c43d8f6e236L,0xb14be0d28ee39386L,0xd3c55814262dd390L, + 0xa1b40401e1f23d0bL,0x1377b07c61534375L,0xfe4e3eb116f6d95eL }, + { 0x17b1af0040b4386cL,0x2dc657a837ca3851L,0x6862ca92ef976731L, + 0x9f0c380ba4118d3bL,0x23bf793977c1aa94L,0xaadee0612bc27d4bL } }, + /* 19 << 287 */ + { { 0xfa5e4cb6f1847a9aL,0x0e13a60cba6f07f1L,0x68d9db450ac86498L, + 0x44b02de3920ff013L,0x43724c2d84b46078L,0xb3686ee81f951b93L }, + { 0x019b3e77d712fe85L,0x313e7b7497dfb295L,0x7d883ed826d50e37L, + 0x64815565d32562ddL,0x2f9e48bed7b3e2f2L,0xc97cf156dcb93450L } }, + /* 20 << 287 */ + { { 0x0573d9963ab4c707L,0xee5d87691420fdf1L,0x41873aa55e2b9c12L, + 0xe09290456810bf08L,0x4ff4143fccbe4bbfL,0xd0e5a74969328301L }, + { 0xab5912621c4b73beL,0x550ea0633f3edf99L,0x8a77633734c93db1L, + 0x5c51d3f832b21521L,0xcee9f604713feea0L,0x0d6f8a5a7bf4268eL } }, + /* 21 << 287 */ + { { 0xc415d467009a0cffL,0x32dd46ef55960242L,0x4ccc6f676d6a81b0L, + 0xa860bcb6b2571d81L,0x7e74150991f9b6c9L,0x9a96b2f9d3a0592aL }, + { 0xcc3d821071248929L,0x586062daf1cb0f52L,0x18d993483d48b6c1L, + 0x667f17949f4e612aL,0xf1d7a77ffb3a12e9L,0xf7586397f5753220L } }, + /* 22 << 287 */ + { { 0xb87d5ce2722f405fL,0x24d1f993d7c6a322L,0x09d837291e0d8113L, + 0x70b5cdbf89a6cbc3L,0xdfb3ee16fb2c9607L,0xf0acc1163465c7c6L }, + { 0x10cef4b707e6659bL,0xc280c4331fde9940L,0xc8b5e9819a2d3f25L, + 0xc36faa763f7f68c1L,0x17878bfa8d54e281L,0x8fda8b359c42c5a2L } }, + /* 23 << 287 */ + { { 0x2aa1366305d22d7dL,0xee77da6eb0c62a12L,0xff8f99c5bacad876L, + 0xcbe33479f8a0f0baL,0x4c69bd7f4a232c8aL,0x760ce3fd485d3f48L }, + { 0x0b286a59268d7411L,0x2dd746b6589819b9L,0xe017a53060ce76f2L, + 0xe4407828d642a7f0L,0x12761e51b6badaecL,0x4f4f286b78d07257L } }, + /* 24 << 287 */ + { { 0x43c78835661019ecL,0x68e916b124e66d29L,0x02c0f3a224094671L, + 0xab6f1c05d0f17d86L,0x6d3bac72a22d4264L,0xd7b8f152f6e5fafeL }, + { 0x95627c6339447eb3L,0xfd15901879e1ff93L,0x39277c835ad80806L, + 0x758aafc90d7c7b74L,0x605ad8ca4cb8bec9L,0x6a90085c5741828aL } }, + /* 25 << 287 */ + { { 0xbc11d3d559cdebfeL,0x75c31b4531b2796eL,0x8d11e18a07b1055eL, + 0xcf522c1fb2d2986dL,0xc994c377eafcbec6L,0x840d27ebc0c0e2f0L }, + { 0xd4124d17859550d3L,0xeea6047aba21b2b6L,0xbd2a036e335a2854L, + 0xd8703d6b207ac2e5L,0x09d2244a94a34bbbL,0xd6b9481417ec6f44L } }, + /* 26 << 287 */ + { { 0x7d8ddca252aa7ff2L,0x0985e47d6953b9a2L,0xed328993dfff63ccL, + 0xbfeca5327cfa6ee5L,0x7535a871b1e6a010L,0xb0052764303c2ec5L }, + { 0xd39c72102fedb0daL,0x7ee2b384e1001505L,0xb638a1b1c82a7e1cL, + 0x1b94a47b4573fd7dL,0xef2bca7792cb2b88L,0x49ad6e97a75b21efL } }, + /* 27 << 287 */ + { { 0x591bdd0d8f4093abL,0xa2c63f1ba1322343L,0x5e548f71b32a4331L, + 0x9930891c5e7f3c14L,0xb2b2406e54c27043L,0x7ffe3e5ef1281af8L }, + { 0xc31ba363900742d1L,0xf24c8ae1e61ee209L,0x687c56b7beed46f4L, + 0x0b63e47895682562L,0x9117cf4c0c8a45a8L,0x0744a86824c20748L } }, + /* 28 << 287 */ + { { 0x9ac777993acb39ddL,0xd1d3ecddbb7c6a8aL,0xa5271c9e7a75159cL, + 0xa6ffb41f2c276e4dL,0xc526556e0bb9a955L,0xa32e1352233b7774L }, + { 0x103f124bc2cf09aaL,0x1816d1eff10bae5aL,0xc5f9197ee8837629L, + 0x064d5dcb13b1b76bL,0x109c70748d0fe0b1L,0xbb4e9743fce5f6e1L } }, + /* 29 << 287 */ + { { 0x4636f36d3ef05af6L,0x3695267b3e498920L,0xd59830285d773fc8L, + 0x939591245d3cc515L,0xc3f52a9569134370L,0xc9d0db7af8848992L }, + { 0xcd1be9bf15906eeeL,0xa95d25fb916d576fL,0x08de893be152fb62L, + 0x65d743658ab1e35cL,0xd6d97057fef14ac1L,0x67ad47b9574508c7L } }, + /* 30 << 287 */ + { { 0x1b403c4f1470433eL,0x6f8cb19257e53eecL,0x87b5b93df0cce4f5L, + 0xfefaa5008c566f77L,0xf6aa8066db71517bL,0x9f01b036d67f5952L }, + { 0x9524306faaeb40dfL,0x5cb2e8e1421350a6L,0xa57d05ea3d69040cL, + 0xd0ff12a1b9bbdcd8L,0xed64d3259e3e19bbL,0x29509c0fed0a490dL } }, + /* 31 << 287 */ + { { 0xc94191e7a607c050L,0xb918a096b98d3d4eL,0x97413dbce3f253f3L, + 0x8476c03cdc6d8418L,0x50247d1d2402202dL,0x077476225f8097c5L }, + { 0x1457ab609b71c6d6L,0x9ff312c447cf0c94L,0x954dce23ee79d2bcL, + 0x3ba2b1a4a0da6e48L,0x363df36f532be9f6L,0x816642ddc742c7d4L } }, + /* 32 << 287 */ + { { 0x6edf5561ff8b1fbeL,0x614b788ef6eac0c0L,0x7699ae56d8d66d29L, + 0x5f81602ae9d58eb2L,0xd0c04874faf9176dL,0x4b3a0046523153b1L }, + { 0x9690930ff6315883L,0xa81c0b44a60ca92dL,0x2d0e725873bcba90L, + 0x57efe72de902e329L,0x3fcd598676bc27b9L,0x492adf0393940c09L } }, + /* 33 << 287 */ + { { 0xf2ab8e22973a4b6bL,0x6a96f2ef6ad73ce7L,0xad5e22547235e929L, + 0xfab3e4a9bc6c3b76L,0xf69fb2062dc950d0L,0xd863ca9049478ff2L }, + { 0xec669f122749fabbL,0xe1d28bdc71a6d279L,0x766ee6458372942dL, + 0xd118b90480ade5ccL,0xedcfb0a72293740bL,0xa3ee3a67f16b29cbL } }, + /* 34 << 287 */ + { { 0xc29fb53e118a0c7dL,0xea7a1017193b834cL,0x678072a2cec93ecbL, + 0x9054d6b72475dedfL,0x4a7d477342ee616cL,0x05cec7f8680f8a43L }, + { 0x39c491d496915870L,0xe07a2b1d8746edeeL,0x1d8ed3c83566e7fcL, + 0xc7d744e5e002298bL,0x8a0acec99c0e6388L,0xb2daac39ebf48fe3L } }, + /* 35 << 287 */ + { { 0x773ad1cb8e133d97L,0x1e29f5a2872523d3L,0xa2a742293a09c1ffL, + 0x809e6d284369ca06L,0xf22e521a7fe148caL,0xbaaf90c383ef9578L }, + { 0x65aa9b54d633b2d5L,0xe55f2ce29a2994a8L,0x8a0af446e67e0b85L, + 0xb9714de9c1f062c8L,0x1f4047dd2a3aa1d7L,0x39658ea965179222L } }, + /* 36 << 287 */ + { { 0x0322b29a57fbc5cfL,0xf55af7863078be9cL,0xd4b186e6ecb59f79L, + 0x50f5fe746d950733L,0xaf8a1898a9f90d02L,0x483801a742d6d9bfL }, + { 0xf0a0af145ec09c0eL,0x85af0e6188383360L,0x404b295e42592235L, + 0xb3199d63c596493cL,0x7aadacdb194abb80L,0xac84563ec1c845c6L } }, + /* 37 << 287 */ + { { 0xd78d1dae5336e58dL,0xa3f36e0bc5ff354fL,0x8421f95e5d1ed78cL, + 0xff4c16019f360c43L,0xd5efa09f8bb582a1L,0x0ece005aefb39652L }, + { 0xce8bb58036c2c940L,0x11f8f74bcd1ae8ccL,0x923c350b57a2f2b3L, + 0x2438e3213c86faacL,0xe76129503e230776L,0x35c73d415e6158e2L } }, + /* 38 << 287 */ + { { 0x8ffda4643672507aL,0x76301be7dd91327aL,0x42720bb0958860bfL, + 0xedc0b8945ad4f455L,0x2fb553201bfbeb4dL,0x22a425bda1c6494dL }, + { 0xfb927a85de0e7f52L,0xb84a82cf49a4b6a1L,0x8afd0546b640fe0fL, + 0x23b78fbed2fc15cbL,0xeab469c26742a49fL,0x308e453fe277c7cdL } }, + /* 39 << 287 */ + { { 0x60ce0f55af7b14aaL,0xf2577fbe5cf5a2caL,0x7bb9521fabf3bb41L, + 0x68b6409def00287aL,0x700bf423bfaf9391L,0x98e6c3017d637300L }, + { 0x342ed4870ce28aeeL,0xad8b8dc383b059dbL,0x1b8a892b85d0a485L, + 0x553c4fad6b7a7d3aL,0xf5692acc198d0379L,0x6004ebb3ce932f00L } }, + /* 40 << 287 */ + { { 0x6895dbe2f820c195L,0x3787a5003f6c7b40L,0xdc718243ac1e90f3L, + 0x352f8c91ba5d0870L,0xf3d1c53eec0112b5L,0x08a0782f6b84f64aL }, + { 0xd659e6358eedd5d4L,0xfc30df6c29537276L,0xbfb09978a1755ce0L, + 0x227f7b12aa2b4187L,0x828730b9226539d2L,0x9051a37cb2472c95L } }, + /* 41 << 287 */ + { { 0x430c2a45d0a0ddabL,0x916aa68926a6291fL,0x9db5510268dff24fL, + 0xa22121c1850a7aabL,0xd43416194e2d9670L,0x7ef2cb9415cf7636L }, + { 0x2cd6ddf6bf97b27dL,0xac5676b625aba9c0L,0x3ca96f7ec4ee110fL, + 0xc6900abd08e7ebb4L,0xcd3942fbdcb91135L,0x62d6b6f6a8ad56e2L } }, + /* 42 << 287 */ + { { 0x1ec7f2410828d35fL,0xd94c2a926ccae554L,0xdf4227273c36ecedL, + 0x2facd6d89fa6582bL,0xed43247ed349d3beL,0x1d59d55d1db6fcc6L }, + { 0x2b5074b1ee1bea38L,0x025496aac9c21a8fL,0x57dd7fa1d1d817edL, + 0x57b5572aead03124L,0xdc024be87314616dL,0x5bb5b23c10f6e38eL } }, + /* 43 << 287 */ + { { 0x643cb9cd53812134L,0x016a11e8092ff9b5L,0x227f3dfbfcde37bfL, + 0x01b9bcebe8a8fc6dL,0x7009ae45e1da0dd6L,0x193b6f519e2908f3L }, + { 0x28656302230db5feL,0xb0a730c41aaeee73L,0x028320ab387addc8L, + 0x92165d909a92488cL,0xb0b2f8f09066c95cL,0x0fa55db564007634L } }, + /* 44 << 287 */ + { { 0xbff4fe0844284b10L,0xc7e3f8da19c2f775L,0xdcd97e54a45ab746L, + 0xf53158a9540ee8a5L,0xfd19068728c4aa74L,0xa3447e30648fa2e1L }, + { 0xa6794670c374cedcL,0x605629c258204248L,0x1b86f8e6f7d8db3dL, + 0x1e8ffe8bff0f38c9L,0xe4a556b8e274c82bL,0xb31406c94c0076d6L } }, + /* 45 << 287 */ + { { 0x198999821e555a0cL,0x831e923fbc196442L,0x8b294623f682e135L, + 0x79ba90c01743c6e1L,0x74f8dbafeff5ed22L,0xe4c3257d5c010835L }, + { 0x9cf94a208f9ec66bL,0x9fe9da3ddc303c43L,0xa53870be0cb716daL, + 0xc322ffaa2aef881dL,0xb9ff76ff0fcd5580L,0xdcc125d49ebb1d7dL } }, + /* 46 << 287 */ + { { 0x747b6b6ddecaf88eL,0x1a32f8ba368cc7caL,0x52a3a00f60d84fd7L, + 0x60052af507adacf7L,0x8b7bf25650b8de16L,0xb8b2acf8194926baL }, + { 0x4bda72c81d1ef524L,0xe350f73288993f96L,0x63fee4e2e08c5d39L, + 0x1f2cd9cd5db46904L,0xbf11ac311668d3bcL,0x8eaa064371d721aeL } }, + /* 47 << 287 */ + { { 0x33cfdcb3e14210feL,0x4abad5ec4946aa01L,0x14b42417a8cb53b3L, + 0xeebb0d70238d4edfL,0x8c9d87fdb5bdb30bL,0x3cc680f17c928b33L }, + { 0x4b2b2358757c2607L,0x51a70a33c1c8dedfL,0x62a26d776b22d113L, + 0x2f4acd62ef3b4f5eL,0x403e91bf6ed00636L,0x219ba3577bf74d3cL } }, + /* 48 << 287 */ + { { 0x7de743e2b39317b8L,0x9205d4472d372acfL,0x8226fc303eeb0012L, + 0xab2a3e052af74be6L,0xbe4767804af91ac0L,0x98497c710ca36bf4L }, + { 0x74fdf7cd8d6dedb4L,0xb50778eea0fc5919L,0x5d5ec33f2fcd7c63L, + 0x667b81937f33cde0L,0xce48ae4b38364d44L,0xb8578963223ed67eL } }, + /* 49 << 287 */ + { { 0x3e5688e46bfd7adeL,0xb3f1eb051b80bd4bL,0x8626c4cafe3de456L, + 0x8846bc714b7e5444L,0xa54c7cff689e8a67L,0x8c3ea61f43eadcf6L }, + { 0x924f17d6fde15178L,0x45319eb705c08d2dL,0x6d55775d9f85dcbcL, + 0x2aaf9f7405278280L,0x574a13e77b617153L,0xe7fa921ae8b15bebL } }, + /* 50 << 287 */ + { { 0x9dd54056514e343aL,0x8d9116dff12aa25fL,0x5322ec38e3397844L, + 0xe1843921571036a1L,0x2cde0a48650beb19L,0x41ad4a7e4f259728L }, + { 0xf314fceeee6448b2L,0x80006b2aff0e81f5L,0xb5ee5524d51d229aL, + 0xeba6d733128e900bL,0x79278cb8030f391aL,0xb24bcd63a9a5f9fbL } }, + /* 51 << 287 */ + { { 0xed867a7b37d10743L,0xd57d2d8df510023eL,0x4d500e4c737e0a50L, + 0xcfa119900ecbf795L,0x3ac126b89373bdaaL,0xb06324fb735449a1L }, + { 0xfe321df5cd79de70L,0x52d625dbfd07c6d4L,0x88ff505a3d628e51L, + 0x120350fab044d725L,0xf718b20ad02f9515L,0x766698630bbea1b2L } }, + /* 52 << 287 */ + { { 0x6293e0ff50d9bda1L,0xe7259ada433b4dd3L,0x39aee63e821cee67L, + 0x4d707c7144b10739L,0x42b9e0f69bd6efc3L,0x7d71edcc0717a61dL }, + { 0xe7df9e56d1e5a5bcL,0x7895b638ddde509bL,0x6fc597b3d2a6a822L, + 0x022da65d96d2a8abL,0x95541ce7cff45c72L,0xa5bb7799e649800fL } }, + /* 53 << 287 */ + { { 0x7472e4c963676cd5L,0x2836b1d52687f376L,0x1460b664f732a51aL, + 0x7c4541f22a214ae1L,0x743a524d107d6622L,0x9c64e3ff082fc015L }, + { 0x9341f3fc8e0d13bdL,0x9946043e529554edL,0x6fbbbcda5798d6ccL, + 0x3bfad5fb242115c5L,0x1f46bd1945ab793cL,0xd9383bcf3b42f81aL } }, + /* 54 << 287 */ + { { 0xe4ff888f820a13b5L,0x7cd18b3eaf1bfbbbL,0x3fb7f681bd4e4dd5L, + 0xaba364c287d46c40L,0x44e209ab659b3498L,0x5e071a272dde85c1L }, + { 0x8a029b1fb969c790L,0x51bab9f0c6fd1c22L,0x9ee9b047b83eb0c1L, + 0xda0b39439e5b2c35L,0x0cb30625f20ca425L,0x8e4dbd013d25c2c9L } }, + /* 55 << 287 */ + { { 0xe7aa41a96b8f7599L,0xe97ff24a3f556ad5L,0x10e07713dd6a9329L, + 0xaf464b18c4d06a93L,0x9b8e5145a1ccc85fL,0xa256680bd0487ca6L }, + { 0x420b60bf815652f1L,0xeaf09eff5bb45b6fL,0xa31e875f8845a557L, + 0xb035ee09eebe0911L,0x1402d1d86531c356L,0x24aeeaf0b630f75aL } }, + /* 56 << 287 */ + { { 0x4b20d1829567f5f4L,0xde7e814918f02b34L,0xc9a4be7becff9dd7L, + 0xe2f70bbe9812fd3fL,0x471bf90c9c889263L,0xb60d01b53e61f5bfL }, + { 0x258c7f89d22d855bL,0x35ef5c15b75a7d4fL,0x26d8e1dab247f27dL, + 0xcf1361998d0f7757L,0x312447803f8e894dL,0x8d2a20bae1a3d47dL } }, + /* 57 << 287 */ + { { 0x6447cc97f08a0417L,0xd98ea6837afee809L,0x81426d20bf7990aaL, + 0x848bd6223526ad26L,0xb6cdc5b4fe1f3381L,0xe7e10bc7a26189ecL }, + { 0x25a9f7cf57464e6bL,0xf90c1aa12c86ddf0L,0x2126ed530124705fL, + 0xf384e7e5b58e6341L,0xb2dfeb0a12207e57L,0x72875c55e0e23287L } }, + /* 58 << 287 */ + { { 0x37579c3eb954b7a4L,0xf0291f8f3f2ea608L,0xde68104f90a85ed2L, + 0x6a35fea9e1088788L,0xe8d5517470d15d00L,0x0bc72de552467f90L }, + { 0x2ded3293297be2b8L,0x76c53e5761ddc65bL,0xae4b2b5015562d6aL, + 0xfe7cdd329e0aeb79L,0x98ef4c518dd474ecL,0xfca56ffb0076b23aL } }, + /* 59 << 287 */ + { { 0x120adcba6f60309aL,0x41e46edeca8ab2c7L,0xd68aa4c529b79ce0L, + 0x21a21f8d7a3b11fdL,0xea68dc4739d0809fL,0xd4faa71a27973044L }, + { 0x65b42172810be134L,0xb2dafa6c793aee92L,0x951e9f6f1f78f7dcL, + 0x2affc70a17fdba97L,0x4f0f4c51dcaa2789L,0xfde1951c9e703980L } }, + /* 60 << 287 */ + { { 0x80826a196488d9d8L,0xfa452795f3ad867aL,0xdd9bf8f5bd4e6674L, + 0x324386227e8e3ee5L,0x7af4c605dff05c96L,0x79efb6f9541cbbd2L }, + { 0xeb5ff62675e78961L,0x5318c4c30be43d7aL,0x02df456daa4a0562L, + 0x4d6002d88a916a81L,0xf0dbc349f68eced2L,0xfd75d4d5ec8c3fddL } }, + /* 61 << 287 */ + { { 0x6c15d903544378f3L,0x0a9bc9d735ea3c77L,0x9d9066408caa4acbL, + 0x9ba27502402be833L,0x1ed4123f8773fd7bL,0x236364ba190eac92L }, + { 0xd6287f17f8383ee1L,0x75b7b0b5d9739582L,0xeb6cd50d0292806eL, + 0x216f36dc43448409L,0xec136f8cb6c4958aL,0xfa805ab49ef7810eL } }, + /* 62 << 287 */ + { { 0x5c6448f70d00b29aL,0xaa134b87124cd55dL,0xc2c6b269d94b72d9L, + 0x0f0dd472412f76d8L,0xb4cf3c1873f6571aL,0x6aed00218b9218ffL }, + { 0xa55b74eaa0c9dde9L,0x59b952125b4c8fccL,0xbc9873ea4ddc367bL, + 0x26b369ba0fd30421L,0x71763a45e446f4fcL,0x67e800edaff54707L } }, + /* 63 << 287 */ + { { 0x4de97de1126b4919L,0xd631d908883ea109L,0x37c77d729f6ec50cL, + 0x910932e6df718c7dL,0xa798406855028d0fL,0x21b09540a6119a26L }, + { 0xb837cceced4b4962L,0x3c83f4bdba66002aL,0xa067aa3d2ac41124L, + 0xa64bff30d08dc360L,0xa22778a5c108d3abL,0x7f732064aac4dee4L } }, + /* 64 << 287 */ + { { 0xc68b641ec795a2c7L,0x4fe559b15a4d6647L,0xeda98cbad89ce668L, + 0x15f84dc06c269d8eL,0xf0eb685ecbf34023L,0x3668c530c032634aL }, + { 0x2e3d7fffe4531f59L,0xe627030685494d06L,0xf02cabcfa3e050dfL, + 0xccd2da67c001dcd9L,0x50aa3723066d2d52L,0xdb0756507224a41fL } }, + /* 0 << 294 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 294 */ + { { 0x04418b5965b55050L,0xa8a797c3d324aa67L,0x5f87e22c7c65a6d9L, + 0xaac710651dbeffe4L,0xff619d64bd3cc05cL,0x9a29c966e65c92c4L }, + { 0x23af2b21dad7fcbdL,0x4950a767153b817fL,0xc34a7efac6478c55L, + 0x57cde95af6cd140eL,0x64b74575f5a0db2eL,0xd4b5ea5275d7fb76L } }, + /* 2 << 294 */ + { { 0x284050628e72aafbL,0x655bf3538ea8bf00L,0x789d944405547f7bL, + 0x7fa445ed3441e472L,0xfeb198254a44ce87L,0xccb5f12c129aed14L }, + { 0x22b05de3af94fb34L,0x7422a040d3f03199L,0xfba252caa83f7f08L, + 0x0f6ad6e6cefaa757L,0xe1ad18716517d806L,0xd16dc8ed8e9d97adL } }, + /* 3 << 294 */ + { { 0x0208092a0e3dca68L,0x9a49bdccd1a09971L,0xe5194181aefab9c1L, + 0xc1c9690a0076f47cL,0xd7499e95b486c2fbL,0x83a69e43d4b72e00L }, + { 0x75f2838a2d1a6c2bL,0x57a24c69751f6366L,0xd956ee08626cc684L, + 0x434cadd7e6ce3249L,0x3d4eaececfe289bfL,0xbbd53b961b8aafddL } }, + /* 4 << 294 */ + { { 0xcbb99194a3736eb6L,0xdd5161cd36dcf470L,0xd50b24aab6ab6c03L, + 0x419d2810bc41f4b7L,0xe2e88d7a295496cfL,0x350713f2f2457ac0L }, + { 0x838e4a360427e2aeL,0x7631472a4d974e5aL,0x9fa3ab1c7a5c5fdcL, + 0x324798cdde34cb8dL,0xbfa5a9d0889105feL,0xd05dad34fd0df249L } }, + /* 5 << 294 */ + { { 0xb47c1d47d6a3a1baL,0x99bb7e6572f65bd5L,0xf251794578abfda2L, + 0x827f2aba3e3e3420L,0x436ee73250e2de70L,0x5c9ac6dc10eca926L }, + { 0x2ec67465181f5e18L,0x1e8f32fcc6c83d02L,0x9dd3aeaf3953bd81L, + 0xca955f4b07086daaL,0x7b4b6f3fd14eaa88L,0x562e75f1148d826fL } }, + /* 6 << 294 */ + { { 0x536e5657cb419fc3L,0xe8c208bc1d271dd1L,0x6a3713bd22d2b9adL, + 0xa4c761a7471d808dL,0xd93aafb67e6dca35L,0xc46c0ae38f55ca32L }, + { 0x55dc0de7a78bfca0L,0xe9cfb3013407d0caL,0x777e2a60b3256c14L, + 0x32b2238c6d8fee02L,0xe8b3539646e43ee8L,0x310bc1ba247985ddL } }, + /* 7 << 294 */ + { { 0xbb9bce6810168f49L,0x32edc368717445e3L,0xb0b5a04426aa3ff2L, + 0xc671f1fcd166542bL,0x3142864df61d2523L,0x11b2dfc7b0c67410L }, + { 0x2e031a05c99690a5L,0x4782fb749fb7bae8L,0xeac2cd506b7175acL, + 0x2e116782bef2313aL,0x67992027241c4d2dL,0xf8aa0e09a6952d9fL } }, + /* 8 << 294 */ + { { 0x9974759c581f9d3cL,0x9e76a970e5cb1973L,0x8afec58ec64941caL, + 0x2d7c57fa01d05575L,0xc07c74cc5c448db5L,0xa52474ce01bb1440L }, + { 0x93162d9700115bbbL,0x483b6147fd7480f9L,0x4f28c57e6af18dedL, + 0x36faed8f174a3089L,0x702dbd64a3dd6265L,0x86a9c43f6adc0d7bL } }, + /* 9 << 294 */ + { { 0x9d4d4b3c795eb646L,0x727e2aa17485839cL,0xb50018a5aa9250baL, + 0x5a15808d1ba716adL,0xb1748d580ff91cebL,0x0131bcff76144b6dL }, + { 0x23fea4a58dcccffaL,0xe8eddb5ceb64caaeL,0x011a65971c3c5e66L, + 0x7723dfba377a8f6cL,0x00167c71dee2f651L,0x3e89ddf5ee0e4325L } }, + /* 10 << 294 */ + { { 0xa3510710b9de7b63L,0x9f364ad14019c9dfL,0x5b66a5d79b5bdce3L, + 0x2b2f695178b1b385L,0x3e4783d33cfa9f99L,0x1af517506bd6bcf4L }, + { 0xf9c0686a81d8d7efL,0xdc0f22ec37c068d3L,0xe1b8665393545fafL, + 0x37ca8501a8a52881L,0x07ac5c8a5603e359L,0x98fb2bab542cc937L } }, + /* 11 << 294 */ + { { 0x96326ec323da6b81L,0xdb48a5e1f90a6f83L,0xbb141660f640a0fdL, + 0xb51609375b92f5c2L,0xaaabd54c997244e4L,0xbeb8ab2f859bb92cL }, + { 0xcac7c5dda4be476bL,0x7093faea7f58c1b2L,0x3167a2c45c6ad412L, + 0xabd86bc9544fb9a7L,0x571296a72448c363L,0x4da64cd9c6cd4621L } }, + /* 12 << 294 */ + { { 0x4981be690c5bbd3eL,0xb047df0a185fdb55L,0x3168e05074cff00cL, + 0x111150a1b52c7f9cL,0x0db2ed84a51c7986L,0x7d991630e61272adL }, + { 0x7443d93628de14ddL,0xfdf31f41a5daed5fL,0x71e0ef4e866b5e40L, + 0x05c57a45b965a670L,0x85bdb58c70e1aa77L,0xe4d1fe2a9df3ce32L } }, + /* 13 << 294 */ + { { 0x6ff2b1a1772c3796L,0x9b88c1178e186fe8L,0x342ba11f4312af31L, + 0x9a93a4d1a86ae2b6L,0x496d5f219d59e3feL,0xce519a7d6924acdcL }, + { 0x6fdef82327c46e44L,0xab5504c34d31c9bdL,0x6fa52bca71693677L, + 0x31221119033c80f7L,0xdb2cb49dc0a22f91L,0x4962d58f9b4aeb5eL } }, + /* 14 << 294 */ + { { 0x5d4618982f722563L,0x11d22b39567db14cL,0x9a8f004e6779cd40L, + 0x0812ae3d5473ecd5L,0x4ed828624e6c296aL,0x2d9ce40c064ee61fL }, + { 0x4856d586d8a9eb1eL,0x2ddd6b125d1b5e3aL,0x0ab5eec0382fba3cL, + 0x302018dffcf4a9c8L,0x7b4e6fd2ab3cdedbL,0x266c246a8f64cb1dL } }, + /* 15 << 294 */ + { { 0x55bad54bd6dc35e8L,0xa43d72ff38642612L,0xe39a191609bc85ddL, + 0xc9d4bc9b0f85d3baL,0x84cd12b61367a70cL,0xf4ebc0e04937bb2dL }, + { 0xd083145949dc027bL,0x110751601cf29970L,0xa443a29c0b76b4c0L, + 0xee5b8d0ca0de3249L,0x368aa3259002e7d6L,0xeb48afdc6182e2e4L } }, + /* 16 << 294 */ + { { 0xc41e4aedf5c3af59L,0xa0284ad06de9a78aL,0xf5eaab7b8ed812d2L, + 0x7801fbb81afb58b8L,0xbe5cdba671efcc3aL,0xe31a0e3ccd10cb91L }, + { 0x882e821e85dc0bc6L,0xd3ad070fbb32e506L,0x3afede2bd8a0f038L, + 0xe20a117c857fd3a0L,0xebaa2aa43060f767L,0x6524aa0d2b9d1da1L } }, + /* 17 << 294 */ + { { 0x86aeca0ffd81174dL,0x19bc6ee60c6eefc8L,0xc85f7f2ea91f0e19L, + 0x09b9276ad2354dc8L,0xb62adee0542a669aL,0x8354ad1a88097445L }, + { 0xe67d2834df9984a1L,0x2330c8cfa64b2864L,0x309dcdeb39e7b54aL, + 0xbbba4737a18cf5eaL,0x47511b1d92861a8eL,0x99d4bd673286d404L } }, + /* 18 << 294 */ + { { 0x9cc5847c88cffe33L,0xff726b0f6e8eb6c1L,0x9bb2ca161bc45d8eL, + 0xe7903009a6d8a5a6L,0x4f089cc047db2201L,0x4135884de6b5928aL }, + { 0xb1a86a0ae5c017cfL,0xb1d9bf6db0a393dfL,0x33d9c1c628bb3277L, + 0xcb05b67b45b582ceL,0xa72585fcf33792c5L,0x78b7c5e8a7d1ed84L } }, + /* 19 << 294 */ + { { 0xbb83b446b1b4a091L,0x66440b3d9603d875L,0xd1931f33c2b45d1aL, + 0xb8b67f20098d4cccL,0xa3583818790f208aL,0xe01194bec4a3e88fL }, + { 0x29301bb192e8b150L,0x1795cabe9448ee60L,0x377d8f9752500c48L, + 0x474e73d65a457e79L,0xce0a50ef30159027L,0xfe69abaafbb2c214L } }, + /* 20 << 294 */ + { { 0x70e478fb9346df25L,0x01dc0c2eb4a4ada5L,0xaec82b005be36ea7L, + 0x82618b8f6717e06aL,0x2db1f6d4008f1977L,0x4e493f3b16b390d1L }, + { 0xfe86fd4d990a75ebL,0xa1cf7f99783f6076L,0x6cbb23e70c049158L, + 0xd05be7e5ed456235L,0x601374069bd836efL,0x94ec964432e5f604L } }, + /* 21 << 294 */ + { { 0xd96e4d920fc48c7bL,0xa2e29660f66e491cL,0xb92d850601146906L, + 0xa43f4803afe346d6L,0x27885d98700b6bccL,0x90662e9f595d8de2L }, + { 0xefa7f261f70d1007L,0xfe8a8be3fc72531aL,0x3b3f7541f1aa8d93L, + 0xb31bea258215966bL,0x15faa4acf35d2be8L,0x0a5f95e786c9a45fL } }, + /* 22 << 294 */ + { { 0x3361e1ce3d87bfa8L,0x92f235e78dcca4f0L,0xc8084cb4be323fd1L, + 0x3fd481a5c24c6d16L,0x9b1bd9402cea81baL,0xf50911910c5aa59fL }, + { 0x4cd8c9eff81d5e2aL,0x5ad000131550bff4L,0x29d47b9f8cc32e55L, + 0x66e3e6f111694eceL,0xd5edf7017950dd7eL,0x9ccb10960f6350c6L } }, + /* 23 << 294 */ + { { 0xc31e47ff95e784e4L,0x7ad0dfd63fa14241L,0xc91482092dab896eL, + 0xe9a114cccb9bb463L,0xedce9e6f16cb16afL,0x0ee2ce0607508893L }, + { 0x1aedb80ce31c0f54L,0x235d4591512658ccL,0x9029fad2a38583f1L, + 0x95b1e1ddebef898eL,0xeb2f21809efabef3L,0x458c4338b10e9cbbL } }, + /* 24 << 294 */ + { { 0x09db138d18f2470cL,0x63bd2290f613658fL,0x0bb647794feebab9L, + 0xfce4aee17fdb1e71L,0x7d5c0c61a7f1f65dL,0x46405b618d02d6cdL }, + { 0x7cac04856fdcb0d0L,0x85224c4b2f8ec5afL,0xb5879a59db0aa864L, + 0x75f391b8ff94f8b5L,0xa6c994ae49c97f8eL,0x4d968fadd690b232L } }, + /* 25 << 294 */ + { { 0x1e436df6e11a616aL,0x9eb49c76bdb932a8L,0x207d2fe90e6591aeL, + 0x6e05acc8233ac034L,0x464dd321f3d04d32L,0xd4ba4889af43c171L }, + { 0x0808e5207120fab9L,0xb9e4726c3fbac672L,0x5dd1c13b9d7d883bL, + 0x1c091808771f1edbL,0x76988d1c75eac1a5L,0xb0fcd3a893a67be8L } }, + /* 26 << 294 */ + { { 0xf5cd290a67e0b4e7L,0xaa6fa6807c1594b6L,0xebedfbd7b63270beL, + 0x574b410ba369bfeeL,0x431cba5a020ea888L,0xd3a3102f56c71d47L }, + { 0x4894bfe0a90a853aL,0xd78bd98b5f9c4b6bL,0x9b1324f6d900c5c1L, + 0xc65c944d718c2147L,0xf661de6ba987f634L,0x0315e69f172628d8L } }, + /* 27 << 294 */ + { { 0xb12e0ab8aac7ab64L,0x8ce877abb06cf9cfL,0x39b694b40bb11fb4L, + 0x0c2428369b0d8850L,0x6bc9a033ccd50c6eL,0xaa2e77739a1e8fb3L }, + { 0xa7d8be09608e2e9cL,0xeb4cef0542b9f458L,0xa7268c9b985f66fdL, + 0xd60eeab27acf4968L,0x02eb2db3b6e5621eL,0x82fb4abfad8236c4L } }, + /* 28 << 294 */ + { { 0x07c60c7522ea5f1cL,0x35beae34a36bee4fL,0xa8b00a09dcba8997L, + 0xa77f1f3a802ce50cL,0x6c4050df2a2144b0L,0xf79bfa96ab1b10dbL }, + { 0x9025d470433a9b1cL,0xaf3e391790d9eec8L,0xbcad2d629ae2d535L, + 0x7a152829eff0f6a9L,0xe87345cd925fa5a0L,0x6ce007200e84039cL } }, + /* 29 << 294 */ + { { 0xc65acf36c3d095d2L,0x9192c5fe72427e6cL,0xcb84c43c3fa8b90dL, + 0x2f458fe965e15b23L,0xd8bf193731469f11L,0x1ccd8bb93638cc3eL }, + { 0xa067022f78e35577L,0x382e6af730ee676dL,0xf197adc2f6d135bfL, + 0x06360834c9a1cf58L,0x413813f7930371beL,0xf7461d04f5dcaccaL } }, + /* 30 << 294 */ + { { 0xdae449c007f6a05aL,0xbc1b84f55bf26c9eL,0xe3b3f9edb1c13820L, + 0x5442ad5b4090598bL,0x794ef65613749e4dL,0xde809180948b71c5L }, + { 0x4c72dc7de203c5b5L,0x8902b0971b349fc4L,0xa899bedb225a1569L, + 0xeb7da73de6ff3f53L,0x6ee8e1607c0be37bL,0x9ee667d2a31bf943L } }, + /* 31 << 294 */ + { { 0xbc91031108b6fb2bL,0xa5e0ab3e25e06a55L,0x16ff0705360f1698L, + 0x71c0aa7487e72a67L,0xa1f1497b355c75e8L,0x179b67bffa6bbcd7L }, + { 0xc9db6590b6738583L,0xf77660c4d87e72bdL,0x0ee2e7b3f13abc2dL, + 0x0cdf5a37a4d922b6L,0xaa8af2d596c853a4L,0xdc452af4e0092356L } }, + /* 32 << 294 */ + { { 0x5017e145db81146dL,0xc7d2086d45c54db8L,0x2541059dfa98234aL, + 0x4bf344d99985af98L,0x39737ed67b5b7b1cL,0x8e24691987c411adL }, + { 0x2fad8cedb877a75fL,0xe42352df17e60ee2L,0x1a53d856404043f7L, + 0x6c1f07a5863927a1L,0x38d3a4f4b6892121L,0xf4c1092001976c8fL } }, + /* 33 << 294 */ + { { 0x541732a70224214aL,0x61617b515cb2d019L,0xc560c24bcb4fc6b2L, + 0xd0ad737943670d99L,0x08cdd32eb83112a8L,0xbe57493d7e29810fL }, + { 0x7834124899d4523fL,0xae1a5857cc8e5fb7L,0xf8b62a59b8454efaL, + 0x7c63c900ab0f4729L,0xeef9243d72dd0f5fL,0x6b865dfbad766386L } }, + /* 34 << 294 */ + { { 0xd11536eefee626b8L,0x1d2471dd8077b5d4L,0x7db062debdb9a4dbL, + 0xfcc62c0ab9f808ebL,0x619b54c6ef392bc7L,0x81e146fc51b9f5c9L }, + { 0x0343807c7bbd52b3L,0xe024a9f1572125c5L,0xf8b886d86c57cb31L, + 0xcb92aa7d5398a318L,0x4ce0870d2410ef34L,0x1a40c103f8366683L } }, + /* 35 << 294 */ + { { 0x46485baa7bb78552L,0xc0f685f23e6a3f0fL,0xd24970b5fb3cc0ecL, + 0x0d1f380e7bf91feeL,0xf0f7fcafe7624351L,0x27cb99bc697a8055L }, + { 0x55be14685cdc7560L,0xf006927927ba7f93L,0xb0c25c759fdd0e70L, + 0xda82e73785818253L,0x7d40d86946304c51L,0xe06ea6fdcc18ba58L } }, + /* 36 << 294 */ + { { 0x99d37ade6b65e17aL,0x61ca538e38ce217cL,0xd3ea83f68ebb89edL, + 0xce6611eb4b02964eL,0x0ec7cc2f5c0a8e44L,0xa985b0c2974240a4L }, + { 0x7a3abb6c42ee5b0fL,0x55f049a0cb2eddadL,0x69348b027c44a60cL, + 0xcabc65191974a8c7L,0xd9def4bc07b91a35L,0x684a2d71b93b34c3L } }, + /* 37 << 294 */ + { { 0x21c37d21f48f274cL,0x2de96b4da082a098L,0x82520e0ca606b6a6L, + 0xf76c9ec6e1050b81L,0x248c5efbd1ce149dL,0x5a36ae1e9a909790L }, + { 0x8790b09bec8b43afL,0xd592dce560ff709cL,0x726d699724cc8e21L, + 0x61e37bef5e2cb745L,0xd55a68c26eff3ba0L,0xd47f02659ad265c0L } }, + /* 38 << 294 */ + { { 0x3e6351ef3932ef94L,0x65625878db5d64e6L,0x118a688e091ec7b7L, + 0x2a95072abdf60b88L,0x5200703540dc0afeL,0x59c3d90b6fc1cbffL }, + { 0x5622b1b21dfb1a7fL,0xdcb0344834d92243L,0x18fccfa86d7d36c4L, + 0x5d43a14181341761L,0xef375542eaaee79dL,0x4e4667216999d399L } }, + /* 39 << 294 */ + { { 0x1bca97aa9d3c6b9eL,0xb4bb4f95095cb250L,0x4f2c216a996fb52aL, + 0xc4d01916f379790cL,0x510882a4359df53dL,0x6457d76a671d6a8fL }, + { 0x0ded2623061f7d64L,0x3cb4f38f1ce7dcf2L,0x0d86313a224ffa88L, + 0xba8a15012b99aeb3L,0x2fb92183d69f72b5L,0xd3b9d6daf1fdb8f0L } }, + /* 40 << 294 */ + { { 0x5d573a3a0b6320aaL,0xf9ac8ccf289b6700L,0x8bad05cd8f28dd72L, + 0xe2eabd446b62c306L,0x60f70353906ef302L,0x147cdd0c367a768eL }, + { 0xea9d871635a9e846L,0xdd71e80aa8684430L,0xa56a5ccd530768a8L, + 0x59d241270a3e42f6L,0x707cbaf0faa367d1L,0x5419b14f52a0cbd0L } }, + /* 41 << 294 */ + { { 0x625bf4e6d991d842L,0x56b95a56a81daaaeL,0x2101137c9911bdadL, + 0x1141b0a1bbded1c2L,0x85deb889d1df8d43L,0x51e3e17edac3e376L }, + { 0x5d31639381fb19f8L,0xd1cb634b92eed2c4L,0x72a6ed7b943746dfL, + 0xd55f55fb22b85e00L,0x255b025804193aabL,0xd0b94c5d86a78c96L } }, + /* 42 << 294 */ + { { 0x121c15d859c3556aL,0xabe25c21864380dfL,0x2de101832627f78cL, + 0x19988e4b4bcf4a0cL,0x4ed3aad8a2f9cb52L,0x50f8cef5b2b257e1L }, + { 0xab0b000c49f7f596L,0x6cb997471fb9c471L,0x331974b95fefb8f4L, + 0x57cf97578e2e0e5cL,0xa82a8d06174a626cL,0x40ef371b03e80567L } }, + /* 43 << 294 */ + { { 0xfea713e1324cbab8L,0x738885e61897e7baL,0x8234ed08126aaa13L, + 0x4f66467661ed1548L,0x61fdc2aa172c432bL,0x78eade7c9ebf0a29L }, + { 0xd50ae7156aa104a9L,0x977d7a605536df98L,0x024014bdc9eb983cL, + 0x75d53c0585e21649L,0xc181d67098404cffL,0xe00f5f5dfdb3f05aL } }, + /* 44 << 294 */ + { { 0x3cfe2987d10542b1L,0x5935e0dc29f5b006L,0xce5932d6d83344f2L, + 0x67aab7ad9800a6d5L,0x3ef2b0e765073619L,0xc381a99454aa9ccaL }, + { 0xbf069577d4011571L,0x33b70c5d4d1ce997L,0x801ba41c758c9b1bL, + 0x6c2dd5ec36968958L,0x31820ca087921665L,0x0b7f0d337ca55668L } }, + /* 45 << 294 */ + { { 0x0b099a5afce6c55fL,0x91d1caca408dd628L,0x42a5181165449db1L, + 0x540935b040715d49L,0x8feabc5433b00823L,0x7107c06240c2485fL }, + { 0x13f307ac4fea64e4L,0xae4ec4a713a04327L,0x8297be380eff71f5L, + 0x3434286f1ecd0b2eL,0x4d7a5456a3e9d625L,0x657f950b6a0d04e2L } }, + /* 46 << 294 */ + { { 0x2237f78ecebadb15L,0xa1184339da01f9e2L,0x542c3354ef37abd1L, + 0xbec90883de982d70L,0xbacdbb9c457d3024L,0xf1d167c19840ea52L }, + { 0x9ed827d8433bd3cdL,0xf4e5b4231102fdf3L,0x2038c92fb63d6056L, + 0x490cb0188eb9ae35L,0x776331b87c75ffc8L,0xafbe7c6a3fe2e400L } }, + /* 47 << 294 */ + { { 0xf668460c9176a02dL,0xa843a70011d322a2L,0x6424f0e8a8c5d1c8L, + 0x0b45a1ab1bc440e5L,0x3b740cb11c3e391cL,0x5aaa89c4d5850e1bL }, + { 0x77739ee6d632c592L,0x171fd350fffe373cL,0x6a648fcdbd7e83beL, + 0xd98650c6b619f4d5L,0xa4e4ae5438dea07cL,0x10001f5afe0bf5c1L } }, + /* 48 << 294 */ + { { 0x31cb896b57dfc732L,0xc6b74a1edc323e91L,0xd24a41d0f11b04f6L, + 0xb609a26dab8f7159L,0x96d84b372adbec34L,0x154f5307d24ae7f6L }, + { 0x36dd3243e10eb34cL,0x055d3b714f6dbbd3L,0x30b1efde36d0c561L, + 0x3846925ce9bffd15L,0xaf401286aa99ba07L,0x3a191267fd48b839L } }, + /* 49 << 294 */ + { { 0x67145f18e42a26cfL,0x580857fa491122d7L,0xa4e2db8dd03b5071L, + 0x47a39a0d3e379882L,0xb6bfe4b35970766dL,0xe40f4daea8bce767L }, + { 0x38f199a7e812a217L,0x1407f98d97eec7caL,0x25d6f750236a41a0L, + 0x644327340e811ee6L,0x84d5d9c9dddd6e5cL,0xc1b6ef13c44cae4eL } }, + /* 50 << 294 */ + { { 0x79879d4f6714e8daL,0xce409617a17abd07L,0x6f2b14d008a6e685L, + 0x817d467409b5e150L,0xa1181873eb51b966L,0x573ba855da6b9544L }, + { 0x836ec3e5c4a37013L,0xb8da1bbe93fded69L,0xdb5bb6f16edff4c1L, + 0xff30b837f1657d36L,0xa20cf000223270b9L,0x29d60562d44a57cfL } }, + /* 51 << 294 */ + { { 0x0d6f36b9b98b029dL,0xc4cd72d07a371233L,0x23bd419e4f95cd4cL, + 0x2c95b0a2b80d1e13L,0x0f76e62f7edfbef1L,0xd077194dd303a470L }, + { 0xd6e20e7cd1b50934L,0xf4201fca2dfeb806L,0xa57dc150bced28faL, + 0xa84d621be3172301L,0x119768fe9aa14d6dL,0x34f1ae864b363253L } }, + /* 52 << 294 */ + { { 0x2fc83aa3afabd13dL,0x521b745f53c45a27L,0xc6f345a660c18225L, + 0x9609076eb5faa47aL,0x8bdd97fd535388fbL,0x8f5f3bd6e7fd7e87L }, + { 0x6de4454c1c8e1d5aL,0x8d61ca3b2b35e823L,0x93b66fce4672d30eL, + 0xcb9d601721d09ec5L,0xef98137fb1de06eaL,0x45e212758b051877L } }, + /* 53 << 294 */ + { { 0x117b89e9ee6e35f7L,0x2ad205aadd203ed9L,0x3f6c950c0689bd4dL, + 0xaba1e4b342f20742L,0x67464b793e22f0d1L,0x74436dfdbe0ad6c1L }, + { 0xc4a6e964c1470ac7L,0x853ad39b361da35bL,0x261c6fd6a187a6abL, + 0x08d7e89d59fb860eL,0x158e2697e8f88299L,0xf3f1f6f34b04a8ecL } }, + /* 54 << 294 */ + { { 0xbdfb8d006b562705L,0x76dbc217ed9f2aaeL,0x62f713778cfd02ddL, + 0xa05eed177a5d27e1L,0x60082379a006983aL,0x312af914bf7c2c05L }, + { 0x7d163fe76c8500fdL,0x722a35299d4d0dbcL,0x9b4c5c3539f93a78L, + 0xb193734c34c7ec06L,0x457db178cda87a84L,0x088dae087f816e0cL } }, + /* 55 << 294 */ + { { 0x746e73055896ac5dL,0x1d8326c21a7b69f1L,0x695197743132a40dL, + 0x3899f8a03f58720fL,0x2c3070a5df0b7fb2L,0x49bc59f2acb839e3L }, + { 0xf7d5d3f66b8f5a9aL,0x704ed893a4c3b570L,0xbafde26cab591c03L, + 0xc447dac83388a62bL,0xda80991d4416acfeL,0x1625c9151e729d69L } }, + /* 56 << 294 */ + { { 0x3104e59e6b843647L,0x4eccb42720bad138L,0xa575b8e150efd6a9L, + 0x68a6b7055a6e4729L,0x670306798f5b2a22L,0xb2cfcf81df9253bfL }, + { 0x9c3eeb19b8f81c39L,0x082ca86c986b4dfeL,0x1f64eca250250d8eL, + 0xbf26bcfb67f0c713L,0xbc5d0e2a49b609cdL,0x175acb34e6aa3c76L } }, + /* 57 << 294 */ + { { 0x5237d7368c53aae2L,0x2a88098bbdbc0b10L,0x18f1af11cec6db6bL, + 0x12c23392c4e08b3bL,0x23b652bf3eab43f3L,0xb79feb949f3dca0dL }, + { 0xb71e311d2b24e0d9L,0x85e48aede37a0f90L,0x93e8a0e753200b6dL, + 0x5d44b87226bf3a30L,0x466c31d1d0496b98L,0xabec12f7dd39874fL } }, + /* 58 << 294 */ + { { 0x58bc23928ca41326L,0x0744ba8524aa5067L,0x900e7e9baaf80bb2L, + 0x510bd122aff38fe1L,0xf90dd6a1002b277bL,0x829379dc81bf7df2L }, + { 0x5443b8736372d502L,0x124c2abab5b6f9a2L,0x88b237a4d6020c14L, + 0x3542215108f7a498L,0x39e84240e6234eb1L,0x43d721dfcc5827eaL } }, + /* 59 << 294 */ + { { 0x43e7597234658dcbL,0xed936b96bdf3a7caL,0x74acb7f60f1923abL, + 0x6a52b28cc007995bL,0x5abf2909a560fbf4L,0x79d571dd256bf1a8L }, + { 0xa8d51082e4c3281dL,0xc0d6f8aa0b9fdd38L,0xd589f2c57ac30640L, + 0x6abb8faf07635c58L,0x2af1b083d7520b0dL,0x18b9f6c893b951fdL } }, + /* 60 << 294 */ + { { 0x32e678b4c1ba956bL,0x9e8b137248f32982L,0x9b380a118a8f262aL, + 0x5c2d6ce0807f6d1aL,0xe99c2e909f1b3fa2L,0x6a0c9e4a7c4bb836L }, + { 0x30d80329ee8dac83L,0xabcf7b76b60bd5fbL,0xc589a0c8c14d56d4L, + 0x9e40af665de24d43L,0x932f4070230f8331L,0x96bba1c19b87948dL } }, + /* 61 << 294 */ + { { 0x8b83af0c4efaae9aL,0x25e55686770c85cdL,0x0beda54fede0c999L, + 0x6c5749398d249a2eL,0x520ac2ba2f476146L,0x162e482de95b05acL }, + { 0x2d3d19b6c73a32daL,0x945e5e3c33fd2c48L,0x361d9770a36b4ee8L, + 0x8aed760d014cacb3L,0xae66e5de5ae302c7L,0xb5fd5959b5d4d6a4L } }, + /* 62 << 294 */ + { { 0x25df58ff147da470L,0x1b3941ec3f4e3e98L,0x7543b1227aee3587L, + 0xb7bc2b31b4a28218L,0x8628b5400bb3224fL,0xe3e7644d373222e6L }, + { 0xb4e3269299244dc9L,0xe72c679d49781bcdL,0x894d9eb0bb6f0700L, + 0x4a08cdbc443c3639L,0x52c4d04e5baeb02cL,0x53f550ffb5f93552L } }, + /* 63 << 294 */ + { { 0x2b908f693c1f524fL,0x59fd6ae7090970ceL,0x595e15721eb9ec29L, + 0xa55adbd6fbc4f04cL,0x575a2344bcc38bf8L,0x89397944f2b659b7L }, + { 0xc77532a18c87fe8bL,0xa5a75677de4c9eefL,0x2e3d873a0e4a1704L, + 0xe18ff4fcc4d02aa1L,0xd842074275573a79L,0x0fcb532115296dcbL } }, + /* 64 << 294 */ + { { 0xbcc88422c2ec3731L,0x78a3e4d410dc4ec2L,0x745da1ef2571d6b1L, + 0xf01c2921739a956eL,0xeffd8065e4bffc16L,0x6efe62a1f36fe72cL }, + { 0xf49e90d20f4629a4L,0xadd1dcc78ce646f4L,0xcb78b583b7240d91L, + 0x2e1a7c3c03f8387fL,0x16566c223200f2d9L,0x2361b14baaf80a84L } }, + /* 0 << 301 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 301 */ + { { 0x7a1a522b246dc690L,0xb563cbe14b61ab70L,0x41bb4abe3d4ac4abL, + 0xc52950b337f996e8L,0x01d991e679727761L,0x35de93bd978fd7d2L }, + { 0x86bad5e65706d336L,0x10844155e7f26c20L,0x58ffeb7705757453L, + 0xbb1861293939df77L,0xbfdd394a6a78ea0fL,0x907ff0546e33e1d3L } }, + /* 2 << 301 */ + { { 0xa7f295320df93b34L,0x855934f25c14df30L,0xd2f54ce9efae348cL, + 0x5acb931cac52758dL,0x287b3e18d22961a4L,0x42a5516d748f8fe1L }, + { 0x1b62b341877224caL,0xaff58db3d30a4aa7L,0xbad78dadbe8da847L, + 0x85fa710954f18276L,0xe2cc9d287c4bfdadL,0xbb131f762c75f237L } }, + /* 3 << 301 */ + { { 0xcdcdd7d703844670L,0x79ec59afb4a23f91L,0x5923c569c00ce5c3L, + 0x099c17ffc589d0c7L,0x0335eeea89fa6fe6L,0x916bcacaa4e868c4L }, + { 0xb7037325fb687bd5L,0x57d6bca79853b564L,0xdf3132efd5e26d28L, + 0x7ed994b8de919cbeL,0x12df67cd6fbbb18dL,0x516e07c06baff508L } }, + /* 4 << 301 */ + { { 0xf2ec9ef597e833e4L,0x97bdef9734ec7e41L,0x90e2b2387d2ac6e3L, + 0xcf682b120318a3b7L,0x7fe76089ea84a7a0L,0x85c489f916546d05L }, + { 0xf987118f6abdda05L,0x675cf998aa4b95fcL,0x544c7774888a7e8cL, + 0xbd2647ba63ec5831L,0xb479cea3fd2fe985L,0xa042134528d163e8L } }, + /* 5 << 301 */ + { { 0xd93506a4e5947c6fL,0x4340d76a39b81d08L,0x741aee5917930d30L, + 0xfea3d99a18fdb81cL,0x1088ff6b289bcb07L,0xc6b45602b7c082c6L }, + { 0x50e2baab453d8d69L,0xda9bf561e893e183L,0x0af25f86b29a284dL, + 0x0e92e67473e01380L,0xe173a0e32be00e59L,0x402d2f3dada8954aL } }, + /* 6 << 301 */ + { { 0xca9cb3890399721dL,0x03ad9f4aa3291479L,0xd85b5df56dee003dL, + 0xe1fa7b0264a4f83aL,0x01c4cbfdb73f7324L,0x707010d45cf2ddf4L }, + { 0x3c6df430b12e02f8L,0x921a290185531489L,0x302fc77c91d1022cL, + 0xc3733ec0342d8f3fL,0xb83bc75f6195a665L,0x4a14b9e7a79f8027L } }, + /* 7 << 301 */ + { { 0x9f0e5428e2a57359L,0xc690a3c714998c16L,0xd73c3ca2de37e07eL, + 0x2ddf91b8dba0bc0dL,0x69d834b27570ae71L,0x2ac8bed4735195a6L }, + { 0xcd8c51ff3b1fcc5cL,0x7aa8cf4e1ba6863fL,0xebb69e72ae70f428L, + 0xa29409dfaa9e936dL,0x43f6ee805a332b9bL,0x0de49efac2eab0a9L } }, + /* 8 << 301 */ + { { 0x04baa1762310333eL,0xdc75e35f7b9bad46L,0xc4a6031dc6cd6108L, + 0xba2534d030bf87a5L,0x7ebc6e2131e497ccL,0x8a2a82b4851fd665L }, + { 0x9ecae0116d5faf40L,0xfa3a6d7f96956ecbL,0x39e8a9c22fa52782L, + 0x74c93801236d442eL,0x8b21ba23b1c289ceL,0x7f3e221b25c769cfL } }, + /* 9 << 301 */ + { { 0xed800e4d08aa4dfdL,0xf524b107d8105bc7L,0x8c4addc9ab07fc03L, + 0x2b0f038d26a71b4cL,0x5055c471a83d19a7L,0xc6c5ecba27e20a5bL }, + { 0xdbad26b7aaeaa017L,0x4e3abc20d2493554L,0x626310143a0c15bfL, + 0xbafcc06798cec55cL,0x9204e17ce6f87607L,0x8f1c10eed9302c05L } }, + /* 10 << 301 */ + { { 0x53680ce08afe59b9L,0x36a3cec75665022dL,0xb3a5091654490b50L, + 0x803d383f0838f0aeL,0x65531a008005ba2eL,0xb7fa6b4a1241a17dL }, + { 0x9aaec449b17e07bcL,0x19b7d9113d190dd0L,0x79da42457fa5e7feL, + 0x725bd045598ad850L,0x49f96cc45f94ee82L,0x114bbcbf03850eefL } }, + /* 11 << 301 */ + { { 0xf566a287d43a6db8L,0xffb8944b2aeb120cL,0x3e7099427e294c1aL, + 0xce122b126c31214eL,0xe59b280c2a21282dL,0x03916e2ba01a4fc6L }, + { 0x56e65da29f5e409cL,0x374d3dfe7f5c3e11L,0x150684fc13967e2cL, + 0xfbed4f5bdf4bc38eL,0x5973c67182e54b82L,0xcd36c873363f307bL } }, + /* 12 << 301 */ + { { 0xcb42c5617c3805d4L,0x0e74e75c3b43a8b3L,0xfd58f864369f579dL, + 0xf471aa774a3dfe97L,0x2e0dbb51ab37bd2fL,0xc4704487729c887bL }, + { 0xcb7958a9cff32948L,0x3e36de368505e71fL,0x2232fd2dd38ccfbfL, + 0x6f3c502042005175L,0xd1280a3e306fb63bL,0xef7abd792e368ee9L } }, + /* 13 << 301 */ + { { 0x29c5712d56ffcac3L,0x20307670e1a8e0eeL,0x676a23c26356aea0L, + 0xb9c17e3f432f15d5L,0x0008512e287c5705L,0x6ae2704bc5f7ccfeL }, + { 0x6a200db709a13b60L,0x24fb1e9241043271L,0x2e455e9741b766a2L, + 0xa11ff26fbe056684L,0x3cfb8a64ad9178ceL,0x5786978d5d675b79L } }, + /* 14 << 301 */ + { { 0xf4cf2c8e6070a72cL,0x0bd73aecabc3251cL,0x1af44eff17539f67L, + 0xec3ee99e44e8d8f7L,0xba698f6a279afdf7L,0xe871accfb771d4a1L }, + { 0xbf92963d8bb0f264L,0x817b1fcfb10716bdL,0xf57580786b23076dL, + 0x994ff3c535a994cdL,0x05d984e82604847eL,0xd728e292fc9f2e43L } }, + /* 15 << 301 */ + { { 0xa44bf023b900b696L,0x1f82fe54037bb770L,0xa6d12f820717e747L, + 0xf154ac51e3b83029L,0xfbd343128cf3984dL,0x7f734beaa76c72c2L }, + { 0x05c5b443114548b9L,0x4ce414f396af4132L,0x1474c0b79d080a7aL, + 0x865827c6497366a3L,0x34760c457816a0a8L,0x6da2474c15d2a176L } }, + /* 16 << 301 */ + { { 0x761e10e2ca114c4aL,0xe39d121d894301b3L,0xa0870ff43dbc6fcaL, + 0x97651286cbe0ba8aL,0x47d46075c0f1ff6aL,0x18669c843abeb5b6L }, + { 0x1234c80ead8d9309L,0x1ccbe4d51f6f97ffL,0x399a2d41d82ab780L, + 0x8a03afafde426e50L,0xa2bcb109ca6dde77L,0x840e13b00618f5ecL } }, + /* 17 << 301 */ + { { 0x9552a8184929f7eaL,0x514e9ce9acc61766L,0x03159a525a219015L, + 0x5efeebfa14eace54L,0xe8a3736f853da94dL,0x3a0f334ff45e8a32L }, + { 0x71ebab39c9dc65c9L,0x6ef37f49d7c24f39L,0xde3d45f8b24a9383L, + 0x7193bbb80c218869L,0xa1bdfd30c0f7b6beL,0x82b2c4c5c1d9206aL } }, + /* 18 << 301 */ + { { 0xf9d9b678b197099fL,0xfa8548c4c15b2bbeL,0xa36f17fbdd2817beL, + 0xb35597021732d1edL,0xba145100744f3955L,0x7c274633344b43a3L }, + { 0x9b0ee7c8686b65a5L,0x438eaf4823f0e973L,0x79a658a7288c5019L, + 0xf6d938c546d04413L,0xe39bf9a6a6cb9853L,0x880d5b83801b70ddL } }, + /* 19 << 301 */ + { { 0x8f23f00303825482L,0xc4a9f214a6b35023L,0xf0905573794e7de0L, + 0x7ff790144dd68979L,0x8d9c14942959beffL,0xdb34474f82282e48L }, + { 0x423bdfa281fde794L,0xfc31e3e792a8810bL,0x19d316ba8bae4eceL, + 0xddcf30b7159c1386L,0x997968a38e7d69dfL,0xcf67ae9aa6b21be0L } }, + /* 20 << 301 */ + { { 0x877866a3697b4dd0L,0x32a872f4e76481aeL,0x300387bad609cc04L, + 0xc761ae79d74566d4L,0x9fd3e5bff22e2d24L,0x363ef5bf1c46bc0dL }, + { 0x121b25bce299a690L,0x7932471dc2d32b7eL,0x7f89692e94bb4272L, + 0xaf9cc4111a3ce076L,0xaf02ea22ea02e452L,0x43154e581d19dc60L } }, + /* 21 << 301 */ + { { 0xd9389e05e25dbe97L,0x3a8689b162b3afe3L,0x4d5556467014953bL, + 0xd6894c42af5ba9bcL,0x4b233690b3bacaa6L,0x0fc8ad07fc191181L }, + { 0xcd3a1e4df0764f39L,0x18a47233d79567f1L,0xf0f9eb765f921f79L, + 0x7f3d814d19d12a7fL,0x5e48cc36ff33a995L,0x9589679b8960331eL } }, + /* 22 << 301 */ + { { 0xa2ff78bb477d7226L,0x3216fcc085e04a8bL,0x7c594f81e4c3c24aL, + 0x075eefaa029d6ef6L,0x5ae51000493ab006L,0xcdfcc6939ab165efL }, + { 0x50b7eee276073bfaL,0xee52d55b3b60cdb4L,0xc7f7b3af45027275L, + 0x01d5444ac15b2ecbL,0xdf56f8c12a61d1e1L,0xcf032e7e4992e1bcL } }, + /* 23 << 301 */ + { { 0xc8a4dfbf15b6d8d5L,0xcb34e0e4e87ff88dL,0x6dc95befa6ebbff6L, + 0x2a55ca1372ff2cc0L,0x3c4c0f3c6a62588fL,0xa8de444ece156917L }, + { 0xced7c4523e55eba1L,0xa109b7949f05820eL,0xa021717e0e6c318dL, + 0xa0156b8d0b308f5bL,0x3c65ab9daa6634baL,0x1666e650e2839e0eL } }, + /* 24 << 301 */ + { { 0x0d27500f9ebe3c40L,0xeb9ac1022b700fcfL,0xee7578f8610763e3L, + 0x6e56078f47ef08feL,0xa8d03a7f047d04c0L,0x2143606f27cc8aa3L }, + { 0x6b08eb383b004721L,0x1f505c0dc4e36bb6L,0x6f9b869ae3f10ba9L, + 0x3bfb9833e500e846L,0x6d975557b9171b1aL,0x7af9cf4f18fa0045L } }, + /* 25 << 301 */ + { { 0x35bfb51b3b35836dL,0xc834e59003b0fba6L,0xbe6e17d378937ce0L, + 0x2f796f7c4daa9aa8L,0xd7896a0ad310eba9L,0xda258ab05ea4056aL }, + { 0x2d872d2170626628L,0xc9b26d7c2ee433f0L,0xb176220ee72f7491L, + 0x4869adcd895e9b52L,0xd37540e4d3a6d786L,0x024aff303a86b44bL } }, + /* 26 << 301 */ + { { 0x5e78606bd8424b90L,0xc83a5af9ebc9c9fdL,0x8d5b63740b65ada7L, + 0x4d01d6a221fca70fL,0x8ed7787ba1838061L,0x29901318f4a1716eL }, + { 0xc4d260527f25fd2dL,0xa66dc0a98b5147e0L,0x4355e26c269d726fL, + 0x1284fecce3a27644L,0xc9aa6cf7f98e1d0aL,0xa25ac1be3ff560c9L } }, + /* 27 << 301 */ + { { 0x5bbb87ded64d103eL,0xcb53a2f24d20fb37L,0xf8a9c2993a46b892L, + 0xb552910ca793aa9dL,0xd09e5bea51ef0806L,0xb57a0568e0c3817fL }, + { 0x9ca67c5f4e85598fL,0x04f6361fb0336008L,0xf028231b580afa5aL, + 0x8d938c0ef2bba03cL,0xa5984c1f894f37d3L,0x62ead7f4af695ac5L } }, + /* 28 << 301 */ + { { 0xf897de9213a48775L,0x505e21681b0041bbL,0x9f5533aad598ebb7L, + 0xd552ae1e1e87b2fbL,0xbb35a6319b736f5aL,0x391ce7dcc3a4c54aL }, + { 0x4c677d87f90124d6L,0x2ceebe51a9292210L,0x8882ae3133c63951L, + 0x8222c6482d44c9d0L,0xb97511420d607658L,0x3a999028b85f5997L } }, + /* 29 << 301 */ + { { 0x7b23f424eabb3f68L,0xa622a3ba4294750eL,0xb382b118e535b446L, + 0x7dbab9ee5fab292cL,0xcfabbfb037fe2f8eL,0x2283d7606670925bL }, + { 0xd18e90715be9d07fL,0xe191daa7d257745dL,0x86d59808df915e35L, + 0x87f68d5987370b6bL,0x76b9d255f945ac1eL,0xdcf9e8f2dc94ddbdL } }, + /* 30 << 301 */ + { { 0x004f1db65b986506L,0x5da683c32b0d22acL,0xf2afd1d85ee0c71aL, + 0x3b99a78a8f2ad25bL,0x8145d2ffd1c0cb69L,0x4511dc4e4009a536L }, + { 0x5539e8b8a5cb0c13L,0x4f8fd0186aae4603L,0x15dde4476d2365f3L, + 0x7cb887f7380df270L,0x815343a6a741b88aL,0x81a085e4bf99e7e1L } }, + /* 31 << 301 */ + { { 0x37d0460fd647fbd6L,0x2ccc7b01b9541f89L,0xec0e8826877a1b2fL, + 0x54d9e611cd462979L,0x016e8458453dcce6L,0x99b5dbed20ea6a24L }, + { 0x64072ec778550386L,0x279fbd9959d02307L,0x7f2ca27e9183bfebL, + 0xa191d6e8bb5132f5L,0x2b9f6163ba49ee68L,0x5a58a11fa3ee1672L } }, + /* 32 << 301 */ + { { 0x15d47e52ec645a62L,0xabe0ddb38d6d4423L,0x51226a3070cddb11L, + 0x63a253d32b5a8db7L,0xe8be4d1fbef37d65L,0x41e625d9c0920b91L }, + { 0x08b713a8d9d040ecL,0x467fb08dc450cdbaL,0xa8975877917ee393L, + 0x294792e91528cd12L,0x4512dc8c37daf6aaL,0xa83becc9197a99b9L } }, + /* 33 << 301 */ + { { 0x1b7bfdb118815b20L,0x1aa602e8629b81b9L,0x11e6df9d199aa5abL, + 0x1a521728bef9296aL,0xeba3e03b89e127e7L,0x6e69893553dffcf2L }, + { 0x24355785101615e1L,0x126b4c5282e42593L,0xe344ddd85c23144bL, + 0xc73a49b3746c0ca2L,0x1ec2432be6f63f9bL,0x6080ba870243120bL } }, + /* 34 << 301 */ + { { 0x6ab2936a4c3e946aL,0x8de2e0ae3ab052f0L,0xcaf8c35eea109739L, + 0x21d69383032418c8L,0xefab535ae7ee60faL,0x1a3a1be794b44fabL }, + { 0x0842aaa5eb911cbbL,0x789c2b7e0286862dL,0x8bff708715c0b148L, + 0x71100d79d8d7faf7L,0x47caa89a6dfa0c8fL,0x82385cf44b546332L } }, + /* 35 << 301 */ + { { 0x4f5d8c35e4b814fbL,0xe534b7be6a427f92L,0x468fb2819ca1d37aL, + 0x8c1c86347949961cL,0xf9d00305db0f7f19L,0x77534b3a976f7102L }, + { 0x94ecb7933f530710L,0x072f6fc7a916827aL,0x9247acdecc926f8eL, + 0x0d4a8997281d0a50L,0x659712669f353507L,0xd4730a15fde80a6bL } }, + /* 36 << 301 */ + { { 0xde68ca25bd37b630L,0xcfa9d32ca899d623L,0xaaeab905937c9ba8L, + 0xcb261334348ed39dL,0x8d12531fc77e1512L,0xfb7934b6213b63d1L }, + { 0xc6a6fb0096a13f19L,0xe940f3aac8f88d6aL,0x014c7f95c3d2829dL, + 0xc33d87e9fff01f41L,0xbf9c3c23c5cdcb4bL,0x8b8c0afe5d5be5c1L } }, + /* 37 << 301 */ + { { 0xe4f84bf12aac2c23L,0x5bde1744f823f90fL,0x65ffefbc02d5bbe2L, + 0x385aff9332a3b756L,0x3813f2b362abfdacL,0xbbb444cb0a144325L }, + { 0x0cf9d137ec625be1L,0x86b8fcd4c143816bL,0x03f7a9d060ac32d8L, + 0x0428daf9366165b6L,0x6ef94260d2a806d0L,0x94a100a598134bb5L } }, + /* 38 << 301 */ + { { 0x4b68325ca4a34cb5L,0x74f41f7639fada89L,0x34bf397236e593e7L, + 0x0cc75d461c6179c4L,0xe62d5ba577d711e5L,0x7bec1be7876964c7L }, + { 0x768f35d13809fc73L,0xfe55a9a57dcf1703L,0x86405336e69d3390L, + 0x68f5ea2d00bfc544L,0xd4cf822b4834b2d8L,0x77dc1ac22b0d3ad6L } }, + /* 39 << 301 */ + { { 0x45603dfa0337f57aL,0x50623184344b6968L,0x3fb9957ef160d9aaL, + 0x40eef1697c8db44fL,0xa8f394e98bf71121L,0xa55ecf3b86a920f5L }, + { 0x1f3c1f22bb0822e6L,0xb3c2f21357747a3eL,0xfbdb4465bef56f08L, + 0xa9844890a46ac73fL,0x3fd564a5bde3652aL,0x008cc1a97c653c82L } }, + /* 40 << 301 */ + { { 0xcfebe027ca0a98d5L,0x946b0d9aa8914697L,0x00f89d16725ebd08L, + 0x94c6f2b07a584e8dL,0x095ac9cc911cab58L,0xfc9c3b499c4073c8L }, + { 0x265919b0c7233aa8L,0xe6c0c7f474be5217L,0x6db597f1815a70a9L, + 0xdd9e4a101c5fd35aL,0x38b8e35112d52a8bL,0x5d0ed83f2ef20fabL } }, + /* 41 << 301 */ + { { 0x4f47e10a6c96b43eL,0xe406ab39f3d744deL,0x1caf45d83c893b01L, + 0x4f089452a7582ea6L,0xc02f58cd62b5a868L,0xf6532017c2a9aa7bL }, + { 0xf0d8bf6f32b01bf2L,0xfeec5f68a97246f3L,0xb2ead70a1aa7c238L, + 0x1a1d6f77ad83e05aL,0x4b7110533dca7e9aL,0x44a89fb85f96e5adL } }, + /* 42 << 301 */ + { { 0x86a7ebe0f02461f3L,0x6a7a9cc6862282c9L,0x7f8857944a97e48bL, + 0x191244cd20662db2L,0x8d85175183489311L,0xfbcb17b0f934c1fdL }, + { 0x33b4d86e032a7bb3L,0xa99864cb573f5c28L,0x49fe8e799c4f12cbL, + 0xe34c32e32c8bb49cL,0x5888421e962d6d9bL,0xa317c2d1bf1be44dL } }, + /* 43 << 301 */ + { { 0x3454c424cc1dcbbfL,0x67e61434aac98717L,0xfecd8125cc2d3044L, + 0x2032be70df7f8891L,0x04c5a0c81028059cL,0x6563dc8c76ade6b7L }, + { 0x9ff3815192f460aeL,0x8c2c3c632d54785dL,0x1fa99d8e43eabf60L, + 0xd75d9559383be317L,0xc9ef068e3dfc908eL,0x2217c8c1959d3e6cL } }, + /* 44 << 301 */ + { { 0x5828d71bf2e5f345L,0x8b756075929fe375L,0xca625ec12c43a6d1L, + 0x08cd01f53b31e127L,0x56c622619cfc1be2L,0x093ea207b3a6caeaL }, + { 0xdf53b20970b42dc9L,0x2d2dfdf2235f4aa0L,0xcaac3b3598786c94L, + 0x1ce1f893b4998150L,0x40341c41526a98bdL,0xef39e97eedce5288L } }, + /* 45 << 301 */ + { { 0x08cd60d461ea4256L,0x8031748b9461f861L,0x9c96e1f9019c7908L, + 0x7e6e08f4e46bcf7dL,0x8e8408f123ffa986L,0x0bee857ed467288bL }, + { 0x702fa8536e36fcceL,0x3bb25fa905a89edeL,0x642105f4e96866ceL, + 0x6a5207cc16e37536L,0xcb6a96d1372a3e06L,0xb1c7c85a1da6bc6dL } }, + /* 46 << 301 */ + { { 0x0bb97497a97a3316L,0x9416659ce402a800L,0x79656970503a2314L, + 0x0070a7eef8007c50L,0x8093cd4372624892L,0x4c0ee444f9b96830L }, + { 0xc7c10b9fe300c49bL,0x97f5f90a5f7baf99L,0xf04a5a7cfaa064deL, + 0xd5b01fa6b0c111fcL,0x4d12d6fb65d8a2b7L,0x807a381c27770e2fL } }, + /* 47 << 301 */ + { { 0xcd1aeeb43b6a9c22L,0x7fbdc6c19d71dcd0L,0x9bb43b6e6221669eL, + 0x1b76f2bf526f8a00L,0xaeba54302efdf661L,0xe1f623e745537bbdL }, + { 0x340966ae067c5f4aL,0xe2cdb27e4799b2aeL,0x9aeec5989b8458e0L, + 0x1d0588487655b632L,0xa5ffe5897abd70b1L,0x84db43db6721054eL } }, + /* 48 << 301 */ + { { 0x3b21dc1f538d92d8L,0xc80b22b3c005aa86L,0xf536e5d30da87d65L, + 0x4ce10edf0cd999a0L,0x8949181450e08f5dL,0x77fd8f2e526647e6L }, + { 0xcb207ee9250099fdL,0x03c7d1abfd6aa078L,0x7d4940d225e0cf15L, + 0xb688b311067fa052L,0x89308326a98b2e21L,0x3ee4cc2b72311eabL } }, + /* 49 << 301 */ + { { 0xec49fc4e06d255b2L,0xabd0c002fb309d28L,0x97490ff08c601c3cL, + 0xe17102fd58042cd6L,0x861411f11416ebc3L,0xfb31ce455c6c630cL }, + { 0x0a24d561c6cc5e9bL,0x80bec25c9a7c1524L,0x8003494fbe53e50dL, + 0xe89b75e28633c559L,0xafb1f6d6763b3360L,0x0e7e58c52bf70cd3L } }, + /* 50 << 301 */ + { { 0x72322d26aab6c9b5L,0x953e43d0070d7d08L,0xe2dd5444954645c3L, + 0xc5de051cb276ca86L,0x195d454439158c74L,0x26e2cf9fb90a8f97L }, + { 0x774baec15b217a76L,0xdba4bc63f94172baL,0x96ddaa4022e20037L, + 0xfe1ce4aac111af69L,0x6f6d3c428ad6dacaL,0xe59257d8376cdefeL } }, + /* 51 << 301 */ + { { 0xf2cabe73184d44ecL,0x4bf744d60bb08687L,0x10cb9e9209865d58L, + 0x3a63fe414ea221e0L,0x8f595e5892961becL,0x1b8ad036855d186cL }, + { 0x75dd5f70086542abL,0x8b357e087bddbb6bL,0x22de89f06e829a06L, + 0x44ca8b64ecc6cc26L,0xd02fa871a5ddebb6L,0x6adf1d0c6a60a0e3L } }, + /* 52 << 301 */ + { { 0x0102775982e4f5c3L,0xac8eac172c014fc4L,0xa0cd26e85bd843eaL, + 0x9b0431ec056d4b1fL,0x89df7db58eb9c55bL,0xf17f917298fc9b9eL }, + { 0x2cf1e4a78e6b770fL,0x0d6ef9e2b842fe52L,0x40b4ddb76c578172L, + 0x6630657627533b9eL,0xf8d8661eb50ce390L,0x6ceba0aa16577df7L } }, + /* 53 << 301 */ + { { 0x6dff66c19ec8ac93L,0x6261295bfdf6fe7dL,0x9ad1536fcf9fbbb2L, + 0x5cfa30a92a6d6d31L,0xb3bcf1b0296224dcL,0x42e4b410608371daL }, + { 0xd6bad6dac32945fdL,0x0fab7d1dc0c031a1L,0x054df9599b192d32L, + 0x29830094ea78052fL,0x8d73ffce03f2ce45L,0xc14c7012f9d840ebL } }, + /* 54 << 301 */ + { { 0xdf74522e74ce5c21L,0xf864cbac930c4b92L,0xfe0d2358eb0fbe9cL, + 0x10b31736a5cf765aL,0x185bbbe96a9c95c6L,0xcb14d694e5362993L }, + { 0x3f5c921da5332e61L,0x0820b32bd244cc98L,0xdaf09f24d7c32062L, + 0xb2241c9ad5959a1cL,0x16bb89a3226127ddL,0x0b46e3f03723d04dL } }, + /* 55 << 301 */ + { { 0xa38b1a796975230aL,0x25c6db8c3991b5ceL,0x0d89c3fe9c1bf52aL, + 0xe186e293cd8f9f8cL,0x777bb327e6ec37afL,0xa974132a0ae31c7eL }, + { 0xfb9918305c50f089L,0x4a653d6999497954L,0x5055c690774e8a26L, + 0xf94ffbae3815d67aL,0x99d74f5e74ea4481L,0x3b352a327d477151L } }, + /* 56 << 301 */ + { { 0x2a62804172fb61e9L,0xa9bfa73ab13d053fL,0x4a2cdaa3c647fcb9L, + 0xe1a9e91f4952d3a4L,0xbc1b3d8011e2e2c3L,0xe58ef59c18e4340eL }, + { 0xeb8696ff1cf859b8L,0x5b0f5cc4ee918cf4L,0xa471d6ce6c1e905cL, + 0x4e13d6091ed2e8cbL,0x52951509c77c8c91L,0x0926dad8e234884eL } }, + /* 57 << 301 */ + { { 0xb168a6c36e3aa3d7L,0xbd0086ea5ad9142fL,0xbc4da0293c24fe23L, + 0x7ed3b34808b90de6L,0x7a7a2259e33b0df9L,0x483b389c9c3a173dL }, + { 0x02080c626334a061L,0x61944965b020cfbeL,0xece528e9ede88ecfL, + 0xcdf3e2fc99389758L,0xb21470cb7a3fb92fL,0x717cfbe083937e21L } }, + /* 58 << 301 */ + { { 0xfac97f2910e3e93fL,0x1505c7d2f1101b88L,0x7cea978823bc0d11L, + 0x27ead95d45045667L,0x711bc4dcd17ea199L,0xe3f93fb522f3142dL }, + { 0x31b05e6ad7233d64L,0xac28e6c154e7c9d5L,0x892b6366716d273cL, + 0x1622230470da8a48L,0xc85bbe6070d560b3L,0x555e6de987fd38a0L } }, + /* 59 << 301 */ + { { 0xac593f746ed50680L,0x89bdeabbcb01cfd3L,0xfa43158ead35524dL, + 0xb2393726e8d66ca0L,0x248c67c2c36bb495L,0x27d4b0b85c933625L }, + { 0xdbb1364a78c8bb4bL,0xdcf4b1e13486ef0eL,0x554f95cec498b2c9L, + 0x2b76da29811a2329L,0x750c10271a10d941L,0x07045eae375b01b6L } }, + /* 60 << 301 */ + { { 0xd3fb9bef82621500L,0x09b18748f0f647a6L,0x186bed054c357e73L, + 0xd58281f0a85f3174L,0xdcf2e0bb91ded0e9L,0xe77faad126894faaL }, + { 0x6843c160bc3a3c4bL,0x7f8058944c76592dL,0xc53be0883ec05e95L, + 0x318d8ce7cce0c822L,0x6d615f1b4c761dbaL,0x0115824c46ff47e0L } }, + /* 61 << 301 */ + { { 0x1815391cf8d0b74bL,0x903ad8fd797625dfL,0xad1ca24d3983100eL, + 0x0883fd415572ff15L,0x0e9e572cadeb4e56L,0x800bad6f7d0e25c4L }, + { 0x52a394b44c7e2f03L,0x5150c01398f2c416L,0xf4ab35c68ce503c4L, + 0xa0ad209a41b4beeeL,0x050c52c80189706fL,0x86780a924049e913L } }, + /* 62 << 301 */ + { { 0xa398529c74ded2a1L,0x5e7248f52d7ea6e5L,0xbeb250bc28c2225aL, + 0xf7068fc0b40f4843L,0x62098aed839b7290L,0x947087e293ddfec4L }, + { 0x81ba8c8824d71004L,0xa877f443bf4813c2L,0x3cf5f473ca4751bcL, + 0x2533890e633cc635L,0xb358f7781e6d9465L,0x50693deaa7801dc7L } }, + /* 63 << 301 */ + { { 0xaf306f56cbebedf6L,0xdd733be7837acb84L,0xc767237afcff0b9bL, + 0xdf948f12e555bee9L,0x86b85657826dc76dL,0xa4bac032e702b1c0L }, + { 0xdf3544bba81bb117L,0x69c20dff34f4f0aaL,0x846b78577050d98dL, + 0xde0ef0403c70120cL,0x4483872c12c3bd64L,0x870b758550acebacL } }, + /* 64 << 301 */ + { { 0x37be5d3f68d7dfcfL,0x97bdbd49b945e6f2L,0x165a24b59d1569e7L, + 0x254aaf59b4e293abL,0x3c751fbd6fb7c0a4L,0x14eda4ba5018cb18L }, + { 0xacb3b8971b5f6aedL,0x6d10be441e4b6b78L,0x245d7258621df6d7L, + 0x2af0e283185f0e2aL,0x1e7edc818fddbd81L,0xbd1e6c72c538d02aL } }, + /* 0 << 308 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 308 */ + { { 0x6858b674844626a2L,0x610cd40f0cbba6a6L,0x324e674e29d9194dL, + 0x2dc6fdf6dcb30a51L,0x3f3ecb77528aa549L,0x0721f8f923ffaa92L }, + { 0xd8efcbd627a77538L,0xf4e642bfd6162c9cL,0x04f2b0b74cf4a16fL, + 0xbc0bb49fbbf335fdL,0xc6b6e5bd5a928c36L,0x981b01f4d893dd45L } }, + /* 2 << 308 */ + { { 0xfb083c2af810465bL,0xb66a8de902ce0deeL,0x6e4130e747a81b95L, + 0xcd704dc658a98737L,0x842ae329592829c9L,0x99bedc34be20dd63L }, + { 0xabee8e55d53b2df4L,0x6ce657586010b37cL,0x781f39b2467112b9L, + 0x6f06058fbe341038L,0x5effdca512a2f8beL,0xaa9bdad7af34466eL } }, + /* 3 << 308 */ + { { 0x3933b4c1575782aaL,0x610d3ba25c66e501L,0x52fd3c0f0b7e019dL, + 0x7f8e5ddfa48715d6L,0x0879c5defa39be53L,0xe32c886c56f01cdcL }, + { 0x71b2dcbb1726779cL,0x6caaff052c6aa84cL,0x6af94846640b2d74L, + 0x78a10710049a2cbeL,0x41a1ce67ac2ab0f1L,0xd160b7faa76d8438L } }, + /* 4 << 308 */ + { { 0xab86639e9c216137L,0x45a12fb882b18d64L,0xb5734418d763f0bbL, + 0xd2cc332211a9802cL,0xe41d7db881269b8aL,0x91072fc12ecfa355L }, + { 0x59d6912504ce306fL,0x916d9d4da131b86dL,0x84478b6b8a739738L, + 0xe86ad7d91cc83ae3L,0xbc9b2084797ccd97L,0xc1e94af4694944c6L } }, + /* 5 << 308 */ + { { 0xbbb6725b5c82c857L,0x72c66c3f140b561eL,0xab65dd0664bcb2d5L, + 0x755e848a780d5c1bL,0x84e6f686a3a61e6eL,0xd84bf486bd100b4bL }, + { 0xb34fdf846354e899L,0xcbc312da55ec5654L,0x3c2cc881f9a125f0L, + 0xb1fcce564aeadf8eL,0xbdfc54c0c46bf0c2L,0x11d7ea4f09d281beL } }, + /* 6 << 308 */ + { { 0xe1aa844b1601940eL,0xd22221821797e84fL,0x3025aba65ddcb5d1L, + 0xac8cdaba38009c6aL,0xb9ee07b46e261ee5L,0x84069bc106ab8430L }, + { 0x7a36b46278b9b112L,0x2d91ed2c08e77879L,0xae4ef469341275a1L, + 0xf7cb393f1c7cf858L,0x83c00eafd192af3dL,0xa81697a7a1e15176L } }, + /* 7 << 308 */ + { { 0x687d0980f9bfd795L,0x9a7539377ad882bcL,0x641407fabbcde5b3L, + 0x12ec9d216ed103a5L,0xf858c7851fa6ee22L,0x329b61bc818f2c11L }, + { 0x4720d42ad9d48b30L,0x3f61c66082a66766L,0x99aff25533723e4eL, + 0xd6c67ce3d3260b62L,0x63a6fc9d86391c33L,0xc002433a31de2381L } }, + /* 8 << 308 */ + { { 0x585edee3895c0318L,0x775e142f45e8205bL,0x3bd7924fd85ad31fL, + 0x2e7d8f919124bffaL,0x885397c044c62868L,0xc0c2dff47fda9f5dL }, + { 0xd302582ec14e693dL,0x53d6e33a6cec31baL,0xb0216b5b63653c06L, + 0x8f08a1ad9c70dad4L,0xccf014aaffbba93dL,0x900b0d2ca33f12b7L } }, + /* 9 << 308 */ + { { 0x4960ccb6e9824c45L,0x3c5a9b74c7e4cd06L,0x1e78cdfe37cfec62L, + 0x8cd49ca80da56a05L,0x5ba51217dca05707L,0x0d1f6e459d66c960L }, + { 0x7178089467f9c82bL,0x342e4a5b18974c55L,0x16263f18f9b32fdaL, + 0x844b5a02935b3636L,0x9c5abd51c139ea58L,0xf54c69428beef953L } }, + /* 10 << 308 */ + { { 0xbe51552d6d2dedd1L,0x6bc86dc1cd997093L,0xc9b600c4418f03b8L, + 0x4ea4e857e7a9208aL,0x7aac3d96883b639bL,0x4127ed0735d2f4bfL }, + { 0xf5f6310d76bd792aL,0x3da9b6a5fa223d0cL,0xd75f88075a041b79L, + 0xf3261457e4dd58f6L,0x4f0f5b18b0d9a51bL,0xf5aeedc1b8c84f9fL } }, + /* 11 << 308 */ + { { 0x1e08d6a81375620eL,0xed9a4fbae1f62c24L,0x0d3bb90381ab5de2L, + 0x885781f0df1b6a13L,0xc3fb9f97e1c7de7eL,0xf12e4bcf9372b033L }, + { 0x9bc3cf4dd5868448L,0x89465649552016adL,0xeea40cf92a8b2c23L, + 0x57d720ee3af98886L,0x97b14c0b72db853dL,0x65d10f42f23504deL } }, + /* 12 << 308 */ + { { 0x0dd2395e9b8cfa41L,0x50e203abd4f92a44L,0x7280aff16630023bL, + 0xfcce59dc07de820eL,0xa686be05bc8189adL,0xac4b59bfaac70b7eL }, + { 0xd2c0070e7a3c71acL,0x1d550add35ac1c47L,0xd42b6389fb881c1bL, + 0x57ca3fccd0dafd42L,0x909e8284be26ccc9L,0x1abe7595a002235cL } }, + /* 13 << 308 */ + { { 0x02562f1c6b1878daL,0x52a2cd069fce0ee6L,0xf25b35bdeb16199aL, + 0x0320c326a75fb01eL,0x2006d7587de2d46aL,0x6f9d0e256842b459L }, + { 0x70a89562a68b5482L,0x9653726e1ab35865L,0xbda3cebbd8f849adL, + 0xe2f8d9e60b6fc51dL,0x9c3fd51246104400L,0xbbd260c9bab5d34eL } }, + /* 14 << 308 */ + { { 0x1f5094703cbc1df1L,0x9f752a663f962634L,0x98089d2ca2435048L, + 0x05256acb0e755318L,0x91a21f707f3845f4L,0x473ac1e0d68c8fcfL }, + { 0x57ee51417f2ff0c9L,0x959a84f32013c48bL,0xe701f13c4c111ee5L, + 0x70219eee86db5763L,0x385f890cdb0782e5L,0x81fb64b2fea04d2eL } }, + /* 15 << 308 */ + { { 0x61b4bf7eeaa07bd9L,0x49832879afe544c0L,0xf788e97f54eb4d80L, + 0x78351b41338af327L,0x3a631bba77cb8057L,0xeb9a6f23f218e4ceL }, + { 0xbd4a0dcf025b6453L,0x2aad6a467b876222L,0xaee94361215c42cfL, + 0xf8d1fd5de496cddeL,0x3c3af08022d0fe06L,0xb3d5dde0d09cc3f7L } }, + /* 16 << 308 */ + { { 0x1e34781aa6a1913dL,0x9a8f32287d0adc38L,0xfc185ccc28af85baL, + 0xc923d78b3ae9ba11L,0x7d494d7ea7bdb313L,0xf774dfa5af8f8b87L }, + { 0xc178ccc116e863b8L,0x2d472f2aa8899691L,0x608747cc80a50372L, + 0x8147aa90e6f90197L,0x4683d4c978c2f216L,0x8323652c552f3b51L } }, + /* 17 << 308 */ + { { 0x7d6bff984dc9149fL,0x79879e1f499b443dL,0xf4ec65232aff2a1dL, + 0x6cf3c97f27253aa1L,0x95b9471eefe6f72cL,0x3959bd816c8457daL }, + { 0xe2870635cf112073L,0x84e44933ec12174fL,0x67a592deedf434edL, + 0x0c93cdae2897d0e0L,0xe344ecf463c89730L,0x28098b7567a1133fL } }, + /* 18 << 308 */ + { { 0x62e96dc7a12a0cd8L,0x09d7c6f0f02a3d87L,0x9d9fd51233f8929dL, + 0x1231952dab376555L,0x6ef6823c8e3d2d63L,0x7ad2e5405a01c12fL }, + { 0xd1bfaec479af6fc8L,0x4555fedfdad97daeL,0x0e6d3f0155750bdeL, + 0xd37ed9f0056f6128L,0xf1fdf91c65fe6ff7L,0x3ece19ae92d05e43L } }, + /* 19 << 308 */ + { { 0x07d2075e750fc5d0L,0xdc2b03f6a07ca45cL,0x0248d87552efef7fL, + 0x2dfdaf3f744e727eL,0xbef861b8d9b2bcacL,0x5e6363f0baf394c7L }, + { 0xe8f23bbec973934cL,0xb43d619a50ea324dL,0x2bd5e0075842d6cfL, + 0x5c5af62217646e90L,0x5d95d8fd222ec05eL,0xc9adabb45bd67c31L } }, + /* 20 << 308 */ + { { 0xa5c08e8bcc2c9a2aL,0x70e1b4058baaf0fcL,0xf29e1e5c9e36e50cL, + 0xa3d9080080f258c5L,0xc9ceac25ecad4498L,0xcb73130fca32f3feL }, + { 0x2dbe620c48b3863dL,0x8c52727f14ff53bfL,0xb60b22a86b45e9b8L, + 0x81e05bc0f6483c5dL,0x217caa6bcd542972L,0xffab716afa780778L } }, + /* 21 << 308 */ + { { 0xaef1278b0ba5a344L,0x253be7ad2d0c3947L,0xce58bf0fe5408f09L, + 0x867b0d6fe21228f4L,0x815abb5dca61e691L,0x0da28f58f3e94434L }, + { 0x5b0fd178ca4cee2bL,0x8989604240b13224L,0x8e2fe19616c251a7L, + 0x7b3381cb11b17162L,0xc73d96a427ef2c0dL,0x76b7fcf36899c135L } }, + /* 22 << 308 */ + { { 0xcaee3387cad8b585L,0x58446c1ad59d8777L,0xb8755fa540888d8cL, + 0x7868510654428813L,0x7bd21629136e2b59L,0x249903a6998254a3L }, + { 0x2cc73a751f8fd813L,0x4b1a64576d4f3a70L,0xea2aa620b2e7a0fbL, + 0x77c8cb98202f6ddcL,0x68ba9d261e3851cfL,0x936fe8cbfe02e6efL } }, + /* 23 << 308 */ + { { 0x8b84121bda75aba3L,0x4440272d74602c33L,0xb8110b2a1e8a8ab0L, + 0x4de462e9391cf47dL,0x9173d756519b9ab4L,0x3df52d13ba8d5dc7L }, + { 0xd7a822eaa418b01fL,0x58be2b076585f7d8L,0xaa814fde00fb449fL, + 0x6b8260fc7da43c5dL,0xaecbfb442351ba9cL,0x9cbe3d199f8db60aL } }, + /* 24 << 308 */ + { { 0xe5d3e0d80d7410d6L,0xcfa9ed742be432c9L,0x60044434a85a0686L, + 0x93b357166ad6918aL,0x1a3c3e6d051762beL,0x80813589b0ab32d6L }, + { 0x64214b92aad403fdL,0x684befc14d3fb746L,0xaca5a51479515046L, + 0xacdba03472e84485L,0x61aa2834287d9e97L,0x07a515a5cad222e7L } }, + /* 25 << 308 */ + { { 0x8f631b17bc04e9c5L,0x017527212c515161L,0x4358d8e9ee7769a5L, + 0x18f0aed0b59dba1bL,0x035c6bb644973218L,0xa49a4cbcfb3897e6L }, + { 0xd2a0b7505841ab18L,0x8fe952dca6d2d43dL,0x2d30add69a71d0ecL, + 0x0cb84c402c5d440aL,0x33f3cf7c7c47846bL,0x88703c65bc8e8b3dL } }, + /* 26 << 308 */ + { { 0x3c3db9419474059cL,0xcfbf13ad72820ae8L,0x3f84300c51c37d62L, + 0x0f78adc45529d333L,0xa19be46482e34cfcL,0x9ed07ee011c98376L }, + { 0x5113e660b5b6f6beL,0x56f2d2b37a5bc818L,0xd99290c61c2c822cL, + 0x39c026b8b27aafceL,0x8692150b12ef7c76L,0xa55426d1c6de9e16L } }, + /* 27 << 308 */ + { { 0x889aa8ee3465358fL,0x5885ee29afbefa70L,0x05f9dbd290b6ff58L, + 0xc74be0d09b5e02afL,0x4b7da27ea6b29d44L,0x2ad60aefcf68eeddL }, + { 0x2ba942b3388c81c5L,0xda8badcc368e2e62L,0x33e95ac87a9e8511L, + 0x37453bbae72008b3L,0x3e1f181195eceea0L,0x719f550c7b19a417L } }, + /* 28 << 308 */ + { { 0xb03093068af19670L,0xd784125a34c6bf0fL,0x0b425ee0255a8396L, + 0x91076433fb541162L,0xc4d8188586f47a0eL,0x3b767d54fd7bc7c1L }, + { 0x98b405d3bee196e9L,0x4ef9c511edaccf4aL,0x5a6deb6503f4f1a6L, + 0x4a22ca641b4c5104L,0x2cce36679145ce41L,0xd05187523206810dL } }, + /* 29 << 308 */ + { { 0xa5746e07f7e11342L,0xb50e390f2e2ddca0L,0x3847749bcb288bc2L, + 0x6ff43ec646ee679bL,0x343b3fe2c5257b02L,0xc0f57f509b823eb7L }, + { 0x5ce3d2c8aff42c7dL,0x984c9b99c3c76f3fL,0xc8559f58b8823b92L, + 0x883ac8064ce4338cL,0xecf8aac3389d8ebbL,0x9edaec10b40bfb16L } }, + /* 30 << 308 */ + { { 0x0ed8a07cafb04e5eL,0x7e95ed898f6bc911L,0x6a4ed37113dcc222L, + 0x9aa3a43296f07c7dL,0xe819a80b9b338e4dL,0x65fc2778278f53b5L }, + { 0x788408e9024163b3L,0x159de8bb7de54f06L,0xc953e21281239dccL, + 0xacb5ea2c6dd62ce9L,0xf56ac93b753f4ab3L,0x2a1a09b5eacc39a6L } }, + /* 31 << 308 */ + { { 0x89dcbf021c5f4cb9L,0xc0fbe7ce210f98ffL,0x3dc3c743b897cdf2L, + 0x931f9dbb5d02c43fL,0x0ea9f164f74db981L,0x504938874af9f53aL }, + { 0x86bd3ed62531b8aaL,0xcc1fb6dddcfca2a3L,0x24b0cbf2b97abaa9L, + 0xd81ad35c9073f19eL,0x4dde5dc05db7fd5cL,0xce410880e3ac9b63L } }, + /* 32 << 308 */ + { { 0x29d81538037bebadL,0x76e52c73d9e0b78cL,0xaa4ace6e8783d1fdL, + 0x9c14ebddf0e3c126L,0x0eb1c08d6eca4b71L,0xd10c6b961c91df35L }, + { 0xdb8119bbe81bb84aL,0xf784d3c117e3ceefL,0x053c916835436f81L, + 0xeb41ccbb9b18d212L,0x93b3fb43b1bc3497L,0xd85a7c758c1ced81L } }, + /* 33 << 308 */ + { { 0x90b606b2fc9958e6L,0xd39965b6f94234b9L,0xf4a86f1676f4dd03L, + 0xd6a7ba54470f0f7aL,0xa1b85c0ca86fce7fL,0x2b50f14e574c4cfdL }, + { 0x4aff867d80e783bcL,0x031092eb61f78fc4L,0x8ad0d7486fe0af1fL, + 0xb56b1a1a0cdfa574L,0x586c916a56466e12L,0x427e5946d09a9d1bL } }, + /* 34 << 308 */ + { { 0xdd0e3ca276d1b2e5L,0x07dea7e48b4cb3a6L,0x62a63cc7fc4a0f0aL, + 0x048478ef5ea2eccfL,0xa77eae472e34c1a9L,0x7a2120751bfa5dc6L }, + { 0x0c1fbbecabc233ffL,0x6255fd91dee18d7fL,0xd6da39aec38462ebL, + 0xd86bc3194be435f9L,0x23567d64291c606fL,0x6b85038af67051adL } }, + /* 35 << 308 */ + { { 0xbe79e1b1eef4ae7cL,0xa45668dc42fb7357L,0xcdb3b3ee2d497a36L, + 0x6ef724e6c5f8d861L,0x7e8834523802a324L,0x641b3a81aba90442L }, + { 0x13bec555ae4c2544L,0x340d34f927d172ceL,0xfcfd933bd92f558cL, + 0x57d8e300d5a669bdL,0x9f745ce71883049bL,0x19690a31e261f9ceL } }, + /* 36 << 308 */ + { { 0x004105c3811af84aL,0x01307934a7934a0fL,0x179fd49b9b3226a1L, + 0x195d9e5cde6834b4L,0xfbb79dc00e6051bdL,0x354273ed367f4487L }, + { 0x4afa9d4574fb892dL,0x03ae905ea1b7f3bbL,0xea32cd5d592f6122L, + 0xa758eed2f1103301L,0x9dde4238c59d1cc8L,0xe2760bcc51022a42L } }, + /* 37 << 308 */ + { { 0xfed7077b7a7134a8L,0xe65b4eaefe0cf05aL,0x130de76be626841bL, + 0x499934ca300117fcL,0xce74885d4e186b5cL,0xd352d0d2029bee7bL }, + { 0xd86c448c857a38ecL,0x8139eb50a956da9eL,0xa036de4a93ce7131L, + 0x3f9eba375041c9d4L,0x8c24408e548f74fbL,0xa74053fde942bf8fL } }, + /* 38 << 308 */ + { { 0x64cb00f586ff10acL,0xd1eebc4c9cbba8d8L,0x427fad8af3157125L, + 0x9f8eb84cf7523b0bL,0xbdd082bf2e6dc29cL,0xfe40623823d3c315L }, + { 0xad5df7fb546d9dd4L,0x83cadc4b8e42f3c7L,0x7c90502c36876485L, + 0x4f33eccda35bb6d2L,0xdf7571383a79b9baL,0xd250b7d2e6ddafaaL } }, + /* 39 << 308 */ + { { 0xa52a7595504417a1L,0x540f70b014683af9L,0x5f0d1560f27a9620L, + 0xccad06444b2147c9L,0x92223275e52c8eccL,0x30d6b52b7cfedb7bL }, + { 0x2161f8bb9bb5b844L,0x075b9db87033586cL,0x5748d512c8c5189aL, + 0x95d76a950f0aab91L,0x91f85aaed0ce9c56L,0xeab8cd9b8434e695L } }, + /* 40 << 308 */ + { { 0x54f84d70d377d7b0L,0xb745d1903344bc4eL,0x1c693ed08f33aa53L, + 0x990ed45f8bfbee7fL,0xad620c9fe9b258fbL,0x465ccb101a54bf46L }, + { 0x5330a0d3ebc40951L,0x34423e8ca405da61L,0xeef1ce78b83043b6L, + 0x99678f22ac06d182L,0x9213f57d1802f14cL,0xf8549616adf11fdaL } }, + /* 41 << 308 */ + { { 0xc6ca95476c66fa6eL,0xcae41345bdd5b16dL,0xd72a41a4ef022783L, + 0x810f4615b2d5154aL,0xfddc469e6d333af9L,0x3154ccbb02d2bf38L }, + { 0xb33d5c59fc1a0bdfL,0xd8c3f8743c971fb3L,0x5e47ec01114e68b2L, + 0xa440a83fe9baa164L,0x353d01c397c26b35L,0xfaabf5dff03b7672L } }, + /* 42 << 308 */ + { { 0xdc2a97651e22de2eL,0x91eef436b6cd3b6dL,0xff099200f99ac721L, + 0x20faacfed4f89e8aL,0x91bb24373fcfe45cL,0xb7a152897b6d3ff6L }, + { 0xfee966c0ef94332aL,0x944728473c81b942L,0x831d36dfab1a553fL, + 0x244bc8393023cca1L,0x3f4a49d57e7be940L,0x4159aa9d7b71c0e0L } }, + /* 43 << 308 */ + { { 0xfc25fcab5b16ee64L,0x44f807e06841acd2L,0x5f43cfedf59c3f06L, + 0x9279c8110c5b59a7L,0x825df117194b80beL,0xe2c18880d27d6fa7L }, + { 0xc9aab2e66a333721L,0x1665b6f55b034c1cL,0xf28fffd13df9796cL, + 0x23caca87bbefb8a2L,0xfc556d575f7510f0L,0x41990ce8552dafd0L } }, + /* 44 << 308 */ + { { 0xf31796d2b6e392e1L,0x199d624893b3395eL,0xef14c7c212f9b763L, + 0x721ebf2143edb7a5L,0xa40b88945e96f3baL,0x8770608c4cff8394L }, + { 0x990c99ae8d0def0eL,0x292b26dfa15a5649L,0xa98fda2c91ca89d7L, + 0x916cb1b4973e5f5fL,0xa2823f13a72de0bbL,0x415f7bd28cd3219dL } }, + /* 45 << 308 */ + { { 0x5cfde16a9fc0e90fL,0x61bda4caac6c15d3L,0x5935e48e2a79d928L, + 0x31213c7c82f986eaL,0x170dc539bcc4c0dfL,0x2e0d29406f11823cL }, + { 0xd2dbecac80fe659eL,0x98b7f46b8399d8b8L,0x259f975abb204589L, + 0x65f3073cd5c52a46L,0x0f4c007805dc7fc4L,0x16c49d403031a8ffL } }, + /* 46 << 308 */ + { { 0x95705b15359816d5L,0xce0c4379d0641ed7L,0xb3f0d8321e8a448eL, + 0x8bea060873e2d711L,0x5a85fb2f6a040c03L,0x7c19a2185bcebd4aL }, + { 0x2b10a87aa31cffddL,0x4fc728fa9a5814a2L,0xedabb0dc63bdd2ceL, + 0xdb90173f96bdaa40L,0x543c4f01527ff659L,0x5dbff7ad0a33b251L } }, + /* 47 << 308 */ + { { 0xeef30ea55e636f5dL,0x8df2d4040bccc4ddL,0x8b0d6f35ef1afe9fL, + 0xbd288e6ef8f86f6aL,0xbc68817ebda45411L,0x8a6f50070faf9e7bL }, + { 0x6158c57a53d4050cL,0x6d5a3af165b2252cL,0x10f62839f450886aL, + 0x8b9ac19b1df85080L,0xc160c1567553ed58L,0x2195ab29cb449cd9L } }, + /* 48 << 308 */ + { { 0x521f4af73ed03d5fL,0xe3461f66eaf9064cL,0xad099ab7ae03777fL, + 0x541cadcdb65f73ffL,0x53430463a86059b9L,0x8ff88fe5043e9f82L }, + { 0xd515f4c7e42cde45L,0xf7f3dec3f41c3269L,0x7bed53567ef1b8ffL, + 0x8782b45f1295b5feL,0xab54ebaa03917627L,0x8516beb28787ed9fL } }, + /* 49 << 308 */ + { { 0x24b2b95b113940daL,0x8c24d8d3f9c6e6d1L,0x7c584170eddaaf29L, + 0x249267171efd01aeL,0x692cf8f40cd0f2d5L,0x0bf82e142f960244L }, + { 0x6dbcb6162dabe927L,0x76d826d20aa1eed3L,0xe4492fb3be98af99L, + 0xd4f27cbea50dd711L,0xb7796efe2d8085daL,0xf2d42519ec4e8ec2L } }, + /* 50 << 308 */ + { { 0x3fbaf46dccc3c261L,0x773c240c1b646e80L,0x151a711f363b6a5bL, + 0x3c8680b1c53b5b59L,0x8ee6795f9fb234b6L,0xab7840aa2f673211L }, + { 0x0a1a0ff3224a8184L,0xcab87319c71bb575L,0x7a9e9daa8125668fL, + 0xdc607b016c4cff5bL,0xa54cb4c792e5c760L,0x977e4c93d99e4655L } }, + /* 51 << 308 */ + { { 0x87d4ff71ebe95680L,0xa2093915e5adaac7L,0xd5bbbdade32f5d9aL, + 0x5d61056cf328a4e1L,0x61fcdb0f353f565bL,0xb7b8ba004efab5caL }, + { 0xb5bbcfa410f05eabL,0x483ae9221f09a105L,0x17d94ca44bbf4753L, + 0xf734a8cdbbdc9a94L,0xc7f01a4244e81e2dL,0x60c3e777b3ba8033L } }, + /* 52 << 308 */ + { { 0xba7df5a965b68624L,0x30b4d6ed6e7d58bbL,0x67e52341dbb81762L, + 0xd697ab1b0deeac1dL,0x01d15e8e5577ea92L,0xbb12d72498fb38daL }, + { 0x302faa6d4e04908dL,0x66cf6cb909b90a9cL,0xcd665dbd98d96736L, + 0xf7d3c528b86f3af4L,0x4844c7541d8b07f4L,0x2a77d7b91eaf7dc0L } }, + /* 53 << 308 */ + { { 0x8a36c9b57fceaa87L,0x5110912b553c7ad3L,0x4aa51166d5eca67cL, + 0x05740dcf07a5eb58L,0xeaafb3e3396857a4L,0x1ae9571bba8d62d9L }, + { 0x2736975500272434L,0x2c74325c59872fbbL,0xd1d8291709dda11aL, + 0x2a5334eb4683e8a1L,0x22cdd088e3481df0L,0xab1c5f5b4fddc546L } }, + /* 54 << 308 */ + { { 0x1966aa0515f46174L,0x495901bd2a074050L,0xda5b0cdebba902baL, + 0xc47c518a684325bfL,0xa5df133ec4d9d6d9L,0x3771f465fbf7d31aL }, + { 0x0a73718c02b05d1aL,0x1107cd45534237a2L,0x582cfd2980f5d897L, + 0xf51a0a88dab0269eL,0xfdea51cfea1a22faL,0x3c9a0d247a13a324L } }, + /* 55 << 308 */ + { { 0xcc330f58c42f1ce6L,0x8e1fb7df534efc38L,0x2a37208f5fa5a01fL, + 0xc06d8447369bdbb6L,0x0b1ea5161a3e36e7L,0xfb4a48366ff9abbeL }, + { 0x5989c2d524419909L,0xdeaa6136f1d5b1caL,0xac6003b04ba760f1L, + 0x3a6d5422059081beL,0x96c7fa9df797e22dL,0x67c2f77fa9f3addcL } }, + /* 56 << 308 */ + { { 0x53e59f251d70eb73L,0x8aed17afe69d0525L,0x26ddc17864413768L, + 0xa7c8d40f5e48c349L,0x29ad92d187ff01fbL,0x8f4e1b3b965b2de1L }, + { 0xb83cfadf1446eca2L,0x7432bda4e609d416L,0xcf97e8a3f1c7de69L, + 0x45899bd832f55f07L,0x41a6811751175738L,0x89eeb115b8efff21L } }, + /* 57 << 308 */ + { { 0x9dcda4f3723fc25eL,0x710de79fb5d954deL,0x095ffbf1f0b7d129L, + 0x419a2a5e32651179L,0x7b249135827d4268L,0x9dccc98d909fbfb4L }, + { 0xcb4b0cb016554ab5L,0xb2fc635f6d84b255L,0xa7f8f3f553512b87L, + 0xc72633f300ec778bL,0x4e07d91a4f1841a9L,0x2a1adbbdcb4f478cL } }, + /* 58 << 308 */ + { { 0xe31333093bb794fdL,0x34c68bac33b3be44L,0x953fa2c412172b7aL, + 0xa9afc12d4fdde6ffL,0x30b5302ae9c7804cL,0x4a1746c702119e68L }, + { 0xc4d0c7d323e2ec51L,0xbc821f217143d613L,0x8f41251a673e203dL, + 0xfa32c06aac2ca4c3L,0xf4343f2799a7c431L,0x8f7d489e6b96d959L } }, + /* 59 << 308 */ + { { 0x183311763f6278f9L,0x4fcc5b653593cdd5L,0xb09b5880e643f83dL, + 0x0f130a3d2c78466eL,0x926d7c3d2b1c1ebcL,0x7217f875662ed4ecL }, + { 0x2d3be028d81cdad3L,0xb2a04e3507a38019L,0x8da8cddfc9a3097eL, + 0xbaa67f60ddb20228L,0x698fc1c407f04de8L,0x6f0e1d6d7e86db6dL } }, + /* 60 << 308 */ + { { 0x54a01e60936c3ebaL,0xf326fe96ec01b12cL,0xcdfaf00366e4de2eL, + 0xc53dba07392fd0a8L,0x00d9b80f6ec46004L,0x84d59be83ba63f8dL }, + { 0xbac4ea439dea6062L,0xb4b4845badd568caL,0xa6ca3d34d225e2d0L, + 0xce72955db50070a2L,0x56e5c91321c78b68L,0x888eb198999488a3L } }, + /* 61 << 308 */ + { { 0x65bead3c1c2de335L,0x0ecdc057b18a6778L,0x821b836983e57ea8L, + 0x84c80b574a5c11dcL,0x0b6432822ac9ad27L,0x8e09a7f344fe943fL }, + { 0xe510f47daa92dc94L,0x8bb0b5cc6a1666a3L,0x55315bcc24645380L, + 0xe3acbed113dcf7a1L,0xff99c90e3c9a1610L,0xfbe9aa1bc326e1f5L } }, + /* 62 << 308 */ + { { 0x5040bea56827b6e3L,0x1049e004d935eb24L,0xa15f9a07ba9bde68L, + 0xda430c55e6087e70L,0x30ed69af8e84b7c8L,0x8498514eac9d6a72L }, + { 0x69c783d64cb27e79L,0xe55d31a09647a572L,0x0479e8b2fbfb82e8L, + 0x3e845922b52f08c0L,0x252f755f0dbca622L,0x6219778389ddfee8L } }, + /* 63 << 308 */ + { { 0x175264893ca1461fL,0x54c432f92b6476bfL,0x0e0be36a530795f9L, + 0xb9896dacca583429L,0xe4af98239d4e6085L,0xa38b7c4b4a7422ddL }, + { 0x74643ef47163e421L,0x74c28314895ee61aL,0x637c79c20d62b657L, + 0xb232ec619bf2b3afL,0x27bdbfb4b2d5992eL,0xcc6e424c49afb181L } }, + /* 64 << 308 */ + { { 0x5255508c11c92f34L,0x9a346cf3a294d382L,0xd9765eea3095205bL, + 0xfea2ed702c470ef7L,0xf5e8a0fc9c40bf0aL,0xb572390ee4137a16L }, + { 0xb91753712bf2f545L,0x2c2d0f4c58cd9cc7L,0xbea6bce902385486L, + 0x46208408a8bc3a94L,0x64a87a2a3ac45044L,0xe40da33c7df70151L } }, + /* 0 << 315 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 315 */ + { { 0xee9e25d939161b8aL,0x8763f2a2e2eead91L,0xd2fc1157d2d91300L, + 0xe7597e2fffcbe50fL,0x4be3814fe11d376eL,0x1eab3d7edbf14562L }, + { 0x38a107c0c0ad183aL,0x829766267c753bbfL,0x18014e09caebd481L, + 0xb28c331bf9ace60dL,0xe8fba04f211cb8e7L,0x41c4b797e42dc65eL } }, + /* 2 << 315 */ + { { 0x009dc2f4c3e88580L,0x4a405be899db1fb5L,0xc89bfaa2ec5d91feL, + 0x461be9a0f160afcbL,0xfdd084bb7d7566b5L,0x795275e8e48099a2L }, + { 0x1b461fc9fe9815dbL,0x576214cd73627bbcL,0x3246332d9f09a206L, + 0xbde4c0c36941d6efL,0x44ef03fdf387f5f6L,0x99c8ac0157b63400L } }, + /* 3 << 315 */ + { { 0xaa512f202f6e4301L,0xef668a5fbf94a1ccL,0x08713c3015861b88L, + 0x49d47551c99bb2b6L,0x6db5f812e2f0258eL,0x70c9b299998d7435L }, + { 0x46168e1c5d176ae0L,0xec3306e4f730ec30L,0x49439df3ab69c15dL, + 0x1040408bea0143e4L,0xb48ab8eabc549b0aL,0x4aa38bbf10f89223L } }, + /* 4 << 315 */ + { { 0x7e4851599598f49aL,0xbdac3d5e9629305bL,0x20de0dafa6fbabfbL, + 0x04f015838f09fff7L,0x5a0562976a06994fL,0xf51dac8f6e3ccd33L }, + { 0xc087ef9c3af507b8L,0x525ab76e6a5c6663L,0x4fc04814d916ee93L, + 0x3369c978d23d140bL,0xb0fcd70f1662028fL,0x2ca77de2e1e28adbL } }, + /* 5 << 315 */ + { { 0x838acd1bc512bc71L,0xac06d6bddc18afd0L,0xc991c1e39ec45f4bL, + 0x667c5e89cc27c68eL,0x0e059b04ed07f829L,0xceccf1d4cec4b3a7L }, + { 0x3d9c2dc9b953f9a1L,0x4be2f7e72d599b16L,0x1a2054b197256c26L, + 0xcf66fa478b4fdfebL,0x896cc1b38134d7efL,0xa17264cad41dadbcL } }, + /* 6 << 315 */ + { { 0xe3ccfe8e37627e56L,0x00733a867b6b21a6L,0x3f13e2cbb605c427L, + 0x5ee12395b0d80992L,0x4dcaea94b9991381L,0x4cfed7ee8c4c4b6eL }, + { 0xd7aad54b7f7f45dfL,0x2229407fb3809bf8L,0x6eb31eee68048fd9L, + 0x693842dfd57225fcL,0x3e62cd85a88dfd3fL,0xc6307d53d5462cf1L } }, + /* 7 << 315 */ + { { 0x2d15615ef344f5fdL,0xe0ba6a8aa7f23989L,0xbbfc58041c84e3f2L, + 0x22ffeaae6f4ba826L,0x1e9bf27494292682L,0xc768f89146c02af9L }, + { 0x894127d6177cdafaL,0x8d0523da2acdc791L,0x71ada9aedc78c3c4L, + 0xf21dbbb92c532a01L,0x0c797d5eacb20fdaL,0x1ff99d7616cf57b0L } }, + /* 8 << 315 */ + { { 0x99b5f150493c1d64L,0x3422b656fb74075eL,0xe7493900ff19bf24L, + 0xc82e5b80260925edL,0x3398d340c0ea1eafL,0xe7de2ba11287121eL }, + { 0xea6dfb0b87847031L,0x73bed0a1566af2f2L,0xe26678bf12012999L, + 0xb5369e4d32e5cebcL,0x2304eac86d181e32L,0xafdbd9543d364addL } }, + /* 9 << 315 */ + { { 0x5b1a53ca75da4189L,0xa90485802eb4862bL,0x319424092783ad6aL, + 0x15a4c5e11a9e025eL,0x841bc53313837199L,0x6e9d3e14e642954aL }, + { 0xf4a02bbdd436ec5cL,0x62fe177bc6d6ad53L,0xedbf1e4eac86425aL, + 0xff9359c8d9f752f5L,0x79c685d92d7ad656L,0x8d82c0c4fdde9052L } }, + /* 10 << 315 */ + { { 0xf55f868e702f640dL,0xe459aa9b1dedda11L,0xbec0ff9bbb5ba193L, + 0xf7325c4957724703L,0x5ab8f06323e0e4fbL,0xfbf02e91ecb0fd7cL }, + { 0xcc72e8daa2e5fa31L,0x47de252832cb53cfL,0xbfa646e64252763cL, + 0x7a769efeb8d81de3L,0xf5ec70031e772f00L,0x049bea9a2729aa5eL } }, + /* 11 << 315 */ + { { 0xe987ba54759090d6L,0x904d6901619ef08bL,0x9e16d1382024a6fcL, + 0xb6f0459ba9f3b7e4L,0x1f2a530817ee069aL,0x99403b2e2be31049L }, + { 0xba1663c6bfb2f288L,0xf829195cc7a92b41L,0x89b915ee8ae621b1L, + 0x3fbbb1e150f8ea92L,0xb1fe7f978c901ddcL,0x16d1f62cbbc69ca4L } }, + /* 12 << 315 */ + { { 0x51f19bb3fda072dbL,0xa815459fe3f7e0a2L,0x5f7cde2f987112caL, + 0xdc51d948759de2cbL,0x9d05c410ed49bd98L,0xf063ab99364341fdL }, + { 0xd7869d68d1aa0a11L,0xc20291065d862d01L,0x7f258180c2591073L, + 0x7b90fc7a6ebc4ebcL,0x5565390f3dda1d68L,0xae77fca8a44e4493L } }, + /* 13 << 315 */ + { { 0x97564e4847c49ee8L,0xc56bb5a9ab4ebef5L,0x80d969417b4f86bcL, + 0xa594b4e541026cf0L,0xd56c89965a89ece9L,0xbcf609316a0f922bL }, + { 0x702596161103475cL,0xb1224fb58a2a2abbL,0x0a437a03715cd61bL, + 0xcbe2d2b2739921edL,0xf3b1b5e9385541c4L,0x5d0984f4ae010520L } }, + /* 14 << 315 */ + { { 0xb4a2742dcfd9295eL,0x9cd36774ae929cd0L,0xb15fadccdd7fcf4fL, + 0x0b1fa2b337d4fcc6L,0x242c7b26f01c7ab7L,0x2be8131b50574cc9L }, + { 0x6ee50f42bd89a03cL,0xc7f6ff8f005e7765L,0x04d13af18420501bL, + 0xc22e092b1b6e7d2aL,0xa393be7ee9516f80L,0xa2593652b80bb5b5L } }, + /* 15 << 315 */ + { { 0x5caa5da68b23bebbL,0xa1ad33e81fdbbdf4L,0x18dc93cf4e5c1de0L, + 0xc3e6addb5bd9e178L,0xf30d517e7cb8cd03L,0xbb84ce54f1abc417L }, + { 0x0774b64c67699659L,0x228005b9b7d4a401L,0xd8c2ec5b80b2d3d2L, + 0x419c4cd93450ba7fL,0x520ae681789286a6L,0x24b67ea9aa8bcfbbL } }, + /* 16 << 315 */ + { { 0x9e41b9b70f74808fL,0x2d835dae0c061bdbL,0x67e50c8cf272346cL, + 0xc98a5ef5def57493L,0xc2dea8afa02676fcL,0x59508de26ace4659L }, + { 0xc2b707aada6cd733L,0x6c1f226a4be7bfb9L,0x5b580fa2a778c20bL, + 0x272c3a1d57af166bL,0xe47a64a9ca78ce62L,0xd12db7d771d35087L } }, + /* 17 << 315 */ + { { 0x6a37ac5a2ada7e64L,0x664594de04e35dbdL,0x3a82f748ffdbf300L, + 0x4525ddf155975f5dL,0xcfe5a76bbdf2035fL,0x1693a99f0fcbda84L }, + { 0x5bdb76856a297cdeL,0xdb9ad0cef1d1009aL,0x9e9dae1caf902a00L, + 0x7e36f79f271a0a50L,0x688a0f41a2a2f652L,0x33d2178613722e40L } }, + /* 18 << 315 */ + { { 0x2f4abaff356f4ca1L,0xa2e419422d13be2bL,0x58d72e2f3d7db731L, + 0xafc2f505cd455649L,0x8a0794cd1583705cL,0x4a43066288ffe8e7L }, + { 0x2c0c031d135c8e7cL,0x8ecd9ed76b371b41L,0x17cc1ad9563843eaL, + 0x9603987cfc6b810fL,0x6e291ed7f0d9498dL,0x8c69ae62e1a4058dL } }, + /* 19 << 315 */ + { { 0x934666dd40680b5aL,0x37a9c6ac91e762f6L,0xa0a10533e4d26e7eL, + 0xd811d558ade18237L,0x6e2918ed411b121fL,0xbd9352b93c24a52eL }, + { 0xe31569ccb811ec4fL,0x3b5b977553f7d097L,0xa0d9ebfd7198e959L, + 0x63e10ab13f0a942cL,0x65b8b87f8ea55897L,0x935ea3c129aa0212L } }, + /* 20 << 315 */ + { { 0xe14dd3708ba8a3dfL,0x49c1fc3750a645b6L,0x3f0db6a32252ff87L, + 0xea2ac3c4a34ad040L,0x97a37936decf9f0fL,0x810f02326f7f92ffL }, + { 0xd96c2641184e9c88L,0x08c4cd333d5ab12eL,0xa938d8c3eda80fdfL, + 0xf2dded68bfccc054L,0x4b3da61ede36ac9cL,0x2c266df8347ef904L } }, + /* 21 << 315 */ + { { 0x4653cbfbe3443739L,0x53ea14dd8dd85382L,0x2f6d0513f26ba2fbL, + 0x374d9bee51269be1L,0xf976cdb243f1f612L,0x68b47bf7b5f171b8L }, + { 0x726e93dc7095f377L,0xe6f18c57b59fcfb8L,0xffb56a4023d9eb60L, + 0x678c9508447caf79L,0x4cec83e459740ce0L,0x820ab7eff4d7d58cL } }, + /* 22 << 315 */ + { { 0x88eac51c8e376fe4L,0x096e70c49ef465b6L,0xb35265852004969eL, + 0xbd581669d29cc63dL,0x88094298745b6919L,0x317e386c12e7d67fL }, + { 0x33848bb2e3d6f4daL,0xbace887f2a0ca785L,0x83b32feb197e67a7L, + 0x2b58535ade9c851bL,0x3e428b19c38beaa9L,0x784aa3d174f26de1L } }, + /* 23 << 315 */ + { { 0x10c5f1e5b292efd6L,0x47d92b88ddc96103L,0xc8743717e5e802e0L, + 0x47781ba8008dbb2dL,0x7abcd3acf02360fdL,0x673e2b05e9142308L }, + { 0x501db7c76db93818L,0x285ced71f33dbda3L,0x30aa5fb5cdba4b44L, + 0x93d536c2df0445b0L,0x28a77bfa10196091L,0x26b9f668e38c4c7fL } }, + /* 24 << 315 */ + { { 0x98c3a697c0909659L,0x35c3b0f297d847aeL,0x67d9f71273a7a5a8L, + 0x28e83651b47bed08L,0xfca9e849567b3410L,0x5fa9a6ded291fe1fL }, + { 0xd79682421976a995L,0xcff5bb36a0261383L,0x34166ef962e9922bL, + 0xd816b0342d433139L,0x3b62d3589c4b99c3L,0x8521f917104f7cc4L } }, + /* 25 << 315 */ + { { 0xc35a5c7874e09962L,0x1c340269e1690418L,0x2ed61ab4dca0de49L, + 0x2570d29ede2534ffL,0x9077691bc5143c88L,0xaa249a4a346f3ec1L }, + { 0x57e4f1e104de76b3L,0x206859c3f415b99dL,0xdac6f415f9a15eb1L, + 0x2bf456d00a9501bcL,0x1ceb7dc41ef91323L,0x19c1fa8c3cb8afb0L } }, + /* 26 << 315 */ + { { 0x7761d8fc6f7b6eafL,0xdc439bfdcc0575e5L,0x33853d91f1ff4383L, + 0x6da20e4b75dc1254L,0x25a53b581969a1d3L,0xb40df56723311968L }, + { 0xac150a297dd6aaebL,0xfe6865ce2a3ba337L,0xea05d97cf71013feL, + 0x0ab3cf008053c65aL,0x7cd38b647bab4869L,0x788cb867204cc6a5L } }, + /* 27 << 315 */ + { { 0x253a041e36e88e48L,0x1610f836b86297fdL,0x379d3da109334bb9L, + 0x62de4308777fa7a9L,0x604a46bd6dfefd1dL,0x9e4740ae314eed76L }, + { 0x40ec32e12efde5ccL,0xa5b841bdd92c1faeL,0x01852e23dec68e16L, + 0xc76173b88b55b2c2L,0x4609f350377d5e77L,0xe9c4167ffd67c6b2L } }, + /* 28 << 315 */ + { { 0x52732a0a4b0fc112L,0xe654744e9d125dddL,0x9f76cf7e269beee7L, + 0x2fb8bf32ff80a2f0L,0x1bcef16262b7153bL,0xdedc255a43a4201eL }, + { 0xb1b30b91acbd8a37L,0x147fae6f240adc8fL,0x5558702cb39bf39bL, + 0x171e58803e1eb997L,0x095bf301ed7c79b4L,0x29f1dbffeef752f4L } }, + /* 29 << 315 */ + { { 0xcbb2506e7535c370L,0x40ee37ec7ab20106L,0x74f502d4caca3675L, + 0x167e778db57c0364L,0x7726715b13fa3dccL,0x76097791f42e0c3aL }, + { 0xe1d990c3379dd41aL,0x432454d785c8f5e2L,0x1f90c59562ac45e4L, + 0x63e156998ffe0c09L,0xc3bb8c29d42bf0a6L,0x027d5a86ecca4cfcL } }, + /* 30 << 315 */ + { { 0xaf8ca08b20492da0L,0x37b1fa1547508667L,0xc9fc925b96077958L, + 0xb78c83c19ecac8b4L,0xd9d953a17c05a67fL,0x970ee229b9ebcaaaL }, + { 0x689cad7f55dc989eL,0xf02f05bc66c941fcL,0x8d00516281e23d8bL, + 0xfe603ffc8caebcc3L,0x592860bff303153bL,0x9ec1d5ab3344e524L } }, + /* 31 << 315 */ + { { 0x7e374b7b0f922941L,0x44b3f00174466c92L,0xcb3eb28c3c2fe678L, + 0x91079467bb9bf05bL,0x0d268749de2dcbe3L,0xb6383ba4c5204680L }, + { 0xd50269f4951d3c71L,0x9209a2d53ffbf2e0L,0x2f6496258110f811L, + 0x08fc9fbb0b31e275L,0x697960ea1faec287L,0xae95e4a8c5420ad4L } }, + /* 32 << 315 */ + { { 0xc20fb9111a42e5e7L,0x075a678b81d12863L,0x12bcbc6a5cc0aa89L, + 0x5279c6ab4fb9f01eL,0xbc8e178911ae1b89L,0xae74a706c290003cL }, + { 0x9949d6ec79df3f45L,0xba18e26296c8d37fL,0x68de6ee2dd2275bfL, + 0xa9e4fff8c419f1d5L,0xbc759ca4a52b5a40L,0xff18cbd863b0996dL } }, + /* 33 << 315 */ + { { 0x1304bd65ff0e8fbfL,0xa249adb53343deecL,0x20635fa9826e1293L, + 0x6283f098b7bddaadL,0x0d0a7820bc96fed6L,0xcd7605d47de0b9bdL }, + { 0x4f0a9751586f9eb6L,0x2f6dde5556b2521bL,0xb7efccbd76264c6fL, + 0x7df9cd35b2613621L,0xc334c8f924a2ff4fL,0x914f472a0b13b604L } }, + /* 34 << 315 */ + { { 0x89092cbc5f6bb241L,0x8b4dadacca123b83L,0x9ba420eecd2dbaa2L, + 0xf269d1982dd6ef2fL,0x29f68d03809b338dL,0x18cf8675958ae927L }, + { 0xc179d4b2bffac33aL,0x5356ffc1522695e1L,0x453474986d039c90L, + 0xcba0e0fc5a675530L,0xf369b7ab98a0c70cL,0x51f82173d508c254L } }, + /* 35 << 315 */ + { { 0x5f98e5aae8490374L,0xdd84a7506ca52a68L,0xb6904ff8a9244f56L, + 0x4c908c0362a5502fL,0x70ff1e01a8df73b3L,0x573a37f20df382caL }, + { 0x5df73cf8c7dd1209L,0x965ad402abfbcd79L,0x61a633a59e67af24L, + 0x0953c83cc64203f7L,0xe14f58f9a1fd8dcdL,0xb5ea722887a5fadeL } }, + /* 36 << 315 */ + { { 0x55466aa1d896c2f9L,0xd03ade059831fb31L,0xc46711547d968dfbL, + 0x8ade0c97bce2fdb9L,0xb408c7457f6d843eL,0xb1bbe028a709cf63L }, + { 0x1dbd25383ba4fe36L,0x1438d322dc1f2720L,0x1c3c46b9c37694deL, + 0xe57133dc3997e650L,0x754c171e422b95bcL,0x29c47f0da209c7bbL } }, + /* 37 << 315 */ + { { 0xe520480823822d0dL,0x745fe7aae3eab177L,0x6f0f4a7e808500edL, + 0x9383c632200c2bf0L,0x6f3130d7be22d432L,0xed7713d465511061L }, + { 0xff84bc04049067acL,0x33c2be61d56210e1L,0x57d63f885ac04f01L, + 0xc2fbb773284fb49dL,0x46422426e1f349adL,0x3cb627c465863455L } }, + /* 38 << 315 */ + { { 0xea06cbe9a1edcfccL,0xb0438e198aff46ecL,0xa93fb88ba450240dL, + 0xfc4a370021b6b45dL,0x2503aa5d82a21241L,0x7533f1d7f540d3b7L }, + { 0xd7a58a679277538aL,0x466d981a539c347dL,0x46f1682bf26488c2L, + 0xee2b4976318282e4L,0x8fe5e5b85a94409dL,0x40ca43a7b1a4fc28L } }, + /* 39 << 315 */ + { { 0x0ed4414c901e48d7L,0xdcabb46418340890L,0xd50bf12f20998781L, + 0x498a90232a596ffdL,0xcc877212b43f456cL,0x98d9d531f796c4fcL }, + { 0x061e3b31977c11b9L,0xe56bc6f00a00c822L,0x756e62c96887ea43L, + 0x29129d53859ec944L,0x42342589146c1fbeL,0x2f2cd4bdd1884196L } }, + /* 40 << 315 */ + { { 0x3d3815d645d94a24L,0x4cd9fe1139f3e6e2L,0x8c7b8dae8e7eb572L, + 0x7e69faf40f7deecdL,0x0e54b3c0387e97ddL,0xd12e473175a1b6b1L }, + { 0xb7163632c664f92aL,0x86ab4ea88d94e55bL,0x37212aef1133dcbdL, + 0x0c6c7fc6dfc0d47aL,0xacbcb077aa9e1ccaL,0x43cf50a726ef7fb6L } }, + /* 41 << 315 */ + { { 0xc0eb003c54d7bac5L,0x89780aea2b770baeL,0x13a194e8076bb29cL, + 0xb863585046f8aa90L,0x79ebc6066df515f0L,0x25ea422dd1ead000L }, + { 0x16b03b8106c89b71L,0xa964da878ad9fff7L,0x2c96dc6b2e7b9072L, + 0xf71788978c93f6bfL,0x4c7ecef912688648L,0xed7b4a577c663be0L } }, + /* 42 << 315 */ + { { 0x5b7cdd0ad74a20d2L,0x273184f48bcdd2f5L,0x4d8d3b4ce3ac03f7L, + 0x0e2ff518a02cc60cL,0x9c006ad8b6fa606fL,0x401606caccf627a0L }, + { 0xe7429a6f7b967844L,0xe4e5d1c1bc8ac8beL,0xc050f89ff4f46638L, + 0xd23a3eb452f918c9L,0x4528e4e202944b49L,0xeb345a689268719dL } }, + /* 43 << 315 */ + { { 0xf4fbd190ccec4c27L,0x7e042c8722674e8fL,0xbc79835ae8b33439L, + 0xc7923b8fad2124d1L,0x0ece42272c72542aL,0x02d638e2b9264875L }, + { 0xbdf9fba1904e7683L,0xcbbc0e0aac934377L,0xea154d99459ec213L, + 0x87db3f66c3023e2eL,0x7f9262d518de83a8L,0x432fef4f3524400aL } }, + /* 44 << 315 */ + { { 0x3b5566d7938a395bL,0x920dc1111f256c82L,0xcee7f231a059c8f8L, + 0xdc3da434d48b3179L,0xb1e819e913f78de6L,0x94a21bb01f9819deL }, + { 0x8ef14a96f302a94dL,0x9f897e1a079fff9eL,0xff9a4e0e54122af0L, + 0xac6a6cbef0b7f1c7L,0xfd15d9756401df3dL,0x500531a323a0b7b6L } }, + /* 45 << 315 */ + { { 0x12e22a012da0c724L,0xa0a837f3b80cba90L,0x89df9a3e2a9b5434L, + 0xf3299f64925840acL,0x0cc78a3a125b3dc1L,0xa4ea6203c723d647L }, + { 0x5cee8068d369522cL,0x3e479803432d5e87L,0x86e809363ad8126bL, + 0x93e871c9cf89d85dL,0x892e4710286c9010L,0xa075a6d3ec3a1792L } }, + /* 46 << 315 */ + { { 0x095768bc7dfddf6eL,0xc4e331b4e63c4e60L,0x1179808104f28a2aL, + 0x415e33e1bee48983L,0x7fe8050144af7eb7L,0xdf6c423b2f28fbfdL }, + { 0xd10886db007a2b56L,0xea578b286613f26dL,0xd18a9d1c2b90a815L, + 0xd4c6e8b2675c2c8dL,0xff973df5788bf2d6L,0x4fbeb6210d7e611bL } }, + /* 47 << 315 */ + { { 0xcfab317671674fa8L,0x78038a1afef7089eL,0x3109736aa27b5b55L, + 0x1b31325fc0193518L,0x3afd21a8be19b5f0L,0x548196a2d8028eabL }, + { 0x15b0d6d2a94e6be0L,0x1552ffb67afd5dd6L,0x49b1150d89bed9eeL, + 0x2c59b0bfb0d1444cL,0xab265d7eb695a900L,0xa24d0788a1dd1ef4L } }, + /* 48 << 315 */ + { { 0x4e913e1131e325ccL,0xe92f7c8f2a65fe01L,0x8e61a80d5857aae9L, + 0x2c36923d53104397L,0x5b0911d6b36d5379L,0x76eb9b56b1207ae0L }, + { 0xb5cd11646723c4aaL,0xa6bec13b98891a11L,0x09af8be29d806056L, + 0x7da8d29ecc1fc0e6L,0x231cc00e2aa8791dL,0x2ded362c042171c2L } }, + /* 49 << 315 */ + { { 0x26eb2ac96afa51d2L,0x83485eff13c04ce8L,0xdedb48718072d8dcL, + 0x4da1771d8ac3d411L,0x2d8f99ef849c6c0bL,0xea65f6bc2b5882e4L }, + { 0x60a90f58fd671216L,0xb9f3e2058af33bedL,0x29c41ec92bf02916L, + 0xcdf15b1de5ddeae8L,0x67f9ad163109e99dL,0xb9b5585f517d25e1L } }, + /* 50 << 315 */ + { { 0xae016b4811b3e20bL,0x5ccf3cf1e5164179L,0x1281ff8efe9fd47cL, + 0xb85438038e61bdf2L,0x694e42feba5856a0L,0x53f7e09759b32aa1L }, + { 0x5b9848e9c341a531L,0x9a5fb85025952b73L,0x9d5fe0dea6f82c5eL, + 0x9216a8ca44090933L,0x3e986d4bc3272875L,0xc20534f8f3512e42L } }, + /* 51 << 315 */ + { { 0x718124a1033495a6L,0xc4f28a746834851fL,0x91186d80e1baaa77L, + 0xca4e13222a761e95L,0x7b6b8322582ddee2L,0x75d396c6c3c70c6bL }, + { 0x075dcd6b54c75102L,0x3669b97c0b92622cL,0x621154e6f0cd45adL, + 0x7ff0029ff381a6d3L,0x3d37e750a726f84bL,0xc4f79202874de604L } }, + /* 52 << 315 */ + { { 0x215018fdec26297dL,0xaa06fd0bbf35d225L,0xe5fb438cab40bc17L, + 0x6a0ab335acb7f4c5L,0xbe1f4de4187a8e6cL,0x651deba961f7e842L }, + { 0x2b30b0046f629aedL,0x63bdbf8e2218f107L,0x21a21aa5f9ca8bbdL, + 0xa88cd9138304f7e1L,0x23594fc6c5e6f9d4L,0x4d4db41a6682fc06L } }, + /* 53 << 315 */ + { { 0xca2317b0428dcb40L,0x9a7bd387288b5eeeL,0xd62da6d0a060584bL, + 0x601a3d6ce8f10251L,0x65718f0584885319L,0x5a87b1c2a1bc252dL }, + { 0x27ae8015a37b05d5L,0xa624af9c98394605L,0x988220050ba4565dL, + 0xb93395c9da2613deL,0xcef9a880edcaa74eL,0x7b2ef0fe0976687eL } }, + /* 54 << 315 */ + { { 0x094f20588e5c6b80L,0x6e5a5f52846eabebL,0x9eaef2d7370a9345L, + 0x12d6f20687c19719L,0x0d2494ab9c44076cL,0x15ccc737de9309a6L }, + { 0x8eeb8faf94ca6587L,0x7dc9a4fe3fe363f5L,0xf02f6e03b3b08270L, + 0x31adbe77daf15507L,0xc0fb2814343bb4efL,0x724007519bdc1d91L } }, + /* 55 << 315 */ + { { 0xd301525c1677fcb7L,0x11b7141bfb6b0dc1L,0x01f4950eb2163b70L, + 0x34c758c6ed3c0025L,0xd1b1c7573a5196cbL,0x7926f0a42fa19c66L }, + { 0x107e5d32b1c47233L,0x0fe50b00cacbdaa0L,0xf45dd7e8e213397aL, + 0xca6b2de9eaa1db7dL,0xbf234b55dd09c2eeL,0x10db87d1a1db37f3L } }, + /* 56 << 315 */ + { { 0xaff57c87de0572ecL,0xc0745250826246c4L,0x523910fc700ef250L, + 0x8c23aa5793faa067L,0x87f7c7198e7dcf75L,0x45ef4adb46695227L }, + { 0x0ffe09d196ceb1e0L,0xfb72a05790f3383aL,0x62d26e5e07c220d9L, + 0x03e19605766b1e64L,0xa774669458c17fb7L,0x9a851d828e7acfa9L } }, + /* 57 << 315 */ + { { 0x150e936f4baea8efL,0xeb5328d68239dfe4L,0xe064fd95b5f987adL, + 0x13d3803d52e7313dL,0x0e9738f5b215317dL,0xb6dd60a7974be106L }, + { 0x00fa92bd6bac81d0L,0xdee050f9e7cb2338L,0xd7943d4f9075745eL, + 0x07cc4170819cfd9aL,0x21b7e0b04aef1468L,0xd7520b77aef07b1dL } }, + /* 58 << 315 */ + { { 0x126c012681097c49L,0x95339f9475c02669L,0xec3fc15b100115ecL, + 0xea5c8e9c49fb787eL,0x63168108bd3fbc19L,0xdbf2430541573590L }, + { 0xcaa3a69686dbc847L,0x2c464fcb70d76739L,0xdd9e0bcd69e2fd74L, + 0x4ae92cc01652728dL,0xafe3e24812b060cdL,0xf3776c6ff951a38dL } }, + /* 59 << 315 */ + { { 0xe4ab1c417af22e76L,0x35a8addf038840dbL,0x95ba3e3dafd0d7b2L, + 0x2a7bf827f84417a3L,0x0bc177c729bf5a83L,0x29ef7f8bd09905a3L }, + { 0x1df34fb1385e6c69L,0x079bc0fcf99e0d19L,0xcd2dbbc4f30eb5c7L, + 0x2d364701afa7447bL,0x3c7bfa087a791ef9L,0xe21508c8e71166d0L } }, + /* 60 << 315 */ + { { 0x0b204c9ac746ec60L,0xdd5efe2718b93b24L,0x484474e0ce15332eL, + 0x690be23d05a308b7L,0xeea3abfcb0f7081aL,0xaff69f36cd8e8720L }, + { 0x5dadd080d951329cL,0x060c379c8cae67c2L,0x8e284705b20851baL, + 0xacc8d8a0e5df0e85L,0x8c024e789463544dL,0x15a9a3f08003076cL } }, + /* 61 << 315 */ + { { 0x095e284899e0ecb5L,0x61e9d5893415c1bfL,0xb1207d3017f5c585L, + 0x75f73f1d04e97243L,0x868551aa77bd50d8L,0xd530e0cc197f7d84L }, + { 0xdd6ab731ea9fb71bL,0x26e5b52e2cf9510cL,0x4fba03ff11a88911L, + 0x6608b634e921e323L,0x4baf22f836d46a1fL,0xb8bced501bc7ace0L } }, + /* 62 << 315 */ + { { 0xaee397fa327d9bbaL,0x9a45e7a2d832e3dbL,0xccb43a730582ae33L, + 0x457b3271d4093b12L,0x409caea6370bd663L,0xa5019f25657f693aL }, + { 0x5851c78a16478fe7L,0x5e09ace7ddf17dd5L,0x89ca68da0763656cL, + 0xb92d3321e2bad2d0L,0xdd5642098422f6bcL,0x4a6ea69946c04923L } }, + /* 63 << 315 */ + { { 0x7ba1f48579120405L,0x6c136597898be69cL,0x1e75e1586dcacc38L, + 0x3d3cb58b65ee4cbeL,0xbccee7a308db0caeL,0xee8bff34e77edfb7L }, + { 0x123bc3f036f60cf7L,0x3b1dc9e779bb4c78L,0x036a8049fe5f0d85L, + 0xc4de23d318f66f39L,0x593cf51e3c436c16L,0xd4d40e906769584eL } }, + /* 64 << 315 */ + { { 0xf6827150844eefc5L,0x002e82c44515ef68L,0xa46c8f55c51916c4L, + 0x98c3524b61ee081fL,0x5ab7f2c2ad64872aL,0x0b503ff07e555faaL }, + { 0x802e0d23b4c58d29L,0x122890402fd917feL,0xb56d19087af20d26L, + 0x8d619e216be50784L,0x10fdbb721372b851L,0xf2c1673e4935576eL } }, + /* 0 << 322 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 322 */ + { { 0xd97a9b1451a135f6L,0x6d16aaf597b4df14L,0xc57160c254818818L, + 0x4dbdeab61d59be44L,0xb93a9dad81f2b247L,0xe2868cf5ecbcab33L }, + { 0x5e1ce82883a86711L,0x29a9ca2f29c55428L,0xe716273a2d82b0dfL, + 0xb017f5f6ac8ff52fL,0x7563e79970ea7ccdL,0x5fedf0a63f0e674bL } }, + /* 2 << 322 */ + { { 0xa7f8501488d7b3fbL,0x3b5ec513ec78386eL,0xc6586b8a2ad5053dL, + 0x88c09a43fbcebe43L,0xde7f2a4a20054f16L,0x63daba80bbbb147fL }, + { 0x087e48f37d352b55L,0x997e32a08317ab79L,0x8ae802ff7f27cac7L, + 0xb01a131c37b1f6e1L,0x3f0d4c2e9a6d1deaL,0xe06114fce7ceef80L } }, + /* 3 << 322 */ + { { 0x311df84c359590bfL,0xf907d69ddf6ca4b4L,0x876fd36782f22c64L, + 0x64c4d14d9713e68cL,0xd431858d6b07f539L,0x39dfea3384990283L }, + { 0x6afb8cf080cf6498L,0x327056bcde060e9eL,0x5103ce4a49a71086L, + 0xfc94be75cdf853abL,0x2bfb105f8ca579cdL,0x02d19c3a50454b41L } }, + /* 4 << 322 */ + { { 0xaa03b474cde121c7L,0x74a648cb55e52c76L,0xb286ef86f37b57bcL, + 0x95b797eb2a6371d2L,0xa489ef894077ccbdL,0xf46ade048e99ca6dL }, + { 0x5cf9e23723242d03L,0x33c7d32acb708390L,0x329523b6ba7ba477L, + 0xd406ab8757de30bfL,0xaa10e4a21536ca01L,0xdcec94f4dfa7aac5L } }, + /* 5 << 322 */ + { { 0xb5839fa424700097L,0x82fe2251759eb8beL,0xec5f34bd5f104a39L, + 0x7f3da509ed1cf49eL,0x62fe425244621c76L,0x2118b68dc7bba926L }, + { 0xb0ac18009ea4b7e7L,0x33b21ca1fcc83f56L,0x1856161208458096L, + 0xba0e6aa95650f3feL,0x918d427231006f05L,0x955f3951b1066473L } }, + /* 6 << 322 */ + { { 0x0cb41ada3c59ee1fL,0x38b2465861d1633dL,0xde863b47d03e9452L, + 0x2bfab5b41548d45bL,0x580af6272ccb7528L,0x6744c7cb13c04327L }, + { 0x5eca3ab339cc5075L,0x51dbfc7b6d243f62L,0xd64d84b7981ee3ceL, + 0xf639a03db4f2bc63L,0x8a411c36a317a1b6L,0x51edc4c0ed34eb3aL } }, + /* 7 << 322 */ + { { 0x01511b8a9d6fce5eL,0xb5c7b33f89a2875cL,0xa88e720e2fd79b67L, + 0x5337034404229e94L,0x40bb7e7ec94af25cL,0xc11501b99183a7b3L }, + { 0x29a4d81fcec3cc7bL,0x143976fdd75b8febL,0xac8dad2cfa261ad0L, + 0xb14793006a2db8a8L,0xd4981293929c4a12L,0x5703506fb6eef856L } }, + /* 8 << 322 */ + { { 0x762a5eec1f5a9609L,0xfe4f5f6a765b337fL,0x0fd534aeaa4f964aL, + 0xcf46648ed6526f01L,0xbc62a54a18d71d72L,0x48d94f2a4f8488eaL }, + { 0x62c40de7a0c72a86L,0xd73ac51a725dd2efL,0x3a51d7466ab19096L, + 0xf07bea4b2dd1ad3dL,0x2a0ec4672ef88078L,0x92598cb3664e435dL } }, + /* 9 << 322 */ + { { 0xd49f753012fbc44aL,0x769a4fc941c51d91L,0xeb1ed485981fd6a9L, + 0x90a4b3cad7daf430L,0x4bbffd5c75d07405L,0xd998a096da671888L }, + { 0x0514ad4b6e10976cL,0x5d40328aab11d9ecL,0x86de976bfa180702L, + 0x259ca429f6f8a4b7L,0xe08970f05772eb4fL,0xca428fa1b5feb7a7L } }, + /* 10 << 322 */ + { { 0x9f3d76ae35af4a88L,0x0b92f48a242af3e6L,0xd4f8a37b7165d261L, + 0x30e1fa8b2b917832L,0xd26f821f8fdfc06aL,0x75359bcf3669d1a2L }, + { 0x0ba3bcebb638331aL,0x8d02c0996c73b62bL,0x2a8c078d8c4f63a5L, + 0x55458ccaa312c282L,0x901ea0ea5eaaad9dL,0x03665da20e39eba1L } }, + /* 11 << 322 */ + { { 0x79a30b82da9affceL,0xafb188567204a29dL,0x2e64e6105a8ed24aL, + 0x6bf3695a9e44aa24L,0xc22320690c77fa6cL,0x20b3c69531524429L }, + { 0x91e60caad6e0f847L,0xf0fa30c4542d6b57L,0x56a3a66bff98ceffL, + 0xec44f0b72c9507a2L,0x4ef13008c37e17e4L,0xc819ae81cda21355L } }, + /* 12 << 322 */ + { { 0x17c563be1cac0b58L,0x889cfcecb8491347L,0x591d49ac4cd1bfc0L, + 0xd4465510d4e53d3bL,0xca95ccf6ad079a6eL,0xce391389b5ea6eb4L }, + { 0x600ccc9ca48b6447L,0x20d0c7dbc20d56a8L,0x5f27edc569c6c6e7L, + 0xb3fc0f4a586abcdcL,0xdbfdf3f985dbc5b6L,0xfba1cf254ea80fe0L } }, + /* 13 << 322 */ + { { 0x38d6267e427a9075L,0xd1df12006d63ea4cL,0x9887a99881407b57L, + 0x41accae4688e9f0eL,0x33c63c9e10886dc3L,0xf8332ac57574a033L }, + { 0x7d77d41f4c636d00L,0xf6f4ca28add70d4bL,0xbe496330c0ee111dL, + 0xa4de7670b74bc69dL,0x683a93d369e5eabdL,0x4c5461c710963bd5L } }, + /* 14 << 322 */ + { { 0x9bbc99b59310424cL,0x6f4bce534568e290L,0x21373f5bc1572fd6L, + 0xe5ecd5b6a28b4394L,0xd56968f646ef7bacL,0xcbce8614726cc043L }, + { 0xb2fa6101d0a49bd8L,0x65eaa7725a7b41c3L,0x10d7515296e5ae18L, + 0xec8f4639af389838L,0xac660d81bccaff25L,0x3c546ba931734025L } }, + /* 15 << 322 */ + { { 0x81b13d3ee098c584L,0xf8eb4e41fa3460caL,0x1bb889d1f0b905e3L, + 0xd158ebe939a3faafL,0x7ad0f829cf09735eL,0xc89611963aa8b3beL }, + { 0x522327781be516cbL,0x9118d851ee88d911L,0x35ad130f0bf2a62cL, + 0xf35bcf1b39c05087L,0x73b992c3bce42949L,0x93ce50b95b42744dL } }, + /* 16 << 322 */ + { { 0xee6e7006b515fff5L,0xaedf6e3913258ed5L,0x373adf7dfc45111bL, + 0x0c7535b1875c23c8L,0x2a7e04f897039d49L,0xd76787ae9afd1a06L }, + { 0x049dd38591b6dc89L,0x8f0c8ad0932dab78L,0xdce057b9925498c2L, + 0x7b9c9bd2da25daa3L,0x6d0b70a3d4decb7dL,0x099a218303df76efL } }, + /* 17 << 322 */ + { { 0xbfaf4b848c5520a2L,0x36fa343fc6741e50L,0xadcc36dcbd5211c4L, + 0x2cae5a8514bf0578L,0x8fee4d403fe4171eL,0x2acd2756624d0daeL }, + { 0xaf99a323623aa9cbL,0x120cd2038c8191e2L,0x2073e8884068d993L, + 0x144851ac579bbf88L,0x54d458a4ee29fa34L,0xb7704255e5e5d676L } }, + /* 18 << 322 */ + { { 0x02f6e396617dc4bdL,0xbc48c42961497feeL,0xb27487fe0b4d22d7L, + 0x33d6b1161d0b0aabL,0x5e21cebad31278e5L,0xf7119a50dacd8f27L }, + { 0xe47eff2cc8ab54acL,0x7c7ccd3bbbe16c9cL,0xc056d817c584bafcL, + 0x868ead2b97790d9cL,0x8fea6eea1a58126aL,0x67d323640fab2640L } }, + /* 19 << 322 */ + { { 0xee1a958ffa14b58eL,0x900644f9760b54e3L,0x97fa6fa451579d09L, + 0xa7351c3b26e7f95aL,0xc3546595aadfd139L,0x07b7ef48f14f1e6dL }, + { 0xc8d100ec4d139608L,0xf98609b2d8741228L,0xf0890d9d33030d3eL, + 0x893b874fe28ed106L,0x5439b7aff7bb558aL,0xe68a3adba71a2261L } }, + /* 20 << 322 */ + { { 0xff54e8bc8acd597bL,0xdae781e94682b8c6L,0xb2265bc4ed1fae2dL, + 0xa5e23c29ea983db1L,0x4af5f55909851454L,0xffe9538836eb4506L }, + { 0x4c72b2d1c2247b8fL,0xb179573331a67505L,0xb1aa8ad4e19c9c25L, + 0xb9cfea953e8b8004L,0x07782d788ac747fdL,0xe23e547fce9d9e41L } }, + /* 21 << 322 */ + { { 0xbc6b0088fd9e8e72L,0x7e51aa5dc6453462L,0xe8615fb9c8b1725bL, + 0x031f0d2a5a371c9bL,0xb9db0a647441d8aeL,0x0dd0446e9d5783c5L }, + { 0xb3b7be2381720779L,0x49a8ecbb6cc5a610L,0x165c626152cd016cL, + 0x5fcd657da3f6ae6aL,0x30497fbc9f6988dbL,0xd734927936a73fe7L } }, + /* 22 << 322 */ + { { 0xb30ddd0e388562b4L,0xc485506b1f61067fL,0xf0da517684947c84L, + 0x04830cedeb067f33L,0x05084c8262404b76L,0xe7e7efad7996707cL }, + { 0xc2a6a57fc78b9a7eL,0x4e55fd8c7bfbf308L,0x204e7c44d1386117L, + 0x979ecd5a4e56595eL,0x3bfc790853707b85L,0x2c3a41c59fcc5b7aL } }, + /* 23 << 322 */ + { { 0xcdbfd951ed6e2671L,0xb72c42ee135f6b96L,0x38c8d1ca40bbb789L, + 0xf6fa984cda03f270L,0x76dc5a19ed88deb9L,0xa8c88f2a9985bcd7L }, + { 0x2b0d3b66c6628a44L,0xdf679b6a2b311954L,0x30a363c25f851b07L, + 0x78a5d242aecdb9cdL,0x42d7ca82a968b4e6L,0xb188e99af2efb94fL } }, + /* 24 << 322 */ + { { 0x779905b6d8948f95L,0x3c7085b591cd0206L,0xce9af0aa679096dbL, + 0xfdf04f10f558913cL,0x05300cb06f24a2e2L,0xf9d9a2f25d581b35L }, + { 0x855c8de96a713751L,0xc9ac24bc0e0c0dfbL,0x67612a4197740d65L, + 0x7588a52744c9360dL,0x928ac910325cc880L,0xa74abdafacdd3188L } }, + /* 25 << 322 */ + { { 0x98d80359e7c5fbc7L,0x6abc82b7047c61d5L,0x8d8f5fbd58f2fd49L, + 0x321f2426ccb0a4dfL,0x379f10e2e96cac24L,0x34c0444130666763L }, + { 0x8dd3972043632c61L,0xb2bbe2eec19f98eeL,0x00d5a467c464dfa3L, + 0xa44ceb19a85b6fecL,0x88bf80ddc9b1fa77L,0x7e5123c8e6dda98fL } }, + /* 26 << 322 */ + { { 0xf73ad540b75a6b88L,0x57bcf1cc08487cc1L,0x00358de735cd0c27L, + 0x86d469a2573df808L,0x4884cd5684716abfL,0x0157687fa7da61d7L }, + { 0x8efd8acda732c2cfL,0xb6c9bf7198677236L,0x3d1f01826d46c473L, + 0xafa65fd82f497476L,0x535ee757e54f17daL,0x432b5878fe7aaef6L } }, + /* 27 << 322 */ + { { 0xf091c4ff3370e118L,0xabf011ee118d4b8eL,0xb489c4b7a13c7279L, + 0xc2dd44e93bfb19feL,0x10b68e92c5d859dcL,0x57935fc39249205eL }, + { 0xb97e63b06c929bf4L,0x98cb08a739a25097L,0xb13f17c15eeedf15L, + 0x1e27a85c240884feL,0xda1515ad9b601298L,0xe01251fd4ce36c3eL } }, + /* 28 << 322 */ + { { 0x3774af36ba6aca8aL,0x562fcfb1340e6a03L,0xde45205ec1187539L, + 0xf3b114418799c22eL,0xfd53f681e8b0842eL,0x45a0039066d36d64L }, + { 0xa2c3391d353eb1e7L,0xf9d9fcc55840eddaL,0x4df1fa4a6ab8ab4aL, + 0x2b0cd34bd841a623L,0x52441d79b10b189aL,0xfd86d3c2fa025da7L } }, + /* 29 << 322 */ + { { 0xe28f3bab5872204bL,0x6f87cbaf0ba35c66L,0x783e85c03d877c60L, + 0x376e5e2df132df52L,0x213d53a9bc2cd6faL,0x2e2a573008a13174L }, + { 0xc0988fa9ba15290fL,0x51d81b9485456f81L,0xfe371f32a0ef5b80L, + 0x9aca060ff129171bL,0x0b02b39e0e402e65L,0x8e6bce1eae9c209cL } }, + /* 30 << 322 */ + { { 0xb0cb0f0c532f78c8L,0x83113e752d133635L,0x3f64aad5123dc64bL, + 0x4d3201c85aee8c59L,0x265905dbe75e8642L,0x9d1d277805f9a759L }, + { 0x84778aead9e2a07eL,0xc747cc3a9c0aed31L,0x10d1b4e87af2dc61L, + 0xf58a6bd8af0bf23cL,0x83836c2352e1ee75L,0x88c4d1c6d899062dL } }, + /* 31 << 322 */ + { { 0x27eb26a3f3842d98L,0x90f712b69da68159L,0xd11177052676f05bL, + 0xdf603446073bf994L,0x28ad2b498bfcbb7cL,0x6916c6e2e5e1266cL }, + { 0x37d516996e98d62bL,0x155d8ef749634968L,0x0676ea286a1b2222L, + 0x1dc3f8d71566cb3bL,0x95fb3f177dc6aecbL,0x092f4c8120807b13L } }, + /* 32 << 322 */ + { { 0x3c6c5618b9d926c2L,0x7e14c3ae4a9099f9L,0xb3259c90ae2fb830L, + 0xf7cc6e43ec31a504L,0x83bb13c6126230bdL,0x5a1f4313ff1dae3aL }, + { 0x0cc6c1a549b0b65bL,0x67fa836a274a84c2L,0xd454c75fe604a58dL, + 0xceadfd912491f872L,0x6c5575da9ce116a5L,0xfaa4903fb24a4481L } }, + /* 33 << 322 */ + { { 0xc9ade1497c4579f8L,0xdad7eff3be316db0L,0x4ff3abc613fce23dL, + 0x09103a75da708e56L,0x4cf139fa8ab52827L,0x0f82219b8f251a68L }, + { 0xd19719c7dea33388L,0xa482548423085413L,0xbb63cb43f8eb4b18L, + 0xeec33735f3b88079L,0xee79d331de3ddb97L,0x56fc93090e5acf8aL } }, + /* 34 << 322 */ + { { 0x951a780bcef9c5bbL,0xc37d442ddb35bf11L,0x8e2a0e7d64a776b0L, + 0xbf461becc652cf34L,0x3970eb603194f918L,0x2768daedb3bda869L }, + { 0x8e81257557b24bf2L,0xae05e2db38dd69cbL,0x0adab288cee2f522L, + 0xc7a0e1f148234f13L,0x285f6ee36728c9e9L,0xb9ae7b9fc4541e19L } }, + /* 35 << 322 */ + { { 0xfd90c5c1f6422b56L,0xd9fc8cce4dfdb947L,0xf3566dc4d088588eL, + 0x25dd9e27f22682e6L,0xb077392119b0a532L,0x54da228c0d05a9f9L }, + { 0x0f7fda40986f60d4L,0xb6dafff6c9b112feL,0x7eb99e1a4abfdfcaL, + 0xed499eb9389611caL,0xf230d6d6f251477bL,0xc09d328c227ecc92L } }, + /* 36 << 322 */ + { { 0x9b21ef6c16cdcfeaL,0x233be0c3694edecfL,0x110243df7c49c931L, + 0x03a59a2ea3113ed1L,0x6470f721023c9a77L,0x7d1640c88e9ff099L }, + { 0xc21488316f2c7b37L,0x9e1c9e1dac6eebc7L,0x6af65a671109ca9cL, + 0x8379fdd9cc6f80d9L,0x33f74ade7e666a4fL,0x07ac728b7be081a5L } }, + /* 37 << 322 */ + { { 0xa3df31a312354705L,0xffc8fdfc1aec1bd7L,0xd9dd39c112cc342cL, + 0x8077a57e37bf43fcL,0x0f037ce49cb8751eL,0x5740f6b5b805b530L }, + { 0xd26422704e2b5b93L,0x114bb1f02dc158efL,0x71881767a9bec3d1L, + 0x1174386d266d95cfL,0xa373d7ea7cdd4461L,0xaf4f7b40d814a33eL } }, + /* 38 << 322 */ + { { 0x0db94a18f79761beL,0x263e2acb5717b98cL,0x78c28d8182567b0eL, + 0xce1b366b893c35b4L,0x1e20b1bc0d6907a7L,0xd6f123474b973588L }, + { 0xfb945471f717e91bL,0xef85653cb027bd4dL,0x048e9e1df07dc0e1L, + 0xc494aa9cc163b83dL,0xfaec72d3021b4fa5L,0x5c63c30fc9869fe6L } }, + /* 39 << 322 */ + { { 0x2dfa058d510d8d86L,0x772fad416a89aa0cL,0xdf55d15cd586f23dL, + 0x7d96b7a989b604f6L,0x352fe049a38d821bL,0xfc56b8df4fbb5795L }, + { 0x264122b4b3d5dd0bL,0x89317f4a980177d9L,0xc060ab4a13e2aeecL, + 0xc2676725e2cafc87L,0x78863cf45eb1df3cL,0x2e1572dc0ab1a715L } }, + /* 40 << 322 */ + { { 0x7a8a898d5a4703aaL,0xc59933ea1cd6f9d6L,0x703265f5d28124cdL, + 0xe1c1bee10178d1feL,0x9ff31cd4241262e9L,0x9174a939a3c9f80fL }, + { 0x0f7a3d2dbc2a62eeL,0x0454051c62f1b3acL,0x83502c9ea2421254L, + 0xb4fa51fcb684199bL,0x257e9e2bc5e36a44L,0x14efeed597d8647fL } }, + /* 41 << 322 */ + { { 0x09bddbc28f2b12baL,0x8af83a779b7f1c14L,0x88f9b4d3bcc934bbL, + 0x8d8312df8d072340L,0x2ee105bc615989dcL,0x6044fa00de3bab08L }, + { 0x98c499d603cc86ffL,0xf0b48aa7c5068033L,0xdaa536d2c96606d8L, + 0xef905aa2bc6a843eL,0xb6f108ee8ac620ecL,0x0dec7dfbb6dd66f9L } }, + /* 42 << 322 */ + { { 0xb9157d4ab0fe18a8L,0x139bbcbc68cc7a70L,0xd546a06d7dea2914L, + 0x8db142d4a01cc59aL,0x127ce2d9aa09fcdfL,0x3950a5a63bfef8deL }, + { 0xf41ef6d42527522aL,0x4b4e6f107e6fb19cL,0x2a2735d1345788c5L, + 0x87963e1ee72a7ae3L,0xb58d8934fc443360L,0x93552692b16b6f2eL } }, + /* 43 << 322 */ + { { 0x70591a849518f0c7L,0x5c282b6fc67c438fL,0xdbf61b6b100facc1L, + 0x3c5d969f2bf2a5beL,0xe1a0c6cbab980c70L,0x70f4981c680619fdL }, + { 0xc6905d7cc65be256L,0xde3340fbb5c27acdL,0x17be9d182c1b3fbcL, + 0xd584e4f96fb00b1dL,0xac5dc14eb819646fL,0xf5c3279a3242935bL } }, + /* 44 << 322 */ + { { 0xfdb13b31be970ebaL,0x119b1c08b0bfadc2L,0xed62f35e21875542L, + 0x73c8f9b0349a6d12L,0x8c35d8f8bd1622c0L,0x501b9d288b6521a0L }, + { 0x377f8fa1c918b2d5L,0xe2a9580cd0239ef9L,0xee24f4f0371d7bebL, + 0x4cc697a669231b47L,0xa55193c8dc4c5a07L,0xd4e51e1db0ab8507L } }, + /* 45 << 322 */ + { { 0xcb811c27265f267fL,0xb85593aa9e2688f4L,0x57a1969dd76bf364L, + 0xc29946c9014483a2L,0x5bdd72490915bddeL,0xba6d13ff22746ae4L }, + { 0x524121e0d25f6b7bL,0x9011309e0d68a3f9L,0xf25e89ccdb91c66cL, + 0xae79cad781df593aL,0xef8c6bec4f103231L,0x832659c3e038f02eL } }, + /* 46 << 322 */ + { { 0xd58eeece37761959L,0xba6d8ab5b328f084L,0x3911e6ae324a6706L, + 0x299921c8ad139296L,0xb81a3fe4f6b8d9e1L,0x2680c46f5ef06a6cL }, + { 0xab9cdf368611d63cL,0x6c9fa5b3cc0a5da8L,0x712356a3da4d4412L, + 0xc1707a10cd3f550dL,0x5c25b2f3ce468303L,0xe4be20bffa546b6aL } }, + /* 47 << 322 */ + { { 0x797a2919515ee1dfL,0x65dd5991119dc9d3L,0x82e8201b41e4c5ffL, + 0xd27b35130d3dd45aL,0x9ba590c5b13b2dd7L,0x0f15b35282992935L }, + { 0xef39971e227e4e46L,0xb74c524b2786fd6dL,0xe09c28ec71b1579eL, + 0x0d1418e285f6a935L,0x173265448719fbe7L,0xfe3b1d831200b35dL } }, + /* 48 << 322 */ + { { 0x6e96a8195cecb21fL,0x3a58d8b2d8beecaeL,0x93c3cbb0c0c715a8L, + 0xfb06f977541759b7L,0xf25ba095771c3d2cL,0x7560446ea3bfd322L }, + { 0x7cd99f35a015cb4fL,0xa0e541960786f235L,0x0f868f768b8e291aL, + 0xc8260b0b2f95050bL,0xaf38376ef4c0a462L,0x2b3c0f3b98a3395dL } }, + /* 49 << 322 */ + { { 0x99d4529efed6a724L,0xc6f1b084071d8d31L,0x6c48062ba097da1fL, + 0x1dd10493301c1d74L,0x5288f194f554cbccL,0x77b1b81f39dd42c7L }, + { 0xeb1f2d53a007a6d8L,0x43bed54e05648d75L,0x1a85326f29801a1eL, + 0xcb9a91a4f564d78aL,0x4f38fc7893f071deL,0x920117d8aeeeb5adL } }, + /* 50 << 322 */ + { { 0x709b5904b35cba78L,0xef0c321021b11d3dL,0x38f07eec46844b18L, + 0x2e79f99934870a55L,0x9e9df80400d7b924L,0x857a95625cafba4bL }, + { 0xef8ab68f4adfea6fL,0x4a83bfc16ea764e1L,0x21f4c75475e8d874L, + 0xa3597f526ecdf5d1L,0x9d3a4766eff2e1e6L,0x9872db39e5e6ae81L } }, + /* 51 << 322 */ + { { 0x42d9f39e99bb9a10L,0xe617263ce35e4852L,0xb3f8ace1a06b71d0L, + 0x861520de6419d9d1L,0xc2c521cf37b1fe38L,0xd537001b9edf9936L }, + { 0x92614b9f39af94e7L,0xd2003f2e25286664L,0x249d04aeb836d4b1L, + 0x3c6c192ab26df88cL,0x6e0b25442c72ec0eL,0x69d7f6d7497f03dcL } }, + /* 52 << 322 */ + { { 0xbb5a95f6293cc00fL,0xb202a82a65fb729eL,0x819c26aa12e35774L, + 0x70cd5237c2b3f0b2L,0xa752224a89b2c5ccL,0x71c09cbd0ec89df5L }, + { 0xb849e352bab45d24L,0x290f0307d313f461L,0xf083031cee885e9dL, + 0xdf42a973a60bf2faL,0xe39f2118d4842999L,0x8b54cf1d0508febeL } }, + /* 53 << 322 */ + { { 0x8942b4df0d846a3cL,0x18db708662b6605cL,0x6549e019fafa6508L, + 0x85d97fce43ef9443L,0xe9f13da373485de4L,0x5743297bb0f46e8dL }, + { 0xc52781bb70908255L,0xcd88a48a6bc6e666L,0xf857caa5eb4f54d1L, + 0x32dc925320974dfaL,0x6dc79fad965146e6L,0x24e3a8d2edc1f747L } }, + /* 54 << 322 */ + { { 0x1993fa650e81671fL,0xc6acd9f3dd1a1e4fL,0x227edd1a7bf36f1cL, + 0x4ad2478370867ca3L,0xed0254f758b9a7c2L,0x63fe279a7013a5a4L }, + { 0xa65787ee232e6a88L,0x5faceda487161d5cL,0x36e351b603d64c37L, + 0xaa265f1de9e30871L,0xbf3432f521e6f66bL,0x69d68c068621289dL } }, + /* 55 << 322 */ + { { 0xd2bd143ea0807eeaL,0x474ad99582568efeL,0x0fcd6bba7d482c5fL, + 0xf83e6f15e2628f4eL,0x314508252210e41cL,0x8f0a9402f47de776L }, + { 0x7f20bc562ee4d1e0L,0xed4157de791aa7a7L,0xbe443399be2dee9aL, + 0xb461643371625f13L,0x1be21ba8771f55c6L,0x04b3035a300fc187L } }, + /* 56 << 322 */ + { { 0x0952b888b9d0bdf0L,0x3973763c8ce32fb7L,0x221f0ba56dd860c7L, + 0xbb7a27feb16ac501L,0xf113b194bc8fe58fL,0x18f3297a65839ffbL }, + { 0xa2d4eb7c8dc30003L,0x3fb4b4878e334479L,0xa4f32c651a8310e3L, + 0x944cd644f78f46acL,0x14e40c4af96fb91fL,0xc31402bd4ddf6e72L } }, + /* 57 << 322 */ + { { 0x9eb2c9e51ff0ab88L,0x0a29fc0695cc3436L,0x3f4b4ebdbd298127L, + 0xeb8ad8b52ef56848L,0x6159700f5b211ff6L,0x8fb98f2fc3a67bc0L }, + { 0x5c5998ffbd195b66L,0xea99d6767e44a64bL,0x314316e4bafd1471L, + 0xb5f48757cc8c0e77L,0x922a91d15b259ac8L,0x2458279cf9fc4e4eL } }, + /* 58 << 322 */ + { { 0x945c5a3c6aac3e97L,0x5cbdfad9a266ad50L,0xa3e38114fe59f5ceL, + 0x1ca1cfdace3ae206L,0xbe1f15e12a84cfdcL,0x682514726a12ec3fL }, + { 0x48409f871f57341aL,0x632c369e8461bf7fL,0x1c96fc87d8865ed4L, + 0x1727934ae1ffc51aL,0xa60f0ebb6d71f51dL,0xb6c354052e411888L } }, + /* 59 << 322 */ + { { 0xc7b3d3bb72a77726L,0x04b9bdfbbdb03d78L,0xdbdbaa7e2fe88db4L, + 0xc5848e58564710b6L,0x7bbd84863ec55713L,0x1b5aea5670183191L }, + { 0x95d91bb25340d9b7L,0x9a1462e4187a3252L,0x5cee9b8cec352fedL, + 0x7db8350137049284L,0xa1d2822cd3b714f3L,0xe4cf6d53c2e51da6L } }, + /* 60 << 322 */ + { { 0xdb2a2ac9a63f6f62L,0x4c0d2da695f20639L,0xa485a6adb475e177L, + 0xf6dad8b5aa93055fL,0xafcc1e954974bc52L,0x6686940224fcf32fL }, + { 0x10c138bfc103b013L,0xe74ea82bc6faba1bL,0xddb399c581824de5L, + 0xae797b70cdaad079L,0xc648e7ad6ea955e2L,0xd07c5c919be79db6L } }, + /* 61 << 322 */ + { { 0xf4b7a33b39d93befL,0x4be176f9659da9f0L,0xbf57d975f36642cdL, + 0xe10b452d16d5528cL,0x7c062421a6bdd74bL,0xc093e346e7aa1d9eL }, + { 0xb7cc38cc2f5c19ddL,0x9fc7f69b230c8790L,0x9b667acd5e3c5282L, + 0x1cade31144cd22ebL,0x53a0d702bb43a1e4L,0xb25868777906519eL } }, + /* 62 << 322 */ + { { 0x46e2415deb5003acL,0x05aee8855e8a6a0aL,0xbda9f162bbaf343dL, + 0x658b350b21853341L,0xaf6b4948ced47246L,0x1d454740723cd3bfL }, + { 0xc4b7ce3fe1aaef54L,0x619420daa35c9e24L,0x65d455b14eb7a52cL, + 0x2f9b700a4c961515L,0xa5b7b962d3aed448L,0x4e32a6d937851d3fL } }, + /* 63 << 322 */ + { { 0x2c4c1b2ed00f8cb9L,0xbf83ba500fd305aeL,0xb75bcf9f801a8e64L, + 0xd8ab465ccba76b29L,0xf5a2bcd74ea718f4L,0x81501d563b592ae0L }, + { 0x9734e4e26ae6bac5L,0xc4860b0eee304e5eL,0x8bd59b7b1d59f1acL, + 0x7c9497e8e799594dL,0x4bc6634c08292918L,0xc45583aa92619229L } }, + /* 64 << 322 */ + { { 0xc5ad791eb45a8002L,0x4a23fd68ba2d7a40L,0x673b9e4998544bc4L, + 0x934d8f55d273c360L,0x7fb48d0768a75a8cL,0x2e6201055e0fac97L }, + { 0xbe01655ff10ed580L,0xd21d52ae9e96731fL,0x74f830de53325138L, + 0xa7240331de9f3fc5L,0x96b25206a7e01fa5L,0x3fcfedee07eda4b4L } }, + /* 0 << 329 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 329 */ + { { 0x3e6e93818d5c039fL,0x809494228a8d2cc9L,0xf2d7c8b4b843ec06L, + 0x0055d882af8a23f1L,0xe848010ed3792335L,0x9b41a55f55e08e74L }, + { 0x956ea8e95de83059L,0xf159a9973263678eL,0x5f7b9271cca1b548L, + 0xd41d2281f1d0b7f1L,0xb187047b5c9963fbL,0x213ff6af02536cd8L } }, + /* 2 << 329 */ + { { 0xe51a95700d0fa76cL,0x67c7890e4d2e9c8eL,0xc6160fa2f974d2cbL, + 0xe00474f74c6a78deL,0xee916e510ac89d11L,0x1adad97af826f133L }, + { 0x3fc65d3f8d2d77f3L,0xda9420750ba6c300L,0x5237a82e0b9196b1L, + 0x4975e680a572b6f5L,0x41ea8b92b9bed2bcL,0xbe0ad7109826825eL } }, + /* 3 << 329 */ + { { 0x06f721d30a9ec81fL,0xf0359222034f3e78L,0xc5ca6b7a5a44ffd9L, + 0xc53e328915764390L,0x7f16917459747d7dL,0xc3a9981461f79122L }, + { 0x099f4e3a97aa46f7L,0xcb0570c9d70458a6L,0x270a43576b72f327L, + 0x9d6bb26cc33695bdL,0x60f9202126224902L,0x8eb0e108e1b0a51fL } }, + /* 4 << 329 */ + { { 0x8a390dca9fcaba39L,0x3879f0b4278d22b3L,0x77bbea69bc5e82f1L, + 0x71f02e2d4628d6f1L,0x6260790cf968e240L,0x1c7f3df5665270eeL }, + { 0x336395451a87b1c8L,0x2011fd214ffd9fb8L,0x69060f867807ed55L, + 0x1b0ac0119dfa452cL,0xbbdb25fe06d27c0dL,0x5c25d23aa60ef90cL } }, + /* 5 << 329 */ + { { 0xc08dc153d9f75d6bL,0x5c1f07e7a0330237L,0xb3e6fb677d67a5c9L, + 0xca949ed098f9faddL,0x48b16b2dd7720835L,0xfdb1b735fee4d341L }, + { 0x1a6b37b1debf3207L,0x5b3eeb1e3218c63aL,0xc19b57b504c23b30L, + 0x178bd3bb40669e2dL,0x74e57b26fb6b162cL,0xc3626931a0932b58L } }, + /* 6 << 329 */ + { { 0xd3eb69e4734b2e9cL,0x1c2754e2c35ff1b3L,0xa26681e69f3e8c51L, + 0x7892ad11a2cae737L,0x88b1da43cbd8bda6L,0x8a576942419d21c4L }, + { 0x7c124343c90f4545L,0xa5a8d93b26453baeL,0x9a4c08fd76ae72e8L, + 0xa08b82d97b064e94L,0x4f803ba083725330L,0x33672455865235f3L } }, + /* 7 << 329 */ + { { 0xf7a5e2f0a51e695fL,0x3099bf9484adf10bL,0xb2a03c0f22a3ff04L, + 0x30303a910acec674L,0xaccb2f3ca59522f8L,0x00ff4d88f273ba94L }, + { 0xf0056b4210e735ebL,0x3337279a7786e93bL,0xfecc77c44bb3c31dL, + 0x3385bf5be0e26a05L,0xa9454ab85f45fcbfL,0x41a4158346edb553L } }, + /* 8 << 329 */ + { { 0x1877dfd0c8110f1fL,0xea88f59d18db27c2L,0x9d089536c78e295eL, + 0xcbb5d55374a04cc5L,0xe3666006827f75edL,0x8557b81a61e7378cL }, + { 0x74170170ed223f48L,0x84197a6ed86ee829L,0xd75a30f8ac1c4a0fL, + 0xd7e7be0d3cd92824L,0x5ea0abdb1b5e86d4L,0x41146ae1b3b615efL } }, + /* 9 << 329 */ + { { 0x6d340fd3fabd376bL,0xb5066b1ccc169cb3L,0xa4148142d20ef8f1L, + 0x0c5d66fb461544d0L,0x84c7a232d67043d2L,0x4c0e77867e609af4L }, + { 0xb1e83f1af4619e4eL,0x40fca1a0b225d174L,0x39bb3a882e42fa4dL, + 0x04dfe833d2682205L,0x49016d9d685296f8L,0x2da587198b735155L } }, + /* 10 << 329 */ + { { 0x570deceb1ae5e9daL,0x5c079c70b73ead01L,0x522a30a6d2ce6639L, + 0x71dc5c3ff4056ac9L,0xd93c7a2dbaac149fL,0x5c3298b8f1844cebL }, + { 0x282adf408c23c0dcL,0xbe4981899b646f86L,0xe77c1950628da9e5L, + 0x38cc27baa1fd5a18L,0xb5579728aacdca52L,0x8d34fdb4c8e1ecbdL } }, + /* 11 << 329 */ + { { 0x563e0b8a7a7fa597L,0x6697c375bb7dd079L,0x95758ff6c6233951L, + 0xca07993fa2059c40L,0xc3065507ce2aaefcL,0x9faed33c6ea927d5L }, + { 0x0f8b48241207247eL,0x0044f6115eb2263aL,0xd7c9ce7c851596fcL, + 0x54729d523c69d424L,0x42cbdcca45876770L,0xc1e0e6ceeff2adcbL } }, + /* 12 << 329 */ + { { 0x323f2102adea7d6aL,0x035b354eb694b253L,0x66dc4e4a5b8a36c2L, + 0xb609222471795ca4L,0xd8c6d7eed300d80fL,0xf31f258db3b94954L }, + { 0x0f2eb679277ced5bL,0x0b16efa3eba40e3fL,0x400035070dca4f36L, + 0xd34c91cb59a9a3a1L,0x5e8fea3286da6408L,0xf237959f03f31728L } }, + /* 13 << 329 */ + { { 0x1d3173653412e8d3L,0x1d14cd1b09695abbL,0x9044adf2a2cda00cL, + 0x60a6ccd60b7ba011L,0x614b100417284b46L,0xfb3d84b9cf840203L }, + { 0xd65b3566532b068dL,0xc8c03996c2465150L,0xc9035c2df71c35f4L, + 0x350231a752222e21L,0x59440020451935b1L,0xd723a55cccfdd206L } }, + /* 14 << 329 */ + { { 0x1b5bc630bbaaedc6L,0xe7d25088b49cbb3bL,0x5622cbf70deb8cf0L, + 0x3b20803cd309c3baL,0x64c2e7deff45e2fcL,0xfa730ffb9aab84a5L }, + { 0xba83cc514edfb52eL,0xe05c0140748bbd69L,0x27bbb5f52254ec43L, + 0xca740989324c8c40L,0xa21488b1d26491b4L,0xe2753a1f69d8626bL } }, + /* 15 << 329 */ + { { 0xea04908f64dab001L,0x8ea1f127b4debb2eL,0x87adb69534f155a0L, + 0x41595cfcca8afe0bL,0xffef042f8763ba08L,0xb7b4865decd3e667L }, + { 0x2c46c97070c4c8a3L,0x1ab18c080403d206L,0x08b2d3c94b3df379L, + 0xc6a4c268a87a7166L,0x449bc61f5323b1f0L,0x8d4b7ced489ada74L } }, + /* 16 << 329 */ + { { 0x618ca06b8956146cL,0xd51f1e6f552cdecfL,0x981372cca3b6ce7dL, + 0xb44a68ee5f14bb57L,0xfc1167e96373abbbL,0x3d621f8b767d4c0aL }, + { 0xc6dcdfebf6ecc778L,0xddda926282d1fbddL,0x477501aabfcbf2f7L, + 0x0be7228a67aa8277L,0x5de7b8331daab9cdL,0xb88a4f9a262feb4aL } }, + /* 17 << 329 */ + { { 0x203a666c608fea53L,0xbf71f8fde8979c08L,0x3bd58feba22a3d2cL, + 0x596bfcf521f178a1L,0x6f207d89f84beffcL,0x8a7c6dbb18097607L }, + { 0x208f5e64a1c5c927L,0xd7d0e33478dc83c3L,0x5e9397261d4e30f5L, + 0xf3877242fa09a36cL,0x68e4338ae6a7b0feL,0xcf8cd131ac47b369L } }, + /* 18 << 329 */ + { { 0x28f18586936fb33fL,0x9809b2ab381bf7bbL,0xf6e16931eac3c252L, + 0x366d18335e151187L,0xe5b4c2357a3b6460L,0x693a9fa50a68bc91L }, + { 0xa35f104a6a7f8b6eL,0x3e5d6981688676c4L,0xc0c081b10651a609L, + 0x6df5da2dd77057c9L,0x8bb271bbc4602847L,0x322547b3c4bd07d8L } }, + /* 19 << 329 */ + { { 0x9b56b9444deb8158L,0x5f4b15a6da5eb70fL,0x120afa9514cb0126L, + 0x01f6d00d6bdd0d78L,0x73dd7c5c463b1ce6L,0xc770cf35df00a133L }, + { 0xb5db93a1247ff879L,0x1c12f3f0c70ecea1L,0x10168c4e5b59cc9cL, + 0x1e9e0f8a0e19efe5L,0x43987dc1cfd44b62L,0xb1d265c204814e2dL } }, + /* 20 << 329 */ + { { 0x8c283529233d39e4L,0x96300796c6092096L,0x2c549de55dde766cL, + 0x27e0b444b4151002L,0x802e5fc3f2f88f1bL,0x2af579c28ba1956dL }, + { 0x52edd04ed68196c7L,0x2e22e71474a202b0L,0x338948248bf66459L, + 0x8f0d8c259e39df55L,0xee4f109e6c5276d9L,0xc0c893f0c5dc0bf0L } }, + /* 21 << 329 */ + { { 0xa3081bc75b3f17e5L,0x299e7a0222e46b9dL,0x36184c98a9afa278L, + 0xee2043319095a8a1L,0xf5e54622cd5ac080L,0x08d649013fa844a4L }, + { 0xb20ddfc6d7fbb42bL,0x15130bdbd868a81eL,0x25e5fd2f32ff1a03L, + 0x907e3c01ca5288d3L,0x2f2f7496a1f6f96cL,0x831feefd38ab83d9L } }, + /* 22 << 329 */ + { { 0x06054c76f8482849L,0xc24b4a6a5fcca65dL,0x71c27e01a17ebda3L, + 0x1ffce0281be9dfb8L,0x3784c950ebc43854L,0xcf0ecc2dd5086510L }, + { 0x86d0fc3cbe24d8ebL,0x5bad01911f21788eL,0xe2c3bcb9c49b3a12L, + 0x66f82433f7d5992dL,0xf7cc5eb913969246L,0xe52defd48660a6daL } }, + /* 23 << 329 */ + { { 0xd6d6a42b102490deL,0x9e6532acf40d27d7L,0xcd1591cdf2a08bbeL, + 0x973e09f234eb47ccL,0xb3a5915add4fa316L,0xb36ca6ceac38218dL }, + { 0x73d370b3e58a0cafL,0xbc8fd39f07766be2L,0x3d5d9ef7c2ea7997L, + 0x22877500bbfcc1a7L,0xc54d0c6406e0547aL,0xf7bc1d2d564e9ef1L } }, + /* 24 << 329 */ + { { 0x7a9623b653fd1a04L,0x13bd35bf3a3b8500L,0xf8a5dec9e0f8e530L, + 0x88bcbe291d65dcd4L,0x09fe38036739541cL,0xebd04b7fe716a97aL }, + { 0xbd8e34df1e5ef7cbL,0xddfc4243d7c4fd6cL,0x0183d9053519411fL, + 0x63450996f7a3c483L,0x18283cea01355739L,0x8c1d72cf9aaa72f7L } }, + /* 25 << 329 */ + { { 0xffcd4b6f9be9ff57L,0x0bff01bb939327efL,0xde596626b5ed90e3L, + 0xc07464ff4379e17cL,0xefd3e2c470d31340L,0x78b2192f4e7df61bL }, + { 0x7cfe28def3faf2fcL,0xd2d1a994dd642f87L,0xa5d4fb1410b3377eL, + 0x2cb4978ead6fa00aL,0x5b6fe7a765fb3688L,0xc26c1b3336d5acdeL } }, + /* 26 << 329 */ + { { 0x551e1b4e8dc72468L,0x8a926cb2a7b2f1acL,0xb873e83b0fd12fadL, + 0xb6cde14fa4e7fb13L,0x81ae41415befc256L,0xffb0c636b4c7631cL }, + { 0x80f1408f8a2478feL,0xde6d051d44fa7605L,0x5a15b1f84d44a1e4L, + 0x1a0031c5a0daafe3L,0x304338dd597652a7L,0x6830dcc7f257f17aL } }, + /* 27 << 329 */ + { { 0x62fae4072fdc8ea4L,0xff77522fcbe76ee3L,0x5fa03a454fd2bae6L, + 0x774c635e8dc90431L,0x718081b62ddc4376L,0xf4901a2c03e7aec7L }, + { 0x5339a3109eb023d7L,0x15dd4f96366e35f7L,0x1f802d4a0e2d2e95L, + 0x8e5e9cb2fe1b1226L,0x175806f623a0de5cL,0x115a97db068c7bbdL } }, + /* 28 << 329 */ + { { 0x4a67ec76193aabbcL,0x3da6dec6d74761f9L,0x751720c90b35bb70L, + 0xe5e049058d9e0f8bL,0x3cd37c840858f29cL,0x7ff1abfbb881733eL }, + { 0xa0c2698b0c4f7694L,0xc736419296b95e4eL,0xcfa55c5537ece651L, + 0xa2bbd6ae7cb1e9e1L,0xcd2292b9a0eb0e8aL,0x8aba99e18d5030d0L } }, + /* 29 << 329 */ + { { 0xa3f508a498fa3d8cL,0x4d894cbf45bcff40L,0xbcdac17d0c095cc4L, + 0x397caa6f407c2ed8L,0x2195056b5f97b4a9L,0x41eb6e0e97434508L }, + { 0xbb5e4e4a73f211f8L,0x5e8e638f720a451cL,0x8470bc9e4974252dL, + 0xc487aae29f6a9a96L,0xaa66417101165deaL,0xc8af7172b603771bL } }, + /* 30 << 329 */ + { { 0xb7c74c58dc4a1d3eL,0xe3ec30160331ea39L,0x83afb271023c8712L, + 0xc2670d56c9c82680L,0xd426f350feca1061L,0xe8aee692ba6edc01L }, + { 0xc916fbe546e801d9L,0xcb001c377097286eL,0xfcf79d2678ee1328L, + 0xb05b0634b6a4afb3L,0x2ab327bb306da14fL,0xc11a0294ba5ff534L } }, + /* 31 << 329 */ + { { 0xcaa287c30f00dfcaL,0x9ca672930601cc7eL,0x435e883fb105d00fL, + 0xf9cddbf91238536aL,0xda604ccb45f558c3L,0x7e51d9d182f48366L }, + { 0xc1e8d50d7e8396c3L,0x58638b85edbb75e3L,0xe926aabe9b088d2eL, + 0x8103a34a428c41e3L,0x03e5e35d089deeedL,0x64969c6d93bb0b99L } }, + /* 32 << 329 */ + { { 0x7b7da028e19763ddL,0x662f54df8b98ff78L,0xc056d83c51f3dbd9L, + 0xe2f4d46fa91d085aL,0x31759c9ceb35262dL,0x624d0cf20c9dd29eL }, + { 0x108cf9bb1624b02dL,0xa241444e345531d6L,0xf69816b273d372b2L, + 0x126575a7d5415e53L,0x546bb4c1306b8b0eL,0x82bb0c124d54ea5eL } }, + /* 33 << 329 */ + { { 0x85b355304c397362L,0x218a3b0eeda72e19L,0xd8eae54461729c56L, + 0x3d9b4a62735b571dL,0x12f3ee775629e437L,0xa72f9809095e5378L }, + { 0x5420a641bbe6dd1eL,0x8121eb3d02f41fe9L,0x5698eaf945e7acbaL, + 0x8a5e1a89469c2f12L,0x801740e25b434e0fL,0xa4dbe1cc670f58bcL } }, + /* 34 << 329 */ + { { 0x2f1919df5819e9f2L,0x156489e7a62287a9L,0xed038deb20a0c2caL, + 0xf63ac2d5c5ab4fdcL,0xca2b648ce391ec06L,0x8258e3f45b047d2eL }, + { 0xb7dcff56fd17b40aL,0xa8ace11f4bed747eL,0x542d70d175018429L, + 0x6c568967951bb2e2L,0xce420f73bb0e089cL,0xdae9623ed13f8eb5L } }, + /* 35 << 329 */ + { { 0x2d561034009a41d3L,0xf078204f5734d3a1L,0x2b8973ff7408e71fL, + 0x07cb9f95aab9c533L,0x376c1f59d0b35fffL,0x4a756c7fe851b313L }, + { 0xdc690e9874dedeaaL,0x625b082f70cf3f5cL,0x44839b5803dfc301L, + 0x5835a6c3c520f618L,0x695425e3afdb68d5L,0xc04ce4c62db97ee7L } }, + /* 36 << 329 */ + { { 0xc1d9b27ecb5833e7L,0x9911909567a8a669L,0x9317f8c30ab9ee27L, + 0xfad65eb9f34551e6L,0x7725ec2e016504f6L,0xca492cb47ebbdfc1L }, + { 0x6d2a3c962706aa66L,0x53e6d650836d8ee2L,0x109496434bc84bf3L, + 0x8442ee826df7c0f1L,0x7ab2eb9918fe80c5L,0x6a8579b35cd2ea35L } }, + /* 37 << 329 */ + { { 0x96adba7706e80e68L,0xa8839d6a0fe580e1L,0x755227e337a31a9bL, + 0x40b5fc70e27ec051L,0xb900a11b29af222aL,0x8fea2e509dd84811L }, + { 0x4f844c8861b59ab3L,0x26739874560c0948L,0xb39f85ba0cc08828L, + 0xcdce2fca829082edL,0xbd17998eb4555dceL,0x827eae97a3608a9fL } }, + /* 38 << 329 */ + { { 0xa77087f4c98e17c4L,0x9fa12dadbe2985a5L,0xa68cabc94bdce4e2L, + 0x222a6fb6d3500913L,0x15e28fd5a9c0904eL,0xed31c63f7a91f825L }, + { 0x9cd9f3e56f2f35b0L,0xa2b14261923cab8dL,0x71a780516d8ccbeaL, + 0xf1fe532bdfa937b4L,0x6e3d7252539d0a74L,0x27ef2720814cd797L } }, + /* 39 << 329 */ + { { 0x8bd8341e6899b9bfL,0xc2ea111680865aedL,0x0cabb5cf13fed0e6L, + 0xa11e82c1e4ce70c0L,0xefe3d4eb99aba16aL,0xd774db4dd8df10c3L }, + { 0x72ee5c98bae14dbaL,0x9161d0b179b86e02L,0x1ba8b84585e5ba90L, + 0x3830148f17228bdfL,0x222499e2ba89b2a5L,0x5d50922cccd4f87eL } }, + /* 40 << 329 */ + { { 0x81dd074e4398751eL,0x87b11b480a3f3ebcL,0xb5afe1f0352b58f5L, + 0x6d2d94829c390eefL,0xd073f9a0f36a8d23L,0xa7c5abec466ebbe5L }, + { 0x968c04a60539f145L,0x52a3ad0c93f4d3d3L,0x98e196bb15c0970bL, + 0x2af28ea370ab8ddaL,0xb912fbda7a039fa9L,0x3dd8d87acbd02ff6L } }, + /* 41 << 329 */ + { { 0x849b2f0b4ee5ebb7L,0xfd1b015158bea2f9L,0x260a6b5bfbc530f9L, + 0x2b6c198d06776366L,0x6540793f8074c6d2L,0x1c722c259871be11L }, + { 0x8ce5241ce0560ce9L,0x3574db548096df0cL,0x1d9dd078b0fb8c98L, + 0x6049c7f25625a023L,0xd2c0853cb18d0dd0L,0x5e57bd71cd645f78L } }, + /* 42 << 329 */ + { { 0x8da9b831361ce377L,0x6496515b7dc06076L,0x870e7df3b8cba83eL, + 0x315ac0049f8f495bL,0x1a09dee576fe0978L,0xae7af621c18059a2L }, + { 0x2bc9dea404fac2afL,0xc630bd5021b90a79L,0xbded6b8628c0f9a1L, + 0x709d72c7be4fe93cL,0x3d1e2eed74b22303L,0xcdaf6b1d0e81dfcaL } }, + /* 43 << 329 */ + { { 0x42d004f3be8ec138L,0x5379a3063d617cfeL,0xcbbd274ec1a87d06L, + 0xb9967c5284c9df0dL,0x0238d715c421e288L,0x787ee6abd239639fL }, + { 0x746e4071adace009L,0x2e2545db61377666L,0x47cc241cf07deb1fL, + 0x0a0742f1847dee19L,0x50175dd06e59b0acL,0x95ce3065d2333a87L } }, + /* 44 << 329 */ + { { 0x65c33cf4ca5eba6eL,0xbc48b22e12c2f19aL,0x6c5bbde461fbdcb0L, + 0xe086202bbc503a00L,0xa9483799deecbb11L,0x9b2c0216279aff50L }, + { 0xc10fce1069f99456L,0x2b0051d5b7820d55L,0xd2de9cc32129b5a4L, + 0x711166d9e4f565d6L,0x7a8c3dfb88075f30L,0x6914edda224ac45fL } }, + /* 45 << 329 */ + { { 0xca481b6e4e1e3cabL,0xf390ed5f7e12d8b5L,0xcda82616dcd06247L, + 0xf7d791422cec8917L,0x0c2ea9fe2364e5deL,0x471b71ed21f98e3fL }, + { 0xbebd6a753b9aae94L,0xf9914c0b45f5d5a5L,0x07c823ca4b3dd18fL, + 0x0b8c09ab74ad2bafL,0x21048cf7c7376302L,0x080e4a00efb16ac2L } }, + /* 46 << 329 */ + { { 0x1699d711379e6c77L,0x9126d88c7427418eL,0xbb05797d825210acL, + 0xc0b611df315cb277L,0x90f82a9d61f69206L,0x39a79014f517228fL }, + { 0xd9f2def450e8a693L,0x88c1104381e9d71aL,0x28e20b56451f8a9dL, + 0xeaa794763e101231L,0x3f1ba0c56423e8c3L,0x2fe7ce4e3c6c558dL } }, + /* 47 << 329 */ + { { 0xd706ab9cc55b1a3cL,0x99c453663aa386f6L,0x348c8f743617676aL, + 0x5f3c49092b9ef7bcL,0x26969963ff5d4864L,0x1f952e03f5b490ffL }, + { 0x4007914e30cd5518L,0x3b38fd1e0b0e6513L,0xb25e0a81decbba43L, + 0xb7e77345a7d78431L,0xbb7bc23062467d4aL,0x616c1724598ad852L } }, + /* 48 << 329 */ + { { 0x5bcf287864e60ac2L,0xf70e78a455d53345L,0x88685de6707a7138L, + 0xa77646dcfb2041a4L,0x8608695289db3060L,0x08b7c4d8e27a1690L }, + { 0x4148d9373ca7fd81L,0x58c7440bff7698a8L,0x9d722d4db0391d14L, + 0x5683112462b0373fL,0x87b0363be9a9992cL,0x51870cd18853db84L } }, + /* 49 << 329 */ + { { 0x775086f481eb73b1L,0xddf02d0e4db4d236L,0xab3d637445b09e54L, + 0xb7ef92657e883a2eL,0x20e6ae8f7f42b4b3L,0x26a14629bc49d85cL }, + { 0xf0ee4e5ca4ed9ba3L,0x288c5b0793b0b721L,0x9c767a59e9917114L, + 0x3dde322015085ec5L,0x3176507f7ece24dbL,0x71e1995686cc47fcL } }, + /* 50 << 329 */ + { { 0x86dedf2e9b1ab85eL,0xf3330387c2d0593eL,0xf5e6143997e907a5L, + 0x1992569d8cd66e4aL,0x836b215e0869329eL,0x8b5c4891153ff215L }, + { 0xf6c52f1b609dcc15L,0xa3a5258c085722c3L,0x0a4e81501c378dfcL, + 0xa8997ddc739040aeL,0xb1c4417a7180a073L,0x618009bff1dbab34L } }, + /* 51 << 329 */ + { { 0xc276e23733ec753fL,0x196a1ccee112da60L,0xcc049e2b953211efL, + 0xa60e1aa711dcc43cL,0x091ceb49cdfed2ddL,0x8fe1c52e72c69037L }, + { 0xf66eac87a986ba11L,0x4917f822b273d90dL,0xf7ef04cc957befacL, + 0xf8a7ac1320b8aeebL,0x71f0db3dbe6af428L,0xcb0bf8ba566429c8L } }, + /* 52 << 329 */ + { { 0xf617674d2cbb40a8L,0x446ad46b4d11399aL,0x4d4246943076b6b3L, + 0x1b9e7d881c33ea9eL,0x8e1aa6716954589cL,0xf1099b26e221722cL }, + { 0xb18904f94917576eL,0x0512b21bb549058bL,0x12c89a64a209ad3cL, + 0x421f5e575557cc67L,0xb42e17371b5a17edL,0x427c6a621ff3230cL } }, + /* 53 << 329 */ + { { 0x74e75db02bfb49e4L,0x7685588d58cf18dfL,0xfbfe8f56398e27a9L, + 0xd2711ec365666b9fL,0x1df7714d2c59b787L,0x0f2c4b4c486f8fc0L }, + { 0x098ed315f847b688L,0x60c367e332a20ae2L,0x58f48cd6bba6dd13L, + 0xc41e31960616128aL,0x7f90dd69a3205005L,0x8e6ce9d23581c177L } }, + /* 54 << 329 */ + { { 0xcf2da6044a3b3618L,0xcfd27cc6b83f1814L,0x8cb45c0a6b9369a6L, + 0x1f11501633976ef1L,0x2654a1574afc708cL,0xb47f423860970498L }, + { 0x548be9389fd8536bL,0x454fde1673ff1ecfL,0x44657efae96be82dL, + 0xc8e7e96b555df813L,0x2a0b3f4a4fccb822L,0x2e0f36b114b6dfdaL } }, + /* 55 << 329 */ + { { 0x227ba88551cefcb8L,0x81e8f52e00071a19L,0x4afd5a5d170fee3eL, + 0xc8864e274e17ff05L,0x1d8c2083710ffa4dL,0x22529baa9839c46fL }, + { 0xad771341825a0a87L,0x34a3049edad7c56cL,0xf1f14e1712f3625fL, + 0x6103d1fabcd36dfbL,0x9f5ce7a949a7cf78L,0xa5a4e38a333cf634L } }, + /* 56 << 329 */ + { { 0x6c8e5a261d99492cL,0x6e5bab8e77f916a3L,0x9b014aad50ad6f39L, + 0x2a3933c51f107e26L,0x4b04395cc951bf73L,0xf8f683b4b0ef56dfL }, + { 0x28c9fcdd1905c84fL,0xb03604f14141feacL,0xb546f58e53ace23dL, + 0xee5fec4efe688f02L,0xd8b43f6d2e91406dL,0x75e44b21261764d9L } }, + /* 57 << 329 */ + { { 0x56905026e84e6549L,0x1dc1958c5b84b0b7L,0xcb477afba55d3c52L, + 0x6c67cf7bc1434094L,0x739da94d2ecb03edL,0x8c45e5ee778ca2fdL }, + { 0x66084f9712e2fe43L,0xee6a89e66c3289d1L,0x623b73abc5d1a215L, + 0xb0edfa31cbf45830L,0x8024dffbd7de3b1fL,0x2ddf805a27f25caaL } }, + /* 58 << 329 */ + { { 0xb4e5a5d5605d7341L,0xe7a7a4069a1d3465L,0x234783d66c60b1b0L, + 0xdd7ee2fb3b480129L,0xfd183240dbb7032fL,0xba2a97accaedc8c1L }, + { 0x1a1824d3b0185c9bL,0xddc0f82cd36edae3L,0xaf7bbcc03116b17dL, + 0xefc9095985f6e8e4L,0xc6bde428acb9c328L,0x69d80732cbf991a7L } }, + /* 59 << 329 */ + { { 0x455a23a465ecec1dL,0xcf0b2a221d9e9887L,0x0b43131e3fbb1cc9L, + 0xd4ece789bdad49b9L,0x370c2f9aedfa4d17L,0x7f6855be15163f17L }, + { 0x868a16f3735ecbd1L,0xd84527db08897c01L,0xcdbf5b18f2df294aL, + 0x8c500b1f12b99a2fL,0x929c58df2591e3b9L,0x314cb13714eae6cbL } }, + /* 60 << 329 */ + { { 0xd014cc6deda2479bL,0xd2586003f1a85fb5L,0xceb0611153cd207cL, + 0xe8c9fbfa647b3c16L,0x1f53e8e6ab7d6738L,0x06dcceabb060b5f3L }, + { 0x80e023b2ab770ccbL,0x83ca0a5f4cda70d2L,0x19f7f5dfea1caa2cL, + 0x769041414ffe884eL,0xfa4d93a3fca3c05bL,0xd381f527e88e1169L } }, + /* 61 << 329 */ + { { 0xa4553b3534914b85L,0x03968ddddc176f80L,0x095fb9531f258fa3L, + 0xda9d2df7a554bb6dL,0x012a30ed84926864L,0x3fea37b12aa219d2L }, + { 0x730d2c6d81cc6036L,0x96ea83c9ddd81991L,0xfab080dcef1678dfL, + 0x16e25c6bfb2fe230L,0xf083a2b298ef2fb5L,0x0c0d0767581feac0L } }, + /* 62 << 329 */ + { { 0xd464a6525bc81cc8L,0x513353adebfa99d0L,0xd1aa97c0be51245bL, + 0x0d37e590e4d20201L,0x7afc95cbb45c5c19L,0xdbd640cfb6a4ea8cL }, + { 0xffcc3ff2be9c5b78L,0x61cb76ac1b2865d1L,0xb145bb0011352d21L, + 0x69568e5ce550ac6dL,0x454a33043bf7ee0bL,0xa2fcf9b45dad3642L } }, + /* 63 << 329 */ + { { 0x2e2c8fb3f33eaca6L,0xae1c78b265f75366L,0xbdc601092280d2b4L, + 0xed8409b7b6f472f0L,0x69eafa4f439e09afL,0x3b9ca2ecaa2b1531L }, + { 0x59b2e8eb336e484bL,0x93ec3ecac5f0481aL,0xb01e690ad575157bL, + 0x811aebc262e9d767L,0x1b26c0e49a9065eaL,0x5712d2c969a18827L } }, + /* 64 << 329 */ + { { 0xdaa7fcc9f9474bb7L,0x3c82e74bafa5db2aL,0xfbf918c59894edceL, + 0x470c45eda9ac29a7L,0xdfd44f6fbc372f2cL,0x73a4790aa1e38d3fL }, + { 0x23d2400ba9674837L,0x3dad71bc136a92daL,0xc76a488148baa4abL, + 0x73227e4ebc26e6b0L,0xe732edcfe8ef5662L,0xfe96aa5f0c5662bbL } }, + /* 0 << 336 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 336 */ + { { 0x87c7dd7d139b3239L,0x8b57824e4d833baeL,0xbcbc48789fff0015L, + 0x8ffcef8b909eaf1aL,0x9905f4eef1443a78L,0x020dd4a2e15cbfedL }, + { 0xca2969eca306d695L,0xdf940cadb93caf60L,0x67f7fab787ea6e39L, + 0x0d0ee10ff98c4fe5L,0xc646879ac19cb91eL,0x4b4ea50c7d1d7ab4L } }, + /* 2 << 336 */ + { { 0xcfbcbc4a7db62b5aL,0x2919bf514ab45ddeL,0x735de05622322f91L, + 0xd2590bda7662ae23L,0x63d468fed82be7a6L,0xc84d0435695ea172L }, + { 0xc50f494120a6fccdL,0x2d613990620f44f1L,0x680ccd041fd25778L, + 0x25ddac444a3d0808L,0x41d8b738c4684cbaL,0x2611645f53963888L } }, + /* 3 << 336 */ + { { 0xb05cb834b0279be5L,0x2de7d0ebf08c5f93L,0xf023b5aaefa9e4f0L, + 0xb8061e5d9bd075ecL,0x7d2ba50f1aa41bfbL,0x8963f3e390865d96L }, + { 0x7f221a794713ec7aL,0xc83bc5178500b4c3L,0x085feb6af6ab1540L, + 0xfd141024dc87cd93L,0x3e196fdb3239dbf6L,0xb7cf3e16dbcd5364L } }, + /* 4 << 336 */ + { { 0x1466c9f5e03a2fb4L,0xb866c006862a58a2L,0x291e8c75b5865550L, + 0x1ddb7154e65862ccL,0x285153bc2b997167L,0xe2fce0e7954b6c19L }, + { 0x985d450616dc2937L,0xf7f14216ee41d9c3L,0x39e098dafa5fe5e5L, + 0x3fc26046f90f231dL,0xde5d5ced32afd0b5L,0xad688b1d60c09c18L } }, + /* 5 << 336 */ + { { 0x3720b1720f806b59L,0x1f696d47f224597bL,0x03c46e315b54eefcL, + 0x387e466472b0edaaL,0xfc59b03dee77476eL,0x86854e54607a7259L }, + { 0x1478bcee3e9320dcL,0x4aa825a88c9d87e4L,0x71272f72cf272ee0L, + 0x19e3a4a38bd885cdL,0x9af6415b376ba31cL,0x6394b5a7807b2b36L } }, + /* 6 << 336 */ + { { 0xdbfcfa75e572e06dL,0xafa019d08b7d5653L,0xcc6c851d67a19b60L, + 0xace88bf431ae1a67L,0x74554a6193d1e135L,0x51ba2cdd4211890aL }, + { 0x7cb326899e8d1f02L,0x29a6b8258b66ab99L,0x0a672c21766e72f3L, + 0x24bb718a880642e3L,0x425dc41d184d2b36L,0x96a1468e891024abL } }, + /* 7 << 336 */ + { { 0x3180789c26df7050L,0xe375a43e96cdfd31L,0x7951b895e99e922dL, + 0x987ea2503d0bbe80L,0x6d2f49f0e2fe79c0L,0xc9c2c636c2b18d2aL }, + { 0x707798f3d8c8620cL,0xc2d603dad5c6a0eeL,0x46cf1e32bc447940L, + 0x4dfc145938a845f3L,0x210083fe455e5d92L,0x6be989eaa1fedc3fL } }, + /* 8 << 336 */ + { { 0x72fc8198dacc038cL,0x5fdae1d9f1077bbdL,0x369198bbd99e3036L, + 0x6b68390a0efddfcaL,0x8c35f3e4f0914741L,0xd2bc54ecca7d7807L }, + { 0x564d991e3a8695d1L,0x5e1e14c81b0d937dL,0x51f30dab5d635893L, + 0x0427e346f944e49aL,0x1e0bf1b56a233bc0L,0x75b0ee6c617bf93eL } }, + /* 9 << 336 */ + { { 0xcd2db6797b1bbd75L,0x1ce5acecaac388b1L,0x715ab9f634c1fa9cL, + 0xa531e1b8e0815643L,0xa64511c692de769bL,0x8425126b785b8bc0L }, + { 0xc8d9320de72e155bL,0x9cf36dcd5600a04bL,0xbea8b0f4c6e1f7fdL, + 0x6f9af6349767d85bL,0xc3ea9fa4c403ecb8L,0x0af7be1ed60a0e70L } }, + /* 10 << 336 */ + { { 0x180afdcc20928729L,0xec2e90f436bce72bL,0xa8a8c54d8f48e48cL, + 0x9d0c6a355248109bL,0x8bdd819baa6c3ae3L,0x95e221a6dc0bebc1L }, + { 0x83e568eceb113737L,0xaa6d29c8a1a3a0a8L,0x0ebd5015c54fbda4L, + 0x692a84832a5c8b17L,0xa08e384b51836490L,0xf1904bfc37ded786L } }, + /* 11 << 336 */ + { { 0x2093335463919940L,0x34e4f27397ea3359L,0xbe64c5584d4156a5L, + 0x368a6c980497cf92L,0x59931a502288b8cfL,0x67d70ff8c36cf906L }, + { 0x4175562a8886126fL,0x46ecdd1d55114ffeL,0xd12876f94efde702L, + 0xb0c9333fc046d908L,0x8358b04a2cd6c180L,0xcbaf4612336d3c84L } }, + /* 12 << 336 */ + { { 0xd77d9cd4fe8dee55L,0x7a0f60c12e43fc84L,0xecc5cd746d5da126L, + 0xb5ac6fee2382a984L,0xd9db83e26ccd0feeL,0xaa4dbcba350717d4L }, + { 0xb3c0562c812ead77L,0xf7a995eea96cdd07L,0xd5419bf1ffeb4e67L, + 0xba0aa22e1226df29L,0xb8d0d7f4c1e333d1L,0x86fecca60a27388cL } }, + /* 13 << 336 */ + { { 0x9ea1d715dc579084L,0xc1e715dd0b1cf2a4L,0x624fa6e4926bf7d5L, + 0x5034c9d34f7b4e51L,0xc1b0ed7aba3a42a6L,0xd1847c28b73cdb77L }, + { 0xa4794bc36ae49ff0L,0x50b2d908b9144fa5L,0xad112c778f073479L, + 0x040499dd4b98f590L,0xd415d273152b5e30L,0xd3f4ff3f39054cabL } }, + /* 14 << 336 */ + { { 0x1e0318d5fff93451L,0x40b91fa9283e197eL,0xdebc5a28089ac579L, + 0xcf25f527e9d98537L,0x73f7818d4ae08f51L,0x397f2cb6a956c875L }, + { 0xb7d74ac57515436dL,0xc29a2ffd830664abL,0x02e273563cabe01bL, + 0x418417c103c78924L,0xd12994116535005eL,0x53fc391258f66295L } }, + /* 15 << 336 */ + { { 0x6b1fceac4d87dff4L,0xd31aef70f262f722L,0x894361782612da01L, + 0x1d3bdfa9963bc230L,0x9a46505ba7afa565L,0x662c2fc7a31db4ffL }, + { 0x33983a9ae5ef30c0L,0xb8c874ee723f085aL,0xfb5fbc860f279c05L, + 0xcd9cc376ad0a380cL,0xcb19d881fdfad736L,0x1c3d9734585167ddL } }, + /* 16 << 336 */ + { { 0xd23658c8d2e15a8cL,0x23f93df716ba28caL,0x6dab10ec082210f1L, + 0xfb1add91bfc36490L,0xeda8b02f9a4f2d14L,0x9060318c56560443L }, + { 0x6c01479e64711ab2L,0x41446fc7e337eb85L,0x4dcf3c1d71888397L, + 0x87a9c04e13c34fd2L,0xfe0e08ec510c15acL,0xfc0d0413c0f495d2L } }, + /* 17 << 336 */ + { { 0xf791c8196726ae9cL,0xc95c53f13cee0ca7L,0x816b37ae601b0802L, + 0xcf28a2371b854925L,0xdc4f6bc111d5d9f2L,0x222d6102df6862aaL }, + { 0x93d3fcc5c0053ee2L,0x1d30937fdf873eb7L,0x925a2c2527d098b9L, + 0x8564c199001cf28aL,0x87cb85ed748b8479L,0xd12d6b2b184c1020L } }, + /* 18 << 336 */ + { { 0xeaf36b865bddb3c8L,0xa4bab6e0099f18ecL,0xe22839208addee4cL, + 0x485307e053bb454eL,0xf981c80d362db12aL,0x012190355cb4b460L }, + { 0x62824680c78bd110L,0xf3e0b963d87df5f5L,0xd96de5e2758da525L, + 0xc6a810faa60956abL,0x913d5a7b8e3eb6dbL,0x27c581fbbc9e8c3cL } }, + /* 19 << 336 */ + { { 0x5edcd7dcb0c55d75L,0xaeb0b5c727838c23L,0x13d65db758c3fea0L, + 0xe821d853b36f1f15L,0x3435a4bc365e7703L,0xb890e52f3a04d292L }, + { 0x6a96ae92e7a823f3L,0x3960ecb0ca611036L,0x81638aff210cb460L, + 0x5f95793ce6b983d1L,0x0d5029ffa3ae1a8dL,0x54f749b492ca1229L } }, + /* 20 << 336 */ + { { 0xefe0a702537c4a5fL,0x322ff89c151d0e69L,0xcee88b48491b757cL, + 0x8e92cc15b5da77c0L,0x3138b90bf6af039dL,0xeb73edd2f3748d35L }, + { 0xf29f06435b8bb06cL,0x91ea9643560e4966L,0x013c274875acbcc8L, + 0xdb2d1d9703f1d40dL,0xed7aeef1fcac606eL,0x91395dcabff4b849L } }, + /* 21 << 336 */ + { { 0x952e4e21c8967f37L,0xdc9f71994bf85ec3L,0x6b01f3d00c141bd4L, + 0xc6601dec06c9ba55L,0x7d884fc0c4a5945eL,0xcab1de947e19d3baL }, + { 0x9ca6aff02e3c9c5eL,0x01e828a1445e4a8bL,0xf97165ae80d065c1L, + 0xe2195895881978a2L,0x4834501fc6b77acbL,0xbcf7545445d99f5fL } }, + /* 22 << 336 */ + { { 0xbfc9c5071e434ba6L,0x30768f646f2634adL,0xee3a7cec1caf9c0bL, + 0x27c4fd0bc232910fL,0x5c5813ee24ff4510L,0xe5e731af901f2ce6L }, + { 0x440ca2cf68f9aef3L,0x54ff9e837fa17587L,0x4d792db7982acc0bL, + 0x73c3863834846c98L,0x76cff95f8d6243d9L,0x5fa573399d015583L } }, + /* 23 << 336 */ + { { 0xe0419a6fb007e4cdL,0xc44ac4961f613529L,0x3408e15af18f82eaL, + 0x66bebd87d92d3b39L,0x1c563ee4f85d0c1eL,0xb31a8c891f7eb37dL }, + { 0x65c7bf8c458a056dL,0x9d2ba592f25b6f73L,0x1ac4f0bc94eeb39dL, + 0xa008b562d9a9ac29L,0xe7de714589d1c354L,0x420f5cf04c2e45d2L } }, + /* 24 << 336 */ + { { 0xe11cc2e117cc0d20L,0x9b4cc698d406fabfL,0x6f6e9b0cb8567c18L, + 0xa0dcda9c61b22b83L,0x4c8683fa79ee53abL,0x7d46b3f82f11f0c4L }, + { 0x91e74e482740aed8L,0x75afb62a056466e3L,0xc60bb430e8d0c16fL, + 0x36cf252522b4aae9L,0x3713f254aceb6dd2L,0xc2906379eb8c6fd9L } }, + /* 25 << 336 */ + { { 0x440da0369eb8b2deL,0x6c4d1a38462fbb19L,0xfd86930fb050f995L, + 0x2e5f1a8c954823a0L,0xe9122aefcb9f8e9aL,0xc9e923f2794be14eL }, + { 0xdaa5663dbf740c2aL,0xf3a7ecd6df75c915L,0xa047a07efa80015aL, + 0x846b4d27ea4a720bL,0x2389717e295845f4L,0xf56f77f6cbf2eabaL } }, + /* 26 << 336 */ + { { 0xaac4f6a7e67b6dcbL,0x59ccb836d51c5183L,0x78d19f452b7ccb20L, + 0xb32d4ffd5a619a1dL,0x86b11dbe5c4bd17eL,0xd983e839a9b52073L }, + { 0xfe9c0b92993455c1L,0x3a156676ea36006eL,0x578217fea907ca7aL, + 0xaa3c5489440a251fL,0x6760a166d7fdf3fbL,0x4a2fc54b4415c6fbL } }, + /* 27 << 336 */ + { { 0xaedf171dbe18bc16L,0x00febab2b2d026ffL,0x82b6d8890cdcca4aL, + 0x1b1e4c53445bc877L,0xc2174e10ed74285eL,0xced66cc02b243f6bL }, + { 0x73e9ff69c7b9a66eL,0xc4fe5caad5e4d121L,0xaef80d67402c5d1fL, + 0xd3b95a0f2f3dcaf9L,0x00cb6e798ceeea00L,0x1ee2ca8c436f35e1L } }, + /* 28 << 336 */ + { { 0x0b21c764a6db111fL,0x7c36dfde24c5721eL,0x53a0b6db66e2d428L, + 0x6f37bf728169d776L,0x9baf6385a68511c8L,0xeaef9c919b218151L }, + { 0x712cdd5bdd58d201L,0x50bcd0988d3f78c3L,0xfb6427b571fcb05eL, + 0x6245fe7cc4675aebL,0xb5b75b50fb767bdaL,0xc1d8b76ddd7a18fdL } }, + /* 29 << 336 */ + { { 0x6392686cbb52f636L,0xf10df7c41c46a5c1L,0xab7f88acc504a122L, + 0x2a179193fdb6a9d5L,0x2a7c7e4e2901f29cL,0x3ab41b80a2cc726eL }, + { 0x8f577fc31fb5e412L,0x65cba0aeff7c47faL,0xa79191697f45c04dL, + 0x2712fcaeb29a4c06L,0xf2a879e4099f76e3L,0xd333fabd98a22a04L } }, + /* 30 << 336 */ + { { 0x87a905e056ddf14cL,0xd36289cb95a1c633L,0x2fb251aa57f8f0f2L, + 0xbf9c72a9fb7907a4L,0xb4f9b6f3f771333dL,0x7b5ed437469ea10bL }, + { 0xe8cfa847fa5a8f93L,0x456395c945a4c9a9L,0xe20ffc39f7fac5a6L, + 0x8b07c9ff287a3c78L,0x117f306f67e66d0eL,0x97c8a6388b331e09L } }, + /* 31 << 336 */ + { { 0x1b3e04c26a98318fL,0x04d5ed5dd5a63b2bL,0x4098d09f3cebabecL, + 0x226bb70565a14306L,0x5bdce76fd962a94fL,0x47a66e96c40dedbcL }, + { 0xd514ae5bbedcfbb0L,0xa8c0fe40892f07e7L,0xcf78e224c9186f1cL, + 0x2499f68fe94329e0L,0x3ea3fae5ebbe3d2fL,0x681fca8bbc631de3L } }, + /* 32 << 336 */ + { { 0xb097b2c5c4e81268L,0x7ef175521d50ca8cL,0x638266e942099644L, + 0x43d059deff729073L,0xeebb5fe1148c3940L,0xb82e73d1daa8e925L }, + { 0xf43c78d8254380fdL,0x2beabc58fce37fa0L,0xcdd5a7d66b636357L, + 0x8b70a2ebe096a954L,0x011d5419d0afa2fcL,0x3e49eb6704fb095aL } }, + /* 33 << 336 */ + { { 0x5c73f69fb99abd8eL,0x0a7c36aacc1ed636L,0x9d2fe67e7f69a6cdL, + 0x04d015fd48c34b1fL,0xc50f88c17f84915fL,0xeee3e105a706fb24L }, + { 0xbd42861c734d0513L,0x544b6ef495408b60L,0x4526e680d40179beL, + 0x9f984c4140ab740bL,0xbed7baee67a02ab3L,0x09e3446862a9fb2eL } }, + /* 34 << 336 */ + { { 0xdf64ebcf28eedf59L,0x435531be73b5d9f4L,0x1990df01cf35d981L, + 0xa34d4fa9a2cc41b0L,0x9f643bd6b5a10b37L,0x90cae11158a6cd14L }, + { 0x2b0490701943d2f3L,0x2c9f8af4eda3fc20L,0x48c245c5f96e72f3L, + 0xb4505a3a861355deL,0x4dfab1b9be032112L,0x69c1a9195942de24L } }, + /* 35 << 336 */ + { { 0x761c2c356efcc891L,0xd06710d1fa376241L,0xc83a491c8a78b0fcL, + 0x0c0ee8d8af75b3eaL,0xe6d9d92e4532b587L,0xcb3b652d64eba138L }, + { 0x1cc504ca34ff5d2aL,0x207e7443d0eae0baL,0x94ad1676428382b1L, + 0xfcb5909992ec17c5L,0x7f99e1b5ce3b2e48L,0xa8c38c0fac9bc921L } }, + /* 36 << 336 */ + { { 0x5763ff1af4ba4711L,0x6aac1315bfaae662L,0x51b9c30ede4b5505L, + 0x50e63d1891b25d3eL,0x41938349e65ea695L,0x11260360f514dd15L }, + { 0x231f7f574a086eecL,0xa2c3237f55bd9ee1L,0x8afafa043e0705bbL, + 0x44607900e9fc754fL,0x7250929678519ce3L,0xe751c3a74d17708eL } }, + /* 37 << 336 */ + { { 0x0098a3254611d3dbL,0xbee52036dde82f67L,0xec432a62cdd50282L, + 0xae8a144e52f994f2L,0x027e9e60aa5c03fdL,0x1a49ce47821f55f7L }, + { 0x46fbbd6c4d10c0ffL,0xe14c82ff8c461df3L,0x95570f44aef902b8L, + 0xacaa04ec0eb7eb26L,0x3c8c86a8e738570fL,0xb87d47ccb77cc59cL } }, + /* 38 << 336 */ + { { 0x2f4f68377bbf7168L,0xd5b67947f03f7145L,0x2c6ca74d4cecfe22L, + 0x0e559b9f0a7d6fadL,0xdbcd039ff6b37f98L,0xaaf1f6edfa7a3877L }, + { 0x97b779f0f607316fL,0xe2185ccc72b99fd4L,0xd3f696bf2bdfe399L, + 0x20d9baf15e6c403cL,0xe5bbc1cb4c4f1216L,0xd1c0761a428838fcL } }, + /* 39 << 336 */ + { { 0x4f433b8abd08dd65L,0x27849a72773bd3c0L,0x62351b911854502eL, + 0x836580ffca24ce7dL,0xa5c224a39355258aL,0x8d33fb43e65db7f0L }, + { 0xe44d391edf49a825L,0xc28e0d9bd2f5d4bbL,0xf7208342efb61ae9L, + 0x43686b414dbce055L,0x7f7562d01800c062L,0x5031bd7c8b8ace99L } }, + /* 40 << 336 */ + { { 0xc183199375476a4fL,0xa6383a0055fc4367L,0x23a72dea98bf90c4L, + 0x67ee6f451045a947L,0x4e6518836920d0a2L,0x49132c9ac8042a04L }, + { 0xe249e46d5dfa9fc8L,0x6ff9eba1c60d1a11L,0xa4d9362d43490335L, + 0xe8fad79ade504480L,0x519e8d1bac43c951L,0x7e688047952d6f54L } }, + /* 41 << 336 */ + { { 0x135d677342e27f9eL,0xd58b98fb8fcc77e0L,0xf3bb847d7f64928bL, + 0x15ec841663176905L,0x83e75b6a0f755173L,0x4c3eff5c7a24de69L }, + { 0x289e9a45313bf61eL,0x01b15aadeafa2733L,0xae7fafe1d2cf501dL, + 0xd6fba525d5ac0b3eL,0x4bf48be0689bb20aL,0xa591843255bf610eL } }, + /* 42 << 336 */ + { { 0x0f019b64c5f8df0bL,0x112f06a979307310L,0x91dc57276d16102eL, + 0x34070a5be2651248L,0x0b9f35dbd3423044L,0xf29bb4a072b10ed1L }, + { 0x87071a9a07fb6388L,0x4246d532b7dbdb1eL,0x87db3d2285a039c9L, + 0x76620a5d42b030cdL,0xc798e3816a42d8ebL,0xdd97441ac441ef9bL } }, + /* 43 << 336 */ + { { 0xa9b004a0f08592c3L,0x984d17e5d069c54dL,0xc96f2132ccb87e81L, + 0x67fd082f3b1f9eccL,0xcdd0827ac4ff9feeL,0x9d1025070e04b7a6L }, + { 0x4ff3424177c67935L,0x4f2246f58efea5b9L,0x128085b12fbf7615L, + 0x9f111f65174b0575L,0x0b27d8e2f455cba5L,0xda20626b536054eaL } }, + /* 44 << 336 */ + { { 0x4a3df6de3761fa82L,0xb839d6babc56eb6cL,0xe41afc5e13977a26L, + 0x64022937fc0686d5L,0xa5d6dc19e2d681a2L,0x81afab3128f411b0L }, + { 0xc089aff74321a117L,0x32b0ae2657d18f89L,0x650aacd5f66aacd0L, + 0x7b317bf6b8d3f677L,0x2cd5789777ea82dfL,0x935be0f3c74e7509L } }, + /* 45 << 336 */ + { { 0x4387f8f602de9e59L,0x529c06f337589811L,0x6dbaab60bc9f06b4L, + 0x0063bc3db5f181faL,0x7bcb289969b906b3L,0xdca70d1331d1ea3eL }, + { 0xca65e546ee373e94L,0x13cd365c779f415fL,0x4183460e9d71cb08L, + 0x60f312726e35eaf7L,0x3d0c265f14bc5e0eL,0xe7a1b9af39ce618bL } }, + /* 46 << 336 */ + { { 0xc234c892f46aac36L,0x213076ada55983a9L,0x81f96142dcf335a1L, + 0xf21ceb724b22e311L,0xa12d6333dc053e1dL,0xe7808925a930732bL }, + { 0xb5a9eb81b1f1075aL,0xd13739c0f0a3e623L,0xbcd842e9ff2f24d5L, + 0x200cda381b16ff0fL,0x0a85ea521d6a6c54L,0xe1c0dc8756785463L } }, + /* 47 << 336 */ + { { 0x3287c8d39100f769L,0xb349ce8c052e8bcfL,0x5fdb952dd0d3e44bL, + 0x68715110d0639cc4L,0xc9a5fbaac8efc67eL,0x14ebb97da009aec5L }, + { 0xf0684e1ca1423e1eL,0xb282f2f56357fa17L,0xc2e79d3c5af78041L, + 0xe0ca9f4bd7d2ba8bL,0x20629f1e04dd84bfL,0x274ebccc3ee73228L } }, + /* 48 << 336 */ + { { 0xeb05c516156636c2L,0x2f613aba090e93fcL,0xcfd573cd489576f5L, + 0xe6535380535a8d57L,0x13947314671436c4L,0x1172fb0c5f0a122dL }, + { 0xaecc7ec1c12f58f6L,0xfe42f9578e41afd2L,0xdf96f6523d4221aaL, + 0xfef5649f2851996bL,0x46fb9f26d5cfb67eL,0xb047bfc7ef5c4052L } }, + /* 49 << 336 */ + { { 0xeadd123d385f2b36L,0xe3b14829ddf58569L,0xa4fdf0ec47c7e485L, + 0x93c0d8380623ea5fL,0xeb9c0a2c9e2661deL,0x8046fc69e72e0ca6L }, + { 0x6f439e5c7be1c918L,0xcd8fd2f92a9ffcdcL,0x7f134747420e939cL, + 0x8e880ef05ae283f9L,0x502c5c99f780a249L,0x68a529ab94bf9d68L } }, + /* 50 << 336 */ + { { 0x3cf994ed88c9d290L,0x9209f5610bb34d46L,0x8170b567b2bfa21eL, + 0xae87b6f7c62f86d4L,0xac6fc431d71bccebL,0x5f3a62ba83cf2970L }, + { 0x390262d1d943b10aL,0x8fc9a27f28aec573L,0xe59beb203e3069f9L, + 0xf3e7bd365e0812a7L,0xc29c8a433aceffa4L,0x015feecb41c25e2dL } }, + /* 51 << 336 */ + { { 0x5b6a4d6ca8e61f40L,0x35825d762f9a6e70L,0xd48f6d8d346a8b94L, + 0x12bea60889801a40L,0x5182192ad57115f6L,0xb5a8dc6b954c1b47L }, + { 0x084a5c71793b427eL,0xeb66d699f8de2a03L,0x9835b2fb8eb6d905L, + 0xb4229923c79dfe40L,0xa7c8aedddee34c0aL,0x12a00675337b0658L } }, + /* 52 << 336 */ + { { 0x38ca9f61d44aee32L,0xb2cd0f505484905aL,0x23ecb3a4d812e727L, + 0x9be645b874a3ac5dL,0xaa4a1d114bfa93b9L,0x5be5277d147072caL }, + { 0x623a4bd9ba0a6d93L,0x03419661dcf3d9b1L,0x9bffbe8231de1cf4L, + 0xbadfa2ab56a6af06L,0x9103f7256746f09cL,0x0cd5e956344a2688L } }, + /* 53 << 336 */ + { { 0x50a18ab1f40b0edeL,0xf963b76736e01032L,0xba2029b4d4f9a6deL, + 0x8baec9b85a8446b9L,0x7a4107e766fa8a92L,0x06e78bf99f6543d9L }, + { 0xdaa894b3a5043e86L,0x172858a8f4e6fe37L,0xff0265cc0844608dL, + 0x5db1a8f1d5def174L,0xdf9f8a698874fbedL,0xdd2292a977a274d6L } }, + /* 54 << 336 */ + { { 0x46f522196ad8d03dL,0xb63e0eaadaf8b0d3L,0xd667f0a66e29df38L, + 0x6e77432f96ef3b57L,0x78fe0872139ca180L,0x300a0c78d1e4af21L }, + { 0x650f32462148816aL,0x31ef1e883b4301a2L,0xa2222b25f18442fdL, + 0xb26b63066884291fL,0x977b6f7d713d88daL,0x3e8173248cd5f7f7L } }, + /* 55 << 336 */ + { { 0xd5687c9a9684771aL,0x797808e396cf65d4L,0x793d4eb6ea9ee562L, + 0x2359b991fd94defcL,0x4e75cdf03a8959adL,0x7a08566900ce7815L }, + { 0x5c61df5da699fc46L,0x02b62d4868da56d5L,0x8a6972d1eaea27d5L, + 0x727582b3c8e5d04fL,0x0ab2e6c2de87c408L,0xaa9a62e47b9ed157L } }, + /* 56 << 336 */ + { { 0x9c6247d631af03e4L,0xe5a59ad075f9ee90L,0x1da1d64f6ac4b5a6L, + 0xd2fbd169c521ec7dL,0x6d168015dfaa39f7L,0xe9bcf5b59c69d9d7L }, + { 0x3d1d3e6693ae2925L,0xcda60beae4bc73a3L,0xb2456adc954e2f3bL, + 0x5d312fdc02a8fe08L,0x7b37c00e0e497a0cL,0xbd1f3aafc2f8b148L } }, + /* 57 << 336 */ + { { 0x60f3bb27bc00d150L,0x159c5af42448affbL,0x4492b6bd2cfa563dL, + 0x7e58219683c833b8L,0x9f9ebdb20edfafa2L,0x93a7048f31a39a8aL }, + { 0x4172f74d50149d01L,0xff38fceec58b7588L,0x2e71ba9099f25353L, + 0xdf50fb440604e555L,0x7effa7ca8f3b5969L,0x3bbe8d49b836b8bfL } }, + /* 58 << 336 */ + { { 0xc18c375c29d08d49L,0xb04c0c29c1a681bbL,0x0c4acce9e74dd458L, + 0x1d6da95c85c920a1L,0xc67280d285387462L,0xeba99725e7e804adL }, + { 0x08f80e5a8811a138L,0x26f442138f2136e3L,0xf67f157c2d028cc9L, + 0xb436356d14cd7cbaL,0x1c9c610290281895L,0xf67f16ea48598bdbL } }, + /* 59 << 336 */ + { { 0xbf926a077a326266L,0x4045c18bef43cfc6L,0x6fad4cf56ce45553L, + 0x613ad2dc45a9abc8L,0x7b086ace8836eed8L,0x855857c213ad51d7L }, + { 0xa3b19c2d167664adL,0x422c548abbd2c452L,0x8cd3681f85928ef0L, + 0xe969e45c3ed435ecL,0xf76f2cce746c9aacL,0x514df58d1dd90e35L } }, + /* 60 << 336 */ + { { 0x9b66219c4d09cd36L,0x6c6fa570b54f0853L,0x95c268bcf29a8fffL, + 0xc8cf84bf5420c324L,0x5bfc975ebb61617aL,0x935cfe24e78f1bbaL }, + { 0xa6e2afe919d71ea1L,0x8a321e568c9b950eL,0x42dd9e28ec097826L, + 0xf06e600ef391633aL,0x94e5512b46acbe2eL,0xb0bca2cc61cc7a08L } }, + /* 61 << 336 */ + { { 0xcd361103e8b2d41dL,0x2d0d982cab0b5f13L,0x8158129618d55aecL, + 0xf1c28a71579caa03L,0x5ddedfd7e50b83faL,0x932d2c03222105d0L }, + { 0x48fd0ead75ada3f4L,0x29209d988c533a40L,0xc2acc587f2acf0c8L, + 0x05a8703ef689912fL,0x8f28953b9182995aL,0x1cbba2f20fb3eeeaL } }, + /* 62 << 336 */ + { { 0xa1472574180e5eb2L,0xde27569b93fc7b21L,0x3bb956816b9af8aeL, + 0x8a25fc0ee155f89bL,0x8aff018d825126b2L,0x6eda2f31906f0bdcL }, + { 0x19cbbecc4e8fbe4eL,0x04e0a4a40568d248L,0x6de2c002ff07b863L, + 0x6d388447e8d1595dL,0x6a193b70c2cfd10fL,0x00bd826ee6f6bf96L } }, + /* 63 << 336 */ + { { 0x2a0165a40a5b4d1dL,0x49c85ee904f12309L,0xc2d221031ded788dL, + 0x510ccbb3735bd89fL,0x92d2eaebd8eb0e1dL,0x6bda8e346e428c11L }, + { 0x44c01a1d361f7495L,0xddda8e97cc7a95bdL,0x95cbae30524a53baL, + 0x266d7192dacad45bL,0x8a42793f22fa4b99L,0xbb393cb5ed204904L } }, + /* 64 << 336 */ + { { 0x88e7ac8e168d5e60L,0x53abd5696188a98fL,0x3b96d52918be419aL, + 0x7e75e354c057621cL,0xcb1b709f5ce57e59L,0xe78befa2844f2463L }, + { 0x536081993276d4a0L,0x92636ade157f2024L,0x6dd0d348e0411414L, + 0x5b28e9504d73eeaeL,0x08439232690ed85eL,0xdde1a3496da14b58L } }, + /* 0 << 343 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 343 */ + { { 0x6cbd275739ed9ec9L,0x5db68a68fe5d4aa8L,0x177eaa0be4c58c7bL, + 0x603551ef0e488784L,0xc8eba131df916b0fL,0xd0dbceda159732e2L }, + { 0x55acca84b0834afaL,0xdbe98440b59ffbf5L,0x162a2c703bd3b202L, + 0x4c5e5d256ddd8ebaL,0x66e7844a77b1d93dL,0x1292bc0e110b9dcfL } }, + /* 2 << 343 */ + { { 0x1b66faabf9e89beaL,0xc81c5ddc3a441284L,0x1a82f3a0a675f7c8L, + 0x82884a2f30313a71L,0x7ac5d7b058aea9e6L,0x1954f075cd5ff05dL }, + { 0x7c29638d6178d270L,0x6af7f8ba19381929L,0xe85e3c47a17ae3a7L, + 0x91b107c77009e38aL,0xf3b777d8f1f9c52eL,0x5b7b74ff11b688a0L } }, + /* 3 << 343 */ + { { 0xe1e5b76914b87b2aL,0xee187f5d143a4ae1L,0xa9a38728908cb988L, + 0x2027b2ed4443d8daL,0x1c6b4813c0c98675L,0x509ea7d1323bd978L }, + { 0x43b16a587f4dc19eL,0x385f8be812940ae9L,0xa4ed64e57d59acadL, + 0x47e7abed51ca7f14L,0xead594b82bcce6b8L,0xa2bff60cfc03cf06L } }, + /* 4 << 343 */ + { { 0x4ae3d232c0385874L,0x83bda9e6cbf96d2aL,0xba73c769ec62fd6aL, + 0xd586ba7f62a4720cL,0x6497cd140cc1f491L,0x8b012b707b2ac571L }, + { 0xa65eabb6268fd705L,0x8caf100a1431873dL,0x25b31b84231457d7L, + 0xcab62f75901645c5L,0x2377d74db2f7b656L,0x4008277c2d33c95cL } }, + /* 5 << 343 */ + { { 0xa7be70c04bfeb784L,0x4633ddadc222ab44L,0x00e397d30f5924bdL, + 0x5446db3ae25b7b9eL,0x433ea2c4fa1dd048L,0xbb9ae36a1421321aL }, + { 0xf879069dc59fe8f6L,0xe0f2b8b4820bfee2L,0xcc6cf7c49cf239e4L, + 0x0e3545c207dc3122L,0x23b0f48b1d2c737bL,0x1c6b6d9cfc1137d4L } }, + /* 6 << 343 */ + { { 0x10105dfd101d2433L,0x64e009b58ab6d664L,0x122e68324e80fc07L, + 0x3b26e76287dc7da6L,0x7bc183de6d4728cfL,0xebfecf4f8bcdc129L }, + { 0x8b995cec265c66f5L,0x080572d7c4b0e942L,0x612e9e6b4da5b77dL, + 0x8ec048a96caf9161L,0xe3628ee2c7f45eb6L,0x0190b71bd85650e9L } }, + /* 7 << 343 */ + { { 0xccf79a81017fbd3fL,0xa852ca29c875bc66L,0xbb4cd90c0592f8e2L, + 0x2ee786f455b05c79L,0xe1a2b6baf382e6e7L,0xf2d6cf6e6d2e952eL }, + { 0x2f0b534abc9304fcL,0x1d63fd80795629a3L,0x42e70cd9322d8e03L, + 0x8a282cdfb057e36cL,0xd18a0c313ceb177bL,0x270e31569c58b890L } }, + /* 8 << 343 */ + { { 0xaae2f448ed001c43L,0x08ad1d9bcf4be493L,0x3262b2f482c1f372L, + 0x5521febd351a5f7fL,0xf8ec9190916c75a8L,0xf3c258c72728dfb8L }, + { 0x5dd4ff4f8af19574L,0xefddf5795d076b1cL,0x318b5b98ba8b777aL, + 0xd971d426fb7f8409L,0xed1465e8b0fd31dbL,0x80d24d4300f66347L } }, + /* 9 << 343 */ + { { 0xe8263e8012eb6baaL,0xc452c7581dde8c37L,0x5112af2840baa45dL, + 0x949b8a740793703aL,0x8ba78382e60e007eL,0x38cd110412823c99L }, + { 0xdeb0d555f86cf04bL,0xb2f20bfdfd9f6320L,0xff1d399d17c39502L, + 0x1340aedd1bdf0760L,0x36b2b43c88cc0c09L,0x5f3dba7e9ce285edL } }, + /* 10 << 343 */ + { { 0xcea0374a69ca5051L,0x19e060ad5294ae7aL,0xf6ce02361bb01f47L, + 0x2a5b28ba8c328b8bL,0x6991b1d8b253d630L,0x360afd40859455d8L }, + { 0xf5c6e1427c1f5946L,0x1eab83084cc8c391L,0x4eb4032f67e76ecdL, + 0x5bf14aa233898059L,0x0804a7c00e001b76L,0xe3866a93734cd134L } }, + /* 11 << 343 */ + { { 0xbe85177db72e5eadL,0x47c15fad59fd2463L,0x2cf5f07f4bd51f8eL, + 0x82f48288c2898713L,0xdb08aab4c8f753e8L,0x18a1f5c510f58eddL }, + { 0xaeb7bde366d0b94cL,0x04539620079fb6dfL,0x64d1aff2ebe8c4b9L, + 0x08d9ef431a10a101L,0xe326c7ec6c602789L,0xd8b1b3e7f6efc3d1L } }, + /* 12 << 343 */ + { { 0x5ba5288c1ae586a2L,0x044f1fc61b715821L,0xc1a9a997602f3c65L, + 0xc5c7512fe08c0223L,0x48a19c3c367e6f1dL,0xa9f2195dfb241597L }, + { 0x9f674a5fb5ba32a6L,0x275a060f0a312742L,0x5aeb8c4303d6f13eL, + 0x0fed575d917433fbL,0xe4a5ef9a59f53490L,0xa9f86145f315e616L } }, + /* 13 << 343 */ + { { 0x770d01ab2c1deef8L,0xca72f761f61b2a4eL,0xff686a4ceff9ee49L, + 0xd6b338d30d07000aL,0x885b4e8ce1050b10L,0xd6326179b2364b01L }, + { 0xceb2bafc672b298aL,0x7df8941aba628946L,0x9c94004ebc56b115L, + 0xde09cc2d7b12cdd2L,0x9c2dda163833ce43L,0x88da691a6265b59eL } }, + /* 14 << 343 */ + { { 0x7059c58669a03980L,0x91f2dfe4e88e1287L,0x96dcd9318d9633ccL, + 0xb2abc44f37bda148L,0xe31adb3feb8964dcL,0x7b07e015e316876cL }, + { 0x31732880ababd240L,0x5c37a667e95854a1L,0xb5b334c91d6f69adL, + 0xe613e5622c34e118L,0x8bbdbf5c5f5984edL,0x82ecfd95cf4f63a1L } }, + /* 15 << 343 */ + { { 0x813caa72ade4e3bfL,0x29055be8600c93c4L,0xcb346967e6e4ec1bL, + 0x39c1152d50ce992fL,0x4682c20e5ce62852L,0x04e9dcb7f4e45ed4L }, + { 0xda75355d7c0fa5bdL,0xe80f29b078949d91L,0x6214610130fb9e33L, + 0xe70cda8f325eececL,0x49217f74efca3e14L,0xd3c890b36bd7246aL } }, + /* 16 << 343 */ + { { 0x315ad7a47e5a59f4L,0x1c615bfc543c8b00L,0xe12f97a8baa56473L, + 0xf263db4446edcfcbL,0x47cf91d53c1a968eL,0x1a1165b4c15db875L }, + { 0x5d35e53a3479616aL,0x649f87b45c59958fL,0x5d3d11ea246da3d3L, + 0xc1ddfcc653f06820L,0x8169d7116610c00fL,0x15f16ba54bddc8c7L } }, + /* 17 << 343 */ + { { 0x307b040d9977713eL,0xc03f7787dee9e016L,0x761a5d03e12c354fL, + 0x8fa1a4141cc88904L,0x2e079008b7675e71L,0x649c789591d68d60L }, + { 0x63467e93c98f1c9eL,0x81931ac7fcc52703L,0x2060c89538e59af3L, + 0x8c12e002a87024c4L,0xfc881e69b3b8496aL,0x2b4e482e1e827081L } }, + /* 18 << 343 */ + { { 0xf80ed61a30fa7e86L,0xf2e5f324a15ec5d9L,0x139ca085ecba2d64L, + 0xd164ee5ff3f5cfd1L,0x758c0008e5cc3cc5L,0xd180c463ce8fa1f9L }, + { 0xe5dd27054adc6e61L,0x061e0c3c592c39e5L,0xec5a8d4a4e437781L, + 0x9e4c6f461e6d4540L,0x33ab232e2526e6eeL,0x3c551685ea282d9cL } }, + /* 19 << 343 */ + { { 0x59507a2162ce1459L,0x88b465d1c6a2cb30L,0xa5ef8b2b5c8ef7d4L, + 0x73145f4c4dc9a457L,0xabad3390d19186f2L,0x7036b424f9b78a7aL }, + { 0xf76f51bb16e04046L,0xecd1ece92b2b71efL,0xda8d82011900f2b9L, + 0xc2d3291b268d1bfbL,0xa6c1c79a2d176459L,0xb27e5d5885ee1b7bL } }, + /* 20 << 343 */ + { { 0xcf19fb2a1e548ef0L,0x8bb6dfa0cc694171L,0xeb1668ca5c5e390fL, + 0xf5a3485be1975263L,0x4edfc596442cc850L,0x9901f447f9627d74L }, + { 0x3a6b85c984d0413aL,0x1466366167de639cL,0x9fc9fdcf11705bbbL, + 0x6d066e2bbff2cf80L,0x38dedc2fdc3026fdL,0xad533a981b828538L } }, + /* 21 << 343 */ + { { 0xa7d51d862222dcb3L,0x52e2531cd1a6c525L,0x742b1234532126d8L, + 0x226043f24e9e77acL,0x02f270afb3a75b2bL,0x7ede5714d4a8dc0aL }, + { 0x24699e16b34fd97dL,0x4e5d785e8d417ad1L,0x273f5dd1ec307ecdL, + 0x742373863186955aL,0xf46805fde6afd38dL,0xae100ba424562906L } }, + /* 22 << 343 */ + { { 0xed9f434e5216636cL,0x242bd09bc5c1668fL,0x8bb747bd804f3d6eL, + 0xd66d8753c7c83dd2L,0xa71016c2584540b8L,0xd8b16210fdd41a90L }, + { 0x5eb5947e1b65be60L,0x1bf995e7616dbdc2L,0x71b7099abb7dbdd8L, + 0x53650d29079eec24L,0x6bdd1b0e8ebd86c8L,0x0a9658ed9a31624aL } }, + /* 23 << 343 */ + { { 0x3be2ce89b8cf4d55L,0xf9b3c501822cdcd9L,0x0cc8423010e12f3aL, + 0xee09031a3c580ec7L,0xf4c256a812f4b48bL,0x71a8323104018d0cL }, + { 0x69ad6d7babfcf13fL,0xfa79b457af658743L,0x249f32816001af58L, + 0x158430fcea127a64L,0x25a3e4549a9be713L,0x68ba3f0fcc6b5bb5L } }, + /* 24 << 343 */ + { { 0x6c75bc93b7bfa29eL,0xf86f22b218ef6d69L,0x90ce6a1536dcadf2L, + 0xf11f711c7ce50921L,0x0739ceda38a479e3L,0x840b825e6ec3dbc6L }, + { 0x7c36c0a59fa23481L,0xceb61fd170cb186dL,0xac6f7d3c26e4754dL, + 0x4076d3b5f317b385L,0x52f1bd723fd9e9c7L,0x6649d8b6bf316043L } }, + /* 25 << 343 */ + { { 0x5f03dcdcceb1e25cL,0xafff6561d50ff864L,0x17208b6f3a6bb787L, + 0x61d96c978e15abf2L,0xb1beb427991107b1L,0x436328475008aa3fL }, + { 0x8a326eeb3595febdL,0xa8e5a037ec60dc0dL,0x762ebd2a3159f062L, + 0x8ea005adbd1b0bd5L,0xd4d863cf696d4121L,0x2a07a637eacc9b9eL } }, + /* 26 << 343 */ + { { 0xf352e28b54a8ffaaL,0xa8317f089ce68b6eL,0x7deb148770cad820L, + 0x2411b382b2c3579dL,0x20b21ed214d36e66L,0xe7331bec353b9ff5L }, + { 0x5692636840dff0b3L,0x13356f7b646eff07L,0x1e6e6e4508c64091L, + 0x913b83f2ea0b920eL,0xb69e5f839f713aa1L,0x8e59d3794632a60dL } }, + /* 27 << 343 */ + { { 0x3594c0d3cdefc3dfL,0x9d850e2fd21cf9e7L,0x245322944e38263bL, + 0x597964610e43acb7L,0x13fad563bca9408aL,0xe52983dba985390cL }, + { 0x9c5e71e08c000a9dL,0xde6b0b2f800949e2L,0xc58032d131d94108L, + 0x36cd4099b31811e6L,0xa8d9bdeb3981d619L,0x06f644e03d4760c2L } }, + /* 28 << 343 */ + { { 0xdc2870f8243cfbd5L,0x000b71b31ab496f3L,0x53511a3f708f4507L, + 0xbd7bd0381949d835L,0x723a007d938f4db6L,0x5bc8679e2d04e9fdL }, + { 0x51ca5fd176ec7fc4L,0x86c4205c988f354eL,0x9042e76b2a0a4a90L, + 0x368f52a84ad44d2dL,0xddc2cab8912edfb7L,0xde74ccf5cde80199L } }, + /* 29 << 343 */ + { { 0x91b31fcbcaa3f1d2L,0xb8a29af1bcc99f53L,0xc5842b2695662f80L, + 0x13954262a4b4b396L,0xc1fac956a6acfdffL,0xbe37fa4dcf60b88bL }, + { 0xc7715493dffff3deL,0x06dfaceda1274350L,0x9dfcaffd7460fa94L, + 0x5f1d3a351e9c317dL,0x2fbf393d377b84ceL,0xb4d9bc8404b83635L } }, + /* 30 << 343 */ + { { 0x29871ce22855a74eL,0x5418f0dc98696474L,0xd8bc07d6b90d0498L, + 0x391012a79fdc0ea2L,0x271396949b09f60aL,0xa0a43dbf3371f0d7L }, + { 0xab5849422af8d992L,0x64cbd121409eb3faL,0xd36faf01766864fcL, + 0x69189faea2a83417L,0x3c24d85e3733b772L,0x125a915d2ee497adL } }, + /* 31 << 343 */ + { { 0xa8f9eb2abab3fa8cL,0x484584f654ab1e16L,0xee74e5aab21b34edL, + 0x3ce626ff4eb689f0L,0xd757f22b0006e5bcL,0x611505d024a25e65L }, + { 0x212df14c46382659L,0xd17898d78c73da0aL,0x5604a93e51421c2cL, + 0x76147f7603a580a1L,0x325b5c8ae5c34d09L,0x6ff28848db857152L } }, + /* 32 << 343 */ + { { 0x8002f4583e455a61L,0xafbafd375bea205aL,0xa8ced112fb93f735L, + 0x27cb6292196e3084L,0x72395bdd77e8c744L,0x02e018d8ee71f5ffL }, + { 0x7cfc14d9c1337a1dL,0x94e14c0ad7b4d86eL,0x66e50129d213738eL, + 0x7a905d91bc0b5ea3L,0x92cb630afca06700L,0x65e06d5cbf3a0821L } }, + /* 33 << 343 */ + { { 0x769ff9191e1cde66L,0x6ef257d1944a8786L,0x881437da4f75233eL, + 0x15266f3768665eafL,0x21fcccafc1777505L,0xe9513e1ab7fea0ddL }, + { 0x67806e9c53c8a735L,0x24be9a769b11ae2eL,0x928c1455045d2065L, + 0xea0395b53557f62eL,0x910d7cb4c7d3a450L,0xe849c853c634443dL } }, + /* 34 << 343 */ + { { 0x76c6e48d3b476f69L,0x28195cdffe694ee4L,0xa3a9a99e2d3aacc9L, + 0x0f68fe36b7f320d8L,0xca84a6c9889ce762L,0xc1eafac94901907dL }, + { 0xa28b9916208c9770L,0x6846e639f8403e57L,0x12fdf9fa1d179e3eL, + 0xb81e47c843d046dbL,0x700ad19468c14491L,0x136395cebbac51d7L } }, + /* 35 << 343 */ + { { 0x7452dfd4f775003bL,0xb38a2031f1a4765dL,0xef36c513a2888c68L, + 0x2039b168a2339fd3L,0xf74c24be2cc498e9L,0xbeeaca157b622e31L }, + { 0xda72e5a005f2fb8fL,0xab4a98f0568d5811L,0x231aa495fcb15e1eL, + 0xf981bd7f537023f1L,0x29d6eb2db367e5fbL,0x15247194b8cd452dL } }, + /* 36 << 343 */ + { { 0xa81e4a4e55c2369dL,0x394de01b60a0f544L,0x22acfd07a8906e17L, + 0xf59b37a6cc9bc4d0L,0xdd16a22c7ffec12fL,0x07decc2ad5976455L }, + { 0xc5019463abe1d122L,0x2bf0ac0ce318c92cL,0xfa50280ab2bfc47bL, + 0x53354fc5c7cf8bffL,0xaea1d293e20ca341L,0xec25ecda8b626244L } }, + /* 37 << 343 */ + { { 0x05c6f1c99a2f572bL,0xf13f8c7747987918L,0xccb406d74101fdffL, + 0x93cea27bee1abcf4L,0x32703ada8f5adca8L,0xceaecb5f76313a1eL }, + { 0xf1c558980b9620cfL,0x942c28b51046c388L,0xbed4e9dc5a07cf8cL, + 0x423b695a6c734b85L,0x1ce0a2392ac87737L,0x40f126ac4d1cc7d8L } }, + /* 38 << 343 */ + { { 0x63e3bb09ad9e132dL,0xaa2880c5c9e84778L,0x23de89ea06049834L, + 0x442d1df3554e23bbL,0x87214f9f08c5f124L,0x305d967a6beb4996L }, + { 0x01676f804409f827L,0x16992f73a50147f9L,0x77ee56796081b38aL, + 0x8c75d293290afd9bL,0xf9578bca813f0aceL,0x395212dd0e786ed6L } }, + /* 39 << 343 */ + { { 0x63475e65c21b0f48L,0x114f9af5326c2c63L,0xa897bc01310f768aL, + 0xcaf47a8fc1bf3f5aL,0xc023bb3718cb887aL,0x3572f633685652a2L }, + { 0x2dc4ea0d7523287cL,0xafd60b92a121a141L,0xb6b4bf6e085ca490L, + 0xf599f8f2e5351ecbL,0xe38c8eacddba3d60L,0x2540585f5be9e748L } }, + /* 40 << 343 */ + { { 0x313b66cafd8ba33eL,0x10bdb130fabe27ddL,0x1181334c125e2b8cL, + 0x0f4f198fdb6f94baL,0xf7000076ac3f5de9L,0x1a78813d9d6402aeL }, + { 0x3427f75dc8a9e758L,0xcdac8b34b01f791fL,0x922c36d12a9ebaf5L, + 0x195ea05fb0487cc4L,0xe33de901a808baecL,0x15e1d5ac57291d89L } }, + /* 41 << 343 */ + { { 0xfe52cd9cfdc7e2deL,0x3947e578da6dccf1L,0x0548d4b5738751e7L, + 0xc73fc23f4b52a5ffL,0xf38eb8ff1b066accL,0xe9a40d37a27b40f5L }, + { 0x723b0752a264ad77L,0xe5d0c4efdea83bf8L,0xf7301e3fafad27a0L, + 0x336b0d86298d09b3L,0x462766bdb2ef2fb7L,0xa5311241141a7607L } }, + /* 42 << 343 */ + { { 0x10adb987ee1f44a1L,0xd6ebd1c3e51c0152L,0x0cf1303f4dd3b9eaL, + 0xd06351b837a33a3aL,0xb5ce1d941cff1f0fL,0x326b3e055476e2bcL }, + { 0x90f76b5d3426b8ddL,0x77497380648042f1L,0x48684604f9f83902L, + 0x00275191180f197aL,0x36fd84ecde7ce932L,0x52b428e65391a268L } }, + /* 43 << 343 */ + { { 0xd2c1ccb0695c2851L,0xd722b84ff1c78f17L,0xaaa53d26fe52f2a4L, + 0x3057f4ed24742143L,0x951332a4a2aea258L,0xe5e4db6091096878L }, + { 0x71db9e48f0b9ef38L,0x7e4b25c1ac542c26L,0xb7250394dd021df5L, + 0xcdcc6118ee48e711L,0xbc324af1fcdd5db9L,0x71a664ef3e6de57fL } }, + /* 44 << 343 */ + { { 0x4e2a05c1c21cdd1fL,0x8a232097dd46e76aL,0x8b55313cd871b1d6L, + 0x976ce5f6af396bc4L,0xeb91527dafd381b1L,0x6cfd449014455ee2L }, + { 0x8723be9e1f274d1eL,0x1c63fd011999fa9fL,0x5f1726258049b6f8L, + 0xe18a3ecd99a51b4dL,0x329fc2c1b13d4e65L,0x94da252b0f18f300L } }, + /* 45 << 343 */ + { { 0x583adeb8b893316aL,0x69dce1efee5122deL,0xc5cacdf319b77627L, + 0x061fedee5e8aedd8L,0xd53fce220257dce1L,0x0e4124bdc781e069L }, + { 0xf097c697d44ed517L,0x7704e33e9a4e9019L,0xac245dc23e0088dfL, + 0x70e1176bb76102a3L,0x55261ab235e4dcaeL,0xc2ba59230ede3501L } }, + /* 46 << 343 */ + { { 0x6edf35f3af073b6dL,0x7ab4118107376eb0L,0x4ef3e65be7ff1c9aL, + 0x654ea359d2ac6d70L,0x2b41a7f67ffcd91fL,0xe5da0511e0a60e8cL }, + { 0x97fefd9756701b93L,0x7a4a827dd34afe15L,0x8bd6c2299090536cL, + 0x110156f217e510a0L,0xce62a26ec801ca6aL,0xa786e9b05522b64aL } }, + /* 47 << 343 */ + { { 0x3c73c2868f02f70bL,0x744a580d0eeca325L,0x58b7ca1733534669L, + 0xd7d17d77800b0270L,0x864e3509538b116aL,0xc7eda5dce4797818L }, + { 0xd6c00fbaf741f023L,0x718ed11131d022bcL,0x4586baf2f2ce39efL, + 0x1095729dcd9a09f8L,0xf5ff3f2d7652f5ddL,0x29d95a09dbb72722L } }, + /* 48 << 343 */ + { { 0x7b151b98e28fd10dL,0x8fc01ce81dd884cfL,0x1f0ffb5098d56c2cL, + 0xf9df1fa2b084606dL,0xf86232bfdc7d2008L,0xeae5cb8fd8751699L }, + { 0x70f0229883ed54fdL,0xb575283a86087697L,0xad2191350302e2c3L, + 0x1c09a0d6c4b57e01L,0x0f65e1e1c541b9fbL,0x85493d9bf4fe76c0L } }, + /* 49 << 343 */ + { { 0xecf595d6bc19db89L,0x32cdf31bd607e09bL,0xfaf93c636217e9faL, + 0xa9a1619884d37c72L,0xa2688a33bd929e8eL,0x2ce3442e2842b31bL }, + { 0x906ac09ab37184daL,0x93a1a54492587ea0L,0x1acfab1ec5b4ce7eL, + 0xd4788cac7131e80bL,0xb463d67bc8cf0e18L,0xa754ffb81f24067fL } }, + /* 50 << 343 */ + { { 0x634f8d6db04ea518L,0xe8c424b4c60108a7L,0x3553b6d11ef6f4bdL, + 0x1fe850dfbc0a8e1cL,0xa077055473a66e4aL,0x5417bd50da985b55L }, + { 0x3f99edcaed53259aL,0xd243f2d1b3d5ae6cL,0x70f404b8cb49e74eL, + 0xf6893edc51fec8f0L,0x3f3ac23871521335L,0x127c055436e39048L } }, + /* 51 << 343 */ + { { 0x459a96595ab6a5b5L,0x14ec172bb5ac2238L,0xe556f7061642ba57L, + 0xe18d92d2da35bad6L,0xe64f9bcdd5805c1fL,0xabb4e0243b297094L }, + { 0x95429e14b8b876f3L,0x27961a7d9c04bad0L,0x81c74cf57fa32b6aL, + 0xb035259ebb0f1f24L,0x828c42da2e773f8bL,0x06c996366ea73c24L } }, + /* 52 << 343 */ + { { 0x353718ce191c21ccL,0x08e6edf64ad6bd18L,0xc2bb0d6e4dc5b572L, + 0x328e19df88193daaL,0xccc9f6ab7211c958L,0x377d99ef58aae5c5L }, + { 0x40e2ecc91c823442L,0x036d6d528b0d36abL,0x2fe0cd7eda4d0ad3L, + 0xb8fc3c7ffc8af791L,0xdb7e44a42b201b20L,0xa5176004ebcf527dL } }, + /* 53 << 343 */ + { { 0x24d19ca6fed20bb6L,0x0c02db9841d634aeL,0xfb55998930310b8fL, + 0xf9d0818506c00c8bL,0x2b9983fb4742362cL,0x16ae9bfbdce1b6f3L }, + { 0x679057e6a161a419L,0xe1e80fe04db28bbaL,0x2ca0c869f06c9a98L, + 0x7b80c43bc448ffa4L,0x100f205cb7ef73f7L,0x29565a93a938bea7L } }, + /* 54 << 343 */ + { { 0x4d00c613e1e7a831L,0xc90021dc56d9ddf2L,0xbb80b8385286ccccL, + 0x156b05b771f5f09dL,0x120f47f47bc921f7L,0x6ea1715f8a65c50aL }, + { 0xa070c9f695aa8348L,0x96120fe273171f56L,0x10c7d592ebc69e4eL, + 0x73f6ba27c1c7ef52L,0x10f5b9cef8bb536dL,0x8bc82b225ce0220eL } }, + /* 55 << 343 */ + { { 0xac25749af4f3fa3bL,0x2376bcd76f50e4a0L,0x9c68fd1028b2332dL, + 0x130ed4d12130b66bL,0x91842d58038dfc9fL,0x4111e4cbc401a53dL }, + { 0x85532deafb5d9b16L,0x0c5657503025e3b1L,0x1340aa49b6cc0c31L, + 0x1cfdd7d68b7f71a0L,0xee911d7e8b6e548fL,0xcddf07f021456ebdL } }, + /* 56 << 343 */ + { { 0xe19b7576fa5256d2L,0x418d5425db3f8bfdL,0x00424869951a1719L, + 0x2383c7a8533b69b0L,0x166a38e2e67a86fdL,0xa6baa01c5876c435L }, + { 0x574ddc4584a208f5L,0x8cee30b826b18dbbL,0xeced99c1e9f6b30dL, + 0xb638d88da7d34beaL,0xa4836806069adedfL,0x62beb7ee7a07c593L } }, + /* 57 << 343 */ + { { 0xffc89d6de16d63b2L,0x4da3b04f5df40d2fL,0x3437da2ab48706d8L, + 0xc35290a1d677df03L,0xe54fc6567c5b6c8aL,0x84f052ff2c77314eL }, + { 0x59c33a99d968b4eeL,0x2424c5d0facce444L,0x022d7bfbf505307dL, + 0x5372518d00c142ffL,0xcc82d21aeefa787aL,0x3517f3c0473ef630L } }, + /* 58 << 343 */ + { { 0xaf576c307a8a437cL,0x15852131de3f2cc9L,0x96bbff4371759da5L, + 0x106934ec66f5257dL,0x712e7d0ba9cedae6L,0x5b0b876ddabf131bL }, + { 0x1605f3a8b741f94fL,0xe5d961c109305b04L,0x3fb97996346266c6L, + 0xaf4eafc0b3ec7458L,0x0aefa01abcd90b0cL,0x2b7723e3505ea305L } }, + /* 59 << 343 */ + { { 0xe5c6f37b43d12de3L,0xdc34fdad642baf26L,0x89d716d647268e1bL, + 0x50047b391df8d657L,0x40da6352c64470a7L,0x406e3bc97879824eL }, + { 0x9677b4c38b9ecc36L,0xc82bf16fd246788cL,0xbc9fa99cef5dda3dL, + 0x3050febf0e7b676aL,0xfbb1301a53e448afL,0x3239f20267c84d67L } }, + /* 60 << 343 */ + { { 0x5093950b724fb94dL,0x107822718117ff50L,0xdc9e34b59f5961d7L, + 0xfaa2fc012351a33eL,0xb9e0f1d9d5fc462eL,0x276a5b3bdd9c6914L }, + { 0xe6136d1775365ca5L,0x228b77e2a91eed68L,0x5cd6a269411e4770L, + 0xd8857b0e17590390L,0xe7094f3aa0d45fafL,0xe52d11dcf40693e4L } }, + /* 61 << 343 */ + { { 0xc873fdf565a0d2bbL,0x848244dbaa42c6cbL,0xa5d2d766ac50ba78L, + 0xc650cf4343f38ad7L,0x901cf122ea895d06L,0x3ec1b583cbf46321L }, + { 0x863dce6193c3db94L,0x902459202445bb4fL,0xae716052673385dbL, + 0x9266b0bfff830253L,0xd201095844375610L,0x9e008b9712cf8d71L } }, + /* 62 << 343 */ + { { 0x2b1b2a551448e73bL,0xa8486146b5f97da2L,0xcf24d8636c848202L, + 0xa3d6431c5e483407L,0x47a33db852edb78bL,0xb09256a37dad3826L }, + { 0x740222a74dfa2b26L,0x23f43bec2a8ebe04L,0x4081e512a8072f18L, + 0xe53f0d05751ad7e8L,0x100d0a17332361ecL,0x8a2122e9e0c3a152L } }, + /* 63 << 343 */ + { { 0x28be8affe7e6417aL,0x4e18b452d6a30763L,0x73ae410310d0d5f2L, + 0x5151fe80003625caL,0x45ebb636ba7a91ccL,0x50f4b49d994e7e31L }, + { 0x02eaeaa93ebac455L,0x7632c7dac830fb1cL,0x06fe1dde3bb0d765L, + 0x0d2f7623a6789d20L,0xabba46de01a43e9dL,0x2e822e08f27917f9L } }, + /* 64 << 343 */ + { { 0xe96c4aebe5f5b545L,0x10a85a002d4c43b0L,0xf86ad2f632f9151dL, + 0x05daf874302b99e2L,0x4299dbfa14fd3171L,0x27cbedd6812cfc62L }, + { 0x42e61536b8772164L,0x52eecef76a5423efL,0xc34c6c70548fffa3L, + 0x1fbed7777b6db825L,0x850bded44ef2989eL,0x3b8a542c815463eeL } }, + /* 0 << 350 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 350 */ + { { 0x9decf2173079fe2fL,0xc32ec5707c817f6dL,0xd5649ce8aeb36b92L, + 0xab9f77d158fb4dc8L,0x66b11fb6b52d60cfL,0xe217941deaaa4619L }, + { 0xf3522a9a1607c412L,0xea2eba4fc2a3d8c9L,0x267997c625e38722L, + 0xed5047b72d4595eeL,0xaaa41e5f55e5456cL,0x891e3d1278cfc6feL } }, + /* 2 << 350 */ + { { 0xa438634ed7357a51L,0x918f14cd18c04d59L,0x2ab4dedfac40dd56L, + 0x758e95ee4956a5deL,0xfc11e3945113f84dL,0x6d71b6736059f16cL }, + { 0xfd8e2236fb357c3fL,0xd7c8681232dca873L,0x02aeb1538ea13b44L, + 0xde1275d3013d3827L,0x470a7b7e659ca201L,0x862c83c55c77b351L } }, + /* 3 << 350 */ + { { 0xfc9b800f05084cfbL,0x1c4d4510496f23fcL,0xfea0003cc1d08465L, + 0xf0281da09af48a41L,0xa5c0d97144d32eedL,0x2613b73e023a2e31L }, + { 0x455013c87dc8ac1aL,0x581b13195958b3daL,0xd293f2f22290aaeaL, + 0xa068256496f6223bL,0x38fd18fa69410ef6L,0x74eaf35f2b2cf629L } }, + /* 4 << 350 */ + { { 0x281f6e58c7ff5b50L,0xbc67791ecf9cd114L,0xe29fa41afd89abd8L, + 0xfcb0b0b07984feefL,0x0b0928a6d9d20a64L,0x2fd385c46979ccd5L }, + { 0xce9c34c81fbe72e4L,0x69364344aad0135fL,0xd464635250946a5bL, + 0xb09a97c6f39f53b9L,0x1d47bc20dcbc8b64L,0xcda5c7bdd458b0d6L } }, + /* 5 << 350 */ + { { 0xad5b8c2887eff3b3L,0xa8a3917d9937833aL,0xbafdc493200c3b49L, + 0x9e27aac5972c6fbfL,0xfd292bb20518c97dL,0xa62126db33515a63L }, + { 0x9892a8bb1bcfc875L,0x93b066b7e0b674d1L,0xcde9b0087fd3d080L, + 0x1e285a8859401ae8L,0x4679e32982cfea96L,0x52406ea023e615d3L } }, + /* 6 << 350 */ + { { 0x27de61138b6e9462L,0xb8ade1dc473464bfL,0x911ad49394dacc08L, + 0xd036f28e44252cb1L,0x3865abf6d13dc20dL,0xcea487cdd528f0baL }, + { 0x14d77eaf4fc290feL,0x5106533bc5084101L,0x11001dc7cda9eccdL, + 0xb79ad4bc49fc4a78L,0x4f6369f54567f8a9L,0x64050aa2df7ab817L } }, + /* 7 << 350 */ + { { 0xffe057aade07f615L,0xf3f91b55342700bdL,0x294761e127a839f9L, + 0x6411a2b480eafe1cL,0x4900eb120737b80aL,0xa1134d10bb73264cL }, + { 0x0ebfad730ddbf7f1L,0x57bbe692cd1f73ecL,0x675931fca20f8944L, + 0x1950eefffad2ad19L,0x60d304029cdf88a0L,0x121af89e33fd2c6eL } }, + /* 8 << 350 */ + { { 0x763e3664295c4db2L,0x632fd676dbbaa92dL,0x62ab11a8c66b40e9L, + 0x06244698f384b708L,0xe7cdf3bd69197876L,0x9cc79c48064f8837L }, + { 0x95900a229486589eL,0x7953f6e72ff01639L,0x3f65fbbddd3e6e46L, + 0x84f52e06baa2e2a0L,0x1dc462a8e3852824L,0x9be69c3f7e4c032cL } }, + /* 9 << 350 */ + { { 0xa40afc3670977e01L,0x965f110da6c3b289L,0xc4952f87805a8491L, + 0xb36804b80b65e2d3L,0xd3f6f5ace8cf2b2bL,0x0f37a79da4b71938L }, + { 0xb2f810d9489ef671L,0x1feae0262df23cd8L,0x7412eee321a14e4fL, + 0x1458b8ad179d51faL,0x2156a90ee201509cL,0x39f29fca72605867L } }, + /* 10 << 350 */ + { { 0x231f70adb2e066e3L,0xf09db880bb477a19L,0xdfa0e503907e5c63L, + 0x12fe09f4f97022adL,0xdbf06f3620bce7ddL,0x0140e197f1371cbaL }, + { 0x917b6da464b0b4b0L,0x9a6f4d9b20fe3320L,0x0981d60ed66bdf87L, + 0xb430e4e062d3487cL,0xc3440fb934dc4a94L,0xe7972dda09a5e3c9L } }, + /* 11 << 350 */ + { { 0x29d6394093f47052L,0xadf04e70847e5937L,0xa0ef4fee731bab6fL, + 0x21de31956ee7d7bdL,0x99af4a8dbd716777L,0x9e15c983df4c569eL }, + { 0x2ec7bc0ce94401eaL,0xda1835ad85727722L,0x2b5862ce5dad81daL, + 0xb2be508188dddc2eL,0xa02482101414286bL,0xc52c436d8ea33f3fL } }, + /* 12 << 350 */ + { { 0xcc580ea73b24e776L,0x0f3a8b189d721d6eL,0x8665604fb23480cfL, + 0x95787cba34414689L,0x425d7c6f4d10a945L,0xb5ec2626b2f1cc78L }, + { 0x55da88858658de6bL,0xb50919d1e9aba03eL,0xc64881d7d99e417eL, + 0x1eeba5aabf28fba2L,0x20feb7b3504eff80L,0x9f5f9db650debfb7L } }, + /* 13 << 350 */ + { { 0x4eb94584230923dbL,0xba8611287b3a6929L,0x5aa7faa3ab1d6b31L, + 0x95c1e23916ae0966L,0x98674fd3a2fe2297L,0xa8da0ee53c42d488L }, + { 0x103cabace0740db0L,0xf0b860d45bf16882L,0x03cb0cdc289e48ceL, + 0x3c15d3759e52c7d5L,0x524f731998103ca2L,0x828ed65cc609ffebL } }, + /* 14 << 350 */ + { { 0x518f231b83dfb993L,0x4b0987db37c0826cL,0x0c34961cd5177eadL, + 0x9d882d3e452c92daL,0xbfeaf5588765bcedL,0x83957b62b9962295L }, + { 0x2d1d01757bb084cfL,0x04c4cfcde8cffcfcL,0x2f35e33d8d4536c1L, + 0xbebb31cbd83124cfL,0xe342bed2abb29019L,0x2af0fcde2692a0d3L } }, + /* 15 << 350 */ + { { 0xece5d865c7e3b29fL,0xe58106a4622839ddL,0xf5272d43f2969d76L, + 0x90c72c1b2a1a240fL,0x1e2aa0acaf15e14fL,0xfa2f1c7bf1b6b5a0L }, + { 0xfb5d343d880224a5L,0x47b88a84f91881c5L,0x140f5ee9dd142fe7L, + 0x4e76982e24b37c44L,0x6aaf61e9578b482bL,0x01950e22765bc4e2L } }, + /* 16 << 350 */ + { { 0x20ebf79ce8a2e8f0L,0xec040d0daca418a2L,0x016c07e78d630d2aL, + 0x20021d57fa605dcbL,0x6190f3e942d04705L,0x4e000df58974b7e6L }, + { 0x6710da6c5abcedacL,0xf31aa4965f95d37cL,0x192c4b8ba5830899L, + 0x171ab8c4ea7dbcddL,0x715f60818cdf1097L,0x0e0135bf205d10edL } }, + /* 17 << 350 */ + { { 0x070fbbe1687645c4L,0x4dd859c8c7e0261eL,0x749fa1e9fad54b60L, + 0xb35942f483cdc91fL,0xcef26d0018eeb83cL,0x4dddd5787462064fL }, + { 0x0420ed6e703e8740L,0x9087d805c180c7d3L,0x93807412828424f2L, + 0x8bcea69a6dcae236L,0x22aed9a2d1973c78L,0xe3d0f6f83328d690L } }, + /* 18 << 350 */ + { { 0x5ce5bc6da85a13acL,0x868f385c7f1dd71bL,0x15aa63a420c376c6L, + 0x7802fc9e749127dcL,0xfad59f8e67a98935L,0x6bc97b1d60c0fdf3L }, + { 0xd24caa7ebce87ee6L,0x8aa08bc27ba511f8L,0xe5ba94f47ba61c1cL, + 0x9fe9c343364d2d75L,0x8ee0468161273932L,0xab2f0dbe5e8c4861L } }, + /* 19 << 350 */ + { { 0x13239c0a8254ded6L,0x594182e61762f9cdL,0x6326369d480efa21L, + 0x7fee5afd33101382L,0x9e1ea59c4688bc0bL,0x7a3b1b8eae19c17aL }, + { 0xa8f8f8e5777aedf3L,0xe2d018bfc6bbdeacL,0x3625b03b54328db4L, + 0xda7540c8711ab8caL,0x7faa19fc46930a99L,0x61a5d1845b59a973L } }, + /* 20 << 350 */ + { { 0x4a6226f9f7092423L,0xfe6b7a6dec945231L,0xb44e2e60a1193cabL, + 0x2ce6393543dda270L,0x1a9e8a2138d64738L,0x863d151a9d843675L }, + { 0x98a1222ee2b14443L,0xbf8b32712826846fL,0x80475be555508801L, + 0xc39ccd917b38f064L,0xea31304de8e249f5L,0xa3b6891b4d42db74L } }, + /* 21 << 350 */ + { { 0xc0f1627a147e0f32L,0x59fb7f2f5e8822d8L,0x21d8be6371097441L, + 0xa6169f1b855543f5L,0x188c420645102ae3L,0x4c20a136131b674fL }, + { 0x05487c4d15999699L,0x8a82a130e6ba5542L,0x93a2119519ec0de9L, + 0x634d644cc8d0538aL,0xa90c5eeb3b6bbd60L,0xd59105125e4db926L } }, + /* 22 << 350 */ + { { 0x5140a7172119e821L,0xe5a2ca8cbc370a14L,0x0c17ad48a6db3398L, + 0xd7094545ed6fc82aL,0xcf32984dedb976d1L,0xcf04ac16cdf83a9bL }, + { 0x9bbea16b49775502L,0xb4855286452a6f35L,0x45cbc3b7a86f445dL, + 0x5972ec64763f5990L,0x14d0b9c0b780b2f0L,0xb120273456e707feL } }, + /* 23 << 350 */ + { { 0xbf6b76e1e41c43c6L,0x64ea1824db033acdL,0x7fc0399987c9406cL, + 0x9427585a51b371d3L,0x464f3559c9705e0aL,0x6639797ac8cb6ff6L }, + { 0x5104a72e842fbf01L,0x7cabb009fea7af74L,0xe42aa69b19a1db1cL, + 0xca9599a3a6a7ab69L,0xf31e4aaa1a70d770L,0x0fcc7f1b8a5ef098L } }, + /* 24 << 350 */ + { { 0x39a689bc281548baL,0x11aacfca138eabbeL,0xcf33108a8d29457bL, + 0x312612e014ed4b4dL,0xcbb21f345115625fL,0x4e7217de303a363bL }, + { 0xaeb0c8c0d137f67bL,0x4ff84a937bf78dfeL,0x7a022604683b37dcL, + 0xfa4ced77862b0847L,0x5a49bdc136d69390L,0x6d9dff06c0215314L } }, + /* 25 << 350 */ + { { 0xcb116e787b1320bbL,0x6310206258ed15fcL,0x1a7891a082c13108L, + 0x203d73d939eb4c93L,0x0485b8493c78c65aL,0x663897e93c935525L }, + { 0x9b79708088b41afbL,0xbd34d5134f2b649dL,0x0b4c156f62f6b652L, + 0x24125d1d6863dca7L,0x726a8bb2edb6638bL,0x2ec5deaf82aea7a2L } }, + /* 26 << 350 */ + { { 0x9fb22ca52a3706f1L,0x5a265b5279f5203eL,0xc8844f096fcbd426L, + 0x52a165f0ed8a3267L,0xff0b3a00dfdfcac5L,0x80167cf52de9e1c6L }, + { 0x9e9c4391b0b969c7L,0x279440c41e0dabf6L,0xaa535b8f85133e39L, + 0xef61e22234660228L,0x8ea81a41c386528bL,0xd0bb1f6e71a8c66aL } }, + /* 27 << 350 */ + { { 0x75a689bfa67ab0ecL,0x53eaad3e54843363L,0xdb71f81619a3ba98L, + 0x817257fdc244f33dL,0x8181c028c0fb3720L,0xc813c4651cb7bb39L }, + { 0xbc44c1e71b189585L,0xaedef8701eea3a29L,0xcdd828d7ccb5dc90L, + 0xd224f1774fd2e0f1L,0x2a4723b0e78883e6L,0x33bb05473128e260L } }, + /* 28 << 350 */ + { { 0x544874b71477473cL,0x253a455a3907385fL,0xb303afd631411ba1L, + 0x30047aa0466d6415L,0x3a1b676594d4c2deL,0xc265f1912860c7b1L }, + { 0xfe140a73688e7975L,0xf08a652bf37ce7deL,0x6c9f6df9f46f144eL, + 0xf7e7b95bc0defbc4L,0xfbc9a9697824c075L,0x9745d768d7773c39L } }, + /* 29 << 350 */ + { { 0x7170ab4699873dabL,0x765eb89b8952bc0fL,0xbe3fe2c4f78fd020L, + 0xde51f8579f194b70L,0xa625839e7cc68fbbL,0x50e59b49f7105097L }, + { 0x625294f3b82e287dL,0x98daa85288ca9d10L,0xfa0eb790b499d9bfL, + 0xe280de610382dba8L,0x3fd350e0e76a7d70L,0x1e5c2bebece5ba7aL } }, + /* 30 << 350 */ + { { 0x73e187e000ce469bL,0x21dc6268dbd717ceL,0xe9d63224ee564ef2L, + 0xa7553c854c4c444bL,0xdd409398f6a9b713L,0x902c9cff72f94d6fL }, + { 0x944edb33f50a36eaL,0xa48a5ae4cfb65a8aL,0xcb9a83b9ed82fddfL, + 0x9476090c209aa829L,0x66cd0cb1c7e2347bL,0x0f1fe07c86fa005bL } }, + /* 31 << 350 */ + { { 0x7c17a2e0c65e52b9L,0xa987f030615b8325L,0xa39b78aaa3d4dba8L, + 0x738ce26396e96e82L,0x313f7bb7f08f99cdL,0x29571b3cd1a1b7c1L }, + { 0x00c0e66c89ead6e5L,0x231de4ff19b9874dL,0xc9445296a4137755L, + 0x7b95f3ea336ea724L,0x7c0a222c49bfe5a0L,0xa265c41d782f8d4fL } }, + /* 32 << 350 */ + { { 0xd2db4d35c8d2bf7bL,0x52105d0981571d06L,0x447565cc723a57bfL, + 0xd98c3597d8ded62cL,0x0aeac6d9de2f1a9eL,0xd363b0b70a98d3b2L }, + { 0xd9708f0702ad9933L,0x9334677564f5809dL,0x499332cf49cda010L, + 0x546df74a858467e2L,0x8b84a55093748e8eL,0x9e88ef9706f09073L } }, + /* 33 << 350 */ + { { 0x1cdc6b4f673d9c55L,0x4300148a0c11743eL,0x2f924ce4c38b8c99L, + 0x5300ecc925f32459L,0xb9cd815004473c2cL,0xffee15498eebdcabL }, + { 0x42c292d54c537dbcL,0x32f6d8a293a133d0L,0x4da3a50c35dc41a6L, + 0xc16dee6a102f9ea4L,0x69a017a1f00d0bd6L,0x6a95ee1527acbc5eL } }, + /* 34 << 350 */ + { { 0x6c02c17adcb73b47L,0x10073a3454b70b07L,0x417ca218a7fe7a73L, + 0x6f81a38e4ab64b0aL,0x4e25301f8fa7fc44L,0x180f3e1b27d41e1eL }, + { 0x88925649ce1cfbf5L,0xae279fff2eedaeb9L,0xeac9b033eed426cfL, + 0xa8488f8aa1740d49L,0x6f748bc3711b5da7L,0xbb1c46fd23bbe135L } }, + /* 35 << 350 */ + { { 0x6b2f317b9da70c21L,0xebddc2b5c99dc82dL,0xf4a85d4c5c807d1eL, + 0x47a79b298a15ad6eL,0x02afb05befbda553L,0x34f3998e6941a669L }, + { 0xa4a413fb72deac14L,0x2bd9306c1941b899L,0xae023fa5788c1db8L, + 0x38cd6c42e1012bb6L,0x77ae298c13bd860bL,0x6312af9d63bb40cbL } }, + /* 36 << 350 */ + { { 0xbb7742f370fcad48L,0x6dcce7ff57d444acL,0xfc338485b6abc122L, + 0x03c1118caaf9060bL,0x095dc123cb997905L,0x2dfe24453dd9bee4L }, + { 0x9bffbbf9d45cdcdfL,0xc5b50babb4b26fe5L,0xe985754e87d31873L, + 0xb5b007f5a503d2e0L,0xe25c4eb620bb8357L,0xb6f00e50803fa8ddL } }, + /* 37 << 350 */ + { { 0x21cab682b8035f01L,0xec82f6ae301c96c1L,0xf25d6a0c1539a503L, + 0x94180ece1e35b449L,0x13fbc96f1ede3c57L,0xe4a63eac01d8e678L }, + { 0x3d1a745c068c6886L,0x0659d6ff233be378L,0x493d7a6f3244a214L, + 0xfa852b1b772bd953L,0xbf05cc0ce87db547L,0x28f497ccb30aacf9L } }, + /* 38 << 350 */ + { { 0xa92f28b88ea312ecL,0x9c702e953a3b5f1eL,0xf0a2f787583053edL, + 0xf99506f29cb41eceL,0x4c3b00b5c2b5c214L,0x59bb943717b8d5caL }, + { 0x9ccc7869af5e6b94L,0x6eb795a7f340d02cL,0x7fc613c80a09eca5L, + 0xdac14e61d155f16eL,0xda25c7fcccadb39eL,0x160fda8c9c7fe2b3L } }, + /* 39 << 350 */ + { { 0x8aa83310312ee9dcL,0x702ad7bc2af291bfL,0x3940f883ec915c5dL, + 0xdfb7e44f6fe07c64L,0xa7af875c72d09357L,0xb5df04f4f70b766fL }, + { 0x738af1bb96f8b10bL,0xab27b86735563f8eL,0x18fccbec2ebaf570L, + 0x94e9066dc1d7d59dL,0xa1e3518dc63373e4L,0x0722fd0f22d8306fL } }, + /* 40 << 350 */ + { { 0xcd42d2391be93e28L,0x93c11fcae2ea0d1cL,0x8acd0b17345984efL, + 0x3e3feaf350905d0dL,0x4124e89a6f35b49cL,0xafdd8d27a2bae979L }, + { 0xce1e814015ad5661L,0xb0f9296dde281bc6L,0x11e93935c31ea529L, + 0x1c4c3bd7ebb898ffL,0x7cb73fc76ccc32c2L,0x69e5307da3ac9b8bL } }, + /* 41 << 350 */ + { { 0x37bec50c8e5a9a8fL,0x7f0daba5055a1aa3L,0xa56bc577a1c00a74L, + 0x0656b6aeab88258eL,0x2959237fb88f0f0fL,0xffff63bb9ef15ca9L }, + { 0xd9a2909eb94ae6c0L,0x2506a1779b304c76L,0x5658fed3abdf17c8L, + 0x9c95765e0f90cc53L,0x80ffd7b38e74dc97L,0x97e032e6b8c73479L } }, + /* 42 << 350 */ + { { 0x7073ada11780b0c7L,0x6d4ce321f35f07d8L,0x27b26ee589f35e5fL, + 0x5af10ecd324349d4L,0xf9a0a9071b9bd956L,0x5dde968571350ba0L }, + { 0x678158f5b6400a5eL,0x93764a022842e0deL,0x71a17724057c9ff8L, + 0x04c4313c72f58c63L,0x07fdf15cc4e81260L,0xd6c25e82a509f1acL } }, + /* 43 << 350 */ + { { 0x4f8a719ae3cf3138L,0x7aac7f0d9b1a2e30L,0x3fe8dcb88c0c76d0L, + 0x34afed4ade0b5be0L,0x824e043cfdf7c28eL,0x5b700afce708e71bL }, + { 0x6c7fa728eeffc50dL,0x2488eee97ca62450L,0x25490cb59d969f4eL, + 0x8bbbac3d8bd629aeL,0x7e5213b56e75e171L,0x1385bff25324b23bL } }, + /* 44 << 350 */ + { { 0x364e7371c7d996d5L,0x053390bf8cc483aaL,0x69c23cf281e948d1L, + 0x65e45d618e822ec6L,0x9240ee412ed94568L,0xe0f33912510a84cbL }, + { 0xad42eb0f6ecabdadL,0xb35afdb4bc7e39f6L,0x4ee63cb10cb50316L, + 0x7ccfa14a2a27dc3fL,0x584328f0b4141347L,0x361b2614a23cd89fL } }, + /* 45 << 350 */ + { { 0xe70edc42ee93ec36L,0xec773e52bccc99efL,0x9b0367a0ce0816e2L, + 0x43baad458c6757e4L,0x5d25fa821fb7b01aL,0x65913e86bb6bc3fbL }, + { 0xb1f1fcab67fafef2L,0xe5ffd89c9e9261cbL,0x86f7b89ff29bb205L, + 0xa76ed6722db408b5L,0xd6f1ce5cf83f53a5L,0x9cb5cd26c2882d51L } }, + /* 46 << 350 */ + { { 0x03f6ca364b2582d0L,0x70345ae80f8116e4L,0xc2612cbfc562aba3L, + 0x9cdd127789898142L,0xea7f202c02d762ccL,0xa00c15da33662a74L }, + { 0xcb5cc621aa430b63L,0x6dd1482fb1550d67L,0xb27e7df46216f063L, + 0xfffe57408f49403aL,0x9403206cfc2bc9f9L,0x132504014593a578L } }, + /* 47 << 350 */ + { { 0x6b9c67e6076b2d5bL,0x54509f61883d31d1L,0x25905831fe051be5L, + 0xe6633c1be93608f5L,0x284afa7697480e6aL,0xb124e6063a06cc65L }, + { 0xcbcb2c2e2c608edaL,0x07a39d8f813795a2L,0xf27742a8bd108bbeL, + 0x7425519005b4e5b6L,0xa27620b2b0145a3bL,0x6e3d1210c0f42782L } }, + /* 48 << 350 */ + { { 0x0eeb9dc702ed3c24L,0xe7cb624dfb39fc44L,0xded105f581d4cceeL, + 0xaa675d0c46465cc3L,0x313f4fc99af0a81bL,0xd129819f227e6a72L }, + { 0xaa6b690340b16103L,0x3dba75b2fb4c2fdfL,0xc9feeea1e7c79c2aL, + 0x14f503104e024e75L,0x3704aaa8b5729449L,0x39ac6b0c24b86accL } }, + /* 49 << 350 */ + { { 0x7e25860735214575L,0x3baa75cb068c68c2L,0x93b6a33f10be8d33L, + 0xa88f3cc11ba06b10L,0xe70e7ec2a4f8fe72L,0x32fed39fd4835710L }, + { 0x16137edf3e6059b5L,0x57b1bb9fbb064775L,0x68d3f26dac98cfccL, + 0x89339bce7f9fd53fL,0x15b32212825e946fL,0x55b0a89bf92a0ef1L } }, + /* 50 << 350 */ + { { 0xf419d9becd3eed01L,0x851b31659851492fL,0xa9ac81a9c9b0a402L, + 0xf67bdf20122c09acL,0x9b26b131f442a030L,0xf7a548f517e72d1bL }, + { 0x9e0dbf852a7f505eL,0xaa8e7348c7e93ff2L,0x4efa7877134d8017L, + 0x48f476fc13e5fb0eL,0x552d0447154f4040L,0x8d5b166569b18f6aL } }, + /* 51 << 350 */ + { { 0x65ef443e63c90cfcL,0x3a0dfb8194ed3ad4L,0x75570ba710b5547dL, + 0x5e161fa498e84064L,0xf55dc5003c576f89L,0xe46bd28c7f530eabL }, + { 0x367607400109f9c1L,0xde7a997bb15e9598L,0x25386f307593c3d7L, + 0x680e3639def120b7L,0x43fab687aa6e213eL,0xce48861daa99cf3bL } }, + /* 52 << 350 */ + { { 0x93c2cf3e53ead820L,0xfca3b3564f4444e1L,0xeb6d82bfaac7a37dL, + 0x9c0915d4cf49947cL,0x771f9f7cc7edadaaL,0x51418e487b2df679L }, + { 0xad1b249173f28cf8L,0x8fe4fb7baecacd2aL,0x539764bdb20d0b77L, + 0xb0073685a6a4f808L,0x4c6f5602cf909196L,0x1ae89342d45e9e7dL } }, + /* 53 << 350 */ + { { 0xcf8aa4e5f007985eL,0x833ea882c325d2dfL,0xc1cbaaf5f9f326e8L, + 0xe779a4a9bf906c20L,0x29f475bbc923cf15L,0x6598d52a54055b74L }, + { 0x1001a5f1e4fbd4f9L,0xb4933d56cc74cc71L,0x45c04a50fed802baL, + 0xda140558052bd04cL,0x71c127d63dfbd563L,0xef2b85ba42ebaafcL } }, + /* 54 << 350 */ + { { 0x76569e44bc325891L,0x8f8a1487fa2604afL,0x07a8bacdbc90be04L, + 0xeb53b1087b2c9bb7L,0xcfdc78aaad3c7943L,0xd74807da3bfcd779L }, + { 0x642552417189257eL,0x28138e8d23cb9584L,0x0ce0b331476b888dL, + 0x6d9ceaa0f2a9bbe5L,0xb4f1185653b872efL,0xfa9e6fb222d06df6L } }, + /* 55 << 350 */ + { { 0x0d45565ce6eabd52L,0xaca75463f41a4559L,0xc3e4064a846eb291L, + 0x22ac04bc8613d2f2L,0x74cf6fac2364ce2cL,0x61bbaca8be4fce3cL }, + { 0x302e8117b24dc7b4L,0xa72ae24dd89a053fL,0x75b2023967de96e1L, + 0xbe51cfd2a9e6d1bdL,0x807a8e3d07c9259dL,0xcf3cd92e43cf6384L } }, + /* 56 << 350 */ + { { 0xc040412c754b8669L,0xbda7e0cde2c1d3b4L,0x2ac3b3d5ba29b9beL, + 0x98a415e3f63bf3abL,0x25aee93ed1776a16L,0x46db7347ec3bc968L }, + { 0x8e44180a02612d2bL,0x4e3dc4e82db990ffL,0x2050f58f5f7705dfL, + 0x7b41f5892672d845L,0xeb301603c96e4fecL,0x66ecd24e6cb16a6eL } }, + /* 57 << 350 */ + { { 0xd428e7e3d01edc1fL,0xef608062873fadf8L,0x05e7c80d5606965eL, + 0xb818d0c6a979f826L,0xe9b4c5c7c4793537L,0x7ef637225e83bb66L }, + { 0x825d89499fbb3a85L,0x557abf0396e34cabL,0xfc3db05b8040ad0cL, + 0xbdc8e907e305204eL,0xdfc1628d1c1637e1L,0x10841d2a947a78deL } }, + /* 58 << 350 */ + { { 0x99432df309c7b138L,0x288eef14593b1fc1L,0xf47f9fb21b55f0b4L, + 0x5cc20dd46788b9a5L,0x2e87fb4605e43a77L,0x08cf86be849c700aL }, + { 0x467ec61374680ce7L,0x44e5c8d45884aff8L,0x549f2ea86b33a1a9L, + 0x2ebf696a8b4a815dL,0xc1705b152a74323aL,0x930a9fde69745934L } }, + /* 59 << 350 */ + { { 0xbb11fe102d168ee9L,0xba4aea667f39e124L,0x139364b6fca2841fL, + 0x6feef5b13d359df1L,0x4fe89fe19787be92L,0xd4cea92e0f6b6aa9L }, + { 0x794006c0039bd8f5L,0xdce0eb5b0be647abL,0xf4a97f7d4e40c1d3L, + 0x78d19059d5f7254eL,0x464ddc1d0df22d8bL,0x990b0a39e0fc7628L } }, + /* 60 << 350 */ + { { 0x72f5a0f70ad3bb67L,0xabb15e3dce6396d8L,0x2ae94788463efba7L, + 0xe77b53b41fd4c512L,0x09921a1ca88606cdL,0x1b86b75608e980eaL }, + { 0x2def667af3d22731L,0xadebd3a39641b175L,0xc0f35509045da920L, + 0x8fbf85e4952b7ca9L,0x4ee7565023517a65L,0xd31eeea30e75a4a4L } }, + /* 61 << 350 */ + { { 0x6d9a5d3cc4508650L,0xe71fcf32d1a2ac1bL,0x784b9148d62ec2dbL, + 0x9a3d5d572088946aL,0xc488178757848c00L,0x2f50a62e0875c1e9L }, + { 0xbd23d4aedec0f2dfL,0xc9c28dd5188dad0eL,0xf87ef6460977ba29L, + 0x89ce8330ab03e4d7L,0x7dbec90dbcf1a5a9L,0x3ddc39c1f6c2a4d4L } }, + /* 62 << 350 */ + { { 0x8c0518c7618b787eL,0x6f226212b95734feL,0x3e6cab90c66e138bL, + 0x6e56d68037a7c0b8L,0x67a3c7df16f6acbbL,0x43df95107921bb92L }, + { 0x967846f6a0887d25L,0xf717017766908fcbL,0x1a8ec350267430d8L, + 0xebb46f1a25855c90L,0x73eb78cb396c1714L,0xf766957cdc081e43L } }, + /* 63 << 350 */ + { { 0x0700da846de27e73L,0xfac9dcfd78c35563L,0x01af330ccd073b09L, + 0x0bf5c3b1bb784ceeL,0xd3d9a9ff5d465498L,0x4836b065bde8bafbL }, + { 0xf5bf3316329b4cf5L,0x387388fc54a5275fL,0x73e880d8254af26eL, + 0x07ebcddc8d05311dL,0xe8b9965a4f46cec2L,0x4f07a4fa01b06069L } }, + /* 64 << 350 */ + { { 0xc0a40cac52133095L,0xfe1b22fd93c162bbL,0x8625898c34018741L, + 0x69c9f3f636d9e57aL,0x69d9d7f3378aa211L,0x6b03f897e7dca168L }, + { 0x24d49aebf997a48fL,0x1d984c67c149ac40L,0x667c1d01576f533fL, + 0x372eee199ef82eceL,0x577723c0c207c14dL,0x4225907a0eed37f6L } }, + /* 0 << 357 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 357 */ + { { 0xc61db977bc0e0903L,0xbaf6e4da645c32fbL,0xce89b8ca060b1adbL, + 0x41db448188e2c178L,0xba6339f3923bdd3cL,0xff25b818d29db42cL }, + { 0x3521116ee6d6b35dL,0x4e1bd283b22f16acL,0x9357c984bd79fe5dL, + 0x2eda73be9d45eee4L,0x1a50c59f6288e01fL,0x37baf64975018873L } }, + /* 2 << 357 */ + { { 0xc552c6c6097f322fL,0xdf59a3028bc06287L,0xc9ed375c19610b0cL, + 0xf0e7b4ebb051dad5L,0x7267a304c6556643L,0x0044f6d8c96dc1d8L }, + { 0xf0ed5f9af4fc3725L,0xbbaf9f2c9de8e1ffL,0xef5d66f4af5a4b4bL, + 0x0b5bed3d20644cf2L,0xf7e4543a75ae23c0L,0x696f60dc41325b66L } }, + /* 3 << 357 */ + { { 0x9949b33d2c20f868L,0xdb3aa790b5706250L,0x88ce71e788e17f2bL, + 0xd851baf2da9c0881L,0xe869c5ba86d8c9e9L,0x1af68d65a01425b6L }, + { 0xeae8b1c69bbd3963L,0xf34900b1ec087425L,0x14942910c374bb96L, + 0x3e13c45705487483L,0xe0e6fad435bc6ee1L,0xc7c38dc7b54d247bL } }, + /* 4 << 357 */ + { { 0x6d34bdf6ab463fa6L,0x7bb127b60093b9cbL,0x61d051135a3bfdd0L, + 0x4abab575f1296bddL,0x72da68494d2e9a7cL,0x90267bca8d11f03dL }, + { 0x478111223e9b310bL,0x8ffe91d31b1920cdL,0xec293ec67521898eL, + 0xf0cf026996c1da75L,0xb0dbd4c380f2c7b3L,0xe528175534e4baf8L } }, + /* 5 << 357 */ + { { 0x7ce1ce36189e2f1bL,0x36ca8fe3fa84ca41L,0x54cc2c13a6a568e4L, + 0x1967d9ed25a6d223L,0xf8d20c88537252afL,0x5a58936cac3d697cL }, + { 0xa2659671b0084ffeL,0x08a9e041ec25bb0eL,0x6bd405ed4074ccedL, + 0xaeebb470dacb5503L,0x6f18e32bd5448d3eL,0x0412973ba94cd45dL } }, + /* 6 << 357 */ + { { 0xd72fcc3742fb1cd7L,0xadfb8967c49c359dL,0x6dc988a55935bb0dL, + 0x3fb10981e3080802L,0x12c4494f3be161ceL,0x5a0e22d44b649dd0L }, + { 0x5c57cbfd62a85259L,0x7ad55b3c0e5ab7a2L,0xcd53564928de30e7L, + 0xce35e6e76867e6a7L,0x626810562f6716fbL,0xd8b4ff26a88d3bf8L } }, + /* 7 << 357 */ + { { 0x5949ddfa53abe7a9L,0x944a2ae0716f63a6L,0x90961922675d1f43L, + 0x36c41c12f5b55722L,0x85b8250f7782775eL,0x89a3a733748663beL }, + { 0xd4358450475d2d88L,0x4183f45e1beef8adL,0xee3bfe8b06ec8d58L, + 0x2e462b1609cc4d82L,0xf9cc307ec6148e1dL,0x70d3b2f77b1281a3L } }, + /* 8 << 357 */ + { { 0xc32730e8dd14d47eL,0xcdc1fd42c0f01e0fL,0x2bacfdbf3f5cd846L, + 0x45f364167272d4ddL,0xdd813a795eb75776L,0xb57885e450997be2L }, + { 0xda054e2bdb8c9829L,0x4161d820aab5a594L,0x4c428f31026116a3L, + 0x372af9a0dcd85e91L,0xfda6e903673adc2dL,0x4526b8aca8db59e6L } }, + /* 9 << 357 */ + { { 0xf0467111e854f886L,0xe228021d8dc6117fL,0x07ff954cac432e28L, + 0x373be2ef31d9b69bL,0xaa214d016fd61f0aL,0x27bb7932f950b029L }, + { 0x1caa914f967c97f0L,0xfb133ec0d548897dL,0x598514173cfad251L, + 0xd41d1da432d14208L,0x446c79f2cee424ceL,0x8b5272a175e839a5L } }, + /* 10 << 357 */ + { { 0x26b5e85d62f50c12L,0x8418cecf5ff562d5L,0x0d35b4d459be698eL, + 0xd79ca9ee93730d2eL,0x2414d99325627fe5L,0xe31dc5293fc64803L }, + { 0x5c9100d60d027a12L,0x9004ee36f2208db5L,0xe734b13b135d02bdL, + 0xf905c01a7bc09b60L,0x4eb51557b21b68fdL,0xe6e98bea8c583359L } }, + /* 11 << 357 */ + { { 0x14dbcf1a61dae7e6L,0x559a7b52ea0da075L,0x7391545d439d10d6L, + 0x187e00e675e617abL,0x453b546b5142355dL,0x9bdbddbc84bca97aL }, + { 0x742a699591e5035dL,0xcf86d3e1831209ddL,0x6fb66757f5f2a999L, + 0x2e360aeff0e71f2dL,0x6c6f71f2dc97114aL,0xef686b8b17c3a3dcL } }, + /* 12 << 357 */ + { { 0x7d07a61d13b5ea74L,0x7f4b7157c8afecd9L,0xefce9c89820b0298L, + 0xe85c4510e3888d59L,0x9cd3352001234b9cL,0xba2692c0fef767e8L }, + { 0xd2bea3d45b3ca353L,0x9ad478e5b51a704aL,0x1fc9bd0d9426f25bL, + 0x52f930bf864a1ba4L,0x559f36353765ff27L,0x548c7f0dae28479fL } }, + /* 13 << 357 */ + { { 0x6296d54f68b0df62L,0xace420ee9e6afdd4L,0xa20a510dfcd1812fL, + 0x488f113a8cd04a29L,0x1bee07640765cb70L,0x50bb5c446d0f44e5L }, + { 0x5ea842cb7e320ebfL,0xa6e0c1e6e795a7fbL,0x89cd1f765e7e79c9L, + 0x7436ec1e87ce6c5dL,0x1376222de28309f9L,0x9ed7d6fb7f01548aL } }, + /* 14 << 357 */ + { { 0x32e9740ae2fb0467L,0x3a7a32b3ec039d67L,0x630d8d346a425a7cL, + 0xc9af74ae418a7dd0L,0xc903576daf502870L,0x7e02b3b7e98cce5dL }, + { 0x0bfdee7a158f005bL,0x88eff4a363b91d59L,0xf23079728bfe3ed3L, + 0xc75536bce6b1fb4cL,0xf61a82e1a04d46fbL,0x771a8fedfddd52a5L } }, + /* 15 << 357 */ + { { 0xf5efc82065af5b94L,0xd618a9e8ce5535a2L,0x70cfb112cda6249cL, + 0x6986f00f9f217280L,0x41e46ce605faa951L,0x2abb39f3a3ad613cL }, + { 0x3e04b28b07671c94L,0x61d323ac53cdaf80L,0x2389875cbb9580f8L, + 0x64800835febb0b34L,0xdaebba99d0d21027L,0x0f1cebfc23288a7fL } }, + /* 16 << 357 */ + { { 0x51a033a5cecb916fL,0x2ac62f638d7de61cL,0x92eece49a42a266eL, + 0x87e037db82c4d11eL,0x875be1416fbae08aL,0xf348fe26c539478cL }, + { 0x51f8b907ff94c01eL,0xc46cc0e019695a9dL,0x2c74bd666c51b9c2L, + 0x635d3d24ee565de8L,0x6bd656638982c8c3L,0x5c345b79daf6a93cL } }, + /* 17 << 357 */ + { { 0xee7265ee93f081dcL,0xe8f90a6be03493f4L,0x4e8d10275328b0b8L, + 0x13bb82bb96fa0930L,0x764c2915d1f7d5a7L,0x1896c78f73476481L }, + { 0xe9a34ff267873b76L,0x8a9a719cfa0afda4L,0xce93d4cc9ccb715aL, + 0x9ba00f011495d1ffL,0x3131e6666df0e119L,0xe68e1815c902ac6bL } }, + /* 18 << 357 */ + { { 0x0ce4ae1044f4a2dbL,0xa8645e2310bcc5c6L,0x6d9728b5e489762fL, + 0xd365c12a9d46ad88L,0xedf484fee1a527aeL,0xfdf5c519e5be2bb1L }, + { 0x4706cc2870a3d4e3L,0x07c60129065f1506L,0x42e2e16478298553L, + 0xa56a2bd5bae646dbL,0x893bf45c61437e62L,0x97dbf9266c525900L } }, + /* 19 << 357 */ + { { 0x65c56764b52213c3L,0xa171ba9d97aefe9aL,0x5904e8c934336916L, + 0x727209b6ff187f05L,0xaf4e50525cb68a5bL,0xb46a6abadc4319feL }, + { 0xfd48d0d57890cd90L,0x5b0b68c7252942daL,0xc41023352b01887bL, + 0x582251eb5ad09a7dL,0xbd79b557e1312726L,0x9f5ee3788057db5cL } }, + /* 20 << 357 */ + { { 0xa30486a6666fdcc5L,0x5cb7f7ce84056f89L,0x0f8a6b96505636a5L, + 0xfeafdf97c6624ce2L,0x9dade91c55b8a7d6L,0x3d009219ca2b459fL }, + { 0x483549845a969337L,0x37d57cbd323c09adL,0x32a91e91e74b9e74L, + 0xdb4f18ff1c317c24L,0xf9f0daf342418667L,0x735a1eb946946667L } }, + /* 21 << 357 */ + { { 0xb395bfd1c8eaa54bL,0x8181d6262ee25219L,0xf4bf437b38d912f1L, + 0xf9f1161228a8b32eL,0xe359adacc2be5c61L,0x71557ea2971b60c9L }, + { 0xf071404b1b00cf1eL,0xb163c3608da3141fL,0xd9dedc07a8d51d98L, + 0x29e89ac5ac827b74L,0xc38cef633ef35dfbL,0x9abd281097d477f1L } }, + /* 22 << 357 */ + { { 0xb34e560f0e6d9646L,0x4fc05a0dc0ba033fL,0xc9f5e040ddc1bcc8L, + 0xf723b78ab92068cbL,0xd558f5912b5c7030L,0xb16bdec774ed778bL }, + { 0xc12aacc3b32980e0L,0x856e90411daaa32cL,0x34f7a28596429db4L, + 0xcc2c61ea415dcd04L,0xa0e192cb46b7d996L,0x5b7c845d55d87ce9L } }, + /* 23 << 357 */ + { { 0x9ba0a26fc0ee684eL,0x1b871ac353573254L,0x76a094bc5783e706L, + 0xe78bea66dcc01e8fL,0x7e20c5aedfb74e56L,0xbdc5314a8710f0e6L }, + { 0x2bcc7a0085f2233aL,0xc58dd45b8aba1575L,0xdd1c6b78e411b6d8L, + 0xbb8d19529d23d2eaL,0x5293f3cc0066c9cbL,0xb7d0d7b0249c6d93L } }, + /* 24 << 357 */ + { { 0x68fe359de23a8472L,0x43eb12bd4ce3c101L,0x0ec652c3fc704935L, + 0x1eeff1f952e4e22dL,0xba6777cb083e3adaL,0xab52d7dc8befc871L }, + { 0x4ede689f497cbd59L,0xc8ae42b927577dd9L,0xe0f080517ab83c27L, + 0x1f3d5f252c8c1f48L,0x57991607af241aacL,0xc4458b0ab8a337e0L } }, + /* 25 << 357 */ + { { 0x614c4bc273041ddfL,0x4fef1cf6364135aaL,0x2c9ac204ecf0e610L, + 0x75a302a991a6dce1L,0xa5899c96651ec9f9L,0x6c5384f64bcad1a6L }, + { 0xa41012e560f705ebL,0xfcf6512235e85d67L,0x2fdcfc235ced3638L, + 0xf834fac02deac34aL,0xf5a64ec510a8ad80L,0x843855e1a412c4feL } }, + /* 26 << 357 */ + { { 0x440dfebd76ca517aL,0x79924057c577eb59L,0xf1aea290d038a921L, + 0x77afb37fb0c95974L,0x48a5b9a715763d44L,0x713de85155c8683eL }, + { 0x250e8f8239d7e1deL,0xc5f1f61c8a2c846bL,0xf26ea6f9faafd017L, + 0x8ad26055f9d7cd35L,0xc980ba773b2df598L,0xe23b7eabd5e299a3L } }, + /* 27 << 357 */ + { { 0x5d37811464744605L,0xfab096990278c1f0L,0xc4d32b208448c344L, + 0x767a24d2d7d1df17L,0x842de148773ea0fdL,0x73d7dfbdff6e40b4L }, + { 0x3d61439283576d1cL,0x4820c435ec865519L,0xf99e84dd6bfa5e48L, + 0xeb18687a9d0d2adcL,0xc3b7369da7fd75d2L,0x7e332b5739f5f093L } }, + /* 28 << 357 */ + { { 0x0796a8b6ec13d2acL,0x19036c255677347dL,0x2f0d36eef527c827L, + 0x7c8a3d17ca61ed60L,0x3920bc68748cf7c2L,0x61835bdf9018b300L }, + { 0x9cf595c1689d5826L,0xdc547999fb51aea5L,0x11bb04120fc297c6L, + 0x88770df2b2f9fe0eL,0x99e031f5f6856a85L,0xbb59e8c7afe29c50L } }, + /* 29 << 357 */ + { { 0x714e784820dfc5f8L,0x35cde8ae2a2265bcL,0xf6b29ce4bfc32fecL, + 0xbd5e91f1918043a5L,0xd3766f8b60f8c218L,0x273c41935298904cL }, + { 0x0a76492d5d441fb5L,0x99cb3b1d164d9275L,0xb2be87c80ac7935eL, + 0xbd1a1b3f0962981bL,0x8a0c207b96d0df2dL,0x1bb1e505929752d9L } }, + /* 30 << 357 */ + { { 0xa574de94621b2705L,0x0d0ca1b73e3f2227L,0xbdc9ddf2e49bc2d8L, + 0xfbc7254309d314f0L,0xf5900cbb827e0b1dL,0x3994eadd8a7e8164L }, + { 0x2e7949793046f170L,0xde21ddc3c6883cc6L,0x9ea19d34bcd40da7L, + 0xb4334df8f01a9ae5L,0x801496ebce8c53c7L,0xc2a5e8527a4b0601L } }, + /* 31 << 357 */ + { { 0x435a6c512ecf62d2L,0x757cd8f6559a6a0cL,0x47833f815e4c0d40L, + 0x2d0b48047d960c6aL,0xf5474833473d5eb3L,0x70264154bf756b52L }, + { 0xcc46e58d940bfb7cL,0x2e0dd3a69c89d48aL,0x483f3ee19387df66L, + 0xb3097da4585d3600L,0x82d64b4d76411ef9L,0x0df7d95719682e87L } }, + /* 32 << 357 */ + { { 0x179c59cf210c3144L,0xfb613c5733eebbc4L,0xdda75cfdba0cf384L, + 0x94081a5b3a8fbafaL,0xb91de90a33384e0bL,0x7d1f8f4027aa2a45L }, + { 0x0747bcc162031148L,0xd2db8e39f324160bL,0x9c1ce3e9722484f0L, + 0x13a7ee5da62d1ddaL,0x77fd79343a963bceL,0xcd3d871783d2f21bL } }, + /* 33 << 357 */ + { { 0xc7c8eedc93a27196L,0x0832b0dfa8abe585L,0x31fe11e8d8adfb86L, + 0x1091601e9d50e4c7L,0x7931a284ac3d2ca4L,0x0f1464b6f3fc6641L }, + { 0x2ead94f3260f29a7L,0x914b8396d88a7696L,0x950be4bbe73d807dL, + 0x26d0115e5b3ad83dL,0x3de8a73146c22525L,0xe50825dac5fffff1L } }, + /* 34 << 357 */ + { { 0x716378cae4b98aa8L,0xacf8d67b59b746a9L,0x78f0b5eca65ce8ebL, + 0xe5997983523cfa35L,0x85bf5badbeba89e3L,0xc8052bbfcfd73b41L }, + { 0x0b3d77139fb311a3L,0x821a20e2d96f696fL,0x0f087e5744657c9aL, + 0x72031f281ecfea36L,0xd0765f333f32b010L,0x0412c69929c48643L } }, + /* 35 << 357 */ + { { 0x53d361b89f501481L,0x8970937717153c6fL,0xb52280b916bb8d8cL, + 0x5985cdc0b33dabd6L,0x35ba0cd9dca8ae72L,0xf55c6e7301bc4efdL }, + { 0x2106ed2f269577c4L,0x4cc34291bfe765b4L,0x9f4168ea812eb958L, + 0x02869228999ba5cdL,0xff91540d3ab27498L,0x9020e6e158e55a79L } }, + /* 36 << 357 */ + { { 0x1a5b15377f1c7cbdL,0x5b31930b7cc17c56L,0x5b91e1a492cc8cf5L, + 0x970e43deeca08bdeL,0x36424bfe0e2e963bL,0x2e49534968b1a489L }, + { 0xe350ca52d8e85a9aL,0x3cb9f599ae2cdd7cL,0x0ff35a0aa83215ecL, + 0x64cf57b81973a966L,0x128be6cd36b26702L,0x8067afbd5f65f7bdL } }, + /* 37 << 357 */ + { { 0x23d1f49215876c71L,0xafb21c1d41e7495bL,0xdb3ab62c2705885dL, + 0x20ff803f7ba216cdL,0x26cb190699c9ee55L,0x8280dc9c0fb05389L }, + { 0xadf55171df1020dfL,0xc044e9bcbd011b5cL,0xe21aaa60cbed2430L, + 0x5939fe583336df4dL,0xfa306816ff78c665L,0xba92ca8243eb18f2L } }, + /* 38 << 357 */ + { { 0x6f05e6241b7edb64L,0xc280105b6681f48fL,0xd1b94413f993dc9eL, + 0x84f24c01e46de412L,0x092017d54abbf7dbL,0xb73193a56f7b1b08L }, + { 0x22a7c5765195ae46L,0x81dd6b12610c28efL,0x61959874ad7bfcc1L, + 0x3ade0a77d15f8cf9L,0x124cef4d954db624L,0x0733bd7a5c247650L } }, + /* 39 << 357 */ + { { 0x52d7f9ddf1cee098L,0x538b7fa17a6a2ad1L,0x5f2294312911e75aL, + 0x71c337b7e6ef0271L,0x5e278a1267ee72d1L,0x7b348c756f33fea9L }, + { 0x7bb59f1a694bb928L,0x5783e43f292b258aL,0xe3b53ca77181f1d2L, + 0x028ba90e051c7d2eL,0x4bb06f9364789d76L,0xcf97fc4da228a7a7L } }, + /* 40 << 357 */ + { { 0x3dbb3fa651dd1ba9L,0xe53c1c4d545e960bL,0x35ac6574793ce803L, + 0xb2697dc783dbce4fL,0xe35c5bf2e13cf6b0L,0x35034280b0c4a164L }, + { 0xaa490908d9c0d3c1L,0x2cce614dcb4d2e90L,0xf646e96c54d504e4L, + 0xd74e7541b73310a3L,0xead7159618bde5daL,0x96e7f4a8aa09aef7L } }, + /* 41 << 357 */ + { { 0xdf5c2fa79111caacL,0x493ada25b04d2b3aL,0x5c4850bfa39a7872L, + 0xbeae16c067e07e93L,0x63bd7d390178358dL,0x7a7e56a1cfe0bcd0L }, + { 0x9ba7a4500816b666L,0xea6c70c8dae070dfL,0x84013756832c2b35L, + 0xa28e5dd08d3e9fc3L,0xd67665aac653c08fL,0xee54d7b6aa6bdff8L } }, + /* 42 << 357 */ + { { 0x99b870afadbd24baL,0xb34fa9083bee289fL,0x4a20f29bae836fa4L, + 0x4188ed5024b464c3L,0xfb93f48fc6c00297L,0x334b8689736186ecL }, + { 0xbf7f1c424e1016f1L,0xf95e6e59413ca088L,0x5878156c288912d8L, + 0x9e99199704c7ce69L,0x0f0c185d5d6520d1L,0x1ed2ece33fe6f498L } }, + /* 43 << 357 */ + { { 0x319fb249607cfd40L,0x5920056f62b40e28L,0x9ab4528058631ab5L, + 0xb527738f413452d2L,0xb2885e46b296e602L,0xb1dcf41a74824807L }, + { 0xca9d2b06b2ad2fc6L,0x500c5f11ad05eeceL,0xca94160f21f3db6aL, + 0x693adf4e262470d6L,0x1f4c62c5480b0cffL,0xb3ebf11f54c748e4L } }, + /* 44 << 357 */ + { { 0xc8ae4d2bb4ef93b3L,0x4967da7b99758d99L,0xd1483a1fe04db9baL, + 0xf5e657df3033474dL,0xdd9371c89db4b96fL,0xb5f288956044b259L }, + { 0xe8987a43b2ec27bdL,0xaabb1ae68fce67bcL,0x4518fa3eb2b97680L, + 0xa0142a13748591e1L,0xf9148ab96c2db557L,0x65592253e0e4f9e7L } }, + /* 45 << 357 */ + { { 0x21163809bccf41d8L,0x0eafed515b3f09d1L,0x3b5360d9d84b27f6L, + 0xee752fd04411d37aL,0x1cea3b5c6a3f5027L,0xb206e74d9454d9f6L }, + { 0x710715dab52af43dL,0x8175ca136e6c6463L,0xbdb123d39689144dL, + 0x569e6edd4d9c459fL,0x070f09a4f02e5b25L,0x691c23ef3d79a7b9L } }, + /* 46 << 357 */ + { { 0xc0c94165781356cbL,0xcb9fb705876a839bL,0xfe23f07e89db25feL, + 0x710f0fa3a52cec3bL,0xb0ab363073e0f037L,0x3b79a8167c9aa037L }, + { 0xdbc7f83ca1f13fe1L,0x8bd910c63d653a81L,0x2e54ad408c78d003L, + 0x0de02157a3e9ccf0L,0xe9081e8bf7670dfbL,0x6a2ad476c8647bc8L } }, + /* 47 << 357 */ + { { 0xaf58106ebf047836L,0xadc3245e195e5675L,0x75612e175290e051L, + 0x27b81bd869d46bb9L,0x9d4dad5b5417b5faL,0x19850d70fd024259L }, + { 0x987daa604b0a86b5L,0x5d5a5f9c0358a944L,0x9008682f48d2ff67L, + 0xc9db4d4b89e81cf9L,0x133516bc850eaae4L,0x0b5bfdc81da8bd19L } }, + /* 48 << 357 */ + { { 0x609deb162d8bcd6eL,0xe42f23a92591750dL,0x4a9f3132b378305cL, + 0xf101799869275f5eL,0x14be746761b089b5L,0x05f620d20c81b0c5L }, + { 0xca90a9c06cb8412eL,0xfe0f6a8915b1b0d5L,0x1b25ac9620c71988L, + 0xb971b61a390aedd0L,0x995214d779d8cd39L,0xd7fa135b65c6e11aL } }, + /* 49 << 357 */ + { { 0x5aaa98f875330325L,0xc900a7781f3541a6L,0x69bcf864174a3200L, + 0x3abc5ef71c46b3e2L,0xa53c9e4e47851b97L,0xc166a4e22acdc42eL }, + { 0x49e4e6fdb19b4678L,0x4fe02cb162b7da19L,0x575c61a6633153feL, + 0x49578b28a4f83b70L,0xc6840d063737532cL,0x93047d40480f55b9L } }, + /* 50 << 357 */ + { { 0x835be7417d930332L,0xa4d001bb2cd86fc4L,0xef141e30a6e3a24dL, + 0x4047620adc328d2eL,0x5c80a3bc9a5f1f12L,0x6cde5e4ca19b423cL }, + { 0xcdd5d7773ba0fa5cL,0xb96dbe62ea85c28eL,0x963c02245c804896L, + 0xb2a581abe5dd6b98L,0x28a908a2abc8dac4L,0x5834b212985fd18fL } }, + /* 51 << 357 */ + { { 0x02757b1f0fbe0c5dL,0x2d0d05a854ef99e2L,0x2bda526d0377ffa0L, + 0x58ca8b08925985afL,0x1fb7dbe727b69722L,0x322d7db5f1c57fe5L }, + { 0x4049c8bcfdf111f3L,0x0b4712974148b027L,0x34fcb1e58782dab0L, + 0x697dc9431665557cL,0x3ae30e2844659ba2L,0x479dbc2f118e7417L } }, + /* 52 << 357 */ + { { 0x10b10d86227e8607L,0xe83536281d1be36aL,0xe34068f9d952b0e9L, + 0x148eeb38fdb6ea99L,0x82657d605547e7ebL,0x9c35dc82a86155eeL }, + { 0x408f79262060a81aL,0xf2a79205a6282e8aL,0x10dbb58526e70e7cL, + 0xd636f8225df85d6cL,0x03202c027682b922L,0x31323940baf18500L } }, + /* 53 << 357 */ + { { 0x5882374401879796L,0x068943ccd1249281L,0x20dec1c12e1d6effL, + 0x5f4c2c070bdddecdL,0xc56d52b37ee724c3L,0x93bc2c7a559e25ddL }, + { 0x0c95d2e5f98a9940L,0xc570e96ada60a809L,0x94c4a964076233eeL, + 0x843c99627dbbc526L,0xe4075129d4cdc652L,0x0afff70561cb2698L } }, + /* 54 << 357 */ + { { 0x3ec1e3a5f607f893L,0xd476dd24054aaa8cL,0x2cb92280a93488abL, + 0xc8d1207710d1dc68L,0x564839b9bfb494e6L,0x7a13930ceabdfe56L }, + { 0x52f72a9724f9b183L,0x30ae4bc87e9c6fc3L,0x3d7d2765f35b8e6cL, + 0x701f3d89a665ba55L,0x98f2fe85c466111bL,0x338073600c1c0dadL } }, + /* 55 << 357 */ + { { 0x7dd106bab3a48d42L,0x7eac4690ebfc75aeL,0xdbf3547e68ef4ea3L, + 0x3629c438a1a5faa2L,0xac2aa55e653bfd97L,0xae5cc39752c3b8f9L }, + { 0x117380552853b626L,0xd5a955f224a0dfe2L,0xc4356ca25940233eL, + 0x73f7eda97994aedfL,0x2bfa76c693b185d9L,0x091cef91a0327108L } }, + /* 56 << 357 */ + { { 0xa8393a245d6e5f48L,0x2c8d7ea2f9175ce8L,0xd8824e0255a20268L, + 0x9dd9a272a446bcc6L,0xc929cded5351499bL,0xea5ad9eccfe76535L }, + { 0x26f3d7d9dc32d001L,0x51c3be8343eb9689L,0x91fdcc06759e6ddbL, + 0xac2e1904e302b891L,0xad25c645c207e1f7L,0x28a70f0dab3deb4aL } }, + /* 57 << 357 */ + { { 0xf5dafec85f102704L,0x2f3b6b6929f5b946L,0x84472c029d4c9979L, + 0xed49f3e6341f0150L,0x3ee3432eb3bb085fL,0x84c553183cbac42eL }, + { 0xbb358bd9dc4c7ffaL,0x0713917d2db356ccL,0xc73e9fd0670c7139L, + 0x87600c4c3581108eL,0x2ae731d7586af51dL,0x30630ad6614c126eL } }, + /* 58 << 357 */ + { { 0x15f8fba7712c0edfL,0x4a1f93baa2c363ceL,0xfabca37e8f2948a4L, + 0x652922e4dd765560L,0x2da78559220cb98bL,0xb797746a54b940c4L }, + { 0x8535fcfc591bb7faL,0x58857815c25376e3L,0xcd8db789da627557L, + 0x718072ca318512b7L,0x92266469813efd94L,0x3217649aafa85382L } }, + /* 59 << 357 */ + { { 0xd517b39e51c4bf28L,0x6614c16261f583a3L,0x79c72f414739ea59L, + 0x597e1c2ff76e80f8L,0x3a72b05e7b846f3aL,0x1849e5126c0a45a2L }, + { 0x79a6ea5b9d506d83L,0xc48e570219b7f46eL,0xc89c5047c524bb48L, + 0xafc1fdd99cb88cfdL,0xb07eaaa0b82056e6L,0x60f6544f05885df8L } }, + /* 60 << 357 */ + { { 0x9894ef75f39e2738L,0xac585d07b40db6ecL,0x07d9e938c4cfdb92L, + 0xda174933737f1a7fL,0xa4f1fb65484031a6L,0xa96d9f612c21b546L }, + { 0xaf981519d24ccee0L,0x238de6de9d53b571L,0x09afc481fd78c3ffL, + 0x4351715d9ea7f6fbL,0x91a02325b14a7320L,0xcd8958d8bbb6346aL } }, + /* 61 << 357 */ + { { 0x22ef4217452ae6a0L,0x3192309d9ced837aL,0x773585ed2ba43ee9L, + 0xa9b29d94f3379e81L,0x43838b3aa6835e44L,0x1afe27ab0c7b2336L }, + { 0xca1dc61683ecd230L,0xc9e8b95e6d235df5L,0x9667829b2af11adeL, + 0x27254b0fbe532148L,0xb50bc3c86d233f14L,0x30e0e450bb35d985L } }, + /* 62 << 357 */ + { { 0x8b3f79087b95cf32L,0x67c654b06272c619L,0x61160a9d22c0f46eL, + 0x1cce95721d2e36ccL,0x62bd951d3990db3cL,0xcf0005c8d9700d14L }, + { 0x304aff9c70116120L,0x1c919dd2b08d57ceL,0x841b058ec0c0c0b0L, + 0x7cfd4deb7af05aa2L,0x4fbd13c57b11ce5bL,0x03e07dc9f8259bebL } }, + /* 63 << 357 */ + { { 0xe9b37f569d0703e0L,0x7b5e0df5f83c215bL,0x7fbb40f0d3c21efcL, + 0x87a2ff119fb33620L,0x208b062bd1176635L,0x806bc549950d30efL }, + { 0x862de3a4ae2bf355L,0x917b06bacf9ef6e8L,0x55f1ec4cadacc178L, + 0xbcd679fc81d752fbL,0x9404d6ce65a00270L,0x25ce99e6000c6e1fL } }, + /* 64 << 357 */ + { { 0xa13f19b40f3ff12dL,0x57ee08b1019564aaL,0x00ec0c997044a6f4L, + 0xaf5665f8dca1075cL,0xded5ca3f0620ab0cL,0x9b2cb8c7a896deffL }, + { 0x032ab2b307df2345L,0x964d109ef1da3f88L,0x2286b6f725133304L, + 0x0d16d531977a4567L,0x00a66036f1abae4fL,0x5debab1d95f0103bL } }, + /* 0 << 364 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 364 */ + { { 0xf2cdae3196230a58L,0x47cf36b4f304e1eaL,0x9d14f25ad750b29bL, + 0x931b9c65dba15f3eL,0x34db169ebf9fe2ddL,0x8a89e47c52663433L }, + { 0x8859a4f8026ec31fL,0xeeb703eaa913ceeaL,0x74638d6a67ac4db7L, + 0x5c8ea7b2be25d755L,0x8a0f0a8738db10eeL,0x96a26bace890bcd3L } }, + /* 2 << 364 */ + { { 0x883533af64a5e869L,0xaaa778c26973ec23L,0x8f0b5fb546d0fcf3L, + 0x7e6b0a0a4ab05da7L,0xcd91a869c67b6614L,0x7de9f2ff6c6f7cf2L }, + { 0xc072a106d1ec14c3L,0x3f4b960642a128eeL,0x7378192c8f0ce946L, + 0xdf2e7b9fd1149441L,0x4fa17cb614ccf45aL,0x575680e945f03568L } }, + /* 3 << 364 */ + { { 0x0f4ca7803374f910L,0x5948ae98fedc5b5bL,0x4873625b4ef805afL, + 0xbddba22fc015c586L,0x7091b50aa41a8c93L,0x721dd3384c005f42L }, + { 0xf43d37462065f41dL,0xd16bae3e172512b3L,0x3efca10c8277068fL, + 0xd0c25d7b77513f00L,0xc0015cc12dc3af9bL,0xdf11a4ec94c6cadaL } }, + /* 4 << 364 */ + { { 0x8b70e94f8f458c68L,0x292726544160ecc7L,0xe22219ba4d3ef22fL, + 0x7f8a712a1999f948L,0x25575e96abfe7302L,0x21c6ffc6564a1af0L }, + { 0x045e9c667e8500daL,0xef7c3cf704ef8ea6L,0xdd23b825c3db161aL, + 0x05fb173aba33a906L,0x9a8b5ecb870e41f2L,0xf3d9db0bccc30d1dL } }, + /* 5 << 364 */ + { { 0xbed7d94ca1bf2c8cL,0xbb7f437cb8b719ddL,0x65416af6106834bfL, + 0xdade8a144c4f7448L,0x62227a1d881dfc06L,0x37bc7de58dc2b7bcL }, + { 0x4f11541712ce030bL,0x72439d8ac2a9e0d6L,0x98cc53aba0f1b961L, + 0x2f68011d48b0ec8eL,0x4bbc34679c72d034L,0x0320c1469c576e38L } }, + /* 6 << 364 */ + { { 0xd9243926e873ff0fL,0x2e2a5ab6f20b0e49L,0xa1bcfeee0e35f201L, + 0xd25be5f3196f23f3L,0x298c67f2ffc1d068L,0x77dae55c0c3d950bL }, + { 0x5e15ab998822c996L,0x52de2e6d83f60a98L,0xa9f82ec947a7e269L, + 0xf02af9a22ac22e49L,0xdfb3103fa706f090L,0x125599623cf8dcb0L } }, + /* 7 << 364 */ + { { 0x9f5f44fa666e278fL,0x53c88803f5582c78L,0xd7e8f258f9627f9cL, + 0x22499dc938fd51bdL,0xa9d7497c846a4a79L,0x791b8ead026ae250L }, + { 0x84d47d19db15ff63L,0xb58a82c0267b44b5L,0x9b2f138806a52e30L, + 0x3fc8da027f08953fL,0x22d074d292fcac08L,0xb9c7c3db701d73fcL } }, + /* 8 << 364 */ + { { 0xb7b8562588ad12b2L,0x81f5958b1e44b254L,0xb4ebddd5c91b8ffdL, + 0xef815ae155d38511L,0x98587d551b0da525L,0x1d41817734a9ebbdL }, + { 0x844811fb1e6057d7L,0x0c16977176e5976dL,0x4b268bb4f623789bL, + 0xb26ae5be40498058L,0xb47a5ded3c2b435aL,0xe15a684b8fceceb3L } }, + /* 9 << 364 */ + { { 0xd55407583353db48L,0x0e334ccac0c0b5e9L,0x679a935f270c48d3L, + 0x170693e436ef0e90L,0xc72fb12f9de59023L,0xaae13a0e9371697cL }, + { 0xe98ed704d8d56e4dL,0xc6de5384eb71f091L,0xba63adccc6d905a8L, + 0xc84e614d66e40dd4L,0x15dcf1a3fa0f55e3L,0x4e26ee3af157c7a1L } }, + /* 10 << 364 */ + { { 0x122a3eedd09dc3c8L,0x6a19907faefe0819L,0x057aafa1da325339L, + 0x138033bdd42a5345L,0x8ac206af1a065ebeL,0x0a46f5ae25c31ed6L }, + { 0x7fc577a9d7e379dbL,0xc6df694369dcee54L,0x4c167ba2a8336bc1L, + 0x0fbd9708f3a1339cL,0xc6b8c01f226f612fL,0x5d4ed789d51332e1L } }, + /* 11 << 364 */ + { { 0x67ead4e0f6a40814L,0x42fe051ca2ec9ae1L,0xc09f84395eba62cdL, + 0x7bb5ba0c9d8e7305L,0x85962d0db46f81abL,0xc7183752628b18ebL }, + { 0x7a1f023edf58ec0cL,0xf21bfdbaab6535dfL,0x12add590801d2481L, + 0x1fccd1e37a11520aL,0xf83caddd6fa8f8e2L,0x99e7256c24e58433L } }, + /* 12 << 364 */ + { { 0x26aa2c2e5a1abcd8L,0x2b16a12e9609d9d8L,0xe485a551a2bee00cL, + 0xfa28c30bf4f2292eL,0x99abef78b7358f1bL,0xda6b3cdf10a276a1L }, + { 0xbd3858b747c03f71L,0x4f0bf5f0b22d05d1L,0x2d80f5d28250f760L, + 0x060f9b278cd9666cL,0x6a6c40b0b1b014a9L,0x44537af38c440a9eL } }, + /* 13 << 364 */ + { { 0xce1c070a2275263dL,0x2723b3d149cea971L,0xedca02f5817001b6L, + 0x5c160e9349c946e4L,0x273b4952458a5265L,0xc7bcd7c610385173L }, + { 0x22cddfd17fb08b14L,0x959d5dfe10f73d01L,0x900f5f348e387351L, + 0x6d7381dfdadb8695L,0x8dff2b193aeafba6L,0xe4a8d6bd8adadc36L } }, + /* 14 << 364 */ + { { 0xb564cfd676faaca5L,0x8a6e3925920dd223L,0xee59a140a590a383L, + 0x9e29b552a1922ad9L,0x604367de60a0da63L,0xc498aca592c35fd0L }, + { 0x74135082250ed8a0L,0x5d109d1a6c7c3e77L,0xf9e2d84dc63dff94L, + 0xca50f5e4f7aa2b0eL,0x7cba9e87d543d389L,0xaf5fbbefd8fd1292L } }, + /* 15 << 364 */ + { { 0x3163e2e895bcc345L,0x4ceaaf2d80d9a931L,0x4d2dc44b2f621612L, + 0x2a5f60b86cc8ffd0L,0xf49038cf7e8c9434L,0xb580b8c508015b8fL }, + { 0x4283ec01d52af80bL,0xac9dc35f99076245L,0x38785f7bd64c3dd8L, + 0xca19c17623bf8915L,0xd778291370478260L,0xc1e48e6816e34149L } }, + /* 16 << 364 */ + { { 0x707656834fc11c3aL,0x53a9403166aac4d1L,0x2a935ef0a6db6169L, + 0x002927612032d599L,0xb5babb2d3a6f1316L,0x601a7dfadb26af51L }, + { 0x00c340131322d983L,0x45b062ec2bb507c5L,0xa1bbe2ed0f9b3656L, + 0xe17a5d4934031d18L,0xe3661047f8fe1224L,0x0e4f3b3d623c6cf5L } }, + /* 17 << 364 */ + { { 0xb335d83c7c3b8c3cL,0x01eb94f059359a67L,0x3a8359a6aef3ffa0L, + 0xb0270076ecd2d862L,0xc946b1610377e30eL,0x9a5506c282bd6ae1L }, + { 0x737bdad0218512dbL,0x449238633487fb13L,0x36026dd12a8e7907L, + 0xb67bdc80784811eeL,0x9f92cc2405c90646L,0x02c551554c370746L } }, + /* 18 << 364 */ + { { 0xffaac084ca45cccfL,0xaea5cc3d061ffe3cL,0x7c5d7c60b355f387L, + 0x4bbb2a0c99cba92dL,0x6b4ba3ef2f7768d6L,0xc7484ed2cc5f9c40L }, + { 0x5d4e92fc52b57a7eL,0xba9f16c4ca2c200bL,0xebe02a8a3797ccbaL, + 0xb6b3f42138c4133aL,0xad5d85b68153d033L,0x782d6ee85714f269L } }, + /* 19 << 364 */ + { { 0x4654991087f226ccL,0x97894d5fc7bfffcbL,0x94f67786b3cabb83L, + 0xa6abaa960d788dc4L,0x08ae72d61723738dL,0x5003f41d86704dfeL }, + { 0x67687c3d40fb0a3cL,0x6fdc98c9b43320aeL,0x0f22572fdeb08964L, + 0x05bb02a4c8002624L,0x4c5adb7f987c2991L,0x3f1c6dddef4e60cdL } }, + /* 20 << 364 */ + { { 0x7845b6969c0cf752L,0xb82d052b5a732acfL,0x7760564c1262877bL, + 0x29b3c57a8ecc7aa5L,0xb58eccb0df1ebbedL,0x86fc15443c3a3303L }, + { 0x44761ddf13060f0eL,0x5a3dacfd7371a5a8L,0x846f6faaf7cbc2bcL, + 0xf5e098b0368caabfL,0xe23ea10710c08769L,0xbc5df1db1563fcdaL } }, + /* 21 << 364 */ + { { 0x75647f6476638edbL,0xb76ceb04aad6e25bL,0x33c73367d9393a41L, + 0x8396726dc55f0feeL,0xe1cbd48e751b3d43L,0xb779c5bdf47141a3L }, + { 0x122b85434eab6097L,0xeabacf45e08c6fa4L,0xdb32eab7769f49cfL, + 0xf956976a04ac2cb4L,0xf55c6fcb5ea8e71aL,0xd72940dfbad47ea9L } }, + /* 22 << 364 */ + { { 0x65c3a54e142d8955L,0x5c6583cce7814f25L,0xbd5a07d8d924dc7dL, + 0x9f717bd9c28f6e8eL,0xa0c4ec4e3b6540a7L,0x3153bb2b142b3283L }, + { 0x53bf403c9b296946L,0x659a828ab1cdb6d2L,0xe9517d811369af19L, + 0xd8c7a0998990e7a0L,0xbaa9f59de535cd04L,0xbb0cc68e0f269551L } }, + /* 23 << 364 */ + { { 0x2b4a0e69d0cd5fc2L,0xeb8dd25981167a94L,0x356198ae61b73503L, + 0xb159ca12e5289d45L,0x99d71c97991765b5L,0xce3a3b6c198e10b0L }, + { 0xcf6ee0bcafbb512eL,0x4aadd1381e19b49aL,0xcf6a9cf3b4806f0aL, + 0x6aff0386ad688bb4L,0xea487c6e4f2e5065L,0xec200f4b56573b51L } }, + /* 24 << 364 */ + { { 0x3c00ac526a78c6e5L,0x9c61aca6defaa52cL,0x0034128939794a09L, + 0xe08910d141cd7c0aL,0xa58ffbb6a732e3bcL,0x87bf51ab91fe8fd8L }, + { 0xc4f4f2674a59e2beL,0xdeb512c7438071c8L,0xddf82842e9cd290bL, + 0x3e17311d6ae85fe0L,0x6e9236a9b41be881L,0xbb9ddf9853555ebfL } }, + /* 25 << 364 */ + { { 0x07d2df1162bb0e3aL,0xe74ce211ce469affL,0x9629d7d4756b5a83L, + 0x61d2a633aefd449eL,0xd39a6afe491e503bL,0x0f1568d14d2b2ed7L }, + { 0x8216304cd19611bbL,0x6df99bbeb27388daL,0x2b0f60c0b7a3b4beL, + 0xcff84c1c7dadf840L,0x470201e28a9f8a49L,0xcda3693c21afc717L } }, + /* 26 << 364 */ + { { 0xccc163ea09f3f0beL,0x9932b56f6a5b0a63L,0xf89fae919c69668eL, + 0x555f98215ce13021L,0x4b02693f37037aa9L,0xc4afee79bde50f35L }, + { 0x4b0919c202aa6c7aL,0x3166de2a991e15e9L,0x284baa3e7077fb38L, + 0xbb7a6416a116ddecL,0xe8c89547b7636772L,0xff9403620ef92c54L } }, + /* 27 << 364 */ + { { 0xcd183e8bd3ea4c3cL,0xc8ce2f2154b7ac32L,0x75387e04be960826L, + 0xaf878400f2e39f5dL,0x7fcefcd94fa628f7L,0x76eb621c34582cbbL }, + { 0x44e1f848f29d2496L,0x42aa36174ab4eb21L,0x43cead840c08b50aL, + 0xfa4ecf60dd44f7c2L,0x5ac9ffd59f817546L,0xec11567eabcc594dL } }, + /* 28 << 364 */ + { { 0xd5d81275e2ce6008L,0xc45bdf250b3b9d10L,0x15ab5da36cbc83e2L, + 0x85a18cf8c52a66cbL,0x77e202b8b042c047L,0xc4dc3de2e7e7997eL }, + { 0xfe9335b1995fa67aL,0x809e161d75b96a00L,0xfb03c2a5a0c3baeaL, + 0x5c7e0523888c2f77L,0xa8fda1c887ad10e2L,0x90484f78858a3577L } }, + /* 29 << 364 */ + { { 0xefc5aa2681bf26c9L,0xdbe91f606bf105bcL,0x0d70c4d4369dd3aaL, + 0x2b357b847af9bf66L,0x4293e9a01f27f163L,0xc846f67cb3eaeddeL }, + { 0x4556bb787da305dfL,0x4ecebf83a5a26bf9L,0x8e05af924c1bc430L, + 0x4f3bdaba70f80402L,0xccaccfd3cf204577L,0x8fdee135a0c42d1aL } }, + /* 30 << 364 */ + { { 0x49e41f0af9fde126L,0xec9600443613d3c2L,0x2c62a49d10421d3bL, + 0xe24024648131a0d8L,0x8a7ce188bdf794fcL,0x704dea7d4665b1b6L }, + { 0xbdb9c18e4d57c6baL,0x5288a053f669b3c0L,0xbf7d01b878a5e252L, + 0xb26cccf926b9cb7dL,0x14191a3284326c47L,0x460ff74791f8425bL } }, + /* 31 << 364 */ + { { 0xb9958c5397698b9bL,0xe1f74292c27f96ffL,0x172b0d50806da6bfL, + 0xaf3d889ddd38b97eL,0xe7a75ea409c688daL,0x1f0951b85c631b2aL }, + { 0xdad8b2adda1c111eL,0xbacb9cc832813338L,0x30b8336b10582abaL, + 0x0ff3d7549494e71cL,0x8d99be5cd663ed6dL,0x8eb412cf7073a941L } }, + /* 32 << 364 */ + { { 0x59367582bd27be7bL,0x92bf5bbc1ab2c596L,0x5d96351af6a27741L, + 0xeab94db87f929e0dL,0x865ba011043f1afbL,0x43acea125fb631ddL }, + { 0x192e0652b2fd1436L,0x44f22ff17b38d121L,0x7bcc228db7cae5f6L, + 0x02eaeccd6a828b03L,0x7c48a2ea91f301aaL,0x1e090717f5eb1a07L } }, + /* 33 << 364 */ + { { 0x4c7f41b4609c6818L,0x978c2a561c82b3c4L,0x68404f1d7f6ba836L, + 0x91e056d0c863aa7cL,0x0b24599ba2261804L,0x16e9060dcdd7596fL }, + { 0x42aa49434eff004eL,0xb99408690438f1e4L,0x28299e8581775712L, + 0x498998eb83be6877L,0x84273d9e91328a67L,0xb7e9076e9a87bc8cL } }, + /* 34 << 364 */ + { { 0xe8d204865e5aea08L,0xaa946076addc7ba0L,0xc0153a9bb6a5cabdL, + 0x622271bd4fbe43e0L,0x44de159cbd62e5cfL,0xefca41112b9b63f8L }, + { 0x30774d3cf5269928L,0x4fbb7ff84ac0c8b6L,0xe0611f1f8839106aL, + 0x5d4121204ffa4a64L,0x9552c123e86251c0L,0x57d029680efbdb14L } }, + /* 35 << 364 */ + { { 0xdf3f8e06d7aeacd2L,0x725b25fe4d0e7af3L,0x1794f0da5c17392dL, + 0xabc807dac977ff46L,0xd90e6c8f0d5ca66fL,0xaf8eb526c2d26d49L }, + { 0x4661962e8a8efa37L,0x2a2cbeade87ad53aL,0xa57d34b1ce3ff40fL, + 0x1190437dc6aa3067L,0x92c31e779db66b47L,0x86a8ee0f8e8a70d4L } }, + /* 36 << 364 */ + { { 0x7b65bb14de97229eL,0xad6e3fee4c6d35b8L,0xfcbbf6afbee3f5d8L, + 0xb51549ca4a438fe3L,0xe66e615d437d531dL,0x9ee793eabf168624L }, + { 0x796789b0f8878a84L,0x3d38950dd32ec2ecL,0x74c37196a638d45bL, + 0x35d318327aeedaf0L,0x082c44f046a001e5L,0x93fae5cf89886220L } }, + /* 37 << 364 */ + { { 0x8e585fea499b635cL,0x60afcb3566781e83L,0x06594d9267482257L, + 0xb9f6101128773448L,0xba9ef7102817fd2aL,0x494e05b2aad046c8L }, + { 0x65d804fc1614e265L,0x1b0884c6d97fe002L,0xd7d34f60875bcc2dL, + 0xf34725444b440852L,0x49386bfb95591325L,0xe3966f4ccf68a142L } }, + /* 38 << 364 */ + { { 0xa5f3bc6cea06320dL,0x1bf855c637ad6e7eL,0xce7ff06ec58befadL, + 0xcf0d22cf1c2c0478L,0xf53e473e75616621L,0x00539f8700829986L }, + { 0x45398355844866d3L,0xbade46a2d710bc63L,0x6b3da567d4e2641fL, + 0xff70185978fd963cL,0x2eefaabaa5bc18a6L,0x61eeca92eb64cd49L } }, + /* 39 << 364 */ + { { 0xdf7c7c0b4cd4c82fL,0x67a26a97188ab9dcL,0x58c5bd74dd189cebL, + 0x3e1e93a9bb6409f2L,0x0d18a8bca6bb744bL,0xad3eafb45328dcf0L }, + { 0xacd15db5e311dfe8L,0x13a1c10ac1e849bdL,0xfaaa7227e1e73aa5L, + 0xa4cd2400e33d4665L,0xb9be68d9d6d527b4L,0xfe282bc05efbfc40L } }, + /* 40 << 364 */ + { { 0x159b38e17f8fd522L,0xf3ea27b5755e2bd8L,0xfaa52efebf11ac90L, + 0xc2014b892cb9f6dfL,0xa711c179d8baa5d6L,0x5474c1ceb22c2f27L }, + { 0x3cbc74cb031d05d9L,0xddd97ca6c44e469aL,0x21b386a647db83e5L, + 0xd1431c7b7abc0595L,0xbc05d009a416a325L,0x1c29eb709da53e92L } }, + /* 41 << 364 */ + { { 0x7f1aaf98181ce8a0L,0xa890cd3b6caa5b6cL,0x5d78dfaa5fbeac66L, + 0x36c63cef3d3d4594L,0x6f89ac3ec36d117aL,0xce9095640fc90e27L }, + { 0xaa356b1ac127aa76L,0xfa42cc119d181455L,0xbe4622fcd27f5ab7L, + 0x58d924542c3d54f7L,0x78a84f6b07e93c24L,0x5bf7cd278bce9a46L } }, + /* 42 << 364 */ + { { 0x4bde9ce5f810db3bL,0xec4a74b7281552edL,0xf5b4fa5fee085bb0L, + 0xb07a62936192c8b2L,0x163ff0d1fb18d219L,0x8d4b5e1d8e0ce753L }, + { 0xbfa6211baebcbf50L,0x1ed6d4b4fecc19eeL,0xbf6d514b82393e94L, + 0x90b356c1711e7d6fL,0x87b28dc2f975139bL,0xc41900648d8bebe9L } }, + /* 43 << 364 */ + { { 0x3468af53e8d49368L,0xa0a07369ff825262L,0xfad134fd662958f7L, + 0x5be79c00ce900822L,0x4909a56c44bde5abL,0xc2e8c4df4862e335L }, + { 0xd5e9b9386e7e41f5L,0xd3828d424fe474afL,0x058b2723cef44adaL, + 0xc74ac74617eebe66L,0xc3e6e014bca4416cL,0x2e30bc88167c2e86L } }, + /* 44 << 364 */ + { { 0x68211ba4969c2c58L,0x7a34733977f218e4L,0x0237eb3696ea1d64L, + 0xdc97f94b7416f3caL,0x63aa82e476bf9e52L,0x4b88a32d388465baL }, + { 0x7322d9f44adc7579L,0x70c01c7fb24d28f6L,0xdf7f4213c7517ecaL, + 0x42c027f0a8db6d56L,0x2708360eb6c2f8baL,0xf20690d1c2dde09eL } }, + /* 45 << 364 */ + { { 0xf139c3e3bc6158ceL,0x19207b6a4c86b780L,0x55af3eb977c036b1L, + 0xd192686abd563ebdL,0x8bd0afb05550266dL,0xaaa7376d83bf81bfL }, + { 0x26aa74ae4a114541L,0xd92549dfbb6745ecL,0x6ad6a14ec6bbfbd0L, + 0x63fee75b411771f3L,0x111ae3101938e8b5L,0xce3e5e346c363756L } }, + /* 46 << 364 */ + { { 0x2a53c88ae0a45b56L,0x26367466da72228fL,0xdd65516edfdbb135L, + 0x5fe254e82d7e37bfL,0xc0f5cbe433ef39e3L,0x249b7e3ece85effeL }, + { 0x85951a5391ffba8aL,0x41117672c8dd5ec6L,0x7a74538d9dbb0761L, + 0x0b35fba0cfb06ddcL,0x8c36be4d1a0aca2aL,0xbf884a8e45848e1dL } }, + /* 47 << 364 */ + { { 0x191eef31788596c8L,0xa7413be65a2d0ef8L,0x30894fcc5c3c09e1L, + 0x6b0e429b2f72a333L,0xceea52a1e70470e2L,0xfc638b316b682db2L }, + { 0x31af73cd615f7f21L,0xb31663760094996eL,0x7ec37e33dfff756dL, + 0x38c50101d9b63a4cL,0xa517c6df192f18e4L,0xd674c53a841fb337L } }, + /* 48 << 364 */ + { { 0x4dd3bd842446fc6aL,0x4654b82ef25ab510L,0x1ad46998ba066896L, + 0xb7c679acad713bbdL,0xef9389aff7ca4fa5L,0x1b864105d68b6a1cL }, + { 0x3acfff604b6f5ea4L,0x81ef58f7b9e5a475L,0x5e2f6441c66ad734L, + 0x49f144c42fd3eb16L,0xbd7f22082e4e2117L,0x30865994417911a3L } }, + /* 49 << 364 */ + { { 0xc2f25d9e80d2adb5L,0xa0e77dc5242430feL,0x7f30e54b4f504e97L, + 0xdc114db4680ca2cbL,0xf76fae57adec4d89L,0x06f892eff313535fL }, + { 0x50af729a9a266407L,0xb0cbc4f0764dffd1L,0x153ff8f8d20c2e19L, + 0x27fa845a7388d22fL,0x26e08ef5d784e057L,0xccbe49ee53b5dfc0L } }, + /* 50 << 364 */ + { { 0x6fa8e5ff3082ceb5L,0x81f4dd02ef4850ccL,0x626b324456483f9aL, + 0xc0acbd8782e65652L,0xf9bef3117e23f93eL,0xc2474777c2310f6fL }, + { 0x6b4617704379fd64L,0x2f8fc599f18c3b14L,0x2287f1d0bd076aedL, + 0x9f8eac0fef366016L,0x517cd2e371fd845dL,0x0fc2f219a30c371dL } }, + /* 51 << 364 */ + { { 0xfea0464721c56ce8L,0x4f7b055b6a32a26bL,0xf8c8d93e487ed396L, + 0xe620b440855f4df9L,0xa3f6f21dea870c14L,0x0518225207dad127L }, + { 0xbdfb7b12c68ab5f6L,0x5f58bdd7fc68f296L,0x2df9cfc505e4fdc2L, + 0xed12a102379c282cL,0xd388362654d8de77L,0xaefb0f7fb01065afL } }, + /* 52 << 364 */ + { { 0xdc64f8d23d80d738L,0x7ae74ab1d95a1c6dL,0x4dba93a8dd46de0dL, + 0x271aeb870fddbd1dL,0x1bab6546e9e7ed31L,0xe6445d22efec8f37L }, + { 0xd927df1797a718a7L,0x738c2450351b1ceaL,0x3809e595d51a7422L, + 0x4f8d5ea58969456cL,0x74d9168421c9ad95L,0x59a69f8f4f796a11L } }, + /* 53 << 364 */ + { { 0x2542fcf1f07717aaL,0x032abb3f405a7717L,0xc757e6e294cade8cL, + 0xad4776adf2e84dd1L,0xb7e277243d5e397bL,0x173894a605f8921cL }, + { 0x0e3a78531f6afc3fL,0xf33732b8ad62482fL,0xa6b4e0f03e4cb6e9L, + 0x51ba565eda02264aL,0xd0afaa4600f3f376L,0xf5506a1e35252e93L } }, + /* 54 << 364 */ + { { 0x3574783b5ea1c662L,0x675894e514fadc8dL,0x64dd63935ac6ea7fL, + 0xa76c00dc77f16c96L,0xf73ef2c62eb9574cL,0xdd39a89a2e408008L }, + { 0xbef8c8c72bafa10bL,0xa31f030a074733f8L,0x5620dda5445b4b6dL, + 0x4e08fb0173040ab8L,0x0a279f38598ad48aL,0x03e8b55e2d40d775L } }, + /* 55 << 364 */ + { { 0xf49d4d54c20c8610L,0x1b1d70bbc0d62b65L,0x524d3a0c16285ce2L, + 0x0be553b08a0785b4L,0x9b93e5093c84975aL,0xbeac761160769465L }, + { 0xffaaffcb3331dd0aL,0xad0f01542d70fcf1L,0x65aaabab66fe24bcL, + 0x283edb562cab253eL,0x1659deca80383c87L,0x06de45fd83fc6d7cL } }, + /* 56 << 364 */ + { { 0x7bcb055d5f76c311L,0xdb2d05878e293aaaL,0xb15036e7207360b4L, + 0xbc38cc9f163f0ae4L,0x5a942f85a44d0a0eL,0xee8633a23f553a88L }, + { 0xf66b65c5c9bd4ee7L,0x7a4ca96a80b8ceefL,0x7b71cc55f6f08036L, + 0xc0408b198c41be7cL,0x885fd72f80860d93L,0x338a567be7f68b7bL } }, + /* 57 << 364 */ + { { 0xcba302e939d99b60L,0x2557b3d903b8faa0L,0x2a99cd6e9efc4461L, + 0x03ce3e08268f14a3L,0x59226a83b1c68a01L,0x81a18c69fe379976L }, + { 0xfdfc9f148af62557L,0x0cdf327140b2d4ebL,0xf99ff3ded26c6085L, + 0x2c138ffdf9b0273cL,0x393d6de6888dfbd3L,0x75903c68e5cc102bL } }, + /* 58 << 364 */ + { { 0x0c56d477b78a7b91L,0xbedff933c7c3ecf4L,0xe02da64223ead65aL, + 0xf7e7cc19a8162300L,0x3719fb8f2f3dbd03L,0x4f150cb8cff88c59L }, + { 0xa564c5eda7fcb233L,0x9b042870b6a41ca7L,0xf253b65ac1615f1aL, + 0x9ccb49a7b8aaff46L,0x38bbc5f7af0086fdL,0x688f7c2054a6d8a9L } }, + /* 59 << 364 */ + { { 0x3702c5e5d22a0892L,0xf17510a28d510809L,0x5c36dc68bfdab4e7L, + 0xf72c9357623a98e4L,0xc660fc5146624a0cL,0xf0b4983d3e64dd4cL }, + { 0x5cb98cc9a5ecf45eL,0x79759acdf5082a78L,0xfd0daf366e7321dfL, + 0xf61c54f7f1ebcacaL,0x782e5e74b8f665c4L,0xb1d54c2145d78c08L } }, + /* 60 << 364 */ + { { 0xb64f3b9bef1af123L,0xc86dc5ffe1b75401L,0xc3a76d81d928e989L, + 0x075005abff8ca002L,0xca6226325c3cd8b1L,0x017a97b2bd8f772aL }, + { 0x187eb635039c4757L,0x9eb7a9d1e905c6e5L,0xdacb98bfbc251cceL, + 0xe357c60e8704c639L,0x50563b8558fd987aL,0xb2f89c864cea5d4bL } }, + /* 61 << 364 */ + { { 0x3d13c0bfd32233faL,0x997c424145aceb7cL,0x77ff5a75ed2e9df0L, + 0xc4279aa23c91d085L,0x5a11a276ca0392c7L,0x928e06032daae653L }, + { 0x21fe225fc4046f85L,0x591fa82f512dbfb4L,0xb5b01a3f51aa53feL, + 0x900012ef7133befbL,0x24609da17130c15dL,0x3c4a09b33d2549faL } }, + /* 62 << 364 */ + { { 0xcdd3073d3ceabe32L,0x56e155bc5a848977L,0x07f4c7c6da48eef6L, + 0x00a2f9f79e021b38L,0xeb683e17ffc4bd6bL,0xa7d6b87592b7e240L }, + { 0x651d21de7e48836eL,0xf9c9ede775de3c75L,0x72cea748d90f2634L, + 0x29d8022283fc524aL,0x1e412b510dd044faL,0x1b9b332a76a04fdfL } }, + /* 63 << 364 */ + { { 0x4dc8421f06f49d8cL,0x6a3fd9a83f979e4cL,0x50b0e3760b51bd69L, + 0xec22f486a592313eL,0x5e4663ff8e8904d4L,0xde7b9e23f3362548L }, + { 0xa1ad270d1ab757abL,0xb91fd935a3089f6aL,0x1d6b1524a635f996L, + 0x8673f8e29c718c6dL,0x0e04360725932b9fL,0xb5d0447222ac239fL } }, + /* 64 << 364 */ + { { 0xdf0ae8df941948e3L,0x123fee901d010bcdL,0xde3717ca1dd28691L, + 0x0c1db879709b678eL,0x0288959a400acdc6L,0x66c691815ca2d03aL }, + { 0xe52534b3dbbb75deL,0xe914938c3de927cfL,0x1a9a34f873eece30L, + 0x0fb0c7bd642a6799L,0x375cc0cfeaa7e8a8L,0x75fb9eb5d00ec238L } }, + /* 0 << 371 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 371 */ + { { 0x9ca8cc9db72958ebL,0x3c8cd0db1014f562L,0x72115d53059b2bbaL, + 0x8fe7ac30730e5dc3L,0x4e67ef69841d8998L,0xfb6439ffc8ed37a5L }, + { 0x48164b3e26df84c4L,0x37d492ad365bc99eL,0xb7fd4643beed38ceL, + 0x993cfa9fa3e30b3dL,0xdcc5e7af01ddd484L,0x5edf3ac06840175dL } }, + /* 2 << 371 */ + { { 0x79768e9f51d33c11L,0xeec34505a4b24889L,0xc194821bbe0c67d7L, + 0x537a6a4a6909fdfcL,0xae6d705195ccdda7L,0xed4b722292b3926cL }, + { 0x2c5dd6af6b24a3d4L,0x9282ec39e4386095L,0xdd3c7388397a3bd3L, + 0x9d176c6a8baf59c2L,0xd5c6219e380ec958L,0x194fc11654e8e315L } }, + /* 3 << 371 */ + { { 0x0b7576f901ec1432L,0x84b30eecabc5f603L,0xdaaf7ba9f4a84b7aL, + 0x9e3a5daa3bb37a99L,0x56bd964880378cffL,0x2fdeeeb78e6ed856L }, + { 0x079014a73c81ac34L,0xf8de4004b4211c27L,0x0cee3df97fe4391eL, + 0x441aa7fb2fd2fc38L,0xeba7be864d1b575aL,0xca2fb5b7231c2d01L } }, + /* 4 << 371 */ + { { 0x0683349e463a8251L,0x97dc4f475103e72cL,0x47c7181050663b9eL, + 0xf327d1499733dac6L,0x03f55e4a292137c5L,0xccc6232ada59e1c7L }, + { 0xbaa8b4ddadc59cb8L,0x45370d35fe7486e4L,0x99a88c1db0322df9L, + 0x394440a7fd69954fL,0x9060473da5a29889L,0xc8ca43e32f04864aL } }, + /* 5 << 371 */ + { { 0xd5c7241add8b9644L,0x45a5f2d1993116d2L,0xbacacd4a823048dfL, + 0xa278fa042568547aL,0x3a4f2482bff72820L,0x1305d1a713e4314aL }, + { 0x9d84c33334ba28e3L,0x9995b5bb6a32fb41L,0xb0f75f3c520946d8L, + 0xd7c4b8b7de98aa63L,0xee5efcf3ba856b6bL,0x36af33683324ed66L } }, + /* 6 << 371 */ + { { 0x90762c1f5827fe2cL,0x20160f7aeaffda88L,0x7420849f5c47c645L, + 0xb08231956d72e748L,0xaeac683b8ee11773L,0x8c2a0a79fb5c550eL }, + { 0x6d986d696c07cc1eL,0x57269140ba8398b9L,0xd13e136fd94d5223L, + 0x1aa75419ed5b01c6L,0x7c2014b1408fcdccL,0x0680a985cffde5eeL } }, + /* 7 << 371 */ + { { 0x92fc9a3342c5a7eeL,0x8768614af9f0ed71L,0x1ea5f7ed87ebfb66L, + 0x296852ded361069cL,0x1cec6f1a0192498eL,0xbfd4858fa9cca3aaL }, + { 0xfba98c242ef240e8L,0xc8b500e4ab635d9fL,0x9f49c572913a3eddL, + 0xe6181f93d42b2d4dL,0xf96b5db26aa77fa3L,0xdfb2241fe43558d8L } }, + /* 8 << 371 */ + { { 0xc7d0abb2edee15a5L,0x72dc0105228cc4a1L,0xeb67defca80767deL, + 0x6fa174d871820908L,0x3215df485674d19aL,0xf944531a960a081aL }, + { 0x93ed7180ef2cce62L,0xb318edbfc8bcfc0dL,0x0909d56efe787e58L, + 0x5ae74fc98fe8b96fL,0x8fc342c435ab6811L,0x6fc6cc5c0b991e0cL } }, + /* 9 << 371 */ + { { 0xa8eaba6e291f689dL,0xfbfa9a2cdea0cba9L,0x5b1b4a21727bfa11L, + 0x3b69505fac59c8c4L,0xb06290c89368ddb2L,0x4181abc294bcc14aL }, + { 0xa19f65813e29d997L,0xab1ae8408864aac2L,0xb04a24300fcc9ae8L, + 0x3ca2428e1059e4dbL,0xe288731117e1e01dL,0x1f5d4164be56238fL } }, + /* 10 << 371 */ + { { 0xc600dd57354416d9L,0x6f5840991f829d6bL,0x2d7b0a27de43c1d6L, + 0x21bf3a9e616bdb16L,0x33ce767c96297953L,0x99bf97b69e4398b2L }, + { 0x4069cced8d441287L,0x52e0edd6bf01017dL,0x9981bf89c5394236L, + 0x07d9c079acb24e38L,0xd2e5e904a2da4735L,0x4c3c12162f1b6cd9L } }, + /* 11 << 371 */ + { { 0x1f28bd0de6f1c85cL,0x4a49d0864e6f3db6L,0xc9a8e70c4ef7d981L, + 0xde8abcf2682bc68eL,0xd0ef89a4a66cbee3L,0xfa03108432df7f0fL }, + { 0xe361e0f803594856L,0x1f423bafc985c77fL,0x50397b67010ee4acL, + 0x502f4a20c0a48e96L,0x260bed875435539eL,0xdae03cefa0391250L } }, + /* 12 << 371 */ + { { 0xfeecc6e83be5ba68L,0x3293dbda40445158L,0x48454e20e81879caL, + 0xd0ea9cb89c4a2712L,0xba8b6f33540749c3L,0x95e6d6e3e971df93L }, + { 0x4c2a1b13478a2eb5L,0x8b5f9af330b92170L,0xe6c60b5343573986L, + 0xb9f56a6a57040c00L,0x6de6489f6291a7b4L,0xa9a7784653bc3246L } }, + /* 13 << 371 */ + { { 0x0dd4172f9025411fL,0x978e952ac6129de8L,0x9afa974bc7ab7609L, + 0x7bd29a644e42f223L,0xc0232f5f3deb639bL,0xacce69d05f39a264L }, + { 0xdaee07cb3070b24cL,0xe3adc8556b532246L,0xae5935ce1e6ee4f6L, + 0xba9c4329ea018a45L,0xa1a4002e6b97ee9dL,0x98390aab8a9460cbL } }, + /* 14 << 371 */ + { { 0x828a9dbe67154a02L,0x57a3af981866aadfL,0x1558428089faa581L, + 0x2da092202dba2a1dL,0xa225f631df197ae6L,0x0abff5cf8f4ebabbL }, + { 0xbbadc9b3b98e5e4eL,0x7c7cc36e4509f98fL,0x072a6cc2759413f6L, + 0x7b39ea4121dd1222L,0xd6baf9e196ac2c73L,0xee38818c75d46296L } }, + /* 15 << 371 */ + { { 0x19befeacfa37c53fL,0x32c29b361f95c29aL,0x1d282db40d5aeafdL, + 0x8812b6c8f102a97eL,0x1cd4a23c8402f481L,0xbfdf7b6b8eddec81L }, + { 0xc8039ae0616b2654L,0xdc6f38acabd23a57L,0x2431c763f147dd44L, + 0x7c45ed50d795bc37L,0xdbc30ab9842022aeL,0x568f7d4ba1f05a43L } }, + /* 16 << 371 */ + { { 0x55671129542f4e90L,0x43bedccf0623d4cdL,0x7e21207ce99ca16bL, + 0x785fa1057c7a26b9L,0x33c28658c2c3ab00L,0xcce42a48d79cd59fL }, + { 0x9a674db4b8c3bc75L,0xea701d156904e3feL,0x990e722166bf2c6cL, + 0xba29affabd4c3791L,0xd98510cf20696ee1L,0x722ed471f93d26a5L } }, + /* 17 << 371 */ + { { 0x74e6c2624ba40f04L,0xf7ad1f159a63b3c2L,0xa89e8490ef75d482L, + 0xaf8e79b83bb5f5c4L,0xb094f8660c624d8aL,0xb571ce6613c69a60L }, + { 0xcbf9722d53787457L,0x97e24cf5c15d097fL,0xdba98bede99e034bL, + 0x8b6c171a57773590L,0x5d2b441cfe822efbL,0xb8c6dc57fc74ef1aL } }, + /* 18 << 371 */ + { { 0x37c70bdf7db1c03fL,0xd9368612964632abL,0xcf6368d742530338L, + 0xe56beecbb1d9522eL,0xb1caaf16bb6fba3aL,0xb7bd485ac8384d26L }, + { 0x4ba13818528d4372L,0x95c469bab9c5e8f6L,0x4e5cef0c4a370695L, + 0xb87c97ca663f9b07L,0xa9e1b388e5f3b79aL,0xc0416bb84c845a1bL } }, + /* 19 << 371 */ + { { 0x4483db00e4634d8dL,0x4d8d623d0a268bd8L,0x296f179c64e6d10aL, + 0x048f3a1cb6c7ff95L,0x60f8ad62c60c76d1L,0xa0a497610d028845L }, + { 0x10128387aea1b714L,0x81e5c75ca18bd98cL,0xac30d7361dac4200L, + 0xb83c1c12821380f1L,0xc8ca7c6afaaeb726L,0x13fb870dfead4cfbL } }, + /* 20 << 371 */ + { { 0x3921332a6b393648L,0x49ec6df649584f38L,0xa0fc013dce243a6cL, + 0xde5b16b5f8da8a00L,0xabcd0c0471ab1c9aL,0xff6594bc78b83305L }, + { 0x3546004b76c1900bL,0x87428fa236fb3186L,0xd2e464ce59cdeb49L, + 0x1260bd28faf6ec08L,0x1ada2f08d0c9d098L,0xe0b66299dea06396L } }, + /* 21 << 371 */ + { { 0x603d58167c1212e8L,0x95bb823fa4590144L,0xf239058a4bc3ba48L, + 0x21f2aa610db724b3L,0x29c706e8cd6792a2L,0xb143a84a634f01e6L }, + { 0x68f37382626ee80eL,0x56daa0e51fcd8c4aL,0xe01b52b39e5299a5L, + 0x2224513c3accdac7L,0xbb21c7d74acd435fL,0x039bc010bbcb948aL } }, + /* 22 << 371 */ + { { 0x5006c3a00848d6b7L,0x726b8648b28285aeL,0x7162e3c0277c5a87L, + 0x567f7ab02019c20aL,0x490c858fa551d5efL,0x0029a108d134a2bbL }, + { 0xa9e19284ef0aca3cL,0xbc399dc16e414f83L,0x5bdf85f86efa5a8eL, + 0x5291e1a674fe7c5fL,0x249ddf2acd7091dfL,0x71d4cb4c2e29fcf6L } }, + /* 23 << 371 */ + { { 0xc374acf4c1ded13cL,0x300d96132b69132cL,0x909ce34b055622d2L, + 0x26f033f6bad97809L,0x30987ebed1f7a220L,0x23147226db775b8cL }, + { 0x8d45c2c28d05ecfdL,0xeee0c679f0c1b419L,0x9f7df70d8c380da2L, + 0x4d49f3d130212a25L,0xa9602e8c64491ff3L,0x5ab91d223a254c49L } }, + /* 24 << 371 */ + { { 0xedd3291c9dac47a9L,0x02d64634fb5d396dL,0x2ce21bf163264c51L, + 0x0fdcc68e092c4724L,0x653acb286e3e4c2fL,0x2f9c77f12f1fa1edL }, + { 0xd91d4c3aa58afea2L,0x5a91b2ba7b0d8092L,0xd47e0f61f10a15fdL, + 0x01652d86f9c86edeL,0x1cc1b668d6006daeL,0x2763e36d24af68beL } }, + /* 25 << 371 */ + { { 0xaa5f387c2314a1adL,0xb8c00105e2647c74L,0x1f950dd8d6719178L, + 0xb7dae31de79881efL,0xf2d49aa2e45a615eL,0xb22dc098f17352afL }, + { 0xa4c438728ac23ba4L,0xedd6e4092c55e588L,0x1956b199022f5632L, + 0x18adcaa58c11bc50L,0xa0c11f6458b1cbf5L,0xd1204377f961ce1fL } }, + /* 26 << 371 */ + { { 0x35a2685bbb77f5dcL,0x1b5b79bbc08efa67L,0x4ebec6e6ea5f411eL, + 0x1800a21988c57793L,0x8d7397f2cbb13c96L,0xbc13ac35dc0327f4L }, + { 0x53ac05a6fd94b150L,0xd898fa600423e787L,0x802aad2c2a66b97fL, + 0xb604ac0692c62b03L,0x9f395d3a45911e7dL,0x5d38164128ae56b6L } }, + /* 27 << 371 */ + { { 0xa7d5a3afa5fb0decL,0x0d11c0cd5b27e02dL,0x8d854b53366c6cc9L, + 0x87ef4c140ad9a5f5L,0xaf7c2e6b0c5f8acfL,0x81fc22b69f010f1aL }, + { 0xe49e0c7e4e25ddb3L,0xd30bc860ef233d23L,0x0b63afb89fa41205L, + 0xd14b326c702fea93L,0x10ab93662c2a5fc8L,0xab35bab356cfff28L } }, + /* 28 << 371 */ + { { 0xdf0f79524130138bL,0x117e4628934c58afL,0x227be6867b6a4087L, + 0xe73fb2f3b8d298a3L,0xe32e89fda9bacb9dL,0xdd3be6130e9ea7e3L }, + { 0xd3d655ead4da2d1eL,0x153cce647833bb3dL,0x4a32a9f0b36da20cL, + 0x025768e5a69c4b27L,0xb0b5da379cf1fcecL,0xd0ecaba23aa3b99eL } }, + /* 29 << 371 */ + { { 0x9ab6dae0aaf6b398L,0x2d50f46b4f8e270cL,0x46c1e676fd7b7005L, + 0x4b8b203e32cf8be9L,0x0253ec899451bca9L,0xc3a7eab7f512b7a5L }, + { 0xf3bed3fdc5bd61a6L,0x5c0eb52f0a37ef8aL,0xb61aee11140894dfL, + 0x690607f9bec928f6L,0xba2b1db65148b45cL,0xbd309bf56619b652L } }, + /* 30 << 371 */ + { { 0x79d624c7a7b92932L,0xcd086bd7cc75e7a8L,0x3cddc1bbb48eab26L, + 0x10282df1f6791cfdL,0xffedb4fb1048f114L,0x937ed0e7c092d899L }, + { 0x045e4f60b84b6d20L,0xdd67bd36877ed915L,0x9bf8fede97617aa9L, + 0xa7ff9b0789cb8e1aL,0xc49e310e74f4e7d6L,0x12dde0fb3f62eafeL } }, + /* 31 << 371 */ + { { 0xe2e3dc4d50ba6e73L,0x31c19ebce6114f87L,0x8df0ffb01ffa99b5L, + 0x305142f1bfcf7fbdL,0x39931954ab88b782L,0x1952bbab43de3650L }, + { 0xb32ed678aa09e528L,0xa5150011acee68ffL,0x0307716a97b98b23L, + 0xb60c3edd4fc8d2b7L,0x91c81725b2b2f887L,0xf1dfc70ab9fb0288L } }, + /* 32 << 371 */ + { { 0xe7cf5bacbc579793L,0x11db7ddfd73f881cL,0x9c1a531d04fa8473L, + 0x399e84845780efdaL,0x6e9c12be4f62cb5aL,0xf21bdc4994a5df3bL }, + { 0x3c15fe1211da2a4fL,0xdea123bb23e631d1L,0x3ef76da4be294c90L, + 0x5cf21d5aa99b8398L,0x50679cf8751b9f6aL,0x4b3f3b9c54d0b7bfL } }, + /* 33 << 371 */ + { { 0x442dc0fd27174604L,0x5aa056efebc95895L,0xbb8cf9b54c96a2dfL, + 0xf43342d440f8618bL,0x58b0d00a8f89a8bcL,0x74d32dbc81f69f20L }, + { 0x5caf0910ab22a49eL,0xa0e9a677ff372f3cL,0xec90b5aef5c05066L, + 0xe2d98821b663f0e1L,0x388804bf50c7abc2L,0x2fbab16e97ba64d3L } }, + /* 34 << 371 */ + { { 0x09138c6071ed8d4eL,0x994d0fa991ef82b1L,0xe6089dbb931f3193L, + 0xb3b229d0aac23611L,0x52cf03fdacb8affeL,0xf64f9872bd99d6e2L }, + { 0x52ebb8b40186279dL,0x36a2349fb09efd7aL,0xa85b5d802225772aL, + 0xd2dc3c1547522562L,0x659297a666471319L,0x65913b608c8e7b68L } }, + /* 35 << 371 */ + { { 0xd54591f9a713f82eL,0x0ecfcffc6fae64b7L,0x7df9d7ea7287e218L, + 0x8b260162abe71460L,0xf75097efb12d48beL,0x82d5902482581904L }, + { 0xc5c0b5dc400d4288L,0xf6493c78190f768cL,0x1844b5f895bc9fccL, + 0x24afb04ba615bff9L,0x6c9638ee8bf51197L,0x38bce012b9ab9fcaL } }, + /* 36 << 371 */ + { { 0x087a2790494efdc0L,0x0b5f23c9e1645cb8L,0xa6e1d1e8193a99baL, + 0x0d324e67c0e0c026L,0xa86d993820d608b5L,0x48ddfbfd8d6944dfL }, + { 0x6aa07f90d371864eL,0x5cf727eef2060df5L,0x7694e02c9a7cf2d0L, + 0xe091982f6260f63cL,0xd2d481a72cae5da6L,0x045e3685ebcb4172L } }, + /* 37 << 371 */ + { { 0x1765632323c82633L,0x5de90578d590cdd3L,0x5cc5e7b9525caf0aL, + 0xdd9be80dd53e825aL,0x9ed28b29949073f3L,0xd15024156a6ce0bcL }, + { 0xbc34beeabf355f49L,0x73724878d2b210ccL,0xe47b7af911e8122dL, + 0x381a4cccdf53a9eaL,0xaa22c9b229e8a466L,0x7a05e2081a4fa093L } }, + /* 38 << 371 */ + { { 0x3dfb53521830d848L,0xea183d5cd2820590L,0xc83a65bcabbeb376L, + 0x5d9ca4d189bb9ac9L,0xb32217be137c900aL,0xcc40daebb0827afdL }, + { 0xc76130060c58b0afL,0x39f4ed8adf32389dL,0x04a586e2bc1fe9f6L, + 0xcf018c2abb50450eL,0x5072b8f016d55d0dL,0xc3c72e90d59e1dbdL } }, + /* 39 << 371 */ + { { 0xb3291b4e50b4e9f4L,0x79a2e8121b7b9e08L,0x81855db1ddd5f0adL, + 0x91fa12fc884392e5L,0x6373de02291c5694L,0x15c77432a7171428L }, + { 0x6016a06c1132df9eL,0xa4286939a0c21c8fL,0x70c5ebe26dca3f37L, + 0xc5278c510f115497L,0x8f5b07a35ce1953cL,0x4d75c1dc41f6ac0dL } }, + /* 40 << 371 */ + { { 0xfeac8e8ac24002e7L,0xa43892076643fa6aL,0x06e7ed63daa68b52L, + 0x8580bbd5d8c7b952L,0xb17ce22410c8fe9dL,0x40266bd379b88ceaL }, + { 0x32afc840dd63ffa5L,0xb4a3eb27a2280b83L,0x90528bf685897e28L, + 0xe4612391d231f941L,0xa7b3a2ccacb5c909L,0x2606844e5558d57aL } }, + /* 41 << 371 */ + { { 0x49ad52380519dd66L,0xe1b0b03b3c1470f4L,0x15e42792cd3a4852L, + 0x91c954b7388ba040L,0xe9fd8c7f857711f1L,0x8552d3d44b63a36dL }, + { 0xbf867fde230ffab0L,0x362a32a0793f885dL,0x687802cba11e0225L, + 0xd95b073b308c1972L,0x13b104aa6b3e5120L,0x60bef12333673f57L } }, + /* 42 << 371 */ + { { 0x4c4cc5561c8a5d9fL,0x5c6e1fd52b8a42c9L,0x73fd66c44ccfa024L, + 0x73c777563c50d038L,0x26964a68a5076758L,0xb14cdbfa7484d080L }, + { 0x24c499cf3f4b92ccL,0x40c8c0d84682daa1L,0xaa156edf785561beL, + 0x36718fb6de75af0aL,0x4d391cee03f5b180L,0xcf28d08a3100efc8L } }, + /* 43 << 371 */ + { { 0xbf1fc9fdd113a97bL,0x19cee87f5ff5ff3cL,0xfc140acf8f8213a3L, + 0xe70d50d546127d5cL,0x78cd24032faa7ac9L,0x409675f1c1808096L }, + { 0xaa7b6cd91765da93L,0xc0755b924f508d86L,0x09b8fb7640169a6eL, + 0x9ca977e52e7da664L,0xee1aab6c9a9616daL,0x54d740391ca0f4fdL } }, + /* 44 << 371 */ + { { 0xfe011830c37c7fc5L,0x0b2b965b2ee958c7L,0x99fd253588a43cf6L, + 0x6a73d62dbf8dc33aL,0xd53c0241a99247deL,0xb8186dccb4127f94L }, + { 0x86c4c274964cc3d3L,0x2f3f2742cbfa9429L,0x5b4bd23c5391abd3L, + 0x030b211bc5838fe2L,0xd2263dc4ae2e36fbL,0x45583a3ca0bf7280L } }, + /* 45 << 371 */ + { { 0x9ce7f43f1ed3f49aL,0xd8094c4afcdce20cL,0xd8b423d12b37b162L, + 0x332ce47c53d90a7dL,0xc686fc0c94a38ff2L,0xb44938d6c33d842eL }, + { 0x5ed14772cd9b0002L,0xffa5d063e800c655L,0x4511ec79ffcb6120L, + 0xb8c9de3f9da8e70dL,0x4d0759ca952b0ef7L,0x685f7005dfd88f4cL } }, + /* 46 << 371 */ + { { 0xcbdb755f1dbdc85dL,0x63d0d7047961be6aL,0xf65af35d8220a1b3L, + 0x8dcea7df77db51b3L,0x8cb2c5d14bfe8fbeL,0x740579bdee2f03e0L }, + { 0xa7eeea4ed3f0181fL,0xedbdfaa3c12ef399L,0xee3cc40f1c332118L, + 0xdae0995e731ef93fL,0x05165c6c0f24d954L,0xcbcc014219fca63aL } }, + /* 47 << 371 */ + { { 0xff24bcd842c7c110L,0xa5ddfffc56dc10c6L,0xb9937fcdaa1a09c5L, + 0x8e18ed5b852dd22fL,0xf24e43c7826fb5a7L,0x13989a43415c2c63L }, + { 0x71ad7c21d36ffe0bL,0x68b77701129df418L,0x1c5324cd9a8d424aL, + 0x2e2a2b1ba9bf46abL,0x7d0c04d19cd0ea12L,0x8b4186bf2f9869e8L } }, + /* 48 << 371 */ + { { 0x6c8d97e075a46271L,0x0fa0c4cd9dbed39fL,0xfb6da5e2de74ac6cL, + 0x041ce886c17c1ec5L,0xb42941a8d7419105L,0x79768eee002fdfd5L }, + { 0x64849afd88c8111fL,0xf425fe14814192d6L,0xe916e8640448fd7eL, + 0x31e224ad72ed351fL,0x73e6e6ac7c0183c1L,0x375657c621bf7cebL } }, + /* 49 << 371 */ + { { 0x093d8039114fd7b9L,0xb6bed3eb45c5e1c7L,0xb73ab7fe50fdbf14L, + 0x68d95e57af0cd23dL,0x5c260eacc7b750fbL,0x79bb142bb5358c26L }, + { 0x5aa9845158ace251L,0x04b2388637dbfef5L,0x1051172dc0532263L, + 0x686ee9e6294890d9L,0x092617b3bffd1609L,0xb4a50e50ea3836a4L } }, + /* 50 << 371 */ + { { 0x8bdb3886cdf950abL,0xe2bdc8d3d595dbd5L,0xd28211254ecc49f1L, + 0x946566081d3c2f24L,0x8124ad390c87df6dL,0x6020c322d16272baL }, + { 0x2150f7e694af134bL,0x38512401a1a14e33L,0x39a54386b1ff7304L, + 0xfaf1ffea078d8f0fL,0x7739ea99dea995bfL,0x3252e815c020816eL } }, + /* 51 << 371 */ + { { 0x1609832322f1bd8dL,0x6b02533cd4df163fL,0x25108619a8296363L, + 0x373bf9988f8c755cL,0xebfbc5b23b32542dL,0x7ada597688b9d360L }, + { 0x3914406ebd605f01L,0xe245ba48cb3a40b2L,0x11a1dc4ed3171f32L, + 0x4a10d5d26ffb5915L,0x9326b23e997460b6L,0x53ddfee92aa0c77cL } }, + /* 52 << 371 */ + { { 0x44f51dd51104ed7fL,0xfca4773e270f6135L,0xe36c8b266bc757f4L, + 0x2cf0515d6941c7a0L,0xdeab655d5fb16e2aL,0x75c28116cff7be07L }, + { 0xb24ca428abbbca02L,0x6aaeca9b1e7f8116L,0x4252f4c3510f0c81L, + 0x01462d856f3ff7fcL,0x4df702879d1c25e3L,0xddd47a1dbebd1559L } }, + /* 53 << 371 */ + { { 0xdffaef2c6f2e2611L,0xc2c2e6a41f29efa2L,0xa29bc3b75ebb40c9L, + 0x8473594bac31a2c4L,0x100d7d6a8604447aL,0x80318670794bbab9L }, + { 0x78979f72054dfc75L,0x94b4c17e55232511L,0xac44836b78b883c3L, + 0xc1f7e98168422328L,0x34fcdee68266747cL,0x18533b3f0475c011L } }, + /* 54 << 371 */ + { { 0xede6728e3bab17f0L,0xfcd9c96879b94302L,0x6410ae37544a677bL, + 0xeacbf6de1dcd0fdeL,0xdae70841e2f3ac0fL,0xeea2a9b6e41ba13bL }, + { 0x1b06aeae9349cdf0L,0x28571e3d33c0ea87L,0xceaf9dd46043e874L, + 0x32cbcc69fa6fea15L,0x7db75664e135aa11L,0x588d4458f816929aL } }, + /* 55 << 371 */ + { { 0xf70797d02b014160L,0x1ddf312d8d7c3263L,0x3bdd58f3c78beacbL, + 0x8bccd90101c71f77L,0x3c637f58166c1486L,0xb62c0aa45fd1a307L }, + { 0xa68db7b05f2544d4L,0xb9727946f860585aL,0x91565060a068412eL, + 0x1283d6d1ab536c42L,0x86c2a11c79caa387L,0x2687309b62bd7797L } }, + /* 56 << 371 */ + { { 0x525cd8849b711a38L,0xd413d82b8c95bf61L,0x19ecc14a36b82970L, + 0x65190ee6e3416342L,0xde9834c93066fcf7L,0x3b87b15e8302cd85L }, + { 0xec6f67a785268eb2L,0x5ab08b5af95aef07L,0xb5257f70adda86a5L, + 0x53e95ec4b934400aL,0x9611a632c33b870bL,0xd27929522723a3d5L } }, + /* 57 << 371 */ + { { 0xcd203b542c95b469L,0x89b140e768713ca6L,0x451646a165701050L, + 0xb97a582575e54715L,0x070fabaa93bb6a91L,0xe517e07a196421b3L }, + { 0xc8d741235f46e495L,0x920ee94fdf60eb8dL,0x885b86dd19564c3eL, + 0x6c9e973231670005L,0xb52eed1fe4893763L,0xa8f9fbd759157417L } }, + /* 58 << 371 */ + { { 0x0c41f2eb56517cafL,0x47778a92798cf8b0L,0x4232ab390dc60cecL, + 0x5de0b7e39e3eb6f1L,0xa2569d8571562511L,0x37b3c62a1ce1cec9L }, + { 0x312caccd8b3391aeL,0x6b22c9447dcbe533L,0xc890d22f4fefd4edL, + 0xd1504f7df007a64eL,0x117e4e595845d5bcL,0x999386c7723584e1L } }, + /* 59 << 371 */ + { { 0x02c396533bdadbd5L,0xc07325fda1fe704aL,0xf78d7e23350aa0c4L, + 0x9f09cf22ce50784cL,0xcdea9a6a1a6e8abcL,0x245fba06ee5a5e06L }, + { 0xf1fd3b9b4a3d0d7cL,0x24c65a131a4952c4L,0x40ea3ef37236b6f4L, + 0x60aa573d8f7addcfL,0xdd5ec47b0305577dL,0xd92dc5035deacea5L } }, + /* 60 << 371 */ + { { 0xc666f8f3fac2de80L,0xabb2b8aba8fa36a6L,0x1bd0ec8f12202b09L, + 0x88b184be6d17a3c5L,0x00d501fc670a77c1L,0xe1f94f1db3de1c7eL }, + { 0x953179cd2d6de8caL,0xa8873a5bb9263791L,0xd76433098d7ac5d1L, + 0x3d751cab4d2f8224L,0x7417b8262e5458eaL,0xf4eb3c669e454a8cL } }, + /* 61 << 371 */ + { { 0x65b0d7e9ae3284a2L,0x3d4770bb1e3cbb18L,0x217a0cdb808ea164L, + 0x9ed6d0f689810270L,0x62d9cc95f14139e1L,0x4d39eeef6a2c82a0L }, + { 0xecf319f40dcf14afL,0x62c95df6ab0fd145L,0xfe85014d22db0105L, + 0xc37756e6a652168cL,0x6ba9f6b370a67e9dL,0xe453fd0af18d8058L } }, + /* 62 << 371 */ + { { 0x265798acfe3bf4f8L,0xc1603abdc1183f63L,0x14e3952f1063e086L, + 0xdcb106d2910f0a78L,0x27c2aee2f454f625L,0xf16d83e60f463fe9L }, + { 0xaa5547207f5ae172L,0x42ea8fea9a2133eaL,0x9f3b33f6e9253e7eL, + 0x6224ef75d67af0afL,0x06f0ddfbb92d6cc9L,0x12e66e32656e9e9aL } }, + /* 63 << 371 */ + { { 0x1a93be3424ace7f0L,0xb993bcb9a56be2eaL,0x3b054afac33608d7L, + 0x36e782c3aea3d7e9L,0x54f1dda950e9b3adL,0x04dd021f55f51bb4L }, + { 0x9c76f7c0347bb352L,0x3d9a04ee2f1dc5fbL,0xea5e582ae80e06f0L, + 0xe523aab927e1e818L,0xe2f1960252d4904cL,0x1bfa8b03adecc51fL } }, + /* 64 << 371 */ + { { 0xc84f917203bdf6d6L,0xcfc4718769f60e03L,0xcdc4753ba05068eaL, + 0xa177ad14077777efL,0x0b7f54eb7e4cf44aL,0x4ee443f91860144eL }, + { 0x1279ed4d42bb6a93L,0x511137d7436c1b54L,0xebc958fab8cdb6ceL, + 0xbc4f93f4a0c7614aL,0xc5bd6cde7b2c6d8eL,0xecff7dd78d65f38aL } }, + /* 0 << 378 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 << 378 */ + { { 0xffec6674f65de0f5L,0x4043079cd23ad193L,0x31811365ee61bc95L, + 0x358bbd6e8948b6e2L,0x1cd9c342e31644beL,0xbab3aa8c60a8a7a7L }, + { 0xe065519fa375beb6L,0xf7d0b0414439990cL,0x8957c03b8517ae8aL, + 0xc96a040173750d6eL,0x4eb2e364b2aee6d7L,0x813054feed099114L } }, + /* 2 << 378 */ + { { 0xbb39a17a7c34f095L,0x7be330a822fbbe61L,0x6be6abe3b91f1482L, + 0xf972804fbd39a2bcL,0x06737e54f91d813eL,0xbd6066681a87cd4aL }, + { 0xbf88b2e5f538d56eL,0xb8206a8134afd68fL,0x7a93aedfa58af042L, + 0x8853cdf6ac0511b0L,0x9d7f416d067e2c19L,0x5d0bc923f9671d8aL } }, + /* 3 << 378 */ + { { 0xf3b6fd79dd3532a7L,0xf60262b5dbbb9e4cL,0xbf75bb57da4d6ac4L, + 0xf016adf1c094b38cL,0x9114cdd012def474L,0xdc74d638c785f143L }, + { 0xdea060d6a8d90bbbL,0x1f141878cbcd0d4cL,0x552685b79ddee1f5L, + 0x381dfc0c636ea6b6L,0x8c601615cb08f34fL,0x5b843830271041eeL } }, + /* 4 << 378 */ + { { 0x2e7d0a16204be028L,0x4f1d082ed0e41851L,0x15f1ddc63eb317f9L, + 0xf02750715adf71d7L,0x2ce33c2eee858bc3L,0xa24c76d1da73b71aL }, + { 0x9ef6a70a6c70c483L,0xefcf170505cf9612L,0x9f5bf5a67502de64L, + 0xd11122a1a4701973L,0x82cfaac2a2ea7b24L,0x6cad67cc0a4582e1L } }, + /* 5 << 378 */ + { { 0x139d9fef6bfc08e4L,0x4399615939ffcb3bL,0xaa299008a84ace07L, + 0xfce43e873cbb2b3fL,0x07b3e8b9191a320eL,0x3ec851d706c4d485L }, + { 0x03d8a672a4bb8477L,0xb6a5dcb213c31d5cL,0x58b79d01c439ab23L, + 0xdd6f8b5134f66137L,0xccb178a0b29be48cL,0x4c71b7aa4df8a1b2L } }, + /* 6 << 378 */ + { { 0x92bf8c4508359896L,0x77253434ae2c30f2L,0xf05086ec827e6cf8L, + 0x46d4729f1771c5d3L,0x92587306f37f0bedL,0xb82c99d2e7c30180L }, + { 0xee0141dcb1684841L,0x7fa984be994ddaf5L,0x5c583347165c238cL, + 0x1a1ad3eea5d78204L,0xcfed795f2736bce6L,0xa7a413318961204eL } }, + /* 7 << 378 */ + { { 0x87451ca71400851dL,0x3aace28e3573ecf6L,0x3a5902cee85717c5L, + 0xe4b51dd0c9f57944L,0x33cf684789a9d8aeL,0x2f6fb08031e6e769L }, + { 0x4bf3da323b78dad1L,0x2d73fef4e7809638L,0x84d76151965109abL, + 0xa2c932c9a2098f46L,0xb8c457c3bc17d1fcL,0x5ef2562d0c8012a4L } }, + /* 8 << 378 */ + { { 0x96a1e74f51e4de5eL,0x72913696e37f5006L,0x12449c4fbe35109cL, + 0x1fad8b304521d7e6L,0xc85eb23d57d00293L,0x4ebd334b35f68229L }, + { 0x7c5b86682df5acf1L,0xc2b4da6e5463de2eL,0x067b0456757cd570L, + 0xeaab81be3a1c866bL,0x72a6af75bbba88c0L,0xaed4dbde0ef567dcL } }, + /* 9 << 378 */ + { { 0x085e33cd9273818aL,0x8fb9294a8cf4e306L,0xaed46bbc35052bd1L, + 0x031febb3374661eaL,0x9386a35d4868dbb2L,0x381e5b521d3f2dddL }, + { 0xa938a3a5179617edL,0xb0fc99f49dc95af1L,0xf446dfa92b9dacbcL, + 0xbae262ae490c1969L,0x042707ffa7443354L,0x8dc0511f267d5c14L } }, + /* 10 << 378 */ + { { 0x8f0e1908fac2674dL,0xd86e85a483e43c26L,0x1f719f7036fb5a4eL, + 0x7ad61b8ca57dbcbcL,0xcf6ba7db0f63dc79L,0xb4315ab11afe8540L }, + { 0x0448e852425c4df3L,0xf51969ef8838a51dL,0xce98589b9eab87deL, + 0x55867b5645149689L,0x9b70bc8c60d2a624L,0xc158a2710b6dbd45L } }, + /* 11 << 378 */ + { { 0x0b262f808f1915f2L,0x64ba3bc73d501e01L,0x8ce2db1f4645152cL, + 0xf4a4f3afab047cdbL,0x1a7c4af600d31e7fL,0x0005bca678d1c0ecL }, + { 0xf5ed135f6fe5ebb0L,0xa299b1002ea9abdfL,0x4fa387e5fccb58f5L, + 0x105b9dd2fc657b72L,0x1494c6050dc3c22cL,0xf7468e8a92d281c7L } }, + /* 12 << 378 */ + { { 0x597a26ffb4dc8600L,0x264a09f3f9288555L,0x0b06aff65c27f5f6L, + 0xce5ab665d8d544e6L,0x92f031be99275c32L,0xaf51c5bbf42e0e7cL }, + { 0x5bb28b061e37b36dL,0x583fba6a8473543aL,0xe73fd299f93fb7dcL, + 0xfcd999a86e2ccad9L,0xb8c8a6df334d4f57L,0x5adb28dd9a2acc9bL } }, + /* 13 << 378 */ + { { 0xc760823646dd14f3L,0xc6d97d37e7a97f33L,0x05037f26de2f444aL, + 0x5267ded09aa9a5c0L,0xd1ef46340be2d841L,0x308b37a8d48b9574L }, + { 0x102f7878487bad5bL,0x1d5169d938b7c1efL,0x2d8adde62c39c75aL, + 0x71bfb8bc0b80f3bbL,0x126505999bff252fL,0xf99e952f24f8bd3bL } }, + /* 14 << 378 */ + { { 0x24496a8b7a8a6d47L,0x9fc75c0aec6afe43L,0x4200e00670744f15L, + 0xe2f87d5e2973be1dL,0x0f6c5993c82e2013L,0xe9ecf6ce198c99f0L }, + { 0xcbdf72058b37d828L,0xbef4b8c8325d1d93L,0x8e962ffbd0fbb134L, + 0xe4273a124bcffc61L,0x4f24ba23f3d93d73L,0x8f02df83bcfcb930L } }, + /* 15 << 378 */ + { { 0x985c8f4b0614348aL,0xca4ca7cd5a03c014L,0x5bdd4382a7b62effL, + 0x623d44b9e4a0bb42L,0x1f28862ef23931d5L,0x30568303868326beL }, + { 0x850d2a0d82e76f04L,0xf4dc02330ac4a153L,0x62b74879b1e70a9aL, + 0x7b32249baf3f0dbbL,0x2f50395d155eae92L,0x6d990c16f6f5c9a4L } }, + /* 16 << 378 */ + { { 0x3afdee277d221ab6L,0xecf10abc47bb619eL,0x340c8ee3ba4a3301L, + 0x1a6ea51a2a883b7fL,0x64f27976d5d7412bL,0x7fcf0ecc91251b6eL }, + { 0x5f3f8f41365b18b7L,0x38e48b96e2e13e58L,0xde3b73d6ad61b2cbL, + 0xf08398d5d542676dL,0xd373931e8e7d712bL,0x89325d7a7f96e023L } }, + /* 17 << 378 */ + { { 0xeb2e48c10bf4e94dL,0x00614bf206b7e166L,0x536c999ce295c451L, + 0x951f92186359cf06L,0xe2a938890afc827fL,0x63102e93ff029787L }, + { 0xab297c7d2ac89645L,0x7354df74928742bfL,0xc0934ca6c8604304L, + 0x36b7e9711cc2f3b4L,0x487ce890e10ee837L,0xe6aa9eabae2ae9e3L } }, + /* 18 << 378 */ + { { 0x6e7a578340517347L,0x7db868f3a950dfa2L,0x7fd7fd8eb3c2eff7L, + 0xae7b59c5fbe10a47L,0x5239b5c4109797d6L,0x3838356a53264b8aL }, + { 0x8df8454c320a8c5aL,0x67c86ef46958fa2cL,0xfe1aad846241a50aL, + 0x3df64ef5a06f3cf3L,0xde6af0ff83282fbdL,0x25ca45046cdbe5feL } }, + /* 19 << 378 */ + { { 0xa319340d6e6c0debL,0x101f055acb1b1cd5L,0x4bea31ad623e7e55L, + 0xc0c88af6aec23cd2L,0xca98c4364aaf2f73L,0x1969eca437dd1341L }, + { 0x6b03989f97866dc3L,0xafdc99532eaf5b08L,0x199ec0e93d6ea9c4L, + 0xc3d1069474f262e9L,0xa7e5670079911cf9L,0xc0213ec56844da05L } }, + /* 20 << 378 */ + { { 0x5adf3d9a111792b9L,0x1c77a3054f1e0d09L,0xf9fbce33a82d3736L, + 0xf307823e718c8aa3L,0x860578cf416ccf69L,0xb942add81ef8465bL }, + { 0x9ee0cf97cd9472e1L,0xe6792eefb01528a8L,0xf99b9a8dc09da90bL, + 0x1f521c2dcbf3ccb8L,0x6bf6694891a62632L,0xcc7a9ceb854fe9daL } }, + /* 21 << 378 */ + { { 0xfc9660a3c8808373L,0x84c5d6a71a50c560L,0x13fe0588ba057fe2L, + 0x29b0341dafb73ad1L,0x37b11137f15f0cd2L,0x84422ba89c2d7eb0L }, + { 0x0b595ac52554ef7fL,0xd7a8303f08b37a84L,0x908895a9e02d77fcL, + 0x70cdeb0c9f242a42L,0x535e8540116e2db8L,0xc88f0cf685c54d31L } }, + /* 22 << 378 */ + { { 0xf534f145e2290ebaL,0x3d081c0d7f15c9e3L,0x716574c5e9ae3da0L, + 0xbe6bd7b92c078aa8L,0xab8802bab8da8e68L,0x0c5be4a1ab204fb0L }, + { 0xad25c5ee0d3f12b3L,0x3929d0d78fc9b7a5L,0x9c6e2ce0bb5cd2fdL, + 0x855367c4924ec2d2L,0x6b532891e6550d3cL,0xab2bc89575ba5c99L } }, + /* 23 << 378 */ + { { 0xb56b035e2a0349adL,0xcfa41da6f89ce836L,0x9d86bcac8b5c43fcL, + 0xc77375da47644b07L,0x9e9c222607f4b670L,0x71d663c80482a61bL }, + { 0xb423e739ef237431L,0xf1cedf7e48832b5bL,0x09e0cb2a7ca7548bL, + 0x9b463559631b9850L,0x8a2bd7fed4dd03deL,0x46115292ae0c97d3L } }, + /* 24 << 378 */ + { { 0xe44e3f864b3759cfL,0x90cab0eb9d74e3f6L,0x1004254501c4e171L, + 0xc12df68cce52defbL,0xb1fae2fbf363100aL,0x5016c8533573235fL }, + { 0x8d4deb661d922e9bL,0x8a20d42317f84ef2L,0x324985835a4e118eL, + 0x5abfa961308772e9L,0x41c7611ff54e4876L,0xc1da40d31f5867b2L } }, + /* 25 << 378 */ + { { 0x4df02a7d3088aebcL,0x7dea27ea12487485L,0x2a773270df98069eL, + 0xea435fa0e9ceaf44L,0x08e952e365e5ebabL,0x972877d5c3511480L }, + { 0xef5685f859a04cd0L,0xe50abe68b8c7c796L,0xbbb792e2c3225f20L, + 0x7d9878e811c89153L,0x4b72a1e619354751L,0x7d5f05a3faa1be22L } }, + /* 26 << 378 */ + { { 0x61dd7692f27eed54L,0x8540213ea7a3f2f7L,0xe659cbd6ace07e13L, + 0x3a998cdcc8995cacL,0x0accb4a7922d3b25L,0x762b3406c6577d81L }, + { 0xa09db4f57e043740L,0x7f78e02d8cc9bc5fL,0x080a522673b98cd3L, + 0xb6d72f7ce6490808L,0x36815de2c724284aL,0xc27d13df98b867b5L } }, + /* 27 << 378 */ + { { 0xbfeffd5356adb6e4L,0xb5e8876c499a1455L,0x4771281390833f18L, + 0x5f49ef880115b9a5L,0xb041ec67cf575de5L,0x490753350b7e4afcL }, + { 0xad4dc4a15f0b9f24L,0x9dbb181edafad9a5L,0xa84431a6e6ed5198L, + 0x33ee16e27993eed6L,0xfdf76899c1e4f8b4L,0x868d06baff60e943L } }, + /* 28 << 378 */ + { { 0x46303171491ccb92L,0xa80a8c0d2771235bL,0xd8e497fff172c7cfL, + 0x7f7009d735b193cfL,0x6b9fd3f7f19df4bcL,0xada548c3b46f1e37L }, + { 0x87c6eaa9c7a20270L,0xef2245d6ae78ef99L,0x2a121042539eab95L, + 0x29a6d5d779b8f5ccL,0x33803a10b77840dcL,0xfedd3a7011a6a30fL } }, + /* 29 << 378 */ + { { 0x5d782a0778664144L,0xc1413da46682c779L,0x937a15f52a67b12bL, + 0x8ec00d9fc04d8cd5L,0x3f16d1ed3b5fe8d6L,0x24ad6b0ca28c8067L }, + { 0xdd1eecc532732b19L,0x62c4c2beab2fa785L,0x7d863f5b2ac0c238L, + 0xd686eb7239384e15L,0x3770e54d16bd75b2L,0xdcd9e4e8120b3881L } }, + /* 30 << 378 */ + { { 0xe3052838df5147e1L,0x87bc4d75b1baaa7cL,0x49b13eb95acc5572L, + 0x919081881990c13cL,0x5d43a4a6191cc808L,0x20b358444182aa55L }, + { 0x70d49a4a670b1fd1L,0xc6e6e061722e91e7L,0x8d130b3900c5ae9eL, + 0x5db7d06920f68ec5L,0x85b6c505470fbe13L,0x14101ec7326c4d38L } }, + /* 31 << 378 */ + { { 0xeef03450e10e8018L,0x75921e487576c3ddL,0x6c8e22676e97f5afL, + 0xd7323e01a856ae6bL,0x43a195425fed884fL,0x010865380377ba8fL }, + { 0x7cdbd06ac82a8f67L,0xc6fce58bf0fd4281L,0xae098b7f9e67bed0L, + 0x0c8d328bdd918524L,0xddf723ec0a11fb83L,0x210d6016e25a2073L } }, + /* 32 << 378 */ + { { 0x3c90a59f85adde98L,0x35414174e5269140L,0x9aca885c1a0d58e2L, + 0x77b9b6dd6816b009L,0x8e5c12139ee4718fL,0x60ad991e4e4eac45L }, + { 0xc00c35694d71f624L,0xacbf4eb25bc5fd2aL,0xcba1ffc75eaf3eaaL, + 0x5f99092d42a87e32L,0x2e7b49c76f7a882fL,0x5e9bfc5c29040512L } }, + /* 33 << 378 */ + { { 0xa31d3524b295958dL,0x9713a5e04894f486L,0xe8804ab3329a0b9aL, + 0xd4447c1b20eefa54L,0xf5b944c9040b7ad4L,0x9db0ee0b907f2cfdL }, + { 0x0b1a1f3a5384a999L,0x3137241ea8351764L,0xe0663b5ab29c3cffL, + 0x2b47ca0622d4deefL,0x4f952109f1172bcdL,0x1e7a7fca9b447bd4L } }, + /* 34 << 378 */ + { { 0xc9898355ecf2a473L,0x20d0c4740dcd66f6L,0x6459720f8eeefff5L, + 0xd9b625dcf9ce0cdeL,0xed3a6508ea56be90L,0x6847c20de211c90eL }, + { 0x36d86bed71a73ceeL,0x9222eab23023d16eL,0x3155874750209b4dL, + 0xcac8f277d145b831L,0x49cedc634470e754L,0x6c7c065add370f77L } }, + /* 35 << 378 */ + { { 0x46a95735f8171804L,0x1ff2549ec4c93476L,0xfb8a08285bb5202dL, + 0xaff5505f1070737aL,0x162aaad842f412c5L,0x02a37213fac8a477L }, + { 0x05ff9238932f08e2L,0x9be6a0b29fc66787L,0x373a9039db1e5a40L, + 0xe657e8c782d04913L,0xa2006f207e6ee867L,0xd7aa1d2378d82f9aL } }, + /* 36 << 378 */ + { { 0xfa070e22142403d1L,0x68ff316015c6f7f5L,0xe09f04e6223a0ce8L, + 0x22bbd01853e14183L,0x35d9fafccf45b75bL,0x3a34819d7eceec88L }, + { 0xd9cf7568d33262d2L,0x431036d5841d1505L,0x0c8005659eb2a79aL, + 0x8e77d9f05f7edc6aL,0x19e12d0565e800aaL,0x335c8d36b7784e7cL } }, + /* 37 << 378 */ + { { 0xdcac39d87c1d9f4dL,0x88322d8bc225ce6eL,0x5c240cefa3ef5202L, + 0xf60ce5d991f1d487L,0x8e857069e462cfa8L,0xa6e5585e996d2033L }, + { 0x709675a556281e6aL,0xcd90c140f907ebf0L,0x5343a0a2a3231eecL, + 0x74b1443214892291L,0xf8cb9c26a5325b8cL,0x1bb28be140089be5L } }, + /* 38 << 378 */ + { { 0x2bb6e7ec3092d0b2L,0xc7c9e5f1d27d1f31L,0xbac785aeac0939e3L, + 0x186d3d934f810d8fL,0xda296dacfe7d778fL,0x6189f5e41a991ea2L }, + { 0x098f794e9634363eL,0x04aaf59a88a4dccaL,0x09d718487196dfa8L, + 0xa447a31ed83044a6L,0x720cd3908d1363fdL,0x6f670479e22efa03L } }, + /* 39 << 378 */ + { { 0xaa452e81cdf60f9aL,0xf3dc472a8e2c58e9L,0x16ddefa50589fd01L, + 0xd56ec8f223a1656eL,0xcccb784f77921ca4L,0x9bace7adf8a7c0baL }, + { 0xc94ef3ef51f052e2L,0xa70c0579c34e7cb5L,0x3599817883ce8674L, + 0x033647c392a20951L,0xc828fcc77a21add6L,0x5a446de871ba27a5L } }, + /* 40 << 378 */ + { { 0x75cba9d530a3ada1L,0xb69e308bf8ae9565L,0x990e3425ca7b8369L, + 0x9f67567fe0a7ad0bL,0x76ed6fe718bd01b7L,0x282358aa2ff95cfeL }, + { 0x28d2ea41410f8841L,0x89d1533fccd67c81L,0x969bb272b6a7b8f9L, + 0x54f8664c26330782L,0xb89f3ae81dcd9164L,0x54d845b93d962c14L } }, + /* 41 << 378 */ + { { 0x08ba5b61fde4ca03L,0x39b1a9c697b17ee6L,0x885253779336b2b9L, + 0xe964dc9c9aabc3fcL,0x6aed101a5295e728L,0x30369ea0ee12356aL }, + { 0xe081e022c8e80e5eL,0x3a769ef0df9f47c0L,0x3b2f7aab5590750cL, + 0xd16c7a85a1a5e504L,0x9e528623e854d7cfL,0xaca079354468e419L } }, + /* 42 << 378 */ + { { 0xee521c0af93098bfL,0xf517c925b79aa0ebL,0x17779f5e7bbc58feL, + 0x093c3dc2769de891L,0xafbf32372a69ad0dL,0x33a95de702001e8cL }, + { 0x3b30afc73410a2b0L,0xb379a3f425bc7d9aL,0xf1c069251604a646L, + 0x04f0bb334fca052fL,0xe5cd9c39cab33871L,0xf259795816fa1b16L } }, + /* 43 << 378 */ + { { 0x291d65c801189d9aL,0xb16ca18bd8e94e49L,0x55f7680599440d4bL, + 0x55d40c1b2eb7f0fdL,0x752d98f6018d7c64L,0xa1cae78c7b491c4dL }, + { 0x898fc8c78f66b8d3L,0xbb48956a3ceecd27L,0xb8f9498dfaa9451fL, + 0x583b336aa5683ef8L,0x0deaa373e92656f4L,0x7f87b4412a9a0272L } }, + /* 44 << 378 */ + { { 0x8b2fc4e96484fd40L,0xee702764a35d24eaL,0x15b28ac7b871c3f3L, + 0x805b4048e097047fL,0xd6f1b8df647cad2fL,0xf1d5b458dc7dd67fL }, + { 0x324c529c25148803L,0xf6185ebe21274fafL,0xaf14751e95148b55L, + 0x283ed89d28f284f4L,0x93ad20e74cbebf1aL,0x5f6ec65d882935e1L } }, + /* 45 << 378 */ + { { 0x4b0c7d0c69c284cbL,0x907e4f38199c5176L,0x4ebfbda7cf3dab12L, + 0x675f12cca4fa74a9L,0x86628102bdf579e6L,0xf08cbfe771c4d061L }, + { 0x9dde390e03bc1cb9L,0xb6d0d48b4c727915L,0x7cad28c370c0b7bfL, + 0x8d978a8110d1e881L,0x1c071597924baeb1L,0x83c09192eb103fe0L } }, + /* 46 << 378 */ + { { 0x494dbd2665925506L,0xe239b1d404b6fc45L,0x38a1ec5ce16b874dL, + 0x1588c4712a3f012dL,0x5bd45adcdc6938b9L,0xe4c35c2244ab2fccL }, + { 0x87cbd9ff887108a2L,0x92a9c3b2144fd3eeL,0x3a0e55c7982a4928L, + 0xcaf679765bb0fddfL,0x04616318263ea256L,0x56eb022838caa901L } }, + /* 47 << 378 */ + { { 0x2f7de141a48da000L,0x323bd638835a4edfL,0xd2d9da967e155bd5L, + 0x717c302a766b69daL,0x5927968beb0f6ca5L,0xfd96bd168940c766L }, + { 0xf89f7539a334fd71L,0x4ba9cd8bd870954fL,0x7e639523a3d57aa8L, + 0x88f31e162314c0ceL,0xa836a6ad53b7e6e9L,0xd35a825190e43169L } }, + /* 48 << 378 */ + { { 0xb3984b176c0f3509L,0xf9fa4483d8b4d6bcL,0xf4ac2b677dec20d2L, + 0x67ef024eb3dbe034L,0x2dcc51180f94f4d7L,0x024cdcfd74a51393L }, + { 0xf1c0fead20e7abcbL,0xffc18f81d3a7414fL,0xb00ce5567062cb0bL, + 0xeccb0521817bc8d1L,0xa0c0fe6040411c15L,0x053113221defbe00L } }, + /* 49 << 378 */ + { { 0x74faca8a6af7e742L,0x6f206002d878a97aL,0xd69b7c83177305ffL, + 0x605e7a32d2e2bcf1L,0x65bd03584590bf03L,0xab3ae700d1a378c5L }, + { 0x037e79028a929b0dL,0x83625ae0a7c451c6L,0x82a18f03492b01d4L, + 0x12c6d168e67756b1L,0x1e704c3bd7924df1L,0x7708617f1989244eL } }, + /* 50 << 378 */ + { { 0x4c98c61d097bde48L,0x6a55edf1c354f433L,0x1ceee947c3f39212L, + 0x162cf27f36ba3cebL,0xd9f3982e3ec5f7ffL,0xd363e435d58d42d2L }, + { 0x2ee90d7bad36681dL,0xd916df56ebfbf51cL,0x61d94ed8d7c27fe7L, + 0x5010582e923c1acdL,0x89d23e8b6de52994L,0x0a4f9c10525dbccfL } }, + /* 51 << 378 */ + { { 0x7778fad7e65573e2L,0xa4af7a2d74986210L,0xd78ecebfec57d967L, + 0x9be8a33f67d61b2eL,0x6888444f98a9add7L,0x218e7fb1b71a25a4L }, + { 0xf75a6b795f46323bL,0x2f8610ad11a52cd9L,0x23692f85fc6837caL, + 0x3a37965f71fe847bL,0x29c25cc3fe3bdeeeL,0x68fefc83f624665aL } }, + /* 52 << 378 */ + { { 0xe222eba4a4dcefe9L,0x63ad235fec1ceb74L,0x2e0bf749e05b18e7L, + 0x547bd050b48bdd87L,0x0490c970f5aa2fc4L,0xced5e4cf2b431390L }, + { 0x07d8270451d2898eL,0x44b72442083b57d4L,0xa4ada2305037fce8L, + 0x55f7905e50510da6L,0xd8ee724f8d890a98L,0x925a8e7c11b85640L } }, + /* 53 << 378 */ + { { 0x8357d8bb460e77b2L,0xc749a6a77709a52bL,0x94035a1f0c82ab81L, + 0x15245ac616c11ef4L,0xbf3cd96c034d021bL,0xf79e2d39b2e8fac1L }, + { 0x387015194b6cf1bdL,0x341f9b53b3143bf7L,0xb2584aabdda9acf2L, + 0x16f34bdd553a8e68L,0x89d0c4c5da7830b3L,0x6cfe44c63f488c2eL } }, + /* 54 << 378 */ + { { 0xee536a26d4bcaa59L,0x5ea6a57c699397bfL,0xb28f476b59a7eb99L, + 0xa901f2551406ec90L,0x7b6e3e4d1f54ef38L,0x058ff1904c89c9a8L }, + { 0x5690fa10fca546ccL,0xfe98793145e14268L,0x6181fa1675362f5dL, + 0x3ebe84466964b9aeL,0x3e1957812ce0f969L,0xb33ea619b0195852L } }, + /* 55 << 378 */ + { { 0xeef402410ec537acL,0x1f72c1f8911316f6L,0xab4bb08268cc6678L, + 0x031fc087255e8c5eL,0x99c2ff0b948ac53bL,0x13db3201919c1870L }, + { 0xdec81fd312057a3cL,0xbdffa226ff7a44cbL,0x748d2e93d97167e2L, + 0x33a9fe40bd21effeL,0xe08e4213817ea560L,0x2221798b9f4337d5L } }, + /* 56 << 378 */ + { { 0xda828fe556467257L,0x5e9abf67d640c2a1L,0x0eed233cc25c696aL, + 0x72483dc5b3e1d84fL,0x30bf1ee34f114abcL,0xf58b321ed1f9bce8L }, + { 0xcb26564c97524f33L,0xdc2f105e1e453229L,0x9da43ceb72a982ddL, + 0xecf5649dfeef8862L,0xd8afda341fa2f06dL,0xf0d0ced355035432L } }, + /* 57 << 378 */ + { { 0xec22bb32205a5301L,0xe4d168e75b0b727bL,0x91217a6be34fe2e0L, + 0x03c6831675f0f139L,0xb21e275d8b991b29L,0x7f517c9c01f3f401L }, + { 0xbbe95d19e55e49faL,0xc5470808504514b1L,0xb88be15c7cc1367dL, + 0x242cb06bbfd24bacL,0x08647a158d2ab0baL,0x8f1fd1bd5716ed9bL } }, + /* 58 << 378 */ + { { 0xe787054518ba5236L,0x243622f9e8a47507L,0xe7d94f4697b97d7cL, + 0xb120589021649255L,0x8b5101310dd4e1d4L,0x1690687e164c44baL }, + { 0x65bb4d8cf100fef5L,0xfffffee70a684c3dL,0x2aa11707c463a975L, + 0xccaddeaf391ad03dL,0x4d2cda1c81cca7deL,0x9d3eaa58c5b0f8e7L } }, + /* 59 << 378 */ + { { 0x3d92ecc18f8802dfL,0x3024ce311a719461L,0x6bdf53fc46c1f31bL, + 0x4f4576a12c9c7744L,0xe1ee7508c3ff7356L,0xd4b25ed3883ebf03L }, + { 0x1dc46052420c3ac9L,0x376ebbfa11ecefa9L,0x36e175265e9693f5L, + 0xeb82b33740ed3143L,0x6960312ff19fa66aL,0xc7edb5db6c742e1bL } }, + /* 60 << 378 */ + { { 0x5bfa10cd1ca459edL,0x593f085a6dcf56bfL,0xe6f0ad9bc0579c3eL, + 0xc11c95a22527c1adL,0x7cfa71e1cf1cb8b3L,0xedcff8331d6dc79dL }, + { 0x581c4bbe432521c9L,0xbf620096144e11a0L,0x54c38b71be3a107bL, + 0xed555e37e2606ec0L,0x3fb148b8d721d034L,0x79d53dad0091bc90L } }, + /* 61 << 378 */ + { { 0x4b98cb69c5c8a182L,0x887071bbcac96dabL,0x03d42e96afc190c3L, + 0xbc2c3b8d7a813820L,0x1ee7797f6590d0ecL,0x4a95f7f3ad4777a4L }, + { 0x7a36de4e2a8d2736L,0x7f8c6751ad78dab6L,0xf9874bf6974c0a8eL, + 0x759fee1c8b53025aL,0x1b00fb28a2171c8bL,0xdf206f19be8f2e7eL } }, + /* 62 << 378 */ + { { 0xe6bbcf0bf8ed6302L,0x7734dc91f8fe7a42L,0x840210ee61ff9d1eL, + 0xbbf2d5477007f2e9L,0x0f17d421a6542ac0L,0x0b2d3d2ee01df4e9L }, + { 0x520e4fbb84f3703fL,0x8362f7b1431106b7L,0xdcfc96ae6e50d836L, + 0x2dfa176cc44153bbL,0xeef1c6710b09ffe2L,0x633a2ac888531d81L } }, + /* 63 << 378 */ + { { 0x29262b6d7636a78dL,0xdc504f01d3ce2967L,0xa441e5035bcf0e19L, + 0x8025224f7ad39d9aL,0x780ec65de871b792L,0x977b4bce597694b4L }, + { 0xe05eaeb87fe3ef11L,0x1cff87ac9748b10eL,0xb669c1d60c34153aL, + 0xf5da63e0f8f90368L,0x6f7f2fc47d31bf61L,0x37e9158235c16a0fL } }, + /* 64 << 378 */ + { { 0xcf17f9dc08d1be5dL,0xb55de4c8afdfeb23L,0xa69454ffe437b29cL, + 0x6628d789e27ee9e2L,0x56e3b975ee3af03bL,0x0083fe9c2f532d62L }, + { 0xcae15213e63e7511L,0xdb5384f386ed849cL,0x902ba959fa4d825fL, + 0xbad700d55ae17566L,0x16b2c5dc14c82eb4L,0xa4b057a736708ea7L } }, +}; + +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Pre-computed table containing multiples of g times powers of 2. + * Width between powers is 7 bits. + * Accumulate into the result. + * + * r Resulting point. + * g Point to scalar multiply. + * k Scalar to multiply by. + * table Pre-computed table of points. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_add_only_6(sp_point_384* r, const sp_point_384* g, + const sp_table_entry_384* table, const sp_digit* k, int map, + int ct, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_384 rtd; + sp_point_384 pd; + sp_digit tmpd[2 * 6 * 6]; +#endif + sp_point_384* rt; + sp_point_384* p = NULL; + sp_digit* tmp; + sp_digit* negy; + int i; + ecc_recode_384 v[55]; + int err; + + (void)g; + (void)ct; + (void)heap; + + err = sp_384_point_new_6(heap, rtd, rt); + if (err == MP_OKAY) + err = sp_384_point_new_6(heap, pd, p); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 6 * 6, heap, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) + err = MEMORY_E; +#else + tmp = tmpd; +#endif + negy = tmp; + + if (err == MP_OKAY) { + sp_384_ecc_recode_7_6(k, v); + + XMEMCPY(p->z, p384_norm_mod, sizeof(p384_norm_mod)); + XMEMCPY(rt->z, p384_norm_mod, sizeof(p384_norm_mod)); + + i = 54; + #ifndef WC_NO_CACHE_RESISTANT + if (ct) { + sp_384_get_entry_65_6(rt, &table[i * 65], v[i].i); + } + else + #endif + { + XMEMCPY(rt->x, table[i * 65 + v[i].i].x, sizeof(table->x)); + XMEMCPY(rt->y, table[i * 65 + v[i].i].y, sizeof(table->y)); + } + rt->infinity = !v[i].i; + for (--i; i>=0; i--) { + #ifndef WC_NO_CACHE_RESISTANT + if (ct) { + sp_384_get_entry_65_6(p, &table[i * 65], v[i].i); + } + else + #endif + { + XMEMCPY(p->x, table[i * 65 + v[i].i].x, sizeof(table->x)); + XMEMCPY(p->y, table[i * 65 + v[i].i].y, sizeof(table->y)); + } + p->infinity = !v[i].i; + sp_384_sub_6(negy, p384_mod, p->y); + sp_384_norm_6(negy); + sp_384_cond_copy_6(p->y, negy, 0 - v[i].neg); + sp_384_proj_point_add_qz1_6(rt, rt, p, tmp); + } + if (map != 0) { + sp_384_map_6(r, rt, tmp); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_384)); + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (tmp != NULL) { + XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 6 * 6); + XFREE(tmp, heap, DYNAMIC_TYPE_ECC); + } +#else + ForceZero(tmp, sizeof(sp_digit) * 2 * 6 * 6); +#endif + sp_384_point_free_6(p, 0, heap); + sp_384_point_free_6(rt, 0, heap); + + return MP_OKAY; +} + +/* Multiply the base point of P384 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * r Resulting point. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_base_6(sp_point_384* r, const sp_digit* k, + int map, int ct, void* heap) +{ + return sp_384_ecc_mulmod_add_only_6(r, NULL, p384_table, + k, map, ct, heap); +} + +#ifdef HAVE_INTEL_AVX2 +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Pre-computed table containing multiples of g times powers of 2. + * Width between powers is 7 bits. + * Accumulate into the result. + * + * r Resulting point. + * g Point to scalar multiply. + * k Scalar to multiply by. + * table Pre-computed table of points. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_add_only_avx2_6(sp_point_384* r, const sp_point_384* g, + const sp_table_entry_384* table, const sp_digit* k, int map, + int ct, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_384 rtd; + sp_point_384 pd; + sp_digit tmpd[2 * 6 * 6]; +#endif + sp_point_384* rt; + sp_point_384* p = NULL; + sp_digit* tmp; + sp_digit* negy; + int i; + ecc_recode_384 v[55]; + int err; + + (void)g; + (void)ct; + (void)heap; + + err = sp_384_point_new_6(heap, rtd, rt); + if (err == MP_OKAY) + err = sp_384_point_new_6(heap, pd, p); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 6 * 6, heap, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) + err = MEMORY_E; +#else + tmp = tmpd; +#endif + negy = tmp; + + if (err == MP_OKAY) { + sp_384_ecc_recode_7_6(k, v); + + XMEMCPY(p->z, p384_norm_mod, sizeof(p384_norm_mod)); + XMEMCPY(rt->z, p384_norm_mod, sizeof(p384_norm_mod)); + + i = 54; + #ifndef WC_NO_CACHE_RESISTANT + if (ct) { + sp_384_get_entry_65_avx2_6(rt, &table[i * 65], v[i].i); + } + else + #endif + { + XMEMCPY(rt->x, table[i * 65 + v[i].i].x, sizeof(table->x)); + XMEMCPY(rt->y, table[i * 65 + v[i].i].y, sizeof(table->y)); + } + rt->infinity = !v[i].i; + for (--i; i>=0; i--) { + #ifndef WC_NO_CACHE_RESISTANT + if (ct) { + sp_384_get_entry_65_avx2_6(p, &table[i * 65], v[i].i); + } + else + #endif + { + XMEMCPY(p->x, table[i * 65 + v[i].i].x, sizeof(table->x)); + XMEMCPY(p->y, table[i * 65 + v[i].i].y, sizeof(table->y)); + } + p->infinity = !v[i].i; + sp_384_sub_6(negy, p384_mod, p->y); + sp_384_norm_6(negy); + sp_384_cond_copy_6(p->y, negy, 0 - v[i].neg); + sp_384_proj_point_add_qz1_avx2_6(rt, rt, p, tmp); + } + if (map != 0) { + sp_384_map_avx2_6(r, rt, tmp); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_384)); + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (tmp != NULL) { + XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 6 * 6); + XFREE(tmp, heap, DYNAMIC_TYPE_ECC); + } +#else + ForceZero(tmp, sizeof(sp_digit) * 2 * 6 * 6); +#endif + sp_384_point_free_6(p, 0, heap); + sp_384_point_free_6(rt, 0, heap); + + return MP_OKAY; +} + +/* Multiply the base point of P384 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * r Resulting point. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_base_avx2_6(sp_point_384* r, const sp_digit* k, + int map, int ct, void* heap) +{ + return sp_384_ecc_mulmod_add_only_avx2_6(r, NULL, p384_table, + k, map, ct, heap); +} + +#endif /* HAVE_INTEL_AVX2 */ +#endif /* WOLFSSL_SP_SMALL */ /* Multiply the base point of P384 by the scalar and return the result. * If map is true then convert result to affine coordinates. * @@ -29396,7 +47381,7 @@ static int sp_384_ecc_mulmod_base_avx2_6(sp_point_384* r, const sp_digit* k, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_mulmod_base_384(mp_int* km, ecc_point* r, int map, void* heap) +int sp_ecc_mulmod_base_384(const mp_int* km, ecc_point* r, int map, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_384 p; @@ -29445,6 +47430,105 @@ int sp_ecc_mulmod_base_384(mp_int* km, ecc_point* r, int map, void* heap) return err; } +/* Multiply the base point of P384 by the scalar, add point a and return + * the result. If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_add_384(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_384 p; + sp_point_384 a; + sp_digit kd[6]; + sp_digit t[6 * 2 * 6]; +#endif + sp_point_384* point; + sp_point_384* addP = NULL; + sp_digit* tmp = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + + err = sp_384_point_new_6(heap, p, point); + if (err == MP_OKAY) { + err = sp_384_point_new_6(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (6 + 6 * 2 * 6), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 6; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 6, km); + sp_384_point_from_ecc_point_6(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_6(addP->x, addP->x, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_6(addP->y, addP->y, p384_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_384_mod_mul_norm_6(addP->z, addP->z, p384_mod); + } + if (err == MP_OKAY) { +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + err = sp_384_ecc_mulmod_base_avx2_6(point, k, 0, 0, heap); + else +#endif + err = sp_384_ecc_mulmod_base_6(point, k, 0, 0, heap); + } + if (err == MP_OKAY) { +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_384_proj_point_add_avx2_6(point, point, addP, tmp); + else +#endif + sp_384_proj_point_add_6(point, point, addP, tmp); + + if (map) { +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_384_map_avx2_6(point, point, tmp); + else +#endif + sp_384_map_6(point, point, tmp); + } + + err = sp_384_point_to_ecc_point_6(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_6(addP, 0, heap); + sp_384_point_free_6(point, 0, heap); + + return err; +} + #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \ defined(HAVE_ECC_VERIFY) /* Returns 1 if the number of zero. @@ -29458,7 +47542,7 @@ static int sp_384_iszero_6(const sp_digit* a) return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5]) == 0; } -#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN | HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ extern void sp_384_add_one_6(sp_digit* a); extern void sp_384_from_bin_bswap(sp_digit* r, int size, const byte* a, int n); extern void sp_384_from_bin_movbe(sp_digit* r, int size, const byte* a, int n); @@ -29471,12 +47555,15 @@ extern void sp_384_from_bin_movbe(sp_digit* r, int size, const byte* a, int n); */ static void sp_384_from_bin(sp_digit* r, int size, const byte* a, int n) { +#ifndef NO_MOVBE_SUPPORT word32 cpuid_flags = cpuid_get_flags(); if (IS_INTEL_MOVBE(cpuid_flags)) { sp_384_from_bin_movbe(r, size, a, n); } - else { + else +#endif + { sp_384_from_bin_bswap(r, size, a, n); } } @@ -29617,12 +47704,15 @@ extern void sp_384_to_bin_movbe(sp_digit* r, byte* a); */ static void sp_384_to_bin(sp_digit* r, byte* a) { +#ifndef NO_MOVBE_SUPPORT word32 cpuid_flags = cpuid_get_flags(); if (IS_INTEL_MOVBE(cpuid_flags)) { sp_384_to_bin_movbe(r, a); } - else { + else +#endif + { sp_384_to_bin_bswap(r, a); } } @@ -29639,7 +47729,7 @@ static void sp_384_to_bin(sp_digit* r, byte* a) * returns BUFFER_E if the buffer is to small for output size, * MEMORY_E when memory allocation fails and MP_OKAY on success. */ -int sp_ecc_secret_gen_384(mp_int* priv, ecc_point* pub, byte* out, +int sp_ecc_secret_gen_384(const mp_int* priv, const ecc_point* pub, byte* out, word32* outLen, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) @@ -29703,9 +47793,29 @@ int sp_ecc_secret_gen_384(mp_int* priv, ecc_point* pub, byte* out, #endif #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) extern sp_digit sp_384_sub_in_place_6(sp_digit* a, const sp_digit* b); -extern sp_digit sp_384_cond_sub_avx2_6(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m); extern void sp_384_mul_d_6(sp_digit* r, const sp_digit* a, sp_digit b); extern void sp_384_mul_d_avx2_6(sp_digit* r, const sp_digit* a, const sp_digit b); +#ifdef _WIN64 +#if _MSC_VER < 1920 +extern sp_digit div_384_word_asm_6(sp_digit d1, sp_digit d0, sp_digit div); +#endif /* _MSC_VER < 1920 */ +/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) + * + * d1 The high order half of the number to divide. + * d0 The low order half of the number to divide. + * div The dividend. + * returns the result of the division. + */ +static WC_INLINE sp_digit div_384_word_6(sp_digit d1, sp_digit d0, + sp_digit div) +{ +#if _MSC_VER >= 1920 + return _udiv128(d1, d0, div, NULL); +#else + return div_384_word_asm_6(d1, d0, div); +#endif +} +#else /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) * * d1 The high order half of the number to divide. @@ -29725,6 +47835,7 @@ static WC_INLINE sp_digit div_384_word_6(sp_digit d1, sp_digit d0, ); return r; } +#endif /* _WIN64 */ /* AND m into each word of a and store in r. * * r A single precision integer. @@ -29761,8 +47872,10 @@ static void sp_384_mask_6(sp_digit* r, const sp_digit* a, sp_digit m) static WC_INLINE int sp_384_div_6(const sp_digit* a, const sp_digit* d, sp_digit* m, sp_digit* r) { - sp_digit t1[12], t2[7]; - sp_digit div, r1; + sp_digit t1[12]; + sp_digit t2[7]; + sp_digit div; + sp_digit r1; int i; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); @@ -29815,7 +47928,8 @@ static WC_INLINE int sp_384_div_6(const sp_digit* a, const sp_digit* d, sp_digit * m A single precision number that is the modulus to reduce with. * returns MP_OKAY indicating success. */ -static WC_INLINE int sp_384_mod_6(sp_digit* r, const sp_digit* a, const sp_digit* m) +static WC_INLINE int sp_384_mod_6(sp_digit* r, const sp_digit* a, + const sp_digit* m) { return sp_384_div_6(a, m, NULL, r); } @@ -29832,7 +47946,6 @@ static const uint64_t p384_order_minus_2[6] = { /* The low half of the order-2 of the P384 curve. */ static const uint64_t p384_order_low[3] = { 0xecec196accc52971U,0x581a0db248b0a77aU,0xc7634d81f4372ddfU - }; #endif /* WOLFSSL_SP_SMALL */ @@ -29980,7 +48093,7 @@ static void sp_384_mont_inv_order_6(sp_digit* r, const sp_digit* a, sp_384_mont_mul_order_6(t2, t2, t); for (i=191; i>=1; i--) { sp_384_mont_sqr_order_6(t2, t2); - if (((sp_digit)p384_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { + if ((p384_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { sp_384_mont_mul_order_6(t2, t2, a); } } @@ -30134,7 +48247,7 @@ static void sp_384_mont_inv_order_avx2_6(sp_digit* r, const sp_digit* a, sp_384_mont_mul_order_avx2_6(t2, t2, t); for (i=191; i>=1; i--) { sp_384_mont_sqr_order_avx2_6(t2, t2); - if (((sp_digit)p384_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { + if ((p384_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { sp_384_mont_mul_order_avx2_6(t2, t2, a); } } @@ -30144,12 +48257,86 @@ static void sp_384_mont_inv_order_avx2_6(sp_digit* r, const sp_digit* a, } #endif /* HAVE_INTEL_AVX2 */ -#endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +#endif /* HAVE_ECC_SIGN | HAVE_ECC_VERIFY */ #ifdef HAVE_ECC_SIGN #ifndef SP_ECC_MAX_SIG_GEN #define SP_ECC_MAX_SIG_GEN 64 #endif +/* Calculate second signature value S from R, k and private value. + * + * s = (r * x + e) / k + * + * s Signature value. + * r First signature value. + * k Ephemeral private key. + * x Private key as a number. + * e Hash of message as a number. + * tmp Temporary storage for intermediate numbers. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_calc_s_6(sp_digit* s, const sp_digit* r, sp_digit* k, + sp_digit* x, const sp_digit* e, sp_digit* tmp) +{ + int err; + sp_digit carry; + int64_t c; + sp_digit* kInv = k; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + + /* Conv k to Montgomery form (mod order) */ +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_384_mul_avx2_6(k, k, p384_norm_order); + else +#endif + sp_384_mul_6(k, k, p384_norm_order); + err = sp_384_mod_6(k, k, p384_order); + if (err == MP_OKAY) { + sp_384_norm_6(k); + + /* kInv = 1/k mod order */ +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_384_mont_inv_order_avx2_6(kInv, k, tmp); + else +#endif + sp_384_mont_inv_order_6(kInv, k, tmp); + sp_384_norm_6(kInv); + + /* s = r * x + e */ +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_384_mul_avx2_6(x, x, r); + else +#endif + sp_384_mul_6(x, x, r); + err = sp_384_mod_6(x, x, p384_order); + } + if (err == MP_OKAY) { + sp_384_norm_6(x); + carry = sp_384_add_6(s, e, x); + sp_384_cond_sub_6(s, s, p384_order, 0 - carry); + sp_384_norm_6(s); + c = sp_384_cmp_6(s, p384_order); + sp_384_cond_sub_6(s, s, p384_order, 0L - (sp_digit)(c >= 0)); + sp_384_norm_6(s); + + /* s = s * k^-1 mod order */ +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_384_mont_mul_order_avx2_6(s, s, kInv); + else +#endif + sp_384_mont_mul_order_6(s, s, kInv); + sp_384_norm_6(s); + } + + return err; +} + /* Sign the hash using the private key. * e = [hash, 384 bits] from binary * r = (k.G)->x mod order @@ -30184,8 +48371,8 @@ typedef struct sp_ecc_sign_384_ctx { int i; } sp_ecc_sign_384_ctx; -int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, WC_RNG* rng, + mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_sign_384_ctx* ctx = (sp_ecc_sign_384_ctx*)sp_ctx->data; @@ -30325,8 +48512,8 @@ int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, W } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap) +int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, + const mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -30344,11 +48531,9 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit* r = NULL; sp_digit* tmp = NULL; sp_point_384* point = NULL; - sp_digit carry; sp_digit* s = NULL; - sp_digit* kInv = NULL; - int err = MP_OKAY; int64_t c; + int err = MP_OKAY; int i; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); @@ -30382,7 +48567,6 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, tmp = td; #endif s = e; - kInv = k; if (hashLen > 48U) { hashLen = 48U; @@ -30390,8 +48574,6 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, } for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) { - sp_384_from_mp(x, 6, priv); - /* New random point. */ if (km == NULL || mp_iszero(km)) { err = sp_384_ecc_gen_k_6(rng, k); @@ -30406,7 +48588,7 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, err = sp_384_ecc_mulmod_base_avx2_6(point, k, 1, 1, heap); else #endif - err = sp_384_ecc_mulmod_base_6(point, k, 1, 1, NULL); + err = sp_384_ecc_mulmod_base_6(point, k, 1, 1, heap); } if (err == MP_OKAY) { @@ -30417,58 +48599,15 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_384_cond_sub_6(r, r, p384_order, 0L - (sp_digit)(c >= 0)); sp_384_norm_6(r); - /* Conv k to Montgomery form (mod order) */ -#ifdef HAVE_INTEL_AVX2 - if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) - sp_384_mul_avx2_6(k, k, p384_norm_order); - else -#endif - sp_384_mul_6(k, k, p384_norm_order); - err = sp_384_mod_6(k, k, p384_order); - } - if (err == MP_OKAY) { - sp_384_norm_6(k); - /* kInv = 1/k mod order */ -#ifdef HAVE_INTEL_AVX2 - if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) - sp_384_mont_inv_order_avx2_6(kInv, k, tmp); - else -#endif - sp_384_mont_inv_order_6(kInv, k, tmp); - sp_384_norm_6(kInv); - - /* s = r * x + e */ -#ifdef HAVE_INTEL_AVX2 - if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) - sp_384_mul_avx2_6(x, x, r); - else -#endif - sp_384_mul_6(x, x, r); - err = sp_384_mod_6(x, x, p384_order); - } - if (err == MP_OKAY) { - sp_384_norm_6(x); + sp_384_from_mp(x, 6, priv); sp_384_from_bin(e, 6, hash, (int)hashLen); - carry = sp_384_add_6(s, e, x); - sp_384_cond_sub_6(s, s, p384_order, 0 - carry); - sp_384_norm_6(s); - c = sp_384_cmp_6(s, p384_order); - sp_384_cond_sub_6(s, s, p384_order, 0L - (sp_digit)(c >= 0)); - sp_384_norm_6(s); - /* s = s * k^-1 mod order */ -#ifdef HAVE_INTEL_AVX2 - if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) - sp_384_mont_mul_order_avx2_6(s, s, kInv); - else -#endif - sp_384_mont_mul_order_6(s, s, kInv); - sp_384_norm_6(s); + err = sp_384_calc_s_6(s, r, k, x, e, tmp); + } - /* Check that signature is usable. */ - if (sp_384_iszero_6(s) == 0) { - break; - } + /* Check that signature is usable. */ + if ((err == MP_OKAY) && (sp_384_iszero_6(s) == 0)) { + break; } #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP i = 1; @@ -30496,7 +48635,6 @@ int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, XMEMSET(x, 0, sizeof(sp_digit) * 2U * 6U); XMEMSET(k, 0, sizeof(sp_digit) * 2U * 6U); XMEMSET(r, 0, sizeof(sp_digit) * 2U * 6U); - XMEMSET(r, 0, sizeof(sp_digit) * 2U * 6U); XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 6U); #endif sp_384_point_free_6(point, 1, heap); @@ -30590,6 +48728,143 @@ static int sp_384_mod_inv_6(sp_digit* r, const sp_digit* a, const sp_digit* m) } #endif /* WOLFSSL_SP_SMALL */ + +/* Add point p1 into point p2. Handles p1 == p2 and result at infinity. + * + * p1 First point to add and holds result. + * p2 Second point to add. + * tmp Temporary storage for intermediate numbers. + */ +static void sp_384_add_points_6(sp_point_384* p1, const sp_point_384* p2, + sp_digit* tmp) +{ +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { + sp_384_proj_point_add_avx2_6(p1, p1, p2, tmp); + } + else +#endif + sp_384_proj_point_add_6(p1, p1, p2, tmp); + if (sp_384_iszero_6(p1->z)) { + if (sp_384_iszero_6(p1->x) && sp_384_iszero_6(p1->y)) { +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { + sp_384_proj_point_dbl_avx2_6(p1, p2, tmp); + } + else +#endif + sp_384_proj_point_dbl_6(p1, p2, tmp); + } + else { + /* Y ordinate is not used from here - don't set. */ + p1->x[0] = 0; + p1->x[1] = 0; + p1->x[2] = 0; + p1->x[3] = 0; + p1->x[4] = 0; + p1->x[5] = 0; + XMEMCPY(p1->z, p384_norm_mod, sizeof(p384_norm_mod)); + } + } +} + +/* Calculate the verification point: [e/s]G + [r/s]Q + * + * p1 Calculated point. + * p2 Public point and temporary. + * s Second part of signature as a number. + * u1 Temporary number. + * u2 Temproray number. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_calc_vfy_point_6(sp_point_384* p1, sp_point_384* p2, + sp_digit* s, sp_digit* u1, sp_digit* u2, sp_digit* tmp, void* heap) +{ + int err; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + +#ifndef WOLFSSL_SP_SMALL + { + sp_384_mod_inv_6(s, s, p384_order); + } +#endif /* !WOLFSSL_SP_SMALL */ +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { + sp_384_mul_avx2_6(s, s, p384_norm_order); + } + else +#endif + { + sp_384_mul_6(s, s, p384_norm_order); + } + err = sp_384_mod_6(s, s, p384_order); + if (err == MP_OKAY) { + sp_384_norm_6(s); +#ifdef WOLFSSL_SP_SMALL +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { + sp_384_mont_inv_order_avx2_6(s, s, tmp); + sp_384_mont_mul_order_avx2_6(u1, u1, s); + sp_384_mont_mul_order_avx2_6(u2, u2, s); + } + else +#endif + { + sp_384_mont_inv_order_6(s, s, tmp); + sp_384_mont_mul_order_6(u1, u1, s); + sp_384_mont_mul_order_6(u2, u2, s); + } + +#else +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { + sp_384_mont_mul_order_avx2_6(u1, u1, s); + sp_384_mont_mul_order_avx2_6(u2, u2, s); + } + else +#endif + { + sp_384_mont_mul_order_6(u1, u1, s); + sp_384_mont_mul_order_6(u2, u2, s); + } + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + err = sp_384_ecc_mulmod_base_avx2_6(p1, u1, 0, 0, heap); + else +#endif + err = sp_384_ecc_mulmod_base_6(p1, u1, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_384_iszero_6(p1->z)) { + p1->infinity = 1; + } + if (err == MP_OKAY) { +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + err = sp_384_ecc_mulmod_avx2_6(p2, p2, u2, 0, 0, heap); + else +#endif + err = sp_384_ecc_mulmod_6(p2, p2, u2, 0, 0, heap); + } + if ((err == MP_OKAY) && sp_384_iszero_6(p2->z)) { + p2->infinity = 1; + } + + if (err == MP_OKAY) { + sp_384_add_points_6(p1, p2, tmp); + } + + return err; +} + #ifdef HAVE_ECC_VERIFY /* Verify the signature values with the hash and public key. * e = Truncate(hash, 384) @@ -30608,8 +48883,7 @@ static int sp_384_mod_inv_6(sp_digit* r, const sp_digit* a, const sp_digit* m) * rm First part of result as an mp_int. * sm Sirst part of result as an mp_int. * heap Heap to use for allocation. - * returns RNG failures, MEMORY_E when memory allocation fails and - * MP_OKAY on success. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ #ifdef WOLFSSL_SP_NONBLOCK typedef struct sp_ecc_verify_384_ctx { @@ -30628,8 +48902,9 @@ typedef struct sp_ecc_verify_384_ctx { sp_point_384 p2; } sp_ecc_verify_384_ctx; -int sp_ecc_verify_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, + word32 hashLen, const mp_int* pX, const mp_int* pY, const mp_int* pZ, + const mp_int* r, const mp_int* sm, int* res, void* heap) { int err = FP_WOULDBLOCK; sp_ecc_verify_384_ctx* ctx = (sp_ecc_verify_384_ctx*)sp_ctx->data; @@ -30783,8 +49058,9 @@ int sp_ecc_verify_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, } #endif /* WOLFSSL_SP_NONBLOCK */ -int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, - mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap) +int sp_ecc_verify_384(const byte* hash, word32 hashLen, const mp_int* pX, + const mp_int* pY, const mp_int* pZ, const mp_int* r, const mp_int* sm, + int* res, void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -30803,11 +49079,8 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, sp_point_384* p1; sp_point_384* p2 = NULL; sp_digit carry; - int64_t c; + int64_t c = 0; int err; -#ifdef HAVE_INTEL_AVX2 - word32 cpuid_flags = cpuid_get_flags(); -#endif err = sp_384_point_new_6(heap, p1d, p1); if (err == MP_OKAY) { @@ -30847,116 +49120,9 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, sp_384_from_mp(p2->y, 6, pY); sp_384_from_mp(p2->z, 6, pZ); -#ifndef WOLFSSL_SP_SMALL - { - sp_384_mod_inv_6(s, s, p384_order); - } -#endif /* !WOLFSSL_SP_SMALL */ -#ifdef HAVE_INTEL_AVX2 - if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { - sp_384_mul_avx2_6(s, s, p384_norm_order); - } - else -#endif - { - sp_384_mul_6(s, s, p384_norm_order); - } - err = sp_384_mod_6(s, s, p384_order); + err = sp_384_calc_vfy_point_6(p1, p2, s, u1, u2, tmp, heap); } if (err == MP_OKAY) { - sp_384_norm_6(s); -#ifdef WOLFSSL_SP_SMALL -#ifdef HAVE_INTEL_AVX2 - if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { - sp_384_mont_inv_order_avx2_6(s, s, tmp); - sp_384_mont_mul_order_avx2_6(u1, u1, s); - sp_384_mont_mul_order_avx2_6(u2, u2, s); - } - else -#endif - { - sp_384_mont_inv_order_6(s, s, tmp); - sp_384_mont_mul_order_6(u1, u1, s); - sp_384_mont_mul_order_6(u2, u2, s); - } - -#else -#ifdef HAVE_INTEL_AVX2 - if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { - sp_384_mont_mul_order_avx2_6(u1, u1, s); - sp_384_mont_mul_order_avx2_6(u2, u2, s); - } - else -#endif - { - sp_384_mont_mul_order_6(u1, u1, s); - sp_384_mont_mul_order_6(u2, u2, s); - } - -#endif /* WOLFSSL_SP_SMALL */ -#ifdef HAVE_INTEL_AVX2 - if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) - err = sp_384_ecc_mulmod_base_avx2_6(p1, u1, 0, 0, heap); - else -#endif - err = sp_384_ecc_mulmod_base_6(p1, u1, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_384_iszero_6(p1->z)) { - p1->infinity = 1; - } - if (err == MP_OKAY) { -#ifdef HAVE_INTEL_AVX2 - if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) - err = sp_384_ecc_mulmod_avx2_6(p2, p2, u2, 0, 0, heap); - else -#endif - err = sp_384_ecc_mulmod_6(p2, p2, u2, 0, 0, heap); - } - if ((err == MP_OKAY) && sp_384_iszero_6(p2->z)) { - p2->infinity = 1; - } - - if (err == MP_OKAY) { -#ifdef HAVE_INTEL_AVX2 - if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { - sp_384_proj_point_add_avx2_6(p1, p1, p2, tmp); - if (sp_384_iszero_6(p1->z)) { - if (sp_384_iszero_6(p1->x) && sp_384_iszero_6(p1->y)) { - sp_384_proj_point_dbl_avx2_6(p1, p2, tmp); - } - else { - /* Y ordinate is not used from here - don't set. */ - p1->x[0] = 0; - p1->x[1] = 0; - p1->x[2] = 0; - p1->x[3] = 0; - p1->x[4] = 0; - p1->x[5] = 0; - XMEMCPY(p1->z, p384_norm_mod, sizeof(p384_norm_mod)); - } - } - } - else -#endif - { - sp_384_proj_point_add_6(p1, p1, p2, tmp); - if (sp_384_iszero_6(p1->z)) { - if (sp_384_iszero_6(p1->x) && sp_384_iszero_6(p1->y)) { - sp_384_proj_point_dbl_6(p1, p2, tmp); - } - else { - /* Y ordinate is not used from here - don't set. */ - p1->x[0] = 0; - p1->x[1] = 0; - p1->x[2] = 0; - p1->x[3] = 0; - p1->x[4] = 0; - p1->x[5] = 0; - XMEMCPY(p1->z, p384_norm_mod, sizeof(p384_norm_mod)); - } - } - } - /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */ /* Reload r and convert to Montgomery form. */ sp_384_from_mp(u2, 6, r); @@ -30978,16 +49144,16 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, /* Compare with mod and if greater or equal then not valid. */ c = sp_384_cmp_6(u2, p384_mod); - if (c < 0) { - /* Convert to Montogomery form */ - err = sp_384_mod_mul_norm_6(u2, u2, p384_mod); - if (err == MP_OKAY) { - /* u1 = (r + 1*order).z'.z' mod prime */ - sp_384_mont_mul_6(u1, u2, p1->z, p384_mod, - p384_mp_mod); - *res = (int)(sp_384_cmp_6(p1->x, u1) == 0); - } - } + } + } + if ((*res == 0) && (c < 0)) { + /* Convert to Montogomery form */ + err = sp_384_mod_mul_norm_6(u2, u2, p384_mod); + if (err == MP_OKAY) { + /* u1 = (r + 1*order).z'.z' mod prime */ + sp_384_mont_mul_6(u1, u2, p1->z, p384_mod, + p384_mp_mod); + *res = (sp_384_cmp_6(p1->x, u1) == 0); } } } @@ -31011,7 +49177,8 @@ int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX, * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -static int sp_384_ecc_is_point_6(sp_point_384* point, void* heap) +static int sp_384_ecc_is_point_6(const sp_point_384* point, + void* heap) { #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) sp_digit* d = NULL; @@ -31074,7 +49241,7 @@ static int sp_384_ecc_is_point_6(sp_point_384* point, void* heap) * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is * not on the curve and MP_OKAY otherwise. */ -int sp_ecc_is_point_384(mp_int* pX, mp_int* pY) +int sp_ecc_is_point_384(const mp_int* pX, const mp_int* pY) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_point_384 pubd; @@ -31108,7 +49275,8 @@ int sp_ecc_is_point_384(mp_int* pX, mp_int* pY) * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and * MP_OKAY otherwise. */ -int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) +int sp_ecc_check_key_384(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap) { #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) sp_digit privd[6]; @@ -31165,12 +49333,11 @@ int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) } } - if (err == MP_OKAY) { - /* Check range of X and Y */ - if (sp_384_cmp_6(pub->x, p384_mod) >= 0 || - sp_384_cmp_6(pub->y, p384_mod) >= 0) { - err = ECC_OUT_OF_RANGE_E; - } + /* Check range of X and Y */ + if ((err == MP_OKAY) && + ((sp_384_cmp_6(pub->x, p384_mod) >= 0) || + (sp_384_cmp_6(pub->y, p384_mod) >= 0))) { + err = ECC_OUT_OF_RANGE_E; } if (err == MP_OKAY) { @@ -31187,12 +49354,10 @@ int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) #endif err = sp_384_ecc_mulmod_6(p, pub, p384_order, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is infinity */ - if ((sp_384_iszero_6(p->x) == 0) || - (sp_384_iszero_6(p->y) == 0)) { - err = ECC_INF_E; - } + /* Check result is infinity */ + if ((err == MP_OKAY) && ((sp_384_iszero_6(p->x) == 0) || + (sp_384_iszero_6(p->y) == 0))) { + err = ECC_INF_E; } if (privm) { @@ -31205,12 +49370,11 @@ int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) #endif err = sp_384_ecc_mulmod_base_6(p, priv, 1, 1, heap); } - if (err == MP_OKAY) { - /* Check result is public key */ - if (sp_384_cmp_6(p->x, pub->x) != 0 || - sp_384_cmp_6(p->y, pub->y) != 0) { - err = ECC_PRIV_KEY_E; - } + /* Check result is public key */ + if ((err == MP_OKAY) && + ((sp_384_cmp_6(p->x, pub->x) != 0) || + (sp_384_cmp_6(p->y, pub->y) != 0))) { + err = ECC_PRIV_KEY_E; } } @@ -31398,6 +49562,9 @@ int sp_ecc_map_384(mp_int* pX, mp_int* pY, mp_int* pZ) sp_digit* tmp = NULL; sp_point_384* p; int err; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif err = sp_384_point_new_6(NULL, pd, p); #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) @@ -31416,7 +49583,12 @@ int sp_ecc_map_384(mp_int* pX, mp_int* pY, mp_int* pZ) sp_384_from_mp(p->y, 6, pY); sp_384_from_mp(p->z, 6, pZ); - sp_384_map_6(p, p, tmp); +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_384_map_avx2_6(point, point, tmp); + else +#endif + sp_384_map_6(p, p, tmp); } if (err == MP_OKAY) { @@ -31701,6 +49873,12255 @@ int sp_ecc_uncompress_384(mp_int* xm, int odd, mp_int* ym) } #endif #endif /* WOLFSSL_SP_384 */ +#ifdef WOLFSSL_SP_1024 + +/* Point structure to use. */ +typedef struct sp_point_1024 { + /* X ordinate of point. */ + sp_digit x[2 * 16]; + /* Y ordinate of point. */ + sp_digit y[2 * 16]; + /* Z ordinate of point. */ + sp_digit z[2 * 16]; + /* Indicates point is at infinity. */ + int infinity; +} sp_point_1024; + +extern void sp_1024_mul_16(sp_digit* r, const sp_digit* a, const sp_digit* b); +extern void sp_1024_sqr_16(sp_digit* r, const sp_digit* a); +extern void sp_1024_mul_avx2_16(sp_digit* r, const sp_digit* a, const sp_digit* b); +extern void sp_1024_sqr_avx2_16(sp_digit* r, const sp_digit* a); +/* The modulus (prime) of the curve P1024. */ +static const sp_digit p1024_mod[16] = { + 0x666d807afea85febL,0x80c5df10ac7ace87L,0xfce3e82389857db0L, + 0x9f94d6af56971f1fL,0xa7cf3c521c3c09aaL,0xb6aff4a831852a82L, + 0x512ac5cd65681ce1L,0xe26c6487326b4cd4L,0x356d27f4a666a6d0L, + 0xe791b39ff7c88a19L,0x228730d531a59cb0L,0xf40aab27e2fc0f1bL, + 0xbe9ae358b3e01a2eL,0x416c0ce19cb48261L,0x65c61198dad0657aL, + 0x997abb1f0a563fdaL +}; +/* The Montogmery normalizer for modulus of the curve P1024. */ +static const sp_digit p1024_norm_mod[16] = { + 0x99927f850157a015L,0x7f3a20ef53853178L,0x031c17dc767a824fL, + 0x606b2950a968e0e0L,0x5830c3ade3c3f655L,0x49500b57ce7ad57dL, + 0xaed53a329a97e31eL,0x1d939b78cd94b32bL,0xca92d80b5999592fL, + 0x186e4c60083775e6L,0xdd78cf2ace5a634fL,0x0bf554d81d03f0e4L, + 0x41651ca74c1fe5d1L,0xbe93f31e634b7d9eL,0x9a39ee67252f9a85L, + 0x668544e0f5a9c025L +}; +/* The Montogmery multiplier for modulus of the curve P1024. */ +static sp_digit p1024_mp_mod = 0x290420077c8f2f3d; +#if defined(WOLFSSL_SP_SMALL) || defined(HAVE_ECC_CHECK_KEY) +/* The order of the curve P1024. */ +static const sp_digit p1024_order[16] = { + 0xd99b601ebfaa17fbL,0x203177c42b1eb3a1L,0xff38fa08e2615f6cL, + 0xa7e535abd5a5c7c7L,0xa9f3cf14870f026aL,0x6dabfd2a0c614aa0L, + 0x144ab173595a0738L,0x389b1921cc9ad335L,0x4d5b49fd2999a9b4L, + 0x39e46ce7fdf22286L,0xc8a1cc354c69672cL,0xbd02aac9f8bf03c6L, + 0x6fa6b8d62cf8068bL,0x905b0338672d2098L,0x9971846636b4195eL, + 0x265eaec7c2958ff6L +}; +#endif +/* The base point of curve P1024. */ +static const sp_point_1024 p1024_base = { + /* X ordinate */ + { + 0x880dc8abeae63895L,0x80ec46c4967e0979L,0xee9163a5b63f73ecL, + 0xd5cfb4cc80728d87L,0xa7c1514dba66910dL,0xa702c3397a60de74L, + 0x337c86548b72f2e1L,0x9760af765dd5bccbL,0x718bd9e7406ce890L, + 0x43d5f22cdb9dfa55L,0xab10db9030b09e10L,0xb5edb6c0f6ce2308L, + 0x98b2f204b6ff7cbfL,0x2b1a2fd60aec69c6L,0x0a7990053ed9b52aL, + 0x53fc09ee332c29adL, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* Y ordinate */ + { + 0x75573fd71bef16d7L,0xadb9b5706a67dcdeL,0x80bdad5ad5bb4636L, + 0x13515ad7e9cb99a9L,0x492d979fc5a4d5f2L,0xac6f1e80164aa989L, + 0xcad696b5b7652fe0L,0x70dae117ad547c6cL,0x416cff0ca9e032b9L, + 0x6b598ccf9a140b2eL,0xe7f7f5e5f0de55f6L,0xf5ea69f4654ec2b9L, + 0x3d778d821e141178L,0xd3e8201602990696L,0xf9f1f0533634a135L, + 0x0a8249063f6009f1L, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* Z ordinate */ + { + 0x0000000000000001L,0x0000000000000000L,0x0000000000000000L, + 0x0000000000000000L,0x0000000000000000L,0x0000000000000000L, + 0x0000000000000000L,0x0000000000000000L,0x0000000000000000L, + 0x0000000000000000L,0x0000000000000000L,0x0000000000000000L, + 0x0000000000000000L,0x0000000000000000L,0x0000000000000000L, + 0x0000000000000000L, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* infinity */ + 0 +}; + +extern sp_digit sp_1024_add_16(sp_digit* r, const sp_digit* a, const sp_digit* b); +extern sp_digit sp_1024_sub_in_place_16(sp_digit* a, const sp_digit* b); +extern sp_digit sp_1024_cond_sub_16(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m); +extern sp_digit sp_1024_cond_sub_avx2_16(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m); +extern void sp_1024_mul_d_16(sp_digit* r, const sp_digit* a, sp_digit b); +extern void sp_1024_mul_d_avx2_16(sp_digit* r, const sp_digit* a, const sp_digit b); +#ifdef _WIN64 +#if _MSC_VER < 1920 +extern sp_digit div_1024_word_asm_16(sp_digit d1, sp_digit d0, sp_digit div); +#endif /* _MSC_VER < 1920 */ +/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) + * + * d1 The high order half of the number to divide. + * d0 The low order half of the number to divide. + * div The dividend. + * returns the result of the division. + */ +static WC_INLINE sp_digit div_1024_word_16(sp_digit d1, sp_digit d0, + sp_digit div) +{ +#if _MSC_VER >= 1920 + return _udiv128(d1, d0, div, NULL); +#else + return div_1024_word_asm_16(d1, d0, div); +#endif +} +#else +/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) + * + * d1 The high order half of the number to divide. + * d0 The low order half of the number to divide. + * div The dividend. + * returns the result of the division. + */ +static WC_INLINE sp_digit div_1024_word_16(sp_digit d1, sp_digit d0, + sp_digit div) +{ + register sp_digit r asm("rax"); + __asm__ __volatile__ ( + "divq %3" + : "=a" (r) + : "d" (d1), "a" (d0), "r" (div) + : + ); + return r; +} +#endif /* _WIN64 */ +/* AND m into each word of a and store in r. + * + * r A single precision integer. + * a A single precision integer. + * m Mask to AND against each digit. + */ +static void sp_1024_mask_16(sp_digit* r, const sp_digit* a, sp_digit m) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i=0; i<16; i++) { + r[i] = a[i] & m; + } +#else + int i; + + for (i = 0; i < 16; i += 8) { + r[i+0] = a[i+0] & m; + r[i+1] = a[i+1] & m; + r[i+2] = a[i+2] & m; + r[i+3] = a[i+3] & m; + r[i+4] = a[i+4] & m; + r[i+5] = a[i+5] & m; + r[i+6] = a[i+6] & m; + r[i+7] = a[i+7] & m; + } +#endif +} + +extern int64_t sp_1024_cmp_16(const sp_digit* a, const sp_digit* b); +/* Divide d in a and put remainder into r (m*d + r = a) + * m is not calculated as it is not needed at this time. + * + * a Number to be divided. + * d Number to divide with. + * m Multiplier result. + * r Remainder from the division. + * returns MP_OKAY indicating success. + */ +static WC_INLINE int sp_1024_div_16(const sp_digit* a, const sp_digit* d, sp_digit* m, + sp_digit* r) +{ + sp_digit t1[32]; + sp_digit t2[17]; + sp_digit div; + sp_digit r1; + int i; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + + (void)m; + + div = d[15]; + XMEMCPY(t1, a, sizeof(*t1) * 2 * 16); + r1 = sp_1024_cmp_16(&t1[16], d) >= 0; +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_1024_cond_sub_avx2_16(&t1[16], &t1[16], d, (sp_digit)0 - r1); + else +#endif + sp_1024_cond_sub_16(&t1[16], &t1[16], d, (sp_digit)0 - r1); + for (i=15; i>=0; i--) { + sp_digit hi = t1[16 + i] - (t1[16 + i] == div); + r1 = div_1024_word_16(hi, t1[16 + i - 1], div); + +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_1024_mul_d_avx2_16(t2, d, r1); + else +#endif + sp_1024_mul_d_16(t2, d, r1); + t1[16 + i] += sp_1024_sub_in_place_16(&t1[i], t2); + t1[16 + i] -= t2[16]; + sp_1024_mask_16(t2, d, t1[16 + i]); + t1[16 + i] += sp_1024_add_16(&t1[i], &t1[i], t2); + sp_1024_mask_16(t2, d, t1[16 + i]); + t1[16 + i] += sp_1024_add_16(&t1[i], &t1[i], t2); + } + + r1 = sp_1024_cmp_16(t1, d) >= 0; +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_1024_cond_sub_avx2_16(r, t1, d, (sp_digit)0 - r1); + else +#endif + sp_1024_cond_sub_16(r, t1, d, (sp_digit)0 - r1); + + return MP_OKAY; +} + +/* Reduce a modulo m into r. (r = a mod m) + * + * r A single precision number that is the reduced result. + * a A single precision number that is to be reduced. + * m A single precision number that is the modulus to reduce with. + * returns MP_OKAY indicating success. + */ +static WC_INLINE int sp_1024_mod_16(sp_digit* r, const sp_digit* a, + const sp_digit* m) +{ + return sp_1024_div_16(a, m, NULL, r); +} + +/* Multiply a number by Montogmery normalizer mod modulus (prime). + * + * r The resulting Montgomery form number. + * a The number to convert. + * m The modulus (prime). + * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. + */ +static int sp_1024_mod_mul_norm_16(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_1024_mul_16(r, a, p1024_norm_mod); + return sp_1024_mod_16(r, r, m); +} + +#ifdef HAVE_INTEL_AVX2 +/* Multiply a number by Montogmery normalizer mod modulus (prime). + * + * r The resulting Montgomery form number. + * a The number to convert. + * m The modulus (prime). + * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise. + */ +static int sp_1024_mod_mul_norm_avx2_16(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_1024_mul_avx2_16(r, a, p1024_norm_mod); + return sp_1024_mod_16(r, r, m); +} + +#endif /* HAVE_INTEL_AVX2 */ +/* Create a new point. + * + * heap [in] Buffer to allocate dynamic memory from. + * sp [in] Data for point - only if not allocating. + * p [out] New point. + * returns MEMORY_E when dynamic memory allocation fails and 0 otherwise. + */ +static int sp_1024_point_new_ex_16(void* heap, sp_point_1024* sp, + sp_point_1024** p) +{ + int ret = MP_OKAY; + (void)heap; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + (void)sp; + *p = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024), heap, DYNAMIC_TYPE_ECC); +#else + *p = sp; +#endif + if (*p == NULL) { + ret = MEMORY_E; + } + return ret; +} + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* Allocate memory for point and return error. */ +#define sp_1024_point_new_16(heap, sp, p) sp_1024_point_new_ex_16((heap), NULL, &(p)) +#else +/* Set pointer to data and return no error. */ +#define sp_1024_point_new_16(heap, sp, p) sp_1024_point_new_ex_16((heap), &(sp), &(p)) +#endif + + +/* Free the point. + * + * p [in,out] Point to free. + * clear [in] Indicates whether to zeroize point. + * heap [in] Buffer from which dynamic memory was allocate from. + */ +static void sp_1024_point_free_16(sp_point_1024* p, int clear, void* heap) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) +/* If valid pointer then clear point data if requested and free data. */ + if (p != NULL) { + if (clear != 0) { + XMEMSET(p, 0, sizeof(*p)); + } + XFREE(p, heap, DYNAMIC_TYPE_ECC); + } +#else +/* Clear point data if requested. */ + if ((p != NULL) && (clear != 0)) { + XMEMSET(p, 0, sizeof(*p)); + } +#endif + (void)heap; +} + +/* Convert an mp_int to an array of sp_digit. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a A multi-precision integer. + */ +static void sp_1024_from_mp(sp_digit* r, int size, const mp_int* a) +{ +#if DIGIT_BIT == 64 + int j; + + XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used); + + for (j = a->used; j < size; j++) { + r[j] = 0; + } +#elif DIGIT_BIT > 64 + int i; + int j = 0; + word32 s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i] << s); + r[j] &= 0xffffffffffffffffl; + s = 64U - s; + if (j + 1 >= size) { + break; + } + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + while ((s + 64U) <= (word32)DIGIT_BIT) { + s += 64U; + r[j] &= 0xffffffffffffffffl; + if (j + 1 >= size) { + break; + } + if (s < (word32)DIGIT_BIT) { + /* lint allow cast of mismatch word32 and mp_digit */ + r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/ + } + else { + r[++j] = 0L; + } + } + s = (word32)DIGIT_BIT - s; + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#else + int i; + int j = 0; + int s = 0; + + r[0] = 0; + for (i = 0; i < a->used && j < size; i++) { + r[j] |= ((sp_digit)a->dp[i]) << s; + if (s + DIGIT_BIT >= 64) { + r[j] &= 0xffffffffffffffffl; + if (j + 1 >= size) { + break; + } + s = 64 - s; + if (s == DIGIT_BIT) { + r[++j] = 0; + s = 0; + } + else { + r[++j] = a->dp[i] >> s; + s = DIGIT_BIT - s; + } + } + else { + s += DIGIT_BIT; + } + } + + for (j++; j < size; j++) { + r[j] = 0; + } +#endif +} + +/* Convert a point of type ecc_point to type sp_point_1024. + * + * p Point of type sp_point_1024 (result). + * pm Point of type ecc_point. + */ +static void sp_1024_point_from_ecc_point_16(sp_point_1024* p, + const ecc_point* pm) +{ + XMEMSET(p->x, 0, sizeof(p->x)); + XMEMSET(p->y, 0, sizeof(p->y)); + XMEMSET(p->z, 0, sizeof(p->z)); + sp_1024_from_mp(p->x, 16, pm->x); + sp_1024_from_mp(p->y, 16, pm->y); + sp_1024_from_mp(p->z, 16, pm->z); + p->infinity = 0; +} + +/* Convert an array of sp_digit to an mp_int. + * + * a A single precision integer. + * r A multi-precision integer. + */ +static int sp_1024_to_mp(const sp_digit* a, mp_int* r) +{ + int err; + + err = mp_grow(r, (1024 + DIGIT_BIT - 1) / DIGIT_BIT); + if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/ +#if DIGIT_BIT == 64 + XMEMCPY(r->dp, a, sizeof(sp_digit) * 16); + r->used = 16; + mp_clamp(r); +#elif DIGIT_BIT < 64 + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 16; i++) { + r->dp[j] |= (mp_digit)(a[i] << s); + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + s = DIGIT_BIT - s; + r->dp[++j] = (mp_digit)(a[i] >> s); + while (s + DIGIT_BIT <= 64) { + s += DIGIT_BIT; + r->dp[j++] &= ((sp_digit)1 << DIGIT_BIT) - 1; + if (s == SP_WORD_SIZE) { + r->dp[j] = 0; + } + else { + r->dp[j] = (mp_digit)(a[i] >> s); + } + } + s = 64 - s; + } + r->used = (1024 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#else + int i; + int j = 0; + int s = 0; + + r->dp[0] = 0; + for (i = 0; i < 16; i++) { + r->dp[j] |= ((mp_digit)a[i]) << s; + if (s + 64 >= DIGIT_BIT) { + #if DIGIT_BIT != 32 && DIGIT_BIT != 64 + r->dp[j] &= ((sp_digit)1 << DIGIT_BIT) - 1; + #endif + s = DIGIT_BIT - s; + r->dp[++j] = a[i] >> s; + s = 64 - s; + } + else { + s += 64; + } + } + r->used = (1024 + DIGIT_BIT - 1) / DIGIT_BIT; + mp_clamp(r); +#endif + } + + return err; +} + +/* Convert a point of type sp_point_1024 to type ecc_point. + * + * p Point of type sp_point_1024. + * pm Point of type ecc_point (result). + * returns MEMORY_E when allocation of memory in ecc_point fails otherwise + * MP_OKAY. + */ +static int sp_1024_point_to_ecc_point_16(const sp_point_1024* p, ecc_point* pm) +{ + int err; + + err = sp_1024_to_mp(p->x, pm->x); + if (err == MP_OKAY) { + err = sp_1024_to_mp(p->y, pm->y); + } + if (err == MP_OKAY) { + err = sp_1024_to_mp(p->z, pm->z); + } + + return err; +} + +extern void sp_1024_cond_copy_16(sp_digit* r, const sp_digit* a, sp_digit m); +extern void sp_1024_mont_reduce_16(sp_digit* a, const sp_digit* m, sp_digit mp); +/* Multiply two Montogmery form numbers mod the modulus (prime). + * (r = a * b mod m) + * + * r Result of multiplication. + * a First number to multiply in Montogmery form. + * b Second number to multiply in Montogmery form. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_1024_mont_mul_16(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) +{ + sp_1024_mul_16(r, a, b); + sp_1024_mont_reduce_16(r, m, mp); +} + +/* Square the Montgomery form number. (r = a * a mod m) + * + * r Result of squaring. + * a Number to square in Montogmery form. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_1024_mont_sqr_16(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) +{ + sp_1024_sqr_16(r, a); + sp_1024_mont_reduce_16(r, m, mp); +} + +/* Mod-2 for the P1024 curve. */ +static const uint8_t p1024_mod_minus_2[] = { + 6,0x06, 7,0x0f, 7,0x0b, 6,0x0c, 7,0x1e, 9,0x09, 7,0x0c, 7,0x1f, + 6,0x16, 6,0x06, 7,0x0e, 8,0x10, 6,0x03, 8,0x11, 6,0x0d, 7,0x14, + 9,0x12, 6,0x0f, 7,0x04, 9,0x0d, 6,0x00, 7,0x13, 6,0x01, 6,0x07, + 8,0x0d, 8,0x00, 6,0x06, 9,0x17, 6,0x14, 6,0x15, 6,0x11, 6,0x0b, + 9,0x0c, 6,0x1e, 13,0x14, 7,0x0e, 6,0x1d, 12,0x0a, 6,0x0b, 8,0x07, + 6,0x18, 6,0x0f, 6,0x10, 8,0x1c, 7,0x16, 7,0x02, 6,0x01, 6,0x13, + 10,0x15, 7,0x06, 8,0x14, 6,0x0c, 6,0x19, 7,0x10, 6,0x19, 6,0x19, + 9,0x16, 7,0x19, 6,0x1f, 6,0x17, 6,0x12, 8,0x02, 6,0x01, 6,0x04, + 6,0x15, 7,0x16, 6,0x04, 6,0x1f, 6,0x09, 7,0x06, 7,0x13, 7,0x09, + 6,0x0d, 10,0x18, 6,0x06, 6,0x11, 6,0x04, 6,0x01, 6,0x13, 8,0x06, + 6,0x0d, 8,0x13, 7,0x08, 6,0x08, 6,0x05, 7,0x0c, 7,0x0e, 7,0x15, + 6,0x05, 7,0x14, 10,0x19, 6,0x10, 6,0x16, 6,0x15, 7,0x1f, 6,0x14, + 6,0x0a, 10,0x11, 6,0x01, 7,0x05, 7,0x08, 8,0x0a, 7,0x1e, 7,0x1c, + 6,0x1c, 7,0x09, 10,0x18, 7,0x1c, 10,0x06, 6,0x0a, 6,0x07, 6,0x19, + 7,0x06, 6,0x0d, 7,0x0f, 7,0x0b, 7,0x05, 6,0x11, 6,0x1c, 7,0x1f, + 6,0x1e, 7,0x18, 6,0x1e, 6,0x00, 6,0x03, 6,0x02, 7,0x10, 6,0x0b, + 6,0x1b, 7,0x10, 6,0x00, 8,0x11, 7,0x1b, 6,0x18, 6,0x01, 7,0x0c, + 7,0x1d, 7,0x13, 6,0x08, 7,0x1b, 8,0x13, 7,0x16, 13,0x1d, 7,0x1f, + 6,0x0a, 6,0x01, 7,0x1f, 6,0x14, 1,0x01 +}; + +/* Invert the number, in Montgomery form, modulo the modulus (prime) of the + * P1024 curve. (r = 1 / a mod m) + * + * r Inverse result. + * a Number to invert. + * td Temporary data. + */ +static void sp_1024_mont_inv_16(sp_digit* r, const sp_digit* a, + sp_digit* td) +{ + sp_digit* t = td; + int i; + int j; + sp_digit table[32][2 * 16]; + + XMEMCPY(table[0], a, sizeof(sp_digit) * 16); + for (i = 1; i < 6; i++) { + sp_1024_mont_sqr_16(table[0], table[0], p1024_mod, p1024_mp_mod); + } + for (i = 1; i < 32; i++) { + sp_1024_mont_mul_16(table[i], table[i-1], a, p1024_mod, p1024_mp_mod); + } + + XMEMCPY(t, table[p1024_mod_minus_2[1]], sizeof(sp_digit) * 16); + for (i = 2; i < (int)sizeof(p1024_mod_minus_2) - 2; i += 2) { + for (j = 0; j < p1024_mod_minus_2[i]; j++) { + sp_1024_mont_sqr_16(t, t, p1024_mod, p1024_mp_mod); + } + sp_1024_mont_mul_16(t, t, table[p1024_mod_minus_2[i+1]], p1024_mod, + p1024_mp_mod); + } + sp_1024_mont_sqr_16(t, t, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(r, t, a, p1024_mod, p1024_mp_mod); +} + +/* Normalize the values in each word to 64. + * + * a Array of sp_digit to normalize. + */ +#define sp_1024_norm_16(a) + +/* Map the Montgomery form projective coordinate point to an affine point. + * + * r Resulting affine coordinate point. + * p Montgomery form projective coordinate point. + * t Temporary ordinate data. + */ +static void sp_1024_map_16(sp_point_1024* r, const sp_point_1024* p, + sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*16; + int64_t n; + + sp_1024_mont_inv_16(t1, p->z, t + 2*16); + + sp_1024_mont_sqr_16(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t1, t2, t1, p1024_mod, p1024_mp_mod); + + /* x /= z^2 */ + sp_1024_mont_mul_16(r->x, p->x, t2, p1024_mod, p1024_mp_mod); + XMEMSET(r->x + 16, 0, sizeof(r->x) / 2U); + sp_1024_mont_reduce_16(r->x, p1024_mod, p1024_mp_mod); + /* Reduce x to less than modulus */ + n = sp_1024_cmp_16(r->x, p1024_mod); + sp_1024_cond_sub_16(r->x, r->x, p1024_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_16(r->x); + + /* y /= z^3 */ + sp_1024_mont_mul_16(r->y, p->y, t1, p1024_mod, p1024_mp_mod); + XMEMSET(r->y + 16, 0, sizeof(r->y) / 2U); + sp_1024_mont_reduce_16(r->y, p1024_mod, p1024_mp_mod); + /* Reduce y to less than modulus */ + n = sp_1024_cmp_16(r->y, p1024_mod); + sp_1024_cond_sub_16(r->y, r->y, p1024_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_16(r->y); + + XMEMSET(r->z, 0, sizeof(r->z)); + r->z[0] = 1; + +} + +extern void sp_1024_mont_add_16(sp_digit* r, const sp_digit* a, const sp_digit* b, const sp_digit* m); +extern void sp_1024_mont_dbl_16(sp_digit* r, const sp_digit* a, const sp_digit* m); +extern void sp_1024_mont_tpl_16(sp_digit* r, const sp_digit* a, const sp_digit* m); +extern void sp_1024_mont_sub_16(sp_digit* r, const sp_digit* a, const sp_digit* b, const sp_digit* m); +extern void sp_1024_div2_16(sp_digit* r, const sp_digit* a, const sp_digit* m); +/* Double the Montgomery form projective point p. + * + * r Result of doubling point. + * p Point to double. + * t Temporary ordinate data. + */ +#ifdef WOLFSSL_SP_NONBLOCK +typedef struct sp_1024_proj_point_dbl_16_ctx { + int state; + sp_digit* t1; + sp_digit* t2; + sp_digit* x; + sp_digit* y; + sp_digit* z; +} sp_1024_proj_point_dbl_16_ctx; + +static int sp_1024_proj_point_dbl_16_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r, const sp_point_1024* p, sp_digit* t) +{ + int err = FP_WOULDBLOCK; + sp_1024_proj_point_dbl_16_ctx* ctx = (sp_1024_proj_point_dbl_16_ctx*)sp_ctx->data; + + typedef char ctx_size_test[sizeof(sp_1024_proj_point_dbl_16_ctx) >= sizeof(*sp_ctx) ? -1 : 1]; + (void)sizeof(ctx_size_test); + + switch (ctx->state) { + case 0: + ctx->t1 = t; + ctx->t2 = t + 2*16; + ctx->x = r->x; + ctx->y = r->y; + ctx->z = r->z; + + /* Put infinity into result. */ + if (r != p) { + r->infinity = p->infinity; + } + ctx->state = 1; + break; + case 1: + /* T1 = Z * Z */ + sp_1024_mont_sqr_16(ctx->t1, p->z, p1024_mod, p1024_mp_mod); + ctx->state = 2; + break; + case 2: + /* Z = Y * Z */ + sp_1024_mont_mul_16(ctx->z, p->y, p->z, p1024_mod, p1024_mp_mod); + ctx->state = 3; + break; + case 3: + /* Z = 2Z */ + sp_1024_mont_dbl_16(ctx->z, ctx->z, p1024_mod); + ctx->state = 4; + break; + case 4: + /* T2 = X - T1 */ + sp_1024_mont_sub_16(ctx->t2, p->x, ctx->t1, p1024_mod); + ctx->state = 5; + break; + case 5: + /* T1 = X + T1 */ + sp_1024_mont_add_16(ctx->t1, p->x, ctx->t1, p1024_mod); + ctx->state = 6; + break; + case 6: + /* T2 = T1 * T2 */ + sp_1024_mont_mul_16(ctx->t2, ctx->t1, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 7; + break; + case 7: + /* T1 = 3T2 */ + sp_1024_mont_tpl_16(ctx->t1, ctx->t2, p1024_mod); + ctx->state = 8; + break; + case 8: + /* Y = 2Y */ + sp_1024_mont_dbl_16(ctx->y, p->y, p1024_mod); + ctx->state = 9; + break; + case 9: + /* Y = Y * Y */ + sp_1024_mont_sqr_16(ctx->y, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 10; + break; + case 10: + /* T2 = Y * Y */ + sp_1024_mont_sqr_16(ctx->t2, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 11; + break; + case 11: + /* T2 = T2/2 */ + sp_1024_div2_16(ctx->t2, ctx->t2, p1024_mod); + ctx->state = 12; + break; + case 12: + /* Y = Y * X */ + sp_1024_mont_mul_16(ctx->y, ctx->y, p->x, p1024_mod, p1024_mp_mod); + ctx->state = 13; + break; + case 13: + /* X = T1 * T1 */ + sp_1024_mont_sqr_16(ctx->x, ctx->t1, p1024_mod, p1024_mp_mod); + ctx->state = 14; + break; + case 14: + /* X = X - Y */ + sp_1024_mont_sub_16(ctx->x, ctx->x, ctx->y, p1024_mod); + ctx->state = 15; + break; + case 15: + /* X = X - Y */ + sp_1024_mont_sub_16(ctx->x, ctx->x, ctx->y, p1024_mod); + ctx->state = 16; + break; + case 16: + /* Y = Y - X */ + sp_1024_mont_sub_16(ctx->y, ctx->y, ctx->x, p1024_mod); + ctx->state = 17; + break; + case 17: + /* Y = Y * T1 */ + sp_1024_mont_mul_16(ctx->y, ctx->y, ctx->t1, p1024_mod, p1024_mp_mod); + ctx->state = 18; + break; + case 18: + /* Y = Y - T2 */ + sp_1024_mont_sub_16(ctx->y, ctx->y, ctx->t2, p1024_mod); + ctx->state = 19; + /* fall-through */ + case 19: + err = MP_OKAY; + break; + } + + if (err == MP_OKAY && ctx->state != 19) { + err = FP_WOULDBLOCK; + } + + return err; +} +#endif /* WOLFSSL_SP_NONBLOCK */ + +static void sp_1024_proj_point_dbl_16(sp_point_1024* r, const sp_point_1024* p, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*16; + sp_digit* x; + sp_digit* y; + sp_digit* z; + + x = r->x; + y = r->y; + z = r->z; + /* Put infinity into result. */ + if (r != p) { + r->infinity = p->infinity; + } + + /* T1 = Z * Z */ + sp_1024_mont_sqr_16(t1, p->z, p1024_mod, p1024_mp_mod); + /* Z = Y * Z */ + sp_1024_mont_mul_16(z, p->y, p->z, p1024_mod, p1024_mp_mod); + /* Z = 2Z */ + sp_1024_mont_dbl_16(z, z, p1024_mod); + /* T2 = X - T1 */ + sp_1024_mont_sub_16(t2, p->x, t1, p1024_mod); + /* T1 = X + T1 */ + sp_1024_mont_add_16(t1, p->x, t1, p1024_mod); + /* T2 = T1 * T2 */ + sp_1024_mont_mul_16(t2, t1, t2, p1024_mod, p1024_mp_mod); + /* T1 = 3T2 */ + sp_1024_mont_tpl_16(t1, t2, p1024_mod); + /* Y = 2Y */ + sp_1024_mont_dbl_16(y, p->y, p1024_mod); + /* Y = Y * Y */ + sp_1024_mont_sqr_16(y, y, p1024_mod, p1024_mp_mod); + /* T2 = Y * Y */ + sp_1024_mont_sqr_16(t2, y, p1024_mod, p1024_mp_mod); + /* T2 = T2/2 */ + sp_1024_div2_16(t2, t2, p1024_mod); + /* Y = Y * X */ + sp_1024_mont_mul_16(y, y, p->x, p1024_mod, p1024_mp_mod); + /* X = T1 * T1 */ + sp_1024_mont_sqr_16(x, t1, p1024_mod, p1024_mp_mod); + /* X = X - Y */ + sp_1024_mont_sub_16(x, x, y, p1024_mod); + /* X = X - Y */ + sp_1024_mont_sub_16(x, x, y, p1024_mod); + /* Y = Y - X */ + sp_1024_mont_sub_16(y, y, x, p1024_mod); + /* Y = Y * T1 */ + sp_1024_mont_mul_16(y, y, t1, p1024_mod, p1024_mp_mod); + /* Y = Y - T2 */ + sp_1024_mont_sub_16(y, y, t2, p1024_mod); +} + +/* Double the Montgomery form projective point p a number of times. + * + * r Result of repeated doubling of point. + * p Point to double. + * n Number of times to double + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_dbl_n_16(sp_point_1024* p, int n, + sp_digit* t) +{ + sp_digit* w = t; + sp_digit* a = t + 2*16; + sp_digit* b = t + 4*16; + sp_digit* t1 = t + 6*16; + sp_digit* t2 = t + 8*16; + sp_digit* x; + sp_digit* y; + sp_digit* z; + + x = p->x; + y = p->y; + z = p->z; + + /* Y = 2*Y */ + sp_1024_mont_dbl_16(y, y, p1024_mod); + /* W = Z^4 */ + sp_1024_mont_sqr_16(w, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_16(w, w, p1024_mod, p1024_mp_mod); + +#ifndef WOLFSSL_SP_SMALL + while (--n > 0) +#else + while (--n >= 0) +#endif + { + /* A = 3*(X^2 - W) */ + sp_1024_mont_sqr_16(t1, x, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_16(t1, t1, w, p1024_mod); + sp_1024_mont_tpl_16(a, t1, p1024_mod); + /* B = X*Y^2 */ + sp_1024_mont_sqr_16(t1, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(b, t1, x, p1024_mod, p1024_mp_mod); + /* X = A^2 - 2B */ + sp_1024_mont_sqr_16(x, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_16(t2, b, p1024_mod); + sp_1024_mont_sub_16(x, x, t2, p1024_mod); + /* Z = Z*Y */ + sp_1024_mont_mul_16(z, z, y, p1024_mod, p1024_mp_mod); + /* t2 = Y^4 */ + sp_1024_mont_sqr_16(t1, t1, p1024_mod, p1024_mp_mod); +#ifdef WOLFSSL_SP_SMALL + if (n != 0) +#endif + { + /* W = W*Y^4 */ + sp_1024_mont_mul_16(w, w, t1, p1024_mod, p1024_mp_mod); + } + /* y = 2*A*(B - X) - Y^4 */ + sp_1024_mont_sub_16(y, b, x, p1024_mod); + sp_1024_mont_mul_16(y, y, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_16(y, y, p1024_mod); + sp_1024_mont_sub_16(y, y, t1, p1024_mod); + } +#ifndef WOLFSSL_SP_SMALL + /* A = 3*(X^2 - W) */ + sp_1024_mont_sqr_16(t1, x, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_16(t1, t1, w, p1024_mod); + sp_1024_mont_tpl_16(a, t1, p1024_mod); + /* B = X*Y^2 */ + sp_1024_mont_sqr_16(t1, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(b, t1, x, p1024_mod, p1024_mp_mod); + /* X = A^2 - 2B */ + sp_1024_mont_sqr_16(x, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_16(t2, b, p1024_mod); + sp_1024_mont_sub_16(x, x, t2, p1024_mod); + /* Z = Z*Y */ + sp_1024_mont_mul_16(z, z, y, p1024_mod, p1024_mp_mod); + /* t2 = Y^4 */ + sp_1024_mont_sqr_16(t1, t1, p1024_mod, p1024_mp_mod); + /* y = 2*A*(B - X) - Y^4 */ + sp_1024_mont_sub_16(y, b, x, p1024_mod); + sp_1024_mont_mul_16(y, y, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_16(y, y, p1024_mod); + sp_1024_mont_sub_16(y, y, t1, p1024_mod); +#endif + /* Y = Y/2 */ + sp_1024_div2_16(y, y, p1024_mod); +} + +extern sp_digit sp_1024_sub_16(sp_digit* r, const sp_digit* a, const sp_digit* b); +/* Compare two numbers to determine if they are equal. + * Constant time implementation. + * + * a First number to compare. + * b Second number to compare. + * returns 1 when equal and 0 otherwise. + */ +static int sp_1024_cmp_equal_16(const sp_digit* a, const sp_digit* b) +{ + return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) | (a[3] ^ b[3]) | + (a[4] ^ b[4]) | (a[5] ^ b[5]) | (a[6] ^ b[6]) | (a[7] ^ b[7]) | + (a[8] ^ b[8]) | (a[9] ^ b[9]) | (a[10] ^ b[10]) | (a[11] ^ b[11]) | + (a[12] ^ b[12]) | (a[13] ^ b[13]) | (a[14] ^ b[14]) | (a[15] ^ b[15])) == 0; +} + +/* Add two Montgomery form projective points. + * + * r Result of addition. + * p First point to add. + * q Second point to add. + * t Temporary ordinate data. + */ + +#ifdef WOLFSSL_SP_NONBLOCK +typedef struct sp_1024_proj_point_add_16_ctx { + int state; + sp_1024_proj_point_dbl_16_ctx dbl_ctx; + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1; + sp_digit* t2; + sp_digit* t3; + sp_digit* t4; + sp_digit* t5; + sp_digit* x; + sp_digit* y; + sp_digit* z; +} sp_1024_proj_point_add_16_ctx; + +static int sp_1024_proj_point_add_16_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r, + const sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + int err = FP_WOULDBLOCK; + sp_1024_proj_point_add_16_ctx* ctx = (sp_1024_proj_point_add_16_ctx*)sp_ctx->data; + + /* Ensure only the first point is the same as the result. */ + if (q == r) { + const sp_point_1024* a = p; + p = q; + q = a; + } + + typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_16_ctx) >= sizeof(*sp_ctx) ? -1 : 1]; + (void)sizeof(ctx_size_test); + + switch (ctx->state) { + case 0: /* INIT */ + ctx->t1 = t; + ctx->t2 = t + 2*16; + ctx->t3 = t + 4*16; + ctx->t4 = t + 6*16; + ctx->t5 = t + 8*16; + + ctx->state = 1; + break; + case 1: + /* Check double */ + (void)sp_1024_sub_16(ctx->t1, p1024_mod, q->y); + sp_1024_norm_16(ctx->t1); + if ((sp_1024_cmp_equal_16(p->x, q->x) & sp_1024_cmp_equal_16(p->z, q->z) & + (sp_1024_cmp_equal_16(p->y, q->y) | sp_1024_cmp_equal_16(p->y, ctx->t1))) != 0) + { + XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx)); + ctx->state = 2; + } + else { + ctx->state = 3; + } + break; + case 2: + err = sp_1024_proj_point_dbl_16_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, r, p, t); + if (err == MP_OKAY) + ctx->state = 27; /* done */ + break; + case 3: + { + int i; + ctx->rp[0] = r; + + /*lint allow cast to different type of pointer*/ + ctx->rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(ctx->rp[1], 0, sizeof(sp_point_1024)); + ctx->x = ctx->rp[p->infinity | q->infinity]->x; + ctx->y = ctx->rp[p->infinity | q->infinity]->y; + ctx->z = ctx->rp[p->infinity | q->infinity]->z; + + ctx->ap[0] = p; + ctx->ap[1] = q; + for (i=0; i<16; i++) { + r->x[i] = ctx->ap[p->infinity]->x[i]; + } + for (i=0; i<16; i++) { + r->y[i] = ctx->ap[p->infinity]->y[i]; + } + for (i=0; i<16; i++) { + r->z[i] = ctx->ap[p->infinity]->z[i]; + } + r->infinity = ctx->ap[p->infinity]->infinity; + + ctx->state = 4; + break; + } + case 4: + /* U1 = X1*Z2^2 */ + sp_1024_mont_sqr_16(ctx->t1, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 5; + break; + case 5: + sp_1024_mont_mul_16(ctx->t3, ctx->t1, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 6; + break; + case 6: + sp_1024_mont_mul_16(ctx->t1, ctx->t1, ctx->x, p1024_mod, p1024_mp_mod); + ctx->state = 7; + break; + case 7: + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_16(ctx->t2, ctx->z, p1024_mod, p1024_mp_mod); + ctx->state = 8; + break; + case 8: + sp_1024_mont_mul_16(ctx->t4, ctx->t2, ctx->z, p1024_mod, p1024_mp_mod); + ctx->state = 9; + break; + case 9: + sp_1024_mont_mul_16(ctx->t2, ctx->t2, q->x, p1024_mod, p1024_mp_mod); + ctx->state = 10; + break; + case 10: + /* S1 = Y1*Z2^3 */ + sp_1024_mont_mul_16(ctx->t3, ctx->t3, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 11; + break; + case 11: + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_16(ctx->t4, ctx->t4, q->y, p1024_mod, p1024_mp_mod); + ctx->state = 12; + break; + case 12: + /* H = U2 - U1 */ + sp_1024_mont_sub_16(ctx->t2, ctx->t2, ctx->t1, p1024_mod); + ctx->state = 13; + break; + case 13: + /* R = S2 - S1 */ + sp_1024_mont_sub_16(ctx->t4, ctx->t4, ctx->t3, p1024_mod); + ctx->state = 14; + break; + case 14: + /* Z3 = H*Z1*Z2 */ + sp_1024_mont_mul_16(ctx->z, ctx->z, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 15; + break; + case 15: + sp_1024_mont_mul_16(ctx->z, ctx->z, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 16; + break; + case 16: + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_1024_mont_sqr_16(ctx->x, ctx->t4, p1024_mod, p1024_mp_mod); + ctx->state = 17; + break; + case 17: + sp_1024_mont_sqr_16(ctx->t5, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 18; + break; + case 18: + sp_1024_mont_mul_16(ctx->y, ctx->t1, ctx->t5, p1024_mod, p1024_mp_mod); + ctx->state = 19; + break; + case 19: + sp_1024_mont_mul_16(ctx->t5, ctx->t5, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 20; + break; + case 20: + sp_1024_mont_sub_16(ctx->x, ctx->x, ctx->t5, p1024_mod); + ctx->state = 21; + break; + case 21: + sp_1024_mont_dbl_16(ctx->t1, ctx->y, p1024_mod); + ctx->state = 22; + break; + case 22: + sp_1024_mont_sub_16(ctx->x, ctx->x, ctx->t1, p1024_mod); + ctx->state = 23; + break; + case 23: + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_1024_mont_sub_16(ctx->y, ctx->y, ctx->x, p1024_mod); + ctx->state = 24; + break; + case 24: + sp_1024_mont_mul_16(ctx->y, ctx->y, ctx->t4, p1024_mod, p1024_mp_mod); + ctx->state = 25; + break; + case 25: + sp_1024_mont_mul_16(ctx->t5, ctx->t5, ctx->t3, p1024_mod, p1024_mp_mod); + ctx->state = 26; + break; + case 26: + sp_1024_mont_sub_16(ctx->y, ctx->y, ctx->t5, p1024_mod); + ctx->state = 27; + /* fall-through */ + case 27: + err = MP_OKAY; + break; + } + + if (err == MP_OKAY && ctx->state != 27) { + err = FP_WOULDBLOCK; + } + return err; +} +#endif /* WOLFSSL_SP_NONBLOCK */ + +static void sp_1024_proj_point_add_16(sp_point_1024* r, + const sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*16; + sp_digit* t3 = t + 4*16; + sp_digit* t4 = t + 6*16; + sp_digit* t5 = t + 8*16; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Ensure only the first point is the same as the result. */ + if (q == r) { + const sp_point_1024* a = p; + p = q; + q = a; + } + + /* Check double */ + (void)sp_1024_mont_sub_16(t1, p1024_mod, q->y, p1024_mod); + sp_1024_norm_16(t1); + if ((sp_1024_cmp_equal_16(p->x, q->x) & sp_1024_cmp_equal_16(p->z, q->z) & + (sp_1024_cmp_equal_16(p->y, q->y) | sp_1024_cmp_equal_16(p->y, t1))) != 0) { + sp_1024_proj_point_dbl_16(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_1024)); + x = rp[p->infinity | q->infinity]->x; + y = rp[p->infinity | q->infinity]->y; + z = rp[p->infinity | q->infinity]->z; + + ap[0] = p; + ap[1] = q; + for (i=0; i<16; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<16; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<16; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U1 = X1*Z2^2 */ + sp_1024_mont_sqr_16(t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t3, t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t1, t1, x, p1024_mod, p1024_mp_mod); + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_16(t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t4, t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t2, t2, q->x, p1024_mod, p1024_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_1024_mont_mul_16(t3, t3, y, p1024_mod, p1024_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_16(t4, t4, q->y, p1024_mod, p1024_mp_mod); + /* H = U2 - U1 */ + sp_1024_mont_sub_16(t2, t2, t1, p1024_mod); + /* R = S2 - S1 */ + sp_1024_mont_sub_16(t4, t4, t3, p1024_mod); + /* Z3 = H*Z1*Z2 */ + sp_1024_mont_mul_16(z, z, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(z, z, t2, p1024_mod, p1024_mp_mod); + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_1024_mont_sqr_16(x, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_16(t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(y, t1, t5, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t5, t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_16(x, x, t5, p1024_mod); + sp_1024_mont_dbl_16(t1, y, p1024_mod); + sp_1024_mont_sub_16(x, x, t1, p1024_mod); + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_1024_mont_sub_16(y, y, x, p1024_mod); + sp_1024_mont_mul_16(y, y, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t5, t5, t3, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_16(y, y, t5, p1024_mod); + } +} + +/* Double the Montgomery form projective point p a number of times. + * + * r Result of repeated doubling of point. + * p Point to double. + * n Number of times to double + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_dbl_n_store_16(sp_point_1024* r, + const sp_point_1024* p, int n, int m, sp_digit* t) +{ + sp_digit* w = t; + sp_digit* a = t + 2*16; + sp_digit* b = t + 4*16; + sp_digit* t1 = t + 6*16; + sp_digit* t2 = t + 8*16; + sp_digit* x = r[2*m].x; + sp_digit* y = r[(1<x[i]; + } + for (i=0; i<16; i++) { + y[i] = p->y[i]; + } + for (i=0; i<16; i++) { + z[i] = p->z[i]; + } + + /* Y = 2*Y */ + sp_1024_mont_dbl_16(y, y, p1024_mod); + /* W = Z^4 */ + sp_1024_mont_sqr_16(w, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_16(w, w, p1024_mod, p1024_mp_mod); + j = m; + for (i=1; i<=n; i++) { + j *= 2; + + /* A = 3*(X^2 - W) */ + sp_1024_mont_sqr_16(t1, x, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_16(t1, t1, w, p1024_mod); + sp_1024_mont_tpl_16(a, t1, p1024_mod); + /* B = X*Y^2 */ + sp_1024_mont_sqr_16(t2, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(b, t2, x, p1024_mod, p1024_mp_mod); + x = r[j].x; + /* X = A^2 - 2B */ + sp_1024_mont_sqr_16(x, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_16(t1, b, p1024_mod); + sp_1024_mont_sub_16(x, x, t1, p1024_mod); + /* Z = Z*Y */ + sp_1024_mont_mul_16(r[j].z, z, y, p1024_mod, p1024_mp_mod); + z = r[j].z; + /* t2 = Y^4 */ + sp_1024_mont_sqr_16(t2, t2, p1024_mod, p1024_mp_mod); + if (i != n) { + /* W = W*Y^4 */ + sp_1024_mont_mul_16(w, w, t2, p1024_mod, p1024_mp_mod); + } + /* y = 2*A*(B - X) - Y^4 */ + sp_1024_mont_sub_16(y, b, x, p1024_mod); + sp_1024_mont_mul_16(y, y, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_16(y, y, p1024_mod); + sp_1024_mont_sub_16(y, y, t2, p1024_mod); + + /* Y = Y/2 */ + sp_1024_div2_16(r[j].y, y, p1024_mod); + r[j].infinity = 0; + } +} + +/* Add two Montgomery form projective points. + * + * ra Result of addition. + * rs Result of subtraction. + * p First point to add. + * q Second point to add. + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_add_sub_16(sp_point_1024* ra, + sp_point_1024* rs, const sp_point_1024* p, const sp_point_1024* q, + sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*16; + sp_digit* t3 = t + 4*16; + sp_digit* t4 = t + 6*16; + sp_digit* t5 = t + 8*16; + sp_digit* t6 = t + 10*16; + sp_digit* x = ra->x; + sp_digit* y = ra->y; + sp_digit* z = ra->z; + sp_digit* xs = rs->x; + sp_digit* ys = rs->y; + sp_digit* zs = rs->z; + + + XMEMCPY(x, p->x, sizeof(p->x) / 2); + XMEMCPY(y, p->y, sizeof(p->y) / 2); + XMEMCPY(z, p->z, sizeof(p->z) / 2); + ra->infinity = 0; + rs->infinity = 0; + + /* U1 = X1*Z2^2 */ + sp_1024_mont_sqr_16(t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t3, t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t1, t1, x, p1024_mod, p1024_mp_mod); + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_16(t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t4, t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t2, t2, q->x, p1024_mod, p1024_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_1024_mont_mul_16(t3, t3, y, p1024_mod, p1024_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_16(t4, t4, q->y, p1024_mod, p1024_mp_mod); + /* H = U2 - U1 */ + sp_1024_mont_sub_16(t2, t2, t1, p1024_mod); + /* RS = S2 + S1 */ + sp_1024_mont_add_16(t6, t4, t3, p1024_mod); + /* R = S2 - S1 */ + sp_1024_mont_sub_16(t4, t4, t3, p1024_mod); + /* Z3 = H*Z1*Z2 */ + /* ZS = H*Z1*Z2 */ + sp_1024_mont_mul_16(z, z, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(z, z, t2, p1024_mod, p1024_mp_mod); + XMEMCPY(zs, z, sizeof(p->z)/2); + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + /* XS = RS^2 - H^3 - 2*U1*H^2 */ + sp_1024_mont_sqr_16(x, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_16(xs, t6, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_16(t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(y, t1, t5, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t5, t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_16(x, x, t5, p1024_mod); + sp_1024_mont_sub_16(xs, xs, t5, p1024_mod); + sp_1024_mont_dbl_16(t1, y, p1024_mod); + sp_1024_mont_sub_16(x, x, t1, p1024_mod); + sp_1024_mont_sub_16(xs, xs, t1, p1024_mod); + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + /* YS = -RS*(U1*H^2 - XS) - S1*H^3 */ + sp_1024_mont_sub_16(ys, y, xs, p1024_mod); + sp_1024_mont_sub_16(y, y, x, p1024_mod); + sp_1024_mont_mul_16(y, y, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_16(t6, p1024_mod, t6, p1024_mod); + sp_1024_mont_mul_16(ys, ys, t6, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t5, t5, t3, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_16(y, y, t5, p1024_mod); + sp_1024_mont_sub_16(ys, ys, t5, p1024_mod); +} + +/* Structure used to describe recoding of scalar multiplication. */ +typedef struct ecc_recode_1024 { + /* Index into pre-computation table. */ + uint8_t i; + /* Use the negative of the point. */ + uint8_t neg; +} ecc_recode_1024; + +/* The index into pre-computation table to use. */ +static const uint8_t recode_index_16_7[130] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, + 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, + 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, + 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, + 0, 1, +}; + +/* Whether to negate y-ordinate. */ +static const uint8_t recode_neg_16_7[130] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, +}; + +/* Recode the scalar for multiplication using pre-computed values and + * subtraction. + * + * k Scalar to multiply by. + * v Vector of operations to perform. + */ +static void sp_1024_ecc_recode_7_16(const sp_digit* k, ecc_recode_1024* v) +{ + int i; + int j; + uint8_t y; + int carry = 0; + int o; + sp_digit n; + + j = 0; + n = k[j]; + o = 0; + for (i=0; i<147; i++) { + y = (int8_t)n; + if (o + 7 < 64) { + y &= 0x7f; + n >>= 7; + o += 7; + } + else if (o + 7 == 64) { + n >>= 7; + if (++j < 16) + n = k[j]; + o = 0; + } + else if (++j < 16) { + n = k[j]; + y |= (uint8_t)((n << (64 - o)) & 0x7f); + o -= 57; + n >>= o; + } + + y += (uint8_t)carry; + v[i].i = recode_index_16_7[y]; + v[i].neg = recode_neg_16_7[y]; + carry = (y >> 7) + v[i].neg; + } +} + +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Window technique of 7 bits. (Add-Sub variation.) + * Calculate 0..64 times the point. Use function that adds and + * subtracts the same two points. + * Recode to add or subtract one of the computed points. + * Double to push up. + * NOT a sliding window. + * + * r Resulting point. + * g Point to multiply. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_win_add_sub_16(sp_point_1024* r, const sp_point_1024* g, + const sp_digit* k, int map, int ct, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 td[65]; + sp_point_1024 rtd; + sp_point_1024 pd; + sp_digit tmpd[2 * 16 * 6]; +#endif + sp_point_1024* t; + sp_point_1024* rt; + sp_point_1024* p = NULL; + sp_digit* tmp; + sp_digit* negy; + int i; + ecc_recode_1024 v[147]; + int err; + + /* Constant time used for cache attack resistance implementation. */ + (void)ct; + (void)heap; + + err = sp_1024_point_new_16(heap, rtd, rt); + if (err == MP_OKAY) + err = sp_1024_point_new_16(heap, pd, p); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) * 65, heap, DYNAMIC_TYPE_ECC); + if (t == NULL) + err = MEMORY_E; + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 16 * 6, heap, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) + err = MEMORY_E; +#else + t = td; + tmp = tmpd; +#endif + + + if (err == MP_OKAY) { + /* t[0] = {0, 0, 1} * norm */ + XMEMSET(&t[0], 0, sizeof(t[0])); + t[0].infinity = 1; + /* t[1] = {g->x, g->y, g->z} * norm */ + err = sp_1024_mod_mul_norm_16(t[1].x, g->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(t[1].y, g->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(t[1].z, g->z, p1024_mod); + } + + if (err == MP_OKAY) { + t[1].infinity = 0; + /* t[2] ... t[64] */ + sp_1024_proj_point_dbl_n_store_16(t, &t[ 1], 6, 1, tmp); + sp_1024_proj_point_add_16(&t[ 3], &t[ 2], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[ 6], &t[ 3], tmp); + sp_1024_proj_point_add_sub_16(&t[ 7], &t[ 5], &t[ 6], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[10], &t[ 5], tmp); + sp_1024_proj_point_add_sub_16(&t[11], &t[ 9], &t[10], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[12], &t[ 6], tmp); + sp_1024_proj_point_dbl_16(&t[14], &t[ 7], tmp); + sp_1024_proj_point_add_sub_16(&t[15], &t[13], &t[14], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[18], &t[ 9], tmp); + sp_1024_proj_point_add_sub_16(&t[19], &t[17], &t[18], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[20], &t[10], tmp); + sp_1024_proj_point_dbl_16(&t[22], &t[11], tmp); + sp_1024_proj_point_add_sub_16(&t[23], &t[21], &t[22], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[24], &t[12], tmp); + sp_1024_proj_point_dbl_16(&t[26], &t[13], tmp); + sp_1024_proj_point_add_sub_16(&t[27], &t[25], &t[26], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[28], &t[14], tmp); + sp_1024_proj_point_dbl_16(&t[30], &t[15], tmp); + sp_1024_proj_point_add_sub_16(&t[31], &t[29], &t[30], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[34], &t[17], tmp); + sp_1024_proj_point_add_sub_16(&t[35], &t[33], &t[34], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[36], &t[18], tmp); + sp_1024_proj_point_dbl_16(&t[38], &t[19], tmp); + sp_1024_proj_point_add_sub_16(&t[39], &t[37], &t[38], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[40], &t[20], tmp); + sp_1024_proj_point_dbl_16(&t[42], &t[21], tmp); + sp_1024_proj_point_add_sub_16(&t[43], &t[41], &t[42], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[44], &t[22], tmp); + sp_1024_proj_point_dbl_16(&t[46], &t[23], tmp); + sp_1024_proj_point_add_sub_16(&t[47], &t[45], &t[46], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[48], &t[24], tmp); + sp_1024_proj_point_dbl_16(&t[50], &t[25], tmp); + sp_1024_proj_point_add_sub_16(&t[51], &t[49], &t[50], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[52], &t[26], tmp); + sp_1024_proj_point_dbl_16(&t[54], &t[27], tmp); + sp_1024_proj_point_add_sub_16(&t[55], &t[53], &t[54], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[56], &t[28], tmp); + sp_1024_proj_point_dbl_16(&t[58], &t[29], tmp); + sp_1024_proj_point_add_sub_16(&t[59], &t[57], &t[58], &t[ 1], tmp); + sp_1024_proj_point_dbl_16(&t[60], &t[30], tmp); + sp_1024_proj_point_dbl_16(&t[62], &t[31], tmp); + sp_1024_proj_point_add_sub_16(&t[63], &t[61], &t[62], &t[ 1], tmp); + + negy = t[0].y; + + sp_1024_ecc_recode_7_16(k, v); + + i = 146; + XMEMCPY(rt, &t[v[i].i], sizeof(sp_point_1024)); + for (--i; i>=0; i--) { + sp_1024_proj_point_dbl_n_16(rt, 7, tmp); + XMEMCPY(p, &t[v[i].i], sizeof(sp_point_1024)); + sp_1024_mont_sub_16(negy, p1024_mod, p->y, p1024_mod); + sp_1024_norm_16(negy); + sp_1024_cond_copy_16(p->y, negy, (sp_digit)0 - v[i].neg); + sp_1024_proj_point_add_16(rt, rt, p, tmp); + } + + if (map != 0) { + sp_1024_map_16(r, rt, tmp); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_1024)); + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (t != NULL) + XFREE(t, heap, DYNAMIC_TYPE_ECC); + if (tmp != NULL) + XFREE(tmp, heap, DYNAMIC_TYPE_ECC); +#endif + sp_1024_point_free_16(p, 0, heap); + sp_1024_point_free_16(rt, 0, heap); + + return err; +} + +#ifdef HAVE_INTEL_AVX2 +#ifdef HAVE_INTEL_AVX2 +extern void sp_1024_mont_reduce_avx2_16(sp_digit* a, const sp_digit* m, sp_digit mp); +/* Multiply two Montogmery form numbers mod the modulus (prime). + * (r = a * b mod m) + * + * r Result of multiplication. + * a First number to multiply in Montogmery form. + * b Second number to multiply in Montogmery form. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_1024_mont_mul_avx2_16(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) +{ + sp_1024_mul_avx2_16(r, a, b); + sp_1024_mont_reduce_avx2_16(r, m, mp); +} + +#endif /* HAVE_INTEL_AVX2 */ +#ifdef HAVE_INTEL_AVX2 +/* Square the Montgomery form number. (r = a * a mod m) + * + * r Result of squaring. + * a Number to square in Montogmery form. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_1024_mont_sqr_avx2_16(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) +{ + sp_1024_sqr_avx2_16(r, a); + sp_1024_mont_reduce_avx2_16(r, m, mp); +} + +#endif /* HAVE_INTEL_AVX2 */ + +/* Invert the number, in Montgomery form, modulo the modulus (prime) of the + * P1024 curve. (r = 1 / a mod m) + * + * r Inverse result. + * a Number to invert. + * td Temporary data. + */ +static void sp_1024_mont_inv_avx2_16(sp_digit* r, const sp_digit* a, + sp_digit* td) +{ + sp_digit* t = td; + int i; + int j; + sp_digit table[32][2 * 16]; + + XMEMCPY(table[0], a, sizeof(sp_digit) * 16); + for (i = 1; i < 6; i++) { + sp_1024_mont_sqr_avx2_16(table[0], table[0], p1024_mod, p1024_mp_mod); + } + for (i = 1; i < 32; i++) { + sp_1024_mont_mul_avx2_16(table[i], table[i-1], a, p1024_mod, p1024_mp_mod); + } + + XMEMCPY(t, table[p1024_mod_minus_2[1]], sizeof(sp_digit) * 16); + for (i = 2; i < (int)sizeof(p1024_mod_minus_2) - 2; i += 2) { + for (j = 0; j < p1024_mod_minus_2[i]; j++) { + sp_1024_mont_sqr_avx2_16(t, t, p1024_mod, p1024_mp_mod); + } + sp_1024_mont_mul_avx2_16(t, t, table[p1024_mod_minus_2[i+1]], p1024_mod, + p1024_mp_mod); + } + sp_1024_mont_sqr_avx2_16(t, t, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(r, t, a, p1024_mod, p1024_mp_mod); +} + +/* Map the Montgomery form projective coordinate point to an affine point. + * + * r Resulting affine coordinate point. + * p Montgomery form projective coordinate point. + * t Temporary ordinate data. + */ +static void sp_1024_map_avx2_16(sp_point_1024* r, const sp_point_1024* p, + sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*16; + int64_t n; + + sp_1024_mont_inv_avx2_16(t1, p->z, t + 2*16); + + sp_1024_mont_sqr_avx2_16(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(t1, t2, t1, p1024_mod, p1024_mp_mod); + + /* x /= z^2 */ + sp_1024_mont_mul_avx2_16(r->x, p->x, t2, p1024_mod, p1024_mp_mod); + XMEMSET(r->x + 16, 0, sizeof(r->x) / 2U); + sp_1024_mont_reduce_avx2_16(r->x, p1024_mod, p1024_mp_mod); + /* Reduce x to less than modulus */ + n = sp_1024_cmp_16(r->x, p1024_mod); + sp_1024_cond_sub_16(r->x, r->x, p1024_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_16(r->x); + + /* y /= z^3 */ + sp_1024_mont_mul_avx2_16(r->y, p->y, t1, p1024_mod, p1024_mp_mod); + XMEMSET(r->y + 16, 0, sizeof(r->y) / 2U); + sp_1024_mont_reduce_avx2_16(r->y, p1024_mod, p1024_mp_mod); + /* Reduce y to less than modulus */ + n = sp_1024_cmp_16(r->y, p1024_mod); + sp_1024_cond_sub_avx2_16(r->y, r->y, p1024_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_16(r->y); + + XMEMSET(r->z, 0, sizeof(r->z)); + r->z[0] = 1; + +} + +extern void sp_1024_mont_add_avx2_16(sp_digit* r, const sp_digit* a, const sp_digit* b, const sp_digit* m); +extern void sp_1024_mont_dbl_avx2_16(sp_digit* r, const sp_digit* a, const sp_digit* m); +extern void sp_1024_mont_tpl_avx2_16(sp_digit* r, const sp_digit* a, const sp_digit* m); +extern void sp_1024_mont_sub_avx2_16(sp_digit* r, const sp_digit* a, const sp_digit* b, const sp_digit* m); +extern void sp_1024_div2_avx2_16(sp_digit* r, const sp_digit* a, const sp_digit* m); +/* Double the Montgomery form projective point p. + * + * r Result of doubling point. + * p Point to double. + * t Temporary ordinate data. + */ +#ifdef WOLFSSL_SP_NONBLOCK +typedef struct sp_1024_proj_point_dbl_avx2_16_ctx { + int state; + sp_digit* t1; + sp_digit* t2; + sp_digit* x; + sp_digit* y; + sp_digit* z; +} sp_1024_proj_point_dbl_avx2_16_ctx; + +static int sp_1024_proj_point_dbl_avx2_16_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r, const sp_point_1024* p, sp_digit* t) +{ + int err = FP_WOULDBLOCK; + sp_1024_proj_point_dbl_avx2_16_ctx* ctx = (sp_1024_proj_point_dbl_avx2_16_ctx*)sp_ctx->data; + + typedef char ctx_size_test[sizeof(sp_1024_proj_point_dbl_avx2_16_ctx) >= sizeof(*sp_ctx) ? -1 : 1]; + (void)sizeof(ctx_size_test); + + switch (ctx->state) { + case 0: + ctx->t1 = t; + ctx->t2 = t + 2*16; + ctx->x = r->x; + ctx->y = r->y; + ctx->z = r->z; + + /* Put infinity into result. */ + if (r != p) { + r->infinity = p->infinity; + } + ctx->state = 1; + break; + case 1: + /* T1 = Z * Z */ + sp_1024_mont_sqr_avx2_16(ctx->t1, p->z, p1024_mod, p1024_mp_mod); + ctx->state = 2; + break; + case 2: + /* Z = Y * Z */ + sp_1024_mont_mul_avx2_16(ctx->z, p->y, p->z, p1024_mod, p1024_mp_mod); + ctx->state = 3; + break; + case 3: + /* Z = 2Z */ + sp_1024_mont_dbl_avx2_16(ctx->z, ctx->z, p1024_mod); + ctx->state = 4; + break; + case 4: + /* T2 = X - T1 */ + sp_1024_mont_sub_avx2_16(ctx->t2, p->x, ctx->t1, p1024_mod); + ctx->state = 5; + break; + case 5: + /* T1 = X + T1 */ + sp_1024_mont_add_avx2_16(ctx->t1, p->x, ctx->t1, p1024_mod); + ctx->state = 6; + break; + case 6: + /* T2 = T1 * T2 */ + sp_1024_mont_mul_avx2_16(ctx->t2, ctx->t1, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 7; + break; + case 7: + /* T1 = 3T2 */ + sp_1024_mont_tpl_avx2_16(ctx->t1, ctx->t2, p1024_mod); + ctx->state = 8; + break; + case 8: + /* Y = 2Y */ + sp_1024_mont_dbl_avx2_16(ctx->y, p->y, p1024_mod); + ctx->state = 9; + break; + case 9: + /* Y = Y * Y */ + sp_1024_mont_sqr_avx2_16(ctx->y, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 10; + break; + case 10: + /* T2 = Y * Y */ + sp_1024_mont_sqr_avx2_16(ctx->t2, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 11; + break; + case 11: + /* T2 = T2/2 */ + sp_1024_div2_avx2_16(ctx->t2, ctx->t2, p1024_mod); + ctx->state = 12; + break; + case 12: + /* Y = Y * X */ + sp_1024_mont_mul_avx2_16(ctx->y, ctx->y, p->x, p1024_mod, p1024_mp_mod); + ctx->state = 13; + break; + case 13: + /* X = T1 * T1 */ + sp_1024_mont_sqr_avx2_16(ctx->x, ctx->t1, p1024_mod, p1024_mp_mod); + ctx->state = 14; + break; + case 14: + /* X = X - Y */ + sp_1024_mont_sub_avx2_16(ctx->x, ctx->x, ctx->y, p1024_mod); + ctx->state = 15; + break; + case 15: + /* X = X - Y */ + sp_1024_mont_sub_avx2_16(ctx->x, ctx->x, ctx->y, p1024_mod); + ctx->state = 16; + break; + case 16: + /* Y = Y - X */ + sp_1024_mont_sub_avx2_16(ctx->y, ctx->y, ctx->x, p1024_mod); + ctx->state = 17; + break; + case 17: + /* Y = Y * T1 */ + sp_1024_mont_mul_avx2_16(ctx->y, ctx->y, ctx->t1, p1024_mod, p1024_mp_mod); + ctx->state = 18; + break; + case 18: + /* Y = Y - T2 */ + sp_1024_mont_sub_avx2_16(ctx->y, ctx->y, ctx->t2, p1024_mod); + ctx->state = 19; + /* fall-through */ + case 19: + err = MP_OKAY; + break; + } + + if (err == MP_OKAY && ctx->state != 19) { + err = FP_WOULDBLOCK; + } + + return err; +} +#endif /* WOLFSSL_SP_NONBLOCK */ + +static void sp_1024_proj_point_dbl_avx2_16(sp_point_1024* r, const sp_point_1024* p, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*16; + sp_digit* x; + sp_digit* y; + sp_digit* z; + + x = r->x; + y = r->y; + z = r->z; + /* Put infinity into result. */ + if (r != p) { + r->infinity = p->infinity; + } + + /* T1 = Z * Z */ + sp_1024_mont_sqr_avx2_16(t1, p->z, p1024_mod, p1024_mp_mod); + /* Z = Y * Z */ + sp_1024_mont_mul_avx2_16(z, p->y, p->z, p1024_mod, p1024_mp_mod); + /* Z = 2Z */ + sp_1024_mont_dbl_avx2_16(z, z, p1024_mod); + /* T2 = X - T1 */ + sp_1024_mont_sub_avx2_16(t2, p->x, t1, p1024_mod); + /* T1 = X + T1 */ + sp_1024_mont_add_avx2_16(t1, p->x, t1, p1024_mod); + /* T2 = T1 * T2 */ + sp_1024_mont_mul_avx2_16(t2, t1, t2, p1024_mod, p1024_mp_mod); + /* T1 = 3T2 */ + sp_1024_mont_tpl_avx2_16(t1, t2, p1024_mod); + /* Y = 2Y */ + sp_1024_mont_dbl_avx2_16(y, p->y, p1024_mod); + /* Y = Y * Y */ + sp_1024_mont_sqr_avx2_16(y, y, p1024_mod, p1024_mp_mod); + /* T2 = Y * Y */ + sp_1024_mont_sqr_avx2_16(t2, y, p1024_mod, p1024_mp_mod); + /* T2 = T2/2 */ + sp_1024_div2_avx2_16(t2, t2, p1024_mod); + /* Y = Y * X */ + sp_1024_mont_mul_avx2_16(y, y, p->x, p1024_mod, p1024_mp_mod); + /* X = T1 * T1 */ + sp_1024_mont_sqr_avx2_16(x, t1, p1024_mod, p1024_mp_mod); + /* X = X - Y */ + sp_1024_mont_sub_avx2_16(x, x, y, p1024_mod); + /* X = X - Y */ + sp_1024_mont_sub_avx2_16(x, x, y, p1024_mod); + /* Y = Y - X */ + sp_1024_mont_sub_avx2_16(y, y, x, p1024_mod); + /* Y = Y * T1 */ + sp_1024_mont_mul_avx2_16(y, y, t1, p1024_mod, p1024_mp_mod); + /* Y = Y - T2 */ + sp_1024_mont_sub_avx2_16(y, y, t2, p1024_mod); +} + +/* Double the Montgomery form projective point p a number of times. + * + * r Result of repeated doubling of point. + * p Point to double. + * n Number of times to double + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_dbl_n_avx2_16(sp_point_1024* p, int n, + sp_digit* t) +{ + sp_digit* w = t; + sp_digit* a = t + 2*16; + sp_digit* b = t + 4*16; + sp_digit* t1 = t + 6*16; + sp_digit* t2 = t + 8*16; + sp_digit* x; + sp_digit* y; + sp_digit* z; + + x = p->x; + y = p->y; + z = p->z; + + /* Y = 2*Y */ + sp_1024_mont_dbl_avx2_16(y, y, p1024_mod); + /* W = Z^4 */ + sp_1024_mont_sqr_avx2_16(w, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_avx2_16(w, w, p1024_mod, p1024_mp_mod); + +#ifndef WOLFSSL_SP_SMALL + while (--n > 0) +#else + while (--n >= 0) +#endif + { + /* A = 3*(X^2 - W) */ + sp_1024_mont_sqr_avx2_16(t1, x, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_avx2_16(t1, t1, w, p1024_mod); + sp_1024_mont_tpl_avx2_16(a, t1, p1024_mod); + /* B = X*Y^2 */ + sp_1024_mont_sqr_avx2_16(t1, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(b, t1, x, p1024_mod, p1024_mp_mod); + /* X = A^2 - 2B */ + sp_1024_mont_sqr_avx2_16(x, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_avx2_16(t2, b, p1024_mod); + sp_1024_mont_sub_avx2_16(x, x, t2, p1024_mod); + /* Z = Z*Y */ + sp_1024_mont_mul_avx2_16(z, z, y, p1024_mod, p1024_mp_mod); + /* t2 = Y^4 */ + sp_1024_mont_sqr_avx2_16(t1, t1, p1024_mod, p1024_mp_mod); +#ifdef WOLFSSL_SP_SMALL + if (n != 0) +#endif + { + /* W = W*Y^4 */ + sp_1024_mont_mul_avx2_16(w, w, t1, p1024_mod, p1024_mp_mod); + } + /* y = 2*A*(B - X) - Y^4 */ + sp_1024_mont_sub_avx2_16(y, b, x, p1024_mod); + sp_1024_mont_mul_avx2_16(y, y, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_avx2_16(y, y, p1024_mod); + sp_1024_mont_sub_avx2_16(y, y, t1, p1024_mod); + } +#ifndef WOLFSSL_SP_SMALL + /* A = 3*(X^2 - W) */ + sp_1024_mont_sqr_avx2_16(t1, x, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_avx2_16(t1, t1, w, p1024_mod); + sp_1024_mont_tpl_avx2_16(a, t1, p1024_mod); + /* B = X*Y^2 */ + sp_1024_mont_sqr_avx2_16(t1, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(b, t1, x, p1024_mod, p1024_mp_mod); + /* X = A^2 - 2B */ + sp_1024_mont_sqr_avx2_16(x, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_avx2_16(t2, b, p1024_mod); + sp_1024_mont_sub_avx2_16(x, x, t2, p1024_mod); + /* Z = Z*Y */ + sp_1024_mont_mul_avx2_16(z, z, y, p1024_mod, p1024_mp_mod); + /* t2 = Y^4 */ + sp_1024_mont_sqr_avx2_16(t1, t1, p1024_mod, p1024_mp_mod); + /* y = 2*A*(B - X) - Y^4 */ + sp_1024_mont_sub_avx2_16(y, b, x, p1024_mod); + sp_1024_mont_mul_avx2_16(y, y, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_avx2_16(y, y, p1024_mod); + sp_1024_mont_sub_avx2_16(y, y, t1, p1024_mod); +#endif + /* Y = Y/2 */ + sp_1024_div2_avx2_16(y, y, p1024_mod); +} + +/* Add two Montgomery form projective points. + * + * r Result of addition. + * p First point to add. + * q Second point to add. + * t Temporary ordinate data. + */ + +#ifdef WOLFSSL_SP_NONBLOCK +typedef struct sp_1024_proj_point_add_avx2_16_ctx { + int state; + sp_1024_proj_point_dbl_avx2_16_ctx dbl_ctx; + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1; + sp_digit* t2; + sp_digit* t3; + sp_digit* t4; + sp_digit* t5; + sp_digit* x; + sp_digit* y; + sp_digit* z; +} sp_1024_proj_point_add_avx2_16_ctx; + +static int sp_1024_proj_point_add_avx2_16_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r, + const sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + int err = FP_WOULDBLOCK; + sp_1024_proj_point_add_avx2_16_ctx* ctx = (sp_1024_proj_point_add_avx2_16_ctx*)sp_ctx->data; + + /* Ensure only the first point is the same as the result. */ + if (q == r) { + const sp_point_1024* a = p; + p = q; + q = a; + } + + typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_avx2_16_ctx) >= sizeof(*sp_ctx) ? -1 : 1]; + (void)sizeof(ctx_size_test); + + switch (ctx->state) { + case 0: /* INIT */ + ctx->t1 = t; + ctx->t2 = t + 2*16; + ctx->t3 = t + 4*16; + ctx->t4 = t + 6*16; + ctx->t5 = t + 8*16; + + ctx->state = 1; + break; + case 1: + /* Check double */ + (void)sp_1024_sub_avx2_16(ctx->t1, p1024_mod, q->y); + sp_1024_norm_avx2_16(ctx->t1); + if ((sp_1024_cmp_equal_avx2_16(p->x, q->x) & sp_1024_cmp_equal_avx2_16(p->z, q->z) & + (sp_1024_cmp_equal_avx2_16(p->y, q->y) | sp_1024_cmp_equal_avx2_16(p->y, ctx->t1))) != 0) + { + XMEMSET(&ctx->dbl_ctx, 0, sizeof(ctx->dbl_ctx)); + ctx->state = 2; + } + else { + ctx->state = 3; + } + break; + case 2: + err = sp_1024_proj_point_dbl_avx2_16_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, r, p, t); + if (err == MP_OKAY) + ctx->state = 27; /* done */ + break; + case 3: + { + int i; + ctx->rp[0] = r; + + /*lint allow cast to different type of pointer*/ + ctx->rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(ctx->rp[1], 0, sizeof(sp_point_1024)); + ctx->x = ctx->rp[p->infinity | q->infinity]->x; + ctx->y = ctx->rp[p->infinity | q->infinity]->y; + ctx->z = ctx->rp[p->infinity | q->infinity]->z; + + ctx->ap[0] = p; + ctx->ap[1] = q; + for (i=0; i<16; i++) { + r->x[i] = ctx->ap[p->infinity]->x[i]; + } + for (i=0; i<16; i++) { + r->y[i] = ctx->ap[p->infinity]->y[i]; + } + for (i=0; i<16; i++) { + r->z[i] = ctx->ap[p->infinity]->z[i]; + } + r->infinity = ctx->ap[p->infinity]->infinity; + + ctx->state = 4; + break; + } + case 4: + /* U1 = X1*Z2^2 */ + sp_1024_mont_sqr_avx2_16(ctx->t1, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 5; + break; + case 5: + sp_1024_mont_mul_avx2_16(ctx->t3, ctx->t1, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 6; + break; + case 6: + sp_1024_mont_mul_avx2_16(ctx->t1, ctx->t1, ctx->x, p1024_mod, p1024_mp_mod); + ctx->state = 7; + break; + case 7: + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_avx2_16(ctx->t2, ctx->z, p1024_mod, p1024_mp_mod); + ctx->state = 8; + break; + case 8: + sp_1024_mont_mul_avx2_16(ctx->t4, ctx->t2, ctx->z, p1024_mod, p1024_mp_mod); + ctx->state = 9; + break; + case 9: + sp_1024_mont_mul_avx2_16(ctx->t2, ctx->t2, q->x, p1024_mod, p1024_mp_mod); + ctx->state = 10; + break; + case 10: + /* S1 = Y1*Z2^3 */ + sp_1024_mont_mul_avx2_16(ctx->t3, ctx->t3, ctx->y, p1024_mod, p1024_mp_mod); + ctx->state = 11; + break; + case 11: + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_avx2_16(ctx->t4, ctx->t4, q->y, p1024_mod, p1024_mp_mod); + ctx->state = 12; + break; + case 12: + /* H = U2 - U1 */ + sp_1024_mont_sub_avx2_16(ctx->t2, ctx->t2, ctx->t1, p1024_mod); + ctx->state = 13; + break; + case 13: + /* R = S2 - S1 */ + sp_1024_mont_sub_avx2_16(ctx->t4, ctx->t4, ctx->t3, p1024_mod); + ctx->state = 14; + break; + case 14: + /* Z3 = H*Z1*Z2 */ + sp_1024_mont_mul_avx2_16(ctx->z, ctx->z, q->z, p1024_mod, p1024_mp_mod); + ctx->state = 15; + break; + case 15: + sp_1024_mont_mul_avx2_16(ctx->z, ctx->z, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 16; + break; + case 16: + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_1024_mont_sqr_avx2_16(ctx->x, ctx->t4, p1024_mod, p1024_mp_mod); + ctx->state = 17; + break; + case 17: + sp_1024_mont_sqr_avx2_16(ctx->t5, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 18; + break; + case 18: + sp_1024_mont_mul_avx2_16(ctx->y, ctx->t1, ctx->t5, p1024_mod, p1024_mp_mod); + ctx->state = 19; + break; + case 19: + sp_1024_mont_mul_avx2_16(ctx->t5, ctx->t5, ctx->t2, p1024_mod, p1024_mp_mod); + ctx->state = 20; + break; + case 20: + sp_1024_mont_sub_avx2_16(ctx->x, ctx->x, ctx->t5, p1024_mod); + ctx->state = 21; + break; + case 21: + sp_1024_mont_dbl_avx2_16(ctx->t1, ctx->y, p1024_mod); + ctx->state = 22; + break; + case 22: + sp_1024_mont_sub_avx2_16(ctx->x, ctx->x, ctx->t1, p1024_mod); + ctx->state = 23; + break; + case 23: + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_1024_mont_sub_avx2_16(ctx->y, ctx->y, ctx->x, p1024_mod); + ctx->state = 24; + break; + case 24: + sp_1024_mont_mul_avx2_16(ctx->y, ctx->y, ctx->t4, p1024_mod, p1024_mp_mod); + ctx->state = 25; + break; + case 25: + sp_1024_mont_mul_avx2_16(ctx->t5, ctx->t5, ctx->t3, p1024_mod, p1024_mp_mod); + ctx->state = 26; + break; + case 26: + sp_1024_mont_sub_avx2_16(ctx->y, ctx->y, ctx->t5, p1024_mod); + ctx->state = 27; + /* fall-through */ + case 27: + err = MP_OKAY; + break; + } + + if (err == MP_OKAY && ctx->state != 27) { + err = FP_WOULDBLOCK; + } + return err; +} +#endif /* WOLFSSL_SP_NONBLOCK */ + +static void sp_1024_proj_point_add_avx2_16(sp_point_1024* r, + const sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*16; + sp_digit* t3 = t + 4*16; + sp_digit* t4 = t + 6*16; + sp_digit* t5 = t + 8*16; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Ensure only the first point is the same as the result. */ + if (q == r) { + const sp_point_1024* a = p; + p = q; + q = a; + } + + /* Check double */ + (void)sp_1024_mont_sub_avx2_16(t1, p1024_mod, q->y, p1024_mod); + sp_1024_norm_16(t1); + if ((sp_1024_cmp_equal_16(p->x, q->x) & sp_1024_cmp_equal_16(p->z, q->z) & + (sp_1024_cmp_equal_16(p->y, q->y) | sp_1024_cmp_equal_16(p->y, t1))) != 0) { + sp_1024_proj_point_dbl_avx2_16(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_1024)); + x = rp[p->infinity | q->infinity]->x; + y = rp[p->infinity | q->infinity]->y; + z = rp[p->infinity | q->infinity]->z; + + ap[0] = p; + ap[1] = q; + for (i=0; i<16; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<16; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<16; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U1 = X1*Z2^2 */ + sp_1024_mont_sqr_avx2_16(t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(t3, t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(t1, t1, x, p1024_mod, p1024_mp_mod); + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_avx2_16(t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(t4, t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(t2, t2, q->x, p1024_mod, p1024_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_1024_mont_mul_avx2_16(t3, t3, y, p1024_mod, p1024_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_avx2_16(t4, t4, q->y, p1024_mod, p1024_mp_mod); + /* H = U2 - U1 */ + sp_1024_mont_sub_avx2_16(t2, t2, t1, p1024_mod); + /* R = S2 - S1 */ + sp_1024_mont_sub_avx2_16(t4, t4, t3, p1024_mod); + /* Z3 = H*Z1*Z2 */ + sp_1024_mont_mul_avx2_16(z, z, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(z, z, t2, p1024_mod, p1024_mp_mod); + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_1024_mont_sqr_avx2_16(x, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_avx2_16(t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(y, t1, t5, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(t5, t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_avx2_16(x, x, t5, p1024_mod); + sp_1024_mont_dbl_avx2_16(t1, y, p1024_mod); + sp_1024_mont_sub_avx2_16(x, x, t1, p1024_mod); + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_1024_mont_sub_avx2_16(y, y, x, p1024_mod); + sp_1024_mont_mul_avx2_16(y, y, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(t5, t5, t3, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_avx2_16(y, y, t5, p1024_mod); + } +} + +/* Double the Montgomery form projective point p a number of times. + * + * r Result of repeated doubling of point. + * p Point to double. + * n Number of times to double + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_dbl_n_store_avx2_16(sp_point_1024* r, + const sp_point_1024* p, int n, int m, sp_digit* t) +{ + sp_digit* w = t; + sp_digit* a = t + 2*16; + sp_digit* b = t + 4*16; + sp_digit* t1 = t + 6*16; + sp_digit* t2 = t + 8*16; + sp_digit* x = r[2*m].x; + sp_digit* y = r[(1<x[i]; + } + for (i=0; i<16; i++) { + y[i] = p->y[i]; + } + for (i=0; i<16; i++) { + z[i] = p->z[i]; + } + + /* Y = 2*Y */ + sp_1024_mont_dbl_avx2_16(y, y, p1024_mod); + /* W = Z^4 */ + sp_1024_mont_sqr_avx2_16(w, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_avx2_16(w, w, p1024_mod, p1024_mp_mod); + j = m; + for (i=1; i<=n; i++) { + j *= 2; + + /* A = 3*(X^2 - W) */ + sp_1024_mont_sqr_avx2_16(t1, x, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_avx2_16(t1, t1, w, p1024_mod); + sp_1024_mont_tpl_avx2_16(a, t1, p1024_mod); + /* B = X*Y^2 */ + sp_1024_mont_sqr_avx2_16(t2, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(b, t2, x, p1024_mod, p1024_mp_mod); + x = r[j].x; + /* X = A^2 - 2B */ + sp_1024_mont_sqr_avx2_16(x, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_avx2_16(t1, b, p1024_mod); + sp_1024_mont_sub_avx2_16(x, x, t1, p1024_mod); + /* Z = Z*Y */ + sp_1024_mont_mul_avx2_16(r[j].z, z, y, p1024_mod, p1024_mp_mod); + z = r[j].z; + /* t2 = Y^4 */ + sp_1024_mont_sqr_avx2_16(t2, t2, p1024_mod, p1024_mp_mod); + if (i != n) { + /* W = W*Y^4 */ + sp_1024_mont_mul_avx2_16(w, w, t2, p1024_mod, p1024_mp_mod); + } + /* y = 2*A*(B - X) - Y^4 */ + sp_1024_mont_sub_avx2_16(y, b, x, p1024_mod); + sp_1024_mont_mul_avx2_16(y, y, a, p1024_mod, p1024_mp_mod); + sp_1024_mont_dbl_avx2_16(y, y, p1024_mod); + sp_1024_mont_sub_avx2_16(y, y, t2, p1024_mod); + + /* Y = Y/2 */ + sp_1024_div2_avx2_16(r[j].y, y, p1024_mod); + r[j].infinity = 0; + } +} + +/* Add two Montgomery form projective points. + * + * ra Result of addition. + * rs Result of subtraction. + * p First point to add. + * q Second point to add. + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_add_sub_avx2_16(sp_point_1024* ra, + sp_point_1024* rs, const sp_point_1024* p, const sp_point_1024* q, + sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*16; + sp_digit* t3 = t + 4*16; + sp_digit* t4 = t + 6*16; + sp_digit* t5 = t + 8*16; + sp_digit* t6 = t + 10*16; + sp_digit* x = ra->x; + sp_digit* y = ra->y; + sp_digit* z = ra->z; + sp_digit* xs = rs->x; + sp_digit* ys = rs->y; + sp_digit* zs = rs->z; + + + XMEMCPY(x, p->x, sizeof(p->x) / 2); + XMEMCPY(y, p->y, sizeof(p->y) / 2); + XMEMCPY(z, p->z, sizeof(p->z) / 2); + ra->infinity = 0; + rs->infinity = 0; + + /* U1 = X1*Z2^2 */ + sp_1024_mont_sqr_avx2_16(t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(t3, t1, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(t1, t1, x, p1024_mod, p1024_mp_mod); + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_avx2_16(t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(t4, t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(t2, t2, q->x, p1024_mod, p1024_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_1024_mont_mul_avx2_16(t3, t3, y, p1024_mod, p1024_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_avx2_16(t4, t4, q->y, p1024_mod, p1024_mp_mod); + /* H = U2 - U1 */ + sp_1024_mont_sub_avx2_16(t2, t2, t1, p1024_mod); + /* RS = S2 + S1 */ + sp_1024_mont_add_avx2_16(t6, t4, t3, p1024_mod); + /* R = S2 - S1 */ + sp_1024_mont_sub_avx2_16(t4, t4, t3, p1024_mod); + /* Z3 = H*Z1*Z2 */ + /* ZS = H*Z1*Z2 */ + sp_1024_mont_mul_avx2_16(z, z, q->z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(z, z, t2, p1024_mod, p1024_mp_mod); + XMEMCPY(zs, z, sizeof(p->z)/2); + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + /* XS = RS^2 - H^3 - 2*U1*H^2 */ + sp_1024_mont_sqr_avx2_16(x, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_avx2_16(xs, t6, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_avx2_16(t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(y, t1, t5, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(t5, t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_avx2_16(x, x, t5, p1024_mod); + sp_1024_mont_sub_avx2_16(xs, xs, t5, p1024_mod); + sp_1024_mont_dbl_avx2_16(t1, y, p1024_mod); + sp_1024_mont_sub_avx2_16(x, x, t1, p1024_mod); + sp_1024_mont_sub_avx2_16(xs, xs, t1, p1024_mod); + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + /* YS = -RS*(U1*H^2 - XS) - S1*H^3 */ + sp_1024_mont_sub_avx2_16(ys, y, xs, p1024_mod); + sp_1024_mont_sub_avx2_16(y, y, x, p1024_mod); + sp_1024_mont_mul_avx2_16(y, y, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_avx2_16(t6, p1024_mod, t6, p1024_mod); + sp_1024_mont_mul_avx2_16(ys, ys, t6, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(t5, t5, t3, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_avx2_16(y, y, t5, p1024_mod); + sp_1024_mont_sub_avx2_16(ys, ys, t5, p1024_mod); +} + +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Window technique of 7 bits. (Add-Sub variation.) + * Calculate 0..64 times the point. Use function that adds and + * subtracts the same two points. + * Recode to add or subtract one of the computed points. + * Double to push up. + * NOT a sliding window. + * + * r Resulting point. + * g Point to multiply. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_win_add_sub_avx2_16(sp_point_1024* r, const sp_point_1024* g, + const sp_digit* k, int map, int ct, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 td[65]; + sp_point_1024 rtd; + sp_point_1024 pd; + sp_digit tmpd[2 * 16 * 6]; +#endif + sp_point_1024* t; + sp_point_1024* rt; + sp_point_1024* p = NULL; + sp_digit* tmp; + sp_digit* negy; + int i; + ecc_recode_1024 v[147]; + int err; + + /* Constant time used for cache attack resistance implementation. */ + (void)ct; + (void)heap; + + err = sp_1024_point_new_16(heap, rtd, rt); + if (err == MP_OKAY) + err = sp_1024_point_new_16(heap, pd, p); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = (sp_point_1024*)XMALLOC(sizeof(sp_point_1024) * 65, heap, DYNAMIC_TYPE_ECC); + if (t == NULL) + err = MEMORY_E; + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 16 * 6, heap, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) + err = MEMORY_E; +#else + t = td; + tmp = tmpd; +#endif + + + if (err == MP_OKAY) { + /* t[0] = {0, 0, 1} * norm */ + XMEMSET(&t[0], 0, sizeof(t[0])); + t[0].infinity = 1; + /* t[1] = {g->x, g->y, g->z} * norm */ + err = sp_1024_mod_mul_norm_avx2_16(t[1].x, g->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_avx2_16(t[1].y, g->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_avx2_16(t[1].z, g->z, p1024_mod); + } + + if (err == MP_OKAY) { + t[1].infinity = 0; + /* t[2] ... t[64] */ + sp_1024_proj_point_dbl_n_store_avx2_16(t, &t[ 1], 6, 1, tmp); + sp_1024_proj_point_add_avx2_16(&t[ 3], &t[ 2], &t[ 1], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[ 6], &t[ 3], tmp); + sp_1024_proj_point_add_sub_avx2_16(&t[ 7], &t[ 5], &t[ 6], &t[ 1], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[10], &t[ 5], tmp); + sp_1024_proj_point_add_sub_avx2_16(&t[11], &t[ 9], &t[10], &t[ 1], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[12], &t[ 6], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[14], &t[ 7], tmp); + sp_1024_proj_point_add_sub_avx2_16(&t[15], &t[13], &t[14], &t[ 1], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[18], &t[ 9], tmp); + sp_1024_proj_point_add_sub_avx2_16(&t[19], &t[17], &t[18], &t[ 1], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[20], &t[10], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[22], &t[11], tmp); + sp_1024_proj_point_add_sub_avx2_16(&t[23], &t[21], &t[22], &t[ 1], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[24], &t[12], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[26], &t[13], tmp); + sp_1024_proj_point_add_sub_avx2_16(&t[27], &t[25], &t[26], &t[ 1], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[28], &t[14], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[30], &t[15], tmp); + sp_1024_proj_point_add_sub_avx2_16(&t[31], &t[29], &t[30], &t[ 1], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[34], &t[17], tmp); + sp_1024_proj_point_add_sub_avx2_16(&t[35], &t[33], &t[34], &t[ 1], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[36], &t[18], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[38], &t[19], tmp); + sp_1024_proj_point_add_sub_avx2_16(&t[39], &t[37], &t[38], &t[ 1], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[40], &t[20], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[42], &t[21], tmp); + sp_1024_proj_point_add_sub_avx2_16(&t[43], &t[41], &t[42], &t[ 1], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[44], &t[22], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[46], &t[23], tmp); + sp_1024_proj_point_add_sub_avx2_16(&t[47], &t[45], &t[46], &t[ 1], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[48], &t[24], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[50], &t[25], tmp); + sp_1024_proj_point_add_sub_avx2_16(&t[51], &t[49], &t[50], &t[ 1], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[52], &t[26], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[54], &t[27], tmp); + sp_1024_proj_point_add_sub_avx2_16(&t[55], &t[53], &t[54], &t[ 1], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[56], &t[28], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[58], &t[29], tmp); + sp_1024_proj_point_add_sub_avx2_16(&t[59], &t[57], &t[58], &t[ 1], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[60], &t[30], tmp); + sp_1024_proj_point_dbl_avx2_16(&t[62], &t[31], tmp); + sp_1024_proj_point_add_sub_avx2_16(&t[63], &t[61], &t[62], &t[ 1], tmp); + + negy = t[0].y; + + sp_1024_ecc_recode_7_16(k, v); + + i = 146; + XMEMCPY(rt, &t[v[i].i], sizeof(sp_point_1024)); + for (--i; i>=0; i--) { + sp_1024_proj_point_dbl_n_avx2_16(rt, 7, tmp); + XMEMCPY(p, &t[v[i].i], sizeof(sp_point_1024)); + sp_1024_mont_sub_avx2_16(negy, p1024_mod, p->y, p1024_mod); + sp_1024_norm_16(negy); + sp_1024_cond_copy_16(p->y, negy, (sp_digit)0 - v[i].neg); + sp_1024_proj_point_add_avx2_16(rt, rt, p, tmp); + } + + if (map != 0) { + sp_1024_map_avx2_16(r, rt, tmp); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_1024)); + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (t != NULL) + XFREE(t, heap, DYNAMIC_TYPE_ECC); + if (tmp != NULL) + XFREE(tmp, heap, DYNAMIC_TYPE_ECC); +#endif + sp_1024_point_free_16(p, 0, heap); + sp_1024_point_free_16(rt, 0, heap); + + return err; +} + +#endif /* HAVE_INTEL_AVX2 */ +/* A table entry for pre-computed points. */ +typedef struct sp_table_entry_1024 { + sp_digit x[16]; + sp_digit y[16]; +} sp_table_entry_1024; + +#ifdef FP_ECC +#endif /* FP_ECC */ +/* Add two Montgomery form projective points. The second point has a q value of + * one. + * Only the first point can be the same pointer as the result point. + * + * r Result of addition. + * p First point to add. + * q Second point to add. + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_add_qz1_16(sp_point_1024* r, const sp_point_1024* p, + const sp_point_1024* q, sp_digit* t) +{ + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*16; + sp_digit* t3 = t + 4*16; + sp_digit* t4 = t + 6*16; + sp_digit* t5 = t + 8*16; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Check double */ + (void)sp_1024_mont_sub_16(t1, p1024_mod, q->y, p1024_mod); + sp_1024_norm_16(t1); + if ((sp_1024_cmp_equal_16(p->x, q->x) & sp_1024_cmp_equal_16(p->z, q->z) & + (sp_1024_cmp_equal_16(p->y, q->y) | sp_1024_cmp_equal_16(p->y, t1))) != 0) { + sp_1024_proj_point_dbl_16(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_1024)); + x = rp[p->infinity | q->infinity]->x; + y = rp[p->infinity | q->infinity]->y; + z = rp[p->infinity | q->infinity]->z; + + ap[0] = p; + ap[1] = q; + for (i=0; i<16; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<16; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<16; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_16(t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t4, t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t2, t2, q->x, p1024_mod, p1024_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_16(t4, t4, q->y, p1024_mod, p1024_mp_mod); + /* H = U2 - X1 */ + sp_1024_mont_sub_16(t2, t2, x, p1024_mod); + /* R = S2 - Y1 */ + sp_1024_mont_sub_16(t4, t4, y, p1024_mod); + /* Z3 = H*Z1 */ + sp_1024_mont_mul_16(z, z, t2, p1024_mod, p1024_mp_mod); + /* X3 = R^2 - H^3 - 2*X1*H^2 */ + sp_1024_mont_sqr_16(t1, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_16(t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t3, x, t5, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t5, t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_16(x, t1, t5, p1024_mod); + sp_1024_mont_dbl_16(t1, t3, p1024_mod); + sp_1024_mont_sub_16(x, x, t1, p1024_mod); + /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */ + sp_1024_mont_sub_16(t3, t3, x, p1024_mod); + sp_1024_mont_mul_16(t3, t3, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t5, t5, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_16(y, t3, t5, p1024_mod); + } +} + +#if defined(FP_ECC) || !defined(WOLFSSL_SP_SMALL) +/* Convert the projective point to affine. + * Ordinates are in Montgomery form. + * + * a Point to convert. + * t Temporary data. + */ +static void sp_1024_proj_to_affine_16(sp_point_1024* a, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 16; + sp_digit* tmp = t + 4 * 16; + + sp_1024_mont_inv_16(t1, a->z, tmp); + + sp_1024_mont_sqr_16(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t1, t2, t1, p1024_mod, p1024_mp_mod); + + sp_1024_mont_mul_16(a->x, a->x, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(a->y, a->y, t1, p1024_mod, p1024_mp_mod); + XMEMCPY(a->z, p1024_norm_mod, sizeof(p1024_norm_mod)); +} + +/* Generate the pre-computed table of points for the base point. + * + * width = 8 + * 256 entries + * 128 bits between + * + * a The base point. + * table Place to store generated point data. + * tmp Temporary data. + * heap Heap to use for allocation. + */ +static int sp_1024_gen_stripe_table_16(const sp_point_1024* a, + sp_table_entry_1024* table, sp_digit* tmp, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 td; + sp_point_1024 s1d; + sp_point_1024 s2d; +#endif + sp_point_1024* t; + sp_point_1024* s1 = NULL; + sp_point_1024* s2 = NULL; + int i; + int j; + int err; + + (void)heap; + + err = sp_1024_point_new_16(heap, td, t); + if (err == MP_OKAY) { + err = sp_1024_point_new_16(heap, s1d, s1); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_16(heap, s2d, s2); + } + + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(t->x, a->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(t->y, a->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(t->z, a->z, p1024_mod); + } + if (err == MP_OKAY) { + t->infinity = 0; + sp_1024_proj_to_affine_16(t, tmp); + + XMEMCPY(s1->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + s1->infinity = 0; + XMEMCPY(s2->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + s2->infinity = 0; + + /* table[0] = {0, 0, infinity} */ + XMEMSET(&table[0], 0, sizeof(sp_table_entry_1024)); + /* table[1] = Affine version of 'a' in Montgomery form */ + XMEMCPY(table[1].x, t->x, sizeof(table->x)); + XMEMCPY(table[1].y, t->y, sizeof(table->y)); + + for (i=1; i<8; i++) { + sp_1024_proj_point_dbl_n_16(t, 128, tmp); + sp_1024_proj_to_affine_16(t, tmp); + XMEMCPY(table[1<x, sizeof(table->x)); + XMEMCPY(table[1<y, sizeof(table->y)); + } + + for (i=1; i<8; i++) { + XMEMCPY(s1->x, table[1<x)); + XMEMCPY(s1->y, table[1<y)); + for (j=(1<x, table[j-(1<x)); + XMEMCPY(s2->y, table[j-(1<y)); + sp_1024_proj_point_add_qz1_16(t, s1, s2, tmp); + sp_1024_proj_to_affine_16(t, tmp); + XMEMCPY(table[j].x, t->x, sizeof(table->x)); + XMEMCPY(table[j].y, t->y, sizeof(table->y)); + } + } + } + + sp_1024_point_free_16(s2, 0, heap); + sp_1024_point_free_16(s1, 0, heap); + sp_1024_point_free_16( t, 0, heap); + + return err; +} + +#endif /* FP_ECC | !WOLFSSL_SP_SMALL */ +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^128, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * table Pre-computed table. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_stripe_16(sp_point_1024* r, const sp_point_1024* g, + const sp_table_entry_1024* table, const sp_digit* k, int map, + int ct, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 rtd; + sp_point_1024 pd; + sp_digit td[2 * 16 * 5]; +#endif + sp_point_1024* rt; + sp_point_1024* p = NULL; + sp_digit* t; + int i; + int j; + int y; + int x; + int err; + + (void)g; + /* Constant time used for cache attack resistance implementation. */ + (void)ct; + (void)heap; + + + err = sp_1024_point_new_16(heap, rtd, rt); + if (err == MP_OKAY) { + err = sp_1024_point_new_16(heap, pd, p); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 16 * 5, heap, + DYNAMIC_TYPE_ECC); + if (t == NULL) { + err = MEMORY_E; + } +#else + t = td; +#endif + + if (err == MP_OKAY) { + XMEMCPY(p->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + XMEMCPY(rt->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + + y = 0; + x = 127; + for (j=0; j<8; j++) { + y |= (int)(((k[x / 64] >> (x % 64)) & 1) << j); + x += 128; + } + XMEMCPY(rt->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(rt->y, table[y].y, sizeof(table[y].y)); + rt->infinity = !y; + for (i=126; i>=0; i--) { + y = 0; + x = i; + for (j=0; j<8; j++) { + y |= (int)(((k[x / 64] >> (x % 64)) & 1) << j); + x += 128; + } + + sp_1024_proj_point_dbl_16(rt, rt, t); + XMEMCPY(p->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(p->y, table[y].y, sizeof(table[y].y)); + p->infinity = !y; + sp_1024_proj_point_add_qz1_16(rt, rt, p, t); + } + + if (map != 0) { + sp_1024_map_16(r, rt, t); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_1024)); + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (t != NULL) { + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_16(p, 0, heap); + sp_1024_point_free_16(rt, 0, heap); + + return err; +} + +#ifdef FP_ECC +#ifndef FP_ENTRIES + #define FP_ENTRIES 16 +#endif + +/* Cache entry - holds precomputation tables for a point. */ +typedef struct sp_cache_1024_t { + /* X ordinate of point that table was generated from. */ + sp_digit x[16]; + /* Y ordinate of point that table was generated from. */ + sp_digit y[16]; + /* Precomputation table for point. */ + sp_table_entry_1024 table[256]; + /* Count of entries in table. */ + uint32_t cnt; + /* Point and table set in entry. */ + int set; +} sp_cache_1024_t; + +/* Cache of tables. */ +static THREAD_LS_T sp_cache_1024_t sp_cache_1024[FP_ENTRIES]; +/* Index of last entry in cache. */ +static THREAD_LS_T int sp_cache_1024_last = -1; +/* Cache has been initialized. */ +static THREAD_LS_T int sp_cache_1024_inited = 0; + +#ifndef HAVE_THREAD_LS + static volatile int initCacheMutex_1024 = 0; + static wolfSSL_Mutex sp_cache_1024_lock; +#endif + +/* Get the cache entry for the point. + * + * g [in] Point scalar multipling. + * cache [out] Cache table to use. + */ +static void sp_ecc_get_cache_1024(const sp_point_1024* g, sp_cache_1024_t** cache) +{ + int i; + int j; + uint32_t least; + + if (sp_cache_1024_inited == 0) { + for (i=0; ix, sp_cache_1024[i].x) & + sp_1024_cmp_equal_16(g->y, sp_cache_1024[i].y)) { + sp_cache_1024[i].cnt++; + break; + } + } + + /* No match. */ + if (i == FP_ENTRIES) { + /* Find empty entry. */ + i = (sp_cache_1024_last + 1) % FP_ENTRIES; + for (; i != sp_cache_1024_last; i=(i+1)%FP_ENTRIES) { + if (!sp_cache_1024[i].set) { + break; + } + } + + /* Evict least used. */ + if (i == sp_cache_1024_last) { + least = sp_cache_1024[0].cnt; + for (j=1; jx, sizeof(sp_cache_1024[i].x)); + XMEMCPY(sp_cache_1024[i].y, g->y, sizeof(sp_cache_1024[i].y)); + sp_cache_1024[i].set = 1; + sp_cache_1024[i].cnt = 1; + } + + *cache = &sp_cache_1024[i]; + sp_cache_1024_last = i; +} +#endif /* FP_ECC */ + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * r Resulting point. + * g Point to multiply. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_16(sp_point_1024* r, const sp_point_1024* g, const sp_digit* k, + int map, int ct, void* heap) +{ +#ifndef FP_ECC + return sp_1024_ecc_mulmod_win_add_sub_16(r, g, k, map, ct, heap); +#else + sp_digit tmp[2 * 16 * 5]; + sp_cache_1024_t* cache; + int err = MP_OKAY; + +#ifndef HAVE_THREAD_LS + if (initCacheMutex_1024 == 0) { + wc_InitMutex(&sp_cache_1024_lock); + initCacheMutex_1024 = 1; + } + if (wc_LockMutex(&sp_cache_1024_lock) != 0) + err = BAD_MUTEX_E; +#endif /* HAVE_THREAD_LS */ + + if (err == MP_OKAY) { + sp_ecc_get_cache_1024(g, &cache); + if (cache->cnt == 2) + sp_1024_gen_stripe_table_16(g, cache->table, tmp, heap); + +#ifndef HAVE_THREAD_LS + wc_UnLockMutex(&sp_cache_1024_lock); +#endif /* HAVE_THREAD_LS */ + + if (cache->cnt < 2) { + err = sp_1024_ecc_mulmod_win_add_sub_16(r, g, k, map, ct, heap); + } + else { + err = sp_1024_ecc_mulmod_stripe_16(r, g, cache->table, k, + map, ct, heap); + } + } + + return err; +#endif +} + +#ifdef HAVE_INTEL_AVX2 +#ifdef FP_ECC +#endif /* FP_ECC */ +/* Add two Montgomery form projective points. The second point has a q value of + * one. + * Only the first point can be the same pointer as the result point. + * + * r Result of addition. + * p First point to add. + * q Second point to add. + * t Temporary ordinate data. + */ +static void sp_1024_proj_point_add_qz1_avx2_16(sp_point_1024* r, const sp_point_1024* p, + const sp_point_1024* q, sp_digit* t) +{ + const sp_point_1024* ap[2]; + sp_point_1024* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*16; + sp_digit* t3 = t + 4*16; + sp_digit* t4 = t + 6*16; + sp_digit* t5 = t + 8*16; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Check double */ + (void)sp_1024_mont_sub_avx2_16(t1, p1024_mod, q->y, p1024_mod); + sp_1024_norm_16(t1); + if ((sp_1024_cmp_equal_16(p->x, q->x) & sp_1024_cmp_equal_16(p->z, q->z) & + (sp_1024_cmp_equal_16(p->y, q->y) | sp_1024_cmp_equal_16(p->y, t1))) != 0) { + sp_1024_proj_point_dbl_avx2_16(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_1024*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_1024)); + x = rp[p->infinity | q->infinity]->x; + y = rp[p->infinity | q->infinity]->y; + z = rp[p->infinity | q->infinity]->z; + + ap[0] = p; + ap[1] = q; + for (i=0; i<16; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<16; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<16; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U2 = X2*Z1^2 */ + sp_1024_mont_sqr_avx2_16(t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(t4, t2, z, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(t2, t2, q->x, p1024_mod, p1024_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_1024_mont_mul_avx2_16(t4, t4, q->y, p1024_mod, p1024_mp_mod); + /* H = U2 - X1 */ + sp_1024_mont_sub_avx2_16(t2, t2, x, p1024_mod); + /* R = S2 - Y1 */ + sp_1024_mont_sub_avx2_16(t4, t4, y, p1024_mod); + /* Z3 = H*Z1 */ + sp_1024_mont_mul_avx2_16(z, z, t2, p1024_mod, p1024_mp_mod); + /* X3 = R^2 - H^3 - 2*X1*H^2 */ + sp_1024_mont_sqr_avx2_16(t1, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_sqr_avx2_16(t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(t3, x, t5, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(t5, t5, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_avx2_16(x, t1, t5, p1024_mod); + sp_1024_mont_dbl_avx2_16(t1, t3, p1024_mod); + sp_1024_mont_sub_avx2_16(x, x, t1, p1024_mod); + /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */ + sp_1024_mont_sub_avx2_16(t3, t3, x, p1024_mod); + sp_1024_mont_mul_avx2_16(t3, t3, t4, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(t5, t5, y, p1024_mod, p1024_mp_mod); + sp_1024_mont_sub_avx2_16(y, t3, t5, p1024_mod); + } +} + +#if defined(FP_ECC) || !defined(WOLFSSL_SP_SMALL) +/* Convert the projective point to affine. + * Ordinates are in Montgomery form. + * + * a Point to convert. + * t Temporary data. + */ +static void sp_1024_proj_to_affine_avx2_16(sp_point_1024* a, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 16; + sp_digit* tmp = t + 4 * 16; + + sp_1024_mont_inv_avx2_16(t1, a->z, tmp); + + sp_1024_mont_sqr_avx2_16(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(t1, t2, t1, p1024_mod, p1024_mp_mod); + + sp_1024_mont_mul_avx2_16(a->x, a->x, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(a->y, a->y, t1, p1024_mod, p1024_mp_mod); + XMEMCPY(a->z, p1024_norm_mod, sizeof(p1024_norm_mod)); +} + +/* Generate the pre-computed table of points for the base point. + * + * width = 8 + * 256 entries + * 128 bits between + * + * a The base point. + * table Place to store generated point data. + * tmp Temporary data. + * heap Heap to use for allocation. + */ +static int sp_1024_gen_stripe_table_avx2_16(const sp_point_1024* a, + sp_table_entry_1024* table, sp_digit* tmp, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 td; + sp_point_1024 s1d; + sp_point_1024 s2d; +#endif + sp_point_1024* t; + sp_point_1024* s1 = NULL; + sp_point_1024* s2 = NULL; + int i; + int j; + int err; + + (void)heap; + + err = sp_1024_point_new_16(heap, td, t); + if (err == MP_OKAY) { + err = sp_1024_point_new_16(heap, s1d, s1); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_16(heap, s2d, s2); + } + + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_avx2_16(t->x, a->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_avx2_16(t->y, a->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_avx2_16(t->z, a->z, p1024_mod); + } + if (err == MP_OKAY) { + t->infinity = 0; + sp_1024_proj_to_affine_avx2_16(t, tmp); + + XMEMCPY(s1->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + s1->infinity = 0; + XMEMCPY(s2->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + s2->infinity = 0; + + /* table[0] = {0, 0, infinity} */ + XMEMSET(&table[0], 0, sizeof(sp_table_entry_1024)); + /* table[1] = Affine version of 'a' in Montgomery form */ + XMEMCPY(table[1].x, t->x, sizeof(table->x)); + XMEMCPY(table[1].y, t->y, sizeof(table->y)); + + for (i=1; i<8; i++) { + sp_1024_proj_point_dbl_n_avx2_16(t, 128, tmp); + sp_1024_proj_to_affine_avx2_16(t, tmp); + XMEMCPY(table[1<x, sizeof(table->x)); + XMEMCPY(table[1<y, sizeof(table->y)); + } + + for (i=1; i<8; i++) { + XMEMCPY(s1->x, table[1<x)); + XMEMCPY(s1->y, table[1<y)); + for (j=(1<x, table[j-(1<x)); + XMEMCPY(s2->y, table[j-(1<y)); + sp_1024_proj_point_add_qz1_avx2_16(t, s1, s2, tmp); + sp_1024_proj_to_affine_avx2_16(t, tmp); + XMEMCPY(table[j].x, t->x, sizeof(table->x)); + XMEMCPY(table[j].y, t->y, sizeof(table->y)); + } + } + } + + sp_1024_point_free_16(s2, 0, heap); + sp_1024_point_free_16(s1, 0, heap); + sp_1024_point_free_16( t, 0, heap); + + return err; +} + +#endif /* FP_ECC | !WOLFSSL_SP_SMALL */ +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^128, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * table Pre-computed table. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_stripe_avx2_16(sp_point_1024* r, const sp_point_1024* g, + const sp_table_entry_1024* table, const sp_digit* k, int map, + int ct, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 rtd; + sp_point_1024 pd; + sp_digit td[2 * 16 * 5]; +#endif + sp_point_1024* rt; + sp_point_1024* p = NULL; + sp_digit* t; + int i; + int j; + int y; + int x; + int err; + + (void)g; + /* Constant time used for cache attack resistance implementation. */ + (void)ct; + (void)heap; + + + err = sp_1024_point_new_16(heap, rtd, rt); + if (err == MP_OKAY) { + err = sp_1024_point_new_16(heap, pd, p); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 16 * 5, heap, + DYNAMIC_TYPE_ECC); + if (t == NULL) { + err = MEMORY_E; + } +#else + t = td; +#endif + + if (err == MP_OKAY) { + XMEMCPY(p->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + XMEMCPY(rt->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + + y = 0; + x = 127; + for (j=0; j<8; j++) { + y |= (int)(((k[x / 64] >> (x % 64)) & 1) << j); + x += 128; + } + XMEMCPY(rt->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(rt->y, table[y].y, sizeof(table[y].y)); + rt->infinity = !y; + for (i=126; i>=0; i--) { + y = 0; + x = i; + for (j=0; j<8; j++) { + y |= (int)(((k[x / 64] >> (x % 64)) & 1) << j); + x += 128; + } + + sp_1024_proj_point_dbl_avx2_16(rt, rt, t); + XMEMCPY(p->x, table[y].x, sizeof(table[y].x)); + XMEMCPY(p->y, table[y].y, sizeof(table[y].y)); + p->infinity = !y; + sp_1024_proj_point_add_qz1_avx2_16(rt, rt, p, t); + } + + if (map != 0) { + sp_1024_map_avx2_16(r, rt, t); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_1024)); + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (t != NULL) { + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_16(p, 0, heap); + sp_1024_point_free_16(rt, 0, heap); + + return err; +} + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * r Resulting point. + * g Point to multiply. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_avx2_16(sp_point_1024* r, const sp_point_1024* g, const sp_digit* k, + int map, int ct, void* heap) +{ +#ifndef FP_ECC + return sp_1024_ecc_mulmod_win_add_sub_avx2_16(r, g, k, map, ct, heap); +#else + sp_digit tmp[2 * 16 * 5]; + sp_cache_1024_t* cache; + int err = MP_OKAY; + +#ifndef HAVE_THREAD_LS + if (initCacheMutex_1024 == 0) { + wc_InitMutex(&sp_cache_1024_lock); + initCacheMutex_1024 = 1; + } + if (wc_LockMutex(&sp_cache_1024_lock) != 0) + err = BAD_MUTEX_E; +#endif /* HAVE_THREAD_LS */ + + if (err == MP_OKAY) { + sp_ecc_get_cache_1024(g, &cache); + if (cache->cnt == 2) + sp_1024_gen_stripe_table_avx2_16(g, cache->table, tmp, heap); + +#ifndef HAVE_THREAD_LS + wc_UnLockMutex(&sp_cache_1024_lock); +#endif /* HAVE_THREAD_LS */ + + if (cache->cnt < 2) { + err = sp_1024_ecc_mulmod_win_add_sub_avx2_16(r, g, k, map, ct, heap); + } + else { + err = sp_1024_ecc_mulmod_stripe_avx2_16(r, g, cache->table, k, + map, ct, heap); + } + } + + return err; +#endif +} + +#endif /* HAVE_INTEL_AVX2 */ +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * p Point to multiply. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_1024(const mp_int* km, const ecc_point* gm, ecc_point* r, + int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_digit kd[16]; +#endif + sp_point_1024* point; + sp_digit* k = NULL; + int err = MP_OKAY; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + + err = sp_1024_point_new_16(heap, p, point); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 16, km); + sp_1024_point_from_ecc_point_16(point, gm); + +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + err = sp_1024_ecc_mulmod_avx2_16(point, point, k, map, 1, heap); + else +#endif + err = sp_1024_ecc_mulmod_16(point, point, k, map, 1, heap); + } + if (err == MP_OKAY) { + err = sp_1024_point_to_ecc_point_16(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_16(point, 0, heap); + + return err; +} + +/* Striping precomputation table. + * 8 points combined into a table of 256 points. + * Distance of 128 between points. + */ +static const sp_table_entry_1024 p1024_table[256] = { + /* 0 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 */ + { { 0xbf9c7ec6e0162bc2L,0xddecc6e310a89289L,0x5d599df09e499d81L, + 0x9a96ea286d358218L,0x01aec7d370c5f8dbL,0xe72e49958cf5d066L, + 0xc2e7297d3e91d7f8L,0x8621db92da9f2f5aL,0x4b26c8675a5679edL, + 0x233385df2c56aac1L,0xb88e74d4c6a13f99L,0x1214b173ffa8ec11L, + 0xa0386a271f3f9fefL,0xbd9b1b4ec0e7b44eL,0xafe528dceecd3496L, + 0x8dfff96a1c49f80bL }, + { 0xb4a4753ac03c0c83L,0x68e69d18abcdcd75L,0xe3839b88f775b649L, + 0x803f949abf58f352L,0x5f702679bd0bc15cL,0x85bf5d168ff298c2L, + 0x3f6ebd98c6c7976eL,0x20618af445e3e1b4L,0x67d5598e54e64093L, + 0xb047283b504fed9eL,0x450cabfd70d87517L,0x47d628bf3f5addbeL, + 0x0037ef3078cb4ccaL,0x4e148d3c6b1c4908L,0xe256d3294fcfd837L, + 0x2aa1207bde3c01f3L } }, + /* 2 */ + { { 0xa95b6dae01900955L,0xa5dc9cc1ceb4656dL,0x50c78907e72fe95bL, + 0xa1ae5447a040c334L,0x911913707952ea6eL,0x54ff73436d097305L, + 0xa4db0074bda4d10fL,0xfd5306f191644070L,0x14b9fe738b24522cL, + 0x1468dad67849f762L,0x87b29a18b0dcd2e4L,0xadd7f1a15e1ad492L, + 0x9ac63a81dbba2a1aL,0x01379c5b81223379L,0xf402b2f0b0e53bc8L, + 0x8c3eb27f0bf13b61L }, + { 0x9a4ad3e1e513696fL,0x0350ba5c18c81ffaL,0x1e2fc1363c033d13L, + 0x53da6e7117a531bcL,0x42ec64901aed610dL,0xd33e8df7e99ff567L, + 0xe4aad73e3deed12aL,0xd983b465180f4debL,0x99365269502f30b4L, + 0x7e2799aba8918d7fL,0x0ffe84b6700fc79aL,0x7b4400d640bfd8c2L, + 0xc3a21d215d2641bdL,0x79839442c32621cbL,0xace6500bb1401e83L, + 0x7bf4163e251c4310L } }, + /* 3 */ + { { 0x1c174f88e3fd589eL,0xdb501790df974a03L,0xd09623e33e70549fL, + 0x8d091eff15924f34L,0xeef79cadf9b65ac5L,0xd2cc42623f69c2cfL, + 0x817d903252cd82bcL,0xacf4f4d9a5f1ddddL,0xd06126355011b6bdL, + 0x9f74490d2ed140c9L,0x64092e8c4db686d2L,0x225eef16776b0fccL, + 0x0e8c01e9df16aeb6L,0x6283674184bbd82aL,0x757574e28956e337L, + 0x9871edc6705a7f07L }, + { 0xbd0b76d5776535f7L,0x5214d6022635b3b8L,0xc0c25ad99d216f64L, + 0xfd4df3a75515bf75L,0x24a625bc5e9f1675L,0x3c35efb7406873e7L, + 0xef5c9a33bb2e5c4aL,0xa971b35e806b198aL,0x9f5c0ca5a3c690edL, + 0xa8d5dd898e1e2341L,0x4cecbcce955ad9e4L,0x2ecf4407248d3416L, + 0x1abb381145c0af6eL,0x3f4bee821c780fffL,0xd14df768c272ed57L, + 0x397ed10a371637adL } }, + /* 4 */ + { { 0xcf3e0bb2755c2a27L,0xd38e42f959585c44L,0x46b13e0f19285e60L, + 0xc3ecd0c076273d0fL,0x7800f085193c569aL,0xf04e74ab4351818aL, + 0x9258aa388496363bL,0x8456617cb8c894feL,0x8bc62aaa2af969a0L, + 0x66c2280b5a4668d9L,0xbc9df58ea992f4faL,0x5db0b7d93f401e99L, + 0xe0614fe1c4c38c0eL,0xd531151c2ccdf6b3L,0x1c7575ece143b618L, + 0x40247985df9398a4L }, + { 0xfba251788f055746L,0xc5ba00400ab1e6e0L,0xe1b194fbac292697L, + 0x771521195b4f4740L,0x250091d09bb7ba54L,0x7a674861b9a139a4L, + 0xba8413b3f353aa7eL,0xafe771922443ceeeL,0x14468d363847bbd0L, + 0x61f79ff63da4942dL,0x1563a1c1d425b456L,0x3c270fcd75ff4630L, + 0x42072090eb2802c9L,0x68f0cdcbc85c7004L,0xca4372fbfa032e74L, + 0x1a6fd1e6c8b79d80L } }, + /* 5 */ + { { 0x967a901a8d5116a3L,0x0b844394b2f5f47fL,0xe39ad45260ebaf3bL, + 0x1e1be61760ccfc0cL,0xac07e3d2cc3f53f2L,0xdd838e0e1ed11bb6L, + 0x454753071c15b0c2L,0x70dd4748920fe5b8L,0x1a20be2de471896dL, + 0x3c3fad8a59276c7cL,0x026a1cc3c886ee07L,0x9fdb6f376e831ac4L, + 0x26a35d1aac501d65L,0x0ae9890540da8574L,0x65dde0a4abd734e5L, + 0x29b7d4dc15614750L }, + { 0x44b3c2cbcbf4e20bL,0x1c3f548f58cc44c5L,0x39809b545b0cac1fL, + 0x0c0f02b500f80621L,0xe612b890066905e0L,0x8f158ed78350188cL, + 0xc01dc4583f5576b2L,0x29803272a45492e0L,0x77a5623a0ff92443L, + 0xd12a2b0029d0dc41L,0xb41254592780e87aL,0x1ebcf9030d53f272L, + 0xbae6ea4024301e8dL,0x1e5f3f2fa37d0798L,0x9342c31022b4126cL, + 0x5d0928025382497eL } }, + /* 6 */ + { { 0x583a2b7eff2f780dL,0x34d26820d7d76b1dL,0xe3c3284786f74aecL, + 0x0fd4221210823febL,0x227e417efb5e7bf4L,0x510d49b6a568f8cdL, + 0x53bce7d61781bbecL,0x9cfe3f222f3718b7L,0x7f44e89fd9de6c1fL, + 0xf1cc553f3fac9b55L,0x9d2d0846e6f300bcL,0x976c82a29f0ae6b1L, + 0xe63dbf5e24b8bbe0L,0x4cac7f45973a5aa7L,0xc6eb623784dd33c7L, + 0x0a26e434142fee5dL }, + { 0x8081339facaa9a08L,0x40f311055246ece1L,0x892c817061393747L, + 0x8d8d4103242f02e1L,0x482bfd203b5de98aL,0x89ef946b5abbe952L, + 0xb8d218b937698249L,0xd5268e8966617c7aL,0x962e75518b7d2b91L, + 0x2c5c7973fe8d67c3L,0x42e3150a2b017c51L,0x6f4e5ebcc1a29469L, + 0xa39910ce531c7083L,0xaf4f6eb4b77b9e50L,0x68cbb175da120ad0L, + 0x19497c61b92636ecL } }, + /* 7 */ + { { 0x6920b0c6417659a8L,0xc77ab9c792cb28ffL,0x55b67180b687797fL, + 0x4caf58c1e7759363L,0x5155bdb65561b186L,0x2e64e355780f4946L, + 0xeb0ac9b7229a8b20L,0x88594d782571bd60L,0x5dcc0939e3fa78f9L, + 0x7b8b48302ac2d379L,0x505fbf60b90f1444L,0xac610e813ce4b3c1L, + 0x39a4f27ad59b5c18L,0x5fa339737cea0222L,0xe578730b8dff1c7bL, + 0x96b91b8b517bf7a6L }, + { 0xc1a991f49aac087cL,0xce62f74e6cfdb28dL,0x08d6ff9a5f7600d6L, + 0xd781cd04f917f9c9L,0x7796f5f63de52dbfL,0xe7db64e02ed72180L, + 0x0f0876f66fa4137dL,0x3271ee643ca1f716L,0xcb9b20587c4ab8a3L, + 0xcba1710739481047L,0xdf9a190d598c5c37L,0x0cb6e72a6f20e125L, + 0xa3142204f4f2902dL,0x42d28cb97ce2dcfbL,0xdf261b8aa3d3c351L, + 0x73f3d315cffc249dL } }, + /* 8 */ + { { 0x5d86855be6fd3673L,0x309b70af9d214b7bL,0x8d332f90dcc46cd3L, + 0xe553c015595510deL,0x5746a09638c1251cL,0xcd7cea5b85cc1bc9L, + 0x4ffa1468002eba8fL,0x10a3cb7022fcd77cL,0xb6999dfbc4ea05e3L, + 0x3375a0d04efa756eL,0x4d90279edced5fd8L,0x48192403251fd56eL, + 0xe87633a482a4c5f1L,0x3170d1301b34105bL,0x93998b0f7247e578L, + 0x88934f64436ba1faL }, + { 0xf09f43b04713eabcL,0x4ca7dd91accdc517L,0x27daa63bef13ca7cL, + 0x8b2e5a7a2588184bL,0x0a8cb612d95dc269L,0x346975a2e1f2f14cL, + 0x1f29b8ede172935cL,0xc3cbfd6ed40bc1e3L,0xd3f46b3f132623daL, + 0xc115be6dfb0b7681L,0x5e31c34556da4344L,0xa7c63f18a8e43d98L, + 0x55cb20834bddb4eaL,0xb16a0c384a54f58cL,0x74eacca246fd69d9L, + 0x0d1898bb153548e1L } }, + /* 9 */ + { { 0x4ea73461e35ef043L,0x107b67d93496b564L,0xd62c173bd0f83a3cL, + 0xfad4b03851d29c35L,0x3f42882a71b1c1a4L,0x5d2bcf6654b43b9eL, + 0xc77b15aa2abdf543L,0x5cb38a80dabe3dc1L,0x15fda0aea481673bL, + 0x86996b4de7b90ebeL,0x84f87e252bc8f3d8L,0xaded03d637c4e424L, + 0xe5ede666d7a7afd8L,0x80dd95a2a1ccb93aL,0xa55cfd2546fba391L, + 0x2bdab1dc46f82e60L }, + { 0x7a4de22bfa6fed61L,0xca458aa5cc8dd94eL,0x3e372df1071222f5L, + 0x06a4b44fe5aff377L,0xbc2d0ba74a738e6dL,0x1a470e1d5f31f136L, + 0x77ff933ae102a911L,0x8b380a50310c7885L,0x9f3c0228783fc5acL, + 0xec66892544725d06L,0x878f0e165ac84221L,0x9a3af1afcfda6e8aL, + 0x0183ed3778cd2abaL,0x32cdbd60826d0eaeL,0xb3234661cbee6415L, + 0x353eb892b9c10120L } }, + /* 10 */ + { { 0xc8fdcad610b5521eL,0x1a11b44052e702f0L,0x6302680d8ffda49cL, + 0xcdb9654acbf36badL,0x7b58ce114c10a2d7L,0x1e5d1f7de630e7e0L, + 0x8cbe3d7d6760a813L,0xeb35866b6480d77fL,0x58728cf37f036219L, + 0xdd5865ed42a8a757L,0x283f1f1d906a2870L,0x79e23fa4a51f906bL, + 0xf2ac6e83543b20a8L,0x4f0b6379b81e7754L,0x57fbc0d4840016eeL, + 0x8da20771e621b67dL }, + { 0x3c855004ecce65ecL,0x76d10d1fb748185eL,0x64be7bca78797ad2L, + 0x43444db077e54aadL,0x17b6b0c9be0df0ffL,0x8fc4256c055086a4L, + 0xf952c43bfd74d5a3L,0x501e005a01c4edb8L,0xd5172dfc4a57e328L, + 0xdb40ce4e535d6ee3L,0xbaef1e5c0c650918L,0xe85145e7857561fcL, + 0xe468536a34a224c6L,0x69a8e2270ec0e0a2L,0xb3f52247242b03fcL, + 0x862f55e2c3bebd5fL } }, + /* 11 */ + { { 0x2d6a390f226049feL,0xcc92a578dcbbc9fbL,0xa52feca497634fb7L, + 0x2b340cb63dea5893L,0xa39f338a2a49e916L,0x26b2df3d949e41f3L, + 0xc71c7cdb065a7e40L,0x4a9b84a0468281a2L,0x63eeb503731eeecaL, + 0xe6d0913476cbb725L,0x0cf979a9b94a678cL,0xb44d8c3b808fd9f1L, + 0xe60da613e0afc5b9L,0x52dce7de3ea5be69L,0x3a5d6864dc1ee74fL, + 0x71ab28913bc80790L }, + { 0xcf618fc43b5b60adL,0x0afb5e304a0c3184L,0xd22381ccbc403302L, + 0x33cf8953db1c0c66L,0x9c994e4da6112a8dL,0xd7aae2c3d1967a86L, + 0xc28d54935b7acd29L,0x8075bd136c9a57fbL,0xc9c0373e9c8427f9L, + 0x2cbca18d193225f5L,0x73777d13442c018cL,0xebe5ed47fbb3a727L, + 0x70437d491962dc18L,0xf39c1e092dc08806L,0x03e9c6f715fff35cL, + 0x8d087bb65e360a65L } }, + /* 12 */ + { { 0xbe2123023fdc1844L,0x6eca27ef105eac56L,0x2183a606f168a348L, + 0x295f807de1d7a4cbL,0x7246a6327ef5d43eL,0xae143205c77025c7L, + 0x4bdfc7caf3484e3eL,0xec939895df52c075L,0x82e655f6d7a9cac0L, + 0x985dfe208baeddb0L,0x79c817e4527de731L,0x30ce0fbc313de1eaL, + 0x9df95b89cc4f6cbbL,0xf2aedf1ef5bb20cdL,0xfc1e0a891a8cfb01L, + 0x225ed34a63edb7ecL }, + { 0x3e13154dbabb1a85L,0xd3d8dae71e6a565aL,0xd3217d56ab4b100fL, + 0xd44d934eebc78e1aL,0x0215321b48e73d37L,0xbbc90bfa201e43cbL, + 0x3c23f1d027500905L,0x2a2e5000c86691a1L,0x08b2bad26065841cL, + 0x15d41caf30026b60L,0x1712c2f45276ce61L,0x01c4c3e715932ffbL, + 0x7894e13d6a74caf2L,0x02d6f5df0c0537a4L,0xa8fb7602c2b1c97eL, + 0x612b60e5d0887c7bL } }, + /* 13 */ + { { 0xefd495cfba245d6bL,0x5cf0cbb7a2ce3ff6L,0x24da2ac0dff5feeeL, + 0x90c914f8cf28c6a3L,0x72fdb50d4308a56bL,0x03dbf77913d72034L, + 0xcfa5ec91822ac9e9L,0x0dde73c83aea3e81L,0x545ba96266289139L, + 0xa52f648bca6acbd3L,0xff6f276e98a0683aL,0x2536d3aca378ed52L, + 0x353c2c54885ac1d9L,0xcaff52da00bc84a7L,0x3971f81c37684167L, + 0x0f7334e1d2d7986eL }, + { 0xafbb5c836596067eL,0x33e54e1938c19806L,0x8285d96739cb0dccL, + 0x2b53f43d424035f9L,0x38c531f8dfef9095L,0x90fbe8e4db0f571aL, + 0x9a0c1ed2a39ca787L,0x2fecc1d6606f2620L,0x9dc890b172b7cb4aL, + 0xc33ca6fbccbb7868L,0xd1b11082fe73ee49L,0x590b7d17fcb66c48L, + 0x9356b0a686e14573L,0x75d682c4053ead85L,0xb2ae55fac54d30fbL, + 0x67636a72f8aee949L } }, + /* 14 */ + { { 0x638063bcb91d6beaL,0xae263a2e923ecb96L,0x9d7b0992c627aca6L, + 0xc6ed001a77af9e7eL,0x9214accf24aafebbL,0xa3564b9678055a90L, + 0x00999b1ce027499dL,0xe413a4e1e46a06a5L,0xa05d13f62e51efe7L, + 0x35e87d349ba843beL,0x0a6338253183159eL,0x6023e8ba54601923L, + 0x9b107721b7fd1cf2L,0x46b5542bfdf2fd53L,0xb314f4f81c18af38L, + 0x086f987660ac8965L }, + { 0x767019548cbb9850L,0x6210b730a20d2c8cL,0x4084d0575335670cL, + 0x3ecdc5950324baeaL,0x607fc5f2c76ee9b4L,0xf393d00f440ffa64L, + 0xe01117962dc1463cL,0xf00b82519c7725e7L,0x35e607365bd1d186L, + 0xf3d8554c2cf72aacL,0xb4dd0fdeefa3497dL,0xd712268cf646ad11L, + 0x07c20afb9f7b8eadL,0x630969d4fc06dfe5L,0x76b7df1c7245549aL, + 0x681f9403e61ae810L } }, + /* 15 */ + { { 0x7cad5163c9a0623bL,0xdbf8295767fab8d4L,0x2ccab0ec81af7c7cL, + 0x469e38c8e966d5c2L,0x34430d52f0d4e41cL,0x426075a2a52b359cL, + 0x242dd3e333bd0127L,0xcda3f6359fed2341L,0x4df33730d7d52ffaL, + 0x5fff56f07640c3efL,0x4783c21c1bbde57cL,0xd8784a2aeb8bb336L, + 0x1ec7c533ead08405L,0x4b7f1423f9b62bd4L,0x5543145c7075d4afL, + 0x0c9de94aba60590aL }, + { 0x8ed7273595d5682bL,0x711c42832ec276edL,0xd1f4aed58b36a0d2L, + 0x62ab40c48498a88fL,0x58c8fc624480f451L,0x8bc8ca4bb79cffe2L, + 0x90ab583c701a359dL,0xaee31a733fd5d15dL,0x02a5597bc912333cL, + 0x1019cae4b6c3e3c2L,0xe513042c29938088L,0x0e00283df47c8199L, + 0x90d68e58f2a00e92L,0x69e2df41a775ae3bL,0xb8d2eca5871c30b2L, + 0x733dca0ebb1de396L } }, + /* 16 */ + { { 0xf5b495d04b59213aL,0xca6720398d70200eL,0x4bcb09a62b6771c1L, + 0x26adeed42b9eb0cbL,0xeb5447548cdba212L,0x0e1abfcdf08890d1L, + 0x52509963698e46b4L,0xe1bff0b082e9c138L,0xa189e4cd51099a71L, + 0x2360c9bcc9b91cc7L,0x9bd4d7dc137ec4beL,0xd0356521d1519f6eL, + 0xbf5f6d78cf832503L,0xe43010318deea2b4L,0xc3132494ef4c319cL, + 0x2ab3bd470f1fa7d7L }, + { 0x5753b680922c9fbbL,0x869e7dc80f16c6d1L,0x83445135bac16efcL, + 0x4326a3b4846d1d9bL,0xb517fee3b2d62c21L,0x6905afa20b292ad5L, + 0x2a57131a2cadac13L,0xcd904d8febdbca8dL,0xdfeda86f3f365fb2L, + 0x7097b208dc7eaa1cL,0x89a35a84a45e77c0L,0x417a062ccf5d118eL, + 0x3c0c04a81f6e99e8L,0xc44704b0ba7a087dL,0x6f8a27d13ea22ad2L, + 0x93a4b4164c27d229L } }, + /* 17 */ + { { 0xd4271bc11f1efb7aL,0xae4e68e633fccc0dL,0x9d9bc8f1b11f50a8L, + 0x5430398faf076089L,0x45e242fb443d0e03L,0x73ec2519f6e3d4c1L, + 0xab70f790ba9bad09L,0xde612ad5f9add10fL,0xb837e54e14e942b4L, + 0x175a56d3ddb8b68aL,0xe85b233c1ac2a408L,0xf8ff6c30f0c80f94L, + 0x4b7f3fb7898db4f9L,0xa2c6044f45a7dcddL,0xf3abb2f6fe3d3895L, + 0x342ce0d732ee7763L }, + { 0xeb261394cf491b1fL,0xdcaaeed71909e395L,0xdcc4055a9fe4dbeaL, + 0x17a6611d493d604dL,0xba445a3a1ce5ebefL,0xe82e2858e3989cb5L, + 0xb96f428283f58406L,0x99877b99a156cf55L,0xaf906a664e166a0eL, + 0xcea1d353b2976d13L,0xefc16f2736c61a01L,0xdb04c433b0f55d86L, + 0x3cb4b2698eb34c01L,0x38d07f782ae60280L,0x43ac3bcb43be3ec5L, + 0x455f4af3e156fd20L } }, + /* 18 */ + { { 0xc057f262754ec21cL,0x3eacd4c9e3a1ba38L,0x3a0210d1116c1fe9L, + 0xe4ea4e94eacc8ab6L,0x31c00c9aea6f32caL,0x5cb6239d86b975ceL, + 0x654d5d8ca14ea1e9L,0x230d31f45067fc8bL,0x48bb90cb6355fecbL, + 0x78f81ecedc172e8eL,0x288380a8cb006737L,0x19b02e01e162d012L, + 0x0e087a06c5af145cL,0xf04dc8b7b72dc354L,0xf70ef2148de3c066L, + 0x4f14824313009fb7L }, + { 0x5e004fce6e2055e2L,0x89e247ea86c32067L,0x4ebcbd955f9daaa2L, + 0xd15f212fceb7f63bL,0x5ecc5c1f863784a0L,0x53b3800b75760251L, + 0xeb9301c38a6a2954L,0x0f16ba18a13cdd19L,0x8313d251887c2d24L, + 0xf99235859a9413f6L,0x423405e6fe3fd7c5L,0x678aeb3416e0ee05L, + 0x1f3be7bb3fadaab0L,0x7901fa2c82884471L,0xc950db304d662ff6L, + 0x74d5d2d43c01170bL } }, + /* 19 */ + { { 0xa3002dc02b5bfe11L,0x0733410d52d321e7L,0x15920f659679ba89L, + 0x0e248c14685b236eL,0x8cfab594346f6040L,0x9f57afb740c717f0L, + 0x0dbab28c66044576L,0x0fa099689cdc3247L,0x41e02ae2c230ed05L, + 0x0d961554e45bef74L,0x9688a982ce4d7b6fL,0xfadefac75e62d22eL, + 0xaf1512a6bd2cba28L,0x78868e62be7c749fL,0x88048d81ae9f5a6bL, + 0x6b1a5442c5857a29L }, + { 0x9f5ab9ad43242066L,0x0afef1b52ccca2aeL,0xb1b43ec7988edc4eL, + 0x0d0c00f10341b0d5L,0x4d68b8f7b50aab37L,0x9a8e4e6ff3a64a99L, + 0x198338fb7f1a684eL,0x8bc0e748351a0f5cL,0x2cacf2cddac44515L, + 0xc14d39995e9ff76bL,0x54a01b3f16393055L,0x6ac3eea5888d8376L, + 0xb84d9a9a723277b1L,0x99132691e11dbbbfL,0x597717aeabb67178L, + 0x4c2135268bb14ac8L } }, + /* 20 */ + { { 0x2e6fe0a695532833L,0xabca228ed626d067L,0x22aef3d9649e73bdL, + 0x2083a87af03c4c0cL,0xe954e75d35169b45L,0x577509ee74506a89L, + 0x49cb276e2aeacf90L,0x08275d77fa409f91L,0x61eb6f3df0bbd6b9L, + 0x948202cbe4132704L,0x35f3fc21b1c498b1L,0x76c68ba8361fee59L, + 0xa18cbbd950e051f3L,0x2384a879318e7042L,0x292abead80dd1e8bL, + 0x65713c295c37c334L }, + { 0xdccca8e9ceb77b9aL,0x2f97e72723b69469L,0xc76abee6a01d6b28L, + 0x3925203d5abecdfeL,0x8944808229290d70L,0xf9931424b0314438L, + 0x04209df17cd447c3L,0x7c6f2059c855c827L,0xd97d786256c0e069L, + 0x5a9db6fe412d94c4L,0x19a64591994c41ddL,0x12348aa1c89e21a3L, + 0xd6904b50c6a03f0eL,0x55c15156a616feacL,0x4e36d1b57cc7693bL, + 0x6b0e996c3bae3c38L } }, + /* 21 */ + { { 0x32789fabcceced00L,0x3237e71ae5b7aa66L,0x87b2e2692ddebcdfL, + 0xb7245120b61dad8fL,0xe11e5e48d35f803cL,0xfb4df5d798e50f0dL, + 0x60ee68b4bcd2ab92L,0x98ab2f5c1ce3363dL,0x15ba39da7cd42647L, + 0x1a6572eb83f4fb3fL,0x0f77de88e56f08dbL,0x1743761e172562c2L, + 0xbe349ff88a58f0f4L,0xe04da71b84d1d6e2L,0x368f03429e9ff3b4L, + 0x4022a205678223f8L }, + { 0x527bbd0583847375L,0x3ae56b623f451af0L,0x6198f24d4b2c7f18L, + 0xee323f5b4525b98dL,0xa9d8d39a0e0884b5L,0xd005d7f6fb12c776L, + 0xd71c483e708bc154L,0x8ca6fd28742541bcL,0x0af3dccdf8397ddbL, + 0xb80d31253eccf243L,0xc743a10858d81b8dL,0x3f48eb2171391f68L, + 0x493aff8833bb657fL,0x1d15ed6607e47e31L,0x10159b11e08279f6L, + 0x312179cb24a6a956L } }, + /* 22 */ + { { 0xa94cc3ca07615ac2L,0x85865e64121ad581L,0xae47616fa7986b79L, + 0x395a40eb9d5e0f1dL,0xa91432643d9457eaL,0x8de6d6a3fa2865d9L, + 0x0771db961014ae8cL,0x77a7cce6976a87cbL,0xa7de42e1143a0f60L, + 0xe203cc09d993d934L,0x9201869398ec4c3dL,0xd77546d83a25df4bL, + 0x0ad9eb4762b02d6bL,0xfaaaf208d05a7189L,0x5238181f431221bbL, + 0x417d6c78733511eaL }, + { 0x3cbd81b70e91e9a8L,0x73340418c370d6b3L,0x825db10a8eaa2373L, + 0x8f2b09e46c7d6756L,0xe288ee9b94c33dedL,0xcd8426bb1695e3fbL, + 0xa6176c86dce9e888L,0x3f4c89226165e362L,0x514e411f6063fb09L, + 0x6907ac20c8f9e04cL,0xcef7469cdfd2ad61L,0xba30bae48452199aL, + 0x3068129312ac3462L,0x011be873c92d482dL,0xff4cbf89e8330995L, + 0x02189d52d1470a0aL } }, + /* 23 */ + { { 0x73e419dd92599c69L,0x5b94221b7fec32caL,0xb2bf9bd209bbfbfdL, + 0x61ea97a463ed895bL,0x6609146b3f486f79L,0xbd1c7a05fd141a39L, + 0xc79ec8cf83d64135L,0x7f8fd42f9883507bL,0xafcb53b717b3d027L, + 0x86658dcd67ca5a21L,0xa6a6c0accd149786L,0x16f3d70e34b95067L, + 0x371208e3df44958cL,0xd2dd64e6ec280212L,0x33b2c4ab30782c71L, + 0x7bbf8abd521176faL }, + { 0xbe9e4aafa78b981aL,0x788b4e36304ec828L,0x0c45cf393959dea3L, + 0x70a9bdd3240b39c7L,0x499cd7dd28383b7dL,0x30690b2e307a1026L, + 0x2262d598ee92f1b3L,0xc62d77deb4725a48L,0xa16f25bc7bc3aa0eL, + 0x62dd8b65d15ef7faL,0xd979221d0b96d68fL,0xb92885c3a00f1906L, + 0xfa476b9beb74c740L,0x217ddbb5c7576222L,0xc2782c305788504fL, + 0x860d096cf812716bL } }, + /* 24 */ + { { 0xfebc337d4d79bbf9L,0x5d53eab869f74f80L,0xff36a09533104d53L, + 0x2ab820da196f8b97L,0x961d3d1f75ce6909L,0xb197ec0404683754L, + 0xa68ce1bf93a6cb9bL,0x503456ffc5f021a3L,0xb50a2db18940ffdbL, + 0x77c50f8fef004209L,0xd635d17704965875L,0x725766d98bb8770aL, + 0x8e19b028a078e53eL,0x364d4ccaf9fc8378L,0x1a3df411f0dd39a0L, + 0x7e80e44203adf920L }, + { 0x4b5f8a57539a1ddfL,0xd248e7aeee486562L,0x1c7b491d816021e1L, + 0x2e7b871bfd36d2c4L,0xda38b5040aec00d9L,0xf28276126193f1b3L, + 0x69c3fe86fb1f78d6L,0x56c8b786e827ac33L,0x1687f6c73487c8f7L, + 0xab8f221719dee5bcL,0x04e8473fff399418L,0xf384c014a9027c80L, + 0x9967be9aaa1d2e28L,0x869686d3e065eef1L,0x737c6b08c7bd837cL, + 0x5dcab5d19e8bd863L } }, + /* 25 */ + { { 0x0784283a9a7d772bL,0x6b49e525e540959bL,0x546bb00886414ab5L, + 0xd44481629d74b2a9L,0x267890ad203b0b1bL,0x1e7a82bcc8d3f86bL, + 0x1352bfb5d85a83c7L,0xf29f16e3fad07ccfL,0xc02a63b841e0c43fL, + 0x904f22c56b379fefL,0x19d8a653b1244f26L,0x6635b6df3a28bdeaL, + 0x18b68851f6d455ceL,0x74ac28189cff3735L,0xad40f9df8b2cbdabL, + 0x08cc2d9eadc9d498L }, + { 0x2e6a6866c170c84bL,0xbb989e8b5a49a484L,0x7b0e00e0d04c8992L, + 0x55ad347861b3a423L,0x3c952450b0d01899L,0xe3922155e3100cb3L, + 0x19265b6ef03276d0L,0x0fe8595a76d42b53L,0x0a96dee0fc6353b6L, + 0x761e0dc8246f893eL,0x4ec902bef0a74cbaL,0x610086843fdfad9bL, + 0x5d6a60e44fdb6975L,0x3f53aac87ef7590aL,0xd29e6be012870a37L, + 0x991fadc155aa55b0L } }, + /* 26 */ + { { 0x82bc4b0fb4844ffeL,0x7392271460f8b871L,0x8ac000e24ce3f1f3L, + 0xf0d548b4163519ecL,0x7aaf842b88288b5fL,0x9e8b0c4c2bdc9a70L, + 0xa06d51524ba5fd67L,0xd0b1afa0f93cdec3L,0x280955badf89f8f0L, + 0x86cbe92deea32c92L,0x0cae3f993fe05be4L,0xf2607095fa6919aaL, + 0x0f54741e6e0f1b8bL,0x2aed1f7430ecf988L,0x9296f76b734991d7L, + 0x66cf8d28259f0fe9L }, + { 0x9b01905b226f5868L,0xc102e88c16909e9eL,0x2bd089164a37eb54L, + 0xf72253e8c9816323L,0x37f84e9d86bac53cL,0x2e352454afeaaaf7L, + 0x67c86f772ca0046eL,0x86bce50e6663372eL,0xf6a3a960b6950a04L, + 0x61f994d7fc1aba93L,0x1957c12bc1326e6eL,0x9b658fe42e56b005L, + 0x9cd297fc8592740cL,0x7654ce9b177f26a5L,0xaaa699dba79d2ebbL, + 0x5fca0c5a0ecb6448L } }, + /* 27 */ + { { 0xe26e25f3569a6663L,0x09597ee7e6aa4ca7L,0x25a4cda68d18b80cL, + 0x450602b522926730L,0x9af5f65007387209L,0xfeeedb3426733a53L, + 0x0f5ce76886572951L,0x872a360b8398ae9aL,0x60347a802b30f6c3L, + 0xd2113b231a162158L,0x6fd9cf92ee6c6decL,0x85f0a5a85cbcf9e6L, + 0xd7a5a6e42ba3fe84L,0xaafe672051ecd727L,0xe09c6bb2a2081a10L, + 0x657acbf0b973b0b4L }, + { 0x3130466fc274c8d4L,0x4276517630a994d1L,0x217258ca7079435fL, + 0x44850406eb897a06L,0xf38dfeee561ee130L,0x11f4facfaa1778bbL, + 0x765c6617b9abb9e9L,0xb135499bd8f10932L,0xc0eb6337a73b9159L, + 0xf2c1ccf16f7e8b6aL,0x5b32c03a187def53L,0x89ad1d49830b9c62L, + 0x1735eae32f10e538L,0xb1cbd9c29d5f55bcL,0x42428c47e539db0dL, + 0x3d2da412c852b3bbL } }, + /* 28 */ + { { 0x97702b6e871f2865L,0x56cb639f142920d6L,0x328522a045b58611L, + 0xf3943ad1f3b13812L,0xe6c2200a712206e8L,0xc2890e5aa34d59eaL, + 0xab52fd40f6b7f759L,0xf522c8de180bf567L,0x181e97b2accee396L, + 0xe0375819c4ea5cbbL,0x0d9985e8ab51d3efL,0xe26c96cabcb50fd8L, + 0xfb9d6b1397e1c80dL,0x582b1814f796357dL,0x89a7822107f4c7fbL, + 0x02aeef2dc0357e61L }, + { 0x2ba7926f2c7ec9beL,0x292f307e7258b201L,0x74e62a10c6fa6b4aL, + 0x80c08549e2bcc5abL,0xb4160db87bb8c073L,0xd5ef0529329f194dL, + 0x0eb8da146dda4a9cL,0x0b5d43d215ea23d1L,0x6cebef02fc34bfaeL, + 0xacd364d0848757a7L,0xc14013682d34cca3L,0x09ca67421d2d95e2L, + 0xc3fd1d6e786eaa28L,0x9eb1136da2965fecL,0x48871baac0779203L, + 0x6b446c014b15aeb0L } }, + /* 29 */ + { { 0xc819eb2e25e8fe80L,0x2b5f790698238a17L,0xd6f1e99681e41849L, + 0x58ad8ad698ea6d45L,0x5bae5ad4bfd02e40L,0x016dc327a812416dL, + 0x8b31a985a3347ca1L,0x0b4da61082a65391L,0x1cb91b2db48c35fbL, + 0x9e96817cd2aaf8c4L,0x1a630483cdfdcdc0L,0x7055936112b69254L, + 0x5fdcd712f8a2a097L,0x59ab623a35cc5281L,0x30c8ebe0932b6095L, + 0x8613424bb08e052fL }, + { 0x28902063b2231d8aL,0xb0f62329d9a61667L,0xaafa0fe7071a9f27L, + 0x6bcd8960603f047eL,0x118cca76fd92a1c3L,0x3414e62b71d483b6L, + 0xa123ccddba705262L,0x1a576437fd9b5c5aL,0xa5301bc24c8d0fa3L, + 0x96f0ad44102427cdL,0x0e6fb5e0d3aa6c02L,0xcd8c4880072a3996L, + 0x4dafca12840d3fadL,0x29f4ca3dde91d541L,0x0037c5988441734dL, + 0x86333a999ccfe57cL } }, + /* 30 */ + { { 0xd213a751ecf53b40L,0xcff2c6f22f78a542L,0x0f59f0e2f13ae56dL, + 0x91f8ccbf0e61748eL,0x0aadecb9d72c4145L,0x6b2ed8524c9cdcb7L, + 0x8e00b72c1eaffc70L,0x89b24285aa728102L,0xaa7ea7e0b679cafaL, + 0x5d2b8c264f0a6f6fL,0x7ed7b1730e804397L,0x5a93eb45c8573049L, + 0xc92bf5d40986e93eL,0x526b5a9c6a20c0afL,0x0adf47c9b99dc3afL, + 0x12b25fe2ba202cc9L }, + { 0x09b8d78a33eea395L,0xc7a93618f633fc5cL,0x7e821629270eceefL, + 0x524779b8c628ed0cL,0x91db5ca1a1d68939L,0x8626e18e586edc90L, + 0xfe023e8bfeb3f3bfL,0x6279fde10250171cL,0xe52ec7dc55e172deL, + 0x445e8695c6d4ca45L,0x42de3878bdbc10f1L,0x2b114de86fc3835eL, + 0x9faba4567e10b652L,0x4111d82a390e78feL,0x576b61c2aedf0acaL, + 0x216279a974accb74L } }, + /* 31 */ + { { 0xc14cdabf4047f747L,0x03ca233dc1315a1eL,0x59e7cbd340e5d0a7L, + 0x1fd0c4e9bb413869L,0x189d08b10f01fbd8L,0x50449c42a76b823dL, + 0x81c224a1398b00a1L,0x08084e4f8e8179e4L,0xfd8af994698e41e9L, + 0x1e30e37c5610bf2eL,0x4e6a043fa7d2790fL,0x9d96e60cb3195388L, + 0xe75f986d03799dfdL,0x3b4a8f11f8ff902fL,0xfa9453787588416eL, + 0x20683e3f9827535eL }, + { 0xcb582e26d0378878L,0x9e214c23a7945787L,0x13d000bf8f6688b3L, + 0x7548d4f540515270L,0x7113c15d40111f5dL,0x3bf5a526a8bff902L, + 0xbda6b0109b4945ccL,0x83dcc74ebc2f3a05L,0x2aef628443efdfa1L, + 0xd2e60ee9565c5bf4L,0x4f0fa10d592f243aL,0x6ae58b321bc3bf51L, + 0x813b086860576a74L,0x0bc023f84d73081aL,0x9fd03aa032dcee59L, + 0x5e416bf527d6c795L } }, + /* 32 */ + { { 0x24313760026cc23cL,0xf819aaeeb5b29058L,0xa92272f8c5d2ee17L, + 0x8048e7cbee5cc402L,0xdbc7d6ee77def07dL,0x61d69244f6af821eL, + 0x5f7966ed996cbb89L,0xf81b17ea96a155a4L,0xb2d9ef7003f3ed56L, + 0x5e6e5906e882a5b2L,0x86fa1072ae947180L,0x34d9fc51658c76f4L, + 0x9f603dc0cb035aa0L,0xb7b39feb75be6481L,0xca87554acf04a9efL, + 0x4ff682ec87b4fde3L }, + { 0x3125627fd0a10ad5L,0x7fd45c72968e6f45L,0x2981bd6b806a1163L, + 0xb92de1cdde5033e3L,0x3b44b45ebf4f8988L,0xca1b9896dae7e1dcL, + 0x52166e5a0778d878L,0x82d472bea5116847L,0xfbdd382af2895445L, + 0x22ed16025d6ec4c9L,0x3614eb1cb6552b02L,0x63c5df73a1e6210fL, + 0xe9160285021a74a7L,0xa44ca400c65cbd4dL,0x48cb187e0f15e299L, + 0x51eb818e3402507cL } }, + /* 33 */ + { { 0x1fc1d178b92100abL,0xdf2e3d609605b839L,0x12a7c255b71e59d0L, + 0x3f8b667514fcbe04L,0x0e8a393559fd06afL,0x5632650212020d07L, + 0x6696fcd1528e7be5L,0x6588514b0c7b7654L,0x0cd80f8c5912a5b5L, + 0x8bafef04f324cb7fL,0x6b53eecfc6da3d75L,0xedef48d831d1df2fL, + 0xf336b96573812b6dL,0xc82eae4aee626031L,0x300abd32d244f09bL, + 0x8b0af95531d9647fL }, + { 0xb770180a2e603544L,0x2b573ac3221acd9eL,0x3a17f66562407032L, + 0xad3e74adb89abc3dL,0x8a3d2e3ad793225aL,0x457bba04ef02564bL, + 0x8875652ffc2dd2b5L,0xd2905d15e67143e8L,0x6d884b4202e48d70L, + 0x06f99219c7636a57L,0xa8dc342135e378dfL,0x95c1d73d10c64a02L, + 0xcd6a4ececc157a66L,0xbadcc1c88e24a354L,0x8024f1b29839329dL, + 0x5363e5494da48ad0L } }, + /* 34 */ + { { 0x1f5523b7e23fc641L,0xfe54e72f86667063L,0x294a15f58e009d2fL, + 0xf203997f8c57f5e1L,0xa229724cb16d64dcL,0x697be4fd4baa2ffbL, + 0x3f507e460a6e8ed6L,0x0afe3a5d78508536L,0xeeef6cdd95408208L, + 0x701fd889f2c4237cL,0x496d883a5c385253L,0xe25c67ed72a212f1L, + 0x4b4167831ff78fcdL,0xe9967004c16f4146L,0xfa45c3a1c45b0697L, + 0x633340183fbd30c3L }, + { 0x39c9a0cca2fbbbceL,0x876f6e5caa0cb744L,0x9ce6010e3438ece3L, + 0x0aad148e13802d82L,0x9c3e5c609cd45a1bL,0x875cb8597bcfc1e0L, + 0xb19ff790d8584dd0L,0x2598b81ed81c2a2bL,0x118bdf2f02be07e3L, + 0x074fc8eeb9765ce9L,0x125e9d88b24f95aeL,0x3bb12cdc0c98f09dL, + 0x4a6aee07a0b74b27L,0x4723d2f9c08077ceL,0x959447d6bea8026fL, + 0x93a7075c16280b73L } }, + /* 35 */ + { { 0x26bbefe2715b27f9L,0xa935a5e22a280923L,0x5ddf23affd58a26aL, + 0x54c83e167c138694L,0x44799bc9892a2153L,0x4e6e47109b8d09f5L, + 0xc63af616d588ea68L,0x5e896706883ab1b6L,0x3c1393a03d209336L, + 0xd02f292192c23ddaL,0xab70cb7adcf6ea43L,0x12434ea8791559e1L, + 0x040680db6d70ff0bL,0x1a10fe522832ba45L,0xd69f9c08e5f0cb8fL, + 0x1a7422ac44b141fdL }, + { 0xc3a9dd2e9f40b675L,0x2a7c6603fcc71f39L,0x18939a611948e342L, + 0x8f3b6158ed0ab484L,0xa3aa7d97ee31ca6bL,0xbc1e865ef7a8db63L, + 0x315f8c092c7c62e4L,0xa260788f9f5c6d0fL,0xb18331294b6f3ec5L, + 0x73adbcd636b4d849L,0x66e14890bc699a9bL,0xbf3790d82a1175e7L, + 0x7f43605afc53ca4fL,0x577f6c4787ff6091L,0x827c7552600c82b6L, + 0x0944d6309d25599cL } }, + /* 36 */ + { { 0xcfdeb63ee6ab9620L,0xdff4fa6d786cd808L,0x145edd82456320b3L, + 0x2ae5f862c4943915L,0x9508e813b73b3f87L,0x3bd805f3e52f97a9L, + 0xf71b5c28c9829b62L,0xb394c70e86e0cefcL,0x534fb1a923bdb36eL, + 0xd64f5862dbe27e5aL,0xbae23df383ab6169L,0xdd6df1b127c828cbL, + 0x1901899f3a307a8aL,0x36cc8659811ddf66L,0xa3cb777479943b77L, + 0x7d89f3836fd86576L }, + { 0xf8564242c9f92b2bL,0x700c6a75c46e32bdL,0x93e768b77f99a5c5L, + 0xb6efe85803149568L,0xbbfe8a19c2ce6709L,0x721a3b1bee6ec493L, + 0x26eeeea9c371c28dL,0xd798115e15177e1dL,0xd7bf3bceb068a5a5L, + 0xdf8da22046d2b4b2L,0x3df0995b59be9dfcL,0xc96897bc77640b79L, + 0xce0cf4c25a2bd3c5L,0x16f45d6e89afe744L,0xb53f3acb3a8509bbL, + 0x449af81f63f2a6e6L } }, + /* 37 */ + { { 0xc2fcf132a16d9377L,0x9ab377b37e1a2f9eL,0x72e1a12e86d19ae5L, + 0xd2b12e66d013bbb1L,0x0972e055cb5f66baL,0xd11de1c0399eab50L, + 0xc1f314fdc65f5ec2L,0xfc3118418a9ff593L,0xdf73c1ece05246e6L, + 0xc28d13631625056dL,0x30a9dbd76fb25e19L,0x049ed244845cd2d7L, + 0xc779b83fd36e852dL,0x85a35fc7f68c8a83L,0x299bf1e1c95e8033L, + 0x0e8617c320891af5L }, + { 0x5372060267c81b5cL,0x2fa89dcde737873cL,0x2a7430b0a8144fd0L, + 0x3006c5a726208c83L,0x4e066660d8ea40f5L,0x9dd025f9896413a4L, + 0xbdf380cc46b9149fL,0x801566190a125cc2L,0x04d6a3b752793c37L, + 0xb60013746b7a62f2L,0xa9cfe268585d5978L,0xdcad0cb88395fe66L, + 0xbab468fc46b261f6L,0xca0ef5ef9d9d9218L,0xc507d4a85e452402L, + 0x6f4404f1326cf687L } }, + /* 38 */ + { { 0xa3e1920b4febd3ffL,0xca6234d8fdfd2bbaL,0xb7d1af2ae19a9829L, + 0x23de1610c6f5bc20L,0xe204dbf3daa39ca9L,0x2a2de9b86d8c70abL, + 0x272e0c377c9d370bL,0x80914c06e565510eL,0xb611e7a857cbb6b0L, + 0x076fc6efd8266a6eL,0xdfac34ee3095801cL,0x69ff40a2b9e24063L, + 0xa7ba31a9787aa5c5L,0x0e4d1fdf33c70cd2L,0x903e31326895f074L, + 0x905771f87fb671e2L }, + { 0x5199ba0da4062beeL,0x18e7238c94d7d9f9L,0xf53f29bc1e0922c0L, + 0xde9b2a81b12d855fL,0x649f3eed6d68ca29L,0x64adfc34c50c097fL, + 0x81964ab99db398a0L,0x00d59c477a587224L,0x09fea39674c5903aL, + 0x6aafd8ee15043dd0L,0xc5721a6e5f1ecc20L,0xb6d6a4830db9b7b4L, + 0x06ffc61766c8d52aL,0x3de241d6acc82a27L,0x0605f05227f2f7a8L, + 0x6a22953b6404deccL } }, + /* 39 */ + { { 0x92452d8f74fce389L,0x059634c02afa5564L,0x9377ccbbf0ed7825L, + 0x89f4045b37718e0dL,0x11074e7d9fa69a4dL,0x5d70bb077295b0baL, + 0xb22d54adf107ede6L,0x5c39a3d8a1a29c7bL,0x37236c02d795e3abL, + 0xf7282d002b589951L,0x5e2265be5790bee2L,0x91e0ea11a8e65ea2L, + 0x0e71a7086001cebdL,0x16900f5a2c1c5402L,0xc3b2d5c0357f6981L, + 0x528c9ea0619e3427L }, + { 0x1edc86b45f26c577L,0xf80747089438bd45L,0x2dfe1013792582a7L, + 0xe08eaca0de1e569fL,0x5f952efa9a55a356L,0xa4d80b53e4976216L, + 0xd2b65855cd5d71f2L,0x246704bf66cea3f0L,0x193f641f492323caL, + 0xa681855c9adb1325L,0x86d522ce2d19d652L,0x53609f105b82ed7bL, + 0x3b0f00948e150d29L,0x23ad8bfb0b13e891L,0xcbb1556cf794b449L, + 0x200f9093738bcf57L } }, + /* 40 */ + { { 0xf9b22fc58388387fL,0xcf26f17028e883c5L,0x447cab90d1b7973cL, + 0x8d5d4ea2f6ec9171L,0x2e16f498c30cdbc0L,0xdc92910c48623c2bL, + 0xeb1491b030dbc545L,0x631deb2e14de21b0L,0x04a210662fe830f4L, + 0xa4c6979c379c1f3fL,0x8a732b68fb06a795L,0x3a44327a1619dfa9L, + 0x91a307d38dbe2c9bL,0x939bc8d203989feaL,0x3daabaf20f4a331fL, + 0x5c307e98dd0f55dcL }, + { 0xbbc4e0c435b233daL,0xe3d2908522f6f985L,0x99dd2d21a8b02468L, + 0x978f40e9a96916e7L,0x0327d86c614bccedL,0x95e95502b290762cL, + 0x0ffd2197a879f2edL,0xc436513750e0bd33L,0x26c3148a0827c4c4L, + 0xc79812a83fcfc0b2L,0xc3d8d17e31928589L,0x8b572cfe8830f42dL, + 0x7cd9ff924b07f83fL,0x331ca9500a51148fL,0xd0c539684c59f9acL, + 0x1df16dfac1434785L } }, + /* 41 */ + { { 0xcc7bb4ac68bcacc3L,0x06ded34f430f58cfL,0xc59f9f4fd461855aL, + 0xf549199445c9f0bcL,0xdc5f7ec64375c892L,0x1b8708f13c85983aL, + 0xb32a5cc482fcd087L,0xefdcdc352d6b4c0fL,0x4bb24f048ac6fb2dL, + 0x5982d4f533906471L,0x162eb52fb83a3ac4L,0x7130df282337a223L, + 0xdce7b802cbc3dbd3L,0x8b3959592467ac0eL,0x21d3d2e81b56717eL, + 0x729a7f5046512617L }, + { 0x874ed1aa8420f90aL,0x6368e19e0fe4c855L,0xb62d4aaab0be74afL, + 0x76fcc4808ca60ca9L,0xf310b5a57645a867L,0x131bac9bddb1b24cL, + 0xef77d71d2dea5b44L,0x4706d21072fcc64eL,0x29b92691673d77f0L, + 0x22e00bf3e89e0663L,0x472d0cd374077d40L,0x3e21040d829232e2L, + 0x2f916dfb38dc8533L,0x48bbb59b14b8f667L,0x19de9f4ad44be19dL, + 0x7f6d3649232d9d5cL } }, + /* 42 */ + { { 0x3bd064de6e794819L,0x5a6b694ef82ebda1L,0x1f017fe0b91e2804L, + 0x190d31f307a43cd2L,0x6c26f226630433e9L,0xba488aa70abfdcb4L, + 0x418d9085a46411c0L,0x1b934fe6bffb5880L,0x75d1e237e200f849L, + 0xdf04d63fa55413dbL,0xe216ed75e23b3f77L,0xa05866cb0f91bd30L, + 0x84c395d97729c509L,0xec97e188452ab2d7L,0x8cb7c1f90093d686L, + 0x2d032395628f086cL }, + { 0xa81c94074a44b4c5L,0xb9846879cc702c98L,0xcb502287ceb0dc97L, + 0x303011266e3aa321L,0xc0ac8763e4c256c2L,0x65034d20e55b4845L, + 0xaa96a040f240f35bL,0x046d26d37cf7eedcL,0x62a5a8e13b810656L, + 0x86044b9783d70c2bL,0x2fbaff8859e4da8fL,0x929d901a5457f5d1L, + 0xd29e1eb2b531b757L,0x214dabdc9e4e9739L,0x5bd724fc4eaa9bd9L, + 0x734c12b31ef9bb9bL } }, + /* 43 */ + { { 0x98fe3c2e92f9b086L,0x4641b93eb3fd4544L,0x47ce208b5c02c65cL, + 0x8a52dca1c4f03242L,0xb5ec17d9679d29f6L,0x11d2fed09406f5f4L, + 0x260f63dc0d9ba811L,0xde2b056f15472a3fL,0x1b170d9f007290e6L, + 0xa2e23e8db6b5c8f9L,0x345a2839cf34c3eeL,0x9bdc54611b973ee2L, + 0x65bda6c2bb24d1c5L,0x97d52ba33c6141a1L,0x47bb16129d2eb201L, + 0x7c558a8721fbe49fL }, + { 0xb9485a523f350fecL,0x016678c56a38d4c0L,0x8ef346a20d5aa64dL, + 0xb85daa02d96da2e4L,0x845ec4ea4f647b3cL,0xc0d1a6ca0d5e946cL, + 0x41d8d1c14fa9f4abL,0x43972cc59c8b1303L,0x67e1f48d434ffbfbL, + 0x350ce93a819d2318L,0x49f530906ddef23fL,0x3c2e6cf9200cf12cL, + 0x42691cc1640432fcL,0xbfff74b472496b52L,0x44527c9f020a97beL, + 0x34cd7dca7b3c4348L } }, + /* 44 */ + { { 0xf031761a59e7fe87L,0xb1eae31a0047cd72L,0x27902e68fae30f62L, + 0xa666f48db71db143L,0x75ee66780e0038f4L,0x3b45ac6702bdd76dL, + 0x0d2fb828a0d6cd5cL,0x27ce7f1d9d8c5b11L,0x141fe0e4120b5e96L, + 0x95a1b984b9267c37L,0x5206e589d60312cdL,0x1867342eda549356L, + 0x374520b9070c74acL,0x2703cbb59557b0b3L,0xf621f59ca6ed8c14L, + 0x7ceb1cc2abf7b887L }, + { 0x0647a5bbdb7fd65bL,0xd8d45cc036c9457cL,0xc6da99db9e12718aL, + 0xed1dbbf4e93a7fb1L,0x4512c95cbd1566a1L,0x4861ba00dbc0c919L, + 0x3c6cc2989e7f5269L,0x671961500941aaaeL,0xbfcf5d0fc8c538e3L, + 0xad6e9929a25a551fL,0x9071098517ca0f26L,0x743b78eafa89ef7eL, + 0x39d5ea3171ab4549L,0x7442f3f3e6d1c36dL,0x25a683e0059d568dL, + 0x1f629a99227ced5cL } }, + /* 45 */ + { { 0x8925ddace45a1c3eL,0x72d2936541f7545fL,0x45622fcb37e7f828L, + 0x882345133e4c79d2L,0x5dffaf849c2645d6L,0x3078f4dd994802b9L, + 0x566927f09d339fa0L,0x9a500a1e9fd91dccL,0xce0081800ab0abd7L, + 0xd97135a38194e5dfL,0x9e87630798adf088L,0x3baf01b89a45a2a7L, + 0x6fed6154788b4399L,0x980e5722e77a997dL,0xaac90ffa2a378eedL, + 0x4a75fda28bd805a2L }, + { 0xd09a8fbb55e74cbcL,0x737738cefab18f25L,0x0fc23ad69764ec3aL, + 0xc5a7d35be7e0ad31L,0xe75e068ee481cc9bL,0xf0c2ea993d4aec34L, + 0xf1324fe80d4a63c4L,0x5dbb7c1699b0592cL,0x442d674da7e0f46bL, + 0x5a5d66c7a300faeaL,0xe83dc8213333ac83L,0x70ef812e8c408496L, + 0x96e1dcb699ef5fc1L,0x6e2b771b1734e862L,0x04629cdc583507d8L, + 0x5819f9ae23d8179aL } }, + /* 46 */ + { { 0xd99691216aa78811L,0xf64ee8f42103e7c3L,0xddf0107022b9e698L, + 0xe6001f9e4f582cdeL,0x24a608af2ecfac1aL,0x6ef4c78406393009L, + 0x5262eae6ebf72911L,0xddbd0af58c4ee5a0L,0x875aff90ecd87bc7L, + 0x2fddb34c6f24f114L,0x48104281e865f172L,0x95692426886c1b9aL, + 0x6f5f32089ef4231fL,0xaf587acfd0a7e82eL,0xd65719179ac395c8L, + 0x7459603c1364a750L }, + { 0x1c2475bff41ae519L,0x34401fb14af8f251L,0x70ddfcd2aefb2c3dL, + 0x9b2d385b51cdaf08L,0x8531c2568208bb19L,0x16c89df64c33f3f6L, + 0xc23cfa9924571769L,0x2339b51e86d010baL,0x08db0e8d22638313L, + 0xf769e17900fedeb7L,0x3fd96dcba3687ef1L,0xcd046b2391476475L, + 0xf3ff20640c45c8ddL,0xefd167bdb8343d78L,0x493ccb6d4b77ee90L, + 0x33025513b3cf7b45L } }, + /* 47 */ + { { 0x36f0046935eaaca1L,0x0c384b7589119102L,0xcb375665e6d2954cL, + 0xcb9199b9b1e9d6d7L,0x75852349c29c2757L,0x89cbd1bab8e738d0L, + 0x9b8dbe905923a427L,0xa237793e18fe1889L,0xa4271757a742e083L, + 0x8c4979d24eebd613L,0x40325054d4f2cf77L,0xa3b8a091958705deL, + 0x1b191bd933d999baL,0xbafefba43b0fee1eL,0xb3bad1843facdf14L, + 0x9328adb04387561cL }, + { 0xabe84e80f906b872L,0x705523a078262665L,0xd89c6a7e3398ccf7L, + 0x2fab551df55b5323L,0xa0578eca0554dea8L,0xef26523d375589cdL, + 0xd8fd6242864ad750L,0x93f27fc5178fe1feL,0x7b3e6f309df87422L, + 0x2862e49e3750d054L,0x7d90c6b25dc038a1L,0xc1a1ae2284db682bL, + 0x47f3dab79881930aL,0x30e6bd52baf3e0a4L,0x0680025bf62d25c5L, + 0x0aa1f3cfadd0d5e7L } }, + /* 48 */ + { { 0xa982219022a10453L,0xdd1eb91c2a03a10bL,0xafbb5d9596646f3bL, + 0xa58de344f38b6fc6L,0xce47c3e5b8cfca1dL,0xfcd8e16d0f70da04L, + 0xac44349bda262ed6L,0x9320d87bc56e2f8eL,0x9ce3ea0819138e58L, + 0xa5862dffa2b236c0L,0x6b0f9a5c8e7efb0dL,0x4b53432b16ac78ebL, + 0x6ff43105709b51afL,0x08e236f88f519628L,0x1f93f176eed403adL, + 0x559337e09636545eL }, + { 0x30ddf738d8fd807aL,0xf4e0ec9dab131222L,0x14a2f4db625afbc3L, + 0xd5b706049f12f895L,0xb46f3c23ac3044fdL,0x1b232d1ff540148fL, + 0x61b458f539b4e554L,0xf694b24a0dd70b75L,0x0fc64299289581d9L, + 0xc05d49beee5fe22dL,0x7af3447f6a18bf63L,0xe96a1dc27f1929d6L, + 0x6afe6028c1551e8cL,0x27dacaf32b5d4fa2L,0x4a1631bc545c2cb4L, + 0x930070f9b0c914d3L } }, + /* 49 */ + { { 0xd2f32c5e69a9bc05L,0x0a5c19c6589c4b73L,0x095c9e5e94665f9cL, + 0x8ab0f293bcfb4c39L,0xb90708771ddb7c31L,0x894e965866b38048L, + 0xf19a90cf606bd9bdL,0xcc1d58dfb6fd2d69L,0x886dcc4e461d8a69L, + 0xc455c277f9ce4831L,0x749a5996765f8a82L,0x2ffc668cc3badc8dL, + 0x380183969112cdabL,0xa98795c3b243c7cbL,0x8775f310010a2224L, + 0x043a2141587b5e14L }, + { 0x7bbe9dbc3a873752L,0xee1493f42f442feeL,0x981ca2c8c18c2181L, + 0x00ce3090e29769e7L,0xb4626ac8de768c5fL,0x33e9ce4634d7677eL, + 0xf89c2cade0fa94e6L,0x04f5cc1141f5b5bfL,0x2565f7362228c12cL, + 0xf1bf706a0c05cce5L,0x5d07ffffbe487c4fL,0x3ec43c09a499f1a4L, + 0x4f4e79bb98d94800L,0x8a335a16073f12f8L,0x4bb5eaf70f970d6dL, + 0x18d0747bf24d0ae8L } }, + /* 50 */ + { { 0x58d3c77c84601fafL,0xc9465be2af1c1f72L,0xff626798d116d806L, + 0x3996c0c6d5b0d93cL,0x2fa1ad755ec6723aL,0x966a814403ba5349L, + 0xdc4c94222ac34d8aL,0xddf471deed675865L,0xd8aca597953d528fL, + 0xb2e463b524ebf67dL,0x258248717e25b4d3L,0x23c5adba43159daaL, + 0x5458f9c683357540L,0xcf685da7f938b1a6L,0x981a4fdacefed231L, + 0x711093ed08bb5e59L }, + { 0x12aa3fc6401f161aL,0xf7358560974c5e87L,0x4aa252fb17b5df82L, + 0xb0b82b07a48e6299L,0x0023415729dd847dL,0xf1e54d004529c5a6L, + 0xcc1c539e6d98f538L,0x36162b5328d3abcbL,0x75a379382a84f0cdL, + 0xf717a81b4dee7484L,0x16cf35fb4c23bf1bL,0x7fd1c29f787e8b3eL, + 0xb7da7e6859b79ab0L,0x072100a085f6c60bL,0x31840159e7ed48b5L, + 0x17898bda4d9c97d4L } }, + /* 51 */ + { { 0xcd8483d8ae1b8cf8L,0x323d4b42e9a28856L,0x7633584f204a4bc2L, + 0x4e0b2228ca7a69faL,0x8afbda8bf757bab2L,0x85b240886cc5f9caL, + 0x47fb4813d41a95c3L,0x3f1bc53cc2aabe6bL,0xf22cda3f1ad1599dL, + 0x1b2ec081c31ea9b1L,0x048f304b01614ac1L,0xce31cee9c6afa7abL, + 0x55af76334140dc3dL,0x84b7ab37dce8abbaL,0x50de7648c7cf3efeL, + 0x73a88dcf15356ab2L }, + { 0x3f86828806e83b39L,0x477a44139f44037dL,0xf9058b0f17dbc841L, + 0x2db64f4f54d17549L,0xa23cea6af2307ffeL,0x393efd554f126261L, + 0x2f4e658a10f37f26L,0xa4437ce3f4ee1e35L,0x64ef42a7a93cde8bL, + 0x1debc9f4939aa901L,0x44223d6a3d7b5cd4L,0x789a6a11f88a3accL, + 0x56fb9df82c608a2dL,0xe79db8e3bbf56c06L,0x73c56af2668fa300L, + 0x52f32b17ae396a1eL } }, + /* 52 */ + { { 0x56f524c1e714f71aL,0xc1be12629add8519L,0xad9189d865cadbe3L, + 0xd88bf5c85a0fb649L,0x9efa6a9221d192d9L,0xe3fe83896f724b6fL, + 0xec3fae24b250119cL,0x4b6af9f62ae0d3c0L,0x8fceba0bd619624dL, + 0x7dc3092b2fdb6e3aL,0xc91da3763263cd29L,0x30c0761ef95c43bdL, + 0x89136400cdeb44d9L,0xfd7dce8443c0d31dL,0x78fec3b19871899fL, + 0x79e14d28efdf58c1L }, + { 0xe38222359bb40c55L,0x0a27202d0ed07a42L,0x48e6c1a94838c1f4L, + 0x2b5f24a7d864a78eL,0x7e7f140a0c6c55c9L,0xe62c104ace12d508L, + 0x9b0a1a7ec11b1e10L,0xfd8a275fafbb3dd5L,0xdff354fe9a3b6b30L, + 0x5a105d9e46602a01L,0x3d371b4d93bb65f7L,0xda5cbf0b0f82fdebL, + 0x4601229bde468545L,0x505e10b9c73d517eL,0x77cfa541672ff492L, + 0x0d8ec28a99566ce2L } }, + /* 53 */ + { { 0x014cf73ecbeee995L,0xb2eb88bcd491e80cL,0x615a6cadd9aba5d4L, + 0x2f7d46339304c84dL,0xba0501d28ab03c9aL,0xc8f723de91babb94L, + 0xc885f97750405772L,0xb5e1d2b3c7fcb094L,0x61ee7995df96c71aL, + 0xb8c8daab3464499eL,0xdb425ddd5f607932L,0x70251ca1b1243587L, + 0x26d7d3be9fc74340L,0x8c179310c902ac89L,0x72522c154559a74fL, + 0x86001e27c3734afcL }, + { 0x13b00ba5e7693947L,0x6478641e012c062bL,0xe1a438e0e85490a8L, + 0x5173dbbfd9574d5eL,0x9532eb8c9bd3ba61L,0x1f41bcb85f3ea075L, + 0xac1cc2478cbb92b9L,0x0f34648e1ef901b4L,0xdd929d1ed2b3b2eeL, + 0x470f1eabc3d75bfcL,0x5cdbc6f7139cf4d2L,0xcd86454df0424953L, + 0x1e07981247fcb383L,0xb9f209b417df930cL,0x4225fc31114ebc00L, + 0x020591cb347946c1L } }, + /* 54 */ + { { 0xe3003721275e0af4L,0x721141efe78a4a4bL,0x666cfcf6d1757485L, + 0x5fa1d737168e659eL,0x263e3e540e2842eeL,0xadecc3d4948bd5f6L, + 0x019de03d246b104aL,0xf8a9e903f343d818L,0xcb57ba4a5b0c0d31L, + 0x8246c50651e2765fL,0x80c5751f6519bf67L,0x5f05c200f2119a01L, + 0x7e6487b87821d4f4L,0x262f94aa261c3a06L,0x56cfe48972146052L, + 0x5119985fa1df05efL }, + { 0x5819497db18586c0L,0x004415d6c6eeaa62L,0x7c6a46b697cda28bL, + 0x9a149b287c194594L,0xb56369fa4ed3a506L,0x7092aa6643c94cb4L, + 0x55bce73aa9e9eee2L,0x34bb287077893509L,0x8af95fb006eb5326L, + 0x87cd03239638f485L,0x293762685ba75bf8L,0xf32d6f3d9d42d581L, + 0xa4cad57465c6d64dL,0x985f50fbb2cded41L,0xcf34ce0e9006a067L, + 0x59eaf26558a57f9aL } }, + /* 55 */ + { { 0x7b407efb6ec3876fL,0x780c6123f0f48648L,0x2abb56ffbf893039L, + 0x9592eaa045a91ab0L,0xce5b84d778811b82L,0x86a71a341f9f3fc9L, + 0xc17fdd86f0e7e13bL,0x88ed8297655a0880L,0x75d6dc7481d5e666L, + 0xeffc9df61d171797L,0x36ad4c8de3f79e1fL,0xdb15317d2046192eL, + 0x78c9fa7a274fda62L,0x04ec924f82dd9914L,0x059d1e383a64971cL, + 0x3b4450ea2620bbfbL }, + { 0x3db7a955c776dcdbL,0x35c4a57c81c8ba47L,0xae285003505760fbL, + 0xe3e80691b3aec353L,0x380335be47117be5L,0xe1c47e3a056ccf61L, + 0x253cfdeb33977916L,0x3decdfbaf5cb7ee1L,0xf3c9794f7cf4b704L, + 0x2401680c9ff81462L,0x4e440e11be3daa9fL,0xc5d0437769f91d8aL, + 0x4106c7a8cb5e9c5dL,0x191909a133b7d24dL,0xe893c8383764b4a2L, + 0x4a7fe30cc429b614L } }, + /* 56 */ + { { 0xe78f3a702455c7c5L,0x5b7636e870157754L,0xf32c45247623262cL, + 0x2c98b11e1bc780c7L,0xd48eaeac915ed877L,0xbb04d3c0199265f4L, + 0x6b52b19bcfa5200fL,0xc46a098193ea3fe8L,0xd82c733dba758059L, + 0xd324bbd61896aaccL,0xac09a2fcce8ecd51L,0x529918fd02fc44b3L, + 0xf0c45e4aaaa1784bL,0x35626340fe22085cL,0x53cbb676c50c7d61L, + 0x83fa1ea365126b23L }, + { 0x60ac86da10ccc646L,0x2ce0637f7b0451e9L,0xbbbcf6308a088610L, + 0x23c1901920349982L,0x707fc39cfc0bcda0L,0x7f4d1f151bd4fd7dL, + 0xd6a64e7444713bbbL,0x57bdc676c5ac9e60L,0x456c530337b61169L, + 0xd3451396dcf40a1dL,0xf3edec254997d2c7L,0x534ae9a4c2c4a739L, + 0x1401397e6a6ad2e2L,0x20769d4d23e95f81L,0xcee007c6de98fabfL, + 0x61409779931c51e0L } }, + /* 57 */ + { { 0x3ddb32db15156623L,0x68137fbcab7a67c2L,0x26011f506f19e3c2L, + 0x34218b0289924c61L,0x492a0b0fc6804c1cL,0xd65be706afaae6a7L, + 0x3b13d23e0d01be61L,0x44545b47f87f4c69L,0xd42236e204dc1aa3L, + 0x6135261d3c5161ecL,0x1eb46a63bd88bc07L,0x78c6d8361599d720L, + 0xf6955fe169baf0f3L,0x467eebd617072820L,0x2f1b8a2a3e3a340aL, + 0x636dac762d0b5f88L }, + { 0x94280db9b4c80af3L,0x9a189cd14e3892abL,0x26e702e0d1477ddcL, + 0xe91aee3868f9f14fL,0x2864f63a80baa0b2L,0xacd81f738b714a29L, + 0x30e1b870c5fe7cb6L,0x883ea1c3b10837fdL,0x2da279536b20489fL, + 0x3aeb2a6858a2da5fL,0xe2330bf203a8fa14L,0xb5c488b5dc70b1c4L, + 0x0a78c4d9299678f4L,0x233bd09825df675cL,0x37b5c0767b67d368L, + 0x2f6dbdfe4d0bef3fL } }, + /* 58 */ + { { 0x2f8472fd2e4da7c7L,0x708cfc91ae677932L,0x364af08a3dc268e2L, + 0x0f10dfe0799a2424L,0xef912d5871d58bffL,0x6bf35dfc988962e6L, + 0x28b96fa95f47ea0aL,0x734a79eaaad308c1L,0x957303379f437bbaL, + 0x002cbd8e6cf54f75L,0x47606dcfe7632eecL,0x404b5ecb53193104L, + 0x0ae0897c0acf729dL,0x89628b863bddf1deL,0xeced154ef87d7448L, + 0x5cb6e197458d5d4eL }, + { 0x98cef197008c75edL,0x7cf49d3ef6eeaaf8L,0x1d6f9e021875e96dL, + 0xfcec2cfedd9b0d8aL,0x38a61cfeb9576daaL,0x10003f3936a7dbb8L, + 0xb37c386823b814f4L,0x9fb66dcbb80e3153L,0x9e7e2eba059847a8L, + 0xa4ec63fd35a72770L,0x311f3d91fc9e0ed0L,0x3c1dc094d515baa4L, + 0x75a06ebca08cd4e3L,0xab6172382ed5eeaaL,0x2e82bbb0e1f52c1fL, + 0x2149d6305175d6e5L } }, + /* 59 */ + { { 0xee1a8e6f5f9311f6L,0xc97e3c9fbabc1f85L,0x4fa7c52eb494209aL, + 0x04c2f51c19774fe1L,0x5cefd1228555844fL,0xb53862a3b5873ab3L, + 0x768efdd6cbed19fcL,0xcdc12479ee58469aL,0x11237e313d80c09cL, + 0xdd74a290c044c28cL,0x9ee6517abd47e287L,0xc2421228ad0ffeefL, + 0x4273088f818d281fL,0xebc744bc43ec0de1L,0x5b26eccfb415bd73L, + 0x14e2f350cb07c26cL }, + { 0x548d2a104216946bL,0x6e801f077a4bd92dL,0x5996d0a343695160L, + 0x0f1b5c2f63a197c9L,0x79da3c4f061f77c9L,0x1c1cd63493ff7b22L, + 0x5e61b650a234123fL,0x826b34c5f284033cL,0x718b90e8c2f34214L, + 0xa5f35620ae806ec5L,0xa2fae345e324a9b4L,0x8c0bb95e8b53cb51L, + 0xc94f6ac2f9965778L,0x07ec607d6b9def32L,0x63bf1dbad0ed8f27L, + 0x58537e02dcb61e4fL } }, + /* 60 */ + { { 0x1f64b06464f80ba2L,0xe8e055e70559a45bL,0xc3262b34f1f4b634L, + 0xef4f7d5fde8c8482L,0x9d55dea0c30c780aL,0x1740afb9cfa1e693L, + 0x2cfe6a667460c34bL,0xf66959411187c1eeL,0x1382f2775f974d94L, + 0x1ca0ace4004549ebL,0xf8244b3fbabded02L,0xc36f4d064e3653eaL, + 0xeab9f0dcc55c5f83L,0xd93b9cefacebce90L,0x16658e7219061425L, + 0x4857835f82d7970dL }, + { 0xdcd525bcd2576210L,0x9f378aa7d51b5443L,0xfe97bf171bd83994L, + 0x930d0f63f38ac621L,0xaf8f2c17818408ccL,0x2692c87e260f53f6L, + 0x0ee45407db0a75e4L,0x0ec47ae5ffdb1b37L,0x769129dc7aa6a44bL, + 0xb6f932b22e40b75dL,0xe06764d095ef3b77L,0x28fd47f568bc63e8L, + 0xd18104949c0014c0L,0x90e2d3fdd7995d8eL,0xeb39a05d6c2a85afL, + 0x6c0277bda21f3128L } }, + /* 61 */ + { { 0xe41b7086b509e7efL,0x8842ec7b3d7f9f91L,0xcd285f945526b88bL, + 0x6e44e064051dd0abL,0x90198c10774f1cebL,0x6ecabe98123e661bL, + 0x4481113632f647d9L,0x1dd82b4526c52aeeL,0xd650907f939dc9d5L, + 0xbd5eeef2fcd455bfL,0x7815a4dd8d2e5d7cL,0x5ad4ec9288bc9f2aL, + 0xc6f10d0b57a3b322L,0xe8d0c1e720b9cbdbL,0x5a0b071a9b774ee8L, + 0x3067bc9af22fcf8fL }, + { 0xe0e589f2b7ca9326L,0x17a106fdb1224f63L,0xb2354521747a57bdL, + 0x2614982d62b0882eL,0x7f3af5444391ffcfL,0x1aaa337ba84e440dL, + 0x28ea37b0941bb071L,0xa957dcb42e4a7f54L,0xe7ab662c1a6ad5fbL, + 0xd135e381f7c36a20L,0x42e7980c9baa0b6bL,0x4237030c94e4671fL, + 0x24cc63ff8b0922e3L,0xd10d5279445a589fL,0xbb99d316a870ff6cL, + 0x390c83caa996c195L } }, + /* 62 */ + { { 0x50d3fa82ffc4a73fL,0x2665d6353bd53303L,0x80a06f8a264bb77dL, + 0x81c04a6e22d73d84L,0x2409cff50323b8aaL,0x31dce2178c4c4d5aL, + 0x374aa80e0c0f9c19L,0x0b25a38700186bb8L,0xd0b77a10aaf1487fL, + 0x15f39ad5ab498de1L,0x92e32da61aa0c116L,0x228e3dbd96e25ce8L, + 0xb57c88dc5e8646d1L,0x672b1164267b1c68L,0x5d0d807f600bdec5L, + 0x3ea4007d223e573aL }, + { 0xd76debd0a595d0a3L,0xa6bd76cbaff0b3b4L,0xbf2c154f9b1bdb97L, + 0x62b19ab44c714c71L,0xc9bf33b9221af663L,0x23d87c498c941ef6L, + 0x255804c3d79f0f6dL,0x6f1a10052a7acbc1L,0x5dab79d9550528afL, + 0xfd77a6f0c8d16213L,0x40508b6dde5e1029L,0xd95ac0f2f95da12bL, + 0x8860af71758a8ba1L,0x0b194c837160c8fbL,0xa40e6c80ce004d34L, + 0x09f82a176b14aaa0L } }, + /* 63 */ + { { 0x60abe588c21366dcL,0x729c0a4faf75daf9L,0x70501fd9acb93ed4L, + 0xb97e744e87a16d70L,0xa42e0a7a98e7361bL,0x1acdaff228b54cf3L, + 0xf087ccbbb7bd9078L,0xda6f3983663250e7L,0x66d693eebaf07c09L, + 0x79baf4c38cbaf157L,0x5a984e07dfca99d0L,0xab4d3247f26d8dabL, + 0x4d0be7017eba36f9L,0x37bb9e650e8dd216L,0x72aa4e24531c4f03L, + 0x77d1e984b753d85aL }, + { 0xd9373239d8e62367L,0x3361848bb9820cf1L,0x00c7e3445a9c97c4L, + 0x9a0ec9ae14f960fcL,0xcf41f0cf740474b5L,0xa5eede8fece065d5L, + 0xb1de5a4e9e808610L,0x17c44ae4ae0cf75dL,0x2fa563236b148d0bL, + 0x64fa740fd29ff2dcL,0xc605eb8a88cb212eL,0xf2c771ad6a863016L, + 0x6d6112e7607b4c17L,0xfe90ec0740d49785L,0x599be18be256e0e5L, + 0x4e6eabecca54adb0L } }, + /* 64 */ + { { 0x950323d3fb99cfe6L,0x7b09bc26c9334178L,0x64111e417cbdfb6fL, + 0x9114174489a75760L,0x4c633df910919cb0L,0x715fc7c7396bfd2fL, + 0x8ca195128cab62dbL,0x306724734db81aacL,0xe67a246bb4c4c54aL, + 0xd77ea0fabf229646L,0x5bed15f1fa5b5d70L,0xa5686da5c2f192f3L, + 0xdecac72a7f6690adL,0x0c4af2a2caa50b7dL,0xf44631c16049ad2fL, + 0x325d279604ecf056L }, + { 0xee11fb554848c144L,0x4e062925b6a7af32L,0x125b68e1369e0f9aL, + 0xad9bdae6ca53b21eL,0xf50d605c2e98ea1bL,0xbdb9e1539f2fa395L, + 0x4570e32de91532f5L,0x810698ae46a250d7L,0x7fd9546cad9d9145L, + 0xabf6772111e97a5eL,0xca29f7d5249f82e9L,0xa9c539a99851df63L, + 0xfd84d54b71d0e3e5L,0xd1e0459c041d2b56L,0xceb3eb6efd80096aL, + 0x19d48546e32a79d3L } }, + /* 65 */ + { { 0xfe19ee8fb540f5e5L,0x86d2a52f04e68d17L,0xd2320db0adbdc871L, + 0xa83ad5a8d03a7fc8L,0x54bf83c708bcb916L,0x092133ea2e51e840L, + 0xbce38424cb52dddfL,0xd5c7be4031063583L,0xc1ebb9df458e3176L, + 0xafb19639bc4dabbfL,0x36350fe4c05725a8L,0xac4a063484e1cd24L, + 0xadf73154c145b8deL,0x0aa6dd9eb3483237L,0xa3345c3dcbff2720L, + 0x1b3ace6cb4e453b0L }, + { 0x0343e5e990a8bdc5L,0xa203bf9d6306a089L,0x98489a358e48520eL, + 0xbd17debede7d1d06L,0x8fafa6d75f795d3fL,0xa4ceb630387b0a3fL, + 0xe0166b32ffddeafaL,0xa2fe20547e764e02L,0x55ab9824e871f304L, + 0xa2bd36bb952ec45eL,0x7b4c1484a90d20caL,0x5319f38775bcfb53L, + 0x34238a4a6982c4e5L,0xa2bb61c7a102921dL,0x1e061b64db3ab17eL, + 0x538ec33e192f0a14L } }, + /* 66 */ + { { 0x193496fea19b56cfL,0x663d77f47bb99acdL,0x8f04afa857d0a881L, + 0xcced3da2082835fdL,0x7e21faed5d82cec7L,0x6e175b99f8009c85L, + 0xd9c6e31b2d05a307L,0x96948d4a81487d82L,0x86ebd3f2d46f6655L, + 0x86851aa8773ccc49L,0x3e220f228b1640a6L,0x9f06e3a841a20b75L, + 0x2cfffe5e90ac0a6fL,0xf5a9b1da8ebeb3fbL,0x2587d9976e08e2c9L, + 0x6fd6029803e9f401L }, + { 0x54709f8d8eb7516aL,0x83058a74bdc598abL,0xd234dd9887e801ceL, + 0xfd0f9d90d17b8a96L,0xaa1e549f6e90f6abL,0x2496ff805a7ed55bL, + 0x0d9f657a6c254c19L,0x3cdea49cb8962575L,0xb685a3f02dff27deL, + 0x3c50e7fddb8bc04bL,0x904ff0ff987236b0L,0x494298fdbb0d5055L, + 0x34b3386de14be8d0L,0x7ad34e9c7c3d30d6L,0x1f2b32bde159fdd9L, + 0x84cfa23cc761e5c0L } }, + /* 67 */ + { { 0x13bc11eb8b99b964L,0x8e280c0a58e2fc47L,0x870fbc49d4c9a54bL, + 0x37a334a2bf6e20faL,0xee583d0dd7c88cfaL,0x05e029a8ef4af1daL, + 0x6d55e2340c2ef8a6L,0x61b6fdfe209e9b62L,0x3b1dad26bb8e080fL, + 0x5adbc1629392fc1aL,0x02ac0fe60aae3f4eL,0x8d99801ac2bf4d5bL, + 0x2333f93fc282fed2L,0x16dcb10cb52db33fL,0x09f90f84c55752e7L, + 0x287d4c51c84a0d8eL }, + { 0x5fa582010e9867daL,0x614589b31a874cdaL,0x005e27c5fbdee22eL, + 0xe357fef5e612bda8L,0x4e0dbedf2d3635f9L,0x62be70e46f125a86L, + 0xa09b98840d94a2e5L,0x7eb99a1528b5e5d1L,0x21b9416e751028b5L, + 0x1b137fd7e06d2cc4L,0x6fa1f517fea09845L,0x3ba1e966ffcecbd7L, + 0xd4c89a4a832f453eL,0x07b1e2afeca68fa1L,0xd0fb44534bd395a3L, + 0x0132a3dcd8ef9e13L } }, + /* 68 */ + { { 0xe53c7785576374c2L,0xe60526d184727040L,0x8a066dc8228ca044L, + 0x1fe1c1b2f1ce1313L,0x2aeec832cdeb0c5dL,0xa75966999cbf826fL, + 0xcd188e81de77a589L,0xe5ce0fe0118d1254L,0xa142a9840790b86aL, + 0xe28f043f39ac28ceL,0x4eef829087de5804L,0x83c31b32f639a8c5L, + 0xd70454a75887794fL,0xca635d5018b1b391L,0xcefea07631d9c795L, + 0x13cbee76b6f8aa25L }, + { 0x79cabe0f8d3f34f3L,0xbda9c31ca3617fe3L,0xb26dee23dd9426a1L, + 0xe9dd9627f29c9104L,0x033eb169e2c6cd3bL,0x8a73f492fcba2196L, + 0x92e37e0bb858c83cL,0xe4f2aca623b3fbb7L,0x8101fb1e64be00a2L, + 0x91a7826a948f6448L,0x414067b4907260e7L,0xf774aa50e30bb835L, + 0xf922ca80c999c06eL,0x6b8635b90ba08511L,0xbf936b5c25fa04f0L, + 0x4e0a1adae02e8967L } }, + /* 69 */ + { { 0x00ca66708ba29c4dL,0xc08240ce22988094L,0x21c5ca6716dda752L, + 0x689c0e45abbbfa34L,0x1d7545fd3ed28b72L,0x5f221198d7c56ab4L, + 0x4b3d8f7438759d65L,0x93490dfb8fe50b89L,0xb641f5d7e80eba16L, + 0x7b0da5eb79acb537L,0xab6b14970c1d5e5eL,0x2338e68da5da429aL, + 0xe010c4372f6d2f25L,0x226f16d26530f3a7L,0xefb0f7b6cbef08bcL, + 0x733e30d99f99c999L }, + { 0xecfe1582a42a38f9L,0xaec2d58e4730b500L,0x2ee2f2a7de976b2cL, + 0xf0539db5a969c1bbL,0x31954168fcecdb4aL,0xf2f7348ae7a8e902L, + 0x1d58d7cc3121541fL,0x5d25b75c2202ae52L,0xdea9965af40835a7L, + 0x3feb6a41529b4e46L,0x5c97fb6fbd27ad9bL,0xd87554c0261f900bL, + 0xb43031d904d5b19eL,0x33d5e9b8cb219b9cL,0x7a43d4923ee00bcfL, + 0x56facb39b79a5c0cL } }, + /* 70 */ + { { 0x019165a2a3018bfaL,0x100c6b249ffad984L,0xbbf1b1f655341a9bL, + 0xe6bd1d9725dc4cc9L,0x52850ed52bfffe60L,0x24e992cc7e5509abL, + 0xff6c502e4ceb59f1L,0x2f0b35731aa7d148L,0xe90c1ddde7e3aa46L, + 0xbaec9f45d1142880L,0x475cfd2665be5dd5L,0x83abb14e1febce13L, + 0x6aba482980942d30L,0x1e1b235d297e82c8L,0xb771cdbe50d8218dL, + 0x88599266d94d6cbbL }, + { 0x08847290155ccaf2L,0x8679ebc77c5b773eL,0xa88b2dd1b2dd08edL, + 0x960a180e87d475dbL,0x80fdb6b76694d02aL,0x3e8758c93f3f9e96L, + 0xbda3f6fa4ad836c4L,0x9400c58132fb387dL,0x25a785422550200fL, + 0x2a97c351776ecf18L,0x03ebf46e566db59aL,0x4743a28026545edaL, + 0xed169d84cf74ab44L,0xbaab931d88cb3f69L,0x70ae932cd8257196L, + 0x797224a6a0c09719L } }, + /* 71 */ + { { 0x632923f8441f3567L,0xc11c31682e24bf1dL,0x4b97726bb7671fffL, + 0x601746a77a5e1a22L,0x53dddea03addb417L,0x57867a3c7f59b846L, + 0xb012a98756cd7ff7L,0x1bd5fec9f19ba9a8L,0x750379a2f8306748L, + 0x7763445dab8c05d1L,0x5d7f441b7903f42aL,0xc011674da903e46dL, + 0x1b1d3c4dadd126c1L,0xa2752aac61455b40L,0x4da42a68555c356eL, + 0x3ff09c15d820852cL }, + { 0x4c0a1bcef9cb7784L,0xaec539bc2422f305L,0x5f40f9fd0c414aa7L, + 0xd3aa316cffd42bc4L,0x42f5a4c32f358e15L,0x00bdcd9ed6e27682L, + 0x069f789ff8a5eceeL,0x8078018e05e14f5dL,0x2bb3e4938b40c741L, + 0x5dbc8c1d7917f72dL,0xe0eea664cc57150cL,0xa25ecc5ac3fa8920L, + 0x3c21b0f51c797164L,0x8f09a2f2634ad16bL,0x8e730fc558391d9aL, + 0x47ef18054fdfae4cL } }, + /* 72 */ + { { 0x9965f3d13da285e4L,0xba7d4dba3a01e3f4L,0x4738413a61214ad0L, + 0xd3b7d53522397549L,0xa53dbdcf5a730b92L,0x3130d92b332d165dL, + 0x44a2854182f97ef4L,0xbf62221c44dce1b6L,0xbba138587e2a0ec9L, + 0x33f32c8dcbfad998L,0x409e5f3fb5fed44bL,0x5c328c65c66217bbL, + 0xb00db69ffcdf71a9L,0xa23c2a21b8920788L,0xf8ab28e63ae6464bL, + 0x1a6b6e9cb8de0861L }, + { 0xaf6ec2b606af77aaL,0x2e60f5cda887f065L,0x87d214009f498c56L, + 0xdb595b59fcbaaf4bL,0x0fb592a1271ab855L,0xa0ce10e5d4349b0cL, + 0x9d6187d8887d8c9cL,0x03ee95f9154bd6dbL,0x8fe532135d06c999L, + 0xf4a7bc30fb6a64d0L,0x3d22af0d66a4cb60L,0x16952cef5d37367cL, + 0x6f0ea734997d8e55L,0xb447c70f731732d0L,0x00ab3034a9cb3942L, + 0x79dd018028510fd0L } }, + /* 73 */ + { { 0x04e0033a3ac7424eL,0xdb06b68860fda4d0L,0x236a9766bcb772fbL, + 0x294a8e2bf297cda4L,0x4b0aab85db013c6eL,0x3d2aec988723a3adL, + 0x0cae32cd13c84a6bL,0x21888f5e70ec169eL,0x739633bd42a88262L, + 0x68ac792e7b60d9b8L,0x89f2b72210769fe1L,0x8f3fcfe6d24bed34L, + 0xd35efb88a3eb24aaL,0xddecfa3f484c706bL,0x7cc119a9929ece0dL, + 0x87e5ad458d405436L }, + { 0xba99aa9d7d1000a7L,0x8b94affcae823833L,0xc8229628dfb83dc5L, + 0x2f59fe11845a418dL,0xa8b970f85d417054L,0x8918c26572b71581L, + 0xe4ef477dc0d1dd17L,0xb50b4cf33afad7c0L,0x21baea7901870a5bL, + 0xc77087f9bb3a2868L,0x7857531e124a59cdL,0xed74c26f57f43239L, + 0xd5f5ae250164c94aL,0x6608b7e2f094bf74L,0xf4cdb5bafdceea32L, + 0x0b712519990cc045L } }, + /* 74 */ + { { 0x5a290ca188d5c64dL,0x0596d749a7492534L,0xa04b0d3d2a00e925L, + 0x082cd02ccaf7b66bL,0x912b50c2ecdded83L,0x813ce9deff31646eL, + 0x62ae70c7c75fff95L,0x6f6852e07e2a4615L,0x320fd7d003804fd1L, + 0xb1a2a4dd8218e8d9L,0x4918a6fbafc645d7L,0xfb080fa1e8d9fdbeL, + 0x33d4d08a4470b6eeL,0xd2ba20776d974ef7L,0x8ecb95a769dae5d2L, + 0x7a3f423a7d69596dL }, + { 0x362d2ca69a929387L,0xabdb7581cb1c1fffL,0xd892ec9f7e51b6cbL, + 0xee8d86323a4e131fL,0x4680e3f15bd87561L,0xe3a597e1d4e7e732L, + 0x3cc72b7c5581fefeL,0xf3e77f8aca8cae0bL,0xfcc7d7dc5e2fd4afL, + 0xdd3a455221355b79L,0x546b24f2a2c07177L,0x415b532d0689621fL, + 0x2be9af513f78163eL,0x27d63b9b33d7ed21L,0xab019ef296802943L, + 0x2da5fc551623faf4L } }, + /* 75 */ + { { 0x62429cf3c8a5c600L,0xa7a80c223fe33e7cL,0x9ffda7400a57ddcbL, + 0xd1ae156d925b0c74L,0x097a43f96b100eb0L,0x169e945cef943c81L, + 0xa1f734e51128cf24L,0x04387c4a419f0133L,0xc007868b01044024L, + 0xe5416abf90359cf2L,0xf9c76fee478d54e3L,0x66219da642a2173eL, + 0x61e031569fe30141L,0xa0ff5ce393ef247eL,0x811792ba072b6592L, + 0x855f021970c854d3L }, + { 0x61fbfb6c847314c4L,0x97906155eb45b96aL,0x7102e1466ba2afacL, + 0xed51f975ab949781L,0x9d2f5b17c110c4feL,0x7ac8ce70aff57667L, + 0xe7366a216eb244e7L,0xdd1bbcec551c65c7L,0xb525060ae1a859deL, + 0x7a0481748ba7d2e7L,0xe1a2c541ab8ea8c4L,0x6e7824c36fdff078L, + 0x79b49fc714874b04L,0x22ae337f06b1f733L,0x1c3521926f8fe6cfL, + 0x292236cf525d0797L } }, + /* 76 */ + { { 0xcdb8d80a7d8b29dcL,0xd17a202408ea648aL,0x7db12c5eae92be91L, + 0x1f347d18fda72fbcL,0x11374b409e760c6fL,0x7361e8f1d8e38d91L, + 0x7714be9d739ac1f4L,0xc1f9701cb4df5c4eL,0xd9138ed86f72cae1L, + 0x1c7fe1f76ad180c4L,0xf8c185be9e2dbf9cL,0x835db2697c70c44dL, + 0xf997cfeab0d15b5fL,0x5101445a61e6545eL,0x16b0688425184e5eL, + 0x7cfac3597521e7aaL }, + { 0x811821673c0bc53aL,0x84b5ede37e751367L,0x3ca255fda3657a18L, + 0x096abbf4ba1fdd98L,0x9ce8369fc5da77d8L,0xf27b9ae7aab342c5L, + 0x06c91bd6972059f1L,0xee0dab30914ecfe9L,0xbb647fbb93f53f12L, + 0x30c38a7affa57e0eL,0x517d06ef9f2ad607L,0x49728d87bb99dcc9L, + 0xb0034af1446080a1L,0xcc810c3f12b9c17dL,0x7225f14f772a22a0L, + 0x6ce3dc7f1ddf82bdL } }, + /* 77 */ + { { 0xc07cd835a4397830L,0x4dd9290cf4733306L,0xdd35d3a829989e8cL, + 0x79902559563d8152L,0xf278d911e87de61bL,0x9c7340c71024e35cL, + 0x2d4444614a0d0e59L,0x63e7608ff32626a1L,0x627a37e9c4c9baa9L, + 0x0c56dc5176fffd25L,0xcb6defc8cef2a1cdL,0xcbcc0d56efc559d9L, + 0xe45f3fc5041cb692L,0xcd05c239e5161e09L,0x2a731ee95c3b559cL, + 0x85151122a3d0a16dL }, + { 0x782d033586ff19e2L,0xc2c60daa1da28603L,0xb2e78cfe557c7eedL, + 0xa8f6f9841bc4e8b0L,0xcc1f9b4b3df35c67L,0x96e136034764462aL, + 0xbf910b977c7ae0b0L,0x27c7f30551435956L,0xc14db15cf631eae5L, + 0xa51d61427e69b34cL,0xdec828515fc12ff2L,0xfcceae13fb887162L, + 0xda332ac1de1488bdL,0xa20374e22ee3e74cL,0x597ea1a1f0ae069cL, + 0x8b1159f277bdec04L } }, + /* 78 */ + { { 0x4af71a442f961d30L,0xbdf968a87ac7248fL,0xd32df87cb1a906cdL, + 0x00c10e2604abf925L,0xb8711759b9f04d4cL,0x00d54e60939705daL, + 0xf7587433c9f80849L,0x2e9abade6a7a2375L,0x5676d47894ac17acL, + 0x4ca0525bc202d99cL,0x95b8bcadabfae73dL,0x2371ed383405991bL, + 0x2b69e47a458a99c3L,0x7cac0b182b78c866L,0x6ceaa79be0232c7cL, + 0x0bd86433588f7459L }, + { 0xdea1a8b47e734189L,0x52c5ac88cfe5fa17L,0x444a4d4e11437664L, + 0xc2522308af9e9750L,0x78b1d0c3d30c6b3bL,0x2edae5f04c6df477L, + 0x53131d9a2ee88dd7L,0xc4e380eeacc93e34L,0xd499b1aca8db0e8eL, + 0x77348c167f5d49d7L,0xc96632571556ccd7L,0x65ce0e8c2611d13dL, + 0x2c95fe66b5a2fdccL,0x266988328658faa1L,0xda87d1f431c32c98L, + 0x46650598fcd91907L } }, + /* 79 */ + { { 0x4c6c13cc6b4a5efaL,0xc481989b1d07b265L,0x10b966ce8bdc69c0L, + 0xf54cfaa22c2531d4L,0xcb5f1808cad0a100L,0xbeb52538ee5da449L, + 0xa6240085bedd83ccL,0xe792dacfd6255c78L,0x883719062062058fL, + 0x96615e83ed1658c1L,0x4b549b277d28d542L,0xeaf127db83b75df3L, + 0x4f60df6d17fbb942L,0xd08631dbf6f7c930L,0x17c38f986018789fL, + 0x0c43574ab9a9280cL }, + { 0x76eb324c1d20cad0L,0x90decb098c61108aL,0xa6e9d39c6f06d36dL, + 0x6cd978babc0da197L,0x5948b1c0507ac5ceL,0x2bd47164c5497eb5L, + 0x2a9c4c0f4d5914e3L,0x772c5046a759f03cL,0xe7d7328a69ac847eL, + 0xa8d57d0c3048b330L,0xe60034e040f7baceL,0x823d9193a85f1790L, + 0xa6e9b66c5c859736L,0x22ca2c7a679e1022L,0x00e7a19c09023fa4L, + 0x324999f12726d5b9L } }, + /* 80 */ + { { 0x667eaed67c834915L,0x9f77aa6abc5eb64dL,0x729ebcb625d62011L, + 0x0aee24f2699fd9c2L,0xe1eb58742b8d4f6cL,0x7f12710c14c976d6L, + 0x91390335f6d9ea65L,0x668b704906b50064L,0x65969a0e0876ee4fL, + 0xf901bf3f2f9d9360L,0xfb1a8651b499e3ceL,0x80b953fbf2dbcaaaL, + 0x312cc566973b06b6L,0x3534d9c33af36c64L,0xe4463a5210ffd815L, + 0x57ea2b4bf18c2b91L }, + { 0x00f5e1628aa0f2f2L,0x8c7e75c50e46bcaaL,0x97ab479aa4a2c42dL, + 0xb4f308ea14baa202L,0xa901bd146943cc2eL,0xbb125feeeed58804L, + 0x6502c8f99d180f7cL,0xe53539191580c61cL,0x7e27806927101ee3L, + 0x7a0a40a1faa72717L,0x32edce024c75b153L,0xda23660b538f1c22L, + 0x4d511e98be307d2eL,0x24276e409baee0b4L,0xa78c39277ff1f307L, + 0x60480b46ea7935c9L } }, + /* 81 */ + { { 0x31087d663872ece3L,0x5f29be7d955b70f8L,0xb50b4fc79cf95bb8L, + 0xbae3b58ddbffa621L,0x0e61d280e022ba5dL,0x78ae51174181449cL, + 0x0b132840cf555485L,0x800ed1b6b8ce0b0eL,0x35dffdd578d5de3dL, + 0xf7e4237469a56b47L,0xd5e323698d910ae7L,0xb6ff52a06313c7c7L, + 0x5a2fe20da92de9e5L,0x41b347d3d12110bbL,0xc5905edb40c16f23L, + 0x0774a0d39a8f88ccL }, + { 0x3ae181abe3b6c106L,0x4ebe163f8de150b7L,0xcf75b82f6f354836L, + 0xaa0d20633ac7ac16L,0x5c680668291722afL,0x73941e6111545553L, + 0x17127e38bf5de3f7L,0x32cfdf031afb41daL,0xc6893c9187bc8663L, + 0x75046744a62c9c99L,0x96866e2d962c1947L,0x489ec8df378cdf4cL, + 0x3a60709b3407fa32L,0xd37d2159551290d1L,0x9623d303bab92273L, + 0x081519542432014bL } }, + /* 82 */ + { { 0xf9236d89fb7b2108L,0x3ecc83ccad75f9aaL,0xf7c72b15b4e1da11L, + 0x552aeaef0315c362L,0x11e140edf272fe3fL,0x99d79bf687843ee8L, + 0xce6b54fd1d9bb25bL,0xb20b0e215b1bad74L,0x54a0214f5b84c90dL, + 0x459bbf52fca6cec9L,0xe363c48d9e4df76fL,0x3045f84ed64cf17eL, + 0x8402a167f62ada48L,0x2c9e1bf36a74ca01L,0xe8cf9d41f691c42dL, + 0x5abf2178c2c4b874L }, + { 0x4777966bf3b3bccdL,0x0047e0f0be3e0caaL,0xcb8383b38c7d5043L, + 0xe77e3baf946fd5fcL,0x79baa785e9ec0e87L,0xd83c557cc8a18d25L, + 0x9b96e5af25befcfeL,0x4f05d15e98c71b61L,0x081f991a77e62da1L, + 0x1c6ec781cbaa3821L,0x7522f65de54d9bfbL,0xf5d0557344ed1430L, + 0x3035b31f95cafddaL,0x47e67f436378f5bfL,0x029f7cad5270b9d9L, + 0x15ad15874d916a48L } }, + /* 83 */ + { { 0x00de2eceaa588ae4L,0x552ebc58a371a232L,0xd00ea93471230444L, + 0xafbfa67de4b1832dL,0x29216341b689e843L,0x1f96bbbd61f4e2e8L, + 0x9542068404c29dc5L,0xc7fe382742317fd1L,0xe0a0aec663483162L, + 0xfc2b94d10700184fL,0x07219973fe1fbd85L,0x648b6ab1fb074352L, + 0x23bbdaadc46e5392L,0x0db8dd1f00fa56ffL,0x104815eb866725f6L, + 0x3f9c4cca52e81963L }, + { 0xff36b29732ce637eL,0x81a15f2df5d25cddL,0x1a1d052d8b02ad97L, + 0x2e5f3bbccfbab3e9L,0x60d2cbd7614eeb75L,0xd4491843cd5a793aL, + 0x2242cf75cdba2144L,0xa20705e788b99766L,0x64e12cc0ec77e132L, + 0xb1c14df6b61a9b05L,0x8fd97f0474825b5aL,0x956048213da31223L, + 0xde4867274d30c70dL,0xbcab8f151c12ee69L,0x5dc638b4668d893dL, + 0x6479dad6223f574bL } }, + /* 84 */ + { { 0x569044f3b05f2b26L,0xb35a294a80b9f76cL,0x8839fe284290f6aeL, + 0x761cfb23026a5877L,0x768926b62e5ff9c3L,0xbae6cd200b11c576L, + 0xdc85775672a03efeL,0x0cae074ae1bad63aL,0x3fe491a1d709d99cL, + 0x76c5ded66501d9c1L,0x1da6eca1c32aeff7L,0x50849d55c57683e8L, + 0x9e392e9cdf98d847L,0xfad7982f64d9a564L,0xf7c3bdb7a37b98b2L, + 0x1fe09f94f0860497L }, + { 0x49a7eaae7648cc63L,0x13ea251167cfa714L,0xfc8b923c653f4559L, + 0xd957619b81a16e86L,0x0c7e804b3c864674L,0xfc88134a1616599aL, + 0x366ea9690a652328L,0x415329604bc9029eL,0xef9e1994ae2aad2bL, + 0x9e2a8c527f10bef5L,0x73dcb586c67bf860L,0xf61a43fa844cc25dL, + 0xd74e7eea74eb3653L,0xf3356706dd240f02L,0xeec7694cfd83bcb4L, + 0x4de95786db62526aL } }, + /* 85 */ + { { 0x4867d3153deac2f7L,0xa084778ab61d9a8eL,0xf3b76f960ab7b2d5L, + 0x00b30056cfdf4f79L,0xd0701e1531ab8f4bL,0x07f948d59c779d01L, + 0x7c994ebc82675371L,0x1104d4ee48bad4c0L,0x798ce0b5bfc9d058L, + 0xc7ca898d309fa80bL,0x0244f225acb33eafL,0xd51e8dfc5b2f3175L, + 0x3e49ba6ba4d7be34L,0x1760f4c7bda02b43L,0x37e36a7e4435275aL, + 0x1c94418be636980cL }, + { 0x43a2131309dc1414L,0x060765fc43c93537L,0x6ff3207adf5f79ceL, + 0x6f18b1fa85d4cfcaL,0xf5c4272e63e995abL,0x121a09e4a82b3002L, + 0x82b65d1b97147f16L,0x4993c20c20a7fe26L,0x99c9cb98e6716726L, + 0x5a02d673feb440a0L,0x3f3fa9e1251b4bc5L,0x75dbc474a05338eaL, + 0x3cb4044b7b09f6cbL,0x6767da1880434609L,0x97851422098ceac2L, + 0x611bfbb2b55235baL } }, + /* 86 */ + { { 0xbdbaa55ef00ad2a1L,0x29efa85e14a290d7L,0x3b4a4768e92b1694L, + 0x67111bcd11ec8130L,0x0e42570288bd27b2L,0xf28cf2a3d9a03c06L, + 0xbb7c8d2df318884aL,0xe2ea1462e3aaeb20L,0x3353580443b85d77L, + 0x81ee4482554ee9bdL,0xeb2eee9ee6aa198fL,0x7a5aa804c26c5944L, + 0xa0ef2da582ab167cL,0x5a2ab47602fe21a5L,0x169cb3b83370298eL, + 0x86e6c5440eb3aa8dL }, + { 0xede033210b793d9bL,0xf79fade11ddb5eceL,0xf73fda9268930b64L, + 0x06aad97dfe4fd1b2L,0x073a5b1d92a4dc88L,0x8af8cbd8bc976d75L, + 0x60b4abb163ce26c0L,0x9c8300a9dcb1fb06L,0x335a594cda95b3d3L, + 0x1f97d7d4b37eac87L,0xa3d2eba220eefaabL,0x3258c906f3e828c8L, + 0xc832616f85ab7781L,0x725971928c28b617L,0xcd7196bc3233b82dL, + 0x83867eb919fa126dL } }, + /* 87 */ + { { 0x774fe73e22474edbL,0x2a7663941a84e1aeL,0x270329ad9c6dd6e3L, + 0x00c4a41514f8bf5dL,0x3ce2ea37d2267b90L,0x1275301511d24faeL, + 0x7c14d854263a1b78L,0x20c8401b1ae0b206L,0xf32a011b081f49fcL, + 0x1e8123fb959c6df8L,0xa328dc7c800e1d06L,0x5876a37824259a9aL, + 0x23ada8b5b7ef6c37L,0x023f6b6ea93d4c9fL,0x89f5414dffb6389fL, + 0x4b26bba2e628b39eL }, + { 0xd30b1cb45d318454L,0x123b749fd7436cb6L,0x3110c726568a7461L, + 0xc85de1231c84fd1eL,0xa5f8d6e608403d55L,0x395b6e139b1fabf8L, + 0xfe6d68c33cfedce0L,0x1d90381f94b91110L,0xf0a8ea812dcc6eb7L, + 0x59e804137e90ca2bL,0xbeb5fc07c8a25c5aL,0x009c253a5d84663cL, + 0x00b15073910b6a7cL,0x8607da4c4108f8d5L,0x02c3d9c3cb901e65L, + 0x4d697bc52c9615c6L } }, + /* 88 */ + { { 0xe0db1ef0efa8fb40L,0x29021c5b5ba3989cL,0xa8d6fb15809d19dfL, + 0x6b787b734c1219e1L,0x6417e16814ef05e2L,0x449342db8f9796e2L, + 0x2f878a5ebf84421bL,0xe71916d7e94a4536L,0x9818bba3ae119693L, + 0xec674be95768804eL,0x0a26074cf8424f8aL,0xdbc93b9d466ce6abL, + 0xb3f15a98c920078bL,0x9d10fd0d3870f1a3L,0xa61241d9e4e785a7L, + 0x76ca87a1e6c8cd80L }, + { 0x4357fb56e02e48b7L,0xfbd14b13cc09e9c6L,0xdb5f243524069cf0L, + 0xf878165c2c3b01a9L,0xe549e7c4e6956dadL,0xf2fe9538bbd60b68L, + 0x952f856b059dc653L,0xd3f60225b377fe9bL,0x6a0c7328bfe908c4L, + 0xce6aa2d3bc8f5f2dL,0xf721344324425050L,0x17e1266a3d3b3ce5L, + 0x75b5e43fc1677512L,0x1592706237fb894aL,0x152607532be3e375L, + 0x27e7f2c66da3b7beL } }, + /* 89 */ + { { 0x638f65ade6a15883L,0xd4a7e68c66afdb33L,0x6207b6abd3f12de5L, + 0x1c6ff95037b87810L,0xc0d44cb264acf6d3L,0x163ac601f2be78c2L, + 0x1c63cc5a1636980eL,0x3e92cfe895c9349bL,0x7738e0d841ec7220L, + 0x6169d7642d5fa961L,0x2aa776c1c3e028e9L,0x93dc5646b16d5409L, + 0xa0b27fb5706df4d9L,0x9e991170ce9c6b97L,0xea8e42be53c85f40L, + 0x02e9643783246528L }, + { 0x91540addae78ea1fL,0x51a1b74d7b670e96L,0xf9936441f7006826L, + 0x8f97d6ea7d7520c7L,0x0faa6a0269ce12e1L,0x2590aca879208342L, + 0x7a48386375614436L,0x07c6149ef381408fL,0x733bf584d7853406L, + 0x8761b0109abbb6f7L,0xe4eb249ff528a09aL,0x08781ed82e00ae3cL, + 0x864c1b252178effaL,0xcc1e62a29d513a7eL,0xedb8b94e1919062fL, + 0x739f53da4f16527dL } }, + /* 90 */ + { { 0x7a5f4a88924adc5fL,0x95646c16a818f56dL,0x0ec491297795f954L, + 0x2b48753dd19c5400L,0x16fa236b205912b4L,0x6b3d65f3e87a4946L, + 0xa7174a01045fd066L,0xb635031312a5e140L,0xa79c4b44a96b8623L, + 0x7a339d659ab003d5L,0xc72f30c63826f31aL,0xb4e7390c6f7090cdL, + 0x59ac6c36906ebe24L,0x39a7f06dbba4505aL,0x839991e1c58c413aL, + 0x020c23ffa20e0e84L }, + { 0x120e4adaafc74661L,0x37bbcf63277fc065L,0x41049cf6b6dce799L, + 0x5b8d6b537b161ba1L,0x22218431a9610fb2L,0xde9ec9d1dfdde769L, + 0xd32bfa4d42d80630L,0x3885702a6244df4bL,0xcdedd1ed45592dfbL, + 0x0e1df45bfb4e01b8L,0x8f4bded286e215b0L,0x809354876a937e6aL, + 0x415278ba8130f723L,0xc6dc469238a821f8L,0x2207b119fd8b4f8aL, + 0x76e7bf53f9269cefL } }, + /* 91 */ + { { 0x5f12842827ebd187L,0x8d3320abb65aadbbL,0xb042765a72258695L, + 0xda3f33f98f0986abL,0x411807a7aebff503L,0x25c776ca825f71a5L, + 0xc0de7bedff7df24bL,0xda8b0f42165f1fb4L,0x5f3ff737731f3ae3L, + 0x4cd1d7e7193e0a52L,0x8df84aa3b6b3ba46L,0xba84b897aa1f3782L, + 0x6e7960cce7733ac7L,0x4d46d6ab50981a21L,0x1ec12c257cbb80edL, + 0x79e7ad272b96ef09L }, + { 0x3cd970dc8f30caaeL,0x85cabcf10a6ebef4L,0x63c1863ec714616dL, + 0x1c50db0b519e3a98L,0xf39b896364cb13d6L,0xdf67d81f22547b69L, + 0x7157abb9d67db0ccL,0xccca25ba889491b7L,0xf689207c7a27e0dcL, + 0x34ae8fbe0fd43281L,0xa5d91f735720ec09L,0xb2f61909cdfd7bedL, + 0x1ec102324a039e32L,0xd3c3d65edb0d8fdcL,0x32c916c84fe5005dL, + 0x7f8c37ac4c0bea94L } }, + /* 92 */ + { { 0x33ec1e5443ac05e5L,0xda4a4da4cd8d3825L,0x86d88c0b88bf9e2bL, + 0x34d71dd0b53811dcL,0x655040d2a3c3aba4L,0x2bc40949b61611beL, + 0x1c2d426e279a4fa0L,0x535a5aa23b065ac3L,0xdaa8a32fc52ea890L, + 0x5a5deca79fddad22L,0x911f05fd2ab3b26fL,0x5dace7dbf37cd81eL, + 0x0e0e44e790d16b8cL,0x15e68aede4f5894eL,0xafe04999fc92a74fL, + 0x1d7703aa970e7c2fL }, + { 0xa8a4c81d3f0062a9L,0xe31eb2b8d96a20baL,0x66dd98df864bd101L, + 0xba05f5924413b614L,0x51a67a0de9a555f8L,0xacc2f0972e4b52d1L, + 0xab5daaec7184ab23L,0xce08b43e7c7f691bL,0x520e530b76c427f4L, + 0x7d352069e423ebdcL,0x6b5e39e834df14ceL,0x3dcbf295446305acL, + 0x682cb2e1fe34cdc1L,0xd4ac45d1111f5afbL,0xc5ef63cd47f296f9L, + 0x0a2c40ec93c20871L } }, + /* 93 */ + { { 0x09bc384faf5747dbL,0x3bad6086c06ab86bL,0xa406882e9e7c1547L, + 0x2d5326d155977abfL,0x063a9a05da81deb0L,0x9a86e4a7524b6111L, + 0x1402f87a4ab2eb90L,0x7d0721d4d5c600baL,0x1a2fd9a9f289fdbfL, + 0xf5dce66decde6f07L,0x62171277dab9fa73L,0x6d2dc49f6c474babL, + 0xdc017e1f76eed033L,0xb97175c04da825d3L,0x6c297e3d54b05e43L, + 0x2efb454656c9c87eL }, + { 0xa4712b008b21c064L,0xd186fe424a70629eL,0x6435b3409b74f0afL, + 0x6965aa437ec9e629L,0xdda14673c4c60d08L,0x0b656670bf3057aaL, + 0x7f05e8403ce86f60L,0xc05073a904401a16L,0x16b1e638294e607eL, + 0x2078325269cf7046L,0x2941141be8ce7d3aL,0xd38ad8d37577053dL, + 0xdba68fb3caa6630dL,0xecbeaff1e9504350L,0x9f5166d51d2d760bL, + 0x337532ce462891e4L } }, + /* 94 */ + { { 0x3f1118533a00bb9bL,0x2d2ffbae45f66685L,0x9ae11a85d4aee24dL, + 0x18ba1e1b0341856eL,0xa9ac81782731349fL,0xc13dfd4a545715b5L, + 0xa5f7423c5daad2eaL,0x30a483b9535b76a7L,0x92e9ada4ff873e9bL, + 0x15662d84723a1055L,0xb935497b8edac4e0L,0x61b6441a39d8fa70L, + 0x1541d75640d1589fL,0x62994237f0a05f0aL,0xfd8b00346bb28908L, + 0x192a2b5dd4cd32bfL }, + { 0x63576628365ced07L,0x029f32fb05de1d1fL,0x6d17b9bcbf40a7aaL, + 0x1b1b2a089bb50a47L,0x9389abbb795a6278L,0x52cff60fb34fc19bL, + 0xf3ab9492387d8739L,0xa8f053e66920ccd6L,0x3ef2dd4b63a9b4f0L, + 0x9ab0ede151e82129L,0xafba0c0b0838bfa1L,0x2bd5a7ac9ffc11beL, + 0x058bfd9595cc0878L,0x686d48a3f8c2f0c6L,0xc33abaaf1d9b31baL, + 0x632e22893bc0c268L } }, + /* 95 */ + { { 0x1c851d2015a1cccaL,0x4efe290c7e522bc3L,0x0b741d5518eab053L, + 0xae656197bc85e217L,0xae13141e01cf8b29L,0x2e2cb59366948478L, + 0xeb57bb0fc31bd8aeL,0xdecef5d6c264e788L,0x6fa856cc9cb96d86L, + 0x2db16813279183daL,0xf03f3820383d796aL,0x58a456ff1d0c6fedL, + 0x255898058a6abd9bL,0x339f52c583f96f19L,0xcf6ded8fda7e9ea7L, + 0x68c3d9c15d1ccd45L }, + { 0x67e26265e6b392b7L,0xcec1d9bf775d9509L,0xe16abcd4d76514f7L, + 0xd86f59b20de72e1cL,0xa66e43cd1adfb033L,0xdb34434005e457ccL, + 0xb67a79165681daa2L,0xc32e7babf0114731L,0x066fe16ed3b1e961L, + 0x924e298ef63d26e6L,0x9bea0dd8541add6dL,0xef9500df9982f971L, + 0x5c876e63c5f076acL,0x55e12ae5b23d396bL,0x09efbb362ec6747aL, + 0x8f2055ee233286a5L } }, + /* 96 */ + { { 0x4a4ab9e3b82c1af0L,0xfc65e9e7f2cae264L,0x4feaac0a60187d46L, + 0x27d3f335e393b363L,0x9c9f7c00819bacceL,0x3f7418b5b8aa6611L, + 0xffa94557372aae95L,0x937d78048db38589L,0xd10c86df6f1fbc1cL, + 0x48aebd89a2f0a0ceL,0xae5d5fa2367439ebL,0x103a6a0b3f17d2d8L, + 0xf233f68a411d9894L,0x7fece8b3218b67a2L,0x0422540f2319bf06L, + 0x1292c8c9340d322eL }, + { 0xf5eb55870386463dL,0xd4bbc2b20371d97fL,0x1b3645710b819c5aL, + 0x0cbb42d6cf04ad41L,0x5d819c7666939ec1L,0x8745ac13a01847e7L, + 0x4f704b021c7232e4L,0x2c9e58a0acb05780L,0x9523b8b3b561e295L, + 0x3384df0079f9ba35L,0x78231fc21eaa9628L,0xa2eac54f8aea2b90L, + 0x8075ed7730d1c263L,0xacb44ed5fb339000L,0x92546ac2f011293aL, + 0x7c78762beb821764L } }, + /* 97 */ + { { 0xb8f7d6fb067902b6L,0xb2823a43d1735980L,0x062cfb1259741dddL, + 0x6e391b074033f95cL,0x3831d0a368589b8cL,0xe3474d49522290f2L, + 0x4dab14d6222e1f3aL,0x8f00fcde53f08d39L,0x559917ae707f28f5L, + 0x166aa0ba068e607cL,0x602713e7d7e1f824L,0x7c2555404d6a328fL, + 0x0d2e32649890cd2aL,0xf2207944eca0b20aL,0x5c98dc0752f4e09cL, + 0x69403504d84de81dL }, + { 0xf8b7b366e5407206L,0x1ecf54cf0d88fa8cL,0x6fefe548f7272e6fL, + 0xd653137281ab4468L,0x52cb5f0e4e474408L,0x9e426b3a6490737fL, + 0x2576c19b4980d071L,0x91f346280f272cafL,0x78e60a4f468f31c9L, + 0x8776a32990844d89L,0x8a55700cb951582bL,0xab1af36514b1adbfL, + 0x22ebff92fbd343efL,0x32f9fb01b7d81f34L,0xad850e06ba6b30e1L, + 0x6da9e027bc5f9546L } }, + /* 98 */ + { { 0x21eee4c25c9490ceL,0xa96ec4a30df68381L,0xe6c607e0a4a9368eL, + 0xd8b0492a4bc262f3L,0x0846a210460c34ffL,0xf7ff7a6428df33cdL, + 0x10c5504421827612L,0x9d25fce9149bcd01L,0x725611cdcfc613dcL, + 0x159f7e8897f51ce5L,0x3fa3bf314e8c08b5L,0xea15611575e7538fL, + 0xd1e0a95191c84020L,0x0d2268bacf02ad0aL,0xa04c6ac4058b8e5fL, + 0x773b40b9b3515912L }, + { 0x00ff2cdc3631cfd2L,0x14c4c2d3807737bcL,0xd600616a338a5270L, + 0xd0e3306db32cabdeL,0x336738eaa70b17caL,0xf2f4aa8d79f353eeL, + 0x712f6ad9576f3ad3L,0xe427985289b2bce0L,0x05d8f94dda92ca30L, + 0x9891d475d8492dd9L,0x3e06a5ca4d15e4bdL,0x4725d4eb254eabbdL, + 0x31394acec0ed513cL,0x7e0f9859bbfaae6cL,0xdc125546833fd137L, + 0x12b46385c56c4f75L } }, + /* 99 */ + { { 0x810dbebd932951deL,0x96959d425aa69c94L,0x5fc49c04ecb2f08dL, + 0xac74f0cc2250b82cL,0x96a439a53aec4e1dL,0xc33cab9a90499acdL, + 0x2fccde6654d9b3afL,0xf4af285c3863ae8bL,0x2373373e46febf88L, + 0x751d672c3c9ab7edL,0xc1c51130fe12020cL,0xad82402f52f3e56eL, + 0x3489ab7aa4a64a81L,0x0a1fb661d9f163f2L,0x17c69be10e553317L, + 0x61c1935e7d88d417L }, + { 0x2e722d9b3492ae43L,0x1ef89d950538f05aL,0xae77e588200aab63L, + 0x2872c120eba4b117L,0x5c2432c83a461cb8L,0x315b3434cb938f26L, + 0x05bf2ac58c4c7dc0L,0xd2e501dd596b378dL,0xa8506c9fcb890c30L, + 0x3d0af4617c361f0cL,0x21f7b7185a35cbaeL,0xbd1035f1f3fc0138L, + 0x74628af58b248edfL,0x8d6421d048c9cae0L,0x75e3da392ca18773L, + 0x27ad0df271d3db94L } }, + /* 100 */ + { { 0x9e3bda79305b5aedL,0x2c67d4a45998d6a7L,0xc855e1d30f7eb700L, + 0xc18a7e9e147d1c44L,0x3ea99618c89540edL,0xa53be20a7e6bfd20L, + 0xc9487e64ecc14437L,0x7297920734ef85c6L,0xfa0d4e71d5e1ebd5L, + 0xfda2b1e64d48d6b6L,0x782a1e0566e200d4L,0x2a3c70da5a5366a1L, + 0xfe3fbd2b1a473738L,0xd7ef8c067fe020e8L,0xec686fdeeacfb665L, + 0x5d9b5e276dd1542fL }, + { 0x3637c5a5cb3e472eL,0x2153d92730a1405eL,0x009992e5b4498558L, + 0x18f00ccdf39a0851L,0x26237c11b5c6c560L,0x418ed4081343540eL, + 0xfef7cbf07e7f3184L,0xecd92366bf48576bL,0x1b75be1abc94c91aL, + 0x8e1778de4a162276L,0xc52e57d3c5c6bcb8L,0x5cc382c75ab71858L, + 0xe12c2c283f6e39f9L,0x4c7e0ef2d62735fcL,0xe071deb1835a5996L, + 0x24f891cdcbb8c766L } }, + /* 101 */ + { { 0x24ef60bf6778c1e2L,0xff49c03d00d5be5cL,0xec11986e2f01a09fL, + 0x59a728a4ae096e58L,0xaabbcedb7077984cL,0xfb473bd2870ca5a5L, + 0x8c928c614de30e3dL,0x3fae7f9a4f67abcaL,0x83c2b2ebec21a9cfL, + 0xafa70d629cd9b5deL,0xadeaea59c60b18dfL,0xd5fef7be4049b54cL, + 0xfceebc766dd310e3L,0x7748efe38f6321ccL,0xfe9c32b118ee8af5L, + 0x863ac3cfd42df612L }, + { 0x0a36fca7b85a2fe2L,0xf3e70d08ee429dc6L,0x8c9ba209141c3944L, + 0x306a810667272a0aL,0xe69a1555f968bd06L,0xb86f7e47153c603dL, + 0x9706614aef56e4faL,0xc0dc36b898780b4cL,0x43657fe23a1d3263L, + 0x01f97a86435522c9L,0xd91897f6edfef679L,0xebbe31d46daa17a0L, + 0x6f17910085accfbdL,0xe0da6e328f9fc1deL,0x1c9d53dbe1e7142cL, + 0x3e3f1b1e8b86725aL } }, + /* 102 */ + { { 0xb7ea15c07b7fbf05L,0x992f11b61f1a3882L,0xc9ddd95ad1dcd1bcL, + 0x31f5b7faad0f7e8bL,0x2936e5ebfca7ab79L,0x30f417dc19a55be6L, + 0x1f6f4e4343cde554L,0x971f5e6582f044bfL,0x73c3b8e44288c408L, + 0x61aac59fb807f575L,0xa64ee2dd818b58f0L,0x6f7a0a6097a3b0d3L, + 0x8b85ecc80394b058L,0x9a059474bfb3517dL,0x89ad5977a79c3f06L, + 0x81208ed8700a8025L }, + { 0x1093509914c4ce37L,0xf34bb843a1aa48a6L,0x86007024580d58e8L, + 0x6db42c49b375b8baL,0xac365524ed3bde83L,0x5521e1b4649233b6L, + 0xbc7cc5d564dd946fL,0x9c14b035bfb5b6aeL,0x7f22ba180146c1a3L, + 0x0b62fbbc872214f5L,0x3acfd7f7b4921764L,0x5ff10da1cb4d6df1L, + 0x660e262062600a91L,0x7ac7da9d81d9167fL,0x6e8e260cb6e7a199L, + 0x44383fb880deb3c2L } }, + /* 103 */ + { { 0xe107f01de44f9af6L,0x36381a4d8cb1fa1cL,0xe65be3ecfb7dd493L, + 0xd0b8435a26a8839fL,0xee60f9153ec789d8L,0xe25fea502bcc5e1fL, + 0x0477c0c57e44a81cL,0x349e9f83230ba5b8L,0xdd42f32fde180dd9L, + 0x8b039eaf64a3d11cL,0x80ef884ebeb7083aL,0x288e60c4f12742cbL, + 0x44156cc5720a0262L,0xcd547de67253b77fL,0x9829a6eca6013a59L, + 0x8aee708f0d548445L }, + { 0x18f22d9c32c54409L,0xa9ebfa4675ebaac4L,0x90e2e92886284981L, + 0xd0201f6f6b3a8e0cL,0xc973016cbd77641eL,0xf926f2f070170575L, + 0x4984048ffec0ce01L,0xbf696211f319d304L,0x74b5c844c91a88c4L, + 0x4c40fbcee0030a82L,0xbed67525e4f6d521L,0xaf7e47cc29d67d1eL, + 0xfa307db8c21d3536L,0x56b6c46abbb29405L,0xf059a7e3033e805fL, + 0x970f61fe6096a5a0L } }, + /* 104 */ + { { 0x1bc53d231bec8e4aL,0x8809ac1435a6034cL,0x4ee081da509e464dL, + 0x496ae1fd8a488235L,0xa1ae9863325864b6L,0xbaca13e974cd069fL, + 0x3738cc58b1d8a6b4L,0x5fa71f58e76b9da4L,0xc919be88c7eb16fbL, + 0xf5c8f13fad4e429dL,0x4583b6712499f9edL,0xbce20115a10d8bd7L, + 0xf66d76055790bb7eL,0x9316aede482b78ddL,0xe0d8fb2d75f855faL, + 0x404b5b945a7dcca7L }, + { 0xf9ee682a517a15c7L,0xaae4cfbcef880202L,0xcee2c1395106a354L, + 0x5de60192170febe7L,0x589e39fd73d0c54bL,0x195c71358c9092b7L, + 0xcb7ed53f0a7bfe5fL,0x2bd9242af61cc979L,0x8d2ef16c5395f7d9L, + 0x0d4ac1ca70b32f09L,0xa587526d52d185c1L,0x2932b04a942d6195L, + 0xfe25a979a500b0acL,0x5fa1f4ae562fd230L,0x60f55af220da253cL, + 0x7faa11b583146002L } }, + /* 105 */ + { { 0xb0ba4f0c6e402149L,0x3584cc1d963cc119L,0x7740dc1aa6527476L, + 0x3f77ff75c95715f2L,0xb2f234ad3f89fb0eL,0x55159032ef9be3ffL, + 0xfc9fb21d04237e82L,0xeb2eff38a153ed93L,0x89d53ae010041d13L, + 0xcf2e545b7f1bd828L,0xdd4a27ce43953ea5L,0x00d2e5d4d85e75c8L, + 0xeb93ed62241be1c3L,0x1e53f25f0242032dL,0xb9957636c3a4e701L, + 0x14b63a52ed98febfL }, + { 0x7610b55371c43336L,0x19dfd4a623a4824bL,0x7b97a2e00286051bL, + 0x86abbb9c8f5f1edbL,0x67a57d779b67daadL,0x8ace506dcd5ffafbL, + 0x85da9f9589ac3c63L,0x081cbaa875a3d150L,0x03353d8fe9346ed2L, + 0xb2ab61f1a1f9a02dL,0xb0cb09373a659c71L,0xb7e0e30b4f5df8a1L, + 0x77c4c741eb7d5a1dL,0x8f046c9c728e5cf0L,0x32dd0bc7f7c171acL, + 0x02485873836d2655L } }, + /* 106 */ + { { 0xcd40dd2375a4cd8dL,0x132ca43397bcba78L,0x30c5cd84258d61f5L, + 0x0a7ec059da1e8e68L,0x07a8f1711d65d40aL,0x869e655ef4350d76L, + 0xb98ce6f05983ae42L,0x7b61391d9d8bebd0L,0x3a529e25b1ba5d49L, + 0x46f732e91f6b2cf6L,0xbd66ec6a3fa3b629L,0x397950ecc3ef0ed2L, + 0xee9008cb5f08b476L,0xfd6be425965a0e2eL,0x78ed513c1177bc87L, + 0x6798cedffe512daeL }, + { 0x49e3f8fd1b97c5c6L,0x39fbab3e78c3b33fL,0x4427441240f595baL, + 0x174225b95d7d4376L,0x880b3fcc79c44777L,0xdc3aca833296b245L, + 0x55913df71734e184L,0xa4db23d39c934472L,0xcebb3733d1420a11L, + 0xb9d20cf9f3608bdcL,0xa618acf630cfe13fL,0x75f06b315f30874cL, + 0x506efe7f9f0005a5L,0x8aaea78c01bfc9dbL,0xf9179255f78e7c41L, + 0x3ea7aed252e96395L } }, + /* 107 */ + { { 0x98617e045b06ae25L,0xbcac148dcb5750efL,0x91ea2f0e604c2ba2L, + 0x00c19f6b76b78975L,0x79b9b6d0651da181L,0xf3225bebc945705bL, + 0x30b435f35c005bf1L,0x440b4482bc24d86dL,0x2b8f0996d6373777L, + 0x65fd6c561c44b4dcL,0xe9405ee630906999L,0x19ff092408aa1ec1L, + 0xeef3246a3d2f2895L,0x016c3765bc746797L,0x62d2569fd0705f7eL, + 0x6a8ad39c05250044L }, + { 0xe45f020d46be7282L,0x9405afed21380f12L,0x4cdca5bdd5da6ad0L, + 0xc2d6f1847f8be61eL,0x20132953596b8178L,0x8d3b1e7b7a8df954L, + 0x757c61bb39572b4dL,0xd749b57b80cc3b56L,0x9590ff9337b3ffecL, + 0x39bbb653145dc94dL,0x70c1c6062335e573L,0x9c2e72d7f763febaL, + 0x4768e424cc61b732L,0x777d2fa6aa73f2caL,0xdee4dbaac5cb58cdL, + 0x1a1811799cfae1aaL } }, + /* 108 */ + { { 0x6f6ff62f77575ed0L,0x18f14fa97d1da99bL,0x2e72aefb69efd7f6L, + 0xc45ab4cbddc28633L,0xb0e20d48586c5834L,0xd397011a39775dd8L, + 0x0130c808f4134498L,0x2d408ebaf5115ed8L,0xc506a05c0260ded9L, + 0x9e5b736219cab911L,0x4cf508c6e8693a86L,0x4e71245fcc773617L, + 0x2f71aa1f95d89ca3L,0x4bba7c6a607bbc98L,0xf3a515e7212b7fd2L, + 0x7d2ddc759230f5a8L }, + { 0x3d05816d4ed2cae8L,0x4cf6bc7db9c00377L,0xc23e98e6646b08d4L, + 0xf9ee6c614b9c0180L,0xe11c9a13ef9179c1L,0xa5b6147e8ed9688aL, + 0x7afeb648d06670a7L,0xd670333c17685275L,0xa89dd96975f9e8f2L, + 0xbb57228d37a68adeL,0x21a05d5e454cb186L,0x4810158f063dd550L, + 0x92dd4f084cb6caf3L,0x70c4d8527854abe7L,0x845969dc6e729d76L, + 0x5a52f87ab1bf40baL } }, + /* 109 */ + { { 0xed019e9109ecacbdL,0x6544023d7b89bdeaL,0x7cc51f0b5707371eL, + 0x14832b0416c8e217L,0xb1aa668281259ab5L,0x6e100f9223e361d4L, + 0xe593eee9e3a95c2aL,0x699b6bbd16c10e26L,0xad4878739473a13fL, + 0xf1c14dc5b274987cL,0x57dc00752559e2e9L,0x8449849dc3d47ad2L, + 0x83df278add527793L,0x770e3ec8eefd5b99L,0x2ae5844676bd02a0L, + 0x17f027643e705ffeL }, + { 0xdda4010d29abea1fL,0x636b96952407ac4cL,0x96a601290433218bL, + 0xf221fc3b163d534aL,0x05ba15beccc20565L,0x1238e54d96285577L, + 0x1b144257878804d3L,0x96fbf304a89a9fe4L,0xc8a7f06c4be642b1L, + 0xdd1a20e86e2b085eL,0x8f7f27c2ff4a591dL,0xc17b0753a4a343b8L, + 0x684b1e88bb173d4dL,0x3accea443dc07bbeL,0xdb15c88d4c441d77L, + 0x0ef0309a53e5957eL } }, + /* 110 */ + { { 0x4fc25721fa8e5b60L,0x646938ad691c0bb2L,0xe46d4b760b0a2248L, + 0x863f9ac27de16877L,0x503bb6ef2721c630L,0xf8c199df0b67fb02L, + 0x78c1ed72e07abd39L,0xcf9deb7bb32f0ddaL,0xaff726f06c3c89f3L, + 0xb7008b2d1972225aL,0x8f5a61174f145f5cL,0x4e0e6f8c457c4f37L, + 0x8bbdaa441c453c64L,0x57be326da6e92c80L,0xa9bc3fd95d773561L, + 0x3d3b6cc6bb37b72aL }, + { 0x6e6f12cc9722c880L,0x3a1b6ae7286b6889L,0xba1cc09bad2fafecL, + 0xad64ad7a43bb8befL,0xa5af6a0097c3f4c3L,0x2afcb0d9c353a91bL, + 0xca13fcab69ccbf6bL,0x699a1391f2abc190L,0x2dbd554223a247e5L, + 0xe206180f95488d9aL,0xba9e7bff1244cc3cL,0x29297abe87d3a365L, + 0x4054fa38fa4ca5e2L,0xb390623d67be1b6cL,0x1fa67c5778f41a44L, + 0x2e946e43c7b544e7L } }, + /* 111 */ + { { 0x2980fddfc60934aeL,0x2c3e7eff164206d1L,0xf75e7f96416ed75aL, + 0xfac60cf35cd0b2dcL,0xddc4bece1faad87bL,0x753fa87c9849e5ddL, + 0xc5d516a32c1bf1aeL,0x565dbea814732b4bL,0x007ebe3ace48696bL, + 0x40ca74d6cdb97694L,0x3f5cd27065e4e7beL,0x74847c013aac4ebcL, + 0x6762e03443d6c3a1L,0x690d8c95467a076aL,0x768d78d61eda677dL, + 0x0997ce550181d8c2L }, + { 0x9297746c965a0b81L,0x48b58be6e5e12dfaL,0x5573b3c4715f437fL, + 0xe425e907b565c459L,0x4f43f5121582797cL,0xe5dafa6f8ea5474fL, + 0x2aeb8fbe13de04acL,0xed7f95f0e8a07c83L,0x3e012a6e662c09feL, + 0xbf96e9b8c742cf17L,0x8ea5759ae28a1c45L,0x475941b45cf4e2f3L, + 0x7dd3c02df901a019L,0xe7a4deea70916b2eL,0x50b272b52fa9b988L, + 0x96f9f09fd0917fe6L } }, + /* 112 */ + { { 0x78e8aac42c310a96L,0x32a98303f7a2a734L,0xc46ca83d23962207L, + 0xad131e6ed9541280L,0x5791fc5e2cabe911L,0x50cb77eb841b6c68L, + 0xaff93dea3d3c8878L,0x06541f1df1007bceL,0x4ee729c255cdf1fdL, + 0xe0f71317323e3972L,0xa2de7a41ad4d08c1L,0xa9912abfa35e22bfL, + 0xa050122b89b03325L,0x8b9e51f406514d4eL,0x423c7aad79d3e0abL, + 0x71998e2640b8fea5L }, + { 0x40140fcdceb6ed78L,0x653cf37718534516L,0x0450b65ae8d60dccL, + 0xce6c1a769dac55f8L,0x8a96a92dae05686cL,0x2fe4476212712562L, + 0x747bcb50a4f39425L,0xf0ec6ff2fc531fc2L,0xc97c344710fe9ff0L, + 0xfb4887839c792cffL,0x552c5248026fb019L,0x4001a29cd804c290L, + 0x742b5ad835c8ca73L,0xc3781f176ee5dfa0L,0xca6b85f03dfa4ab1L, + 0x8389941a0b0d32acL } }, + /* 113 */ + { { 0xc0f062a2de067dffL,0xd4f32690bcb80162L,0x98cd990d0707a2bdL, + 0x5afc63b8fae4a391L,0x684f1b7bb32ad814L,0xb0a2dce2f199dfb1L, + 0x2260e17f48f25848L,0x7393db00c2d5e862L,0x9e88f854338cf171L, + 0x0067942902acf522L,0x19157cb86835af3dL,0x2faa6f92b8a2614cL, + 0x04ff95f5134ec46cL,0xcf00626efb7a8135L,0x454b3d05b37a4704L, + 0x1fbfda312694ec25L }, + { 0xfdebb657c8f69c77L,0x92a8278ba3df88faL,0x463b5571c1fb78b4L, + 0xd2066a1a11c71a33L,0x10c88143089958b0L,0xb975c7e0cf9d67a6L, + 0xdaa5d20873037b8fL,0x5ee5005d40bf5861L,0x300e6ce77dba69a9L, + 0x893c3cb3c962cc74L,0x0ac986294cf84055L,0x0a7ef63a225c9d70L, + 0xfe184869b91e47e8L,0x1b9d7deb8c2f84beL,0x67788915c0e278bfL, + 0x4f9488cac426f19eL } }, + /* 114 */ + { { 0x610dfcd4dd51b8ceL,0x0857927836230e80L,0xedc7ff1c36599562L, + 0x905ead4be2cae877L,0xa1c325d9e7967608L,0x3e39edddbd38926cL, + 0xda92c8685f6f0a4eL,0xe16f800af47a0fa4L,0x50b4db5be5f60aabL, + 0x3665412f983853d3L,0x64b622509b79789cL,0xea5600584e0e72b2L, + 0xabbd4901e555c2bbL,0x378419a717292e11L,0x6e0b5aaae174218fL, + 0x688e06848f796b92L }, + { 0xcdfef641313b8f64L,0xaef11b7b942c7462L,0x067cfb775c0d8abdL, + 0x608ea5f0af4041a9L,0x23d5bd826935210fL,0x5ab904fc27917a08L, + 0x85dbb1fe45d22d21L,0xc3d5e5094d36159fL,0xaebb528e1d39b8f2L, + 0xdd5ca828f44acef0L,0x24209adf20c57a54L,0x5742b43378f95f44L, + 0xd11fa7d9a9337d37L,0xd66a0c09c64cfdb7L,0x56e55b8f9bb817ecL, + 0x1723c7e3e4c41265L } }, + /* 115 */ + { { 0x9a6486d8dc8b43f3L,0xfc3e0e6126409e68L,0x1889c437d9b46003L, + 0x3a8503356284ec7bL,0x5a3665c46a9dbaeaL,0x7bf6941de978933cL, + 0x1ed5a51069341490L,0x664a7b7a8cb8002dL,0x603f76e460ed0a59L, + 0xc3e06ba31f4ebf27L,0x296ced41f2c38a7fL,0x2ac18f79cf1db08aL, + 0xc919e882cde7a3b6L,0x15e77d29dbf68b06L,0x21978baa4e947cb5L, + 0x84bf542b7630993aL }, + { 0xc1decda9e364f21eL,0x0d6cf345012e557eL,0xba246848588f90e1L, + 0x9f6dda4be3b104b8L,0x6bf7a346e3aef57aL,0x210299fee8327ea9L, + 0xaa99f487da95e6c7L,0x24ff813ed2cdf645L,0xd1dbb2d28bd414b8L, + 0x065101afcafa1a61L,0x7d9f4b9a9cdebda4L,0xaf41b395e41039e4L, + 0xe3e9e6bac50adf42L,0x4f2133ae341e9e49L,0x4968c0f3cb157f23L, + 0x383f827bda068153L } }, + /* 116 */ + { { 0x2ec46a216583ff4cL,0x4e645a294ad709e7L,0xdc66e9cfc04ca12aL, + 0x82f128f49160a7e5L,0xbfb227b1569c762eL,0xf80c7963c2edb8e7L, + 0xa7dafe0649a0f688L,0xb7e417542d14b8ccL,0x3a0c5c5386de40beL, + 0xf0d052861db79331L,0xb902ce69fbfe071bL,0x61e46956210e9903L, + 0xfaef874ef703ebb8L,0xf668947edd5f78b6L,0x6fe865475af5ea3aL, + 0x3b121f1543f94625L }, + { 0x5b26e847659275e9L,0x47581cfd6d0fce50L,0x55f5cbfd8aa3f1efL, + 0x1e7be315e484e60eL,0xd8f1a20ffe9698e4L,0x25d46da97ab04784L, + 0xa526db75834cdb3eL,0x1fd408d98d08a009L,0xfc004b205b5ca816L, + 0x5b3e3bb365e4bbe8L,0xf50cc125759bb6efL,0xf05fa817c2fac737L, + 0x9ee102d2d273951aL,0x2a8e540bfecb3367L,0x673446fb2a6a515fL, + 0x5505e1d137290c83L } }, + /* 117 */ + { { 0x0c3014a1d15e68a6L,0x6f9f0b2664dd35e5L,0x18c3742d03ad67f9L, + 0x74818c0ed2c14484L,0xc51811690d41a3cbL,0x65c8c83fc49f3e9eL, + 0x9b260c612c279386L,0xf6086faeced04e9cL,0xa7b2ccebfd7c4758L, + 0x4b3c313390297fd8L,0xca8264e809701ac8L,0x9f976a87508b3762L, + 0x5d582714983a8dfeL,0x350d2669d9d598e9L,0x85cb89cb0f6fd348L, + 0x617d80d4a574317cL }, + { 0x4cef267e70022b67L,0x80536bb53768b94aL,0x3153a566d2784462L, + 0x49054d4438243919L,0x8d11e1725df78c4aL,0x9b252a71d5a1e35aL, + 0x07866c808171e31dL,0x0a8501db1b38a00eL,0x2ed932b8ce770236L, + 0xa2d776098edaf7d0L,0x3aee5dabb93006e9L,0xfaffc8c4bbfeb036L, + 0x077b96784e21b38bL,0x491fc59fdca8e069L,0x3f624f550e938471L, + 0x5156f5087cd1780bL } }, + /* 118 */ + { { 0x58234e220206e8d0L,0xf5f6f5d47f15af32L,0xafab7289d638950fL, + 0x66ec4d097d4495f4L,0xad890c5d68da80a9L,0xe4aa092064f8a36bL, + 0x799e257e0f4d5c5fL,0x44c677ae24495e31L,0x720387b3a5b8e352L, + 0x703790f475a287b9L,0x54895cc5c3c1f2f7L,0xb8680f9b41a7fa41L, + 0xfcd47458b00b008bL,0x149cc838ba6473cbL,0x78ed5f7aac9be19aL, + 0x5254599cb33765baL }, + { 0x08739679a21b54c4L,0x029ece2ab6497d9dL,0xf14f1a92c8488640L, + 0xae48dcffe9fa79d9L,0x14b911c246c208dbL,0x5ab0fbf2dae3f69eL, + 0x180ac87ed1edb838L,0x146fd718188586bbL,0x210eb6545467cbd0L, + 0xaa2394081667cfeeL,0xdb125c1ab73d1a60L,0xde685300881c1cbeL, + 0xfe34c71337c30232L,0xc6c6070e6f3c8d18L,0x07e365bab4af4e83L, + 0x22f0a7eddcf82b45L } }, + /* 119 */ + { { 0xe262791fea7f1b7fL,0x9c3d8c5ddcff09d4L,0x86c2a9c339c7dc58L, + 0x4dad40174276e8c0L,0x0a918f59e9fe1d56L,0xb8d796702aa810c9L, + 0xeb7a88364aa5cdc4L,0xfc4c23bbe7afa72eL,0x4dbb5c9e4ac86908L, + 0x37e390136a0c7e6fL,0x855d700149c218d2L,0xe475bc6794b324a2L, + 0xc98a8dc66287a071L,0x395a299b5fb4323cL,0xe186c3ee0c0389e9L, + 0x79f81e6f16734c46L }, + { 0x83f2c1f3364f3c4eL,0x536b2ac51367e14bL,0x44a6dcfc5933e43dL, + 0x34e5947510d961feL,0x08234ece7e3f2aaeL,0xcb92e00abdea7f25L, + 0x1efba4f0a791a124L,0xc2086fd21192d53aL,0xfec0d0fcb51c8af6L, + 0x48d1b2cadc0f1b5fL,0xb07a388f812dbe19L,0x40873a6adedbdd45L, + 0xbc2a1268d702589aL,0xbbf6e3a817e27b64L,0x73ee56636d386e85L, + 0x442ecd379de7c000L } }, + /* 120 */ + { { 0xb4cd1ae68a2f90a6L,0xf277d41d6f5ad0ccL,0x6a3828c4401d4b8eL, + 0xe817a134d8376631L,0x142b758df5e1124bL,0x25fbc69dfd6b95e4L, + 0xa30c9f5fd74a9e3eL,0x5ac0f163d89663ceL,0x32a9eef70ce6386dL, + 0x7a690ea5d8ed5544L,0x5de23ff09889427aL,0x75ad36a5eaaced58L, + 0x3514a6c1d3e18465L,0x3d9162c37f093910L,0x5c10add9e33d56e8L, + 0x85176b7306aa691eL }, + { 0xa32110fa28a21e38L,0x97b6379d5773d538L,0xd3697bbf2d020dc4L, + 0x59177593961833cdL,0x6d7045fae5fa8516L,0x3390f29a786ab5d2L, + 0xac0bda30dc4f5b70L,0xcca0240adcc615c6L,0x8e1f1702c5146d91L, + 0xceb472d0a72cef87L,0x848407080b669ba1L,0x79b08f9d7e61aa0aL, + 0x388160be4669560bL,0x23935c2d948eb71eL,0xd7fd83c09431590cL, + 0x8ab154bb6e5768b3L } }, + /* 121 */ + { { 0x28686003353c4a96L,0x4e5c60e8905cd835L,0xbd5913648f66f8ccL, + 0xb6b80b989faccf9eL,0xbc1c1faee32639e5L,0x2f6396d2278aadebL, + 0x00a796d01898202dL,0x18ab548f3a474835L,0xacd056c3b31b0e3eL, + 0x15ba68dd0164512dL,0x203836d94b03f3bcL,0xd64eca6bd8f206c5L, + 0x931a361e9f1779b6L,0xd82690fc52ab34a8L,0x342bb8e092922e22L, + 0x1bfcdd84e00b02a9L }, + { 0x310b9a4375a365d9L,0xd4ade15e08d8fb03L,0x9c9753d7d742df83L, + 0xcf7309d4de318742L,0x1228e2123360ace0L,0x1043d238f7669643L, + 0xfc2adbedf90f5a53L,0x41d64cb77b5f9397L,0x5200b30ac446d010L, + 0xc3c8642d231720feL,0xfcc0122db9aa2075L,0x856e3b12041eae47L, + 0x4586445568c876a4L,0x1a1c7842233606b1L,0x9b766d1f227757bfL, + 0x25b78a3bf7b9d4f1L } }, + /* 122 */ + { { 0x90835718156707ceL,0x9bdc23984314f90aL,0x017c885a8be57dbdL, + 0xd4bba225ad63a4b8L,0x5ce71b8615aacffdL,0x5f26647572954722L, + 0x0a80f1f74f0ad3ddL,0x010538a3fc352ed7L,0xf8a640454203c6caL, + 0x2b2c7a88330c73b4L,0xb3433ee602dcac1bL,0x2e0499cfed2b17c7L, + 0x9f8681a4bd6329c7L,0x3897994636fadc37L,0xdc5650c892b7895bL, + 0x70ab957065a51cf0L }, + { 0x46778ec47b585d93L,0xca6d3610a633fe4eL,0x21da154e4ea0311aL, + 0xaf22190bbd64002fL,0x9e633ac7d91cb7a9L,0xed13c31fee6837d7L, + 0xda4a07d71616ee8aL,0xd78a27323afcd616L,0xc06696e5ba14d694L, + 0x733754d74df58420L,0xe85e504e2778e3c9L,0x3055aa0c55b5a5c2L, + 0x313df5388a3acb5cL,0x5896acb52a088edaL,0xfc8842a084c85ddeL, + 0x5fec9f7951dde6beL } }, + /* 123 */ + { { 0x5ebc2c7cfe519f99L,0xe396bd80e5410353L,0xaded94028a3988f3L, + 0x1c03b735d601bda1L,0xfd30203614ce64acL,0x5837ebe901240290L, + 0xcaaea1a3a554097dL,0xdce73d25b0b88139L,0x35ed412becb090b9L, + 0x99029ff7d63dab3cL,0x555437d9062db071L,0x277d2f5642a4c11dL, + 0x477fa64524fc9109L,0x7b12e9b72799254dL,0x7ad2ae22d84c618cL, + 0x0a8d5663ce8ed195L }, + { 0x43ac51630a21fde1L,0xcfcf5dd66903d849L,0x6d2499ee5fdd6281L, + 0x4dedc6f077a49a34L,0x46bda2c02875c06fL,0xd0e0e0f6347b8046L, + 0x1058169b5e67836fL,0xc961912ade8a8042L,0xdf3fea0aa93b3d32L, + 0x9f138edb0c576bc5L,0x7971ad6ed8d37e47L,0xeab85739cce5e7cbL, + 0x88a4b4341d202b40L,0x5d842557e3a1fd26L,0x872fabd5b3a86f91L, + 0x95b934936aa4629fL } }, + /* 124 */ + { { 0x9998a70199f951deL,0x8fade596f058db45L,0x4d479c1ef3d03dd3L, + 0x6e928d5d33b141d3L,0x9a465800acfe8a40L,0xd108ad2fc1cefa3dL, + 0x64b96921e013726eL,0xb9b6a6b68e83bb9fL,0x29f1e6dc1242e544L, + 0xd3f8f6762f65966bL,0xa34dd0965e105b41L,0xd4e9139a16011e1cL, + 0xeea4dc682515541bL,0x6f8030acc822166dL,0xbdc7ae1d31d16124L, + 0x2e25ef51621afa7dL }, + { 0x2533cf8fdd8e7357L,0x333ba218eaceddb8L,0x68e3e31d0784d2acL, + 0x1c927f36f2804ae2L,0x01433d2277e7ad7eL,0x0b401cf0587f78a0L, + 0x9dfcf036aa0027aeL,0xc9e46c8b1d9a46b5L,0xaa6de4861f288d32L, + 0xdd56da2f1b8a043dL,0x346230e5f2d0bb56L,0x19f0b6e419defb56L, + 0x55ec37cd21d2c874L,0x3dbf0397b70e45b3L,0xf0862a8dac7ce852L, + 0x87979ea7e141f3d6L } }, + /* 125 */ + { { 0x9b7e7b3f7f1c747fL,0x151a4c1dc6e63369L,0x4273ff70b372dba0L, + 0xca6d2234d3ee54feL,0x12fc8e0cd33cae0fL,0x273285385dd6f10cL, + 0xc86f3fbdf01a9cf9L,0x5322677fe36cae91L,0x39a700332fefea44L, + 0x2c9ca328ce8af217L,0xc0256776f6a731f4L,0xc687b3df66a96813L, + 0x194aab128db2eda8L,0xde30dc5aeec4febdL,0xc052236a979241b2L, + 0x3ec98802c23d4c16L }, + { 0x0f9e760c4072f74dL,0xe78eb0deab594059L,0xdb3dea40c9b009c2L, + 0x47e875f038b59ae5L,0xf40eb4362b4daa06L,0x9a6a4f92090f3788L, + 0xefebe9afedbfaf8bL,0xf87f96a59867e256L,0x1e6fed2375ab6aebL, + 0x17f2782a3fdb13cbL,0x5102c71e70fa2621L,0x5d2b06ecfd4c0dbeL, + 0x537cc26830347297L,0x8dbf5e2b2b67e780L,0x2f633f3aba25da32L, + 0x3e9315e8efaec914L } }, + /* 126 */ + { { 0x9255cfa5239a9ea9L,0x20f3c6900be33a62L,0x759eeb4b9cb642bdL, + 0x3316c54600bae718L,0x874a76d5f3410f84L,0x123b502e90f129b6L, + 0xadc8f9a812851f1cL,0xf57b764a1b62408cL,0x116ec01f1a80777bL, + 0x746ecef21f0ddc5cL,0x3c49d47ce5a6a5a7L,0x1e15dbe706e955baL, + 0x629c0c79b45d79b0L,0x11278308778d1087L,0x22585dc78c6a22d7L, + 0x2ed02a0d0a682791L }, + { 0x530434164daa2682L,0x0e26d32b01359625L,0x449c834abd867097L, + 0x11a19d2bee77ae2eL,0x39bd529a3af6c169L,0x36cca5c05cd61054L, + 0x6370a59bdc6c0fe1L,0xca420d27b93d5135L,0xd8730d45554c451aL, + 0xebd258c996cdebf2L,0x0cb1b990a50f9a05L,0x69a8c97a7b0f0151L, + 0x2cc36d3411d217e1L,0xf117688a752f75e8L,0x1db01394a09b2a61L, + 0x14627844a9efd7ddL } }, + /* 127 */ + { { 0x6bca3aed232803cfL,0xc1e4398b9a96ff34L,0xcaf6757f74ab788bL, + 0xc3a53e007e68c04dL,0x5f969c195cb7cd20L,0xf28b65a6dc068bcaL, + 0xe3ca01d31d863032L,0x9b733b8187808e14L,0xb5d704d9efe618beL, + 0x276f3542b01b946dL,0xe057e19efbedddbfL,0x7d182f2b903275ceL, + 0x3cdc5f77880f7bc6L,0xd6f03d3f78476c14L,0x035f5557a9ba5072L, + 0x7acb57b6b4029628L }, + { 0xd241356944e6b07cL,0x451c4cc9e1c7345dL,0x407444d8e273b9fbL, + 0xfe496079b88e34fcL,0x77d184cff152776dL,0x6d1033b9c742299cL, + 0x29a0a68477bf2897L,0x59ffdf10ee8f0420L,0x4e17146c44bb56d6L, + 0x831d06c2fb9ae855L,0xb2cb82dbd93e7cd5L,0x83381c463c96b607L, + 0x06aed2517549e2a8L,0xef97891c774a21d4L,0xae9807c78675fbddL, + 0x6a5a05b96363516cL } }, + /* 128 */ + { { 0x92e71ea66a8f4f33L,0xf2fc6fc64dea8f4aL,0xd356252cfee88461L, + 0x59b0a83e08954d08L,0x5bd68c23468ab766L,0x40281357900f8d04L, + 0x181c19c052b867aeL,0x986a516918764c41L,0xcb01dfae13575d24L, + 0x17269ae5593677b7L,0xf6d1702546dc9b19L,0x8de68499c40097c8L, + 0x76df0032259c407bL,0x4091aad917d29d8bL,0xa7f46d214a7ab5f6L, + 0x688054b470ece48cL }, + { 0xf0d168aa51a5b86cL,0x2437e4d895777247L,0xae844076f1720329L, + 0x0a7ac87d9647a54eL,0x1e597a4b0405622cL,0xedefe5c6f0a79f2fL, + 0xaf3ef0c24d55156dL,0x917fb04eef047cf6L,0x3792799f54b62137L, + 0x875ea32f314be0b8L,0xe157c65b0c466b0cL,0xd28c90ce7e218978L, + 0xb90fc3bacde587afL,0xdd32d71c8b877bedL,0x3b432200ca8e10cdL, + 0x0021f419d94f6e53L } }, + /* 129 */ + { { 0x2191122c43519d26L,0xbdafac1d40a51845L,0xcc6f71e9548bb89fL, + 0x9ef3375c16844bf9L,0xe7789f79178e8d55L,0x04f599b61f8be1c5L, + 0x8088c99a2cbbde40L,0x8939a260893206c9L,0xa1ae4bfffcd30851L, + 0x664cb3fee08feafeL,0x61f38099ff14aabcL,0x0d8394cc2a841ef9L, + 0x75fad8ad17f01db6L,0x6fc345766debb773L,0x1e716b05a4252512L, + 0x7985588029e1ed9fL }, + { 0xa2cb3aaa95106473L,0x95fafa415a61da04L,0xfd3c9362539563c0L, + 0xbaa4809195312b87L,0x6c7e7582bf885c76L,0x70f6dab6230c78d5L, + 0x8ce3051c7747440dL,0x6dbebd14ffdb6186L,0xb0e041fa190e4096L, + 0xba10c4666ee62e2aL,0x93d57e2a74f333d6L,0x006aadc4fe7b9b66L, + 0xfaf72f6c06d2837dL,0x318cc5e6910741eaL,0x9c50260965692477L, + 0x95d823c31d0fb08dL } }, + /* 130 */ + { { 0x6aeebd86140528a5L,0xf268c2ba53979bc8L,0xb1bc9b8a4ec144abL, + 0x1efabb0d82a7d7edL,0xf12c70d14e0118d8L,0x31607168a1c1558eL, + 0x33e428b7e4b7e73eL,0x6317663783aec9ddL,0x5172ffbee12ac35cL, + 0x37df0bfbbc17b2a4L,0x4212f870741f812aL,0x3dcecbdbe2888f9cL, + 0xa9dc15aa756ca55dL,0xf31918ecb9028e41L,0x7ede02856aeadb03L, + 0x0e2708d578654f54L }, + { 0x2270cc53cde20f88L,0x9338272c5f5b1039L,0x5042e19e5dcb1dbfL, + 0x4b3de219b72d74c1L,0x16c49a8b2aaaaa55L,0x008443e5bba86ba6L, + 0xee6bcd7220cf1695L,0x59ffac6ba89abd11L,0x2831217bf115639dL, + 0xe4d28af2f34cba52L,0xf27f03e70727a906L,0x6842c79f69017766L, + 0xcb3469bd7a81123eL,0x48c0f346a42973b8L,0xfc5784a623990dbdL, + 0x0d3dab3bfb299678L } }, + /* 131 */ + { { 0x8f8376e6ce29c3ccL,0xcb0507ecf016cbc6L,0xdebff9965e394ce1L, + 0x24fc526f73c50d41L,0x4edd5a542d16ce3dL,0xbb37bdd991c13141L, + 0xe3442ef2e33a8606L,0x2ae90337c0629da8L,0x57faec64592ab331L, + 0x1a938997d82b857bL,0xad6c8cb9a3373176L,0x82595de29086751fL, + 0xa81e97fb18c17196L,0xe4f48a13bf697357L,0xa1387c2e5cb89f69L, + 0x530b4eeb5874b426L }, + { 0xe9f275a1bab7b5aeL,0xbb69dc4d03a57bf4L,0xc974dc4aa45c505bL, + 0x726369f3416ac402L,0x735e4e78aed985dcL,0x0548d879cdd446a1L, + 0x84ceb0699e16b02aL,0xf73f6fa4789b11a6L,0x6aa0c41fb2a4e784L, + 0xb1f7690293a9b697L,0x814cce00f03a8ab2L,0x64cb255b844d66c1L, + 0xb794e7d630952201L,0xe052d4e43da32271L,0x5278b2e708b6a4d9L, + 0x9094255280c6577fL } }, + /* 132 */ + { { 0xd269a14d0d5b4c2fL,0x2b8fc59b5c8a649cL,0x95becb3ab0e37d4aL, + 0xfda1a7689111037eL,0x5810e05a94e35322L,0xa24dcc12a178fafcL, + 0x5c2c63b28e3dce62L,0x995c3f179452c444L,0x35330ec342d45161L, + 0xa025a60ab4ef8129L,0x854932528bae9c13L,0x25d1a606e2e3caf8L, + 0xd44091ab3649bf47L,0xc7d0afbf704ec5f1L,0x27bd1d62bd8b3333L, + 0x50570111cfe616f5L }, + { 0xd0084acef534356bL,0x9df1de054b4b0fbcL,0x021afe05cee04dc1L, + 0x64bde688361b78e1L,0xa324fcc7ef78d38bL,0xfeb372ceeb0a5e4eL, + 0xef04fcb365811996L,0x7dce5d505eb0ab4eL,0x1e29b588238c586eL, + 0xde5e3197bcd80037L,0x8bf5e4514806b9cfL,0x4330968bd18e67abL, + 0x26a7d04ef9f63fadL,0xa1c7f123b5c18bb4L,0x485b848225dce22cL, + 0x8ff0b36fd540e79fL } }, + /* 133 */ + { { 0x99f2e2f43ff42cffL,0xa3c19f9d1c35317cL,0xdb749392aba1b545L, + 0x84232b054afa9a32L,0x0b855d46d7dcd436L,0x8ac35e2045cf9915L, + 0xd7cf22c7f001a218L,0x057d35aeed408305L,0x25a4a519553ccfcdL, + 0x5e56579393e2b939L,0xa20332b03422ec27L,0x9b09005e3ac53958L, + 0x628051a379e9b163L,0xb4a0dc09fc6618d6L,0x9e0e857f6748e7afL, + 0x71b28eeec577d63eL }, + { 0x4942b0cd99726bf8L,0x1290a3b91c208f3cL,0xfd7290e7b0598eaaL, + 0xc6a7791fa25a9128L,0x2d33db24c037d7daL,0xc21efeb070e2837bL, + 0xbf70d96ee3dae2a0L,0x43ed819185076027L,0x4aeb0aa84d4ad7e3L, + 0xbc75101fe8c5b74cL,0xdbfb2a6ead26ebddL,0xba8120686b78aa4eL, + 0xc94aa8f2e1159848L,0x0d10d9db3eba5c4eL,0xce7fec476318295aL, + 0x7294711a330d925aL } }, + /* 134 */ + { { 0xfce4590432bbd495L,0x330f4dd1be54973fL,0x006bee1d5d9c3f4eL, + 0x40ee607859ba7204L,0xc194fd3f42c2c768L,0xa0e76b12e9fe88beL, + 0x17cddddbec2b0210L,0x689d436b00811ec7L,0xa6a6ba37284be9e4L, + 0xabc395b2007d4114L,0xf8cdf9f30f11e744L,0xc5febec8e9396402L, + 0x8a751743eeb46285L,0x99bf8782c6e0d137L,0x3965e170beb292e3L, + 0x001c39d85801fd5fL }, + { 0xf4805cb9da4a0912L,0xd27cb76a4410bca4L,0xef3dcb8eec71d65bL, + 0x780fbb2b4816849aL,0xef6a7026a8b24635L,0x15625c8812c44e68L, + 0x624c232c4d7a74a8L,0x81a770374b1631e4L,0x04e4f7f1db917c2eL, + 0x1d0465fd1f61ed95L,0xb1048049cbde6e3dL,0x637ce0c1d7131fcfL, + 0x22e4dbc28ada4715L,0xf7530c5cace99726L,0xa0160dccee287450L, + 0x9132e670bb91af13L } }, + /* 135 */ + { { 0x8057efe27996099dL,0xb72344dba06e608cL,0xeb4a8740d0958588L, + 0xe53daf0679e5aee9L,0xc9560a9a908a2fadL,0x7f4be131107e706aL, + 0x6d5f3d9b2830246aL,0xa5f8e8da27cca3e6L,0xeb51dca64c28f292L, + 0x4cfa310ef31dfd78L,0x92e0c7c22ca073e5L,0x102f1694a40da683L, + 0x16bb07cc750d38fcL,0x703e83e2badae035L,0xea93c066b4d3c9ddL, + 0x7d0b03e579940ed1L }, + { 0x5fe7ea304dd94c63L,0x57ef01c5738b0b3aL,0x9534a78ca14e6b4bL, + 0x07622cdea5353276L,0xaf696a077c22d006L,0x733c18867d46b209L, + 0x9654ccbb626c2b4aL,0xa098d3a1a84f3c4cL,0x3596f9ed2d734b74L, + 0xdfd3021a5d551c90L,0xe2ba7d2f1ec5123fL,0xf9726925b2c1aa39L, + 0xd2e75d0ef8eb2927L,0xfaba712e19192a6fL,0xa606b43a9b83e50eL, + 0x31b1782fdab5de60L } }, + /* 136 */ + { { 0x878dba454034db92L,0xa39779018f34dc4dL,0x8d004f2edf754c33L, + 0xeaa5954acd563a88L,0xa29d6c89bb5ffad1L,0xa8adf655b0d8bdb8L, + 0xf7fb842d8cdbdb47L,0xb72e3a0380d3205bL,0xc335b0b27cac7ca9L, + 0xffc60bcbd8a5475dL,0x736f7719eba4d25fL,0x3d901c380c50fca6L, + 0x1fdacf7b80c01900L,0x75cf658f5681f84dL,0x57a7e6345cefbbc1L, + 0x6fc0fbe53e07ed1fL }, + { 0x496d116bb81b0e5fL,0xd82dd2a52ac853b8L,0x357e22d4327387f0L, + 0x3e332a84ba912c59L,0x8b71c64349d5dcc1L,0x0c982ee9438d85d3L, + 0x90b9553cbf7fcd4eL,0x2cb39bbc38fed5e3L,0xa2c67c9c5ac42903L, + 0xebf21217bf07da55L,0x55ac05ada0b9e4eeL,0x10bb12c28ee9e0c6L, + 0x5cf3aee548bb6e3fL,0x4ae7269c8b046e91L,0xcb266012aa0e553fL, + 0x701935a1a94c8fc8L } }, + /* 137 */ + { { 0xde58d41da4626deaL,0x25ef66ca15b9039fL,0x99a810a43164e65bL, + 0x9fe6daad748cfccfL,0x7ab9a6bd2f142fa9L,0xa4cba1685d471796L, + 0x12d30b366bc3a39bL,0x1f46a5dc8bf45076L,0xb868e5291421ac0eL, + 0x7a68620659bba1c4L,0x2b4b552eda698b90L,0x5039dcd4e5453707L, + 0x42a07a9e9e90165fL,0xa838fff3d7d45dfcL,0x41991e5a3b5ceb30L, + 0x6c961ec8969ca600L }, + { 0x703bdc1bc4e7eb46L,0xd6bac557596c7b48L,0x4f9917cd66afd74dL, + 0x56355105656ce6f3L,0x3d1fb50c32497175L,0xfda6783e63effb2dL, + 0xbd79f1f3eefaa2bdL,0xa4efbe5417af9ef7L,0x6cef64625a55b7a4L, + 0x116f32381a713304L,0xdb2a2a7fb95625a3L,0x6a0aa43a0b027e96L, + 0x458fe5d24832b3bcL,0x523418df5adfaac0L,0xc05a89cbc49e7f9aL, + 0x830883d869e24b53L } }, + /* 138 */ + { { 0x959b1c6202557389L,0x5fe5ce97adefc0bcL,0x893bbe7f8330f383L, + 0x27e0c6af16cfb81eL,0x6f64e65bd04428fdL,0x53de9245b79e6182L, + 0x08a313c1487e11caL,0x65cec3b9445bce93L,0x33bc0314d67ed49eL, + 0x69f36b2430782352L,0xd78e5daf93ad31d2L,0xf2682b70c780890cL, + 0x7015c34f9e45efe9L,0x135d4ba4e6cbafeaL,0x43a378a47e3fcc6cL, + 0x2376f97f96638f8cL }, + { 0x0a6e1ec0ae575b99L,0x7e14cb4f81b970dcL,0xf00a3824d3a73947L, + 0x0b4b9c81fb235a9dL,0x8d15115f5bf62944L,0xcfd35b431e165d7aL, + 0x5d12fea2b2ee3e3bL,0x629984a6f5182e7bL,0x4e43e2f3c365d08eL, + 0x9932709130f36e72L,0x698b4a00fd345401L,0x23c4fd0ebaf96dceL, + 0xa60ba0ae23675554L,0x51bdac2db0325784L,0x8ab4190a215464a1L, + 0x8c4616616bf10296L } }, + /* 139 */ + { { 0xeffca2582d1f36a5L,0x0eded2b2894c5f2dL,0x35a5cdb843ced84fL, + 0x290f8982db0e3b9bL,0xcce0eaf00719a112L,0xd0e657e439a362d6L, + 0x5516a55d62697e47L,0x269e1f778e636514L,0x5e3dedcbd50269bcL, + 0xecec2300441c57c5L,0xdb83f31cc705578dL,0x1bdefb731e489eabL, + 0x20b678cf395fcdb4L,0x908cf91cff9db001L,0xcbebc6f455f52cc8L, + 0x155ea622b4c61162L }, + { 0x94be2f1f876fa42eL,0xab5e87497fadeee7L,0x692e70f538c865afL, + 0x16e99b84df8059b0L,0x0ceb606e8b5a7ac9L,0xced233572d463d2bL, + 0x2d0f26232a9a09a0L,0x2529998c3861fbdfL,0x711888a7c1be310bL, + 0x9b1229c50d8aade3L,0xdbcf9b783b13533dL,0x3ca746f8ff029708L, + 0xa5a013a1da83ef88L,0x8e904d184ab28444L,0x2fe84b3dbcbd4abaL, + 0x8f570f24259058c3L } }, + /* 140 */ + { { 0xdeb66c8a2ca9c508L,0x2dc5bec269d6b780L,0x16d6126688ead600L, + 0x61841b9749d72614L,0x41e40e6cce472e6fL,0xada242641fa7a876L, + 0x45b9fd33cc3997a0L,0xb25e8fa97c15dcf4L,0x0124ceb212e9629dL, + 0x3a8c72c67db3d956L,0x8e2ded2b7c1a7844L,0x94ab09c66dd027ffL, + 0xf89a057d7e7a2bc6L,0xad8bf226cf70c763L,0x4cb268e7c8a26212L, + 0x3d171e87b2c44c1dL }, + { 0x382ac16e8ce49820L,0x24ee45e2c0c44dc9L,0x0ec6791273e858c4L, + 0x918cb25c46327cf9L,0x43e3876bc6159c1fL,0xb6b6e0e037545cb3L, + 0x64b839ab5d12347eL,0x72e09274a300d541L,0x26ab28e6881c1169L, + 0x4a580fffeb75a843L,0x0a5802ca359120dfL,0x7fee82d03209f4a3L, + 0xb518016b8e6a9380L,0xb99c6c70c2ee11caL,0x16105af1ab9d4ec7L, + 0x234e98f834cd9004L } }, + /* 141 */ + { { 0xff43520814db9cdaL,0x99cfdc4796adec90L,0x843aaa6faf458b6dL, + 0x3f1f7415743eaa31L,0x915e192e61735d81L,0x3441a22d0ac595d5L, + 0x704bbf67c044bc8dL,0x2f960471be23a236L,0xcc32638815d1d557L, + 0x9410230b76b1dd94L,0xf2e5439f0c1c8a67L,0x56b141ac833c910dL, + 0x467c999f865b84dfL,0x1b0251fa21f02b7bL,0xde5b526096216950L, + 0x6a2130e3ce3a1e93L }, + { 0xd21b67a04b3ca1a7L,0xaf42ed5300c0ce80L,0x22ccd368932cf07aL, + 0x36523a815c25c35aL,0xecdd39588dd04d06L,0x73da3502b2f93a3bL, + 0x4c5e0c3cd5e5b530L,0xef9f548613268777L,0xed87fefc1e742292L, + 0x6d9ac29ea24e5edeL,0x08abc9f033849f1aL,0xb09b229240f23905L, + 0x6791072c7f934353L,0x102a6381e6aeb550L,0x3ee0740996feb870L, + 0x34f06faa9c4d2830L } }, + /* 142 */ + { { 0x869dc79f2348f005L,0x9b5c5d71df4920b1L,0xfd1b57ca6dee64a4L, + 0x21b7f734e82a4fb4L,0x637cb834b9578366L,0xc934101b7d287d96L, + 0x1590f8ac0392ecabL,0x280dc3737f75f4e3L,0x8b36f50f6a61ac62L, + 0x74f58304a65568daL,0x80d792a9d930870aL,0x6d17b192fc8895ccL, + 0x498392fa4914939fL,0xaf36027dd41d5b9eL,0x452d79e25caa82b5L, + 0x764d47b1f4115d1aL }, + { 0x5df22303a2ee8b9cL,0x1b9f72d385dfcd48L,0x6b42b98310813a37L, + 0xe28c523b3de741f5L,0x0857625af303bb5bL,0x926f299aac9bf9afL, + 0x21beac080d445b34L,0x6a523a02d6ba2c0eL,0xe302a1b17fce2864L, + 0x4516a235e300c1eaL,0x4543736a7b4a9311L,0xd3c0b9e8c0cc89f7L, + 0x0481904f40ed88deL,0x4f269b563cb7fc70L,0x09a1d53a321b9738L, + 0x1c0dd9c3230a3810L } }, + /* 143 */ + { { 0xffaa1f67c46a7d9aL,0x64743334bedf91ccL,0x45833a7447a42f2eL, + 0x67980051241ffaa9L,0x70979a84335efe6bL,0x5f0613f5f08b2403L, + 0x6bb22fcd64f211dcL,0xe1b8b2a3a0572cfcL,0x19e0eb417950a14aL, + 0xe634bb293eb6cd4cL,0x31a04b25470a25ffL,0xa41f7ac9a3d15a0aL, + 0xefed85ecbf2fede9L,0x1f581f5f81b94a00L,0xaa3996b09ef4a15cL, + 0x52d8be39b06041bcL }, + { 0xbd1536f6fd631a2fL,0x91fae7f0b351a8dcL,0xd1a590c79b126212L, + 0x52d4875f2bd0f435L,0x9aedb6d392b0ea70L,0x0bd0abdcb83ab89eL, + 0x827a106289fe192cL,0x6566a960102a0bdaL,0xda083037ce036814L, + 0x30bed79f58639405L,0x972019b6dbca8df9L,0x89201286efdaa3f5L, + 0xb337b9965236b892L,0x11d3e38e28fc2e73L,0x70787f41880e8da3L, + 0x6cff6367dae4a45dL } }, + /* 144 */ + { { 0xbd3d0433f89a8bb4L,0x42144c3393b98f71L,0x82b616c803470a2dL, + 0x98fcc757e5da089eL,0x542354ef7bf5fda6L,0x1885c2539ebd34ccL, + 0x2e20b285bec5dd0dL,0xe71bbbe1782a1bcaL,0x959ded309b854ef0L, + 0x172499798997fa6aL,0x50cf8fa8d81f3c45L,0xa9a3b51760c11152L, + 0xc9b0ef7decf845eaL,0xc9339e23b9fed11bL,0xc93e9c5c28256080L, + 0x1d2c8217613ec1e7L }, + { 0x7381347d987cfc93L,0x047603bbf187f810L,0x3fa6bc9d1250ca31L, + 0x480091e0bb055bf3L,0xbdf95f1a3a3af87cL,0xe2687770140540abL, + 0x998df730d7fe045bL,0xb398135fb723bc2dL,0xac230f8c15ebec46L, + 0xe08e18305f5561c0L,0x7c0fbf4cda60a47fL,0x06e95c24e16d4bfcL, + 0x7416349574617e92L,0x397198694ae0c20eL,0xfe2693122131e2b6L, + 0x25486e360a537722L } }, + /* 145 */ + { { 0x618795ca53572806L,0xb2c89449656968e1L,0x149c2c973fb323aeL, + 0xfb15de26409bc7d6L,0xa90cda72c79121b3L,0x6d2fa14e204cabbbL, + 0xcbcda6f791604125L,0x25086261b435f947L,0xdb686c38c282eb10L, + 0x51016d62f1a791cbL,0x6b1c7ed161a2266cL,0x26780666271d74a6L, + 0xb5ffeda1824287a4L,0xcbe503ffbbe4f0f3L,0xd7f7f0beb9482a74L, + 0x751b2358088493f1L }, + { 0xd597b9d6e9c9be68L,0x1794b5c467d10c6cL,0xa88cdc3d7762b2f4L, + 0x6d94a63aa1b44e11L,0xfb0bbbb9aaa8eca8L,0xf4b0f2d0c963d87fL, + 0xb753062c5dc7075dL,0xfed726ac49933989L,0x5da6063857f9ccdeL, + 0x221c392a75f8c766L,0xcd264d955dc672caL,0x7004ff22b66ecc8dL, + 0xfb1aa9ae18a458baL,0xea9644df8babd653L,0xa9378e802ba0de7cL, + 0x144cc12dca2c6c75L } }, + /* 146 */ + { { 0x593a0a1d2989aa3aL,0xd83f228359e6e64dL,0xe938b0cbd32e732eL, + 0xf4c464c53c3cb249L,0x9750a5f8f89ea6acL,0x467e5bbf346cfc32L, + 0xc9bfab9d37b2b809L,0xf8eb74533b339c6dL,0x3fe01fbe3b766deeL, + 0xb3154254ef6aea27L,0x555c3df27be61b10L,0x70fb6d81dd818488L, + 0xda1af3a4bbe714f9L,0x575f20179d18f693L,0xdc08fc6b2465b839L, + 0x874ecf336b84a951L }, + { 0x624af83ebbb3f6beL,0xf578fbb908bb423dL,0x5623b0bad7873527L, + 0xc3659bd8a62e0442L,0x2903b167fe236f79L,0x55a430c6e53f26a6L, + 0x222547ae3ad712cfL,0xb73890d776eb272bL,0x95b4f70b3d628df9L, + 0x9f0e13b053eae4acL,0x5b4f5138e7f2174eL,0x75482cf998dbae17L, + 0x2b69bbde44518480L,0x4f279652cafef15cL,0xa0a3ef2bb6bcaf19L, + 0x31fb8581ce4c634fL } }, + /* 147 */ + { { 0x398306d1615cd607L,0x680c9faaaa32c3a6L,0xe87a705b7779131dL, + 0x1031013a36708b00L,0x814fa0e19445297fL,0x70c5583aa6a79b56L, + 0x03039cbf4b16bed4L,0x18a7ca8daaaaf8d3L,0xf33159e75cdb68a5L, + 0xdea0e738d23814faL,0xeb3527188d0f4f9fL,0xb0b76609dcdff032L, + 0x65ba8ea93d48338bL,0x18044d8255dd507aL,0x844a223e4a4a50b4L, + 0x9832300018e19e54L }, + { 0x28a2102757f3d5a6L,0xffce56486e8cadcdL,0x9590381b02551f3bL, + 0xb26cc64f935ebdf1L,0x60611291c083aa6eL,0xcd988a6688e4cf41L, + 0x581c3f73dd53b1b5L,0x78c804a977fc621dL,0x31874330fadca2faL, + 0xf7008da4c83ccf02L,0xc4122a1da79a4707L,0x9a8e0d3f4a915eb5L, + 0xa2de157dd0123660L,0x45ef43b265ead2a0L,0xd0a22ade188db285L, + 0x8abbe39e922e0caaL } }, + /* 148 */ + { { 0xb44469053a2d2f01L,0xd27c31935dc6685cL,0x6a908bbf1d74a027L, + 0x01da350f5b50ec1dL,0x1d3dd45e3f3c2e26L,0xf66e11d0b836ee92L, + 0x7e03908f474b979cL,0x19e7c5b998b87834L,0xa741d3febd3d1de9L, + 0x63c68e8d1ef6059bL,0x9b9ff9393674e247L,0x1d7d53e73e7e67f6L, + 0x698dc326aee9e248L,0x52f23edab3bd984cL,0xf95e31b06f8fe8a7L, + 0x0f15b4d0c3d0ba95L }, + { 0x8f2f6635790a8d85L,0x51bffbaee2595af1L,0xd15b7ec624b51287L, + 0x7639b6ab3234715dL,0x0cdd52992bc5441dL,0x54800ea4f6d05833L, + 0x21efd752f6d6e360L,0xc0b7ffe519290613L,0xb68a5825eea898cdL, + 0xecedba9222982266L,0x678a91b0bbd06bb2L,0xb2436dc04bb6b0cbL, + 0xcf7a99e7caf8ea98L,0xb92d0e6e71aa05bbL,0xbf8d0471f5993eb1L, + 0x515db37820385ddbL } }, + /* 149 */ + { { 0xee43eaaa6f5bef22L,0x952d269820348712L,0x1e4c484e7a3af6c6L, + 0x18d434c69a8c9403L,0x63e5d7415001899aL,0x5238dbbcfe8ea40cL, + 0xca6cc8d296798721L,0x73db6aee04acbde8L,0xbf69328db7f993ceL, + 0xa3f79bbfad45e334L,0x8c51ec937c1f1630L,0x4907325f9b00a6deL, + 0x49e6acb412d82bc3L,0x5901b36d0ec59fc9L,0xcb09b7109cf34e3bL, + 0x2de0487e1abf4c02L }, + { 0x18b722f38dd9d484L,0x833493937c77baccL,0x58dbb8f193d92b8aL, + 0x80d78d508e3fac25L,0xf0500981745f4a7dL,0xd072bfed877cc29dL, + 0x67abf8f2c30a89f8L,0x92c567ea9a0820d7L,0x425ab12e8a3a5738L, + 0xc162faebf055521bL,0xee1c4f26b94ea5e9L,0x1e4149943d71e546L, + 0x258183b843e8be1dL,0x44917c82ef9eae0bL,0x6813a45773874a30L, + 0x6f6ac071cc42f86eL } }, + /* 150 */ + { { 0xd38822ad4dd6e3b1L,0xfc78e1ccad620869L,0xe78438452cacde80L, + 0x121cc14aa8469fe3L,0x8e8f3da7e67e8ef2L,0xdb83d16e4d347448L, + 0x3ba1dd98798631f4L,0xdfab59770a4c4c17L,0x1f0a13063edc701fL, + 0x4649d6016cd8ff28L,0x2267230bbcc55bc9L,0x02a19c605760412aL, + 0xc719d5f1328faef6L,0x27cb969ef67eaad9L,0xf342530e719bafb5L, + 0x6e2c24ccff5a82cbL }, + { 0x6313024badaf8793L,0x944bccf1035c948eL,0xe9a066b7953500bfL, + 0x7991a9461d116765L,0x95addb2e9fd93c78L,0x05d2c037e92e5495L, + 0xcb145b189f03e5cfL,0x81ae48ca95aa1f72L,0x203f2702135a6e4fL, + 0x2bcef5a249b2a7d5L,0x0687a90002d7f2a3L,0x2f7d32286c6745b0L, + 0x3da8a87586507305L,0xbe38b8842e8dc58fL,0x6b48bf34dbf11185L, + 0x5af7fd0d97c08f91L } }, + /* 151 */ + { { 0x55f9b950f4a224a5L,0x41904574cc50273aL,0x34f81330643f1fd5L, + 0x996801bb0e50f783L,0x866d740389581712L,0xdb9a405da4091d36L, + 0xf1e379df16a46fe7L,0x8d04a93f83bf9168L,0xae4c833532b20bcaL, + 0x99d334b1f72a1c10L,0x8fbc9977d8195db4L,0xcaeb3dfffba14b5dL, + 0x60fef02276daf476L,0x4b948dfedb5b72f4L,0x5185c925b6dfb062L, + 0x27a9c3819609d4aeL }, + { 0x73c37346f12a93afL,0x028b707c5536634dL,0x8efa58d5498193d1L, + 0x4f83a5ccef21b69dL,0x05cbb0a3a788a0e2L,0x0103178165b13c98L, + 0xfea20e582b73784cL,0xdf9713a0e50361f2L,0x31449a0fd0cc22d9L, + 0x183752e77c5e2e1bL,0x6e44d6bdb67044cfL,0x012dde95733e177aL, + 0x68b4966908ee2c23L,0xd9bb05411f5f1949L,0x95182c716acd886fL, + 0x1c690694fbde9244L } }, + /* 152 */ + { { 0x5db67d173a880026L,0x89c4f0a0125d95f2L,0x290505513f6cb7a4L, + 0x3eb231d15cbbdca5L,0xf8cffc99972bcbd3L,0xcb4ef4d4ad55a03aL, + 0x944d47ca22867c2fL,0x96d885480ead1aa5L,0x76a57cf8cbc8b045L, + 0xdfe5844b005e55a0L,0x5e9e7e191d18a097L,0x957a26e852923c74L, + 0xd0867b797f5db339L,0x2553408e63bed0c8L,0x1596e5d5689ad23cL, + 0x7b8c13d6a504c339L }, + { 0x2fc43aad52fb6901L,0x1c0313f916ca253bL,0x1475830a515aadc6L, + 0xc93d19267f577dc2L,0x26e52e8ef723c0ddL,0x2f1e0eb83eb9f6daL, + 0x9979de82f180376dL,0x43e28ecbb0834939L,0x9a2d51dca39c38e7L, + 0x6e6063a9a8e3f6b5L,0x4cf1da3a4b9b3270L,0x6e5348a2d2f8915dL, + 0x5e75e3e050507912L,0xaeffce5720d383faL,0x1d6d53cc8fd2fb29L, + 0x0e3c3ef6696f4cd0L } }, + /* 153 */ + { { 0x3bc337c121ee1d83L,0x97e08f6d787b7788L,0xbf709fcc138fa4ceL, + 0xbaf77647a0348e58L,0x04f8babca55e672dL,0x0ed2919d7d5ec5ddL, + 0x8ce64bff33e99218L,0xac09fc5724b059afL,0x506831f9dc5e32baL, + 0x26a22677465af6a9L,0x3c5efe66c97f1ff8L,0x1515e0d6bc6087fdL, + 0xb1a39c5eaa8edc6bL,0x3dd816bb0e79ed29L,0x6cc13769bc3788b8L, + 0x463098e3c092a51cL }, + { 0x3a6408c7c8bd0fa7L,0xd1764311ce6bde49L,0xe315e108283ef7beL, + 0x8213cc7799b5d938L,0xaf7f158145a49a6bL,0xd00fdb0fe529e4d1L, + 0x55d38f77ce66c9d6L,0xb4f7ccc01bd4b952L,0x8d975b49af71f986L, + 0x12b59fcbcd64d00aL,0x1860e504a5a3bad7L,0x6d9760442b5c89f1L, + 0xfed0c6597a3e231fL,0x58114c33178cba92L,0xe2e74c066698e11eL, + 0x7f8fd093a348b85aL } }, + /* 154 */ + { { 0xf24592cac19428afL,0x192a1c813a308665L,0x42589812e30bbd7fL, + 0x10db0723836c6bb9L,0x9c7a41e9598e4987L,0x8aff179e6ead6f4bL, + 0x70f8f9b975862c44L,0x6b3b02376f21983eL,0x25d83e9b98e65152L, + 0x3b2d26a8d751218aL,0x9508281a9d6f1da6L,0x8df78d05a5a81f74L, + 0xd79ee559e4687471L,0x2060ca576787d8ccL,0x427a84ffa8476c95L, + 0x87b64c51e6435131L }, + { 0x87f46f654b30d3c4L,0xcdec4c5c23b4ef14L,0xb3b7476663ca4d68L, + 0x1df34269cf3fb56dL,0xd4f139c40fd7d46aL,0xa3b7c7c76a69a8bdL, + 0xee56b4c9cbadd7d2L,0xb28ff342ac942334L,0x0046fdfa786f1da3L, + 0xce5d149cb700c82eL,0xca30ef8150966597L,0x44a20609fcff4bddL, + 0x0f2f65e744925268L,0xe5b6552cd4021f38L,0x77ea9c2a042dbbd0L, + 0x8c95267cd9c062f5L } }, + /* 155 */ + { { 0x6655032e5fc1abb1L,0x2215af5412fe4743L,0xfd65756029f05ef5L, + 0xb0e73325dc191be9L,0x7ab3c65ec08639b0L,0x67507f511c3e6673L, + 0x638befc3c8615555L,0x5d0188cf42f0c4adL,0x843a301cd896186dL, + 0x045603f7b2c6741eL,0xf7545c0cfa3cd1d0L,0xf612affd4a40672eL, + 0x56197c9f45b9e8ddL,0xb453237d87922d74L,0xbf132e3a4b2d59bfL, + 0x8afa1b73b84a6a16L }, + { 0x6b3596eae793ac70L,0x4c94ef8eeef6dd10L,0x926b4fa270422e40L, + 0xc8c71dcee9e5d763L,0x352fcb70f512aadfL,0x1b7ba138a883975fL, + 0x57991390058c3b13L,0x9692092a97740fd1L,0x19ad945b160b0697L, + 0xbc63438810837ab2L,0x76ee11c4f174bb71L,0x6111bfc1ab1b80ebL, + 0xbc82bac870ec458aL,0xeee60127312d3325L,0xb4118b1ab240adc8L, + 0x672111912b5a093cL } }, + /* 156 */ + { { 0x91e99306f55cf9bfL,0x9b045308a46b96d9L,0xae3c1e1d9e7a65dfL, + 0x453cb151c731bcbbL,0x14be5227a4d58a61L,0x39dac92297c74cc2L, + 0x4d0f7a45822e00d6L,0xafeb1d51c62b03dfL,0xbb1dc3a4baa18b2dL, + 0x7f3c7178df2b74f0L,0xfcd328a6896b6a33L,0xe95ed4541dce055fL, + 0x97fbc76b6a4e2b87L,0xe5ec67f1fa59dce9L,0x052368accc0367c1L, + 0x7c86391654e4a3feL }, + { 0x55e94b5eca7388cfL,0x17cc0a60c0335d38L,0x9b69b78b616f85baL, + 0x705d02ef10122980L,0x565a6e801cfd0a79L,0xeb74a96d7d1ee352L, + 0x5c8832ed427b9dadL,0x96ea8528e6d5330fL,0x30d8862b18d24ee8L, + 0x9cd38ed59ff939f7L,0x690fc9a201060252L,0xc62d88b82303b3ffL, + 0xfc42d7a4dd52b469L,0x06f8dfa28cad2d93L,0x5023609060920438L, + 0x32582758fce855adL } }, + /* 157 */ + { { 0xeb20e45f359e8c60L,0xc71bb8a5364ca186L,0x02b15071dff8e110L, + 0x074e91d34c93e578L,0xc0326e00b829d0d8L,0x3c192258626a83faL, + 0x387a64d5fb29a09eL,0xcaaa3d34e5ac5c82L,0x8ed685e5ada2da29L, + 0x92720267eb29650eL,0xf7184b19763802f3L,0x23f5dd0edf6b1aeaL, + 0xbe1fa34725e6125dL,0xd6287f9d0c872a1aL,0x49aa93d2ac57c3afL, + 0x1a4e6a715bda7656L }, + { 0x1a126ede554d1267L,0x37f945331cd02b48L,0xd70af04cce31fb1dL, + 0xcf410b0b097dc012L,0x930e1d1736c7b6c5L,0x902fee41c6891085L, + 0x349ba4a779fb638fL,0xa16c5821acd6f8dfL,0xfb3b83c12e076aceL, + 0x6b8d033be501d14dL,0x0593d45220f2d2daL,0x3752526d99df1880L, + 0xca32351c9feb33a6L,0xd91343bc1f6ef456L,0xc74857db35b9dc8aL, + 0x856a7c9385b4e832L } }, + /* 158 */ + { { 0xa007d0020d0a5583L,0x2f1301ddeda4658aL,0x91c0796434d939beL, + 0xa0cb6780a70c0836L,0xc0b4df95be81e540L,0x6cbbcd345d4ac8b8L, + 0x57c52ed054756239L,0xcac2dca41805ceb6L,0x915ee6ab79344255L, + 0x366def3124c9a2a6L,0xbd3b962f8c12c674L,0xaab64f1b7dbb7c3bL, + 0x3c0e4553e22bb95bL,0x2408febac4c63b74L,0x3ca773122a4da631L, + 0x62889084c636da40L }, + { 0xa457fd538cb8d208L,0x7a8f8009543f06d4L,0xb66de154f2eff2abL, + 0xfddb28ebf72517e7L,0x0149fe66f9389d2cL,0x79e8773fd85b88ceL, + 0x452e090b0ba543f7L,0xdeb9b5cfb0b03fc0L,0x3113448a6c5ed77bL, + 0x3609f3cf8ffc0372L,0x2bc9c46d5c1b4c4aL,0xe66f3bf38fa59be9L, + 0x1396bf5fcdb02691L,0xf1ec59d4009f88f9L,0xc29034562ad9dfe3L, + 0x79d8122c5ada4d58L } }, + /* 159 */ + { { 0x14d4e4ceaa529507L,0x056a081474655d00L,0xc0d30a384f0fc474L, + 0x8a8203ea3443cb8eL,0x33c62fb097f1728dL,0x8a38dcfdb520ef52L, + 0xa0f90d5d7cac9d3eL,0x28a7b0bf873cea50L,0xd115ae3a6c6c41cbL, + 0xa35171daa13812c1L,0x25d4bba5624d507eL,0x91dad2897e98f42fL, + 0xffd6b1e996a41371L,0xd46c2125b69e5b77L,0xc7d2b42420c4f707L, + 0x2ab3af958142557aL }, + { 0x86ca074c6a5372a6L,0x728fb83e56292ba7L,0x745596dc77741cf5L, + 0x70b4cea1520ef49dL,0x1472fe3461e46472L,0xf4d6bd663fb8ac5dL, + 0x46e52cc9c10bc071L,0x28794efe371a3461L,0xa4850718276fe877L, + 0xedad57739bef5ab4L,0x24c2d9ff3f15c815L,0x188950e58f8395c3L, + 0xbae4099680b6a855L,0x4f53e22c8a8803e1L,0xaf233f61039d25eeL, + 0x07db2c35250409caL } }, + /* 160 */ + { { 0xc7f3b8db037d4703L,0xe83708dfc5f488b9L,0x1fba830f8471d402L, + 0xa55ee8d25a2faae9L,0xc2e5bf105404fc1eL,0x647d5027aa2d5651L, + 0x37a53c0c7ebaf5f9L,0x7adf0bb295b30abfL,0x5a62e1fed64c93baL, + 0x7ffc18c0e2ef4a78L,0x139dd9d94d2cd04fL,0x253fbab75ea0af02L, + 0x7c8100ea0fef9acfL,0x74c5384dc8615aa7L,0xcb28682d9fe52069L, + 0x08b6ca8fcf7dd759L }, + { 0xe04e5bea036c3b5aL,0x387261027f9f2b4bL,0xa9fca57029797c0fL, + 0x1656180b82879ea3L,0x153389bb607f0ddfL,0x99a1223c67b0e087L, + 0x0d1808ec9d897fc7L,0x9470711a916edf19L,0xf8f52f2b07217118L, + 0x5d8b29ffd18888b6L,0xef1e22c54cc6f900L,0xc4036165eb24877fL, + 0xfda9523335479525L,0xd622a4216861468aL,0x5d043b0774faba08L, + 0x2c337b020d31a7d2L } }, + /* 161 */ + { { 0x7b2305bcea22fa65L,0xbe183ef4d159f63aL,0x3473d87d3f35923fL, + 0xb27fb306c11d7753L,0x702e7e6b2a054cffL,0x3ce9f97caf185619L, + 0x835502434e7d51c5L,0xa63e3d82f356ac5bL,0x867b7caad7645131L, + 0xee85e6afa671fc9dL,0x3b985ede2b07cd77L,0x07d598b0ffda5193L, + 0xb10eca39a942dc36L,0x17f3dcee506218a9L,0x3d94e8d106b7d5caL, + 0x509b2634ed8831c9L }, + { 0xb1b9414e48caed54L,0x77a78c6ccbf51e97L,0xa4688c8d4de9b258L, + 0x0024137c91ee3d78L,0xa68f9234e30ee64cL,0x573255bc88190d78L, + 0x41e8e05fba80690bL,0x50038d84ec354f4cL,0xb18f02d6dfa52816L, + 0xc47f9007ccb63fdaL,0x29d480fbe98ae455L,0x4ac45d225d0e319dL, + 0xd06f3575026db719L,0x733b9e202c3587b9L,0x224839922c317727L, + 0x1592d5a754bb8752L } }, + /* 162 */ + { { 0x5778d9a2cf7453f0L,0xaffb899aed83c1f0L,0xae6506d3e0a82ba7L, + 0x32c84e1aea3d5081L,0x9ad528c0810aa38bL,0xb1fdb020bd37d041L, + 0x78d6cbe1d06ce41fL,0xd287f0f02e74b7f6L,0xf5cd2575c43bb022L, + 0x6d28f2f3f81a71b3L,0xe65bb1f5c633e7f4L,0x32e5fc1cc4fc580eL, + 0xcd55539fbb7b07a5L,0xb5a94471c3caaf3aL,0xb958bdf44cc22d2dL, + 0x1614bdbd77a2777cL }, + { 0x4c1f0230ed0ab04dL,0xae347b006e2082eaL,0x9f10bc63c42c5b5fL, + 0xb0539e6fde019935L,0xd89bd4e765dd0825L,0x92260fefbbceda16L, + 0x8aaa755ce62aca32L,0xed762fa95ec82c5fL,0x99e64c0118650768L, + 0x57dd6245c92e348cL,0x0db88a7731ea6d68L,0xef0012ab07b44736L, + 0xb9356b94171d70feL,0xe68b062803f891b0L,0x3a54a53ab79c20a2L, + 0x489656c7b00b0728L } }, + /* 163 */ + { { 0xe43649ba71353c25L,0x517f27a113f67e24L,0x10bd333a1c1eb9e3L, + 0x94e1c05c78e29bf9L,0x84fe7d974743f15dL,0x9c87490890da2df0L, + 0x82403fa753673be1L,0x7ebf5db41baea1b1L,0xcfe0ae3524180eadL, + 0x1d15873fc2f50c3fL,0x16851ad670661cd9L,0x802968d9a51e8c2cL, + 0xe7d1a9cde0161099L,0x2b153c89a8a7ea56L,0x6d41b78906e3c498L, + 0x082bb2e9d6769dcbL }, + { 0x6180ef46c4d6615fL,0xfc629dc101b9829cL,0xde222ec00fb264caL, + 0xc5457e0610ecc2c4L,0x95ce599f1eea2c4dL,0x0433fa728f9c5b2cL, + 0xee035462cd6310f9L,0x84c57c3bce2e2253L,0x6c8ec31a96d87e44L, + 0x30bfe393a452c5a7L,0xc592b140a047b235L,0x7bd8be18c018545eL, + 0x794e01075c178c46L,0x484719462e23005bL,0x2665e237622a54f3L, + 0x36451a46901c9042L } }, + /* 164 */ + { { 0x17802d1819893e71L,0xa1765d8b539a2082L,0xfc6aea012302ecfcL, + 0x8d4cf51b365bf59dL,0x87741d720d232a80L,0xac343eb318e80427L, + 0x553ecb2fe74739ecL,0xaeca79a81a8b07caL,0x089ff32256f4ab3aL, + 0x5e95d7293fa1d1f7L,0x260569aef62a9a16L,0x5e776232aa08ddc2L, + 0x93fabec31b7bb54aL,0x48a20956743d56e7L,0x749cdb12eb0ebeffL, + 0x705307a469b8fcf1L }, + { 0x7a8e4c04e488310bL,0x12726e325325cd7bL,0x5d0fd8b04983efacL, + 0x796e552c02ddb913L,0x0eeca3f777b9685cL,0x9b766e89b15f24a3L, + 0x7c2736d648efc979L,0x3d619685a8021c6cL,0xfe33e278a0b2f1eaL, + 0x95c69879b676d6b0L,0xa07473191af4e0beL,0xa2fab5f136c4ee55L, + 0x6938b8ff59e5f3b9L,0x1e114da439cafe6eL,0xc9595ec36a6ad120L, + 0x80f79bd057e62aecL } }, + /* 165 */ + { { 0x3cef42a760af09b3L,0x3c016ebd933dfe14L,0x720cf1e0ed85eaa8L, + 0xd4f5e99fceaa3bc9L,0x7216b9d2b7106f97L,0x65f34c36c9668ad2L, + 0xa8fb82bc5b0c651fL,0x20f42f1cf2fda4deL,0xeb31ab2cd21f659eL, + 0xb7a776c7a13d1618L,0xec44102238662be5L,0xc825da70cad08e0bL, + 0x99299079022c0180L,0x7623bda02aef9ffdL,0xde84f4f3f5c58b50L, + 0x5f5a5da4d824ff19L }, + { 0x5737257e7e8311dcL,0xdef94f51466cf136L,0xa73e1645b05ca21aL, + 0x38ea9b3c02e4ab37L,0x7760eac98579165bL,0xdffdd047c24b01a4L, + 0x188d4fd13fb95584L,0xfaac38b825548bdaL,0x1a79a6f059e9dcacL, + 0x983f720f09a2700fL,0x8cbba554fb8a7e48L,0x38a1996847a1fad5L, + 0x118565475abd6b5eL,0x75113d31f3716ec2L,0x1391e7814212907bL, + 0x5319c8010dc15889L } }, + /* 166 */ + { { 0x2320136e6b61c3afL,0x1d40f2de07b4bb68L,0x651dee7f380c97f0L, + 0xa978ba706a8c313aL,0x22c587d62011ca10L,0x48bba218ab1f445bL, + 0x8c5eaf07e50444e6L,0x5549f02a442fccf9L,0x2564746f3d80493dL, + 0x42d24f6179c04591L,0x1600fa18abdc8887L,0x5cb8600aded38f8fL, + 0xa4bf9b90923aeb46L,0xd63fee351e1c578aL,0xf3c9c5acebb9ea14L, + 0x3d13314df11a4ff0L }, + { 0xe5cc662db4513d1eL,0xde78a8c5d55952bdL,0xe8a37a3fe7f86d0aL, + 0xca2d12a47a04f0c5L,0x4c6696e42e25d06cL,0x52614698b2136071L, + 0xf4d2701b89f6e1cbL,0xaafd617780efd95eL,0xe6d73ac4c5bb6907L, + 0x49e874ac420db35aL,0x11631de4f2751fa0L,0xb29f7336a1fa2eddL, + 0x4c406864b7fd794dL,0x73cb21d3e22f92a6L,0xeae904e62043cc76L, + 0x67f28a9fb322c6adL } }, + /* 167 */ + { { 0x7c17b258ca148ab5L,0xb9a1976fb3c60051L,0xea260698c8f28df9L, + 0x87b2cc74e8d45017L,0x372573290578a422L,0x81d5ee2517bec732L, + 0xd7411fcf1d48bbc4L,0x46217e6b487f5cfeL,0xcb007ac541eb8e1bL, + 0xc41c57a6e05a00c8L,0x1f954d2bd2f9fa99L,0x370bd5db40941cadL, + 0xe487879c3829509dL,0x4c1375525ceca5eeL,0xe8ef7fa4fd3efb9eL, + 0x5ff091741bd1bdb2L }, + { 0x791912a4579c6632L,0xbb19a44fb8a20815L,0xf4f97b84535639d3L, + 0xe57e2bcbbc3c9bceL,0x122b3f2bf19e6410L,0x1f0189da1357d9adL, + 0x675573bb79e5ff66L,0x444e5c98ef2f3c4cL,0xd6f61e2004d10731L, + 0x0dfa366fac75d635L,0x9fc47c862c854f23L,0xc04ae43e0ad0850bL, + 0x5ce94f642f720c32L,0x67efae65a753bc9dL,0xc27d30d3b0373a63L, + 0x6681013a29721646L } }, + /* 168 */ + { { 0x1385d913e84509dfL,0xe978beddcf339376L,0x2df425d33423a148L, + 0x43fa0ae3ee8cb579L,0xf015369d31c4553cL,0x05cf08bbdfbf1d48L, + 0xadff4be69444244aL,0x01635f81a35dda33L,0x085c8949e76fab7cL, + 0x4bd7fcde16737783L,0xfd8cb52ca254f8d2L,0x62168a66413ec985L, + 0xf2db97417a9026ccL,0x3962ee5650e1e1b7L,0xbee0a346d3beffdeL, + 0x3b35b72f0bdfab1fL }, + { 0xbff8de9f535c3749L,0x23c1f20f8add9c48L,0xa975b37bc8f8f663L, + 0x2529e475e8f3ae49L,0xc32f10d51d5e2628L,0x5ac0d29767862f1dL, + 0x13c79338854cbe36L,0x48f004ef4b67e462L,0xfa37a150e5d10ee1L, + 0x4974778dd28288a0L,0x96830a66cfb73f4dL,0x9f44401307804952L, + 0x8233c7099760b694L,0x8340cca525b75c99L,0x3f62e40bc771f99cL, + 0x47d0a1ebcd95c685L } }, + /* 169 */ + { { 0x266f4fff652811f1L,0xeaacaa9362ef3002L,0x6c387a5550cba0caL, + 0xa350142a007f5467L,0xc7fd102a202f2673L,0x5daee57033dc6e65L, + 0x60682ec3064a63d9L,0x46cf0bb0462b251eL,0x0e030ca55da936e7L, + 0xc87a60f2434265b5L,0x9637b2bb69b4e8f5L,0x601fb58c7ad7770aL, + 0x1f2147f6ed3a15a6L,0x05b47d5e2995e961L,0xcb0ca9b383213a16L, + 0x8f4b614a4995a85cL }, + { 0x5aa8ec194b4eb3c1L,0x8c549ac420323a70L,0x00d493224f6cc6aaL, + 0x0e53b9bb45f9a5a3L,0xe46ef1100897abbbL,0xfe873e57d7acd7d0L, + 0x7cfccfe50f7cb588L,0x0ea53d65c85557d1L,0xfdd9eb447288f2e2L, + 0xab2dedfac0eb68a8L,0x5822147008603a0cL,0x6946468900feb06cL, + 0x804cf5bf25e5caacL,0xd85598589fc91ae9L,0xed9378b173c45eaeL, + 0x8f942d02524c9801L } }, + /* 170 */ + { { 0x1f1ec3028e845808L,0xc302bffab77abfc5L,0x26afd4b9f8d97dc7L, + 0x3d3a83c43aac594bL,0xe3b74bd1674d94dcL,0x4464b737caa5911cL, + 0x62925773871c2cd2L,0x419f24853b4440feL,0xdda6a0f3e052ad7dL, + 0x645280d6846c86c0L,0xa25689faf8324f42L,0xc74ad1e807cf117aL, + 0x5626dea08ddc9db7L,0x52620373966fc85dL,0xe0ad57c3f3b1eb53L, + 0x38300252949c1acbL }, + { 0xa0ef5a405e744723L,0xdb5bcf751ae08481L,0xabfad8ccfec1f76fL, + 0xfba5d831fab37fc6L,0xbe39e248c8fedb78L,0xa5cfad5fad93f310L, + 0x747fdb1e913d5c24L,0x052a47c94518b7f5L,0x9e208d6c7cfb4327L, + 0xb135cb9c70e538beL,0x363527595bb17916L,0xa2c078805b3106c7L, + 0xd2d42a06c209bb06L,0xb525b471d3c504adL,0xc9f4b368822ce034L, + 0x15f18796eb4185a5L } }, + /* 171 */ + { { 0x094dea060aee4684L,0x42b21f067cdbdbc8L,0xa439e149b1931319L, + 0xea4bdd4181a7dba6L,0xc62137063c2ae80fL,0xb58b096712823dc2L, + 0x7443d515832611b1L,0x2e16f83113c20384L,0x0ce204d62bd992d2L, + 0x499dbcd6f419388bL,0x492ded1d1d3778c7L,0x9d5bd74fc5ddae73L, + 0xd4813d52994b6259L,0x191d9cf60e86ca68L,0x562179eaf3e9c2acL, + 0x6146f1f39fee1238L }, + { 0xbd06d33e078e2aa6L,0x693af7f79dee9265L,0xd56e0f81daa40e84L, + 0x05fbbb889b9a407eL,0xdcf44adcede99519L,0x7f71f8d3092dba39L, + 0x675b5da54231774bL,0x7456a251a5f605ebL,0x9031d4af87a39a9eL, + 0xdb43000605b474bdL,0xbda5dbf2b665aa91L,0x5d1a3df56631eeb4L, + 0x028149ef62377c58L,0x2e1af4e9685d0bffL,0xe0ea087582a465deL, + 0x95543f9e06bd0050L } }, + /* 172 */ + { { 0xf7cbc6f485d7c6efL,0xcad8084d63b1bc24L,0xdf90ce88bf8cba62L, + 0x98e4b686b455c192L,0x6146b8d5774fc6edL,0x70e2389e7ae20077L, + 0x5241c47961c22529L,0x7d2215103884e5f5L,0xd6d20ce217e28273L, + 0xe3119f514f2674f8L,0x8545905570c011dbL,0xdfab75d9fcfb760eL, + 0x9546362a9e8c2a19L,0x4b6d3f8a4a7d4b27L,0xa5c87104ee5d698cL, + 0x6db434782ba296ffL }, + { 0x064864935c3f0d95L,0x8917db824e748895L,0xf73fdf626b2f3e44L, + 0xc60edc542b7f574bL,0xbe1c09a2af732723L,0x7d34669d7cad114cL, + 0x9646600a321aaff9L,0xb94e2bbaed0cd61cL,0x866e1a41dec4750eL, + 0xa1be990db1a89f58L,0xc39e4d6cf2759693L,0x11cfb780c0e0dddfL, + 0xf0afcd7fd99c8a41L,0xcebffadb6e1c3050L,0x4f3981b096d2c6e4L, + 0x07a791e72ae27a94L } }, + /* 173 */ + { { 0xe70e90471e9f0300L,0xe0253ad9bccdf904L,0x51c0289dff053078L, + 0xf1ef092eae893462L,0x2c90a91aa4846845L,0x1946eda0f1dad4b4L, + 0xf07650f333df67b2L,0xc6e988db0b15a014L,0x72e0c66eb542f0f9L, + 0x5d4b6311e0c0378fL,0x548badaaae86950dL,0x6801638db35f1c8fL, + 0x129e3216944d1ad4L,0x9951bac840471d32L,0x03cc29f385e94ddeL, + 0x6d6acc2e4543ecacL }, + { 0xeb999e9557b2d299L,0x3a2bcd9be3d721cdL,0x2e60384fbb4cb444L, + 0xae177709dc060faaL,0x74f0e6d38c987cdeL,0x9a237cf81076fbedL, + 0x69af15137983fbffL,0x6c3f7a1d323f9584L,0x3e21cacf6db64398L, + 0x7cd8134f96703d92L,0x0755898fb8393f76L,0x1b5b28bc2e825222L, + 0xb78799c17924aa7cL,0x1db378f281427a8aL,0xd5a451b1ff289492L, + 0x79d182123d3c46eeL } }, + /* 174 */ + { { 0x1a3edff9109d5589L,0xded52eb4029b4499L,0x13eb9d30b4b54adfL, + 0x4f9214c1a27bff67L,0x4c817ee767f0f460L,0xbadf8d83c3a50e28L, + 0xc5dc03c994026237L,0x5f29581b966647c1L,0x10b6a0898a0687f3L, + 0xae787cec31634517L,0x2001dba562e75188L,0x55d4e1a745e2c3fbL, + 0xbfcacdebb67d3395L,0xa1a0af9cbc6842eeL,0x50590a2b3e88580bL, + 0x73104491a784cdc8L }, + { 0x44ca2cdf2648d676L,0x9a85eca54f1b12b1L,0x1b9dac942980e1ebL, + 0xf30d37091ac8aa89L,0x73072ab7c719e195L,0xba518c822f703797L, + 0xac090e14ac0067f6L,0x0e6cfc708dcd2927L,0x4f5889e221e7da63L, + 0xb4aaa40b8371c7c6L,0x1f9dabe28f7878c9L,0xf78aed6bd84caf3fL, + 0x3c39dd079e0e1d92L,0x680be5fb122424dcL,0xf41b214d0bdc0099L, + 0x6a8f8fc95180c54fL } }, + /* 175 */ + { { 0x62a1ed6353235132L,0x1db233f159dba88bL,0x85625452291efdd8L, + 0xc7505297b25111aeL,0xb5921af91d701bd8L,0xb4d05d729774f45dL, + 0x6e3d4c5ef18e73ffL,0x897d985f899b3038L,0x8a9c30fbc89b1558L, + 0x3c92d1a34d13181cL,0x292e86ba2223320eL,0xcf2454c201ceed02L, + 0x27a45f74583f309fL,0x75a6102cad0fd1a3L,0xdb4f45d2cb9c7538L, + 0x4752d8c1db283fd7L }, + { 0x514d6cead5dff4d5L,0x74cd5fdb45a827f4L,0x1070a60c4fc7135eL, + 0xdec0bb781be5778eL,0x271e12cd58dc6b08L,0xb765089b54bc2496L, + 0x6ddf2c63619098acL,0xfd6ebac667528832L,0xeaa2d025c2508af1L, + 0x13c2cda84dcfc1f0L,0x1c7836a845510be0L,0x3904688d1a886801L, + 0x643132aaafaf2545L,0x496855772830a88dL,0x569491ca8744b470L, + 0x3a6518f375fb8552L } }, + /* 176 */ + { { 0xaaa8ed50224042a0L,0x6cb4e3b02452f1e6L,0xedca5f4c768211d8L, + 0x4e0fe3f9ef4d5d3fL,0x33a8e2a4522d46e5L,0x5998e21ff1446775L, + 0x1496c50ef592d01bL,0x69104c2f83a67739L,0x28670bcb472bbf00L, + 0x8ea883b2503177bdL,0xc5d8bc057d2712a2L,0x41ef9317b439c994L, + 0x9801d3a8dcda1affL,0xd686eeb57038f6fbL,0xe80c5cd0fbfbf820L, + 0x540ac363edc25817L }, + { 0xa71969a9fe7f43dfL,0xe66538082c1b9e4cL,0xad9677d8859c2917L, + 0xbaca954596aa4404L,0x0e9d855fff1297daL,0x1f61897b22aea7deL, + 0x96edccfd36f13f8eL,0x627d307016e200dfL,0x729f0736c98988a4L, + 0x95e25e6097f231d2L,0xaf7f221bf6048752L,0xd66826094019b299L, + 0x1d99de0926b4b1d9L,0xec47cf661acdd7a3L,0x4de9f2b36ebe15e9L, + 0x17db32ecfa16974fL } }, + /* 177 */ + { { 0x75ef69196cf40599L,0x7ea10dfb00c020eaL,0x3da5ae7bfcaaf679L, + 0x0d663ca388ddd678L,0x5a21f8fe255bcfcdL,0xe9c3f538e344bc7eL, + 0x35f62b1d548e0632L,0x654f242543c6e64dL,0xc755a7a626993627L, + 0xa3b7c5f7b0f41324L,0x05697f793a2180f3L,0x6cf85fb11e81675bL, + 0x6d3cdb35e53428f5L,0xe3aa159152d28b02L,0xa8470255f7a3fb78L, + 0x460bd01ba194445dL }, + { 0xbc34dc23c24d8077L,0x82f4b5804c720d2cL,0xa29da9116f5d1ffeL, + 0x578af52092783ce2L,0xe29f51abb5904af3L,0x46c570d7f7aa1190L, + 0x4a522fba571bddf0L,0xbf4e2a06ae89bb51L,0x799b35cc59f3444dL, + 0xc302836726cc2557L,0x94a4e985afcec177L,0xadaf7dcb7c36cbd0L, + 0xed31b78775d39077L,0x52d6904f2d3e24bcL,0xc5ca26691f95421bL, + 0x7d342c3c1734878dL } }, + /* 178 */ + { { 0xe5cf2c0a11fd127fL,0x66d36bb8119e4c5eL,0x621ab2526ef56ac3L, + 0x30cfeaeee5430675L,0x2ede27d2ac3e9619L,0x6413513af8fce671L, + 0x6159c61b075f4c3dL,0xd447efe959069d98L,0xaf8d6f68ea76aea9L, + 0xac5dc61b0f5bd164L,0xdbab446e1e88bb98L,0x618b8b161ba92320L, + 0xa0eafb3c78989865L,0x0c7abcc2c08b7e82L,0x10f09b6e20d160bbL, + 0x5be0afa68e4c63a7L }, + { 0x82ab6d381bbbf49cL,0x3e09ce498c0703feL,0xeca58b5de10f4263L, + 0xd9cc6581da5a4532L,0x07e18876f618f7b7L,0x0419a5e3250f7fe7L, + 0xbb1a9e90de6b86beL,0x584a7deb37359169L,0x38eb34895149db2cL, + 0x14546a33b0ebabb8L,0x0067f0b0c2f88a92L,0xbde0dfe70a2db019L, + 0xba51b06cc63e6f3eL,0xa19127b9e9206fadL,0xe4eb5e87fe80dc0aL, + 0x1e6fccf5d4de30aeL } }, + /* 179 */ + { { 0xb57dff66aa8ac924L,0x06e9ad31c298b3e8L,0xd140e32965fb080cL, + 0x7dab211d1d95c93fL,0x6d68d8428a180caaL,0x1a929408a20ded69L, + 0xa815175338df461fL,0xff5604ae60eae932L,0x901b9e497dae4c0bL, + 0x4573a97fde262e89L,0xed69d9a4f1084983L,0x8ffa022f64724f1dL, + 0xd5f1c2e4ea85a15fL,0x4c626ce901453794L,0x80440cd6bf0907ddL, + 0x4522d4615ddaa837L }, + { 0x8895f079ebfbe7c5L,0x30ea1ded84ef3446L,0x716a9eb6d4a1ab96L, + 0x1a4a5d2250a30c68L,0x5a16631c0043bbaaL,0xbd1075025010e5f5L, + 0xbffe3e9d3d8c0556L,0x31b30b1807772419L,0x90ff7ef084b82297L, + 0x00c37d75f21a18c3L,0x18d0a635565bb8f8L,0xbac1da2a45e3bcebL, + 0x1c38e90c23f0b08dL,0xf1ba1aa25fbc5ac5L,0x09d5256bdda71fc6L, + 0x346501a96d7e40baL } }, + /* 180 */ + { { 0x86be448ccc2b0f1dL,0xe3eb45c9ac4c3703L,0x5387f65d9fc96bbfL, + 0xcef3c4e95ae27fdaL,0xa008f7761bc18089L,0xf374a08422ca18a1L, + 0xee88284253b73371L,0xcb6fc6d87cc09354L,0x8489ec1b61496d6bL, + 0xa92c29b949e325c4L,0x15c6ca527bdec166L,0x95444eeedcea2813L, + 0x34683eb33a21154fL,0x8fb26f98d39061cfL,0xc3b08aa806c940bbL, + 0x7c1d42cfe554c96dL }, + { 0x766e703fdc110aa7L,0xab7b79d7f362e378L,0xd259c75d5aadca3cL, + 0x2a6eca7960be3373L,0xf4744a4b06c4e8ffL,0xb2842ccef3b705bfL, + 0x1a3af5aaae304b53L,0x7bbfa2011b2d31b8L,0xc4ba6eba4bee88d9L, + 0x2d3565ce565cb839L,0x24808696daf7ece8L,0x2c7ccce7e6959745L, + 0xefd6eb3ce94f9837L,0x0a33b4cf3811a326L,0x14203f43fffa93a6L, + 0x031e982873c31d90L } }, + /* 181 */ + { { 0x4fefecfc765a17ffL,0xa09f3888d1290a65L,0xbf265c46938da038L, + 0x4bb6145da169ad46L,0x33cf821423a62fe8L,0x562df571abc860a5L, + 0xbf2a90fa815c38c4L,0x45ba1d6e17eda875L,0x799d881a946fa5e1L, + 0x6c1be784b90f5a3bL,0x0910a37cb10ff52aL,0xc38c1fe4a4f4fd36L, + 0xc3180fc58e2d3ba0L,0x3e2ff050b17a6187L,0x3a00059b943a35c2L, + 0x494d3645a28cc51cL }, + { 0x398426b64ba021f8L,0xd14c9083796deb6cL,0x6d2e53957e36c762L, + 0x8f556eca751cf216L,0xdaca1e0019b24a19L,0x47887da44b20c2aeL, + 0x93ed4ccdff41a733L,0x8d717c445c7c0cd7L,0xcc48634a91bf7009L, + 0xa1f146f93b59bbafL,0xdd38bb39e5624f15L,0x96d41aad303f8443L, + 0x6b670f034bf104fcL,0x0503f9ed29706582L,0x768e1f47b34200f5L, + 0x3cfdcc5ebbd4c6f3L } }, + /* 182 */ + { { 0x536c2a86b523e13dL,0x1014a4582920d0a0L,0x3d52b478e7571296L, + 0x057460667eb51beaL,0x709f786187b0e919L,0x028aed88686888e8L, + 0x79a809d7d94afcd4L,0x50c6032fe2129af3L,0x75e4be72983c4082L, + 0x98331bbb7ab3be8eL,0xd31a032cb618c728L,0x36dd85a13f59c4a4L, + 0xdbece345ed4f61e2L,0xba7aaccd1e571715L,0x138c58da64a1ebd7L, + 0x89296d0f3d1aeea1L }, + { 0xb165288fcca82c97L,0x26c6c12d1427e8dcL,0x66a94f074c3edda9L, + 0x94600e1eeaa01ebeL,0x14abce7c30f5e86dL,0x741d7020cb456a31L, + 0xab05aa13279f42c2L,0x70b60fafd4238468L,0xa18efec1318d39e6L, + 0xeb07f1ac8920b318L,0x01e3cba8d8399e03L,0x65f8932e3c81a301L, + 0xae8bca7dccc667d8L,0xcee1ae79a268607cL,0x3182e64ccac0a12cL, + 0x9233a2f72b1a4c54L } }, + /* 183 */ + { { 0x717e8df60acbee17L,0x0f0959c25c24fcdcL,0x46f09887e54ffcb0L, + 0xb993decad285116bL,0x0bfaa4f8bba1fa51L,0x9c9249efd0f2183eL, + 0xf93cb35896847779L,0x284bfb7f2322d421L,0x40cc709ad42af009L, + 0xc69f22749bb1d615L,0x76f50b3a717c3c6aL,0x8b21e985bb9c5eebL, + 0x58fb19aea4783b5fL,0x04c86b9b52e1c3e7L,0xaca59092f2971ac8L, + 0x2bb26a6921ed8291L }, + { 0x98a3443515f81416L,0x086e72e7aaff5bb4L,0x3d1f64de0317261cL, + 0x31c0786c5c0a1cfeL,0x542ea4d8b3683401L,0x2f77273a1a39b4cdL, + 0x14fe7ee1cbef27f1L,0xee7fc09e16bb27dcL,0xc0dccc17410e5dc7L, + 0xa34667421943b3ddL,0x92934b603f31c1b7L,0x0186ded9c22c1070L, + 0xa37ee8ba799f966bL,0x0f3bfcb4249b0893L,0xbae614472e92d4deL, + 0x937cb3f8e196eb08L } }, + /* 184 */ + { { 0x57c0e77c16fbfdceL,0xea034cc9c98d4cc0L,0xe7606d7242572d20L, + 0x9861b55c0019a83cL,0x80ba2803f1597162L,0x0f4141dd05a0fd7bL, + 0x8865913b4b0daaa2L,0xe6685746aa3848ecL,0x16d15a5a3e0485d2L, + 0x81c0c7743b6905ddL,0xcec31b7d818af2baL,0x80d8f194d2b74b78L, + 0xca659db2543e2f28L,0x31b83a7d9fb07c1cL,0x86537fdc1f1048c0L, + 0x4d57bb0778586a11L }, + { 0xbc4b768a53b396b6L,0xbc8b24c493b51dacL,0x33e511eba30ae1b3L, + 0x893bbd95945147c5L,0x6cc86031179fe3ceL,0x34b0a1673f920bd4L, + 0xb32912eb6b256160L,0xbc69a2a49d168d83L,0xb4949e7aef0dd128L, + 0x2613419a872699e1L,0x06c58477bf21376bL,0xe55b1909a4f97147L, + 0x63d6eb757b9b745fL,0xb5365b2908df3c85L,0x0e257e4355fcfae3L, + 0x1067c118979f2aa8L } }, + /* 185 */ + { { 0xc845508432bf8883L,0x4755286a6fd06667L,0xd70b0f8f77c2335dL, + 0x678e60da2f4a2c94L,0xa468d8acd118acf5L,0xce93830bbf5b90d9L, + 0xea4b1c74ed4e9104L,0xac67316d27776ea4L,0xb98ad75c361bab12L, + 0xc323d48299122451L,0x26440220530a43aeL,0x3a44532e3292d5a5L, + 0xdb48694b5fecf1bcL,0xe4e0516ec667b8b8L,0xb3aa595fa4306adeL, + 0x7e4f7091f34e9725L }, + { 0x3f3816e9b7f70919L,0x765216ed16b003f5L,0x46c6cff4778c99e5L, + 0xe6a5abe830a51810L,0xef6f49e645e728dbL,0x6fdd73eacaccefd6L, + 0xec394e6f8c37f3f7L,0x73320802b6407fc3L,0x988e8f7a96625cbdL, + 0x832923637cabfb00L,0x258ba9df407f359aL,0xff01aee5ccbfae50L, + 0xfbeaeacefe251813L,0x9c69f16183f1cba1L,0x512c58ad9eadcdb5L, + 0x2ae49cd46ccce8bdL } }, + /* 186 */ + { { 0x1239b0e3c40849f2L,0x5136a4cda441098cL,0x61535a99e547f649L, + 0x92e4bdc47a9bbac6L,0x195a164653547af6L,0x85ecb3198b47a74aL, + 0x278553fc9de6a2b2L,0x471c038a0e2ba52dL,0x12ba1b8835bcba93L, + 0xd4bf50da6f31eca2L,0xd146e3f6802b32c6L,0x0c9c01313c64c8c4L, + 0xad30f12deed21297L,0x9b75bffb9c68530fL,0x23c0ad3e8918de51L, + 0x180e9d52a73771b7L }, + { 0xc316542f29ab77b0L,0xdd411d9cf7aee628L,0x044c0685353c2f40L, + 0x638dc7e44b0ae4cfL,0xa092418595fc266fL,0x639da671fd2feb7dL, + 0x56858ed55ea39798L,0x7a694f3158f3832aL,0xa94233c6d316d831L, + 0x2fcacb2630a35a7bL,0xfef8f7ddf1ff713bL,0x8b9b452559eee2f3L, + 0xd1b4f91b156d064aL,0x177866c22f5cfcfcL,0x12bc25663777eb41L, + 0x21ca6f3cd8ab85b4L } }, + /* 187 */ + { { 0x0e162b13a3e66635L,0x1ef20a2b2a9f76afL,0xab473a3046db3356L, + 0x0840bd777802bb8dL,0x5b6baf5ea699b44cL,0xc6e119001b2207f1L, + 0xe5de16a9790b0105L,0x22b12f15db67f004L,0x185fad458a025d25L, + 0xbccf6953df0a1142L,0x4c42129bf45034c0L,0x0f7404001c277bffL, + 0x6e440b4c280a9e18L,0x767de8f5842aa2b4L,0x3de20ab805e8d94fL, + 0x5aff585920227635L }, + { 0x805acd20a8458e40L,0x5a5557d8149732bdL,0xc70741315f1ca72dL, + 0x7f2e269c952b5323L,0x5c5925566494fadfL,0x153b7acd1a7d2666L, + 0xa6df063d86fe2865L,0x1e91db1357d53b6bL,0x9195bb89e93ead01L, + 0x3d71e1af2963bfe6L,0xfab2b9c288278886L,0x778366923b859b6fL, + 0x6e695174f7029dd1L,0xc79878767b984561L,0x64fb4f1d5907d849L, + 0x3eab7e1c88d8a977L } }, + /* 188 */ + { { 0xc73a94b652e5718bL,0xe3aefa54f4cee1e9L,0x654e9e63553eedeaL, + 0xf2541e1b5f3aca1aL,0xd71294890d083316L,0x7965af63fb7f950eL, + 0xd8fc9e0dc74e3e4aL,0xb4ee48d2eaf79ebcL,0xa458a86a8b7787e6L, + 0xd8c7621ff7cceaf0L,0x8228eeffdf67980dL,0x210d4742f9106727L, + 0x91f63501b07e3629L,0x441761c67971e29dL,0xc0ccc65f03a3b8a5L, + 0x3491da4f38e09544L }, + { 0x6706d046cb062eaeL,0xee7db7355d08776dL,0x80de8052292315d2L, + 0x40785662c402bbdbL,0x5f93525c26ed3337L,0x6cea14d67d568ed3L, + 0x916a118966888b1eL,0x0fbd52055dc71675L,0x833d1077e4575df2L, + 0x4e93100aec092335L,0x2f9e1d016cd85389L,0xeebd372543226368L, + 0x401d172b1ba4cfd7L,0x377dab9d574c5838L,0xaeaa695880d517deL, + 0x0c843dfd6ad15a18L } }, + /* 189 */ + { { 0x455811ffc9373300L,0x1c39332a99fdc300L,0xe19bb81c353cb655L, + 0x774b924a96a83d27L,0xcbfc8fcbb2ee3f1aL,0xaf278ec4010d56c7L, + 0x6fde682fe0abaf79L,0x7566d0727339aebfL,0xbd35ad5d71205db6L, + 0xb5bbe6947051c9d0L,0x577db480d3a3067cL,0x2c70ff54572d7530L, + 0xe8615aece06d853dL,0x71999ccb05abfb5dL,0xeeefc96bea0a8ed7L, + 0x2dcc469d35f6df69L }, + { 0xcca6cd06c65f0e77L,0xddcc7980bd71b14aL,0xb6221f8b3c93cc00L, + 0xddfcd5b3ae8cbf57L,0xbc92973f76f8e63fL,0xe9848a3406e132b7L, + 0x4cc59a03d51ec9e2L,0x9c9d32bb3a33081aL,0x0012105280e8466bL, + 0xc2b0032a1bbe7295L,0xdbfc657224938448L,0xe972a0ceb6bba0ffL, + 0xf60c0a4fc0a94802L,0xf62c41cc599d8bc7L,0x820c96ee312da0b8L, + 0x5a1a65dbcdbdf9fcL } }, + /* 190 */ + { { 0xbfba691a42485684L,0x613116b929c470c9L,0xb4b01971e62a0519L, + 0xf3245aa65ff499daL,0xc2ef87f4a5238effL,0xc16dc6bacc9d5515L, + 0x5a7f227e2dbdacacL,0x8dedaac4a9bbaecbL,0xff308a6d2e7c9885L, + 0x4c6f2fc2e6895593L,0x3655f285177e0611L,0xa63e8d06300b1beeL, + 0xbed0ce7913c17b54L,0xca4abe35c4974262L,0xf4b44a17bc4e4037L, + 0x5ae95099efe5fbd9L }, + { 0x122e5ee7804f7455L,0x341a499722066682L,0x97d24c317795e333L, + 0x12f4123ce48efcedL,0xe8738d9219fbc21cL,0xbb3bdc610663a3aeL, + 0x3603d8c28593a6dbL,0x926227f2e3c1ac75L,0xfea92ac05eaae519L, + 0x5b596f0bfd6812acL,0x3ce7e844fc2a82dcL,0x3840481a63522b27L, + 0x836088b152867895L,0x21ffb7cc26588688L,0x0ca331612f4a7cacL, + 0x4110667ea3edd298L } }, + /* 191 */ + { { 0x81830357c2d04b63L,0x3fc5a34df4929a18L,0xc73bf6da22d195dfL, + 0x14df2f89cb432473L,0x345afe5ce997f138L,0xd8e3f5f98b9604f4L, + 0xad7942e950c10ae5L,0xcefd5447eed25ff3L,0xbf68e51e0e73c0ccL, + 0x5b1ad591ab54fa4cL,0x8bbc110512b61c8cL,0xbb932913b5abf760L, + 0xdb1231be01e79649L,0xd0a83e91040ccbe7L,0x3dde426f90a96db9L, + 0x1cceb64534df11eaL }, + { 0x2d210c4f0c6d0f55L,0x6cadf61b9c673c9dL,0xdd7f9919a9ce3fbbL, + 0x135f494c93b063e4L,0x580bdb3c145a93beL,0x4d8723320f52ef7cL, + 0x74d876e88814bb6aL,0x4f6f723ac7a97deeL,0x7de2b8f03e3cd833L, + 0x6162f082ae720270L,0xe88ec2d4ddfa486eL,0xd965c8598d3a17c6L, + 0x62e59e543980171aL,0x0ab6285dbbef6b22L,0x3cf451954d48b203L, + 0x1f1752334ea25ea3L } }, + /* 192 */ + { { 0x808a765b3467ea91L,0x3f4632eefd2d9c45L,0x7b75dc6d9cf2bc6fL, + 0xefc8d240359813aeL,0x23ecb209e44cbd8dL,0x59ba10e321525622L, + 0xfa14d9343f1ee19aL,0xdf97c21bfb0c48f7L,0xc4e62890ea30d437L, + 0xb286e2a4651475c2L,0x291f01e4126672a5L,0x9c6fda5c31aab3b8L, + 0xb7277a5ae17d22ecL,0xbd88ed83914f0badL,0xd0b05d1b6a2392e1L, + 0x4cb8af9065893c2bL }, + { 0xa2b02057bb4b1953L,0x4ce08b44f597f6eeL,0x854f5d9b5e6412c8L, + 0x1913262db3cd4919L,0x902762e46e42bb5dL,0x8355c8e6d78e7f60L, + 0x8efaa82438b6c16cL,0xd0173790e550f618L,0x118af462e57d778eL, + 0xa16ad5e8715b4714L,0x900596c341dea4f9L,0x2a957c32280ca610L, + 0x2faee800374c65a1L,0xdb10512750080414L,0x8c1db931ff080fa1L, + 0x486a5c25d79878fcL } }, + /* 193 */ + { { 0x0521e213941b4f36L,0xbaacfb14f803b4f9L,0xfdf1e22e52a54ba8L, + 0xacfabbba8fe4796cL,0xae0788db58dbacb6L,0xdf98d736c19dfa51L, + 0x155c286a35a716eeL,0xbe7d46769c86461bL,0x50b6380f63a64a5eL, + 0x14b419149f609262L,0x0919a7d0a2dfc5b3L,0xc454da55cef466acL, + 0x93fa4a246986aaecL,0x5090b17171a49cedL,0x602f1d6cc1fa75adL, + 0x5d269f8978e4c054L }, + { 0x3a74030c14920419L,0x0845d86890968739L,0x81b994c4eeb70fa6L, + 0xabcaa06dd9fc5bcbL,0x06539427f58f8f2dL,0x35c85f67b1dc52aaL, + 0x5a7d8d722c911baaL,0x4041005caec2d834L,0xb5868a447a8e5347L, + 0x04ee180b8de512c3L,0x4daa66e5211168ebL,0xc0bd5dab2317cd8aL, + 0xa1d4185d61164df6L,0xacedca261dbad7c9L,0x0fe4b5ac09b02683L, + 0x8ac9995a26d9550fL } }, + /* 194 */ + { { 0xb2c8dc9b2640a39dL,0x21ff0b38ede0c9f9L,0x74f469bda1ecba0aL, + 0x8a902ccd080d0417L,0xe956fa32f4994604L,0x348f85cf9776ab15L, + 0xc21fc6ee0066f492L,0x35b1ebfefeeef367L,0x7804581c4613e5edL, + 0xcbdfe8e6ea6ba071L,0xddfcaa32950d73edL,0xc97479361da48889L, + 0xce867c8cdbaffbd1L,0xd267431f1cbaeae7L,0x68255045897912c8L, + 0x0c7c1ddcd7ea1e4dL }, + { 0x53aa30cc1ce963a7L,0x7352f64cc4c5fadeL,0x2b9aa2f82828afbfL, + 0x64273c56ca212107L,0xaadd765485a576dcL,0x6196ac3e90b5c77cL, + 0x20d43e9fd1aaf39bL,0xfc392062cd05cbc4L,0x141638724c0ff2fdL, + 0xcf32b8d82ae821e6L,0x5f58f9433fa7a3f0L,0xaebf1d2df644ca92L, + 0x0c0615631918a75fL,0x7989b5ed6b876118L,0xbf342445ad412441L, + 0x24ffc9ae1df633abL } }, + /* 195 */ + { { 0x89fcdc0593c7cb2bL,0xc1243b95590053fbL,0x601debcf6182343cL, + 0x364546ef66c18a63L,0xa5290701ec913287L,0xc35b8026f9788c31L, + 0x852b862a92d1f7d7L,0x1809cb050aa79728L,0x897d467ca3cb2005L, + 0xf20c77c09ef5b946L,0xc3372c42f2241984L,0xda053e0df35bb206L, + 0xbc26c6d0a9c140b5L,0x61cfcc0ccb56fb33L,0x1c3cf9ef299b3968L, + 0x89e4d3d140621ba4L }, + { 0xd35e80e7a45a9be3L,0xc4daa57807356fbdL,0x0186d62eb967bc2fL, + 0xa702679e47cd16e3L,0xca2f1c025f30ce9bL,0xf1205b461f864f50L, + 0x7fd6d79785061d66L,0x47edc4f68a08809eL,0x5dac04499a4d3ae2L, + 0xf844664a6d1f9da8L,0x9f30ce84d7a83a71L,0xe9382baceaac33f1L, + 0x1f033831948622abL,0xb037a4baf7681eb2L,0xd156a90899a1b5c7L, + 0x675d3e6fe6f1d0fbL } }, + /* 196 */ + { { 0xd9767ffd707193e5L,0xe478aa91810358e5L,0x5634f9ff328d8ef7L, + 0x913a0ee86dbbd9a7L,0x379b29687e215686L,0x903f410a89d9da38L, + 0xd9f8d7b91b1334d2L,0x9fe74229bd82efb5L,0xdb568b623803c778L, + 0x93e9a350d3d25344L,0x559c35b0724497e8L,0xc472d436a169e23bL, + 0x09864632cc5b4c69L,0x9f6d759d83c7f531L,0xa91cf1db1e497888L, + 0x5f7f92fe60af1a4bL }, + { 0xf18a1cc60545167eL,0x55ee2e02affa88e0L,0x24cdff51432a7bcfL, + 0x7382da42a7510866L,0xe894c11f40511af7L,0xaa4e4e312aaf1423L, + 0x8c3d36f0f63dd2aeL,0xfc5c9550d7660635L,0x0125373137ea7eabL, + 0x2a5cd59839b950f6L,0x95a0f60140e63442L,0x905e238ef2ac7045L, + 0x44bacc0e446b0f73L,0x4cd4206ec448578aL,0x367b1aaaa5bd7803L, + 0x25beced90a2b458dL } }, + /* 197 */ + { { 0x079a73820c33a8fbL,0xcfbf6cd10f25dc1dL,0x4ffc73f8c6d482b6L, + 0x3e51f18c07bf844aL,0xa7651236599162f0L,0xac59a74e14013811L, + 0x957a6865e55018a0L,0xe1ec51bde3ca09b1L,0xbc0c7eb3a960253fL, + 0xe83bfd147de03f84L,0xc0540ed152fbdb09L,0x6ba52eddcea15ec1L, + 0xf3d30ed54b261307L,0x9bd7bae8e8397206L,0xf20d8692096373aaL, + 0x0a616a4bc3b0bf63L }, + { 0x2075f3ed6e1339c9L,0x7afaa072bf8b00a6L,0xdfafec82bccd9b47L, + 0x4713158f00ca54c7L,0x449102f138bc31aeL,0xaf98f158310dfc8aL, + 0xc9ef207559e954d4L,0xe8021af9c527a0c4L,0x6e8012777a192023L, + 0x635f538c7fb02377L,0x5df1974fe8c9e951L,0x0287faed15cc9097L, + 0xfa0728f0f7a5115cL,0x90dbfbe60fac623dL,0xa8d40fd40311ba09L, + 0x876d154e07c6464cL } }, + /* 198 */ + { { 0xd3a4d6d2c2d3ea8aL,0x36be681ba842600eL,0xc53f100de4070672L, + 0xe3e5b6fe6a7d7a7bL,0x6e6994f95d5e1a83L,0x07cacd2276097c2aL, + 0x12d98dbaa6791011L,0xddfc4461102e0e24L,0x4815dbc2d493272aL, + 0x7e38e64ba9436696L,0x4960eb1a32b2bf90L,0xda457525d928e28bL, + 0x72f75b392a077c9eL,0x27760cbb7fd61d00L,0xaf235d1b0f4b1456L, + 0x3040c23be76d1700L }, + { 0xb10dc55b4efa9a70L,0xd4de414f53e86610L,0x3d95c11309f8a27fL, + 0x505109a506661d3cL,0xcaa2994a60eb513eL,0x3ee415371e7d338bL, + 0x4fd145fc4651e71fL,0x51bbf838cbc313b4L,0xb039e0781eb92150L, + 0xe8696b4414bf5ac7L,0x2d6671888be0d48cL,0xbe93b2f5dd8f2b6fL, + 0xc1dfd1e7eb8a7f8aL,0x862b3dd990f751c5L,0x1eb1ad58a32a74beL, + 0x5486d79a1ebbc9a2L } }, + /* 199 */ + { { 0xcb2e34ffa1359e13L,0x202d8dbf28196051L,0xe95e023d23564b5eL, + 0xfb1340b642f6ac12L,0x543ba852b653725dL,0x81aedcd68d2466adL, + 0xbf780224547c728bL,0x559f8a119569fb65L,0x505b7a62dfb22ec9L, + 0x071075409eed5e52L,0x9c899288299f6f11L,0xa7d692613db6f8c7L, + 0x30eb7fb3b3ca79a9L,0xcab99bb8fb2160b0L,0xd2012568d28b409aL, + 0x380f1b0f5ac45f8bL }, + { 0xc0b99e6be6a0068fL,0x4b67cf2ac8a73753L,0xa6c9a548b2faeb7cL, + 0x7f417f99340260c3L,0x8ee56855cc0f739eL,0xf08b510f780949daL, + 0xb1770fc28d5c6effL,0xb4f5abeefd96a7bbL,0xa07b1136f2665a2aL, + 0x2fb380a4b601dcf9L,0xcc803614162becc6L,0x3498fb96ee6b83b3L, + 0xea9b0fd6a8c17eebL,0x5834b5baa177efc2L,0x929044f55b110b3eL, + 0x4abeddedebd7285eL } }, + /* 200 */ + { { 0x3355e1b9700ef376L,0xd56e5d9a66cdabffL,0xb3dc257547e87646L, + 0x28f44b8a00f79369L,0x08c32b1ea0c52e29L,0x5a78de123729b392L, + 0x4184519ab26d239dL,0x23f6b4b7e0ce4a6bL,0x235f6f8aacb2a9f9L, + 0xbb8bc454e2064a59L,0x37efd0341bf3062eL,0x6bac683b94dff6f9L, + 0xc3364b1e8aa7fa06L,0x0616772ace0b3745L,0x46f08d08d1e3fb0fL, + 0x6a20abb318e132d3L }, + { 0xea8310166a85cbc7L,0xd0990946934f9aa7L,0xc2211088e778f1b3L, + 0x7ea4ff8f2247b799L,0xb3171d71454484ceL,0x294039494f98c364L, + 0x5da911f397df1458L,0xa6b5809309439116L,0x75f9509a174238bcL, + 0xfeb518218209758dL,0xae0c6021a47925d0L,0x0e946694af8a315eL, + 0xae7af8a36bad04b7L,0x44c15e7ff072447dL,0x5184668aa5456ffeL, + 0x45e353a7bf36b977L } }, + /* 201 */ + { { 0x7605676493092f71L,0xeb66b6c2f5b92d71L,0x9db3149be2c8b6c5L, + 0xf62f583a20c0363eL,0x688acd3303cd7097L,0x85d0c0f8ebb916acL, + 0x1bf7462c84c19b0eL,0xc76ed5f97c4a6ad1L,0xec8b88bad119f369L, + 0x59b8371bebe50b83L,0x0cc69508866706a6L,0x531c75a3f8373d2cL, + 0x4e1cd3a32a5a02fbL,0xe8274778da39a1d0L,0xedfc5bbb75da333eL, + 0x15941f24ca79bd36L }, + { 0x42e8c0f8a77dd512L,0xa91b59a71dc365f6L,0xe80d14cd08753862L, + 0x1624230dd272facaL,0xeea3ec164027cb5aL,0xc1700b59c1ef9f03L, + 0xd411c1270da3148dL,0x801ee448c4181af1L,0xedf285599e3a900bL, + 0x5d67b0bd0d09affdL,0xd839df968b370024L,0x3b6307e0e6f836b8L, + 0x5382e588bd3201c9L,0x636d8a6b7a1d02bbL,0x70b7db76968641e9L, + 0x6d17c34a118fad03L } }, + /* 202 */ + { { 0xcf608841c181c99bL,0xb65dc901c87bdcafL,0xb460b4473720dabeL, + 0x4c79c3965377515bL,0xd447f22e0a96c277L,0x0d9521302ac0f440L, + 0x8330b26bc90583adL,0xe25e977a928904a0L,0x1deaffd985c50b18L, + 0xcf4dbcb7a5ad5f6aL,0xcbcd0019c8a37ed5L,0x7846dd901e9850b6L, + 0x1ac8194ab0b8e605L,0xb972857134132f90L,0x4ce9f149f56ee28bL, + 0x1ab9b5a43e9e1d4eL }, + { 0x206dab92314fa7a3L,0xcc4af0f0478ff963L,0x4cce1713904d9fdbL, + 0xac20a2eb12c045feL,0x44fc5478fd8f6d7dL,0x886e72c5ca7b6ffaL, + 0x7fa4529b6fd6f758L,0x4df1d1b192a820d5L,0x3d812f9f2789f149L, + 0x9842f083aabb53d2L,0x2648539b2a03ab32L,0x631ce090b1512502L, + 0xe1294d15731f6bd5L,0xb229361d9436e634L,0x8c4281c43ca966afL, + 0x24b34956c21ab3edL } }, + /* 203 */ + { { 0x49bdcb86659824e2L,0x6dc4ce484e13e74cL,0xa4c01a266bbe1eeaL, + 0x47b2b8e71e3ec457L,0x7e8b15e02f5a8e4bL,0xe81eb6e6e333530dL, + 0xacba369e17a45202L,0x81241431d70e4c9fL,0xc190af4b3e12beb8L, + 0x5327052311f486fdL,0x9f6c41e129fb2bceL,0xbe6287ebb70f6c08L, + 0x1479850a3feb4477L,0xfcfdfb119bcf18bbL,0x925c292fda80d040L, + 0x212d65e57e3c5bf9L }, + { 0x23adb386ca15cf08L,0x4dfa4ac481e172ebL,0x9d1dbf934d42d0c0L, + 0xd9cf607374404dc7L,0x60508441e932bfcdL,0x9ae910ca1c682a98L, + 0x9528fc1841ac1cc0L,0xe6a120aedbbed630L,0x94e0e1ec30ccf250L, + 0xfe84ba54e58bbf2fL,0xc66d0b4f9faa4415L,0x0c58f1e7ecee7ce5L, + 0x7a1d43eb6fa6873aL,0x96c6c5a0399f1348L,0xe6ef9aaae6727ab7L, + 0x66afa5549a5c2447L } }, + /* 204 */ + { { 0xda5aaba8c980e91dL,0xa93cf5096ac98efaL,0xb0990e0a8da32662L, + 0x01d215300081453eL,0x2bb0d33e3d71de84L,0x465f6d803e19a012L, + 0x5902ff4c78a838e7L,0x74e2afb71931348cL,0xa49327579cfb057bL, + 0x761ea6423ad03f8fL,0xb7d4c24558ffa40aL,0xb5e9c0d977a87e30L, + 0xd1c5edbac9c84d26L,0xeca8839a3d1963a0L,0xbc6f2f35ebf6bf0dL, + 0x01ef06310d58abdfL }, + { 0x2bf903163ecdcbb0L,0x19e2d72827c1c955L,0x9e5270309575c930L, + 0x0dc1c5a996983930L,0xef9f80ff7cd082dfL,0xcd915075df97e051L, + 0xf286fffe9cc61b55L,0x352db38f80f24cc4L,0xed9b99ec36523ae3L, + 0x109a8ca810b104a9L,0xc2700fe7305203adL,0x2a2ee24e769400f5L, + 0xd595d399ee0c452cL,0x0ab75d6af7f02a41L,0x341080990db730b7L, + 0x0e4f5ffd5e8d1202L } }, + /* 205 */ + { { 0xbd1c64440ff14c38L,0x9a5b59faaece11f2L,0xaa4605a722af6330L, + 0xddc9f65a82af24eeL,0xf4ee4bfeeb9a1159L,0x2463d07674e84eafL, + 0x88cbe1e00e0baaceL,0x7ca568ead5fabdcbL,0xbd80d524c57eb99dL, + 0x9c46572ce9be9873L,0x918a1dcd7300b85eL,0x4922131240f54176L, + 0xf7e324ffb5b14236L,0x40dda5012434f16aL,0x08833421a133d97cL, + 0x33d411610876f020L }, + { 0x7531a36b9878e5ecL,0x5de3e32146918232L,0xd15f9a33d0a30464L, + 0x734c1b87aa173659L,0xac2094a2f925d4feL,0x43c965a1c262b0f4L, + 0x759c903e447d5cbcL,0x92af215e05239300L,0xfffb6d5f1f593f34L, + 0x65943b4bc3cddb5fL,0x9d03a29cbfdd5408L,0x8f7cda6b198d76c0L, + 0xc0790a22c0f27b59L,0xba557a848cb58ccfL,0x5922052d76c54fdcL, + 0x2d3de7aa47b6b466L } }, + /* 206 */ + { { 0xaade746265add3b7L,0xe5888f35abf24c2aL,0xd41549cae1a57d93L, + 0x0e22e18e2c76f7bfL,0x67f288eabe3202b3L,0xb79a66ba1d1d0f0aL, + 0x0e0ab7492881ad18L,0x7d424086c7adb0e9L,0x870c32c52842132fL, + 0x858477f158f9a09eL,0x422a9372ec025589L,0xbe428c5ca5098777L, + 0x45b7956457660058L,0x6c7fc631957f37cfL,0x8b7023ddd6316289L, + 0x47003bb65b1c12a6L }, + { 0xd99401c1c91c1c96L,0xaa5dcdf927a12970L,0x3ab92e17c3c29107L, + 0x26fce8f7a3fe4710L,0xb0d09d5e4ee998eeL,0xafa622048e3a41f8L, + 0xb1c012a5a26ca506L,0x2c6f734c99b57252L,0x1093d79f512f7fe1L, + 0x2f30906eacee19a6L,0x6bff8381056d1ea6L,0x61c75856eff35f21L, + 0x6e07e978c1ad2224L,0x2cca6ca16b20fde8L,0xab4d6d2d633fe81bL, + 0x73dff504b06a2ce6L } }, + /* 207 */ + { { 0x8b615805d8e20fb8L,0x7c6873e482b533f0L,0x5205f00156a854caL, + 0x87fec6accb369211L,0x1fa3c0ecc7f092b7L,0x5b36647ee845fe4cL, + 0xd4781e85f8b1f112L,0xc65268398b0f1a6fL,0xceeb8c6cdcb8eb92L, + 0x133f0ead8e5f6d52L,0x31883e23c8d934dcL,0x214ed5bd428ac45aL, + 0xf77ca492dbbfca85L,0xdf4113fe07e5ae13L,0x63e4a0d272ab05fbL, + 0x7544d0b77148f535L }, + { 0x4fe8d13480797aceL,0x216d6aa0af86d97eL,0xdbf0a688ef5a68fcL, + 0x18b26f459f9b2684L,0x52fefcfa8999d2fcL,0xd5af8d8262423955L, + 0x8f123469f63a3780L,0x2933454fdcd4feafL,0xba8018b7a73b5d09L, + 0x9af1f276e5552c18L,0xc5d4773dff26bb1cL,0x9ef4941006dd4f44L, + 0xad8f12f95f39ba49L,0x5767f6dcf66ca4f2L,0xba8773f17922f59aL, + 0x220081eac1e42d49L } }, + /* 208 */ + { { 0x3043d573ba37a0baL,0x05a431bcdd176df6L,0x03322cfcc42070f7L, + 0x5cabd30e67c2d109L,0x362c95decbf8bcfaL,0xd767d2777787b10bL, + 0x612c915e6ec05e64L,0x9e669631ce69c30eL,0x27c9dd8f682e2635L, + 0x79021f1295ffcc38L,0x06a8ee798a2adca2L,0x8e00e7844b5d500aL, + 0x87746fc78d80d6c5L,0x246053be915f10ccL,0x844e328b219f6fd8L, + 0x620541ac11bd3733L }, + { 0x0f7fd382509e5a29L,0x8748d7d0b432531eL,0x8f749354cd3883b9L, + 0xc6b8ac748bfbb17aL,0xa4616a6605f2d2c5L,0xb3d966251bcb1b83L, + 0xcf7531042fee265aL,0xc70d73fbdb225058L,0x1211d434f0c2d556L, + 0x862061d854b259b3L,0xffe4606dc42b3f7dL,0x4c5c8585e86a4949L, + 0x04ddcc8b160eedacL,0x1804ce67568e2420L,0x91f3855a42141656L, + 0x7f378198f932be97L } }, + /* 209 */ + { { 0x9a374bdadfa6639aL,0x0cbd48d402ab7391L,0x5c5ef23647031e2dL, + 0xb49ee2bcd0599d1fL,0xd285eb60e0d38443L,0xdbbea92f269392e8L, + 0x91455fbfb8bc538fL,0xae259ff1e469b768L,0xc1cecb1f41de5682L, + 0xc876f0719952d1aeL,0x1ce25181e7bf7446L,0xcb93ad86282ad2f1L, + 0x8fa3cd316ba4ef67L,0xfce68a04e507aa3eL,0xced74170a61bb608L, + 0x6de716b3f6ac10d0L }, + { 0xd4e58d04172d6dc5L,0xbed2cde66397c65cL,0x7ae77e180c9eb4e8L, + 0x5627546875fa2edbL,0x4b30324ea91e6738L,0x6023a856235c8b2eL, + 0x9df6d6c2a8f92887L,0xec2c185ff6f5e8b5L,0x7892e12b3ad5748aL, + 0x7aebb4f2d54aefbcL,0x14915448ee868821L,0xa26c5f71b1d9bd5bL, + 0xe5ccd1662ff00df7L,0xebc99f17b95b1deeL,0x909836163fe1f774L, + 0x51f90830bb3d25b0L } }, + /* 210 */ + { { 0x49376fa1f2922461L,0xdbb1b1c31650d0d1L,0x92b91c330dd8608dL, + 0x3e612c4b36b89906L,0xe1977b0bdf560052L,0xf8afff70636a2545L, + 0xcda7d27811723d8eL,0x0b0bc4bb81bde7baL,0x3cb080b2ed2a578eL, + 0x5bda0d0d171b2e02L,0xf6df38cf941bb9aeL,0x85dd81dbc14a65c5L, + 0x7f98c82dc19dd98eL,0xc613747f52206f93L,0x9e13a2c25f5bbe78L, + 0x5eed218e0aa34be7L }, + { 0xe156575401d4dc0bL,0xa1ae5f27f566bb07L,0xe985ebebb82225d5L, + 0x5f3ad21c1189ec6bL,0x17da518cecce4d9dL,0xc84a2d3ed6b65b59L, + 0x7f9881758ffa771cL,0x50d6ae122ac69a7aL,0xcb7f30b1c6e6846dL, + 0x8c023a605bd0bb13L,0x9a10fecdd73f2407L,0x8c5158cce5f0a996L, + 0xd26bf615bd8f5806L,0xaf32ea87915a46e1L,0xeaf74e810287d308L, + 0x8c14ba06a6264254L } }, + /* 211 */ + { { 0x0c877895b17ee201L,0xc05aa47188e57a77L,0x19c3e76397822456L, + 0x0be6f8c0c9c3ba1dL,0xfe85f4ffb4389ebeL,0x538bccce0ce7fbb6L, + 0x876eab2a65266c64L,0x5c9ac690cf9a3842L,0x9f5cf3b1ccc8f981L, + 0xfa17be6a9cf687deL,0xfcfc10fc83835c15L,0x086b0fdb150ef2ebL, + 0x9f97ecd9884a52e6L,0x416e6fa2b0cd1eb8L,0xe2bd15993ecc03baL, + 0x645c0a5deabb165eL }, + { 0xd94c420550aa7e31L,0xaec8df0c2f851da5L,0x996469093c726e6aL, + 0x72dbdc362619bf9aL,0x1b4260e0e253fbd5L,0x97c259fb8c709e06L, + 0xfabf7cbbcddaec5bL,0xb4d5e8b1e4b703e9L,0x1b06e56e0734efddL, + 0x02d4a4f91f55f8a5L,0x7f8608ba3f565c8dL,0x822f47d2816d1d94L, + 0x0cc361565ce7b136L,0xe46ee5ef31d04242L,0xb2a65f70683567f6L, + 0x27e9ff40d2fa6c91L } }, + /* 212 */ + { { 0x75251893d7e952e7L,0x15b30583c735bf18L,0x732b599296fe0491L, + 0x27451858806d2fcaL,0x71ab76a01b885ed9L,0xbdce9d976d9f55ecL, + 0x3da60b2048f2ba9cL,0x6977c086592b132bL,0xb6dca9cb099051d7L, + 0xd9c2ab23d188ae25L,0x9f469f3fe20aaf3dL,0xdbd1f7cf5aad74d0L, + 0x3d5efe5c22a9eb3bL,0x8c5edfa2137010c4L,0xada2217b57870260L, + 0x4feee5673dac9776L }, + { 0x30e18d52b5d3d780L,0x4dadb5d307166744L,0x320d386e5a742156L, + 0x5d8c290e8d6bbb86L,0x981a43232d263dd1L,0x33d0e7ca98984636L, + 0x5138784da519acb1L,0x832e3fabdddc81ffL,0xfc2785943199a43aL, + 0x5b4cabcf32743163L,0x9fa010bd74f94fa7L,0xc28a743d5694a627L, + 0xc1d2a888cb657a24L,0x7eef2503e86a25eaL,0xed11a5d304c561ffL, + 0x4fe818e79c9ede0eL } }, + /* 213 */ + { { 0x00252c9d7fc1c7ffL,0xa9bd419d9fa89ad1L,0xc93a124a4064e9ccL, + 0x384cbcb843942eccL,0x004c21fd8749695bL,0x69c81d9f421165bfL, + 0xe2325628dde01102L,0xec9374575a9b004dL,0xfb3346bff6dcfc21L, + 0xac4da64b4d372c7dL,0xcecb7ad3f20494e2L,0x562c41b5e867c150L, + 0x299395cec2b723d8L,0xc91adfc57ee53231L,0xe06f1161f10b6597L, + 0x81915529b74d3ffcL }, + { 0x8ec124316ed9d4eeL,0x3dffa154689aff01L,0x4aba349f2a89a3f4L, + 0x2db1e8e2d467efb2L,0x18dea354039102e2L,0x422ab853e52f082bL, + 0x7130a2c1ed36dd47L,0xca60e86d0295d1eeL,0xe6ac68087c7f5ad3L, + 0x0f83cecfde864658L,0x72e66c21461d1265L,0xfeef4150bd385099L, + 0x0f183f3aa6632289L,0x275454be792dc795L,0x2744c11b11367702L, + 0x7d06bcc7e8ea6ef3L } }, + /* 214 */ + { { 0x892859427090212fL,0x691b7d4c5521e844L,0x4c038422be2dbb92L, + 0x317721edbd81f880L,0xc136cbeeac89bc36L,0x4f71b60b7b8f004dL, + 0x269132d04e218ab8L,0xb0e2496ee6cc814dL,0x0b2ce31775fadc15L, + 0x82e3c08466d223c5L,0x9721caa64c612f8bL,0x59a751eba4b65355L, + 0x3433aad5c7d3d9d1L,0x1e61b9d2e80d4246L,0x149f655ffc673caaL, + 0x48b52b99d0f9cb92L }, + { 0xa3915399efdc05beL,0xde70db1813e095e9L,0x447862e9cddb3fdaL, + 0xa2b031621a009451L,0x4b27980c23920ea3L,0xac5394f1a23b8febL, + 0x163f72563e5616d4L,0xaa0ff93fb714219aL,0xd26f96d293d62474L, + 0xdd212ea87dcfe276L,0xab27bf2f47038d15L,0xe58c8325f418168eL, + 0xe3704222b32a989aL,0xa3694390bfc9f13bL,0xf16e26060d0684adL, + 0x17c0de879d8c76ecL } }, + /* 215 */ + { { 0xbca5f453dcc01958L,0x7d9459541ce88393L,0x5e6350a1561f5b6dL, + 0x291c3c867e2d36bcL,0xf6c7ed84a5ac3a6cL,0x7913c40bd98006cdL, + 0xf78bb0875671ec3bL,0x1c928f6eb43e89a9L,0xfdf28df3ae1ea1edL, + 0x62bba5b1b924b2b5L,0x491d27051a116e05L,0x08ec02b7167ed3e3L, + 0xe291cf7b5bc0b046L,0x30e501698c5d7f59L,0x0c7c350df5c799b7L, + 0x6862b9e20ac6e1d7L }, + { 0x56c6f4e79ffa1f64L,0xfed6a91aa1e24349L,0xe9a0ee0ccdb75232L, + 0xbfc90b370322d607L,0x29480ad2462fef87L,0xfc214969c2bfcf34L, + 0x6e5211e0a539e38fL,0x2a59ec2612a5149cL,0x195fe212d706b532L, + 0xf77fb108e99c8429L,0x74ceaea35dc80482L,0xa5a6030bbd92d298L, + 0xad42dca5aaea15eeL,0xd6ac3bc74987109cL,0xc64e1c40290af649L, + 0x5093fa2d51f8de6cL } }, + /* 216 */ + { { 0xc4cf32804c2d553bL,0xdc1abe223b966c29L,0x556a549c2296914aL, + 0xd8c9f8b5999976c9L,0xc22c57bd776e83f3L,0x4f2942ab7c85ec57L, + 0xef3407e56e2c61f5L,0xf005e8caf213db48L,0x470c853df32698c7L, + 0xe6f488d7cac0a54bL,0xb6bd6bed60b7501eL,0xf0103106714a4bd9L, + 0x5285bc3b6e098894L,0xec06741af5f92a00L,0x32f16426ef7ef24aL, + 0x12f9c44d6c77a438L }, + { 0x1951e96483313a1cL,0x98edd3da33c58b37L,0x4edbbf52c7ac4044L, + 0x866ca6f70dcb5ee8L,0xec0ae8f56dd422f8L,0x1077bc540661ec2eL, + 0x6d39913ad422523cL,0xd105e1e858e7cb3eL,0x47c9397fc979bb45L, + 0x3221d4a90997b592L,0x0ef628a3e8952fe7L,0xd08d58274e946241L, + 0x64cbed0f59780f40L,0x13d7c22708e110ecL,0xd186d8667679b1a3L, + 0x02f75e4e26ae1d18L } }, + /* 217 */ + { { 0x1b637ebf47f307d7L,0x6b644a6ad0141477L,0x82a33d652e05a80cL, + 0xc8f1a0f3fed07b31L,0xc09ee7f93696e597L,0xcdaa7ec3c7ffc01eL, + 0x549f88fef8f373b9L,0xc88d1961c3bb8989L,0xd92a4fe9dfcaa7b7L, + 0x12ff9ee23ae4ab20L,0xf5aea641f5ecb1a5L,0xe769237fe32fb47dL, + 0x96a5c42025d085c0L,0xdc91255826c755a2L,0x580b985f9bce9723L, + 0x72b1b56663961941L }, + { 0x9d708a08790e5558L,0x985360410689af80L,0xe85e7b8a42313b5fL, + 0xe6ba129255a49d1aL,0x5e76c4b0ac371b0bL,0x58504f39938e6e19L, + 0x8dd4142260ae9a21L,0xd8b04e9b968485ceL,0xf94c4ba5887efe43L, + 0x11268e67f11c5e73L,0x92623e28cf6b99c4L,0xf2d0aaa87a0a9662L, + 0xb266772a4ca02ed3L,0x68ee8e4e2d63b551L,0xcdebb2992e78b5b5L, + 0x5df19216e17225adL } }, + /* 218 */ + { { 0x20027e1e8df2e7e3L,0xb183cc68d8da07deL,0xce35ba694b4ae694L, + 0x896d97df3ca62e88L,0x3de4713b52efed2cL,0xd006c40e26bd084fL, + 0x1e9b71bbfc81923bL,0x9991c7b61aacc6b0L,0x650c93648f656840L, + 0x138561d187f47524L,0x610f2b11bffd3ca2L,0x96915faffa191418L, + 0x8f1236de955e5309L,0x613cbeeaa1872d79L,0x7f7b44ea66a2a48bL, + 0x452265c2e0a89c32L }, + { 0x4ad5ec7925430010L,0xcac786ffebd090c0L,0xa5f9f4ff20a9d3f5L, + 0xfcbf4112a3edc65fL,0x8824839c0cf3eb11L,0xb8dd6d4e8aa5b700L, + 0xe2271dfdb7568ab8L,0xe43ec373b744560eL,0x78eaf9261cf75296L, + 0x1809ae0e3fa96d9bL,0x0b312d2ddc25dfd5L,0x6b8f78b46bab7711L, + 0x069efc8db5ecf1e4L,0xc1952bae609fecaaL,0x43e302ed5f4dbde1L, + 0x14b02bf91e078555L } }, + /* 219 */ + { { 0x2c71c768b87e5b57L,0x0bcc78f7f531a557L,0x4ff93f8bf7597dc8L, + 0xb28e026d139e175fL,0x6b83b727cb94ca6cL,0x2eafe3b20079f7fcL, + 0x2aca54decf3bd170L,0x17c4133c6af0dc6cL,0xbea1e665ccf5e35eL, + 0xa6691a48345505c6L,0x2633abd0e6100b89L,0x966c6706c17d0388L, + 0x7aefffbe1a0cf90cL,0x4d847be7d0add64cL,0xd49bcdfbaea2aa46L, + 0x85e07e742cc7d0a5L }, + { 0x23aae0a60bc25bcaL,0x6e8e55f1e44f64ecL,0xe1e696d8b607b773L, + 0xaa90a746d3005909L,0x072b1ccd2cbc4990L,0x0d0fe6c6c68e2f5dL, + 0x920ec5f053e28ec9L,0x79b21fb4f0040cc1L,0xa7375bd3fcc4a2c7L, + 0xf5f5def9e1bac7ddL,0xdc315d7935c0f8d3L,0x7117c1702cacd318L, + 0x6f2823c4e926f71cL,0x38db58bbed02f39aL,0xe5b492317db69323L, + 0x0964039f8d49f430L } }, + /* 220 */ + { { 0x21774f1656999ebaL,0x3d8ee287b1de6305L,0xd81af726de0b2669L, + 0x374469393f8942a1L,0xbcf6b615ea03e13cL,0xd30c0c3594e273cfL, + 0x4fd33a56c6725c56L,0xa57534ada8be97a2L,0x799242a67c22a251L, + 0x4e51bdb59d0c5c49L,0xd7cd76ccc6a42768L,0x914097acd426bf59L, + 0x59404a2c66e9beb2L,0x4738fe985c96e3e9L,0xbcbb3e0eaad666d0L, + 0x626b0fd263bc5e56L }, + { 0x47217dbae1a1ec42L,0xaa6ae7dbab5acc50L,0xb7e1ab1e865331d1L, + 0xb84530703d30126fL,0x280649e0dee61851L,0x8806f4a3ea689544L, + 0x4bbe43adcb56f632L,0x036b9bdabcaff94fL,0x0d941e65bd0637beL, + 0x82179d44686f3abbL,0x1486912caad6afd6L,0x9a3b891eff7e1534L, + 0x88c426ceeb86fd96L,0xb56e6a81117928c3L,0x933e713596399e00L, + 0x09bbddd9a17b6ac1L } }, + /* 221 */ + { { 0x75e39c1de4fd3673L,0xf880d9d1a65c8e07L,0x4725c1dc7289c7feL, + 0x5b6735ee3529d200L,0xc1f8f2ed3c747af3L,0x5cf3998f912efdf5L, + 0xed72261849859c39L,0x23793a2f0e69795dL,0x8a6ab8d686b1d2a7L, + 0x00c815de22a882e4L,0xbe77d6fcf9db8d7eL,0x0886fb3202267547L, + 0xb62687d449c10edcL,0x9f1c3e177c83ed4cL,0xe6d5d7f05af366eaL, + 0x2eaa01b8d1efad24L }, + { 0x5e47fb701f357c74L,0x93085c4aa9e3b794L,0x4f0987336e85a905L, + 0xf53808ffbe0244c9L,0x91dddf93a3b5660dL,0x8b76377bf3b95ed6L, + 0x91b911b7bb3920d4L,0x7ccf08bf86a13cf3L,0x53ed8f97ea018e58L, + 0xb1ea434378c55194L,0x8e6adde9e0d2d5a6L,0xfc2b248f9b96259aL, + 0x96ebceaeeef17dddL,0xf694b443557f9c85L,0x48cd150f07d5bba8L, + 0x02d31de9b4c1986bL } }, + /* 222 */ + { { 0xa6bb9e1ede79499dL,0xf6ca8ff8fd0fc2adL,0xbec0f8e81a7d9356L, + 0xbc3d1c9fe8f06327L,0x805c72173b300bebL,0x00420a08413c181bL, + 0x9e9a167ef0ca9d01L,0x076c909d1aeeddd6L,0x64a1997f8e3a8a72L, + 0x3ce7f7a7a77b429eL,0xaac0fbf45c94d3e9L,0xf37694a7e6d48407L, + 0xf56679e2a91921e7L,0xf23fe0f3ee1dbbd6L,0xc7917566cbf9fa99L, + 0x965860f2e0f4d765L }, + { 0xe734702b7fa5f79cL,0x930bd4265af2d26dL,0x45bd8b986c73e0ceL, + 0x7dbe7bed4ee44a2dL,0xc129e024956c8a1aL,0x6fdc05ac77cdf80eL, + 0x70a6ba2b589ca59bL,0xfc484021999825afL,0x1d284b547a23f0b6L, + 0xb1da10a428a0a8afL,0xb1eb1b312b2af6d8L,0xf051443a33935ee3L, + 0x7a07eb268effa6ecL,0x16ee4086d662654cL,0x7a7bc5014549ee4cL, + 0x650810321fa98a52L } }, + /* 223 */ + { { 0x49f0e460b67ed9b2L,0x0cda0fd0c36d93d2L,0xbb5963e988c75e1cL, + 0x757bbe93614bc0c9L,0x9a9b88019a768605L,0xa8b7e2af48edc544L, + 0x9e77ed9eb51a5985L,0xdd025274ebbf024cL,0x598b62881545c636L, + 0x39bdaed04800dba0L,0x7fc2013981e2a23aL,0xdc66fd5c550cb4f2L, + 0xad27032fb52068c7L,0xc9a0bcae8169fa15L,0x60606f213a7ca8a2L, + 0x982950469862652fL }, + { 0x3e3746002e11c128L,0x80dfae5d0e6dca7eL,0xe44016e2d9552264L, + 0xf65f88f2880b7143L,0xca3d28d4526b881cL,0xf9c59dd1dfb86afeL, + 0x548860c24c74f958L,0xd06ea43c9cb69f4fL,0x5343c9ae7334ececL, + 0x5cc2ccd635329713L,0xa95ff4035f3a6c0cL,0x2e01a1ccb372653bL, + 0x31510fdfa250523dL,0xeee538e2a6227eb2L,0xeadfc8a0ca23cd10L, + 0x4b7e6e1b3e78f54bL } }, + /* 224 */ + { { 0x79c9076fdb5f928bL,0xe6250bb6b7347cecL,0x54b67798ac00ec41L, + 0x900d20ba9d9619c7L,0xed42c0d059e4343fL,0x3df39e85451935d7L, + 0x2639118264f701ceL,0xce8f2554e1f87aacL,0xfddd678965f91aaaL, + 0x96cd163fa324539fL,0x5c815f2c4bace995L,0xd78c8c2aa94f9ea5L, + 0x7ab2aff4ef24e455L,0xf0ed64091cddc26aL,0x954a420b00ca2822L, + 0x0611c4c5d3297658L }, + { 0xf192001ca9e81829L,0xded3332008a282ccL,0x0bfd7de18f9ded9bL, + 0x6793ac0db7889003L,0xbb00d91d3577a5ddL,0xe17a23a7802d3c2bL, + 0xff95f88cfb549014L,0x7cd1bf4bc71b6e07L,0x2e3b24a023588c8bL, + 0x9b5335b8a4112076L,0x2481c05ec4056d30L,0x55c7410ce916a1b5L, + 0xbbe03271850179f4L,0x15e6c177b3cd1208L,0x509a24c090cbfe50L, + 0x820795291c108566L } }, + /* 225 */ + { { 0x5d2d3cff1c7d353eL,0xd5e7eccd7de0ce3bL,0xb4b1075f6ca87635L, + 0xda8404e025f9ad3eL,0x6b963e89205cb5aeL,0x9e5ee0d809f221a1L, + 0xd64c85d9ea41aca4L,0x6a46c4e934442a34L,0xac6ff97e3cf655a4L, + 0x76565c1ee5417d7cL,0x681009a9eebf9c4cL,0x95b61d3988da6388L, + 0x6402b46af6b472c6L,0x1fde51650b7f1171L,0x94f8f273be0c05e3L, + 0x7487b036a88344a7L }, + { 0xa860e5759c3e2370L,0x19d58193f8048719L,0x3a0dbf3ca6e2f9aaL, + 0xb6c7e9596144719bL,0xa9049c74deffec21L,0x8ba064b23f50cebfL, + 0xb12822c049a1de15L,0xb654b7d9b1d527f2L,0xc470859d0ffd0430L, + 0x37c74a674f05446bL,0xe553251ba3add995L,0x4a3ed6cbe33533b5L, + 0x2f2f44d027e419ceL,0x2d84ee82a5d1b979L,0xcc76b123db6fa69fL, + 0x834f85c521fa3bddL } }, + /* 226 */ + { { 0x329347c12ce9b31aL,0x1d88522afe3fb3b7L,0x4bcefb4d52ff90fdL, + 0x53b173862b1a081dL,0x538c11ba2a411f08L,0x7895b93c141b603aL, + 0x2993b9aab10bd741L,0xccbbd04609912986L,0x669fafb0eea0aba5L, + 0xd484462235661897L,0x4a63b89c367ffa54L,0xcbad5d1d1c3478daL, + 0xc5339227aa6034f7L,0x0e6d705fe61b1391L,0xdd14b660f74ff515L, + 0x639d8b0a5332b54cL }, + { 0xfa423162162217cdL,0x2e0e4a2a811c28e6L,0x68d9ce1821766dc0L, + 0x51263739046a06efL,0x44eea231dde92101L,0x0607c8f2114298d3L, + 0x27f272ba63d957e9L,0xe7ce80cca5e8cae1L,0x5816ebe224f7a63fL, + 0x4dece5a789673e34L,0x13756a22536babd4L,0x644d61aee3bf77afL, + 0x60b2bf6e2bcf98bcL,0x3b0b59f329fa962cL,0xb0769a1aabb50023L, + 0x409031360c75402cL } }, + /* 227 */ + { { 0x84d2873a1670433fL,0xc9394df625493dfcL,0xeb05a19a80fcf89eL, + 0xe39e4310db297616L,0x50742dc9d9e63046L,0xf31ad8c81de9ca9eL, + 0x86aabf94fb7b1d0dL,0x36cda27a1b3c82d1L,0xfb1a2ef439702d84L, + 0x280bfddc46081299L,0xe4b2b48dd2396238L,0x2db2c2f37b3c9353L, + 0xd5b5b31712fb8a69L,0xf9b87a3b08180474L,0xd85909861e952578L, + 0x80668eedf37a2bc8L }, + { 0xe2edcd35b39a0249L,0xaf230cd4b2f8aeaeL,0x295b15e47223df05L, + 0xbb66982ae0e937f4L,0x019d2b728cbc9162L,0x5c512ae9cf49dca1L, + 0x11b491a7630f07b4L,0x48d4f34ca03874e9L,0xc1fd0ea644cb7433L, + 0x13f79ae1f95b30c3L,0x40362d4ded8b60acL,0x9e8314ff61ead81cL, + 0xed600dd4498c3d28L,0x5fcb1c19c2521702L,0x592329fc3a9c1f33L, + 0x046775481bde6ce9L } }, + /* 228 */ + { { 0xee3de56e39233c96L,0x868c409c80737eafL,0xacae11bd201abc68L, + 0x0f2cea9b2b486205L,0xe32387e16f19056cL,0xea75365aa5dc2a41L, + 0x76c29acc12b4be86L,0xa01fcab78d63294dL,0x81dbe88b0cab9f24L, + 0x76646e5bf414c054L,0xfe111893cb96b7aaL,0xb649f5b17664e097L, + 0xa196422e53fcf5a9L,0x5978c9bd0b7ff634L,0xb5feb38e3c229895L, + 0x038a49fb0833c456L }, + { 0x35e3818c13e93257L,0x14cebc9da612741bL,0x4f6e92497caac06bL, + 0x82278e333daa1116L,0xe7cc565e4de2034aL,0xbb7dc95f0a1ba630L, + 0x81dd9f2366956fbdL,0xc63e6319bb132dd6L,0x6e22b022fc241337L, + 0x238481937e8beb1cL,0x83b1994dd8c938acL,0xb54cfacaa6bb5644L, + 0x1a7cd44e06f91807L,0x1dd439bba8f8d9f3L,0x660c2a787f74a8e6L, + 0x4bb76e22121b5660L } }, + /* 229 */ + { { 0x7a151e8ae6354817L,0x33d494eaf038b438L,0x4c86c68885958986L, + 0x721538271dcbac12L,0xf487af8cc0edad06L,0xad33051fe500e5d6L, + 0x0a711b1bd6e47f55L,0xa68709a78c746ad5L,0x27f172626402f35eL, + 0xc6d08efafb30c130L,0x9ef1c041c06c7497L,0xd0c74ecedcc3e2daL, + 0x30c5f96e092e1073L,0x0f1393cf2aa12b74L,0x245840162107eb02L, + 0x8843d25f7b76f98bL }, + { 0x4e1501dcedb2a83eL,0xbcfe8fb02bb8d724L,0x09020659d925df62L, + 0x3c715dcf42ab6fc3L,0x73c05055a0f09dfdL,0x126745d8e3590aeaL, + 0x5382f4d876ff749eL,0xfc69feefa920c663L,0xde1602119fd711caL, + 0x4219c3bd9075c4d5L,0x3800cbd13ded6bf2L,0x8c7ea0eb6263a116L, + 0x35bd79587d264c37L,0x56e22e457159c98cL,0x71bf2a2dfa7373b5L, + 0x0503f9398935c949L } }, + /* 230 */ + { { 0x65addc6671dad4f6L,0x238e4889024bea1bL,0xfb76c8e2f605d3ddL, + 0x13d5f5deb0d96b89L,0xe0b5ba356601b2cbL,0xe37d491d83e3d254L, + 0xe8860423240c8ea7L,0x374182f3e91c99baL,0x26c2caf9a87ad919L, + 0x4b13040af574f295L,0x5b9bced1944000a3L,0x4ccc57be06df42e7L, + 0x22e8ec504bd1089dL,0x0c53177adddbb500L,0x690d31d29ecfeadbL, + 0x735778fe176668f9L }, + { 0x0f86ee3e843c1137L,0x3c1c42fa3f0b73cdL,0x0e75679d8ab20e3aL, + 0x6f95f1f416242faeL,0x7b88e11c39b092e4L,0x1629403e4c236ac0L, + 0x66105f412dac02e6L,0x74dc28a7862e0632L,0x2118ffb2f3b23c8dL, + 0x1182417c0745ffbfL,0x49b55a044c05711eL,0x2c665b74cefbe4deL, + 0x1cc4c01d97bf7107L,0xb2ca06dac54f0676L,0xfc599daa7450d0f8L, + 0x52e637a61a3182a1L } }, + /* 231 */ + { { 0x481700f16bebc6dbL,0x4a6b45dbf9503d92L,0xc715cd3c5d153919L, + 0x942a1c05e5ad2abcL,0x36a82433ab7b466fL,0xba413bedba13918bL, + 0x698a562490f4e6ceL,0xbb720da6f3f1f3caL,0x2116d41d63471ab3L, + 0xe00d2227303d3609L,0x7fd4cc00463ba69eL,0xac609e4d62845fd1L, + 0x63603b2c80adc9c7L,0xbf16fc9a45fafbcaL,0x41007f7fc4bc94abL, + 0x7c916b4fa74b1698L }, + { 0xc1026f9178bac2d4L,0x8a2e80982601a875L,0xad2f276e0073d640L, + 0x443610c4fcc1fb88L,0x5727b822ca6b291fL,0x0645532c88ec60fcL, + 0x51e48899ed9ad48bL,0x841b48b5f543f103L,0xa6ccb1bed591ceebL, + 0xfc4adf0f9dcf5a8bL,0x3a7ca020b347ddb4L,0xaa1accc2cb44c521L, + 0x773b68280527c0c4L,0xaa374c107023cf50L,0x733d10006b74c926L, + 0x1ff3916f77a8d07cL } }, + /* 232 */ + { { 0xaa218fe4f997939dL,0x3d4dfbbb791583b3L,0xb3a7b5da87f7560bL, + 0xa9c028015da92c98L,0xe1eb4aad46666f4aL,0x2eb17a5114ce9dd7L, + 0xf46a66a4ef8f3076L,0x900b45c6810e546eL,0xf7af22584baf04ddL, + 0x3cc1c8725c84d42fL,0x3093f2258e4c83deL,0x62fade41170d88b2L, + 0xe19612e4ac076e44L,0xf48d734632dd141bL,0xc1b1f759925e34daL, + 0x19ed1a56072b90c9L }, + { 0x9cf7fcde6c735473L,0xaab88e676003bc3eL,0x12187cbcfb199bb8L, + 0xbb7304419accccbdL,0x214aff3cb0f65459L,0x6aec81a36f926282L, + 0xaa82cb329f9d20b8L,0x82f3f90f5773cc90L,0x4af60e6bf62257e1L, + 0xf18b44bfbd4762dfL,0x3948b129db970753L,0xc6e920e97c22c18eL, + 0x393d620857be97adL,0xe8d7382c46b637f9L,0xf6625ccbf1fed1d5L, + 0x6f31e0f968681599L } }, + /* 233 */ + { { 0xc45afe5582b8f204L,0xac0441b6d358b54aL,0x7213e7bfacd5f5edL, + 0x1914c70b139bcd93L,0x714b458196dbcbb0L,0xe9297d351ed35d21L, + 0x8f6408376a3e1f20L,0x150a8a9d2f3cd705L,0xfb36e801dcdd9f6dL, + 0x5a54eb655cf56d82L,0x7610500c92aa5a21L,0xd10d0ae23b089f03L, + 0x491b2079c42b66e8L,0x4af1ae3d0eee8d48L,0x137e4c2841556f45L, + 0x875e330863d8a7e6L }, + { 0xdc80fddcaf6c0accL,0xd5ad1e66bb1e7c08L,0xdc717ae1828585adL, + 0xbdc54340275c7da6L,0xf4b4c852d26b9e15L,0x5f0a1fbf6a05fa50L, + 0xc6f81e47817bcb32L,0x2cbd432870ff2e1dL,0x8a24901667c7f7fcL, + 0xd045acb7b585a6c4L,0x2e972ad44666c057L,0xc74d87cfe6d7d63dL, + 0xf7067d870e274144L,0xb2ca157a8b2584aeL,0x495c5bfb75f0fdebL, + 0x5abb0581f386e009L } }, + /* 234 */ + { { 0x8be62d2bf0c97f57L,0x0fe04871962f28c7L,0xc548a46747b50abbL, + 0xf6b26e0344fa09edL,0xfd44c6e3ab05a96eL,0xedb0032c70e6ae82L, + 0x28bd402bd7e4899dL,0x43f2e9639b7c11c2L,0x0ec3fc0ece913716L, + 0x769b8bc902fd0f8cL,0x9d9cb3aa7cabc3acL,0xe88a889206924cc9L, + 0xa51461aa42609014L,0xc7f4aa8b962e79e0L,0x4ef0210a8b1b3e80L, + 0x705446801bfee4bcL }, + { 0xfab3d713121901c1L,0xe90a2627fead54aaL,0x64f6d285bc08ba23L, + 0x8d99301536ec227eL,0x99a16ab906c191abL,0x86b1cf5bf649ce2cL, + 0x5920675966be3a80L,0x18836279ccba2cf0L,0x2c157b87eff53486L, + 0xbfac98964b223af2L,0xcd0fd4f00aae7a57L,0xdaddb94063218a80L, + 0x3844bb79df88f14eL,0xc1b3e3d4b71ed9fdL,0x6c634a13d6205036L, + 0x6f56aecfb8680a6bL } }, + /* 235 */ + { { 0xb01dc803d9205c5dL,0x68955f7d67123929L,0x3debbffd9d9b6565L, + 0xb844395ed3b1acfeL,0x04328b216094eeffL,0x6631ffa822991febL, + 0x0dde66e6190dd075L,0x75b03c55e8577c05L,0x6c91ce5f91722407L, + 0x9a288a408ebb3a3fL,0x1d376f8a058a1396L,0xf3a594579a6e0676L, + 0x103029c57b71d288L,0x0843f428b44c30c0L,0xd8e6aff8730e0b9cL, + 0x7b6be8114ed644adL }, + { 0x3ec38e4a3d3aa54eL,0x10233943d83d509aL,0xf84aa621243955e2L, + 0x29104717f51d3d44L,0x62d2442c7eca4e37L,0x8c5a523d85fa55deL, + 0xc6f5ccda851da1b5L,0x044bcaa820001468L,0xf7501e68e01702e0L, + 0xf0819359e6a0acecL,0x33dda6adac0ef0b2L,0x97aeedc8fd964f01L, + 0x48dacd0e530b90d8L,0x4c5fad6fb84122ebL,0x2284ec1ed700a1deL, + 0x86f9a835dbca5474L } }, + /* 236 */ + { { 0x0e1d9055450cc69fL,0x50eb14bcc9edf98fL,0x1bb94e77ee7eba01L, + 0x5f7a6737998f8e53L,0x588384e31b16eef0L,0xbb928723d85c5e15L, + 0xfe51e345cbd952aaL,0xc5d0ee287e241674L,0xfdc146ef100182f0L, + 0x0f739e92e7f5be2cL,0x501ab3afb656bd3eL,0xb1552dde5168e289L, + 0x940dfe31b8ee104aL,0x42923603c4304475L,0x9306f114c460a913L, + 0x5bfa9faf03b51f86L }, + { 0x2a23f52c107b258eL,0x989e82bbd66341dcL,0x54a3ced8823cff1aL, + 0xf45b7794719b491fL,0x898c22182433dfb8L,0x0f9dd91cc49250eeL, + 0x50c2a2ae4fa17655L,0xf7aa1ce42c327f45L,0x13a15ad6583b1e41L, + 0x9aa0d5a5a1bfad9eL,0x9b1caa288e1fbdcdL,0xaf9283b6915f7f87L, + 0xc10e4e0c87e81a1eL,0x04fdca561080d296L,0x6acc961612755bd8L, + 0x1b1266aa828feedaL } }, + /* 237 */ + { { 0x4ebc0a00774ee49cL,0x776f6852cb6237d7L,0xfc0544ac5df938a3L, + 0xc3388ec8b6fbfbbdL,0x84ac8bcd745f2eaeL,0xa9c56609b1ece937L, + 0x656fb6ac7de8fa13L,0x5f8ded74a532b871L,0xab0d428baa889f09L, + 0x43b27f2810b7aec2L,0x26426e1efeecb34cL,0x44431b6b9e89c2dbL, + 0xaac4bc5d39211090L,0x926f73684fd81058L,0x452fa691471ef60eL, + 0x33517fdb218d7a23L }, + { 0xa9c33f46593c4a36L,0xac69d71836b1a9eeL,0x55a20c1d4277beecL, + 0x3e8ca24e7e4f179cL,0x57373369d46d88a2L,0x71ceb1cc730702f8L, + 0x8b184d9735eed574L,0x7f4517a20704cec2L,0x7f129d18d7062a53L, + 0x07a4571bb1d77e1cL,0x774ac3098350d8b2L,0x27b2919f61fab8efL, + 0xa7c4cc13b5dd801bL,0xe7e6255b1434591fL,0x349937b85a3592b3L, + 0x31fac63d30c77549L } }, + /* 238 */ + { { 0x2ee8cf1b04913fb6L,0x7e4013501769a6b3L,0x790ebb71783e61f0L, + 0x1e5107f9e27f2ffeL,0x124ba67fedaf89bfL,0x189200e1e58de68dL, + 0x962732a36df5abeeL,0x72cc37cfacbeb4aaL,0xb0c5fa96e93c5a76L, + 0x4c2a317cde63393bL,0x97f65e67830b2d6cL,0x4afc35041be5b96aL, + 0x0bf40a60730ce66dL,0x96a1ba799340d84fL,0x3ee1825407626b08L, + 0x01db35db7ab0cbf5L }, + { 0x6e0fbc2dac0efee2L,0x8406ebcdd71dbb45L,0xe72bde3e19b69abeL, + 0x49cb7e6137e01822L,0xcbb8c01c11458b4cL,0x420b4847687c5d63L, + 0x1847dfa1454c6776L,0xbede911dd1839d18L,0x1b9dc9c9278df046L, + 0x294bd62b881a336cL,0x7f09687993e77adcL,0x7ac9066543ce3ba7L, + 0x148695fd7764eefcL,0xe0c20f0b9ac465cfL,0x636e8d28a6e2cdb1L, + 0x7b6ba98cd755341dL } }, + /* 239 */ + { { 0xcb1d9e03c1881ab4L,0x19c25d55b3168c88L,0xa82d3d47282364ceL, + 0x95994390f161aa24L,0x7838bc00e1ebb2c9L,0x8fd5dfccbdec7a75L, + 0x4dd203c24ff7220aL,0x5ec173b30efeff48L,0x99f1d2b316428b35L, + 0xc06bd9e5056e813fL,0x929172bac0b319f1L,0x6ae0e384fd223b15L, + 0xbd01059e98d091edL,0x6b3168e4a654648eL,0x2211447f3375e798L, + 0x47e8101971eb4508L }, + { 0x7045d45abc8c290dL,0xa33d1355810fb33aL,0x2baf009246fbbf2fL, + 0xacff3f1b385c7cd9L,0xc5b150ece161985cL,0xc6ee0a7f2a888748L, + 0x9d888c8e5e88dcc8L,0x4dd735f2ccb86443L,0xcc1e13b73c40f6f2L, + 0xfc3a25fff3fed691L,0x4cb43b17257ee5c7L,0xaa654f93f32db135L, + 0x44f58d0a02dff2d3L,0x78e3f188a8ca6394L,0x39646ccef3e86697L, + 0x785b1902e0dce87bL } }, + /* 240 */ + { { 0xfcce2361a92f9a20L,0xb7bdca879d64540eL,0xd4739a851d00d7c5L, + 0x067ac8dc2e97c926L,0x2aea3ffe78da6a8bL,0x6828bf5463c51b69L, + 0x76f1c4797155141aL,0xf4bcbef63977d810L,0x75bc4949541bce7aL, + 0xe01f4066d17041a5L,0xd282d5bd87755eafL,0x6e2107dd59e7ae80L, + 0xaa56e166382ab36fL,0x65ee8ef6b9d1d634L,0x99a2160ace4ed844L, + 0x6557c367b7712c27L }, + { 0x561b0268d75b6e52L,0xb0813640118d0e89L,0xcff533306a2eb1aeL, + 0x4e4622266d090894L,0xbb351227b5fc1d48L,0x9365ea0757a3062dL, + 0x4caca37bd66e2dc5L,0x220d7d23b9095887L,0x9c0fd3938c4473bfL, + 0xadff370a6787da4fL,0xef0aebccd057f4b8L,0x205e744c1173f33aL, + 0xb8d1f0a5925a26b4L,0xa9364f49722fbbfdL,0xc891ae778227d284L, + 0x15c40d04a0e08ab4L } }, + /* 241 */ + { { 0x9baf169a2a0e18d1L,0x9971c0174c0327c2L,0xd81a323f7bc262ceL, + 0x2099db8d818ff379L,0x663f663d4cd3c330L,0xef5325c3011a0553L, + 0x9cd70bdcf980a470L,0xe64452d11c9ed070L,0xafbf43f4ac676e13L, + 0x97bec0a6ae85c2a5L,0x2faae550470490c4L,0x0ab97a87491e6ba9L, + 0x4055f537aafa9914L,0xfc95adbb36726557L,0x646343b9d119d6bfL, + 0x788e94a09d341e37L }, + { 0x053a6fe59c53461aL,0x75ec897e08e3b6edL,0xa8f5d2f30768d939L, + 0x9bd6bff6cc213d4fL,0x590c7b4105b0147cL,0x20a3628b7c7b8169L, + 0xc66a086e5bce78e9L,0x3dd4d2824dec1d8fL,0x890acf44c19dcce9L, + 0x6632d875d8435a7eL,0x590167c1ea6381b2L,0xb2259797f0dcc128L, + 0x91a612b446f8d463L,0x42185d78c15efa39L,0xdf55ec37119f6788L, + 0x91b19cc6780dea93L } }, + /* 242 */ + { { 0xebf2709dcb5d8b80L,0x03b96182fc35660eL,0xb873d991055ef969L, + 0xd1ea4b4de47c4342L,0xcc4b9244d54f8867L,0x93b1a2cafd8d77efL, + 0x068d24e7e8c1f563L,0x5f5fabb649973056L,0x83248c500542374fL, + 0xc36de2b53f38e913L,0xed07e8eb7bb680beL,0x964813d7d8f313b5L, + 0x7bb6a069afd2d392L,0xc06d848e0848a31aL,0x6867fb2fe4f0c325L, + 0x3c2ba834067343afL }, + { 0xab62d7759d3ad63bL,0x3f9cab9759e0eb1fL,0x70332a633885e117L, + 0xf22cafcee20b2f9eL,0xb529ba7e49eca947L,0x249542166228d88dL, + 0x80ea23ec39239561L,0x1b8907e7d4370644L,0x4b7fa455563e4e44L, + 0xcca9829eb2a4b0faL,0xd0a720a448060792L,0x8ccdda0c246991ceL, + 0x37a2325b348d086bL,0x566ed509f60aee13L,0x3d30e091147f253fL, + 0x1fa627a5c1073bd8L } }, + /* 243 */ + { { 0xa11222a242478fd4L,0xacf4c6f1670b2000L,0xf71bb04f8359c6deL, + 0x618e28297b93cdbcL,0x96e1bae3230db60bL,0xf17fd3b4965b3b29L, + 0xa58639c6bc7055ddL,0xc3ea92ed4b817d7fL,0x9082b2a6d23b08a4L, + 0x8471228adc17010eL,0x753b9e4620e89d97L,0xcf7e4f9703ff77c9L, + 0x6c3f82452bbe60e5L,0x9e432cbcb80e017dL,0x150a5acdc0a45edbL, + 0x67b8bd054798743eL }, + { 0xe66079b4f4797cf7L,0xe31c998ad03fde02L,0x5aa3763a54caaef1L, + 0x64d9a1fef7649711L,0x7ce0dc73af29b1a7L,0x6661b083fb66ca93L, + 0xbf4d74fe32fb6a78L,0x25f6ef09df00a561L,0x2bc4383f831d1159L, + 0x6d5cc10c536bde37L,0xd4945f9f882cc65bL,0x81f48f13451a99b8L, + 0x140161cd6bac11a4L,0x9d94d4edf18a4a0aL,0x65363165a467a824L, + 0x74297aa9a4c9aedfL } }, + /* 244 */ + { { 0xc49758a4e21124baL,0x99bd8198a87ffbd2L,0x45fbcdd13d6638a8L, + 0x94645ff815f7bf76L,0x5fa6736fc4e6d57eL,0x1eae647592e61db9L, + 0x79575c0ccbdf944aL,0xa3d1304725b31d74L,0x7881df224cab5ae6L, + 0x8dbfd2991a2887f2L,0x23d07590a26ac459L,0x2e589852d8661d4aL, + 0x37b5c13b8a0140f7L,0x0f94199e3fb3782aL,0x722aa0591bc14e90L, + 0x89aab7bad55bbb12L }, + { 0x8b345a96d656bdc7L,0x43bdc8afe176cd3bL,0xd69518b632d64c43L, + 0xfcf364a779b82b41L,0x907b344effb0cf82L,0xf3d0c83c5101287bL, + 0xe9f26a5934cd90efL,0xe5f5aaf207082b5cL,0x4eb72c75ece7c165L, + 0xe9590a81be986cd6L,0xfeef498fff1536aaL,0x04560243a8263d5eL, + 0x940be14f54ae872bL,0xbee7bcc9e3207686L,0xd496a27dc1bc4d7aL, + 0x002dc2975940ab46L } }, + /* 245 */ + { { 0xee533937b69d60c3L,0x260be552fe972755L,0xb11fb78dc0c725a6L, + 0x6982c27ecab2e7c2L,0x4bceedd9ee2322cbL,0x952b19ed122704f7L, + 0x2df4c285854a6165L,0xba40b5bf7b192485L,0xfcbca9500119f52aL, + 0x7467d1cbe5add86fL,0x9bf536fbd9d0f2c1L,0x3c296e34b8d4ebc9L, + 0x0495f8f405a81317L,0x8c59e8d673335f76L,0x0b53d324e0542122L, + 0x4d5645353c3bda73L }, + { 0x7322f8007e5c0877L,0x481b43e60ca9a764L,0x231f4f4ba2c12716L, + 0x09596857ed3136c2L,0xae82632238db30deL,0x652fad4099908ebcL, + 0x0b8d1814af0d231eL,0x2680c54b09cbc349L,0xfd4562f34bf3bf8eL, + 0x2985090b092b595fL,0xe6f39ca45e15fc34L,0x70175191bc378168L, + 0x906944b3845a4a87L,0xacc6d74a82a1541aL,0xadc9bab3b155c8b4L, + 0x1f2f89ce77306c62L } }, + /* 246 */ + { { 0x8253ef419affefdfL,0x05d7ece54cf9256bL,0x377002f2b444e483L, + 0xb189755fcba5471fL,0xc88483cbd5cbe015L,0x254f7c696a0b8429L, + 0x18850bd461f3f61dL,0x7ba210890a247157L,0x35abbc2ed92eeb0dL, + 0xfb56cabe965dec89L,0x9da23724bc55684aL,0xd8ba396f6a7a7492L, + 0xfcb90db72ef4ba46L,0xdd234fe09909b27aL,0xbdf3c16476f4366eL, + 0x09c8097f17e50d47L }, + { 0x6a04b14060050c07L,0xc29e831843a8e37eL,0xcb9429b2bb55e41fL, + 0xed2fea5a2ce60e3aL,0xdc7b1ff3db9d82f4L,0x48ebecc3687d37faL, + 0x79153e32ecb07539L,0x6a60054f57075692L,0x3871cd0c800759baL, + 0x17a7386f30922df1L,0x4e9fc59e83357b7cL,0x1d26b3a939415186L, + 0x912a0222d34db889L,0x6672fcf459fcdb71L,0x5a3f268d44ff3036L, + 0x6f113ed36911e16cL } }, + /* 247 */ + { { 0x52a9df591836f1c9L,0xfa6519f54232307dL,0x8406c7015ded285aL, + 0x0a1545caaf627f75L,0xae1111eeace0417dL,0xfb28bdf6a6113443L, + 0xde9ef0ab52dbcbcbL,0xe9dc181b7813e658L,0x0b1dabdb99127225L, + 0x5f0598e322814c59L,0x5c3b966ed934ee7eL,0x4eb84edab99ba4bfL, + 0xb2919a343c1b55e7L,0xa9addb4994aa860fL,0x1b7220dff6811ff6L, + 0x6636a23bd1a183e2L }, + { 0xdf5d5a2d20587283L,0x0b3822c9ef07fc5dL,0x1786bd550ef6de38L, + 0x163cf90725d1671dL,0x74bf971f1cdb1defL,0x5749e8300842fc4aL, + 0x0e2edbc727f854f7L,0xbb27bbdabce24acbL,0xc1b19cec05bed08dL, + 0xaada123ef7c904bcL,0x02429f1bd89982dbL,0x49d3616e65f6e632L, + 0xa3789fa8ee59fd32L,0x160ba3bafe9f29f5L,0x0f2d3b61af5378a0L, + 0x7aeecc7673c2a6f8L } }, + /* 248 */ + { { 0xf3a4757cdc43b0dbL,0x3d8a4e8598119cadL,0xf8095bf64616c156L, + 0x3e2a07bc4f533e97L,0xa982436739cfc5adL,0x18a6ba3acd68052cL, + 0xbd60e5908a1cec66L,0xae3841a502b1b695L,0x986dff12190a195bL, + 0x2df2beacad31fd9bL,0x7d893224cc728f7bL,0xc38ea7380cf0a992L, + 0xa8439a80586a44eaL,0xede7f7f01615f03cL,0x4824990827a1f885L, + 0x28ec4006b78a7645L }, + { 0xe1820c2ea2fe0009L,0xe11ba5d2f13874e9L,0x97522454c524db52L, + 0x4d4774267fede529L,0x01d3419a9b2500d4L,0xce08a4921869244bL, + 0xba169023dd1be1b9L,0x242c3e5432a301e0L,0x9b56f7ba70906788L, + 0xf0ad2a09c74a8cc4L,0x99cd1841d76f9439L,0xeddafe0b621fb60eL, + 0x056bee54bc397634L,0x4653f860ff7f0a84L,0x6bd4876f2011c0afL, + 0x134f4cc70c9525c3L } }, + /* 249 */ + { { 0x9621a3ece938dff4L,0x7d101a7b486a79a3L,0xf2c4ef97de950537L, + 0xf3184099e65d87dbL,0xb89c7ffb373b8cfaL,0x68baa505e842916eL, + 0xa790fd094ebea764L,0x679df6d4e592892bL,0x2023331cfcfed741L, + 0x0bf4efd29880ff21L,0x7ca78dddd0344501L,0x2cb09ecb342858c8L, + 0x9e5eb6dc2575487aL,0x50675a15ebcb0491L,0x09d2e74f7381d471L, + 0x6ea3782983d3d6f4L }, + { 0xc65c094b4e5cc40aL,0x7a2e3f6a1af37dfbL,0xef677e9df9026e44L, + 0xb7878c9593880f53L,0x4aa30b077f644aa9L,0xa0c516832f208c3cL, + 0x7c0277ae658d663bL,0xef0b3c38ae1d9130L,0x302f37a7695c3ea4L, + 0xe004c1c56a0c5e0dL,0x9fd495c420cbcf9fL,0x706d5b9d568a0e7cL, + 0x8b225dff59286454L,0x527d44658d9a709cL,0x47c558da87c08d68L, + 0x606ee6e6bb4ef07dL } }, + /* 250 */ + { { 0x02d99fc757c621f6L,0x292e40c17fe83d48L,0x1bdfc7a19ef199b0L, + 0x78a04102e62c7666L,0x16cda370e6738753L,0xbc81974d1e3a65afL, + 0x19742048f78fe209L,0xc83a058abf5981c6L,0xf26b24349c89702dL, + 0x988b2f1e9d1a678aL,0x472bf9b0ff29ae29L,0xa143e3981d7cf5ecL, + 0x9c9d7e45b268ddd8L,0x166cda555fc4ff76L,0x6044cdf0a4aa7673L, + 0x49dba6f7e9148707L }, + { 0x20e47fb2a758e37aL,0xaf6b31d72d8eaf66L,0x352ad5f96f9c2210L, + 0x0093f72790efc32bL,0x435c99dc41e4b264L,0xbfa878e005b15795L, + 0x99c520a40e673575L,0xca68259487eea759L,0x029f7b81f12a348bL, + 0xa547cc182aa2ce35L,0xa11d874bead5e2c5L,0x9af0349b55682cdfL, + 0xf86ebfea8bbe8e66L,0x3dab8782f55394abL,0x458bf797ebc8eb8fL, + 0x4890a7a49b7de78cL } }, + /* 251 */ + { { 0xd72996898da995f6L,0xd39eaae7ec6156efL,0x6959040c356a82d5L, + 0xb2046b21c135bcfeL,0xea720b640f595c78L,0x02824efae7c5fb40L, + 0x97d8fd4c0edb3bfcL,0x12f0290579f24ebeL,0x16fc47cf187ea6b9L, + 0xc219fd27789d5c23L,0x233a6b6c89263eccL,0x823634b28b6d30a6L, + 0xca352e25c9b33680L,0x9388d6ca40c77456L,0xf8e55b0b3c92065bL, + 0x5c17474b02439a76L }, + { 0xd888e7c28aaccab5L,0x18027836aaced05bL,0x185b877dccec0f65L, + 0x93cadc1c125c2882L,0x45df540a67fdc54cL,0x4f3c86e2c2788a33L, + 0x3e874469e3a0fa2cL,0xc59daa47273983cfL,0x3063c48b4a96d8a5L, + 0xc38d2bcfc2e58915L,0x90e78b8784e428c3L,0x900a292cf0c4fd53L, + 0xb7f92db7941e6005L,0x956792416ca53a1cL,0x35f6f31db1ab0fa7L, + 0x5d675eb47b58408cL } }, + /* 252 */ + { { 0xaeee1a77870c6025L,0xfc4a23b791a2dfcaL,0x7b0e60c4386b64c4L, + 0xd5d5b17de5ae72b1L,0x6dfc88ac9eefa212L,0x4feaefbed4038b96L, + 0x099ac3568e2d2eccL,0x548ea612012af207L,0x4ffed9db89c31218L, + 0x1c1e91c4e0e67331L,0x009bb64faf8300e0L,0x8780501c6773c3beL, + 0xe0cd6edec08219faL,0x7c055e07f81b06ffL,0x82b63f9ce080b36fL, + 0x02fccbaf0a9feca3L }, + { 0x9991d4d1b47cac61L,0x2e9d1687ab86e12cL,0x8c6855ec2b94f042L, + 0xca40051948e648e5L,0x9ba91fb2ef89ac57L,0x4f4192061be792cdL, + 0x82d221cbbd0f1e15L,0x062eb13bfc444019L,0xf3a97c3299790fdcL, + 0x4e796d946067a64bL,0xc46dd3006d23775aL,0x8672c4d5ed7f0f23L, + 0x821851dc3b4f63d7L,0x50a3ae0cd26273f2L,0x800e58fceac60f6fL, + 0x56f1e45613845545L } }, + /* 253 */ + { { 0x01ccb3f632c24f3bL,0x99eb1c7f06d817e6L,0x8dc640bb6aa26776L, + 0x7838affe0845d5e0L,0xf34fecb1f81a79a8L,0x6a2e282d3e6819b0L, + 0xc4b977ce8237a4b8L,0x0f46b3db87636439L,0xa465f54097970497L, + 0xd7e087628791be43L,0x00220b6c34198ec6L,0x57b38637093d94bbL, + 0x84012e1629d690b2L,0x02ec9db520aad1a4L,0xafee2fc685dc34e3L, + 0x911d193625500cf8L }, + { 0x13b1bd58f5e5af5bL,0xa7ca263b7b6a22a7L,0xab6bec4df3af2adcL, + 0x16651e59a04420bdL,0x3b448b3b4ba36c11L,0x3c62bfcdff424310L, + 0xde15c4a5f1a96cbbL,0xbe0ad8a1e4d1f980L,0x812bd14e36673a3aL, + 0x40303af69212acddL,0x8f6dab9c576095ceL,0x7df1882a107f5ca5L, + 0xb903e63c8896a3b0L,0xf5048544d863b3f0L,0x5e5019b9c09887deL, + 0x2be744fea0f53865L } }, + /* 254 */ + { { 0x054cd05f5b50f324L,0xb9b1eb241ea3c7a2L,0x4a858a5c7ff8e6b7L, + 0xd83902feec040882L,0x72b26494d0cba9bdL,0xd0176f90b29c9e1eL, + 0x05d4eb02cebadb81L,0x874405b1372b8bfcL,0x5c41288179ead190L, + 0xd44a3dd3ec2b48cdL,0x84499a773f4d5033L,0xb37b38cd564c3a09L, + 0x80e99497f42e803bL,0xc07b47a0b8f518b2L,0xc710e3c53568fde4L, + 0x735f542fcead0e7aL }, + { 0xcaa9a17138380039L,0xadfafe17f74d19c8L,0x92d4393eccbc1a8bL, + 0x3c5dbf39fe029705L,0x4552b5ab930e9b36L,0x7ee630322afd494aL, + 0x826a9ad73f02ac43L,0x98c5356299356298L,0x0c869f877342bb39L, + 0xd7510020e4f9b79aL,0x6361d1a4d34789a9L,0xf0ded5bacfa85637L, + 0x407ee73f88ac07e4L,0xfac7d03f09ef1cbdL,0x25d697cb4d475badL, + 0x1e984c9d14bd399eL } }, + /* 255 */ + { { 0xc76d05614850c817L,0xb08a5b193489812dL,0x7273d1545e58cbbeL, + 0x8900b5fa4be61e5aL,0xaa088691d7aeb8e1L,0xe66666afd35a3d4bL, + 0x38a2c19957ec7d3dL,0xa0648e8f668d6f5cL,0x1f9fc92c7adc1746L, + 0x23a116c0843065c3L,0x36370a2061e6ae69L,0x626c37362aa47e73L, + 0x540c25f2deff6d84L,0x9804824ccdbed2d4L,0x4b5bfce0039a9492L, + 0x6c474a5676942e01L }, + { 0x3aeb9a417d88e3a1L,0x105d3c88c484742aL,0xe59de8d13fe61131L, + 0x148f5b6b1a869e8bL,0x7a8abc59aa75d90aL,0x2f0c9bc762146013L, + 0x43faa747c3824cd9L,0x81763a186a5d0b92L,0xbbc341bc9bcbaebcL, + 0xe1813160f745d1ddL,0xa53ce52db75ce5f4L,0x15eae66cd50de4c2L, + 0x5ed8996c75d7656dL,0xe4ff5711c4ca552aL,0x215e985a3c5305b4L, + 0x6b258954fa1ba2ceL } }, +}; + +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^128, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_base_16(sp_point_1024* r, const sp_digit* k, + int map, int ct, void* heap) +{ + return sp_1024_ecc_mulmod_stripe_16(r, &p1024_base, p1024_table, + k, map, ct, heap); +} + +#ifdef HAVE_INTEL_AVX2 +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * Stripe implementation. + * Pre-generated: 2^0, 2^128, ... + * Pre-generated: products of all combinations of above. + * 8 doubles and adds (with qz=1) + * + * r Resulting point. + * k Scalar to multiply by. + * map Indicates whether to convert result to affine. + * ct Constant time required. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_1024_ecc_mulmod_base_avx2_16(sp_point_1024* r, const sp_digit* k, + int map, int ct, void* heap) +{ + return sp_1024_ecc_mulmod_stripe_avx2_16(r, &p1024_base, p1024_table, + k, map, ct, heap); +} + +#endif /* HAVE_INTEL_AVX2 */ +/* Multiply the base point of P1024 by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_1024(const mp_int* km, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_digit kd[16]; +#endif + sp_point_1024* point; + sp_digit* k = NULL; + int err = MP_OKAY; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + + err = sp_1024_point_new_16(heap, p, point); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 16, km); + +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + err = sp_1024_ecc_mulmod_base_avx2_16(point, k, map, 1, heap); + else +#endif + err = sp_1024_ecc_mulmod_base_16(point, k, map, 1, heap); + } + if (err == MP_OKAY) { + err = sp_1024_point_to_ecc_point_16(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_16(point, 0, heap); + + return err; +} + +/* Multiply the base point of P1024 by the scalar, add point a and return + * the result. If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * am Point to add to scalar mulitply result. + * inMont Point to add is in montogmery form. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_base_add_1024(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_point_1024 a; + sp_digit kd[16]; + sp_digit t[16 * 2 * 5]; +#endif + sp_point_1024* point; + sp_point_1024* addP = NULL; + sp_digit* tmp = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + + err = sp_1024_point_new_16(heap, p, point); + if (err == MP_OKAY) { + err = sp_1024_point_new_16(heap, a, addP); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * (16 + 16 * 2 * 5), heap, DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + else { + tmp = k + 16; + } + } +#else + k = kd; + tmp = t; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 16, km); + sp_1024_point_from_ecc_point_16(addP, am); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_1024_mod_mul_norm_16(addP->x, addP->x, p1024_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_1024_mod_mul_norm_16(addP->y, addP->y, p1024_mod); + } + if ((err == MP_OKAY) && (!inMont)) { + err = sp_1024_mod_mul_norm_16(addP->z, addP->z, p1024_mod); + } + if (err == MP_OKAY) { +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + err = sp_1024_ecc_mulmod_base_avx2_16(point, k, 0, 0, heap); + else +#endif + err = sp_1024_ecc_mulmod_base_16(point, k, 0, 0, heap); + } + if (err == MP_OKAY) { +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_1024_proj_point_add_avx2_16(point, point, addP, tmp); + else +#endif + sp_1024_proj_point_add_16(point, point, addP, tmp); + + if (map) { +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_1024_map_avx2_16(point, point, tmp); + else +#endif + sp_1024_map_16(point, point, tmp); + } + + err = sp_1024_point_to_ecc_point_16(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_16(addP, 0, heap); + sp_1024_point_free_16(point, 0, heap); + + return err; +} + +#ifndef WOLFSSL_SP_SMALL +/* Generate a pre-computation table for the point. + * + * gm Point to generate table for. + * table Buffer to hold pre-computed points table. + * len Length of table. + * heap Heap to use for allocation. + * returns BAD_FUNC_ARG when gm or len is NULL, LENGTH_ONLY_E when table is + * NULL and length is returned, BUFFER_E if length is too small and 0 otherwise. + */ +int sp_ecc_gen_table_1024(const ecc_point* gm, byte* table, word32* len, + void* heap) +{ + int err = 0; +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; +#endif + sp_point_1024* point = NULL; + sp_digit t[5 * 2 * 16]; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + + if ((gm == NULL) || (len == NULL)) { + err = BAD_FUNC_ARG; + } + + if ((err == 0) && (table == NULL)) { + *len = sizeof(sp_table_entry_1024) * 256; + err = LENGTH_ONLY_E; + } + if ((err == 0) && (*len < (int)(sizeof(sp_table_entry_1024) * 256))) { + err = BUFFER_E; + } + + if (err == 0) { + err = sp_1024_point_new_16(heap, p, point); + } + if (err == 0) { + sp_1024_point_from_ecc_point_16(point, gm); +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + err = sp_1024_gen_stripe_table_avx2_16(point, + (sp_table_entry_1024*)table, t, heap); + else +#endif + err = sp_1024_gen_stripe_table_16(point, + (sp_table_entry_1024*)table, t, heap); + } + if (err == 0) { + *len = sizeof(sp_table_entry_1024) * 256; + } + + sp_1024_point_free_16(point, 0, heap); + + return err; +} +#else +/* Generate a pre-computation table for the point. + * + * gm Point to generate table for. + * table Buffer to hold pre-computed points table. + * len Length of table. + * heap Heap to use for allocation. + * returns BAD_FUNC_ARG when gm or len is NULL, LENGTH_ONLY_E when table is + * NULL and length is returned, BUFFER_E if length is too small and 0 otherwise. + */ +int sp_ecc_gen_table_1024(const ecc_point* gm, byte* table, word32* len, + void* heap) +{ + int err = 0; + + if ((gm == NULL) || (len == NULL)) { + err = BAD_FUNC_ARG; + } + + if ((err == 0) && (table == NULL)) { + *len = 0; + err = LENGTH_ONLY_E; + } + if ((err == 0) && (*len != 0)) { + err = BUFFER_E; + } + if (err == 0) { + *len = 0; + } + + (void)heap; + + return err; +} +#endif +/* Multiply the point by the scalar and return the result. + * If map is true then convert result to affine coordinates. + * + * km Scalar to multiply by. + * gm Point to multiply. + * table Pre-computed points. + * r Resulting point. + * map Indicates whether to convert result to affine. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_mulmod_table_1024(const mp_int* km, const ecc_point* gm, byte* table, + ecc_point* r, int map, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 p; + sp_digit kd[16]; +#endif + sp_point_1024* point; + sp_digit* k = NULL; + int err = MP_OKAY; +#if defined(HAVE_INTEL_AVX2) && !defined(WOLFSSL_SP_SMALL) + word32 cpuid_flags = cpuid_get_flags(); +#endif + + err = sp_1024_point_new_16(heap, p, point); +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16, heap, DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_1024_from_mp(k, 16, km); + sp_1024_point_from_ecc_point_16(point, gm); + +#ifndef WOLFSSL_SP_SMALL +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + err = sp_1024_ecc_mulmod_stripe_avx2_16(point, point, + (const sp_table_entry_1024*)table, k, map, 0, heap); + else +#endif + err = sp_1024_ecc_mulmod_stripe_16(point, point, + (const sp_table_entry_1024*)table, k, map, 0, heap); +#else + (void)table; + err = sp_1024_ecc_mulmod_16(point, point, k, map, 0, heap); +#endif + } + if (err == MP_OKAY) { + err = sp_1024_point_to_ecc_point_16(point, r); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_16(point, 0, heap); + + return err; +} + +/* Multiply p* in projective co-ordinates by q*. + * + * r.x = p.x - (p.y * q.y) + * r.y = (p.x * q.y) + p.y + * + * px [in,out] A single precision integer - X ordinate of number to multiply. + * py [in,out] A single precision integer - Y ordinate of number to multiply. + * q [in] A single precision integer - multiplier. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_mul_qx1_16(sp_digit* px, sp_digit* py, + const sp_digit* q, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 16; + + /* t1 = p.x * q.y */ + sp_1024_mont_mul_16(t1, px, q, p1024_mod, p1024_mp_mod); + /* t2 = p.y * q.y */ + sp_1024_mont_mul_16(t2, py, q, p1024_mod, p1024_mp_mod); + /* r.x = p.x - (p.y * q.y) */ + sp_1024_mont_sub_16(px, px, t2, p1024_mod); + /* r.y = (p.x * q.y) + p.y */ + sp_1024_mont_add_16(py, t1, py, p1024_mod); +} + +/* Square p* in projective co-ordinates. + * + * px' = (p.x + p.y) * (p.x - p.y) = p.x^2 - p.y^2 + * py' = 2 * p.x * p.y + * + * px [in,out] A single precision integer - X ordinate of number to square. + * py [in,out] A single precision integer - Y ordinate of number to square. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_sqr_16(sp_digit* px, sp_digit* py, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 16; + + /* t1 = p.x + p.y */ + sp_1024_mont_add_16(t1, px, py, p1024_mod); + /* t2 = p.x - p.y */ + sp_1024_mont_sub_16(t2, px, py, p1024_mod); + /* r.y = p.x * p.y */ + sp_1024_mont_mul_16(py, px, py, p1024_mod, p1024_mp_mod); + /* r.x = (p.x + p.y) * (p.x - p.y) */ + sp_1024_mont_mul_16(px, t1, t2, p1024_mod, p1024_mp_mod); + /* r.y = (p.x * p.y) * 2 */ + sp_1024_mont_dbl_16(py, py, p1024_mod); +} + +#ifdef WOLFSSL_SP_SMALL +/* Perform the modular exponentiation in Fp* for SAKKE. + * + * Simple square and multiply when expontent bit is one algorithm. + * Square and multiply performed in Fp*. + * + * base [in] Base. MP integer. + * exp [in] Exponent. MP integer. + * res [out] Result. MP integer. + * returns 0 on success and MEMORY_E if memory allocation fails. + */ +static int sp_ModExp_Fp_star_x64_1024(const mp_int* base, mp_int* exp, mp_int* res) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td; + sp_digit* t; + sp_digit* tx; + sp_digit* ty; + sp_digit* b; + sp_digit* e; +#else + sp_digit t[4 * 2 * 16]; + sp_digit tx[2 * 16]; + sp_digit ty[2 * 16]; + sp_digit b[2 * 16]; + sp_digit e[2 * 16]; +#endif + sp_digit* r; + int err = MP_OKAY; + int bits; + int i; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8 * 16 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + tx = td + 4 * 16 * 2; + ty = td + 5 * 16 * 2; + b = td + 6 * 16 * 2; + e = td + 7 * 16 * 2; +#endif + r = ty; + + bits = mp_count_bits(exp); + sp_1024_from_mp(b, 16, base); + sp_1024_from_mp(e, 16, exp); + + XMEMCPY(tx, p1024_norm_mod, sizeof(sp_digit) * 16); + sp_1024_mul_16(b, b, p1024_norm_mod); + err = sp_1024_mod_16(b, b, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(ty, b, sizeof(sp_digit) * 16); + + for (i = bits - 2; i >= 0; i--) { + sp_1024_proj_sqr_16(tx, ty, t); + if ((e[i / 64] >> (i % 64)) & 1) { + sp_1024_proj_mul_qx1_16(tx, ty, b, t); + } + } + } + + if (err == MP_OKAY) { + sp_1024_mont_inv_16(tx, tx, t); + + XMEMSET(tx + 16, 0, sizeof(sp_digit) * 16); + sp_1024_mont_reduce_16(tx, p1024_mod, p1024_mp_mod); + XMEMSET(ty + 16, 0, sizeof(sp_digit) * 16); + sp_1024_mont_reduce_16(ty, p1024_mod, p1024_mp_mod); + + sp_1024_mul_16(r, tx, ty); + err = sp_1024_mod_16(r, r, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + return err; +} + +#else +/* Pre-computed table for exponentiating g. + * Striping: 8 points at a distance of (128 combined for + * a total of 256 points. + */ +static const sp_digit sp_1024_g_table[256][16] = { + { 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, + 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, + 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, + 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, + 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, + 0x0000000000000000L }, + { 0x170a46d2335c1685L, 0xeac9e971e1007a58L, 0x40e8f3df43ca4a73L, + 0x2646f81582642475L, 0x3af49bb4b36576d1L, 0xd89e2d1472bf1afbL, + 0x27be882c2fd151e6L, 0xaddedc858f88717cL, 0xd6d859bf16ac6c6fL, + 0x0e741a1b2d8eae58L, 0x6faf7a0061c1f30dL, 0x66dbd09a9b67e096L, + 0x21f11c067d3b4f7dL, 0x6152ba02c727c98eL, 0xafd58891e86cb221L, + 0x59e93c6a6bd3baf4L }, + { 0xe54dd36f71dd4594L, 0xbbc9cc9f00aef1e6L, 0x9ea5a44ea19f6530L, + 0x8588aa993f520928L, 0x9753794c8f5c1418L, 0x118bd792c11399faL, + 0xb9bd3afdf5cb6ab5L, 0x813d1cb22ecb9652L, 0xfd45626740389813L, + 0x51f7119b4ac8431cL, 0xdd9f6a910a180eb6L, 0x13946d179f7bfa2eL, + 0x16f1863150a9d0d9L, 0x5f19c20d6f8373d3L, 0xbe85ac6a9b6a52b9L, + 0x63ef187b74f62e03L }, + { 0x7c376b7f016f45e7L, 0x1c1bdb572bec82f8L, 0x7392f741ce429b60L, + 0x6fdbf0a2c7afd81dL, 0xbda41b1f7241098bL, 0x5b407474bb60f8cfL, + 0x933e0d41b330bc4dL, 0xae182830733fa3beL, 0xa0ed299b0f5c6cd1L, + 0x7ff3354e3f9860c8L, 0xb136098615559c41L, 0xab0cb63c129f85cbL, + 0x682ecc4947685fbeL, 0x505e8ec2eb199633L, 0x90dcc794ddac2cdaL, + 0x4fe6791cf192da23L }, + { 0x94a423d505e8733cL, 0xcc845e651d5717c1L, 0x237c7e88e961b322L, + 0x0c4471c6db4181ccL, 0x00c875e2713bd721L, 0x9dfde9edb2c17b09L, + 0x430a6de5e88ceaf6L, 0xaaa7a61a7b81cea6L, 0xea52d026233f98d5L, + 0xb55efdd060689a9aL, 0x30cfa7ce5cac4aabL, 0xfa4db1148e950761L, + 0x309570c44e9a1e52L, 0x18c21f611a040170L, 0x555d1ffebe78d9d2L, + 0x04482a18561db297L }, + { 0xe7758ac273d486d8L, 0x8169f94661cdc1e7L, 0x723c99fc2188ab4fL, + 0xa0e54f02f3373630L, 0x560bee25bd8c2260L, 0x28fc307c4531bc60L, + 0xd6f21f1a7e44feb5L, 0xc8e4499c57128d37L, 0x963b053ed7b2ea45L, + 0x40c27a0432a3d222L, 0x5b51854d35459668L, 0x66e1a49fd73557e9L, + 0x0d267fd98692077aL, 0xfa1350d3e7342702L, 0x1a9c3f2568ccdb44L, + 0x833a0ff8dedbf89fL }, + { 0xa8c419c7ab376b76L, 0x3b7294f327d0f0ccL, 0xe56bb9e2a90c514dL, + 0x931ba51ea62575a6L, 0x56fee07b098c0a88L, 0x04be5aeeb4c16a2aL, + 0xe513350be6eb260bL, 0x339edad6a1d5c270L, 0xf366ed59e9dbadd1L, + 0x4213be882dd06ec0L, 0x22d639c8cb1187dbL, 0x1fec95e1d8a1058aL, + 0x03f73ea6a2b744f1L, 0x741fd51af4f05c0cL, 0x2e2df95a85f811a0L, + 0x692b3ce3eb24965fL }, + { 0x0ce6cb72d2a127b4L, 0x66a46ea58f92816fL, 0x43ecf46347a37616L, + 0x163d9a01e0ab96eeL, 0xc8145c6db2edbe8cL, 0x2f426cae4de4e665L, + 0x174d0b4074e252f9L, 0x54c240d77d2af831L, 0x581fa3973d652936L, + 0x05b9491ca09d4695L, 0x8c4e85335452643cL, 0x32d64331d4128327L, + 0x6447903870361f25L, 0x774191b189ef09f2L, 0xc0cf0aaf81de5fe0L, + 0x333e430af40042d6L }, + { 0x5df04de4cf26d3b7L, 0x57a77306b53f79beL, 0xa4013c5f1808b664L, + 0xef291ea485037360L, 0x1ffc9d7d0b061037L, 0xd9d04dd965c913bbL, + 0x948a37aff13b8587L, 0xb5443483fe3ee755L, 0x3fc21e7404631386L, + 0xb3a104e5cddeb58cL, 0x94fe18626572cd52L, 0xeb9a71a115aaa408L, + 0x8adc6fe5459ea462L, 0xbb18d1754aeb02a3L, 0xae1276362f7791d1L, + 0x10e8b31dd6bbd708L }, + { 0xb87f03e53ed9f1afL, 0x03ad247756676166L, 0x38dcd63074ce15b8L, + 0x1877e2b026b1e85bL, 0xb1654d171af99c15L, 0x9782e9e49382547aL, + 0x6dc7fc7c26d55ef5L, 0x9038f95d2fbeb54cL, 0xfe590dfe036c0357L, + 0xcfcb6eae4fdc3f7fL, 0xcb1fbc54f35e1a88L, 0x3c8e1db2da0a5568L, + 0x9a87393f5b6f5557L, 0x38646b32e7ac0a06L, 0xfd261c832a8495abL, + 0x6485524c0cdcc4bcL }, + { 0x1abfb3e2c4a6ff2aL, 0x2aa03fba35a6428aL, 0x884227f089aff742L, + 0x2337883aba5dbd93L, 0x38186ae9d2a182cbL, 0xb9f0764d49a01f05L, + 0x92411feb917b1e7aL, 0x700b1903570cbb5bL, 0x5d5181d5b914be7cL, + 0x135c44371981182dL, 0x32758d24574b9997L, 0xa650a8f5632d28b2L, + 0x24078bacfa383f09L, 0x6546a60c00a33d80L, 0xa4061c7a2df8b449L, + 0x1f76f3f2f234563cL }, + { 0x9aa2c14344c436b0L, 0x790705561f69c87aL, 0x35f3117b5f6db2dfL, + 0x85761f41ed56ba82L, 0xf831464f7d0afa48L, 0xa99f29153adce71eL, + 0xb27bf693116b7488L, 0xa98a5a8c9bb9443aL, 0x7f8780262ee5fde8L, + 0x3a6f93dd1812acb7L, 0xaf92a4ccdc84bc92L, 0x3c2562aff1d4995aL, + 0xfd9fc33c04ed899dL, 0xc028ca944ed2a538L, 0xd0f367bb049ea726L, + 0x04924ffb3d108e05L }, + { 0x06548e3dc673562fL, 0xd3b33025e2eae48cL, 0xe61fd32b5e1c6977L, + 0x424e20646ebe557bL, 0x767391c041d6e18eL, 0x4b8ebb8e14d7e95bL, + 0x4ae8b7d420991b8cL, 0xf8a0df66e01290d3L, 0xc97e24a3925e5f4eL, + 0x79a7b2cb1508272aL, 0xb40b072e25072661L, 0xdad9e1829062fa49L, + 0x8780a784f3c53bceL, 0x58a82b769f142799L, 0x08cd849cc1468426L, + 0x4dfce809c380ae35L }, + { 0x45069cb2d527b780L, 0xd52da015977930ddL, 0x10cc600be27d0263L, + 0x34102c26bb2d1b2bL, 0x4c652623554adf3cL, 0xd689138245f0ff47L, + 0x83fa8cc5ca916e7cL, 0x1e10f139d15c8d8aL, 0xf173dc2e81dc56b3L, + 0x7fcecb045c4ed9baL, 0x307fd7d847d01228L, 0x24a571539f3a532fL, + 0x59e9e81de2153c22L, 0xc562595de428a408L, 0xdc7daff89339bd23L, + 0x0d075908b8a06802L }, + { 0x870af2a7de085f2aL, 0x88fcd24fbe99b2e5L, 0x88c0d26159ca413bL, + 0x1f02a2e48559f851L, 0x83b96021f622da0dL, 0x5c05c2f56dca3615L, + 0x0148cf1c7910c682L, 0x392f2896272695beL, 0x883d0bb5a8d64ef6L, + 0xef0d22441cfcbc52L, 0xf5dafcec526117e5L, 0xb68612b9f04928e9L, + 0x283f744d393f2e2aL, 0xfbeed7ed700c1151L, 0xf2cde215a4360dfeL, + 0x24fa961c2f08535aL }, + { 0x0767db3f616df7f6L, 0x643057d8fbd90326L, 0x174daa906e82d544L, + 0x2284f345689643dbL, 0x18b191dfcc89a060L, 0xbab46af4d6c27d12L, + 0x5a57f486c9895145L, 0xc03214e9cc942f9eL, 0x273e1c8f41950158L, + 0x8ceb759f39ad43abL, 0x5e1b8b7fe50ee173L, 0xf635b1fc8f4d7d4eL, + 0x8eff77e3755603f3L, 0x201f61d17752fa60L, 0x94d7a03d4a6fb6e1L, + 0x371cc23dfc4f0114L }, + { 0x289b115dda90c351L, 0x6d196ebf364d9c06L, 0x77a89202f650b31bL, + 0xcc28c1646f57642fL, 0xdc4f7e3608100127L, 0x8836cd08dc4c807bL, + 0x1280f156e00240f2L, 0x3f9a6d7899cb3953L, 0x40a494d33a802038L, + 0x45697e91e87d3474L, 0x70d97d0726dde24aL, 0x06f6a58d7640c30eL, + 0x03c2c0e85ba6e6c6L, 0x330f6a7af1bc13e8L, 0x3e602e4fc9f4d78fL, + 0x92b6bca00c80fb7fL }, + { 0x2e3d5c835f00822eL, 0x0e825712b8b16f12L, 0x81c329c492b0a330L, + 0x6b4e32ada7cc1954L, 0x0bee9cee1bb1413fL, 0xedfb7baa4a92ca27L, + 0xcd472afaea3b9153L, 0xe8f09e7e00f0c0f9L, 0xa4e1d8725cdebb70L, + 0xfe2bae084a9b63b6L, 0xf40141b83fd58f65L, 0xd7ec5edaa3b62759L, + 0x9aaf6e67790e3088L, 0x215ad8301f277e31L, 0xe7db4b98cf33871cL, + 0x71ff62c94f02f89dL }, + { 0xaa4c71022a4a84d9L, 0xe2ee4acd5ebc71e6L, 0x3b11a8a5f1cd6578L, + 0x83f5ef9ffff120a5L, 0xa4c598e109e65033L, 0xe1e9f990ca044180L, + 0x8b832d46f59828c1L, 0x753f28a033af536bL, 0x92edc4b1b6d4f68aL, + 0xedde692a72ccd1f0L, 0xd3aa0f7dd2226432L, 0x38dbb63ea3d2661cL, + 0xf1e19fc6fdc37ddaL, 0x6c18b35084ef6b4cL, 0xe6a83fe9df1bba69L, + 0x40fd47e75f958273L }, + { 0x5b88b746267140a4L, 0x6dbbfc1eeab6f2fbL, 0xdd9ec88e69862548L, + 0x69beeba12eb6efc2L, 0xcfc2214a8ac8ff88L, 0x95d5c96eb5a21950L, + 0x93389c054171fb69L, 0x2d85d4521b468337L, 0x14d68a084113425cL, + 0xe52c0139ec6c2174L, 0x20cf0b97f730084dL, 0x1ac16a261f578aa3L, + 0x18b9fab3f9b6ae43L, 0x68d82111d854a695L, 0x0b334d98dffbe286L, + 0x5b1c1157e639338cL }, + { 0x90edaab172b6bb8fL, 0x8dc64ed202fc92c2L, 0xf42ba3c5fe694c73L, + 0x316dc65fcb54dce4L, 0xcb2d66a3632420dcL, 0x16e706e7056dcf94L, + 0x2809c764a4f32c9dL, 0xab18d830ea6edca8L, 0x4fd1ace681c65f57L, + 0x1f91651c7da12c10L, 0x0ac3bd66c7791a48L, 0xb6ad1cf4785e67a3L, + 0xe4d3fc44da0fd591L, 0xce1648016e1c6344L, 0x84de9cb833e50ab3L, + 0x963ab83aa756eef4L }, + { 0x944b47d8df4ea5a3L, 0x965688155cfe45feL, 0xd16e7d588a3c3564L, + 0x84e55b3ee7c99e15L, 0x3fee204df55071bcL, 0x71006f2904057dceL, + 0xfe8c390dbba75570L, 0x3645bcb63319adacL, 0x8189e8b07c20bfd8L, + 0x8e5509697d7d9578L, 0x037d1321b99f4e3bL, 0x011b2521a60cfb6aL, + 0x66594aaa837382daL, 0xc89b91fd83c1dc07L, 0x6b82b899076b9884L, + 0x443480fcbe45c558L }, + { 0xf8ffffb49114221aL, 0x4aec4f2e3e857a7aL, 0x42e2d0e40fa54787L, + 0xef3e6b31d6f96152L, 0xb2296537fbfe9b77L, 0xc2a9d0f2fb43a86aL, + 0x241284ed24572ac6L, 0xa3868917e721ba7bL, 0xdbef7c00c117a78dL, + 0x38149071d31605acL, 0xc2dada9e065a8ee9L, 0xd5b138d8c442be82L, + 0x9b6c224bf6d72b58L, 0xb9d355cf8eb03e6dL, 0xab6d1eb0a1700371L, + 0x97118a88cffaa7ebL }, + { 0xbf9c59a2cdecb5d8L, 0x8083c81ba93a6866L, 0x24e0dd8104774fbfL, + 0xe779a3caa02070b4L, 0x9d352fbb0fbfb781L, 0xa8b0d8203ef2a1c4L, + 0xb858637b14b3e501L, 0x5ba70a498a882ff2L, 0xa27300833b06efa5L, + 0xa42c02f4102fee2aL, 0xe4e762998a0223a5L, 0xdba2ba2685c3fc72L, + 0x554fe763fe52eae7L, 0x30b5405a270f45f6L, 0xd56a177aa573387cL, + 0x17c0778d4b71fa82L }, + { 0x0e6dff1d2735e37bL, 0xc9884e56656ec572L, 0xa2f5ac9d9ebba978L, + 0x40fa4518ba09f3c4L, 0x8c3fa177f5b04377L, 0xa1a1decd967a2ecaL, + 0x768bca700528bd40L, 0xf224952b18691c4aL, 0x16e12c45e86d5fd5L, + 0x7a0d915737859a6aL, 0x723f4309a0ffce0eL, 0x5a8db79ba96cc9a3L, + 0x6dd12ae01ad23a38L, 0x9ffec3a1e2bf5d84L, 0xd6ce84e1a452ed66L, + 0x1219d5c8571fe4c6L }, + { 0x43eaa67f262969ebL, 0x3a3ab39d2f03e773L, 0xe6127e5157bb0909L, + 0x0f82b0ed8d150274L, 0xffffcad8e580bdbdL, 0x51d3d075a9743e6bL, + 0x1484bdb18bac11d6L, 0x95cd9990eb24c388L, 0x216a61d07fac67c6L, + 0x4308f762a04e6b87L, 0x2865dd61cba57cc8L, 0x3c296b0dd234a07aL, + 0x76f928393a0793f9L, 0x70b57e1f0be29eceL, 0x1314a82f7e626f42L, + 0x2c8d7ab2d657f230L }, + { 0x67cf58920825e4d6L, 0xdf51eaa56ef83b44L, 0x63e665d81310108dL, + 0x229f89f58dd0963fL, 0x8c4b14dd9df6436aL, 0x99dae469d45ebba7L, + 0x118aab775a4df381L, 0xda8978bd29e37febL, 0x69ced5aaaca2d7efL, + 0x6c98d05dc67d6a8aL, 0x7474bf0d77f84a34L, 0xd4428b2eed8cd59aL, + 0xb0fd1cd5d1d398fbL, 0x596013db94a20b11L, 0x96eb705a1b404c44L, + 0x2299d2774b09d958L }, + { 0x5b9cd58dc64397e6L, 0xac198f1ebf6dd31eL, 0x5866d8e13e9f1db2L, + 0x405ae2878fcdc68cL, 0xa4b280cde53c01fdL, 0xdc963f2d411db5f6L, + 0xed5d5189bec4f8a0L, 0x336fd13d916ee98bL, 0x6925b1b3042df48eL, + 0x0cf56291ace0074eL, 0xe8d38b4825317e95L, 0xc7ad1d2b821c446bL, + 0x71c44135f0b65934L, 0x971b736f52ca0d50L, 0xaf9ffa5727b46c26L, + 0x21ac67791936618eL }, + { 0xab420e3f2d7fbcd2L, 0x1272247397bdfc18L, 0x492033f84df5d4b4L, + 0x6fcd42363807b7d3L, 0xdfc19b09b33c3625L, 0x13d6f375a0f22814L, + 0x70978a59037c19b8L, 0x4f3989970ff27b9cL, 0xfc0e1a45615a4389L, + 0xffa3496a3e602f74L, 0xc3f1c431b261ca1cL, 0x612211dbee0164cdL, + 0x30463ee4e7f7be9fL, 0x015f7e7892c2e1bbL, 0x663d88d624483a56L, + 0x0e8ec1e70e62d9d8L }, + { 0xa88ccc298a0878ddL, 0x99ac175d6640071aL, 0x90344820a5173617L, + 0x316d023edd58a315L, 0x30785bd488d221a1L, 0xb74b3de7959c48e3L, + 0x42ee03824c67a771L, 0x59ef6cdde0b91453L, 0x7830ae289b237e91L, + 0xe1847a4c495d8325L, 0x67b1217ed0773666L, 0x58192c86a294a325L, + 0x76aa0f56864d8326L, 0xe2a2bd12f4b13e5bL, 0xd850c1c01b6b73fdL, + 0x653a795f5d103635L }, + { 0xcfe2898550dcb199L, 0xb35b8e5e7fa02b60L, 0xbca7d7c3c97603d0L, + 0xb0e5288d27f131b5L, 0x3aa704dee2b12d52L, 0xe206b1d81db725c7L, + 0x0b12839ac5d1b113L, 0x14f970cbdb45d763L, 0xc997f93eb2125e8eL, + 0xbd75739cee7daa26L, 0x46ecbd3f1fef20e9L, 0xf994a1147c6a42b1L, + 0xd289eb4f27fb0fd1L, 0x11186d319a40da4bL, 0x083f65a5fb9d7976L, + 0x30dfc47bd444675eL }, + { 0xbcfc5ae29eaadfe8L, 0x25027e54b4d4e812L, 0xab0702df8b533561L, + 0xa2b9c20456a6a214L, 0xb1a3df7a3059068eL, 0xa3514b219883110fL, + 0xb7be2336c4b78e1cL, 0x17073ce63e2f6984L, 0x86e114a62ddf7ac6L, + 0x276192bf07d7c3c8L, 0x5da69e0beb1ae289L, 0x983af17525184939L, + 0x9ac52a4d407a3aa0L, 0x1535c7daae0fe218L, 0xe16fe872397f2501L, + 0x572a591f54c212cfL }, + { 0x4966841909a5553aL, 0x3f054318327733bcL, 0xf9ceb4b23eefd690L, + 0xbd3cbf9bf22126d4L, 0x6d9671c02fed9578L, 0xbba597ceca0306d8L, + 0xb705ed613d674fe5L, 0xf1d3622b67f33f76L, 0x15bcf3c611cb8c31L, + 0xa38467dce53d1aa9L, 0x902fe929f908ab43L, 0x6e3e499d8d15767aL, + 0x8142db5c90afd07bL, 0x120c6fbc6c8b190eL, 0x80c8655324919a4eL, + 0x65c2cbe1d8c82c3cL }, + { 0x684cda20a660bb63L, 0x27dc3b0a86e86245L, 0x76472cf66ba0eed7L, + 0x79c162e5679dd158L, 0xb688427708452d44L, 0x829bc6b3413f579eL, + 0x92ea15ec95011770L, 0x5e34e30047738183L, 0x8c3ca34973e1d2f1L, + 0xa5c4f1dc229bd3deL, 0x783eff1b94ef7ed3L, 0x46db738ddfae7a1aL, + 0x4353d72e1a099852L, 0x2533ad58a0dcf4abL, 0xd80550160e7888b9L, + 0x831440d53ba77f66L }, + { 0xf43e2e32f611b2daL, 0x5d066e29d0fa46acL, 0xe897f3e8820b3c0dL, + 0xc45c28e61d3e44f0L, 0x929d7f66dfd27a66L, 0x735b860a101e8517L, + 0xea3fce983de078ddL, 0xc9977db5638ce11aL, 0x0488382f48536b3bL, + 0x7e0c7a3c64cadfc6L, 0x3cd17f7f82147b71L, 0xe95663cc1b411e3eL, + 0x5739ac8f985fb46dL, 0x385399cdbcf119caL, 0x4a985a70e15a2815L, + 0x504c3a8a6d5f4566L }, + { 0x00b55283b8fa53c7L, 0x985cff38509474e3L, 0x234d241c437ce25fL, + 0x29832430e5a129edL, 0x6ad38956aabcc674L, 0xa2dc001d7ee81ee1L, + 0x4c23c6b6670b2702L, 0xb35e567ea6e8a3bbL, 0xbc70b3cea69673eaL, + 0x85a7a9c3e6e28eacL, 0x2ae684de5537b7daL, 0x5ecac3e56de937dcL, + 0xbf2ea6c9f8430422L, 0x38caf7d077fdc520L, 0xc27af0b169f56addL, + 0x496e4699c71d21d2L }, + { 0xba14fc829fa93467L, 0xc2e376840eb2a614L, 0x659bcfaf4833e09bL, + 0xbc8597523686bdccL, 0x40bfd08081f3216aL, 0xc463bda617c081b8L, + 0xbd01fa86bb04793bL, 0x5a21ece62cd640c5L, 0x97bf6a542203d5c4L, + 0xceb40edc951167b7L, 0xd67aacaf765ba268L, 0x8ba0d9e9aeab51f9L, + 0xc14b215eb0d6863aL, 0x354cdcdbe5f06952L, 0x4f2b5ccfcb3744b5L, + 0x1338917313037fe8L }, + { 0xee68064045003cd1L, 0xfdac17bc44ae2ac6L, 0x4bcd419fde8e5314L, + 0x81e34eb9c7cea95cL, 0xbb57762d38f37e01L, 0xecc4cfb0260990c8L, + 0x0bc493f950a34a7bL, 0x68074172543304efL, 0xaec0fcb26bc8aa2aL, + 0x9e7a9b463b45fea5L, 0x4bb2952e55fbdbacL, 0x50f0c0a60485dff4L, + 0x02c5104d4dea4796L, 0xd2cefa09695e3a02L, 0x4c8102b46da1f345L, + 0x422eb573f3833fbdL }, + { 0xac592eb6a6ad3f47L, 0xb0861f6d9714ba0eL, 0x57c1e91907281459L, + 0xcf7c94e264ea5803L, 0x725376ac54b12723L, 0xf2a6ba41dafb736aL, + 0xc89e8920cba03cdcL, 0xf2e20cb45b0fd3adL, 0x26ea5a54d66059feL, + 0xee63fa8b889df8bcL, 0x40f1c7e166a3f2bfL, 0x09febc9c747312e1L, + 0x7d19b9c2727999ffL, 0xa9fbbb4cb7fd2b05L, 0xcfba27d7a0da2dc6L, + 0x368541cf2c252582L }, + { 0x510d3c9e22799d37L, 0x1b677de5acfa333aL, 0x4e6ae18f080f795bL, + 0x69b53c2aafc8dfc2L, 0x797541b60e842dc2L, 0xd5a6f2afac067fe8L, + 0xd0208a03bd07d877L, 0x34b473f0654be2f2L, 0xe67c102af515e23eL, + 0xb00dbf9d2ac1af48L, 0xe264fa41b6a13d00L, 0x1669786a97e94c11L, + 0x09d8cf2d86a586f4L, 0x073bf869c7f927e9L, 0xb89778802241a566L, + 0x59a5bf5922261334L }, + { 0xe9d1c91e81347191L, 0x186c1abceb969972L, 0x07888767a9d46a7fL, + 0xda93cfccdaa7d397L, 0x08bee9f1d91b9aa0L, 0x8267fd78f8dd3c6cL, + 0xf93860d094228100L, 0x6a6a71aadadb47fbL, 0x9caa06b7a6156f8aL, + 0xaa1b05e039848bc9L, 0x36ddc2372aaa9135L, 0x77e7e079b13f3bd1L, + 0x8d0b5cbe4acc5f4dL, 0x04da45f8984cfd36L, 0xf14ef618d3d3e0f8L, + 0x467564c143eb799cL }, + { 0x8d725904b6fff5d7L, 0x037f33af92dc4752L, 0x9095d5756d20b8aaL, + 0x32235fc143baec39L, 0xa2feb4af68a2b9b0L, 0x61c5031894d35c61L, + 0xac92b6a2ea877486L, 0x8eb48b15011bc6f3L, 0xa28fe128c79edcb2L, + 0x9f71bc0ca5d2a006L, 0xf31677322f15b850L, 0xfe8d728c7a036218L, + 0x068f39cb4f81e09eL, 0x1773f0167b7c50d9L, 0x0d0f7adbed6a1e03L, + 0x8a0dee164ee984d5L }, + { 0x504991bf47366e6fL, 0xb8084d9fe86c3005L, 0x14c4c751a40cce36L, + 0xbbb46aa63f1961e2L, 0x56a785f940445e43L, 0xdb8d1b57c91e215fL, + 0x6a8e453ec7ee808dL, 0xc0367ef8bbaa1e8cL, 0x310d91f1e3e18109L, + 0xf97cfd0e7e20a2c3L, 0xf1e80c84554cc277L, 0xe89bbc1d7b628403L, + 0x7778a9663fe0a17cL, 0x9e9db19fc1f00073L, 0x2ce7fe7db6f6bed2L, + 0x7b04b5d2ee97ce23L }, + { 0x5b546bc782c5faf8L, 0x1a734c5e8eb81097L, 0x3d566861e77851e0L, + 0x833a1013e956d51fL, 0xc7351731c3c3c37cL, 0x607738fbe0c148ecL, + 0x2ec6f0bbe1bbef41L, 0x0aa2ac6ecfa51857L, 0x072902d766e3adf0L, + 0xcd4d5089c622d6e3L, 0x3ae21b23a6dd802fL, 0xe5465a5533886372L, + 0xd85119a0a8d81822L, 0x4f14d0323786977aL, 0x515b081c9c7b272cL, + 0x1c6a95a4c99be31cL }, + { 0xa6b14ad5c2821363L, 0x829c18234d17de1cL, 0xaef5d2c4ccade848L, + 0xf412ab3982489e27L, 0x92c9c098f081d927L, 0x6f87bdf475cbad1fL, + 0xf4aadab81a1d9fb1L, 0x475a7923b75f3b76L, 0x99dd0ad6dbbba8feL, + 0x836f61644b70ab45L, 0x2a46488134bd9af1L, 0x5c91226eba9abda3L, + 0x4cec8709e65625fbL, 0xd4b3919e0818e4beL, 0xa5c09c8414f6879cL, + 0x72708a0230a864c9L }, + { 0x4f33c0b1f34a466cL, 0xa1bae09c7f9d45baL, 0xd70f0fee0e28785cL, + 0x824c714690880881L, 0xe2416c2abb043da3L, 0x733da713cec6f432L, + 0x2b590649c9793e1cL, 0xdb62d5b0b35c9365L, 0x355eb6e23e5c1b2aL, + 0xcfe8b5cebb16b515L, 0x9e081869f709691cL, 0xc865f9fb61a85bd5L, + 0xf169d3ccfae103f7L, 0x9525c47373467e9dL, 0x7db55c0b43695113L, + 0x7491c74c73265d21L }, + { 0x312ed5bf80d2b94dL, 0x1b8ac633ba4b260bL, 0xac86c58cd62219a1L, + 0x317ccf6baeb82c8eL, 0x2dfb29ee59ef9cedL, 0xdaa7d898e42bcd5aL, + 0x93e295c85974b201L, 0x69e75784d9fc5adcL, 0xd6c4709f012aa3baL, + 0x1fda9f37c85d3cb9L, 0xe5487e25d3dd4abdL, 0x00fd4b010b3ba22eL, + 0xcb591493c6e8dcbbL, 0xb7329fabbce68664L, 0x6829d1c268906b76L, + 0x8bcfd3e574176841L }, + { 0x06882734d3c8c314L, 0x95f0b2f111870833L, 0xb937f7c3c068ba16L, + 0x5365e0d877924787L, 0x15527e5e1f992227L, 0x0a06964827dffd4fL, + 0xd58b3df22f586389L, 0x83446b896af20eadL, 0x09d7970b50746257L, + 0xd9e8d2064022a691L, 0xd1e5f8af671ec379L, 0x6f542509057fe91eL, + 0xf14dda8152890418L, 0xbd78010e1db932adL, 0x3e18d1e4905a9378L, + 0x53cadcf7bd37ab49L }, + { 0x1bb5edf75e53d0ffL, 0xd886606c888abf67L, 0x6491b0f812206d15L, + 0xb3018345e22b6a33L, 0xaba6794bb173b317L, 0x8c1e58677dc9e595L, + 0x4e106482239624d1L, 0x61752e59da55dd53L, 0x018b4eab9e42879cL, + 0xcaf6784b491f2bedL, 0x3dcdb9d21e79429eL, 0x3694148510f26224L, + 0x106f190aa650ec5cL, 0x7542a5aeb69a9760L, 0x69bd75e9c32d1046L, + 0x90849964bf8c62b1L }, + { 0xb1390cf65a93c661L, 0x184862649db5f056L, 0x92a93a9da51a1788L, + 0x1b0cbb8f6772de9aL, 0x6e67febd7c71487cL, 0xf9b4382d4e62423eL, + 0x96fda50ebb5a42f8L, 0xc921b3376089a4f2L, 0x49d32d7b875ec516L, + 0xbd86d2cac410124bL, 0xf6862209c421fb7aL, 0x3e1949abf6b7de33L, + 0xcdee18f0e93c9268L, 0xd4edbd5e08dc4cc0L, 0xc2b75be473580d22L, + 0x3d7f6ffa468cd7e8L }, + { 0xea7b290cdffbd5d1L, 0x9d759da6970338dfL, 0x56680b0890feedc9L, + 0xbc690af542dce68eL, 0x8519df2bb2ae4d82L, 0x5612467f7f195b60L, + 0x659a342cd83c21f4L, 0x55771bf555651633L, 0x5fc68935548ba562L, + 0xb54192039492f23aL, 0x567528e39c9c6017L, 0x3f064ed4511e6019L, + 0x303f9eb91d16a555L, 0x3e18c4fd2254abeeL, 0x40994d6ffd434e7cL, + 0x8fb12d3f6dde74e6L }, + { 0x6c6381a2293cb7a4L, 0x453e09f0b87b7e4dL, 0x4f212823078ac3efL, + 0xe89ffad0578cae91L, 0x4a2b696a716ba4ddL, 0x14681a14f6f580a0L, + 0x1358f97b4c2f1307L, 0x878969962932fb89L, 0x29dd850a268a5af7L, + 0xaf771f6dfe239f83L, 0x5f20fd2e4f47499dL, 0x9b643e77867ca0e9L, + 0xe7858ecd375981ecL, 0xbe946a5919ab1c97L, 0x4f9303a206ff3453L, + 0x3fcc673175d237b1L }, + { 0x509debd5df21f920L, 0xfaf70e1fc1401b90L, 0x2429cbfd95a64aafL, + 0xf21208552c37a122L, 0x1d4c93f47deb926bL, 0x12f3e4c09fb3f1dcL, + 0x56085a595b51bc46L, 0x2a2f5d62f10fdbd2L, 0x60dd62cfdf0cb3c2L, + 0x154424a36b0f254bL, 0xc3a5a05d564612b7L, 0xbebe30cfa1f5249cL, + 0x24ec69037e62a188L, 0x75f0fbacaf429939L, 0xd41345dcb3fa8685L, + 0x645146fdc7151c34L }, + { 0xecec633aba1924f9L, 0xbba6f136006326e1L, 0x203757ac7e50fc17L, + 0xca531919ef3d8e00L, 0x9545a6aa51dc5a74L, 0x6e21d58fd31412b8L, + 0x01bc30057bb1d000L, 0xf1789c696ed1a9c3L, 0x7af2d35f9858fa48L, + 0x434d09b98197be85L, 0x1dc0775529aa265dL, 0xcad03be7c058fa80L, + 0x92d70a9f54ba14ceL, 0x6dc785056c050a74L, 0x2a7ca4a94d005ddaL, + 0x448d3d72abfb9f2eL }, + { 0xdc56f14529b33989L, 0x868351bca9ae815aL, 0xb3f456134b074414L, + 0x955ce42a3cd9f33bL, 0x13ade4ec5ff6e4a3L, 0xd3aac715a50eaa91L, + 0x0c61ec995666efdfL, 0x108a28b8f6a4470aL, 0x402ef584e54844c9L, + 0xb825b162d0e2f337L, 0x3dcd131fb46f7cbcL, 0x208178ec96f2fd89L, + 0x4d8c5d6725928c78L, 0x285a33df9963c459L, 0x72497175d92a309fL, + 0x76881479cb7019a5L }, + { 0xba43a11491767eedL, 0x5e11b9ad92bf65dbL, 0xe8a22ce003a5e21aL, + 0x636044212a335415L, 0xc2c563b44a9ead62L, 0x4bc06264a0b2aee5L, + 0x75b8d5758bf2e1d7L, 0x1cff0ee7d08a265dL, 0x17914e1db0b712a7L, + 0xc35925d04b18692dL, 0xde253f4c56cce815L, 0xa479241c9fff0e3aL, + 0x50b9d06eddabed19L, 0x6713526059fae506L, 0xf37600fb532ce180L, + 0x670eb01c5e5a8626L }, + { 0xdf73c0af73cdbb43L, 0xcf08ecc57f2431adL, 0x917805412a1a3845L, + 0x69a104f29224ddf1L, 0x4352f38dbeac7effL, 0xfc3b3b4e7c2d1322L, + 0xa69e9430b5e4b476L, 0x7d932340975a46f0L, 0x8093899e5d64eeceL, + 0x7b821250db2345e9L, 0x235529327f4b796bL, 0x2ee9cc154bb90b1fL, + 0x1fa9c8f59112f7d6L, 0x2d0f2f981cbaae32L, 0xb77f03660075166aL, + 0x504852e7635dff27L }, + { 0x2f0f3ce5a2f392faL, 0x326c076aec6c9078L, 0xad01de9284baaaf6L, + 0xb01b16d3cbe8e993L, 0x71305c242d950908L, 0xc66fd6173853af38L, + 0x7735140ed3c429a0L, 0x8a31b12a1fabf027L, 0xa0530002058b3177L, + 0xabffd9fca9c7deb9L, 0xd05ef69be8667d30L, 0x2f3a7308e9a9e13fL, + 0x3f4c9a19b91eae9cL, 0x50d0cee7618ce6c4L, 0xfb24dc405240f8b0L, + 0x992fe151f7e90cc4L }, + { 0x4454db3138f197aaL, 0xa4ded69d87872f98L, 0x97b427b044f0a828L, + 0x9821e1aea31e48c6L, 0xe38cb09fdd98efecL, 0x20b84fa8480cb3aeL, + 0xba5bb4a847475573L, 0xa9be080acd50e96bL, 0xc4451e9cef103550L, + 0x626ee75fc441325cL, 0x6eea5e9838a5e33dL, 0x7321beb9a2b0abd2L, + 0xca92e4849b6082a9L, 0x1dc8168a992bcc2aL, 0x134ecf4b9c8eb9fbL, + 0x5a68bfa84c5b71e0L }, + { 0xb4ff3b45ff0a2bfbL, 0xd105fff95502f8b0L, 0x14de58855b1c0c26L, + 0xed16865b0d3b9d04L, 0x2f5a2453026d3917L, 0x6a22f493f4db3c0eL, + 0x4871548ae2418f2eL, 0x6ab363a8509bef61L, 0x91ca1e3ab8cbbbecL, + 0x71e0dc984011a396L, 0xff982e0a0d5ca577L, 0xeb40b04581897bc1L, + 0x4bc24a46085ad5e7L, 0xd15c8fa0a6337b7cL, 0x56ce6ef7bef1628fL, + 0x78acfdf99f5ef439L }, + { 0x45bf7f15f8520189L, 0x954202a0c77f61c4L, 0x39edc6b9dfa22e1bL, + 0xd2d602671f4a3487L, 0xcd9339294814cc52L, 0xde76a12405e9f123L, + 0xe2306ea0ae36b6f7L, 0x53815218b83a58e0L, 0x9862bb76a041231aL, + 0xe8da253cbf31be71L, 0x2dfc533237de861fL, 0xf25c93f690ae4890L, + 0x66bcb8f08baa6ed2L, 0x6f10ae0f908b4a29L, 0x8cb4b48cb061c949L, + 0x0ad92d73d075a366L }, + { 0xbfb95fedc2ca548aL, 0x4778c62080cd89abL, 0xbe99154b3466c280L, + 0xea3be093d4be8902L, 0x847b799513e681edL, 0xf22a8f4b02f40161L, + 0x3ef2cb4d4aeb7fe8L, 0x9adc5151b3aed5f6L, 0xec1ccfd198c31163L, + 0xdc2ac17ba3d7d88fL, 0x08fa64d346421097L, 0x5ebf80b794b90bcfL, + 0x1b78b4ba0b50a9ebL, 0x1a4fe934279aa66bL, 0x8ef4dcaf075b3cedL, + 0x95bbd8a070a6e9aeL }, + { 0x59f92495e614bbd0L, 0x7567a887b823e363L, 0xe247c9ecfc1bd6a7L, + 0x2bfaaf478e835c42L, 0x314ef4e0aade066aL, 0x072baa635c16d336L, + 0xfa429c71e2f0e389L, 0xcac1e5d0bd07d90fL, 0x69ff35ea514f5c04L, + 0x893053fcc0554ec1L, 0xab1d86b72a35947fL, 0xe29fb0602aebe487L, + 0xa0a10d6ddfb9cf21L, 0xad147059f20dfcf5L, 0x480dc66fb8867a2aL, + 0x375a884fc125a919L }, + { 0x178cbe2e1217f7eaL, 0x1a161e2a875c6dabL, 0xf7707ec01bdb1a54L, + 0x678864a0e4fd73caL, 0xbaebc664d13a0d86L, 0x40325f99c8d30668L, + 0xb93ed9c92f1c5950L, 0xfdf36763541e0667L, 0xfd97fbb0b91a6763L, + 0x26aa69ea6079c9a0L, 0xc7303c801eaa8c47L, 0xdec75c81afa63c55L, + 0x01cdcde24fd12adbL, 0x9fe0dda71968838aL, 0x66bb093b38415379L, + 0x268d818b08cb84ecL }, + { 0x73dae35841580555L, 0x4fc32e67473d103bL, 0x240c1013beccc1abL, + 0xda4099f2b24ee9deL, 0x37b0cb5b9fa8e066L, 0xb5ae04e46438d7eeL, + 0x7f7d31642b720140L, 0x86ef4edb339e4a78L, 0xa5e77eed3a7d8375L, + 0x883fad37bd707c2eL, 0x816b633a0f979189L, 0xe24c028a2e7a208eL, + 0x1171fe3c4435516aL, 0x3eb93b334f5f2bf5L, 0x8419ed4b01b53a56L, + 0x8b02735c056ca44bL }, + { 0xb89bb464e1019195L, 0x1de4c026f3fc28c1L, 0xac120e6e2bfc3b21L, + 0xec71bc5a91bdf92fL, 0x485d7ab40d995bc9L, 0x97c6768ee6491ffeL, + 0xd9552d19afbce265L, 0xbae6c7fe8e1b76c2L, 0x167d8281d7e3ad1bL, + 0x3e149af95e989734L, 0xd1f0024c8a0c8182L, 0xf571ffdbc3006c0dL, + 0xb32ecf7e58773d4cL, 0x5822a782fd3540d8L, 0x5ab45c3f04365042L, + 0x400e3aa04b4d85feL }, + { 0x473216495e46e4a2L, 0x37a2ed6424136074L, 0x659223b1c60ec77dL, + 0x5e13aac3e5e0ac2eL, 0xda17c41bc5107ab7L, 0x65b22ec973c253dbL, + 0xff3867b8a5012296L, 0xfed660d50621a99bL, 0xa3c28506c89fc3f5L, + 0x3ed350b9f16451a7L, 0x27c3e03267cb586fL, 0xc807c779967185b1L, + 0x09c157d44a13009bL, 0x362f7647adaf1f4dL, 0x4a42b9acf3a6a198L, + 0x131c3da28da6e039L }, + { 0x4a785ff1a7da83baL, 0xf415b425d04f4436L, 0x7c0899bdec03f812L, + 0xc58d411a80f5f4a2L, 0x3d32d610fda251b9L, 0x99bb4504cd3b2f32L, + 0x198c444bf4c2083cL, 0x60c261af730e83fdL, 0x060ca4dfcb02db90L, + 0x0ff7838b9df1e7c8L, 0x6b79cf97c4c690c9L, 0x131514d75d75f154L, + 0xa7c074f11cb0e8ffL, 0xb920aac1b2c17615L, 0xde8098ad44aa0ff0L, + 0x71d1a46a34545ce9L }, + { 0x76178f76fa1b382eL, 0xa0d8ecc3772dda0dL, 0xaa5aab2ac5d4d130L, + 0x27d38ba48d72622cL, 0xc5410db6ca3bed06L, 0xf637a588793ceccfL, + 0x1f65dafd6e65e3d7L, 0xc3b44a8560a45641L, 0x0f47b3a84f78540bL, + 0x824fdadd5e4d60f6L, 0xd8ccf90c17d3b6d5L, 0x008eabdf325fc13aL, + 0x3e90d7163648fab9L, 0x3964ff3a24c52d4bL, 0xb95cc416533d0acbL, + 0x6cd2699f1167f521L }, + { 0x2d8c0b3b12f4f3acL, 0xb03dcfe299d1bdfbL, 0x540034f830f37326L, + 0x22dd68937c5a8c82L, 0xeb7093d0cd8f1442L, 0x892795a7585742f2L, + 0xe15f282c087adaddL, 0x7bbdc74916ab7b5eL, 0xd30fe40ba58acbb4L, + 0x0de417ebe2bac39bL, 0x4b4b19a6c61a04bcL, 0x9338c34df2735569L, + 0xe8f0374230ab196fL, 0xfa2efcb86c88c965L, 0x19eee274c7eeb826L, + 0x327c063fda345dc2L }, + { 0xab399eff5b47cd53L, 0xbbe9869d1943aefeL, 0xe64ecc7b1402a866L, + 0xc3e7c2aab1c25a16L, 0xc4216b79022de271L, 0xe58dfcc8366d6a5fL, + 0xd159509eda813336L, 0x370400f2130bfb7cL, 0x1be4e05993b48780L, + 0x0623a1fe39f3cd22L, 0x72aa22b2eecb4f87L, 0x1af4c4966c27b83bL, + 0x7a42a94bda5fa5bfL, 0x9afba82248b01af2L, 0xeb6b9d2a3670112cL, + 0x020f19d1c0df6856L }, + { 0x37051a86a4dbba20L, 0xb618ebc6db1de5c5L, 0x9a780a19e6525840L, + 0x9440302dd2bccc4dL, 0xe9ff023d10285a24L, 0x3b937ee33a486268L, + 0xe37ee2f24cd61147L, 0x79fbbfd3a3d057cfL, 0x5fba16d3ccddefceL, + 0x916058ec5b231727L, 0x47699ebe720c3adbL, 0x262743868b4f6bbaL, + 0x54b0092af18a0770L, 0x99d090ebacca1160L, 0xf757e1ff0c888f60L, + 0x79e72720b0050544L }, + { 0x632acf252820a239L, 0xb1a3974eaae6b310L, 0xd61fd6ba48c0a1dfL, + 0xd2453c395a3ee7aaL, 0x548455a0b980446dL, 0x9f29d97bde16676fL, + 0xf252ca0c789375a1L, 0xe961af3e7743a985L, 0x70c79c5666cdbd8dL, + 0x14a3854ecbc538f9L, 0x58daa73aa126851cL, 0xe9b5bb452a9f558cL, + 0x37af7f83fbd15e05L, 0xa448792738a1939dL, 0xe428b2b59511a056L, + 0x001d3ce37015846dL }, + { 0xd6be36b9e145b1d7L, 0xf3e3938a009c5664L, 0x2e562e7de7c0f6dbL, + 0x951044e6c343f539L, 0xa5ab62b8d90897b1L, 0xb1a1f70b512f797cL, + 0x91cdd754750f28e4L, 0xb4c80e2fffb8165dL, 0x65ed39c7594d02b3L, + 0xcc12a49d56833edcL, 0xe73694bcf3693a18L, 0x34cc134afcd2c404L, + 0x071bd5fc11d40194L, 0x05759047fc585e46L, 0xb3280360790b7a04L, + 0x4bb8c6fc40afc684L }, + { 0x3120e2ddfd0f8796L, 0x6968a40db133c9deL, 0xfea366c0a9369c6eL, + 0x37e5b6d66007273bL, 0x39e4ecf08cb81439L, 0x487fe9cd9febc005L, + 0xeb8af4440199b53cL, 0x2f124e3b293519ebL, 0x860c218ac82c9c16L, + 0xacd1d6f2709dc590L, 0x5696d54536d50529L, 0xc03f5df959120bfcL, + 0x99a3e88d10ffa690L, 0xd4f9cfa56c432827L, 0x2e8fea9e9a135d89L, + 0x3699a881b6a77e78L }, + { 0x5bca33721eb1c64dL, 0xe9cf3a2df1d28154L, 0xb7e2e9b36537106fL, + 0x06c171514f7cbf4dL, 0xcbde416e2058b37fL, 0x82c53a7e8834e9c5L, + 0x94dbdfe2e9ac3a75L, 0x795ec6cbc5e67c02L, 0x8c23c25f1426a80dL, + 0xee2cd20d6a8d4f9fL, 0x838daa54d3b7c235L, 0xb9e08ec03d7a4d52L, + 0xca9475e9781cb473L, 0x7271f39e5ec31caaL, 0x1df08e9f82535187L, + 0x4f3a4b03208aff8bL }, + { 0x0f7b81071ed095f8L, 0x23e37fa6da226d4eL, 0x8b0f9852afb36d1dL, + 0xb114634e07d8e311L, 0xb9634a97e3e0f16eL, 0x2454bb9c421eec37L, + 0xb4ecd5dbd72b21c1L, 0xf96038686df20d7cL, 0x9f5359fddf86e0a2L, + 0xc43d54fa5ac488aaL, 0x56d714abd1049df4L, 0x13152b3eb020607aL, + 0x49be1c187a02325eL, 0x44f24f4a52ae84dbL, 0x9e525c030b5a7b80L, + 0x6d874446a6d179fdL }, + { 0xd29d07aabe9a42f5L, 0x1fd5316c3781ccc8L, 0x71a75a6d9dc69ea1L, + 0x4e19e0df88fee91aL, 0x99c2b4dcf8d44f12L, 0x05f6df9231ae94e4L, + 0x27fba876cf28ccc2L, 0x6e1a0f01f57f7cebL, 0xe03f1f34f3fd3b74L, + 0xa0edc4a742c1d213L, 0x5caac2707deb8580L, 0x0f5d791faf0848bcL, + 0x17f514ad07ac759dL, 0x95a39734904fc531L, 0x95a4aca97bb70f3dL, + 0x3cf384c9ff9c5609L }, + { 0x700506bace1fc9e3L, 0x49721742676b0399L, 0x2b4a1b8de72bf7b3L, + 0xca8602a879b209f7L, 0x90580b90ce26a8e1L, 0x1ef339b7fe24f39aL, + 0xb6c5d991629362e1L, 0x51174e1a577b24f4L, 0xf380fcb505e451e9L, + 0xf4d97afb148321bdL, 0x099806bb747e5d2aL, 0x85525d65be99a608L, + 0x264828d9d455e820L, 0x8c8c5405d8560a65L, 0x3c67e73c71030770L, + 0x2b248850ee73df26L }, + { 0x2173cde68541159fL, 0x78224c184fb410b2L, 0x07a286191f2ca1c7L, + 0x52c207d6a8b23e40L, 0x071a0210a6b2344aL, 0xdb0e587cb5ed2945L, + 0x6c56b8ef810fcc6cL, 0x1248c58f62d843b9L, 0x4b90363d74c66975L, + 0x6348f7f2e66c66f6L, 0xb2f9d441c126bcbeL, 0xac07f2a373ce49e8L, + 0x52486758e81b0df0L, 0xa108b54d1d4621d1L, 0x17261ece74414a1cL, + 0x938b3bcc6a3ac215L }, + { 0xa9e4a16be4ded340L, 0x8e65fb2a80e88036L, 0x97089606dcd73acbL, + 0x1c3a0434aaa657a9L, 0xf304fc5849101b06L, 0xe60fb61ada0bb64cL, + 0x818c2aecf5542df5L, 0x7402057656f76d5fL, 0xb566b79092533d97L, + 0xae4655e574d6eb5fL, 0x60f7a1b5a55b44b7L, 0x7970179b93747ea5L, + 0x8ae7e0e8f2dace56L, 0x9847460784e83c06L, 0x24e8c9ed15307341L, + 0x6cff58a5d9e89d6bL }, + { 0x508c01b003e51f68L, 0xe1d1f2251d2fe7d6L, 0xf7998d0b09bd8805L, + 0x255e907a03e415b7L, 0xd148467d607d9798L, 0x055c3b1e9b453896L, + 0x35001013809f50f4L, 0xfbbb2fa6d0233fdcL, 0x0b680b0aff1820b8L, + 0xb1d404dc38d317e0L, 0x133d5444ccc8c7dfL, 0x7fa847e66ec13f84L, + 0xc33f83d8046e2e48L, 0x3c627fc54863b3acL, 0x5f67f8aaeb936af7L, + 0x5fe4ac8f31b79327L }, + { 0x581aa4bf8b6f401eL, 0x05db12a3ad5c7ed4L, 0x7b0187266fb07b4aL, + 0xfdd11f049c22bcd4L, 0x5454a7d469371c95L, 0x066c55fb99a46eafL, + 0x18637c7c7fef96d0L, 0xbafc1d346b83e95cL, 0x55c3859300bb42dcL, + 0xdd8dec2b34e7e712L, 0x69c9cfb0b184cee8L, 0x8dcc0c4249a27864L, + 0x290d95f22010f2e7L, 0x86e254c96977a420L, 0x20931c89eb2abdadL, + 0x81377164121c0548L }, + { 0x6266b25e9c5a8edfL, 0x6e1388c21078a7adL, 0x5f02737d4876eedfL, + 0x242fa7f962744617L, 0x3e2cfbd9b385382aL, 0xbadad7b102f71befL, + 0x562abcfa677d0a92L, 0x573ebd1751fdff34L, 0xd7f658527c250c78L, + 0xe0cf16eec47ca896L, 0x8ccd79b067622c9eL, 0x31fc5882f8f2c075L, + 0x9232b37ea6008515L, 0x4d7bb36182e8c5baL, 0xbf24735cd2f146feL, + 0x79c280ee9cd2db98L }, + { 0xbdcc8203f2b48122L, 0xa8c04916b04ac48eL, 0xacf064dc9fc4885eL, + 0xab83899782c1001cL, 0x7339e721676de250L, 0x17aa5aea8e1ab820L, + 0x24d28ca06bc14b2eL, 0x570c5bb7816b6230L, 0x6c51235ccee6b606L, + 0x1b2bf89f183eae42L, 0x3e3af3c69c66274bL, 0xe0b04426b51e38bcL, + 0x26dbc58e73e40e3bL, 0x3f9dd578b5be5be4L, 0x9fd9f79152c8f408L, + 0x758073a4a9e3ff4fL }, + { 0x7d27b0578691ca22L, 0xf206bfd613a2a1b6L, 0xe84bd385ac795413L, + 0xc5d18a2a75536607L, 0x2e166de7c8a0e24cL, 0x56d5750c3c474dbdL, + 0xdef444c11366843aL, 0x14646e53cf4b8432L, 0x4bc0d030a9fd9783L, + 0xbda4c824297ee203L, 0x3d0b10bffd7be6c7L, 0x2d21647608c7f3ffL, + 0x06e52599b4fd4c45L, 0xfbab9fa149e9e104L, 0x9342a7fa8661d32dL, + 0x3f3e3458faf66aa8L }, + { 0x51ec35af951597aaL, 0xb677d4ac49df64ebL, 0x0276cd9c9bf4eff5L, + 0x423eca49515a2935L, 0x8a696553fd9bb9c3L, 0xf99ee9dfede1f09cL, + 0xb8fa2956199e5f98L, 0xb763875835292c32L, 0x8734eddcfc40e81bL, + 0xd82d5e9f65457d95L, 0xc8ee323e30c78d2bL, 0xe77b2e4cc1433d67L, + 0x56d9f8073c8314aeL, 0x441eede22a0e2f63L, 0x1e9e17ed6c48295eL, + 0x640d20c434c294efL }, + { 0x4e9a0b8e3284d513L, 0x074c3545f315053aL, 0xb36e740745acd52aL, + 0xd80bdcfc1de50db7L, 0x8d9d47dc2549fc46L, 0x29b6ef13303f07a8L, + 0x4e461aca6d4ad4c2L, 0xca8e351dfc9f1b73L, 0x8bc4094d57460e65L, + 0xb6302b330f32d367L, 0x69a074b6285742e8L, 0xdfe52b11876c29c3L, + 0xf39e4609912bd17aL, 0x8ee40d66349aa639L, 0xb968902ac72e05c1L, + 0x0f9c1ca8c0d92816L }, + { 0x1ebbaab367433df3L, 0xb6aa534715d3628cL, 0x13a320d897f0c5ccL, + 0x72c918cb65e408f9L, 0x4b638854d5373451L, 0x731399a30b4dca09L, + 0xcf2567300a3b1326L, 0x5ea60dfa6608b388L, 0x58ad74b07b290dfdL, + 0x83202789d7694f9bL, 0x48593db8b6630fb1L, 0x3db47f70c65e3eafL, + 0x63949c913e7263f8L, 0x9b9acec6e6e6ff33L, 0x34bd9ba7098a8240L, + 0x7e31c12f45d36ec5L }, + { 0xbe281d680dfd2dd7L, 0x1efacb0024ab61d8L, 0xb9c3005f94431f97L, + 0x660c8dfa959cb3bcL, 0xfdd5fc30cffbb406L, 0x7a4631be7969a10dL, + 0x336e309ede13fd1bL, 0x76b3bfadfc947076L, 0xfa91925ddcc72223L, + 0x741f0d73156c4ee1L, 0x4f64ee410e2b3747L, 0x86be92d3efc4d93cL, + 0xc53b7e03fc4fbb2eL, 0xac196cf5337ca1bbL, 0x4de41a307e23ba60L, + 0x1a219c45326d5357L }, + { 0xfdcf7ef8aa4db0bcL, 0x2e2318067b6c9963L, 0xc26390673d8a192fL, + 0xc0cec2e2ffdc7771L, 0x997c8e35a2fc0edbL, 0x78e10ec182cc6043L, + 0xfd0de2cb2b0c8120L, 0x4d6c457f69e57f8eL, 0x953e69b25b53f1c3L, + 0x422a330ac4f89cb8L, 0x92ff232995566be6L, 0x73cd502d437442d1L, + 0xf04ce590bea69403L, 0x6ac1537ef8030662L, 0xe02bcf77b6d0bf93L, + 0x17aaa999bc90192fL }, + { 0x0d3d56438e55db2eL, 0x835dee433b946851L, 0x1a1440e55b88462fL, + 0xa6ff3b35ea17e27cL, 0x23f99c36dd95f7a9L, 0x7217fdd9bdd672cfL, + 0xf400ac1edd2045c0L, 0x94b55c874ff06b25L, 0x0a44a0e50e4a49beL, + 0xe8925e91b43b6813L, 0x78bedde1214f96c5L, 0x0f456a4c0f97fa97L, + 0xa28fd86ba5bfd267L, 0x3b4b2d8fbe7608efL, 0xfbd5ff8c226474bcL, + 0x6b282af0a5f3b24aL }, + { 0x78fc025f6341a595L, 0x591c38d6a445e28cL, 0x72bd6e3deb446842L, + 0x3f9466d375547833L, 0x911414d3083e16c4L, 0x145d946695a7acb4L, + 0x102ddf098fd2fb64L, 0x2a2b2d2d0bfd87b1L, 0x69e9be5c59455088L, + 0xee378bf4a80245deL, 0x80b0bd68b2306b0eL, 0x76a545c6c2be9f3dL, + 0x429d167b4802c245L, 0x13e644272b412dfbL, 0xb664f529ee8d9762L, + 0x6d4f5d2354706ebfL }, + { 0x35c8f2b600ba9f88L, 0xfdc807e07bb6d0bfL, 0x0a126d42b3b81e5bL, + 0x335ce6cea7ac781eL, 0x3e308e6ff37dcba6L, 0x028dca6263c96487L, + 0x72eba57e8818434dL, 0xa9e3d59f79b78a26L, 0xd2f0a7dd2f07aea3L, + 0xe0fe467824d05f74L, 0xb20851700116deb6L, 0x9c2a5e9258f37580L, + 0xe78bd7a574070bb3L, 0x551fc872b9977d90L, 0x6eda93c440db81b4L, + 0x4aaf0b4fd65d34adL }, + { 0x9bef25063514c7afL, 0xb09e7dadbc181eadL, 0xef3cae878fa3ec58L, + 0xd8dbfab5173b8685L, 0xb2490fc0921d32ddL, 0x4eef386b8bd9c466L, + 0xc1cdd52fa061dbdbL, 0x64de989a25bc04dbL, 0x06f9836b85728636L, + 0x11a5a8048be44aa0L, 0x16dede4e097018c7L, 0x72aec577b2c11fb1L, + 0x144dade1a721ecd9L, 0xf99c526bd6ebf3a9L, 0xa1d4165b1c2e14d7L, + 0x8b2cbd3982bc6337L }, + { 0x28ec1bf28a52e991L, 0x0ba202f6cf9d42ecL, 0x8307d130c634ea45L, + 0x3fc257b3c5762b9cL, 0xbd3298d1487c2a2dL, 0xca14f1a7a319488aL, + 0xc70ca93b06ba06d2L, 0x9aa3f4b3ee405e89L, 0xcc64eeb335deeae7L, + 0xd155f57803bf1d4cL, 0x041ec0b545616bfdL, 0x23df80e6086e33f6L, + 0x399a79c8f0243cf5L, 0x86c2824e874ccd58L, 0x220eeaec8fc5c831L, + 0x57e283047dbe3670L }, + { 0x6e60b698fbcdf666L, 0xbdd06a998bebb1d2L, 0x4044adba80498436L, + 0xd76bf75e522bc88dL, 0x655c4b9b28423b20L, 0x65c0f49253398a72L, + 0x76d4f2b70ca37601L, 0x469899252030fa5aL, 0x96b37e87b6054705L, + 0xef96f73153de1b2fL, 0x5ecbbc8cad54ef05L, 0xeb289d0aa93617b0L, + 0x3ac0fbd57cba217dL, 0xd0d3cb5619d4a2d7L, 0xe8bee9d4c91d6063L, + 0x4f12e037696ffda6L }, + { 0x4ccfa42215f1a610L, 0x804a5c553786519aL, 0x1246a45473838134L, + 0xfa15b4844b284e2aL, 0x36464c65146d1320L, 0xfb6ba88c70a8a0faL, + 0x74e7cee793c4804eL, 0x8c34d22cb95ae16aL, 0x9d9ed89ff9c1d4ddL, + 0x61a0866d32025371L, 0x45b232b29bd6444aL, 0xf888e92cf277bab1L, + 0x73e69c6ea9448b02L, 0x1a496ea95b521ecbL, 0xa8f78ea75858afb2L, + 0x83d2333eb1266f91L }, + { 0x1c63328867b478d7L, 0xa1ee1ae150a2fc9cL, 0x05b6ab3018d2241bL, + 0x69f1f288893cd696L, 0x159d6660a8117a87L, 0xe812011970e73d77L, + 0x528fef0093f55f0aL, 0xb3978db8d854dfb2L, 0xd6b43ef6f45d9fbbL, + 0x17de4bfed5bee397L, 0xa01e0f596bf76dadL, 0x28b2280e3d40754cL, + 0x8edb6122f8e86ef3L, 0x8226b6afb7d1e586L, 0x463532152f40a55bL, + 0x7362f13ec5a31621L }, + { 0x792eb27c73c0c430L, 0x8cc0a65fa51c3657L, 0x50a5ceced2194f1bL, + 0x18945688814b4947L, 0xbbf0a81a4b6fbbf4L, 0x376f4f58f0aa8608L, + 0xd9361d683987795eL, 0xb6510cd8e3a8d0d5L, 0x63e2fdbfb6c1a455L, + 0x2c91154eaec891f9L, 0x0eb1e715ff568f64L, 0xe7af9cd72f2b399eL, + 0x1fc39bac89f0bf0bL, 0xf0861d9290983695L, 0xd9b16f02da0a20a8L, + 0x2f10693fa38c0eadL }, + { 0x07a6ce910c06ded2L, 0xf974842f2fd9087bL, 0xe468bfd6a9f635a6L, + 0x04b618911ed60626L, 0x1fb2f89f369ee548L, 0x9cbd1113dc96a201L, + 0x6759acfe10d633acL, 0x64ba66fc8faa629eL, 0xa686ae4947f38283L, + 0x828c3a05d59cda99L, 0x7c7afb1408ea2f6eL, 0x2551c8e4af3953c8L, + 0x5b53d2799daa9e4fL, 0x1eff68d4ad6f1940L, 0x2775dbdd96437cdbL, + 0x985f83e44fe7a043L }, + { 0x89603c16eaf45294L, 0x70131160c24b5751L, 0x4c11201839d6b52dL, + 0x7079cf02ed943340L, 0x0c5b028b74f41b68L, 0x3dc3f0769c8ac1e1L, + 0x5ac5eea3f8b24f0eL, 0xee6684bae34c5c22L, 0xa5259e639abc452aL, + 0xb07d2cd1e9df45ccL, 0x07019c931a443cfaL, 0x68fddaa992c003b3L, + 0x2d9f179c0d8cbc2eL, 0xbbf15a6f1e781ca7L, 0x54d779d550dcc799L, + 0x0c88e5400fe962f1L }, + { 0x84f71a6ae8f44357L, 0xf75b4bf63a3cab6aL, 0x334c9d9e5aebc680L, + 0xcecaf0848a753ef2L, 0xe28014c1075e3c8eL, 0xbb9d5a38f74f8d3aL, + 0x75988464b80e32aeL, 0x7b328e6ff2bc3792L, 0xebbb1fafeed0e197L, + 0x674eac955a33065aL, 0x8c19fd8f922dbce8L, 0x8c17ae85987b907aL, + 0x89f336273b3a2cd7L, 0xebaea019fa87772fL, 0x4e5de4993a25ced6L, + 0x8e2560b8af110715L }, + { 0x56d3746c3141aba6L, 0x45a1079fbab2cf9eL, 0xb63828319cdd27c7L, + 0x222376329dfd950eL, 0x1e0b15cd3a9408ffL, 0x49a80200b1160118L, + 0x2719db5da383bba7L, 0x6078340a651046d5L, 0x8929d4de97523b1fL, + 0x4040345c8e0a28abL, 0x61275ac20adf09c7L, 0xb41ab2652331d611L, + 0x230cc77c5391ca50L, 0x88be0c928f922315L, 0xfef3d92b92fd9a29L, + 0x59005f228324f2e5L }, + { 0x6bb1750c3c4c1c74L, 0xbe73aac0e966fb79L, 0x85a75d9266c5973fL, + 0x8c97f9323a8656b6L, 0x2b7043b150446cdeL, 0x548916f73ff3897fL, + 0x913dd01cb18b72b2L, 0xd0a751f1488c0de6L, 0x191757148558ca58L, + 0x9771430144a663daL, 0x2df190acb0e08618L, 0x0080fc0cf39ead9cL, + 0x0085ac6e17382da1L, 0xe97918513262a338L, 0xe4495936b43bae8dL, + 0x57a78e26d783df6eL }, + { 0x161b346f40dbddd8L, 0x2b49a9279410c3acL, 0x8c5427831886cf3bL, + 0x72df323233b93debL, 0x9c8d59f540df579dL, 0xe5d7a67dc20ef500L, + 0xc46b391867f08643L, 0xecfa2445ad96adc3L, 0x658f589b0c4544d0L, + 0xe6ec9301e08417d7L, 0x6ca5ef6ac454e288L, 0x4191048fac0f462dL, + 0x852407d808d8a036L, 0xb4c533a7f6d35b7eL, 0x3251e4128f6ada87L, + 0x1ca370c581c472e8L }, + { 0x94bd5171a801b68aL, 0x7312879cfd1998b3L, 0x4905aabf41163202L, + 0xb5fe87f4f5b01fdbL, 0x78de523a9cda128bL, 0x0bf161a1c7bd31f7L, + 0xb5decfd023904c35L, 0x224b2882e188f12dL, 0x0dd2801df99dae74L, + 0xcad467b508cd1cd2L, 0x6c311c3dc0867e39L, 0x71a117202b425072L, + 0x83bf464e2efd9003L, 0x53d0448a1dbd3b03L, 0x32db52f4e6265baaL, + 0x2584b34c4c33ac79L }, + { 0x3cb863892aeec688L, 0xa5e740ba45fbe523L, 0x422e71f7fd60b5f8L, + 0x455d185c4874913dL, 0x04c2bb36fa17d80dL, 0x3f271854ac054524L, + 0x76dd3045a8b9a657L, 0x2e42c3e162ee7cc8L, 0x002667064df6c7d0L, + 0x5927dd51dc7cb488L, 0x6b3faabe187897e0L, 0xfe6ad22ef2d5737cL, + 0xafb60269ff51a9ffL, 0xe1c8354569807baaL, 0xacddb6ff951ca49aL, + 0x7e8113743f9ab085L }, + { 0xad722a8b830a88b1L, 0x91918ea8ce1117e1L, 0x3e02d0b80409b47dL, + 0xb53812d36c46d1d3L, 0x2fd09db0e589669cL, 0x9845cd0615b0cd5eL, + 0x0c1c155a2386c453L, 0xda774de5f5ff43cbL, 0xbb076b98e391c0cdL, + 0x97d71eff5004f286L, 0x23e0b46caeec0bfeL, 0xe453866732a1ad94L, + 0xfe0c9f81396da422L, 0x6376c1a263db2bfeL, 0x001c7918ba56fa91L, + 0x436b8c64df8485a6L }, + { 0x88117e9d8ab764bcL, 0xdfa61e94a077df84L, 0x5a7765d30c18eebdL, + 0x548916affc9451dcL, 0x01a52e33071a347aL, 0x633b95deb23b41dfL, + 0xdd7d68c943c8c286L, 0xe4f9d41e18d97068L, 0x79908b908c92799dL, + 0xe614148ed47394a3L, 0xe5018517cd51e53fL, 0x5060075e0243dcb6L, + 0xe5dcde6217954405L, 0x6f7c90e1537da5ffL, 0x1df7aae40768cb66L, + 0x5266ca9e6dbe95e1L }, + { 0x84ddee6d1386b3dbL, 0xf9e4af5a7c38e540L, 0xb3418440eb04f49dL, + 0x2138a1e8fde5a4fdL, 0x3e6e692430257cfcL, 0x3519c6e319fd70c1L, + 0x8f34e17486c31ff0L, 0xf1e298fd940ce1e8L, 0x6fb8cb1d14960d7cL, + 0x207c13472b2f3bffL, 0x899a20b4146ef8ffL, 0x7dec362b7bd3e220L, + 0xa975044e626bea27L, 0x0f32b4494fb4cb67L, 0xc17a09201fc6703aL, + 0x41f325b99cd84a2bL }, + { 0x312ed513ce2843a4L, 0xe748498e00728afcL, 0xa8ef28224d864ce5L, + 0x34064704a620083bL, 0x5905e1d94bed338dL, 0x2a578cb5063e7b38L, + 0x98276d96289e7bb9L, 0xdfe2dc47f17b7341L, 0x5923521f1dac8944L, + 0x3db6d28d23400aa7L, 0xc647705ea761ba43L, 0x8947ba6d9bfd07ddL, + 0x00f2e3ac242ca8fdL, 0x49ef4670eb8c3468L, 0x7db3d37bd9aa18fdL, + 0x56b30fb6e58cea9eL }, + { 0x07ecdcaacd80a428L, 0x7af922dc8732c891L, 0x20d887983ada441fL, + 0x3bed9a44924b008aL, 0x2123533cb2e81c3aL, 0xc34e407565f807d3L, + 0x0bfaefa51f2faecbL, 0x78b634a5ade8a88dL, 0xc4e0b7f894392a91L, + 0x3092237790bb1cd8L, 0xdea9b4faf87204aeL, 0x3edf81f585d3cd83L, + 0x58f88c51c6523a79L, 0xe472fb8b17c0d969L, 0x899081e5dccf7f07L, + 0x1353cc5758bdd146L }, + { 0x28a5649739bf6e18L, 0x59e8b5a2649b89c7L, 0x8d9434a0dce8b8e7L, + 0xd935bf512047040cL, 0x2ab3a1646a7b8e82L, 0xf1583ed627f81294L, + 0x8416a7e072d67297L, 0x49685d86cd39e42bL, 0x8a797fc7958ddbadL, + 0xa558f928155ce6deL, 0x75f4e570f8a36235L, 0xbc69cfc052877ae5L, + 0x8f4193a9a6b16ebdL, 0x8d1df43cbb1cc1f1L, 0x723a830e5a21e789L, + 0x3ec2185df451df58L }, + { 0xb9d4c7d71f0bc2d7L, 0x6982c6cc6e51d412L, 0x92e02d93a09f80f6L, + 0xb7dd2d25047ae09cL, 0x3503149f37f351f9L, 0x69d49ce1c77850beL, + 0x60242acb12f0d2c8L, 0xba188c567bc28b9dL, 0x8e40612106bc0550L, + 0xb0d84b1f8d7d4329L, 0xb4a67ae7d38951e0L, 0xb527c57b8bc97607L, + 0xbc93c5f35497aa72L, 0x5f1de8cc39bdd666L, 0x3087dc5ce9d447a3L, + 0x89b356b6a211abe5L }, + { 0xed6db0afdfdcc837L, 0x0fb80baaa871b7a9L, 0x413abfc91c1d4b72L, + 0xf5b56bf7adac9e5cL, 0x5664a2da8b8657a3L, 0x11b04f720e41d94eL, + 0x63e11d2637433658L, 0xee628ecef426daeaL, 0x011619c9cb162dc2L, + 0x9cf5817f87648643L, 0xe1bb97025584bc86L, 0x2cc27cef00bf7928L, + 0x4ef3a80edc60eee5L, 0x7e1202be87adc2f9L, 0x656f18e08a0d4f52L, + 0x39c4f10d57c5d126L }, + { 0xb3a9b68ce88aecd3L, 0x555b0918a518aa9dL, 0xedc1cdad4bd4ee54L, + 0x79b68b6702068d84L, 0x7dac80d0811ac72dL, 0x6d1e6d35a81a0a78L, + 0xc841e9ea3bd16283L, 0xa7bc1775894c4444L, 0xf2b63725f1aa1202L, + 0xbec7767ec7d4c556L, 0x2817ebb3d46ff51bL, 0xfde5be8d73f7e339L, + 0x44c6c9775aed24c4L, 0x0b9a1707b6e579cfL, 0xcff164789069fbccL, + 0x414b542d49152b00L }, + { 0x33c31e58606e173bL, 0x5b7f4e1b90e6713aL, 0x425fb512debb20afL, + 0xc788c61705120e70L, 0x3ef056029013e4ecL, 0x9f9d35ac81c6e6d7L, + 0xe131e88f9450690aL, 0x708f9b3244af082eL, 0xb2e4d66c1ba2aea9L, + 0xaf1f4a6e740db29cL, 0x74ab9248d1843007L, 0x13338ef8ed556a6cL, + 0xf48e623e270d17a6L, 0x3c7362fa9608f5bfL, 0x43977874444e8515L, + 0x52678d6ae00b8b2aL }, + { 0x5dff1c59df36aeb4L, 0x52d6653ca92bc0abL, 0x0e03f496927a5f81L, + 0x8509d4142dfd491fL, 0x258c2c52a571f89bL, 0x2bd6180493334485L, + 0x1a33e94f3f7d9e09L, 0xfab418d32c1bf906L, 0xf39c490e5aa5695cL, + 0x0e41196ef6d2d7ffL, 0x3ecd40750f7948a9L, 0x4b58f9b2d3053b4fL, + 0xb8ee842a5d9974c9L, 0x23a59c1dbf22f682L, 0x045ac614c8efcea6L, + 0x7040ba5bc10ceeddL }, + { 0x2c364f81515a1a96L, 0x31a63503184327e0L, 0x0a0966501ad93d4fL, + 0x9d7694f1273b6173L, 0x8886d876d2cda9d2L, 0x1e01a7422814c177L, + 0x3492276b8667696bL, 0x2fd4f0c65b25f006L, 0x6527349ffb294c4aL, + 0xc1fe0d8ade1d336fL, 0xaf9a23e8e7e3860eL, 0x97d2b721b774c31eL, + 0xfac3e5824365784aL, 0xff2dff4e70f4eaa3L, 0x3d281e1afe873248L, + 0x9043a6d60bd1c9c1L }, + { 0x1511a0fe766c7937L, 0x1b2ded5cabbc3be3L, 0x2ac160cce00888acL, + 0x928754bd616200f3L, 0xb801c83d34a2ea06L, 0x8ad7a03a9cbe106fL, + 0x996b0822cedfcd94L, 0xc3c3463ae4069880L, 0xfb12ea4df597f663L, + 0x2c8d383440c92af9L, 0x79bc85c64e8da154L, 0x95771fa2db4e801aL, + 0x7bd2c1381e3579b2L, 0xe45c75dfffaad078L, 0xb0760a3cb73eac46L, + 0x26362b483a125f35L }, + { 0x25c68d28eefc3e89L, 0x2d0ee87769e9ee71L, 0x8b07bb86af5e4b75L, + 0xdb709072cb86b333L, 0xfd3d20eaff552bacL, 0xa5eeb2b14c0da1e9L, + 0x391f688a44f97145L, 0x21fbd3101e06d485L, 0x45e4f2a5bea9cd49L, + 0x7b60d464a7bf21daL, 0x193f88c8054d5471L, 0x5ace53d1bee0f2e9L, + 0x92c26563c1439273L, 0x9c86e0b296c6b5eeL, 0x452fe23109ff59baL, + 0x2e952b20555c935eL }, + { 0x2a846bcad75f886eL, 0xe68a5dbed43dfc58L, 0x103e45b6007b1b86L, + 0x580e2ec9355ff2b5L, 0xbc702f26a263ecc9L, 0x2835b386181e5e33L, + 0x025113ec6c122076L, 0xa5c26e3a7fbd856dL, 0x8ef83fb39d6ebcb1L, + 0x7aaa53f2a44d2fa8L, 0x7c14ef3353b1fa97L, 0xff604a1117559a30L, + 0x2bcd96b0b09377e0L, 0xa5c14896db2f0273L, 0x1c0a84c9eb53ef06L, + 0x1236d01730378e4bL }, + { 0xd7481c8fc084373bL, 0x29ae4768646097aeL, 0x1300dfa0613bc34bL, + 0x3712714c934bc2b0L, 0x865246290e2be7e2L, 0x554fbb9fed010800L, + 0xf0ec0b3842314576L, 0x65baf594330a3282L, 0x3bdde1a8706ef817L, + 0x7d2c727dba7530e9L, 0xbb0c5d6674cc95cbL, 0xb3fcd3652438906dL, + 0x19881941d14658f3L, 0xe616f5556c97f0e9L, 0x353c2d854b9ec7eaL, + 0x02a48014620cb56eL }, + { 0x11d6d23d506ccd38L, 0x229a1c549059baa6L, 0x717c9c2769d011c5L, + 0xe87e1b46d828937dL, 0xf5d63bbb83835083L, 0xf0a7b427aadac258L, + 0x99ab26bd9f154d1fL, 0xdec0ffbf8ec955fdL, 0xee957c6749fcb880L, + 0x32395dee1e0114deL, 0x192a64b7369f46c7L, 0x4304466091eb2599L, + 0xbe2da887a2e8c3daL, 0xa44e2c25c3556d18L, 0x31390414b55f75f3L, + 0x1d8bde6f8f217fe0L }, + { 0x03cd39f8a2028924L, 0x6e54f19cb06ecb9fL, 0x862bbcb7d6f05846L, + 0xdbe067165a060776L, 0x9397c97ab10fec10L, 0xf42138266f1bb65cL, + 0x414deccba672ba38L, 0x594d4d43f88b05e6L, 0x7993f57aac94d4d1L, + 0x74fc2a6abfb17638L, 0xd8196b5bb6fc655aL, 0xdc375c84ee8d2139L, + 0xb9b00a02360d3a26L, 0xb36ed35cdeb93b87L, 0xf565b28bcc83209eL, + 0x349c6943c61013c1L }, + { 0xd1b394444de6c88aL, 0xd5c2c4714700207eL, 0xb6f458a221c2b780L, + 0x749f75640850993eL, 0x400ba579baef0c18L, 0x2d742938737c70f0L, + 0xc5a8e2ec21467ebfL, 0x243a666e5337f453L, 0xc991f1c7ed0bd50aL, + 0x3a7f3e90f4bd1f91L, 0x96089e8a5f0e129bL, 0xd0d3a17707389635L, + 0x9cf842d527182ac9L, 0x211952990817c5c2L, 0xa32f327e87255769L, + 0x056587ab89c2d8faL }, + { 0x008562ed1ce4733dL, 0x5faff7cb98e51444L, 0x5f03021fa9ab46b9L, + 0x89494c5eb61a8c13L, 0x57c9503636b35976L, 0x6be84c8f2ac2d2f6L, + 0x0e5b34d89bd2703eL, 0xc4ad918f7e872abbL, 0xc2a89e9fc4052ee1L, + 0xc2caee3f3190b51eL, 0x58fd14376fff254fL, 0x6f3c0d68883e0972L, + 0x63d0a0e90fb15438L, 0xc438764bf6caae00L, 0x815f15653f1d0f6cL, + 0x1b87f2edb86cdbdeL }, + { 0x35792bbb2b0b15b1L, 0xa3e4b5a7ce6ba779L, 0xfbacffd9dd8f3779L, + 0x005450bdc298d1efL, 0x0e3f5556c47031c6L, 0x0770f07a95d68066L, + 0xce3e84e02d1052c2L, 0xb050791e7aa8cc54L, 0x4d621e73ba3223a3L, + 0x87b9b94d39632990L, 0x8df9cb477eb8056dL, 0xe2430de8edfca0ccL, + 0x374bf4169712a0caL, 0xbe3f3c7788848a99L, 0xb22b87b1c4a3e59eL, + 0x8e0227c43e95bc23L }, + { 0x000e22a83210964dL, 0xdccd5df5ff056eebL, 0x02173a1fdaf1ead7L, + 0xd02833e067cdcae3L, 0x1cc574cb8bdcc90cL, 0x86eca7143224b4f5L, + 0xd00e603abb3f8298L, 0xb98ece1b0c1a8debL, 0x228a46e4378c261dL, + 0xc6f9dd0da6165e5dL, 0xb3ae38994b7ef0e2L, 0x3a3c16b3bda9f306L, + 0x5e9a26d338a084dbL, 0x528e59935394e950L, 0x848ecb114ea206bcL, + 0x14b15ab540545d6eL }, + { 0x0f6d86c9664c59a2L, 0x3dfe2be160fd7aa5L, 0x33f9b5699072cb8eL, + 0x5f2325d98176a7e0L, 0x79a0d4e74587080bL, 0xa4ee0def0d5d4e05L, + 0xc0ad9ffac87b28e1L, 0xd6f18d2f3f09b4eeL, 0xcc896ae7292e9d87L, + 0xca88953d6094763cL, 0xdbee97a818fbf9faL, 0xdf20e0e94b63d701L, + 0xcbba6e3047ea722fL, 0xce57e1ca612b571fL, 0x1e16ac76009a55f5L, + 0x742bbed8c4389e2eL }, + { 0x23ea86dcc1dc2c73L, 0x4bbbfd5bc1643abfL, 0x07f8fa1f24d8ca1fL, + 0xde68a6e08cb5cac7L, 0x7d54c64b54e66a7dL, 0x789dba22a9b7ad78L, + 0x4d88d540e364ab94L, 0xc8c2e02d1f72e011L, 0x4c82605746e2a278L, + 0xe6c35bb34b187c7dL, 0xed8b3dfeeb8fe0c9L, 0xb6bc34e87d11e415L, + 0xb3908bbfb865c7f9L, 0x717d1ce6e1ecc17cL, 0x151e3308f7cdd69bL, + 0x97bd5a14b5c94124L }, + { 0xe01c62fe81e82861L, 0x703d4b6ddd42c40eL, 0x7e52e55be65e91e5L, + 0xb8b493745abbbfddL, 0xb4f15f52c72a45f4L, 0xce8435a8550f29d8L, + 0x9df76b9b582de75fL, 0x52e84c5fa20c8b96L, 0xaf77d2d10a8a0af4L, + 0x0389bbd8ca6013c3L, 0xb0d9b9ba26f8305fL, 0xf053e8480cec8b9aL, + 0x4d63367affabda18L, 0x50f53be4a6424c2aL, 0xf892c58c864fba2eL, + 0x317c6d3148cc5469L }, + { 0x0c3525b02cb7d42bL, 0x55240bc9310facaeL, 0x8d5d2022ff20408fL, + 0x6b01402fe0c10ea0L, 0x7fbef68a718eb23dL, 0xa0146b5a41252a19L, + 0x59afce48110e0d6eL, 0xe9a1d27f022de181L, 0x6db96d16dc3f49daL, + 0xfc1ae3f5efbe4008L, 0xf9d70641eccbc11cL, 0x49022279525f8636L, + 0x3769796ac2763c30L, 0x9cc3483c1d90630bL, 0x451651f0ee3d3f17L, + 0x6ae597399da0b8fdL }, + { 0x57b13bc7bff4d2eeL, 0x2075422930b173d8L, 0xb6254bd50794936cL, + 0x1d5f232a5efd55beL, 0xc06f4a854e0c3389L, 0xcf2c5b598e61f944L, + 0xc564861ffd5f87b7L, 0xee261fb15a2afa4cL, 0xb0ff72262d97a774L, + 0x1a89ae22d6cf007aL, 0x28880534d346f214L, 0x8fe73bff97b6497eL, + 0x8a8595b2fa2afffcL, 0x9ef9cf3ef151a726L, 0xa84ee5f1e744b82bL, + 0x6649048dbc63fe72L }, + { 0x91b7bb781e8b760dL, 0xd47b0bd825aadaa0L, 0x81493d9ffab5226fL, + 0x4a6dd226bffc148eL, 0x5a032f8aa29be3dbL, 0x318dbc7034b0ab0bL, + 0xdcccbfb57d654868L, 0x8506ab379c581e46L, 0x09136a6e2830ece2L, + 0x48b79356cf6c80c7L, 0xfa176377ef6b1e86L, 0x2c9c1cc183f0f1c9L, + 0x96f0526d16abedddL, 0x3e0e98e2a93b0de4L, 0x6f2d7ada0f13873aL, + 0x4eb93b5cf3fa49ecL }, + { 0xbd89f7e5e11fae32L, 0xd13d74f5c4023f51L, 0x1b0014df491c3f6fL, + 0x1d849a57555279b7L, 0xbb9e889705ba0068L, 0x82222419c13ca2caL, + 0xafbbb685fd33676fL, 0x931c3f5275878a2aL, 0x12aeefefef3d5173L, + 0x189a5cc8bd8a6878L, 0x82cffdb3d99f0c16L, 0xbf565406a19d48b6L, + 0x5605e223e9c6c4e0L, 0x53e781de86804172L, 0xcdf5c90bc7001cc8L, + 0x2b582d937c043f68L }, + { 0xa1165c8281abc2aeL, 0xa73380f5e2b69ecaL, 0xc097b3d207fff66fL, + 0x5d60382654776506L, 0xdcbac9f3b57fa21cL, 0x78750db4c98dbdd5L, + 0x85e21103d9eff32aL, 0xceed172c2f11c41cL, 0xa8e392649e348c09L, + 0x71cb936b831eddfbL, 0x915c3d06f50864a3L, 0xfe8e33cde93acfcdL, + 0x4bee10d7b3f2f7aaL, 0xc1d8eb48eb7cee9aL, 0x4fa49ce3fa574afdL, + 0x78615109862db4c0L }, + { 0x3fe3f4807ae72c21L, 0x631aa144fd0f0da5L, 0xc76ee1e8f8c3a454L, + 0x379ae09451b4f1abL, 0x2a3a4397d7cdbb24L, 0x7a14cffe82bd5fcdL, + 0xbbe4ed12f427ef5aL, 0x9b0a43ee284d3ccfL, 0x57b78b938eec6e1eL, + 0x18d404e467b8e87bL, 0x0c8adc0534374c20L, 0x643736055428deb5L, + 0xb4d80ec0c3afa2cfL, 0x6d51f93c3aa956f9L, 0x9f9a28ab84161c68L, + 0x540b6bb76bc9c025L }, + { 0x04e1734c321d315dL, 0x4ef56612d86e05d0L, 0xeafae145bba8cd81L, + 0x1fb07a49acdc789aL, 0x6a21e9ad5877570fL, 0x2e4a837eb9bc53deL, + 0x436db2931d6298ebL, 0x43afbc78ea362f45L, 0x2a973d97aabf6585L, + 0xdce7dabe0c924d60L, 0xf69d98f07cadf0e9L, 0xe0b505a175020538L, + 0x3db7d1a34461cd29L, 0xe1c287765e20e818L, 0x2ca2586752dd50f6L, + 0x897cab1492e0388cL }, + { 0x59ed38130d8bab8aL, 0xc11d364ca438200aL, 0x0687bf2c40581415L, + 0x86ad0d3a7ac89674L, 0x44928105b97411a0L, 0x74984b11f383371cL, + 0x70d2ed840d1a831eL, 0xd883628b6c912fe0L, 0x44f8f7fb14fa88d2L, + 0x564f2a4dcf0ac93eL, 0x82f629aaa6c24fa6L, 0xab906ba3bf6cd949L, + 0x2c822e6720a5182dL, 0x2ff47dac30eb93a5L, 0xdc62c4a4fff673aaL, + 0x64b00763476b0ec5L }, + { 0x1e3f533eb3c9a404L, 0xb1db7f73b7ef9952L, 0xc7f13e296c253693L, + 0x7ce7f4c40738eed4L, 0xccfd3b33ce26cad0L, 0xd878493501ec5cf1L, + 0x3f8fc09ddc084e01L, 0x217cab32c39b5acfL, 0x42daf0bb9ef5551cL, + 0xfbc76f56e1217a95L, 0x80178b12c237002aL, 0x0b52c39fb070a293L, + 0xe3925153576ca964L, 0x2555942419d68e36L, 0x291fb82c09e50e84L, + 0x7dd22ea66618ed8cL }, + { 0x7ffe844b49cbb3bfL, 0xde0cc7045562fb25L, 0x1e6ee5379f5a845aL, + 0x956d7f26e51277fcL, 0x2c75d4b930635718L, 0x39a1489296957f34L, + 0x8cf4eb3282e5742bL, 0x6b0d3ddd83247b72L, 0x67a9f633201a4237L, + 0x416403c11414a485L, 0x60afd447b6f6a916L, 0x95f94930dac6f790L, + 0x685ff94bbd3b9d82L, 0x5c8f98fc51cadf0fL, 0x9559c88ab13b7489L, + 0x31377c665f18fcc8L }, + { 0x35c5de097dcfb35fL, 0x2dccca9f01cc36f8L, 0x7e93e85d7576cb63L, + 0x0c2dd48af7b4b375L, 0x9d95cd4fb09a19b5L, 0x752ed15971bfe607L, + 0x439880cf2596dad2L, 0xe52efb5369e90a6fL, 0x4409766303d3e60aL, + 0xfcf364faa95070e0L, 0xd8f993b605624dd2L, 0xb35a982400d5e467L, + 0xe289d0240c8f4524L, 0xef45423c648a0179L, 0x3a5fd695587edabdL, + 0x3dacc50ca11e5271L }, + { 0xcb3e4f946499ae4cL, 0xa46dcbe17053c527L, 0x807f5ce9be782e8aL, + 0xb6c64d28d8481e45L, 0xf35e4518aa286fd0L, 0xf7b7b9badf1cdb49L, + 0xf3fb6210aec23eafL, 0x0a9ba385b9bfd2fbL, 0xe51a0d538807f3a0L, + 0x7ab24404b17b2842L, 0x6fd57687f9dd9f0aL, 0xcd1efdb4f3e9df64L, + 0x5dd2df7a60df194dL, 0xbed3f2c3e069df05L, 0x469b756123248a31L, + 0x866949e1694744f7L }, + { 0x3a9a0da53f4ab07aL, 0x2cd6f333f54a6fbfL, 0x0c92e921b23cf290L, + 0xc9581c3e848e3d58L, 0x93af1fbdd3b218abL, 0x38598ea1066cb4d7L, + 0x5001394e990c03a0L, 0x3b664b1e7d0877b5L, 0xd79db1bbd74c7091L, + 0x852d44354e2d5dd0L, 0x0d2b841b3329db82L, 0xfa844eb07b96d480L, + 0x37a50569c295dc46L, 0xc2d3837394f7ec4eL, 0xdc3884ff5b083177L, + 0x574352b88b1fa598L }, + { 0xed2193f70d5d7ce9L, 0x3c19fd260b487eafL, 0x7c44ab597be65fd0L, + 0xdd9da86078270d56L, 0x8a84ec00baa70198L, 0x2ec27e49285985dfL, + 0x996ccaf0de2028d8L, 0x4e7648c761c2201dL, 0xa96335bc091c19ebL, + 0x253a3a69f0d6782bL, 0x3f204340d2946493L, 0x444521a1099f6873L, + 0x5fcbcc096996011aL, 0x3884d5d8f853a94eL, 0x2418c624d3b6a3a1L, + 0x3e431af206ae3c4fL }, + { 0xf967d93983d381f1L, 0x36501aaed0c033c3L, 0xbf3af4d054410768L, + 0xa86d15985093a6d3L, 0x43ae0741d92f2900L, 0xfeb2afa636f0b755L, + 0xd090a6a3aa456d6fL, 0x336a4fdaaefdb646L, 0xfd1bfe441a942f7dL, + 0x7fc2a3ed851ee41eL, 0x4f1c968611e935c5L, 0xcd57766653bbb343L, + 0xf26931baad896c2aL, 0x8a0fbbd186bbfa41L, 0x1c3d7d82a203cef1L, + 0x6dad3f15e2664d35L }, + { 0xd1940b7d12ec35a1L, 0x6219c5b6e7dfb128L, 0x2cc278c6f13321d5L, + 0x5e76904a33c58eb6L, 0x15090f55d9903c43L, 0x061bc926c3d96a19L, + 0x974a9f038c0acba7L, 0x7a4140217198b21bL, 0xb069599df8958c6fL, + 0x517f2f1dbebd0129L, 0x1109a613df3a8dc3L, 0x08e58448672375c5L, + 0x56590ba49383d2d3L, 0xfc3ee7c60bff837cL, 0xc87a539027d2d55fL, + 0x2438e9d45f517a3fL }, + { 0xc4a453088815af3cL, 0xe55f1a32f3c9bed5L, 0xaef1cdc997b65ddfL, + 0x61c61d9412e51eb5L, 0xbd0dac54e63f2490L, 0x6f14429cd0b3e231L, + 0xf737c3c2f1da6010L, 0x7150e04b6bbc4fb1L, 0x205b4c891be281cbL, + 0xf1b4633cd7701f5bL, 0x8b33ef462a513490L, 0xddb47c7368f1f7f2L, + 0xf4ada511bd416b67L, 0x9d2a97cdff795bb3L, 0x00a8b7b296200e67L, + 0x13f39011afe30e01L }, + { 0x3dd296ef7bd0c827L, 0x506110f34a29ff46L, 0xf87930681c9a515aL, + 0xde8d8045268bca77L, 0xcbb83024998045dfL, 0x3f90d71068c0e584L, + 0x2a838ca8263b6062L, 0x293bb5e7535c5d0bL, 0xceea99d556415110L, + 0xfe311ad01bbda005L, 0x2497e0bfa4d8d018L, 0x33dd77a01cf2b866L, + 0xbc075b73d8c4ba8bL, 0x298466d4722b7bc9L, 0x17a7ce24cbda1b0bL, + 0x458d4b6b680703b6L }, + { 0x8a26a20e4d54d8b2L, 0x05a5696e4d320a0dL, 0x698b5858f994f700L, + 0x7a4adc3c2f6549a8L, 0x1812e8193694d00dL, 0x46b9b000730402bdL, + 0xe10a1449a1b36410L, 0xeae95ea599230220L, 0x3efc2e9b1b4820c3L, + 0xfe5b5cb585c9eb8aL, 0x21ae031997847064L, 0x68ef0b708f27d49fL, + 0x3259ef182f72556bL, 0x00ae0457624db01aL, 0x628e3b065668f95cL, + 0x5f13f5fab6fbbf91L }, + { 0x7c6ed9ae3a9b0dc6L, 0xaea1bde96f883ec8L, 0xea66bf88ea8b3677L, + 0xdefa6abc9a66e3abL, 0xc4d3317b68217ffdL, 0xf741c8f2290df05cL, + 0x1f0fdf177d11674eL, 0xfdf0ece7c35989caL, 0x0eed92df6b9c482dL, + 0x73713e6655bf1ca7L, 0x90acb29025cec99cL, 0x37c9e3a2e803e69cL, + 0x7c0a3c5317713a1aL, 0x350dc5656f5a174dL, 0x11625a4405f802f6L, + 0x2196495da37ba4a2L }, + { 0x00cb2fd313142680L, 0xab9e91d765d14cf4L, 0xc6a0ceabdfe2669eL, + 0xbeefce580ae22bc5L, 0x3c2b7986cb6ec250L, 0x84adb1a2d738f1ffL, + 0x9709bc28516ec8ecL, 0xf36931298e8f7db5L, 0xc48efc6b95b197f9L, + 0x9ff109529aaaa404L, 0x2c3c8cbd144154b0L, 0x33ef7bc3427f3435L, + 0x04a17940d21897c1L, 0x5aa0c47d6ce548a0L, 0x2971cea73d56fa62L, + 0x93ad0eb004475f08L }, + { 0x7a0b6967988a9963L, 0x61e477f76515e8ddL, 0x6274e3863b6b50f2L, + 0x63a9b8d5d33922deL, 0x3c38d3fb687a5b3dL, 0x18f6f09c1302e323L, + 0x254c05c3e02fcccfL, 0xc04ed0b726e662f7L, 0x1d5646b8143fe079L, + 0xef8a9448c9016c8cL, 0xe5674c4bf823d797L, 0x0586f72fbccde451L, + 0xc5fc88d54417eadeL, 0x2b952209576e588dL, 0x4408dd425844d1f9L, + 0x73f8c3f0ea41c034L }, + { 0x89534fc85df763ddL, 0x3b1427f33ac71836L, 0x0db5be176e8f15a0L, + 0x1d390944cb20888eL, 0x7804c9ad857caea6L, 0xaa584428519f7bf3L, + 0x626eecf1293aa8cfL, 0x749e0d98ea36a015L, 0xefff6dae3321edcdL, + 0x963deea628b791ccL, 0xa14e05522d16e361L, 0xa2e058fcb15ae206L, + 0x0f268745fca325e4L, 0x7cf9d40721341a8aL, 0xdfed25d97caa51b8L, + 0x0108ae39adbedd75L }, + { 0x54d178f3a9e88f63L, 0xaa05b11eab0c7325L, 0x773a53e6e261d8a6L, + 0x24db7dae8d0b91c8L, 0xde10b073e9bb004dL, 0xfc8befe754e3090bL, + 0x16af05990cc69c89L, 0xddc838039d59511aL, 0xc3f65b9946c5dafcL, + 0xfbbe4be81ee0a599L, 0x88891e36fb3a9b17L, 0x0c9aad75445dad00L, + 0xdffc46abd5097e1fL, 0x8848089bac85a4e1L, 0x348bb42fa0c45233L, + 0x807c06d8eb13c1dfL }, + { 0x00a969ec98ee0ef6L, 0xba9d54838bb7b7afL, 0x24484c92a02f8fdbL, + 0x7bdb201a8b70557cL, 0xe59343e460ad1af2L, 0x53a9a942998c95fbL, + 0x974db3deda861d3bL, 0xce1525c9ed399c0eL, 0x89b56881f72109bdL, + 0x08ff7d15998211a4L, 0x5df76b3aef0f275aL, 0x93f180f7fa2f358bL, + 0xaac4ffcfc39b0634L, 0x2692c62617583b53L, 0xb2fdfa36b55399fcL, + 0x16424c6c99607a61L }, + { 0x5dd65c55dd2744a9L, 0x2544c1c2fe3af418L, 0x32c82e99efe8b089L, + 0x30b7ab25a9df691aL, 0x983845509be99674L, 0xbcecd258caf2d122L, + 0x88ae4098bcc77272L, 0xd43961414b8efa0cL, 0x44ff67b9ed64d12cL, + 0xa9e655e42e7f3404L, 0x3d16fc4545b0e9ebL, 0x474a3e14f03ded28L, + 0xa3c9adffacccb85cL, 0x3dfe6bc17253a51bL, 0xdddaf4b9fb5831b1L, + 0x5544e602a4f4478aL }, + { 0x897c5313baa80b4fL, 0x0122716f63bdc8efL, 0xae2742db7b42c5a8L, + 0xe9d9e1e90883308cL, 0x352c8c3f2d341ab1L, 0x163d0500ed945870L, + 0x8349dd73c290d9d8L, 0x2053c5e01f6c7d29L, 0x83107446cb42033cL, + 0x76c88bd209d09af1L, 0xd0f70e6eb2794681L, 0x720b59de19b1b540L, + 0x80b7ecdc22994b43L, 0xc1a4cdce2dec53cfL, 0xdd7d3edd1ed60f42L, + 0x5735995ce241d261L }, + { 0xdc4ba3fba0237056L, 0x6856c16433ab3388L, 0xc01eebbd271ec612L, + 0xabdeb033e3031becL, 0x4eee44196118a1f5L, 0xec4974215b600f33L, + 0x1b7185cf08868773L, 0x7b0c46cd7c1b7dfdL, 0xd143b2da4a4c5e89L, + 0xdb9a5984bb1ff94dL, 0xac3904e4c9cf3465L, 0xf8729bc0eace64c9L, + 0x5cc22821768ad99aL, 0xbbd3b0818a9540c2L, 0xe468ed5f049a6917L, + 0x885486df3ec45ef0L }, + { 0x6a942c934bdff464L, 0x3db2719f25a7b451L, 0xccb0070b325be324L, + 0x2055a31b19fe3339L, 0xaca69ae8241ee8ffL, 0x7607dd0855ef8defL, + 0x9e24960f1a1b73c6L, 0xbcb0e8a271d36810L, 0x29e11aa26885e6b9L, + 0x98b5d0ab185eae19L, 0x1a0b96e40f81f91cL, 0x4d0e8bcf994fc503L, + 0x33d81697f119d6e0L, 0x29083287aaa4ce0cL, 0xc5dd4d3ec91ff9d7L, + 0x31cecfe8d4ab962dL }, + { 0x437bfd9afc8b21e8L, 0xe5dd32b3b19436dfL, 0xfe5902d4921c36a0L, + 0x8e9de84da3d0fa90L, 0x9663e6ad5bb523bdL, 0x9800a23faecd6975L, + 0x1009c0d9b4fbb59cL, 0x839aa7bdc9d20ff1L, 0xf502f66decd6fa3dL, + 0x480ed4fbc5516ca9L, 0x65ffa5f66c742ac4L, 0x2b7c7945ff3252f8L, + 0x72fefc0575d9cb3dL, 0x11b0863bd6d6f1d2L, 0x5d8f3cf09a6a4ec3L, + 0x6961b46ada2547b3L }, + { 0xd07b587ecb35e2acL, 0x1ed5546b57af14d9L, 0xeca17a5bdb28a04cL, + 0xa1f91d44709d54f0L, 0xa6e719fd9c6f400eL, 0x4e4b88edfb8ce190L, + 0xf9781edd246e3fd2L, 0xd67120e6b655af5dL, 0xda782d1d93413ca7L, + 0x697e20a29707fa21L, 0x1eb51f3254e84123L, 0x2e254d9e36051f9fL, + 0xddaec42b73ce5be9L, 0x89a9a32ecd3f794fL, 0x1964e22f0781aad9L, + 0x6a63a90c53755212L }, + { 0x76554e003d7acbbbL, 0x2c01668ab74f6108L, 0xe4a29672388c519bL, + 0x016677143eb94d4fL, 0x086a3cdf0cd6d2f6L, 0xf86580217b370f7fL, + 0x658880c15a4d3e7cL, 0xd6ed58165ba3f4a1L, 0xabcc78135ca471ddL, + 0x809bf074e844a576L, 0xa53a81b36ea502eaL, 0xc20b93070e021ed3L, + 0x8c27f8928617f165L, 0xa54764468235cd0bL, 0xffc89ffd82552961L, + 0x51ed4a22d151d90eL }, + { 0x37d6963a449701b4L, 0xea8d91a3bb27caf2L, 0x3ef9be15b572965fL, + 0x75a7a055db50bf7dL, 0xfd67480ece643b9bL, 0xf2a60d2d6ceb5d5eL, + 0x68fc320c5ed7c897L, 0x41c53cf628ce685fL, 0x0e29711f7106615eL, + 0x7a87213823500eccL, 0xaf0a92606c29fe48L, 0x93df3f2ae1ef9712L, + 0x0d5f6fb1d2d169bfL, 0xeb7afe2674a9793cL, 0x4173d94ae9f49256L, + 0x2d6951bc2b8b5ce5L }, + { 0xdd007d9f904e222eL, 0x333f248f86f4e109L, 0xd4994e8b8f429eeeL, + 0x29573415cfc77518L, 0x6e7fea3a0b0f42f1L, 0xc795cb7dc2743519L, + 0x820a8f66711e71a0L, 0x83d95d9c2b874f55L, 0xd4b64d78e70e1627L, + 0x924353f58b92a742L, 0x322048b1447b5e6dL, 0x0bad730cbcf931a0L, + 0x75c4d089a7af2268L, 0x464904c1b83b93f9L, 0xa24eba02165b3aeeL, + 0x65c48e78e08cc5f0L }, + { 0x1a1c73cede222c22L, 0x5683d8cdfcea23b4L, 0x0301cb14b2143b06L, + 0x284adf8f59fcec77L, 0xfb1c581c31204cefL, 0xf54d3eee94735107L, + 0xdbf67f0b4d3188c0L, 0x76a3f2d110f18d12L, 0x3809fa2807d3e013L, + 0xf06f0a4625e7ece0L, 0xd82867edb2895d2eL, 0xe106f48908b0553aL, + 0xe2280fa6ef245445L, 0x402d5785a8d9a3cbL, 0xf63dd9ffd438ba2dL, + 0x36b5cd2c7a6b226fL }, + { 0x87ff4e20545679a7L, 0x64d80b414520c750L, 0x90a357fa9b459cd8L, + 0xa19eaf39c85af1a3L, 0x0d475d798d935a5eL, 0x74501983781a678aL, + 0x748397790cc2e810L, 0xc6a21d112f412244L, 0x8d0e85f936a51a37L, + 0xff50151eeaa74df8L, 0x14e182a793cf99c4L, 0x45593df1376a9ab6L, + 0x18f73caf522389ffL, 0xd27cc960f7445e8aL, 0x0692f4c539a51dc8L, + 0x08d7c144db39bfd8L }, + { 0x809c0d963ecca773L, 0x87ea9192d48c2156L, 0xf0eccd74db6bd641L, + 0x773123742a678cdfL, 0x7a966d8bd1587b7eL, 0xf3c1a1016130a4c6L, + 0x7cc6e8385fce17bdL, 0x95e95bb8a8de7aa4L, 0x3fe1e8b5898308e3L, + 0x0197243ee347694aL, 0xf3fe9c42bb0cd2bfL, 0xb59052640f9b2b49L, + 0x4c385e8bc7367d1fL, 0x1d3050aeb5ee147bL, 0x8e2c387904004ad9L, + 0x5f2aa8eebab70202L }, + { 0xe208d4641266524bL, 0xb7bf3880d0a19f66L, 0xa5aa685eda106ebfL, + 0x0a69e8d3e642dd46L, 0xef349c61c682e4d6L, 0x26f6ee3b0fcb534cL, + 0x7daba12705eb67b8L, 0x2babb27e18be05f6L, 0x959afcba8e2d85d1L, + 0xedcf2d1ae2d9d386L, 0x59dc52e61ea6f06eL, 0xc28278b4866e5ae8L, + 0xd9ff034002bcd3c7L, 0xe884ac76784be82fL, 0xa316498083c9f224L, + 0x62501a98b46ff949L }, + { 0x563f7d9aad264086L, 0xca6a33dba5e0e4bdL, 0xe82530028c8d3d67L, + 0xa288dac846e64b19L, 0xfa3c919720aa4536L, 0x8130c9b0ed553eacL, + 0x622806e02ea8abd3L, 0x52fbf54dceccfe77L, 0xbd9a8e314f0d1b70L, + 0x519d2133d59b1741L, 0xfd74101c9a6fea8aL, 0xd1acf7a0b5c4eb10L, + 0x78499b7391f9da5eL, 0xabaa4c49c0dea586L, 0xcc9c5f73a1f3531aL, + 0x497b15fefd3fc665L }, + { 0x8a56cbaaf45568e9L, 0xf491a0fec7192a6fL, 0xdbb03dd39ab2539aL, + 0xc86522f84ac37da9L, 0x8c8cdba202a0f5b4L, 0x8109fc75a29c539fL, + 0x9cd06d31ca90f02eL, 0x8f31f0443e216dbfL, 0x99aa68acba3ebd91L, + 0x2a80d0d242c007f4L, 0xdd8dffbf86a9b7ceL, 0x405d3e84d6308edcL, + 0xdafa33fe068012caL, 0xc2eebd13edea1071L, 0xb7ae7e5c2ff637e6L, + 0x18d46a6c9e514cb7L }, + { 0x868cbb22a78b7802L, 0x0745ddb2497cbaf4L, 0xc4eb2f3e42ae8addL, + 0xac0abcdab4ceb4e4L, 0x2e0d8325a325fd40L, 0x6cfe057113ac7345L, + 0x7407a788b14171b9L, 0x70eb06036da7a52bL, 0xab0b36f9d85176acL, + 0x14109d297c2954f3L, 0x370de9c8dcd705adL, 0x3f0db5cd7bb5e751L, + 0x45f93d41a06e708cL, 0x10d54f8a7e93050dL, 0x69e6f8e45a38fef9L, + 0x55044601d3f62e40L }, + { 0xd1c5c91006cb9cc9L, 0x542074d741d00014L, 0x7cd8663e11236fb8L, + 0x39721ffe29ad5f82L, 0x1d21fbfa2951fc83L, 0x1cde06e7400d144fL, + 0x9042596b91792e6bL, 0x3365c8e529ad5166L, 0xe2220e859aeefe98L, + 0xbcb5318970c2aee3L, 0x477ca3db9ff100bcL, 0x27074176f532973fL, + 0xa12118ac9a2bd01bL, 0xf34252093dd79f93L, 0x563a8ff7c6f5d7dbL, + 0x0da313fcd7b0ec4fL }, + { 0x37125a8c15aa2557L, 0xca21d70c00893e9cL, 0x4871399467b8a823L, + 0x0d3e9a747cb0042aL, 0x2d2bf4ffc9e2ce18L, 0xd5531a0d049aeac2L, + 0x4d29a616f03d0660L, 0x473d50d61f1b7f00L, 0x3af0ecbbca3de50cL, + 0xe2959bea09c28f27L, 0x6d7c2ea0f8704664L, 0xadfae4e1731083efL, + 0x50940c26941c2554L, 0x44167410a1162d03L, 0x620230d81e82290eL, + 0x63630be8db414accL }, + { 0xbf8d52228a7d2e41L, 0x49e75823eb62f879L, 0x1b4d33dd6c402d89L, + 0x883e04d6de2c59adL, 0xbf3f38f449b9dc38L, 0x9d997d18b4b70c4cL, + 0x1f69b20c13cea045L, 0xca3d702558e2606dL, 0x3d4fd977261d1b79L, + 0x56aeafa85a1436faL, 0x369b3e98bb443c07L, 0xfce5186ce558f6beL, + 0xeb0cd478f8ac8f89L, 0x68074f37d5e5aa72L, 0x295845c068544eb0L, + 0x306a9871f16688edL }, + { 0xbc451e9d634ec136L, 0x1edf27ca0e6f658fL, 0xa9be0152c0db4120L, + 0x87b6ef20c5bfee67L, 0x352832389a2d6023L, 0x60e564d8c7afb899L, + 0x4af22bc00ac9c2deL, 0x28e6f63182a9d22bL, 0xc075c701f532701bL, + 0xf6d418f882075f91L, 0xf9fa628d1beaa511L, 0x551e7a176e72a13dL, + 0x9306215b77f4c01cL, 0x71aba73193c9d588L, 0x6443ebe058e57cd4L, + 0x2833ac41e8103e37L }, + { 0x7e564b868da5ec5cL, 0xac3d9da81c08db24L, 0x9d7c1f0b8c57a728L, + 0x3512afe79d343dc2L, 0xb438e4cffdc60339L, 0x7d5a2700dcfa1941L, + 0xd5f323f827320449L, 0x1b87a58e1393c6e6L, 0xecb68bd104baa431L, + 0xc09c1c5a4722b4d7L, 0xf42faa97206b5faaL, 0xe1dcbcd69976327eL, + 0x655ba9e4087787d9L, 0xbd59c757de5c0191L, 0x673020ed0bcf3538L, + 0x120cd454a49d6303L }, + { 0xebfdb8f4cab0f9eeL, 0xbc003ef02cce58eeL, 0x9b6a68415a8d0665L, + 0x642ed3a69b957774L, 0x3de487f04721ab5cL, 0xef2ff38021a4f0d3L, + 0xbd16f55829dbddcdL, 0x2ef05b4b0e93dff2L, 0xde1faa120bc9aec1L, + 0x66dae2c2d467fa92L, 0x758daf645eb33e34L, 0xa67ad9f68f0103cbL, + 0x151f693a9be02430L, 0xd5698496eb4054bcL, 0x8ef1677e7019336eL, + 0x021cfd167fdeea3eL }, + { 0x5c73715fdf5c36f3L, 0x703bde37d64ad254L, 0x55368d10f2cf7713L, + 0x1e5ec7b70f3993c8L, 0xfdb16776304ae4caL, 0x0d8f717e3d3bb18bL, + 0x5267073f66343d5aL, 0xfaeb52ef156008b5L, 0xb97ad5f9224a470fL, + 0xaf86e391ed2ab51aL, 0xdc0c7e579974302cL, 0xc88fa817fd0ae28aL, + 0x807c22dfbf8ed59cL, 0x5dedc231eb128bb6L, 0x71edcd9ca20595a3L, + 0x07265b46c73cf78eL }, + { 0x73dd99f0bd66232fL, 0xc59aaf89c4027716L, 0xaf826dfa5b860fc4L, + 0x239ea8aa7a943f3bL, 0x0e0e1b1a523c428dL, 0x55ea0e3a6973b95aL, + 0xea399caa2557753bL, 0xf8adf72f06957b1fL, 0x0389f3413bd34302L, + 0x333f27d0f8a43a97L, 0xcd9c0c08adaf796fL, 0x6dcca49b49c12aa2L, + 0xdd88deee7a0ac6e9L, 0x8f47575d0644080eL, 0x6e9d667d0cc2f4bdL, + 0x36c5754b31d1496cL }, + { 0x9120046ef323d84bL, 0xa69911227e789c4fL, 0x4b0eaf4e921b8055L, + 0x6339844a8079974eL, 0xc905466a740f8c79L, 0x1c18d0f7cd6def49L, + 0x5297da6b4b23e4baL, 0x1c09dff3c41800c5L, 0x6c49075b37ef6777L, + 0xa94c3a4050513dedL, 0x3d6742e96b0b1705L, 0xc0784494c48af5aeL, + 0x40c01532c95822deL, 0xa2ddade5c164d94fL, 0xfc8a8ac9a2975eb5L, + 0x06fbf8611946944eL }, + { 0x2d65338e3f45aa97L, 0xd83b58c81d040febL, 0x05fef59b0fdef8b9L, + 0x7beb071ae4d7417cL, 0x982b61f5b30a1a23L, 0x4c5f2a2afb65bd03L, + 0xe40abc9d5cbf6bf3L, 0x422c326df06612a5L, 0xc921e69d9571ae28L, + 0x7c88b10b23d3434eL, 0x96d2e9579da07933L, 0x833d46a13619cf4dL, + 0xd9d19653d95eefa1L, 0x2a7d8411a03e8f0eL, 0x5e64295304bb5ab1L, + 0x5e9ca0fd1f0fa9eaL }, + { 0x5bd54571197c5dc4L, 0xe2da40bfe78a95a2L, 0x65fb9efcffdb0eb2L, + 0xe952dc2c0d17467cL, 0xc1fc9c7bc758c6a3L, 0xfc79562cd4034a9aL, + 0x26e36fbe61f64b56L, 0x6adc4b9e1e84728bL, 0x7f165fd3a8f9ac8aL, + 0x7bc93a4503e3e013L, 0xeacc5513656478e3L, 0xd3391717064ddc77L, + 0x75b318dc76936914L, 0x69b1f1c7362424a6L, 0x8cc2045b49955f34L, + 0x940622b3c6836af8L }, + { 0x4710ccb70d997973L, 0x3b29625dd3f8f115L, 0x8cf0c4d55b97abd5L, + 0xc6321e0a673e14a5L, 0x0541af9d3d262246L, 0xde6d87546fc83b11L, + 0x47e97da8f01652a4L, 0x0f82b3a6ad9802b6L, 0x69aa4075ae9c44b2L, + 0xaf3f5de2ced2bf77L, 0x1ef1ea8a497a40daL, 0x2e0f86083c23ba9cL, + 0xd8a998a4f190a2c8L, 0xe2b49c8ccfde3368L, 0xb9f49824bde6bd71L, + 0x80bb1664785bedb6L }, + { 0x05e575fefd145cb5L, 0x155ee561ac5e6883L, 0x461e70cf8793b273L, + 0x9f1553de133b2338L, 0x2fb9e0c3a2a7ba07L, 0xc3bfd6a83e7086faL, + 0xb6ba85008bb4cb93L, 0x0b66d78976f82dbdL, 0x7d5a6ff654eb49ffL, + 0xcd65d2371f20b322L, 0x79ea49c254e29cdcL, 0x64975963cb118ff9L, + 0x969598ddcc58000bL, 0x95107918110c779cL, 0xedfc154863b85a35L, + 0x077ba5ea41212350L }, + { 0x0b3a38d3cdd86f61L, 0x431214450502a0abL, 0x1912edc5806d0272L, + 0x01dc1f988a32f10fL, 0xbb1d31d10e80c760L, 0xd46ec7e5f464e8b3L, + 0xd569af369abf49eeL, 0x9d286ea72cdade77L, 0x2be7020d45ad5920L, + 0xabe5236e6299ae7fL, 0xc93179bdd3f55c07L, 0x8138995a52350e80L, + 0x0901265caff07586L, 0x5b3c81b2f4739653L, 0xbaf7581d9bc77d21L, + 0x6b2006df4591a2e2L }, + { 0xb2fe50a8965b1bc1L, 0x931f536a962bb4fdL, 0xd5718d33000e7f99L, + 0x84728f2553d5125eL, 0x4f8a6184d2125cafL, 0x54f1a701357f679eL, + 0x70a9f40c1531c05aL, 0x10d0cb976fa8b775L, 0xb476f41e9dc12ce9L, + 0x5c8d7a752755f894L, 0xd6c12e10625741a4L, 0x262a6fb8c917b16cL, + 0x24d116e638d6b0a0L, 0x849540c032c38e83L, 0x855b911c66868afcL, + 0x53217ea6bd26b550L }, + { 0xfc840473259f52b4L, 0x968da9cbe621146cL, 0x964eb85ecacbd26eL, + 0xab7daa2de4a54344L, 0x6dc3b848381a4ff7L, 0xa07a96b341c815efL, + 0xc4fae9e8c3d4b1e1L, 0x0f938d1e42ce9ea8L, 0xa727dacc35cc052fL, + 0xc81e01c9e9a06f07L, 0xa9e08dcb4a6d65a1L, 0xf8e2d1736044a9a6L, + 0x99893dd0f2bd295bL, 0xa08d3379f9781b12L, 0x64bd600161830ac2L, + 0x0386931ed9adbeefL }, + { 0xd0d7abb3d09885a5L, 0xed9d2b67e355bb07L, 0x3bc238cf536ebaedL, + 0x61ca2e78699ce4d6L, 0x354ff447111594cdL, 0x55cbe70903316ad2L, + 0x418679fd49fff5c4L, 0x75bacd750f9c6c40L, 0x677edc882972721aL, + 0x82596887e5ef502fL, 0x459e9367bf320e0eL, 0x81ce36ef8bbdccb2L, + 0x1ba097fcb766863dL, 0xcd3a21d6d58c6db8L, 0x0e4967cdb4a8748bL, + 0x2caaf74915041c20L }, + { 0x44f980066ed20424L, 0xb3e4ea2322471545L, 0x268ed1a5781a8c86L, + 0x48d0ab757ae5b70bL, 0x6ca8b320356d3982L, 0x9ce8e6812df31fa4L, + 0xb909d232d925dcf2L, 0x302c8f78f56723deL, 0x11725d69abac96f9L, + 0x656a47ca57d1a170L, 0x6bb5d511c18a2be7L, 0xb56e45f1ad50d9d9L, + 0x36e886e270b05518L, 0xc7c71f3d09d8ff91L, 0x65a1bbe29350361eL, + 0x86d7f53245fe3bd8L }, + { 0x99f16eb6b0bf719aL, 0xb69750988bc3d913L, 0xfae50e5226cd01b4L, + 0xd3e3ac5490898d1cL, 0x4da3b9db887ec666L, 0x58300644fbea45b8L, + 0x369f3bd98355b058L, 0x0fb239a8579bcc13L, 0x4f5b45396e2bd811L, + 0x007f3baf24198fd2L, 0x68a676db8837d51dL, 0x68eeea62eae75b16L, + 0x5ffe5f943db6083cL, 0x52c94d0f7d836c5aL, 0x5a4c3c6fcbc1ff85L, + 0x682a55e386c0b4ddL }, + { 0xc8f235a4587495aaL, 0x2276026c34c7245dL, 0xd6ae0cc5b75a46e3L, + 0x890d3965ecc3e5e7L, 0x1b13342f14296629L, 0xc89927e68a877227L, + 0x1543f27e2324a68bL, 0x6c44768449cdc21aL, 0x9bc7fd4f1452d0acL, + 0x2cc30a31ff4b045cL, 0x415d46a0852f7611L, 0xad737052c6fdd7a6L, + 0xdcecc3ab7b4c7c91L, 0xd2cdf01b7688d70cL, 0x054f2542e40d3905L, + 0x02227fa6fefe4dcdL }, + { 0x1805efd9b751948bL, 0x8efeed46fdfd225dL, 0xcb128e094f2c8b22L, + 0x9d1090bf96f7c5e5L, 0x0959d044b4cbeca0L, 0x21c955f98e08cb04L, + 0xbc1f279d68fa4fceL, 0xb021e14e0710ae9aL, 0x64d16e9f881167f4L, + 0xf5a5c22ebbc9f1a5L, 0x5f3716dfe3420eeaL, 0x971eb915d5c4e843L, + 0x64fc55fc28ffba81L, 0x3427e54d7dd37578L, 0x446e6a6215ebc7d0L, + 0x547e249a29269778L }, + { 0x4706868aa1ffda27L, 0xb4e6cdcc7955cf50L, 0xf65151e10a63f3d8L, + 0x5b4127ea9de5e70aL, 0x3d2c09baf9342823L, 0x18c99d83aa2f7d51L, + 0xa0c5bb1dddeec025L, 0x7ffddf8403dcf1ceL, 0xe57e4d29616fdedaL, + 0xd24565697932a1f0L, 0x7475e0e83191d4e3L, 0x3479bea1c220218bL, + 0xfceb5c908bcb2505L, 0x1c685cea3c6132e6L, 0xc42dc745bfe6c1ebL, + 0x45a41cc0d2b08eeaL }, + { 0x3ea9b2c74dbbf0e1L, 0x41ff962fa17cf70eL, 0xdc1ea7585eeb4c66L, + 0x4f5412d2a9beb17eL, 0x2c9e4f52a285741aL, 0x93df7da4984fd11fL, + 0xb2afbddc0df3184eL, 0x96323d252421e375L, 0xc87be1e449df781eL, + 0x145601ed3d589beaL, 0x0f0bd9bd28fff6ddL, 0x2d3259d48a0f298cL, + 0x362d7a77d88e6944L, 0xa84c06b6b6ac2af6L, 0xba850ac9d087da02L, + 0x128763c942ee40c8L }, + { 0x29a80f07acbac178L, 0x7cc2004434b08f6eL, 0xe9631d1470feded2L, + 0xb2115da386615767L, 0x7c75f5c4cb088548L, 0x5b29d2139a2e8e03L, + 0xfe9fda668b881752L, 0x3f1d8d88c1de7ebcL, 0xb476565e03218123L, + 0x07365561b1c995f3L, 0x2160cb18b13eb71bL, 0x7e8da51399b3a0ebL, + 0x5e8ca1f9b20fcd74L, 0x6a7e0067b4126d72L, 0x1e8204b768bb637fL, + 0x75e96bccfc4f74d2L }, + { 0x189d1fdc0d19716eL, 0xdf5850587c384525L, 0x64a846d1ea987d2aL, + 0x12b6bf836c07150fL, 0x91d85d464d6fd5b7L, 0xa97888364f53f55fL, + 0x60083bd881509129L, 0xa7672683ea876f48L, 0xe80b2e7ac15b2489L, + 0x985ef8d242d1d992L, 0x9c57b029cf3de492L, 0xfe02f83cb1487627L, + 0xaeba4fe48ae5b687L, 0x8a86f09b5d6b8196L, 0xd88f566ba16e523dL, + 0x309a6e9aba268949L }, + { 0xef27ee50bdfbe97aL, 0x1a5fe70fb8c50c4dL, 0xcc7beb017fe09f5cL, + 0x8fa15a85bed36cc5L, 0xc0c3acdb7550ed3aL, 0xc581ef87eb908681L, + 0xa15b3362c49d5ccbL, 0x0fbb17141fa264e8L, 0x267f8d8f8e1eee88L, + 0xd31ccfd621c2b63dL, 0x924dbe7d53be7efdL, 0xd42e877fdb2a358aL, + 0xcf9673c775d68ac1L, 0xe35978fd714fea55L, 0xeeb366535769b202L, + 0x0458258ad7593789L }, + { 0x5df71a74a042dbdfL, 0x2d4058575779dfa2L, 0x0e66cba70d2e6657L, + 0x285d6745ca2e892eL, 0xf56a8def0f0e6b5fL, 0xe0ee851da30767c3L, + 0x98c0565843346b9cL, 0xb35fce26d6b3c742L, 0xc0895bff39777e00L, + 0x83c8f6a6e7b6d886L, 0xbee148434f02904bL, 0x7f74915b2e84ec34L, + 0xbaaf663c96d10991L, 0x004b8757e41facc0L, 0xa2b880e56f86c029L, + 0x53f4a3e095b77358L }, + { 0x11bb08ce89fc48e7L, 0xba60c577afab5aebL, 0xf06bcbf8a0c1cb5aL, + 0x7d2efaea79757cb6L, 0xe26d90b176319160L, 0x42aa1ab62b77b7a9L, + 0x38eec0cd285df2bfL, 0xd35947f5f3a8f7f0L, 0x97c8dc0efc1cb5b5L, + 0xfeb8cca0c45845cfL, 0x16e8d989249e26f2L, 0x7c264e6d483ed89aL, + 0x13a3f14551d91073L, 0x8501562e305e99f0L, 0xaaf98d746908d563L, + 0x0a99e653d723d236L }, + { 0x23536f46abbc0559L, 0xc163067b9aa1a160L, 0x229fd2290c1681b5L, + 0x61254be11378e907L, 0xc60ff57aab793a2dL, 0xa6f2df8b466552dbL, + 0x9ad318938c170a36L, 0xc5cd9abe29b74d9aL, 0xcf747273f7848523L, + 0xc126a93a0d0e3063L, 0xfe2021e34248e3d8L, 0xd97343ee8323ddfaL, + 0x9f768775332639e7L, 0x9650fc3175325548L, 0xb595dbd13eebf7eaL, + 0x3a95cb45010fcbc0L }, + { 0x954e68cb39d7ff2eL, 0x8dd1cb4bc1d5c48fL, 0x02a92c777169438aL, + 0x7965c0b091cad8ceL, 0x0c5798ab32cd08d2L, 0x1a5bc3c3a6902bdaL, + 0x545d09255186d218L, 0xf0077cdbd27e64dbL, 0x0157caa48cd092daL, + 0x2a2fa3a024532ab3L, 0xa5fb639b41ccaba3L, 0x01702dc14744aee6L, + 0x485bb436cdba93daL, 0x93597f66329784f1L, 0x5d713c1ddad672c3L, + 0x366d222e030b7245L }, + { 0xd50b4875573ea5b2L, 0x0fce401ba90da44dL, 0x7b53fa657a1a0310L, + 0x722a80a5cf114460L, 0x0b8ebf05a538bf49L, 0xae141147d32acd21L, + 0x6692712c7b5ad07dL, 0x6dc5fee73f48ca07L, 0x98ed14992b8a78d8L, + 0x4e8b3145dd2f1759L, 0x43408de15f971b8eL, 0x055ea6ddadf1b368L, + 0x4bb76e73e5932b7eL, 0x44287153d30893fdL, 0x173dccd20661bfdaL, + 0x9072ba9979defd25L }, + { 0x474de4dd9620ea39L, 0xfbf1649fc831cee8L, 0x0b0e8bb1cd3a9c43L, + 0x6a38286f3f3df1d5L, 0x4ed072b38f0ec9b3L, 0xa6e4c987729c09e3L, + 0xea3e8ac68ad12242L, 0x6ae0e22bfbdfa5baL, 0x56171ecfb0a0f592L, + 0x33b2886d6b871f8dL, 0x6b19bea935e11bdaL, 0x4d815a407f0f153fL, + 0x7e608d977d6c02eeL, 0x7e8f23d9b6a88f46L, 0x26ac9652439d1654L, + 0x8d92c6bd35546c29L }, + { 0xb3e0d7ceabeb0ff7L, 0xfbe352543e0e42f8L, 0x57d1b226de808499L, + 0x9ece2e1f1cd44bc3L, 0x1245adbc435cfee1L, 0x874ee840f93f581cL, + 0x916a779cbda0b947L, 0xabcc815afa57ae0aL, 0x97adec2df0a621b0L, + 0xbe6a502b81f90bdcL, 0x54bf9de153bde63dL, 0xa88fdabf78884c25L, + 0x30aa52b1cbbb5470L, 0xf805396c29053ef5L, 0x8d43d8988dd827eaL, + 0x4e4bec175c1ae5c0L }, + { 0xbf8483a2fcc09676L, 0x457c4a3f19ea9a94L, 0xa6852ef3d702a5ddL, + 0xe7915fd2843fe7d8L, 0x644bba9816e35158L, 0x8d1b95d09ed746f0L, + 0x47704581b90af0b5L, 0x0bd4bc6bd4fd135eL, 0xa6dce067b4e833a5L, + 0x2c0e8f30ff56a9a1L, 0xa9c80800ec2c63feL, 0x449c20a598f508a8L, + 0x02b94cb33292813aL, 0x647e3d28ec7e81a2L, 0x72e67d1ab4877677L, + 0x7a4aa3f56f9ded24L }, + { 0x559ef1bae27a0045L, 0xdc812d4fb242cb50L, 0x23a478e439cf8d24L, + 0x97544fc59b3f9c54L, 0x5ac68132affa1fcfL, 0x74f8fee034a2c83bL, + 0x96cc640fcd3f4bb7L, 0x775dce9db0512ea6L, 0x67dca19dcdce381eL, + 0xc1eeb3f3a9d3fe55L, 0x38e0bf421a19274fL, 0x15992fb428d69b12L, + 0x48fcebde9fd09df8L, 0xdc9dfa4fb41ab5dfL, 0x0cbd7dc8c0a269c5L, + 0x60282a7bf7f0ade1L }, + { 0x7c07e538dceea2e7L, 0x38a322c83c42061dL, 0x676828f94f1f6516L, + 0xf21b69fbc7776a10L, 0xc63a3417b5e6b405L, 0x4c99f25891a7b642L, + 0x38692ca82cad1440L, 0xf1e82ffe00869bcdL, 0xc30b714e16fe466aL, + 0x5fb742f919019138L, 0xe90166d00fa516aeL, 0x5550f7acd8c73a43L, + 0x2d6a407dfbc5c372L, 0xe47a753968cc39edL, 0x3fd286d94a5fbe70L, + 0x5f4ae9c723c6b942L }, + { 0xd96a2dda53f4d561L, 0x286d45d016da1992L, 0x449a01fbfdd4b051L, + 0x25488a0d9f2195eaL, 0xc4151b0aa37661b3L, 0xb98c471ef9e5ee02L, + 0xa4bca86ea8658817L, 0xbbcadb877a68fc0aL, 0x88b346496b7366a9L, + 0x32ee98d415661c2dL, 0xf5b3b4c6c901420cL, 0xa23527352f2752afL, + 0x2f64ce73510e4d9cL, 0x939a7f26aca4aa80L, 0x9cd3e291401aa503L, + 0x92a01423dc46afd2L }, + { 0xe9f24be11c2f7dbdL, 0xda8c900fb7d527faL, 0x963e25bb8648f128L, + 0x9ab713e248141941L, 0xe87f7d017a6756fbL, 0x274dd85e058d90bdL, + 0x823fee7a82566abdL, 0x9f6230d774240195L, 0x04579f2cacb5e46eL, + 0x2a22626316a4c87eL, 0x9ca19a43d99b0857L, 0x86dc2ba3e488789eL, + 0xf960b5b99406c3bdL, 0x6f2c428b8960957eL, 0x90748706161c515bL, + 0x0fc8fe1eaa88cb9bL }, + { 0x68ae1bedfeb90f2dL, 0xf393bb3ca48b1559L, 0x2be62f9cf64e9635L, + 0x354c2410f8be75c2L, 0xbd7ea7035e6f7529L, 0xc264868e162cab31L, + 0xb1391e70c860f3ffL, 0xdf367c751d89837eL, 0xe150b6b42bf32941L, + 0x95e8f46e78c1318fL, 0x2b3f1daba2c4b160L, 0xc6ccf5ce701afbf3L, + 0x3ad275305e8874c5L, 0x39285e515dc6dcbeL, 0x3c954d86d99892ddL, + 0x2d0ba862dfd3789fL }, + { 0xeacd8ee8b472e1afL, 0xeb354eaeb76abbccL, 0x9b520bf8d0d93fbdL, + 0xfccd60d7fe6fc706L, 0xa9353ddea4ee2f39L, 0x5eb0925e9a81e51eL, + 0xee334da1d1366777L, 0xc1d28c9fd5354d69L, 0xb977175592a5ed54L, + 0x5d3e367fb7f70d81L, 0x7be7eecaa933ae7aL, 0x264cf1f9e23cfbb7L, + 0x0d129f4a89497681L, 0x705375a409b6235bL, 0xccf64c7548a376daL, + 0x963c87124d41dbfcL }, + { 0xbae290cbde36a814L, 0x9bdb0195733b12b5L, 0x0ebad867f77fe0e1L, + 0x0a7d19fd29720ceaL, 0x434d76519029ec72L, 0x856aff17bb51911eL, + 0xd0a25d9ad80a7f60L, 0xffca86aff848c106L, 0x53e8bdf943ad749cL, + 0xfb9e0284e3e696bbL, 0x3eb6630aeeee4215L, 0x9d8fbb9e2ecf3c63L, + 0x71da4ffa4e00c0c0L, 0xb296be595d57beacL, 0x1751fbada8cec7efL, + 0x2d03eb3cff55d7bdL }, + { 0xeb16925f04f2ec1dL, 0xa878f2760d147ee2L, 0x442df604aad9d9e0L, + 0x891df44b3f71035bL, 0xc28272b38cb95d5bL, 0x6f14efb55ee8ed23L, + 0xf3c4460f13b0f3e3L, 0x889f9bd76bd7335eL, 0x889ee771f755ba6eL, + 0x626984feed219b6cL, 0x2d44c737ec2ee411L, 0xb94385a263efcd37L, + 0xd909321b6637826bL, 0xc24f8a793ee6b7a7L, 0xa3ca8d24a7cf61b7L, + 0x842e40c1c54bacd9L }, + { 0x5a268ed6a661d843L, 0x02328cca4f5b30cdL, 0x16e6fed11311e177L, + 0x690decb4c6695967L, 0xbdac5bf657b2e280L, 0x827f82ca1efe42d0L, + 0xc554ec0aca5fca2fL, 0xac5276c1dde45506L, 0xb7f4cb08e3077513L, + 0x8caf6d9acc8797ccL, 0xd59648140d9332d2L, 0xcc6ae297285a409fL, + 0x7773c2a56223d093L, 0x2d5266ac5128fc09L, 0xa596b7cbbc31fe6cL, + 0x0e63319acac91328L }, + { 0xb5cd2fadf0360ac2L, 0x86b660de285e605aL, 0x82c6cf10e25b9b14L, + 0x9d5fa38daa9ac554L, 0x3dfcf1b8526c070eL, 0x0379a96b3fccc52dL, + 0xe3659c290bfcc7f5L, 0x5b1a3db569d3e6a1L, 0xb41528b59b7b42d5L, + 0x934defa49c22a006L, 0x90f380189b4ce3b6L, 0xb073bc04b3abaf32L, + 0x27a5a222ff8389e2L, 0x0b7a9d51ffa5a35bL, 0x4939ecef28e1a7c2L, + 0x88839da21872705aL }, + { 0x56b66c30701ce29aL, 0x3acaf12658981d50L, 0xd4dafc0c105f9f21L, + 0xfee571e6373e3d13L, 0xe7269c86fa2ee3caL, 0xf5cca64add20385aL, + 0x217f27573000e9acL, 0xc934db470e7273efL, 0x4294f4f7355b6776L, + 0x1faa36b96fc05180L, 0x8f88b1dbb052190bL, 0x35791b90e9eaef52L, + 0xf37fb2ebdb681b90L, 0x39d0a51d4415c369L, 0xfc59cca71d2e21c9L, + 0x64128cfea1f50c26L }, + { 0xf03678a2e8f5b0b5L, 0x5c7e249cd340f059L, 0x4144044193ca7cecL, + 0x075ca346bc83af98L, 0xf39f0033faa8bbb0L, 0x3d18f0edf38230f7L, + 0x78dff00cd448f345L, 0x849228c0d51aa475L, 0xdd4e270830c928d1L, + 0xc66ba6868f12cfd3L, 0x091049db88b3a206L, 0xd865d059016dae01L, + 0x4599e905e253e37dL, 0x322cf0c27ce9871bL, 0x014f54da174a132eL, + 0x93634a09bdabcbdaL }, + { 0x62826b27a9a2e304L, 0xc57e1866c1a4c124L, 0x913ab83222381710L, + 0x7e9b6b85a9847cfeL, 0x29655cf12b5f46fdL, 0x7295572b8038e66dL, + 0xe4cba6016fa95eabL, 0xbbc11071b9deda81L, 0x97f0009a3f1cf61eL, + 0x5372777b373e0cfbL, 0x302f909cd139d63bL, 0x1ed672da4f87d78eL, + 0x362077a3b4048763L, 0xc408c32d9dcc22b2L, 0x4b4c5bf226deeee7L, + 0x266cb467bc06357eL }, + { 0x6faa4154b56363e8L, 0x4b4fd0783c1aa4dbL, 0x14358dde2b9e6597L, + 0x5b34ae3efa004b84L, 0xcf44b2ecf19911a6L, 0x55caa833a536bf78L, + 0x606e1eb98870dc95L, 0xe3c3287d09f3511dL, 0x68b2f4eb9d5cf364L, + 0xc154e89263ab8c9eL, 0x1548828ec36ab611L, 0x0932bfcba1b7d120L, + 0x7ee7b5bc5315b8d7L, 0x782fd0d1f7473ac1L, 0xbcb029a83c8f2af3L, + 0x4b1d5a1b52454ee1L }, + { 0x12fe517463d52c0cL, 0x3735525e188c099dL, 0x5c621563360e3956L, + 0x88b3f1caacfa5a43L, 0x90123a0a797e8107L, 0xba31f6b5b15e080aL, + 0xd7de5e12fca3dadaL, 0x3287361b0df511c8L, 0x7cc800d465757d4eL, + 0x10810f3d5207ec91L, 0x0d4e56f130eea0e3L, 0xbbf7ee133ea5a2ecL, + 0x6fc07762be6abbd0L, 0xc831fdce120bf619L, 0xe07439fab622d42aL, + 0x8186b93f508e4b27L }, + { 0xc619d15409312867L, 0x7e042c05bfaf7db4L, 0xc1cf16681f5f5ddaL, + 0x50aa5057a4fc3d82L, 0xed30ed65ce68b8feL, 0xecb01c0bbeb4d644L, + 0x7b5dc444831c0497L, 0x351e6a009b7d9b1cL, 0x4bb863b9d9477c91L, + 0xaba6589105d4110aL, 0x30086cf443580b7aL, 0xb139c07690be357eL, + 0x12bfff1a27b5214eL, 0x79cfc6d722c3ab57L, 0x4743de57f34a9bfaL, + 0x0bf97e97c9ee2b2aL }, + { 0x96ec4ec8dda19e96L, 0x54ce18ea6c306e8bL, 0x7e83612b65f6918aL, + 0x1ac6f68b0d9a0d99L, 0x98a697a462fdcc09L, 0x65ce25f195bc3e13L, + 0x1896ecdab3939730L, 0x9eb81a0f32f12806L, 0xd3d7416e1d2dc7dfL, + 0xe22c7976ad473599L, 0x3de37a9a9f5ef439L, 0x6b7ac0ab9e69d94eL, + 0xe6bfa9e00a9d0bc8L, 0x576a870d5676f120L, 0x3bd91bb4feaac23fL, + 0x8fe5482c3e40aabbL }, + { 0x85ae67c2ce9a4d1eL, 0x4c3eb8034f1d2038L, 0x5c6c8f3a25d06192L, + 0x803de0ad308fb41cL, 0x9961f5bce71c294eL, 0xdc62078df02eb0daL, + 0xc87ef515b64ae8b6L, 0x69679f1e50b4d18fL, 0xc5c009a152199f43L, + 0xa7d484be0f640a5fL, 0x4c918bb123dab566L, 0xa67c114c64275d2cL, + 0x95a913b9cad2ded6L, 0x189ed18b6b4b5c8dL, 0x4aeb6206b42d3bf6L, + 0x3928c669bbc8bc3fL }, + { 0xde4bea4adacb4b64L, 0x03f62a44f26179a1L, 0xf3aac94e7a9112a4L, + 0x90448fbdd36f331eL, 0x426042bc407b85c4L, 0x5ad8a5962121b77bL, + 0x31674a4f67cee984L, 0x7fae8bbe4e3b2f0dL, 0x681df6dda7c930ebL, + 0xadeefa98c259d0d4L, 0x1b14d9e6bea1c1fdL, 0x3baadc8b21d405d1L, + 0xf01dff9373892754L, 0x81c35b3ef071cde4L, 0x1704d2e19150d0d9L, + 0x6ccc888f355134f6L }, + { 0xf8d36f0e7ad7504cL, 0xbca3265ff7959dddL, 0x0dcd1edefede67aaL, + 0x1276f4cebaebf32fL, 0x6825a6e6014edcfcL, 0x0b8c1a8299ad8eb7L, + 0x312024a909b8ce1eL, 0xcb8fd98b9cbd351aL, 0xa4841378fab1e8beL, + 0x17ed0f5d3973cacfL, 0xa17e1484259d5254L, 0x53d5b84374b91393L, + 0x8f792b211aca3ce9L, 0x035ff110c8c0f815L, 0x6afa6357ad4ed7bdL, + 0x2f151980b26faef9L }, + { 0x0c8631da29d2d439L, 0x121fbbc2bc039955L, 0x3e5a97926c05b75bL, + 0x6d6cf4c0b6ce47ecL, 0xbaaa17679d88c658L, 0x031db9e7f3355a17L, + 0x8381e3d80aef5a85L, 0xc71db29015a31bdfL, 0x638f6b749498fd7dL, + 0x44edf3f913beeef6L, 0xe6173271f4ab67b3L, 0x3a202c70fd22df11L, + 0xf7be0389205c4e92L, 0x1c219085a8eb9920L, 0x6c805ce8beb54aaaL, + 0x354b05b70ac58d65L }, + { 0x7171e2367a9170e9L, 0x01eec42d4cad50cdL, 0xffbe824f3cddccfbL, + 0xa73e8ce3a66cae1aL, 0xb7138a7f965c7d01L, 0x00058e3f5c3d971eL, + 0x52591ac32ff0a72bL, 0xa32fb5bcbbbce76fL, 0xf3241ab8a9f81a18L, + 0xf31d3332eca68630L, 0x847af9fc4482f13bL, 0x6196e217a4681be2L, + 0x9938f932e55efcf9L, 0x3e7dacb870acc705L, 0xd41be893cf09fac2L, + 0x48dc55c4ae3523a1L }, + { 0x8e623826a5092193L, 0xe46ec3626898970cL, 0x2f1356af25c9eb41L, + 0x4178064083c7d245L, 0x982def6797d00e38L, 0x382eb6e7a512151cL, + 0x154e10778af58869L, 0x187070758a51cf02L, 0xcdeba9f771313c58L, + 0x5d67b973ba155904L, 0x851c9f4b1d0d7b3aL, 0x19f29d718b8af2cdL, + 0xcb94ccff986b8d62L, 0x8725e24bb93b9c33L, 0x405ce4c566e38c68L, + 0x5f6a8edd0b6dc021L }, + { 0x83704ca58f9a8690L, 0x3f3697662f76a407L, 0xfbc12d8c69201028L, + 0x4cd58f16bce3a4cfL, 0x7804664a04aab26dL, 0x005cfbba4ea457a8L, + 0x537951b3b8a59794L, 0x4ca2b9e44fe1f739L, 0xe4428acddf325797L, + 0x648da3420ea243dbL, 0xcce6562bf43ce01eL, 0x840f0421f27db490L, + 0x156ccb708bfb7cf0L, 0x9b33480d5a8797d3L, 0x2e12e07a9eb814bbL, + 0x1ca65072ca7f87acL }, + { 0xfbb321cf2b9d25a0L, 0x66affdca40a746dbL, 0xc1c1530e59e368b5L, + 0x56ed1ea47d80068fL, 0x9b74d8fe5647dd68L, 0x1d96b50789b78da8L, + 0x39b752438bbe3391L, 0xef8d443e0d858c5fL, 0x4dd2db499646aa34L, + 0x7fad3bd1e667543cL, 0xd0d710c068980985L, 0x9f7aff3249facabaL, + 0x055dec1c14f9a192L, 0xaca663991fb307a1L, 0xac44fd9135ffff64L, + 0x462cafb6cbad3ceeL }, + { 0x1660a647de3237ddL, 0x95f735cc82b87404L, 0xf7879f59ddfa55f8L, + 0x15ef043e726b914aL, 0x1875393d1c93e298L, 0xa1a2be746ef18331L, + 0x4e7e8dfc25a9a12bL, 0xdfefc97da9c3917fL, 0xbc875d030a2ebe41L, + 0x0f75d235a732d1ccL, 0x06fee7fed9baa6d3L, 0xaa784fab65f48576L, + 0x23155e22513f83c0L, 0xd2fb77183e8f9d13L, 0x2a291503b546eafdL, + 0x1293c98c6cd93608L }, + { 0x7278125149d53b77L, 0xa6ab403d96eafac7L, 0xb7d7c7db4a36b711L, + 0x8238c70887e771c1L, 0x495f6abf33b37522L, 0xb0b0289c8c87530dL, + 0xca83cb86e77b111aL, 0xbe1c0fb8a1bd189eL, 0x58cfb2fb1ae9d7c7L, + 0xd05c23c54940c3e8L, 0x16e79e4174ad9107L, 0xa0a47f05064e7142L, + 0xc6929cd4fdfd614fL, 0xedb2584c3946988bL, 0x73e4b5f3e46f8fb1L, + 0x53b79aa168ea94baL }, + { 0x216fafce44bbb6a1L, 0xd3a5bba067821728L, 0xef1e4b30a9dd939aL, + 0x022eaf3df19efafeL, 0xfed5abce7b4ec014L, 0x64968ee6512c6738L, + 0x2311986929fe89a2L, 0x0d539d8d47397c05L, 0x6400bc54234596c4L, + 0xb9287f585346611dL, 0x04099903c9d5da0fL, 0xe5ef4997c83af2a8L, + 0xc89dc01b328151e1L, 0x150fb4a958401104L, 0x40a6f7d5f3872c9dL, + 0x8290d6d156c2e833L }, + { 0xf84637c6d8546946L, 0xda134a3969ec57faL, 0xd42359a4d789007eL, + 0xb42557fe0dc7b809L, 0xe62ae52d2d6784a9L, 0xa2714ca60bcadb5fL, + 0xcc208de633aafca5L, 0x2380ed5ced967811L, 0x6e6b55e9db321660L, + 0x1bead02ca675235aL, 0x51cc6ef9b33fa0e1L, 0xfd223e26f06a2a08L, + 0x00f332e1ec47b3cfL, 0x459f297ba0aa984eL, 0x6fa1d969ee952e14L, + 0x506ef1ab304fabb0L }, + { 0x11b4eb2735bff163L, 0x7130b96fea9fa984L, 0x66aceb3f9deb27ceL, + 0xa2daf1a59dd1c3d5L, 0xf5090a7ea73075aaL, 0x36a6af39e3071b58L, + 0xa28d633ddf73ad9cL, 0xdd354cacbdc89a16L, 0xdfea3423d4dcbc3cL, + 0x6eec74d2379d92d1L, 0xe14a456f8eed6765L, 0xfabe7743fa8feb1fL, + 0x1404ccf8b98fcbc7L, 0x6ccd2fbff71a706eL, 0xdaaf3fdb4d85c678L, + 0x415b7dbf15200344L }, + { 0x970105867d8377a7L, 0x068a3d68cb803272L, 0xfd67d289f03a4c32L, + 0x4bc7095d93c8f290L, 0x712fa13ce9e5a2b8L, 0xfc6ac6c60feb9f3bL, + 0x0cda36d96e0e54c2L, 0x4549975186320a01L, 0xf9318c9197f00f11L, + 0x01dc4c3fe6936508L, 0x769a2ef985f068aaL, 0x3522cef0a2b5511cL, + 0x006965edb4122e05L, 0xfce0fafcc175d43fL, 0x525dc9bdec831d59L, + 0x1ec314f1af58879dL }, + { 0x0663feef2c8310c2L, 0xaa7e14da457e3f74L, 0x392b10fce5346887L, + 0xcde4a38f637ec2c5L, 0x50773320b542f8dfL, 0x341302f9f7de1711L, + 0x018b1c63ae4b9bc6L, 0xf001c46edd2f9e6fL, 0xd3bb0a9726eccfa0L, + 0xa931b99d7746e0c7L, 0xe0c8b6f7f5875aecL, 0xbb32f17c96939c82L, + 0x765135d23de5a664L, 0x71936cb452abfa6bL, 0xad5cc08f2dc105deL, + 0x17e91d127fff5788L }, + { 0xbe92ced3b7e051caL, 0xc644d4fd19c776d4L, 0xc8ab4b520086784bL, + 0x3ea66227ce9d6b31L, 0x395249a3d289e9c7L, 0x54509e65d12a19eeL, + 0xa7bd46928c365aecL, 0x354997e477963e0eL, 0x0d765957b599732dL, + 0x99584aeb91d4a3b6L, 0x6e653ea41deb3e28L, 0xca7c98ed572571dfL, + 0xf301a38fb18ae1f9L, 0x1629f7c263f7b97eL, 0xdf242282afc4a0d5L, + 0x118f3b4b3ddd0c01L }, + { 0x74a0a0a87ad4762bL, 0x1aef84da8c58d175L, 0x16ff49604cf76d86L, + 0xc0be87867e60d98bL, 0x83637ffb3ecc1dbaL, 0xc244a6095dd6147aL, + 0xa3e178345b0846e5L, 0x735eb686e77a4c05L, 0x5bc18b4fdf758695L, + 0x15618d0b1bdfe52fL, 0x878ecc0d00715ba1L, 0x1dbdbd1ac2dd617fL, + 0x21d2b63121b61710L, 0x22ce8a7944f593c2L, 0x3b9b536a44f17024L, + 0x01d0a67c8d03e727L }, + { 0x7b9642361e46533cL, 0xe9477990fb88c2aeL, 0x019b5d16a42c4a18L, + 0x7135e81dd83c7a45L, 0x74a69bdd4cb663e3L, 0x7b67ecdbe76c0d63L, + 0x03d5452111e68da6L, 0x596cceb5d2e8650aL, 0xcd572dfd2af03b37L, + 0x52364ba1fabd5952L, 0x7f47d456b4ed8569L, 0x5ad8b572c950d5d4L, + 0xcadd2dfa486e2f84L, 0xdd527b43c56bb044L, 0xc9adba24997c08e6L, + 0x1b625b067da6320fL }, + { 0x44dfaa7b4fd8446dL, 0xc01b2f01af6febebL, 0xbf444388fe8838b5L, + 0xf33c434fbba9758bL, 0x2b971cba87156bc9L, 0x6b245e5c1f49098bL, + 0x87dcb5342b41c5ddL, 0xdb1f80c634d852d7L, 0x6d6e32582433da34L, + 0xf66820653f7df0c2L, 0xc4ca567c360cb365L, 0x321faac29826656aL, + 0x13f5ca6fbf069768L, 0x15397921a7076639L, 0xbdf143288400736eL, + 0x333eca9619fc948dL }, + { 0x23337948ac775d81L, 0x38c2518fd41dbbcaL, 0x623c7a4fbcfce948L, + 0xaad3623654703fe7L, 0x2b3a13a413fb3b5bL, 0x5db3565a7f5c01f0L, + 0xd72408dc52359661L, 0x5a17f8e51d616e91L, 0x90c16eebcb25b999L, + 0xf35e8cf13393743eL, 0x987da74ae54b64a7L, 0x557b322a65cd449dL, + 0x765082a537e7b15dL, 0x4d25c742f2cd134fL, 0xae9d9c074ccf0746L, + 0x72fc21108728d135L }, + { 0xa906b203f96004c8L, 0xd83f95cf458055ffL, 0xd77d586755f35909L, + 0x4a9ea6fbe550c8eeL, 0x91c8cca955a06081L, 0x4a1fee78bce82062L, + 0xeb9ade069a3df85eL, 0xfbbdcf0c7d3de666L, 0x228a391b5d336d51L, + 0x760f8d285c2ffc3cL, 0x1ee48de32f7b165bL, 0x03803d8456177040L, + 0xe573f6489deff9a0L, 0xe1a2738ea17e35a4L, 0x238ef17c8840a6c6L, + 0x480946f8b11ed92dL }, + { 0x84c747a8fd71f119L, 0x19e65c5e53eb3695L, 0x0e2f67866298587aL, + 0x48a48899ab18d6f4L, 0xa1a99024c630b8c0L, 0x849750962caaf892L, + 0xc8869abae20fd624L, 0x3b72b04d6c2b7dd4L, 0xe2775eb60992f7d0L, + 0x0089c06e7d06e684L, 0xcb3b4361e4bbd007L, 0xa1ae666b4ba846e4L, + 0xc01c2eb246464d9eL, 0xf86f2be6c1f8539fL, 0x16e8e8aecf68afc7L, + 0x8dab61fdc7386902L }, + { 0x42a5c903d54d1d45L, 0xacd4297eff4f9ba2L, 0x2d88b52034d478b4L, + 0x35b2ba2b08c4621aL, 0xd3d239bb34865402L, 0x1de76aed911f32e6L, + 0x877f8bcf3f06fdc2L, 0x802714c19ec51502L, 0xa10444eba590700dL, + 0x8694229f31dcc957L, 0x5ece77abb8169fedL, 0x55be8a152caf080eL, + 0x3eb21b14cbd7cef1L, 0x9def7ad167b97ee1L, 0xe03ca879118f690cL, + 0x6f77e62df99b29e7L }, + { 0xa271bdede40bbf59L, 0x177ba4536401aad6L, 0x1755e03573541cd1L, + 0x3465b4664b71b02fL, 0x22eb7113a813359fL, 0x9792a8fd6f38eac7L, + 0x11aa012fff3bf3b5L, 0x99aafabff85c3fbfL, 0x91e0a2ef06c0cc42L, + 0x314d5d57773b7b3aL, 0xae5e2e76d669840aL, 0x861360732e5a8be6L, + 0xee6d7578c1cf5580L, 0x2344e00f68bed102L, 0x799d78868184f0ebL, + 0x63819c91c3d2cf80L }, + { 0xca5392e17884b073L, 0x9ec3a1fceb1267eaL, 0x3d07f5f0907038a7L, + 0xcb2ac07ce4c47b70L, 0xf96664ee1bf96b91L, 0xebf575892aea4fbfL, + 0x5aabf391fade6500L, 0xc5b3376f171d1204L, 0x1ff60c51a0d3d81aL, + 0x10b2cfe7976a844bL, 0xe131cc9abda6125aL, 0xe0fc16d34ebd453eL, + 0xc0d0319a504b6bc1L, 0xe43a0be70a2f8cabL, 0xc80afeec55e49b47L, + 0x67d48d128265d7eeL }, + { 0x068d59a7ea2d56d6L, 0xd71abd0e27480a63L, 0x6bd11db0ae7366cdL, + 0xfbb639ca07204ebcL, 0x89a242e7f77e6293L, 0xdee7ca2b75ba8c3dL, + 0x472ddc3d64a2f9a8L, 0x84229df47561a010L, 0x95f62c85c5b649d4L, + 0xfdd56b1b4dc927cdL, 0xfe8bb1205ee60596L, 0x3efcaa50abf29401L, + 0xd4900d0f10d1c184L, 0x2cf113a928b01df5L, 0xa3d7ebc31f0e43f5L, + 0x27950e38e8384dc7L }, + { 0xeab21ff0e1d0fa79L, 0x4b9fd033048b5de9L, 0x4c9346892fe374cbL, + 0xbb4827fa4eb21f6bL, 0x46716f79a925e7e7L, 0x1442bf367dd4c531L, + 0x2073954cd2e96ddfL, 0x4e0141ae8502aa89L, 0x8ee00e1a8eef6cc9L, + 0x55ce84915880cdafL, 0xff3aba5c69628046L, 0x335cc4f85d15dfbfL, + 0xa7f0440c9f684f25L, 0xae80453fbb1e5bd8L, 0xa1c99813ff2225abL, + 0x54ff788479b25d71L }, + { 0x27c6ee30de40b068L, 0x9226465be6f3a51eL, 0xe24a4604fa3b21f6L, + 0x50a5a5adc0418115L, 0xe32854418df90d2bL, 0xbb74e58fdcb0c00fL, + 0xc68f1b3b4a2c08e3L, 0x339df0810ccd9ec9L, 0x915362dcb786ea9fL, + 0x28945e31c955aeadL, 0xd6a2c01d8b6a6c6bL, 0x069e82dc3678a427L, + 0x1787550028c9302cL, 0x8acda9659fa101e6L, 0x4e4e4573ee30b286L, + 0x8adbad853f1830feL }, + { 0x060ae11f0969d524L, 0xf42fdaf7f39bcc79L, 0x3cec67667cc1fcc2L, + 0x456b9cf2e2336d4fL, 0x6aa1f5de8e1c0f7fL, 0xcdbc2ad20984fb0eL, + 0x4090cfa61b464b28L, 0x40d86f301243f3efL, 0x95b16ccccd5e87e7L, + 0x403f168c3026cd41L, 0xdbe386cb816c0730L, 0x14eb86f358407a1dL, + 0xf588b4f81717e1afL, 0xb75c41a666cbc96cL, 0xf342c1aa027e71c1L, + 0x73930036c0945e5fL }, + { 0x954f757d22cdaf42L, 0x788b591df4181aabL, 0x8b986819f5514f25L, + 0x69642e08f18fd5bcL, 0x92b305d1022ceb91L, 0x1715903e6a4f6985L, + 0x4bd7d69d61179caeL, 0xdacdfd5dd29c01aaL, 0x705ddd5ad91108ccL, + 0x434ac7b164ac8f15L, 0x61a514e1b524632fL, 0x45b9e61b731fc447L, + 0xcf561348e0961b31L, 0x9c28a96773eaf223L, 0x5bd10182aa7c99d3L, + 0x8bc6ec4ae42965e2L }, + { 0xd096e5c0e7f2a32bL, 0xff54800c09388a30L, 0x06fe437c401e360cL, + 0x6655fc9cbb6054a6L, 0x510e18608457aa6eL, 0xa0acfca22b29b2b7L, + 0x732483e351b7da61L, 0xe31471ee6be6c8caL, 0xe565431c8b65c9a1L, + 0xfc9ac3b948d65cbbL, 0xd308fc21ae9b2aa8L, 0xd6a7df0daa60aa6aL, + 0x2844d96a982fc0d4L, 0xab012c2c5847a4d7L, 0x2b3c8f71dceb8955L, + 0x8e85437dbe9c7e15L }, +}; + +/* Perform the modular exponentiation in Fp* for SAKKE. + * + * Base is fixed to be the g parameter - a precomputed table is used. + * + * Striping: 128 points at a distance of 8 combined. + * Total of 256 points in table. + * Square and multiply performed in Fp*. + * + * base [in] Base. MP integer. + * exp [in] Exponent. MP integer. + * res [out] Result. MP integer. + * returns 0 on success, MP_READ_E if there are too many bytes in an array + * and MEMORY_E if memory allocation fails. + */ +static int sp_ModExp_Fp_star_x64_1024(const mp_int* base, mp_int* exp, mp_int* res) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td; + sp_digit* t; + sp_digit* tx; + sp_digit* ty; +#else + sp_digit t[4 * 2 * 16]; + sp_digit tx[2 * 16]; + sp_digit ty[2 * 16]; +#endif + sp_digit* r = NULL; + unsigned char e[128]; + int err = MP_OKAY; + int i; + int y; + + (void)base; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6 * 16 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + tx = td + 4 * 16 * 2; + ty = td + 5 * 16 * 2; +#endif + r = ty; + + (void)mp_to_unsigned_bin_len(exp, e, 128); + + XMEMCPY(tx, p1024_norm_mod, sizeof(sp_digit) * 16); + y = e[112] >> 7; + y |= (e[96] >> 7) << 1; + y |= (e[80] >> 7) << 2; + y |= (e[64] >> 7) << 3; + y |= (e[48] >> 7) << 4; + y |= (e[32] >> 7) << 5; + y |= (e[16] >> 7) << 6; + y |= (e[0] >> 7) << 7; + XMEMCPY(ty, sp_1024_g_table[y], sizeof(sp_digit) * 16); + for (i = 126; i >= 0; i--) { + y = (e[127 - (i / 8)] >> (i & 0x7)) & 1; + y |= ((e[111 - (i / 8)] >> (i & 0x7)) & 1) << 1; + y |= ((e[95 - (i / 8)] >> (i & 0x7)) & 1) << 2; + y |= ((e[79 - (i / 8)] >> (i & 0x7)) & 1) << 3; + y |= ((e[63 - (i / 8)] >> (i & 0x7)) & 1) << 4; + y |= ((e[47 - (i / 8)] >> (i & 0x7)) & 1) << 5; + y |= ((e[31 - (i / 8)] >> (i & 0x7)) & 1) << 6; + y |= ((e[15 - (i / 8)] >> (i & 0x7)) & 1) << 7; + + sp_1024_proj_sqr_16(tx, ty, t); + sp_1024_proj_mul_qx1_16(tx, ty, sp_1024_g_table[y], t); + } + } + + if (err == MP_OKAY) { + sp_1024_mont_inv_16(tx, tx, t); + sp_1024_mont_mul_16(r, tx, ty, p1024_mod, p1024_mp_mod); + XMEMSET(r + 16, 0, sizeof(sp_digit) * 16); + sp_1024_mont_reduce_16(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef HAVE_INTEL_AVX2 +/* Multiply p* in projective co-ordinates by q*. + * + * r.x = p.x - (p.y * q.y) + * r.y = (p.x * q.y) + p.y + * + * px [in,out] A single precision integer - X ordinate of number to multiply. + * py [in,out] A single precision integer - Y ordinate of number to multiply. + * q [in] A single precision integer - multiplier. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_mul_qx1_avx2_16(sp_digit* px, sp_digit* py, + const sp_digit* q, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 16; + + /* t1 = p.x * q.y */ + sp_1024_mont_mul_avx2_16(t1, px, q, p1024_mod, p1024_mp_mod); + /* t2 = p.y * q.y */ + sp_1024_mont_mul_avx2_16(t2, py, q, p1024_mod, p1024_mp_mod); + /* r.x = p.x - (p.y * q.y) */ + sp_1024_mont_sub_avx2_16(px, px, t2, p1024_mod); + /* r.y = (p.x * q.y) + p.y */ + sp_1024_mont_add_avx2_16(py, t1, py, p1024_mod); +} + +/* Square p* in projective co-ordinates. + * + * px' = (p.x + p.y) * (p.x - p.y) = p.x^2 - p.y^2 + * py' = 2 * p.x * p.y + * + * px [in,out] A single precision integer - X ordinate of number to square. + * py [in,out] A single precision integer - Y ordinate of number to square. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_sqr_avx2_16(sp_digit* px, sp_digit* py, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 16; + + /* t1 = p.x + p.y */ + sp_1024_mont_add_avx2_16(t1, px, py, p1024_mod); + /* t2 = p.x - p.y */ + sp_1024_mont_sub_avx2_16(t2, px, py, p1024_mod); + /* r.y = p.x * p.y */ + sp_1024_mont_mul_avx2_16(py, px, py, p1024_mod, p1024_mp_mod); + /* r.x = (p.x + p.y) * (p.x - p.y) */ + sp_1024_mont_mul_avx2_16(px, t1, t2, p1024_mod, p1024_mp_mod); + /* r.y = (p.x * p.y) * 2 */ + sp_1024_mont_dbl_avx2_16(py, py, p1024_mod); +} + +#ifdef WOLFSSL_SP_SMALL +/* Perform the modular exponentiation in Fp* for SAKKE. + * + * Simple square and multiply when expontent bit is one algorithm. + * Square and multiply performed in Fp*. + * + * base [in] Base. MP integer. + * exp [in] Exponent. MP integer. + * res [out] Result. MP integer. + * returns 0 on success and MEMORY_E if memory allocation fails. + */ +static int sp_ModExp_Fp_star_avx2_1024(const mp_int* base, mp_int* exp, mp_int* res) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td; + sp_digit* t; + sp_digit* tx; + sp_digit* ty; + sp_digit* b; + sp_digit* e; +#else + sp_digit t[4 * 2 * 16]; + sp_digit tx[2 * 16]; + sp_digit ty[2 * 16]; + sp_digit b[2 * 16]; + sp_digit e[2 * 16]; +#endif + sp_digit* r; + int err = MP_OKAY; + int bits; + int i; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8 * 16 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + tx = td + 4 * 16 * 2; + ty = td + 5 * 16 * 2; + b = td + 6 * 16 * 2; + e = td + 7 * 16 * 2; +#endif + r = ty; + + bits = mp_count_bits(exp); + sp_1024_from_mp(b, 16, base); + sp_1024_from_mp(e, 16, exp); + + XMEMCPY(tx, p1024_norm_mod, sizeof(sp_digit) * 16); + sp_1024_mul_avx2_16(b, b, p1024_norm_mod); + err = sp_1024_mod_16(b, b, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(ty, b, sizeof(sp_digit) * 16); + + for (i = bits - 2; i >= 0; i--) { + sp_1024_proj_sqr_avx2_16(tx, ty, t); + if ((e[i / 64] >> (i % 64)) & 1) { + sp_1024_proj_mul_qx1_avx2_16(tx, ty, b, t); + } + } + } + + if (err == MP_OKAY) { + sp_1024_mont_inv_avx2_16(tx, tx, t); + + XMEMSET(tx + 16, 0, sizeof(sp_digit) * 16); + sp_1024_mont_reduce_avx2_16(tx, p1024_mod, p1024_mp_mod); + XMEMSET(ty + 16, 0, sizeof(sp_digit) * 16); + sp_1024_mont_reduce_avx2_16(ty, p1024_mod, p1024_mp_mod); + + sp_1024_mul_avx2_16(r, tx, ty); + err = sp_1024_mod_16(r, r, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + return err; +} + +#else +/* Perform the modular exponentiation in Fp* for SAKKE. + * + * Base is fixed to be the g parameter - a precomputed table is used. + * + * Striping: 128 points at a distance of 8 combined. + * Total of 256 points in table. + * Square and multiply performed in Fp*. + * + * base [in] Base. MP integer. + * exp [in] Exponent. MP integer. + * res [out] Result. MP integer. + * returns 0 on success, MP_READ_E if there are too many bytes in an array + * and MEMORY_E if memory allocation fails. + */ +static int sp_ModExp_Fp_star_avx2_1024(const mp_int* base, mp_int* exp, mp_int* res) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td; + sp_digit* t; + sp_digit* tx; + sp_digit* ty; +#else + sp_digit t[4 * 2 * 16]; + sp_digit tx[2 * 16]; + sp_digit ty[2 * 16]; +#endif + sp_digit* r = NULL; + unsigned char e[128]; + int err = MP_OKAY; + int i; + int y; + + (void)base; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6 * 16 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + tx = td + 4 * 16 * 2; + ty = td + 5 * 16 * 2; +#endif + r = ty; + + (void)mp_to_unsigned_bin_len(exp, e, 128); + + XMEMCPY(tx, p1024_norm_mod, sizeof(sp_digit) * 16); + y = e[112] >> 7; + y |= (e[96] >> 7) << 1; + y |= (e[80] >> 7) << 2; + y |= (e[64] >> 7) << 3; + y |= (e[48] >> 7) << 4; + y |= (e[32] >> 7) << 5; + y |= (e[16] >> 7) << 6; + y |= (e[0] >> 7) << 7; + XMEMCPY(ty, sp_1024_g_table[y], sizeof(sp_digit) * 16); + for (i = 126; i >= 0; i--) { + y = (e[127 - (i / 8)] >> (i & 0x7)) & 1; + y |= ((e[111 - (i / 8)] >> (i & 0x7)) & 1) << 1; + y |= ((e[95 - (i / 8)] >> (i & 0x7)) & 1) << 2; + y |= ((e[79 - (i / 8)] >> (i & 0x7)) & 1) << 3; + y |= ((e[63 - (i / 8)] >> (i & 0x7)) & 1) << 4; + y |= ((e[47 - (i / 8)] >> (i & 0x7)) & 1) << 5; + y |= ((e[31 - (i / 8)] >> (i & 0x7)) & 1) << 6; + y |= ((e[15 - (i / 8)] >> (i & 0x7)) & 1) << 7; + + sp_1024_proj_sqr_avx2_16(tx, ty, t); + sp_1024_proj_mul_qx1_avx2_16(tx, ty, sp_1024_g_table[y], t); + } + } + + if (err == MP_OKAY) { + sp_1024_mont_inv_avx2_16(tx, tx, t); + sp_1024_mont_mul_avx2_16(r, tx, ty, p1024_mod, p1024_mp_mod); + XMEMSET(r + 16, 0, sizeof(sp_digit) * 16); + sp_1024_mont_reduce_avx2_16(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +#endif /* HAVE_INTEL_AVX2 */ +/* Perform the modular exponentiation for SAKKE. + * + * base Base. MP integer. + * exp Exponent. MP integer. + * res Result. MP integer. + * returns 0 on success, MP_READ_E if there are too many bytes in an array + * and MEMORY_E if memory allocation fails. + */ +int sp_ModExp_Fp_star_1024(const mp_int* base, mp_int* exp, mp_int* res) +{ + int err; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { + err = sp_ModExp_Fp_star_avx2_1024(base, exp, res); + } + else +#endif + { + err = sp_ModExp_Fp_star_x64_1024(base, exp, res); + } + + return err; +} + +/* Multiply p* by q* in projective co-ordinates. + * + * p.x' = (p.x * q.x) - (p.y * q.y) + * p.y' = (p.x * q.y) + (p.y * q.x) + * But applying Karatsuba: + * v0 = p.x * q.x + * v1 = p.y * q.y + * p.x' = v0 - v1 + * p.y' = (px + py) * (qx + qy) - v0 - v1 + * + * px [in,out] A single precision integer - X ordinate of number to multiply. + * py [in,out] A single precision integer - Y ordinate of number to multiply. + * qx [in] A single precision integer - X ordinate of number of + * multiplier. + * qy [in] A single precision integer - Y ordinate of number of + * multiplier. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_mul_16(sp_digit* px, sp_digit* py, + const sp_digit* qx, const sp_digit* qy, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 16; + + /* t1 = px + py */ + sp_1024_mont_add_16(t1, px, py, p1024_mod); + /* t2 = qx + qy */ + sp_1024_mont_add_16(t2, qx, qy, p1024_mod); + /* t2 = (px + py) * (qx + qy) */ + sp_1024_mont_mul_16(t2, t1, t2, p1024_mod, p1024_mp_mod); + /* t1 = py * qy */ + sp_1024_mont_mul_16(t1, py, qy, p1024_mod, p1024_mp_mod); + /* t2 = (px + py) * (qx + qy) - (py * qy) */ + sp_1024_mont_sub_16(t2, t2, t1, p1024_mod); + /* px = px * qx */ + sp_1024_mont_mul_16(px, px, qx, p1024_mod, p1024_mp_mod); + /* py = (px + py) * (qx + qy) - (py * qy) - (px * qx) */ + sp_1024_mont_sub_16(py, t2, px, p1024_mod); + /* px = (px * qx) - (py * qy)*/ + sp_1024_mont_sub_16(px, px, t1, p1024_mod); +} + +#ifndef WOLFSSL_SP_SMALL +/* + * Convert point from projective to affine but keep in Montgomery form. + * + * p [in,out] Point to convert. + * t [in] Temporary numbers: 2. + */ +static void sp_1024_mont_map_16(sp_point_1024* p, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 16; + + sp_1024_mont_inv_16(t1, p->z, t2); + sp_1024_mont_sqr_16(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(t1, t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(p->x, p->x, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_16(p->y, p->y, t1, p1024_mod, p1024_mp_mod); + XMEMCPY(p->z, p1024_norm_mod, sizeof(sp_digit) * 16); +} + +#endif /* WOLFSSL_SP_SMALL */ +/* + * Calculate gradient of line through P, P and [-2]P, accumulate line and + * double P. + * + * Calculations: + * l = 3 * (p.x^2 - p.z^4) = 3 * (p.x - p.z^2) * (p.x + p.z^2) + * r.x = l * (p.x + q.x * p.z^2) - 2 * p.y^2 + * r.y = 2 * p.y * p.z^3 * q.y (= p'.z * p.z^2 * q.y) + * v* = v*^2 * r* + * p'.x = l^2 - 8 * p.y^2 * p.x + * p'.y = (4 * p.y^2 * p.x - p'.x) * l - 8 * p.y^4 + * p'.z = 2 * p.y * p.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] p ECC point - point on E(F_p^2) to double. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_dbl_16(sp_digit* vx, sp_digit* vy, + sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 16; + sp_digit* pz2 = t + 2 * 16; + sp_digit* rx = t + 4 * 16; + sp_digit* ry = t + 6 * 16; + sp_digit* l = t + 8 * 16; + sp_digit* ty = t + 10 * 16; + + /* v = v^2 */ + sp_1024_proj_sqr_16(vx, vy, t); + /* pz2 = p.z^2 */ + sp_1024_mont_sqr_16(pz2, p->z, p1024_mod, p1024_mp_mod); + /* t1 = p.x + p.z^2 */ + sp_1024_mont_add_16(ty, p->x, pz2, p1024_mod); + /* l = p.x - p.z^2 */ + sp_1024_mont_sub_16(l, p->x, pz2, p1024_mod); + /* t1 = (p.x + p.z^2) * (p.x - p.z^2) = p.x^2 - p.z^4 */ + sp_1024_mont_mul_16(t1, l, ty, p1024_mod, p1024_mp_mod); + /* l = 3 * (p.x^2 - p.z^4) */ + sp_1024_mont_tpl_16(l, t1, p1024_mod); + /* t1 = q.x * p.z^2 */ + sp_1024_mont_mul_16(t1, q->x, pz2, p1024_mod, p1024_mp_mod); + /* t1 = p.x + q.x * p.z^2 */ + sp_1024_mont_add_16(t1, p->x, t1, p1024_mod); + /* r.x = l * (p.x + q.x * p.z^2) */ + sp_1024_mont_mul_16(rx, l, t1, p1024_mod, p1024_mp_mod); + /* r.y = 2 * p.y */ + sp_1024_mont_dbl_16(ry, p->y, p1024_mod); + /* ty = 4 * p.y ^ 2 */ + sp_1024_mont_sqr_16(ty, ry, p1024_mod, p1024_mp_mod); + /* t1 = 2 * p.y ^ 2 */ + sp_1024_div2_16(t1, ty, p1024_mod); + /* r.x -= 2 * (p.y ^ 2) */ + sp_1024_mont_sub_16(rx, rx, t1, p1024_mod); + /* p'.z = p.y * 2 * p.z */ + sp_1024_mont_mul_16(p->z, p->z, ry, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 */ + sp_1024_mont_mul_16(t1, p->z, pz2, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 * q.y */ + sp_1024_mont_mul_16(ry, t1, q->y, p1024_mod, p1024_mp_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_16(vx, vy, rx, ry, t); + + /* Double point using previously calculated values + * l = 3 * (p.x - p.z^2).(p.x + p.z^2) + * ty = 4 * p.y^2 + * p'.z = 2 * p.y * p.z + */ + /* t1 = (4 * p.y^2) ^ 2 = 16 * p.y^4 */ + sp_1024_mont_sqr_16(t1, ty, p1024_mod, p1024_mp_mod); + /* t1 = 16 * p.y^4 / 2 = 8 * p.y^4 */ + sp_1024_div2_16(t1, t1, p1024_mod); + /* p'.y = 4 * p.y^2 * p.x */ + sp_1024_mont_mul_16(p->y, ty, p->x, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 */ + sp_1024_mont_sqr_16(p->x, l, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 - 4 * p.y^2 * p.x */ + sp_1024_mont_sub_16(p->x, p->x, p->y, p1024_mod); + /* p'.x = l^2 - 8 * p.y^2 * p.x */ + sp_1024_mont_sub_16(p->x, p->x, p->y, p1024_mod); + /* p'.y = 4 * p.y^2 * p.x - p.x' */ + sp_1024_mont_sub_16(ty, p->y, p->x, p1024_mod); + /* p'.y = (4 * p.y^2 * p.x - p'.x) * l */ + sp_1024_mont_mul_16(p->y, ty, l, p1024_mod, p1024_mp_mod); + /* p'.y = (4 * p.y^2 * p.x - p'.x) * l - 8 * p.y^4 */ + sp_1024_mont_sub_16(p->y, p->y, t1, p1024_mod); +} + +#ifdef WOLFSSL_SP_SMALL +/* + * Calculate gradient of line through C, P and -C-P, accumulate line and + * add P to C. + * + * Calculations: + * r.x = (q.x + p.x) * c.y - (q.x * c.z^2 + c.x) * p.y * c.z + * r.y = (c.x - p.x * c.z^2) * q.y * c.z + * v* = v* * r* + * r = p.y * c.z^3 - c.y + * c'.x = r^2 + h^3 - 2 * c.x * h^2 + * c'.y = r * (c'.x - c.x * h^2) - c.y * h^3 + * c'.z = (c.x - p.x * c.z^2) * c.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] c ECC point - current point on E(F_p^2) to be added + * to. + * @param [in] p ECC point - point on E(F_p^2) to add. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] qx_px SP that is a constant value across adds. + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_add_one_16(sp_digit* vx, sp_digit* vy, + sp_point_1024* c, sp_point_1024* p, sp_point_1024* q, sp_digit* qx_px, + sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 16; + sp_digit* rx = t + 4 * 16; + sp_digit* ry = t + 6 * 16; + sp_digit* h = t + 8 * 16; + sp_digit* r = t + 10 * 16; + + /* r.x = (q.x + p.x) * c.y */ + sp_1024_mont_mul_16(rx, qx_px, c->y, p1024_mod, p1024_mp_mod); + /* t2 = c.z^2 */ + sp_1024_mont_sqr_16(t2, c->z, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 */ + sp_1024_mont_mul_16(t1, q->x, t2, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 + c.x */ + sp_1024_mont_add_16(h, t1, c->x, p1024_mod); + /* r = p.y * c.z */ + sp_1024_mont_mul_16(ry, p->y, c->z, p1024_mod, p1024_mp_mod); + /* t1 = (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_mul_16(t1, h, ry, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z * c.z^2 = p.y * c.z^3 */ + sp_1024_mont_mul_16(r, ry, t2, p1024_mod, p1024_mp_mod); + /* r.x -= (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_sub_16(rx, rx, t1, p1024_mod); + /* t1 = p.x * c.z^2 */ + sp_1024_mont_mul_16(t1, p->x, t2, p1024_mod, p1024_mp_mod); + /* h = c.x - p.x * c.z^2 */ + sp_1024_mont_sub_16(h, c->x, t1, p1024_mod); + /* c'.z = (c.x - p.x * c.z^2) * c.z */ + sp_1024_mont_mul_16(c->z, h, c->z, p1024_mod, p1024_mp_mod); + /* r.y = (c.x - p.x * c.z^2) * c.z * q.y */ + sp_1024_mont_mul_16(ry, c->z, q->y, p1024_mod, p1024_mp_mod); + /* v = v * r */ + sp_1024_proj_mul_16(vx, vy, rx, ry, t); + + /* Add p to c using previously calculated values. + * h = c.x - p.x * c.z^2 + * r = p.y * c.z^3 + * c'.z = (c.x - p.x * c.z^2) * c.z + */ + + /* r = p.y * c.z^3 - c.y */ + sp_1024_mont_sub_16(r, r, c->y, p1024_mod); + /* t1 = r^2 */ + sp_1024_mont_sqr_16(t1, r, p1024_mod, p1024_mp_mod); + /* t2 = h^2 */ + sp_1024_mont_sqr_16(rx, h, p1024_mod, p1024_mp_mod); + /* ry = c.x * h^2 */ + sp_1024_mont_mul_16(ry, c->x, rx, p1024_mod, p1024_mp_mod); + /* t2 = h^3 */ + sp_1024_mont_mul_16(t2, rx, h, p1024_mod, p1024_mp_mod); + /* c->x = r^2 + h^3 */ + sp_1024_mont_add_16(c->x, t1, t2, p1024_mod); + /* t1 = 2 * c.x * h^2 */ + sp_1024_mont_dbl_16(t1, ry, p1024_mod); + /* c'.x = r^2 + h^3 - 2 * c.x * h^2 */ + sp_1024_mont_sub_16(c->x, c->x, t1, p1024_mod); + /* ry = c'.x - c.x * h^2 */ + sp_1024_mont_sub_16(t1, c->x, ry, p1024_mod); + /* ry = r * (c'.x - c.x * h^2) */ + sp_1024_mont_mul_16(ry, t1, r, p1024_mod, p1024_mp_mod); + /* t2 = c.y * h^3 */ + sp_1024_mont_mul_16(t1, t2, c->y, p1024_mod, p1024_mp_mod); + /* c'.y = r * (c'.x - c.x * h^2) - c.y * h^3 */ + sp_1024_mont_sub_16(c->y, ry, t1, p1024_mod); +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * @param [in] key SAKKE key. + * @param [in] p First point on E(F_p)[q]. + * @param [in] q Second point on E(F_p)[q]. + * @param [in] r Result of calculation. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sp_Pairing_x64_1024(const ecc_point* pm, const ecc_point* qm, mp_int* res) +{ + int err = MP_OKAY; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit* qx_px; +#else + sp_digit t[6 * 2 * 16]; + sp_digit vx[2 * 16]; + sp_digit vy[2 * 16]; + sp_digit qx_px[2 * 16]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + + err = sp_1024_point_new_16(NULL, pd, p); + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 9 * 16 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 16 * 2; + vy = td + 7 * 16 * 2; + qx_px = td + 8 * 16 * 2; +#endif + r = vy; + + sp_1024_point_from_ecc_point_16(p, pm); + sp_1024_point_from_ecc_point_16(q, qm); + + err = sp_1024_mod_mul_norm_16(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 16); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 16); + + sp_1024_mont_add_16(qx_px, q->x, p->x, p1024_mod); + + for (i = 1020; i >= 0; i--) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_dbl_16(vx, vy, c, q, t); + + if ((i > 0) && ((p1024_order[i / 64] >> (i % 64)) & 1)) { + /* Accumulate line into v and add P into C. */ + sp_1024_accumulate_line_add_one_16(vx, vy, c, p, q, qx_px, t); + } + } + + /* Final exponentiation */ + sp_1024_proj_sqr_16(vx, vy, t); + sp_1024_proj_sqr_16(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_16(vx, vx, t); + sp_1024_mont_mul_16(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 16, 0, sizeof(sp_digit) * 16); + sp_1024_mont_reduce_16(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_16(c, 1, NULL); + sp_1024_point_free_16(q, 1, NULL); + sp_1024_point_free_16(p, 1, NULL); + return err; +} + +#else +/* + * Calculate gradient of line through C, P and -C-P, accumulate line and + * add P to C. + * + * Both C and P have z ordinates to use in the calculation. + * + * Calculations: + * r.x = (q.x * c.z^2 + c.x) * p.y * c.z - (q.x * p.z^2 + p.x) * c.y * p.z + * r.y = (p.x * c.z^2 - c.x * p.z^2) * q.y * p.z * c.z + * v* = v* * r* + * h = p.x * c.z^2 - c.x * p.z^2 + * r = p.y * c.z^3 - c.y * p.z^3 + * c'.x = r^2 - h^3 - 2 * c.x * p.z^2 * h^2 + * c'.y = r * (c.x * p.z^2 * h^2 - c'.x) - c.y * p.z^3 * h^3 + * c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] c ECC point - current point on E(F_p^2) to be added + * to. + * @param [in,out] p ECC point - point on E(F_p^2) to add. + * @param [in,out] q ECC point - second point on E(F_P^2). + * @param [in,out] t SP temporaries (6 used). + * @param [in,out] neg Indicates to use negative P. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static void sp_1024_accumulate_line_add_n_16(sp_digit* vx, sp_digit* vy, + const sp_point_1024* p, const sp_point_1024* q, + sp_point_1024* c, sp_digit* t, int neg) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 16; + sp_digit* rx = t + 4 * 16; + sp_digit* ry = t + 6 * 16; + sp_digit* h = t + 8 * 16; + sp_digit* r = t + 10 * 16; + + /* h = p.z^2 */ + sp_1024_mont_sqr_16(h, p->z, p1024_mod, p1024_mp_mod); + /* rx = q.x * p.z^2 */ + sp_1024_mont_mul_16(rx, q->x, h, p1024_mod, p1024_mp_mod); + /* rx = q.x * p.z^2 + p.x */ + sp_1024_mont_add_16(t2, rx, p->x, p1024_mod); + /* c.y = c.y * p.z */ + sp_1024_mont_mul_16(t1, c->y, p->z, p1024_mod, p1024_mp_mod); + /* r.x = (q.x * p.z^2 + p.x) * c.y * p.z */ + sp_1024_mont_mul_16(rx, t2, t1, p1024_mod, p1024_mp_mod); + /* c.y = c.y * p.z^3 */ + sp_1024_mont_mul_16(c->y, t1, h, p1024_mod, p1024_mp_mod); + /* t2 = c.z^2 */ + sp_1024_mont_sqr_16(t2, c->z, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 */ + sp_1024_mont_mul_16(t1, q->x, t2, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 + c.x */ + sp_1024_mont_add_16(t1, t1, c->x, p1024_mod); + /* c.x = c.x * p.z^2 */ + sp_1024_mont_mul_16(c->x, c->x, h, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z */ + sp_1024_mont_mul_16(r, p->y, c->z, p1024_mod, p1024_mp_mod); + if (neg) { + /* r = -p.y * c.z */ + sp_1024_mont_sub_16(r, p1024_mod, r, p1024_mod); + } + /* t1 = (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_mul_16(ry, t1, r, p1024_mod, p1024_mp_mod); + /* r.x -= (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_sub_16(rx, ry, rx, p1024_mod); + /* t1 = p.x * c.z^2 */ + sp_1024_mont_mul_16(t1, p->x, t2, p1024_mod, p1024_mp_mod); + /* h = p.x * c.z^2 - c.x * p.z^2 */ + sp_1024_mont_sub_16(h, t1, c->x, p1024_mod); + /* c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z */ + sp_1024_mont_mul_16(t1, h, c->z, p1024_mod, p1024_mp_mod); + /* c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z * p.z */ + sp_1024_mont_mul_16(c->z, t1, p->z, p1024_mod, p1024_mp_mod); + /* r.y = (p.x * c.z^2 - c.x * p.z^2) * c.z * p.z * q.y */ + sp_1024_mont_mul_16(ry, c->z, q->y, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z^3 */ + sp_1024_mont_mul_16(t1, r, t2, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z^3 - c.y * p.z^3 */ + sp_1024_mont_sub_16(r, t1, c->y, p1024_mod); + /* v = v * r */ + sp_1024_proj_mul_16(vx, vy, rx, ry, t); + + /* Add p to c using previously calculated values. + * h = p.x * c.z^2 - c.x * p.z^2 + * r = p.y * c.z^3 - c.y * p.z^3 + * c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z + */ + + /* t1 = r^2 */ + sp_1024_mont_sqr_16(t1, r, p1024_mod, p1024_mp_mod); + /* t2 = h^2 */ + sp_1024_mont_sqr_16(rx, h, p1024_mod, p1024_mp_mod); + /* ry = c.x * p.z^2 * h^2 */ + sp_1024_mont_mul_16(ry, rx, c->x, p1024_mod, p1024_mp_mod); + /* t2 = h^3 */ + sp_1024_mont_mul_16(t2, rx, h, p1024_mod, p1024_mp_mod); + /* c'.x = r^2 - h^3 */ + sp_1024_mont_sub_16(c->x, t1, t2, p1024_mod); + /* t1 = 2 * c.x * p.z^2 * h^2 */ + sp_1024_mont_dbl_16(t1, ry, p1024_mod); + /* c'.x = r^2 - h^3 - 2 * c.x * p.z^2 * h^2 */ + sp_1024_mont_sub_16(c->x, c->x, t1, p1024_mod); + /* ry = c.x * p.z^2 * h^2 - c'.x */ + sp_1024_mont_sub_16(t1, ry, c->x, p1024_mod); + /* ry = r * (c.x * p.z^2 * h^2 - c'.x) */ + sp_1024_mont_mul_16(ry, t1, r, p1024_mod, p1024_mp_mod); + /* t2 = c.y * p.z^3 * h^3 */ + sp_1024_mont_mul_16(t1, t2, c->y, p1024_mod, p1024_mp_mod); + /* c'.y = r * (c.x * p.z^2 * h^2 - c'.x) - c.y * p.z^3 * h^3 */ + sp_1024_mont_sub_16(c->y, ry, t1, p1024_mod); +} + +/* + * Perform n accumulate doubles and doubles of P. + * + * py = 2 * p.y + * + * For each double: + * Calculate gradient of line through P, P and [-2]P, accumulate line and + * double P. + * + * Calculations: + * l = 3 * (p.x^2 - p.z^4) = 3 * (p.x - p.z^2) * (p.x + p.z^2) + * r.x = l * (p.x + q.x * p.z^2) - py^2 / 2 + * r.y = py * p.z^3 * q.y (= p'.z * p.z^2 * q.y) + * v* = v*^2 * r* + * p'.x = l^2 - 2 * py^2 * p.x + * py' = (py^2 * p.x - p'.x) * l - py^4 (= 2 * p'.y) + * p'.z = py * p.z + * + * Finally: + * p'.y = py' / 2 + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] p ECC point - point on E(F_p^2) to double. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] n Number of times to double. + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_dbl_n_16(sp_digit* vx, sp_digit* vy, + sp_point_1024* p, const sp_point_1024* q, int n, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 16; + sp_digit* pz2 = t + 2 * 16; + sp_digit* rx = t + 4 * 16; + sp_digit* ry = t + 6 * 16; + sp_digit* l = t + 8 * 16; + sp_digit* ty = t + 10 * 16; + int i; + + /* py = 2 * p.y */ + sp_1024_mont_dbl_16(p->y, p->y, p1024_mod); + + for (i = 0; i < n; i++) { + /* v = v^2 */ + sp_1024_proj_sqr_16(vx, vy, t); + /* pz2 = p.z^2 */ + sp_1024_mont_sqr_16(pz2, p->z, p1024_mod, p1024_mp_mod); + /* t1 = p.x + p.z^2 */ + sp_1024_mont_add_16(t1, p->x, pz2, p1024_mod); + /* l = p.x - p.z^2 */ + sp_1024_mont_sub_16(l, p->x, pz2, p1024_mod); + /* t1 = (p.x + p.z^2) * (p.x - p.z^2) = p.x^2 - p.z^4 */ + sp_1024_mont_mul_16(ty, l, t1, p1024_mod, p1024_mp_mod); + /* l = 3 * (p.x^2 - p.z^4) */ + sp_1024_mont_tpl_16(l, ty, p1024_mod); + /* t1 = q.x * p.z^2 */ + sp_1024_mont_mul_16(t1, q->x, pz2, p1024_mod, p1024_mp_mod); + /* t1 = p.x + q.x * p.z^2 */ + sp_1024_mont_add_16(t1, p->x, t1, p1024_mod); + /* r.x = l * (p.x + q.x * p.z^2) */ + sp_1024_mont_mul_16(rx, l, t1, p1024_mod, p1024_mp_mod); + /* ty = py ^ 2 */ + sp_1024_mont_sqr_16(ty, p->y, p1024_mod, p1024_mp_mod); + /* t1 = py ^ 2 / 2 */ + sp_1024_div2_16(t1, ty, p1024_mod); + /* r.x -= py ^ 2 / 2 */ + sp_1024_mont_sub_16(rx, rx, t1, p1024_mod); + /* p'.z = py * pz */ + sp_1024_mont_mul_16(p->z, p->z, p->y, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 */ + sp_1024_mont_mul_16(t1, p->z, pz2, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 * q.y */ + sp_1024_mont_mul_16(ry, t1, q->y, p1024_mod, p1024_mp_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_16(vx, vy, rx, ry, t); + + /* Double point using previously calculated values + * l = 3 * (p.x - p.z^2).(p.x + p.z^2) + * ty = py^2 + * p'.z = py * p.z + */ + /* t1 = py^2 ^ 2 = py^4 */ + sp_1024_mont_sqr_16(t1, ty, p1024_mod, p1024_mp_mod); + /* py' = py^2 * p. x */ + sp_1024_mont_mul_16(p->y, ty, p->x, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 */ + sp_1024_mont_sqr_16(p->x, l, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 - py^2 * p.x */ + sp_1024_mont_sub_16(p->x, p->x, p->y, p1024_mod); + /* p'.x = l^2 - 2 * p.y^2 * p.x */ + sp_1024_mont_sub_16(p->x, p->x, p->y, p1024_mod); + /* py' = py^2 * p.x - p.x' */ + sp_1024_mont_sub_16(ty, p->y, p->x, p1024_mod); + /* py' = (p.y^2 * p.x - p'.x) * l */ + sp_1024_mont_mul_16(p->y, ty, l, p1024_mod, p1024_mp_mod); + /* py' = (p.y^2 * p.x - p'.x) * l * 2 */ + sp_1024_mont_dbl_16(p->y, p->y, p1024_mod); + /* py' = (p.y^2 * p.x - p'.x) * l * 2 - p.y^4 */ + sp_1024_mont_sub_16(p->y, p->y, t1, p1024_mod); + } + + /* p'.y = py' / 2 */ + sp_1024_div2_16(p->y, p->y, p1024_mod); +} + +/* Operations to perform based on order - 1. + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * Pairs: #dbls, add/subtract window value + */ +static const signed char sp_1024_order_op[] = { + 5, 6, -13, 9, -21, 6, -5, 8, 31, 6, 3, 6, -27, 6, 25, 9, + -1, 6, -11, 6, -13, 6, -7, 6, -15, 6, -29, 7, 25, 6, -9, 6, + -19, 7, 3, 6, 11, 9, -23, 6, 1, 6, 27, 6, 1, 7, -25, 8, + 13, 7, -13, 7, -23, 10, 19, 7, 7, 7, -3, 7, 27, 6, -7, 7, + -21, 7, 11, 7, 31, 8, 1, 7, -23, 6, -17, 6, -3, 10, 11, 6, + -21, 7, -27, 11, -29, 6, -1, 10, 15, 8, 27, 7, 17, 6, 17, 7, + -13, 8, 13, 6, 21, 7, -29, 6, 19, 7, -25, 6, 11, 9, 29, 7, + -7, 8, 27, 7, 29, 10, -1, 8, -7, 8, 17, 6, 17, 7, -27, 7, + -21, 6, -9, 6, -27, 12, -23, 6, 19, 6, 13, 6, -11, 7, 27, 6, + 17, 6, -7, 6, -25, 7, -29, 6, 9, 7, 7, 6, 13, 6, -25, 6, + -19, 6, 13, 6, -11, 6, 5, 8, 19, 6, -21, 8, 23, 7, 27, 6, + -13, 6, -19, 11, 29, 7, -15, 6, -9, 7, -21, 10, -3, 7, 21, 10, + 25, 6, -15, 6, -23, 6, 21, 6, 1, 6, 21, 7, -3, 6, -3, 7, + -7, 6, -23, 7, 7, 8, 15, 9, 5, 6, -11, 6, 21, 11, -27, 7, + 27, 6, -11, 6, 31, 6, -21, 6, 19, 6, -7, 8, -7, 13, -3, 6, + -7, 7, -3, 6, 1, 6, 7, 8, 19, 8, 11, 9, -9, 7, -31, 12, + 25, 6, -17, 9, -15, 7, 5, 6, 25, 7, -5, 7, -25, 6, 17, 8, + -19, 6, -13, 6, 27, 8, 1, 7, -5, 7, -1, 6, 21, 6, 3, 10, + -3, 1, +}; +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +static int sp_Pairing_x64_1024(const ecc_point* pm, const ecc_point* qm, mp_int* res) +{ + int err; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit (*pre_vx)[32]; + sp_digit (*pre_vy)[32]; + sp_digit (*pre_nvy)[32]; + sp_point_1024* pre_p; +#else + sp_digit t[6 * 2 * 16]; + sp_digit vx[2 * 16]; + sp_digit vy[2 * 16]; + sp_digit pre_vx[16][32]; + sp_digit pre_vy[16][32]; + sp_digit pre_nvy[16][32]; + sp_point_1024 pre_p[16]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + int j; + + err = sp_1024_point_new_16(NULL, pd, p); + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 56 * 16 * 2 + 16 * sizeof(sp_point_1024), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 16 * 2; + vy = td + 7 * 16 * 2; + pre_vx = (sp_digit(*)[32])(td + 8 * 16 * 2); + pre_vy = (sp_digit(*)[32])(td + 24 * 16 * 2); + pre_nvy = (sp_digit(*)[32])(td + 40 * 16 * 2); + pre_p = (sp_point_1024*)(td + 56 * 16 * 2); +#endif + r = vy; + + sp_1024_point_from_ecc_point_16(p, pm); + sp_1024_point_from_ecc_point_16(q, qm); + + err = sp_1024_mod_mul_norm_16(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMCPY(&pre_p[0], p, sizeof(sp_point_1024)); + XMEMSET(pre_vx[0], 0, sizeof(sp_digit) * 2 * 16); + pre_vx[0][0] = 1; + XMEMSET(pre_vy[0], 0, sizeof(sp_digit) * 2 * 16); + sp_1024_mont_sub_16(pre_nvy[0], p1024_mod, pre_vy[0], p1024_mod); + + /* [2]P for adding */ + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 16); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 16); + sp_1024_accumulate_line_dbl_16(vx, vy, c, q, t); + + /* 3, 5, ... */ + for (i = 1; i < 16; i++) { + XMEMCPY(&pre_p[i], &pre_p[i-1], sizeof(sp_point_1024)); + XMEMCPY(pre_vx[i], pre_vx[i-1], sizeof(sp_digit) * 2 * 16); + XMEMCPY(pre_vy[i], pre_vy[i-1], sizeof(sp_digit) * 2 * 16); + sp_1024_proj_mul_16(pre_vx[i], pre_vy[i], vx, vy, t); + sp_1024_accumulate_line_add_n_16(pre_vx[i], pre_vy[i], c, + q, &pre_p[i], t, 0); + sp_1024_mont_sub_16(pre_nvy[i], p1024_mod, pre_vy[i], p1024_mod); + } + + j = sp_1024_order_op[0] / 2; + XMEMCPY(c, &pre_p[j], sizeof(sp_point_1024)); + XMEMCPY(vx, pre_vx[j], sizeof(sp_digit) * 2 * 16); + XMEMCPY(vy, pre_vy[j], sizeof(sp_digit) * 2 * 16); + + /* Accumulate line into v and double point n times. */ + sp_1024_accumulate_line_dbl_n_16(vx, vy, c, q, + sp_1024_order_op[1], t); + + for (i = 2; i < 290; i += 2) { + j = sp_1024_order_op[i]; + if (j > 0) { + j /= 2; + /* Accumulate line into v and add P into C. */ + sp_1024_proj_mul_16(vx, vy, pre_vx[j], pre_vy[j], t); + sp_1024_accumulate_line_add_n_16(vx, vy, &pre_p[j], q, c, + t, 0); + } + else { + j = -j / 2; + /* Accumulate line into v and add P into C. */ + sp_1024_proj_mul_16(vx, vy, pre_vx[j], pre_nvy[j], t); + sp_1024_accumulate_line_add_n_16(vx, vy, &pre_p[j], q, c, + t, 1); + } + + /* Accumulate line into v and double point n times. */ + sp_1024_accumulate_line_dbl_n_16(vx, vy, c, q, + sp_1024_order_op[i + 1], t); + } + + /* Final exponentiation */ + sp_1024_proj_sqr_16(vx, vy, t); + sp_1024_proj_sqr_16(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_16(vx, vx, t); + sp_1024_mont_mul_16(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 16, 0, sizeof(sp_digit) * 16); + sp_1024_mont_reduce_16(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_16(c, 1, NULL); + sp_1024_point_free_16(q, 1, NULL); + sp_1024_point_free_16(p, 1, NULL); + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef HAVE_INTEL_AVX2 +/* Multiply p* by q* in projective co-ordinates. + * + * p.x' = (p.x * q.x) - (p.y * q.y) + * p.y' = (p.x * q.y) + (p.y * q.x) + * But applying Karatsuba: + * v0 = p.x * q.x + * v1 = p.y * q.y + * p.x' = v0 - v1 + * p.y' = (px + py) * (qx + qy) - v0 - v1 + * + * px [in,out] A single precision integer - X ordinate of number to multiply. + * py [in,out] A single precision integer - Y ordinate of number to multiply. + * qx [in] A single precision integer - X ordinate of number of + * multiplier. + * qy [in] A single precision integer - Y ordinate of number of + * multiplier. + * t [in] Two single precision integers - temps. + */ +static void sp_1024_proj_mul_avx2_16(sp_digit* px, sp_digit* py, + const sp_digit* qx, const sp_digit* qy, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 16; + + /* t1 = px + py */ + sp_1024_mont_add_avx2_16(t1, px, py, p1024_mod); + /* t2 = qx + qy */ + sp_1024_mont_add_avx2_16(t2, qx, qy, p1024_mod); + /* t2 = (px + py) * (qx + qy) */ + sp_1024_mont_mul_avx2_16(t2, t1, t2, p1024_mod, p1024_mp_mod); + /* t1 = py * qy */ + sp_1024_mont_mul_avx2_16(t1, py, qy, p1024_mod, p1024_mp_mod); + /* t2 = (px + py) * (qx + qy) - (py * qy) */ + sp_1024_mont_sub_avx2_16(t2, t2, t1, p1024_mod); + /* px = px * qx */ + sp_1024_mont_mul_avx2_16(px, px, qx, p1024_mod, p1024_mp_mod); + /* py = (px + py) * (qx + qy) - (py * qy) - (px * qx) */ + sp_1024_mont_sub_avx2_16(py, t2, px, p1024_mod); + /* px = (px * qx) - (py * qy)*/ + sp_1024_mont_sub_avx2_16(px, px, t1, p1024_mod); +} + +#ifndef WOLFSSL_SP_SMALL +/* + * Convert point from projective to affine but keep in Montgomery form. + * + * p [in,out] Point to convert. + * t [in] Temporary numbers: 2. + */ +static void sp_1024_mont_map_avx2_16(sp_point_1024* p, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 16; + + sp_1024_mont_inv_avx2_16(t1, p->z, t2); + sp_1024_mont_sqr_avx2_16(t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(t1, t2, t1, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(p->x, p->x, t2, p1024_mod, p1024_mp_mod); + sp_1024_mont_mul_avx2_16(p->y, p->y, t1, p1024_mod, p1024_mp_mod); + XMEMCPY(p->z, p1024_norm_mod, sizeof(sp_digit) * 16); +} + +#endif /* WOLFSSL_SP_SMALL */ +/* + * Calculate gradient of line through P, P and [-2]P, accumulate line and + * double P. + * + * Calculations: + * l = 3 * (p.x^2 - p.z^4) = 3 * (p.x - p.z^2) * (p.x + p.z^2) + * r.x = l * (p.x + q.x * p.z^2) - 2 * p.y^2 + * r.y = 2 * p.y * p.z^3 * q.y (= p'.z * p.z^2 * q.y) + * v* = v*^2 * r* + * p'.x = l^2 - 8 * p.y^2 * p.x + * p'.y = (4 * p.y^2 * p.x - p'.x) * l - 8 * p.y^4 + * p'.z = 2 * p.y * p.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] p ECC point - point on E(F_p^2) to double. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_dbl_avx2_16(sp_digit* vx, sp_digit* vy, + sp_point_1024* p, const sp_point_1024* q, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 16; + sp_digit* pz2 = t + 2 * 16; + sp_digit* rx = t + 4 * 16; + sp_digit* ry = t + 6 * 16; + sp_digit* l = t + 8 * 16; + sp_digit* ty = t + 10 * 16; + + /* v = v^2 */ + sp_1024_proj_sqr_avx2_16(vx, vy, t); + /* pz2 = p.z^2 */ + sp_1024_mont_sqr_avx2_16(pz2, p->z, p1024_mod, p1024_mp_mod); + /* t1 = p.x + p.z^2 */ + sp_1024_mont_add_avx2_16(ty, p->x, pz2, p1024_mod); + /* l = p.x - p.z^2 */ + sp_1024_mont_sub_avx2_16(l, p->x, pz2, p1024_mod); + /* t1 = (p.x + p.z^2) * (p.x - p.z^2) = p.x^2 - p.z^4 */ + sp_1024_mont_mul_avx2_16(t1, l, ty, p1024_mod, p1024_mp_mod); + /* l = 3 * (p.x^2 - p.z^4) */ + sp_1024_mont_tpl_avx2_16(l, t1, p1024_mod); + /* t1 = q.x * p.z^2 */ + sp_1024_mont_mul_avx2_16(t1, q->x, pz2, p1024_mod, p1024_mp_mod); + /* t1 = p.x + q.x * p.z^2 */ + sp_1024_mont_add_avx2_16(t1, p->x, t1, p1024_mod); + /* r.x = l * (p.x + q.x * p.z^2) */ + sp_1024_mont_mul_avx2_16(rx, l, t1, p1024_mod, p1024_mp_mod); + /* r.y = 2 * p.y */ + sp_1024_mont_dbl_avx2_16(ry, p->y, p1024_mod); + /* ty = 4 * p.y ^ 2 */ + sp_1024_mont_sqr_avx2_16(ty, ry, p1024_mod, p1024_mp_mod); + /* t1 = 2 * p.y ^ 2 */ + sp_1024_div2_avx2_16(t1, ty, p1024_mod); + /* r.x -= 2 * (p.y ^ 2) */ + sp_1024_mont_sub_avx2_16(rx, rx, t1, p1024_mod); + /* p'.z = p.y * 2 * p.z */ + sp_1024_mont_mul_avx2_16(p->z, p->z, ry, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 */ + sp_1024_mont_mul_avx2_16(t1, p->z, pz2, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 * q.y */ + sp_1024_mont_mul_avx2_16(ry, t1, q->y, p1024_mod, p1024_mp_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_avx2_16(vx, vy, rx, ry, t); + + /* Double point using previously calculated values + * l = 3 * (p.x - p.z^2).(p.x + p.z^2) + * ty = 4 * p.y^2 + * p'.z = 2 * p.y * p.z + */ + /* t1 = (4 * p.y^2) ^ 2 = 16 * p.y^4 */ + sp_1024_mont_sqr_avx2_16(t1, ty, p1024_mod, p1024_mp_mod); + /* t1 = 16 * p.y^4 / 2 = 8 * p.y^4 */ + sp_1024_div2_avx2_16(t1, t1, p1024_mod); + /* p'.y = 4 * p.y^2 * p.x */ + sp_1024_mont_mul_avx2_16(p->y, ty, p->x, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 */ + sp_1024_mont_sqr_avx2_16(p->x, l, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 - 4 * p.y^2 * p.x */ + sp_1024_mont_sub_avx2_16(p->x, p->x, p->y, p1024_mod); + /* p'.x = l^2 - 8 * p.y^2 * p.x */ + sp_1024_mont_sub_avx2_16(p->x, p->x, p->y, p1024_mod); + /* p'.y = 4 * p.y^2 * p.x - p.x' */ + sp_1024_mont_sub_avx2_16(ty, p->y, p->x, p1024_mod); + /* p'.y = (4 * p.y^2 * p.x - p'.x) * l */ + sp_1024_mont_mul_avx2_16(p->y, ty, l, p1024_mod, p1024_mp_mod); + /* p'.y = (4 * p.y^2 * p.x - p'.x) * l - 8 * p.y^4 */ + sp_1024_mont_sub_avx2_16(p->y, p->y, t1, p1024_mod); +} + +#ifdef WOLFSSL_SP_SMALL +/* + * Calculate gradient of line through C, P and -C-P, accumulate line and + * add P to C. + * + * Calculations: + * r.x = (q.x + p.x) * c.y - (q.x * c.z^2 + c.x) * p.y * c.z + * r.y = (c.x - p.x * c.z^2) * q.y * c.z + * v* = v* * r* + * r = p.y * c.z^3 - c.y + * c'.x = r^2 + h^3 - 2 * c.x * h^2 + * c'.y = r * (c'.x - c.x * h^2) - c.y * h^3 + * c'.z = (c.x - p.x * c.z^2) * c.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] c ECC point - current point on E(F_p^2) to be added + * to. + * @param [in] p ECC point - point on E(F_p^2) to add. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] qx_px SP that is a constant value across adds. + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_add_one_avx2_16(sp_digit* vx, sp_digit* vy, + sp_point_1024* c, sp_point_1024* p, sp_point_1024* q, sp_digit* qx_px, + sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 16; + sp_digit* rx = t + 4 * 16; + sp_digit* ry = t + 6 * 16; + sp_digit* h = t + 8 * 16; + sp_digit* r = t + 10 * 16; + + /* r.x = (q.x + p.x) * c.y */ + sp_1024_mont_mul_avx2_16(rx, qx_px, c->y, p1024_mod, p1024_mp_mod); + /* t2 = c.z^2 */ + sp_1024_mont_sqr_avx2_16(t2, c->z, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 */ + sp_1024_mont_mul_avx2_16(t1, q->x, t2, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 + c.x */ + sp_1024_mont_add_avx2_16(h, t1, c->x, p1024_mod); + /* r = p.y * c.z */ + sp_1024_mont_mul_avx2_16(ry, p->y, c->z, p1024_mod, p1024_mp_mod); + /* t1 = (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_mul_avx2_16(t1, h, ry, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z * c.z^2 = p.y * c.z^3 */ + sp_1024_mont_mul_avx2_16(r, ry, t2, p1024_mod, p1024_mp_mod); + /* r.x -= (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_sub_avx2_16(rx, rx, t1, p1024_mod); + /* t1 = p.x * c.z^2 */ + sp_1024_mont_mul_avx2_16(t1, p->x, t2, p1024_mod, p1024_mp_mod); + /* h = c.x - p.x * c.z^2 */ + sp_1024_mont_sub_avx2_16(h, c->x, t1, p1024_mod); + /* c'.z = (c.x - p.x * c.z^2) * c.z */ + sp_1024_mont_mul_avx2_16(c->z, h, c->z, p1024_mod, p1024_mp_mod); + /* r.y = (c.x - p.x * c.z^2) * c.z * q.y */ + sp_1024_mont_mul_avx2_16(ry, c->z, q->y, p1024_mod, p1024_mp_mod); + /* v = v * r */ + sp_1024_proj_mul_avx2_16(vx, vy, rx, ry, t); + + /* Add p to c using previously calculated values. + * h = c.x - p.x * c.z^2 + * r = p.y * c.z^3 + * c'.z = (c.x - p.x * c.z^2) * c.z + */ + + /* r = p.y * c.z^3 - c.y */ + sp_1024_mont_sub_avx2_16(r, r, c->y, p1024_mod); + /* t1 = r^2 */ + sp_1024_mont_sqr_avx2_16(t1, r, p1024_mod, p1024_mp_mod); + /* t2 = h^2 */ + sp_1024_mont_sqr_avx2_16(rx, h, p1024_mod, p1024_mp_mod); + /* ry = c.x * h^2 */ + sp_1024_mont_mul_avx2_16(ry, c->x, rx, p1024_mod, p1024_mp_mod); + /* t2 = h^3 */ + sp_1024_mont_mul_avx2_16(t2, rx, h, p1024_mod, p1024_mp_mod); + /* c->x = r^2 + h^3 */ + sp_1024_mont_add_avx2_16(c->x, t1, t2, p1024_mod); + /* t1 = 2 * c.x * h^2 */ + sp_1024_mont_dbl_avx2_16(t1, ry, p1024_mod); + /* c'.x = r^2 + h^3 - 2 * c.x * h^2 */ + sp_1024_mont_sub_avx2_16(c->x, c->x, t1, p1024_mod); + /* ry = c'.x - c.x * h^2 */ + sp_1024_mont_sub_avx2_16(t1, c->x, ry, p1024_mod); + /* ry = r * (c'.x - c.x * h^2) */ + sp_1024_mont_mul_avx2_16(ry, t1, r, p1024_mod, p1024_mp_mod); + /* t2 = c.y * h^3 */ + sp_1024_mont_mul_avx2_16(t1, t2, c->y, p1024_mod, p1024_mp_mod); + /* c'.y = r * (c'.x - c.x * h^2) - c.y * h^3 */ + sp_1024_mont_sub_avx2_16(c->y, ry, t1, p1024_mod); +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * @param [in] key SAKKE key. + * @param [in] p First point on E(F_p)[q]. + * @param [in] q Second point on E(F_p)[q]. + * @param [in] r Result of calculation. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static int sp_Pairing_avx2_1024(const ecc_point* pm, const ecc_point* qm, mp_int* res) +{ + int err = MP_OKAY; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit* qx_px; +#else + sp_digit t[6 * 2 * 16]; + sp_digit vx[2 * 16]; + sp_digit vy[2 * 16]; + sp_digit qx_px[2 * 16]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + + err = sp_1024_point_new_16(NULL, pd, p); + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 9 * 16 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 16 * 2; + vy = td + 7 * 16 * 2; + qx_px = td + 8 * 16 * 2; +#endif + r = vy; + + sp_1024_point_from_ecc_point_16(p, pm); + sp_1024_point_from_ecc_point_16(q, qm); + + err = sp_1024_mod_mul_norm_avx2_16(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_avx2_16(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_avx2_16(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_avx2_16(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_avx2_16(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 16); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 16); + + sp_1024_mont_add_avx2_16(qx_px, q->x, p->x, p1024_mod); + + for (i = 1020; i >= 0; i--) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_dbl_avx2_16(vx, vy, c, q, t); + + if ((i > 0) && ((p1024_order[i / 64] >> (i % 64)) & 1)) { + /* Accumulate line into v and add P into C. */ + sp_1024_accumulate_line_add_one_avx2_16(vx, vy, c, p, q, qx_px, t); + } + } + + /* Final exponentiation */ + sp_1024_proj_sqr_avx2_16(vx, vy, t); + sp_1024_proj_sqr_avx2_16(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_avx2_16(vx, vx, t); + sp_1024_mont_mul_avx2_16(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 16, 0, sizeof(sp_digit) * 16); + sp_1024_mont_reduce_16(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_16(c, 1, NULL); + sp_1024_point_free_16(q, 1, NULL); + sp_1024_point_free_16(p, 1, NULL); + return err; +} + +#else +/* + * Calculate gradient of line through C, P and -C-P, accumulate line and + * add P to C. + * + * Both C and P have z ordinates to use in the calculation. + * + * Calculations: + * r.x = (q.x * c.z^2 + c.x) * p.y * c.z - (q.x * p.z^2 + p.x) * c.y * p.z + * r.y = (p.x * c.z^2 - c.x * p.z^2) * q.y * p.z * c.z + * v* = v* * r* + * h = p.x * c.z^2 - c.x * p.z^2 + * r = p.y * c.z^3 - c.y * p.z^3 + * c'.x = r^2 - h^3 - 2 * c.x * p.z^2 * h^2 + * c'.y = r * (c.x * p.z^2 * h^2 - c'.x) - c.y * p.z^3 * h^3 + * c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] c ECC point - current point on E(F_p^2) to be added + * to. + * @param [in,out] p ECC point - point on E(F_p^2) to add. + * @param [in,out] q ECC point - second point on E(F_P^2). + * @param [in,out] t SP temporaries (6 used). + * @param [in,out] neg Indicates to use negative P. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +static void sp_1024_accumulate_line_add_n_avx2_16(sp_digit* vx, sp_digit* vy, + const sp_point_1024* p, const sp_point_1024* q, + sp_point_1024* c, sp_digit* t, int neg) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 16; + sp_digit* rx = t + 4 * 16; + sp_digit* ry = t + 6 * 16; + sp_digit* h = t + 8 * 16; + sp_digit* r = t + 10 * 16; + + /* h = p.z^2 */ + sp_1024_mont_sqr_avx2_16(h, p->z, p1024_mod, p1024_mp_mod); + /* rx = q.x * p.z^2 */ + sp_1024_mont_mul_avx2_16(rx, q->x, h, p1024_mod, p1024_mp_mod); + /* rx = q.x * p.z^2 + p.x */ + sp_1024_mont_add_avx2_16(t2, rx, p->x, p1024_mod); + /* c.y = c.y * p.z */ + sp_1024_mont_mul_avx2_16(t1, c->y, p->z, p1024_mod, p1024_mp_mod); + /* r.x = (q.x * p.z^2 + p.x) * c.y * p.z */ + sp_1024_mont_mul_avx2_16(rx, t2, t1, p1024_mod, p1024_mp_mod); + /* c.y = c.y * p.z^3 */ + sp_1024_mont_mul_avx2_16(c->y, t1, h, p1024_mod, p1024_mp_mod); + /* t2 = c.z^2 */ + sp_1024_mont_sqr_avx2_16(t2, c->z, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 */ + sp_1024_mont_mul_avx2_16(t1, q->x, t2, p1024_mod, p1024_mp_mod); + /* t1 = q.x * c.z^2 + c.x */ + sp_1024_mont_add_avx2_16(t1, t1, c->x, p1024_mod); + /* c.x = c.x * p.z^2 */ + sp_1024_mont_mul_avx2_16(c->x, c->x, h, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z */ + sp_1024_mont_mul_avx2_16(r, p->y, c->z, p1024_mod, p1024_mp_mod); + if (neg) { + /* r = -p.y * c.z */ + sp_1024_mont_sub_avx2_16(r, p1024_mod, r, p1024_mod); + } + /* t1 = (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_mul_avx2_16(ry, t1, r, p1024_mod, p1024_mp_mod); + /* r.x -= (q.x * c.z^2 + c.x) * p.y * c.z */ + sp_1024_mont_sub_avx2_16(rx, ry, rx, p1024_mod); + /* t1 = p.x * c.z^2 */ + sp_1024_mont_mul_avx2_16(t1, p->x, t2, p1024_mod, p1024_mp_mod); + /* h = p.x * c.z^2 - c.x * p.z^2 */ + sp_1024_mont_sub_avx2_16(h, t1, c->x, p1024_mod); + /* c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z */ + sp_1024_mont_mul_avx2_16(t1, h, c->z, p1024_mod, p1024_mp_mod); + /* c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z * p.z */ + sp_1024_mont_mul_avx2_16(c->z, t1, p->z, p1024_mod, p1024_mp_mod); + /* r.y = (p.x * c.z^2 - c.x * p.z^2) * c.z * p.z * q.y */ + sp_1024_mont_mul_avx2_16(ry, c->z, q->y, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z^3 */ + sp_1024_mont_mul_avx2_16(t1, r, t2, p1024_mod, p1024_mp_mod); + /* r = p.y * c.z^3 - c.y * p.z^3 */ + sp_1024_mont_sub_avx2_16(r, t1, c->y, p1024_mod); + /* v = v * r */ + sp_1024_proj_mul_avx2_16(vx, vy, rx, ry, t); + + /* Add p to c using previously calculated values. + * h = p.x * c.z^2 - c.x * p.z^2 + * r = p.y * c.z^3 - c.y * p.z^3 + * c'.z = (p.x * c.z^2 - c.x * p.z^2) * c.z + */ + + /* t1 = r^2 */ + sp_1024_mont_sqr_avx2_16(t1, r, p1024_mod, p1024_mp_mod); + /* t2 = h^2 */ + sp_1024_mont_sqr_avx2_16(rx, h, p1024_mod, p1024_mp_mod); + /* ry = c.x * p.z^2 * h^2 */ + sp_1024_mont_mul_avx2_16(ry, rx, c->x, p1024_mod, p1024_mp_mod); + /* t2 = h^3 */ + sp_1024_mont_mul_avx2_16(t2, rx, h, p1024_mod, p1024_mp_mod); + /* c'.x = r^2 - h^3 */ + sp_1024_mont_sub_avx2_16(c->x, t1, t2, p1024_mod); + /* t1 = 2 * c.x * p.z^2 * h^2 */ + sp_1024_mont_dbl_avx2_16(t1, ry, p1024_mod); + /* c'.x = r^2 - h^3 - 2 * c.x * p.z^2 * h^2 */ + sp_1024_mont_sub_avx2_16(c->x, c->x, t1, p1024_mod); + /* ry = c.x * p.z^2 * h^2 - c'.x */ + sp_1024_mont_sub_avx2_16(t1, ry, c->x, p1024_mod); + /* ry = r * (c.x * p.z^2 * h^2 - c'.x) */ + sp_1024_mont_mul_avx2_16(ry, t1, r, p1024_mod, p1024_mp_mod); + /* t2 = c.y * p.z^3 * h^3 */ + sp_1024_mont_mul_avx2_16(t1, t2, c->y, p1024_mod, p1024_mp_mod); + /* c'.y = r * (c.x * p.z^2 * h^2 - c'.x) - c.y * p.z^3 * h^3 */ + sp_1024_mont_sub_avx2_16(c->y, ry, t1, p1024_mod); +} + +/* + * Perform n accumulate doubles and doubles of P. + * + * py = 2 * p.y + * + * For each double: + * Calculate gradient of line through P, P and [-2]P, accumulate line and + * double P. + * + * Calculations: + * l = 3 * (p.x^2 - p.z^4) = 3 * (p.x - p.z^2) * (p.x + p.z^2) + * r.x = l * (p.x + q.x * p.z^2) - py^2 / 2 + * r.y = py * p.z^3 * q.y (= p'.z * p.z^2 * q.y) + * v* = v*^2 * r* + * p'.x = l^2 - 2 * py^2 * p.x + * py' = (py^2 * p.x - p'.x) * l - py^4 (= 2 * p'.y) + * p'.z = py * p.z + * + * Finally: + * p'.y = py' / 2 + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in,out] p ECC point - point on E(F_p^2) to double. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] n Number of times to double. + * @param [in] t SP temporaries (6 used). + */ +static void sp_1024_accumulate_line_dbl_n_avx2_16(sp_digit* vx, sp_digit* vy, + sp_point_1024* p, const sp_point_1024* q, int n, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 16; + sp_digit* pz2 = t + 2 * 16; + sp_digit* rx = t + 4 * 16; + sp_digit* ry = t + 6 * 16; + sp_digit* l = t + 8 * 16; + sp_digit* ty = t + 10 * 16; + int i; + + /* py = 2 * p.y */ + sp_1024_mont_dbl_avx2_16(p->y, p->y, p1024_mod); + + for (i = 0; i < n; i++) { + /* v = v^2 */ + sp_1024_proj_sqr_avx2_16(vx, vy, t); + /* pz2 = p.z^2 */ + sp_1024_mont_sqr_avx2_16(pz2, p->z, p1024_mod, p1024_mp_mod); + /* t1 = p.x + p.z^2 */ + sp_1024_mont_add_avx2_16(t1, p->x, pz2, p1024_mod); + /* l = p.x - p.z^2 */ + sp_1024_mont_sub_avx2_16(l, p->x, pz2, p1024_mod); + /* t1 = (p.x + p.z^2) * (p.x - p.z^2) = p.x^2 - p.z^4 */ + sp_1024_mont_mul_avx2_16(ty, l, t1, p1024_mod, p1024_mp_mod); + /* l = 3 * (p.x^2 - p.z^4) */ + sp_1024_mont_tpl_avx2_16(l, ty, p1024_mod); + /* t1 = q.x * p.z^2 */ + sp_1024_mont_mul_avx2_16(t1, q->x, pz2, p1024_mod, p1024_mp_mod); + /* t1 = p.x + q.x * p.z^2 */ + sp_1024_mont_add_avx2_16(t1, p->x, t1, p1024_mod); + /* r.x = l * (p.x + q.x * p.z^2) */ + sp_1024_mont_mul_avx2_16(rx, l, t1, p1024_mod, p1024_mp_mod); + /* ty = py ^ 2 */ + sp_1024_mont_sqr_avx2_16(ty, p->y, p1024_mod, p1024_mp_mod); + /* t1 = py ^ 2 / 2 */ + sp_1024_div2_avx2_16(t1, ty, p1024_mod); + /* r.x -= py ^ 2 / 2 */ + sp_1024_mont_sub_avx2_16(rx, rx, t1, p1024_mod); + /* p'.z = py * pz */ + sp_1024_mont_mul_avx2_16(p->z, p->z, p->y, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 */ + sp_1024_mont_mul_avx2_16(t1, p->z, pz2, p1024_mod, p1024_mp_mod); + /* r.y = p'.z * p.z^2 * q.y */ + sp_1024_mont_mul_avx2_16(ry, t1, q->y, p1024_mod, p1024_mp_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_avx2_16(vx, vy, rx, ry, t); + + /* Double point using previously calculated values + * l = 3 * (p.x - p.z^2).(p.x + p.z^2) + * ty = py^2 + * p'.z = py * p.z + */ + /* t1 = py^2 ^ 2 = py^4 */ + sp_1024_mont_sqr_avx2_16(t1, ty, p1024_mod, p1024_mp_mod); + /* py' = py^2 * p. x */ + sp_1024_mont_mul_avx2_16(p->y, ty, p->x, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 */ + sp_1024_mont_sqr_avx2_16(p->x, l, p1024_mod, p1024_mp_mod); + /* p'.x = l^2 - py^2 * p.x */ + sp_1024_mont_sub_avx2_16(p->x, p->x, p->y, p1024_mod); + /* p'.x = l^2 - 2 * p.y^2 * p.x */ + sp_1024_mont_sub_avx2_16(p->x, p->x, p->y, p1024_mod); + /* py' = py^2 * p.x - p.x' */ + sp_1024_mont_sub_avx2_16(ty, p->y, p->x, p1024_mod); + /* py' = (p.y^2 * p.x - p'.x) * l */ + sp_1024_mont_mul_avx2_16(p->y, ty, l, p1024_mod, p1024_mp_mod); + /* py' = (p.y^2 * p.x - p'.x) * l * 2 */ + sp_1024_mont_dbl_avx2_16(p->y, p->y, p1024_mod); + /* py' = (p.y^2 * p.x - p'.x) * l * 2 - p.y^4 */ + sp_1024_mont_sub_avx2_16(p->y, p->y, t1, p1024_mod); + } + + /* p'.y = py' / 2 */ + sp_1024_div2_avx2_16(p->y, p->y, p1024_mod); +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +static int sp_Pairing_avx2_1024(const ecc_point* pm, const ecc_point* qm, mp_int* res) +{ + int err; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit (*pre_vx)[32]; + sp_digit (*pre_vy)[32]; + sp_digit (*pre_nvy)[32]; + sp_point_1024* pre_p; +#else + sp_digit t[6 * 2 * 16]; + sp_digit vx[2 * 16]; + sp_digit vy[2 * 16]; + sp_digit pre_vx[16][32]; + sp_digit pre_vy[16][32]; + sp_digit pre_nvy[16][32]; + sp_point_1024 pre_p[16]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + int j; + + err = sp_1024_point_new_16(NULL, pd, p); + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 56 * 16 * 2 + 16 * sizeof(sp_point_1024), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 16 * 2; + vy = td + 7 * 16 * 2; + pre_vx = (sp_digit(*)[32])(td + 8 * 16 * 2); + pre_vy = (sp_digit(*)[32])(td + 24 * 16 * 2); + pre_nvy = (sp_digit(*)[32])(td + 40 * 16 * 2); + pre_p = (sp_point_1024*)(td + 56 * 16 * 2); +#endif + r = vy; + + sp_1024_point_from_ecc_point_16(p, pm); + sp_1024_point_from_ecc_point_16(q, qm); + + err = sp_1024_mod_mul_norm_avx2_16(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_avx2_16(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_avx2_16(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_avx2_16(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_avx2_16(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMCPY(&pre_p[0], p, sizeof(sp_point_1024)); + XMEMSET(pre_vx[0], 0, sizeof(sp_digit) * 2 * 16); + pre_vx[0][0] = 1; + XMEMSET(pre_vy[0], 0, sizeof(sp_digit) * 2 * 16); + sp_1024_mont_sub_avx2_16(pre_nvy[0], p1024_mod, pre_vy[0], p1024_mod); + + /* [2]P for adding */ + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 16); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 16); + sp_1024_accumulate_line_dbl_avx2_16(vx, vy, c, q, t); + + /* 3, 5, ... */ + for (i = 1; i < 16; i++) { + XMEMCPY(&pre_p[i], &pre_p[i-1], sizeof(sp_point_1024)); + XMEMCPY(pre_vx[i], pre_vx[i-1], sizeof(sp_digit) * 2 * 16); + XMEMCPY(pre_vy[i], pre_vy[i-1], sizeof(sp_digit) * 2 * 16); + sp_1024_proj_mul_avx2_16(pre_vx[i], pre_vy[i], vx, vy, t); + sp_1024_accumulate_line_add_n_avx2_16(pre_vx[i], pre_vy[i], c, + q, &pre_p[i], t, 0); + sp_1024_mont_sub_avx2_16(pre_nvy[i], p1024_mod, pre_vy[i], p1024_mod); + } + + j = sp_1024_order_op[0] / 2; + XMEMCPY(c, &pre_p[j], sizeof(sp_point_1024)); + XMEMCPY(vx, pre_vx[j], sizeof(sp_digit) * 2 * 16); + XMEMCPY(vy, pre_vy[j], sizeof(sp_digit) * 2 * 16); + + /* Accumulate line into v and double point n times. */ + sp_1024_accumulate_line_dbl_n_avx2_16(vx, vy, c, q, + sp_1024_order_op[1], t); + + for (i = 2; i < 290; i += 2) { + j = sp_1024_order_op[i]; + if (j > 0) { + j /= 2; + /* Accumulate line into v and add P into C. */ + sp_1024_proj_mul_avx2_16(vx, vy, pre_vx[j], pre_vy[j], t); + sp_1024_accumulate_line_add_n_avx2_16(vx, vy, &pre_p[j], q, c, + t, 0); + } + else { + j = -j / 2; + /* Accumulate line into v and add P into C. */ + sp_1024_proj_mul_avx2_16(vx, vy, pre_vx[j], pre_nvy[j], t); + sp_1024_accumulate_line_add_n_avx2_16(vx, vy, &pre_p[j], q, c, + t, 1); + } + + /* Accumulate line into v and double point n times. */ + sp_1024_accumulate_line_dbl_n_avx2_16(vx, vy, c, q, + sp_1024_order_op[i + 1], t); + } + + /* Final exponentiation */ + sp_1024_proj_sqr_avx2_16(vx, vy, t); + sp_1024_proj_sqr_avx2_16(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_avx2_16(vx, vx, t); + sp_1024_mont_mul_avx2_16(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 16, 0, sizeof(sp_digit) * 16); + sp_1024_mont_reduce_avx2_16(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_16(c, 1, NULL); + sp_1024_point_free_16(q, 1, NULL); + sp_1024_point_free_16(p, 1, NULL); + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +#endif /* HAVE_INTEL_AVX2 */ +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * @param [in] key SAKKE key. + * @param [in] p First point on E(F_p)[q]. + * @param [in] q Second point on E(F_p)[q]. + * @param [in] r Result of calculation. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +int sp_Pairing_1024(const ecc_point* pm, const ecc_point* qm, mp_int* res) +{ + int err; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { + err = sp_Pairing_avx2_1024(pm, qm, res); + } + else +#endif + { + err = sp_Pairing_x64_1024(pm, qm, res); + } + + return err; +} + +#ifdef WOLFSSL_SP_SMALL +/* + * Generate table for pairing. + * + * Small implementation does not use a table - returns 0 length. + * + * pm [in] Point to generate table for. + * table [in] Generated table. + * len [in,out] On in, the size of the buffer. + * On out, length of table generated. + * @return 0 on success. + * LENGTH_ONLY_E when table is NULL and only length returned. + * BUFFER_E when len is too small. + */ +static int sp_Pairing_gen_precomp_x64_1024(const ecc_point* pm, byte* table, + word32* len) +{ + int err = 0; + + if (table == NULL) { + *len = 0; + err = LENGTH_ONLY_E; + } + else if (*len != 0) { + err = BUFFER_E; + } + + (void)*pm; + + return err; +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Small implementation does not use a table - use the normal implementation. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @param [in] table Precomputed table of values. + * @param [in] len Length of precomputed table of values in bytes. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +static int sp_Pairing_precomp_x64_1024(const ecc_point* pm, const ecc_point* qm, + mp_int* res, const byte* table, word32 len) +{ + (void)table; + (void)len; + return sp_Pairing_x64_1024(pm, qm, res); +} + +#else +/* + * Calc l and c for the point when doubling p. + * + * l = 3 * (p.x^2 - 1) / (2 * p.y) + * c = l * p.x - p.y + * + * @param [out] lr Gradient result - table entry. + * @param [out] cr Constant result - table entry. + * @param [in] px X-ordinate of point to double. + * @param [in] py Y-ordinate of point to double. + * @param [in] t SP temporaries (3 used). + */ +static void sp_1024_accum_dbl_calc_lc_16(sp_digit* lr, sp_digit* cr, + const sp_digit* px, const sp_digit* py, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 2 * 16; + sp_digit* t2 = t + 2 * 2 * 16; + sp_digit* l = t + 4 * 2 * 16; + + + /* l = 1 / 2 * p.y */ + sp_1024_mont_dbl_16(l, py, p1024_mod); + sp_1024_mont_inv_16(l, l, t); + + /* t1 = p.x^2 */ + sp_1024_mont_sqr_16(t1, px, p1024_mod, p1024_mp_mod); + /* t1 = p.x - 1 */ + sp_1024_mont_sub_16(t1, t1, p1024_norm_mod, p1024_mod); + /* t1 = 3 * (p.x^2 - 1) */ + sp_1024_mont_dbl_16(t2, t1, p1024_mod); + sp_1024_mont_add_16(t1, t1, t2, p1024_mod); + /* t1 = 3 * (p.x^2 - 1) / (2 * p.y) */ + sp_1024_mont_mul_16(l, l, t1, p1024_mod, p1024_mp_mod); + /* t2 = l * p.x */ + sp_1024_mont_mul_16(t2, l, px, p1024_mod, p1024_mp_mod); + /* c = t2 = l * p.x - p.y */ + sp_1024_mont_sub_16(t2, t2, py, p1024_mod); + + XMEMCPY(lr, l, sizeof(sp_digit) * 16); + XMEMCPY(cr, t2, sizeof(sp_digit) * 16); +} + +/* + * Calc l and c when adding p and c. + * + * l = (c.y - p.y) / (c.x - p.x) + * c = (p.x * c.y - cx * p.y) / (cx - p.x) + * + * @param [out] lr Gradient result - table entry. + * @param [out] cr Constant result - table entry. + * @param [in] px X-ordinate of point to add. + * @param [in] py Y-ordinate of point to add. + * @param [in] cx X-ordinate of current point. + * @param [in] cy Y-ordinate of current point. + * @param [in] t SP temporaries (3 used). + */ +static void sp_1024_accum_add_calc_lc_16(sp_digit* lr, sp_digit* cr, + const sp_digit* px, const sp_digit* py, const sp_digit* cx, + const sp_digit* cy, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 2 * 16; + sp_digit* c = t + 2 * 2 * 16; + sp_digit* l = t + 4 * 2 * 16; + + + /* l = 1 / (c.x - p.x) */ + sp_1024_mont_sub_16(l, cx, px, p1024_mod); + sp_1024_mont_inv_16(l, l, t); + + /* c = p.x * c.y */ + sp_1024_mont_mul_16(c, px, cy, p1024_mod, p1024_mp_mod); + /* t1 = c.x * p.y */ + sp_1024_mont_mul_16(t1, cx, py, p1024_mod, p1024_mp_mod); + /* c = (p.x * c.y) - (c.x * p.y) */ + sp_1024_mont_sub_16(c, c, t1, p1024_mod); + /* c = ((p.x * c.y) - (c.x * p.y)) / (c.x - p.x) */ + sp_1024_mont_mul_16(c, c, l, p1024_mod, p1024_mp_mod); + /* t1 = c.y - p.y */ + sp_1024_mont_sub_16(t1, cy, py, p1024_mod); + /* l = (c.y - p.y) / (c.x - p.x) */ + sp_1024_mont_mul_16(l, t1, l, p1024_mod, p1024_mp_mod); + + XMEMCPY(lr, l, sizeof(sp_digit) * 16); + XMEMCPY(cr, c, sizeof(sp_digit) * 16); +} + +/* + * Calculate vx and vy given gradient l and constant c and point q. + * + * l is a the gradient and is multiplied by q->x. + * c is a the constant that is added to the multiplicative result. + * q->y is the y-ordinate in result to multiply. + * + * if dbl + * v* = v*^2 + * r.x = l * q.x + c + * r.y = q->y + * v* = v* * r* + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in] l Gradient to multiply with. + * @param [in] c Constant to add with. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] t SP temporaries (3 used). + * @param [in] dbl Indicates whether this is for doubling. Otherwise + * adding. + */ +static void sp_1024_accumulate_line_lc_16(sp_digit* vx, sp_digit* vy, + const sp_digit* l, const sp_digit* c, const sp_point_1024* q, + sp_digit* t, int dbl) +{ + sp_digit* rx = t + 4 * 2 * 16; + + /* v = v^2 */ + if (dbl) { + sp_1024_proj_sqr_16(vx, vy, t); + } + /* rx = l * q.x + c */ + sp_1024_mont_mul_16(rx, l, q->x, p1024_mod, p1024_mp_mod); + sp_1024_mont_add_16(rx, rx, c, p1024_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_16(vx, vy, rx, q->y, t); +} + +/* Operations to perform based on order - 1. + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * Pairs: #dbls, add/subtract window value + */ +static const signed char sp_1024_order_op_pre[] = { + 5, 6, -13, 9, -21, 6, -5, 8, 31, 6, 3, 6, -27, 6, 25, 9, + -1, 6, -11, 6, -13, 6, -7, 6, -15, 6, -29, 7, 25, 6, -9, 6, + -19, 7, 3, 6, 11, 9, -23, 6, 1, 6, 27, 6, 1, 7, -25, 8, + 13, 7, -13, 7, -23, 10, 19, 7, 7, 7, -3, 7, 27, 6, -7, 7, + -21, 7, 11, 7, 31, 8, 1, 7, -23, 6, -17, 6, -3, 10, 11, 6, + -21, 7, -27, 11, -29, 6, -1, 10, 15, 8, 27, 7, 17, 6, 17, 7, + -13, 8, 13, 6, 21, 7, -29, 6, 19, 7, -25, 6, 11, 9, 29, 7, + -7, 8, 27, 7, 29, 10, -1, 8, -7, 8, 17, 6, 17, 7, -27, 7, + -21, 6, -9, 6, -27, 12, -23, 6, 19, 6, 13, 6, -11, 7, 27, 6, + 17, 6, -7, 6, -25, 7, -29, 6, 9, 7, 7, 6, 13, 6, -25, 6, + -19, 6, 13, 6, -11, 6, 5, 8, 19, 6, -21, 8, 23, 7, 27, 6, + -13, 6, -19, 11, 29, 7, -15, 6, -9, 7, -21, 10, -3, 7, 21, 10, + 25, 6, -15, 6, -23, 6, 21, 6, 1, 6, 21, 7, -3, 6, -3, 7, + -7, 6, -23, 7, 7, 8, 15, 9, 5, 6, -11, 6, 21, 11, -27, 7, + 27, 6, -11, 6, 31, 6, -21, 6, 19, 6, -7, 8, -7, 13, -3, 6, + -7, 7, -3, 6, 1, 6, 7, 8, 19, 8, 11, 9, -9, 7, -31, 12, + 25, 6, -17, 9, -15, 7, 5, 6, 25, 7, -5, 7, -25, 6, 17, 8, + -19, 6, -13, 6, 27, 8, 1, 7, -5, 7, -1, 6, 21, 6, 3, 10, + -3, 1, +}; + +/* + * Generate table for pairing. + * + * Calculate the graident (l) and constant (c) at each step of the way. + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * + * pm [in] Point to generate table for. + * table [in] Generated table. + * len [in,out] On in, the size of the buffer. + * On out, length of table generated. + * @return 0 on success. + * LENGTH_ONLY_E when table is NULL and only length returned. + * BUFFER_E when len is too small. + * MEMORY_E when dynamic memory allocation fauls. + */ +static int sp_Pairing_gen_precomp_x64_1024(const ecc_point* pm, byte* table, + word32* len) +{ + int err = 0; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_point_1024* pre_p; +#else + sp_digit t[6 * 2 * 16]; + sp_point_1024 pre_p[16]; + sp_point_1024 pd; + sp_point_1024 cd; + sp_point_1024 negd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* c = NULL; + sp_point_1024* neg = NULL; + int i; + int j; + int k; + sp_table_entry_1024* precomp = (sp_table_entry_1024*)table; + + if (table == NULL) { + *len = sizeof(sp_table_entry_1024) * 1167; + err = LENGTH_ONLY_E; + } + + if ((err == MP_OKAY) && + (*len < (int)(sizeof(sp_table_entry_1024) * 1167))) { + err = BUFFER_E; + } + + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, pd, p); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, cd, c); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, negd, neg); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6 * 16 * 2 + 16 * sizeof(sp_point_1024), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + pre_p = (sp_point_1024*)(td + 6 * 16 * 2); +#endif + + sp_1024_point_from_ecc_point_16(p, pm); + + err = sp_1024_mod_mul_norm_16(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(p->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + neg->infinity = 0; + c->infinity = 0; + + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMCPY(&pre_p[0], p, sizeof(sp_point_1024)); + /* [2]P for adding */ + sp_1024_proj_point_dbl_16(c, p, t); + + /* 1, 3, ... */ + for (i = 1; i < 16; i++) { + sp_1024_proj_point_add_16(&pre_p[i], &pre_p[i-1], c, t); + sp_1024_mont_map_16(&pre_p[i], t); + } + + k = 0; + j = sp_1024_order_op_pre[0] / 2; + XMEMCPY(c, &pre_p[j], sizeof(sp_point_1024)); + + for (j = 0; j < sp_1024_order_op_pre[1]; j++) { + sp_1024_accum_dbl_calc_lc_16(precomp[k].x, precomp[k].y, c->x, c->y, t); + k++; + sp_1024_proj_point_dbl_16(c, c, t); + sp_1024_mont_map_16(c, t); + } + + for (i = 2; i < 290; i += 2) { + j = sp_1024_order_op_pre[i]; + if (j > 0) { + sp_1024_accum_add_calc_lc_16(precomp[k].x, precomp[k].y, + pre_p[j/2].x, pre_p[j/2].y, c->x, c->y, t); + k++; + sp_1024_proj_point_add_16(c, c, &pre_p[j/2], t); + sp_1024_mont_map_16(c, t); + } + else { + XMEMCPY(neg->x, pre_p[-j / 2].x, sizeof(pre_p->x)); + sp_1024_mont_sub_16(neg->y, p1024_mod, pre_p[-j / 2].y, + p1024_mod); + XMEMCPY(neg->z, pre_p[-j / 2].z, sizeof(pre_p->z)); + + sp_1024_accum_add_calc_lc_16(precomp[k].x, precomp[k].y, + neg->x, neg->y, c->x, c->y, t); + k++; + sp_1024_proj_point_add_16(c, c, neg, t); + sp_1024_mont_map_16(c, t); + } + + for (j = 0; j < sp_1024_order_op_pre[i + 1]; j++) { + sp_1024_accum_dbl_calc_lc_16(precomp[k].x, precomp[k].y, c->x, c->y, t); + k++; + sp_1024_proj_point_dbl_16(c, c, t); + sp_1024_mont_map_16(c, t); + } + } + + *len = sizeof(sp_table_entry_1024) * 1167; + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_16(neg, 1, NULL); + sp_1024_point_free_16(c, 1, NULL); + sp_1024_point_free_16(p, 1, NULL); + return err; +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * Pre-generate values in window (1, 3, ...) - only V. + * Table contains all gradient l and a constant for each point on the path. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @param [in] table Precomputed table of values. + * @param [in] len Length of precomputed table of values in bytes. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +static int sp_Pairing_precomp_x64_1024(const ecc_point* pm, const ecc_point* qm, + mp_int* res, const byte* table, word32 len) +{ + int err = 0; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit (*pre_vx)[32]; + sp_digit (*pre_vy)[32]; + sp_digit (*pre_nvy)[32]; +#else + sp_digit t[6 * 2 * 16]; + sp_digit vx[2 * 16]; + sp_digit vy[2 * 16]; + sp_digit pre_vx[16][32]; + sp_digit pre_vy[16][32]; + sp_digit pre_nvy[16][32]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + int j; + int k; + const sp_table_entry_1024* precomp = (const sp_table_entry_1024*)table; + + if (len < (int)(sizeof(sp_table_entry_1024) * 1167)) { + err = BUFFER_E; + } + + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, pd, p); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 56 * 16 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 16 * 2; + vy = td + 7 * 16 * 2; + pre_vx = (sp_digit(*)[32])(td + 8 * 16 * 2); + pre_vy = (sp_digit(*)[32])(td + 24 * 16 * 2); + pre_nvy = (sp_digit(*)[32])(td + 40 * 16 * 2); +#endif + r = vy; + + sp_1024_point_from_ecc_point_16(p, pm); + sp_1024_point_from_ecc_point_16(q, qm); + + err = sp_1024_mod_mul_norm_16(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_16(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMSET(pre_vx[0], 0, sizeof(sp_digit) * 2 * 16); + pre_vx[0][0] = 1; + XMEMSET(pre_vy[0], 0, sizeof(sp_digit) * 2 * 16); + sp_1024_mont_sub_16(pre_nvy[0], p1024_mod, pre_vy[0], p1024_mod); + + /* [2]P for adding */ + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 16); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 16); + sp_1024_accumulate_line_dbl_16(vx, vy, c, q, t); + + /* 3, 5, ... */ + for (i = 1; i < 16; i++) { + XMEMCPY(pre_vx[i], pre_vx[i-1], sizeof(sp_digit) * 2 * 16); + XMEMCPY(pre_vy[i], pre_vy[i-1], sizeof(sp_digit) * 2 * 16); + sp_1024_proj_mul_16(pre_vx[i], pre_vy[i], vx, vy, t); + sp_1024_accumulate_line_add_n_16(pre_vx[i], pre_vy[i], c, + q, p, t, 0); + sp_1024_mont_sub_16(pre_nvy[i], p1024_mod, pre_vy[i], + p1024_mod); + } + + XMEMCPY(c->z, p1024_norm_mod, sizeof(sp_digit) * 16); + c->infinity = 0; + j = sp_1024_order_op_pre[0] / 2; + XMEMCPY(vx, pre_vx[j], sizeof(sp_digit) * 2 * 16); + XMEMCPY(vy, pre_vy[j], sizeof(sp_digit) * 2 * 16); + + k = 0; + for (j = 0; j < sp_1024_order_op_pre[1]; j++) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_lc_16(vx, vy, precomp[k].x, + precomp[k].y, q, t, 1); + k++; + } + + for (i = 2; i < 290; i += 2) { + sp_1024_accumulate_line_lc_16(vx, vy, precomp[k].x, + precomp[k].y, q, t, 0); + k++; + + j = sp_1024_order_op_pre[i]; + if (j > 0) { + j /= 2; + /* Accumulate line into v. */ + sp_1024_proj_mul_16(vx, vy, pre_vx[j], pre_vy[j], t); + } + else { + j = -j / 2; + /* Accumulate line into v. */ + sp_1024_proj_mul_16(vx, vy, pre_vx[j], pre_nvy[j], t); + } + + for (j = 0; j < sp_1024_order_op_pre[i + 1]; j++) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_lc_16(vx, vy, precomp[k].x, + precomp[k].y, q, t, 1); + k++; + } + } + + /* Final exponentiation */ + sp_1024_proj_sqr_16(vx, vy, t); + sp_1024_proj_sqr_16(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_16(vx, vx, t); + sp_1024_mont_mul_16(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 16, 0, sizeof(sp_digit) * 16); + sp_1024_mont_reduce_16(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_16(c, 1, NULL); + sp_1024_point_free_16(q, 1, NULL); + sp_1024_point_free_16(p, 1, NULL); + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +#ifdef HAVE_INTEL_AVX2 +#ifdef WOLFSSL_SP_SMALL +/* + * Generate table for pairing. + * + * Small implementation does not use a table - returns 0 length. + * + * pm [in] Point to generate table for. + * table [in] Generated table. + * len [in,out] On in, the size of the buffer. + * On out, length of table generated. + * @return 0 on success. + * LENGTH_ONLY_E when table is NULL and only length returned. + * BUFFER_E when len is too small. + */ +static int sp_Pairing_gen_precomp_avx2_1024(const ecc_point* pm, byte* table, + word32* len) +{ + int err = 0; + + if (table == NULL) { + *len = 0; + err = LENGTH_ONLY_E; + } + else if (*len != 0) { + err = BUFFER_E; + } + + (void)*pm; + + return err; +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Small implementation does not use a table - use the normal implementation. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @param [in] table Precomputed table of values. + * @param [in] len Length of precomputed table of values in bytes. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +static int sp_Pairing_precomp_avx2_1024(const ecc_point* pm, const ecc_point* qm, + mp_int* res, const byte* table, word32 len) +{ + (void)table; + (void)len; + return sp_Pairing_avx2_1024(pm, qm, res); +} + +#else +/* + * Calc l and c for the point when doubling p. + * + * l = 3 * (p.x^2 - 1) / (2 * p.y) + * c = l * p.x - p.y + * + * @param [out] lr Gradient result - table entry. + * @param [out] cr Constant result - table entry. + * @param [in] px X-ordinate of point to double. + * @param [in] py Y-ordinate of point to double. + * @param [in] t SP temporaries (3 used). + */ +static void sp_1024_accum_dbl_calc_lc_avx2_16(sp_digit* lr, sp_digit* cr, + const sp_digit* px, const sp_digit* py, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 2 * 16; + sp_digit* t2 = t + 2 * 2 * 16; + sp_digit* l = t + 4 * 2 * 16; + + + /* l = 1 / 2 * p.y */ + sp_1024_mont_dbl_avx2_16(l, py, p1024_mod); + sp_1024_mont_inv_avx2_16(l, l, t); + + /* t1 = p.x^2 */ + sp_1024_mont_sqr_avx2_16(t1, px, p1024_mod, p1024_mp_mod); + /* t1 = p.x - 1 */ + sp_1024_mont_sub_avx2_16(t1, t1, p1024_norm_mod, p1024_mod); + /* t1 = 3 * (p.x^2 - 1) */ + sp_1024_mont_dbl_avx2_16(t2, t1, p1024_mod); + sp_1024_mont_add_avx2_16(t1, t1, t2, p1024_mod); + /* t1 = 3 * (p.x^2 - 1) / (2 * p.y) */ + sp_1024_mont_mul_avx2_16(l, l, t1, p1024_mod, p1024_mp_mod); + /* t2 = l * p.x */ + sp_1024_mont_mul_avx2_16(t2, l, px, p1024_mod, p1024_mp_mod); + /* c = t2 = l * p.x - p.y */ + sp_1024_mont_sub_avx2_16(t2, t2, py, p1024_mod); + + XMEMCPY(lr, l, sizeof(sp_digit) * 16); + XMEMCPY(cr, t2, sizeof(sp_digit) * 16); +} + +/* + * Calc l and c when adding p and c. + * + * l = (c.y - p.y) / (c.x - p.x) + * c = (p.x * c.y - cx * p.y) / (cx - p.x) + * + * @param [out] lr Gradient result - table entry. + * @param [out] cr Constant result - table entry. + * @param [in] px X-ordinate of point to add. + * @param [in] py Y-ordinate of point to add. + * @param [in] cx X-ordinate of current point. + * @param [in] cy Y-ordinate of current point. + * @param [in] t SP temporaries (3 used). + */ +static void sp_1024_accum_add_calc_lc_avx2_16(sp_digit* lr, sp_digit* cr, + const sp_digit* px, const sp_digit* py, const sp_digit* cx, + const sp_digit* cy, sp_digit* t) +{ + sp_digit* t1 = t + 0 * 2 * 16; + sp_digit* c = t + 2 * 2 * 16; + sp_digit* l = t + 4 * 2 * 16; + + + /* l = 1 / (c.x - p.x) */ + sp_1024_mont_sub_avx2_16(l, cx, px, p1024_mod); + sp_1024_mont_inv_avx2_16(l, l, t); + + /* c = p.x * c.y */ + sp_1024_mont_mul_avx2_16(c, px, cy, p1024_mod, p1024_mp_mod); + /* t1 = c.x * p.y */ + sp_1024_mont_mul_avx2_16(t1, cx, py, p1024_mod, p1024_mp_mod); + /* c = (p.x * c.y) - (c.x * p.y) */ + sp_1024_mont_sub_avx2_16(c, c, t1, p1024_mod); + /* c = ((p.x * c.y) - (c.x * p.y)) / (c.x - p.x) */ + sp_1024_mont_mul_avx2_16(c, c, l, p1024_mod, p1024_mp_mod); + /* t1 = c.y - p.y */ + sp_1024_mont_sub_avx2_16(t1, cy, py, p1024_mod); + /* l = (c.y - p.y) / (c.x - p.x) */ + sp_1024_mont_mul_avx2_16(l, t1, l, p1024_mod, p1024_mp_mod); + + XMEMCPY(lr, l, sizeof(sp_digit) * 16); + XMEMCPY(cr, c, sizeof(sp_digit) * 16); +} + +/* + * Calculate vx and vy given gradient l and constant c and point q. + * + * l is a the gradient and is multiplied by q->x. + * c is a the constant that is added to the multiplicative result. + * q->y is the y-ordinate in result to multiply. + * + * if dbl + * v* = v*^2 + * r.x = l * q.x + c + * r.y = q->y + * v* = v* * r* + * + * @param [in,out] vx X-ordinate of projective value in F*. + * @param [in,out] vy Y-ordinate of projective value in F*. + * @param [in] l Gradient to multiply with. + * @param [in] c Constant to add with. + * @param [in] q ECC point - second point on E(F_P^2). + * @param [in] t SP temporaries (3 used). + * @param [in] dbl Indicates whether this is for doubling. Otherwise + * adding. + */ +static void sp_1024_accumulate_line_lc_avx2_16(sp_digit* vx, sp_digit* vy, + const sp_digit* l, const sp_digit* c, const sp_point_1024* q, + sp_digit* t, int dbl) +{ + sp_digit* rx = t + 4 * 2 * 16; + + /* v = v^2 */ + if (dbl) { + sp_1024_proj_sqr_avx2_16(vx, vy, t); + } + /* rx = l * q.x + c */ + sp_1024_mont_mul_avx2_16(rx, l, q->x, p1024_mod, p1024_mp_mod); + sp_1024_mont_add_avx2_16(rx, rx, c, p1024_mod); + /* v = v^2 * r */ + sp_1024_proj_mul_avx2_16(vx, vy, rx, q->y, t); +} + + +/* + * Generate table for pairing. + * + * Calculate the graident (l) and constant (c) at each step of the way. + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * + * pm [in] Point to generate table for. + * table [in] Generated table. + * len [in,out] On in, the size of the buffer. + * On out, length of table generated. + * @return 0 on success. + * LENGTH_ONLY_E when table is NULL and only length returned. + * BUFFER_E when len is too small. + * MEMORY_E when dynamic memory allocation fauls. + */ +static int sp_Pairing_gen_precomp_avx2_1024(const ecc_point* pm, byte* table, + word32* len) +{ + int err = 0; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_point_1024* pre_p; +#else + sp_digit t[6 * 2 * 16]; + sp_point_1024 pre_p[16]; + sp_point_1024 pd; + sp_point_1024 cd; + sp_point_1024 negd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* c = NULL; + sp_point_1024* neg = NULL; + int i; + int j; + int k; + sp_table_entry_1024* precomp = (sp_table_entry_1024*)table; + + if (table == NULL) { + *len = sizeof(sp_table_entry_1024) * 1167; + err = LENGTH_ONLY_E; + } + + if ((err == MP_OKAY) && + (*len < (int)(sizeof(sp_table_entry_1024) * 1167))) { + err = BUFFER_E; + } + + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, pd, p); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, cd, c); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, negd, neg); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6 * 16 * 2 + 16 * sizeof(sp_point_1024), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + pre_p = (sp_point_1024*)(td + 6 * 16 * 2); +#endif + + sp_1024_point_from_ecc_point_16(p, pm); + + err = sp_1024_mod_mul_norm_avx2_16(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_avx2_16(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + XMEMCPY(p->z, p1024_norm_mod, sizeof(p1024_norm_mod)); + neg->infinity = 0; + c->infinity = 0; + + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMCPY(&pre_p[0], p, sizeof(sp_point_1024)); + /* [2]P for adding */ + sp_1024_proj_point_dbl_avx2_16(c, p, t); + + /* 1, 3, ... */ + for (i = 1; i < 16; i++) { + sp_1024_proj_point_add_avx2_16(&pre_p[i], &pre_p[i-1], c, t); + sp_1024_mont_map_avx2_16(&pre_p[i], t); + } + + k = 0; + j = sp_1024_order_op_pre[0] / 2; + XMEMCPY(c, &pre_p[j], sizeof(sp_point_1024)); + + for (j = 0; j < sp_1024_order_op_pre[1]; j++) { + sp_1024_accum_dbl_calc_lc_avx2_16(precomp[k].x, precomp[k].y, c->x, c->y, t); + k++; + sp_1024_proj_point_dbl_avx2_16(c, c, t); + sp_1024_mont_map_avx2_16(c, t); + } + + for (i = 2; i < 290; i += 2) { + j = sp_1024_order_op_pre[i]; + if (j > 0) { + sp_1024_accum_add_calc_lc_avx2_16(precomp[k].x, precomp[k].y, + pre_p[j/2].x, pre_p[j/2].y, c->x, c->y, t); + k++; + sp_1024_proj_point_add_avx2_16(c, c, &pre_p[j/2], t); + sp_1024_mont_map_avx2_16(c, t); + } + else { + XMEMCPY(neg->x, pre_p[-j / 2].x, sizeof(pre_p->x)); + sp_1024_mont_sub_avx2_16(neg->y, p1024_mod, pre_p[-j / 2].y, + p1024_mod); + XMEMCPY(neg->z, pre_p[-j / 2].z, sizeof(pre_p->z)); + + sp_1024_accum_add_calc_lc_avx2_16(precomp[k].x, precomp[k].y, + neg->x, neg->y, c->x, c->y, t); + k++; + sp_1024_proj_point_add_avx2_16(c, c, neg, t); + sp_1024_mont_map_avx2_16(c, t); + } + + for (j = 0; j < sp_1024_order_op_pre[i + 1]; j++) { + sp_1024_accum_dbl_calc_lc_avx2_16(precomp[k].x, precomp[k].y, c->x, c->y, t); + k++; + sp_1024_proj_point_dbl_avx2_16(c, c, t); + sp_1024_mont_map_avx2_16(c, t); + } + } + + *len = sizeof(sp_table_entry_1024) * 1167; + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_16(neg, 1, NULL); + sp_1024_point_free_16(c, 1, NULL); + sp_1024_point_free_16(p, 1, NULL); + return err; +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * Sliding window. Start at bottom and stop when bottom bit is one. + * Subtract if top bit in window is one. + * Width of 6 bits. + * Pre-generate values in window (1, 3, ...) - only V. + * Table contains all gradient l and a constant for each point on the path. + * + * @param [in] pm First point on E(F_p)[q]. + * @param [in] qm Second point on E(F_p)[q]. + * @param [in] res Result of calculation. + * @param [in] table Precomputed table of values. + * @param [in] len Length of precomputed table of values in bytes. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + */ +static int sp_Pairing_precomp_avx2_1024(const ecc_point* pm, const ecc_point* qm, + mp_int* res, const byte* table, word32 len) +{ + int err = 0; +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* td = NULL; + sp_digit* t; + sp_digit* vx; + sp_digit* vy; + sp_digit (*pre_vx)[32]; + sp_digit (*pre_vy)[32]; + sp_digit (*pre_nvy)[32]; +#else + sp_digit t[6 * 2 * 16]; + sp_digit vx[2 * 16]; + sp_digit vy[2 * 16]; + sp_digit pre_vx[16][32]; + sp_digit pre_vy[16][32]; + sp_digit pre_nvy[16][32]; + sp_point_1024 pd; + sp_point_1024 qd; + sp_point_1024 cd; +#endif + sp_point_1024* p = NULL; + sp_point_1024* q = NULL; + sp_point_1024* c = NULL; + sp_digit* r = NULL; + int i; + int j; + int k; + const sp_table_entry_1024* precomp = (const sp_table_entry_1024*)table; + + if (len < (int)(sizeof(sp_table_entry_1024) * 1167)) { + err = BUFFER_E; + } + + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, pd, p); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, qd, q); + } + if (err == MP_OKAY) { + err = sp_1024_point_new_16(NULL, cd, c); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY) { + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 56 * 16 * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (td == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t = td; + vx = td + 6 * 16 * 2; + vy = td + 7 * 16 * 2; + pre_vx = (sp_digit(*)[32])(td + 8 * 16 * 2); + pre_vy = (sp_digit(*)[32])(td + 24 * 16 * 2); + pre_nvy = (sp_digit(*)[32])(td + 40 * 16 * 2); +#endif + r = vy; + + sp_1024_point_from_ecc_point_16(p, pm); + sp_1024_point_from_ecc_point_16(q, qm); + + err = sp_1024_mod_mul_norm_avx2_16(p->x, p->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_avx2_16(p->y, p->y, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_avx2_16(p->z, p->z, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_avx2_16(q->x, q->x, p1024_mod); + } + if (err == MP_OKAY) { + err = sp_1024_mod_mul_norm_avx2_16(q->y, q->y, p1024_mod); + } + if (err == MP_OKAY) { + /* Generate pre-computation table: 1, 3, ... , 31 */ + XMEMSET(pre_vx[0], 0, sizeof(sp_digit) * 2 * 16); + pre_vx[0][0] = 1; + XMEMSET(pre_vy[0], 0, sizeof(sp_digit) * 2 * 16); + sp_1024_mont_sub_avx2_16(pre_nvy[0], p1024_mod, pre_vy[0], p1024_mod); + + /* [2]P for adding */ + XMEMCPY(c, p, sizeof(sp_point_1024)); + XMEMSET(vx, 0, sizeof(sp_digit) * 2 * 16); + vx[0] = 1; + XMEMSET(vy, 0, sizeof(sp_digit) * 2 * 16); + sp_1024_accumulate_line_dbl_avx2_16(vx, vy, c, q, t); + + /* 3, 5, ... */ + for (i = 1; i < 16; i++) { + XMEMCPY(pre_vx[i], pre_vx[i-1], sizeof(sp_digit) * 2 * 16); + XMEMCPY(pre_vy[i], pre_vy[i-1], sizeof(sp_digit) * 2 * 16); + sp_1024_proj_mul_avx2_16(pre_vx[i], pre_vy[i], vx, vy, t); + sp_1024_accumulate_line_add_n_avx2_16(pre_vx[i], pre_vy[i], c, + q, p, t, 0); + sp_1024_mont_sub_avx2_16(pre_nvy[i], p1024_mod, pre_vy[i], + p1024_mod); + } + + XMEMCPY(c->z, p1024_norm_mod, sizeof(sp_digit) * 16); + c->infinity = 0; + j = sp_1024_order_op_pre[0] / 2; + XMEMCPY(vx, pre_vx[j], sizeof(sp_digit) * 2 * 16); + XMEMCPY(vy, pre_vy[j], sizeof(sp_digit) * 2 * 16); + + k = 0; + for (j = 0; j < sp_1024_order_op_pre[1]; j++) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_lc_avx2_16(vx, vy, precomp[k].x, + precomp[k].y, q, t, 1); + k++; + } + + for (i = 2; i < 290; i += 2) { + sp_1024_accumulate_line_lc_avx2_16(vx, vy, precomp[k].x, + precomp[k].y, q, t, 0); + k++; + + j = sp_1024_order_op_pre[i]; + if (j > 0) { + j /= 2; + /* Accumulate line into v. */ + sp_1024_proj_mul_avx2_16(vx, vy, pre_vx[j], pre_vy[j], t); + } + else { + j = -j / 2; + /* Accumulate line into v. */ + sp_1024_proj_mul_avx2_16(vx, vy, pre_vx[j], pre_nvy[j], t); + } + + for (j = 0; j < sp_1024_order_op_pre[i + 1]; j++) { + /* Accumulate line into v and double point. */ + sp_1024_accumulate_line_lc_avx2_16(vx, vy, precomp[k].x, + precomp[k].y, q, t, 1); + k++; + } + } + + /* Final exponentiation */ + sp_1024_proj_sqr_avx2_16(vx, vy, t); + sp_1024_proj_sqr_avx2_16(vx, vy, t); + + /* Convert from PF_p[q] to F_p */ + sp_1024_mont_inv_avx2_16(vx, vx, t); + sp_1024_mont_mul_avx2_16(r, vx, vy, p1024_mod, p1024_mp_mod); + XMEMSET(r + 16, 0, sizeof(sp_digit) * 16); + sp_1024_mont_reduce_avx2_16(r, p1024_mod, p1024_mp_mod); + + err = sp_1024_to_mp(r, res); + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (td != NULL) { + XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + sp_1024_point_free_16(c, 1, NULL); + sp_1024_point_free_16(q, 1, NULL); + sp_1024_point_free_16(p, 1, NULL); + return err; +} + +#endif /* WOLFSSL_SP_SMALL */ +#endif /* HAVE_INTEL_AVX2 */ +/* + * Generate table for pairing. + * + * pm [in] Point to generate table for. + * table [in] Generated table. + * len [in,out] On in, the size of the buffer. + * On out, length of table generated. + * @return 0 on success. + * Otherwise failure. + */ +int sp_Pairing_gen_precomp_1024(const ecc_point* pm, byte* table, word32* len) +{ + int err; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { + err = sp_Pairing_gen_precomp_avx2_1024(pm, table, len); + } + else +#endif + { + err = sp_Pairing_gen_precomp_x64_1024(pm, table, len); + } + + return err; +} + +/* + * Calculate r = pairing . + * + * That is, multiply base in PF_p[q] by the scalar s, such that s.P = Q. + * + * @param [in] key SAKKE key. + * @param [in] p First point on E(F_p)[q]. + * @param [in] q Second point on E(F_p)[q]. + * @param [in] r Result of calculation. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Other -ve value on internal failure. + */ +int sp_Pairing_precomp_1024(const ecc_point* pm, const ecc_point* qm, mp_int* res, + const byte* table, word32 len) +{ + int err; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { + err = sp_Pairing_precomp_avx2_1024(pm, qm, res, table, len); + } + else +#endif + { + err = sp_Pairing_precomp_x64_1024(pm, qm, res, table, len); + } + + return err; +} + +/* Returns 1 if the number of zero. + * Implementation is constant time. + * + * a Number to check. + * returns 1 if the number is zero and 0 otherwise. + */ +static int sp_1024_iszero_16(const sp_digit* a) +{ + return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6] | a[7] | + a[8] | a[9] | a[10] | a[11] | a[12] | a[13] | a[14] | a[15]) == 0; +} + +#ifdef HAVE_ECC_CHECK_KEY +extern void sp_1024_from_bin_bswap(sp_digit* r, int size, const byte* a, int n); +extern void sp_1024_from_bin_movbe(sp_digit* r, int size, const byte* a, int n); +/* Read big endian unsigned byte array into r. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a Byte array. + * n Number of bytes in array to read. + */ +static void sp_1024_from_bin(sp_digit* r, int size, const byte* a, int n) +{ +#ifndef NO_MOVBE_SUPPORT + word32 cpuid_flags = cpuid_get_flags(); + + if (IS_INTEL_MOVBE(cpuid_flags)) { + sp_1024_from_bin_movbe(r, size, a, n); + } + else +#endif + { + sp_1024_from_bin_bswap(r, size, a, n); + } +} + +/* Check that the x and y oridinates are a valid point on the curve. + * + * point EC point. + * heap Heap to use if dynamically allocating. + * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is + * not on the curve and MP_OKAY otherwise. + */ +static int sp_1024_ecc_is_point_16(const sp_point_1024* point, + void* heap) +{ +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + sp_digit* d = NULL; +#else + sp_digit t1d[2*16]; + sp_digit t2d[2*16]; +#endif + sp_digit* t1; + sp_digit* t2; + int64_t n; + int err = MP_OKAY; + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 4, heap, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + (void)heap; + + if (err == MP_OKAY) { +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + t1 = d + 0 * 16; + t2 = d + 2 * 16; +#else + t1 = t1d; + t2 = t2d; +#endif + + sp_1024_sqr_16(t1, point->y); + (void)sp_1024_mod_16(t1, t1, p1024_mod); + sp_1024_sqr_16(t2, point->x); + (void)sp_1024_mod_16(t2, t2, p1024_mod); + sp_1024_mul_16(t2, t2, point->x); + (void)sp_1024_mod_16(t2, t2, p1024_mod); + (void)sp_1024_sub_16(t2, p1024_mod, t2); + sp_1024_mont_add_16(t1, t1, t2, p1024_mod); + + sp_1024_mont_add_16(t1, t1, point->x, p1024_mod); + sp_1024_mont_add_16(t1, t1, point->x, p1024_mod); + sp_1024_mont_add_16(t1, t1, point->x, p1024_mod); + + n = sp_1024_cmp_16(t1, p1024_mod); + sp_1024_cond_sub_16(t1, t1, p1024_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_1024_norm_16(t1); + if (!sp_1024_iszero_16(t1)) { + err = MP_VAL; + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (d != NULL) { + XFREE(d, heap, DYNAMIC_TYPE_ECC); + } +#endif + + return err; +} + +/* Check that the x and y oridinates are a valid point on the curve. + * + * pX X ordinate of EC point. + * pY Y ordinate of EC point. + * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is + * not on the curve and MP_OKAY otherwise. + */ +int sp_ecc_is_point_1024(const mp_int* pX, const mp_int* pY) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_point_1024 pubd; +#endif + sp_point_1024* pub; + byte one[1] = { 1 }; + int err; + + err = sp_1024_point_new_16(NULL, pubd, pub); + if (err == MP_OKAY) { + sp_1024_from_mp(pub->x, 16, pX); + sp_1024_from_mp(pub->y, 16, pY); + sp_1024_from_bin(pub->z, 16, one, (int)sizeof(one)); + + err = sp_1024_ecc_is_point_16(pub, NULL); + } + + sp_1024_point_free_16(pub, 0, NULL); + + return err; +} + +/* Check that the private scalar generates the EC point (px, py), the point is + * on the curve and the point has the correct order. + * + * pX X ordinate of EC point. + * pY Y ordinate of EC point. + * privm Private scalar that generates EC point. + * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is + * not on the curve, ECC_INF_E if the point does not have the correct order, + * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and + * MP_OKAY otherwise. + */ +int sp_ecc_check_key_1024(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap) +{ +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + sp_digit privd[16]; + sp_point_1024 pubd; + sp_point_1024 pd; +#endif + sp_digit* priv = NULL; + sp_point_1024* pub; + sp_point_1024* p = NULL; + byte one[1] = { 1 }; + int err; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + + err = sp_1024_point_new_16(heap, pubd, pub); + if (err == MP_OKAY) { + err = sp_1024_point_new_16(heap, pd, p); + } +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (err == MP_OKAY && privm) { + priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16, heap, + DYNAMIC_TYPE_ECC); + if (priv == NULL) { + err = MEMORY_E; + } + } +#endif + + /* Quick check the lengs of public key ordinates and private key are in + * range. Proper check later. + */ + if ((err == MP_OKAY) && ((mp_count_bits(pX) > 1024) || + (mp_count_bits(pY) > 1024) || + ((privm != NULL) && (mp_count_bits(privm) > 1024)))) { + err = ECC_OUT_OF_RANGE_E; + } + + if (err == MP_OKAY) { +#if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC) + priv = privd; +#endif + + sp_1024_from_mp(pub->x, 16, pX); + sp_1024_from_mp(pub->y, 16, pY); + sp_1024_from_bin(pub->z, 16, one, (int)sizeof(one)); + if (privm) + sp_1024_from_mp(priv, 16, privm); + + /* Check point at infinitiy. */ + if ((sp_1024_iszero_16(pub->x) != 0) && + (sp_1024_iszero_16(pub->y) != 0)) { + err = ECC_INF_E; + } + } + + /* Check range of X and Y */ + if ((err == MP_OKAY) && + ((sp_1024_cmp_16(pub->x, p1024_mod) >= 0) || + (sp_1024_cmp_16(pub->y, p1024_mod) >= 0))) { + err = ECC_OUT_OF_RANGE_E; + } + + if (err == MP_OKAY) { + /* Check point is on curve */ + err = sp_1024_ecc_is_point_16(pub, heap); + } + + if (err == MP_OKAY) { + /* Point * order = infinity */ +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + err = sp_1024_ecc_mulmod_avx2_16(p, pub, p1024_order, 1, 1, heap); + else +#endif + err = sp_1024_ecc_mulmod_16(p, pub, p1024_order, 1, 1, heap); + } + /* Check result is infinity */ + if ((err == MP_OKAY) && ((sp_1024_iszero_16(p->x) == 0) || + (sp_1024_iszero_16(p->y) == 0))) { + err = ECC_INF_E; + } + + if (privm) { + if (err == MP_OKAY) { + /* Base * private = point */ +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + err = sp_1024_ecc_mulmod_base_avx2_16(p, priv, 1, 1, heap); + else +#endif + err = sp_1024_ecc_mulmod_base_16(p, priv, 1, 1, heap); + } + /* Check result is public key */ + if ((err == MP_OKAY) && + ((sp_1024_cmp_16(p->x, pub->x) != 0) || + (sp_1024_cmp_16(p->y, pub->y) != 0))) { + err = ECC_PRIV_KEY_E; + } + } + +#if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC) + if (priv != NULL) { + XFREE(priv, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_1024_point_free_16(p, 0, heap); + sp_1024_point_free_16(pub, 0, heap); + + return err; +} +#endif +#endif /* WOLFSSL_SP_1024 */ #endif /* WOLFSSL_HAVE_SP_ECC */ #endif /* WOLFSSL_SP_X86_64_ASM */ -#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH || WOLFSSL_HAVE_SP_ECC */ +#endif /* WOLFSSL_HAVE_SP_RSA | WOLFSSL_HAVE_SP_DH | WOLFSSL_HAVE_SP_ECC */ diff --git a/wolfcrypt/src/sp_x86_64_asm.S b/wolfcrypt/src/sp_x86_64_asm.S index feb766fbf..9de68792b 100644 --- a/wolfcrypt/src/sp_x86_64_asm.S +++ b/wolfcrypt/src/sp_x86_64_asm.S @@ -1,6 +1,6 @@ /* sp_x86_64_asm * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -122,6 +122,7 @@ L_2048_from_bin_bswap_zero_end: #ifndef __APPLE__ .size sp_2048_from_bin_bswap,.-sp_2048_from_bin_bswap #endif /* __APPLE__ */ +#ifndef NO_MOVBE_SUPPORT /* Read big endian unsigned byte array into r. * Uses the movbe instruction which is an optional instruction. * @@ -207,6 +208,7 @@ L_2048_from_bin_movbe_zero_end: #ifndef __APPLE__ .size sp_2048_from_bin_movbe,.-sp_2048_from_bin_movbe #endif /* __APPLE__ */ +#endif /* !NO_MOVBE_SUPPORT */ /* Write r as big endian to byte array. * Fixed length number of bytes written: 256 * Uses the bswap instruction. @@ -326,6 +328,7 @@ _sp_2048_to_bin_bswap: #ifndef __APPLE__ .size sp_2048_to_bin_bswap,.-sp_2048_to_bin_bswap #endif /* __APPLE__ */ +#ifndef NO_MOVBE_SUPPORT /* Write r as big endian to byte array. * Fixed length number of bytes written: 256 * Uses the movbe instruction which is optional. @@ -413,6 +416,7 @@ _sp_2048_to_bin_movbe: #ifndef __APPLE__ .size sp_2048_to_bin_movbe,.-sp_2048_to_bin_movbe #endif /* __APPLE__ */ +#endif /* NO_MOVBE_SUPPORT */ /* Multiply a and b into r. (r = a * b) * * r A single precision integer. @@ -3190,6 +3194,7 @@ _sp_2048_mul_avx2_16: cmovne %rdi, %rbx cmpq %rdi, %rbp cmove %rsp, %rbx + addq $0x80, %rdi xorq %r14, %r14 movq (%rsi), %rdx # A[0] * B[0] @@ -3258,7 +3263,7 @@ _sp_2048_mul_avx2_16: movq %r14, %r13 adcxq %r14, %r13 movq %r8, 120(%rbx) - movq %r9, 128(%rdi) + movq %r9, (%rdi) movq 8(%rsi), %rdx movq 8(%rbx), %r9 movq 16(%rbx), %r10 @@ -3335,7 +3340,7 @@ _sp_2048_mul_avx2_16: movq %r10, 96(%rbx) movq 112(%rbx), %r12 movq 120(%rbx), %r8 - movq 128(%rdi), %r9 + movq (%rdi), %r9 # A[1] * B[12] mulx 96(%rbp), %rax, %rcx adcxq %rax, %r11 @@ -3360,8 +3365,8 @@ _sp_2048_mul_avx2_16: movq %r14, %r13 adoxq %r14, %r13 adcxq %r14, %r13 - movq %r9, 128(%rdi) - movq %r10, 136(%rdi) + movq %r9, (%rdi) + movq %r10, 8(%rdi) movq 16(%rsi), %rdx movq 16(%rbx), %r10 movq 24(%rbx), %r11 @@ -3437,8 +3442,8 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r12 movq %r11, 104(%rbx) movq 120(%rbx), %r8 - movq 128(%rdi), %r9 - movq 136(%rdi), %r10 + movq (%rdi), %r9 + movq 8(%rdi), %r10 # A[2] * B[12] mulx 96(%rbp), %rax, %rcx adcxq %rax, %r12 @@ -3455,7 +3460,7 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r10 # A[2] * B[15] mulx 120(%rbp), %rax, %rcx - movq %r9, 128(%rdi) + movq %r9, (%rdi) movq %r14, %r11 adcxq %rax, %r10 adoxq %rcx, %r11 @@ -3463,8 +3468,8 @@ _sp_2048_mul_avx2_16: movq %r14, %r13 adoxq %r14, %r13 adcxq %r14, %r13 - movq %r10, 136(%rdi) - movq %r11, 144(%rdi) + movq %r10, 8(%rdi) + movq %r11, 16(%rdi) movq 24(%rsi), %rdx movq 24(%rbx), %r11 movq 32(%rbx), %r12 @@ -3539,9 +3544,9 @@ _sp_2048_mul_avx2_16: adcxq %rax, %r12 adoxq %rcx, %r8 movq %r12, 112(%rbx) - movq 128(%rdi), %r9 - movq 136(%rdi), %r10 - movq 144(%rdi), %r11 + movq (%rdi), %r9 + movq 8(%rdi), %r10 + movq 16(%rdi), %r11 # A[3] * B[12] mulx 96(%rbp), %rax, %rcx adcxq %rax, %r8 @@ -3553,12 +3558,12 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r10 # A[3] * B[14] mulx 112(%rbp), %rax, %rcx - movq %r9, 128(%rdi) + movq %r9, (%rdi) adcxq %rax, %r10 adoxq %rcx, %r11 # A[3] * B[15] mulx 120(%rbp), %rax, %rcx - movq %r10, 136(%rdi) + movq %r10, 8(%rdi) movq %r14, %r12 adcxq %rax, %r11 adoxq %rcx, %r12 @@ -3566,8 +3571,8 @@ _sp_2048_mul_avx2_16: movq %r14, %r13 adoxq %r14, %r13 adcxq %r14, %r13 - movq %r11, 144(%rdi) - movq %r12, 152(%rdi) + movq %r11, 16(%rdi) + movq %r12, 24(%rdi) movq 32(%rsi), %rdx movq 32(%rbx), %r12 movq 40(%rbx), %r8 @@ -3621,7 +3626,7 @@ _sp_2048_mul_avx2_16: movq 104(%rbx), %r11 movq 112(%rbx), %r12 movq 120(%rbx), %r8 - movq 128(%rdi), %r9 + movq (%rdi), %r9 # A[4] * B[8] mulx 64(%rbp), %rax, %rcx adcxq %rax, %r10 @@ -3642,26 +3647,26 @@ _sp_2048_mul_avx2_16: adcxq %rax, %r8 adoxq %rcx, %r9 movq %r8, 120(%rbx) - movq 136(%rdi), %r10 - movq 144(%rdi), %r11 - movq 152(%rdi), %r12 + movq 8(%rdi), %r10 + movq 16(%rdi), %r11 + movq 24(%rdi), %r12 # A[4] * B[12] mulx 96(%rbp), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 # A[4] * B[13] mulx 104(%rbp), %rax, %rcx - movq %r9, 128(%rdi) + movq %r9, (%rdi) adcxq %rax, %r10 adoxq %rcx, %r11 # A[4] * B[14] mulx 112(%rbp), %rax, %rcx - movq %r10, 136(%rdi) + movq %r10, 8(%rdi) adcxq %rax, %r11 adoxq %rcx, %r12 # A[4] * B[15] mulx 120(%rbp), %rax, %rcx - movq %r11, 144(%rdi) + movq %r11, 16(%rdi) movq %r14, %r8 adcxq %rax, %r12 adoxq %rcx, %r8 @@ -3669,8 +3674,8 @@ _sp_2048_mul_avx2_16: movq %r14, %r13 adoxq %r14, %r13 adcxq %r14, %r13 - movq %r12, 152(%rdi) - movq %r8, 160(%rdi) + movq %r12, 24(%rdi) + movq %r8, 32(%rdi) movq 40(%rsi), %rdx movq 40(%rbx), %r8 movq 48(%rbx), %r9 @@ -3723,8 +3728,8 @@ _sp_2048_mul_avx2_16: movq %r10, 96(%rbx) movq 112(%rbx), %r12 movq 120(%rbx), %r8 - movq 128(%rdi), %r9 - movq 136(%rdi), %r10 + movq (%rdi), %r9 + movq 8(%rdi), %r10 # A[5] * B[8] mulx 64(%rbp), %rax, %rcx adcxq %rax, %r11 @@ -3744,27 +3749,27 @@ _sp_2048_mul_avx2_16: movq %r8, 120(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r9, 128(%rdi) - movq 144(%rdi), %r11 - movq 152(%rdi), %r12 - movq 160(%rdi), %r8 + movq %r9, (%rdi) + movq 16(%rdi), %r11 + movq 24(%rdi), %r12 + movq 32(%rdi), %r8 # A[5] * B[12] mulx 96(%rbp), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r11 # A[5] * B[13] mulx 104(%rbp), %rax, %rcx - movq %r10, 136(%rdi) + movq %r10, 8(%rdi) adcxq %rax, %r11 adoxq %rcx, %r12 # A[5] * B[14] mulx 112(%rbp), %rax, %rcx - movq %r11, 144(%rdi) + movq %r11, 16(%rdi) adcxq %rax, %r12 adoxq %rcx, %r8 # A[5] * B[15] mulx 120(%rbp), %rax, %rcx - movq %r12, 152(%rdi) + movq %r12, 24(%rdi) movq %r14, %r9 adcxq %rax, %r8 adoxq %rcx, %r9 @@ -3772,8 +3777,8 @@ _sp_2048_mul_avx2_16: movq %r14, %r13 adoxq %r14, %r13 adcxq %r14, %r13 - movq %r8, 160(%rdi) - movq %r9, 168(%rdi) + movq %r8, 32(%rdi) + movq %r9, 40(%rdi) movq 48(%rsi), %rdx movq 48(%rbx), %r9 movq 56(%rbx), %r10 @@ -3825,9 +3830,9 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r12 movq %r11, 104(%rbx) movq 120(%rbx), %r8 - movq 128(%rdi), %r9 - movq 136(%rdi), %r10 - movq 144(%rdi), %r11 + movq (%rdi), %r9 + movq 8(%rdi), %r10 + movq 16(%rdi), %r11 # A[6] * B[8] mulx 64(%rbp), %rax, %rcx adcxq %rax, %r12 @@ -3844,30 +3849,30 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r10 # A[6] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r9, 128(%rdi) + movq %r9, (%rdi) adcxq %rax, %r10 adoxq %rcx, %r11 - movq %r10, 136(%rdi) - movq 152(%rdi), %r12 - movq 160(%rdi), %r8 - movq 168(%rdi), %r9 + movq %r10, 8(%rdi) + movq 24(%rdi), %r12 + movq 32(%rdi), %r8 + movq 40(%rdi), %r9 # A[6] * B[12] mulx 96(%rbp), %rax, %rcx adcxq %rax, %r11 adoxq %rcx, %r12 # A[6] * B[13] mulx 104(%rbp), %rax, %rcx - movq %r11, 144(%rdi) + movq %r11, 16(%rdi) adcxq %rax, %r12 adoxq %rcx, %r8 # A[6] * B[14] mulx 112(%rbp), %rax, %rcx - movq %r12, 152(%rdi) + movq %r12, 24(%rdi) adcxq %rax, %r8 adoxq %rcx, %r9 # A[6] * B[15] mulx 120(%rbp), %rax, %rcx - movq %r8, 160(%rdi) + movq %r8, 32(%rdi) movq %r14, %r10 adcxq %rax, %r9 adoxq %rcx, %r10 @@ -3875,8 +3880,8 @@ _sp_2048_mul_avx2_16: movq %r14, %r13 adoxq %r14, %r13 adcxq %r14, %r13 - movq %r9, 168(%rdi) - movq %r10, 176(%rdi) + movq %r9, 40(%rdi) + movq %r10, 48(%rdi) movq 56(%rsi), %rdx movq 56(%rbx), %r10 movq 64(%rbx), %r11 @@ -3927,10 +3932,10 @@ _sp_2048_mul_avx2_16: adcxq %rax, %r12 adoxq %rcx, %r8 movq %r12, 112(%rbx) - movq 128(%rdi), %r9 - movq 136(%rdi), %r10 - movq 144(%rdi), %r11 - movq 152(%rdi), %r12 + movq (%rdi), %r9 + movq 8(%rdi), %r10 + movq 16(%rdi), %r11 + movq 24(%rdi), %r12 # A[7] * B[8] mulx 64(%rbp), %rax, %rcx adcxq %rax, %r8 @@ -3942,35 +3947,35 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r10 # A[7] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r9, 128(%rdi) + movq %r9, (%rdi) adcxq %rax, %r10 adoxq %rcx, %r11 # A[7] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r10, 136(%rdi) + movq %r10, 8(%rdi) adcxq %rax, %r11 adoxq %rcx, %r12 - movq %r11, 144(%rdi) - movq 160(%rdi), %r8 - movq 168(%rdi), %r9 - movq 176(%rdi), %r10 + movq %r11, 16(%rdi) + movq 32(%rdi), %r8 + movq 40(%rdi), %r9 + movq 48(%rdi), %r10 # A[7] * B[12] mulx 96(%rbp), %rax, %rcx adcxq %rax, %r12 adoxq %rcx, %r8 # A[7] * B[13] mulx 104(%rbp), %rax, %rcx - movq %r12, 152(%rdi) + movq %r12, 24(%rdi) adcxq %rax, %r8 adoxq %rcx, %r9 # A[7] * B[14] mulx 112(%rbp), %rax, %rcx - movq %r8, 160(%rdi) + movq %r8, 32(%rdi) adcxq %rax, %r9 adoxq %rcx, %r10 # A[7] * B[15] mulx 120(%rbp), %rax, %rcx - movq %r9, 168(%rdi) + movq %r9, 40(%rdi) movq %r14, %r11 adcxq %rax, %r10 adoxq %rcx, %r11 @@ -3978,8 +3983,8 @@ _sp_2048_mul_avx2_16: movq %r14, %r13 adoxq %r14, %r13 adcxq %r14, %r13 - movq %r10, 176(%rdi) - movq %r11, 184(%rdi) + movq %r10, 48(%rdi) + movq %r11, 56(%rdi) movq 64(%rsi), %rdx movq 64(%rbx), %r11 movq 72(%rbx), %r12 @@ -4009,7 +4014,7 @@ _sp_2048_mul_avx2_16: movq 104(%rbx), %r11 movq 112(%rbx), %r12 movq 120(%rbx), %r8 - movq 128(%rdi), %r9 + movq (%rdi), %r9 # A[8] * B[4] mulx 32(%rbp), %rax, %rcx adcxq %rax, %r10 @@ -4030,50 +4035,50 @@ _sp_2048_mul_avx2_16: adcxq %rax, %r8 adoxq %rcx, %r9 movq %r8, 120(%rbx) - movq 136(%rdi), %r10 - movq 144(%rdi), %r11 - movq 152(%rdi), %r12 - movq 160(%rdi), %r8 + movq 8(%rdi), %r10 + movq 16(%rdi), %r11 + movq 24(%rdi), %r12 + movq 32(%rdi), %r8 # A[8] * B[8] mulx 64(%rbp), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 # A[8] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r9, 128(%rdi) + movq %r9, (%rdi) adcxq %rax, %r10 adoxq %rcx, %r11 # A[8] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r10, 136(%rdi) + movq %r10, 8(%rdi) adcxq %rax, %r11 adoxq %rcx, %r12 # A[8] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r11, 144(%rdi) + movq %r11, 16(%rdi) adcxq %rax, %r12 adoxq %rcx, %r8 - movq %r12, 152(%rdi) - movq 168(%rdi), %r9 - movq 176(%rdi), %r10 - movq 184(%rdi), %r11 + movq %r12, 24(%rdi) + movq 40(%rdi), %r9 + movq 48(%rdi), %r10 + movq 56(%rdi), %r11 # A[8] * B[12] mulx 96(%rbp), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 # A[8] * B[13] mulx 104(%rbp), %rax, %rcx - movq %r8, 160(%rdi) + movq %r8, 32(%rdi) adcxq %rax, %r9 adoxq %rcx, %r10 # A[8] * B[14] mulx 112(%rbp), %rax, %rcx - movq %r9, 168(%rdi) + movq %r9, 40(%rdi) adcxq %rax, %r10 adoxq %rcx, %r11 # A[8] * B[15] mulx 120(%rbp), %rax, %rcx - movq %r10, 176(%rdi) + movq %r10, 48(%rdi) movq %r14, %r12 adcxq %rax, %r11 adoxq %rcx, %r12 @@ -4081,8 +4086,8 @@ _sp_2048_mul_avx2_16: movq %r14, %r13 adoxq %r14, %r13 adcxq %r14, %r13 - movq %r11, 184(%rdi) - movq %r12, 192(%rdi) + movq %r11, 56(%rdi) + movq %r12, 64(%rdi) movq 72(%rsi), %rdx movq 72(%rbx), %r12 movq 80(%rbx), %r8 @@ -4111,8 +4116,8 @@ _sp_2048_mul_avx2_16: movq %r10, 96(%rbx) movq 112(%rbx), %r12 movq 120(%rbx), %r8 - movq 128(%rdi), %r9 - movq 136(%rdi), %r10 + movq (%rdi), %r9 + movq 8(%rdi), %r10 # A[9] * B[4] mulx 32(%rbp), %rax, %rcx adcxq %rax, %r11 @@ -4132,51 +4137,51 @@ _sp_2048_mul_avx2_16: movq %r8, 120(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r9, 128(%rdi) - movq 144(%rdi), %r11 - movq 152(%rdi), %r12 - movq 160(%rdi), %r8 - movq 168(%rdi), %r9 + movq %r9, (%rdi) + movq 16(%rdi), %r11 + movq 24(%rdi), %r12 + movq 32(%rdi), %r8 + movq 40(%rdi), %r9 # A[9] * B[8] mulx 64(%rbp), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r11 # A[9] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r10, 136(%rdi) + movq %r10, 8(%rdi) adcxq %rax, %r11 adoxq %rcx, %r12 # A[9] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r11, 144(%rdi) + movq %r11, 16(%rdi) adcxq %rax, %r12 adoxq %rcx, %r8 # A[9] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r12, 152(%rdi) + movq %r12, 24(%rdi) adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 160(%rdi) - movq 176(%rdi), %r10 - movq 184(%rdi), %r11 - movq 192(%rdi), %r12 + movq %r8, 32(%rdi) + movq 48(%rdi), %r10 + movq 56(%rdi), %r11 + movq 64(%rdi), %r12 # A[9] * B[12] mulx 96(%rbp), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 # A[9] * B[13] mulx 104(%rbp), %rax, %rcx - movq %r9, 168(%rdi) + movq %r9, 40(%rdi) adcxq %rax, %r10 adoxq %rcx, %r11 # A[9] * B[14] mulx 112(%rbp), %rax, %rcx - movq %r10, 176(%rdi) + movq %r10, 48(%rdi) adcxq %rax, %r11 adoxq %rcx, %r12 # A[9] * B[15] mulx 120(%rbp), %rax, %rcx - movq %r11, 184(%rdi) + movq %r11, 56(%rdi) movq %r14, %r8 adcxq %rax, %r12 adoxq %rcx, %r8 @@ -4184,8 +4189,8 @@ _sp_2048_mul_avx2_16: movq %r14, %r13 adoxq %r14, %r13 adcxq %r14, %r13 - movq %r12, 192(%rdi) - movq %r8, 200(%rdi) + movq %r12, 64(%rdi) + movq %r8, 72(%rdi) movq 80(%rsi), %rdx movq 80(%rbx), %r8 movq 88(%rbx), %r9 @@ -4213,9 +4218,9 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r12 movq %r11, 104(%rbx) movq 120(%rbx), %r8 - movq 128(%rdi), %r9 - movq 136(%rdi), %r10 - movq 144(%rdi), %r11 + movq (%rdi), %r9 + movq 8(%rdi), %r10 + movq 16(%rdi), %r11 # A[10] * B[4] mulx 32(%rbp), %rax, %rcx adcxq %rax, %r12 @@ -4232,54 +4237,54 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r10 # A[10] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r9, 128(%rdi) + movq %r9, (%rdi) adcxq %rax, %r10 adoxq %rcx, %r11 - movq %r10, 136(%rdi) - movq 152(%rdi), %r12 - movq 160(%rdi), %r8 - movq 168(%rdi), %r9 - movq 176(%rdi), %r10 + movq %r10, 8(%rdi) + movq 24(%rdi), %r12 + movq 32(%rdi), %r8 + movq 40(%rdi), %r9 + movq 48(%rdi), %r10 # A[10] * B[8] mulx 64(%rbp), %rax, %rcx adcxq %rax, %r11 adoxq %rcx, %r12 # A[10] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r11, 144(%rdi) + movq %r11, 16(%rdi) adcxq %rax, %r12 adoxq %rcx, %r8 # A[10] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r12, 152(%rdi) + movq %r12, 24(%rdi) adcxq %rax, %r8 adoxq %rcx, %r9 # A[10] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r8, 160(%rdi) + movq %r8, 32(%rdi) adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r9, 168(%rdi) - movq 184(%rdi), %r11 - movq 192(%rdi), %r12 - movq 200(%rdi), %r8 + movq %r9, 40(%rdi) + movq 56(%rdi), %r11 + movq 64(%rdi), %r12 + movq 72(%rdi), %r8 # A[10] * B[12] mulx 96(%rbp), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r11 # A[10] * B[13] mulx 104(%rbp), %rax, %rcx - movq %r10, 176(%rdi) + movq %r10, 48(%rdi) adcxq %rax, %r11 adoxq %rcx, %r12 # A[10] * B[14] mulx 112(%rbp), %rax, %rcx - movq %r11, 184(%rdi) + movq %r11, 56(%rdi) adcxq %rax, %r12 adoxq %rcx, %r8 # A[10] * B[15] mulx 120(%rbp), %rax, %rcx - movq %r12, 192(%rdi) + movq %r12, 64(%rdi) movq %r14, %r9 adcxq %rax, %r8 adoxq %rcx, %r9 @@ -4287,8 +4292,8 @@ _sp_2048_mul_avx2_16: movq %r14, %r13 adoxq %r14, %r13 adcxq %r14, %r13 - movq %r8, 200(%rdi) - movq %r9, 208(%rdi) + movq %r8, 72(%rdi) + movq %r9, 80(%rdi) movq 88(%rsi), %rdx movq 88(%rbx), %r9 movq 96(%rbx), %r10 @@ -4315,10 +4320,10 @@ _sp_2048_mul_avx2_16: adcxq %rax, %r12 adoxq %rcx, %r8 movq %r12, 112(%rbx) - movq 128(%rdi), %r9 - movq 136(%rdi), %r10 - movq 144(%rdi), %r11 - movq 152(%rdi), %r12 + movq (%rdi), %r9 + movq 8(%rdi), %r10 + movq 16(%rdi), %r11 + movq 24(%rdi), %r12 # A[11] * B[4] mulx 32(%rbp), %rax, %rcx adcxq %rax, %r8 @@ -4330,59 +4335,59 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r10 # A[11] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r9, 128(%rdi) + movq %r9, (%rdi) adcxq %rax, %r10 adoxq %rcx, %r11 # A[11] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r10, 136(%rdi) + movq %r10, 8(%rdi) adcxq %rax, %r11 adoxq %rcx, %r12 - movq %r11, 144(%rdi) - movq 160(%rdi), %r8 - movq 168(%rdi), %r9 - movq 176(%rdi), %r10 - movq 184(%rdi), %r11 + movq %r11, 16(%rdi) + movq 32(%rdi), %r8 + movq 40(%rdi), %r9 + movq 48(%rdi), %r10 + movq 56(%rdi), %r11 # A[11] * B[8] mulx 64(%rbp), %rax, %rcx adcxq %rax, %r12 adoxq %rcx, %r8 # A[11] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r12, 152(%rdi) + movq %r12, 24(%rdi) adcxq %rax, %r8 adoxq %rcx, %r9 # A[11] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r8, 160(%rdi) + movq %r8, 32(%rdi) adcxq %rax, %r9 adoxq %rcx, %r10 # A[11] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r9, 168(%rdi) + movq %r9, 40(%rdi) adcxq %rax, %r10 adoxq %rcx, %r11 - movq %r10, 176(%rdi) - movq 192(%rdi), %r12 - movq 200(%rdi), %r8 - movq 208(%rdi), %r9 + movq %r10, 48(%rdi) + movq 64(%rdi), %r12 + movq 72(%rdi), %r8 + movq 80(%rdi), %r9 # A[11] * B[12] mulx 96(%rbp), %rax, %rcx adcxq %rax, %r11 adoxq %rcx, %r12 # A[11] * B[13] mulx 104(%rbp), %rax, %rcx - movq %r11, 184(%rdi) + movq %r11, 56(%rdi) adcxq %rax, %r12 adoxq %rcx, %r8 # A[11] * B[14] mulx 112(%rbp), %rax, %rcx - movq %r12, 192(%rdi) + movq %r12, 64(%rdi) adcxq %rax, %r8 adoxq %rcx, %r9 # A[11] * B[15] mulx 120(%rbp), %rax, %rcx - movq %r8, 200(%rdi) + movq %r8, 72(%rdi) movq %r14, %r10 adcxq %rax, %r9 adoxq %rcx, %r10 @@ -4390,14 +4395,14 @@ _sp_2048_mul_avx2_16: movq %r14, %r13 adoxq %r14, %r13 adcxq %r14, %r13 - movq %r9, 208(%rdi) - movq %r10, 216(%rdi) + movq %r9, 80(%rdi) + movq %r10, 88(%rdi) movq 96(%rsi), %rdx movq 96(%rbx), %r10 movq 104(%rbx), %r11 movq 112(%rbx), %r12 movq 120(%rbx), %r8 - movq 128(%rdi), %r9 + movq (%rdi), %r9 # A[12] * B[0] mulx (%rbp), %rax, %rcx adcxq %rax, %r10 @@ -4418,74 +4423,74 @@ _sp_2048_mul_avx2_16: adcxq %rax, %r8 adoxq %rcx, %r9 movq %r8, 120(%rbx) - movq 136(%rdi), %r10 - movq 144(%rdi), %r11 - movq 152(%rdi), %r12 - movq 160(%rdi), %r8 + movq 8(%rdi), %r10 + movq 16(%rdi), %r11 + movq 24(%rdi), %r12 + movq 32(%rdi), %r8 # A[12] * B[4] mulx 32(%rbp), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 # A[12] * B[5] mulx 40(%rbp), %rax, %rcx - movq %r9, 128(%rdi) + movq %r9, (%rdi) adcxq %rax, %r10 adoxq %rcx, %r11 # A[12] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r10, 136(%rdi) + movq %r10, 8(%rdi) adcxq %rax, %r11 adoxq %rcx, %r12 # A[12] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r11, 144(%rdi) + movq %r11, 16(%rdi) adcxq %rax, %r12 adoxq %rcx, %r8 - movq %r12, 152(%rdi) - movq 168(%rdi), %r9 - movq 176(%rdi), %r10 - movq 184(%rdi), %r11 - movq 192(%rdi), %r12 + movq %r12, 24(%rdi) + movq 40(%rdi), %r9 + movq 48(%rdi), %r10 + movq 56(%rdi), %r11 + movq 64(%rdi), %r12 # A[12] * B[8] mulx 64(%rbp), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 # A[12] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r8, 160(%rdi) + movq %r8, 32(%rdi) adcxq %rax, %r9 adoxq %rcx, %r10 # A[12] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r9, 168(%rdi) + movq %r9, 40(%rdi) adcxq %rax, %r10 adoxq %rcx, %r11 # A[12] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r10, 176(%rdi) + movq %r10, 48(%rdi) adcxq %rax, %r11 adoxq %rcx, %r12 - movq %r11, 184(%rdi) - movq 200(%rdi), %r8 - movq 208(%rdi), %r9 - movq 216(%rdi), %r10 + movq %r11, 56(%rdi) + movq 72(%rdi), %r8 + movq 80(%rdi), %r9 + movq 88(%rdi), %r10 # A[12] * B[12] mulx 96(%rbp), %rax, %rcx adcxq %rax, %r12 adoxq %rcx, %r8 # A[12] * B[13] mulx 104(%rbp), %rax, %rcx - movq %r12, 192(%rdi) + movq %r12, 64(%rdi) adcxq %rax, %r8 adoxq %rcx, %r9 # A[12] * B[14] mulx 112(%rbp), %rax, %rcx - movq %r8, 200(%rdi) + movq %r8, 72(%rdi) adcxq %rax, %r9 adoxq %rcx, %r10 # A[12] * B[15] mulx 120(%rbp), %rax, %rcx - movq %r9, 208(%rdi) + movq %r9, 80(%rdi) movq %r14, %r11 adcxq %rax, %r10 adoxq %rcx, %r11 @@ -4493,14 +4498,14 @@ _sp_2048_mul_avx2_16: movq %r14, %r13 adoxq %r14, %r13 adcxq %r14, %r13 - movq %r10, 216(%rdi) - movq %r11, 224(%rdi) + movq %r10, 88(%rdi) + movq %r11, 96(%rdi) movq 104(%rsi), %rdx movq 104(%rbx), %r11 movq 112(%rbx), %r12 movq 120(%rbx), %r8 - movq 128(%rdi), %r9 - movq 136(%rdi), %r10 + movq (%rdi), %r9 + movq 8(%rdi), %r10 # A[13] * B[0] mulx (%rbp), %rax, %rcx adcxq %rax, %r11 @@ -4520,75 +4525,75 @@ _sp_2048_mul_avx2_16: movq %r8, 120(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r9, 128(%rdi) - movq 144(%rdi), %r11 - movq 152(%rdi), %r12 - movq 160(%rdi), %r8 - movq 168(%rdi), %r9 + movq %r9, (%rdi) + movq 16(%rdi), %r11 + movq 24(%rdi), %r12 + movq 32(%rdi), %r8 + movq 40(%rdi), %r9 # A[13] * B[4] mulx 32(%rbp), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r11 # A[13] * B[5] mulx 40(%rbp), %rax, %rcx - movq %r10, 136(%rdi) + movq %r10, 8(%rdi) adcxq %rax, %r11 adoxq %rcx, %r12 # A[13] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r11, 144(%rdi) + movq %r11, 16(%rdi) adcxq %rax, %r12 adoxq %rcx, %r8 # A[13] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r12, 152(%rdi) + movq %r12, 24(%rdi) adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 160(%rdi) - movq 176(%rdi), %r10 - movq 184(%rdi), %r11 - movq 192(%rdi), %r12 - movq 200(%rdi), %r8 + movq %r8, 32(%rdi) + movq 48(%rdi), %r10 + movq 56(%rdi), %r11 + movq 64(%rdi), %r12 + movq 72(%rdi), %r8 # A[13] * B[8] mulx 64(%rbp), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 # A[13] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r9, 168(%rdi) + movq %r9, 40(%rdi) adcxq %rax, %r10 adoxq %rcx, %r11 # A[13] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r10, 176(%rdi) + movq %r10, 48(%rdi) adcxq %rax, %r11 adoxq %rcx, %r12 # A[13] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r11, 184(%rdi) + movq %r11, 56(%rdi) adcxq %rax, %r12 adoxq %rcx, %r8 - movq %r12, 192(%rdi) - movq 208(%rdi), %r9 - movq 216(%rdi), %r10 - movq 224(%rdi), %r11 + movq %r12, 64(%rdi) + movq 80(%rdi), %r9 + movq 88(%rdi), %r10 + movq 96(%rdi), %r11 # A[13] * B[12] mulx 96(%rbp), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 # A[13] * B[13] mulx 104(%rbp), %rax, %rcx - movq %r8, 200(%rdi) + movq %r8, 72(%rdi) adcxq %rax, %r9 adoxq %rcx, %r10 # A[13] * B[14] mulx 112(%rbp), %rax, %rcx - movq %r9, 208(%rdi) + movq %r9, 80(%rdi) adcxq %rax, %r10 adoxq %rcx, %r11 # A[13] * B[15] mulx 120(%rbp), %rax, %rcx - movq %r10, 216(%rdi) + movq %r10, 88(%rdi) movq %r14, %r12 adcxq %rax, %r11 adoxq %rcx, %r12 @@ -4596,14 +4601,14 @@ _sp_2048_mul_avx2_16: movq %r14, %r13 adoxq %r14, %r13 adcxq %r14, %r13 - movq %r11, 224(%rdi) - movq %r12, 232(%rdi) + movq %r11, 96(%rdi) + movq %r12, 104(%rdi) movq 112(%rsi), %rdx movq 112(%rbx), %r12 movq 120(%rbx), %r8 - movq 128(%rdi), %r9 - movq 136(%rdi), %r10 - movq 144(%rdi), %r11 + movq (%rdi), %r9 + movq 8(%rdi), %r10 + movq 16(%rdi), %r11 # A[14] * B[0] mulx (%rbp), %rax, %rcx adcxq %rax, %r12 @@ -4620,78 +4625,78 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r10 # A[14] * B[3] mulx 24(%rbp), %rax, %rcx - movq %r9, 128(%rdi) + movq %r9, (%rdi) adcxq %rax, %r10 adoxq %rcx, %r11 - movq %r10, 136(%rdi) - movq 152(%rdi), %r12 - movq 160(%rdi), %r8 - movq 168(%rdi), %r9 - movq 176(%rdi), %r10 + movq %r10, 8(%rdi) + movq 24(%rdi), %r12 + movq 32(%rdi), %r8 + movq 40(%rdi), %r9 + movq 48(%rdi), %r10 # A[14] * B[4] mulx 32(%rbp), %rax, %rcx adcxq %rax, %r11 adoxq %rcx, %r12 # A[14] * B[5] mulx 40(%rbp), %rax, %rcx - movq %r11, 144(%rdi) + movq %r11, 16(%rdi) adcxq %rax, %r12 adoxq %rcx, %r8 # A[14] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r12, 152(%rdi) + movq %r12, 24(%rdi) adcxq %rax, %r8 adoxq %rcx, %r9 # A[14] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r8, 160(%rdi) + movq %r8, 32(%rdi) adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r9, 168(%rdi) - movq 184(%rdi), %r11 - movq 192(%rdi), %r12 - movq 200(%rdi), %r8 - movq 208(%rdi), %r9 + movq %r9, 40(%rdi) + movq 56(%rdi), %r11 + movq 64(%rdi), %r12 + movq 72(%rdi), %r8 + movq 80(%rdi), %r9 # A[14] * B[8] mulx 64(%rbp), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r11 # A[14] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r10, 176(%rdi) + movq %r10, 48(%rdi) adcxq %rax, %r11 adoxq %rcx, %r12 # A[14] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r11, 184(%rdi) + movq %r11, 56(%rdi) adcxq %rax, %r12 adoxq %rcx, %r8 # A[14] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r12, 192(%rdi) + movq %r12, 64(%rdi) adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 200(%rdi) - movq 216(%rdi), %r10 - movq 224(%rdi), %r11 - movq 232(%rdi), %r12 + movq %r8, 72(%rdi) + movq 88(%rdi), %r10 + movq 96(%rdi), %r11 + movq 104(%rdi), %r12 # A[14] * B[12] mulx 96(%rbp), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 # A[14] * B[13] mulx 104(%rbp), %rax, %rcx - movq %r9, 208(%rdi) + movq %r9, 80(%rdi) adcxq %rax, %r10 adoxq %rcx, %r11 # A[14] * B[14] mulx 112(%rbp), %rax, %rcx - movq %r10, 216(%rdi) + movq %r10, 88(%rdi) adcxq %rax, %r11 adoxq %rcx, %r12 # A[14] * B[15] mulx 120(%rbp), %rax, %rcx - movq %r11, 224(%rdi) + movq %r11, 96(%rdi) movq %r14, %r8 adcxq %rax, %r12 adoxq %rcx, %r8 @@ -4699,14 +4704,14 @@ _sp_2048_mul_avx2_16: movq %r14, %r13 adoxq %r14, %r13 adcxq %r14, %r13 - movq %r12, 232(%rdi) - movq %r8, 240(%rdi) + movq %r12, 104(%rdi) + movq %r8, 112(%rdi) movq 120(%rsi), %rdx movq 120(%rbx), %r8 - movq 128(%rdi), %r9 - movq 136(%rdi), %r10 - movq 144(%rdi), %r11 - movq 152(%rdi), %r12 + movq (%rdi), %r9 + movq 8(%rdi), %r10 + movq 16(%rdi), %r11 + movq 24(%rdi), %r12 # A[15] * B[0] mulx (%rbp), %rax, %rcx adcxq %rax, %r8 @@ -4718,89 +4723,90 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r10 # A[15] * B[2] mulx 16(%rbp), %rax, %rcx - movq %r9, 128(%rdi) + movq %r9, (%rdi) adcxq %rax, %r10 adoxq %rcx, %r11 # A[15] * B[3] mulx 24(%rbp), %rax, %rcx - movq %r10, 136(%rdi) + movq %r10, 8(%rdi) adcxq %rax, %r11 adoxq %rcx, %r12 - movq %r11, 144(%rdi) - movq 160(%rdi), %r8 - movq 168(%rdi), %r9 - movq 176(%rdi), %r10 - movq 184(%rdi), %r11 + movq %r11, 16(%rdi) + movq 32(%rdi), %r8 + movq 40(%rdi), %r9 + movq 48(%rdi), %r10 + movq 56(%rdi), %r11 # A[15] * B[4] mulx 32(%rbp), %rax, %rcx adcxq %rax, %r12 adoxq %rcx, %r8 # A[15] * B[5] mulx 40(%rbp), %rax, %rcx - movq %r12, 152(%rdi) + movq %r12, 24(%rdi) adcxq %rax, %r8 adoxq %rcx, %r9 # A[15] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r8, 160(%rdi) + movq %r8, 32(%rdi) adcxq %rax, %r9 adoxq %rcx, %r10 # A[15] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r9, 168(%rdi) + movq %r9, 40(%rdi) adcxq %rax, %r10 adoxq %rcx, %r11 - movq %r10, 176(%rdi) - movq 192(%rdi), %r12 - movq 200(%rdi), %r8 - movq 208(%rdi), %r9 - movq 216(%rdi), %r10 + movq %r10, 48(%rdi) + movq 64(%rdi), %r12 + movq 72(%rdi), %r8 + movq 80(%rdi), %r9 + movq 88(%rdi), %r10 # A[15] * B[8] mulx 64(%rbp), %rax, %rcx adcxq %rax, %r11 adoxq %rcx, %r12 # A[15] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r11, 184(%rdi) + movq %r11, 56(%rdi) adcxq %rax, %r12 adoxq %rcx, %r8 # A[15] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r12, 192(%rdi) + movq %r12, 64(%rdi) adcxq %rax, %r8 adoxq %rcx, %r9 # A[15] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r8, 200(%rdi) + movq %r8, 72(%rdi) adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r9, 208(%rdi) - movq 224(%rdi), %r11 - movq 232(%rdi), %r12 - movq 240(%rdi), %r8 + movq %r9, 80(%rdi) + movq 96(%rdi), %r11 + movq 104(%rdi), %r12 + movq 112(%rdi), %r8 # A[15] * B[12] mulx 96(%rbp), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r11 # A[15] * B[13] mulx 104(%rbp), %rax, %rcx - movq %r10, 216(%rdi) + movq %r10, 88(%rdi) adcxq %rax, %r11 adoxq %rcx, %r12 # A[15] * B[14] mulx 112(%rbp), %rax, %rcx - movq %r11, 224(%rdi) + movq %r11, 96(%rdi) adcxq %rax, %r12 adoxq %rcx, %r8 # A[15] * B[15] mulx 120(%rbp), %rax, %rcx - movq %r12, 232(%rdi) + movq %r12, 104(%rdi) movq %r14, %r9 adcxq %rax, %r8 adoxq %rcx, %r9 adcxq %r13, %r9 - movq %r8, 240(%rdi) - movq %r9, 248(%rdi) + movq %r8, 112(%rdi) + movq %r9, 120(%rdi) + subq $0x80, %rdi cmpq %rdi, %rsi je L_start_2048_mul_avx2_16 cmpq %rdi, %rbp @@ -4862,6 +4868,7 @@ _sp_2048_sqr_avx2_16: cmpq %rdi, %rsi movq %rsp, %rbp cmovne %rdi, %rbp + addq $0x80, %rdi xorq %r11, %r11 # Diagonal 1 xorq %r10, %r10 @@ -4957,7 +4964,7 @@ _sp_2048_sqr_avx2_16: movq %r11, %r12 adcxq %r11, %r12 adoxq %r11, %r12 - movq %r8, 128(%rdi) + movq %r8, (%rdi) # Diagonal 2 movq 24(%rbp), %r8 movq 32(%rbp), %r9 @@ -5033,7 +5040,7 @@ _sp_2048_sqr_avx2_16: adoxq %rcx, %rbx # No store %r14 # No store %r15 - movq 128(%rdi), %r9 + movq (%rdi), %r9 movq %r11, %r10 # A[14] x A[1] mulxq 112(%rsi), %rax, %rcx @@ -5044,20 +5051,20 @@ _sp_2048_sqr_avx2_16: adcxq %rax, %r9 adoxq %rcx, %r10 # No store %rbx - movq %r9, 128(%rdi) + movq %r9, (%rdi) movq %r11, %r8 # A[15] x A[2] movq 16(%rsi), %rdx mulxq 120(%rsi), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r10, 136(%rdi) + movq %r10, 8(%rdi) # Carry adcxq %r12, %r8 movq %r11, %r12 adcxq %r11, %r12 adoxq %r11, %r12 - movq %r8, 144(%rdi) + movq %r8, 16(%rdi) # Diagonal 3 movq 40(%rbp), %r8 movq 48(%rbp), %r9 @@ -5120,8 +5127,8 @@ _sp_2048_sqr_avx2_16: adoxq %rcx, %rbx # No store %r14 # No store %r15 - movq 128(%rdi), %r10 - movq 136(%rdi), %r8 + movq (%rdi), %r10 + movq 8(%rdi), %r8 # A[13] x A[2] mulxq 104(%rsi), %rax, %rcx adcxq %rax, %rbx @@ -5131,8 +5138,8 @@ _sp_2048_sqr_avx2_16: adcxq %rax, %r10 adoxq %rcx, %r8 # No store %rbx - movq %r10, 128(%rdi) - movq 144(%rdi), %r9 + movq %r10, (%rdi) + movq 16(%rdi), %r9 movq %r11, %r10 # A[14] x A[3] movq 112(%rsi), %rdx @@ -5143,20 +5150,20 @@ _sp_2048_sqr_avx2_16: mulxq 32(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r8, 136(%rdi) - movq %r9, 144(%rdi) + movq %r8, 8(%rdi) + movq %r9, 16(%rdi) movq %r11, %r8 # A[14] x A[5] mulxq 40(%rsi), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r10, 152(%rdi) + movq %r10, 24(%rdi) # Carry adcxq %r12, %r8 movq %r11, %r12 adcxq %r11, %r12 adoxq %r11, %r12 - movq %r8, 160(%rdi) + movq %r8, 32(%rdi) # Diagonal 4 movq 56(%rbp), %r8 movq 64(%rbp), %r9 @@ -5208,8 +5215,8 @@ _sp_2048_sqr_avx2_16: adoxq %rcx, %rbx # No store %r14 # No store %r15 - movq 128(%rdi), %r8 - movq 136(%rdi), %r9 + movq (%rdi), %r8 + movq 8(%rdi), %r9 # A[12] x A[3] mulxq 96(%rsi), %rax, %rcx adcxq %rax, %rbx @@ -5219,9 +5226,9 @@ _sp_2048_sqr_avx2_16: adcxq %rax, %r8 adoxq %rcx, %r9 # No store %rbx - movq %r8, 128(%rdi) - movq 144(%rdi), %r10 - movq 152(%rdi), %r8 + movq %r8, (%rdi) + movq 16(%rdi), %r10 + movq 24(%rdi), %r8 # A[13] x A[4] movq 104(%rsi), %rdx mulxq 32(%rsi), %rax, %rcx @@ -5231,9 +5238,9 @@ _sp_2048_sqr_avx2_16: mulxq 40(%rsi), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r9, 136(%rdi) - movq %r10, 144(%rdi) - movq 160(%rdi), %r9 + movq %r9, 8(%rdi) + movq %r10, 16(%rdi) + movq 32(%rdi), %r9 movq %r11, %r10 # A[13] x A[6] mulxq 48(%rsi), %rax, %rcx @@ -5243,20 +5250,20 @@ _sp_2048_sqr_avx2_16: mulxq 56(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r8, 152(%rdi) - movq %r9, 160(%rdi) + movq %r8, 24(%rdi) + movq %r9, 32(%rdi) movq %r11, %r8 # A[13] x A[8] mulxq 64(%rsi), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r10, 168(%rdi) + movq %r10, 40(%rdi) # Carry adcxq %r12, %r8 movq %r11, %r12 adcxq %r11, %r12 adoxq %r11, %r12 - movq %r8, 176(%rdi) + movq %r8, 48(%rdi) # Diagonal 5 movq 72(%rbp), %r8 movq 80(%rbp), %r9 @@ -5296,8 +5303,8 @@ _sp_2048_sqr_avx2_16: adoxq %rcx, %rbx # No store %r14 # No store %r15 - movq 128(%rdi), %r9 - movq 136(%rdi), %r10 + movq (%rdi), %r9 + movq 8(%rdi), %r10 # A[11] x A[4] mulxq 88(%rsi), %rax, %rcx adcxq %rax, %rbx @@ -5307,9 +5314,9 @@ _sp_2048_sqr_avx2_16: adcxq %rax, %r9 adoxq %rcx, %r10 # No store %rbx - movq %r9, 128(%rdi) - movq 144(%rdi), %r8 - movq 152(%rdi), %r9 + movq %r9, (%rdi) + movq 16(%rdi), %r8 + movq 24(%rdi), %r9 # A[12] x A[5] movq 96(%rsi), %rdx mulxq 40(%rsi), %rax, %rcx @@ -5319,10 +5326,10 @@ _sp_2048_sqr_avx2_16: mulxq 48(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r10, 136(%rdi) - movq %r8, 144(%rdi) - movq 160(%rdi), %r10 - movq 168(%rdi), %r8 + movq %r10, 8(%rdi) + movq %r8, 16(%rdi) + movq 32(%rdi), %r10 + movq 40(%rdi), %r8 # A[12] x A[7] mulxq 56(%rsi), %rax, %rcx adcxq %rax, %r9 @@ -5331,9 +5338,9 @@ _sp_2048_sqr_avx2_16: mulxq 64(%rsi), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r9, 152(%rdi) - movq %r10, 160(%rdi) - movq 176(%rdi), %r9 + movq %r9, 24(%rdi) + movq %r10, 32(%rdi) + movq 48(%rdi), %r9 movq %r11, %r10 # A[12] x A[9] mulxq 72(%rsi), %rax, %rcx @@ -5343,20 +5350,20 @@ _sp_2048_sqr_avx2_16: mulxq 80(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r8, 168(%rdi) - movq %r9, 176(%rdi) + movq %r8, 40(%rdi) + movq %r9, 48(%rdi) movq %r11, %r8 # A[12] x A[11] mulxq 88(%rsi), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r10, 184(%rdi) + movq %r10, 56(%rdi) # Carry adcxq %r12, %r8 movq %r11, %r12 adcxq %r11, %r12 adoxq %r11, %r12 - movq %r8, 192(%rdi) + movq %r8, 64(%rdi) # Diagonal 6 movq 88(%rbp), %r8 # No load %r13 - %r9 @@ -5384,8 +5391,8 @@ _sp_2048_sqr_avx2_16: adoxq %rcx, %rbx # No store %r14 # No store %r15 - movq 128(%rdi), %r10 - movq 136(%rdi), %r8 + movq (%rdi), %r10 + movq 8(%rdi), %r8 # A[10] x A[5] mulxq 80(%rsi), %rax, %rcx adcxq %rax, %rbx @@ -5395,9 +5402,9 @@ _sp_2048_sqr_avx2_16: adcxq %rax, %r10 adoxq %rcx, %r8 # No store %rbx - movq %r10, 128(%rdi) - movq 144(%rdi), %r9 - movq 152(%rdi), %r10 + movq %r10, (%rdi) + movq 16(%rdi), %r9 + movq 24(%rdi), %r10 # A[11] x A[6] movq 88(%rsi), %rdx mulxq 48(%rsi), %rax, %rcx @@ -5407,10 +5414,10 @@ _sp_2048_sqr_avx2_16: mulxq 56(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r8, 136(%rdi) - movq %r9, 144(%rdi) - movq 160(%rdi), %r8 - movq 168(%rdi), %r9 + movq %r8, 8(%rdi) + movq %r9, 16(%rdi) + movq 32(%rdi), %r8 + movq 40(%rdi), %r9 # A[11] x A[8] mulxq 64(%rsi), %rax, %rcx adcxq %rax, %r10 @@ -5419,10 +5426,10 @@ _sp_2048_sqr_avx2_16: mulxq 72(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r10, 152(%rdi) - movq %r8, 160(%rdi) - movq 176(%rdi), %r10 - movq 184(%rdi), %r8 + movq %r10, 24(%rdi) + movq %r8, 32(%rdi) + movq 48(%rdi), %r10 + movq 56(%rdi), %r8 # A[11] x A[10] mulxq 80(%rsi), %rax, %rcx adcxq %rax, %r9 @@ -5432,9 +5439,9 @@ _sp_2048_sqr_avx2_16: mulxq 72(%rsi), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r9, 168(%rdi) - movq %r10, 176(%rdi) - movq 192(%rdi), %r9 + movq %r9, 40(%rdi) + movq %r10, 48(%rdi) + movq 64(%rdi), %r9 movq %r11, %r10 # A[13] x A[10] mulxq 80(%rsi), %rax, %rcx @@ -5444,20 +5451,20 @@ _sp_2048_sqr_avx2_16: mulxq 88(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r8, 184(%rdi) - movq %r9, 192(%rdi) + movq %r8, 56(%rdi) + movq %r9, 64(%rdi) movq %r11, %r8 # A[13] x A[12] mulxq 96(%rsi), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r10, 200(%rdi) + movq %r10, 72(%rdi) # Carry adcxq %r12, %r8 movq %r11, %r12 adcxq %r11, %r12 adoxq %r11, %r12 - movq %r8, 208(%rdi) + movq %r8, 80(%rdi) # Diagonal 7 # No load %r14 - %r8 # No load %r15 - %r9 @@ -5473,8 +5480,8 @@ _sp_2048_sqr_avx2_16: adoxq %rcx, %rbx # No store %r14 # No store %r15 - movq 128(%rdi), %r8 - movq 136(%rdi), %r9 + movq (%rdi), %r8 + movq 8(%rdi), %r9 # A[9] x A[6] mulxq 72(%rsi), %rax, %rcx adcxq %rax, %rbx @@ -5484,9 +5491,9 @@ _sp_2048_sqr_avx2_16: adcxq %rax, %r8 adoxq %rcx, %r9 # No store %rbx - movq %r8, 128(%rdi) - movq 144(%rdi), %r10 - movq 152(%rdi), %r8 + movq %r8, (%rdi) + movq 16(%rdi), %r10 + movq 24(%rdi), %r8 # A[10] x A[7] movq 80(%rsi), %rdx mulxq 56(%rsi), %rax, %rcx @@ -5496,10 +5503,10 @@ _sp_2048_sqr_avx2_16: mulxq 64(%rsi), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r9, 136(%rdi) - movq %r10, 144(%rdi) - movq 160(%rdi), %r9 - movq 168(%rdi), %r10 + movq %r9, 8(%rdi) + movq %r10, 16(%rdi) + movq 32(%rdi), %r9 + movq 40(%rdi), %r10 # A[10] x A[9] mulxq 72(%rsi), %rax, %rcx adcxq %rax, %r8 @@ -5509,10 +5516,10 @@ _sp_2048_sqr_avx2_16: mulxq 48(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r8, 152(%rdi) - movq %r9, 160(%rdi) - movq 176(%rdi), %r8 - movq 184(%rdi), %r9 + movq %r8, 24(%rdi) + movq %r9, 32(%rdi) + movq 48(%rdi), %r8 + movq 56(%rdi), %r9 # A[14] x A[7] mulxq 56(%rsi), %rax, %rcx adcxq %rax, %r10 @@ -5521,10 +5528,10 @@ _sp_2048_sqr_avx2_16: mulxq 64(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r10, 168(%rdi) - movq %r8, 176(%rdi) - movq 192(%rdi), %r10 - movq 200(%rdi), %r8 + movq %r10, 40(%rdi) + movq %r8, 48(%rdi) + movq 64(%rdi), %r10 + movq 72(%rdi), %r8 # A[14] x A[9] mulxq 72(%rsi), %rax, %rcx adcxq %rax, %r9 @@ -5533,9 +5540,9 @@ _sp_2048_sqr_avx2_16: mulxq 80(%rsi), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r9, 184(%rdi) - movq %r10, 192(%rdi) - movq 208(%rdi), %r9 + movq %r9, 56(%rdi) + movq %r10, 64(%rdi) + movq 80(%rdi), %r9 movq %r11, %r10 # A[14] x A[11] mulxq 88(%rsi), %rax, %rcx @@ -5545,24 +5552,24 @@ _sp_2048_sqr_avx2_16: mulxq 96(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r8, 200(%rdi) - movq %r9, 208(%rdi) + movq %r8, 72(%rdi) + movq %r9, 80(%rdi) movq %r11, %r8 # A[14] x A[13] mulxq 104(%rsi), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r10, 216(%rdi) + movq %r10, 88(%rdi) # Carry adcxq %r12, %r8 movq %r11, %r12 adcxq %r11, %r12 adoxq %r11, %r12 - movq %r8, 224(%rdi) + movq %r8, 96(%rdi) # Diagonal 8 # No load %rbx - %r8 - movq 128(%rdi), %r9 - movq 136(%rdi), %r10 + movq (%rdi), %r9 + movq 8(%rdi), %r10 # A[8] x A[7] movq 56(%rsi), %rdx mulxq 64(%rsi), %rax, %rcx @@ -5573,9 +5580,9 @@ _sp_2048_sqr_avx2_16: adcxq %rax, %r9 adoxq %rcx, %r10 # No store %rbx - movq %r9, 128(%rdi) - movq 144(%rdi), %r8 - movq 152(%rdi), %r9 + movq %r9, (%rdi) + movq 16(%rdi), %r8 + movq 24(%rdi), %r9 # A[9] x A[8] movq 64(%rsi), %rdx mulxq 72(%rsi), %rax, %rcx @@ -5586,10 +5593,10 @@ _sp_2048_sqr_avx2_16: mulxq 24(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r10, 136(%rdi) - movq %r8, 144(%rdi) - movq 160(%rdi), %r10 - movq 168(%rdi), %r8 + movq %r10, 8(%rdi) + movq %r8, 16(%rdi) + movq 32(%rdi), %r10 + movq 40(%rdi), %r8 # A[15] x A[4] mulxq 32(%rsi), %rax, %rcx adcxq %rax, %r9 @@ -5598,10 +5605,10 @@ _sp_2048_sqr_avx2_16: mulxq 40(%rsi), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r9, 152(%rdi) - movq %r10, 160(%rdi) - movq 176(%rdi), %r9 - movq 184(%rdi), %r10 + movq %r9, 24(%rdi) + movq %r10, 32(%rdi) + movq 48(%rdi), %r9 + movq 56(%rdi), %r10 # A[15] x A[6] mulxq 48(%rsi), %rax, %rcx adcxq %rax, %r8 @@ -5610,10 +5617,10 @@ _sp_2048_sqr_avx2_16: mulxq 56(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r8, 168(%rdi) - movq %r9, 176(%rdi) - movq 192(%rdi), %r8 - movq 200(%rdi), %r9 + movq %r8, 40(%rdi) + movq %r9, 48(%rdi) + movq 64(%rdi), %r8 + movq 72(%rdi), %r9 # A[15] x A[8] mulxq 64(%rsi), %rax, %rcx adcxq %rax, %r10 @@ -5622,10 +5629,10 @@ _sp_2048_sqr_avx2_16: mulxq 72(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r10, 184(%rdi) - movq %r8, 192(%rdi) - movq 208(%rdi), %r10 - movq 216(%rdi), %r8 + movq %r10, 56(%rdi) + movq %r8, 64(%rdi) + movq 80(%rdi), %r10 + movq 88(%rdi), %r8 # A[15] x A[10] mulxq 80(%rsi), %rax, %rcx adcxq %rax, %r9 @@ -5634,9 +5641,9 @@ _sp_2048_sqr_avx2_16: mulxq 88(%rsi), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r9, 200(%rdi) - movq %r10, 208(%rdi) - movq 224(%rdi), %r9 + movq %r9, 72(%rdi) + movq %r10, 80(%rdi) + movq 96(%rdi), %r9 movq %r11, %r10 # A[15] x A[12] mulxq 96(%rsi), %rax, %rcx @@ -5646,21 +5653,21 @@ _sp_2048_sqr_avx2_16: mulxq 104(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r8, 216(%rdi) - movq %r9, 224(%rdi) + movq %r8, 88(%rdi) + movq %r9, 96(%rdi) movq %r11, %r8 # A[15] x A[14] mulxq 112(%rsi), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r10, 232(%rdi) + movq %r10, 104(%rdi) # Carry adcxq %r12, %r8 movq %r11, %r12 adcxq %r11, %r12 adoxq %r11, %r12 - movq %r8, 240(%rdi) - movq %r12, 248(%rdi) + movq %r8, 112(%rdi) + movq %r12, 120(%rdi) # Double and Add in A[i] x A[i] movq 8(%rbp), %r9 # A[0] x A[0] @@ -5739,8 +5746,8 @@ _sp_2048_sqr_avx2_16: adoxq %rbx, %rbx adcxq %rax, %r15 adcxq %rcx, %rbx - movq 128(%rdi), %r8 - movq 136(%rdi), %r9 + movq (%rdi), %r8 + movq 8(%rdi), %r9 # A[8] x A[8] movq 64(%rsi), %rdx mulxq %rdx, %rax, %rcx @@ -5748,10 +5755,10 @@ _sp_2048_sqr_avx2_16: adoxq %r9, %r9 adcxq %rax, %r8 adcxq %rcx, %r9 - movq %r8, 128(%rdi) - movq %r9, 136(%rdi) - movq 144(%rdi), %r8 - movq 152(%rdi), %r9 + movq %r8, (%rdi) + movq %r9, 8(%rdi) + movq 16(%rdi), %r8 + movq 24(%rdi), %r9 # A[9] x A[9] movq 72(%rsi), %rdx mulxq %rdx, %rax, %rcx @@ -5759,10 +5766,10 @@ _sp_2048_sqr_avx2_16: adoxq %r9, %r9 adcxq %rax, %r8 adcxq %rcx, %r9 - movq %r8, 144(%rdi) - movq %r9, 152(%rdi) - movq 160(%rdi), %r8 - movq 168(%rdi), %r9 + movq %r8, 16(%rdi) + movq %r9, 24(%rdi) + movq 32(%rdi), %r8 + movq 40(%rdi), %r9 # A[10] x A[10] movq 80(%rsi), %rdx mulxq %rdx, %rax, %rcx @@ -5770,10 +5777,10 @@ _sp_2048_sqr_avx2_16: adoxq %r9, %r9 adcxq %rax, %r8 adcxq %rcx, %r9 - movq %r8, 160(%rdi) - movq %r9, 168(%rdi) - movq 176(%rdi), %r8 - movq 184(%rdi), %r9 + movq %r8, 32(%rdi) + movq %r9, 40(%rdi) + movq 48(%rdi), %r8 + movq 56(%rdi), %r9 # A[11] x A[11] movq 88(%rsi), %rdx mulxq %rdx, %rax, %rcx @@ -5781,10 +5788,10 @@ _sp_2048_sqr_avx2_16: adoxq %r9, %r9 adcxq %rax, %r8 adcxq %rcx, %r9 - movq %r8, 176(%rdi) - movq %r9, 184(%rdi) - movq 192(%rdi), %r8 - movq 200(%rdi), %r9 + movq %r8, 48(%rdi) + movq %r9, 56(%rdi) + movq 64(%rdi), %r8 + movq 72(%rdi), %r9 # A[12] x A[12] movq 96(%rsi), %rdx mulxq %rdx, %rax, %rcx @@ -5792,10 +5799,10 @@ _sp_2048_sqr_avx2_16: adoxq %r9, %r9 adcxq %rax, %r8 adcxq %rcx, %r9 - movq %r8, 192(%rdi) - movq %r9, 200(%rdi) - movq 208(%rdi), %r8 - movq 216(%rdi), %r9 + movq %r8, 64(%rdi) + movq %r9, 72(%rdi) + movq 80(%rdi), %r8 + movq 88(%rdi), %r9 # A[13] x A[13] movq 104(%rsi), %rdx mulxq %rdx, %rax, %rcx @@ -5803,10 +5810,10 @@ _sp_2048_sqr_avx2_16: adoxq %r9, %r9 adcxq %rax, %r8 adcxq %rcx, %r9 - movq %r8, 208(%rdi) - movq %r9, 216(%rdi) - movq 224(%rdi), %r8 - movq 232(%rdi), %r9 + movq %r8, 80(%rdi) + movq %r9, 88(%rdi) + movq 96(%rdi), %r8 + movq 104(%rdi), %r9 # A[14] x A[14] movq 112(%rsi), %rdx mulxq %rdx, %rax, %rcx @@ -5814,10 +5821,10 @@ _sp_2048_sqr_avx2_16: adoxq %r9, %r9 adcxq %rax, %r8 adcxq %rcx, %r9 - movq %r8, 224(%rdi) - movq %r9, 232(%rdi) - movq 240(%rdi), %r8 - movq 248(%rdi), %r9 + movq %r8, 96(%rdi) + movq %r9, 104(%rdi) + movq 112(%rdi), %r8 + movq 120(%rdi), %r9 # A[15] x A[15] movq 120(%rsi), %rdx mulxq %rdx, %rax, %rcx @@ -5825,12 +5832,13 @@ _sp_2048_sqr_avx2_16: adoxq %r9, %r9 adcxq %rax, %r8 adcxq %rcx, %r9 - movq %r8, 240(%rdi) - movq %r9, 248(%rdi) - movq %r13, 96(%rdi) - movq %r14, 104(%rdi) - movq %r15, 112(%rdi) - movq %rbx, 120(%rdi) + movq %r8, 112(%rdi) + movq %r9, 120(%rdi) + movq %r13, -32(%rdi) + movq %r14, -24(%rdi) + movq %r15, -16(%rdi) + movq %rbx, -8(%rdi) + subq $0x80, %rdi cmpq %rdi, %rsi jne L_end_2048_sqr_avx2_16 vmovdqu (%rbp), %xmm0 @@ -6331,6 +6339,11 @@ _sp_2048_mul_32: #else callq _sp_2048_mul_16 #endif /* __APPLE__ */ +#ifdef _WIN64 + movq 784(%rsp), %rdx + movq 776(%rsp), %rsi + movq 768(%rsp), %rdi +#endif /* _WIN64 */ movq 792(%rsp), %r13 movq 800(%rsp), %r14 movq 768(%rsp), %r15 @@ -7059,6 +7072,10 @@ _sp_2048_sqr_32: #else callq _sp_2048_sqr_16 #endif /* __APPLE__ */ +#ifdef _WIN64 + movq 648(%rsp), %rsi + movq 640(%rsp), %rdi +#endif /* _WIN64 */ movq 656(%rsp), %r10 leaq 512(%rsp), %r8 movq %r10, %rcx @@ -7560,6 +7577,7 @@ _sp_2048_sqr_32: #ifndef __APPLE__ .size sp_2048_sqr_32,.-sp_2048_sqr_32 #endif /* __APPLE__ */ +#ifdef HAVE_INTEL_AVX2 /* Multiply a and b into r. (r = a * b) * * r A single precision integer. @@ -7720,6 +7738,11 @@ _sp_2048_mul_avx2_32: #else callq _sp_2048_mul_avx2_16 #endif /* __APPLE__ */ +#ifdef _WIN64 + movq 784(%rsp), %rdx + movq 776(%rsp), %rsi + movq 768(%rsp), %rdi +#endif /* _WIN64 */ movq 792(%rsp), %r13 movq 800(%rsp), %r14 movq 768(%rsp), %r15 @@ -8233,6 +8256,8 @@ _sp_2048_mul_avx2_32: #ifndef __APPLE__ .size sp_2048_mul_avx2_32,.-sp_2048_mul_avx2_32 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +#ifdef HAVE_INTEL_AVX2 /* Square a and put result in r. (r = a * a) * * r A single precision integer. @@ -8329,6 +8354,10 @@ _sp_2048_sqr_avx2_32: #else callq _sp_2048_sqr_avx2_16 #endif /* __APPLE__ */ +#ifdef _WIN64 + movq 648(%rsp), %rsi + movq 640(%rsp), %rdi +#endif /* _WIN64 */ movq 656(%rsp), %r10 leaq 512(%rsp), %r8 movq %r10, %rcx @@ -8798,6 +8827,78 @@ _sp_2048_sqr_avx2_32: #ifndef __APPLE__ .size sp_2048_sqr_avx2_32,.-sp_2048_sqr_avx2_32 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +/* Sub b from a into a. (a -= b) + * + * a A single precision integer and result. + * b A single precision integer. + */ +#ifndef __APPLE__ +.text +.globl sp_2048_sub_in_place_16 +.type sp_2048_sub_in_place_16,@function +.align 16 +sp_2048_sub_in_place_16: +#else +.section __TEXT,__text +.globl _sp_2048_sub_in_place_16 +.p2align 4 +_sp_2048_sub_in_place_16: +#endif /* __APPLE__ */ + movq (%rdi), %rdx + xorq %rax, %rax + subq (%rsi), %rdx + movq 8(%rdi), %rcx + movq %rdx, (%rdi) + sbbq 8(%rsi), %rcx + movq 16(%rdi), %rdx + movq %rcx, 8(%rdi) + sbbq 16(%rsi), %rdx + movq 24(%rdi), %rcx + movq %rdx, 16(%rdi) + sbbq 24(%rsi), %rcx + movq 32(%rdi), %rdx + movq %rcx, 24(%rdi) + sbbq 32(%rsi), %rdx + movq 40(%rdi), %rcx + movq %rdx, 32(%rdi) + sbbq 40(%rsi), %rcx + movq 48(%rdi), %rdx + movq %rcx, 40(%rdi) + sbbq 48(%rsi), %rdx + movq 56(%rdi), %rcx + movq %rdx, 48(%rdi) + sbbq 56(%rsi), %rcx + movq 64(%rdi), %rdx + movq %rcx, 56(%rdi) + sbbq 64(%rsi), %rdx + movq 72(%rdi), %rcx + movq %rdx, 64(%rdi) + sbbq 72(%rsi), %rcx + movq 80(%rdi), %rdx + movq %rcx, 72(%rdi) + sbbq 80(%rsi), %rdx + movq 88(%rdi), %rcx + movq %rdx, 80(%rdi) + sbbq 88(%rsi), %rcx + movq 96(%rdi), %rdx + movq %rcx, 88(%rdi) + sbbq 96(%rsi), %rdx + movq 104(%rdi), %rcx + movq %rdx, 96(%rdi) + sbbq 104(%rsi), %rcx + movq 112(%rdi), %rdx + movq %rcx, 104(%rdi) + sbbq 112(%rsi), %rdx + movq 120(%rdi), %rcx + movq %rdx, 112(%rdi) + sbbq 120(%rsi), %rcx + movq %rcx, 120(%rdi) + sbbq $0x00, %rax + repz retq +#ifndef __APPLE__ +.size sp_2048_sub_in_place_16,.-sp_2048_sub_in_place_16 +#endif /* __APPLE__ */ /* Mul a by digit b into r. (r = a * b) * * r A single precision integer. @@ -9075,77 +9176,6 @@ _sp_2048_mul_d_32: #ifndef __APPLE__ .size sp_2048_mul_d_32,.-sp_2048_mul_d_32 #endif /* __APPLE__ */ -/* Sub b from a into a. (a -= b) - * - * a A single precision integer and result. - * b A single precision integer. - */ -#ifndef __APPLE__ -.text -.globl sp_2048_sub_in_place_16 -.type sp_2048_sub_in_place_16,@function -.align 16 -sp_2048_sub_in_place_16: -#else -.section __TEXT,__text -.globl _sp_2048_sub_in_place_16 -.p2align 4 -_sp_2048_sub_in_place_16: -#endif /* __APPLE__ */ - movq (%rdi), %rdx - xorq %rax, %rax - subq (%rsi), %rdx - movq 8(%rdi), %rcx - movq %rdx, (%rdi) - sbbq 8(%rsi), %rcx - movq 16(%rdi), %rdx - movq %rcx, 8(%rdi) - sbbq 16(%rsi), %rdx - movq 24(%rdi), %rcx - movq %rdx, 16(%rdi) - sbbq 24(%rsi), %rcx - movq 32(%rdi), %rdx - movq %rcx, 24(%rdi) - sbbq 32(%rsi), %rdx - movq 40(%rdi), %rcx - movq %rdx, 32(%rdi) - sbbq 40(%rsi), %rcx - movq 48(%rdi), %rdx - movq %rcx, 40(%rdi) - sbbq 48(%rsi), %rdx - movq 56(%rdi), %rcx - movq %rdx, 48(%rdi) - sbbq 56(%rsi), %rcx - movq 64(%rdi), %rdx - movq %rcx, 56(%rdi) - sbbq 64(%rsi), %rdx - movq 72(%rdi), %rcx - movq %rdx, 64(%rdi) - sbbq 72(%rsi), %rcx - movq 80(%rdi), %rdx - movq %rcx, 72(%rdi) - sbbq 80(%rsi), %rdx - movq 88(%rdi), %rcx - movq %rdx, 80(%rdi) - sbbq 88(%rsi), %rcx - movq 96(%rdi), %rdx - movq %rcx, 88(%rdi) - sbbq 96(%rsi), %rdx - movq 104(%rdi), %rcx - movq %rdx, 96(%rdi) - sbbq 104(%rsi), %rcx - movq 112(%rdi), %rdx - movq %rcx, 104(%rdi) - sbbq 112(%rsi), %rdx - movq 120(%rdi), %rcx - movq %rdx, 112(%rdi) - sbbq 120(%rsi), %rcx - movq %rcx, 120(%rdi) - sbbq $0x00, %rax - repz retq -#ifndef __APPLE__ -.size sp_2048_sub_in_place_16,.-sp_2048_sub_in_place_16 -#endif /* __APPLE__ */ /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -9314,7 +9344,7 @@ _sp_2048_mont_reduce_16: movq $16, %r8 movq (%rdi), %r13 movq 8(%rdi), %r14 -L_mont_loop_16: +L_2048_mont_loop_16: # mu = a[i] * mp movq %r13, %r11 imulq %rcx, %r11 @@ -9477,12 +9507,17 @@ L_mont_loop_16: # i -= 1 addq $8, %rdi decq %r8 - jnz L_mont_loop_16 + jnz L_2048_mont_loop_16 movq %r13, (%rdi) movq %r14, 8(%rdi) negq %r15 +#ifdef _WIN64 + movq %rsi, %rdx + movq %r15, %rcx +#else movq %r15, %rcx movq %rsi, %rdx +#endif /* _WIN64 */ movq %rdi, %rsi movq %rdi, %rdi subq $0x80, %rdi @@ -9499,6 +9534,7 @@ L_mont_loop_16: #ifndef __APPLE__ .size sp_2048_mont_reduce_16,.-sp_2048_mont_reduce_16 #endif /* __APPLE__ */ +#ifdef HAVE_INTEL_AVX2 /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -9605,6 +9641,7 @@ _sp_2048_cond_sub_avx2_16: #ifndef __APPLE__ .size sp_2048_cond_sub_avx2_16,.-sp_2048_cond_sub_avx2_16 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ /* Mul a by digit b into r. (r = a * b) * * r A single precision integer. @@ -9783,86 +9820,86 @@ _sp_2048_mul_d_avx2_16: mulxq 8(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 8(%rdi) adoxq %r8, %r9 + movq %r10, 8(%rdi) # A[2] * B mulxq 16(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 16(%rdi) adoxq %r8, %r10 + movq %r9, 16(%rdi) # A[3] * B mulxq 24(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 24(%rdi) adoxq %r8, %r9 + movq %r10, 24(%rdi) # A[4] * B mulxq 32(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 32(%rdi) adoxq %r8, %r10 + movq %r9, 32(%rdi) # A[5] * B mulxq 40(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 40(%rdi) adoxq %r8, %r9 + movq %r10, 40(%rdi) # A[6] * B mulxq 48(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 48(%rdi) adoxq %r8, %r10 + movq %r9, 48(%rdi) # A[7] * B mulxq 56(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 56(%rdi) adoxq %r8, %r9 + movq %r10, 56(%rdi) # A[8] * B mulxq 64(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 64(%rdi) adoxq %r8, %r10 + movq %r9, 64(%rdi) # A[9] * B mulxq 72(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 72(%rdi) adoxq %r8, %r9 + movq %r10, 72(%rdi) # A[10] * B mulxq 80(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 80(%rdi) adoxq %r8, %r10 + movq %r9, 80(%rdi) # A[11] * B mulxq 88(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 88(%rdi) adoxq %r8, %r9 + movq %r10, 88(%rdi) # A[12] * B mulxq 96(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 96(%rdi) adoxq %r8, %r10 + movq %r9, 96(%rdi) # A[13] * B mulxq 104(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 104(%rdi) adoxq %r8, %r9 + movq %r10, 104(%rdi) # A[14] * B mulxq 112(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 112(%rdi) adoxq %r8, %r10 + movq %r9, 112(%rdi) # A[15] * B mulxq 120(%rsi), %rcx, %r8 movq %r11, %r9 @@ -9876,6 +9913,35 @@ _sp_2048_mul_d_avx2_16: .size sp_2048_mul_d_avx2_16,.-sp_2048_mul_d_avx2_16 #endif /* __APPLE__ */ #endif /* HAVE_INTEL_AVX2 */ +#ifdef _WIN64 +/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) + * + * d1 The high order half of the number to divide. + * d0 The low order half of the number to divide. + * div The dividend. + * returns the result of the division. + */ +#ifndef __APPLE__ +.text +.globl div_2048_word_asm_16 +.type div_2048_word_asm_16,@function +.align 16 +div_2048_word_asm_16: +#else +.section __TEXT,__text +.globl _div_2048_word_asm_16 +.p2align 4 +_div_2048_word_asm_16: +#endif /* __APPLE__ */ + movq %rdx, %rcx + movq %rsi, %rax + movq %rdi, %rdx + divq %rcx + repz retq +#ifndef __APPLE__ +.size div_2048_word_asm_16,.-div_2048_word_asm_16 +#endif /* __APPLE__ */ +#endif /* _WIN64 */ /* Compare a with b in constant time. * * a A single precision integer. @@ -10054,14 +10120,20 @@ _sp_2048_mont_reduce_avx2_16: pushq %r12 pushq %r13 pushq %r14 + pushq %r15 + pushq %rbx + pushq %rbp movq %rdx, %r8 - xorq %r14, %r14 + xorq %rbp, %rbp # i = 16 movq $16, %r9 movq (%rdi), %r13 + movq 8(%rdi), %r14 + movq 16(%rdi), %r15 + movq 24(%rdi), %rbx addq $0x40, %rdi - xorq %r12, %r12 -L_mont_loop_avx2_16: + xorq %rbp, %rbp +L_2048_mont_loop_avx2_16: # mu = a[i] * mp movq %r13, %rdx movq %r13, %r10 @@ -10069,32 +10141,29 @@ L_mont_loop_avx2_16: xorq %r12, %r12 # a[i+0] += m[0] * mu mulxq (%rsi), %rax, %rcx - movq -56(%rdi), %r13 + movq %r14, %r13 adcxq %rax, %r10 adoxq %rcx, %r13 # a[i+1] += m[1] * mu mulxq 8(%rsi), %rax, %rcx - movq -48(%rdi), %r10 + movq %r15, %r14 adcxq %rax, %r13 - adoxq %rcx, %r10 + adoxq %rcx, %r14 # a[i+2] += m[2] * mu mulxq 16(%rsi), %rax, %rcx - movq -40(%rdi), %r11 - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, -48(%rdi) + movq %rbx, %r15 + adcxq %rax, %r14 + adoxq %rcx, %r15 # a[i+3] += m[3] * mu mulxq 24(%rsi), %rax, %rcx - movq -32(%rdi), %r10 - adcxq %rax, %r11 - adoxq %rcx, %r10 - movq %r11, -40(%rdi) + movq -32(%rdi), %rbx + adcxq %rax, %r15 + adoxq %rcx, %rbx # a[i+4] += m[4] * mu mulxq 32(%rsi), %rax, %rcx movq -24(%rdi), %r11 - adcxq %rax, %r10 + adcxq %rax, %rbx adoxq %rcx, %r11 - movq %r10, -32(%rdi) # a[i+5] += m[5] * mu mulxq 40(%rsi), %rax, %rcx movq -16(%rdi), %r10 @@ -10161,11 +10230,11 @@ L_mont_loop_avx2_16: adcxq %rax, %r11 adoxq %rcx, %r10 movq %r11, 56(%rdi) - adcxq %r14, %r10 + adcxq %rbp, %r10 + movq %r12, %rbp movq %r10, 64(%rdi) - movq %r12, %r14 - adoxq %r12, %r14 - adcxq %r12, %r14 + adoxq %r12, %rbp + adcxq %r12, %rbp # mu = a[i] * mp movq %r13, %rdx movq %r13, %r10 @@ -10173,32 +10242,29 @@ L_mont_loop_avx2_16: xorq %r12, %r12 # a[i+0] += m[0] * mu mulxq (%rsi), %rax, %rcx - movq -48(%rdi), %r13 + movq %r14, %r13 adcxq %rax, %r10 adoxq %rcx, %r13 # a[i+1] += m[1] * mu mulxq 8(%rsi), %rax, %rcx - movq -40(%rdi), %r10 + movq %r15, %r14 adcxq %rax, %r13 - adoxq %rcx, %r10 + adoxq %rcx, %r14 # a[i+2] += m[2] * mu mulxq 16(%rsi), %rax, %rcx - movq -32(%rdi), %r11 - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, -40(%rdi) + movq %rbx, %r15 + adcxq %rax, %r14 + adoxq %rcx, %r15 # a[i+3] += m[3] * mu mulxq 24(%rsi), %rax, %rcx - movq -24(%rdi), %r10 - adcxq %rax, %r11 - adoxq %rcx, %r10 - movq %r11, -32(%rdi) + movq -24(%rdi), %rbx + adcxq %rax, %r15 + adoxq %rcx, %rbx # a[i+4] += m[4] * mu mulxq 32(%rsi), %rax, %rcx movq -16(%rdi), %r11 - adcxq %rax, %r10 + adcxq %rax, %rbx adoxq %rcx, %r11 - movq %r10, -24(%rdi) # a[i+5] += m[5] * mu mulxq 40(%rsi), %rax, %rcx movq -8(%rdi), %r10 @@ -10265,100 +10331,103 @@ L_mont_loop_avx2_16: adcxq %rax, %r11 adoxq %rcx, %r10 movq %r11, 64(%rdi) - adcxq %r14, %r10 + adcxq %rbp, %r10 + movq %r12, %rbp movq %r10, 72(%rdi) - movq %r12, %r14 - adoxq %r12, %r14 - adcxq %r12, %r14 + adoxq %r12, %rbp + adcxq %r12, %rbp # a += 2 addq $16, %rdi # i -= 2 subq $2, %r9 - jnz L_mont_loop_avx2_16 + jnz L_2048_mont_loop_avx2_16 subq $0x40, %rdi - negq %r14 + negq %rbp movq %rdi, %r8 subq $0x80, %rdi movq (%rsi), %rcx movq %r13, %rdx - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx subq %rcx, %rdx movq 8(%rsi), %rcx - movq 8(%r8), %rax - pextq %r14, %rcx, %rcx + movq %r14, %rax + pextq %rbp, %rcx, %rcx movq %rdx, (%rdi) sbbq %rcx, %rax movq 16(%rsi), %rdx - movq 16(%r8), %rcx - pextq %r14, %rdx, %rdx + movq %r15, %rcx + pextq %rbp, %rdx, %rdx movq %rax, 8(%rdi) sbbq %rdx, %rcx movq 24(%rsi), %rax - movq 24(%r8), %rdx - pextq %r14, %rax, %rax + movq %rbx, %rdx + pextq %rbp, %rax, %rax movq %rcx, 16(%rdi) sbbq %rax, %rdx movq 32(%rsi), %rcx movq 32(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 24(%rdi) sbbq %rcx, %rax movq 40(%rsi), %rdx movq 40(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 32(%rdi) sbbq %rdx, %rcx movq 48(%rsi), %rax movq 48(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 40(%rdi) sbbq %rax, %rdx movq 56(%rsi), %rcx movq 56(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 48(%rdi) sbbq %rcx, %rax movq 64(%rsi), %rdx movq 64(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 56(%rdi) sbbq %rdx, %rcx movq 72(%rsi), %rax movq 72(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 64(%rdi) sbbq %rax, %rdx movq 80(%rsi), %rcx movq 80(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 72(%rdi) sbbq %rcx, %rax movq 88(%rsi), %rdx movq 88(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 80(%rdi) sbbq %rdx, %rcx movq 96(%rsi), %rax movq 96(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 88(%rdi) sbbq %rax, %rdx movq 104(%rsi), %rcx movq 104(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 96(%rdi) sbbq %rcx, %rax movq 112(%rsi), %rdx movq 112(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 104(%rdi) sbbq %rdx, %rcx movq 120(%rsi), %rax movq 120(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 112(%rdi) sbbq %rax, %rdx movq %rdx, 120(%rdi) + popq %rbp + popq %rbx + popq %r15 popq %r14 popq %r13 popq %r12 @@ -10647,7 +10716,7 @@ _sp_2048_mont_reduce_32: movq $32, %r8 movq (%rdi), %r13 movq 8(%rdi), %r14 -L_mont_loop_32: +L_2048_mont_loop_32: # mu = a[i] * mp movq %r13, %r11 imulq %rcx, %r11 @@ -10970,12 +11039,17 @@ L_mont_loop_32: # i -= 1 addq $8, %rdi decq %r8 - jnz L_mont_loop_32 + jnz L_2048_mont_loop_32 movq %r13, (%rdi) movq %r14, 8(%rdi) negq %r15 +#ifdef _WIN64 + movq %rsi, %rdx + movq %r15, %rcx +#else movq %r15, %rcx movq %rsi, %rdx +#endif /* _WIN64 */ movq %rdi, %rsi movq %rdi, %rdi subq $0x100, %rdi @@ -10992,6 +11066,7 @@ L_mont_loop_32: #ifndef __APPLE__ .size sp_2048_mont_reduce_32,.-sp_2048_mont_reduce_32 #endif /* __APPLE__ */ +#ifdef HAVE_INTEL_AVX2 /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -11178,6 +11253,7 @@ _sp_2048_cond_sub_avx2_32: #ifndef __APPLE__ .size sp_2048_cond_sub_avx2_32,.-sp_2048_cond_sub_avx2_32 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ #ifdef HAVE_INTEL_AVX2 /* Mul a by digit b into r. (r = a * b) * @@ -11207,182 +11283,182 @@ _sp_2048_mul_d_avx2_32: mulxq 8(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 8(%rdi) adoxq %r8, %r9 + movq %r10, 8(%rdi) # A[2] * B mulxq 16(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 16(%rdi) adoxq %r8, %r10 + movq %r9, 16(%rdi) # A[3] * B mulxq 24(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 24(%rdi) adoxq %r8, %r9 + movq %r10, 24(%rdi) # A[4] * B mulxq 32(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 32(%rdi) adoxq %r8, %r10 + movq %r9, 32(%rdi) # A[5] * B mulxq 40(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 40(%rdi) adoxq %r8, %r9 + movq %r10, 40(%rdi) # A[6] * B mulxq 48(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 48(%rdi) adoxq %r8, %r10 + movq %r9, 48(%rdi) # A[7] * B mulxq 56(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 56(%rdi) adoxq %r8, %r9 + movq %r10, 56(%rdi) # A[8] * B mulxq 64(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 64(%rdi) adoxq %r8, %r10 + movq %r9, 64(%rdi) # A[9] * B mulxq 72(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 72(%rdi) adoxq %r8, %r9 + movq %r10, 72(%rdi) # A[10] * B mulxq 80(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 80(%rdi) adoxq %r8, %r10 + movq %r9, 80(%rdi) # A[11] * B mulxq 88(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 88(%rdi) adoxq %r8, %r9 + movq %r10, 88(%rdi) # A[12] * B mulxq 96(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 96(%rdi) adoxq %r8, %r10 + movq %r9, 96(%rdi) # A[13] * B mulxq 104(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 104(%rdi) adoxq %r8, %r9 + movq %r10, 104(%rdi) # A[14] * B mulxq 112(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 112(%rdi) adoxq %r8, %r10 + movq %r9, 112(%rdi) # A[15] * B mulxq 120(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 120(%rdi) adoxq %r8, %r9 + movq %r10, 120(%rdi) # A[16] * B mulxq 128(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 128(%rdi) adoxq %r8, %r10 + movq %r9, 128(%rdi) # A[17] * B mulxq 136(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 136(%rdi) adoxq %r8, %r9 + movq %r10, 136(%rdi) # A[18] * B mulxq 144(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 144(%rdi) adoxq %r8, %r10 + movq %r9, 144(%rdi) # A[19] * B mulxq 152(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 152(%rdi) adoxq %r8, %r9 + movq %r10, 152(%rdi) # A[20] * B mulxq 160(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 160(%rdi) adoxq %r8, %r10 + movq %r9, 160(%rdi) # A[21] * B mulxq 168(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 168(%rdi) adoxq %r8, %r9 + movq %r10, 168(%rdi) # A[22] * B mulxq 176(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 176(%rdi) adoxq %r8, %r10 + movq %r9, 176(%rdi) # A[23] * B mulxq 184(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 184(%rdi) adoxq %r8, %r9 + movq %r10, 184(%rdi) # A[24] * B mulxq 192(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 192(%rdi) adoxq %r8, %r10 + movq %r9, 192(%rdi) # A[25] * B mulxq 200(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 200(%rdi) adoxq %r8, %r9 + movq %r10, 200(%rdi) # A[26] * B mulxq 208(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 208(%rdi) adoxq %r8, %r10 + movq %r9, 208(%rdi) # A[27] * B mulxq 216(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 216(%rdi) adoxq %r8, %r9 + movq %r10, 216(%rdi) # A[28] * B mulxq 224(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 224(%rdi) adoxq %r8, %r10 + movq %r9, 224(%rdi) # A[29] * B mulxq 232(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 232(%rdi) adoxq %r8, %r9 + movq %r10, 232(%rdi) # A[30] * B mulxq 240(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 240(%rdi) adoxq %r8, %r10 + movq %r9, 240(%rdi) # A[31] * B mulxq 248(%rsi), %rcx, %r8 movq %r11, %r9 @@ -11396,6 +11472,35 @@ _sp_2048_mul_d_avx2_32: .size sp_2048_mul_d_avx2_32,.-sp_2048_mul_d_avx2_32 #endif /* __APPLE__ */ #endif /* HAVE_INTEL_AVX2 */ +#ifdef _WIN64 +/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) + * + * d1 The high order half of the number to divide. + * d0 The low order half of the number to divide. + * div The dividend. + * returns the result of the division. + */ +#ifndef __APPLE__ +.text +.globl div_2048_word_asm_32 +.type div_2048_word_asm_32,@function +.align 16 +div_2048_word_asm_32: +#else +.section __TEXT,__text +.globl _div_2048_word_asm_32 +.p2align 4 +_div_2048_word_asm_32: +#endif /* __APPLE__ */ + movq %rdx, %rcx + movq %rsi, %rax + movq %rdi, %rdx + divq %rcx + repz retq +#ifndef __APPLE__ +.size div_2048_word_asm_32,.-div_2048_word_asm_32 +#endif /* __APPLE__ */ +#endif /* _WIN64 */ /* Compare a with b in constant time. * * a A single precision integer. @@ -11822,14 +11927,20 @@ _sp_2048_mont_reduce_avx2_32: pushq %r12 pushq %r13 pushq %r14 + pushq %r15 + pushq %rbx + pushq %rbp movq %rdx, %r8 - xorq %r14, %r14 + xorq %rbp, %rbp # i = 32 movq $32, %r9 movq (%rdi), %r13 + movq 8(%rdi), %r14 + movq 16(%rdi), %r15 + movq 24(%rdi), %rbx addq $0x80, %rdi - xorq %r12, %r12 -L_mont_loop_avx2_32: + xorq %rbp, %rbp +L_2048_mont_loop_avx2_32: # mu = a[i] * mp movq %r13, %rdx movq %r13, %r10 @@ -11837,32 +11948,29 @@ L_mont_loop_avx2_32: xorq %r12, %r12 # a[i+0] += m[0] * mu mulxq (%rsi), %rax, %rcx - movq -120(%rdi), %r13 + movq %r14, %r13 adcxq %rax, %r10 adoxq %rcx, %r13 # a[i+1] += m[1] * mu mulxq 8(%rsi), %rax, %rcx - movq -112(%rdi), %r10 + movq %r15, %r14 adcxq %rax, %r13 - adoxq %rcx, %r10 + adoxq %rcx, %r14 # a[i+2] += m[2] * mu mulxq 16(%rsi), %rax, %rcx - movq -104(%rdi), %r11 - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, -112(%rdi) + movq %rbx, %r15 + adcxq %rax, %r14 + adoxq %rcx, %r15 # a[i+3] += m[3] * mu mulxq 24(%rsi), %rax, %rcx - movq -96(%rdi), %r10 - adcxq %rax, %r11 - adoxq %rcx, %r10 - movq %r11, -104(%rdi) + movq -96(%rdi), %rbx + adcxq %rax, %r15 + adoxq %rcx, %rbx # a[i+4] += m[4] * mu mulxq 32(%rsi), %rax, %rcx movq -88(%rdi), %r11 - adcxq %rax, %r10 + adcxq %rax, %rbx adoxq %rcx, %r11 - movq %r10, -96(%rdi) # a[i+5] += m[5] * mu mulxq 40(%rsi), %rax, %rcx movq -80(%rdi), %r10 @@ -12025,180 +12133,183 @@ L_mont_loop_avx2_32: adcxq %rax, %r11 adoxq %rcx, %r10 movq %r11, 120(%rdi) - adcxq %r14, %r10 + adcxq %rbp, %r10 + movq %r12, %rbp movq %r10, 128(%rdi) - movq %r12, %r14 - adoxq %r12, %r14 - adcxq %r12, %r14 + adoxq %r12, %rbp + adcxq %r12, %rbp # a += 1 addq $8, %rdi # i -= 1 subq $0x01, %r9 - jnz L_mont_loop_avx2_32 + jnz L_2048_mont_loop_avx2_32 subq $0x80, %rdi - negq %r14 + negq %rbp movq %rdi, %r8 subq $0x100, %rdi movq (%rsi), %rcx movq %r13, %rdx - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx subq %rcx, %rdx movq 8(%rsi), %rcx - movq 8(%r8), %rax - pextq %r14, %rcx, %rcx + movq %r14, %rax + pextq %rbp, %rcx, %rcx movq %rdx, (%rdi) sbbq %rcx, %rax movq 16(%rsi), %rdx - movq 16(%r8), %rcx - pextq %r14, %rdx, %rdx + movq %r15, %rcx + pextq %rbp, %rdx, %rdx movq %rax, 8(%rdi) sbbq %rdx, %rcx movq 24(%rsi), %rax - movq 24(%r8), %rdx - pextq %r14, %rax, %rax + movq %rbx, %rdx + pextq %rbp, %rax, %rax movq %rcx, 16(%rdi) sbbq %rax, %rdx movq 32(%rsi), %rcx movq 32(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 24(%rdi) sbbq %rcx, %rax movq 40(%rsi), %rdx movq 40(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 32(%rdi) sbbq %rdx, %rcx movq 48(%rsi), %rax movq 48(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 40(%rdi) sbbq %rax, %rdx movq 56(%rsi), %rcx movq 56(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 48(%rdi) sbbq %rcx, %rax movq 64(%rsi), %rdx movq 64(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 56(%rdi) sbbq %rdx, %rcx movq 72(%rsi), %rax movq 72(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 64(%rdi) sbbq %rax, %rdx movq 80(%rsi), %rcx movq 80(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 72(%rdi) sbbq %rcx, %rax movq 88(%rsi), %rdx movq 88(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 80(%rdi) sbbq %rdx, %rcx movq 96(%rsi), %rax movq 96(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 88(%rdi) sbbq %rax, %rdx movq 104(%rsi), %rcx movq 104(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 96(%rdi) sbbq %rcx, %rax movq 112(%rsi), %rdx movq 112(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 104(%rdi) sbbq %rdx, %rcx movq 120(%rsi), %rax movq 120(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 112(%rdi) sbbq %rax, %rdx movq 128(%rsi), %rcx movq 128(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 120(%rdi) sbbq %rcx, %rax movq 136(%rsi), %rdx movq 136(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 128(%rdi) sbbq %rdx, %rcx movq 144(%rsi), %rax movq 144(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 136(%rdi) sbbq %rax, %rdx movq 152(%rsi), %rcx movq 152(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 144(%rdi) sbbq %rcx, %rax movq 160(%rsi), %rdx movq 160(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 152(%rdi) sbbq %rdx, %rcx movq 168(%rsi), %rax movq 168(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 160(%rdi) sbbq %rax, %rdx movq 176(%rsi), %rcx movq 176(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 168(%rdi) sbbq %rcx, %rax movq 184(%rsi), %rdx movq 184(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 176(%rdi) sbbq %rdx, %rcx movq 192(%rsi), %rax movq 192(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 184(%rdi) sbbq %rax, %rdx movq 200(%rsi), %rcx movq 200(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 192(%rdi) sbbq %rcx, %rax movq 208(%rsi), %rdx movq 208(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 200(%rdi) sbbq %rdx, %rcx movq 216(%rsi), %rax movq 216(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 208(%rdi) sbbq %rax, %rdx movq 224(%rsi), %rcx movq 224(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 216(%rdi) sbbq %rcx, %rax movq 232(%rsi), %rdx movq 232(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 224(%rdi) sbbq %rdx, %rcx movq 240(%rsi), %rax movq 240(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 232(%rdi) sbbq %rax, %rdx movq 248(%rsi), %rcx movq 248(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 240(%rdi) sbbq %rcx, %rax movq %rax, 248(%rdi) + popq %rbp + popq %rbx + popq %r15 popq %r14 popq %r13 popq %r12 @@ -12347,6 +12458,7 @@ _sp_2048_cond_add_16: #ifndef __APPLE__ .size sp_2048_cond_add_16,.-sp_2048_cond_add_16 #endif /* __APPLE__ */ +#ifdef HAVE_INTEL_AVX2 /* Conditionally add a and b using the mask m. * m is -1 to add and 0 when not. * @@ -12453,6 +12565,7 @@ _sp_2048_cond_add_avx2_16: #ifndef __APPLE__ .size sp_2048_cond_add_avx2_16,.-sp_2048_cond_add_avx2_16 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ /* Shift number left by n bit. (r = a << n) * * r Result of left shift by n. @@ -12471,107 +12584,116 @@ sp_2048_lshift_32: .p2align 4 _sp_2048_lshift_32: #endif /* __APPLE__ */ + pushq %r12 + pushq %r13 + movq %rdi, %r9 movb %dl, %cl - movq $0x00, %r10 - movq 216(%rsi), %r11 - movq 224(%rsi), %rdx - movq 232(%rsi), %rax - movq 240(%rsi), %r8 - movq 248(%rsi), %r9 - shldq %cl, %r9, %r10 - shldq %cl, %r8, %r9 + movq %rsi, %rdx + movq $0x00, %r12 + movq 216(%rdx), %r13 + movq 224(%rdx), %rax + movq 232(%rdx), %r8 + movq 240(%rdx), %r10 + movq 248(%rdx), %r11 + shldq %cl, %r11, %r12 + shldq %cl, %r10, %r11 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r11, %rdx - movq %rdx, 224(%rdi) - movq %rax, 232(%rdi) - movq %r8, 240(%rdi) - movq %r9, 248(%rdi) - movq %r10, 256(%rdi) - movq 184(%rsi), %r9 - movq 192(%rsi), %rdx - movq 200(%rsi), %rax - movq 208(%rsi), %r8 - shldq %cl, %r8, %r11 + shldq %cl, %r13, %rax + movq %rax, 224(%r9) + movq %r8, 232(%r9) + movq %r10, 240(%r9) + movq %r11, 248(%r9) + movq %r12, 256(%r9) + movq 184(%rdx), %r11 + movq 192(%rdx), %rax + movq 200(%rdx), %r8 + movq 208(%rdx), %r10 + shldq %cl, %r10, %r13 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r9, %rdx - movq %rdx, 192(%rdi) - movq %rax, 200(%rdi) - movq %r8, 208(%rdi) - movq %r11, 216(%rdi) - movq 152(%rsi), %r11 - movq 160(%rsi), %rdx - movq 168(%rsi), %rax - movq 176(%rsi), %r8 - shldq %cl, %r8, %r9 + shldq %cl, %r11, %rax + movq %rax, 192(%r9) + movq %r8, 200(%r9) + movq %r10, 208(%r9) + movq %r13, 216(%r9) + movq 152(%rdx), %r13 + movq 160(%rdx), %rax + movq 168(%rdx), %r8 + movq 176(%rdx), %r10 + shldq %cl, %r10, %r11 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r11, %rdx - movq %rdx, 160(%rdi) - movq %rax, 168(%rdi) - movq %r8, 176(%rdi) - movq %r9, 184(%rdi) - movq 120(%rsi), %r9 - movq 128(%rsi), %rdx - movq 136(%rsi), %rax - movq 144(%rsi), %r8 - shldq %cl, %r8, %r11 + shldq %cl, %r13, %rax + movq %rax, 160(%r9) + movq %r8, 168(%r9) + movq %r10, 176(%r9) + movq %r11, 184(%r9) + movq 120(%rdx), %r11 + movq 128(%rdx), %rax + movq 136(%rdx), %r8 + movq 144(%rdx), %r10 + shldq %cl, %r10, %r13 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r9, %rdx - movq %rdx, 128(%rdi) - movq %rax, 136(%rdi) - movq %r8, 144(%rdi) - movq %r11, 152(%rdi) - movq 88(%rsi), %r11 - movq 96(%rsi), %rdx - movq 104(%rsi), %rax - movq 112(%rsi), %r8 - shldq %cl, %r8, %r9 + shldq %cl, %r11, %rax + movq %rax, 128(%r9) + movq %r8, 136(%r9) + movq %r10, 144(%r9) + movq %r13, 152(%r9) + movq 88(%rdx), %r13 + movq 96(%rdx), %rax + movq 104(%rdx), %r8 + movq 112(%rdx), %r10 + shldq %cl, %r10, %r11 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r11, %rdx - movq %rdx, 96(%rdi) - movq %rax, 104(%rdi) - movq %r8, 112(%rdi) - movq %r9, 120(%rdi) - movq 56(%rsi), %r9 - movq 64(%rsi), %rdx - movq 72(%rsi), %rax - movq 80(%rsi), %r8 - shldq %cl, %r8, %r11 + shldq %cl, %r13, %rax + movq %rax, 96(%r9) + movq %r8, 104(%r9) + movq %r10, 112(%r9) + movq %r11, 120(%r9) + movq 56(%rdx), %r11 + movq 64(%rdx), %rax + movq 72(%rdx), %r8 + movq 80(%rdx), %r10 + shldq %cl, %r10, %r13 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r9, %rdx - movq %rdx, 64(%rdi) - movq %rax, 72(%rdi) - movq %r8, 80(%rdi) - movq %r11, 88(%rdi) - movq 24(%rsi), %r11 - movq 32(%rsi), %rdx - movq 40(%rsi), %rax - movq 48(%rsi), %r8 - shldq %cl, %r8, %r9 + shldq %cl, %r11, %rax + movq %rax, 64(%r9) + movq %r8, 72(%r9) + movq %r10, 80(%r9) + movq %r13, 88(%r9) + movq 24(%rdx), %r13 + movq 32(%rdx), %rax + movq 40(%rdx), %r8 + movq 48(%rdx), %r10 + shldq %cl, %r10, %r11 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r11, %rdx - movq %rdx, 32(%rdi) - movq %rax, 40(%rdi) - movq %r8, 48(%rdi) - movq %r9, 56(%rdi) - movq (%rsi), %rdx - movq 8(%rsi), %rax - movq 16(%rsi), %r8 - shldq %cl, %r8, %r11 + shldq %cl, %r13, %rax + movq %rax, 32(%r9) + movq %r8, 40(%r9) + movq %r10, 48(%r9) + movq %r11, 56(%r9) + movq (%rdx), %rax + movq 8(%rdx), %r8 + movq 16(%rdx), %r10 + shldq %cl, %r10, %r13 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shlq %cl, %rdx - movq %rdx, (%rdi) - movq %rax, 8(%rdi) - movq %r8, 16(%rdi) - movq %r11, 24(%rdi) + shlq %cl, %rax + movq %rax, (%r9) + movq %r8, 8(%r9) + movq %r10, 16(%r9) + movq %r13, 24(%r9) + popq %r13 + popq %r12 repz retq +#ifndef __APPLE__ +.size sp_2048_lshift_32,.-sp_2048_lshift_32 +#endif /* __APPLE__ */ #endif /* !WOLFSSL_SP_NO_2048 */ #endif /* !WOLFSSL_SP_NO_2048 */ #ifndef WOLFSSL_SP_NO_3072 @@ -12670,6 +12792,7 @@ L_3072_from_bin_bswap_zero_end: #ifndef __APPLE__ .size sp_3072_from_bin_bswap,.-sp_3072_from_bin_bswap #endif /* __APPLE__ */ +#ifndef NO_MOVBE_SUPPORT /* Read big endian unsigned byte array into r. * Uses the movbe instruction which is an optional instruction. * @@ -12755,6 +12878,7 @@ L_3072_from_bin_movbe_zero_end: #ifndef __APPLE__ .size sp_3072_from_bin_movbe,.-sp_3072_from_bin_movbe #endif /* __APPLE__ */ +#endif /* !NO_MOVBE_SUPPORT */ /* Write r as big endian to byte array. * Fixed length number of bytes written: 384 * Uses the bswap instruction. @@ -12922,6 +13046,7 @@ _sp_3072_to_bin_bswap: #ifndef __APPLE__ .size sp_3072_to_bin_bswap,.-sp_3072_to_bin_bswap #endif /* __APPLE__ */ +#ifndef NO_MOVBE_SUPPORT /* Write r as big endian to byte array. * Fixed length number of bytes written: 384 * Uses the movbe instruction which is optional. @@ -13041,6 +13166,7 @@ _sp_3072_to_bin_movbe: #ifndef __APPLE__ .size sp_3072_to_bin_movbe,.-sp_3072_to_bin_movbe #endif /* __APPLE__ */ +#endif /* NO_MOVBE_SUPPORT */ /* Multiply a and b into r. (r = a * b) * * r A single precision integer. @@ -14700,6 +14826,7 @@ _sp_3072_mul_avx2_12: cmovne %rdi, %rbx cmpq %rdi, %rbp cmove %rsp, %rbx + addq $0x60, %rdi xorq %r12, %r12 movq (%rsi), %rdx # A[0] * B[0] @@ -14752,7 +14879,7 @@ _sp_3072_mul_avx2_12: movq %r12, %r11 adcxq %r12, %r11 movq %r10, 88(%rbx) - movq %r8, 96(%rdi) + movq %r8, (%rdi) movq 8(%rsi), %rdx movq 8(%rbx), %r9 movq 16(%rbx), %r10 @@ -14815,7 +14942,7 @@ _sp_3072_mul_avx2_12: adcxq %rax, %r9 adoxq %rcx, %r10 movq %r9, 80(%rbx) - movq 96(%rdi), %r8 + movq (%rdi), %r8 # A[1] * B[10] mulx 80(%rbp), %rax, %rcx adcxq %rax, %r10 @@ -14830,8 +14957,8 @@ _sp_3072_mul_avx2_12: movq %r12, %r11 adoxq %r12, %r11 adcxq %r12, %r11 - movq %r8, 96(%rdi) - movq %r9, 104(%rdi) + movq %r8, (%rdi) + movq %r9, 8(%rdi) movq 16(%rsi), %rdx movq 16(%rbx), %r10 movq 24(%rbx), %r8 @@ -14883,7 +15010,7 @@ _sp_3072_mul_avx2_12: adoxq %rcx, %r9 movq %r8, 72(%rbx) movq 88(%rbx), %r10 - movq 96(%rdi), %r8 + movq (%rdi), %r8 # A[2] * B[8] mulx 64(%rbp), %rax, %rcx adcxq %rax, %r9 @@ -14894,14 +15021,14 @@ _sp_3072_mul_avx2_12: adcxq %rax, %r10 adoxq %rcx, %r8 movq %r10, 88(%rbx) - movq 104(%rdi), %r9 + movq 8(%rdi), %r9 # A[2] * B[10] mulx 80(%rbp), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 # A[2] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r8, 96(%rdi) + movq %r8, (%rdi) movq %r12, %r10 adcxq %rax, %r9 adoxq %rcx, %r10 @@ -14909,8 +15036,8 @@ _sp_3072_mul_avx2_12: movq %r12, %r11 adoxq %r12, %r11 adcxq %r12, %r11 - movq %r9, 104(%rdi) - movq %r10, 112(%rdi) + movq %r9, 8(%rdi) + movq %r10, 16(%rdi) movq 24(%rsi), %rdx movq 24(%rbx), %r8 movq 32(%rbx), %r9 @@ -14961,8 +15088,8 @@ _sp_3072_mul_avx2_12: adcxq %rax, %r9 adoxq %rcx, %r10 movq %r9, 80(%rbx) - movq 96(%rdi), %r8 - movq 104(%rdi), %r9 + movq (%rdi), %r8 + movq 8(%rdi), %r9 # A[3] * B[8] mulx 64(%rbp), %rax, %rcx adcxq %rax, %r10 @@ -14972,15 +15099,15 @@ _sp_3072_mul_avx2_12: movq %r10, 88(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 96(%rdi) - movq 112(%rdi), %r10 + movq %r8, (%rdi) + movq 16(%rdi), %r10 # A[3] * B[10] mulx 80(%rbp), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 # A[3] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r9, 104(%rdi) + movq %r9, 8(%rdi) movq %r12, %r8 adcxq %rax, %r10 adoxq %rcx, %r8 @@ -14988,8 +15115,8 @@ _sp_3072_mul_avx2_12: movq %r12, %r11 adoxq %r12, %r11 adcxq %r12, %r11 - movq %r10, 112(%rdi) - movq %r8, 120(%rdi) + movq %r10, 16(%rdi) + movq %r8, 24(%rdi) movq 32(%rsi), %rdx movq 32(%rbx), %r9 movq 40(%rbx), %r10 @@ -15029,7 +15156,7 @@ _sp_3072_mul_avx2_12: adoxq %rcx, %r9 movq %r8, 72(%rbx) movq 88(%rbx), %r10 - movq 96(%rdi), %r8 + movq (%rdi), %r8 # A[4] * B[6] mulx 48(%rbp), %rax, %rcx adcxq %rax, %r9 @@ -15040,26 +15167,26 @@ _sp_3072_mul_avx2_12: adcxq %rax, %r10 adoxq %rcx, %r8 movq %r10, 88(%rbx) - movq 104(%rdi), %r9 - movq 112(%rdi), %r10 + movq 8(%rdi), %r9 + movq 16(%rdi), %r10 # A[4] * B[8] mulx 64(%rbp), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 # A[4] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r8, 96(%rdi) + movq %r8, (%rdi) adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r9, 104(%rdi) - movq 120(%rdi), %r8 + movq %r9, 8(%rdi) + movq 24(%rdi), %r8 # A[4] * B[10] mulx 80(%rbp), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r8 # A[4] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r10, 112(%rdi) + movq %r10, 16(%rdi) movq %r12, %r9 adcxq %rax, %r8 adoxq %rcx, %r9 @@ -15067,8 +15194,8 @@ _sp_3072_mul_avx2_12: movq %r12, %r11 adoxq %r12, %r11 adcxq %r12, %r11 - movq %r8, 120(%rdi) - movq %r9, 128(%rdi) + movq %r8, 24(%rdi) + movq %r9, 32(%rdi) movq 40(%rsi), %rdx movq 40(%rbx), %r10 movq 48(%rbx), %r8 @@ -15107,8 +15234,8 @@ _sp_3072_mul_avx2_12: adcxq %rax, %r9 adoxq %rcx, %r10 movq %r9, 80(%rbx) - movq 96(%rdi), %r8 - movq 104(%rdi), %r9 + movq (%rdi), %r8 + movq 8(%rdi), %r9 # A[5] * B[6] mulx 48(%rbp), %rax, %rcx adcxq %rax, %r10 @@ -15118,27 +15245,27 @@ _sp_3072_mul_avx2_12: movq %r10, 88(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 96(%rdi) - movq 112(%rdi), %r10 - movq 120(%rdi), %r8 + movq %r8, (%rdi) + movq 16(%rdi), %r10 + movq 24(%rdi), %r8 # A[5] * B[8] mulx 64(%rbp), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 # A[5] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r9, 104(%rdi) + movq %r9, 8(%rdi) adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r10, 112(%rdi) - movq 128(%rdi), %r9 + movq %r10, 16(%rdi) + movq 32(%rdi), %r9 # A[5] * B[10] mulx 80(%rbp), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 # A[5] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r8, 120(%rdi) + movq %r8, 24(%rdi) movq %r12, %r10 adcxq %rax, %r9 adoxq %rcx, %r10 @@ -15146,8 +15273,8 @@ _sp_3072_mul_avx2_12: movq %r12, %r11 adoxq %r12, %r11 adcxq %r12, %r11 - movq %r9, 128(%rdi) - movq %r10, 136(%rdi) + movq %r9, 32(%rdi) + movq %r10, 40(%rdi) movq 48(%rsi), %rdx movq 48(%rbx), %r8 movq 56(%rbx), %r9 @@ -15175,7 +15302,7 @@ _sp_3072_mul_avx2_12: adoxq %rcx, %r9 movq %r8, 72(%rbx) movq 88(%rbx), %r10 - movq 96(%rdi), %r8 + movq (%rdi), %r8 # A[6] * B[4] mulx 32(%rbp), %rax, %rcx adcxq %rax, %r9 @@ -15186,38 +15313,38 @@ _sp_3072_mul_avx2_12: adcxq %rax, %r10 adoxq %rcx, %r8 movq %r10, 88(%rbx) - movq 104(%rdi), %r9 - movq 112(%rdi), %r10 + movq 8(%rdi), %r9 + movq 16(%rdi), %r10 # A[6] * B[6] mulx 48(%rbp), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 # A[6] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r8, 96(%rdi) + movq %r8, (%rdi) adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r9, 104(%rdi) - movq 120(%rdi), %r8 - movq 128(%rdi), %r9 + movq %r9, 8(%rdi) + movq 24(%rdi), %r8 + movq 32(%rdi), %r9 # A[6] * B[8] mulx 64(%rbp), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r8 # A[6] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r10, 112(%rdi) + movq %r10, 16(%rdi) adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 120(%rdi) - movq 136(%rdi), %r10 + movq %r8, 24(%rdi) + movq 40(%rdi), %r10 # A[6] * B[10] mulx 80(%rbp), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 # A[6] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r9, 128(%rdi) + movq %r9, 32(%rdi) movq %r12, %r8 adcxq %rax, %r10 adoxq %rcx, %r8 @@ -15225,8 +15352,8 @@ _sp_3072_mul_avx2_12: movq %r12, %r11 adoxq %r12, %r11 adcxq %r12, %r11 - movq %r10, 136(%rdi) - movq %r8, 144(%rdi) + movq %r10, 40(%rdi) + movq %r8, 48(%rdi) movq 56(%rsi), %rdx movq 56(%rbx), %r9 movq 64(%rbx), %r10 @@ -15253,8 +15380,8 @@ _sp_3072_mul_avx2_12: adcxq %rax, %r9 adoxq %rcx, %r10 movq %r9, 80(%rbx) - movq 96(%rdi), %r8 - movq 104(%rdi), %r9 + movq (%rdi), %r8 + movq 8(%rdi), %r9 # A[7] * B[4] mulx 32(%rbp), %rax, %rcx adcxq %rax, %r10 @@ -15264,39 +15391,39 @@ _sp_3072_mul_avx2_12: movq %r10, 88(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 96(%rdi) - movq 112(%rdi), %r10 - movq 120(%rdi), %r8 + movq %r8, (%rdi) + movq 16(%rdi), %r10 + movq 24(%rdi), %r8 # A[7] * B[6] mulx 48(%rbp), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 # A[7] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r9, 104(%rdi) + movq %r9, 8(%rdi) adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r10, 112(%rdi) - movq 128(%rdi), %r9 - movq 136(%rdi), %r10 + movq %r10, 16(%rdi) + movq 32(%rdi), %r9 + movq 40(%rdi), %r10 # A[7] * B[8] mulx 64(%rbp), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 # A[7] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r8, 120(%rdi) + movq %r8, 24(%rdi) adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r9, 128(%rdi) - movq 144(%rdi), %r8 + movq %r9, 32(%rdi) + movq 48(%rdi), %r8 # A[7] * B[10] mulx 80(%rbp), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r8 # A[7] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r10, 136(%rdi) + movq %r10, 40(%rdi) movq %r12, %r9 adcxq %rax, %r8 adoxq %rcx, %r9 @@ -15304,8 +15431,8 @@ _sp_3072_mul_avx2_12: movq %r12, %r11 adoxq %r12, %r11 adcxq %r12, %r11 - movq %r8, 144(%rdi) - movq %r9, 152(%rdi) + movq %r8, 48(%rdi) + movq %r9, 56(%rdi) movq 64(%rsi), %rdx movq 64(%rbx), %r10 movq 72(%rbx), %r8 @@ -15321,7 +15448,7 @@ _sp_3072_mul_avx2_12: adoxq %rcx, %r9 movq %r8, 72(%rbx) movq 88(%rbx), %r10 - movq 96(%rdi), %r8 + movq (%rdi), %r8 # A[8] * B[2] mulx 16(%rbp), %rax, %rcx adcxq %rax, %r9 @@ -15332,50 +15459,50 @@ _sp_3072_mul_avx2_12: adcxq %rax, %r10 adoxq %rcx, %r8 movq %r10, 88(%rbx) - movq 104(%rdi), %r9 - movq 112(%rdi), %r10 + movq 8(%rdi), %r9 + movq 16(%rdi), %r10 # A[8] * B[4] mulx 32(%rbp), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 # A[8] * B[5] mulx 40(%rbp), %rax, %rcx - movq %r8, 96(%rdi) + movq %r8, (%rdi) adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r9, 104(%rdi) - movq 120(%rdi), %r8 - movq 128(%rdi), %r9 + movq %r9, 8(%rdi) + movq 24(%rdi), %r8 + movq 32(%rdi), %r9 # A[8] * B[6] mulx 48(%rbp), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r8 # A[8] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r10, 112(%rdi) + movq %r10, 16(%rdi) adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 120(%rdi) - movq 136(%rdi), %r10 - movq 144(%rdi), %r8 + movq %r8, 24(%rdi) + movq 40(%rdi), %r10 + movq 48(%rdi), %r8 # A[8] * B[8] mulx 64(%rbp), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 # A[8] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r9, 128(%rdi) + movq %r9, 32(%rdi) adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r10, 136(%rdi) - movq 152(%rdi), %r9 + movq %r10, 40(%rdi) + movq 56(%rdi), %r9 # A[8] * B[10] mulx 80(%rbp), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 # A[8] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r8, 144(%rdi) + movq %r8, 48(%rdi) movq %r12, %r10 adcxq %rax, %r9 adoxq %rcx, %r10 @@ -15383,8 +15510,8 @@ _sp_3072_mul_avx2_12: movq %r12, %r11 adoxq %r12, %r11 adcxq %r12, %r11 - movq %r9, 152(%rdi) - movq %r10, 160(%rdi) + movq %r9, 56(%rdi) + movq %r10, 64(%rdi) movq 72(%rsi), %rdx movq 72(%rbx), %r8 movq 80(%rbx), %r9 @@ -15399,8 +15526,8 @@ _sp_3072_mul_avx2_12: adcxq %rax, %r9 adoxq %rcx, %r10 movq %r9, 80(%rbx) - movq 96(%rdi), %r8 - movq 104(%rdi), %r9 + movq (%rdi), %r8 + movq 8(%rdi), %r9 # A[9] * B[2] mulx 16(%rbp), %rax, %rcx adcxq %rax, %r10 @@ -15410,51 +15537,51 @@ _sp_3072_mul_avx2_12: movq %r10, 88(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 96(%rdi) - movq 112(%rdi), %r10 - movq 120(%rdi), %r8 + movq %r8, (%rdi) + movq 16(%rdi), %r10 + movq 24(%rdi), %r8 # A[9] * B[4] mulx 32(%rbp), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 # A[9] * B[5] mulx 40(%rbp), %rax, %rcx - movq %r9, 104(%rdi) + movq %r9, 8(%rdi) adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r10, 112(%rdi) - movq 128(%rdi), %r9 - movq 136(%rdi), %r10 + movq %r10, 16(%rdi) + movq 32(%rdi), %r9 + movq 40(%rdi), %r10 # A[9] * B[6] mulx 48(%rbp), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 # A[9] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r8, 120(%rdi) + movq %r8, 24(%rdi) adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r9, 128(%rdi) - movq 144(%rdi), %r8 - movq 152(%rdi), %r9 + movq %r9, 32(%rdi) + movq 48(%rdi), %r8 + movq 56(%rdi), %r9 # A[9] * B[8] mulx 64(%rbp), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r8 # A[9] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r10, 136(%rdi) + movq %r10, 40(%rdi) adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 144(%rdi) - movq 160(%rdi), %r10 + movq %r8, 48(%rdi) + movq 64(%rdi), %r10 # A[9] * B[10] mulx 80(%rbp), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 # A[9] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r9, 152(%rdi) + movq %r9, 56(%rdi) movq %r12, %r8 adcxq %rax, %r10 adoxq %rcx, %r8 @@ -15462,12 +15589,12 @@ _sp_3072_mul_avx2_12: movq %r12, %r11 adoxq %r12, %r11 adcxq %r12, %r11 - movq %r10, 160(%rdi) - movq %r8, 168(%rdi) + movq %r10, 64(%rdi) + movq %r8, 72(%rdi) movq 80(%rsi), %rdx movq 80(%rbx), %r9 movq 88(%rbx), %r10 - movq 96(%rdi), %r8 + movq (%rdi), %r8 # A[10] * B[0] mulx (%rbp), %rax, %rcx adcxq %rax, %r9 @@ -15478,62 +15605,62 @@ _sp_3072_mul_avx2_12: adcxq %rax, %r10 adoxq %rcx, %r8 movq %r10, 88(%rbx) - movq 104(%rdi), %r9 - movq 112(%rdi), %r10 + movq 8(%rdi), %r9 + movq 16(%rdi), %r10 # A[10] * B[2] mulx 16(%rbp), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 # A[10] * B[3] mulx 24(%rbp), %rax, %rcx - movq %r8, 96(%rdi) + movq %r8, (%rdi) adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r9, 104(%rdi) - movq 120(%rdi), %r8 - movq 128(%rdi), %r9 + movq %r9, 8(%rdi) + movq 24(%rdi), %r8 + movq 32(%rdi), %r9 # A[10] * B[4] mulx 32(%rbp), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r8 # A[10] * B[5] mulx 40(%rbp), %rax, %rcx - movq %r10, 112(%rdi) + movq %r10, 16(%rdi) adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 120(%rdi) - movq 136(%rdi), %r10 - movq 144(%rdi), %r8 + movq %r8, 24(%rdi) + movq 40(%rdi), %r10 + movq 48(%rdi), %r8 # A[10] * B[6] mulx 48(%rbp), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 # A[10] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r9, 128(%rdi) + movq %r9, 32(%rdi) adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r10, 136(%rdi) - movq 152(%rdi), %r9 - movq 160(%rdi), %r10 + movq %r10, 40(%rdi) + movq 56(%rdi), %r9 + movq 64(%rdi), %r10 # A[10] * B[8] mulx 64(%rbp), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 # A[10] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r8, 144(%rdi) + movq %r8, 48(%rdi) adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r9, 152(%rdi) - movq 168(%rdi), %r8 + movq %r9, 56(%rdi) + movq 72(%rdi), %r8 # A[10] * B[10] mulx 80(%rbp), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r8 # A[10] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r10, 160(%rdi) + movq %r10, 64(%rdi) movq %r12, %r9 adcxq %rax, %r8 adoxq %rcx, %r9 @@ -15541,12 +15668,12 @@ _sp_3072_mul_avx2_12: movq %r12, %r11 adoxq %r12, %r11 adcxq %r12, %r11 - movq %r8, 168(%rdi) - movq %r9, 176(%rdi) + movq %r8, 72(%rdi) + movq %r9, 80(%rdi) movq 88(%rsi), %rdx movq 88(%rbx), %r10 - movq 96(%rdi), %r8 - movq 104(%rdi), %r9 + movq (%rdi), %r8 + movq 8(%rdi), %r9 # A[11] * B[0] mulx (%rbp), %rax, %rcx adcxq %rax, %r10 @@ -15556,69 +15683,70 @@ _sp_3072_mul_avx2_12: movq %r10, 88(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 96(%rdi) - movq 112(%rdi), %r10 - movq 120(%rdi), %r8 + movq %r8, (%rdi) + movq 16(%rdi), %r10 + movq 24(%rdi), %r8 # A[11] * B[2] mulx 16(%rbp), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 # A[11] * B[3] mulx 24(%rbp), %rax, %rcx - movq %r9, 104(%rdi) + movq %r9, 8(%rdi) adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r10, 112(%rdi) - movq 128(%rdi), %r9 - movq 136(%rdi), %r10 + movq %r10, 16(%rdi) + movq 32(%rdi), %r9 + movq 40(%rdi), %r10 # A[11] * B[4] mulx 32(%rbp), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 # A[11] * B[5] mulx 40(%rbp), %rax, %rcx - movq %r8, 120(%rdi) + movq %r8, 24(%rdi) adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r9, 128(%rdi) - movq 144(%rdi), %r8 - movq 152(%rdi), %r9 + movq %r9, 32(%rdi) + movq 48(%rdi), %r8 + movq 56(%rdi), %r9 # A[11] * B[6] mulx 48(%rbp), %rax, %rcx adcxq %rax, %r10 adoxq %rcx, %r8 # A[11] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r10, 136(%rdi) + movq %r10, 40(%rdi) adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 144(%rdi) - movq 160(%rdi), %r10 - movq 168(%rdi), %r8 + movq %r8, 48(%rdi) + movq 64(%rdi), %r10 + movq 72(%rdi), %r8 # A[11] * B[8] mulx 64(%rbp), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 # A[11] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r9, 152(%rdi) + movq %r9, 56(%rdi) adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r10, 160(%rdi) - movq 176(%rdi), %r9 + movq %r10, 64(%rdi) + movq 80(%rdi), %r9 # A[11] * B[10] mulx 80(%rbp), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 # A[11] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r8, 168(%rdi) + movq %r8, 72(%rdi) movq %r12, %r10 adcxq %rax, %r9 adoxq %rcx, %r10 adcxq %r11, %r10 - movq %r9, 176(%rdi) - movq %r10, 184(%rdi) + movq %r9, 80(%rdi) + movq %r10, 88(%rdi) + subq $0x60, %rdi cmpq %rdi, %rsi je L_start_3072_mul_avx2_12 cmpq %rdi, %rbp @@ -15674,6 +15802,7 @@ _sp_3072_sqr_avx2_12: cmpq %rdi, %rsi movq %rsp, %rbp cmovne %rdi, %rbp + addq $0x60, %rdi xorq %r10, %r10 # Diagonal 1 # A[1] x A[0] @@ -15745,7 +15874,7 @@ _sp_3072_sqr_avx2_12: movq %r10, %r11 adcxq %r10, %r11 adoxq %r10, %r11 - movq %r9, 96(%rdi) + movq %r9, (%rdi) # Diagonal 2 movq 24(%rbp), %r9 movq 32(%rbp), %r8 @@ -15797,7 +15926,7 @@ _sp_3072_sqr_avx2_12: adcxq %rax, %r15 adoxq %rcx, %rbx # No store %r15 - movq 96(%rdi), %r8 + movq (%rdi), %r8 # A[10] x A[1] mulxq 80(%rsi), %rax, %rcx adcxq %rax, %rbx @@ -15808,20 +15937,20 @@ _sp_3072_sqr_avx2_12: mulxq 88(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 96(%rdi) + movq %r8, (%rdi) movq %r10, %r8 # A[11] x A[2] movq 16(%rsi), %rdx mulxq 88(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r8 - movq %r9, 104(%rdi) + movq %r9, 8(%rdi) # Carry adcxq %r11, %r8 movq %r10, %r11 adcxq %r10, %r11 adoxq %r10, %r11 - movq %r8, 112(%rdi) + movq %r8, 16(%rdi) # Diagonal 3 movq 40(%rbp), %r8 movq 48(%rbp), %r9 @@ -15860,43 +15989,43 @@ _sp_3072_sqr_avx2_12: adcxq %rax, %r15 adoxq %rcx, %rbx # No store %r15 - movq 96(%rdi), %r9 + movq (%rdi), %r9 # A[9] x A[2] mulxq 72(%rsi), %rax, %rcx adcxq %rax, %rbx adoxq %rcx, %r9 # No store %rbx - movq 104(%rdi), %r8 + movq 8(%rdi), %r8 # A[10] x A[2] mulxq 80(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r8 - movq %r9, 96(%rdi) - movq 112(%rdi), %r9 + movq %r9, (%rdi) + movq 16(%rdi), %r9 # A[10] x A[3] movq 80(%rsi), %rdx mulxq 24(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 104(%rdi) + movq %r8, 8(%rdi) movq %r10, %r8 # A[10] x A[4] mulxq 32(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r8 - movq %r9, 112(%rdi) + movq %r9, 16(%rdi) movq %r10, %r9 # A[10] x A[5] mulxq 40(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 120(%rdi) + movq %r8, 24(%rdi) # Carry adcxq %r11, %r9 movq %r10, %r11 adcxq %r10, %r11 adoxq %r10, %r11 - movq %r9, 128(%rdi) + movq %r9, 32(%rdi) # Diagonal 4 # No load %r12 - %r9 # No load %r13 - %r8 @@ -15924,55 +16053,55 @@ _sp_3072_sqr_avx2_12: adcxq %rax, %r15 adoxq %rcx, %rbx # No store %r15 - movq 96(%rdi), %r8 + movq (%rdi), %r8 # A[8] x A[3] mulxq 64(%rsi), %rax, %rcx adcxq %rax, %rbx adoxq %rcx, %r8 # No store %rbx - movq 104(%rdi), %r9 + movq 8(%rdi), %r9 # A[9] x A[3] mulxq 72(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 96(%rdi) - movq 112(%rdi), %r8 + movq %r8, (%rdi) + movq 16(%rdi), %r8 # A[9] x A[4] movq 72(%rsi), %rdx mulxq 32(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r8 - movq %r9, 104(%rdi) - movq 120(%rdi), %r9 + movq %r9, 8(%rdi) + movq 24(%rdi), %r9 # A[9] x A[5] mulxq 40(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 112(%rdi) - movq 128(%rdi), %r8 + movq %r8, 16(%rdi) + movq 32(%rdi), %r8 # A[9] x A[6] mulxq 48(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r8 - movq %r9, 120(%rdi) + movq %r9, 24(%rdi) movq %r10, %r9 # A[9] x A[7] mulxq 56(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 128(%rdi) + movq %r8, 32(%rdi) movq %r10, %r8 # A[9] x A[8] mulxq 64(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r8 - movq %r9, 136(%rdi) + movq %r9, 40(%rdi) # Carry adcxq %r11, %r8 movq %r10, %r11 adcxq %r10, %r11 adoxq %r10, %r11 - movq %r8, 144(%rdi) + movq %r8, 48(%rdi) # Diagonal 5 # No load %r14 - %r8 # No load %r15 - %r9 @@ -15988,146 +16117,146 @@ _sp_3072_sqr_avx2_12: adcxq %rax, %r15 adoxq %rcx, %rbx # No store %r15 - movq 96(%rdi), %r9 + movq (%rdi), %r9 # A[7] x A[4] mulxq 56(%rsi), %rax, %rcx adcxq %rax, %rbx adoxq %rcx, %r9 # No store %rbx - movq 104(%rdi), %r8 + movq 8(%rdi), %r8 # A[8] x A[4] mulxq 64(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r8 - movq %r9, 96(%rdi) - movq 112(%rdi), %r9 + movq %r9, (%rdi) + movq 16(%rdi), %r9 # A[8] x A[5] movq 64(%rsi), %rdx mulxq 40(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 104(%rdi) - movq 120(%rdi), %r8 + movq %r8, 8(%rdi) + movq 24(%rdi), %r8 # A[8] x A[6] mulxq 48(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r8 - movq %r9, 112(%rdi) - movq 128(%rdi), %r9 + movq %r9, 16(%rdi) + movq 32(%rdi), %r9 # A[8] x A[7] mulxq 56(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 120(%rdi) - movq 136(%rdi), %r8 + movq %r8, 24(%rdi) + movq 40(%rdi), %r8 # A[10] x A[6] movq 80(%rsi), %rdx mulxq 48(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r8 - movq %r9, 128(%rdi) - movq 144(%rdi), %r9 + movq %r9, 32(%rdi) + movq 48(%rdi), %r9 # A[10] x A[7] mulxq 56(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 136(%rdi) + movq %r8, 40(%rdi) movq %r10, %r8 # A[10] x A[8] mulxq 64(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r8 - movq %r9, 144(%rdi) + movq %r9, 48(%rdi) movq %r10, %r9 # A[10] x A[9] mulxq 72(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 152(%rdi) + movq %r8, 56(%rdi) # Carry adcxq %r11, %r9 movq %r10, %r11 adcxq %r10, %r11 adoxq %r10, %r11 - movq %r9, 160(%rdi) + movq %r9, 64(%rdi) # Diagonal 6 # No load %rbx - %r9 - movq 96(%rdi), %r8 + movq (%rdi), %r8 # A[6] x A[5] movq 40(%rsi), %rdx mulxq 48(%rsi), %rax, %rcx adcxq %rax, %rbx adoxq %rcx, %r8 # No store %rbx - movq 104(%rdi), %r9 + movq 8(%rdi), %r9 # A[7] x A[5] mulxq 56(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 96(%rdi) - movq 112(%rdi), %r8 + movq %r8, (%rdi) + movq 16(%rdi), %r8 # A[7] x A[6] movq 48(%rsi), %rdx mulxq 56(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r8 - movq %r9, 104(%rdi) - movq 120(%rdi), %r9 + movq %r9, 8(%rdi) + movq 24(%rdi), %r9 # A[11] x A[3] movq 88(%rsi), %rdx mulxq 24(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 112(%rdi) - movq 128(%rdi), %r8 + movq %r8, 16(%rdi) + movq 32(%rdi), %r8 # A[11] x A[4] mulxq 32(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r8 - movq %r9, 120(%rdi) - movq 136(%rdi), %r9 + movq %r9, 24(%rdi) + movq 40(%rdi), %r9 # A[11] x A[5] mulxq 40(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 128(%rdi) - movq 144(%rdi), %r8 + movq %r8, 32(%rdi) + movq 48(%rdi), %r8 # A[11] x A[6] mulxq 48(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r8 - movq %r9, 136(%rdi) - movq 152(%rdi), %r9 + movq %r9, 40(%rdi) + movq 56(%rdi), %r9 # A[11] x A[7] mulxq 56(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 144(%rdi) - movq 160(%rdi), %r8 + movq %r8, 48(%rdi) + movq 64(%rdi), %r8 # A[11] x A[8] mulxq 64(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r8 - movq %r9, 152(%rdi) + movq %r9, 56(%rdi) movq %r10, %r9 # A[11] x A[9] mulxq 72(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 160(%rdi) + movq %r8, 64(%rdi) movq %r10, %r8 # A[11] x A[10] mulxq 80(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r8 - movq %r9, 168(%rdi) + movq %r9, 72(%rdi) # Carry adcxq %r11, %r8 movq %r10, %r11 adcxq %r10, %r11 adoxq %r10, %r11 - movq %r8, 176(%rdi) - movq %r11, 184(%rdi) + movq %r8, 80(%rdi) + movq %r11, 88(%rdi) # Double and Add in A[i] x A[i] movq 8(%rbp), %r9 # A[0] x A[0] @@ -16182,8 +16311,8 @@ _sp_3072_sqr_avx2_12: adoxq %rbx, %rbx adcxq %rax, %r15 adcxq %rcx, %rbx - movq 96(%rdi), %r8 - movq 104(%rdi), %r9 + movq (%rdi), %r8 + movq 8(%rdi), %r9 # A[6] x A[6] movq 48(%rsi), %rdx mulxq %rdx, %rax, %rcx @@ -16191,10 +16320,10 @@ _sp_3072_sqr_avx2_12: adoxq %r9, %r9 adcxq %rax, %r8 adcxq %rcx, %r9 - movq %r8, 96(%rdi) - movq %r9, 104(%rdi) - movq 112(%rdi), %r8 - movq 120(%rdi), %r9 + movq %r8, (%rdi) + movq %r9, 8(%rdi) + movq 16(%rdi), %r8 + movq 24(%rdi), %r9 # A[7] x A[7] movq 56(%rsi), %rdx mulxq %rdx, %rax, %rcx @@ -16202,10 +16331,10 @@ _sp_3072_sqr_avx2_12: adoxq %r9, %r9 adcxq %rax, %r8 adcxq %rcx, %r9 - movq %r8, 112(%rdi) - movq %r9, 120(%rdi) - movq 128(%rdi), %r8 - movq 136(%rdi), %r9 + movq %r8, 16(%rdi) + movq %r9, 24(%rdi) + movq 32(%rdi), %r8 + movq 40(%rdi), %r9 # A[8] x A[8] movq 64(%rsi), %rdx mulxq %rdx, %rax, %rcx @@ -16213,10 +16342,10 @@ _sp_3072_sqr_avx2_12: adoxq %r9, %r9 adcxq %rax, %r8 adcxq %rcx, %r9 - movq %r8, 128(%rdi) - movq %r9, 136(%rdi) - movq 144(%rdi), %r8 - movq 152(%rdi), %r9 + movq %r8, 32(%rdi) + movq %r9, 40(%rdi) + movq 48(%rdi), %r8 + movq 56(%rdi), %r9 # A[9] x A[9] movq 72(%rsi), %rdx mulxq %rdx, %rax, %rcx @@ -16224,10 +16353,10 @@ _sp_3072_sqr_avx2_12: adoxq %r9, %r9 adcxq %rax, %r8 adcxq %rcx, %r9 - movq %r8, 144(%rdi) - movq %r9, 152(%rdi) - movq 160(%rdi), %r8 - movq 168(%rdi), %r9 + movq %r8, 48(%rdi) + movq %r9, 56(%rdi) + movq 64(%rdi), %r8 + movq 72(%rdi), %r9 # A[10] x A[10] movq 80(%rsi), %rdx mulxq %rdx, %rax, %rcx @@ -16235,10 +16364,10 @@ _sp_3072_sqr_avx2_12: adoxq %r9, %r9 adcxq %rax, %r8 adcxq %rcx, %r9 - movq %r8, 160(%rdi) - movq %r9, 168(%rdi) - movq 176(%rdi), %r8 - movq 184(%rdi), %r9 + movq %r8, 64(%rdi) + movq %r9, 72(%rdi) + movq 80(%rdi), %r8 + movq 88(%rdi), %r9 # A[11] x A[11] movq 88(%rsi), %rdx mulxq %rdx, %rax, %rcx @@ -16246,13 +16375,14 @@ _sp_3072_sqr_avx2_12: adoxq %r9, %r9 adcxq %rax, %r8 adcxq %rcx, %r9 - movq %r8, 176(%rdi) - movq %r9, 184(%rdi) - movq %r12, 56(%rdi) - movq %r13, 64(%rdi) - movq %r14, 72(%rdi) - movq %r15, 80(%rdi) - movq %rbx, 88(%rdi) + movq %r8, 80(%rdi) + movq %r9, 88(%rdi) + movq %r12, -40(%rdi) + movq %r13, -32(%rdi) + movq %r14, -24(%rdi) + movq %r15, -16(%rdi) + movq %rbx, -8(%rdi) + subq $0x60, %rdi cmpq %rdi, %rsi jne L_end_3072_sqr_avx2_12 vmovdqu (%rbp), %xmm0 @@ -16665,6 +16795,11 @@ _sp_3072_mul_24: #else callq _sp_3072_mul_12 #endif /* __APPLE__ */ +#ifdef _WIN64 + movq 592(%rsp), %rdx + movq 584(%rsp), %rsi + movq 576(%rsp), %rdi +#endif /* _WIN64 */ movq 600(%rsp), %r13 movq 608(%rsp), %r14 movq 576(%rsp), %r15 @@ -17235,6 +17370,10 @@ _sp_3072_sqr_24: #else callq _sp_3072_sqr_12 #endif /* __APPLE__ */ +#ifdef _WIN64 + movq 488(%rsp), %rsi + movq 480(%rsp), %rdi +#endif /* _WIN64 */ movq 496(%rsp), %r10 movq %rdi, %r9 leaq 384(%rsp), %r8 @@ -17617,6 +17756,7 @@ _sp_3072_sqr_24: #ifndef __APPLE__ .size sp_3072_sqr_24,.-sp_3072_sqr_24 #endif /* __APPLE__ */ +#ifdef HAVE_INTEL_AVX2 /* Multiply a and b into r. (r = a * b) * * r A single precision integer. @@ -17753,6 +17893,11 @@ _sp_3072_mul_avx2_24: #else callq _sp_3072_mul_avx2_12 #endif /* __APPLE__ */ +#ifdef _WIN64 + movq 592(%rsp), %rdx + movq 584(%rsp), %rsi + movq 576(%rsp), %rdi +#endif /* _WIN64 */ movq 600(%rsp), %r13 movq 608(%rsp), %r14 movq 576(%rsp), %r15 @@ -18144,6 +18289,8 @@ _sp_3072_mul_avx2_24: #ifndef __APPLE__ .size sp_3072_mul_avx2_24,.-sp_3072_mul_avx2_24 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +#ifdef HAVE_INTEL_AVX2 /* Square a and put result in r. (r = a * a) * * r A single precision integer. @@ -18228,6 +18375,10 @@ _sp_3072_sqr_avx2_24: #else callq _sp_3072_sqr_avx2_12 #endif /* __APPLE__ */ +#ifdef _WIN64 + movq 488(%rsp), %rsi + movq 480(%rsp), %rdi +#endif /* _WIN64 */ movq 496(%rsp), %r10 movq %rdi, %r9 leaq 384(%rsp), %r8 @@ -18586,6 +18737,7 @@ _sp_3072_sqr_avx2_24: #ifndef __APPLE__ .size sp_3072_sqr_avx2_24,.-sp_3072_sqr_avx2_24 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ /* Sub b from a into a. (a -= b) * * a A single precision integer and result. @@ -19130,6 +19282,11 @@ _sp_3072_mul_48: #else callq _sp_3072_mul_24 #endif /* __APPLE__ */ +#ifdef _WIN64 + movq 1168(%rsp), %rdx + movq 1160(%rsp), %rsi + movq 1152(%rsp), %rdi +#endif /* _WIN64 */ movq 1176(%rsp), %r13 movq 1184(%rsp), %r14 movq 1152(%rsp), %r15 @@ -20168,6 +20325,10 @@ _sp_3072_sqr_48: #else callq _sp_3072_sqr_24 #endif /* __APPLE__ */ +#ifdef _WIN64 + movq 968(%rsp), %rsi + movq 960(%rsp), %rdi +#endif /* _WIN64 */ movq 976(%rsp), %r10 movq %rdi, %r9 leaq 768(%rsp), %r8 @@ -20910,6 +21071,7 @@ _sp_3072_sqr_48: #ifndef __APPLE__ .size sp_3072_sqr_48,.-sp_3072_sqr_48 #endif /* __APPLE__ */ +#ifdef HAVE_INTEL_AVX2 /* Multiply a and b into r. (r = a * b) * * r A single precision integer. @@ -21118,6 +21280,11 @@ _sp_3072_mul_avx2_48: #else callq _sp_3072_mul_avx2_24 #endif /* __APPLE__ */ +#ifdef _WIN64 + movq 1168(%rsp), %rdx + movq 1160(%rsp), %rsi + movq 1152(%rsp), %rdi +#endif /* _WIN64 */ movq 1176(%rsp), %r13 movq 1184(%rsp), %r14 movq 1152(%rsp), %r15 @@ -21869,6 +22036,8 @@ _sp_3072_mul_avx2_48: #ifndef __APPLE__ .size sp_3072_mul_avx2_48,.-sp_3072_mul_avx2_48 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +#ifdef HAVE_INTEL_AVX2 /* Square a and put result in r. (r = a * a) * * r A single precision integer. @@ -21989,6 +22158,10 @@ _sp_3072_sqr_avx2_48: #else callq _sp_3072_sqr_avx2_24 #endif /* __APPLE__ */ +#ifdef _WIN64 + movq 968(%rsp), %rsi + movq 960(%rsp), %rdi +#endif /* _WIN64 */ movq 976(%rsp), %r10 movq %rdi, %r9 leaq 768(%rsp), %r8 @@ -22683,6 +22856,7 @@ _sp_3072_sqr_avx2_48: #ifndef __APPLE__ .size sp_3072_sqr_avx2_48,.-sp_3072_sqr_avx2_48 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ /* Mul a by digit b into r. (r = a * b) * * r A single precision integer. @@ -23312,7 +23486,7 @@ _sp_3072_mont_reduce_24: movq $24, %r8 movq (%rdi), %r13 movq 8(%rdi), %r14 -L_mont_loop_24: +L_3072_mont_loop_24: # mu = a[i] * mp movq %r13, %r11 imulq %rcx, %r11 @@ -23555,12 +23729,17 @@ L_mont_loop_24: # i -= 1 addq $8, %rdi decq %r8 - jnz L_mont_loop_24 + jnz L_3072_mont_loop_24 movq %r13, (%rdi) movq %r14, 8(%rdi) negq %r15 +#ifdef _WIN64 + movq %rsi, %rdx + movq %r15, %rcx +#else movq %r15, %rcx movq %rsi, %rdx +#endif /* _WIN64 */ movq %rdi, %rsi movq %rdi, %rdi subq $0xc0, %rdi @@ -23577,6 +23756,7 @@ L_mont_loop_24: #ifndef __APPLE__ .size sp_3072_mont_reduce_24,.-sp_3072_mont_reduce_24 #endif /* __APPLE__ */ +#ifdef HAVE_INTEL_AVX2 /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -23723,6 +23903,7 @@ _sp_3072_cond_sub_avx2_24: #ifndef __APPLE__ .size sp_3072_cond_sub_avx2_24,.-sp_3072_cond_sub_avx2_24 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ /* Mul a by digit b into r. (r = a * b) * * r A single precision integer. @@ -23965,134 +24146,134 @@ _sp_3072_mul_d_avx2_24: mulxq 8(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 8(%rdi) adoxq %r8, %r9 + movq %r10, 8(%rdi) # A[2] * B mulxq 16(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 16(%rdi) adoxq %r8, %r10 + movq %r9, 16(%rdi) # A[3] * B mulxq 24(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 24(%rdi) adoxq %r8, %r9 + movq %r10, 24(%rdi) # A[4] * B mulxq 32(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 32(%rdi) adoxq %r8, %r10 + movq %r9, 32(%rdi) # A[5] * B mulxq 40(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 40(%rdi) adoxq %r8, %r9 + movq %r10, 40(%rdi) # A[6] * B mulxq 48(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 48(%rdi) adoxq %r8, %r10 + movq %r9, 48(%rdi) # A[7] * B mulxq 56(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 56(%rdi) adoxq %r8, %r9 + movq %r10, 56(%rdi) # A[8] * B mulxq 64(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 64(%rdi) adoxq %r8, %r10 + movq %r9, 64(%rdi) # A[9] * B mulxq 72(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 72(%rdi) adoxq %r8, %r9 + movq %r10, 72(%rdi) # A[10] * B mulxq 80(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 80(%rdi) adoxq %r8, %r10 + movq %r9, 80(%rdi) # A[11] * B mulxq 88(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 88(%rdi) adoxq %r8, %r9 + movq %r10, 88(%rdi) # A[12] * B mulxq 96(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 96(%rdi) adoxq %r8, %r10 + movq %r9, 96(%rdi) # A[13] * B mulxq 104(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 104(%rdi) adoxq %r8, %r9 + movq %r10, 104(%rdi) # A[14] * B mulxq 112(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 112(%rdi) adoxq %r8, %r10 + movq %r9, 112(%rdi) # A[15] * B mulxq 120(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 120(%rdi) adoxq %r8, %r9 + movq %r10, 120(%rdi) # A[16] * B mulxq 128(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 128(%rdi) adoxq %r8, %r10 + movq %r9, 128(%rdi) # A[17] * B mulxq 136(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 136(%rdi) adoxq %r8, %r9 + movq %r10, 136(%rdi) # A[18] * B mulxq 144(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 144(%rdi) adoxq %r8, %r10 + movq %r9, 144(%rdi) # A[19] * B mulxq 152(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 152(%rdi) adoxq %r8, %r9 + movq %r10, 152(%rdi) # A[20] * B mulxq 160(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 160(%rdi) adoxq %r8, %r10 + movq %r9, 160(%rdi) # A[21] * B mulxq 168(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 168(%rdi) adoxq %r8, %r9 + movq %r10, 168(%rdi) # A[22] * B mulxq 176(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 176(%rdi) adoxq %r8, %r10 + movq %r9, 176(%rdi) # A[23] * B mulxq 184(%rsi), %rcx, %r8 movq %r11, %r9 @@ -24106,6 +24287,35 @@ _sp_3072_mul_d_avx2_24: .size sp_3072_mul_d_avx2_24,.-sp_3072_mul_d_avx2_24 #endif /* __APPLE__ */ #endif /* HAVE_INTEL_AVX2 */ +#ifdef _WIN64 +/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) + * + * d1 The high order half of the number to divide. + * d0 The low order half of the number to divide. + * div The dividend. + * returns the result of the division. + */ +#ifndef __APPLE__ +.text +.globl div_3072_word_asm_24 +.type div_3072_word_asm_24,@function +.align 16 +div_3072_word_asm_24: +#else +.section __TEXT,__text +.globl _div_3072_word_asm_24 +.p2align 4 +_div_3072_word_asm_24: +#endif /* __APPLE__ */ + movq %rdx, %rcx + movq %rsi, %rax + movq %rdi, %rdx + divq %rcx + repz retq +#ifndef __APPLE__ +.size div_3072_word_asm_24,.-div_3072_word_asm_24 +#endif /* __APPLE__ */ +#endif /* _WIN64 */ /* Compare a with b in constant time. * * a A single precision integer. @@ -24348,14 +24558,20 @@ _sp_3072_mont_reduce_avx2_24: pushq %r12 pushq %r13 pushq %r14 + pushq %r15 + pushq %rbx + pushq %rbp movq %rdx, %r8 - xorq %r14, %r14 + xorq %rbp, %rbp # i = 24 movq $24, %r9 movq (%rdi), %r13 + movq 8(%rdi), %r14 + movq 16(%rdi), %r15 + movq 24(%rdi), %rbx addq $0x60, %rdi - xorq %r12, %r12 -L_mont_loop_avx2_24: + xorq %rbp, %rbp +L_3072_mont_loop_avx2_24: # mu = a[i] * mp movq %r13, %rdx movq %r13, %r10 @@ -24363,32 +24579,29 @@ L_mont_loop_avx2_24: xorq %r12, %r12 # a[i+0] += m[0] * mu mulxq (%rsi), %rax, %rcx - movq -88(%rdi), %r13 + movq %r14, %r13 adcxq %rax, %r10 adoxq %rcx, %r13 # a[i+1] += m[1] * mu mulxq 8(%rsi), %rax, %rcx - movq -80(%rdi), %r10 + movq %r15, %r14 adcxq %rax, %r13 - adoxq %rcx, %r10 + adoxq %rcx, %r14 # a[i+2] += m[2] * mu mulxq 16(%rsi), %rax, %rcx - movq -72(%rdi), %r11 - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, -80(%rdi) + movq %rbx, %r15 + adcxq %rax, %r14 + adoxq %rcx, %r15 # a[i+3] += m[3] * mu mulxq 24(%rsi), %rax, %rcx - movq -64(%rdi), %r10 - adcxq %rax, %r11 - adoxq %rcx, %r10 - movq %r11, -72(%rdi) + movq -64(%rdi), %rbx + adcxq %rax, %r15 + adoxq %rcx, %rbx # a[i+4] += m[4] * mu mulxq 32(%rsi), %rax, %rcx movq -56(%rdi), %r11 - adcxq %rax, %r10 + adcxq %rax, %rbx adoxq %rcx, %r11 - movq %r10, -64(%rdi) # a[i+5] += m[5] * mu mulxq 40(%rsi), %rax, %rcx movq -48(%rdi), %r10 @@ -24503,140 +24716,143 @@ L_mont_loop_avx2_24: adcxq %rax, %r11 adoxq %rcx, %r10 movq %r11, 88(%rdi) - adcxq %r14, %r10 + adcxq %rbp, %r10 + movq %r12, %rbp movq %r10, 96(%rdi) - movq %r12, %r14 - adoxq %r12, %r14 - adcxq %r12, %r14 + adoxq %r12, %rbp + adcxq %r12, %rbp # a += 1 addq $8, %rdi # i -= 1 subq $0x01, %r9 - jnz L_mont_loop_avx2_24 + jnz L_3072_mont_loop_avx2_24 subq $0x60, %rdi - negq %r14 + negq %rbp movq %rdi, %r8 subq $0xc0, %rdi movq (%rsi), %rcx movq %r13, %rdx - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx subq %rcx, %rdx movq 8(%rsi), %rcx - movq 8(%r8), %rax - pextq %r14, %rcx, %rcx + movq %r14, %rax + pextq %rbp, %rcx, %rcx movq %rdx, (%rdi) sbbq %rcx, %rax movq 16(%rsi), %rdx - movq 16(%r8), %rcx - pextq %r14, %rdx, %rdx + movq %r15, %rcx + pextq %rbp, %rdx, %rdx movq %rax, 8(%rdi) sbbq %rdx, %rcx movq 24(%rsi), %rax - movq 24(%r8), %rdx - pextq %r14, %rax, %rax + movq %rbx, %rdx + pextq %rbp, %rax, %rax movq %rcx, 16(%rdi) sbbq %rax, %rdx movq 32(%rsi), %rcx movq 32(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 24(%rdi) sbbq %rcx, %rax movq 40(%rsi), %rdx movq 40(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 32(%rdi) sbbq %rdx, %rcx movq 48(%rsi), %rax movq 48(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 40(%rdi) sbbq %rax, %rdx movq 56(%rsi), %rcx movq 56(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 48(%rdi) sbbq %rcx, %rax movq 64(%rsi), %rdx movq 64(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 56(%rdi) sbbq %rdx, %rcx movq 72(%rsi), %rax movq 72(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 64(%rdi) sbbq %rax, %rdx movq 80(%rsi), %rcx movq 80(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 72(%rdi) sbbq %rcx, %rax movq 88(%rsi), %rdx movq 88(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 80(%rdi) sbbq %rdx, %rcx movq 96(%rsi), %rax movq 96(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 88(%rdi) sbbq %rax, %rdx movq 104(%rsi), %rcx movq 104(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 96(%rdi) sbbq %rcx, %rax movq 112(%rsi), %rdx movq 112(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 104(%rdi) sbbq %rdx, %rcx movq 120(%rsi), %rax movq 120(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 112(%rdi) sbbq %rax, %rdx movq 128(%rsi), %rcx movq 128(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 120(%rdi) sbbq %rcx, %rax movq 136(%rsi), %rdx movq 136(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 128(%rdi) sbbq %rdx, %rcx movq 144(%rsi), %rax movq 144(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 136(%rdi) sbbq %rax, %rdx movq 152(%rsi), %rcx movq 152(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 144(%rdi) sbbq %rcx, %rax movq 160(%rsi), %rdx movq 160(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 152(%rdi) sbbq %rdx, %rcx movq 168(%rsi), %rax movq 168(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 160(%rdi) sbbq %rax, %rdx movq 176(%rsi), %rcx movq 176(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 168(%rdi) sbbq %rcx, %rax movq 184(%rsi), %rdx movq 184(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 176(%rdi) sbbq %rdx, %rcx movq %rcx, 184(%rdi) + popq %rbp + popq %rbx + popq %r15 popq %r14 popq %r13 popq %r12 @@ -25037,7 +25253,7 @@ _sp_3072_mont_reduce_48: movq $48, %r8 movq (%rdi), %r13 movq 8(%rdi), %r14 -L_mont_loop_48: +L_3072_mont_loop_48: # mu = a[i] * mp movq %r13, %r11 imulq %rcx, %r11 @@ -25520,12 +25736,17 @@ L_mont_loop_48: # i -= 1 addq $8, %rdi decq %r8 - jnz L_mont_loop_48 + jnz L_3072_mont_loop_48 movq %r13, (%rdi) movq %r14, 8(%rdi) negq %r15 +#ifdef _WIN64 + movq %rsi, %rdx + movq %r15, %rcx +#else movq %r15, %rcx movq %rsi, %rdx +#endif /* _WIN64 */ movq %rdi, %rsi movq %rdi, %rdi subq $0x180, %rdi @@ -25542,6 +25763,7 @@ L_mont_loop_48: #ifndef __APPLE__ .size sp_3072_mont_reduce_48,.-sp_3072_mont_reduce_48 #endif /* __APPLE__ */ +#ifdef HAVE_INTEL_AVX2 /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -25808,6 +26030,7 @@ _sp_3072_cond_sub_avx2_48: #ifndef __APPLE__ .size sp_3072_cond_sub_avx2_48,.-sp_3072_cond_sub_avx2_48 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ #ifdef HAVE_INTEL_AVX2 /* Mul a by digit b into r. (r = a * b) * @@ -25837,278 +26060,278 @@ _sp_3072_mul_d_avx2_48: mulxq 8(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 8(%rdi) adoxq %r8, %r9 + movq %r10, 8(%rdi) # A[2] * B mulxq 16(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 16(%rdi) adoxq %r8, %r10 + movq %r9, 16(%rdi) # A[3] * B mulxq 24(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 24(%rdi) adoxq %r8, %r9 + movq %r10, 24(%rdi) # A[4] * B mulxq 32(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 32(%rdi) adoxq %r8, %r10 + movq %r9, 32(%rdi) # A[5] * B mulxq 40(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 40(%rdi) adoxq %r8, %r9 + movq %r10, 40(%rdi) # A[6] * B mulxq 48(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 48(%rdi) adoxq %r8, %r10 + movq %r9, 48(%rdi) # A[7] * B mulxq 56(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 56(%rdi) adoxq %r8, %r9 + movq %r10, 56(%rdi) # A[8] * B mulxq 64(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 64(%rdi) adoxq %r8, %r10 + movq %r9, 64(%rdi) # A[9] * B mulxq 72(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 72(%rdi) adoxq %r8, %r9 + movq %r10, 72(%rdi) # A[10] * B mulxq 80(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 80(%rdi) adoxq %r8, %r10 + movq %r9, 80(%rdi) # A[11] * B mulxq 88(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 88(%rdi) adoxq %r8, %r9 + movq %r10, 88(%rdi) # A[12] * B mulxq 96(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 96(%rdi) adoxq %r8, %r10 + movq %r9, 96(%rdi) # A[13] * B mulxq 104(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 104(%rdi) adoxq %r8, %r9 + movq %r10, 104(%rdi) # A[14] * B mulxq 112(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 112(%rdi) adoxq %r8, %r10 + movq %r9, 112(%rdi) # A[15] * B mulxq 120(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 120(%rdi) adoxq %r8, %r9 + movq %r10, 120(%rdi) # A[16] * B mulxq 128(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 128(%rdi) adoxq %r8, %r10 + movq %r9, 128(%rdi) # A[17] * B mulxq 136(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 136(%rdi) adoxq %r8, %r9 + movq %r10, 136(%rdi) # A[18] * B mulxq 144(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 144(%rdi) adoxq %r8, %r10 + movq %r9, 144(%rdi) # A[19] * B mulxq 152(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 152(%rdi) adoxq %r8, %r9 + movq %r10, 152(%rdi) # A[20] * B mulxq 160(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 160(%rdi) adoxq %r8, %r10 + movq %r9, 160(%rdi) # A[21] * B mulxq 168(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 168(%rdi) adoxq %r8, %r9 + movq %r10, 168(%rdi) # A[22] * B mulxq 176(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 176(%rdi) adoxq %r8, %r10 + movq %r9, 176(%rdi) # A[23] * B mulxq 184(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 184(%rdi) adoxq %r8, %r9 + movq %r10, 184(%rdi) # A[24] * B mulxq 192(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 192(%rdi) adoxq %r8, %r10 + movq %r9, 192(%rdi) # A[25] * B mulxq 200(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 200(%rdi) adoxq %r8, %r9 + movq %r10, 200(%rdi) # A[26] * B mulxq 208(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 208(%rdi) adoxq %r8, %r10 + movq %r9, 208(%rdi) # A[27] * B mulxq 216(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 216(%rdi) adoxq %r8, %r9 + movq %r10, 216(%rdi) # A[28] * B mulxq 224(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 224(%rdi) adoxq %r8, %r10 + movq %r9, 224(%rdi) # A[29] * B mulxq 232(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 232(%rdi) adoxq %r8, %r9 + movq %r10, 232(%rdi) # A[30] * B mulxq 240(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 240(%rdi) adoxq %r8, %r10 + movq %r9, 240(%rdi) # A[31] * B mulxq 248(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 248(%rdi) adoxq %r8, %r9 + movq %r10, 248(%rdi) # A[32] * B mulxq 256(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 256(%rdi) adoxq %r8, %r10 + movq %r9, 256(%rdi) # A[33] * B mulxq 264(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 264(%rdi) adoxq %r8, %r9 + movq %r10, 264(%rdi) # A[34] * B mulxq 272(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 272(%rdi) adoxq %r8, %r10 + movq %r9, 272(%rdi) # A[35] * B mulxq 280(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 280(%rdi) adoxq %r8, %r9 + movq %r10, 280(%rdi) # A[36] * B mulxq 288(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 288(%rdi) adoxq %r8, %r10 + movq %r9, 288(%rdi) # A[37] * B mulxq 296(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 296(%rdi) adoxq %r8, %r9 + movq %r10, 296(%rdi) # A[38] * B mulxq 304(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 304(%rdi) adoxq %r8, %r10 + movq %r9, 304(%rdi) # A[39] * B mulxq 312(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 312(%rdi) adoxq %r8, %r9 + movq %r10, 312(%rdi) # A[40] * B mulxq 320(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 320(%rdi) adoxq %r8, %r10 + movq %r9, 320(%rdi) # A[41] * B mulxq 328(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 328(%rdi) adoxq %r8, %r9 + movq %r10, 328(%rdi) # A[42] * B mulxq 336(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 336(%rdi) adoxq %r8, %r10 + movq %r9, 336(%rdi) # A[43] * B mulxq 344(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 344(%rdi) adoxq %r8, %r9 + movq %r10, 344(%rdi) # A[44] * B mulxq 352(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 352(%rdi) adoxq %r8, %r10 + movq %r9, 352(%rdi) # A[45] * B mulxq 360(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 360(%rdi) adoxq %r8, %r9 + movq %r10, 360(%rdi) # A[46] * B mulxq 368(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 368(%rdi) adoxq %r8, %r10 + movq %r9, 368(%rdi) # A[47] * B mulxq 376(%rsi), %rcx, %r8 movq %r11, %r9 @@ -26122,6 +26345,35 @@ _sp_3072_mul_d_avx2_48: .size sp_3072_mul_d_avx2_48,.-sp_3072_mul_d_avx2_48 #endif /* __APPLE__ */ #endif /* HAVE_INTEL_AVX2 */ +#ifdef _WIN64 +/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) + * + * d1 The high order half of the number to divide. + * d0 The low order half of the number to divide. + * div The dividend. + * returns the result of the division. + */ +#ifndef __APPLE__ +.text +.globl div_3072_word_asm_48 +.type div_3072_word_asm_48,@function +.align 16 +div_3072_word_asm_48: +#else +.section __TEXT,__text +.globl _div_3072_word_asm_48 +.p2align 4 +_div_3072_word_asm_48: +#endif /* __APPLE__ */ + movq %rdx, %rcx + movq %rsi, %rax + movq %rdi, %rdx + divq %rcx + repz retq +#ifndef __APPLE__ +.size div_3072_word_asm_48,.-div_3072_word_asm_48 +#endif /* __APPLE__ */ +#endif /* _WIN64 */ /* Compare a with b in constant time. * * a A single precision integer. @@ -26724,14 +26976,20 @@ _sp_3072_mont_reduce_avx2_48: pushq %r12 pushq %r13 pushq %r14 + pushq %r15 + pushq %rbx + pushq %rbp movq %rdx, %r8 - xorq %r14, %r14 + xorq %rbp, %rbp # i = 48 movq $48, %r9 movq (%rdi), %r13 + movq 8(%rdi), %r14 + movq 16(%rdi), %r15 + movq 24(%rdi), %rbx addq $0xc0, %rdi - xorq %r12, %r12 -L_mont_loop_avx2_48: + xorq %rbp, %rbp +L_3072_mont_loop_avx2_48: # mu = a[i] * mp movq %r13, %rdx movq %r13, %r10 @@ -26739,32 +26997,29 @@ L_mont_loop_avx2_48: xorq %r12, %r12 # a[i+0] += m[0] * mu mulxq (%rsi), %rax, %rcx - movq -184(%rdi), %r13 + movq %r14, %r13 adcxq %rax, %r10 adoxq %rcx, %r13 # a[i+1] += m[1] * mu mulxq 8(%rsi), %rax, %rcx - movq -176(%rdi), %r10 + movq %r15, %r14 adcxq %rax, %r13 - adoxq %rcx, %r10 + adoxq %rcx, %r14 # a[i+2] += m[2] * mu mulxq 16(%rsi), %rax, %rcx - movq -168(%rdi), %r11 - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, -176(%rdi) + movq %rbx, %r15 + adcxq %rax, %r14 + adoxq %rcx, %r15 # a[i+3] += m[3] * mu mulxq 24(%rsi), %rax, %rcx - movq -160(%rdi), %r10 - adcxq %rax, %r11 - adoxq %rcx, %r10 - movq %r11, -168(%rdi) + movq -160(%rdi), %rbx + adcxq %rax, %r15 + adoxq %rcx, %rbx # a[i+4] += m[4] * mu mulxq 32(%rsi), %rax, %rcx movq -152(%rdi), %r11 - adcxq %rax, %r10 + adcxq %rax, %rbx adoxq %rcx, %r11 - movq %r10, -160(%rdi) # a[i+5] += m[5] * mu mulxq 40(%rsi), %rax, %rcx movq -144(%rdi), %r10 @@ -27023,260 +27278,263 @@ L_mont_loop_avx2_48: adcxq %rax, %r11 adoxq %rcx, %r10 movq %r11, 184(%rdi) - adcxq %r14, %r10 + adcxq %rbp, %r10 + movq %r12, %rbp movq %r10, 192(%rdi) - movq %r12, %r14 - adoxq %r12, %r14 - adcxq %r12, %r14 + adoxq %r12, %rbp + adcxq %r12, %rbp # a += 1 addq $8, %rdi # i -= 1 subq $0x01, %r9 - jnz L_mont_loop_avx2_48 + jnz L_3072_mont_loop_avx2_48 subq $0xc0, %rdi - negq %r14 + negq %rbp movq %rdi, %r8 subq $0x180, %rdi movq (%rsi), %rcx movq %r13, %rdx - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx subq %rcx, %rdx movq 8(%rsi), %rcx - movq 8(%r8), %rax - pextq %r14, %rcx, %rcx + movq %r14, %rax + pextq %rbp, %rcx, %rcx movq %rdx, (%rdi) sbbq %rcx, %rax movq 16(%rsi), %rdx - movq 16(%r8), %rcx - pextq %r14, %rdx, %rdx + movq %r15, %rcx + pextq %rbp, %rdx, %rdx movq %rax, 8(%rdi) sbbq %rdx, %rcx movq 24(%rsi), %rax - movq 24(%r8), %rdx - pextq %r14, %rax, %rax + movq %rbx, %rdx + pextq %rbp, %rax, %rax movq %rcx, 16(%rdi) sbbq %rax, %rdx movq 32(%rsi), %rcx movq 32(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 24(%rdi) sbbq %rcx, %rax movq 40(%rsi), %rdx movq 40(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 32(%rdi) sbbq %rdx, %rcx movq 48(%rsi), %rax movq 48(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 40(%rdi) sbbq %rax, %rdx movq 56(%rsi), %rcx movq 56(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 48(%rdi) sbbq %rcx, %rax movq 64(%rsi), %rdx movq 64(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 56(%rdi) sbbq %rdx, %rcx movq 72(%rsi), %rax movq 72(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 64(%rdi) sbbq %rax, %rdx movq 80(%rsi), %rcx movq 80(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 72(%rdi) sbbq %rcx, %rax movq 88(%rsi), %rdx movq 88(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 80(%rdi) sbbq %rdx, %rcx movq 96(%rsi), %rax movq 96(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 88(%rdi) sbbq %rax, %rdx movq 104(%rsi), %rcx movq 104(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 96(%rdi) sbbq %rcx, %rax movq 112(%rsi), %rdx movq 112(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 104(%rdi) sbbq %rdx, %rcx movq 120(%rsi), %rax movq 120(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 112(%rdi) sbbq %rax, %rdx movq 128(%rsi), %rcx movq 128(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 120(%rdi) sbbq %rcx, %rax movq 136(%rsi), %rdx movq 136(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 128(%rdi) sbbq %rdx, %rcx movq 144(%rsi), %rax movq 144(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 136(%rdi) sbbq %rax, %rdx movq 152(%rsi), %rcx movq 152(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 144(%rdi) sbbq %rcx, %rax movq 160(%rsi), %rdx movq 160(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 152(%rdi) sbbq %rdx, %rcx movq 168(%rsi), %rax movq 168(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 160(%rdi) sbbq %rax, %rdx movq 176(%rsi), %rcx movq 176(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 168(%rdi) sbbq %rcx, %rax movq 184(%rsi), %rdx movq 184(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 176(%rdi) sbbq %rdx, %rcx movq 192(%rsi), %rax movq 192(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 184(%rdi) sbbq %rax, %rdx movq 200(%rsi), %rcx movq 200(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 192(%rdi) sbbq %rcx, %rax movq 208(%rsi), %rdx movq 208(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 200(%rdi) sbbq %rdx, %rcx movq 216(%rsi), %rax movq 216(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 208(%rdi) sbbq %rax, %rdx movq 224(%rsi), %rcx movq 224(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 216(%rdi) sbbq %rcx, %rax movq 232(%rsi), %rdx movq 232(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 224(%rdi) sbbq %rdx, %rcx movq 240(%rsi), %rax movq 240(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 232(%rdi) sbbq %rax, %rdx movq 248(%rsi), %rcx movq 248(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 240(%rdi) sbbq %rcx, %rax movq 256(%rsi), %rdx movq 256(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 248(%rdi) sbbq %rdx, %rcx movq 264(%rsi), %rax movq 264(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 256(%rdi) sbbq %rax, %rdx movq 272(%rsi), %rcx movq 272(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 264(%rdi) sbbq %rcx, %rax movq 280(%rsi), %rdx movq 280(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 272(%rdi) sbbq %rdx, %rcx movq 288(%rsi), %rax movq 288(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 280(%rdi) sbbq %rax, %rdx movq 296(%rsi), %rcx movq 296(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 288(%rdi) sbbq %rcx, %rax movq 304(%rsi), %rdx movq 304(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 296(%rdi) sbbq %rdx, %rcx movq 312(%rsi), %rax movq 312(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 304(%rdi) sbbq %rax, %rdx movq 320(%rsi), %rcx movq 320(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 312(%rdi) sbbq %rcx, %rax movq 328(%rsi), %rdx movq 328(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 320(%rdi) sbbq %rdx, %rcx movq 336(%rsi), %rax movq 336(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 328(%rdi) sbbq %rax, %rdx movq 344(%rsi), %rcx movq 344(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 336(%rdi) sbbq %rcx, %rax movq 352(%rsi), %rdx movq 352(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 344(%rdi) sbbq %rdx, %rcx movq 360(%rsi), %rax movq 360(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 352(%rdi) sbbq %rax, %rdx movq 368(%rsi), %rcx movq 368(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 360(%rdi) sbbq %rcx, %rax movq 376(%rsi), %rdx movq 376(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 368(%rdi) sbbq %rdx, %rcx movq %rcx, 376(%rdi) + popq %rbp + popq %rbx + popq %r15 popq %r14 popq %r13 popq %r12 @@ -27481,6 +27739,7 @@ _sp_3072_cond_add_24: #ifndef __APPLE__ .size sp_3072_cond_add_24,.-sp_3072_cond_add_24 #endif /* __APPLE__ */ +#ifdef HAVE_INTEL_AVX2 /* Conditionally add a and b using the mask m. * m is -1 to add and 0 when not. * @@ -27627,6 +27886,7 @@ _sp_3072_cond_add_avx2_24: #ifndef __APPLE__ .size sp_3072_cond_add_avx2_24,.-sp_3072_cond_add_avx2_24 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ /* Shift number left by n bit. (r = a << n) * * r Result of left shift by n. @@ -27645,155 +27905,164 @@ sp_3072_lshift_48: .p2align 4 _sp_3072_lshift_48: #endif /* __APPLE__ */ + pushq %r12 + pushq %r13 + movq %rdi, %r9 movb %dl, %cl - movq $0x00, %r10 - movq 344(%rsi), %r11 - movq 352(%rsi), %rdx - movq 360(%rsi), %rax - movq 368(%rsi), %r8 - movq 376(%rsi), %r9 - shldq %cl, %r9, %r10 - shldq %cl, %r8, %r9 + movq %rsi, %rdx + movq $0x00, %r12 + movq 344(%rdx), %r13 + movq 352(%rdx), %rax + movq 360(%rdx), %r8 + movq 368(%rdx), %r10 + movq 376(%rdx), %r11 + shldq %cl, %r11, %r12 + shldq %cl, %r10, %r11 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r11, %rdx - movq %rdx, 352(%rdi) - movq %rax, 360(%rdi) - movq %r8, 368(%rdi) - movq %r9, 376(%rdi) - movq %r10, 384(%rdi) - movq 312(%rsi), %r9 - movq 320(%rsi), %rdx - movq 328(%rsi), %rax - movq 336(%rsi), %r8 - shldq %cl, %r8, %r11 + shldq %cl, %r13, %rax + movq %rax, 352(%r9) + movq %r8, 360(%r9) + movq %r10, 368(%r9) + movq %r11, 376(%r9) + movq %r12, 384(%r9) + movq 312(%rdx), %r11 + movq 320(%rdx), %rax + movq 328(%rdx), %r8 + movq 336(%rdx), %r10 + shldq %cl, %r10, %r13 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r9, %rdx - movq %rdx, 320(%rdi) - movq %rax, 328(%rdi) - movq %r8, 336(%rdi) - movq %r11, 344(%rdi) - movq 280(%rsi), %r11 - movq 288(%rsi), %rdx - movq 296(%rsi), %rax - movq 304(%rsi), %r8 - shldq %cl, %r8, %r9 + shldq %cl, %r11, %rax + movq %rax, 320(%r9) + movq %r8, 328(%r9) + movq %r10, 336(%r9) + movq %r13, 344(%r9) + movq 280(%rdx), %r13 + movq 288(%rdx), %rax + movq 296(%rdx), %r8 + movq 304(%rdx), %r10 + shldq %cl, %r10, %r11 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r11, %rdx - movq %rdx, 288(%rdi) - movq %rax, 296(%rdi) - movq %r8, 304(%rdi) - movq %r9, 312(%rdi) - movq 248(%rsi), %r9 - movq 256(%rsi), %rdx - movq 264(%rsi), %rax - movq 272(%rsi), %r8 - shldq %cl, %r8, %r11 + shldq %cl, %r13, %rax + movq %rax, 288(%r9) + movq %r8, 296(%r9) + movq %r10, 304(%r9) + movq %r11, 312(%r9) + movq 248(%rdx), %r11 + movq 256(%rdx), %rax + movq 264(%rdx), %r8 + movq 272(%rdx), %r10 + shldq %cl, %r10, %r13 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r9, %rdx - movq %rdx, 256(%rdi) - movq %rax, 264(%rdi) - movq %r8, 272(%rdi) - movq %r11, 280(%rdi) - movq 216(%rsi), %r11 - movq 224(%rsi), %rdx - movq 232(%rsi), %rax - movq 240(%rsi), %r8 - shldq %cl, %r8, %r9 + shldq %cl, %r11, %rax + movq %rax, 256(%r9) + movq %r8, 264(%r9) + movq %r10, 272(%r9) + movq %r13, 280(%r9) + movq 216(%rdx), %r13 + movq 224(%rdx), %rax + movq 232(%rdx), %r8 + movq 240(%rdx), %r10 + shldq %cl, %r10, %r11 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r11, %rdx - movq %rdx, 224(%rdi) - movq %rax, 232(%rdi) - movq %r8, 240(%rdi) - movq %r9, 248(%rdi) - movq 184(%rsi), %r9 - movq 192(%rsi), %rdx - movq 200(%rsi), %rax - movq 208(%rsi), %r8 - shldq %cl, %r8, %r11 + shldq %cl, %r13, %rax + movq %rax, 224(%r9) + movq %r8, 232(%r9) + movq %r10, 240(%r9) + movq %r11, 248(%r9) + movq 184(%rdx), %r11 + movq 192(%rdx), %rax + movq 200(%rdx), %r8 + movq 208(%rdx), %r10 + shldq %cl, %r10, %r13 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r9, %rdx - movq %rdx, 192(%rdi) - movq %rax, 200(%rdi) - movq %r8, 208(%rdi) - movq %r11, 216(%rdi) - movq 152(%rsi), %r11 - movq 160(%rsi), %rdx - movq 168(%rsi), %rax - movq 176(%rsi), %r8 - shldq %cl, %r8, %r9 + shldq %cl, %r11, %rax + movq %rax, 192(%r9) + movq %r8, 200(%r9) + movq %r10, 208(%r9) + movq %r13, 216(%r9) + movq 152(%rdx), %r13 + movq 160(%rdx), %rax + movq 168(%rdx), %r8 + movq 176(%rdx), %r10 + shldq %cl, %r10, %r11 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r11, %rdx - movq %rdx, 160(%rdi) - movq %rax, 168(%rdi) - movq %r8, 176(%rdi) - movq %r9, 184(%rdi) - movq 120(%rsi), %r9 - movq 128(%rsi), %rdx - movq 136(%rsi), %rax - movq 144(%rsi), %r8 - shldq %cl, %r8, %r11 + shldq %cl, %r13, %rax + movq %rax, 160(%r9) + movq %r8, 168(%r9) + movq %r10, 176(%r9) + movq %r11, 184(%r9) + movq 120(%rdx), %r11 + movq 128(%rdx), %rax + movq 136(%rdx), %r8 + movq 144(%rdx), %r10 + shldq %cl, %r10, %r13 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r9, %rdx - movq %rdx, 128(%rdi) - movq %rax, 136(%rdi) - movq %r8, 144(%rdi) - movq %r11, 152(%rdi) - movq 88(%rsi), %r11 - movq 96(%rsi), %rdx - movq 104(%rsi), %rax - movq 112(%rsi), %r8 - shldq %cl, %r8, %r9 + shldq %cl, %r11, %rax + movq %rax, 128(%r9) + movq %r8, 136(%r9) + movq %r10, 144(%r9) + movq %r13, 152(%r9) + movq 88(%rdx), %r13 + movq 96(%rdx), %rax + movq 104(%rdx), %r8 + movq 112(%rdx), %r10 + shldq %cl, %r10, %r11 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r11, %rdx - movq %rdx, 96(%rdi) - movq %rax, 104(%rdi) - movq %r8, 112(%rdi) - movq %r9, 120(%rdi) - movq 56(%rsi), %r9 - movq 64(%rsi), %rdx - movq 72(%rsi), %rax - movq 80(%rsi), %r8 - shldq %cl, %r8, %r11 + shldq %cl, %r13, %rax + movq %rax, 96(%r9) + movq %r8, 104(%r9) + movq %r10, 112(%r9) + movq %r11, 120(%r9) + movq 56(%rdx), %r11 + movq 64(%rdx), %rax + movq 72(%rdx), %r8 + movq 80(%rdx), %r10 + shldq %cl, %r10, %r13 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r9, %rdx - movq %rdx, 64(%rdi) - movq %rax, 72(%rdi) - movq %r8, 80(%rdi) - movq %r11, 88(%rdi) - movq 24(%rsi), %r11 - movq 32(%rsi), %rdx - movq 40(%rsi), %rax - movq 48(%rsi), %r8 - shldq %cl, %r8, %r9 + shldq %cl, %r11, %rax + movq %rax, 64(%r9) + movq %r8, 72(%r9) + movq %r10, 80(%r9) + movq %r13, 88(%r9) + movq 24(%rdx), %r13 + movq 32(%rdx), %rax + movq 40(%rdx), %r8 + movq 48(%rdx), %r10 + shldq %cl, %r10, %r11 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r11, %rdx - movq %rdx, 32(%rdi) - movq %rax, 40(%rdi) - movq %r8, 48(%rdi) - movq %r9, 56(%rdi) - movq (%rsi), %rdx - movq 8(%rsi), %rax - movq 16(%rsi), %r8 - shldq %cl, %r8, %r11 + shldq %cl, %r13, %rax + movq %rax, 32(%r9) + movq %r8, 40(%r9) + movq %r10, 48(%r9) + movq %r11, 56(%r9) + movq (%rdx), %rax + movq 8(%rdx), %r8 + movq 16(%rdx), %r10 + shldq %cl, %r10, %r13 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shlq %cl, %rdx - movq %rdx, (%rdi) - movq %rax, 8(%rdi) - movq %r8, 16(%rdi) - movq %r11, 24(%rdi) + shlq %cl, %rax + movq %rax, (%r9) + movq %r8, 8(%r9) + movq %r10, 16(%r9) + movq %r13, 24(%r9) + popq %r13 + popq %r12 repz retq +#ifndef __APPLE__ +.size sp_3072_lshift_48,.-sp_3072_lshift_48 +#endif /* __APPLE__ */ #endif /* !WOLFSSL_SP_NO_3072 */ #endif /* !WOLFSSL_SP_NO_3072 */ #ifdef WOLFSSL_SP_4096 @@ -27892,6 +28161,7 @@ L_4096_from_bin_bswap_zero_end: #ifndef __APPLE__ .size sp_4096_from_bin_bswap,.-sp_4096_from_bin_bswap #endif /* __APPLE__ */ +#ifndef NO_MOVBE_SUPPORT /* Read big endian unsigned byte array into r. * Uses the movbe instruction which is an optional instruction. * @@ -27977,6 +28247,7 @@ L_4096_from_bin_movbe_zero_end: #ifndef __APPLE__ .size sp_4096_from_bin_movbe,.-sp_4096_from_bin_movbe #endif /* __APPLE__ */ +#endif /* !NO_MOVBE_SUPPORT */ /* Write r as big endian to byte array. * Fixed length number of bytes written: 512 * Uses the bswap instruction. @@ -28192,6 +28463,7 @@ _sp_4096_to_bin_bswap: #ifndef __APPLE__ .size sp_4096_to_bin_bswap,.-sp_4096_to_bin_bswap #endif /* __APPLE__ */ +#ifndef NO_MOVBE_SUPPORT /* Write r as big endian to byte array. * Fixed length number of bytes written: 512 * Uses the movbe instruction which is optional. @@ -28343,6 +28615,7 @@ _sp_4096_to_bin_movbe: #ifndef __APPLE__ .size sp_4096_to_bin_movbe,.-sp_4096_to_bin_movbe #endif /* __APPLE__ */ +#endif /* NO_MOVBE_SUPPORT */ /* Sub b from a into a. (a -= b) * * a A single precision integer and result. @@ -29031,6 +29304,11 @@ _sp_4096_mul_64: #else callq _sp_2048_mul_32 #endif /* __APPLE__ */ +#ifdef _WIN64 + movq 1552(%rsp), %rdx + movq 1544(%rsp), %rsi + movq 1536(%rsp), %rdi +#endif /* _WIN64 */ movq 1560(%rsp), %r13 movq 1568(%rsp), %r14 movq 1536(%rsp), %r15 @@ -30383,6 +30661,10 @@ _sp_4096_sqr_64: #else callq _sp_2048_sqr_32 #endif /* __APPLE__ */ +#ifdef _WIN64 + movq 1288(%rsp), %rsi + movq 1280(%rsp), %rdi +#endif /* _WIN64 */ movq 1296(%rsp), %r10 leaq 1024(%rsp), %r8 movq %r10, %rcx @@ -31364,6 +31646,7 @@ _sp_4096_sqr_64: #ifndef __APPLE__ .size sp_4096_sqr_64,.-sp_4096_sqr_64 #endif /* __APPLE__ */ +#ifdef HAVE_INTEL_AVX2 /* Multiply a and b into r. (r = a * b) * * r A single precision integer. @@ -31620,6 +31903,11 @@ _sp_4096_mul_avx2_64: #else callq _sp_2048_mul_avx2_32 #endif /* __APPLE__ */ +#ifdef _WIN64 + movq 1552(%rsp), %rdx + movq 1544(%rsp), %rsi + movq 1536(%rsp), %rdi +#endif /* _WIN64 */ movq 1560(%rsp), %r13 movq 1568(%rsp), %r14 movq 1536(%rsp), %r15 @@ -32613,6 +32901,8 @@ _sp_4096_mul_avx2_64: #ifndef __APPLE__ .size sp_4096_mul_avx2_64,.-sp_4096_mul_avx2_64 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +#ifdef HAVE_INTEL_AVX2 /* Square a and put result in r. (r = a * a) * * r A single precision integer. @@ -32757,6 +33047,10 @@ _sp_4096_sqr_avx2_64: #else callq _sp_2048_sqr_avx2_32 #endif /* __APPLE__ */ +#ifdef _WIN64 + movq 1288(%rsp), %rsi + movq 1280(%rsp), %rdi +#endif /* _WIN64 */ movq 1296(%rsp), %r10 leaq 1024(%rsp), %r8 movq %r10, %rcx @@ -33674,6 +33968,7 @@ _sp_4096_sqr_avx2_64: #ifndef __APPLE__ .size sp_4096_sqr_avx2_64,.-sp_4096_sqr_avx2_64 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ /* Mul a by digit b into r. (r = a * b) * * r A single precision integer. @@ -34711,7 +35006,7 @@ _sp_4096_mont_reduce_64: movq $0x40, %r8 movq (%rdi), %r13 movq 8(%rdi), %r14 -L_mont_loop_64: +L_4096_mont_loop_64: # mu = a[i] * mp movq %r13, %r11 imulq %rcx, %r11 @@ -35354,12 +35649,17 @@ L_mont_loop_64: # i -= 1 addq $8, %rdi decq %r8 - jnz L_mont_loop_64 + jnz L_4096_mont_loop_64 movq %r13, (%rdi) movq %r14, 8(%rdi) negq %r15 +#ifdef _WIN64 + movq %rsi, %rdx + movq %r15, %rcx +#else movq %r15, %rcx movq %rsi, %rdx +#endif /* _WIN64 */ movq %rdi, %rsi movq %rdi, %rdi subq $0x200, %rdi @@ -35376,6 +35676,7 @@ L_mont_loop_64: #ifndef __APPLE__ .size sp_4096_mont_reduce_64,.-sp_4096_mont_reduce_64 #endif /* __APPLE__ */ +#ifdef HAVE_INTEL_AVX2 /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -35722,6 +36023,7 @@ _sp_4096_cond_sub_avx2_64: #ifndef __APPLE__ .size sp_4096_cond_sub_avx2_64,.-sp_4096_cond_sub_avx2_64 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ #ifdef HAVE_INTEL_AVX2 /* Mul a by digit b into r. (r = a * b) * @@ -35751,374 +36053,374 @@ _sp_4096_mul_d_avx2_64: mulxq 8(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 8(%rdi) adoxq %r8, %r9 + movq %r10, 8(%rdi) # A[2] * B mulxq 16(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 16(%rdi) adoxq %r8, %r10 + movq %r9, 16(%rdi) # A[3] * B mulxq 24(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 24(%rdi) adoxq %r8, %r9 + movq %r10, 24(%rdi) # A[4] * B mulxq 32(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 32(%rdi) adoxq %r8, %r10 + movq %r9, 32(%rdi) # A[5] * B mulxq 40(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 40(%rdi) adoxq %r8, %r9 + movq %r10, 40(%rdi) # A[6] * B mulxq 48(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 48(%rdi) adoxq %r8, %r10 + movq %r9, 48(%rdi) # A[7] * B mulxq 56(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 56(%rdi) adoxq %r8, %r9 + movq %r10, 56(%rdi) # A[8] * B mulxq 64(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 64(%rdi) adoxq %r8, %r10 + movq %r9, 64(%rdi) # A[9] * B mulxq 72(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 72(%rdi) adoxq %r8, %r9 + movq %r10, 72(%rdi) # A[10] * B mulxq 80(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 80(%rdi) adoxq %r8, %r10 + movq %r9, 80(%rdi) # A[11] * B mulxq 88(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 88(%rdi) adoxq %r8, %r9 + movq %r10, 88(%rdi) # A[12] * B mulxq 96(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 96(%rdi) adoxq %r8, %r10 + movq %r9, 96(%rdi) # A[13] * B mulxq 104(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 104(%rdi) adoxq %r8, %r9 + movq %r10, 104(%rdi) # A[14] * B mulxq 112(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 112(%rdi) adoxq %r8, %r10 + movq %r9, 112(%rdi) # A[15] * B mulxq 120(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 120(%rdi) adoxq %r8, %r9 + movq %r10, 120(%rdi) # A[16] * B mulxq 128(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 128(%rdi) adoxq %r8, %r10 + movq %r9, 128(%rdi) # A[17] * B mulxq 136(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 136(%rdi) adoxq %r8, %r9 + movq %r10, 136(%rdi) # A[18] * B mulxq 144(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 144(%rdi) adoxq %r8, %r10 + movq %r9, 144(%rdi) # A[19] * B mulxq 152(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 152(%rdi) adoxq %r8, %r9 + movq %r10, 152(%rdi) # A[20] * B mulxq 160(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 160(%rdi) adoxq %r8, %r10 + movq %r9, 160(%rdi) # A[21] * B mulxq 168(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 168(%rdi) adoxq %r8, %r9 + movq %r10, 168(%rdi) # A[22] * B mulxq 176(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 176(%rdi) adoxq %r8, %r10 + movq %r9, 176(%rdi) # A[23] * B mulxq 184(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 184(%rdi) adoxq %r8, %r9 + movq %r10, 184(%rdi) # A[24] * B mulxq 192(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 192(%rdi) adoxq %r8, %r10 + movq %r9, 192(%rdi) # A[25] * B mulxq 200(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 200(%rdi) adoxq %r8, %r9 + movq %r10, 200(%rdi) # A[26] * B mulxq 208(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 208(%rdi) adoxq %r8, %r10 + movq %r9, 208(%rdi) # A[27] * B mulxq 216(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 216(%rdi) adoxq %r8, %r9 + movq %r10, 216(%rdi) # A[28] * B mulxq 224(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 224(%rdi) adoxq %r8, %r10 + movq %r9, 224(%rdi) # A[29] * B mulxq 232(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 232(%rdi) adoxq %r8, %r9 + movq %r10, 232(%rdi) # A[30] * B mulxq 240(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 240(%rdi) adoxq %r8, %r10 + movq %r9, 240(%rdi) # A[31] * B mulxq 248(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 248(%rdi) adoxq %r8, %r9 + movq %r10, 248(%rdi) # A[32] * B mulxq 256(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 256(%rdi) adoxq %r8, %r10 + movq %r9, 256(%rdi) # A[33] * B mulxq 264(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 264(%rdi) adoxq %r8, %r9 + movq %r10, 264(%rdi) # A[34] * B mulxq 272(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 272(%rdi) adoxq %r8, %r10 + movq %r9, 272(%rdi) # A[35] * B mulxq 280(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 280(%rdi) adoxq %r8, %r9 + movq %r10, 280(%rdi) # A[36] * B mulxq 288(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 288(%rdi) adoxq %r8, %r10 + movq %r9, 288(%rdi) # A[37] * B mulxq 296(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 296(%rdi) adoxq %r8, %r9 + movq %r10, 296(%rdi) # A[38] * B mulxq 304(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 304(%rdi) adoxq %r8, %r10 + movq %r9, 304(%rdi) # A[39] * B mulxq 312(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 312(%rdi) adoxq %r8, %r9 + movq %r10, 312(%rdi) # A[40] * B mulxq 320(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 320(%rdi) adoxq %r8, %r10 + movq %r9, 320(%rdi) # A[41] * B mulxq 328(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 328(%rdi) adoxq %r8, %r9 + movq %r10, 328(%rdi) # A[42] * B mulxq 336(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 336(%rdi) adoxq %r8, %r10 + movq %r9, 336(%rdi) # A[43] * B mulxq 344(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 344(%rdi) adoxq %r8, %r9 + movq %r10, 344(%rdi) # A[44] * B mulxq 352(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 352(%rdi) adoxq %r8, %r10 + movq %r9, 352(%rdi) # A[45] * B mulxq 360(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 360(%rdi) adoxq %r8, %r9 + movq %r10, 360(%rdi) # A[46] * B mulxq 368(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 368(%rdi) adoxq %r8, %r10 + movq %r9, 368(%rdi) # A[47] * B mulxq 376(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 376(%rdi) adoxq %r8, %r9 + movq %r10, 376(%rdi) # A[48] * B mulxq 384(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 384(%rdi) adoxq %r8, %r10 + movq %r9, 384(%rdi) # A[49] * B mulxq 392(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 392(%rdi) adoxq %r8, %r9 + movq %r10, 392(%rdi) # A[50] * B mulxq 400(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 400(%rdi) adoxq %r8, %r10 + movq %r9, 400(%rdi) # A[51] * B mulxq 408(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 408(%rdi) adoxq %r8, %r9 + movq %r10, 408(%rdi) # A[52] * B mulxq 416(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 416(%rdi) adoxq %r8, %r10 + movq %r9, 416(%rdi) # A[53] * B mulxq 424(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 424(%rdi) adoxq %r8, %r9 + movq %r10, 424(%rdi) # A[54] * B mulxq 432(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 432(%rdi) adoxq %r8, %r10 + movq %r9, 432(%rdi) # A[55] * B mulxq 440(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 440(%rdi) adoxq %r8, %r9 + movq %r10, 440(%rdi) # A[56] * B mulxq 448(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 448(%rdi) adoxq %r8, %r10 + movq %r9, 448(%rdi) # A[57] * B mulxq 456(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 456(%rdi) adoxq %r8, %r9 + movq %r10, 456(%rdi) # A[58] * B mulxq 464(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 464(%rdi) adoxq %r8, %r10 + movq %r9, 464(%rdi) # A[59] * B mulxq 472(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 472(%rdi) adoxq %r8, %r9 + movq %r10, 472(%rdi) # A[60] * B mulxq 480(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 480(%rdi) adoxq %r8, %r10 + movq %r9, 480(%rdi) # A[61] * B mulxq 488(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 488(%rdi) adoxq %r8, %r9 + movq %r10, 488(%rdi) # A[62] * B mulxq 496(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 496(%rdi) adoxq %r8, %r10 + movq %r9, 496(%rdi) # A[63] * B mulxq 504(%rsi), %rcx, %r8 movq %r11, %r9 @@ -36132,6 +36434,35 @@ _sp_4096_mul_d_avx2_64: .size sp_4096_mul_d_avx2_64,.-sp_4096_mul_d_avx2_64 #endif /* __APPLE__ */ #endif /* HAVE_INTEL_AVX2 */ +#ifdef _WIN64 +/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) + * + * d1 The high order half of the number to divide. + * d0 The low order half of the number to divide. + * div The dividend. + * returns the result of the division. + */ +#ifndef __APPLE__ +.text +.globl div_4096_word_asm_64 +.type div_4096_word_asm_64,@function +.align 16 +div_4096_word_asm_64: +#else +.section __TEXT,__text +.globl _div_4096_word_asm_64 +.p2align 4 +_div_4096_word_asm_64: +#endif /* __APPLE__ */ + movq %rdx, %rcx + movq %rsi, %rax + movq %rdi, %rdx + divq %rcx + repz retq +#ifndef __APPLE__ +.size div_4096_word_asm_64,.-div_4096_word_asm_64 +#endif /* __APPLE__ */ +#endif /* _WIN64 */ /* Compare a with b in constant time. * * a A single precision integer. @@ -36910,14 +37241,20 @@ _sp_4096_mont_reduce_avx2_64: pushq %r12 pushq %r13 pushq %r14 + pushq %r15 + pushq %rbx + pushq %rbp movq %rdx, %r8 - xorq %r14, %r14 + xorq %rbp, %rbp # i = 64 movq $0x40, %r9 movq (%rdi), %r13 + movq 8(%rdi), %r14 + movq 16(%rdi), %r15 + movq 24(%rdi), %rbx addq $0x100, %rdi - xorq %r12, %r12 -L_mont_loop_avx2_64: + xorq %rbp, %rbp +L_4096_mont_loop_avx2_64: # mu = a[i] * mp movq %r13, %rdx movq %r13, %r10 @@ -36925,32 +37262,29 @@ L_mont_loop_avx2_64: xorq %r12, %r12 # a[i+0] += m[0] * mu mulxq (%rsi), %rax, %rcx - movq -248(%rdi), %r13 + movq %r14, %r13 adcxq %rax, %r10 adoxq %rcx, %r13 # a[i+1] += m[1] * mu mulxq 8(%rsi), %rax, %rcx - movq -240(%rdi), %r10 + movq %r15, %r14 adcxq %rax, %r13 - adoxq %rcx, %r10 + adoxq %rcx, %r14 # a[i+2] += m[2] * mu mulxq 16(%rsi), %rax, %rcx - movq -232(%rdi), %r11 - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, -240(%rdi) + movq %rbx, %r15 + adcxq %rax, %r14 + adoxq %rcx, %r15 # a[i+3] += m[3] * mu mulxq 24(%rsi), %rax, %rcx - movq -224(%rdi), %r10 - adcxq %rax, %r11 - adoxq %rcx, %r10 - movq %r11, -232(%rdi) + movq -224(%rdi), %rbx + adcxq %rax, %r15 + adoxq %rcx, %rbx # a[i+4] += m[4] * mu mulxq 32(%rsi), %rax, %rcx movq -216(%rdi), %r11 - adcxq %rax, %r10 + adcxq %rax, %rbx adoxq %rcx, %r11 - movq %r10, -224(%rdi) # a[i+5] += m[5] * mu mulxq 40(%rsi), %rax, %rcx movq -208(%rdi), %r10 @@ -37305,340 +37639,343 @@ L_mont_loop_avx2_64: adcxq %rax, %r11 adoxq %rcx, %r10 movq %r11, 248(%rdi) - adcxq %r14, %r10 + adcxq %rbp, %r10 + movq %r12, %rbp movq %r10, 256(%rdi) - movq %r12, %r14 - adoxq %r12, %r14 - adcxq %r12, %r14 + adoxq %r12, %rbp + adcxq %r12, %rbp # a += 1 addq $8, %rdi # i -= 1 subq $0x01, %r9 - jnz L_mont_loop_avx2_64 + jnz L_4096_mont_loop_avx2_64 subq $0x100, %rdi - negq %r14 + negq %rbp movq %rdi, %r8 subq $0x200, %rdi movq (%rsi), %rcx movq %r13, %rdx - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx subq %rcx, %rdx movq 8(%rsi), %rcx - movq 8(%r8), %rax - pextq %r14, %rcx, %rcx + movq %r14, %rax + pextq %rbp, %rcx, %rcx movq %rdx, (%rdi) sbbq %rcx, %rax movq 16(%rsi), %rdx - movq 16(%r8), %rcx - pextq %r14, %rdx, %rdx + movq %r15, %rcx + pextq %rbp, %rdx, %rdx movq %rax, 8(%rdi) sbbq %rdx, %rcx movq 24(%rsi), %rax - movq 24(%r8), %rdx - pextq %r14, %rax, %rax + movq %rbx, %rdx + pextq %rbp, %rax, %rax movq %rcx, 16(%rdi) sbbq %rax, %rdx movq 32(%rsi), %rcx movq 32(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 24(%rdi) sbbq %rcx, %rax movq 40(%rsi), %rdx movq 40(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 32(%rdi) sbbq %rdx, %rcx movq 48(%rsi), %rax movq 48(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 40(%rdi) sbbq %rax, %rdx movq 56(%rsi), %rcx movq 56(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 48(%rdi) sbbq %rcx, %rax movq 64(%rsi), %rdx movq 64(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 56(%rdi) sbbq %rdx, %rcx movq 72(%rsi), %rax movq 72(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 64(%rdi) sbbq %rax, %rdx movq 80(%rsi), %rcx movq 80(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 72(%rdi) sbbq %rcx, %rax movq 88(%rsi), %rdx movq 88(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 80(%rdi) sbbq %rdx, %rcx movq 96(%rsi), %rax movq 96(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 88(%rdi) sbbq %rax, %rdx movq 104(%rsi), %rcx movq 104(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 96(%rdi) sbbq %rcx, %rax movq 112(%rsi), %rdx movq 112(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 104(%rdi) sbbq %rdx, %rcx movq 120(%rsi), %rax movq 120(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 112(%rdi) sbbq %rax, %rdx movq 128(%rsi), %rcx movq 128(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 120(%rdi) sbbq %rcx, %rax movq 136(%rsi), %rdx movq 136(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 128(%rdi) sbbq %rdx, %rcx movq 144(%rsi), %rax movq 144(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 136(%rdi) sbbq %rax, %rdx movq 152(%rsi), %rcx movq 152(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 144(%rdi) sbbq %rcx, %rax movq 160(%rsi), %rdx movq 160(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 152(%rdi) sbbq %rdx, %rcx movq 168(%rsi), %rax movq 168(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 160(%rdi) sbbq %rax, %rdx movq 176(%rsi), %rcx movq 176(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 168(%rdi) sbbq %rcx, %rax movq 184(%rsi), %rdx movq 184(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 176(%rdi) sbbq %rdx, %rcx movq 192(%rsi), %rax movq 192(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 184(%rdi) sbbq %rax, %rdx movq 200(%rsi), %rcx movq 200(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 192(%rdi) sbbq %rcx, %rax movq 208(%rsi), %rdx movq 208(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 200(%rdi) sbbq %rdx, %rcx movq 216(%rsi), %rax movq 216(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 208(%rdi) sbbq %rax, %rdx movq 224(%rsi), %rcx movq 224(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 216(%rdi) sbbq %rcx, %rax movq 232(%rsi), %rdx movq 232(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 224(%rdi) sbbq %rdx, %rcx movq 240(%rsi), %rax movq 240(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 232(%rdi) sbbq %rax, %rdx movq 248(%rsi), %rcx movq 248(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 240(%rdi) sbbq %rcx, %rax movq 256(%rsi), %rdx movq 256(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 248(%rdi) sbbq %rdx, %rcx movq 264(%rsi), %rax movq 264(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 256(%rdi) sbbq %rax, %rdx movq 272(%rsi), %rcx movq 272(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 264(%rdi) sbbq %rcx, %rax movq 280(%rsi), %rdx movq 280(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 272(%rdi) sbbq %rdx, %rcx movq 288(%rsi), %rax movq 288(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 280(%rdi) sbbq %rax, %rdx movq 296(%rsi), %rcx movq 296(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 288(%rdi) sbbq %rcx, %rax movq 304(%rsi), %rdx movq 304(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 296(%rdi) sbbq %rdx, %rcx movq 312(%rsi), %rax movq 312(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 304(%rdi) sbbq %rax, %rdx movq 320(%rsi), %rcx movq 320(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 312(%rdi) sbbq %rcx, %rax movq 328(%rsi), %rdx movq 328(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 320(%rdi) sbbq %rdx, %rcx movq 336(%rsi), %rax movq 336(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 328(%rdi) sbbq %rax, %rdx movq 344(%rsi), %rcx movq 344(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 336(%rdi) sbbq %rcx, %rax movq 352(%rsi), %rdx movq 352(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 344(%rdi) sbbq %rdx, %rcx movq 360(%rsi), %rax movq 360(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 352(%rdi) sbbq %rax, %rdx movq 368(%rsi), %rcx movq 368(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 360(%rdi) sbbq %rcx, %rax movq 376(%rsi), %rdx movq 376(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 368(%rdi) sbbq %rdx, %rcx movq 384(%rsi), %rax movq 384(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 376(%rdi) sbbq %rax, %rdx movq 392(%rsi), %rcx movq 392(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 384(%rdi) sbbq %rcx, %rax movq 400(%rsi), %rdx movq 400(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 392(%rdi) sbbq %rdx, %rcx movq 408(%rsi), %rax movq 408(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 400(%rdi) sbbq %rax, %rdx movq 416(%rsi), %rcx movq 416(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 408(%rdi) sbbq %rcx, %rax movq 424(%rsi), %rdx movq 424(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 416(%rdi) sbbq %rdx, %rcx movq 432(%rsi), %rax movq 432(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 424(%rdi) sbbq %rax, %rdx movq 440(%rsi), %rcx movq 440(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 432(%rdi) sbbq %rcx, %rax movq 448(%rsi), %rdx movq 448(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 440(%rdi) sbbq %rdx, %rcx movq 456(%rsi), %rax movq 456(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 448(%rdi) sbbq %rax, %rdx movq 464(%rsi), %rcx movq 464(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 456(%rdi) sbbq %rcx, %rax movq 472(%rsi), %rdx movq 472(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 464(%rdi) sbbq %rdx, %rcx movq 480(%rsi), %rax movq 480(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 472(%rdi) sbbq %rax, %rdx movq 488(%rsi), %rcx movq 488(%r8), %rax - pextq %r14, %rcx, %rcx + pextq %rbp, %rcx, %rcx movq %rdx, 480(%rdi) sbbq %rcx, %rax movq 496(%rsi), %rdx movq 496(%r8), %rcx - pextq %r14, %rdx, %rdx + pextq %rbp, %rdx, %rdx movq %rax, 488(%rdi) sbbq %rdx, %rcx movq 504(%rsi), %rax movq 504(%r8), %rdx - pextq %r14, %rax, %rax + pextq %rbp, %rax, %rax movq %rcx, 496(%rdi) sbbq %rax, %rdx movq %rdx, 504(%rdi) + popq %rbp + popq %rbx + popq %r15 popq %r14 popq %r13 popq %r12 @@ -37899,6 +38236,7 @@ _sp_4096_cond_add_32: #ifndef __APPLE__ .size sp_4096_cond_add_32,.-sp_4096_cond_add_32 #endif /* __APPLE__ */ +#ifdef HAVE_INTEL_AVX2 /* Conditionally add a and b using the mask m. * m is -1 to add and 0 when not. * @@ -38085,6 +38423,7 @@ _sp_4096_cond_add_avx2_32: #ifndef __APPLE__ .size sp_4096_cond_add_avx2_32,.-sp_4096_cond_add_avx2_32 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ /* Shift number left by n bit. (r = a << n) * * r Result of left shift by n. @@ -38103,206 +38442,550 @@ sp_4096_lshift_64: .p2align 4 _sp_4096_lshift_64: #endif /* __APPLE__ */ + pushq %r12 + pushq %r13 + movq %rdi, %r9 movb %dl, %cl - movq $0x00, %r10 - movq 472(%rsi), %r11 - movq 480(%rsi), %rdx - movq 488(%rsi), %rax - movq 496(%rsi), %r8 - movq 504(%rsi), %r9 - shldq %cl, %r9, %r10 - shldq %cl, %r8, %r9 + movq %rsi, %rdx + movq $0x00, %r12 + movq 472(%rdx), %r13 + movq 480(%rdx), %rax + movq 488(%rdx), %r8 + movq 496(%rdx), %r10 + movq 504(%rdx), %r11 + shldq %cl, %r11, %r12 + shldq %cl, %r10, %r11 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r11, %rdx - movq %rdx, 480(%rdi) - movq %rax, 488(%rdi) - movq %r8, 496(%rdi) - movq %r9, 504(%rdi) - movq %r10, 512(%rdi) - movq 440(%rsi), %r9 - movq 448(%rsi), %rdx - movq 456(%rsi), %rax - movq 464(%rsi), %r8 - shldq %cl, %r8, %r11 + shldq %cl, %r13, %rax + movq %rax, 480(%r9) + movq %r8, 488(%r9) + movq %r10, 496(%r9) + movq %r11, 504(%r9) + movq %r12, 512(%r9) + movq 440(%rdx), %r11 + movq 448(%rdx), %rax + movq 456(%rdx), %r8 + movq 464(%rdx), %r10 + shldq %cl, %r10, %r13 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r9, %rdx - movq %rdx, 448(%rdi) - movq %rax, 456(%rdi) - movq %r8, 464(%rdi) - movq %r11, 472(%rdi) - movq 408(%rsi), %r11 - movq 416(%rsi), %rdx - movq 424(%rsi), %rax - movq 432(%rsi), %r8 - shldq %cl, %r8, %r9 + shldq %cl, %r11, %rax + movq %rax, 448(%r9) + movq %r8, 456(%r9) + movq %r10, 464(%r9) + movq %r13, 472(%r9) + movq 408(%rdx), %r13 + movq 416(%rdx), %rax + movq 424(%rdx), %r8 + movq 432(%rdx), %r10 + shldq %cl, %r10, %r11 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r11, %rdx - movq %rdx, 416(%rdi) - movq %rax, 424(%rdi) - movq %r8, 432(%rdi) - movq %r9, 440(%rdi) - movq 376(%rsi), %r9 - movq 384(%rsi), %rdx - movq 392(%rsi), %rax - movq 400(%rsi), %r8 - shldq %cl, %r8, %r11 + shldq %cl, %r13, %rax + movq %rax, 416(%r9) + movq %r8, 424(%r9) + movq %r10, 432(%r9) + movq %r11, 440(%r9) + movq 376(%rdx), %r11 + movq 384(%rdx), %rax + movq 392(%rdx), %r8 + movq 400(%rdx), %r10 + shldq %cl, %r10, %r13 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r9, %rdx - movq %rdx, 384(%rdi) - movq %rax, 392(%rdi) - movq %r8, 400(%rdi) - movq %r11, 408(%rdi) - movq 344(%rsi), %r11 - movq 352(%rsi), %rdx - movq 360(%rsi), %rax - movq 368(%rsi), %r8 - shldq %cl, %r8, %r9 + shldq %cl, %r11, %rax + movq %rax, 384(%r9) + movq %r8, 392(%r9) + movq %r10, 400(%r9) + movq %r13, 408(%r9) + movq 344(%rdx), %r13 + movq 352(%rdx), %rax + movq 360(%rdx), %r8 + movq 368(%rdx), %r10 + shldq %cl, %r10, %r11 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r11, %rdx - movq %rdx, 352(%rdi) - movq %rax, 360(%rdi) - movq %r8, 368(%rdi) - movq %r9, 376(%rdi) - movq 312(%rsi), %r9 - movq 320(%rsi), %rdx - movq 328(%rsi), %rax - movq 336(%rsi), %r8 - shldq %cl, %r8, %r11 + shldq %cl, %r13, %rax + movq %rax, 352(%r9) + movq %r8, 360(%r9) + movq %r10, 368(%r9) + movq %r11, 376(%r9) + movq 312(%rdx), %r11 + movq 320(%rdx), %rax + movq 328(%rdx), %r8 + movq 336(%rdx), %r10 + shldq %cl, %r10, %r13 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r9, %rdx - movq %rdx, 320(%rdi) - movq %rax, 328(%rdi) - movq %r8, 336(%rdi) - movq %r11, 344(%rdi) - movq 280(%rsi), %r11 - movq 288(%rsi), %rdx - movq 296(%rsi), %rax - movq 304(%rsi), %r8 - shldq %cl, %r8, %r9 + shldq %cl, %r11, %rax + movq %rax, 320(%r9) + movq %r8, 328(%r9) + movq %r10, 336(%r9) + movq %r13, 344(%r9) + movq 280(%rdx), %r13 + movq 288(%rdx), %rax + movq 296(%rdx), %r8 + movq 304(%rdx), %r10 + shldq %cl, %r10, %r11 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r11, %rdx - movq %rdx, 288(%rdi) - movq %rax, 296(%rdi) - movq %r8, 304(%rdi) - movq %r9, 312(%rdi) - movq 248(%rsi), %r9 - movq 256(%rsi), %rdx - movq 264(%rsi), %rax - movq 272(%rsi), %r8 - shldq %cl, %r8, %r11 + shldq %cl, %r13, %rax + movq %rax, 288(%r9) + movq %r8, 296(%r9) + movq %r10, 304(%r9) + movq %r11, 312(%r9) + movq 248(%rdx), %r11 + movq 256(%rdx), %rax + movq 264(%rdx), %r8 + movq 272(%rdx), %r10 + shldq %cl, %r10, %r13 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r9, %rdx - movq %rdx, 256(%rdi) - movq %rax, 264(%rdi) - movq %r8, 272(%rdi) - movq %r11, 280(%rdi) - movq 216(%rsi), %r11 - movq 224(%rsi), %rdx - movq 232(%rsi), %rax - movq 240(%rsi), %r8 - shldq %cl, %r8, %r9 + shldq %cl, %r11, %rax + movq %rax, 256(%r9) + movq %r8, 264(%r9) + movq %r10, 272(%r9) + movq %r13, 280(%r9) + movq 216(%rdx), %r13 + movq 224(%rdx), %rax + movq 232(%rdx), %r8 + movq 240(%rdx), %r10 + shldq %cl, %r10, %r11 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r11, %rdx - movq %rdx, 224(%rdi) - movq %rax, 232(%rdi) - movq %r8, 240(%rdi) - movq %r9, 248(%rdi) - movq 184(%rsi), %r9 - movq 192(%rsi), %rdx - movq 200(%rsi), %rax - movq 208(%rsi), %r8 - shldq %cl, %r8, %r11 + shldq %cl, %r13, %rax + movq %rax, 224(%r9) + movq %r8, 232(%r9) + movq %r10, 240(%r9) + movq %r11, 248(%r9) + movq 184(%rdx), %r11 + movq 192(%rdx), %rax + movq 200(%rdx), %r8 + movq 208(%rdx), %r10 + shldq %cl, %r10, %r13 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r9, %rdx - movq %rdx, 192(%rdi) - movq %rax, 200(%rdi) - movq %r8, 208(%rdi) - movq %r11, 216(%rdi) - movq 152(%rsi), %r11 - movq 160(%rsi), %rdx - movq 168(%rsi), %rax - movq 176(%rsi), %r8 - shldq %cl, %r8, %r9 + shldq %cl, %r11, %rax + movq %rax, 192(%r9) + movq %r8, 200(%r9) + movq %r10, 208(%r9) + movq %r13, 216(%r9) + movq 152(%rdx), %r13 + movq 160(%rdx), %rax + movq 168(%rdx), %r8 + movq 176(%rdx), %r10 + shldq %cl, %r10, %r11 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r11, %rdx - movq %rdx, 160(%rdi) - movq %rax, 168(%rdi) - movq %r8, 176(%rdi) - movq %r9, 184(%rdi) - movq 120(%rsi), %r9 - movq 128(%rsi), %rdx - movq 136(%rsi), %rax - movq 144(%rsi), %r8 - shldq %cl, %r8, %r11 + shldq %cl, %r13, %rax + movq %rax, 160(%r9) + movq %r8, 168(%r9) + movq %r10, 176(%r9) + movq %r11, 184(%r9) + movq 120(%rdx), %r11 + movq 128(%rdx), %rax + movq 136(%rdx), %r8 + movq 144(%rdx), %r10 + shldq %cl, %r10, %r13 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r9, %rdx - movq %rdx, 128(%rdi) - movq %rax, 136(%rdi) - movq %r8, 144(%rdi) - movq %r11, 152(%rdi) - movq 88(%rsi), %r11 - movq 96(%rsi), %rdx - movq 104(%rsi), %rax - movq 112(%rsi), %r8 - shldq %cl, %r8, %r9 + shldq %cl, %r11, %rax + movq %rax, 128(%r9) + movq %r8, 136(%r9) + movq %r10, 144(%r9) + movq %r13, 152(%r9) + movq 88(%rdx), %r13 + movq 96(%rdx), %rax + movq 104(%rdx), %r8 + movq 112(%rdx), %r10 + shldq %cl, %r10, %r11 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r11, %rdx - movq %rdx, 96(%rdi) - movq %rax, 104(%rdi) - movq %r8, 112(%rdi) - movq %r9, 120(%rdi) - movq 56(%rsi), %r9 - movq 64(%rsi), %rdx - movq 72(%rsi), %rax - movq 80(%rsi), %r8 - shldq %cl, %r8, %r11 + shldq %cl, %r13, %rax + movq %rax, 96(%r9) + movq %r8, 104(%r9) + movq %r10, 112(%r9) + movq %r11, 120(%r9) + movq 56(%rdx), %r11 + movq 64(%rdx), %rax + movq 72(%rdx), %r8 + movq 80(%rdx), %r10 + shldq %cl, %r10, %r13 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r9, %rdx - movq %rdx, 64(%rdi) - movq %rax, 72(%rdi) - movq %r8, 80(%rdi) - movq %r11, 88(%rdi) - movq 24(%rsi), %r11 - movq 32(%rsi), %rdx - movq 40(%rsi), %rax - movq 48(%rsi), %r8 - shldq %cl, %r8, %r9 + shldq %cl, %r11, %rax + movq %rax, 64(%r9) + movq %r8, 72(%r9) + movq %r10, 80(%r9) + movq %r13, 88(%r9) + movq 24(%rdx), %r13 + movq 32(%rdx), %rax + movq 40(%rdx), %r8 + movq 48(%rdx), %r10 + shldq %cl, %r10, %r11 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shldq %cl, %r11, %rdx - movq %rdx, 32(%rdi) - movq %rax, 40(%rdi) - movq %r8, 48(%rdi) - movq %r9, 56(%rdi) - movq (%rsi), %rdx - movq 8(%rsi), %rax - movq 16(%rsi), %r8 - shldq %cl, %r8, %r11 + shldq %cl, %r13, %rax + movq %rax, 32(%r9) + movq %r8, 40(%r9) + movq %r10, 48(%r9) + movq %r11, 56(%r9) + movq (%rdx), %rax + movq 8(%rdx), %r8 + movq 16(%rdx), %r10 + shldq %cl, %r10, %r13 + shldq %cl, %r8, %r10 shldq %cl, %rax, %r8 - shldq %cl, %rdx, %rax - shlq %cl, %rdx - movq %rdx, (%rdi) - movq %rax, 8(%rdi) - movq %r8, 16(%rdi) - movq %r11, 24(%rdi) + shlq %cl, %rax + movq %rax, (%r9) + movq %r8, 8(%r9) + movq %r10, 16(%r9) + movq %r13, 24(%r9) + popq %r13 + popq %r12 repz retq +#ifndef __APPLE__ +.size sp_4096_lshift_64,.-sp_4096_lshift_64 +#endif /* __APPLE__ */ #endif /* WOLFSSL_SP_4096 */ #endif /* WOLFSSL_SP_4096 */ #ifndef WOLFSSL_SP_NO_256 +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +#ifndef __APPLE__ +.text +.globl sp_256_mul_4 +.type sp_256_mul_4,@function +.align 16 +sp_256_mul_4: +#else +.section __TEXT,__text +.globl _sp_256_mul_4 +.p2align 4 +_sp_256_mul_4: +#endif /* __APPLE__ */ + movq %rdx, %rcx + subq $32, %rsp + # A[0] * B[0] + movq (%rcx), %rax + mulq (%rsi) + xorq %r10, %r10 + movq %rax, (%rsp) + movq %rdx, %r9 + # A[0] * B[1] + movq 8(%rcx), %rax + mulq (%rsi) + xorq %r8, %r8 + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[1] * B[0] + movq (%rcx), %rax + mulq 8(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + movq %r9, 8(%rsp) + # A[0] * B[2] + movq 16(%rcx), %rax + mulq (%rsi) + xorq %r9, %r9 + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[1] * B[1] + movq 8(%rcx), %rax + mulq 8(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[2] * B[0] + movq (%rcx), %rax + mulq 16(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + movq %r10, 16(%rsp) + # A[0] * B[3] + movq 24(%rcx), %rax + mulq (%rsi) + xorq %r10, %r10 + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[1] * B[2] + movq 16(%rcx), %rax + mulq 8(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[2] * B[1] + movq 8(%rcx), %rax + mulq 16(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[3] * B[0] + movq (%rcx), %rax + mulq 24(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + movq %r8, 24(%rsp) + # A[1] * B[3] + movq 24(%rcx), %rax + mulq 8(%rsi) + xorq %r8, %r8 + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[2] * B[2] + movq 16(%rcx), %rax + mulq 16(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[3] * B[1] + movq 8(%rcx), %rax + mulq 24(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + movq %r9, 32(%rdi) + # A[2] * B[3] + movq 24(%rcx), %rax + mulq 16(%rsi) + xorq %r9, %r9 + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[3] * B[2] + movq 16(%rcx), %rax + mulq 24(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + movq %r10, 40(%rdi) + # A[3] * B[3] + movq 24(%rcx), %rax + mulq 24(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + movq %r8, 48(%rdi) + movq %r9, 56(%rdi) + movq (%rsp), %rax + movq 8(%rsp), %rdx + movq 16(%rsp), %r8 + movq 24(%rsp), %r9 + movq %rax, (%rdi) + movq %rdx, 8(%rdi) + movq %r8, 16(%rdi) + movq %r9, 24(%rdi) + addq $32, %rsp + repz retq +#ifndef __APPLE__ +.size sp_256_mul_4,.-sp_256_mul_4 +#endif /* __APPLE__ */ +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +#ifndef __APPLE__ +.text +.globl sp_256_sqr_4 +.type sp_256_sqr_4,@function +.align 16 +sp_256_sqr_4: +#else +.section __TEXT,__text +.globl _sp_256_sqr_4 +.p2align 4 +_sp_256_sqr_4: +#endif /* __APPLE__ */ + pushq %r12 + subq $32, %rsp + # A[0] * A[0] + movq (%rsi), %rax + mulq %rax + xorq %r9, %r9 + movq %rax, (%rsp) + movq %rdx, %r8 + # A[0] * A[1] + movq 8(%rsi), %rax + mulq (%rsi) + xorq %rcx, %rcx + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %rcx + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %rcx + movq %r8, 8(%rsp) + # A[0] * A[2] + movq 16(%rsi), %rax + mulq (%rsi) + xorq %r8, %r8 + addq %rax, %r9 + adcq %rdx, %rcx + adcq $0x00, %r8 + addq %rax, %r9 + adcq %rdx, %rcx + adcq $0x00, %r8 + # A[1] * A[1] + movq 8(%rsi), %rax + mulq %rax + addq %rax, %r9 + adcq %rdx, %rcx + adcq $0x00, %r8 + movq %r9, 16(%rsp) + # A[0] * A[3] + movq 24(%rsi), %rax + mulq (%rsi) + xorq %r9, %r9 + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0x00, %r9 + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[1] * A[2] + movq 16(%rsi), %rax + mulq 8(%rsi) + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0x00, %r9 + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0x00, %r9 + movq %rcx, 24(%rsp) + # A[1] * A[3] + movq 24(%rsi), %rax + mulq 8(%rsi) + xorq %rcx, %rcx + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %rcx + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %rcx + # A[2] * A[2] + movq 16(%rsi), %rax + mulq %rax + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %rcx + movq %r8, 32(%rdi) + # A[2] * A[3] + movq 24(%rsi), %rax + mulq 16(%rsi) + xorq %r8, %r8 + addq %rax, %r9 + adcq %rdx, %rcx + adcq $0x00, %r8 + addq %rax, %r9 + adcq %rdx, %rcx + adcq $0x00, %r8 + movq %r9, 40(%rdi) + # A[3] * A[3] + movq 24(%rsi), %rax + mulq %rax + addq %rax, %rcx + adcq %rdx, %r8 + movq %rcx, 48(%rdi) + movq %r8, 56(%rdi) + movq (%rsp), %rax + movq 8(%rsp), %rdx + movq 16(%rsp), %r10 + movq 24(%rsp), %r11 + movq %rax, (%rdi) + movq %rdx, 8(%rdi) + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + addq $32, %rsp + popq %r12 + repz retq +#ifndef __APPLE__ +.size sp_256_sqr_4,.-sp_256_sqr_4 +#endif /* __APPLE__ */ +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +#ifndef __APPLE__ +.text +.globl sp_256_add_4 +.type sp_256_add_4,@function +.align 16 +sp_256_add_4: +#else +.section __TEXT,__text +.globl _sp_256_add_4 +.p2align 4 +_sp_256_add_4: +#endif /* __APPLE__ */ + # Add + movq (%rsi), %rcx + xorq %rax, %rax + addq (%rdx), %rcx + movq 8(%rsi), %r8 + movq %rcx, (%rdi) + adcq 8(%rdx), %r8 + movq 16(%rsi), %rcx + movq %r8, 8(%rdi) + adcq 16(%rdx), %rcx + movq 24(%rsi), %r8 + movq %rcx, 16(%rdi) + adcq 24(%rdx), %r8 + movq %r8, 24(%rdi) + adcq $0x00, %rax + repz retq +#ifndef __APPLE__ +.size sp_256_add_4,.-sp_256_add_4 +#endif /* __APPLE__ */ +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +#ifndef __APPLE__ +.text +.globl sp_256_sub_4 +.type sp_256_sub_4,@function +.align 16 +sp_256_sub_4: +#else +.section __TEXT,__text +.globl _sp_256_sub_4 +.p2align 4 +_sp_256_sub_4: +#endif /* __APPLE__ */ + xorq %rax, %rax + movq (%rsi), %rcx + movq 8(%rsi), %r8 + movq 16(%rsi), %r9 + movq 24(%rsi), %r10 + subq (%rdx), %rcx + sbbq 8(%rdx), %r8 + sbbq 16(%rdx), %r9 + sbbq 24(%rdx), %r10 + movq %rcx, (%rdi) + movq %r8, 8(%rdi) + movq %r9, 16(%rdi) + movq %r10, 24(%rdi) + sbbq $0x00, %rax + repz retq +#ifndef __APPLE__ +.size sp_256_sub_4,.-sp_256_sub_4 +#endif /* __APPLE__ */ /* Conditionally copy a into r using the mask m. * m is -1 to copy and 0 when not. * @@ -38842,42 +39525,6 @@ _sp_256_cond_sub_4: #ifndef __APPLE__ .size sp_256_cond_sub_4,.-sp_256_cond_sub_4 #endif /* __APPLE__ */ -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -#ifndef __APPLE__ -.text -.globl sp_256_sub_4 -.type sp_256_sub_4,@function -.align 16 -sp_256_sub_4: -#else -.section __TEXT,__text -.globl _sp_256_sub_4 -.p2align 4 -_sp_256_sub_4: -#endif /* __APPLE__ */ - xorq %rax, %rax - movq (%rsi), %rcx - movq 8(%rsi), %r8 - movq 16(%rsi), %r9 - movq 24(%rsi), %r10 - subq (%rdx), %rcx - sbbq 8(%rdx), %r8 - sbbq 16(%rdx), %r9 - sbbq 24(%rdx), %r10 - movq %rcx, (%rdi) - movq %r8, 8(%rdi) - movq %r9, 16(%rdi) - movq %r10, 24(%rdi) - sbbq $0x00, %rax - repz retq -#ifndef __APPLE__ -.size sp_256_sub_4,.-sp_256_sub_4 -#endif /* __APPLE__ */ /* Reduce the number back to 256 bits using Montgomery reduction. * * a A single precision number to reduce in place. @@ -39329,6 +39976,7 @@ L_256_get_point_33_4_start: #ifndef __APPLE__ .size sp_256_get_point_33_4,.-sp_256_get_point_33_4 #endif /* __APPLE__ */ +#ifdef HAVE_INTEL_AVX2 /* Touch each possible point that could be being copied. * * r Point to copy into. @@ -39362,9 +40010,9 @@ _sp_256_get_point_33_avx2_4: L_256_get_point_33_avx2_4_start: vpcmpeqd %ymm7, %ymm8, %ymm6 vpaddd %ymm9, %ymm8, %ymm8 - vmovdqu (%rsi), %ymm3 - vmovdqu 64(%rsi), %ymm4 - vmovdqu 128(%rsi), %ymm5 + vmovupd (%rsi), %ymm3 + vmovupd 64(%rsi), %ymm4 + vmovupd 128(%rsi), %ymm5 addq $0xc8, %rsi vpand %ymm6, %ymm3, %ymm3 vpand %ymm6, %ymm4, %ymm4 @@ -39374,14 +40022,16 @@ L_256_get_point_33_avx2_4_start: vpor %ymm5, %ymm2, %ymm2 decq %rax jnz L_256_get_point_33_avx2_4_start - vmovdqu %ymm0, (%rdi) - vmovdqu %ymm1, 64(%rdi) - vmovdqu %ymm2, 128(%rdi) + vmovupd %ymm0, (%rdi) + vmovupd %ymm1, 64(%rdi) + vmovupd %ymm2, 128(%rdi) repz retq #ifndef __APPLE__ .size sp_256_get_point_33_avx2_4,.-sp_256_get_point_33_avx2_4 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ #endif /* !WC_NO_CACHE_RESISTANT */ +#ifdef HAVE_INTEL_AVX2 /* Multiply two Montogmery form numbers mod the modulus (prime). * (r = a * b mod m) * @@ -39404,11 +40054,11 @@ sp_256_mont_mul_avx2_4: _sp_256_mont_mul_avx2_4: #endif /* __APPLE__ */ pushq %rbx - pushq %rbp pushq %r12 pushq %r13 pushq %r14 pushq %r15 + pushq %rbp movq %rdx, %rbp # A[0] * B[0] movq (%rbp), %rdx @@ -39557,16 +40207,18 @@ _sp_256_mont_mul_avx2_4: movq %r13, 8(%rdi) movq %r14, 16(%rdi) movq %r15, 24(%rdi) + popq %rbp popq %r15 popq %r14 popq %r13 popq %r12 - popq %rbp popq %rbx repz retq #ifndef __APPLE__ .size sp_256_mont_mul_avx2_4,.-sp_256_mont_mul_avx2_4 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +#ifdef HAVE_INTEL_AVX2 /* Square the Montgomery form number mod the modulus (prime). (r = a * a mod m) * * r Result of squaring. @@ -39725,6 +40377,276 @@ _sp_256_mont_sqr_avx2_4: #ifndef __APPLE__ .size sp_256_mont_sqr_avx2_4,.-sp_256_mont_sqr_avx2_4 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +#ifdef HAVE_INTEL_AVX2 +/* Conditionally subtract b from a using the mask m. + * m is -1 to subtract and 0 when not copying. + * + * r A single precision number representing condition subtract result. + * a A single precision number to subtract from. + * b A single precision number to subtract. + * m Mask value to apply. + */ +#ifndef __APPLE__ +.text +.globl sp_256_cond_sub_avx2_4 +.type sp_256_cond_sub_avx2_4,@function +.align 16 +sp_256_cond_sub_avx2_4: +#else +.section __TEXT,__text +.globl _sp_256_cond_sub_avx2_4 +.p2align 4 +_sp_256_cond_sub_avx2_4: +#endif /* __APPLE__ */ + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + movq $0x00, %rax + movq (%rdx), %r12 + movq 8(%rdx), %r13 + movq 16(%rdx), %r14 + movq 24(%rdx), %r15 + andq %rcx, %r12 + andq %rcx, %r13 + andq %rcx, %r14 + andq %rcx, %r15 + movq (%rsi), %r8 + movq 8(%rsi), %r9 + movq 16(%rsi), %r10 + movq 24(%rsi), %r11 + subq %r12, %r8 + sbbq %r13, %r9 + sbbq %r14, %r10 + sbbq %r15, %r11 + movq %r8, (%rdi) + movq %r9, 8(%rdi) + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + sbbq $0x00, %rax + popq %r15 + popq %r14 + popq %r13 + popq %r12 + repz retq +#ifndef __APPLE__ +.size sp_256_cond_sub_avx2_4,.-sp_256_cond_sub_avx2_4 +#endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +#ifdef HAVE_INTEL_AVX2 +/* Reduce the number back to 256 bits using Montgomery reduction. + * + * a A single precision number to reduce in place. + * m The single precision number representing the modulus. + * mp The digit representing the negative inverse of m mod 2^n. + */ +#ifndef __APPLE__ +.text +.globl sp_256_mont_reduce_avx2_4 +.type sp_256_mont_reduce_avx2_4,@function +.align 16 +sp_256_mont_reduce_avx2_4: +#else +.section __TEXT,__text +.globl _sp_256_mont_reduce_avx2_4 +.p2align 4 +_sp_256_mont_reduce_avx2_4: +#endif /* __APPLE__ */ + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + pushq %rbx + movq %rdx, %rax + movq (%rdi), %r12 + movq 8(%rdi), %r13 + movq 16(%rdi), %r14 + movq 24(%rdi), %r15 + xorq %r11, %r11 + xorq %r10, %r10 + # a[0-4] += m[0-3] * mu = m[0-3] * (a[0] * mp) + movq 32(%rdi), %rbx + # mu = a[0] * mp + movq %r12, %rdx + mulxq %rax, %rdx, %rcx + # a[0] += m[0] * mu + mulx (%rsi), %r8, %r9 + adcxq %r8, %r12 + # a[1] += m[1] * mu + mulx 8(%rsi), %r8, %rcx + adoxq %r9, %r13 + adcxq %r8, %r13 + # a[2] += m[2] * mu + mulx 16(%rsi), %r8, %r9 + adoxq %rcx, %r14 + adcxq %r8, %r14 + # a[3] += m[3] * mu + mulx 24(%rsi), %r8, %rcx + adoxq %r9, %r15 + adcxq %r8, %r15 + # a[4] += carry + adoxq %rcx, %rbx + adcxq %r10, %rbx + # carry + adoxq %r10, %r11 + adcxq %r10, %r11 + # a[1-5] += m[0-3] * mu = m[0-3] * (a[1] * mp) + movq 40(%rdi), %r12 + # mu = a[1] * mp + movq %r13, %rdx + mulxq %rax, %rdx, %rcx + # a[1] += m[0] * mu + mulx (%rsi), %r8, %r9 + adcxq %r8, %r13 + # a[2] += m[1] * mu + mulx 8(%rsi), %r8, %rcx + adoxq %r9, %r14 + adcxq %r8, %r14 + # a[3] += m[2] * mu + mulx 16(%rsi), %r8, %r9 + adoxq %rcx, %r15 + adcxq %r8, %r15 + # a[4] += m[3] * mu + mulx 24(%rsi), %r8, %rcx + adoxq %r9, %rbx + adcxq %r8, %rbx + # a[5] += carry + adoxq %rcx, %r12 + adcxq %r11, %r12 + movq %r10, %r11 + # carry + adoxq %r10, %r11 + adcxq %r10, %r11 + # a[2-6] += m[0-3] * mu = m[0-3] * (a[2] * mp) + movq 48(%rdi), %r13 + # mu = a[2] * mp + movq %r14, %rdx + mulxq %rax, %rdx, %rcx + # a[2] += m[0] * mu + mulx (%rsi), %r8, %r9 + adcxq %r8, %r14 + # a[3] += m[1] * mu + mulx 8(%rsi), %r8, %rcx + adoxq %r9, %r15 + adcxq %r8, %r15 + # a[4] += m[2] * mu + mulx 16(%rsi), %r8, %r9 + adoxq %rcx, %rbx + adcxq %r8, %rbx + # a[5] += m[3] * mu + mulx 24(%rsi), %r8, %rcx + adoxq %r9, %r12 + adcxq %r8, %r12 + # a[6] += carry + adoxq %rcx, %r13 + adcxq %r11, %r13 + movq %r10, %r11 + # carry + adoxq %r10, %r11 + adcxq %r10, %r11 + # a[3-7] += m[0-3] * mu = m[0-3] * (a[3] * mp) + movq 56(%rdi), %r14 + # mu = a[3] * mp + movq %r15, %rdx + mulxq %rax, %rdx, %rcx + # a[3] += m[0] * mu + mulx (%rsi), %r8, %r9 + adcxq %r8, %r15 + # a[4] += m[1] * mu + mulx 8(%rsi), %r8, %rcx + adoxq %r9, %rbx + adcxq %r8, %rbx + # a[5] += m[2] * mu + mulx 16(%rsi), %r8, %r9 + adoxq %rcx, %r12 + adcxq %r8, %r12 + # a[6] += m[3] * mu + mulx 24(%rsi), %r8, %rcx + adoxq %r9, %r13 + adcxq %r8, %r13 + # a[7] += carry + adoxq %rcx, %r14 + adcxq %r11, %r14 + movq %r10, %r11 + # carry + adoxq %r10, %r11 + adcxq %r10, %r11 + # Subtract mod if carry + negq %r11 + movq $0xf3b9cac2fc632551, %r8 + movq $0xbce6faada7179e84, %r9 + movq $0xffffffff00000000, %rdx + andq %r11, %r8 + andq %r11, %r9 + andq %r11, %rdx + subq %r8, %rbx + sbbq %r9, %r12 + sbbq %r11, %r13 + sbbq %rdx, %r14 + movq %rbx, (%rdi) + movq %r12, 8(%rdi) + movq %r13, 16(%rdi) + movq %r14, 24(%rdi) + popq %rbx + popq %r15 + popq %r14 + popq %r13 + popq %r12 + repz retq +#ifndef __APPLE__ +.size sp_256_mont_reduce_avx2_4,.-sp_256_mont_reduce_avx2_4 +#endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +#ifdef HAVE_INTEL_AVX2 +/* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m) + * + * r Result of division by 2. + * a Number to divide. + * m Modulus (prime). + */ +#ifndef __APPLE__ +.text +.globl sp_256_div2_avx2_4 +.type sp_256_div2_avx2_4,@function +.align 16 +sp_256_div2_avx2_4: +#else +.section __TEXT,__text +.globl _sp_256_div2_avx2_4 +.p2align 4 +_sp_256_div2_avx2_4: +#endif /* __APPLE__ */ + movq (%rsi), %rdx + movq 8(%rsi), %rax + movq 16(%rsi), %rcx + movq 24(%rsi), %r8 + movq $0xffffffff, %r9 + movq $0xffffffff00000001, %r10 + movq %rdx, %r11 + andq $0x01, %r11 + negq %r11 + andq %r11, %r9 + andq %r11, %r10 + addq %r11, %rdx + adcq %r9, %rax + adcq $0x00, %rcx + adcq %r10, %r8 + movq $0x00, %r11 + adcq $0x00, %r11 + shrdq $0x01, %rax, %rdx + shrdq $0x01, %rcx, %rax + shrdq $0x01, %r8, %rcx + shrdq $0x01, %r11, %r8 + movq %rdx, (%rdi) + movq %rax, 8(%rdi) + movq %rcx, 16(%rdi) + movq %r8, 24(%rdi) + repz retq +#ifndef __APPLE__ +.size sp_256_div2_avx2_4,.-sp_256_div2_avx2_4 +#endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ #ifndef WC_NO_CACHE_RESISTANT /* Touch each possible entry that could be being copied. * @@ -39761,10 +40683,10 @@ L_256_get_entry_64_4_start: movdqa %xmm10, %xmm8 paddd %xmm11, %xmm10 pcmpeqd %xmm9, %xmm8 - movdqa (%rsi), %xmm4 - movdqa 16(%rsi), %xmm5 - movdqa 32(%rsi), %xmm6 - movdqa 48(%rsi), %xmm7 + movdqu (%rsi), %xmm4 + movdqu 16(%rsi), %xmm5 + movdqu 32(%rsi), %xmm6 + movdqu 48(%rsi), %xmm7 addq $0x40, %rsi pand %xmm8, %xmm4 pand %xmm8, %xmm5 @@ -39784,6 +40706,7 @@ L_256_get_entry_64_4_start: #ifndef __APPLE__ .size sp_256_get_entry_64_4,.-sp_256_get_entry_64_4 #endif /* __APPLE__ */ +#ifdef HAVE_INTEL_AVX2 /* Touch each possible entry that could be being copied. * * r Point to copy into. @@ -39816,8 +40739,8 @@ _sp_256_get_entry_64_avx2_4: L_256_get_entry_64_avx2_4_start: vpcmpeqd %ymm5, %ymm6, %ymm4 vpaddd %ymm7, %ymm6, %ymm6 - vmovdqu (%rsi), %ymm2 - vmovdqu 32(%rsi), %ymm3 + vmovupd (%rsi), %ymm2 + vmovupd 32(%rsi), %ymm3 addq $0x40, %rsi vpand %ymm4, %ymm2, %ymm2 vpand %ymm4, %ymm3, %ymm3 @@ -39825,12 +40748,13 @@ L_256_get_entry_64_avx2_4_start: vpor %ymm3, %ymm1, %ymm1 decq %rax jnz L_256_get_entry_64_avx2_4_start - vmovdqu %ymm0, (%rdi) - vmovdqu %ymm1, 64(%rdi) + vmovupd %ymm0, (%rdi) + vmovupd %ymm1, 64(%rdi) repz retq #ifndef __APPLE__ .size sp_256_get_entry_64_avx2_4,.-sp_256_get_entry_64_avx2_4 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ #endif /* !WC_NO_CACHE_RESISTANT */ #ifndef WC_NO_CACHE_RESISTANT /* Touch each possible entry that could be being copied. @@ -39868,10 +40792,10 @@ L_256_get_entry_65_4_start: movdqa %xmm10, %xmm8 paddd %xmm11, %xmm10 pcmpeqd %xmm9, %xmm8 - movdqa (%rsi), %xmm4 - movdqa 16(%rsi), %xmm5 - movdqa 32(%rsi), %xmm6 - movdqa 48(%rsi), %xmm7 + movdqu (%rsi), %xmm4 + movdqu 16(%rsi), %xmm5 + movdqu 32(%rsi), %xmm6 + movdqu 48(%rsi), %xmm7 addq $0x40, %rsi pand %xmm8, %xmm4 pand %xmm8, %xmm5 @@ -39891,6 +40815,7 @@ L_256_get_entry_65_4_start: #ifndef __APPLE__ .size sp_256_get_entry_65_4,.-sp_256_get_entry_65_4 #endif /* __APPLE__ */ +#ifdef HAVE_INTEL_AVX2 /* Touch each possible entry that could be being copied. * * r Point to copy into. @@ -39923,8 +40848,8 @@ _sp_256_get_entry_65_avx2_4: L_256_get_entry_65_avx2_4_start: vpcmpeqd %ymm5, %ymm6, %ymm4 vpaddd %ymm7, %ymm6, %ymm6 - vmovdqu (%rsi), %ymm2 - vmovdqu 32(%rsi), %ymm3 + vmovupd (%rsi), %ymm2 + vmovupd 32(%rsi), %ymm3 addq $0x40, %rsi vpand %ymm4, %ymm2, %ymm2 vpand %ymm4, %ymm3, %ymm3 @@ -39932,12 +40857,13 @@ L_256_get_entry_65_avx2_4_start: vpor %ymm3, %ymm1, %ymm1 decq %rax jnz L_256_get_entry_65_avx2_4_start - vmovdqu %ymm0, (%rdi) - vmovdqu %ymm1, 64(%rdi) + vmovupd %ymm0, (%rdi) + vmovupd %ymm1, 64(%rdi) repz retq #ifndef __APPLE__ .size sp_256_get_entry_65_avx2_4,.-sp_256_get_entry_65_avx2_4 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ #endif /* !WC_NO_CACHE_RESISTANT */ /* Add 1 to a. (a = a + 1) * @@ -40057,6 +40983,7 @@ L_256_from_bin_bswap_zero_end: #ifndef __APPLE__ .size sp_256_from_bin_bswap,.-sp_256_from_bin_bswap #endif /* __APPLE__ */ +#ifndef NO_MOVBE_SUPPORT /* Read big endian unsigned byte array into r. * Uses the movbe instruction which is an optional instruction. * @@ -40142,6 +41069,7 @@ L_256_from_bin_movbe_zero_end: #ifndef __APPLE__ .size sp_256_from_bin_movbe,.-sp_256_from_bin_movbe #endif /* __APPLE__ */ +#endif /* !NO_MOVBE_SUPPORT */ /* Write r as big endian to byte array. * Fixed length number of bytes written: 32 * Uses the bswap instruction. @@ -40177,6 +41105,7 @@ _sp_256_to_bin_bswap: #ifndef __APPLE__ .size sp_256_to_bin_bswap,.-sp_256_to_bin_bswap #endif /* __APPLE__ */ +#ifndef NO_MOVBE_SUPPORT /* Write r as big endian to byte array. * Fixed length number of bytes written: 32 * Uses the movbe instruction which is optional. @@ -40208,183 +41137,8 @@ _sp_256_to_bin_movbe: #ifndef __APPLE__ .size sp_256_to_bin_movbe,.-sp_256_to_bin_movbe #endif /* __APPLE__ */ -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -#ifndef __APPLE__ -.text -.globl sp_256_add_4 -.type sp_256_add_4,@function -.align 16 -sp_256_add_4: -#else -.section __TEXT,__text -.globl _sp_256_add_4 -.p2align 4 -_sp_256_add_4: -#endif /* __APPLE__ */ - # Add - movq (%rsi), %rcx - xorq %rax, %rax - addq (%rdx), %rcx - movq 8(%rsi), %r8 - movq %rcx, (%rdi) - adcq 8(%rdx), %r8 - movq 16(%rsi), %rcx - movq %r8, 8(%rdi) - adcq 16(%rdx), %rcx - movq 24(%rsi), %r8 - movq %rcx, 16(%rdi) - adcq 24(%rdx), %r8 - movq %r8, 24(%rdi) - adcq $0x00, %rax - repz retq -#ifndef __APPLE__ -.size sp_256_add_4,.-sp_256_add_4 -#endif /* __APPLE__ */ -/* Multiply a and b into r. (r = a * b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -#ifndef __APPLE__ -.text -.globl sp_256_mul_4 -.type sp_256_mul_4,@function -.align 16 -sp_256_mul_4: -#else -.section __TEXT,__text -.globl _sp_256_mul_4 -.p2align 4 -_sp_256_mul_4: -#endif /* __APPLE__ */ - movq %rdx, %rcx - subq $32, %rsp - # A[0] * B[0] - movq (%rcx), %rax - mulq (%rsi) - xorq %r10, %r10 - movq %rax, (%rsp) - movq %rdx, %r9 - # A[0] * B[1] - movq 8(%rcx), %rax - mulq (%rsi) - xorq %r8, %r8 - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0x00, %r8 - # A[1] * B[0] - movq (%rcx), %rax - mulq 8(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0x00, %r8 - movq %r9, 8(%rsp) - # A[0] * B[2] - movq 16(%rcx), %rax - mulq (%rsi) - xorq %r9, %r9 - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0x00, %r9 - # A[1] * B[1] - movq 8(%rcx), %rax - mulq 8(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0x00, %r9 - # A[2] * B[0] - movq (%rcx), %rax - mulq 16(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0x00, %r9 - movq %r10, 16(%rsp) - # A[0] * B[3] - movq 24(%rcx), %rax - mulq (%rsi) - xorq %r10, %r10 - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0x00, %r10 - # A[1] * B[2] - movq 16(%rcx), %rax - mulq 8(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0x00, %r10 - # A[2] * B[1] - movq 8(%rcx), %rax - mulq 16(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0x00, %r10 - # A[3] * B[0] - movq (%rcx), %rax - mulq 24(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0x00, %r10 - movq %r8, 24(%rsp) - # A[1] * B[3] - movq 24(%rcx), %rax - mulq 8(%rsi) - xorq %r8, %r8 - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0x00, %r8 - # A[2] * B[2] - movq 16(%rcx), %rax - mulq 16(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0x00, %r8 - # A[3] * B[1] - movq 8(%rcx), %rax - mulq 24(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0x00, %r8 - movq %r9, 32(%rdi) - # A[2] * B[3] - movq 24(%rcx), %rax - mulq 16(%rsi) - xorq %r9, %r9 - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0x00, %r9 - # A[3] * B[2] - movq 16(%rcx), %rax - mulq 24(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0x00, %r9 - movq %r10, 40(%rdi) - # A[3] * B[3] - movq 24(%rcx), %rax - mulq 24(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - movq %r8, 48(%rdi) - movq %r9, 56(%rdi) - movq (%rsp), %rax - movq 8(%rsp), %rdx - movq 16(%rsp), %r8 - movq 24(%rsp), %r9 - movq %rax, (%rdi) - movq %rdx, 8(%rdi) - movq %r8, 16(%rdi) - movq %r9, 24(%rdi) - addq $32, %rsp - repz retq -#ifndef __APPLE__ -.size sp_256_mul_4,.-sp_256_mul_4 -#endif /* __APPLE__ */ +#endif /* NO_MOVBE_SUPPORT */ +#ifdef HAVE_INTEL_AVX2 /* Multiply a and b into r. (r = a * b) * * r Result of multiplication. @@ -40404,11 +41158,11 @@ sp_256_mul_avx2_4: _sp_256_mul_avx2_4: #endif /* __APPLE__ */ pushq %rbx - pushq %rbp pushq %r12 pushq %r13 pushq %r14 pushq %r15 + pushq %rbp movq %rdx, %rbp # A[0] * B[0] movq (%rbp), %rdx @@ -40494,16 +41248,17 @@ _sp_256_mul_avx2_4: movq %r13, 40(%rdi) movq %r14, 48(%rdi) movq %r15, 56(%rdi) + popq %rbp popq %r15 popq %r14 popq %r13 popq %r12 - popq %rbp popq %rbx repz retq #ifndef __APPLE__ .size sp_256_mul_avx2_4,.-sp_256_mul_avx2_4 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ /* Sub b from a into a. (a -= b) * * a A single precision integer and result. @@ -40535,60 +41290,6 @@ _sp_256_sub_in_place_4: #ifndef __APPLE__ .size sp_256_sub_in_place_4,.-sp_256_sub_in_place_4 #endif /* __APPLE__ */ -/* Conditionally subtract b from a using the mask m. - * m is -1 to subtract and 0 when not copying. - * - * r A single precision number representing condition subtract result. - * a A single precision number to subtract from. - * b A single precision number to subtract. - * m Mask value to apply. - */ -#ifndef __APPLE__ -.text -.globl sp_256_cond_sub_avx2_4 -.type sp_256_cond_sub_avx2_4,@function -.align 16 -sp_256_cond_sub_avx2_4: -#else -.section __TEXT,__text -.globl _sp_256_cond_sub_avx2_4 -.p2align 4 -_sp_256_cond_sub_avx2_4: -#endif /* __APPLE__ */ - pushq %r12 - pushq %r13 - pushq %r14 - pushq %r15 - movq $0x00, %rax - movq (%rdx), %r12 - movq 8(%rdx), %r13 - movq 16(%rdx), %r14 - movq 24(%rdx), %r15 - andq %rcx, %r12 - andq %rcx, %r13 - andq %rcx, %r14 - andq %rcx, %r15 - movq (%rsi), %r8 - movq 8(%rsi), %r9 - movq 16(%rsi), %r10 - movq 24(%rsi), %r11 - subq %r12, %r8 - sbbq %r13, %r9 - sbbq %r14, %r10 - sbbq %r15, %r11 - movq %r8, (%rdi) - movq %r9, 8(%rdi) - movq %r10, 16(%rdi) - movq %r11, 24(%rdi) - sbbq $0x00, %rax - popq %r15 - popq %r14 - popq %r13 - popq %r12 - repz retq -#ifndef __APPLE__ -.size sp_256_cond_sub_avx2_4,.-sp_256_cond_sub_avx2_4 -#endif /* __APPLE__ */ /* Mul a by digit b into r. (r = a * b) * * r A single precision integer. @@ -40671,14 +41372,14 @@ _sp_256_mul_d_avx2_4: mulxq 8(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 8(%rdi) adoxq %r8, %r9 + movq %r10, 8(%rdi) # A[2] * B mulxq 16(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 16(%rdi) adoxq %r8, %r10 + movq %r9, 16(%rdi) # A[3] * B mulxq 24(%rsi), %rcx, %r8 movq %r11, %r9 @@ -40692,128 +41393,36 @@ _sp_256_mul_d_avx2_4: .size sp_256_mul_d_avx2_4,.-sp_256_mul_d_avx2_4 #endif /* __APPLE__ */ #endif /* HAVE_INTEL_AVX2 */ -/* Square a and put result in r. (r = a * a) +#ifdef _WIN64 +/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) * - * r A single precision integer. - * a A single precision integer. + * d1 The high order half of the number to divide. + * d0 The low order half of the number to divide. + * div The dividend. + * returns the result of the division. */ #ifndef __APPLE__ .text -.globl sp_256_sqr_4 -.type sp_256_sqr_4,@function +.globl div_256_word_asm_4 +.type div_256_word_asm_4,@function .align 16 -sp_256_sqr_4: +div_256_word_asm_4: #else .section __TEXT,__text -.globl _sp_256_sqr_4 +.globl _div_256_word_asm_4 .p2align 4 -_sp_256_sqr_4: +_div_256_word_asm_4: #endif /* __APPLE__ */ - pushq %r12 - subq $32, %rsp - # A[0] * A[0] - movq (%rsi), %rax - mulq %rax - xorq %r9, %r9 - movq %rax, (%rsp) - movq %rdx, %r8 - # A[0] * A[1] - movq 8(%rsi), %rax - mulq (%rsi) - xorq %rcx, %rcx - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0x00, %rcx - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0x00, %rcx - movq %r8, 8(%rsp) - # A[0] * A[2] - movq 16(%rsi), %rax - mulq (%rsi) - xorq %r8, %r8 - addq %rax, %r9 - adcq %rdx, %rcx - adcq $0x00, %r8 - addq %rax, %r9 - adcq %rdx, %rcx - adcq $0x00, %r8 - # A[1] * A[1] - movq 8(%rsi), %rax - mulq %rax - addq %rax, %r9 - adcq %rdx, %rcx - adcq $0x00, %r8 - movq %r9, 16(%rsp) - # A[0] * A[3] - movq 24(%rsi), %rax - mulq (%rsi) - xorq %r9, %r9 - addq %rax, %rcx - adcq %rdx, %r8 - adcq $0x00, %r9 - addq %rax, %rcx - adcq %rdx, %r8 - adcq $0x00, %r9 - # A[1] * A[2] - movq 16(%rsi), %rax - mulq 8(%rsi) - addq %rax, %rcx - adcq %rdx, %r8 - adcq $0x00, %r9 - addq %rax, %rcx - adcq %rdx, %r8 - adcq $0x00, %r9 - movq %rcx, 24(%rsp) - # A[1] * A[3] - movq 24(%rsi), %rax - mulq 8(%rsi) - xorq %rcx, %rcx - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0x00, %rcx - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0x00, %rcx - # A[2] * A[2] - movq 16(%rsi), %rax - mulq %rax - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0x00, %rcx - movq %r8, 32(%rdi) - # A[2] * A[3] - movq 24(%rsi), %rax - mulq 16(%rsi) - xorq %r8, %r8 - addq %rax, %r9 - adcq %rdx, %rcx - adcq $0x00, %r8 - addq %rax, %r9 - adcq %rdx, %rcx - adcq $0x00, %r8 - movq %r9, 40(%rdi) - # A[3] * A[3] - movq 24(%rsi), %rax - mulq %rax - addq %rax, %rcx - adcq %rdx, %r8 - movq %rcx, 48(%rdi) - movq %r8, 56(%rdi) - movq (%rsp), %rax - movq 8(%rsp), %rdx - movq 16(%rsp), %r10 - movq 24(%rsp), %r11 - movq %rax, (%rdi) - movq %rdx, 8(%rdi) - movq %r10, 16(%rdi) - movq %r11, 24(%rdi) - addq $32, %rsp - popq %r12 + movq %rdx, %rcx + movq %rsi, %rax + movq %rdi, %rdx + divq %rcx repz retq #ifndef __APPLE__ -.size sp_256_sqr_4,.-sp_256_sqr_4 +.size div_256_word_asm_4,.-div_256_word_asm_4 #endif /* __APPLE__ */ +#endif /* _WIN64 */ +#ifdef HAVE_INTEL_AVX2 /* Multiply two Montogmery form numbers mod the modulus (prime). * (r = a * b mod m) * @@ -40834,11 +41443,11 @@ sp_256_mont_mul_order_avx2_4: _sp_256_mont_mul_order_avx2_4: #endif /* __APPLE__ */ pushq %rbx - pushq %rbp pushq %r12 pushq %r13 pushq %r14 pushq %r15 + pushq %rbp movq %rdx, %rbp # A[0] * B[0] movq (%rbp), %rdx @@ -40918,6 +41527,7 @@ _sp_256_mont_mul_order_avx2_4: adoxq %rcx, %r15 # Start Reduction movq $0xccd1c8aaee00bc4f, %rbx + # A[0] movq %rbx, %rdx imulq %r8, %rdx movq $0xf3b9cac2fc632551, %rax @@ -40942,6 +41552,7 @@ _sp_256_mont_mul_order_avx2_4: # carry adoxq %rbp, %r8 adcxq %rbp, %r8 + # A[1] movq %rbx, %rdx imulq %r9, %rdx movq $0xf3b9cac2fc632551, %rax @@ -40966,6 +41577,7 @@ _sp_256_mont_mul_order_avx2_4: # carry adoxq %rbp, %r8 adcxq %rbp, %r8 + # A[2] movq %rbx, %rdx imulq %r10, %rdx movq $0xf3b9cac2fc632551, %rax @@ -40990,6 +41602,7 @@ _sp_256_mont_mul_order_avx2_4: # carry adoxq %rbp, %r8 adcxq %rbp, %r8 + # A[3] movq %rbx, %rdx imulq %r11, %rdx movq $0xf3b9cac2fc632551, %rax @@ -41029,16 +41642,18 @@ _sp_256_mont_mul_order_avx2_4: sbbq %rbp, %r15 movq %r14, 16(%rdi) movq %r15, 24(%rdi) + popq %rbp popq %r15 popq %r14 popq %r13 popq %r12 - popq %rbp popq %rbx repz retq #ifndef __APPLE__ .size sp_256_mont_mul_order_avx2_4,.-sp_256_mont_mul_order_avx2_4 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +#ifdef HAVE_INTEL_AVX2 /* Square the Montgomery form number mod the modulus (prime). (r = a * a mod m) * * r Result of squaring. @@ -41118,6 +41733,7 @@ _sp_256_mont_sqr_order_avx2_4: adoxq %rbx, %r15 # Start Reduction movq $0xccd1c8aaee00bc4f, %rbx + # A[0] movq %rbx, %rdx imulq %r8, %rdx movq $0xf3b9cac2fc632551, %rax @@ -41142,6 +41758,7 @@ _sp_256_mont_sqr_order_avx2_4: # carry adoxq %rbp, %r8 adcxq %rbp, %r8 + # A[1] movq %rbx, %rdx imulq %r9, %rdx movq $0xf3b9cac2fc632551, %rax @@ -41166,6 +41783,7 @@ _sp_256_mont_sqr_order_avx2_4: # carry adoxq %rbp, %r8 adcxq %rbp, %r8 + # A[2] movq %rbx, %rdx imulq %r10, %rdx movq $0xf3b9cac2fc632551, %rax @@ -41190,6 +41808,7 @@ _sp_256_mont_sqr_order_avx2_4: # carry adoxq %rbp, %r8 adcxq %rbp, %r8 + # A[3] movq %rbx, %rdx imulq %r11, %rdx movq $0xf3b9cac2fc632551, %rax @@ -41239,6 +41858,7 @@ _sp_256_mont_sqr_order_avx2_4: #ifndef __APPLE__ .size sp_256_mont_sqr_order_avx2_4,.-sp_256_mont_sqr_order_avx2_4 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ /* Non-constant time modular inversion. * * @param [out] r Resulting number. @@ -41466,6 +42086,7 @@ L_256_mod_inv_4_store_end: #ifndef __APPLE__ .size sp_256_mod_inv_4,.-sp_256_mod_inv_4 #endif /* __APPLE__ */ +#ifdef HAVE_INTEL_AVX2 #ifndef __APPLE__ .data #else @@ -41569,15 +42190,15 @@ _sp_256_mod_inv_avx2_4: movq 8(%rsi), %r11 movq 16(%rsi), %r12 movq 24(%rsi), %r13 - vmovdqu 0+L_sp256_mod_inv_avx2_4_order(%rip), %ymm6 - vmovdqu 32+L_sp256_mod_inv_avx2_4_order(%rip), %ymm7 - vmovdqu 0+L_sp256_mod_inv_avx2_4_one(%rip), %ymm8 - vmovdqu 0+L_sp256_mod_inv_avx2_4_mask01111(%rip), %ymm9 - vmovdqu 0+L_sp256_mod_inv_avx2_4_all_one(%rip), %ymm10 - vmovdqu L_sp256_mod_inv_avx2_4_down_one_dword(%rip), %ymm11 - vmovdqu L_sp256_mod_inv_avx2_4_neg(%rip), %ymm12 - vmovdqu L_sp256_mod_inv_avx2_4_up_one_dword(%rip), %ymm13 - vmovdqu L_sp256_mod_inv_avx2_4_mask26(%rip), %ymm14 + vmovupd 0+L_sp256_mod_inv_avx2_4_order(%rip), %ymm6 + vmovupd 32+L_sp256_mod_inv_avx2_4_order(%rip), %ymm7 + vmovupd 0+L_sp256_mod_inv_avx2_4_one(%rip), %ymm8 + vmovupd 0+L_sp256_mod_inv_avx2_4_mask01111(%rip), %ymm9 + vmovupd 0+L_sp256_mod_inv_avx2_4_all_one(%rip), %ymm10 + vmovupd 0+L_sp256_mod_inv_avx2_4_down_one_dword(%rip), %ymm11 + vmovupd 0+L_sp256_mod_inv_avx2_4_neg(%rip), %ymm12 + vmovupd 0+L_sp256_mod_inv_avx2_4_up_one_dword(%rip), %ymm13 + vmovupd 0+L_sp256_mod_inv_avx2_4_mask26(%rip), %ymm14 vpxor %xmm0, %xmm0, %xmm0 vpxor %xmm1, %xmm1, %xmm1 vmovdqu %ymm8, %ymm2 @@ -41794,55 +42415,9 @@ L_256_mod_inv_avx2_4_store_done: #ifndef __APPLE__ .size sp_256_mod_inv_avx2_4,.-sp_256_mod_inv_avx2_4 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ #endif /* !WOLFSSL_SP_NO_256 */ #ifdef WOLFSSL_SP_384 -/* Conditionally copy a into r using the mask m. - * m is -1 to copy and 0 when not. - * - * r A single precision number to copy over. - * a A single precision number to copy. - * m Mask value to apply. - */ -#ifndef __APPLE__ -.text -.globl sp_384_cond_copy_6 -.type sp_384_cond_copy_6,@function -.align 16 -sp_384_cond_copy_6: -#else -.section __TEXT,__text -.globl _sp_384_cond_copy_6 -.p2align 4 -_sp_384_cond_copy_6: -#endif /* __APPLE__ */ - movq (%rdi), %rax - movq 8(%rdi), %rcx - movq 16(%rdi), %r8 - movq 24(%rdi), %r9 - movq 32(%rdi), %r10 - movq 40(%rdi), %r11 - xorq (%rsi), %rax - xorq 8(%rsi), %rcx - xorq 16(%rsi), %r8 - xorq 24(%rsi), %r9 - xorq 32(%rsi), %r10 - xorq 40(%rsi), %r11 - andq %rdx, %rax - andq %rdx, %rcx - andq %rdx, %r8 - andq %rdx, %r9 - andq %rdx, %r10 - andq %rdx, %r11 - xorq %rax, (%rdi) - xorq %rcx, 8(%rdi) - xorq %r8, 16(%rdi) - xorq %r9, 24(%rdi) - xorq %r10, 32(%rdi) - xorq %r11, 40(%rdi) - repz retq -#ifndef __APPLE__ -.size sp_384_cond_copy_6,.-sp_384_cond_copy_6 -#endif /* __APPLE__ */ /* Multiply a and b into r. (r = a * b) * * r A single precision integer. @@ -42115,371 +42690,6 @@ _sp_384_mul_6: #ifndef __APPLE__ .size sp_384_mul_6,.-sp_384_mul_6 #endif /* __APPLE__ */ -/* Conditionally subtract b from a using the mask m. - * m is -1 to subtract and 0 when not copying. - * - * r A single precision number representing condition subtract result. - * a A single precision number to subtract from. - * b A single precision number to subtract. - * m Mask value to apply. - */ -#ifndef __APPLE__ -.text -.globl sp_384_cond_sub_6 -.type sp_384_cond_sub_6,@function -.align 16 -sp_384_cond_sub_6: -#else -.section __TEXT,__text -.globl _sp_384_cond_sub_6 -.p2align 4 -_sp_384_cond_sub_6: -#endif /* __APPLE__ */ - subq $48, %rsp - movq $0x00, %rax - movq (%rdx), %r8 - movq 8(%rdx), %r9 - andq %rcx, %r8 - andq %rcx, %r9 - movq %r8, (%rsp) - movq %r9, 8(%rsp) - movq 16(%rdx), %r8 - movq 24(%rdx), %r9 - andq %rcx, %r8 - andq %rcx, %r9 - movq %r8, 16(%rsp) - movq %r9, 24(%rsp) - movq 32(%rdx), %r8 - movq 40(%rdx), %r9 - andq %rcx, %r8 - andq %rcx, %r9 - movq %r8, 32(%rsp) - movq %r9, 40(%rsp) - movq (%rsi), %r8 - movq (%rsp), %rdx - subq %rdx, %r8 - movq 8(%rsi), %r9 - movq 8(%rsp), %rdx - sbbq %rdx, %r9 - movq %r8, (%rdi) - movq 16(%rsi), %r8 - movq 16(%rsp), %rdx - sbbq %rdx, %r8 - movq %r9, 8(%rdi) - movq 24(%rsi), %r9 - movq 24(%rsp), %rdx - sbbq %rdx, %r9 - movq %r8, 16(%rdi) - movq 32(%rsi), %r8 - movq 32(%rsp), %rdx - sbbq %rdx, %r8 - movq %r9, 24(%rdi) - movq 40(%rsi), %r9 - movq 40(%rsp), %rdx - sbbq %rdx, %r9 - movq %r8, 32(%rdi) - movq %r9, 40(%rdi) - sbbq $0x00, %rax - addq $48, %rsp - repz retq -#ifndef __APPLE__ -.size sp_384_cond_sub_6,.-sp_384_cond_sub_6 -#endif /* __APPLE__ */ -#ifdef HAVE_INTEL_AVX2 -/* Reduce the number back to 384 bits using Montgomery reduction. - * - * a A single precision number to reduce in place. - * m The single precision number representing the modulus. - * mp The digit representing the negative inverse of m mod 2^n. - */ -#ifndef __APPLE__ -.text -.globl sp_384_mont_reduce_6 -.type sp_384_mont_reduce_6,@function -.align 16 -sp_384_mont_reduce_6: -#else -.section __TEXT,__text -.globl _sp_384_mont_reduce_6 -.p2align 4 -_sp_384_mont_reduce_6: -#endif /* __APPLE__ */ - pushq %r12 - pushq %r13 - pushq %r14 - pushq %r15 - pushq %rbx - pushq %rbp - movq (%rdi), %r11 - movq 8(%rdi), %r12 - movq 16(%rdi), %r13 - movq 24(%rdi), %r14 - movq 32(%rdi), %r15 - movq 40(%rdi), %rsi - xorq %r10, %r10 - # a[0-7] += m[0-5] * mu[0..1] = m[0-5] * (a[0..1] * mp) - movq 48(%rdi), %rbx - movq 56(%rdi), %rbp - movq %r11, %rdx - movq %r12, %rax - shldq $32, %rdx, %rax - shlq $32, %rdx - addq %r11, %rdx - adcq %r12, %rax - addq %r11, %rax - movq %rdx, %rcx - movq %rax, %r8 - movq %rax, %r9 - shldq $32, %rcx, %r8 - shlq $32, %rcx - shrq $32, %r9 - addq %rcx, %r11 - adcq %r8, %r12 - adcq %r9, %r13 - adcq $0x00, %r14 - adcq $0x00, %r15 - adcq $0x00, %rsi - adcq %rdx, %rbx - adcq %rax, %rbp - adcq $0x00, %r10 - addq %rax, %rcx - adcq %rdx, %r8 - adcq %rax, %r9 - movq $0x00, %rax - adcq $0x00, %rax - subq %r8, %r13 - sbbq %r9, %r14 - sbbq %rax, %r15 - sbbq $0x00, %rsi - sbbq $0x00, %rbx - sbbq $0x00, %rbp - sbbq $0x00, %r10 - # a[2-9] += m[0-5] * mu[0..1] = m[0-5] * (a[2..3] * mp) - movq 64(%rdi), %r11 - movq 72(%rdi), %r12 - movq %r13, %rdx - movq %r14, %rax - shldq $32, %rdx, %rax - shlq $32, %rdx - addq %r13, %rdx - adcq %r14, %rax - addq %r13, %rax - movq %rdx, %rcx - movq %rax, %r8 - movq %rax, %r9 - shldq $32, %rcx, %r8 - shlq $32, %rcx - shrq $32, %r9 - addq %r10, %r11 - adcq $0x00, %r12 - movq $0x00, %r10 - adcq $0x00, %r10 - addq %rcx, %r13 - adcq %r8, %r14 - adcq %r9, %r15 - adcq $0x00, %rsi - adcq $0x00, %rbx - adcq $0x00, %rbp - adcq %rdx, %r11 - adcq %rax, %r12 - adcq $0x00, %r10 - addq %rax, %rcx - adcq %rdx, %r8 - adcq %rax, %r9 - movq $0x00, %rax - adcq $0x00, %rax - subq %r8, %r15 - sbbq %r9, %rsi - sbbq %rax, %rbx - sbbq $0x00, %rbp - sbbq $0x00, %r11 - sbbq $0x00, %r12 - sbbq $0x00, %r10 - # a[4-11] += m[0-5] * mu[0..1] = m[0-5] * (a[4..5] * mp) - movq 80(%rdi), %r13 - movq 88(%rdi), %r14 - movq %r15, %rdx - movq %rsi, %rax - shldq $32, %rdx, %rax - shlq $32, %rdx - addq %r15, %rdx - adcq %rsi, %rax - addq %r15, %rax - movq %rdx, %rcx - movq %rax, %r8 - movq %rax, %r9 - shldq $32, %rcx, %r8 - shlq $32, %rcx - shrq $32, %r9 - addq %r10, %r13 - adcq $0x00, %r14 - movq $0x00, %r10 - adcq $0x00, %r10 - addq %rcx, %r15 - adcq %r8, %rsi - adcq %r9, %rbx - adcq $0x00, %rbp - adcq $0x00, %r11 - adcq $0x00, %r12 - adcq %rdx, %r13 - adcq %rax, %r14 - adcq $0x00, %r10 - addq %rax, %rcx - adcq %rdx, %r8 - adcq %rax, %r9 - movq $0x00, %rax - adcq $0x00, %rax - subq %r8, %rbx - sbbq %r9, %rbp - sbbq %rax, %r11 - sbbq $0x00, %r12 - sbbq $0x00, %r13 - sbbq $0x00, %r14 - sbbq $0x00, %r10 - # Subtract mod if carry - negq %r10 - movq $0xfffffffffffffffe, %r9 - movq %r10, %rcx - movq %r10, %r8 - shrq $32, %rcx - shlq $32, %r8 - andq %r10, %r9 - subq %rcx, %rbx - sbbq %r8, %rbp - sbbq %r9, %r11 - sbbq %r10, %r12 - sbbq %r10, %r13 - sbbq %r10, %r14 - movq %rbx, (%rdi) - movq %rbp, 8(%rdi) - movq %r11, 16(%rdi) - movq %r12, 24(%rdi) - movq %r13, 32(%rdi) - movq %r14, 40(%rdi) - popq %rbp - popq %rbx - popq %r15 - popq %r14 - popq %r13 - popq %r12 - repz retq -#ifndef __APPLE__ -.size sp_384_mont_reduce_6,.-sp_384_mont_reduce_6 -#endif /* __APPLE__ */ -#endif /* HAVE_INTEL_AVX2 */ -/* Reduce the number back to 384 bits using Montgomery reduction. - * - * a A single precision number to reduce in place. - * m The single precision number representing the modulus. - * mp The digit representing the negative inverse of m mod 2^n. - */ -#ifndef __APPLE__ -.text -.globl sp_384_mont_reduce_order_6 -.type sp_384_mont_reduce_order_6,@function -.align 16 -sp_384_mont_reduce_order_6: -#else -.section __TEXT,__text -.globl _sp_384_mont_reduce_order_6 -.p2align 4 -_sp_384_mont_reduce_order_6: -#endif /* __APPLE__ */ - pushq %r12 - pushq %r13 - pushq %r14 - pushq %r15 - movq %rdx, %rcx - xorq %r15, %r15 - # i = 6 - movq $6, %r8 - movq (%rdi), %r13 - movq 8(%rdi), %r14 -L_mont_loop_order_6: - # mu = a[i] * mp - movq %r13, %r11 - imulq %rcx, %r11 - # a[i+0] += m[0] * mu - movq %r11, %rax - xorq %r10, %r10 - mulq (%rsi) - addq %rax, %r13 - adcq %rdx, %r10 - # a[i+1] += m[1] * mu - movq %r11, %rax - xorq %r9, %r9 - mulq 8(%rsi) - movq %r14, %r13 - addq %rax, %r13 - adcq %rdx, %r9 - addq %r10, %r13 - adcq $0x00, %r9 - # a[i+2] += m[2] * mu - movq %r11, %rax - xorq %r10, %r10 - mulq 16(%rsi) - movq 16(%rdi), %r14 - addq %rax, %r14 - adcq %rdx, %r10 - addq %r9, %r14 - adcq $0x00, %r10 - # a[i+3] += m[3] * mu - movq %r11, %rax - xorq %r9, %r9 - mulq 24(%rsi) - movq 24(%rdi), %r12 - addq %rax, %r12 - adcq %rdx, %r9 - addq %r10, %r12 - movq %r12, 24(%rdi) - adcq $0x00, %r9 - # a[i+4] += m[4] * mu - movq %r11, %rax - xorq %r10, %r10 - mulq 32(%rsi) - movq 32(%rdi), %r12 - addq %rax, %r12 - adcq %rdx, %r10 - addq %r9, %r12 - movq %r12, 32(%rdi) - adcq $0x00, %r10 - # a[i+5] += m[5] * mu - movq %r11, %rax - mulq 40(%rsi) - movq 40(%rdi), %r12 - addq %rax, %r10 - adcq %r15, %rdx - movq $0x00, %r15 - adcq $0x00, %r15 - addq %r10, %r12 - movq %r12, 40(%rdi) - adcq %rdx, 48(%rdi) - adcq $0x00, %r15 - # i -= 1 - addq $8, %rdi - decq %r8 - jnz L_mont_loop_order_6 - movq %r13, (%rdi) - movq %r14, 8(%rdi) - negq %r15 - movq %r15, %rcx - movq %rsi, %rdx - movq %rdi, %rsi - movq %rdi, %rdi - subq $48, %rdi -#ifndef __APPLE__ - callq sp_384_cond_sub_6@plt -#else - callq _sp_384_cond_sub_6 -#endif /* __APPLE__ */ - popq %r15 - popq %r14 - popq %r13 - popq %r12 - repz retq -#ifndef __APPLE__ -.size sp_384_mont_reduce_order_6,.-sp_384_mont_reduce_order_6 -#endif /* __APPLE__ */ /* Square a and put result in r. (r = a * a) * * r A single precision integer. @@ -42704,6 +42914,508 @@ _sp_384_sqr_6: #ifndef __APPLE__ .size sp_384_sqr_6,.-sp_384_sqr_6 #endif /* __APPLE__ */ +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +#ifndef __APPLE__ +.text +.globl sp_384_add_6 +.type sp_384_add_6,@function +.align 16 +sp_384_add_6: +#else +.section __TEXT,__text +.globl _sp_384_add_6 +.p2align 4 +_sp_384_add_6: +#endif /* __APPLE__ */ + # Add + movq (%rsi), %rcx + xorq %rax, %rax + addq (%rdx), %rcx + movq 8(%rsi), %r8 + movq %rcx, (%rdi) + adcq 8(%rdx), %r8 + movq 16(%rsi), %rcx + movq %r8, 8(%rdi) + adcq 16(%rdx), %rcx + movq 24(%rsi), %r8 + movq %rcx, 16(%rdi) + adcq 24(%rdx), %r8 + movq 32(%rsi), %rcx + movq %r8, 24(%rdi) + adcq 32(%rdx), %rcx + movq 40(%rsi), %r8 + movq %rcx, 32(%rdi) + adcq 40(%rdx), %r8 + movq %r8, 40(%rdi) + adcq $0x00, %rax + repz retq +#ifndef __APPLE__ +.size sp_384_add_6,.-sp_384_add_6 +#endif /* __APPLE__ */ +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +#ifndef __APPLE__ +.text +.globl sp_384_sub_6 +.type sp_384_sub_6,@function +.align 16 +sp_384_sub_6: +#else +.section __TEXT,__text +.globl _sp_384_sub_6 +.p2align 4 +_sp_384_sub_6: +#endif /* __APPLE__ */ + pushq %r12 + xorq %rax, %rax + movq (%rsi), %rcx + movq 8(%rsi), %r8 + movq 16(%rsi), %r9 + movq 24(%rsi), %r10 + movq 32(%rsi), %r11 + movq 40(%rsi), %r12 + subq (%rdx), %rcx + sbbq 8(%rdx), %r8 + sbbq 16(%rdx), %r9 + sbbq 24(%rdx), %r10 + sbbq 32(%rdx), %r11 + sbbq 40(%rdx), %r12 + movq %rcx, (%rdi) + movq %r8, 8(%rdi) + movq %r9, 16(%rdi) + movq %r10, 24(%rdi) + movq %r11, 32(%rdi) + movq %r12, 40(%rdi) + sbbq $0x00, %rax + popq %r12 + repz retq +#ifndef __APPLE__ +.size sp_384_sub_6,.-sp_384_sub_6 +#endif /* __APPLE__ */ +/* Conditionally copy a into r using the mask m. + * m is -1 to copy and 0 when not. + * + * r A single precision number to copy over. + * a A single precision number to copy. + * m Mask value to apply. + */ +#ifndef __APPLE__ +.text +.globl sp_384_cond_copy_6 +.type sp_384_cond_copy_6,@function +.align 16 +sp_384_cond_copy_6: +#else +.section __TEXT,__text +.globl _sp_384_cond_copy_6 +.p2align 4 +_sp_384_cond_copy_6: +#endif /* __APPLE__ */ + movq (%rdi), %rax + movq 8(%rdi), %rcx + movq 16(%rdi), %r8 + movq 24(%rdi), %r9 + movq 32(%rdi), %r10 + movq 40(%rdi), %r11 + xorq (%rsi), %rax + xorq 8(%rsi), %rcx + xorq 16(%rsi), %r8 + xorq 24(%rsi), %r9 + xorq 32(%rsi), %r10 + xorq 40(%rsi), %r11 + andq %rdx, %rax + andq %rdx, %rcx + andq %rdx, %r8 + andq %rdx, %r9 + andq %rdx, %r10 + andq %rdx, %r11 + xorq %rax, (%rdi) + xorq %rcx, 8(%rdi) + xorq %r8, 16(%rdi) + xorq %r9, 24(%rdi) + xorq %r10, 32(%rdi) + xorq %r11, 40(%rdi) + repz retq +#ifndef __APPLE__ +.size sp_384_cond_copy_6,.-sp_384_cond_copy_6 +#endif /* __APPLE__ */ +/* Conditionally subtract b from a using the mask m. + * m is -1 to subtract and 0 when not copying. + * + * r A single precision number representing condition subtract result. + * a A single precision number to subtract from. + * b A single precision number to subtract. + * m Mask value to apply. + */ +#ifndef __APPLE__ +.text +.globl sp_384_cond_sub_6 +.type sp_384_cond_sub_6,@function +.align 16 +sp_384_cond_sub_6: +#else +.section __TEXT,__text +.globl _sp_384_cond_sub_6 +.p2align 4 +_sp_384_cond_sub_6: +#endif /* __APPLE__ */ + subq $48, %rsp + movq $0x00, %rax + movq (%rdx), %r8 + movq 8(%rdx), %r9 + andq %rcx, %r8 + andq %rcx, %r9 + movq %r8, (%rsp) + movq %r9, 8(%rsp) + movq 16(%rdx), %r8 + movq 24(%rdx), %r9 + andq %rcx, %r8 + andq %rcx, %r9 + movq %r8, 16(%rsp) + movq %r9, 24(%rsp) + movq 32(%rdx), %r8 + movq 40(%rdx), %r9 + andq %rcx, %r8 + andq %rcx, %r9 + movq %r8, 32(%rsp) + movq %r9, 40(%rsp) + movq (%rsi), %r8 + movq (%rsp), %rdx + subq %rdx, %r8 + movq 8(%rsi), %r9 + movq 8(%rsp), %rdx + sbbq %rdx, %r9 + movq %r8, (%rdi) + movq 16(%rsi), %r8 + movq 16(%rsp), %rdx + sbbq %rdx, %r8 + movq %r9, 8(%rdi) + movq 24(%rsi), %r9 + movq 24(%rsp), %rdx + sbbq %rdx, %r9 + movq %r8, 16(%rdi) + movq 32(%rsi), %r8 + movq 32(%rsp), %rdx + sbbq %rdx, %r8 + movq %r9, 24(%rdi) + movq 40(%rsi), %r9 + movq 40(%rsp), %rdx + sbbq %rdx, %r9 + movq %r8, 32(%rdi) + movq %r9, 40(%rdi) + sbbq $0x00, %rax + addq $48, %rsp + repz retq +#ifndef __APPLE__ +.size sp_384_cond_sub_6,.-sp_384_cond_sub_6 +#endif /* __APPLE__ */ +/* Reduce the number back to 384 bits using Montgomery reduction. + * + * a A single precision number to reduce in place. + * m The single precision number representing the modulus. + * mp The digit representing the negative inverse of m mod 2^n. + */ +#ifndef __APPLE__ +.text +.globl sp_384_mont_reduce_6 +.type sp_384_mont_reduce_6,@function +.align 16 +sp_384_mont_reduce_6: +#else +.section __TEXT,__text +.globl _sp_384_mont_reduce_6 +.p2align 4 +_sp_384_mont_reduce_6: +#endif /* __APPLE__ */ + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + pushq %rbx + pushq %rbp + movq (%rdi), %r11 + movq 8(%rdi), %r12 + movq 16(%rdi), %r13 + movq 24(%rdi), %r14 + movq 32(%rdi), %r15 + movq 40(%rdi), %rsi + xorq %r10, %r10 + # a[0-7] += m[0-5] * mu[0..1] = m[0-5] * (a[0..1] * mp) + movq 48(%rdi), %rbx + movq 56(%rdi), %rbp + movq %r11, %rdx + movq %r12, %rax + shldq $32, %rdx, %rax + shlq $32, %rdx + addq %r11, %rdx + adcq %r12, %rax + addq %r11, %rax + movq %rdx, %rcx + movq %rax, %r8 + movq %rax, %r9 + shldq $32, %rcx, %r8 + shlq $32, %rcx + shrq $32, %r9 + addq %rcx, %r11 + adcq %r8, %r12 + adcq %r9, %r13 + adcq $0x00, %r14 + adcq $0x00, %r15 + adcq $0x00, %rsi + adcq %rdx, %rbx + adcq %rax, %rbp + adcq $0x00, %r10 + addq %rax, %rcx + adcq %rdx, %r8 + adcq %rax, %r9 + movq $0x00, %rax + adcq $0x00, %rax + subq %r8, %r13 + sbbq %r9, %r14 + sbbq %rax, %r15 + sbbq $0x00, %rsi + sbbq $0x00, %rbx + sbbq $0x00, %rbp + sbbq $0x00, %r10 + # a[2-9] += m[0-5] * mu[0..1] = m[0-5] * (a[2..3] * mp) + movq 64(%rdi), %r11 + movq 72(%rdi), %r12 + movq %r13, %rdx + movq %r14, %rax + shldq $32, %rdx, %rax + shlq $32, %rdx + addq %r13, %rdx + adcq %r14, %rax + addq %r13, %rax + movq %rdx, %rcx + movq %rax, %r8 + movq %rax, %r9 + shldq $32, %rcx, %r8 + shlq $32, %rcx + shrq $32, %r9 + addq %r10, %r11 + adcq $0x00, %r12 + movq $0x00, %r10 + adcq $0x00, %r10 + addq %rcx, %r13 + adcq %r8, %r14 + adcq %r9, %r15 + adcq $0x00, %rsi + adcq $0x00, %rbx + adcq $0x00, %rbp + adcq %rdx, %r11 + adcq %rax, %r12 + adcq $0x00, %r10 + addq %rax, %rcx + adcq %rdx, %r8 + adcq %rax, %r9 + movq $0x00, %rax + adcq $0x00, %rax + subq %r8, %r15 + sbbq %r9, %rsi + sbbq %rax, %rbx + sbbq $0x00, %rbp + sbbq $0x00, %r11 + sbbq $0x00, %r12 + sbbq $0x00, %r10 + # a[4-11] += m[0-5] * mu[0..1] = m[0-5] * (a[4..5] * mp) + movq 80(%rdi), %r13 + movq 88(%rdi), %r14 + movq %r15, %rdx + movq %rsi, %rax + shldq $32, %rdx, %rax + shlq $32, %rdx + addq %r15, %rdx + adcq %rsi, %rax + addq %r15, %rax + movq %rdx, %rcx + movq %rax, %r8 + movq %rax, %r9 + shldq $32, %rcx, %r8 + shlq $32, %rcx + shrq $32, %r9 + addq %r10, %r13 + adcq $0x00, %r14 + movq $0x00, %r10 + adcq $0x00, %r10 + addq %rcx, %r15 + adcq %r8, %rsi + adcq %r9, %rbx + adcq $0x00, %rbp + adcq $0x00, %r11 + adcq $0x00, %r12 + adcq %rdx, %r13 + adcq %rax, %r14 + adcq $0x00, %r10 + addq %rax, %rcx + adcq %rdx, %r8 + adcq %rax, %r9 + movq $0x00, %rax + adcq $0x00, %rax + subq %r8, %rbx + sbbq %r9, %rbp + sbbq %rax, %r11 + sbbq $0x00, %r12 + sbbq $0x00, %r13 + sbbq $0x00, %r14 + sbbq $0x00, %r10 + # Subtract mod if carry + negq %r10 + movq $0xfffffffffffffffe, %r9 + movq %r10, %rcx + movq %r10, %r8 + shrq $32, %rcx + shlq $32, %r8 + andq %r10, %r9 + subq %rcx, %rbx + sbbq %r8, %rbp + sbbq %r9, %r11 + sbbq %r10, %r12 + sbbq %r10, %r13 + sbbq %r10, %r14 + movq %rbx, (%rdi) + movq %rbp, 8(%rdi) + movq %r11, 16(%rdi) + movq %r12, 24(%rdi) + movq %r13, 32(%rdi) + movq %r14, 40(%rdi) + popq %rbp + popq %rbx + popq %r15 + popq %r14 + popq %r13 + popq %r12 + repz retq +#ifndef __APPLE__ +.size sp_384_mont_reduce_6,.-sp_384_mont_reduce_6 +#endif /* __APPLE__ */ +/* Reduce the number back to 384 bits using Montgomery reduction. + * + * a A single precision number to reduce in place. + * m The single precision number representing the modulus. + * mp The digit representing the negative inverse of m mod 2^n. + */ +#ifndef __APPLE__ +.text +.globl sp_384_mont_reduce_order_6 +.type sp_384_mont_reduce_order_6,@function +.align 16 +sp_384_mont_reduce_order_6: +#else +.section __TEXT,__text +.globl _sp_384_mont_reduce_order_6 +.p2align 4 +_sp_384_mont_reduce_order_6: +#endif /* __APPLE__ */ + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + movq %rdx, %rcx + xorq %r15, %r15 + # i = 6 + movq $6, %r8 + movq (%rdi), %r13 + movq 8(%rdi), %r14 +L_384_mont_loop_order_6: + # mu = a[i] * mp + movq %r13, %r11 + imulq %rcx, %r11 + # a[i+0] += m[0] * mu + movq %r11, %rax + xorq %r10, %r10 + mulq (%rsi) + addq %rax, %r13 + adcq %rdx, %r10 + # a[i+1] += m[1] * mu + movq %r11, %rax + xorq %r9, %r9 + mulq 8(%rsi) + movq %r14, %r13 + addq %rax, %r13 + adcq %rdx, %r9 + addq %r10, %r13 + adcq $0x00, %r9 + # a[i+2] += m[2] * mu + movq %r11, %rax + xorq %r10, %r10 + mulq 16(%rsi) + movq 16(%rdi), %r14 + addq %rax, %r14 + adcq %rdx, %r10 + addq %r9, %r14 + adcq $0x00, %r10 + # a[i+3] += m[3] * mu + movq %r11, %rax + xorq %r9, %r9 + mulq 24(%rsi) + movq 24(%rdi), %r12 + addq %rax, %r12 + adcq %rdx, %r9 + addq %r10, %r12 + movq %r12, 24(%rdi) + adcq $0x00, %r9 + # a[i+4] += m[4] * mu + movq %r11, %rax + xorq %r10, %r10 + mulq 32(%rsi) + movq 32(%rdi), %r12 + addq %rax, %r12 + adcq %rdx, %r10 + addq %r9, %r12 + movq %r12, 32(%rdi) + adcq $0x00, %r10 + # a[i+5] += m[5] * mu + movq %r11, %rax + mulq 40(%rsi) + movq 40(%rdi), %r12 + addq %rax, %r10 + adcq %r15, %rdx + movq $0x00, %r15 + adcq $0x00, %r15 + addq %r10, %r12 + movq %r12, 40(%rdi) + adcq %rdx, 48(%rdi) + adcq $0x00, %r15 + # i -= 1 + addq $8, %rdi + decq %r8 + jnz L_384_mont_loop_order_6 + movq %r13, (%rdi) + movq %r14, 8(%rdi) + negq %r15 +#ifdef _WIN64 + movq %rsi, %rdx + movq %r15, %rcx +#else + movq %r15, %rcx + movq %rsi, %rdx +#endif /* _WIN64 */ + movq %rdi, %rsi + movq %rdi, %rdi + subq $48, %rdi +#ifndef __APPLE__ + callq sp_384_cond_sub_6@plt +#else + callq _sp_384_cond_sub_6 +#endif /* __APPLE__ */ + popq %r15 + popq %r14 + popq %r13 + popq %r12 + repz retq +#ifndef __APPLE__ +.size sp_384_mont_reduce_order_6,.-sp_384_mont_reduce_order_6 +#endif /* __APPLE__ */ /* Compare a with b in constant time. * * a A single precision integer. @@ -42780,49 +43492,6 @@ _sp_384_cmp_6: #ifndef __APPLE__ .size sp_384_cmp_6,.-sp_384_cmp_6 #endif /* __APPLE__ */ -/* Add b to a into r. (r = a + b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -#ifndef __APPLE__ -.text -.globl sp_384_add_6 -.type sp_384_add_6,@function -.align 16 -sp_384_add_6: -#else -.section __TEXT,__text -.globl _sp_384_add_6 -.p2align 4 -_sp_384_add_6: -#endif /* __APPLE__ */ - # Add - movq (%rsi), %rcx - xorq %rax, %rax - addq (%rdx), %rcx - movq 8(%rsi), %r8 - movq %rcx, (%rdi) - adcq 8(%rdx), %r8 - movq 16(%rsi), %rcx - movq %r8, 8(%rdi) - adcq 16(%rdx), %rcx - movq 24(%rsi), %r8 - movq %rcx, 16(%rdi) - adcq 24(%rdx), %r8 - movq 32(%rsi), %rcx - movq %r8, 24(%rdi) - adcq 32(%rdx), %rcx - movq 40(%rsi), %r8 - movq %rcx, 32(%rdi) - adcq 40(%rdx), %r8 - movq %r8, 40(%rdi) - adcq $0x00, %rax - repz retq -#ifndef __APPLE__ -.size sp_384_add_6,.-sp_384_add_6 -#endif /* __APPLE__ */ /* Add a to a into r. (r = a + a) * * r A single precision integer. @@ -42864,50 +43533,6 @@ _sp_384_dbl_6: #ifndef __APPLE__ .size sp_384_dbl_6,.-sp_384_dbl_6 #endif /* __APPLE__ */ -/* Sub b from a into r. (r = a - b) - * - * r A single precision integer. - * a A single precision integer. - * b A single precision integer. - */ -#ifndef __APPLE__ -.text -.globl sp_384_sub_6 -.type sp_384_sub_6,@function -.align 16 -sp_384_sub_6: -#else -.section __TEXT,__text -.globl _sp_384_sub_6 -.p2align 4 -_sp_384_sub_6: -#endif /* __APPLE__ */ - pushq %r12 - xorq %rax, %rax - movq (%rsi), %rcx - movq 8(%rsi), %r8 - movq 16(%rsi), %r9 - movq 24(%rsi), %r10 - movq 32(%rsi), %r11 - movq 40(%rsi), %r12 - subq (%rdx), %rcx - sbbq 8(%rdx), %r8 - sbbq 16(%rdx), %r9 - sbbq 24(%rdx), %r10 - sbbq 32(%rdx), %r11 - sbbq 40(%rdx), %r12 - movq %rcx, (%rdi) - movq %r8, 8(%rdi) - movq %r9, 16(%rdi) - movq %r10, 24(%rdi) - movq %r11, 32(%rdi) - movq %r12, 40(%rdi) - sbbq $0x00, %rax - popq %r12 - repz retq -#ifndef __APPLE__ -.size sp_384_sub_6,.-sp_384_sub_6 -#endif /* __APPLE__ */ /* Conditionally add a and b using the mask m. * m is -1 to add and 0 when not. * @@ -42997,11 +43622,11 @@ sp_384_div2_6: _sp_384_div2_6: #endif /* __APPLE__ */ subq $48, %rsp - movq (%rsi), %rax - movq %rax, %r11 + movq (%rsi), %r11 + xorq %r10, %r10 + movq %r11, %rax andq $0x01, %r11 negq %r11 - xorq %r10, %r10 movq (%rdx), %r8 andq %r11, %r8 movq %r8, (%rsp) @@ -43155,6 +43780,7 @@ L_384_get_point_33_6_start_2: #ifndef __APPLE__ .size sp_384_get_point_33_6,.-sp_384_get_point_33_6 #endif /* __APPLE__ */ +#ifdef HAVE_INTEL_AVX2 /* Touch each possible point that could be being copied. * * r Point to copy into. @@ -43191,11 +43817,11 @@ _sp_384_get_point_33_avx2_6: L_384_get_point_33_avx2_6_start: vpcmpeqd %ymm13, %ymm14, %ymm12 vpaddd %ymm15, %ymm14, %ymm14 - vmovdqu (%rsi), %ymm6 + vmovupd (%rsi), %ymm6 vmovdqu 32(%rsi), %xmm7 - vmovdqu 96(%rsi), %ymm8 + vmovupd 96(%rsi), %ymm8 vmovdqu 128(%rsi), %xmm9 - vmovdqu 192(%rsi), %ymm10 + vmovupd 192(%rsi), %ymm10 vmovdqu 224(%rsi), %xmm11 addq $0x128, %rsi vpand %ymm12, %ymm6, %ymm6 @@ -43212,17 +43838,19 @@ L_384_get_point_33_avx2_6_start: vpor %xmm11, %xmm5, %xmm5 decq %rax jnz L_384_get_point_33_avx2_6_start - vmovdqu %ymm0, (%rdi) + vmovupd %ymm0, (%rdi) vmovdqu %xmm1, 32(%rdi) - vmovdqu %ymm2, 96(%rdi) + vmovupd %ymm2, 96(%rdi) vmovdqu %xmm3, 128(%rdi) - vmovdqu %ymm4, 192(%rdi) + vmovupd %ymm4, 192(%rdi) vmovdqu %xmm5, 224(%rdi) repz retq #ifndef __APPLE__ .size sp_384_get_point_33_avx2_6,.-sp_384_get_point_33_avx2_6 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ #endif /* !WC_NO_CACHE_RESISTANT */ +#ifdef HAVE_INTEL_AVX2 /* Multiply a and b into r. (r = a * b) * * r Result of multiplication. @@ -43445,6 +44073,7 @@ _sp_384_mul_avx2_6: #ifndef __APPLE__ .size sp_384_mul_avx2_6,.-sp_384_mul_avx2_6 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ #ifdef HAVE_INTEL_AVX2 /* Reduce the number back to 384 bits using Montgomery reduction. * @@ -43775,6 +44404,7 @@ L_mont_loop_order_avx2_6: .size sp_384_mont_reduce_order_avx2_6,.-sp_384_mont_reduce_order_avx2_6 #endif /* __APPLE__ */ #endif /* HAVE_INTEL_AVX2 */ +#ifdef HAVE_INTEL_AVX2 /* Square a and put result in r. (r = a * a) * * r Result of squaring. @@ -43937,6 +44567,143 @@ _sp_384_sqr_avx2_6: #ifndef __APPLE__ .size sp_384_sqr_avx2_6,.-sp_384_sqr_avx2_6 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +#ifdef HAVE_INTEL_AVX2 +/* Conditionally subtract b from a using the mask m. + * m is -1 to subtract and 0 when not copying. + * + * r A single precision number representing condition subtract result. + * a A single precision number to subtract from. + * b A single precision number to subtract. + * m Mask value to apply. + */ +#ifndef __APPLE__ +.text +.globl sp_384_cond_sub_avx2_6 +.type sp_384_cond_sub_avx2_6,@function +.align 16 +sp_384_cond_sub_avx2_6: +#else +.section __TEXT,__text +.globl _sp_384_cond_sub_avx2_6 +.p2align 4 +_sp_384_cond_sub_avx2_6: +#endif /* __APPLE__ */ + movq $0x00, %rax + movq (%rdx), %r10 + movq (%rsi), %r8 + pextq %rcx, %r10, %r10 + subq %r10, %r8 + movq 8(%rdx), %r10 + movq 8(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, (%rdi) + sbbq %r10, %r9 + movq 16(%rdx), %r8 + movq 16(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 8(%rdi) + sbbq %r8, %r10 + movq 24(%rdx), %r9 + movq 24(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 16(%rdi) + sbbq %r9, %r8 + movq 32(%rdx), %r10 + movq 32(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 24(%rdi) + sbbq %r10, %r9 + movq 40(%rdx), %r8 + movq 40(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 32(%rdi) + sbbq %r8, %r10 + movq %r10, 40(%rdi) + sbbq $0x00, %rax + repz retq +#ifndef __APPLE__ +.size sp_384_cond_sub_avx2_6,.-sp_384_cond_sub_avx2_6 +#endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +#ifdef HAVE_INTEL_AVX2 +/* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m) + * + * r Result of division by 2. + * a Number to divide. + * m Modulus (prime). + */ +#ifndef __APPLE__ +.text +.globl sp_384_div2_avx2_6 +.type sp_384_div2_avx2_6,@function +.align 16 +sp_384_div2_avx2_6: +#else +.section __TEXT,__text +.globl _sp_384_div2_avx2_6 +.p2align 4 +_sp_384_div2_avx2_6: +#endif /* __APPLE__ */ + movq (%rsi), %r11 + xorq %r10, %r10 + movq %r11, %r8 + andq $0x01, %r11 + negq %r11 + movq (%rdx), %rax + movq 8(%rdx), %rcx + movq (%rsi), %r8 + movq 8(%rsi), %r9 + pextq %r11, %rax, %rax + pextq %r11, %rcx, %rcx + addq %rax, %r8 + adcq %rcx, %r9 + movq %r8, (%rdi) + movq %r9, 8(%rdi) + movq 16(%rdx), %rax + movq 24(%rdx), %rcx + movq 16(%rsi), %r8 + movq 24(%rsi), %r9 + pextq %r11, %rax, %rax + pextq %r11, %rcx, %rcx + adcq %rax, %r8 + adcq %rcx, %r9 + movq %r8, 16(%rdi) + movq %r9, 24(%rdi) + movq 32(%rdx), %rax + movq 40(%rdx), %rcx + movq 32(%rsi), %r8 + movq 40(%rsi), %r9 + pextq %r11, %rax, %rax + pextq %r11, %rcx, %rcx + adcq %rax, %r8 + adcq %rcx, %r9 + movq %r8, 32(%rdi) + movq %r9, 40(%rdi) + adcq $0x00, %r10 + movq (%rdi), %r8 + movq 8(%rdi), %r9 + shrdq $0x01, %r9, %r8 + movq %r8, (%rdi) + movq 16(%rdi), %r8 + shrdq $0x01, %r8, %r9 + movq %r9, 8(%rdi) + movq 24(%rdi), %r9 + shrdq $0x01, %r9, %r8 + movq %r8, 16(%rdi) + movq 32(%rdi), %r8 + shrdq $0x01, %r8, %r9 + movq %r9, 24(%rdi) + movq 40(%rdi), %r9 + shrdq $0x01, %r9, %r8 + movq %r8, 32(%rdi) + shrdq $0x01, %r10, %r9 + movq %r9, 40(%rdi) + repz retq +#ifndef __APPLE__ +.size sp_384_div2_avx2_6,.-sp_384_div2_avx2_6 +#endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ #ifndef WC_NO_CACHE_RESISTANT /* Touch each possible entry that could be being copied. * @@ -43946,21 +44713,21 @@ _sp_384_sqr_avx2_6: */ #ifndef __APPLE__ .text -.globl sp_384_get_entry_256_6 -.type sp_384_get_entry_256_6,@function +.globl sp_384_get_entry_64_6 +.type sp_384_get_entry_64_6,@function .align 16 -sp_384_get_entry_256_6: +sp_384_get_entry_64_6: #else .section __TEXT,__text -.globl _sp_384_get_entry_256_6 +.globl _sp_384_get_entry_64_6 .p2align 4 -_sp_384_get_entry_256_6: +_sp_384_get_entry_64_6: #endif /* __APPLE__ */ movq $0x01, %rax movd %edx, %xmm13 addq $0x60, %rsi movd %eax, %xmm15 - movq $0xff, %rax + movq $63, %rax pshufd $0x00, %xmm15, %xmm15 pshufd $0x00, %xmm13, %xmm13 pxor %xmm14, %xmm14 @@ -43971,16 +44738,16 @@ _sp_384_get_entry_256_6: pxor %xmm4, %xmm4 pxor %xmm5, %xmm5 movdqa %xmm15, %xmm14 -L_384_get_entry_256_6_start: +L_384_get_entry_64_6_start: movdqa %xmm14, %xmm12 paddd %xmm15, %xmm14 pcmpeqd %xmm13, %xmm12 - movdqa (%rsi), %xmm6 - movdqa 16(%rsi), %xmm7 - movdqa 32(%rsi), %xmm8 - movdqa 48(%rsi), %xmm9 - movdqa 64(%rsi), %xmm10 - movdqa 80(%rsi), %xmm11 + movdqu (%rsi), %xmm6 + movdqu 16(%rsi), %xmm7 + movdqu 32(%rsi), %xmm8 + movdqu 48(%rsi), %xmm9 + movdqu 64(%rsi), %xmm10 + movdqu 80(%rsi), %xmm11 addq $0x60, %rsi pand %xmm12, %xmm6 pand %xmm12, %xmm7 @@ -43995,7 +44762,7 @@ L_384_get_entry_256_6_start: por %xmm10, %xmm4 por %xmm11, %xmm5 decq %rax - jnz L_384_get_entry_256_6_start + jnz L_384_get_entry_64_6_start movdqu %xmm0, (%rdi) movdqu %xmm1, 16(%rdi) movdqu %xmm2, 32(%rdi) @@ -44004,8 +44771,9 @@ L_384_get_entry_256_6_start: movdqu %xmm5, 128(%rdi) repz retq #ifndef __APPLE__ -.size sp_384_get_entry_256_6,.-sp_384_get_entry_256_6 +.size sp_384_get_entry_64_6,.-sp_384_get_entry_64_6 #endif /* __APPLE__ */ +#ifdef HAVE_INTEL_AVX2 /* Touch each possible entry that could be being copied. * * r Point to copy into. @@ -44014,21 +44782,21 @@ L_384_get_entry_256_6_start: */ #ifndef __APPLE__ .text -.globl sp_384_get_entry_256_avx2_6 -.type sp_384_get_entry_256_avx2_6,@function +.globl sp_384_get_entry_64_avx2_6 +.type sp_384_get_entry_64_avx2_6,@function .align 16 -sp_384_get_entry_256_avx2_6: +sp_384_get_entry_64_avx2_6: #else .section __TEXT,__text -.globl _sp_384_get_entry_256_avx2_6 +.globl _sp_384_get_entry_64_avx2_6 .p2align 4 -_sp_384_get_entry_256_avx2_6: +_sp_384_get_entry_64_avx2_6: #endif /* __APPLE__ */ movq $0x01, %rax movd %edx, %xmm9 addq $0x60, %rsi movd %eax, %xmm11 - movq $0x100, %rax + movq $0x40, %rax vpxor %ymm10, %ymm10, %ymm10 vpermd %ymm9, %ymm10, %ymm9 vpermd %ymm11, %ymm10, %ymm11 @@ -44037,12 +44805,12 @@ _sp_384_get_entry_256_avx2_6: vpxor %ymm2, %ymm2, %ymm2 vpxor %xmm3, %xmm3, %xmm3 vmovdqa %ymm11, %ymm10 -L_384_get_entry_256_avx2_6_start: +L_384_get_entry_64_avx2_6_start: vpcmpeqd %ymm9, %ymm10, %ymm8 vpaddd %ymm11, %ymm10, %ymm10 - vmovdqu (%rsi), %ymm4 + vmovupd (%rsi), %ymm4 vmovdqu 32(%rsi), %xmm5 - vmovdqu 48(%rsi), %ymm6 + vmovupd 48(%rsi), %ymm6 vmovdqu 80(%rsi), %xmm7 addq $0x60, %rsi vpand %ymm8, %ymm4, %ymm4 @@ -44054,15 +44822,145 @@ L_384_get_entry_256_avx2_6_start: vpor %ymm6, %ymm2, %ymm2 vpor %xmm7, %xmm3, %xmm3 decq %rax - jnz L_384_get_entry_256_avx2_6_start - vmovdqu %ymm0, (%rdi) + jnz L_384_get_entry_64_avx2_6_start + vmovupd %ymm0, (%rdi) vmovdqu %xmm1, 32(%rdi) - vmovdqu %ymm2, 96(%rdi) + vmovupd %ymm2, 96(%rdi) vmovdqu %xmm3, 128(%rdi) repz retq #ifndef __APPLE__ -.size sp_384_get_entry_256_avx2_6,.-sp_384_get_entry_256_avx2_6 +.size sp_384_get_entry_64_avx2_6,.-sp_384_get_entry_64_avx2_6 #endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +#endif /* !WC_NO_CACHE_RESISTANT */ +#ifndef WC_NO_CACHE_RESISTANT +/* Touch each possible entry that could be being copied. + * + * r Point to copy into. + * table Table - start of the entires to access + * idx Index of entry to retrieve. + */ +#ifndef __APPLE__ +.text +.globl sp_384_get_entry_65_6 +.type sp_384_get_entry_65_6,@function +.align 16 +sp_384_get_entry_65_6: +#else +.section __TEXT,__text +.globl _sp_384_get_entry_65_6 +.p2align 4 +_sp_384_get_entry_65_6: +#endif /* __APPLE__ */ + movq $0x01, %rax + movd %edx, %xmm13 + addq $0x60, %rsi + movd %eax, %xmm15 + movq $0x40, %rax + pshufd $0x00, %xmm15, %xmm15 + pshufd $0x00, %xmm13, %xmm13 + pxor %xmm14, %xmm14 + pxor %xmm0, %xmm0 + pxor %xmm1, %xmm1 + pxor %xmm2, %xmm2 + pxor %xmm3, %xmm3 + pxor %xmm4, %xmm4 + pxor %xmm5, %xmm5 + movdqa %xmm15, %xmm14 +L_384_get_entry_65_6_start: + movdqa %xmm14, %xmm12 + paddd %xmm15, %xmm14 + pcmpeqd %xmm13, %xmm12 + movdqu (%rsi), %xmm6 + movdqu 16(%rsi), %xmm7 + movdqu 32(%rsi), %xmm8 + movdqu 48(%rsi), %xmm9 + movdqu 64(%rsi), %xmm10 + movdqu 80(%rsi), %xmm11 + addq $0x60, %rsi + pand %xmm12, %xmm6 + pand %xmm12, %xmm7 + pand %xmm12, %xmm8 + pand %xmm12, %xmm9 + pand %xmm12, %xmm10 + pand %xmm12, %xmm11 + por %xmm6, %xmm0 + por %xmm7, %xmm1 + por %xmm8, %xmm2 + por %xmm9, %xmm3 + por %xmm10, %xmm4 + por %xmm11, %xmm5 + decq %rax + jnz L_384_get_entry_65_6_start + movdqu %xmm0, (%rdi) + movdqu %xmm1, 16(%rdi) + movdqu %xmm2, 32(%rdi) + movdqu %xmm3, 96(%rdi) + movdqu %xmm4, 112(%rdi) + movdqu %xmm5, 128(%rdi) + repz retq +#ifndef __APPLE__ +.size sp_384_get_entry_65_6,.-sp_384_get_entry_65_6 +#endif /* __APPLE__ */ +#ifdef HAVE_INTEL_AVX2 +/* Touch each possible entry that could be being copied. + * + * r Point to copy into. + * table Table - start of the entires to access + * idx Index of entry to retrieve. + */ +#ifndef __APPLE__ +.text +.globl sp_384_get_entry_65_avx2_6 +.type sp_384_get_entry_65_avx2_6,@function +.align 16 +sp_384_get_entry_65_avx2_6: +#else +.section __TEXT,__text +.globl _sp_384_get_entry_65_avx2_6 +.p2align 4 +_sp_384_get_entry_65_avx2_6: +#endif /* __APPLE__ */ + movq $0x01, %rax + movd %edx, %xmm9 + addq $0x60, %rsi + movd %eax, %xmm11 + movq $0x41, %rax + vpxor %ymm10, %ymm10, %ymm10 + vpermd %ymm9, %ymm10, %ymm9 + vpermd %ymm11, %ymm10, %ymm11 + vpxor %ymm0, %ymm0, %ymm0 + vpxor %xmm1, %xmm1, %xmm1 + vpxor %ymm2, %ymm2, %ymm2 + vpxor %xmm3, %xmm3, %xmm3 + vmovdqa %ymm11, %ymm10 +L_384_get_entry_65_avx2_6_start: + vpcmpeqd %ymm9, %ymm10, %ymm8 + vpaddd %ymm11, %ymm10, %ymm10 + vmovupd (%rsi), %ymm4 + vmovdqu 32(%rsi), %xmm5 + vmovupd 48(%rsi), %ymm6 + vmovdqu 80(%rsi), %xmm7 + addq $0x60, %rsi + vpand %ymm8, %ymm4, %ymm4 + vpand %xmm8, %xmm5, %xmm5 + vpand %ymm8, %ymm6, %ymm6 + vpand %xmm8, %xmm7, %xmm7 + vpor %ymm4, %ymm0, %ymm0 + vpor %xmm5, %xmm1, %xmm1 + vpor %ymm6, %ymm2, %ymm2 + vpor %xmm7, %xmm3, %xmm3 + decq %rax + jnz L_384_get_entry_65_avx2_6_start + vmovupd %ymm0, (%rdi) + vmovdqu %xmm1, 32(%rdi) + vmovupd %ymm2, 96(%rdi) + vmovdqu %xmm3, 128(%rdi) + repz retq +#ifndef __APPLE__ +.size sp_384_get_entry_65_avx2_6,.-sp_384_get_entry_65_avx2_6 +#endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ #endif /* !WC_NO_CACHE_RESISTANT */ /* Add 1 to a. (a = a + 1) * @@ -44184,6 +45082,7 @@ L_384_from_bin_bswap_zero_end: #ifndef __APPLE__ .size sp_384_from_bin_bswap,.-sp_384_from_bin_bswap #endif /* __APPLE__ */ +#ifndef NO_MOVBE_SUPPORT /* Read big endian unsigned byte array into r. * Uses the movbe instruction which is an optional instruction. * @@ -44269,6 +45168,7 @@ L_384_from_bin_movbe_zero_end: #ifndef __APPLE__ .size sp_384_from_bin_movbe,.-sp_384_from_bin_movbe #endif /* __APPLE__ */ +#endif /* !NO_MOVBE_SUPPORT */ /* Write r as big endian to byte array. * Fixed length number of bytes written: 48 * Uses the bswap instruction. @@ -44310,6 +45210,7 @@ _sp_384_to_bin_bswap: #ifndef __APPLE__ .size sp_384_to_bin_bswap,.-sp_384_to_bin_bswap #endif /* __APPLE__ */ +#ifndef NO_MOVBE_SUPPORT /* Write r as big endian to byte array. * Fixed length number of bytes written: 48 * Uses the movbe instruction which is optional. @@ -44345,6 +45246,7 @@ _sp_384_to_bin_movbe: #ifndef __APPLE__ .size sp_384_to_bin_movbe,.-sp_384_to_bin_movbe #endif /* __APPLE__ */ +#endif /* NO_MOVBE_SUPPORT */ /* Sub b from a into a. (a -= b) * * a A single precision integer and result. @@ -44380,62 +45282,6 @@ _sp_384_sub_in_place_6: #ifndef __APPLE__ .size sp_384_sub_in_place_6,.-sp_384_sub_in_place_6 #endif /* __APPLE__ */ -/* Conditionally subtract b from a using the mask m. - * m is -1 to subtract and 0 when not copying. - * - * r A single precision number representing condition subtract result. - * a A single precision number to subtract from. - * b A single precision number to subtract. - * m Mask value to apply. - */ -#ifndef __APPLE__ -.text -.globl sp_384_cond_sub_avx2_6 -.type sp_384_cond_sub_avx2_6,@function -.align 16 -sp_384_cond_sub_avx2_6: -#else -.section __TEXT,__text -.globl _sp_384_cond_sub_avx2_6 -.p2align 4 -_sp_384_cond_sub_avx2_6: -#endif /* __APPLE__ */ - movq $0x00, %rax - movq (%rdx), %r10 - movq (%rsi), %r8 - pextq %rcx, %r10, %r10 - subq %r10, %r8 - movq 8(%rdx), %r10 - movq 8(%rsi), %r9 - pextq %rcx, %r10, %r10 - movq %r8, (%rdi) - sbbq %r10, %r9 - movq 16(%rdx), %r8 - movq 16(%rsi), %r10 - pextq %rcx, %r8, %r8 - movq %r9, 8(%rdi) - sbbq %r8, %r10 - movq 24(%rdx), %r9 - movq 24(%rsi), %r8 - pextq %rcx, %r9, %r9 - movq %r10, 16(%rdi) - sbbq %r9, %r8 - movq 32(%rdx), %r10 - movq 32(%rsi), %r9 - pextq %rcx, %r10, %r10 - movq %r8, 24(%rdi) - sbbq %r10, %r9 - movq 40(%rdx), %r8 - movq 40(%rsi), %r10 - pextq %rcx, %r8, %r8 - movq %r9, 32(%rdi) - sbbq %r8, %r10 - movq %r10, 40(%rdi) - sbbq $0x00, %rax - repz retq -#ifndef __APPLE__ -.size sp_384_cond_sub_avx2_6,.-sp_384_cond_sub_avx2_6 -#endif /* __APPLE__ */ /* Mul a by digit b into r. (r = a * b) * * r A single precision integer. @@ -44534,26 +45380,26 @@ _sp_384_mul_d_avx2_6: mulxq 8(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 8(%rdi) adoxq %r8, %r9 + movq %r10, 8(%rdi) # A[2] * B mulxq 16(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 16(%rdi) adoxq %r8, %r10 + movq %r9, 16(%rdi) # A[3] * B mulxq 24(%rsi), %rcx, %r8 movq %r11, %r9 adcxq %rcx, %r10 - movq %r10, 24(%rdi) adoxq %r8, %r9 + movq %r10, 24(%rdi) # A[4] * B mulxq 32(%rsi), %rcx, %r8 movq %r11, %r10 adcxq %rcx, %r9 - movq %r9, 32(%rdi) adoxq %r8, %r10 + movq %r9, 32(%rdi) # A[5] * B mulxq 40(%rsi), %rcx, %r8 movq %r11, %r9 @@ -44567,6 +45413,35 @@ _sp_384_mul_d_avx2_6: .size sp_384_mul_d_avx2_6,.-sp_384_mul_d_avx2_6 #endif /* __APPLE__ */ #endif /* HAVE_INTEL_AVX2 */ +#ifdef _WIN64 +/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) + * + * d1 The high order half of the number to divide. + * d0 The low order half of the number to divide. + * div The dividend. + * returns the result of the division. + */ +#ifndef __APPLE__ +.text +.globl div_384_word_asm_6 +.type div_384_word_asm_6,@function +.align 16 +div_384_word_asm_6: +#else +.section __TEXT,__text +.globl _div_384_word_asm_6 +.p2align 4 +_div_384_word_asm_6: +#endif /* __APPLE__ */ + movq %rdx, %rcx + movq %rsi, %rax + movq %rdi, %rdx + divq %rcx + repz retq +#ifndef __APPLE__ +.size div_384_word_asm_6,.-div_384_word_asm_6 +#endif /* __APPLE__ */ +#endif /* _WIN64 */ /* Shift number right by 1 bit. (r = a >> 1) * * r Result of right shift by 1. @@ -44743,6 +45618,9133 @@ L_384_num_bits_6_done: .size sp_384_num_bits_6,.-sp_384_num_bits_6 #endif /* __APPLE__ */ #endif /* WOLFSSL_SP_384 */ +#ifdef WOLFSSL_SP_1024 +/* Multiply a and b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +#ifndef __APPLE__ +.text +.globl sp_1024_mul_16 +.type sp_1024_mul_16,@function +.align 16 +sp_1024_mul_16: +#else +.section __TEXT,__text +.globl _sp_1024_mul_16 +.p2align 4 +_sp_1024_mul_16: +#endif /* __APPLE__ */ + movq %rdx, %rcx + subq $0x80, %rsp + # A[0] * B[0] + movq (%rcx), %rax + mulq (%rsi) + xorq %r10, %r10 + movq %rax, (%rsp) + movq %rdx, %r9 + # A[0] * B[1] + movq 8(%rcx), %rax + mulq (%rsi) + xorq %r8, %r8 + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[1] * B[0] + movq (%rcx), %rax + mulq 8(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + movq %r9, 8(%rsp) + # A[0] * B[2] + movq 16(%rcx), %rax + mulq (%rsi) + xorq %r9, %r9 + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[1] * B[1] + movq 8(%rcx), %rax + mulq 8(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[2] * B[0] + movq (%rcx), %rax + mulq 16(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + movq %r10, 16(%rsp) + # A[0] * B[3] + movq 24(%rcx), %rax + mulq (%rsi) + xorq %r10, %r10 + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[1] * B[2] + movq 16(%rcx), %rax + mulq 8(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[2] * B[1] + movq 8(%rcx), %rax + mulq 16(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[3] * B[0] + movq (%rcx), %rax + mulq 24(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + movq %r8, 24(%rsp) + # A[0] * B[4] + movq 32(%rcx), %rax + mulq (%rsi) + xorq %r8, %r8 + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[1] * B[3] + movq 24(%rcx), %rax + mulq 8(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[2] * B[2] + movq 16(%rcx), %rax + mulq 16(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[3] * B[1] + movq 8(%rcx), %rax + mulq 24(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[4] * B[0] + movq (%rcx), %rax + mulq 32(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + movq %r9, 32(%rsp) + # A[0] * B[5] + movq 40(%rcx), %rax + mulq (%rsi) + xorq %r9, %r9 + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[1] * B[4] + movq 32(%rcx), %rax + mulq 8(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[2] * B[3] + movq 24(%rcx), %rax + mulq 16(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[3] * B[2] + movq 16(%rcx), %rax + mulq 24(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[4] * B[1] + movq 8(%rcx), %rax + mulq 32(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[5] * B[0] + movq (%rcx), %rax + mulq 40(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + movq %r10, 40(%rsp) + # A[0] * B[6] + movq 48(%rcx), %rax + mulq (%rsi) + xorq %r10, %r10 + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[1] * B[5] + movq 40(%rcx), %rax + mulq 8(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[2] * B[4] + movq 32(%rcx), %rax + mulq 16(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[3] * B[3] + movq 24(%rcx), %rax + mulq 24(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[4] * B[2] + movq 16(%rcx), %rax + mulq 32(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[5] * B[1] + movq 8(%rcx), %rax + mulq 40(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[6] * B[0] + movq (%rcx), %rax + mulq 48(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + movq %r8, 48(%rsp) + # A[0] * B[7] + movq 56(%rcx), %rax + mulq (%rsi) + xorq %r8, %r8 + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[1] * B[6] + movq 48(%rcx), %rax + mulq 8(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[2] * B[5] + movq 40(%rcx), %rax + mulq 16(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[3] * B[4] + movq 32(%rcx), %rax + mulq 24(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[4] * B[3] + movq 24(%rcx), %rax + mulq 32(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[5] * B[2] + movq 16(%rcx), %rax + mulq 40(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[6] * B[1] + movq 8(%rcx), %rax + mulq 48(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[7] * B[0] + movq (%rcx), %rax + mulq 56(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + movq %r9, 56(%rsp) + # A[0] * B[8] + movq 64(%rcx), %rax + mulq (%rsi) + xorq %r9, %r9 + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[1] * B[7] + movq 56(%rcx), %rax + mulq 8(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[2] * B[6] + movq 48(%rcx), %rax + mulq 16(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[3] * B[5] + movq 40(%rcx), %rax + mulq 24(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[4] * B[4] + movq 32(%rcx), %rax + mulq 32(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[5] * B[3] + movq 24(%rcx), %rax + mulq 40(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[6] * B[2] + movq 16(%rcx), %rax + mulq 48(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[7] * B[1] + movq 8(%rcx), %rax + mulq 56(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[8] * B[0] + movq (%rcx), %rax + mulq 64(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + movq %r10, 64(%rsp) + # A[0] * B[9] + movq 72(%rcx), %rax + mulq (%rsi) + xorq %r10, %r10 + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[1] * B[8] + movq 64(%rcx), %rax + mulq 8(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[2] * B[7] + movq 56(%rcx), %rax + mulq 16(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[3] * B[6] + movq 48(%rcx), %rax + mulq 24(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[4] * B[5] + movq 40(%rcx), %rax + mulq 32(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[5] * B[4] + movq 32(%rcx), %rax + mulq 40(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[6] * B[3] + movq 24(%rcx), %rax + mulq 48(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[7] * B[2] + movq 16(%rcx), %rax + mulq 56(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[8] * B[1] + movq 8(%rcx), %rax + mulq 64(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[9] * B[0] + movq (%rcx), %rax + mulq 72(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + movq %r8, 72(%rsp) + # A[0] * B[10] + movq 80(%rcx), %rax + mulq (%rsi) + xorq %r8, %r8 + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[1] * B[9] + movq 72(%rcx), %rax + mulq 8(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[2] * B[8] + movq 64(%rcx), %rax + mulq 16(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[3] * B[7] + movq 56(%rcx), %rax + mulq 24(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[4] * B[6] + movq 48(%rcx), %rax + mulq 32(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[5] * B[5] + movq 40(%rcx), %rax + mulq 40(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[6] * B[4] + movq 32(%rcx), %rax + mulq 48(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[7] * B[3] + movq 24(%rcx), %rax + mulq 56(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[8] * B[2] + movq 16(%rcx), %rax + mulq 64(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[9] * B[1] + movq 8(%rcx), %rax + mulq 72(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[10] * B[0] + movq (%rcx), %rax + mulq 80(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + movq %r9, 80(%rsp) + # A[0] * B[11] + movq 88(%rcx), %rax + mulq (%rsi) + xorq %r9, %r9 + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[1] * B[10] + movq 80(%rcx), %rax + mulq 8(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[2] * B[9] + movq 72(%rcx), %rax + mulq 16(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[3] * B[8] + movq 64(%rcx), %rax + mulq 24(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[4] * B[7] + movq 56(%rcx), %rax + mulq 32(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[5] * B[6] + movq 48(%rcx), %rax + mulq 40(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[6] * B[5] + movq 40(%rcx), %rax + mulq 48(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[7] * B[4] + movq 32(%rcx), %rax + mulq 56(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[8] * B[3] + movq 24(%rcx), %rax + mulq 64(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[9] * B[2] + movq 16(%rcx), %rax + mulq 72(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[10] * B[1] + movq 8(%rcx), %rax + mulq 80(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[11] * B[0] + movq (%rcx), %rax + mulq 88(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + movq %r10, 88(%rsp) + # A[0] * B[12] + movq 96(%rcx), %rax + mulq (%rsi) + xorq %r10, %r10 + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[1] * B[11] + movq 88(%rcx), %rax + mulq 8(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[2] * B[10] + movq 80(%rcx), %rax + mulq 16(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[3] * B[9] + movq 72(%rcx), %rax + mulq 24(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[4] * B[8] + movq 64(%rcx), %rax + mulq 32(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[5] * B[7] + movq 56(%rcx), %rax + mulq 40(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[6] * B[6] + movq 48(%rcx), %rax + mulq 48(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[7] * B[5] + movq 40(%rcx), %rax + mulq 56(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[8] * B[4] + movq 32(%rcx), %rax + mulq 64(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[9] * B[3] + movq 24(%rcx), %rax + mulq 72(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[10] * B[2] + movq 16(%rcx), %rax + mulq 80(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[11] * B[1] + movq 8(%rcx), %rax + mulq 88(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[12] * B[0] + movq (%rcx), %rax + mulq 96(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + movq %r8, 96(%rsp) + # A[0] * B[13] + movq 104(%rcx), %rax + mulq (%rsi) + xorq %r8, %r8 + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[1] * B[12] + movq 96(%rcx), %rax + mulq 8(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[2] * B[11] + movq 88(%rcx), %rax + mulq 16(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[3] * B[10] + movq 80(%rcx), %rax + mulq 24(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[4] * B[9] + movq 72(%rcx), %rax + mulq 32(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[5] * B[8] + movq 64(%rcx), %rax + mulq 40(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[6] * B[7] + movq 56(%rcx), %rax + mulq 48(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[7] * B[6] + movq 48(%rcx), %rax + mulq 56(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[8] * B[5] + movq 40(%rcx), %rax + mulq 64(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[9] * B[4] + movq 32(%rcx), %rax + mulq 72(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[10] * B[3] + movq 24(%rcx), %rax + mulq 80(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[11] * B[2] + movq 16(%rcx), %rax + mulq 88(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[12] * B[1] + movq 8(%rcx), %rax + mulq 96(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[13] * B[0] + movq (%rcx), %rax + mulq 104(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + movq %r9, 104(%rsp) + # A[0] * B[14] + movq 112(%rcx), %rax + mulq (%rsi) + xorq %r9, %r9 + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[1] * B[13] + movq 104(%rcx), %rax + mulq 8(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[2] * B[12] + movq 96(%rcx), %rax + mulq 16(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[3] * B[11] + movq 88(%rcx), %rax + mulq 24(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[4] * B[10] + movq 80(%rcx), %rax + mulq 32(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[5] * B[9] + movq 72(%rcx), %rax + mulq 40(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[6] * B[8] + movq 64(%rcx), %rax + mulq 48(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[7] * B[7] + movq 56(%rcx), %rax + mulq 56(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[8] * B[6] + movq 48(%rcx), %rax + mulq 64(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[9] * B[5] + movq 40(%rcx), %rax + mulq 72(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[10] * B[4] + movq 32(%rcx), %rax + mulq 80(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[11] * B[3] + movq 24(%rcx), %rax + mulq 88(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[12] * B[2] + movq 16(%rcx), %rax + mulq 96(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[13] * B[1] + movq 8(%rcx), %rax + mulq 104(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[14] * B[0] + movq (%rcx), %rax + mulq 112(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + movq %r10, 112(%rsp) + # A[0] * B[15] + movq 120(%rcx), %rax + mulq (%rsi) + xorq %r10, %r10 + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[1] * B[14] + movq 112(%rcx), %rax + mulq 8(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[2] * B[13] + movq 104(%rcx), %rax + mulq 16(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[3] * B[12] + movq 96(%rcx), %rax + mulq 24(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[4] * B[11] + movq 88(%rcx), %rax + mulq 32(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[5] * B[10] + movq 80(%rcx), %rax + mulq 40(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[6] * B[9] + movq 72(%rcx), %rax + mulq 48(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[7] * B[8] + movq 64(%rcx), %rax + mulq 56(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[8] * B[7] + movq 56(%rcx), %rax + mulq 64(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[9] * B[6] + movq 48(%rcx), %rax + mulq 72(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[10] * B[5] + movq 40(%rcx), %rax + mulq 80(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[11] * B[4] + movq 32(%rcx), %rax + mulq 88(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[12] * B[3] + movq 24(%rcx), %rax + mulq 96(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[13] * B[2] + movq 16(%rcx), %rax + mulq 104(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[14] * B[1] + movq 8(%rcx), %rax + mulq 112(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[15] * B[0] + movq (%rcx), %rax + mulq 120(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + movq %r8, 120(%rsp) + # A[1] * B[15] + movq 120(%rcx), %rax + mulq 8(%rsi) + xorq %r8, %r8 + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[2] * B[14] + movq 112(%rcx), %rax + mulq 16(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[3] * B[13] + movq 104(%rcx), %rax + mulq 24(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[4] * B[12] + movq 96(%rcx), %rax + mulq 32(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[5] * B[11] + movq 88(%rcx), %rax + mulq 40(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[6] * B[10] + movq 80(%rcx), %rax + mulq 48(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[7] * B[9] + movq 72(%rcx), %rax + mulq 56(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[8] * B[8] + movq 64(%rcx), %rax + mulq 64(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[9] * B[7] + movq 56(%rcx), %rax + mulq 72(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[10] * B[6] + movq 48(%rcx), %rax + mulq 80(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[11] * B[5] + movq 40(%rcx), %rax + mulq 88(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[12] * B[4] + movq 32(%rcx), %rax + mulq 96(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[13] * B[3] + movq 24(%rcx), %rax + mulq 104(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[14] * B[2] + movq 16(%rcx), %rax + mulq 112(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[15] * B[1] + movq 8(%rcx), %rax + mulq 120(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + movq %r9, 128(%rdi) + # A[2] * B[15] + movq 120(%rcx), %rax + mulq 16(%rsi) + xorq %r9, %r9 + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[3] * B[14] + movq 112(%rcx), %rax + mulq 24(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[4] * B[13] + movq 104(%rcx), %rax + mulq 32(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[5] * B[12] + movq 96(%rcx), %rax + mulq 40(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[6] * B[11] + movq 88(%rcx), %rax + mulq 48(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[7] * B[10] + movq 80(%rcx), %rax + mulq 56(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[8] * B[9] + movq 72(%rcx), %rax + mulq 64(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[9] * B[8] + movq 64(%rcx), %rax + mulq 72(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[10] * B[7] + movq 56(%rcx), %rax + mulq 80(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[11] * B[6] + movq 48(%rcx), %rax + mulq 88(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[12] * B[5] + movq 40(%rcx), %rax + mulq 96(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[13] * B[4] + movq 32(%rcx), %rax + mulq 104(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[14] * B[3] + movq 24(%rcx), %rax + mulq 112(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[15] * B[2] + movq 16(%rcx), %rax + mulq 120(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + movq %r10, 136(%rdi) + # A[3] * B[15] + movq 120(%rcx), %rax + mulq 24(%rsi) + xorq %r10, %r10 + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[4] * B[14] + movq 112(%rcx), %rax + mulq 32(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[5] * B[13] + movq 104(%rcx), %rax + mulq 40(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[6] * B[12] + movq 96(%rcx), %rax + mulq 48(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[7] * B[11] + movq 88(%rcx), %rax + mulq 56(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[8] * B[10] + movq 80(%rcx), %rax + mulq 64(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[9] * B[9] + movq 72(%rcx), %rax + mulq 72(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[10] * B[8] + movq 64(%rcx), %rax + mulq 80(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[11] * B[7] + movq 56(%rcx), %rax + mulq 88(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[12] * B[6] + movq 48(%rcx), %rax + mulq 96(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[13] * B[5] + movq 40(%rcx), %rax + mulq 104(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[14] * B[4] + movq 32(%rcx), %rax + mulq 112(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[15] * B[3] + movq 24(%rcx), %rax + mulq 120(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + movq %r8, 144(%rdi) + # A[4] * B[15] + movq 120(%rcx), %rax + mulq 32(%rsi) + xorq %r8, %r8 + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[5] * B[14] + movq 112(%rcx), %rax + mulq 40(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[6] * B[13] + movq 104(%rcx), %rax + mulq 48(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[7] * B[12] + movq 96(%rcx), %rax + mulq 56(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[8] * B[11] + movq 88(%rcx), %rax + mulq 64(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[9] * B[10] + movq 80(%rcx), %rax + mulq 72(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[10] * B[9] + movq 72(%rcx), %rax + mulq 80(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[11] * B[8] + movq 64(%rcx), %rax + mulq 88(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[12] * B[7] + movq 56(%rcx), %rax + mulq 96(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[13] * B[6] + movq 48(%rcx), %rax + mulq 104(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[14] * B[5] + movq 40(%rcx), %rax + mulq 112(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[15] * B[4] + movq 32(%rcx), %rax + mulq 120(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + movq %r9, 152(%rdi) + # A[5] * B[15] + movq 120(%rcx), %rax + mulq 40(%rsi) + xorq %r9, %r9 + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[6] * B[14] + movq 112(%rcx), %rax + mulq 48(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[7] * B[13] + movq 104(%rcx), %rax + mulq 56(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[8] * B[12] + movq 96(%rcx), %rax + mulq 64(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[9] * B[11] + movq 88(%rcx), %rax + mulq 72(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[10] * B[10] + movq 80(%rcx), %rax + mulq 80(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[11] * B[9] + movq 72(%rcx), %rax + mulq 88(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[12] * B[8] + movq 64(%rcx), %rax + mulq 96(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[13] * B[7] + movq 56(%rcx), %rax + mulq 104(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[14] * B[6] + movq 48(%rcx), %rax + mulq 112(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[15] * B[5] + movq 40(%rcx), %rax + mulq 120(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + movq %r10, 160(%rdi) + # A[6] * B[15] + movq 120(%rcx), %rax + mulq 48(%rsi) + xorq %r10, %r10 + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[7] * B[14] + movq 112(%rcx), %rax + mulq 56(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[8] * B[13] + movq 104(%rcx), %rax + mulq 64(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[9] * B[12] + movq 96(%rcx), %rax + mulq 72(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[10] * B[11] + movq 88(%rcx), %rax + mulq 80(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[11] * B[10] + movq 80(%rcx), %rax + mulq 88(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[12] * B[9] + movq 72(%rcx), %rax + mulq 96(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[13] * B[8] + movq 64(%rcx), %rax + mulq 104(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[14] * B[7] + movq 56(%rcx), %rax + mulq 112(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[15] * B[6] + movq 48(%rcx), %rax + mulq 120(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + movq %r8, 168(%rdi) + # A[7] * B[15] + movq 120(%rcx), %rax + mulq 56(%rsi) + xorq %r8, %r8 + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[8] * B[14] + movq 112(%rcx), %rax + mulq 64(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[9] * B[13] + movq 104(%rcx), %rax + mulq 72(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[10] * B[12] + movq 96(%rcx), %rax + mulq 80(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[11] * B[11] + movq 88(%rcx), %rax + mulq 88(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[12] * B[10] + movq 80(%rcx), %rax + mulq 96(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[13] * B[9] + movq 72(%rcx), %rax + mulq 104(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[14] * B[8] + movq 64(%rcx), %rax + mulq 112(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[15] * B[7] + movq 56(%rcx), %rax + mulq 120(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + movq %r9, 176(%rdi) + # A[8] * B[15] + movq 120(%rcx), %rax + mulq 64(%rsi) + xorq %r9, %r9 + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[9] * B[14] + movq 112(%rcx), %rax + mulq 72(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[10] * B[13] + movq 104(%rcx), %rax + mulq 80(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[11] * B[12] + movq 96(%rcx), %rax + mulq 88(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[12] * B[11] + movq 88(%rcx), %rax + mulq 96(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[13] * B[10] + movq 80(%rcx), %rax + mulq 104(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[14] * B[9] + movq 72(%rcx), %rax + mulq 112(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[15] * B[8] + movq 64(%rcx), %rax + mulq 120(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + movq %r10, 184(%rdi) + # A[9] * B[15] + movq 120(%rcx), %rax + mulq 72(%rsi) + xorq %r10, %r10 + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[10] * B[14] + movq 112(%rcx), %rax + mulq 80(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[11] * B[13] + movq 104(%rcx), %rax + mulq 88(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[12] * B[12] + movq 96(%rcx), %rax + mulq 96(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[13] * B[11] + movq 88(%rcx), %rax + mulq 104(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[14] * B[10] + movq 80(%rcx), %rax + mulq 112(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[15] * B[9] + movq 72(%rcx), %rax + mulq 120(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + movq %r8, 192(%rdi) + # A[10] * B[15] + movq 120(%rcx), %rax + mulq 80(%rsi) + xorq %r8, %r8 + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[11] * B[14] + movq 112(%rcx), %rax + mulq 88(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[12] * B[13] + movq 104(%rcx), %rax + mulq 96(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[13] * B[12] + movq 96(%rcx), %rax + mulq 104(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[14] * B[11] + movq 88(%rcx), %rax + mulq 112(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[15] * B[10] + movq 80(%rcx), %rax + mulq 120(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + movq %r9, 200(%rdi) + # A[11] * B[15] + movq 120(%rcx), %rax + mulq 88(%rsi) + xorq %r9, %r9 + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[12] * B[14] + movq 112(%rcx), %rax + mulq 96(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[13] * B[13] + movq 104(%rcx), %rax + mulq 104(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[14] * B[12] + movq 96(%rcx), %rax + mulq 112(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[15] * B[11] + movq 88(%rcx), %rax + mulq 120(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + movq %r10, 208(%rdi) + # A[12] * B[15] + movq 120(%rcx), %rax + mulq 96(%rsi) + xorq %r10, %r10 + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[13] * B[14] + movq 112(%rcx), %rax + mulq 104(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[14] * B[13] + movq 104(%rcx), %rax + mulq 112(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[15] * B[12] + movq 96(%rcx), %rax + mulq 120(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %r10 + movq %r8, 216(%rdi) + # A[13] * B[15] + movq 120(%rcx), %rax + mulq 104(%rsi) + xorq %r8, %r8 + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[14] * B[14] + movq 112(%rcx), %rax + mulq 112(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[15] * B[13] + movq 104(%rcx), %rax + mulq 120(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0x00, %r8 + movq %r9, 224(%rdi) + # A[14] * B[15] + movq 120(%rcx), %rax + mulq 112(%rsi) + xorq %r9, %r9 + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[15] * B[14] + movq 112(%rcx), %rax + mulq 120(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0x00, %r9 + movq %r10, 232(%rdi) + # A[15] * B[15] + movq 120(%rcx), %rax + mulq 120(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + movq %r8, 240(%rdi) + movq %r9, 248(%rdi) + movq (%rsp), %rax + movq 8(%rsp), %rdx + movq 16(%rsp), %r8 + movq 24(%rsp), %r9 + movq %rax, (%rdi) + movq %rdx, 8(%rdi) + movq %r8, 16(%rdi) + movq %r9, 24(%rdi) + movq 32(%rsp), %rax + movq 40(%rsp), %rdx + movq 48(%rsp), %r8 + movq 56(%rsp), %r9 + movq %rax, 32(%rdi) + movq %rdx, 40(%rdi) + movq %r8, 48(%rdi) + movq %r9, 56(%rdi) + movq 64(%rsp), %rax + movq 72(%rsp), %rdx + movq 80(%rsp), %r8 + movq 88(%rsp), %r9 + movq %rax, 64(%rdi) + movq %rdx, 72(%rdi) + movq %r8, 80(%rdi) + movq %r9, 88(%rdi) + movq 96(%rsp), %rax + movq 104(%rsp), %rdx + movq 112(%rsp), %r8 + movq 120(%rsp), %r9 + movq %rax, 96(%rdi) + movq %rdx, 104(%rdi) + movq %r8, 112(%rdi) + movq %r9, 120(%rdi) + addq $0x80, %rsp + repz retq +#ifndef __APPLE__ +.size sp_1024_mul_16,.-sp_1024_mul_16 +#endif /* __APPLE__ */ +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +#ifndef __APPLE__ +.text +.globl sp_1024_sqr_16 +.type sp_1024_sqr_16,@function +.align 16 +sp_1024_sqr_16: +#else +.section __TEXT,__text +.globl _sp_1024_sqr_16 +.p2align 4 +_sp_1024_sqr_16: +#endif /* __APPLE__ */ + pushq %r12 + subq $0x80, %rsp + # A[0] * A[0] + movq (%rsi), %rax + mulq %rax + xorq %r9, %r9 + movq %rax, (%rsp) + movq %rdx, %r8 + # A[0] * A[1] + movq 8(%rsi), %rax + mulq (%rsi) + xorq %rcx, %rcx + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %rcx + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %rcx + movq %r8, 8(%rsp) + # A[0] * A[2] + movq 16(%rsi), %rax + mulq (%rsi) + xorq %r8, %r8 + addq %rax, %r9 + adcq %rdx, %rcx + adcq $0x00, %r8 + addq %rax, %r9 + adcq %rdx, %rcx + adcq $0x00, %r8 + # A[1] * A[1] + movq 8(%rsi), %rax + mulq %rax + addq %rax, %r9 + adcq %rdx, %rcx + adcq $0x00, %r8 + movq %r9, 16(%rsp) + # A[0] * A[3] + movq 24(%rsi), %rax + mulq (%rsi) + xorq %r9, %r9 + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0x00, %r9 + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[1] * A[2] + movq 16(%rsi), %rax + mulq 8(%rsi) + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0x00, %r9 + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0x00, %r9 + movq %rcx, 24(%rsp) + # A[0] * A[4] + movq 32(%rsi), %rax + mulq (%rsi) + xorq %rcx, %rcx + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %rcx + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %rcx + # A[1] * A[3] + movq 24(%rsi), %rax + mulq 8(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %rcx + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %rcx + # A[2] * A[2] + movq 16(%rsi), %rax + mulq %rax + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %rcx + movq %r8, 32(%rsp) + # A[0] * A[5] + movq 40(%rsi), %rax + mulq (%rsi) + xorq %r8, %r8 + xorq %r12, %r12 + movq %rax, %r10 + movq %rdx, %r11 + # A[1] * A[4] + movq 32(%rsi), %rax + mulq 8(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[2] * A[3] + movq 24(%rsi), %rax + mulq 16(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + addq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + addq %r10, %r9 + adcq %r11, %rcx + adcq %r12, %r8 + movq %r9, 40(%rsp) + # A[0] * A[6] + movq 48(%rsi), %rax + mulq (%rsi) + xorq %r9, %r9 + xorq %r12, %r12 + movq %rax, %r10 + movq %rdx, %r11 + # A[1] * A[5] + movq 40(%rsi), %rax + mulq 8(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[2] * A[4] + movq 32(%rsi), %rax + mulq 16(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[3] * A[3] + movq 24(%rsi), %rax + mulq %rax + addq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + addq %r10, %rcx + adcq %r11, %r8 + adcq %r12, %r9 + movq %rcx, 48(%rsp) + # A[0] * A[7] + movq 56(%rsi), %rax + mulq (%rsi) + xorq %rcx, %rcx + xorq %r12, %r12 + movq %rax, %r10 + movq %rdx, %r11 + # A[1] * A[6] + movq 48(%rsi), %rax + mulq 8(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[2] * A[5] + movq 40(%rsi), %rax + mulq 16(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[3] * A[4] + movq 32(%rsi), %rax + mulq 24(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + addq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + addq %r10, %r8 + adcq %r11, %r9 + adcq %r12, %rcx + movq %r8, 56(%rsp) + # A[0] * A[8] + movq 64(%rsi), %rax + mulq (%rsi) + xorq %r8, %r8 + xorq %r12, %r12 + movq %rax, %r10 + movq %rdx, %r11 + # A[1] * A[7] + movq 56(%rsi), %rax + mulq 8(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[2] * A[6] + movq 48(%rsi), %rax + mulq 16(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[3] * A[5] + movq 40(%rsi), %rax + mulq 24(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[4] * A[4] + movq 32(%rsi), %rax + mulq %rax + addq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + addq %r10, %r9 + adcq %r11, %rcx + adcq %r12, %r8 + movq %r9, 64(%rsp) + # A[0] * A[9] + movq 72(%rsi), %rax + mulq (%rsi) + xorq %r9, %r9 + xorq %r12, %r12 + movq %rax, %r10 + movq %rdx, %r11 + # A[1] * A[8] + movq 64(%rsi), %rax + mulq 8(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[2] * A[7] + movq 56(%rsi), %rax + mulq 16(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[3] * A[6] + movq 48(%rsi), %rax + mulq 24(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[4] * A[5] + movq 40(%rsi), %rax + mulq 32(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + addq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + addq %r10, %rcx + adcq %r11, %r8 + adcq %r12, %r9 + movq %rcx, 72(%rsp) + # A[0] * A[10] + movq 80(%rsi), %rax + mulq (%rsi) + xorq %rcx, %rcx + xorq %r12, %r12 + movq %rax, %r10 + movq %rdx, %r11 + # A[1] * A[9] + movq 72(%rsi), %rax + mulq 8(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[2] * A[8] + movq 64(%rsi), %rax + mulq 16(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[3] * A[7] + movq 56(%rsi), %rax + mulq 24(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[4] * A[6] + movq 48(%rsi), %rax + mulq 32(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[5] * A[5] + movq 40(%rsi), %rax + mulq %rax + addq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + addq %r10, %r8 + adcq %r11, %r9 + adcq %r12, %rcx + movq %r8, 80(%rsp) + # A[0] * A[11] + movq 88(%rsi), %rax + mulq (%rsi) + xorq %r8, %r8 + xorq %r12, %r12 + movq %rax, %r10 + movq %rdx, %r11 + # A[1] * A[10] + movq 80(%rsi), %rax + mulq 8(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[2] * A[9] + movq 72(%rsi), %rax + mulq 16(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[3] * A[8] + movq 64(%rsi), %rax + mulq 24(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[4] * A[7] + movq 56(%rsi), %rax + mulq 32(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[5] * A[6] + movq 48(%rsi), %rax + mulq 40(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + addq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + addq %r10, %r9 + adcq %r11, %rcx + adcq %r12, %r8 + movq %r9, 88(%rsp) + # A[0] * A[12] + movq 96(%rsi), %rax + mulq (%rsi) + xorq %r9, %r9 + xorq %r12, %r12 + movq %rax, %r10 + movq %rdx, %r11 + # A[1] * A[11] + movq 88(%rsi), %rax + mulq 8(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[2] * A[10] + movq 80(%rsi), %rax + mulq 16(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[3] * A[9] + movq 72(%rsi), %rax + mulq 24(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[4] * A[8] + movq 64(%rsi), %rax + mulq 32(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[5] * A[7] + movq 56(%rsi), %rax + mulq 40(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[6] * A[6] + movq 48(%rsi), %rax + mulq %rax + addq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + addq %r10, %rcx + adcq %r11, %r8 + adcq %r12, %r9 + movq %rcx, 96(%rsp) + # A[0] * A[13] + movq 104(%rsi), %rax + mulq (%rsi) + xorq %rcx, %rcx + xorq %r12, %r12 + movq %rax, %r10 + movq %rdx, %r11 + # A[1] * A[12] + movq 96(%rsi), %rax + mulq 8(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[2] * A[11] + movq 88(%rsi), %rax + mulq 16(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[3] * A[10] + movq 80(%rsi), %rax + mulq 24(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[4] * A[9] + movq 72(%rsi), %rax + mulq 32(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[5] * A[8] + movq 64(%rsi), %rax + mulq 40(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[6] * A[7] + movq 56(%rsi), %rax + mulq 48(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + addq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + addq %r10, %r8 + adcq %r11, %r9 + adcq %r12, %rcx + movq %r8, 104(%rsp) + # A[0] * A[14] + movq 112(%rsi), %rax + mulq (%rsi) + xorq %r8, %r8 + xorq %r12, %r12 + movq %rax, %r10 + movq %rdx, %r11 + # A[1] * A[13] + movq 104(%rsi), %rax + mulq 8(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[2] * A[12] + movq 96(%rsi), %rax + mulq 16(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[3] * A[11] + movq 88(%rsi), %rax + mulq 24(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[4] * A[10] + movq 80(%rsi), %rax + mulq 32(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[5] * A[9] + movq 72(%rsi), %rax + mulq 40(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[6] * A[8] + movq 64(%rsi), %rax + mulq 48(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[7] * A[7] + movq 56(%rsi), %rax + mulq %rax + addq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + addq %r10, %r9 + adcq %r11, %rcx + adcq %r12, %r8 + movq %r9, 112(%rsp) + # A[0] * A[15] + movq 120(%rsi), %rax + mulq (%rsi) + xorq %r9, %r9 + xorq %r12, %r12 + movq %rax, %r10 + movq %rdx, %r11 + # A[1] * A[14] + movq 112(%rsi), %rax + mulq 8(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[2] * A[13] + movq 104(%rsi), %rax + mulq 16(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[3] * A[12] + movq 96(%rsi), %rax + mulq 24(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[4] * A[11] + movq 88(%rsi), %rax + mulq 32(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[5] * A[10] + movq 80(%rsi), %rax + mulq 40(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[6] * A[9] + movq 72(%rsi), %rax + mulq 48(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[7] * A[8] + movq 64(%rsi), %rax + mulq 56(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + addq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + addq %r10, %rcx + adcq %r11, %r8 + adcq %r12, %r9 + movq %rcx, 120(%rsp) + # A[1] * A[15] + movq 120(%rsi), %rax + mulq 8(%rsi) + xorq %rcx, %rcx + xorq %r12, %r12 + movq %rax, %r10 + movq %rdx, %r11 + # A[2] * A[14] + movq 112(%rsi), %rax + mulq 16(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[3] * A[13] + movq 104(%rsi), %rax + mulq 24(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[4] * A[12] + movq 96(%rsi), %rax + mulq 32(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[5] * A[11] + movq 88(%rsi), %rax + mulq 40(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[6] * A[10] + movq 80(%rsi), %rax + mulq 48(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[7] * A[9] + movq 72(%rsi), %rax + mulq 56(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[8] * A[8] + movq 64(%rsi), %rax + mulq %rax + addq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + addq %r10, %r8 + adcq %r11, %r9 + adcq %r12, %rcx + movq %r8, 128(%rdi) + # A[2] * A[15] + movq 120(%rsi), %rax + mulq 16(%rsi) + xorq %r8, %r8 + xorq %r12, %r12 + movq %rax, %r10 + movq %rdx, %r11 + # A[3] * A[14] + movq 112(%rsi), %rax + mulq 24(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[4] * A[13] + movq 104(%rsi), %rax + mulq 32(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[5] * A[12] + movq 96(%rsi), %rax + mulq 40(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[6] * A[11] + movq 88(%rsi), %rax + mulq 48(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[7] * A[10] + movq 80(%rsi), %rax + mulq 56(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[8] * A[9] + movq 72(%rsi), %rax + mulq 64(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + addq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + addq %r10, %r9 + adcq %r11, %rcx + adcq %r12, %r8 + movq %r9, 136(%rdi) + # A[3] * A[15] + movq 120(%rsi), %rax + mulq 24(%rsi) + xorq %r9, %r9 + xorq %r12, %r12 + movq %rax, %r10 + movq %rdx, %r11 + # A[4] * A[14] + movq 112(%rsi), %rax + mulq 32(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[5] * A[13] + movq 104(%rsi), %rax + mulq 40(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[6] * A[12] + movq 96(%rsi), %rax + mulq 48(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[7] * A[11] + movq 88(%rsi), %rax + mulq 56(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[8] * A[10] + movq 80(%rsi), %rax + mulq 64(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[9] * A[9] + movq 72(%rsi), %rax + mulq %rax + addq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + addq %r10, %rcx + adcq %r11, %r8 + adcq %r12, %r9 + movq %rcx, 144(%rdi) + # A[4] * A[15] + movq 120(%rsi), %rax + mulq 32(%rsi) + xorq %rcx, %rcx + xorq %r12, %r12 + movq %rax, %r10 + movq %rdx, %r11 + # A[5] * A[14] + movq 112(%rsi), %rax + mulq 40(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[6] * A[13] + movq 104(%rsi), %rax + mulq 48(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[7] * A[12] + movq 96(%rsi), %rax + mulq 56(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[8] * A[11] + movq 88(%rsi), %rax + mulq 64(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[9] * A[10] + movq 80(%rsi), %rax + mulq 72(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + addq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + addq %r10, %r8 + adcq %r11, %r9 + adcq %r12, %rcx + movq %r8, 152(%rdi) + # A[5] * A[15] + movq 120(%rsi), %rax + mulq 40(%rsi) + xorq %r8, %r8 + xorq %r12, %r12 + movq %rax, %r10 + movq %rdx, %r11 + # A[6] * A[14] + movq 112(%rsi), %rax + mulq 48(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[7] * A[13] + movq 104(%rsi), %rax + mulq 56(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[8] * A[12] + movq 96(%rsi), %rax + mulq 64(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[9] * A[11] + movq 88(%rsi), %rax + mulq 72(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[10] * A[10] + movq 80(%rsi), %rax + mulq %rax + addq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + addq %r10, %r9 + adcq %r11, %rcx + adcq %r12, %r8 + movq %r9, 160(%rdi) + # A[6] * A[15] + movq 120(%rsi), %rax + mulq 48(%rsi) + xorq %r9, %r9 + xorq %r12, %r12 + movq %rax, %r10 + movq %rdx, %r11 + # A[7] * A[14] + movq 112(%rsi), %rax + mulq 56(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[8] * A[13] + movq 104(%rsi), %rax + mulq 64(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[9] * A[12] + movq 96(%rsi), %rax + mulq 72(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[10] * A[11] + movq 88(%rsi), %rax + mulq 80(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + addq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + addq %r10, %rcx + adcq %r11, %r8 + adcq %r12, %r9 + movq %rcx, 168(%rdi) + # A[7] * A[15] + movq 120(%rsi), %rax + mulq 56(%rsi) + xorq %rcx, %rcx + xorq %r12, %r12 + movq %rax, %r10 + movq %rdx, %r11 + # A[8] * A[14] + movq 112(%rsi), %rax + mulq 64(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[9] * A[13] + movq 104(%rsi), %rax + mulq 72(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[10] * A[12] + movq 96(%rsi), %rax + mulq 80(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[11] * A[11] + movq 88(%rsi), %rax + mulq %rax + addq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + addq %r10, %r8 + adcq %r11, %r9 + adcq %r12, %rcx + movq %r8, 176(%rdi) + # A[8] * A[15] + movq 120(%rsi), %rax + mulq 64(%rsi) + xorq %r8, %r8 + xorq %r12, %r12 + movq %rax, %r10 + movq %rdx, %r11 + # A[9] * A[14] + movq 112(%rsi), %rax + mulq 72(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[10] * A[13] + movq 104(%rsi), %rax + mulq 80(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[11] * A[12] + movq 96(%rsi), %rax + mulq 88(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + addq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + addq %r10, %r9 + adcq %r11, %rcx + adcq %r12, %r8 + movq %r9, 184(%rdi) + # A[9] * A[15] + movq 120(%rsi), %rax + mulq 72(%rsi) + xorq %r9, %r9 + xorq %r12, %r12 + movq %rax, %r10 + movq %rdx, %r11 + # A[10] * A[14] + movq 112(%rsi), %rax + mulq 80(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[11] * A[13] + movq 104(%rsi), %rax + mulq 88(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[12] * A[12] + movq 96(%rsi), %rax + mulq %rax + addq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + addq %r10, %rcx + adcq %r11, %r8 + adcq %r12, %r9 + movq %rcx, 192(%rdi) + # A[10] * A[15] + movq 120(%rsi), %rax + mulq 80(%rsi) + xorq %rcx, %rcx + xorq %r12, %r12 + movq %rax, %r10 + movq %rdx, %r11 + # A[11] * A[14] + movq 112(%rsi), %rax + mulq 88(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + # A[12] * A[13] + movq 104(%rsi), %rax + mulq 96(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0x00, %r12 + addq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + addq %r10, %r8 + adcq %r11, %r9 + adcq %r12, %rcx + movq %r8, 200(%rdi) + # A[11] * A[15] + movq 120(%rsi), %rax + mulq 88(%rsi) + xorq %r8, %r8 + addq %rax, %r9 + adcq %rdx, %rcx + adcq $0x00, %r8 + addq %rax, %r9 + adcq %rdx, %rcx + adcq $0x00, %r8 + # A[12] * A[14] + movq 112(%rsi), %rax + mulq 96(%rsi) + addq %rax, %r9 + adcq %rdx, %rcx + adcq $0x00, %r8 + addq %rax, %r9 + adcq %rdx, %rcx + adcq $0x00, %r8 + # A[13] * A[13] + movq 104(%rsi), %rax + mulq %rax + addq %rax, %r9 + adcq %rdx, %rcx + adcq $0x00, %r8 + movq %r9, 208(%rdi) + # A[12] * A[15] + movq 120(%rsi), %rax + mulq 96(%rsi) + xorq %r9, %r9 + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0x00, %r9 + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[13] * A[14] + movq 112(%rsi), %rax + mulq 104(%rsi) + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0x00, %r9 + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0x00, %r9 + movq %rcx, 216(%rdi) + # A[13] * A[15] + movq 120(%rsi), %rax + mulq 104(%rsi) + xorq %rcx, %rcx + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %rcx + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %rcx + # A[14] * A[14] + movq 112(%rsi), %rax + mulq %rax + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0x00, %rcx + movq %r8, 224(%rdi) + # A[14] * A[15] + movq 120(%rsi), %rax + mulq 112(%rsi) + xorq %r8, %r8 + addq %rax, %r9 + adcq %rdx, %rcx + adcq $0x00, %r8 + addq %rax, %r9 + adcq %rdx, %rcx + adcq $0x00, %r8 + movq %r9, 232(%rdi) + # A[15] * A[15] + movq 120(%rsi), %rax + mulq %rax + addq %rax, %rcx + adcq %rdx, %r8 + movq %rcx, 240(%rdi) + movq %r8, 248(%rdi) + movq (%rsp), %rax + movq 8(%rsp), %rdx + movq 16(%rsp), %r10 + movq 24(%rsp), %r11 + movq %rax, (%rdi) + movq %rdx, 8(%rdi) + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + movq 32(%rsp), %rax + movq 40(%rsp), %rdx + movq 48(%rsp), %r10 + movq 56(%rsp), %r11 + movq %rax, 32(%rdi) + movq %rdx, 40(%rdi) + movq %r10, 48(%rdi) + movq %r11, 56(%rdi) + movq 64(%rsp), %rax + movq 72(%rsp), %rdx + movq 80(%rsp), %r10 + movq 88(%rsp), %r11 + movq %rax, 64(%rdi) + movq %rdx, 72(%rdi) + movq %r10, 80(%rdi) + movq %r11, 88(%rdi) + movq 96(%rsp), %rax + movq 104(%rsp), %rdx + movq 112(%rsp), %r10 + movq 120(%rsp), %r11 + movq %rax, 96(%rdi) + movq %rdx, 104(%rdi) + movq %r10, 112(%rdi) + movq %r11, 120(%rdi) + addq $0x80, %rsp + popq %r12 + repz retq +#ifndef __APPLE__ +.size sp_1024_sqr_16,.-sp_1024_sqr_16 +#endif /* __APPLE__ */ +#ifdef HAVE_INTEL_AVX2 +/* Multiply a and b into r. (r = a * b) + * + * r Result of multiplication. + * a First number to multiply. + * b Second number to multiply. + */ +#ifndef __APPLE__ +.text +.globl sp_1024_mul_avx2_16 +.type sp_1024_mul_avx2_16,@function +.align 16 +sp_1024_mul_avx2_16: +#else +.section __TEXT,__text +.globl _sp_1024_mul_avx2_16 +.p2align 4 +_sp_1024_mul_avx2_16: +#endif /* __APPLE__ */ + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + movq %rdx, %rbp + subq $0x80, %rsp + cmpq %rdi, %rsi + movq %rsp, %rbx + cmovne %rdi, %rbx + cmpq %rdi, %rbp + cmove %rsp, %rbx + addq $0x80, %rdi + xorq %r14, %r14 + movq (%rsi), %rdx + # A[0] * B[0] + mulx (%rbp), %r8, %r9 + # A[0] * B[1] + mulx 8(%rbp), %rax, %r10 + movq %r8, (%rbx) + adcxq %rax, %r9 + # A[0] * B[2] + mulx 16(%rbp), %rax, %r11 + movq %r9, 8(%rbx) + adcxq %rax, %r10 + # A[0] * B[3] + mulx 24(%rbp), %rax, %r12 + movq %r10, 16(%rbx) + adcxq %rax, %r11 + movq %r11, 24(%rbx) + # A[0] * B[4] + mulx 32(%rbp), %rax, %r8 + adcxq %rax, %r12 + # A[0] * B[5] + mulx 40(%rbp), %rax, %r9 + movq %r12, 32(%rbx) + adcxq %rax, %r8 + # A[0] * B[6] + mulx 48(%rbp), %rax, %r10 + movq %r8, 40(%rbx) + adcxq %rax, %r9 + # A[0] * B[7] + mulx 56(%rbp), %rax, %r11 + movq %r9, 48(%rbx) + adcxq %rax, %r10 + movq %r10, 56(%rbx) + # A[0] * B[8] + mulx 64(%rbp), %rax, %r12 + adcxq %rax, %r11 + # A[0] * B[9] + mulx 72(%rbp), %rax, %r8 + movq %r11, 64(%rbx) + adcxq %rax, %r12 + # A[0] * B[10] + mulx 80(%rbp), %rax, %r9 + movq %r12, 72(%rbx) + adcxq %rax, %r8 + # A[0] * B[11] + mulx 88(%rbp), %rax, %r10 + movq %r8, 80(%rbx) + adcxq %rax, %r9 + movq %r9, 88(%rbx) + # A[0] * B[12] + mulx 96(%rbp), %rax, %r11 + adcxq %rax, %r10 + # A[0] * B[13] + mulx 104(%rbp), %rax, %r12 + movq %r10, 96(%rbx) + adcxq %rax, %r11 + # A[0] * B[14] + mulx 112(%rbp), %rax, %r8 + movq %r11, 104(%rbx) + adcxq %rax, %r12 + # A[0] * B[15] + mulx 120(%rbp), %rax, %r9 + movq %r12, 112(%rbx) + adcxq %rax, %r8 + adcxq %r14, %r9 + movq %r14, %r13 + adcxq %r14, %r13 + movq %r8, 120(%rbx) + movq %r9, (%rdi) + movq 8(%rsi), %rdx + movq 8(%rbx), %r9 + movq 16(%rbx), %r10 + movq 24(%rbx), %r11 + movq 32(%rbx), %r12 + movq 40(%rbx), %r8 + # A[1] * B[0] + mulx (%rbp), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[1] * B[1] + mulx 8(%rbp), %rax, %rcx + movq %r9, 8(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[1] * B[2] + mulx 16(%rbp), %rax, %rcx + movq %r10, 16(%rbx) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[1] * B[3] + mulx 24(%rbp), %rax, %rcx + movq %r11, 24(%rbx) + adcxq %rax, %r12 + adoxq %rcx, %r8 + movq %r12, 32(%rbx) + movq 48(%rbx), %r9 + movq 56(%rbx), %r10 + movq 64(%rbx), %r11 + movq 72(%rbx), %r12 + # A[1] * B[4] + mulx 32(%rbp), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[1] * B[5] + mulx 40(%rbp), %rax, %rcx + movq %r8, 40(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[1] * B[6] + mulx 48(%rbp), %rax, %rcx + movq %r9, 48(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[1] * B[7] + mulx 56(%rbp), %rax, %rcx + movq %r10, 56(%rbx) + adcxq %rax, %r11 + adoxq %rcx, %r12 + movq %r11, 64(%rbx) + movq 80(%rbx), %r8 + movq 88(%rbx), %r9 + movq 96(%rbx), %r10 + movq 104(%rbx), %r11 + # A[1] * B[8] + mulx 64(%rbp), %rax, %rcx + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[1] * B[9] + mulx 72(%rbp), %rax, %rcx + movq %r12, 72(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[1] * B[10] + mulx 80(%rbp), %rax, %rcx + movq %r8, 80(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[1] * B[11] + mulx 88(%rbp), %rax, %rcx + movq %r9, 88(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 96(%rbx) + movq 112(%rbx), %r12 + movq 120(%rbx), %r8 + movq (%rdi), %r9 + # A[1] * B[12] + mulx 96(%rbp), %rax, %rcx + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[1] * B[13] + mulx 104(%rbp), %rax, %rcx + movq %r11, 104(%rbx) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[1] * B[14] + mulx 112(%rbp), %rax, %rcx + movq %r12, 112(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[1] * B[15] + mulx 120(%rbp), %rax, %rcx + movq %r8, 120(%rbx) + movq %r14, %r10 + adcxq %rax, %r9 + adoxq %rcx, %r10 + adcxq %r13, %r10 + movq %r14, %r13 + adoxq %r14, %r13 + adcxq %r14, %r13 + movq %r9, (%rdi) + movq %r10, 8(%rdi) + movq 16(%rsi), %rdx + movq 16(%rbx), %r10 + movq 24(%rbx), %r11 + movq 32(%rbx), %r12 + movq 40(%rbx), %r8 + movq 48(%rbx), %r9 + # A[2] * B[0] + mulx (%rbp), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[2] * B[1] + mulx 8(%rbp), %rax, %rcx + movq %r10, 16(%rbx) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[2] * B[2] + mulx 16(%rbp), %rax, %rcx + movq %r11, 24(%rbx) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[2] * B[3] + mulx 24(%rbp), %rax, %rcx + movq %r12, 32(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 40(%rbx) + movq 56(%rbx), %r10 + movq 64(%rbx), %r11 + movq 72(%rbx), %r12 + movq 80(%rbx), %r8 + # A[2] * B[4] + mulx 32(%rbp), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[2] * B[5] + mulx 40(%rbp), %rax, %rcx + movq %r9, 48(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[2] * B[6] + mulx 48(%rbp), %rax, %rcx + movq %r10, 56(%rbx) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[2] * B[7] + mulx 56(%rbp), %rax, %rcx + movq %r11, 64(%rbx) + adcxq %rax, %r12 + adoxq %rcx, %r8 + movq %r12, 72(%rbx) + movq 88(%rbx), %r9 + movq 96(%rbx), %r10 + movq 104(%rbx), %r11 + movq 112(%rbx), %r12 + # A[2] * B[8] + mulx 64(%rbp), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[2] * B[9] + mulx 72(%rbp), %rax, %rcx + movq %r8, 80(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[2] * B[10] + mulx 80(%rbp), %rax, %rcx + movq %r9, 88(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[2] * B[11] + mulx 88(%rbp), %rax, %rcx + movq %r10, 96(%rbx) + adcxq %rax, %r11 + adoxq %rcx, %r12 + movq %r11, 104(%rbx) + movq 120(%rbx), %r8 + movq (%rdi), %r9 + movq 8(%rdi), %r10 + # A[2] * B[12] + mulx 96(%rbp), %rax, %rcx + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[2] * B[13] + mulx 104(%rbp), %rax, %rcx + movq %r12, 112(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[2] * B[14] + mulx 112(%rbp), %rax, %rcx + movq %r8, 120(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[2] * B[15] + mulx 120(%rbp), %rax, %rcx + movq %r9, (%rdi) + movq %r14, %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + adcxq %r13, %r11 + movq %r14, %r13 + adoxq %r14, %r13 + adcxq %r14, %r13 + movq %r10, 8(%rdi) + movq %r11, 16(%rdi) + movq 24(%rsi), %rdx + movq 24(%rbx), %r11 + movq 32(%rbx), %r12 + movq 40(%rbx), %r8 + movq 48(%rbx), %r9 + movq 56(%rbx), %r10 + # A[3] * B[0] + mulx (%rbp), %rax, %rcx + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[3] * B[1] + mulx 8(%rbp), %rax, %rcx + movq %r11, 24(%rbx) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[3] * B[2] + mulx 16(%rbp), %rax, %rcx + movq %r12, 32(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[3] * B[3] + mulx 24(%rbp), %rax, %rcx + movq %r8, 40(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r9, 48(%rbx) + movq 64(%rbx), %r11 + movq 72(%rbx), %r12 + movq 80(%rbx), %r8 + movq 88(%rbx), %r9 + # A[3] * B[4] + mulx 32(%rbp), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[3] * B[5] + mulx 40(%rbp), %rax, %rcx + movq %r10, 56(%rbx) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[3] * B[6] + mulx 48(%rbp), %rax, %rcx + movq %r11, 64(%rbx) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[3] * B[7] + mulx 56(%rbp), %rax, %rcx + movq %r12, 72(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 80(%rbx) + movq 96(%rbx), %r10 + movq 104(%rbx), %r11 + movq 112(%rbx), %r12 + movq 120(%rbx), %r8 + # A[3] * B[8] + mulx 64(%rbp), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[3] * B[9] + mulx 72(%rbp), %rax, %rcx + movq %r9, 88(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[3] * B[10] + mulx 80(%rbp), %rax, %rcx + movq %r10, 96(%rbx) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[3] * B[11] + mulx 88(%rbp), %rax, %rcx + movq %r11, 104(%rbx) + adcxq %rax, %r12 + adoxq %rcx, %r8 + movq %r12, 112(%rbx) + movq (%rdi), %r9 + movq 8(%rdi), %r10 + movq 16(%rdi), %r11 + # A[3] * B[12] + mulx 96(%rbp), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[3] * B[13] + mulx 104(%rbp), %rax, %rcx + movq %r8, 120(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[3] * B[14] + mulx 112(%rbp), %rax, %rcx + movq %r9, (%rdi) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[3] * B[15] + mulx 120(%rbp), %rax, %rcx + movq %r10, 8(%rdi) + movq %r14, %r12 + adcxq %rax, %r11 + adoxq %rcx, %r12 + adcxq %r13, %r12 + movq %r14, %r13 + adoxq %r14, %r13 + adcxq %r14, %r13 + movq %r11, 16(%rdi) + movq %r12, 24(%rdi) + movq 32(%rsi), %rdx + movq 32(%rbx), %r12 + movq 40(%rbx), %r8 + movq 48(%rbx), %r9 + movq 56(%rbx), %r10 + movq 64(%rbx), %r11 + # A[4] * B[0] + mulx (%rbp), %rax, %rcx + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[4] * B[1] + mulx 8(%rbp), %rax, %rcx + movq %r12, 32(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[4] * B[2] + mulx 16(%rbp), %rax, %rcx + movq %r8, 40(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[4] * B[3] + mulx 24(%rbp), %rax, %rcx + movq %r9, 48(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 56(%rbx) + movq 72(%rbx), %r12 + movq 80(%rbx), %r8 + movq 88(%rbx), %r9 + movq 96(%rbx), %r10 + # A[4] * B[4] + mulx 32(%rbp), %rax, %rcx + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[4] * B[5] + mulx 40(%rbp), %rax, %rcx + movq %r11, 64(%rbx) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[4] * B[6] + mulx 48(%rbp), %rax, %rcx + movq %r12, 72(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[4] * B[7] + mulx 56(%rbp), %rax, %rcx + movq %r8, 80(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r9, 88(%rbx) + movq 104(%rbx), %r11 + movq 112(%rbx), %r12 + movq 120(%rbx), %r8 + movq (%rdi), %r9 + # A[4] * B[8] + mulx 64(%rbp), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[4] * B[9] + mulx 72(%rbp), %rax, %rcx + movq %r10, 96(%rbx) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[4] * B[10] + mulx 80(%rbp), %rax, %rcx + movq %r11, 104(%rbx) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[4] * B[11] + mulx 88(%rbp), %rax, %rcx + movq %r12, 112(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 120(%rbx) + movq 8(%rdi), %r10 + movq 16(%rdi), %r11 + movq 24(%rdi), %r12 + # A[4] * B[12] + mulx 96(%rbp), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[4] * B[13] + mulx 104(%rbp), %rax, %rcx + movq %r9, (%rdi) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[4] * B[14] + mulx 112(%rbp), %rax, %rcx + movq %r10, 8(%rdi) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[4] * B[15] + mulx 120(%rbp), %rax, %rcx + movq %r11, 16(%rdi) + movq %r14, %r8 + adcxq %rax, %r12 + adoxq %rcx, %r8 + adcxq %r13, %r8 + movq %r14, %r13 + adoxq %r14, %r13 + adcxq %r14, %r13 + movq %r12, 24(%rdi) + movq %r8, 32(%rdi) + movq 40(%rsi), %rdx + movq 40(%rbx), %r8 + movq 48(%rbx), %r9 + movq 56(%rbx), %r10 + movq 64(%rbx), %r11 + movq 72(%rbx), %r12 + # A[5] * B[0] + mulx (%rbp), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[5] * B[1] + mulx 8(%rbp), %rax, %rcx + movq %r8, 40(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[5] * B[2] + mulx 16(%rbp), %rax, %rcx + movq %r9, 48(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[5] * B[3] + mulx 24(%rbp), %rax, %rcx + movq %r10, 56(%rbx) + adcxq %rax, %r11 + adoxq %rcx, %r12 + movq %r11, 64(%rbx) + movq 80(%rbx), %r8 + movq 88(%rbx), %r9 + movq 96(%rbx), %r10 + movq 104(%rbx), %r11 + # A[5] * B[4] + mulx 32(%rbp), %rax, %rcx + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[5] * B[5] + mulx 40(%rbp), %rax, %rcx + movq %r12, 72(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[5] * B[6] + mulx 48(%rbp), %rax, %rcx + movq %r8, 80(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[5] * B[7] + mulx 56(%rbp), %rax, %rcx + movq %r9, 88(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 96(%rbx) + movq 112(%rbx), %r12 + movq 120(%rbx), %r8 + movq (%rdi), %r9 + movq 8(%rdi), %r10 + # A[5] * B[8] + mulx 64(%rbp), %rax, %rcx + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[5] * B[9] + mulx 72(%rbp), %rax, %rcx + movq %r11, 104(%rbx) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[5] * B[10] + mulx 80(%rbp), %rax, %rcx + movq %r12, 112(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[5] * B[11] + mulx 88(%rbp), %rax, %rcx + movq %r8, 120(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r9, (%rdi) + movq 16(%rdi), %r11 + movq 24(%rdi), %r12 + movq 32(%rdi), %r8 + # A[5] * B[12] + mulx 96(%rbp), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[5] * B[13] + mulx 104(%rbp), %rax, %rcx + movq %r10, 8(%rdi) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[5] * B[14] + mulx 112(%rbp), %rax, %rcx + movq %r11, 16(%rdi) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[5] * B[15] + mulx 120(%rbp), %rax, %rcx + movq %r12, 24(%rdi) + movq %r14, %r9 + adcxq %rax, %r8 + adoxq %rcx, %r9 + adcxq %r13, %r9 + movq %r14, %r13 + adoxq %r14, %r13 + adcxq %r14, %r13 + movq %r8, 32(%rdi) + movq %r9, 40(%rdi) + movq 48(%rsi), %rdx + movq 48(%rbx), %r9 + movq 56(%rbx), %r10 + movq 64(%rbx), %r11 + movq 72(%rbx), %r12 + movq 80(%rbx), %r8 + # A[6] * B[0] + mulx (%rbp), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[6] * B[1] + mulx 8(%rbp), %rax, %rcx + movq %r9, 48(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[6] * B[2] + mulx 16(%rbp), %rax, %rcx + movq %r10, 56(%rbx) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[6] * B[3] + mulx 24(%rbp), %rax, %rcx + movq %r11, 64(%rbx) + adcxq %rax, %r12 + adoxq %rcx, %r8 + movq %r12, 72(%rbx) + movq 88(%rbx), %r9 + movq 96(%rbx), %r10 + movq 104(%rbx), %r11 + movq 112(%rbx), %r12 + # A[6] * B[4] + mulx 32(%rbp), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[6] * B[5] + mulx 40(%rbp), %rax, %rcx + movq %r8, 80(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[6] * B[6] + mulx 48(%rbp), %rax, %rcx + movq %r9, 88(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[6] * B[7] + mulx 56(%rbp), %rax, %rcx + movq %r10, 96(%rbx) + adcxq %rax, %r11 + adoxq %rcx, %r12 + movq %r11, 104(%rbx) + movq 120(%rbx), %r8 + movq (%rdi), %r9 + movq 8(%rdi), %r10 + movq 16(%rdi), %r11 + # A[6] * B[8] + mulx 64(%rbp), %rax, %rcx + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[6] * B[9] + mulx 72(%rbp), %rax, %rcx + movq %r12, 112(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[6] * B[10] + mulx 80(%rbp), %rax, %rcx + movq %r8, 120(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[6] * B[11] + mulx 88(%rbp), %rax, %rcx + movq %r9, (%rdi) + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 8(%rdi) + movq 24(%rdi), %r12 + movq 32(%rdi), %r8 + movq 40(%rdi), %r9 + # A[6] * B[12] + mulx 96(%rbp), %rax, %rcx + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[6] * B[13] + mulx 104(%rbp), %rax, %rcx + movq %r11, 16(%rdi) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[6] * B[14] + mulx 112(%rbp), %rax, %rcx + movq %r12, 24(%rdi) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[6] * B[15] + mulx 120(%rbp), %rax, %rcx + movq %r8, 32(%rdi) + movq %r14, %r10 + adcxq %rax, %r9 + adoxq %rcx, %r10 + adcxq %r13, %r10 + movq %r14, %r13 + adoxq %r14, %r13 + adcxq %r14, %r13 + movq %r9, 40(%rdi) + movq %r10, 48(%rdi) + movq 56(%rsi), %rdx + movq 56(%rbx), %r10 + movq 64(%rbx), %r11 + movq 72(%rbx), %r12 + movq 80(%rbx), %r8 + movq 88(%rbx), %r9 + # A[7] * B[0] + mulx (%rbp), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[7] * B[1] + mulx 8(%rbp), %rax, %rcx + movq %r10, 56(%rbx) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[7] * B[2] + mulx 16(%rbp), %rax, %rcx + movq %r11, 64(%rbx) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[7] * B[3] + mulx 24(%rbp), %rax, %rcx + movq %r12, 72(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 80(%rbx) + movq 96(%rbx), %r10 + movq 104(%rbx), %r11 + movq 112(%rbx), %r12 + movq 120(%rbx), %r8 + # A[7] * B[4] + mulx 32(%rbp), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[7] * B[5] + mulx 40(%rbp), %rax, %rcx + movq %r9, 88(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[7] * B[6] + mulx 48(%rbp), %rax, %rcx + movq %r10, 96(%rbx) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[7] * B[7] + mulx 56(%rbp), %rax, %rcx + movq %r11, 104(%rbx) + adcxq %rax, %r12 + adoxq %rcx, %r8 + movq %r12, 112(%rbx) + movq (%rdi), %r9 + movq 8(%rdi), %r10 + movq 16(%rdi), %r11 + movq 24(%rdi), %r12 + # A[7] * B[8] + mulx 64(%rbp), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[7] * B[9] + mulx 72(%rbp), %rax, %rcx + movq %r8, 120(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[7] * B[10] + mulx 80(%rbp), %rax, %rcx + movq %r9, (%rdi) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[7] * B[11] + mulx 88(%rbp), %rax, %rcx + movq %r10, 8(%rdi) + adcxq %rax, %r11 + adoxq %rcx, %r12 + movq %r11, 16(%rdi) + movq 32(%rdi), %r8 + movq 40(%rdi), %r9 + movq 48(%rdi), %r10 + # A[7] * B[12] + mulx 96(%rbp), %rax, %rcx + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[7] * B[13] + mulx 104(%rbp), %rax, %rcx + movq %r12, 24(%rdi) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[7] * B[14] + mulx 112(%rbp), %rax, %rcx + movq %r8, 32(%rdi) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[7] * B[15] + mulx 120(%rbp), %rax, %rcx + movq %r9, 40(%rdi) + movq %r14, %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + adcxq %r13, %r11 + movq %r14, %r13 + adoxq %r14, %r13 + adcxq %r14, %r13 + movq %r10, 48(%rdi) + movq %r11, 56(%rdi) + movq 64(%rsi), %rdx + movq 64(%rbx), %r11 + movq 72(%rbx), %r12 + movq 80(%rbx), %r8 + movq 88(%rbx), %r9 + movq 96(%rbx), %r10 + # A[8] * B[0] + mulx (%rbp), %rax, %rcx + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[8] * B[1] + mulx 8(%rbp), %rax, %rcx + movq %r11, 64(%rbx) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[8] * B[2] + mulx 16(%rbp), %rax, %rcx + movq %r12, 72(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[8] * B[3] + mulx 24(%rbp), %rax, %rcx + movq %r8, 80(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r9, 88(%rbx) + movq 104(%rbx), %r11 + movq 112(%rbx), %r12 + movq 120(%rbx), %r8 + movq (%rdi), %r9 + # A[8] * B[4] + mulx 32(%rbp), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[8] * B[5] + mulx 40(%rbp), %rax, %rcx + movq %r10, 96(%rbx) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[8] * B[6] + mulx 48(%rbp), %rax, %rcx + movq %r11, 104(%rbx) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[8] * B[7] + mulx 56(%rbp), %rax, %rcx + movq %r12, 112(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 120(%rbx) + movq 8(%rdi), %r10 + movq 16(%rdi), %r11 + movq 24(%rdi), %r12 + movq 32(%rdi), %r8 + # A[8] * B[8] + mulx 64(%rbp), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[8] * B[9] + mulx 72(%rbp), %rax, %rcx + movq %r9, (%rdi) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[8] * B[10] + mulx 80(%rbp), %rax, %rcx + movq %r10, 8(%rdi) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[8] * B[11] + mulx 88(%rbp), %rax, %rcx + movq %r11, 16(%rdi) + adcxq %rax, %r12 + adoxq %rcx, %r8 + movq %r12, 24(%rdi) + movq 40(%rdi), %r9 + movq 48(%rdi), %r10 + movq 56(%rdi), %r11 + # A[8] * B[12] + mulx 96(%rbp), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[8] * B[13] + mulx 104(%rbp), %rax, %rcx + movq %r8, 32(%rdi) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[8] * B[14] + mulx 112(%rbp), %rax, %rcx + movq %r9, 40(%rdi) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[8] * B[15] + mulx 120(%rbp), %rax, %rcx + movq %r10, 48(%rdi) + movq %r14, %r12 + adcxq %rax, %r11 + adoxq %rcx, %r12 + adcxq %r13, %r12 + movq %r14, %r13 + adoxq %r14, %r13 + adcxq %r14, %r13 + movq %r11, 56(%rdi) + movq %r12, 64(%rdi) + movq 72(%rsi), %rdx + movq 72(%rbx), %r12 + movq 80(%rbx), %r8 + movq 88(%rbx), %r9 + movq 96(%rbx), %r10 + movq 104(%rbx), %r11 + # A[9] * B[0] + mulx (%rbp), %rax, %rcx + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[9] * B[1] + mulx 8(%rbp), %rax, %rcx + movq %r12, 72(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[9] * B[2] + mulx 16(%rbp), %rax, %rcx + movq %r8, 80(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[9] * B[3] + mulx 24(%rbp), %rax, %rcx + movq %r9, 88(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 96(%rbx) + movq 112(%rbx), %r12 + movq 120(%rbx), %r8 + movq (%rdi), %r9 + movq 8(%rdi), %r10 + # A[9] * B[4] + mulx 32(%rbp), %rax, %rcx + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[9] * B[5] + mulx 40(%rbp), %rax, %rcx + movq %r11, 104(%rbx) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[9] * B[6] + mulx 48(%rbp), %rax, %rcx + movq %r12, 112(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[9] * B[7] + mulx 56(%rbp), %rax, %rcx + movq %r8, 120(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r9, (%rdi) + movq 16(%rdi), %r11 + movq 24(%rdi), %r12 + movq 32(%rdi), %r8 + movq 40(%rdi), %r9 + # A[9] * B[8] + mulx 64(%rbp), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[9] * B[9] + mulx 72(%rbp), %rax, %rcx + movq %r10, 8(%rdi) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[9] * B[10] + mulx 80(%rbp), %rax, %rcx + movq %r11, 16(%rdi) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[9] * B[11] + mulx 88(%rbp), %rax, %rcx + movq %r12, 24(%rdi) + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 32(%rdi) + movq 48(%rdi), %r10 + movq 56(%rdi), %r11 + movq 64(%rdi), %r12 + # A[9] * B[12] + mulx 96(%rbp), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[9] * B[13] + mulx 104(%rbp), %rax, %rcx + movq %r9, 40(%rdi) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[9] * B[14] + mulx 112(%rbp), %rax, %rcx + movq %r10, 48(%rdi) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[9] * B[15] + mulx 120(%rbp), %rax, %rcx + movq %r11, 56(%rdi) + movq %r14, %r8 + adcxq %rax, %r12 + adoxq %rcx, %r8 + adcxq %r13, %r8 + movq %r14, %r13 + adoxq %r14, %r13 + adcxq %r14, %r13 + movq %r12, 64(%rdi) + movq %r8, 72(%rdi) + movq 80(%rsi), %rdx + movq 80(%rbx), %r8 + movq 88(%rbx), %r9 + movq 96(%rbx), %r10 + movq 104(%rbx), %r11 + movq 112(%rbx), %r12 + # A[10] * B[0] + mulx (%rbp), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[10] * B[1] + mulx 8(%rbp), %rax, %rcx + movq %r8, 80(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[10] * B[2] + mulx 16(%rbp), %rax, %rcx + movq %r9, 88(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[10] * B[3] + mulx 24(%rbp), %rax, %rcx + movq %r10, 96(%rbx) + adcxq %rax, %r11 + adoxq %rcx, %r12 + movq %r11, 104(%rbx) + movq 120(%rbx), %r8 + movq (%rdi), %r9 + movq 8(%rdi), %r10 + movq 16(%rdi), %r11 + # A[10] * B[4] + mulx 32(%rbp), %rax, %rcx + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[10] * B[5] + mulx 40(%rbp), %rax, %rcx + movq %r12, 112(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[10] * B[6] + mulx 48(%rbp), %rax, %rcx + movq %r8, 120(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[10] * B[7] + mulx 56(%rbp), %rax, %rcx + movq %r9, (%rdi) + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 8(%rdi) + movq 24(%rdi), %r12 + movq 32(%rdi), %r8 + movq 40(%rdi), %r9 + movq 48(%rdi), %r10 + # A[10] * B[8] + mulx 64(%rbp), %rax, %rcx + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[10] * B[9] + mulx 72(%rbp), %rax, %rcx + movq %r11, 16(%rdi) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[10] * B[10] + mulx 80(%rbp), %rax, %rcx + movq %r12, 24(%rdi) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[10] * B[11] + mulx 88(%rbp), %rax, %rcx + movq %r8, 32(%rdi) + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r9, 40(%rdi) + movq 56(%rdi), %r11 + movq 64(%rdi), %r12 + movq 72(%rdi), %r8 + # A[10] * B[12] + mulx 96(%rbp), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[10] * B[13] + mulx 104(%rbp), %rax, %rcx + movq %r10, 48(%rdi) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[10] * B[14] + mulx 112(%rbp), %rax, %rcx + movq %r11, 56(%rdi) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[10] * B[15] + mulx 120(%rbp), %rax, %rcx + movq %r12, 64(%rdi) + movq %r14, %r9 + adcxq %rax, %r8 + adoxq %rcx, %r9 + adcxq %r13, %r9 + movq %r14, %r13 + adoxq %r14, %r13 + adcxq %r14, %r13 + movq %r8, 72(%rdi) + movq %r9, 80(%rdi) + movq 88(%rsi), %rdx + movq 88(%rbx), %r9 + movq 96(%rbx), %r10 + movq 104(%rbx), %r11 + movq 112(%rbx), %r12 + movq 120(%rbx), %r8 + # A[11] * B[0] + mulx (%rbp), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[11] * B[1] + mulx 8(%rbp), %rax, %rcx + movq %r9, 88(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[11] * B[2] + mulx 16(%rbp), %rax, %rcx + movq %r10, 96(%rbx) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[11] * B[3] + mulx 24(%rbp), %rax, %rcx + movq %r11, 104(%rbx) + adcxq %rax, %r12 + adoxq %rcx, %r8 + movq %r12, 112(%rbx) + movq (%rdi), %r9 + movq 8(%rdi), %r10 + movq 16(%rdi), %r11 + movq 24(%rdi), %r12 + # A[11] * B[4] + mulx 32(%rbp), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[11] * B[5] + mulx 40(%rbp), %rax, %rcx + movq %r8, 120(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[11] * B[6] + mulx 48(%rbp), %rax, %rcx + movq %r9, (%rdi) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[11] * B[7] + mulx 56(%rbp), %rax, %rcx + movq %r10, 8(%rdi) + adcxq %rax, %r11 + adoxq %rcx, %r12 + movq %r11, 16(%rdi) + movq 32(%rdi), %r8 + movq 40(%rdi), %r9 + movq 48(%rdi), %r10 + movq 56(%rdi), %r11 + # A[11] * B[8] + mulx 64(%rbp), %rax, %rcx + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[11] * B[9] + mulx 72(%rbp), %rax, %rcx + movq %r12, 24(%rdi) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[11] * B[10] + mulx 80(%rbp), %rax, %rcx + movq %r8, 32(%rdi) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[11] * B[11] + mulx 88(%rbp), %rax, %rcx + movq %r9, 40(%rdi) + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 48(%rdi) + movq 64(%rdi), %r12 + movq 72(%rdi), %r8 + movq 80(%rdi), %r9 + # A[11] * B[12] + mulx 96(%rbp), %rax, %rcx + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[11] * B[13] + mulx 104(%rbp), %rax, %rcx + movq %r11, 56(%rdi) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[11] * B[14] + mulx 112(%rbp), %rax, %rcx + movq %r12, 64(%rdi) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[11] * B[15] + mulx 120(%rbp), %rax, %rcx + movq %r8, 72(%rdi) + movq %r14, %r10 + adcxq %rax, %r9 + adoxq %rcx, %r10 + adcxq %r13, %r10 + movq %r14, %r13 + adoxq %r14, %r13 + adcxq %r14, %r13 + movq %r9, 80(%rdi) + movq %r10, 88(%rdi) + movq 96(%rsi), %rdx + movq 96(%rbx), %r10 + movq 104(%rbx), %r11 + movq 112(%rbx), %r12 + movq 120(%rbx), %r8 + movq (%rdi), %r9 + # A[12] * B[0] + mulx (%rbp), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[12] * B[1] + mulx 8(%rbp), %rax, %rcx + movq %r10, 96(%rbx) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[12] * B[2] + mulx 16(%rbp), %rax, %rcx + movq %r11, 104(%rbx) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[12] * B[3] + mulx 24(%rbp), %rax, %rcx + movq %r12, 112(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 120(%rbx) + movq 8(%rdi), %r10 + movq 16(%rdi), %r11 + movq 24(%rdi), %r12 + movq 32(%rdi), %r8 + # A[12] * B[4] + mulx 32(%rbp), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[12] * B[5] + mulx 40(%rbp), %rax, %rcx + movq %r9, (%rdi) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[12] * B[6] + mulx 48(%rbp), %rax, %rcx + movq %r10, 8(%rdi) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[12] * B[7] + mulx 56(%rbp), %rax, %rcx + movq %r11, 16(%rdi) + adcxq %rax, %r12 + adoxq %rcx, %r8 + movq %r12, 24(%rdi) + movq 40(%rdi), %r9 + movq 48(%rdi), %r10 + movq 56(%rdi), %r11 + movq 64(%rdi), %r12 + # A[12] * B[8] + mulx 64(%rbp), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[12] * B[9] + mulx 72(%rbp), %rax, %rcx + movq %r8, 32(%rdi) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[12] * B[10] + mulx 80(%rbp), %rax, %rcx + movq %r9, 40(%rdi) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[12] * B[11] + mulx 88(%rbp), %rax, %rcx + movq %r10, 48(%rdi) + adcxq %rax, %r11 + adoxq %rcx, %r12 + movq %r11, 56(%rdi) + movq 72(%rdi), %r8 + movq 80(%rdi), %r9 + movq 88(%rdi), %r10 + # A[12] * B[12] + mulx 96(%rbp), %rax, %rcx + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[12] * B[13] + mulx 104(%rbp), %rax, %rcx + movq %r12, 64(%rdi) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[12] * B[14] + mulx 112(%rbp), %rax, %rcx + movq %r8, 72(%rdi) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[12] * B[15] + mulx 120(%rbp), %rax, %rcx + movq %r9, 80(%rdi) + movq %r14, %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + adcxq %r13, %r11 + movq %r14, %r13 + adoxq %r14, %r13 + adcxq %r14, %r13 + movq %r10, 88(%rdi) + movq %r11, 96(%rdi) + movq 104(%rsi), %rdx + movq 104(%rbx), %r11 + movq 112(%rbx), %r12 + movq 120(%rbx), %r8 + movq (%rdi), %r9 + movq 8(%rdi), %r10 + # A[13] * B[0] + mulx (%rbp), %rax, %rcx + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[13] * B[1] + mulx 8(%rbp), %rax, %rcx + movq %r11, 104(%rbx) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[13] * B[2] + mulx 16(%rbp), %rax, %rcx + movq %r12, 112(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[13] * B[3] + mulx 24(%rbp), %rax, %rcx + movq %r8, 120(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r9, (%rdi) + movq 16(%rdi), %r11 + movq 24(%rdi), %r12 + movq 32(%rdi), %r8 + movq 40(%rdi), %r9 + # A[13] * B[4] + mulx 32(%rbp), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[13] * B[5] + mulx 40(%rbp), %rax, %rcx + movq %r10, 8(%rdi) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[13] * B[6] + mulx 48(%rbp), %rax, %rcx + movq %r11, 16(%rdi) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[13] * B[7] + mulx 56(%rbp), %rax, %rcx + movq %r12, 24(%rdi) + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 32(%rdi) + movq 48(%rdi), %r10 + movq 56(%rdi), %r11 + movq 64(%rdi), %r12 + movq 72(%rdi), %r8 + # A[13] * B[8] + mulx 64(%rbp), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[13] * B[9] + mulx 72(%rbp), %rax, %rcx + movq %r9, 40(%rdi) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[13] * B[10] + mulx 80(%rbp), %rax, %rcx + movq %r10, 48(%rdi) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[13] * B[11] + mulx 88(%rbp), %rax, %rcx + movq %r11, 56(%rdi) + adcxq %rax, %r12 + adoxq %rcx, %r8 + movq %r12, 64(%rdi) + movq 80(%rdi), %r9 + movq 88(%rdi), %r10 + movq 96(%rdi), %r11 + # A[13] * B[12] + mulx 96(%rbp), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[13] * B[13] + mulx 104(%rbp), %rax, %rcx + movq %r8, 72(%rdi) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[13] * B[14] + mulx 112(%rbp), %rax, %rcx + movq %r9, 80(%rdi) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[13] * B[15] + mulx 120(%rbp), %rax, %rcx + movq %r10, 88(%rdi) + movq %r14, %r12 + adcxq %rax, %r11 + adoxq %rcx, %r12 + adcxq %r13, %r12 + movq %r14, %r13 + adoxq %r14, %r13 + adcxq %r14, %r13 + movq %r11, 96(%rdi) + movq %r12, 104(%rdi) + movq 112(%rsi), %rdx + movq 112(%rbx), %r12 + movq 120(%rbx), %r8 + movq (%rdi), %r9 + movq 8(%rdi), %r10 + movq 16(%rdi), %r11 + # A[14] * B[0] + mulx (%rbp), %rax, %rcx + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[14] * B[1] + mulx 8(%rbp), %rax, %rcx + movq %r12, 112(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[14] * B[2] + mulx 16(%rbp), %rax, %rcx + movq %r8, 120(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[14] * B[3] + mulx 24(%rbp), %rax, %rcx + movq %r9, (%rdi) + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 8(%rdi) + movq 24(%rdi), %r12 + movq 32(%rdi), %r8 + movq 40(%rdi), %r9 + movq 48(%rdi), %r10 + # A[14] * B[4] + mulx 32(%rbp), %rax, %rcx + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[14] * B[5] + mulx 40(%rbp), %rax, %rcx + movq %r11, 16(%rdi) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[14] * B[6] + mulx 48(%rbp), %rax, %rcx + movq %r12, 24(%rdi) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[14] * B[7] + mulx 56(%rbp), %rax, %rcx + movq %r8, 32(%rdi) + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r9, 40(%rdi) + movq 56(%rdi), %r11 + movq 64(%rdi), %r12 + movq 72(%rdi), %r8 + movq 80(%rdi), %r9 + # A[14] * B[8] + mulx 64(%rbp), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[14] * B[9] + mulx 72(%rbp), %rax, %rcx + movq %r10, 48(%rdi) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[14] * B[10] + mulx 80(%rbp), %rax, %rcx + movq %r11, 56(%rdi) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[14] * B[11] + mulx 88(%rbp), %rax, %rcx + movq %r12, 64(%rdi) + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 72(%rdi) + movq 88(%rdi), %r10 + movq 96(%rdi), %r11 + movq 104(%rdi), %r12 + # A[14] * B[12] + mulx 96(%rbp), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[14] * B[13] + mulx 104(%rbp), %rax, %rcx + movq %r9, 80(%rdi) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[14] * B[14] + mulx 112(%rbp), %rax, %rcx + movq %r10, 88(%rdi) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[14] * B[15] + mulx 120(%rbp), %rax, %rcx + movq %r11, 96(%rdi) + movq %r14, %r8 + adcxq %rax, %r12 + adoxq %rcx, %r8 + adcxq %r13, %r8 + movq %r14, %r13 + adoxq %r14, %r13 + adcxq %r14, %r13 + movq %r12, 104(%rdi) + movq %r8, 112(%rdi) + movq 120(%rsi), %rdx + movq 120(%rbx), %r8 + movq (%rdi), %r9 + movq 8(%rdi), %r10 + movq 16(%rdi), %r11 + movq 24(%rdi), %r12 + # A[15] * B[0] + mulx (%rbp), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[15] * B[1] + mulx 8(%rbp), %rax, %rcx + movq %r8, 120(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[15] * B[2] + mulx 16(%rbp), %rax, %rcx + movq %r9, (%rdi) + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[15] * B[3] + mulx 24(%rbp), %rax, %rcx + movq %r10, 8(%rdi) + adcxq %rax, %r11 + adoxq %rcx, %r12 + movq %r11, 16(%rdi) + movq 32(%rdi), %r8 + movq 40(%rdi), %r9 + movq 48(%rdi), %r10 + movq 56(%rdi), %r11 + # A[15] * B[4] + mulx 32(%rbp), %rax, %rcx + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[15] * B[5] + mulx 40(%rbp), %rax, %rcx + movq %r12, 24(%rdi) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[15] * B[6] + mulx 48(%rbp), %rax, %rcx + movq %r8, 32(%rdi) + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[15] * B[7] + mulx 56(%rbp), %rax, %rcx + movq %r9, 40(%rdi) + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 48(%rdi) + movq 64(%rdi), %r12 + movq 72(%rdi), %r8 + movq 80(%rdi), %r9 + movq 88(%rdi), %r10 + # A[15] * B[8] + mulx 64(%rbp), %rax, %rcx + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[15] * B[9] + mulx 72(%rbp), %rax, %rcx + movq %r11, 56(%rdi) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[15] * B[10] + mulx 80(%rbp), %rax, %rcx + movq %r12, 64(%rdi) + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[15] * B[11] + mulx 88(%rbp), %rax, %rcx + movq %r8, 72(%rdi) + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r9, 80(%rdi) + movq 96(%rdi), %r11 + movq 104(%rdi), %r12 + movq 112(%rdi), %r8 + # A[15] * B[12] + mulx 96(%rbp), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[15] * B[13] + mulx 104(%rbp), %rax, %rcx + movq %r10, 88(%rdi) + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[15] * B[14] + mulx 112(%rbp), %rax, %rcx + movq %r11, 96(%rdi) + adcxq %rax, %r12 + adoxq %rcx, %r8 + # A[15] * B[15] + mulx 120(%rbp), %rax, %rcx + movq %r12, 104(%rdi) + movq %r14, %r9 + adcxq %rax, %r8 + adoxq %rcx, %r9 + adcxq %r13, %r9 + movq %r8, 112(%rdi) + movq %r9, 120(%rdi) + subq $0x80, %rdi + cmpq %rdi, %rsi + je L_start_1024_mul_avx2_16 + cmpq %rdi, %rbp + jne L_end_1024_mul_avx2_16 +L_start_1024_mul_avx2_16: + vmovdqu (%rbx), %xmm0 + vmovups %xmm0, (%rdi) + vmovdqu 16(%rbx), %xmm0 + vmovups %xmm0, 16(%rdi) + vmovdqu 32(%rbx), %xmm0 + vmovups %xmm0, 32(%rdi) + vmovdqu 48(%rbx), %xmm0 + vmovups %xmm0, 48(%rdi) + vmovdqu 64(%rbx), %xmm0 + vmovups %xmm0, 64(%rdi) + vmovdqu 80(%rbx), %xmm0 + vmovups %xmm0, 80(%rdi) + vmovdqu 96(%rbx), %xmm0 + vmovups %xmm0, 96(%rdi) + vmovdqu 112(%rbx), %xmm0 + vmovups %xmm0, 112(%rdi) +L_end_1024_mul_avx2_16: + addq $0x80, %rsp + popq %r14 + popq %r13 + popq %r12 + popq %rbp + popq %rbx + repz retq +#ifndef __APPLE__ +.size sp_1024_mul_avx2_16,.-sp_1024_mul_avx2_16 +#endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +#ifdef HAVE_INTEL_AVX2 +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +#ifndef __APPLE__ +.text +.globl sp_1024_sqr_avx2_16 +.type sp_1024_sqr_avx2_16,@function +.align 16 +sp_1024_sqr_avx2_16: +#else +.section __TEXT,__text +.globl _sp_1024_sqr_avx2_16 +.p2align 4 +_sp_1024_sqr_avx2_16: +#endif /* __APPLE__ */ + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + pushq %rbx + subq $0x80, %rsp + cmpq %rdi, %rsi + movq %rsp, %rbp + cmovne %rdi, %rbp + addq $0x80, %rdi + xorq %r11, %r11 + # Diagonal 1 + xorq %r10, %r10 + # A[1] x A[0] + movq (%rsi), %rdx + mulxq 8(%rsi), %r8, %r9 + # A[2] x A[0] + mulxq 16(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r8, 8(%rbp) + movq %r9, 16(%rbp) + movq %r11, %r8 + movq %r11, %r9 + # A[3] x A[0] + mulxq 24(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + # A[4] x A[0] + mulxq 32(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r10, 24(%rbp) + movq %r8, 32(%rbp) + movq %r11, %r10 + movq %r11, %r8 + # A[5] x A[0] + mulxq 40(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[6] x A[0] + mulxq 48(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r9, 40(%rbp) + movq %r10, 48(%rbp) + movq %r11, %r9 + movq %r11, %r10 + # A[7] x A[0] + mulxq 56(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[8] x A[0] + mulxq 64(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r8, 56(%rbp) + movq %r9, 64(%rbp) + movq %r11, %r8 + movq %r11, %r9 + # A[9] x A[0] + mulxq 72(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + # A[10] x A[0] + mulxq 80(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r10, 72(%rbp) + movq %r8, 80(%rbp) + movq %r11, %r10 + movq %r11, %r8 + # A[11] x A[0] + mulxq 88(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[12] x A[0] + mulxq 96(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r9, 88(%rbp) + movq %r10, %r13 + movq %r11, %r9 + movq %r11, %r10 + # A[13] x A[0] + mulxq 104(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[14] x A[0] + mulxq 112(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r8, %r14 + movq %r9, %r15 + movq %r11, %r8 + # A[15] x A[0] + mulxq 120(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r10, %rbx + # Carry + adcxq %r11, %r8 + movq %r11, %r12 + adcxq %r11, %r12 + adoxq %r11, %r12 + movq %r8, (%rdi) + # Diagonal 2 + movq 24(%rbp), %r8 + movq 32(%rbp), %r9 + movq 40(%rbp), %r10 + # A[2] x A[1] + movq 8(%rsi), %rdx + mulxq 16(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[3] x A[1] + mulxq 24(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r8, 24(%rbp) + movq %r9, 32(%rbp) + movq 48(%rbp), %r8 + movq 56(%rbp), %r9 + # A[4] x A[1] + mulxq 32(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + # A[5] x A[1] + mulxq 40(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r10, 40(%rbp) + movq %r8, 48(%rbp) + movq 64(%rbp), %r10 + movq 72(%rbp), %r8 + # A[6] x A[1] + mulxq 48(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[7] x A[1] + mulxq 56(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r9, 56(%rbp) + movq %r10, 64(%rbp) + movq 80(%rbp), %r9 + movq 88(%rbp), %r10 + # A[8] x A[1] + mulxq 64(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[9] x A[1] + mulxq 72(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r8, 72(%rbp) + movq %r9, 80(%rbp) + # No load %r13 - %r8 + # No load %r14 - %r9 + # A[10] x A[1] + mulxq 80(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r13 + # A[11] x A[1] + mulxq 88(%rsi), %rax, %rcx + adcxq %rax, %r13 + adoxq %rcx, %r14 + movq %r10, 88(%rbp) + # No store %r13 + # No load %r15 - %r10 + # No load %rbx - %r8 + # A[12] x A[1] + mulxq 96(%rsi), %rax, %rcx + adcxq %rax, %r14 + adoxq %rcx, %r15 + # A[13] x A[1] + mulxq 104(%rsi), %rax, %rcx + adcxq %rax, %r15 + adoxq %rcx, %rbx + # No store %r14 + # No store %r15 + movq (%rdi), %r9 + movq %r11, %r10 + # A[14] x A[1] + mulxq 112(%rsi), %rax, %rcx + adcxq %rax, %rbx + adoxq %rcx, %r9 + # A[15] x A[1] + mulxq 120(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # No store %rbx + movq %r9, (%rdi) + movq %r11, %r8 + # A[15] x A[2] + movq 16(%rsi), %rdx + mulxq 120(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r10, 8(%rdi) + # Carry + adcxq %r12, %r8 + movq %r11, %r12 + adcxq %r11, %r12 + adoxq %r11, %r12 + movq %r8, 16(%rdi) + # Diagonal 3 + movq 40(%rbp), %r8 + movq 48(%rbp), %r9 + movq 56(%rbp), %r10 + # A[3] x A[2] + mulxq 24(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[4] x A[2] + mulxq 32(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r8, 40(%rbp) + movq %r9, 48(%rbp) + movq 64(%rbp), %r8 + movq 72(%rbp), %r9 + # A[5] x A[2] + mulxq 40(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + # A[6] x A[2] + mulxq 48(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r10, 56(%rbp) + movq %r8, 64(%rbp) + movq 80(%rbp), %r10 + movq 88(%rbp), %r8 + # A[7] x A[2] + mulxq 56(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[8] x A[2] + mulxq 64(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r9, 72(%rbp) + movq %r10, 80(%rbp) + # No load %r13 - %r9 + # No load %r14 - %r10 + # A[9] x A[2] + mulxq 72(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r13 + # A[10] x A[2] + mulxq 80(%rsi), %rax, %rcx + adcxq %rax, %r13 + adoxq %rcx, %r14 + movq %r8, 88(%rbp) + # No store %r13 + # No load %r15 - %r8 + # No load %rbx - %r9 + # A[11] x A[2] + mulxq 88(%rsi), %rax, %rcx + adcxq %rax, %r14 + adoxq %rcx, %r15 + # A[12] x A[2] + mulxq 96(%rsi), %rax, %rcx + adcxq %rax, %r15 + adoxq %rcx, %rbx + # No store %r14 + # No store %r15 + movq (%rdi), %r10 + movq 8(%rdi), %r8 + # A[13] x A[2] + mulxq 104(%rsi), %rax, %rcx + adcxq %rax, %rbx + adoxq %rcx, %r10 + # A[14] x A[2] + mulxq 112(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + # No store %rbx + movq %r10, (%rdi) + movq 16(%rdi), %r9 + movq %r11, %r10 + # A[14] x A[3] + movq 112(%rsi), %rdx + mulxq 24(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[14] x A[4] + mulxq 32(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r8, 8(%rdi) + movq %r9, 16(%rdi) + movq %r11, %r8 + # A[14] x A[5] + mulxq 40(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r10, 24(%rdi) + # Carry + adcxq %r12, %r8 + movq %r11, %r12 + adcxq %r11, %r12 + adoxq %r11, %r12 + movq %r8, 32(%rdi) + # Diagonal 4 + movq 56(%rbp), %r8 + movq 64(%rbp), %r9 + movq 72(%rbp), %r10 + # A[4] x A[3] + movq 24(%rsi), %rdx + mulxq 32(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[5] x A[3] + mulxq 40(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r8, 56(%rbp) + movq %r9, 64(%rbp) + movq 80(%rbp), %r8 + movq 88(%rbp), %r9 + # A[6] x A[3] + mulxq 48(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + # A[7] x A[3] + mulxq 56(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r10, 72(%rbp) + movq %r8, 80(%rbp) + # No load %r13 - %r10 + # No load %r14 - %r8 + # A[8] x A[3] + mulxq 64(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r13 + # A[9] x A[3] + mulxq 72(%rsi), %rax, %rcx + adcxq %rax, %r13 + adoxq %rcx, %r14 + movq %r9, 88(%rbp) + # No store %r13 + # No load %r15 - %r9 + # No load %rbx - %r10 + # A[10] x A[3] + mulxq 80(%rsi), %rax, %rcx + adcxq %rax, %r14 + adoxq %rcx, %r15 + # A[11] x A[3] + mulxq 88(%rsi), %rax, %rcx + adcxq %rax, %r15 + adoxq %rcx, %rbx + # No store %r14 + # No store %r15 + movq (%rdi), %r8 + movq 8(%rdi), %r9 + # A[12] x A[3] + mulxq 96(%rsi), %rax, %rcx + adcxq %rax, %rbx + adoxq %rcx, %r8 + # A[13] x A[3] + mulxq 104(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # No store %rbx + movq %r8, (%rdi) + movq 16(%rdi), %r10 + movq 24(%rdi), %r8 + # A[13] x A[4] + movq 104(%rsi), %rdx + mulxq 32(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[13] x A[5] + mulxq 40(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r9, 8(%rdi) + movq %r10, 16(%rdi) + movq 32(%rdi), %r9 + movq %r11, %r10 + # A[13] x A[6] + mulxq 48(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[13] x A[7] + mulxq 56(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r8, 24(%rdi) + movq %r9, 32(%rdi) + movq %r11, %r8 + # A[13] x A[8] + mulxq 64(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r10, 40(%rdi) + # Carry + adcxq %r12, %r8 + movq %r11, %r12 + adcxq %r11, %r12 + adoxq %r11, %r12 + movq %r8, 48(%rdi) + # Diagonal 5 + movq 72(%rbp), %r8 + movq 80(%rbp), %r9 + movq 88(%rbp), %r10 + # A[5] x A[4] + movq 32(%rsi), %rdx + mulxq 40(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[6] x A[4] + mulxq 48(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r8, 72(%rbp) + movq %r9, 80(%rbp) + # No load %r13 - %r8 + # No load %r14 - %r9 + # A[7] x A[4] + mulxq 56(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r13 + # A[8] x A[4] + mulxq 64(%rsi), %rax, %rcx + adcxq %rax, %r13 + adoxq %rcx, %r14 + movq %r10, 88(%rbp) + # No store %r13 + # No load %r15 - %r10 + # No load %rbx - %r8 + # A[9] x A[4] + mulxq 72(%rsi), %rax, %rcx + adcxq %rax, %r14 + adoxq %rcx, %r15 + # A[10] x A[4] + mulxq 80(%rsi), %rax, %rcx + adcxq %rax, %r15 + adoxq %rcx, %rbx + # No store %r14 + # No store %r15 + movq (%rdi), %r9 + movq 8(%rdi), %r10 + # A[11] x A[4] + mulxq 88(%rsi), %rax, %rcx + adcxq %rax, %rbx + adoxq %rcx, %r9 + # A[12] x A[4] + mulxq 96(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # No store %rbx + movq %r9, (%rdi) + movq 16(%rdi), %r8 + movq 24(%rdi), %r9 + # A[12] x A[5] + movq 96(%rsi), %rdx + mulxq 40(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + # A[12] x A[6] + mulxq 48(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r10, 8(%rdi) + movq %r8, 16(%rdi) + movq 32(%rdi), %r10 + movq 40(%rdi), %r8 + # A[12] x A[7] + mulxq 56(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[12] x A[8] + mulxq 64(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r9, 24(%rdi) + movq %r10, 32(%rdi) + movq 48(%rdi), %r9 + movq %r11, %r10 + # A[12] x A[9] + mulxq 72(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[12] x A[10] + mulxq 80(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r8, 40(%rdi) + movq %r9, 48(%rdi) + movq %r11, %r8 + # A[12] x A[11] + mulxq 88(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r10, 56(%rdi) + # Carry + adcxq %r12, %r8 + movq %r11, %r12 + adcxq %r11, %r12 + adoxq %r11, %r12 + movq %r8, 64(%rdi) + # Diagonal 6 + movq 88(%rbp), %r8 + # No load %r13 - %r9 + # No load %r14 - %r10 + # A[6] x A[5] + movq 40(%rsi), %rdx + mulxq 48(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r13 + # A[7] x A[5] + mulxq 56(%rsi), %rax, %rcx + adcxq %rax, %r13 + adoxq %rcx, %r14 + movq %r8, 88(%rbp) + # No store %r13 + # No load %r15 - %r8 + # No load %rbx - %r9 + # A[8] x A[5] + mulxq 64(%rsi), %rax, %rcx + adcxq %rax, %r14 + adoxq %rcx, %r15 + # A[9] x A[5] + mulxq 72(%rsi), %rax, %rcx + adcxq %rax, %r15 + adoxq %rcx, %rbx + # No store %r14 + # No store %r15 + movq (%rdi), %r10 + movq 8(%rdi), %r8 + # A[10] x A[5] + mulxq 80(%rsi), %rax, %rcx + adcxq %rax, %rbx + adoxq %rcx, %r10 + # A[11] x A[5] + mulxq 88(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + # No store %rbx + movq %r10, (%rdi) + movq 16(%rdi), %r9 + movq 24(%rdi), %r10 + # A[11] x A[6] + movq 88(%rsi), %rdx + mulxq 48(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[11] x A[7] + mulxq 56(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r8, 8(%rdi) + movq %r9, 16(%rdi) + movq 32(%rdi), %r8 + movq 40(%rdi), %r9 + # A[11] x A[8] + mulxq 64(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + # A[11] x A[9] + mulxq 72(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r10, 24(%rdi) + movq %r8, 32(%rdi) + movq 48(%rdi), %r10 + movq 56(%rdi), %r8 + # A[11] x A[10] + mulxq 80(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[13] x A[9] + movq 104(%rsi), %rdx + mulxq 72(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r9, 40(%rdi) + movq %r10, 48(%rdi) + movq 64(%rdi), %r9 + movq %r11, %r10 + # A[13] x A[10] + mulxq 80(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[13] x A[11] + mulxq 88(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r8, 56(%rdi) + movq %r9, 64(%rdi) + movq %r11, %r8 + # A[13] x A[12] + mulxq 96(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r10, 72(%rdi) + # Carry + adcxq %r12, %r8 + movq %r11, %r12 + adcxq %r11, %r12 + adoxq %r11, %r12 + movq %r8, 80(%rdi) + # Diagonal 7 + # No load %r14 - %r8 + # No load %r15 - %r9 + # No load %rbx - %r10 + # A[7] x A[6] + movq 48(%rsi), %rdx + mulxq 56(%rsi), %rax, %rcx + adcxq %rax, %r14 + adoxq %rcx, %r15 + # A[8] x A[6] + mulxq 64(%rsi), %rax, %rcx + adcxq %rax, %r15 + adoxq %rcx, %rbx + # No store %r14 + # No store %r15 + movq (%rdi), %r8 + movq 8(%rdi), %r9 + # A[9] x A[6] + mulxq 72(%rsi), %rax, %rcx + adcxq %rax, %rbx + adoxq %rcx, %r8 + # A[10] x A[6] + mulxq 80(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # No store %rbx + movq %r8, (%rdi) + movq 16(%rdi), %r10 + movq 24(%rdi), %r8 + # A[10] x A[7] + movq 80(%rsi), %rdx + mulxq 56(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[10] x A[8] + mulxq 64(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r9, 8(%rdi) + movq %r10, 16(%rdi) + movq 32(%rdi), %r9 + movq 40(%rdi), %r10 + # A[10] x A[9] + mulxq 72(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[14] x A[6] + movq 112(%rsi), %rdx + mulxq 48(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r8, 24(%rdi) + movq %r9, 32(%rdi) + movq 48(%rdi), %r8 + movq 56(%rdi), %r9 + # A[14] x A[7] + mulxq 56(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + # A[14] x A[8] + mulxq 64(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r10, 40(%rdi) + movq %r8, 48(%rdi) + movq 64(%rdi), %r10 + movq 72(%rdi), %r8 + # A[14] x A[9] + mulxq 72(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[14] x A[10] + mulxq 80(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r9, 56(%rdi) + movq %r10, 64(%rdi) + movq 80(%rdi), %r9 + movq %r11, %r10 + # A[14] x A[11] + mulxq 88(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[14] x A[12] + mulxq 96(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r8, 72(%rdi) + movq %r9, 80(%rdi) + movq %r11, %r8 + # A[14] x A[13] + mulxq 104(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r10, 88(%rdi) + # Carry + adcxq %r12, %r8 + movq %r11, %r12 + adcxq %r11, %r12 + adoxq %r11, %r12 + movq %r8, 96(%rdi) + # Diagonal 8 + # No load %rbx - %r8 + movq (%rdi), %r9 + movq 8(%rdi), %r10 + # A[8] x A[7] + movq 56(%rsi), %rdx + mulxq 64(%rsi), %rax, %rcx + adcxq %rax, %rbx + adoxq %rcx, %r9 + # A[9] x A[7] + mulxq 72(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # No store %rbx + movq %r9, (%rdi) + movq 16(%rdi), %r8 + movq 24(%rdi), %r9 + # A[9] x A[8] + movq 64(%rsi), %rdx + mulxq 72(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + # A[15] x A[3] + movq 120(%rsi), %rdx + mulxq 24(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r10, 8(%rdi) + movq %r8, 16(%rdi) + movq 32(%rdi), %r10 + movq 40(%rdi), %r8 + # A[15] x A[4] + mulxq 32(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[15] x A[5] + mulxq 40(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r9, 24(%rdi) + movq %r10, 32(%rdi) + movq 48(%rdi), %r9 + movq 56(%rdi), %r10 + # A[15] x A[6] + mulxq 48(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[15] x A[7] + mulxq 56(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r8, 40(%rdi) + movq %r9, 48(%rdi) + movq 64(%rdi), %r8 + movq 72(%rdi), %r9 + # A[15] x A[8] + mulxq 64(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + # A[15] x A[9] + mulxq 72(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r10, 56(%rdi) + movq %r8, 64(%rdi) + movq 80(%rdi), %r10 + movq 88(%rdi), %r8 + # A[15] x A[10] + mulxq 80(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[15] x A[11] + mulxq 88(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r9, 72(%rdi) + movq %r10, 80(%rdi) + movq 96(%rdi), %r9 + movq %r11, %r10 + # A[15] x A[12] + mulxq 96(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[15] x A[13] + mulxq 104(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r8, 88(%rdi) + movq %r9, 96(%rdi) + movq %r11, %r8 + # A[15] x A[14] + mulxq 112(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r10, 104(%rdi) + # Carry + adcxq %r12, %r8 + movq %r11, %r12 + adcxq %r11, %r12 + adoxq %r11, %r12 + movq %r8, 112(%rdi) + movq %r12, 120(%rdi) + # Double and Add in A[i] x A[i] + movq 8(%rbp), %r9 + # A[0] x A[0] + movq (%rsi), %rdx + mulxq %rdx, %rax, %rcx + movq %rax, (%rbp) + adoxq %r9, %r9 + adcxq %rcx, %r9 + movq %r9, 8(%rbp) + movq 16(%rbp), %r8 + movq 24(%rbp), %r9 + # A[1] x A[1] + movq 8(%rsi), %rdx + mulxq %rdx, %rax, %rcx + adoxq %r8, %r8 + adoxq %r9, %r9 + adcxq %rax, %r8 + adcxq %rcx, %r9 + movq %r8, 16(%rbp) + movq %r9, 24(%rbp) + movq 32(%rbp), %r8 + movq 40(%rbp), %r9 + # A[2] x A[2] + movq 16(%rsi), %rdx + mulxq %rdx, %rax, %rcx + adoxq %r8, %r8 + adoxq %r9, %r9 + adcxq %rax, %r8 + adcxq %rcx, %r9 + movq %r8, 32(%rbp) + movq %r9, 40(%rbp) + movq 48(%rbp), %r8 + movq 56(%rbp), %r9 + # A[3] x A[3] + movq 24(%rsi), %rdx + mulxq %rdx, %rax, %rcx + adoxq %r8, %r8 + adoxq %r9, %r9 + adcxq %rax, %r8 + adcxq %rcx, %r9 + movq %r8, 48(%rbp) + movq %r9, 56(%rbp) + movq 64(%rbp), %r8 + movq 72(%rbp), %r9 + # A[4] x A[4] + movq 32(%rsi), %rdx + mulxq %rdx, %rax, %rcx + adoxq %r8, %r8 + adoxq %r9, %r9 + adcxq %rax, %r8 + adcxq %rcx, %r9 + movq %r8, 64(%rbp) + movq %r9, 72(%rbp) + movq 80(%rbp), %r8 + movq 88(%rbp), %r9 + # A[5] x A[5] + movq 40(%rsi), %rdx + mulxq %rdx, %rax, %rcx + adoxq %r8, %r8 + adoxq %r9, %r9 + adcxq %rax, %r8 + adcxq %rcx, %r9 + movq %r8, 80(%rbp) + movq %r9, 88(%rbp) + # A[6] x A[6] + movq 48(%rsi), %rdx + mulxq %rdx, %rax, %rcx + adoxq %r13, %r13 + adoxq %r14, %r14 + adcxq %rax, %r13 + adcxq %rcx, %r14 + # A[7] x A[7] + movq 56(%rsi), %rdx + mulxq %rdx, %rax, %rcx + adoxq %r15, %r15 + adoxq %rbx, %rbx + adcxq %rax, %r15 + adcxq %rcx, %rbx + movq (%rdi), %r8 + movq 8(%rdi), %r9 + # A[8] x A[8] + movq 64(%rsi), %rdx + mulxq %rdx, %rax, %rcx + adoxq %r8, %r8 + adoxq %r9, %r9 + adcxq %rax, %r8 + adcxq %rcx, %r9 + movq %r8, (%rdi) + movq %r9, 8(%rdi) + movq 16(%rdi), %r8 + movq 24(%rdi), %r9 + # A[9] x A[9] + movq 72(%rsi), %rdx + mulxq %rdx, %rax, %rcx + adoxq %r8, %r8 + adoxq %r9, %r9 + adcxq %rax, %r8 + adcxq %rcx, %r9 + movq %r8, 16(%rdi) + movq %r9, 24(%rdi) + movq 32(%rdi), %r8 + movq 40(%rdi), %r9 + # A[10] x A[10] + movq 80(%rsi), %rdx + mulxq %rdx, %rax, %rcx + adoxq %r8, %r8 + adoxq %r9, %r9 + adcxq %rax, %r8 + adcxq %rcx, %r9 + movq %r8, 32(%rdi) + movq %r9, 40(%rdi) + movq 48(%rdi), %r8 + movq 56(%rdi), %r9 + # A[11] x A[11] + movq 88(%rsi), %rdx + mulxq %rdx, %rax, %rcx + adoxq %r8, %r8 + adoxq %r9, %r9 + adcxq %rax, %r8 + adcxq %rcx, %r9 + movq %r8, 48(%rdi) + movq %r9, 56(%rdi) + movq 64(%rdi), %r8 + movq 72(%rdi), %r9 + # A[12] x A[12] + movq 96(%rsi), %rdx + mulxq %rdx, %rax, %rcx + adoxq %r8, %r8 + adoxq %r9, %r9 + adcxq %rax, %r8 + adcxq %rcx, %r9 + movq %r8, 64(%rdi) + movq %r9, 72(%rdi) + movq 80(%rdi), %r8 + movq 88(%rdi), %r9 + # A[13] x A[13] + movq 104(%rsi), %rdx + mulxq %rdx, %rax, %rcx + adoxq %r8, %r8 + adoxq %r9, %r9 + adcxq %rax, %r8 + adcxq %rcx, %r9 + movq %r8, 80(%rdi) + movq %r9, 88(%rdi) + movq 96(%rdi), %r8 + movq 104(%rdi), %r9 + # A[14] x A[14] + movq 112(%rsi), %rdx + mulxq %rdx, %rax, %rcx + adoxq %r8, %r8 + adoxq %r9, %r9 + adcxq %rax, %r8 + adcxq %rcx, %r9 + movq %r8, 96(%rdi) + movq %r9, 104(%rdi) + movq 112(%rdi), %r8 + movq 120(%rdi), %r9 + # A[15] x A[15] + movq 120(%rsi), %rdx + mulxq %rdx, %rax, %rcx + adoxq %r8, %r8 + adoxq %r9, %r9 + adcxq %rax, %r8 + adcxq %rcx, %r9 + movq %r8, 112(%rdi) + movq %r9, 120(%rdi) + movq %r13, -32(%rdi) + movq %r14, -24(%rdi) + movq %r15, -16(%rdi) + movq %rbx, -8(%rdi) + subq $0x80, %rdi + cmpq %rdi, %rsi + jne L_end_1024_sqr_avx2_16 + vmovdqu (%rbp), %xmm0 + vmovups %xmm0, (%rdi) + vmovdqu 16(%rbp), %xmm0 + vmovups %xmm0, 16(%rdi) + vmovdqu 32(%rbp), %xmm0 + vmovups %xmm0, 32(%rdi) + vmovdqu 48(%rbp), %xmm0 + vmovups %xmm0, 48(%rdi) + vmovdqu 64(%rbp), %xmm0 + vmovups %xmm0, 64(%rdi) + vmovdqu 80(%rbp), %xmm0 + vmovups %xmm0, 80(%rdi) +L_end_1024_sqr_avx2_16: + addq $0x80, %rsp + popq %rbx + popq %r15 + popq %r14 + popq %r13 + popq %r12 + popq %rbp + repz retq +#ifndef __APPLE__ +.size sp_1024_sqr_avx2_16,.-sp_1024_sqr_avx2_16 +#endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +/* Add b to a into r. (r = a + b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +#ifndef __APPLE__ +.text +.globl sp_1024_add_16 +.type sp_1024_add_16,@function +.align 16 +sp_1024_add_16: +#else +.section __TEXT,__text +.globl _sp_1024_add_16 +.p2align 4 +_sp_1024_add_16: +#endif /* __APPLE__ */ + # Add + movq (%rsi), %rcx + xorq %rax, %rax + addq (%rdx), %rcx + movq 8(%rsi), %r8 + movq %rcx, (%rdi) + adcq 8(%rdx), %r8 + movq 16(%rsi), %rcx + movq %r8, 8(%rdi) + adcq 16(%rdx), %rcx + movq 24(%rsi), %r8 + movq %rcx, 16(%rdi) + adcq 24(%rdx), %r8 + movq 32(%rsi), %rcx + movq %r8, 24(%rdi) + adcq 32(%rdx), %rcx + movq 40(%rsi), %r8 + movq %rcx, 32(%rdi) + adcq 40(%rdx), %r8 + movq 48(%rsi), %rcx + movq %r8, 40(%rdi) + adcq 48(%rdx), %rcx + movq 56(%rsi), %r8 + movq %rcx, 48(%rdi) + adcq 56(%rdx), %r8 + movq 64(%rsi), %rcx + movq %r8, 56(%rdi) + adcq 64(%rdx), %rcx + movq 72(%rsi), %r8 + movq %rcx, 64(%rdi) + adcq 72(%rdx), %r8 + movq 80(%rsi), %rcx + movq %r8, 72(%rdi) + adcq 80(%rdx), %rcx + movq 88(%rsi), %r8 + movq %rcx, 80(%rdi) + adcq 88(%rdx), %r8 + movq 96(%rsi), %rcx + movq %r8, 88(%rdi) + adcq 96(%rdx), %rcx + movq 104(%rsi), %r8 + movq %rcx, 96(%rdi) + adcq 104(%rdx), %r8 + movq 112(%rsi), %rcx + movq %r8, 104(%rdi) + adcq 112(%rdx), %rcx + movq 120(%rsi), %r8 + movq %rcx, 112(%rdi) + adcq 120(%rdx), %r8 + movq %r8, 120(%rdi) + adcq $0x00, %rax + repz retq +#ifndef __APPLE__ +.size sp_1024_add_16,.-sp_1024_add_16 +#endif /* __APPLE__ */ +/* Sub b from a into a. (a -= b) + * + * a A single precision integer and result. + * b A single precision integer. + */ +#ifndef __APPLE__ +.text +.globl sp_1024_sub_in_place_16 +.type sp_1024_sub_in_place_16,@function +.align 16 +sp_1024_sub_in_place_16: +#else +.section __TEXT,__text +.globl _sp_1024_sub_in_place_16 +.p2align 4 +_sp_1024_sub_in_place_16: +#endif /* __APPLE__ */ + movq (%rdi), %rdx + xorq %rax, %rax + subq (%rsi), %rdx + movq 8(%rdi), %rcx + movq %rdx, (%rdi) + sbbq 8(%rsi), %rcx + movq 16(%rdi), %rdx + movq %rcx, 8(%rdi) + sbbq 16(%rsi), %rdx + movq 24(%rdi), %rcx + movq %rdx, 16(%rdi) + sbbq 24(%rsi), %rcx + movq 32(%rdi), %rdx + movq %rcx, 24(%rdi) + sbbq 32(%rsi), %rdx + movq 40(%rdi), %rcx + movq %rdx, 32(%rdi) + sbbq 40(%rsi), %rcx + movq 48(%rdi), %rdx + movq %rcx, 40(%rdi) + sbbq 48(%rsi), %rdx + movq 56(%rdi), %rcx + movq %rdx, 48(%rdi) + sbbq 56(%rsi), %rcx + movq 64(%rdi), %rdx + movq %rcx, 56(%rdi) + sbbq 64(%rsi), %rdx + movq 72(%rdi), %rcx + movq %rdx, 64(%rdi) + sbbq 72(%rsi), %rcx + movq 80(%rdi), %rdx + movq %rcx, 72(%rdi) + sbbq 80(%rsi), %rdx + movq 88(%rdi), %rcx + movq %rdx, 80(%rdi) + sbbq 88(%rsi), %rcx + movq 96(%rdi), %rdx + movq %rcx, 88(%rdi) + sbbq 96(%rsi), %rdx + movq 104(%rdi), %rcx + movq %rdx, 96(%rdi) + sbbq 104(%rsi), %rcx + movq 112(%rdi), %rdx + movq %rcx, 104(%rdi) + sbbq 112(%rsi), %rdx + movq 120(%rdi), %rcx + movq %rdx, 112(%rdi) + sbbq 120(%rsi), %rcx + movq %rcx, 120(%rdi) + sbbq $0x00, %rax + repz retq +#ifndef __APPLE__ +.size sp_1024_sub_in_place_16,.-sp_1024_sub_in_place_16 +#endif /* __APPLE__ */ +/* Conditionally subtract b from a using the mask m. + * m is -1 to subtract and 0 when not copying. + * + * r A single precision number representing condition subtract result. + * a A single precision number to subtract from. + * b A single precision number to subtract. + * m Mask value to apply. + */ +#ifndef __APPLE__ +.text +.globl sp_1024_cond_sub_16 +.type sp_1024_cond_sub_16,@function +.align 16 +sp_1024_cond_sub_16: +#else +.section __TEXT,__text +.globl _sp_1024_cond_sub_16 +.p2align 4 +_sp_1024_cond_sub_16: +#endif /* __APPLE__ */ + subq $0x80, %rsp + movq $0x00, %rax + movq (%rdx), %r8 + movq 8(%rdx), %r9 + andq %rcx, %r8 + andq %rcx, %r9 + movq %r8, (%rsp) + movq %r9, 8(%rsp) + movq 16(%rdx), %r8 + movq 24(%rdx), %r9 + andq %rcx, %r8 + andq %rcx, %r9 + movq %r8, 16(%rsp) + movq %r9, 24(%rsp) + movq 32(%rdx), %r8 + movq 40(%rdx), %r9 + andq %rcx, %r8 + andq %rcx, %r9 + movq %r8, 32(%rsp) + movq %r9, 40(%rsp) + movq 48(%rdx), %r8 + movq 56(%rdx), %r9 + andq %rcx, %r8 + andq %rcx, %r9 + movq %r8, 48(%rsp) + movq %r9, 56(%rsp) + movq 64(%rdx), %r8 + movq 72(%rdx), %r9 + andq %rcx, %r8 + andq %rcx, %r9 + movq %r8, 64(%rsp) + movq %r9, 72(%rsp) + movq 80(%rdx), %r8 + movq 88(%rdx), %r9 + andq %rcx, %r8 + andq %rcx, %r9 + movq %r8, 80(%rsp) + movq %r9, 88(%rsp) + movq 96(%rdx), %r8 + movq 104(%rdx), %r9 + andq %rcx, %r8 + andq %rcx, %r9 + movq %r8, 96(%rsp) + movq %r9, 104(%rsp) + movq 112(%rdx), %r8 + movq 120(%rdx), %r9 + andq %rcx, %r8 + andq %rcx, %r9 + movq %r8, 112(%rsp) + movq %r9, 120(%rsp) + movq (%rsi), %r8 + movq (%rsp), %rdx + subq %rdx, %r8 + movq 8(%rsi), %r9 + movq 8(%rsp), %rdx + sbbq %rdx, %r9 + movq %r8, (%rdi) + movq 16(%rsi), %r8 + movq 16(%rsp), %rdx + sbbq %rdx, %r8 + movq %r9, 8(%rdi) + movq 24(%rsi), %r9 + movq 24(%rsp), %rdx + sbbq %rdx, %r9 + movq %r8, 16(%rdi) + movq 32(%rsi), %r8 + movq 32(%rsp), %rdx + sbbq %rdx, %r8 + movq %r9, 24(%rdi) + movq 40(%rsi), %r9 + movq 40(%rsp), %rdx + sbbq %rdx, %r9 + movq %r8, 32(%rdi) + movq 48(%rsi), %r8 + movq 48(%rsp), %rdx + sbbq %rdx, %r8 + movq %r9, 40(%rdi) + movq 56(%rsi), %r9 + movq 56(%rsp), %rdx + sbbq %rdx, %r9 + movq %r8, 48(%rdi) + movq 64(%rsi), %r8 + movq 64(%rsp), %rdx + sbbq %rdx, %r8 + movq %r9, 56(%rdi) + movq 72(%rsi), %r9 + movq 72(%rsp), %rdx + sbbq %rdx, %r9 + movq %r8, 64(%rdi) + movq 80(%rsi), %r8 + movq 80(%rsp), %rdx + sbbq %rdx, %r8 + movq %r9, 72(%rdi) + movq 88(%rsi), %r9 + movq 88(%rsp), %rdx + sbbq %rdx, %r9 + movq %r8, 80(%rdi) + movq 96(%rsi), %r8 + movq 96(%rsp), %rdx + sbbq %rdx, %r8 + movq %r9, 88(%rdi) + movq 104(%rsi), %r9 + movq 104(%rsp), %rdx + sbbq %rdx, %r9 + movq %r8, 96(%rdi) + movq 112(%rsi), %r8 + movq 112(%rsp), %rdx + sbbq %rdx, %r8 + movq %r9, 104(%rdi) + movq 120(%rsi), %r9 + movq 120(%rsp), %rdx + sbbq %rdx, %r9 + movq %r8, 112(%rdi) + movq %r9, 120(%rdi) + sbbq $0x00, %rax + addq $0x80, %rsp + repz retq +#ifndef __APPLE__ +.size sp_1024_cond_sub_16,.-sp_1024_cond_sub_16 +#endif /* __APPLE__ */ +#ifdef HAVE_INTEL_AVX2 +/* Conditionally subtract b from a using the mask m. + * m is -1 to subtract and 0 when not copying. + * + * r A single precision number representing condition subtract result. + * a A single precision number to subtract from. + * b A single precision number to subtract. + * m Mask value to apply. + */ +#ifndef __APPLE__ +.text +.globl sp_1024_cond_sub_avx2_16 +.type sp_1024_cond_sub_avx2_16,@function +.align 16 +sp_1024_cond_sub_avx2_16: +#else +.section __TEXT,__text +.globl _sp_1024_cond_sub_avx2_16 +.p2align 4 +_sp_1024_cond_sub_avx2_16: +#endif /* __APPLE__ */ + movq $0x00, %rax + movq (%rdx), %r10 + movq (%rsi), %r8 + pextq %rcx, %r10, %r10 + subq %r10, %r8 + movq 8(%rdx), %r10 + movq 8(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, (%rdi) + sbbq %r10, %r9 + movq 16(%rdx), %r8 + movq 16(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 8(%rdi) + sbbq %r8, %r10 + movq 24(%rdx), %r9 + movq 24(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 16(%rdi) + sbbq %r9, %r8 + movq 32(%rdx), %r10 + movq 32(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 24(%rdi) + sbbq %r10, %r9 + movq 40(%rdx), %r8 + movq 40(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 32(%rdi) + sbbq %r8, %r10 + movq 48(%rdx), %r9 + movq 48(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 40(%rdi) + sbbq %r9, %r8 + movq 56(%rdx), %r10 + movq 56(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 48(%rdi) + sbbq %r10, %r9 + movq 64(%rdx), %r8 + movq 64(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 56(%rdi) + sbbq %r8, %r10 + movq 72(%rdx), %r9 + movq 72(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 64(%rdi) + sbbq %r9, %r8 + movq 80(%rdx), %r10 + movq 80(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 72(%rdi) + sbbq %r10, %r9 + movq 88(%rdx), %r8 + movq 88(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 80(%rdi) + sbbq %r8, %r10 + movq 96(%rdx), %r9 + movq 96(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 88(%rdi) + sbbq %r9, %r8 + movq 104(%rdx), %r10 + movq 104(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 96(%rdi) + sbbq %r10, %r9 + movq 112(%rdx), %r8 + movq 112(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 104(%rdi) + sbbq %r8, %r10 + movq 120(%rdx), %r9 + movq 120(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 112(%rdi) + sbbq %r9, %r8 + movq %r8, 120(%rdi) + sbbq $0x00, %rax + repz retq +#ifndef __APPLE__ +.size sp_1024_cond_sub_avx2_16,.-sp_1024_cond_sub_avx2_16 +#endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +/* Mul a by digit b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision digit. + */ +#ifndef __APPLE__ +.text +.globl sp_1024_mul_d_16 +.type sp_1024_mul_d_16,@function +.align 16 +sp_1024_mul_d_16: +#else +.section __TEXT,__text +.globl _sp_1024_mul_d_16 +.p2align 4 +_sp_1024_mul_d_16: +#endif /* __APPLE__ */ + movq %rdx, %rcx + # A[0] * B + movq %rcx, %rax + xorq %r10, %r10 + mulq (%rsi) + movq %rax, %r8 + movq %rdx, %r9 + movq %r8, (%rdi) + # A[1] * B + movq %rcx, %rax + xorq %r8, %r8 + mulq 8(%rsi) + addq %rax, %r9 + movq %r9, 8(%rdi) + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[2] * B + movq %rcx, %rax + xorq %r9, %r9 + mulq 16(%rsi) + addq %rax, %r10 + movq %r10, 16(%rdi) + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[3] * B + movq %rcx, %rax + xorq %r10, %r10 + mulq 24(%rsi) + addq %rax, %r8 + movq %r8, 24(%rdi) + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[4] * B + movq %rcx, %rax + xorq %r8, %r8 + mulq 32(%rsi) + addq %rax, %r9 + movq %r9, 32(%rdi) + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[5] * B + movq %rcx, %rax + xorq %r9, %r9 + mulq 40(%rsi) + addq %rax, %r10 + movq %r10, 40(%rdi) + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[6] * B + movq %rcx, %rax + xorq %r10, %r10 + mulq 48(%rsi) + addq %rax, %r8 + movq %r8, 48(%rdi) + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[7] * B + movq %rcx, %rax + xorq %r8, %r8 + mulq 56(%rsi) + addq %rax, %r9 + movq %r9, 56(%rdi) + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[8] * B + movq %rcx, %rax + xorq %r9, %r9 + mulq 64(%rsi) + addq %rax, %r10 + movq %r10, 64(%rdi) + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[9] * B + movq %rcx, %rax + xorq %r10, %r10 + mulq 72(%rsi) + addq %rax, %r8 + movq %r8, 72(%rdi) + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[10] * B + movq %rcx, %rax + xorq %r8, %r8 + mulq 80(%rsi) + addq %rax, %r9 + movq %r9, 80(%rdi) + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[11] * B + movq %rcx, %rax + xorq %r9, %r9 + mulq 88(%rsi) + addq %rax, %r10 + movq %r10, 88(%rdi) + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[12] * B + movq %rcx, %rax + xorq %r10, %r10 + mulq 96(%rsi) + addq %rax, %r8 + movq %r8, 96(%rdi) + adcq %rdx, %r9 + adcq $0x00, %r10 + # A[13] * B + movq %rcx, %rax + xorq %r8, %r8 + mulq 104(%rsi) + addq %rax, %r9 + movq %r9, 104(%rdi) + adcq %rdx, %r10 + adcq $0x00, %r8 + # A[14] * B + movq %rcx, %rax + xorq %r9, %r9 + mulq 112(%rsi) + addq %rax, %r10 + movq %r10, 112(%rdi) + adcq %rdx, %r8 + adcq $0x00, %r9 + # A[15] * B + movq %rcx, %rax + mulq 120(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + movq %r8, 120(%rdi) + movq %r9, 128(%rdi) + repz retq +#ifndef __APPLE__ +.size sp_1024_mul_d_16,.-sp_1024_mul_d_16 +#endif /* __APPLE__ */ +#ifdef HAVE_INTEL_AVX2 +/* Mul a by digit b into r. (r = a * b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision digit. + */ +#ifndef __APPLE__ +.text +.globl sp_1024_mul_d_avx2_16 +.type sp_1024_mul_d_avx2_16,@function +.align 16 +sp_1024_mul_d_avx2_16: +#else +.section __TEXT,__text +.globl _sp_1024_mul_d_avx2_16 +.p2align 4 +_sp_1024_mul_d_avx2_16: +#endif /* __APPLE__ */ + movq %rdx, %rax + # A[0] * B + movq %rax, %rdx + xorq %r11, %r11 + mulxq (%rsi), %r9, %r10 + movq %r9, (%rdi) + # A[1] * B + mulxq 8(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + movq %r10, 8(%rdi) + # A[2] * B + mulxq 16(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + adoxq %r8, %r10 + movq %r9, 16(%rdi) + # A[3] * B + mulxq 24(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + movq %r10, 24(%rdi) + # A[4] * B + mulxq 32(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + adoxq %r8, %r10 + movq %r9, 32(%rdi) + # A[5] * B + mulxq 40(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + movq %r10, 40(%rdi) + # A[6] * B + mulxq 48(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + adoxq %r8, %r10 + movq %r9, 48(%rdi) + # A[7] * B + mulxq 56(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + movq %r10, 56(%rdi) + # A[8] * B + mulxq 64(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + adoxq %r8, %r10 + movq %r9, 64(%rdi) + # A[9] * B + mulxq 72(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + movq %r10, 72(%rdi) + # A[10] * B + mulxq 80(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + adoxq %r8, %r10 + movq %r9, 80(%rdi) + # A[11] * B + mulxq 88(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + movq %r10, 88(%rdi) + # A[12] * B + mulxq 96(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + adoxq %r8, %r10 + movq %r9, 96(%rdi) + # A[13] * B + mulxq 104(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + movq %r10, 104(%rdi) + # A[14] * B + mulxq 112(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + adoxq %r8, %r10 + movq %r9, 112(%rdi) + # A[15] * B + mulxq 120(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + adcxq %r11, %r9 + movq %r10, 120(%rdi) + movq %r9, 128(%rdi) + repz retq +#ifndef __APPLE__ +.size sp_1024_mul_d_avx2_16,.-sp_1024_mul_d_avx2_16 +#endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +#ifdef _WIN64 +/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) + * + * d1 The high order half of the number to divide. + * d0 The low order half of the number to divide. + * div The dividend. + * returns the result of the division. + */ +#ifndef __APPLE__ +.text +.globl div_1024_word_asm_16 +.type div_1024_word_asm_16,@function +.align 16 +div_1024_word_asm_16: +#else +.section __TEXT,__text +.globl _div_1024_word_asm_16 +.p2align 4 +_div_1024_word_asm_16: +#endif /* __APPLE__ */ + movq %rdx, %rcx + movq %rsi, %rax + movq %rdi, %rdx + divq %rcx + repz retq +#ifndef __APPLE__ +.size div_1024_word_asm_16,.-div_1024_word_asm_16 +#endif /* __APPLE__ */ +#endif /* _WIN64 */ +/* Compare a with b in constant time. + * + * a A single precision integer. + * b A single precision integer. + * return -ve, 0 or +ve if a is less than, equal to or greater than b + * respectively. + */ +#ifndef __APPLE__ +.text +.globl sp_1024_cmp_16 +.type sp_1024_cmp_16,@function +.align 16 +sp_1024_cmp_16: +#else +.section __TEXT,__text +.globl _sp_1024_cmp_16 +.p2align 4 +_sp_1024_cmp_16: +#endif /* __APPLE__ */ + xorq %rcx, %rcx + movq $-1, %rdx + movq $-1, %rax + movq $0x01, %r8 + movq 120(%rdi), %r9 + movq 120(%rsi), %r10 + andq %rdx, %r9 + andq %rdx, %r10 + subq %r10, %r9 + cmova %r8, %rax + cmovc %rdx, %rax + cmovnz %rcx, %rdx + movq 112(%rdi), %r9 + movq 112(%rsi), %r10 + andq %rdx, %r9 + andq %rdx, %r10 + subq %r10, %r9 + cmova %r8, %rax + cmovc %rdx, %rax + cmovnz %rcx, %rdx + movq 104(%rdi), %r9 + movq 104(%rsi), %r10 + andq %rdx, %r9 + andq %rdx, %r10 + subq %r10, %r9 + cmova %r8, %rax + cmovc %rdx, %rax + cmovnz %rcx, %rdx + movq 96(%rdi), %r9 + movq 96(%rsi), %r10 + andq %rdx, %r9 + andq %rdx, %r10 + subq %r10, %r9 + cmova %r8, %rax + cmovc %rdx, %rax + cmovnz %rcx, %rdx + movq 88(%rdi), %r9 + movq 88(%rsi), %r10 + andq %rdx, %r9 + andq %rdx, %r10 + subq %r10, %r9 + cmova %r8, %rax + cmovc %rdx, %rax + cmovnz %rcx, %rdx + movq 80(%rdi), %r9 + movq 80(%rsi), %r10 + andq %rdx, %r9 + andq %rdx, %r10 + subq %r10, %r9 + cmova %r8, %rax + cmovc %rdx, %rax + cmovnz %rcx, %rdx + movq 72(%rdi), %r9 + movq 72(%rsi), %r10 + andq %rdx, %r9 + andq %rdx, %r10 + subq %r10, %r9 + cmova %r8, %rax + cmovc %rdx, %rax + cmovnz %rcx, %rdx + movq 64(%rdi), %r9 + movq 64(%rsi), %r10 + andq %rdx, %r9 + andq %rdx, %r10 + subq %r10, %r9 + cmova %r8, %rax + cmovc %rdx, %rax + cmovnz %rcx, %rdx + movq 56(%rdi), %r9 + movq 56(%rsi), %r10 + andq %rdx, %r9 + andq %rdx, %r10 + subq %r10, %r9 + cmova %r8, %rax + cmovc %rdx, %rax + cmovnz %rcx, %rdx + movq 48(%rdi), %r9 + movq 48(%rsi), %r10 + andq %rdx, %r9 + andq %rdx, %r10 + subq %r10, %r9 + cmova %r8, %rax + cmovc %rdx, %rax + cmovnz %rcx, %rdx + movq 40(%rdi), %r9 + movq 40(%rsi), %r10 + andq %rdx, %r9 + andq %rdx, %r10 + subq %r10, %r9 + cmova %r8, %rax + cmovc %rdx, %rax + cmovnz %rcx, %rdx + movq 32(%rdi), %r9 + movq 32(%rsi), %r10 + andq %rdx, %r9 + andq %rdx, %r10 + subq %r10, %r9 + cmova %r8, %rax + cmovc %rdx, %rax + cmovnz %rcx, %rdx + movq 24(%rdi), %r9 + movq 24(%rsi), %r10 + andq %rdx, %r9 + andq %rdx, %r10 + subq %r10, %r9 + cmova %r8, %rax + cmovc %rdx, %rax + cmovnz %rcx, %rdx + movq 16(%rdi), %r9 + movq 16(%rsi), %r10 + andq %rdx, %r9 + andq %rdx, %r10 + subq %r10, %r9 + cmova %r8, %rax + cmovc %rdx, %rax + cmovnz %rcx, %rdx + movq 8(%rdi), %r9 + movq 8(%rsi), %r10 + andq %rdx, %r9 + andq %rdx, %r10 + subq %r10, %r9 + cmova %r8, %rax + cmovc %rdx, %rax + cmovnz %rcx, %rdx + movq (%rdi), %r9 + movq (%rsi), %r10 + andq %rdx, %r9 + andq %rdx, %r10 + subq %r10, %r9 + cmova %r8, %rax + cmovc %rdx, %rax + cmovnz %rcx, %rdx + xorq %rdx, %rax + repz retq +#ifndef __APPLE__ +.size sp_1024_cmp_16,.-sp_1024_cmp_16 +#endif /* __APPLE__ */ +/* Conditionally copy a into r using the mask m. + * m is -1 to copy and 0 when not. + * + * r A single precision number to copy over. + * a A single precision number to copy. + * m Mask value to apply. + */ +#ifndef __APPLE__ +.text +.globl sp_1024_cond_copy_16 +.type sp_1024_cond_copy_16,@function +.align 16 +sp_1024_cond_copy_16: +#else +.section __TEXT,__text +.globl _sp_1024_cond_copy_16 +.p2align 4 +_sp_1024_cond_copy_16: +#endif /* __APPLE__ */ + movq (%rdi), %rax + movq 8(%rdi), %rcx + movq 16(%rdi), %r8 + movq 24(%rdi), %r9 + xorq (%rsi), %rax + xorq 8(%rsi), %rcx + xorq 16(%rsi), %r8 + xorq 24(%rsi), %r9 + andq %rdx, %rax + andq %rdx, %rcx + andq %rdx, %r8 + andq %rdx, %r9 + xorq %rax, (%rdi) + xorq %rcx, 8(%rdi) + xorq %r8, 16(%rdi) + xorq %r9, 24(%rdi) + movq 32(%rdi), %rax + movq 40(%rdi), %rcx + movq 48(%rdi), %r8 + movq 56(%rdi), %r9 + xorq 32(%rsi), %rax + xorq 40(%rsi), %rcx + xorq 48(%rsi), %r8 + xorq 56(%rsi), %r9 + andq %rdx, %rax + andq %rdx, %rcx + andq %rdx, %r8 + andq %rdx, %r9 + xorq %rax, 32(%rdi) + xorq %rcx, 40(%rdi) + xorq %r8, 48(%rdi) + xorq %r9, 56(%rdi) + movq 64(%rdi), %rax + movq 72(%rdi), %rcx + movq 80(%rdi), %r8 + movq 88(%rdi), %r9 + xorq 64(%rsi), %rax + xorq 72(%rsi), %rcx + xorq 80(%rsi), %r8 + xorq 88(%rsi), %r9 + andq %rdx, %rax + andq %rdx, %rcx + andq %rdx, %r8 + andq %rdx, %r9 + xorq %rax, 64(%rdi) + xorq %rcx, 72(%rdi) + xorq %r8, 80(%rdi) + xorq %r9, 88(%rdi) + movq 96(%rdi), %rax + movq 104(%rdi), %rcx + movq 112(%rdi), %r8 + movq 120(%rdi), %r9 + xorq 96(%rsi), %rax + xorq 104(%rsi), %rcx + xorq 112(%rsi), %r8 + xorq 120(%rsi), %r9 + andq %rdx, %rax + andq %rdx, %rcx + andq %rdx, %r8 + andq %rdx, %r9 + xorq %rax, 96(%rdi) + xorq %rcx, 104(%rdi) + xorq %r8, 112(%rdi) + xorq %r9, 120(%rdi) + repz retq +#ifndef __APPLE__ +.size sp_1024_cond_copy_16,.-sp_1024_cond_copy_16 +#endif /* __APPLE__ */ +/* Reduce the number back to 1024 bits using Montgomery reduction. + * + * a A single precision number to reduce in place. + * m The single precision number representing the modulus. + * mp The digit representing the negative inverse of m mod 2^n. + */ +#ifndef __APPLE__ +.text +.globl sp_1024_mont_reduce_16 +.type sp_1024_mont_reduce_16,@function +.align 16 +sp_1024_mont_reduce_16: +#else +.section __TEXT,__text +.globl _sp_1024_mont_reduce_16 +.p2align 4 +_sp_1024_mont_reduce_16: +#endif /* __APPLE__ */ + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + movq %rdx, %rcx + xorq %r15, %r15 + # i = 16 + movq $16, %r8 + movq (%rdi), %r13 + movq 8(%rdi), %r14 +L_1024_mont_loop_16: + # mu = a[i] * mp + movq %r13, %r11 + imulq %rcx, %r11 + # a[i+0] += m[0] * mu + movq %r11, %rax + xorq %r10, %r10 + mulq (%rsi) + addq %rax, %r13 + adcq %rdx, %r10 + # a[i+1] += m[1] * mu + movq %r11, %rax + xorq %r9, %r9 + mulq 8(%rsi) + movq %r14, %r13 + addq %rax, %r13 + adcq %rdx, %r9 + addq %r10, %r13 + adcq $0x00, %r9 + # a[i+2] += m[2] * mu + movq %r11, %rax + xorq %r10, %r10 + mulq 16(%rsi) + movq 16(%rdi), %r14 + addq %rax, %r14 + adcq %rdx, %r10 + addq %r9, %r14 + adcq $0x00, %r10 + # a[i+3] += m[3] * mu + movq %r11, %rax + xorq %r9, %r9 + mulq 24(%rsi) + movq 24(%rdi), %r12 + addq %rax, %r12 + adcq %rdx, %r9 + addq %r10, %r12 + movq %r12, 24(%rdi) + adcq $0x00, %r9 + # a[i+4] += m[4] * mu + movq %r11, %rax + xorq %r10, %r10 + mulq 32(%rsi) + movq 32(%rdi), %r12 + addq %rax, %r12 + adcq %rdx, %r10 + addq %r9, %r12 + movq %r12, 32(%rdi) + adcq $0x00, %r10 + # a[i+5] += m[5] * mu + movq %r11, %rax + xorq %r9, %r9 + mulq 40(%rsi) + movq 40(%rdi), %r12 + addq %rax, %r12 + adcq %rdx, %r9 + addq %r10, %r12 + movq %r12, 40(%rdi) + adcq $0x00, %r9 + # a[i+6] += m[6] * mu + movq %r11, %rax + xorq %r10, %r10 + mulq 48(%rsi) + movq 48(%rdi), %r12 + addq %rax, %r12 + adcq %rdx, %r10 + addq %r9, %r12 + movq %r12, 48(%rdi) + adcq $0x00, %r10 + # a[i+7] += m[7] * mu + movq %r11, %rax + xorq %r9, %r9 + mulq 56(%rsi) + movq 56(%rdi), %r12 + addq %rax, %r12 + adcq %rdx, %r9 + addq %r10, %r12 + movq %r12, 56(%rdi) + adcq $0x00, %r9 + # a[i+8] += m[8] * mu + movq %r11, %rax + xorq %r10, %r10 + mulq 64(%rsi) + movq 64(%rdi), %r12 + addq %rax, %r12 + adcq %rdx, %r10 + addq %r9, %r12 + movq %r12, 64(%rdi) + adcq $0x00, %r10 + # a[i+9] += m[9] * mu + movq %r11, %rax + xorq %r9, %r9 + mulq 72(%rsi) + movq 72(%rdi), %r12 + addq %rax, %r12 + adcq %rdx, %r9 + addq %r10, %r12 + movq %r12, 72(%rdi) + adcq $0x00, %r9 + # a[i+10] += m[10] * mu + movq %r11, %rax + xorq %r10, %r10 + mulq 80(%rsi) + movq 80(%rdi), %r12 + addq %rax, %r12 + adcq %rdx, %r10 + addq %r9, %r12 + movq %r12, 80(%rdi) + adcq $0x00, %r10 + # a[i+11] += m[11] * mu + movq %r11, %rax + xorq %r9, %r9 + mulq 88(%rsi) + movq 88(%rdi), %r12 + addq %rax, %r12 + adcq %rdx, %r9 + addq %r10, %r12 + movq %r12, 88(%rdi) + adcq $0x00, %r9 + # a[i+12] += m[12] * mu + movq %r11, %rax + xorq %r10, %r10 + mulq 96(%rsi) + movq 96(%rdi), %r12 + addq %rax, %r12 + adcq %rdx, %r10 + addq %r9, %r12 + movq %r12, 96(%rdi) + adcq $0x00, %r10 + # a[i+13] += m[13] * mu + movq %r11, %rax + xorq %r9, %r9 + mulq 104(%rsi) + movq 104(%rdi), %r12 + addq %rax, %r12 + adcq %rdx, %r9 + addq %r10, %r12 + movq %r12, 104(%rdi) + adcq $0x00, %r9 + # a[i+14] += m[14] * mu + movq %r11, %rax + xorq %r10, %r10 + mulq 112(%rsi) + movq 112(%rdi), %r12 + addq %rax, %r12 + adcq %rdx, %r10 + addq %r9, %r12 + movq %r12, 112(%rdi) + adcq $0x00, %r10 + # a[i+15] += m[15] * mu + movq %r11, %rax + mulq 120(%rsi) + movq 120(%rdi), %r12 + addq %rax, %r10 + adcq %r15, %rdx + movq $0x00, %r15 + adcq $0x00, %r15 + addq %r10, %r12 + movq %r12, 120(%rdi) + adcq %rdx, 128(%rdi) + adcq $0x00, %r15 + # i -= 1 + addq $8, %rdi + decq %r8 + jnz L_1024_mont_loop_16 + movq 120(%rdi), %r12 + movq %r13, (%rdi) + subq 120(%rsi), %r12 + movq %r14, 8(%rdi) + sbbq %r12, %r12 + negq %r15 + notq %r12 + orq %r12, %r15 +#ifdef _WIN64 + movq %rsi, %rdx + movq %r15, %rcx +#else + movq %r15, %rcx + movq %rsi, %rdx +#endif /* _WIN64 */ + movq %rdi, %rsi + movq %rdi, %rdi + subq $0x80, %rdi +#ifndef __APPLE__ + callq sp_1024_cond_sub_16@plt +#else + callq _sp_1024_cond_sub_16 +#endif /* __APPLE__ */ + popq %r15 + popq %r14 + popq %r13 + popq %r12 + repz retq +#ifndef __APPLE__ +.size sp_1024_mont_reduce_16,.-sp_1024_mont_reduce_16 +#endif /* __APPLE__ */ +/* Add two Montgomery form numbers (r = a + b % m). + * + * r Result of addition. + * a First number to add in Montogmery form. + * b Second number to add in Montogmery form. + * m Modulus (prime). + */ +#ifndef __APPLE__ +.text +.globl sp_1024_mont_add_16 +.type sp_1024_mont_add_16,@function +.align 16 +sp_1024_mont_add_16: +#else +.section __TEXT,__text +.globl _sp_1024_mont_add_16 +.p2align 4 +_sp_1024_mont_add_16: +#endif /* __APPLE__ */ + subq $0x80, %rsp + movq (%rsi), %rax + movq 8(%rsi), %r8 + movq 16(%rsi), %r9 + movq 24(%rsi), %r10 + addq (%rdx), %rax + movq $0x00, %r11 + adcq 8(%rdx), %r8 + adcq 16(%rdx), %r9 + adcq 24(%rdx), %r10 + movq %rax, (%rdi) + movq %r8, 8(%rdi) + movq %r9, 16(%rdi) + movq %r10, 24(%rdi) + movq 32(%rsi), %rax + movq 40(%rsi), %r8 + movq 48(%rsi), %r9 + movq 56(%rsi), %r10 + adcq 32(%rdx), %rax + adcq 40(%rdx), %r8 + adcq 48(%rdx), %r9 + adcq 56(%rdx), %r10 + movq %rax, 32(%rdi) + movq %r8, 40(%rdi) + movq %r9, 48(%rdi) + movq %r10, 56(%rdi) + movq 64(%rsi), %rax + movq 72(%rsi), %r8 + movq 80(%rsi), %r9 + movq 88(%rsi), %r10 + adcq 64(%rdx), %rax + adcq 72(%rdx), %r8 + adcq 80(%rdx), %r9 + adcq 88(%rdx), %r10 + movq %rax, 64(%rdi) + movq %r8, 72(%rdi) + movq %r9, 80(%rdi) + movq %r10, 88(%rdi) + movq 96(%rsi), %rax + movq 104(%rsi), %r8 + movq 112(%rsi), %r9 + movq 120(%rsi), %r10 + adcq 96(%rdx), %rax + adcq 104(%rdx), %r8 + adcq 112(%rdx), %r9 + adcq 120(%rdx), %r10 + movq %rax, 96(%rdi) + movq %r8, 104(%rdi) + movq %r9, 112(%rdi) + movq %r10, 120(%rdi) + sbbq $0x00, %r11 + subq 120(%rcx), %r10 + sbbq %r10, %r10 + notq %r10 + orq %r10, %r11 + movq (%rcx), %r9 + movq 8(%rcx), %r10 + andq %r11, %r9 + andq %r11, %r10 + movq %r9, (%rsp) + movq %r10, 8(%rsp) + movq 16(%rcx), %r9 + movq 24(%rcx), %r10 + andq %r11, %r9 + andq %r11, %r10 + movq %r9, 16(%rsp) + movq %r10, 24(%rsp) + movq 32(%rcx), %r9 + movq 40(%rcx), %r10 + andq %r11, %r9 + andq %r11, %r10 + movq %r9, 32(%rsp) + movq %r10, 40(%rsp) + movq 48(%rcx), %r9 + movq 56(%rcx), %r10 + andq %r11, %r9 + andq %r11, %r10 + movq %r9, 48(%rsp) + movq %r10, 56(%rsp) + movq 64(%rcx), %r9 + movq 72(%rcx), %r10 + andq %r11, %r9 + andq %r11, %r10 + movq %r9, 64(%rsp) + movq %r10, 72(%rsp) + movq 80(%rcx), %r9 + movq 88(%rcx), %r10 + andq %r11, %r9 + andq %r11, %r10 + movq %r9, 80(%rsp) + movq %r10, 88(%rsp) + movq 96(%rcx), %r9 + movq 104(%rcx), %r10 + andq %r11, %r9 + andq %r11, %r10 + movq %r9, 96(%rsp) + movq %r10, 104(%rsp) + movq 112(%rcx), %r9 + movq 120(%rcx), %r10 + andq %r11, %r9 + andq %r11, %r10 + movq %r9, 112(%rsp) + movq %r10, 120(%rsp) + movq (%rdi), %rax + movq 8(%rdi), %r8 + subq (%rsp), %rax + sbbq 8(%rsp), %r8 + movq %rax, (%rdi) + movq %r8, 8(%rdi) + movq 16(%rdi), %rax + movq 24(%rdi), %r8 + sbbq 16(%rsp), %rax + sbbq 24(%rsp), %r8 + movq %rax, 16(%rdi) + movq %r8, 24(%rdi) + movq 32(%rdi), %rax + movq 40(%rdi), %r8 + sbbq 32(%rsp), %rax + sbbq 40(%rsp), %r8 + movq %rax, 32(%rdi) + movq %r8, 40(%rdi) + movq 48(%rdi), %rax + movq 56(%rdi), %r8 + sbbq 48(%rsp), %rax + sbbq 56(%rsp), %r8 + movq %rax, 48(%rdi) + movq %r8, 56(%rdi) + movq 64(%rdi), %rax + movq 72(%rdi), %r8 + sbbq 64(%rsp), %rax + sbbq 72(%rsp), %r8 + movq %rax, 64(%rdi) + movq %r8, 72(%rdi) + movq 80(%rdi), %rax + movq 88(%rdi), %r8 + sbbq 80(%rsp), %rax + sbbq 88(%rsp), %r8 + movq %rax, 80(%rdi) + movq %r8, 88(%rdi) + movq 96(%rdi), %rax + movq 104(%rdi), %r8 + sbbq 96(%rsp), %rax + sbbq 104(%rsp), %r8 + movq %rax, 96(%rdi) + movq %r8, 104(%rdi) + movq 112(%rdi), %rax + movq 120(%rdi), %r8 + sbbq 112(%rsp), %rax + sbbq 120(%rsp), %r8 + movq %rax, 112(%rdi) + movq %r8, 120(%rdi) + addq $0x80, %rsp + repz retq +#ifndef __APPLE__ +.size sp_1024_mont_add_16,.-sp_1024_mont_add_16 +#endif /* __APPLE__ */ +/* Double a Montgomery form number (r = a + a % m). + * + * r Result of addition. + * a Number to souble in Montogmery form. + * m Modulus (prime). + */ +#ifndef __APPLE__ +.text +.globl sp_1024_mont_dbl_16 +.type sp_1024_mont_dbl_16,@function +.align 16 +sp_1024_mont_dbl_16: +#else +.section __TEXT,__text +.globl _sp_1024_mont_dbl_16 +.p2align 4 +_sp_1024_mont_dbl_16: +#endif /* __APPLE__ */ + subq $0x80, %rsp + movq (%rsi), %rax + movq 8(%rsi), %rcx + movq 16(%rsi), %r8 + movq 24(%rsi), %r9 + addq (%rsi), %rax + movq $0x00, %r10 + adcq 8(%rsi), %rcx + adcq 16(%rsi), %r8 + adcq 24(%rsi), %r9 + movq %rax, (%rdi) + movq %rcx, 8(%rdi) + movq %r8, 16(%rdi) + movq %r9, 24(%rdi) + movq 32(%rsi), %rax + movq 40(%rsi), %rcx + movq 48(%rsi), %r8 + movq 56(%rsi), %r9 + adcq 32(%rsi), %rax + adcq 40(%rsi), %rcx + adcq 48(%rsi), %r8 + adcq 56(%rsi), %r9 + movq %rax, 32(%rdi) + movq %rcx, 40(%rdi) + movq %r8, 48(%rdi) + movq %r9, 56(%rdi) + movq 64(%rsi), %rax + movq 72(%rsi), %rcx + movq 80(%rsi), %r8 + movq 88(%rsi), %r9 + adcq 64(%rsi), %rax + adcq 72(%rsi), %rcx + adcq 80(%rsi), %r8 + adcq 88(%rsi), %r9 + movq %rax, 64(%rdi) + movq %rcx, 72(%rdi) + movq %r8, 80(%rdi) + movq %r9, 88(%rdi) + movq 96(%rsi), %rax + movq 104(%rsi), %rcx + movq 112(%rsi), %r8 + movq 120(%rsi), %r9 + adcq 96(%rsi), %rax + adcq 104(%rsi), %rcx + adcq 112(%rsi), %r8 + adcq 120(%rsi), %r9 + movq %rax, 96(%rdi) + movq %rcx, 104(%rdi) + movq %r8, 112(%rdi) + movq %r9, 120(%rdi) + sbbq $0x00, %r10 + subq 120(%rdx), %r9 + sbbq %r9, %r9 + notq %r9 + orq %r9, %r10 + movq (%rdx), %r8 + movq 8(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, (%rsp) + movq %r9, 8(%rsp) + movq 16(%rdx), %r8 + movq 24(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, 16(%rsp) + movq %r9, 24(%rsp) + movq 32(%rdx), %r8 + movq 40(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, 32(%rsp) + movq %r9, 40(%rsp) + movq 48(%rdx), %r8 + movq 56(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, 48(%rsp) + movq %r9, 56(%rsp) + movq 64(%rdx), %r8 + movq 72(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, 64(%rsp) + movq %r9, 72(%rsp) + movq 80(%rdx), %r8 + movq 88(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, 80(%rsp) + movq %r9, 88(%rsp) + movq 96(%rdx), %r8 + movq 104(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, 96(%rsp) + movq %r9, 104(%rsp) + movq 112(%rdx), %r8 + movq 120(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, 112(%rsp) + movq %r9, 120(%rsp) + movq (%rdi), %rax + movq 8(%rdi), %rcx + subq (%rsp), %rax + sbbq 8(%rsp), %rcx + movq %rax, (%rdi) + movq %rcx, 8(%rdi) + movq 16(%rdi), %rax + movq 24(%rdi), %rcx + sbbq 16(%rsp), %rax + sbbq 24(%rsp), %rcx + movq %rax, 16(%rdi) + movq %rcx, 24(%rdi) + movq 32(%rdi), %rax + movq 40(%rdi), %rcx + sbbq 32(%rsp), %rax + sbbq 40(%rsp), %rcx + movq %rax, 32(%rdi) + movq %rcx, 40(%rdi) + movq 48(%rdi), %rax + movq 56(%rdi), %rcx + sbbq 48(%rsp), %rax + sbbq 56(%rsp), %rcx + movq %rax, 48(%rdi) + movq %rcx, 56(%rdi) + movq 64(%rdi), %rax + movq 72(%rdi), %rcx + sbbq 64(%rsp), %rax + sbbq 72(%rsp), %rcx + movq %rax, 64(%rdi) + movq %rcx, 72(%rdi) + movq 80(%rdi), %rax + movq 88(%rdi), %rcx + sbbq 80(%rsp), %rax + sbbq 88(%rsp), %rcx + movq %rax, 80(%rdi) + movq %rcx, 88(%rdi) + movq 96(%rdi), %rax + movq 104(%rdi), %rcx + sbbq 96(%rsp), %rax + sbbq 104(%rsp), %rcx + movq %rax, 96(%rdi) + movq %rcx, 104(%rdi) + movq 112(%rdi), %rax + movq 120(%rdi), %rcx + sbbq 112(%rsp), %rax + sbbq 120(%rsp), %rcx + movq %rax, 112(%rdi) + movq %rcx, 120(%rdi) + addq $0x80, %rsp + repz retq +#ifndef __APPLE__ +.size sp_1024_mont_dbl_16,.-sp_1024_mont_dbl_16 +#endif /* __APPLE__ */ +/* Triple a Montgomery form number (r = a + a + a % m). + * + * r Result of addition. + * a Number to souble in Montogmery form. + * m Modulus (prime). + */ +#ifndef __APPLE__ +.text +.globl sp_1024_mont_tpl_16 +.type sp_1024_mont_tpl_16,@function +.align 16 +sp_1024_mont_tpl_16: +#else +.section __TEXT,__text +.globl _sp_1024_mont_tpl_16 +.p2align 4 +_sp_1024_mont_tpl_16: +#endif /* __APPLE__ */ + subq $0x80, %rsp + movq (%rsi), %rax + movq 8(%rsi), %rcx + movq 16(%rsi), %r8 + movq 24(%rsi), %r9 + addq (%rsi), %rax + movq $0x00, %r10 + adcq 8(%rsi), %rcx + adcq 16(%rsi), %r8 + adcq 24(%rsi), %r9 + movq %rax, (%rdi) + movq %rcx, 8(%rdi) + movq %r8, 16(%rdi) + movq %r9, 24(%rdi) + movq 32(%rsi), %rax + movq 40(%rsi), %rcx + movq 48(%rsi), %r8 + movq 56(%rsi), %r9 + adcq 32(%rsi), %rax + adcq 40(%rsi), %rcx + adcq 48(%rsi), %r8 + adcq 56(%rsi), %r9 + movq %rax, 32(%rdi) + movq %rcx, 40(%rdi) + movq %r8, 48(%rdi) + movq %r9, 56(%rdi) + movq 64(%rsi), %rax + movq 72(%rsi), %rcx + movq 80(%rsi), %r8 + movq 88(%rsi), %r9 + adcq 64(%rsi), %rax + adcq 72(%rsi), %rcx + adcq 80(%rsi), %r8 + adcq 88(%rsi), %r9 + movq %rax, 64(%rdi) + movq %rcx, 72(%rdi) + movq %r8, 80(%rdi) + movq %r9, 88(%rdi) + movq 96(%rsi), %rax + movq 104(%rsi), %rcx + movq 112(%rsi), %r8 + movq 120(%rsi), %r9 + adcq 96(%rsi), %rax + adcq 104(%rsi), %rcx + adcq 112(%rsi), %r8 + adcq 120(%rsi), %r9 + movq %rax, 96(%rdi) + movq %rcx, 104(%rdi) + movq %r8, 112(%rdi) + movq %r9, 120(%rdi) + sbbq $0x00, %r10 + subq 120(%rdx), %r9 + sbbq %r9, %r9 + notq %r9 + orq %r9, %r10 + movq (%rdx), %r8 + movq 8(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, (%rsp) + movq %r9, 8(%rsp) + movq 16(%rdx), %r8 + movq 24(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, 16(%rsp) + movq %r9, 24(%rsp) + movq 32(%rdx), %r8 + movq 40(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, 32(%rsp) + movq %r9, 40(%rsp) + movq 48(%rdx), %r8 + movq 56(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, 48(%rsp) + movq %r9, 56(%rsp) + movq 64(%rdx), %r8 + movq 72(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, 64(%rsp) + movq %r9, 72(%rsp) + movq 80(%rdx), %r8 + movq 88(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, 80(%rsp) + movq %r9, 88(%rsp) + movq 96(%rdx), %r8 + movq 104(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, 96(%rsp) + movq %r9, 104(%rsp) + movq 112(%rdx), %r8 + movq 120(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, 112(%rsp) + movq %r9, 120(%rsp) + movq (%rdi), %rax + movq 8(%rdi), %rcx + subq (%rsp), %rax + sbbq 8(%rsp), %rcx + movq %rax, (%rdi) + movq %rcx, 8(%rdi) + movq 16(%rdi), %rax + movq 24(%rdi), %rcx + sbbq 16(%rsp), %rax + sbbq 24(%rsp), %rcx + movq %rax, 16(%rdi) + movq %rcx, 24(%rdi) + movq 32(%rdi), %rax + movq 40(%rdi), %rcx + sbbq 32(%rsp), %rax + sbbq 40(%rsp), %rcx + movq %rax, 32(%rdi) + movq %rcx, 40(%rdi) + movq 48(%rdi), %rax + movq 56(%rdi), %rcx + sbbq 48(%rsp), %rax + sbbq 56(%rsp), %rcx + movq %rax, 48(%rdi) + movq %rcx, 56(%rdi) + movq 64(%rdi), %rax + movq 72(%rdi), %rcx + sbbq 64(%rsp), %rax + sbbq 72(%rsp), %rcx + movq %rax, 64(%rdi) + movq %rcx, 72(%rdi) + movq 80(%rdi), %rax + movq 88(%rdi), %rcx + sbbq 80(%rsp), %rax + sbbq 88(%rsp), %rcx + movq %rax, 80(%rdi) + movq %rcx, 88(%rdi) + movq 96(%rdi), %rax + movq 104(%rdi), %rcx + sbbq 96(%rsp), %rax + sbbq 104(%rsp), %rcx + movq %rax, 96(%rdi) + movq %rcx, 104(%rdi) + movq 112(%rdi), %rax + movq 120(%rdi), %rcx + sbbq 112(%rsp), %rax + sbbq 120(%rsp), %rcx + movq %rax, 112(%rdi) + movq %rcx, 120(%rdi) + movq (%rdi), %rax + movq 8(%rdi), %rcx + movq 16(%rdi), %r8 + movq 24(%rdi), %r9 + addq (%rsi), %rax + movq $0x00, %r10 + adcq 8(%rsi), %rcx + adcq 16(%rsi), %r8 + adcq 24(%rsi), %r9 + movq %rax, (%rdi) + movq %rcx, 8(%rdi) + movq %r8, 16(%rdi) + movq %r9, 24(%rdi) + movq 32(%rdi), %rax + movq 40(%rdi), %rcx + movq 48(%rdi), %r8 + movq 56(%rdi), %r9 + adcq 32(%rsi), %rax + adcq 40(%rsi), %rcx + adcq 48(%rsi), %r8 + adcq 56(%rsi), %r9 + movq %rax, 32(%rdi) + movq %rcx, 40(%rdi) + movq %r8, 48(%rdi) + movq %r9, 56(%rdi) + movq 64(%rdi), %rax + movq 72(%rdi), %rcx + movq 80(%rdi), %r8 + movq 88(%rdi), %r9 + adcq 64(%rsi), %rax + adcq 72(%rsi), %rcx + adcq 80(%rsi), %r8 + adcq 88(%rsi), %r9 + movq %rax, 64(%rdi) + movq %rcx, 72(%rdi) + movq %r8, 80(%rdi) + movq %r9, 88(%rdi) + movq 96(%rdi), %rax + movq 104(%rdi), %rcx + movq 112(%rdi), %r8 + movq 120(%rdi), %r9 + adcq 96(%rsi), %rax + adcq 104(%rsi), %rcx + adcq 112(%rsi), %r8 + adcq 120(%rsi), %r9 + movq %rax, 96(%rdi) + movq %rcx, 104(%rdi) + movq %r8, 112(%rdi) + movq %r9, 120(%rdi) + sbbq $0x00, %r10 + subq 120(%rdx), %r9 + sbbq %r9, %r9 + notq %r9 + orq %r9, %r10 + movq (%rdx), %r8 + movq 8(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, (%rsp) + movq %r9, 8(%rsp) + movq 16(%rdx), %r8 + movq 24(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, 16(%rsp) + movq %r9, 24(%rsp) + movq 32(%rdx), %r8 + movq 40(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, 32(%rsp) + movq %r9, 40(%rsp) + movq 48(%rdx), %r8 + movq 56(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, 48(%rsp) + movq %r9, 56(%rsp) + movq 64(%rdx), %r8 + movq 72(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, 64(%rsp) + movq %r9, 72(%rsp) + movq 80(%rdx), %r8 + movq 88(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, 80(%rsp) + movq %r9, 88(%rsp) + movq 96(%rdx), %r8 + movq 104(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, 96(%rsp) + movq %r9, 104(%rsp) + movq 112(%rdx), %r8 + movq 120(%rdx), %r9 + andq %r10, %r8 + andq %r10, %r9 + movq %r8, 112(%rsp) + movq %r9, 120(%rsp) + movq (%rdi), %rax + movq 8(%rdi), %rcx + subq (%rsp), %rax + sbbq 8(%rsp), %rcx + movq %rax, (%rdi) + movq %rcx, 8(%rdi) + movq 16(%rdi), %rax + movq 24(%rdi), %rcx + sbbq 16(%rsp), %rax + sbbq 24(%rsp), %rcx + movq %rax, 16(%rdi) + movq %rcx, 24(%rdi) + movq 32(%rdi), %rax + movq 40(%rdi), %rcx + sbbq 32(%rsp), %rax + sbbq 40(%rsp), %rcx + movq %rax, 32(%rdi) + movq %rcx, 40(%rdi) + movq 48(%rdi), %rax + movq 56(%rdi), %rcx + sbbq 48(%rsp), %rax + sbbq 56(%rsp), %rcx + movq %rax, 48(%rdi) + movq %rcx, 56(%rdi) + movq 64(%rdi), %rax + movq 72(%rdi), %rcx + sbbq 64(%rsp), %rax + sbbq 72(%rsp), %rcx + movq %rax, 64(%rdi) + movq %rcx, 72(%rdi) + movq 80(%rdi), %rax + movq 88(%rdi), %rcx + sbbq 80(%rsp), %rax + sbbq 88(%rsp), %rcx + movq %rax, 80(%rdi) + movq %rcx, 88(%rdi) + movq 96(%rdi), %rax + movq 104(%rdi), %rcx + sbbq 96(%rsp), %rax + sbbq 104(%rsp), %rcx + movq %rax, 96(%rdi) + movq %rcx, 104(%rdi) + movq 112(%rdi), %rax + movq 120(%rdi), %rcx + sbbq 112(%rsp), %rax + sbbq 120(%rsp), %rcx + movq %rax, 112(%rdi) + movq %rcx, 120(%rdi) + addq $0x80, %rsp + repz retq +#ifndef __APPLE__ +.size sp_1024_mont_tpl_16,.-sp_1024_mont_tpl_16 +#endif /* __APPLE__ */ +/* Subtract two Montgomery form numbers (r = a - b % m). + * + * r Result of addition. + * a First number to add in Montogmery form. + * b Second number to add in Montogmery form. + * m Modulus (prime). + */ +#ifndef __APPLE__ +.text +.globl sp_1024_mont_sub_16 +.type sp_1024_mont_sub_16,@function +.align 16 +sp_1024_mont_sub_16: +#else +.section __TEXT,__text +.globl _sp_1024_mont_sub_16 +.p2align 4 +_sp_1024_mont_sub_16: +#endif /* __APPLE__ */ + subq $0x80, %rsp + movq (%rsi), %rax + movq 8(%rsi), %r8 + movq 16(%rsi), %r9 + movq 24(%rsi), %r10 + subq (%rdx), %rax + movq $0x00, %r11 + sbbq 8(%rdx), %r8 + sbbq 16(%rdx), %r9 + sbbq 24(%rdx), %r10 + movq %rax, (%rdi) + movq %r8, 8(%rdi) + movq %r9, 16(%rdi) + movq %r10, 24(%rdi) + movq 32(%rsi), %rax + movq 40(%rsi), %r8 + movq 48(%rsi), %r9 + movq 56(%rsi), %r10 + sbbq 32(%rdx), %rax + sbbq 40(%rdx), %r8 + sbbq 48(%rdx), %r9 + sbbq 56(%rdx), %r10 + movq %rax, 32(%rdi) + movq %r8, 40(%rdi) + movq %r9, 48(%rdi) + movq %r10, 56(%rdi) + movq 64(%rsi), %rax + movq 72(%rsi), %r8 + movq 80(%rsi), %r9 + movq 88(%rsi), %r10 + sbbq 64(%rdx), %rax + sbbq 72(%rdx), %r8 + sbbq 80(%rdx), %r9 + sbbq 88(%rdx), %r10 + movq %rax, 64(%rdi) + movq %r8, 72(%rdi) + movq %r9, 80(%rdi) + movq %r10, 88(%rdi) + movq 96(%rsi), %rax + movq 104(%rsi), %r8 + movq 112(%rsi), %r9 + movq 120(%rsi), %r10 + sbbq 96(%rdx), %rax + sbbq 104(%rdx), %r8 + sbbq 112(%rdx), %r9 + sbbq 120(%rdx), %r10 + movq %rax, 96(%rdi) + movq %r8, 104(%rdi) + movq %r9, 112(%rdi) + movq %r10, 120(%rdi) + sbbq $0x00, %r11 + movq (%rcx), %r9 + movq 8(%rcx), %r10 + andq %r11, %r9 + andq %r11, %r10 + movq %r9, (%rsp) + movq %r10, 8(%rsp) + movq 16(%rcx), %r9 + movq 24(%rcx), %r10 + andq %r11, %r9 + andq %r11, %r10 + movq %r9, 16(%rsp) + movq %r10, 24(%rsp) + movq 32(%rcx), %r9 + movq 40(%rcx), %r10 + andq %r11, %r9 + andq %r11, %r10 + movq %r9, 32(%rsp) + movq %r10, 40(%rsp) + movq 48(%rcx), %r9 + movq 56(%rcx), %r10 + andq %r11, %r9 + andq %r11, %r10 + movq %r9, 48(%rsp) + movq %r10, 56(%rsp) + movq 64(%rcx), %r9 + movq 72(%rcx), %r10 + andq %r11, %r9 + andq %r11, %r10 + movq %r9, 64(%rsp) + movq %r10, 72(%rsp) + movq 80(%rcx), %r9 + movq 88(%rcx), %r10 + andq %r11, %r9 + andq %r11, %r10 + movq %r9, 80(%rsp) + movq %r10, 88(%rsp) + movq 96(%rcx), %r9 + movq 104(%rcx), %r10 + andq %r11, %r9 + andq %r11, %r10 + movq %r9, 96(%rsp) + movq %r10, 104(%rsp) + movq 112(%rcx), %r9 + movq 120(%rcx), %r10 + andq %r11, %r9 + andq %r11, %r10 + movq %r9, 112(%rsp) + movq %r10, 120(%rsp) + movq (%rdi), %rax + movq 8(%rdi), %r8 + addq (%rsp), %rax + adcq 8(%rsp), %r8 + movq %rax, (%rdi) + movq %r8, 8(%rdi) + movq 16(%rdi), %rax + movq 24(%rdi), %r8 + adcq 16(%rsp), %rax + adcq 24(%rsp), %r8 + movq %rax, 16(%rdi) + movq %r8, 24(%rdi) + movq 32(%rdi), %rax + movq 40(%rdi), %r8 + adcq 32(%rsp), %rax + adcq 40(%rsp), %r8 + movq %rax, 32(%rdi) + movq %r8, 40(%rdi) + movq 48(%rdi), %rax + movq 56(%rdi), %r8 + adcq 48(%rsp), %rax + adcq 56(%rsp), %r8 + movq %rax, 48(%rdi) + movq %r8, 56(%rdi) + movq 64(%rdi), %rax + movq 72(%rdi), %r8 + adcq 64(%rsp), %rax + adcq 72(%rsp), %r8 + movq %rax, 64(%rdi) + movq %r8, 72(%rdi) + movq 80(%rdi), %rax + movq 88(%rdi), %r8 + adcq 80(%rsp), %rax + adcq 88(%rsp), %r8 + movq %rax, 80(%rdi) + movq %r8, 88(%rdi) + movq 96(%rdi), %rax + movq 104(%rdi), %r8 + adcq 96(%rsp), %rax + adcq 104(%rsp), %r8 + movq %rax, 96(%rdi) + movq %r8, 104(%rdi) + movq 112(%rdi), %rax + movq 120(%rdi), %r8 + adcq 112(%rsp), %rax + adcq 120(%rsp), %r8 + movq %rax, 112(%rdi) + movq %r8, 120(%rdi) + addq $0x80, %rsp + repz retq +#ifndef __APPLE__ +.size sp_1024_mont_sub_16,.-sp_1024_mont_sub_16 +#endif /* __APPLE__ */ +/* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m) + * + * r Result of division by 2. + * a Number to divide. + * m Modulus (prime). + */ +#ifndef __APPLE__ +.text +.globl sp_1024_div2_16 +.type sp_1024_div2_16,@function +.align 16 +sp_1024_div2_16: +#else +.section __TEXT,__text +.globl _sp_1024_div2_16 +.p2align 4 +_sp_1024_div2_16: +#endif /* __APPLE__ */ + subq $0x80, %rsp + movq (%rsi), %r11 + xorq %r10, %r10 + movq %r11, %rax + andq $0x01, %r11 + negq %r11 + movq (%rdx), %r8 + andq %r11, %r8 + movq %r8, (%rsp) + movq 8(%rdx), %r8 + andq %r11, %r8 + movq %r8, 8(%rsp) + movq 16(%rdx), %r8 + andq %r11, %r8 + movq %r8, 16(%rsp) + movq 24(%rdx), %r8 + andq %r11, %r8 + movq %r8, 24(%rsp) + movq 32(%rdx), %r8 + andq %r11, %r8 + movq %r8, 32(%rsp) + movq 40(%rdx), %r8 + andq %r11, %r8 + movq %r8, 40(%rsp) + movq 48(%rdx), %r8 + andq %r11, %r8 + movq %r8, 48(%rsp) + movq 56(%rdx), %r8 + andq %r11, %r8 + movq %r8, 56(%rsp) + movq 64(%rdx), %r8 + andq %r11, %r8 + movq %r8, 64(%rsp) + movq 72(%rdx), %r8 + andq %r11, %r8 + movq %r8, 72(%rsp) + movq 80(%rdx), %r8 + andq %r11, %r8 + movq %r8, 80(%rsp) + movq 88(%rdx), %r8 + andq %r11, %r8 + movq %r8, 88(%rsp) + movq 96(%rdx), %r8 + andq %r11, %r8 + movq %r8, 96(%rsp) + movq 104(%rdx), %r8 + andq %r11, %r8 + movq %r8, 104(%rsp) + movq 112(%rdx), %r8 + andq %r11, %r8 + movq %r8, 112(%rsp) + movq 120(%rdx), %r8 + andq %r11, %r8 + movq %r8, 120(%rsp) + addq %rax, (%rsp) + movq 8(%rsi), %rax + adcq %rax, 8(%rsp) + movq 16(%rsi), %rax + adcq %rax, 16(%rsp) + movq 24(%rsi), %rax + adcq %rax, 24(%rsp) + movq 32(%rsi), %rax + adcq %rax, 32(%rsp) + movq 40(%rsi), %rax + adcq %rax, 40(%rsp) + movq 48(%rsi), %rax + adcq %rax, 48(%rsp) + movq 56(%rsi), %rax + adcq %rax, 56(%rsp) + movq 64(%rsi), %rax + adcq %rax, 64(%rsp) + movq 72(%rsi), %rax + adcq %rax, 72(%rsp) + movq 80(%rsi), %rax + adcq %rax, 80(%rsp) + movq 88(%rsi), %rax + adcq %rax, 88(%rsp) + movq 96(%rsi), %rax + adcq %rax, 96(%rsp) + movq 104(%rsi), %rax + adcq %rax, 104(%rsp) + movq 112(%rsi), %rax + adcq %rax, 112(%rsp) + movq 120(%rsi), %rax + adcq %rax, 120(%rsp) + adcq $0x00, %r10 + movq (%rsp), %rax + movq 8(%rsp), %rcx + shrdq $0x01, %rcx, %rax + movq %rax, (%rdi) + movq 16(%rsp), %rax + shrdq $0x01, %rax, %rcx + movq %rcx, 8(%rdi) + movq 24(%rsp), %rcx + shrdq $0x01, %rcx, %rax + movq %rax, 16(%rdi) + movq 32(%rsp), %rax + shrdq $0x01, %rax, %rcx + movq %rcx, 24(%rdi) + movq 40(%rsp), %rcx + shrdq $0x01, %rcx, %rax + movq %rax, 32(%rdi) + movq 48(%rsp), %rax + shrdq $0x01, %rax, %rcx + movq %rcx, 40(%rdi) + movq 56(%rsp), %rcx + shrdq $0x01, %rcx, %rax + movq %rax, 48(%rdi) + movq 64(%rsp), %rax + shrdq $0x01, %rax, %rcx + movq %rcx, 56(%rdi) + movq 72(%rsp), %rcx + shrdq $0x01, %rcx, %rax + movq %rax, 64(%rdi) + movq 80(%rsp), %rax + shrdq $0x01, %rax, %rcx + movq %rcx, 72(%rdi) + movq 88(%rsp), %rcx + shrdq $0x01, %rcx, %rax + movq %rax, 80(%rdi) + movq 96(%rsp), %rax + shrdq $0x01, %rax, %rcx + movq %rcx, 88(%rdi) + movq 104(%rsp), %rcx + shrdq $0x01, %rcx, %rax + movq %rax, 96(%rdi) + movq 112(%rsp), %rax + shrdq $0x01, %rax, %rcx + movq %rcx, 104(%rdi) + movq 120(%rsp), %rcx + shrdq $0x01, %rcx, %rax + movq %rax, 112(%rdi) + shrdq $0x01, %r10, %rcx + movq %rcx, 120(%rdi) + addq $0x80, %rsp + repz retq +#ifndef __APPLE__ +.size sp_1024_div2_16,.-sp_1024_div2_16 +#endif /* __APPLE__ */ +/* Sub b from a into r. (r = a - b) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +#ifndef __APPLE__ +.text +.globl sp_1024_sub_16 +.type sp_1024_sub_16,@function +.align 16 +sp_1024_sub_16: +#else +.section __TEXT,__text +.globl _sp_1024_sub_16 +.p2align 4 +_sp_1024_sub_16: +#endif /* __APPLE__ */ + movq (%rsi), %rcx + xorq %rax, %rax + subq (%rdx), %rcx + movq 8(%rsi), %r8 + movq %rcx, (%rdi) + sbbq 8(%rdx), %r8 + movq 16(%rsi), %rcx + movq %r8, 8(%rdi) + sbbq 16(%rdx), %rcx + movq 24(%rsi), %r8 + movq %rcx, 16(%rdi) + sbbq 24(%rdx), %r8 + movq 32(%rsi), %rcx + movq %r8, 24(%rdi) + sbbq 32(%rdx), %rcx + movq 40(%rsi), %r8 + movq %rcx, 32(%rdi) + sbbq 40(%rdx), %r8 + movq 48(%rsi), %rcx + movq %r8, 40(%rdi) + sbbq 48(%rdx), %rcx + movq 56(%rsi), %r8 + movq %rcx, 48(%rdi) + sbbq 56(%rdx), %r8 + movq 64(%rsi), %rcx + movq %r8, 56(%rdi) + sbbq 64(%rdx), %rcx + movq 72(%rsi), %r8 + movq %rcx, 64(%rdi) + sbbq 72(%rdx), %r8 + movq 80(%rsi), %rcx + movq %r8, 72(%rdi) + sbbq 80(%rdx), %rcx + movq 88(%rsi), %r8 + movq %rcx, 80(%rdi) + sbbq 88(%rdx), %r8 + movq 96(%rsi), %rcx + movq %r8, 88(%rdi) + sbbq 96(%rdx), %rcx + movq 104(%rsi), %r8 + movq %rcx, 96(%rdi) + sbbq 104(%rdx), %r8 + movq 112(%rsi), %rcx + movq %r8, 104(%rdi) + sbbq 112(%rdx), %rcx + movq 120(%rsi), %r8 + movq %rcx, 112(%rdi) + sbbq 120(%rdx), %r8 + movq %r8, 120(%rdi) + sbbq $0x00, %rax + repz retq +#ifndef __APPLE__ +.size sp_1024_sub_16,.-sp_1024_sub_16 +#endif /* __APPLE__ */ +#ifdef HAVE_INTEL_AVX2 +/* Reduce the number back to 1024 bits using Montgomery reduction. + * + * a A single precision number to reduce in place. + * m The single precision number representing the modulus. + * mp The digit representing the negative inverse of m mod 2^n. + */ +#ifndef __APPLE__ +.text +.globl sp_1024_mont_reduce_avx2_16 +.type sp_1024_mont_reduce_avx2_16,@function +.align 16 +sp_1024_mont_reduce_avx2_16: +#else +.section __TEXT,__text +.globl _sp_1024_mont_reduce_avx2_16 +.p2align 4 +_sp_1024_mont_reduce_avx2_16: +#endif /* __APPLE__ */ + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + pushq %rbx + pushq %rbp + movq %rdx, %r8 + xorq %rbp, %rbp + # i = 16 + movq $16, %r9 + movq (%rdi), %r13 + movq 8(%rdi), %r14 + movq 16(%rdi), %r15 + movq 24(%rdi), %rbx + addq $0x40, %rdi + xorq %rbp, %rbp +L_1024_mont_loop_avx2_16: + # mu = a[i] * mp + movq %r13, %rdx + movq %r13, %r10 + imulq %r8, %rdx + xorq %r12, %r12 + # a[i+0] += m[0] * mu + mulxq (%rsi), %rax, %rcx + movq %r14, %r13 + adcxq %rax, %r10 + adoxq %rcx, %r13 + # a[i+1] += m[1] * mu + mulxq 8(%rsi), %rax, %rcx + movq %r15, %r14 + adcxq %rax, %r13 + adoxq %rcx, %r14 + # a[i+2] += m[2] * mu + mulxq 16(%rsi), %rax, %rcx + movq %rbx, %r15 + adcxq %rax, %r14 + adoxq %rcx, %r15 + # a[i+3] += m[3] * mu + mulxq 24(%rsi), %rax, %rcx + movq -32(%rdi), %rbx + adcxq %rax, %r15 + adoxq %rcx, %rbx + # a[i+4] += m[4] * mu + mulxq 32(%rsi), %rax, %rcx + movq -24(%rdi), %r11 + adcxq %rax, %rbx + adoxq %rcx, %r11 + # a[i+5] += m[5] * mu + mulxq 40(%rsi), %rax, %rcx + movq -16(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -24(%rdi) + # a[i+6] += m[6] * mu + mulxq 48(%rsi), %rax, %rcx + movq -8(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -16(%rdi) + # a[i+7] += m[7] * mu + mulxq 56(%rsi), %rax, %rcx + movq (%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -8(%rdi) + # a[i+8] += m[8] * mu + mulxq 64(%rsi), %rax, %rcx + movq 8(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, (%rdi) + # a[i+9] += m[9] * mu + mulxq 72(%rsi), %rax, %rcx + movq 16(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 8(%rdi) + # a[i+10] += m[10] * mu + mulxq 80(%rsi), %rax, %rcx + movq 24(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 16(%rdi) + # a[i+11] += m[11] * mu + mulxq 88(%rsi), %rax, %rcx + movq 32(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 24(%rdi) + # a[i+12] += m[12] * mu + mulxq 96(%rsi), %rax, %rcx + movq 40(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 32(%rdi) + # a[i+13] += m[13] * mu + mulxq 104(%rsi), %rax, %rcx + movq 48(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 40(%rdi) + # a[i+14] += m[14] * mu + mulxq 112(%rsi), %rax, %rcx + movq 56(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 48(%rdi) + # a[i+15] += m[15] * mu + mulxq 120(%rsi), %rax, %rcx + movq 64(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 56(%rdi) + adcxq %rbp, %r10 + movq %r12, %rbp + movq %r10, 64(%rdi) + adoxq %r12, %rbp + adcxq %r12, %rbp + # mu = a[i] * mp + movq %r13, %rdx + movq %r13, %r10 + imulq %r8, %rdx + xorq %r12, %r12 + # a[i+0] += m[0] * mu + mulxq (%rsi), %rax, %rcx + movq %r14, %r13 + adcxq %rax, %r10 + adoxq %rcx, %r13 + # a[i+1] += m[1] * mu + mulxq 8(%rsi), %rax, %rcx + movq %r15, %r14 + adcxq %rax, %r13 + adoxq %rcx, %r14 + # a[i+2] += m[2] * mu + mulxq 16(%rsi), %rax, %rcx + movq %rbx, %r15 + adcxq %rax, %r14 + adoxq %rcx, %r15 + # a[i+3] += m[3] * mu + mulxq 24(%rsi), %rax, %rcx + movq -24(%rdi), %rbx + adcxq %rax, %r15 + adoxq %rcx, %rbx + # a[i+4] += m[4] * mu + mulxq 32(%rsi), %rax, %rcx + movq -16(%rdi), %r11 + adcxq %rax, %rbx + adoxq %rcx, %r11 + # a[i+5] += m[5] * mu + mulxq 40(%rsi), %rax, %rcx + movq -8(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -16(%rdi) + # a[i+6] += m[6] * mu + mulxq 48(%rsi), %rax, %rcx + movq (%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -8(%rdi) + # a[i+7] += m[7] * mu + mulxq 56(%rsi), %rax, %rcx + movq 8(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, (%rdi) + # a[i+8] += m[8] * mu + mulxq 64(%rsi), %rax, %rcx + movq 16(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 8(%rdi) + # a[i+9] += m[9] * mu + mulxq 72(%rsi), %rax, %rcx + movq 24(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 16(%rdi) + # a[i+10] += m[10] * mu + mulxq 80(%rsi), %rax, %rcx + movq 32(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 24(%rdi) + # a[i+11] += m[11] * mu + mulxq 88(%rsi), %rax, %rcx + movq 40(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 32(%rdi) + # a[i+12] += m[12] * mu + mulxq 96(%rsi), %rax, %rcx + movq 48(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 40(%rdi) + # a[i+13] += m[13] * mu + mulxq 104(%rsi), %rax, %rcx + movq 56(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 48(%rdi) + # a[i+14] += m[14] * mu + mulxq 112(%rsi), %rax, %rcx + movq 64(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 56(%rdi) + # a[i+15] += m[15] * mu + mulxq 120(%rsi), %rax, %rcx + movq 72(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 64(%rdi) + adcxq %rbp, %r10 + movq %r12, %rbp + movq %r10, 72(%rdi) + adoxq %r12, %rbp + adcxq %r12, %rbp + # a += 2 + addq $16, %rdi + # i -= 2 + subq $2, %r9 + jnz L_1024_mont_loop_avx2_16 + subq $0x40, %rdi + subq 120(%rsi), %r10 + movq %rdi, %r8 + sbbq %r10, %r10 + negq %rbp + notq %r10 + orq %r10, %rbp + subq $0x80, %rdi + movq (%rsi), %rcx + movq %r13, %rdx + pextq %rbp, %rcx, %rcx + subq %rcx, %rdx + movq 8(%rsi), %rcx + movq %r14, %rax + pextq %rbp, %rcx, %rcx + movq %rdx, (%rdi) + sbbq %rcx, %rax + movq 16(%rsi), %rdx + movq %r15, %rcx + pextq %rbp, %rdx, %rdx + movq %rax, 8(%rdi) + sbbq %rdx, %rcx + movq 24(%rsi), %rax + movq %rbx, %rdx + pextq %rbp, %rax, %rax + movq %rcx, 16(%rdi) + sbbq %rax, %rdx + movq 32(%rsi), %rcx + movq 32(%r8), %rax + pextq %rbp, %rcx, %rcx + movq %rdx, 24(%rdi) + sbbq %rcx, %rax + movq 40(%rsi), %rdx + movq 40(%r8), %rcx + pextq %rbp, %rdx, %rdx + movq %rax, 32(%rdi) + sbbq %rdx, %rcx + movq 48(%rsi), %rax + movq 48(%r8), %rdx + pextq %rbp, %rax, %rax + movq %rcx, 40(%rdi) + sbbq %rax, %rdx + movq 56(%rsi), %rcx + movq 56(%r8), %rax + pextq %rbp, %rcx, %rcx + movq %rdx, 48(%rdi) + sbbq %rcx, %rax + movq 64(%rsi), %rdx + movq 64(%r8), %rcx + pextq %rbp, %rdx, %rdx + movq %rax, 56(%rdi) + sbbq %rdx, %rcx + movq 72(%rsi), %rax + movq 72(%r8), %rdx + pextq %rbp, %rax, %rax + movq %rcx, 64(%rdi) + sbbq %rax, %rdx + movq 80(%rsi), %rcx + movq 80(%r8), %rax + pextq %rbp, %rcx, %rcx + movq %rdx, 72(%rdi) + sbbq %rcx, %rax + movq 88(%rsi), %rdx + movq 88(%r8), %rcx + pextq %rbp, %rdx, %rdx + movq %rax, 80(%rdi) + sbbq %rdx, %rcx + movq 96(%rsi), %rax + movq 96(%r8), %rdx + pextq %rbp, %rax, %rax + movq %rcx, 88(%rdi) + sbbq %rax, %rdx + movq 104(%rsi), %rcx + movq 104(%r8), %rax + pextq %rbp, %rcx, %rcx + movq %rdx, 96(%rdi) + sbbq %rcx, %rax + movq 112(%rsi), %rdx + movq 112(%r8), %rcx + pextq %rbp, %rdx, %rdx + movq %rax, 104(%rdi) + sbbq %rdx, %rcx + movq 120(%rsi), %rax + movq 120(%r8), %rdx + pextq %rbp, %rax, %rax + movq %rcx, 112(%rdi) + sbbq %rax, %rdx + movq %rdx, 120(%rdi) + popq %rbp + popq %rbx + popq %r15 + popq %r14 + popq %r13 + popq %r12 + repz retq +#ifndef __APPLE__ +.size sp_1024_mont_reduce_avx2_16,.-sp_1024_mont_reduce_avx2_16 +#endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +#ifdef HAVE_INTEL_AVX2 +/* Add two Montgomery form numbers (r = a + b % m). + * + * r Result of addition. + * a First number to add in Montogmery form. + * b Second number to add in Montogmery form. + * m Modulus (prime). + */ +#ifndef __APPLE__ +.text +.globl sp_1024_mont_add_avx2_16 +.type sp_1024_mont_add_avx2_16,@function +.align 16 +sp_1024_mont_add_avx2_16: +#else +.section __TEXT,__text +.globl _sp_1024_mont_add_avx2_16 +.p2align 4 +_sp_1024_mont_add_avx2_16: +#endif /* __APPLE__ */ + movq (%rsi), %rax + movq 8(%rsi), %r8 + movq 16(%rsi), %r9 + movq 24(%rsi), %r10 + addq (%rdx), %rax + movq $0x00, %r11 + adcq 8(%rdx), %r8 + adcq 16(%rdx), %r9 + adcq 24(%rdx), %r10 + movq %rax, (%rdi) + movq %r8, 8(%rdi) + movq %r9, 16(%rdi) + movq %r10, 24(%rdi) + movq 32(%rsi), %rax + movq 40(%rsi), %r8 + movq 48(%rsi), %r9 + movq 56(%rsi), %r10 + adcq 32(%rdx), %rax + adcq 40(%rdx), %r8 + adcq 48(%rdx), %r9 + adcq 56(%rdx), %r10 + movq %rax, 32(%rdi) + movq %r8, 40(%rdi) + movq %r9, 48(%rdi) + movq %r10, 56(%rdi) + movq 64(%rsi), %rax + movq 72(%rsi), %r8 + movq 80(%rsi), %r9 + movq 88(%rsi), %r10 + adcq 64(%rdx), %rax + adcq 72(%rdx), %r8 + adcq 80(%rdx), %r9 + adcq 88(%rdx), %r10 + movq %rax, 64(%rdi) + movq %r8, 72(%rdi) + movq %r9, 80(%rdi) + movq %r10, 88(%rdi) + movq 96(%rsi), %rax + movq 104(%rsi), %r8 + movq 112(%rsi), %r9 + movq 120(%rsi), %r10 + adcq 96(%rdx), %rax + adcq 104(%rdx), %r8 + adcq 112(%rdx), %r9 + adcq 120(%rdx), %r10 + movq %rax, 96(%rdi) + movq %r8, 104(%rdi) + movq %r9, 112(%rdi) + movq %r10, 120(%rdi) + sbbq $0x00, %r11 + subq 120(%rcx), %r10 + sbbq %r10, %r10 + notq %r10 + orq %r10, %r11 + movq (%rcx), %r9 + movq 8(%rcx), %r10 + movq (%rdi), %rax + movq 8(%rdi), %r8 + pextq %r11, %r9, %r9 + pextq %r11, %r10, %r10 + subq %r9, %rax + sbbq %r10, %r8 + movq %rax, (%rdi) + movq %r8, 8(%rdi) + movq 16(%rcx), %r9 + movq 24(%rcx), %r10 + movq 16(%rdi), %rax + movq 24(%rdi), %r8 + pextq %r11, %r9, %r9 + pextq %r11, %r10, %r10 + sbbq %r9, %rax + sbbq %r10, %r8 + movq %rax, 16(%rdi) + movq %r8, 24(%rdi) + movq 32(%rcx), %r9 + movq 40(%rcx), %r10 + movq 32(%rdi), %rax + movq 40(%rdi), %r8 + pextq %r11, %r9, %r9 + pextq %r11, %r10, %r10 + sbbq %r9, %rax + sbbq %r10, %r8 + movq %rax, 32(%rdi) + movq %r8, 40(%rdi) + movq 48(%rcx), %r9 + movq 56(%rcx), %r10 + movq 48(%rdi), %rax + movq 56(%rdi), %r8 + pextq %r11, %r9, %r9 + pextq %r11, %r10, %r10 + sbbq %r9, %rax + sbbq %r10, %r8 + movq %rax, 48(%rdi) + movq %r8, 56(%rdi) + movq 64(%rcx), %r9 + movq 72(%rcx), %r10 + movq 64(%rdi), %rax + movq 72(%rdi), %r8 + pextq %r11, %r9, %r9 + pextq %r11, %r10, %r10 + sbbq %r9, %rax + sbbq %r10, %r8 + movq %rax, 64(%rdi) + movq %r8, 72(%rdi) + movq 80(%rcx), %r9 + movq 88(%rcx), %r10 + movq 80(%rdi), %rax + movq 88(%rdi), %r8 + pextq %r11, %r9, %r9 + pextq %r11, %r10, %r10 + sbbq %r9, %rax + sbbq %r10, %r8 + movq %rax, 80(%rdi) + movq %r8, 88(%rdi) + movq 96(%rcx), %r9 + movq 104(%rcx), %r10 + movq 96(%rdi), %rax + movq 104(%rdi), %r8 + pextq %r11, %r9, %r9 + pextq %r11, %r10, %r10 + sbbq %r9, %rax + sbbq %r10, %r8 + movq %rax, 96(%rdi) + movq %r8, 104(%rdi) + movq 112(%rcx), %r9 + movq 120(%rcx), %r10 + movq 112(%rdi), %rax + movq 120(%rdi), %r8 + pextq %r11, %r9, %r9 + pextq %r11, %r10, %r10 + sbbq %r9, %rax + sbbq %r10, %r8 + movq %rax, 112(%rdi) + movq %r8, 120(%rdi) + repz retq +#ifndef __APPLE__ +.size sp_1024_mont_add_avx2_16,.-sp_1024_mont_add_avx2_16 +#endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +#ifdef HAVE_INTEL_AVX2 +/* Double a Montgomery form number (r = a + a % m). + * + * r Result of addition. + * a Number to souble in Montogmery form. + * m Modulus (prime). + */ +#ifndef __APPLE__ +.text +.globl sp_1024_mont_dbl_avx2_16 +.type sp_1024_mont_dbl_avx2_16,@function +.align 16 +sp_1024_mont_dbl_avx2_16: +#else +.section __TEXT,__text +.globl _sp_1024_mont_dbl_avx2_16 +.p2align 4 +_sp_1024_mont_dbl_avx2_16: +#endif /* __APPLE__ */ + movq (%rsi), %rax + movq 8(%rsi), %rcx + movq 16(%rsi), %r8 + movq 24(%rsi), %r9 + addq (%rsi), %rax + movq $0x00, %r10 + adcq 8(%rsi), %rcx + adcq 16(%rsi), %r8 + adcq 24(%rsi), %r9 + movq %rax, (%rdi) + movq %rcx, 8(%rdi) + movq %r8, 16(%rdi) + movq %r9, 24(%rdi) + movq 32(%rsi), %rax + movq 40(%rsi), %rcx + movq 48(%rsi), %r8 + movq 56(%rsi), %r9 + adcq 32(%rsi), %rax + adcq 40(%rsi), %rcx + adcq 48(%rsi), %r8 + adcq 56(%rsi), %r9 + movq %rax, 32(%rdi) + movq %rcx, 40(%rdi) + movq %r8, 48(%rdi) + movq %r9, 56(%rdi) + movq 64(%rsi), %rax + movq 72(%rsi), %rcx + movq 80(%rsi), %r8 + movq 88(%rsi), %r9 + adcq 64(%rsi), %rax + adcq 72(%rsi), %rcx + adcq 80(%rsi), %r8 + adcq 88(%rsi), %r9 + movq %rax, 64(%rdi) + movq %rcx, 72(%rdi) + movq %r8, 80(%rdi) + movq %r9, 88(%rdi) + movq 96(%rsi), %rax + movq 104(%rsi), %rcx + movq 112(%rsi), %r8 + movq 120(%rsi), %r9 + adcq 96(%rsi), %rax + adcq 104(%rsi), %rcx + adcq 112(%rsi), %r8 + adcq 120(%rsi), %r9 + movq %rax, 96(%rdi) + movq %rcx, 104(%rdi) + movq %r8, 112(%rdi) + movq %r9, 120(%rdi) + sbbq $0x00, %r10 + subq 120(%rdx), %r9 + sbbq %r9, %r9 + notq %r9 + orq %r9, %r10 + movq (%rdx), %r8 + movq 8(%rdx), %r9 + movq (%rdi), %rax + movq 8(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + subq %r8, %rax + sbbq %r9, %rcx + movq %rax, (%rdi) + movq %rcx, 8(%rdi) + movq 16(%rdx), %r8 + movq 24(%rdx), %r9 + movq 16(%rdi), %rax + movq 24(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + sbbq %r8, %rax + sbbq %r9, %rcx + movq %rax, 16(%rdi) + movq %rcx, 24(%rdi) + movq 32(%rdx), %r8 + movq 40(%rdx), %r9 + movq 32(%rdi), %rax + movq 40(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + sbbq %r8, %rax + sbbq %r9, %rcx + movq %rax, 32(%rdi) + movq %rcx, 40(%rdi) + movq 48(%rdx), %r8 + movq 56(%rdx), %r9 + movq 48(%rdi), %rax + movq 56(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + sbbq %r8, %rax + sbbq %r9, %rcx + movq %rax, 48(%rdi) + movq %rcx, 56(%rdi) + movq 64(%rdx), %r8 + movq 72(%rdx), %r9 + movq 64(%rdi), %rax + movq 72(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + sbbq %r8, %rax + sbbq %r9, %rcx + movq %rax, 64(%rdi) + movq %rcx, 72(%rdi) + movq 80(%rdx), %r8 + movq 88(%rdx), %r9 + movq 80(%rdi), %rax + movq 88(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + sbbq %r8, %rax + sbbq %r9, %rcx + movq %rax, 80(%rdi) + movq %rcx, 88(%rdi) + movq 96(%rdx), %r8 + movq 104(%rdx), %r9 + movq 96(%rdi), %rax + movq 104(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + sbbq %r8, %rax + sbbq %r9, %rcx + movq %rax, 96(%rdi) + movq %rcx, 104(%rdi) + movq 112(%rdx), %r8 + movq 120(%rdx), %r9 + movq 112(%rdi), %rax + movq 120(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + sbbq %r8, %rax + sbbq %r9, %rcx + movq %rax, 112(%rdi) + movq %rcx, 120(%rdi) + repz retq +#ifndef __APPLE__ +.size sp_1024_mont_dbl_avx2_16,.-sp_1024_mont_dbl_avx2_16 +#endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +#ifdef HAVE_INTEL_AVX2 +/* Triple a Montgomery form number (r = a + a + a % m). + * + * r Result of addition. + * a Number to souble in Montogmery form. + * m Modulus (prime). + */ +#ifndef __APPLE__ +.text +.globl sp_1024_mont_tpl_avx2_16 +.type sp_1024_mont_tpl_avx2_16,@function +.align 16 +sp_1024_mont_tpl_avx2_16: +#else +.section __TEXT,__text +.globl _sp_1024_mont_tpl_avx2_16 +.p2align 4 +_sp_1024_mont_tpl_avx2_16: +#endif /* __APPLE__ */ + movq (%rsi), %rax + movq 8(%rsi), %rcx + movq 16(%rsi), %r8 + movq 24(%rsi), %r9 + addq (%rsi), %rax + movq $0x00, %r10 + adcq 8(%rsi), %rcx + adcq 16(%rsi), %r8 + adcq 24(%rsi), %r9 + movq %rax, (%rdi) + movq %rcx, 8(%rdi) + movq %r8, 16(%rdi) + movq %r9, 24(%rdi) + movq 32(%rsi), %rax + movq 40(%rsi), %rcx + movq 48(%rsi), %r8 + movq 56(%rsi), %r9 + adcq 32(%rsi), %rax + adcq 40(%rsi), %rcx + adcq 48(%rsi), %r8 + adcq 56(%rsi), %r9 + movq %rax, 32(%rdi) + movq %rcx, 40(%rdi) + movq %r8, 48(%rdi) + movq %r9, 56(%rdi) + movq 64(%rsi), %rax + movq 72(%rsi), %rcx + movq 80(%rsi), %r8 + movq 88(%rsi), %r9 + adcq 64(%rsi), %rax + adcq 72(%rsi), %rcx + adcq 80(%rsi), %r8 + adcq 88(%rsi), %r9 + movq %rax, 64(%rdi) + movq %rcx, 72(%rdi) + movq %r8, 80(%rdi) + movq %r9, 88(%rdi) + movq 96(%rsi), %rax + movq 104(%rsi), %rcx + movq 112(%rsi), %r8 + movq 120(%rsi), %r9 + adcq 96(%rsi), %rax + adcq 104(%rsi), %rcx + adcq 112(%rsi), %r8 + adcq 120(%rsi), %r9 + movq %rax, 96(%rdi) + movq %rcx, 104(%rdi) + movq %r8, 112(%rdi) + movq %r9, 120(%rdi) + sbbq $0x00, %r10 + subq 120(%rdx), %r9 + sbbq %r9, %r9 + notq %r9 + orq %r9, %r10 + movq (%rdx), %r8 + movq 8(%rdx), %r9 + movq (%rdi), %rax + movq 8(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + subq %r8, %rax + sbbq %r9, %rcx + movq %rax, (%rdi) + movq %rcx, 8(%rdi) + movq 16(%rdx), %r8 + movq 24(%rdx), %r9 + movq 16(%rdi), %rax + movq 24(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + sbbq %r8, %rax + sbbq %r9, %rcx + movq %rax, 16(%rdi) + movq %rcx, 24(%rdi) + movq 32(%rdx), %r8 + movq 40(%rdx), %r9 + movq 32(%rdi), %rax + movq 40(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + sbbq %r8, %rax + sbbq %r9, %rcx + movq %rax, 32(%rdi) + movq %rcx, 40(%rdi) + movq 48(%rdx), %r8 + movq 56(%rdx), %r9 + movq 48(%rdi), %rax + movq 56(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + sbbq %r8, %rax + sbbq %r9, %rcx + movq %rax, 48(%rdi) + movq %rcx, 56(%rdi) + movq 64(%rdx), %r8 + movq 72(%rdx), %r9 + movq 64(%rdi), %rax + movq 72(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + sbbq %r8, %rax + sbbq %r9, %rcx + movq %rax, 64(%rdi) + movq %rcx, 72(%rdi) + movq 80(%rdx), %r8 + movq 88(%rdx), %r9 + movq 80(%rdi), %rax + movq 88(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + sbbq %r8, %rax + sbbq %r9, %rcx + movq %rax, 80(%rdi) + movq %rcx, 88(%rdi) + movq 96(%rdx), %r8 + movq 104(%rdx), %r9 + movq 96(%rdi), %rax + movq 104(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + sbbq %r8, %rax + sbbq %r9, %rcx + movq %rax, 96(%rdi) + movq %rcx, 104(%rdi) + movq 112(%rdx), %r8 + movq 120(%rdx), %r9 + movq 112(%rdi), %rax + movq 120(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + sbbq %r8, %rax + sbbq %r9, %rcx + movq %rax, 112(%rdi) + movq %rcx, 120(%rdi) + movq (%rdi), %rax + movq 8(%rdi), %rcx + movq 16(%rdi), %r8 + movq 24(%rdi), %r9 + addq (%rsi), %rax + movq $0x00, %r10 + adcq 8(%rsi), %rcx + adcq 16(%rsi), %r8 + adcq 24(%rsi), %r9 + movq %rax, (%rdi) + movq %rcx, 8(%rdi) + movq %r8, 16(%rdi) + movq %r9, 24(%rdi) + movq 32(%rdi), %rax + movq 40(%rdi), %rcx + movq 48(%rdi), %r8 + movq 56(%rdi), %r9 + adcq 32(%rsi), %rax + adcq 40(%rsi), %rcx + adcq 48(%rsi), %r8 + adcq 56(%rsi), %r9 + movq %rax, 32(%rdi) + movq %rcx, 40(%rdi) + movq %r8, 48(%rdi) + movq %r9, 56(%rdi) + movq 64(%rdi), %rax + movq 72(%rdi), %rcx + movq 80(%rdi), %r8 + movq 88(%rdi), %r9 + adcq 64(%rsi), %rax + adcq 72(%rsi), %rcx + adcq 80(%rsi), %r8 + adcq 88(%rsi), %r9 + movq %rax, 64(%rdi) + movq %rcx, 72(%rdi) + movq %r8, 80(%rdi) + movq %r9, 88(%rdi) + movq 96(%rdi), %rax + movq 104(%rdi), %rcx + movq 112(%rdi), %r8 + movq 120(%rdi), %r9 + adcq 96(%rsi), %rax + adcq 104(%rsi), %rcx + adcq 112(%rsi), %r8 + adcq 120(%rsi), %r9 + movq %rax, 96(%rdi) + movq %rcx, 104(%rdi) + movq %r8, 112(%rdi) + movq %r9, 120(%rdi) + sbbq $0x00, %r10 + subq 120(%rdx), %r9 + sbbq %r9, %r9 + notq %r9 + orq %r9, %r10 + movq (%rdx), %r8 + movq 8(%rdx), %r9 + movq (%rdi), %rax + movq 8(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + subq %r8, %rax + sbbq %r9, %rcx + movq %rax, (%rdi) + movq %rcx, 8(%rdi) + movq 16(%rdx), %r8 + movq 24(%rdx), %r9 + movq 16(%rdi), %rax + movq 24(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + sbbq %r8, %rax + sbbq %r9, %rcx + movq %rax, 16(%rdi) + movq %rcx, 24(%rdi) + movq 32(%rdx), %r8 + movq 40(%rdx), %r9 + movq 32(%rdi), %rax + movq 40(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + sbbq %r8, %rax + sbbq %r9, %rcx + movq %rax, 32(%rdi) + movq %rcx, 40(%rdi) + movq 48(%rdx), %r8 + movq 56(%rdx), %r9 + movq 48(%rdi), %rax + movq 56(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + sbbq %r8, %rax + sbbq %r9, %rcx + movq %rax, 48(%rdi) + movq %rcx, 56(%rdi) + movq 64(%rdx), %r8 + movq 72(%rdx), %r9 + movq 64(%rdi), %rax + movq 72(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + sbbq %r8, %rax + sbbq %r9, %rcx + movq %rax, 64(%rdi) + movq %rcx, 72(%rdi) + movq 80(%rdx), %r8 + movq 88(%rdx), %r9 + movq 80(%rdi), %rax + movq 88(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + sbbq %r8, %rax + sbbq %r9, %rcx + movq %rax, 80(%rdi) + movq %rcx, 88(%rdi) + movq 96(%rdx), %r8 + movq 104(%rdx), %r9 + movq 96(%rdi), %rax + movq 104(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + sbbq %r8, %rax + sbbq %r9, %rcx + movq %rax, 96(%rdi) + movq %rcx, 104(%rdi) + movq 112(%rdx), %r8 + movq 120(%rdx), %r9 + movq 112(%rdi), %rax + movq 120(%rdi), %rcx + pextq %r10, %r8, %r8 + pextq %r10, %r9, %r9 + sbbq %r8, %rax + sbbq %r9, %rcx + movq %rax, 112(%rdi) + movq %rcx, 120(%rdi) + repz retq +#ifndef __APPLE__ +.size sp_1024_mont_tpl_avx2_16,.-sp_1024_mont_tpl_avx2_16 +#endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +#ifdef HAVE_INTEL_AVX2 +/* Subtract two Montgomery form numbers (r = a - b % m). + * + * r Result of addition. + * a First number to add in Montogmery form. + * b Second number to add in Montogmery form. + * m Modulus (prime). + */ +#ifndef __APPLE__ +.text +.globl sp_1024_mont_sub_avx2_16 +.type sp_1024_mont_sub_avx2_16,@function +.align 16 +sp_1024_mont_sub_avx2_16: +#else +.section __TEXT,__text +.globl _sp_1024_mont_sub_avx2_16 +.p2align 4 +_sp_1024_mont_sub_avx2_16: +#endif /* __APPLE__ */ + movq (%rsi), %rax + movq 8(%rsi), %r8 + movq 16(%rsi), %r9 + movq 24(%rsi), %r10 + subq (%rdx), %rax + movq $0x00, %r11 + sbbq 8(%rdx), %r8 + sbbq 16(%rdx), %r9 + sbbq 24(%rdx), %r10 + movq %rax, (%rdi) + movq %r8, 8(%rdi) + movq %r9, 16(%rdi) + movq %r10, 24(%rdi) + movq 32(%rsi), %rax + movq 40(%rsi), %r8 + movq 48(%rsi), %r9 + movq 56(%rsi), %r10 + sbbq 32(%rdx), %rax + sbbq 40(%rdx), %r8 + sbbq 48(%rdx), %r9 + sbbq 56(%rdx), %r10 + movq %rax, 32(%rdi) + movq %r8, 40(%rdi) + movq %r9, 48(%rdi) + movq %r10, 56(%rdi) + movq 64(%rsi), %rax + movq 72(%rsi), %r8 + movq 80(%rsi), %r9 + movq 88(%rsi), %r10 + sbbq 64(%rdx), %rax + sbbq 72(%rdx), %r8 + sbbq 80(%rdx), %r9 + sbbq 88(%rdx), %r10 + movq %rax, 64(%rdi) + movq %r8, 72(%rdi) + movq %r9, 80(%rdi) + movq %r10, 88(%rdi) + movq 96(%rsi), %rax + movq 104(%rsi), %r8 + movq 112(%rsi), %r9 + movq 120(%rsi), %r10 + sbbq 96(%rdx), %rax + sbbq 104(%rdx), %r8 + sbbq 112(%rdx), %r9 + sbbq 120(%rdx), %r10 + movq %rax, 96(%rdi) + movq %r8, 104(%rdi) + movq %r9, 112(%rdi) + movq %r10, 120(%rdi) + sbbq $0x00, %r11 + movq (%rcx), %r9 + movq 8(%rcx), %r10 + movq (%rdi), %rax + movq 8(%rdi), %r8 + pextq %r11, %r9, %r9 + pextq %r11, %r10, %r10 + addq %r9, %rax + adcq %r10, %r8 + movq %rax, (%rdi) + movq %r8, 8(%rdi) + movq 16(%rcx), %r9 + movq 24(%rcx), %r10 + movq 16(%rdi), %rax + movq 24(%rdi), %r8 + pextq %r11, %r9, %r9 + pextq %r11, %r10, %r10 + adcq %r9, %rax + adcq %r10, %r8 + movq %rax, 16(%rdi) + movq %r8, 24(%rdi) + movq 32(%rcx), %r9 + movq 40(%rcx), %r10 + movq 32(%rdi), %rax + movq 40(%rdi), %r8 + pextq %r11, %r9, %r9 + pextq %r11, %r10, %r10 + adcq %r9, %rax + adcq %r10, %r8 + movq %rax, 32(%rdi) + movq %r8, 40(%rdi) + movq 48(%rcx), %r9 + movq 56(%rcx), %r10 + movq 48(%rdi), %rax + movq 56(%rdi), %r8 + pextq %r11, %r9, %r9 + pextq %r11, %r10, %r10 + adcq %r9, %rax + adcq %r10, %r8 + movq %rax, 48(%rdi) + movq %r8, 56(%rdi) + movq 64(%rcx), %r9 + movq 72(%rcx), %r10 + movq 64(%rdi), %rax + movq 72(%rdi), %r8 + pextq %r11, %r9, %r9 + pextq %r11, %r10, %r10 + adcq %r9, %rax + adcq %r10, %r8 + movq %rax, 64(%rdi) + movq %r8, 72(%rdi) + movq 80(%rcx), %r9 + movq 88(%rcx), %r10 + movq 80(%rdi), %rax + movq 88(%rdi), %r8 + pextq %r11, %r9, %r9 + pextq %r11, %r10, %r10 + adcq %r9, %rax + adcq %r10, %r8 + movq %rax, 80(%rdi) + movq %r8, 88(%rdi) + movq 96(%rcx), %r9 + movq 104(%rcx), %r10 + movq 96(%rdi), %rax + movq 104(%rdi), %r8 + pextq %r11, %r9, %r9 + pextq %r11, %r10, %r10 + adcq %r9, %rax + adcq %r10, %r8 + movq %rax, 96(%rdi) + movq %r8, 104(%rdi) + movq 112(%rcx), %r9 + movq 120(%rcx), %r10 + movq 112(%rdi), %rax + movq 120(%rdi), %r8 + pextq %r11, %r9, %r9 + pextq %r11, %r10, %r10 + adcq %r9, %rax + adcq %r10, %r8 + movq %rax, 112(%rdi) + movq %r8, 120(%rdi) + repz retq +#ifndef __APPLE__ +.size sp_1024_mont_sub_avx2_16,.-sp_1024_mont_sub_avx2_16 +#endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +#ifdef HAVE_INTEL_AVX2 +/* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m) + * + * r Result of division by 2. + * a Number to divide. + * m Modulus (prime). + */ +#ifndef __APPLE__ +.text +.globl sp_1024_div2_avx2_16 +.type sp_1024_div2_avx2_16,@function +.align 16 +sp_1024_div2_avx2_16: +#else +.section __TEXT,__text +.globl _sp_1024_div2_avx2_16 +.p2align 4 +_sp_1024_div2_avx2_16: +#endif /* __APPLE__ */ + movq (%rsi), %r11 + xorq %r10, %r10 + movq %r11, %r8 + andq $0x01, %r11 + negq %r11 + movq (%rdx), %rax + movq 8(%rdx), %rcx + movq (%rsi), %r8 + movq 8(%rsi), %r9 + pextq %r11, %rax, %rax + pextq %r11, %rcx, %rcx + addq %rax, %r8 + adcq %rcx, %r9 + movq %r8, (%rdi) + movq %r9, 8(%rdi) + movq 16(%rdx), %rax + movq 24(%rdx), %rcx + movq 16(%rsi), %r8 + movq 24(%rsi), %r9 + pextq %r11, %rax, %rax + pextq %r11, %rcx, %rcx + adcq %rax, %r8 + adcq %rcx, %r9 + movq %r8, 16(%rdi) + movq %r9, 24(%rdi) + movq 32(%rdx), %rax + movq 40(%rdx), %rcx + movq 32(%rsi), %r8 + movq 40(%rsi), %r9 + pextq %r11, %rax, %rax + pextq %r11, %rcx, %rcx + adcq %rax, %r8 + adcq %rcx, %r9 + movq %r8, 32(%rdi) + movq %r9, 40(%rdi) + movq 48(%rdx), %rax + movq 56(%rdx), %rcx + movq 48(%rsi), %r8 + movq 56(%rsi), %r9 + pextq %r11, %rax, %rax + pextq %r11, %rcx, %rcx + adcq %rax, %r8 + adcq %rcx, %r9 + movq %r8, 48(%rdi) + movq %r9, 56(%rdi) + movq 64(%rdx), %rax + movq 72(%rdx), %rcx + movq 64(%rsi), %r8 + movq 72(%rsi), %r9 + pextq %r11, %rax, %rax + pextq %r11, %rcx, %rcx + adcq %rax, %r8 + adcq %rcx, %r9 + movq %r8, 64(%rdi) + movq %r9, 72(%rdi) + movq 80(%rdx), %rax + movq 88(%rdx), %rcx + movq 80(%rsi), %r8 + movq 88(%rsi), %r9 + pextq %r11, %rax, %rax + pextq %r11, %rcx, %rcx + adcq %rax, %r8 + adcq %rcx, %r9 + movq %r8, 80(%rdi) + movq %r9, 88(%rdi) + movq 96(%rdx), %rax + movq 104(%rdx), %rcx + movq 96(%rsi), %r8 + movq 104(%rsi), %r9 + pextq %r11, %rax, %rax + pextq %r11, %rcx, %rcx + adcq %rax, %r8 + adcq %rcx, %r9 + movq %r8, 96(%rdi) + movq %r9, 104(%rdi) + movq 112(%rdx), %rax + movq 120(%rdx), %rcx + movq 112(%rsi), %r8 + movq 120(%rsi), %r9 + pextq %r11, %rax, %rax + pextq %r11, %rcx, %rcx + adcq %rax, %r8 + adcq %rcx, %r9 + movq %r8, 112(%rdi) + movq %r9, 120(%rdi) + adcq $0x00, %r10 + movq (%rdi), %r8 + movq 8(%rdi), %r9 + shrdq $0x01, %r9, %r8 + movq %r8, (%rdi) + movq 16(%rdi), %r8 + shrdq $0x01, %r8, %r9 + movq %r9, 8(%rdi) + movq 24(%rdi), %r9 + shrdq $0x01, %r9, %r8 + movq %r8, 16(%rdi) + movq 32(%rdi), %r8 + shrdq $0x01, %r8, %r9 + movq %r9, 24(%rdi) + movq 40(%rdi), %r9 + shrdq $0x01, %r9, %r8 + movq %r8, 32(%rdi) + movq 48(%rdi), %r8 + shrdq $0x01, %r8, %r9 + movq %r9, 40(%rdi) + movq 56(%rdi), %r9 + shrdq $0x01, %r9, %r8 + movq %r8, 48(%rdi) + movq 64(%rdi), %r8 + shrdq $0x01, %r8, %r9 + movq %r9, 56(%rdi) + movq 72(%rdi), %r9 + shrdq $0x01, %r9, %r8 + movq %r8, 64(%rdi) + movq 80(%rdi), %r8 + shrdq $0x01, %r8, %r9 + movq %r9, 72(%rdi) + movq 88(%rdi), %r9 + shrdq $0x01, %r9, %r8 + movq %r8, 80(%rdi) + movq 96(%rdi), %r8 + shrdq $0x01, %r8, %r9 + movq %r9, 88(%rdi) + movq 104(%rdi), %r9 + shrdq $0x01, %r9, %r8 + movq %r8, 96(%rdi) + movq 112(%rdi), %r8 + shrdq $0x01, %r8, %r9 + movq %r9, 104(%rdi) + movq 120(%rdi), %r9 + shrdq $0x01, %r9, %r8 + movq %r8, 112(%rdi) + shrdq $0x01, %r10, %r9 + movq %r9, 120(%rdi) + repz retq +#ifndef __APPLE__ +.size sp_1024_div2_avx2_16,.-sp_1024_div2_avx2_16 +#endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +/* Read big endian unsigned byte array into r. + * Uses the bswap instruction. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a Byte array. + * n Number of bytes in array to read. + */ +#ifndef __APPLE__ +.text +.globl sp_1024_from_bin_bswap +.type sp_1024_from_bin_bswap,@function +.align 16 +sp_1024_from_bin_bswap: +#else +.section __TEXT,__text +.globl _sp_1024_from_bin_bswap +.p2align 4 +_sp_1024_from_bin_bswap: +#endif /* __APPLE__ */ + movq %rdx, %r9 + movq %rdi, %r10 + addq %rcx, %r9 + addq $0x80, %r10 + xorq %r11, %r11 + jmp L_1024_from_bin_bswap_64_end +L_1024_from_bin_bswap_64_start: + subq $0x40, %r9 + movq 56(%r9), %rax + movq 48(%r9), %r8 + bswapq %rax + bswapq %r8 + movq %rax, (%rdi) + movq %r8, 8(%rdi) + movq 40(%r9), %rax + movq 32(%r9), %r8 + bswapq %rax + bswapq %r8 + movq %rax, 16(%rdi) + movq %r8, 24(%rdi) + movq 24(%r9), %rax + movq 16(%r9), %r8 + bswapq %rax + bswapq %r8 + movq %rax, 32(%rdi) + movq %r8, 40(%rdi) + movq 8(%r9), %rax + movq (%r9), %r8 + bswapq %rax + bswapq %r8 + movq %rax, 48(%rdi) + movq %r8, 56(%rdi) + addq $0x40, %rdi + subq $0x40, %rcx +L_1024_from_bin_bswap_64_end: + cmpq $63, %rcx + jg L_1024_from_bin_bswap_64_start + jmp L_1024_from_bin_bswap_8_end +L_1024_from_bin_bswap_8_start: + subq $8, %r9 + movq (%r9), %rax + bswapq %rax + movq %rax, (%rdi) + addq $8, %rdi + subq $8, %rcx +L_1024_from_bin_bswap_8_end: + cmpq $7, %rcx + jg L_1024_from_bin_bswap_8_start + cmpq %r11, %rcx + je L_1024_from_bin_bswap_hi_end + movq %r11, %r8 + movq %r11, %rax +L_1024_from_bin_bswap_hi_start: + movb (%rdx), %al + shlq $8, %r8 + incq %rdx + addq %rax, %r8 + decq %rcx + jg L_1024_from_bin_bswap_hi_start + movq %r8, (%rdi) + addq $8, %rdi +L_1024_from_bin_bswap_hi_end: + cmpq %r10, %rdi + je L_1024_from_bin_bswap_zero_end +L_1024_from_bin_bswap_zero_start: + movq %r11, (%rdi) + addq $8, %rdi + cmpq %r10, %rdi + jl L_1024_from_bin_bswap_zero_start +L_1024_from_bin_bswap_zero_end: + repz retq +#ifndef __APPLE__ +.size sp_1024_from_bin_bswap,.-sp_1024_from_bin_bswap +#endif /* __APPLE__ */ +#ifndef NO_MOVBE_SUPPORT +/* Read big endian unsigned byte array into r. + * Uses the movbe instruction which is an optional instruction. + * + * r A single precision integer. + * size Maximum number of bytes to convert + * a Byte array. + * n Number of bytes in array to read. + */ +#ifndef __APPLE__ +.text +.globl sp_1024_from_bin_movbe +.type sp_1024_from_bin_movbe,@function +.align 16 +sp_1024_from_bin_movbe: +#else +.section __TEXT,__text +.globl _sp_1024_from_bin_movbe +.p2align 4 +_sp_1024_from_bin_movbe: +#endif /* __APPLE__ */ + movq %rdx, %r9 + movq %rdi, %r10 + addq %rcx, %r9 + addq $0x80, %r10 + xorq %r11, %r11 + jmp L_1024_from_bin_movbe_64_end +L_1024_from_bin_movbe_64_start: + subq $0x40, %r9 + movbeq 56(%r9), %rax + movbeq 48(%r9), %r8 + movq %rax, (%rdi) + movq %r8, 8(%rdi) + movbeq 40(%r9), %rax + movbeq 32(%r9), %r8 + movq %rax, 16(%rdi) + movq %r8, 24(%rdi) + movbeq 24(%r9), %rax + movbeq 16(%r9), %r8 + movq %rax, 32(%rdi) + movq %r8, 40(%rdi) + movbeq 8(%r9), %rax + movbeq (%r9), %r8 + movq %rax, 48(%rdi) + movq %r8, 56(%rdi) + addq $0x40, %rdi + subq $0x40, %rcx +L_1024_from_bin_movbe_64_end: + cmpq $63, %rcx + jg L_1024_from_bin_movbe_64_start + jmp L_1024_from_bin_movbe_8_end +L_1024_from_bin_movbe_8_start: + subq $8, %r9 + movbeq (%r9), %rax + movq %rax, (%rdi) + addq $8, %rdi + subq $8, %rcx +L_1024_from_bin_movbe_8_end: + cmpq $7, %rcx + jg L_1024_from_bin_movbe_8_start + cmpq %r11, %rcx + je L_1024_from_bin_movbe_hi_end + movq %r11, %r8 + movq %r11, %rax +L_1024_from_bin_movbe_hi_start: + movb (%rdx), %al + shlq $8, %r8 + incq %rdx + addq %rax, %r8 + decq %rcx + jg L_1024_from_bin_movbe_hi_start + movq %r8, (%rdi) + addq $8, %rdi +L_1024_from_bin_movbe_hi_end: + cmpq %r10, %rdi + je L_1024_from_bin_movbe_zero_end +L_1024_from_bin_movbe_zero_start: + movq %r11, (%rdi) + addq $8, %rdi + cmpq %r10, %rdi + jl L_1024_from_bin_movbe_zero_start +L_1024_from_bin_movbe_zero_end: + repz retq +#ifndef __APPLE__ +.size sp_1024_from_bin_movbe,.-sp_1024_from_bin_movbe +#endif /* __APPLE__ */ +#endif /* !NO_MOVBE_SUPPORT */ +#endif /* WOLFSSL_SP_1024 */ #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/wolfcrypt/src/sp_x86_64_asm.asm b/wolfcrypt/src/sp_x86_64_asm.asm new file mode 100644 index 000000000..f4ed57470 --- /dev/null +++ b/wolfcrypt/src/sp_x86_64_asm.asm @@ -0,0 +1,52719 @@ +; /* sp_x86_64_asm +; * +; * Copyright (C) 2006-2021 wolfSSL Inc. +; * +; * This file is part of wolfSSL. +; * +; * wolfSSL 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. +; * +; * wolfSSL 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. +; * +; * You should have received a copy of the GNU General Public License +; * along with this program; if not, write to the Free Software +; * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA +; */ +IF @Version LT 1200 +; AVX2 instructions not recognized by old versions of MASM +IFNDEF NO_AVX2_SUPPORT +NO_AVX2_SUPPORT = 1 +ENDIF +; MOVBE instruction not recognized by old versions of MASM +IFNDEF NO_MOVBE_SUPPORT +NO_MOVBE_SUPPORT = 1 +ENDIF +ENDIF + +IFNDEF HAVE_INTEL_AVX1 +HAVE_INTEL_AVX1 = 1 +ENDIF +IFNDEF NO_AVX2_SUPPORT +HAVE_INTEL_AVX2 = 1 +ENDIF + +IFNDEF _WIN64 +_WIN64 = 1 +ENDIF + +IFNDEF WOLFSSL_SP_NO_2048 +IFNDEF WOLFSSL_SP_NO_2048 +; /* Read big endian unsigned byte array into r. +; * Uses the bswap instruction. +; * +; * r A single precision integer. +; * size Maximum number of bytes to convert +; * a Byte array. +; * n Number of bytes in array to read. +; */ +_text SEGMENT READONLY PARA +sp_2048_from_bin_bswap PROC + push r12 + push r13 + mov r11, r8 + mov r12, rcx + add r11, r9 + add r12, 256 + xor r13, r13 + jmp L_2048_from_bin_bswap_64_end +L_2048_from_bin_bswap_64_start: + sub r11, 64 + mov rax, QWORD PTR [r11+56] + mov r10, QWORD PTR [r11+48] + bswap rax + bswap r10 + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r10 + mov rax, QWORD PTR [r11+40] + mov r10, QWORD PTR [r11+32] + bswap rax + bswap r10 + mov QWORD PTR [rcx+16], rax + mov QWORD PTR [rcx+24], r10 + mov rax, QWORD PTR [r11+24] + mov r10, QWORD PTR [r11+16] + bswap rax + bswap r10 + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r10 + mov rax, QWORD PTR [r11+8] + mov r10, QWORD PTR [r11] + bswap rax + bswap r10 + mov QWORD PTR [rcx+48], rax + mov QWORD PTR [rcx+56], r10 + add rcx, 64 + sub r9, 64 +L_2048_from_bin_bswap_64_end: + cmp r9, 63 + jg L_2048_from_bin_bswap_64_start + jmp L_2048_from_bin_bswap_8_end +L_2048_from_bin_bswap_8_start: + sub r11, 8 + mov rax, QWORD PTR [r11] + bswap rax + mov QWORD PTR [rcx], rax + add rcx, 8 + sub r9, 8 +L_2048_from_bin_bswap_8_end: + cmp r9, 7 + jg L_2048_from_bin_bswap_8_start + cmp r9, r13 + je L_2048_from_bin_bswap_hi_end + mov r10, r13 + mov rax, r13 +L_2048_from_bin_bswap_hi_start: + mov al, BYTE PTR [r8] + shl r10, 8 + inc r8 + add r10, rax + dec r9 + jg L_2048_from_bin_bswap_hi_start + mov QWORD PTR [rcx], r10 + add rcx, 8 +L_2048_from_bin_bswap_hi_end: + cmp rcx, r12 + je L_2048_from_bin_bswap_zero_end +L_2048_from_bin_bswap_zero_start: + mov QWORD PTR [rcx], r13 + add rcx, 8 + cmp rcx, r12 + jl L_2048_from_bin_bswap_zero_start +L_2048_from_bin_bswap_zero_end: + pop r13 + pop r12 + ret +sp_2048_from_bin_bswap ENDP +_text ENDS +IFNDEF NO_MOVBE_SUPPORT +; /* Read big endian unsigned byte array into r. +; * Uses the movbe instruction which is an optional instruction. +; * +; * r A single precision integer. +; * size Maximum number of bytes to convert +; * a Byte array. +; * n Number of bytes in array to read. +; */ +_text SEGMENT READONLY PARA +sp_2048_from_bin_movbe PROC + push r12 + push r13 + mov r11, r8 + mov r12, rcx + add r11, r9 + add r12, 256 + xor r13, r13 + jmp L_2048_from_bin_movbe_64_end +L_2048_from_bin_movbe_64_start: + sub r11, 64 + movbe rax, QWORD PTR [r11+56] + movbe r10, QWORD PTR [r11+48] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r10 + movbe rax, QWORD PTR [r11+40] + movbe r10, QWORD PTR [r11+32] + mov QWORD PTR [rcx+16], rax + mov QWORD PTR [rcx+24], r10 + movbe rax, QWORD PTR [r11+24] + movbe r10, QWORD PTR [r11+16] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r10 + movbe rax, QWORD PTR [r11+8] + movbe r10, QWORD PTR [r11] + mov QWORD PTR [rcx+48], rax + mov QWORD PTR [rcx+56], r10 + add rcx, 64 + sub r9, 64 +L_2048_from_bin_movbe_64_end: + cmp r9, 63 + jg L_2048_from_bin_movbe_64_start + jmp L_2048_from_bin_movbe_8_end +L_2048_from_bin_movbe_8_start: + sub r11, 8 + movbe rax, QWORD PTR [r11] + mov QWORD PTR [rcx], rax + add rcx, 8 + sub r9, 8 +L_2048_from_bin_movbe_8_end: + cmp r9, 7 + jg L_2048_from_bin_movbe_8_start + cmp r9, r13 + je L_2048_from_bin_movbe_hi_end + mov r10, r13 + mov rax, r13 +L_2048_from_bin_movbe_hi_start: + mov al, BYTE PTR [r8] + shl r10, 8 + inc r8 + add r10, rax + dec r9 + jg L_2048_from_bin_movbe_hi_start + mov QWORD PTR [rcx], r10 + add rcx, 8 +L_2048_from_bin_movbe_hi_end: + cmp rcx, r12 + je L_2048_from_bin_movbe_zero_end +L_2048_from_bin_movbe_zero_start: + mov QWORD PTR [rcx], r13 + add rcx, 8 + cmp rcx, r12 + jl L_2048_from_bin_movbe_zero_start +L_2048_from_bin_movbe_zero_end: + pop r13 + pop r12 + ret +sp_2048_from_bin_movbe ENDP +_text ENDS +ENDIF +; /* Write r as big endian to byte array. +; * Fixed length number of bytes written: 256 +; * Uses the bswap instruction. +; * +; * r A single precision integer. +; * a Byte array. +; */ +_text SEGMENT READONLY PARA +sp_2048_to_bin_bswap PROC + mov rax, QWORD PTR [rcx+248] + mov r8, QWORD PTR [rcx+240] + bswap rax + bswap r8 + mov QWORD PTR [rdx], rax + mov QWORD PTR [rdx+8], r8 + mov rax, QWORD PTR [rcx+232] + mov r8, QWORD PTR [rcx+224] + bswap rax + bswap r8 + mov QWORD PTR [rdx+16], rax + mov QWORD PTR [rdx+24], r8 + mov rax, QWORD PTR [rcx+216] + mov r8, QWORD PTR [rcx+208] + bswap rax + bswap r8 + mov QWORD PTR [rdx+32], rax + mov QWORD PTR [rdx+40], r8 + mov rax, QWORD PTR [rcx+200] + mov r8, QWORD PTR [rcx+192] + bswap rax + bswap r8 + mov QWORD PTR [rdx+48], rax + mov QWORD PTR [rdx+56], r8 + mov rax, QWORD PTR [rcx+184] + mov r8, QWORD PTR [rcx+176] + bswap rax + bswap r8 + mov QWORD PTR [rdx+64], rax + mov QWORD PTR [rdx+72], r8 + mov rax, QWORD PTR [rcx+168] + mov r8, QWORD PTR [rcx+160] + bswap rax + bswap r8 + mov QWORD PTR [rdx+80], rax + mov QWORD PTR [rdx+88], r8 + mov rax, QWORD PTR [rcx+152] + mov r8, QWORD PTR [rcx+144] + bswap rax + bswap r8 + mov QWORD PTR [rdx+96], rax + mov QWORD PTR [rdx+104], r8 + mov rax, QWORD PTR [rcx+136] + mov r8, QWORD PTR [rcx+128] + bswap rax + bswap r8 + mov QWORD PTR [rdx+112], rax + mov QWORD PTR [rdx+120], r8 + mov rax, QWORD PTR [rcx+120] + mov r8, QWORD PTR [rcx+112] + bswap rax + bswap r8 + mov QWORD PTR [rdx+128], rax + mov QWORD PTR [rdx+136], r8 + mov rax, QWORD PTR [rcx+104] + mov r8, QWORD PTR [rcx+96] + bswap rax + bswap r8 + mov QWORD PTR [rdx+144], rax + mov QWORD PTR [rdx+152], r8 + mov rax, QWORD PTR [rcx+88] + mov r8, QWORD PTR [rcx+80] + bswap rax + bswap r8 + mov QWORD PTR [rdx+160], rax + mov QWORD PTR [rdx+168], r8 + mov rax, QWORD PTR [rcx+72] + mov r8, QWORD PTR [rcx+64] + bswap rax + bswap r8 + mov QWORD PTR [rdx+176], rax + mov QWORD PTR [rdx+184], r8 + mov rax, QWORD PTR [rcx+56] + mov r8, QWORD PTR [rcx+48] + bswap rax + bswap r8 + mov QWORD PTR [rdx+192], rax + mov QWORD PTR [rdx+200], r8 + mov rax, QWORD PTR [rcx+40] + mov r8, QWORD PTR [rcx+32] + bswap rax + bswap r8 + mov QWORD PTR [rdx+208], rax + mov QWORD PTR [rdx+216], r8 + mov rax, QWORD PTR [rcx+24] + mov r8, QWORD PTR [rcx+16] + bswap rax + bswap r8 + mov QWORD PTR [rdx+224], rax + mov QWORD PTR [rdx+232], r8 + mov rax, QWORD PTR [rcx+8] + mov r8, QWORD PTR [rcx] + bswap rax + bswap r8 + mov QWORD PTR [rdx+240], rax + mov QWORD PTR [rdx+248], r8 + ret +sp_2048_to_bin_bswap ENDP +_text ENDS +IFNDEF NO_MOVBE_SUPPORT +; /* Write r as big endian to byte array. +; * Fixed length number of bytes written: 256 +; * Uses the movbe instruction which is optional. +; * +; * r A single precision integer. +; * a Byte array. +; */ +_text SEGMENT READONLY PARA +sp_2048_to_bin_movbe PROC + movbe rax, QWORD PTR [rcx+248] + movbe r8, QWORD PTR [rcx+240] + mov QWORD PTR [rdx], rax + mov QWORD PTR [rdx+8], r8 + movbe rax, QWORD PTR [rcx+232] + movbe r8, QWORD PTR [rcx+224] + mov QWORD PTR [rdx+16], rax + mov QWORD PTR [rdx+24], r8 + movbe rax, QWORD PTR [rcx+216] + movbe r8, QWORD PTR [rcx+208] + mov QWORD PTR [rdx+32], rax + mov QWORD PTR [rdx+40], r8 + movbe rax, QWORD PTR [rcx+200] + movbe r8, QWORD PTR [rcx+192] + mov QWORD PTR [rdx+48], rax + mov QWORD PTR [rdx+56], r8 + movbe rax, QWORD PTR [rcx+184] + movbe r8, QWORD PTR [rcx+176] + mov QWORD PTR [rdx+64], rax + mov QWORD PTR [rdx+72], r8 + movbe rax, QWORD PTR [rcx+168] + movbe r8, QWORD PTR [rcx+160] + mov QWORD PTR [rdx+80], rax + mov QWORD PTR [rdx+88], r8 + movbe rax, QWORD PTR [rcx+152] + movbe r8, QWORD PTR [rcx+144] + mov QWORD PTR [rdx+96], rax + mov QWORD PTR [rdx+104], r8 + movbe rax, QWORD PTR [rcx+136] + movbe r8, QWORD PTR [rcx+128] + mov QWORD PTR [rdx+112], rax + mov QWORD PTR [rdx+120], r8 + movbe rax, QWORD PTR [rcx+120] + movbe r8, QWORD PTR [rcx+112] + mov QWORD PTR [rdx+128], rax + mov QWORD PTR [rdx+136], r8 + movbe rax, QWORD PTR [rcx+104] + movbe r8, QWORD PTR [rcx+96] + mov QWORD PTR [rdx+144], rax + mov QWORD PTR [rdx+152], r8 + movbe rax, QWORD PTR [rcx+88] + movbe r8, QWORD PTR [rcx+80] + mov QWORD PTR [rdx+160], rax + mov QWORD PTR [rdx+168], r8 + movbe rax, QWORD PTR [rcx+72] + movbe r8, QWORD PTR [rcx+64] + mov QWORD PTR [rdx+176], rax + mov QWORD PTR [rdx+184], r8 + movbe rax, QWORD PTR [rcx+56] + movbe r8, QWORD PTR [rcx+48] + mov QWORD PTR [rdx+192], rax + mov QWORD PTR [rdx+200], r8 + movbe rax, QWORD PTR [rcx+40] + movbe r8, QWORD PTR [rcx+32] + mov QWORD PTR [rdx+208], rax + mov QWORD PTR [rdx+216], r8 + movbe rax, QWORD PTR [rcx+24] + movbe r8, QWORD PTR [rcx+16] + mov QWORD PTR [rdx+224], rax + mov QWORD PTR [rdx+232], r8 + movbe rax, QWORD PTR [rcx+8] + movbe r8, QWORD PTR [rcx] + mov QWORD PTR [rdx+240], rax + mov QWORD PTR [rdx+248], r8 + ret +sp_2048_to_bin_movbe ENDP +_text ENDS +ENDIF +; /* Multiply a and b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_2048_mul_16 PROC + push r12 + mov r9, rdx + sub rsp, 128 + ; A[0] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9] + xor r12, r12 + mov QWORD PTR [rsp], rax + mov r11, rdx + ; A[0] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[1] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+8] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rsp+8], r11 + ; A[0] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[1] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+8] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[2] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+16] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rsp+16], r12 + ; A[0] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[1] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+8] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[2] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+16] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[3] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+24] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rsp+24], r10 + ; A[0] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[1] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+8] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[2] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+16] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[3] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+24] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[4] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+32] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rsp+32], r11 + ; A[0] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[1] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+8] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[2] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+16] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[3] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+24] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[4] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+32] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[5] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+40] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rsp+40], r12 + ; A[0] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[1] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+8] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[2] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+16] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[3] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+24] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[4] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+32] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[5] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+40] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[6] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+48] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rsp+48], r10 + ; A[0] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[1] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+8] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[2] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+16] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[3] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+24] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[4] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+32] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[5] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+40] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[6] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+48] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[7] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+56] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rsp+56], r11 + ; A[0] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[1] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+8] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[2] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+16] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[3] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+24] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[4] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+32] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[5] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+40] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[6] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+48] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[7] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+56] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[8] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+64] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rsp+64], r12 + ; A[0] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[1] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+8] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[2] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+16] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[3] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+24] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[4] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+32] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[5] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+40] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[6] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+48] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[7] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+56] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[8] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+64] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[9] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+72] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rsp+72], r10 + ; A[0] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[1] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+8] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[2] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+16] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[3] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+24] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[4] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+32] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[5] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+40] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[6] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+48] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[7] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+56] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[8] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+64] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[9] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+72] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[10] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+80] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rsp+80], r11 + ; A[0] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[1] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+8] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[2] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+16] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[3] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+24] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[4] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+32] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[5] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+40] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[6] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+48] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[7] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+56] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[8] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+64] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[9] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+72] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[10] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+80] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[11] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+88] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rsp+88], r12 + ; A[0] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[1] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+8] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[2] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+16] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[3] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+24] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[4] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+32] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[5] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+40] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[6] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+48] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[7] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+56] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[8] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+64] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[9] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+72] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[10] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+80] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[11] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+88] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[12] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+96] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rsp+96], r10 + ; A[0] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[1] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+8] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[2] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+16] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[3] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+24] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[4] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+32] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[5] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+40] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[6] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+48] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[7] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+56] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[8] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+64] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[9] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+72] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[10] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+80] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[11] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+88] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[12] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+96] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[13] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+104] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rsp+104], r11 + ; A[0] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[1] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+8] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[2] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+16] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[3] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+24] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[4] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+32] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[5] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+40] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[6] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+48] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[7] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+56] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[8] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+64] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[9] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+72] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[10] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+80] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[11] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+88] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[12] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+96] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[13] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+104] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[14] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+112] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rsp+112], r12 + ; A[0] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[1] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+8] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[2] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+16] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[3] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+24] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[4] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+32] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[5] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+40] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[6] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+48] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[7] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+56] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[8] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+64] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[9] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+72] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[10] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+80] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[11] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+88] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[12] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+96] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[13] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+104] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[14] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+112] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[15] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+120] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rsp+120], r10 + ; A[1] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+8] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[2] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+16] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[3] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+24] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[4] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+32] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[5] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+40] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[6] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+48] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[7] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+56] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[8] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+64] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[9] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+72] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[10] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+80] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[11] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+88] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[12] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+96] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[13] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+104] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[14] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+112] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[15] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+120] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rcx+128], r11 + ; A[2] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+16] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[3] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+24] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[4] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+32] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[5] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+40] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[6] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+48] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[7] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+56] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[8] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+64] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[9] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+72] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[10] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+80] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[11] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+88] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[12] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+96] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[13] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+104] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[14] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+112] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[15] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+120] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rcx+136], r12 + ; A[3] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+24] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[4] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+32] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[5] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+40] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[6] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+48] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[7] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+56] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[8] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+64] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[9] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+72] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[10] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+80] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[11] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+88] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[12] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+96] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[13] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+104] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[14] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+112] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[15] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+120] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rcx+144], r10 + ; A[4] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+32] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[5] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+40] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[6] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+48] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[7] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+56] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[8] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+64] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[9] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+72] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[10] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+80] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[11] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+88] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[12] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+96] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[13] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+104] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[14] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+112] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[15] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+120] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rcx+152], r11 + ; A[5] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+40] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[6] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+48] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[7] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+56] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[8] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+64] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[9] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+72] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[10] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+80] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[11] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+88] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[12] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+96] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[13] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+104] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[14] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+112] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[15] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+120] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rcx+160], r12 + ; A[6] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+48] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[7] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+56] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[8] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+64] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[9] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+72] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[10] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+80] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[11] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+88] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[12] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+96] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[13] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+104] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[14] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+112] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[15] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+120] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rcx+168], r10 + ; A[7] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+56] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[8] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+64] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[9] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+72] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[10] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+80] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[11] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+88] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[12] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+96] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[13] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+104] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[14] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+112] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[15] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+120] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rcx+176], r11 + ; A[8] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+64] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[9] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+72] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[10] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+80] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[11] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+88] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[12] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+96] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[13] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+104] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[14] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+112] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[15] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+120] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rcx+184], r12 + ; A[9] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+72] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[10] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+80] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[11] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+88] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[12] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+96] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[13] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+104] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[14] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+112] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[15] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+120] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rcx+192], r10 + ; A[10] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+80] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[11] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+88] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[12] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+96] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[13] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+104] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[14] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+112] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[15] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+120] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rcx+200], r11 + ; A[11] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+88] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[12] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+96] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[13] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+104] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[14] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+112] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[15] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+120] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rcx+208], r12 + ; A[12] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+96] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[13] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+104] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[14] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+112] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[15] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+120] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rcx+216], r10 + ; A[13] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+104] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[14] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+112] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[15] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+120] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rcx+224], r11 + ; A[14] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+112] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[15] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+120] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rcx+232], r12 + ; A[15] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+120] + add r10, rax + adc r11, rdx + mov QWORD PTR [rcx+240], r10 + mov QWORD PTR [rcx+248], r11 + mov rax, QWORD PTR [rsp] + mov rdx, QWORD PTR [rsp+8] + mov r10, QWORD PTR [rsp+16] + mov r11, QWORD PTR [rsp+24] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], rdx + mov QWORD PTR [rcx+16], r10 + mov QWORD PTR [rcx+24], r11 + mov rax, QWORD PTR [rsp+32] + mov rdx, QWORD PTR [rsp+40] + mov r10, QWORD PTR [rsp+48] + mov r11, QWORD PTR [rsp+56] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], rdx + mov QWORD PTR [rcx+48], r10 + mov QWORD PTR [rcx+56], r11 + mov rax, QWORD PTR [rsp+64] + mov rdx, QWORD PTR [rsp+72] + mov r10, QWORD PTR [rsp+80] + mov r11, QWORD PTR [rsp+88] + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], rdx + mov QWORD PTR [rcx+80], r10 + mov QWORD PTR [rcx+88], r11 + mov rax, QWORD PTR [rsp+96] + mov rdx, QWORD PTR [rsp+104] + mov r10, QWORD PTR [rsp+112] + mov r11, QWORD PTR [rsp+120] + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], rdx + mov QWORD PTR [rcx+112], r10 + mov QWORD PTR [rcx+120], r11 + add rsp, 128 + pop r12 + ret +sp_2048_mul_16 ENDP +_text ENDS +; /* Square a and put result in r. (r = a * a) +; * +; * r A single precision integer. +; * a A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_2048_sqr_16 PROC + push r12 + push r13 + push r14 + mov r8, rdx + sub rsp, 128 + ; A[0] * A[0] + mov rax, QWORD PTR [r8] + mul rax + xor r11, r11 + mov QWORD PTR [rsp], rax + mov r10, rdx + ; A[0] * A[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r8] + xor r9, r9 + add r10, rax + adc r11, rdx + adc r9, 0 + add r10, rax + adc r11, rdx + adc r9, 0 + mov QWORD PTR [rsp+8], r10 + ; A[0] * A[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r8] + xor r10, r10 + add r11, rax + adc r9, rdx + adc r10, 0 + add r11, rax + adc r9, rdx + adc r10, 0 + ; A[1] * A[1] + mov rax, QWORD PTR [r8+8] + mul rax + add r11, rax + adc r9, rdx + adc r10, 0 + mov QWORD PTR [rsp+16], r11 + ; A[0] * A[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r8] + xor r11, r11 + add r9, rax + adc r10, rdx + adc r11, 0 + add r9, rax + adc r10, rdx + adc r11, 0 + ; A[1] * A[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r8+8] + add r9, rax + adc r10, rdx + adc r11, 0 + add r9, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rsp+24], r9 + ; A[0] * A[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r8] + xor r9, r9 + add r10, rax + adc r11, rdx + adc r9, 0 + add r10, rax + adc r11, rdx + adc r9, 0 + ; A[1] * A[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r8+8] + add r10, rax + adc r11, rdx + adc r9, 0 + add r10, rax + adc r11, rdx + adc r9, 0 + ; A[2] * A[2] + mov rax, QWORD PTR [r8+16] + mul rax + add r10, rax + adc r11, rdx + adc r9, 0 + mov QWORD PTR [rsp+32], r10 + ; A[0] * A[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r8] + xor r10, r10 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r11, r12 + adc r9, r13 + adc r10, r14 + mov QWORD PTR [rsp+40], r11 + ; A[0] * A[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r8] + xor r11, r11 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[3] + mov rax, QWORD PTR [r8+24] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r9, r12 + adc r10, r13 + adc r11, r14 + mov QWORD PTR [rsp+48], r9 + ; A[0] * A[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r8] + xor r9, r9 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r10, r12 + adc r11, r13 + adc r9, r14 + mov QWORD PTR [rsp+56], r10 + ; A[0] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8] + xor r10, r10 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[4] + mov rax, QWORD PTR [r8+32] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r11, r12 + adc r9, r13 + adc r10, r14 + mov QWORD PTR [rsp+64], r11 + ; A[0] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8] + xor r11, r11 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r9, r12 + adc r10, r13 + adc r11, r14 + mov QWORD PTR [rsp+72], r9 + ; A[0] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8] + xor r9, r9 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[5] * A[5] + mov rax, QWORD PTR [r8+40] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r10, r12 + adc r11, r13 + adc r9, r14 + mov QWORD PTR [rsp+80], r10 + ; A[0] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8] + xor r10, r10 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[5] * A[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r8+40] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r11, r12 + adc r9, r13 + adc r10, r14 + mov QWORD PTR [rsp+88], r11 + ; A[0] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8] + xor r11, r11 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[5] * A[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r8+40] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[6] * A[6] + mov rax, QWORD PTR [r8+48] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r9, r12 + adc r10, r13 + adc r11, r14 + mov QWORD PTR [rsp+96], r9 + ; A[0] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8] + xor r9, r9 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[5] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8+40] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[6] * A[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r8+48] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r10, r12 + adc r11, r13 + adc r9, r14 + mov QWORD PTR [rsp+104], r10 + ; A[0] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8] + xor r10, r10 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[5] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+40] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[6] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8+48] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[7] * A[7] + mov rax, QWORD PTR [r8+56] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r11, r12 + adc r9, r13 + adc r10, r14 + mov QWORD PTR [rsp+112], r11 + ; A[0] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8] + xor r11, r11 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[5] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+40] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[6] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+48] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[7] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8+56] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r9, r12 + adc r10, r13 + adc r11, r14 + mov QWORD PTR [rsp+120], r9 + ; A[1] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+8] + xor r9, r9 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[2] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[5] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+40] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[6] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+48] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[7] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+56] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[8] * A[8] + mov rax, QWORD PTR [r8+64] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r10, r12 + adc r11, r13 + adc r9, r14 + mov QWORD PTR [rcx+128], r10 + ; A[2] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+16] + xor r10, r10 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[3] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[5] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8+40] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[6] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+48] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[7] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+56] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[8] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+64] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r11, r12 + adc r9, r13 + adc r10, r14 + mov QWORD PTR [rcx+136], r11 + ; A[3] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+24] + xor r11, r11 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[4] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[5] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+40] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[6] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8+48] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[7] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+56] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[8] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+64] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[9] * A[9] + mov rax, QWORD PTR [r8+72] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r9, r12 + adc r10, r13 + adc r11, r14 + mov QWORD PTR [rcx+144], r9 + ; A[4] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+32] + xor r9, r9 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[5] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+40] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[6] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+48] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[7] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8+56] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[8] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+64] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[9] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+72] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r10, r12 + adc r11, r13 + adc r9, r14 + mov QWORD PTR [rcx+152], r10 + ; A[5] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+40] + xor r10, r10 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[6] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+48] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[7] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+56] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[8] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8+64] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[9] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+72] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[10] * A[10] + mov rax, QWORD PTR [r8+80] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r11, r12 + adc r9, r13 + adc r10, r14 + mov QWORD PTR [rcx+160], r11 + ; A[6] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+48] + xor r11, r11 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[7] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+56] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[8] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+64] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[9] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8+72] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[10] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+80] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r9, r12 + adc r10, r13 + adc r11, r14 + mov QWORD PTR [rcx+168], r9 + ; A[7] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+56] + xor r9, r9 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[8] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+64] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[9] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+72] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[10] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8+80] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[11] * A[11] + mov rax, QWORD PTR [r8+88] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r10, r12 + adc r11, r13 + adc r9, r14 + mov QWORD PTR [rcx+176], r10 + ; A[8] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+64] + xor r10, r10 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[9] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+72] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[10] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+80] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[11] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8+88] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r11, r12 + adc r9, r13 + adc r10, r14 + mov QWORD PTR [rcx+184], r11 + ; A[9] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+72] + xor r11, r11 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[10] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+80] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[11] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+88] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[12] * A[12] + mov rax, QWORD PTR [r8+96] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r9, r12 + adc r10, r13 + adc r11, r14 + mov QWORD PTR [rcx+192], r9 + ; A[10] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+80] + xor r9, r9 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[11] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+88] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[12] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+96] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r10, r12 + adc r11, r13 + adc r9, r14 + mov QWORD PTR [rcx+200], r10 + ; A[11] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+88] + xor r10, r10 + add r11, rax + adc r9, rdx + adc r10, 0 + add r11, rax + adc r9, rdx + adc r10, 0 + ; A[12] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+96] + add r11, rax + adc r9, rdx + adc r10, 0 + add r11, rax + adc r9, rdx + adc r10, 0 + ; A[13] * A[13] + mov rax, QWORD PTR [r8+104] + mul rax + add r11, rax + adc r9, rdx + adc r10, 0 + mov QWORD PTR [rcx+208], r11 + ; A[12] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+96] + xor r11, r11 + add r9, rax + adc r10, rdx + adc r11, 0 + add r9, rax + adc r10, rdx + adc r11, 0 + ; A[13] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+104] + add r9, rax + adc r10, rdx + adc r11, 0 + add r9, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rcx+216], r9 + ; A[13] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+104] + xor r9, r9 + add r10, rax + adc r11, rdx + adc r9, 0 + add r10, rax + adc r11, rdx + adc r9, 0 + ; A[14] * A[14] + mov rax, QWORD PTR [r8+112] + mul rax + add r10, rax + adc r11, rdx + adc r9, 0 + mov QWORD PTR [rcx+224], r10 + ; A[14] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+112] + xor r10, r10 + add r11, rax + adc r9, rdx + adc r10, 0 + add r11, rax + adc r9, rdx + adc r10, 0 + mov QWORD PTR [rcx+232], r11 + ; A[15] * A[15] + mov rax, QWORD PTR [r8+120] + mul rax + add r9, rax + adc r10, rdx + mov QWORD PTR [rcx+240], r9 + mov QWORD PTR [rcx+248], r10 + mov rax, QWORD PTR [rsp] + mov rdx, QWORD PTR [rsp+8] + mov r12, QWORD PTR [rsp+16] + mov r13, QWORD PTR [rsp+24] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], rdx + mov QWORD PTR [rcx+16], r12 + mov QWORD PTR [rcx+24], r13 + mov rax, QWORD PTR [rsp+32] + mov rdx, QWORD PTR [rsp+40] + mov r12, QWORD PTR [rsp+48] + mov r13, QWORD PTR [rsp+56] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], rdx + mov QWORD PTR [rcx+48], r12 + mov QWORD PTR [rcx+56], r13 + mov rax, QWORD PTR [rsp+64] + mov rdx, QWORD PTR [rsp+72] + mov r12, QWORD PTR [rsp+80] + mov r13, QWORD PTR [rsp+88] + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], rdx + mov QWORD PTR [rcx+80], r12 + mov QWORD PTR [rcx+88], r13 + mov rax, QWORD PTR [rsp+96] + mov rdx, QWORD PTR [rsp+104] + mov r12, QWORD PTR [rsp+112] + mov r13, QWORD PTR [rsp+120] + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], rdx + mov QWORD PTR [rcx+112], r12 + mov QWORD PTR [rcx+120], r13 + add rsp, 128 + pop r14 + pop r13 + pop r12 + ret +sp_2048_sqr_16 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Multiply a and b into r. (r = a * b) +; * +; * r Result of multiplication. +; * a First number to multiply. +; * b Second number to multiply. +; */ +_text SEGMENT READONLY PARA +sp_2048_mul_avx2_16 PROC + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + push rdi + mov rbp, r8 + mov r8, rcx + mov r9, rdx + sub rsp, 128 + cmp r9, r8 + mov rbx, rsp + cmovne rbx, r8 + cmp rbp, r8 + cmove rbx, rsp + add r8, 128 + xor rdi, rdi + mov rdx, QWORD PTR [r9] + ; A[0] * B[0] + mulx r11, r10, QWORD PTR [rbp] + ; A[0] * B[1] + mulx r12, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx], r10 + adcx r11, rax + ; A[0] * B[2] + mulx r13, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+8], r11 + adcx r12, rax + ; A[0] * B[3] + mulx r14, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+16], r12 + adcx r13, rax + mov QWORD PTR [rbx+24], r13 + ; A[0] * B[4] + mulx r10, rax, QWORD PTR [rbp+32] + adcx r14, rax + ; A[0] * B[5] + mulx r11, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+32], r14 + adcx r10, rax + ; A[0] * B[6] + mulx r12, rax, QWORD PTR [rbp+48] + mov QWORD PTR [rbx+40], r10 + adcx r11, rax + ; A[0] * B[7] + mulx r13, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+48], r11 + adcx r12, rax + mov QWORD PTR [rbx+56], r12 + ; A[0] * B[8] + mulx r14, rax, QWORD PTR [rbp+64] + adcx r13, rax + ; A[0] * B[9] + mulx r10, rax, QWORD PTR [rbp+72] + mov QWORD PTR [rbx+64], r13 + adcx r14, rax + ; A[0] * B[10] + mulx r11, rax, QWORD PTR [rbp+80] + mov QWORD PTR [rbx+72], r14 + adcx r10, rax + ; A[0] * B[11] + mulx r12, rax, QWORD PTR [rbp+88] + mov QWORD PTR [rbx+80], r10 + adcx r11, rax + mov QWORD PTR [rbx+88], r11 + ; A[0] * B[12] + mulx r13, rax, QWORD PTR [rbp+96] + adcx r12, rax + ; A[0] * B[13] + mulx r14, rax, QWORD PTR [rbp+104] + mov QWORD PTR [rbx+96], r12 + adcx r13, rax + ; A[0] * B[14] + mulx r10, rax, QWORD PTR [rbp+112] + mov QWORD PTR [rbx+104], r13 + adcx r14, rax + ; A[0] * B[15] + mulx r11, rax, QWORD PTR [rbp+120] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adcx r11, rdi + mov r15, rdi + adcx r15, rdi + mov QWORD PTR [rbx+120], r10 + mov QWORD PTR [r8], r11 + mov rdx, QWORD PTR [r9+8] + mov r11, QWORD PTR [rbx+8] + mov r12, QWORD PTR [rbx+16] + mov r13, QWORD PTR [rbx+24] + mov r14, QWORD PTR [rbx+32] + mov r10, QWORD PTR [rbx+40] + ; A[1] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r11, rax + adox r12, rcx + ; A[1] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+8], r11 + adcx r12, rax + adox r13, rcx + ; A[1] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+16], r12 + adcx r13, rax + adox r14, rcx + ; A[1] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+24], r13 + adcx r14, rax + adox r10, rcx + mov QWORD PTR [rbx+32], r14 + mov r11, QWORD PTR [rbx+48] + mov r12, QWORD PTR [rbx+56] + mov r13, QWORD PTR [rbx+64] + mov r14, QWORD PTR [rbx+72] + ; A[1] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r10, rax + adox r11, rcx + ; A[1] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+40], r10 + adcx r11, rax + adox r12, rcx + ; A[1] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [rbx+48], r11 + adcx r12, rax + adox r13, rcx + ; A[1] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+56], r12 + adcx r13, rax + adox r14, rcx + mov QWORD PTR [rbx+64], r13 + mov r10, QWORD PTR [rbx+80] + mov r11, QWORD PTR [rbx+88] + mov r12, QWORD PTR [rbx+96] + mov r13, QWORD PTR [rbx+104] + ; A[1] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r14, rax + adox r10, rcx + ; A[1] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [rbx+72], r14 + adcx r10, rax + adox r11, rcx + ; A[1] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [rbx+80], r10 + adcx r11, rax + adox r12, rcx + ; A[1] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [rbx+88], r11 + adcx r12, rax + adox r13, rcx + mov QWORD PTR [rbx+96], r12 + mov r14, QWORD PTR [rbx+112] + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + ; A[1] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r13, rax + adox r14, rcx + ; A[1] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [rbx+104], r13 + adcx r14, rax + adox r10, rcx + ; A[1] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adox r11, rcx + ; A[1] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [rbx+120], r10 + mov r12, rdi + adcx r11, rax + adox r12, rcx + adcx r12, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8], r11 + mov QWORD PTR [r8+8], r12 + mov rdx, QWORD PTR [r9+16] + mov r12, QWORD PTR [rbx+16] + mov r13, QWORD PTR [rbx+24] + mov r14, QWORD PTR [rbx+32] + mov r10, QWORD PTR [rbx+40] + mov r11, QWORD PTR [rbx+48] + ; A[2] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r12, rax + adox r13, rcx + ; A[2] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+16], r12 + adcx r13, rax + adox r14, rcx + ; A[2] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+24], r13 + adcx r14, rax + adox r10, rcx + ; A[2] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+32], r14 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbx+40], r10 + mov r12, QWORD PTR [rbx+56] + mov r13, QWORD PTR [rbx+64] + mov r14, QWORD PTR [rbx+72] + mov r10, QWORD PTR [rbx+80] + ; A[2] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r11, rax + adox r12, rcx + ; A[2] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+48], r11 + adcx r12, rax + adox r13, rcx + ; A[2] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [rbx+56], r12 + adcx r13, rax + adox r14, rcx + ; A[2] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+64], r13 + adcx r14, rax + adox r10, rcx + mov QWORD PTR [rbx+72], r14 + mov r11, QWORD PTR [rbx+88] + mov r12, QWORD PTR [rbx+96] + mov r13, QWORD PTR [rbx+104] + mov r14, QWORD PTR [rbx+112] + ; A[2] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r10, rax + adox r11, rcx + ; A[2] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [rbx+80], r10 + adcx r11, rax + adox r12, rcx + ; A[2] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [rbx+88], r11 + adcx r12, rax + adox r13, rcx + ; A[2] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [rbx+96], r12 + adcx r13, rax + adox r14, rcx + mov QWORD PTR [rbx+104], r13 + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + ; A[2] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r14, rax + adox r10, rcx + ; A[2] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adox r11, rcx + ; A[2] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [rbx+120], r10 + adcx r11, rax + adox r12, rcx + ; A[2] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8], r11 + mov r13, rdi + adcx r12, rax + adox r13, rcx + adcx r13, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+8], r12 + mov QWORD PTR [r8+16], r13 + mov rdx, QWORD PTR [r9+24] + mov r13, QWORD PTR [rbx+24] + mov r14, QWORD PTR [rbx+32] + mov r10, QWORD PTR [rbx+40] + mov r11, QWORD PTR [rbx+48] + mov r12, QWORD PTR [rbx+56] + ; A[3] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r13, rax + adox r14, rcx + ; A[3] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+24], r13 + adcx r14, rax + adox r10, rcx + ; A[3] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+32], r14 + adcx r10, rax + adox r11, rcx + ; A[3] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+40], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbx+48], r11 + mov r13, QWORD PTR [rbx+64] + mov r14, QWORD PTR [rbx+72] + mov r10, QWORD PTR [rbx+80] + mov r11, QWORD PTR [rbx+88] + ; A[3] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r12, rax + adox r13, rcx + ; A[3] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+56], r12 + adcx r13, rax + adox r14, rcx + ; A[3] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [rbx+64], r13 + adcx r14, rax + adox r10, rcx + ; A[3] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+72], r14 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbx+80], r10 + mov r12, QWORD PTR [rbx+96] + mov r13, QWORD PTR [rbx+104] + mov r14, QWORD PTR [rbx+112] + mov r10, QWORD PTR [rbx+120] + ; A[3] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r11, rax + adox r12, rcx + ; A[3] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [rbx+88], r11 + adcx r12, rax + adox r13, rcx + ; A[3] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [rbx+96], r12 + adcx r13, rax + adox r14, rcx + ; A[3] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [rbx+104], r13 + adcx r14, rax + adox r10, rcx + mov QWORD PTR [rbx+112], r14 + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + mov r13, QWORD PTR [r8+16] + ; A[3] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r10, rax + adox r11, rcx + ; A[3] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [rbx+120], r10 + adcx r11, rax + adox r12, rcx + ; A[3] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8], r11 + adcx r12, rax + adox r13, rcx + ; A[3] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+8], r12 + mov r14, rdi + adcx r13, rax + adox r14, rcx + adcx r14, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+16], r13 + mov QWORD PTR [r8+24], r14 + mov rdx, QWORD PTR [r9+32] + mov r14, QWORD PTR [rbx+32] + mov r10, QWORD PTR [rbx+40] + mov r11, QWORD PTR [rbx+48] + mov r12, QWORD PTR [rbx+56] + mov r13, QWORD PTR [rbx+64] + ; A[4] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r14, rax + adox r10, rcx + ; A[4] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+32], r14 + adcx r10, rax + adox r11, rcx + ; A[4] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+40], r10 + adcx r11, rax + adox r12, rcx + ; A[4] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+48], r11 + adcx r12, rax + adox r13, rcx + mov QWORD PTR [rbx+56], r12 + mov r14, QWORD PTR [rbx+72] + mov r10, QWORD PTR [rbx+80] + mov r11, QWORD PTR [rbx+88] + mov r12, QWORD PTR [rbx+96] + ; A[4] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r13, rax + adox r14, rcx + ; A[4] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+64], r13 + adcx r14, rax + adox r10, rcx + ; A[4] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [rbx+72], r14 + adcx r10, rax + adox r11, rcx + ; A[4] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+80], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbx+88], r11 + mov r13, QWORD PTR [rbx+104] + mov r14, QWORD PTR [rbx+112] + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + ; A[4] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r12, rax + adox r13, rcx + ; A[4] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [rbx+96], r12 + adcx r13, rax + adox r14, rcx + ; A[4] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [rbx+104], r13 + adcx r14, rax + adox r10, rcx + ; A[4] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbx+120], r10 + mov r12, QWORD PTR [r8+8] + mov r13, QWORD PTR [r8+16] + mov r14, QWORD PTR [r8+24] + ; A[4] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r11, rax + adox r12, rcx + ; A[4] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8], r11 + adcx r12, rax + adox r13, rcx + ; A[4] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+8], r12 + adcx r13, rax + adox r14, rcx + ; A[4] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+16], r13 + mov r10, rdi + adcx r14, rax + adox r10, rcx + adcx r10, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+24], r14 + mov QWORD PTR [r8+32], r10 + mov rdx, QWORD PTR [r9+40] + mov r10, QWORD PTR [rbx+40] + mov r11, QWORD PTR [rbx+48] + mov r12, QWORD PTR [rbx+56] + mov r13, QWORD PTR [rbx+64] + mov r14, QWORD PTR [rbx+72] + ; A[5] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r10, rax + adox r11, rcx + ; A[5] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+40], r10 + adcx r11, rax + adox r12, rcx + ; A[5] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+48], r11 + adcx r12, rax + adox r13, rcx + ; A[5] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+56], r12 + adcx r13, rax + adox r14, rcx + mov QWORD PTR [rbx+64], r13 + mov r10, QWORD PTR [rbx+80] + mov r11, QWORD PTR [rbx+88] + mov r12, QWORD PTR [rbx+96] + mov r13, QWORD PTR [rbx+104] + ; A[5] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r14, rax + adox r10, rcx + ; A[5] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+72], r14 + adcx r10, rax + adox r11, rcx + ; A[5] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [rbx+80], r10 + adcx r11, rax + adox r12, rcx + ; A[5] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+88], r11 + adcx r12, rax + adox r13, rcx + mov QWORD PTR [rbx+96], r12 + mov r14, QWORD PTR [rbx+112] + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + ; A[5] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r13, rax + adox r14, rcx + ; A[5] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [rbx+104], r13 + adcx r14, rax + adox r10, rcx + ; A[5] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adox r11, rcx + ; A[5] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [rbx+120], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8], r11 + mov r13, QWORD PTR [r8+16] + mov r14, QWORD PTR [r8+24] + mov r10, QWORD PTR [r8+32] + ; A[5] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r12, rax + adox r13, rcx + ; A[5] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8+8], r12 + adcx r13, rax + adox r14, rcx + ; A[5] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+16], r13 + adcx r14, rax + adox r10, rcx + ; A[5] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+24], r14 + mov r11, rdi + adcx r10, rax + adox r11, rcx + adcx r11, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+32], r10 + mov QWORD PTR [r8+40], r11 + mov rdx, QWORD PTR [r9+48] + mov r11, QWORD PTR [rbx+48] + mov r12, QWORD PTR [rbx+56] + mov r13, QWORD PTR [rbx+64] + mov r14, QWORD PTR [rbx+72] + mov r10, QWORD PTR [rbx+80] + ; A[6] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r11, rax + adox r12, rcx + ; A[6] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+48], r11 + adcx r12, rax + adox r13, rcx + ; A[6] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+56], r12 + adcx r13, rax + adox r14, rcx + ; A[6] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+64], r13 + adcx r14, rax + adox r10, rcx + mov QWORD PTR [rbx+72], r14 + mov r11, QWORD PTR [rbx+88] + mov r12, QWORD PTR [rbx+96] + mov r13, QWORD PTR [rbx+104] + mov r14, QWORD PTR [rbx+112] + ; A[6] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r10, rax + adox r11, rcx + ; A[6] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+80], r10 + adcx r11, rax + adox r12, rcx + ; A[6] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [rbx+88], r11 + adcx r12, rax + adox r13, rcx + ; A[6] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+96], r12 + adcx r13, rax + adox r14, rcx + mov QWORD PTR [rbx+104], r13 + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + mov r13, QWORD PTR [r8+16] + ; A[6] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r14, rax + adox r10, rcx + ; A[6] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adox r11, rcx + ; A[6] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [rbx+120], r10 + adcx r11, rax + adox r12, rcx + ; A[6] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8], r11 + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r8+8], r12 + mov r14, QWORD PTR [r8+24] + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + ; A[6] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r13, rax + adox r14, rcx + ; A[6] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8+16], r13 + adcx r14, rax + adox r10, rcx + ; A[6] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+24], r14 + adcx r10, rax + adox r11, rcx + ; A[6] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+32], r10 + mov r12, rdi + adcx r11, rax + adox r12, rcx + adcx r12, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+40], r11 + mov QWORD PTR [r8+48], r12 + mov rdx, QWORD PTR [r9+56] + mov r12, QWORD PTR [rbx+56] + mov r13, QWORD PTR [rbx+64] + mov r14, QWORD PTR [rbx+72] + mov r10, QWORD PTR [rbx+80] + mov r11, QWORD PTR [rbx+88] + ; A[7] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r12, rax + adox r13, rcx + ; A[7] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+56], r12 + adcx r13, rax + adox r14, rcx + ; A[7] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+64], r13 + adcx r14, rax + adox r10, rcx + ; A[7] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+72], r14 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbx+80], r10 + mov r12, QWORD PTR [rbx+96] + mov r13, QWORD PTR [rbx+104] + mov r14, QWORD PTR [rbx+112] + mov r10, QWORD PTR [rbx+120] + ; A[7] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r11, rax + adox r12, rcx + ; A[7] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+88], r11 + adcx r12, rax + adox r13, rcx + ; A[7] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [rbx+96], r12 + adcx r13, rax + adox r14, rcx + ; A[7] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+104], r13 + adcx r14, rax + adox r10, rcx + mov QWORD PTR [rbx+112], r14 + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + mov r13, QWORD PTR [r8+16] + mov r14, QWORD PTR [r8+24] + ; A[7] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r10, rax + adox r11, rcx + ; A[7] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [rbx+120], r10 + adcx r11, rax + adox r12, rcx + ; A[7] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [r8], r11 + adcx r12, rax + adox r13, rcx + ; A[7] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+8], r12 + adcx r13, rax + adox r14, rcx + mov QWORD PTR [r8+16], r13 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + mov r12, QWORD PTR [r8+48] + ; A[7] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r14, rax + adox r10, rcx + ; A[7] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8+24], r14 + adcx r10, rax + adox r11, rcx + ; A[7] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+32], r10 + adcx r11, rax + adox r12, rcx + ; A[7] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+40], r11 + mov r13, rdi + adcx r12, rax + adox r13, rcx + adcx r13, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+48], r12 + mov QWORD PTR [r8+56], r13 + mov rdx, QWORD PTR [r9+64] + mov r13, QWORD PTR [rbx+64] + mov r14, QWORD PTR [rbx+72] + mov r10, QWORD PTR [rbx+80] + mov r11, QWORD PTR [rbx+88] + mov r12, QWORD PTR [rbx+96] + ; A[8] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r13, rax + adox r14, rcx + ; A[8] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+64], r13 + adcx r14, rax + adox r10, rcx + ; A[8] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+72], r14 + adcx r10, rax + adox r11, rcx + ; A[8] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+80], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbx+88], r11 + mov r13, QWORD PTR [rbx+104] + mov r14, QWORD PTR [rbx+112] + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + ; A[8] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r12, rax + adox r13, rcx + ; A[8] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+96], r12 + adcx r13, rax + adox r14, rcx + ; A[8] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [rbx+104], r13 + adcx r14, rax + adox r10, rcx + ; A[8] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbx+120], r10 + mov r12, QWORD PTR [r8+8] + mov r13, QWORD PTR [r8+16] + mov r14, QWORD PTR [r8+24] + mov r10, QWORD PTR [r8+32] + ; A[8] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r11, rax + adox r12, rcx + ; A[8] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8], r11 + adcx r12, rax + adox r13, rcx + ; A[8] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [r8+8], r12 + adcx r13, rax + adox r14, rcx + ; A[8] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+16], r13 + adcx r14, rax + adox r10, rcx + mov QWORD PTR [r8+24], r14 + mov r11, QWORD PTR [r8+40] + mov r12, QWORD PTR [r8+48] + mov r13, QWORD PTR [r8+56] + ; A[8] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r10, rax + adox r11, rcx + ; A[8] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8+32], r10 + adcx r11, rax + adox r12, rcx + ; A[8] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+40], r11 + adcx r12, rax + adox r13, rcx + ; A[8] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+48], r12 + mov r14, rdi + adcx r13, rax + adox r14, rcx + adcx r14, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+56], r13 + mov QWORD PTR [r8+64], r14 + mov rdx, QWORD PTR [r9+72] + mov r14, QWORD PTR [rbx+72] + mov r10, QWORD PTR [rbx+80] + mov r11, QWORD PTR [rbx+88] + mov r12, QWORD PTR [rbx+96] + mov r13, QWORD PTR [rbx+104] + ; A[9] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r14, rax + adox r10, rcx + ; A[9] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+72], r14 + adcx r10, rax + adox r11, rcx + ; A[9] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+80], r10 + adcx r11, rax + adox r12, rcx + ; A[9] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+88], r11 + adcx r12, rax + adox r13, rcx + mov QWORD PTR [rbx+96], r12 + mov r14, QWORD PTR [rbx+112] + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + ; A[9] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r13, rax + adox r14, rcx + ; A[9] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+104], r13 + adcx r14, rax + adox r10, rcx + ; A[9] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adox r11, rcx + ; A[9] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+120], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8], r11 + mov r13, QWORD PTR [r8+16] + mov r14, QWORD PTR [r8+24] + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + ; A[9] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r12, rax + adox r13, rcx + ; A[9] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8+8], r12 + adcx r13, rax + adox r14, rcx + ; A[9] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [r8+16], r13 + adcx r14, rax + adox r10, rcx + ; A[9] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+24], r14 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+32], r10 + mov r12, QWORD PTR [r8+48] + mov r13, QWORD PTR [r8+56] + mov r14, QWORD PTR [r8+64] + ; A[9] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r11, rax + adox r12, rcx + ; A[9] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8+40], r11 + adcx r12, rax + adox r13, rcx + ; A[9] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+48], r12 + adcx r13, rax + adox r14, rcx + ; A[9] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+56], r13 + mov r10, rdi + adcx r14, rax + adox r10, rcx + adcx r10, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+64], r14 + mov QWORD PTR [r8+72], r10 + mov rdx, QWORD PTR [r9+80] + mov r10, QWORD PTR [rbx+80] + mov r11, QWORD PTR [rbx+88] + mov r12, QWORD PTR [rbx+96] + mov r13, QWORD PTR [rbx+104] + mov r14, QWORD PTR [rbx+112] + ; A[10] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r10, rax + adox r11, rcx + ; A[10] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+80], r10 + adcx r11, rax + adox r12, rcx + ; A[10] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+88], r11 + adcx r12, rax + adox r13, rcx + ; A[10] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+96], r12 + adcx r13, rax + adox r14, rcx + mov QWORD PTR [rbx+104], r13 + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + mov r13, QWORD PTR [r8+16] + ; A[10] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r14, rax + adox r10, rcx + ; A[10] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adox r11, rcx + ; A[10] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [rbx+120], r10 + adcx r11, rax + adox r12, rcx + ; A[10] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [r8], r11 + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r8+8], r12 + mov r14, QWORD PTR [r8+24] + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + mov r12, QWORD PTR [r8+48] + ; A[10] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r13, rax + adox r14, rcx + ; A[10] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8+16], r13 + adcx r14, rax + adox r10, rcx + ; A[10] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [r8+24], r14 + adcx r10, rax + adox r11, rcx + ; A[10] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+32], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+40], r11 + mov r13, QWORD PTR [r8+56] + mov r14, QWORD PTR [r8+64] + mov r10, QWORD PTR [r8+72] + ; A[10] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r12, rax + adox r13, rcx + ; A[10] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8+48], r12 + adcx r13, rax + adox r14, rcx + ; A[10] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+56], r13 + adcx r14, rax + adox r10, rcx + ; A[10] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+64], r14 + mov r11, rdi + adcx r10, rax + adox r11, rcx + adcx r11, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+72], r10 + mov QWORD PTR [r8+80], r11 + mov rdx, QWORD PTR [r9+88] + mov r11, QWORD PTR [rbx+88] + mov r12, QWORD PTR [rbx+96] + mov r13, QWORD PTR [rbx+104] + mov r14, QWORD PTR [rbx+112] + mov r10, QWORD PTR [rbx+120] + ; A[11] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r11, rax + adox r12, rcx + ; A[11] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+88], r11 + adcx r12, rax + adox r13, rcx + ; A[11] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+96], r12 + adcx r13, rax + adox r14, rcx + ; A[11] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+104], r13 + adcx r14, rax + adox r10, rcx + mov QWORD PTR [rbx+112], r14 + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + mov r13, QWORD PTR [r8+16] + mov r14, QWORD PTR [r8+24] + ; A[11] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r10, rax + adox r11, rcx + ; A[11] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+120], r10 + adcx r11, rax + adox r12, rcx + ; A[11] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [r8], r11 + adcx r12, rax + adox r13, rcx + ; A[11] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [r8+8], r12 + adcx r13, rax + adox r14, rcx + mov QWORD PTR [r8+16], r13 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + mov r12, QWORD PTR [r8+48] + mov r13, QWORD PTR [r8+56] + ; A[11] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r14, rax + adox r10, rcx + ; A[11] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8+24], r14 + adcx r10, rax + adox r11, rcx + ; A[11] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [r8+32], r10 + adcx r11, rax + adox r12, rcx + ; A[11] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+40], r11 + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r8+48], r12 + mov r14, QWORD PTR [r8+64] + mov r10, QWORD PTR [r8+72] + mov r11, QWORD PTR [r8+80] + ; A[11] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r13, rax + adox r14, rcx + ; A[11] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8+56], r13 + adcx r14, rax + adox r10, rcx + ; A[11] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+64], r14 + adcx r10, rax + adox r11, rcx + ; A[11] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+72], r10 + mov r12, rdi + adcx r11, rax + adox r12, rcx + adcx r12, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+80], r11 + mov QWORD PTR [r8+88], r12 + mov rdx, QWORD PTR [r9+96] + mov r12, QWORD PTR [rbx+96] + mov r13, QWORD PTR [rbx+104] + mov r14, QWORD PTR [rbx+112] + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + ; A[12] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r12, rax + adox r13, rcx + ; A[12] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+96], r12 + adcx r13, rax + adox r14, rcx + ; A[12] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+104], r13 + adcx r14, rax + adox r10, rcx + ; A[12] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbx+120], r10 + mov r12, QWORD PTR [r8+8] + mov r13, QWORD PTR [r8+16] + mov r14, QWORD PTR [r8+24] + mov r10, QWORD PTR [r8+32] + ; A[12] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r11, rax + adox r12, rcx + ; A[12] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [r8], r11 + adcx r12, rax + adox r13, rcx + ; A[12] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [r8+8], r12 + adcx r13, rax + adox r14, rcx + ; A[12] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [r8+16], r13 + adcx r14, rax + adox r10, rcx + mov QWORD PTR [r8+24], r14 + mov r11, QWORD PTR [r8+40] + mov r12, QWORD PTR [r8+48] + mov r13, QWORD PTR [r8+56] + mov r14, QWORD PTR [r8+64] + ; A[12] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r10, rax + adox r11, rcx + ; A[12] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8+32], r10 + adcx r11, rax + adox r12, rcx + ; A[12] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [r8+40], r11 + adcx r12, rax + adox r13, rcx + ; A[12] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+48], r12 + adcx r13, rax + adox r14, rcx + mov QWORD PTR [r8+56], r13 + mov r10, QWORD PTR [r8+72] + mov r11, QWORD PTR [r8+80] + mov r12, QWORD PTR [r8+88] + ; A[12] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r14, rax + adox r10, rcx + ; A[12] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8+64], r14 + adcx r10, rax + adox r11, rcx + ; A[12] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+72], r10 + adcx r11, rax + adox r12, rcx + ; A[12] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+80], r11 + mov r13, rdi + adcx r12, rax + adox r13, rcx + adcx r13, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+88], r12 + mov QWORD PTR [r8+96], r13 + mov rdx, QWORD PTR [r9+104] + mov r13, QWORD PTR [rbx+104] + mov r14, QWORD PTR [rbx+112] + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + ; A[13] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r13, rax + adox r14, rcx + ; A[13] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+104], r13 + adcx r14, rax + adox r10, rcx + ; A[13] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adox r11, rcx + ; A[13] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+120], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8], r11 + mov r13, QWORD PTR [r8+16] + mov r14, QWORD PTR [r8+24] + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + ; A[13] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r12, rax + adox r13, rcx + ; A[13] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [r8+8], r12 + adcx r13, rax + adox r14, rcx + ; A[13] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [r8+16], r13 + adcx r14, rax + adox r10, rcx + ; A[13] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [r8+24], r14 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+32], r10 + mov r12, QWORD PTR [r8+48] + mov r13, QWORD PTR [r8+56] + mov r14, QWORD PTR [r8+64] + mov r10, QWORD PTR [r8+72] + ; A[13] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r11, rax + adox r12, rcx + ; A[13] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8+40], r11 + adcx r12, rax + adox r13, rcx + ; A[13] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [r8+48], r12 + adcx r13, rax + adox r14, rcx + ; A[13] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+56], r13 + adcx r14, rax + adox r10, rcx + mov QWORD PTR [r8+64], r14 + mov r11, QWORD PTR [r8+80] + mov r12, QWORD PTR [r8+88] + mov r13, QWORD PTR [r8+96] + ; A[13] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r10, rax + adox r11, rcx + ; A[13] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8+72], r10 + adcx r11, rax + adox r12, rcx + ; A[13] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+80], r11 + adcx r12, rax + adox r13, rcx + ; A[13] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+88], r12 + mov r14, rdi + adcx r13, rax + adox r14, rcx + adcx r14, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+96], r13 + mov QWORD PTR [r8+104], r14 + mov rdx, QWORD PTR [r9+112] + mov r14, QWORD PTR [rbx+112] + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + mov r13, QWORD PTR [r8+16] + ; A[14] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r14, rax + adox r10, rcx + ; A[14] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adox r11, rcx + ; A[14] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+120], r10 + adcx r11, rax + adox r12, rcx + ; A[14] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [r8], r11 + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r8+8], r12 + mov r14, QWORD PTR [r8+24] + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + mov r12, QWORD PTR [r8+48] + ; A[14] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r13, rax + adox r14, rcx + ; A[14] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [r8+16], r13 + adcx r14, rax + adox r10, rcx + ; A[14] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [r8+24], r14 + adcx r10, rax + adox r11, rcx + ; A[14] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [r8+32], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+40], r11 + mov r13, QWORD PTR [r8+56] + mov r14, QWORD PTR [r8+64] + mov r10, QWORD PTR [r8+72] + mov r11, QWORD PTR [r8+80] + ; A[14] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r12, rax + adox r13, rcx + ; A[14] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8+48], r12 + adcx r13, rax + adox r14, rcx + ; A[14] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [r8+56], r13 + adcx r14, rax + adox r10, rcx + ; A[14] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+64], r14 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+72], r10 + mov r12, QWORD PTR [r8+88] + mov r13, QWORD PTR [r8+96] + mov r14, QWORD PTR [r8+104] + ; A[14] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r11, rax + adox r12, rcx + ; A[14] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8+80], r11 + adcx r12, rax + adox r13, rcx + ; A[14] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+88], r12 + adcx r13, rax + adox r14, rcx + ; A[14] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+96], r13 + mov r10, rdi + adcx r14, rax + adox r10, rcx + adcx r10, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+104], r14 + mov QWORD PTR [r8+112], r10 + mov rdx, QWORD PTR [r9+120] + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + mov r13, QWORD PTR [r8+16] + mov r14, QWORD PTR [r8+24] + ; A[15] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r10, rax + adox r11, rcx + ; A[15] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+120], r10 + adcx r11, rax + adox r12, rcx + ; A[15] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [r8], r11 + adcx r12, rax + adox r13, rcx + ; A[15] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [r8+8], r12 + adcx r13, rax + adox r14, rcx + mov QWORD PTR [r8+16], r13 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + mov r12, QWORD PTR [r8+48] + mov r13, QWORD PTR [r8+56] + ; A[15] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r14, rax + adox r10, rcx + ; A[15] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [r8+24], r14 + adcx r10, rax + adox r11, rcx + ; A[15] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [r8+32], r10 + adcx r11, rax + adox r12, rcx + ; A[15] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [r8+40], r11 + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r8+48], r12 + mov r14, QWORD PTR [r8+64] + mov r10, QWORD PTR [r8+72] + mov r11, QWORD PTR [r8+80] + mov r12, QWORD PTR [r8+88] + ; A[15] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r13, rax + adox r14, rcx + ; A[15] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8+56], r13 + adcx r14, rax + adox r10, rcx + ; A[15] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [r8+64], r14 + adcx r10, rax + adox r11, rcx + ; A[15] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+72], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+80], r11 + mov r13, QWORD PTR [r8+96] + mov r14, QWORD PTR [r8+104] + mov r10, QWORD PTR [r8+112] + ; A[15] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r12, rax + adox r13, rcx + ; A[15] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8+88], r12 + adcx r13, rax + adox r14, rcx + ; A[15] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+96], r13 + adcx r14, rax + adox r10, rcx + ; A[15] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+104], r14 + mov r11, rdi + adcx r10, rax + adox r11, rcx + adcx r11, r15 + mov QWORD PTR [r8+112], r10 + mov QWORD PTR [r8+120], r11 + sub r8, 128 + cmp r9, r8 + je L_start_2048_mul_avx2_16 + cmp rbp, r8 + jne L_end_2048_mul_avx2_16 +L_start_2048_mul_avx2_16: + vmovdqu xmm0, OWORD PTR [rbx] + vmovups OWORD PTR [r8], xmm0 + vmovdqu xmm0, OWORD PTR [rbx+16] + vmovups OWORD PTR [r8+16], xmm0 + vmovdqu xmm0, OWORD PTR [rbx+32] + vmovups OWORD PTR [r8+32], xmm0 + vmovdqu xmm0, OWORD PTR [rbx+48] + vmovups OWORD PTR [r8+48], xmm0 + vmovdqu xmm0, OWORD PTR [rbx+64] + vmovups OWORD PTR [r8+64], xmm0 + vmovdqu xmm0, OWORD PTR [rbx+80] + vmovups OWORD PTR [r8+80], xmm0 + vmovdqu xmm0, OWORD PTR [rbx+96] + vmovups OWORD PTR [r8+96], xmm0 + vmovdqu xmm0, OWORD PTR [rbx+112] + vmovups OWORD PTR [r8+112], xmm0 +L_end_2048_mul_avx2_16: + add rsp, 128 + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + pop rbp + pop rbx + ret +sp_2048_mul_avx2_16 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Square a and put result in r. (r = a * a) +; * +; * r A single precision integer. +; * a A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_2048_sqr_avx2_16 PROC + push rbp + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + push rbx + mov r8, rcx + mov r9, rdx + sub rsp, 128 + cmp r9, r8 + mov rbp, rsp + cmovne rbp, r8 + add r8, 128 + xor r13, r13 + ; Diagonal 1 + xor r12, r12 + ; A[1] x A[0] + mov rdx, QWORD PTR [r9] + mulx r11, r10, QWORD PTR [r9+8] + ; A[2] x A[0] + mulx rcx, rax, QWORD PTR [r9+16] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbp+8], r10 + mov QWORD PTR [rbp+16], r11 + mov r10, r13 + mov r11, r13 + ; A[3] x A[0] + mulx rcx, rax, QWORD PTR [r9+24] + adcx r12, rax + adox r10, rcx + ; A[4] x A[0] + mulx rcx, rax, QWORD PTR [r9+32] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbp+24], r12 + mov QWORD PTR [rbp+32], r10 + mov r12, r13 + mov r10, r13 + ; A[5] x A[0] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r11, rax + adox r12, rcx + ; A[6] x A[0] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [rbp+40], r11 + mov QWORD PTR [rbp+48], r12 + mov r11, r13 + mov r12, r13 + ; A[7] x A[0] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r10, rax + adox r11, rcx + ; A[8] x A[0] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbp+56], r10 + mov QWORD PTR [rbp+64], r11 + mov r10, r13 + mov r11, r13 + ; A[9] x A[0] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r12, rax + adox r10, rcx + ; A[10] x A[0] + mulx rcx, rax, QWORD PTR [r9+80] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbp+72], r12 + mov QWORD PTR [rbp+80], r10 + mov r12, r13 + mov r10, r13 + ; A[11] x A[0] + mulx rcx, rax, QWORD PTR [r9+88] + adcx r11, rax + adox r12, rcx + ; A[12] x A[0] + mulx rcx, rax, QWORD PTR [r9+96] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [rbp+88], r11 + mov r15, r12 + mov r11, r13 + mov r12, r13 + ; A[13] x A[0] + mulx rcx, rax, QWORD PTR [r9+104] + adcx r10, rax + adox r11, rcx + ; A[14] x A[0] + mulx rcx, rax, QWORD PTR [r9+112] + adcx r11, rax + adox r12, rcx + mov rdi, r10 + mov rsi, r11 + mov r10, r13 + ; A[15] x A[0] + mulx rcx, rax, QWORD PTR [r9+120] + adcx r12, rax + adox r10, rcx + mov rbx, r12 + ; Carry + adcx r10, r13 + mov r14, r13 + adcx r14, r13 + adox r14, r13 + mov QWORD PTR [r8], r10 + ; Diagonal 2 + mov r10, QWORD PTR [rbp+24] + mov r11, QWORD PTR [rbp+32] + mov r12, QWORD PTR [rbp+40] + ; A[2] x A[1] + mov rdx, QWORD PTR [r9+8] + mulx rcx, rax, QWORD PTR [r9+16] + adcx r10, rax + adox r11, rcx + ; A[3] x A[1] + mulx rcx, rax, QWORD PTR [r9+24] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbp+24], r10 + mov QWORD PTR [rbp+32], r11 + mov r10, QWORD PTR [rbp+48] + mov r11, QWORD PTR [rbp+56] + ; A[4] x A[1] + mulx rcx, rax, QWORD PTR [r9+32] + adcx r12, rax + adox r10, rcx + ; A[5] x A[1] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbp+40], r12 + mov QWORD PTR [rbp+48], r10 + mov r12, QWORD PTR [rbp+64] + mov r10, QWORD PTR [rbp+72] + ; A[6] x A[1] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r11, rax + adox r12, rcx + ; A[7] x A[1] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [rbp+56], r11 + mov QWORD PTR [rbp+64], r12 + mov r11, QWORD PTR [rbp+80] + mov r12, QWORD PTR [rbp+88] + ; A[8] x A[1] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r10, rax + adox r11, rcx + ; A[9] x A[1] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbp+72], r10 + mov QWORD PTR [rbp+80], r11 + ; No load %r13 - %r8 + ; No load %r14 - %r9 + ; A[10] x A[1] + mulx rcx, rax, QWORD PTR [r9+80] + adcx r12, rax + adox r15, rcx + ; A[11] x A[1] + mulx rcx, rax, QWORD PTR [r9+88] + adcx r15, rax + adox rdi, rcx + mov QWORD PTR [rbp+88], r12 + ; No store %r13 + ; No load %r15 - %r10 + ; No load %rbx - %r8 + ; A[12] x A[1] + mulx rcx, rax, QWORD PTR [r9+96] + adcx rdi, rax + adox rsi, rcx + ; A[13] x A[1] + mulx rcx, rax, QWORD PTR [r9+104] + adcx rsi, rax + adox rbx, rcx + ; No store %r14 + ; No store %r15 + mov r11, QWORD PTR [r8] + mov r12, r13 + ; A[14] x A[1] + mulx rcx, rax, QWORD PTR [r9+112] + adcx rbx, rax + adox r11, rcx + ; A[15] x A[1] + mulx rcx, rax, QWORD PTR [r9+120] + adcx r11, rax + adox r12, rcx + ; No store %rbx + mov QWORD PTR [r8], r11 + mov r10, r13 + ; A[15] x A[2] + mov rdx, QWORD PTR [r9+16] + mulx rcx, rax, QWORD PTR [r9+120] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+8], r12 + ; Carry + adcx r10, r14 + mov r14, r13 + adcx r14, r13 + adox r14, r13 + mov QWORD PTR [r8+16], r10 + ; Diagonal 3 + mov r10, QWORD PTR [rbp+40] + mov r11, QWORD PTR [rbp+48] + mov r12, QWORD PTR [rbp+56] + ; A[3] x A[2] + mulx rcx, rax, QWORD PTR [r9+24] + adcx r10, rax + adox r11, rcx + ; A[4] x A[2] + mulx rcx, rax, QWORD PTR [r9+32] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbp+40], r10 + mov QWORD PTR [rbp+48], r11 + mov r10, QWORD PTR [rbp+64] + mov r11, QWORD PTR [rbp+72] + ; A[5] x A[2] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r12, rax + adox r10, rcx + ; A[6] x A[2] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbp+56], r12 + mov QWORD PTR [rbp+64], r10 + mov r12, QWORD PTR [rbp+80] + mov r10, QWORD PTR [rbp+88] + ; A[7] x A[2] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r11, rax + adox r12, rcx + ; A[8] x A[2] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [rbp+72], r11 + mov QWORD PTR [rbp+80], r12 + ; No load %r13 - %r9 + ; No load %r14 - %r10 + ; A[9] x A[2] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r10, rax + adox r15, rcx + ; A[10] x A[2] + mulx rcx, rax, QWORD PTR [r9+80] + adcx r15, rax + adox rdi, rcx + mov QWORD PTR [rbp+88], r10 + ; No store %r13 + ; No load %r15 - %r8 + ; No load %rbx - %r9 + ; A[11] x A[2] + mulx rcx, rax, QWORD PTR [r9+88] + adcx rdi, rax + adox rsi, rcx + ; A[12] x A[2] + mulx rcx, rax, QWORD PTR [r9+96] + adcx rsi, rax + adox rbx, rcx + ; No store %r14 + ; No store %r15 + mov r12, QWORD PTR [r8] + mov r10, QWORD PTR [r8+8] + ; A[13] x A[2] + mulx rcx, rax, QWORD PTR [r9+104] + adcx rbx, rax + adox r12, rcx + ; A[14] x A[2] + mulx rcx, rax, QWORD PTR [r9+112] + adcx r12, rax + adox r10, rcx + ; No store %rbx + mov QWORD PTR [r8], r12 + mov r11, QWORD PTR [r8+16] + mov r12, r13 + ; A[14] x A[3] + mov rdx, QWORD PTR [r9+112] + mulx rcx, rax, QWORD PTR [r9+24] + adcx r10, rax + adox r11, rcx + ; A[14] x A[4] + mulx rcx, rax, QWORD PTR [r9+32] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+8], r10 + mov QWORD PTR [r8+16], r11 + mov r10, r13 + ; A[14] x A[5] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+24], r12 + ; Carry + adcx r10, r14 + mov r14, r13 + adcx r14, r13 + adox r14, r13 + mov QWORD PTR [r8+32], r10 + ; Diagonal 4 + mov r10, QWORD PTR [rbp+56] + mov r11, QWORD PTR [rbp+64] + mov r12, QWORD PTR [rbp+72] + ; A[4] x A[3] + mov rdx, QWORD PTR [r9+24] + mulx rcx, rax, QWORD PTR [r9+32] + adcx r10, rax + adox r11, rcx + ; A[5] x A[3] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbp+56], r10 + mov QWORD PTR [rbp+64], r11 + mov r10, QWORD PTR [rbp+80] + mov r11, QWORD PTR [rbp+88] + ; A[6] x A[3] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r12, rax + adox r10, rcx + ; A[7] x A[3] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbp+72], r12 + mov QWORD PTR [rbp+80], r10 + ; No load %r13 - %r10 + ; No load %r14 - %r8 + ; A[8] x A[3] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r11, rax + adox r15, rcx + ; A[9] x A[3] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r15, rax + adox rdi, rcx + mov QWORD PTR [rbp+88], r11 + ; No store %r13 + ; No load %r15 - %r9 + ; No load %rbx - %r10 + ; A[10] x A[3] + mulx rcx, rax, QWORD PTR [r9+80] + adcx rdi, rax + adox rsi, rcx + ; A[11] x A[3] + mulx rcx, rax, QWORD PTR [r9+88] + adcx rsi, rax + adox rbx, rcx + ; No store %r14 + ; No store %r15 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + ; A[12] x A[3] + mulx rcx, rax, QWORD PTR [r9+96] + adcx rbx, rax + adox r10, rcx + ; A[13] x A[3] + mulx rcx, rax, QWORD PTR [r9+104] + adcx r10, rax + adox r11, rcx + ; No store %rbx + mov QWORD PTR [r8], r10 + mov r12, QWORD PTR [r8+16] + mov r10, QWORD PTR [r8+24] + ; A[13] x A[4] + mov rdx, QWORD PTR [r9+104] + mulx rcx, rax, QWORD PTR [r9+32] + adcx r11, rax + adox r12, rcx + ; A[13] x A[5] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+8], r11 + mov QWORD PTR [r8+16], r12 + mov r11, QWORD PTR [r8+32] + mov r12, r13 + ; A[13] x A[6] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r10, rax + adox r11, rcx + ; A[13] x A[7] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+24], r10 + mov QWORD PTR [r8+32], r11 + mov r10, r13 + ; A[13] x A[8] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+40], r12 + ; Carry + adcx r10, r14 + mov r14, r13 + adcx r14, r13 + adox r14, r13 + mov QWORD PTR [r8+48], r10 + ; Diagonal 5 + mov r10, QWORD PTR [rbp+72] + mov r11, QWORD PTR [rbp+80] + mov r12, QWORD PTR [rbp+88] + ; A[5] x A[4] + mov rdx, QWORD PTR [r9+32] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r10, rax + adox r11, rcx + ; A[6] x A[4] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbp+72], r10 + mov QWORD PTR [rbp+80], r11 + ; No load %r13 - %r8 + ; No load %r14 - %r9 + ; A[7] x A[4] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r12, rax + adox r15, rcx + ; A[8] x A[4] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r15, rax + adox rdi, rcx + mov QWORD PTR [rbp+88], r12 + ; No store %r13 + ; No load %r15 - %r10 + ; No load %rbx - %r8 + ; A[9] x A[4] + mulx rcx, rax, QWORD PTR [r9+72] + adcx rdi, rax + adox rsi, rcx + ; A[10] x A[4] + mulx rcx, rax, QWORD PTR [r9+80] + adcx rsi, rax + adox rbx, rcx + ; No store %r14 + ; No store %r15 + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + ; A[11] x A[4] + mulx rcx, rax, QWORD PTR [r9+88] + adcx rbx, rax + adox r11, rcx + ; A[12] x A[4] + mulx rcx, rax, QWORD PTR [r9+96] + adcx r11, rax + adox r12, rcx + ; No store %rbx + mov QWORD PTR [r8], r11 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + ; A[12] x A[5] + mov rdx, QWORD PTR [r9+96] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r12, rax + adox r10, rcx + ; A[12] x A[6] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+8], r12 + mov QWORD PTR [r8+16], r10 + mov r12, QWORD PTR [r8+32] + mov r10, QWORD PTR [r8+40] + ; A[12] x A[7] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r11, rax + adox r12, rcx + ; A[12] x A[8] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+24], r11 + mov QWORD PTR [r8+32], r12 + mov r11, QWORD PTR [r8+48] + mov r12, r13 + ; A[12] x A[9] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r10, rax + adox r11, rcx + ; A[12] x A[10] + mulx rcx, rax, QWORD PTR [r9+80] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+40], r10 + mov QWORD PTR [r8+48], r11 + mov r10, r13 + ; A[12] x A[11] + mulx rcx, rax, QWORD PTR [r9+88] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+56], r12 + ; Carry + adcx r10, r14 + mov r14, r13 + adcx r14, r13 + adox r14, r13 + mov QWORD PTR [r8+64], r10 + ; Diagonal 6 + mov r10, QWORD PTR [rbp+88] + ; No load %r13 - %r9 + ; No load %r14 - %r10 + ; A[6] x A[5] + mov rdx, QWORD PTR [r9+40] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r10, rax + adox r15, rcx + ; A[7] x A[5] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r15, rax + adox rdi, rcx + mov QWORD PTR [rbp+88], r10 + ; No store %r13 + ; No load %r15 - %r8 + ; No load %rbx - %r9 + ; A[8] x A[5] + mulx rcx, rax, QWORD PTR [r9+64] + adcx rdi, rax + adox rsi, rcx + ; A[9] x A[5] + mulx rcx, rax, QWORD PTR [r9+72] + adcx rsi, rax + adox rbx, rcx + ; No store %r14 + ; No store %r15 + mov r12, QWORD PTR [r8] + mov r10, QWORD PTR [r8+8] + ; A[10] x A[5] + mulx rcx, rax, QWORD PTR [r9+80] + adcx rbx, rax + adox r12, rcx + ; A[11] x A[5] + mulx rcx, rax, QWORD PTR [r9+88] + adcx r12, rax + adox r10, rcx + ; No store %rbx + mov QWORD PTR [r8], r12 + mov r11, QWORD PTR [r8+16] + mov r12, QWORD PTR [r8+24] + ; A[11] x A[6] + mov rdx, QWORD PTR [r9+88] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r10, rax + adox r11, rcx + ; A[11] x A[7] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+8], r10 + mov QWORD PTR [r8+16], r11 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + ; A[11] x A[8] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r12, rax + adox r10, rcx + ; A[11] x A[9] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+24], r12 + mov QWORD PTR [r8+32], r10 + mov r12, QWORD PTR [r8+48] + mov r10, QWORD PTR [r8+56] + ; A[11] x A[10] + mulx rcx, rax, QWORD PTR [r9+80] + adcx r11, rax + adox r12, rcx + ; A[13] x A[9] + mov rdx, QWORD PTR [r9+104] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+40], r11 + mov QWORD PTR [r8+48], r12 + mov r11, QWORD PTR [r8+64] + mov r12, r13 + ; A[13] x A[10] + mulx rcx, rax, QWORD PTR [r9+80] + adcx r10, rax + adox r11, rcx + ; A[13] x A[11] + mulx rcx, rax, QWORD PTR [r9+88] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+56], r10 + mov QWORD PTR [r8+64], r11 + mov r10, r13 + ; A[13] x A[12] + mulx rcx, rax, QWORD PTR [r9+96] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+72], r12 + ; Carry + adcx r10, r14 + mov r14, r13 + adcx r14, r13 + adox r14, r13 + mov QWORD PTR [r8+80], r10 + ; Diagonal 7 + ; No load %r14 - %r8 + ; No load %r15 - %r9 + ; No load %rbx - %r10 + ; A[7] x A[6] + mov rdx, QWORD PTR [r9+48] + mulx rcx, rax, QWORD PTR [r9+56] + adcx rdi, rax + adox rsi, rcx + ; A[8] x A[6] + mulx rcx, rax, QWORD PTR [r9+64] + adcx rsi, rax + adox rbx, rcx + ; No store %r14 + ; No store %r15 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + ; A[9] x A[6] + mulx rcx, rax, QWORD PTR [r9+72] + adcx rbx, rax + adox r10, rcx + ; A[10] x A[6] + mulx rcx, rax, QWORD PTR [r9+80] + adcx r10, rax + adox r11, rcx + ; No store %rbx + mov QWORD PTR [r8], r10 + mov r12, QWORD PTR [r8+16] + mov r10, QWORD PTR [r8+24] + ; A[10] x A[7] + mov rdx, QWORD PTR [r9+80] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r11, rax + adox r12, rcx + ; A[10] x A[8] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+8], r11 + mov QWORD PTR [r8+16], r12 + mov r11, QWORD PTR [r8+32] + mov r12, QWORD PTR [r8+40] + ; A[10] x A[9] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r10, rax + adox r11, rcx + ; A[14] x A[6] + mov rdx, QWORD PTR [r9+112] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+24], r10 + mov QWORD PTR [r8+32], r11 + mov r10, QWORD PTR [r8+48] + mov r11, QWORD PTR [r8+56] + ; A[14] x A[7] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r12, rax + adox r10, rcx + ; A[14] x A[8] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+40], r12 + mov QWORD PTR [r8+48], r10 + mov r12, QWORD PTR [r8+64] + mov r10, QWORD PTR [r8+72] + ; A[14] x A[9] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r11, rax + adox r12, rcx + ; A[14] x A[10] + mulx rcx, rax, QWORD PTR [r9+80] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+56], r11 + mov QWORD PTR [r8+64], r12 + mov r11, QWORD PTR [r8+80] + mov r12, r13 + ; A[14] x A[11] + mulx rcx, rax, QWORD PTR [r9+88] + adcx r10, rax + adox r11, rcx + ; A[14] x A[12] + mulx rcx, rax, QWORD PTR [r9+96] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+72], r10 + mov QWORD PTR [r8+80], r11 + mov r10, r13 + ; A[14] x A[13] + mulx rcx, rax, QWORD PTR [r9+104] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+88], r12 + ; Carry + adcx r10, r14 + mov r14, r13 + adcx r14, r13 + adox r14, r13 + mov QWORD PTR [r8+96], r10 + ; Diagonal 8 + ; No load %rbx - %r8 + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + ; A[8] x A[7] + mov rdx, QWORD PTR [r9+56] + mulx rcx, rax, QWORD PTR [r9+64] + adcx rbx, rax + adox r11, rcx + ; A[9] x A[7] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r11, rax + adox r12, rcx + ; No store %rbx + mov QWORD PTR [r8], r11 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + ; A[9] x A[8] + mov rdx, QWORD PTR [r9+64] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r12, rax + adox r10, rcx + ; A[15] x A[3] + mov rdx, QWORD PTR [r9+120] + mulx rcx, rax, QWORD PTR [r9+24] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+8], r12 + mov QWORD PTR [r8+16], r10 + mov r12, QWORD PTR [r8+32] + mov r10, QWORD PTR [r8+40] + ; A[15] x A[4] + mulx rcx, rax, QWORD PTR [r9+32] + adcx r11, rax + adox r12, rcx + ; A[15] x A[5] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+24], r11 + mov QWORD PTR [r8+32], r12 + mov r11, QWORD PTR [r8+48] + mov r12, QWORD PTR [r8+56] + ; A[15] x A[6] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r10, rax + adox r11, rcx + ; A[15] x A[7] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+40], r10 + mov QWORD PTR [r8+48], r11 + mov r10, QWORD PTR [r8+64] + mov r11, QWORD PTR [r8+72] + ; A[15] x A[8] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r12, rax + adox r10, rcx + ; A[15] x A[9] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+56], r12 + mov QWORD PTR [r8+64], r10 + mov r12, QWORD PTR [r8+80] + mov r10, QWORD PTR [r8+88] + ; A[15] x A[10] + mulx rcx, rax, QWORD PTR [r9+80] + adcx r11, rax + adox r12, rcx + ; A[15] x A[11] + mulx rcx, rax, QWORD PTR [r9+88] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+72], r11 + mov QWORD PTR [r8+80], r12 + mov r11, QWORD PTR [r8+96] + mov r12, r13 + ; A[15] x A[12] + mulx rcx, rax, QWORD PTR [r9+96] + adcx r10, rax + adox r11, rcx + ; A[15] x A[13] + mulx rcx, rax, QWORD PTR [r9+104] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+88], r10 + mov QWORD PTR [r8+96], r11 + mov r10, r13 + ; A[15] x A[14] + mulx rcx, rax, QWORD PTR [r9+112] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+104], r12 + ; Carry + adcx r10, r14 + mov r14, r13 + adcx r14, r13 + adox r14, r13 + mov QWORD PTR [r8+112], r10 + mov QWORD PTR [r8+120], r14 + ; Double and Add in A[i] x A[i] + mov r11, QWORD PTR [rbp+8] + ; A[0] x A[0] + mov rdx, QWORD PTR [r9] + mulx rcx, rax, rdx + mov QWORD PTR [rbp], rax + adox r11, r11 + adcx r11, rcx + mov QWORD PTR [rbp+8], r11 + mov r10, QWORD PTR [rbp+16] + mov r11, QWORD PTR [rbp+24] + ; A[1] x A[1] + mov rdx, QWORD PTR [r9+8] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [rbp+16], r10 + mov QWORD PTR [rbp+24], r11 + mov r10, QWORD PTR [rbp+32] + mov r11, QWORD PTR [rbp+40] + ; A[2] x A[2] + mov rdx, QWORD PTR [r9+16] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [rbp+32], r10 + mov QWORD PTR [rbp+40], r11 + mov r10, QWORD PTR [rbp+48] + mov r11, QWORD PTR [rbp+56] + ; A[3] x A[3] + mov rdx, QWORD PTR [r9+24] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [rbp+48], r10 + mov QWORD PTR [rbp+56], r11 + mov r10, QWORD PTR [rbp+64] + mov r11, QWORD PTR [rbp+72] + ; A[4] x A[4] + mov rdx, QWORD PTR [r9+32] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [rbp+64], r10 + mov QWORD PTR [rbp+72], r11 + mov r10, QWORD PTR [rbp+80] + mov r11, QWORD PTR [rbp+88] + ; A[5] x A[5] + mov rdx, QWORD PTR [r9+40] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [rbp+80], r10 + mov QWORD PTR [rbp+88], r11 + ; A[6] x A[6] + mov rdx, QWORD PTR [r9+48] + mulx rcx, rax, rdx + adox r15, r15 + adox rdi, rdi + adcx r15, rax + adcx rdi, rcx + ; A[7] x A[7] + mov rdx, QWORD PTR [r9+56] + mulx rcx, rax, rdx + adox rsi, rsi + adox rbx, rbx + adcx rsi, rax + adcx rbx, rcx + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + ; A[8] x A[8] + mov rdx, QWORD PTR [r9+64] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [r8], r10 + mov QWORD PTR [r8+8], r11 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + ; A[9] x A[9] + mov rdx, QWORD PTR [r9+72] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [r8+16], r10 + mov QWORD PTR [r8+24], r11 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + ; A[10] x A[10] + mov rdx, QWORD PTR [r9+80] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [r8+32], r10 + mov QWORD PTR [r8+40], r11 + mov r10, QWORD PTR [r8+48] + mov r11, QWORD PTR [r8+56] + ; A[11] x A[11] + mov rdx, QWORD PTR [r9+88] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [r8+48], r10 + mov QWORD PTR [r8+56], r11 + mov r10, QWORD PTR [r8+64] + mov r11, QWORD PTR [r8+72] + ; A[12] x A[12] + mov rdx, QWORD PTR [r9+96] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [r8+64], r10 + mov QWORD PTR [r8+72], r11 + mov r10, QWORD PTR [r8+80] + mov r11, QWORD PTR [r8+88] + ; A[13] x A[13] + mov rdx, QWORD PTR [r9+104] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [r8+80], r10 + mov QWORD PTR [r8+88], r11 + mov r10, QWORD PTR [r8+96] + mov r11, QWORD PTR [r8+104] + ; A[14] x A[14] + mov rdx, QWORD PTR [r9+112] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [r8+96], r10 + mov QWORD PTR [r8+104], r11 + mov r10, QWORD PTR [r8+112] + mov r11, QWORD PTR [r8+120] + ; A[15] x A[15] + mov rdx, QWORD PTR [r9+120] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [r8+112], r10 + mov QWORD PTR [r8+120], r11 + mov QWORD PTR [r8+-32], r15 + mov QWORD PTR [r8+-24], rdi + mov QWORD PTR [r8+-16], rsi + mov QWORD PTR [r8+-8], rbx + sub r8, 128 + cmp r9, r8 + jne L_end_2048_sqr_avx2_16 + vmovdqu xmm0, OWORD PTR [rbp] + vmovups OWORD PTR [r8], xmm0 + vmovdqu xmm0, OWORD PTR [rbp+16] + vmovups OWORD PTR [r8+16], xmm0 + vmovdqu xmm0, OWORD PTR [rbp+32] + vmovups OWORD PTR [r8+32], xmm0 + vmovdqu xmm0, OWORD PTR [rbp+48] + vmovups OWORD PTR [r8+48], xmm0 + vmovdqu xmm0, OWORD PTR [rbp+64] + vmovups OWORD PTR [r8+64], xmm0 + vmovdqu xmm0, OWORD PTR [rbp+80] + vmovups OWORD PTR [r8+80], xmm0 +L_end_2048_sqr_avx2_16: + add rsp, 128 + pop rbx + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + pop rbp + ret +sp_2048_sqr_avx2_16 ENDP +_text ENDS +ENDIF +; /* Add b to a into r. (r = a + b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_2048_add_16 PROC + ; Add + mov r9, QWORD PTR [rdx] + xor rax, rax + add r9, QWORD PTR [r8] + mov r10, QWORD PTR [rdx+8] + mov QWORD PTR [rcx], r9 + adc r10, QWORD PTR [r8+8] + mov r9, QWORD PTR [rdx+16] + mov QWORD PTR [rcx+8], r10 + adc r9, QWORD PTR [r8+16] + mov r10, QWORD PTR [rdx+24] + mov QWORD PTR [rcx+16], r9 + adc r10, QWORD PTR [r8+24] + mov r9, QWORD PTR [rdx+32] + mov QWORD PTR [rcx+24], r10 + adc r9, QWORD PTR [r8+32] + mov r10, QWORD PTR [rdx+40] + mov QWORD PTR [rcx+32], r9 + adc r10, QWORD PTR [r8+40] + mov r9, QWORD PTR [rdx+48] + mov QWORD PTR [rcx+40], r10 + adc r9, QWORD PTR [r8+48] + mov r10, QWORD PTR [rdx+56] + mov QWORD PTR [rcx+48], r9 + adc r10, QWORD PTR [r8+56] + mov r9, QWORD PTR [rdx+64] + mov QWORD PTR [rcx+56], r10 + adc r9, QWORD PTR [r8+64] + mov r10, QWORD PTR [rdx+72] + mov QWORD PTR [rcx+64], r9 + adc r10, QWORD PTR [r8+72] + mov r9, QWORD PTR [rdx+80] + mov QWORD PTR [rcx+72], r10 + adc r9, QWORD PTR [r8+80] + mov r10, QWORD PTR [rdx+88] + mov QWORD PTR [rcx+80], r9 + adc r10, QWORD PTR [r8+88] + mov r9, QWORD PTR [rdx+96] + mov QWORD PTR [rcx+88], r10 + adc r9, QWORD PTR [r8+96] + mov r10, QWORD PTR [rdx+104] + mov QWORD PTR [rcx+96], r9 + adc r10, QWORD PTR [r8+104] + mov r9, QWORD PTR [rdx+112] + mov QWORD PTR [rcx+104], r10 + adc r9, QWORD PTR [r8+112] + mov r10, QWORD PTR [rdx+120] + mov QWORD PTR [rcx+112], r9 + adc r10, QWORD PTR [r8+120] + mov QWORD PTR [rcx+120], r10 + adc rax, 0 + ret +sp_2048_add_16 ENDP +_text ENDS +; /* Sub b from a into a. (a -= b) +; * +; * a A single precision integer and result. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_2048_sub_in_place_32 PROC + mov r8, QWORD PTR [rcx] + xor rax, rax + sub r8, QWORD PTR [rdx] + mov r9, QWORD PTR [rcx+8] + mov QWORD PTR [rcx], r8 + sbb r9, QWORD PTR [rdx+8] + mov r8, QWORD PTR [rcx+16] + mov QWORD PTR [rcx+8], r9 + sbb r8, QWORD PTR [rdx+16] + mov r9, QWORD PTR [rcx+24] + mov QWORD PTR [rcx+16], r8 + sbb r9, QWORD PTR [rdx+24] + mov r8, QWORD PTR [rcx+32] + mov QWORD PTR [rcx+24], r9 + sbb r8, QWORD PTR [rdx+32] + mov r9, QWORD PTR [rcx+40] + mov QWORD PTR [rcx+32], r8 + sbb r9, QWORD PTR [rdx+40] + mov r8, QWORD PTR [rcx+48] + mov QWORD PTR [rcx+40], r9 + sbb r8, QWORD PTR [rdx+48] + mov r9, QWORD PTR [rcx+56] + mov QWORD PTR [rcx+48], r8 + sbb r9, QWORD PTR [rdx+56] + mov r8, QWORD PTR [rcx+64] + mov QWORD PTR [rcx+56], r9 + sbb r8, QWORD PTR [rdx+64] + mov r9, QWORD PTR [rcx+72] + mov QWORD PTR [rcx+64], r8 + sbb r9, QWORD PTR [rdx+72] + mov r8, QWORD PTR [rcx+80] + mov QWORD PTR [rcx+72], r9 + sbb r8, QWORD PTR [rdx+80] + mov r9, QWORD PTR [rcx+88] + mov QWORD PTR [rcx+80], r8 + sbb r9, QWORD PTR [rdx+88] + mov r8, QWORD PTR [rcx+96] + mov QWORD PTR [rcx+88], r9 + sbb r8, QWORD PTR [rdx+96] + mov r9, QWORD PTR [rcx+104] + mov QWORD PTR [rcx+96], r8 + sbb r9, QWORD PTR [rdx+104] + mov r8, QWORD PTR [rcx+112] + mov QWORD PTR [rcx+104], r9 + sbb r8, QWORD PTR [rdx+112] + mov r9, QWORD PTR [rcx+120] + mov QWORD PTR [rcx+112], r8 + sbb r9, QWORD PTR [rdx+120] + mov r8, QWORD PTR [rcx+128] + mov QWORD PTR [rcx+120], r9 + sbb r8, QWORD PTR [rdx+128] + mov r9, QWORD PTR [rcx+136] + mov QWORD PTR [rcx+128], r8 + sbb r9, QWORD PTR [rdx+136] + mov r8, QWORD PTR [rcx+144] + mov QWORD PTR [rcx+136], r9 + sbb r8, QWORD PTR [rdx+144] + mov r9, QWORD PTR [rcx+152] + mov QWORD PTR [rcx+144], r8 + sbb r9, QWORD PTR [rdx+152] + mov r8, QWORD PTR [rcx+160] + mov QWORD PTR [rcx+152], r9 + sbb r8, QWORD PTR [rdx+160] + mov r9, QWORD PTR [rcx+168] + mov QWORD PTR [rcx+160], r8 + sbb r9, QWORD PTR [rdx+168] + mov r8, QWORD PTR [rcx+176] + mov QWORD PTR [rcx+168], r9 + sbb r8, QWORD PTR [rdx+176] + mov r9, QWORD PTR [rcx+184] + mov QWORD PTR [rcx+176], r8 + sbb r9, QWORD PTR [rdx+184] + mov r8, QWORD PTR [rcx+192] + mov QWORD PTR [rcx+184], r9 + sbb r8, QWORD PTR [rdx+192] + mov r9, QWORD PTR [rcx+200] + mov QWORD PTR [rcx+192], r8 + sbb r9, QWORD PTR [rdx+200] + mov r8, QWORD PTR [rcx+208] + mov QWORD PTR [rcx+200], r9 + sbb r8, QWORD PTR [rdx+208] + mov r9, QWORD PTR [rcx+216] + mov QWORD PTR [rcx+208], r8 + sbb r9, QWORD PTR [rdx+216] + mov r8, QWORD PTR [rcx+224] + mov QWORD PTR [rcx+216], r9 + sbb r8, QWORD PTR [rdx+224] + mov r9, QWORD PTR [rcx+232] + mov QWORD PTR [rcx+224], r8 + sbb r9, QWORD PTR [rdx+232] + mov r8, QWORD PTR [rcx+240] + mov QWORD PTR [rcx+232], r9 + sbb r8, QWORD PTR [rdx+240] + mov r9, QWORD PTR [rcx+248] + mov QWORD PTR [rcx+240], r8 + sbb r9, QWORD PTR [rdx+248] + mov QWORD PTR [rcx+248], r9 + sbb rax, 0 + ret +sp_2048_sub_in_place_32 ENDP +_text ENDS +; /* Add b to a into r. (r = a + b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_2048_add_32 PROC + ; Add + mov r9, QWORD PTR [rdx] + xor rax, rax + add r9, QWORD PTR [r8] + mov r10, QWORD PTR [rdx+8] + mov QWORD PTR [rcx], r9 + adc r10, QWORD PTR [r8+8] + mov r9, QWORD PTR [rdx+16] + mov QWORD PTR [rcx+8], r10 + adc r9, QWORD PTR [r8+16] + mov r10, QWORD PTR [rdx+24] + mov QWORD PTR [rcx+16], r9 + adc r10, QWORD PTR [r8+24] + mov r9, QWORD PTR [rdx+32] + mov QWORD PTR [rcx+24], r10 + adc r9, QWORD PTR [r8+32] + mov r10, QWORD PTR [rdx+40] + mov QWORD PTR [rcx+32], r9 + adc r10, QWORD PTR [r8+40] + mov r9, QWORD PTR [rdx+48] + mov QWORD PTR [rcx+40], r10 + adc r9, QWORD PTR [r8+48] + mov r10, QWORD PTR [rdx+56] + mov QWORD PTR [rcx+48], r9 + adc r10, QWORD PTR [r8+56] + mov r9, QWORD PTR [rdx+64] + mov QWORD PTR [rcx+56], r10 + adc r9, QWORD PTR [r8+64] + mov r10, QWORD PTR [rdx+72] + mov QWORD PTR [rcx+64], r9 + adc r10, QWORD PTR [r8+72] + mov r9, QWORD PTR [rdx+80] + mov QWORD PTR [rcx+72], r10 + adc r9, QWORD PTR [r8+80] + mov r10, QWORD PTR [rdx+88] + mov QWORD PTR [rcx+80], r9 + adc r10, QWORD PTR [r8+88] + mov r9, QWORD PTR [rdx+96] + mov QWORD PTR [rcx+88], r10 + adc r9, QWORD PTR [r8+96] + mov r10, QWORD PTR [rdx+104] + mov QWORD PTR [rcx+96], r9 + adc r10, QWORD PTR [r8+104] + mov r9, QWORD PTR [rdx+112] + mov QWORD PTR [rcx+104], r10 + adc r9, QWORD PTR [r8+112] + mov r10, QWORD PTR [rdx+120] + mov QWORD PTR [rcx+112], r9 + adc r10, QWORD PTR [r8+120] + mov r9, QWORD PTR [rdx+128] + mov QWORD PTR [rcx+120], r10 + adc r9, QWORD PTR [r8+128] + mov r10, QWORD PTR [rdx+136] + mov QWORD PTR [rcx+128], r9 + adc r10, QWORD PTR [r8+136] + mov r9, QWORD PTR [rdx+144] + mov QWORD PTR [rcx+136], r10 + adc r9, QWORD PTR [r8+144] + mov r10, QWORD PTR [rdx+152] + mov QWORD PTR [rcx+144], r9 + adc r10, QWORD PTR [r8+152] + mov r9, QWORD PTR [rdx+160] + mov QWORD PTR [rcx+152], r10 + adc r9, QWORD PTR [r8+160] + mov r10, QWORD PTR [rdx+168] + mov QWORD PTR [rcx+160], r9 + adc r10, QWORD PTR [r8+168] + mov r9, QWORD PTR [rdx+176] + mov QWORD PTR [rcx+168], r10 + adc r9, QWORD PTR [r8+176] + mov r10, QWORD PTR [rdx+184] + mov QWORD PTR [rcx+176], r9 + adc r10, QWORD PTR [r8+184] + mov r9, QWORD PTR [rdx+192] + mov QWORD PTR [rcx+184], r10 + adc r9, QWORD PTR [r8+192] + mov r10, QWORD PTR [rdx+200] + mov QWORD PTR [rcx+192], r9 + adc r10, QWORD PTR [r8+200] + mov r9, QWORD PTR [rdx+208] + mov QWORD PTR [rcx+200], r10 + adc r9, QWORD PTR [r8+208] + mov r10, QWORD PTR [rdx+216] + mov QWORD PTR [rcx+208], r9 + adc r10, QWORD PTR [r8+216] + mov r9, QWORD PTR [rdx+224] + mov QWORD PTR [rcx+216], r10 + adc r9, QWORD PTR [r8+224] + mov r10, QWORD PTR [rdx+232] + mov QWORD PTR [rcx+224], r9 + adc r10, QWORD PTR [r8+232] + mov r9, QWORD PTR [rdx+240] + mov QWORD PTR [rcx+232], r10 + adc r9, QWORD PTR [r8+240] + mov r10, QWORD PTR [rdx+248] + mov QWORD PTR [rcx+240], r9 + adc r10, QWORD PTR [r8+248] + mov QWORD PTR [rcx+248], r10 + adc rax, 0 + ret +sp_2048_add_32 ENDP +_text ENDS +; /* Multiply a and b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_2048_mul_32 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + sub rsp, 808 + mov QWORD PTR [rsp+768], rcx + mov QWORD PTR [rsp+776], rdx + mov QWORD PTR [rsp+784], r8 + lea r12, QWORD PTR [rsp+512] + lea r14, QWORD PTR [rdx+128] + ; Add + mov rax, QWORD PTR [rdx] + xor r15, r15 + add rax, QWORD PTR [r14] + mov r9, QWORD PTR [rdx+8] + mov QWORD PTR [r12], rax + adc r9, QWORD PTR [r14+8] + mov r10, QWORD PTR [rdx+16] + mov QWORD PTR [r12+8], r9 + adc r10, QWORD PTR [r14+16] + mov rax, QWORD PTR [rdx+24] + mov QWORD PTR [r12+16], r10 + adc rax, QWORD PTR [r14+24] + mov r9, QWORD PTR [rdx+32] + mov QWORD PTR [r12+24], rax + adc r9, QWORD PTR [r14+32] + mov r10, QWORD PTR [rdx+40] + mov QWORD PTR [r12+32], r9 + adc r10, QWORD PTR [r14+40] + mov rax, QWORD PTR [rdx+48] + mov QWORD PTR [r12+40], r10 + adc rax, QWORD PTR [r14+48] + mov r9, QWORD PTR [rdx+56] + mov QWORD PTR [r12+48], rax + adc r9, QWORD PTR [r14+56] + mov r10, QWORD PTR [rdx+64] + mov QWORD PTR [r12+56], r9 + adc r10, QWORD PTR [r14+64] + mov rax, QWORD PTR [rdx+72] + mov QWORD PTR [r12+64], r10 + adc rax, QWORD PTR [r14+72] + mov r9, QWORD PTR [rdx+80] + mov QWORD PTR [r12+72], rax + adc r9, QWORD PTR [r14+80] + mov r10, QWORD PTR [rdx+88] + mov QWORD PTR [r12+80], r9 + adc r10, QWORD PTR [r14+88] + mov rax, QWORD PTR [rdx+96] + mov QWORD PTR [r12+88], r10 + adc rax, QWORD PTR [r14+96] + mov r9, QWORD PTR [rdx+104] + mov QWORD PTR [r12+96], rax + adc r9, QWORD PTR [r14+104] + mov r10, QWORD PTR [rdx+112] + mov QWORD PTR [r12+104], r9 + adc r10, QWORD PTR [r14+112] + mov rax, QWORD PTR [rdx+120] + mov QWORD PTR [r12+112], r10 + adc rax, QWORD PTR [r14+120] + mov QWORD PTR [r12+120], rax + adc r15, 0 + mov QWORD PTR [rsp+792], r15 + lea r13, QWORD PTR [rsp+640] + lea r14, QWORD PTR [r8+128] + ; Add + mov rax, QWORD PTR [r8] + xor rdi, rdi + add rax, QWORD PTR [r14] + mov r9, QWORD PTR [r8+8] + mov QWORD PTR [r13], rax + adc r9, QWORD PTR [r14+8] + mov r10, QWORD PTR [r8+16] + mov QWORD PTR [r13+8], r9 + adc r10, QWORD PTR [r14+16] + mov rax, QWORD PTR [r8+24] + mov QWORD PTR [r13+16], r10 + adc rax, QWORD PTR [r14+24] + mov r9, QWORD PTR [r8+32] + mov QWORD PTR [r13+24], rax + adc r9, QWORD PTR [r14+32] + mov r10, QWORD PTR [r8+40] + mov QWORD PTR [r13+32], r9 + adc r10, QWORD PTR [r14+40] + mov rax, QWORD PTR [r8+48] + mov QWORD PTR [r13+40], r10 + adc rax, QWORD PTR [r14+48] + mov r9, QWORD PTR [r8+56] + mov QWORD PTR [r13+48], rax + adc r9, QWORD PTR [r14+56] + mov r10, QWORD PTR [r8+64] + mov QWORD PTR [r13+56], r9 + adc r10, QWORD PTR [r14+64] + mov rax, QWORD PTR [r8+72] + mov QWORD PTR [r13+64], r10 + adc rax, QWORD PTR [r14+72] + mov r9, QWORD PTR [r8+80] + mov QWORD PTR [r13+72], rax + adc r9, QWORD PTR [r14+80] + mov r10, QWORD PTR [r8+88] + mov QWORD PTR [r13+80], r9 + adc r10, QWORD PTR [r14+88] + mov rax, QWORD PTR [r8+96] + mov QWORD PTR [r13+88], r10 + adc rax, QWORD PTR [r14+96] + mov r9, QWORD PTR [r8+104] + mov QWORD PTR [r13+96], rax + adc r9, QWORD PTR [r14+104] + mov r10, QWORD PTR [r8+112] + mov QWORD PTR [r13+104], r9 + adc r10, QWORD PTR [r14+112] + mov rax, QWORD PTR [r8+120] + mov QWORD PTR [r13+112], r10 + adc rax, QWORD PTR [r14+120] + mov QWORD PTR [r13+120], rax + adc rdi, 0 + mov QWORD PTR [rsp+800], rdi + mov r8, r13 + mov rdx, r12 + mov rcx, rsp + call sp_2048_mul_16 + mov r8, QWORD PTR [rsp+784] + mov rdx, QWORD PTR [rsp+776] + lea rcx, QWORD PTR [rsp+256] + add r8, 128 + add rdx, 128 + call sp_2048_mul_16 + mov r8, QWORD PTR [rsp+784] + mov rdx, QWORD PTR [rsp+776] + mov rcx, QWORD PTR [rsp+768] + call sp_2048_mul_16 +IFDEF _WIN64 + mov r8, QWORD PTR [rsp+784] + mov rdx, QWORD PTR [rsp+776] + mov rcx, QWORD PTR [rsp+768] +ENDIF + mov r15, QWORD PTR [rsp+792] + mov rdi, QWORD PTR [rsp+800] + mov rsi, QWORD PTR [rsp+768] + mov r11, r15 + lea r12, QWORD PTR [rsp+512] + lea r13, QWORD PTR [rsp+640] + and r11, rdi + neg r15 + neg rdi + add rsi, 256 + mov rax, QWORD PTR [r12] + mov r9, QWORD PTR [r13] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12], rax + mov QWORD PTR [r13], r9 + mov rax, QWORD PTR [r12+8] + mov r9, QWORD PTR [r13+8] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+8], rax + mov QWORD PTR [r13+8], r9 + mov rax, QWORD PTR [r12+16] + mov r9, QWORD PTR [r13+16] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+16], rax + mov QWORD PTR [r13+16], r9 + mov rax, QWORD PTR [r12+24] + mov r9, QWORD PTR [r13+24] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+24], rax + mov QWORD PTR [r13+24], r9 + mov rax, QWORD PTR [r12+32] + mov r9, QWORD PTR [r13+32] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+32], rax + mov QWORD PTR [r13+32], r9 + mov rax, QWORD PTR [r12+40] + mov r9, QWORD PTR [r13+40] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+40], rax + mov QWORD PTR [r13+40], r9 + mov rax, QWORD PTR [r12+48] + mov r9, QWORD PTR [r13+48] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+48], rax + mov QWORD PTR [r13+48], r9 + mov rax, QWORD PTR [r12+56] + mov r9, QWORD PTR [r13+56] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+56], rax + mov QWORD PTR [r13+56], r9 + mov rax, QWORD PTR [r12+64] + mov r9, QWORD PTR [r13+64] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+64], rax + mov QWORD PTR [r13+64], r9 + mov rax, QWORD PTR [r12+72] + mov r9, QWORD PTR [r13+72] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+72], rax + mov QWORD PTR [r13+72], r9 + mov rax, QWORD PTR [r12+80] + mov r9, QWORD PTR [r13+80] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+80], rax + mov QWORD PTR [r13+80], r9 + mov rax, QWORD PTR [r12+88] + mov r9, QWORD PTR [r13+88] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+88], rax + mov QWORD PTR [r13+88], r9 + mov rax, QWORD PTR [r12+96] + mov r9, QWORD PTR [r13+96] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+96], rax + mov QWORD PTR [r13+96], r9 + mov rax, QWORD PTR [r12+104] + mov r9, QWORD PTR [r13+104] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+104], rax + mov QWORD PTR [r13+104], r9 + mov rax, QWORD PTR [r12+112] + mov r9, QWORD PTR [r13+112] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+112], rax + mov QWORD PTR [r13+112], r9 + mov rax, QWORD PTR [r12+120] + mov r9, QWORD PTR [r13+120] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+120], rax + mov QWORD PTR [r13+120], r9 + mov rax, QWORD PTR [r12] + add rax, QWORD PTR [r13] + mov r9, QWORD PTR [r12+8] + mov QWORD PTR [rsi], rax + adc r9, QWORD PTR [r13+8] + mov r10, QWORD PTR [r12+16] + mov QWORD PTR [rsi+8], r9 + adc r10, QWORD PTR [r13+16] + mov rax, QWORD PTR [r12+24] + mov QWORD PTR [rsi+16], r10 + adc rax, QWORD PTR [r13+24] + mov r9, QWORD PTR [r12+32] + mov QWORD PTR [rsi+24], rax + adc r9, QWORD PTR [r13+32] + mov r10, QWORD PTR [r12+40] + mov QWORD PTR [rsi+32], r9 + adc r10, QWORD PTR [r13+40] + mov rax, QWORD PTR [r12+48] + mov QWORD PTR [rsi+40], r10 + adc rax, QWORD PTR [r13+48] + mov r9, QWORD PTR [r12+56] + mov QWORD PTR [rsi+48], rax + adc r9, QWORD PTR [r13+56] + mov r10, QWORD PTR [r12+64] + mov QWORD PTR [rsi+56], r9 + adc r10, QWORD PTR [r13+64] + mov rax, QWORD PTR [r12+72] + mov QWORD PTR [rsi+64], r10 + adc rax, QWORD PTR [r13+72] + mov r9, QWORD PTR [r12+80] + mov QWORD PTR [rsi+72], rax + adc r9, QWORD PTR [r13+80] + mov r10, QWORD PTR [r12+88] + mov QWORD PTR [rsi+80], r9 + adc r10, QWORD PTR [r13+88] + mov rax, QWORD PTR [r12+96] + mov QWORD PTR [rsi+88], r10 + adc rax, QWORD PTR [r13+96] + mov r9, QWORD PTR [r12+104] + mov QWORD PTR [rsi+96], rax + adc r9, QWORD PTR [r13+104] + mov r10, QWORD PTR [r12+112] + mov QWORD PTR [rsi+104], r9 + adc r10, QWORD PTR [r13+112] + mov rax, QWORD PTR [r12+120] + mov QWORD PTR [rsi+112], r10 + adc rax, QWORD PTR [r13+120] + mov QWORD PTR [rsi+120], rax + adc r11, 0 + lea r13, QWORD PTR [rsp+256] + mov r12, rsp + mov rax, QWORD PTR [r12] + sub rax, QWORD PTR [r13] + mov r9, QWORD PTR [r12+8] + mov QWORD PTR [r12], rax + sbb r9, QWORD PTR [r13+8] + mov r10, QWORD PTR [r12+16] + mov QWORD PTR [r12+8], r9 + sbb r10, QWORD PTR [r13+16] + mov rax, QWORD PTR [r12+24] + mov QWORD PTR [r12+16], r10 + sbb rax, QWORD PTR [r13+24] + mov r9, QWORD PTR [r12+32] + mov QWORD PTR [r12+24], rax + sbb r9, QWORD PTR [r13+32] + mov r10, QWORD PTR [r12+40] + mov QWORD PTR [r12+32], r9 + sbb r10, QWORD PTR [r13+40] + mov rax, QWORD PTR [r12+48] + mov QWORD PTR [r12+40], r10 + sbb rax, QWORD PTR [r13+48] + mov r9, QWORD PTR [r12+56] + mov QWORD PTR [r12+48], rax + sbb r9, QWORD PTR [r13+56] + mov r10, QWORD PTR [r12+64] + mov QWORD PTR [r12+56], r9 + sbb r10, QWORD PTR [r13+64] + mov rax, QWORD PTR [r12+72] + mov QWORD PTR [r12+64], r10 + sbb rax, QWORD PTR [r13+72] + mov r9, QWORD PTR [r12+80] + mov QWORD PTR [r12+72], rax + sbb r9, QWORD PTR [r13+80] + mov r10, QWORD PTR [r12+88] + mov QWORD PTR [r12+80], r9 + sbb r10, QWORD PTR [r13+88] + mov rax, QWORD PTR [r12+96] + mov QWORD PTR [r12+88], r10 + sbb rax, QWORD PTR [r13+96] + mov r9, QWORD PTR [r12+104] + mov QWORD PTR [r12+96], rax + sbb r9, QWORD PTR [r13+104] + mov r10, QWORD PTR [r12+112] + mov QWORD PTR [r12+104], r9 + sbb r10, QWORD PTR [r13+112] + mov rax, QWORD PTR [r12+120] + mov QWORD PTR [r12+112], r10 + sbb rax, QWORD PTR [r13+120] + mov r9, QWORD PTR [r12+128] + mov QWORD PTR [r12+120], rax + sbb r9, QWORD PTR [r13+128] + mov r10, QWORD PTR [r12+136] + mov QWORD PTR [r12+128], r9 + sbb r10, QWORD PTR [r13+136] + mov rax, QWORD PTR [r12+144] + mov QWORD PTR [r12+136], r10 + sbb rax, QWORD PTR [r13+144] + mov r9, QWORD PTR [r12+152] + mov QWORD PTR [r12+144], rax + sbb r9, QWORD PTR [r13+152] + mov r10, QWORD PTR [r12+160] + mov QWORD PTR [r12+152], r9 + sbb r10, QWORD PTR [r13+160] + mov rax, QWORD PTR [r12+168] + mov QWORD PTR [r12+160], r10 + sbb rax, QWORD PTR [r13+168] + mov r9, QWORD PTR [r12+176] + mov QWORD PTR [r12+168], rax + sbb r9, QWORD PTR [r13+176] + mov r10, QWORD PTR [r12+184] + mov QWORD PTR [r12+176], r9 + sbb r10, QWORD PTR [r13+184] + mov rax, QWORD PTR [r12+192] + mov QWORD PTR [r12+184], r10 + sbb rax, QWORD PTR [r13+192] + mov r9, QWORD PTR [r12+200] + mov QWORD PTR [r12+192], rax + sbb r9, QWORD PTR [r13+200] + mov r10, QWORD PTR [r12+208] + mov QWORD PTR [r12+200], r9 + sbb r10, QWORD PTR [r13+208] + mov rax, QWORD PTR [r12+216] + mov QWORD PTR [r12+208], r10 + sbb rax, QWORD PTR [r13+216] + mov r9, QWORD PTR [r12+224] + mov QWORD PTR [r12+216], rax + sbb r9, QWORD PTR [r13+224] + mov r10, QWORD PTR [r12+232] + mov QWORD PTR [r12+224], r9 + sbb r10, QWORD PTR [r13+232] + mov rax, QWORD PTR [r12+240] + mov QWORD PTR [r12+232], r10 + sbb rax, QWORD PTR [r13+240] + mov r9, QWORD PTR [r12+248] + mov QWORD PTR [r12+240], rax + sbb r9, QWORD PTR [r13+248] + mov QWORD PTR [r12+248], r9 + sbb r11, 0 + mov rax, QWORD PTR [r12] + sub rax, QWORD PTR [rcx] + mov r9, QWORD PTR [r12+8] + mov QWORD PTR [r12], rax + sbb r9, QWORD PTR [rcx+8] + mov r10, QWORD PTR [r12+16] + mov QWORD PTR [r12+8], r9 + sbb r10, QWORD PTR [rcx+16] + mov rax, QWORD PTR [r12+24] + mov QWORD PTR [r12+16], r10 + sbb rax, QWORD PTR [rcx+24] + mov r9, QWORD PTR [r12+32] + mov QWORD PTR [r12+24], rax + sbb r9, QWORD PTR [rcx+32] + mov r10, QWORD PTR [r12+40] + mov QWORD PTR [r12+32], r9 + sbb r10, QWORD PTR [rcx+40] + mov rax, QWORD PTR [r12+48] + mov QWORD PTR [r12+40], r10 + sbb rax, QWORD PTR [rcx+48] + mov r9, QWORD PTR [r12+56] + mov QWORD PTR [r12+48], rax + sbb r9, QWORD PTR [rcx+56] + mov r10, QWORD PTR [r12+64] + mov QWORD PTR [r12+56], r9 + sbb r10, QWORD PTR [rcx+64] + mov rax, QWORD PTR [r12+72] + mov QWORD PTR [r12+64], r10 + sbb rax, QWORD PTR [rcx+72] + mov r9, QWORD PTR [r12+80] + mov QWORD PTR [r12+72], rax + sbb r9, QWORD PTR [rcx+80] + mov r10, QWORD PTR [r12+88] + mov QWORD PTR [r12+80], r9 + sbb r10, QWORD PTR [rcx+88] + mov rax, QWORD PTR [r12+96] + mov QWORD PTR [r12+88], r10 + sbb rax, QWORD PTR [rcx+96] + mov r9, QWORD PTR [r12+104] + mov QWORD PTR [r12+96], rax + sbb r9, QWORD PTR [rcx+104] + mov r10, QWORD PTR [r12+112] + mov QWORD PTR [r12+104], r9 + sbb r10, QWORD PTR [rcx+112] + mov rax, QWORD PTR [r12+120] + mov QWORD PTR [r12+112], r10 + sbb rax, QWORD PTR [rcx+120] + mov r9, QWORD PTR [r12+128] + mov QWORD PTR [r12+120], rax + sbb r9, QWORD PTR [rcx+128] + mov r10, QWORD PTR [r12+136] + mov QWORD PTR [r12+128], r9 + sbb r10, QWORD PTR [rcx+136] + mov rax, QWORD PTR [r12+144] + mov QWORD PTR [r12+136], r10 + sbb rax, QWORD PTR [rcx+144] + mov r9, QWORD PTR [r12+152] + mov QWORD PTR [r12+144], rax + sbb r9, QWORD PTR [rcx+152] + mov r10, QWORD PTR [r12+160] + mov QWORD PTR [r12+152], r9 + sbb r10, QWORD PTR [rcx+160] + mov rax, QWORD PTR [r12+168] + mov QWORD PTR [r12+160], r10 + sbb rax, QWORD PTR [rcx+168] + mov r9, QWORD PTR [r12+176] + mov QWORD PTR [r12+168], rax + sbb r9, QWORD PTR [rcx+176] + mov r10, QWORD PTR [r12+184] + mov QWORD PTR [r12+176], r9 + sbb r10, QWORD PTR [rcx+184] + mov rax, QWORD PTR [r12+192] + mov QWORD PTR [r12+184], r10 + sbb rax, QWORD PTR [rcx+192] + mov r9, QWORD PTR [r12+200] + mov QWORD PTR [r12+192], rax + sbb r9, QWORD PTR [rcx+200] + mov r10, QWORD PTR [r12+208] + mov QWORD PTR [r12+200], r9 + sbb r10, QWORD PTR [rcx+208] + mov rax, QWORD PTR [r12+216] + mov QWORD PTR [r12+208], r10 + sbb rax, QWORD PTR [rcx+216] + mov r9, QWORD PTR [r12+224] + mov QWORD PTR [r12+216], rax + sbb r9, QWORD PTR [rcx+224] + mov r10, QWORD PTR [r12+232] + mov QWORD PTR [r12+224], r9 + sbb r10, QWORD PTR [rcx+232] + mov rax, QWORD PTR [r12+240] + mov QWORD PTR [r12+232], r10 + sbb rax, QWORD PTR [rcx+240] + mov r9, QWORD PTR [r12+248] + mov QWORD PTR [r12+240], rax + sbb r9, QWORD PTR [rcx+248] + mov QWORD PTR [r12+248], r9 + sbb r11, 0 + sub rsi, 128 + ; Add + mov rax, QWORD PTR [rsi] + add rax, QWORD PTR [r12] + mov r9, QWORD PTR [rsi+8] + mov QWORD PTR [rsi], rax + adc r9, QWORD PTR [r12+8] + mov r10, QWORD PTR [rsi+16] + mov QWORD PTR [rsi+8], r9 + adc r10, QWORD PTR [r12+16] + mov rax, QWORD PTR [rsi+24] + mov QWORD PTR [rsi+16], r10 + adc rax, QWORD PTR [r12+24] + mov r9, QWORD PTR [rsi+32] + mov QWORD PTR [rsi+24], rax + adc r9, QWORD PTR [r12+32] + mov r10, QWORD PTR [rsi+40] + mov QWORD PTR [rsi+32], r9 + adc r10, QWORD PTR [r12+40] + mov rax, QWORD PTR [rsi+48] + mov QWORD PTR [rsi+40], r10 + adc rax, QWORD PTR [r12+48] + mov r9, QWORD PTR [rsi+56] + mov QWORD PTR [rsi+48], rax + adc r9, QWORD PTR [r12+56] + mov r10, QWORD PTR [rsi+64] + mov QWORD PTR [rsi+56], r9 + adc r10, QWORD PTR [r12+64] + mov rax, QWORD PTR [rsi+72] + mov QWORD PTR [rsi+64], r10 + adc rax, QWORD PTR [r12+72] + mov r9, QWORD PTR [rsi+80] + mov QWORD PTR [rsi+72], rax + adc r9, QWORD PTR [r12+80] + mov r10, QWORD PTR [rsi+88] + mov QWORD PTR [rsi+80], r9 + adc r10, QWORD PTR [r12+88] + mov rax, QWORD PTR [rsi+96] + mov QWORD PTR [rsi+88], r10 + adc rax, QWORD PTR [r12+96] + mov r9, QWORD PTR [rsi+104] + mov QWORD PTR [rsi+96], rax + adc r9, QWORD PTR [r12+104] + mov r10, QWORD PTR [rsi+112] + mov QWORD PTR [rsi+104], r9 + adc r10, QWORD PTR [r12+112] + mov rax, QWORD PTR [rsi+120] + mov QWORD PTR [rsi+112], r10 + adc rax, QWORD PTR [r12+120] + mov r9, QWORD PTR [rsi+128] + mov QWORD PTR [rsi+120], rax + adc r9, QWORD PTR [r12+128] + mov r10, QWORD PTR [rsi+136] + mov QWORD PTR [rsi+128], r9 + adc r10, QWORD PTR [r12+136] + mov rax, QWORD PTR [rsi+144] + mov QWORD PTR [rsi+136], r10 + adc rax, QWORD PTR [r12+144] + mov r9, QWORD PTR [rsi+152] + mov QWORD PTR [rsi+144], rax + adc r9, QWORD PTR [r12+152] + mov r10, QWORD PTR [rsi+160] + mov QWORD PTR [rsi+152], r9 + adc r10, QWORD PTR [r12+160] + mov rax, QWORD PTR [rsi+168] + mov QWORD PTR [rsi+160], r10 + adc rax, QWORD PTR [r12+168] + mov r9, QWORD PTR [rsi+176] + mov QWORD PTR [rsi+168], rax + adc r9, QWORD PTR [r12+176] + mov r10, QWORD PTR [rsi+184] + mov QWORD PTR [rsi+176], r9 + adc r10, QWORD PTR [r12+184] + mov rax, QWORD PTR [rsi+192] + mov QWORD PTR [rsi+184], r10 + adc rax, QWORD PTR [r12+192] + mov r9, QWORD PTR [rsi+200] + mov QWORD PTR [rsi+192], rax + adc r9, QWORD PTR [r12+200] + mov r10, QWORD PTR [rsi+208] + mov QWORD PTR [rsi+200], r9 + adc r10, QWORD PTR [r12+208] + mov rax, QWORD PTR [rsi+216] + mov QWORD PTR [rsi+208], r10 + adc rax, QWORD PTR [r12+216] + mov r9, QWORD PTR [rsi+224] + mov QWORD PTR [rsi+216], rax + adc r9, QWORD PTR [r12+224] + mov r10, QWORD PTR [rsi+232] + mov QWORD PTR [rsi+224], r9 + adc r10, QWORD PTR [r12+232] + mov rax, QWORD PTR [rsi+240] + mov QWORD PTR [rsi+232], r10 + adc rax, QWORD PTR [r12+240] + mov r9, QWORD PTR [rsi+248] + mov QWORD PTR [rsi+240], rax + adc r9, QWORD PTR [r12+248] + mov QWORD PTR [rsi+248], r9 + adc r11, 0 + mov QWORD PTR [rcx+384], r11 + add rsi, 128 + ; Add + mov rax, QWORD PTR [rsi] + xor r11, r11 + add rax, QWORD PTR [r13] + mov r9, QWORD PTR [rsi+8] + mov QWORD PTR [rsi], rax + adc r9, QWORD PTR [r13+8] + mov r10, QWORD PTR [rsi+16] + mov QWORD PTR [rsi+8], r9 + adc r10, QWORD PTR [r13+16] + mov rax, QWORD PTR [rsi+24] + mov QWORD PTR [rsi+16], r10 + adc rax, QWORD PTR [r13+24] + mov r9, QWORD PTR [rsi+32] + mov QWORD PTR [rsi+24], rax + adc r9, QWORD PTR [r13+32] + mov r10, QWORD PTR [rsi+40] + mov QWORD PTR [rsi+32], r9 + adc r10, QWORD PTR [r13+40] + mov rax, QWORD PTR [rsi+48] + mov QWORD PTR [rsi+40], r10 + adc rax, QWORD PTR [r13+48] + mov r9, QWORD PTR [rsi+56] + mov QWORD PTR [rsi+48], rax + adc r9, QWORD PTR [r13+56] + mov r10, QWORD PTR [rsi+64] + mov QWORD PTR [rsi+56], r9 + adc r10, QWORD PTR [r13+64] + mov rax, QWORD PTR [rsi+72] + mov QWORD PTR [rsi+64], r10 + adc rax, QWORD PTR [r13+72] + mov r9, QWORD PTR [rsi+80] + mov QWORD PTR [rsi+72], rax + adc r9, QWORD PTR [r13+80] + mov r10, QWORD PTR [rsi+88] + mov QWORD PTR [rsi+80], r9 + adc r10, QWORD PTR [r13+88] + mov rax, QWORD PTR [rsi+96] + mov QWORD PTR [rsi+88], r10 + adc rax, QWORD PTR [r13+96] + mov r9, QWORD PTR [rsi+104] + mov QWORD PTR [rsi+96], rax + adc r9, QWORD PTR [r13+104] + mov r10, QWORD PTR [rsi+112] + mov QWORD PTR [rsi+104], r9 + adc r10, QWORD PTR [r13+112] + mov rax, QWORD PTR [rsi+120] + mov QWORD PTR [rsi+112], r10 + adc rax, QWORD PTR [r13+120] + mov r9, QWORD PTR [rsi+128] + mov QWORD PTR [rsi+120], rax + adc r9, QWORD PTR [r13+128] + mov QWORD PTR [rsi+128], r9 + adc r11, 0 + ; Add to zero + mov rax, QWORD PTR [r13+136] + adc rax, 0 + mov r9, QWORD PTR [r13+144] + mov QWORD PTR [rsi+136], rax + adc r9, 0 + mov r10, QWORD PTR [r13+152] + mov QWORD PTR [rsi+144], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+160] + mov QWORD PTR [rsi+152], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+168] + mov QWORD PTR [rsi+160], rax + adc r9, 0 + mov r10, QWORD PTR [r13+176] + mov QWORD PTR [rsi+168], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+184] + mov QWORD PTR [rsi+176], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+192] + mov QWORD PTR [rsi+184], rax + adc r9, 0 + mov r10, QWORD PTR [r13+200] + mov QWORD PTR [rsi+192], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+208] + mov QWORD PTR [rsi+200], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+216] + mov QWORD PTR [rsi+208], rax + adc r9, 0 + mov r10, QWORD PTR [r13+224] + mov QWORD PTR [rsi+216], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+232] + mov QWORD PTR [rsi+224], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+240] + mov QWORD PTR [rsi+232], rax + adc r9, 0 + mov r10, QWORD PTR [r13+248] + mov QWORD PTR [rsi+240], r9 + adc r10, 0 + mov QWORD PTR [rsi+248], r10 + add rsp, 808 + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_2048_mul_32 ENDP +_text ENDS +; /* Add a to a into r. (r = a + a) +; * +; * r A single precision integer. +; * a A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_2048_dbl_16 PROC + mov r8, QWORD PTR [rdx] + xor rax, rax + add r8, r8 + mov r9, QWORD PTR [rdx+8] + mov QWORD PTR [rcx], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+16] + mov QWORD PTR [rcx+8], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+24] + mov QWORD PTR [rcx+16], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+32] + mov QWORD PTR [rcx+24], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+40] + mov QWORD PTR [rcx+32], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+48] + mov QWORD PTR [rcx+40], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+56] + mov QWORD PTR [rcx+48], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+64] + mov QWORD PTR [rcx+56], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+72] + mov QWORD PTR [rcx+64], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+80] + mov QWORD PTR [rcx+72], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+88] + mov QWORD PTR [rcx+80], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+96] + mov QWORD PTR [rcx+88], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+104] + mov QWORD PTR [rcx+96], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+112] + mov QWORD PTR [rcx+104], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+120] + mov QWORD PTR [rcx+112], r8 + adc r9, r9 + mov QWORD PTR [rcx+120], r9 + adc rax, 0 + ret +sp_2048_dbl_16 ENDP +_text ENDS +; /* Square a and put result in r. (r = a * a) +; * +; * r A single precision integer. +; * a A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_2048_sqr_32 PROC + push r12 + sub rsp, 664 + mov QWORD PTR [rsp+640], rcx + mov QWORD PTR [rsp+648], rdx + lea r10, QWORD PTR [rsp+512] + lea r11, QWORD PTR [rdx+128] + ; Add + mov rax, QWORD PTR [rdx] + xor r9, r9 + add rax, QWORD PTR [r11] + mov r8, QWORD PTR [rdx+8] + mov QWORD PTR [r10], rax + adc r8, QWORD PTR [r11+8] + mov rax, QWORD PTR [rdx+16] + mov QWORD PTR [r10+8], r8 + adc rax, QWORD PTR [r11+16] + mov r8, QWORD PTR [rdx+24] + mov QWORD PTR [r10+16], rax + adc r8, QWORD PTR [r11+24] + mov rax, QWORD PTR [rdx+32] + mov QWORD PTR [r10+24], r8 + adc rax, QWORD PTR [r11+32] + mov r8, QWORD PTR [rdx+40] + mov QWORD PTR [r10+32], rax + adc r8, QWORD PTR [r11+40] + mov rax, QWORD PTR [rdx+48] + mov QWORD PTR [r10+40], r8 + adc rax, QWORD PTR [r11+48] + mov r8, QWORD PTR [rdx+56] + mov QWORD PTR [r10+48], rax + adc r8, QWORD PTR [r11+56] + mov rax, QWORD PTR [rdx+64] + mov QWORD PTR [r10+56], r8 + adc rax, QWORD PTR [r11+64] + mov r8, QWORD PTR [rdx+72] + mov QWORD PTR [r10+64], rax + adc r8, QWORD PTR [r11+72] + mov rax, QWORD PTR [rdx+80] + mov QWORD PTR [r10+72], r8 + adc rax, QWORD PTR [r11+80] + mov r8, QWORD PTR [rdx+88] + mov QWORD PTR [r10+80], rax + adc r8, QWORD PTR [r11+88] + mov rax, QWORD PTR [rdx+96] + mov QWORD PTR [r10+88], r8 + adc rax, QWORD PTR [r11+96] + mov r8, QWORD PTR [rdx+104] + mov QWORD PTR [r10+96], rax + adc r8, QWORD PTR [r11+104] + mov rax, QWORD PTR [rdx+112] + mov QWORD PTR [r10+104], r8 + adc rax, QWORD PTR [r11+112] + mov r8, QWORD PTR [rdx+120] + mov QWORD PTR [r10+112], rax + adc r8, QWORD PTR [r11+120] + mov QWORD PTR [r10+120], r8 + adc r9, 0 + mov QWORD PTR [rsp+656], r9 + mov rdx, r10 + mov rcx, rsp + call sp_2048_sqr_16 + mov rdx, QWORD PTR [rsp+648] + lea rcx, QWORD PTR [rsp+256] + add rdx, 128 + call sp_2048_sqr_16 + mov rdx, QWORD PTR [rsp+648] + mov rcx, QWORD PTR [rsp+640] + call sp_2048_sqr_16 +IFDEF _WIN64 + mov rdx, QWORD PTR [rsp+648] + mov rcx, QWORD PTR [rsp+640] +ENDIF + mov r12, QWORD PTR [rsp+656] + lea r10, QWORD PTR [rsp+512] + mov r9, r12 + neg r12 + mov rax, QWORD PTR [r10] + mov r8, QWORD PTR [r10+8] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+256], rax + mov QWORD PTR [rcx+264], r8 + mov rax, QWORD PTR [r10+16] + mov r8, QWORD PTR [r10+24] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+272], rax + mov QWORD PTR [rcx+280], r8 + mov rax, QWORD PTR [r10+32] + mov r8, QWORD PTR [r10+40] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+288], rax + mov QWORD PTR [rcx+296], r8 + mov rax, QWORD PTR [r10+48] + mov r8, QWORD PTR [r10+56] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+304], rax + mov QWORD PTR [rcx+312], r8 + mov rax, QWORD PTR [r10+64] + mov r8, QWORD PTR [r10+72] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+320], rax + mov QWORD PTR [rcx+328], r8 + mov rax, QWORD PTR [r10+80] + mov r8, QWORD PTR [r10+88] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+336], rax + mov QWORD PTR [rcx+344], r8 + mov rax, QWORD PTR [r10+96] + mov r8, QWORD PTR [r10+104] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+352], rax + mov QWORD PTR [rcx+360], r8 + mov rax, QWORD PTR [r10+112] + mov r8, QWORD PTR [r10+120] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+368], rax + mov QWORD PTR [rcx+376], r8 + mov rax, QWORD PTR [rcx+256] + add rax, rax + mov r8, QWORD PTR [rcx+264] + mov QWORD PTR [rcx+256], rax + adc r8, r8 + mov rax, QWORD PTR [rcx+272] + mov QWORD PTR [rcx+264], r8 + adc rax, rax + mov r8, QWORD PTR [rcx+280] + mov QWORD PTR [rcx+272], rax + adc r8, r8 + mov rax, QWORD PTR [rcx+288] + mov QWORD PTR [rcx+280], r8 + adc rax, rax + mov r8, QWORD PTR [rcx+296] + mov QWORD PTR [rcx+288], rax + adc r8, r8 + mov rax, QWORD PTR [rcx+304] + mov QWORD PTR [rcx+296], r8 + adc rax, rax + mov r8, QWORD PTR [rcx+312] + mov QWORD PTR [rcx+304], rax + adc r8, r8 + mov rax, QWORD PTR [rcx+320] + mov QWORD PTR [rcx+312], r8 + adc rax, rax + mov r8, QWORD PTR [rcx+328] + mov QWORD PTR [rcx+320], rax + adc r8, r8 + mov rax, QWORD PTR [rcx+336] + mov QWORD PTR [rcx+328], r8 + adc rax, rax + mov r8, QWORD PTR [rcx+344] + mov QWORD PTR [rcx+336], rax + adc r8, r8 + mov rax, QWORD PTR [rcx+352] + mov QWORD PTR [rcx+344], r8 + adc rax, rax + mov r8, QWORD PTR [rcx+360] + mov QWORD PTR [rcx+352], rax + adc r8, r8 + mov rax, QWORD PTR [rcx+368] + mov QWORD PTR [rcx+360], r8 + adc rax, rax + mov r8, QWORD PTR [rcx+376] + mov QWORD PTR [rcx+368], rax + adc r8, r8 + mov QWORD PTR [rcx+376], r8 + adc r9, 0 + lea rdx, QWORD PTR [rsp+256] + mov r10, rsp + mov rax, QWORD PTR [r10] + sub rax, QWORD PTR [rdx] + mov r8, QWORD PTR [r10+8] + mov QWORD PTR [r10], rax + sbb r8, QWORD PTR [rdx+8] + mov rax, QWORD PTR [r10+16] + mov QWORD PTR [r10+8], r8 + sbb rax, QWORD PTR [rdx+16] + mov r8, QWORD PTR [r10+24] + mov QWORD PTR [r10+16], rax + sbb r8, QWORD PTR [rdx+24] + mov rax, QWORD PTR [r10+32] + mov QWORD PTR [r10+24], r8 + sbb rax, QWORD PTR [rdx+32] + mov r8, QWORD PTR [r10+40] + mov QWORD PTR [r10+32], rax + sbb r8, QWORD PTR [rdx+40] + mov rax, QWORD PTR [r10+48] + mov QWORD PTR [r10+40], r8 + sbb rax, QWORD PTR [rdx+48] + mov r8, QWORD PTR [r10+56] + mov QWORD PTR [r10+48], rax + sbb r8, QWORD PTR [rdx+56] + mov rax, QWORD PTR [r10+64] + mov QWORD PTR [r10+56], r8 + sbb rax, QWORD PTR [rdx+64] + mov r8, QWORD PTR [r10+72] + mov QWORD PTR [r10+64], rax + sbb r8, QWORD PTR [rdx+72] + mov rax, QWORD PTR [r10+80] + mov QWORD PTR [r10+72], r8 + sbb rax, QWORD PTR [rdx+80] + mov r8, QWORD PTR [r10+88] + mov QWORD PTR [r10+80], rax + sbb r8, QWORD PTR [rdx+88] + mov rax, QWORD PTR [r10+96] + mov QWORD PTR [r10+88], r8 + sbb rax, QWORD PTR [rdx+96] + mov r8, QWORD PTR [r10+104] + mov QWORD PTR [r10+96], rax + sbb r8, QWORD PTR [rdx+104] + mov rax, QWORD PTR [r10+112] + mov QWORD PTR [r10+104], r8 + sbb rax, QWORD PTR [rdx+112] + mov r8, QWORD PTR [r10+120] + mov QWORD PTR [r10+112], rax + sbb r8, QWORD PTR [rdx+120] + mov rax, QWORD PTR [r10+128] + mov QWORD PTR [r10+120], r8 + sbb rax, QWORD PTR [rdx+128] + mov r8, QWORD PTR [r10+136] + mov QWORD PTR [r10+128], rax + sbb r8, QWORD PTR [rdx+136] + mov rax, QWORD PTR [r10+144] + mov QWORD PTR [r10+136], r8 + sbb rax, QWORD PTR [rdx+144] + mov r8, QWORD PTR [r10+152] + mov QWORD PTR [r10+144], rax + sbb r8, QWORD PTR [rdx+152] + mov rax, QWORD PTR [r10+160] + mov QWORD PTR [r10+152], r8 + sbb rax, QWORD PTR [rdx+160] + mov r8, QWORD PTR [r10+168] + mov QWORD PTR [r10+160], rax + sbb r8, QWORD PTR [rdx+168] + mov rax, QWORD PTR [r10+176] + mov QWORD PTR [r10+168], r8 + sbb rax, QWORD PTR [rdx+176] + mov r8, QWORD PTR [r10+184] + mov QWORD PTR [r10+176], rax + sbb r8, QWORD PTR [rdx+184] + mov rax, QWORD PTR [r10+192] + mov QWORD PTR [r10+184], r8 + sbb rax, QWORD PTR [rdx+192] + mov r8, QWORD PTR [r10+200] + mov QWORD PTR [r10+192], rax + sbb r8, QWORD PTR [rdx+200] + mov rax, QWORD PTR [r10+208] + mov QWORD PTR [r10+200], r8 + sbb rax, QWORD PTR [rdx+208] + mov r8, QWORD PTR [r10+216] + mov QWORD PTR [r10+208], rax + sbb r8, QWORD PTR [rdx+216] + mov rax, QWORD PTR [r10+224] + mov QWORD PTR [r10+216], r8 + sbb rax, QWORD PTR [rdx+224] + mov r8, QWORD PTR [r10+232] + mov QWORD PTR [r10+224], rax + sbb r8, QWORD PTR [rdx+232] + mov rax, QWORD PTR [r10+240] + mov QWORD PTR [r10+232], r8 + sbb rax, QWORD PTR [rdx+240] + mov r8, QWORD PTR [r10+248] + mov QWORD PTR [r10+240], rax + sbb r8, QWORD PTR [rdx+248] + mov QWORD PTR [r10+248], r8 + sbb r9, 0 + mov rax, QWORD PTR [r10] + sub rax, QWORD PTR [rcx] + mov r8, QWORD PTR [r10+8] + mov QWORD PTR [r10], rax + sbb r8, QWORD PTR [rcx+8] + mov rax, QWORD PTR [r10+16] + mov QWORD PTR [r10+8], r8 + sbb rax, QWORD PTR [rcx+16] + mov r8, QWORD PTR [r10+24] + mov QWORD PTR [r10+16], rax + sbb r8, QWORD PTR [rcx+24] + mov rax, QWORD PTR [r10+32] + mov QWORD PTR [r10+24], r8 + sbb rax, QWORD PTR [rcx+32] + mov r8, QWORD PTR [r10+40] + mov QWORD PTR [r10+32], rax + sbb r8, QWORD PTR [rcx+40] + mov rax, QWORD PTR [r10+48] + mov QWORD PTR [r10+40], r8 + sbb rax, QWORD PTR [rcx+48] + mov r8, QWORD PTR [r10+56] + mov QWORD PTR [r10+48], rax + sbb r8, QWORD PTR [rcx+56] + mov rax, QWORD PTR [r10+64] + mov QWORD PTR [r10+56], r8 + sbb rax, QWORD PTR [rcx+64] + mov r8, QWORD PTR [r10+72] + mov QWORD PTR [r10+64], rax + sbb r8, QWORD PTR [rcx+72] + mov rax, QWORD PTR [r10+80] + mov QWORD PTR [r10+72], r8 + sbb rax, QWORD PTR [rcx+80] + mov r8, QWORD PTR [r10+88] + mov QWORD PTR [r10+80], rax + sbb r8, QWORD PTR [rcx+88] + mov rax, QWORD PTR [r10+96] + mov QWORD PTR [r10+88], r8 + sbb rax, QWORD PTR [rcx+96] + mov r8, QWORD PTR [r10+104] + mov QWORD PTR [r10+96], rax + sbb r8, QWORD PTR [rcx+104] + mov rax, QWORD PTR [r10+112] + mov QWORD PTR [r10+104], r8 + sbb rax, QWORD PTR [rcx+112] + mov r8, QWORD PTR [r10+120] + mov QWORD PTR [r10+112], rax + sbb r8, QWORD PTR [rcx+120] + mov rax, QWORD PTR [r10+128] + mov QWORD PTR [r10+120], r8 + sbb rax, QWORD PTR [rcx+128] + mov r8, QWORD PTR [r10+136] + mov QWORD PTR [r10+128], rax + sbb r8, QWORD PTR [rcx+136] + mov rax, QWORD PTR [r10+144] + mov QWORD PTR [r10+136], r8 + sbb rax, QWORD PTR [rcx+144] + mov r8, QWORD PTR [r10+152] + mov QWORD PTR [r10+144], rax + sbb r8, QWORD PTR [rcx+152] + mov rax, QWORD PTR [r10+160] + mov QWORD PTR [r10+152], r8 + sbb rax, QWORD PTR [rcx+160] + mov r8, QWORD PTR [r10+168] + mov QWORD PTR [r10+160], rax + sbb r8, QWORD PTR [rcx+168] + mov rax, QWORD PTR [r10+176] + mov QWORD PTR [r10+168], r8 + sbb rax, QWORD PTR [rcx+176] + mov r8, QWORD PTR [r10+184] + mov QWORD PTR [r10+176], rax + sbb r8, QWORD PTR [rcx+184] + mov rax, QWORD PTR [r10+192] + mov QWORD PTR [r10+184], r8 + sbb rax, QWORD PTR [rcx+192] + mov r8, QWORD PTR [r10+200] + mov QWORD PTR [r10+192], rax + sbb r8, QWORD PTR [rcx+200] + mov rax, QWORD PTR [r10+208] + mov QWORD PTR [r10+200], r8 + sbb rax, QWORD PTR [rcx+208] + mov r8, QWORD PTR [r10+216] + mov QWORD PTR [r10+208], rax + sbb r8, QWORD PTR [rcx+216] + mov rax, QWORD PTR [r10+224] + mov QWORD PTR [r10+216], r8 + sbb rax, QWORD PTR [rcx+224] + mov r8, QWORD PTR [r10+232] + mov QWORD PTR [r10+224], rax + sbb r8, QWORD PTR [rcx+232] + mov rax, QWORD PTR [r10+240] + mov QWORD PTR [r10+232], r8 + sbb rax, QWORD PTR [rcx+240] + mov r8, QWORD PTR [r10+248] + mov QWORD PTR [r10+240], rax + sbb r8, QWORD PTR [rcx+248] + mov QWORD PTR [r10+248], r8 + sbb r9, 0 + ; Add in place + mov rax, QWORD PTR [rcx+128] + add rax, QWORD PTR [r10] + mov r8, QWORD PTR [rcx+136] + mov QWORD PTR [rcx+128], rax + adc r8, QWORD PTR [r10+8] + mov rax, QWORD PTR [rcx+144] + mov QWORD PTR [rcx+136], r8 + adc rax, QWORD PTR [r10+16] + mov r8, QWORD PTR [rcx+152] + mov QWORD PTR [rcx+144], rax + adc r8, QWORD PTR [r10+24] + mov rax, QWORD PTR [rcx+160] + mov QWORD PTR [rcx+152], r8 + adc rax, QWORD PTR [r10+32] + mov r8, QWORD PTR [rcx+168] + mov QWORD PTR [rcx+160], rax + adc r8, QWORD PTR [r10+40] + mov rax, QWORD PTR [rcx+176] + mov QWORD PTR [rcx+168], r8 + adc rax, QWORD PTR [r10+48] + mov r8, QWORD PTR [rcx+184] + mov QWORD PTR [rcx+176], rax + adc r8, QWORD PTR [r10+56] + mov rax, QWORD PTR [rcx+192] + mov QWORD PTR [rcx+184], r8 + adc rax, QWORD PTR [r10+64] + mov r8, QWORD PTR [rcx+200] + mov QWORD PTR [rcx+192], rax + adc r8, QWORD PTR [r10+72] + mov rax, QWORD PTR [rcx+208] + mov QWORD PTR [rcx+200], r8 + adc rax, QWORD PTR [r10+80] + mov r8, QWORD PTR [rcx+216] + mov QWORD PTR [rcx+208], rax + adc r8, QWORD PTR [r10+88] + mov rax, QWORD PTR [rcx+224] + mov QWORD PTR [rcx+216], r8 + adc rax, QWORD PTR [r10+96] + mov r8, QWORD PTR [rcx+232] + mov QWORD PTR [rcx+224], rax + adc r8, QWORD PTR [r10+104] + mov rax, QWORD PTR [rcx+240] + mov QWORD PTR [rcx+232], r8 + adc rax, QWORD PTR [r10+112] + mov r8, QWORD PTR [rcx+248] + mov QWORD PTR [rcx+240], rax + adc r8, QWORD PTR [r10+120] + mov rax, QWORD PTR [rcx+256] + mov QWORD PTR [rcx+248], r8 + adc rax, QWORD PTR [r10+128] + mov r8, QWORD PTR [rcx+264] + mov QWORD PTR [rcx+256], rax + adc r8, QWORD PTR [r10+136] + mov rax, QWORD PTR [rcx+272] + mov QWORD PTR [rcx+264], r8 + adc rax, QWORD PTR [r10+144] + mov r8, QWORD PTR [rcx+280] + mov QWORD PTR [rcx+272], rax + adc r8, QWORD PTR [r10+152] + mov rax, QWORD PTR [rcx+288] + mov QWORD PTR [rcx+280], r8 + adc rax, QWORD PTR [r10+160] + mov r8, QWORD PTR [rcx+296] + mov QWORD PTR [rcx+288], rax + adc r8, QWORD PTR [r10+168] + mov rax, QWORD PTR [rcx+304] + mov QWORD PTR [rcx+296], r8 + adc rax, QWORD PTR [r10+176] + mov r8, QWORD PTR [rcx+312] + mov QWORD PTR [rcx+304], rax + adc r8, QWORD PTR [r10+184] + mov rax, QWORD PTR [rcx+320] + mov QWORD PTR [rcx+312], r8 + adc rax, QWORD PTR [r10+192] + mov r8, QWORD PTR [rcx+328] + mov QWORD PTR [rcx+320], rax + adc r8, QWORD PTR [r10+200] + mov rax, QWORD PTR [rcx+336] + mov QWORD PTR [rcx+328], r8 + adc rax, QWORD PTR [r10+208] + mov r8, QWORD PTR [rcx+344] + mov QWORD PTR [rcx+336], rax + adc r8, QWORD PTR [r10+216] + mov rax, QWORD PTR [rcx+352] + mov QWORD PTR [rcx+344], r8 + adc rax, QWORD PTR [r10+224] + mov r8, QWORD PTR [rcx+360] + mov QWORD PTR [rcx+352], rax + adc r8, QWORD PTR [r10+232] + mov rax, QWORD PTR [rcx+368] + mov QWORD PTR [rcx+360], r8 + adc rax, QWORD PTR [r10+240] + mov r8, QWORD PTR [rcx+376] + mov QWORD PTR [rcx+368], rax + adc r8, QWORD PTR [r10+248] + mov QWORD PTR [rcx+376], r8 + adc r9, 0 + mov QWORD PTR [rcx+384], r9 + ; Add in place + mov rax, QWORD PTR [rcx+256] + xor r9, r9 + add rax, QWORD PTR [rdx] + mov r8, QWORD PTR [rcx+264] + mov QWORD PTR [rcx+256], rax + adc r8, QWORD PTR [rdx+8] + mov rax, QWORD PTR [rcx+272] + mov QWORD PTR [rcx+264], r8 + adc rax, QWORD PTR [rdx+16] + mov r8, QWORD PTR [rcx+280] + mov QWORD PTR [rcx+272], rax + adc r8, QWORD PTR [rdx+24] + mov rax, QWORD PTR [rcx+288] + mov QWORD PTR [rcx+280], r8 + adc rax, QWORD PTR [rdx+32] + mov r8, QWORD PTR [rcx+296] + mov QWORD PTR [rcx+288], rax + adc r8, QWORD PTR [rdx+40] + mov rax, QWORD PTR [rcx+304] + mov QWORD PTR [rcx+296], r8 + adc rax, QWORD PTR [rdx+48] + mov r8, QWORD PTR [rcx+312] + mov QWORD PTR [rcx+304], rax + adc r8, QWORD PTR [rdx+56] + mov rax, QWORD PTR [rcx+320] + mov QWORD PTR [rcx+312], r8 + adc rax, QWORD PTR [rdx+64] + mov r8, QWORD PTR [rcx+328] + mov QWORD PTR [rcx+320], rax + adc r8, QWORD PTR [rdx+72] + mov rax, QWORD PTR [rcx+336] + mov QWORD PTR [rcx+328], r8 + adc rax, QWORD PTR [rdx+80] + mov r8, QWORD PTR [rcx+344] + mov QWORD PTR [rcx+336], rax + adc r8, QWORD PTR [rdx+88] + mov rax, QWORD PTR [rcx+352] + mov QWORD PTR [rcx+344], r8 + adc rax, QWORD PTR [rdx+96] + mov r8, QWORD PTR [rcx+360] + mov QWORD PTR [rcx+352], rax + adc r8, QWORD PTR [rdx+104] + mov rax, QWORD PTR [rcx+368] + mov QWORD PTR [rcx+360], r8 + adc rax, QWORD PTR [rdx+112] + mov r8, QWORD PTR [rcx+376] + mov QWORD PTR [rcx+368], rax + adc r8, QWORD PTR [rdx+120] + mov rax, QWORD PTR [rcx+384] + mov QWORD PTR [rcx+376], r8 + adc rax, QWORD PTR [rdx+128] + mov QWORD PTR [rcx+384], rax + adc r9, 0 + ; Add to zero + mov rax, QWORD PTR [rdx+136] + adc rax, 0 + mov r8, QWORD PTR [rdx+144] + mov QWORD PTR [rcx+392], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+152] + mov QWORD PTR [rcx+400], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+160] + mov QWORD PTR [rcx+408], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+168] + mov QWORD PTR [rcx+416], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+176] + mov QWORD PTR [rcx+424], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+184] + mov QWORD PTR [rcx+432], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+192] + mov QWORD PTR [rcx+440], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+200] + mov QWORD PTR [rcx+448], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+208] + mov QWORD PTR [rcx+456], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+216] + mov QWORD PTR [rcx+464], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+224] + mov QWORD PTR [rcx+472], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+232] + mov QWORD PTR [rcx+480], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+240] + mov QWORD PTR [rcx+488], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+248] + mov QWORD PTR [rcx+496], r8 + adc rax, 0 + mov QWORD PTR [rcx+504], rax + add rsp, 664 + pop r12 + ret +sp_2048_sqr_32 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Multiply a and b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_2048_mul_avx2_32 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + sub rsp, 808 + mov QWORD PTR [rsp+768], rcx + mov QWORD PTR [rsp+776], rdx + mov QWORD PTR [rsp+784], r8 + lea r12, QWORD PTR [rsp+512] + lea r14, QWORD PTR [rdx+128] + ; Add + mov rax, QWORD PTR [rdx] + xor r15, r15 + add rax, QWORD PTR [r14] + mov r9, QWORD PTR [rdx+8] + mov QWORD PTR [r12], rax + adc r9, QWORD PTR [r14+8] + mov r10, QWORD PTR [rdx+16] + mov QWORD PTR [r12+8], r9 + adc r10, QWORD PTR [r14+16] + mov rax, QWORD PTR [rdx+24] + mov QWORD PTR [r12+16], r10 + adc rax, QWORD PTR [r14+24] + mov r9, QWORD PTR [rdx+32] + mov QWORD PTR [r12+24], rax + adc r9, QWORD PTR [r14+32] + mov r10, QWORD PTR [rdx+40] + mov QWORD PTR [r12+32], r9 + adc r10, QWORD PTR [r14+40] + mov rax, QWORD PTR [rdx+48] + mov QWORD PTR [r12+40], r10 + adc rax, QWORD PTR [r14+48] + mov r9, QWORD PTR [rdx+56] + mov QWORD PTR [r12+48], rax + adc r9, QWORD PTR [r14+56] + mov r10, QWORD PTR [rdx+64] + mov QWORD PTR [r12+56], r9 + adc r10, QWORD PTR [r14+64] + mov rax, QWORD PTR [rdx+72] + mov QWORD PTR [r12+64], r10 + adc rax, QWORD PTR [r14+72] + mov r9, QWORD PTR [rdx+80] + mov QWORD PTR [r12+72], rax + adc r9, QWORD PTR [r14+80] + mov r10, QWORD PTR [rdx+88] + mov QWORD PTR [r12+80], r9 + adc r10, QWORD PTR [r14+88] + mov rax, QWORD PTR [rdx+96] + mov QWORD PTR [r12+88], r10 + adc rax, QWORD PTR [r14+96] + mov r9, QWORD PTR [rdx+104] + mov QWORD PTR [r12+96], rax + adc r9, QWORD PTR [r14+104] + mov r10, QWORD PTR [rdx+112] + mov QWORD PTR [r12+104], r9 + adc r10, QWORD PTR [r14+112] + mov rax, QWORD PTR [rdx+120] + mov QWORD PTR [r12+112], r10 + adc rax, QWORD PTR [r14+120] + mov QWORD PTR [r12+120], rax + adc r15, 0 + mov QWORD PTR [rsp+792], r15 + lea r13, QWORD PTR [rsp+640] + lea r14, QWORD PTR [r8+128] + ; Add + mov rax, QWORD PTR [r8] + xor rdi, rdi + add rax, QWORD PTR [r14] + mov r9, QWORD PTR [r8+8] + mov QWORD PTR [r13], rax + adc r9, QWORD PTR [r14+8] + mov r10, QWORD PTR [r8+16] + mov QWORD PTR [r13+8], r9 + adc r10, QWORD PTR [r14+16] + mov rax, QWORD PTR [r8+24] + mov QWORD PTR [r13+16], r10 + adc rax, QWORD PTR [r14+24] + mov r9, QWORD PTR [r8+32] + mov QWORD PTR [r13+24], rax + adc r9, QWORD PTR [r14+32] + mov r10, QWORD PTR [r8+40] + mov QWORD PTR [r13+32], r9 + adc r10, QWORD PTR [r14+40] + mov rax, QWORD PTR [r8+48] + mov QWORD PTR [r13+40], r10 + adc rax, QWORD PTR [r14+48] + mov r9, QWORD PTR [r8+56] + mov QWORD PTR [r13+48], rax + adc r9, QWORD PTR [r14+56] + mov r10, QWORD PTR [r8+64] + mov QWORD PTR [r13+56], r9 + adc r10, QWORD PTR [r14+64] + mov rax, QWORD PTR [r8+72] + mov QWORD PTR [r13+64], r10 + adc rax, QWORD PTR [r14+72] + mov r9, QWORD PTR [r8+80] + mov QWORD PTR [r13+72], rax + adc r9, QWORD PTR [r14+80] + mov r10, QWORD PTR [r8+88] + mov QWORD PTR [r13+80], r9 + adc r10, QWORD PTR [r14+88] + mov rax, QWORD PTR [r8+96] + mov QWORD PTR [r13+88], r10 + adc rax, QWORD PTR [r14+96] + mov r9, QWORD PTR [r8+104] + mov QWORD PTR [r13+96], rax + adc r9, QWORD PTR [r14+104] + mov r10, QWORD PTR [r8+112] + mov QWORD PTR [r13+104], r9 + adc r10, QWORD PTR [r14+112] + mov rax, QWORD PTR [r8+120] + mov QWORD PTR [r13+112], r10 + adc rax, QWORD PTR [r14+120] + mov QWORD PTR [r13+120], rax + adc rdi, 0 + mov QWORD PTR [rsp+800], rdi + mov r8, r13 + mov rdx, r12 + mov rcx, rsp + call sp_2048_mul_avx2_16 + mov r8, QWORD PTR [rsp+784] + mov rdx, QWORD PTR [rsp+776] + lea rcx, QWORD PTR [rsp+256] + add r8, 128 + add rdx, 128 + call sp_2048_mul_avx2_16 + mov r8, QWORD PTR [rsp+784] + mov rdx, QWORD PTR [rsp+776] + mov rcx, QWORD PTR [rsp+768] + call sp_2048_mul_avx2_16 +IFDEF _WIN64 + mov r8, QWORD PTR [rsp+784] + mov rdx, QWORD PTR [rsp+776] + mov rcx, QWORD PTR [rsp+768] +ENDIF + mov r15, QWORD PTR [rsp+792] + mov rdi, QWORD PTR [rsp+800] + mov rsi, QWORD PTR [rsp+768] + mov r11, r15 + lea r12, QWORD PTR [rsp+512] + lea r13, QWORD PTR [rsp+640] + and r11, rdi + neg r15 + neg rdi + add rsi, 256 + mov rax, QWORD PTR [r12] + mov r9, QWORD PTR [r13] + pext rax, rax, rdi + pext r9, r9, r15 + add rax, r9 + mov r9, QWORD PTR [r12+8] + mov r10, QWORD PTR [r13+8] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi], rax + adc r9, r10 + mov r10, QWORD PTR [r12+16] + mov rax, QWORD PTR [r13+16] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+8], r9 + adc r10, rax + mov rax, QWORD PTR [r12+24] + mov r9, QWORD PTR [r13+24] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+16], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+32] + mov r10, QWORD PTR [r13+32] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+24], rax + adc r9, r10 + mov r10, QWORD PTR [r12+40] + mov rax, QWORD PTR [r13+40] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+32], r9 + adc r10, rax + mov rax, QWORD PTR [r12+48] + mov r9, QWORD PTR [r13+48] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+40], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+56] + mov r10, QWORD PTR [r13+56] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+48], rax + adc r9, r10 + mov r10, QWORD PTR [r12+64] + mov rax, QWORD PTR [r13+64] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+56], r9 + adc r10, rax + mov rax, QWORD PTR [r12+72] + mov r9, QWORD PTR [r13+72] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+64], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+80] + mov r10, QWORD PTR [r13+80] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+72], rax + adc r9, r10 + mov r10, QWORD PTR [r12+88] + mov rax, QWORD PTR [r13+88] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+80], r9 + adc r10, rax + mov rax, QWORD PTR [r12+96] + mov r9, QWORD PTR [r13+96] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+88], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+104] + mov r10, QWORD PTR [r13+104] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+96], rax + adc r9, r10 + mov r10, QWORD PTR [r12+112] + mov rax, QWORD PTR [r13+112] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+104], r9 + adc r10, rax + mov rax, QWORD PTR [r12+120] + mov r9, QWORD PTR [r13+120] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+112], r10 + adc rax, r9 + mov QWORD PTR [rsi+120], rax + adc r11, 0 + lea r13, QWORD PTR [rsp+256] + mov r12, rsp + mov rax, QWORD PTR [r12] + sub rax, QWORD PTR [r13] + mov r9, QWORD PTR [r12+8] + mov QWORD PTR [r12], rax + sbb r9, QWORD PTR [r13+8] + mov r10, QWORD PTR [r12+16] + mov QWORD PTR [r12+8], r9 + sbb r10, QWORD PTR [r13+16] + mov rax, QWORD PTR [r12+24] + mov QWORD PTR [r12+16], r10 + sbb rax, QWORD PTR [r13+24] + mov r9, QWORD PTR [r12+32] + mov QWORD PTR [r12+24], rax + sbb r9, QWORD PTR [r13+32] + mov r10, QWORD PTR [r12+40] + mov QWORD PTR [r12+32], r9 + sbb r10, QWORD PTR [r13+40] + mov rax, QWORD PTR [r12+48] + mov QWORD PTR [r12+40], r10 + sbb rax, QWORD PTR [r13+48] + mov r9, QWORD PTR [r12+56] + mov QWORD PTR [r12+48], rax + sbb r9, QWORD PTR [r13+56] + mov r10, QWORD PTR [r12+64] + mov QWORD PTR [r12+56], r9 + sbb r10, QWORD PTR [r13+64] + mov rax, QWORD PTR [r12+72] + mov QWORD PTR [r12+64], r10 + sbb rax, QWORD PTR [r13+72] + mov r9, QWORD PTR [r12+80] + mov QWORD PTR [r12+72], rax + sbb r9, QWORD PTR [r13+80] + mov r10, QWORD PTR [r12+88] + mov QWORD PTR [r12+80], r9 + sbb r10, QWORD PTR [r13+88] + mov rax, QWORD PTR [r12+96] + mov QWORD PTR [r12+88], r10 + sbb rax, QWORD PTR [r13+96] + mov r9, QWORD PTR [r12+104] + mov QWORD PTR [r12+96], rax + sbb r9, QWORD PTR [r13+104] + mov r10, QWORD PTR [r12+112] + mov QWORD PTR [r12+104], r9 + sbb r10, QWORD PTR [r13+112] + mov rax, QWORD PTR [r12+120] + mov QWORD PTR [r12+112], r10 + sbb rax, QWORD PTR [r13+120] + mov r9, QWORD PTR [r12+128] + mov QWORD PTR [r12+120], rax + sbb r9, QWORD PTR [r13+128] + mov r10, QWORD PTR [r12+136] + mov QWORD PTR [r12+128], r9 + sbb r10, QWORD PTR [r13+136] + mov rax, QWORD PTR [r12+144] + mov QWORD PTR [r12+136], r10 + sbb rax, QWORD PTR [r13+144] + mov r9, QWORD PTR [r12+152] + mov QWORD PTR [r12+144], rax + sbb r9, QWORD PTR [r13+152] + mov r10, QWORD PTR [r12+160] + mov QWORD PTR [r12+152], r9 + sbb r10, QWORD PTR [r13+160] + mov rax, QWORD PTR [r12+168] + mov QWORD PTR [r12+160], r10 + sbb rax, QWORD PTR [r13+168] + mov r9, QWORD PTR [r12+176] + mov QWORD PTR [r12+168], rax + sbb r9, QWORD PTR [r13+176] + mov r10, QWORD PTR [r12+184] + mov QWORD PTR [r12+176], r9 + sbb r10, QWORD PTR [r13+184] + mov rax, QWORD PTR [r12+192] + mov QWORD PTR [r12+184], r10 + sbb rax, QWORD PTR [r13+192] + mov r9, QWORD PTR [r12+200] + mov QWORD PTR [r12+192], rax + sbb r9, QWORD PTR [r13+200] + mov r10, QWORD PTR [r12+208] + mov QWORD PTR [r12+200], r9 + sbb r10, QWORD PTR [r13+208] + mov rax, QWORD PTR [r12+216] + mov QWORD PTR [r12+208], r10 + sbb rax, QWORD PTR [r13+216] + mov r9, QWORD PTR [r12+224] + mov QWORD PTR [r12+216], rax + sbb r9, QWORD PTR [r13+224] + mov r10, QWORD PTR [r12+232] + mov QWORD PTR [r12+224], r9 + sbb r10, QWORD PTR [r13+232] + mov rax, QWORD PTR [r12+240] + mov QWORD PTR [r12+232], r10 + sbb rax, QWORD PTR [r13+240] + mov r9, QWORD PTR [r12+248] + mov QWORD PTR [r12+240], rax + sbb r9, QWORD PTR [r13+248] + mov QWORD PTR [r12+248], r9 + sbb r11, 0 + mov rax, QWORD PTR [r12] + sub rax, QWORD PTR [rcx] + mov r9, QWORD PTR [r12+8] + mov QWORD PTR [r12], rax + sbb r9, QWORD PTR [rcx+8] + mov r10, QWORD PTR [r12+16] + mov QWORD PTR [r12+8], r9 + sbb r10, QWORD PTR [rcx+16] + mov rax, QWORD PTR [r12+24] + mov QWORD PTR [r12+16], r10 + sbb rax, QWORD PTR [rcx+24] + mov r9, QWORD PTR [r12+32] + mov QWORD PTR [r12+24], rax + sbb r9, QWORD PTR [rcx+32] + mov r10, QWORD PTR [r12+40] + mov QWORD PTR [r12+32], r9 + sbb r10, QWORD PTR [rcx+40] + mov rax, QWORD PTR [r12+48] + mov QWORD PTR [r12+40], r10 + sbb rax, QWORD PTR [rcx+48] + mov r9, QWORD PTR [r12+56] + mov QWORD PTR [r12+48], rax + sbb r9, QWORD PTR [rcx+56] + mov r10, QWORD PTR [r12+64] + mov QWORD PTR [r12+56], r9 + sbb r10, QWORD PTR [rcx+64] + mov rax, QWORD PTR [r12+72] + mov QWORD PTR [r12+64], r10 + sbb rax, QWORD PTR [rcx+72] + mov r9, QWORD PTR [r12+80] + mov QWORD PTR [r12+72], rax + sbb r9, QWORD PTR [rcx+80] + mov r10, QWORD PTR [r12+88] + mov QWORD PTR [r12+80], r9 + sbb r10, QWORD PTR [rcx+88] + mov rax, QWORD PTR [r12+96] + mov QWORD PTR [r12+88], r10 + sbb rax, QWORD PTR [rcx+96] + mov r9, QWORD PTR [r12+104] + mov QWORD PTR [r12+96], rax + sbb r9, QWORD PTR [rcx+104] + mov r10, QWORD PTR [r12+112] + mov QWORD PTR [r12+104], r9 + sbb r10, QWORD PTR [rcx+112] + mov rax, QWORD PTR [r12+120] + mov QWORD PTR [r12+112], r10 + sbb rax, QWORD PTR [rcx+120] + mov r9, QWORD PTR [r12+128] + mov QWORD PTR [r12+120], rax + sbb r9, QWORD PTR [rcx+128] + mov r10, QWORD PTR [r12+136] + mov QWORD PTR [r12+128], r9 + sbb r10, QWORD PTR [rcx+136] + mov rax, QWORD PTR [r12+144] + mov QWORD PTR [r12+136], r10 + sbb rax, QWORD PTR [rcx+144] + mov r9, QWORD PTR [r12+152] + mov QWORD PTR [r12+144], rax + sbb r9, QWORD PTR [rcx+152] + mov r10, QWORD PTR [r12+160] + mov QWORD PTR [r12+152], r9 + sbb r10, QWORD PTR [rcx+160] + mov rax, QWORD PTR [r12+168] + mov QWORD PTR [r12+160], r10 + sbb rax, QWORD PTR [rcx+168] + mov r9, QWORD PTR [r12+176] + mov QWORD PTR [r12+168], rax + sbb r9, QWORD PTR [rcx+176] + mov r10, QWORD PTR [r12+184] + mov QWORD PTR [r12+176], r9 + sbb r10, QWORD PTR [rcx+184] + mov rax, QWORD PTR [r12+192] + mov QWORD PTR [r12+184], r10 + sbb rax, QWORD PTR [rcx+192] + mov r9, QWORD PTR [r12+200] + mov QWORD PTR [r12+192], rax + sbb r9, QWORD PTR [rcx+200] + mov r10, QWORD PTR [r12+208] + mov QWORD PTR [r12+200], r9 + sbb r10, QWORD PTR [rcx+208] + mov rax, QWORD PTR [r12+216] + mov QWORD PTR [r12+208], r10 + sbb rax, QWORD PTR [rcx+216] + mov r9, QWORD PTR [r12+224] + mov QWORD PTR [r12+216], rax + sbb r9, QWORD PTR [rcx+224] + mov r10, QWORD PTR [r12+232] + mov QWORD PTR [r12+224], r9 + sbb r10, QWORD PTR [rcx+232] + mov rax, QWORD PTR [r12+240] + mov QWORD PTR [r12+232], r10 + sbb rax, QWORD PTR [rcx+240] + mov r9, QWORD PTR [r12+248] + mov QWORD PTR [r12+240], rax + sbb r9, QWORD PTR [rcx+248] + mov QWORD PTR [r12+248], r9 + sbb r11, 0 + sub rsi, 128 + ; Add + mov rax, QWORD PTR [rsi] + add rax, QWORD PTR [r12] + mov r9, QWORD PTR [rsi+8] + mov QWORD PTR [rsi], rax + adc r9, QWORD PTR [r12+8] + mov r10, QWORD PTR [rsi+16] + mov QWORD PTR [rsi+8], r9 + adc r10, QWORD PTR [r12+16] + mov rax, QWORD PTR [rsi+24] + mov QWORD PTR [rsi+16], r10 + adc rax, QWORD PTR [r12+24] + mov r9, QWORD PTR [rsi+32] + mov QWORD PTR [rsi+24], rax + adc r9, QWORD PTR [r12+32] + mov r10, QWORD PTR [rsi+40] + mov QWORD PTR [rsi+32], r9 + adc r10, QWORD PTR [r12+40] + mov rax, QWORD PTR [rsi+48] + mov QWORD PTR [rsi+40], r10 + adc rax, QWORD PTR [r12+48] + mov r9, QWORD PTR [rsi+56] + mov QWORD PTR [rsi+48], rax + adc r9, QWORD PTR [r12+56] + mov r10, QWORD PTR [rsi+64] + mov QWORD PTR [rsi+56], r9 + adc r10, QWORD PTR [r12+64] + mov rax, QWORD PTR [rsi+72] + mov QWORD PTR [rsi+64], r10 + adc rax, QWORD PTR [r12+72] + mov r9, QWORD PTR [rsi+80] + mov QWORD PTR [rsi+72], rax + adc r9, QWORD PTR [r12+80] + mov r10, QWORD PTR [rsi+88] + mov QWORD PTR [rsi+80], r9 + adc r10, QWORD PTR [r12+88] + mov rax, QWORD PTR [rsi+96] + mov QWORD PTR [rsi+88], r10 + adc rax, QWORD PTR [r12+96] + mov r9, QWORD PTR [rsi+104] + mov QWORD PTR [rsi+96], rax + adc r9, QWORD PTR [r12+104] + mov r10, QWORD PTR [rsi+112] + mov QWORD PTR [rsi+104], r9 + adc r10, QWORD PTR [r12+112] + mov rax, QWORD PTR [rsi+120] + mov QWORD PTR [rsi+112], r10 + adc rax, QWORD PTR [r12+120] + mov r9, QWORD PTR [rsi+128] + mov QWORD PTR [rsi+120], rax + adc r9, QWORD PTR [r12+128] + mov r10, QWORD PTR [rsi+136] + mov QWORD PTR [rsi+128], r9 + adc r10, QWORD PTR [r12+136] + mov rax, QWORD PTR [rsi+144] + mov QWORD PTR [rsi+136], r10 + adc rax, QWORD PTR [r12+144] + mov r9, QWORD PTR [rsi+152] + mov QWORD PTR [rsi+144], rax + adc r9, QWORD PTR [r12+152] + mov r10, QWORD PTR [rsi+160] + mov QWORD PTR [rsi+152], r9 + adc r10, QWORD PTR [r12+160] + mov rax, QWORD PTR [rsi+168] + mov QWORD PTR [rsi+160], r10 + adc rax, QWORD PTR [r12+168] + mov r9, QWORD PTR [rsi+176] + mov QWORD PTR [rsi+168], rax + adc r9, QWORD PTR [r12+176] + mov r10, QWORD PTR [rsi+184] + mov QWORD PTR [rsi+176], r9 + adc r10, QWORD PTR [r12+184] + mov rax, QWORD PTR [rsi+192] + mov QWORD PTR [rsi+184], r10 + adc rax, QWORD PTR [r12+192] + mov r9, QWORD PTR [rsi+200] + mov QWORD PTR [rsi+192], rax + adc r9, QWORD PTR [r12+200] + mov r10, QWORD PTR [rsi+208] + mov QWORD PTR [rsi+200], r9 + adc r10, QWORD PTR [r12+208] + mov rax, QWORD PTR [rsi+216] + mov QWORD PTR [rsi+208], r10 + adc rax, QWORD PTR [r12+216] + mov r9, QWORD PTR [rsi+224] + mov QWORD PTR [rsi+216], rax + adc r9, QWORD PTR [r12+224] + mov r10, QWORD PTR [rsi+232] + mov QWORD PTR [rsi+224], r9 + adc r10, QWORD PTR [r12+232] + mov rax, QWORD PTR [rsi+240] + mov QWORD PTR [rsi+232], r10 + adc rax, QWORD PTR [r12+240] + mov r9, QWORD PTR [rsi+248] + mov QWORD PTR [rsi+240], rax + adc r9, QWORD PTR [r12+248] + mov QWORD PTR [rsi+248], r9 + adc r11, 0 + mov QWORD PTR [rcx+384], r11 + add rsi, 128 + ; Add + mov rax, QWORD PTR [rsi] + xor r11, r11 + add rax, QWORD PTR [r13] + mov r9, QWORD PTR [rsi+8] + mov QWORD PTR [rsi], rax + adc r9, QWORD PTR [r13+8] + mov r10, QWORD PTR [rsi+16] + mov QWORD PTR [rsi+8], r9 + adc r10, QWORD PTR [r13+16] + mov rax, QWORD PTR [rsi+24] + mov QWORD PTR [rsi+16], r10 + adc rax, QWORD PTR [r13+24] + mov r9, QWORD PTR [rsi+32] + mov QWORD PTR [rsi+24], rax + adc r9, QWORD PTR [r13+32] + mov r10, QWORD PTR [rsi+40] + mov QWORD PTR [rsi+32], r9 + adc r10, QWORD PTR [r13+40] + mov rax, QWORD PTR [rsi+48] + mov QWORD PTR [rsi+40], r10 + adc rax, QWORD PTR [r13+48] + mov r9, QWORD PTR [rsi+56] + mov QWORD PTR [rsi+48], rax + adc r9, QWORD PTR [r13+56] + mov r10, QWORD PTR [rsi+64] + mov QWORD PTR [rsi+56], r9 + adc r10, QWORD PTR [r13+64] + mov rax, QWORD PTR [rsi+72] + mov QWORD PTR [rsi+64], r10 + adc rax, QWORD PTR [r13+72] + mov r9, QWORD PTR [rsi+80] + mov QWORD PTR [rsi+72], rax + adc r9, QWORD PTR [r13+80] + mov r10, QWORD PTR [rsi+88] + mov QWORD PTR [rsi+80], r9 + adc r10, QWORD PTR [r13+88] + mov rax, QWORD PTR [rsi+96] + mov QWORD PTR [rsi+88], r10 + adc rax, QWORD PTR [r13+96] + mov r9, QWORD PTR [rsi+104] + mov QWORD PTR [rsi+96], rax + adc r9, QWORD PTR [r13+104] + mov r10, QWORD PTR [rsi+112] + mov QWORD PTR [rsi+104], r9 + adc r10, QWORD PTR [r13+112] + mov rax, QWORD PTR [rsi+120] + mov QWORD PTR [rsi+112], r10 + adc rax, QWORD PTR [r13+120] + mov r9, QWORD PTR [rsi+128] + mov QWORD PTR [rsi+120], rax + adc r9, QWORD PTR [r13+128] + mov QWORD PTR [rsi+128], r9 + adc r11, 0 + ; Add to zero + mov rax, QWORD PTR [r13+136] + adc rax, 0 + mov r9, QWORD PTR [r13+144] + mov QWORD PTR [rsi+136], rax + adc r9, 0 + mov r10, QWORD PTR [r13+152] + mov QWORD PTR [rsi+144], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+160] + mov QWORD PTR [rsi+152], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+168] + mov QWORD PTR [rsi+160], rax + adc r9, 0 + mov r10, QWORD PTR [r13+176] + mov QWORD PTR [rsi+168], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+184] + mov QWORD PTR [rsi+176], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+192] + mov QWORD PTR [rsi+184], rax + adc r9, 0 + mov r10, QWORD PTR [r13+200] + mov QWORD PTR [rsi+192], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+208] + mov QWORD PTR [rsi+200], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+216] + mov QWORD PTR [rsi+208], rax + adc r9, 0 + mov r10, QWORD PTR [r13+224] + mov QWORD PTR [rsi+216], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+232] + mov QWORD PTR [rsi+224], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+240] + mov QWORD PTR [rsi+232], rax + adc r9, 0 + mov r10, QWORD PTR [r13+248] + mov QWORD PTR [rsi+240], r9 + adc r10, 0 + mov QWORD PTR [rsi+248], r10 + add rsp, 808 + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_2048_mul_avx2_32 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Square a and put result in r. (r = a * a) +; * +; * r A single precision integer. +; * a A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_2048_sqr_avx2_32 PROC + push r12 + sub rsp, 664 + mov QWORD PTR [rsp+640], rcx + mov QWORD PTR [rsp+648], rdx + lea r10, QWORD PTR [rsp+512] + lea r11, QWORD PTR [rdx+128] + ; Add + mov rax, QWORD PTR [rdx] + xor r9, r9 + add rax, QWORD PTR [r11] + mov r8, QWORD PTR [rdx+8] + mov QWORD PTR [r10], rax + adc r8, QWORD PTR [r11+8] + mov rax, QWORD PTR [rdx+16] + mov QWORD PTR [r10+8], r8 + adc rax, QWORD PTR [r11+16] + mov r8, QWORD PTR [rdx+24] + mov QWORD PTR [r10+16], rax + adc r8, QWORD PTR [r11+24] + mov rax, QWORD PTR [rdx+32] + mov QWORD PTR [r10+24], r8 + adc rax, QWORD PTR [r11+32] + mov r8, QWORD PTR [rdx+40] + mov QWORD PTR [r10+32], rax + adc r8, QWORD PTR [r11+40] + mov rax, QWORD PTR [rdx+48] + mov QWORD PTR [r10+40], r8 + adc rax, QWORD PTR [r11+48] + mov r8, QWORD PTR [rdx+56] + mov QWORD PTR [r10+48], rax + adc r8, QWORD PTR [r11+56] + mov rax, QWORD PTR [rdx+64] + mov QWORD PTR [r10+56], r8 + adc rax, QWORD PTR [r11+64] + mov r8, QWORD PTR [rdx+72] + mov QWORD PTR [r10+64], rax + adc r8, QWORD PTR [r11+72] + mov rax, QWORD PTR [rdx+80] + mov QWORD PTR [r10+72], r8 + adc rax, QWORD PTR [r11+80] + mov r8, QWORD PTR [rdx+88] + mov QWORD PTR [r10+80], rax + adc r8, QWORD PTR [r11+88] + mov rax, QWORD PTR [rdx+96] + mov QWORD PTR [r10+88], r8 + adc rax, QWORD PTR [r11+96] + mov r8, QWORD PTR [rdx+104] + mov QWORD PTR [r10+96], rax + adc r8, QWORD PTR [r11+104] + mov rax, QWORD PTR [rdx+112] + mov QWORD PTR [r10+104], r8 + adc rax, QWORD PTR [r11+112] + mov r8, QWORD PTR [rdx+120] + mov QWORD PTR [r10+112], rax + adc r8, QWORD PTR [r11+120] + mov QWORD PTR [r10+120], r8 + adc r9, 0 + mov QWORD PTR [rsp+656], r9 + mov rdx, r10 + mov rcx, rsp + call sp_2048_sqr_avx2_16 + mov rdx, QWORD PTR [rsp+648] + lea rcx, QWORD PTR [rsp+256] + add rdx, 128 + call sp_2048_sqr_avx2_16 + mov rdx, QWORD PTR [rsp+648] + mov rcx, QWORD PTR [rsp+640] + call sp_2048_sqr_avx2_16 +IFDEF _WIN64 + mov rdx, QWORD PTR [rsp+648] + mov rcx, QWORD PTR [rsp+640] +ENDIF + mov r12, QWORD PTR [rsp+656] + lea r10, QWORD PTR [rsp+512] + mov r9, r12 + neg r12 + mov rax, QWORD PTR [r10] + pext rax, rax, r12 + add rax, rax + mov r8, QWORD PTR [r10+8] + mov QWORD PTR [rcx+256], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+16] + mov QWORD PTR [rcx+264], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+24] + mov QWORD PTR [rcx+272], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+32] + mov QWORD PTR [rcx+280], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+40] + mov QWORD PTR [rcx+288], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+48] + mov QWORD PTR [rcx+296], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+56] + mov QWORD PTR [rcx+304], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+64] + mov QWORD PTR [rcx+312], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+72] + mov QWORD PTR [rcx+320], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+80] + mov QWORD PTR [rcx+328], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+88] + mov QWORD PTR [rcx+336], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+96] + mov QWORD PTR [rcx+344], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+104] + mov QWORD PTR [rcx+352], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+112] + mov QWORD PTR [rcx+360], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+120] + mov QWORD PTR [rcx+368], rax + pext r8, r8, r12 + adc r8, r8 + mov QWORD PTR [rcx+376], r8 + adc r9, 0 + lea rdx, QWORD PTR [rsp+256] + mov r10, rsp + mov rax, QWORD PTR [r10] + sub rax, QWORD PTR [rdx] + mov r8, QWORD PTR [r10+8] + mov QWORD PTR [r10], rax + sbb r8, QWORD PTR [rdx+8] + mov rax, QWORD PTR [r10+16] + mov QWORD PTR [r10+8], r8 + sbb rax, QWORD PTR [rdx+16] + mov r8, QWORD PTR [r10+24] + mov QWORD PTR [r10+16], rax + sbb r8, QWORD PTR [rdx+24] + mov rax, QWORD PTR [r10+32] + mov QWORD PTR [r10+24], r8 + sbb rax, QWORD PTR [rdx+32] + mov r8, QWORD PTR [r10+40] + mov QWORD PTR [r10+32], rax + sbb r8, QWORD PTR [rdx+40] + mov rax, QWORD PTR [r10+48] + mov QWORD PTR [r10+40], r8 + sbb rax, QWORD PTR [rdx+48] + mov r8, QWORD PTR [r10+56] + mov QWORD PTR [r10+48], rax + sbb r8, QWORD PTR [rdx+56] + mov rax, QWORD PTR [r10+64] + mov QWORD PTR [r10+56], r8 + sbb rax, QWORD PTR [rdx+64] + mov r8, QWORD PTR [r10+72] + mov QWORD PTR [r10+64], rax + sbb r8, QWORD PTR [rdx+72] + mov rax, QWORD PTR [r10+80] + mov QWORD PTR [r10+72], r8 + sbb rax, QWORD PTR [rdx+80] + mov r8, QWORD PTR [r10+88] + mov QWORD PTR [r10+80], rax + sbb r8, QWORD PTR [rdx+88] + mov rax, QWORD PTR [r10+96] + mov QWORD PTR [r10+88], r8 + sbb rax, QWORD PTR [rdx+96] + mov r8, QWORD PTR [r10+104] + mov QWORD PTR [r10+96], rax + sbb r8, QWORD PTR [rdx+104] + mov rax, QWORD PTR [r10+112] + mov QWORD PTR [r10+104], r8 + sbb rax, QWORD PTR [rdx+112] + mov r8, QWORD PTR [r10+120] + mov QWORD PTR [r10+112], rax + sbb r8, QWORD PTR [rdx+120] + mov rax, QWORD PTR [r10+128] + mov QWORD PTR [r10+120], r8 + sbb rax, QWORD PTR [rdx+128] + mov r8, QWORD PTR [r10+136] + mov QWORD PTR [r10+128], rax + sbb r8, QWORD PTR [rdx+136] + mov rax, QWORD PTR [r10+144] + mov QWORD PTR [r10+136], r8 + sbb rax, QWORD PTR [rdx+144] + mov r8, QWORD PTR [r10+152] + mov QWORD PTR [r10+144], rax + sbb r8, QWORD PTR [rdx+152] + mov rax, QWORD PTR [r10+160] + mov QWORD PTR [r10+152], r8 + sbb rax, QWORD PTR [rdx+160] + mov r8, QWORD PTR [r10+168] + mov QWORD PTR [r10+160], rax + sbb r8, QWORD PTR [rdx+168] + mov rax, QWORD PTR [r10+176] + mov QWORD PTR [r10+168], r8 + sbb rax, QWORD PTR [rdx+176] + mov r8, QWORD PTR [r10+184] + mov QWORD PTR [r10+176], rax + sbb r8, QWORD PTR [rdx+184] + mov rax, QWORD PTR [r10+192] + mov QWORD PTR [r10+184], r8 + sbb rax, QWORD PTR [rdx+192] + mov r8, QWORD PTR [r10+200] + mov QWORD PTR [r10+192], rax + sbb r8, QWORD PTR [rdx+200] + mov rax, QWORD PTR [r10+208] + mov QWORD PTR [r10+200], r8 + sbb rax, QWORD PTR [rdx+208] + mov r8, QWORD PTR [r10+216] + mov QWORD PTR [r10+208], rax + sbb r8, QWORD PTR [rdx+216] + mov rax, QWORD PTR [r10+224] + mov QWORD PTR [r10+216], r8 + sbb rax, QWORD PTR [rdx+224] + mov r8, QWORD PTR [r10+232] + mov QWORD PTR [r10+224], rax + sbb r8, QWORD PTR [rdx+232] + mov rax, QWORD PTR [r10+240] + mov QWORD PTR [r10+232], r8 + sbb rax, QWORD PTR [rdx+240] + mov r8, QWORD PTR [r10+248] + mov QWORD PTR [r10+240], rax + sbb r8, QWORD PTR [rdx+248] + mov QWORD PTR [r10+248], r8 + sbb r9, 0 + mov rax, QWORD PTR [r10] + sub rax, QWORD PTR [rcx] + mov r8, QWORD PTR [r10+8] + mov QWORD PTR [r10], rax + sbb r8, QWORD PTR [rcx+8] + mov rax, QWORD PTR [r10+16] + mov QWORD PTR [r10+8], r8 + sbb rax, QWORD PTR [rcx+16] + mov r8, QWORD PTR [r10+24] + mov QWORD PTR [r10+16], rax + sbb r8, QWORD PTR [rcx+24] + mov rax, QWORD PTR [r10+32] + mov QWORD PTR [r10+24], r8 + sbb rax, QWORD PTR [rcx+32] + mov r8, QWORD PTR [r10+40] + mov QWORD PTR [r10+32], rax + sbb r8, QWORD PTR [rcx+40] + mov rax, QWORD PTR [r10+48] + mov QWORD PTR [r10+40], r8 + sbb rax, QWORD PTR [rcx+48] + mov r8, QWORD PTR [r10+56] + mov QWORD PTR [r10+48], rax + sbb r8, QWORD PTR [rcx+56] + mov rax, QWORD PTR [r10+64] + mov QWORD PTR [r10+56], r8 + sbb rax, QWORD PTR [rcx+64] + mov r8, QWORD PTR [r10+72] + mov QWORD PTR [r10+64], rax + sbb r8, QWORD PTR [rcx+72] + mov rax, QWORD PTR [r10+80] + mov QWORD PTR [r10+72], r8 + sbb rax, QWORD PTR [rcx+80] + mov r8, QWORD PTR [r10+88] + mov QWORD PTR [r10+80], rax + sbb r8, QWORD PTR [rcx+88] + mov rax, QWORD PTR [r10+96] + mov QWORD PTR [r10+88], r8 + sbb rax, QWORD PTR [rcx+96] + mov r8, QWORD PTR [r10+104] + mov QWORD PTR [r10+96], rax + sbb r8, QWORD PTR [rcx+104] + mov rax, QWORD PTR [r10+112] + mov QWORD PTR [r10+104], r8 + sbb rax, QWORD PTR [rcx+112] + mov r8, QWORD PTR [r10+120] + mov QWORD PTR [r10+112], rax + sbb r8, QWORD PTR [rcx+120] + mov rax, QWORD PTR [r10+128] + mov QWORD PTR [r10+120], r8 + sbb rax, QWORD PTR [rcx+128] + mov r8, QWORD PTR [r10+136] + mov QWORD PTR [r10+128], rax + sbb r8, QWORD PTR [rcx+136] + mov rax, QWORD PTR [r10+144] + mov QWORD PTR [r10+136], r8 + sbb rax, QWORD PTR [rcx+144] + mov r8, QWORD PTR [r10+152] + mov QWORD PTR [r10+144], rax + sbb r8, QWORD PTR [rcx+152] + mov rax, QWORD PTR [r10+160] + mov QWORD PTR [r10+152], r8 + sbb rax, QWORD PTR [rcx+160] + mov r8, QWORD PTR [r10+168] + mov QWORD PTR [r10+160], rax + sbb r8, QWORD PTR [rcx+168] + mov rax, QWORD PTR [r10+176] + mov QWORD PTR [r10+168], r8 + sbb rax, QWORD PTR [rcx+176] + mov r8, QWORD PTR [r10+184] + mov QWORD PTR [r10+176], rax + sbb r8, QWORD PTR [rcx+184] + mov rax, QWORD PTR [r10+192] + mov QWORD PTR [r10+184], r8 + sbb rax, QWORD PTR [rcx+192] + mov r8, QWORD PTR [r10+200] + mov QWORD PTR [r10+192], rax + sbb r8, QWORD PTR [rcx+200] + mov rax, QWORD PTR [r10+208] + mov QWORD PTR [r10+200], r8 + sbb rax, QWORD PTR [rcx+208] + mov r8, QWORD PTR [r10+216] + mov QWORD PTR [r10+208], rax + sbb r8, QWORD PTR [rcx+216] + mov rax, QWORD PTR [r10+224] + mov QWORD PTR [r10+216], r8 + sbb rax, QWORD PTR [rcx+224] + mov r8, QWORD PTR [r10+232] + mov QWORD PTR [r10+224], rax + sbb r8, QWORD PTR [rcx+232] + mov rax, QWORD PTR [r10+240] + mov QWORD PTR [r10+232], r8 + sbb rax, QWORD PTR [rcx+240] + mov r8, QWORD PTR [r10+248] + mov QWORD PTR [r10+240], rax + sbb r8, QWORD PTR [rcx+248] + mov QWORD PTR [r10+248], r8 + sbb r9, 0 + ; Add in place + mov rax, QWORD PTR [rcx+128] + add rax, QWORD PTR [r10] + mov r8, QWORD PTR [rcx+136] + mov QWORD PTR [rcx+128], rax + adc r8, QWORD PTR [r10+8] + mov rax, QWORD PTR [rcx+144] + mov QWORD PTR [rcx+136], r8 + adc rax, QWORD PTR [r10+16] + mov r8, QWORD PTR [rcx+152] + mov QWORD PTR [rcx+144], rax + adc r8, QWORD PTR [r10+24] + mov rax, QWORD PTR [rcx+160] + mov QWORD PTR [rcx+152], r8 + adc rax, QWORD PTR [r10+32] + mov r8, QWORD PTR [rcx+168] + mov QWORD PTR [rcx+160], rax + adc r8, QWORD PTR [r10+40] + mov rax, QWORD PTR [rcx+176] + mov QWORD PTR [rcx+168], r8 + adc rax, QWORD PTR [r10+48] + mov r8, QWORD PTR [rcx+184] + mov QWORD PTR [rcx+176], rax + adc r8, QWORD PTR [r10+56] + mov rax, QWORD PTR [rcx+192] + mov QWORD PTR [rcx+184], r8 + adc rax, QWORD PTR [r10+64] + mov r8, QWORD PTR [rcx+200] + mov QWORD PTR [rcx+192], rax + adc r8, QWORD PTR [r10+72] + mov rax, QWORD PTR [rcx+208] + mov QWORD PTR [rcx+200], r8 + adc rax, QWORD PTR [r10+80] + mov r8, QWORD PTR [rcx+216] + mov QWORD PTR [rcx+208], rax + adc r8, QWORD PTR [r10+88] + mov rax, QWORD PTR [rcx+224] + mov QWORD PTR [rcx+216], r8 + adc rax, QWORD PTR [r10+96] + mov r8, QWORD PTR [rcx+232] + mov QWORD PTR [rcx+224], rax + adc r8, QWORD PTR [r10+104] + mov rax, QWORD PTR [rcx+240] + mov QWORD PTR [rcx+232], r8 + adc rax, QWORD PTR [r10+112] + mov r8, QWORD PTR [rcx+248] + mov QWORD PTR [rcx+240], rax + adc r8, QWORD PTR [r10+120] + mov rax, QWORD PTR [rcx+256] + mov QWORD PTR [rcx+248], r8 + adc rax, QWORD PTR [r10+128] + mov r8, QWORD PTR [rcx+264] + mov QWORD PTR [rcx+256], rax + adc r8, QWORD PTR [r10+136] + mov rax, QWORD PTR [rcx+272] + mov QWORD PTR [rcx+264], r8 + adc rax, QWORD PTR [r10+144] + mov r8, QWORD PTR [rcx+280] + mov QWORD PTR [rcx+272], rax + adc r8, QWORD PTR [r10+152] + mov rax, QWORD PTR [rcx+288] + mov QWORD PTR [rcx+280], r8 + adc rax, QWORD PTR [r10+160] + mov r8, QWORD PTR [rcx+296] + mov QWORD PTR [rcx+288], rax + adc r8, QWORD PTR [r10+168] + mov rax, QWORD PTR [rcx+304] + mov QWORD PTR [rcx+296], r8 + adc rax, QWORD PTR [r10+176] + mov r8, QWORD PTR [rcx+312] + mov QWORD PTR [rcx+304], rax + adc r8, QWORD PTR [r10+184] + mov rax, QWORD PTR [rcx+320] + mov QWORD PTR [rcx+312], r8 + adc rax, QWORD PTR [r10+192] + mov r8, QWORD PTR [rcx+328] + mov QWORD PTR [rcx+320], rax + adc r8, QWORD PTR [r10+200] + mov rax, QWORD PTR [rcx+336] + mov QWORD PTR [rcx+328], r8 + adc rax, QWORD PTR [r10+208] + mov r8, QWORD PTR [rcx+344] + mov QWORD PTR [rcx+336], rax + adc r8, QWORD PTR [r10+216] + mov rax, QWORD PTR [rcx+352] + mov QWORD PTR [rcx+344], r8 + adc rax, QWORD PTR [r10+224] + mov r8, QWORD PTR [rcx+360] + mov QWORD PTR [rcx+352], rax + adc r8, QWORD PTR [r10+232] + mov rax, QWORD PTR [rcx+368] + mov QWORD PTR [rcx+360], r8 + adc rax, QWORD PTR [r10+240] + mov r8, QWORD PTR [rcx+376] + mov QWORD PTR [rcx+368], rax + adc r8, QWORD PTR [r10+248] + mov QWORD PTR [rcx+376], r8 + adc r9, 0 + mov QWORD PTR [rcx+384], r9 + ; Add in place + mov rax, QWORD PTR [rcx+256] + xor r9, r9 + add rax, QWORD PTR [rdx] + mov r8, QWORD PTR [rcx+264] + mov QWORD PTR [rcx+256], rax + adc r8, QWORD PTR [rdx+8] + mov rax, QWORD PTR [rcx+272] + mov QWORD PTR [rcx+264], r8 + adc rax, QWORD PTR [rdx+16] + mov r8, QWORD PTR [rcx+280] + mov QWORD PTR [rcx+272], rax + adc r8, QWORD PTR [rdx+24] + mov rax, QWORD PTR [rcx+288] + mov QWORD PTR [rcx+280], r8 + adc rax, QWORD PTR [rdx+32] + mov r8, QWORD PTR [rcx+296] + mov QWORD PTR [rcx+288], rax + adc r8, QWORD PTR [rdx+40] + mov rax, QWORD PTR [rcx+304] + mov QWORD PTR [rcx+296], r8 + adc rax, QWORD PTR [rdx+48] + mov r8, QWORD PTR [rcx+312] + mov QWORD PTR [rcx+304], rax + adc r8, QWORD PTR [rdx+56] + mov rax, QWORD PTR [rcx+320] + mov QWORD PTR [rcx+312], r8 + adc rax, QWORD PTR [rdx+64] + mov r8, QWORD PTR [rcx+328] + mov QWORD PTR [rcx+320], rax + adc r8, QWORD PTR [rdx+72] + mov rax, QWORD PTR [rcx+336] + mov QWORD PTR [rcx+328], r8 + adc rax, QWORD PTR [rdx+80] + mov r8, QWORD PTR [rcx+344] + mov QWORD PTR [rcx+336], rax + adc r8, QWORD PTR [rdx+88] + mov rax, QWORD PTR [rcx+352] + mov QWORD PTR [rcx+344], r8 + adc rax, QWORD PTR [rdx+96] + mov r8, QWORD PTR [rcx+360] + mov QWORD PTR [rcx+352], rax + adc r8, QWORD PTR [rdx+104] + mov rax, QWORD PTR [rcx+368] + mov QWORD PTR [rcx+360], r8 + adc rax, QWORD PTR [rdx+112] + mov r8, QWORD PTR [rcx+376] + mov QWORD PTR [rcx+368], rax + adc r8, QWORD PTR [rdx+120] + mov rax, QWORD PTR [rcx+384] + mov QWORD PTR [rcx+376], r8 + adc rax, QWORD PTR [rdx+128] + mov QWORD PTR [rcx+384], rax + adc r9, 0 + ; Add to zero + mov rax, QWORD PTR [rdx+136] + adc rax, 0 + mov r8, QWORD PTR [rdx+144] + mov QWORD PTR [rcx+392], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+152] + mov QWORD PTR [rcx+400], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+160] + mov QWORD PTR [rcx+408], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+168] + mov QWORD PTR [rcx+416], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+176] + mov QWORD PTR [rcx+424], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+184] + mov QWORD PTR [rcx+432], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+192] + mov QWORD PTR [rcx+440], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+200] + mov QWORD PTR [rcx+448], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+208] + mov QWORD PTR [rcx+456], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+216] + mov QWORD PTR [rcx+464], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+224] + mov QWORD PTR [rcx+472], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+232] + mov QWORD PTR [rcx+480], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+240] + mov QWORD PTR [rcx+488], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+248] + mov QWORD PTR [rcx+496], r8 + adc rax, 0 + mov QWORD PTR [rcx+504], rax + add rsp, 664 + pop r12 + ret +sp_2048_sqr_avx2_32 ENDP +_text ENDS +ENDIF +; /* Sub b from a into a. (a -= b) +; * +; * a A single precision integer and result. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_2048_sub_in_place_16 PROC + mov r8, QWORD PTR [rcx] + xor rax, rax + sub r8, QWORD PTR [rdx] + mov r9, QWORD PTR [rcx+8] + mov QWORD PTR [rcx], r8 + sbb r9, QWORD PTR [rdx+8] + mov r8, QWORD PTR [rcx+16] + mov QWORD PTR [rcx+8], r9 + sbb r8, QWORD PTR [rdx+16] + mov r9, QWORD PTR [rcx+24] + mov QWORD PTR [rcx+16], r8 + sbb r9, QWORD PTR [rdx+24] + mov r8, QWORD PTR [rcx+32] + mov QWORD PTR [rcx+24], r9 + sbb r8, QWORD PTR [rdx+32] + mov r9, QWORD PTR [rcx+40] + mov QWORD PTR [rcx+32], r8 + sbb r9, QWORD PTR [rdx+40] + mov r8, QWORD PTR [rcx+48] + mov QWORD PTR [rcx+40], r9 + sbb r8, QWORD PTR [rdx+48] + mov r9, QWORD PTR [rcx+56] + mov QWORD PTR [rcx+48], r8 + sbb r9, QWORD PTR [rdx+56] + mov r8, QWORD PTR [rcx+64] + mov QWORD PTR [rcx+56], r9 + sbb r8, QWORD PTR [rdx+64] + mov r9, QWORD PTR [rcx+72] + mov QWORD PTR [rcx+64], r8 + sbb r9, QWORD PTR [rdx+72] + mov r8, QWORD PTR [rcx+80] + mov QWORD PTR [rcx+72], r9 + sbb r8, QWORD PTR [rdx+80] + mov r9, QWORD PTR [rcx+88] + mov QWORD PTR [rcx+80], r8 + sbb r9, QWORD PTR [rdx+88] + mov r8, QWORD PTR [rcx+96] + mov QWORD PTR [rcx+88], r9 + sbb r8, QWORD PTR [rdx+96] + mov r9, QWORD PTR [rcx+104] + mov QWORD PTR [rcx+96], r8 + sbb r9, QWORD PTR [rdx+104] + mov r8, QWORD PTR [rcx+112] + mov QWORD PTR [rcx+104], r9 + sbb r8, QWORD PTR [rdx+112] + mov r9, QWORD PTR [rcx+120] + mov QWORD PTR [rcx+112], r8 + sbb r9, QWORD PTR [rdx+120] + mov QWORD PTR [rcx+120], r9 + sbb rax, 0 + ret +sp_2048_sub_in_place_16 ENDP +_text ENDS +; /* Mul a by digit b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision digit. +; */ +_text SEGMENT READONLY PARA +sp_2048_mul_d_32 PROC + push r12 + mov r9, rdx + ; A[0] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9] + mov r10, rax + mov r11, rdx + mov QWORD PTR [rcx], r10 + ; A[1] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+8] + add r11, rax + mov QWORD PTR [rcx+8], r11 + adc r12, rdx + adc r10, 0 + ; A[2] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+16] + add r12, rax + mov QWORD PTR [rcx+16], r12 + adc r10, rdx + adc r11, 0 + ; A[3] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+24] + add r10, rax + mov QWORD PTR [rcx+24], r10 + adc r11, rdx + adc r12, 0 + ; A[4] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+32] + add r11, rax + mov QWORD PTR [rcx+32], r11 + adc r12, rdx + adc r10, 0 + ; A[5] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+40] + add r12, rax + mov QWORD PTR [rcx+40], r12 + adc r10, rdx + adc r11, 0 + ; A[6] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+48] + add r10, rax + mov QWORD PTR [rcx+48], r10 + adc r11, rdx + adc r12, 0 + ; A[7] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+56] + add r11, rax + mov QWORD PTR [rcx+56], r11 + adc r12, rdx + adc r10, 0 + ; A[8] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+64] + add r12, rax + mov QWORD PTR [rcx+64], r12 + adc r10, rdx + adc r11, 0 + ; A[9] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+72] + add r10, rax + mov QWORD PTR [rcx+72], r10 + adc r11, rdx + adc r12, 0 + ; A[10] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+80] + add r11, rax + mov QWORD PTR [rcx+80], r11 + adc r12, rdx + adc r10, 0 + ; A[11] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+88] + add r12, rax + mov QWORD PTR [rcx+88], r12 + adc r10, rdx + adc r11, 0 + ; A[12] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+96] + add r10, rax + mov QWORD PTR [rcx+96], r10 + adc r11, rdx + adc r12, 0 + ; A[13] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+104] + add r11, rax + mov QWORD PTR [rcx+104], r11 + adc r12, rdx + adc r10, 0 + ; A[14] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+112] + add r12, rax + mov QWORD PTR [rcx+112], r12 + adc r10, rdx + adc r11, 0 + ; A[15] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+120] + add r10, rax + mov QWORD PTR [rcx+120], r10 + adc r11, rdx + adc r12, 0 + ; A[16] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+128] + add r11, rax + mov QWORD PTR [rcx+128], r11 + adc r12, rdx + adc r10, 0 + ; A[17] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+136] + add r12, rax + mov QWORD PTR [rcx+136], r12 + adc r10, rdx + adc r11, 0 + ; A[18] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+144] + add r10, rax + mov QWORD PTR [rcx+144], r10 + adc r11, rdx + adc r12, 0 + ; A[19] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+152] + add r11, rax + mov QWORD PTR [rcx+152], r11 + adc r12, rdx + adc r10, 0 + ; A[20] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+160] + add r12, rax + mov QWORD PTR [rcx+160], r12 + adc r10, rdx + adc r11, 0 + ; A[21] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+168] + add r10, rax + mov QWORD PTR [rcx+168], r10 + adc r11, rdx + adc r12, 0 + ; A[22] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+176] + add r11, rax + mov QWORD PTR [rcx+176], r11 + adc r12, rdx + adc r10, 0 + ; A[23] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+184] + add r12, rax + mov QWORD PTR [rcx+184], r12 + adc r10, rdx + adc r11, 0 + ; A[24] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+192] + add r10, rax + mov QWORD PTR [rcx+192], r10 + adc r11, rdx + adc r12, 0 + ; A[25] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+200] + add r11, rax + mov QWORD PTR [rcx+200], r11 + adc r12, rdx + adc r10, 0 + ; A[26] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+208] + add r12, rax + mov QWORD PTR [rcx+208], r12 + adc r10, rdx + adc r11, 0 + ; A[27] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+216] + add r10, rax + mov QWORD PTR [rcx+216], r10 + adc r11, rdx + adc r12, 0 + ; A[28] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+224] + add r11, rax + mov QWORD PTR [rcx+224], r11 + adc r12, rdx + adc r10, 0 + ; A[29] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+232] + add r12, rax + mov QWORD PTR [rcx+232], r12 + adc r10, rdx + adc r11, 0 + ; A[30] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+240] + add r10, rax + mov QWORD PTR [rcx+240], r10 + adc r11, rdx + adc r12, 0 + ; A[31] * B + mov rax, r8 + mul QWORD PTR [r9+248] + add r11, rax + adc r12, rdx + mov QWORD PTR [rcx+248], r11 + mov QWORD PTR [rcx+256], r12 + pop r12 + ret +sp_2048_mul_d_32 ENDP +_text ENDS +; /* Conditionally subtract b from a using the mask m. +; * m is -1 to subtract and 0 when not copying. +; * +; * r A single precision number representing condition subtract result. +; * a A single precision number to subtract from. +; * b A single precision number to subtract. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_2048_cond_sub_16 PROC + sub rsp, 128 + mov rax, 0 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp], r10 + mov QWORD PTR [rsp+8], r11 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+16], r10 + mov QWORD PTR [rsp+24], r11 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+32], r10 + mov QWORD PTR [rsp+40], r11 + mov r10, QWORD PTR [r8+48] + mov r11, QWORD PTR [r8+56] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+48], r10 + mov QWORD PTR [rsp+56], r11 + mov r10, QWORD PTR [r8+64] + mov r11, QWORD PTR [r8+72] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+64], r10 + mov QWORD PTR [rsp+72], r11 + mov r10, QWORD PTR [r8+80] + mov r11, QWORD PTR [r8+88] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+80], r10 + mov QWORD PTR [rsp+88], r11 + mov r10, QWORD PTR [r8+96] + mov r11, QWORD PTR [r8+104] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+96], r10 + mov QWORD PTR [rsp+104], r11 + mov r10, QWORD PTR [r8+112] + mov r11, QWORD PTR [r8+120] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+112], r10 + mov QWORD PTR [rsp+120], r11 + mov r10, QWORD PTR [rdx] + mov r8, QWORD PTR [rsp] + sub r10, r8 + mov r11, QWORD PTR [rdx+8] + mov r8, QWORD PTR [rsp+8] + sbb r11, r8 + mov QWORD PTR [rcx], r10 + mov r10, QWORD PTR [rdx+16] + mov r8, QWORD PTR [rsp+16] + sbb r10, r8 + mov QWORD PTR [rcx+8], r11 + mov r11, QWORD PTR [rdx+24] + mov r8, QWORD PTR [rsp+24] + sbb r11, r8 + mov QWORD PTR [rcx+16], r10 + mov r10, QWORD PTR [rdx+32] + mov r8, QWORD PTR [rsp+32] + sbb r10, r8 + mov QWORD PTR [rcx+24], r11 + mov r11, QWORD PTR [rdx+40] + mov r8, QWORD PTR [rsp+40] + sbb r11, r8 + mov QWORD PTR [rcx+32], r10 + mov r10, QWORD PTR [rdx+48] + mov r8, QWORD PTR [rsp+48] + sbb r10, r8 + mov QWORD PTR [rcx+40], r11 + mov r11, QWORD PTR [rdx+56] + mov r8, QWORD PTR [rsp+56] + sbb r11, r8 + mov QWORD PTR [rcx+48], r10 + mov r10, QWORD PTR [rdx+64] + mov r8, QWORD PTR [rsp+64] + sbb r10, r8 + mov QWORD PTR [rcx+56], r11 + mov r11, QWORD PTR [rdx+72] + mov r8, QWORD PTR [rsp+72] + sbb r11, r8 + mov QWORD PTR [rcx+64], r10 + mov r10, QWORD PTR [rdx+80] + mov r8, QWORD PTR [rsp+80] + sbb r10, r8 + mov QWORD PTR [rcx+72], r11 + mov r11, QWORD PTR [rdx+88] + mov r8, QWORD PTR [rsp+88] + sbb r11, r8 + mov QWORD PTR [rcx+80], r10 + mov r10, QWORD PTR [rdx+96] + mov r8, QWORD PTR [rsp+96] + sbb r10, r8 + mov QWORD PTR [rcx+88], r11 + mov r11, QWORD PTR [rdx+104] + mov r8, QWORD PTR [rsp+104] + sbb r11, r8 + mov QWORD PTR [rcx+96], r10 + mov r10, QWORD PTR [rdx+112] + mov r8, QWORD PTR [rsp+112] + sbb r10, r8 + mov QWORD PTR [rcx+104], r11 + mov r11, QWORD PTR [rdx+120] + mov r8, QWORD PTR [rsp+120] + sbb r11, r8 + mov QWORD PTR [rcx+112], r10 + mov QWORD PTR [rcx+120], r11 + sbb rax, 0 + add rsp, 128 + ret +sp_2048_cond_sub_16 ENDP +_text ENDS +; /* Reduce the number back to 2048 bits using Montgomery reduction. +; * +; * a A single precision number to reduce in place. +; * m The single precision number representing the modulus. +; * mp The digit representing the negative inverse of m mod 2^n. +; */ +_text SEGMENT READONLY PARA +sp_2048_mont_reduce_16 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + mov r9, rdx + xor rsi, rsi + ; i = 16 + mov r10, 16 + mov r15, QWORD PTR [rcx] + mov rdi, QWORD PTR [rcx+8] +L_2048_mont_loop_16: + ; mu = a[i] * mp + mov r13, r15 + imul r13, r8 + ; a[i+0] += m[0] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9] + add r15, rax + adc r12, rdx + ; a[i+1] += m[1] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+8] + mov r15, rdi + add r15, rax + adc r11, rdx + add r15, r12 + adc r11, 0 + ; a[i+2] += m[2] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+16] + mov rdi, QWORD PTR [rcx+16] + add rdi, rax + adc r12, rdx + add rdi, r11 + adc r12, 0 + ; a[i+3] += m[3] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+24] + mov r14, QWORD PTR [rcx+24] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+24], r14 + adc r11, 0 + ; a[i+4] += m[4] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+32] + mov r14, QWORD PTR [rcx+32] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+32], r14 + adc r12, 0 + ; a[i+5] += m[5] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+40] + mov r14, QWORD PTR [rcx+40] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+40], r14 + adc r11, 0 + ; a[i+6] += m[6] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+48] + mov r14, QWORD PTR [rcx+48] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+48], r14 + adc r12, 0 + ; a[i+7] += m[7] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+56] + mov r14, QWORD PTR [rcx+56] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+56], r14 + adc r11, 0 + ; a[i+8] += m[8] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+64] + mov r14, QWORD PTR [rcx+64] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+64], r14 + adc r12, 0 + ; a[i+9] += m[9] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+72] + mov r14, QWORD PTR [rcx+72] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+72], r14 + adc r11, 0 + ; a[i+10] += m[10] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+80] + mov r14, QWORD PTR [rcx+80] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+80], r14 + adc r12, 0 + ; a[i+11] += m[11] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+88] + mov r14, QWORD PTR [rcx+88] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+88], r14 + adc r11, 0 + ; a[i+12] += m[12] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+96] + mov r14, QWORD PTR [rcx+96] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+96], r14 + adc r12, 0 + ; a[i+13] += m[13] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+104] + mov r14, QWORD PTR [rcx+104] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+104], r14 + adc r11, 0 + ; a[i+14] += m[14] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+112] + mov r14, QWORD PTR [rcx+112] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+112], r14 + adc r12, 0 + ; a[i+15] += m[15] * mu + mov rax, r13 + mul QWORD PTR [r9+120] + mov r14, QWORD PTR [rcx+120] + add r12, rax + adc rdx, rsi + mov rsi, 0 + adc rsi, 0 + add r14, r12 + mov QWORD PTR [rcx+120], r14 + adc QWORD PTR [rcx+128], rdx + adc rsi, 0 + ; i -= 1 + add rcx, 8 + dec r10 + jnz L_2048_mont_loop_16 + mov QWORD PTR [rcx], r15 + mov QWORD PTR [rcx+8], rdi + neg rsi +IFDEF _WIN64 + mov r8, r9 + mov r9, rsi +ELSE + mov r9, rsi + mov r8, r9 +ENDIF + mov rdx, rcx + mov rcx, rcx + sub rcx, 128 + call sp_2048_cond_sub_16 + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_2048_mont_reduce_16 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Conditionally subtract b from a using the mask m. +; * m is -1 to subtract and 0 when not copying. +; * +; * r A single precision number representing condition subtract result. +; * a A single precision number to subtract from. +; * b A single precision number to subtract. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_2048_cond_sub_avx2_16 PROC + push r12 + mov rax, 0 + mov r12, QWORD PTR [r8] + mov r10, QWORD PTR [rdx] + pext r12, r12, r9 + sub r10, r12 + mov r12, QWORD PTR [r8+8] + mov r11, QWORD PTR [rdx+8] + pext r12, r12, r9 + mov QWORD PTR [rcx], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+16] + mov r12, QWORD PTR [rdx+16] + pext r10, r10, r9 + mov QWORD PTR [rcx+8], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+24] + mov r10, QWORD PTR [rdx+24] + pext r11, r11, r9 + mov QWORD PTR [rcx+16], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+32] + mov r11, QWORD PTR [rdx+32] + pext r12, r12, r9 + mov QWORD PTR [rcx+24], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+40] + mov r12, QWORD PTR [rdx+40] + pext r10, r10, r9 + mov QWORD PTR [rcx+32], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+48] + mov r10, QWORD PTR [rdx+48] + pext r11, r11, r9 + mov QWORD PTR [rcx+40], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+56] + mov r11, QWORD PTR [rdx+56] + pext r12, r12, r9 + mov QWORD PTR [rcx+48], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+64] + mov r12, QWORD PTR [rdx+64] + pext r10, r10, r9 + mov QWORD PTR [rcx+56], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+72] + mov r10, QWORD PTR [rdx+72] + pext r11, r11, r9 + mov QWORD PTR [rcx+64], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+80] + mov r11, QWORD PTR [rdx+80] + pext r12, r12, r9 + mov QWORD PTR [rcx+72], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+88] + mov r12, QWORD PTR [rdx+88] + pext r10, r10, r9 + mov QWORD PTR [rcx+80], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+96] + mov r10, QWORD PTR [rdx+96] + pext r11, r11, r9 + mov QWORD PTR [rcx+88], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+104] + mov r11, QWORD PTR [rdx+104] + pext r12, r12, r9 + mov QWORD PTR [rcx+96], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+112] + mov r12, QWORD PTR [rdx+112] + pext r10, r10, r9 + mov QWORD PTR [rcx+104], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+120] + mov r10, QWORD PTR [rdx+120] + pext r11, r11, r9 + mov QWORD PTR [rcx+112], r12 + sbb r10, r11 + mov QWORD PTR [rcx+120], r10 + sbb rax, 0 + pop r12 + ret +sp_2048_cond_sub_avx2_16 ENDP +_text ENDS +ENDIF +; /* Mul a by digit b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision digit. +; */ +_text SEGMENT READONLY PARA +sp_2048_mul_d_16 PROC + push r12 + mov r9, rdx + ; A[0] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9] + mov r10, rax + mov r11, rdx + mov QWORD PTR [rcx], r10 + ; A[1] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+8] + add r11, rax + mov QWORD PTR [rcx+8], r11 + adc r12, rdx + adc r10, 0 + ; A[2] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+16] + add r12, rax + mov QWORD PTR [rcx+16], r12 + adc r10, rdx + adc r11, 0 + ; A[3] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+24] + add r10, rax + mov QWORD PTR [rcx+24], r10 + adc r11, rdx + adc r12, 0 + ; A[4] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+32] + add r11, rax + mov QWORD PTR [rcx+32], r11 + adc r12, rdx + adc r10, 0 + ; A[5] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+40] + add r12, rax + mov QWORD PTR [rcx+40], r12 + adc r10, rdx + adc r11, 0 + ; A[6] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+48] + add r10, rax + mov QWORD PTR [rcx+48], r10 + adc r11, rdx + adc r12, 0 + ; A[7] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+56] + add r11, rax + mov QWORD PTR [rcx+56], r11 + adc r12, rdx + adc r10, 0 + ; A[8] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+64] + add r12, rax + mov QWORD PTR [rcx+64], r12 + adc r10, rdx + adc r11, 0 + ; A[9] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+72] + add r10, rax + mov QWORD PTR [rcx+72], r10 + adc r11, rdx + adc r12, 0 + ; A[10] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+80] + add r11, rax + mov QWORD PTR [rcx+80], r11 + adc r12, rdx + adc r10, 0 + ; A[11] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+88] + add r12, rax + mov QWORD PTR [rcx+88], r12 + adc r10, rdx + adc r11, 0 + ; A[12] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+96] + add r10, rax + mov QWORD PTR [rcx+96], r10 + adc r11, rdx + adc r12, 0 + ; A[13] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+104] + add r11, rax + mov QWORD PTR [rcx+104], r11 + adc r12, rdx + adc r10, 0 + ; A[14] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+112] + add r12, rax + mov QWORD PTR [rcx+112], r12 + adc r10, rdx + adc r11, 0 + ; A[15] * B + mov rax, r8 + mul QWORD PTR [r9+120] + add r10, rax + adc r11, rdx + mov QWORD PTR [rcx+120], r10 + mov QWORD PTR [rcx+128], r11 + pop r12 + ret +sp_2048_mul_d_16 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Mul a by digit b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision digit. +; */ +_text SEGMENT READONLY PARA +sp_2048_mul_d_avx2_16 PROC + push r12 + push r13 + mov rax, rdx + ; A[0] * B + mov rdx, r8 + xor r13, r13 + mulx r12, r11, QWORD PTR [rax] + mov QWORD PTR [rcx], r11 + ; A[1] * B + mulx r10, r9, QWORD PTR [rax+8] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+8], r12 + ; A[2] * B + mulx r10, r9, QWORD PTR [rax+16] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+16], r11 + ; A[3] * B + mulx r10, r9, QWORD PTR [rax+24] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+24], r12 + ; A[4] * B + mulx r10, r9, QWORD PTR [rax+32] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+32], r11 + ; A[5] * B + mulx r10, r9, QWORD PTR [rax+40] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+40], r12 + ; A[6] * B + mulx r10, r9, QWORD PTR [rax+48] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+48], r11 + ; A[7] * B + mulx r10, r9, QWORD PTR [rax+56] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+56], r12 + ; A[8] * B + mulx r10, r9, QWORD PTR [rax+64] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+64], r11 + ; A[9] * B + mulx r10, r9, QWORD PTR [rax+72] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+72], r12 + ; A[10] * B + mulx r10, r9, QWORD PTR [rax+80] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+80], r11 + ; A[11] * B + mulx r10, r9, QWORD PTR [rax+88] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+88], r12 + ; A[12] * B + mulx r10, r9, QWORD PTR [rax+96] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+96], r11 + ; A[13] * B + mulx r10, r9, QWORD PTR [rax+104] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+104], r12 + ; A[14] * B + mulx r10, r9, QWORD PTR [rax+112] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+112], r11 + ; A[15] * B + mulx r10, r9, QWORD PTR [rax+120] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + adcx r11, r13 + mov QWORD PTR [rcx+120], r12 + mov QWORD PTR [rcx+128], r11 + pop r13 + pop r12 + ret +sp_2048_mul_d_avx2_16 ENDP +_text ENDS +ENDIF +IFDEF _WIN64 +; /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) +; * +; * d1 The high order half of the number to divide. +; * d0 The low order half of the number to divide. +; * div The dividend. +; * returns the result of the division. +; */ +_text SEGMENT READONLY PARA +div_2048_word_asm_16 PROC + mov r9, rdx + mov rax, r9 + mov rdx, rcx + div r8 + ret +div_2048_word_asm_16 ENDP +_text ENDS +ENDIF +; /* Compare a with b in constant time. +; * +; * a A single precision integer. +; * b A single precision integer. +; * return -ve, 0 or +ve if a is less than, equal to or greater than b +; * respectively. +; */ +_text SEGMENT READONLY PARA +sp_2048_cmp_16 PROC + push r12 + xor r9, r9 + mov r8, -1 + mov rax, -1 + mov r10, 1 + mov r11, QWORD PTR [rcx+120] + mov r12, QWORD PTR [rdx+120] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+112] + mov r12, QWORD PTR [rdx+112] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+104] + mov r12, QWORD PTR [rdx+104] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+96] + mov r12, QWORD PTR [rdx+96] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+88] + mov r12, QWORD PTR [rdx+88] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+80] + mov r12, QWORD PTR [rdx+80] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+72] + mov r12, QWORD PTR [rdx+72] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+64] + mov r12, QWORD PTR [rdx+64] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+56] + mov r12, QWORD PTR [rdx+56] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+48] + mov r12, QWORD PTR [rdx+48] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+40] + mov r12, QWORD PTR [rdx+40] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+32] + mov r12, QWORD PTR [rdx+32] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+24] + mov r12, QWORD PTR [rdx+24] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+16] + mov r12, QWORD PTR [rdx+16] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+8] + mov r12, QWORD PTR [rdx+8] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx] + mov r12, QWORD PTR [rdx] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + xor rax, r8 + pop r12 + ret +sp_2048_cmp_16 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Reduce the number back to 2048 bits using Montgomery reduction. +; * +; * a A single precision number to reduce in place. +; * m The single precision number representing the modulus. +; * mp The digit representing the negative inverse of m mod 2^n. +; */ +_text SEGMENT READONLY PARA +sp_2048_mont_reduce_avx2_16 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + push rbx + push rbp + mov r9, rcx + mov r10, rdx + xor rbp, rbp + ; i = 16 + mov r11, 16 + mov r15, QWORD PTR [r9] + mov rdi, QWORD PTR [r9+8] + mov rsi, QWORD PTR [r9+16] + mov rbx, QWORD PTR [r9+24] + add r9, 64 + xor rbp, rbp +L_2048_mont_loop_avx2_16: + ; mu = a[i] * mp + mov rdx, r15 + mov r12, r15 + imul rdx, r8 + xor r14, r14 + ; a[i+0] += m[0] * mu + mulx rcx, rax, QWORD PTR [r10] + mov r15, rdi + adcx r12, rax + adox r15, rcx + ; a[i+1] += m[1] * mu + mulx rcx, rax, QWORD PTR [r10+8] + mov rdi, rsi + adcx r15, rax + adox rdi, rcx + ; a[i+2] += m[2] * mu + mulx rcx, rax, QWORD PTR [r10+16] + mov rsi, rbx + adcx rdi, rax + adox rsi, rcx + ; a[i+3] += m[3] * mu + mulx rcx, rax, QWORD PTR [r10+24] + mov rbx, QWORD PTR [r9+-32] + adcx rsi, rax + adox rbx, rcx + ; a[i+4] += m[4] * mu + mulx rcx, rax, QWORD PTR [r10+32] + mov r13, QWORD PTR [r9+-24] + adcx rbx, rax + adox r13, rcx + ; a[i+5] += m[5] * mu + mulx rcx, rax, QWORD PTR [r10+40] + mov r12, QWORD PTR [r9+-16] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-24], r13 + ; a[i+6] += m[6] * mu + mulx rcx, rax, QWORD PTR [r10+48] + mov r13, QWORD PTR [r9+-8] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-16], r12 + ; a[i+7] += m[7] * mu + mulx rcx, rax, QWORD PTR [r10+56] + mov r12, QWORD PTR [r9] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-8], r13 + ; a[i+8] += m[8] * mu + mulx rcx, rax, QWORD PTR [r10+64] + mov r13, QWORD PTR [r9+8] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9], r12 + ; a[i+9] += m[9] * mu + mulx rcx, rax, QWORD PTR [r10+72] + mov r12, QWORD PTR [r9+16] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+8], r13 + ; a[i+10] += m[10] * mu + mulx rcx, rax, QWORD PTR [r10+80] + mov r13, QWORD PTR [r9+24] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+16], r12 + ; a[i+11] += m[11] * mu + mulx rcx, rax, QWORD PTR [r10+88] + mov r12, QWORD PTR [r9+32] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+24], r13 + ; a[i+12] += m[12] * mu + mulx rcx, rax, QWORD PTR [r10+96] + mov r13, QWORD PTR [r9+40] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+32], r12 + ; a[i+13] += m[13] * mu + mulx rcx, rax, QWORD PTR [r10+104] + mov r12, QWORD PTR [r9+48] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+40], r13 + ; a[i+14] += m[14] * mu + mulx rcx, rax, QWORD PTR [r10+112] + mov r13, QWORD PTR [r9+56] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+48], r12 + ; a[i+15] += m[15] * mu + mulx rcx, rax, QWORD PTR [r10+120] + mov r12, QWORD PTR [r9+64] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+56], r13 + adcx r12, rbp + mov rbp, r14 + mov QWORD PTR [r9+64], r12 + adox rbp, r14 + adcx rbp, r14 + ; mu = a[i] * mp + mov rdx, r15 + mov r12, r15 + imul rdx, r8 + xor r14, r14 + ; a[i+0] += m[0] * mu + mulx rcx, rax, QWORD PTR [r10] + mov r15, rdi + adcx r12, rax + adox r15, rcx + ; a[i+1] += m[1] * mu + mulx rcx, rax, QWORD PTR [r10+8] + mov rdi, rsi + adcx r15, rax + adox rdi, rcx + ; a[i+2] += m[2] * mu + mulx rcx, rax, QWORD PTR [r10+16] + mov rsi, rbx + adcx rdi, rax + adox rsi, rcx + ; a[i+3] += m[3] * mu + mulx rcx, rax, QWORD PTR [r10+24] + mov rbx, QWORD PTR [r9+-24] + adcx rsi, rax + adox rbx, rcx + ; a[i+4] += m[4] * mu + mulx rcx, rax, QWORD PTR [r10+32] + mov r13, QWORD PTR [r9+-16] + adcx rbx, rax + adox r13, rcx + ; a[i+5] += m[5] * mu + mulx rcx, rax, QWORD PTR [r10+40] + mov r12, QWORD PTR [r9+-8] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-16], r13 + ; a[i+6] += m[6] * mu + mulx rcx, rax, QWORD PTR [r10+48] + mov r13, QWORD PTR [r9] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-8], r12 + ; a[i+7] += m[7] * mu + mulx rcx, rax, QWORD PTR [r10+56] + mov r12, QWORD PTR [r9+8] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9], r13 + ; a[i+8] += m[8] * mu + mulx rcx, rax, QWORD PTR [r10+64] + mov r13, QWORD PTR [r9+16] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+8], r12 + ; a[i+9] += m[9] * mu + mulx rcx, rax, QWORD PTR [r10+72] + mov r12, QWORD PTR [r9+24] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+16], r13 + ; a[i+10] += m[10] * mu + mulx rcx, rax, QWORD PTR [r10+80] + mov r13, QWORD PTR [r9+32] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+24], r12 + ; a[i+11] += m[11] * mu + mulx rcx, rax, QWORD PTR [r10+88] + mov r12, QWORD PTR [r9+40] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+32], r13 + ; a[i+12] += m[12] * mu + mulx rcx, rax, QWORD PTR [r10+96] + mov r13, QWORD PTR [r9+48] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+40], r12 + ; a[i+13] += m[13] * mu + mulx rcx, rax, QWORD PTR [r10+104] + mov r12, QWORD PTR [r9+56] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+48], r13 + ; a[i+14] += m[14] * mu + mulx rcx, rax, QWORD PTR [r10+112] + mov r13, QWORD PTR [r9+64] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+56], r12 + ; a[i+15] += m[15] * mu + mulx rcx, rax, QWORD PTR [r10+120] + mov r12, QWORD PTR [r9+72] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+64], r13 + adcx r12, rbp + mov rbp, r14 + mov QWORD PTR [r9+72], r12 + adox rbp, r14 + adcx rbp, r14 + ; a += 2 + add r9, 16 + ; i -= 2 + sub r11, 2 + jnz L_2048_mont_loop_avx2_16 + sub r9, 64 + neg rbp + mov r8, r9 + sub r9, 128 + mov rcx, QWORD PTR [r10] + mov rdx, r15 + pext rcx, rcx, rbp + sub rdx, rcx + mov rcx, QWORD PTR [r10+8] + mov rax, rdi + pext rcx, rcx, rbp + mov QWORD PTR [r9], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+16] + mov rcx, rsi + pext rdx, rdx, rbp + mov QWORD PTR [r9+8], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+24] + mov rdx, rbx + pext rax, rax, rbp + mov QWORD PTR [r9+16], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+32] + mov rax, QWORD PTR [r8+32] + pext rcx, rcx, rbp + mov QWORD PTR [r9+24], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+40] + mov rcx, QWORD PTR [r8+40] + pext rdx, rdx, rbp + mov QWORD PTR [r9+32], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+48] + mov rdx, QWORD PTR [r8+48] + pext rax, rax, rbp + mov QWORD PTR [r9+40], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+56] + mov rax, QWORD PTR [r8+56] + pext rcx, rcx, rbp + mov QWORD PTR [r9+48], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+64] + mov rcx, QWORD PTR [r8+64] + pext rdx, rdx, rbp + mov QWORD PTR [r9+56], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+72] + mov rdx, QWORD PTR [r8+72] + pext rax, rax, rbp + mov QWORD PTR [r9+64], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+80] + mov rax, QWORD PTR [r8+80] + pext rcx, rcx, rbp + mov QWORD PTR [r9+72], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+88] + mov rcx, QWORD PTR [r8+88] + pext rdx, rdx, rbp + mov QWORD PTR [r9+80], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+96] + mov rdx, QWORD PTR [r8+96] + pext rax, rax, rbp + mov QWORD PTR [r9+88], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+104] + mov rax, QWORD PTR [r8+104] + pext rcx, rcx, rbp + mov QWORD PTR [r9+96], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+112] + mov rcx, QWORD PTR [r8+112] + pext rdx, rdx, rbp + mov QWORD PTR [r9+104], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+120] + mov rdx, QWORD PTR [r8+120] + pext rax, rax, rbp + mov QWORD PTR [r9+112], rcx + sbb rdx, rax + mov QWORD PTR [r9+120], rdx + pop rbp + pop rbx + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_2048_mont_reduce_avx2_16 ENDP +_text ENDS +ENDIF +; /* Conditionally subtract b from a using the mask m. +; * m is -1 to subtract and 0 when not copying. +; * +; * r A single precision number representing condition subtract result. +; * a A single precision number to subtract from. +; * b A single precision number to subtract. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_2048_cond_sub_32 PROC + sub rsp, 256 + mov rax, 0 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp], r10 + mov QWORD PTR [rsp+8], r11 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+16], r10 + mov QWORD PTR [rsp+24], r11 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+32], r10 + mov QWORD PTR [rsp+40], r11 + mov r10, QWORD PTR [r8+48] + mov r11, QWORD PTR [r8+56] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+48], r10 + mov QWORD PTR [rsp+56], r11 + mov r10, QWORD PTR [r8+64] + mov r11, QWORD PTR [r8+72] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+64], r10 + mov QWORD PTR [rsp+72], r11 + mov r10, QWORD PTR [r8+80] + mov r11, QWORD PTR [r8+88] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+80], r10 + mov QWORD PTR [rsp+88], r11 + mov r10, QWORD PTR [r8+96] + mov r11, QWORD PTR [r8+104] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+96], r10 + mov QWORD PTR [rsp+104], r11 + mov r10, QWORD PTR [r8+112] + mov r11, QWORD PTR [r8+120] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+112], r10 + mov QWORD PTR [rsp+120], r11 + mov r10, QWORD PTR [r8+128] + mov r11, QWORD PTR [r8+136] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+128], r10 + mov QWORD PTR [rsp+136], r11 + mov r10, QWORD PTR [r8+144] + mov r11, QWORD PTR [r8+152] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+144], r10 + mov QWORD PTR [rsp+152], r11 + mov r10, QWORD PTR [r8+160] + mov r11, QWORD PTR [r8+168] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+160], r10 + mov QWORD PTR [rsp+168], r11 + mov r10, QWORD PTR [r8+176] + mov r11, QWORD PTR [r8+184] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+176], r10 + mov QWORD PTR [rsp+184], r11 + mov r10, QWORD PTR [r8+192] + mov r11, QWORD PTR [r8+200] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+192], r10 + mov QWORD PTR [rsp+200], r11 + mov r10, QWORD PTR [r8+208] + mov r11, QWORD PTR [r8+216] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+208], r10 + mov QWORD PTR [rsp+216], r11 + mov r10, QWORD PTR [r8+224] + mov r11, QWORD PTR [r8+232] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+224], r10 + mov QWORD PTR [rsp+232], r11 + mov r10, QWORD PTR [r8+240] + mov r11, QWORD PTR [r8+248] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+240], r10 + mov QWORD PTR [rsp+248], r11 + mov r10, QWORD PTR [rdx] + mov r8, QWORD PTR [rsp] + sub r10, r8 + mov r11, QWORD PTR [rdx+8] + mov r8, QWORD PTR [rsp+8] + sbb r11, r8 + mov QWORD PTR [rcx], r10 + mov r10, QWORD PTR [rdx+16] + mov r8, QWORD PTR [rsp+16] + sbb r10, r8 + mov QWORD PTR [rcx+8], r11 + mov r11, QWORD PTR [rdx+24] + mov r8, QWORD PTR [rsp+24] + sbb r11, r8 + mov QWORD PTR [rcx+16], r10 + mov r10, QWORD PTR [rdx+32] + mov r8, QWORD PTR [rsp+32] + sbb r10, r8 + mov QWORD PTR [rcx+24], r11 + mov r11, QWORD PTR [rdx+40] + mov r8, QWORD PTR [rsp+40] + sbb r11, r8 + mov QWORD PTR [rcx+32], r10 + mov r10, QWORD PTR [rdx+48] + mov r8, QWORD PTR [rsp+48] + sbb r10, r8 + mov QWORD PTR [rcx+40], r11 + mov r11, QWORD PTR [rdx+56] + mov r8, QWORD PTR [rsp+56] + sbb r11, r8 + mov QWORD PTR [rcx+48], r10 + mov r10, QWORD PTR [rdx+64] + mov r8, QWORD PTR [rsp+64] + sbb r10, r8 + mov QWORD PTR [rcx+56], r11 + mov r11, QWORD PTR [rdx+72] + mov r8, QWORD PTR [rsp+72] + sbb r11, r8 + mov QWORD PTR [rcx+64], r10 + mov r10, QWORD PTR [rdx+80] + mov r8, QWORD PTR [rsp+80] + sbb r10, r8 + mov QWORD PTR [rcx+72], r11 + mov r11, QWORD PTR [rdx+88] + mov r8, QWORD PTR [rsp+88] + sbb r11, r8 + mov QWORD PTR [rcx+80], r10 + mov r10, QWORD PTR [rdx+96] + mov r8, QWORD PTR [rsp+96] + sbb r10, r8 + mov QWORD PTR [rcx+88], r11 + mov r11, QWORD PTR [rdx+104] + mov r8, QWORD PTR [rsp+104] + sbb r11, r8 + mov QWORD PTR [rcx+96], r10 + mov r10, QWORD PTR [rdx+112] + mov r8, QWORD PTR [rsp+112] + sbb r10, r8 + mov QWORD PTR [rcx+104], r11 + mov r11, QWORD PTR [rdx+120] + mov r8, QWORD PTR [rsp+120] + sbb r11, r8 + mov QWORD PTR [rcx+112], r10 + mov r10, QWORD PTR [rdx+128] + mov r8, QWORD PTR [rsp+128] + sbb r10, r8 + mov QWORD PTR [rcx+120], r11 + mov r11, QWORD PTR [rdx+136] + mov r8, QWORD PTR [rsp+136] + sbb r11, r8 + mov QWORD PTR [rcx+128], r10 + mov r10, QWORD PTR [rdx+144] + mov r8, QWORD PTR [rsp+144] + sbb r10, r8 + mov QWORD PTR [rcx+136], r11 + mov r11, QWORD PTR [rdx+152] + mov r8, QWORD PTR [rsp+152] + sbb r11, r8 + mov QWORD PTR [rcx+144], r10 + mov r10, QWORD PTR [rdx+160] + mov r8, QWORD PTR [rsp+160] + sbb r10, r8 + mov QWORD PTR [rcx+152], r11 + mov r11, QWORD PTR [rdx+168] + mov r8, QWORD PTR [rsp+168] + sbb r11, r8 + mov QWORD PTR [rcx+160], r10 + mov r10, QWORD PTR [rdx+176] + mov r8, QWORD PTR [rsp+176] + sbb r10, r8 + mov QWORD PTR [rcx+168], r11 + mov r11, QWORD PTR [rdx+184] + mov r8, QWORD PTR [rsp+184] + sbb r11, r8 + mov QWORD PTR [rcx+176], r10 + mov r10, QWORD PTR [rdx+192] + mov r8, QWORD PTR [rsp+192] + sbb r10, r8 + mov QWORD PTR [rcx+184], r11 + mov r11, QWORD PTR [rdx+200] + mov r8, QWORD PTR [rsp+200] + sbb r11, r8 + mov QWORD PTR [rcx+192], r10 + mov r10, QWORD PTR [rdx+208] + mov r8, QWORD PTR [rsp+208] + sbb r10, r8 + mov QWORD PTR [rcx+200], r11 + mov r11, QWORD PTR [rdx+216] + mov r8, QWORD PTR [rsp+216] + sbb r11, r8 + mov QWORD PTR [rcx+208], r10 + mov r10, QWORD PTR [rdx+224] + mov r8, QWORD PTR [rsp+224] + sbb r10, r8 + mov QWORD PTR [rcx+216], r11 + mov r11, QWORD PTR [rdx+232] + mov r8, QWORD PTR [rsp+232] + sbb r11, r8 + mov QWORD PTR [rcx+224], r10 + mov r10, QWORD PTR [rdx+240] + mov r8, QWORD PTR [rsp+240] + sbb r10, r8 + mov QWORD PTR [rcx+232], r11 + mov r11, QWORD PTR [rdx+248] + mov r8, QWORD PTR [rsp+248] + sbb r11, r8 + mov QWORD PTR [rcx+240], r10 + mov QWORD PTR [rcx+248], r11 + sbb rax, 0 + add rsp, 256 + ret +sp_2048_cond_sub_32 ENDP +_text ENDS +; /* Reduce the number back to 2048 bits using Montgomery reduction. +; * +; * a A single precision number to reduce in place. +; * m The single precision number representing the modulus. +; * mp The digit representing the negative inverse of m mod 2^n. +; */ +_text SEGMENT READONLY PARA +sp_2048_mont_reduce_32 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + mov r9, rdx + xor rsi, rsi + ; i = 32 + mov r10, 32 + mov r15, QWORD PTR [rcx] + mov rdi, QWORD PTR [rcx+8] +L_2048_mont_loop_32: + ; mu = a[i] * mp + mov r13, r15 + imul r13, r8 + ; a[i+0] += m[0] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9] + add r15, rax + adc r12, rdx + ; a[i+1] += m[1] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+8] + mov r15, rdi + add r15, rax + adc r11, rdx + add r15, r12 + adc r11, 0 + ; a[i+2] += m[2] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+16] + mov rdi, QWORD PTR [rcx+16] + add rdi, rax + adc r12, rdx + add rdi, r11 + adc r12, 0 + ; a[i+3] += m[3] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+24] + mov r14, QWORD PTR [rcx+24] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+24], r14 + adc r11, 0 + ; a[i+4] += m[4] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+32] + mov r14, QWORD PTR [rcx+32] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+32], r14 + adc r12, 0 + ; a[i+5] += m[5] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+40] + mov r14, QWORD PTR [rcx+40] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+40], r14 + adc r11, 0 + ; a[i+6] += m[6] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+48] + mov r14, QWORD PTR [rcx+48] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+48], r14 + adc r12, 0 + ; a[i+7] += m[7] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+56] + mov r14, QWORD PTR [rcx+56] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+56], r14 + adc r11, 0 + ; a[i+8] += m[8] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+64] + mov r14, QWORD PTR [rcx+64] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+64], r14 + adc r12, 0 + ; a[i+9] += m[9] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+72] + mov r14, QWORD PTR [rcx+72] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+72], r14 + adc r11, 0 + ; a[i+10] += m[10] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+80] + mov r14, QWORD PTR [rcx+80] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+80], r14 + adc r12, 0 + ; a[i+11] += m[11] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+88] + mov r14, QWORD PTR [rcx+88] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+88], r14 + adc r11, 0 + ; a[i+12] += m[12] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+96] + mov r14, QWORD PTR [rcx+96] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+96], r14 + adc r12, 0 + ; a[i+13] += m[13] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+104] + mov r14, QWORD PTR [rcx+104] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+104], r14 + adc r11, 0 + ; a[i+14] += m[14] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+112] + mov r14, QWORD PTR [rcx+112] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+112], r14 + adc r12, 0 + ; a[i+15] += m[15] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+120] + mov r14, QWORD PTR [rcx+120] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+120], r14 + adc r11, 0 + ; a[i+16] += m[16] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+128] + mov r14, QWORD PTR [rcx+128] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+128], r14 + adc r12, 0 + ; a[i+17] += m[17] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+136] + mov r14, QWORD PTR [rcx+136] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+136], r14 + adc r11, 0 + ; a[i+18] += m[18] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+144] + mov r14, QWORD PTR [rcx+144] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+144], r14 + adc r12, 0 + ; a[i+19] += m[19] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+152] + mov r14, QWORD PTR [rcx+152] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+152], r14 + adc r11, 0 + ; a[i+20] += m[20] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+160] + mov r14, QWORD PTR [rcx+160] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+160], r14 + adc r12, 0 + ; a[i+21] += m[21] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+168] + mov r14, QWORD PTR [rcx+168] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+168], r14 + adc r11, 0 + ; a[i+22] += m[22] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+176] + mov r14, QWORD PTR [rcx+176] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+176], r14 + adc r12, 0 + ; a[i+23] += m[23] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+184] + mov r14, QWORD PTR [rcx+184] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+184], r14 + adc r11, 0 + ; a[i+24] += m[24] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+192] + mov r14, QWORD PTR [rcx+192] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+192], r14 + adc r12, 0 + ; a[i+25] += m[25] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+200] + mov r14, QWORD PTR [rcx+200] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+200], r14 + adc r11, 0 + ; a[i+26] += m[26] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+208] + mov r14, QWORD PTR [rcx+208] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+208], r14 + adc r12, 0 + ; a[i+27] += m[27] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+216] + mov r14, QWORD PTR [rcx+216] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+216], r14 + adc r11, 0 + ; a[i+28] += m[28] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+224] + mov r14, QWORD PTR [rcx+224] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+224], r14 + adc r12, 0 + ; a[i+29] += m[29] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+232] + mov r14, QWORD PTR [rcx+232] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+232], r14 + adc r11, 0 + ; a[i+30] += m[30] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+240] + mov r14, QWORD PTR [rcx+240] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+240], r14 + adc r12, 0 + ; a[i+31] += m[31] * mu + mov rax, r13 + mul QWORD PTR [r9+248] + mov r14, QWORD PTR [rcx+248] + add r12, rax + adc rdx, rsi + mov rsi, 0 + adc rsi, 0 + add r14, r12 + mov QWORD PTR [rcx+248], r14 + adc QWORD PTR [rcx+256], rdx + adc rsi, 0 + ; i -= 1 + add rcx, 8 + dec r10 + jnz L_2048_mont_loop_32 + mov QWORD PTR [rcx], r15 + mov QWORD PTR [rcx+8], rdi + neg rsi +IFDEF _WIN64 + mov r8, r9 + mov r9, rsi +ELSE + mov r9, rsi + mov r8, r9 +ENDIF + mov rdx, rcx + mov rcx, rcx + sub rcx, 256 + call sp_2048_cond_sub_32 + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_2048_mont_reduce_32 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Conditionally subtract b from a using the mask m. +; * m is -1 to subtract and 0 when not copying. +; * +; * r A single precision number representing condition subtract result. +; * a A single precision number to subtract from. +; * b A single precision number to subtract. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_2048_cond_sub_avx2_32 PROC + push r12 + mov rax, 0 + mov r12, QWORD PTR [r8] + mov r10, QWORD PTR [rdx] + pext r12, r12, r9 + sub r10, r12 + mov r12, QWORD PTR [r8+8] + mov r11, QWORD PTR [rdx+8] + pext r12, r12, r9 + mov QWORD PTR [rcx], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+16] + mov r12, QWORD PTR [rdx+16] + pext r10, r10, r9 + mov QWORD PTR [rcx+8], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+24] + mov r10, QWORD PTR [rdx+24] + pext r11, r11, r9 + mov QWORD PTR [rcx+16], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+32] + mov r11, QWORD PTR [rdx+32] + pext r12, r12, r9 + mov QWORD PTR [rcx+24], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+40] + mov r12, QWORD PTR [rdx+40] + pext r10, r10, r9 + mov QWORD PTR [rcx+32], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+48] + mov r10, QWORD PTR [rdx+48] + pext r11, r11, r9 + mov QWORD PTR [rcx+40], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+56] + mov r11, QWORD PTR [rdx+56] + pext r12, r12, r9 + mov QWORD PTR [rcx+48], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+64] + mov r12, QWORD PTR [rdx+64] + pext r10, r10, r9 + mov QWORD PTR [rcx+56], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+72] + mov r10, QWORD PTR [rdx+72] + pext r11, r11, r9 + mov QWORD PTR [rcx+64], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+80] + mov r11, QWORD PTR [rdx+80] + pext r12, r12, r9 + mov QWORD PTR [rcx+72], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+88] + mov r12, QWORD PTR [rdx+88] + pext r10, r10, r9 + mov QWORD PTR [rcx+80], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+96] + mov r10, QWORD PTR [rdx+96] + pext r11, r11, r9 + mov QWORD PTR [rcx+88], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+104] + mov r11, QWORD PTR [rdx+104] + pext r12, r12, r9 + mov QWORD PTR [rcx+96], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+112] + mov r12, QWORD PTR [rdx+112] + pext r10, r10, r9 + mov QWORD PTR [rcx+104], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+120] + mov r10, QWORD PTR [rdx+120] + pext r11, r11, r9 + mov QWORD PTR [rcx+112], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+128] + mov r11, QWORD PTR [rdx+128] + pext r12, r12, r9 + mov QWORD PTR [rcx+120], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+136] + mov r12, QWORD PTR [rdx+136] + pext r10, r10, r9 + mov QWORD PTR [rcx+128], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+144] + mov r10, QWORD PTR [rdx+144] + pext r11, r11, r9 + mov QWORD PTR [rcx+136], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+152] + mov r11, QWORD PTR [rdx+152] + pext r12, r12, r9 + mov QWORD PTR [rcx+144], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+160] + mov r12, QWORD PTR [rdx+160] + pext r10, r10, r9 + mov QWORD PTR [rcx+152], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+168] + mov r10, QWORD PTR [rdx+168] + pext r11, r11, r9 + mov QWORD PTR [rcx+160], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+176] + mov r11, QWORD PTR [rdx+176] + pext r12, r12, r9 + mov QWORD PTR [rcx+168], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+184] + mov r12, QWORD PTR [rdx+184] + pext r10, r10, r9 + mov QWORD PTR [rcx+176], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+192] + mov r10, QWORD PTR [rdx+192] + pext r11, r11, r9 + mov QWORD PTR [rcx+184], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+200] + mov r11, QWORD PTR [rdx+200] + pext r12, r12, r9 + mov QWORD PTR [rcx+192], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+208] + mov r12, QWORD PTR [rdx+208] + pext r10, r10, r9 + mov QWORD PTR [rcx+200], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+216] + mov r10, QWORD PTR [rdx+216] + pext r11, r11, r9 + mov QWORD PTR [rcx+208], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+224] + mov r11, QWORD PTR [rdx+224] + pext r12, r12, r9 + mov QWORD PTR [rcx+216], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+232] + mov r12, QWORD PTR [rdx+232] + pext r10, r10, r9 + mov QWORD PTR [rcx+224], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+240] + mov r10, QWORD PTR [rdx+240] + pext r11, r11, r9 + mov QWORD PTR [rcx+232], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+248] + mov r11, QWORD PTR [rdx+248] + pext r12, r12, r9 + mov QWORD PTR [rcx+240], r10 + sbb r11, r12 + mov QWORD PTR [rcx+248], r11 + sbb rax, 0 + pop r12 + ret +sp_2048_cond_sub_avx2_32 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Mul a by digit b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision digit. +; */ +_text SEGMENT READONLY PARA +sp_2048_mul_d_avx2_32 PROC + push r12 + push r13 + mov rax, rdx + ; A[0] * B + mov rdx, r8 + xor r13, r13 + mulx r12, r11, QWORD PTR [rax] + mov QWORD PTR [rcx], r11 + ; A[1] * B + mulx r10, r9, QWORD PTR [rax+8] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+8], r12 + ; A[2] * B + mulx r10, r9, QWORD PTR [rax+16] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+16], r11 + ; A[3] * B + mulx r10, r9, QWORD PTR [rax+24] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+24], r12 + ; A[4] * B + mulx r10, r9, QWORD PTR [rax+32] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+32], r11 + ; A[5] * B + mulx r10, r9, QWORD PTR [rax+40] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+40], r12 + ; A[6] * B + mulx r10, r9, QWORD PTR [rax+48] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+48], r11 + ; A[7] * B + mulx r10, r9, QWORD PTR [rax+56] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+56], r12 + ; A[8] * B + mulx r10, r9, QWORD PTR [rax+64] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+64], r11 + ; A[9] * B + mulx r10, r9, QWORD PTR [rax+72] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+72], r12 + ; A[10] * B + mulx r10, r9, QWORD PTR [rax+80] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+80], r11 + ; A[11] * B + mulx r10, r9, QWORD PTR [rax+88] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+88], r12 + ; A[12] * B + mulx r10, r9, QWORD PTR [rax+96] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+96], r11 + ; A[13] * B + mulx r10, r9, QWORD PTR [rax+104] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+104], r12 + ; A[14] * B + mulx r10, r9, QWORD PTR [rax+112] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+112], r11 + ; A[15] * B + mulx r10, r9, QWORD PTR [rax+120] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+120], r12 + ; A[16] * B + mulx r10, r9, QWORD PTR [rax+128] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+128], r11 + ; A[17] * B + mulx r10, r9, QWORD PTR [rax+136] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+136], r12 + ; A[18] * B + mulx r10, r9, QWORD PTR [rax+144] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+144], r11 + ; A[19] * B + mulx r10, r9, QWORD PTR [rax+152] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+152], r12 + ; A[20] * B + mulx r10, r9, QWORD PTR [rax+160] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+160], r11 + ; A[21] * B + mulx r10, r9, QWORD PTR [rax+168] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+168], r12 + ; A[22] * B + mulx r10, r9, QWORD PTR [rax+176] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+176], r11 + ; A[23] * B + mulx r10, r9, QWORD PTR [rax+184] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+184], r12 + ; A[24] * B + mulx r10, r9, QWORD PTR [rax+192] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+192], r11 + ; A[25] * B + mulx r10, r9, QWORD PTR [rax+200] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+200], r12 + ; A[26] * B + mulx r10, r9, QWORD PTR [rax+208] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+208], r11 + ; A[27] * B + mulx r10, r9, QWORD PTR [rax+216] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+216], r12 + ; A[28] * B + mulx r10, r9, QWORD PTR [rax+224] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+224], r11 + ; A[29] * B + mulx r10, r9, QWORD PTR [rax+232] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+232], r12 + ; A[30] * B + mulx r10, r9, QWORD PTR [rax+240] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+240], r11 + ; A[31] * B + mulx r10, r9, QWORD PTR [rax+248] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + adcx r11, r13 + mov QWORD PTR [rcx+248], r12 + mov QWORD PTR [rcx+256], r11 + pop r13 + pop r12 + ret +sp_2048_mul_d_avx2_32 ENDP +_text ENDS +ENDIF +IFDEF _WIN64 +; /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) +; * +; * d1 The high order half of the number to divide. +; * d0 The low order half of the number to divide. +; * div The dividend. +; * returns the result of the division. +; */ +_text SEGMENT READONLY PARA +div_2048_word_asm_32 PROC + mov r9, rdx + mov rax, r9 + mov rdx, rcx + div r8 + ret +div_2048_word_asm_32 ENDP +_text ENDS +ENDIF +; /* Compare a with b in constant time. +; * +; * a A single precision integer. +; * b A single precision integer. +; * return -ve, 0 or +ve if a is less than, equal to or greater than b +; * respectively. +; */ +_text SEGMENT READONLY PARA +sp_2048_cmp_32 PROC + push r12 + xor r9, r9 + mov r8, -1 + mov rax, -1 + mov r10, 1 + mov r11, QWORD PTR [rcx+248] + mov r12, QWORD PTR [rdx+248] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+240] + mov r12, QWORD PTR [rdx+240] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+232] + mov r12, QWORD PTR [rdx+232] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+224] + mov r12, QWORD PTR [rdx+224] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+216] + mov r12, QWORD PTR [rdx+216] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+208] + mov r12, QWORD PTR [rdx+208] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+200] + mov r12, QWORD PTR [rdx+200] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+192] + mov r12, QWORD PTR [rdx+192] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+184] + mov r12, QWORD PTR [rdx+184] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+176] + mov r12, QWORD PTR [rdx+176] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+168] + mov r12, QWORD PTR [rdx+168] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+160] + mov r12, QWORD PTR [rdx+160] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+152] + mov r12, QWORD PTR [rdx+152] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+144] + mov r12, QWORD PTR [rdx+144] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+136] + mov r12, QWORD PTR [rdx+136] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+128] + mov r12, QWORD PTR [rdx+128] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+120] + mov r12, QWORD PTR [rdx+120] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+112] + mov r12, QWORD PTR [rdx+112] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+104] + mov r12, QWORD PTR [rdx+104] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+96] + mov r12, QWORD PTR [rdx+96] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+88] + mov r12, QWORD PTR [rdx+88] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+80] + mov r12, QWORD PTR [rdx+80] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+72] + mov r12, QWORD PTR [rdx+72] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+64] + mov r12, QWORD PTR [rdx+64] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+56] + mov r12, QWORD PTR [rdx+56] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+48] + mov r12, QWORD PTR [rdx+48] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+40] + mov r12, QWORD PTR [rdx+40] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+32] + mov r12, QWORD PTR [rdx+32] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+24] + mov r12, QWORD PTR [rdx+24] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+16] + mov r12, QWORD PTR [rdx+16] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+8] + mov r12, QWORD PTR [rdx+8] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx] + mov r12, QWORD PTR [rdx] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + xor rax, r8 + pop r12 + ret +sp_2048_cmp_32 ENDP +_text ENDS +; /* Sub b from a into r. (r = a - b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_2048_sub_32 PROC + mov r9, QWORD PTR [rdx] + xor rax, rax + sub r9, QWORD PTR [r8] + mov r10, QWORD PTR [rdx+8] + mov QWORD PTR [rcx], r9 + sbb r10, QWORD PTR [r8+8] + mov r9, QWORD PTR [rdx+16] + mov QWORD PTR [rcx+8], r10 + sbb r9, QWORD PTR [r8+16] + mov r10, QWORD PTR [rdx+24] + mov QWORD PTR [rcx+16], r9 + sbb r10, QWORD PTR [r8+24] + mov r9, QWORD PTR [rdx+32] + mov QWORD PTR [rcx+24], r10 + sbb r9, QWORD PTR [r8+32] + mov r10, QWORD PTR [rdx+40] + mov QWORD PTR [rcx+32], r9 + sbb r10, QWORD PTR [r8+40] + mov r9, QWORD PTR [rdx+48] + mov QWORD PTR [rcx+40], r10 + sbb r9, QWORD PTR [r8+48] + mov r10, QWORD PTR [rdx+56] + mov QWORD PTR [rcx+48], r9 + sbb r10, QWORD PTR [r8+56] + mov r9, QWORD PTR [rdx+64] + mov QWORD PTR [rcx+56], r10 + sbb r9, QWORD PTR [r8+64] + mov r10, QWORD PTR [rdx+72] + mov QWORD PTR [rcx+64], r9 + sbb r10, QWORD PTR [r8+72] + mov r9, QWORD PTR [rdx+80] + mov QWORD PTR [rcx+72], r10 + sbb r9, QWORD PTR [r8+80] + mov r10, QWORD PTR [rdx+88] + mov QWORD PTR [rcx+80], r9 + sbb r10, QWORD PTR [r8+88] + mov r9, QWORD PTR [rdx+96] + mov QWORD PTR [rcx+88], r10 + sbb r9, QWORD PTR [r8+96] + mov r10, QWORD PTR [rdx+104] + mov QWORD PTR [rcx+96], r9 + sbb r10, QWORD PTR [r8+104] + mov r9, QWORD PTR [rdx+112] + mov QWORD PTR [rcx+104], r10 + sbb r9, QWORD PTR [r8+112] + mov r10, QWORD PTR [rdx+120] + mov QWORD PTR [rcx+112], r9 + sbb r10, QWORD PTR [r8+120] + mov r9, QWORD PTR [rdx+128] + mov QWORD PTR [rcx+120], r10 + sbb r9, QWORD PTR [r8+128] + mov r10, QWORD PTR [rdx+136] + mov QWORD PTR [rcx+128], r9 + sbb r10, QWORD PTR [r8+136] + mov r9, QWORD PTR [rdx+144] + mov QWORD PTR [rcx+136], r10 + sbb r9, QWORD PTR [r8+144] + mov r10, QWORD PTR [rdx+152] + mov QWORD PTR [rcx+144], r9 + sbb r10, QWORD PTR [r8+152] + mov r9, QWORD PTR [rdx+160] + mov QWORD PTR [rcx+152], r10 + sbb r9, QWORD PTR [r8+160] + mov r10, QWORD PTR [rdx+168] + mov QWORD PTR [rcx+160], r9 + sbb r10, QWORD PTR [r8+168] + mov r9, QWORD PTR [rdx+176] + mov QWORD PTR [rcx+168], r10 + sbb r9, QWORD PTR [r8+176] + mov r10, QWORD PTR [rdx+184] + mov QWORD PTR [rcx+176], r9 + sbb r10, QWORD PTR [r8+184] + mov r9, QWORD PTR [rdx+192] + mov QWORD PTR [rcx+184], r10 + sbb r9, QWORD PTR [r8+192] + mov r10, QWORD PTR [rdx+200] + mov QWORD PTR [rcx+192], r9 + sbb r10, QWORD PTR [r8+200] + mov r9, QWORD PTR [rdx+208] + mov QWORD PTR [rcx+200], r10 + sbb r9, QWORD PTR [r8+208] + mov r10, QWORD PTR [rdx+216] + mov QWORD PTR [rcx+208], r9 + sbb r10, QWORD PTR [r8+216] + mov r9, QWORD PTR [rdx+224] + mov QWORD PTR [rcx+216], r10 + sbb r9, QWORD PTR [r8+224] + mov r10, QWORD PTR [rdx+232] + mov QWORD PTR [rcx+224], r9 + sbb r10, QWORD PTR [r8+232] + mov r9, QWORD PTR [rdx+240] + mov QWORD PTR [rcx+232], r10 + sbb r9, QWORD PTR [r8+240] + mov r10, QWORD PTR [rdx+248] + mov QWORD PTR [rcx+240], r9 + sbb r10, QWORD PTR [r8+248] + mov QWORD PTR [rcx+248], r10 + sbb rax, 0 + ret +sp_2048_sub_32 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Reduce the number back to 2048 bits using Montgomery reduction. +; * +; * a A single precision number to reduce in place. +; * m The single precision number representing the modulus. +; * mp The digit representing the negative inverse of m mod 2^n. +; */ +_text SEGMENT READONLY PARA +sp_2048_mont_reduce_avx2_32 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + push rbx + push rbp + mov r9, rcx + mov r10, rdx + xor rbp, rbp + ; i = 32 + mov r11, 32 + mov r15, QWORD PTR [r9] + mov rdi, QWORD PTR [r9+8] + mov rsi, QWORD PTR [r9+16] + mov rbx, QWORD PTR [r9+24] + add r9, 128 + xor rbp, rbp +L_2048_mont_loop_avx2_32: + ; mu = a[i] * mp + mov rdx, r15 + mov r12, r15 + imul rdx, r8 + xor r14, r14 + ; a[i+0] += m[0] * mu + mulx rcx, rax, QWORD PTR [r10] + mov r15, rdi + adcx r12, rax + adox r15, rcx + ; a[i+1] += m[1] * mu + mulx rcx, rax, QWORD PTR [r10+8] + mov rdi, rsi + adcx r15, rax + adox rdi, rcx + ; a[i+2] += m[2] * mu + mulx rcx, rax, QWORD PTR [r10+16] + mov rsi, rbx + adcx rdi, rax + adox rsi, rcx + ; a[i+3] += m[3] * mu + mulx rcx, rax, QWORD PTR [r10+24] + mov rbx, QWORD PTR [r9+-96] + adcx rsi, rax + adox rbx, rcx + ; a[i+4] += m[4] * mu + mulx rcx, rax, QWORD PTR [r10+32] + mov r13, QWORD PTR [r9+-88] + adcx rbx, rax + adox r13, rcx + ; a[i+5] += m[5] * mu + mulx rcx, rax, QWORD PTR [r10+40] + mov r12, QWORD PTR [r9+-80] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-88], r13 + ; a[i+6] += m[6] * mu + mulx rcx, rax, QWORD PTR [r10+48] + mov r13, QWORD PTR [r9+-72] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-80], r12 + ; a[i+7] += m[7] * mu + mulx rcx, rax, QWORD PTR [r10+56] + mov r12, QWORD PTR [r9+-64] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-72], r13 + ; a[i+8] += m[8] * mu + mulx rcx, rax, QWORD PTR [r10+64] + mov r13, QWORD PTR [r9+-56] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-64], r12 + ; a[i+9] += m[9] * mu + mulx rcx, rax, QWORD PTR [r10+72] + mov r12, QWORD PTR [r9+-48] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-56], r13 + ; a[i+10] += m[10] * mu + mulx rcx, rax, QWORD PTR [r10+80] + mov r13, QWORD PTR [r9+-40] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-48], r12 + ; a[i+11] += m[11] * mu + mulx rcx, rax, QWORD PTR [r10+88] + mov r12, QWORD PTR [r9+-32] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-40], r13 + ; a[i+12] += m[12] * mu + mulx rcx, rax, QWORD PTR [r10+96] + mov r13, QWORD PTR [r9+-24] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-32], r12 + ; a[i+13] += m[13] * mu + mulx rcx, rax, QWORD PTR [r10+104] + mov r12, QWORD PTR [r9+-16] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-24], r13 + ; a[i+14] += m[14] * mu + mulx rcx, rax, QWORD PTR [r10+112] + mov r13, QWORD PTR [r9+-8] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-16], r12 + ; a[i+15] += m[15] * mu + mulx rcx, rax, QWORD PTR [r10+120] + mov r12, QWORD PTR [r9] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-8], r13 + ; a[i+16] += m[16] * mu + mulx rcx, rax, QWORD PTR [r10+128] + mov r13, QWORD PTR [r9+8] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9], r12 + ; a[i+17] += m[17] * mu + mulx rcx, rax, QWORD PTR [r10+136] + mov r12, QWORD PTR [r9+16] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+8], r13 + ; a[i+18] += m[18] * mu + mulx rcx, rax, QWORD PTR [r10+144] + mov r13, QWORD PTR [r9+24] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+16], r12 + ; a[i+19] += m[19] * mu + mulx rcx, rax, QWORD PTR [r10+152] + mov r12, QWORD PTR [r9+32] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+24], r13 + ; a[i+20] += m[20] * mu + mulx rcx, rax, QWORD PTR [r10+160] + mov r13, QWORD PTR [r9+40] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+32], r12 + ; a[i+21] += m[21] * mu + mulx rcx, rax, QWORD PTR [r10+168] + mov r12, QWORD PTR [r9+48] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+40], r13 + ; a[i+22] += m[22] * mu + mulx rcx, rax, QWORD PTR [r10+176] + mov r13, QWORD PTR [r9+56] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+48], r12 + ; a[i+23] += m[23] * mu + mulx rcx, rax, QWORD PTR [r10+184] + mov r12, QWORD PTR [r9+64] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+56], r13 + ; a[i+24] += m[24] * mu + mulx rcx, rax, QWORD PTR [r10+192] + mov r13, QWORD PTR [r9+72] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+64], r12 + ; a[i+25] += m[25] * mu + mulx rcx, rax, QWORD PTR [r10+200] + mov r12, QWORD PTR [r9+80] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+72], r13 + ; a[i+26] += m[26] * mu + mulx rcx, rax, QWORD PTR [r10+208] + mov r13, QWORD PTR [r9+88] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+80], r12 + ; a[i+27] += m[27] * mu + mulx rcx, rax, QWORD PTR [r10+216] + mov r12, QWORD PTR [r9+96] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+88], r13 + ; a[i+28] += m[28] * mu + mulx rcx, rax, QWORD PTR [r10+224] + mov r13, QWORD PTR [r9+104] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+96], r12 + ; a[i+29] += m[29] * mu + mulx rcx, rax, QWORD PTR [r10+232] + mov r12, QWORD PTR [r9+112] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+104], r13 + ; a[i+30] += m[30] * mu + mulx rcx, rax, QWORD PTR [r10+240] + mov r13, QWORD PTR [r9+120] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+112], r12 + ; a[i+31] += m[31] * mu + mulx rcx, rax, QWORD PTR [r10+248] + mov r12, QWORD PTR [r9+128] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+120], r13 + adcx r12, rbp + mov rbp, r14 + mov QWORD PTR [r9+128], r12 + adox rbp, r14 + adcx rbp, r14 + ; a += 1 + add r9, 8 + ; i -= 1 + sub r11, 1 + jnz L_2048_mont_loop_avx2_32 + sub r9, 128 + neg rbp + mov r8, r9 + sub r9, 256 + mov rcx, QWORD PTR [r10] + mov rdx, r15 + pext rcx, rcx, rbp + sub rdx, rcx + mov rcx, QWORD PTR [r10+8] + mov rax, rdi + pext rcx, rcx, rbp + mov QWORD PTR [r9], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+16] + mov rcx, rsi + pext rdx, rdx, rbp + mov QWORD PTR [r9+8], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+24] + mov rdx, rbx + pext rax, rax, rbp + mov QWORD PTR [r9+16], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+32] + mov rax, QWORD PTR [r8+32] + pext rcx, rcx, rbp + mov QWORD PTR [r9+24], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+40] + mov rcx, QWORD PTR [r8+40] + pext rdx, rdx, rbp + mov QWORD PTR [r9+32], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+48] + mov rdx, QWORD PTR [r8+48] + pext rax, rax, rbp + mov QWORD PTR [r9+40], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+56] + mov rax, QWORD PTR [r8+56] + pext rcx, rcx, rbp + mov QWORD PTR [r9+48], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+64] + mov rcx, QWORD PTR [r8+64] + pext rdx, rdx, rbp + mov QWORD PTR [r9+56], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+72] + mov rdx, QWORD PTR [r8+72] + pext rax, rax, rbp + mov QWORD PTR [r9+64], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+80] + mov rax, QWORD PTR [r8+80] + pext rcx, rcx, rbp + mov QWORD PTR [r9+72], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+88] + mov rcx, QWORD PTR [r8+88] + pext rdx, rdx, rbp + mov QWORD PTR [r9+80], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+96] + mov rdx, QWORD PTR [r8+96] + pext rax, rax, rbp + mov QWORD PTR [r9+88], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+104] + mov rax, QWORD PTR [r8+104] + pext rcx, rcx, rbp + mov QWORD PTR [r9+96], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+112] + mov rcx, QWORD PTR [r8+112] + pext rdx, rdx, rbp + mov QWORD PTR [r9+104], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+120] + mov rdx, QWORD PTR [r8+120] + pext rax, rax, rbp + mov QWORD PTR [r9+112], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+128] + mov rax, QWORD PTR [r8+128] + pext rcx, rcx, rbp + mov QWORD PTR [r9+120], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+136] + mov rcx, QWORD PTR [r8+136] + pext rdx, rdx, rbp + mov QWORD PTR [r9+128], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+144] + mov rdx, QWORD PTR [r8+144] + pext rax, rax, rbp + mov QWORD PTR [r9+136], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+152] + mov rax, QWORD PTR [r8+152] + pext rcx, rcx, rbp + mov QWORD PTR [r9+144], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+160] + mov rcx, QWORD PTR [r8+160] + pext rdx, rdx, rbp + mov QWORD PTR [r9+152], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+168] + mov rdx, QWORD PTR [r8+168] + pext rax, rax, rbp + mov QWORD PTR [r9+160], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+176] + mov rax, QWORD PTR [r8+176] + pext rcx, rcx, rbp + mov QWORD PTR [r9+168], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+184] + mov rcx, QWORD PTR [r8+184] + pext rdx, rdx, rbp + mov QWORD PTR [r9+176], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+192] + mov rdx, QWORD PTR [r8+192] + pext rax, rax, rbp + mov QWORD PTR [r9+184], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+200] + mov rax, QWORD PTR [r8+200] + pext rcx, rcx, rbp + mov QWORD PTR [r9+192], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+208] + mov rcx, QWORD PTR [r8+208] + pext rdx, rdx, rbp + mov QWORD PTR [r9+200], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+216] + mov rdx, QWORD PTR [r8+216] + pext rax, rax, rbp + mov QWORD PTR [r9+208], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+224] + mov rax, QWORD PTR [r8+224] + pext rcx, rcx, rbp + mov QWORD PTR [r9+216], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+232] + mov rcx, QWORD PTR [r8+232] + pext rdx, rdx, rbp + mov QWORD PTR [r9+224], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+240] + mov rdx, QWORD PTR [r8+240] + pext rax, rax, rbp + mov QWORD PTR [r9+232], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+248] + mov rax, QWORD PTR [r8+248] + pext rcx, rcx, rbp + mov QWORD PTR [r9+240], rdx + sbb rax, rcx + mov QWORD PTR [r9+248], rax + pop rbp + pop rbx + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_2048_mont_reduce_avx2_32 ENDP +_text ENDS +ENDIF +; /* Conditionally add a and b using the mask m. +; * m is -1 to add and 0 when not. +; * +; * r A single precision number representing conditional add result. +; * a A single precision number to add with. +; * b A single precision number to add. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_2048_cond_add_16 PROC + sub rsp, 128 + mov rax, 0 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp], r10 + mov QWORD PTR [rsp+8], r11 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+16], r10 + mov QWORD PTR [rsp+24], r11 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+32], r10 + mov QWORD PTR [rsp+40], r11 + mov r10, QWORD PTR [r8+48] + mov r11, QWORD PTR [r8+56] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+48], r10 + mov QWORD PTR [rsp+56], r11 + mov r10, QWORD PTR [r8+64] + mov r11, QWORD PTR [r8+72] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+64], r10 + mov QWORD PTR [rsp+72], r11 + mov r10, QWORD PTR [r8+80] + mov r11, QWORD PTR [r8+88] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+80], r10 + mov QWORD PTR [rsp+88], r11 + mov r10, QWORD PTR [r8+96] + mov r11, QWORD PTR [r8+104] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+96], r10 + mov QWORD PTR [rsp+104], r11 + mov r10, QWORD PTR [r8+112] + mov r11, QWORD PTR [r8+120] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+112], r10 + mov QWORD PTR [rsp+120], r11 + mov r10, QWORD PTR [rdx] + mov r8, QWORD PTR [rsp] + add r10, r8 + mov r11, QWORD PTR [rdx+8] + mov r8, QWORD PTR [rsp+8] + adc r11, r8 + mov QWORD PTR [rcx], r10 + mov r10, QWORD PTR [rdx+16] + mov r8, QWORD PTR [rsp+16] + adc r10, r8 + mov QWORD PTR [rcx+8], r11 + mov r11, QWORD PTR [rdx+24] + mov r8, QWORD PTR [rsp+24] + adc r11, r8 + mov QWORD PTR [rcx+16], r10 + mov r10, QWORD PTR [rdx+32] + mov r8, QWORD PTR [rsp+32] + adc r10, r8 + mov QWORD PTR [rcx+24], r11 + mov r11, QWORD PTR [rdx+40] + mov r8, QWORD PTR [rsp+40] + adc r11, r8 + mov QWORD PTR [rcx+32], r10 + mov r10, QWORD PTR [rdx+48] + mov r8, QWORD PTR [rsp+48] + adc r10, r8 + mov QWORD PTR [rcx+40], r11 + mov r11, QWORD PTR [rdx+56] + mov r8, QWORD PTR [rsp+56] + adc r11, r8 + mov QWORD PTR [rcx+48], r10 + mov r10, QWORD PTR [rdx+64] + mov r8, QWORD PTR [rsp+64] + adc r10, r8 + mov QWORD PTR [rcx+56], r11 + mov r11, QWORD PTR [rdx+72] + mov r8, QWORD PTR [rsp+72] + adc r11, r8 + mov QWORD PTR [rcx+64], r10 + mov r10, QWORD PTR [rdx+80] + mov r8, QWORD PTR [rsp+80] + adc r10, r8 + mov QWORD PTR [rcx+72], r11 + mov r11, QWORD PTR [rdx+88] + mov r8, QWORD PTR [rsp+88] + adc r11, r8 + mov QWORD PTR [rcx+80], r10 + mov r10, QWORD PTR [rdx+96] + mov r8, QWORD PTR [rsp+96] + adc r10, r8 + mov QWORD PTR [rcx+88], r11 + mov r11, QWORD PTR [rdx+104] + mov r8, QWORD PTR [rsp+104] + adc r11, r8 + mov QWORD PTR [rcx+96], r10 + mov r10, QWORD PTR [rdx+112] + mov r8, QWORD PTR [rsp+112] + adc r10, r8 + mov QWORD PTR [rcx+104], r11 + mov r11, QWORD PTR [rdx+120] + mov r8, QWORD PTR [rsp+120] + adc r11, r8 + mov QWORD PTR [rcx+112], r10 + mov QWORD PTR [rcx+120], r11 + adc rax, 0 + add rsp, 128 + ret +sp_2048_cond_add_16 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Conditionally add a and b using the mask m. +; * m is -1 to add and 0 when not. +; * +; * r A single precision number representing conditional add result. +; * a A single precision number to add with. +; * b A single precision number to add. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_2048_cond_add_avx2_16 PROC + push r12 + mov rax, 0 + mov r12, QWORD PTR [r8] + mov r10, QWORD PTR [rdx] + pext r12, r12, r9 + add r10, r12 + mov r12, QWORD PTR [r8+8] + mov r11, QWORD PTR [rdx+8] + pext r12, r12, r9 + mov QWORD PTR [rcx], r10 + adc r11, r12 + mov r10, QWORD PTR [r8+16] + mov r12, QWORD PTR [rdx+16] + pext r10, r10, r9 + mov QWORD PTR [rcx+8], r11 + adc r12, r10 + mov r11, QWORD PTR [r8+24] + mov r10, QWORD PTR [rdx+24] + pext r11, r11, r9 + mov QWORD PTR [rcx+16], r12 + adc r10, r11 + mov r12, QWORD PTR [r8+32] + mov r11, QWORD PTR [rdx+32] + pext r12, r12, r9 + mov QWORD PTR [rcx+24], r10 + adc r11, r12 + mov r10, QWORD PTR [r8+40] + mov r12, QWORD PTR [rdx+40] + pext r10, r10, r9 + mov QWORD PTR [rcx+32], r11 + adc r12, r10 + mov r11, QWORD PTR [r8+48] + mov r10, QWORD PTR [rdx+48] + pext r11, r11, r9 + mov QWORD PTR [rcx+40], r12 + adc r10, r11 + mov r12, QWORD PTR [r8+56] + mov r11, QWORD PTR [rdx+56] + pext r12, r12, r9 + mov QWORD PTR [rcx+48], r10 + adc r11, r12 + mov r10, QWORD PTR [r8+64] + mov r12, QWORD PTR [rdx+64] + pext r10, r10, r9 + mov QWORD PTR [rcx+56], r11 + adc r12, r10 + mov r11, QWORD PTR [r8+72] + mov r10, QWORD PTR [rdx+72] + pext r11, r11, r9 + mov QWORD PTR [rcx+64], r12 + adc r10, r11 + mov r12, QWORD PTR [r8+80] + mov r11, QWORD PTR [rdx+80] + pext r12, r12, r9 + mov QWORD PTR [rcx+72], r10 + adc r11, r12 + mov r10, QWORD PTR [r8+88] + mov r12, QWORD PTR [rdx+88] + pext r10, r10, r9 + mov QWORD PTR [rcx+80], r11 + adc r12, r10 + mov r11, QWORD PTR [r8+96] + mov r10, QWORD PTR [rdx+96] + pext r11, r11, r9 + mov QWORD PTR [rcx+88], r12 + adc r10, r11 + mov r12, QWORD PTR [r8+104] + mov r11, QWORD PTR [rdx+104] + pext r12, r12, r9 + mov QWORD PTR [rcx+96], r10 + adc r11, r12 + mov r10, QWORD PTR [r8+112] + mov r12, QWORD PTR [rdx+112] + pext r10, r10, r9 + mov QWORD PTR [rcx+104], r11 + adc r12, r10 + mov r11, QWORD PTR [r8+120] + mov r10, QWORD PTR [rdx+120] + pext r11, r11, r9 + mov QWORD PTR [rcx+112], r12 + adc r10, r11 + mov QWORD PTR [rcx+120], r10 + adc rax, 0 + pop r12 + ret +sp_2048_cond_add_avx2_16 ENDP +_text ENDS +ENDIF +; /* Shift number left by n bit. (r = a << n) +; * +; * r Result of left shift by n. +; * a Number to shift. +; * n Amoutnt o shift. +; */ +_text SEGMENT READONLY PARA +sp_2048_lshift_32 PROC + push r12 + push r13 + mov r9, rcx + mov rcx, r8 + mov r12, 0 + mov r13, QWORD PTR [rdx+216] + mov rax, QWORD PTR [rdx+224] + mov r8, QWORD PTR [rdx+232] + mov r10, QWORD PTR [rdx+240] + mov r11, QWORD PTR [rdx+248] + shld r12, r11, cl + shld r11, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r13, cl + mov QWORD PTR [r9+224], rax + mov QWORD PTR [r9+232], r8 + mov QWORD PTR [r9+240], r10 + mov QWORD PTR [r9+248], r11 + mov QWORD PTR [r9+256], r12 + mov r11, QWORD PTR [rdx+184] + mov rax, QWORD PTR [rdx+192] + mov r8, QWORD PTR [rdx+200] + mov r10, QWORD PTR [rdx+208] + shld r13, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r11, cl + mov QWORD PTR [r9+192], rax + mov QWORD PTR [r9+200], r8 + mov QWORD PTR [r9+208], r10 + mov QWORD PTR [r9+216], r13 + mov r13, QWORD PTR [rdx+152] + mov rax, QWORD PTR [rdx+160] + mov r8, QWORD PTR [rdx+168] + mov r10, QWORD PTR [rdx+176] + shld r11, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r13, cl + mov QWORD PTR [r9+160], rax + mov QWORD PTR [r9+168], r8 + mov QWORD PTR [r9+176], r10 + mov QWORD PTR [r9+184], r11 + mov r11, QWORD PTR [rdx+120] + mov rax, QWORD PTR [rdx+128] + mov r8, QWORD PTR [rdx+136] + mov r10, QWORD PTR [rdx+144] + shld r13, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r11, cl + mov QWORD PTR [r9+128], rax + mov QWORD PTR [r9+136], r8 + mov QWORD PTR [r9+144], r10 + mov QWORD PTR [r9+152], r13 + mov r13, QWORD PTR [rdx+88] + mov rax, QWORD PTR [rdx+96] + mov r8, QWORD PTR [rdx+104] + mov r10, QWORD PTR [rdx+112] + shld r11, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r13, cl + mov QWORD PTR [r9+96], rax + mov QWORD PTR [r9+104], r8 + mov QWORD PTR [r9+112], r10 + mov QWORD PTR [r9+120], r11 + mov r11, QWORD PTR [rdx+56] + mov rax, QWORD PTR [rdx+64] + mov r8, QWORD PTR [rdx+72] + mov r10, QWORD PTR [rdx+80] + shld r13, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r11, cl + mov QWORD PTR [r9+64], rax + mov QWORD PTR [r9+72], r8 + mov QWORD PTR [r9+80], r10 + mov QWORD PTR [r9+88], r13 + mov r13, QWORD PTR [rdx+24] + mov rax, QWORD PTR [rdx+32] + mov r8, QWORD PTR [rdx+40] + mov r10, QWORD PTR [rdx+48] + shld r11, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r13, cl + mov QWORD PTR [r9+32], rax + mov QWORD PTR [r9+40], r8 + mov QWORD PTR [r9+48], r10 + mov QWORD PTR [r9+56], r11 + mov rax, QWORD PTR [rdx] + mov r8, QWORD PTR [rdx+8] + mov r10, QWORD PTR [rdx+16] + shld r13, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shl rax, cl + mov QWORD PTR [r9], rax + mov QWORD PTR [r9+8], r8 + mov QWORD PTR [r9+16], r10 + mov QWORD PTR [r9+24], r13 + pop r13 + pop r12 + ret +sp_2048_lshift_32 ENDP +_text ENDS +ENDIF +ENDIF +IFNDEF WOLFSSL_SP_NO_3072 +IFNDEF WOLFSSL_SP_NO_3072 +; /* Read big endian unsigned byte array into r. +; * Uses the bswap instruction. +; * +; * r A single precision integer. +; * size Maximum number of bytes to convert +; * a Byte array. +; * n Number of bytes in array to read. +; */ +_text SEGMENT READONLY PARA +sp_3072_from_bin_bswap PROC + push r12 + push r13 + mov r11, r8 + mov r12, rcx + add r11, r9 + add r12, 384 + xor r13, r13 + jmp L_3072_from_bin_bswap_64_end +L_3072_from_bin_bswap_64_start: + sub r11, 64 + mov rax, QWORD PTR [r11+56] + mov r10, QWORD PTR [r11+48] + bswap rax + bswap r10 + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r10 + mov rax, QWORD PTR [r11+40] + mov r10, QWORD PTR [r11+32] + bswap rax + bswap r10 + mov QWORD PTR [rcx+16], rax + mov QWORD PTR [rcx+24], r10 + mov rax, QWORD PTR [r11+24] + mov r10, QWORD PTR [r11+16] + bswap rax + bswap r10 + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r10 + mov rax, QWORD PTR [r11+8] + mov r10, QWORD PTR [r11] + bswap rax + bswap r10 + mov QWORD PTR [rcx+48], rax + mov QWORD PTR [rcx+56], r10 + add rcx, 64 + sub r9, 64 +L_3072_from_bin_bswap_64_end: + cmp r9, 63 + jg L_3072_from_bin_bswap_64_start + jmp L_3072_from_bin_bswap_8_end +L_3072_from_bin_bswap_8_start: + sub r11, 8 + mov rax, QWORD PTR [r11] + bswap rax + mov QWORD PTR [rcx], rax + add rcx, 8 + sub r9, 8 +L_3072_from_bin_bswap_8_end: + cmp r9, 7 + jg L_3072_from_bin_bswap_8_start + cmp r9, r13 + je L_3072_from_bin_bswap_hi_end + mov r10, r13 + mov rax, r13 +L_3072_from_bin_bswap_hi_start: + mov al, BYTE PTR [r8] + shl r10, 8 + inc r8 + add r10, rax + dec r9 + jg L_3072_from_bin_bswap_hi_start + mov QWORD PTR [rcx], r10 + add rcx, 8 +L_3072_from_bin_bswap_hi_end: + cmp rcx, r12 + je L_3072_from_bin_bswap_zero_end +L_3072_from_bin_bswap_zero_start: + mov QWORD PTR [rcx], r13 + add rcx, 8 + cmp rcx, r12 + jl L_3072_from_bin_bswap_zero_start +L_3072_from_bin_bswap_zero_end: + pop r13 + pop r12 + ret +sp_3072_from_bin_bswap ENDP +_text ENDS +IFNDEF NO_MOVBE_SUPPORT +; /* Read big endian unsigned byte array into r. +; * Uses the movbe instruction which is an optional instruction. +; * +; * r A single precision integer. +; * size Maximum number of bytes to convert +; * a Byte array. +; * n Number of bytes in array to read. +; */ +_text SEGMENT READONLY PARA +sp_3072_from_bin_movbe PROC + push r12 + push r13 + mov r11, r8 + mov r12, rcx + add r11, r9 + add r12, 384 + xor r13, r13 + jmp L_3072_from_bin_movbe_64_end +L_3072_from_bin_movbe_64_start: + sub r11, 64 + movbe rax, QWORD PTR [r11+56] + movbe r10, QWORD PTR [r11+48] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r10 + movbe rax, QWORD PTR [r11+40] + movbe r10, QWORD PTR [r11+32] + mov QWORD PTR [rcx+16], rax + mov QWORD PTR [rcx+24], r10 + movbe rax, QWORD PTR [r11+24] + movbe r10, QWORD PTR [r11+16] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r10 + movbe rax, QWORD PTR [r11+8] + movbe r10, QWORD PTR [r11] + mov QWORD PTR [rcx+48], rax + mov QWORD PTR [rcx+56], r10 + add rcx, 64 + sub r9, 64 +L_3072_from_bin_movbe_64_end: + cmp r9, 63 + jg L_3072_from_bin_movbe_64_start + jmp L_3072_from_bin_movbe_8_end +L_3072_from_bin_movbe_8_start: + sub r11, 8 + movbe rax, QWORD PTR [r11] + mov QWORD PTR [rcx], rax + add rcx, 8 + sub r9, 8 +L_3072_from_bin_movbe_8_end: + cmp r9, 7 + jg L_3072_from_bin_movbe_8_start + cmp r9, r13 + je L_3072_from_bin_movbe_hi_end + mov r10, r13 + mov rax, r13 +L_3072_from_bin_movbe_hi_start: + mov al, BYTE PTR [r8] + shl r10, 8 + inc r8 + add r10, rax + dec r9 + jg L_3072_from_bin_movbe_hi_start + mov QWORD PTR [rcx], r10 + add rcx, 8 +L_3072_from_bin_movbe_hi_end: + cmp rcx, r12 + je L_3072_from_bin_movbe_zero_end +L_3072_from_bin_movbe_zero_start: + mov QWORD PTR [rcx], r13 + add rcx, 8 + cmp rcx, r12 + jl L_3072_from_bin_movbe_zero_start +L_3072_from_bin_movbe_zero_end: + pop r13 + pop r12 + ret +sp_3072_from_bin_movbe ENDP +_text ENDS +ENDIF +; /* Write r as big endian to byte array. +; * Fixed length number of bytes written: 384 +; * Uses the bswap instruction. +; * +; * r A single precision integer. +; * a Byte array. +; */ +_text SEGMENT READONLY PARA +sp_3072_to_bin_bswap PROC + mov rax, QWORD PTR [rcx+376] + mov r8, QWORD PTR [rcx+368] + bswap rax + bswap r8 + mov QWORD PTR [rdx], rax + mov QWORD PTR [rdx+8], r8 + mov rax, QWORD PTR [rcx+360] + mov r8, QWORD PTR [rcx+352] + bswap rax + bswap r8 + mov QWORD PTR [rdx+16], rax + mov QWORD PTR [rdx+24], r8 + mov rax, QWORD PTR [rcx+344] + mov r8, QWORD PTR [rcx+336] + bswap rax + bswap r8 + mov QWORD PTR [rdx+32], rax + mov QWORD PTR [rdx+40], r8 + mov rax, QWORD PTR [rcx+328] + mov r8, QWORD PTR [rcx+320] + bswap rax + bswap r8 + mov QWORD PTR [rdx+48], rax + mov QWORD PTR [rdx+56], r8 + mov rax, QWORD PTR [rcx+312] + mov r8, QWORD PTR [rcx+304] + bswap rax + bswap r8 + mov QWORD PTR [rdx+64], rax + mov QWORD PTR [rdx+72], r8 + mov rax, QWORD PTR [rcx+296] + mov r8, QWORD PTR [rcx+288] + bswap rax + bswap r8 + mov QWORD PTR [rdx+80], rax + mov QWORD PTR [rdx+88], r8 + mov rax, QWORD PTR [rcx+280] + mov r8, QWORD PTR [rcx+272] + bswap rax + bswap r8 + mov QWORD PTR [rdx+96], rax + mov QWORD PTR [rdx+104], r8 + mov rax, QWORD PTR [rcx+264] + mov r8, QWORD PTR [rcx+256] + bswap rax + bswap r8 + mov QWORD PTR [rdx+112], rax + mov QWORD PTR [rdx+120], r8 + mov rax, QWORD PTR [rcx+248] + mov r8, QWORD PTR [rcx+240] + bswap rax + bswap r8 + mov QWORD PTR [rdx+128], rax + mov QWORD PTR [rdx+136], r8 + mov rax, QWORD PTR [rcx+232] + mov r8, QWORD PTR [rcx+224] + bswap rax + bswap r8 + mov QWORD PTR [rdx+144], rax + mov QWORD PTR [rdx+152], r8 + mov rax, QWORD PTR [rcx+216] + mov r8, QWORD PTR [rcx+208] + bswap rax + bswap r8 + mov QWORD PTR [rdx+160], rax + mov QWORD PTR [rdx+168], r8 + mov rax, QWORD PTR [rcx+200] + mov r8, QWORD PTR [rcx+192] + bswap rax + bswap r8 + mov QWORD PTR [rdx+176], rax + mov QWORD PTR [rdx+184], r8 + mov rax, QWORD PTR [rcx+184] + mov r8, QWORD PTR [rcx+176] + bswap rax + bswap r8 + mov QWORD PTR [rdx+192], rax + mov QWORD PTR [rdx+200], r8 + mov rax, QWORD PTR [rcx+168] + mov r8, QWORD PTR [rcx+160] + bswap rax + bswap r8 + mov QWORD PTR [rdx+208], rax + mov QWORD PTR [rdx+216], r8 + mov rax, QWORD PTR [rcx+152] + mov r8, QWORD PTR [rcx+144] + bswap rax + bswap r8 + mov QWORD PTR [rdx+224], rax + mov QWORD PTR [rdx+232], r8 + mov rax, QWORD PTR [rcx+136] + mov r8, QWORD PTR [rcx+128] + bswap rax + bswap r8 + mov QWORD PTR [rdx+240], rax + mov QWORD PTR [rdx+248], r8 + mov rax, QWORD PTR [rcx+120] + mov r8, QWORD PTR [rcx+112] + bswap rax + bswap r8 + mov QWORD PTR [rdx+256], rax + mov QWORD PTR [rdx+264], r8 + mov rax, QWORD PTR [rcx+104] + mov r8, QWORD PTR [rcx+96] + bswap rax + bswap r8 + mov QWORD PTR [rdx+272], rax + mov QWORD PTR [rdx+280], r8 + mov rax, QWORD PTR [rcx+88] + mov r8, QWORD PTR [rcx+80] + bswap rax + bswap r8 + mov QWORD PTR [rdx+288], rax + mov QWORD PTR [rdx+296], r8 + mov rax, QWORD PTR [rcx+72] + mov r8, QWORD PTR [rcx+64] + bswap rax + bswap r8 + mov QWORD PTR [rdx+304], rax + mov QWORD PTR [rdx+312], r8 + mov rax, QWORD PTR [rcx+56] + mov r8, QWORD PTR [rcx+48] + bswap rax + bswap r8 + mov QWORD PTR [rdx+320], rax + mov QWORD PTR [rdx+328], r8 + mov rax, QWORD PTR [rcx+40] + mov r8, QWORD PTR [rcx+32] + bswap rax + bswap r8 + mov QWORD PTR [rdx+336], rax + mov QWORD PTR [rdx+344], r8 + mov rax, QWORD PTR [rcx+24] + mov r8, QWORD PTR [rcx+16] + bswap rax + bswap r8 + mov QWORD PTR [rdx+352], rax + mov QWORD PTR [rdx+360], r8 + mov rax, QWORD PTR [rcx+8] + mov r8, QWORD PTR [rcx] + bswap rax + bswap r8 + mov QWORD PTR [rdx+368], rax + mov QWORD PTR [rdx+376], r8 + ret +sp_3072_to_bin_bswap ENDP +_text ENDS +IFNDEF NO_MOVBE_SUPPORT +; /* Write r as big endian to byte array. +; * Fixed length number of bytes written: 384 +; * Uses the movbe instruction which is optional. +; * +; * r A single precision integer. +; * a Byte array. +; */ +_text SEGMENT READONLY PARA +sp_3072_to_bin_movbe PROC + movbe rax, QWORD PTR [rcx+376] + movbe r8, QWORD PTR [rcx+368] + mov QWORD PTR [rdx], rax + mov QWORD PTR [rdx+8], r8 + movbe rax, QWORD PTR [rcx+360] + movbe r8, QWORD PTR [rcx+352] + mov QWORD PTR [rdx+16], rax + mov QWORD PTR [rdx+24], r8 + movbe rax, QWORD PTR [rcx+344] + movbe r8, QWORD PTR [rcx+336] + mov QWORD PTR [rdx+32], rax + mov QWORD PTR [rdx+40], r8 + movbe rax, QWORD PTR [rcx+328] + movbe r8, QWORD PTR [rcx+320] + mov QWORD PTR [rdx+48], rax + mov QWORD PTR [rdx+56], r8 + movbe rax, QWORD PTR [rcx+312] + movbe r8, QWORD PTR [rcx+304] + mov QWORD PTR [rdx+64], rax + mov QWORD PTR [rdx+72], r8 + movbe rax, QWORD PTR [rcx+296] + movbe r8, QWORD PTR [rcx+288] + mov QWORD PTR [rdx+80], rax + mov QWORD PTR [rdx+88], r8 + movbe rax, QWORD PTR [rcx+280] + movbe r8, QWORD PTR [rcx+272] + mov QWORD PTR [rdx+96], rax + mov QWORD PTR [rdx+104], r8 + movbe rax, QWORD PTR [rcx+264] + movbe r8, QWORD PTR [rcx+256] + mov QWORD PTR [rdx+112], rax + mov QWORD PTR [rdx+120], r8 + movbe rax, QWORD PTR [rcx+248] + movbe r8, QWORD PTR [rcx+240] + mov QWORD PTR [rdx+128], rax + mov QWORD PTR [rdx+136], r8 + movbe rax, QWORD PTR [rcx+232] + movbe r8, QWORD PTR [rcx+224] + mov QWORD PTR [rdx+144], rax + mov QWORD PTR [rdx+152], r8 + movbe rax, QWORD PTR [rcx+216] + movbe r8, QWORD PTR [rcx+208] + mov QWORD PTR [rdx+160], rax + mov QWORD PTR [rdx+168], r8 + movbe rax, QWORD PTR [rcx+200] + movbe r8, QWORD PTR [rcx+192] + mov QWORD PTR [rdx+176], rax + mov QWORD PTR [rdx+184], r8 + movbe rax, QWORD PTR [rcx+184] + movbe r8, QWORD PTR [rcx+176] + mov QWORD PTR [rdx+192], rax + mov QWORD PTR [rdx+200], r8 + movbe rax, QWORD PTR [rcx+168] + movbe r8, QWORD PTR [rcx+160] + mov QWORD PTR [rdx+208], rax + mov QWORD PTR [rdx+216], r8 + movbe rax, QWORD PTR [rcx+152] + movbe r8, QWORD PTR [rcx+144] + mov QWORD PTR [rdx+224], rax + mov QWORD PTR [rdx+232], r8 + movbe rax, QWORD PTR [rcx+136] + movbe r8, QWORD PTR [rcx+128] + mov QWORD PTR [rdx+240], rax + mov QWORD PTR [rdx+248], r8 + movbe rax, QWORD PTR [rcx+120] + movbe r8, QWORD PTR [rcx+112] + mov QWORD PTR [rdx+256], rax + mov QWORD PTR [rdx+264], r8 + movbe rax, QWORD PTR [rcx+104] + movbe r8, QWORD PTR [rcx+96] + mov QWORD PTR [rdx+272], rax + mov QWORD PTR [rdx+280], r8 + movbe rax, QWORD PTR [rcx+88] + movbe r8, QWORD PTR [rcx+80] + mov QWORD PTR [rdx+288], rax + mov QWORD PTR [rdx+296], r8 + movbe rax, QWORD PTR [rcx+72] + movbe r8, QWORD PTR [rcx+64] + mov QWORD PTR [rdx+304], rax + mov QWORD PTR [rdx+312], r8 + movbe rax, QWORD PTR [rcx+56] + movbe r8, QWORD PTR [rcx+48] + mov QWORD PTR [rdx+320], rax + mov QWORD PTR [rdx+328], r8 + movbe rax, QWORD PTR [rcx+40] + movbe r8, QWORD PTR [rcx+32] + mov QWORD PTR [rdx+336], rax + mov QWORD PTR [rdx+344], r8 + movbe rax, QWORD PTR [rcx+24] + movbe r8, QWORD PTR [rcx+16] + mov QWORD PTR [rdx+352], rax + mov QWORD PTR [rdx+360], r8 + movbe rax, QWORD PTR [rcx+8] + movbe r8, QWORD PTR [rcx] + mov QWORD PTR [rdx+368], rax + mov QWORD PTR [rdx+376], r8 + ret +sp_3072_to_bin_movbe ENDP +_text ENDS +ENDIF +; /* Multiply a and b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_3072_mul_12 PROC + push r12 + mov r9, rdx + sub rsp, 96 + ; A[0] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9] + xor r12, r12 + mov QWORD PTR [rsp], rax + mov r11, rdx + ; A[0] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[1] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+8] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rsp+8], r11 + ; A[0] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[1] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+8] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[2] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+16] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rsp+16], r12 + ; A[0] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[1] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+8] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[2] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+16] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[3] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+24] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rsp+24], r10 + ; A[0] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[1] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+8] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[2] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+16] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[3] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+24] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[4] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+32] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rsp+32], r11 + ; A[0] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[1] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+8] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[2] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+16] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[3] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+24] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[4] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+32] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[5] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+40] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rsp+40], r12 + ; A[0] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[1] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+8] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[2] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+16] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[3] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+24] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[4] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+32] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[5] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+40] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[6] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+48] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rsp+48], r10 + ; A[0] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[1] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+8] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[2] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+16] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[3] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+24] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[4] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+32] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[5] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+40] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[6] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+48] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[7] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+56] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rsp+56], r11 + ; A[0] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[1] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+8] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[2] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+16] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[3] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+24] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[4] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+32] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[5] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+40] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[6] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+48] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[7] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+56] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[8] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+64] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rsp+64], r12 + ; A[0] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[1] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+8] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[2] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+16] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[3] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+24] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[4] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+32] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[5] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+40] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[6] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+48] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[7] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+56] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[8] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+64] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[9] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+72] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rsp+72], r10 + ; A[0] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[1] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+8] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[2] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+16] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[3] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+24] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[4] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+32] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[5] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+40] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[6] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+48] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[7] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+56] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[8] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+64] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[9] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+72] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[10] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+80] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rsp+80], r11 + ; A[0] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[1] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+8] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[2] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+16] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[3] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+24] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[4] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+32] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[5] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+40] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[6] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+48] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[7] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+56] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[8] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+64] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[9] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+72] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[10] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+80] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[11] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+88] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rsp+88], r12 + ; A[1] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+8] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[2] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+16] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[3] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+24] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[4] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+32] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[5] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+40] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[6] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+48] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[7] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+56] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[8] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+64] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[9] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+72] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[10] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+80] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[11] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+88] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rcx+96], r10 + ; A[2] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+16] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[3] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+24] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[4] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+32] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[5] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+40] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[6] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+48] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[7] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+56] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[8] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+64] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[9] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+72] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[10] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+80] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[11] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+88] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rcx+104], r11 + ; A[3] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+24] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[4] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+32] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[5] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+40] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[6] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+48] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[7] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+56] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[8] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+64] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[9] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+72] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[10] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+80] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[11] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+88] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rcx+112], r12 + ; A[4] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+32] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[5] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+40] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[6] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+48] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[7] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+56] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[8] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+64] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[9] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+72] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[10] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+80] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[11] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+88] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rcx+120], r10 + ; A[5] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+40] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[6] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+48] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[7] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+56] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[8] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+64] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[9] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+72] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[10] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+80] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[11] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+88] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rcx+128], r11 + ; A[6] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+48] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[7] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+56] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[8] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+64] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[9] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+72] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[10] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+80] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[11] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+88] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rcx+136], r12 + ; A[7] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+56] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[8] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+64] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[9] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+72] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[10] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+80] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[11] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+88] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rcx+144], r10 + ; A[8] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+64] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[9] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+72] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[10] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+80] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[11] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+88] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rcx+152], r11 + ; A[9] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+72] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[10] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+80] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[11] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+88] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rcx+160], r12 + ; A[10] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+80] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[11] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+88] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rcx+168], r10 + ; A[11] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+88] + add r11, rax + adc r12, rdx + mov QWORD PTR [rcx+176], r11 + mov QWORD PTR [rcx+184], r12 + mov rax, QWORD PTR [rsp] + mov rdx, QWORD PTR [rsp+8] + mov r10, QWORD PTR [rsp+16] + mov r11, QWORD PTR [rsp+24] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], rdx + mov QWORD PTR [rcx+16], r10 + mov QWORD PTR [rcx+24], r11 + mov rax, QWORD PTR [rsp+32] + mov rdx, QWORD PTR [rsp+40] + mov r10, QWORD PTR [rsp+48] + mov r11, QWORD PTR [rsp+56] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], rdx + mov QWORD PTR [rcx+48], r10 + mov QWORD PTR [rcx+56], r11 + mov rax, QWORD PTR [rsp+64] + mov rdx, QWORD PTR [rsp+72] + mov r10, QWORD PTR [rsp+80] + mov r11, QWORD PTR [rsp+88] + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], rdx + mov QWORD PTR [rcx+80], r10 + mov QWORD PTR [rcx+88], r11 + add rsp, 96 + pop r12 + ret +sp_3072_mul_12 ENDP +_text ENDS +; /* Square a and put result in r. (r = a * a) +; * +; * r A single precision integer. +; * a A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_3072_sqr_12 PROC + push r12 + push r13 + push r14 + mov r8, rdx + sub rsp, 96 + ; A[0] * A[0] + mov rax, QWORD PTR [r8] + mul rax + xor r11, r11 + mov QWORD PTR [rsp], rax + mov r10, rdx + ; A[0] * A[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r8] + xor r9, r9 + add r10, rax + adc r11, rdx + adc r9, 0 + add r10, rax + adc r11, rdx + adc r9, 0 + mov QWORD PTR [rsp+8], r10 + ; A[0] * A[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r8] + xor r10, r10 + add r11, rax + adc r9, rdx + adc r10, 0 + add r11, rax + adc r9, rdx + adc r10, 0 + ; A[1] * A[1] + mov rax, QWORD PTR [r8+8] + mul rax + add r11, rax + adc r9, rdx + adc r10, 0 + mov QWORD PTR [rsp+16], r11 + ; A[0] * A[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r8] + xor r11, r11 + add r9, rax + adc r10, rdx + adc r11, 0 + add r9, rax + adc r10, rdx + adc r11, 0 + ; A[1] * A[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r8+8] + add r9, rax + adc r10, rdx + adc r11, 0 + add r9, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rsp+24], r9 + ; A[0] * A[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r8] + xor r9, r9 + add r10, rax + adc r11, rdx + adc r9, 0 + add r10, rax + adc r11, rdx + adc r9, 0 + ; A[1] * A[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r8+8] + add r10, rax + adc r11, rdx + adc r9, 0 + add r10, rax + adc r11, rdx + adc r9, 0 + ; A[2] * A[2] + mov rax, QWORD PTR [r8+16] + mul rax + add r10, rax + adc r11, rdx + adc r9, 0 + mov QWORD PTR [rsp+32], r10 + ; A[0] * A[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r8] + xor r10, r10 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r11, r12 + adc r9, r13 + adc r10, r14 + mov QWORD PTR [rsp+40], r11 + ; A[0] * A[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r8] + xor r11, r11 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[3] + mov rax, QWORD PTR [r8+24] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r9, r12 + adc r10, r13 + adc r11, r14 + mov QWORD PTR [rsp+48], r9 + ; A[0] * A[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r8] + xor r9, r9 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r10, r12 + adc r11, r13 + adc r9, r14 + mov QWORD PTR [rsp+56], r10 + ; A[0] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8] + xor r10, r10 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[4] + mov rax, QWORD PTR [r8+32] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r11, r12 + adc r9, r13 + adc r10, r14 + mov QWORD PTR [rsp+64], r11 + ; A[0] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8] + xor r11, r11 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r9, r12 + adc r10, r13 + adc r11, r14 + mov QWORD PTR [rsp+72], r9 + ; A[0] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8] + xor r9, r9 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[5] * A[5] + mov rax, QWORD PTR [r8+40] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r10, r12 + adc r11, r13 + adc r9, r14 + mov QWORD PTR [rsp+80], r10 + ; A[0] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8] + xor r10, r10 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[5] * A[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r8+40] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r11, r12 + adc r9, r13 + adc r10, r14 + mov QWORD PTR [rsp+88], r11 + ; A[1] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+8] + xor r11, r11 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[2] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[5] * A[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r8+40] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[6] * A[6] + mov rax, QWORD PTR [r8+48] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r9, r12 + adc r10, r13 + adc r11, r14 + mov QWORD PTR [rcx+96], r9 + ; A[2] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+16] + xor r9, r9 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[3] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[5] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8+40] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[6] * A[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r8+48] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r10, r12 + adc r11, r13 + adc r9, r14 + mov QWORD PTR [rcx+104], r10 + ; A[3] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+24] + xor r10, r10 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[4] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[5] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+40] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[6] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8+48] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[7] * A[7] + mov rax, QWORD PTR [r8+56] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r11, r12 + adc r9, r13 + adc r10, r14 + mov QWORD PTR [rcx+112], r11 + ; A[4] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+32] + xor r11, r11 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[5] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+40] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[6] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+48] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[7] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8+56] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r9, r12 + adc r10, r13 + adc r11, r14 + mov QWORD PTR [rcx+120], r9 + ; A[5] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+40] + xor r9, r9 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[6] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+48] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[7] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+56] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[8] * A[8] + mov rax, QWORD PTR [r8+64] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r10, r12 + adc r11, r13 + adc r9, r14 + mov QWORD PTR [rcx+128], r10 + ; A[6] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+48] + xor r10, r10 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[7] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+56] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[8] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+64] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r11, r12 + adc r9, r13 + adc r10, r14 + mov QWORD PTR [rcx+136], r11 + ; A[7] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+56] + xor r11, r11 + add r9, rax + adc r10, rdx + adc r11, 0 + add r9, rax + adc r10, rdx + adc r11, 0 + ; A[8] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+64] + add r9, rax + adc r10, rdx + adc r11, 0 + add r9, rax + adc r10, rdx + adc r11, 0 + ; A[9] * A[9] + mov rax, QWORD PTR [r8+72] + mul rax + add r9, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rcx+144], r9 + ; A[8] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+64] + xor r9, r9 + add r10, rax + adc r11, rdx + adc r9, 0 + add r10, rax + adc r11, rdx + adc r9, 0 + ; A[9] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+72] + add r10, rax + adc r11, rdx + adc r9, 0 + add r10, rax + adc r11, rdx + adc r9, 0 + mov QWORD PTR [rcx+152], r10 + ; A[9] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+72] + xor r10, r10 + add r11, rax + adc r9, rdx + adc r10, 0 + add r11, rax + adc r9, rdx + adc r10, 0 + ; A[10] * A[10] + mov rax, QWORD PTR [r8+80] + mul rax + add r11, rax + adc r9, rdx + adc r10, 0 + mov QWORD PTR [rcx+160], r11 + ; A[10] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+80] + xor r11, r11 + add r9, rax + adc r10, rdx + adc r11, 0 + add r9, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rcx+168], r9 + ; A[11] * A[11] + mov rax, QWORD PTR [r8+88] + mul rax + add r10, rax + adc r11, rdx + mov QWORD PTR [rcx+176], r10 + mov QWORD PTR [rcx+184], r11 + mov rax, QWORD PTR [rsp] + mov rdx, QWORD PTR [rsp+8] + mov r12, QWORD PTR [rsp+16] + mov r13, QWORD PTR [rsp+24] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], rdx + mov QWORD PTR [rcx+16], r12 + mov QWORD PTR [rcx+24], r13 + mov rax, QWORD PTR [rsp+32] + mov rdx, QWORD PTR [rsp+40] + mov r12, QWORD PTR [rsp+48] + mov r13, QWORD PTR [rsp+56] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], rdx + mov QWORD PTR [rcx+48], r12 + mov QWORD PTR [rcx+56], r13 + mov rax, QWORD PTR [rsp+64] + mov rdx, QWORD PTR [rsp+72] + mov r12, QWORD PTR [rsp+80] + mov r13, QWORD PTR [rsp+88] + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], rdx + mov QWORD PTR [rcx+80], r12 + mov QWORD PTR [rcx+88], r13 + add rsp, 96 + pop r14 + pop r13 + pop r12 + ret +sp_3072_sqr_12 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Multiply a and b into r. (r = a * b) +; * +; * r Result of multiplication. +; * a First number to multiply. +; * b Second number to multiply. +; */ +_text SEGMENT READONLY PARA +sp_3072_mul_avx2_12 PROC + push rbx + push rbp + push r12 + push r13 + push r14 + mov rbp, r8 + mov r8, rcx + mov r9, rdx + sub rsp, 96 + cmp r9, r8 + mov rbx, rsp + cmovne rbx, r8 + cmp rbp, r8 + cmove rbx, rsp + add r8, 96 + xor r14, r14 + mov rdx, QWORD PTR [r9] + ; A[0] * B[0] + mulx r11, r10, QWORD PTR [rbp] + ; A[0] * B[1] + mulx r12, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx], r10 + adcx r11, rax + mov QWORD PTR [rbx+8], r11 + ; A[0] * B[2] + mulx r10, rax, QWORD PTR [rbp+16] + adcx r12, rax + ; A[0] * B[3] + mulx r11, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+16], r12 + adcx r10, rax + mov QWORD PTR [rbx+24], r10 + ; A[0] * B[4] + mulx r12, rax, QWORD PTR [rbp+32] + adcx r11, rax + ; A[0] * B[5] + mulx r10, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+32], r11 + adcx r12, rax + mov QWORD PTR [rbx+40], r12 + ; A[0] * B[6] + mulx r11, rax, QWORD PTR [rbp+48] + adcx r10, rax + ; A[0] * B[7] + mulx r12, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+48], r10 + adcx r11, rax + mov QWORD PTR [rbx+56], r11 + ; A[0] * B[8] + mulx r10, rax, QWORD PTR [rbp+64] + adcx r12, rax + ; A[0] * B[9] + mulx r11, rax, QWORD PTR [rbp+72] + mov QWORD PTR [rbx+64], r12 + adcx r10, rax + mov QWORD PTR [rbx+72], r10 + ; A[0] * B[10] + mulx r12, rax, QWORD PTR [rbp+80] + adcx r11, rax + ; A[0] * B[11] + mulx r10, rax, QWORD PTR [rbp+88] + mov QWORD PTR [rbx+80], r11 + adcx r12, rax + adcx r10, r14 + mov r13, r14 + adcx r13, r14 + mov QWORD PTR [rbx+88], r12 + mov QWORD PTR [r8], r10 + mov rdx, QWORD PTR [r9+8] + mov r11, QWORD PTR [rbx+8] + mov r12, QWORD PTR [rbx+16] + mov r10, QWORD PTR [rbx+24] + ; A[1] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r11, rax + adox r12, rcx + ; A[1] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+8], r11 + adcx r12, rax + adox r10, rcx + mov QWORD PTR [rbx+16], r12 + mov r11, QWORD PTR [rbx+32] + mov r12, QWORD PTR [rbx+40] + ; A[1] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + adcx r10, rax + adox r11, rcx + ; A[1] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+24], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbx+32], r11 + mov r10, QWORD PTR [rbx+48] + mov r11, QWORD PTR [rbx+56] + ; A[1] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r12, rax + adox r10, rcx + ; A[1] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+40], r12 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbx+48], r10 + mov r12, QWORD PTR [rbx+64] + mov r10, QWORD PTR [rbx+72] + ; A[1] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + adcx r11, rax + adox r12, rcx + ; A[1] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+56], r11 + adcx r12, rax + adox r10, rcx + mov QWORD PTR [rbx+64], r12 + mov r11, QWORD PTR [rbx+80] + mov r12, QWORD PTR [rbx+88] + ; A[1] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r10, rax + adox r11, rcx + ; A[1] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [rbx+72], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbx+80], r11 + mov r10, QWORD PTR [r8] + ; A[1] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + adcx r12, rax + adox r10, rcx + ; A[1] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [rbx+88], r12 + mov r11, r14 + adcx r10, rax + adox r11, rcx + adcx r11, r13 + mov r13, r14 + adox r13, r14 + adcx r13, r14 + mov QWORD PTR [r8], r10 + mov QWORD PTR [r8+8], r11 + mov rdx, QWORD PTR [r9+16] + mov r12, QWORD PTR [rbx+16] + mov r10, QWORD PTR [rbx+24] + mov r11, QWORD PTR [rbx+32] + ; A[2] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r12, rax + adox r10, rcx + ; A[2] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+16], r12 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbx+24], r10 + mov r12, QWORD PTR [rbx+40] + mov r10, QWORD PTR [rbx+48] + ; A[2] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + adcx r11, rax + adox r12, rcx + ; A[2] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+32], r11 + adcx r12, rax + adox r10, rcx + mov QWORD PTR [rbx+40], r12 + mov r11, QWORD PTR [rbx+56] + mov r12, QWORD PTR [rbx+64] + ; A[2] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r10, rax + adox r11, rcx + ; A[2] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+48], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbx+56], r11 + mov r10, QWORD PTR [rbx+72] + mov r11, QWORD PTR [rbx+80] + ; A[2] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + adcx r12, rax + adox r10, rcx + ; A[2] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+64], r12 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbx+72], r10 + mov r12, QWORD PTR [rbx+88] + mov r10, QWORD PTR [r8] + ; A[2] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r11, rax + adox r12, rcx + ; A[2] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [rbx+80], r11 + adcx r12, rax + adox r10, rcx + mov QWORD PTR [rbx+88], r12 + mov r11, QWORD PTR [r8+8] + ; A[2] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + adcx r10, rax + adox r11, rcx + ; A[2] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8], r10 + mov r12, r14 + adcx r11, rax + adox r12, rcx + adcx r12, r13 + mov r13, r14 + adox r13, r14 + adcx r13, r14 + mov QWORD PTR [r8+8], r11 + mov QWORD PTR [r8+16], r12 + mov rdx, QWORD PTR [r9+24] + mov r10, QWORD PTR [rbx+24] + mov r11, QWORD PTR [rbx+32] + mov r12, QWORD PTR [rbx+40] + ; A[3] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r10, rax + adox r11, rcx + ; A[3] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+24], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbx+32], r11 + mov r10, QWORD PTR [rbx+48] + mov r11, QWORD PTR [rbx+56] + ; A[3] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + adcx r12, rax + adox r10, rcx + ; A[3] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+40], r12 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbx+48], r10 + mov r12, QWORD PTR [rbx+64] + mov r10, QWORD PTR [rbx+72] + ; A[3] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r11, rax + adox r12, rcx + ; A[3] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+56], r11 + adcx r12, rax + adox r10, rcx + mov QWORD PTR [rbx+64], r12 + mov r11, QWORD PTR [rbx+80] + mov r12, QWORD PTR [rbx+88] + ; A[3] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + adcx r10, rax + adox r11, rcx + ; A[3] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+72], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbx+80], r11 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + ; A[3] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r12, rax + adox r10, rcx + ; A[3] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [rbx+88], r12 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8], r10 + mov r12, QWORD PTR [r8+16] + ; A[3] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + adcx r11, rax + adox r12, rcx + ; A[3] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+8], r11 + mov r10, r14 + adcx r12, rax + adox r10, rcx + adcx r10, r13 + mov r13, r14 + adox r13, r14 + adcx r13, r14 + mov QWORD PTR [r8+16], r12 + mov QWORD PTR [r8+24], r10 + mov rdx, QWORD PTR [r9+32] + mov r11, QWORD PTR [rbx+32] + mov r12, QWORD PTR [rbx+40] + mov r10, QWORD PTR [rbx+48] + ; A[4] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r11, rax + adox r12, rcx + ; A[4] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+32], r11 + adcx r12, rax + adox r10, rcx + mov QWORD PTR [rbx+40], r12 + mov r11, QWORD PTR [rbx+56] + mov r12, QWORD PTR [rbx+64] + ; A[4] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + adcx r10, rax + adox r11, rcx + ; A[4] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+48], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbx+56], r11 + mov r10, QWORD PTR [rbx+72] + mov r11, QWORD PTR [rbx+80] + ; A[4] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r12, rax + adox r10, rcx + ; A[4] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+64], r12 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbx+72], r10 + mov r12, QWORD PTR [rbx+88] + mov r10, QWORD PTR [r8] + ; A[4] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + adcx r11, rax + adox r12, rcx + ; A[4] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+80], r11 + adcx r12, rax + adox r10, rcx + mov QWORD PTR [rbx+88], r12 + mov r11, QWORD PTR [r8+8] + mov r12, QWORD PTR [r8+16] + ; A[4] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r10, rax + adox r11, rcx + ; A[4] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+8], r11 + mov r10, QWORD PTR [r8+24] + ; A[4] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + adcx r12, rax + adox r10, rcx + ; A[4] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+16], r12 + mov r11, r14 + adcx r10, rax + adox r11, rcx + adcx r11, r13 + mov r13, r14 + adox r13, r14 + adcx r13, r14 + mov QWORD PTR [r8+24], r10 + mov QWORD PTR [r8+32], r11 + mov rdx, QWORD PTR [r9+40] + mov r12, QWORD PTR [rbx+40] + mov r10, QWORD PTR [rbx+48] + mov r11, QWORD PTR [rbx+56] + ; A[5] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r12, rax + adox r10, rcx + ; A[5] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+40], r12 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbx+48], r10 + mov r12, QWORD PTR [rbx+64] + mov r10, QWORD PTR [rbx+72] + ; A[5] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + adcx r11, rax + adox r12, rcx + ; A[5] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+56], r11 + adcx r12, rax + adox r10, rcx + mov QWORD PTR [rbx+64], r12 + mov r11, QWORD PTR [rbx+80] + mov r12, QWORD PTR [rbx+88] + ; A[5] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r10, rax + adox r11, rcx + ; A[5] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+72], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbx+80], r11 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + ; A[5] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + adcx r12, rax + adox r10, rcx + ; A[5] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+88], r12 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8], r10 + mov r12, QWORD PTR [r8+16] + mov r10, QWORD PTR [r8+24] + ; A[5] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r11, rax + adox r12, rcx + ; A[5] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8+8], r11 + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+16], r12 + mov r11, QWORD PTR [r8+32] + ; A[5] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + adcx r10, rax + adox r11, rcx + ; A[5] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+24], r10 + mov r12, r14 + adcx r11, rax + adox r12, rcx + adcx r12, r13 + mov r13, r14 + adox r13, r14 + adcx r13, r14 + mov QWORD PTR [r8+32], r11 + mov QWORD PTR [r8+40], r12 + mov rdx, QWORD PTR [r9+48] + mov r10, QWORD PTR [rbx+48] + mov r11, QWORD PTR [rbx+56] + mov r12, QWORD PTR [rbx+64] + ; A[6] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r10, rax + adox r11, rcx + ; A[6] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+48], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbx+56], r11 + mov r10, QWORD PTR [rbx+72] + mov r11, QWORD PTR [rbx+80] + ; A[6] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + adcx r12, rax + adox r10, rcx + ; A[6] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+64], r12 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbx+72], r10 + mov r12, QWORD PTR [rbx+88] + mov r10, QWORD PTR [r8] + ; A[6] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r11, rax + adox r12, rcx + ; A[6] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+80], r11 + adcx r12, rax + adox r10, rcx + mov QWORD PTR [rbx+88], r12 + mov r11, QWORD PTR [r8+8] + mov r12, QWORD PTR [r8+16] + ; A[6] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + adcx r10, rax + adox r11, rcx + ; A[6] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [r8], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+8], r11 + mov r10, QWORD PTR [r8+24] + mov r11, QWORD PTR [r8+32] + ; A[6] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r12, rax + adox r10, rcx + ; A[6] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8+16], r12 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+24], r10 + mov r12, QWORD PTR [r8+40] + ; A[6] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + adcx r11, rax + adox r12, rcx + ; A[6] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+32], r11 + mov r10, r14 + adcx r12, rax + adox r10, rcx + adcx r10, r13 + mov r13, r14 + adox r13, r14 + adcx r13, r14 + mov QWORD PTR [r8+40], r12 + mov QWORD PTR [r8+48], r10 + mov rdx, QWORD PTR [r9+56] + mov r11, QWORD PTR [rbx+56] + mov r12, QWORD PTR [rbx+64] + mov r10, QWORD PTR [rbx+72] + ; A[7] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r11, rax + adox r12, rcx + ; A[7] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+56], r11 + adcx r12, rax + adox r10, rcx + mov QWORD PTR [rbx+64], r12 + mov r11, QWORD PTR [rbx+80] + mov r12, QWORD PTR [rbx+88] + ; A[7] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + adcx r10, rax + adox r11, rcx + ; A[7] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+72], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbx+80], r11 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + ; A[7] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r12, rax + adox r10, rcx + ; A[7] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+88], r12 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8], r10 + mov r12, QWORD PTR [r8+16] + mov r10, QWORD PTR [r8+24] + ; A[7] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + adcx r11, rax + adox r12, rcx + ; A[7] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [r8+8], r11 + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+16], r12 + mov r11, QWORD PTR [r8+32] + mov r12, QWORD PTR [r8+40] + ; A[7] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r10, rax + adox r11, rcx + ; A[7] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8+24], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+32], r11 + mov r10, QWORD PTR [r8+48] + ; A[7] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + adcx r12, rax + adox r10, rcx + ; A[7] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+40], r12 + mov r11, r14 + adcx r10, rax + adox r11, rcx + adcx r11, r13 + mov r13, r14 + adox r13, r14 + adcx r13, r14 + mov QWORD PTR [r8+48], r10 + mov QWORD PTR [r8+56], r11 + mov rdx, QWORD PTR [r9+64] + mov r12, QWORD PTR [rbx+64] + mov r10, QWORD PTR [rbx+72] + mov r11, QWORD PTR [rbx+80] + ; A[8] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r12, rax + adox r10, rcx + ; A[8] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+64], r12 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbx+72], r10 + mov r12, QWORD PTR [rbx+88] + mov r10, QWORD PTR [r8] + ; A[8] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + adcx r11, rax + adox r12, rcx + ; A[8] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+80], r11 + adcx r12, rax + adox r10, rcx + mov QWORD PTR [rbx+88], r12 + mov r11, QWORD PTR [r8+8] + mov r12, QWORD PTR [r8+16] + ; A[8] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r10, rax + adox r11, rcx + ; A[8] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [r8], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+8], r11 + mov r10, QWORD PTR [r8+24] + mov r11, QWORD PTR [r8+32] + ; A[8] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + adcx r12, rax + adox r10, rcx + ; A[8] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [r8+16], r12 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+24], r10 + mov r12, QWORD PTR [r8+40] + mov r10, QWORD PTR [r8+48] + ; A[8] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r11, rax + adox r12, rcx + ; A[8] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8+32], r11 + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+40], r12 + mov r11, QWORD PTR [r8+56] + ; A[8] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + adcx r10, rax + adox r11, rcx + ; A[8] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+48], r10 + mov r12, r14 + adcx r11, rax + adox r12, rcx + adcx r12, r13 + mov r13, r14 + adox r13, r14 + adcx r13, r14 + mov QWORD PTR [r8+56], r11 + mov QWORD PTR [r8+64], r12 + mov rdx, QWORD PTR [r9+72] + mov r10, QWORD PTR [rbx+72] + mov r11, QWORD PTR [rbx+80] + mov r12, QWORD PTR [rbx+88] + ; A[9] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r10, rax + adox r11, rcx + ; A[9] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+72], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbx+80], r11 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + ; A[9] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + adcx r12, rax + adox r10, rcx + ; A[9] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+88], r12 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8], r10 + mov r12, QWORD PTR [r8+16] + mov r10, QWORD PTR [r8+24] + ; A[9] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r11, rax + adox r12, rcx + ; A[9] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [r8+8], r11 + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+16], r12 + mov r11, QWORD PTR [r8+32] + mov r12, QWORD PTR [r8+40] + ; A[9] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + adcx r10, rax + adox r11, rcx + ; A[9] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [r8+24], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+32], r11 + mov r10, QWORD PTR [r8+48] + mov r11, QWORD PTR [r8+56] + ; A[9] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r12, rax + adox r10, rcx + ; A[9] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8+40], r12 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+48], r10 + mov r12, QWORD PTR [r8+64] + ; A[9] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + adcx r11, rax + adox r12, rcx + ; A[9] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+56], r11 + mov r10, r14 + adcx r12, rax + adox r10, rcx + adcx r10, r13 + mov r13, r14 + adox r13, r14 + adcx r13, r14 + mov QWORD PTR [r8+64], r12 + mov QWORD PTR [r8+72], r10 + mov rdx, QWORD PTR [r9+80] + mov r11, QWORD PTR [rbx+80] + mov r12, QWORD PTR [rbx+88] + mov r10, QWORD PTR [r8] + ; A[10] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r11, rax + adox r12, rcx + ; A[10] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+80], r11 + adcx r12, rax + adox r10, rcx + mov QWORD PTR [rbx+88], r12 + mov r11, QWORD PTR [r8+8] + mov r12, QWORD PTR [r8+16] + ; A[10] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + adcx r10, rax + adox r11, rcx + ; A[10] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [r8], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+8], r11 + mov r10, QWORD PTR [r8+24] + mov r11, QWORD PTR [r8+32] + ; A[10] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r12, rax + adox r10, rcx + ; A[10] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [r8+16], r12 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+24], r10 + mov r12, QWORD PTR [r8+40] + mov r10, QWORD PTR [r8+48] + ; A[10] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + adcx r11, rax + adox r12, rcx + ; A[10] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [r8+32], r11 + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+40], r12 + mov r11, QWORD PTR [r8+56] + mov r12, QWORD PTR [r8+64] + ; A[10] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r10, rax + adox r11, rcx + ; A[10] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8+48], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+56], r11 + mov r10, QWORD PTR [r8+72] + ; A[10] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + adcx r12, rax + adox r10, rcx + ; A[10] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+64], r12 + mov r11, r14 + adcx r10, rax + adox r11, rcx + adcx r11, r13 + mov r13, r14 + adox r13, r14 + adcx r13, r14 + mov QWORD PTR [r8+72], r10 + mov QWORD PTR [r8+80], r11 + mov rdx, QWORD PTR [r9+88] + mov r12, QWORD PTR [rbx+88] + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + ; A[11] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r12, rax + adox r10, rcx + ; A[11] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+88], r12 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8], r10 + mov r12, QWORD PTR [r8+16] + mov r10, QWORD PTR [r8+24] + ; A[11] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + adcx r11, rax + adox r12, rcx + ; A[11] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [r8+8], r11 + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+16], r12 + mov r11, QWORD PTR [r8+32] + mov r12, QWORD PTR [r8+40] + ; A[11] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r10, rax + adox r11, rcx + ; A[11] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [r8+24], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+32], r11 + mov r10, QWORD PTR [r8+48] + mov r11, QWORD PTR [r8+56] + ; A[11] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + adcx r12, rax + adox r10, rcx + ; A[11] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [r8+40], r12 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+48], r10 + mov r12, QWORD PTR [r8+64] + mov r10, QWORD PTR [r8+72] + ; A[11] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r11, rax + adox r12, rcx + ; A[11] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8+56], r11 + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+64], r12 + mov r11, QWORD PTR [r8+80] + ; A[11] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + adcx r10, rax + adox r11, rcx + ; A[11] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+72], r10 + mov r12, r14 + adcx r11, rax + adox r12, rcx + adcx r12, r13 + mov QWORD PTR [r8+80], r11 + mov QWORD PTR [r8+88], r12 + sub r8, 96 + cmp r9, r8 + je L_start_3072_mul_avx2_12 + cmp rbp, r8 + jne L_end_3072_mul_avx2_12 +L_start_3072_mul_avx2_12: + vmovdqu xmm0, OWORD PTR [rbx] + vmovups OWORD PTR [r8], xmm0 + vmovdqu xmm0, OWORD PTR [rbx+16] + vmovups OWORD PTR [r8+16], xmm0 + vmovdqu xmm0, OWORD PTR [rbx+32] + vmovups OWORD PTR [r8+32], xmm0 + vmovdqu xmm0, OWORD PTR [rbx+48] + vmovups OWORD PTR [r8+48], xmm0 + vmovdqu xmm0, OWORD PTR [rbx+64] + vmovups OWORD PTR [r8+64], xmm0 + vmovdqu xmm0, OWORD PTR [rbx+80] + vmovups OWORD PTR [r8+80], xmm0 +L_end_3072_mul_avx2_12: + add rsp, 96 + pop r14 + pop r13 + pop r12 + pop rbp + pop rbx + ret +sp_3072_mul_avx2_12 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Square a and put result in r. (r = a * a) +; * +; * r A single precision integer. +; * a A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_3072_sqr_avx2_12 PROC + push rbp + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + push rbx + mov r8, rcx + mov r9, rdx + sub rsp, 96 + cmp r9, r8 + mov rbp, rsp + cmovne rbp, r8 + add r8, 96 + xor r12, r12 + ; Diagonal 1 + ; A[1] x A[0] + mov rdx, QWORD PTR [r9] + mulx r11, r10, QWORD PTR [r9+8] + mov QWORD PTR [rbp+8], r10 + mov r10, r12 + ; A[2] x A[0] + mulx rcx, rax, QWORD PTR [r9+16] + adcx r11, rax + adox r10, rcx + mov QWORD PTR [rbp+16], r11 + mov r11, r12 + ; A[3] x A[0] + mulx rcx, rax, QWORD PTR [r9+24] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbp+24], r10 + mov r10, r12 + ; A[4] x A[0] + mulx rcx, rax, QWORD PTR [r9+32] + adcx r11, rax + adox r10, rcx + mov QWORD PTR [rbp+32], r11 + mov r11, r12 + ; A[5] x A[0] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbp+40], r10 + mov r10, r12 + ; A[6] x A[0] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r11, rax + adox r10, rcx + mov QWORD PTR [rbp+48], r11 + mov r11, r12 + ; A[7] x A[0] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r10, rax + adox r11, rcx + mov r14, r10 + mov r10, r12 + ; A[8] x A[0] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r11, rax + adox r10, rcx + mov r15, r11 + mov r11, r12 + ; A[9] x A[0] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r10, rax + adox r11, rcx + mov rdi, r10 + mov r10, r12 + ; A[10] x A[0] + mulx rcx, rax, QWORD PTR [r9+80] + adcx r11, rax + adox r10, rcx + mov rsi, r11 + mov r11, r12 + ; A[11] x A[0] + mulx rcx, rax, QWORD PTR [r9+88] + adcx r10, rax + adox r11, rcx + mov rbx, r10 + ; Carry + adcx r11, r12 + mov r13, r12 + adcx r13, r12 + adox r13, r12 + mov QWORD PTR [r8], r11 + ; Diagonal 2 + mov r11, QWORD PTR [rbp+24] + mov r10, QWORD PTR [rbp+32] + ; A[2] x A[1] + mov rdx, QWORD PTR [r9+8] + mulx rcx, rax, QWORD PTR [r9+16] + adcx r11, rax + adox r10, rcx + mov QWORD PTR [rbp+24], r11 + mov r11, QWORD PTR [rbp+40] + ; A[3] x A[1] + mulx rcx, rax, QWORD PTR [r9+24] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbp+32], r10 + mov r10, QWORD PTR [rbp+48] + ; A[4] x A[1] + mulx rcx, rax, QWORD PTR [r9+32] + adcx r11, rax + adox r10, rcx + mov QWORD PTR [rbp+40], r11 + ; No load %r12 - %r9 + ; A[5] x A[1] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r10, rax + adox r14, rcx + mov QWORD PTR [rbp+48], r10 + ; No load %r13 - %r8 + ; A[6] x A[1] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r14, rax + adox r15, rcx + ; No store %r12 + ; No load %r14 - %r9 + ; A[7] x A[1] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r15, rax + adox rdi, rcx + ; No store %r13 + ; No load %r15 - %r8 + ; A[8] x A[1] + mulx rcx, rax, QWORD PTR [r9+64] + adcx rdi, rax + adox rsi, rcx + ; No store %r14 + ; No load %rbx - %r9 + ; A[9] x A[1] + mulx rcx, rax, QWORD PTR [r9+72] + adcx rsi, rax + adox rbx, rcx + ; No store %r15 + mov r10, QWORD PTR [r8] + ; A[10] x A[1] + mulx rcx, rax, QWORD PTR [r9+80] + adcx rbx, rax + adox r10, rcx + ; No store %rbx + mov r11, r12 + ; A[11] x A[1] + mulx rcx, rax, QWORD PTR [r9+88] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8], r10 + mov r10, r12 + ; A[11] x A[2] + mov rdx, QWORD PTR [r9+16] + mulx rcx, rax, QWORD PTR [r9+88] + adcx r11, rax + adox r10, rcx + mov QWORD PTR [r8+8], r11 + ; Carry + adcx r10, r13 + mov r13, r12 + adcx r13, r12 + adox r13, r12 + mov QWORD PTR [r8+16], r10 + ; Diagonal 3 + mov r10, QWORD PTR [rbp+40] + mov r11, QWORD PTR [rbp+48] + ; A[3] x A[2] + mulx rcx, rax, QWORD PTR [r9+24] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbp+40], r10 + ; No load %r12 - %r8 + ; A[4] x A[2] + mulx rcx, rax, QWORD PTR [r9+32] + adcx r11, rax + adox r14, rcx + mov QWORD PTR [rbp+48], r11 + ; No load %r13 - %r9 + ; A[5] x A[2] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r14, rax + adox r15, rcx + ; No store %r12 + ; No load %r14 - %r8 + ; A[6] x A[2] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r15, rax + adox rdi, rcx + ; No store %r13 + ; No load %r15 - %r9 + ; A[7] x A[2] + mulx rcx, rax, QWORD PTR [r9+56] + adcx rdi, rax + adox rsi, rcx + ; No store %r14 + ; No load %rbx - %r8 + ; A[8] x A[2] + mulx rcx, rax, QWORD PTR [r9+64] + adcx rsi, rax + adox rbx, rcx + ; No store %r15 + mov r11, QWORD PTR [r8] + ; A[9] x A[2] + mulx rcx, rax, QWORD PTR [r9+72] + adcx rbx, rax + adox r11, rcx + ; No store %rbx + mov r10, QWORD PTR [r8+8] + ; A[10] x A[2] + mulx rcx, rax, QWORD PTR [r9+80] + adcx r11, rax + adox r10, rcx + mov QWORD PTR [r8], r11 + mov r11, QWORD PTR [r8+16] + ; A[10] x A[3] + mov rdx, QWORD PTR [r9+80] + mulx rcx, rax, QWORD PTR [r9+24] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+8], r10 + mov r10, r12 + ; A[10] x A[4] + mulx rcx, rax, QWORD PTR [r9+32] + adcx r11, rax + adox r10, rcx + mov QWORD PTR [r8+16], r11 + mov r11, r12 + ; A[10] x A[5] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+24], r10 + ; Carry + adcx r11, r13 + mov r13, r12 + adcx r13, r12 + adox r13, r12 + mov QWORD PTR [r8+32], r11 + ; Diagonal 4 + ; No load %r12 - %r9 + ; No load %r13 - %r8 + ; A[4] x A[3] + mov rdx, QWORD PTR [r9+24] + mulx rcx, rax, QWORD PTR [r9+32] + adcx r14, rax + adox r15, rcx + ; No store %r12 + ; No load %r14 - %r9 + ; A[5] x A[3] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r15, rax + adox rdi, rcx + ; No store %r13 + ; No load %r15 - %r8 + ; A[6] x A[3] + mulx rcx, rax, QWORD PTR [r9+48] + adcx rdi, rax + adox rsi, rcx + ; No store %r14 + ; No load %rbx - %r9 + ; A[7] x A[3] + mulx rcx, rax, QWORD PTR [r9+56] + adcx rsi, rax + adox rbx, rcx + ; No store %r15 + mov r10, QWORD PTR [r8] + ; A[8] x A[3] + mulx rcx, rax, QWORD PTR [r9+64] + adcx rbx, rax + adox r10, rcx + ; No store %rbx + mov r11, QWORD PTR [r8+8] + ; A[9] x A[3] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8], r10 + mov r10, QWORD PTR [r8+16] + ; A[9] x A[4] + mov rdx, QWORD PTR [r9+72] + mulx rcx, rax, QWORD PTR [r9+32] + adcx r11, rax + adox r10, rcx + mov QWORD PTR [r8+8], r11 + mov r11, QWORD PTR [r8+24] + ; A[9] x A[5] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+16], r10 + mov r10, QWORD PTR [r8+32] + ; A[9] x A[6] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r11, rax + adox r10, rcx + mov QWORD PTR [r8+24], r11 + mov r11, r12 + ; A[9] x A[7] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+32], r10 + mov r10, r12 + ; A[9] x A[8] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r11, rax + adox r10, rcx + mov QWORD PTR [r8+40], r11 + ; Carry + adcx r10, r13 + mov r13, r12 + adcx r13, r12 + adox r13, r12 + mov QWORD PTR [r8+48], r10 + ; Diagonal 5 + ; No load %r14 - %r8 + ; No load %r15 - %r9 + ; A[5] x A[4] + mov rdx, QWORD PTR [r9+32] + mulx rcx, rax, QWORD PTR [r9+40] + adcx rdi, rax + adox rsi, rcx + ; No store %r14 + ; No load %rbx - %r8 + ; A[6] x A[4] + mulx rcx, rax, QWORD PTR [r9+48] + adcx rsi, rax + adox rbx, rcx + ; No store %r15 + mov r11, QWORD PTR [r8] + ; A[7] x A[4] + mulx rcx, rax, QWORD PTR [r9+56] + adcx rbx, rax + adox r11, rcx + ; No store %rbx + mov r10, QWORD PTR [r8+8] + ; A[8] x A[4] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r11, rax + adox r10, rcx + mov QWORD PTR [r8], r11 + mov r11, QWORD PTR [r8+16] + ; A[8] x A[5] + mov rdx, QWORD PTR [r9+64] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+8], r10 + mov r10, QWORD PTR [r8+24] + ; A[8] x A[6] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r11, rax + adox r10, rcx + mov QWORD PTR [r8+16], r11 + mov r11, QWORD PTR [r8+32] + ; A[8] x A[7] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+24], r10 + mov r10, QWORD PTR [r8+40] + ; A[10] x A[6] + mov rdx, QWORD PTR [r9+80] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r11, rax + adox r10, rcx + mov QWORD PTR [r8+32], r11 + mov r11, QWORD PTR [r8+48] + ; A[10] x A[7] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+40], r10 + mov r10, r12 + ; A[10] x A[8] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r11, rax + adox r10, rcx + mov QWORD PTR [r8+48], r11 + mov r11, r12 + ; A[10] x A[9] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+56], r10 + ; Carry + adcx r11, r13 + mov r13, r12 + adcx r13, r12 + adox r13, r12 + mov QWORD PTR [r8+64], r11 + ; Diagonal 6 + ; No load %rbx - %r9 + mov r10, QWORD PTR [r8] + ; A[6] x A[5] + mov rdx, QWORD PTR [r9+40] + mulx rcx, rax, QWORD PTR [r9+48] + adcx rbx, rax + adox r10, rcx + ; No store %rbx + mov r11, QWORD PTR [r8+8] + ; A[7] x A[5] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8], r10 + mov r10, QWORD PTR [r8+16] + ; A[7] x A[6] + mov rdx, QWORD PTR [r9+48] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r11, rax + adox r10, rcx + mov QWORD PTR [r8+8], r11 + mov r11, QWORD PTR [r8+24] + ; A[11] x A[3] + mov rdx, QWORD PTR [r9+88] + mulx rcx, rax, QWORD PTR [r9+24] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+16], r10 + mov r10, QWORD PTR [r8+32] + ; A[11] x A[4] + mulx rcx, rax, QWORD PTR [r9+32] + adcx r11, rax + adox r10, rcx + mov QWORD PTR [r8+24], r11 + mov r11, QWORD PTR [r8+40] + ; A[11] x A[5] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+32], r10 + mov r10, QWORD PTR [r8+48] + ; A[11] x A[6] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r11, rax + adox r10, rcx + mov QWORD PTR [r8+40], r11 + mov r11, QWORD PTR [r8+56] + ; A[11] x A[7] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+48], r10 + mov r10, QWORD PTR [r8+64] + ; A[11] x A[8] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r11, rax + adox r10, rcx + mov QWORD PTR [r8+56], r11 + mov r11, r12 + ; A[11] x A[9] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+64], r10 + mov r10, r12 + ; A[11] x A[10] + mulx rcx, rax, QWORD PTR [r9+80] + adcx r11, rax + adox r10, rcx + mov QWORD PTR [r8+72], r11 + ; Carry + adcx r10, r13 + mov r13, r12 + adcx r13, r12 + adox r13, r12 + mov QWORD PTR [r8+80], r10 + mov QWORD PTR [r8+88], r13 + ; Double and Add in A[i] x A[i] + mov r11, QWORD PTR [rbp+8] + ; A[0] x A[0] + mov rdx, QWORD PTR [r9] + mulx rcx, rax, rdx + mov QWORD PTR [rbp], rax + adox r11, r11 + adcx r11, rcx + mov QWORD PTR [rbp+8], r11 + mov r10, QWORD PTR [rbp+16] + mov r11, QWORD PTR [rbp+24] + ; A[1] x A[1] + mov rdx, QWORD PTR [r9+8] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [rbp+16], r10 + mov QWORD PTR [rbp+24], r11 + mov r10, QWORD PTR [rbp+32] + mov r11, QWORD PTR [rbp+40] + ; A[2] x A[2] + mov rdx, QWORD PTR [r9+16] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [rbp+32], r10 + mov QWORD PTR [rbp+40], r11 + mov r10, QWORD PTR [rbp+48] + ; A[3] x A[3] + mov rdx, QWORD PTR [r9+24] + mulx rcx, rax, rdx + adox r10, r10 + adox r14, r14 + adcx r10, rax + adcx r14, rcx + mov QWORD PTR [rbp+48], r10 + ; A[4] x A[4] + mov rdx, QWORD PTR [r9+32] + mulx rcx, rax, rdx + adox r15, r15 + adox rdi, rdi + adcx r15, rax + adcx rdi, rcx + ; A[5] x A[5] + mov rdx, QWORD PTR [r9+40] + mulx rcx, rax, rdx + adox rsi, rsi + adox rbx, rbx + adcx rsi, rax + adcx rbx, rcx + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + ; A[6] x A[6] + mov rdx, QWORD PTR [r9+48] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [r8], r10 + mov QWORD PTR [r8+8], r11 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + ; A[7] x A[7] + mov rdx, QWORD PTR [r9+56] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [r8+16], r10 + mov QWORD PTR [r8+24], r11 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + ; A[8] x A[8] + mov rdx, QWORD PTR [r9+64] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [r8+32], r10 + mov QWORD PTR [r8+40], r11 + mov r10, QWORD PTR [r8+48] + mov r11, QWORD PTR [r8+56] + ; A[9] x A[9] + mov rdx, QWORD PTR [r9+72] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [r8+48], r10 + mov QWORD PTR [r8+56], r11 + mov r10, QWORD PTR [r8+64] + mov r11, QWORD PTR [r8+72] + ; A[10] x A[10] + mov rdx, QWORD PTR [r9+80] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [r8+64], r10 + mov QWORD PTR [r8+72], r11 + mov r10, QWORD PTR [r8+80] + mov r11, QWORD PTR [r8+88] + ; A[11] x A[11] + mov rdx, QWORD PTR [r9+88] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [r8+80], r10 + mov QWORD PTR [r8+88], r11 + mov QWORD PTR [r8+-40], r14 + mov QWORD PTR [r8+-32], r15 + mov QWORD PTR [r8+-24], rdi + mov QWORD PTR [r8+-16], rsi + mov QWORD PTR [r8+-8], rbx + sub r8, 96 + cmp r9, r8 + jne L_end_3072_sqr_avx2_12 + vmovdqu xmm0, OWORD PTR [rbp] + vmovups OWORD PTR [r8], xmm0 + vmovdqu xmm0, OWORD PTR [rbp+16] + vmovups OWORD PTR [r8+16], xmm0 + vmovdqu xmm0, OWORD PTR [rbp+32] + vmovups OWORD PTR [r8+32], xmm0 + mov rax, QWORD PTR [rbp+48] + mov QWORD PTR [r8+48], rax +L_end_3072_sqr_avx2_12: + add rsp, 96 + pop rbx + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + pop rbp + ret +sp_3072_sqr_avx2_12 ENDP +_text ENDS +ENDIF +; /* Add b to a into r. (r = a + b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_3072_add_12 PROC + ; Add + mov r9, QWORD PTR [rdx] + xor rax, rax + add r9, QWORD PTR [r8] + mov r10, QWORD PTR [rdx+8] + mov QWORD PTR [rcx], r9 + adc r10, QWORD PTR [r8+8] + mov r9, QWORD PTR [rdx+16] + mov QWORD PTR [rcx+8], r10 + adc r9, QWORD PTR [r8+16] + mov r10, QWORD PTR [rdx+24] + mov QWORD PTR [rcx+16], r9 + adc r10, QWORD PTR [r8+24] + mov r9, QWORD PTR [rdx+32] + mov QWORD PTR [rcx+24], r10 + adc r9, QWORD PTR [r8+32] + mov r10, QWORD PTR [rdx+40] + mov QWORD PTR [rcx+32], r9 + adc r10, QWORD PTR [r8+40] + mov r9, QWORD PTR [rdx+48] + mov QWORD PTR [rcx+40], r10 + adc r9, QWORD PTR [r8+48] + mov r10, QWORD PTR [rdx+56] + mov QWORD PTR [rcx+48], r9 + adc r10, QWORD PTR [r8+56] + mov r9, QWORD PTR [rdx+64] + mov QWORD PTR [rcx+56], r10 + adc r9, QWORD PTR [r8+64] + mov r10, QWORD PTR [rdx+72] + mov QWORD PTR [rcx+64], r9 + adc r10, QWORD PTR [r8+72] + mov r9, QWORD PTR [rdx+80] + mov QWORD PTR [rcx+72], r10 + adc r9, QWORD PTR [r8+80] + mov r10, QWORD PTR [rdx+88] + mov QWORD PTR [rcx+80], r9 + adc r10, QWORD PTR [r8+88] + mov QWORD PTR [rcx+88], r10 + adc rax, 0 + ret +sp_3072_add_12 ENDP +_text ENDS +; /* Sub b from a into a. (a -= b) +; * +; * a A single precision integer and result. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_3072_sub_in_place_24 PROC + mov r8, QWORD PTR [rcx] + xor rax, rax + sub r8, QWORD PTR [rdx] + mov r9, QWORD PTR [rcx+8] + mov QWORD PTR [rcx], r8 + sbb r9, QWORD PTR [rdx+8] + mov r8, QWORD PTR [rcx+16] + mov QWORD PTR [rcx+8], r9 + sbb r8, QWORD PTR [rdx+16] + mov r9, QWORD PTR [rcx+24] + mov QWORD PTR [rcx+16], r8 + sbb r9, QWORD PTR [rdx+24] + mov r8, QWORD PTR [rcx+32] + mov QWORD PTR [rcx+24], r9 + sbb r8, QWORD PTR [rdx+32] + mov r9, QWORD PTR [rcx+40] + mov QWORD PTR [rcx+32], r8 + sbb r9, QWORD PTR [rdx+40] + mov r8, QWORD PTR [rcx+48] + mov QWORD PTR [rcx+40], r9 + sbb r8, QWORD PTR [rdx+48] + mov r9, QWORD PTR [rcx+56] + mov QWORD PTR [rcx+48], r8 + sbb r9, QWORD PTR [rdx+56] + mov r8, QWORD PTR [rcx+64] + mov QWORD PTR [rcx+56], r9 + sbb r8, QWORD PTR [rdx+64] + mov r9, QWORD PTR [rcx+72] + mov QWORD PTR [rcx+64], r8 + sbb r9, QWORD PTR [rdx+72] + mov r8, QWORD PTR [rcx+80] + mov QWORD PTR [rcx+72], r9 + sbb r8, QWORD PTR [rdx+80] + mov r9, QWORD PTR [rcx+88] + mov QWORD PTR [rcx+80], r8 + sbb r9, QWORD PTR [rdx+88] + mov r8, QWORD PTR [rcx+96] + mov QWORD PTR [rcx+88], r9 + sbb r8, QWORD PTR [rdx+96] + mov r9, QWORD PTR [rcx+104] + mov QWORD PTR [rcx+96], r8 + sbb r9, QWORD PTR [rdx+104] + mov r8, QWORD PTR [rcx+112] + mov QWORD PTR [rcx+104], r9 + sbb r8, QWORD PTR [rdx+112] + mov r9, QWORD PTR [rcx+120] + mov QWORD PTR [rcx+112], r8 + sbb r9, QWORD PTR [rdx+120] + mov r8, QWORD PTR [rcx+128] + mov QWORD PTR [rcx+120], r9 + sbb r8, QWORD PTR [rdx+128] + mov r9, QWORD PTR [rcx+136] + mov QWORD PTR [rcx+128], r8 + sbb r9, QWORD PTR [rdx+136] + mov r8, QWORD PTR [rcx+144] + mov QWORD PTR [rcx+136], r9 + sbb r8, QWORD PTR [rdx+144] + mov r9, QWORD PTR [rcx+152] + mov QWORD PTR [rcx+144], r8 + sbb r9, QWORD PTR [rdx+152] + mov r8, QWORD PTR [rcx+160] + mov QWORD PTR [rcx+152], r9 + sbb r8, QWORD PTR [rdx+160] + mov r9, QWORD PTR [rcx+168] + mov QWORD PTR [rcx+160], r8 + sbb r9, QWORD PTR [rdx+168] + mov r8, QWORD PTR [rcx+176] + mov QWORD PTR [rcx+168], r9 + sbb r8, QWORD PTR [rdx+176] + mov r9, QWORD PTR [rcx+184] + mov QWORD PTR [rcx+176], r8 + sbb r9, QWORD PTR [rdx+184] + mov QWORD PTR [rcx+184], r9 + sbb rax, 0 + ret +sp_3072_sub_in_place_24 ENDP +_text ENDS +; /* Add b to a into r. (r = a + b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_3072_add_24 PROC + ; Add + mov r9, QWORD PTR [rdx] + xor rax, rax + add r9, QWORD PTR [r8] + mov r10, QWORD PTR [rdx+8] + mov QWORD PTR [rcx], r9 + adc r10, QWORD PTR [r8+8] + mov r9, QWORD PTR [rdx+16] + mov QWORD PTR [rcx+8], r10 + adc r9, QWORD PTR [r8+16] + mov r10, QWORD PTR [rdx+24] + mov QWORD PTR [rcx+16], r9 + adc r10, QWORD PTR [r8+24] + mov r9, QWORD PTR [rdx+32] + mov QWORD PTR [rcx+24], r10 + adc r9, QWORD PTR [r8+32] + mov r10, QWORD PTR [rdx+40] + mov QWORD PTR [rcx+32], r9 + adc r10, QWORD PTR [r8+40] + mov r9, QWORD PTR [rdx+48] + mov QWORD PTR [rcx+40], r10 + adc r9, QWORD PTR [r8+48] + mov r10, QWORD PTR [rdx+56] + mov QWORD PTR [rcx+48], r9 + adc r10, QWORD PTR [r8+56] + mov r9, QWORD PTR [rdx+64] + mov QWORD PTR [rcx+56], r10 + adc r9, QWORD PTR [r8+64] + mov r10, QWORD PTR [rdx+72] + mov QWORD PTR [rcx+64], r9 + adc r10, QWORD PTR [r8+72] + mov r9, QWORD PTR [rdx+80] + mov QWORD PTR [rcx+72], r10 + adc r9, QWORD PTR [r8+80] + mov r10, QWORD PTR [rdx+88] + mov QWORD PTR [rcx+80], r9 + adc r10, QWORD PTR [r8+88] + mov r9, QWORD PTR [rdx+96] + mov QWORD PTR [rcx+88], r10 + adc r9, QWORD PTR [r8+96] + mov r10, QWORD PTR [rdx+104] + mov QWORD PTR [rcx+96], r9 + adc r10, QWORD PTR [r8+104] + mov r9, QWORD PTR [rdx+112] + mov QWORD PTR [rcx+104], r10 + adc r9, QWORD PTR [r8+112] + mov r10, QWORD PTR [rdx+120] + mov QWORD PTR [rcx+112], r9 + adc r10, QWORD PTR [r8+120] + mov r9, QWORD PTR [rdx+128] + mov QWORD PTR [rcx+120], r10 + adc r9, QWORD PTR [r8+128] + mov r10, QWORD PTR [rdx+136] + mov QWORD PTR [rcx+128], r9 + adc r10, QWORD PTR [r8+136] + mov r9, QWORD PTR [rdx+144] + mov QWORD PTR [rcx+136], r10 + adc r9, QWORD PTR [r8+144] + mov r10, QWORD PTR [rdx+152] + mov QWORD PTR [rcx+144], r9 + adc r10, QWORD PTR [r8+152] + mov r9, QWORD PTR [rdx+160] + mov QWORD PTR [rcx+152], r10 + adc r9, QWORD PTR [r8+160] + mov r10, QWORD PTR [rdx+168] + mov QWORD PTR [rcx+160], r9 + adc r10, QWORD PTR [r8+168] + mov r9, QWORD PTR [rdx+176] + mov QWORD PTR [rcx+168], r10 + adc r9, QWORD PTR [r8+176] + mov r10, QWORD PTR [rdx+184] + mov QWORD PTR [rcx+176], r9 + adc r10, QWORD PTR [r8+184] + mov QWORD PTR [rcx+184], r10 + adc rax, 0 + ret +sp_3072_add_24 ENDP +_text ENDS +; /* Multiply a and b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_3072_mul_24 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + sub rsp, 616 + mov QWORD PTR [rsp+576], rcx + mov QWORD PTR [rsp+584], rdx + mov QWORD PTR [rsp+592], r8 + lea r12, QWORD PTR [rsp+384] + lea r14, QWORD PTR [rdx+96] + ; Add + mov rax, QWORD PTR [rdx] + xor r15, r15 + add rax, QWORD PTR [r14] + mov r9, QWORD PTR [rdx+8] + mov QWORD PTR [r12], rax + adc r9, QWORD PTR [r14+8] + mov r10, QWORD PTR [rdx+16] + mov QWORD PTR [r12+8], r9 + adc r10, QWORD PTR [r14+16] + mov rax, QWORD PTR [rdx+24] + mov QWORD PTR [r12+16], r10 + adc rax, QWORD PTR [r14+24] + mov r9, QWORD PTR [rdx+32] + mov QWORD PTR [r12+24], rax + adc r9, QWORD PTR [r14+32] + mov r10, QWORD PTR [rdx+40] + mov QWORD PTR [r12+32], r9 + adc r10, QWORD PTR [r14+40] + mov rax, QWORD PTR [rdx+48] + mov QWORD PTR [r12+40], r10 + adc rax, QWORD PTR [r14+48] + mov r9, QWORD PTR [rdx+56] + mov QWORD PTR [r12+48], rax + adc r9, QWORD PTR [r14+56] + mov r10, QWORD PTR [rdx+64] + mov QWORD PTR [r12+56], r9 + adc r10, QWORD PTR [r14+64] + mov rax, QWORD PTR [rdx+72] + mov QWORD PTR [r12+64], r10 + adc rax, QWORD PTR [r14+72] + mov r9, QWORD PTR [rdx+80] + mov QWORD PTR [r12+72], rax + adc r9, QWORD PTR [r14+80] + mov r10, QWORD PTR [rdx+88] + mov QWORD PTR [r12+80], r9 + adc r10, QWORD PTR [r14+88] + mov QWORD PTR [r12+88], r10 + adc r15, 0 + mov QWORD PTR [rsp+600], r15 + lea r13, QWORD PTR [rsp+480] + lea r14, QWORD PTR [r8+96] + ; Add + mov rax, QWORD PTR [r8] + xor rdi, rdi + add rax, QWORD PTR [r14] + mov r9, QWORD PTR [r8+8] + mov QWORD PTR [r13], rax + adc r9, QWORD PTR [r14+8] + mov r10, QWORD PTR [r8+16] + mov QWORD PTR [r13+8], r9 + adc r10, QWORD PTR [r14+16] + mov rax, QWORD PTR [r8+24] + mov QWORD PTR [r13+16], r10 + adc rax, QWORD PTR [r14+24] + mov r9, QWORD PTR [r8+32] + mov QWORD PTR [r13+24], rax + adc r9, QWORD PTR [r14+32] + mov r10, QWORD PTR [r8+40] + mov QWORD PTR [r13+32], r9 + adc r10, QWORD PTR [r14+40] + mov rax, QWORD PTR [r8+48] + mov QWORD PTR [r13+40], r10 + adc rax, QWORD PTR [r14+48] + mov r9, QWORD PTR [r8+56] + mov QWORD PTR [r13+48], rax + adc r9, QWORD PTR [r14+56] + mov r10, QWORD PTR [r8+64] + mov QWORD PTR [r13+56], r9 + adc r10, QWORD PTR [r14+64] + mov rax, QWORD PTR [r8+72] + mov QWORD PTR [r13+64], r10 + adc rax, QWORD PTR [r14+72] + mov r9, QWORD PTR [r8+80] + mov QWORD PTR [r13+72], rax + adc r9, QWORD PTR [r14+80] + mov r10, QWORD PTR [r8+88] + mov QWORD PTR [r13+80], r9 + adc r10, QWORD PTR [r14+88] + mov QWORD PTR [r13+88], r10 + adc rdi, 0 + mov QWORD PTR [rsp+608], rdi + mov r8, r13 + mov rdx, r12 + mov rcx, rsp + call sp_3072_mul_12 + mov r8, QWORD PTR [rsp+592] + mov rdx, QWORD PTR [rsp+584] + lea rcx, QWORD PTR [rsp+192] + add r8, 96 + add rdx, 96 + call sp_3072_mul_12 + mov r8, QWORD PTR [rsp+592] + mov rdx, QWORD PTR [rsp+584] + mov rcx, QWORD PTR [rsp+576] + call sp_3072_mul_12 +IFDEF _WIN64 + mov r8, QWORD PTR [rsp+592] + mov rdx, QWORD PTR [rsp+584] + mov rcx, QWORD PTR [rsp+576] +ENDIF + mov r15, QWORD PTR [rsp+600] + mov rdi, QWORD PTR [rsp+608] + mov rsi, QWORD PTR [rsp+576] + mov r11, r15 + lea r12, QWORD PTR [rsp+384] + lea r13, QWORD PTR [rsp+480] + and r11, rdi + neg r15 + neg rdi + add rsi, 192 + mov rax, QWORD PTR [r12] + mov r9, QWORD PTR [r13] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12], rax + mov QWORD PTR [r13], r9 + mov rax, QWORD PTR [r12+8] + mov r9, QWORD PTR [r13+8] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+8], rax + mov QWORD PTR [r13+8], r9 + mov rax, QWORD PTR [r12+16] + mov r9, QWORD PTR [r13+16] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+16], rax + mov QWORD PTR [r13+16], r9 + mov rax, QWORD PTR [r12+24] + mov r9, QWORD PTR [r13+24] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+24], rax + mov QWORD PTR [r13+24], r9 + mov rax, QWORD PTR [r12+32] + mov r9, QWORD PTR [r13+32] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+32], rax + mov QWORD PTR [r13+32], r9 + mov rax, QWORD PTR [r12+40] + mov r9, QWORD PTR [r13+40] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+40], rax + mov QWORD PTR [r13+40], r9 + mov rax, QWORD PTR [r12+48] + mov r9, QWORD PTR [r13+48] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+48], rax + mov QWORD PTR [r13+48], r9 + mov rax, QWORD PTR [r12+56] + mov r9, QWORD PTR [r13+56] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+56], rax + mov QWORD PTR [r13+56], r9 + mov rax, QWORD PTR [r12+64] + mov r9, QWORD PTR [r13+64] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+64], rax + mov QWORD PTR [r13+64], r9 + mov rax, QWORD PTR [r12+72] + mov r9, QWORD PTR [r13+72] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+72], rax + mov QWORD PTR [r13+72], r9 + mov rax, QWORD PTR [r12+80] + mov r9, QWORD PTR [r13+80] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+80], rax + mov QWORD PTR [r13+80], r9 + mov rax, QWORD PTR [r12+88] + mov r9, QWORD PTR [r13+88] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+88], rax + mov QWORD PTR [r13+88], r9 + mov rax, QWORD PTR [r12] + add rax, QWORD PTR [r13] + mov r9, QWORD PTR [r12+8] + mov QWORD PTR [rsi], rax + adc r9, QWORD PTR [r13+8] + mov r10, QWORD PTR [r12+16] + mov QWORD PTR [rsi+8], r9 + adc r10, QWORD PTR [r13+16] + mov rax, QWORD PTR [r12+24] + mov QWORD PTR [rsi+16], r10 + adc rax, QWORD PTR [r13+24] + mov r9, QWORD PTR [r12+32] + mov QWORD PTR [rsi+24], rax + adc r9, QWORD PTR [r13+32] + mov r10, QWORD PTR [r12+40] + mov QWORD PTR [rsi+32], r9 + adc r10, QWORD PTR [r13+40] + mov rax, QWORD PTR [r12+48] + mov QWORD PTR [rsi+40], r10 + adc rax, QWORD PTR [r13+48] + mov r9, QWORD PTR [r12+56] + mov QWORD PTR [rsi+48], rax + adc r9, QWORD PTR [r13+56] + mov r10, QWORD PTR [r12+64] + mov QWORD PTR [rsi+56], r9 + adc r10, QWORD PTR [r13+64] + mov rax, QWORD PTR [r12+72] + mov QWORD PTR [rsi+64], r10 + adc rax, QWORD PTR [r13+72] + mov r9, QWORD PTR [r12+80] + mov QWORD PTR [rsi+72], rax + adc r9, QWORD PTR [r13+80] + mov r10, QWORD PTR [r12+88] + mov QWORD PTR [rsi+80], r9 + adc r10, QWORD PTR [r13+88] + mov QWORD PTR [rsi+88], r10 + adc r11, 0 + lea r13, QWORD PTR [rsp+192] + mov r12, rsp + mov rax, QWORD PTR [r12] + sub rax, QWORD PTR [r13] + mov r9, QWORD PTR [r12+8] + mov QWORD PTR [r12], rax + sbb r9, QWORD PTR [r13+8] + mov r10, QWORD PTR [r12+16] + mov QWORD PTR [r12+8], r9 + sbb r10, QWORD PTR [r13+16] + mov rax, QWORD PTR [r12+24] + mov QWORD PTR [r12+16], r10 + sbb rax, QWORD PTR [r13+24] + mov r9, QWORD PTR [r12+32] + mov QWORD PTR [r12+24], rax + sbb r9, QWORD PTR [r13+32] + mov r10, QWORD PTR [r12+40] + mov QWORD PTR [r12+32], r9 + sbb r10, QWORD PTR [r13+40] + mov rax, QWORD PTR [r12+48] + mov QWORD PTR [r12+40], r10 + sbb rax, QWORD PTR [r13+48] + mov r9, QWORD PTR [r12+56] + mov QWORD PTR [r12+48], rax + sbb r9, QWORD PTR [r13+56] + mov r10, QWORD PTR [r12+64] + mov QWORD PTR [r12+56], r9 + sbb r10, QWORD PTR [r13+64] + mov rax, QWORD PTR [r12+72] + mov QWORD PTR [r12+64], r10 + sbb rax, QWORD PTR [r13+72] + mov r9, QWORD PTR [r12+80] + mov QWORD PTR [r12+72], rax + sbb r9, QWORD PTR [r13+80] + mov r10, QWORD PTR [r12+88] + mov QWORD PTR [r12+80], r9 + sbb r10, QWORD PTR [r13+88] + mov rax, QWORD PTR [r12+96] + mov QWORD PTR [r12+88], r10 + sbb rax, QWORD PTR [r13+96] + mov r9, QWORD PTR [r12+104] + mov QWORD PTR [r12+96], rax + sbb r9, QWORD PTR [r13+104] + mov r10, QWORD PTR [r12+112] + mov QWORD PTR [r12+104], r9 + sbb r10, QWORD PTR [r13+112] + mov rax, QWORD PTR [r12+120] + mov QWORD PTR [r12+112], r10 + sbb rax, QWORD PTR [r13+120] + mov r9, QWORD PTR [r12+128] + mov QWORD PTR [r12+120], rax + sbb r9, QWORD PTR [r13+128] + mov r10, QWORD PTR [r12+136] + mov QWORD PTR [r12+128], r9 + sbb r10, QWORD PTR [r13+136] + mov rax, QWORD PTR [r12+144] + mov QWORD PTR [r12+136], r10 + sbb rax, QWORD PTR [r13+144] + mov r9, QWORD PTR [r12+152] + mov QWORD PTR [r12+144], rax + sbb r9, QWORD PTR [r13+152] + mov r10, QWORD PTR [r12+160] + mov QWORD PTR [r12+152], r9 + sbb r10, QWORD PTR [r13+160] + mov rax, QWORD PTR [r12+168] + mov QWORD PTR [r12+160], r10 + sbb rax, QWORD PTR [r13+168] + mov r9, QWORD PTR [r12+176] + mov QWORD PTR [r12+168], rax + sbb r9, QWORD PTR [r13+176] + mov r10, QWORD PTR [r12+184] + mov QWORD PTR [r12+176], r9 + sbb r10, QWORD PTR [r13+184] + mov QWORD PTR [r12+184], r10 + sbb r11, 0 + mov rax, QWORD PTR [r12] + sub rax, QWORD PTR [rcx] + mov r9, QWORD PTR [r12+8] + mov QWORD PTR [r12], rax + sbb r9, QWORD PTR [rcx+8] + mov r10, QWORD PTR [r12+16] + mov QWORD PTR [r12+8], r9 + sbb r10, QWORD PTR [rcx+16] + mov rax, QWORD PTR [r12+24] + mov QWORD PTR [r12+16], r10 + sbb rax, QWORD PTR [rcx+24] + mov r9, QWORD PTR [r12+32] + mov QWORD PTR [r12+24], rax + sbb r9, QWORD PTR [rcx+32] + mov r10, QWORD PTR [r12+40] + mov QWORD PTR [r12+32], r9 + sbb r10, QWORD PTR [rcx+40] + mov rax, QWORD PTR [r12+48] + mov QWORD PTR [r12+40], r10 + sbb rax, QWORD PTR [rcx+48] + mov r9, QWORD PTR [r12+56] + mov QWORD PTR [r12+48], rax + sbb r9, QWORD PTR [rcx+56] + mov r10, QWORD PTR [r12+64] + mov QWORD PTR [r12+56], r9 + sbb r10, QWORD PTR [rcx+64] + mov rax, QWORD PTR [r12+72] + mov QWORD PTR [r12+64], r10 + sbb rax, QWORD PTR [rcx+72] + mov r9, QWORD PTR [r12+80] + mov QWORD PTR [r12+72], rax + sbb r9, QWORD PTR [rcx+80] + mov r10, QWORD PTR [r12+88] + mov QWORD PTR [r12+80], r9 + sbb r10, QWORD PTR [rcx+88] + mov rax, QWORD PTR [r12+96] + mov QWORD PTR [r12+88], r10 + sbb rax, QWORD PTR [rcx+96] + mov r9, QWORD PTR [r12+104] + mov QWORD PTR [r12+96], rax + sbb r9, QWORD PTR [rcx+104] + mov r10, QWORD PTR [r12+112] + mov QWORD PTR [r12+104], r9 + sbb r10, QWORD PTR [rcx+112] + mov rax, QWORD PTR [r12+120] + mov QWORD PTR [r12+112], r10 + sbb rax, QWORD PTR [rcx+120] + mov r9, QWORD PTR [r12+128] + mov QWORD PTR [r12+120], rax + sbb r9, QWORD PTR [rcx+128] + mov r10, QWORD PTR [r12+136] + mov QWORD PTR [r12+128], r9 + sbb r10, QWORD PTR [rcx+136] + mov rax, QWORD PTR [r12+144] + mov QWORD PTR [r12+136], r10 + sbb rax, QWORD PTR [rcx+144] + mov r9, QWORD PTR [r12+152] + mov QWORD PTR [r12+144], rax + sbb r9, QWORD PTR [rcx+152] + mov r10, QWORD PTR [r12+160] + mov QWORD PTR [r12+152], r9 + sbb r10, QWORD PTR [rcx+160] + mov rax, QWORD PTR [r12+168] + mov QWORD PTR [r12+160], r10 + sbb rax, QWORD PTR [rcx+168] + mov r9, QWORD PTR [r12+176] + mov QWORD PTR [r12+168], rax + sbb r9, QWORD PTR [rcx+176] + mov r10, QWORD PTR [r12+184] + mov QWORD PTR [r12+176], r9 + sbb r10, QWORD PTR [rcx+184] + mov QWORD PTR [r12+184], r10 + sbb r11, 0 + sub rsi, 96 + ; Add + mov rax, QWORD PTR [rsi] + add rax, QWORD PTR [r12] + mov r9, QWORD PTR [rsi+8] + mov QWORD PTR [rsi], rax + adc r9, QWORD PTR [r12+8] + mov r10, QWORD PTR [rsi+16] + mov QWORD PTR [rsi+8], r9 + adc r10, QWORD PTR [r12+16] + mov rax, QWORD PTR [rsi+24] + mov QWORD PTR [rsi+16], r10 + adc rax, QWORD PTR [r12+24] + mov r9, QWORD PTR [rsi+32] + mov QWORD PTR [rsi+24], rax + adc r9, QWORD PTR [r12+32] + mov r10, QWORD PTR [rsi+40] + mov QWORD PTR [rsi+32], r9 + adc r10, QWORD PTR [r12+40] + mov rax, QWORD PTR [rsi+48] + mov QWORD PTR [rsi+40], r10 + adc rax, QWORD PTR [r12+48] + mov r9, QWORD PTR [rsi+56] + mov QWORD PTR [rsi+48], rax + adc r9, QWORD PTR [r12+56] + mov r10, QWORD PTR [rsi+64] + mov QWORD PTR [rsi+56], r9 + adc r10, QWORD PTR [r12+64] + mov rax, QWORD PTR [rsi+72] + mov QWORD PTR [rsi+64], r10 + adc rax, QWORD PTR [r12+72] + mov r9, QWORD PTR [rsi+80] + mov QWORD PTR [rsi+72], rax + adc r9, QWORD PTR [r12+80] + mov r10, QWORD PTR [rsi+88] + mov QWORD PTR [rsi+80], r9 + adc r10, QWORD PTR [r12+88] + mov rax, QWORD PTR [rsi+96] + mov QWORD PTR [rsi+88], r10 + adc rax, QWORD PTR [r12+96] + mov r9, QWORD PTR [rsi+104] + mov QWORD PTR [rsi+96], rax + adc r9, QWORD PTR [r12+104] + mov r10, QWORD PTR [rsi+112] + mov QWORD PTR [rsi+104], r9 + adc r10, QWORD PTR [r12+112] + mov rax, QWORD PTR [rsi+120] + mov QWORD PTR [rsi+112], r10 + adc rax, QWORD PTR [r12+120] + mov r9, QWORD PTR [rsi+128] + mov QWORD PTR [rsi+120], rax + adc r9, QWORD PTR [r12+128] + mov r10, QWORD PTR [rsi+136] + mov QWORD PTR [rsi+128], r9 + adc r10, QWORD PTR [r12+136] + mov rax, QWORD PTR [rsi+144] + mov QWORD PTR [rsi+136], r10 + adc rax, QWORD PTR [r12+144] + mov r9, QWORD PTR [rsi+152] + mov QWORD PTR [rsi+144], rax + adc r9, QWORD PTR [r12+152] + mov r10, QWORD PTR [rsi+160] + mov QWORD PTR [rsi+152], r9 + adc r10, QWORD PTR [r12+160] + mov rax, QWORD PTR [rsi+168] + mov QWORD PTR [rsi+160], r10 + adc rax, QWORD PTR [r12+168] + mov r9, QWORD PTR [rsi+176] + mov QWORD PTR [rsi+168], rax + adc r9, QWORD PTR [r12+176] + mov r10, QWORD PTR [rsi+184] + mov QWORD PTR [rsi+176], r9 + adc r10, QWORD PTR [r12+184] + mov QWORD PTR [rsi+184], r10 + adc r11, 0 + mov QWORD PTR [rcx+288], r11 + add rsi, 96 + ; Add + mov rax, QWORD PTR [rsi] + add rax, QWORD PTR [r13] + mov r9, QWORD PTR [rsi+8] + mov QWORD PTR [rsi], rax + adc r9, QWORD PTR [r13+8] + mov r10, QWORD PTR [rsi+16] + mov QWORD PTR [rsi+8], r9 + adc r10, QWORD PTR [r13+16] + mov rax, QWORD PTR [rsi+24] + mov QWORD PTR [rsi+16], r10 + adc rax, QWORD PTR [r13+24] + mov r9, QWORD PTR [rsi+32] + mov QWORD PTR [rsi+24], rax + adc r9, QWORD PTR [r13+32] + mov r10, QWORD PTR [rsi+40] + mov QWORD PTR [rsi+32], r9 + adc r10, QWORD PTR [r13+40] + mov rax, QWORD PTR [rsi+48] + mov QWORD PTR [rsi+40], r10 + adc rax, QWORD PTR [r13+48] + mov r9, QWORD PTR [rsi+56] + mov QWORD PTR [rsi+48], rax + adc r9, QWORD PTR [r13+56] + mov r10, QWORD PTR [rsi+64] + mov QWORD PTR [rsi+56], r9 + adc r10, QWORD PTR [r13+64] + mov rax, QWORD PTR [rsi+72] + mov QWORD PTR [rsi+64], r10 + adc rax, QWORD PTR [r13+72] + mov r9, QWORD PTR [rsi+80] + mov QWORD PTR [rsi+72], rax + adc r9, QWORD PTR [r13+80] + mov r10, QWORD PTR [rsi+88] + mov QWORD PTR [rsi+80], r9 + adc r10, QWORD PTR [r13+88] + mov rax, QWORD PTR [rsi+96] + mov QWORD PTR [rsi+88], r10 + adc rax, QWORD PTR [r13+96] + mov QWORD PTR [rsi+96], rax + ; Add to zero + mov rax, QWORD PTR [r13+104] + adc rax, 0 + mov r9, QWORD PTR [r13+112] + mov QWORD PTR [rsi+104], rax + adc r9, 0 + mov r10, QWORD PTR [r13+120] + mov QWORD PTR [rsi+112], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+128] + mov QWORD PTR [rsi+120], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+136] + mov QWORD PTR [rsi+128], rax + adc r9, 0 + mov r10, QWORD PTR [r13+144] + mov QWORD PTR [rsi+136], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+152] + mov QWORD PTR [rsi+144], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+160] + mov QWORD PTR [rsi+152], rax + adc r9, 0 + mov r10, QWORD PTR [r13+168] + mov QWORD PTR [rsi+160], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+176] + mov QWORD PTR [rsi+168], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+184] + mov QWORD PTR [rsi+176], rax + adc r9, 0 + mov QWORD PTR [rsi+184], r9 + add rsp, 616 + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_3072_mul_24 ENDP +_text ENDS +; /* Add a to a into r. (r = a + a) +; * +; * r A single precision integer. +; * a A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_3072_dbl_12 PROC + mov r8, QWORD PTR [rdx] + xor rax, rax + add r8, r8 + mov r9, QWORD PTR [rdx+8] + mov QWORD PTR [rcx], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+16] + mov QWORD PTR [rcx+8], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+24] + mov QWORD PTR [rcx+16], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+32] + mov QWORD PTR [rcx+24], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+40] + mov QWORD PTR [rcx+32], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+48] + mov QWORD PTR [rcx+40], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+56] + mov QWORD PTR [rcx+48], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+64] + mov QWORD PTR [rcx+56], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+72] + mov QWORD PTR [rcx+64], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+80] + mov QWORD PTR [rcx+72], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+88] + mov QWORD PTR [rcx+80], r8 + adc r9, r9 + mov QWORD PTR [rcx+88], r9 + adc rax, 0 + ret +sp_3072_dbl_12 ENDP +_text ENDS +; /* Square a and put result in r. (r = a * a) +; * +; * r A single precision integer. +; * a A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_3072_sqr_24 PROC + push r12 + sub rsp, 504 + mov QWORD PTR [rsp+480], rcx + mov QWORD PTR [rsp+488], rdx + lea r10, QWORD PTR [rsp+384] + lea r11, QWORD PTR [rdx+96] + ; Add + mov rax, QWORD PTR [rdx] + xor r9, r9 + add rax, QWORD PTR [r11] + mov r8, QWORD PTR [rdx+8] + mov QWORD PTR [r10], rax + adc r8, QWORD PTR [r11+8] + mov rax, QWORD PTR [rdx+16] + mov QWORD PTR [r10+8], r8 + adc rax, QWORD PTR [r11+16] + mov r8, QWORD PTR [rdx+24] + mov QWORD PTR [r10+16], rax + adc r8, QWORD PTR [r11+24] + mov rax, QWORD PTR [rdx+32] + mov QWORD PTR [r10+24], r8 + adc rax, QWORD PTR [r11+32] + mov r8, QWORD PTR [rdx+40] + mov QWORD PTR [r10+32], rax + adc r8, QWORD PTR [r11+40] + mov rax, QWORD PTR [rdx+48] + mov QWORD PTR [r10+40], r8 + adc rax, QWORD PTR [r11+48] + mov r8, QWORD PTR [rdx+56] + mov QWORD PTR [r10+48], rax + adc r8, QWORD PTR [r11+56] + mov rax, QWORD PTR [rdx+64] + mov QWORD PTR [r10+56], r8 + adc rax, QWORD PTR [r11+64] + mov r8, QWORD PTR [rdx+72] + mov QWORD PTR [r10+64], rax + adc r8, QWORD PTR [r11+72] + mov rax, QWORD PTR [rdx+80] + mov QWORD PTR [r10+72], r8 + adc rax, QWORD PTR [r11+80] + mov r8, QWORD PTR [rdx+88] + mov QWORD PTR [r10+80], rax + adc r8, QWORD PTR [r11+88] + mov QWORD PTR [r10+88], r8 + adc r9, 0 + mov QWORD PTR [rsp+496], r9 + mov rdx, r10 + mov rcx, rsp + call sp_3072_sqr_12 + mov rdx, QWORD PTR [rsp+488] + lea rcx, QWORD PTR [rsp+192] + add rdx, 96 + call sp_3072_sqr_12 + mov rdx, QWORD PTR [rsp+488] + mov rcx, QWORD PTR [rsp+480] + call sp_3072_sqr_12 +IFDEF _WIN64 + mov rdx, QWORD PTR [rsp+488] + mov rcx, QWORD PTR [rsp+480] +ENDIF + mov r12, QWORD PTR [rsp+496] + mov r11, rcx + lea r10, QWORD PTR [rsp+384] + mov r9, r12 + neg r12 + add r11, 192 + mov rax, QWORD PTR [r10] + mov r8, QWORD PTR [r10+8] + and rax, r12 + and r8, r12 + mov QWORD PTR [r11], rax + mov QWORD PTR [r11+8], r8 + mov rax, QWORD PTR [r10+16] + mov r8, QWORD PTR [r10+24] + and rax, r12 + and r8, r12 + mov QWORD PTR [r11+16], rax + mov QWORD PTR [r11+24], r8 + mov rax, QWORD PTR [r10+32] + mov r8, QWORD PTR [r10+40] + and rax, r12 + and r8, r12 + mov QWORD PTR [r11+32], rax + mov QWORD PTR [r11+40], r8 + mov rax, QWORD PTR [r10+48] + mov r8, QWORD PTR [r10+56] + and rax, r12 + and r8, r12 + mov QWORD PTR [r11+48], rax + mov QWORD PTR [r11+56], r8 + mov rax, QWORD PTR [r10+64] + mov r8, QWORD PTR [r10+72] + and rax, r12 + and r8, r12 + mov QWORD PTR [r11+64], rax + mov QWORD PTR [r11+72], r8 + mov rax, QWORD PTR [r10+80] + mov r8, QWORD PTR [r10+88] + and rax, r12 + and r8, r12 + mov QWORD PTR [r11+80], rax + mov QWORD PTR [r11+88], r8 + mov rax, QWORD PTR [r11] + add rax, rax + mov r8, QWORD PTR [r11+8] + mov QWORD PTR [r11], rax + adc r8, r8 + mov rax, QWORD PTR [r11+16] + mov QWORD PTR [r11+8], r8 + adc rax, rax + mov r8, QWORD PTR [r11+24] + mov QWORD PTR [r11+16], rax + adc r8, r8 + mov rax, QWORD PTR [r11+32] + mov QWORD PTR [r11+24], r8 + adc rax, rax + mov r8, QWORD PTR [r11+40] + mov QWORD PTR [r11+32], rax + adc r8, r8 + mov rax, QWORD PTR [r11+48] + mov QWORD PTR [r11+40], r8 + adc rax, rax + mov r8, QWORD PTR [r11+56] + mov QWORD PTR [r11+48], rax + adc r8, r8 + mov rax, QWORD PTR [r11+64] + mov QWORD PTR [r11+56], r8 + adc rax, rax + mov r8, QWORD PTR [r11+72] + mov QWORD PTR [r11+64], rax + adc r8, r8 + mov rax, QWORD PTR [r11+80] + mov QWORD PTR [r11+72], r8 + adc rax, rax + mov r8, QWORD PTR [r11+88] + mov QWORD PTR [r11+80], rax + adc r8, r8 + mov QWORD PTR [r11+88], r8 + adc r9, 0 + lea rdx, QWORD PTR [rsp+192] + mov r10, rsp + mov rax, QWORD PTR [r10] + sub rax, QWORD PTR [rdx] + mov r8, QWORD PTR [r10+8] + mov QWORD PTR [r10], rax + sbb r8, QWORD PTR [rdx+8] + mov rax, QWORD PTR [r10+16] + mov QWORD PTR [r10+8], r8 + sbb rax, QWORD PTR [rdx+16] + mov r8, QWORD PTR [r10+24] + mov QWORD PTR [r10+16], rax + sbb r8, QWORD PTR [rdx+24] + mov rax, QWORD PTR [r10+32] + mov QWORD PTR [r10+24], r8 + sbb rax, QWORD PTR [rdx+32] + mov r8, QWORD PTR [r10+40] + mov QWORD PTR [r10+32], rax + sbb r8, QWORD PTR [rdx+40] + mov rax, QWORD PTR [r10+48] + mov QWORD PTR [r10+40], r8 + sbb rax, QWORD PTR [rdx+48] + mov r8, QWORD PTR [r10+56] + mov QWORD PTR [r10+48], rax + sbb r8, QWORD PTR [rdx+56] + mov rax, QWORD PTR [r10+64] + mov QWORD PTR [r10+56], r8 + sbb rax, QWORD PTR [rdx+64] + mov r8, QWORD PTR [r10+72] + mov QWORD PTR [r10+64], rax + sbb r8, QWORD PTR [rdx+72] + mov rax, QWORD PTR [r10+80] + mov QWORD PTR [r10+72], r8 + sbb rax, QWORD PTR [rdx+80] + mov r8, QWORD PTR [r10+88] + mov QWORD PTR [r10+80], rax + sbb r8, QWORD PTR [rdx+88] + mov rax, QWORD PTR [r10+96] + mov QWORD PTR [r10+88], r8 + sbb rax, QWORD PTR [rdx+96] + mov r8, QWORD PTR [r10+104] + mov QWORD PTR [r10+96], rax + sbb r8, QWORD PTR [rdx+104] + mov rax, QWORD PTR [r10+112] + mov QWORD PTR [r10+104], r8 + sbb rax, QWORD PTR [rdx+112] + mov r8, QWORD PTR [r10+120] + mov QWORD PTR [r10+112], rax + sbb r8, QWORD PTR [rdx+120] + mov rax, QWORD PTR [r10+128] + mov QWORD PTR [r10+120], r8 + sbb rax, QWORD PTR [rdx+128] + mov r8, QWORD PTR [r10+136] + mov QWORD PTR [r10+128], rax + sbb r8, QWORD PTR [rdx+136] + mov rax, QWORD PTR [r10+144] + mov QWORD PTR [r10+136], r8 + sbb rax, QWORD PTR [rdx+144] + mov r8, QWORD PTR [r10+152] + mov QWORD PTR [r10+144], rax + sbb r8, QWORD PTR [rdx+152] + mov rax, QWORD PTR [r10+160] + mov QWORD PTR [r10+152], r8 + sbb rax, QWORD PTR [rdx+160] + mov r8, QWORD PTR [r10+168] + mov QWORD PTR [r10+160], rax + sbb r8, QWORD PTR [rdx+168] + mov rax, QWORD PTR [r10+176] + mov QWORD PTR [r10+168], r8 + sbb rax, QWORD PTR [rdx+176] + mov r8, QWORD PTR [r10+184] + mov QWORD PTR [r10+176], rax + sbb r8, QWORD PTR [rdx+184] + mov QWORD PTR [r10+184], r8 + sbb r9, 0 + mov rax, QWORD PTR [r10] + sub rax, QWORD PTR [rcx] + mov r8, QWORD PTR [r10+8] + mov QWORD PTR [r10], rax + sbb r8, QWORD PTR [rcx+8] + mov rax, QWORD PTR [r10+16] + mov QWORD PTR [r10+8], r8 + sbb rax, QWORD PTR [rcx+16] + mov r8, QWORD PTR [r10+24] + mov QWORD PTR [r10+16], rax + sbb r8, QWORD PTR [rcx+24] + mov rax, QWORD PTR [r10+32] + mov QWORD PTR [r10+24], r8 + sbb rax, QWORD PTR [rcx+32] + mov r8, QWORD PTR [r10+40] + mov QWORD PTR [r10+32], rax + sbb r8, QWORD PTR [rcx+40] + mov rax, QWORD PTR [r10+48] + mov QWORD PTR [r10+40], r8 + sbb rax, QWORD PTR [rcx+48] + mov r8, QWORD PTR [r10+56] + mov QWORD PTR [r10+48], rax + sbb r8, QWORD PTR [rcx+56] + mov rax, QWORD PTR [r10+64] + mov QWORD PTR [r10+56], r8 + sbb rax, QWORD PTR [rcx+64] + mov r8, QWORD PTR [r10+72] + mov QWORD PTR [r10+64], rax + sbb r8, QWORD PTR [rcx+72] + mov rax, QWORD PTR [r10+80] + mov QWORD PTR [r10+72], r8 + sbb rax, QWORD PTR [rcx+80] + mov r8, QWORD PTR [r10+88] + mov QWORD PTR [r10+80], rax + sbb r8, QWORD PTR [rcx+88] + mov rax, QWORD PTR [r10+96] + mov QWORD PTR [r10+88], r8 + sbb rax, QWORD PTR [rcx+96] + mov r8, QWORD PTR [r10+104] + mov QWORD PTR [r10+96], rax + sbb r8, QWORD PTR [rcx+104] + mov rax, QWORD PTR [r10+112] + mov QWORD PTR [r10+104], r8 + sbb rax, QWORD PTR [rcx+112] + mov r8, QWORD PTR [r10+120] + mov QWORD PTR [r10+112], rax + sbb r8, QWORD PTR [rcx+120] + mov rax, QWORD PTR [r10+128] + mov QWORD PTR [r10+120], r8 + sbb rax, QWORD PTR [rcx+128] + mov r8, QWORD PTR [r10+136] + mov QWORD PTR [r10+128], rax + sbb r8, QWORD PTR [rcx+136] + mov rax, QWORD PTR [r10+144] + mov QWORD PTR [r10+136], r8 + sbb rax, QWORD PTR [rcx+144] + mov r8, QWORD PTR [r10+152] + mov QWORD PTR [r10+144], rax + sbb r8, QWORD PTR [rcx+152] + mov rax, QWORD PTR [r10+160] + mov QWORD PTR [r10+152], r8 + sbb rax, QWORD PTR [rcx+160] + mov r8, QWORD PTR [r10+168] + mov QWORD PTR [r10+160], rax + sbb r8, QWORD PTR [rcx+168] + mov rax, QWORD PTR [r10+176] + mov QWORD PTR [r10+168], r8 + sbb rax, QWORD PTR [rcx+176] + mov r8, QWORD PTR [r10+184] + mov QWORD PTR [r10+176], rax + sbb r8, QWORD PTR [rcx+184] + mov QWORD PTR [r10+184], r8 + sbb r9, 0 + sub r11, 96 + ; Add in place + mov rax, QWORD PTR [r11] + add rax, QWORD PTR [r10] + mov r8, QWORD PTR [r11+8] + mov QWORD PTR [r11], rax + adc r8, QWORD PTR [r10+8] + mov rax, QWORD PTR [r11+16] + mov QWORD PTR [r11+8], r8 + adc rax, QWORD PTR [r10+16] + mov r8, QWORD PTR [r11+24] + mov QWORD PTR [r11+16], rax + adc r8, QWORD PTR [r10+24] + mov rax, QWORD PTR [r11+32] + mov QWORD PTR [r11+24], r8 + adc rax, QWORD PTR [r10+32] + mov r8, QWORD PTR [r11+40] + mov QWORD PTR [r11+32], rax + adc r8, QWORD PTR [r10+40] + mov rax, QWORD PTR [r11+48] + mov QWORD PTR [r11+40], r8 + adc rax, QWORD PTR [r10+48] + mov r8, QWORD PTR [r11+56] + mov QWORD PTR [r11+48], rax + adc r8, QWORD PTR [r10+56] + mov rax, QWORD PTR [r11+64] + mov QWORD PTR [r11+56], r8 + adc rax, QWORD PTR [r10+64] + mov r8, QWORD PTR [r11+72] + mov QWORD PTR [r11+64], rax + adc r8, QWORD PTR [r10+72] + mov rax, QWORD PTR [r11+80] + mov QWORD PTR [r11+72], r8 + adc rax, QWORD PTR [r10+80] + mov r8, QWORD PTR [r11+88] + mov QWORD PTR [r11+80], rax + adc r8, QWORD PTR [r10+88] + mov rax, QWORD PTR [r11+96] + mov QWORD PTR [r11+88], r8 + adc rax, QWORD PTR [r10+96] + mov r8, QWORD PTR [r11+104] + mov QWORD PTR [r11+96], rax + adc r8, QWORD PTR [r10+104] + mov rax, QWORD PTR [r11+112] + mov QWORD PTR [r11+104], r8 + adc rax, QWORD PTR [r10+112] + mov r8, QWORD PTR [r11+120] + mov QWORD PTR [r11+112], rax + adc r8, QWORD PTR [r10+120] + mov rax, QWORD PTR [r11+128] + mov QWORD PTR [r11+120], r8 + adc rax, QWORD PTR [r10+128] + mov r8, QWORD PTR [r11+136] + mov QWORD PTR [r11+128], rax + adc r8, QWORD PTR [r10+136] + mov rax, QWORD PTR [r11+144] + mov QWORD PTR [r11+136], r8 + adc rax, QWORD PTR [r10+144] + mov r8, QWORD PTR [r11+152] + mov QWORD PTR [r11+144], rax + adc r8, QWORD PTR [r10+152] + mov rax, QWORD PTR [r11+160] + mov QWORD PTR [r11+152], r8 + adc rax, QWORD PTR [r10+160] + mov r8, QWORD PTR [r11+168] + mov QWORD PTR [r11+160], rax + adc r8, QWORD PTR [r10+168] + mov rax, QWORD PTR [r11+176] + mov QWORD PTR [r11+168], r8 + adc rax, QWORD PTR [r10+176] + mov r8, QWORD PTR [r11+184] + mov QWORD PTR [r11+176], rax + adc r8, QWORD PTR [r10+184] + mov QWORD PTR [r11+184], r8 + adc r9, 0 + mov QWORD PTR [rcx+288], r9 + ; Add in place + mov rax, QWORD PTR [r11+96] + add rax, QWORD PTR [rdx] + mov r8, QWORD PTR [r11+104] + mov QWORD PTR [r11+96], rax + adc r8, QWORD PTR [rdx+8] + mov rax, QWORD PTR [r11+112] + mov QWORD PTR [r11+104], r8 + adc rax, QWORD PTR [rdx+16] + mov r8, QWORD PTR [r11+120] + mov QWORD PTR [r11+112], rax + adc r8, QWORD PTR [rdx+24] + mov rax, QWORD PTR [r11+128] + mov QWORD PTR [r11+120], r8 + adc rax, QWORD PTR [rdx+32] + mov r8, QWORD PTR [r11+136] + mov QWORD PTR [r11+128], rax + adc r8, QWORD PTR [rdx+40] + mov rax, QWORD PTR [r11+144] + mov QWORD PTR [r11+136], r8 + adc rax, QWORD PTR [rdx+48] + mov r8, QWORD PTR [r11+152] + mov QWORD PTR [r11+144], rax + adc r8, QWORD PTR [rdx+56] + mov rax, QWORD PTR [r11+160] + mov QWORD PTR [r11+152], r8 + adc rax, QWORD PTR [rdx+64] + mov r8, QWORD PTR [r11+168] + mov QWORD PTR [r11+160], rax + adc r8, QWORD PTR [rdx+72] + mov rax, QWORD PTR [r11+176] + mov QWORD PTR [r11+168], r8 + adc rax, QWORD PTR [rdx+80] + mov r8, QWORD PTR [r11+184] + mov QWORD PTR [r11+176], rax + adc r8, QWORD PTR [rdx+88] + mov rax, QWORD PTR [r11+192] + mov QWORD PTR [r11+184], r8 + adc rax, QWORD PTR [rdx+96] + mov QWORD PTR [r11+192], rax + ; Add to zero + mov rax, QWORD PTR [rdx+104] + adc rax, 0 + mov r8, QWORD PTR [rdx+112] + mov QWORD PTR [r11+200], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+120] + mov QWORD PTR [r11+208], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+128] + mov QWORD PTR [r11+216], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+136] + mov QWORD PTR [r11+224], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+144] + mov QWORD PTR [r11+232], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+152] + mov QWORD PTR [r11+240], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+160] + mov QWORD PTR [r11+248], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+168] + mov QWORD PTR [r11+256], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+176] + mov QWORD PTR [r11+264], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+184] + mov QWORD PTR [r11+272], r8 + adc rax, 0 + mov QWORD PTR [r11+280], rax + add rsp, 504 + pop r12 + ret +sp_3072_sqr_24 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Multiply a and b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_3072_mul_avx2_24 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + sub rsp, 616 + mov QWORD PTR [rsp+576], rcx + mov QWORD PTR [rsp+584], rdx + mov QWORD PTR [rsp+592], r8 + lea r12, QWORD PTR [rsp+384] + lea r14, QWORD PTR [rdx+96] + ; Add + mov rax, QWORD PTR [rdx] + xor r15, r15 + add rax, QWORD PTR [r14] + mov r9, QWORD PTR [rdx+8] + mov QWORD PTR [r12], rax + adc r9, QWORD PTR [r14+8] + mov r10, QWORD PTR [rdx+16] + mov QWORD PTR [r12+8], r9 + adc r10, QWORD PTR [r14+16] + mov rax, QWORD PTR [rdx+24] + mov QWORD PTR [r12+16], r10 + adc rax, QWORD PTR [r14+24] + mov r9, QWORD PTR [rdx+32] + mov QWORD PTR [r12+24], rax + adc r9, QWORD PTR [r14+32] + mov r10, QWORD PTR [rdx+40] + mov QWORD PTR [r12+32], r9 + adc r10, QWORD PTR [r14+40] + mov rax, QWORD PTR [rdx+48] + mov QWORD PTR [r12+40], r10 + adc rax, QWORD PTR [r14+48] + mov r9, QWORD PTR [rdx+56] + mov QWORD PTR [r12+48], rax + adc r9, QWORD PTR [r14+56] + mov r10, QWORD PTR [rdx+64] + mov QWORD PTR [r12+56], r9 + adc r10, QWORD PTR [r14+64] + mov rax, QWORD PTR [rdx+72] + mov QWORD PTR [r12+64], r10 + adc rax, QWORD PTR [r14+72] + mov r9, QWORD PTR [rdx+80] + mov QWORD PTR [r12+72], rax + adc r9, QWORD PTR [r14+80] + mov r10, QWORD PTR [rdx+88] + mov QWORD PTR [r12+80], r9 + adc r10, QWORD PTR [r14+88] + mov QWORD PTR [r12+88], r10 + adc r15, 0 + mov QWORD PTR [rsp+600], r15 + lea r13, QWORD PTR [rsp+480] + lea r14, QWORD PTR [r8+96] + ; Add + mov rax, QWORD PTR [r8] + xor rdi, rdi + add rax, QWORD PTR [r14] + mov r9, QWORD PTR [r8+8] + mov QWORD PTR [r13], rax + adc r9, QWORD PTR [r14+8] + mov r10, QWORD PTR [r8+16] + mov QWORD PTR [r13+8], r9 + adc r10, QWORD PTR [r14+16] + mov rax, QWORD PTR [r8+24] + mov QWORD PTR [r13+16], r10 + adc rax, QWORD PTR [r14+24] + mov r9, QWORD PTR [r8+32] + mov QWORD PTR [r13+24], rax + adc r9, QWORD PTR [r14+32] + mov r10, QWORD PTR [r8+40] + mov QWORD PTR [r13+32], r9 + adc r10, QWORD PTR [r14+40] + mov rax, QWORD PTR [r8+48] + mov QWORD PTR [r13+40], r10 + adc rax, QWORD PTR [r14+48] + mov r9, QWORD PTR [r8+56] + mov QWORD PTR [r13+48], rax + adc r9, QWORD PTR [r14+56] + mov r10, QWORD PTR [r8+64] + mov QWORD PTR [r13+56], r9 + adc r10, QWORD PTR [r14+64] + mov rax, QWORD PTR [r8+72] + mov QWORD PTR [r13+64], r10 + adc rax, QWORD PTR [r14+72] + mov r9, QWORD PTR [r8+80] + mov QWORD PTR [r13+72], rax + adc r9, QWORD PTR [r14+80] + mov r10, QWORD PTR [r8+88] + mov QWORD PTR [r13+80], r9 + adc r10, QWORD PTR [r14+88] + mov QWORD PTR [r13+88], r10 + adc rdi, 0 + mov QWORD PTR [rsp+608], rdi + mov r8, r13 + mov rdx, r12 + mov rcx, rsp + call sp_3072_mul_avx2_12 + mov r8, QWORD PTR [rsp+592] + mov rdx, QWORD PTR [rsp+584] + lea rcx, QWORD PTR [rsp+192] + add r8, 96 + add rdx, 96 + call sp_3072_mul_avx2_12 + mov r8, QWORD PTR [rsp+592] + mov rdx, QWORD PTR [rsp+584] + mov rcx, QWORD PTR [rsp+576] + call sp_3072_mul_avx2_12 +IFDEF _WIN64 + mov r8, QWORD PTR [rsp+592] + mov rdx, QWORD PTR [rsp+584] + mov rcx, QWORD PTR [rsp+576] +ENDIF + mov r15, QWORD PTR [rsp+600] + mov rdi, QWORD PTR [rsp+608] + mov rsi, QWORD PTR [rsp+576] + mov r11, r15 + lea r12, QWORD PTR [rsp+384] + lea r13, QWORD PTR [rsp+480] + and r11, rdi + neg r15 + neg rdi + add rsi, 192 + mov rax, QWORD PTR [r12] + mov r9, QWORD PTR [r13] + pext rax, rax, rdi + pext r9, r9, r15 + add rax, r9 + mov r9, QWORD PTR [r12+8] + mov r10, QWORD PTR [r13+8] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi], rax + adc r9, r10 + mov r10, QWORD PTR [r12+16] + mov rax, QWORD PTR [r13+16] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+8], r9 + adc r10, rax + mov rax, QWORD PTR [r12+24] + mov r9, QWORD PTR [r13+24] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+16], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+32] + mov r10, QWORD PTR [r13+32] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+24], rax + adc r9, r10 + mov r10, QWORD PTR [r12+40] + mov rax, QWORD PTR [r13+40] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+32], r9 + adc r10, rax + mov rax, QWORD PTR [r12+48] + mov r9, QWORD PTR [r13+48] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+40], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+56] + mov r10, QWORD PTR [r13+56] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+48], rax + adc r9, r10 + mov r10, QWORD PTR [r12+64] + mov rax, QWORD PTR [r13+64] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+56], r9 + adc r10, rax + mov rax, QWORD PTR [r12+72] + mov r9, QWORD PTR [r13+72] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+64], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+80] + mov r10, QWORD PTR [r13+80] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+72], rax + adc r9, r10 + mov r10, QWORD PTR [r12+88] + mov rax, QWORD PTR [r13+88] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+80], r9 + adc r10, rax + mov QWORD PTR [rsi+88], r10 + adc r11, 0 + lea r13, QWORD PTR [rsp+192] + mov r12, rsp + mov rax, QWORD PTR [r12] + sub rax, QWORD PTR [r13] + mov r9, QWORD PTR [r12+8] + mov QWORD PTR [r12], rax + sbb r9, QWORD PTR [r13+8] + mov r10, QWORD PTR [r12+16] + mov QWORD PTR [r12+8], r9 + sbb r10, QWORD PTR [r13+16] + mov rax, QWORD PTR [r12+24] + mov QWORD PTR [r12+16], r10 + sbb rax, QWORD PTR [r13+24] + mov r9, QWORD PTR [r12+32] + mov QWORD PTR [r12+24], rax + sbb r9, QWORD PTR [r13+32] + mov r10, QWORD PTR [r12+40] + mov QWORD PTR [r12+32], r9 + sbb r10, QWORD PTR [r13+40] + mov rax, QWORD PTR [r12+48] + mov QWORD PTR [r12+40], r10 + sbb rax, QWORD PTR [r13+48] + mov r9, QWORD PTR [r12+56] + mov QWORD PTR [r12+48], rax + sbb r9, QWORD PTR [r13+56] + mov r10, QWORD PTR [r12+64] + mov QWORD PTR [r12+56], r9 + sbb r10, QWORD PTR [r13+64] + mov rax, QWORD PTR [r12+72] + mov QWORD PTR [r12+64], r10 + sbb rax, QWORD PTR [r13+72] + mov r9, QWORD PTR [r12+80] + mov QWORD PTR [r12+72], rax + sbb r9, QWORD PTR [r13+80] + mov r10, QWORD PTR [r12+88] + mov QWORD PTR [r12+80], r9 + sbb r10, QWORD PTR [r13+88] + mov rax, QWORD PTR [r12+96] + mov QWORD PTR [r12+88], r10 + sbb rax, QWORD PTR [r13+96] + mov r9, QWORD PTR [r12+104] + mov QWORD PTR [r12+96], rax + sbb r9, QWORD PTR [r13+104] + mov r10, QWORD PTR [r12+112] + mov QWORD PTR [r12+104], r9 + sbb r10, QWORD PTR [r13+112] + mov rax, QWORD PTR [r12+120] + mov QWORD PTR [r12+112], r10 + sbb rax, QWORD PTR [r13+120] + mov r9, QWORD PTR [r12+128] + mov QWORD PTR [r12+120], rax + sbb r9, QWORD PTR [r13+128] + mov r10, QWORD PTR [r12+136] + mov QWORD PTR [r12+128], r9 + sbb r10, QWORD PTR [r13+136] + mov rax, QWORD PTR [r12+144] + mov QWORD PTR [r12+136], r10 + sbb rax, QWORD PTR [r13+144] + mov r9, QWORD PTR [r12+152] + mov QWORD PTR [r12+144], rax + sbb r9, QWORD PTR [r13+152] + mov r10, QWORD PTR [r12+160] + mov QWORD PTR [r12+152], r9 + sbb r10, QWORD PTR [r13+160] + mov rax, QWORD PTR [r12+168] + mov QWORD PTR [r12+160], r10 + sbb rax, QWORD PTR [r13+168] + mov r9, QWORD PTR [r12+176] + mov QWORD PTR [r12+168], rax + sbb r9, QWORD PTR [r13+176] + mov r10, QWORD PTR [r12+184] + mov QWORD PTR [r12+176], r9 + sbb r10, QWORD PTR [r13+184] + mov QWORD PTR [r12+184], r10 + sbb r11, 0 + mov rax, QWORD PTR [r12] + sub rax, QWORD PTR [rcx] + mov r9, QWORD PTR [r12+8] + mov QWORD PTR [r12], rax + sbb r9, QWORD PTR [rcx+8] + mov r10, QWORD PTR [r12+16] + mov QWORD PTR [r12+8], r9 + sbb r10, QWORD PTR [rcx+16] + mov rax, QWORD PTR [r12+24] + mov QWORD PTR [r12+16], r10 + sbb rax, QWORD PTR [rcx+24] + mov r9, QWORD PTR [r12+32] + mov QWORD PTR [r12+24], rax + sbb r9, QWORD PTR [rcx+32] + mov r10, QWORD PTR [r12+40] + mov QWORD PTR [r12+32], r9 + sbb r10, QWORD PTR [rcx+40] + mov rax, QWORD PTR [r12+48] + mov QWORD PTR [r12+40], r10 + sbb rax, QWORD PTR [rcx+48] + mov r9, QWORD PTR [r12+56] + mov QWORD PTR [r12+48], rax + sbb r9, QWORD PTR [rcx+56] + mov r10, QWORD PTR [r12+64] + mov QWORD PTR [r12+56], r9 + sbb r10, QWORD PTR [rcx+64] + mov rax, QWORD PTR [r12+72] + mov QWORD PTR [r12+64], r10 + sbb rax, QWORD PTR [rcx+72] + mov r9, QWORD PTR [r12+80] + mov QWORD PTR [r12+72], rax + sbb r9, QWORD PTR [rcx+80] + mov r10, QWORD PTR [r12+88] + mov QWORD PTR [r12+80], r9 + sbb r10, QWORD PTR [rcx+88] + mov rax, QWORD PTR [r12+96] + mov QWORD PTR [r12+88], r10 + sbb rax, QWORD PTR [rcx+96] + mov r9, QWORD PTR [r12+104] + mov QWORD PTR [r12+96], rax + sbb r9, QWORD PTR [rcx+104] + mov r10, QWORD PTR [r12+112] + mov QWORD PTR [r12+104], r9 + sbb r10, QWORD PTR [rcx+112] + mov rax, QWORD PTR [r12+120] + mov QWORD PTR [r12+112], r10 + sbb rax, QWORD PTR [rcx+120] + mov r9, QWORD PTR [r12+128] + mov QWORD PTR [r12+120], rax + sbb r9, QWORD PTR [rcx+128] + mov r10, QWORD PTR [r12+136] + mov QWORD PTR [r12+128], r9 + sbb r10, QWORD PTR [rcx+136] + mov rax, QWORD PTR [r12+144] + mov QWORD PTR [r12+136], r10 + sbb rax, QWORD PTR [rcx+144] + mov r9, QWORD PTR [r12+152] + mov QWORD PTR [r12+144], rax + sbb r9, QWORD PTR [rcx+152] + mov r10, QWORD PTR [r12+160] + mov QWORD PTR [r12+152], r9 + sbb r10, QWORD PTR [rcx+160] + mov rax, QWORD PTR [r12+168] + mov QWORD PTR [r12+160], r10 + sbb rax, QWORD PTR [rcx+168] + mov r9, QWORD PTR [r12+176] + mov QWORD PTR [r12+168], rax + sbb r9, QWORD PTR [rcx+176] + mov r10, QWORD PTR [r12+184] + mov QWORD PTR [r12+176], r9 + sbb r10, QWORD PTR [rcx+184] + mov QWORD PTR [r12+184], r10 + sbb r11, 0 + sub rsi, 96 + ; Add + mov rax, QWORD PTR [rsi] + add rax, QWORD PTR [r12] + mov r9, QWORD PTR [rsi+8] + mov QWORD PTR [rsi], rax + adc r9, QWORD PTR [r12+8] + mov r10, QWORD PTR [rsi+16] + mov QWORD PTR [rsi+8], r9 + adc r10, QWORD PTR [r12+16] + mov rax, QWORD PTR [rsi+24] + mov QWORD PTR [rsi+16], r10 + adc rax, QWORD PTR [r12+24] + mov r9, QWORD PTR [rsi+32] + mov QWORD PTR [rsi+24], rax + adc r9, QWORD PTR [r12+32] + mov r10, QWORD PTR [rsi+40] + mov QWORD PTR [rsi+32], r9 + adc r10, QWORD PTR [r12+40] + mov rax, QWORD PTR [rsi+48] + mov QWORD PTR [rsi+40], r10 + adc rax, QWORD PTR [r12+48] + mov r9, QWORD PTR [rsi+56] + mov QWORD PTR [rsi+48], rax + adc r9, QWORD PTR [r12+56] + mov r10, QWORD PTR [rsi+64] + mov QWORD PTR [rsi+56], r9 + adc r10, QWORD PTR [r12+64] + mov rax, QWORD PTR [rsi+72] + mov QWORD PTR [rsi+64], r10 + adc rax, QWORD PTR [r12+72] + mov r9, QWORD PTR [rsi+80] + mov QWORD PTR [rsi+72], rax + adc r9, QWORD PTR [r12+80] + mov r10, QWORD PTR [rsi+88] + mov QWORD PTR [rsi+80], r9 + adc r10, QWORD PTR [r12+88] + mov rax, QWORD PTR [rsi+96] + mov QWORD PTR [rsi+88], r10 + adc rax, QWORD PTR [r12+96] + mov r9, QWORD PTR [rsi+104] + mov QWORD PTR [rsi+96], rax + adc r9, QWORD PTR [r12+104] + mov r10, QWORD PTR [rsi+112] + mov QWORD PTR [rsi+104], r9 + adc r10, QWORD PTR [r12+112] + mov rax, QWORD PTR [rsi+120] + mov QWORD PTR [rsi+112], r10 + adc rax, QWORD PTR [r12+120] + mov r9, QWORD PTR [rsi+128] + mov QWORD PTR [rsi+120], rax + adc r9, QWORD PTR [r12+128] + mov r10, QWORD PTR [rsi+136] + mov QWORD PTR [rsi+128], r9 + adc r10, QWORD PTR [r12+136] + mov rax, QWORD PTR [rsi+144] + mov QWORD PTR [rsi+136], r10 + adc rax, QWORD PTR [r12+144] + mov r9, QWORD PTR [rsi+152] + mov QWORD PTR [rsi+144], rax + adc r9, QWORD PTR [r12+152] + mov r10, QWORD PTR [rsi+160] + mov QWORD PTR [rsi+152], r9 + adc r10, QWORD PTR [r12+160] + mov rax, QWORD PTR [rsi+168] + mov QWORD PTR [rsi+160], r10 + adc rax, QWORD PTR [r12+168] + mov r9, QWORD PTR [rsi+176] + mov QWORD PTR [rsi+168], rax + adc r9, QWORD PTR [r12+176] + mov r10, QWORD PTR [rsi+184] + mov QWORD PTR [rsi+176], r9 + adc r10, QWORD PTR [r12+184] + mov QWORD PTR [rsi+184], r10 + adc r11, 0 + mov QWORD PTR [rcx+288], r11 + add rsi, 96 + ; Add + mov rax, QWORD PTR [rsi] + add rax, QWORD PTR [r13] + mov r9, QWORD PTR [rsi+8] + mov QWORD PTR [rsi], rax + adc r9, QWORD PTR [r13+8] + mov r10, QWORD PTR [rsi+16] + mov QWORD PTR [rsi+8], r9 + adc r10, QWORD PTR [r13+16] + mov rax, QWORD PTR [rsi+24] + mov QWORD PTR [rsi+16], r10 + adc rax, QWORD PTR [r13+24] + mov r9, QWORD PTR [rsi+32] + mov QWORD PTR [rsi+24], rax + adc r9, QWORD PTR [r13+32] + mov r10, QWORD PTR [rsi+40] + mov QWORD PTR [rsi+32], r9 + adc r10, QWORD PTR [r13+40] + mov rax, QWORD PTR [rsi+48] + mov QWORD PTR [rsi+40], r10 + adc rax, QWORD PTR [r13+48] + mov r9, QWORD PTR [rsi+56] + mov QWORD PTR [rsi+48], rax + adc r9, QWORD PTR [r13+56] + mov r10, QWORD PTR [rsi+64] + mov QWORD PTR [rsi+56], r9 + adc r10, QWORD PTR [r13+64] + mov rax, QWORD PTR [rsi+72] + mov QWORD PTR [rsi+64], r10 + adc rax, QWORD PTR [r13+72] + mov r9, QWORD PTR [rsi+80] + mov QWORD PTR [rsi+72], rax + adc r9, QWORD PTR [r13+80] + mov r10, QWORD PTR [rsi+88] + mov QWORD PTR [rsi+80], r9 + adc r10, QWORD PTR [r13+88] + mov rax, QWORD PTR [rsi+96] + mov QWORD PTR [rsi+88], r10 + adc rax, QWORD PTR [r13+96] + mov QWORD PTR [rsi+96], rax + ; Add to zero + mov rax, QWORD PTR [r13+104] + adc rax, 0 + mov r9, QWORD PTR [r13+112] + mov QWORD PTR [rsi+104], rax + adc r9, 0 + mov r10, QWORD PTR [r13+120] + mov QWORD PTR [rsi+112], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+128] + mov QWORD PTR [rsi+120], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+136] + mov QWORD PTR [rsi+128], rax + adc r9, 0 + mov r10, QWORD PTR [r13+144] + mov QWORD PTR [rsi+136], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+152] + mov QWORD PTR [rsi+144], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+160] + mov QWORD PTR [rsi+152], rax + adc r9, 0 + mov r10, QWORD PTR [r13+168] + mov QWORD PTR [rsi+160], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+176] + mov QWORD PTR [rsi+168], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+184] + mov QWORD PTR [rsi+176], rax + adc r9, 0 + mov QWORD PTR [rsi+184], r9 + add rsp, 616 + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_3072_mul_avx2_24 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Square a and put result in r. (r = a * a) +; * +; * r A single precision integer. +; * a A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_3072_sqr_avx2_24 PROC + push r12 + sub rsp, 504 + mov QWORD PTR [rsp+480], rcx + mov QWORD PTR [rsp+488], rdx + lea r10, QWORD PTR [rsp+384] + lea r11, QWORD PTR [rdx+96] + ; Add + mov rax, QWORD PTR [rdx] + xor r9, r9 + add rax, QWORD PTR [r11] + mov r8, QWORD PTR [rdx+8] + mov QWORD PTR [r10], rax + adc r8, QWORD PTR [r11+8] + mov rax, QWORD PTR [rdx+16] + mov QWORD PTR [r10+8], r8 + adc rax, QWORD PTR [r11+16] + mov r8, QWORD PTR [rdx+24] + mov QWORD PTR [r10+16], rax + adc r8, QWORD PTR [r11+24] + mov rax, QWORD PTR [rdx+32] + mov QWORD PTR [r10+24], r8 + adc rax, QWORD PTR [r11+32] + mov r8, QWORD PTR [rdx+40] + mov QWORD PTR [r10+32], rax + adc r8, QWORD PTR [r11+40] + mov rax, QWORD PTR [rdx+48] + mov QWORD PTR [r10+40], r8 + adc rax, QWORD PTR [r11+48] + mov r8, QWORD PTR [rdx+56] + mov QWORD PTR [r10+48], rax + adc r8, QWORD PTR [r11+56] + mov rax, QWORD PTR [rdx+64] + mov QWORD PTR [r10+56], r8 + adc rax, QWORD PTR [r11+64] + mov r8, QWORD PTR [rdx+72] + mov QWORD PTR [r10+64], rax + adc r8, QWORD PTR [r11+72] + mov rax, QWORD PTR [rdx+80] + mov QWORD PTR [r10+72], r8 + adc rax, QWORD PTR [r11+80] + mov r8, QWORD PTR [rdx+88] + mov QWORD PTR [r10+80], rax + adc r8, QWORD PTR [r11+88] + mov QWORD PTR [r10+88], r8 + adc r9, 0 + mov QWORD PTR [rsp+496], r9 + mov rdx, r10 + mov rcx, rsp + call sp_3072_sqr_avx2_12 + mov rdx, QWORD PTR [rsp+488] + lea rcx, QWORD PTR [rsp+192] + add rdx, 96 + call sp_3072_sqr_avx2_12 + mov rdx, QWORD PTR [rsp+488] + mov rcx, QWORD PTR [rsp+480] + call sp_3072_sqr_avx2_12 +IFDEF _WIN64 + mov rdx, QWORD PTR [rsp+488] + mov rcx, QWORD PTR [rsp+480] +ENDIF + mov r12, QWORD PTR [rsp+496] + mov r11, rcx + lea r10, QWORD PTR [rsp+384] + mov r9, r12 + neg r12 + add r11, 192 + mov rax, QWORD PTR [r10] + pext rax, rax, r12 + add rax, rax + mov r8, QWORD PTR [r10+8] + mov QWORD PTR [r11], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+16] + mov QWORD PTR [r11+8], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+24] + mov QWORD PTR [r11+16], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+32] + mov QWORD PTR [r11+24], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+40] + mov QWORD PTR [r11+32], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+48] + mov QWORD PTR [r11+40], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+56] + mov QWORD PTR [r11+48], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+64] + mov QWORD PTR [r11+56], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+72] + mov QWORD PTR [r11+64], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+80] + mov QWORD PTR [r11+72], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+88] + mov QWORD PTR [r11+80], rax + pext r8, r8, r12 + adc r8, r8 + mov QWORD PTR [r11+88], r8 + adc r9, 0 + lea rdx, QWORD PTR [rsp+192] + mov r10, rsp + mov rax, QWORD PTR [r10] + sub rax, QWORD PTR [rdx] + mov r8, QWORD PTR [r10+8] + mov QWORD PTR [r10], rax + sbb r8, QWORD PTR [rdx+8] + mov rax, QWORD PTR [r10+16] + mov QWORD PTR [r10+8], r8 + sbb rax, QWORD PTR [rdx+16] + mov r8, QWORD PTR [r10+24] + mov QWORD PTR [r10+16], rax + sbb r8, QWORD PTR [rdx+24] + mov rax, QWORD PTR [r10+32] + mov QWORD PTR [r10+24], r8 + sbb rax, QWORD PTR [rdx+32] + mov r8, QWORD PTR [r10+40] + mov QWORD PTR [r10+32], rax + sbb r8, QWORD PTR [rdx+40] + mov rax, QWORD PTR [r10+48] + mov QWORD PTR [r10+40], r8 + sbb rax, QWORD PTR [rdx+48] + mov r8, QWORD PTR [r10+56] + mov QWORD PTR [r10+48], rax + sbb r8, QWORD PTR [rdx+56] + mov rax, QWORD PTR [r10+64] + mov QWORD PTR [r10+56], r8 + sbb rax, QWORD PTR [rdx+64] + mov r8, QWORD PTR [r10+72] + mov QWORD PTR [r10+64], rax + sbb r8, QWORD PTR [rdx+72] + mov rax, QWORD PTR [r10+80] + mov QWORD PTR [r10+72], r8 + sbb rax, QWORD PTR [rdx+80] + mov r8, QWORD PTR [r10+88] + mov QWORD PTR [r10+80], rax + sbb r8, QWORD PTR [rdx+88] + mov rax, QWORD PTR [r10+96] + mov QWORD PTR [r10+88], r8 + sbb rax, QWORD PTR [rdx+96] + mov r8, QWORD PTR [r10+104] + mov QWORD PTR [r10+96], rax + sbb r8, QWORD PTR [rdx+104] + mov rax, QWORD PTR [r10+112] + mov QWORD PTR [r10+104], r8 + sbb rax, QWORD PTR [rdx+112] + mov r8, QWORD PTR [r10+120] + mov QWORD PTR [r10+112], rax + sbb r8, QWORD PTR [rdx+120] + mov rax, QWORD PTR [r10+128] + mov QWORD PTR [r10+120], r8 + sbb rax, QWORD PTR [rdx+128] + mov r8, QWORD PTR [r10+136] + mov QWORD PTR [r10+128], rax + sbb r8, QWORD PTR [rdx+136] + mov rax, QWORD PTR [r10+144] + mov QWORD PTR [r10+136], r8 + sbb rax, QWORD PTR [rdx+144] + mov r8, QWORD PTR [r10+152] + mov QWORD PTR [r10+144], rax + sbb r8, QWORD PTR [rdx+152] + mov rax, QWORD PTR [r10+160] + mov QWORD PTR [r10+152], r8 + sbb rax, QWORD PTR [rdx+160] + mov r8, QWORD PTR [r10+168] + mov QWORD PTR [r10+160], rax + sbb r8, QWORD PTR [rdx+168] + mov rax, QWORD PTR [r10+176] + mov QWORD PTR [r10+168], r8 + sbb rax, QWORD PTR [rdx+176] + mov r8, QWORD PTR [r10+184] + mov QWORD PTR [r10+176], rax + sbb r8, QWORD PTR [rdx+184] + mov QWORD PTR [r10+184], r8 + sbb r9, 0 + mov rax, QWORD PTR [r10] + sub rax, QWORD PTR [rcx] + mov r8, QWORD PTR [r10+8] + mov QWORD PTR [r10], rax + sbb r8, QWORD PTR [rcx+8] + mov rax, QWORD PTR [r10+16] + mov QWORD PTR [r10+8], r8 + sbb rax, QWORD PTR [rcx+16] + mov r8, QWORD PTR [r10+24] + mov QWORD PTR [r10+16], rax + sbb r8, QWORD PTR [rcx+24] + mov rax, QWORD PTR [r10+32] + mov QWORD PTR [r10+24], r8 + sbb rax, QWORD PTR [rcx+32] + mov r8, QWORD PTR [r10+40] + mov QWORD PTR [r10+32], rax + sbb r8, QWORD PTR [rcx+40] + mov rax, QWORD PTR [r10+48] + mov QWORD PTR [r10+40], r8 + sbb rax, QWORD PTR [rcx+48] + mov r8, QWORD PTR [r10+56] + mov QWORD PTR [r10+48], rax + sbb r8, QWORD PTR [rcx+56] + mov rax, QWORD PTR [r10+64] + mov QWORD PTR [r10+56], r8 + sbb rax, QWORD PTR [rcx+64] + mov r8, QWORD PTR [r10+72] + mov QWORD PTR [r10+64], rax + sbb r8, QWORD PTR [rcx+72] + mov rax, QWORD PTR [r10+80] + mov QWORD PTR [r10+72], r8 + sbb rax, QWORD PTR [rcx+80] + mov r8, QWORD PTR [r10+88] + mov QWORD PTR [r10+80], rax + sbb r8, QWORD PTR [rcx+88] + mov rax, QWORD PTR [r10+96] + mov QWORD PTR [r10+88], r8 + sbb rax, QWORD PTR [rcx+96] + mov r8, QWORD PTR [r10+104] + mov QWORD PTR [r10+96], rax + sbb r8, QWORD PTR [rcx+104] + mov rax, QWORD PTR [r10+112] + mov QWORD PTR [r10+104], r8 + sbb rax, QWORD PTR [rcx+112] + mov r8, QWORD PTR [r10+120] + mov QWORD PTR [r10+112], rax + sbb r8, QWORD PTR [rcx+120] + mov rax, QWORD PTR [r10+128] + mov QWORD PTR [r10+120], r8 + sbb rax, QWORD PTR [rcx+128] + mov r8, QWORD PTR [r10+136] + mov QWORD PTR [r10+128], rax + sbb r8, QWORD PTR [rcx+136] + mov rax, QWORD PTR [r10+144] + mov QWORD PTR [r10+136], r8 + sbb rax, QWORD PTR [rcx+144] + mov r8, QWORD PTR [r10+152] + mov QWORD PTR [r10+144], rax + sbb r8, QWORD PTR [rcx+152] + mov rax, QWORD PTR [r10+160] + mov QWORD PTR [r10+152], r8 + sbb rax, QWORD PTR [rcx+160] + mov r8, QWORD PTR [r10+168] + mov QWORD PTR [r10+160], rax + sbb r8, QWORD PTR [rcx+168] + mov rax, QWORD PTR [r10+176] + mov QWORD PTR [r10+168], r8 + sbb rax, QWORD PTR [rcx+176] + mov r8, QWORD PTR [r10+184] + mov QWORD PTR [r10+176], rax + sbb r8, QWORD PTR [rcx+184] + mov QWORD PTR [r10+184], r8 + sbb r9, 0 + sub r11, 96 + ; Add in place + mov rax, QWORD PTR [r11] + add rax, QWORD PTR [r10] + mov r8, QWORD PTR [r11+8] + mov QWORD PTR [r11], rax + adc r8, QWORD PTR [r10+8] + mov rax, QWORD PTR [r11+16] + mov QWORD PTR [r11+8], r8 + adc rax, QWORD PTR [r10+16] + mov r8, QWORD PTR [r11+24] + mov QWORD PTR [r11+16], rax + adc r8, QWORD PTR [r10+24] + mov rax, QWORD PTR [r11+32] + mov QWORD PTR [r11+24], r8 + adc rax, QWORD PTR [r10+32] + mov r8, QWORD PTR [r11+40] + mov QWORD PTR [r11+32], rax + adc r8, QWORD PTR [r10+40] + mov rax, QWORD PTR [r11+48] + mov QWORD PTR [r11+40], r8 + adc rax, QWORD PTR [r10+48] + mov r8, QWORD PTR [r11+56] + mov QWORD PTR [r11+48], rax + adc r8, QWORD PTR [r10+56] + mov rax, QWORD PTR [r11+64] + mov QWORD PTR [r11+56], r8 + adc rax, QWORD PTR [r10+64] + mov r8, QWORD PTR [r11+72] + mov QWORD PTR [r11+64], rax + adc r8, QWORD PTR [r10+72] + mov rax, QWORD PTR [r11+80] + mov QWORD PTR [r11+72], r8 + adc rax, QWORD PTR [r10+80] + mov r8, QWORD PTR [r11+88] + mov QWORD PTR [r11+80], rax + adc r8, QWORD PTR [r10+88] + mov rax, QWORD PTR [r11+96] + mov QWORD PTR [r11+88], r8 + adc rax, QWORD PTR [r10+96] + mov r8, QWORD PTR [r11+104] + mov QWORD PTR [r11+96], rax + adc r8, QWORD PTR [r10+104] + mov rax, QWORD PTR [r11+112] + mov QWORD PTR [r11+104], r8 + adc rax, QWORD PTR [r10+112] + mov r8, QWORD PTR [r11+120] + mov QWORD PTR [r11+112], rax + adc r8, QWORD PTR [r10+120] + mov rax, QWORD PTR [r11+128] + mov QWORD PTR [r11+120], r8 + adc rax, QWORD PTR [r10+128] + mov r8, QWORD PTR [r11+136] + mov QWORD PTR [r11+128], rax + adc r8, QWORD PTR [r10+136] + mov rax, QWORD PTR [r11+144] + mov QWORD PTR [r11+136], r8 + adc rax, QWORD PTR [r10+144] + mov r8, QWORD PTR [r11+152] + mov QWORD PTR [r11+144], rax + adc r8, QWORD PTR [r10+152] + mov rax, QWORD PTR [r11+160] + mov QWORD PTR [r11+152], r8 + adc rax, QWORD PTR [r10+160] + mov r8, QWORD PTR [r11+168] + mov QWORD PTR [r11+160], rax + adc r8, QWORD PTR [r10+168] + mov rax, QWORD PTR [r11+176] + mov QWORD PTR [r11+168], r8 + adc rax, QWORD PTR [r10+176] + mov r8, QWORD PTR [r11+184] + mov QWORD PTR [r11+176], rax + adc r8, QWORD PTR [r10+184] + mov QWORD PTR [r11+184], r8 + adc r9, 0 + mov QWORD PTR [rcx+288], r9 + ; Add in place + mov rax, QWORD PTR [r11+96] + add rax, QWORD PTR [rdx] + mov r8, QWORD PTR [r11+104] + mov QWORD PTR [r11+96], rax + adc r8, QWORD PTR [rdx+8] + mov rax, QWORD PTR [r11+112] + mov QWORD PTR [r11+104], r8 + adc rax, QWORD PTR [rdx+16] + mov r8, QWORD PTR [r11+120] + mov QWORD PTR [r11+112], rax + adc r8, QWORD PTR [rdx+24] + mov rax, QWORD PTR [r11+128] + mov QWORD PTR [r11+120], r8 + adc rax, QWORD PTR [rdx+32] + mov r8, QWORD PTR [r11+136] + mov QWORD PTR [r11+128], rax + adc r8, QWORD PTR [rdx+40] + mov rax, QWORD PTR [r11+144] + mov QWORD PTR [r11+136], r8 + adc rax, QWORD PTR [rdx+48] + mov r8, QWORD PTR [r11+152] + mov QWORD PTR [r11+144], rax + adc r8, QWORD PTR [rdx+56] + mov rax, QWORD PTR [r11+160] + mov QWORD PTR [r11+152], r8 + adc rax, QWORD PTR [rdx+64] + mov r8, QWORD PTR [r11+168] + mov QWORD PTR [r11+160], rax + adc r8, QWORD PTR [rdx+72] + mov rax, QWORD PTR [r11+176] + mov QWORD PTR [r11+168], r8 + adc rax, QWORD PTR [rdx+80] + mov r8, QWORD PTR [r11+184] + mov QWORD PTR [r11+176], rax + adc r8, QWORD PTR [rdx+88] + mov rax, QWORD PTR [r11+192] + mov QWORD PTR [r11+184], r8 + adc rax, QWORD PTR [rdx+96] + mov QWORD PTR [r11+192], rax + ; Add to zero + mov rax, QWORD PTR [rdx+104] + adc rax, 0 + mov r8, QWORD PTR [rdx+112] + mov QWORD PTR [r11+200], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+120] + mov QWORD PTR [r11+208], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+128] + mov QWORD PTR [r11+216], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+136] + mov QWORD PTR [r11+224], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+144] + mov QWORD PTR [r11+232], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+152] + mov QWORD PTR [r11+240], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+160] + mov QWORD PTR [r11+248], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+168] + mov QWORD PTR [r11+256], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+176] + mov QWORD PTR [r11+264], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+184] + mov QWORD PTR [r11+272], r8 + adc rax, 0 + mov QWORD PTR [r11+280], rax + add rsp, 504 + pop r12 + ret +sp_3072_sqr_avx2_24 ENDP +_text ENDS +ENDIF +; /* Sub b from a into a. (a -= b) +; * +; * a A single precision integer and result. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_3072_sub_in_place_48 PROC + mov r8, QWORD PTR [rcx] + xor rax, rax + sub r8, QWORD PTR [rdx] + mov r9, QWORD PTR [rcx+8] + mov QWORD PTR [rcx], r8 + sbb r9, QWORD PTR [rdx+8] + mov r8, QWORD PTR [rcx+16] + mov QWORD PTR [rcx+8], r9 + sbb r8, QWORD PTR [rdx+16] + mov r9, QWORD PTR [rcx+24] + mov QWORD PTR [rcx+16], r8 + sbb r9, QWORD PTR [rdx+24] + mov r8, QWORD PTR [rcx+32] + mov QWORD PTR [rcx+24], r9 + sbb r8, QWORD PTR [rdx+32] + mov r9, QWORD PTR [rcx+40] + mov QWORD PTR [rcx+32], r8 + sbb r9, QWORD PTR [rdx+40] + mov r8, QWORD PTR [rcx+48] + mov QWORD PTR [rcx+40], r9 + sbb r8, QWORD PTR [rdx+48] + mov r9, QWORD PTR [rcx+56] + mov QWORD PTR [rcx+48], r8 + sbb r9, QWORD PTR [rdx+56] + mov r8, QWORD PTR [rcx+64] + mov QWORD PTR [rcx+56], r9 + sbb r8, QWORD PTR [rdx+64] + mov r9, QWORD PTR [rcx+72] + mov QWORD PTR [rcx+64], r8 + sbb r9, QWORD PTR [rdx+72] + mov r8, QWORD PTR [rcx+80] + mov QWORD PTR [rcx+72], r9 + sbb r8, QWORD PTR [rdx+80] + mov r9, QWORD PTR [rcx+88] + mov QWORD PTR [rcx+80], r8 + sbb r9, QWORD PTR [rdx+88] + mov r8, QWORD PTR [rcx+96] + mov QWORD PTR [rcx+88], r9 + sbb r8, QWORD PTR [rdx+96] + mov r9, QWORD PTR [rcx+104] + mov QWORD PTR [rcx+96], r8 + sbb r9, QWORD PTR [rdx+104] + mov r8, QWORD PTR [rcx+112] + mov QWORD PTR [rcx+104], r9 + sbb r8, QWORD PTR [rdx+112] + mov r9, QWORD PTR [rcx+120] + mov QWORD PTR [rcx+112], r8 + sbb r9, QWORD PTR [rdx+120] + mov r8, QWORD PTR [rcx+128] + mov QWORD PTR [rcx+120], r9 + sbb r8, QWORD PTR [rdx+128] + mov r9, QWORD PTR [rcx+136] + mov QWORD PTR [rcx+128], r8 + sbb r9, QWORD PTR [rdx+136] + mov r8, QWORD PTR [rcx+144] + mov QWORD PTR [rcx+136], r9 + sbb r8, QWORD PTR [rdx+144] + mov r9, QWORD PTR [rcx+152] + mov QWORD PTR [rcx+144], r8 + sbb r9, QWORD PTR [rdx+152] + mov r8, QWORD PTR [rcx+160] + mov QWORD PTR [rcx+152], r9 + sbb r8, QWORD PTR [rdx+160] + mov r9, QWORD PTR [rcx+168] + mov QWORD PTR [rcx+160], r8 + sbb r9, QWORD PTR [rdx+168] + mov r8, QWORD PTR [rcx+176] + mov QWORD PTR [rcx+168], r9 + sbb r8, QWORD PTR [rdx+176] + mov r9, QWORD PTR [rcx+184] + mov QWORD PTR [rcx+176], r8 + sbb r9, QWORD PTR [rdx+184] + mov r8, QWORD PTR [rcx+192] + mov QWORD PTR [rcx+184], r9 + sbb r8, QWORD PTR [rdx+192] + mov r9, QWORD PTR [rcx+200] + mov QWORD PTR [rcx+192], r8 + sbb r9, QWORD PTR [rdx+200] + mov r8, QWORD PTR [rcx+208] + mov QWORD PTR [rcx+200], r9 + sbb r8, QWORD PTR [rdx+208] + mov r9, QWORD PTR [rcx+216] + mov QWORD PTR [rcx+208], r8 + sbb r9, QWORD PTR [rdx+216] + mov r8, QWORD PTR [rcx+224] + mov QWORD PTR [rcx+216], r9 + sbb r8, QWORD PTR [rdx+224] + mov r9, QWORD PTR [rcx+232] + mov QWORD PTR [rcx+224], r8 + sbb r9, QWORD PTR [rdx+232] + mov r8, QWORD PTR [rcx+240] + mov QWORD PTR [rcx+232], r9 + sbb r8, QWORD PTR [rdx+240] + mov r9, QWORD PTR [rcx+248] + mov QWORD PTR [rcx+240], r8 + sbb r9, QWORD PTR [rdx+248] + mov r8, QWORD PTR [rcx+256] + mov QWORD PTR [rcx+248], r9 + sbb r8, QWORD PTR [rdx+256] + mov r9, QWORD PTR [rcx+264] + mov QWORD PTR [rcx+256], r8 + sbb r9, QWORD PTR [rdx+264] + mov r8, QWORD PTR [rcx+272] + mov QWORD PTR [rcx+264], r9 + sbb r8, QWORD PTR [rdx+272] + mov r9, QWORD PTR [rcx+280] + mov QWORD PTR [rcx+272], r8 + sbb r9, QWORD PTR [rdx+280] + mov r8, QWORD PTR [rcx+288] + mov QWORD PTR [rcx+280], r9 + sbb r8, QWORD PTR [rdx+288] + mov r9, QWORD PTR [rcx+296] + mov QWORD PTR [rcx+288], r8 + sbb r9, QWORD PTR [rdx+296] + mov r8, QWORD PTR [rcx+304] + mov QWORD PTR [rcx+296], r9 + sbb r8, QWORD PTR [rdx+304] + mov r9, QWORD PTR [rcx+312] + mov QWORD PTR [rcx+304], r8 + sbb r9, QWORD PTR [rdx+312] + mov r8, QWORD PTR [rcx+320] + mov QWORD PTR [rcx+312], r9 + sbb r8, QWORD PTR [rdx+320] + mov r9, QWORD PTR [rcx+328] + mov QWORD PTR [rcx+320], r8 + sbb r9, QWORD PTR [rdx+328] + mov r8, QWORD PTR [rcx+336] + mov QWORD PTR [rcx+328], r9 + sbb r8, QWORD PTR [rdx+336] + mov r9, QWORD PTR [rcx+344] + mov QWORD PTR [rcx+336], r8 + sbb r9, QWORD PTR [rdx+344] + mov r8, QWORD PTR [rcx+352] + mov QWORD PTR [rcx+344], r9 + sbb r8, QWORD PTR [rdx+352] + mov r9, QWORD PTR [rcx+360] + mov QWORD PTR [rcx+352], r8 + sbb r9, QWORD PTR [rdx+360] + mov r8, QWORD PTR [rcx+368] + mov QWORD PTR [rcx+360], r9 + sbb r8, QWORD PTR [rdx+368] + mov r9, QWORD PTR [rcx+376] + mov QWORD PTR [rcx+368], r8 + sbb r9, QWORD PTR [rdx+376] + mov QWORD PTR [rcx+376], r9 + sbb rax, 0 + ret +sp_3072_sub_in_place_48 ENDP +_text ENDS +; /* Add b to a into r. (r = a + b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_3072_add_48 PROC + ; Add + mov r9, QWORD PTR [rdx] + xor rax, rax + add r9, QWORD PTR [r8] + mov r10, QWORD PTR [rdx+8] + mov QWORD PTR [rcx], r9 + adc r10, QWORD PTR [r8+8] + mov r9, QWORD PTR [rdx+16] + mov QWORD PTR [rcx+8], r10 + adc r9, QWORD PTR [r8+16] + mov r10, QWORD PTR [rdx+24] + mov QWORD PTR [rcx+16], r9 + adc r10, QWORD PTR [r8+24] + mov r9, QWORD PTR [rdx+32] + mov QWORD PTR [rcx+24], r10 + adc r9, QWORD PTR [r8+32] + mov r10, QWORD PTR [rdx+40] + mov QWORD PTR [rcx+32], r9 + adc r10, QWORD PTR [r8+40] + mov r9, QWORD PTR [rdx+48] + mov QWORD PTR [rcx+40], r10 + adc r9, QWORD PTR [r8+48] + mov r10, QWORD PTR [rdx+56] + mov QWORD PTR [rcx+48], r9 + adc r10, QWORD PTR [r8+56] + mov r9, QWORD PTR [rdx+64] + mov QWORD PTR [rcx+56], r10 + adc r9, QWORD PTR [r8+64] + mov r10, QWORD PTR [rdx+72] + mov QWORD PTR [rcx+64], r9 + adc r10, QWORD PTR [r8+72] + mov r9, QWORD PTR [rdx+80] + mov QWORD PTR [rcx+72], r10 + adc r9, QWORD PTR [r8+80] + mov r10, QWORD PTR [rdx+88] + mov QWORD PTR [rcx+80], r9 + adc r10, QWORD PTR [r8+88] + mov r9, QWORD PTR [rdx+96] + mov QWORD PTR [rcx+88], r10 + adc r9, QWORD PTR [r8+96] + mov r10, QWORD PTR [rdx+104] + mov QWORD PTR [rcx+96], r9 + adc r10, QWORD PTR [r8+104] + mov r9, QWORD PTR [rdx+112] + mov QWORD PTR [rcx+104], r10 + adc r9, QWORD PTR [r8+112] + mov r10, QWORD PTR [rdx+120] + mov QWORD PTR [rcx+112], r9 + adc r10, QWORD PTR [r8+120] + mov r9, QWORD PTR [rdx+128] + mov QWORD PTR [rcx+120], r10 + adc r9, QWORD PTR [r8+128] + mov r10, QWORD PTR [rdx+136] + mov QWORD PTR [rcx+128], r9 + adc r10, QWORD PTR [r8+136] + mov r9, QWORD PTR [rdx+144] + mov QWORD PTR [rcx+136], r10 + adc r9, QWORD PTR [r8+144] + mov r10, QWORD PTR [rdx+152] + mov QWORD PTR [rcx+144], r9 + adc r10, QWORD PTR [r8+152] + mov r9, QWORD PTR [rdx+160] + mov QWORD PTR [rcx+152], r10 + adc r9, QWORD PTR [r8+160] + mov r10, QWORD PTR [rdx+168] + mov QWORD PTR [rcx+160], r9 + adc r10, QWORD PTR [r8+168] + mov r9, QWORD PTR [rdx+176] + mov QWORD PTR [rcx+168], r10 + adc r9, QWORD PTR [r8+176] + mov r10, QWORD PTR [rdx+184] + mov QWORD PTR [rcx+176], r9 + adc r10, QWORD PTR [r8+184] + mov r9, QWORD PTR [rdx+192] + mov QWORD PTR [rcx+184], r10 + adc r9, QWORD PTR [r8+192] + mov r10, QWORD PTR [rdx+200] + mov QWORD PTR [rcx+192], r9 + adc r10, QWORD PTR [r8+200] + mov r9, QWORD PTR [rdx+208] + mov QWORD PTR [rcx+200], r10 + adc r9, QWORD PTR [r8+208] + mov r10, QWORD PTR [rdx+216] + mov QWORD PTR [rcx+208], r9 + adc r10, QWORD PTR [r8+216] + mov r9, QWORD PTR [rdx+224] + mov QWORD PTR [rcx+216], r10 + adc r9, QWORD PTR [r8+224] + mov r10, QWORD PTR [rdx+232] + mov QWORD PTR [rcx+224], r9 + adc r10, QWORD PTR [r8+232] + mov r9, QWORD PTR [rdx+240] + mov QWORD PTR [rcx+232], r10 + adc r9, QWORD PTR [r8+240] + mov r10, QWORD PTR [rdx+248] + mov QWORD PTR [rcx+240], r9 + adc r10, QWORD PTR [r8+248] + mov r9, QWORD PTR [rdx+256] + mov QWORD PTR [rcx+248], r10 + adc r9, QWORD PTR [r8+256] + mov r10, QWORD PTR [rdx+264] + mov QWORD PTR [rcx+256], r9 + adc r10, QWORD PTR [r8+264] + mov r9, QWORD PTR [rdx+272] + mov QWORD PTR [rcx+264], r10 + adc r9, QWORD PTR [r8+272] + mov r10, QWORD PTR [rdx+280] + mov QWORD PTR [rcx+272], r9 + adc r10, QWORD PTR [r8+280] + mov r9, QWORD PTR [rdx+288] + mov QWORD PTR [rcx+280], r10 + adc r9, QWORD PTR [r8+288] + mov r10, QWORD PTR [rdx+296] + mov QWORD PTR [rcx+288], r9 + adc r10, QWORD PTR [r8+296] + mov r9, QWORD PTR [rdx+304] + mov QWORD PTR [rcx+296], r10 + adc r9, QWORD PTR [r8+304] + mov r10, QWORD PTR [rdx+312] + mov QWORD PTR [rcx+304], r9 + adc r10, QWORD PTR [r8+312] + mov r9, QWORD PTR [rdx+320] + mov QWORD PTR [rcx+312], r10 + adc r9, QWORD PTR [r8+320] + mov r10, QWORD PTR [rdx+328] + mov QWORD PTR [rcx+320], r9 + adc r10, QWORD PTR [r8+328] + mov r9, QWORD PTR [rdx+336] + mov QWORD PTR [rcx+328], r10 + adc r9, QWORD PTR [r8+336] + mov r10, QWORD PTR [rdx+344] + mov QWORD PTR [rcx+336], r9 + adc r10, QWORD PTR [r8+344] + mov r9, QWORD PTR [rdx+352] + mov QWORD PTR [rcx+344], r10 + adc r9, QWORD PTR [r8+352] + mov r10, QWORD PTR [rdx+360] + mov QWORD PTR [rcx+352], r9 + adc r10, QWORD PTR [r8+360] + mov r9, QWORD PTR [rdx+368] + mov QWORD PTR [rcx+360], r10 + adc r9, QWORD PTR [r8+368] + mov r10, QWORD PTR [rdx+376] + mov QWORD PTR [rcx+368], r9 + adc r10, QWORD PTR [r8+376] + mov QWORD PTR [rcx+376], r10 + adc rax, 0 + ret +sp_3072_add_48 ENDP +_text ENDS +; /* Multiply a and b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_3072_mul_48 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + sub rsp, 1192 + mov QWORD PTR [rsp+1152], rcx + mov QWORD PTR [rsp+1160], rdx + mov QWORD PTR [rsp+1168], r8 + lea r12, QWORD PTR [rsp+768] + lea r14, QWORD PTR [rdx+192] + ; Add + mov rax, QWORD PTR [rdx] + xor r15, r15 + add rax, QWORD PTR [r14] + mov r9, QWORD PTR [rdx+8] + mov QWORD PTR [r12], rax + adc r9, QWORD PTR [r14+8] + mov r10, QWORD PTR [rdx+16] + mov QWORD PTR [r12+8], r9 + adc r10, QWORD PTR [r14+16] + mov rax, QWORD PTR [rdx+24] + mov QWORD PTR [r12+16], r10 + adc rax, QWORD PTR [r14+24] + mov r9, QWORD PTR [rdx+32] + mov QWORD PTR [r12+24], rax + adc r9, QWORD PTR [r14+32] + mov r10, QWORD PTR [rdx+40] + mov QWORD PTR [r12+32], r9 + adc r10, QWORD PTR [r14+40] + mov rax, QWORD PTR [rdx+48] + mov QWORD PTR [r12+40], r10 + adc rax, QWORD PTR [r14+48] + mov r9, QWORD PTR [rdx+56] + mov QWORD PTR [r12+48], rax + adc r9, QWORD PTR [r14+56] + mov r10, QWORD PTR [rdx+64] + mov QWORD PTR [r12+56], r9 + adc r10, QWORD PTR [r14+64] + mov rax, QWORD PTR [rdx+72] + mov QWORD PTR [r12+64], r10 + adc rax, QWORD PTR [r14+72] + mov r9, QWORD PTR [rdx+80] + mov QWORD PTR [r12+72], rax + adc r9, QWORD PTR [r14+80] + mov r10, QWORD PTR [rdx+88] + mov QWORD PTR [r12+80], r9 + adc r10, QWORD PTR [r14+88] + mov rax, QWORD PTR [rdx+96] + mov QWORD PTR [r12+88], r10 + adc rax, QWORD PTR [r14+96] + mov r9, QWORD PTR [rdx+104] + mov QWORD PTR [r12+96], rax + adc r9, QWORD PTR [r14+104] + mov r10, QWORD PTR [rdx+112] + mov QWORD PTR [r12+104], r9 + adc r10, QWORD PTR [r14+112] + mov rax, QWORD PTR [rdx+120] + mov QWORD PTR [r12+112], r10 + adc rax, QWORD PTR [r14+120] + mov r9, QWORD PTR [rdx+128] + mov QWORD PTR [r12+120], rax + adc r9, QWORD PTR [r14+128] + mov r10, QWORD PTR [rdx+136] + mov QWORD PTR [r12+128], r9 + adc r10, QWORD PTR [r14+136] + mov rax, QWORD PTR [rdx+144] + mov QWORD PTR [r12+136], r10 + adc rax, QWORD PTR [r14+144] + mov r9, QWORD PTR [rdx+152] + mov QWORD PTR [r12+144], rax + adc r9, QWORD PTR [r14+152] + mov r10, QWORD PTR [rdx+160] + mov QWORD PTR [r12+152], r9 + adc r10, QWORD PTR [r14+160] + mov rax, QWORD PTR [rdx+168] + mov QWORD PTR [r12+160], r10 + adc rax, QWORD PTR [r14+168] + mov r9, QWORD PTR [rdx+176] + mov QWORD PTR [r12+168], rax + adc r9, QWORD PTR [r14+176] + mov r10, QWORD PTR [rdx+184] + mov QWORD PTR [r12+176], r9 + adc r10, QWORD PTR [r14+184] + mov QWORD PTR [r12+184], r10 + adc r15, 0 + mov QWORD PTR [rsp+1176], r15 + lea r13, QWORD PTR [rsp+960] + lea r14, QWORD PTR [r8+192] + ; Add + mov rax, QWORD PTR [r8] + xor rdi, rdi + add rax, QWORD PTR [r14] + mov r9, QWORD PTR [r8+8] + mov QWORD PTR [r13], rax + adc r9, QWORD PTR [r14+8] + mov r10, QWORD PTR [r8+16] + mov QWORD PTR [r13+8], r9 + adc r10, QWORD PTR [r14+16] + mov rax, QWORD PTR [r8+24] + mov QWORD PTR [r13+16], r10 + adc rax, QWORD PTR [r14+24] + mov r9, QWORD PTR [r8+32] + mov QWORD PTR [r13+24], rax + adc r9, QWORD PTR [r14+32] + mov r10, QWORD PTR [r8+40] + mov QWORD PTR [r13+32], r9 + adc r10, QWORD PTR [r14+40] + mov rax, QWORD PTR [r8+48] + mov QWORD PTR [r13+40], r10 + adc rax, QWORD PTR [r14+48] + mov r9, QWORD PTR [r8+56] + mov QWORD PTR [r13+48], rax + adc r9, QWORD PTR [r14+56] + mov r10, QWORD PTR [r8+64] + mov QWORD PTR [r13+56], r9 + adc r10, QWORD PTR [r14+64] + mov rax, QWORD PTR [r8+72] + mov QWORD PTR [r13+64], r10 + adc rax, QWORD PTR [r14+72] + mov r9, QWORD PTR [r8+80] + mov QWORD PTR [r13+72], rax + adc r9, QWORD PTR [r14+80] + mov r10, QWORD PTR [r8+88] + mov QWORD PTR [r13+80], r9 + adc r10, QWORD PTR [r14+88] + mov rax, QWORD PTR [r8+96] + mov QWORD PTR [r13+88], r10 + adc rax, QWORD PTR [r14+96] + mov r9, QWORD PTR [r8+104] + mov QWORD PTR [r13+96], rax + adc r9, QWORD PTR [r14+104] + mov r10, QWORD PTR [r8+112] + mov QWORD PTR [r13+104], r9 + adc r10, QWORD PTR [r14+112] + mov rax, QWORD PTR [r8+120] + mov QWORD PTR [r13+112], r10 + adc rax, QWORD PTR [r14+120] + mov r9, QWORD PTR [r8+128] + mov QWORD PTR [r13+120], rax + adc r9, QWORD PTR [r14+128] + mov r10, QWORD PTR [r8+136] + mov QWORD PTR [r13+128], r9 + adc r10, QWORD PTR [r14+136] + mov rax, QWORD PTR [r8+144] + mov QWORD PTR [r13+136], r10 + adc rax, QWORD PTR [r14+144] + mov r9, QWORD PTR [r8+152] + mov QWORD PTR [r13+144], rax + adc r9, QWORD PTR [r14+152] + mov r10, QWORD PTR [r8+160] + mov QWORD PTR [r13+152], r9 + adc r10, QWORD PTR [r14+160] + mov rax, QWORD PTR [r8+168] + mov QWORD PTR [r13+160], r10 + adc rax, QWORD PTR [r14+168] + mov r9, QWORD PTR [r8+176] + mov QWORD PTR [r13+168], rax + adc r9, QWORD PTR [r14+176] + mov r10, QWORD PTR [r8+184] + mov QWORD PTR [r13+176], r9 + adc r10, QWORD PTR [r14+184] + mov QWORD PTR [r13+184], r10 + adc rdi, 0 + mov QWORD PTR [rsp+1184], rdi + mov r8, r13 + mov rdx, r12 + mov rcx, rsp + call sp_3072_mul_24 + mov r8, QWORD PTR [rsp+1168] + mov rdx, QWORD PTR [rsp+1160] + lea rcx, QWORD PTR [rsp+384] + add r8, 192 + add rdx, 192 + call sp_3072_mul_24 + mov r8, QWORD PTR [rsp+1168] + mov rdx, QWORD PTR [rsp+1160] + mov rcx, QWORD PTR [rsp+1152] + call sp_3072_mul_24 +IFDEF _WIN64 + mov r8, QWORD PTR [rsp+1168] + mov rdx, QWORD PTR [rsp+1160] + mov rcx, QWORD PTR [rsp+1152] +ENDIF + mov r15, QWORD PTR [rsp+1176] + mov rdi, QWORD PTR [rsp+1184] + mov rsi, QWORD PTR [rsp+1152] + mov r11, r15 + lea r12, QWORD PTR [rsp+768] + lea r13, QWORD PTR [rsp+960] + and r11, rdi + neg r15 + neg rdi + add rsi, 384 + mov rax, QWORD PTR [r12] + mov r9, QWORD PTR [r13] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12], rax + mov QWORD PTR [r13], r9 + mov rax, QWORD PTR [r12+8] + mov r9, QWORD PTR [r13+8] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+8], rax + mov QWORD PTR [r13+8], r9 + mov rax, QWORD PTR [r12+16] + mov r9, QWORD PTR [r13+16] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+16], rax + mov QWORD PTR [r13+16], r9 + mov rax, QWORD PTR [r12+24] + mov r9, QWORD PTR [r13+24] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+24], rax + mov QWORD PTR [r13+24], r9 + mov rax, QWORD PTR [r12+32] + mov r9, QWORD PTR [r13+32] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+32], rax + mov QWORD PTR [r13+32], r9 + mov rax, QWORD PTR [r12+40] + mov r9, QWORD PTR [r13+40] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+40], rax + mov QWORD PTR [r13+40], r9 + mov rax, QWORD PTR [r12+48] + mov r9, QWORD PTR [r13+48] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+48], rax + mov QWORD PTR [r13+48], r9 + mov rax, QWORD PTR [r12+56] + mov r9, QWORD PTR [r13+56] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+56], rax + mov QWORD PTR [r13+56], r9 + mov rax, QWORD PTR [r12+64] + mov r9, QWORD PTR [r13+64] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+64], rax + mov QWORD PTR [r13+64], r9 + mov rax, QWORD PTR [r12+72] + mov r9, QWORD PTR [r13+72] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+72], rax + mov QWORD PTR [r13+72], r9 + mov rax, QWORD PTR [r12+80] + mov r9, QWORD PTR [r13+80] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+80], rax + mov QWORD PTR [r13+80], r9 + mov rax, QWORD PTR [r12+88] + mov r9, QWORD PTR [r13+88] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+88], rax + mov QWORD PTR [r13+88], r9 + mov rax, QWORD PTR [r12+96] + mov r9, QWORD PTR [r13+96] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+96], rax + mov QWORD PTR [r13+96], r9 + mov rax, QWORD PTR [r12+104] + mov r9, QWORD PTR [r13+104] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+104], rax + mov QWORD PTR [r13+104], r9 + mov rax, QWORD PTR [r12+112] + mov r9, QWORD PTR [r13+112] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+112], rax + mov QWORD PTR [r13+112], r9 + mov rax, QWORD PTR [r12+120] + mov r9, QWORD PTR [r13+120] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+120], rax + mov QWORD PTR [r13+120], r9 + mov rax, QWORD PTR [r12+128] + mov r9, QWORD PTR [r13+128] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+128], rax + mov QWORD PTR [r13+128], r9 + mov rax, QWORD PTR [r12+136] + mov r9, QWORD PTR [r13+136] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+136], rax + mov QWORD PTR [r13+136], r9 + mov rax, QWORD PTR [r12+144] + mov r9, QWORD PTR [r13+144] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+144], rax + mov QWORD PTR [r13+144], r9 + mov rax, QWORD PTR [r12+152] + mov r9, QWORD PTR [r13+152] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+152], rax + mov QWORD PTR [r13+152], r9 + mov rax, QWORD PTR [r12+160] + mov r9, QWORD PTR [r13+160] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+160], rax + mov QWORD PTR [r13+160], r9 + mov rax, QWORD PTR [r12+168] + mov r9, QWORD PTR [r13+168] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+168], rax + mov QWORD PTR [r13+168], r9 + mov rax, QWORD PTR [r12+176] + mov r9, QWORD PTR [r13+176] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+176], rax + mov QWORD PTR [r13+176], r9 + mov rax, QWORD PTR [r12+184] + mov r9, QWORD PTR [r13+184] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+184], rax + mov QWORD PTR [r13+184], r9 + mov rax, QWORD PTR [r12] + add rax, QWORD PTR [r13] + mov r9, QWORD PTR [r12+8] + mov QWORD PTR [rsi], rax + adc r9, QWORD PTR [r13+8] + mov r10, QWORD PTR [r12+16] + mov QWORD PTR [rsi+8], r9 + adc r10, QWORD PTR [r13+16] + mov rax, QWORD PTR [r12+24] + mov QWORD PTR [rsi+16], r10 + adc rax, QWORD PTR [r13+24] + mov r9, QWORD PTR [r12+32] + mov QWORD PTR [rsi+24], rax + adc r9, QWORD PTR [r13+32] + mov r10, QWORD PTR [r12+40] + mov QWORD PTR [rsi+32], r9 + adc r10, QWORD PTR [r13+40] + mov rax, QWORD PTR [r12+48] + mov QWORD PTR [rsi+40], r10 + adc rax, QWORD PTR [r13+48] + mov r9, QWORD PTR [r12+56] + mov QWORD PTR [rsi+48], rax + adc r9, QWORD PTR [r13+56] + mov r10, QWORD PTR [r12+64] + mov QWORD PTR [rsi+56], r9 + adc r10, QWORD PTR [r13+64] + mov rax, QWORD PTR [r12+72] + mov QWORD PTR [rsi+64], r10 + adc rax, QWORD PTR [r13+72] + mov r9, QWORD PTR [r12+80] + mov QWORD PTR [rsi+72], rax + adc r9, QWORD PTR [r13+80] + mov r10, QWORD PTR [r12+88] + mov QWORD PTR [rsi+80], r9 + adc r10, QWORD PTR [r13+88] + mov rax, QWORD PTR [r12+96] + mov QWORD PTR [rsi+88], r10 + adc rax, QWORD PTR [r13+96] + mov r9, QWORD PTR [r12+104] + mov QWORD PTR [rsi+96], rax + adc r9, QWORD PTR [r13+104] + mov r10, QWORD PTR [r12+112] + mov QWORD PTR [rsi+104], r9 + adc r10, QWORD PTR [r13+112] + mov rax, QWORD PTR [r12+120] + mov QWORD PTR [rsi+112], r10 + adc rax, QWORD PTR [r13+120] + mov r9, QWORD PTR [r12+128] + mov QWORD PTR [rsi+120], rax + adc r9, QWORD PTR [r13+128] + mov r10, QWORD PTR [r12+136] + mov QWORD PTR [rsi+128], r9 + adc r10, QWORD PTR [r13+136] + mov rax, QWORD PTR [r12+144] + mov QWORD PTR [rsi+136], r10 + adc rax, QWORD PTR [r13+144] + mov r9, QWORD PTR [r12+152] + mov QWORD PTR [rsi+144], rax + adc r9, QWORD PTR [r13+152] + mov r10, QWORD PTR [r12+160] + mov QWORD PTR [rsi+152], r9 + adc r10, QWORD PTR [r13+160] + mov rax, QWORD PTR [r12+168] + mov QWORD PTR [rsi+160], r10 + adc rax, QWORD PTR [r13+168] + mov r9, QWORD PTR [r12+176] + mov QWORD PTR [rsi+168], rax + adc r9, QWORD PTR [r13+176] + mov r10, QWORD PTR [r12+184] + mov QWORD PTR [rsi+176], r9 + adc r10, QWORD PTR [r13+184] + mov QWORD PTR [rsi+184], r10 + adc r11, 0 + lea r13, QWORD PTR [rsp+384] + mov r12, rsp + mov rax, QWORD PTR [r12] + sub rax, QWORD PTR [r13] + mov r9, QWORD PTR [r12+8] + mov QWORD PTR [r12], rax + sbb r9, QWORD PTR [r13+8] + mov r10, QWORD PTR [r12+16] + mov QWORD PTR [r12+8], r9 + sbb r10, QWORD PTR [r13+16] + mov rax, QWORD PTR [r12+24] + mov QWORD PTR [r12+16], r10 + sbb rax, QWORD PTR [r13+24] + mov r9, QWORD PTR [r12+32] + mov QWORD PTR [r12+24], rax + sbb r9, QWORD PTR [r13+32] + mov r10, QWORD PTR [r12+40] + mov QWORD PTR [r12+32], r9 + sbb r10, QWORD PTR [r13+40] + mov rax, QWORD PTR [r12+48] + mov QWORD PTR [r12+40], r10 + sbb rax, QWORD PTR [r13+48] + mov r9, QWORD PTR [r12+56] + mov QWORD PTR [r12+48], rax + sbb r9, QWORD PTR [r13+56] + mov r10, QWORD PTR [r12+64] + mov QWORD PTR [r12+56], r9 + sbb r10, QWORD PTR [r13+64] + mov rax, QWORD PTR [r12+72] + mov QWORD PTR [r12+64], r10 + sbb rax, QWORD PTR [r13+72] + mov r9, QWORD PTR [r12+80] + mov QWORD PTR [r12+72], rax + sbb r9, QWORD PTR [r13+80] + mov r10, QWORD PTR [r12+88] + mov QWORD PTR [r12+80], r9 + sbb r10, QWORD PTR [r13+88] + mov rax, QWORD PTR [r12+96] + mov QWORD PTR [r12+88], r10 + sbb rax, QWORD PTR [r13+96] + mov r9, QWORD PTR [r12+104] + mov QWORD PTR [r12+96], rax + sbb r9, QWORD PTR [r13+104] + mov r10, QWORD PTR [r12+112] + mov QWORD PTR [r12+104], r9 + sbb r10, QWORD PTR [r13+112] + mov rax, QWORD PTR [r12+120] + mov QWORD PTR [r12+112], r10 + sbb rax, QWORD PTR [r13+120] + mov r9, QWORD PTR [r12+128] + mov QWORD PTR [r12+120], rax + sbb r9, QWORD PTR [r13+128] + mov r10, QWORD PTR [r12+136] + mov QWORD PTR [r12+128], r9 + sbb r10, QWORD PTR [r13+136] + mov rax, QWORD PTR [r12+144] + mov QWORD PTR [r12+136], r10 + sbb rax, QWORD PTR [r13+144] + mov r9, QWORD PTR [r12+152] + mov QWORD PTR [r12+144], rax + sbb r9, QWORD PTR [r13+152] + mov r10, QWORD PTR [r12+160] + mov QWORD PTR [r12+152], r9 + sbb r10, QWORD PTR [r13+160] + mov rax, QWORD PTR [r12+168] + mov QWORD PTR [r12+160], r10 + sbb rax, QWORD PTR [r13+168] + mov r9, QWORD PTR [r12+176] + mov QWORD PTR [r12+168], rax + sbb r9, QWORD PTR [r13+176] + mov r10, QWORD PTR [r12+184] + mov QWORD PTR [r12+176], r9 + sbb r10, QWORD PTR [r13+184] + mov rax, QWORD PTR [r12+192] + mov QWORD PTR [r12+184], r10 + sbb rax, QWORD PTR [r13+192] + mov r9, QWORD PTR [r12+200] + mov QWORD PTR [r12+192], rax + sbb r9, QWORD PTR [r13+200] + mov r10, QWORD PTR [r12+208] + mov QWORD PTR [r12+200], r9 + sbb r10, QWORD PTR [r13+208] + mov rax, QWORD PTR [r12+216] + mov QWORD PTR [r12+208], r10 + sbb rax, QWORD PTR [r13+216] + mov r9, QWORD PTR [r12+224] + mov QWORD PTR [r12+216], rax + sbb r9, QWORD PTR [r13+224] + mov r10, QWORD PTR [r12+232] + mov QWORD PTR [r12+224], r9 + sbb r10, QWORD PTR [r13+232] + mov rax, QWORD PTR [r12+240] + mov QWORD PTR [r12+232], r10 + sbb rax, QWORD PTR [r13+240] + mov r9, QWORD PTR [r12+248] + mov QWORD PTR [r12+240], rax + sbb r9, QWORD PTR [r13+248] + mov r10, QWORD PTR [r12+256] + mov QWORD PTR [r12+248], r9 + sbb r10, QWORD PTR [r13+256] + mov rax, QWORD PTR [r12+264] + mov QWORD PTR [r12+256], r10 + sbb rax, QWORD PTR [r13+264] + mov r9, QWORD PTR [r12+272] + mov QWORD PTR [r12+264], rax + sbb r9, QWORD PTR [r13+272] + mov r10, QWORD PTR [r12+280] + mov QWORD PTR [r12+272], r9 + sbb r10, QWORD PTR [r13+280] + mov rax, QWORD PTR [r12+288] + mov QWORD PTR [r12+280], r10 + sbb rax, QWORD PTR [r13+288] + mov r9, QWORD PTR [r12+296] + mov QWORD PTR [r12+288], rax + sbb r9, QWORD PTR [r13+296] + mov r10, QWORD PTR [r12+304] + mov QWORD PTR [r12+296], r9 + sbb r10, QWORD PTR [r13+304] + mov rax, QWORD PTR [r12+312] + mov QWORD PTR [r12+304], r10 + sbb rax, QWORD PTR [r13+312] + mov r9, QWORD PTR [r12+320] + mov QWORD PTR [r12+312], rax + sbb r9, QWORD PTR [r13+320] + mov r10, QWORD PTR [r12+328] + mov QWORD PTR [r12+320], r9 + sbb r10, QWORD PTR [r13+328] + mov rax, QWORD PTR [r12+336] + mov QWORD PTR [r12+328], r10 + sbb rax, QWORD PTR [r13+336] + mov r9, QWORD PTR [r12+344] + mov QWORD PTR [r12+336], rax + sbb r9, QWORD PTR [r13+344] + mov r10, QWORD PTR [r12+352] + mov QWORD PTR [r12+344], r9 + sbb r10, QWORD PTR [r13+352] + mov rax, QWORD PTR [r12+360] + mov QWORD PTR [r12+352], r10 + sbb rax, QWORD PTR [r13+360] + mov r9, QWORD PTR [r12+368] + mov QWORD PTR [r12+360], rax + sbb r9, QWORD PTR [r13+368] + mov r10, QWORD PTR [r12+376] + mov QWORD PTR [r12+368], r9 + sbb r10, QWORD PTR [r13+376] + mov QWORD PTR [r12+376], r10 + sbb r11, 0 + mov rax, QWORD PTR [r12] + sub rax, QWORD PTR [rcx] + mov r9, QWORD PTR [r12+8] + mov QWORD PTR [r12], rax + sbb r9, QWORD PTR [rcx+8] + mov r10, QWORD PTR [r12+16] + mov QWORD PTR [r12+8], r9 + sbb r10, QWORD PTR [rcx+16] + mov rax, QWORD PTR [r12+24] + mov QWORD PTR [r12+16], r10 + sbb rax, QWORD PTR [rcx+24] + mov r9, QWORD PTR [r12+32] + mov QWORD PTR [r12+24], rax + sbb r9, QWORD PTR [rcx+32] + mov r10, QWORD PTR [r12+40] + mov QWORD PTR [r12+32], r9 + sbb r10, QWORD PTR [rcx+40] + mov rax, QWORD PTR [r12+48] + mov QWORD PTR [r12+40], r10 + sbb rax, QWORD PTR [rcx+48] + mov r9, QWORD PTR [r12+56] + mov QWORD PTR [r12+48], rax + sbb r9, QWORD PTR [rcx+56] + mov r10, QWORD PTR [r12+64] + mov QWORD PTR [r12+56], r9 + sbb r10, QWORD PTR [rcx+64] + mov rax, QWORD PTR [r12+72] + mov QWORD PTR [r12+64], r10 + sbb rax, QWORD PTR [rcx+72] + mov r9, QWORD PTR [r12+80] + mov QWORD PTR [r12+72], rax + sbb r9, QWORD PTR [rcx+80] + mov r10, QWORD PTR [r12+88] + mov QWORD PTR [r12+80], r9 + sbb r10, QWORD PTR [rcx+88] + mov rax, QWORD PTR [r12+96] + mov QWORD PTR [r12+88], r10 + sbb rax, QWORD PTR [rcx+96] + mov r9, QWORD PTR [r12+104] + mov QWORD PTR [r12+96], rax + sbb r9, QWORD PTR [rcx+104] + mov r10, QWORD PTR [r12+112] + mov QWORD PTR [r12+104], r9 + sbb r10, QWORD PTR [rcx+112] + mov rax, QWORD PTR [r12+120] + mov QWORD PTR [r12+112], r10 + sbb rax, QWORD PTR [rcx+120] + mov r9, QWORD PTR [r12+128] + mov QWORD PTR [r12+120], rax + sbb r9, QWORD PTR [rcx+128] + mov r10, QWORD PTR [r12+136] + mov QWORD PTR [r12+128], r9 + sbb r10, QWORD PTR [rcx+136] + mov rax, QWORD PTR [r12+144] + mov QWORD PTR [r12+136], r10 + sbb rax, QWORD PTR [rcx+144] + mov r9, QWORD PTR [r12+152] + mov QWORD PTR [r12+144], rax + sbb r9, QWORD PTR [rcx+152] + mov r10, QWORD PTR [r12+160] + mov QWORD PTR [r12+152], r9 + sbb r10, QWORD PTR [rcx+160] + mov rax, QWORD PTR [r12+168] + mov QWORD PTR [r12+160], r10 + sbb rax, QWORD PTR [rcx+168] + mov r9, QWORD PTR [r12+176] + mov QWORD PTR [r12+168], rax + sbb r9, QWORD PTR [rcx+176] + mov r10, QWORD PTR [r12+184] + mov QWORD PTR [r12+176], r9 + sbb r10, QWORD PTR [rcx+184] + mov rax, QWORD PTR [r12+192] + mov QWORD PTR [r12+184], r10 + sbb rax, QWORD PTR [rcx+192] + mov r9, QWORD PTR [r12+200] + mov QWORD PTR [r12+192], rax + sbb r9, QWORD PTR [rcx+200] + mov r10, QWORD PTR [r12+208] + mov QWORD PTR [r12+200], r9 + sbb r10, QWORD PTR [rcx+208] + mov rax, QWORD PTR [r12+216] + mov QWORD PTR [r12+208], r10 + sbb rax, QWORD PTR [rcx+216] + mov r9, QWORD PTR [r12+224] + mov QWORD PTR [r12+216], rax + sbb r9, QWORD PTR [rcx+224] + mov r10, QWORD PTR [r12+232] + mov QWORD PTR [r12+224], r9 + sbb r10, QWORD PTR [rcx+232] + mov rax, QWORD PTR [r12+240] + mov QWORD PTR [r12+232], r10 + sbb rax, QWORD PTR [rcx+240] + mov r9, QWORD PTR [r12+248] + mov QWORD PTR [r12+240], rax + sbb r9, QWORD PTR [rcx+248] + mov r10, QWORD PTR [r12+256] + mov QWORD PTR [r12+248], r9 + sbb r10, QWORD PTR [rcx+256] + mov rax, QWORD PTR [r12+264] + mov QWORD PTR [r12+256], r10 + sbb rax, QWORD PTR [rcx+264] + mov r9, QWORD PTR [r12+272] + mov QWORD PTR [r12+264], rax + sbb r9, QWORD PTR [rcx+272] + mov r10, QWORD PTR [r12+280] + mov QWORD PTR [r12+272], r9 + sbb r10, QWORD PTR [rcx+280] + mov rax, QWORD PTR [r12+288] + mov QWORD PTR [r12+280], r10 + sbb rax, QWORD PTR [rcx+288] + mov r9, QWORD PTR [r12+296] + mov QWORD PTR [r12+288], rax + sbb r9, QWORD PTR [rcx+296] + mov r10, QWORD PTR [r12+304] + mov QWORD PTR [r12+296], r9 + sbb r10, QWORD PTR [rcx+304] + mov rax, QWORD PTR [r12+312] + mov QWORD PTR [r12+304], r10 + sbb rax, QWORD PTR [rcx+312] + mov r9, QWORD PTR [r12+320] + mov QWORD PTR [r12+312], rax + sbb r9, QWORD PTR [rcx+320] + mov r10, QWORD PTR [r12+328] + mov QWORD PTR [r12+320], r9 + sbb r10, QWORD PTR [rcx+328] + mov rax, QWORD PTR [r12+336] + mov QWORD PTR [r12+328], r10 + sbb rax, QWORD PTR [rcx+336] + mov r9, QWORD PTR [r12+344] + mov QWORD PTR [r12+336], rax + sbb r9, QWORD PTR [rcx+344] + mov r10, QWORD PTR [r12+352] + mov QWORD PTR [r12+344], r9 + sbb r10, QWORD PTR [rcx+352] + mov rax, QWORD PTR [r12+360] + mov QWORD PTR [r12+352], r10 + sbb rax, QWORD PTR [rcx+360] + mov r9, QWORD PTR [r12+368] + mov QWORD PTR [r12+360], rax + sbb r9, QWORD PTR [rcx+368] + mov r10, QWORD PTR [r12+376] + mov QWORD PTR [r12+368], r9 + sbb r10, QWORD PTR [rcx+376] + mov QWORD PTR [r12+376], r10 + sbb r11, 0 + sub rsi, 192 + ; Add + mov rax, QWORD PTR [rsi] + add rax, QWORD PTR [r12] + mov r9, QWORD PTR [rsi+8] + mov QWORD PTR [rsi], rax + adc r9, QWORD PTR [r12+8] + mov r10, QWORD PTR [rsi+16] + mov QWORD PTR [rsi+8], r9 + adc r10, QWORD PTR [r12+16] + mov rax, QWORD PTR [rsi+24] + mov QWORD PTR [rsi+16], r10 + adc rax, QWORD PTR [r12+24] + mov r9, QWORD PTR [rsi+32] + mov QWORD PTR [rsi+24], rax + adc r9, QWORD PTR [r12+32] + mov r10, QWORD PTR [rsi+40] + mov QWORD PTR [rsi+32], r9 + adc r10, QWORD PTR [r12+40] + mov rax, QWORD PTR [rsi+48] + mov QWORD PTR [rsi+40], r10 + adc rax, QWORD PTR [r12+48] + mov r9, QWORD PTR [rsi+56] + mov QWORD PTR [rsi+48], rax + adc r9, QWORD PTR [r12+56] + mov r10, QWORD PTR [rsi+64] + mov QWORD PTR [rsi+56], r9 + adc r10, QWORD PTR [r12+64] + mov rax, QWORD PTR [rsi+72] + mov QWORD PTR [rsi+64], r10 + adc rax, QWORD PTR [r12+72] + mov r9, QWORD PTR [rsi+80] + mov QWORD PTR [rsi+72], rax + adc r9, QWORD PTR [r12+80] + mov r10, QWORD PTR [rsi+88] + mov QWORD PTR [rsi+80], r9 + adc r10, QWORD PTR [r12+88] + mov rax, QWORD PTR [rsi+96] + mov QWORD PTR [rsi+88], r10 + adc rax, QWORD PTR [r12+96] + mov r9, QWORD PTR [rsi+104] + mov QWORD PTR [rsi+96], rax + adc r9, QWORD PTR [r12+104] + mov r10, QWORD PTR [rsi+112] + mov QWORD PTR [rsi+104], r9 + adc r10, QWORD PTR [r12+112] + mov rax, QWORD PTR [rsi+120] + mov QWORD PTR [rsi+112], r10 + adc rax, QWORD PTR [r12+120] + mov r9, QWORD PTR [rsi+128] + mov QWORD PTR [rsi+120], rax + adc r9, QWORD PTR [r12+128] + mov r10, QWORD PTR [rsi+136] + mov QWORD PTR [rsi+128], r9 + adc r10, QWORD PTR [r12+136] + mov rax, QWORD PTR [rsi+144] + mov QWORD PTR [rsi+136], r10 + adc rax, QWORD PTR [r12+144] + mov r9, QWORD PTR [rsi+152] + mov QWORD PTR [rsi+144], rax + adc r9, QWORD PTR [r12+152] + mov r10, QWORD PTR [rsi+160] + mov QWORD PTR [rsi+152], r9 + adc r10, QWORD PTR [r12+160] + mov rax, QWORD PTR [rsi+168] + mov QWORD PTR [rsi+160], r10 + adc rax, QWORD PTR [r12+168] + mov r9, QWORD PTR [rsi+176] + mov QWORD PTR [rsi+168], rax + adc r9, QWORD PTR [r12+176] + mov r10, QWORD PTR [rsi+184] + mov QWORD PTR [rsi+176], r9 + adc r10, QWORD PTR [r12+184] + mov rax, QWORD PTR [rsi+192] + mov QWORD PTR [rsi+184], r10 + adc rax, QWORD PTR [r12+192] + mov r9, QWORD PTR [rsi+200] + mov QWORD PTR [rsi+192], rax + adc r9, QWORD PTR [r12+200] + mov r10, QWORD PTR [rsi+208] + mov QWORD PTR [rsi+200], r9 + adc r10, QWORD PTR [r12+208] + mov rax, QWORD PTR [rsi+216] + mov QWORD PTR [rsi+208], r10 + adc rax, QWORD PTR [r12+216] + mov r9, QWORD PTR [rsi+224] + mov QWORD PTR [rsi+216], rax + adc r9, QWORD PTR [r12+224] + mov r10, QWORD PTR [rsi+232] + mov QWORD PTR [rsi+224], r9 + adc r10, QWORD PTR [r12+232] + mov rax, QWORD PTR [rsi+240] + mov QWORD PTR [rsi+232], r10 + adc rax, QWORD PTR [r12+240] + mov r9, QWORD PTR [rsi+248] + mov QWORD PTR [rsi+240], rax + adc r9, QWORD PTR [r12+248] + mov r10, QWORD PTR [rsi+256] + mov QWORD PTR [rsi+248], r9 + adc r10, QWORD PTR [r12+256] + mov rax, QWORD PTR [rsi+264] + mov QWORD PTR [rsi+256], r10 + adc rax, QWORD PTR [r12+264] + mov r9, QWORD PTR [rsi+272] + mov QWORD PTR [rsi+264], rax + adc r9, QWORD PTR [r12+272] + mov r10, QWORD PTR [rsi+280] + mov QWORD PTR [rsi+272], r9 + adc r10, QWORD PTR [r12+280] + mov rax, QWORD PTR [rsi+288] + mov QWORD PTR [rsi+280], r10 + adc rax, QWORD PTR [r12+288] + mov r9, QWORD PTR [rsi+296] + mov QWORD PTR [rsi+288], rax + adc r9, QWORD PTR [r12+296] + mov r10, QWORD PTR [rsi+304] + mov QWORD PTR [rsi+296], r9 + adc r10, QWORD PTR [r12+304] + mov rax, QWORD PTR [rsi+312] + mov QWORD PTR [rsi+304], r10 + adc rax, QWORD PTR [r12+312] + mov r9, QWORD PTR [rsi+320] + mov QWORD PTR [rsi+312], rax + adc r9, QWORD PTR [r12+320] + mov r10, QWORD PTR [rsi+328] + mov QWORD PTR [rsi+320], r9 + adc r10, QWORD PTR [r12+328] + mov rax, QWORD PTR [rsi+336] + mov QWORD PTR [rsi+328], r10 + adc rax, QWORD PTR [r12+336] + mov r9, QWORD PTR [rsi+344] + mov QWORD PTR [rsi+336], rax + adc r9, QWORD PTR [r12+344] + mov r10, QWORD PTR [rsi+352] + mov QWORD PTR [rsi+344], r9 + adc r10, QWORD PTR [r12+352] + mov rax, QWORD PTR [rsi+360] + mov QWORD PTR [rsi+352], r10 + adc rax, QWORD PTR [r12+360] + mov r9, QWORD PTR [rsi+368] + mov QWORD PTR [rsi+360], rax + adc r9, QWORD PTR [r12+368] + mov r10, QWORD PTR [rsi+376] + mov QWORD PTR [rsi+368], r9 + adc r10, QWORD PTR [r12+376] + mov QWORD PTR [rsi+376], r10 + adc r11, 0 + mov QWORD PTR [rcx+576], r11 + add rsi, 192 + ; Add + mov rax, QWORD PTR [rsi] + add rax, QWORD PTR [r13] + mov r9, QWORD PTR [rsi+8] + mov QWORD PTR [rsi], rax + adc r9, QWORD PTR [r13+8] + mov r10, QWORD PTR [rsi+16] + mov QWORD PTR [rsi+8], r9 + adc r10, QWORD PTR [r13+16] + mov rax, QWORD PTR [rsi+24] + mov QWORD PTR [rsi+16], r10 + adc rax, QWORD PTR [r13+24] + mov r9, QWORD PTR [rsi+32] + mov QWORD PTR [rsi+24], rax + adc r9, QWORD PTR [r13+32] + mov r10, QWORD PTR [rsi+40] + mov QWORD PTR [rsi+32], r9 + adc r10, QWORD PTR [r13+40] + mov rax, QWORD PTR [rsi+48] + mov QWORD PTR [rsi+40], r10 + adc rax, QWORD PTR [r13+48] + mov r9, QWORD PTR [rsi+56] + mov QWORD PTR [rsi+48], rax + adc r9, QWORD PTR [r13+56] + mov r10, QWORD PTR [rsi+64] + mov QWORD PTR [rsi+56], r9 + adc r10, QWORD PTR [r13+64] + mov rax, QWORD PTR [rsi+72] + mov QWORD PTR [rsi+64], r10 + adc rax, QWORD PTR [r13+72] + mov r9, QWORD PTR [rsi+80] + mov QWORD PTR [rsi+72], rax + adc r9, QWORD PTR [r13+80] + mov r10, QWORD PTR [rsi+88] + mov QWORD PTR [rsi+80], r9 + adc r10, QWORD PTR [r13+88] + mov rax, QWORD PTR [rsi+96] + mov QWORD PTR [rsi+88], r10 + adc rax, QWORD PTR [r13+96] + mov r9, QWORD PTR [rsi+104] + mov QWORD PTR [rsi+96], rax + adc r9, QWORD PTR [r13+104] + mov r10, QWORD PTR [rsi+112] + mov QWORD PTR [rsi+104], r9 + adc r10, QWORD PTR [r13+112] + mov rax, QWORD PTR [rsi+120] + mov QWORD PTR [rsi+112], r10 + adc rax, QWORD PTR [r13+120] + mov r9, QWORD PTR [rsi+128] + mov QWORD PTR [rsi+120], rax + adc r9, QWORD PTR [r13+128] + mov r10, QWORD PTR [rsi+136] + mov QWORD PTR [rsi+128], r9 + adc r10, QWORD PTR [r13+136] + mov rax, QWORD PTR [rsi+144] + mov QWORD PTR [rsi+136], r10 + adc rax, QWORD PTR [r13+144] + mov r9, QWORD PTR [rsi+152] + mov QWORD PTR [rsi+144], rax + adc r9, QWORD PTR [r13+152] + mov r10, QWORD PTR [rsi+160] + mov QWORD PTR [rsi+152], r9 + adc r10, QWORD PTR [r13+160] + mov rax, QWORD PTR [rsi+168] + mov QWORD PTR [rsi+160], r10 + adc rax, QWORD PTR [r13+168] + mov r9, QWORD PTR [rsi+176] + mov QWORD PTR [rsi+168], rax + adc r9, QWORD PTR [r13+176] + mov r10, QWORD PTR [rsi+184] + mov QWORD PTR [rsi+176], r9 + adc r10, QWORD PTR [r13+184] + mov rax, QWORD PTR [rsi+192] + mov QWORD PTR [rsi+184], r10 + adc rax, QWORD PTR [r13+192] + mov QWORD PTR [rsi+192], rax + ; Add to zero + mov rax, QWORD PTR [r13+200] + adc rax, 0 + mov r9, QWORD PTR [r13+208] + mov QWORD PTR [rsi+200], rax + adc r9, 0 + mov r10, QWORD PTR [r13+216] + mov QWORD PTR [rsi+208], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+224] + mov QWORD PTR [rsi+216], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+232] + mov QWORD PTR [rsi+224], rax + adc r9, 0 + mov r10, QWORD PTR [r13+240] + mov QWORD PTR [rsi+232], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+248] + mov QWORD PTR [rsi+240], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+256] + mov QWORD PTR [rsi+248], rax + adc r9, 0 + mov r10, QWORD PTR [r13+264] + mov QWORD PTR [rsi+256], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+272] + mov QWORD PTR [rsi+264], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+280] + mov QWORD PTR [rsi+272], rax + adc r9, 0 + mov r10, QWORD PTR [r13+288] + mov QWORD PTR [rsi+280], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+296] + mov QWORD PTR [rsi+288], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+304] + mov QWORD PTR [rsi+296], rax + adc r9, 0 + mov r10, QWORD PTR [r13+312] + mov QWORD PTR [rsi+304], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+320] + mov QWORD PTR [rsi+312], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+328] + mov QWORD PTR [rsi+320], rax + adc r9, 0 + mov r10, QWORD PTR [r13+336] + mov QWORD PTR [rsi+328], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+344] + mov QWORD PTR [rsi+336], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+352] + mov QWORD PTR [rsi+344], rax + adc r9, 0 + mov r10, QWORD PTR [r13+360] + mov QWORD PTR [rsi+352], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+368] + mov QWORD PTR [rsi+360], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+376] + mov QWORD PTR [rsi+368], rax + adc r9, 0 + mov QWORD PTR [rsi+376], r9 + add rsp, 1192 + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_3072_mul_48 ENDP +_text ENDS +; /* Add a to a into r. (r = a + a) +; * +; * r A single precision integer. +; * a A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_3072_dbl_24 PROC + mov r8, QWORD PTR [rdx] + xor rax, rax + add r8, r8 + mov r9, QWORD PTR [rdx+8] + mov QWORD PTR [rcx], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+16] + mov QWORD PTR [rcx+8], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+24] + mov QWORD PTR [rcx+16], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+32] + mov QWORD PTR [rcx+24], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+40] + mov QWORD PTR [rcx+32], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+48] + mov QWORD PTR [rcx+40], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+56] + mov QWORD PTR [rcx+48], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+64] + mov QWORD PTR [rcx+56], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+72] + mov QWORD PTR [rcx+64], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+80] + mov QWORD PTR [rcx+72], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+88] + mov QWORD PTR [rcx+80], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+96] + mov QWORD PTR [rcx+88], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+104] + mov QWORD PTR [rcx+96], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+112] + mov QWORD PTR [rcx+104], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+120] + mov QWORD PTR [rcx+112], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+128] + mov QWORD PTR [rcx+120], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+136] + mov QWORD PTR [rcx+128], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+144] + mov QWORD PTR [rcx+136], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+152] + mov QWORD PTR [rcx+144], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+160] + mov QWORD PTR [rcx+152], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+168] + mov QWORD PTR [rcx+160], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+176] + mov QWORD PTR [rcx+168], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+184] + mov QWORD PTR [rcx+176], r8 + adc r9, r9 + mov QWORD PTR [rcx+184], r9 + adc rax, 0 + ret +sp_3072_dbl_24 ENDP +_text ENDS +; /* Square a and put result in r. (r = a * a) +; * +; * r A single precision integer. +; * a A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_3072_sqr_48 PROC + push r12 + sub rsp, 984 + mov QWORD PTR [rsp+960], rcx + mov QWORD PTR [rsp+968], rdx + lea r10, QWORD PTR [rsp+768] + lea r11, QWORD PTR [rdx+192] + ; Add + mov rax, QWORD PTR [rdx] + xor r9, r9 + add rax, QWORD PTR [r11] + mov r8, QWORD PTR [rdx+8] + mov QWORD PTR [r10], rax + adc r8, QWORD PTR [r11+8] + mov rax, QWORD PTR [rdx+16] + mov QWORD PTR [r10+8], r8 + adc rax, QWORD PTR [r11+16] + mov r8, QWORD PTR [rdx+24] + mov QWORD PTR [r10+16], rax + adc r8, QWORD PTR [r11+24] + mov rax, QWORD PTR [rdx+32] + mov QWORD PTR [r10+24], r8 + adc rax, QWORD PTR [r11+32] + mov r8, QWORD PTR [rdx+40] + mov QWORD PTR [r10+32], rax + adc r8, QWORD PTR [r11+40] + mov rax, QWORD PTR [rdx+48] + mov QWORD PTR [r10+40], r8 + adc rax, QWORD PTR [r11+48] + mov r8, QWORD PTR [rdx+56] + mov QWORD PTR [r10+48], rax + adc r8, QWORD PTR [r11+56] + mov rax, QWORD PTR [rdx+64] + mov QWORD PTR [r10+56], r8 + adc rax, QWORD PTR [r11+64] + mov r8, QWORD PTR [rdx+72] + mov QWORD PTR [r10+64], rax + adc r8, QWORD PTR [r11+72] + mov rax, QWORD PTR [rdx+80] + mov QWORD PTR [r10+72], r8 + adc rax, QWORD PTR [r11+80] + mov r8, QWORD PTR [rdx+88] + mov QWORD PTR [r10+80], rax + adc r8, QWORD PTR [r11+88] + mov rax, QWORD PTR [rdx+96] + mov QWORD PTR [r10+88], r8 + adc rax, QWORD PTR [r11+96] + mov r8, QWORD PTR [rdx+104] + mov QWORD PTR [r10+96], rax + adc r8, QWORD PTR [r11+104] + mov rax, QWORD PTR [rdx+112] + mov QWORD PTR [r10+104], r8 + adc rax, QWORD PTR [r11+112] + mov r8, QWORD PTR [rdx+120] + mov QWORD PTR [r10+112], rax + adc r8, QWORD PTR [r11+120] + mov rax, QWORD PTR [rdx+128] + mov QWORD PTR [r10+120], r8 + adc rax, QWORD PTR [r11+128] + mov r8, QWORD PTR [rdx+136] + mov QWORD PTR [r10+128], rax + adc r8, QWORD PTR [r11+136] + mov rax, QWORD PTR [rdx+144] + mov QWORD PTR [r10+136], r8 + adc rax, QWORD PTR [r11+144] + mov r8, QWORD PTR [rdx+152] + mov QWORD PTR [r10+144], rax + adc r8, QWORD PTR [r11+152] + mov rax, QWORD PTR [rdx+160] + mov QWORD PTR [r10+152], r8 + adc rax, QWORD PTR [r11+160] + mov r8, QWORD PTR [rdx+168] + mov QWORD PTR [r10+160], rax + adc r8, QWORD PTR [r11+168] + mov rax, QWORD PTR [rdx+176] + mov QWORD PTR [r10+168], r8 + adc rax, QWORD PTR [r11+176] + mov r8, QWORD PTR [rdx+184] + mov QWORD PTR [r10+176], rax + adc r8, QWORD PTR [r11+184] + mov QWORD PTR [r10+184], r8 + adc r9, 0 + mov QWORD PTR [rsp+976], r9 + mov rdx, r10 + mov rcx, rsp + call sp_3072_sqr_24 + mov rdx, QWORD PTR [rsp+968] + lea rcx, QWORD PTR [rsp+384] + add rdx, 192 + call sp_3072_sqr_24 + mov rdx, QWORD PTR [rsp+968] + mov rcx, QWORD PTR [rsp+960] + call sp_3072_sqr_24 +IFDEF _WIN64 + mov rdx, QWORD PTR [rsp+968] + mov rcx, QWORD PTR [rsp+960] +ENDIF + mov r12, QWORD PTR [rsp+976] + mov r11, rcx + lea r10, QWORD PTR [rsp+768] + mov r9, r12 + neg r12 + add r11, 384 + mov rax, QWORD PTR [r10] + mov r8, QWORD PTR [r10+8] + and rax, r12 + and r8, r12 + mov QWORD PTR [r11], rax + mov QWORD PTR [r11+8], r8 + mov rax, QWORD PTR [r10+16] + mov r8, QWORD PTR [r10+24] + and rax, r12 + and r8, r12 + mov QWORD PTR [r11+16], rax + mov QWORD PTR [r11+24], r8 + mov rax, QWORD PTR [r10+32] + mov r8, QWORD PTR [r10+40] + and rax, r12 + and r8, r12 + mov QWORD PTR [r11+32], rax + mov QWORD PTR [r11+40], r8 + mov rax, QWORD PTR [r10+48] + mov r8, QWORD PTR [r10+56] + and rax, r12 + and r8, r12 + mov QWORD PTR [r11+48], rax + mov QWORD PTR [r11+56], r8 + mov rax, QWORD PTR [r10+64] + mov r8, QWORD PTR [r10+72] + and rax, r12 + and r8, r12 + mov QWORD PTR [r11+64], rax + mov QWORD PTR [r11+72], r8 + mov rax, QWORD PTR [r10+80] + mov r8, QWORD PTR [r10+88] + and rax, r12 + and r8, r12 + mov QWORD PTR [r11+80], rax + mov QWORD PTR [r11+88], r8 + mov rax, QWORD PTR [r10+96] + mov r8, QWORD PTR [r10+104] + and rax, r12 + and r8, r12 + mov QWORD PTR [r11+96], rax + mov QWORD PTR [r11+104], r8 + mov rax, QWORD PTR [r10+112] + mov r8, QWORD PTR [r10+120] + and rax, r12 + and r8, r12 + mov QWORD PTR [r11+112], rax + mov QWORD PTR [r11+120], r8 + mov rax, QWORD PTR [r10+128] + mov r8, QWORD PTR [r10+136] + and rax, r12 + and r8, r12 + mov QWORD PTR [r11+128], rax + mov QWORD PTR [r11+136], r8 + mov rax, QWORD PTR [r10+144] + mov r8, QWORD PTR [r10+152] + and rax, r12 + and r8, r12 + mov QWORD PTR [r11+144], rax + mov QWORD PTR [r11+152], r8 + mov rax, QWORD PTR [r10+160] + mov r8, QWORD PTR [r10+168] + and rax, r12 + and r8, r12 + mov QWORD PTR [r11+160], rax + mov QWORD PTR [r11+168], r8 + mov rax, QWORD PTR [r10+176] + mov r8, QWORD PTR [r10+184] + and rax, r12 + and r8, r12 + mov QWORD PTR [r11+176], rax + mov QWORD PTR [r11+184], r8 + mov rax, QWORD PTR [r11] + add rax, rax + mov r8, QWORD PTR [r11+8] + mov QWORD PTR [r11], rax + adc r8, r8 + mov rax, QWORD PTR [r11+16] + mov QWORD PTR [r11+8], r8 + adc rax, rax + mov r8, QWORD PTR [r11+24] + mov QWORD PTR [r11+16], rax + adc r8, r8 + mov rax, QWORD PTR [r11+32] + mov QWORD PTR [r11+24], r8 + adc rax, rax + mov r8, QWORD PTR [r11+40] + mov QWORD PTR [r11+32], rax + adc r8, r8 + mov rax, QWORD PTR [r11+48] + mov QWORD PTR [r11+40], r8 + adc rax, rax + mov r8, QWORD PTR [r11+56] + mov QWORD PTR [r11+48], rax + adc r8, r8 + mov rax, QWORD PTR [r11+64] + mov QWORD PTR [r11+56], r8 + adc rax, rax + mov r8, QWORD PTR [r11+72] + mov QWORD PTR [r11+64], rax + adc r8, r8 + mov rax, QWORD PTR [r11+80] + mov QWORD PTR [r11+72], r8 + adc rax, rax + mov r8, QWORD PTR [r11+88] + mov QWORD PTR [r11+80], rax + adc r8, r8 + mov rax, QWORD PTR [r11+96] + mov QWORD PTR [r11+88], r8 + adc rax, rax + mov r8, QWORD PTR [r11+104] + mov QWORD PTR [r11+96], rax + adc r8, r8 + mov rax, QWORD PTR [r11+112] + mov QWORD PTR [r11+104], r8 + adc rax, rax + mov r8, QWORD PTR [r11+120] + mov QWORD PTR [r11+112], rax + adc r8, r8 + mov rax, QWORD PTR [r11+128] + mov QWORD PTR [r11+120], r8 + adc rax, rax + mov r8, QWORD PTR [r11+136] + mov QWORD PTR [r11+128], rax + adc r8, r8 + mov rax, QWORD PTR [r11+144] + mov QWORD PTR [r11+136], r8 + adc rax, rax + mov r8, QWORD PTR [r11+152] + mov QWORD PTR [r11+144], rax + adc r8, r8 + mov rax, QWORD PTR [r11+160] + mov QWORD PTR [r11+152], r8 + adc rax, rax + mov r8, QWORD PTR [r11+168] + mov QWORD PTR [r11+160], rax + adc r8, r8 + mov rax, QWORD PTR [r11+176] + mov QWORD PTR [r11+168], r8 + adc rax, rax + mov r8, QWORD PTR [r11+184] + mov QWORD PTR [r11+176], rax + adc r8, r8 + mov QWORD PTR [r11+184], r8 + adc r9, 0 + lea rdx, QWORD PTR [rsp+384] + mov r10, rsp + mov rax, QWORD PTR [r10] + sub rax, QWORD PTR [rdx] + mov r8, QWORD PTR [r10+8] + mov QWORD PTR [r10], rax + sbb r8, QWORD PTR [rdx+8] + mov rax, QWORD PTR [r10+16] + mov QWORD PTR [r10+8], r8 + sbb rax, QWORD PTR [rdx+16] + mov r8, QWORD PTR [r10+24] + mov QWORD PTR [r10+16], rax + sbb r8, QWORD PTR [rdx+24] + mov rax, QWORD PTR [r10+32] + mov QWORD PTR [r10+24], r8 + sbb rax, QWORD PTR [rdx+32] + mov r8, QWORD PTR [r10+40] + mov QWORD PTR [r10+32], rax + sbb r8, QWORD PTR [rdx+40] + mov rax, QWORD PTR [r10+48] + mov QWORD PTR [r10+40], r8 + sbb rax, QWORD PTR [rdx+48] + mov r8, QWORD PTR [r10+56] + mov QWORD PTR [r10+48], rax + sbb r8, QWORD PTR [rdx+56] + mov rax, QWORD PTR [r10+64] + mov QWORD PTR [r10+56], r8 + sbb rax, QWORD PTR [rdx+64] + mov r8, QWORD PTR [r10+72] + mov QWORD PTR [r10+64], rax + sbb r8, QWORD PTR [rdx+72] + mov rax, QWORD PTR [r10+80] + mov QWORD PTR [r10+72], r8 + sbb rax, QWORD PTR [rdx+80] + mov r8, QWORD PTR [r10+88] + mov QWORD PTR [r10+80], rax + sbb r8, QWORD PTR [rdx+88] + mov rax, QWORD PTR [r10+96] + mov QWORD PTR [r10+88], r8 + sbb rax, QWORD PTR [rdx+96] + mov r8, QWORD PTR [r10+104] + mov QWORD PTR [r10+96], rax + sbb r8, QWORD PTR [rdx+104] + mov rax, QWORD PTR [r10+112] + mov QWORD PTR [r10+104], r8 + sbb rax, QWORD PTR [rdx+112] + mov r8, QWORD PTR [r10+120] + mov QWORD PTR [r10+112], rax + sbb r8, QWORD PTR [rdx+120] + mov rax, QWORD PTR [r10+128] + mov QWORD PTR [r10+120], r8 + sbb rax, QWORD PTR [rdx+128] + mov r8, QWORD PTR [r10+136] + mov QWORD PTR [r10+128], rax + sbb r8, QWORD PTR [rdx+136] + mov rax, QWORD PTR [r10+144] + mov QWORD PTR [r10+136], r8 + sbb rax, QWORD PTR [rdx+144] + mov r8, QWORD PTR [r10+152] + mov QWORD PTR [r10+144], rax + sbb r8, QWORD PTR [rdx+152] + mov rax, QWORD PTR [r10+160] + mov QWORD PTR [r10+152], r8 + sbb rax, QWORD PTR [rdx+160] + mov r8, QWORD PTR [r10+168] + mov QWORD PTR [r10+160], rax + sbb r8, QWORD PTR [rdx+168] + mov rax, QWORD PTR [r10+176] + mov QWORD PTR [r10+168], r8 + sbb rax, QWORD PTR [rdx+176] + mov r8, QWORD PTR [r10+184] + mov QWORD PTR [r10+176], rax + sbb r8, QWORD PTR [rdx+184] + mov rax, QWORD PTR [r10+192] + mov QWORD PTR [r10+184], r8 + sbb rax, QWORD PTR [rdx+192] + mov r8, QWORD PTR [r10+200] + mov QWORD PTR [r10+192], rax + sbb r8, QWORD PTR [rdx+200] + mov rax, QWORD PTR [r10+208] + mov QWORD PTR [r10+200], r8 + sbb rax, QWORD PTR [rdx+208] + mov r8, QWORD PTR [r10+216] + mov QWORD PTR [r10+208], rax + sbb r8, QWORD PTR [rdx+216] + mov rax, QWORD PTR [r10+224] + mov QWORD PTR [r10+216], r8 + sbb rax, QWORD PTR [rdx+224] + mov r8, QWORD PTR [r10+232] + mov QWORD PTR [r10+224], rax + sbb r8, QWORD PTR [rdx+232] + mov rax, QWORD PTR [r10+240] + mov QWORD PTR [r10+232], r8 + sbb rax, QWORD PTR [rdx+240] + mov r8, QWORD PTR [r10+248] + mov QWORD PTR [r10+240], rax + sbb r8, QWORD PTR [rdx+248] + mov rax, QWORD PTR [r10+256] + mov QWORD PTR [r10+248], r8 + sbb rax, QWORD PTR [rdx+256] + mov r8, QWORD PTR [r10+264] + mov QWORD PTR [r10+256], rax + sbb r8, QWORD PTR [rdx+264] + mov rax, QWORD PTR [r10+272] + mov QWORD PTR [r10+264], r8 + sbb rax, QWORD PTR [rdx+272] + mov r8, QWORD PTR [r10+280] + mov QWORD PTR [r10+272], rax + sbb r8, QWORD PTR [rdx+280] + mov rax, QWORD PTR [r10+288] + mov QWORD PTR [r10+280], r8 + sbb rax, QWORD PTR [rdx+288] + mov r8, QWORD PTR [r10+296] + mov QWORD PTR [r10+288], rax + sbb r8, QWORD PTR [rdx+296] + mov rax, QWORD PTR [r10+304] + mov QWORD PTR [r10+296], r8 + sbb rax, QWORD PTR [rdx+304] + mov r8, QWORD PTR [r10+312] + mov QWORD PTR [r10+304], rax + sbb r8, QWORD PTR [rdx+312] + mov rax, QWORD PTR [r10+320] + mov QWORD PTR [r10+312], r8 + sbb rax, QWORD PTR [rdx+320] + mov r8, QWORD PTR [r10+328] + mov QWORD PTR [r10+320], rax + sbb r8, QWORD PTR [rdx+328] + mov rax, QWORD PTR [r10+336] + mov QWORD PTR [r10+328], r8 + sbb rax, QWORD PTR [rdx+336] + mov r8, QWORD PTR [r10+344] + mov QWORD PTR [r10+336], rax + sbb r8, QWORD PTR [rdx+344] + mov rax, QWORD PTR [r10+352] + mov QWORD PTR [r10+344], r8 + sbb rax, QWORD PTR [rdx+352] + mov r8, QWORD PTR [r10+360] + mov QWORD PTR [r10+352], rax + sbb r8, QWORD PTR [rdx+360] + mov rax, QWORD PTR [r10+368] + mov QWORD PTR [r10+360], r8 + sbb rax, QWORD PTR [rdx+368] + mov r8, QWORD PTR [r10+376] + mov QWORD PTR [r10+368], rax + sbb r8, QWORD PTR [rdx+376] + mov QWORD PTR [r10+376], r8 + sbb r9, 0 + mov rax, QWORD PTR [r10] + sub rax, QWORD PTR [rcx] + mov r8, QWORD PTR [r10+8] + mov QWORD PTR [r10], rax + sbb r8, QWORD PTR [rcx+8] + mov rax, QWORD PTR [r10+16] + mov QWORD PTR [r10+8], r8 + sbb rax, QWORD PTR [rcx+16] + mov r8, QWORD PTR [r10+24] + mov QWORD PTR [r10+16], rax + sbb r8, QWORD PTR [rcx+24] + mov rax, QWORD PTR [r10+32] + mov QWORD PTR [r10+24], r8 + sbb rax, QWORD PTR [rcx+32] + mov r8, QWORD PTR [r10+40] + mov QWORD PTR [r10+32], rax + sbb r8, QWORD PTR [rcx+40] + mov rax, QWORD PTR [r10+48] + mov QWORD PTR [r10+40], r8 + sbb rax, QWORD PTR [rcx+48] + mov r8, QWORD PTR [r10+56] + mov QWORD PTR [r10+48], rax + sbb r8, QWORD PTR [rcx+56] + mov rax, QWORD PTR [r10+64] + mov QWORD PTR [r10+56], r8 + sbb rax, QWORD PTR [rcx+64] + mov r8, QWORD PTR [r10+72] + mov QWORD PTR [r10+64], rax + sbb r8, QWORD PTR [rcx+72] + mov rax, QWORD PTR [r10+80] + mov QWORD PTR [r10+72], r8 + sbb rax, QWORD PTR [rcx+80] + mov r8, QWORD PTR [r10+88] + mov QWORD PTR [r10+80], rax + sbb r8, QWORD PTR [rcx+88] + mov rax, QWORD PTR [r10+96] + mov QWORD PTR [r10+88], r8 + sbb rax, QWORD PTR [rcx+96] + mov r8, QWORD PTR [r10+104] + mov QWORD PTR [r10+96], rax + sbb r8, QWORD PTR [rcx+104] + mov rax, QWORD PTR [r10+112] + mov QWORD PTR [r10+104], r8 + sbb rax, QWORD PTR [rcx+112] + mov r8, QWORD PTR [r10+120] + mov QWORD PTR [r10+112], rax + sbb r8, QWORD PTR [rcx+120] + mov rax, QWORD PTR [r10+128] + mov QWORD PTR [r10+120], r8 + sbb rax, QWORD PTR [rcx+128] + mov r8, QWORD PTR [r10+136] + mov QWORD PTR [r10+128], rax + sbb r8, QWORD PTR [rcx+136] + mov rax, QWORD PTR [r10+144] + mov QWORD PTR [r10+136], r8 + sbb rax, QWORD PTR [rcx+144] + mov r8, QWORD PTR [r10+152] + mov QWORD PTR [r10+144], rax + sbb r8, QWORD PTR [rcx+152] + mov rax, QWORD PTR [r10+160] + mov QWORD PTR [r10+152], r8 + sbb rax, QWORD PTR [rcx+160] + mov r8, QWORD PTR [r10+168] + mov QWORD PTR [r10+160], rax + sbb r8, QWORD PTR [rcx+168] + mov rax, QWORD PTR [r10+176] + mov QWORD PTR [r10+168], r8 + sbb rax, QWORD PTR [rcx+176] + mov r8, QWORD PTR [r10+184] + mov QWORD PTR [r10+176], rax + sbb r8, QWORD PTR [rcx+184] + mov rax, QWORD PTR [r10+192] + mov QWORD PTR [r10+184], r8 + sbb rax, QWORD PTR [rcx+192] + mov r8, QWORD PTR [r10+200] + mov QWORD PTR [r10+192], rax + sbb r8, QWORD PTR [rcx+200] + mov rax, QWORD PTR [r10+208] + mov QWORD PTR [r10+200], r8 + sbb rax, QWORD PTR [rcx+208] + mov r8, QWORD PTR [r10+216] + mov QWORD PTR [r10+208], rax + sbb r8, QWORD PTR [rcx+216] + mov rax, QWORD PTR [r10+224] + mov QWORD PTR [r10+216], r8 + sbb rax, QWORD PTR [rcx+224] + mov r8, QWORD PTR [r10+232] + mov QWORD PTR [r10+224], rax + sbb r8, QWORD PTR [rcx+232] + mov rax, QWORD PTR [r10+240] + mov QWORD PTR [r10+232], r8 + sbb rax, QWORD PTR [rcx+240] + mov r8, QWORD PTR [r10+248] + mov QWORD PTR [r10+240], rax + sbb r8, QWORD PTR [rcx+248] + mov rax, QWORD PTR [r10+256] + mov QWORD PTR [r10+248], r8 + sbb rax, QWORD PTR [rcx+256] + mov r8, QWORD PTR [r10+264] + mov QWORD PTR [r10+256], rax + sbb r8, QWORD PTR [rcx+264] + mov rax, QWORD PTR [r10+272] + mov QWORD PTR [r10+264], r8 + sbb rax, QWORD PTR [rcx+272] + mov r8, QWORD PTR [r10+280] + mov QWORD PTR [r10+272], rax + sbb r8, QWORD PTR [rcx+280] + mov rax, QWORD PTR [r10+288] + mov QWORD PTR [r10+280], r8 + sbb rax, QWORD PTR [rcx+288] + mov r8, QWORD PTR [r10+296] + mov QWORD PTR [r10+288], rax + sbb r8, QWORD PTR [rcx+296] + mov rax, QWORD PTR [r10+304] + mov QWORD PTR [r10+296], r8 + sbb rax, QWORD PTR [rcx+304] + mov r8, QWORD PTR [r10+312] + mov QWORD PTR [r10+304], rax + sbb r8, QWORD PTR [rcx+312] + mov rax, QWORD PTR [r10+320] + mov QWORD PTR [r10+312], r8 + sbb rax, QWORD PTR [rcx+320] + mov r8, QWORD PTR [r10+328] + mov QWORD PTR [r10+320], rax + sbb r8, QWORD PTR [rcx+328] + mov rax, QWORD PTR [r10+336] + mov QWORD PTR [r10+328], r8 + sbb rax, QWORD PTR [rcx+336] + mov r8, QWORD PTR [r10+344] + mov QWORD PTR [r10+336], rax + sbb r8, QWORD PTR [rcx+344] + mov rax, QWORD PTR [r10+352] + mov QWORD PTR [r10+344], r8 + sbb rax, QWORD PTR [rcx+352] + mov r8, QWORD PTR [r10+360] + mov QWORD PTR [r10+352], rax + sbb r8, QWORD PTR [rcx+360] + mov rax, QWORD PTR [r10+368] + mov QWORD PTR [r10+360], r8 + sbb rax, QWORD PTR [rcx+368] + mov r8, QWORD PTR [r10+376] + mov QWORD PTR [r10+368], rax + sbb r8, QWORD PTR [rcx+376] + mov QWORD PTR [r10+376], r8 + sbb r9, 0 + sub r11, 192 + ; Add in place + mov rax, QWORD PTR [r11] + add rax, QWORD PTR [r10] + mov r8, QWORD PTR [r11+8] + mov QWORD PTR [r11], rax + adc r8, QWORD PTR [r10+8] + mov rax, QWORD PTR [r11+16] + mov QWORD PTR [r11+8], r8 + adc rax, QWORD PTR [r10+16] + mov r8, QWORD PTR [r11+24] + mov QWORD PTR [r11+16], rax + adc r8, QWORD PTR [r10+24] + mov rax, QWORD PTR [r11+32] + mov QWORD PTR [r11+24], r8 + adc rax, QWORD PTR [r10+32] + mov r8, QWORD PTR [r11+40] + mov QWORD PTR [r11+32], rax + adc r8, QWORD PTR [r10+40] + mov rax, QWORD PTR [r11+48] + mov QWORD PTR [r11+40], r8 + adc rax, QWORD PTR [r10+48] + mov r8, QWORD PTR [r11+56] + mov QWORD PTR [r11+48], rax + adc r8, QWORD PTR [r10+56] + mov rax, QWORD PTR [r11+64] + mov QWORD PTR [r11+56], r8 + adc rax, QWORD PTR [r10+64] + mov r8, QWORD PTR [r11+72] + mov QWORD PTR [r11+64], rax + adc r8, QWORD PTR [r10+72] + mov rax, QWORD PTR [r11+80] + mov QWORD PTR [r11+72], r8 + adc rax, QWORD PTR [r10+80] + mov r8, QWORD PTR [r11+88] + mov QWORD PTR [r11+80], rax + adc r8, QWORD PTR [r10+88] + mov rax, QWORD PTR [r11+96] + mov QWORD PTR [r11+88], r8 + adc rax, QWORD PTR [r10+96] + mov r8, QWORD PTR [r11+104] + mov QWORD PTR [r11+96], rax + adc r8, QWORD PTR [r10+104] + mov rax, QWORD PTR [r11+112] + mov QWORD PTR [r11+104], r8 + adc rax, QWORD PTR [r10+112] + mov r8, QWORD PTR [r11+120] + mov QWORD PTR [r11+112], rax + adc r8, QWORD PTR [r10+120] + mov rax, QWORD PTR [r11+128] + mov QWORD PTR [r11+120], r8 + adc rax, QWORD PTR [r10+128] + mov r8, QWORD PTR [r11+136] + mov QWORD PTR [r11+128], rax + adc r8, QWORD PTR [r10+136] + mov rax, QWORD PTR [r11+144] + mov QWORD PTR [r11+136], r8 + adc rax, QWORD PTR [r10+144] + mov r8, QWORD PTR [r11+152] + mov QWORD PTR [r11+144], rax + adc r8, QWORD PTR [r10+152] + mov rax, QWORD PTR [r11+160] + mov QWORD PTR [r11+152], r8 + adc rax, QWORD PTR [r10+160] + mov r8, QWORD PTR [r11+168] + mov QWORD PTR [r11+160], rax + adc r8, QWORD PTR [r10+168] + mov rax, QWORD PTR [r11+176] + mov QWORD PTR [r11+168], r8 + adc rax, QWORD PTR [r10+176] + mov r8, QWORD PTR [r11+184] + mov QWORD PTR [r11+176], rax + adc r8, QWORD PTR [r10+184] + mov rax, QWORD PTR [r11+192] + mov QWORD PTR [r11+184], r8 + adc rax, QWORD PTR [r10+192] + mov r8, QWORD PTR [r11+200] + mov QWORD PTR [r11+192], rax + adc r8, QWORD PTR [r10+200] + mov rax, QWORD PTR [r11+208] + mov QWORD PTR [r11+200], r8 + adc rax, QWORD PTR [r10+208] + mov r8, QWORD PTR [r11+216] + mov QWORD PTR [r11+208], rax + adc r8, QWORD PTR [r10+216] + mov rax, QWORD PTR [r11+224] + mov QWORD PTR [r11+216], r8 + adc rax, QWORD PTR [r10+224] + mov r8, QWORD PTR [r11+232] + mov QWORD PTR [r11+224], rax + adc r8, QWORD PTR [r10+232] + mov rax, QWORD PTR [r11+240] + mov QWORD PTR [r11+232], r8 + adc rax, QWORD PTR [r10+240] + mov r8, QWORD PTR [r11+248] + mov QWORD PTR [r11+240], rax + adc r8, QWORD PTR [r10+248] + mov rax, QWORD PTR [r11+256] + mov QWORD PTR [r11+248], r8 + adc rax, QWORD PTR [r10+256] + mov r8, QWORD PTR [r11+264] + mov QWORD PTR [r11+256], rax + adc r8, QWORD PTR [r10+264] + mov rax, QWORD PTR [r11+272] + mov QWORD PTR [r11+264], r8 + adc rax, QWORD PTR [r10+272] + mov r8, QWORD PTR [r11+280] + mov QWORD PTR [r11+272], rax + adc r8, QWORD PTR [r10+280] + mov rax, QWORD PTR [r11+288] + mov QWORD PTR [r11+280], r8 + adc rax, QWORD PTR [r10+288] + mov r8, QWORD PTR [r11+296] + mov QWORD PTR [r11+288], rax + adc r8, QWORD PTR [r10+296] + mov rax, QWORD PTR [r11+304] + mov QWORD PTR [r11+296], r8 + adc rax, QWORD PTR [r10+304] + mov r8, QWORD PTR [r11+312] + mov QWORD PTR [r11+304], rax + adc r8, QWORD PTR [r10+312] + mov rax, QWORD PTR [r11+320] + mov QWORD PTR [r11+312], r8 + adc rax, QWORD PTR [r10+320] + mov r8, QWORD PTR [r11+328] + mov QWORD PTR [r11+320], rax + adc r8, QWORD PTR [r10+328] + mov rax, QWORD PTR [r11+336] + mov QWORD PTR [r11+328], r8 + adc rax, QWORD PTR [r10+336] + mov r8, QWORD PTR [r11+344] + mov QWORD PTR [r11+336], rax + adc r8, QWORD PTR [r10+344] + mov rax, QWORD PTR [r11+352] + mov QWORD PTR [r11+344], r8 + adc rax, QWORD PTR [r10+352] + mov r8, QWORD PTR [r11+360] + mov QWORD PTR [r11+352], rax + adc r8, QWORD PTR [r10+360] + mov rax, QWORD PTR [r11+368] + mov QWORD PTR [r11+360], r8 + adc rax, QWORD PTR [r10+368] + mov r8, QWORD PTR [r11+376] + mov QWORD PTR [r11+368], rax + adc r8, QWORD PTR [r10+376] + mov QWORD PTR [r11+376], r8 + adc r9, 0 + mov QWORD PTR [rcx+576], r9 + ; Add in place + mov rax, QWORD PTR [r11+192] + add rax, QWORD PTR [rdx] + mov r8, QWORD PTR [r11+200] + mov QWORD PTR [r11+192], rax + adc r8, QWORD PTR [rdx+8] + mov rax, QWORD PTR [r11+208] + mov QWORD PTR [r11+200], r8 + adc rax, QWORD PTR [rdx+16] + mov r8, QWORD PTR [r11+216] + mov QWORD PTR [r11+208], rax + adc r8, QWORD PTR [rdx+24] + mov rax, QWORD PTR [r11+224] + mov QWORD PTR [r11+216], r8 + adc rax, QWORD PTR [rdx+32] + mov r8, QWORD PTR [r11+232] + mov QWORD PTR [r11+224], rax + adc r8, QWORD PTR [rdx+40] + mov rax, QWORD PTR [r11+240] + mov QWORD PTR [r11+232], r8 + adc rax, QWORD PTR [rdx+48] + mov r8, QWORD PTR [r11+248] + mov QWORD PTR [r11+240], rax + adc r8, QWORD PTR [rdx+56] + mov rax, QWORD PTR [r11+256] + mov QWORD PTR [r11+248], r8 + adc rax, QWORD PTR [rdx+64] + mov r8, QWORD PTR [r11+264] + mov QWORD PTR [r11+256], rax + adc r8, QWORD PTR [rdx+72] + mov rax, QWORD PTR [r11+272] + mov QWORD PTR [r11+264], r8 + adc rax, QWORD PTR [rdx+80] + mov r8, QWORD PTR [r11+280] + mov QWORD PTR [r11+272], rax + adc r8, QWORD PTR [rdx+88] + mov rax, QWORD PTR [r11+288] + mov QWORD PTR [r11+280], r8 + adc rax, QWORD PTR [rdx+96] + mov r8, QWORD PTR [r11+296] + mov QWORD PTR [r11+288], rax + adc r8, QWORD PTR [rdx+104] + mov rax, QWORD PTR [r11+304] + mov QWORD PTR [r11+296], r8 + adc rax, QWORD PTR [rdx+112] + mov r8, QWORD PTR [r11+312] + mov QWORD PTR [r11+304], rax + adc r8, QWORD PTR [rdx+120] + mov rax, QWORD PTR [r11+320] + mov QWORD PTR [r11+312], r8 + adc rax, QWORD PTR [rdx+128] + mov r8, QWORD PTR [r11+328] + mov QWORD PTR [r11+320], rax + adc r8, QWORD PTR [rdx+136] + mov rax, QWORD PTR [r11+336] + mov QWORD PTR [r11+328], r8 + adc rax, QWORD PTR [rdx+144] + mov r8, QWORD PTR [r11+344] + mov QWORD PTR [r11+336], rax + adc r8, QWORD PTR [rdx+152] + mov rax, QWORD PTR [r11+352] + mov QWORD PTR [r11+344], r8 + adc rax, QWORD PTR [rdx+160] + mov r8, QWORD PTR [r11+360] + mov QWORD PTR [r11+352], rax + adc r8, QWORD PTR [rdx+168] + mov rax, QWORD PTR [r11+368] + mov QWORD PTR [r11+360], r8 + adc rax, QWORD PTR [rdx+176] + mov r8, QWORD PTR [r11+376] + mov QWORD PTR [r11+368], rax + adc r8, QWORD PTR [rdx+184] + mov rax, QWORD PTR [r11+384] + mov QWORD PTR [r11+376], r8 + adc rax, QWORD PTR [rdx+192] + mov QWORD PTR [r11+384], rax + ; Add to zero + mov rax, QWORD PTR [rdx+200] + adc rax, 0 + mov r8, QWORD PTR [rdx+208] + mov QWORD PTR [r11+392], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+216] + mov QWORD PTR [r11+400], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+224] + mov QWORD PTR [r11+408], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+232] + mov QWORD PTR [r11+416], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+240] + mov QWORD PTR [r11+424], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+248] + mov QWORD PTR [r11+432], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+256] + mov QWORD PTR [r11+440], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+264] + mov QWORD PTR [r11+448], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+272] + mov QWORD PTR [r11+456], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+280] + mov QWORD PTR [r11+464], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+288] + mov QWORD PTR [r11+472], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+296] + mov QWORD PTR [r11+480], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+304] + mov QWORD PTR [r11+488], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+312] + mov QWORD PTR [r11+496], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+320] + mov QWORD PTR [r11+504], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+328] + mov QWORD PTR [r11+512], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+336] + mov QWORD PTR [r11+520], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+344] + mov QWORD PTR [r11+528], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+352] + mov QWORD PTR [r11+536], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+360] + mov QWORD PTR [r11+544], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+368] + mov QWORD PTR [r11+552], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+376] + mov QWORD PTR [r11+560], r8 + adc rax, 0 + mov QWORD PTR [r11+568], rax + add rsp, 984 + pop r12 + ret +sp_3072_sqr_48 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Multiply a and b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_3072_mul_avx2_48 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + sub rsp, 1192 + mov QWORD PTR [rsp+1152], rcx + mov QWORD PTR [rsp+1160], rdx + mov QWORD PTR [rsp+1168], r8 + lea r12, QWORD PTR [rsp+768] + lea r14, QWORD PTR [rdx+192] + ; Add + mov rax, QWORD PTR [rdx] + xor r15, r15 + add rax, QWORD PTR [r14] + mov r9, QWORD PTR [rdx+8] + mov QWORD PTR [r12], rax + adc r9, QWORD PTR [r14+8] + mov r10, QWORD PTR [rdx+16] + mov QWORD PTR [r12+8], r9 + adc r10, QWORD PTR [r14+16] + mov rax, QWORD PTR [rdx+24] + mov QWORD PTR [r12+16], r10 + adc rax, QWORD PTR [r14+24] + mov r9, QWORD PTR [rdx+32] + mov QWORD PTR [r12+24], rax + adc r9, QWORD PTR [r14+32] + mov r10, QWORD PTR [rdx+40] + mov QWORD PTR [r12+32], r9 + adc r10, QWORD PTR [r14+40] + mov rax, QWORD PTR [rdx+48] + mov QWORD PTR [r12+40], r10 + adc rax, QWORD PTR [r14+48] + mov r9, QWORD PTR [rdx+56] + mov QWORD PTR [r12+48], rax + adc r9, QWORD PTR [r14+56] + mov r10, QWORD PTR [rdx+64] + mov QWORD PTR [r12+56], r9 + adc r10, QWORD PTR [r14+64] + mov rax, QWORD PTR [rdx+72] + mov QWORD PTR [r12+64], r10 + adc rax, QWORD PTR [r14+72] + mov r9, QWORD PTR [rdx+80] + mov QWORD PTR [r12+72], rax + adc r9, QWORD PTR [r14+80] + mov r10, QWORD PTR [rdx+88] + mov QWORD PTR [r12+80], r9 + adc r10, QWORD PTR [r14+88] + mov rax, QWORD PTR [rdx+96] + mov QWORD PTR [r12+88], r10 + adc rax, QWORD PTR [r14+96] + mov r9, QWORD PTR [rdx+104] + mov QWORD PTR [r12+96], rax + adc r9, QWORD PTR [r14+104] + mov r10, QWORD PTR [rdx+112] + mov QWORD PTR [r12+104], r9 + adc r10, QWORD PTR [r14+112] + mov rax, QWORD PTR [rdx+120] + mov QWORD PTR [r12+112], r10 + adc rax, QWORD PTR [r14+120] + mov r9, QWORD PTR [rdx+128] + mov QWORD PTR [r12+120], rax + adc r9, QWORD PTR [r14+128] + mov r10, QWORD PTR [rdx+136] + mov QWORD PTR [r12+128], r9 + adc r10, QWORD PTR [r14+136] + mov rax, QWORD PTR [rdx+144] + mov QWORD PTR [r12+136], r10 + adc rax, QWORD PTR [r14+144] + mov r9, QWORD PTR [rdx+152] + mov QWORD PTR [r12+144], rax + adc r9, QWORD PTR [r14+152] + mov r10, QWORD PTR [rdx+160] + mov QWORD PTR [r12+152], r9 + adc r10, QWORD PTR [r14+160] + mov rax, QWORD PTR [rdx+168] + mov QWORD PTR [r12+160], r10 + adc rax, QWORD PTR [r14+168] + mov r9, QWORD PTR [rdx+176] + mov QWORD PTR [r12+168], rax + adc r9, QWORD PTR [r14+176] + mov r10, QWORD PTR [rdx+184] + mov QWORD PTR [r12+176], r9 + adc r10, QWORD PTR [r14+184] + mov QWORD PTR [r12+184], r10 + adc r15, 0 + mov QWORD PTR [rsp+1176], r15 + lea r13, QWORD PTR [rsp+960] + lea r14, QWORD PTR [r8+192] + ; Add + mov rax, QWORD PTR [r8] + xor rdi, rdi + add rax, QWORD PTR [r14] + mov r9, QWORD PTR [r8+8] + mov QWORD PTR [r13], rax + adc r9, QWORD PTR [r14+8] + mov r10, QWORD PTR [r8+16] + mov QWORD PTR [r13+8], r9 + adc r10, QWORD PTR [r14+16] + mov rax, QWORD PTR [r8+24] + mov QWORD PTR [r13+16], r10 + adc rax, QWORD PTR [r14+24] + mov r9, QWORD PTR [r8+32] + mov QWORD PTR [r13+24], rax + adc r9, QWORD PTR [r14+32] + mov r10, QWORD PTR [r8+40] + mov QWORD PTR [r13+32], r9 + adc r10, QWORD PTR [r14+40] + mov rax, QWORD PTR [r8+48] + mov QWORD PTR [r13+40], r10 + adc rax, QWORD PTR [r14+48] + mov r9, QWORD PTR [r8+56] + mov QWORD PTR [r13+48], rax + adc r9, QWORD PTR [r14+56] + mov r10, QWORD PTR [r8+64] + mov QWORD PTR [r13+56], r9 + adc r10, QWORD PTR [r14+64] + mov rax, QWORD PTR [r8+72] + mov QWORD PTR [r13+64], r10 + adc rax, QWORD PTR [r14+72] + mov r9, QWORD PTR [r8+80] + mov QWORD PTR [r13+72], rax + adc r9, QWORD PTR [r14+80] + mov r10, QWORD PTR [r8+88] + mov QWORD PTR [r13+80], r9 + adc r10, QWORD PTR [r14+88] + mov rax, QWORD PTR [r8+96] + mov QWORD PTR [r13+88], r10 + adc rax, QWORD PTR [r14+96] + mov r9, QWORD PTR [r8+104] + mov QWORD PTR [r13+96], rax + adc r9, QWORD PTR [r14+104] + mov r10, QWORD PTR [r8+112] + mov QWORD PTR [r13+104], r9 + adc r10, QWORD PTR [r14+112] + mov rax, QWORD PTR [r8+120] + mov QWORD PTR [r13+112], r10 + adc rax, QWORD PTR [r14+120] + mov r9, QWORD PTR [r8+128] + mov QWORD PTR [r13+120], rax + adc r9, QWORD PTR [r14+128] + mov r10, QWORD PTR [r8+136] + mov QWORD PTR [r13+128], r9 + adc r10, QWORD PTR [r14+136] + mov rax, QWORD PTR [r8+144] + mov QWORD PTR [r13+136], r10 + adc rax, QWORD PTR [r14+144] + mov r9, QWORD PTR [r8+152] + mov QWORD PTR [r13+144], rax + adc r9, QWORD PTR [r14+152] + mov r10, QWORD PTR [r8+160] + mov QWORD PTR [r13+152], r9 + adc r10, QWORD PTR [r14+160] + mov rax, QWORD PTR [r8+168] + mov QWORD PTR [r13+160], r10 + adc rax, QWORD PTR [r14+168] + mov r9, QWORD PTR [r8+176] + mov QWORD PTR [r13+168], rax + adc r9, QWORD PTR [r14+176] + mov r10, QWORD PTR [r8+184] + mov QWORD PTR [r13+176], r9 + adc r10, QWORD PTR [r14+184] + mov QWORD PTR [r13+184], r10 + adc rdi, 0 + mov QWORD PTR [rsp+1184], rdi + mov r8, r13 + mov rdx, r12 + mov rcx, rsp + call sp_3072_mul_avx2_24 + mov r8, QWORD PTR [rsp+1168] + mov rdx, QWORD PTR [rsp+1160] + lea rcx, QWORD PTR [rsp+384] + add r8, 192 + add rdx, 192 + call sp_3072_mul_avx2_24 + mov r8, QWORD PTR [rsp+1168] + mov rdx, QWORD PTR [rsp+1160] + mov rcx, QWORD PTR [rsp+1152] + call sp_3072_mul_avx2_24 +IFDEF _WIN64 + mov r8, QWORD PTR [rsp+1168] + mov rdx, QWORD PTR [rsp+1160] + mov rcx, QWORD PTR [rsp+1152] +ENDIF + mov r15, QWORD PTR [rsp+1176] + mov rdi, QWORD PTR [rsp+1184] + mov rsi, QWORD PTR [rsp+1152] + mov r11, r15 + lea r12, QWORD PTR [rsp+768] + lea r13, QWORD PTR [rsp+960] + and r11, rdi + neg r15 + neg rdi + add rsi, 384 + mov rax, QWORD PTR [r12] + mov r9, QWORD PTR [r13] + pext rax, rax, rdi + pext r9, r9, r15 + add rax, r9 + mov r9, QWORD PTR [r12+8] + mov r10, QWORD PTR [r13+8] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi], rax + adc r9, r10 + mov r10, QWORD PTR [r12+16] + mov rax, QWORD PTR [r13+16] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+8], r9 + adc r10, rax + mov rax, QWORD PTR [r12+24] + mov r9, QWORD PTR [r13+24] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+16], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+32] + mov r10, QWORD PTR [r13+32] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+24], rax + adc r9, r10 + mov r10, QWORD PTR [r12+40] + mov rax, QWORD PTR [r13+40] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+32], r9 + adc r10, rax + mov rax, QWORD PTR [r12+48] + mov r9, QWORD PTR [r13+48] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+40], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+56] + mov r10, QWORD PTR [r13+56] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+48], rax + adc r9, r10 + mov r10, QWORD PTR [r12+64] + mov rax, QWORD PTR [r13+64] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+56], r9 + adc r10, rax + mov rax, QWORD PTR [r12+72] + mov r9, QWORD PTR [r13+72] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+64], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+80] + mov r10, QWORD PTR [r13+80] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+72], rax + adc r9, r10 + mov r10, QWORD PTR [r12+88] + mov rax, QWORD PTR [r13+88] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+80], r9 + adc r10, rax + mov rax, QWORD PTR [r12+96] + mov r9, QWORD PTR [r13+96] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+88], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+104] + mov r10, QWORD PTR [r13+104] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+96], rax + adc r9, r10 + mov r10, QWORD PTR [r12+112] + mov rax, QWORD PTR [r13+112] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+104], r9 + adc r10, rax + mov rax, QWORD PTR [r12+120] + mov r9, QWORD PTR [r13+120] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+112], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+128] + mov r10, QWORD PTR [r13+128] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+120], rax + adc r9, r10 + mov r10, QWORD PTR [r12+136] + mov rax, QWORD PTR [r13+136] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+128], r9 + adc r10, rax + mov rax, QWORD PTR [r12+144] + mov r9, QWORD PTR [r13+144] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+136], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+152] + mov r10, QWORD PTR [r13+152] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+144], rax + adc r9, r10 + mov r10, QWORD PTR [r12+160] + mov rax, QWORD PTR [r13+160] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+152], r9 + adc r10, rax + mov rax, QWORD PTR [r12+168] + mov r9, QWORD PTR [r13+168] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+160], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+176] + mov r10, QWORD PTR [r13+176] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+168], rax + adc r9, r10 + mov r10, QWORD PTR [r12+184] + mov rax, QWORD PTR [r13+184] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+176], r9 + adc r10, rax + mov QWORD PTR [rsi+184], r10 + adc r11, 0 + lea r13, QWORD PTR [rsp+384] + mov r12, rsp + mov rax, QWORD PTR [r12] + sub rax, QWORD PTR [r13] + mov r9, QWORD PTR [r12+8] + mov QWORD PTR [r12], rax + sbb r9, QWORD PTR [r13+8] + mov r10, QWORD PTR [r12+16] + mov QWORD PTR [r12+8], r9 + sbb r10, QWORD PTR [r13+16] + mov rax, QWORD PTR [r12+24] + mov QWORD PTR [r12+16], r10 + sbb rax, QWORD PTR [r13+24] + mov r9, QWORD PTR [r12+32] + mov QWORD PTR [r12+24], rax + sbb r9, QWORD PTR [r13+32] + mov r10, QWORD PTR [r12+40] + mov QWORD PTR [r12+32], r9 + sbb r10, QWORD PTR [r13+40] + mov rax, QWORD PTR [r12+48] + mov QWORD PTR [r12+40], r10 + sbb rax, QWORD PTR [r13+48] + mov r9, QWORD PTR [r12+56] + mov QWORD PTR [r12+48], rax + sbb r9, QWORD PTR [r13+56] + mov r10, QWORD PTR [r12+64] + mov QWORD PTR [r12+56], r9 + sbb r10, QWORD PTR [r13+64] + mov rax, QWORD PTR [r12+72] + mov QWORD PTR [r12+64], r10 + sbb rax, QWORD PTR [r13+72] + mov r9, QWORD PTR [r12+80] + mov QWORD PTR [r12+72], rax + sbb r9, QWORD PTR [r13+80] + mov r10, QWORD PTR [r12+88] + mov QWORD PTR [r12+80], r9 + sbb r10, QWORD PTR [r13+88] + mov rax, QWORD PTR [r12+96] + mov QWORD PTR [r12+88], r10 + sbb rax, QWORD PTR [r13+96] + mov r9, QWORD PTR [r12+104] + mov QWORD PTR [r12+96], rax + sbb r9, QWORD PTR [r13+104] + mov r10, QWORD PTR [r12+112] + mov QWORD PTR [r12+104], r9 + sbb r10, QWORD PTR [r13+112] + mov rax, QWORD PTR [r12+120] + mov QWORD PTR [r12+112], r10 + sbb rax, QWORD PTR [r13+120] + mov r9, QWORD PTR [r12+128] + mov QWORD PTR [r12+120], rax + sbb r9, QWORD PTR [r13+128] + mov r10, QWORD PTR [r12+136] + mov QWORD PTR [r12+128], r9 + sbb r10, QWORD PTR [r13+136] + mov rax, QWORD PTR [r12+144] + mov QWORD PTR [r12+136], r10 + sbb rax, QWORD PTR [r13+144] + mov r9, QWORD PTR [r12+152] + mov QWORD PTR [r12+144], rax + sbb r9, QWORD PTR [r13+152] + mov r10, QWORD PTR [r12+160] + mov QWORD PTR [r12+152], r9 + sbb r10, QWORD PTR [r13+160] + mov rax, QWORD PTR [r12+168] + mov QWORD PTR [r12+160], r10 + sbb rax, QWORD PTR [r13+168] + mov r9, QWORD PTR [r12+176] + mov QWORD PTR [r12+168], rax + sbb r9, QWORD PTR [r13+176] + mov r10, QWORD PTR [r12+184] + mov QWORD PTR [r12+176], r9 + sbb r10, QWORD PTR [r13+184] + mov rax, QWORD PTR [r12+192] + mov QWORD PTR [r12+184], r10 + sbb rax, QWORD PTR [r13+192] + mov r9, QWORD PTR [r12+200] + mov QWORD PTR [r12+192], rax + sbb r9, QWORD PTR [r13+200] + mov r10, QWORD PTR [r12+208] + mov QWORD PTR [r12+200], r9 + sbb r10, QWORD PTR [r13+208] + mov rax, QWORD PTR [r12+216] + mov QWORD PTR [r12+208], r10 + sbb rax, QWORD PTR [r13+216] + mov r9, QWORD PTR [r12+224] + mov QWORD PTR [r12+216], rax + sbb r9, QWORD PTR [r13+224] + mov r10, QWORD PTR [r12+232] + mov QWORD PTR [r12+224], r9 + sbb r10, QWORD PTR [r13+232] + mov rax, QWORD PTR [r12+240] + mov QWORD PTR [r12+232], r10 + sbb rax, QWORD PTR [r13+240] + mov r9, QWORD PTR [r12+248] + mov QWORD PTR [r12+240], rax + sbb r9, QWORD PTR [r13+248] + mov r10, QWORD PTR [r12+256] + mov QWORD PTR [r12+248], r9 + sbb r10, QWORD PTR [r13+256] + mov rax, QWORD PTR [r12+264] + mov QWORD PTR [r12+256], r10 + sbb rax, QWORD PTR [r13+264] + mov r9, QWORD PTR [r12+272] + mov QWORD PTR [r12+264], rax + sbb r9, QWORD PTR [r13+272] + mov r10, QWORD PTR [r12+280] + mov QWORD PTR [r12+272], r9 + sbb r10, QWORD PTR [r13+280] + mov rax, QWORD PTR [r12+288] + mov QWORD PTR [r12+280], r10 + sbb rax, QWORD PTR [r13+288] + mov r9, QWORD PTR [r12+296] + mov QWORD PTR [r12+288], rax + sbb r9, QWORD PTR [r13+296] + mov r10, QWORD PTR [r12+304] + mov QWORD PTR [r12+296], r9 + sbb r10, QWORD PTR [r13+304] + mov rax, QWORD PTR [r12+312] + mov QWORD PTR [r12+304], r10 + sbb rax, QWORD PTR [r13+312] + mov r9, QWORD PTR [r12+320] + mov QWORD PTR [r12+312], rax + sbb r9, QWORD PTR [r13+320] + mov r10, QWORD PTR [r12+328] + mov QWORD PTR [r12+320], r9 + sbb r10, QWORD PTR [r13+328] + mov rax, QWORD PTR [r12+336] + mov QWORD PTR [r12+328], r10 + sbb rax, QWORD PTR [r13+336] + mov r9, QWORD PTR [r12+344] + mov QWORD PTR [r12+336], rax + sbb r9, QWORD PTR [r13+344] + mov r10, QWORD PTR [r12+352] + mov QWORD PTR [r12+344], r9 + sbb r10, QWORD PTR [r13+352] + mov rax, QWORD PTR [r12+360] + mov QWORD PTR [r12+352], r10 + sbb rax, QWORD PTR [r13+360] + mov r9, QWORD PTR [r12+368] + mov QWORD PTR [r12+360], rax + sbb r9, QWORD PTR [r13+368] + mov r10, QWORD PTR [r12+376] + mov QWORD PTR [r12+368], r9 + sbb r10, QWORD PTR [r13+376] + mov QWORD PTR [r12+376], r10 + sbb r11, 0 + mov rax, QWORD PTR [r12] + sub rax, QWORD PTR [rcx] + mov r9, QWORD PTR [r12+8] + mov QWORD PTR [r12], rax + sbb r9, QWORD PTR [rcx+8] + mov r10, QWORD PTR [r12+16] + mov QWORD PTR [r12+8], r9 + sbb r10, QWORD PTR [rcx+16] + mov rax, QWORD PTR [r12+24] + mov QWORD PTR [r12+16], r10 + sbb rax, QWORD PTR [rcx+24] + mov r9, QWORD PTR [r12+32] + mov QWORD PTR [r12+24], rax + sbb r9, QWORD PTR [rcx+32] + mov r10, QWORD PTR [r12+40] + mov QWORD PTR [r12+32], r9 + sbb r10, QWORD PTR [rcx+40] + mov rax, QWORD PTR [r12+48] + mov QWORD PTR [r12+40], r10 + sbb rax, QWORD PTR [rcx+48] + mov r9, QWORD PTR [r12+56] + mov QWORD PTR [r12+48], rax + sbb r9, QWORD PTR [rcx+56] + mov r10, QWORD PTR [r12+64] + mov QWORD PTR [r12+56], r9 + sbb r10, QWORD PTR [rcx+64] + mov rax, QWORD PTR [r12+72] + mov QWORD PTR [r12+64], r10 + sbb rax, QWORD PTR [rcx+72] + mov r9, QWORD PTR [r12+80] + mov QWORD PTR [r12+72], rax + sbb r9, QWORD PTR [rcx+80] + mov r10, QWORD PTR [r12+88] + mov QWORD PTR [r12+80], r9 + sbb r10, QWORD PTR [rcx+88] + mov rax, QWORD PTR [r12+96] + mov QWORD PTR [r12+88], r10 + sbb rax, QWORD PTR [rcx+96] + mov r9, QWORD PTR [r12+104] + mov QWORD PTR [r12+96], rax + sbb r9, QWORD PTR [rcx+104] + mov r10, QWORD PTR [r12+112] + mov QWORD PTR [r12+104], r9 + sbb r10, QWORD PTR [rcx+112] + mov rax, QWORD PTR [r12+120] + mov QWORD PTR [r12+112], r10 + sbb rax, QWORD PTR [rcx+120] + mov r9, QWORD PTR [r12+128] + mov QWORD PTR [r12+120], rax + sbb r9, QWORD PTR [rcx+128] + mov r10, QWORD PTR [r12+136] + mov QWORD PTR [r12+128], r9 + sbb r10, QWORD PTR [rcx+136] + mov rax, QWORD PTR [r12+144] + mov QWORD PTR [r12+136], r10 + sbb rax, QWORD PTR [rcx+144] + mov r9, QWORD PTR [r12+152] + mov QWORD PTR [r12+144], rax + sbb r9, QWORD PTR [rcx+152] + mov r10, QWORD PTR [r12+160] + mov QWORD PTR [r12+152], r9 + sbb r10, QWORD PTR [rcx+160] + mov rax, QWORD PTR [r12+168] + mov QWORD PTR [r12+160], r10 + sbb rax, QWORD PTR [rcx+168] + mov r9, QWORD PTR [r12+176] + mov QWORD PTR [r12+168], rax + sbb r9, QWORD PTR [rcx+176] + mov r10, QWORD PTR [r12+184] + mov QWORD PTR [r12+176], r9 + sbb r10, QWORD PTR [rcx+184] + mov rax, QWORD PTR [r12+192] + mov QWORD PTR [r12+184], r10 + sbb rax, QWORD PTR [rcx+192] + mov r9, QWORD PTR [r12+200] + mov QWORD PTR [r12+192], rax + sbb r9, QWORD PTR [rcx+200] + mov r10, QWORD PTR [r12+208] + mov QWORD PTR [r12+200], r9 + sbb r10, QWORD PTR [rcx+208] + mov rax, QWORD PTR [r12+216] + mov QWORD PTR [r12+208], r10 + sbb rax, QWORD PTR [rcx+216] + mov r9, QWORD PTR [r12+224] + mov QWORD PTR [r12+216], rax + sbb r9, QWORD PTR [rcx+224] + mov r10, QWORD PTR [r12+232] + mov QWORD PTR [r12+224], r9 + sbb r10, QWORD PTR [rcx+232] + mov rax, QWORD PTR [r12+240] + mov QWORD PTR [r12+232], r10 + sbb rax, QWORD PTR [rcx+240] + mov r9, QWORD PTR [r12+248] + mov QWORD PTR [r12+240], rax + sbb r9, QWORD PTR [rcx+248] + mov r10, QWORD PTR [r12+256] + mov QWORD PTR [r12+248], r9 + sbb r10, QWORD PTR [rcx+256] + mov rax, QWORD PTR [r12+264] + mov QWORD PTR [r12+256], r10 + sbb rax, QWORD PTR [rcx+264] + mov r9, QWORD PTR [r12+272] + mov QWORD PTR [r12+264], rax + sbb r9, QWORD PTR [rcx+272] + mov r10, QWORD PTR [r12+280] + mov QWORD PTR [r12+272], r9 + sbb r10, QWORD PTR [rcx+280] + mov rax, QWORD PTR [r12+288] + mov QWORD PTR [r12+280], r10 + sbb rax, QWORD PTR [rcx+288] + mov r9, QWORD PTR [r12+296] + mov QWORD PTR [r12+288], rax + sbb r9, QWORD PTR [rcx+296] + mov r10, QWORD PTR [r12+304] + mov QWORD PTR [r12+296], r9 + sbb r10, QWORD PTR [rcx+304] + mov rax, QWORD PTR [r12+312] + mov QWORD PTR [r12+304], r10 + sbb rax, QWORD PTR [rcx+312] + mov r9, QWORD PTR [r12+320] + mov QWORD PTR [r12+312], rax + sbb r9, QWORD PTR [rcx+320] + mov r10, QWORD PTR [r12+328] + mov QWORD PTR [r12+320], r9 + sbb r10, QWORD PTR [rcx+328] + mov rax, QWORD PTR [r12+336] + mov QWORD PTR [r12+328], r10 + sbb rax, QWORD PTR [rcx+336] + mov r9, QWORD PTR [r12+344] + mov QWORD PTR [r12+336], rax + sbb r9, QWORD PTR [rcx+344] + mov r10, QWORD PTR [r12+352] + mov QWORD PTR [r12+344], r9 + sbb r10, QWORD PTR [rcx+352] + mov rax, QWORD PTR [r12+360] + mov QWORD PTR [r12+352], r10 + sbb rax, QWORD PTR [rcx+360] + mov r9, QWORD PTR [r12+368] + mov QWORD PTR [r12+360], rax + sbb r9, QWORD PTR [rcx+368] + mov r10, QWORD PTR [r12+376] + mov QWORD PTR [r12+368], r9 + sbb r10, QWORD PTR [rcx+376] + mov QWORD PTR [r12+376], r10 + sbb r11, 0 + sub rsi, 192 + ; Add + mov rax, QWORD PTR [rsi] + add rax, QWORD PTR [r12] + mov r9, QWORD PTR [rsi+8] + mov QWORD PTR [rsi], rax + adc r9, QWORD PTR [r12+8] + mov r10, QWORD PTR [rsi+16] + mov QWORD PTR [rsi+8], r9 + adc r10, QWORD PTR [r12+16] + mov rax, QWORD PTR [rsi+24] + mov QWORD PTR [rsi+16], r10 + adc rax, QWORD PTR [r12+24] + mov r9, QWORD PTR [rsi+32] + mov QWORD PTR [rsi+24], rax + adc r9, QWORD PTR [r12+32] + mov r10, QWORD PTR [rsi+40] + mov QWORD PTR [rsi+32], r9 + adc r10, QWORD PTR [r12+40] + mov rax, QWORD PTR [rsi+48] + mov QWORD PTR [rsi+40], r10 + adc rax, QWORD PTR [r12+48] + mov r9, QWORD PTR [rsi+56] + mov QWORD PTR [rsi+48], rax + adc r9, QWORD PTR [r12+56] + mov r10, QWORD PTR [rsi+64] + mov QWORD PTR [rsi+56], r9 + adc r10, QWORD PTR [r12+64] + mov rax, QWORD PTR [rsi+72] + mov QWORD PTR [rsi+64], r10 + adc rax, QWORD PTR [r12+72] + mov r9, QWORD PTR [rsi+80] + mov QWORD PTR [rsi+72], rax + adc r9, QWORD PTR [r12+80] + mov r10, QWORD PTR [rsi+88] + mov QWORD PTR [rsi+80], r9 + adc r10, QWORD PTR [r12+88] + mov rax, QWORD PTR [rsi+96] + mov QWORD PTR [rsi+88], r10 + adc rax, QWORD PTR [r12+96] + mov r9, QWORD PTR [rsi+104] + mov QWORD PTR [rsi+96], rax + adc r9, QWORD PTR [r12+104] + mov r10, QWORD PTR [rsi+112] + mov QWORD PTR [rsi+104], r9 + adc r10, QWORD PTR [r12+112] + mov rax, QWORD PTR [rsi+120] + mov QWORD PTR [rsi+112], r10 + adc rax, QWORD PTR [r12+120] + mov r9, QWORD PTR [rsi+128] + mov QWORD PTR [rsi+120], rax + adc r9, QWORD PTR [r12+128] + mov r10, QWORD PTR [rsi+136] + mov QWORD PTR [rsi+128], r9 + adc r10, QWORD PTR [r12+136] + mov rax, QWORD PTR [rsi+144] + mov QWORD PTR [rsi+136], r10 + adc rax, QWORD PTR [r12+144] + mov r9, QWORD PTR [rsi+152] + mov QWORD PTR [rsi+144], rax + adc r9, QWORD PTR [r12+152] + mov r10, QWORD PTR [rsi+160] + mov QWORD PTR [rsi+152], r9 + adc r10, QWORD PTR [r12+160] + mov rax, QWORD PTR [rsi+168] + mov QWORD PTR [rsi+160], r10 + adc rax, QWORD PTR [r12+168] + mov r9, QWORD PTR [rsi+176] + mov QWORD PTR [rsi+168], rax + adc r9, QWORD PTR [r12+176] + mov r10, QWORD PTR [rsi+184] + mov QWORD PTR [rsi+176], r9 + adc r10, QWORD PTR [r12+184] + mov rax, QWORD PTR [rsi+192] + mov QWORD PTR [rsi+184], r10 + adc rax, QWORD PTR [r12+192] + mov r9, QWORD PTR [rsi+200] + mov QWORD PTR [rsi+192], rax + adc r9, QWORD PTR [r12+200] + mov r10, QWORD PTR [rsi+208] + mov QWORD PTR [rsi+200], r9 + adc r10, QWORD PTR [r12+208] + mov rax, QWORD PTR [rsi+216] + mov QWORD PTR [rsi+208], r10 + adc rax, QWORD PTR [r12+216] + mov r9, QWORD PTR [rsi+224] + mov QWORD PTR [rsi+216], rax + adc r9, QWORD PTR [r12+224] + mov r10, QWORD PTR [rsi+232] + mov QWORD PTR [rsi+224], r9 + adc r10, QWORD PTR [r12+232] + mov rax, QWORD PTR [rsi+240] + mov QWORD PTR [rsi+232], r10 + adc rax, QWORD PTR [r12+240] + mov r9, QWORD PTR [rsi+248] + mov QWORD PTR [rsi+240], rax + adc r9, QWORD PTR [r12+248] + mov r10, QWORD PTR [rsi+256] + mov QWORD PTR [rsi+248], r9 + adc r10, QWORD PTR [r12+256] + mov rax, QWORD PTR [rsi+264] + mov QWORD PTR [rsi+256], r10 + adc rax, QWORD PTR [r12+264] + mov r9, QWORD PTR [rsi+272] + mov QWORD PTR [rsi+264], rax + adc r9, QWORD PTR [r12+272] + mov r10, QWORD PTR [rsi+280] + mov QWORD PTR [rsi+272], r9 + adc r10, QWORD PTR [r12+280] + mov rax, QWORD PTR [rsi+288] + mov QWORD PTR [rsi+280], r10 + adc rax, QWORD PTR [r12+288] + mov r9, QWORD PTR [rsi+296] + mov QWORD PTR [rsi+288], rax + adc r9, QWORD PTR [r12+296] + mov r10, QWORD PTR [rsi+304] + mov QWORD PTR [rsi+296], r9 + adc r10, QWORD PTR [r12+304] + mov rax, QWORD PTR [rsi+312] + mov QWORD PTR [rsi+304], r10 + adc rax, QWORD PTR [r12+312] + mov r9, QWORD PTR [rsi+320] + mov QWORD PTR [rsi+312], rax + adc r9, QWORD PTR [r12+320] + mov r10, QWORD PTR [rsi+328] + mov QWORD PTR [rsi+320], r9 + adc r10, QWORD PTR [r12+328] + mov rax, QWORD PTR [rsi+336] + mov QWORD PTR [rsi+328], r10 + adc rax, QWORD PTR [r12+336] + mov r9, QWORD PTR [rsi+344] + mov QWORD PTR [rsi+336], rax + adc r9, QWORD PTR [r12+344] + mov r10, QWORD PTR [rsi+352] + mov QWORD PTR [rsi+344], r9 + adc r10, QWORD PTR [r12+352] + mov rax, QWORD PTR [rsi+360] + mov QWORD PTR [rsi+352], r10 + adc rax, QWORD PTR [r12+360] + mov r9, QWORD PTR [rsi+368] + mov QWORD PTR [rsi+360], rax + adc r9, QWORD PTR [r12+368] + mov r10, QWORD PTR [rsi+376] + mov QWORD PTR [rsi+368], r9 + adc r10, QWORD PTR [r12+376] + mov QWORD PTR [rsi+376], r10 + adc r11, 0 + mov QWORD PTR [rcx+576], r11 + add rsi, 192 + ; Add + mov rax, QWORD PTR [rsi] + add rax, QWORD PTR [r13] + mov r9, QWORD PTR [rsi+8] + mov QWORD PTR [rsi], rax + adc r9, QWORD PTR [r13+8] + mov r10, QWORD PTR [rsi+16] + mov QWORD PTR [rsi+8], r9 + adc r10, QWORD PTR [r13+16] + mov rax, QWORD PTR [rsi+24] + mov QWORD PTR [rsi+16], r10 + adc rax, QWORD PTR [r13+24] + mov r9, QWORD PTR [rsi+32] + mov QWORD PTR [rsi+24], rax + adc r9, QWORD PTR [r13+32] + mov r10, QWORD PTR [rsi+40] + mov QWORD PTR [rsi+32], r9 + adc r10, QWORD PTR [r13+40] + mov rax, QWORD PTR [rsi+48] + mov QWORD PTR [rsi+40], r10 + adc rax, QWORD PTR [r13+48] + mov r9, QWORD PTR [rsi+56] + mov QWORD PTR [rsi+48], rax + adc r9, QWORD PTR [r13+56] + mov r10, QWORD PTR [rsi+64] + mov QWORD PTR [rsi+56], r9 + adc r10, QWORD PTR [r13+64] + mov rax, QWORD PTR [rsi+72] + mov QWORD PTR [rsi+64], r10 + adc rax, QWORD PTR [r13+72] + mov r9, QWORD PTR [rsi+80] + mov QWORD PTR [rsi+72], rax + adc r9, QWORD PTR [r13+80] + mov r10, QWORD PTR [rsi+88] + mov QWORD PTR [rsi+80], r9 + adc r10, QWORD PTR [r13+88] + mov rax, QWORD PTR [rsi+96] + mov QWORD PTR [rsi+88], r10 + adc rax, QWORD PTR [r13+96] + mov r9, QWORD PTR [rsi+104] + mov QWORD PTR [rsi+96], rax + adc r9, QWORD PTR [r13+104] + mov r10, QWORD PTR [rsi+112] + mov QWORD PTR [rsi+104], r9 + adc r10, QWORD PTR [r13+112] + mov rax, QWORD PTR [rsi+120] + mov QWORD PTR [rsi+112], r10 + adc rax, QWORD PTR [r13+120] + mov r9, QWORD PTR [rsi+128] + mov QWORD PTR [rsi+120], rax + adc r9, QWORD PTR [r13+128] + mov r10, QWORD PTR [rsi+136] + mov QWORD PTR [rsi+128], r9 + adc r10, QWORD PTR [r13+136] + mov rax, QWORD PTR [rsi+144] + mov QWORD PTR [rsi+136], r10 + adc rax, QWORD PTR [r13+144] + mov r9, QWORD PTR [rsi+152] + mov QWORD PTR [rsi+144], rax + adc r9, QWORD PTR [r13+152] + mov r10, QWORD PTR [rsi+160] + mov QWORD PTR [rsi+152], r9 + adc r10, QWORD PTR [r13+160] + mov rax, QWORD PTR [rsi+168] + mov QWORD PTR [rsi+160], r10 + adc rax, QWORD PTR [r13+168] + mov r9, QWORD PTR [rsi+176] + mov QWORD PTR [rsi+168], rax + adc r9, QWORD PTR [r13+176] + mov r10, QWORD PTR [rsi+184] + mov QWORD PTR [rsi+176], r9 + adc r10, QWORD PTR [r13+184] + mov rax, QWORD PTR [rsi+192] + mov QWORD PTR [rsi+184], r10 + adc rax, QWORD PTR [r13+192] + mov QWORD PTR [rsi+192], rax + ; Add to zero + mov rax, QWORD PTR [r13+200] + adc rax, 0 + mov r9, QWORD PTR [r13+208] + mov QWORD PTR [rsi+200], rax + adc r9, 0 + mov r10, QWORD PTR [r13+216] + mov QWORD PTR [rsi+208], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+224] + mov QWORD PTR [rsi+216], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+232] + mov QWORD PTR [rsi+224], rax + adc r9, 0 + mov r10, QWORD PTR [r13+240] + mov QWORD PTR [rsi+232], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+248] + mov QWORD PTR [rsi+240], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+256] + mov QWORD PTR [rsi+248], rax + adc r9, 0 + mov r10, QWORD PTR [r13+264] + mov QWORD PTR [rsi+256], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+272] + mov QWORD PTR [rsi+264], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+280] + mov QWORD PTR [rsi+272], rax + adc r9, 0 + mov r10, QWORD PTR [r13+288] + mov QWORD PTR [rsi+280], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+296] + mov QWORD PTR [rsi+288], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+304] + mov QWORD PTR [rsi+296], rax + adc r9, 0 + mov r10, QWORD PTR [r13+312] + mov QWORD PTR [rsi+304], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+320] + mov QWORD PTR [rsi+312], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+328] + mov QWORD PTR [rsi+320], rax + adc r9, 0 + mov r10, QWORD PTR [r13+336] + mov QWORD PTR [rsi+328], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+344] + mov QWORD PTR [rsi+336], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+352] + mov QWORD PTR [rsi+344], rax + adc r9, 0 + mov r10, QWORD PTR [r13+360] + mov QWORD PTR [rsi+352], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+368] + mov QWORD PTR [rsi+360], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+376] + mov QWORD PTR [rsi+368], rax + adc r9, 0 + mov QWORD PTR [rsi+376], r9 + add rsp, 1192 + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_3072_mul_avx2_48 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Square a and put result in r. (r = a * a) +; * +; * r A single precision integer. +; * a A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_3072_sqr_avx2_48 PROC + push r12 + sub rsp, 984 + mov QWORD PTR [rsp+960], rcx + mov QWORD PTR [rsp+968], rdx + lea r10, QWORD PTR [rsp+768] + lea r11, QWORD PTR [rdx+192] + ; Add + mov rax, QWORD PTR [rdx] + xor r9, r9 + add rax, QWORD PTR [r11] + mov r8, QWORD PTR [rdx+8] + mov QWORD PTR [r10], rax + adc r8, QWORD PTR [r11+8] + mov rax, QWORD PTR [rdx+16] + mov QWORD PTR [r10+8], r8 + adc rax, QWORD PTR [r11+16] + mov r8, QWORD PTR [rdx+24] + mov QWORD PTR [r10+16], rax + adc r8, QWORD PTR [r11+24] + mov rax, QWORD PTR [rdx+32] + mov QWORD PTR [r10+24], r8 + adc rax, QWORD PTR [r11+32] + mov r8, QWORD PTR [rdx+40] + mov QWORD PTR [r10+32], rax + adc r8, QWORD PTR [r11+40] + mov rax, QWORD PTR [rdx+48] + mov QWORD PTR [r10+40], r8 + adc rax, QWORD PTR [r11+48] + mov r8, QWORD PTR [rdx+56] + mov QWORD PTR [r10+48], rax + adc r8, QWORD PTR [r11+56] + mov rax, QWORD PTR [rdx+64] + mov QWORD PTR [r10+56], r8 + adc rax, QWORD PTR [r11+64] + mov r8, QWORD PTR [rdx+72] + mov QWORD PTR [r10+64], rax + adc r8, QWORD PTR [r11+72] + mov rax, QWORD PTR [rdx+80] + mov QWORD PTR [r10+72], r8 + adc rax, QWORD PTR [r11+80] + mov r8, QWORD PTR [rdx+88] + mov QWORD PTR [r10+80], rax + adc r8, QWORD PTR [r11+88] + mov rax, QWORD PTR [rdx+96] + mov QWORD PTR [r10+88], r8 + adc rax, QWORD PTR [r11+96] + mov r8, QWORD PTR [rdx+104] + mov QWORD PTR [r10+96], rax + adc r8, QWORD PTR [r11+104] + mov rax, QWORD PTR [rdx+112] + mov QWORD PTR [r10+104], r8 + adc rax, QWORD PTR [r11+112] + mov r8, QWORD PTR [rdx+120] + mov QWORD PTR [r10+112], rax + adc r8, QWORD PTR [r11+120] + mov rax, QWORD PTR [rdx+128] + mov QWORD PTR [r10+120], r8 + adc rax, QWORD PTR [r11+128] + mov r8, QWORD PTR [rdx+136] + mov QWORD PTR [r10+128], rax + adc r8, QWORD PTR [r11+136] + mov rax, QWORD PTR [rdx+144] + mov QWORD PTR [r10+136], r8 + adc rax, QWORD PTR [r11+144] + mov r8, QWORD PTR [rdx+152] + mov QWORD PTR [r10+144], rax + adc r8, QWORD PTR [r11+152] + mov rax, QWORD PTR [rdx+160] + mov QWORD PTR [r10+152], r8 + adc rax, QWORD PTR [r11+160] + mov r8, QWORD PTR [rdx+168] + mov QWORD PTR [r10+160], rax + adc r8, QWORD PTR [r11+168] + mov rax, QWORD PTR [rdx+176] + mov QWORD PTR [r10+168], r8 + adc rax, QWORD PTR [r11+176] + mov r8, QWORD PTR [rdx+184] + mov QWORD PTR [r10+176], rax + adc r8, QWORD PTR [r11+184] + mov QWORD PTR [r10+184], r8 + adc r9, 0 + mov QWORD PTR [rsp+976], r9 + mov rdx, r10 + mov rcx, rsp + call sp_3072_sqr_avx2_24 + mov rdx, QWORD PTR [rsp+968] + lea rcx, QWORD PTR [rsp+384] + add rdx, 192 + call sp_3072_sqr_avx2_24 + mov rdx, QWORD PTR [rsp+968] + mov rcx, QWORD PTR [rsp+960] + call sp_3072_sqr_avx2_24 +IFDEF _WIN64 + mov rdx, QWORD PTR [rsp+968] + mov rcx, QWORD PTR [rsp+960] +ENDIF + mov r12, QWORD PTR [rsp+976] + mov r11, rcx + lea r10, QWORD PTR [rsp+768] + mov r9, r12 + neg r12 + add r11, 384 + mov rax, QWORD PTR [r10] + pext rax, rax, r12 + add rax, rax + mov r8, QWORD PTR [r10+8] + mov QWORD PTR [r11], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+16] + mov QWORD PTR [r11+8], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+24] + mov QWORD PTR [r11+16], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+32] + mov QWORD PTR [r11+24], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+40] + mov QWORD PTR [r11+32], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+48] + mov QWORD PTR [r11+40], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+56] + mov QWORD PTR [r11+48], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+64] + mov QWORD PTR [r11+56], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+72] + mov QWORD PTR [r11+64], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+80] + mov QWORD PTR [r11+72], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+88] + mov QWORD PTR [r11+80], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+96] + mov QWORD PTR [r11+88], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+104] + mov QWORD PTR [r11+96], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+112] + mov QWORD PTR [r11+104], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+120] + mov QWORD PTR [r11+112], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+128] + mov QWORD PTR [r11+120], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+136] + mov QWORD PTR [r11+128], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+144] + mov QWORD PTR [r11+136], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+152] + mov QWORD PTR [r11+144], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+160] + mov QWORD PTR [r11+152], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+168] + mov QWORD PTR [r11+160], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+176] + mov QWORD PTR [r11+168], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+184] + mov QWORD PTR [r11+176], rax + pext r8, r8, r12 + adc r8, r8 + mov QWORD PTR [r11+184], r8 + adc r9, 0 + lea rdx, QWORD PTR [rsp+384] + mov r10, rsp + mov rax, QWORD PTR [r10] + sub rax, QWORD PTR [rdx] + mov r8, QWORD PTR [r10+8] + mov QWORD PTR [r10], rax + sbb r8, QWORD PTR [rdx+8] + mov rax, QWORD PTR [r10+16] + mov QWORD PTR [r10+8], r8 + sbb rax, QWORD PTR [rdx+16] + mov r8, QWORD PTR [r10+24] + mov QWORD PTR [r10+16], rax + sbb r8, QWORD PTR [rdx+24] + mov rax, QWORD PTR [r10+32] + mov QWORD PTR [r10+24], r8 + sbb rax, QWORD PTR [rdx+32] + mov r8, QWORD PTR [r10+40] + mov QWORD PTR [r10+32], rax + sbb r8, QWORD PTR [rdx+40] + mov rax, QWORD PTR [r10+48] + mov QWORD PTR [r10+40], r8 + sbb rax, QWORD PTR [rdx+48] + mov r8, QWORD PTR [r10+56] + mov QWORD PTR [r10+48], rax + sbb r8, QWORD PTR [rdx+56] + mov rax, QWORD PTR [r10+64] + mov QWORD PTR [r10+56], r8 + sbb rax, QWORD PTR [rdx+64] + mov r8, QWORD PTR [r10+72] + mov QWORD PTR [r10+64], rax + sbb r8, QWORD PTR [rdx+72] + mov rax, QWORD PTR [r10+80] + mov QWORD PTR [r10+72], r8 + sbb rax, QWORD PTR [rdx+80] + mov r8, QWORD PTR [r10+88] + mov QWORD PTR [r10+80], rax + sbb r8, QWORD PTR [rdx+88] + mov rax, QWORD PTR [r10+96] + mov QWORD PTR [r10+88], r8 + sbb rax, QWORD PTR [rdx+96] + mov r8, QWORD PTR [r10+104] + mov QWORD PTR [r10+96], rax + sbb r8, QWORD PTR [rdx+104] + mov rax, QWORD PTR [r10+112] + mov QWORD PTR [r10+104], r8 + sbb rax, QWORD PTR [rdx+112] + mov r8, QWORD PTR [r10+120] + mov QWORD PTR [r10+112], rax + sbb r8, QWORD PTR [rdx+120] + mov rax, QWORD PTR [r10+128] + mov QWORD PTR [r10+120], r8 + sbb rax, QWORD PTR [rdx+128] + mov r8, QWORD PTR [r10+136] + mov QWORD PTR [r10+128], rax + sbb r8, QWORD PTR [rdx+136] + mov rax, QWORD PTR [r10+144] + mov QWORD PTR [r10+136], r8 + sbb rax, QWORD PTR [rdx+144] + mov r8, QWORD PTR [r10+152] + mov QWORD PTR [r10+144], rax + sbb r8, QWORD PTR [rdx+152] + mov rax, QWORD PTR [r10+160] + mov QWORD PTR [r10+152], r8 + sbb rax, QWORD PTR [rdx+160] + mov r8, QWORD PTR [r10+168] + mov QWORD PTR [r10+160], rax + sbb r8, QWORD PTR [rdx+168] + mov rax, QWORD PTR [r10+176] + mov QWORD PTR [r10+168], r8 + sbb rax, QWORD PTR [rdx+176] + mov r8, QWORD PTR [r10+184] + mov QWORD PTR [r10+176], rax + sbb r8, QWORD PTR [rdx+184] + mov rax, QWORD PTR [r10+192] + mov QWORD PTR [r10+184], r8 + sbb rax, QWORD PTR [rdx+192] + mov r8, QWORD PTR [r10+200] + mov QWORD PTR [r10+192], rax + sbb r8, QWORD PTR [rdx+200] + mov rax, QWORD PTR [r10+208] + mov QWORD PTR [r10+200], r8 + sbb rax, QWORD PTR [rdx+208] + mov r8, QWORD PTR [r10+216] + mov QWORD PTR [r10+208], rax + sbb r8, QWORD PTR [rdx+216] + mov rax, QWORD PTR [r10+224] + mov QWORD PTR [r10+216], r8 + sbb rax, QWORD PTR [rdx+224] + mov r8, QWORD PTR [r10+232] + mov QWORD PTR [r10+224], rax + sbb r8, QWORD PTR [rdx+232] + mov rax, QWORD PTR [r10+240] + mov QWORD PTR [r10+232], r8 + sbb rax, QWORD PTR [rdx+240] + mov r8, QWORD PTR [r10+248] + mov QWORD PTR [r10+240], rax + sbb r8, QWORD PTR [rdx+248] + mov rax, QWORD PTR [r10+256] + mov QWORD PTR [r10+248], r8 + sbb rax, QWORD PTR [rdx+256] + mov r8, QWORD PTR [r10+264] + mov QWORD PTR [r10+256], rax + sbb r8, QWORD PTR [rdx+264] + mov rax, QWORD PTR [r10+272] + mov QWORD PTR [r10+264], r8 + sbb rax, QWORD PTR [rdx+272] + mov r8, QWORD PTR [r10+280] + mov QWORD PTR [r10+272], rax + sbb r8, QWORD PTR [rdx+280] + mov rax, QWORD PTR [r10+288] + mov QWORD PTR [r10+280], r8 + sbb rax, QWORD PTR [rdx+288] + mov r8, QWORD PTR [r10+296] + mov QWORD PTR [r10+288], rax + sbb r8, QWORD PTR [rdx+296] + mov rax, QWORD PTR [r10+304] + mov QWORD PTR [r10+296], r8 + sbb rax, QWORD PTR [rdx+304] + mov r8, QWORD PTR [r10+312] + mov QWORD PTR [r10+304], rax + sbb r8, QWORD PTR [rdx+312] + mov rax, QWORD PTR [r10+320] + mov QWORD PTR [r10+312], r8 + sbb rax, QWORD PTR [rdx+320] + mov r8, QWORD PTR [r10+328] + mov QWORD PTR [r10+320], rax + sbb r8, QWORD PTR [rdx+328] + mov rax, QWORD PTR [r10+336] + mov QWORD PTR [r10+328], r8 + sbb rax, QWORD PTR [rdx+336] + mov r8, QWORD PTR [r10+344] + mov QWORD PTR [r10+336], rax + sbb r8, QWORD PTR [rdx+344] + mov rax, QWORD PTR [r10+352] + mov QWORD PTR [r10+344], r8 + sbb rax, QWORD PTR [rdx+352] + mov r8, QWORD PTR [r10+360] + mov QWORD PTR [r10+352], rax + sbb r8, QWORD PTR [rdx+360] + mov rax, QWORD PTR [r10+368] + mov QWORD PTR [r10+360], r8 + sbb rax, QWORD PTR [rdx+368] + mov r8, QWORD PTR [r10+376] + mov QWORD PTR [r10+368], rax + sbb r8, QWORD PTR [rdx+376] + mov QWORD PTR [r10+376], r8 + sbb r9, 0 + mov rax, QWORD PTR [r10] + sub rax, QWORD PTR [rcx] + mov r8, QWORD PTR [r10+8] + mov QWORD PTR [r10], rax + sbb r8, QWORD PTR [rcx+8] + mov rax, QWORD PTR [r10+16] + mov QWORD PTR [r10+8], r8 + sbb rax, QWORD PTR [rcx+16] + mov r8, QWORD PTR [r10+24] + mov QWORD PTR [r10+16], rax + sbb r8, QWORD PTR [rcx+24] + mov rax, QWORD PTR [r10+32] + mov QWORD PTR [r10+24], r8 + sbb rax, QWORD PTR [rcx+32] + mov r8, QWORD PTR [r10+40] + mov QWORD PTR [r10+32], rax + sbb r8, QWORD PTR [rcx+40] + mov rax, QWORD PTR [r10+48] + mov QWORD PTR [r10+40], r8 + sbb rax, QWORD PTR [rcx+48] + mov r8, QWORD PTR [r10+56] + mov QWORD PTR [r10+48], rax + sbb r8, QWORD PTR [rcx+56] + mov rax, QWORD PTR [r10+64] + mov QWORD PTR [r10+56], r8 + sbb rax, QWORD PTR [rcx+64] + mov r8, QWORD PTR [r10+72] + mov QWORD PTR [r10+64], rax + sbb r8, QWORD PTR [rcx+72] + mov rax, QWORD PTR [r10+80] + mov QWORD PTR [r10+72], r8 + sbb rax, QWORD PTR [rcx+80] + mov r8, QWORD PTR [r10+88] + mov QWORD PTR [r10+80], rax + sbb r8, QWORD PTR [rcx+88] + mov rax, QWORD PTR [r10+96] + mov QWORD PTR [r10+88], r8 + sbb rax, QWORD PTR [rcx+96] + mov r8, QWORD PTR [r10+104] + mov QWORD PTR [r10+96], rax + sbb r8, QWORD PTR [rcx+104] + mov rax, QWORD PTR [r10+112] + mov QWORD PTR [r10+104], r8 + sbb rax, QWORD PTR [rcx+112] + mov r8, QWORD PTR [r10+120] + mov QWORD PTR [r10+112], rax + sbb r8, QWORD PTR [rcx+120] + mov rax, QWORD PTR [r10+128] + mov QWORD PTR [r10+120], r8 + sbb rax, QWORD PTR [rcx+128] + mov r8, QWORD PTR [r10+136] + mov QWORD PTR [r10+128], rax + sbb r8, QWORD PTR [rcx+136] + mov rax, QWORD PTR [r10+144] + mov QWORD PTR [r10+136], r8 + sbb rax, QWORD PTR [rcx+144] + mov r8, QWORD PTR [r10+152] + mov QWORD PTR [r10+144], rax + sbb r8, QWORD PTR [rcx+152] + mov rax, QWORD PTR [r10+160] + mov QWORD PTR [r10+152], r8 + sbb rax, QWORD PTR [rcx+160] + mov r8, QWORD PTR [r10+168] + mov QWORD PTR [r10+160], rax + sbb r8, QWORD PTR [rcx+168] + mov rax, QWORD PTR [r10+176] + mov QWORD PTR [r10+168], r8 + sbb rax, QWORD PTR [rcx+176] + mov r8, QWORD PTR [r10+184] + mov QWORD PTR [r10+176], rax + sbb r8, QWORD PTR [rcx+184] + mov rax, QWORD PTR [r10+192] + mov QWORD PTR [r10+184], r8 + sbb rax, QWORD PTR [rcx+192] + mov r8, QWORD PTR [r10+200] + mov QWORD PTR [r10+192], rax + sbb r8, QWORD PTR [rcx+200] + mov rax, QWORD PTR [r10+208] + mov QWORD PTR [r10+200], r8 + sbb rax, QWORD PTR [rcx+208] + mov r8, QWORD PTR [r10+216] + mov QWORD PTR [r10+208], rax + sbb r8, QWORD PTR [rcx+216] + mov rax, QWORD PTR [r10+224] + mov QWORD PTR [r10+216], r8 + sbb rax, QWORD PTR [rcx+224] + mov r8, QWORD PTR [r10+232] + mov QWORD PTR [r10+224], rax + sbb r8, QWORD PTR [rcx+232] + mov rax, QWORD PTR [r10+240] + mov QWORD PTR [r10+232], r8 + sbb rax, QWORD PTR [rcx+240] + mov r8, QWORD PTR [r10+248] + mov QWORD PTR [r10+240], rax + sbb r8, QWORD PTR [rcx+248] + mov rax, QWORD PTR [r10+256] + mov QWORD PTR [r10+248], r8 + sbb rax, QWORD PTR [rcx+256] + mov r8, QWORD PTR [r10+264] + mov QWORD PTR [r10+256], rax + sbb r8, QWORD PTR [rcx+264] + mov rax, QWORD PTR [r10+272] + mov QWORD PTR [r10+264], r8 + sbb rax, QWORD PTR [rcx+272] + mov r8, QWORD PTR [r10+280] + mov QWORD PTR [r10+272], rax + sbb r8, QWORD PTR [rcx+280] + mov rax, QWORD PTR [r10+288] + mov QWORD PTR [r10+280], r8 + sbb rax, QWORD PTR [rcx+288] + mov r8, QWORD PTR [r10+296] + mov QWORD PTR [r10+288], rax + sbb r8, QWORD PTR [rcx+296] + mov rax, QWORD PTR [r10+304] + mov QWORD PTR [r10+296], r8 + sbb rax, QWORD PTR [rcx+304] + mov r8, QWORD PTR [r10+312] + mov QWORD PTR [r10+304], rax + sbb r8, QWORD PTR [rcx+312] + mov rax, QWORD PTR [r10+320] + mov QWORD PTR [r10+312], r8 + sbb rax, QWORD PTR [rcx+320] + mov r8, QWORD PTR [r10+328] + mov QWORD PTR [r10+320], rax + sbb r8, QWORD PTR [rcx+328] + mov rax, QWORD PTR [r10+336] + mov QWORD PTR [r10+328], r8 + sbb rax, QWORD PTR [rcx+336] + mov r8, QWORD PTR [r10+344] + mov QWORD PTR [r10+336], rax + sbb r8, QWORD PTR [rcx+344] + mov rax, QWORD PTR [r10+352] + mov QWORD PTR [r10+344], r8 + sbb rax, QWORD PTR [rcx+352] + mov r8, QWORD PTR [r10+360] + mov QWORD PTR [r10+352], rax + sbb r8, QWORD PTR [rcx+360] + mov rax, QWORD PTR [r10+368] + mov QWORD PTR [r10+360], r8 + sbb rax, QWORD PTR [rcx+368] + mov r8, QWORD PTR [r10+376] + mov QWORD PTR [r10+368], rax + sbb r8, QWORD PTR [rcx+376] + mov QWORD PTR [r10+376], r8 + sbb r9, 0 + sub r11, 192 + ; Add in place + mov rax, QWORD PTR [r11] + add rax, QWORD PTR [r10] + mov r8, QWORD PTR [r11+8] + mov QWORD PTR [r11], rax + adc r8, QWORD PTR [r10+8] + mov rax, QWORD PTR [r11+16] + mov QWORD PTR [r11+8], r8 + adc rax, QWORD PTR [r10+16] + mov r8, QWORD PTR [r11+24] + mov QWORD PTR [r11+16], rax + adc r8, QWORD PTR [r10+24] + mov rax, QWORD PTR [r11+32] + mov QWORD PTR [r11+24], r8 + adc rax, QWORD PTR [r10+32] + mov r8, QWORD PTR [r11+40] + mov QWORD PTR [r11+32], rax + adc r8, QWORD PTR [r10+40] + mov rax, QWORD PTR [r11+48] + mov QWORD PTR [r11+40], r8 + adc rax, QWORD PTR [r10+48] + mov r8, QWORD PTR [r11+56] + mov QWORD PTR [r11+48], rax + adc r8, QWORD PTR [r10+56] + mov rax, QWORD PTR [r11+64] + mov QWORD PTR [r11+56], r8 + adc rax, QWORD PTR [r10+64] + mov r8, QWORD PTR [r11+72] + mov QWORD PTR [r11+64], rax + adc r8, QWORD PTR [r10+72] + mov rax, QWORD PTR [r11+80] + mov QWORD PTR [r11+72], r8 + adc rax, QWORD PTR [r10+80] + mov r8, QWORD PTR [r11+88] + mov QWORD PTR [r11+80], rax + adc r8, QWORD PTR [r10+88] + mov rax, QWORD PTR [r11+96] + mov QWORD PTR [r11+88], r8 + adc rax, QWORD PTR [r10+96] + mov r8, QWORD PTR [r11+104] + mov QWORD PTR [r11+96], rax + adc r8, QWORD PTR [r10+104] + mov rax, QWORD PTR [r11+112] + mov QWORD PTR [r11+104], r8 + adc rax, QWORD PTR [r10+112] + mov r8, QWORD PTR [r11+120] + mov QWORD PTR [r11+112], rax + adc r8, QWORD PTR [r10+120] + mov rax, QWORD PTR [r11+128] + mov QWORD PTR [r11+120], r8 + adc rax, QWORD PTR [r10+128] + mov r8, QWORD PTR [r11+136] + mov QWORD PTR [r11+128], rax + adc r8, QWORD PTR [r10+136] + mov rax, QWORD PTR [r11+144] + mov QWORD PTR [r11+136], r8 + adc rax, QWORD PTR [r10+144] + mov r8, QWORD PTR [r11+152] + mov QWORD PTR [r11+144], rax + adc r8, QWORD PTR [r10+152] + mov rax, QWORD PTR [r11+160] + mov QWORD PTR [r11+152], r8 + adc rax, QWORD PTR [r10+160] + mov r8, QWORD PTR [r11+168] + mov QWORD PTR [r11+160], rax + adc r8, QWORD PTR [r10+168] + mov rax, QWORD PTR [r11+176] + mov QWORD PTR [r11+168], r8 + adc rax, QWORD PTR [r10+176] + mov r8, QWORD PTR [r11+184] + mov QWORD PTR [r11+176], rax + adc r8, QWORD PTR [r10+184] + mov rax, QWORD PTR [r11+192] + mov QWORD PTR [r11+184], r8 + adc rax, QWORD PTR [r10+192] + mov r8, QWORD PTR [r11+200] + mov QWORD PTR [r11+192], rax + adc r8, QWORD PTR [r10+200] + mov rax, QWORD PTR [r11+208] + mov QWORD PTR [r11+200], r8 + adc rax, QWORD PTR [r10+208] + mov r8, QWORD PTR [r11+216] + mov QWORD PTR [r11+208], rax + adc r8, QWORD PTR [r10+216] + mov rax, QWORD PTR [r11+224] + mov QWORD PTR [r11+216], r8 + adc rax, QWORD PTR [r10+224] + mov r8, QWORD PTR [r11+232] + mov QWORD PTR [r11+224], rax + adc r8, QWORD PTR [r10+232] + mov rax, QWORD PTR [r11+240] + mov QWORD PTR [r11+232], r8 + adc rax, QWORD PTR [r10+240] + mov r8, QWORD PTR [r11+248] + mov QWORD PTR [r11+240], rax + adc r8, QWORD PTR [r10+248] + mov rax, QWORD PTR [r11+256] + mov QWORD PTR [r11+248], r8 + adc rax, QWORD PTR [r10+256] + mov r8, QWORD PTR [r11+264] + mov QWORD PTR [r11+256], rax + adc r8, QWORD PTR [r10+264] + mov rax, QWORD PTR [r11+272] + mov QWORD PTR [r11+264], r8 + adc rax, QWORD PTR [r10+272] + mov r8, QWORD PTR [r11+280] + mov QWORD PTR [r11+272], rax + adc r8, QWORD PTR [r10+280] + mov rax, QWORD PTR [r11+288] + mov QWORD PTR [r11+280], r8 + adc rax, QWORD PTR [r10+288] + mov r8, QWORD PTR [r11+296] + mov QWORD PTR [r11+288], rax + adc r8, QWORD PTR [r10+296] + mov rax, QWORD PTR [r11+304] + mov QWORD PTR [r11+296], r8 + adc rax, QWORD PTR [r10+304] + mov r8, QWORD PTR [r11+312] + mov QWORD PTR [r11+304], rax + adc r8, QWORD PTR [r10+312] + mov rax, QWORD PTR [r11+320] + mov QWORD PTR [r11+312], r8 + adc rax, QWORD PTR [r10+320] + mov r8, QWORD PTR [r11+328] + mov QWORD PTR [r11+320], rax + adc r8, QWORD PTR [r10+328] + mov rax, QWORD PTR [r11+336] + mov QWORD PTR [r11+328], r8 + adc rax, QWORD PTR [r10+336] + mov r8, QWORD PTR [r11+344] + mov QWORD PTR [r11+336], rax + adc r8, QWORD PTR [r10+344] + mov rax, QWORD PTR [r11+352] + mov QWORD PTR [r11+344], r8 + adc rax, QWORD PTR [r10+352] + mov r8, QWORD PTR [r11+360] + mov QWORD PTR [r11+352], rax + adc r8, QWORD PTR [r10+360] + mov rax, QWORD PTR [r11+368] + mov QWORD PTR [r11+360], r8 + adc rax, QWORD PTR [r10+368] + mov r8, QWORD PTR [r11+376] + mov QWORD PTR [r11+368], rax + adc r8, QWORD PTR [r10+376] + mov QWORD PTR [r11+376], r8 + adc r9, 0 + mov QWORD PTR [rcx+576], r9 + ; Add in place + mov rax, QWORD PTR [r11+192] + add rax, QWORD PTR [rdx] + mov r8, QWORD PTR [r11+200] + mov QWORD PTR [r11+192], rax + adc r8, QWORD PTR [rdx+8] + mov rax, QWORD PTR [r11+208] + mov QWORD PTR [r11+200], r8 + adc rax, QWORD PTR [rdx+16] + mov r8, QWORD PTR [r11+216] + mov QWORD PTR [r11+208], rax + adc r8, QWORD PTR [rdx+24] + mov rax, QWORD PTR [r11+224] + mov QWORD PTR [r11+216], r8 + adc rax, QWORD PTR [rdx+32] + mov r8, QWORD PTR [r11+232] + mov QWORD PTR [r11+224], rax + adc r8, QWORD PTR [rdx+40] + mov rax, QWORD PTR [r11+240] + mov QWORD PTR [r11+232], r8 + adc rax, QWORD PTR [rdx+48] + mov r8, QWORD PTR [r11+248] + mov QWORD PTR [r11+240], rax + adc r8, QWORD PTR [rdx+56] + mov rax, QWORD PTR [r11+256] + mov QWORD PTR [r11+248], r8 + adc rax, QWORD PTR [rdx+64] + mov r8, QWORD PTR [r11+264] + mov QWORD PTR [r11+256], rax + adc r8, QWORD PTR [rdx+72] + mov rax, QWORD PTR [r11+272] + mov QWORD PTR [r11+264], r8 + adc rax, QWORD PTR [rdx+80] + mov r8, QWORD PTR [r11+280] + mov QWORD PTR [r11+272], rax + adc r8, QWORD PTR [rdx+88] + mov rax, QWORD PTR [r11+288] + mov QWORD PTR [r11+280], r8 + adc rax, QWORD PTR [rdx+96] + mov r8, QWORD PTR [r11+296] + mov QWORD PTR [r11+288], rax + adc r8, QWORD PTR [rdx+104] + mov rax, QWORD PTR [r11+304] + mov QWORD PTR [r11+296], r8 + adc rax, QWORD PTR [rdx+112] + mov r8, QWORD PTR [r11+312] + mov QWORD PTR [r11+304], rax + adc r8, QWORD PTR [rdx+120] + mov rax, QWORD PTR [r11+320] + mov QWORD PTR [r11+312], r8 + adc rax, QWORD PTR [rdx+128] + mov r8, QWORD PTR [r11+328] + mov QWORD PTR [r11+320], rax + adc r8, QWORD PTR [rdx+136] + mov rax, QWORD PTR [r11+336] + mov QWORD PTR [r11+328], r8 + adc rax, QWORD PTR [rdx+144] + mov r8, QWORD PTR [r11+344] + mov QWORD PTR [r11+336], rax + adc r8, QWORD PTR [rdx+152] + mov rax, QWORD PTR [r11+352] + mov QWORD PTR [r11+344], r8 + adc rax, QWORD PTR [rdx+160] + mov r8, QWORD PTR [r11+360] + mov QWORD PTR [r11+352], rax + adc r8, QWORD PTR [rdx+168] + mov rax, QWORD PTR [r11+368] + mov QWORD PTR [r11+360], r8 + adc rax, QWORD PTR [rdx+176] + mov r8, QWORD PTR [r11+376] + mov QWORD PTR [r11+368], rax + adc r8, QWORD PTR [rdx+184] + mov rax, QWORD PTR [r11+384] + mov QWORD PTR [r11+376], r8 + adc rax, QWORD PTR [rdx+192] + mov QWORD PTR [r11+384], rax + ; Add to zero + mov rax, QWORD PTR [rdx+200] + adc rax, 0 + mov r8, QWORD PTR [rdx+208] + mov QWORD PTR [r11+392], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+216] + mov QWORD PTR [r11+400], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+224] + mov QWORD PTR [r11+408], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+232] + mov QWORD PTR [r11+416], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+240] + mov QWORD PTR [r11+424], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+248] + mov QWORD PTR [r11+432], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+256] + mov QWORD PTR [r11+440], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+264] + mov QWORD PTR [r11+448], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+272] + mov QWORD PTR [r11+456], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+280] + mov QWORD PTR [r11+464], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+288] + mov QWORD PTR [r11+472], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+296] + mov QWORD PTR [r11+480], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+304] + mov QWORD PTR [r11+488], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+312] + mov QWORD PTR [r11+496], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+320] + mov QWORD PTR [r11+504], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+328] + mov QWORD PTR [r11+512], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+336] + mov QWORD PTR [r11+520], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+344] + mov QWORD PTR [r11+528], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+352] + mov QWORD PTR [r11+536], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+360] + mov QWORD PTR [r11+544], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+368] + mov QWORD PTR [r11+552], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+376] + mov QWORD PTR [r11+560], r8 + adc rax, 0 + mov QWORD PTR [r11+568], rax + add rsp, 984 + pop r12 + ret +sp_3072_sqr_avx2_48 ENDP +_text ENDS +ENDIF +; /* Mul a by digit b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision digit. +; */ +_text SEGMENT READONLY PARA +sp_3072_mul_d_48 PROC + push r12 + mov r9, rdx + ; A[0] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9] + mov r10, rax + mov r11, rdx + mov QWORD PTR [rcx], r10 + ; A[1] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+8] + add r11, rax + mov QWORD PTR [rcx+8], r11 + adc r12, rdx + adc r10, 0 + ; A[2] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+16] + add r12, rax + mov QWORD PTR [rcx+16], r12 + adc r10, rdx + adc r11, 0 + ; A[3] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+24] + add r10, rax + mov QWORD PTR [rcx+24], r10 + adc r11, rdx + adc r12, 0 + ; A[4] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+32] + add r11, rax + mov QWORD PTR [rcx+32], r11 + adc r12, rdx + adc r10, 0 + ; A[5] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+40] + add r12, rax + mov QWORD PTR [rcx+40], r12 + adc r10, rdx + adc r11, 0 + ; A[6] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+48] + add r10, rax + mov QWORD PTR [rcx+48], r10 + adc r11, rdx + adc r12, 0 + ; A[7] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+56] + add r11, rax + mov QWORD PTR [rcx+56], r11 + adc r12, rdx + adc r10, 0 + ; A[8] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+64] + add r12, rax + mov QWORD PTR [rcx+64], r12 + adc r10, rdx + adc r11, 0 + ; A[9] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+72] + add r10, rax + mov QWORD PTR [rcx+72], r10 + adc r11, rdx + adc r12, 0 + ; A[10] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+80] + add r11, rax + mov QWORD PTR [rcx+80], r11 + adc r12, rdx + adc r10, 0 + ; A[11] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+88] + add r12, rax + mov QWORD PTR [rcx+88], r12 + adc r10, rdx + adc r11, 0 + ; A[12] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+96] + add r10, rax + mov QWORD PTR [rcx+96], r10 + adc r11, rdx + adc r12, 0 + ; A[13] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+104] + add r11, rax + mov QWORD PTR [rcx+104], r11 + adc r12, rdx + adc r10, 0 + ; A[14] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+112] + add r12, rax + mov QWORD PTR [rcx+112], r12 + adc r10, rdx + adc r11, 0 + ; A[15] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+120] + add r10, rax + mov QWORD PTR [rcx+120], r10 + adc r11, rdx + adc r12, 0 + ; A[16] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+128] + add r11, rax + mov QWORD PTR [rcx+128], r11 + adc r12, rdx + adc r10, 0 + ; A[17] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+136] + add r12, rax + mov QWORD PTR [rcx+136], r12 + adc r10, rdx + adc r11, 0 + ; A[18] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+144] + add r10, rax + mov QWORD PTR [rcx+144], r10 + adc r11, rdx + adc r12, 0 + ; A[19] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+152] + add r11, rax + mov QWORD PTR [rcx+152], r11 + adc r12, rdx + adc r10, 0 + ; A[20] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+160] + add r12, rax + mov QWORD PTR [rcx+160], r12 + adc r10, rdx + adc r11, 0 + ; A[21] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+168] + add r10, rax + mov QWORD PTR [rcx+168], r10 + adc r11, rdx + adc r12, 0 + ; A[22] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+176] + add r11, rax + mov QWORD PTR [rcx+176], r11 + adc r12, rdx + adc r10, 0 + ; A[23] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+184] + add r12, rax + mov QWORD PTR [rcx+184], r12 + adc r10, rdx + adc r11, 0 + ; A[24] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+192] + add r10, rax + mov QWORD PTR [rcx+192], r10 + adc r11, rdx + adc r12, 0 + ; A[25] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+200] + add r11, rax + mov QWORD PTR [rcx+200], r11 + adc r12, rdx + adc r10, 0 + ; A[26] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+208] + add r12, rax + mov QWORD PTR [rcx+208], r12 + adc r10, rdx + adc r11, 0 + ; A[27] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+216] + add r10, rax + mov QWORD PTR [rcx+216], r10 + adc r11, rdx + adc r12, 0 + ; A[28] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+224] + add r11, rax + mov QWORD PTR [rcx+224], r11 + adc r12, rdx + adc r10, 0 + ; A[29] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+232] + add r12, rax + mov QWORD PTR [rcx+232], r12 + adc r10, rdx + adc r11, 0 + ; A[30] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+240] + add r10, rax + mov QWORD PTR [rcx+240], r10 + adc r11, rdx + adc r12, 0 + ; A[31] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+248] + add r11, rax + mov QWORD PTR [rcx+248], r11 + adc r12, rdx + adc r10, 0 + ; A[32] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+256] + add r12, rax + mov QWORD PTR [rcx+256], r12 + adc r10, rdx + adc r11, 0 + ; A[33] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+264] + add r10, rax + mov QWORD PTR [rcx+264], r10 + adc r11, rdx + adc r12, 0 + ; A[34] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+272] + add r11, rax + mov QWORD PTR [rcx+272], r11 + adc r12, rdx + adc r10, 0 + ; A[35] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+280] + add r12, rax + mov QWORD PTR [rcx+280], r12 + adc r10, rdx + adc r11, 0 + ; A[36] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+288] + add r10, rax + mov QWORD PTR [rcx+288], r10 + adc r11, rdx + adc r12, 0 + ; A[37] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+296] + add r11, rax + mov QWORD PTR [rcx+296], r11 + adc r12, rdx + adc r10, 0 + ; A[38] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+304] + add r12, rax + mov QWORD PTR [rcx+304], r12 + adc r10, rdx + adc r11, 0 + ; A[39] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+312] + add r10, rax + mov QWORD PTR [rcx+312], r10 + adc r11, rdx + adc r12, 0 + ; A[40] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+320] + add r11, rax + mov QWORD PTR [rcx+320], r11 + adc r12, rdx + adc r10, 0 + ; A[41] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+328] + add r12, rax + mov QWORD PTR [rcx+328], r12 + adc r10, rdx + adc r11, 0 + ; A[42] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+336] + add r10, rax + mov QWORD PTR [rcx+336], r10 + adc r11, rdx + adc r12, 0 + ; A[43] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+344] + add r11, rax + mov QWORD PTR [rcx+344], r11 + adc r12, rdx + adc r10, 0 + ; A[44] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+352] + add r12, rax + mov QWORD PTR [rcx+352], r12 + adc r10, rdx + adc r11, 0 + ; A[45] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+360] + add r10, rax + mov QWORD PTR [rcx+360], r10 + adc r11, rdx + adc r12, 0 + ; A[46] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+368] + add r11, rax + mov QWORD PTR [rcx+368], r11 + adc r12, rdx + adc r10, 0 + ; A[47] * B + mov rax, r8 + mul QWORD PTR [r9+376] + add r12, rax + adc r10, rdx + mov QWORD PTR [rcx+376], r12 + mov QWORD PTR [rcx+384], r10 + pop r12 + ret +sp_3072_mul_d_48 ENDP +_text ENDS +; /* Conditionally subtract b from a using the mask m. +; * m is -1 to subtract and 0 when not copying. +; * +; * r A single precision number representing condition subtract result. +; * a A single precision number to subtract from. +; * b A single precision number to subtract. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_3072_cond_sub_24 PROC + sub rsp, 192 + mov rax, 0 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp], r10 + mov QWORD PTR [rsp+8], r11 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+16], r10 + mov QWORD PTR [rsp+24], r11 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+32], r10 + mov QWORD PTR [rsp+40], r11 + mov r10, QWORD PTR [r8+48] + mov r11, QWORD PTR [r8+56] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+48], r10 + mov QWORD PTR [rsp+56], r11 + mov r10, QWORD PTR [r8+64] + mov r11, QWORD PTR [r8+72] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+64], r10 + mov QWORD PTR [rsp+72], r11 + mov r10, QWORD PTR [r8+80] + mov r11, QWORD PTR [r8+88] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+80], r10 + mov QWORD PTR [rsp+88], r11 + mov r10, QWORD PTR [r8+96] + mov r11, QWORD PTR [r8+104] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+96], r10 + mov QWORD PTR [rsp+104], r11 + mov r10, QWORD PTR [r8+112] + mov r11, QWORD PTR [r8+120] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+112], r10 + mov QWORD PTR [rsp+120], r11 + mov r10, QWORD PTR [r8+128] + mov r11, QWORD PTR [r8+136] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+128], r10 + mov QWORD PTR [rsp+136], r11 + mov r10, QWORD PTR [r8+144] + mov r11, QWORD PTR [r8+152] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+144], r10 + mov QWORD PTR [rsp+152], r11 + mov r10, QWORD PTR [r8+160] + mov r11, QWORD PTR [r8+168] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+160], r10 + mov QWORD PTR [rsp+168], r11 + mov r10, QWORD PTR [r8+176] + mov r11, QWORD PTR [r8+184] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+176], r10 + mov QWORD PTR [rsp+184], r11 + mov r10, QWORD PTR [rdx] + mov r8, QWORD PTR [rsp] + sub r10, r8 + mov r11, QWORD PTR [rdx+8] + mov r8, QWORD PTR [rsp+8] + sbb r11, r8 + mov QWORD PTR [rcx], r10 + mov r10, QWORD PTR [rdx+16] + mov r8, QWORD PTR [rsp+16] + sbb r10, r8 + mov QWORD PTR [rcx+8], r11 + mov r11, QWORD PTR [rdx+24] + mov r8, QWORD PTR [rsp+24] + sbb r11, r8 + mov QWORD PTR [rcx+16], r10 + mov r10, QWORD PTR [rdx+32] + mov r8, QWORD PTR [rsp+32] + sbb r10, r8 + mov QWORD PTR [rcx+24], r11 + mov r11, QWORD PTR [rdx+40] + mov r8, QWORD PTR [rsp+40] + sbb r11, r8 + mov QWORD PTR [rcx+32], r10 + mov r10, QWORD PTR [rdx+48] + mov r8, QWORD PTR [rsp+48] + sbb r10, r8 + mov QWORD PTR [rcx+40], r11 + mov r11, QWORD PTR [rdx+56] + mov r8, QWORD PTR [rsp+56] + sbb r11, r8 + mov QWORD PTR [rcx+48], r10 + mov r10, QWORD PTR [rdx+64] + mov r8, QWORD PTR [rsp+64] + sbb r10, r8 + mov QWORD PTR [rcx+56], r11 + mov r11, QWORD PTR [rdx+72] + mov r8, QWORD PTR [rsp+72] + sbb r11, r8 + mov QWORD PTR [rcx+64], r10 + mov r10, QWORD PTR [rdx+80] + mov r8, QWORD PTR [rsp+80] + sbb r10, r8 + mov QWORD PTR [rcx+72], r11 + mov r11, QWORD PTR [rdx+88] + mov r8, QWORD PTR [rsp+88] + sbb r11, r8 + mov QWORD PTR [rcx+80], r10 + mov r10, QWORD PTR [rdx+96] + mov r8, QWORD PTR [rsp+96] + sbb r10, r8 + mov QWORD PTR [rcx+88], r11 + mov r11, QWORD PTR [rdx+104] + mov r8, QWORD PTR [rsp+104] + sbb r11, r8 + mov QWORD PTR [rcx+96], r10 + mov r10, QWORD PTR [rdx+112] + mov r8, QWORD PTR [rsp+112] + sbb r10, r8 + mov QWORD PTR [rcx+104], r11 + mov r11, QWORD PTR [rdx+120] + mov r8, QWORD PTR [rsp+120] + sbb r11, r8 + mov QWORD PTR [rcx+112], r10 + mov r10, QWORD PTR [rdx+128] + mov r8, QWORD PTR [rsp+128] + sbb r10, r8 + mov QWORD PTR [rcx+120], r11 + mov r11, QWORD PTR [rdx+136] + mov r8, QWORD PTR [rsp+136] + sbb r11, r8 + mov QWORD PTR [rcx+128], r10 + mov r10, QWORD PTR [rdx+144] + mov r8, QWORD PTR [rsp+144] + sbb r10, r8 + mov QWORD PTR [rcx+136], r11 + mov r11, QWORD PTR [rdx+152] + mov r8, QWORD PTR [rsp+152] + sbb r11, r8 + mov QWORD PTR [rcx+144], r10 + mov r10, QWORD PTR [rdx+160] + mov r8, QWORD PTR [rsp+160] + sbb r10, r8 + mov QWORD PTR [rcx+152], r11 + mov r11, QWORD PTR [rdx+168] + mov r8, QWORD PTR [rsp+168] + sbb r11, r8 + mov QWORD PTR [rcx+160], r10 + mov r10, QWORD PTR [rdx+176] + mov r8, QWORD PTR [rsp+176] + sbb r10, r8 + mov QWORD PTR [rcx+168], r11 + mov r11, QWORD PTR [rdx+184] + mov r8, QWORD PTR [rsp+184] + sbb r11, r8 + mov QWORD PTR [rcx+176], r10 + mov QWORD PTR [rcx+184], r11 + sbb rax, 0 + add rsp, 192 + ret +sp_3072_cond_sub_24 ENDP +_text ENDS +; /* Reduce the number back to 3072 bits using Montgomery reduction. +; * +; * a A single precision number to reduce in place. +; * m The single precision number representing the modulus. +; * mp The digit representing the negative inverse of m mod 2^n. +; */ +_text SEGMENT READONLY PARA +sp_3072_mont_reduce_24 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + mov r9, rdx + xor rsi, rsi + ; i = 24 + mov r10, 24 + mov r15, QWORD PTR [rcx] + mov rdi, QWORD PTR [rcx+8] +L_3072_mont_loop_24: + ; mu = a[i] * mp + mov r13, r15 + imul r13, r8 + ; a[i+0] += m[0] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9] + add r15, rax + adc r12, rdx + ; a[i+1] += m[1] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+8] + mov r15, rdi + add r15, rax + adc r11, rdx + add r15, r12 + adc r11, 0 + ; a[i+2] += m[2] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+16] + mov rdi, QWORD PTR [rcx+16] + add rdi, rax + adc r12, rdx + add rdi, r11 + adc r12, 0 + ; a[i+3] += m[3] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+24] + mov r14, QWORD PTR [rcx+24] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+24], r14 + adc r11, 0 + ; a[i+4] += m[4] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+32] + mov r14, QWORD PTR [rcx+32] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+32], r14 + adc r12, 0 + ; a[i+5] += m[5] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+40] + mov r14, QWORD PTR [rcx+40] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+40], r14 + adc r11, 0 + ; a[i+6] += m[6] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+48] + mov r14, QWORD PTR [rcx+48] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+48], r14 + adc r12, 0 + ; a[i+7] += m[7] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+56] + mov r14, QWORD PTR [rcx+56] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+56], r14 + adc r11, 0 + ; a[i+8] += m[8] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+64] + mov r14, QWORD PTR [rcx+64] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+64], r14 + adc r12, 0 + ; a[i+9] += m[9] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+72] + mov r14, QWORD PTR [rcx+72] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+72], r14 + adc r11, 0 + ; a[i+10] += m[10] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+80] + mov r14, QWORD PTR [rcx+80] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+80], r14 + adc r12, 0 + ; a[i+11] += m[11] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+88] + mov r14, QWORD PTR [rcx+88] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+88], r14 + adc r11, 0 + ; a[i+12] += m[12] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+96] + mov r14, QWORD PTR [rcx+96] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+96], r14 + adc r12, 0 + ; a[i+13] += m[13] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+104] + mov r14, QWORD PTR [rcx+104] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+104], r14 + adc r11, 0 + ; a[i+14] += m[14] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+112] + mov r14, QWORD PTR [rcx+112] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+112], r14 + adc r12, 0 + ; a[i+15] += m[15] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+120] + mov r14, QWORD PTR [rcx+120] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+120], r14 + adc r11, 0 + ; a[i+16] += m[16] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+128] + mov r14, QWORD PTR [rcx+128] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+128], r14 + adc r12, 0 + ; a[i+17] += m[17] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+136] + mov r14, QWORD PTR [rcx+136] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+136], r14 + adc r11, 0 + ; a[i+18] += m[18] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+144] + mov r14, QWORD PTR [rcx+144] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+144], r14 + adc r12, 0 + ; a[i+19] += m[19] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+152] + mov r14, QWORD PTR [rcx+152] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+152], r14 + adc r11, 0 + ; a[i+20] += m[20] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+160] + mov r14, QWORD PTR [rcx+160] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+160], r14 + adc r12, 0 + ; a[i+21] += m[21] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+168] + mov r14, QWORD PTR [rcx+168] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+168], r14 + adc r11, 0 + ; a[i+22] += m[22] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+176] + mov r14, QWORD PTR [rcx+176] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+176], r14 + adc r12, 0 + ; a[i+23] += m[23] * mu + mov rax, r13 + mul QWORD PTR [r9+184] + mov r14, QWORD PTR [rcx+184] + add r12, rax + adc rdx, rsi + mov rsi, 0 + adc rsi, 0 + add r14, r12 + mov QWORD PTR [rcx+184], r14 + adc QWORD PTR [rcx+192], rdx + adc rsi, 0 + ; i -= 1 + add rcx, 8 + dec r10 + jnz L_3072_mont_loop_24 + mov QWORD PTR [rcx], r15 + mov QWORD PTR [rcx+8], rdi + neg rsi +IFDEF _WIN64 + mov r8, r9 + mov r9, rsi +ELSE + mov r9, rsi + mov r8, r9 +ENDIF + mov rdx, rcx + mov rcx, rcx + sub rcx, 192 + call sp_3072_cond_sub_24 + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_3072_mont_reduce_24 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Conditionally subtract b from a using the mask m. +; * m is -1 to subtract and 0 when not copying. +; * +; * r A single precision number representing condition subtract result. +; * a A single precision number to subtract from. +; * b A single precision number to subtract. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_3072_cond_sub_avx2_24 PROC + push r12 + mov rax, 0 + mov r12, QWORD PTR [r8] + mov r10, QWORD PTR [rdx] + pext r12, r12, r9 + sub r10, r12 + mov r12, QWORD PTR [r8+8] + mov r11, QWORD PTR [rdx+8] + pext r12, r12, r9 + mov QWORD PTR [rcx], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+16] + mov r12, QWORD PTR [rdx+16] + pext r10, r10, r9 + mov QWORD PTR [rcx+8], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+24] + mov r10, QWORD PTR [rdx+24] + pext r11, r11, r9 + mov QWORD PTR [rcx+16], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+32] + mov r11, QWORD PTR [rdx+32] + pext r12, r12, r9 + mov QWORD PTR [rcx+24], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+40] + mov r12, QWORD PTR [rdx+40] + pext r10, r10, r9 + mov QWORD PTR [rcx+32], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+48] + mov r10, QWORD PTR [rdx+48] + pext r11, r11, r9 + mov QWORD PTR [rcx+40], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+56] + mov r11, QWORD PTR [rdx+56] + pext r12, r12, r9 + mov QWORD PTR [rcx+48], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+64] + mov r12, QWORD PTR [rdx+64] + pext r10, r10, r9 + mov QWORD PTR [rcx+56], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+72] + mov r10, QWORD PTR [rdx+72] + pext r11, r11, r9 + mov QWORD PTR [rcx+64], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+80] + mov r11, QWORD PTR [rdx+80] + pext r12, r12, r9 + mov QWORD PTR [rcx+72], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+88] + mov r12, QWORD PTR [rdx+88] + pext r10, r10, r9 + mov QWORD PTR [rcx+80], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+96] + mov r10, QWORD PTR [rdx+96] + pext r11, r11, r9 + mov QWORD PTR [rcx+88], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+104] + mov r11, QWORD PTR [rdx+104] + pext r12, r12, r9 + mov QWORD PTR [rcx+96], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+112] + mov r12, QWORD PTR [rdx+112] + pext r10, r10, r9 + mov QWORD PTR [rcx+104], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+120] + mov r10, QWORD PTR [rdx+120] + pext r11, r11, r9 + mov QWORD PTR [rcx+112], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+128] + mov r11, QWORD PTR [rdx+128] + pext r12, r12, r9 + mov QWORD PTR [rcx+120], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+136] + mov r12, QWORD PTR [rdx+136] + pext r10, r10, r9 + mov QWORD PTR [rcx+128], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+144] + mov r10, QWORD PTR [rdx+144] + pext r11, r11, r9 + mov QWORD PTR [rcx+136], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+152] + mov r11, QWORD PTR [rdx+152] + pext r12, r12, r9 + mov QWORD PTR [rcx+144], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+160] + mov r12, QWORD PTR [rdx+160] + pext r10, r10, r9 + mov QWORD PTR [rcx+152], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+168] + mov r10, QWORD PTR [rdx+168] + pext r11, r11, r9 + mov QWORD PTR [rcx+160], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+176] + mov r11, QWORD PTR [rdx+176] + pext r12, r12, r9 + mov QWORD PTR [rcx+168], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+184] + mov r12, QWORD PTR [rdx+184] + pext r10, r10, r9 + mov QWORD PTR [rcx+176], r11 + sbb r12, r10 + mov QWORD PTR [rcx+184], r12 + sbb rax, 0 + pop r12 + ret +sp_3072_cond_sub_avx2_24 ENDP +_text ENDS +ENDIF +; /* Mul a by digit b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision digit. +; */ +_text SEGMENT READONLY PARA +sp_3072_mul_d_24 PROC + push r12 + mov r9, rdx + ; A[0] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9] + mov r10, rax + mov r11, rdx + mov QWORD PTR [rcx], r10 + ; A[1] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+8] + add r11, rax + mov QWORD PTR [rcx+8], r11 + adc r12, rdx + adc r10, 0 + ; A[2] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+16] + add r12, rax + mov QWORD PTR [rcx+16], r12 + adc r10, rdx + adc r11, 0 + ; A[3] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+24] + add r10, rax + mov QWORD PTR [rcx+24], r10 + adc r11, rdx + adc r12, 0 + ; A[4] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+32] + add r11, rax + mov QWORD PTR [rcx+32], r11 + adc r12, rdx + adc r10, 0 + ; A[5] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+40] + add r12, rax + mov QWORD PTR [rcx+40], r12 + adc r10, rdx + adc r11, 0 + ; A[6] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+48] + add r10, rax + mov QWORD PTR [rcx+48], r10 + adc r11, rdx + adc r12, 0 + ; A[7] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+56] + add r11, rax + mov QWORD PTR [rcx+56], r11 + adc r12, rdx + adc r10, 0 + ; A[8] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+64] + add r12, rax + mov QWORD PTR [rcx+64], r12 + adc r10, rdx + adc r11, 0 + ; A[9] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+72] + add r10, rax + mov QWORD PTR [rcx+72], r10 + adc r11, rdx + adc r12, 0 + ; A[10] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+80] + add r11, rax + mov QWORD PTR [rcx+80], r11 + adc r12, rdx + adc r10, 0 + ; A[11] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+88] + add r12, rax + mov QWORD PTR [rcx+88], r12 + adc r10, rdx + adc r11, 0 + ; A[12] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+96] + add r10, rax + mov QWORD PTR [rcx+96], r10 + adc r11, rdx + adc r12, 0 + ; A[13] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+104] + add r11, rax + mov QWORD PTR [rcx+104], r11 + adc r12, rdx + adc r10, 0 + ; A[14] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+112] + add r12, rax + mov QWORD PTR [rcx+112], r12 + adc r10, rdx + adc r11, 0 + ; A[15] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+120] + add r10, rax + mov QWORD PTR [rcx+120], r10 + adc r11, rdx + adc r12, 0 + ; A[16] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+128] + add r11, rax + mov QWORD PTR [rcx+128], r11 + adc r12, rdx + adc r10, 0 + ; A[17] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+136] + add r12, rax + mov QWORD PTR [rcx+136], r12 + adc r10, rdx + adc r11, 0 + ; A[18] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+144] + add r10, rax + mov QWORD PTR [rcx+144], r10 + adc r11, rdx + adc r12, 0 + ; A[19] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+152] + add r11, rax + mov QWORD PTR [rcx+152], r11 + adc r12, rdx + adc r10, 0 + ; A[20] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+160] + add r12, rax + mov QWORD PTR [rcx+160], r12 + adc r10, rdx + adc r11, 0 + ; A[21] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+168] + add r10, rax + mov QWORD PTR [rcx+168], r10 + adc r11, rdx + adc r12, 0 + ; A[22] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+176] + add r11, rax + mov QWORD PTR [rcx+176], r11 + adc r12, rdx + adc r10, 0 + ; A[23] * B + mov rax, r8 + mul QWORD PTR [r9+184] + add r12, rax + adc r10, rdx + mov QWORD PTR [rcx+184], r12 + mov QWORD PTR [rcx+192], r10 + pop r12 + ret +sp_3072_mul_d_24 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Mul a by digit b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision digit. +; */ +_text SEGMENT READONLY PARA +sp_3072_mul_d_avx2_24 PROC + push r12 + push r13 + mov rax, rdx + ; A[0] * B + mov rdx, r8 + xor r13, r13 + mulx r12, r11, QWORD PTR [rax] + mov QWORD PTR [rcx], r11 + ; A[1] * B + mulx r10, r9, QWORD PTR [rax+8] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+8], r12 + ; A[2] * B + mulx r10, r9, QWORD PTR [rax+16] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+16], r11 + ; A[3] * B + mulx r10, r9, QWORD PTR [rax+24] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+24], r12 + ; A[4] * B + mulx r10, r9, QWORD PTR [rax+32] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+32], r11 + ; A[5] * B + mulx r10, r9, QWORD PTR [rax+40] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+40], r12 + ; A[6] * B + mulx r10, r9, QWORD PTR [rax+48] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+48], r11 + ; A[7] * B + mulx r10, r9, QWORD PTR [rax+56] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+56], r12 + ; A[8] * B + mulx r10, r9, QWORD PTR [rax+64] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+64], r11 + ; A[9] * B + mulx r10, r9, QWORD PTR [rax+72] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+72], r12 + ; A[10] * B + mulx r10, r9, QWORD PTR [rax+80] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+80], r11 + ; A[11] * B + mulx r10, r9, QWORD PTR [rax+88] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+88], r12 + ; A[12] * B + mulx r10, r9, QWORD PTR [rax+96] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+96], r11 + ; A[13] * B + mulx r10, r9, QWORD PTR [rax+104] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+104], r12 + ; A[14] * B + mulx r10, r9, QWORD PTR [rax+112] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+112], r11 + ; A[15] * B + mulx r10, r9, QWORD PTR [rax+120] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+120], r12 + ; A[16] * B + mulx r10, r9, QWORD PTR [rax+128] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+128], r11 + ; A[17] * B + mulx r10, r9, QWORD PTR [rax+136] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+136], r12 + ; A[18] * B + mulx r10, r9, QWORD PTR [rax+144] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+144], r11 + ; A[19] * B + mulx r10, r9, QWORD PTR [rax+152] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+152], r12 + ; A[20] * B + mulx r10, r9, QWORD PTR [rax+160] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+160], r11 + ; A[21] * B + mulx r10, r9, QWORD PTR [rax+168] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+168], r12 + ; A[22] * B + mulx r10, r9, QWORD PTR [rax+176] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+176], r11 + ; A[23] * B + mulx r10, r9, QWORD PTR [rax+184] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + adcx r11, r13 + mov QWORD PTR [rcx+184], r12 + mov QWORD PTR [rcx+192], r11 + pop r13 + pop r12 + ret +sp_3072_mul_d_avx2_24 ENDP +_text ENDS +ENDIF +IFDEF _WIN64 +; /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) +; * +; * d1 The high order half of the number to divide. +; * d0 The low order half of the number to divide. +; * div The dividend. +; * returns the result of the division. +; */ +_text SEGMENT READONLY PARA +div_3072_word_asm_24 PROC + mov r9, rdx + mov rax, r9 + mov rdx, rcx + div r8 + ret +div_3072_word_asm_24 ENDP +_text ENDS +ENDIF +; /* Compare a with b in constant time. +; * +; * a A single precision integer. +; * b A single precision integer. +; * return -ve, 0 or +ve if a is less than, equal to or greater than b +; * respectively. +; */ +_text SEGMENT READONLY PARA +sp_3072_cmp_24 PROC + push r12 + xor r9, r9 + mov r8, -1 + mov rax, -1 + mov r10, 1 + mov r11, QWORD PTR [rcx+184] + mov r12, QWORD PTR [rdx+184] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+176] + mov r12, QWORD PTR [rdx+176] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+168] + mov r12, QWORD PTR [rdx+168] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+160] + mov r12, QWORD PTR [rdx+160] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+152] + mov r12, QWORD PTR [rdx+152] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+144] + mov r12, QWORD PTR [rdx+144] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+136] + mov r12, QWORD PTR [rdx+136] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+128] + mov r12, QWORD PTR [rdx+128] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+120] + mov r12, QWORD PTR [rdx+120] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+112] + mov r12, QWORD PTR [rdx+112] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+104] + mov r12, QWORD PTR [rdx+104] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+96] + mov r12, QWORD PTR [rdx+96] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+88] + mov r12, QWORD PTR [rdx+88] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+80] + mov r12, QWORD PTR [rdx+80] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+72] + mov r12, QWORD PTR [rdx+72] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+64] + mov r12, QWORD PTR [rdx+64] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+56] + mov r12, QWORD PTR [rdx+56] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+48] + mov r12, QWORD PTR [rdx+48] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+40] + mov r12, QWORD PTR [rdx+40] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+32] + mov r12, QWORD PTR [rdx+32] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+24] + mov r12, QWORD PTR [rdx+24] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+16] + mov r12, QWORD PTR [rdx+16] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+8] + mov r12, QWORD PTR [rdx+8] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx] + mov r12, QWORD PTR [rdx] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + xor rax, r8 + pop r12 + ret +sp_3072_cmp_24 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Reduce the number back to 3072 bits using Montgomery reduction. +; * +; * a A single precision number to reduce in place. +; * m The single precision number representing the modulus. +; * mp The digit representing the negative inverse of m mod 2^n. +; */ +_text SEGMENT READONLY PARA +sp_3072_mont_reduce_avx2_24 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + push rbx + push rbp + mov r9, rcx + mov r10, rdx + xor rbp, rbp + ; i = 24 + mov r11, 24 + mov r15, QWORD PTR [r9] + mov rdi, QWORD PTR [r9+8] + mov rsi, QWORD PTR [r9+16] + mov rbx, QWORD PTR [r9+24] + add r9, 96 + xor rbp, rbp +L_3072_mont_loop_avx2_24: + ; mu = a[i] * mp + mov rdx, r15 + mov r12, r15 + imul rdx, r8 + xor r14, r14 + ; a[i+0] += m[0] * mu + mulx rcx, rax, QWORD PTR [r10] + mov r15, rdi + adcx r12, rax + adox r15, rcx + ; a[i+1] += m[1] * mu + mulx rcx, rax, QWORD PTR [r10+8] + mov rdi, rsi + adcx r15, rax + adox rdi, rcx + ; a[i+2] += m[2] * mu + mulx rcx, rax, QWORD PTR [r10+16] + mov rsi, rbx + adcx rdi, rax + adox rsi, rcx + ; a[i+3] += m[3] * mu + mulx rcx, rax, QWORD PTR [r10+24] + mov rbx, QWORD PTR [r9+-64] + adcx rsi, rax + adox rbx, rcx + ; a[i+4] += m[4] * mu + mulx rcx, rax, QWORD PTR [r10+32] + mov r13, QWORD PTR [r9+-56] + adcx rbx, rax + adox r13, rcx + ; a[i+5] += m[5] * mu + mulx rcx, rax, QWORD PTR [r10+40] + mov r12, QWORD PTR [r9+-48] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-56], r13 + ; a[i+6] += m[6] * mu + mulx rcx, rax, QWORD PTR [r10+48] + mov r13, QWORD PTR [r9+-40] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-48], r12 + ; a[i+7] += m[7] * mu + mulx rcx, rax, QWORD PTR [r10+56] + mov r12, QWORD PTR [r9+-32] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-40], r13 + ; a[i+8] += m[8] * mu + mulx rcx, rax, QWORD PTR [r10+64] + mov r13, QWORD PTR [r9+-24] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-32], r12 + ; a[i+9] += m[9] * mu + mulx rcx, rax, QWORD PTR [r10+72] + mov r12, QWORD PTR [r9+-16] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-24], r13 + ; a[i+10] += m[10] * mu + mulx rcx, rax, QWORD PTR [r10+80] + mov r13, QWORD PTR [r9+-8] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-16], r12 + ; a[i+11] += m[11] * mu + mulx rcx, rax, QWORD PTR [r10+88] + mov r12, QWORD PTR [r9] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-8], r13 + ; a[i+12] += m[12] * mu + mulx rcx, rax, QWORD PTR [r10+96] + mov r13, QWORD PTR [r9+8] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9], r12 + ; a[i+13] += m[13] * mu + mulx rcx, rax, QWORD PTR [r10+104] + mov r12, QWORD PTR [r9+16] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+8], r13 + ; a[i+14] += m[14] * mu + mulx rcx, rax, QWORD PTR [r10+112] + mov r13, QWORD PTR [r9+24] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+16], r12 + ; a[i+15] += m[15] * mu + mulx rcx, rax, QWORD PTR [r10+120] + mov r12, QWORD PTR [r9+32] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+24], r13 + ; a[i+16] += m[16] * mu + mulx rcx, rax, QWORD PTR [r10+128] + mov r13, QWORD PTR [r9+40] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+32], r12 + ; a[i+17] += m[17] * mu + mulx rcx, rax, QWORD PTR [r10+136] + mov r12, QWORD PTR [r9+48] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+40], r13 + ; a[i+18] += m[18] * mu + mulx rcx, rax, QWORD PTR [r10+144] + mov r13, QWORD PTR [r9+56] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+48], r12 + ; a[i+19] += m[19] * mu + mulx rcx, rax, QWORD PTR [r10+152] + mov r12, QWORD PTR [r9+64] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+56], r13 + ; a[i+20] += m[20] * mu + mulx rcx, rax, QWORD PTR [r10+160] + mov r13, QWORD PTR [r9+72] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+64], r12 + ; a[i+21] += m[21] * mu + mulx rcx, rax, QWORD PTR [r10+168] + mov r12, QWORD PTR [r9+80] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+72], r13 + ; a[i+22] += m[22] * mu + mulx rcx, rax, QWORD PTR [r10+176] + mov r13, QWORD PTR [r9+88] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+80], r12 + ; a[i+23] += m[23] * mu + mulx rcx, rax, QWORD PTR [r10+184] + mov r12, QWORD PTR [r9+96] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+88], r13 + adcx r12, rbp + mov rbp, r14 + mov QWORD PTR [r9+96], r12 + adox rbp, r14 + adcx rbp, r14 + ; a += 1 + add r9, 8 + ; i -= 1 + sub r11, 1 + jnz L_3072_mont_loop_avx2_24 + sub r9, 96 + neg rbp + mov r8, r9 + sub r9, 192 + mov rcx, QWORD PTR [r10] + mov rdx, r15 + pext rcx, rcx, rbp + sub rdx, rcx + mov rcx, QWORD PTR [r10+8] + mov rax, rdi + pext rcx, rcx, rbp + mov QWORD PTR [r9], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+16] + mov rcx, rsi + pext rdx, rdx, rbp + mov QWORD PTR [r9+8], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+24] + mov rdx, rbx + pext rax, rax, rbp + mov QWORD PTR [r9+16], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+32] + mov rax, QWORD PTR [r8+32] + pext rcx, rcx, rbp + mov QWORD PTR [r9+24], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+40] + mov rcx, QWORD PTR [r8+40] + pext rdx, rdx, rbp + mov QWORD PTR [r9+32], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+48] + mov rdx, QWORD PTR [r8+48] + pext rax, rax, rbp + mov QWORD PTR [r9+40], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+56] + mov rax, QWORD PTR [r8+56] + pext rcx, rcx, rbp + mov QWORD PTR [r9+48], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+64] + mov rcx, QWORD PTR [r8+64] + pext rdx, rdx, rbp + mov QWORD PTR [r9+56], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+72] + mov rdx, QWORD PTR [r8+72] + pext rax, rax, rbp + mov QWORD PTR [r9+64], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+80] + mov rax, QWORD PTR [r8+80] + pext rcx, rcx, rbp + mov QWORD PTR [r9+72], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+88] + mov rcx, QWORD PTR [r8+88] + pext rdx, rdx, rbp + mov QWORD PTR [r9+80], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+96] + mov rdx, QWORD PTR [r8+96] + pext rax, rax, rbp + mov QWORD PTR [r9+88], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+104] + mov rax, QWORD PTR [r8+104] + pext rcx, rcx, rbp + mov QWORD PTR [r9+96], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+112] + mov rcx, QWORD PTR [r8+112] + pext rdx, rdx, rbp + mov QWORD PTR [r9+104], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+120] + mov rdx, QWORD PTR [r8+120] + pext rax, rax, rbp + mov QWORD PTR [r9+112], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+128] + mov rax, QWORD PTR [r8+128] + pext rcx, rcx, rbp + mov QWORD PTR [r9+120], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+136] + mov rcx, QWORD PTR [r8+136] + pext rdx, rdx, rbp + mov QWORD PTR [r9+128], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+144] + mov rdx, QWORD PTR [r8+144] + pext rax, rax, rbp + mov QWORD PTR [r9+136], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+152] + mov rax, QWORD PTR [r8+152] + pext rcx, rcx, rbp + mov QWORD PTR [r9+144], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+160] + mov rcx, QWORD PTR [r8+160] + pext rdx, rdx, rbp + mov QWORD PTR [r9+152], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+168] + mov rdx, QWORD PTR [r8+168] + pext rax, rax, rbp + mov QWORD PTR [r9+160], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+176] + mov rax, QWORD PTR [r8+176] + pext rcx, rcx, rbp + mov QWORD PTR [r9+168], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+184] + mov rcx, QWORD PTR [r8+184] + pext rdx, rdx, rbp + mov QWORD PTR [r9+176], rax + sbb rcx, rdx + mov QWORD PTR [r9+184], rcx + pop rbp + pop rbx + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_3072_mont_reduce_avx2_24 ENDP +_text ENDS +ENDIF +; /* Conditionally subtract b from a using the mask m. +; * m is -1 to subtract and 0 when not copying. +; * +; * r A single precision number representing condition subtract result. +; * a A single precision number to subtract from. +; * b A single precision number to subtract. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_3072_cond_sub_48 PROC + sub rsp, 384 + mov rax, 0 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp], r10 + mov QWORD PTR [rsp+8], r11 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+16], r10 + mov QWORD PTR [rsp+24], r11 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+32], r10 + mov QWORD PTR [rsp+40], r11 + mov r10, QWORD PTR [r8+48] + mov r11, QWORD PTR [r8+56] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+48], r10 + mov QWORD PTR [rsp+56], r11 + mov r10, QWORD PTR [r8+64] + mov r11, QWORD PTR [r8+72] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+64], r10 + mov QWORD PTR [rsp+72], r11 + mov r10, QWORD PTR [r8+80] + mov r11, QWORD PTR [r8+88] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+80], r10 + mov QWORD PTR [rsp+88], r11 + mov r10, QWORD PTR [r8+96] + mov r11, QWORD PTR [r8+104] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+96], r10 + mov QWORD PTR [rsp+104], r11 + mov r10, QWORD PTR [r8+112] + mov r11, QWORD PTR [r8+120] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+112], r10 + mov QWORD PTR [rsp+120], r11 + mov r10, QWORD PTR [r8+128] + mov r11, QWORD PTR [r8+136] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+128], r10 + mov QWORD PTR [rsp+136], r11 + mov r10, QWORD PTR [r8+144] + mov r11, QWORD PTR [r8+152] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+144], r10 + mov QWORD PTR [rsp+152], r11 + mov r10, QWORD PTR [r8+160] + mov r11, QWORD PTR [r8+168] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+160], r10 + mov QWORD PTR [rsp+168], r11 + mov r10, QWORD PTR [r8+176] + mov r11, QWORD PTR [r8+184] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+176], r10 + mov QWORD PTR [rsp+184], r11 + mov r10, QWORD PTR [r8+192] + mov r11, QWORD PTR [r8+200] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+192], r10 + mov QWORD PTR [rsp+200], r11 + mov r10, QWORD PTR [r8+208] + mov r11, QWORD PTR [r8+216] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+208], r10 + mov QWORD PTR [rsp+216], r11 + mov r10, QWORD PTR [r8+224] + mov r11, QWORD PTR [r8+232] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+224], r10 + mov QWORD PTR [rsp+232], r11 + mov r10, QWORD PTR [r8+240] + mov r11, QWORD PTR [r8+248] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+240], r10 + mov QWORD PTR [rsp+248], r11 + mov r10, QWORD PTR [r8+256] + mov r11, QWORD PTR [r8+264] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+256], r10 + mov QWORD PTR [rsp+264], r11 + mov r10, QWORD PTR [r8+272] + mov r11, QWORD PTR [r8+280] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+272], r10 + mov QWORD PTR [rsp+280], r11 + mov r10, QWORD PTR [r8+288] + mov r11, QWORD PTR [r8+296] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+288], r10 + mov QWORD PTR [rsp+296], r11 + mov r10, QWORD PTR [r8+304] + mov r11, QWORD PTR [r8+312] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+304], r10 + mov QWORD PTR [rsp+312], r11 + mov r10, QWORD PTR [r8+320] + mov r11, QWORD PTR [r8+328] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+320], r10 + mov QWORD PTR [rsp+328], r11 + mov r10, QWORD PTR [r8+336] + mov r11, QWORD PTR [r8+344] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+336], r10 + mov QWORD PTR [rsp+344], r11 + mov r10, QWORD PTR [r8+352] + mov r11, QWORD PTR [r8+360] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+352], r10 + mov QWORD PTR [rsp+360], r11 + mov r10, QWORD PTR [r8+368] + mov r11, QWORD PTR [r8+376] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+368], r10 + mov QWORD PTR [rsp+376], r11 + mov r10, QWORD PTR [rdx] + mov r8, QWORD PTR [rsp] + sub r10, r8 + mov r11, QWORD PTR [rdx+8] + mov r8, QWORD PTR [rsp+8] + sbb r11, r8 + mov QWORD PTR [rcx], r10 + mov r10, QWORD PTR [rdx+16] + mov r8, QWORD PTR [rsp+16] + sbb r10, r8 + mov QWORD PTR [rcx+8], r11 + mov r11, QWORD PTR [rdx+24] + mov r8, QWORD PTR [rsp+24] + sbb r11, r8 + mov QWORD PTR [rcx+16], r10 + mov r10, QWORD PTR [rdx+32] + mov r8, QWORD PTR [rsp+32] + sbb r10, r8 + mov QWORD PTR [rcx+24], r11 + mov r11, QWORD PTR [rdx+40] + mov r8, QWORD PTR [rsp+40] + sbb r11, r8 + mov QWORD PTR [rcx+32], r10 + mov r10, QWORD PTR [rdx+48] + mov r8, QWORD PTR [rsp+48] + sbb r10, r8 + mov QWORD PTR [rcx+40], r11 + mov r11, QWORD PTR [rdx+56] + mov r8, QWORD PTR [rsp+56] + sbb r11, r8 + mov QWORD PTR [rcx+48], r10 + mov r10, QWORD PTR [rdx+64] + mov r8, QWORD PTR [rsp+64] + sbb r10, r8 + mov QWORD PTR [rcx+56], r11 + mov r11, QWORD PTR [rdx+72] + mov r8, QWORD PTR [rsp+72] + sbb r11, r8 + mov QWORD PTR [rcx+64], r10 + mov r10, QWORD PTR [rdx+80] + mov r8, QWORD PTR [rsp+80] + sbb r10, r8 + mov QWORD PTR [rcx+72], r11 + mov r11, QWORD PTR [rdx+88] + mov r8, QWORD PTR [rsp+88] + sbb r11, r8 + mov QWORD PTR [rcx+80], r10 + mov r10, QWORD PTR [rdx+96] + mov r8, QWORD PTR [rsp+96] + sbb r10, r8 + mov QWORD PTR [rcx+88], r11 + mov r11, QWORD PTR [rdx+104] + mov r8, QWORD PTR [rsp+104] + sbb r11, r8 + mov QWORD PTR [rcx+96], r10 + mov r10, QWORD PTR [rdx+112] + mov r8, QWORD PTR [rsp+112] + sbb r10, r8 + mov QWORD PTR [rcx+104], r11 + mov r11, QWORD PTR [rdx+120] + mov r8, QWORD PTR [rsp+120] + sbb r11, r8 + mov QWORD PTR [rcx+112], r10 + mov r10, QWORD PTR [rdx+128] + mov r8, QWORD PTR [rsp+128] + sbb r10, r8 + mov QWORD PTR [rcx+120], r11 + mov r11, QWORD PTR [rdx+136] + mov r8, QWORD PTR [rsp+136] + sbb r11, r8 + mov QWORD PTR [rcx+128], r10 + mov r10, QWORD PTR [rdx+144] + mov r8, QWORD PTR [rsp+144] + sbb r10, r8 + mov QWORD PTR [rcx+136], r11 + mov r11, QWORD PTR [rdx+152] + mov r8, QWORD PTR [rsp+152] + sbb r11, r8 + mov QWORD PTR [rcx+144], r10 + mov r10, QWORD PTR [rdx+160] + mov r8, QWORD PTR [rsp+160] + sbb r10, r8 + mov QWORD PTR [rcx+152], r11 + mov r11, QWORD PTR [rdx+168] + mov r8, QWORD PTR [rsp+168] + sbb r11, r8 + mov QWORD PTR [rcx+160], r10 + mov r10, QWORD PTR [rdx+176] + mov r8, QWORD PTR [rsp+176] + sbb r10, r8 + mov QWORD PTR [rcx+168], r11 + mov r11, QWORD PTR [rdx+184] + mov r8, QWORD PTR [rsp+184] + sbb r11, r8 + mov QWORD PTR [rcx+176], r10 + mov r10, QWORD PTR [rdx+192] + mov r8, QWORD PTR [rsp+192] + sbb r10, r8 + mov QWORD PTR [rcx+184], r11 + mov r11, QWORD PTR [rdx+200] + mov r8, QWORD PTR [rsp+200] + sbb r11, r8 + mov QWORD PTR [rcx+192], r10 + mov r10, QWORD PTR [rdx+208] + mov r8, QWORD PTR [rsp+208] + sbb r10, r8 + mov QWORD PTR [rcx+200], r11 + mov r11, QWORD PTR [rdx+216] + mov r8, QWORD PTR [rsp+216] + sbb r11, r8 + mov QWORD PTR [rcx+208], r10 + mov r10, QWORD PTR [rdx+224] + mov r8, QWORD PTR [rsp+224] + sbb r10, r8 + mov QWORD PTR [rcx+216], r11 + mov r11, QWORD PTR [rdx+232] + mov r8, QWORD PTR [rsp+232] + sbb r11, r8 + mov QWORD PTR [rcx+224], r10 + mov r10, QWORD PTR [rdx+240] + mov r8, QWORD PTR [rsp+240] + sbb r10, r8 + mov QWORD PTR [rcx+232], r11 + mov r11, QWORD PTR [rdx+248] + mov r8, QWORD PTR [rsp+248] + sbb r11, r8 + mov QWORD PTR [rcx+240], r10 + mov r10, QWORD PTR [rdx+256] + mov r8, QWORD PTR [rsp+256] + sbb r10, r8 + mov QWORD PTR [rcx+248], r11 + mov r11, QWORD PTR [rdx+264] + mov r8, QWORD PTR [rsp+264] + sbb r11, r8 + mov QWORD PTR [rcx+256], r10 + mov r10, QWORD PTR [rdx+272] + mov r8, QWORD PTR [rsp+272] + sbb r10, r8 + mov QWORD PTR [rcx+264], r11 + mov r11, QWORD PTR [rdx+280] + mov r8, QWORD PTR [rsp+280] + sbb r11, r8 + mov QWORD PTR [rcx+272], r10 + mov r10, QWORD PTR [rdx+288] + mov r8, QWORD PTR [rsp+288] + sbb r10, r8 + mov QWORD PTR [rcx+280], r11 + mov r11, QWORD PTR [rdx+296] + mov r8, QWORD PTR [rsp+296] + sbb r11, r8 + mov QWORD PTR [rcx+288], r10 + mov r10, QWORD PTR [rdx+304] + mov r8, QWORD PTR [rsp+304] + sbb r10, r8 + mov QWORD PTR [rcx+296], r11 + mov r11, QWORD PTR [rdx+312] + mov r8, QWORD PTR [rsp+312] + sbb r11, r8 + mov QWORD PTR [rcx+304], r10 + mov r10, QWORD PTR [rdx+320] + mov r8, QWORD PTR [rsp+320] + sbb r10, r8 + mov QWORD PTR [rcx+312], r11 + mov r11, QWORD PTR [rdx+328] + mov r8, QWORD PTR [rsp+328] + sbb r11, r8 + mov QWORD PTR [rcx+320], r10 + mov r10, QWORD PTR [rdx+336] + mov r8, QWORD PTR [rsp+336] + sbb r10, r8 + mov QWORD PTR [rcx+328], r11 + mov r11, QWORD PTR [rdx+344] + mov r8, QWORD PTR [rsp+344] + sbb r11, r8 + mov QWORD PTR [rcx+336], r10 + mov r10, QWORD PTR [rdx+352] + mov r8, QWORD PTR [rsp+352] + sbb r10, r8 + mov QWORD PTR [rcx+344], r11 + mov r11, QWORD PTR [rdx+360] + mov r8, QWORD PTR [rsp+360] + sbb r11, r8 + mov QWORD PTR [rcx+352], r10 + mov r10, QWORD PTR [rdx+368] + mov r8, QWORD PTR [rsp+368] + sbb r10, r8 + mov QWORD PTR [rcx+360], r11 + mov r11, QWORD PTR [rdx+376] + mov r8, QWORD PTR [rsp+376] + sbb r11, r8 + mov QWORD PTR [rcx+368], r10 + mov QWORD PTR [rcx+376], r11 + sbb rax, 0 + add rsp, 384 + ret +sp_3072_cond_sub_48 ENDP +_text ENDS +; /* Reduce the number back to 3072 bits using Montgomery reduction. +; * +; * a A single precision number to reduce in place. +; * m The single precision number representing the modulus. +; * mp The digit representing the negative inverse of m mod 2^n. +; */ +_text SEGMENT READONLY PARA +sp_3072_mont_reduce_48 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + mov r9, rdx + xor rsi, rsi + ; i = 48 + mov r10, 48 + mov r15, QWORD PTR [rcx] + mov rdi, QWORD PTR [rcx+8] +L_3072_mont_loop_48: + ; mu = a[i] * mp + mov r13, r15 + imul r13, r8 + ; a[i+0] += m[0] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9] + add r15, rax + adc r12, rdx + ; a[i+1] += m[1] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+8] + mov r15, rdi + add r15, rax + adc r11, rdx + add r15, r12 + adc r11, 0 + ; a[i+2] += m[2] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+16] + mov rdi, QWORD PTR [rcx+16] + add rdi, rax + adc r12, rdx + add rdi, r11 + adc r12, 0 + ; a[i+3] += m[3] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+24] + mov r14, QWORD PTR [rcx+24] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+24], r14 + adc r11, 0 + ; a[i+4] += m[4] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+32] + mov r14, QWORD PTR [rcx+32] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+32], r14 + adc r12, 0 + ; a[i+5] += m[5] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+40] + mov r14, QWORD PTR [rcx+40] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+40], r14 + adc r11, 0 + ; a[i+6] += m[6] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+48] + mov r14, QWORD PTR [rcx+48] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+48], r14 + adc r12, 0 + ; a[i+7] += m[7] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+56] + mov r14, QWORD PTR [rcx+56] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+56], r14 + adc r11, 0 + ; a[i+8] += m[8] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+64] + mov r14, QWORD PTR [rcx+64] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+64], r14 + adc r12, 0 + ; a[i+9] += m[9] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+72] + mov r14, QWORD PTR [rcx+72] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+72], r14 + adc r11, 0 + ; a[i+10] += m[10] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+80] + mov r14, QWORD PTR [rcx+80] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+80], r14 + adc r12, 0 + ; a[i+11] += m[11] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+88] + mov r14, QWORD PTR [rcx+88] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+88], r14 + adc r11, 0 + ; a[i+12] += m[12] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+96] + mov r14, QWORD PTR [rcx+96] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+96], r14 + adc r12, 0 + ; a[i+13] += m[13] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+104] + mov r14, QWORD PTR [rcx+104] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+104], r14 + adc r11, 0 + ; a[i+14] += m[14] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+112] + mov r14, QWORD PTR [rcx+112] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+112], r14 + adc r12, 0 + ; a[i+15] += m[15] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+120] + mov r14, QWORD PTR [rcx+120] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+120], r14 + adc r11, 0 + ; a[i+16] += m[16] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+128] + mov r14, QWORD PTR [rcx+128] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+128], r14 + adc r12, 0 + ; a[i+17] += m[17] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+136] + mov r14, QWORD PTR [rcx+136] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+136], r14 + adc r11, 0 + ; a[i+18] += m[18] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+144] + mov r14, QWORD PTR [rcx+144] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+144], r14 + adc r12, 0 + ; a[i+19] += m[19] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+152] + mov r14, QWORD PTR [rcx+152] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+152], r14 + adc r11, 0 + ; a[i+20] += m[20] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+160] + mov r14, QWORD PTR [rcx+160] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+160], r14 + adc r12, 0 + ; a[i+21] += m[21] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+168] + mov r14, QWORD PTR [rcx+168] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+168], r14 + adc r11, 0 + ; a[i+22] += m[22] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+176] + mov r14, QWORD PTR [rcx+176] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+176], r14 + adc r12, 0 + ; a[i+23] += m[23] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+184] + mov r14, QWORD PTR [rcx+184] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+184], r14 + adc r11, 0 + ; a[i+24] += m[24] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+192] + mov r14, QWORD PTR [rcx+192] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+192], r14 + adc r12, 0 + ; a[i+25] += m[25] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+200] + mov r14, QWORD PTR [rcx+200] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+200], r14 + adc r11, 0 + ; a[i+26] += m[26] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+208] + mov r14, QWORD PTR [rcx+208] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+208], r14 + adc r12, 0 + ; a[i+27] += m[27] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+216] + mov r14, QWORD PTR [rcx+216] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+216], r14 + adc r11, 0 + ; a[i+28] += m[28] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+224] + mov r14, QWORD PTR [rcx+224] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+224], r14 + adc r12, 0 + ; a[i+29] += m[29] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+232] + mov r14, QWORD PTR [rcx+232] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+232], r14 + adc r11, 0 + ; a[i+30] += m[30] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+240] + mov r14, QWORD PTR [rcx+240] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+240], r14 + adc r12, 0 + ; a[i+31] += m[31] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+248] + mov r14, QWORD PTR [rcx+248] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+248], r14 + adc r11, 0 + ; a[i+32] += m[32] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+256] + mov r14, QWORD PTR [rcx+256] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+256], r14 + adc r12, 0 + ; a[i+33] += m[33] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+264] + mov r14, QWORD PTR [rcx+264] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+264], r14 + adc r11, 0 + ; a[i+34] += m[34] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+272] + mov r14, QWORD PTR [rcx+272] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+272], r14 + adc r12, 0 + ; a[i+35] += m[35] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+280] + mov r14, QWORD PTR [rcx+280] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+280], r14 + adc r11, 0 + ; a[i+36] += m[36] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+288] + mov r14, QWORD PTR [rcx+288] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+288], r14 + adc r12, 0 + ; a[i+37] += m[37] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+296] + mov r14, QWORD PTR [rcx+296] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+296], r14 + adc r11, 0 + ; a[i+38] += m[38] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+304] + mov r14, QWORD PTR [rcx+304] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+304], r14 + adc r12, 0 + ; a[i+39] += m[39] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+312] + mov r14, QWORD PTR [rcx+312] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+312], r14 + adc r11, 0 + ; a[i+40] += m[40] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+320] + mov r14, QWORD PTR [rcx+320] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+320], r14 + adc r12, 0 + ; a[i+41] += m[41] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+328] + mov r14, QWORD PTR [rcx+328] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+328], r14 + adc r11, 0 + ; a[i+42] += m[42] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+336] + mov r14, QWORD PTR [rcx+336] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+336], r14 + adc r12, 0 + ; a[i+43] += m[43] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+344] + mov r14, QWORD PTR [rcx+344] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+344], r14 + adc r11, 0 + ; a[i+44] += m[44] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+352] + mov r14, QWORD PTR [rcx+352] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+352], r14 + adc r12, 0 + ; a[i+45] += m[45] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+360] + mov r14, QWORD PTR [rcx+360] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+360], r14 + adc r11, 0 + ; a[i+46] += m[46] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+368] + mov r14, QWORD PTR [rcx+368] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+368], r14 + adc r12, 0 + ; a[i+47] += m[47] * mu + mov rax, r13 + mul QWORD PTR [r9+376] + mov r14, QWORD PTR [rcx+376] + add r12, rax + adc rdx, rsi + mov rsi, 0 + adc rsi, 0 + add r14, r12 + mov QWORD PTR [rcx+376], r14 + adc QWORD PTR [rcx+384], rdx + adc rsi, 0 + ; i -= 1 + add rcx, 8 + dec r10 + jnz L_3072_mont_loop_48 + mov QWORD PTR [rcx], r15 + mov QWORD PTR [rcx+8], rdi + neg rsi +IFDEF _WIN64 + mov r8, r9 + mov r9, rsi +ELSE + mov r9, rsi + mov r8, r9 +ENDIF + mov rdx, rcx + mov rcx, rcx + sub rcx, 384 + call sp_3072_cond_sub_48 + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_3072_mont_reduce_48 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Conditionally subtract b from a using the mask m. +; * m is -1 to subtract and 0 when not copying. +; * +; * r A single precision number representing condition subtract result. +; * a A single precision number to subtract from. +; * b A single precision number to subtract. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_3072_cond_sub_avx2_48 PROC + push r12 + mov rax, 0 + mov r12, QWORD PTR [r8] + mov r10, QWORD PTR [rdx] + pext r12, r12, r9 + sub r10, r12 + mov r12, QWORD PTR [r8+8] + mov r11, QWORD PTR [rdx+8] + pext r12, r12, r9 + mov QWORD PTR [rcx], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+16] + mov r12, QWORD PTR [rdx+16] + pext r10, r10, r9 + mov QWORD PTR [rcx+8], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+24] + mov r10, QWORD PTR [rdx+24] + pext r11, r11, r9 + mov QWORD PTR [rcx+16], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+32] + mov r11, QWORD PTR [rdx+32] + pext r12, r12, r9 + mov QWORD PTR [rcx+24], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+40] + mov r12, QWORD PTR [rdx+40] + pext r10, r10, r9 + mov QWORD PTR [rcx+32], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+48] + mov r10, QWORD PTR [rdx+48] + pext r11, r11, r9 + mov QWORD PTR [rcx+40], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+56] + mov r11, QWORD PTR [rdx+56] + pext r12, r12, r9 + mov QWORD PTR [rcx+48], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+64] + mov r12, QWORD PTR [rdx+64] + pext r10, r10, r9 + mov QWORD PTR [rcx+56], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+72] + mov r10, QWORD PTR [rdx+72] + pext r11, r11, r9 + mov QWORD PTR [rcx+64], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+80] + mov r11, QWORD PTR [rdx+80] + pext r12, r12, r9 + mov QWORD PTR [rcx+72], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+88] + mov r12, QWORD PTR [rdx+88] + pext r10, r10, r9 + mov QWORD PTR [rcx+80], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+96] + mov r10, QWORD PTR [rdx+96] + pext r11, r11, r9 + mov QWORD PTR [rcx+88], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+104] + mov r11, QWORD PTR [rdx+104] + pext r12, r12, r9 + mov QWORD PTR [rcx+96], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+112] + mov r12, QWORD PTR [rdx+112] + pext r10, r10, r9 + mov QWORD PTR [rcx+104], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+120] + mov r10, QWORD PTR [rdx+120] + pext r11, r11, r9 + mov QWORD PTR [rcx+112], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+128] + mov r11, QWORD PTR [rdx+128] + pext r12, r12, r9 + mov QWORD PTR [rcx+120], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+136] + mov r12, QWORD PTR [rdx+136] + pext r10, r10, r9 + mov QWORD PTR [rcx+128], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+144] + mov r10, QWORD PTR [rdx+144] + pext r11, r11, r9 + mov QWORD PTR [rcx+136], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+152] + mov r11, QWORD PTR [rdx+152] + pext r12, r12, r9 + mov QWORD PTR [rcx+144], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+160] + mov r12, QWORD PTR [rdx+160] + pext r10, r10, r9 + mov QWORD PTR [rcx+152], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+168] + mov r10, QWORD PTR [rdx+168] + pext r11, r11, r9 + mov QWORD PTR [rcx+160], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+176] + mov r11, QWORD PTR [rdx+176] + pext r12, r12, r9 + mov QWORD PTR [rcx+168], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+184] + mov r12, QWORD PTR [rdx+184] + pext r10, r10, r9 + mov QWORD PTR [rcx+176], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+192] + mov r10, QWORD PTR [rdx+192] + pext r11, r11, r9 + mov QWORD PTR [rcx+184], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+200] + mov r11, QWORD PTR [rdx+200] + pext r12, r12, r9 + mov QWORD PTR [rcx+192], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+208] + mov r12, QWORD PTR [rdx+208] + pext r10, r10, r9 + mov QWORD PTR [rcx+200], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+216] + mov r10, QWORD PTR [rdx+216] + pext r11, r11, r9 + mov QWORD PTR [rcx+208], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+224] + mov r11, QWORD PTR [rdx+224] + pext r12, r12, r9 + mov QWORD PTR [rcx+216], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+232] + mov r12, QWORD PTR [rdx+232] + pext r10, r10, r9 + mov QWORD PTR [rcx+224], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+240] + mov r10, QWORD PTR [rdx+240] + pext r11, r11, r9 + mov QWORD PTR [rcx+232], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+248] + mov r11, QWORD PTR [rdx+248] + pext r12, r12, r9 + mov QWORD PTR [rcx+240], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+256] + mov r12, QWORD PTR [rdx+256] + pext r10, r10, r9 + mov QWORD PTR [rcx+248], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+264] + mov r10, QWORD PTR [rdx+264] + pext r11, r11, r9 + mov QWORD PTR [rcx+256], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+272] + mov r11, QWORD PTR [rdx+272] + pext r12, r12, r9 + mov QWORD PTR [rcx+264], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+280] + mov r12, QWORD PTR [rdx+280] + pext r10, r10, r9 + mov QWORD PTR [rcx+272], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+288] + mov r10, QWORD PTR [rdx+288] + pext r11, r11, r9 + mov QWORD PTR [rcx+280], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+296] + mov r11, QWORD PTR [rdx+296] + pext r12, r12, r9 + mov QWORD PTR [rcx+288], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+304] + mov r12, QWORD PTR [rdx+304] + pext r10, r10, r9 + mov QWORD PTR [rcx+296], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+312] + mov r10, QWORD PTR [rdx+312] + pext r11, r11, r9 + mov QWORD PTR [rcx+304], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+320] + mov r11, QWORD PTR [rdx+320] + pext r12, r12, r9 + mov QWORD PTR [rcx+312], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+328] + mov r12, QWORD PTR [rdx+328] + pext r10, r10, r9 + mov QWORD PTR [rcx+320], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+336] + mov r10, QWORD PTR [rdx+336] + pext r11, r11, r9 + mov QWORD PTR [rcx+328], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+344] + mov r11, QWORD PTR [rdx+344] + pext r12, r12, r9 + mov QWORD PTR [rcx+336], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+352] + mov r12, QWORD PTR [rdx+352] + pext r10, r10, r9 + mov QWORD PTR [rcx+344], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+360] + mov r10, QWORD PTR [rdx+360] + pext r11, r11, r9 + mov QWORD PTR [rcx+352], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+368] + mov r11, QWORD PTR [rdx+368] + pext r12, r12, r9 + mov QWORD PTR [rcx+360], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+376] + mov r12, QWORD PTR [rdx+376] + pext r10, r10, r9 + mov QWORD PTR [rcx+368], r11 + sbb r12, r10 + mov QWORD PTR [rcx+376], r12 + sbb rax, 0 + pop r12 + ret +sp_3072_cond_sub_avx2_48 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Mul a by digit b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision digit. +; */ +_text SEGMENT READONLY PARA +sp_3072_mul_d_avx2_48 PROC + push r12 + push r13 + mov rax, rdx + ; A[0] * B + mov rdx, r8 + xor r13, r13 + mulx r12, r11, QWORD PTR [rax] + mov QWORD PTR [rcx], r11 + ; A[1] * B + mulx r10, r9, QWORD PTR [rax+8] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+8], r12 + ; A[2] * B + mulx r10, r9, QWORD PTR [rax+16] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+16], r11 + ; A[3] * B + mulx r10, r9, QWORD PTR [rax+24] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+24], r12 + ; A[4] * B + mulx r10, r9, QWORD PTR [rax+32] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+32], r11 + ; A[5] * B + mulx r10, r9, QWORD PTR [rax+40] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+40], r12 + ; A[6] * B + mulx r10, r9, QWORD PTR [rax+48] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+48], r11 + ; A[7] * B + mulx r10, r9, QWORD PTR [rax+56] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+56], r12 + ; A[8] * B + mulx r10, r9, QWORD PTR [rax+64] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+64], r11 + ; A[9] * B + mulx r10, r9, QWORD PTR [rax+72] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+72], r12 + ; A[10] * B + mulx r10, r9, QWORD PTR [rax+80] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+80], r11 + ; A[11] * B + mulx r10, r9, QWORD PTR [rax+88] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+88], r12 + ; A[12] * B + mulx r10, r9, QWORD PTR [rax+96] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+96], r11 + ; A[13] * B + mulx r10, r9, QWORD PTR [rax+104] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+104], r12 + ; A[14] * B + mulx r10, r9, QWORD PTR [rax+112] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+112], r11 + ; A[15] * B + mulx r10, r9, QWORD PTR [rax+120] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+120], r12 + ; A[16] * B + mulx r10, r9, QWORD PTR [rax+128] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+128], r11 + ; A[17] * B + mulx r10, r9, QWORD PTR [rax+136] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+136], r12 + ; A[18] * B + mulx r10, r9, QWORD PTR [rax+144] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+144], r11 + ; A[19] * B + mulx r10, r9, QWORD PTR [rax+152] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+152], r12 + ; A[20] * B + mulx r10, r9, QWORD PTR [rax+160] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+160], r11 + ; A[21] * B + mulx r10, r9, QWORD PTR [rax+168] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+168], r12 + ; A[22] * B + mulx r10, r9, QWORD PTR [rax+176] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+176], r11 + ; A[23] * B + mulx r10, r9, QWORD PTR [rax+184] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+184], r12 + ; A[24] * B + mulx r10, r9, QWORD PTR [rax+192] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+192], r11 + ; A[25] * B + mulx r10, r9, QWORD PTR [rax+200] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+200], r12 + ; A[26] * B + mulx r10, r9, QWORD PTR [rax+208] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+208], r11 + ; A[27] * B + mulx r10, r9, QWORD PTR [rax+216] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+216], r12 + ; A[28] * B + mulx r10, r9, QWORD PTR [rax+224] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+224], r11 + ; A[29] * B + mulx r10, r9, QWORD PTR [rax+232] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+232], r12 + ; A[30] * B + mulx r10, r9, QWORD PTR [rax+240] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+240], r11 + ; A[31] * B + mulx r10, r9, QWORD PTR [rax+248] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+248], r12 + ; A[32] * B + mulx r10, r9, QWORD PTR [rax+256] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+256], r11 + ; A[33] * B + mulx r10, r9, QWORD PTR [rax+264] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+264], r12 + ; A[34] * B + mulx r10, r9, QWORD PTR [rax+272] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+272], r11 + ; A[35] * B + mulx r10, r9, QWORD PTR [rax+280] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+280], r12 + ; A[36] * B + mulx r10, r9, QWORD PTR [rax+288] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+288], r11 + ; A[37] * B + mulx r10, r9, QWORD PTR [rax+296] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+296], r12 + ; A[38] * B + mulx r10, r9, QWORD PTR [rax+304] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+304], r11 + ; A[39] * B + mulx r10, r9, QWORD PTR [rax+312] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+312], r12 + ; A[40] * B + mulx r10, r9, QWORD PTR [rax+320] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+320], r11 + ; A[41] * B + mulx r10, r9, QWORD PTR [rax+328] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+328], r12 + ; A[42] * B + mulx r10, r9, QWORD PTR [rax+336] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+336], r11 + ; A[43] * B + mulx r10, r9, QWORD PTR [rax+344] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+344], r12 + ; A[44] * B + mulx r10, r9, QWORD PTR [rax+352] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+352], r11 + ; A[45] * B + mulx r10, r9, QWORD PTR [rax+360] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+360], r12 + ; A[46] * B + mulx r10, r9, QWORD PTR [rax+368] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+368], r11 + ; A[47] * B + mulx r10, r9, QWORD PTR [rax+376] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + adcx r11, r13 + mov QWORD PTR [rcx+376], r12 + mov QWORD PTR [rcx+384], r11 + pop r13 + pop r12 + ret +sp_3072_mul_d_avx2_48 ENDP +_text ENDS +ENDIF +IFDEF _WIN64 +; /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) +; * +; * d1 The high order half of the number to divide. +; * d0 The low order half of the number to divide. +; * div The dividend. +; * returns the result of the division. +; */ +_text SEGMENT READONLY PARA +div_3072_word_asm_48 PROC + mov r9, rdx + mov rax, r9 + mov rdx, rcx + div r8 + ret +div_3072_word_asm_48 ENDP +_text ENDS +ENDIF +; /* Compare a with b in constant time. +; * +; * a A single precision integer. +; * b A single precision integer. +; * return -ve, 0 or +ve if a is less than, equal to or greater than b +; * respectively. +; */ +_text SEGMENT READONLY PARA +sp_3072_cmp_48 PROC + push r12 + xor r9, r9 + mov r8, -1 + mov rax, -1 + mov r10, 1 + mov r11, QWORD PTR [rcx+376] + mov r12, QWORD PTR [rdx+376] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+368] + mov r12, QWORD PTR [rdx+368] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+360] + mov r12, QWORD PTR [rdx+360] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+352] + mov r12, QWORD PTR [rdx+352] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+344] + mov r12, QWORD PTR [rdx+344] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+336] + mov r12, QWORD PTR [rdx+336] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+328] + mov r12, QWORD PTR [rdx+328] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+320] + mov r12, QWORD PTR [rdx+320] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+312] + mov r12, QWORD PTR [rdx+312] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+304] + mov r12, QWORD PTR [rdx+304] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+296] + mov r12, QWORD PTR [rdx+296] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+288] + mov r12, QWORD PTR [rdx+288] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+280] + mov r12, QWORD PTR [rdx+280] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+272] + mov r12, QWORD PTR [rdx+272] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+264] + mov r12, QWORD PTR [rdx+264] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+256] + mov r12, QWORD PTR [rdx+256] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+248] + mov r12, QWORD PTR [rdx+248] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+240] + mov r12, QWORD PTR [rdx+240] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+232] + mov r12, QWORD PTR [rdx+232] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+224] + mov r12, QWORD PTR [rdx+224] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+216] + mov r12, QWORD PTR [rdx+216] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+208] + mov r12, QWORD PTR [rdx+208] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+200] + mov r12, QWORD PTR [rdx+200] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+192] + mov r12, QWORD PTR [rdx+192] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+184] + mov r12, QWORD PTR [rdx+184] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+176] + mov r12, QWORD PTR [rdx+176] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+168] + mov r12, QWORD PTR [rdx+168] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+160] + mov r12, QWORD PTR [rdx+160] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+152] + mov r12, QWORD PTR [rdx+152] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+144] + mov r12, QWORD PTR [rdx+144] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+136] + mov r12, QWORD PTR [rdx+136] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+128] + mov r12, QWORD PTR [rdx+128] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+120] + mov r12, QWORD PTR [rdx+120] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+112] + mov r12, QWORD PTR [rdx+112] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+104] + mov r12, QWORD PTR [rdx+104] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+96] + mov r12, QWORD PTR [rdx+96] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+88] + mov r12, QWORD PTR [rdx+88] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+80] + mov r12, QWORD PTR [rdx+80] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+72] + mov r12, QWORD PTR [rdx+72] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+64] + mov r12, QWORD PTR [rdx+64] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+56] + mov r12, QWORD PTR [rdx+56] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+48] + mov r12, QWORD PTR [rdx+48] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+40] + mov r12, QWORD PTR [rdx+40] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+32] + mov r12, QWORD PTR [rdx+32] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+24] + mov r12, QWORD PTR [rdx+24] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+16] + mov r12, QWORD PTR [rdx+16] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+8] + mov r12, QWORD PTR [rdx+8] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx] + mov r12, QWORD PTR [rdx] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + xor rax, r8 + pop r12 + ret +sp_3072_cmp_48 ENDP +_text ENDS +; /* Sub b from a into r. (r = a - b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_3072_sub_48 PROC + mov r9, QWORD PTR [rdx] + xor rax, rax + sub r9, QWORD PTR [r8] + mov r10, QWORD PTR [rdx+8] + mov QWORD PTR [rcx], r9 + sbb r10, QWORD PTR [r8+8] + mov r9, QWORD PTR [rdx+16] + mov QWORD PTR [rcx+8], r10 + sbb r9, QWORD PTR [r8+16] + mov r10, QWORD PTR [rdx+24] + mov QWORD PTR [rcx+16], r9 + sbb r10, QWORD PTR [r8+24] + mov r9, QWORD PTR [rdx+32] + mov QWORD PTR [rcx+24], r10 + sbb r9, QWORD PTR [r8+32] + mov r10, QWORD PTR [rdx+40] + mov QWORD PTR [rcx+32], r9 + sbb r10, QWORD PTR [r8+40] + mov r9, QWORD PTR [rdx+48] + mov QWORD PTR [rcx+40], r10 + sbb r9, QWORD PTR [r8+48] + mov r10, QWORD PTR [rdx+56] + mov QWORD PTR [rcx+48], r9 + sbb r10, QWORD PTR [r8+56] + mov r9, QWORD PTR [rdx+64] + mov QWORD PTR [rcx+56], r10 + sbb r9, QWORD PTR [r8+64] + mov r10, QWORD PTR [rdx+72] + mov QWORD PTR [rcx+64], r9 + sbb r10, QWORD PTR [r8+72] + mov r9, QWORD PTR [rdx+80] + mov QWORD PTR [rcx+72], r10 + sbb r9, QWORD PTR [r8+80] + mov r10, QWORD PTR [rdx+88] + mov QWORD PTR [rcx+80], r9 + sbb r10, QWORD PTR [r8+88] + mov r9, QWORD PTR [rdx+96] + mov QWORD PTR [rcx+88], r10 + sbb r9, QWORD PTR [r8+96] + mov r10, QWORD PTR [rdx+104] + mov QWORD PTR [rcx+96], r9 + sbb r10, QWORD PTR [r8+104] + mov r9, QWORD PTR [rdx+112] + mov QWORD PTR [rcx+104], r10 + sbb r9, QWORD PTR [r8+112] + mov r10, QWORD PTR [rdx+120] + mov QWORD PTR [rcx+112], r9 + sbb r10, QWORD PTR [r8+120] + mov r9, QWORD PTR [rdx+128] + mov QWORD PTR [rcx+120], r10 + sbb r9, QWORD PTR [r8+128] + mov r10, QWORD PTR [rdx+136] + mov QWORD PTR [rcx+128], r9 + sbb r10, QWORD PTR [r8+136] + mov r9, QWORD PTR [rdx+144] + mov QWORD PTR [rcx+136], r10 + sbb r9, QWORD PTR [r8+144] + mov r10, QWORD PTR [rdx+152] + mov QWORD PTR [rcx+144], r9 + sbb r10, QWORD PTR [r8+152] + mov r9, QWORD PTR [rdx+160] + mov QWORD PTR [rcx+152], r10 + sbb r9, QWORD PTR [r8+160] + mov r10, QWORD PTR [rdx+168] + mov QWORD PTR [rcx+160], r9 + sbb r10, QWORD PTR [r8+168] + mov r9, QWORD PTR [rdx+176] + mov QWORD PTR [rcx+168], r10 + sbb r9, QWORD PTR [r8+176] + mov r10, QWORD PTR [rdx+184] + mov QWORD PTR [rcx+176], r9 + sbb r10, QWORD PTR [r8+184] + mov r9, QWORD PTR [rdx+192] + mov QWORD PTR [rcx+184], r10 + sbb r9, QWORD PTR [r8+192] + mov r10, QWORD PTR [rdx+200] + mov QWORD PTR [rcx+192], r9 + sbb r10, QWORD PTR [r8+200] + mov r9, QWORD PTR [rdx+208] + mov QWORD PTR [rcx+200], r10 + sbb r9, QWORD PTR [r8+208] + mov r10, QWORD PTR [rdx+216] + mov QWORD PTR [rcx+208], r9 + sbb r10, QWORD PTR [r8+216] + mov r9, QWORD PTR [rdx+224] + mov QWORD PTR [rcx+216], r10 + sbb r9, QWORD PTR [r8+224] + mov r10, QWORD PTR [rdx+232] + mov QWORD PTR [rcx+224], r9 + sbb r10, QWORD PTR [r8+232] + mov r9, QWORD PTR [rdx+240] + mov QWORD PTR [rcx+232], r10 + sbb r9, QWORD PTR [r8+240] + mov r10, QWORD PTR [rdx+248] + mov QWORD PTR [rcx+240], r9 + sbb r10, QWORD PTR [r8+248] + mov r9, QWORD PTR [rdx+256] + mov QWORD PTR [rcx+248], r10 + sbb r9, QWORD PTR [r8+256] + mov r10, QWORD PTR [rdx+264] + mov QWORD PTR [rcx+256], r9 + sbb r10, QWORD PTR [r8+264] + mov r9, QWORD PTR [rdx+272] + mov QWORD PTR [rcx+264], r10 + sbb r9, QWORD PTR [r8+272] + mov r10, QWORD PTR [rdx+280] + mov QWORD PTR [rcx+272], r9 + sbb r10, QWORD PTR [r8+280] + mov r9, QWORD PTR [rdx+288] + mov QWORD PTR [rcx+280], r10 + sbb r9, QWORD PTR [r8+288] + mov r10, QWORD PTR [rdx+296] + mov QWORD PTR [rcx+288], r9 + sbb r10, QWORD PTR [r8+296] + mov r9, QWORD PTR [rdx+304] + mov QWORD PTR [rcx+296], r10 + sbb r9, QWORD PTR [r8+304] + mov r10, QWORD PTR [rdx+312] + mov QWORD PTR [rcx+304], r9 + sbb r10, QWORD PTR [r8+312] + mov r9, QWORD PTR [rdx+320] + mov QWORD PTR [rcx+312], r10 + sbb r9, QWORD PTR [r8+320] + mov r10, QWORD PTR [rdx+328] + mov QWORD PTR [rcx+320], r9 + sbb r10, QWORD PTR [r8+328] + mov r9, QWORD PTR [rdx+336] + mov QWORD PTR [rcx+328], r10 + sbb r9, QWORD PTR [r8+336] + mov r10, QWORD PTR [rdx+344] + mov QWORD PTR [rcx+336], r9 + sbb r10, QWORD PTR [r8+344] + mov r9, QWORD PTR [rdx+352] + mov QWORD PTR [rcx+344], r10 + sbb r9, QWORD PTR [r8+352] + mov r10, QWORD PTR [rdx+360] + mov QWORD PTR [rcx+352], r9 + sbb r10, QWORD PTR [r8+360] + mov r9, QWORD PTR [rdx+368] + mov QWORD PTR [rcx+360], r10 + sbb r9, QWORD PTR [r8+368] + mov r10, QWORD PTR [rdx+376] + mov QWORD PTR [rcx+368], r9 + sbb r10, QWORD PTR [r8+376] + mov QWORD PTR [rcx+376], r10 + sbb rax, 0 + ret +sp_3072_sub_48 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Reduce the number back to 3072 bits using Montgomery reduction. +; * +; * a A single precision number to reduce in place. +; * m The single precision number representing the modulus. +; * mp The digit representing the negative inverse of m mod 2^n. +; */ +_text SEGMENT READONLY PARA +sp_3072_mont_reduce_avx2_48 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + push rbx + push rbp + mov r9, rcx + mov r10, rdx + xor rbp, rbp + ; i = 48 + mov r11, 48 + mov r15, QWORD PTR [r9] + mov rdi, QWORD PTR [r9+8] + mov rsi, QWORD PTR [r9+16] + mov rbx, QWORD PTR [r9+24] + add r9, 192 + xor rbp, rbp +L_3072_mont_loop_avx2_48: + ; mu = a[i] * mp + mov rdx, r15 + mov r12, r15 + imul rdx, r8 + xor r14, r14 + ; a[i+0] += m[0] * mu + mulx rcx, rax, QWORD PTR [r10] + mov r15, rdi + adcx r12, rax + adox r15, rcx + ; a[i+1] += m[1] * mu + mulx rcx, rax, QWORD PTR [r10+8] + mov rdi, rsi + adcx r15, rax + adox rdi, rcx + ; a[i+2] += m[2] * mu + mulx rcx, rax, QWORD PTR [r10+16] + mov rsi, rbx + adcx rdi, rax + adox rsi, rcx + ; a[i+3] += m[3] * mu + mulx rcx, rax, QWORD PTR [r10+24] + mov rbx, QWORD PTR [r9+-160] + adcx rsi, rax + adox rbx, rcx + ; a[i+4] += m[4] * mu + mulx rcx, rax, QWORD PTR [r10+32] + mov r13, QWORD PTR [r9+-152] + adcx rbx, rax + adox r13, rcx + ; a[i+5] += m[5] * mu + mulx rcx, rax, QWORD PTR [r10+40] + mov r12, QWORD PTR [r9+-144] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-152], r13 + ; a[i+6] += m[6] * mu + mulx rcx, rax, QWORD PTR [r10+48] + mov r13, QWORD PTR [r9+-136] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-144], r12 + ; a[i+7] += m[7] * mu + mulx rcx, rax, QWORD PTR [r10+56] + mov r12, QWORD PTR [r9+-128] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-136], r13 + ; a[i+8] += m[8] * mu + mulx rcx, rax, QWORD PTR [r10+64] + mov r13, QWORD PTR [r9+-120] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-128], r12 + ; a[i+9] += m[9] * mu + mulx rcx, rax, QWORD PTR [r10+72] + mov r12, QWORD PTR [r9+-112] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-120], r13 + ; a[i+10] += m[10] * mu + mulx rcx, rax, QWORD PTR [r10+80] + mov r13, QWORD PTR [r9+-104] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-112], r12 + ; a[i+11] += m[11] * mu + mulx rcx, rax, QWORD PTR [r10+88] + mov r12, QWORD PTR [r9+-96] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-104], r13 + ; a[i+12] += m[12] * mu + mulx rcx, rax, QWORD PTR [r10+96] + mov r13, QWORD PTR [r9+-88] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-96], r12 + ; a[i+13] += m[13] * mu + mulx rcx, rax, QWORD PTR [r10+104] + mov r12, QWORD PTR [r9+-80] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-88], r13 + ; a[i+14] += m[14] * mu + mulx rcx, rax, QWORD PTR [r10+112] + mov r13, QWORD PTR [r9+-72] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-80], r12 + ; a[i+15] += m[15] * mu + mulx rcx, rax, QWORD PTR [r10+120] + mov r12, QWORD PTR [r9+-64] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-72], r13 + ; a[i+16] += m[16] * mu + mulx rcx, rax, QWORD PTR [r10+128] + mov r13, QWORD PTR [r9+-56] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-64], r12 + ; a[i+17] += m[17] * mu + mulx rcx, rax, QWORD PTR [r10+136] + mov r12, QWORD PTR [r9+-48] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-56], r13 + ; a[i+18] += m[18] * mu + mulx rcx, rax, QWORD PTR [r10+144] + mov r13, QWORD PTR [r9+-40] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-48], r12 + ; a[i+19] += m[19] * mu + mulx rcx, rax, QWORD PTR [r10+152] + mov r12, QWORD PTR [r9+-32] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-40], r13 + ; a[i+20] += m[20] * mu + mulx rcx, rax, QWORD PTR [r10+160] + mov r13, QWORD PTR [r9+-24] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-32], r12 + ; a[i+21] += m[21] * mu + mulx rcx, rax, QWORD PTR [r10+168] + mov r12, QWORD PTR [r9+-16] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-24], r13 + ; a[i+22] += m[22] * mu + mulx rcx, rax, QWORD PTR [r10+176] + mov r13, QWORD PTR [r9+-8] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-16], r12 + ; a[i+23] += m[23] * mu + mulx rcx, rax, QWORD PTR [r10+184] + mov r12, QWORD PTR [r9] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-8], r13 + ; a[i+24] += m[24] * mu + mulx rcx, rax, QWORD PTR [r10+192] + mov r13, QWORD PTR [r9+8] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9], r12 + ; a[i+25] += m[25] * mu + mulx rcx, rax, QWORD PTR [r10+200] + mov r12, QWORD PTR [r9+16] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+8], r13 + ; a[i+26] += m[26] * mu + mulx rcx, rax, QWORD PTR [r10+208] + mov r13, QWORD PTR [r9+24] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+16], r12 + ; a[i+27] += m[27] * mu + mulx rcx, rax, QWORD PTR [r10+216] + mov r12, QWORD PTR [r9+32] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+24], r13 + ; a[i+28] += m[28] * mu + mulx rcx, rax, QWORD PTR [r10+224] + mov r13, QWORD PTR [r9+40] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+32], r12 + ; a[i+29] += m[29] * mu + mulx rcx, rax, QWORD PTR [r10+232] + mov r12, QWORD PTR [r9+48] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+40], r13 + ; a[i+30] += m[30] * mu + mulx rcx, rax, QWORD PTR [r10+240] + mov r13, QWORD PTR [r9+56] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+48], r12 + ; a[i+31] += m[31] * mu + mulx rcx, rax, QWORD PTR [r10+248] + mov r12, QWORD PTR [r9+64] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+56], r13 + ; a[i+32] += m[32] * mu + mulx rcx, rax, QWORD PTR [r10+256] + mov r13, QWORD PTR [r9+72] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+64], r12 + ; a[i+33] += m[33] * mu + mulx rcx, rax, QWORD PTR [r10+264] + mov r12, QWORD PTR [r9+80] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+72], r13 + ; a[i+34] += m[34] * mu + mulx rcx, rax, QWORD PTR [r10+272] + mov r13, QWORD PTR [r9+88] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+80], r12 + ; a[i+35] += m[35] * mu + mulx rcx, rax, QWORD PTR [r10+280] + mov r12, QWORD PTR [r9+96] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+88], r13 + ; a[i+36] += m[36] * mu + mulx rcx, rax, QWORD PTR [r10+288] + mov r13, QWORD PTR [r9+104] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+96], r12 + ; a[i+37] += m[37] * mu + mulx rcx, rax, QWORD PTR [r10+296] + mov r12, QWORD PTR [r9+112] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+104], r13 + ; a[i+38] += m[38] * mu + mulx rcx, rax, QWORD PTR [r10+304] + mov r13, QWORD PTR [r9+120] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+112], r12 + ; a[i+39] += m[39] * mu + mulx rcx, rax, QWORD PTR [r10+312] + mov r12, QWORD PTR [r9+128] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+120], r13 + ; a[i+40] += m[40] * mu + mulx rcx, rax, QWORD PTR [r10+320] + mov r13, QWORD PTR [r9+136] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+128], r12 + ; a[i+41] += m[41] * mu + mulx rcx, rax, QWORD PTR [r10+328] + mov r12, QWORD PTR [r9+144] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+136], r13 + ; a[i+42] += m[42] * mu + mulx rcx, rax, QWORD PTR [r10+336] + mov r13, QWORD PTR [r9+152] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+144], r12 + ; a[i+43] += m[43] * mu + mulx rcx, rax, QWORD PTR [r10+344] + mov r12, QWORD PTR [r9+160] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+152], r13 + ; a[i+44] += m[44] * mu + mulx rcx, rax, QWORD PTR [r10+352] + mov r13, QWORD PTR [r9+168] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+160], r12 + ; a[i+45] += m[45] * mu + mulx rcx, rax, QWORD PTR [r10+360] + mov r12, QWORD PTR [r9+176] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+168], r13 + ; a[i+46] += m[46] * mu + mulx rcx, rax, QWORD PTR [r10+368] + mov r13, QWORD PTR [r9+184] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+176], r12 + ; a[i+47] += m[47] * mu + mulx rcx, rax, QWORD PTR [r10+376] + mov r12, QWORD PTR [r9+192] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+184], r13 + adcx r12, rbp + mov rbp, r14 + mov QWORD PTR [r9+192], r12 + adox rbp, r14 + adcx rbp, r14 + ; a += 1 + add r9, 8 + ; i -= 1 + sub r11, 1 + jnz L_3072_mont_loop_avx2_48 + sub r9, 192 + neg rbp + mov r8, r9 + sub r9, 384 + mov rcx, QWORD PTR [r10] + mov rdx, r15 + pext rcx, rcx, rbp + sub rdx, rcx + mov rcx, QWORD PTR [r10+8] + mov rax, rdi + pext rcx, rcx, rbp + mov QWORD PTR [r9], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+16] + mov rcx, rsi + pext rdx, rdx, rbp + mov QWORD PTR [r9+8], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+24] + mov rdx, rbx + pext rax, rax, rbp + mov QWORD PTR [r9+16], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+32] + mov rax, QWORD PTR [r8+32] + pext rcx, rcx, rbp + mov QWORD PTR [r9+24], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+40] + mov rcx, QWORD PTR [r8+40] + pext rdx, rdx, rbp + mov QWORD PTR [r9+32], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+48] + mov rdx, QWORD PTR [r8+48] + pext rax, rax, rbp + mov QWORD PTR [r9+40], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+56] + mov rax, QWORD PTR [r8+56] + pext rcx, rcx, rbp + mov QWORD PTR [r9+48], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+64] + mov rcx, QWORD PTR [r8+64] + pext rdx, rdx, rbp + mov QWORD PTR [r9+56], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+72] + mov rdx, QWORD PTR [r8+72] + pext rax, rax, rbp + mov QWORD PTR [r9+64], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+80] + mov rax, QWORD PTR [r8+80] + pext rcx, rcx, rbp + mov QWORD PTR [r9+72], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+88] + mov rcx, QWORD PTR [r8+88] + pext rdx, rdx, rbp + mov QWORD PTR [r9+80], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+96] + mov rdx, QWORD PTR [r8+96] + pext rax, rax, rbp + mov QWORD PTR [r9+88], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+104] + mov rax, QWORD PTR [r8+104] + pext rcx, rcx, rbp + mov QWORD PTR [r9+96], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+112] + mov rcx, QWORD PTR [r8+112] + pext rdx, rdx, rbp + mov QWORD PTR [r9+104], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+120] + mov rdx, QWORD PTR [r8+120] + pext rax, rax, rbp + mov QWORD PTR [r9+112], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+128] + mov rax, QWORD PTR [r8+128] + pext rcx, rcx, rbp + mov QWORD PTR [r9+120], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+136] + mov rcx, QWORD PTR [r8+136] + pext rdx, rdx, rbp + mov QWORD PTR [r9+128], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+144] + mov rdx, QWORD PTR [r8+144] + pext rax, rax, rbp + mov QWORD PTR [r9+136], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+152] + mov rax, QWORD PTR [r8+152] + pext rcx, rcx, rbp + mov QWORD PTR [r9+144], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+160] + mov rcx, QWORD PTR [r8+160] + pext rdx, rdx, rbp + mov QWORD PTR [r9+152], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+168] + mov rdx, QWORD PTR [r8+168] + pext rax, rax, rbp + mov QWORD PTR [r9+160], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+176] + mov rax, QWORD PTR [r8+176] + pext rcx, rcx, rbp + mov QWORD PTR [r9+168], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+184] + mov rcx, QWORD PTR [r8+184] + pext rdx, rdx, rbp + mov QWORD PTR [r9+176], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+192] + mov rdx, QWORD PTR [r8+192] + pext rax, rax, rbp + mov QWORD PTR [r9+184], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+200] + mov rax, QWORD PTR [r8+200] + pext rcx, rcx, rbp + mov QWORD PTR [r9+192], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+208] + mov rcx, QWORD PTR [r8+208] + pext rdx, rdx, rbp + mov QWORD PTR [r9+200], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+216] + mov rdx, QWORD PTR [r8+216] + pext rax, rax, rbp + mov QWORD PTR [r9+208], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+224] + mov rax, QWORD PTR [r8+224] + pext rcx, rcx, rbp + mov QWORD PTR [r9+216], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+232] + mov rcx, QWORD PTR [r8+232] + pext rdx, rdx, rbp + mov QWORD PTR [r9+224], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+240] + mov rdx, QWORD PTR [r8+240] + pext rax, rax, rbp + mov QWORD PTR [r9+232], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+248] + mov rax, QWORD PTR [r8+248] + pext rcx, rcx, rbp + mov QWORD PTR [r9+240], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+256] + mov rcx, QWORD PTR [r8+256] + pext rdx, rdx, rbp + mov QWORD PTR [r9+248], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+264] + mov rdx, QWORD PTR [r8+264] + pext rax, rax, rbp + mov QWORD PTR [r9+256], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+272] + mov rax, QWORD PTR [r8+272] + pext rcx, rcx, rbp + mov QWORD PTR [r9+264], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+280] + mov rcx, QWORD PTR [r8+280] + pext rdx, rdx, rbp + mov QWORD PTR [r9+272], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+288] + mov rdx, QWORD PTR [r8+288] + pext rax, rax, rbp + mov QWORD PTR [r9+280], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+296] + mov rax, QWORD PTR [r8+296] + pext rcx, rcx, rbp + mov QWORD PTR [r9+288], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+304] + mov rcx, QWORD PTR [r8+304] + pext rdx, rdx, rbp + mov QWORD PTR [r9+296], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+312] + mov rdx, QWORD PTR [r8+312] + pext rax, rax, rbp + mov QWORD PTR [r9+304], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+320] + mov rax, QWORD PTR [r8+320] + pext rcx, rcx, rbp + mov QWORD PTR [r9+312], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+328] + mov rcx, QWORD PTR [r8+328] + pext rdx, rdx, rbp + mov QWORD PTR [r9+320], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+336] + mov rdx, QWORD PTR [r8+336] + pext rax, rax, rbp + mov QWORD PTR [r9+328], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+344] + mov rax, QWORD PTR [r8+344] + pext rcx, rcx, rbp + mov QWORD PTR [r9+336], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+352] + mov rcx, QWORD PTR [r8+352] + pext rdx, rdx, rbp + mov QWORD PTR [r9+344], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+360] + mov rdx, QWORD PTR [r8+360] + pext rax, rax, rbp + mov QWORD PTR [r9+352], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+368] + mov rax, QWORD PTR [r8+368] + pext rcx, rcx, rbp + mov QWORD PTR [r9+360], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+376] + mov rcx, QWORD PTR [r8+376] + pext rdx, rdx, rbp + mov QWORD PTR [r9+368], rax + sbb rcx, rdx + mov QWORD PTR [r9+376], rcx + pop rbp + pop rbx + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_3072_mont_reduce_avx2_48 ENDP +_text ENDS +ENDIF +; /* Conditionally add a and b using the mask m. +; * m is -1 to add and 0 when not. +; * +; * r A single precision number representing conditional add result. +; * a A single precision number to add with. +; * b A single precision number to add. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_3072_cond_add_24 PROC + sub rsp, 192 + mov rax, 0 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp], r10 + mov QWORD PTR [rsp+8], r11 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+16], r10 + mov QWORD PTR [rsp+24], r11 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+32], r10 + mov QWORD PTR [rsp+40], r11 + mov r10, QWORD PTR [r8+48] + mov r11, QWORD PTR [r8+56] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+48], r10 + mov QWORD PTR [rsp+56], r11 + mov r10, QWORD PTR [r8+64] + mov r11, QWORD PTR [r8+72] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+64], r10 + mov QWORD PTR [rsp+72], r11 + mov r10, QWORD PTR [r8+80] + mov r11, QWORD PTR [r8+88] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+80], r10 + mov QWORD PTR [rsp+88], r11 + mov r10, QWORD PTR [r8+96] + mov r11, QWORD PTR [r8+104] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+96], r10 + mov QWORD PTR [rsp+104], r11 + mov r10, QWORD PTR [r8+112] + mov r11, QWORD PTR [r8+120] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+112], r10 + mov QWORD PTR [rsp+120], r11 + mov r10, QWORD PTR [r8+128] + mov r11, QWORD PTR [r8+136] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+128], r10 + mov QWORD PTR [rsp+136], r11 + mov r10, QWORD PTR [r8+144] + mov r11, QWORD PTR [r8+152] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+144], r10 + mov QWORD PTR [rsp+152], r11 + mov r10, QWORD PTR [r8+160] + mov r11, QWORD PTR [r8+168] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+160], r10 + mov QWORD PTR [rsp+168], r11 + mov r10, QWORD PTR [r8+176] + mov r11, QWORD PTR [r8+184] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+176], r10 + mov QWORD PTR [rsp+184], r11 + mov r10, QWORD PTR [rdx] + mov r8, QWORD PTR [rsp] + add r10, r8 + mov r11, QWORD PTR [rdx+8] + mov r8, QWORD PTR [rsp+8] + adc r11, r8 + mov QWORD PTR [rcx], r10 + mov r10, QWORD PTR [rdx+16] + mov r8, QWORD PTR [rsp+16] + adc r10, r8 + mov QWORD PTR [rcx+8], r11 + mov r11, QWORD PTR [rdx+24] + mov r8, QWORD PTR [rsp+24] + adc r11, r8 + mov QWORD PTR [rcx+16], r10 + mov r10, QWORD PTR [rdx+32] + mov r8, QWORD PTR [rsp+32] + adc r10, r8 + mov QWORD PTR [rcx+24], r11 + mov r11, QWORD PTR [rdx+40] + mov r8, QWORD PTR [rsp+40] + adc r11, r8 + mov QWORD PTR [rcx+32], r10 + mov r10, QWORD PTR [rdx+48] + mov r8, QWORD PTR [rsp+48] + adc r10, r8 + mov QWORD PTR [rcx+40], r11 + mov r11, QWORD PTR [rdx+56] + mov r8, QWORD PTR [rsp+56] + adc r11, r8 + mov QWORD PTR [rcx+48], r10 + mov r10, QWORD PTR [rdx+64] + mov r8, QWORD PTR [rsp+64] + adc r10, r8 + mov QWORD PTR [rcx+56], r11 + mov r11, QWORD PTR [rdx+72] + mov r8, QWORD PTR [rsp+72] + adc r11, r8 + mov QWORD PTR [rcx+64], r10 + mov r10, QWORD PTR [rdx+80] + mov r8, QWORD PTR [rsp+80] + adc r10, r8 + mov QWORD PTR [rcx+72], r11 + mov r11, QWORD PTR [rdx+88] + mov r8, QWORD PTR [rsp+88] + adc r11, r8 + mov QWORD PTR [rcx+80], r10 + mov r10, QWORD PTR [rdx+96] + mov r8, QWORD PTR [rsp+96] + adc r10, r8 + mov QWORD PTR [rcx+88], r11 + mov r11, QWORD PTR [rdx+104] + mov r8, QWORD PTR [rsp+104] + adc r11, r8 + mov QWORD PTR [rcx+96], r10 + mov r10, QWORD PTR [rdx+112] + mov r8, QWORD PTR [rsp+112] + adc r10, r8 + mov QWORD PTR [rcx+104], r11 + mov r11, QWORD PTR [rdx+120] + mov r8, QWORD PTR [rsp+120] + adc r11, r8 + mov QWORD PTR [rcx+112], r10 + mov r10, QWORD PTR [rdx+128] + mov r8, QWORD PTR [rsp+128] + adc r10, r8 + mov QWORD PTR [rcx+120], r11 + mov r11, QWORD PTR [rdx+136] + mov r8, QWORD PTR [rsp+136] + adc r11, r8 + mov QWORD PTR [rcx+128], r10 + mov r10, QWORD PTR [rdx+144] + mov r8, QWORD PTR [rsp+144] + adc r10, r8 + mov QWORD PTR [rcx+136], r11 + mov r11, QWORD PTR [rdx+152] + mov r8, QWORD PTR [rsp+152] + adc r11, r8 + mov QWORD PTR [rcx+144], r10 + mov r10, QWORD PTR [rdx+160] + mov r8, QWORD PTR [rsp+160] + adc r10, r8 + mov QWORD PTR [rcx+152], r11 + mov r11, QWORD PTR [rdx+168] + mov r8, QWORD PTR [rsp+168] + adc r11, r8 + mov QWORD PTR [rcx+160], r10 + mov r10, QWORD PTR [rdx+176] + mov r8, QWORD PTR [rsp+176] + adc r10, r8 + mov QWORD PTR [rcx+168], r11 + mov r11, QWORD PTR [rdx+184] + mov r8, QWORD PTR [rsp+184] + adc r11, r8 + mov QWORD PTR [rcx+176], r10 + mov QWORD PTR [rcx+184], r11 + adc rax, 0 + add rsp, 192 + ret +sp_3072_cond_add_24 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Conditionally add a and b using the mask m. +; * m is -1 to add and 0 when not. +; * +; * r A single precision number representing conditional add result. +; * a A single precision number to add with. +; * b A single precision number to add. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_3072_cond_add_avx2_24 PROC + push r12 + mov rax, 0 + mov r12, QWORD PTR [r8] + mov r10, QWORD PTR [rdx] + pext r12, r12, r9 + add r10, r12 + mov r12, QWORD PTR [r8+8] + mov r11, QWORD PTR [rdx+8] + pext r12, r12, r9 + mov QWORD PTR [rcx], r10 + adc r11, r12 + mov r10, QWORD PTR [r8+16] + mov r12, QWORD PTR [rdx+16] + pext r10, r10, r9 + mov QWORD PTR [rcx+8], r11 + adc r12, r10 + mov r11, QWORD PTR [r8+24] + mov r10, QWORD PTR [rdx+24] + pext r11, r11, r9 + mov QWORD PTR [rcx+16], r12 + adc r10, r11 + mov r12, QWORD PTR [r8+32] + mov r11, QWORD PTR [rdx+32] + pext r12, r12, r9 + mov QWORD PTR [rcx+24], r10 + adc r11, r12 + mov r10, QWORD PTR [r8+40] + mov r12, QWORD PTR [rdx+40] + pext r10, r10, r9 + mov QWORD PTR [rcx+32], r11 + adc r12, r10 + mov r11, QWORD PTR [r8+48] + mov r10, QWORD PTR [rdx+48] + pext r11, r11, r9 + mov QWORD PTR [rcx+40], r12 + adc r10, r11 + mov r12, QWORD PTR [r8+56] + mov r11, QWORD PTR [rdx+56] + pext r12, r12, r9 + mov QWORD PTR [rcx+48], r10 + adc r11, r12 + mov r10, QWORD PTR [r8+64] + mov r12, QWORD PTR [rdx+64] + pext r10, r10, r9 + mov QWORD PTR [rcx+56], r11 + adc r12, r10 + mov r11, QWORD PTR [r8+72] + mov r10, QWORD PTR [rdx+72] + pext r11, r11, r9 + mov QWORD PTR [rcx+64], r12 + adc r10, r11 + mov r12, QWORD PTR [r8+80] + mov r11, QWORD PTR [rdx+80] + pext r12, r12, r9 + mov QWORD PTR [rcx+72], r10 + adc r11, r12 + mov r10, QWORD PTR [r8+88] + mov r12, QWORD PTR [rdx+88] + pext r10, r10, r9 + mov QWORD PTR [rcx+80], r11 + adc r12, r10 + mov r11, QWORD PTR [r8+96] + mov r10, QWORD PTR [rdx+96] + pext r11, r11, r9 + mov QWORD PTR [rcx+88], r12 + adc r10, r11 + mov r12, QWORD PTR [r8+104] + mov r11, QWORD PTR [rdx+104] + pext r12, r12, r9 + mov QWORD PTR [rcx+96], r10 + adc r11, r12 + mov r10, QWORD PTR [r8+112] + mov r12, QWORD PTR [rdx+112] + pext r10, r10, r9 + mov QWORD PTR [rcx+104], r11 + adc r12, r10 + mov r11, QWORD PTR [r8+120] + mov r10, QWORD PTR [rdx+120] + pext r11, r11, r9 + mov QWORD PTR [rcx+112], r12 + adc r10, r11 + mov r12, QWORD PTR [r8+128] + mov r11, QWORD PTR [rdx+128] + pext r12, r12, r9 + mov QWORD PTR [rcx+120], r10 + adc r11, r12 + mov r10, QWORD PTR [r8+136] + mov r12, QWORD PTR [rdx+136] + pext r10, r10, r9 + mov QWORD PTR [rcx+128], r11 + adc r12, r10 + mov r11, QWORD PTR [r8+144] + mov r10, QWORD PTR [rdx+144] + pext r11, r11, r9 + mov QWORD PTR [rcx+136], r12 + adc r10, r11 + mov r12, QWORD PTR [r8+152] + mov r11, QWORD PTR [rdx+152] + pext r12, r12, r9 + mov QWORD PTR [rcx+144], r10 + adc r11, r12 + mov r10, QWORD PTR [r8+160] + mov r12, QWORD PTR [rdx+160] + pext r10, r10, r9 + mov QWORD PTR [rcx+152], r11 + adc r12, r10 + mov r11, QWORD PTR [r8+168] + mov r10, QWORD PTR [rdx+168] + pext r11, r11, r9 + mov QWORD PTR [rcx+160], r12 + adc r10, r11 + mov r12, QWORD PTR [r8+176] + mov r11, QWORD PTR [rdx+176] + pext r12, r12, r9 + mov QWORD PTR [rcx+168], r10 + adc r11, r12 + mov r10, QWORD PTR [r8+184] + mov r12, QWORD PTR [rdx+184] + pext r10, r10, r9 + mov QWORD PTR [rcx+176], r11 + adc r12, r10 + mov QWORD PTR [rcx+184], r12 + adc rax, 0 + pop r12 + ret +sp_3072_cond_add_avx2_24 ENDP +_text ENDS +ENDIF +; /* Shift number left by n bit. (r = a << n) +; * +; * r Result of left shift by n. +; * a Number to shift. +; * n Amoutnt o shift. +; */ +_text SEGMENT READONLY PARA +sp_3072_lshift_48 PROC + push r12 + push r13 + mov r9, rcx + mov rcx, r8 + mov r12, 0 + mov r13, QWORD PTR [rdx+344] + mov rax, QWORD PTR [rdx+352] + mov r8, QWORD PTR [rdx+360] + mov r10, QWORD PTR [rdx+368] + mov r11, QWORD PTR [rdx+376] + shld r12, r11, cl + shld r11, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r13, cl + mov QWORD PTR [r9+352], rax + mov QWORD PTR [r9+360], r8 + mov QWORD PTR [r9+368], r10 + mov QWORD PTR [r9+376], r11 + mov QWORD PTR [r9+384], r12 + mov r11, QWORD PTR [rdx+312] + mov rax, QWORD PTR [rdx+320] + mov r8, QWORD PTR [rdx+328] + mov r10, QWORD PTR [rdx+336] + shld r13, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r11, cl + mov QWORD PTR [r9+320], rax + mov QWORD PTR [r9+328], r8 + mov QWORD PTR [r9+336], r10 + mov QWORD PTR [r9+344], r13 + mov r13, QWORD PTR [rdx+280] + mov rax, QWORD PTR [rdx+288] + mov r8, QWORD PTR [rdx+296] + mov r10, QWORD PTR [rdx+304] + shld r11, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r13, cl + mov QWORD PTR [r9+288], rax + mov QWORD PTR [r9+296], r8 + mov QWORD PTR [r9+304], r10 + mov QWORD PTR [r9+312], r11 + mov r11, QWORD PTR [rdx+248] + mov rax, QWORD PTR [rdx+256] + mov r8, QWORD PTR [rdx+264] + mov r10, QWORD PTR [rdx+272] + shld r13, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r11, cl + mov QWORD PTR [r9+256], rax + mov QWORD PTR [r9+264], r8 + mov QWORD PTR [r9+272], r10 + mov QWORD PTR [r9+280], r13 + mov r13, QWORD PTR [rdx+216] + mov rax, QWORD PTR [rdx+224] + mov r8, QWORD PTR [rdx+232] + mov r10, QWORD PTR [rdx+240] + shld r11, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r13, cl + mov QWORD PTR [r9+224], rax + mov QWORD PTR [r9+232], r8 + mov QWORD PTR [r9+240], r10 + mov QWORD PTR [r9+248], r11 + mov r11, QWORD PTR [rdx+184] + mov rax, QWORD PTR [rdx+192] + mov r8, QWORD PTR [rdx+200] + mov r10, QWORD PTR [rdx+208] + shld r13, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r11, cl + mov QWORD PTR [r9+192], rax + mov QWORD PTR [r9+200], r8 + mov QWORD PTR [r9+208], r10 + mov QWORD PTR [r9+216], r13 + mov r13, QWORD PTR [rdx+152] + mov rax, QWORD PTR [rdx+160] + mov r8, QWORD PTR [rdx+168] + mov r10, QWORD PTR [rdx+176] + shld r11, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r13, cl + mov QWORD PTR [r9+160], rax + mov QWORD PTR [r9+168], r8 + mov QWORD PTR [r9+176], r10 + mov QWORD PTR [r9+184], r11 + mov r11, QWORD PTR [rdx+120] + mov rax, QWORD PTR [rdx+128] + mov r8, QWORD PTR [rdx+136] + mov r10, QWORD PTR [rdx+144] + shld r13, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r11, cl + mov QWORD PTR [r9+128], rax + mov QWORD PTR [r9+136], r8 + mov QWORD PTR [r9+144], r10 + mov QWORD PTR [r9+152], r13 + mov r13, QWORD PTR [rdx+88] + mov rax, QWORD PTR [rdx+96] + mov r8, QWORD PTR [rdx+104] + mov r10, QWORD PTR [rdx+112] + shld r11, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r13, cl + mov QWORD PTR [r9+96], rax + mov QWORD PTR [r9+104], r8 + mov QWORD PTR [r9+112], r10 + mov QWORD PTR [r9+120], r11 + mov r11, QWORD PTR [rdx+56] + mov rax, QWORD PTR [rdx+64] + mov r8, QWORD PTR [rdx+72] + mov r10, QWORD PTR [rdx+80] + shld r13, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r11, cl + mov QWORD PTR [r9+64], rax + mov QWORD PTR [r9+72], r8 + mov QWORD PTR [r9+80], r10 + mov QWORD PTR [r9+88], r13 + mov r13, QWORD PTR [rdx+24] + mov rax, QWORD PTR [rdx+32] + mov r8, QWORD PTR [rdx+40] + mov r10, QWORD PTR [rdx+48] + shld r11, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r13, cl + mov QWORD PTR [r9+32], rax + mov QWORD PTR [r9+40], r8 + mov QWORD PTR [r9+48], r10 + mov QWORD PTR [r9+56], r11 + mov rax, QWORD PTR [rdx] + mov r8, QWORD PTR [rdx+8] + mov r10, QWORD PTR [rdx+16] + shld r13, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shl rax, cl + mov QWORD PTR [r9], rax + mov QWORD PTR [r9+8], r8 + mov QWORD PTR [r9+16], r10 + mov QWORD PTR [r9+24], r13 + pop r13 + pop r12 + ret +sp_3072_lshift_48 ENDP +_text ENDS +ENDIF +ENDIF +IFDEF WOLFSSL_SP_4096 +IFDEF WOLFSSL_SP_4096 +; /* Read big endian unsigned byte array into r. +; * Uses the bswap instruction. +; * +; * r A single precision integer. +; * size Maximum number of bytes to convert +; * a Byte array. +; * n Number of bytes in array to read. +; */ +_text SEGMENT READONLY PARA +sp_4096_from_bin_bswap PROC + push r12 + push r13 + mov r11, r8 + mov r12, rcx + add r11, r9 + add r12, 512 + xor r13, r13 + jmp L_4096_from_bin_bswap_64_end +L_4096_from_bin_bswap_64_start: + sub r11, 64 + mov rax, QWORD PTR [r11+56] + mov r10, QWORD PTR [r11+48] + bswap rax + bswap r10 + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r10 + mov rax, QWORD PTR [r11+40] + mov r10, QWORD PTR [r11+32] + bswap rax + bswap r10 + mov QWORD PTR [rcx+16], rax + mov QWORD PTR [rcx+24], r10 + mov rax, QWORD PTR [r11+24] + mov r10, QWORD PTR [r11+16] + bswap rax + bswap r10 + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r10 + mov rax, QWORD PTR [r11+8] + mov r10, QWORD PTR [r11] + bswap rax + bswap r10 + mov QWORD PTR [rcx+48], rax + mov QWORD PTR [rcx+56], r10 + add rcx, 64 + sub r9, 64 +L_4096_from_bin_bswap_64_end: + cmp r9, 63 + jg L_4096_from_bin_bswap_64_start + jmp L_4096_from_bin_bswap_8_end +L_4096_from_bin_bswap_8_start: + sub r11, 8 + mov rax, QWORD PTR [r11] + bswap rax + mov QWORD PTR [rcx], rax + add rcx, 8 + sub r9, 8 +L_4096_from_bin_bswap_8_end: + cmp r9, 7 + jg L_4096_from_bin_bswap_8_start + cmp r9, r13 + je L_4096_from_bin_bswap_hi_end + mov r10, r13 + mov rax, r13 +L_4096_from_bin_bswap_hi_start: + mov al, BYTE PTR [r8] + shl r10, 8 + inc r8 + add r10, rax + dec r9 + jg L_4096_from_bin_bswap_hi_start + mov QWORD PTR [rcx], r10 + add rcx, 8 +L_4096_from_bin_bswap_hi_end: + cmp rcx, r12 + je L_4096_from_bin_bswap_zero_end +L_4096_from_bin_bswap_zero_start: + mov QWORD PTR [rcx], r13 + add rcx, 8 + cmp rcx, r12 + jl L_4096_from_bin_bswap_zero_start +L_4096_from_bin_bswap_zero_end: + pop r13 + pop r12 + ret +sp_4096_from_bin_bswap ENDP +_text ENDS +IFNDEF NO_MOVBE_SUPPORT +; /* Read big endian unsigned byte array into r. +; * Uses the movbe instruction which is an optional instruction. +; * +; * r A single precision integer. +; * size Maximum number of bytes to convert +; * a Byte array. +; * n Number of bytes in array to read. +; */ +_text SEGMENT READONLY PARA +sp_4096_from_bin_movbe PROC + push r12 + push r13 + mov r11, r8 + mov r12, rcx + add r11, r9 + add r12, 512 + xor r13, r13 + jmp L_4096_from_bin_movbe_64_end +L_4096_from_bin_movbe_64_start: + sub r11, 64 + movbe rax, QWORD PTR [r11+56] + movbe r10, QWORD PTR [r11+48] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r10 + movbe rax, QWORD PTR [r11+40] + movbe r10, QWORD PTR [r11+32] + mov QWORD PTR [rcx+16], rax + mov QWORD PTR [rcx+24], r10 + movbe rax, QWORD PTR [r11+24] + movbe r10, QWORD PTR [r11+16] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r10 + movbe rax, QWORD PTR [r11+8] + movbe r10, QWORD PTR [r11] + mov QWORD PTR [rcx+48], rax + mov QWORD PTR [rcx+56], r10 + add rcx, 64 + sub r9, 64 +L_4096_from_bin_movbe_64_end: + cmp r9, 63 + jg L_4096_from_bin_movbe_64_start + jmp L_4096_from_bin_movbe_8_end +L_4096_from_bin_movbe_8_start: + sub r11, 8 + movbe rax, QWORD PTR [r11] + mov QWORD PTR [rcx], rax + add rcx, 8 + sub r9, 8 +L_4096_from_bin_movbe_8_end: + cmp r9, 7 + jg L_4096_from_bin_movbe_8_start + cmp r9, r13 + je L_4096_from_bin_movbe_hi_end + mov r10, r13 + mov rax, r13 +L_4096_from_bin_movbe_hi_start: + mov al, BYTE PTR [r8] + shl r10, 8 + inc r8 + add r10, rax + dec r9 + jg L_4096_from_bin_movbe_hi_start + mov QWORD PTR [rcx], r10 + add rcx, 8 +L_4096_from_bin_movbe_hi_end: + cmp rcx, r12 + je L_4096_from_bin_movbe_zero_end +L_4096_from_bin_movbe_zero_start: + mov QWORD PTR [rcx], r13 + add rcx, 8 + cmp rcx, r12 + jl L_4096_from_bin_movbe_zero_start +L_4096_from_bin_movbe_zero_end: + pop r13 + pop r12 + ret +sp_4096_from_bin_movbe ENDP +_text ENDS +ENDIF +; /* Write r as big endian to byte array. +; * Fixed length number of bytes written: 512 +; * Uses the bswap instruction. +; * +; * r A single precision integer. +; * a Byte array. +; */ +_text SEGMENT READONLY PARA +sp_4096_to_bin_bswap PROC + mov rax, QWORD PTR [rcx+504] + mov r8, QWORD PTR [rcx+496] + bswap rax + bswap r8 + mov QWORD PTR [rdx], rax + mov QWORD PTR [rdx+8], r8 + mov rax, QWORD PTR [rcx+488] + mov r8, QWORD PTR [rcx+480] + bswap rax + bswap r8 + mov QWORD PTR [rdx+16], rax + mov QWORD PTR [rdx+24], r8 + mov rax, QWORD PTR [rcx+472] + mov r8, QWORD PTR [rcx+464] + bswap rax + bswap r8 + mov QWORD PTR [rdx+32], rax + mov QWORD PTR [rdx+40], r8 + mov rax, QWORD PTR [rcx+456] + mov r8, QWORD PTR [rcx+448] + bswap rax + bswap r8 + mov QWORD PTR [rdx+48], rax + mov QWORD PTR [rdx+56], r8 + mov rax, QWORD PTR [rcx+440] + mov r8, QWORD PTR [rcx+432] + bswap rax + bswap r8 + mov QWORD PTR [rdx+64], rax + mov QWORD PTR [rdx+72], r8 + mov rax, QWORD PTR [rcx+424] + mov r8, QWORD PTR [rcx+416] + bswap rax + bswap r8 + mov QWORD PTR [rdx+80], rax + mov QWORD PTR [rdx+88], r8 + mov rax, QWORD PTR [rcx+408] + mov r8, QWORD PTR [rcx+400] + bswap rax + bswap r8 + mov QWORD PTR [rdx+96], rax + mov QWORD PTR [rdx+104], r8 + mov rax, QWORD PTR [rcx+392] + mov r8, QWORD PTR [rcx+384] + bswap rax + bswap r8 + mov QWORD PTR [rdx+112], rax + mov QWORD PTR [rdx+120], r8 + mov rax, QWORD PTR [rcx+376] + mov r8, QWORD PTR [rcx+368] + bswap rax + bswap r8 + mov QWORD PTR [rdx+128], rax + mov QWORD PTR [rdx+136], r8 + mov rax, QWORD PTR [rcx+360] + mov r8, QWORD PTR [rcx+352] + bswap rax + bswap r8 + mov QWORD PTR [rdx+144], rax + mov QWORD PTR [rdx+152], r8 + mov rax, QWORD PTR [rcx+344] + mov r8, QWORD PTR [rcx+336] + bswap rax + bswap r8 + mov QWORD PTR [rdx+160], rax + mov QWORD PTR [rdx+168], r8 + mov rax, QWORD PTR [rcx+328] + mov r8, QWORD PTR [rcx+320] + bswap rax + bswap r8 + mov QWORD PTR [rdx+176], rax + mov QWORD PTR [rdx+184], r8 + mov rax, QWORD PTR [rcx+312] + mov r8, QWORD PTR [rcx+304] + bswap rax + bswap r8 + mov QWORD PTR [rdx+192], rax + mov QWORD PTR [rdx+200], r8 + mov rax, QWORD PTR [rcx+296] + mov r8, QWORD PTR [rcx+288] + bswap rax + bswap r8 + mov QWORD PTR [rdx+208], rax + mov QWORD PTR [rdx+216], r8 + mov rax, QWORD PTR [rcx+280] + mov r8, QWORD PTR [rcx+272] + bswap rax + bswap r8 + mov QWORD PTR [rdx+224], rax + mov QWORD PTR [rdx+232], r8 + mov rax, QWORD PTR [rcx+264] + mov r8, QWORD PTR [rcx+256] + bswap rax + bswap r8 + mov QWORD PTR [rdx+240], rax + mov QWORD PTR [rdx+248], r8 + mov rax, QWORD PTR [rcx+248] + mov r8, QWORD PTR [rcx+240] + bswap rax + bswap r8 + mov QWORD PTR [rdx+256], rax + mov QWORD PTR [rdx+264], r8 + mov rax, QWORD PTR [rcx+232] + mov r8, QWORD PTR [rcx+224] + bswap rax + bswap r8 + mov QWORD PTR [rdx+272], rax + mov QWORD PTR [rdx+280], r8 + mov rax, QWORD PTR [rcx+216] + mov r8, QWORD PTR [rcx+208] + bswap rax + bswap r8 + mov QWORD PTR [rdx+288], rax + mov QWORD PTR [rdx+296], r8 + mov rax, QWORD PTR [rcx+200] + mov r8, QWORD PTR [rcx+192] + bswap rax + bswap r8 + mov QWORD PTR [rdx+304], rax + mov QWORD PTR [rdx+312], r8 + mov rax, QWORD PTR [rcx+184] + mov r8, QWORD PTR [rcx+176] + bswap rax + bswap r8 + mov QWORD PTR [rdx+320], rax + mov QWORD PTR [rdx+328], r8 + mov rax, QWORD PTR [rcx+168] + mov r8, QWORD PTR [rcx+160] + bswap rax + bswap r8 + mov QWORD PTR [rdx+336], rax + mov QWORD PTR [rdx+344], r8 + mov rax, QWORD PTR [rcx+152] + mov r8, QWORD PTR [rcx+144] + bswap rax + bswap r8 + mov QWORD PTR [rdx+352], rax + mov QWORD PTR [rdx+360], r8 + mov rax, QWORD PTR [rcx+136] + mov r8, QWORD PTR [rcx+128] + bswap rax + bswap r8 + mov QWORD PTR [rdx+368], rax + mov QWORD PTR [rdx+376], r8 + mov rax, QWORD PTR [rcx+120] + mov r8, QWORD PTR [rcx+112] + bswap rax + bswap r8 + mov QWORD PTR [rdx+384], rax + mov QWORD PTR [rdx+392], r8 + mov rax, QWORD PTR [rcx+104] + mov r8, QWORD PTR [rcx+96] + bswap rax + bswap r8 + mov QWORD PTR [rdx+400], rax + mov QWORD PTR [rdx+408], r8 + mov rax, QWORD PTR [rcx+88] + mov r8, QWORD PTR [rcx+80] + bswap rax + bswap r8 + mov QWORD PTR [rdx+416], rax + mov QWORD PTR [rdx+424], r8 + mov rax, QWORD PTR [rcx+72] + mov r8, QWORD PTR [rcx+64] + bswap rax + bswap r8 + mov QWORD PTR [rdx+432], rax + mov QWORD PTR [rdx+440], r8 + mov rax, QWORD PTR [rcx+56] + mov r8, QWORD PTR [rcx+48] + bswap rax + bswap r8 + mov QWORD PTR [rdx+448], rax + mov QWORD PTR [rdx+456], r8 + mov rax, QWORD PTR [rcx+40] + mov r8, QWORD PTR [rcx+32] + bswap rax + bswap r8 + mov QWORD PTR [rdx+464], rax + mov QWORD PTR [rdx+472], r8 + mov rax, QWORD PTR [rcx+24] + mov r8, QWORD PTR [rcx+16] + bswap rax + bswap r8 + mov QWORD PTR [rdx+480], rax + mov QWORD PTR [rdx+488], r8 + mov rax, QWORD PTR [rcx+8] + mov r8, QWORD PTR [rcx] + bswap rax + bswap r8 + mov QWORD PTR [rdx+496], rax + mov QWORD PTR [rdx+504], r8 + ret +sp_4096_to_bin_bswap ENDP +_text ENDS +IFNDEF NO_MOVBE_SUPPORT +; /* Write r as big endian to byte array. +; * Fixed length number of bytes written: 512 +; * Uses the movbe instruction which is optional. +; * +; * r A single precision integer. +; * a Byte array. +; */ +_text SEGMENT READONLY PARA +sp_4096_to_bin_movbe PROC + movbe rax, QWORD PTR [rcx+504] + movbe r8, QWORD PTR [rcx+496] + mov QWORD PTR [rdx], rax + mov QWORD PTR [rdx+8], r8 + movbe rax, QWORD PTR [rcx+488] + movbe r8, QWORD PTR [rcx+480] + mov QWORD PTR [rdx+16], rax + mov QWORD PTR [rdx+24], r8 + movbe rax, QWORD PTR [rcx+472] + movbe r8, QWORD PTR [rcx+464] + mov QWORD PTR [rdx+32], rax + mov QWORD PTR [rdx+40], r8 + movbe rax, QWORD PTR [rcx+456] + movbe r8, QWORD PTR [rcx+448] + mov QWORD PTR [rdx+48], rax + mov QWORD PTR [rdx+56], r8 + movbe rax, QWORD PTR [rcx+440] + movbe r8, QWORD PTR [rcx+432] + mov QWORD PTR [rdx+64], rax + mov QWORD PTR [rdx+72], r8 + movbe rax, QWORD PTR [rcx+424] + movbe r8, QWORD PTR [rcx+416] + mov QWORD PTR [rdx+80], rax + mov QWORD PTR [rdx+88], r8 + movbe rax, QWORD PTR [rcx+408] + movbe r8, QWORD PTR [rcx+400] + mov QWORD PTR [rdx+96], rax + mov QWORD PTR [rdx+104], r8 + movbe rax, QWORD PTR [rcx+392] + movbe r8, QWORD PTR [rcx+384] + mov QWORD PTR [rdx+112], rax + mov QWORD PTR [rdx+120], r8 + movbe rax, QWORD PTR [rcx+376] + movbe r8, QWORD PTR [rcx+368] + mov QWORD PTR [rdx+128], rax + mov QWORD PTR [rdx+136], r8 + movbe rax, QWORD PTR [rcx+360] + movbe r8, QWORD PTR [rcx+352] + mov QWORD PTR [rdx+144], rax + mov QWORD PTR [rdx+152], r8 + movbe rax, QWORD PTR [rcx+344] + movbe r8, QWORD PTR [rcx+336] + mov QWORD PTR [rdx+160], rax + mov QWORD PTR [rdx+168], r8 + movbe rax, QWORD PTR [rcx+328] + movbe r8, QWORD PTR [rcx+320] + mov QWORD PTR [rdx+176], rax + mov QWORD PTR [rdx+184], r8 + movbe rax, QWORD PTR [rcx+312] + movbe r8, QWORD PTR [rcx+304] + mov QWORD PTR [rdx+192], rax + mov QWORD PTR [rdx+200], r8 + movbe rax, QWORD PTR [rcx+296] + movbe r8, QWORD PTR [rcx+288] + mov QWORD PTR [rdx+208], rax + mov QWORD PTR [rdx+216], r8 + movbe rax, QWORD PTR [rcx+280] + movbe r8, QWORD PTR [rcx+272] + mov QWORD PTR [rdx+224], rax + mov QWORD PTR [rdx+232], r8 + movbe rax, QWORD PTR [rcx+264] + movbe r8, QWORD PTR [rcx+256] + mov QWORD PTR [rdx+240], rax + mov QWORD PTR [rdx+248], r8 + movbe rax, QWORD PTR [rcx+248] + movbe r8, QWORD PTR [rcx+240] + mov QWORD PTR [rdx+256], rax + mov QWORD PTR [rdx+264], r8 + movbe rax, QWORD PTR [rcx+232] + movbe r8, QWORD PTR [rcx+224] + mov QWORD PTR [rdx+272], rax + mov QWORD PTR [rdx+280], r8 + movbe rax, QWORD PTR [rcx+216] + movbe r8, QWORD PTR [rcx+208] + mov QWORD PTR [rdx+288], rax + mov QWORD PTR [rdx+296], r8 + movbe rax, QWORD PTR [rcx+200] + movbe r8, QWORD PTR [rcx+192] + mov QWORD PTR [rdx+304], rax + mov QWORD PTR [rdx+312], r8 + movbe rax, QWORD PTR [rcx+184] + movbe r8, QWORD PTR [rcx+176] + mov QWORD PTR [rdx+320], rax + mov QWORD PTR [rdx+328], r8 + movbe rax, QWORD PTR [rcx+168] + movbe r8, QWORD PTR [rcx+160] + mov QWORD PTR [rdx+336], rax + mov QWORD PTR [rdx+344], r8 + movbe rax, QWORD PTR [rcx+152] + movbe r8, QWORD PTR [rcx+144] + mov QWORD PTR [rdx+352], rax + mov QWORD PTR [rdx+360], r8 + movbe rax, QWORD PTR [rcx+136] + movbe r8, QWORD PTR [rcx+128] + mov QWORD PTR [rdx+368], rax + mov QWORD PTR [rdx+376], r8 + movbe rax, QWORD PTR [rcx+120] + movbe r8, QWORD PTR [rcx+112] + mov QWORD PTR [rdx+384], rax + mov QWORD PTR [rdx+392], r8 + movbe rax, QWORD PTR [rcx+104] + movbe r8, QWORD PTR [rcx+96] + mov QWORD PTR [rdx+400], rax + mov QWORD PTR [rdx+408], r8 + movbe rax, QWORD PTR [rcx+88] + movbe r8, QWORD PTR [rcx+80] + mov QWORD PTR [rdx+416], rax + mov QWORD PTR [rdx+424], r8 + movbe rax, QWORD PTR [rcx+72] + movbe r8, QWORD PTR [rcx+64] + mov QWORD PTR [rdx+432], rax + mov QWORD PTR [rdx+440], r8 + movbe rax, QWORD PTR [rcx+56] + movbe r8, QWORD PTR [rcx+48] + mov QWORD PTR [rdx+448], rax + mov QWORD PTR [rdx+456], r8 + movbe rax, QWORD PTR [rcx+40] + movbe r8, QWORD PTR [rcx+32] + mov QWORD PTR [rdx+464], rax + mov QWORD PTR [rdx+472], r8 + movbe rax, QWORD PTR [rcx+24] + movbe r8, QWORD PTR [rcx+16] + mov QWORD PTR [rdx+480], rax + mov QWORD PTR [rdx+488], r8 + movbe rax, QWORD PTR [rcx+8] + movbe r8, QWORD PTR [rcx] + mov QWORD PTR [rdx+496], rax + mov QWORD PTR [rdx+504], r8 + ret +sp_4096_to_bin_movbe ENDP +_text ENDS +ENDIF +; /* Sub b from a into a. (a -= b) +; * +; * a A single precision integer and result. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_4096_sub_in_place_64 PROC + mov r8, QWORD PTR [rcx] + xor rax, rax + sub r8, QWORD PTR [rdx] + mov r9, QWORD PTR [rcx+8] + mov QWORD PTR [rcx], r8 + sbb r9, QWORD PTR [rdx+8] + mov r8, QWORD PTR [rcx+16] + mov QWORD PTR [rcx+8], r9 + sbb r8, QWORD PTR [rdx+16] + mov r9, QWORD PTR [rcx+24] + mov QWORD PTR [rcx+16], r8 + sbb r9, QWORD PTR [rdx+24] + mov r8, QWORD PTR [rcx+32] + mov QWORD PTR [rcx+24], r9 + sbb r8, QWORD PTR [rdx+32] + mov r9, QWORD PTR [rcx+40] + mov QWORD PTR [rcx+32], r8 + sbb r9, QWORD PTR [rdx+40] + mov r8, QWORD PTR [rcx+48] + mov QWORD PTR [rcx+40], r9 + sbb r8, QWORD PTR [rdx+48] + mov r9, QWORD PTR [rcx+56] + mov QWORD PTR [rcx+48], r8 + sbb r9, QWORD PTR [rdx+56] + mov r8, QWORD PTR [rcx+64] + mov QWORD PTR [rcx+56], r9 + sbb r8, QWORD PTR [rdx+64] + mov r9, QWORD PTR [rcx+72] + mov QWORD PTR [rcx+64], r8 + sbb r9, QWORD PTR [rdx+72] + mov r8, QWORD PTR [rcx+80] + mov QWORD PTR [rcx+72], r9 + sbb r8, QWORD PTR [rdx+80] + mov r9, QWORD PTR [rcx+88] + mov QWORD PTR [rcx+80], r8 + sbb r9, QWORD PTR [rdx+88] + mov r8, QWORD PTR [rcx+96] + mov QWORD PTR [rcx+88], r9 + sbb r8, QWORD PTR [rdx+96] + mov r9, QWORD PTR [rcx+104] + mov QWORD PTR [rcx+96], r8 + sbb r9, QWORD PTR [rdx+104] + mov r8, QWORD PTR [rcx+112] + mov QWORD PTR [rcx+104], r9 + sbb r8, QWORD PTR [rdx+112] + mov r9, QWORD PTR [rcx+120] + mov QWORD PTR [rcx+112], r8 + sbb r9, QWORD PTR [rdx+120] + mov r8, QWORD PTR [rcx+128] + mov QWORD PTR [rcx+120], r9 + sbb r8, QWORD PTR [rdx+128] + mov r9, QWORD PTR [rcx+136] + mov QWORD PTR [rcx+128], r8 + sbb r9, QWORD PTR [rdx+136] + mov r8, QWORD PTR [rcx+144] + mov QWORD PTR [rcx+136], r9 + sbb r8, QWORD PTR [rdx+144] + mov r9, QWORD PTR [rcx+152] + mov QWORD PTR [rcx+144], r8 + sbb r9, QWORD PTR [rdx+152] + mov r8, QWORD PTR [rcx+160] + mov QWORD PTR [rcx+152], r9 + sbb r8, QWORD PTR [rdx+160] + mov r9, QWORD PTR [rcx+168] + mov QWORD PTR [rcx+160], r8 + sbb r9, QWORD PTR [rdx+168] + mov r8, QWORD PTR [rcx+176] + mov QWORD PTR [rcx+168], r9 + sbb r8, QWORD PTR [rdx+176] + mov r9, QWORD PTR [rcx+184] + mov QWORD PTR [rcx+176], r8 + sbb r9, QWORD PTR [rdx+184] + mov r8, QWORD PTR [rcx+192] + mov QWORD PTR [rcx+184], r9 + sbb r8, QWORD PTR [rdx+192] + mov r9, QWORD PTR [rcx+200] + mov QWORD PTR [rcx+192], r8 + sbb r9, QWORD PTR [rdx+200] + mov r8, QWORD PTR [rcx+208] + mov QWORD PTR [rcx+200], r9 + sbb r8, QWORD PTR [rdx+208] + mov r9, QWORD PTR [rcx+216] + mov QWORD PTR [rcx+208], r8 + sbb r9, QWORD PTR [rdx+216] + mov r8, QWORD PTR [rcx+224] + mov QWORD PTR [rcx+216], r9 + sbb r8, QWORD PTR [rdx+224] + mov r9, QWORD PTR [rcx+232] + mov QWORD PTR [rcx+224], r8 + sbb r9, QWORD PTR [rdx+232] + mov r8, QWORD PTR [rcx+240] + mov QWORD PTR [rcx+232], r9 + sbb r8, QWORD PTR [rdx+240] + mov r9, QWORD PTR [rcx+248] + mov QWORD PTR [rcx+240], r8 + sbb r9, QWORD PTR [rdx+248] + mov r8, QWORD PTR [rcx+256] + mov QWORD PTR [rcx+248], r9 + sbb r8, QWORD PTR [rdx+256] + mov r9, QWORD PTR [rcx+264] + mov QWORD PTR [rcx+256], r8 + sbb r9, QWORD PTR [rdx+264] + mov r8, QWORD PTR [rcx+272] + mov QWORD PTR [rcx+264], r9 + sbb r8, QWORD PTR [rdx+272] + mov r9, QWORD PTR [rcx+280] + mov QWORD PTR [rcx+272], r8 + sbb r9, QWORD PTR [rdx+280] + mov r8, QWORD PTR [rcx+288] + mov QWORD PTR [rcx+280], r9 + sbb r8, QWORD PTR [rdx+288] + mov r9, QWORD PTR [rcx+296] + mov QWORD PTR [rcx+288], r8 + sbb r9, QWORD PTR [rdx+296] + mov r8, QWORD PTR [rcx+304] + mov QWORD PTR [rcx+296], r9 + sbb r8, QWORD PTR [rdx+304] + mov r9, QWORD PTR [rcx+312] + mov QWORD PTR [rcx+304], r8 + sbb r9, QWORD PTR [rdx+312] + mov r8, QWORD PTR [rcx+320] + mov QWORD PTR [rcx+312], r9 + sbb r8, QWORD PTR [rdx+320] + mov r9, QWORD PTR [rcx+328] + mov QWORD PTR [rcx+320], r8 + sbb r9, QWORD PTR [rdx+328] + mov r8, QWORD PTR [rcx+336] + mov QWORD PTR [rcx+328], r9 + sbb r8, QWORD PTR [rdx+336] + mov r9, QWORD PTR [rcx+344] + mov QWORD PTR [rcx+336], r8 + sbb r9, QWORD PTR [rdx+344] + mov r8, QWORD PTR [rcx+352] + mov QWORD PTR [rcx+344], r9 + sbb r8, QWORD PTR [rdx+352] + mov r9, QWORD PTR [rcx+360] + mov QWORD PTR [rcx+352], r8 + sbb r9, QWORD PTR [rdx+360] + mov r8, QWORD PTR [rcx+368] + mov QWORD PTR [rcx+360], r9 + sbb r8, QWORD PTR [rdx+368] + mov r9, QWORD PTR [rcx+376] + mov QWORD PTR [rcx+368], r8 + sbb r9, QWORD PTR [rdx+376] + mov r8, QWORD PTR [rcx+384] + mov QWORD PTR [rcx+376], r9 + sbb r8, QWORD PTR [rdx+384] + mov r9, QWORD PTR [rcx+392] + mov QWORD PTR [rcx+384], r8 + sbb r9, QWORD PTR [rdx+392] + mov r8, QWORD PTR [rcx+400] + mov QWORD PTR [rcx+392], r9 + sbb r8, QWORD PTR [rdx+400] + mov r9, QWORD PTR [rcx+408] + mov QWORD PTR [rcx+400], r8 + sbb r9, QWORD PTR [rdx+408] + mov r8, QWORD PTR [rcx+416] + mov QWORD PTR [rcx+408], r9 + sbb r8, QWORD PTR [rdx+416] + mov r9, QWORD PTR [rcx+424] + mov QWORD PTR [rcx+416], r8 + sbb r9, QWORD PTR [rdx+424] + mov r8, QWORD PTR [rcx+432] + mov QWORD PTR [rcx+424], r9 + sbb r8, QWORD PTR [rdx+432] + mov r9, QWORD PTR [rcx+440] + mov QWORD PTR [rcx+432], r8 + sbb r9, QWORD PTR [rdx+440] + mov r8, QWORD PTR [rcx+448] + mov QWORD PTR [rcx+440], r9 + sbb r8, QWORD PTR [rdx+448] + mov r9, QWORD PTR [rcx+456] + mov QWORD PTR [rcx+448], r8 + sbb r9, QWORD PTR [rdx+456] + mov r8, QWORD PTR [rcx+464] + mov QWORD PTR [rcx+456], r9 + sbb r8, QWORD PTR [rdx+464] + mov r9, QWORD PTR [rcx+472] + mov QWORD PTR [rcx+464], r8 + sbb r9, QWORD PTR [rdx+472] + mov r8, QWORD PTR [rcx+480] + mov QWORD PTR [rcx+472], r9 + sbb r8, QWORD PTR [rdx+480] + mov r9, QWORD PTR [rcx+488] + mov QWORD PTR [rcx+480], r8 + sbb r9, QWORD PTR [rdx+488] + mov r8, QWORD PTR [rcx+496] + mov QWORD PTR [rcx+488], r9 + sbb r8, QWORD PTR [rdx+496] + mov r9, QWORD PTR [rcx+504] + mov QWORD PTR [rcx+496], r8 + sbb r9, QWORD PTR [rdx+504] + mov QWORD PTR [rcx+504], r9 + sbb rax, 0 + ret +sp_4096_sub_in_place_64 ENDP +_text ENDS +; /* Add b to a into r. (r = a + b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_4096_add_64 PROC + ; Add + mov r9, QWORD PTR [rdx] + xor rax, rax + add r9, QWORD PTR [r8] + mov r10, QWORD PTR [rdx+8] + mov QWORD PTR [rcx], r9 + adc r10, QWORD PTR [r8+8] + mov r9, QWORD PTR [rdx+16] + mov QWORD PTR [rcx+8], r10 + adc r9, QWORD PTR [r8+16] + mov r10, QWORD PTR [rdx+24] + mov QWORD PTR [rcx+16], r9 + adc r10, QWORD PTR [r8+24] + mov r9, QWORD PTR [rdx+32] + mov QWORD PTR [rcx+24], r10 + adc r9, QWORD PTR [r8+32] + mov r10, QWORD PTR [rdx+40] + mov QWORD PTR [rcx+32], r9 + adc r10, QWORD PTR [r8+40] + mov r9, QWORD PTR [rdx+48] + mov QWORD PTR [rcx+40], r10 + adc r9, QWORD PTR [r8+48] + mov r10, QWORD PTR [rdx+56] + mov QWORD PTR [rcx+48], r9 + adc r10, QWORD PTR [r8+56] + mov r9, QWORD PTR [rdx+64] + mov QWORD PTR [rcx+56], r10 + adc r9, QWORD PTR [r8+64] + mov r10, QWORD PTR [rdx+72] + mov QWORD PTR [rcx+64], r9 + adc r10, QWORD PTR [r8+72] + mov r9, QWORD PTR [rdx+80] + mov QWORD PTR [rcx+72], r10 + adc r9, QWORD PTR [r8+80] + mov r10, QWORD PTR [rdx+88] + mov QWORD PTR [rcx+80], r9 + adc r10, QWORD PTR [r8+88] + mov r9, QWORD PTR [rdx+96] + mov QWORD PTR [rcx+88], r10 + adc r9, QWORD PTR [r8+96] + mov r10, QWORD PTR [rdx+104] + mov QWORD PTR [rcx+96], r9 + adc r10, QWORD PTR [r8+104] + mov r9, QWORD PTR [rdx+112] + mov QWORD PTR [rcx+104], r10 + adc r9, QWORD PTR [r8+112] + mov r10, QWORD PTR [rdx+120] + mov QWORD PTR [rcx+112], r9 + adc r10, QWORD PTR [r8+120] + mov r9, QWORD PTR [rdx+128] + mov QWORD PTR [rcx+120], r10 + adc r9, QWORD PTR [r8+128] + mov r10, QWORD PTR [rdx+136] + mov QWORD PTR [rcx+128], r9 + adc r10, QWORD PTR [r8+136] + mov r9, QWORD PTR [rdx+144] + mov QWORD PTR [rcx+136], r10 + adc r9, QWORD PTR [r8+144] + mov r10, QWORD PTR [rdx+152] + mov QWORD PTR [rcx+144], r9 + adc r10, QWORD PTR [r8+152] + mov r9, QWORD PTR [rdx+160] + mov QWORD PTR [rcx+152], r10 + adc r9, QWORD PTR [r8+160] + mov r10, QWORD PTR [rdx+168] + mov QWORD PTR [rcx+160], r9 + adc r10, QWORD PTR [r8+168] + mov r9, QWORD PTR [rdx+176] + mov QWORD PTR [rcx+168], r10 + adc r9, QWORD PTR [r8+176] + mov r10, QWORD PTR [rdx+184] + mov QWORD PTR [rcx+176], r9 + adc r10, QWORD PTR [r8+184] + mov r9, QWORD PTR [rdx+192] + mov QWORD PTR [rcx+184], r10 + adc r9, QWORD PTR [r8+192] + mov r10, QWORD PTR [rdx+200] + mov QWORD PTR [rcx+192], r9 + adc r10, QWORD PTR [r8+200] + mov r9, QWORD PTR [rdx+208] + mov QWORD PTR [rcx+200], r10 + adc r9, QWORD PTR [r8+208] + mov r10, QWORD PTR [rdx+216] + mov QWORD PTR [rcx+208], r9 + adc r10, QWORD PTR [r8+216] + mov r9, QWORD PTR [rdx+224] + mov QWORD PTR [rcx+216], r10 + adc r9, QWORD PTR [r8+224] + mov r10, QWORD PTR [rdx+232] + mov QWORD PTR [rcx+224], r9 + adc r10, QWORD PTR [r8+232] + mov r9, QWORD PTR [rdx+240] + mov QWORD PTR [rcx+232], r10 + adc r9, QWORD PTR [r8+240] + mov r10, QWORD PTR [rdx+248] + mov QWORD PTR [rcx+240], r9 + adc r10, QWORD PTR [r8+248] + mov r9, QWORD PTR [rdx+256] + mov QWORD PTR [rcx+248], r10 + adc r9, QWORD PTR [r8+256] + mov r10, QWORD PTR [rdx+264] + mov QWORD PTR [rcx+256], r9 + adc r10, QWORD PTR [r8+264] + mov r9, QWORD PTR [rdx+272] + mov QWORD PTR [rcx+264], r10 + adc r9, QWORD PTR [r8+272] + mov r10, QWORD PTR [rdx+280] + mov QWORD PTR [rcx+272], r9 + adc r10, QWORD PTR [r8+280] + mov r9, QWORD PTR [rdx+288] + mov QWORD PTR [rcx+280], r10 + adc r9, QWORD PTR [r8+288] + mov r10, QWORD PTR [rdx+296] + mov QWORD PTR [rcx+288], r9 + adc r10, QWORD PTR [r8+296] + mov r9, QWORD PTR [rdx+304] + mov QWORD PTR [rcx+296], r10 + adc r9, QWORD PTR [r8+304] + mov r10, QWORD PTR [rdx+312] + mov QWORD PTR [rcx+304], r9 + adc r10, QWORD PTR [r8+312] + mov r9, QWORD PTR [rdx+320] + mov QWORD PTR [rcx+312], r10 + adc r9, QWORD PTR [r8+320] + mov r10, QWORD PTR [rdx+328] + mov QWORD PTR [rcx+320], r9 + adc r10, QWORD PTR [r8+328] + mov r9, QWORD PTR [rdx+336] + mov QWORD PTR [rcx+328], r10 + adc r9, QWORD PTR [r8+336] + mov r10, QWORD PTR [rdx+344] + mov QWORD PTR [rcx+336], r9 + adc r10, QWORD PTR [r8+344] + mov r9, QWORD PTR [rdx+352] + mov QWORD PTR [rcx+344], r10 + adc r9, QWORD PTR [r8+352] + mov r10, QWORD PTR [rdx+360] + mov QWORD PTR [rcx+352], r9 + adc r10, QWORD PTR [r8+360] + mov r9, QWORD PTR [rdx+368] + mov QWORD PTR [rcx+360], r10 + adc r9, QWORD PTR [r8+368] + mov r10, QWORD PTR [rdx+376] + mov QWORD PTR [rcx+368], r9 + adc r10, QWORD PTR [r8+376] + mov r9, QWORD PTR [rdx+384] + mov QWORD PTR [rcx+376], r10 + adc r9, QWORD PTR [r8+384] + mov r10, QWORD PTR [rdx+392] + mov QWORD PTR [rcx+384], r9 + adc r10, QWORD PTR [r8+392] + mov r9, QWORD PTR [rdx+400] + mov QWORD PTR [rcx+392], r10 + adc r9, QWORD PTR [r8+400] + mov r10, QWORD PTR [rdx+408] + mov QWORD PTR [rcx+400], r9 + adc r10, QWORD PTR [r8+408] + mov r9, QWORD PTR [rdx+416] + mov QWORD PTR [rcx+408], r10 + adc r9, QWORD PTR [r8+416] + mov r10, QWORD PTR [rdx+424] + mov QWORD PTR [rcx+416], r9 + adc r10, QWORD PTR [r8+424] + mov r9, QWORD PTR [rdx+432] + mov QWORD PTR [rcx+424], r10 + adc r9, QWORD PTR [r8+432] + mov r10, QWORD PTR [rdx+440] + mov QWORD PTR [rcx+432], r9 + adc r10, QWORD PTR [r8+440] + mov r9, QWORD PTR [rdx+448] + mov QWORD PTR [rcx+440], r10 + adc r9, QWORD PTR [r8+448] + mov r10, QWORD PTR [rdx+456] + mov QWORD PTR [rcx+448], r9 + adc r10, QWORD PTR [r8+456] + mov r9, QWORD PTR [rdx+464] + mov QWORD PTR [rcx+456], r10 + adc r9, QWORD PTR [r8+464] + mov r10, QWORD PTR [rdx+472] + mov QWORD PTR [rcx+464], r9 + adc r10, QWORD PTR [r8+472] + mov r9, QWORD PTR [rdx+480] + mov QWORD PTR [rcx+472], r10 + adc r9, QWORD PTR [r8+480] + mov r10, QWORD PTR [rdx+488] + mov QWORD PTR [rcx+480], r9 + adc r10, QWORD PTR [r8+488] + mov r9, QWORD PTR [rdx+496] + mov QWORD PTR [rcx+488], r10 + adc r9, QWORD PTR [r8+496] + mov r10, QWORD PTR [rdx+504] + mov QWORD PTR [rcx+496], r9 + adc r10, QWORD PTR [r8+504] + mov QWORD PTR [rcx+504], r10 + adc rax, 0 + ret +sp_4096_add_64 ENDP +_text ENDS +; /* Multiply a and b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_4096_mul_64 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + sub rsp, 1576 + mov QWORD PTR [rsp+1536], rcx + mov QWORD PTR [rsp+1544], rdx + mov QWORD PTR [rsp+1552], r8 + lea r12, QWORD PTR [rsp+1024] + lea r14, QWORD PTR [rdx+256] + ; Add + mov rax, QWORD PTR [rdx] + xor r15, r15 + add rax, QWORD PTR [r14] + mov r9, QWORD PTR [rdx+8] + mov QWORD PTR [r12], rax + adc r9, QWORD PTR [r14+8] + mov r10, QWORD PTR [rdx+16] + mov QWORD PTR [r12+8], r9 + adc r10, QWORD PTR [r14+16] + mov rax, QWORD PTR [rdx+24] + mov QWORD PTR [r12+16], r10 + adc rax, QWORD PTR [r14+24] + mov r9, QWORD PTR [rdx+32] + mov QWORD PTR [r12+24], rax + adc r9, QWORD PTR [r14+32] + mov r10, QWORD PTR [rdx+40] + mov QWORD PTR [r12+32], r9 + adc r10, QWORD PTR [r14+40] + mov rax, QWORD PTR [rdx+48] + mov QWORD PTR [r12+40], r10 + adc rax, QWORD PTR [r14+48] + mov r9, QWORD PTR [rdx+56] + mov QWORD PTR [r12+48], rax + adc r9, QWORD PTR [r14+56] + mov r10, QWORD PTR [rdx+64] + mov QWORD PTR [r12+56], r9 + adc r10, QWORD PTR [r14+64] + mov rax, QWORD PTR [rdx+72] + mov QWORD PTR [r12+64], r10 + adc rax, QWORD PTR [r14+72] + mov r9, QWORD PTR [rdx+80] + mov QWORD PTR [r12+72], rax + adc r9, QWORD PTR [r14+80] + mov r10, QWORD PTR [rdx+88] + mov QWORD PTR [r12+80], r9 + adc r10, QWORD PTR [r14+88] + mov rax, QWORD PTR [rdx+96] + mov QWORD PTR [r12+88], r10 + adc rax, QWORD PTR [r14+96] + mov r9, QWORD PTR [rdx+104] + mov QWORD PTR [r12+96], rax + adc r9, QWORD PTR [r14+104] + mov r10, QWORD PTR [rdx+112] + mov QWORD PTR [r12+104], r9 + adc r10, QWORD PTR [r14+112] + mov rax, QWORD PTR [rdx+120] + mov QWORD PTR [r12+112], r10 + adc rax, QWORD PTR [r14+120] + mov r9, QWORD PTR [rdx+128] + mov QWORD PTR [r12+120], rax + adc r9, QWORD PTR [r14+128] + mov r10, QWORD PTR [rdx+136] + mov QWORD PTR [r12+128], r9 + adc r10, QWORD PTR [r14+136] + mov rax, QWORD PTR [rdx+144] + mov QWORD PTR [r12+136], r10 + adc rax, QWORD PTR [r14+144] + mov r9, QWORD PTR [rdx+152] + mov QWORD PTR [r12+144], rax + adc r9, QWORD PTR [r14+152] + mov r10, QWORD PTR [rdx+160] + mov QWORD PTR [r12+152], r9 + adc r10, QWORD PTR [r14+160] + mov rax, QWORD PTR [rdx+168] + mov QWORD PTR [r12+160], r10 + adc rax, QWORD PTR [r14+168] + mov r9, QWORD PTR [rdx+176] + mov QWORD PTR [r12+168], rax + adc r9, QWORD PTR [r14+176] + mov r10, QWORD PTR [rdx+184] + mov QWORD PTR [r12+176], r9 + adc r10, QWORD PTR [r14+184] + mov rax, QWORD PTR [rdx+192] + mov QWORD PTR [r12+184], r10 + adc rax, QWORD PTR [r14+192] + mov r9, QWORD PTR [rdx+200] + mov QWORD PTR [r12+192], rax + adc r9, QWORD PTR [r14+200] + mov r10, QWORD PTR [rdx+208] + mov QWORD PTR [r12+200], r9 + adc r10, QWORD PTR [r14+208] + mov rax, QWORD PTR [rdx+216] + mov QWORD PTR [r12+208], r10 + adc rax, QWORD PTR [r14+216] + mov r9, QWORD PTR [rdx+224] + mov QWORD PTR [r12+216], rax + adc r9, QWORD PTR [r14+224] + mov r10, QWORD PTR [rdx+232] + mov QWORD PTR [r12+224], r9 + adc r10, QWORD PTR [r14+232] + mov rax, QWORD PTR [rdx+240] + mov QWORD PTR [r12+232], r10 + adc rax, QWORD PTR [r14+240] + mov r9, QWORD PTR [rdx+248] + mov QWORD PTR [r12+240], rax + adc r9, QWORD PTR [r14+248] + mov QWORD PTR [r12+248], r9 + adc r15, 0 + mov QWORD PTR [rsp+1560], r15 + lea r13, QWORD PTR [rsp+1280] + lea r14, QWORD PTR [r8+256] + ; Add + mov rax, QWORD PTR [r8] + xor rdi, rdi + add rax, QWORD PTR [r14] + mov r9, QWORD PTR [r8+8] + mov QWORD PTR [r13], rax + adc r9, QWORD PTR [r14+8] + mov r10, QWORD PTR [r8+16] + mov QWORD PTR [r13+8], r9 + adc r10, QWORD PTR [r14+16] + mov rax, QWORD PTR [r8+24] + mov QWORD PTR [r13+16], r10 + adc rax, QWORD PTR [r14+24] + mov r9, QWORD PTR [r8+32] + mov QWORD PTR [r13+24], rax + adc r9, QWORD PTR [r14+32] + mov r10, QWORD PTR [r8+40] + mov QWORD PTR [r13+32], r9 + adc r10, QWORD PTR [r14+40] + mov rax, QWORD PTR [r8+48] + mov QWORD PTR [r13+40], r10 + adc rax, QWORD PTR [r14+48] + mov r9, QWORD PTR [r8+56] + mov QWORD PTR [r13+48], rax + adc r9, QWORD PTR [r14+56] + mov r10, QWORD PTR [r8+64] + mov QWORD PTR [r13+56], r9 + adc r10, QWORD PTR [r14+64] + mov rax, QWORD PTR [r8+72] + mov QWORD PTR [r13+64], r10 + adc rax, QWORD PTR [r14+72] + mov r9, QWORD PTR [r8+80] + mov QWORD PTR [r13+72], rax + adc r9, QWORD PTR [r14+80] + mov r10, QWORD PTR [r8+88] + mov QWORD PTR [r13+80], r9 + adc r10, QWORD PTR [r14+88] + mov rax, QWORD PTR [r8+96] + mov QWORD PTR [r13+88], r10 + adc rax, QWORD PTR [r14+96] + mov r9, QWORD PTR [r8+104] + mov QWORD PTR [r13+96], rax + adc r9, QWORD PTR [r14+104] + mov r10, QWORD PTR [r8+112] + mov QWORD PTR [r13+104], r9 + adc r10, QWORD PTR [r14+112] + mov rax, QWORD PTR [r8+120] + mov QWORD PTR [r13+112], r10 + adc rax, QWORD PTR [r14+120] + mov r9, QWORD PTR [r8+128] + mov QWORD PTR [r13+120], rax + adc r9, QWORD PTR [r14+128] + mov r10, QWORD PTR [r8+136] + mov QWORD PTR [r13+128], r9 + adc r10, QWORD PTR [r14+136] + mov rax, QWORD PTR [r8+144] + mov QWORD PTR [r13+136], r10 + adc rax, QWORD PTR [r14+144] + mov r9, QWORD PTR [r8+152] + mov QWORD PTR [r13+144], rax + adc r9, QWORD PTR [r14+152] + mov r10, QWORD PTR [r8+160] + mov QWORD PTR [r13+152], r9 + adc r10, QWORD PTR [r14+160] + mov rax, QWORD PTR [r8+168] + mov QWORD PTR [r13+160], r10 + adc rax, QWORD PTR [r14+168] + mov r9, QWORD PTR [r8+176] + mov QWORD PTR [r13+168], rax + adc r9, QWORD PTR [r14+176] + mov r10, QWORD PTR [r8+184] + mov QWORD PTR [r13+176], r9 + adc r10, QWORD PTR [r14+184] + mov rax, QWORD PTR [r8+192] + mov QWORD PTR [r13+184], r10 + adc rax, QWORD PTR [r14+192] + mov r9, QWORD PTR [r8+200] + mov QWORD PTR [r13+192], rax + adc r9, QWORD PTR [r14+200] + mov r10, QWORD PTR [r8+208] + mov QWORD PTR [r13+200], r9 + adc r10, QWORD PTR [r14+208] + mov rax, QWORD PTR [r8+216] + mov QWORD PTR [r13+208], r10 + adc rax, QWORD PTR [r14+216] + mov r9, QWORD PTR [r8+224] + mov QWORD PTR [r13+216], rax + adc r9, QWORD PTR [r14+224] + mov r10, QWORD PTR [r8+232] + mov QWORD PTR [r13+224], r9 + adc r10, QWORD PTR [r14+232] + mov rax, QWORD PTR [r8+240] + mov QWORD PTR [r13+232], r10 + adc rax, QWORD PTR [r14+240] + mov r9, QWORD PTR [r8+248] + mov QWORD PTR [r13+240], rax + adc r9, QWORD PTR [r14+248] + mov QWORD PTR [r13+248], r9 + adc rdi, 0 + mov QWORD PTR [rsp+1568], rdi + mov r8, r13 + mov rdx, r12 + mov rcx, rsp + call sp_2048_mul_32 + mov r8, QWORD PTR [rsp+1552] + mov rdx, QWORD PTR [rsp+1544] + lea rcx, QWORD PTR [rsp+512] + add r8, 256 + add rdx, 256 + call sp_2048_mul_32 + mov r8, QWORD PTR [rsp+1552] + mov rdx, QWORD PTR [rsp+1544] + mov rcx, QWORD PTR [rsp+1536] + call sp_2048_mul_32 +IFDEF _WIN64 + mov r8, QWORD PTR [rsp+1552] + mov rdx, QWORD PTR [rsp+1544] + mov rcx, QWORD PTR [rsp+1536] +ENDIF + mov r15, QWORD PTR [rsp+1560] + mov rdi, QWORD PTR [rsp+1568] + mov rsi, QWORD PTR [rsp+1536] + mov r11, r15 + lea r12, QWORD PTR [rsp+1024] + lea r13, QWORD PTR [rsp+1280] + and r11, rdi + neg r15 + neg rdi + add rsi, 512 + mov rax, QWORD PTR [r12] + mov r9, QWORD PTR [r13] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12], rax + mov QWORD PTR [r13], r9 + mov rax, QWORD PTR [r12+8] + mov r9, QWORD PTR [r13+8] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+8], rax + mov QWORD PTR [r13+8], r9 + mov rax, QWORD PTR [r12+16] + mov r9, QWORD PTR [r13+16] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+16], rax + mov QWORD PTR [r13+16], r9 + mov rax, QWORD PTR [r12+24] + mov r9, QWORD PTR [r13+24] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+24], rax + mov QWORD PTR [r13+24], r9 + mov rax, QWORD PTR [r12+32] + mov r9, QWORD PTR [r13+32] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+32], rax + mov QWORD PTR [r13+32], r9 + mov rax, QWORD PTR [r12+40] + mov r9, QWORD PTR [r13+40] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+40], rax + mov QWORD PTR [r13+40], r9 + mov rax, QWORD PTR [r12+48] + mov r9, QWORD PTR [r13+48] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+48], rax + mov QWORD PTR [r13+48], r9 + mov rax, QWORD PTR [r12+56] + mov r9, QWORD PTR [r13+56] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+56], rax + mov QWORD PTR [r13+56], r9 + mov rax, QWORD PTR [r12+64] + mov r9, QWORD PTR [r13+64] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+64], rax + mov QWORD PTR [r13+64], r9 + mov rax, QWORD PTR [r12+72] + mov r9, QWORD PTR [r13+72] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+72], rax + mov QWORD PTR [r13+72], r9 + mov rax, QWORD PTR [r12+80] + mov r9, QWORD PTR [r13+80] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+80], rax + mov QWORD PTR [r13+80], r9 + mov rax, QWORD PTR [r12+88] + mov r9, QWORD PTR [r13+88] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+88], rax + mov QWORD PTR [r13+88], r9 + mov rax, QWORD PTR [r12+96] + mov r9, QWORD PTR [r13+96] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+96], rax + mov QWORD PTR [r13+96], r9 + mov rax, QWORD PTR [r12+104] + mov r9, QWORD PTR [r13+104] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+104], rax + mov QWORD PTR [r13+104], r9 + mov rax, QWORD PTR [r12+112] + mov r9, QWORD PTR [r13+112] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+112], rax + mov QWORD PTR [r13+112], r9 + mov rax, QWORD PTR [r12+120] + mov r9, QWORD PTR [r13+120] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+120], rax + mov QWORD PTR [r13+120], r9 + mov rax, QWORD PTR [r12+128] + mov r9, QWORD PTR [r13+128] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+128], rax + mov QWORD PTR [r13+128], r9 + mov rax, QWORD PTR [r12+136] + mov r9, QWORD PTR [r13+136] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+136], rax + mov QWORD PTR [r13+136], r9 + mov rax, QWORD PTR [r12+144] + mov r9, QWORD PTR [r13+144] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+144], rax + mov QWORD PTR [r13+144], r9 + mov rax, QWORD PTR [r12+152] + mov r9, QWORD PTR [r13+152] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+152], rax + mov QWORD PTR [r13+152], r9 + mov rax, QWORD PTR [r12+160] + mov r9, QWORD PTR [r13+160] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+160], rax + mov QWORD PTR [r13+160], r9 + mov rax, QWORD PTR [r12+168] + mov r9, QWORD PTR [r13+168] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+168], rax + mov QWORD PTR [r13+168], r9 + mov rax, QWORD PTR [r12+176] + mov r9, QWORD PTR [r13+176] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+176], rax + mov QWORD PTR [r13+176], r9 + mov rax, QWORD PTR [r12+184] + mov r9, QWORD PTR [r13+184] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+184], rax + mov QWORD PTR [r13+184], r9 + mov rax, QWORD PTR [r12+192] + mov r9, QWORD PTR [r13+192] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+192], rax + mov QWORD PTR [r13+192], r9 + mov rax, QWORD PTR [r12+200] + mov r9, QWORD PTR [r13+200] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+200], rax + mov QWORD PTR [r13+200], r9 + mov rax, QWORD PTR [r12+208] + mov r9, QWORD PTR [r13+208] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+208], rax + mov QWORD PTR [r13+208], r9 + mov rax, QWORD PTR [r12+216] + mov r9, QWORD PTR [r13+216] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+216], rax + mov QWORD PTR [r13+216], r9 + mov rax, QWORD PTR [r12+224] + mov r9, QWORD PTR [r13+224] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+224], rax + mov QWORD PTR [r13+224], r9 + mov rax, QWORD PTR [r12+232] + mov r9, QWORD PTR [r13+232] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+232], rax + mov QWORD PTR [r13+232], r9 + mov rax, QWORD PTR [r12+240] + mov r9, QWORD PTR [r13+240] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+240], rax + mov QWORD PTR [r13+240], r9 + mov rax, QWORD PTR [r12+248] + mov r9, QWORD PTR [r13+248] + and rax, rdi + and r9, r15 + mov QWORD PTR [r12+248], rax + mov QWORD PTR [r13+248], r9 + mov rax, QWORD PTR [r12] + add rax, QWORD PTR [r13] + mov r9, QWORD PTR [r12+8] + mov QWORD PTR [rsi], rax + adc r9, QWORD PTR [r13+8] + mov r10, QWORD PTR [r12+16] + mov QWORD PTR [rsi+8], r9 + adc r10, QWORD PTR [r13+16] + mov rax, QWORD PTR [r12+24] + mov QWORD PTR [rsi+16], r10 + adc rax, QWORD PTR [r13+24] + mov r9, QWORD PTR [r12+32] + mov QWORD PTR [rsi+24], rax + adc r9, QWORD PTR [r13+32] + mov r10, QWORD PTR [r12+40] + mov QWORD PTR [rsi+32], r9 + adc r10, QWORD PTR [r13+40] + mov rax, QWORD PTR [r12+48] + mov QWORD PTR [rsi+40], r10 + adc rax, QWORD PTR [r13+48] + mov r9, QWORD PTR [r12+56] + mov QWORD PTR [rsi+48], rax + adc r9, QWORD PTR [r13+56] + mov r10, QWORD PTR [r12+64] + mov QWORD PTR [rsi+56], r9 + adc r10, QWORD PTR [r13+64] + mov rax, QWORD PTR [r12+72] + mov QWORD PTR [rsi+64], r10 + adc rax, QWORD PTR [r13+72] + mov r9, QWORD PTR [r12+80] + mov QWORD PTR [rsi+72], rax + adc r9, QWORD PTR [r13+80] + mov r10, QWORD PTR [r12+88] + mov QWORD PTR [rsi+80], r9 + adc r10, QWORD PTR [r13+88] + mov rax, QWORD PTR [r12+96] + mov QWORD PTR [rsi+88], r10 + adc rax, QWORD PTR [r13+96] + mov r9, QWORD PTR [r12+104] + mov QWORD PTR [rsi+96], rax + adc r9, QWORD PTR [r13+104] + mov r10, QWORD PTR [r12+112] + mov QWORD PTR [rsi+104], r9 + adc r10, QWORD PTR [r13+112] + mov rax, QWORD PTR [r12+120] + mov QWORD PTR [rsi+112], r10 + adc rax, QWORD PTR [r13+120] + mov r9, QWORD PTR [r12+128] + mov QWORD PTR [rsi+120], rax + adc r9, QWORD PTR [r13+128] + mov r10, QWORD PTR [r12+136] + mov QWORD PTR [rsi+128], r9 + adc r10, QWORD PTR [r13+136] + mov rax, QWORD PTR [r12+144] + mov QWORD PTR [rsi+136], r10 + adc rax, QWORD PTR [r13+144] + mov r9, QWORD PTR [r12+152] + mov QWORD PTR [rsi+144], rax + adc r9, QWORD PTR [r13+152] + mov r10, QWORD PTR [r12+160] + mov QWORD PTR [rsi+152], r9 + adc r10, QWORD PTR [r13+160] + mov rax, QWORD PTR [r12+168] + mov QWORD PTR [rsi+160], r10 + adc rax, QWORD PTR [r13+168] + mov r9, QWORD PTR [r12+176] + mov QWORD PTR [rsi+168], rax + adc r9, QWORD PTR [r13+176] + mov r10, QWORD PTR [r12+184] + mov QWORD PTR [rsi+176], r9 + adc r10, QWORD PTR [r13+184] + mov rax, QWORD PTR [r12+192] + mov QWORD PTR [rsi+184], r10 + adc rax, QWORD PTR [r13+192] + mov r9, QWORD PTR [r12+200] + mov QWORD PTR [rsi+192], rax + adc r9, QWORD PTR [r13+200] + mov r10, QWORD PTR [r12+208] + mov QWORD PTR [rsi+200], r9 + adc r10, QWORD PTR [r13+208] + mov rax, QWORD PTR [r12+216] + mov QWORD PTR [rsi+208], r10 + adc rax, QWORD PTR [r13+216] + mov r9, QWORD PTR [r12+224] + mov QWORD PTR [rsi+216], rax + adc r9, QWORD PTR [r13+224] + mov r10, QWORD PTR [r12+232] + mov QWORD PTR [rsi+224], r9 + adc r10, QWORD PTR [r13+232] + mov rax, QWORD PTR [r12+240] + mov QWORD PTR [rsi+232], r10 + adc rax, QWORD PTR [r13+240] + mov r9, QWORD PTR [r12+248] + mov QWORD PTR [rsi+240], rax + adc r9, QWORD PTR [r13+248] + mov QWORD PTR [rsi+248], r9 + adc r11, 0 + lea r13, QWORD PTR [rsp+512] + mov r12, rsp + mov rax, QWORD PTR [r12] + sub rax, QWORD PTR [r13] + mov r9, QWORD PTR [r12+8] + mov QWORD PTR [r12], rax + sbb r9, QWORD PTR [r13+8] + mov r10, QWORD PTR [r12+16] + mov QWORD PTR [r12+8], r9 + sbb r10, QWORD PTR [r13+16] + mov rax, QWORD PTR [r12+24] + mov QWORD PTR [r12+16], r10 + sbb rax, QWORD PTR [r13+24] + mov r9, QWORD PTR [r12+32] + mov QWORD PTR [r12+24], rax + sbb r9, QWORD PTR [r13+32] + mov r10, QWORD PTR [r12+40] + mov QWORD PTR [r12+32], r9 + sbb r10, QWORD PTR [r13+40] + mov rax, QWORD PTR [r12+48] + mov QWORD PTR [r12+40], r10 + sbb rax, QWORD PTR [r13+48] + mov r9, QWORD PTR [r12+56] + mov QWORD PTR [r12+48], rax + sbb r9, QWORD PTR [r13+56] + mov r10, QWORD PTR [r12+64] + mov QWORD PTR [r12+56], r9 + sbb r10, QWORD PTR [r13+64] + mov rax, QWORD PTR [r12+72] + mov QWORD PTR [r12+64], r10 + sbb rax, QWORD PTR [r13+72] + mov r9, QWORD PTR [r12+80] + mov QWORD PTR [r12+72], rax + sbb r9, QWORD PTR [r13+80] + mov r10, QWORD PTR [r12+88] + mov QWORD PTR [r12+80], r9 + sbb r10, QWORD PTR [r13+88] + mov rax, QWORD PTR [r12+96] + mov QWORD PTR [r12+88], r10 + sbb rax, QWORD PTR [r13+96] + mov r9, QWORD PTR [r12+104] + mov QWORD PTR [r12+96], rax + sbb r9, QWORD PTR [r13+104] + mov r10, QWORD PTR [r12+112] + mov QWORD PTR [r12+104], r9 + sbb r10, QWORD PTR [r13+112] + mov rax, QWORD PTR [r12+120] + mov QWORD PTR [r12+112], r10 + sbb rax, QWORD PTR [r13+120] + mov r9, QWORD PTR [r12+128] + mov QWORD PTR [r12+120], rax + sbb r9, QWORD PTR [r13+128] + mov r10, QWORD PTR [r12+136] + mov QWORD PTR [r12+128], r9 + sbb r10, QWORD PTR [r13+136] + mov rax, QWORD PTR [r12+144] + mov QWORD PTR [r12+136], r10 + sbb rax, QWORD PTR [r13+144] + mov r9, QWORD PTR [r12+152] + mov QWORD PTR [r12+144], rax + sbb r9, QWORD PTR [r13+152] + mov r10, QWORD PTR [r12+160] + mov QWORD PTR [r12+152], r9 + sbb r10, QWORD PTR [r13+160] + mov rax, QWORD PTR [r12+168] + mov QWORD PTR [r12+160], r10 + sbb rax, QWORD PTR [r13+168] + mov r9, QWORD PTR [r12+176] + mov QWORD PTR [r12+168], rax + sbb r9, QWORD PTR [r13+176] + mov r10, QWORD PTR [r12+184] + mov QWORD PTR [r12+176], r9 + sbb r10, QWORD PTR [r13+184] + mov rax, QWORD PTR [r12+192] + mov QWORD PTR [r12+184], r10 + sbb rax, QWORD PTR [r13+192] + mov r9, QWORD PTR [r12+200] + mov QWORD PTR [r12+192], rax + sbb r9, QWORD PTR [r13+200] + mov r10, QWORD PTR [r12+208] + mov QWORD PTR [r12+200], r9 + sbb r10, QWORD PTR [r13+208] + mov rax, QWORD PTR [r12+216] + mov QWORD PTR [r12+208], r10 + sbb rax, QWORD PTR [r13+216] + mov r9, QWORD PTR [r12+224] + mov QWORD PTR [r12+216], rax + sbb r9, QWORD PTR [r13+224] + mov r10, QWORD PTR [r12+232] + mov QWORD PTR [r12+224], r9 + sbb r10, QWORD PTR [r13+232] + mov rax, QWORD PTR [r12+240] + mov QWORD PTR [r12+232], r10 + sbb rax, QWORD PTR [r13+240] + mov r9, QWORD PTR [r12+248] + mov QWORD PTR [r12+240], rax + sbb r9, QWORD PTR [r13+248] + mov r10, QWORD PTR [r12+256] + mov QWORD PTR [r12+248], r9 + sbb r10, QWORD PTR [r13+256] + mov rax, QWORD PTR [r12+264] + mov QWORD PTR [r12+256], r10 + sbb rax, QWORD PTR [r13+264] + mov r9, QWORD PTR [r12+272] + mov QWORD PTR [r12+264], rax + sbb r9, QWORD PTR [r13+272] + mov r10, QWORD PTR [r12+280] + mov QWORD PTR [r12+272], r9 + sbb r10, QWORD PTR [r13+280] + mov rax, QWORD PTR [r12+288] + mov QWORD PTR [r12+280], r10 + sbb rax, QWORD PTR [r13+288] + mov r9, QWORD PTR [r12+296] + mov QWORD PTR [r12+288], rax + sbb r9, QWORD PTR [r13+296] + mov r10, QWORD PTR [r12+304] + mov QWORD PTR [r12+296], r9 + sbb r10, QWORD PTR [r13+304] + mov rax, QWORD PTR [r12+312] + mov QWORD PTR [r12+304], r10 + sbb rax, QWORD PTR [r13+312] + mov r9, QWORD PTR [r12+320] + mov QWORD PTR [r12+312], rax + sbb r9, QWORD PTR [r13+320] + mov r10, QWORD PTR [r12+328] + mov QWORD PTR [r12+320], r9 + sbb r10, QWORD PTR [r13+328] + mov rax, QWORD PTR [r12+336] + mov QWORD PTR [r12+328], r10 + sbb rax, QWORD PTR [r13+336] + mov r9, QWORD PTR [r12+344] + mov QWORD PTR [r12+336], rax + sbb r9, QWORD PTR [r13+344] + mov r10, QWORD PTR [r12+352] + mov QWORD PTR [r12+344], r9 + sbb r10, QWORD PTR [r13+352] + mov rax, QWORD PTR [r12+360] + mov QWORD PTR [r12+352], r10 + sbb rax, QWORD PTR [r13+360] + mov r9, QWORD PTR [r12+368] + mov QWORD PTR [r12+360], rax + sbb r9, QWORD PTR [r13+368] + mov r10, QWORD PTR [r12+376] + mov QWORD PTR [r12+368], r9 + sbb r10, QWORD PTR [r13+376] + mov rax, QWORD PTR [r12+384] + mov QWORD PTR [r12+376], r10 + sbb rax, QWORD PTR [r13+384] + mov r9, QWORD PTR [r12+392] + mov QWORD PTR [r12+384], rax + sbb r9, QWORD PTR [r13+392] + mov r10, QWORD PTR [r12+400] + mov QWORD PTR [r12+392], r9 + sbb r10, QWORD PTR [r13+400] + mov rax, QWORD PTR [r12+408] + mov QWORD PTR [r12+400], r10 + sbb rax, QWORD PTR [r13+408] + mov r9, QWORD PTR [r12+416] + mov QWORD PTR [r12+408], rax + sbb r9, QWORD PTR [r13+416] + mov r10, QWORD PTR [r12+424] + mov QWORD PTR [r12+416], r9 + sbb r10, QWORD PTR [r13+424] + mov rax, QWORD PTR [r12+432] + mov QWORD PTR [r12+424], r10 + sbb rax, QWORD PTR [r13+432] + mov r9, QWORD PTR [r12+440] + mov QWORD PTR [r12+432], rax + sbb r9, QWORD PTR [r13+440] + mov r10, QWORD PTR [r12+448] + mov QWORD PTR [r12+440], r9 + sbb r10, QWORD PTR [r13+448] + mov rax, QWORD PTR [r12+456] + mov QWORD PTR [r12+448], r10 + sbb rax, QWORD PTR [r13+456] + mov r9, QWORD PTR [r12+464] + mov QWORD PTR [r12+456], rax + sbb r9, QWORD PTR [r13+464] + mov r10, QWORD PTR [r12+472] + mov QWORD PTR [r12+464], r9 + sbb r10, QWORD PTR [r13+472] + mov rax, QWORD PTR [r12+480] + mov QWORD PTR [r12+472], r10 + sbb rax, QWORD PTR [r13+480] + mov r9, QWORD PTR [r12+488] + mov QWORD PTR [r12+480], rax + sbb r9, QWORD PTR [r13+488] + mov r10, QWORD PTR [r12+496] + mov QWORD PTR [r12+488], r9 + sbb r10, QWORD PTR [r13+496] + mov rax, QWORD PTR [r12+504] + mov QWORD PTR [r12+496], r10 + sbb rax, QWORD PTR [r13+504] + mov QWORD PTR [r12+504], rax + sbb r11, 0 + mov rax, QWORD PTR [r12] + sub rax, QWORD PTR [rcx] + mov r9, QWORD PTR [r12+8] + mov QWORD PTR [r12], rax + sbb r9, QWORD PTR [rcx+8] + mov r10, QWORD PTR [r12+16] + mov QWORD PTR [r12+8], r9 + sbb r10, QWORD PTR [rcx+16] + mov rax, QWORD PTR [r12+24] + mov QWORD PTR [r12+16], r10 + sbb rax, QWORD PTR [rcx+24] + mov r9, QWORD PTR [r12+32] + mov QWORD PTR [r12+24], rax + sbb r9, QWORD PTR [rcx+32] + mov r10, QWORD PTR [r12+40] + mov QWORD PTR [r12+32], r9 + sbb r10, QWORD PTR [rcx+40] + mov rax, QWORD PTR [r12+48] + mov QWORD PTR [r12+40], r10 + sbb rax, QWORD PTR [rcx+48] + mov r9, QWORD PTR [r12+56] + mov QWORD PTR [r12+48], rax + sbb r9, QWORD PTR [rcx+56] + mov r10, QWORD PTR [r12+64] + mov QWORD PTR [r12+56], r9 + sbb r10, QWORD PTR [rcx+64] + mov rax, QWORD PTR [r12+72] + mov QWORD PTR [r12+64], r10 + sbb rax, QWORD PTR [rcx+72] + mov r9, QWORD PTR [r12+80] + mov QWORD PTR [r12+72], rax + sbb r9, QWORD PTR [rcx+80] + mov r10, QWORD PTR [r12+88] + mov QWORD PTR [r12+80], r9 + sbb r10, QWORD PTR [rcx+88] + mov rax, QWORD PTR [r12+96] + mov QWORD PTR [r12+88], r10 + sbb rax, QWORD PTR [rcx+96] + mov r9, QWORD PTR [r12+104] + mov QWORD PTR [r12+96], rax + sbb r9, QWORD PTR [rcx+104] + mov r10, QWORD PTR [r12+112] + mov QWORD PTR [r12+104], r9 + sbb r10, QWORD PTR [rcx+112] + mov rax, QWORD PTR [r12+120] + mov QWORD PTR [r12+112], r10 + sbb rax, QWORD PTR [rcx+120] + mov r9, QWORD PTR [r12+128] + mov QWORD PTR [r12+120], rax + sbb r9, QWORD PTR [rcx+128] + mov r10, QWORD PTR [r12+136] + mov QWORD PTR [r12+128], r9 + sbb r10, QWORD PTR [rcx+136] + mov rax, QWORD PTR [r12+144] + mov QWORD PTR [r12+136], r10 + sbb rax, QWORD PTR [rcx+144] + mov r9, QWORD PTR [r12+152] + mov QWORD PTR [r12+144], rax + sbb r9, QWORD PTR [rcx+152] + mov r10, QWORD PTR [r12+160] + mov QWORD PTR [r12+152], r9 + sbb r10, QWORD PTR [rcx+160] + mov rax, QWORD PTR [r12+168] + mov QWORD PTR [r12+160], r10 + sbb rax, QWORD PTR [rcx+168] + mov r9, QWORD PTR [r12+176] + mov QWORD PTR [r12+168], rax + sbb r9, QWORD PTR [rcx+176] + mov r10, QWORD PTR [r12+184] + mov QWORD PTR [r12+176], r9 + sbb r10, QWORD PTR [rcx+184] + mov rax, QWORD PTR [r12+192] + mov QWORD PTR [r12+184], r10 + sbb rax, QWORD PTR [rcx+192] + mov r9, QWORD PTR [r12+200] + mov QWORD PTR [r12+192], rax + sbb r9, QWORD PTR [rcx+200] + mov r10, QWORD PTR [r12+208] + mov QWORD PTR [r12+200], r9 + sbb r10, QWORD PTR [rcx+208] + mov rax, QWORD PTR [r12+216] + mov QWORD PTR [r12+208], r10 + sbb rax, QWORD PTR [rcx+216] + mov r9, QWORD PTR [r12+224] + mov QWORD PTR [r12+216], rax + sbb r9, QWORD PTR [rcx+224] + mov r10, QWORD PTR [r12+232] + mov QWORD PTR [r12+224], r9 + sbb r10, QWORD PTR [rcx+232] + mov rax, QWORD PTR [r12+240] + mov QWORD PTR [r12+232], r10 + sbb rax, QWORD PTR [rcx+240] + mov r9, QWORD PTR [r12+248] + mov QWORD PTR [r12+240], rax + sbb r9, QWORD PTR [rcx+248] + mov r10, QWORD PTR [r12+256] + mov QWORD PTR [r12+248], r9 + sbb r10, QWORD PTR [rcx+256] + mov rax, QWORD PTR [r12+264] + mov QWORD PTR [r12+256], r10 + sbb rax, QWORD PTR [rcx+264] + mov r9, QWORD PTR [r12+272] + mov QWORD PTR [r12+264], rax + sbb r9, QWORD PTR [rcx+272] + mov r10, QWORD PTR [r12+280] + mov QWORD PTR [r12+272], r9 + sbb r10, QWORD PTR [rcx+280] + mov rax, QWORD PTR [r12+288] + mov QWORD PTR [r12+280], r10 + sbb rax, QWORD PTR [rcx+288] + mov r9, QWORD PTR [r12+296] + mov QWORD PTR [r12+288], rax + sbb r9, QWORD PTR [rcx+296] + mov r10, QWORD PTR [r12+304] + mov QWORD PTR [r12+296], r9 + sbb r10, QWORD PTR [rcx+304] + mov rax, QWORD PTR [r12+312] + mov QWORD PTR [r12+304], r10 + sbb rax, QWORD PTR [rcx+312] + mov r9, QWORD PTR [r12+320] + mov QWORD PTR [r12+312], rax + sbb r9, QWORD PTR [rcx+320] + mov r10, QWORD PTR [r12+328] + mov QWORD PTR [r12+320], r9 + sbb r10, QWORD PTR [rcx+328] + mov rax, QWORD PTR [r12+336] + mov QWORD PTR [r12+328], r10 + sbb rax, QWORD PTR [rcx+336] + mov r9, QWORD PTR [r12+344] + mov QWORD PTR [r12+336], rax + sbb r9, QWORD PTR [rcx+344] + mov r10, QWORD PTR [r12+352] + mov QWORD PTR [r12+344], r9 + sbb r10, QWORD PTR [rcx+352] + mov rax, QWORD PTR [r12+360] + mov QWORD PTR [r12+352], r10 + sbb rax, QWORD PTR [rcx+360] + mov r9, QWORD PTR [r12+368] + mov QWORD PTR [r12+360], rax + sbb r9, QWORD PTR [rcx+368] + mov r10, QWORD PTR [r12+376] + mov QWORD PTR [r12+368], r9 + sbb r10, QWORD PTR [rcx+376] + mov rax, QWORD PTR [r12+384] + mov QWORD PTR [r12+376], r10 + sbb rax, QWORD PTR [rcx+384] + mov r9, QWORD PTR [r12+392] + mov QWORD PTR [r12+384], rax + sbb r9, QWORD PTR [rcx+392] + mov r10, QWORD PTR [r12+400] + mov QWORD PTR [r12+392], r9 + sbb r10, QWORD PTR [rcx+400] + mov rax, QWORD PTR [r12+408] + mov QWORD PTR [r12+400], r10 + sbb rax, QWORD PTR [rcx+408] + mov r9, QWORD PTR [r12+416] + mov QWORD PTR [r12+408], rax + sbb r9, QWORD PTR [rcx+416] + mov r10, QWORD PTR [r12+424] + mov QWORD PTR [r12+416], r9 + sbb r10, QWORD PTR [rcx+424] + mov rax, QWORD PTR [r12+432] + mov QWORD PTR [r12+424], r10 + sbb rax, QWORD PTR [rcx+432] + mov r9, QWORD PTR [r12+440] + mov QWORD PTR [r12+432], rax + sbb r9, QWORD PTR [rcx+440] + mov r10, QWORD PTR [r12+448] + mov QWORD PTR [r12+440], r9 + sbb r10, QWORD PTR [rcx+448] + mov rax, QWORD PTR [r12+456] + mov QWORD PTR [r12+448], r10 + sbb rax, QWORD PTR [rcx+456] + mov r9, QWORD PTR [r12+464] + mov QWORD PTR [r12+456], rax + sbb r9, QWORD PTR [rcx+464] + mov r10, QWORD PTR [r12+472] + mov QWORD PTR [r12+464], r9 + sbb r10, QWORD PTR [rcx+472] + mov rax, QWORD PTR [r12+480] + mov QWORD PTR [r12+472], r10 + sbb rax, QWORD PTR [rcx+480] + mov r9, QWORD PTR [r12+488] + mov QWORD PTR [r12+480], rax + sbb r9, QWORD PTR [rcx+488] + mov r10, QWORD PTR [r12+496] + mov QWORD PTR [r12+488], r9 + sbb r10, QWORD PTR [rcx+496] + mov rax, QWORD PTR [r12+504] + mov QWORD PTR [r12+496], r10 + sbb rax, QWORD PTR [rcx+504] + mov QWORD PTR [r12+504], rax + sbb r11, 0 + sub rsi, 256 + ; Add + mov rax, QWORD PTR [rsi] + add rax, QWORD PTR [r12] + mov r9, QWORD PTR [rsi+8] + mov QWORD PTR [rsi], rax + adc r9, QWORD PTR [r12+8] + mov r10, QWORD PTR [rsi+16] + mov QWORD PTR [rsi+8], r9 + adc r10, QWORD PTR [r12+16] + mov rax, QWORD PTR [rsi+24] + mov QWORD PTR [rsi+16], r10 + adc rax, QWORD PTR [r12+24] + mov r9, QWORD PTR [rsi+32] + mov QWORD PTR [rsi+24], rax + adc r9, QWORD PTR [r12+32] + mov r10, QWORD PTR [rsi+40] + mov QWORD PTR [rsi+32], r9 + adc r10, QWORD PTR [r12+40] + mov rax, QWORD PTR [rsi+48] + mov QWORD PTR [rsi+40], r10 + adc rax, QWORD PTR [r12+48] + mov r9, QWORD PTR [rsi+56] + mov QWORD PTR [rsi+48], rax + adc r9, QWORD PTR [r12+56] + mov r10, QWORD PTR [rsi+64] + mov QWORD PTR [rsi+56], r9 + adc r10, QWORD PTR [r12+64] + mov rax, QWORD PTR [rsi+72] + mov QWORD PTR [rsi+64], r10 + adc rax, QWORD PTR [r12+72] + mov r9, QWORD PTR [rsi+80] + mov QWORD PTR [rsi+72], rax + adc r9, QWORD PTR [r12+80] + mov r10, QWORD PTR [rsi+88] + mov QWORD PTR [rsi+80], r9 + adc r10, QWORD PTR [r12+88] + mov rax, QWORD PTR [rsi+96] + mov QWORD PTR [rsi+88], r10 + adc rax, QWORD PTR [r12+96] + mov r9, QWORD PTR [rsi+104] + mov QWORD PTR [rsi+96], rax + adc r9, QWORD PTR [r12+104] + mov r10, QWORD PTR [rsi+112] + mov QWORD PTR [rsi+104], r9 + adc r10, QWORD PTR [r12+112] + mov rax, QWORD PTR [rsi+120] + mov QWORD PTR [rsi+112], r10 + adc rax, QWORD PTR [r12+120] + mov r9, QWORD PTR [rsi+128] + mov QWORD PTR [rsi+120], rax + adc r9, QWORD PTR [r12+128] + mov r10, QWORD PTR [rsi+136] + mov QWORD PTR [rsi+128], r9 + adc r10, QWORD PTR [r12+136] + mov rax, QWORD PTR [rsi+144] + mov QWORD PTR [rsi+136], r10 + adc rax, QWORD PTR [r12+144] + mov r9, QWORD PTR [rsi+152] + mov QWORD PTR [rsi+144], rax + adc r9, QWORD PTR [r12+152] + mov r10, QWORD PTR [rsi+160] + mov QWORD PTR [rsi+152], r9 + adc r10, QWORD PTR [r12+160] + mov rax, QWORD PTR [rsi+168] + mov QWORD PTR [rsi+160], r10 + adc rax, QWORD PTR [r12+168] + mov r9, QWORD PTR [rsi+176] + mov QWORD PTR [rsi+168], rax + adc r9, QWORD PTR [r12+176] + mov r10, QWORD PTR [rsi+184] + mov QWORD PTR [rsi+176], r9 + adc r10, QWORD PTR [r12+184] + mov rax, QWORD PTR [rsi+192] + mov QWORD PTR [rsi+184], r10 + adc rax, QWORD PTR [r12+192] + mov r9, QWORD PTR [rsi+200] + mov QWORD PTR [rsi+192], rax + adc r9, QWORD PTR [r12+200] + mov r10, QWORD PTR [rsi+208] + mov QWORD PTR [rsi+200], r9 + adc r10, QWORD PTR [r12+208] + mov rax, QWORD PTR [rsi+216] + mov QWORD PTR [rsi+208], r10 + adc rax, QWORD PTR [r12+216] + mov r9, QWORD PTR [rsi+224] + mov QWORD PTR [rsi+216], rax + adc r9, QWORD PTR [r12+224] + mov r10, QWORD PTR [rsi+232] + mov QWORD PTR [rsi+224], r9 + adc r10, QWORD PTR [r12+232] + mov rax, QWORD PTR [rsi+240] + mov QWORD PTR [rsi+232], r10 + adc rax, QWORD PTR [r12+240] + mov r9, QWORD PTR [rsi+248] + mov QWORD PTR [rsi+240], rax + adc r9, QWORD PTR [r12+248] + mov r10, QWORD PTR [rsi+256] + mov QWORD PTR [rsi+248], r9 + adc r10, QWORD PTR [r12+256] + mov rax, QWORD PTR [rsi+264] + mov QWORD PTR [rsi+256], r10 + adc rax, QWORD PTR [r12+264] + mov r9, QWORD PTR [rsi+272] + mov QWORD PTR [rsi+264], rax + adc r9, QWORD PTR [r12+272] + mov r10, QWORD PTR [rsi+280] + mov QWORD PTR [rsi+272], r9 + adc r10, QWORD PTR [r12+280] + mov rax, QWORD PTR [rsi+288] + mov QWORD PTR [rsi+280], r10 + adc rax, QWORD PTR [r12+288] + mov r9, QWORD PTR [rsi+296] + mov QWORD PTR [rsi+288], rax + adc r9, QWORD PTR [r12+296] + mov r10, QWORD PTR [rsi+304] + mov QWORD PTR [rsi+296], r9 + adc r10, QWORD PTR [r12+304] + mov rax, QWORD PTR [rsi+312] + mov QWORD PTR [rsi+304], r10 + adc rax, QWORD PTR [r12+312] + mov r9, QWORD PTR [rsi+320] + mov QWORD PTR [rsi+312], rax + adc r9, QWORD PTR [r12+320] + mov r10, QWORD PTR [rsi+328] + mov QWORD PTR [rsi+320], r9 + adc r10, QWORD PTR [r12+328] + mov rax, QWORD PTR [rsi+336] + mov QWORD PTR [rsi+328], r10 + adc rax, QWORD PTR [r12+336] + mov r9, QWORD PTR [rsi+344] + mov QWORD PTR [rsi+336], rax + adc r9, QWORD PTR [r12+344] + mov r10, QWORD PTR [rsi+352] + mov QWORD PTR [rsi+344], r9 + adc r10, QWORD PTR [r12+352] + mov rax, QWORD PTR [rsi+360] + mov QWORD PTR [rsi+352], r10 + adc rax, QWORD PTR [r12+360] + mov r9, QWORD PTR [rsi+368] + mov QWORD PTR [rsi+360], rax + adc r9, QWORD PTR [r12+368] + mov r10, QWORD PTR [rsi+376] + mov QWORD PTR [rsi+368], r9 + adc r10, QWORD PTR [r12+376] + mov rax, QWORD PTR [rsi+384] + mov QWORD PTR [rsi+376], r10 + adc rax, QWORD PTR [r12+384] + mov r9, QWORD PTR [rsi+392] + mov QWORD PTR [rsi+384], rax + adc r9, QWORD PTR [r12+392] + mov r10, QWORD PTR [rsi+400] + mov QWORD PTR [rsi+392], r9 + adc r10, QWORD PTR [r12+400] + mov rax, QWORD PTR [rsi+408] + mov QWORD PTR [rsi+400], r10 + adc rax, QWORD PTR [r12+408] + mov r9, QWORD PTR [rsi+416] + mov QWORD PTR [rsi+408], rax + adc r9, QWORD PTR [r12+416] + mov r10, QWORD PTR [rsi+424] + mov QWORD PTR [rsi+416], r9 + adc r10, QWORD PTR [r12+424] + mov rax, QWORD PTR [rsi+432] + mov QWORD PTR [rsi+424], r10 + adc rax, QWORD PTR [r12+432] + mov r9, QWORD PTR [rsi+440] + mov QWORD PTR [rsi+432], rax + adc r9, QWORD PTR [r12+440] + mov r10, QWORD PTR [rsi+448] + mov QWORD PTR [rsi+440], r9 + adc r10, QWORD PTR [r12+448] + mov rax, QWORD PTR [rsi+456] + mov QWORD PTR [rsi+448], r10 + adc rax, QWORD PTR [r12+456] + mov r9, QWORD PTR [rsi+464] + mov QWORD PTR [rsi+456], rax + adc r9, QWORD PTR [r12+464] + mov r10, QWORD PTR [rsi+472] + mov QWORD PTR [rsi+464], r9 + adc r10, QWORD PTR [r12+472] + mov rax, QWORD PTR [rsi+480] + mov QWORD PTR [rsi+472], r10 + adc rax, QWORD PTR [r12+480] + mov r9, QWORD PTR [rsi+488] + mov QWORD PTR [rsi+480], rax + adc r9, QWORD PTR [r12+488] + mov r10, QWORD PTR [rsi+496] + mov QWORD PTR [rsi+488], r9 + adc r10, QWORD PTR [r12+496] + mov rax, QWORD PTR [rsi+504] + mov QWORD PTR [rsi+496], r10 + adc rax, QWORD PTR [r12+504] + mov QWORD PTR [rsi+504], rax + adc r11, 0 + mov QWORD PTR [rcx+768], r11 + add rsi, 256 + ; Add + mov rax, QWORD PTR [rsi] + xor r11, r11 + add rax, QWORD PTR [r13] + mov r9, QWORD PTR [rsi+8] + mov QWORD PTR [rsi], rax + adc r9, QWORD PTR [r13+8] + mov r10, QWORD PTR [rsi+16] + mov QWORD PTR [rsi+8], r9 + adc r10, QWORD PTR [r13+16] + mov rax, QWORD PTR [rsi+24] + mov QWORD PTR [rsi+16], r10 + adc rax, QWORD PTR [r13+24] + mov r9, QWORD PTR [rsi+32] + mov QWORD PTR [rsi+24], rax + adc r9, QWORD PTR [r13+32] + mov r10, QWORD PTR [rsi+40] + mov QWORD PTR [rsi+32], r9 + adc r10, QWORD PTR [r13+40] + mov rax, QWORD PTR [rsi+48] + mov QWORD PTR [rsi+40], r10 + adc rax, QWORD PTR [r13+48] + mov r9, QWORD PTR [rsi+56] + mov QWORD PTR [rsi+48], rax + adc r9, QWORD PTR [r13+56] + mov r10, QWORD PTR [rsi+64] + mov QWORD PTR [rsi+56], r9 + adc r10, QWORD PTR [r13+64] + mov rax, QWORD PTR [rsi+72] + mov QWORD PTR [rsi+64], r10 + adc rax, QWORD PTR [r13+72] + mov r9, QWORD PTR [rsi+80] + mov QWORD PTR [rsi+72], rax + adc r9, QWORD PTR [r13+80] + mov r10, QWORD PTR [rsi+88] + mov QWORD PTR [rsi+80], r9 + adc r10, QWORD PTR [r13+88] + mov rax, QWORD PTR [rsi+96] + mov QWORD PTR [rsi+88], r10 + adc rax, QWORD PTR [r13+96] + mov r9, QWORD PTR [rsi+104] + mov QWORD PTR [rsi+96], rax + adc r9, QWORD PTR [r13+104] + mov r10, QWORD PTR [rsi+112] + mov QWORD PTR [rsi+104], r9 + adc r10, QWORD PTR [r13+112] + mov rax, QWORD PTR [rsi+120] + mov QWORD PTR [rsi+112], r10 + adc rax, QWORD PTR [r13+120] + mov r9, QWORD PTR [rsi+128] + mov QWORD PTR [rsi+120], rax + adc r9, QWORD PTR [r13+128] + mov r10, QWORD PTR [rsi+136] + mov QWORD PTR [rsi+128], r9 + adc r10, QWORD PTR [r13+136] + mov rax, QWORD PTR [rsi+144] + mov QWORD PTR [rsi+136], r10 + adc rax, QWORD PTR [r13+144] + mov r9, QWORD PTR [rsi+152] + mov QWORD PTR [rsi+144], rax + adc r9, QWORD PTR [r13+152] + mov r10, QWORD PTR [rsi+160] + mov QWORD PTR [rsi+152], r9 + adc r10, QWORD PTR [r13+160] + mov rax, QWORD PTR [rsi+168] + mov QWORD PTR [rsi+160], r10 + adc rax, QWORD PTR [r13+168] + mov r9, QWORD PTR [rsi+176] + mov QWORD PTR [rsi+168], rax + adc r9, QWORD PTR [r13+176] + mov r10, QWORD PTR [rsi+184] + mov QWORD PTR [rsi+176], r9 + adc r10, QWORD PTR [r13+184] + mov rax, QWORD PTR [rsi+192] + mov QWORD PTR [rsi+184], r10 + adc rax, QWORD PTR [r13+192] + mov r9, QWORD PTR [rsi+200] + mov QWORD PTR [rsi+192], rax + adc r9, QWORD PTR [r13+200] + mov r10, QWORD PTR [rsi+208] + mov QWORD PTR [rsi+200], r9 + adc r10, QWORD PTR [r13+208] + mov rax, QWORD PTR [rsi+216] + mov QWORD PTR [rsi+208], r10 + adc rax, QWORD PTR [r13+216] + mov r9, QWORD PTR [rsi+224] + mov QWORD PTR [rsi+216], rax + adc r9, QWORD PTR [r13+224] + mov r10, QWORD PTR [rsi+232] + mov QWORD PTR [rsi+224], r9 + adc r10, QWORD PTR [r13+232] + mov rax, QWORD PTR [rsi+240] + mov QWORD PTR [rsi+232], r10 + adc rax, QWORD PTR [r13+240] + mov r9, QWORD PTR [rsi+248] + mov QWORD PTR [rsi+240], rax + adc r9, QWORD PTR [r13+248] + mov r10, QWORD PTR [rsi+256] + mov QWORD PTR [rsi+248], r9 + adc r10, QWORD PTR [r13+256] + mov QWORD PTR [rsi+256], r10 + adc r11, 0 + ; Add to zero + mov rax, QWORD PTR [r13+264] + adc rax, 0 + mov r9, QWORD PTR [r13+272] + mov QWORD PTR [rsi+264], rax + adc r9, 0 + mov r10, QWORD PTR [r13+280] + mov QWORD PTR [rsi+272], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+288] + mov QWORD PTR [rsi+280], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+296] + mov QWORD PTR [rsi+288], rax + adc r9, 0 + mov r10, QWORD PTR [r13+304] + mov QWORD PTR [rsi+296], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+312] + mov QWORD PTR [rsi+304], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+320] + mov QWORD PTR [rsi+312], rax + adc r9, 0 + mov r10, QWORD PTR [r13+328] + mov QWORD PTR [rsi+320], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+336] + mov QWORD PTR [rsi+328], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+344] + mov QWORD PTR [rsi+336], rax + adc r9, 0 + mov r10, QWORD PTR [r13+352] + mov QWORD PTR [rsi+344], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+360] + mov QWORD PTR [rsi+352], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+368] + mov QWORD PTR [rsi+360], rax + adc r9, 0 + mov r10, QWORD PTR [r13+376] + mov QWORD PTR [rsi+368], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+384] + mov QWORD PTR [rsi+376], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+392] + mov QWORD PTR [rsi+384], rax + adc r9, 0 + mov r10, QWORD PTR [r13+400] + mov QWORD PTR [rsi+392], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+408] + mov QWORD PTR [rsi+400], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+416] + mov QWORD PTR [rsi+408], rax + adc r9, 0 + mov r10, QWORD PTR [r13+424] + mov QWORD PTR [rsi+416], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+432] + mov QWORD PTR [rsi+424], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+440] + mov QWORD PTR [rsi+432], rax + adc r9, 0 + mov r10, QWORD PTR [r13+448] + mov QWORD PTR [rsi+440], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+456] + mov QWORD PTR [rsi+448], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+464] + mov QWORD PTR [rsi+456], rax + adc r9, 0 + mov r10, QWORD PTR [r13+472] + mov QWORD PTR [rsi+464], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+480] + mov QWORD PTR [rsi+472], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+488] + mov QWORD PTR [rsi+480], rax + adc r9, 0 + mov r10, QWORD PTR [r13+496] + mov QWORD PTR [rsi+488], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+504] + mov QWORD PTR [rsi+496], r10 + adc rax, 0 + mov QWORD PTR [rsi+504], rax + add rsp, 1576 + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_4096_mul_64 ENDP +_text ENDS +; /* Add a to a into r. (r = a + a) +; * +; * r A single precision integer. +; * a A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_2048_dbl_32 PROC + mov r8, QWORD PTR [rdx] + xor rax, rax + add r8, r8 + mov r9, QWORD PTR [rdx+8] + mov QWORD PTR [rcx], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+16] + mov QWORD PTR [rcx+8], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+24] + mov QWORD PTR [rcx+16], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+32] + mov QWORD PTR [rcx+24], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+40] + mov QWORD PTR [rcx+32], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+48] + mov QWORD PTR [rcx+40], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+56] + mov QWORD PTR [rcx+48], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+64] + mov QWORD PTR [rcx+56], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+72] + mov QWORD PTR [rcx+64], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+80] + mov QWORD PTR [rcx+72], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+88] + mov QWORD PTR [rcx+80], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+96] + mov QWORD PTR [rcx+88], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+104] + mov QWORD PTR [rcx+96], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+112] + mov QWORD PTR [rcx+104], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+120] + mov QWORD PTR [rcx+112], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+128] + mov QWORD PTR [rcx+120], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+136] + mov QWORD PTR [rcx+128], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+144] + mov QWORD PTR [rcx+136], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+152] + mov QWORD PTR [rcx+144], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+160] + mov QWORD PTR [rcx+152], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+168] + mov QWORD PTR [rcx+160], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+176] + mov QWORD PTR [rcx+168], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+184] + mov QWORD PTR [rcx+176], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+192] + mov QWORD PTR [rcx+184], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+200] + mov QWORD PTR [rcx+192], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+208] + mov QWORD PTR [rcx+200], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+216] + mov QWORD PTR [rcx+208], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+224] + mov QWORD PTR [rcx+216], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+232] + mov QWORD PTR [rcx+224], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+240] + mov QWORD PTR [rcx+232], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+248] + mov QWORD PTR [rcx+240], r8 + adc r9, r9 + mov QWORD PTR [rcx+248], r9 + adc rax, 0 + ret +sp_2048_dbl_32 ENDP +_text ENDS +; /* Square a and put result in r. (r = a * a) +; * +; * r A single precision integer. +; * a A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_4096_sqr_64 PROC + push r12 + sub rsp, 1304 + mov QWORD PTR [rsp+1280], rcx + mov QWORD PTR [rsp+1288], rdx + lea r10, QWORD PTR [rsp+1024] + lea r11, QWORD PTR [rdx+256] + ; Add + mov rax, QWORD PTR [rdx] + xor r9, r9 + add rax, QWORD PTR [r11] + mov r8, QWORD PTR [rdx+8] + mov QWORD PTR [r10], rax + adc r8, QWORD PTR [r11+8] + mov rax, QWORD PTR [rdx+16] + mov QWORD PTR [r10+8], r8 + adc rax, QWORD PTR [r11+16] + mov r8, QWORD PTR [rdx+24] + mov QWORD PTR [r10+16], rax + adc r8, QWORD PTR [r11+24] + mov rax, QWORD PTR [rdx+32] + mov QWORD PTR [r10+24], r8 + adc rax, QWORD PTR [r11+32] + mov r8, QWORD PTR [rdx+40] + mov QWORD PTR [r10+32], rax + adc r8, QWORD PTR [r11+40] + mov rax, QWORD PTR [rdx+48] + mov QWORD PTR [r10+40], r8 + adc rax, QWORD PTR [r11+48] + mov r8, QWORD PTR [rdx+56] + mov QWORD PTR [r10+48], rax + adc r8, QWORD PTR [r11+56] + mov rax, QWORD PTR [rdx+64] + mov QWORD PTR [r10+56], r8 + adc rax, QWORD PTR [r11+64] + mov r8, QWORD PTR [rdx+72] + mov QWORD PTR [r10+64], rax + adc r8, QWORD PTR [r11+72] + mov rax, QWORD PTR [rdx+80] + mov QWORD PTR [r10+72], r8 + adc rax, QWORD PTR [r11+80] + mov r8, QWORD PTR [rdx+88] + mov QWORD PTR [r10+80], rax + adc r8, QWORD PTR [r11+88] + mov rax, QWORD PTR [rdx+96] + mov QWORD PTR [r10+88], r8 + adc rax, QWORD PTR [r11+96] + mov r8, QWORD PTR [rdx+104] + mov QWORD PTR [r10+96], rax + adc r8, QWORD PTR [r11+104] + mov rax, QWORD PTR [rdx+112] + mov QWORD PTR [r10+104], r8 + adc rax, QWORD PTR [r11+112] + mov r8, QWORD PTR [rdx+120] + mov QWORD PTR [r10+112], rax + adc r8, QWORD PTR [r11+120] + mov rax, QWORD PTR [rdx+128] + mov QWORD PTR [r10+120], r8 + adc rax, QWORD PTR [r11+128] + mov r8, QWORD PTR [rdx+136] + mov QWORD PTR [r10+128], rax + adc r8, QWORD PTR [r11+136] + mov rax, QWORD PTR [rdx+144] + mov QWORD PTR [r10+136], r8 + adc rax, QWORD PTR [r11+144] + mov r8, QWORD PTR [rdx+152] + mov QWORD PTR [r10+144], rax + adc r8, QWORD PTR [r11+152] + mov rax, QWORD PTR [rdx+160] + mov QWORD PTR [r10+152], r8 + adc rax, QWORD PTR [r11+160] + mov r8, QWORD PTR [rdx+168] + mov QWORD PTR [r10+160], rax + adc r8, QWORD PTR [r11+168] + mov rax, QWORD PTR [rdx+176] + mov QWORD PTR [r10+168], r8 + adc rax, QWORD PTR [r11+176] + mov r8, QWORD PTR [rdx+184] + mov QWORD PTR [r10+176], rax + adc r8, QWORD PTR [r11+184] + mov rax, QWORD PTR [rdx+192] + mov QWORD PTR [r10+184], r8 + adc rax, QWORD PTR [r11+192] + mov r8, QWORD PTR [rdx+200] + mov QWORD PTR [r10+192], rax + adc r8, QWORD PTR [r11+200] + mov rax, QWORD PTR [rdx+208] + mov QWORD PTR [r10+200], r8 + adc rax, QWORD PTR [r11+208] + mov r8, QWORD PTR [rdx+216] + mov QWORD PTR [r10+208], rax + adc r8, QWORD PTR [r11+216] + mov rax, QWORD PTR [rdx+224] + mov QWORD PTR [r10+216], r8 + adc rax, QWORD PTR [r11+224] + mov r8, QWORD PTR [rdx+232] + mov QWORD PTR [r10+224], rax + adc r8, QWORD PTR [r11+232] + mov rax, QWORD PTR [rdx+240] + mov QWORD PTR [r10+232], r8 + adc rax, QWORD PTR [r11+240] + mov r8, QWORD PTR [rdx+248] + mov QWORD PTR [r10+240], rax + adc r8, QWORD PTR [r11+248] + mov QWORD PTR [r10+248], r8 + adc r9, 0 + mov QWORD PTR [rsp+1296], r9 + mov rdx, r10 + mov rcx, rsp + call sp_2048_sqr_32 + mov rdx, QWORD PTR [rsp+1288] + lea rcx, QWORD PTR [rsp+512] + add rdx, 256 + call sp_2048_sqr_32 + mov rdx, QWORD PTR [rsp+1288] + mov rcx, QWORD PTR [rsp+1280] + call sp_2048_sqr_32 +IFDEF _WIN64 + mov rdx, QWORD PTR [rsp+1288] + mov rcx, QWORD PTR [rsp+1280] +ENDIF + mov r12, QWORD PTR [rsp+1296] + lea r10, QWORD PTR [rsp+1024] + mov r9, r12 + neg r12 + mov rax, QWORD PTR [r10] + mov r8, QWORD PTR [r10+8] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+512], rax + mov QWORD PTR [rcx+520], r8 + mov rax, QWORD PTR [r10+16] + mov r8, QWORD PTR [r10+24] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+528], rax + mov QWORD PTR [rcx+536], r8 + mov rax, QWORD PTR [r10+32] + mov r8, QWORD PTR [r10+40] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+544], rax + mov QWORD PTR [rcx+552], r8 + mov rax, QWORD PTR [r10+48] + mov r8, QWORD PTR [r10+56] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+560], rax + mov QWORD PTR [rcx+568], r8 + mov rax, QWORD PTR [r10+64] + mov r8, QWORD PTR [r10+72] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+576], rax + mov QWORD PTR [rcx+584], r8 + mov rax, QWORD PTR [r10+80] + mov r8, QWORD PTR [r10+88] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+592], rax + mov QWORD PTR [rcx+600], r8 + mov rax, QWORD PTR [r10+96] + mov r8, QWORD PTR [r10+104] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+608], rax + mov QWORD PTR [rcx+616], r8 + mov rax, QWORD PTR [r10+112] + mov r8, QWORD PTR [r10+120] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+624], rax + mov QWORD PTR [rcx+632], r8 + mov rax, QWORD PTR [r10+128] + mov r8, QWORD PTR [r10+136] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+640], rax + mov QWORD PTR [rcx+648], r8 + mov rax, QWORD PTR [r10+144] + mov r8, QWORD PTR [r10+152] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+656], rax + mov QWORD PTR [rcx+664], r8 + mov rax, QWORD PTR [r10+160] + mov r8, QWORD PTR [r10+168] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+672], rax + mov QWORD PTR [rcx+680], r8 + mov rax, QWORD PTR [r10+176] + mov r8, QWORD PTR [r10+184] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+688], rax + mov QWORD PTR [rcx+696], r8 + mov rax, QWORD PTR [r10+192] + mov r8, QWORD PTR [r10+200] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+704], rax + mov QWORD PTR [rcx+712], r8 + mov rax, QWORD PTR [r10+208] + mov r8, QWORD PTR [r10+216] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+720], rax + mov QWORD PTR [rcx+728], r8 + mov rax, QWORD PTR [r10+224] + mov r8, QWORD PTR [r10+232] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+736], rax + mov QWORD PTR [rcx+744], r8 + mov rax, QWORD PTR [r10+240] + mov r8, QWORD PTR [r10+248] + and rax, r12 + and r8, r12 + mov QWORD PTR [rcx+752], rax + mov QWORD PTR [rcx+760], r8 + mov rax, QWORD PTR [rcx+512] + add rax, rax + mov r8, QWORD PTR [rcx+520] + mov QWORD PTR [rcx+512], rax + adc r8, r8 + mov rax, QWORD PTR [rcx+528] + mov QWORD PTR [rcx+520], r8 + adc rax, rax + mov r8, QWORD PTR [rcx+536] + mov QWORD PTR [rcx+528], rax + adc r8, r8 + mov rax, QWORD PTR [rcx+544] + mov QWORD PTR [rcx+536], r8 + adc rax, rax + mov r8, QWORD PTR [rcx+552] + mov QWORD PTR [rcx+544], rax + adc r8, r8 + mov rax, QWORD PTR [rcx+560] + mov QWORD PTR [rcx+552], r8 + adc rax, rax + mov r8, QWORD PTR [rcx+568] + mov QWORD PTR [rcx+560], rax + adc r8, r8 + mov rax, QWORD PTR [rcx+576] + mov QWORD PTR [rcx+568], r8 + adc rax, rax + mov r8, QWORD PTR [rcx+584] + mov QWORD PTR [rcx+576], rax + adc r8, r8 + mov rax, QWORD PTR [rcx+592] + mov QWORD PTR [rcx+584], r8 + adc rax, rax + mov r8, QWORD PTR [rcx+600] + mov QWORD PTR [rcx+592], rax + adc r8, r8 + mov rax, QWORD PTR [rcx+608] + mov QWORD PTR [rcx+600], r8 + adc rax, rax + mov r8, QWORD PTR [rcx+616] + mov QWORD PTR [rcx+608], rax + adc r8, r8 + mov rax, QWORD PTR [rcx+624] + mov QWORD PTR [rcx+616], r8 + adc rax, rax + mov r8, QWORD PTR [rcx+632] + mov QWORD PTR [rcx+624], rax + adc r8, r8 + mov rax, QWORD PTR [rcx+640] + mov QWORD PTR [rcx+632], r8 + adc rax, rax + mov r8, QWORD PTR [rcx+648] + mov QWORD PTR [rcx+640], rax + adc r8, r8 + mov rax, QWORD PTR [rcx+656] + mov QWORD PTR [rcx+648], r8 + adc rax, rax + mov r8, QWORD PTR [rcx+664] + mov QWORD PTR [rcx+656], rax + adc r8, r8 + mov rax, QWORD PTR [rcx+672] + mov QWORD PTR [rcx+664], r8 + adc rax, rax + mov r8, QWORD PTR [rcx+680] + mov QWORD PTR [rcx+672], rax + adc r8, r8 + mov rax, QWORD PTR [rcx+688] + mov QWORD PTR [rcx+680], r8 + adc rax, rax + mov r8, QWORD PTR [rcx+696] + mov QWORD PTR [rcx+688], rax + adc r8, r8 + mov rax, QWORD PTR [rcx+704] + mov QWORD PTR [rcx+696], r8 + adc rax, rax + mov r8, QWORD PTR [rcx+712] + mov QWORD PTR [rcx+704], rax + adc r8, r8 + mov rax, QWORD PTR [rcx+720] + mov QWORD PTR [rcx+712], r8 + adc rax, rax + mov r8, QWORD PTR [rcx+728] + mov QWORD PTR [rcx+720], rax + adc r8, r8 + mov rax, QWORD PTR [rcx+736] + mov QWORD PTR [rcx+728], r8 + adc rax, rax + mov r8, QWORD PTR [rcx+744] + mov QWORD PTR [rcx+736], rax + adc r8, r8 + mov rax, QWORD PTR [rcx+752] + mov QWORD PTR [rcx+744], r8 + adc rax, rax + mov r8, QWORD PTR [rcx+760] + mov QWORD PTR [rcx+752], rax + adc r8, r8 + mov QWORD PTR [rcx+760], r8 + adc r9, 0 + lea rdx, QWORD PTR [rsp+512] + mov r10, rsp + mov rax, QWORD PTR [r10] + sub rax, QWORD PTR [rdx] + mov r8, QWORD PTR [r10+8] + mov QWORD PTR [r10], rax + sbb r8, QWORD PTR [rdx+8] + mov rax, QWORD PTR [r10+16] + mov QWORD PTR [r10+8], r8 + sbb rax, QWORD PTR [rdx+16] + mov r8, QWORD PTR [r10+24] + mov QWORD PTR [r10+16], rax + sbb r8, QWORD PTR [rdx+24] + mov rax, QWORD PTR [r10+32] + mov QWORD PTR [r10+24], r8 + sbb rax, QWORD PTR [rdx+32] + mov r8, QWORD PTR [r10+40] + mov QWORD PTR [r10+32], rax + sbb r8, QWORD PTR [rdx+40] + mov rax, QWORD PTR [r10+48] + mov QWORD PTR [r10+40], r8 + sbb rax, QWORD PTR [rdx+48] + mov r8, QWORD PTR [r10+56] + mov QWORD PTR [r10+48], rax + sbb r8, QWORD PTR [rdx+56] + mov rax, QWORD PTR [r10+64] + mov QWORD PTR [r10+56], r8 + sbb rax, QWORD PTR [rdx+64] + mov r8, QWORD PTR [r10+72] + mov QWORD PTR [r10+64], rax + sbb r8, QWORD PTR [rdx+72] + mov rax, QWORD PTR [r10+80] + mov QWORD PTR [r10+72], r8 + sbb rax, QWORD PTR [rdx+80] + mov r8, QWORD PTR [r10+88] + mov QWORD PTR [r10+80], rax + sbb r8, QWORD PTR [rdx+88] + mov rax, QWORD PTR [r10+96] + mov QWORD PTR [r10+88], r8 + sbb rax, QWORD PTR [rdx+96] + mov r8, QWORD PTR [r10+104] + mov QWORD PTR [r10+96], rax + sbb r8, QWORD PTR [rdx+104] + mov rax, QWORD PTR [r10+112] + mov QWORD PTR [r10+104], r8 + sbb rax, QWORD PTR [rdx+112] + mov r8, QWORD PTR [r10+120] + mov QWORD PTR [r10+112], rax + sbb r8, QWORD PTR [rdx+120] + mov rax, QWORD PTR [r10+128] + mov QWORD PTR [r10+120], r8 + sbb rax, QWORD PTR [rdx+128] + mov r8, QWORD PTR [r10+136] + mov QWORD PTR [r10+128], rax + sbb r8, QWORD PTR [rdx+136] + mov rax, QWORD PTR [r10+144] + mov QWORD PTR [r10+136], r8 + sbb rax, QWORD PTR [rdx+144] + mov r8, QWORD PTR [r10+152] + mov QWORD PTR [r10+144], rax + sbb r8, QWORD PTR [rdx+152] + mov rax, QWORD PTR [r10+160] + mov QWORD PTR [r10+152], r8 + sbb rax, QWORD PTR [rdx+160] + mov r8, QWORD PTR [r10+168] + mov QWORD PTR [r10+160], rax + sbb r8, QWORD PTR [rdx+168] + mov rax, QWORD PTR [r10+176] + mov QWORD PTR [r10+168], r8 + sbb rax, QWORD PTR [rdx+176] + mov r8, QWORD PTR [r10+184] + mov QWORD PTR [r10+176], rax + sbb r8, QWORD PTR [rdx+184] + mov rax, QWORD PTR [r10+192] + mov QWORD PTR [r10+184], r8 + sbb rax, QWORD PTR [rdx+192] + mov r8, QWORD PTR [r10+200] + mov QWORD PTR [r10+192], rax + sbb r8, QWORD PTR [rdx+200] + mov rax, QWORD PTR [r10+208] + mov QWORD PTR [r10+200], r8 + sbb rax, QWORD PTR [rdx+208] + mov r8, QWORD PTR [r10+216] + mov QWORD PTR [r10+208], rax + sbb r8, QWORD PTR [rdx+216] + mov rax, QWORD PTR [r10+224] + mov QWORD PTR [r10+216], r8 + sbb rax, QWORD PTR [rdx+224] + mov r8, QWORD PTR [r10+232] + mov QWORD PTR [r10+224], rax + sbb r8, QWORD PTR [rdx+232] + mov rax, QWORD PTR [r10+240] + mov QWORD PTR [r10+232], r8 + sbb rax, QWORD PTR [rdx+240] + mov r8, QWORD PTR [r10+248] + mov QWORD PTR [r10+240], rax + sbb r8, QWORD PTR [rdx+248] + mov rax, QWORD PTR [r10+256] + mov QWORD PTR [r10+248], r8 + sbb rax, QWORD PTR [rdx+256] + mov r8, QWORD PTR [r10+264] + mov QWORD PTR [r10+256], rax + sbb r8, QWORD PTR [rdx+264] + mov rax, QWORD PTR [r10+272] + mov QWORD PTR [r10+264], r8 + sbb rax, QWORD PTR [rdx+272] + mov r8, QWORD PTR [r10+280] + mov QWORD PTR [r10+272], rax + sbb r8, QWORD PTR [rdx+280] + mov rax, QWORD PTR [r10+288] + mov QWORD PTR [r10+280], r8 + sbb rax, QWORD PTR [rdx+288] + mov r8, QWORD PTR [r10+296] + mov QWORD PTR [r10+288], rax + sbb r8, QWORD PTR [rdx+296] + mov rax, QWORD PTR [r10+304] + mov QWORD PTR [r10+296], r8 + sbb rax, QWORD PTR [rdx+304] + mov r8, QWORD PTR [r10+312] + mov QWORD PTR [r10+304], rax + sbb r8, QWORD PTR [rdx+312] + mov rax, QWORD PTR [r10+320] + mov QWORD PTR [r10+312], r8 + sbb rax, QWORD PTR [rdx+320] + mov r8, QWORD PTR [r10+328] + mov QWORD PTR [r10+320], rax + sbb r8, QWORD PTR [rdx+328] + mov rax, QWORD PTR [r10+336] + mov QWORD PTR [r10+328], r8 + sbb rax, QWORD PTR [rdx+336] + mov r8, QWORD PTR [r10+344] + mov QWORD PTR [r10+336], rax + sbb r8, QWORD PTR [rdx+344] + mov rax, QWORD PTR [r10+352] + mov QWORD PTR [r10+344], r8 + sbb rax, QWORD PTR [rdx+352] + mov r8, QWORD PTR [r10+360] + mov QWORD PTR [r10+352], rax + sbb r8, QWORD PTR [rdx+360] + mov rax, QWORD PTR [r10+368] + mov QWORD PTR [r10+360], r8 + sbb rax, QWORD PTR [rdx+368] + mov r8, QWORD PTR [r10+376] + mov QWORD PTR [r10+368], rax + sbb r8, QWORD PTR [rdx+376] + mov rax, QWORD PTR [r10+384] + mov QWORD PTR [r10+376], r8 + sbb rax, QWORD PTR [rdx+384] + mov r8, QWORD PTR [r10+392] + mov QWORD PTR [r10+384], rax + sbb r8, QWORD PTR [rdx+392] + mov rax, QWORD PTR [r10+400] + mov QWORD PTR [r10+392], r8 + sbb rax, QWORD PTR [rdx+400] + mov r8, QWORD PTR [r10+408] + mov QWORD PTR [r10+400], rax + sbb r8, QWORD PTR [rdx+408] + mov rax, QWORD PTR [r10+416] + mov QWORD PTR [r10+408], r8 + sbb rax, QWORD PTR [rdx+416] + mov r8, QWORD PTR [r10+424] + mov QWORD PTR [r10+416], rax + sbb r8, QWORD PTR [rdx+424] + mov rax, QWORD PTR [r10+432] + mov QWORD PTR [r10+424], r8 + sbb rax, QWORD PTR [rdx+432] + mov r8, QWORD PTR [r10+440] + mov QWORD PTR [r10+432], rax + sbb r8, QWORD PTR [rdx+440] + mov rax, QWORD PTR [r10+448] + mov QWORD PTR [r10+440], r8 + sbb rax, QWORD PTR [rdx+448] + mov r8, QWORD PTR [r10+456] + mov QWORD PTR [r10+448], rax + sbb r8, QWORD PTR [rdx+456] + mov rax, QWORD PTR [r10+464] + mov QWORD PTR [r10+456], r8 + sbb rax, QWORD PTR [rdx+464] + mov r8, QWORD PTR [r10+472] + mov QWORD PTR [r10+464], rax + sbb r8, QWORD PTR [rdx+472] + mov rax, QWORD PTR [r10+480] + mov QWORD PTR [r10+472], r8 + sbb rax, QWORD PTR [rdx+480] + mov r8, QWORD PTR [r10+488] + mov QWORD PTR [r10+480], rax + sbb r8, QWORD PTR [rdx+488] + mov rax, QWORD PTR [r10+496] + mov QWORD PTR [r10+488], r8 + sbb rax, QWORD PTR [rdx+496] + mov r8, QWORD PTR [r10+504] + mov QWORD PTR [r10+496], rax + sbb r8, QWORD PTR [rdx+504] + mov QWORD PTR [r10+504], r8 + sbb r9, 0 + mov rax, QWORD PTR [r10] + sub rax, QWORD PTR [rcx] + mov r8, QWORD PTR [r10+8] + mov QWORD PTR [r10], rax + sbb r8, QWORD PTR [rcx+8] + mov rax, QWORD PTR [r10+16] + mov QWORD PTR [r10+8], r8 + sbb rax, QWORD PTR [rcx+16] + mov r8, QWORD PTR [r10+24] + mov QWORD PTR [r10+16], rax + sbb r8, QWORD PTR [rcx+24] + mov rax, QWORD PTR [r10+32] + mov QWORD PTR [r10+24], r8 + sbb rax, QWORD PTR [rcx+32] + mov r8, QWORD PTR [r10+40] + mov QWORD PTR [r10+32], rax + sbb r8, QWORD PTR [rcx+40] + mov rax, QWORD PTR [r10+48] + mov QWORD PTR [r10+40], r8 + sbb rax, QWORD PTR [rcx+48] + mov r8, QWORD PTR [r10+56] + mov QWORD PTR [r10+48], rax + sbb r8, QWORD PTR [rcx+56] + mov rax, QWORD PTR [r10+64] + mov QWORD PTR [r10+56], r8 + sbb rax, QWORD PTR [rcx+64] + mov r8, QWORD PTR [r10+72] + mov QWORD PTR [r10+64], rax + sbb r8, QWORD PTR [rcx+72] + mov rax, QWORD PTR [r10+80] + mov QWORD PTR [r10+72], r8 + sbb rax, QWORD PTR [rcx+80] + mov r8, QWORD PTR [r10+88] + mov QWORD PTR [r10+80], rax + sbb r8, QWORD PTR [rcx+88] + mov rax, QWORD PTR [r10+96] + mov QWORD PTR [r10+88], r8 + sbb rax, QWORD PTR [rcx+96] + mov r8, QWORD PTR [r10+104] + mov QWORD PTR [r10+96], rax + sbb r8, QWORD PTR [rcx+104] + mov rax, QWORD PTR [r10+112] + mov QWORD PTR [r10+104], r8 + sbb rax, QWORD PTR [rcx+112] + mov r8, QWORD PTR [r10+120] + mov QWORD PTR [r10+112], rax + sbb r8, QWORD PTR [rcx+120] + mov rax, QWORD PTR [r10+128] + mov QWORD PTR [r10+120], r8 + sbb rax, QWORD PTR [rcx+128] + mov r8, QWORD PTR [r10+136] + mov QWORD PTR [r10+128], rax + sbb r8, QWORD PTR [rcx+136] + mov rax, QWORD PTR [r10+144] + mov QWORD PTR [r10+136], r8 + sbb rax, QWORD PTR [rcx+144] + mov r8, QWORD PTR [r10+152] + mov QWORD PTR [r10+144], rax + sbb r8, QWORD PTR [rcx+152] + mov rax, QWORD PTR [r10+160] + mov QWORD PTR [r10+152], r8 + sbb rax, QWORD PTR [rcx+160] + mov r8, QWORD PTR [r10+168] + mov QWORD PTR [r10+160], rax + sbb r8, QWORD PTR [rcx+168] + mov rax, QWORD PTR [r10+176] + mov QWORD PTR [r10+168], r8 + sbb rax, QWORD PTR [rcx+176] + mov r8, QWORD PTR [r10+184] + mov QWORD PTR [r10+176], rax + sbb r8, QWORD PTR [rcx+184] + mov rax, QWORD PTR [r10+192] + mov QWORD PTR [r10+184], r8 + sbb rax, QWORD PTR [rcx+192] + mov r8, QWORD PTR [r10+200] + mov QWORD PTR [r10+192], rax + sbb r8, QWORD PTR [rcx+200] + mov rax, QWORD PTR [r10+208] + mov QWORD PTR [r10+200], r8 + sbb rax, QWORD PTR [rcx+208] + mov r8, QWORD PTR [r10+216] + mov QWORD PTR [r10+208], rax + sbb r8, QWORD PTR [rcx+216] + mov rax, QWORD PTR [r10+224] + mov QWORD PTR [r10+216], r8 + sbb rax, QWORD PTR [rcx+224] + mov r8, QWORD PTR [r10+232] + mov QWORD PTR [r10+224], rax + sbb r8, QWORD PTR [rcx+232] + mov rax, QWORD PTR [r10+240] + mov QWORD PTR [r10+232], r8 + sbb rax, QWORD PTR [rcx+240] + mov r8, QWORD PTR [r10+248] + mov QWORD PTR [r10+240], rax + sbb r8, QWORD PTR [rcx+248] + mov rax, QWORD PTR [r10+256] + mov QWORD PTR [r10+248], r8 + sbb rax, QWORD PTR [rcx+256] + mov r8, QWORD PTR [r10+264] + mov QWORD PTR [r10+256], rax + sbb r8, QWORD PTR [rcx+264] + mov rax, QWORD PTR [r10+272] + mov QWORD PTR [r10+264], r8 + sbb rax, QWORD PTR [rcx+272] + mov r8, QWORD PTR [r10+280] + mov QWORD PTR [r10+272], rax + sbb r8, QWORD PTR [rcx+280] + mov rax, QWORD PTR [r10+288] + mov QWORD PTR [r10+280], r8 + sbb rax, QWORD PTR [rcx+288] + mov r8, QWORD PTR [r10+296] + mov QWORD PTR [r10+288], rax + sbb r8, QWORD PTR [rcx+296] + mov rax, QWORD PTR [r10+304] + mov QWORD PTR [r10+296], r8 + sbb rax, QWORD PTR [rcx+304] + mov r8, QWORD PTR [r10+312] + mov QWORD PTR [r10+304], rax + sbb r8, QWORD PTR [rcx+312] + mov rax, QWORD PTR [r10+320] + mov QWORD PTR [r10+312], r8 + sbb rax, QWORD PTR [rcx+320] + mov r8, QWORD PTR [r10+328] + mov QWORD PTR [r10+320], rax + sbb r8, QWORD PTR [rcx+328] + mov rax, QWORD PTR [r10+336] + mov QWORD PTR [r10+328], r8 + sbb rax, QWORD PTR [rcx+336] + mov r8, QWORD PTR [r10+344] + mov QWORD PTR [r10+336], rax + sbb r8, QWORD PTR [rcx+344] + mov rax, QWORD PTR [r10+352] + mov QWORD PTR [r10+344], r8 + sbb rax, QWORD PTR [rcx+352] + mov r8, QWORD PTR [r10+360] + mov QWORD PTR [r10+352], rax + sbb r8, QWORD PTR [rcx+360] + mov rax, QWORD PTR [r10+368] + mov QWORD PTR [r10+360], r8 + sbb rax, QWORD PTR [rcx+368] + mov r8, QWORD PTR [r10+376] + mov QWORD PTR [r10+368], rax + sbb r8, QWORD PTR [rcx+376] + mov rax, QWORD PTR [r10+384] + mov QWORD PTR [r10+376], r8 + sbb rax, QWORD PTR [rcx+384] + mov r8, QWORD PTR [r10+392] + mov QWORD PTR [r10+384], rax + sbb r8, QWORD PTR [rcx+392] + mov rax, QWORD PTR [r10+400] + mov QWORD PTR [r10+392], r8 + sbb rax, QWORD PTR [rcx+400] + mov r8, QWORD PTR [r10+408] + mov QWORD PTR [r10+400], rax + sbb r8, QWORD PTR [rcx+408] + mov rax, QWORD PTR [r10+416] + mov QWORD PTR [r10+408], r8 + sbb rax, QWORD PTR [rcx+416] + mov r8, QWORD PTR [r10+424] + mov QWORD PTR [r10+416], rax + sbb r8, QWORD PTR [rcx+424] + mov rax, QWORD PTR [r10+432] + mov QWORD PTR [r10+424], r8 + sbb rax, QWORD PTR [rcx+432] + mov r8, QWORD PTR [r10+440] + mov QWORD PTR [r10+432], rax + sbb r8, QWORD PTR [rcx+440] + mov rax, QWORD PTR [r10+448] + mov QWORD PTR [r10+440], r8 + sbb rax, QWORD PTR [rcx+448] + mov r8, QWORD PTR [r10+456] + mov QWORD PTR [r10+448], rax + sbb r8, QWORD PTR [rcx+456] + mov rax, QWORD PTR [r10+464] + mov QWORD PTR [r10+456], r8 + sbb rax, QWORD PTR [rcx+464] + mov r8, QWORD PTR [r10+472] + mov QWORD PTR [r10+464], rax + sbb r8, QWORD PTR [rcx+472] + mov rax, QWORD PTR [r10+480] + mov QWORD PTR [r10+472], r8 + sbb rax, QWORD PTR [rcx+480] + mov r8, QWORD PTR [r10+488] + mov QWORD PTR [r10+480], rax + sbb r8, QWORD PTR [rcx+488] + mov rax, QWORD PTR [r10+496] + mov QWORD PTR [r10+488], r8 + sbb rax, QWORD PTR [rcx+496] + mov r8, QWORD PTR [r10+504] + mov QWORD PTR [r10+496], rax + sbb r8, QWORD PTR [rcx+504] + mov QWORD PTR [r10+504], r8 + sbb r9, 0 + ; Add in place + mov rax, QWORD PTR [rcx+256] + add rax, QWORD PTR [r10] + mov r8, QWORD PTR [rcx+264] + mov QWORD PTR [rcx+256], rax + adc r8, QWORD PTR [r10+8] + mov rax, QWORD PTR [rcx+272] + mov QWORD PTR [rcx+264], r8 + adc rax, QWORD PTR [r10+16] + mov r8, QWORD PTR [rcx+280] + mov QWORD PTR [rcx+272], rax + adc r8, QWORD PTR [r10+24] + mov rax, QWORD PTR [rcx+288] + mov QWORD PTR [rcx+280], r8 + adc rax, QWORD PTR [r10+32] + mov r8, QWORD PTR [rcx+296] + mov QWORD PTR [rcx+288], rax + adc r8, QWORD PTR [r10+40] + mov rax, QWORD PTR [rcx+304] + mov QWORD PTR [rcx+296], r8 + adc rax, QWORD PTR [r10+48] + mov r8, QWORD PTR [rcx+312] + mov QWORD PTR [rcx+304], rax + adc r8, QWORD PTR [r10+56] + mov rax, QWORD PTR [rcx+320] + mov QWORD PTR [rcx+312], r8 + adc rax, QWORD PTR [r10+64] + mov r8, QWORD PTR [rcx+328] + mov QWORD PTR [rcx+320], rax + adc r8, QWORD PTR [r10+72] + mov rax, QWORD PTR [rcx+336] + mov QWORD PTR [rcx+328], r8 + adc rax, QWORD PTR [r10+80] + mov r8, QWORD PTR [rcx+344] + mov QWORD PTR [rcx+336], rax + adc r8, QWORD PTR [r10+88] + mov rax, QWORD PTR [rcx+352] + mov QWORD PTR [rcx+344], r8 + adc rax, QWORD PTR [r10+96] + mov r8, QWORD PTR [rcx+360] + mov QWORD PTR [rcx+352], rax + adc r8, QWORD PTR [r10+104] + mov rax, QWORD PTR [rcx+368] + mov QWORD PTR [rcx+360], r8 + adc rax, QWORD PTR [r10+112] + mov r8, QWORD PTR [rcx+376] + mov QWORD PTR [rcx+368], rax + adc r8, QWORD PTR [r10+120] + mov rax, QWORD PTR [rcx+384] + mov QWORD PTR [rcx+376], r8 + adc rax, QWORD PTR [r10+128] + mov r8, QWORD PTR [rcx+392] + mov QWORD PTR [rcx+384], rax + adc r8, QWORD PTR [r10+136] + mov rax, QWORD PTR [rcx+400] + mov QWORD PTR [rcx+392], r8 + adc rax, QWORD PTR [r10+144] + mov r8, QWORD PTR [rcx+408] + mov QWORD PTR [rcx+400], rax + adc r8, QWORD PTR [r10+152] + mov rax, QWORD PTR [rcx+416] + mov QWORD PTR [rcx+408], r8 + adc rax, QWORD PTR [r10+160] + mov r8, QWORD PTR [rcx+424] + mov QWORD PTR [rcx+416], rax + adc r8, QWORD PTR [r10+168] + mov rax, QWORD PTR [rcx+432] + mov QWORD PTR [rcx+424], r8 + adc rax, QWORD PTR [r10+176] + mov r8, QWORD PTR [rcx+440] + mov QWORD PTR [rcx+432], rax + adc r8, QWORD PTR [r10+184] + mov rax, QWORD PTR [rcx+448] + mov QWORD PTR [rcx+440], r8 + adc rax, QWORD PTR [r10+192] + mov r8, QWORD PTR [rcx+456] + mov QWORD PTR [rcx+448], rax + adc r8, QWORD PTR [r10+200] + mov rax, QWORD PTR [rcx+464] + mov QWORD PTR [rcx+456], r8 + adc rax, QWORD PTR [r10+208] + mov r8, QWORD PTR [rcx+472] + mov QWORD PTR [rcx+464], rax + adc r8, QWORD PTR [r10+216] + mov rax, QWORD PTR [rcx+480] + mov QWORD PTR [rcx+472], r8 + adc rax, QWORD PTR [r10+224] + mov r8, QWORD PTR [rcx+488] + mov QWORD PTR [rcx+480], rax + adc r8, QWORD PTR [r10+232] + mov rax, QWORD PTR [rcx+496] + mov QWORD PTR [rcx+488], r8 + adc rax, QWORD PTR [r10+240] + mov r8, QWORD PTR [rcx+504] + mov QWORD PTR [rcx+496], rax + adc r8, QWORD PTR [r10+248] + mov rax, QWORD PTR [rcx+512] + mov QWORD PTR [rcx+504], r8 + adc rax, QWORD PTR [r10+256] + mov r8, QWORD PTR [rcx+520] + mov QWORD PTR [rcx+512], rax + adc r8, QWORD PTR [r10+264] + mov rax, QWORD PTR [rcx+528] + mov QWORD PTR [rcx+520], r8 + adc rax, QWORD PTR [r10+272] + mov r8, QWORD PTR [rcx+536] + mov QWORD PTR [rcx+528], rax + adc r8, QWORD PTR [r10+280] + mov rax, QWORD PTR [rcx+544] + mov QWORD PTR [rcx+536], r8 + adc rax, QWORD PTR [r10+288] + mov r8, QWORD PTR [rcx+552] + mov QWORD PTR [rcx+544], rax + adc r8, QWORD PTR [r10+296] + mov rax, QWORD PTR [rcx+560] + mov QWORD PTR [rcx+552], r8 + adc rax, QWORD PTR [r10+304] + mov r8, QWORD PTR [rcx+568] + mov QWORD PTR [rcx+560], rax + adc r8, QWORD PTR [r10+312] + mov rax, QWORD PTR [rcx+576] + mov QWORD PTR [rcx+568], r8 + adc rax, QWORD PTR [r10+320] + mov r8, QWORD PTR [rcx+584] + mov QWORD PTR [rcx+576], rax + adc r8, QWORD PTR [r10+328] + mov rax, QWORD PTR [rcx+592] + mov QWORD PTR [rcx+584], r8 + adc rax, QWORD PTR [r10+336] + mov r8, QWORD PTR [rcx+600] + mov QWORD PTR [rcx+592], rax + adc r8, QWORD PTR [r10+344] + mov rax, QWORD PTR [rcx+608] + mov QWORD PTR [rcx+600], r8 + adc rax, QWORD PTR [r10+352] + mov r8, QWORD PTR [rcx+616] + mov QWORD PTR [rcx+608], rax + adc r8, QWORD PTR [r10+360] + mov rax, QWORD PTR [rcx+624] + mov QWORD PTR [rcx+616], r8 + adc rax, QWORD PTR [r10+368] + mov r8, QWORD PTR [rcx+632] + mov QWORD PTR [rcx+624], rax + adc r8, QWORD PTR [r10+376] + mov rax, QWORD PTR [rcx+640] + mov QWORD PTR [rcx+632], r8 + adc rax, QWORD PTR [r10+384] + mov r8, QWORD PTR [rcx+648] + mov QWORD PTR [rcx+640], rax + adc r8, QWORD PTR [r10+392] + mov rax, QWORD PTR [rcx+656] + mov QWORD PTR [rcx+648], r8 + adc rax, QWORD PTR [r10+400] + mov r8, QWORD PTR [rcx+664] + mov QWORD PTR [rcx+656], rax + adc r8, QWORD PTR [r10+408] + mov rax, QWORD PTR [rcx+672] + mov QWORD PTR [rcx+664], r8 + adc rax, QWORD PTR [r10+416] + mov r8, QWORD PTR [rcx+680] + mov QWORD PTR [rcx+672], rax + adc r8, QWORD PTR [r10+424] + mov rax, QWORD PTR [rcx+688] + mov QWORD PTR [rcx+680], r8 + adc rax, QWORD PTR [r10+432] + mov r8, QWORD PTR [rcx+696] + mov QWORD PTR [rcx+688], rax + adc r8, QWORD PTR [r10+440] + mov rax, QWORD PTR [rcx+704] + mov QWORD PTR [rcx+696], r8 + adc rax, QWORD PTR [r10+448] + mov r8, QWORD PTR [rcx+712] + mov QWORD PTR [rcx+704], rax + adc r8, QWORD PTR [r10+456] + mov rax, QWORD PTR [rcx+720] + mov QWORD PTR [rcx+712], r8 + adc rax, QWORD PTR [r10+464] + mov r8, QWORD PTR [rcx+728] + mov QWORD PTR [rcx+720], rax + adc r8, QWORD PTR [r10+472] + mov rax, QWORD PTR [rcx+736] + mov QWORD PTR [rcx+728], r8 + adc rax, QWORD PTR [r10+480] + mov r8, QWORD PTR [rcx+744] + mov QWORD PTR [rcx+736], rax + adc r8, QWORD PTR [r10+488] + mov rax, QWORD PTR [rcx+752] + mov QWORD PTR [rcx+744], r8 + adc rax, QWORD PTR [r10+496] + mov r8, QWORD PTR [rcx+760] + mov QWORD PTR [rcx+752], rax + adc r8, QWORD PTR [r10+504] + mov QWORD PTR [rcx+760], r8 + adc r9, 0 + mov QWORD PTR [rcx+768], r9 + ; Add in place + mov rax, QWORD PTR [rcx+512] + xor r9, r9 + add rax, QWORD PTR [rdx] + mov r8, QWORD PTR [rcx+520] + mov QWORD PTR [rcx+512], rax + adc r8, QWORD PTR [rdx+8] + mov rax, QWORD PTR [rcx+528] + mov QWORD PTR [rcx+520], r8 + adc rax, QWORD PTR [rdx+16] + mov r8, QWORD PTR [rcx+536] + mov QWORD PTR [rcx+528], rax + adc r8, QWORD PTR [rdx+24] + mov rax, QWORD PTR [rcx+544] + mov QWORD PTR [rcx+536], r8 + adc rax, QWORD PTR [rdx+32] + mov r8, QWORD PTR [rcx+552] + mov QWORD PTR [rcx+544], rax + adc r8, QWORD PTR [rdx+40] + mov rax, QWORD PTR [rcx+560] + mov QWORD PTR [rcx+552], r8 + adc rax, QWORD PTR [rdx+48] + mov r8, QWORD PTR [rcx+568] + mov QWORD PTR [rcx+560], rax + adc r8, QWORD PTR [rdx+56] + mov rax, QWORD PTR [rcx+576] + mov QWORD PTR [rcx+568], r8 + adc rax, QWORD PTR [rdx+64] + mov r8, QWORD PTR [rcx+584] + mov QWORD PTR [rcx+576], rax + adc r8, QWORD PTR [rdx+72] + mov rax, QWORD PTR [rcx+592] + mov QWORD PTR [rcx+584], r8 + adc rax, QWORD PTR [rdx+80] + mov r8, QWORD PTR [rcx+600] + mov QWORD PTR [rcx+592], rax + adc r8, QWORD PTR [rdx+88] + mov rax, QWORD PTR [rcx+608] + mov QWORD PTR [rcx+600], r8 + adc rax, QWORD PTR [rdx+96] + mov r8, QWORD PTR [rcx+616] + mov QWORD PTR [rcx+608], rax + adc r8, QWORD PTR [rdx+104] + mov rax, QWORD PTR [rcx+624] + mov QWORD PTR [rcx+616], r8 + adc rax, QWORD PTR [rdx+112] + mov r8, QWORD PTR [rcx+632] + mov QWORD PTR [rcx+624], rax + adc r8, QWORD PTR [rdx+120] + mov rax, QWORD PTR [rcx+640] + mov QWORD PTR [rcx+632], r8 + adc rax, QWORD PTR [rdx+128] + mov r8, QWORD PTR [rcx+648] + mov QWORD PTR [rcx+640], rax + adc r8, QWORD PTR [rdx+136] + mov rax, QWORD PTR [rcx+656] + mov QWORD PTR [rcx+648], r8 + adc rax, QWORD PTR [rdx+144] + mov r8, QWORD PTR [rcx+664] + mov QWORD PTR [rcx+656], rax + adc r8, QWORD PTR [rdx+152] + mov rax, QWORD PTR [rcx+672] + mov QWORD PTR [rcx+664], r8 + adc rax, QWORD PTR [rdx+160] + mov r8, QWORD PTR [rcx+680] + mov QWORD PTR [rcx+672], rax + adc r8, QWORD PTR [rdx+168] + mov rax, QWORD PTR [rcx+688] + mov QWORD PTR [rcx+680], r8 + adc rax, QWORD PTR [rdx+176] + mov r8, QWORD PTR [rcx+696] + mov QWORD PTR [rcx+688], rax + adc r8, QWORD PTR [rdx+184] + mov rax, QWORD PTR [rcx+704] + mov QWORD PTR [rcx+696], r8 + adc rax, QWORD PTR [rdx+192] + mov r8, QWORD PTR [rcx+712] + mov QWORD PTR [rcx+704], rax + adc r8, QWORD PTR [rdx+200] + mov rax, QWORD PTR [rcx+720] + mov QWORD PTR [rcx+712], r8 + adc rax, QWORD PTR [rdx+208] + mov r8, QWORD PTR [rcx+728] + mov QWORD PTR [rcx+720], rax + adc r8, QWORD PTR [rdx+216] + mov rax, QWORD PTR [rcx+736] + mov QWORD PTR [rcx+728], r8 + adc rax, QWORD PTR [rdx+224] + mov r8, QWORD PTR [rcx+744] + mov QWORD PTR [rcx+736], rax + adc r8, QWORD PTR [rdx+232] + mov rax, QWORD PTR [rcx+752] + mov QWORD PTR [rcx+744], r8 + adc rax, QWORD PTR [rdx+240] + mov r8, QWORD PTR [rcx+760] + mov QWORD PTR [rcx+752], rax + adc r8, QWORD PTR [rdx+248] + mov rax, QWORD PTR [rcx+768] + mov QWORD PTR [rcx+760], r8 + adc rax, QWORD PTR [rdx+256] + mov QWORD PTR [rcx+768], rax + adc r9, 0 + ; Add to zero + mov rax, QWORD PTR [rdx+264] + adc rax, 0 + mov r8, QWORD PTR [rdx+272] + mov QWORD PTR [rcx+776], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+280] + mov QWORD PTR [rcx+784], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+288] + mov QWORD PTR [rcx+792], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+296] + mov QWORD PTR [rcx+800], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+304] + mov QWORD PTR [rcx+808], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+312] + mov QWORD PTR [rcx+816], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+320] + mov QWORD PTR [rcx+824], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+328] + mov QWORD PTR [rcx+832], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+336] + mov QWORD PTR [rcx+840], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+344] + mov QWORD PTR [rcx+848], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+352] + mov QWORD PTR [rcx+856], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+360] + mov QWORD PTR [rcx+864], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+368] + mov QWORD PTR [rcx+872], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+376] + mov QWORD PTR [rcx+880], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+384] + mov QWORD PTR [rcx+888], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+392] + mov QWORD PTR [rcx+896], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+400] + mov QWORD PTR [rcx+904], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+408] + mov QWORD PTR [rcx+912], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+416] + mov QWORD PTR [rcx+920], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+424] + mov QWORD PTR [rcx+928], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+432] + mov QWORD PTR [rcx+936], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+440] + mov QWORD PTR [rcx+944], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+448] + mov QWORD PTR [rcx+952], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+456] + mov QWORD PTR [rcx+960], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+464] + mov QWORD PTR [rcx+968], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+472] + mov QWORD PTR [rcx+976], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+480] + mov QWORD PTR [rcx+984], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+488] + mov QWORD PTR [rcx+992], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+496] + mov QWORD PTR [rcx+1000], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+504] + mov QWORD PTR [rcx+1008], r8 + adc rax, 0 + mov QWORD PTR [rcx+1016], rax + add rsp, 1304 + pop r12 + ret +sp_4096_sqr_64 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Multiply a and b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_4096_mul_avx2_64 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + sub rsp, 1576 + mov QWORD PTR [rsp+1536], rcx + mov QWORD PTR [rsp+1544], rdx + mov QWORD PTR [rsp+1552], r8 + lea r12, QWORD PTR [rsp+1024] + lea r14, QWORD PTR [rdx+256] + ; Add + mov rax, QWORD PTR [rdx] + xor r15, r15 + add rax, QWORD PTR [r14] + mov r9, QWORD PTR [rdx+8] + mov QWORD PTR [r12], rax + adc r9, QWORD PTR [r14+8] + mov r10, QWORD PTR [rdx+16] + mov QWORD PTR [r12+8], r9 + adc r10, QWORD PTR [r14+16] + mov rax, QWORD PTR [rdx+24] + mov QWORD PTR [r12+16], r10 + adc rax, QWORD PTR [r14+24] + mov r9, QWORD PTR [rdx+32] + mov QWORD PTR [r12+24], rax + adc r9, QWORD PTR [r14+32] + mov r10, QWORD PTR [rdx+40] + mov QWORD PTR [r12+32], r9 + adc r10, QWORD PTR [r14+40] + mov rax, QWORD PTR [rdx+48] + mov QWORD PTR [r12+40], r10 + adc rax, QWORD PTR [r14+48] + mov r9, QWORD PTR [rdx+56] + mov QWORD PTR [r12+48], rax + adc r9, QWORD PTR [r14+56] + mov r10, QWORD PTR [rdx+64] + mov QWORD PTR [r12+56], r9 + adc r10, QWORD PTR [r14+64] + mov rax, QWORD PTR [rdx+72] + mov QWORD PTR [r12+64], r10 + adc rax, QWORD PTR [r14+72] + mov r9, QWORD PTR [rdx+80] + mov QWORD PTR [r12+72], rax + adc r9, QWORD PTR [r14+80] + mov r10, QWORD PTR [rdx+88] + mov QWORD PTR [r12+80], r9 + adc r10, QWORD PTR [r14+88] + mov rax, QWORD PTR [rdx+96] + mov QWORD PTR [r12+88], r10 + adc rax, QWORD PTR [r14+96] + mov r9, QWORD PTR [rdx+104] + mov QWORD PTR [r12+96], rax + adc r9, QWORD PTR [r14+104] + mov r10, QWORD PTR [rdx+112] + mov QWORD PTR [r12+104], r9 + adc r10, QWORD PTR [r14+112] + mov rax, QWORD PTR [rdx+120] + mov QWORD PTR [r12+112], r10 + adc rax, QWORD PTR [r14+120] + mov r9, QWORD PTR [rdx+128] + mov QWORD PTR [r12+120], rax + adc r9, QWORD PTR [r14+128] + mov r10, QWORD PTR [rdx+136] + mov QWORD PTR [r12+128], r9 + adc r10, QWORD PTR [r14+136] + mov rax, QWORD PTR [rdx+144] + mov QWORD PTR [r12+136], r10 + adc rax, QWORD PTR [r14+144] + mov r9, QWORD PTR [rdx+152] + mov QWORD PTR [r12+144], rax + adc r9, QWORD PTR [r14+152] + mov r10, QWORD PTR [rdx+160] + mov QWORD PTR [r12+152], r9 + adc r10, QWORD PTR [r14+160] + mov rax, QWORD PTR [rdx+168] + mov QWORD PTR [r12+160], r10 + adc rax, QWORD PTR [r14+168] + mov r9, QWORD PTR [rdx+176] + mov QWORD PTR [r12+168], rax + adc r9, QWORD PTR [r14+176] + mov r10, QWORD PTR [rdx+184] + mov QWORD PTR [r12+176], r9 + adc r10, QWORD PTR [r14+184] + mov rax, QWORD PTR [rdx+192] + mov QWORD PTR [r12+184], r10 + adc rax, QWORD PTR [r14+192] + mov r9, QWORD PTR [rdx+200] + mov QWORD PTR [r12+192], rax + adc r9, QWORD PTR [r14+200] + mov r10, QWORD PTR [rdx+208] + mov QWORD PTR [r12+200], r9 + adc r10, QWORD PTR [r14+208] + mov rax, QWORD PTR [rdx+216] + mov QWORD PTR [r12+208], r10 + adc rax, QWORD PTR [r14+216] + mov r9, QWORD PTR [rdx+224] + mov QWORD PTR [r12+216], rax + adc r9, QWORD PTR [r14+224] + mov r10, QWORD PTR [rdx+232] + mov QWORD PTR [r12+224], r9 + adc r10, QWORD PTR [r14+232] + mov rax, QWORD PTR [rdx+240] + mov QWORD PTR [r12+232], r10 + adc rax, QWORD PTR [r14+240] + mov r9, QWORD PTR [rdx+248] + mov QWORD PTR [r12+240], rax + adc r9, QWORD PTR [r14+248] + mov QWORD PTR [r12+248], r9 + adc r15, 0 + mov QWORD PTR [rsp+1560], r15 + lea r13, QWORD PTR [rsp+1280] + lea r14, QWORD PTR [r8+256] + ; Add + mov rax, QWORD PTR [r8] + xor rdi, rdi + add rax, QWORD PTR [r14] + mov r9, QWORD PTR [r8+8] + mov QWORD PTR [r13], rax + adc r9, QWORD PTR [r14+8] + mov r10, QWORD PTR [r8+16] + mov QWORD PTR [r13+8], r9 + adc r10, QWORD PTR [r14+16] + mov rax, QWORD PTR [r8+24] + mov QWORD PTR [r13+16], r10 + adc rax, QWORD PTR [r14+24] + mov r9, QWORD PTR [r8+32] + mov QWORD PTR [r13+24], rax + adc r9, QWORD PTR [r14+32] + mov r10, QWORD PTR [r8+40] + mov QWORD PTR [r13+32], r9 + adc r10, QWORD PTR [r14+40] + mov rax, QWORD PTR [r8+48] + mov QWORD PTR [r13+40], r10 + adc rax, QWORD PTR [r14+48] + mov r9, QWORD PTR [r8+56] + mov QWORD PTR [r13+48], rax + adc r9, QWORD PTR [r14+56] + mov r10, QWORD PTR [r8+64] + mov QWORD PTR [r13+56], r9 + adc r10, QWORD PTR [r14+64] + mov rax, QWORD PTR [r8+72] + mov QWORD PTR [r13+64], r10 + adc rax, QWORD PTR [r14+72] + mov r9, QWORD PTR [r8+80] + mov QWORD PTR [r13+72], rax + adc r9, QWORD PTR [r14+80] + mov r10, QWORD PTR [r8+88] + mov QWORD PTR [r13+80], r9 + adc r10, QWORD PTR [r14+88] + mov rax, QWORD PTR [r8+96] + mov QWORD PTR [r13+88], r10 + adc rax, QWORD PTR [r14+96] + mov r9, QWORD PTR [r8+104] + mov QWORD PTR [r13+96], rax + adc r9, QWORD PTR [r14+104] + mov r10, QWORD PTR [r8+112] + mov QWORD PTR [r13+104], r9 + adc r10, QWORD PTR [r14+112] + mov rax, QWORD PTR [r8+120] + mov QWORD PTR [r13+112], r10 + adc rax, QWORD PTR [r14+120] + mov r9, QWORD PTR [r8+128] + mov QWORD PTR [r13+120], rax + adc r9, QWORD PTR [r14+128] + mov r10, QWORD PTR [r8+136] + mov QWORD PTR [r13+128], r9 + adc r10, QWORD PTR [r14+136] + mov rax, QWORD PTR [r8+144] + mov QWORD PTR [r13+136], r10 + adc rax, QWORD PTR [r14+144] + mov r9, QWORD PTR [r8+152] + mov QWORD PTR [r13+144], rax + adc r9, QWORD PTR [r14+152] + mov r10, QWORD PTR [r8+160] + mov QWORD PTR [r13+152], r9 + adc r10, QWORD PTR [r14+160] + mov rax, QWORD PTR [r8+168] + mov QWORD PTR [r13+160], r10 + adc rax, QWORD PTR [r14+168] + mov r9, QWORD PTR [r8+176] + mov QWORD PTR [r13+168], rax + adc r9, QWORD PTR [r14+176] + mov r10, QWORD PTR [r8+184] + mov QWORD PTR [r13+176], r9 + adc r10, QWORD PTR [r14+184] + mov rax, QWORD PTR [r8+192] + mov QWORD PTR [r13+184], r10 + adc rax, QWORD PTR [r14+192] + mov r9, QWORD PTR [r8+200] + mov QWORD PTR [r13+192], rax + adc r9, QWORD PTR [r14+200] + mov r10, QWORD PTR [r8+208] + mov QWORD PTR [r13+200], r9 + adc r10, QWORD PTR [r14+208] + mov rax, QWORD PTR [r8+216] + mov QWORD PTR [r13+208], r10 + adc rax, QWORD PTR [r14+216] + mov r9, QWORD PTR [r8+224] + mov QWORD PTR [r13+216], rax + adc r9, QWORD PTR [r14+224] + mov r10, QWORD PTR [r8+232] + mov QWORD PTR [r13+224], r9 + adc r10, QWORD PTR [r14+232] + mov rax, QWORD PTR [r8+240] + mov QWORD PTR [r13+232], r10 + adc rax, QWORD PTR [r14+240] + mov r9, QWORD PTR [r8+248] + mov QWORD PTR [r13+240], rax + adc r9, QWORD PTR [r14+248] + mov QWORD PTR [r13+248], r9 + adc rdi, 0 + mov QWORD PTR [rsp+1568], rdi + mov r8, r13 + mov rdx, r12 + mov rcx, rsp + call sp_2048_mul_avx2_32 + mov r8, QWORD PTR [rsp+1552] + mov rdx, QWORD PTR [rsp+1544] + lea rcx, QWORD PTR [rsp+512] + add r8, 256 + add rdx, 256 + call sp_2048_mul_avx2_32 + mov r8, QWORD PTR [rsp+1552] + mov rdx, QWORD PTR [rsp+1544] + mov rcx, QWORD PTR [rsp+1536] + call sp_2048_mul_avx2_32 +IFDEF _WIN64 + mov r8, QWORD PTR [rsp+1552] + mov rdx, QWORD PTR [rsp+1544] + mov rcx, QWORD PTR [rsp+1536] +ENDIF + mov r15, QWORD PTR [rsp+1560] + mov rdi, QWORD PTR [rsp+1568] + mov rsi, QWORD PTR [rsp+1536] + mov r11, r15 + lea r12, QWORD PTR [rsp+1024] + lea r13, QWORD PTR [rsp+1280] + and r11, rdi + neg r15 + neg rdi + add rsi, 512 + mov rax, QWORD PTR [r12] + mov r9, QWORD PTR [r13] + pext rax, rax, rdi + pext r9, r9, r15 + add rax, r9 + mov r9, QWORD PTR [r12+8] + mov r10, QWORD PTR [r13+8] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi], rax + adc r9, r10 + mov r10, QWORD PTR [r12+16] + mov rax, QWORD PTR [r13+16] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+8], r9 + adc r10, rax + mov rax, QWORD PTR [r12+24] + mov r9, QWORD PTR [r13+24] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+16], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+32] + mov r10, QWORD PTR [r13+32] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+24], rax + adc r9, r10 + mov r10, QWORD PTR [r12+40] + mov rax, QWORD PTR [r13+40] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+32], r9 + adc r10, rax + mov rax, QWORD PTR [r12+48] + mov r9, QWORD PTR [r13+48] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+40], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+56] + mov r10, QWORD PTR [r13+56] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+48], rax + adc r9, r10 + mov r10, QWORD PTR [r12+64] + mov rax, QWORD PTR [r13+64] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+56], r9 + adc r10, rax + mov rax, QWORD PTR [r12+72] + mov r9, QWORD PTR [r13+72] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+64], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+80] + mov r10, QWORD PTR [r13+80] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+72], rax + adc r9, r10 + mov r10, QWORD PTR [r12+88] + mov rax, QWORD PTR [r13+88] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+80], r9 + adc r10, rax + mov rax, QWORD PTR [r12+96] + mov r9, QWORD PTR [r13+96] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+88], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+104] + mov r10, QWORD PTR [r13+104] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+96], rax + adc r9, r10 + mov r10, QWORD PTR [r12+112] + mov rax, QWORD PTR [r13+112] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+104], r9 + adc r10, rax + mov rax, QWORD PTR [r12+120] + mov r9, QWORD PTR [r13+120] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+112], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+128] + mov r10, QWORD PTR [r13+128] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+120], rax + adc r9, r10 + mov r10, QWORD PTR [r12+136] + mov rax, QWORD PTR [r13+136] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+128], r9 + adc r10, rax + mov rax, QWORD PTR [r12+144] + mov r9, QWORD PTR [r13+144] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+136], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+152] + mov r10, QWORD PTR [r13+152] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+144], rax + adc r9, r10 + mov r10, QWORD PTR [r12+160] + mov rax, QWORD PTR [r13+160] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+152], r9 + adc r10, rax + mov rax, QWORD PTR [r12+168] + mov r9, QWORD PTR [r13+168] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+160], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+176] + mov r10, QWORD PTR [r13+176] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+168], rax + adc r9, r10 + mov r10, QWORD PTR [r12+184] + mov rax, QWORD PTR [r13+184] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+176], r9 + adc r10, rax + mov rax, QWORD PTR [r12+192] + mov r9, QWORD PTR [r13+192] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+184], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+200] + mov r10, QWORD PTR [r13+200] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+192], rax + adc r9, r10 + mov r10, QWORD PTR [r12+208] + mov rax, QWORD PTR [r13+208] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+200], r9 + adc r10, rax + mov rax, QWORD PTR [r12+216] + mov r9, QWORD PTR [r13+216] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+208], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+224] + mov r10, QWORD PTR [r13+224] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+216], rax + adc r9, r10 + mov r10, QWORD PTR [r12+232] + mov rax, QWORD PTR [r13+232] + pext r10, r10, rdi + pext rax, rax, r15 + mov QWORD PTR [rsi+224], r9 + adc r10, rax + mov rax, QWORD PTR [r12+240] + mov r9, QWORD PTR [r13+240] + pext rax, rax, rdi + pext r9, r9, r15 + mov QWORD PTR [rsi+232], r10 + adc rax, r9 + mov r9, QWORD PTR [r12+248] + mov r10, QWORD PTR [r13+248] + pext r9, r9, rdi + pext r10, r10, r15 + mov QWORD PTR [rsi+240], rax + adc r9, r10 + mov QWORD PTR [rsi+248], r9 + adc r11, 0 + lea r13, QWORD PTR [rsp+512] + mov r12, rsp + mov rax, QWORD PTR [r12] + sub rax, QWORD PTR [r13] + mov r9, QWORD PTR [r12+8] + mov QWORD PTR [r12], rax + sbb r9, QWORD PTR [r13+8] + mov r10, QWORD PTR [r12+16] + mov QWORD PTR [r12+8], r9 + sbb r10, QWORD PTR [r13+16] + mov rax, QWORD PTR [r12+24] + mov QWORD PTR [r12+16], r10 + sbb rax, QWORD PTR [r13+24] + mov r9, QWORD PTR [r12+32] + mov QWORD PTR [r12+24], rax + sbb r9, QWORD PTR [r13+32] + mov r10, QWORD PTR [r12+40] + mov QWORD PTR [r12+32], r9 + sbb r10, QWORD PTR [r13+40] + mov rax, QWORD PTR [r12+48] + mov QWORD PTR [r12+40], r10 + sbb rax, QWORD PTR [r13+48] + mov r9, QWORD PTR [r12+56] + mov QWORD PTR [r12+48], rax + sbb r9, QWORD PTR [r13+56] + mov r10, QWORD PTR [r12+64] + mov QWORD PTR [r12+56], r9 + sbb r10, QWORD PTR [r13+64] + mov rax, QWORD PTR [r12+72] + mov QWORD PTR [r12+64], r10 + sbb rax, QWORD PTR [r13+72] + mov r9, QWORD PTR [r12+80] + mov QWORD PTR [r12+72], rax + sbb r9, QWORD PTR [r13+80] + mov r10, QWORD PTR [r12+88] + mov QWORD PTR [r12+80], r9 + sbb r10, QWORD PTR [r13+88] + mov rax, QWORD PTR [r12+96] + mov QWORD PTR [r12+88], r10 + sbb rax, QWORD PTR [r13+96] + mov r9, QWORD PTR [r12+104] + mov QWORD PTR [r12+96], rax + sbb r9, QWORD PTR [r13+104] + mov r10, QWORD PTR [r12+112] + mov QWORD PTR [r12+104], r9 + sbb r10, QWORD PTR [r13+112] + mov rax, QWORD PTR [r12+120] + mov QWORD PTR [r12+112], r10 + sbb rax, QWORD PTR [r13+120] + mov r9, QWORD PTR [r12+128] + mov QWORD PTR [r12+120], rax + sbb r9, QWORD PTR [r13+128] + mov r10, QWORD PTR [r12+136] + mov QWORD PTR [r12+128], r9 + sbb r10, QWORD PTR [r13+136] + mov rax, QWORD PTR [r12+144] + mov QWORD PTR [r12+136], r10 + sbb rax, QWORD PTR [r13+144] + mov r9, QWORD PTR [r12+152] + mov QWORD PTR [r12+144], rax + sbb r9, QWORD PTR [r13+152] + mov r10, QWORD PTR [r12+160] + mov QWORD PTR [r12+152], r9 + sbb r10, QWORD PTR [r13+160] + mov rax, QWORD PTR [r12+168] + mov QWORD PTR [r12+160], r10 + sbb rax, QWORD PTR [r13+168] + mov r9, QWORD PTR [r12+176] + mov QWORD PTR [r12+168], rax + sbb r9, QWORD PTR [r13+176] + mov r10, QWORD PTR [r12+184] + mov QWORD PTR [r12+176], r9 + sbb r10, QWORD PTR [r13+184] + mov rax, QWORD PTR [r12+192] + mov QWORD PTR [r12+184], r10 + sbb rax, QWORD PTR [r13+192] + mov r9, QWORD PTR [r12+200] + mov QWORD PTR [r12+192], rax + sbb r9, QWORD PTR [r13+200] + mov r10, QWORD PTR [r12+208] + mov QWORD PTR [r12+200], r9 + sbb r10, QWORD PTR [r13+208] + mov rax, QWORD PTR [r12+216] + mov QWORD PTR [r12+208], r10 + sbb rax, QWORD PTR [r13+216] + mov r9, QWORD PTR [r12+224] + mov QWORD PTR [r12+216], rax + sbb r9, QWORD PTR [r13+224] + mov r10, QWORD PTR [r12+232] + mov QWORD PTR [r12+224], r9 + sbb r10, QWORD PTR [r13+232] + mov rax, QWORD PTR [r12+240] + mov QWORD PTR [r12+232], r10 + sbb rax, QWORD PTR [r13+240] + mov r9, QWORD PTR [r12+248] + mov QWORD PTR [r12+240], rax + sbb r9, QWORD PTR [r13+248] + mov r10, QWORD PTR [r12+256] + mov QWORD PTR [r12+248], r9 + sbb r10, QWORD PTR [r13+256] + mov rax, QWORD PTR [r12+264] + mov QWORD PTR [r12+256], r10 + sbb rax, QWORD PTR [r13+264] + mov r9, QWORD PTR [r12+272] + mov QWORD PTR [r12+264], rax + sbb r9, QWORD PTR [r13+272] + mov r10, QWORD PTR [r12+280] + mov QWORD PTR [r12+272], r9 + sbb r10, QWORD PTR [r13+280] + mov rax, QWORD PTR [r12+288] + mov QWORD PTR [r12+280], r10 + sbb rax, QWORD PTR [r13+288] + mov r9, QWORD PTR [r12+296] + mov QWORD PTR [r12+288], rax + sbb r9, QWORD PTR [r13+296] + mov r10, QWORD PTR [r12+304] + mov QWORD PTR [r12+296], r9 + sbb r10, QWORD PTR [r13+304] + mov rax, QWORD PTR [r12+312] + mov QWORD PTR [r12+304], r10 + sbb rax, QWORD PTR [r13+312] + mov r9, QWORD PTR [r12+320] + mov QWORD PTR [r12+312], rax + sbb r9, QWORD PTR [r13+320] + mov r10, QWORD PTR [r12+328] + mov QWORD PTR [r12+320], r9 + sbb r10, QWORD PTR [r13+328] + mov rax, QWORD PTR [r12+336] + mov QWORD PTR [r12+328], r10 + sbb rax, QWORD PTR [r13+336] + mov r9, QWORD PTR [r12+344] + mov QWORD PTR [r12+336], rax + sbb r9, QWORD PTR [r13+344] + mov r10, QWORD PTR [r12+352] + mov QWORD PTR [r12+344], r9 + sbb r10, QWORD PTR [r13+352] + mov rax, QWORD PTR [r12+360] + mov QWORD PTR [r12+352], r10 + sbb rax, QWORD PTR [r13+360] + mov r9, QWORD PTR [r12+368] + mov QWORD PTR [r12+360], rax + sbb r9, QWORD PTR [r13+368] + mov r10, QWORD PTR [r12+376] + mov QWORD PTR [r12+368], r9 + sbb r10, QWORD PTR [r13+376] + mov rax, QWORD PTR [r12+384] + mov QWORD PTR [r12+376], r10 + sbb rax, QWORD PTR [r13+384] + mov r9, QWORD PTR [r12+392] + mov QWORD PTR [r12+384], rax + sbb r9, QWORD PTR [r13+392] + mov r10, QWORD PTR [r12+400] + mov QWORD PTR [r12+392], r9 + sbb r10, QWORD PTR [r13+400] + mov rax, QWORD PTR [r12+408] + mov QWORD PTR [r12+400], r10 + sbb rax, QWORD PTR [r13+408] + mov r9, QWORD PTR [r12+416] + mov QWORD PTR [r12+408], rax + sbb r9, QWORD PTR [r13+416] + mov r10, QWORD PTR [r12+424] + mov QWORD PTR [r12+416], r9 + sbb r10, QWORD PTR [r13+424] + mov rax, QWORD PTR [r12+432] + mov QWORD PTR [r12+424], r10 + sbb rax, QWORD PTR [r13+432] + mov r9, QWORD PTR [r12+440] + mov QWORD PTR [r12+432], rax + sbb r9, QWORD PTR [r13+440] + mov r10, QWORD PTR [r12+448] + mov QWORD PTR [r12+440], r9 + sbb r10, QWORD PTR [r13+448] + mov rax, QWORD PTR [r12+456] + mov QWORD PTR [r12+448], r10 + sbb rax, QWORD PTR [r13+456] + mov r9, QWORD PTR [r12+464] + mov QWORD PTR [r12+456], rax + sbb r9, QWORD PTR [r13+464] + mov r10, QWORD PTR [r12+472] + mov QWORD PTR [r12+464], r9 + sbb r10, QWORD PTR [r13+472] + mov rax, QWORD PTR [r12+480] + mov QWORD PTR [r12+472], r10 + sbb rax, QWORD PTR [r13+480] + mov r9, QWORD PTR [r12+488] + mov QWORD PTR [r12+480], rax + sbb r9, QWORD PTR [r13+488] + mov r10, QWORD PTR [r12+496] + mov QWORD PTR [r12+488], r9 + sbb r10, QWORD PTR [r13+496] + mov rax, QWORD PTR [r12+504] + mov QWORD PTR [r12+496], r10 + sbb rax, QWORD PTR [r13+504] + mov QWORD PTR [r12+504], rax + sbb r11, 0 + mov rax, QWORD PTR [r12] + sub rax, QWORD PTR [rcx] + mov r9, QWORD PTR [r12+8] + mov QWORD PTR [r12], rax + sbb r9, QWORD PTR [rcx+8] + mov r10, QWORD PTR [r12+16] + mov QWORD PTR [r12+8], r9 + sbb r10, QWORD PTR [rcx+16] + mov rax, QWORD PTR [r12+24] + mov QWORD PTR [r12+16], r10 + sbb rax, QWORD PTR [rcx+24] + mov r9, QWORD PTR [r12+32] + mov QWORD PTR [r12+24], rax + sbb r9, QWORD PTR [rcx+32] + mov r10, QWORD PTR [r12+40] + mov QWORD PTR [r12+32], r9 + sbb r10, QWORD PTR [rcx+40] + mov rax, QWORD PTR [r12+48] + mov QWORD PTR [r12+40], r10 + sbb rax, QWORD PTR [rcx+48] + mov r9, QWORD PTR [r12+56] + mov QWORD PTR [r12+48], rax + sbb r9, QWORD PTR [rcx+56] + mov r10, QWORD PTR [r12+64] + mov QWORD PTR [r12+56], r9 + sbb r10, QWORD PTR [rcx+64] + mov rax, QWORD PTR [r12+72] + mov QWORD PTR [r12+64], r10 + sbb rax, QWORD PTR [rcx+72] + mov r9, QWORD PTR [r12+80] + mov QWORD PTR [r12+72], rax + sbb r9, QWORD PTR [rcx+80] + mov r10, QWORD PTR [r12+88] + mov QWORD PTR [r12+80], r9 + sbb r10, QWORD PTR [rcx+88] + mov rax, QWORD PTR [r12+96] + mov QWORD PTR [r12+88], r10 + sbb rax, QWORD PTR [rcx+96] + mov r9, QWORD PTR [r12+104] + mov QWORD PTR [r12+96], rax + sbb r9, QWORD PTR [rcx+104] + mov r10, QWORD PTR [r12+112] + mov QWORD PTR [r12+104], r9 + sbb r10, QWORD PTR [rcx+112] + mov rax, QWORD PTR [r12+120] + mov QWORD PTR [r12+112], r10 + sbb rax, QWORD PTR [rcx+120] + mov r9, QWORD PTR [r12+128] + mov QWORD PTR [r12+120], rax + sbb r9, QWORD PTR [rcx+128] + mov r10, QWORD PTR [r12+136] + mov QWORD PTR [r12+128], r9 + sbb r10, QWORD PTR [rcx+136] + mov rax, QWORD PTR [r12+144] + mov QWORD PTR [r12+136], r10 + sbb rax, QWORD PTR [rcx+144] + mov r9, QWORD PTR [r12+152] + mov QWORD PTR [r12+144], rax + sbb r9, QWORD PTR [rcx+152] + mov r10, QWORD PTR [r12+160] + mov QWORD PTR [r12+152], r9 + sbb r10, QWORD PTR [rcx+160] + mov rax, QWORD PTR [r12+168] + mov QWORD PTR [r12+160], r10 + sbb rax, QWORD PTR [rcx+168] + mov r9, QWORD PTR [r12+176] + mov QWORD PTR [r12+168], rax + sbb r9, QWORD PTR [rcx+176] + mov r10, QWORD PTR [r12+184] + mov QWORD PTR [r12+176], r9 + sbb r10, QWORD PTR [rcx+184] + mov rax, QWORD PTR [r12+192] + mov QWORD PTR [r12+184], r10 + sbb rax, QWORD PTR [rcx+192] + mov r9, QWORD PTR [r12+200] + mov QWORD PTR [r12+192], rax + sbb r9, QWORD PTR [rcx+200] + mov r10, QWORD PTR [r12+208] + mov QWORD PTR [r12+200], r9 + sbb r10, QWORD PTR [rcx+208] + mov rax, QWORD PTR [r12+216] + mov QWORD PTR [r12+208], r10 + sbb rax, QWORD PTR [rcx+216] + mov r9, QWORD PTR [r12+224] + mov QWORD PTR [r12+216], rax + sbb r9, QWORD PTR [rcx+224] + mov r10, QWORD PTR [r12+232] + mov QWORD PTR [r12+224], r9 + sbb r10, QWORD PTR [rcx+232] + mov rax, QWORD PTR [r12+240] + mov QWORD PTR [r12+232], r10 + sbb rax, QWORD PTR [rcx+240] + mov r9, QWORD PTR [r12+248] + mov QWORD PTR [r12+240], rax + sbb r9, QWORD PTR [rcx+248] + mov r10, QWORD PTR [r12+256] + mov QWORD PTR [r12+248], r9 + sbb r10, QWORD PTR [rcx+256] + mov rax, QWORD PTR [r12+264] + mov QWORD PTR [r12+256], r10 + sbb rax, QWORD PTR [rcx+264] + mov r9, QWORD PTR [r12+272] + mov QWORD PTR [r12+264], rax + sbb r9, QWORD PTR [rcx+272] + mov r10, QWORD PTR [r12+280] + mov QWORD PTR [r12+272], r9 + sbb r10, QWORD PTR [rcx+280] + mov rax, QWORD PTR [r12+288] + mov QWORD PTR [r12+280], r10 + sbb rax, QWORD PTR [rcx+288] + mov r9, QWORD PTR [r12+296] + mov QWORD PTR [r12+288], rax + sbb r9, QWORD PTR [rcx+296] + mov r10, QWORD PTR [r12+304] + mov QWORD PTR [r12+296], r9 + sbb r10, QWORD PTR [rcx+304] + mov rax, QWORD PTR [r12+312] + mov QWORD PTR [r12+304], r10 + sbb rax, QWORD PTR [rcx+312] + mov r9, QWORD PTR [r12+320] + mov QWORD PTR [r12+312], rax + sbb r9, QWORD PTR [rcx+320] + mov r10, QWORD PTR [r12+328] + mov QWORD PTR [r12+320], r9 + sbb r10, QWORD PTR [rcx+328] + mov rax, QWORD PTR [r12+336] + mov QWORD PTR [r12+328], r10 + sbb rax, QWORD PTR [rcx+336] + mov r9, QWORD PTR [r12+344] + mov QWORD PTR [r12+336], rax + sbb r9, QWORD PTR [rcx+344] + mov r10, QWORD PTR [r12+352] + mov QWORD PTR [r12+344], r9 + sbb r10, QWORD PTR [rcx+352] + mov rax, QWORD PTR [r12+360] + mov QWORD PTR [r12+352], r10 + sbb rax, QWORD PTR [rcx+360] + mov r9, QWORD PTR [r12+368] + mov QWORD PTR [r12+360], rax + sbb r9, QWORD PTR [rcx+368] + mov r10, QWORD PTR [r12+376] + mov QWORD PTR [r12+368], r9 + sbb r10, QWORD PTR [rcx+376] + mov rax, QWORD PTR [r12+384] + mov QWORD PTR [r12+376], r10 + sbb rax, QWORD PTR [rcx+384] + mov r9, QWORD PTR [r12+392] + mov QWORD PTR [r12+384], rax + sbb r9, QWORD PTR [rcx+392] + mov r10, QWORD PTR [r12+400] + mov QWORD PTR [r12+392], r9 + sbb r10, QWORD PTR [rcx+400] + mov rax, QWORD PTR [r12+408] + mov QWORD PTR [r12+400], r10 + sbb rax, QWORD PTR [rcx+408] + mov r9, QWORD PTR [r12+416] + mov QWORD PTR [r12+408], rax + sbb r9, QWORD PTR [rcx+416] + mov r10, QWORD PTR [r12+424] + mov QWORD PTR [r12+416], r9 + sbb r10, QWORD PTR [rcx+424] + mov rax, QWORD PTR [r12+432] + mov QWORD PTR [r12+424], r10 + sbb rax, QWORD PTR [rcx+432] + mov r9, QWORD PTR [r12+440] + mov QWORD PTR [r12+432], rax + sbb r9, QWORD PTR [rcx+440] + mov r10, QWORD PTR [r12+448] + mov QWORD PTR [r12+440], r9 + sbb r10, QWORD PTR [rcx+448] + mov rax, QWORD PTR [r12+456] + mov QWORD PTR [r12+448], r10 + sbb rax, QWORD PTR [rcx+456] + mov r9, QWORD PTR [r12+464] + mov QWORD PTR [r12+456], rax + sbb r9, QWORD PTR [rcx+464] + mov r10, QWORD PTR [r12+472] + mov QWORD PTR [r12+464], r9 + sbb r10, QWORD PTR [rcx+472] + mov rax, QWORD PTR [r12+480] + mov QWORD PTR [r12+472], r10 + sbb rax, QWORD PTR [rcx+480] + mov r9, QWORD PTR [r12+488] + mov QWORD PTR [r12+480], rax + sbb r9, QWORD PTR [rcx+488] + mov r10, QWORD PTR [r12+496] + mov QWORD PTR [r12+488], r9 + sbb r10, QWORD PTR [rcx+496] + mov rax, QWORD PTR [r12+504] + mov QWORD PTR [r12+496], r10 + sbb rax, QWORD PTR [rcx+504] + mov QWORD PTR [r12+504], rax + sbb r11, 0 + sub rsi, 256 + ; Add + mov rax, QWORD PTR [rsi] + add rax, QWORD PTR [r12] + mov r9, QWORD PTR [rsi+8] + mov QWORD PTR [rsi], rax + adc r9, QWORD PTR [r12+8] + mov r10, QWORD PTR [rsi+16] + mov QWORD PTR [rsi+8], r9 + adc r10, QWORD PTR [r12+16] + mov rax, QWORD PTR [rsi+24] + mov QWORD PTR [rsi+16], r10 + adc rax, QWORD PTR [r12+24] + mov r9, QWORD PTR [rsi+32] + mov QWORD PTR [rsi+24], rax + adc r9, QWORD PTR [r12+32] + mov r10, QWORD PTR [rsi+40] + mov QWORD PTR [rsi+32], r9 + adc r10, QWORD PTR [r12+40] + mov rax, QWORD PTR [rsi+48] + mov QWORD PTR [rsi+40], r10 + adc rax, QWORD PTR [r12+48] + mov r9, QWORD PTR [rsi+56] + mov QWORD PTR [rsi+48], rax + adc r9, QWORD PTR [r12+56] + mov r10, QWORD PTR [rsi+64] + mov QWORD PTR [rsi+56], r9 + adc r10, QWORD PTR [r12+64] + mov rax, QWORD PTR [rsi+72] + mov QWORD PTR [rsi+64], r10 + adc rax, QWORD PTR [r12+72] + mov r9, QWORD PTR [rsi+80] + mov QWORD PTR [rsi+72], rax + adc r9, QWORD PTR [r12+80] + mov r10, QWORD PTR [rsi+88] + mov QWORD PTR [rsi+80], r9 + adc r10, QWORD PTR [r12+88] + mov rax, QWORD PTR [rsi+96] + mov QWORD PTR [rsi+88], r10 + adc rax, QWORD PTR [r12+96] + mov r9, QWORD PTR [rsi+104] + mov QWORD PTR [rsi+96], rax + adc r9, QWORD PTR [r12+104] + mov r10, QWORD PTR [rsi+112] + mov QWORD PTR [rsi+104], r9 + adc r10, QWORD PTR [r12+112] + mov rax, QWORD PTR [rsi+120] + mov QWORD PTR [rsi+112], r10 + adc rax, QWORD PTR [r12+120] + mov r9, QWORD PTR [rsi+128] + mov QWORD PTR [rsi+120], rax + adc r9, QWORD PTR [r12+128] + mov r10, QWORD PTR [rsi+136] + mov QWORD PTR [rsi+128], r9 + adc r10, QWORD PTR [r12+136] + mov rax, QWORD PTR [rsi+144] + mov QWORD PTR [rsi+136], r10 + adc rax, QWORD PTR [r12+144] + mov r9, QWORD PTR [rsi+152] + mov QWORD PTR [rsi+144], rax + adc r9, QWORD PTR [r12+152] + mov r10, QWORD PTR [rsi+160] + mov QWORD PTR [rsi+152], r9 + adc r10, QWORD PTR [r12+160] + mov rax, QWORD PTR [rsi+168] + mov QWORD PTR [rsi+160], r10 + adc rax, QWORD PTR [r12+168] + mov r9, QWORD PTR [rsi+176] + mov QWORD PTR [rsi+168], rax + adc r9, QWORD PTR [r12+176] + mov r10, QWORD PTR [rsi+184] + mov QWORD PTR [rsi+176], r9 + adc r10, QWORD PTR [r12+184] + mov rax, QWORD PTR [rsi+192] + mov QWORD PTR [rsi+184], r10 + adc rax, QWORD PTR [r12+192] + mov r9, QWORD PTR [rsi+200] + mov QWORD PTR [rsi+192], rax + adc r9, QWORD PTR [r12+200] + mov r10, QWORD PTR [rsi+208] + mov QWORD PTR [rsi+200], r9 + adc r10, QWORD PTR [r12+208] + mov rax, QWORD PTR [rsi+216] + mov QWORD PTR [rsi+208], r10 + adc rax, QWORD PTR [r12+216] + mov r9, QWORD PTR [rsi+224] + mov QWORD PTR [rsi+216], rax + adc r9, QWORD PTR [r12+224] + mov r10, QWORD PTR [rsi+232] + mov QWORD PTR [rsi+224], r9 + adc r10, QWORD PTR [r12+232] + mov rax, QWORD PTR [rsi+240] + mov QWORD PTR [rsi+232], r10 + adc rax, QWORD PTR [r12+240] + mov r9, QWORD PTR [rsi+248] + mov QWORD PTR [rsi+240], rax + adc r9, QWORD PTR [r12+248] + mov r10, QWORD PTR [rsi+256] + mov QWORD PTR [rsi+248], r9 + adc r10, QWORD PTR [r12+256] + mov rax, QWORD PTR [rsi+264] + mov QWORD PTR [rsi+256], r10 + adc rax, QWORD PTR [r12+264] + mov r9, QWORD PTR [rsi+272] + mov QWORD PTR [rsi+264], rax + adc r9, QWORD PTR [r12+272] + mov r10, QWORD PTR [rsi+280] + mov QWORD PTR [rsi+272], r9 + adc r10, QWORD PTR [r12+280] + mov rax, QWORD PTR [rsi+288] + mov QWORD PTR [rsi+280], r10 + adc rax, QWORD PTR [r12+288] + mov r9, QWORD PTR [rsi+296] + mov QWORD PTR [rsi+288], rax + adc r9, QWORD PTR [r12+296] + mov r10, QWORD PTR [rsi+304] + mov QWORD PTR [rsi+296], r9 + adc r10, QWORD PTR [r12+304] + mov rax, QWORD PTR [rsi+312] + mov QWORD PTR [rsi+304], r10 + adc rax, QWORD PTR [r12+312] + mov r9, QWORD PTR [rsi+320] + mov QWORD PTR [rsi+312], rax + adc r9, QWORD PTR [r12+320] + mov r10, QWORD PTR [rsi+328] + mov QWORD PTR [rsi+320], r9 + adc r10, QWORD PTR [r12+328] + mov rax, QWORD PTR [rsi+336] + mov QWORD PTR [rsi+328], r10 + adc rax, QWORD PTR [r12+336] + mov r9, QWORD PTR [rsi+344] + mov QWORD PTR [rsi+336], rax + adc r9, QWORD PTR [r12+344] + mov r10, QWORD PTR [rsi+352] + mov QWORD PTR [rsi+344], r9 + adc r10, QWORD PTR [r12+352] + mov rax, QWORD PTR [rsi+360] + mov QWORD PTR [rsi+352], r10 + adc rax, QWORD PTR [r12+360] + mov r9, QWORD PTR [rsi+368] + mov QWORD PTR [rsi+360], rax + adc r9, QWORD PTR [r12+368] + mov r10, QWORD PTR [rsi+376] + mov QWORD PTR [rsi+368], r9 + adc r10, QWORD PTR [r12+376] + mov rax, QWORD PTR [rsi+384] + mov QWORD PTR [rsi+376], r10 + adc rax, QWORD PTR [r12+384] + mov r9, QWORD PTR [rsi+392] + mov QWORD PTR [rsi+384], rax + adc r9, QWORD PTR [r12+392] + mov r10, QWORD PTR [rsi+400] + mov QWORD PTR [rsi+392], r9 + adc r10, QWORD PTR [r12+400] + mov rax, QWORD PTR [rsi+408] + mov QWORD PTR [rsi+400], r10 + adc rax, QWORD PTR [r12+408] + mov r9, QWORD PTR [rsi+416] + mov QWORD PTR [rsi+408], rax + adc r9, QWORD PTR [r12+416] + mov r10, QWORD PTR [rsi+424] + mov QWORD PTR [rsi+416], r9 + adc r10, QWORD PTR [r12+424] + mov rax, QWORD PTR [rsi+432] + mov QWORD PTR [rsi+424], r10 + adc rax, QWORD PTR [r12+432] + mov r9, QWORD PTR [rsi+440] + mov QWORD PTR [rsi+432], rax + adc r9, QWORD PTR [r12+440] + mov r10, QWORD PTR [rsi+448] + mov QWORD PTR [rsi+440], r9 + adc r10, QWORD PTR [r12+448] + mov rax, QWORD PTR [rsi+456] + mov QWORD PTR [rsi+448], r10 + adc rax, QWORD PTR [r12+456] + mov r9, QWORD PTR [rsi+464] + mov QWORD PTR [rsi+456], rax + adc r9, QWORD PTR [r12+464] + mov r10, QWORD PTR [rsi+472] + mov QWORD PTR [rsi+464], r9 + adc r10, QWORD PTR [r12+472] + mov rax, QWORD PTR [rsi+480] + mov QWORD PTR [rsi+472], r10 + adc rax, QWORD PTR [r12+480] + mov r9, QWORD PTR [rsi+488] + mov QWORD PTR [rsi+480], rax + adc r9, QWORD PTR [r12+488] + mov r10, QWORD PTR [rsi+496] + mov QWORD PTR [rsi+488], r9 + adc r10, QWORD PTR [r12+496] + mov rax, QWORD PTR [rsi+504] + mov QWORD PTR [rsi+496], r10 + adc rax, QWORD PTR [r12+504] + mov QWORD PTR [rsi+504], rax + adc r11, 0 + mov QWORD PTR [rcx+768], r11 + add rsi, 256 + ; Add + mov rax, QWORD PTR [rsi] + xor r11, r11 + add rax, QWORD PTR [r13] + mov r9, QWORD PTR [rsi+8] + mov QWORD PTR [rsi], rax + adc r9, QWORD PTR [r13+8] + mov r10, QWORD PTR [rsi+16] + mov QWORD PTR [rsi+8], r9 + adc r10, QWORD PTR [r13+16] + mov rax, QWORD PTR [rsi+24] + mov QWORD PTR [rsi+16], r10 + adc rax, QWORD PTR [r13+24] + mov r9, QWORD PTR [rsi+32] + mov QWORD PTR [rsi+24], rax + adc r9, QWORD PTR [r13+32] + mov r10, QWORD PTR [rsi+40] + mov QWORD PTR [rsi+32], r9 + adc r10, QWORD PTR [r13+40] + mov rax, QWORD PTR [rsi+48] + mov QWORD PTR [rsi+40], r10 + adc rax, QWORD PTR [r13+48] + mov r9, QWORD PTR [rsi+56] + mov QWORD PTR [rsi+48], rax + adc r9, QWORD PTR [r13+56] + mov r10, QWORD PTR [rsi+64] + mov QWORD PTR [rsi+56], r9 + adc r10, QWORD PTR [r13+64] + mov rax, QWORD PTR [rsi+72] + mov QWORD PTR [rsi+64], r10 + adc rax, QWORD PTR [r13+72] + mov r9, QWORD PTR [rsi+80] + mov QWORD PTR [rsi+72], rax + adc r9, QWORD PTR [r13+80] + mov r10, QWORD PTR [rsi+88] + mov QWORD PTR [rsi+80], r9 + adc r10, QWORD PTR [r13+88] + mov rax, QWORD PTR [rsi+96] + mov QWORD PTR [rsi+88], r10 + adc rax, QWORD PTR [r13+96] + mov r9, QWORD PTR [rsi+104] + mov QWORD PTR [rsi+96], rax + adc r9, QWORD PTR [r13+104] + mov r10, QWORD PTR [rsi+112] + mov QWORD PTR [rsi+104], r9 + adc r10, QWORD PTR [r13+112] + mov rax, QWORD PTR [rsi+120] + mov QWORD PTR [rsi+112], r10 + adc rax, QWORD PTR [r13+120] + mov r9, QWORD PTR [rsi+128] + mov QWORD PTR [rsi+120], rax + adc r9, QWORD PTR [r13+128] + mov r10, QWORD PTR [rsi+136] + mov QWORD PTR [rsi+128], r9 + adc r10, QWORD PTR [r13+136] + mov rax, QWORD PTR [rsi+144] + mov QWORD PTR [rsi+136], r10 + adc rax, QWORD PTR [r13+144] + mov r9, QWORD PTR [rsi+152] + mov QWORD PTR [rsi+144], rax + adc r9, QWORD PTR [r13+152] + mov r10, QWORD PTR [rsi+160] + mov QWORD PTR [rsi+152], r9 + adc r10, QWORD PTR [r13+160] + mov rax, QWORD PTR [rsi+168] + mov QWORD PTR [rsi+160], r10 + adc rax, QWORD PTR [r13+168] + mov r9, QWORD PTR [rsi+176] + mov QWORD PTR [rsi+168], rax + adc r9, QWORD PTR [r13+176] + mov r10, QWORD PTR [rsi+184] + mov QWORD PTR [rsi+176], r9 + adc r10, QWORD PTR [r13+184] + mov rax, QWORD PTR [rsi+192] + mov QWORD PTR [rsi+184], r10 + adc rax, QWORD PTR [r13+192] + mov r9, QWORD PTR [rsi+200] + mov QWORD PTR [rsi+192], rax + adc r9, QWORD PTR [r13+200] + mov r10, QWORD PTR [rsi+208] + mov QWORD PTR [rsi+200], r9 + adc r10, QWORD PTR [r13+208] + mov rax, QWORD PTR [rsi+216] + mov QWORD PTR [rsi+208], r10 + adc rax, QWORD PTR [r13+216] + mov r9, QWORD PTR [rsi+224] + mov QWORD PTR [rsi+216], rax + adc r9, QWORD PTR [r13+224] + mov r10, QWORD PTR [rsi+232] + mov QWORD PTR [rsi+224], r9 + adc r10, QWORD PTR [r13+232] + mov rax, QWORD PTR [rsi+240] + mov QWORD PTR [rsi+232], r10 + adc rax, QWORD PTR [r13+240] + mov r9, QWORD PTR [rsi+248] + mov QWORD PTR [rsi+240], rax + adc r9, QWORD PTR [r13+248] + mov r10, QWORD PTR [rsi+256] + mov QWORD PTR [rsi+248], r9 + adc r10, QWORD PTR [r13+256] + mov QWORD PTR [rsi+256], r10 + adc r11, 0 + ; Add to zero + mov rax, QWORD PTR [r13+264] + adc rax, 0 + mov r9, QWORD PTR [r13+272] + mov QWORD PTR [rsi+264], rax + adc r9, 0 + mov r10, QWORD PTR [r13+280] + mov QWORD PTR [rsi+272], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+288] + mov QWORD PTR [rsi+280], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+296] + mov QWORD PTR [rsi+288], rax + adc r9, 0 + mov r10, QWORD PTR [r13+304] + mov QWORD PTR [rsi+296], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+312] + mov QWORD PTR [rsi+304], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+320] + mov QWORD PTR [rsi+312], rax + adc r9, 0 + mov r10, QWORD PTR [r13+328] + mov QWORD PTR [rsi+320], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+336] + mov QWORD PTR [rsi+328], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+344] + mov QWORD PTR [rsi+336], rax + adc r9, 0 + mov r10, QWORD PTR [r13+352] + mov QWORD PTR [rsi+344], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+360] + mov QWORD PTR [rsi+352], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+368] + mov QWORD PTR [rsi+360], rax + adc r9, 0 + mov r10, QWORD PTR [r13+376] + mov QWORD PTR [rsi+368], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+384] + mov QWORD PTR [rsi+376], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+392] + mov QWORD PTR [rsi+384], rax + adc r9, 0 + mov r10, QWORD PTR [r13+400] + mov QWORD PTR [rsi+392], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+408] + mov QWORD PTR [rsi+400], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+416] + mov QWORD PTR [rsi+408], rax + adc r9, 0 + mov r10, QWORD PTR [r13+424] + mov QWORD PTR [rsi+416], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+432] + mov QWORD PTR [rsi+424], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+440] + mov QWORD PTR [rsi+432], rax + adc r9, 0 + mov r10, QWORD PTR [r13+448] + mov QWORD PTR [rsi+440], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+456] + mov QWORD PTR [rsi+448], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+464] + mov QWORD PTR [rsi+456], rax + adc r9, 0 + mov r10, QWORD PTR [r13+472] + mov QWORD PTR [rsi+464], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+480] + mov QWORD PTR [rsi+472], r10 + adc rax, 0 + mov r9, QWORD PTR [r13+488] + mov QWORD PTR [rsi+480], rax + adc r9, 0 + mov r10, QWORD PTR [r13+496] + mov QWORD PTR [rsi+488], r9 + adc r10, 0 + mov rax, QWORD PTR [r13+504] + mov QWORD PTR [rsi+496], r10 + adc rax, 0 + mov QWORD PTR [rsi+504], rax + add rsp, 1576 + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_4096_mul_avx2_64 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Square a and put result in r. (r = a * a) +; * +; * r A single precision integer. +; * a A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_4096_sqr_avx2_64 PROC + push r12 + sub rsp, 1304 + mov QWORD PTR [rsp+1280], rcx + mov QWORD PTR [rsp+1288], rdx + lea r10, QWORD PTR [rsp+1024] + lea r11, QWORD PTR [rdx+256] + ; Add + mov rax, QWORD PTR [rdx] + xor r9, r9 + add rax, QWORD PTR [r11] + mov r8, QWORD PTR [rdx+8] + mov QWORD PTR [r10], rax + adc r8, QWORD PTR [r11+8] + mov rax, QWORD PTR [rdx+16] + mov QWORD PTR [r10+8], r8 + adc rax, QWORD PTR [r11+16] + mov r8, QWORD PTR [rdx+24] + mov QWORD PTR [r10+16], rax + adc r8, QWORD PTR [r11+24] + mov rax, QWORD PTR [rdx+32] + mov QWORD PTR [r10+24], r8 + adc rax, QWORD PTR [r11+32] + mov r8, QWORD PTR [rdx+40] + mov QWORD PTR [r10+32], rax + adc r8, QWORD PTR [r11+40] + mov rax, QWORD PTR [rdx+48] + mov QWORD PTR [r10+40], r8 + adc rax, QWORD PTR [r11+48] + mov r8, QWORD PTR [rdx+56] + mov QWORD PTR [r10+48], rax + adc r8, QWORD PTR [r11+56] + mov rax, QWORD PTR [rdx+64] + mov QWORD PTR [r10+56], r8 + adc rax, QWORD PTR [r11+64] + mov r8, QWORD PTR [rdx+72] + mov QWORD PTR [r10+64], rax + adc r8, QWORD PTR [r11+72] + mov rax, QWORD PTR [rdx+80] + mov QWORD PTR [r10+72], r8 + adc rax, QWORD PTR [r11+80] + mov r8, QWORD PTR [rdx+88] + mov QWORD PTR [r10+80], rax + adc r8, QWORD PTR [r11+88] + mov rax, QWORD PTR [rdx+96] + mov QWORD PTR [r10+88], r8 + adc rax, QWORD PTR [r11+96] + mov r8, QWORD PTR [rdx+104] + mov QWORD PTR [r10+96], rax + adc r8, QWORD PTR [r11+104] + mov rax, QWORD PTR [rdx+112] + mov QWORD PTR [r10+104], r8 + adc rax, QWORD PTR [r11+112] + mov r8, QWORD PTR [rdx+120] + mov QWORD PTR [r10+112], rax + adc r8, QWORD PTR [r11+120] + mov rax, QWORD PTR [rdx+128] + mov QWORD PTR [r10+120], r8 + adc rax, QWORD PTR [r11+128] + mov r8, QWORD PTR [rdx+136] + mov QWORD PTR [r10+128], rax + adc r8, QWORD PTR [r11+136] + mov rax, QWORD PTR [rdx+144] + mov QWORD PTR [r10+136], r8 + adc rax, QWORD PTR [r11+144] + mov r8, QWORD PTR [rdx+152] + mov QWORD PTR [r10+144], rax + adc r8, QWORD PTR [r11+152] + mov rax, QWORD PTR [rdx+160] + mov QWORD PTR [r10+152], r8 + adc rax, QWORD PTR [r11+160] + mov r8, QWORD PTR [rdx+168] + mov QWORD PTR [r10+160], rax + adc r8, QWORD PTR [r11+168] + mov rax, QWORD PTR [rdx+176] + mov QWORD PTR [r10+168], r8 + adc rax, QWORD PTR [r11+176] + mov r8, QWORD PTR [rdx+184] + mov QWORD PTR [r10+176], rax + adc r8, QWORD PTR [r11+184] + mov rax, QWORD PTR [rdx+192] + mov QWORD PTR [r10+184], r8 + adc rax, QWORD PTR [r11+192] + mov r8, QWORD PTR [rdx+200] + mov QWORD PTR [r10+192], rax + adc r8, QWORD PTR [r11+200] + mov rax, QWORD PTR [rdx+208] + mov QWORD PTR [r10+200], r8 + adc rax, QWORD PTR [r11+208] + mov r8, QWORD PTR [rdx+216] + mov QWORD PTR [r10+208], rax + adc r8, QWORD PTR [r11+216] + mov rax, QWORD PTR [rdx+224] + mov QWORD PTR [r10+216], r8 + adc rax, QWORD PTR [r11+224] + mov r8, QWORD PTR [rdx+232] + mov QWORD PTR [r10+224], rax + adc r8, QWORD PTR [r11+232] + mov rax, QWORD PTR [rdx+240] + mov QWORD PTR [r10+232], r8 + adc rax, QWORD PTR [r11+240] + mov r8, QWORD PTR [rdx+248] + mov QWORD PTR [r10+240], rax + adc r8, QWORD PTR [r11+248] + mov QWORD PTR [r10+248], r8 + adc r9, 0 + mov QWORD PTR [rsp+1296], r9 + mov rdx, r10 + mov rcx, rsp + call sp_2048_sqr_avx2_32 + mov rdx, QWORD PTR [rsp+1288] + lea rcx, QWORD PTR [rsp+512] + add rdx, 256 + call sp_2048_sqr_avx2_32 + mov rdx, QWORD PTR [rsp+1288] + mov rcx, QWORD PTR [rsp+1280] + call sp_2048_sqr_avx2_32 +IFDEF _WIN64 + mov rdx, QWORD PTR [rsp+1288] + mov rcx, QWORD PTR [rsp+1280] +ENDIF + mov r12, QWORD PTR [rsp+1296] + lea r10, QWORD PTR [rsp+1024] + mov r9, r12 + neg r12 + mov rax, QWORD PTR [r10] + pext rax, rax, r12 + add rax, rax + mov r8, QWORD PTR [r10+8] + mov QWORD PTR [rcx+512], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+16] + mov QWORD PTR [rcx+520], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+24] + mov QWORD PTR [rcx+528], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+32] + mov QWORD PTR [rcx+536], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+40] + mov QWORD PTR [rcx+544], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+48] + mov QWORD PTR [rcx+552], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+56] + mov QWORD PTR [rcx+560], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+64] + mov QWORD PTR [rcx+568], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+72] + mov QWORD PTR [rcx+576], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+80] + mov QWORD PTR [rcx+584], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+88] + mov QWORD PTR [rcx+592], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+96] + mov QWORD PTR [rcx+600], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+104] + mov QWORD PTR [rcx+608], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+112] + mov QWORD PTR [rcx+616], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+120] + mov QWORD PTR [rcx+624], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+128] + mov QWORD PTR [rcx+632], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+136] + mov QWORD PTR [rcx+640], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+144] + mov QWORD PTR [rcx+648], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+152] + mov QWORD PTR [rcx+656], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+160] + mov QWORD PTR [rcx+664], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+168] + mov QWORD PTR [rcx+672], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+176] + mov QWORD PTR [rcx+680], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+184] + mov QWORD PTR [rcx+688], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+192] + mov QWORD PTR [rcx+696], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+200] + mov QWORD PTR [rcx+704], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+208] + mov QWORD PTR [rcx+712], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+216] + mov QWORD PTR [rcx+720], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+224] + mov QWORD PTR [rcx+728], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+232] + mov QWORD PTR [rcx+736], rax + pext r8, r8, r12 + adc r8, r8 + mov rax, QWORD PTR [r10+240] + mov QWORD PTR [rcx+744], r8 + pext rax, rax, r12 + adc rax, rax + mov r8, QWORD PTR [r10+248] + mov QWORD PTR [rcx+752], rax + pext r8, r8, r12 + adc r8, r8 + mov QWORD PTR [rcx+760], r8 + adc r9, 0 + lea rdx, QWORD PTR [rsp+512] + mov r10, rsp + mov rax, QWORD PTR [r10] + sub rax, QWORD PTR [rdx] + mov r8, QWORD PTR [r10+8] + mov QWORD PTR [r10], rax + sbb r8, QWORD PTR [rdx+8] + mov rax, QWORD PTR [r10+16] + mov QWORD PTR [r10+8], r8 + sbb rax, QWORD PTR [rdx+16] + mov r8, QWORD PTR [r10+24] + mov QWORD PTR [r10+16], rax + sbb r8, QWORD PTR [rdx+24] + mov rax, QWORD PTR [r10+32] + mov QWORD PTR [r10+24], r8 + sbb rax, QWORD PTR [rdx+32] + mov r8, QWORD PTR [r10+40] + mov QWORD PTR [r10+32], rax + sbb r8, QWORD PTR [rdx+40] + mov rax, QWORD PTR [r10+48] + mov QWORD PTR [r10+40], r8 + sbb rax, QWORD PTR [rdx+48] + mov r8, QWORD PTR [r10+56] + mov QWORD PTR [r10+48], rax + sbb r8, QWORD PTR [rdx+56] + mov rax, QWORD PTR [r10+64] + mov QWORD PTR [r10+56], r8 + sbb rax, QWORD PTR [rdx+64] + mov r8, QWORD PTR [r10+72] + mov QWORD PTR [r10+64], rax + sbb r8, QWORD PTR [rdx+72] + mov rax, QWORD PTR [r10+80] + mov QWORD PTR [r10+72], r8 + sbb rax, QWORD PTR [rdx+80] + mov r8, QWORD PTR [r10+88] + mov QWORD PTR [r10+80], rax + sbb r8, QWORD PTR [rdx+88] + mov rax, QWORD PTR [r10+96] + mov QWORD PTR [r10+88], r8 + sbb rax, QWORD PTR [rdx+96] + mov r8, QWORD PTR [r10+104] + mov QWORD PTR [r10+96], rax + sbb r8, QWORD PTR [rdx+104] + mov rax, QWORD PTR [r10+112] + mov QWORD PTR [r10+104], r8 + sbb rax, QWORD PTR [rdx+112] + mov r8, QWORD PTR [r10+120] + mov QWORD PTR [r10+112], rax + sbb r8, QWORD PTR [rdx+120] + mov rax, QWORD PTR [r10+128] + mov QWORD PTR [r10+120], r8 + sbb rax, QWORD PTR [rdx+128] + mov r8, QWORD PTR [r10+136] + mov QWORD PTR [r10+128], rax + sbb r8, QWORD PTR [rdx+136] + mov rax, QWORD PTR [r10+144] + mov QWORD PTR [r10+136], r8 + sbb rax, QWORD PTR [rdx+144] + mov r8, QWORD PTR [r10+152] + mov QWORD PTR [r10+144], rax + sbb r8, QWORD PTR [rdx+152] + mov rax, QWORD PTR [r10+160] + mov QWORD PTR [r10+152], r8 + sbb rax, QWORD PTR [rdx+160] + mov r8, QWORD PTR [r10+168] + mov QWORD PTR [r10+160], rax + sbb r8, QWORD PTR [rdx+168] + mov rax, QWORD PTR [r10+176] + mov QWORD PTR [r10+168], r8 + sbb rax, QWORD PTR [rdx+176] + mov r8, QWORD PTR [r10+184] + mov QWORD PTR [r10+176], rax + sbb r8, QWORD PTR [rdx+184] + mov rax, QWORD PTR [r10+192] + mov QWORD PTR [r10+184], r8 + sbb rax, QWORD PTR [rdx+192] + mov r8, QWORD PTR [r10+200] + mov QWORD PTR [r10+192], rax + sbb r8, QWORD PTR [rdx+200] + mov rax, QWORD PTR [r10+208] + mov QWORD PTR [r10+200], r8 + sbb rax, QWORD PTR [rdx+208] + mov r8, QWORD PTR [r10+216] + mov QWORD PTR [r10+208], rax + sbb r8, QWORD PTR [rdx+216] + mov rax, QWORD PTR [r10+224] + mov QWORD PTR [r10+216], r8 + sbb rax, QWORD PTR [rdx+224] + mov r8, QWORD PTR [r10+232] + mov QWORD PTR [r10+224], rax + sbb r8, QWORD PTR [rdx+232] + mov rax, QWORD PTR [r10+240] + mov QWORD PTR [r10+232], r8 + sbb rax, QWORD PTR [rdx+240] + mov r8, QWORD PTR [r10+248] + mov QWORD PTR [r10+240], rax + sbb r8, QWORD PTR [rdx+248] + mov rax, QWORD PTR [r10+256] + mov QWORD PTR [r10+248], r8 + sbb rax, QWORD PTR [rdx+256] + mov r8, QWORD PTR [r10+264] + mov QWORD PTR [r10+256], rax + sbb r8, QWORD PTR [rdx+264] + mov rax, QWORD PTR [r10+272] + mov QWORD PTR [r10+264], r8 + sbb rax, QWORD PTR [rdx+272] + mov r8, QWORD PTR [r10+280] + mov QWORD PTR [r10+272], rax + sbb r8, QWORD PTR [rdx+280] + mov rax, QWORD PTR [r10+288] + mov QWORD PTR [r10+280], r8 + sbb rax, QWORD PTR [rdx+288] + mov r8, QWORD PTR [r10+296] + mov QWORD PTR [r10+288], rax + sbb r8, QWORD PTR [rdx+296] + mov rax, QWORD PTR [r10+304] + mov QWORD PTR [r10+296], r8 + sbb rax, QWORD PTR [rdx+304] + mov r8, QWORD PTR [r10+312] + mov QWORD PTR [r10+304], rax + sbb r8, QWORD PTR [rdx+312] + mov rax, QWORD PTR [r10+320] + mov QWORD PTR [r10+312], r8 + sbb rax, QWORD PTR [rdx+320] + mov r8, QWORD PTR [r10+328] + mov QWORD PTR [r10+320], rax + sbb r8, QWORD PTR [rdx+328] + mov rax, QWORD PTR [r10+336] + mov QWORD PTR [r10+328], r8 + sbb rax, QWORD PTR [rdx+336] + mov r8, QWORD PTR [r10+344] + mov QWORD PTR [r10+336], rax + sbb r8, QWORD PTR [rdx+344] + mov rax, QWORD PTR [r10+352] + mov QWORD PTR [r10+344], r8 + sbb rax, QWORD PTR [rdx+352] + mov r8, QWORD PTR [r10+360] + mov QWORD PTR [r10+352], rax + sbb r8, QWORD PTR [rdx+360] + mov rax, QWORD PTR [r10+368] + mov QWORD PTR [r10+360], r8 + sbb rax, QWORD PTR [rdx+368] + mov r8, QWORD PTR [r10+376] + mov QWORD PTR [r10+368], rax + sbb r8, QWORD PTR [rdx+376] + mov rax, QWORD PTR [r10+384] + mov QWORD PTR [r10+376], r8 + sbb rax, QWORD PTR [rdx+384] + mov r8, QWORD PTR [r10+392] + mov QWORD PTR [r10+384], rax + sbb r8, QWORD PTR [rdx+392] + mov rax, QWORD PTR [r10+400] + mov QWORD PTR [r10+392], r8 + sbb rax, QWORD PTR [rdx+400] + mov r8, QWORD PTR [r10+408] + mov QWORD PTR [r10+400], rax + sbb r8, QWORD PTR [rdx+408] + mov rax, QWORD PTR [r10+416] + mov QWORD PTR [r10+408], r8 + sbb rax, QWORD PTR [rdx+416] + mov r8, QWORD PTR [r10+424] + mov QWORD PTR [r10+416], rax + sbb r8, QWORD PTR [rdx+424] + mov rax, QWORD PTR [r10+432] + mov QWORD PTR [r10+424], r8 + sbb rax, QWORD PTR [rdx+432] + mov r8, QWORD PTR [r10+440] + mov QWORD PTR [r10+432], rax + sbb r8, QWORD PTR [rdx+440] + mov rax, QWORD PTR [r10+448] + mov QWORD PTR [r10+440], r8 + sbb rax, QWORD PTR [rdx+448] + mov r8, QWORD PTR [r10+456] + mov QWORD PTR [r10+448], rax + sbb r8, QWORD PTR [rdx+456] + mov rax, QWORD PTR [r10+464] + mov QWORD PTR [r10+456], r8 + sbb rax, QWORD PTR [rdx+464] + mov r8, QWORD PTR [r10+472] + mov QWORD PTR [r10+464], rax + sbb r8, QWORD PTR [rdx+472] + mov rax, QWORD PTR [r10+480] + mov QWORD PTR [r10+472], r8 + sbb rax, QWORD PTR [rdx+480] + mov r8, QWORD PTR [r10+488] + mov QWORD PTR [r10+480], rax + sbb r8, QWORD PTR [rdx+488] + mov rax, QWORD PTR [r10+496] + mov QWORD PTR [r10+488], r8 + sbb rax, QWORD PTR [rdx+496] + mov r8, QWORD PTR [r10+504] + mov QWORD PTR [r10+496], rax + sbb r8, QWORD PTR [rdx+504] + mov QWORD PTR [r10+504], r8 + sbb r9, 0 + mov rax, QWORD PTR [r10] + sub rax, QWORD PTR [rcx] + mov r8, QWORD PTR [r10+8] + mov QWORD PTR [r10], rax + sbb r8, QWORD PTR [rcx+8] + mov rax, QWORD PTR [r10+16] + mov QWORD PTR [r10+8], r8 + sbb rax, QWORD PTR [rcx+16] + mov r8, QWORD PTR [r10+24] + mov QWORD PTR [r10+16], rax + sbb r8, QWORD PTR [rcx+24] + mov rax, QWORD PTR [r10+32] + mov QWORD PTR [r10+24], r8 + sbb rax, QWORD PTR [rcx+32] + mov r8, QWORD PTR [r10+40] + mov QWORD PTR [r10+32], rax + sbb r8, QWORD PTR [rcx+40] + mov rax, QWORD PTR [r10+48] + mov QWORD PTR [r10+40], r8 + sbb rax, QWORD PTR [rcx+48] + mov r8, QWORD PTR [r10+56] + mov QWORD PTR [r10+48], rax + sbb r8, QWORD PTR [rcx+56] + mov rax, QWORD PTR [r10+64] + mov QWORD PTR [r10+56], r8 + sbb rax, QWORD PTR [rcx+64] + mov r8, QWORD PTR [r10+72] + mov QWORD PTR [r10+64], rax + sbb r8, QWORD PTR [rcx+72] + mov rax, QWORD PTR [r10+80] + mov QWORD PTR [r10+72], r8 + sbb rax, QWORD PTR [rcx+80] + mov r8, QWORD PTR [r10+88] + mov QWORD PTR [r10+80], rax + sbb r8, QWORD PTR [rcx+88] + mov rax, QWORD PTR [r10+96] + mov QWORD PTR [r10+88], r8 + sbb rax, QWORD PTR [rcx+96] + mov r8, QWORD PTR [r10+104] + mov QWORD PTR [r10+96], rax + sbb r8, QWORD PTR [rcx+104] + mov rax, QWORD PTR [r10+112] + mov QWORD PTR [r10+104], r8 + sbb rax, QWORD PTR [rcx+112] + mov r8, QWORD PTR [r10+120] + mov QWORD PTR [r10+112], rax + sbb r8, QWORD PTR [rcx+120] + mov rax, QWORD PTR [r10+128] + mov QWORD PTR [r10+120], r8 + sbb rax, QWORD PTR [rcx+128] + mov r8, QWORD PTR [r10+136] + mov QWORD PTR [r10+128], rax + sbb r8, QWORD PTR [rcx+136] + mov rax, QWORD PTR [r10+144] + mov QWORD PTR [r10+136], r8 + sbb rax, QWORD PTR [rcx+144] + mov r8, QWORD PTR [r10+152] + mov QWORD PTR [r10+144], rax + sbb r8, QWORD PTR [rcx+152] + mov rax, QWORD PTR [r10+160] + mov QWORD PTR [r10+152], r8 + sbb rax, QWORD PTR [rcx+160] + mov r8, QWORD PTR [r10+168] + mov QWORD PTR [r10+160], rax + sbb r8, QWORD PTR [rcx+168] + mov rax, QWORD PTR [r10+176] + mov QWORD PTR [r10+168], r8 + sbb rax, QWORD PTR [rcx+176] + mov r8, QWORD PTR [r10+184] + mov QWORD PTR [r10+176], rax + sbb r8, QWORD PTR [rcx+184] + mov rax, QWORD PTR [r10+192] + mov QWORD PTR [r10+184], r8 + sbb rax, QWORD PTR [rcx+192] + mov r8, QWORD PTR [r10+200] + mov QWORD PTR [r10+192], rax + sbb r8, QWORD PTR [rcx+200] + mov rax, QWORD PTR [r10+208] + mov QWORD PTR [r10+200], r8 + sbb rax, QWORD PTR [rcx+208] + mov r8, QWORD PTR [r10+216] + mov QWORD PTR [r10+208], rax + sbb r8, QWORD PTR [rcx+216] + mov rax, QWORD PTR [r10+224] + mov QWORD PTR [r10+216], r8 + sbb rax, QWORD PTR [rcx+224] + mov r8, QWORD PTR [r10+232] + mov QWORD PTR [r10+224], rax + sbb r8, QWORD PTR [rcx+232] + mov rax, QWORD PTR [r10+240] + mov QWORD PTR [r10+232], r8 + sbb rax, QWORD PTR [rcx+240] + mov r8, QWORD PTR [r10+248] + mov QWORD PTR [r10+240], rax + sbb r8, QWORD PTR [rcx+248] + mov rax, QWORD PTR [r10+256] + mov QWORD PTR [r10+248], r8 + sbb rax, QWORD PTR [rcx+256] + mov r8, QWORD PTR [r10+264] + mov QWORD PTR [r10+256], rax + sbb r8, QWORD PTR [rcx+264] + mov rax, QWORD PTR [r10+272] + mov QWORD PTR [r10+264], r8 + sbb rax, QWORD PTR [rcx+272] + mov r8, QWORD PTR [r10+280] + mov QWORD PTR [r10+272], rax + sbb r8, QWORD PTR [rcx+280] + mov rax, QWORD PTR [r10+288] + mov QWORD PTR [r10+280], r8 + sbb rax, QWORD PTR [rcx+288] + mov r8, QWORD PTR [r10+296] + mov QWORD PTR [r10+288], rax + sbb r8, QWORD PTR [rcx+296] + mov rax, QWORD PTR [r10+304] + mov QWORD PTR [r10+296], r8 + sbb rax, QWORD PTR [rcx+304] + mov r8, QWORD PTR [r10+312] + mov QWORD PTR [r10+304], rax + sbb r8, QWORD PTR [rcx+312] + mov rax, QWORD PTR [r10+320] + mov QWORD PTR [r10+312], r8 + sbb rax, QWORD PTR [rcx+320] + mov r8, QWORD PTR [r10+328] + mov QWORD PTR [r10+320], rax + sbb r8, QWORD PTR [rcx+328] + mov rax, QWORD PTR [r10+336] + mov QWORD PTR [r10+328], r8 + sbb rax, QWORD PTR [rcx+336] + mov r8, QWORD PTR [r10+344] + mov QWORD PTR [r10+336], rax + sbb r8, QWORD PTR [rcx+344] + mov rax, QWORD PTR [r10+352] + mov QWORD PTR [r10+344], r8 + sbb rax, QWORD PTR [rcx+352] + mov r8, QWORD PTR [r10+360] + mov QWORD PTR [r10+352], rax + sbb r8, QWORD PTR [rcx+360] + mov rax, QWORD PTR [r10+368] + mov QWORD PTR [r10+360], r8 + sbb rax, QWORD PTR [rcx+368] + mov r8, QWORD PTR [r10+376] + mov QWORD PTR [r10+368], rax + sbb r8, QWORD PTR [rcx+376] + mov rax, QWORD PTR [r10+384] + mov QWORD PTR [r10+376], r8 + sbb rax, QWORD PTR [rcx+384] + mov r8, QWORD PTR [r10+392] + mov QWORD PTR [r10+384], rax + sbb r8, QWORD PTR [rcx+392] + mov rax, QWORD PTR [r10+400] + mov QWORD PTR [r10+392], r8 + sbb rax, QWORD PTR [rcx+400] + mov r8, QWORD PTR [r10+408] + mov QWORD PTR [r10+400], rax + sbb r8, QWORD PTR [rcx+408] + mov rax, QWORD PTR [r10+416] + mov QWORD PTR [r10+408], r8 + sbb rax, QWORD PTR [rcx+416] + mov r8, QWORD PTR [r10+424] + mov QWORD PTR [r10+416], rax + sbb r8, QWORD PTR [rcx+424] + mov rax, QWORD PTR [r10+432] + mov QWORD PTR [r10+424], r8 + sbb rax, QWORD PTR [rcx+432] + mov r8, QWORD PTR [r10+440] + mov QWORD PTR [r10+432], rax + sbb r8, QWORD PTR [rcx+440] + mov rax, QWORD PTR [r10+448] + mov QWORD PTR [r10+440], r8 + sbb rax, QWORD PTR [rcx+448] + mov r8, QWORD PTR [r10+456] + mov QWORD PTR [r10+448], rax + sbb r8, QWORD PTR [rcx+456] + mov rax, QWORD PTR [r10+464] + mov QWORD PTR [r10+456], r8 + sbb rax, QWORD PTR [rcx+464] + mov r8, QWORD PTR [r10+472] + mov QWORD PTR [r10+464], rax + sbb r8, QWORD PTR [rcx+472] + mov rax, QWORD PTR [r10+480] + mov QWORD PTR [r10+472], r8 + sbb rax, QWORD PTR [rcx+480] + mov r8, QWORD PTR [r10+488] + mov QWORD PTR [r10+480], rax + sbb r8, QWORD PTR [rcx+488] + mov rax, QWORD PTR [r10+496] + mov QWORD PTR [r10+488], r8 + sbb rax, QWORD PTR [rcx+496] + mov r8, QWORD PTR [r10+504] + mov QWORD PTR [r10+496], rax + sbb r8, QWORD PTR [rcx+504] + mov QWORD PTR [r10+504], r8 + sbb r9, 0 + ; Add in place + mov rax, QWORD PTR [rcx+256] + add rax, QWORD PTR [r10] + mov r8, QWORD PTR [rcx+264] + mov QWORD PTR [rcx+256], rax + adc r8, QWORD PTR [r10+8] + mov rax, QWORD PTR [rcx+272] + mov QWORD PTR [rcx+264], r8 + adc rax, QWORD PTR [r10+16] + mov r8, QWORD PTR [rcx+280] + mov QWORD PTR [rcx+272], rax + adc r8, QWORD PTR [r10+24] + mov rax, QWORD PTR [rcx+288] + mov QWORD PTR [rcx+280], r8 + adc rax, QWORD PTR [r10+32] + mov r8, QWORD PTR [rcx+296] + mov QWORD PTR [rcx+288], rax + adc r8, QWORD PTR [r10+40] + mov rax, QWORD PTR [rcx+304] + mov QWORD PTR [rcx+296], r8 + adc rax, QWORD PTR [r10+48] + mov r8, QWORD PTR [rcx+312] + mov QWORD PTR [rcx+304], rax + adc r8, QWORD PTR [r10+56] + mov rax, QWORD PTR [rcx+320] + mov QWORD PTR [rcx+312], r8 + adc rax, QWORD PTR [r10+64] + mov r8, QWORD PTR [rcx+328] + mov QWORD PTR [rcx+320], rax + adc r8, QWORD PTR [r10+72] + mov rax, QWORD PTR [rcx+336] + mov QWORD PTR [rcx+328], r8 + adc rax, QWORD PTR [r10+80] + mov r8, QWORD PTR [rcx+344] + mov QWORD PTR [rcx+336], rax + adc r8, QWORD PTR [r10+88] + mov rax, QWORD PTR [rcx+352] + mov QWORD PTR [rcx+344], r8 + adc rax, QWORD PTR [r10+96] + mov r8, QWORD PTR [rcx+360] + mov QWORD PTR [rcx+352], rax + adc r8, QWORD PTR [r10+104] + mov rax, QWORD PTR [rcx+368] + mov QWORD PTR [rcx+360], r8 + adc rax, QWORD PTR [r10+112] + mov r8, QWORD PTR [rcx+376] + mov QWORD PTR [rcx+368], rax + adc r8, QWORD PTR [r10+120] + mov rax, QWORD PTR [rcx+384] + mov QWORD PTR [rcx+376], r8 + adc rax, QWORD PTR [r10+128] + mov r8, QWORD PTR [rcx+392] + mov QWORD PTR [rcx+384], rax + adc r8, QWORD PTR [r10+136] + mov rax, QWORD PTR [rcx+400] + mov QWORD PTR [rcx+392], r8 + adc rax, QWORD PTR [r10+144] + mov r8, QWORD PTR [rcx+408] + mov QWORD PTR [rcx+400], rax + adc r8, QWORD PTR [r10+152] + mov rax, QWORD PTR [rcx+416] + mov QWORD PTR [rcx+408], r8 + adc rax, QWORD PTR [r10+160] + mov r8, QWORD PTR [rcx+424] + mov QWORD PTR [rcx+416], rax + adc r8, QWORD PTR [r10+168] + mov rax, QWORD PTR [rcx+432] + mov QWORD PTR [rcx+424], r8 + adc rax, QWORD PTR [r10+176] + mov r8, QWORD PTR [rcx+440] + mov QWORD PTR [rcx+432], rax + adc r8, QWORD PTR [r10+184] + mov rax, QWORD PTR [rcx+448] + mov QWORD PTR [rcx+440], r8 + adc rax, QWORD PTR [r10+192] + mov r8, QWORD PTR [rcx+456] + mov QWORD PTR [rcx+448], rax + adc r8, QWORD PTR [r10+200] + mov rax, QWORD PTR [rcx+464] + mov QWORD PTR [rcx+456], r8 + adc rax, QWORD PTR [r10+208] + mov r8, QWORD PTR [rcx+472] + mov QWORD PTR [rcx+464], rax + adc r8, QWORD PTR [r10+216] + mov rax, QWORD PTR [rcx+480] + mov QWORD PTR [rcx+472], r8 + adc rax, QWORD PTR [r10+224] + mov r8, QWORD PTR [rcx+488] + mov QWORD PTR [rcx+480], rax + adc r8, QWORD PTR [r10+232] + mov rax, QWORD PTR [rcx+496] + mov QWORD PTR [rcx+488], r8 + adc rax, QWORD PTR [r10+240] + mov r8, QWORD PTR [rcx+504] + mov QWORD PTR [rcx+496], rax + adc r8, QWORD PTR [r10+248] + mov rax, QWORD PTR [rcx+512] + mov QWORD PTR [rcx+504], r8 + adc rax, QWORD PTR [r10+256] + mov r8, QWORD PTR [rcx+520] + mov QWORD PTR [rcx+512], rax + adc r8, QWORD PTR [r10+264] + mov rax, QWORD PTR [rcx+528] + mov QWORD PTR [rcx+520], r8 + adc rax, QWORD PTR [r10+272] + mov r8, QWORD PTR [rcx+536] + mov QWORD PTR [rcx+528], rax + adc r8, QWORD PTR [r10+280] + mov rax, QWORD PTR [rcx+544] + mov QWORD PTR [rcx+536], r8 + adc rax, QWORD PTR [r10+288] + mov r8, QWORD PTR [rcx+552] + mov QWORD PTR [rcx+544], rax + adc r8, QWORD PTR [r10+296] + mov rax, QWORD PTR [rcx+560] + mov QWORD PTR [rcx+552], r8 + adc rax, QWORD PTR [r10+304] + mov r8, QWORD PTR [rcx+568] + mov QWORD PTR [rcx+560], rax + adc r8, QWORD PTR [r10+312] + mov rax, QWORD PTR [rcx+576] + mov QWORD PTR [rcx+568], r8 + adc rax, QWORD PTR [r10+320] + mov r8, QWORD PTR [rcx+584] + mov QWORD PTR [rcx+576], rax + adc r8, QWORD PTR [r10+328] + mov rax, QWORD PTR [rcx+592] + mov QWORD PTR [rcx+584], r8 + adc rax, QWORD PTR [r10+336] + mov r8, QWORD PTR [rcx+600] + mov QWORD PTR [rcx+592], rax + adc r8, QWORD PTR [r10+344] + mov rax, QWORD PTR [rcx+608] + mov QWORD PTR [rcx+600], r8 + adc rax, QWORD PTR [r10+352] + mov r8, QWORD PTR [rcx+616] + mov QWORD PTR [rcx+608], rax + adc r8, QWORD PTR [r10+360] + mov rax, QWORD PTR [rcx+624] + mov QWORD PTR [rcx+616], r8 + adc rax, QWORD PTR [r10+368] + mov r8, QWORD PTR [rcx+632] + mov QWORD PTR [rcx+624], rax + adc r8, QWORD PTR [r10+376] + mov rax, QWORD PTR [rcx+640] + mov QWORD PTR [rcx+632], r8 + adc rax, QWORD PTR [r10+384] + mov r8, QWORD PTR [rcx+648] + mov QWORD PTR [rcx+640], rax + adc r8, QWORD PTR [r10+392] + mov rax, QWORD PTR [rcx+656] + mov QWORD PTR [rcx+648], r8 + adc rax, QWORD PTR [r10+400] + mov r8, QWORD PTR [rcx+664] + mov QWORD PTR [rcx+656], rax + adc r8, QWORD PTR [r10+408] + mov rax, QWORD PTR [rcx+672] + mov QWORD PTR [rcx+664], r8 + adc rax, QWORD PTR [r10+416] + mov r8, QWORD PTR [rcx+680] + mov QWORD PTR [rcx+672], rax + adc r8, QWORD PTR [r10+424] + mov rax, QWORD PTR [rcx+688] + mov QWORD PTR [rcx+680], r8 + adc rax, QWORD PTR [r10+432] + mov r8, QWORD PTR [rcx+696] + mov QWORD PTR [rcx+688], rax + adc r8, QWORD PTR [r10+440] + mov rax, QWORD PTR [rcx+704] + mov QWORD PTR [rcx+696], r8 + adc rax, QWORD PTR [r10+448] + mov r8, QWORD PTR [rcx+712] + mov QWORD PTR [rcx+704], rax + adc r8, QWORD PTR [r10+456] + mov rax, QWORD PTR [rcx+720] + mov QWORD PTR [rcx+712], r8 + adc rax, QWORD PTR [r10+464] + mov r8, QWORD PTR [rcx+728] + mov QWORD PTR [rcx+720], rax + adc r8, QWORD PTR [r10+472] + mov rax, QWORD PTR [rcx+736] + mov QWORD PTR [rcx+728], r8 + adc rax, QWORD PTR [r10+480] + mov r8, QWORD PTR [rcx+744] + mov QWORD PTR [rcx+736], rax + adc r8, QWORD PTR [r10+488] + mov rax, QWORD PTR [rcx+752] + mov QWORD PTR [rcx+744], r8 + adc rax, QWORD PTR [r10+496] + mov r8, QWORD PTR [rcx+760] + mov QWORD PTR [rcx+752], rax + adc r8, QWORD PTR [r10+504] + mov QWORD PTR [rcx+760], r8 + adc r9, 0 + mov QWORD PTR [rcx+768], r9 + ; Add in place + mov rax, QWORD PTR [rcx+512] + xor r9, r9 + add rax, QWORD PTR [rdx] + mov r8, QWORD PTR [rcx+520] + mov QWORD PTR [rcx+512], rax + adc r8, QWORD PTR [rdx+8] + mov rax, QWORD PTR [rcx+528] + mov QWORD PTR [rcx+520], r8 + adc rax, QWORD PTR [rdx+16] + mov r8, QWORD PTR [rcx+536] + mov QWORD PTR [rcx+528], rax + adc r8, QWORD PTR [rdx+24] + mov rax, QWORD PTR [rcx+544] + mov QWORD PTR [rcx+536], r8 + adc rax, QWORD PTR [rdx+32] + mov r8, QWORD PTR [rcx+552] + mov QWORD PTR [rcx+544], rax + adc r8, QWORD PTR [rdx+40] + mov rax, QWORD PTR [rcx+560] + mov QWORD PTR [rcx+552], r8 + adc rax, QWORD PTR [rdx+48] + mov r8, QWORD PTR [rcx+568] + mov QWORD PTR [rcx+560], rax + adc r8, QWORD PTR [rdx+56] + mov rax, QWORD PTR [rcx+576] + mov QWORD PTR [rcx+568], r8 + adc rax, QWORD PTR [rdx+64] + mov r8, QWORD PTR [rcx+584] + mov QWORD PTR [rcx+576], rax + adc r8, QWORD PTR [rdx+72] + mov rax, QWORD PTR [rcx+592] + mov QWORD PTR [rcx+584], r8 + adc rax, QWORD PTR [rdx+80] + mov r8, QWORD PTR [rcx+600] + mov QWORD PTR [rcx+592], rax + adc r8, QWORD PTR [rdx+88] + mov rax, QWORD PTR [rcx+608] + mov QWORD PTR [rcx+600], r8 + adc rax, QWORD PTR [rdx+96] + mov r8, QWORD PTR [rcx+616] + mov QWORD PTR [rcx+608], rax + adc r8, QWORD PTR [rdx+104] + mov rax, QWORD PTR [rcx+624] + mov QWORD PTR [rcx+616], r8 + adc rax, QWORD PTR [rdx+112] + mov r8, QWORD PTR [rcx+632] + mov QWORD PTR [rcx+624], rax + adc r8, QWORD PTR [rdx+120] + mov rax, QWORD PTR [rcx+640] + mov QWORD PTR [rcx+632], r8 + adc rax, QWORD PTR [rdx+128] + mov r8, QWORD PTR [rcx+648] + mov QWORD PTR [rcx+640], rax + adc r8, QWORD PTR [rdx+136] + mov rax, QWORD PTR [rcx+656] + mov QWORD PTR [rcx+648], r8 + adc rax, QWORD PTR [rdx+144] + mov r8, QWORD PTR [rcx+664] + mov QWORD PTR [rcx+656], rax + adc r8, QWORD PTR [rdx+152] + mov rax, QWORD PTR [rcx+672] + mov QWORD PTR [rcx+664], r8 + adc rax, QWORD PTR [rdx+160] + mov r8, QWORD PTR [rcx+680] + mov QWORD PTR [rcx+672], rax + adc r8, QWORD PTR [rdx+168] + mov rax, QWORD PTR [rcx+688] + mov QWORD PTR [rcx+680], r8 + adc rax, QWORD PTR [rdx+176] + mov r8, QWORD PTR [rcx+696] + mov QWORD PTR [rcx+688], rax + adc r8, QWORD PTR [rdx+184] + mov rax, QWORD PTR [rcx+704] + mov QWORD PTR [rcx+696], r8 + adc rax, QWORD PTR [rdx+192] + mov r8, QWORD PTR [rcx+712] + mov QWORD PTR [rcx+704], rax + adc r8, QWORD PTR [rdx+200] + mov rax, QWORD PTR [rcx+720] + mov QWORD PTR [rcx+712], r8 + adc rax, QWORD PTR [rdx+208] + mov r8, QWORD PTR [rcx+728] + mov QWORD PTR [rcx+720], rax + adc r8, QWORD PTR [rdx+216] + mov rax, QWORD PTR [rcx+736] + mov QWORD PTR [rcx+728], r8 + adc rax, QWORD PTR [rdx+224] + mov r8, QWORD PTR [rcx+744] + mov QWORD PTR [rcx+736], rax + adc r8, QWORD PTR [rdx+232] + mov rax, QWORD PTR [rcx+752] + mov QWORD PTR [rcx+744], r8 + adc rax, QWORD PTR [rdx+240] + mov r8, QWORD PTR [rcx+760] + mov QWORD PTR [rcx+752], rax + adc r8, QWORD PTR [rdx+248] + mov rax, QWORD PTR [rcx+768] + mov QWORD PTR [rcx+760], r8 + adc rax, QWORD PTR [rdx+256] + mov QWORD PTR [rcx+768], rax + adc r9, 0 + ; Add to zero + mov rax, QWORD PTR [rdx+264] + adc rax, 0 + mov r8, QWORD PTR [rdx+272] + mov QWORD PTR [rcx+776], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+280] + mov QWORD PTR [rcx+784], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+288] + mov QWORD PTR [rcx+792], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+296] + mov QWORD PTR [rcx+800], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+304] + mov QWORD PTR [rcx+808], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+312] + mov QWORD PTR [rcx+816], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+320] + mov QWORD PTR [rcx+824], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+328] + mov QWORD PTR [rcx+832], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+336] + mov QWORD PTR [rcx+840], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+344] + mov QWORD PTR [rcx+848], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+352] + mov QWORD PTR [rcx+856], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+360] + mov QWORD PTR [rcx+864], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+368] + mov QWORD PTR [rcx+872], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+376] + mov QWORD PTR [rcx+880], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+384] + mov QWORD PTR [rcx+888], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+392] + mov QWORD PTR [rcx+896], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+400] + mov QWORD PTR [rcx+904], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+408] + mov QWORD PTR [rcx+912], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+416] + mov QWORD PTR [rcx+920], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+424] + mov QWORD PTR [rcx+928], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+432] + mov QWORD PTR [rcx+936], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+440] + mov QWORD PTR [rcx+944], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+448] + mov QWORD PTR [rcx+952], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+456] + mov QWORD PTR [rcx+960], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+464] + mov QWORD PTR [rcx+968], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+472] + mov QWORD PTR [rcx+976], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+480] + mov QWORD PTR [rcx+984], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+488] + mov QWORD PTR [rcx+992], r8 + adc rax, 0 + mov r8, QWORD PTR [rdx+496] + mov QWORD PTR [rcx+1000], rax + adc r8, 0 + mov rax, QWORD PTR [rdx+504] + mov QWORD PTR [rcx+1008], r8 + adc rax, 0 + mov QWORD PTR [rcx+1016], rax + add rsp, 1304 + pop r12 + ret +sp_4096_sqr_avx2_64 ENDP +_text ENDS +ENDIF +; /* Mul a by digit b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision digit. +; */ +_text SEGMENT READONLY PARA +sp_4096_mul_d_64 PROC + push r12 + mov r9, rdx + ; A[0] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9] + mov r10, rax + mov r11, rdx + mov QWORD PTR [rcx], r10 + ; A[1] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+8] + add r11, rax + mov QWORD PTR [rcx+8], r11 + adc r12, rdx + adc r10, 0 + ; A[2] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+16] + add r12, rax + mov QWORD PTR [rcx+16], r12 + adc r10, rdx + adc r11, 0 + ; A[3] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+24] + add r10, rax + mov QWORD PTR [rcx+24], r10 + adc r11, rdx + adc r12, 0 + ; A[4] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+32] + add r11, rax + mov QWORD PTR [rcx+32], r11 + adc r12, rdx + adc r10, 0 + ; A[5] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+40] + add r12, rax + mov QWORD PTR [rcx+40], r12 + adc r10, rdx + adc r11, 0 + ; A[6] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+48] + add r10, rax + mov QWORD PTR [rcx+48], r10 + adc r11, rdx + adc r12, 0 + ; A[7] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+56] + add r11, rax + mov QWORD PTR [rcx+56], r11 + adc r12, rdx + adc r10, 0 + ; A[8] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+64] + add r12, rax + mov QWORD PTR [rcx+64], r12 + adc r10, rdx + adc r11, 0 + ; A[9] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+72] + add r10, rax + mov QWORD PTR [rcx+72], r10 + adc r11, rdx + adc r12, 0 + ; A[10] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+80] + add r11, rax + mov QWORD PTR [rcx+80], r11 + adc r12, rdx + adc r10, 0 + ; A[11] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+88] + add r12, rax + mov QWORD PTR [rcx+88], r12 + adc r10, rdx + adc r11, 0 + ; A[12] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+96] + add r10, rax + mov QWORD PTR [rcx+96], r10 + adc r11, rdx + adc r12, 0 + ; A[13] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+104] + add r11, rax + mov QWORD PTR [rcx+104], r11 + adc r12, rdx + adc r10, 0 + ; A[14] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+112] + add r12, rax + mov QWORD PTR [rcx+112], r12 + adc r10, rdx + adc r11, 0 + ; A[15] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+120] + add r10, rax + mov QWORD PTR [rcx+120], r10 + adc r11, rdx + adc r12, 0 + ; A[16] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+128] + add r11, rax + mov QWORD PTR [rcx+128], r11 + adc r12, rdx + adc r10, 0 + ; A[17] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+136] + add r12, rax + mov QWORD PTR [rcx+136], r12 + adc r10, rdx + adc r11, 0 + ; A[18] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+144] + add r10, rax + mov QWORD PTR [rcx+144], r10 + adc r11, rdx + adc r12, 0 + ; A[19] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+152] + add r11, rax + mov QWORD PTR [rcx+152], r11 + adc r12, rdx + adc r10, 0 + ; A[20] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+160] + add r12, rax + mov QWORD PTR [rcx+160], r12 + adc r10, rdx + adc r11, 0 + ; A[21] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+168] + add r10, rax + mov QWORD PTR [rcx+168], r10 + adc r11, rdx + adc r12, 0 + ; A[22] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+176] + add r11, rax + mov QWORD PTR [rcx+176], r11 + adc r12, rdx + adc r10, 0 + ; A[23] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+184] + add r12, rax + mov QWORD PTR [rcx+184], r12 + adc r10, rdx + adc r11, 0 + ; A[24] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+192] + add r10, rax + mov QWORD PTR [rcx+192], r10 + adc r11, rdx + adc r12, 0 + ; A[25] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+200] + add r11, rax + mov QWORD PTR [rcx+200], r11 + adc r12, rdx + adc r10, 0 + ; A[26] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+208] + add r12, rax + mov QWORD PTR [rcx+208], r12 + adc r10, rdx + adc r11, 0 + ; A[27] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+216] + add r10, rax + mov QWORD PTR [rcx+216], r10 + adc r11, rdx + adc r12, 0 + ; A[28] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+224] + add r11, rax + mov QWORD PTR [rcx+224], r11 + adc r12, rdx + adc r10, 0 + ; A[29] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+232] + add r12, rax + mov QWORD PTR [rcx+232], r12 + adc r10, rdx + adc r11, 0 + ; A[30] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+240] + add r10, rax + mov QWORD PTR [rcx+240], r10 + adc r11, rdx + adc r12, 0 + ; A[31] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+248] + add r11, rax + mov QWORD PTR [rcx+248], r11 + adc r12, rdx + adc r10, 0 + ; A[32] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+256] + add r12, rax + mov QWORD PTR [rcx+256], r12 + adc r10, rdx + adc r11, 0 + ; A[33] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+264] + add r10, rax + mov QWORD PTR [rcx+264], r10 + adc r11, rdx + adc r12, 0 + ; A[34] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+272] + add r11, rax + mov QWORD PTR [rcx+272], r11 + adc r12, rdx + adc r10, 0 + ; A[35] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+280] + add r12, rax + mov QWORD PTR [rcx+280], r12 + adc r10, rdx + adc r11, 0 + ; A[36] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+288] + add r10, rax + mov QWORD PTR [rcx+288], r10 + adc r11, rdx + adc r12, 0 + ; A[37] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+296] + add r11, rax + mov QWORD PTR [rcx+296], r11 + adc r12, rdx + adc r10, 0 + ; A[38] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+304] + add r12, rax + mov QWORD PTR [rcx+304], r12 + adc r10, rdx + adc r11, 0 + ; A[39] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+312] + add r10, rax + mov QWORD PTR [rcx+312], r10 + adc r11, rdx + adc r12, 0 + ; A[40] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+320] + add r11, rax + mov QWORD PTR [rcx+320], r11 + adc r12, rdx + adc r10, 0 + ; A[41] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+328] + add r12, rax + mov QWORD PTR [rcx+328], r12 + adc r10, rdx + adc r11, 0 + ; A[42] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+336] + add r10, rax + mov QWORD PTR [rcx+336], r10 + adc r11, rdx + adc r12, 0 + ; A[43] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+344] + add r11, rax + mov QWORD PTR [rcx+344], r11 + adc r12, rdx + adc r10, 0 + ; A[44] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+352] + add r12, rax + mov QWORD PTR [rcx+352], r12 + adc r10, rdx + adc r11, 0 + ; A[45] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+360] + add r10, rax + mov QWORD PTR [rcx+360], r10 + adc r11, rdx + adc r12, 0 + ; A[46] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+368] + add r11, rax + mov QWORD PTR [rcx+368], r11 + adc r12, rdx + adc r10, 0 + ; A[47] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+376] + add r12, rax + mov QWORD PTR [rcx+376], r12 + adc r10, rdx + adc r11, 0 + ; A[48] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+384] + add r10, rax + mov QWORD PTR [rcx+384], r10 + adc r11, rdx + adc r12, 0 + ; A[49] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+392] + add r11, rax + mov QWORD PTR [rcx+392], r11 + adc r12, rdx + adc r10, 0 + ; A[50] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+400] + add r12, rax + mov QWORD PTR [rcx+400], r12 + adc r10, rdx + adc r11, 0 + ; A[51] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+408] + add r10, rax + mov QWORD PTR [rcx+408], r10 + adc r11, rdx + adc r12, 0 + ; A[52] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+416] + add r11, rax + mov QWORD PTR [rcx+416], r11 + adc r12, rdx + adc r10, 0 + ; A[53] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+424] + add r12, rax + mov QWORD PTR [rcx+424], r12 + adc r10, rdx + adc r11, 0 + ; A[54] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+432] + add r10, rax + mov QWORD PTR [rcx+432], r10 + adc r11, rdx + adc r12, 0 + ; A[55] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+440] + add r11, rax + mov QWORD PTR [rcx+440], r11 + adc r12, rdx + adc r10, 0 + ; A[56] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+448] + add r12, rax + mov QWORD PTR [rcx+448], r12 + adc r10, rdx + adc r11, 0 + ; A[57] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+456] + add r10, rax + mov QWORD PTR [rcx+456], r10 + adc r11, rdx + adc r12, 0 + ; A[58] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+464] + add r11, rax + mov QWORD PTR [rcx+464], r11 + adc r12, rdx + adc r10, 0 + ; A[59] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+472] + add r12, rax + mov QWORD PTR [rcx+472], r12 + adc r10, rdx + adc r11, 0 + ; A[60] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+480] + add r10, rax + mov QWORD PTR [rcx+480], r10 + adc r11, rdx + adc r12, 0 + ; A[61] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+488] + add r11, rax + mov QWORD PTR [rcx+488], r11 + adc r12, rdx + adc r10, 0 + ; A[62] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+496] + add r12, rax + mov QWORD PTR [rcx+496], r12 + adc r10, rdx + adc r11, 0 + ; A[63] * B + mov rax, r8 + mul QWORD PTR [r9+504] + add r10, rax + adc r11, rdx + mov QWORD PTR [rcx+504], r10 + mov QWORD PTR [rcx+512], r11 + pop r12 + ret +sp_4096_mul_d_64 ENDP +_text ENDS +; /* Conditionally subtract b from a using the mask m. +; * m is -1 to subtract and 0 when not copying. +; * +; * r A single precision number representing condition subtract result. +; * a A single precision number to subtract from. +; * b A single precision number to subtract. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_4096_cond_sub_64 PROC + sub rsp, 512 + mov rax, 0 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp], r10 + mov QWORD PTR [rsp+8], r11 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+16], r10 + mov QWORD PTR [rsp+24], r11 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+32], r10 + mov QWORD PTR [rsp+40], r11 + mov r10, QWORD PTR [r8+48] + mov r11, QWORD PTR [r8+56] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+48], r10 + mov QWORD PTR [rsp+56], r11 + mov r10, QWORD PTR [r8+64] + mov r11, QWORD PTR [r8+72] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+64], r10 + mov QWORD PTR [rsp+72], r11 + mov r10, QWORD PTR [r8+80] + mov r11, QWORD PTR [r8+88] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+80], r10 + mov QWORD PTR [rsp+88], r11 + mov r10, QWORD PTR [r8+96] + mov r11, QWORD PTR [r8+104] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+96], r10 + mov QWORD PTR [rsp+104], r11 + mov r10, QWORD PTR [r8+112] + mov r11, QWORD PTR [r8+120] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+112], r10 + mov QWORD PTR [rsp+120], r11 + mov r10, QWORD PTR [r8+128] + mov r11, QWORD PTR [r8+136] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+128], r10 + mov QWORD PTR [rsp+136], r11 + mov r10, QWORD PTR [r8+144] + mov r11, QWORD PTR [r8+152] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+144], r10 + mov QWORD PTR [rsp+152], r11 + mov r10, QWORD PTR [r8+160] + mov r11, QWORD PTR [r8+168] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+160], r10 + mov QWORD PTR [rsp+168], r11 + mov r10, QWORD PTR [r8+176] + mov r11, QWORD PTR [r8+184] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+176], r10 + mov QWORD PTR [rsp+184], r11 + mov r10, QWORD PTR [r8+192] + mov r11, QWORD PTR [r8+200] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+192], r10 + mov QWORD PTR [rsp+200], r11 + mov r10, QWORD PTR [r8+208] + mov r11, QWORD PTR [r8+216] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+208], r10 + mov QWORD PTR [rsp+216], r11 + mov r10, QWORD PTR [r8+224] + mov r11, QWORD PTR [r8+232] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+224], r10 + mov QWORD PTR [rsp+232], r11 + mov r10, QWORD PTR [r8+240] + mov r11, QWORD PTR [r8+248] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+240], r10 + mov QWORD PTR [rsp+248], r11 + mov r10, QWORD PTR [r8+256] + mov r11, QWORD PTR [r8+264] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+256], r10 + mov QWORD PTR [rsp+264], r11 + mov r10, QWORD PTR [r8+272] + mov r11, QWORD PTR [r8+280] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+272], r10 + mov QWORD PTR [rsp+280], r11 + mov r10, QWORD PTR [r8+288] + mov r11, QWORD PTR [r8+296] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+288], r10 + mov QWORD PTR [rsp+296], r11 + mov r10, QWORD PTR [r8+304] + mov r11, QWORD PTR [r8+312] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+304], r10 + mov QWORD PTR [rsp+312], r11 + mov r10, QWORD PTR [r8+320] + mov r11, QWORD PTR [r8+328] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+320], r10 + mov QWORD PTR [rsp+328], r11 + mov r10, QWORD PTR [r8+336] + mov r11, QWORD PTR [r8+344] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+336], r10 + mov QWORD PTR [rsp+344], r11 + mov r10, QWORD PTR [r8+352] + mov r11, QWORD PTR [r8+360] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+352], r10 + mov QWORD PTR [rsp+360], r11 + mov r10, QWORD PTR [r8+368] + mov r11, QWORD PTR [r8+376] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+368], r10 + mov QWORD PTR [rsp+376], r11 + mov r10, QWORD PTR [r8+384] + mov r11, QWORD PTR [r8+392] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+384], r10 + mov QWORD PTR [rsp+392], r11 + mov r10, QWORD PTR [r8+400] + mov r11, QWORD PTR [r8+408] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+400], r10 + mov QWORD PTR [rsp+408], r11 + mov r10, QWORD PTR [r8+416] + mov r11, QWORD PTR [r8+424] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+416], r10 + mov QWORD PTR [rsp+424], r11 + mov r10, QWORD PTR [r8+432] + mov r11, QWORD PTR [r8+440] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+432], r10 + mov QWORD PTR [rsp+440], r11 + mov r10, QWORD PTR [r8+448] + mov r11, QWORD PTR [r8+456] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+448], r10 + mov QWORD PTR [rsp+456], r11 + mov r10, QWORD PTR [r8+464] + mov r11, QWORD PTR [r8+472] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+464], r10 + mov QWORD PTR [rsp+472], r11 + mov r10, QWORD PTR [r8+480] + mov r11, QWORD PTR [r8+488] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+480], r10 + mov QWORD PTR [rsp+488], r11 + mov r10, QWORD PTR [r8+496] + mov r11, QWORD PTR [r8+504] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+496], r10 + mov QWORD PTR [rsp+504], r11 + mov r10, QWORD PTR [rdx] + mov r8, QWORD PTR [rsp] + sub r10, r8 + mov r11, QWORD PTR [rdx+8] + mov r8, QWORD PTR [rsp+8] + sbb r11, r8 + mov QWORD PTR [rcx], r10 + mov r10, QWORD PTR [rdx+16] + mov r8, QWORD PTR [rsp+16] + sbb r10, r8 + mov QWORD PTR [rcx+8], r11 + mov r11, QWORD PTR [rdx+24] + mov r8, QWORD PTR [rsp+24] + sbb r11, r8 + mov QWORD PTR [rcx+16], r10 + mov r10, QWORD PTR [rdx+32] + mov r8, QWORD PTR [rsp+32] + sbb r10, r8 + mov QWORD PTR [rcx+24], r11 + mov r11, QWORD PTR [rdx+40] + mov r8, QWORD PTR [rsp+40] + sbb r11, r8 + mov QWORD PTR [rcx+32], r10 + mov r10, QWORD PTR [rdx+48] + mov r8, QWORD PTR [rsp+48] + sbb r10, r8 + mov QWORD PTR [rcx+40], r11 + mov r11, QWORD PTR [rdx+56] + mov r8, QWORD PTR [rsp+56] + sbb r11, r8 + mov QWORD PTR [rcx+48], r10 + mov r10, QWORD PTR [rdx+64] + mov r8, QWORD PTR [rsp+64] + sbb r10, r8 + mov QWORD PTR [rcx+56], r11 + mov r11, QWORD PTR [rdx+72] + mov r8, QWORD PTR [rsp+72] + sbb r11, r8 + mov QWORD PTR [rcx+64], r10 + mov r10, QWORD PTR [rdx+80] + mov r8, QWORD PTR [rsp+80] + sbb r10, r8 + mov QWORD PTR [rcx+72], r11 + mov r11, QWORD PTR [rdx+88] + mov r8, QWORD PTR [rsp+88] + sbb r11, r8 + mov QWORD PTR [rcx+80], r10 + mov r10, QWORD PTR [rdx+96] + mov r8, QWORD PTR [rsp+96] + sbb r10, r8 + mov QWORD PTR [rcx+88], r11 + mov r11, QWORD PTR [rdx+104] + mov r8, QWORD PTR [rsp+104] + sbb r11, r8 + mov QWORD PTR [rcx+96], r10 + mov r10, QWORD PTR [rdx+112] + mov r8, QWORD PTR [rsp+112] + sbb r10, r8 + mov QWORD PTR [rcx+104], r11 + mov r11, QWORD PTR [rdx+120] + mov r8, QWORD PTR [rsp+120] + sbb r11, r8 + mov QWORD PTR [rcx+112], r10 + mov r10, QWORD PTR [rdx+128] + mov r8, QWORD PTR [rsp+128] + sbb r10, r8 + mov QWORD PTR [rcx+120], r11 + mov r11, QWORD PTR [rdx+136] + mov r8, QWORD PTR [rsp+136] + sbb r11, r8 + mov QWORD PTR [rcx+128], r10 + mov r10, QWORD PTR [rdx+144] + mov r8, QWORD PTR [rsp+144] + sbb r10, r8 + mov QWORD PTR [rcx+136], r11 + mov r11, QWORD PTR [rdx+152] + mov r8, QWORD PTR [rsp+152] + sbb r11, r8 + mov QWORD PTR [rcx+144], r10 + mov r10, QWORD PTR [rdx+160] + mov r8, QWORD PTR [rsp+160] + sbb r10, r8 + mov QWORD PTR [rcx+152], r11 + mov r11, QWORD PTR [rdx+168] + mov r8, QWORD PTR [rsp+168] + sbb r11, r8 + mov QWORD PTR [rcx+160], r10 + mov r10, QWORD PTR [rdx+176] + mov r8, QWORD PTR [rsp+176] + sbb r10, r8 + mov QWORD PTR [rcx+168], r11 + mov r11, QWORD PTR [rdx+184] + mov r8, QWORD PTR [rsp+184] + sbb r11, r8 + mov QWORD PTR [rcx+176], r10 + mov r10, QWORD PTR [rdx+192] + mov r8, QWORD PTR [rsp+192] + sbb r10, r8 + mov QWORD PTR [rcx+184], r11 + mov r11, QWORD PTR [rdx+200] + mov r8, QWORD PTR [rsp+200] + sbb r11, r8 + mov QWORD PTR [rcx+192], r10 + mov r10, QWORD PTR [rdx+208] + mov r8, QWORD PTR [rsp+208] + sbb r10, r8 + mov QWORD PTR [rcx+200], r11 + mov r11, QWORD PTR [rdx+216] + mov r8, QWORD PTR [rsp+216] + sbb r11, r8 + mov QWORD PTR [rcx+208], r10 + mov r10, QWORD PTR [rdx+224] + mov r8, QWORD PTR [rsp+224] + sbb r10, r8 + mov QWORD PTR [rcx+216], r11 + mov r11, QWORD PTR [rdx+232] + mov r8, QWORD PTR [rsp+232] + sbb r11, r8 + mov QWORD PTR [rcx+224], r10 + mov r10, QWORD PTR [rdx+240] + mov r8, QWORD PTR [rsp+240] + sbb r10, r8 + mov QWORD PTR [rcx+232], r11 + mov r11, QWORD PTR [rdx+248] + mov r8, QWORD PTR [rsp+248] + sbb r11, r8 + mov QWORD PTR [rcx+240], r10 + mov r10, QWORD PTR [rdx+256] + mov r8, QWORD PTR [rsp+256] + sbb r10, r8 + mov QWORD PTR [rcx+248], r11 + mov r11, QWORD PTR [rdx+264] + mov r8, QWORD PTR [rsp+264] + sbb r11, r8 + mov QWORD PTR [rcx+256], r10 + mov r10, QWORD PTR [rdx+272] + mov r8, QWORD PTR [rsp+272] + sbb r10, r8 + mov QWORD PTR [rcx+264], r11 + mov r11, QWORD PTR [rdx+280] + mov r8, QWORD PTR [rsp+280] + sbb r11, r8 + mov QWORD PTR [rcx+272], r10 + mov r10, QWORD PTR [rdx+288] + mov r8, QWORD PTR [rsp+288] + sbb r10, r8 + mov QWORD PTR [rcx+280], r11 + mov r11, QWORD PTR [rdx+296] + mov r8, QWORD PTR [rsp+296] + sbb r11, r8 + mov QWORD PTR [rcx+288], r10 + mov r10, QWORD PTR [rdx+304] + mov r8, QWORD PTR [rsp+304] + sbb r10, r8 + mov QWORD PTR [rcx+296], r11 + mov r11, QWORD PTR [rdx+312] + mov r8, QWORD PTR [rsp+312] + sbb r11, r8 + mov QWORD PTR [rcx+304], r10 + mov r10, QWORD PTR [rdx+320] + mov r8, QWORD PTR [rsp+320] + sbb r10, r8 + mov QWORD PTR [rcx+312], r11 + mov r11, QWORD PTR [rdx+328] + mov r8, QWORD PTR [rsp+328] + sbb r11, r8 + mov QWORD PTR [rcx+320], r10 + mov r10, QWORD PTR [rdx+336] + mov r8, QWORD PTR [rsp+336] + sbb r10, r8 + mov QWORD PTR [rcx+328], r11 + mov r11, QWORD PTR [rdx+344] + mov r8, QWORD PTR [rsp+344] + sbb r11, r8 + mov QWORD PTR [rcx+336], r10 + mov r10, QWORD PTR [rdx+352] + mov r8, QWORD PTR [rsp+352] + sbb r10, r8 + mov QWORD PTR [rcx+344], r11 + mov r11, QWORD PTR [rdx+360] + mov r8, QWORD PTR [rsp+360] + sbb r11, r8 + mov QWORD PTR [rcx+352], r10 + mov r10, QWORD PTR [rdx+368] + mov r8, QWORD PTR [rsp+368] + sbb r10, r8 + mov QWORD PTR [rcx+360], r11 + mov r11, QWORD PTR [rdx+376] + mov r8, QWORD PTR [rsp+376] + sbb r11, r8 + mov QWORD PTR [rcx+368], r10 + mov r10, QWORD PTR [rdx+384] + mov r8, QWORD PTR [rsp+384] + sbb r10, r8 + mov QWORD PTR [rcx+376], r11 + mov r11, QWORD PTR [rdx+392] + mov r8, QWORD PTR [rsp+392] + sbb r11, r8 + mov QWORD PTR [rcx+384], r10 + mov r10, QWORD PTR [rdx+400] + mov r8, QWORD PTR [rsp+400] + sbb r10, r8 + mov QWORD PTR [rcx+392], r11 + mov r11, QWORD PTR [rdx+408] + mov r8, QWORD PTR [rsp+408] + sbb r11, r8 + mov QWORD PTR [rcx+400], r10 + mov r10, QWORD PTR [rdx+416] + mov r8, QWORD PTR [rsp+416] + sbb r10, r8 + mov QWORD PTR [rcx+408], r11 + mov r11, QWORD PTR [rdx+424] + mov r8, QWORD PTR [rsp+424] + sbb r11, r8 + mov QWORD PTR [rcx+416], r10 + mov r10, QWORD PTR [rdx+432] + mov r8, QWORD PTR [rsp+432] + sbb r10, r8 + mov QWORD PTR [rcx+424], r11 + mov r11, QWORD PTR [rdx+440] + mov r8, QWORD PTR [rsp+440] + sbb r11, r8 + mov QWORD PTR [rcx+432], r10 + mov r10, QWORD PTR [rdx+448] + mov r8, QWORD PTR [rsp+448] + sbb r10, r8 + mov QWORD PTR [rcx+440], r11 + mov r11, QWORD PTR [rdx+456] + mov r8, QWORD PTR [rsp+456] + sbb r11, r8 + mov QWORD PTR [rcx+448], r10 + mov r10, QWORD PTR [rdx+464] + mov r8, QWORD PTR [rsp+464] + sbb r10, r8 + mov QWORD PTR [rcx+456], r11 + mov r11, QWORD PTR [rdx+472] + mov r8, QWORD PTR [rsp+472] + sbb r11, r8 + mov QWORD PTR [rcx+464], r10 + mov r10, QWORD PTR [rdx+480] + mov r8, QWORD PTR [rsp+480] + sbb r10, r8 + mov QWORD PTR [rcx+472], r11 + mov r11, QWORD PTR [rdx+488] + mov r8, QWORD PTR [rsp+488] + sbb r11, r8 + mov QWORD PTR [rcx+480], r10 + mov r10, QWORD PTR [rdx+496] + mov r8, QWORD PTR [rsp+496] + sbb r10, r8 + mov QWORD PTR [rcx+488], r11 + mov r11, QWORD PTR [rdx+504] + mov r8, QWORD PTR [rsp+504] + sbb r11, r8 + mov QWORD PTR [rcx+496], r10 + mov QWORD PTR [rcx+504], r11 + sbb rax, 0 + add rsp, 512 + ret +sp_4096_cond_sub_64 ENDP +_text ENDS +; /* Reduce the number back to 4096 bits using Montgomery reduction. +; * +; * a A single precision number to reduce in place. +; * m The single precision number representing the modulus. +; * mp The digit representing the negative inverse of m mod 2^n. +; */ +_text SEGMENT READONLY PARA +sp_4096_mont_reduce_64 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + mov r9, rdx + xor rsi, rsi + ; i = 64 + mov r10, 64 + mov r15, QWORD PTR [rcx] + mov rdi, QWORD PTR [rcx+8] +L_4096_mont_loop_64: + ; mu = a[i] * mp + mov r13, r15 + imul r13, r8 + ; a[i+0] += m[0] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9] + add r15, rax + adc r12, rdx + ; a[i+1] += m[1] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+8] + mov r15, rdi + add r15, rax + adc r11, rdx + add r15, r12 + adc r11, 0 + ; a[i+2] += m[2] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+16] + mov rdi, QWORD PTR [rcx+16] + add rdi, rax + adc r12, rdx + add rdi, r11 + adc r12, 0 + ; a[i+3] += m[3] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+24] + mov r14, QWORD PTR [rcx+24] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+24], r14 + adc r11, 0 + ; a[i+4] += m[4] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+32] + mov r14, QWORD PTR [rcx+32] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+32], r14 + adc r12, 0 + ; a[i+5] += m[5] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+40] + mov r14, QWORD PTR [rcx+40] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+40], r14 + adc r11, 0 + ; a[i+6] += m[6] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+48] + mov r14, QWORD PTR [rcx+48] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+48], r14 + adc r12, 0 + ; a[i+7] += m[7] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+56] + mov r14, QWORD PTR [rcx+56] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+56], r14 + adc r11, 0 + ; a[i+8] += m[8] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+64] + mov r14, QWORD PTR [rcx+64] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+64], r14 + adc r12, 0 + ; a[i+9] += m[9] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+72] + mov r14, QWORD PTR [rcx+72] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+72], r14 + adc r11, 0 + ; a[i+10] += m[10] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+80] + mov r14, QWORD PTR [rcx+80] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+80], r14 + adc r12, 0 + ; a[i+11] += m[11] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+88] + mov r14, QWORD PTR [rcx+88] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+88], r14 + adc r11, 0 + ; a[i+12] += m[12] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+96] + mov r14, QWORD PTR [rcx+96] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+96], r14 + adc r12, 0 + ; a[i+13] += m[13] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+104] + mov r14, QWORD PTR [rcx+104] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+104], r14 + adc r11, 0 + ; a[i+14] += m[14] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+112] + mov r14, QWORD PTR [rcx+112] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+112], r14 + adc r12, 0 + ; a[i+15] += m[15] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+120] + mov r14, QWORD PTR [rcx+120] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+120], r14 + adc r11, 0 + ; a[i+16] += m[16] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+128] + mov r14, QWORD PTR [rcx+128] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+128], r14 + adc r12, 0 + ; a[i+17] += m[17] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+136] + mov r14, QWORD PTR [rcx+136] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+136], r14 + adc r11, 0 + ; a[i+18] += m[18] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+144] + mov r14, QWORD PTR [rcx+144] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+144], r14 + adc r12, 0 + ; a[i+19] += m[19] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+152] + mov r14, QWORD PTR [rcx+152] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+152], r14 + adc r11, 0 + ; a[i+20] += m[20] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+160] + mov r14, QWORD PTR [rcx+160] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+160], r14 + adc r12, 0 + ; a[i+21] += m[21] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+168] + mov r14, QWORD PTR [rcx+168] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+168], r14 + adc r11, 0 + ; a[i+22] += m[22] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+176] + mov r14, QWORD PTR [rcx+176] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+176], r14 + adc r12, 0 + ; a[i+23] += m[23] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+184] + mov r14, QWORD PTR [rcx+184] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+184], r14 + adc r11, 0 + ; a[i+24] += m[24] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+192] + mov r14, QWORD PTR [rcx+192] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+192], r14 + adc r12, 0 + ; a[i+25] += m[25] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+200] + mov r14, QWORD PTR [rcx+200] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+200], r14 + adc r11, 0 + ; a[i+26] += m[26] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+208] + mov r14, QWORD PTR [rcx+208] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+208], r14 + adc r12, 0 + ; a[i+27] += m[27] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+216] + mov r14, QWORD PTR [rcx+216] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+216], r14 + adc r11, 0 + ; a[i+28] += m[28] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+224] + mov r14, QWORD PTR [rcx+224] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+224], r14 + adc r12, 0 + ; a[i+29] += m[29] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+232] + mov r14, QWORD PTR [rcx+232] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+232], r14 + adc r11, 0 + ; a[i+30] += m[30] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+240] + mov r14, QWORD PTR [rcx+240] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+240], r14 + adc r12, 0 + ; a[i+31] += m[31] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+248] + mov r14, QWORD PTR [rcx+248] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+248], r14 + adc r11, 0 + ; a[i+32] += m[32] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+256] + mov r14, QWORD PTR [rcx+256] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+256], r14 + adc r12, 0 + ; a[i+33] += m[33] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+264] + mov r14, QWORD PTR [rcx+264] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+264], r14 + adc r11, 0 + ; a[i+34] += m[34] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+272] + mov r14, QWORD PTR [rcx+272] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+272], r14 + adc r12, 0 + ; a[i+35] += m[35] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+280] + mov r14, QWORD PTR [rcx+280] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+280], r14 + adc r11, 0 + ; a[i+36] += m[36] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+288] + mov r14, QWORD PTR [rcx+288] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+288], r14 + adc r12, 0 + ; a[i+37] += m[37] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+296] + mov r14, QWORD PTR [rcx+296] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+296], r14 + adc r11, 0 + ; a[i+38] += m[38] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+304] + mov r14, QWORD PTR [rcx+304] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+304], r14 + adc r12, 0 + ; a[i+39] += m[39] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+312] + mov r14, QWORD PTR [rcx+312] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+312], r14 + adc r11, 0 + ; a[i+40] += m[40] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+320] + mov r14, QWORD PTR [rcx+320] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+320], r14 + adc r12, 0 + ; a[i+41] += m[41] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+328] + mov r14, QWORD PTR [rcx+328] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+328], r14 + adc r11, 0 + ; a[i+42] += m[42] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+336] + mov r14, QWORD PTR [rcx+336] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+336], r14 + adc r12, 0 + ; a[i+43] += m[43] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+344] + mov r14, QWORD PTR [rcx+344] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+344], r14 + adc r11, 0 + ; a[i+44] += m[44] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+352] + mov r14, QWORD PTR [rcx+352] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+352], r14 + adc r12, 0 + ; a[i+45] += m[45] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+360] + mov r14, QWORD PTR [rcx+360] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+360], r14 + adc r11, 0 + ; a[i+46] += m[46] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+368] + mov r14, QWORD PTR [rcx+368] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+368], r14 + adc r12, 0 + ; a[i+47] += m[47] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+376] + mov r14, QWORD PTR [rcx+376] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+376], r14 + adc r11, 0 + ; a[i+48] += m[48] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+384] + mov r14, QWORD PTR [rcx+384] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+384], r14 + adc r12, 0 + ; a[i+49] += m[49] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+392] + mov r14, QWORD PTR [rcx+392] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+392], r14 + adc r11, 0 + ; a[i+50] += m[50] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+400] + mov r14, QWORD PTR [rcx+400] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+400], r14 + adc r12, 0 + ; a[i+51] += m[51] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+408] + mov r14, QWORD PTR [rcx+408] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+408], r14 + adc r11, 0 + ; a[i+52] += m[52] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+416] + mov r14, QWORD PTR [rcx+416] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+416], r14 + adc r12, 0 + ; a[i+53] += m[53] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+424] + mov r14, QWORD PTR [rcx+424] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+424], r14 + adc r11, 0 + ; a[i+54] += m[54] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+432] + mov r14, QWORD PTR [rcx+432] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+432], r14 + adc r12, 0 + ; a[i+55] += m[55] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+440] + mov r14, QWORD PTR [rcx+440] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+440], r14 + adc r11, 0 + ; a[i+56] += m[56] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+448] + mov r14, QWORD PTR [rcx+448] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+448], r14 + adc r12, 0 + ; a[i+57] += m[57] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+456] + mov r14, QWORD PTR [rcx+456] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+456], r14 + adc r11, 0 + ; a[i+58] += m[58] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+464] + mov r14, QWORD PTR [rcx+464] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+464], r14 + adc r12, 0 + ; a[i+59] += m[59] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+472] + mov r14, QWORD PTR [rcx+472] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+472], r14 + adc r11, 0 + ; a[i+60] += m[60] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+480] + mov r14, QWORD PTR [rcx+480] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+480], r14 + adc r12, 0 + ; a[i+61] += m[61] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+488] + mov r14, QWORD PTR [rcx+488] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+488], r14 + adc r11, 0 + ; a[i+62] += m[62] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+496] + mov r14, QWORD PTR [rcx+496] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+496], r14 + adc r12, 0 + ; a[i+63] += m[63] * mu + mov rax, r13 + mul QWORD PTR [r9+504] + mov r14, QWORD PTR [rcx+504] + add r12, rax + adc rdx, rsi + mov rsi, 0 + adc rsi, 0 + add r14, r12 + mov QWORD PTR [rcx+504], r14 + adc QWORD PTR [rcx+512], rdx + adc rsi, 0 + ; i -= 1 + add rcx, 8 + dec r10 + jnz L_4096_mont_loop_64 + mov QWORD PTR [rcx], r15 + mov QWORD PTR [rcx+8], rdi + neg rsi +IFDEF _WIN64 + mov r8, r9 + mov r9, rsi +ELSE + mov r9, rsi + mov r8, r9 +ENDIF + mov rdx, rcx + mov rcx, rcx + sub rcx, 512 + call sp_4096_cond_sub_64 + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_4096_mont_reduce_64 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Conditionally subtract b from a using the mask m. +; * m is -1 to subtract and 0 when not copying. +; * +; * r A single precision number representing condition subtract result. +; * a A single precision number to subtract from. +; * b A single precision number to subtract. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_4096_cond_sub_avx2_64 PROC + push r12 + mov rax, 0 + mov r12, QWORD PTR [r8] + mov r10, QWORD PTR [rdx] + pext r12, r12, r9 + sub r10, r12 + mov r12, QWORD PTR [r8+8] + mov r11, QWORD PTR [rdx+8] + pext r12, r12, r9 + mov QWORD PTR [rcx], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+16] + mov r12, QWORD PTR [rdx+16] + pext r10, r10, r9 + mov QWORD PTR [rcx+8], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+24] + mov r10, QWORD PTR [rdx+24] + pext r11, r11, r9 + mov QWORD PTR [rcx+16], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+32] + mov r11, QWORD PTR [rdx+32] + pext r12, r12, r9 + mov QWORD PTR [rcx+24], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+40] + mov r12, QWORD PTR [rdx+40] + pext r10, r10, r9 + mov QWORD PTR [rcx+32], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+48] + mov r10, QWORD PTR [rdx+48] + pext r11, r11, r9 + mov QWORD PTR [rcx+40], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+56] + mov r11, QWORD PTR [rdx+56] + pext r12, r12, r9 + mov QWORD PTR [rcx+48], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+64] + mov r12, QWORD PTR [rdx+64] + pext r10, r10, r9 + mov QWORD PTR [rcx+56], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+72] + mov r10, QWORD PTR [rdx+72] + pext r11, r11, r9 + mov QWORD PTR [rcx+64], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+80] + mov r11, QWORD PTR [rdx+80] + pext r12, r12, r9 + mov QWORD PTR [rcx+72], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+88] + mov r12, QWORD PTR [rdx+88] + pext r10, r10, r9 + mov QWORD PTR [rcx+80], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+96] + mov r10, QWORD PTR [rdx+96] + pext r11, r11, r9 + mov QWORD PTR [rcx+88], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+104] + mov r11, QWORD PTR [rdx+104] + pext r12, r12, r9 + mov QWORD PTR [rcx+96], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+112] + mov r12, QWORD PTR [rdx+112] + pext r10, r10, r9 + mov QWORD PTR [rcx+104], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+120] + mov r10, QWORD PTR [rdx+120] + pext r11, r11, r9 + mov QWORD PTR [rcx+112], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+128] + mov r11, QWORD PTR [rdx+128] + pext r12, r12, r9 + mov QWORD PTR [rcx+120], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+136] + mov r12, QWORD PTR [rdx+136] + pext r10, r10, r9 + mov QWORD PTR [rcx+128], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+144] + mov r10, QWORD PTR [rdx+144] + pext r11, r11, r9 + mov QWORD PTR [rcx+136], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+152] + mov r11, QWORD PTR [rdx+152] + pext r12, r12, r9 + mov QWORD PTR [rcx+144], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+160] + mov r12, QWORD PTR [rdx+160] + pext r10, r10, r9 + mov QWORD PTR [rcx+152], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+168] + mov r10, QWORD PTR [rdx+168] + pext r11, r11, r9 + mov QWORD PTR [rcx+160], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+176] + mov r11, QWORD PTR [rdx+176] + pext r12, r12, r9 + mov QWORD PTR [rcx+168], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+184] + mov r12, QWORD PTR [rdx+184] + pext r10, r10, r9 + mov QWORD PTR [rcx+176], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+192] + mov r10, QWORD PTR [rdx+192] + pext r11, r11, r9 + mov QWORD PTR [rcx+184], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+200] + mov r11, QWORD PTR [rdx+200] + pext r12, r12, r9 + mov QWORD PTR [rcx+192], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+208] + mov r12, QWORD PTR [rdx+208] + pext r10, r10, r9 + mov QWORD PTR [rcx+200], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+216] + mov r10, QWORD PTR [rdx+216] + pext r11, r11, r9 + mov QWORD PTR [rcx+208], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+224] + mov r11, QWORD PTR [rdx+224] + pext r12, r12, r9 + mov QWORD PTR [rcx+216], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+232] + mov r12, QWORD PTR [rdx+232] + pext r10, r10, r9 + mov QWORD PTR [rcx+224], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+240] + mov r10, QWORD PTR [rdx+240] + pext r11, r11, r9 + mov QWORD PTR [rcx+232], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+248] + mov r11, QWORD PTR [rdx+248] + pext r12, r12, r9 + mov QWORD PTR [rcx+240], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+256] + mov r12, QWORD PTR [rdx+256] + pext r10, r10, r9 + mov QWORD PTR [rcx+248], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+264] + mov r10, QWORD PTR [rdx+264] + pext r11, r11, r9 + mov QWORD PTR [rcx+256], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+272] + mov r11, QWORD PTR [rdx+272] + pext r12, r12, r9 + mov QWORD PTR [rcx+264], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+280] + mov r12, QWORD PTR [rdx+280] + pext r10, r10, r9 + mov QWORD PTR [rcx+272], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+288] + mov r10, QWORD PTR [rdx+288] + pext r11, r11, r9 + mov QWORD PTR [rcx+280], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+296] + mov r11, QWORD PTR [rdx+296] + pext r12, r12, r9 + mov QWORD PTR [rcx+288], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+304] + mov r12, QWORD PTR [rdx+304] + pext r10, r10, r9 + mov QWORD PTR [rcx+296], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+312] + mov r10, QWORD PTR [rdx+312] + pext r11, r11, r9 + mov QWORD PTR [rcx+304], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+320] + mov r11, QWORD PTR [rdx+320] + pext r12, r12, r9 + mov QWORD PTR [rcx+312], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+328] + mov r12, QWORD PTR [rdx+328] + pext r10, r10, r9 + mov QWORD PTR [rcx+320], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+336] + mov r10, QWORD PTR [rdx+336] + pext r11, r11, r9 + mov QWORD PTR [rcx+328], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+344] + mov r11, QWORD PTR [rdx+344] + pext r12, r12, r9 + mov QWORD PTR [rcx+336], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+352] + mov r12, QWORD PTR [rdx+352] + pext r10, r10, r9 + mov QWORD PTR [rcx+344], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+360] + mov r10, QWORD PTR [rdx+360] + pext r11, r11, r9 + mov QWORD PTR [rcx+352], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+368] + mov r11, QWORD PTR [rdx+368] + pext r12, r12, r9 + mov QWORD PTR [rcx+360], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+376] + mov r12, QWORD PTR [rdx+376] + pext r10, r10, r9 + mov QWORD PTR [rcx+368], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+384] + mov r10, QWORD PTR [rdx+384] + pext r11, r11, r9 + mov QWORD PTR [rcx+376], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+392] + mov r11, QWORD PTR [rdx+392] + pext r12, r12, r9 + mov QWORD PTR [rcx+384], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+400] + mov r12, QWORD PTR [rdx+400] + pext r10, r10, r9 + mov QWORD PTR [rcx+392], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+408] + mov r10, QWORD PTR [rdx+408] + pext r11, r11, r9 + mov QWORD PTR [rcx+400], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+416] + mov r11, QWORD PTR [rdx+416] + pext r12, r12, r9 + mov QWORD PTR [rcx+408], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+424] + mov r12, QWORD PTR [rdx+424] + pext r10, r10, r9 + mov QWORD PTR [rcx+416], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+432] + mov r10, QWORD PTR [rdx+432] + pext r11, r11, r9 + mov QWORD PTR [rcx+424], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+440] + mov r11, QWORD PTR [rdx+440] + pext r12, r12, r9 + mov QWORD PTR [rcx+432], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+448] + mov r12, QWORD PTR [rdx+448] + pext r10, r10, r9 + mov QWORD PTR [rcx+440], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+456] + mov r10, QWORD PTR [rdx+456] + pext r11, r11, r9 + mov QWORD PTR [rcx+448], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+464] + mov r11, QWORD PTR [rdx+464] + pext r12, r12, r9 + mov QWORD PTR [rcx+456], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+472] + mov r12, QWORD PTR [rdx+472] + pext r10, r10, r9 + mov QWORD PTR [rcx+464], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+480] + mov r10, QWORD PTR [rdx+480] + pext r11, r11, r9 + mov QWORD PTR [rcx+472], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+488] + mov r11, QWORD PTR [rdx+488] + pext r12, r12, r9 + mov QWORD PTR [rcx+480], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+496] + mov r12, QWORD PTR [rdx+496] + pext r10, r10, r9 + mov QWORD PTR [rcx+488], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+504] + mov r10, QWORD PTR [rdx+504] + pext r11, r11, r9 + mov QWORD PTR [rcx+496], r12 + sbb r10, r11 + mov QWORD PTR [rcx+504], r10 + sbb rax, 0 + pop r12 + ret +sp_4096_cond_sub_avx2_64 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Mul a by digit b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision digit. +; */ +_text SEGMENT READONLY PARA +sp_4096_mul_d_avx2_64 PROC + push r12 + push r13 + mov rax, rdx + ; A[0] * B + mov rdx, r8 + xor r13, r13 + mulx r12, r11, QWORD PTR [rax] + mov QWORD PTR [rcx], r11 + ; A[1] * B + mulx r10, r9, QWORD PTR [rax+8] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+8], r12 + ; A[2] * B + mulx r10, r9, QWORD PTR [rax+16] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+16], r11 + ; A[3] * B + mulx r10, r9, QWORD PTR [rax+24] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+24], r12 + ; A[4] * B + mulx r10, r9, QWORD PTR [rax+32] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+32], r11 + ; A[5] * B + mulx r10, r9, QWORD PTR [rax+40] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+40], r12 + ; A[6] * B + mulx r10, r9, QWORD PTR [rax+48] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+48], r11 + ; A[7] * B + mulx r10, r9, QWORD PTR [rax+56] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+56], r12 + ; A[8] * B + mulx r10, r9, QWORD PTR [rax+64] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+64], r11 + ; A[9] * B + mulx r10, r9, QWORD PTR [rax+72] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+72], r12 + ; A[10] * B + mulx r10, r9, QWORD PTR [rax+80] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+80], r11 + ; A[11] * B + mulx r10, r9, QWORD PTR [rax+88] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+88], r12 + ; A[12] * B + mulx r10, r9, QWORD PTR [rax+96] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+96], r11 + ; A[13] * B + mulx r10, r9, QWORD PTR [rax+104] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+104], r12 + ; A[14] * B + mulx r10, r9, QWORD PTR [rax+112] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+112], r11 + ; A[15] * B + mulx r10, r9, QWORD PTR [rax+120] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+120], r12 + ; A[16] * B + mulx r10, r9, QWORD PTR [rax+128] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+128], r11 + ; A[17] * B + mulx r10, r9, QWORD PTR [rax+136] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+136], r12 + ; A[18] * B + mulx r10, r9, QWORD PTR [rax+144] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+144], r11 + ; A[19] * B + mulx r10, r9, QWORD PTR [rax+152] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+152], r12 + ; A[20] * B + mulx r10, r9, QWORD PTR [rax+160] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+160], r11 + ; A[21] * B + mulx r10, r9, QWORD PTR [rax+168] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+168], r12 + ; A[22] * B + mulx r10, r9, QWORD PTR [rax+176] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+176], r11 + ; A[23] * B + mulx r10, r9, QWORD PTR [rax+184] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+184], r12 + ; A[24] * B + mulx r10, r9, QWORD PTR [rax+192] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+192], r11 + ; A[25] * B + mulx r10, r9, QWORD PTR [rax+200] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+200], r12 + ; A[26] * B + mulx r10, r9, QWORD PTR [rax+208] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+208], r11 + ; A[27] * B + mulx r10, r9, QWORD PTR [rax+216] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+216], r12 + ; A[28] * B + mulx r10, r9, QWORD PTR [rax+224] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+224], r11 + ; A[29] * B + mulx r10, r9, QWORD PTR [rax+232] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+232], r12 + ; A[30] * B + mulx r10, r9, QWORD PTR [rax+240] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+240], r11 + ; A[31] * B + mulx r10, r9, QWORD PTR [rax+248] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+248], r12 + ; A[32] * B + mulx r10, r9, QWORD PTR [rax+256] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+256], r11 + ; A[33] * B + mulx r10, r9, QWORD PTR [rax+264] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+264], r12 + ; A[34] * B + mulx r10, r9, QWORD PTR [rax+272] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+272], r11 + ; A[35] * B + mulx r10, r9, QWORD PTR [rax+280] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+280], r12 + ; A[36] * B + mulx r10, r9, QWORD PTR [rax+288] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+288], r11 + ; A[37] * B + mulx r10, r9, QWORD PTR [rax+296] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+296], r12 + ; A[38] * B + mulx r10, r9, QWORD PTR [rax+304] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+304], r11 + ; A[39] * B + mulx r10, r9, QWORD PTR [rax+312] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+312], r12 + ; A[40] * B + mulx r10, r9, QWORD PTR [rax+320] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+320], r11 + ; A[41] * B + mulx r10, r9, QWORD PTR [rax+328] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+328], r12 + ; A[42] * B + mulx r10, r9, QWORD PTR [rax+336] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+336], r11 + ; A[43] * B + mulx r10, r9, QWORD PTR [rax+344] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+344], r12 + ; A[44] * B + mulx r10, r9, QWORD PTR [rax+352] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+352], r11 + ; A[45] * B + mulx r10, r9, QWORD PTR [rax+360] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+360], r12 + ; A[46] * B + mulx r10, r9, QWORD PTR [rax+368] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+368], r11 + ; A[47] * B + mulx r10, r9, QWORD PTR [rax+376] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+376], r12 + ; A[48] * B + mulx r10, r9, QWORD PTR [rax+384] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+384], r11 + ; A[49] * B + mulx r10, r9, QWORD PTR [rax+392] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+392], r12 + ; A[50] * B + mulx r10, r9, QWORD PTR [rax+400] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+400], r11 + ; A[51] * B + mulx r10, r9, QWORD PTR [rax+408] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+408], r12 + ; A[52] * B + mulx r10, r9, QWORD PTR [rax+416] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+416], r11 + ; A[53] * B + mulx r10, r9, QWORD PTR [rax+424] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+424], r12 + ; A[54] * B + mulx r10, r9, QWORD PTR [rax+432] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+432], r11 + ; A[55] * B + mulx r10, r9, QWORD PTR [rax+440] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+440], r12 + ; A[56] * B + mulx r10, r9, QWORD PTR [rax+448] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+448], r11 + ; A[57] * B + mulx r10, r9, QWORD PTR [rax+456] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+456], r12 + ; A[58] * B + mulx r10, r9, QWORD PTR [rax+464] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+464], r11 + ; A[59] * B + mulx r10, r9, QWORD PTR [rax+472] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+472], r12 + ; A[60] * B + mulx r10, r9, QWORD PTR [rax+480] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+480], r11 + ; A[61] * B + mulx r10, r9, QWORD PTR [rax+488] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+488], r12 + ; A[62] * B + mulx r10, r9, QWORD PTR [rax+496] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+496], r11 + ; A[63] * B + mulx r10, r9, QWORD PTR [rax+504] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + adcx r11, r13 + mov QWORD PTR [rcx+504], r12 + mov QWORD PTR [rcx+512], r11 + pop r13 + pop r12 + ret +sp_4096_mul_d_avx2_64 ENDP +_text ENDS +ENDIF +IFDEF _WIN64 +; /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) +; * +; * d1 The high order half of the number to divide. +; * d0 The low order half of the number to divide. +; * div The dividend. +; * returns the result of the division. +; */ +_text SEGMENT READONLY PARA +div_4096_word_asm_64 PROC + mov r9, rdx + mov rax, r9 + mov rdx, rcx + div r8 + ret +div_4096_word_asm_64 ENDP +_text ENDS +ENDIF +; /* Compare a with b in constant time. +; * +; * a A single precision integer. +; * b A single precision integer. +; * return -ve, 0 or +ve if a is less than, equal to or greater than b +; * respectively. +; */ +_text SEGMENT READONLY PARA +sp_4096_cmp_64 PROC + push r12 + xor r9, r9 + mov r8, -1 + mov rax, -1 + mov r10, 1 + mov r11, QWORD PTR [rcx+504] + mov r12, QWORD PTR [rdx+504] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+496] + mov r12, QWORD PTR [rdx+496] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+488] + mov r12, QWORD PTR [rdx+488] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+480] + mov r12, QWORD PTR [rdx+480] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+472] + mov r12, QWORD PTR [rdx+472] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+464] + mov r12, QWORD PTR [rdx+464] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+456] + mov r12, QWORD PTR [rdx+456] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+448] + mov r12, QWORD PTR [rdx+448] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+440] + mov r12, QWORD PTR [rdx+440] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+432] + mov r12, QWORD PTR [rdx+432] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+424] + mov r12, QWORD PTR [rdx+424] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+416] + mov r12, QWORD PTR [rdx+416] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+408] + mov r12, QWORD PTR [rdx+408] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+400] + mov r12, QWORD PTR [rdx+400] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+392] + mov r12, QWORD PTR [rdx+392] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+384] + mov r12, QWORD PTR [rdx+384] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+376] + mov r12, QWORD PTR [rdx+376] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+368] + mov r12, QWORD PTR [rdx+368] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+360] + mov r12, QWORD PTR [rdx+360] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+352] + mov r12, QWORD PTR [rdx+352] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+344] + mov r12, QWORD PTR [rdx+344] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+336] + mov r12, QWORD PTR [rdx+336] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+328] + mov r12, QWORD PTR [rdx+328] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+320] + mov r12, QWORD PTR [rdx+320] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+312] + mov r12, QWORD PTR [rdx+312] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+304] + mov r12, QWORD PTR [rdx+304] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+296] + mov r12, QWORD PTR [rdx+296] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+288] + mov r12, QWORD PTR [rdx+288] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+280] + mov r12, QWORD PTR [rdx+280] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+272] + mov r12, QWORD PTR [rdx+272] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+264] + mov r12, QWORD PTR [rdx+264] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+256] + mov r12, QWORD PTR [rdx+256] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+248] + mov r12, QWORD PTR [rdx+248] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+240] + mov r12, QWORD PTR [rdx+240] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+232] + mov r12, QWORD PTR [rdx+232] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+224] + mov r12, QWORD PTR [rdx+224] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+216] + mov r12, QWORD PTR [rdx+216] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+208] + mov r12, QWORD PTR [rdx+208] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+200] + mov r12, QWORD PTR [rdx+200] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+192] + mov r12, QWORD PTR [rdx+192] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+184] + mov r12, QWORD PTR [rdx+184] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+176] + mov r12, QWORD PTR [rdx+176] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+168] + mov r12, QWORD PTR [rdx+168] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+160] + mov r12, QWORD PTR [rdx+160] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+152] + mov r12, QWORD PTR [rdx+152] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+144] + mov r12, QWORD PTR [rdx+144] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+136] + mov r12, QWORD PTR [rdx+136] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+128] + mov r12, QWORD PTR [rdx+128] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+120] + mov r12, QWORD PTR [rdx+120] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+112] + mov r12, QWORD PTR [rdx+112] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+104] + mov r12, QWORD PTR [rdx+104] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+96] + mov r12, QWORD PTR [rdx+96] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+88] + mov r12, QWORD PTR [rdx+88] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+80] + mov r12, QWORD PTR [rdx+80] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+72] + mov r12, QWORD PTR [rdx+72] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+64] + mov r12, QWORD PTR [rdx+64] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+56] + mov r12, QWORD PTR [rdx+56] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+48] + mov r12, QWORD PTR [rdx+48] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+40] + mov r12, QWORD PTR [rdx+40] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+32] + mov r12, QWORD PTR [rdx+32] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+24] + mov r12, QWORD PTR [rdx+24] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+16] + mov r12, QWORD PTR [rdx+16] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+8] + mov r12, QWORD PTR [rdx+8] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx] + mov r12, QWORD PTR [rdx] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + xor rax, r8 + pop r12 + ret +sp_4096_cmp_64 ENDP +_text ENDS +; /* Sub b from a into r. (r = a - b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_4096_sub_64 PROC + mov r9, QWORD PTR [rdx] + xor rax, rax + sub r9, QWORD PTR [r8] + mov r10, QWORD PTR [rdx+8] + mov QWORD PTR [rcx], r9 + sbb r10, QWORD PTR [r8+8] + mov r9, QWORD PTR [rdx+16] + mov QWORD PTR [rcx+8], r10 + sbb r9, QWORD PTR [r8+16] + mov r10, QWORD PTR [rdx+24] + mov QWORD PTR [rcx+16], r9 + sbb r10, QWORD PTR [r8+24] + mov r9, QWORD PTR [rdx+32] + mov QWORD PTR [rcx+24], r10 + sbb r9, QWORD PTR [r8+32] + mov r10, QWORD PTR [rdx+40] + mov QWORD PTR [rcx+32], r9 + sbb r10, QWORD PTR [r8+40] + mov r9, QWORD PTR [rdx+48] + mov QWORD PTR [rcx+40], r10 + sbb r9, QWORD PTR [r8+48] + mov r10, QWORD PTR [rdx+56] + mov QWORD PTR [rcx+48], r9 + sbb r10, QWORD PTR [r8+56] + mov r9, QWORD PTR [rdx+64] + mov QWORD PTR [rcx+56], r10 + sbb r9, QWORD PTR [r8+64] + mov r10, QWORD PTR [rdx+72] + mov QWORD PTR [rcx+64], r9 + sbb r10, QWORD PTR [r8+72] + mov r9, QWORD PTR [rdx+80] + mov QWORD PTR [rcx+72], r10 + sbb r9, QWORD PTR [r8+80] + mov r10, QWORD PTR [rdx+88] + mov QWORD PTR [rcx+80], r9 + sbb r10, QWORD PTR [r8+88] + mov r9, QWORD PTR [rdx+96] + mov QWORD PTR [rcx+88], r10 + sbb r9, QWORD PTR [r8+96] + mov r10, QWORD PTR [rdx+104] + mov QWORD PTR [rcx+96], r9 + sbb r10, QWORD PTR [r8+104] + mov r9, QWORD PTR [rdx+112] + mov QWORD PTR [rcx+104], r10 + sbb r9, QWORD PTR [r8+112] + mov r10, QWORD PTR [rdx+120] + mov QWORD PTR [rcx+112], r9 + sbb r10, QWORD PTR [r8+120] + mov r9, QWORD PTR [rdx+128] + mov QWORD PTR [rcx+120], r10 + sbb r9, QWORD PTR [r8+128] + mov r10, QWORD PTR [rdx+136] + mov QWORD PTR [rcx+128], r9 + sbb r10, QWORD PTR [r8+136] + mov r9, QWORD PTR [rdx+144] + mov QWORD PTR [rcx+136], r10 + sbb r9, QWORD PTR [r8+144] + mov r10, QWORD PTR [rdx+152] + mov QWORD PTR [rcx+144], r9 + sbb r10, QWORD PTR [r8+152] + mov r9, QWORD PTR [rdx+160] + mov QWORD PTR [rcx+152], r10 + sbb r9, QWORD PTR [r8+160] + mov r10, QWORD PTR [rdx+168] + mov QWORD PTR [rcx+160], r9 + sbb r10, QWORD PTR [r8+168] + mov r9, QWORD PTR [rdx+176] + mov QWORD PTR [rcx+168], r10 + sbb r9, QWORD PTR [r8+176] + mov r10, QWORD PTR [rdx+184] + mov QWORD PTR [rcx+176], r9 + sbb r10, QWORD PTR [r8+184] + mov r9, QWORD PTR [rdx+192] + mov QWORD PTR [rcx+184], r10 + sbb r9, QWORD PTR [r8+192] + mov r10, QWORD PTR [rdx+200] + mov QWORD PTR [rcx+192], r9 + sbb r10, QWORD PTR [r8+200] + mov r9, QWORD PTR [rdx+208] + mov QWORD PTR [rcx+200], r10 + sbb r9, QWORD PTR [r8+208] + mov r10, QWORD PTR [rdx+216] + mov QWORD PTR [rcx+208], r9 + sbb r10, QWORD PTR [r8+216] + mov r9, QWORD PTR [rdx+224] + mov QWORD PTR [rcx+216], r10 + sbb r9, QWORD PTR [r8+224] + mov r10, QWORD PTR [rdx+232] + mov QWORD PTR [rcx+224], r9 + sbb r10, QWORD PTR [r8+232] + mov r9, QWORD PTR [rdx+240] + mov QWORD PTR [rcx+232], r10 + sbb r9, QWORD PTR [r8+240] + mov r10, QWORD PTR [rdx+248] + mov QWORD PTR [rcx+240], r9 + sbb r10, QWORD PTR [r8+248] + mov r9, QWORD PTR [rdx+256] + mov QWORD PTR [rcx+248], r10 + sbb r9, QWORD PTR [r8+256] + mov r10, QWORD PTR [rdx+264] + mov QWORD PTR [rcx+256], r9 + sbb r10, QWORD PTR [r8+264] + mov r9, QWORD PTR [rdx+272] + mov QWORD PTR [rcx+264], r10 + sbb r9, QWORD PTR [r8+272] + mov r10, QWORD PTR [rdx+280] + mov QWORD PTR [rcx+272], r9 + sbb r10, QWORD PTR [r8+280] + mov r9, QWORD PTR [rdx+288] + mov QWORD PTR [rcx+280], r10 + sbb r9, QWORD PTR [r8+288] + mov r10, QWORD PTR [rdx+296] + mov QWORD PTR [rcx+288], r9 + sbb r10, QWORD PTR [r8+296] + mov r9, QWORD PTR [rdx+304] + mov QWORD PTR [rcx+296], r10 + sbb r9, QWORD PTR [r8+304] + mov r10, QWORD PTR [rdx+312] + mov QWORD PTR [rcx+304], r9 + sbb r10, QWORD PTR [r8+312] + mov r9, QWORD PTR [rdx+320] + mov QWORD PTR [rcx+312], r10 + sbb r9, QWORD PTR [r8+320] + mov r10, QWORD PTR [rdx+328] + mov QWORD PTR [rcx+320], r9 + sbb r10, QWORD PTR [r8+328] + mov r9, QWORD PTR [rdx+336] + mov QWORD PTR [rcx+328], r10 + sbb r9, QWORD PTR [r8+336] + mov r10, QWORD PTR [rdx+344] + mov QWORD PTR [rcx+336], r9 + sbb r10, QWORD PTR [r8+344] + mov r9, QWORD PTR [rdx+352] + mov QWORD PTR [rcx+344], r10 + sbb r9, QWORD PTR [r8+352] + mov r10, QWORD PTR [rdx+360] + mov QWORD PTR [rcx+352], r9 + sbb r10, QWORD PTR [r8+360] + mov r9, QWORD PTR [rdx+368] + mov QWORD PTR [rcx+360], r10 + sbb r9, QWORD PTR [r8+368] + mov r10, QWORD PTR [rdx+376] + mov QWORD PTR [rcx+368], r9 + sbb r10, QWORD PTR [r8+376] + mov r9, QWORD PTR [rdx+384] + mov QWORD PTR [rcx+376], r10 + sbb r9, QWORD PTR [r8+384] + mov r10, QWORD PTR [rdx+392] + mov QWORD PTR [rcx+384], r9 + sbb r10, QWORD PTR [r8+392] + mov r9, QWORD PTR [rdx+400] + mov QWORD PTR [rcx+392], r10 + sbb r9, QWORD PTR [r8+400] + mov r10, QWORD PTR [rdx+408] + mov QWORD PTR [rcx+400], r9 + sbb r10, QWORD PTR [r8+408] + mov r9, QWORD PTR [rdx+416] + mov QWORD PTR [rcx+408], r10 + sbb r9, QWORD PTR [r8+416] + mov r10, QWORD PTR [rdx+424] + mov QWORD PTR [rcx+416], r9 + sbb r10, QWORD PTR [r8+424] + mov r9, QWORD PTR [rdx+432] + mov QWORD PTR [rcx+424], r10 + sbb r9, QWORD PTR [r8+432] + mov r10, QWORD PTR [rdx+440] + mov QWORD PTR [rcx+432], r9 + sbb r10, QWORD PTR [r8+440] + mov r9, QWORD PTR [rdx+448] + mov QWORD PTR [rcx+440], r10 + sbb r9, QWORD PTR [r8+448] + mov r10, QWORD PTR [rdx+456] + mov QWORD PTR [rcx+448], r9 + sbb r10, QWORD PTR [r8+456] + mov r9, QWORD PTR [rdx+464] + mov QWORD PTR [rcx+456], r10 + sbb r9, QWORD PTR [r8+464] + mov r10, QWORD PTR [rdx+472] + mov QWORD PTR [rcx+464], r9 + sbb r10, QWORD PTR [r8+472] + mov r9, QWORD PTR [rdx+480] + mov QWORD PTR [rcx+472], r10 + sbb r9, QWORD PTR [r8+480] + mov r10, QWORD PTR [rdx+488] + mov QWORD PTR [rcx+480], r9 + sbb r10, QWORD PTR [r8+488] + mov r9, QWORD PTR [rdx+496] + mov QWORD PTR [rcx+488], r10 + sbb r9, QWORD PTR [r8+496] + mov r10, QWORD PTR [rdx+504] + mov QWORD PTR [rcx+496], r9 + sbb r10, QWORD PTR [r8+504] + mov QWORD PTR [rcx+504], r10 + sbb rax, 0 + ret +sp_4096_sub_64 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Reduce the number back to 4096 bits using Montgomery reduction. +; * +; * a A single precision number to reduce in place. +; * m The single precision number representing the modulus. +; * mp The digit representing the negative inverse of m mod 2^n. +; */ +_text SEGMENT READONLY PARA +sp_4096_mont_reduce_avx2_64 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + push rbx + push rbp + mov r9, rcx + mov r10, rdx + xor rbp, rbp + ; i = 64 + mov r11, 64 + mov r15, QWORD PTR [r9] + mov rdi, QWORD PTR [r9+8] + mov rsi, QWORD PTR [r9+16] + mov rbx, QWORD PTR [r9+24] + add r9, 256 + xor rbp, rbp +L_4096_mont_loop_avx2_64: + ; mu = a[i] * mp + mov rdx, r15 + mov r12, r15 + imul rdx, r8 + xor r14, r14 + ; a[i+0] += m[0] * mu + mulx rcx, rax, QWORD PTR [r10] + mov r15, rdi + adcx r12, rax + adox r15, rcx + ; a[i+1] += m[1] * mu + mulx rcx, rax, QWORD PTR [r10+8] + mov rdi, rsi + adcx r15, rax + adox rdi, rcx + ; a[i+2] += m[2] * mu + mulx rcx, rax, QWORD PTR [r10+16] + mov rsi, rbx + adcx rdi, rax + adox rsi, rcx + ; a[i+3] += m[3] * mu + mulx rcx, rax, QWORD PTR [r10+24] + mov rbx, QWORD PTR [r9+-224] + adcx rsi, rax + adox rbx, rcx + ; a[i+4] += m[4] * mu + mulx rcx, rax, QWORD PTR [r10+32] + mov r13, QWORD PTR [r9+-216] + adcx rbx, rax + adox r13, rcx + ; a[i+5] += m[5] * mu + mulx rcx, rax, QWORD PTR [r10+40] + mov r12, QWORD PTR [r9+-208] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-216], r13 + ; a[i+6] += m[6] * mu + mulx rcx, rax, QWORD PTR [r10+48] + mov r13, QWORD PTR [r9+-200] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-208], r12 + ; a[i+7] += m[7] * mu + mulx rcx, rax, QWORD PTR [r10+56] + mov r12, QWORD PTR [r9+-192] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-200], r13 + ; a[i+8] += m[8] * mu + mulx rcx, rax, QWORD PTR [r10+64] + mov r13, QWORD PTR [r9+-184] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-192], r12 + ; a[i+9] += m[9] * mu + mulx rcx, rax, QWORD PTR [r10+72] + mov r12, QWORD PTR [r9+-176] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-184], r13 + ; a[i+10] += m[10] * mu + mulx rcx, rax, QWORD PTR [r10+80] + mov r13, QWORD PTR [r9+-168] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-176], r12 + ; a[i+11] += m[11] * mu + mulx rcx, rax, QWORD PTR [r10+88] + mov r12, QWORD PTR [r9+-160] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-168], r13 + ; a[i+12] += m[12] * mu + mulx rcx, rax, QWORD PTR [r10+96] + mov r13, QWORD PTR [r9+-152] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-160], r12 + ; a[i+13] += m[13] * mu + mulx rcx, rax, QWORD PTR [r10+104] + mov r12, QWORD PTR [r9+-144] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-152], r13 + ; a[i+14] += m[14] * mu + mulx rcx, rax, QWORD PTR [r10+112] + mov r13, QWORD PTR [r9+-136] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-144], r12 + ; a[i+15] += m[15] * mu + mulx rcx, rax, QWORD PTR [r10+120] + mov r12, QWORD PTR [r9+-128] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-136], r13 + ; a[i+16] += m[16] * mu + mulx rcx, rax, QWORD PTR [r10+128] + mov r13, QWORD PTR [r9+-120] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-128], r12 + ; a[i+17] += m[17] * mu + mulx rcx, rax, QWORD PTR [r10+136] + mov r12, QWORD PTR [r9+-112] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-120], r13 + ; a[i+18] += m[18] * mu + mulx rcx, rax, QWORD PTR [r10+144] + mov r13, QWORD PTR [r9+-104] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-112], r12 + ; a[i+19] += m[19] * mu + mulx rcx, rax, QWORD PTR [r10+152] + mov r12, QWORD PTR [r9+-96] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-104], r13 + ; a[i+20] += m[20] * mu + mulx rcx, rax, QWORD PTR [r10+160] + mov r13, QWORD PTR [r9+-88] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-96], r12 + ; a[i+21] += m[21] * mu + mulx rcx, rax, QWORD PTR [r10+168] + mov r12, QWORD PTR [r9+-80] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-88], r13 + ; a[i+22] += m[22] * mu + mulx rcx, rax, QWORD PTR [r10+176] + mov r13, QWORD PTR [r9+-72] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-80], r12 + ; a[i+23] += m[23] * mu + mulx rcx, rax, QWORD PTR [r10+184] + mov r12, QWORD PTR [r9+-64] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-72], r13 + ; a[i+24] += m[24] * mu + mulx rcx, rax, QWORD PTR [r10+192] + mov r13, QWORD PTR [r9+-56] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-64], r12 + ; a[i+25] += m[25] * mu + mulx rcx, rax, QWORD PTR [r10+200] + mov r12, QWORD PTR [r9+-48] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-56], r13 + ; a[i+26] += m[26] * mu + mulx rcx, rax, QWORD PTR [r10+208] + mov r13, QWORD PTR [r9+-40] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-48], r12 + ; a[i+27] += m[27] * mu + mulx rcx, rax, QWORD PTR [r10+216] + mov r12, QWORD PTR [r9+-32] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-40], r13 + ; a[i+28] += m[28] * mu + mulx rcx, rax, QWORD PTR [r10+224] + mov r13, QWORD PTR [r9+-24] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-32], r12 + ; a[i+29] += m[29] * mu + mulx rcx, rax, QWORD PTR [r10+232] + mov r12, QWORD PTR [r9+-16] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-24], r13 + ; a[i+30] += m[30] * mu + mulx rcx, rax, QWORD PTR [r10+240] + mov r13, QWORD PTR [r9+-8] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-16], r12 + ; a[i+31] += m[31] * mu + mulx rcx, rax, QWORD PTR [r10+248] + mov r12, QWORD PTR [r9] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-8], r13 + ; a[i+32] += m[32] * mu + mulx rcx, rax, QWORD PTR [r10+256] + mov r13, QWORD PTR [r9+8] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9], r12 + ; a[i+33] += m[33] * mu + mulx rcx, rax, QWORD PTR [r10+264] + mov r12, QWORD PTR [r9+16] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+8], r13 + ; a[i+34] += m[34] * mu + mulx rcx, rax, QWORD PTR [r10+272] + mov r13, QWORD PTR [r9+24] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+16], r12 + ; a[i+35] += m[35] * mu + mulx rcx, rax, QWORD PTR [r10+280] + mov r12, QWORD PTR [r9+32] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+24], r13 + ; a[i+36] += m[36] * mu + mulx rcx, rax, QWORD PTR [r10+288] + mov r13, QWORD PTR [r9+40] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+32], r12 + ; a[i+37] += m[37] * mu + mulx rcx, rax, QWORD PTR [r10+296] + mov r12, QWORD PTR [r9+48] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+40], r13 + ; a[i+38] += m[38] * mu + mulx rcx, rax, QWORD PTR [r10+304] + mov r13, QWORD PTR [r9+56] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+48], r12 + ; a[i+39] += m[39] * mu + mulx rcx, rax, QWORD PTR [r10+312] + mov r12, QWORD PTR [r9+64] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+56], r13 + ; a[i+40] += m[40] * mu + mulx rcx, rax, QWORD PTR [r10+320] + mov r13, QWORD PTR [r9+72] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+64], r12 + ; a[i+41] += m[41] * mu + mulx rcx, rax, QWORD PTR [r10+328] + mov r12, QWORD PTR [r9+80] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+72], r13 + ; a[i+42] += m[42] * mu + mulx rcx, rax, QWORD PTR [r10+336] + mov r13, QWORD PTR [r9+88] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+80], r12 + ; a[i+43] += m[43] * mu + mulx rcx, rax, QWORD PTR [r10+344] + mov r12, QWORD PTR [r9+96] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+88], r13 + ; a[i+44] += m[44] * mu + mulx rcx, rax, QWORD PTR [r10+352] + mov r13, QWORD PTR [r9+104] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+96], r12 + ; a[i+45] += m[45] * mu + mulx rcx, rax, QWORD PTR [r10+360] + mov r12, QWORD PTR [r9+112] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+104], r13 + ; a[i+46] += m[46] * mu + mulx rcx, rax, QWORD PTR [r10+368] + mov r13, QWORD PTR [r9+120] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+112], r12 + ; a[i+47] += m[47] * mu + mulx rcx, rax, QWORD PTR [r10+376] + mov r12, QWORD PTR [r9+128] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+120], r13 + ; a[i+48] += m[48] * mu + mulx rcx, rax, QWORD PTR [r10+384] + mov r13, QWORD PTR [r9+136] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+128], r12 + ; a[i+49] += m[49] * mu + mulx rcx, rax, QWORD PTR [r10+392] + mov r12, QWORD PTR [r9+144] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+136], r13 + ; a[i+50] += m[50] * mu + mulx rcx, rax, QWORD PTR [r10+400] + mov r13, QWORD PTR [r9+152] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+144], r12 + ; a[i+51] += m[51] * mu + mulx rcx, rax, QWORD PTR [r10+408] + mov r12, QWORD PTR [r9+160] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+152], r13 + ; a[i+52] += m[52] * mu + mulx rcx, rax, QWORD PTR [r10+416] + mov r13, QWORD PTR [r9+168] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+160], r12 + ; a[i+53] += m[53] * mu + mulx rcx, rax, QWORD PTR [r10+424] + mov r12, QWORD PTR [r9+176] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+168], r13 + ; a[i+54] += m[54] * mu + mulx rcx, rax, QWORD PTR [r10+432] + mov r13, QWORD PTR [r9+184] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+176], r12 + ; a[i+55] += m[55] * mu + mulx rcx, rax, QWORD PTR [r10+440] + mov r12, QWORD PTR [r9+192] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+184], r13 + ; a[i+56] += m[56] * mu + mulx rcx, rax, QWORD PTR [r10+448] + mov r13, QWORD PTR [r9+200] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+192], r12 + ; a[i+57] += m[57] * mu + mulx rcx, rax, QWORD PTR [r10+456] + mov r12, QWORD PTR [r9+208] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+200], r13 + ; a[i+58] += m[58] * mu + mulx rcx, rax, QWORD PTR [r10+464] + mov r13, QWORD PTR [r9+216] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+208], r12 + ; a[i+59] += m[59] * mu + mulx rcx, rax, QWORD PTR [r10+472] + mov r12, QWORD PTR [r9+224] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+216], r13 + ; a[i+60] += m[60] * mu + mulx rcx, rax, QWORD PTR [r10+480] + mov r13, QWORD PTR [r9+232] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+224], r12 + ; a[i+61] += m[61] * mu + mulx rcx, rax, QWORD PTR [r10+488] + mov r12, QWORD PTR [r9+240] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+232], r13 + ; a[i+62] += m[62] * mu + mulx rcx, rax, QWORD PTR [r10+496] + mov r13, QWORD PTR [r9+248] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+240], r12 + ; a[i+63] += m[63] * mu + mulx rcx, rax, QWORD PTR [r10+504] + mov r12, QWORD PTR [r9+256] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+248], r13 + adcx r12, rbp + mov rbp, r14 + mov QWORD PTR [r9+256], r12 + adox rbp, r14 + adcx rbp, r14 + ; a += 1 + add r9, 8 + ; i -= 1 + sub r11, 1 + jnz L_4096_mont_loop_avx2_64 + sub r9, 256 + neg rbp + mov r8, r9 + sub r9, 512 + mov rcx, QWORD PTR [r10] + mov rdx, r15 + pext rcx, rcx, rbp + sub rdx, rcx + mov rcx, QWORD PTR [r10+8] + mov rax, rdi + pext rcx, rcx, rbp + mov QWORD PTR [r9], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+16] + mov rcx, rsi + pext rdx, rdx, rbp + mov QWORD PTR [r9+8], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+24] + mov rdx, rbx + pext rax, rax, rbp + mov QWORD PTR [r9+16], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+32] + mov rax, QWORD PTR [r8+32] + pext rcx, rcx, rbp + mov QWORD PTR [r9+24], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+40] + mov rcx, QWORD PTR [r8+40] + pext rdx, rdx, rbp + mov QWORD PTR [r9+32], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+48] + mov rdx, QWORD PTR [r8+48] + pext rax, rax, rbp + mov QWORD PTR [r9+40], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+56] + mov rax, QWORD PTR [r8+56] + pext rcx, rcx, rbp + mov QWORD PTR [r9+48], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+64] + mov rcx, QWORD PTR [r8+64] + pext rdx, rdx, rbp + mov QWORD PTR [r9+56], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+72] + mov rdx, QWORD PTR [r8+72] + pext rax, rax, rbp + mov QWORD PTR [r9+64], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+80] + mov rax, QWORD PTR [r8+80] + pext rcx, rcx, rbp + mov QWORD PTR [r9+72], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+88] + mov rcx, QWORD PTR [r8+88] + pext rdx, rdx, rbp + mov QWORD PTR [r9+80], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+96] + mov rdx, QWORD PTR [r8+96] + pext rax, rax, rbp + mov QWORD PTR [r9+88], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+104] + mov rax, QWORD PTR [r8+104] + pext rcx, rcx, rbp + mov QWORD PTR [r9+96], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+112] + mov rcx, QWORD PTR [r8+112] + pext rdx, rdx, rbp + mov QWORD PTR [r9+104], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+120] + mov rdx, QWORD PTR [r8+120] + pext rax, rax, rbp + mov QWORD PTR [r9+112], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+128] + mov rax, QWORD PTR [r8+128] + pext rcx, rcx, rbp + mov QWORD PTR [r9+120], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+136] + mov rcx, QWORD PTR [r8+136] + pext rdx, rdx, rbp + mov QWORD PTR [r9+128], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+144] + mov rdx, QWORD PTR [r8+144] + pext rax, rax, rbp + mov QWORD PTR [r9+136], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+152] + mov rax, QWORD PTR [r8+152] + pext rcx, rcx, rbp + mov QWORD PTR [r9+144], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+160] + mov rcx, QWORD PTR [r8+160] + pext rdx, rdx, rbp + mov QWORD PTR [r9+152], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+168] + mov rdx, QWORD PTR [r8+168] + pext rax, rax, rbp + mov QWORD PTR [r9+160], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+176] + mov rax, QWORD PTR [r8+176] + pext rcx, rcx, rbp + mov QWORD PTR [r9+168], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+184] + mov rcx, QWORD PTR [r8+184] + pext rdx, rdx, rbp + mov QWORD PTR [r9+176], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+192] + mov rdx, QWORD PTR [r8+192] + pext rax, rax, rbp + mov QWORD PTR [r9+184], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+200] + mov rax, QWORD PTR [r8+200] + pext rcx, rcx, rbp + mov QWORD PTR [r9+192], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+208] + mov rcx, QWORD PTR [r8+208] + pext rdx, rdx, rbp + mov QWORD PTR [r9+200], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+216] + mov rdx, QWORD PTR [r8+216] + pext rax, rax, rbp + mov QWORD PTR [r9+208], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+224] + mov rax, QWORD PTR [r8+224] + pext rcx, rcx, rbp + mov QWORD PTR [r9+216], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+232] + mov rcx, QWORD PTR [r8+232] + pext rdx, rdx, rbp + mov QWORD PTR [r9+224], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+240] + mov rdx, QWORD PTR [r8+240] + pext rax, rax, rbp + mov QWORD PTR [r9+232], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+248] + mov rax, QWORD PTR [r8+248] + pext rcx, rcx, rbp + mov QWORD PTR [r9+240], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+256] + mov rcx, QWORD PTR [r8+256] + pext rdx, rdx, rbp + mov QWORD PTR [r9+248], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+264] + mov rdx, QWORD PTR [r8+264] + pext rax, rax, rbp + mov QWORD PTR [r9+256], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+272] + mov rax, QWORD PTR [r8+272] + pext rcx, rcx, rbp + mov QWORD PTR [r9+264], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+280] + mov rcx, QWORD PTR [r8+280] + pext rdx, rdx, rbp + mov QWORD PTR [r9+272], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+288] + mov rdx, QWORD PTR [r8+288] + pext rax, rax, rbp + mov QWORD PTR [r9+280], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+296] + mov rax, QWORD PTR [r8+296] + pext rcx, rcx, rbp + mov QWORD PTR [r9+288], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+304] + mov rcx, QWORD PTR [r8+304] + pext rdx, rdx, rbp + mov QWORD PTR [r9+296], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+312] + mov rdx, QWORD PTR [r8+312] + pext rax, rax, rbp + mov QWORD PTR [r9+304], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+320] + mov rax, QWORD PTR [r8+320] + pext rcx, rcx, rbp + mov QWORD PTR [r9+312], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+328] + mov rcx, QWORD PTR [r8+328] + pext rdx, rdx, rbp + mov QWORD PTR [r9+320], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+336] + mov rdx, QWORD PTR [r8+336] + pext rax, rax, rbp + mov QWORD PTR [r9+328], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+344] + mov rax, QWORD PTR [r8+344] + pext rcx, rcx, rbp + mov QWORD PTR [r9+336], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+352] + mov rcx, QWORD PTR [r8+352] + pext rdx, rdx, rbp + mov QWORD PTR [r9+344], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+360] + mov rdx, QWORD PTR [r8+360] + pext rax, rax, rbp + mov QWORD PTR [r9+352], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+368] + mov rax, QWORD PTR [r8+368] + pext rcx, rcx, rbp + mov QWORD PTR [r9+360], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+376] + mov rcx, QWORD PTR [r8+376] + pext rdx, rdx, rbp + mov QWORD PTR [r9+368], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+384] + mov rdx, QWORD PTR [r8+384] + pext rax, rax, rbp + mov QWORD PTR [r9+376], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+392] + mov rax, QWORD PTR [r8+392] + pext rcx, rcx, rbp + mov QWORD PTR [r9+384], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+400] + mov rcx, QWORD PTR [r8+400] + pext rdx, rdx, rbp + mov QWORD PTR [r9+392], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+408] + mov rdx, QWORD PTR [r8+408] + pext rax, rax, rbp + mov QWORD PTR [r9+400], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+416] + mov rax, QWORD PTR [r8+416] + pext rcx, rcx, rbp + mov QWORD PTR [r9+408], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+424] + mov rcx, QWORD PTR [r8+424] + pext rdx, rdx, rbp + mov QWORD PTR [r9+416], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+432] + mov rdx, QWORD PTR [r8+432] + pext rax, rax, rbp + mov QWORD PTR [r9+424], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+440] + mov rax, QWORD PTR [r8+440] + pext rcx, rcx, rbp + mov QWORD PTR [r9+432], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+448] + mov rcx, QWORD PTR [r8+448] + pext rdx, rdx, rbp + mov QWORD PTR [r9+440], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+456] + mov rdx, QWORD PTR [r8+456] + pext rax, rax, rbp + mov QWORD PTR [r9+448], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+464] + mov rax, QWORD PTR [r8+464] + pext rcx, rcx, rbp + mov QWORD PTR [r9+456], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+472] + mov rcx, QWORD PTR [r8+472] + pext rdx, rdx, rbp + mov QWORD PTR [r9+464], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+480] + mov rdx, QWORD PTR [r8+480] + pext rax, rax, rbp + mov QWORD PTR [r9+472], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+488] + mov rax, QWORD PTR [r8+488] + pext rcx, rcx, rbp + mov QWORD PTR [r9+480], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+496] + mov rcx, QWORD PTR [r8+496] + pext rdx, rdx, rbp + mov QWORD PTR [r9+488], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+504] + mov rdx, QWORD PTR [r8+504] + pext rax, rax, rbp + mov QWORD PTR [r9+496], rcx + sbb rdx, rax + mov QWORD PTR [r9+504], rdx + pop rbp + pop rbx + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_4096_mont_reduce_avx2_64 ENDP +_text ENDS +ENDIF +; /* Conditionally add a and b using the mask m. +; * m is -1 to add and 0 when not. +; * +; * r A single precision number representing conditional add result. +; * a A single precision number to add with. +; * b A single precision number to add. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_4096_cond_add_32 PROC + sub rsp, 256 + mov rax, 0 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp], r10 + mov QWORD PTR [rsp+8], r11 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+16], r10 + mov QWORD PTR [rsp+24], r11 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+32], r10 + mov QWORD PTR [rsp+40], r11 + mov r10, QWORD PTR [r8+48] + mov r11, QWORD PTR [r8+56] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+48], r10 + mov QWORD PTR [rsp+56], r11 + mov r10, QWORD PTR [r8+64] + mov r11, QWORD PTR [r8+72] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+64], r10 + mov QWORD PTR [rsp+72], r11 + mov r10, QWORD PTR [r8+80] + mov r11, QWORD PTR [r8+88] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+80], r10 + mov QWORD PTR [rsp+88], r11 + mov r10, QWORD PTR [r8+96] + mov r11, QWORD PTR [r8+104] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+96], r10 + mov QWORD PTR [rsp+104], r11 + mov r10, QWORD PTR [r8+112] + mov r11, QWORD PTR [r8+120] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+112], r10 + mov QWORD PTR [rsp+120], r11 + mov r10, QWORD PTR [r8+128] + mov r11, QWORD PTR [r8+136] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+128], r10 + mov QWORD PTR [rsp+136], r11 + mov r10, QWORD PTR [r8+144] + mov r11, QWORD PTR [r8+152] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+144], r10 + mov QWORD PTR [rsp+152], r11 + mov r10, QWORD PTR [r8+160] + mov r11, QWORD PTR [r8+168] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+160], r10 + mov QWORD PTR [rsp+168], r11 + mov r10, QWORD PTR [r8+176] + mov r11, QWORD PTR [r8+184] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+176], r10 + mov QWORD PTR [rsp+184], r11 + mov r10, QWORD PTR [r8+192] + mov r11, QWORD PTR [r8+200] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+192], r10 + mov QWORD PTR [rsp+200], r11 + mov r10, QWORD PTR [r8+208] + mov r11, QWORD PTR [r8+216] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+208], r10 + mov QWORD PTR [rsp+216], r11 + mov r10, QWORD PTR [r8+224] + mov r11, QWORD PTR [r8+232] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+224], r10 + mov QWORD PTR [rsp+232], r11 + mov r10, QWORD PTR [r8+240] + mov r11, QWORD PTR [r8+248] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+240], r10 + mov QWORD PTR [rsp+248], r11 + mov r10, QWORD PTR [rdx] + mov r8, QWORD PTR [rsp] + add r10, r8 + mov r11, QWORD PTR [rdx+8] + mov r8, QWORD PTR [rsp+8] + adc r11, r8 + mov QWORD PTR [rcx], r10 + mov r10, QWORD PTR [rdx+16] + mov r8, QWORD PTR [rsp+16] + adc r10, r8 + mov QWORD PTR [rcx+8], r11 + mov r11, QWORD PTR [rdx+24] + mov r8, QWORD PTR [rsp+24] + adc r11, r8 + mov QWORD PTR [rcx+16], r10 + mov r10, QWORD PTR [rdx+32] + mov r8, QWORD PTR [rsp+32] + adc r10, r8 + mov QWORD PTR [rcx+24], r11 + mov r11, QWORD PTR [rdx+40] + mov r8, QWORD PTR [rsp+40] + adc r11, r8 + mov QWORD PTR [rcx+32], r10 + mov r10, QWORD PTR [rdx+48] + mov r8, QWORD PTR [rsp+48] + adc r10, r8 + mov QWORD PTR [rcx+40], r11 + mov r11, QWORD PTR [rdx+56] + mov r8, QWORD PTR [rsp+56] + adc r11, r8 + mov QWORD PTR [rcx+48], r10 + mov r10, QWORD PTR [rdx+64] + mov r8, QWORD PTR [rsp+64] + adc r10, r8 + mov QWORD PTR [rcx+56], r11 + mov r11, QWORD PTR [rdx+72] + mov r8, QWORD PTR [rsp+72] + adc r11, r8 + mov QWORD PTR [rcx+64], r10 + mov r10, QWORD PTR [rdx+80] + mov r8, QWORD PTR [rsp+80] + adc r10, r8 + mov QWORD PTR [rcx+72], r11 + mov r11, QWORD PTR [rdx+88] + mov r8, QWORD PTR [rsp+88] + adc r11, r8 + mov QWORD PTR [rcx+80], r10 + mov r10, QWORD PTR [rdx+96] + mov r8, QWORD PTR [rsp+96] + adc r10, r8 + mov QWORD PTR [rcx+88], r11 + mov r11, QWORD PTR [rdx+104] + mov r8, QWORD PTR [rsp+104] + adc r11, r8 + mov QWORD PTR [rcx+96], r10 + mov r10, QWORD PTR [rdx+112] + mov r8, QWORD PTR [rsp+112] + adc r10, r8 + mov QWORD PTR [rcx+104], r11 + mov r11, QWORD PTR [rdx+120] + mov r8, QWORD PTR [rsp+120] + adc r11, r8 + mov QWORD PTR [rcx+112], r10 + mov r10, QWORD PTR [rdx+128] + mov r8, QWORD PTR [rsp+128] + adc r10, r8 + mov QWORD PTR [rcx+120], r11 + mov r11, QWORD PTR [rdx+136] + mov r8, QWORD PTR [rsp+136] + adc r11, r8 + mov QWORD PTR [rcx+128], r10 + mov r10, QWORD PTR [rdx+144] + mov r8, QWORD PTR [rsp+144] + adc r10, r8 + mov QWORD PTR [rcx+136], r11 + mov r11, QWORD PTR [rdx+152] + mov r8, QWORD PTR [rsp+152] + adc r11, r8 + mov QWORD PTR [rcx+144], r10 + mov r10, QWORD PTR [rdx+160] + mov r8, QWORD PTR [rsp+160] + adc r10, r8 + mov QWORD PTR [rcx+152], r11 + mov r11, QWORD PTR [rdx+168] + mov r8, QWORD PTR [rsp+168] + adc r11, r8 + mov QWORD PTR [rcx+160], r10 + mov r10, QWORD PTR [rdx+176] + mov r8, QWORD PTR [rsp+176] + adc r10, r8 + mov QWORD PTR [rcx+168], r11 + mov r11, QWORD PTR [rdx+184] + mov r8, QWORD PTR [rsp+184] + adc r11, r8 + mov QWORD PTR [rcx+176], r10 + mov r10, QWORD PTR [rdx+192] + mov r8, QWORD PTR [rsp+192] + adc r10, r8 + mov QWORD PTR [rcx+184], r11 + mov r11, QWORD PTR [rdx+200] + mov r8, QWORD PTR [rsp+200] + adc r11, r8 + mov QWORD PTR [rcx+192], r10 + mov r10, QWORD PTR [rdx+208] + mov r8, QWORD PTR [rsp+208] + adc r10, r8 + mov QWORD PTR [rcx+200], r11 + mov r11, QWORD PTR [rdx+216] + mov r8, QWORD PTR [rsp+216] + adc r11, r8 + mov QWORD PTR [rcx+208], r10 + mov r10, QWORD PTR [rdx+224] + mov r8, QWORD PTR [rsp+224] + adc r10, r8 + mov QWORD PTR [rcx+216], r11 + mov r11, QWORD PTR [rdx+232] + mov r8, QWORD PTR [rsp+232] + adc r11, r8 + mov QWORD PTR [rcx+224], r10 + mov r10, QWORD PTR [rdx+240] + mov r8, QWORD PTR [rsp+240] + adc r10, r8 + mov QWORD PTR [rcx+232], r11 + mov r11, QWORD PTR [rdx+248] + mov r8, QWORD PTR [rsp+248] + adc r11, r8 + mov QWORD PTR [rcx+240], r10 + mov QWORD PTR [rcx+248], r11 + adc rax, 0 + add rsp, 256 + ret +sp_4096_cond_add_32 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Conditionally add a and b using the mask m. +; * m is -1 to add and 0 when not. +; * +; * r A single precision number representing conditional add result. +; * a A single precision number to add with. +; * b A single precision number to add. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_4096_cond_add_avx2_32 PROC + push r12 + mov rax, 0 + mov r12, QWORD PTR [r8] + mov r10, QWORD PTR [rdx] + pext r12, r12, r9 + add r10, r12 + mov r12, QWORD PTR [r8+8] + mov r11, QWORD PTR [rdx+8] + pext r12, r12, r9 + mov QWORD PTR [rcx], r10 + adc r11, r12 + mov r10, QWORD PTR [r8+16] + mov r12, QWORD PTR [rdx+16] + pext r10, r10, r9 + mov QWORD PTR [rcx+8], r11 + adc r12, r10 + mov r11, QWORD PTR [r8+24] + mov r10, QWORD PTR [rdx+24] + pext r11, r11, r9 + mov QWORD PTR [rcx+16], r12 + adc r10, r11 + mov r12, QWORD PTR [r8+32] + mov r11, QWORD PTR [rdx+32] + pext r12, r12, r9 + mov QWORD PTR [rcx+24], r10 + adc r11, r12 + mov r10, QWORD PTR [r8+40] + mov r12, QWORD PTR [rdx+40] + pext r10, r10, r9 + mov QWORD PTR [rcx+32], r11 + adc r12, r10 + mov r11, QWORD PTR [r8+48] + mov r10, QWORD PTR [rdx+48] + pext r11, r11, r9 + mov QWORD PTR [rcx+40], r12 + adc r10, r11 + mov r12, QWORD PTR [r8+56] + mov r11, QWORD PTR [rdx+56] + pext r12, r12, r9 + mov QWORD PTR [rcx+48], r10 + adc r11, r12 + mov r10, QWORD PTR [r8+64] + mov r12, QWORD PTR [rdx+64] + pext r10, r10, r9 + mov QWORD PTR [rcx+56], r11 + adc r12, r10 + mov r11, QWORD PTR [r8+72] + mov r10, QWORD PTR [rdx+72] + pext r11, r11, r9 + mov QWORD PTR [rcx+64], r12 + adc r10, r11 + mov r12, QWORD PTR [r8+80] + mov r11, QWORD PTR [rdx+80] + pext r12, r12, r9 + mov QWORD PTR [rcx+72], r10 + adc r11, r12 + mov r10, QWORD PTR [r8+88] + mov r12, QWORD PTR [rdx+88] + pext r10, r10, r9 + mov QWORD PTR [rcx+80], r11 + adc r12, r10 + mov r11, QWORD PTR [r8+96] + mov r10, QWORD PTR [rdx+96] + pext r11, r11, r9 + mov QWORD PTR [rcx+88], r12 + adc r10, r11 + mov r12, QWORD PTR [r8+104] + mov r11, QWORD PTR [rdx+104] + pext r12, r12, r9 + mov QWORD PTR [rcx+96], r10 + adc r11, r12 + mov r10, QWORD PTR [r8+112] + mov r12, QWORD PTR [rdx+112] + pext r10, r10, r9 + mov QWORD PTR [rcx+104], r11 + adc r12, r10 + mov r11, QWORD PTR [r8+120] + mov r10, QWORD PTR [rdx+120] + pext r11, r11, r9 + mov QWORD PTR [rcx+112], r12 + adc r10, r11 + mov r12, QWORD PTR [r8+128] + mov r11, QWORD PTR [rdx+128] + pext r12, r12, r9 + mov QWORD PTR [rcx+120], r10 + adc r11, r12 + mov r10, QWORD PTR [r8+136] + mov r12, QWORD PTR [rdx+136] + pext r10, r10, r9 + mov QWORD PTR [rcx+128], r11 + adc r12, r10 + mov r11, QWORD PTR [r8+144] + mov r10, QWORD PTR [rdx+144] + pext r11, r11, r9 + mov QWORD PTR [rcx+136], r12 + adc r10, r11 + mov r12, QWORD PTR [r8+152] + mov r11, QWORD PTR [rdx+152] + pext r12, r12, r9 + mov QWORD PTR [rcx+144], r10 + adc r11, r12 + mov r10, QWORD PTR [r8+160] + mov r12, QWORD PTR [rdx+160] + pext r10, r10, r9 + mov QWORD PTR [rcx+152], r11 + adc r12, r10 + mov r11, QWORD PTR [r8+168] + mov r10, QWORD PTR [rdx+168] + pext r11, r11, r9 + mov QWORD PTR [rcx+160], r12 + adc r10, r11 + mov r12, QWORD PTR [r8+176] + mov r11, QWORD PTR [rdx+176] + pext r12, r12, r9 + mov QWORD PTR [rcx+168], r10 + adc r11, r12 + mov r10, QWORD PTR [r8+184] + mov r12, QWORD PTR [rdx+184] + pext r10, r10, r9 + mov QWORD PTR [rcx+176], r11 + adc r12, r10 + mov r11, QWORD PTR [r8+192] + mov r10, QWORD PTR [rdx+192] + pext r11, r11, r9 + mov QWORD PTR [rcx+184], r12 + adc r10, r11 + mov r12, QWORD PTR [r8+200] + mov r11, QWORD PTR [rdx+200] + pext r12, r12, r9 + mov QWORD PTR [rcx+192], r10 + adc r11, r12 + mov r10, QWORD PTR [r8+208] + mov r12, QWORD PTR [rdx+208] + pext r10, r10, r9 + mov QWORD PTR [rcx+200], r11 + adc r12, r10 + mov r11, QWORD PTR [r8+216] + mov r10, QWORD PTR [rdx+216] + pext r11, r11, r9 + mov QWORD PTR [rcx+208], r12 + adc r10, r11 + mov r12, QWORD PTR [r8+224] + mov r11, QWORD PTR [rdx+224] + pext r12, r12, r9 + mov QWORD PTR [rcx+216], r10 + adc r11, r12 + mov r10, QWORD PTR [r8+232] + mov r12, QWORD PTR [rdx+232] + pext r10, r10, r9 + mov QWORD PTR [rcx+224], r11 + adc r12, r10 + mov r11, QWORD PTR [r8+240] + mov r10, QWORD PTR [rdx+240] + pext r11, r11, r9 + mov QWORD PTR [rcx+232], r12 + adc r10, r11 + mov r12, QWORD PTR [r8+248] + mov r11, QWORD PTR [rdx+248] + pext r12, r12, r9 + mov QWORD PTR [rcx+240], r10 + adc r11, r12 + mov QWORD PTR [rcx+248], r11 + adc rax, 0 + pop r12 + ret +sp_4096_cond_add_avx2_32 ENDP +_text ENDS +ENDIF +; /* Shift number left by n bit. (r = a << n) +; * +; * r Result of left shift by n. +; * a Number to shift. +; * n Amoutnt o shift. +; */ +_text SEGMENT READONLY PARA +sp_4096_lshift_64 PROC + push r12 + push r13 + mov r9, rcx + mov rcx, r8 + mov r12, 0 + mov r13, QWORD PTR [rdx+472] + mov rax, QWORD PTR [rdx+480] + mov r8, QWORD PTR [rdx+488] + mov r10, QWORD PTR [rdx+496] + mov r11, QWORD PTR [rdx+504] + shld r12, r11, cl + shld r11, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r13, cl + mov QWORD PTR [r9+480], rax + mov QWORD PTR [r9+488], r8 + mov QWORD PTR [r9+496], r10 + mov QWORD PTR [r9+504], r11 + mov QWORD PTR [r9+512], r12 + mov r11, QWORD PTR [rdx+440] + mov rax, QWORD PTR [rdx+448] + mov r8, QWORD PTR [rdx+456] + mov r10, QWORD PTR [rdx+464] + shld r13, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r11, cl + mov QWORD PTR [r9+448], rax + mov QWORD PTR [r9+456], r8 + mov QWORD PTR [r9+464], r10 + mov QWORD PTR [r9+472], r13 + mov r13, QWORD PTR [rdx+408] + mov rax, QWORD PTR [rdx+416] + mov r8, QWORD PTR [rdx+424] + mov r10, QWORD PTR [rdx+432] + shld r11, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r13, cl + mov QWORD PTR [r9+416], rax + mov QWORD PTR [r9+424], r8 + mov QWORD PTR [r9+432], r10 + mov QWORD PTR [r9+440], r11 + mov r11, QWORD PTR [rdx+376] + mov rax, QWORD PTR [rdx+384] + mov r8, QWORD PTR [rdx+392] + mov r10, QWORD PTR [rdx+400] + shld r13, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r11, cl + mov QWORD PTR [r9+384], rax + mov QWORD PTR [r9+392], r8 + mov QWORD PTR [r9+400], r10 + mov QWORD PTR [r9+408], r13 + mov r13, QWORD PTR [rdx+344] + mov rax, QWORD PTR [rdx+352] + mov r8, QWORD PTR [rdx+360] + mov r10, QWORD PTR [rdx+368] + shld r11, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r13, cl + mov QWORD PTR [r9+352], rax + mov QWORD PTR [r9+360], r8 + mov QWORD PTR [r9+368], r10 + mov QWORD PTR [r9+376], r11 + mov r11, QWORD PTR [rdx+312] + mov rax, QWORD PTR [rdx+320] + mov r8, QWORD PTR [rdx+328] + mov r10, QWORD PTR [rdx+336] + shld r13, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r11, cl + mov QWORD PTR [r9+320], rax + mov QWORD PTR [r9+328], r8 + mov QWORD PTR [r9+336], r10 + mov QWORD PTR [r9+344], r13 + mov r13, QWORD PTR [rdx+280] + mov rax, QWORD PTR [rdx+288] + mov r8, QWORD PTR [rdx+296] + mov r10, QWORD PTR [rdx+304] + shld r11, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r13, cl + mov QWORD PTR [r9+288], rax + mov QWORD PTR [r9+296], r8 + mov QWORD PTR [r9+304], r10 + mov QWORD PTR [r9+312], r11 + mov r11, QWORD PTR [rdx+248] + mov rax, QWORD PTR [rdx+256] + mov r8, QWORD PTR [rdx+264] + mov r10, QWORD PTR [rdx+272] + shld r13, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r11, cl + mov QWORD PTR [r9+256], rax + mov QWORD PTR [r9+264], r8 + mov QWORD PTR [r9+272], r10 + mov QWORD PTR [r9+280], r13 + mov r13, QWORD PTR [rdx+216] + mov rax, QWORD PTR [rdx+224] + mov r8, QWORD PTR [rdx+232] + mov r10, QWORD PTR [rdx+240] + shld r11, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r13, cl + mov QWORD PTR [r9+224], rax + mov QWORD PTR [r9+232], r8 + mov QWORD PTR [r9+240], r10 + mov QWORD PTR [r9+248], r11 + mov r11, QWORD PTR [rdx+184] + mov rax, QWORD PTR [rdx+192] + mov r8, QWORD PTR [rdx+200] + mov r10, QWORD PTR [rdx+208] + shld r13, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r11, cl + mov QWORD PTR [r9+192], rax + mov QWORD PTR [r9+200], r8 + mov QWORD PTR [r9+208], r10 + mov QWORD PTR [r9+216], r13 + mov r13, QWORD PTR [rdx+152] + mov rax, QWORD PTR [rdx+160] + mov r8, QWORD PTR [rdx+168] + mov r10, QWORD PTR [rdx+176] + shld r11, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r13, cl + mov QWORD PTR [r9+160], rax + mov QWORD PTR [r9+168], r8 + mov QWORD PTR [r9+176], r10 + mov QWORD PTR [r9+184], r11 + mov r11, QWORD PTR [rdx+120] + mov rax, QWORD PTR [rdx+128] + mov r8, QWORD PTR [rdx+136] + mov r10, QWORD PTR [rdx+144] + shld r13, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r11, cl + mov QWORD PTR [r9+128], rax + mov QWORD PTR [r9+136], r8 + mov QWORD PTR [r9+144], r10 + mov QWORD PTR [r9+152], r13 + mov r13, QWORD PTR [rdx+88] + mov rax, QWORD PTR [rdx+96] + mov r8, QWORD PTR [rdx+104] + mov r10, QWORD PTR [rdx+112] + shld r11, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r13, cl + mov QWORD PTR [r9+96], rax + mov QWORD PTR [r9+104], r8 + mov QWORD PTR [r9+112], r10 + mov QWORD PTR [r9+120], r11 + mov r11, QWORD PTR [rdx+56] + mov rax, QWORD PTR [rdx+64] + mov r8, QWORD PTR [rdx+72] + mov r10, QWORD PTR [rdx+80] + shld r13, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r11, cl + mov QWORD PTR [r9+64], rax + mov QWORD PTR [r9+72], r8 + mov QWORD PTR [r9+80], r10 + mov QWORD PTR [r9+88], r13 + mov r13, QWORD PTR [rdx+24] + mov rax, QWORD PTR [rdx+32] + mov r8, QWORD PTR [rdx+40] + mov r10, QWORD PTR [rdx+48] + shld r11, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shld rax, r13, cl + mov QWORD PTR [r9+32], rax + mov QWORD PTR [r9+40], r8 + mov QWORD PTR [r9+48], r10 + mov QWORD PTR [r9+56], r11 + mov rax, QWORD PTR [rdx] + mov r8, QWORD PTR [rdx+8] + mov r10, QWORD PTR [rdx+16] + shld r13, r10, cl + shld r10, r8, cl + shld r8, rax, cl + shl rax, cl + mov QWORD PTR [r9], rax + mov QWORD PTR [r9+8], r8 + mov QWORD PTR [r9+16], r10 + mov QWORD PTR [r9+24], r13 + pop r13 + pop r12 + ret +sp_4096_lshift_64 ENDP +_text ENDS +ENDIF +ENDIF +IFNDEF WOLFSSL_SP_NO_256 +; /* Multiply a and b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_256_mul_4 PROC + push r12 + mov r9, rdx + sub rsp, 32 + ; A[0] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9] + xor r12, r12 + mov QWORD PTR [rsp], rax + mov r11, rdx + ; A[0] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[1] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+8] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rsp+8], r11 + ; A[0] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[1] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+8] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[2] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+16] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rsp+16], r12 + ; A[0] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[1] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+8] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[2] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+16] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[3] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+24] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rsp+24], r10 + ; A[1] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+8] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[2] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+16] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[3] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+24] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rcx+32], r11 + ; A[2] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+16] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[3] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+24] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rcx+40], r12 + ; A[3] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+24] + add r10, rax + adc r11, rdx + mov QWORD PTR [rcx+48], r10 + mov QWORD PTR [rcx+56], r11 + mov rax, QWORD PTR [rsp] + mov rdx, QWORD PTR [rsp+8] + mov r10, QWORD PTR [rsp+16] + mov r11, QWORD PTR [rsp+24] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], rdx + mov QWORD PTR [rcx+16], r10 + mov QWORD PTR [rcx+24], r11 + add rsp, 32 + pop r12 + ret +sp_256_mul_4 ENDP +_text ENDS +; /* Square a and put result in r. (r = a * a) +; * +; * r A single precision integer. +; * a A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_256_sqr_4 PROC + push r12 + push r13 + push r14 + mov r8, rdx + sub rsp, 32 + ; A[0] * A[0] + mov rax, QWORD PTR [r8] + mul rax + xor r11, r11 + mov QWORD PTR [rsp], rax + mov r10, rdx + ; A[0] * A[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r8] + xor r9, r9 + add r10, rax + adc r11, rdx + adc r9, 0 + add r10, rax + adc r11, rdx + adc r9, 0 + mov QWORD PTR [rsp+8], r10 + ; A[0] * A[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r8] + xor r10, r10 + add r11, rax + adc r9, rdx + adc r10, 0 + add r11, rax + adc r9, rdx + adc r10, 0 + ; A[1] * A[1] + mov rax, QWORD PTR [r8+8] + mul rax + add r11, rax + adc r9, rdx + adc r10, 0 + mov QWORD PTR [rsp+16], r11 + ; A[0] * A[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r8] + xor r11, r11 + add r9, rax + adc r10, rdx + adc r11, 0 + add r9, rax + adc r10, rdx + adc r11, 0 + ; A[1] * A[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r8+8] + add r9, rax + adc r10, rdx + adc r11, 0 + add r9, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rsp+24], r9 + ; A[1] * A[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r8+8] + xor r9, r9 + add r10, rax + adc r11, rdx + adc r9, 0 + add r10, rax + adc r11, rdx + adc r9, 0 + ; A[2] * A[2] + mov rax, QWORD PTR [r8+16] + mul rax + add r10, rax + adc r11, rdx + adc r9, 0 + mov QWORD PTR [rcx+32], r10 + ; A[2] * A[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r8+16] + xor r10, r10 + add r11, rax + adc r9, rdx + adc r10, 0 + add r11, rax + adc r9, rdx + adc r10, 0 + mov QWORD PTR [rcx+40], r11 + ; A[3] * A[3] + mov rax, QWORD PTR [r8+24] + mul rax + add r9, rax + adc r10, rdx + mov QWORD PTR [rcx+48], r9 + mov QWORD PTR [rcx+56], r10 + mov rax, QWORD PTR [rsp] + mov rdx, QWORD PTR [rsp+8] + mov r12, QWORD PTR [rsp+16] + mov r13, QWORD PTR [rsp+24] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], rdx + mov QWORD PTR [rcx+16], r12 + mov QWORD PTR [rcx+24], r13 + add rsp, 32 + pop r14 + pop r13 + pop r12 + ret +sp_256_sqr_4 ENDP +_text ENDS +; /* Add b to a into r. (r = a + b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_256_add_4 PROC + ; Add + mov r9, QWORD PTR [rdx] + xor rax, rax + add r9, QWORD PTR [r8] + mov r10, QWORD PTR [rdx+8] + mov QWORD PTR [rcx], r9 + adc r10, QWORD PTR [r8+8] + mov r9, QWORD PTR [rdx+16] + mov QWORD PTR [rcx+8], r10 + adc r9, QWORD PTR [r8+16] + mov r10, QWORD PTR [rdx+24] + mov QWORD PTR [rcx+16], r9 + adc r10, QWORD PTR [r8+24] + mov QWORD PTR [rcx+24], r10 + adc rax, 0 + ret +sp_256_add_4 ENDP +_text ENDS +; /* Sub b from a into r. (r = a - b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_256_sub_4 PROC + push r12 + xor rax, rax + mov r9, QWORD PTR [rdx] + mov r10, QWORD PTR [rdx+8] + mov r11, QWORD PTR [rdx+16] + mov r12, QWORD PTR [rdx+24] + sub r9, QWORD PTR [r8] + sbb r10, QWORD PTR [r8+8] + sbb r11, QWORD PTR [r8+16] + sbb r12, QWORD PTR [r8+24] + mov QWORD PTR [rcx], r9 + mov QWORD PTR [rcx+8], r10 + mov QWORD PTR [rcx+16], r11 + mov QWORD PTR [rcx+24], r12 + sbb rax, 0 + pop r12 + ret +sp_256_sub_4 ENDP +_text ENDS +; /* Conditionally copy a into r using the mask m. +; * m is -1 to copy and 0 when not. +; * +; * r A single precision number to copy over. +; * a A single precision number to copy. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_256_cond_copy_4 PROC + mov rax, QWORD PTR [rcx] + mov r9, QWORD PTR [rcx+8] + mov r10, QWORD PTR [rcx+16] + mov r11, QWORD PTR [rcx+24] + xor rax, QWORD PTR [rdx] + xor r9, QWORD PTR [rdx+8] + xor r10, QWORD PTR [rdx+16] + xor r11, QWORD PTR [rdx+24] + and rax, r8 + and r9, r8 + and r10, r8 + and r11, r8 + xor QWORD PTR [rcx], rax + xor QWORD PTR [rcx+8], r9 + xor QWORD PTR [rcx+16], r10 + xor QWORD PTR [rcx+24], r11 + ret +sp_256_cond_copy_4 ENDP +_text ENDS +; /* Multiply two Montogmery form numbers mod the modulus (prime). +; * (r = a * b mod m) +; * +; * r Result of multiplication. +; * a First number to multiply in Montogmery form. +; * b Second number to multiply in Montogmery form. +; * m Modulus (prime). +; * mp Montogmery mulitplier. +; */ +_text SEGMENT READONLY PARA +sp_256_mont_mul_4 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + push rbx + mov r10, rdx + ; A[0] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r10] + mov r11, rax + mov r12, rdx + ; A[0] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r10] + xor r13, r13 + add r12, rax + adc r13, rdx + ; A[1] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r10+8] + xor r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[0] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r10] + add r13, rax + adc r14, rdx + ; A[1] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r10+8] + xor r15, r15 + add r13, rax + adc r14, rdx + adc r15, 0 + ; A[2] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r10+16] + add r13, rax + adc r14, rdx + adc r15, 0 + ; A[0] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r10] + xor rdi, rdi + add r14, rax + adc r15, rdx + adc rdi, 0 + ; A[1] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r10+8] + add r14, rax + adc r15, rdx + adc rdi, 0 + ; A[2] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r10+16] + add r14, rax + adc r15, rdx + adc rdi, 0 + ; A[3] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r10+24] + add r14, rax + adc r15, rdx + adc rdi, 0 + ; A[1] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r10+8] + xor rsi, rsi + add r15, rax + adc rdi, rdx + adc rsi, 0 + ; A[2] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r10+16] + add r15, rax + adc rdi, rdx + adc rsi, 0 + ; A[3] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r10+24] + add r15, rax + adc rdi, rdx + adc rsi, 0 + ; A[2] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r10+16] + xor rbx, rbx + add rdi, rax + adc rsi, rdx + adc rbx, 0 + ; A[3] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r10+24] + add rdi, rax + adc rsi, rdx + adc rbx, 0 + ; A[3] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r10+24] + add rsi, rax + adc rbx, rdx + ; Start Reduction + ; mu = a[0]-a[3] + a[0]-a[2] << 32 << 64 + (a[0] * 2) << 192 + ; - a[0] << 32 << 192 + ; + (a[0] * 2) << 192 + mov rax, r11 + mov rdx, r14 + add rdx, r11 + mov r10, r12 + add rdx, r11 + mov r8, r13 + ; a[0]-a[2] << 32 + shl r11, 32 + shld r13, r10, 32 + shld r12, rax, 32 + ; - a[0] << 32 << 192 + sub rdx, r11 + ; + a[0]-a[2] << 32 << 64 + add r10, r11 + adc r8, r12 + adc rdx, r13 + ; a += (mu << 256) - (mu << 224) + (mu << 192) + (mu << 96) - mu + ; a += mu << 256 + xor r11, r11 + add r15, rax + adc rdi, r10 + adc rsi, r8 + adc rbx, rdx + sbb r11, 0 + ; a += mu << 192 + add r14, rax + adc r15, r10 + adc rdi, r8 + adc rsi, rdx + adc rbx, 0 + sbb r11, 0 + ; mu <<= 32 + mov r9, rdx + shld rdx, r8, 32 + shld r8, r10, 32 + shld r10, rax, 32 + shr r9, 32 + shl rax, 32 + ; a += (mu << 32) << 64 + add r14, r8 + adc r15, rdx + adc rdi, r9 + adc rsi, 0 + adc rbx, 0 + sbb r11, 0 + ; a -= (mu << 32) << 192 + sub r14, rax + sbb r15, r10 + sbb rdi, r8 + sbb rsi, rdx + sbb rbx, r9 + adc r11, 0 + mov rax, 4294967295 + mov r10, 18446744069414584321 + ; mask m and sub from result if overflow + ; m[0] = -1 & mask = mask + and rax, r11 + ; m[2] = 0 & mask = 0 + and r10, r11 + sub r15, r11 + sbb rdi, rax + sbb rsi, 0 + sbb rbx, r10 + mov QWORD PTR [rcx], r15 + mov QWORD PTR [rcx+8], rdi + mov QWORD PTR [rcx+16], rsi + mov QWORD PTR [rcx+24], rbx + pop rbx + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_256_mont_mul_4 ENDP +_text ENDS +; /* Square the Montgomery form number mod the modulus (prime). (r = a * a mod m) +; * +; * r Result of squaring. +; * a Number to square in Montogmery form. +; * m Modulus (prime). +; * mp Montogmery mulitplier. +; */ +_text SEGMENT READONLY PARA +sp_256_mont_sqr_4 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + push rbx + mov r8, rdx + ; A[0] * A[1] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r8+8] + mov r11, rax + mov r12, rdx + ; A[0] * A[2] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r8+16] + xor r13, r13 + add r12, rax + adc r13, rdx + ; A[0] * A[3] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r8+24] + xor r14, r14 + add r13, rax + adc r14, rdx + ; A[1] * A[2] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r8+16] + xor r15, r15 + add r13, rax + adc r14, rdx + adc r15, 0 + ; A[1] * A[3] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r8+24] + add r14, rax + adc r15, rdx + ; A[2] * A[3] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r8+24] + xor rdi, rdi + add r15, rax + adc rdi, rdx + ; Double + xor rsi, rsi + add r11, r11 + adc r12, r12 + adc r13, r13 + adc r14, r14 + adc r15, r15 + adc rdi, rdi + adc rsi, 0 + ; A[0] * A[0] + mov rax, QWORD PTR [r8] + mul rax + mov rax, rax + mov rdx, rdx + mov r10, rax + mov rbx, rdx + ; A[1] * A[1] + mov rax, QWORD PTR [r8+8] + mul rax + mov rax, rax + mov rdx, rdx + add r11, rbx + adc r12, rax + adc rdx, 0 + mov rbx, rdx + ; A[2] * A[2] + mov rax, QWORD PTR [r8+16] + mul rax + mov rax, rax + mov rdx, rdx + add r13, rbx + adc r14, rax + adc rdx, 0 + mov rbx, rdx + ; A[3] * A[3] + mov rax, QWORD PTR [r8+24] + mul rax + mov rax, rax + mov rdx, rdx + add r15, rbx + adc rdi, rax + adc rsi, rdx + ; Start Reduction + ; mu = a[0]-a[3] + a[0]-a[2] << 32 << 64 + (a[0] * 2) << 192 + ; - a[0] << 32 << 192 + ; + (a[0] * 2) << 192 + mov rax, r10 + mov rdx, r13 + add rdx, r10 + mov r8, r11 + add rdx, r10 + mov rbx, r12 + ; a[0]-a[2] << 32 + shl r10, 32 + shld r12, r8, 32 + shld r11, rax, 32 + ; - a[0] << 32 << 192 + sub rdx, r10 + ; + a[0]-a[2] << 32 << 64 + add r8, r10 + adc rbx, r11 + adc rdx, r12 + ; a += (mu << 256) - (mu << 224) + (mu << 192) + (mu << 96) - mu + ; a += mu << 256 + xor r10, r10 + add r14, rax + adc r15, r8 + adc rdi, rbx + adc rsi, rdx + sbb r10, 0 + ; a += mu << 192 + add r13, rax + adc r14, r8 + adc r15, rbx + adc rdi, rdx + adc rsi, 0 + sbb r10, 0 + ; mu <<= 32 + mov r9, rdx + shld rdx, rbx, 32 + shld rbx, r8, 32 + shld r8, rax, 32 + shr r9, 32 + shl rax, 32 + ; a += (mu << 32) << 64 + add r13, rbx + adc r14, rdx + adc r15, r9 + adc rdi, 0 + adc rsi, 0 + sbb r10, 0 + ; a -= (mu << 32) << 192 + sub r13, rax + sbb r14, r8 + sbb r15, rbx + sbb rdi, rdx + sbb rsi, r9 + adc r10, 0 + mov rax, 4294967295 + mov r8, 18446744069414584321 + ; mask m and sub from result if overflow + ; m[0] = -1 & mask = mask + and rax, r10 + ; m[2] = 0 & mask = 0 + and r8, r10 + sub r14, r10 + sbb r15, rax + sbb rdi, 0 + sbb rsi, r8 + mov QWORD PTR [rcx], r14 + mov QWORD PTR [rcx+8], r15 + mov QWORD PTR [rcx+16], rdi + mov QWORD PTR [rcx+24], rsi + pop rbx + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_256_mont_sqr_4 ENDP +_text ENDS +; /* Compare a with b in constant time. +; * +; * a A single precision integer. +; * b A single precision integer. +; * return -ve, 0 or +ve if a is less than, equal to or greater than b +; * respectively. +; */ +_text SEGMENT READONLY PARA +sp_256_cmp_4 PROC + push r12 + xor r9, r9 + mov r8, -1 + mov rax, -1 + mov r10, 1 + mov r11, QWORD PTR [rcx+24] + mov r12, QWORD PTR [rdx+24] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+16] + mov r12, QWORD PTR [rdx+16] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+8] + mov r12, QWORD PTR [rdx+8] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx] + mov r12, QWORD PTR [rdx] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + xor rax, r8 + pop r12 + ret +sp_256_cmp_4 ENDP +_text ENDS +; /* Conditionally subtract b from a using the mask m. +; * m is -1 to subtract and 0 when not copying. +; * +; * r A single precision number representing condition subtract result. +; * a A single precision number to subtract from. +; * b A single precision number to subtract. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_256_cond_sub_4 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + mov rax, 0 + mov r14, QWORD PTR [r8] + mov r15, QWORD PTR [r8+8] + mov rdi, QWORD PTR [r8+16] + mov rsi, QWORD PTR [r8+24] + and r14, r9 + and r15, r9 + and rdi, r9 + and rsi, r9 + mov r10, QWORD PTR [rdx] + mov r11, QWORD PTR [rdx+8] + mov r12, QWORD PTR [rdx+16] + mov r13, QWORD PTR [rdx+24] + sub r10, r14 + sbb r11, r15 + sbb r12, rdi + sbb r13, rsi + mov QWORD PTR [rcx], r10 + mov QWORD PTR [rcx+8], r11 + mov QWORD PTR [rcx+16], r12 + mov QWORD PTR [rcx+24], r13 + sbb rax, 0 + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_256_cond_sub_4 ENDP +_text ENDS +; /* Reduce the number back to 256 bits using Montgomery reduction. +; * +; * a A single precision number to reduce in place. +; * m The single precision number representing the modulus. +; * mp The digit representing the negative inverse of m mod 2^n. +; */ +_text SEGMENT READONLY PARA +sp_256_mont_reduce_4 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + mov r9, rdx + ; i = 0 + xor rdi, rdi + mov r10, 4 + mov r15, rcx +L_mont_loop_4: + ; mu = a[i] * mp + mov r14, QWORD PTR [r15] + imul r14, r8 + ; a[i+0] += m[0] * mu + mov rax, QWORD PTR [r9] + mov r12, QWORD PTR [r9+8] + mul r14 + mov rsi, QWORD PTR [r15] + add rsi, rax + mov r11, rdx + mov QWORD PTR [r15], rsi + adc r11, 0 + ; a[i+1] += m[1] * mu + mov rax, r12 + mul r14 + mov r12, QWORD PTR [r9+16] + mov rsi, QWORD PTR [r15+8] + add rax, r11 + mov r13, rdx + adc r13, 0 + add rsi, rax + mov QWORD PTR [r15+8], rsi + adc r13, 0 + ; a[i+2] += m[2] * mu + mov rax, r12 + mul r14 + mov r12, QWORD PTR [r9+24] + mov rsi, QWORD PTR [r15+16] + add rax, r13 + mov r11, rdx + adc r11, 0 + add rsi, rax + mov QWORD PTR [r15+16], rsi + adc r11, 0 + ; a[i+3] += m[3] * mu + mov rax, r12 + mul r14 + mov rsi, QWORD PTR [r15+24] + add rax, r11 + adc rdx, rdi + mov rdi, 0 + adc rdi, 0 + add rsi, rax + mov QWORD PTR [r15+24], rsi + adc QWORD PTR [r15+32], rdx + adc rdi, 0 + ; i += 1 + add r15, 8 + dec r10 + jnz L_mont_loop_4 + xor rax, rax + mov rdx, QWORD PTR [rcx+32] + mov r10, QWORD PTR [rcx+40] + mov rsi, QWORD PTR [rcx+48] + mov r11, QWORD PTR [rcx+56] + sub rax, rdi + mov r12, QWORD PTR [r9] + mov r13, QWORD PTR [r9+8] + mov r14, QWORD PTR [r9+16] + mov r15, QWORD PTR [r9+24] + and r12, rax + and r13, rax + and r14, rax + and r15, rax + sub rdx, r12 + sbb r10, r13 + sbb rsi, r14 + sbb r11, r15 + mov QWORD PTR [rcx], rdx + mov QWORD PTR [rcx+8], r10 + mov QWORD PTR [rcx+16], rsi + mov QWORD PTR [rcx+24], r11 + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_256_mont_reduce_4 ENDP +_text ENDS +; /* Add two Montgomery form numbers (r = a + b % m). +; * +; * r Result of addition. +; * a First number to add in Montogmery form. +; * b Second number to add in Montogmery form. +; * m Modulus (prime). +; */ +_text SEGMENT READONLY PARA +sp_256_mont_add_4 PROC + push r12 + push r13 + mov rax, QWORD PTR [rdx] + mov r9, QWORD PTR [rdx+8] + mov r10, QWORD PTR [rdx+16] + mov r11, QWORD PTR [rdx+24] + mov r12, 4294967295 + mov r13, 18446744069414584321 + add rax, QWORD PTR [r8] + adc r9, QWORD PTR [r8+8] + adc r10, QWORD PTR [r8+16] + mov rdx, 0 + adc r11, QWORD PTR [r8+24] + sbb rdx, 0 + and r12, rdx + and r13, rdx + sub rax, rdx + sbb r9, r12 + sbb r10, 0 + sbb r11, r13 + adc rdx, 0 + and r12, rdx + and r13, rdx + sub rax, rdx + sbb r9, r12 + mov QWORD PTR [rcx], rax + sbb r10, 0 + mov QWORD PTR [rcx+8], r9 + sbb r11, r13 + mov QWORD PTR [rcx+16], r10 + mov QWORD PTR [rcx+24], r11 + pop r13 + pop r12 + ret +sp_256_mont_add_4 ENDP +_text ENDS +; /* Double a Montgomery form number (r = a + a % m). +; * +; * r Result of doubling. +; * a Number to double in Montogmery form. +; * m Modulus (prime). +; */ +_text SEGMENT READONLY PARA +sp_256_mont_dbl_4 PROC + push r12 + push r13 + mov rax, QWORD PTR [rdx] + mov r8, QWORD PTR [rdx+8] + mov r9, QWORD PTR [rdx+16] + mov r10, QWORD PTR [rdx+24] + mov r11, 4294967295 + mov r12, 18446744069414584321 + add rax, rax + adc r8, r8 + adc r9, r9 + mov r13, 0 + adc r10, r10 + sbb r13, 0 + and r11, r13 + and r12, r13 + sub rax, r13 + sbb r8, r11 + sbb r9, 0 + sbb r10, r12 + adc r13, 0 + and r11, r13 + and r12, r13 + sub rax, r13 + sbb r8, r11 + mov QWORD PTR [rcx], rax + sbb r9, 0 + mov QWORD PTR [rcx+8], r8 + sbb r10, r12 + mov QWORD PTR [rcx+16], r9 + mov QWORD PTR [rcx+24], r10 + pop r13 + pop r12 + ret +sp_256_mont_dbl_4 ENDP +_text ENDS +; /* Triple a Montgomery form number (r = a + a + a % m). +; * +; * r Result of Tripling. +; * a Number to triple in Montogmery form. +; * m Modulus (prime). +; */ +_text SEGMENT READONLY PARA +sp_256_mont_tpl_4 PROC + push r12 + push r13 + mov rax, QWORD PTR [rdx] + mov r8, QWORD PTR [rdx+8] + mov r9, QWORD PTR [rdx+16] + mov r10, QWORD PTR [rdx+24] + mov r11, 4294967295 + mov r12, 18446744069414584321 + add rax, rax + adc r8, r8 + adc r9, r9 + mov r13, 0 + adc r10, r10 + sbb r13, 0 + and r11, r13 + and r12, r13 + sub rax, r13 + sbb r8, r11 + sbb r9, 0 + sbb r10, r12 + adc r13, 0 + and r11, r13 + and r12, r13 + sub rax, r13 + sbb r8, r11 + sbb r9, 0 + sbb r10, r12 + mov r11, 4294967295 + mov r12, 18446744069414584321 + add rax, QWORD PTR [rdx] + adc r8, QWORD PTR [rdx+8] + adc r9, QWORD PTR [rdx+16] + mov r13, 0 + adc r10, QWORD PTR [rdx+24] + sbb r13, 0 + and r11, r13 + and r12, r13 + sub rax, r13 + sbb r8, r11 + sbb r9, 0 + sbb r10, r12 + adc r13, 0 + and r11, r13 + and r12, r13 + sub rax, r13 + sbb r8, r11 + mov QWORD PTR [rcx], rax + sbb r9, 0 + mov QWORD PTR [rcx+8], r8 + sbb r10, r12 + mov QWORD PTR [rcx+16], r9 + mov QWORD PTR [rcx+24], r10 + pop r13 + pop r12 + ret +sp_256_mont_tpl_4 ENDP +_text ENDS +; /* Subtract two Montgomery form numbers (r = a - b % m). +; * +; * r Result of subtration. +; * a Number to subtract from in Montogmery form. +; * b Number to subtract with in Montogmery form. +; * m Modulus (prime). +; */ +_text SEGMENT READONLY PARA +sp_256_mont_sub_4 PROC + push r12 + push r13 + mov rax, QWORD PTR [rdx] + mov r9, QWORD PTR [rdx+8] + mov r10, QWORD PTR [rdx+16] + mov r11, QWORD PTR [rdx+24] + mov r12, 4294967295 + mov r13, 18446744069414584321 + sub rax, QWORD PTR [r8] + sbb r9, QWORD PTR [r8+8] + sbb r10, QWORD PTR [r8+16] + mov rdx, 0 + sbb r11, QWORD PTR [r8+24] + sbb rdx, 0 + and r12, rdx + and r13, rdx + add rax, rdx + adc r9, r12 + adc r10, 0 + adc r11, r13 + adc rdx, 0 + and r12, rdx + and r13, rdx + add rax, rdx + adc r9, r12 + mov QWORD PTR [rcx], rax + adc r10, 0 + mov QWORD PTR [rcx+8], r9 + adc r11, r13 + mov QWORD PTR [rcx+16], r10 + mov QWORD PTR [rcx+24], r11 + pop r13 + pop r12 + ret +sp_256_mont_sub_4 ENDP +_text ENDS +; /* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m) +; * +; * r Result of division by 2. +; * a Number to divide. +; * m Modulus (prime). +; */ +_text SEGMENT READONLY PARA +sp_256_div2_4 PROC + push r12 + push r13 + mov rax, QWORD PTR [rdx] + mov r8, QWORD PTR [rdx+8] + mov r9, QWORD PTR [rdx+16] + mov r10, QWORD PTR [rdx+24] + mov r11, 4294967295 + mov r12, 18446744069414584321 + mov r13, rax + and r13, 1 + neg r13 + and r11, r13 + and r12, r13 + add rax, r13 + adc r8, r11 + adc r9, 0 + adc r10, r12 + mov r13, 0 + adc r13, 0 + shrd rax, r8, 1 + shrd r8, r9, 1 + shrd r9, r10, 1 + shrd r10, r13, 1 + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r8 + mov QWORD PTR [rcx+16], r9 + mov QWORD PTR [rcx+24], r10 + pop r13 + pop r12 + ret +sp_256_div2_4 ENDP +_text ENDS +IFNDEF WC_NO_CACHE_RESISTANT +; /* Touch each possible point that could be being copied. +; * +; * r Point to copy into. +; * table Table - start of the entires to access +; * idx Index of point to retrieve. +; */ +_text SEGMENT READONLY PARA +sp_256_get_point_33_4 PROC + mov rax, 1 + movd xmm13, r8d + add rdx, 200 + movd xmm15, eax + mov rax, 32 + pshufd xmm15, xmm15, 0 + pshufd xmm13, xmm13, 0 + pxor xmm14, xmm14 + pxor xmm0, xmm0 + pxor xmm1, xmm1 + pxor xmm2, xmm2 + pxor xmm3, xmm3 + pxor xmm4, xmm4 + pxor xmm5, xmm5 + movdqa xmm14, xmm15 +L_256_get_point_33_4_start: + movdqa xmm12, xmm14 + paddd xmm14, xmm15 + pcmpeqd xmm12, xmm13 + movdqu xmm6, [rdx] + movdqu xmm7, [rdx+16] + movdqu xmm8, [rdx+64] + movdqu xmm9, [rdx+80] + movdqu xmm10, [rdx+128] + movdqu xmm11, [rdx+144] + add rdx, 200 + pand xmm6, xmm12 + pand xmm7, xmm12 + pand xmm8, xmm12 + pand xmm9, xmm12 + pand xmm10, xmm12 + pand xmm11, xmm12 + por xmm0, xmm6 + por xmm1, xmm7 + por xmm2, xmm8 + por xmm3, xmm9 + por xmm4, xmm10 + por xmm5, xmm11 + dec rax + jnz L_256_get_point_33_4_start + movdqu [rcx], xmm0 + movdqu [rcx+16], xmm1 + movdqu [rcx+64], xmm2 + movdqu [rcx+80], xmm3 + movdqu [rcx+128], xmm4 + movdqu [rcx+144], xmm5 + ret +sp_256_get_point_33_4 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Touch each possible point that could be being copied. +; * +; * r Point to copy into. +; * table Table - start of the entires to access +; * idx Index of point to retrieve. +; */ +_text SEGMENT READONLY PARA +sp_256_get_point_33_avx2_4 PROC + mov rax, 1 + movd xmm7, r8d + add rdx, 200 + movd xmm9, eax + mov rax, 32 + vpxor ymm8, ymm8, ymm8 + vpermd ymm7, ymm8, ymm7 + vpermd ymm9, ymm8, ymm9 + vpxor ymm0, ymm0, ymm0 + vpxor ymm1, ymm1, ymm1 + vpxor ymm2, ymm2, ymm2 + vmovdqa ymm8, ymm9 +L_256_get_point_33_avx2_4_start: + vpcmpeqd ymm6, ymm8, ymm7 + vpaddd ymm8, ymm8, ymm9 + vmovupd ymm3, [rdx] + vmovupd ymm4, [rdx+64] + vmovupd ymm5, [rdx+128] + add rdx, 200 + vpand ymm3, ymm3, ymm6 + vpand ymm4, ymm4, ymm6 + vpand ymm5, ymm5, ymm6 + vpor ymm0, ymm0, ymm3 + vpor ymm1, ymm1, ymm4 + vpor ymm2, ymm2, ymm5 + dec rax + jnz L_256_get_point_33_avx2_4_start + vmovupd YMMWORD PTR [rcx], ymm0 + vmovupd YMMWORD PTR [rcx+64], ymm1 + vmovupd YMMWORD PTR [rcx+128], ymm2 + ret +sp_256_get_point_33_avx2_4 ENDP +_text ENDS +ENDIF +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Multiply two Montogmery form numbers mod the modulus (prime). +; * (r = a * b mod m) +; * +; * r Result of multiplication. +; * a First number to multiply in Montogmery form. +; * b Second number to multiply in Montogmery form. +; * m Modulus (prime). +; * mp Montogmery mulitplier. +; */ +_text SEGMENT READONLY PARA +sp_256_mont_mul_avx2_4 PROC + push rbx + push r12 + push r13 + push r14 + push r15 + push rbp + push rdi + push rsi + mov rbp, r8 + mov rdi, rdx + ; A[0] * B[0] + mov rdx, QWORD PTR [rbp] + mulx r9, r8, QWORD PTR [rdi] + ; A[2] * B[0] + mulx r11, r10, QWORD PTR [rdi+16] + ; A[1] * B[0] + mulx rsi, rax, QWORD PTR [rdi+8] + xor r15, r15 + adcx r9, rax + ; A[1] * B[3] + mov rdx, QWORD PTR [rbp+24] + mulx r13, r12, QWORD PTR [rdi+8] + adcx r10, rsi + ; A[0] * B[1] + mov rdx, QWORD PTR [rbp+8] + mulx rsi, rax, QWORD PTR [rdi] + adox r9, rax + ; A[2] * B[1] + mulx r14, rax, QWORD PTR [rdi+16] + adox r10, rsi + adcx r11, rax + ; A[1] * B[2] + mov rdx, QWORD PTR [rbp+16] + mulx rsi, rax, QWORD PTR [rdi+8] + adcx r12, r14 + adox r11, rax + adcx r13, r15 + adox r12, rsi + ; A[0] * B[2] + mulx rsi, rax, QWORD PTR [rdi] + adox r13, r15 + xor r14, r14 + adcx r10, rax + ; A[1] * B[1] + mov rdx, QWORD PTR [rbp+8] + mulx rax, rdx, QWORD PTR [rdi+8] + adcx r11, rsi + adox r10, rdx + ; A[3] * B[1] + mov rdx, QWORD PTR [rbp+8] + adox r11, rax + mulx rsi, rax, QWORD PTR [rdi+24] + adcx r12, rax + ; A[2] * B[2] + mov rdx, QWORD PTR [rbp+16] + mulx rax, rdx, QWORD PTR [rdi+16] + adcx r13, rsi + adox r12, rdx + ; A[3] * B[3] + mov rdx, QWORD PTR [rbp+24] + adox r13, rax + mulx rsi, rax, QWORD PTR [rdi+24] + adox r14, r15 + adcx r14, rax + ; A[0] * B[3] + mulx rax, rdx, QWORD PTR [rdi] + adcx r15, rsi + xor rsi, rsi + adcx r11, rdx + ; A[3] * B[0] + mov rdx, QWORD PTR [rdi+24] + adcx r12, rax + mulx rax, rbx, QWORD PTR [rbp] + adox r11, rbx + adox r12, rax + ; A[3] * B[2] + mulx rax, rdx, QWORD PTR [rbp+16] + adcx r13, rdx + ; A[2] * B[3] + mov rdx, QWORD PTR [rbp+24] + adcx r14, rax + mulx rdx, rax, QWORD PTR [rdi+16] + adcx r15, rsi + adox r13, rax + adox r14, rdx + adox r15, rsi + ; Start Reduction + ; mu = a[0]-a[3] + a[0]-a[2] << 32 << 64 + (a[0] * 2) << 192 + ; - a[0] << 32 << 192 + ; + (a[0] * 2) << 192 + mov rax, r8 + mov rdx, r11 + add rdx, r8 + mov rdi, r9 + add rdx, r8 + mov rbp, r10 + ; a[0]-a[2] << 32 + shl r8, 32 + shld r10, rdi, 32 + shld r9, rax, 32 + ; - a[0] << 32 << 192 + sub rdx, r8 + ; + a[0]-a[2] << 32 << 64 + add rdi, r8 + adc rbp, r9 + adc rdx, r10 + ; a += (mu << 256) - (mu << 224) + (mu << 192) + (mu << 96) - mu + ; a += mu << 256 + xor r8, r8 + add r12, rax + adc r13, rdi + adc r14, rbp + adc r15, rdx + sbb r8, 0 + ; a += mu << 192 + add r11, rax + adc r12, rdi + adc r13, rbp + adc r14, rdx + adc r15, 0 + sbb r8, 0 + ; mu <<= 32 + mov rsi, rdx + shld rdx, rbp, 32 + shld rbp, rdi, 32 + shld rdi, rax, 32 + shr rsi, 32 + shl rax, 32 + ; a += (mu << 32) << 64 + add r11, rbp + adc r12, rdx + adc r13, rsi + adc r14, 0 + adc r15, 0 + sbb r8, 0 + ; a -= (mu << 32) << 192 + sub r11, rax + sbb r12, rdi + sbb r13, rbp + sbb r14, rdx + sbb r15, rsi + adc r8, 0 + mov rax, 4294967295 + mov rdi, 18446744069414584321 + ; mask m and sub from result if overflow + ; m[0] = -1 & mask = mask + and rax, r8 + ; m[2] = 0 & mask = 0 + and rdi, r8 + sub r12, r8 + sbb r13, rax + sbb r14, 0 + sbb r15, rdi + mov QWORD PTR [rcx], r12 + mov QWORD PTR [rcx+8], r13 + mov QWORD PTR [rcx+16], r14 + mov QWORD PTR [rcx+24], r15 + pop rsi + pop rdi + pop rbp + pop r15 + pop r14 + pop r13 + pop r12 + pop rbx + ret +sp_256_mont_mul_avx2_4 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Square the Montgomery form number mod the modulus (prime). (r = a * a mod m) +; * +; * r Result of squaring. +; * a Number to square in Montogmery form. +; * m Modulus (prime). +; * mp Montogmery mulitplier. +; */ +_text SEGMENT READONLY PARA +sp_256_mont_sqr_avx2_4 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + push rbx + mov rax, rdx + ; A[0] * A[1] + mov rdx, QWORD PTR [rax] + mov r15, QWORD PTR [rax+16] + mulx r10, r9, QWORD PTR [rax+8] + ; A[0] * A[3] + mulx r12, r11, QWORD PTR [rax+24] + ; A[2] * A[1] + mov rdx, r15 + mulx rbx, rsi, QWORD PTR [rax+8] + ; A[2] * A[3] + mulx r14, r13, QWORD PTR [rax+24] + xor r15, r15 + adox r11, rsi + adox r12, rbx + ; A[2] * A[0] + mulx rbx, rsi, QWORD PTR [rax] + ; A[1] * A[3] + mov rdx, QWORD PTR [rax+8] + adox r13, r15 + mulx r8, rdi, QWORD PTR [rax+24] + adcx r10, rsi + adox r14, r15 + adcx r11, rbx + adcx r12, rdi + adcx r13, r8 + adcx r14, r15 + ; Double with Carry Flag + xor r15, r15 + ; A[0] * A[0] + mov rdx, QWORD PTR [rax] + mulx rdi, r8, rdx + adcx r9, r9 + adcx r10, r10 + adox r9, rdi + ; A[1] * A[1] + mov rdx, QWORD PTR [rax+8] + mulx rbx, rsi, rdx + adcx r11, r11 + adox r10, rsi + ; A[2] * A[2] + mov rdx, QWORD PTR [rax+16] + mulx rsi, rdi, rdx + adcx r12, r12 + adox r11, rbx + adcx r13, r13 + adox r12, rdi + adcx r14, r14 + ; A[3] * A[3] + mov rdx, QWORD PTR [rax+24] + mulx rbx, rdi, rdx + adox r13, rsi + adcx r15, r15 + adox r14, rdi + adox r15, rbx + ; Start Reduction + ; mu = a[0]-a[3] + a[0]-a[2] << 32 << 64 + (a[0] * 2) << 192 + ; - a[0] << 32 << 192 + ; + (a[0] * 2) << 192 + mov rdi, r8 + mov rdx, r11 + add rdx, r8 + mov rax, r9 + add rdx, r8 + mov rsi, r10 + ; a[0]-a[2] << 32 + shl r8, 32 + shld r10, rax, 32 + shld r9, rdi, 32 + ; - a[0] << 32 << 192 + sub rdx, r8 + ; + a[0]-a[2] << 32 << 64 + add rax, r8 + adc rsi, r9 + adc rdx, r10 + ; a += (mu << 256) - (mu << 224) + (mu << 192) + (mu << 96) - mu + ; a += mu << 256 + xor r8, r8 + add r12, rdi + adc r13, rax + adc r14, rsi + adc r15, rdx + sbb r8, 0 + ; a += mu << 192 + add r11, rdi + adc r12, rax + adc r13, rsi + adc r14, rdx + adc r15, 0 + sbb r8, 0 + ; mu <<= 32 + mov rbx, rdx + shld rdx, rsi, 32 + shld rsi, rax, 32 + shld rax, rdi, 32 + shr rbx, 32 + shl rdi, 32 + ; a += (mu << 32) << 64 + add r11, rsi + adc r12, rdx + adc r13, rbx + adc r14, 0 + adc r15, 0 + sbb r8, 0 + ; a -= (mu << 32) << 192 + sub r11, rdi + sbb r12, rax + sbb r13, rsi + sbb r14, rdx + sbb r15, rbx + adc r8, 0 + mov rdi, 4294967295 + mov rax, 18446744069414584321 + ; mask m and sub from result if overflow + ; m[0] = -1 & mask = mask + and rdi, r8 + ; m[2] = 0 & mask = 0 + and rax, r8 + sub r12, r8 + sbb r13, rdi + sbb r14, 0 + sbb r15, rax + mov QWORD PTR [rcx], r12 + mov QWORD PTR [rcx+8], r13 + mov QWORD PTR [rcx+16], r14 + mov QWORD PTR [rcx+24], r15 + pop rbx + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_256_mont_sqr_avx2_4 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Conditionally subtract b from a using the mask m. +; * m is -1 to subtract and 0 when not copying. +; * +; * r A single precision number representing condition subtract result. +; * a A single precision number to subtract from. +; * b A single precision number to subtract. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_256_cond_sub_avx2_4 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + mov rax, 0 + mov r14, QWORD PTR [r8] + mov r15, QWORD PTR [r8+8] + mov rdi, QWORD PTR [r8+16] + mov rsi, QWORD PTR [r8+24] + and r14, r9 + and r15, r9 + and rdi, r9 + and rsi, r9 + mov r10, QWORD PTR [rdx] + mov r11, QWORD PTR [rdx+8] + mov r12, QWORD PTR [rdx+16] + mov r13, QWORD PTR [rdx+24] + sub r10, r14 + sbb r11, r15 + sbb r12, rdi + sbb r13, rsi + mov QWORD PTR [rcx], r10 + mov QWORD PTR [rcx+8], r11 + mov QWORD PTR [rcx+16], r12 + mov QWORD PTR [rcx+24], r13 + sbb rax, 0 + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_256_cond_sub_avx2_4 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Reduce the number back to 256 bits using Montgomery reduction. +; * +; * a A single precision number to reduce in place. +; * m The single precision number representing the modulus. +; * mp The digit representing the negative inverse of m mod 2^n. +; */ +_text SEGMENT READONLY PARA +sp_256_mont_reduce_avx2_4 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + push rbx + mov rax, rcx + mov r10, rdx + mov r11, r8 + mov r14, QWORD PTR [rax] + mov r15, QWORD PTR [rax+8] + mov rdi, QWORD PTR [rax+16] + mov rsi, QWORD PTR [rax+24] + xor r13, r13 + xor r12, r12 + ; a[0-4] += m[0-3] * mu = m[0-3] * (a[0] * mp) + mov rbx, QWORD PTR [rax+32] + ; mu = a[0] * mp + mov rdx, r14 + mulx rcx, rdx, r11 + ; a[0] += m[0] * mu + mulx r9, r8, QWORD PTR [r10] + adcx r14, r8 + ; a[1] += m[1] * mu + mulx rcx, r8, QWORD PTR [r10+8] + adox r15, r9 + adcx r15, r8 + ; a[2] += m[2] * mu + mulx r9, r8, QWORD PTR [r10+16] + adox rdi, rcx + adcx rdi, r8 + ; a[3] += m[3] * mu + mulx rcx, r8, QWORD PTR [r10+24] + adox rsi, r9 + adcx rsi, r8 + ; a[4] += carry + adox rbx, rcx + adcx rbx, r12 + ; carry + adox r13, r12 + adcx r13, r12 + ; a[1-5] += m[0-3] * mu = m[0-3] * (a[1] * mp) + mov r14, QWORD PTR [rax+40] + ; mu = a[1] * mp + mov rdx, r15 + mulx rcx, rdx, r11 + ; a[1] += m[0] * mu + mulx r9, r8, QWORD PTR [r10] + adcx r15, r8 + ; a[2] += m[1] * mu + mulx rcx, r8, QWORD PTR [r10+8] + adox rdi, r9 + adcx rdi, r8 + ; a[3] += m[2] * mu + mulx r9, r8, QWORD PTR [r10+16] + adox rsi, rcx + adcx rsi, r8 + ; a[4] += m[3] * mu + mulx rcx, r8, QWORD PTR [r10+24] + adox rbx, r9 + adcx rbx, r8 + ; a[5] += carry + adox r14, rcx + adcx r14, r13 + mov r13, r12 + ; carry + adox r13, r12 + adcx r13, r12 + ; a[2-6] += m[0-3] * mu = m[0-3] * (a[2] * mp) + mov r15, QWORD PTR [rax+48] + ; mu = a[2] * mp + mov rdx, rdi + mulx rcx, rdx, r11 + ; a[2] += m[0] * mu + mulx r9, r8, QWORD PTR [r10] + adcx rdi, r8 + ; a[3] += m[1] * mu + mulx rcx, r8, QWORD PTR [r10+8] + adox rsi, r9 + adcx rsi, r8 + ; a[4] += m[2] * mu + mulx r9, r8, QWORD PTR [r10+16] + adox rbx, rcx + adcx rbx, r8 + ; a[5] += m[3] * mu + mulx rcx, r8, QWORD PTR [r10+24] + adox r14, r9 + adcx r14, r8 + ; a[6] += carry + adox r15, rcx + adcx r15, r13 + mov r13, r12 + ; carry + adox r13, r12 + adcx r13, r12 + ; a[3-7] += m[0-3] * mu = m[0-3] * (a[3] * mp) + mov rdi, QWORD PTR [rax+56] + ; mu = a[3] * mp + mov rdx, rsi + mulx rcx, rdx, r11 + ; a[3] += m[0] * mu + mulx r9, r8, QWORD PTR [r10] + adcx rsi, r8 + ; a[4] += m[1] * mu + mulx rcx, r8, QWORD PTR [r10+8] + adox rbx, r9 + adcx rbx, r8 + ; a[5] += m[2] * mu + mulx r9, r8, QWORD PTR [r10+16] + adox r14, rcx + adcx r14, r8 + ; a[6] += m[3] * mu + mulx rcx, r8, QWORD PTR [r10+24] + adox r15, r9 + adcx r15, r8 + ; a[7] += carry + adox rdi, rcx + adcx rdi, r13 + mov r13, r12 + ; carry + adox r13, r12 + adcx r13, r12 + ; Subtract mod if carry + neg r13 + mov r8, 17562291160714782033 + mov r9, 13611842547513532036 + mov rdx, 18446744069414584320 + and r8, r13 + and r9, r13 + and rdx, r13 + sub rbx, r8 + sbb r14, r9 + sbb r15, r13 + sbb rdi, rdx + mov QWORD PTR [rax], rbx + mov QWORD PTR [rax+8], r14 + mov QWORD PTR [rax+16], r15 + mov QWORD PTR [rax+24], rdi + pop rbx + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_256_mont_reduce_avx2_4 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m) +; * +; * r Result of division by 2. +; * a Number to divide. +; * m Modulus (prime). +; */ +_text SEGMENT READONLY PARA +sp_256_div2_avx2_4 PROC + push r12 + push r13 + mov rax, QWORD PTR [rdx] + mov r8, QWORD PTR [rdx+8] + mov r9, QWORD PTR [rdx+16] + mov r10, QWORD PTR [rdx+24] + mov r11, 4294967295 + mov r12, 18446744069414584321 + mov r13, rax + and r13, 1 + neg r13 + and r11, r13 + and r12, r13 + add rax, r13 + adc r8, r11 + adc r9, 0 + adc r10, r12 + mov r13, 0 + adc r13, 0 + shrd rax, r8, 1 + shrd r8, r9, 1 + shrd r9, r10, 1 + shrd r10, r13, 1 + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r8 + mov QWORD PTR [rcx+16], r9 + mov QWORD PTR [rcx+24], r10 + pop r13 + pop r12 + ret +sp_256_div2_avx2_4 ENDP +_text ENDS +ENDIF +IFNDEF WC_NO_CACHE_RESISTANT +; /* Touch each possible entry that could be being copied. +; * +; * r Point to copy into. +; * table Table - start of the entires to access +; * idx Index of entry to retrieve. +; */ +_text SEGMENT READONLY PARA +sp_256_get_entry_64_4 PROC + mov rax, 1 + movd xmm9, r8d + add rdx, 64 + movd xmm11, eax + mov rax, 63 + pshufd xmm11, xmm11, 0 + pshufd xmm9, xmm9, 0 + pxor xmm10, xmm10 + pxor xmm0, xmm0 + pxor xmm1, xmm1 + pxor xmm2, xmm2 + pxor xmm3, xmm3 + movdqa xmm10, xmm11 +L_256_get_entry_64_4_start: + movdqa xmm8, xmm10 + paddd xmm10, xmm11 + pcmpeqd xmm8, xmm9 + movdqu xmm4, [rdx] + movdqu xmm5, [rdx+16] + movdqu xmm6, [rdx+32] + movdqu xmm7, [rdx+48] + add rdx, 64 + pand xmm4, xmm8 + pand xmm5, xmm8 + pand xmm6, xmm8 + pand xmm7, xmm8 + por xmm0, xmm4 + por xmm1, xmm5 + por xmm2, xmm6 + por xmm3, xmm7 + dec rax + jnz L_256_get_entry_64_4_start + movdqu [rcx], xmm0 + movdqu [rcx+16], xmm1 + movdqu [rcx+64], xmm2 + movdqu [rcx+80], xmm3 + ret +sp_256_get_entry_64_4 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Touch each possible entry that could be being copied. +; * +; * r Point to copy into. +; * table Table - start of the entires to access +; * idx Index of entry to retrieve. +; */ +_text SEGMENT READONLY PARA +sp_256_get_entry_64_avx2_4 PROC + mov rax, 1 + movd xmm5, r8d + add rdx, 64 + movd xmm7, eax + mov rax, 64 + vpxor ymm6, ymm6, ymm6 + vpermd ymm5, ymm6, ymm5 + vpermd ymm7, ymm6, ymm7 + vpxor ymm0, ymm0, ymm0 + vpxor ymm1, ymm1, ymm1 + vmovdqa ymm6, ymm7 +L_256_get_entry_64_avx2_4_start: + vpcmpeqd ymm4, ymm6, ymm5 + vpaddd ymm6, ymm6, ymm7 + vmovupd ymm2, [rdx] + vmovupd ymm3, [rdx+32] + add rdx, 64 + vpand ymm2, ymm2, ymm4 + vpand ymm3, ymm3, ymm4 + vpor ymm0, ymm0, ymm2 + vpor ymm1, ymm1, ymm3 + dec rax + jnz L_256_get_entry_64_avx2_4_start + vmovupd YMMWORD PTR [rcx], ymm0 + vmovupd YMMWORD PTR [rcx+64], ymm1 + ret +sp_256_get_entry_64_avx2_4 ENDP +_text ENDS +ENDIF +ENDIF +IFNDEF WC_NO_CACHE_RESISTANT +; /* Touch each possible entry that could be being copied. +; * +; * r Point to copy into. +; * table Table - start of the entires to access +; * idx Index of entry to retrieve. +; */ +_text SEGMENT READONLY PARA +sp_256_get_entry_65_4 PROC + mov rax, 1 + movd xmm9, r8d + add rdx, 64 + movd xmm11, eax + mov rax, 64 + pshufd xmm11, xmm11, 0 + pshufd xmm9, xmm9, 0 + pxor xmm10, xmm10 + pxor xmm0, xmm0 + pxor xmm1, xmm1 + pxor xmm2, xmm2 + pxor xmm3, xmm3 + movdqa xmm10, xmm11 +L_256_get_entry_65_4_start: + movdqa xmm8, xmm10 + paddd xmm10, xmm11 + pcmpeqd xmm8, xmm9 + movdqu xmm4, [rdx] + movdqu xmm5, [rdx+16] + movdqu xmm6, [rdx+32] + movdqu xmm7, [rdx+48] + add rdx, 64 + pand xmm4, xmm8 + pand xmm5, xmm8 + pand xmm6, xmm8 + pand xmm7, xmm8 + por xmm0, xmm4 + por xmm1, xmm5 + por xmm2, xmm6 + por xmm3, xmm7 + dec rax + jnz L_256_get_entry_65_4_start + movdqu [rcx], xmm0 + movdqu [rcx+16], xmm1 + movdqu [rcx+64], xmm2 + movdqu [rcx+80], xmm3 + ret +sp_256_get_entry_65_4 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Touch each possible entry that could be being copied. +; * +; * r Point to copy into. +; * table Table - start of the entires to access +; * idx Index of entry to retrieve. +; */ +_text SEGMENT READONLY PARA +sp_256_get_entry_65_avx2_4 PROC + mov rax, 1 + movd xmm5, r8d + add rdx, 64 + movd xmm7, eax + mov rax, 65 + vpxor ymm6, ymm6, ymm6 + vpermd ymm5, ymm6, ymm5 + vpermd ymm7, ymm6, ymm7 + vpxor ymm0, ymm0, ymm0 + vpxor ymm1, ymm1, ymm1 + vmovdqa ymm6, ymm7 +L_256_get_entry_65_avx2_4_start: + vpcmpeqd ymm4, ymm6, ymm5 + vpaddd ymm6, ymm6, ymm7 + vmovupd ymm2, [rdx] + vmovupd ymm3, [rdx+32] + add rdx, 64 + vpand ymm2, ymm2, ymm4 + vpand ymm3, ymm3, ymm4 + vpor ymm0, ymm0, ymm2 + vpor ymm1, ymm1, ymm3 + dec rax + jnz L_256_get_entry_65_avx2_4_start + vmovupd YMMWORD PTR [rcx], ymm0 + vmovupd YMMWORD PTR [rcx+64], ymm1 + ret +sp_256_get_entry_65_avx2_4 ENDP +_text ENDS +ENDIF +ENDIF +; /* Add 1 to a. (a = a + 1) +; * +; * a A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_256_add_one_4 PROC + add QWORD PTR [rcx], 1 + adc QWORD PTR [rcx+8], 0 + adc QWORD PTR [rcx+16], 0 + adc QWORD PTR [rcx+24], 0 + ret +sp_256_add_one_4 ENDP +_text ENDS +; /* Read big endian unsigned byte array into r. +; * Uses the bswap instruction. +; * +; * r A single precision integer. +; * size Maximum number of bytes to convert +; * a Byte array. +; * n Number of bytes in array to read. +; */ +_text SEGMENT READONLY PARA +sp_256_from_bin_bswap PROC + push r12 + push r13 + mov r11, r8 + mov r12, rcx + add r11, r9 + add r12, 32 + xor r13, r13 + jmp L_256_from_bin_bswap_64_end +L_256_from_bin_bswap_64_start: + sub r11, 64 + mov rax, QWORD PTR [r11+56] + mov r10, QWORD PTR [r11+48] + bswap rax + bswap r10 + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r10 + mov rax, QWORD PTR [r11+40] + mov r10, QWORD PTR [r11+32] + bswap rax + bswap r10 + mov QWORD PTR [rcx+16], rax + mov QWORD PTR [rcx+24], r10 + mov rax, QWORD PTR [r11+24] + mov r10, QWORD PTR [r11+16] + bswap rax + bswap r10 + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r10 + mov rax, QWORD PTR [r11+8] + mov r10, QWORD PTR [r11] + bswap rax + bswap r10 + mov QWORD PTR [rcx+48], rax + mov QWORD PTR [rcx+56], r10 + add rcx, 64 + sub r9, 64 +L_256_from_bin_bswap_64_end: + cmp r9, 63 + jg L_256_from_bin_bswap_64_start + jmp L_256_from_bin_bswap_8_end +L_256_from_bin_bswap_8_start: + sub r11, 8 + mov rax, QWORD PTR [r11] + bswap rax + mov QWORD PTR [rcx], rax + add rcx, 8 + sub r9, 8 +L_256_from_bin_bswap_8_end: + cmp r9, 7 + jg L_256_from_bin_bswap_8_start + cmp r9, r13 + je L_256_from_bin_bswap_hi_end + mov r10, r13 + mov rax, r13 +L_256_from_bin_bswap_hi_start: + mov al, BYTE PTR [r8] + shl r10, 8 + inc r8 + add r10, rax + dec r9 + jg L_256_from_bin_bswap_hi_start + mov QWORD PTR [rcx], r10 + add rcx, 8 +L_256_from_bin_bswap_hi_end: + cmp rcx, r12 + je L_256_from_bin_bswap_zero_end +L_256_from_bin_bswap_zero_start: + mov QWORD PTR [rcx], r13 + add rcx, 8 + cmp rcx, r12 + jl L_256_from_bin_bswap_zero_start +L_256_from_bin_bswap_zero_end: + pop r13 + pop r12 + ret +sp_256_from_bin_bswap ENDP +_text ENDS +IFNDEF NO_MOVBE_SUPPORT +; /* Read big endian unsigned byte array into r. +; * Uses the movbe instruction which is an optional instruction. +; * +; * r A single precision integer. +; * size Maximum number of bytes to convert +; * a Byte array. +; * n Number of bytes in array to read. +; */ +_text SEGMENT READONLY PARA +sp_256_from_bin_movbe PROC + push r12 + push r13 + mov r11, r8 + mov r12, rcx + add r11, r9 + add r12, 32 + xor r13, r13 + jmp L_256_from_bin_movbe_64_end +L_256_from_bin_movbe_64_start: + sub r11, 64 + movbe rax, QWORD PTR [r11+56] + movbe r10, QWORD PTR [r11+48] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r10 + movbe rax, QWORD PTR [r11+40] + movbe r10, QWORD PTR [r11+32] + mov QWORD PTR [rcx+16], rax + mov QWORD PTR [rcx+24], r10 + movbe rax, QWORD PTR [r11+24] + movbe r10, QWORD PTR [r11+16] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r10 + movbe rax, QWORD PTR [r11+8] + movbe r10, QWORD PTR [r11] + mov QWORD PTR [rcx+48], rax + mov QWORD PTR [rcx+56], r10 + add rcx, 64 + sub r9, 64 +L_256_from_bin_movbe_64_end: + cmp r9, 63 + jg L_256_from_bin_movbe_64_start + jmp L_256_from_bin_movbe_8_end +L_256_from_bin_movbe_8_start: + sub r11, 8 + movbe rax, QWORD PTR [r11] + mov QWORD PTR [rcx], rax + add rcx, 8 + sub r9, 8 +L_256_from_bin_movbe_8_end: + cmp r9, 7 + jg L_256_from_bin_movbe_8_start + cmp r9, r13 + je L_256_from_bin_movbe_hi_end + mov r10, r13 + mov rax, r13 +L_256_from_bin_movbe_hi_start: + mov al, BYTE PTR [r8] + shl r10, 8 + inc r8 + add r10, rax + dec r9 + jg L_256_from_bin_movbe_hi_start + mov QWORD PTR [rcx], r10 + add rcx, 8 +L_256_from_bin_movbe_hi_end: + cmp rcx, r12 + je L_256_from_bin_movbe_zero_end +L_256_from_bin_movbe_zero_start: + mov QWORD PTR [rcx], r13 + add rcx, 8 + cmp rcx, r12 + jl L_256_from_bin_movbe_zero_start +L_256_from_bin_movbe_zero_end: + pop r13 + pop r12 + ret +sp_256_from_bin_movbe ENDP +_text ENDS +ENDIF +; /* Write r as big endian to byte array. +; * Fixed length number of bytes written: 32 +; * Uses the bswap instruction. +; * +; * r A single precision integer. +; * a Byte array. +; */ +_text SEGMENT READONLY PARA +sp_256_to_bin_bswap PROC + mov rax, QWORD PTR [rcx+24] + mov r8, QWORD PTR [rcx+16] + bswap rax + bswap r8 + mov QWORD PTR [rdx], rax + mov QWORD PTR [rdx+8], r8 + mov rax, QWORD PTR [rcx+8] + mov r8, QWORD PTR [rcx] + bswap rax + bswap r8 + mov QWORD PTR [rdx+16], rax + mov QWORD PTR [rdx+24], r8 + ret +sp_256_to_bin_bswap ENDP +_text ENDS +IFNDEF NO_MOVBE_SUPPORT +; /* Write r as big endian to byte array. +; * Fixed length number of bytes written: 32 +; * Uses the movbe instruction which is optional. +; * +; * r A single precision integer. +; * a Byte array. +; */ +_text SEGMENT READONLY PARA +sp_256_to_bin_movbe PROC + movbe rax, QWORD PTR [rcx+24] + movbe r8, QWORD PTR [rcx+16] + mov QWORD PTR [rdx], rax + mov QWORD PTR [rdx+8], r8 + movbe rax, QWORD PTR [rcx+8] + movbe r8, QWORD PTR [rcx] + mov QWORD PTR [rdx+16], rax + mov QWORD PTR [rdx+24], r8 + ret +sp_256_to_bin_movbe ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Multiply a and b into r. (r = a * b) +; * +; * r Result of multiplication. +; * a First number to multiply. +; * b Second number to multiply. +; */ +_text SEGMENT READONLY PARA +sp_256_mul_avx2_4 PROC + push rbx + push r12 + push r13 + push r14 + push r15 + push rbp + push rdi + push rsi + mov rbp, r8 + mov rdi, rdx + ; A[0] * B[0] + mov rdx, QWORD PTR [rbp] + mulx r9, r8, QWORD PTR [rdi] + ; A[2] * B[0] + mulx r11, r10, QWORD PTR [rdi+16] + ; A[1] * B[0] + mulx rsi, rax, QWORD PTR [rdi+8] + xor r15, r15 + adcx r9, rax + ; A[1] * B[3] + mov rdx, QWORD PTR [rbp+24] + mulx r13, r12, QWORD PTR [rdi+8] + adcx r10, rsi + ; A[0] * B[1] + mov rdx, QWORD PTR [rbp+8] + mulx rsi, rax, QWORD PTR [rdi] + adox r9, rax + ; A[2] * B[1] + mulx r14, rax, QWORD PTR [rdi+16] + adox r10, rsi + adcx r11, rax + ; A[1] * B[2] + mov rdx, QWORD PTR [rbp+16] + mulx rsi, rax, QWORD PTR [rdi+8] + adcx r12, r14 + adox r11, rax + adcx r13, r15 + adox r12, rsi + ; A[0] * B[2] + mulx rsi, rax, QWORD PTR [rdi] + adox r13, r15 + xor r14, r14 + adcx r10, rax + ; A[1] * B[1] + mov rdx, QWORD PTR [rbp+8] + mulx rax, rdx, QWORD PTR [rdi+8] + adcx r11, rsi + adox r10, rdx + ; A[3] * B[1] + mov rdx, QWORD PTR [rbp+8] + adox r11, rax + mulx rsi, rax, QWORD PTR [rdi+24] + adcx r12, rax + ; A[2] * B[2] + mov rdx, QWORD PTR [rbp+16] + mulx rax, rdx, QWORD PTR [rdi+16] + adcx r13, rsi + adox r12, rdx + ; A[3] * B[3] + mov rdx, QWORD PTR [rbp+24] + adox r13, rax + mulx rsi, rax, QWORD PTR [rdi+24] + adox r14, r15 + adcx r14, rax + ; A[0] * B[3] + mulx rax, rdx, QWORD PTR [rdi] + adcx r15, rsi + xor rsi, rsi + adcx r11, rdx + ; A[3] * B[0] + mov rdx, QWORD PTR [rdi+24] + adcx r12, rax + mulx rax, rbx, QWORD PTR [rbp] + adox r11, rbx + adox r12, rax + ; A[3] * B[2] + mulx rax, rdx, QWORD PTR [rbp+16] + adcx r13, rdx + ; A[2] * B[3] + mov rdx, QWORD PTR [rbp+24] + adcx r14, rax + mulx rdx, rax, QWORD PTR [rdi+16] + adcx r15, rsi + adox r13, rax + adox r14, rdx + adox r15, rsi + mov QWORD PTR [rcx], r8 + mov QWORD PTR [rcx+8], r9 + mov QWORD PTR [rcx+16], r10 + mov QWORD PTR [rcx+24], r11 + mov QWORD PTR [rcx+32], r12 + mov QWORD PTR [rcx+40], r13 + mov QWORD PTR [rcx+48], r14 + mov QWORD PTR [rcx+56], r15 + pop rsi + pop rdi + pop rbp + pop r15 + pop r14 + pop r13 + pop r12 + pop rbx + ret +sp_256_mul_avx2_4 ENDP +_text ENDS +ENDIF +; /* Sub b from a into a. (a -= b) +; * +; * a A single precision integer and result. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_256_sub_in_place_4 PROC + xor rax, rax + mov r8, QWORD PTR [rdx] + mov r9, QWORD PTR [rdx+8] + mov r10, QWORD PTR [rdx+16] + mov r11, QWORD PTR [rdx+24] + sub QWORD PTR [rcx], r8 + sbb QWORD PTR [rcx+8], r9 + sbb QWORD PTR [rcx+16], r10 + sbb QWORD PTR [rcx+24], r11 + sbb rax, 0 + ret +sp_256_sub_in_place_4 ENDP +_text ENDS +; /* Mul a by digit b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision digit. +; */ +_text SEGMENT READONLY PARA +sp_256_mul_d_4 PROC + push r12 + mov r9, rdx + ; A[0] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9] + mov r10, rax + mov r11, rdx + mov QWORD PTR [rcx], r10 + ; A[1] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+8] + add r11, rax + mov QWORD PTR [rcx+8], r11 + adc r12, rdx + adc r10, 0 + ; A[2] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+16] + add r12, rax + mov QWORD PTR [rcx+16], r12 + adc r10, rdx + adc r11, 0 + ; A[3] * B + mov rax, r8 + mul QWORD PTR [r9+24] + add r10, rax + adc r11, rdx + mov QWORD PTR [rcx+24], r10 + mov QWORD PTR [rcx+32], r11 + pop r12 + ret +sp_256_mul_d_4 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Mul a by digit b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision digit. +; */ +_text SEGMENT READONLY PARA +sp_256_mul_d_avx2_4 PROC + push r12 + push r13 + mov rax, rdx + ; A[0] * B + mov rdx, r8 + xor r13, r13 + mulx r12, r11, QWORD PTR [rax] + mov QWORD PTR [rcx], r11 + ; A[1] * B + mulx r10, r9, QWORD PTR [rax+8] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+8], r12 + ; A[2] * B + mulx r10, r9, QWORD PTR [rax+16] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+16], r11 + ; A[3] * B + mulx r10, r9, QWORD PTR [rax+24] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + adcx r11, r13 + mov QWORD PTR [rcx+24], r12 + mov QWORD PTR [rcx+32], r11 + pop r13 + pop r12 + ret +sp_256_mul_d_avx2_4 ENDP +_text ENDS +ENDIF +IFDEF _WIN64 +; /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) +; * +; * d1 The high order half of the number to divide. +; * d0 The low order half of the number to divide. +; * div The dividend. +; * returns the result of the division. +; */ +_text SEGMENT READONLY PARA +div_256_word_asm_4 PROC + mov r9, rdx + mov rax, r9 + mov rdx, rcx + div r8 + ret +div_256_word_asm_4 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Multiply two Montogmery form numbers mod the modulus (prime). +; * (r = a * b mod m) +; * +; * r Result of multiplication. +; * a First number to multiply in Montogmery form. +; * b Second number to multiply in Montogmery form. +; */ +_text SEGMENT READONLY PARA +sp_256_mont_mul_order_avx2_4 PROC + push rbx + push r12 + push r13 + push r14 + push r15 + push rbp + push rdi + push rsi + mov rbp, r8 + mov rdi, rdx + ; A[0] * B[0] + mov rdx, QWORD PTR [rbp] + mulx r9, r8, QWORD PTR [rdi] + ; A[2] * B[0] + mulx r11, r10, QWORD PTR [rdi+16] + ; A[1] * B[0] + mulx rsi, rax, QWORD PTR [rdi+8] + xor r15, r15 + adcx r9, rax + ; A[1] * B[3] + mov rdx, QWORD PTR [rbp+24] + mulx r13, r12, QWORD PTR [rdi+8] + adcx r10, rsi + ; A[0] * B[1] + mov rdx, QWORD PTR [rbp+8] + mulx rsi, rax, QWORD PTR [rdi] + adox r9, rax + ; A[2] * B[1] + mulx r14, rax, QWORD PTR [rdi+16] + adox r10, rsi + adcx r11, rax + ; A[1] * B[2] + mov rdx, QWORD PTR [rbp+16] + mulx rsi, rax, QWORD PTR [rdi+8] + adcx r12, r14 + adox r11, rax + adcx r13, r15 + adox r12, rsi + ; A[0] * B[2] + mulx rsi, rax, QWORD PTR [rdi] + adox r13, r15 + xor r14, r14 + adcx r10, rax + ; A[1] * B[1] + mov rdx, QWORD PTR [rbp+8] + mulx rax, rdx, QWORD PTR [rdi+8] + adcx r11, rsi + adox r10, rdx + ; A[3] * B[1] + mov rdx, QWORD PTR [rbp+8] + adox r11, rax + mulx rsi, rax, QWORD PTR [rdi+24] + adcx r12, rax + ; A[2] * B[2] + mov rdx, QWORD PTR [rbp+16] + mulx rax, rdx, QWORD PTR [rdi+16] + adcx r13, rsi + adox r12, rdx + ; A[3] * B[3] + mov rdx, QWORD PTR [rbp+24] + adox r13, rax + mulx rsi, rax, QWORD PTR [rdi+24] + adox r14, r15 + adcx r14, rax + ; A[0] * B[3] + mulx rax, rdx, QWORD PTR [rdi] + adcx r15, rsi + xor rsi, rsi + adcx r11, rdx + ; A[3] * B[0] + mov rdx, QWORD PTR [rdi+24] + adcx r12, rax + mulx rax, rbx, QWORD PTR [rbp] + adox r11, rbx + adox r12, rax + ; A[3] * B[2] + mulx rax, rdx, QWORD PTR [rbp+16] + adcx r13, rdx + ; A[2] * B[3] + mov rdx, QWORD PTR [rbp+24] + adcx r14, rax + mulx rdx, rax, QWORD PTR [rdi+16] + adcx r15, rsi + adox r13, rax + adox r14, rdx + adox r15, rsi + ; Start Reduction + mov rbx, 14758798090332847183 + ; A[0] + mov rdx, rbx + imul rdx, r8 + mov rax, 17562291160714782033 + xor rbp, rbp + mulx rdi, rsi, rax + mov rax, 13611842547513532036 + adcx r8, rsi + adox r9, rdi + mulx rdi, rsi, rax + mov rax, 18446744073709551615 + adcx r9, rsi + adox r10, rdi + mulx rdi, rsi, rax + mov rax, 18446744069414584320 + adcx r10, rsi + adox r11, rdi + mulx rdi, rsi, rax + adcx r11, rsi + adox r12, rdi + adcx r12, rbp + mov r8, rbp + ; carry + adox r8, rbp + adcx r8, rbp + ; A[1] + mov rdx, rbx + imul rdx, r9 + mov rax, 17562291160714782033 + xor rbp, rbp + mulx rdi, rsi, rax + mov rax, 13611842547513532036 + adcx r9, rsi + adox r10, rdi + mulx rdi, rsi, rax + mov rax, 18446744073709551615 + adcx r10, rsi + adox r11, rdi + mulx rdi, rsi, rax + mov rax, 18446744069414584320 + adcx r11, rsi + adox r12, rdi + mulx rdi, rsi, rax + adcx r12, rsi + adox r13, rdi + adcx r13, r8 + mov r8, rbp + ; carry + adox r8, rbp + adcx r8, rbp + ; A[2] + mov rdx, rbx + imul rdx, r10 + mov rax, 17562291160714782033 + xor rbp, rbp + mulx rdi, rsi, rax + mov rax, 13611842547513532036 + adcx r10, rsi + adox r11, rdi + mulx rdi, rsi, rax + mov rax, 18446744073709551615 + adcx r11, rsi + adox r12, rdi + mulx rdi, rsi, rax + mov rax, 18446744069414584320 + adcx r12, rsi + adox r13, rdi + mulx rdi, rsi, rax + adcx r13, rsi + adox r14, rdi + adcx r14, r8 + mov r8, rbp + ; carry + adox r8, rbp + adcx r8, rbp + ; A[3] + mov rdx, rbx + imul rdx, r11 + mov rax, 17562291160714782033 + xor rbp, rbp + mulx rdi, rsi, rax + mov rax, 13611842547513532036 + adcx r11, rsi + adox r12, rdi + mulx rdi, rsi, rax + mov rax, 18446744073709551615 + adcx r12, rsi + adox r13, rdi + mulx rdi, rsi, rax + mov rax, 18446744069414584320 + adcx r13, rsi + adox r14, rdi + mulx rdi, rsi, rax + adcx r14, rsi + adox r15, rdi + adcx r15, r8 + mov r8, rbp + ; carry + adox r8, rbp + adcx r8, rbp + neg r8 + mov rax, 17562291160714782033 + mov rbx, 13611842547513532036 + and rax, r8 + mov rbp, 18446744069414584320 + and rbx, r8 + and rbp, r8 + sub r12, rax + sbb r13, rbx + mov QWORD PTR [rcx], r12 + sbb r14, r8 + mov QWORD PTR [rcx+8], r13 + sbb r15, rbp + mov QWORD PTR [rcx+16], r14 + mov QWORD PTR [rcx+24], r15 + pop rsi + pop rdi + pop rbp + pop r15 + pop r14 + pop r13 + pop r12 + pop rbx + ret +sp_256_mont_mul_order_avx2_4 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Square the Montgomery form number mod the modulus (prime). (r = a * a mod m) +; * +; * r Result of squaring. +; * a Number to square in Montogmery form. +; */ +_text SEGMENT READONLY PARA +sp_256_mont_sqr_order_avx2_4 PROC + push rbp + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + push rbx + mov rax, rdx + ; A[0] * A[1] + mov rdx, QWORD PTR [rax] + mov r15, QWORD PTR [rax+16] + mulx r10, r9, QWORD PTR [rax+8] + ; A[0] * A[3] + mulx r12, r11, QWORD PTR [rax+24] + ; A[2] * A[1] + mov rdx, r15 + mulx rbx, rsi, QWORD PTR [rax+8] + ; A[2] * A[3] + mulx r14, r13, QWORD PTR [rax+24] + xor r15, r15 + adox r11, rsi + adox r12, rbx + ; A[2] * A[0] + mulx rbx, rsi, QWORD PTR [rax] + ; A[1] * A[3] + mov rdx, QWORD PTR [rax+8] + adox r13, r15 + mulx r8, rdi, QWORD PTR [rax+24] + adcx r10, rsi + adox r14, r15 + adcx r11, rbx + adcx r12, rdi + adcx r13, r8 + adcx r14, r15 + ; Double with Carry Flag + xor r15, r15 + ; A[0] * A[0] + mov rdx, QWORD PTR [rax] + mulx rdi, r8, rdx + adcx r9, r9 + adcx r10, r10 + adox r9, rdi + ; A[1] * A[1] + mov rdx, QWORD PTR [rax+8] + mulx rbx, rsi, rdx + adcx r11, r11 + adox r10, rsi + ; A[2] * A[2] + mov rdx, QWORD PTR [rax+16] + mulx rsi, rdi, rdx + adcx r12, r12 + adox r11, rbx + adcx r13, r13 + adox r12, rdi + adcx r14, r14 + ; A[3] * A[3] + mov rdx, QWORD PTR [rax+24] + mulx rbx, rdi, rdx + adox r13, rsi + adcx r15, r15 + adox r14, rdi + adox r15, rbx + ; Start Reduction + mov rbx, 14758798090332847183 + ; A[0] + mov rdx, rbx + imul rdx, r8 + mov rdi, 17562291160714782033 + xor rbp, rbp + mulx rax, rsi, rdi + mov rdi, 13611842547513532036 + adcx r8, rsi + adox r9, rax + mulx rax, rsi, rdi + mov rdi, 18446744073709551615 + adcx r9, rsi + adox r10, rax + mulx rax, rsi, rdi + mov rdi, 18446744069414584320 + adcx r10, rsi + adox r11, rax + mulx rax, rsi, rdi + adcx r11, rsi + adox r12, rax + adcx r12, rbp + mov r8, rbp + ; carry + adox r8, rbp + adcx r8, rbp + ; A[1] + mov rdx, rbx + imul rdx, r9 + mov rdi, 17562291160714782033 + xor rbp, rbp + mulx rax, rsi, rdi + mov rdi, 13611842547513532036 + adcx r9, rsi + adox r10, rax + mulx rax, rsi, rdi + mov rdi, 18446744073709551615 + adcx r10, rsi + adox r11, rax + mulx rax, rsi, rdi + mov rdi, 18446744069414584320 + adcx r11, rsi + adox r12, rax + mulx rax, rsi, rdi + adcx r12, rsi + adox r13, rax + adcx r13, r8 + mov r8, rbp + ; carry + adox r8, rbp + adcx r8, rbp + ; A[2] + mov rdx, rbx + imul rdx, r10 + mov rdi, 17562291160714782033 + xor rbp, rbp + mulx rax, rsi, rdi + mov rdi, 13611842547513532036 + adcx r10, rsi + adox r11, rax + mulx rax, rsi, rdi + mov rdi, 18446744073709551615 + adcx r11, rsi + adox r12, rax + mulx rax, rsi, rdi + mov rdi, 18446744069414584320 + adcx r12, rsi + adox r13, rax + mulx rax, rsi, rdi + adcx r13, rsi + adox r14, rax + adcx r14, r8 + mov r8, rbp + ; carry + adox r8, rbp + adcx r8, rbp + ; A[3] + mov rdx, rbx + imul rdx, r11 + mov rdi, 17562291160714782033 + xor rbp, rbp + mulx rax, rsi, rdi + mov rdi, 13611842547513532036 + adcx r11, rsi + adox r12, rax + mulx rax, rsi, rdi + mov rdi, 18446744073709551615 + adcx r12, rsi + adox r13, rax + mulx rax, rsi, rdi + mov rdi, 18446744069414584320 + adcx r13, rsi + adox r14, rax + mulx rax, rsi, rdi + adcx r14, rsi + adox r15, rax + adcx r15, r8 + mov r8, rbp + ; carry + adox r8, rbp + adcx r8, rbp + neg r8 + mov rdi, 17562291160714782033 + mov rbx, 13611842547513532036 + and rdi, r8 + mov rbp, 18446744069414584320 + and rbx, r8 + and rbp, r8 + sub r12, rdi + sbb r13, rbx + mov QWORD PTR [rcx], r12 + sbb r14, r8 + mov QWORD PTR [rcx+8], r13 + sbb r15, rbp + mov QWORD PTR [rcx+16], r14 + mov QWORD PTR [rcx+24], r15 + pop rbx + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + pop rbp + ret +sp_256_mont_sqr_order_avx2_4 ENDP +_text ENDS +ENDIF +; /* Non-constant time modular inversion. +; * +; * @param [out] r Resulting number. +; * @param [in] a Number to invert. +; * @param [in] m Modulus. +; * @return MP_OKAY on success. +; */ +_text SEGMENT READONLY PARA +sp_256_mod_inv_4 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + sub rsp, 513 + mov r9, QWORD PTR [r8] + mov r10, QWORD PTR [r8+8] + mov r11, QWORD PTR [r8+16] + mov r12, QWORD PTR [r8+24] + mov r13, QWORD PTR [rdx] + mov r14, QWORD PTR [rdx+8] + mov r15, QWORD PTR [rdx+16] + mov rdi, QWORD PTR [rdx+24] + mov rsi, 0 + test r13b, 1 + jnz L_256_mod_inv_4_v_even_end +L_256_mod_inv_4_v_even_start: + shrd r13, r14, 1 + shrd r14, r15, 1 + shrd r15, rdi, 1 + shr rdi, 1 + mov BYTE PTR [rsp+rsi], 1 + inc rsi + test r13b, 1 + jz L_256_mod_inv_4_v_even_start +L_256_mod_inv_4_v_even_end: +L_256_mod_inv_4_uv_start: + cmp r12, rdi + jb L_256_mod_inv_4_uv_v + ja L_256_mod_inv_4_uv_u + cmp r11, r15 + jb L_256_mod_inv_4_uv_v + ja L_256_mod_inv_4_uv_u + cmp r10, r14 + jb L_256_mod_inv_4_uv_v + ja L_256_mod_inv_4_uv_u + cmp r9, r13 + jb L_256_mod_inv_4_uv_v +L_256_mod_inv_4_uv_u: + mov BYTE PTR [rsp+rsi], 2 + inc rsi + sub r9, r13 + sbb r10, r14 + sbb r11, r15 + sbb r12, rdi + shrd r9, r10, 1 + shrd r10, r11, 1 + shrd r11, r12, 1 + shr r12, 1 + test r8b, 1 + jnz L_256_mod_inv_4_usubv_even_end +L_256_mod_inv_4_usubv_even_start: + shrd r9, r10, 1 + shrd r10, r11, 1 + shrd r11, r12, 1 + shr r12, 1 + mov BYTE PTR [rsp+rsi], 0 + inc rsi + test r8b, 1 + jz L_256_mod_inv_4_usubv_even_start +L_256_mod_inv_4_usubv_even_end: + cmp r9, 1 + jne L_256_mod_inv_4_uv_start + mov rdx, r10 + or rdx, r11 + jne L_256_mod_inv_4_uv_start + or rdx, r12 + jne L_256_mod_inv_4_uv_start + mov al, 1 + jmp L_256_mod_inv_4_uv_end +L_256_mod_inv_4_uv_v: + mov BYTE PTR [rsp+rsi], 3 + inc rsi + sub r13, r9 + sbb r14, r10 + sbb r15, r11 + sbb rdi, r12 + shrd r13, r14, 1 + shrd r14, r15, 1 + shrd r15, rdi, 1 + shr rdi, 1 + test r13b, 1 + jnz L_256_mod_inv_4_vsubu_even_end +L_256_mod_inv_4_vsubu_even_start: + shrd r13, r14, 1 + shrd r14, r15, 1 + shrd r15, rdi, 1 + shr rdi, 1 + mov BYTE PTR [rsp+rsi], 1 + inc rsi + test r13b, 1 + jz L_256_mod_inv_4_vsubu_even_start +L_256_mod_inv_4_vsubu_even_end: + cmp r13, 1 + jne L_256_mod_inv_4_uv_start + mov rdx, r14 + or rdx, r15 + jne L_256_mod_inv_4_uv_start + or rdx, rdi + jne L_256_mod_inv_4_uv_start + mov al, 0 +L_256_mod_inv_4_uv_end: + mov r9, QWORD PTR [r8] + mov r10, QWORD PTR [r8+8] + mov r11, QWORD PTR [r8+16] + mov r12, QWORD PTR [r8+24] + mov r13, 1 + xor r14, r14 + xor r15, r15 + xor rdi, rdi + mov BYTE PTR [rsp+rsi], 7 + mov dl, BYTE PTR [rsp] + mov rsi, 1 + cmp dl, 1 + je L_256_mod_inv_4_op_div2_d + jl L_256_mod_inv_4_op_div2_b + cmp dl, 3 + je L_256_mod_inv_4_op_d_sub_b + jl L_256_mod_inv_4_op_b_sub_d + jmp L_256_mod_inv_4_op_end +L_256_mod_inv_4_op_b_sub_d: + sub r9, r13 + sbb r10, r14 + sbb r11, r15 + sbb r12, rdi + jnc L_256_mod_inv_4_op_div2_b + add r9, QWORD PTR [r8] + adc r10, QWORD PTR [r8+8] + adc r11, QWORD PTR [r8+16] + adc r12, QWORD PTR [r8+24] +L_256_mod_inv_4_op_div2_b: + test r8b, 1 + mov rdx, 0 + jz L_256_mod_inv_4_op_div2_b_mod + add r9, QWORD PTR [r8] + adc r10, QWORD PTR [r8+8] + adc r11, QWORD PTR [r8+16] + adc r12, QWORD PTR [r8+24] + adc rdx, 0 +L_256_mod_inv_4_op_div2_b_mod: + shrd r9, r10, 1 + shrd r10, r11, 1 + shrd r11, r12, 1 + shrd r12, rdx, 1 + mov dl, BYTE PTR [rsp+rsi] + inc rsi + cmp dl, 1 + je L_256_mod_inv_4_op_div2_d + jl L_256_mod_inv_4_op_div2_b + cmp dl, 3 + je L_256_mod_inv_4_op_d_sub_b + jl L_256_mod_inv_4_op_b_sub_d + jmp L_256_mod_inv_4_op_end +L_256_mod_inv_4_op_d_sub_b: + sub r13, r9 + sbb r14, r10 + sbb r15, r11 + sbb rdi, r12 + jnc L_256_mod_inv_4_op_div2_d + add r13, QWORD PTR [r8] + adc r14, QWORD PTR [r8+8] + adc r15, QWORD PTR [r8+16] + adc rdi, QWORD PTR [r8+24] +L_256_mod_inv_4_op_div2_d: + test r13b, 1 + mov rdx, 0 + jz L_256_mod_inv_4_op_div2_d_mod + add r13, QWORD PTR [r8] + adc r14, QWORD PTR [r8+8] + adc r15, QWORD PTR [r8+16] + adc rdi, QWORD PTR [r8+24] + adc rdx, 0 +L_256_mod_inv_4_op_div2_d_mod: + shrd r13, r14, 1 + shrd r14, r15, 1 + shrd r15, rdi, 1 + shrd rdi, rdx, 1 + mov dl, BYTE PTR [rsp+rsi] + inc rsi + cmp dl, 1 + je L_256_mod_inv_4_op_div2_d + jl L_256_mod_inv_4_op_div2_b + cmp dl, 3 + je L_256_mod_inv_4_op_d_sub_b + jl L_256_mod_inv_4_op_b_sub_d +L_256_mod_inv_4_op_end: + cmp al, 1 + jne L_256_mod_inv_4_store_d + mov QWORD PTR [rcx], r9 + mov QWORD PTR [rcx+8], r10 + mov QWORD PTR [rcx+16], r11 + mov QWORD PTR [rcx+24], r12 + jmp L_256_mod_inv_4_store_end +L_256_mod_inv_4_store_d: + mov QWORD PTR [rcx], r13 + mov QWORD PTR [rcx+8], r14 + mov QWORD PTR [rcx+16], r15 + mov QWORD PTR [rcx+24], rdi +L_256_mod_inv_4_store_end: + add rsp, 513 + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_256_mod_inv_4 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +_DATA SEGMENT +ALIGN 16 +L_sp256_mod_inv_avx2_4_order DWORD 6497617,32001851,62711546,67108863,67043328,0,0,0,41070783,45522014,67108863,1023,4194303,0,0,0 +ptr_L_sp256_mod_inv_avx2_4_order QWORD L_sp256_mod_inv_avx2_4_order +_DATA ENDS +_DATA SEGMENT +ALIGN 16 +L_sp256_mod_inv_avx2_4_one QWORD 1, 0, + 0, 0 +ptr_L_sp256_mod_inv_avx2_4_one QWORD L_sp256_mod_inv_avx2_4_one +_DATA ENDS +_DATA SEGMENT +ALIGN 16 +L_sp256_mod_inv_avx2_4_all_one DWORD 1,1,1,1,1,1,1,1 +ptr_L_sp256_mod_inv_avx2_4_all_one QWORD L_sp256_mod_inv_avx2_4_all_one +_DATA ENDS +_DATA SEGMENT +ALIGN 16 +L_sp256_mod_inv_avx2_4_mask01111 DWORD 0,1,1,1,1,0,0,0 +ptr_L_sp256_mod_inv_avx2_4_mask01111 QWORD L_sp256_mod_inv_avx2_4_mask01111 +_DATA ENDS +_DATA SEGMENT +ALIGN 16 +L_sp256_mod_inv_avx2_4_down_one_dword DWORD 1,2,3,4,5,6,7,7 +ptr_L_sp256_mod_inv_avx2_4_down_one_dword QWORD L_sp256_mod_inv_avx2_4_down_one_dword +_DATA ENDS +_DATA SEGMENT +ALIGN 16 +L_sp256_mod_inv_avx2_4_neg DWORD 0,0,0,0,2147483648,0,0,0 +ptr_L_sp256_mod_inv_avx2_4_neg QWORD L_sp256_mod_inv_avx2_4_neg +_DATA ENDS +_DATA SEGMENT +ALIGN 16 +L_sp256_mod_inv_avx2_4_up_one_dword DWORD 7,0,1,2,3,7,7,7 +ptr_L_sp256_mod_inv_avx2_4_up_one_dword QWORD L_sp256_mod_inv_avx2_4_up_one_dword +_DATA ENDS +_DATA SEGMENT +ALIGN 16 +L_sp256_mod_inv_avx2_4_mask26 DWORD 67108863,67108863,67108863,67108863,67108863,0,0,0 +ptr_L_sp256_mod_inv_avx2_4_mask26 QWORD L_sp256_mod_inv_avx2_4_mask26 +_DATA ENDS +; /* Non-constant time modular inversion. +; * +; * @param [out] r Resulting number. +; * @param [in] a Number to invert. +; * @param [in] m Modulus. +; * @return MP_OKAY on success. +; */ +_text SEGMENT READONLY PARA +sp_256_mod_inv_avx2_4 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + push rbx + mov rax, QWORD PTR [r8] + mov r9, QWORD PTR [r8+8] + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + mov r12, QWORD PTR [rdx] + mov r13, QWORD PTR [rdx+8] + mov r14, QWORD PTR [rdx+16] + mov r15, QWORD PTR [rdx+24] + mov rbx, ptr_L_sp256_mod_inv_avx2_4_order + vmovupd ymm6, [rbx] + vmovupd ymm7, [rbx+32] + mov rbx, ptr_L_sp256_mod_inv_avx2_4_one + vmovupd ymm8, [rbx] + mov rbx, ptr_L_sp256_mod_inv_avx2_4_mask01111 + vmovupd ymm9, [rbx] + mov rbx, ptr_L_sp256_mod_inv_avx2_4_all_one + vmovupd ymm10, [rbx] + mov rbx, ptr_L_sp256_mod_inv_avx2_4_down_one_dword + vmovupd ymm11, [rbx] + mov rbx, ptr_L_sp256_mod_inv_avx2_4_neg + vmovupd ymm12, [rbx] + mov rbx, ptr_L_sp256_mod_inv_avx2_4_up_one_dword + vmovupd ymm13, [rbx] + mov rbx, ptr_L_sp256_mod_inv_avx2_4_mask26 + vmovupd ymm14, [rbx] + vpxor xmm0, xmm0, xmm0 + vpxor xmm1, xmm1, xmm1 + vmovdqu ymm2, ymm8 + vpxor xmm3, xmm3, xmm3 + test r12b, 1 + jnz L_256_mod_inv_avx2_4_v_even_end +L_256_mod_inv_avx2_4_v_even_start: + shrd r12, r13, 1 + shrd r13, r14, 1 + shrd r14, r15, 1 + shr r15, 1 + vptest ymm2, ymm8 + jz L_256_mod_inv_avx2_4_v_even_shr1 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 +L_256_mod_inv_avx2_4_v_even_shr1: + vpand ymm4, ymm2, ymm9 + vpand ymm5, ymm3, ymm10 + vpermd ymm4, ymm11, ymm4 + vpsrad ymm2, ymm2, 1 + vpsrad ymm3, ymm3, 1 + vpslld ymm5, ymm5, 25 + vpslld xmm4, xmm4, 25 + vpaddd ymm2, ymm2, ymm5 + vpaddd ymm3, ymm3, ymm4 + test r12b, 1 + jz L_256_mod_inv_avx2_4_v_even_start +L_256_mod_inv_avx2_4_v_even_end: +L_256_mod_inv_avx2_4_uv_start: + cmp r11, r15 + jb L_256_mod_inv_avx2_4_uv_v + ja L_256_mod_inv_avx2_4_uv_u + cmp r10, r14 + jb L_256_mod_inv_avx2_4_uv_v + ja L_256_mod_inv_avx2_4_uv_u + cmp r9, r13 + jb L_256_mod_inv_avx2_4_uv_v + ja L_256_mod_inv_avx2_4_uv_u + cmp rax, r12 + jb L_256_mod_inv_avx2_4_uv_v +L_256_mod_inv_avx2_4_uv_u: + sub rax, r12 + sbb r9, r13 + vpsubd ymm0, ymm0, ymm2 + sbb r10, r14 + vpsubd ymm1, ymm1, ymm3 + sbb r11, r15 + vptest ymm1, ymm12 + jz L_256_mod_inv_avx2_4_usubv_done_neg + vpaddd ymm0, ymm0, ymm6 + vpaddd ymm1, ymm1, ymm7 +L_256_mod_inv_avx2_4_usubv_done_neg: +L_256_mod_inv_avx2_4_usubv_shr1: + shrd rax, r9, 1 + shrd r9, r10, 1 + shrd r10, r11, 1 + shr r11, 1 + vptest ymm0, ymm8 + jz L_256_mod_inv_avx2_4_usubv_sub_shr1 + vpaddd ymm0, ymm0, ymm6 + vpaddd ymm1, ymm1, ymm7 +L_256_mod_inv_avx2_4_usubv_sub_shr1: + vpand ymm4, ymm0, ymm9 + vpand ymm5, ymm1, ymm10 + vpermd ymm4, ymm11, ymm4 + vpsrad ymm0, ymm0, 1 + vpsrad ymm1, ymm1, 1 + vpslld ymm5, ymm5, 25 + vpslld xmm4, xmm4, 25 + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm4 + test al, 1 + jz L_256_mod_inv_avx2_4_usubv_shr1 + cmp rax, 1 + jne L_256_mod_inv_avx2_4_uv_start + mov rdx, r9 + or rdx, r10 + jne L_256_mod_inv_avx2_4_uv_start + or rdx, r11 + jne L_256_mod_inv_avx2_4_uv_start + vpsrad ymm5, ymm1, 26 + vpsrad ymm4, ymm0, 26 + vpermd ymm5, ymm13, ymm5 + vpand ymm0, ymm0, ymm14 + vpand ymm1, ymm1, ymm14 + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm4 + vpsrad ymm5, ymm1, 26 + vpsrad ymm4, ymm0, 26 + vpermd ymm5, ymm13, ymm5 + vpand ymm0, ymm0, ymm14 + vpand ymm1, ymm1, ymm14 + vpaddd ymm0, ymm0, ymm5 + vpaddd ymm1, ymm1, ymm4 + vpextrd eax, xmm0, 0 + vpextrd r10d, xmm0, 1 + vpextrd r12d, xmm0, 2 + vpextrd r14d, xmm0, 3 + vextracti128 xmm0, ymm0, 1 + vpextrd r9d, xmm1, 0 + vpextrd r11d, xmm1, 1 + vpextrd r13d, xmm1, 2 + vpextrd r15d, xmm1, 3 + vextracti128 xmm1, ymm1, 1 + vpextrd edi, xmm0, 0 + vpextrd esi, xmm1, 0 + jmp L_256_mod_inv_avx2_4_store_done +L_256_mod_inv_avx2_4_uv_v: + sub r12, rax + sbb r13, r9 + vpsubd ymm2, ymm2, ymm0 + sbb r14, r10 + vpsubd ymm3, ymm3, ymm1 + sbb r15, r11 + vptest ymm3, ymm12 + jz L_256_mod_inv_avx2_4_vsubu_done_neg + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 +L_256_mod_inv_avx2_4_vsubu_done_neg: +L_256_mod_inv_avx2_4_vsubu_shr1: + shrd r12, r13, 1 + shrd r13, r14, 1 + shrd r14, r15, 1 + shr r15, 1 + vptest ymm2, ymm8 + jz L_256_mod_inv_avx2_4_vsubu_sub_shr1 + vpaddd ymm2, ymm2, ymm6 + vpaddd ymm3, ymm3, ymm7 +L_256_mod_inv_avx2_4_vsubu_sub_shr1: + vpand ymm4, ymm2, ymm9 + vpand ymm5, ymm3, ymm10 + vpermd ymm4, ymm11, ymm4 + vpsrad ymm2, ymm2, 1 + vpsrad ymm3, ymm3, 1 + vpslld ymm5, ymm5, 25 + vpslld xmm4, xmm4, 25 + vpaddd ymm2, ymm2, ymm5 + vpaddd ymm3, ymm3, ymm4 + test r12b, 1 + jz L_256_mod_inv_avx2_4_vsubu_shr1 + cmp r12, 1 + jne L_256_mod_inv_avx2_4_uv_start + mov rdx, r13 + or rdx, r14 + jne L_256_mod_inv_avx2_4_uv_start + or rdx, r15 + jne L_256_mod_inv_avx2_4_uv_start + vpsrad ymm5, ymm3, 26 + vpsrad ymm4, ymm2, 26 + vpermd ymm5, ymm13, ymm5 + vpand ymm2, ymm2, ymm14 + vpand ymm3, ymm3, ymm14 + vpaddd ymm2, ymm2, ymm5 + vpaddd ymm3, ymm3, ymm4 + vpsrad ymm5, ymm3, 26 + vpsrad ymm4, ymm2, 26 + vpermd ymm5, ymm13, ymm5 + vpand ymm2, ymm2, ymm14 + vpand ymm3, ymm3, ymm14 + vpaddd ymm2, ymm2, ymm5 + vpaddd ymm3, ymm3, ymm4 + vpextrd eax, xmm2, 0 + vpextrd r10d, xmm2, 1 + vpextrd r12d, xmm2, 2 + vpextrd r14d, xmm2, 3 + vextracti128 xmm2, ymm2, 1 + vpextrd r9d, xmm3, 0 + vpextrd r11d, xmm3, 1 + vpextrd r13d, xmm3, 2 + vpextrd r15d, xmm3, 3 + vextracti128 xmm3, ymm3, 1 + vpextrd edi, xmm2, 0 + vpextrd esi, xmm3, 0 +L_256_mod_inv_avx2_4_store_done: + movslq rax, eax + shl r9, 26 + add rax, r9 + movslq r10, r10d + shl r11, 26 + add r10, r11 + movslq r12, r12d + shl r13, 26 + add r12, r13 + movslq r14, r14d + shl r15, 26 + add r14, r15 + movslq rdi, edi + shl rsi, 26 + add rdi, rsi + mov r9, r10 + mov r11, r12 + mov r13, r14 + shl r9, 52 + sar r10, 12 + shl r11, 40 + sar r12, 24 + shl r13, 28 + sar r14, 36 + shl rdi, 16 + add rax, r9 + adc r10, r11 + adc r12, r13 + adc r14, rdi + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r10 + mov QWORD PTR [rcx+16], r12 + mov QWORD PTR [rcx+24], r14 + pop rbx + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_256_mod_inv_avx2_4 ENDP +_text ENDS +ENDIF +ENDIF +IFDEF WOLFSSL_SP_384 +; /* Multiply a and b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_384_mul_6 PROC + push r12 + mov r9, rdx + sub rsp, 48 + ; A[0] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9] + xor r12, r12 + mov QWORD PTR [rsp], rax + mov r11, rdx + ; A[0] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[1] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+8] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rsp+8], r11 + ; A[0] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[1] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+8] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[2] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+16] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rsp+16], r12 + ; A[0] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[1] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+8] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[2] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+16] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[3] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+24] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rsp+24], r10 + ; A[0] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[1] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+8] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[2] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+16] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[3] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+24] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[4] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+32] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rsp+32], r11 + ; A[0] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[1] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+8] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[2] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+16] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[3] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+24] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[4] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+32] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[5] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+40] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rsp+40], r12 + ; A[1] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+8] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[2] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+16] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[3] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+24] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[4] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+32] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[5] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+40] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rcx+48], r10 + ; A[2] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+16] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[3] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+24] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[4] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+32] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[5] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+40] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rcx+56], r11 + ; A[3] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+24] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[4] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+32] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[5] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+40] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rcx+64], r12 + ; A[4] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+32] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[5] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+40] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rcx+72], r10 + ; A[5] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+40] + add r11, rax + adc r12, rdx + mov QWORD PTR [rcx+80], r11 + mov QWORD PTR [rcx+88], r12 + mov rax, QWORD PTR [rsp] + mov rdx, QWORD PTR [rsp+8] + mov r10, QWORD PTR [rsp+16] + mov r11, QWORD PTR [rsp+24] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], rdx + mov QWORD PTR [rcx+16], r10 + mov QWORD PTR [rcx+24], r11 + mov rax, QWORD PTR [rsp+32] + mov rdx, QWORD PTR [rsp+40] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], rdx + add rsp, 48 + pop r12 + ret +sp_384_mul_6 ENDP +_text ENDS +; /* Square a and put result in r. (r = a * a) +; * +; * r A single precision integer. +; * a A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_384_sqr_6 PROC + push r12 + push r13 + push r14 + mov r8, rdx + sub rsp, 48 + ; A[0] * A[0] + mov rax, QWORD PTR [r8] + mul rax + xor r11, r11 + mov QWORD PTR [rsp], rax + mov r10, rdx + ; A[0] * A[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r8] + xor r9, r9 + add r10, rax + adc r11, rdx + adc r9, 0 + add r10, rax + adc r11, rdx + adc r9, 0 + mov QWORD PTR [rsp+8], r10 + ; A[0] * A[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r8] + xor r10, r10 + add r11, rax + adc r9, rdx + adc r10, 0 + add r11, rax + adc r9, rdx + adc r10, 0 + ; A[1] * A[1] + mov rax, QWORD PTR [r8+8] + mul rax + add r11, rax + adc r9, rdx + adc r10, 0 + mov QWORD PTR [rsp+16], r11 + ; A[0] * A[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r8] + xor r11, r11 + add r9, rax + adc r10, rdx + adc r11, 0 + add r9, rax + adc r10, rdx + adc r11, 0 + ; A[1] * A[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r8+8] + add r9, rax + adc r10, rdx + adc r11, 0 + add r9, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rsp+24], r9 + ; A[0] * A[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r8] + xor r9, r9 + add r10, rax + adc r11, rdx + adc r9, 0 + add r10, rax + adc r11, rdx + adc r9, 0 + ; A[1] * A[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r8+8] + add r10, rax + adc r11, rdx + adc r9, 0 + add r10, rax + adc r11, rdx + adc r9, 0 + ; A[2] * A[2] + mov rax, QWORD PTR [r8+16] + mul rax + add r10, rax + adc r11, rdx + adc r9, 0 + mov QWORD PTR [rsp+32], r10 + ; A[0] * A[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r8] + xor r10, r10 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r11, r12 + adc r9, r13 + adc r10, r14 + mov QWORD PTR [rsp+40], r11 + ; A[1] * A[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r8+8] + xor r11, r11 + add r9, rax + adc r10, rdx + adc r11, 0 + add r9, rax + adc r10, rdx + adc r11, 0 + ; A[2] * A[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r8+16] + add r9, rax + adc r10, rdx + adc r11, 0 + add r9, rax + adc r10, rdx + adc r11, 0 + ; A[3] * A[3] + mov rax, QWORD PTR [r8+24] + mul rax + add r9, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rcx+48], r9 + ; A[2] * A[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r8+16] + xor r9, r9 + add r10, rax + adc r11, rdx + adc r9, 0 + add r10, rax + adc r11, rdx + adc r9, 0 + ; A[3] * A[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r8+24] + add r10, rax + adc r11, rdx + adc r9, 0 + add r10, rax + adc r11, rdx + adc r9, 0 + mov QWORD PTR [rcx+56], r10 + ; A[3] * A[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r8+24] + xor r10, r10 + add r11, rax + adc r9, rdx + adc r10, 0 + add r11, rax + adc r9, rdx + adc r10, 0 + ; A[4] * A[4] + mov rax, QWORD PTR [r8+32] + mul rax + add r11, rax + adc r9, rdx + adc r10, 0 + mov QWORD PTR [rcx+64], r11 + ; A[4] * A[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r8+32] + xor r11, r11 + add r9, rax + adc r10, rdx + adc r11, 0 + add r9, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rcx+72], r9 + ; A[5] * A[5] + mov rax, QWORD PTR [r8+40] + mul rax + add r10, rax + adc r11, rdx + mov QWORD PTR [rcx+80], r10 + mov QWORD PTR [rcx+88], r11 + mov rax, QWORD PTR [rsp] + mov rdx, QWORD PTR [rsp+8] + mov r12, QWORD PTR [rsp+16] + mov r13, QWORD PTR [rsp+24] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], rdx + mov QWORD PTR [rcx+16], r12 + mov QWORD PTR [rcx+24], r13 + mov rax, QWORD PTR [rsp+32] + mov rdx, QWORD PTR [rsp+40] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], rdx + add rsp, 48 + pop r14 + pop r13 + pop r12 + ret +sp_384_sqr_6 ENDP +_text ENDS +; /* Add b to a into r. (r = a + b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_384_add_6 PROC + ; Add + mov r9, QWORD PTR [rdx] + xor rax, rax + add r9, QWORD PTR [r8] + mov r10, QWORD PTR [rdx+8] + mov QWORD PTR [rcx], r9 + adc r10, QWORD PTR [r8+8] + mov r9, QWORD PTR [rdx+16] + mov QWORD PTR [rcx+8], r10 + adc r9, QWORD PTR [r8+16] + mov r10, QWORD PTR [rdx+24] + mov QWORD PTR [rcx+16], r9 + adc r10, QWORD PTR [r8+24] + mov r9, QWORD PTR [rdx+32] + mov QWORD PTR [rcx+24], r10 + adc r9, QWORD PTR [r8+32] + mov r10, QWORD PTR [rdx+40] + mov QWORD PTR [rcx+32], r9 + adc r10, QWORD PTR [r8+40] + mov QWORD PTR [rcx+40], r10 + adc rax, 0 + ret +sp_384_add_6 ENDP +_text ENDS +; /* Sub b from a into r. (r = a - b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_384_sub_6 PROC + push r12 + push r13 + push r14 + xor rax, rax + mov r9, QWORD PTR [rdx] + mov r10, QWORD PTR [rdx+8] + mov r11, QWORD PTR [rdx+16] + mov r12, QWORD PTR [rdx+24] + mov r13, QWORD PTR [rdx+32] + mov r14, QWORD PTR [rdx+40] + sub r9, QWORD PTR [r8] + sbb r10, QWORD PTR [r8+8] + sbb r11, QWORD PTR [r8+16] + sbb r12, QWORD PTR [r8+24] + sbb r13, QWORD PTR [r8+32] + sbb r14, QWORD PTR [r8+40] + mov QWORD PTR [rcx], r9 + mov QWORD PTR [rcx+8], r10 + mov QWORD PTR [rcx+16], r11 + mov QWORD PTR [rcx+24], r12 + mov QWORD PTR [rcx+32], r13 + mov QWORD PTR [rcx+40], r14 + sbb rax, 0 + pop r14 + pop r13 + pop r12 + ret +sp_384_sub_6 ENDP +_text ENDS +; /* Conditionally copy a into r using the mask m. +; * m is -1 to copy and 0 when not. +; * +; * r A single precision number to copy over. +; * a A single precision number to copy. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_384_cond_copy_6 PROC + push r12 + push r13 + mov rax, QWORD PTR [rcx] + mov r9, QWORD PTR [rcx+8] + mov r10, QWORD PTR [rcx+16] + mov r11, QWORD PTR [rcx+24] + mov r12, QWORD PTR [rcx+32] + mov r13, QWORD PTR [rcx+40] + xor rax, QWORD PTR [rdx] + xor r9, QWORD PTR [rdx+8] + xor r10, QWORD PTR [rdx+16] + xor r11, QWORD PTR [rdx+24] + xor r12, QWORD PTR [rdx+32] + xor r13, QWORD PTR [rdx+40] + and rax, r8 + and r9, r8 + and r10, r8 + and r11, r8 + and r12, r8 + and r13, r8 + xor QWORD PTR [rcx], rax + xor QWORD PTR [rcx+8], r9 + xor QWORD PTR [rcx+16], r10 + xor QWORD PTR [rcx+24], r11 + xor QWORD PTR [rcx+32], r12 + xor QWORD PTR [rcx+40], r13 + pop r13 + pop r12 + ret +sp_384_cond_copy_6 ENDP +_text ENDS +; /* Conditionally subtract b from a using the mask m. +; * m is -1 to subtract and 0 when not copying. +; * +; * r A single precision number representing condition subtract result. +; * a A single precision number to subtract from. +; * b A single precision number to subtract. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_384_cond_sub_6 PROC + sub rsp, 48 + mov rax, 0 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp], r10 + mov QWORD PTR [rsp+8], r11 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+16], r10 + mov QWORD PTR [rsp+24], r11 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+32], r10 + mov QWORD PTR [rsp+40], r11 + mov r10, QWORD PTR [rdx] + mov r8, QWORD PTR [rsp] + sub r10, r8 + mov r11, QWORD PTR [rdx+8] + mov r8, QWORD PTR [rsp+8] + sbb r11, r8 + mov QWORD PTR [rcx], r10 + mov r10, QWORD PTR [rdx+16] + mov r8, QWORD PTR [rsp+16] + sbb r10, r8 + mov QWORD PTR [rcx+8], r11 + mov r11, QWORD PTR [rdx+24] + mov r8, QWORD PTR [rsp+24] + sbb r11, r8 + mov QWORD PTR [rcx+16], r10 + mov r10, QWORD PTR [rdx+32] + mov r8, QWORD PTR [rsp+32] + sbb r10, r8 + mov QWORD PTR [rcx+24], r11 + mov r11, QWORD PTR [rdx+40] + mov r8, QWORD PTR [rsp+40] + sbb r11, r8 + mov QWORD PTR [rcx+32], r10 + mov QWORD PTR [rcx+40], r11 + sbb rax, 0 + add rsp, 48 + ret +sp_384_cond_sub_6 ENDP +_text ENDS +; /* Reduce the number back to 384 bits using Montgomery reduction. +; * +; * a A single precision number to reduce in place. +; * m The single precision number representing the modulus. +; * mp The digit representing the negative inverse of m mod 2^n. +; */ +_text SEGMENT READONLY PARA +sp_384_mont_reduce_6 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + push rbx + push rbp + mov r12, QWORD PTR [rcx] + mov r13, QWORD PTR [rcx+8] + mov r14, QWORD PTR [rcx+16] + mov r15, QWORD PTR [rcx+24] + mov rdi, QWORD PTR [rcx+32] + mov rsi, QWORD PTR [rcx+40] + xor r11, r11 + ; a[0-7] += m[0-5] * mu[0..1] = m[0-5] * (a[0..1] * mp) + mov rbx, QWORD PTR [rcx+48] + mov rbp, QWORD PTR [rcx+56] + mov rdx, r12 + mov rax, r13 + shld rax, rdx, 32 + shl rdx, 32 + add rdx, r12 + adc rax, r13 + add rax, r12 + mov r8, rdx + mov r9, rax + mov r10, rax + shld r9, r8, 32 + shl r8, 32 + shr r10, 32 + add r12, r8 + adc r13, r9 + adc r14, r10 + adc r15, 0 + adc rdi, 0 + adc rsi, 0 + adc rbx, rdx + adc rbp, rax + adc r11, 0 + add r8, rax + adc r9, rdx + adc r10, rax + mov rax, 0 + adc rax, 0 + sub r14, r9 + sbb r15, r10 + sbb rdi, rax + sbb rsi, 0 + sbb rbx, 0 + sbb rbp, 0 + sbb r11, 0 + ; a[2-9] += m[0-5] * mu[0..1] = m[0-5] * (a[2..3] * mp) + mov r12, QWORD PTR [rcx+64] + mov r13, QWORD PTR [rcx+72] + mov rdx, r14 + mov rax, r15 + shld rax, rdx, 32 + shl rdx, 32 + add rdx, r14 + adc rax, r15 + add rax, r14 + mov r8, rdx + mov r9, rax + mov r10, rax + shld r9, r8, 32 + shl r8, 32 + shr r10, 32 + add r12, r11 + adc r13, 0 + mov r11, 0 + adc r11, 0 + add r14, r8 + adc r15, r9 + adc rdi, r10 + adc rsi, 0 + adc rbx, 0 + adc rbp, 0 + adc r12, rdx + adc r13, rax + adc r11, 0 + add r8, rax + adc r9, rdx + adc r10, rax + mov rax, 0 + adc rax, 0 + sub rdi, r9 + sbb rsi, r10 + sbb rbx, rax + sbb rbp, 0 + sbb r12, 0 + sbb r13, 0 + sbb r11, 0 + ; a[4-11] += m[0-5] * mu[0..1] = m[0-5] * (a[4..5] * mp) + mov r14, QWORD PTR [rcx+80] + mov r15, QWORD PTR [rcx+88] + mov rdx, rdi + mov rax, rsi + shld rax, rdx, 32 + shl rdx, 32 + add rdx, rdi + adc rax, rsi + add rax, rdi + mov r8, rdx + mov r9, rax + mov r10, rax + shld r9, r8, 32 + shl r8, 32 + shr r10, 32 + add r14, r11 + adc r15, 0 + mov r11, 0 + adc r11, 0 + add rdi, r8 + adc rsi, r9 + adc rbx, r10 + adc rbp, 0 + adc r12, 0 + adc r13, 0 + adc r14, rdx + adc r15, rax + adc r11, 0 + add r8, rax + adc r9, rdx + adc r10, rax + mov rax, 0 + adc rax, 0 + sub rbx, r9 + sbb rbp, r10 + sbb r12, rax + sbb r13, 0 + sbb r14, 0 + sbb r15, 0 + sbb r11, 0 + ; Subtract mod if carry + neg r11 + mov r10, 18446744073709551614 + mov r8, r11 + mov r9, r11 + shr r8, 32 + shl r9, 32 + and r10, r11 + sub rbx, r8 + sbb rbp, r9 + sbb r12, r10 + sbb r13, r11 + sbb r14, r11 + sbb r15, r11 + mov QWORD PTR [rcx], rbx + mov QWORD PTR [rcx+8], rbp + mov QWORD PTR [rcx+16], r12 + mov QWORD PTR [rcx+24], r13 + mov QWORD PTR [rcx+32], r14 + mov QWORD PTR [rcx+40], r15 + pop rbp + pop rbx + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_384_mont_reduce_6 ENDP +_text ENDS +; /* Reduce the number back to 384 bits using Montgomery reduction. +; * +; * a A single precision number to reduce in place. +; * m The single precision number representing the modulus. +; * mp The digit representing the negative inverse of m mod 2^n. +; */ +_text SEGMENT READONLY PARA +sp_384_mont_reduce_order_6 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + mov r9, rdx + xor rsi, rsi + ; i = 6 + mov r10, 6 + mov r15, QWORD PTR [rcx] + mov rdi, QWORD PTR [rcx+8] +L_384_mont_loop_order_6: + ; mu = a[i] * mp + mov r13, r15 + imul r13, r8 + ; a[i+0] += m[0] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9] + add r15, rax + adc r12, rdx + ; a[i+1] += m[1] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+8] + mov r15, rdi + add r15, rax + adc r11, rdx + add r15, r12 + adc r11, 0 + ; a[i+2] += m[2] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+16] + mov rdi, QWORD PTR [rcx+16] + add rdi, rax + adc r12, rdx + add rdi, r11 + adc r12, 0 + ; a[i+3] += m[3] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+24] + mov r14, QWORD PTR [rcx+24] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+24], r14 + adc r11, 0 + ; a[i+4] += m[4] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+32] + mov r14, QWORD PTR [rcx+32] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+32], r14 + adc r12, 0 + ; a[i+5] += m[5] * mu + mov rax, r13 + mul QWORD PTR [r9+40] + mov r14, QWORD PTR [rcx+40] + add r12, rax + adc rdx, rsi + mov rsi, 0 + adc rsi, 0 + add r14, r12 + mov QWORD PTR [rcx+40], r14 + adc QWORD PTR [rcx+48], rdx + adc rsi, 0 + ; i -= 1 + add rcx, 8 + dec r10 + jnz L_384_mont_loop_order_6 + mov QWORD PTR [rcx], r15 + mov QWORD PTR [rcx+8], rdi + neg rsi +IFDEF _WIN64 + mov r8, r9 + mov r9, rsi +ELSE + mov r9, rsi + mov r8, r9 +ENDIF + mov rdx, rcx + mov rcx, rcx + sub rcx, 48 + call sp_384_cond_sub_6 + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_384_mont_reduce_order_6 ENDP +_text ENDS +; /* Compare a with b in constant time. +; * +; * a A single precision integer. +; * b A single precision integer. +; * return -ve, 0 or +ve if a is less than, equal to or greater than b +; * respectively. +; */ +_text SEGMENT READONLY PARA +sp_384_cmp_6 PROC + push r12 + xor r9, r9 + mov r8, -1 + mov rax, -1 + mov r10, 1 + mov r11, QWORD PTR [rcx+40] + mov r12, QWORD PTR [rdx+40] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+32] + mov r12, QWORD PTR [rdx+32] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+24] + mov r12, QWORD PTR [rdx+24] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+16] + mov r12, QWORD PTR [rdx+16] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+8] + mov r12, QWORD PTR [rdx+8] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx] + mov r12, QWORD PTR [rdx] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + xor rax, r8 + pop r12 + ret +sp_384_cmp_6 ENDP +_text ENDS +; /* Add a to a into r. (r = a + a) +; * +; * r A single precision integer. +; * a A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_384_dbl_6 PROC + mov r8, QWORD PTR [rdx] + xor rax, rax + add r8, r8 + mov r9, QWORD PTR [rdx+8] + mov QWORD PTR [rcx], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+16] + mov QWORD PTR [rcx+8], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+24] + mov QWORD PTR [rcx+16], r8 + adc r9, r9 + mov r8, QWORD PTR [rdx+32] + mov QWORD PTR [rcx+24], r9 + adc r8, r8 + mov r9, QWORD PTR [rdx+40] + mov QWORD PTR [rcx+32], r8 + adc r9, r9 + mov QWORD PTR [rcx+40], r9 + adc rax, 0 + ret +sp_384_dbl_6 ENDP +_text ENDS +; /* Conditionally add a and b using the mask m. +; * m is -1 to add and 0 when not. +; * +; * r A single precision number representing conditional add result. +; * a A single precision number to add with. +; * b A single precision number to add. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_384_cond_add_6 PROC + sub rsp, 48 + mov rax, 0 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp], r10 + mov QWORD PTR [rsp+8], r11 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+16], r10 + mov QWORD PTR [rsp+24], r11 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+32], r10 + mov QWORD PTR [rsp+40], r11 + mov r10, QWORD PTR [rdx] + mov r8, QWORD PTR [rsp] + add r10, r8 + mov r11, QWORD PTR [rdx+8] + mov r8, QWORD PTR [rsp+8] + adc r11, r8 + mov QWORD PTR [rcx], r10 + mov r10, QWORD PTR [rdx+16] + mov r8, QWORD PTR [rsp+16] + adc r10, r8 + mov QWORD PTR [rcx+8], r11 + mov r11, QWORD PTR [rdx+24] + mov r8, QWORD PTR [rsp+24] + adc r11, r8 + mov QWORD PTR [rcx+16], r10 + mov r10, QWORD PTR [rdx+32] + mov r8, QWORD PTR [rsp+32] + adc r10, r8 + mov QWORD PTR [rcx+24], r11 + mov r11, QWORD PTR [rdx+40] + mov r8, QWORD PTR [rsp+40] + adc r11, r8 + mov QWORD PTR [rcx+32], r10 + mov QWORD PTR [rcx+40], r11 + adc rax, 0 + add rsp, 48 + ret +sp_384_cond_add_6 ENDP +_text ENDS +; /* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m) +; * +; * r Result of division by 2. +; * a Number to divide. +; * m Modulus (prime). +; */ +_text SEGMENT READONLY PARA +sp_384_div2_6 PROC + push r12 + push r13 + sub rsp, 48 + mov r13, QWORD PTR [rdx] + xor r12, r12 + mov rax, r13 + and r13, 1 + neg r13 + mov r10, QWORD PTR [r8] + and r10, r13 + mov QWORD PTR [rsp], r10 + mov r10, QWORD PTR [r8+8] + and r10, r13 + mov QWORD PTR [rsp+8], r10 + mov r10, QWORD PTR [r8+16] + and r10, r13 + mov QWORD PTR [rsp+16], r10 + mov r10, QWORD PTR [r8+24] + and r10, r13 + mov QWORD PTR [rsp+24], r10 + mov r10, QWORD PTR [r8+32] + and r10, r13 + mov QWORD PTR [rsp+32], r10 + mov r10, QWORD PTR [r8+40] + and r10, r13 + mov QWORD PTR [rsp+40], r10 + add QWORD PTR [rsp], rax + mov rax, QWORD PTR [rdx+8] + adc QWORD PTR [rsp+8], rax + mov rax, QWORD PTR [rdx+16] + adc QWORD PTR [rsp+16], rax + mov rax, QWORD PTR [rdx+24] + adc QWORD PTR [rsp+24], rax + mov rax, QWORD PTR [rdx+32] + adc QWORD PTR [rsp+32], rax + mov rax, QWORD PTR [rdx+40] + adc QWORD PTR [rsp+40], rax + adc r12, 0 + mov rax, QWORD PTR [rsp] + mov r9, QWORD PTR [rsp+8] + shrd rax, r9, 1 + mov QWORD PTR [rcx], rax + mov rax, QWORD PTR [rsp+16] + shrd r9, rax, 1 + mov QWORD PTR [rcx+8], r9 + mov r9, QWORD PTR [rsp+24] + shrd rax, r9, 1 + mov QWORD PTR [rcx+16], rax + mov rax, QWORD PTR [rsp+32] + shrd r9, rax, 1 + mov QWORD PTR [rcx+24], r9 + mov r9, QWORD PTR [rsp+40] + shrd rax, r9, 1 + mov QWORD PTR [rcx+32], rax + shrd r9, r12, 1 + mov QWORD PTR [rcx+40], r9 + add rsp, 48 + pop r13 + pop r12 + ret +sp_384_div2_6 ENDP +_text ENDS +IFNDEF WC_NO_CACHE_RESISTANT +; /* Touch each possible point that could be being copied. +; * +; * r Point to copy into. +; * table Table - start of the entires to access +; * idx Index of point to retrieve. +; */ +_text SEGMENT READONLY PARA +sp_384_get_point_33_6 PROC + mov rax, 1 + movd xmm13, r8d + add rdx, 296 + movd xmm15, eax + mov rax, 32 + pshufd xmm15, xmm15, 0 + pshufd xmm13, xmm13, 0 + pxor xmm14, xmm14 + pxor xmm0, xmm0 + pxor xmm1, xmm1 + pxor xmm2, xmm2 + pxor xmm3, xmm3 + pxor xmm4, xmm4 + pxor xmm5, xmm5 + movdqa xmm14, xmm15 +L_384_get_point_33_6_start: + movdqa xmm12, xmm14 + paddd xmm14, xmm15 + pcmpeqd xmm12, xmm13 + movdqu xmm6, [rdx] + movdqu xmm7, [rdx+16] + movdqu xmm8, [rdx+32] + movdqu xmm9, [rdx+96] + movdqu xmm10, [rdx+112] + movdqu xmm11, [rdx+128] + add rdx, 296 + pand xmm6, xmm12 + pand xmm7, xmm12 + pand xmm8, xmm12 + pand xmm9, xmm12 + pand xmm10, xmm12 + pand xmm11, xmm12 + por xmm0, xmm6 + por xmm1, xmm7 + por xmm2, xmm8 + por xmm3, xmm9 + por xmm4, xmm10 + por xmm5, xmm11 + dec rax + jnz L_384_get_point_33_6_start + movdqu [rcx], xmm0 + movdqu [rcx+16], xmm1 + movdqu [rcx+32], xmm2 + movdqu [rcx+96], xmm3 + movdqu [rcx+112], xmm4 + movdqu [rcx+128], xmm5 + mov rax, 1 + movd xmm13, r8d + sub rdx, 9472 + movd xmm15, eax + mov rax, 32 + pshufd xmm15, xmm15, 0 + pshufd xmm13, xmm13, 0 + pxor xmm14, xmm14 + pxor xmm0, xmm0 + pxor xmm1, xmm1 + pxor xmm2, xmm2 + movdqa xmm14, xmm15 +L_384_get_point_33_6_start_2: + movdqa xmm12, xmm14 + paddd xmm14, xmm15 + pcmpeqd xmm12, xmm13 + movdqu xmm6, [rdx+192] + movdqu xmm7, [rdx+208] + movdqu xmm8, [rdx+224] + add rdx, 296 + pand xmm6, xmm12 + pand xmm7, xmm12 + pand xmm8, xmm12 + por xmm0, xmm6 + por xmm1, xmm7 + por xmm2, xmm8 + dec rax + jnz L_384_get_point_33_6_start_2 + movdqu [rcx+192], xmm0 + movdqu [rcx+208], xmm1 + movdqu [rcx+224], xmm2 + ret +sp_384_get_point_33_6 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Touch each possible point that could be being copied. +; * +; * r Point to copy into. +; * table Table - start of the entires to access +; * idx Index of point to retrieve. +; */ +_text SEGMENT READONLY PARA +sp_384_get_point_33_avx2_6 PROC + mov rax, 1 + movd xmm13, r8d + add rdx, 296 + movd xmm15, eax + mov rax, 32 + vpxor ymm14, ymm14, ymm14 + vpermd ymm13, ymm14, ymm13 + vpermd ymm15, ymm14, ymm15 + vpxor ymm0, ymm0, ymm0 + vpxor xmm1, xmm1, xmm1 + vpxor ymm2, ymm2, ymm2 + vpxor xmm3, xmm3, xmm3 + vpxor ymm4, ymm4, ymm4 + vpxor xmm5, xmm5, xmm5 + vmovdqa ymm14, ymm15 +L_384_get_point_33_avx2_6_start: + vpcmpeqd ymm12, ymm14, ymm13 + vpaddd ymm14, ymm14, ymm15 + vmovupd ymm6, [rdx] + vmovdqu xmm7, OWORD PTR [rdx+32] + vmovupd ymm8, [rdx+96] + vmovdqu xmm9, OWORD PTR [rdx+128] + vmovupd ymm10, [rdx+192] + vmovdqu xmm11, OWORD PTR [rdx+224] + add rdx, 296 + vpand ymm6, ymm6, ymm12 + vpand xmm7, xmm7, xmm12 + vpand ymm8, ymm8, ymm12 + vpand xmm9, xmm9, xmm12 + vpand ymm10, ymm10, ymm12 + vpand xmm11, xmm11, xmm12 + vpor ymm0, ymm0, ymm6 + vpor xmm1, xmm1, xmm7 + vpor ymm2, ymm2, ymm8 + vpor xmm3, xmm3, xmm9 + vpor ymm4, ymm4, ymm10 + vpor xmm5, xmm5, xmm11 + dec rax + jnz L_384_get_point_33_avx2_6_start + vmovupd YMMWORD PTR [rcx], ymm0 + vmovdqu [rcx+32], xmm1 + vmovupd YMMWORD PTR [rcx+96], ymm2 + vmovdqu [rcx+128], xmm3 + vmovupd YMMWORD PTR [rcx+192], ymm4 + vmovdqu [rcx+224], xmm5 + ret +sp_384_get_point_33_avx2_6 ENDP +_text ENDS +ENDIF +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Multiply a and b into r. (r = a * b) +; * +; * r Result of multiplication. +; * a First number to multiply. +; * b Second number to multiply. +; */ +_text SEGMENT READONLY PARA +sp_384_mul_avx2_6 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + push rbx + mov rax, rdx + sub rsp, 40 + xor rbx, rbx + mov rdx, QWORD PTR [rax] + ; A[0] * B[0] + mulx r12, r11, QWORD PTR [r8] + ; A[0] * B[1] + mulx r13, r9, QWORD PTR [r8+8] + adcx r12, r9 + ; A[0] * B[2] + mulx r14, r9, QWORD PTR [r8+16] + adcx r13, r9 + ; A[0] * B[3] + mulx r15, r9, QWORD PTR [r8+24] + adcx r14, r9 + ; A[0] * B[4] + mulx rdi, r9, QWORD PTR [r8+32] + adcx r15, r9 + ; A[0] * B[5] + mulx rsi, r9, QWORD PTR [r8+40] + adcx rdi, r9 + adcx rsi, rbx + mov QWORD PTR [rsp], r11 + mov r11, 0 + adcx r11, rbx + xor rbx, rbx + mov rdx, QWORD PTR [rax+8] + ; A[1] * B[0] + mulx r10, r9, QWORD PTR [r8] + adcx r12, r9 + adox r13, r10 + ; A[1] * B[1] + mulx r10, r9, QWORD PTR [r8+8] + adcx r13, r9 + adox r14, r10 + ; A[1] * B[2] + mulx r10, r9, QWORD PTR [r8+16] + adcx r14, r9 + adox r15, r10 + ; A[1] * B[3] + mulx r10, r9, QWORD PTR [r8+24] + adcx r15, r9 + adox rdi, r10 + ; A[1] * B[4] + mulx r10, r9, QWORD PTR [r8+32] + adcx rdi, r9 + adox rsi, r10 + ; A[1] * B[5] + mulx r10, r9, QWORD PTR [r8+40] + adcx rsi, r9 + adox r11, r10 + adcx r11, rbx + mov QWORD PTR [rsp+8], r12 + mov r12, 0 + adcx r12, rbx + adox r12, rbx + xor rbx, rbx + mov rdx, QWORD PTR [rax+16] + ; A[2] * B[0] + mulx r10, r9, QWORD PTR [r8] + adcx r13, r9 + adox r14, r10 + ; A[2] * B[1] + mulx r10, r9, QWORD PTR [r8+8] + adcx r14, r9 + adox r15, r10 + ; A[2] * B[2] + mulx r10, r9, QWORD PTR [r8+16] + adcx r15, r9 + adox rdi, r10 + ; A[2] * B[3] + mulx r10, r9, QWORD PTR [r8+24] + adcx rdi, r9 + adox rsi, r10 + ; A[2] * B[4] + mulx r10, r9, QWORD PTR [r8+32] + adcx rsi, r9 + adox r11, r10 + ; A[2] * B[5] + mulx r10, r9, QWORD PTR [r8+40] + adcx r11, r9 + adox r12, r10 + adcx r12, rbx + mov QWORD PTR [rsp+16], r13 + mov r13, 0 + adcx r13, rbx + adox r13, rbx + xor rbx, rbx + mov rdx, QWORD PTR [rax+24] + ; A[3] * B[0] + mulx r10, r9, QWORD PTR [r8] + adcx r14, r9 + adox r15, r10 + ; A[3] * B[1] + mulx r10, r9, QWORD PTR [r8+8] + adcx r15, r9 + adox rdi, r10 + ; A[3] * B[2] + mulx r10, r9, QWORD PTR [r8+16] + adcx rdi, r9 + adox rsi, r10 + ; A[3] * B[3] + mulx r10, r9, QWORD PTR [r8+24] + adcx rsi, r9 + adox r11, r10 + ; A[3] * B[4] + mulx r10, r9, QWORD PTR [r8+32] + adcx r11, r9 + adox r12, r10 + ; A[3] * B[5] + mulx r10, r9, QWORD PTR [r8+40] + adcx r12, r9 + adox r13, r10 + adcx r13, rbx + mov QWORD PTR [rsp+24], r14 + mov r14, 0 + adcx r14, rbx + adox r14, rbx + xor rbx, rbx + mov rdx, QWORD PTR [rax+32] + ; A[4] * B[0] + mulx r10, r9, QWORD PTR [r8] + adcx r15, r9 + adox rdi, r10 + ; A[4] * B[1] + mulx r10, r9, QWORD PTR [r8+8] + adcx rdi, r9 + adox rsi, r10 + ; A[4] * B[2] + mulx r10, r9, QWORD PTR [r8+16] + adcx rsi, r9 + adox r11, r10 + ; A[4] * B[3] + mulx r10, r9, QWORD PTR [r8+24] + adcx r11, r9 + adox r12, r10 + ; A[4] * B[4] + mulx r10, r9, QWORD PTR [r8+32] + adcx r12, r9 + adox r13, r10 + ; A[4] * B[5] + mulx r10, r9, QWORD PTR [r8+40] + adcx r13, r9 + adox r14, r10 + adcx r14, rbx + mov QWORD PTR [rsp+32], r15 + mov rdx, QWORD PTR [rax+40] + ; A[5] * B[0] + mulx r10, r9, QWORD PTR [r8] + adcx rdi, r9 + adox rsi, r10 + ; A[5] * B[1] + mulx r10, r9, QWORD PTR [r8+8] + adcx rsi, r9 + adox r11, r10 + ; A[5] * B[2] + mulx r10, r9, QWORD PTR [r8+16] + adcx r11, r9 + adox r12, r10 + ; A[5] * B[3] + mulx r10, r9, QWORD PTR [r8+24] + adcx r12, r9 + adox r13, r10 + ; A[5] * B[4] + mulx r10, r9, QWORD PTR [r8+32] + adcx r13, r9 + adox r14, r10 + ; A[5] * B[5] + mulx r15, r9, QWORD PTR [r8+40] + adcx r14, r9 + adox r15, rbx + adcx r15, rbx + mov QWORD PTR [rcx+40], rdi + mov QWORD PTR [rcx+48], rsi + mov QWORD PTR [rcx+56], r11 + mov QWORD PTR [rcx+64], r12 + mov QWORD PTR [rcx+72], r13 + mov QWORD PTR [rcx+80], r14 + mov QWORD PTR [rcx+88], r15 + mov r11, QWORD PTR [rsp] + mov r12, QWORD PTR [rsp+8] + mov r13, QWORD PTR [rsp+16] + mov r14, QWORD PTR [rsp+24] + mov r15, QWORD PTR [rsp+32] + mov QWORD PTR [rcx], r11 + mov QWORD PTR [rcx+8], r12 + mov QWORD PTR [rcx+16], r13 + mov QWORD PTR [rcx+24], r14 + mov QWORD PTR [rcx+32], r15 + add rsp, 40 + pop rbx + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_384_mul_avx2_6 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Reduce the number back to 384 bits using Montgomery reduction. +; * +; * a A single precision number to reduce in place. +; * m The single precision number representing the modulus. +; * mp The digit representing the negative inverse of m mod 2^n. +; */ +_text SEGMENT READONLY PARA +sp_384_mont_reduce_order_avx2_6 PROC + push r12 + push r13 + push r14 + push r15 + mov rax, rdx + xor r15, r15 + mov r14, QWORD PTR [rcx] + xor r13, r13 +L_mont_loop_order_avx2_6: + ; mu = a[i] * mp + mov rdx, r14 + mov r11, r14 + imul rdx, r8 + xor r13, r13 + ; a[i+0] += m[0] * mu + mulx r10, r9, QWORD PTR [rax] + mov r14, QWORD PTR [rcx+8] + adcx r11, r9 + adox r14, r10 + ; a[i+1] += m[1] * mu + mulx r10, r9, QWORD PTR [rax+8] + mov r11, QWORD PTR [rcx+16] + adcx r14, r9 + adox r11, r10 + ; a[i+2] += m[2] * mu + mulx r10, r9, QWORD PTR [rax+16] + mov r12, QWORD PTR [rcx+24] + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+16], r11 + ; a[i+3] += m[3] * mu + mulx r10, r9, QWORD PTR [rax+24] + mov r11, QWORD PTR [rcx+32] + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+24], r12 + ; a[i+4] += m[4] * mu + mulx r10, r9, QWORD PTR [rax+32] + mov r12, QWORD PTR [rcx+40] + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+32], r11 + ; a[i+5] += m[5] * mu + mulx r10, r9, QWORD PTR [rax+40] + mov r11, QWORD PTR [rcx+48] + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+40], r12 + adcx r11, r15 + mov QWORD PTR [rcx+48], r11 + mov r15, r13 + adox r15, r13 + adcx r15, r13 + ; mu = a[i] * mp + mov rdx, r14 + mov r11, r14 + imul rdx, r8 + xor r13, r13 + ; a[i+0] += m[0] * mu + mulx r10, r9, QWORD PTR [rax] + mov r14, QWORD PTR [rcx+16] + adcx r11, r9 + adox r14, r10 + ; a[i+1] += m[1] * mu + mulx r10, r9, QWORD PTR [rax+8] + mov r11, QWORD PTR [rcx+24] + adcx r14, r9 + adox r11, r10 + ; a[i+2] += m[2] * mu + mulx r10, r9, QWORD PTR [rax+16] + mov r12, QWORD PTR [rcx+32] + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+24], r11 + ; a[i+3] += m[3] * mu + mulx r10, r9, QWORD PTR [rax+24] + mov r11, QWORD PTR [rcx+40] + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+32], r12 + ; a[i+4] += m[4] * mu + mulx r10, r9, QWORD PTR [rax+32] + mov r12, QWORD PTR [rcx+48] + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+40], r11 + ; a[i+5] += m[5] * mu + mulx r10, r9, QWORD PTR [rax+40] + mov r11, QWORD PTR [rcx+56] + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+48], r12 + adcx r11, r15 + mov QWORD PTR [rcx+56], r11 + mov r15, r13 + adox r15, r13 + adcx r15, r13 + ; mu = a[i] * mp + mov rdx, r14 + mov r11, r14 + imul rdx, r8 + xor r13, r13 + ; a[i+0] += m[0] * mu + mulx r10, r9, QWORD PTR [rax] + mov r14, QWORD PTR [rcx+24] + adcx r11, r9 + adox r14, r10 + ; a[i+1] += m[1] * mu + mulx r10, r9, QWORD PTR [rax+8] + mov r11, QWORD PTR [rcx+32] + adcx r14, r9 + adox r11, r10 + ; a[i+2] += m[2] * mu + mulx r10, r9, QWORD PTR [rax+16] + mov r12, QWORD PTR [rcx+40] + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+32], r11 + ; a[i+3] += m[3] * mu + mulx r10, r9, QWORD PTR [rax+24] + mov r11, QWORD PTR [rcx+48] + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+40], r12 + ; a[i+4] += m[4] * mu + mulx r10, r9, QWORD PTR [rax+32] + mov r12, QWORD PTR [rcx+56] + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+48], r11 + ; a[i+5] += m[5] * mu + mulx r10, r9, QWORD PTR [rax+40] + mov r11, QWORD PTR [rcx+64] + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+56], r12 + adcx r11, r15 + mov QWORD PTR [rcx+64], r11 + mov r15, r13 + adox r15, r13 + adcx r15, r13 + ; mu = a[i] * mp + mov rdx, r14 + mov r11, r14 + imul rdx, r8 + xor r13, r13 + ; a[i+0] += m[0] * mu + mulx r10, r9, QWORD PTR [rax] + mov r14, QWORD PTR [rcx+32] + adcx r11, r9 + adox r14, r10 + ; a[i+1] += m[1] * mu + mulx r10, r9, QWORD PTR [rax+8] + mov r11, QWORD PTR [rcx+40] + adcx r14, r9 + adox r11, r10 + ; a[i+2] += m[2] * mu + mulx r10, r9, QWORD PTR [rax+16] + mov r12, QWORD PTR [rcx+48] + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+40], r11 + ; a[i+3] += m[3] * mu + mulx r10, r9, QWORD PTR [rax+24] + mov r11, QWORD PTR [rcx+56] + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+48], r12 + ; a[i+4] += m[4] * mu + mulx r10, r9, QWORD PTR [rax+32] + mov r12, QWORD PTR [rcx+64] + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+56], r11 + ; a[i+5] += m[5] * mu + mulx r10, r9, QWORD PTR [rax+40] + mov r11, QWORD PTR [rcx+72] + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+64], r12 + adcx r11, r15 + mov QWORD PTR [rcx+72], r11 + mov r15, r13 + adox r15, r13 + adcx r15, r13 + ; mu = a[i] * mp + mov rdx, r14 + mov r11, r14 + imul rdx, r8 + xor r13, r13 + ; a[i+0] += m[0] * mu + mulx r10, r9, QWORD PTR [rax] + mov r14, QWORD PTR [rcx+40] + adcx r11, r9 + adox r14, r10 + ; a[i+1] += m[1] * mu + mulx r10, r9, QWORD PTR [rax+8] + mov r11, QWORD PTR [rcx+48] + adcx r14, r9 + adox r11, r10 + ; a[i+2] += m[2] * mu + mulx r10, r9, QWORD PTR [rax+16] + mov r12, QWORD PTR [rcx+56] + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+48], r11 + ; a[i+3] += m[3] * mu + mulx r10, r9, QWORD PTR [rax+24] + mov r11, QWORD PTR [rcx+64] + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+56], r12 + ; a[i+4] += m[4] * mu + mulx r10, r9, QWORD PTR [rax+32] + mov r12, QWORD PTR [rcx+72] + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+64], r11 + ; a[i+5] += m[5] * mu + mulx r10, r9, QWORD PTR [rax+40] + mov r11, QWORD PTR [rcx+80] + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+72], r12 + adcx r11, r15 + mov QWORD PTR [rcx+80], r11 + mov r15, r13 + adox r15, r13 + adcx r15, r13 + ; mu = a[i] * mp + mov rdx, r14 + mov r11, r14 + imul rdx, r8 + xor r13, r13 + ; a[i+0] += m[0] * mu + mulx r10, r9, QWORD PTR [rax] + mov r14, QWORD PTR [rcx+48] + adcx r11, r9 + adox r14, r10 + ; a[i+1] += m[1] * mu + mulx r10, r9, QWORD PTR [rax+8] + mov r11, QWORD PTR [rcx+56] + adcx r14, r9 + adox r11, r10 + ; a[i+2] += m[2] * mu + mulx r10, r9, QWORD PTR [rax+16] + mov r12, QWORD PTR [rcx+64] + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+56], r11 + ; a[i+3] += m[3] * mu + mulx r10, r9, QWORD PTR [rax+24] + mov r11, QWORD PTR [rcx+72] + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+64], r12 + ; a[i+4] += m[4] * mu + mulx r10, r9, QWORD PTR [rax+32] + mov r12, QWORD PTR [rcx+80] + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+72], r11 + ; a[i+5] += m[5] * mu + mulx r10, r9, QWORD PTR [rax+40] + mov r11, QWORD PTR [rcx+88] + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+80], r12 + adcx r11, r15 + mov QWORD PTR [rcx+88], r11 + mov r15, r13 + adox r15, r13 + adcx r15, r13 + neg r15 + mov r8, rcx + add rcx, 48 + mov r10, QWORD PTR [rax] + mov rdx, r14 + pext r10, r10, r15 + sub rdx, r10 + mov r10, QWORD PTR [rax+8] + mov r9, QWORD PTR [rcx+8] + pext r10, r10, r15 + mov QWORD PTR [r8], rdx + sbb r9, r10 + mov rdx, QWORD PTR [rax+16] + mov r10, QWORD PTR [rcx+16] + pext rdx, rdx, r15 + mov QWORD PTR [r8+8], r9 + sbb r10, rdx + mov r9, QWORD PTR [rax+24] + mov rdx, QWORD PTR [rcx+24] + pext r9, r9, r15 + mov QWORD PTR [r8+16], r10 + sbb rdx, r9 + mov r10, QWORD PTR [rax+32] + mov r9, QWORD PTR [rcx+32] + pext r10, r10, r15 + mov QWORD PTR [r8+24], rdx + sbb r9, r10 + mov rdx, QWORD PTR [rax+40] + mov r10, QWORD PTR [rcx+40] + pext rdx, rdx, r15 + mov QWORD PTR [r8+32], r9 + sbb r10, rdx + mov QWORD PTR [r8+40], r10 + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_384_mont_reduce_order_avx2_6 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Square a and put result in r. (r = a * a) +; * +; * r Result of squaring. +; * a Number to square in Montogmery form. +; */ +_text SEGMENT READONLY PARA +sp_384_sqr_avx2_6 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + push rbx + push rbp + mov rax, rdx + push rcx + xor rcx, rcx + mov rdx, QWORD PTR [rax] + mov rsi, QWORD PTR [rax+8] + mov rbx, QWORD PTR [rax+16] + mov rbp, QWORD PTR [rax+24] + ; Diagonal 0 + ; A[1] * A[0] + mulx r11, r10, QWORD PTR [rax+8] + ; A[2] * A[0] + mulx r12, r8, QWORD PTR [rax+16] + adcx r11, r8 + ; A[3] * A[0] + mulx r13, r8, QWORD PTR [rax+24] + adcx r12, r8 + ; A[4] * A[0] + mulx r14, r8, QWORD PTR [rax+32] + adcx r13, r8 + ; A[5] * A[0] + mulx r15, r8, QWORD PTR [rax+40] + adcx r14, r8 + adcx r15, rcx + ; Diagonal 1 + mov rdx, rsi + ; A[2] * A[1] + mulx r9, r8, QWORD PTR [rax+16] + adcx r12, r8 + adox r13, r9 + ; A[3] * A[1] + mulx r9, r8, QWORD PTR [rax+24] + adcx r13, r8 + adox r14, r9 + ; A[4] * A[1] + mulx r9, r8, QWORD PTR [rax+32] + adcx r14, r8 + adox r15, r9 + ; A[5] * A[1] + mulx rdi, r8, QWORD PTR [rax+40] + adcx r15, r8 + adox rdi, rcx + mov rdx, rbx + ; A[5] * A[2] + mulx rsi, r8, QWORD PTR [rax+40] + adcx rdi, r8 + adox rsi, rcx + adcx rsi, rcx + adcx rbx, rcx + ; Diagonal 2 + ; A[3] * A[2] + mulx r9, r8, QWORD PTR [rax+24] + adcx r14, r8 + adox r15, r9 + ; A[4] * A[2] + mulx r9, r8, QWORD PTR [rax+32] + adcx r15, r8 + adox rdi, r9 + mov rdx, rbp + ; A[4] * A[3] + mulx r9, r8, QWORD PTR [rax+32] + adcx rdi, r8 + adox rsi, r9 + ; A[5] * A[3] + mulx rbx, r8, QWORD PTR [rax+40] + adcx rsi, r8 + adox rbx, rcx + mov rdx, QWORD PTR [rax+32] + ; A[5] * A[4] + mulx rbp, r8, QWORD PTR [rax+40] + adcx rbx, r8 + adox rbp, rcx + adcx rbp, rcx + adcx rcx, rcx + ; Doubling previous result as we add in square words results + ; A[0] * A[0] + mov rdx, QWORD PTR [rax] + mulx r9, r8, rdx + pop rdx + mov QWORD PTR [rdx], r8 + adox r10, r10 + push rdx + adcx r10, r9 + ; A[1] * A[1] + mov rdx, QWORD PTR [rax+8] + mulx r9, r8, rdx + adox r11, r11 + adcx r11, r8 + adox r12, r12 + adcx r12, r9 + ; A[2] * A[2] + mov rdx, QWORD PTR [rax+16] + mulx r9, r8, rdx + adox r13, r13 + adcx r13, r8 + adox r14, r14 + adcx r14, r9 + ; A[3] * A[3] + mov rdx, QWORD PTR [rax+24] + mulx r9, r8, rdx + adox r15, r15 + adcx r15, r8 + adox rdi, rdi + adcx rdi, r9 + ; A[4] * A[4] + mov rdx, QWORD PTR [rax+32] + mulx r9, r8, rdx + adox rsi, rsi + adcx rsi, r8 + adox rbx, rbx + adcx rbx, r9 + ; A[5] * A[5] + mov rdx, QWORD PTR [rax+40] + mulx r9, r8, rdx + adox rbp, rbp + adcx rbp, r8 + adcx r9, rcx + mov r8, 0 + adox r9, r8 + pop rcx + mov QWORD PTR [rcx+8], r10 + mov QWORD PTR [rcx+16], r11 + mov QWORD PTR [rcx+24], r12 + mov QWORD PTR [rcx+32], r13 + mov QWORD PTR [rcx+40], r14 + mov QWORD PTR [rcx+48], r15 + mov QWORD PTR [rcx+56], rdi + mov QWORD PTR [rcx+64], rsi + mov QWORD PTR [rcx+72], rbx + mov QWORD PTR [rcx+80], rbp + mov QWORD PTR [rcx+88], r9 + pop rbp + pop rbx + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_384_sqr_avx2_6 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Conditionally subtract b from a using the mask m. +; * m is -1 to subtract and 0 when not copying. +; * +; * r A single precision number representing condition subtract result. +; * a A single precision number to subtract from. +; * b A single precision number to subtract. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_384_cond_sub_avx2_6 PROC + push r12 + mov rax, 0 + mov r12, QWORD PTR [r8] + mov r10, QWORD PTR [rdx] + pext r12, r12, r9 + sub r10, r12 + mov r12, QWORD PTR [r8+8] + mov r11, QWORD PTR [rdx+8] + pext r12, r12, r9 + mov QWORD PTR [rcx], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+16] + mov r12, QWORD PTR [rdx+16] + pext r10, r10, r9 + mov QWORD PTR [rcx+8], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+24] + mov r10, QWORD PTR [rdx+24] + pext r11, r11, r9 + mov QWORD PTR [rcx+16], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+32] + mov r11, QWORD PTR [rdx+32] + pext r12, r12, r9 + mov QWORD PTR [rcx+24], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+40] + mov r12, QWORD PTR [rdx+40] + pext r10, r10, r9 + mov QWORD PTR [rcx+32], r11 + sbb r12, r10 + mov QWORD PTR [rcx+40], r12 + sbb rax, 0 + pop r12 + ret +sp_384_cond_sub_avx2_6 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m) +; * +; * r Result of division by 2. +; * a Number to divide. +; * m Modulus (prime). +; */ +_text SEGMENT READONLY PARA +sp_384_div2_avx2_6 PROC + push r12 + push r13 + mov r13, QWORD PTR [rdx] + xor r12, r12 + mov r10, r13 + and r13, 1 + neg r13 + mov rax, QWORD PTR [r8] + mov r9, QWORD PTR [r8+8] + mov r10, QWORD PTR [rdx] + mov r11, QWORD PTR [rdx+8] + pext rax, rax, r13 + pext r9, r9, r13 + add r10, rax + adc r11, r9 + mov QWORD PTR [rcx], r10 + mov QWORD PTR [rcx+8], r11 + mov rax, QWORD PTR [r8+16] + mov r9, QWORD PTR [r8+24] + mov r10, QWORD PTR [rdx+16] + mov r11, QWORD PTR [rdx+24] + pext rax, rax, r13 + pext r9, r9, r13 + adc r10, rax + adc r11, r9 + mov QWORD PTR [rcx+16], r10 + mov QWORD PTR [rcx+24], r11 + mov rax, QWORD PTR [r8+32] + mov r9, QWORD PTR [r8+40] + mov r10, QWORD PTR [rdx+32] + mov r11, QWORD PTR [rdx+40] + pext rax, rax, r13 + pext r9, r9, r13 + adc r10, rax + adc r11, r9 + mov QWORD PTR [rcx+32], r10 + mov QWORD PTR [rcx+40], r11 + adc r12, 0 + mov r10, QWORD PTR [rcx] + mov r11, QWORD PTR [rcx+8] + shrd r10, r11, 1 + mov QWORD PTR [rcx], r10 + mov r10, QWORD PTR [rcx+16] + shrd r11, r10, 1 + mov QWORD PTR [rcx+8], r11 + mov r11, QWORD PTR [rcx+24] + shrd r10, r11, 1 + mov QWORD PTR [rcx+16], r10 + mov r10, QWORD PTR [rcx+32] + shrd r11, r10, 1 + mov QWORD PTR [rcx+24], r11 + mov r11, QWORD PTR [rcx+40] + shrd r10, r11, 1 + mov QWORD PTR [rcx+32], r10 + shrd r11, r12, 1 + mov QWORD PTR [rcx+40], r11 + pop r13 + pop r12 + ret +sp_384_div2_avx2_6 ENDP +_text ENDS +ENDIF +IFNDEF WC_NO_CACHE_RESISTANT +; /* Touch each possible entry that could be being copied. +; * +; * r Point to copy into. +; * table Table - start of the entires to access +; * idx Index of entry to retrieve. +; */ +_text SEGMENT READONLY PARA +sp_384_get_entry_64_6 PROC + mov rax, 1 + movd xmm13, r8d + add rdx, 96 + movd xmm15, eax + mov rax, 63 + pshufd xmm15, xmm15, 0 + pshufd xmm13, xmm13, 0 + pxor xmm14, xmm14 + pxor xmm0, xmm0 + pxor xmm1, xmm1 + pxor xmm2, xmm2 + pxor xmm3, xmm3 + pxor xmm4, xmm4 + pxor xmm5, xmm5 + movdqa xmm14, xmm15 +L_384_get_entry_64_6_start: + movdqa xmm12, xmm14 + paddd xmm14, xmm15 + pcmpeqd xmm12, xmm13 + movdqu xmm6, [rdx] + movdqu xmm7, [rdx+16] + movdqu xmm8, [rdx+32] + movdqu xmm9, [rdx+48] + movdqu xmm10, [rdx+64] + movdqu xmm11, [rdx+80] + add rdx, 96 + pand xmm6, xmm12 + pand xmm7, xmm12 + pand xmm8, xmm12 + pand xmm9, xmm12 + pand xmm10, xmm12 + pand xmm11, xmm12 + por xmm0, xmm6 + por xmm1, xmm7 + por xmm2, xmm8 + por xmm3, xmm9 + por xmm4, xmm10 + por xmm5, xmm11 + dec rax + jnz L_384_get_entry_64_6_start + movdqu [rcx], xmm0 + movdqu [rcx+16], xmm1 + movdqu [rcx+32], xmm2 + movdqu [rcx+96], xmm3 + movdqu [rcx+112], xmm4 + movdqu [rcx+128], xmm5 + ret +sp_384_get_entry_64_6 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Touch each possible entry that could be being copied. +; * +; * r Point to copy into. +; * table Table - start of the entires to access +; * idx Index of entry to retrieve. +; */ +_text SEGMENT READONLY PARA +sp_384_get_entry_64_avx2_6 PROC + mov rax, 1 + movd xmm9, r8d + add rdx, 96 + movd xmm11, eax + mov rax, 64 + vpxor ymm10, ymm10, ymm10 + vpermd ymm9, ymm10, ymm9 + vpermd ymm11, ymm10, ymm11 + vpxor ymm0, ymm0, ymm0 + vpxor xmm1, xmm1, xmm1 + vpxor ymm2, ymm2, ymm2 + vpxor xmm3, xmm3, xmm3 + vmovdqa ymm10, ymm11 +L_384_get_entry_64_avx2_6_start: + vpcmpeqd ymm8, ymm10, ymm9 + vpaddd ymm10, ymm10, ymm11 + vmovupd ymm4, [rdx] + vmovdqu xmm5, OWORD PTR [rdx+32] + vmovupd ymm6, [rdx+48] + vmovdqu xmm7, OWORD PTR [rdx+80] + add rdx, 96 + vpand ymm4, ymm4, ymm8 + vpand xmm5, xmm5, xmm8 + vpand ymm6, ymm6, ymm8 + vpand xmm7, xmm7, xmm8 + vpor ymm0, ymm0, ymm4 + vpor xmm1, xmm1, xmm5 + vpor ymm2, ymm2, ymm6 + vpor xmm3, xmm3, xmm7 + dec rax + jnz L_384_get_entry_64_avx2_6_start + vmovupd YMMWORD PTR [rcx], ymm0 + vmovdqu [rcx+32], xmm1 + vmovupd YMMWORD PTR [rcx+96], ymm2 + vmovdqu [rcx+128], xmm3 + ret +sp_384_get_entry_64_avx2_6 ENDP +_text ENDS +ENDIF +ENDIF +IFNDEF WC_NO_CACHE_RESISTANT +; /* Touch each possible entry that could be being copied. +; * +; * r Point to copy into. +; * table Table - start of the entires to access +; * idx Index of entry to retrieve. +; */ +_text SEGMENT READONLY PARA +sp_384_get_entry_65_6 PROC + mov rax, 1 + movd xmm13, r8d + add rdx, 96 + movd xmm15, eax + mov rax, 64 + pshufd xmm15, xmm15, 0 + pshufd xmm13, xmm13, 0 + pxor xmm14, xmm14 + pxor xmm0, xmm0 + pxor xmm1, xmm1 + pxor xmm2, xmm2 + pxor xmm3, xmm3 + pxor xmm4, xmm4 + pxor xmm5, xmm5 + movdqa xmm14, xmm15 +L_384_get_entry_65_6_start: + movdqa xmm12, xmm14 + paddd xmm14, xmm15 + pcmpeqd xmm12, xmm13 + movdqu xmm6, [rdx] + movdqu xmm7, [rdx+16] + movdqu xmm8, [rdx+32] + movdqu xmm9, [rdx+48] + movdqu xmm10, [rdx+64] + movdqu xmm11, [rdx+80] + add rdx, 96 + pand xmm6, xmm12 + pand xmm7, xmm12 + pand xmm8, xmm12 + pand xmm9, xmm12 + pand xmm10, xmm12 + pand xmm11, xmm12 + por xmm0, xmm6 + por xmm1, xmm7 + por xmm2, xmm8 + por xmm3, xmm9 + por xmm4, xmm10 + por xmm5, xmm11 + dec rax + jnz L_384_get_entry_65_6_start + movdqu [rcx], xmm0 + movdqu [rcx+16], xmm1 + movdqu [rcx+32], xmm2 + movdqu [rcx+96], xmm3 + movdqu [rcx+112], xmm4 + movdqu [rcx+128], xmm5 + ret +sp_384_get_entry_65_6 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Touch each possible entry that could be being copied. +; * +; * r Point to copy into. +; * table Table - start of the entires to access +; * idx Index of entry to retrieve. +; */ +_text SEGMENT READONLY PARA +sp_384_get_entry_65_avx2_6 PROC + mov rax, 1 + movd xmm9, r8d + add rdx, 96 + movd xmm11, eax + mov rax, 65 + vpxor ymm10, ymm10, ymm10 + vpermd ymm9, ymm10, ymm9 + vpermd ymm11, ymm10, ymm11 + vpxor ymm0, ymm0, ymm0 + vpxor xmm1, xmm1, xmm1 + vpxor ymm2, ymm2, ymm2 + vpxor xmm3, xmm3, xmm3 + vmovdqa ymm10, ymm11 +L_384_get_entry_65_avx2_6_start: + vpcmpeqd ymm8, ymm10, ymm9 + vpaddd ymm10, ymm10, ymm11 + vmovupd ymm4, [rdx] + vmovdqu xmm5, OWORD PTR [rdx+32] + vmovupd ymm6, [rdx+48] + vmovdqu xmm7, OWORD PTR [rdx+80] + add rdx, 96 + vpand ymm4, ymm4, ymm8 + vpand xmm5, xmm5, xmm8 + vpand ymm6, ymm6, ymm8 + vpand xmm7, xmm7, xmm8 + vpor ymm0, ymm0, ymm4 + vpor xmm1, xmm1, xmm5 + vpor ymm2, ymm2, ymm6 + vpor xmm3, xmm3, xmm7 + dec rax + jnz L_384_get_entry_65_avx2_6_start + vmovupd YMMWORD PTR [rcx], ymm0 + vmovdqu [rcx+32], xmm1 + vmovupd YMMWORD PTR [rcx+96], ymm2 + vmovdqu [rcx+128], xmm3 + ret +sp_384_get_entry_65_avx2_6 ENDP +_text ENDS +ENDIF +ENDIF +; /* Add 1 to a. (a = a + 1) +; * +; * a A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_384_add_one_6 PROC + add QWORD PTR [rcx], 1 + adc QWORD PTR [rcx+8], 0 + adc QWORD PTR [rcx+16], 0 + adc QWORD PTR [rcx+24], 0 + adc QWORD PTR [rcx+32], 0 + adc QWORD PTR [rcx+40], 0 + ret +sp_384_add_one_6 ENDP +_text ENDS +; /* Read big endian unsigned byte array into r. +; * Uses the bswap instruction. +; * +; * r A single precision integer. +; * size Maximum number of bytes to convert +; * a Byte array. +; * n Number of bytes in array to read. +; */ +_text SEGMENT READONLY PARA +sp_384_from_bin_bswap PROC + push r12 + push r13 + mov r11, r8 + mov r12, rcx + add r11, r9 + add r12, 48 + xor r13, r13 + jmp L_384_from_bin_bswap_64_end +L_384_from_bin_bswap_64_start: + sub r11, 64 + mov rax, QWORD PTR [r11+56] + mov r10, QWORD PTR [r11+48] + bswap rax + bswap r10 + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r10 + mov rax, QWORD PTR [r11+40] + mov r10, QWORD PTR [r11+32] + bswap rax + bswap r10 + mov QWORD PTR [rcx+16], rax + mov QWORD PTR [rcx+24], r10 + mov rax, QWORD PTR [r11+24] + mov r10, QWORD PTR [r11+16] + bswap rax + bswap r10 + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r10 + mov rax, QWORD PTR [r11+8] + mov r10, QWORD PTR [r11] + bswap rax + bswap r10 + mov QWORD PTR [rcx+48], rax + mov QWORD PTR [rcx+56], r10 + add rcx, 64 + sub r9, 64 +L_384_from_bin_bswap_64_end: + cmp r9, 63 + jg L_384_from_bin_bswap_64_start + jmp L_384_from_bin_bswap_8_end +L_384_from_bin_bswap_8_start: + sub r11, 8 + mov rax, QWORD PTR [r11] + bswap rax + mov QWORD PTR [rcx], rax + add rcx, 8 + sub r9, 8 +L_384_from_bin_bswap_8_end: + cmp r9, 7 + jg L_384_from_bin_bswap_8_start + cmp r9, r13 + je L_384_from_bin_bswap_hi_end + mov r10, r13 + mov rax, r13 +L_384_from_bin_bswap_hi_start: + mov al, BYTE PTR [r8] + shl r10, 8 + inc r8 + add r10, rax + dec r9 + jg L_384_from_bin_bswap_hi_start + mov QWORD PTR [rcx], r10 + add rcx, 8 +L_384_from_bin_bswap_hi_end: + cmp rcx, r12 + je L_384_from_bin_bswap_zero_end +L_384_from_bin_bswap_zero_start: + mov QWORD PTR [rcx], r13 + add rcx, 8 + cmp rcx, r12 + jl L_384_from_bin_bswap_zero_start +L_384_from_bin_bswap_zero_end: + pop r13 + pop r12 + ret +sp_384_from_bin_bswap ENDP +_text ENDS +IFNDEF NO_MOVBE_SUPPORT +; /* Read big endian unsigned byte array into r. +; * Uses the movbe instruction which is an optional instruction. +; * +; * r A single precision integer. +; * size Maximum number of bytes to convert +; * a Byte array. +; * n Number of bytes in array to read. +; */ +_text SEGMENT READONLY PARA +sp_384_from_bin_movbe PROC + push r12 + push r13 + mov r11, r8 + mov r12, rcx + add r11, r9 + add r12, 48 + xor r13, r13 + jmp L_384_from_bin_movbe_64_end +L_384_from_bin_movbe_64_start: + sub r11, 64 + movbe rax, QWORD PTR [r11+56] + movbe r10, QWORD PTR [r11+48] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r10 + movbe rax, QWORD PTR [r11+40] + movbe r10, QWORD PTR [r11+32] + mov QWORD PTR [rcx+16], rax + mov QWORD PTR [rcx+24], r10 + movbe rax, QWORD PTR [r11+24] + movbe r10, QWORD PTR [r11+16] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r10 + movbe rax, QWORD PTR [r11+8] + movbe r10, QWORD PTR [r11] + mov QWORD PTR [rcx+48], rax + mov QWORD PTR [rcx+56], r10 + add rcx, 64 + sub r9, 64 +L_384_from_bin_movbe_64_end: + cmp r9, 63 + jg L_384_from_bin_movbe_64_start + jmp L_384_from_bin_movbe_8_end +L_384_from_bin_movbe_8_start: + sub r11, 8 + movbe rax, QWORD PTR [r11] + mov QWORD PTR [rcx], rax + add rcx, 8 + sub r9, 8 +L_384_from_bin_movbe_8_end: + cmp r9, 7 + jg L_384_from_bin_movbe_8_start + cmp r9, r13 + je L_384_from_bin_movbe_hi_end + mov r10, r13 + mov rax, r13 +L_384_from_bin_movbe_hi_start: + mov al, BYTE PTR [r8] + shl r10, 8 + inc r8 + add r10, rax + dec r9 + jg L_384_from_bin_movbe_hi_start + mov QWORD PTR [rcx], r10 + add rcx, 8 +L_384_from_bin_movbe_hi_end: + cmp rcx, r12 + je L_384_from_bin_movbe_zero_end +L_384_from_bin_movbe_zero_start: + mov QWORD PTR [rcx], r13 + add rcx, 8 + cmp rcx, r12 + jl L_384_from_bin_movbe_zero_start +L_384_from_bin_movbe_zero_end: + pop r13 + pop r12 + ret +sp_384_from_bin_movbe ENDP +_text ENDS +ENDIF +; /* Write r as big endian to byte array. +; * Fixed length number of bytes written: 48 +; * Uses the bswap instruction. +; * +; * r A single precision integer. +; * a Byte array. +; */ +_text SEGMENT READONLY PARA +sp_384_to_bin_bswap PROC + mov rax, QWORD PTR [rcx+40] + mov r8, QWORD PTR [rcx+32] + bswap rax + bswap r8 + mov QWORD PTR [rdx], rax + mov QWORD PTR [rdx+8], r8 + mov rax, QWORD PTR [rcx+24] + mov r8, QWORD PTR [rcx+16] + bswap rax + bswap r8 + mov QWORD PTR [rdx+16], rax + mov QWORD PTR [rdx+24], r8 + mov rax, QWORD PTR [rcx+8] + mov r8, QWORD PTR [rcx] + bswap rax + bswap r8 + mov QWORD PTR [rdx+32], rax + mov QWORD PTR [rdx+40], r8 + ret +sp_384_to_bin_bswap ENDP +_text ENDS +IFNDEF NO_MOVBE_SUPPORT +; /* Write r as big endian to byte array. +; * Fixed length number of bytes written: 48 +; * Uses the movbe instruction which is optional. +; * +; * r A single precision integer. +; * a Byte array. +; */ +_text SEGMENT READONLY PARA +sp_384_to_bin_movbe PROC + movbe rax, QWORD PTR [rcx+40] + movbe r8, QWORD PTR [rcx+32] + mov QWORD PTR [rdx], rax + mov QWORD PTR [rdx+8], r8 + movbe rax, QWORD PTR [rcx+24] + movbe r8, QWORD PTR [rcx+16] + mov QWORD PTR [rdx+16], rax + mov QWORD PTR [rdx+24], r8 + movbe rax, QWORD PTR [rcx+8] + movbe r8, QWORD PTR [rcx] + mov QWORD PTR [rdx+32], rax + mov QWORD PTR [rdx+40], r8 + ret +sp_384_to_bin_movbe ENDP +_text ENDS +ENDIF +; /* Sub b from a into a. (a -= b) +; * +; * a A single precision integer and result. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_384_sub_in_place_6 PROC + xor rax, rax + mov r8, QWORD PTR [rdx] + mov r9, QWORD PTR [rdx+8] + mov r10, QWORD PTR [rdx+16] + mov r11, QWORD PTR [rdx+24] + mov r12, QWORD PTR [rdx+32] + mov r13, QWORD PTR [rdx+40] + sub QWORD PTR [rcx], r8 + sbb QWORD PTR [rcx+8], r9 + sbb QWORD PTR [rcx+16], r10 + sbb QWORD PTR [rcx+24], r11 + sbb QWORD PTR [rcx+32], r12 + sbb QWORD PTR [rcx+40], r13 + sbb rax, 0 + pop r13 + pop r12 + ret +sp_384_sub_in_place_6 ENDP +_text ENDS +; /* Mul a by digit b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision digit. +; */ +_text SEGMENT READONLY PARA +sp_384_mul_d_6 PROC + push r12 + mov r9, rdx + ; A[0] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9] + mov r10, rax + mov r11, rdx + mov QWORD PTR [rcx], r10 + ; A[1] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+8] + add r11, rax + mov QWORD PTR [rcx+8], r11 + adc r12, rdx + adc r10, 0 + ; A[2] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+16] + add r12, rax + mov QWORD PTR [rcx+16], r12 + adc r10, rdx + adc r11, 0 + ; A[3] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+24] + add r10, rax + mov QWORD PTR [rcx+24], r10 + adc r11, rdx + adc r12, 0 + ; A[4] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+32] + add r11, rax + mov QWORD PTR [rcx+32], r11 + adc r12, rdx + adc r10, 0 + ; A[5] * B + mov rax, r8 + mul QWORD PTR [r9+40] + add r12, rax + adc r10, rdx + mov QWORD PTR [rcx+40], r12 + mov QWORD PTR [rcx+48], r10 + pop r12 + ret +sp_384_mul_d_6 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Mul a by digit b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision digit. +; */ +_text SEGMENT READONLY PARA +sp_384_mul_d_avx2_6 PROC + push r12 + push r13 + mov rax, rdx + ; A[0] * B + mov rdx, r8 + xor r13, r13 + mulx r12, r11, QWORD PTR [rax] + mov QWORD PTR [rcx], r11 + ; A[1] * B + mulx r10, r9, QWORD PTR [rax+8] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+8], r12 + ; A[2] * B + mulx r10, r9, QWORD PTR [rax+16] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+16], r11 + ; A[3] * B + mulx r10, r9, QWORD PTR [rax+24] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+24], r12 + ; A[4] * B + mulx r10, r9, QWORD PTR [rax+32] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+32], r11 + ; A[5] * B + mulx r10, r9, QWORD PTR [rax+40] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + adcx r11, r13 + mov QWORD PTR [rcx+40], r12 + mov QWORD PTR [rcx+48], r11 + pop r13 + pop r12 + ret +sp_384_mul_d_avx2_6 ENDP +_text ENDS +ENDIF +IFDEF _WIN64 +; /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) +; * +; * d1 The high order half of the number to divide. +; * d0 The low order half of the number to divide. +; * div The dividend. +; * returns the result of the division. +; */ +_text SEGMENT READONLY PARA +div_384_word_asm_6 PROC + mov r9, rdx + mov rax, r9 + mov rdx, rcx + div r8 + ret +div_384_word_asm_6 ENDP +_text ENDS +ENDIF +; /* Shift number right by 1 bit. (r = a >> 1) +; * +; * r Result of right shift by 1. +; * a Number to shift. +; */ +_text SEGMENT READONLY PARA +sp_384_rshift1_6 PROC + push r12 + mov rax, QWORD PTR [rdx] + mov r8, QWORD PTR [rdx+8] + mov r9, QWORD PTR [rdx+16] + mov r10, QWORD PTR [rdx+24] + mov r11, QWORD PTR [rdx+32] + mov r12, QWORD PTR [rdx+40] + shrd rax, r8, 1 + shrd r8, r9, 1 + shrd r9, r10, 1 + shrd r10, r11, 1 + shrd r11, r12, 1 + shr r12, 1 + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r8 + mov QWORD PTR [rcx+16], r9 + mov QWORD PTR [rcx+24], r10 + mov QWORD PTR [rcx+32], r11 + mov QWORD PTR [rcx+40], r12 + pop r12 + ret +sp_384_rshift1_6 ENDP +_text ENDS +; /* Divide the number by 2 mod the prime. (r = a / 2 % m) +; * +; * r Result of division by 2. +; * a Number to divide. +; * m Modulus +; */ +_text SEGMENT READONLY PARA +sp_384_div2_mod_6 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + push rbx + push rbp + mov rax, QWORD PTR [rdx] + mov r9, QWORD PTR [rdx+8] + mov r10, QWORD PTR [rdx+16] + mov r11, QWORD PTR [rdx+24] + mov r12, QWORD PTR [rdx+32] + mov r13, QWORD PTR [rdx+40] + mov r14, QWORD PTR [r8] + mov r15, QWORD PTR [r8+8] + mov rdi, QWORD PTR [r8+16] + mov rsi, QWORD PTR [r8+24] + mov rbx, QWORD PTR [r8+32] + mov rbp, QWORD PTR [r8+40] + mov r8, rax + and r8, 1 + je L_384_mod_inv_6_div2_mod_no_add + add rax, r14 + adc r9, r15 + adc r10, rdi + adc r11, rsi + adc r12, rbx + adc r13, rbp + mov r8, 0 + adc r8, 0 +L_384_mod_inv_6_div2_mod_no_add: + shrd rax, r9, 1 + shrd r9, r10, 1 + shrd r10, r11, 1 + shrd r11, r12, 1 + shrd r12, r13, 1 + shrd r13, r8, 1 + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r9 + mov QWORD PTR [rcx+16], r10 + mov QWORD PTR [rcx+24], r11 + mov QWORD PTR [rcx+32], r12 + mov QWORD PTR [rcx+40], r13 + pop rbp + pop rbx + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_384_div2_mod_6 ENDP +_text ENDS +_text SEGMENT READONLY PARA +sp_384_num_bits_6 PROC + xor rax, rax + mov rdx, QWORD PTR [rcx+40] + cmp rdx, 0 + je L_384_num_bits_6_end_320 + mov rax, -1 + bsr rax, rdx + add rax, 321 + jmp L_384_num_bits_6_done +L_384_num_bits_6_end_320: + mov rdx, QWORD PTR [rcx+32] + cmp rdx, 0 + je L_384_num_bits_6_end_256 + mov rax, -1 + bsr rax, rdx + add rax, 257 + jmp L_384_num_bits_6_done +L_384_num_bits_6_end_256: + mov rdx, QWORD PTR [rcx+24] + cmp rdx, 0 + je L_384_num_bits_6_end_192 + mov rax, -1 + bsr rax, rdx + add rax, 193 + jmp L_384_num_bits_6_done +L_384_num_bits_6_end_192: + mov rdx, QWORD PTR [rcx+16] + cmp rdx, 0 + je L_384_num_bits_6_end_128 + mov rax, -1 + bsr rax, rdx + add rax, 129 + jmp L_384_num_bits_6_done +L_384_num_bits_6_end_128: + mov rdx, QWORD PTR [rcx+8] + cmp rdx, 0 + je L_384_num_bits_6_end_64 + mov rax, -1 + bsr rax, rdx + add rax, 65 + jmp L_384_num_bits_6_done +L_384_num_bits_6_end_64: + mov rdx, QWORD PTR [rcx] + cmp rdx, 0 + je L_384_num_bits_6_end_0 + mov rax, -1 + bsr rax, rdx + add rax, 1 + jmp L_384_num_bits_6_done +L_384_num_bits_6_end_0: +L_384_num_bits_6_done: + ret +sp_384_num_bits_6 ENDP +_text ENDS +ENDIF +IFDEF WOLFSSL_SP_1024 +; /* Multiply a and b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_1024_mul_16 PROC + push r12 + mov r9, rdx + sub rsp, 128 + ; A[0] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9] + xor r12, r12 + mov QWORD PTR [rsp], rax + mov r11, rdx + ; A[0] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[1] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+8] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rsp+8], r11 + ; A[0] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[1] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+8] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[2] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+16] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rsp+16], r12 + ; A[0] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[1] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+8] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[2] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+16] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[3] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+24] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rsp+24], r10 + ; A[0] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[1] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+8] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[2] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+16] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[3] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+24] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[4] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+32] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rsp+32], r11 + ; A[0] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[1] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+8] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[2] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+16] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[3] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+24] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[4] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+32] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[5] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+40] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rsp+40], r12 + ; A[0] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[1] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+8] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[2] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+16] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[3] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+24] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[4] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+32] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[5] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+40] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[6] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+48] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rsp+48], r10 + ; A[0] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[1] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+8] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[2] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+16] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[3] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+24] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[4] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+32] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[5] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+40] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[6] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+48] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[7] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+56] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rsp+56], r11 + ; A[0] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[1] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+8] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[2] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+16] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[3] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+24] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[4] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+32] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[5] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+40] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[6] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+48] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[7] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+56] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[8] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+64] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rsp+64], r12 + ; A[0] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[1] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+8] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[2] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+16] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[3] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+24] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[4] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+32] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[5] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+40] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[6] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+48] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[7] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+56] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[8] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+64] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[9] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+72] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rsp+72], r10 + ; A[0] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[1] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+8] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[2] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+16] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[3] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+24] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[4] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+32] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[5] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+40] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[6] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+48] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[7] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+56] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[8] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+64] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[9] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+72] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[10] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+80] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rsp+80], r11 + ; A[0] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[1] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+8] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[2] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+16] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[3] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+24] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[4] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+32] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[5] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+40] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[6] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+48] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[7] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+56] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[8] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+64] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[9] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+72] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[10] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+80] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[11] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+88] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rsp+88], r12 + ; A[0] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[1] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+8] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[2] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+16] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[3] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+24] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[4] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+32] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[5] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+40] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[6] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+48] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[7] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+56] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[8] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+64] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[9] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+72] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[10] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+80] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[11] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+88] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[12] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+96] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rsp+96], r10 + ; A[0] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[1] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+8] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[2] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+16] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[3] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+24] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[4] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+32] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[5] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+40] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[6] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+48] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[7] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+56] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[8] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+64] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[9] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+72] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[10] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+80] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[11] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+88] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[12] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+96] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[13] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+104] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rsp+104], r11 + ; A[0] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[1] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+8] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[2] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+16] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[3] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+24] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[4] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+32] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[5] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+40] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[6] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+48] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[7] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+56] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[8] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+64] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[9] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+72] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[10] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+80] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[11] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+88] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[12] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+96] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[13] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+104] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[14] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+112] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rsp+112], r12 + ; A[0] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[1] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+8] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[2] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+16] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[3] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+24] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[4] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+32] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[5] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+40] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[6] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+48] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[7] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+56] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[8] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+64] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[9] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+72] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[10] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+80] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[11] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+88] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[12] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+96] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[13] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+104] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[14] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+112] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[15] * B[0] + mov rax, QWORD PTR [r8] + mul QWORD PTR [r9+120] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rsp+120], r10 + ; A[1] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+8] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[2] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+16] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[3] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+24] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[4] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+32] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[5] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+40] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[6] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+48] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[7] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+56] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[8] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+64] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[9] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+72] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[10] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+80] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[11] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+88] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[12] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+96] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[13] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+104] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[14] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+112] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[15] * B[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r9+120] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rcx+128], r11 + ; A[2] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+16] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[3] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+24] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[4] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+32] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[5] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+40] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[6] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+48] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[7] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+56] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[8] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+64] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[9] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+72] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[10] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+80] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[11] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+88] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[12] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+96] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[13] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+104] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[14] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+112] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[15] * B[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r9+120] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rcx+136], r12 + ; A[3] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+24] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[4] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+32] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[5] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+40] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[6] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+48] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[7] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+56] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[8] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+64] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[9] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+72] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[10] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+80] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[11] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+88] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[12] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+96] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[13] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+104] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[14] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+112] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[15] * B[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r9+120] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rcx+144], r10 + ; A[4] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+32] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[5] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+40] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[6] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+48] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[7] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+56] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[8] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+64] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[9] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+72] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[10] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+80] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[11] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+88] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[12] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+96] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[13] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+104] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[14] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+112] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[15] * B[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r9+120] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rcx+152], r11 + ; A[5] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+40] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[6] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+48] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[7] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+56] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[8] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+64] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[9] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+72] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[10] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+80] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[11] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+88] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[12] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+96] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[13] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+104] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[14] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+112] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[15] * B[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r9+120] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rcx+160], r12 + ; A[6] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+48] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[7] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+56] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[8] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+64] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[9] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+72] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[10] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+80] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[11] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+88] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[12] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+96] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[13] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+104] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[14] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+112] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[15] * B[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r9+120] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rcx+168], r10 + ; A[7] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+56] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[8] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+64] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[9] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+72] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[10] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+80] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[11] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+88] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[12] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+96] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[13] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+104] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[14] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+112] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[15] * B[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r9+120] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rcx+176], r11 + ; A[8] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+64] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[9] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+72] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[10] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+80] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[11] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+88] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[12] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+96] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[13] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+104] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[14] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+112] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[15] * B[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r9+120] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rcx+184], r12 + ; A[9] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+72] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[10] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+80] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[11] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+88] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[12] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+96] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[13] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+104] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[14] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+112] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[15] * B[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r9+120] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rcx+192], r10 + ; A[10] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+80] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[11] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+88] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[12] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+96] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[13] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+104] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[14] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+112] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[15] * B[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r9+120] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rcx+200], r11 + ; A[11] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+88] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[12] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+96] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[13] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+104] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[14] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+112] + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[15] * B[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r9+120] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rcx+208], r12 + ; A[12] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+96] + xor r12, r12 + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[13] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+104] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[14] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+112] + add r10, rax + adc r11, rdx + adc r12, 0 + ; A[15] * B[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r9+120] + add r10, rax + adc r11, rdx + adc r12, 0 + mov QWORD PTR [rcx+216], r10 + ; A[13] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+104] + xor r10, r10 + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[14] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+112] + add r11, rax + adc r12, rdx + adc r10, 0 + ; A[15] * B[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r9+120] + add r11, rax + adc r12, rdx + adc r10, 0 + mov QWORD PTR [rcx+224], r11 + ; A[14] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+112] + xor r11, r11 + add r12, rax + adc r10, rdx + adc r11, 0 + ; A[15] * B[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r9+120] + add r12, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rcx+232], r12 + ; A[15] * B[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r9+120] + add r10, rax + adc r11, rdx + mov QWORD PTR [rcx+240], r10 + mov QWORD PTR [rcx+248], r11 + mov rax, QWORD PTR [rsp] + mov rdx, QWORD PTR [rsp+8] + mov r10, QWORD PTR [rsp+16] + mov r11, QWORD PTR [rsp+24] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], rdx + mov QWORD PTR [rcx+16], r10 + mov QWORD PTR [rcx+24], r11 + mov rax, QWORD PTR [rsp+32] + mov rdx, QWORD PTR [rsp+40] + mov r10, QWORD PTR [rsp+48] + mov r11, QWORD PTR [rsp+56] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], rdx + mov QWORD PTR [rcx+48], r10 + mov QWORD PTR [rcx+56], r11 + mov rax, QWORD PTR [rsp+64] + mov rdx, QWORD PTR [rsp+72] + mov r10, QWORD PTR [rsp+80] + mov r11, QWORD PTR [rsp+88] + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], rdx + mov QWORD PTR [rcx+80], r10 + mov QWORD PTR [rcx+88], r11 + mov rax, QWORD PTR [rsp+96] + mov rdx, QWORD PTR [rsp+104] + mov r10, QWORD PTR [rsp+112] + mov r11, QWORD PTR [rsp+120] + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], rdx + mov QWORD PTR [rcx+112], r10 + mov QWORD PTR [rcx+120], r11 + add rsp, 128 + pop r12 + ret +sp_1024_mul_16 ENDP +_text ENDS +; /* Square a and put result in r. (r = a * a) +; * +; * r A single precision integer. +; * a A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_1024_sqr_16 PROC + push r12 + push r13 + push r14 + mov r8, rdx + sub rsp, 128 + ; A[0] * A[0] + mov rax, QWORD PTR [r8] + mul rax + xor r11, r11 + mov QWORD PTR [rsp], rax + mov r10, rdx + ; A[0] * A[1] + mov rax, QWORD PTR [r8+8] + mul QWORD PTR [r8] + xor r9, r9 + add r10, rax + adc r11, rdx + adc r9, 0 + add r10, rax + adc r11, rdx + adc r9, 0 + mov QWORD PTR [rsp+8], r10 + ; A[0] * A[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r8] + xor r10, r10 + add r11, rax + adc r9, rdx + adc r10, 0 + add r11, rax + adc r9, rdx + adc r10, 0 + ; A[1] * A[1] + mov rax, QWORD PTR [r8+8] + mul rax + add r11, rax + adc r9, rdx + adc r10, 0 + mov QWORD PTR [rsp+16], r11 + ; A[0] * A[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r8] + xor r11, r11 + add r9, rax + adc r10, rdx + adc r11, 0 + add r9, rax + adc r10, rdx + adc r11, 0 + ; A[1] * A[2] + mov rax, QWORD PTR [r8+16] + mul QWORD PTR [r8+8] + add r9, rax + adc r10, rdx + adc r11, 0 + add r9, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rsp+24], r9 + ; A[0] * A[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r8] + xor r9, r9 + add r10, rax + adc r11, rdx + adc r9, 0 + add r10, rax + adc r11, rdx + adc r9, 0 + ; A[1] * A[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r8+8] + add r10, rax + adc r11, rdx + adc r9, 0 + add r10, rax + adc r11, rdx + adc r9, 0 + ; A[2] * A[2] + mov rax, QWORD PTR [r8+16] + mul rax + add r10, rax + adc r11, rdx + adc r9, 0 + mov QWORD PTR [rsp+32], r10 + ; A[0] * A[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r8] + xor r10, r10 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[3] + mov rax, QWORD PTR [r8+24] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r11, r12 + adc r9, r13 + adc r10, r14 + mov QWORD PTR [rsp+40], r11 + ; A[0] * A[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r8] + xor r11, r11 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[3] + mov rax, QWORD PTR [r8+24] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r9, r12 + adc r10, r13 + adc r11, r14 + mov QWORD PTR [rsp+48], r9 + ; A[0] * A[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r8] + xor r9, r9 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[4] + mov rax, QWORD PTR [r8+32] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r10, r12 + adc r11, r13 + adc r9, r14 + mov QWORD PTR [rsp+56], r10 + ; A[0] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8] + xor r10, r10 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[4] + mov rax, QWORD PTR [r8+32] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r11, r12 + adc r9, r13 + adc r10, r14 + mov QWORD PTR [rsp+64], r11 + ; A[0] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8] + xor r11, r11 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[5] + mov rax, QWORD PTR [r8+40] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r9, r12 + adc r10, r13 + adc r11, r14 + mov QWORD PTR [rsp+72], r9 + ; A[0] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8] + xor r9, r9 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[5] * A[5] + mov rax, QWORD PTR [r8+40] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r10, r12 + adc r11, r13 + adc r9, r14 + mov QWORD PTR [rsp+80], r10 + ; A[0] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8] + xor r10, r10 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[5] * A[6] + mov rax, QWORD PTR [r8+48] + mul QWORD PTR [r8+40] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r11, r12 + adc r9, r13 + adc r10, r14 + mov QWORD PTR [rsp+88], r11 + ; A[0] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8] + xor r11, r11 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[5] * A[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r8+40] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[6] * A[6] + mov rax, QWORD PTR [r8+48] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r9, r12 + adc r10, r13 + adc r11, r14 + mov QWORD PTR [rsp+96], r9 + ; A[0] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8] + xor r9, r9 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[5] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8+40] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[6] * A[7] + mov rax, QWORD PTR [r8+56] + mul QWORD PTR [r8+48] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r10, r12 + adc r11, r13 + adc r9, r14 + mov QWORD PTR [rsp+104], r10 + ; A[0] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8] + xor r10, r10 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[5] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+40] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[6] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8+48] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[7] * A[7] + mov rax, QWORD PTR [r8+56] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r11, r12 + adc r9, r13 + adc r10, r14 + mov QWORD PTR [rsp+112], r11 + ; A[0] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8] + xor r11, r11 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[1] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+8] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[2] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[5] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+40] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[6] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+48] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[7] * A[8] + mov rax, QWORD PTR [r8+64] + mul QWORD PTR [r8+56] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r9, r12 + adc r10, r13 + adc r11, r14 + mov QWORD PTR [rsp+120], r9 + ; A[1] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+8] + xor r9, r9 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[2] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+16] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[3] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[5] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+40] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[6] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+48] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[7] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+56] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[8] * A[8] + mov rax, QWORD PTR [r8+64] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r10, r12 + adc r11, r13 + adc r9, r14 + mov QWORD PTR [rcx+128], r10 + ; A[2] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+16] + xor r10, r10 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[3] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+24] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[4] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[5] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8+40] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[6] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+48] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[7] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+56] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[8] * A[9] + mov rax, QWORD PTR [r8+72] + mul QWORD PTR [r8+64] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r11, r12 + adc r9, r13 + adc r10, r14 + mov QWORD PTR [rcx+136], r11 + ; A[3] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+24] + xor r11, r11 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[4] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+32] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[5] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+40] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[6] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8+48] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[7] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+56] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[8] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+64] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[9] * A[9] + mov rax, QWORD PTR [r8+72] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r9, r12 + adc r10, r13 + adc r11, r14 + mov QWORD PTR [rcx+144], r9 + ; A[4] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+32] + xor r9, r9 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[5] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+40] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[6] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+48] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[7] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8+56] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[8] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+64] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[9] * A[10] + mov rax, QWORD PTR [r8+80] + mul QWORD PTR [r8+72] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r10, r12 + adc r11, r13 + adc r9, r14 + mov QWORD PTR [rcx+152], r10 + ; A[5] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+40] + xor r10, r10 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[6] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+48] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[7] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+56] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[8] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8+64] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[9] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+72] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[10] * A[10] + mov rax, QWORD PTR [r8+80] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r11, r12 + adc r9, r13 + adc r10, r14 + mov QWORD PTR [rcx+160], r11 + ; A[6] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+48] + xor r11, r11 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[7] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+56] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[8] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+64] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[9] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8+72] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[10] * A[11] + mov rax, QWORD PTR [r8+88] + mul QWORD PTR [r8+80] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r9, r12 + adc r10, r13 + adc r11, r14 + mov QWORD PTR [rcx+168], r9 + ; A[7] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+56] + xor r9, r9 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[8] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+64] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[9] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+72] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[10] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8+80] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[11] * A[11] + mov rax, QWORD PTR [r8+88] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r10, r12 + adc r11, r13 + adc r9, r14 + mov QWORD PTR [rcx+176], r10 + ; A[8] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+64] + xor r10, r10 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[9] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+72] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[10] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+80] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[11] * A[12] + mov rax, QWORD PTR [r8+96] + mul QWORD PTR [r8+88] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r11, r12 + adc r9, r13 + adc r10, r14 + mov QWORD PTR [rcx+184], r11 + ; A[9] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+72] + xor r11, r11 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[10] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+80] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[11] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+88] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[12] * A[12] + mov rax, QWORD PTR [r8+96] + mul rax + add r12, r12 + adc r13, r13 + adc r14, r14 + add r12, rax + adc r13, rdx + adc r14, 0 + add r9, r12 + adc r10, r13 + adc r11, r14 + mov QWORD PTR [rcx+192], r9 + ; A[10] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+80] + xor r9, r9 + xor r14, r14 + mov r12, rax + mov r13, rdx + ; A[11] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+88] + add r12, rax + adc r13, rdx + adc r14, 0 + ; A[12] * A[13] + mov rax, QWORD PTR [r8+104] + mul QWORD PTR [r8+96] + add r12, rax + adc r13, rdx + adc r14, 0 + add r12, r12 + adc r13, r13 + adc r14, r14 + add r10, r12 + adc r11, r13 + adc r9, r14 + mov QWORD PTR [rcx+200], r10 + ; A[11] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+88] + xor r10, r10 + add r11, rax + adc r9, rdx + adc r10, 0 + add r11, rax + adc r9, rdx + adc r10, 0 + ; A[12] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+96] + add r11, rax + adc r9, rdx + adc r10, 0 + add r11, rax + adc r9, rdx + adc r10, 0 + ; A[13] * A[13] + mov rax, QWORD PTR [r8+104] + mul rax + add r11, rax + adc r9, rdx + adc r10, 0 + mov QWORD PTR [rcx+208], r11 + ; A[12] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+96] + xor r11, r11 + add r9, rax + adc r10, rdx + adc r11, 0 + add r9, rax + adc r10, rdx + adc r11, 0 + ; A[13] * A[14] + mov rax, QWORD PTR [r8+112] + mul QWORD PTR [r8+104] + add r9, rax + adc r10, rdx + adc r11, 0 + add r9, rax + adc r10, rdx + adc r11, 0 + mov QWORD PTR [rcx+216], r9 + ; A[13] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+104] + xor r9, r9 + add r10, rax + adc r11, rdx + adc r9, 0 + add r10, rax + adc r11, rdx + adc r9, 0 + ; A[14] * A[14] + mov rax, QWORD PTR [r8+112] + mul rax + add r10, rax + adc r11, rdx + adc r9, 0 + mov QWORD PTR [rcx+224], r10 + ; A[14] * A[15] + mov rax, QWORD PTR [r8+120] + mul QWORD PTR [r8+112] + xor r10, r10 + add r11, rax + adc r9, rdx + adc r10, 0 + add r11, rax + adc r9, rdx + adc r10, 0 + mov QWORD PTR [rcx+232], r11 + ; A[15] * A[15] + mov rax, QWORD PTR [r8+120] + mul rax + add r9, rax + adc r10, rdx + mov QWORD PTR [rcx+240], r9 + mov QWORD PTR [rcx+248], r10 + mov rax, QWORD PTR [rsp] + mov rdx, QWORD PTR [rsp+8] + mov r12, QWORD PTR [rsp+16] + mov r13, QWORD PTR [rsp+24] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], rdx + mov QWORD PTR [rcx+16], r12 + mov QWORD PTR [rcx+24], r13 + mov rax, QWORD PTR [rsp+32] + mov rdx, QWORD PTR [rsp+40] + mov r12, QWORD PTR [rsp+48] + mov r13, QWORD PTR [rsp+56] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], rdx + mov QWORD PTR [rcx+48], r12 + mov QWORD PTR [rcx+56], r13 + mov rax, QWORD PTR [rsp+64] + mov rdx, QWORD PTR [rsp+72] + mov r12, QWORD PTR [rsp+80] + mov r13, QWORD PTR [rsp+88] + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], rdx + mov QWORD PTR [rcx+80], r12 + mov QWORD PTR [rcx+88], r13 + mov rax, QWORD PTR [rsp+96] + mov rdx, QWORD PTR [rsp+104] + mov r12, QWORD PTR [rsp+112] + mov r13, QWORD PTR [rsp+120] + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], rdx + mov QWORD PTR [rcx+112], r12 + mov QWORD PTR [rcx+120], r13 + add rsp, 128 + pop r14 + pop r13 + pop r12 + ret +sp_1024_sqr_16 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Multiply a and b into r. (r = a * b) +; * +; * r Result of multiplication. +; * a First number to multiply. +; * b Second number to multiply. +; */ +_text SEGMENT READONLY PARA +sp_1024_mul_avx2_16 PROC + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + push rdi + mov rbp, r8 + mov r8, rcx + mov r9, rdx + sub rsp, 128 + cmp r9, r8 + mov rbx, rsp + cmovne rbx, r8 + cmp rbp, r8 + cmove rbx, rsp + add r8, 128 + xor rdi, rdi + mov rdx, QWORD PTR [r9] + ; A[0] * B[0] + mulx r11, r10, QWORD PTR [rbp] + ; A[0] * B[1] + mulx r12, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx], r10 + adcx r11, rax + ; A[0] * B[2] + mulx r13, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+8], r11 + adcx r12, rax + ; A[0] * B[3] + mulx r14, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+16], r12 + adcx r13, rax + mov QWORD PTR [rbx+24], r13 + ; A[0] * B[4] + mulx r10, rax, QWORD PTR [rbp+32] + adcx r14, rax + ; A[0] * B[5] + mulx r11, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+32], r14 + adcx r10, rax + ; A[0] * B[6] + mulx r12, rax, QWORD PTR [rbp+48] + mov QWORD PTR [rbx+40], r10 + adcx r11, rax + ; A[0] * B[7] + mulx r13, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+48], r11 + adcx r12, rax + mov QWORD PTR [rbx+56], r12 + ; A[0] * B[8] + mulx r14, rax, QWORD PTR [rbp+64] + adcx r13, rax + ; A[0] * B[9] + mulx r10, rax, QWORD PTR [rbp+72] + mov QWORD PTR [rbx+64], r13 + adcx r14, rax + ; A[0] * B[10] + mulx r11, rax, QWORD PTR [rbp+80] + mov QWORD PTR [rbx+72], r14 + adcx r10, rax + ; A[0] * B[11] + mulx r12, rax, QWORD PTR [rbp+88] + mov QWORD PTR [rbx+80], r10 + adcx r11, rax + mov QWORD PTR [rbx+88], r11 + ; A[0] * B[12] + mulx r13, rax, QWORD PTR [rbp+96] + adcx r12, rax + ; A[0] * B[13] + mulx r14, rax, QWORD PTR [rbp+104] + mov QWORD PTR [rbx+96], r12 + adcx r13, rax + ; A[0] * B[14] + mulx r10, rax, QWORD PTR [rbp+112] + mov QWORD PTR [rbx+104], r13 + adcx r14, rax + ; A[0] * B[15] + mulx r11, rax, QWORD PTR [rbp+120] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adcx r11, rdi + mov r15, rdi + adcx r15, rdi + mov QWORD PTR [rbx+120], r10 + mov QWORD PTR [r8], r11 + mov rdx, QWORD PTR [r9+8] + mov r11, QWORD PTR [rbx+8] + mov r12, QWORD PTR [rbx+16] + mov r13, QWORD PTR [rbx+24] + mov r14, QWORD PTR [rbx+32] + mov r10, QWORD PTR [rbx+40] + ; A[1] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r11, rax + adox r12, rcx + ; A[1] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+8], r11 + adcx r12, rax + adox r13, rcx + ; A[1] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+16], r12 + adcx r13, rax + adox r14, rcx + ; A[1] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+24], r13 + adcx r14, rax + adox r10, rcx + mov QWORD PTR [rbx+32], r14 + mov r11, QWORD PTR [rbx+48] + mov r12, QWORD PTR [rbx+56] + mov r13, QWORD PTR [rbx+64] + mov r14, QWORD PTR [rbx+72] + ; A[1] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r10, rax + adox r11, rcx + ; A[1] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+40], r10 + adcx r11, rax + adox r12, rcx + ; A[1] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [rbx+48], r11 + adcx r12, rax + adox r13, rcx + ; A[1] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+56], r12 + adcx r13, rax + adox r14, rcx + mov QWORD PTR [rbx+64], r13 + mov r10, QWORD PTR [rbx+80] + mov r11, QWORD PTR [rbx+88] + mov r12, QWORD PTR [rbx+96] + mov r13, QWORD PTR [rbx+104] + ; A[1] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r14, rax + adox r10, rcx + ; A[1] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [rbx+72], r14 + adcx r10, rax + adox r11, rcx + ; A[1] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [rbx+80], r10 + adcx r11, rax + adox r12, rcx + ; A[1] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [rbx+88], r11 + adcx r12, rax + adox r13, rcx + mov QWORD PTR [rbx+96], r12 + mov r14, QWORD PTR [rbx+112] + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + ; A[1] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r13, rax + adox r14, rcx + ; A[1] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [rbx+104], r13 + adcx r14, rax + adox r10, rcx + ; A[1] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adox r11, rcx + ; A[1] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [rbx+120], r10 + mov r12, rdi + adcx r11, rax + adox r12, rcx + adcx r12, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8], r11 + mov QWORD PTR [r8+8], r12 + mov rdx, QWORD PTR [r9+16] + mov r12, QWORD PTR [rbx+16] + mov r13, QWORD PTR [rbx+24] + mov r14, QWORD PTR [rbx+32] + mov r10, QWORD PTR [rbx+40] + mov r11, QWORD PTR [rbx+48] + ; A[2] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r12, rax + adox r13, rcx + ; A[2] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+16], r12 + adcx r13, rax + adox r14, rcx + ; A[2] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+24], r13 + adcx r14, rax + adox r10, rcx + ; A[2] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+32], r14 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbx+40], r10 + mov r12, QWORD PTR [rbx+56] + mov r13, QWORD PTR [rbx+64] + mov r14, QWORD PTR [rbx+72] + mov r10, QWORD PTR [rbx+80] + ; A[2] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r11, rax + adox r12, rcx + ; A[2] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+48], r11 + adcx r12, rax + adox r13, rcx + ; A[2] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [rbx+56], r12 + adcx r13, rax + adox r14, rcx + ; A[2] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+64], r13 + adcx r14, rax + adox r10, rcx + mov QWORD PTR [rbx+72], r14 + mov r11, QWORD PTR [rbx+88] + mov r12, QWORD PTR [rbx+96] + mov r13, QWORD PTR [rbx+104] + mov r14, QWORD PTR [rbx+112] + ; A[2] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r10, rax + adox r11, rcx + ; A[2] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [rbx+80], r10 + adcx r11, rax + adox r12, rcx + ; A[2] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [rbx+88], r11 + adcx r12, rax + adox r13, rcx + ; A[2] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [rbx+96], r12 + adcx r13, rax + adox r14, rcx + mov QWORD PTR [rbx+104], r13 + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + ; A[2] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r14, rax + adox r10, rcx + ; A[2] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adox r11, rcx + ; A[2] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [rbx+120], r10 + adcx r11, rax + adox r12, rcx + ; A[2] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8], r11 + mov r13, rdi + adcx r12, rax + adox r13, rcx + adcx r13, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+8], r12 + mov QWORD PTR [r8+16], r13 + mov rdx, QWORD PTR [r9+24] + mov r13, QWORD PTR [rbx+24] + mov r14, QWORD PTR [rbx+32] + mov r10, QWORD PTR [rbx+40] + mov r11, QWORD PTR [rbx+48] + mov r12, QWORD PTR [rbx+56] + ; A[3] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r13, rax + adox r14, rcx + ; A[3] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+24], r13 + adcx r14, rax + adox r10, rcx + ; A[3] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+32], r14 + adcx r10, rax + adox r11, rcx + ; A[3] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+40], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbx+48], r11 + mov r13, QWORD PTR [rbx+64] + mov r14, QWORD PTR [rbx+72] + mov r10, QWORD PTR [rbx+80] + mov r11, QWORD PTR [rbx+88] + ; A[3] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r12, rax + adox r13, rcx + ; A[3] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+56], r12 + adcx r13, rax + adox r14, rcx + ; A[3] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [rbx+64], r13 + adcx r14, rax + adox r10, rcx + ; A[3] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+72], r14 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbx+80], r10 + mov r12, QWORD PTR [rbx+96] + mov r13, QWORD PTR [rbx+104] + mov r14, QWORD PTR [rbx+112] + mov r10, QWORD PTR [rbx+120] + ; A[3] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r11, rax + adox r12, rcx + ; A[3] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [rbx+88], r11 + adcx r12, rax + adox r13, rcx + ; A[3] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [rbx+96], r12 + adcx r13, rax + adox r14, rcx + ; A[3] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [rbx+104], r13 + adcx r14, rax + adox r10, rcx + mov QWORD PTR [rbx+112], r14 + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + mov r13, QWORD PTR [r8+16] + ; A[3] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r10, rax + adox r11, rcx + ; A[3] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [rbx+120], r10 + adcx r11, rax + adox r12, rcx + ; A[3] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8], r11 + adcx r12, rax + adox r13, rcx + ; A[3] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+8], r12 + mov r14, rdi + adcx r13, rax + adox r14, rcx + adcx r14, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+16], r13 + mov QWORD PTR [r8+24], r14 + mov rdx, QWORD PTR [r9+32] + mov r14, QWORD PTR [rbx+32] + mov r10, QWORD PTR [rbx+40] + mov r11, QWORD PTR [rbx+48] + mov r12, QWORD PTR [rbx+56] + mov r13, QWORD PTR [rbx+64] + ; A[4] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r14, rax + adox r10, rcx + ; A[4] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+32], r14 + adcx r10, rax + adox r11, rcx + ; A[4] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+40], r10 + adcx r11, rax + adox r12, rcx + ; A[4] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+48], r11 + adcx r12, rax + adox r13, rcx + mov QWORD PTR [rbx+56], r12 + mov r14, QWORD PTR [rbx+72] + mov r10, QWORD PTR [rbx+80] + mov r11, QWORD PTR [rbx+88] + mov r12, QWORD PTR [rbx+96] + ; A[4] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r13, rax + adox r14, rcx + ; A[4] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+64], r13 + adcx r14, rax + adox r10, rcx + ; A[4] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [rbx+72], r14 + adcx r10, rax + adox r11, rcx + ; A[4] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+80], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbx+88], r11 + mov r13, QWORD PTR [rbx+104] + mov r14, QWORD PTR [rbx+112] + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + ; A[4] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r12, rax + adox r13, rcx + ; A[4] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [rbx+96], r12 + adcx r13, rax + adox r14, rcx + ; A[4] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [rbx+104], r13 + adcx r14, rax + adox r10, rcx + ; A[4] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbx+120], r10 + mov r12, QWORD PTR [r8+8] + mov r13, QWORD PTR [r8+16] + mov r14, QWORD PTR [r8+24] + ; A[4] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r11, rax + adox r12, rcx + ; A[4] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8], r11 + adcx r12, rax + adox r13, rcx + ; A[4] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+8], r12 + adcx r13, rax + adox r14, rcx + ; A[4] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+16], r13 + mov r10, rdi + adcx r14, rax + adox r10, rcx + adcx r10, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+24], r14 + mov QWORD PTR [r8+32], r10 + mov rdx, QWORD PTR [r9+40] + mov r10, QWORD PTR [rbx+40] + mov r11, QWORD PTR [rbx+48] + mov r12, QWORD PTR [rbx+56] + mov r13, QWORD PTR [rbx+64] + mov r14, QWORD PTR [rbx+72] + ; A[5] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r10, rax + adox r11, rcx + ; A[5] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+40], r10 + adcx r11, rax + adox r12, rcx + ; A[5] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+48], r11 + adcx r12, rax + adox r13, rcx + ; A[5] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+56], r12 + adcx r13, rax + adox r14, rcx + mov QWORD PTR [rbx+64], r13 + mov r10, QWORD PTR [rbx+80] + mov r11, QWORD PTR [rbx+88] + mov r12, QWORD PTR [rbx+96] + mov r13, QWORD PTR [rbx+104] + ; A[5] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r14, rax + adox r10, rcx + ; A[5] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+72], r14 + adcx r10, rax + adox r11, rcx + ; A[5] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [rbx+80], r10 + adcx r11, rax + adox r12, rcx + ; A[5] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+88], r11 + adcx r12, rax + adox r13, rcx + mov QWORD PTR [rbx+96], r12 + mov r14, QWORD PTR [rbx+112] + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + ; A[5] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r13, rax + adox r14, rcx + ; A[5] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [rbx+104], r13 + adcx r14, rax + adox r10, rcx + ; A[5] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adox r11, rcx + ; A[5] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [rbx+120], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8], r11 + mov r13, QWORD PTR [r8+16] + mov r14, QWORD PTR [r8+24] + mov r10, QWORD PTR [r8+32] + ; A[5] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r12, rax + adox r13, rcx + ; A[5] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8+8], r12 + adcx r13, rax + adox r14, rcx + ; A[5] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+16], r13 + adcx r14, rax + adox r10, rcx + ; A[5] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+24], r14 + mov r11, rdi + adcx r10, rax + adox r11, rcx + adcx r11, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+32], r10 + mov QWORD PTR [r8+40], r11 + mov rdx, QWORD PTR [r9+48] + mov r11, QWORD PTR [rbx+48] + mov r12, QWORD PTR [rbx+56] + mov r13, QWORD PTR [rbx+64] + mov r14, QWORD PTR [rbx+72] + mov r10, QWORD PTR [rbx+80] + ; A[6] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r11, rax + adox r12, rcx + ; A[6] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+48], r11 + adcx r12, rax + adox r13, rcx + ; A[6] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+56], r12 + adcx r13, rax + adox r14, rcx + ; A[6] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+64], r13 + adcx r14, rax + adox r10, rcx + mov QWORD PTR [rbx+72], r14 + mov r11, QWORD PTR [rbx+88] + mov r12, QWORD PTR [rbx+96] + mov r13, QWORD PTR [rbx+104] + mov r14, QWORD PTR [rbx+112] + ; A[6] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r10, rax + adox r11, rcx + ; A[6] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+80], r10 + adcx r11, rax + adox r12, rcx + ; A[6] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [rbx+88], r11 + adcx r12, rax + adox r13, rcx + ; A[6] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+96], r12 + adcx r13, rax + adox r14, rcx + mov QWORD PTR [rbx+104], r13 + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + mov r13, QWORD PTR [r8+16] + ; A[6] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r14, rax + adox r10, rcx + ; A[6] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adox r11, rcx + ; A[6] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [rbx+120], r10 + adcx r11, rax + adox r12, rcx + ; A[6] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8], r11 + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r8+8], r12 + mov r14, QWORD PTR [r8+24] + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + ; A[6] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r13, rax + adox r14, rcx + ; A[6] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8+16], r13 + adcx r14, rax + adox r10, rcx + ; A[6] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+24], r14 + adcx r10, rax + adox r11, rcx + ; A[6] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+32], r10 + mov r12, rdi + adcx r11, rax + adox r12, rcx + adcx r12, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+40], r11 + mov QWORD PTR [r8+48], r12 + mov rdx, QWORD PTR [r9+56] + mov r12, QWORD PTR [rbx+56] + mov r13, QWORD PTR [rbx+64] + mov r14, QWORD PTR [rbx+72] + mov r10, QWORD PTR [rbx+80] + mov r11, QWORD PTR [rbx+88] + ; A[7] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r12, rax + adox r13, rcx + ; A[7] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+56], r12 + adcx r13, rax + adox r14, rcx + ; A[7] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+64], r13 + adcx r14, rax + adox r10, rcx + ; A[7] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+72], r14 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbx+80], r10 + mov r12, QWORD PTR [rbx+96] + mov r13, QWORD PTR [rbx+104] + mov r14, QWORD PTR [rbx+112] + mov r10, QWORD PTR [rbx+120] + ; A[7] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r11, rax + adox r12, rcx + ; A[7] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+88], r11 + adcx r12, rax + adox r13, rcx + ; A[7] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [rbx+96], r12 + adcx r13, rax + adox r14, rcx + ; A[7] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+104], r13 + adcx r14, rax + adox r10, rcx + mov QWORD PTR [rbx+112], r14 + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + mov r13, QWORD PTR [r8+16] + mov r14, QWORD PTR [r8+24] + ; A[7] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r10, rax + adox r11, rcx + ; A[7] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [rbx+120], r10 + adcx r11, rax + adox r12, rcx + ; A[7] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [r8], r11 + adcx r12, rax + adox r13, rcx + ; A[7] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+8], r12 + adcx r13, rax + adox r14, rcx + mov QWORD PTR [r8+16], r13 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + mov r12, QWORD PTR [r8+48] + ; A[7] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r14, rax + adox r10, rcx + ; A[7] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8+24], r14 + adcx r10, rax + adox r11, rcx + ; A[7] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+32], r10 + adcx r11, rax + adox r12, rcx + ; A[7] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+40], r11 + mov r13, rdi + adcx r12, rax + adox r13, rcx + adcx r13, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+48], r12 + mov QWORD PTR [r8+56], r13 + mov rdx, QWORD PTR [r9+64] + mov r13, QWORD PTR [rbx+64] + mov r14, QWORD PTR [rbx+72] + mov r10, QWORD PTR [rbx+80] + mov r11, QWORD PTR [rbx+88] + mov r12, QWORD PTR [rbx+96] + ; A[8] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r13, rax + adox r14, rcx + ; A[8] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+64], r13 + adcx r14, rax + adox r10, rcx + ; A[8] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+72], r14 + adcx r10, rax + adox r11, rcx + ; A[8] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+80], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbx+88], r11 + mov r13, QWORD PTR [rbx+104] + mov r14, QWORD PTR [rbx+112] + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + ; A[8] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r12, rax + adox r13, rcx + ; A[8] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+96], r12 + adcx r13, rax + adox r14, rcx + ; A[8] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [rbx+104], r13 + adcx r14, rax + adox r10, rcx + ; A[8] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbx+120], r10 + mov r12, QWORD PTR [r8+8] + mov r13, QWORD PTR [r8+16] + mov r14, QWORD PTR [r8+24] + mov r10, QWORD PTR [r8+32] + ; A[8] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r11, rax + adox r12, rcx + ; A[8] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8], r11 + adcx r12, rax + adox r13, rcx + ; A[8] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [r8+8], r12 + adcx r13, rax + adox r14, rcx + ; A[8] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+16], r13 + adcx r14, rax + adox r10, rcx + mov QWORD PTR [r8+24], r14 + mov r11, QWORD PTR [r8+40] + mov r12, QWORD PTR [r8+48] + mov r13, QWORD PTR [r8+56] + ; A[8] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r10, rax + adox r11, rcx + ; A[8] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8+32], r10 + adcx r11, rax + adox r12, rcx + ; A[8] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+40], r11 + adcx r12, rax + adox r13, rcx + ; A[8] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+48], r12 + mov r14, rdi + adcx r13, rax + adox r14, rcx + adcx r14, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+56], r13 + mov QWORD PTR [r8+64], r14 + mov rdx, QWORD PTR [r9+72] + mov r14, QWORD PTR [rbx+72] + mov r10, QWORD PTR [rbx+80] + mov r11, QWORD PTR [rbx+88] + mov r12, QWORD PTR [rbx+96] + mov r13, QWORD PTR [rbx+104] + ; A[9] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r14, rax + adox r10, rcx + ; A[9] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+72], r14 + adcx r10, rax + adox r11, rcx + ; A[9] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+80], r10 + adcx r11, rax + adox r12, rcx + ; A[9] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+88], r11 + adcx r12, rax + adox r13, rcx + mov QWORD PTR [rbx+96], r12 + mov r14, QWORD PTR [rbx+112] + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + ; A[9] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r13, rax + adox r14, rcx + ; A[9] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+104], r13 + adcx r14, rax + adox r10, rcx + ; A[9] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adox r11, rcx + ; A[9] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [rbx+120], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8], r11 + mov r13, QWORD PTR [r8+16] + mov r14, QWORD PTR [r8+24] + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + ; A[9] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r12, rax + adox r13, rcx + ; A[9] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8+8], r12 + adcx r13, rax + adox r14, rcx + ; A[9] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [r8+16], r13 + adcx r14, rax + adox r10, rcx + ; A[9] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+24], r14 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+32], r10 + mov r12, QWORD PTR [r8+48] + mov r13, QWORD PTR [r8+56] + mov r14, QWORD PTR [r8+64] + ; A[9] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r11, rax + adox r12, rcx + ; A[9] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8+40], r11 + adcx r12, rax + adox r13, rcx + ; A[9] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+48], r12 + adcx r13, rax + adox r14, rcx + ; A[9] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+56], r13 + mov r10, rdi + adcx r14, rax + adox r10, rcx + adcx r10, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+64], r14 + mov QWORD PTR [r8+72], r10 + mov rdx, QWORD PTR [r9+80] + mov r10, QWORD PTR [rbx+80] + mov r11, QWORD PTR [rbx+88] + mov r12, QWORD PTR [rbx+96] + mov r13, QWORD PTR [rbx+104] + mov r14, QWORD PTR [rbx+112] + ; A[10] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r10, rax + adox r11, rcx + ; A[10] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+80], r10 + adcx r11, rax + adox r12, rcx + ; A[10] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+88], r11 + adcx r12, rax + adox r13, rcx + ; A[10] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+96], r12 + adcx r13, rax + adox r14, rcx + mov QWORD PTR [rbx+104], r13 + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + mov r13, QWORD PTR [r8+16] + ; A[10] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r14, rax + adox r10, rcx + ; A[10] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adox r11, rcx + ; A[10] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [rbx+120], r10 + adcx r11, rax + adox r12, rcx + ; A[10] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [r8], r11 + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r8+8], r12 + mov r14, QWORD PTR [r8+24] + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + mov r12, QWORD PTR [r8+48] + ; A[10] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r13, rax + adox r14, rcx + ; A[10] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8+16], r13 + adcx r14, rax + adox r10, rcx + ; A[10] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [r8+24], r14 + adcx r10, rax + adox r11, rcx + ; A[10] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+32], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+40], r11 + mov r13, QWORD PTR [r8+56] + mov r14, QWORD PTR [r8+64] + mov r10, QWORD PTR [r8+72] + ; A[10] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r12, rax + adox r13, rcx + ; A[10] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8+48], r12 + adcx r13, rax + adox r14, rcx + ; A[10] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+56], r13 + adcx r14, rax + adox r10, rcx + ; A[10] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+64], r14 + mov r11, rdi + adcx r10, rax + adox r11, rcx + adcx r11, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+72], r10 + mov QWORD PTR [r8+80], r11 + mov rdx, QWORD PTR [r9+88] + mov r11, QWORD PTR [rbx+88] + mov r12, QWORD PTR [rbx+96] + mov r13, QWORD PTR [rbx+104] + mov r14, QWORD PTR [rbx+112] + mov r10, QWORD PTR [rbx+120] + ; A[11] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r11, rax + adox r12, rcx + ; A[11] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+88], r11 + adcx r12, rax + adox r13, rcx + ; A[11] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+96], r12 + adcx r13, rax + adox r14, rcx + ; A[11] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+104], r13 + adcx r14, rax + adox r10, rcx + mov QWORD PTR [rbx+112], r14 + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + mov r13, QWORD PTR [r8+16] + mov r14, QWORD PTR [r8+24] + ; A[11] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r10, rax + adox r11, rcx + ; A[11] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [rbx+120], r10 + adcx r11, rax + adox r12, rcx + ; A[11] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [r8], r11 + adcx r12, rax + adox r13, rcx + ; A[11] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [r8+8], r12 + adcx r13, rax + adox r14, rcx + mov QWORD PTR [r8+16], r13 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + mov r12, QWORD PTR [r8+48] + mov r13, QWORD PTR [r8+56] + ; A[11] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r14, rax + adox r10, rcx + ; A[11] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8+24], r14 + adcx r10, rax + adox r11, rcx + ; A[11] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [r8+32], r10 + adcx r11, rax + adox r12, rcx + ; A[11] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+40], r11 + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r8+48], r12 + mov r14, QWORD PTR [r8+64] + mov r10, QWORD PTR [r8+72] + mov r11, QWORD PTR [r8+80] + ; A[11] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r13, rax + adox r14, rcx + ; A[11] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8+56], r13 + adcx r14, rax + adox r10, rcx + ; A[11] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+64], r14 + adcx r10, rax + adox r11, rcx + ; A[11] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+72], r10 + mov r12, rdi + adcx r11, rax + adox r12, rcx + adcx r12, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+80], r11 + mov QWORD PTR [r8+88], r12 + mov rdx, QWORD PTR [r9+96] + mov r12, QWORD PTR [rbx+96] + mov r13, QWORD PTR [rbx+104] + mov r14, QWORD PTR [rbx+112] + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + ; A[12] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r12, rax + adox r13, rcx + ; A[12] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+96], r12 + adcx r13, rax + adox r14, rcx + ; A[12] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+104], r13 + adcx r14, rax + adox r10, rcx + ; A[12] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbx+120], r10 + mov r12, QWORD PTR [r8+8] + mov r13, QWORD PTR [r8+16] + mov r14, QWORD PTR [r8+24] + mov r10, QWORD PTR [r8+32] + ; A[12] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r11, rax + adox r12, rcx + ; A[12] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [r8], r11 + adcx r12, rax + adox r13, rcx + ; A[12] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [r8+8], r12 + adcx r13, rax + adox r14, rcx + ; A[12] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [r8+16], r13 + adcx r14, rax + adox r10, rcx + mov QWORD PTR [r8+24], r14 + mov r11, QWORD PTR [r8+40] + mov r12, QWORD PTR [r8+48] + mov r13, QWORD PTR [r8+56] + mov r14, QWORD PTR [r8+64] + ; A[12] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r10, rax + adox r11, rcx + ; A[12] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8+32], r10 + adcx r11, rax + adox r12, rcx + ; A[12] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [r8+40], r11 + adcx r12, rax + adox r13, rcx + ; A[12] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+48], r12 + adcx r13, rax + adox r14, rcx + mov QWORD PTR [r8+56], r13 + mov r10, QWORD PTR [r8+72] + mov r11, QWORD PTR [r8+80] + mov r12, QWORD PTR [r8+88] + ; A[12] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r14, rax + adox r10, rcx + ; A[12] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8+64], r14 + adcx r10, rax + adox r11, rcx + ; A[12] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+72], r10 + adcx r11, rax + adox r12, rcx + ; A[12] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+80], r11 + mov r13, rdi + adcx r12, rax + adox r13, rcx + adcx r13, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+88], r12 + mov QWORD PTR [r8+96], r13 + mov rdx, QWORD PTR [r9+104] + mov r13, QWORD PTR [rbx+104] + mov r14, QWORD PTR [rbx+112] + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + ; A[13] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r13, rax + adox r14, rcx + ; A[13] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+104], r13 + adcx r14, rax + adox r10, rcx + ; A[13] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adox r11, rcx + ; A[13] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [rbx+120], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8], r11 + mov r13, QWORD PTR [r8+16] + mov r14, QWORD PTR [r8+24] + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + ; A[13] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r12, rax + adox r13, rcx + ; A[13] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [r8+8], r12 + adcx r13, rax + adox r14, rcx + ; A[13] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [r8+16], r13 + adcx r14, rax + adox r10, rcx + ; A[13] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [r8+24], r14 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+32], r10 + mov r12, QWORD PTR [r8+48] + mov r13, QWORD PTR [r8+56] + mov r14, QWORD PTR [r8+64] + mov r10, QWORD PTR [r8+72] + ; A[13] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r11, rax + adox r12, rcx + ; A[13] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8+40], r11 + adcx r12, rax + adox r13, rcx + ; A[13] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [r8+48], r12 + adcx r13, rax + adox r14, rcx + ; A[13] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+56], r13 + adcx r14, rax + adox r10, rcx + mov QWORD PTR [r8+64], r14 + mov r11, QWORD PTR [r8+80] + mov r12, QWORD PTR [r8+88] + mov r13, QWORD PTR [r8+96] + ; A[13] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r10, rax + adox r11, rcx + ; A[13] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8+72], r10 + adcx r11, rax + adox r12, rcx + ; A[13] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+80], r11 + adcx r12, rax + adox r13, rcx + ; A[13] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+88], r12 + mov r14, rdi + adcx r13, rax + adox r14, rcx + adcx r14, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+96], r13 + mov QWORD PTR [r8+104], r14 + mov rdx, QWORD PTR [r9+112] + mov r14, QWORD PTR [rbx+112] + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + mov r13, QWORD PTR [r8+16] + ; A[14] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r14, rax + adox r10, rcx + ; A[14] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+112], r14 + adcx r10, rax + adox r11, rcx + ; A[14] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [rbx+120], r10 + adcx r11, rax + adox r12, rcx + ; A[14] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [r8], r11 + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r8+8], r12 + mov r14, QWORD PTR [r8+24] + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + mov r12, QWORD PTR [r8+48] + ; A[14] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r13, rax + adox r14, rcx + ; A[14] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [r8+16], r13 + adcx r14, rax + adox r10, rcx + ; A[14] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [r8+24], r14 + adcx r10, rax + adox r11, rcx + ; A[14] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [r8+32], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+40], r11 + mov r13, QWORD PTR [r8+56] + mov r14, QWORD PTR [r8+64] + mov r10, QWORD PTR [r8+72] + mov r11, QWORD PTR [r8+80] + ; A[14] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r12, rax + adox r13, rcx + ; A[14] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8+48], r12 + adcx r13, rax + adox r14, rcx + ; A[14] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [r8+56], r13 + adcx r14, rax + adox r10, rcx + ; A[14] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+64], r14 + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+72], r10 + mov r12, QWORD PTR [r8+88] + mov r13, QWORD PTR [r8+96] + mov r14, QWORD PTR [r8+104] + ; A[14] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r11, rax + adox r12, rcx + ; A[14] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8+80], r11 + adcx r12, rax + adox r13, rcx + ; A[14] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+88], r12 + adcx r13, rax + adox r14, rcx + ; A[14] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+96], r13 + mov r10, rdi + adcx r14, rax + adox r10, rcx + adcx r10, r15 + mov r15, rdi + adox r15, rdi + adcx r15, rdi + mov QWORD PTR [r8+104], r14 + mov QWORD PTR [r8+112], r10 + mov rdx, QWORD PTR [r9+120] + mov r10, QWORD PTR [rbx+120] + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + mov r13, QWORD PTR [r8+16] + mov r14, QWORD PTR [r8+24] + ; A[15] * B[0] + mulx rcx, rax, QWORD PTR [rbp] + adcx r10, rax + adox r11, rcx + ; A[15] * B[1] + mulx rcx, rax, QWORD PTR [rbp+8] + mov QWORD PTR [rbx+120], r10 + adcx r11, rax + adox r12, rcx + ; A[15] * B[2] + mulx rcx, rax, QWORD PTR [rbp+16] + mov QWORD PTR [r8], r11 + adcx r12, rax + adox r13, rcx + ; A[15] * B[3] + mulx rcx, rax, QWORD PTR [rbp+24] + mov QWORD PTR [r8+8], r12 + adcx r13, rax + adox r14, rcx + mov QWORD PTR [r8+16], r13 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + mov r12, QWORD PTR [r8+48] + mov r13, QWORD PTR [r8+56] + ; A[15] * B[4] + mulx rcx, rax, QWORD PTR [rbp+32] + adcx r14, rax + adox r10, rcx + ; A[15] * B[5] + mulx rcx, rax, QWORD PTR [rbp+40] + mov QWORD PTR [r8+24], r14 + adcx r10, rax + adox r11, rcx + ; A[15] * B[6] + mulx rcx, rax, QWORD PTR [rbp+48] + mov QWORD PTR [r8+32], r10 + adcx r11, rax + adox r12, rcx + ; A[15] * B[7] + mulx rcx, rax, QWORD PTR [rbp+56] + mov QWORD PTR [r8+40], r11 + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r8+48], r12 + mov r14, QWORD PTR [r8+64] + mov r10, QWORD PTR [r8+72] + mov r11, QWORD PTR [r8+80] + mov r12, QWORD PTR [r8+88] + ; A[15] * B[8] + mulx rcx, rax, QWORD PTR [rbp+64] + adcx r13, rax + adox r14, rcx + ; A[15] * B[9] + mulx rcx, rax, QWORD PTR [rbp+72] + mov QWORD PTR [r8+56], r13 + adcx r14, rax + adox r10, rcx + ; A[15] * B[10] + mulx rcx, rax, QWORD PTR [rbp+80] + mov QWORD PTR [r8+64], r14 + adcx r10, rax + adox r11, rcx + ; A[15] * B[11] + mulx rcx, rax, QWORD PTR [rbp+88] + mov QWORD PTR [r8+72], r10 + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+80], r11 + mov r13, QWORD PTR [r8+96] + mov r14, QWORD PTR [r8+104] + mov r10, QWORD PTR [r8+112] + ; A[15] * B[12] + mulx rcx, rax, QWORD PTR [rbp+96] + adcx r12, rax + adox r13, rcx + ; A[15] * B[13] + mulx rcx, rax, QWORD PTR [rbp+104] + mov QWORD PTR [r8+88], r12 + adcx r13, rax + adox r14, rcx + ; A[15] * B[14] + mulx rcx, rax, QWORD PTR [rbp+112] + mov QWORD PTR [r8+96], r13 + adcx r14, rax + adox r10, rcx + ; A[15] * B[15] + mulx rcx, rax, QWORD PTR [rbp+120] + mov QWORD PTR [r8+104], r14 + mov r11, rdi + adcx r10, rax + adox r11, rcx + adcx r11, r15 + mov QWORD PTR [r8+112], r10 + mov QWORD PTR [r8+120], r11 + sub r8, 128 + cmp r9, r8 + je L_start_1024_mul_avx2_16 + cmp rbp, r8 + jne L_end_1024_mul_avx2_16 +L_start_1024_mul_avx2_16: + vmovdqu xmm0, OWORD PTR [rbx] + vmovups OWORD PTR [r8], xmm0 + vmovdqu xmm0, OWORD PTR [rbx+16] + vmovups OWORD PTR [r8+16], xmm0 + vmovdqu xmm0, OWORD PTR [rbx+32] + vmovups OWORD PTR [r8+32], xmm0 + vmovdqu xmm0, OWORD PTR [rbx+48] + vmovups OWORD PTR [r8+48], xmm0 + vmovdqu xmm0, OWORD PTR [rbx+64] + vmovups OWORD PTR [r8+64], xmm0 + vmovdqu xmm0, OWORD PTR [rbx+80] + vmovups OWORD PTR [r8+80], xmm0 + vmovdqu xmm0, OWORD PTR [rbx+96] + vmovups OWORD PTR [r8+96], xmm0 + vmovdqu xmm0, OWORD PTR [rbx+112] + vmovups OWORD PTR [r8+112], xmm0 +L_end_1024_mul_avx2_16: + add rsp, 128 + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + pop rbp + pop rbx + ret +sp_1024_mul_avx2_16 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Square a and put result in r. (r = a * a) +; * +; * r A single precision integer. +; * a A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_1024_sqr_avx2_16 PROC + push rbp + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + push rbx + mov r8, rcx + mov r9, rdx + sub rsp, 128 + cmp r9, r8 + mov rbp, rsp + cmovne rbp, r8 + add r8, 128 + xor r13, r13 + ; Diagonal 1 + xor r12, r12 + ; A[1] x A[0] + mov rdx, QWORD PTR [r9] + mulx r11, r10, QWORD PTR [r9+8] + ; A[2] x A[0] + mulx rcx, rax, QWORD PTR [r9+16] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbp+8], r10 + mov QWORD PTR [rbp+16], r11 + mov r10, r13 + mov r11, r13 + ; A[3] x A[0] + mulx rcx, rax, QWORD PTR [r9+24] + adcx r12, rax + adox r10, rcx + ; A[4] x A[0] + mulx rcx, rax, QWORD PTR [r9+32] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbp+24], r12 + mov QWORD PTR [rbp+32], r10 + mov r12, r13 + mov r10, r13 + ; A[5] x A[0] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r11, rax + adox r12, rcx + ; A[6] x A[0] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [rbp+40], r11 + mov QWORD PTR [rbp+48], r12 + mov r11, r13 + mov r12, r13 + ; A[7] x A[0] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r10, rax + adox r11, rcx + ; A[8] x A[0] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbp+56], r10 + mov QWORD PTR [rbp+64], r11 + mov r10, r13 + mov r11, r13 + ; A[9] x A[0] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r12, rax + adox r10, rcx + ; A[10] x A[0] + mulx rcx, rax, QWORD PTR [r9+80] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbp+72], r12 + mov QWORD PTR [rbp+80], r10 + mov r12, r13 + mov r10, r13 + ; A[11] x A[0] + mulx rcx, rax, QWORD PTR [r9+88] + adcx r11, rax + adox r12, rcx + ; A[12] x A[0] + mulx rcx, rax, QWORD PTR [r9+96] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [rbp+88], r11 + mov r15, r12 + mov r11, r13 + mov r12, r13 + ; A[13] x A[0] + mulx rcx, rax, QWORD PTR [r9+104] + adcx r10, rax + adox r11, rcx + ; A[14] x A[0] + mulx rcx, rax, QWORD PTR [r9+112] + adcx r11, rax + adox r12, rcx + mov rdi, r10 + mov rsi, r11 + mov r10, r13 + ; A[15] x A[0] + mulx rcx, rax, QWORD PTR [r9+120] + adcx r12, rax + adox r10, rcx + mov rbx, r12 + ; Carry + adcx r10, r13 + mov r14, r13 + adcx r14, r13 + adox r14, r13 + mov QWORD PTR [r8], r10 + ; Diagonal 2 + mov r10, QWORD PTR [rbp+24] + mov r11, QWORD PTR [rbp+32] + mov r12, QWORD PTR [rbp+40] + ; A[2] x A[1] + mov rdx, QWORD PTR [r9+8] + mulx rcx, rax, QWORD PTR [r9+16] + adcx r10, rax + adox r11, rcx + ; A[3] x A[1] + mulx rcx, rax, QWORD PTR [r9+24] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbp+24], r10 + mov QWORD PTR [rbp+32], r11 + mov r10, QWORD PTR [rbp+48] + mov r11, QWORD PTR [rbp+56] + ; A[4] x A[1] + mulx rcx, rax, QWORD PTR [r9+32] + adcx r12, rax + adox r10, rcx + ; A[5] x A[1] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbp+40], r12 + mov QWORD PTR [rbp+48], r10 + mov r12, QWORD PTR [rbp+64] + mov r10, QWORD PTR [rbp+72] + ; A[6] x A[1] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r11, rax + adox r12, rcx + ; A[7] x A[1] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [rbp+56], r11 + mov QWORD PTR [rbp+64], r12 + mov r11, QWORD PTR [rbp+80] + mov r12, QWORD PTR [rbp+88] + ; A[8] x A[1] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r10, rax + adox r11, rcx + ; A[9] x A[1] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbp+72], r10 + mov QWORD PTR [rbp+80], r11 + ; No load %r13 - %r8 + ; No load %r14 - %r9 + ; A[10] x A[1] + mulx rcx, rax, QWORD PTR [r9+80] + adcx r12, rax + adox r15, rcx + ; A[11] x A[1] + mulx rcx, rax, QWORD PTR [r9+88] + adcx r15, rax + adox rdi, rcx + mov QWORD PTR [rbp+88], r12 + ; No store %r13 + ; No load %r15 - %r10 + ; No load %rbx - %r8 + ; A[12] x A[1] + mulx rcx, rax, QWORD PTR [r9+96] + adcx rdi, rax + adox rsi, rcx + ; A[13] x A[1] + mulx rcx, rax, QWORD PTR [r9+104] + adcx rsi, rax + adox rbx, rcx + ; No store %r14 + ; No store %r15 + mov r11, QWORD PTR [r8] + mov r12, r13 + ; A[14] x A[1] + mulx rcx, rax, QWORD PTR [r9+112] + adcx rbx, rax + adox r11, rcx + ; A[15] x A[1] + mulx rcx, rax, QWORD PTR [r9+120] + adcx r11, rax + adox r12, rcx + ; No store %rbx + mov QWORD PTR [r8], r11 + mov r10, r13 + ; A[15] x A[2] + mov rdx, QWORD PTR [r9+16] + mulx rcx, rax, QWORD PTR [r9+120] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+8], r12 + ; Carry + adcx r10, r14 + mov r14, r13 + adcx r14, r13 + adox r14, r13 + mov QWORD PTR [r8+16], r10 + ; Diagonal 3 + mov r10, QWORD PTR [rbp+40] + mov r11, QWORD PTR [rbp+48] + mov r12, QWORD PTR [rbp+56] + ; A[3] x A[2] + mulx rcx, rax, QWORD PTR [r9+24] + adcx r10, rax + adox r11, rcx + ; A[4] x A[2] + mulx rcx, rax, QWORD PTR [r9+32] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbp+40], r10 + mov QWORD PTR [rbp+48], r11 + mov r10, QWORD PTR [rbp+64] + mov r11, QWORD PTR [rbp+72] + ; A[5] x A[2] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r12, rax + adox r10, rcx + ; A[6] x A[2] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbp+56], r12 + mov QWORD PTR [rbp+64], r10 + mov r12, QWORD PTR [rbp+80] + mov r10, QWORD PTR [rbp+88] + ; A[7] x A[2] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r11, rax + adox r12, rcx + ; A[8] x A[2] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [rbp+72], r11 + mov QWORD PTR [rbp+80], r12 + ; No load %r13 - %r9 + ; No load %r14 - %r10 + ; A[9] x A[2] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r10, rax + adox r15, rcx + ; A[10] x A[2] + mulx rcx, rax, QWORD PTR [r9+80] + adcx r15, rax + adox rdi, rcx + mov QWORD PTR [rbp+88], r10 + ; No store %r13 + ; No load %r15 - %r8 + ; No load %rbx - %r9 + ; A[11] x A[2] + mulx rcx, rax, QWORD PTR [r9+88] + adcx rdi, rax + adox rsi, rcx + ; A[12] x A[2] + mulx rcx, rax, QWORD PTR [r9+96] + adcx rsi, rax + adox rbx, rcx + ; No store %r14 + ; No store %r15 + mov r12, QWORD PTR [r8] + mov r10, QWORD PTR [r8+8] + ; A[13] x A[2] + mulx rcx, rax, QWORD PTR [r9+104] + adcx rbx, rax + adox r12, rcx + ; A[14] x A[2] + mulx rcx, rax, QWORD PTR [r9+112] + adcx r12, rax + adox r10, rcx + ; No store %rbx + mov QWORD PTR [r8], r12 + mov r11, QWORD PTR [r8+16] + mov r12, r13 + ; A[14] x A[3] + mov rdx, QWORD PTR [r9+112] + mulx rcx, rax, QWORD PTR [r9+24] + adcx r10, rax + adox r11, rcx + ; A[14] x A[4] + mulx rcx, rax, QWORD PTR [r9+32] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+8], r10 + mov QWORD PTR [r8+16], r11 + mov r10, r13 + ; A[14] x A[5] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+24], r12 + ; Carry + adcx r10, r14 + mov r14, r13 + adcx r14, r13 + adox r14, r13 + mov QWORD PTR [r8+32], r10 + ; Diagonal 4 + mov r10, QWORD PTR [rbp+56] + mov r11, QWORD PTR [rbp+64] + mov r12, QWORD PTR [rbp+72] + ; A[4] x A[3] + mov rdx, QWORD PTR [r9+24] + mulx rcx, rax, QWORD PTR [r9+32] + adcx r10, rax + adox r11, rcx + ; A[5] x A[3] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbp+56], r10 + mov QWORD PTR [rbp+64], r11 + mov r10, QWORD PTR [rbp+80] + mov r11, QWORD PTR [rbp+88] + ; A[6] x A[3] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r12, rax + adox r10, rcx + ; A[7] x A[3] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [rbp+72], r12 + mov QWORD PTR [rbp+80], r10 + ; No load %r13 - %r10 + ; No load %r14 - %r8 + ; A[8] x A[3] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r11, rax + adox r15, rcx + ; A[9] x A[3] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r15, rax + adox rdi, rcx + mov QWORD PTR [rbp+88], r11 + ; No store %r13 + ; No load %r15 - %r9 + ; No load %rbx - %r10 + ; A[10] x A[3] + mulx rcx, rax, QWORD PTR [r9+80] + adcx rdi, rax + adox rsi, rcx + ; A[11] x A[3] + mulx rcx, rax, QWORD PTR [r9+88] + adcx rsi, rax + adox rbx, rcx + ; No store %r14 + ; No store %r15 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + ; A[12] x A[3] + mulx rcx, rax, QWORD PTR [r9+96] + adcx rbx, rax + adox r10, rcx + ; A[13] x A[3] + mulx rcx, rax, QWORD PTR [r9+104] + adcx r10, rax + adox r11, rcx + ; No store %rbx + mov QWORD PTR [r8], r10 + mov r12, QWORD PTR [r8+16] + mov r10, QWORD PTR [r8+24] + ; A[13] x A[4] + mov rdx, QWORD PTR [r9+104] + mulx rcx, rax, QWORD PTR [r9+32] + adcx r11, rax + adox r12, rcx + ; A[13] x A[5] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+8], r11 + mov QWORD PTR [r8+16], r12 + mov r11, QWORD PTR [r8+32] + mov r12, r13 + ; A[13] x A[6] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r10, rax + adox r11, rcx + ; A[13] x A[7] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+24], r10 + mov QWORD PTR [r8+32], r11 + mov r10, r13 + ; A[13] x A[8] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+40], r12 + ; Carry + adcx r10, r14 + mov r14, r13 + adcx r14, r13 + adox r14, r13 + mov QWORD PTR [r8+48], r10 + ; Diagonal 5 + mov r10, QWORD PTR [rbp+72] + mov r11, QWORD PTR [rbp+80] + mov r12, QWORD PTR [rbp+88] + ; A[5] x A[4] + mov rdx, QWORD PTR [r9+32] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r10, rax + adox r11, rcx + ; A[6] x A[4] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [rbp+72], r10 + mov QWORD PTR [rbp+80], r11 + ; No load %r13 - %r8 + ; No load %r14 - %r9 + ; A[7] x A[4] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r12, rax + adox r15, rcx + ; A[8] x A[4] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r15, rax + adox rdi, rcx + mov QWORD PTR [rbp+88], r12 + ; No store %r13 + ; No load %r15 - %r10 + ; No load %rbx - %r8 + ; A[9] x A[4] + mulx rcx, rax, QWORD PTR [r9+72] + adcx rdi, rax + adox rsi, rcx + ; A[10] x A[4] + mulx rcx, rax, QWORD PTR [r9+80] + adcx rsi, rax + adox rbx, rcx + ; No store %r14 + ; No store %r15 + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + ; A[11] x A[4] + mulx rcx, rax, QWORD PTR [r9+88] + adcx rbx, rax + adox r11, rcx + ; A[12] x A[4] + mulx rcx, rax, QWORD PTR [r9+96] + adcx r11, rax + adox r12, rcx + ; No store %rbx + mov QWORD PTR [r8], r11 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + ; A[12] x A[5] + mov rdx, QWORD PTR [r9+96] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r12, rax + adox r10, rcx + ; A[12] x A[6] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+8], r12 + mov QWORD PTR [r8+16], r10 + mov r12, QWORD PTR [r8+32] + mov r10, QWORD PTR [r8+40] + ; A[12] x A[7] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r11, rax + adox r12, rcx + ; A[12] x A[8] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+24], r11 + mov QWORD PTR [r8+32], r12 + mov r11, QWORD PTR [r8+48] + mov r12, r13 + ; A[12] x A[9] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r10, rax + adox r11, rcx + ; A[12] x A[10] + mulx rcx, rax, QWORD PTR [r9+80] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+40], r10 + mov QWORD PTR [r8+48], r11 + mov r10, r13 + ; A[12] x A[11] + mulx rcx, rax, QWORD PTR [r9+88] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+56], r12 + ; Carry + adcx r10, r14 + mov r14, r13 + adcx r14, r13 + adox r14, r13 + mov QWORD PTR [r8+64], r10 + ; Diagonal 6 + mov r10, QWORD PTR [rbp+88] + ; No load %r13 - %r9 + ; No load %r14 - %r10 + ; A[6] x A[5] + mov rdx, QWORD PTR [r9+40] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r10, rax + adox r15, rcx + ; A[7] x A[5] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r15, rax + adox rdi, rcx + mov QWORD PTR [rbp+88], r10 + ; No store %r13 + ; No load %r15 - %r8 + ; No load %rbx - %r9 + ; A[8] x A[5] + mulx rcx, rax, QWORD PTR [r9+64] + adcx rdi, rax + adox rsi, rcx + ; A[9] x A[5] + mulx rcx, rax, QWORD PTR [r9+72] + adcx rsi, rax + adox rbx, rcx + ; No store %r14 + ; No store %r15 + mov r12, QWORD PTR [r8] + mov r10, QWORD PTR [r8+8] + ; A[10] x A[5] + mulx rcx, rax, QWORD PTR [r9+80] + adcx rbx, rax + adox r12, rcx + ; A[11] x A[5] + mulx rcx, rax, QWORD PTR [r9+88] + adcx r12, rax + adox r10, rcx + ; No store %rbx + mov QWORD PTR [r8], r12 + mov r11, QWORD PTR [r8+16] + mov r12, QWORD PTR [r8+24] + ; A[11] x A[6] + mov rdx, QWORD PTR [r9+88] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r10, rax + adox r11, rcx + ; A[11] x A[7] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+8], r10 + mov QWORD PTR [r8+16], r11 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + ; A[11] x A[8] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r12, rax + adox r10, rcx + ; A[11] x A[9] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+24], r12 + mov QWORD PTR [r8+32], r10 + mov r12, QWORD PTR [r8+48] + mov r10, QWORD PTR [r8+56] + ; A[11] x A[10] + mulx rcx, rax, QWORD PTR [r9+80] + adcx r11, rax + adox r12, rcx + ; A[13] x A[9] + mov rdx, QWORD PTR [r9+104] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+40], r11 + mov QWORD PTR [r8+48], r12 + mov r11, QWORD PTR [r8+64] + mov r12, r13 + ; A[13] x A[10] + mulx rcx, rax, QWORD PTR [r9+80] + adcx r10, rax + adox r11, rcx + ; A[13] x A[11] + mulx rcx, rax, QWORD PTR [r9+88] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+56], r10 + mov QWORD PTR [r8+64], r11 + mov r10, r13 + ; A[13] x A[12] + mulx rcx, rax, QWORD PTR [r9+96] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+72], r12 + ; Carry + adcx r10, r14 + mov r14, r13 + adcx r14, r13 + adox r14, r13 + mov QWORD PTR [r8+80], r10 + ; Diagonal 7 + ; No load %r14 - %r8 + ; No load %r15 - %r9 + ; No load %rbx - %r10 + ; A[7] x A[6] + mov rdx, QWORD PTR [r9+48] + mulx rcx, rax, QWORD PTR [r9+56] + adcx rdi, rax + adox rsi, rcx + ; A[8] x A[6] + mulx rcx, rax, QWORD PTR [r9+64] + adcx rsi, rax + adox rbx, rcx + ; No store %r14 + ; No store %r15 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + ; A[9] x A[6] + mulx rcx, rax, QWORD PTR [r9+72] + adcx rbx, rax + adox r10, rcx + ; A[10] x A[6] + mulx rcx, rax, QWORD PTR [r9+80] + adcx r10, rax + adox r11, rcx + ; No store %rbx + mov QWORD PTR [r8], r10 + mov r12, QWORD PTR [r8+16] + mov r10, QWORD PTR [r8+24] + ; A[10] x A[7] + mov rdx, QWORD PTR [r9+80] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r11, rax + adox r12, rcx + ; A[10] x A[8] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+8], r11 + mov QWORD PTR [r8+16], r12 + mov r11, QWORD PTR [r8+32] + mov r12, QWORD PTR [r8+40] + ; A[10] x A[9] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r10, rax + adox r11, rcx + ; A[14] x A[6] + mov rdx, QWORD PTR [r9+112] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+24], r10 + mov QWORD PTR [r8+32], r11 + mov r10, QWORD PTR [r8+48] + mov r11, QWORD PTR [r8+56] + ; A[14] x A[7] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r12, rax + adox r10, rcx + ; A[14] x A[8] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+40], r12 + mov QWORD PTR [r8+48], r10 + mov r12, QWORD PTR [r8+64] + mov r10, QWORD PTR [r8+72] + ; A[14] x A[9] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r11, rax + adox r12, rcx + ; A[14] x A[10] + mulx rcx, rax, QWORD PTR [r9+80] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+56], r11 + mov QWORD PTR [r8+64], r12 + mov r11, QWORD PTR [r8+80] + mov r12, r13 + ; A[14] x A[11] + mulx rcx, rax, QWORD PTR [r9+88] + adcx r10, rax + adox r11, rcx + ; A[14] x A[12] + mulx rcx, rax, QWORD PTR [r9+96] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+72], r10 + mov QWORD PTR [r8+80], r11 + mov r10, r13 + ; A[14] x A[13] + mulx rcx, rax, QWORD PTR [r9+104] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+88], r12 + ; Carry + adcx r10, r14 + mov r14, r13 + adcx r14, r13 + adox r14, r13 + mov QWORD PTR [r8+96], r10 + ; Diagonal 8 + ; No load %rbx - %r8 + mov r11, QWORD PTR [r8] + mov r12, QWORD PTR [r8+8] + ; A[8] x A[7] + mov rdx, QWORD PTR [r9+56] + mulx rcx, rax, QWORD PTR [r9+64] + adcx rbx, rax + adox r11, rcx + ; A[9] x A[7] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r11, rax + adox r12, rcx + ; No store %rbx + mov QWORD PTR [r8], r11 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + ; A[9] x A[8] + mov rdx, QWORD PTR [r9+64] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r12, rax + adox r10, rcx + ; A[15] x A[3] + mov rdx, QWORD PTR [r9+120] + mulx rcx, rax, QWORD PTR [r9+24] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+8], r12 + mov QWORD PTR [r8+16], r10 + mov r12, QWORD PTR [r8+32] + mov r10, QWORD PTR [r8+40] + ; A[15] x A[4] + mulx rcx, rax, QWORD PTR [r9+32] + adcx r11, rax + adox r12, rcx + ; A[15] x A[5] + mulx rcx, rax, QWORD PTR [r9+40] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+24], r11 + mov QWORD PTR [r8+32], r12 + mov r11, QWORD PTR [r8+48] + mov r12, QWORD PTR [r8+56] + ; A[15] x A[6] + mulx rcx, rax, QWORD PTR [r9+48] + adcx r10, rax + adox r11, rcx + ; A[15] x A[7] + mulx rcx, rax, QWORD PTR [r9+56] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+40], r10 + mov QWORD PTR [r8+48], r11 + mov r10, QWORD PTR [r8+64] + mov r11, QWORD PTR [r8+72] + ; A[15] x A[8] + mulx rcx, rax, QWORD PTR [r9+64] + adcx r12, rax + adox r10, rcx + ; A[15] x A[9] + mulx rcx, rax, QWORD PTR [r9+72] + adcx r10, rax + adox r11, rcx + mov QWORD PTR [r8+56], r12 + mov QWORD PTR [r8+64], r10 + mov r12, QWORD PTR [r8+80] + mov r10, QWORD PTR [r8+88] + ; A[15] x A[10] + mulx rcx, rax, QWORD PTR [r9+80] + adcx r11, rax + adox r12, rcx + ; A[15] x A[11] + mulx rcx, rax, QWORD PTR [r9+88] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+72], r11 + mov QWORD PTR [r8+80], r12 + mov r11, QWORD PTR [r8+96] + mov r12, r13 + ; A[15] x A[12] + mulx rcx, rax, QWORD PTR [r9+96] + adcx r10, rax + adox r11, rcx + ; A[15] x A[13] + mulx rcx, rax, QWORD PTR [r9+104] + adcx r11, rax + adox r12, rcx + mov QWORD PTR [r8+88], r10 + mov QWORD PTR [r8+96], r11 + mov r10, r13 + ; A[15] x A[14] + mulx rcx, rax, QWORD PTR [r9+112] + adcx r12, rax + adox r10, rcx + mov QWORD PTR [r8+104], r12 + ; Carry + adcx r10, r14 + mov r14, r13 + adcx r14, r13 + adox r14, r13 + mov QWORD PTR [r8+112], r10 + mov QWORD PTR [r8+120], r14 + ; Double and Add in A[i] x A[i] + mov r11, QWORD PTR [rbp+8] + ; A[0] x A[0] + mov rdx, QWORD PTR [r9] + mulx rcx, rax, rdx + mov QWORD PTR [rbp], rax + adox r11, r11 + adcx r11, rcx + mov QWORD PTR [rbp+8], r11 + mov r10, QWORD PTR [rbp+16] + mov r11, QWORD PTR [rbp+24] + ; A[1] x A[1] + mov rdx, QWORD PTR [r9+8] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [rbp+16], r10 + mov QWORD PTR [rbp+24], r11 + mov r10, QWORD PTR [rbp+32] + mov r11, QWORD PTR [rbp+40] + ; A[2] x A[2] + mov rdx, QWORD PTR [r9+16] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [rbp+32], r10 + mov QWORD PTR [rbp+40], r11 + mov r10, QWORD PTR [rbp+48] + mov r11, QWORD PTR [rbp+56] + ; A[3] x A[3] + mov rdx, QWORD PTR [r9+24] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [rbp+48], r10 + mov QWORD PTR [rbp+56], r11 + mov r10, QWORD PTR [rbp+64] + mov r11, QWORD PTR [rbp+72] + ; A[4] x A[4] + mov rdx, QWORD PTR [r9+32] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [rbp+64], r10 + mov QWORD PTR [rbp+72], r11 + mov r10, QWORD PTR [rbp+80] + mov r11, QWORD PTR [rbp+88] + ; A[5] x A[5] + mov rdx, QWORD PTR [r9+40] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [rbp+80], r10 + mov QWORD PTR [rbp+88], r11 + ; A[6] x A[6] + mov rdx, QWORD PTR [r9+48] + mulx rcx, rax, rdx + adox r15, r15 + adox rdi, rdi + adcx r15, rax + adcx rdi, rcx + ; A[7] x A[7] + mov rdx, QWORD PTR [r9+56] + mulx rcx, rax, rdx + adox rsi, rsi + adox rbx, rbx + adcx rsi, rax + adcx rbx, rcx + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + ; A[8] x A[8] + mov rdx, QWORD PTR [r9+64] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [r8], r10 + mov QWORD PTR [r8+8], r11 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + ; A[9] x A[9] + mov rdx, QWORD PTR [r9+72] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [r8+16], r10 + mov QWORD PTR [r8+24], r11 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + ; A[10] x A[10] + mov rdx, QWORD PTR [r9+80] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [r8+32], r10 + mov QWORD PTR [r8+40], r11 + mov r10, QWORD PTR [r8+48] + mov r11, QWORD PTR [r8+56] + ; A[11] x A[11] + mov rdx, QWORD PTR [r9+88] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [r8+48], r10 + mov QWORD PTR [r8+56], r11 + mov r10, QWORD PTR [r8+64] + mov r11, QWORD PTR [r8+72] + ; A[12] x A[12] + mov rdx, QWORD PTR [r9+96] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [r8+64], r10 + mov QWORD PTR [r8+72], r11 + mov r10, QWORD PTR [r8+80] + mov r11, QWORD PTR [r8+88] + ; A[13] x A[13] + mov rdx, QWORD PTR [r9+104] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [r8+80], r10 + mov QWORD PTR [r8+88], r11 + mov r10, QWORD PTR [r8+96] + mov r11, QWORD PTR [r8+104] + ; A[14] x A[14] + mov rdx, QWORD PTR [r9+112] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [r8+96], r10 + mov QWORD PTR [r8+104], r11 + mov r10, QWORD PTR [r8+112] + mov r11, QWORD PTR [r8+120] + ; A[15] x A[15] + mov rdx, QWORD PTR [r9+120] + mulx rcx, rax, rdx + adox r10, r10 + adox r11, r11 + adcx r10, rax + adcx r11, rcx + mov QWORD PTR [r8+112], r10 + mov QWORD PTR [r8+120], r11 + mov QWORD PTR [r8+-32], r15 + mov QWORD PTR [r8+-24], rdi + mov QWORD PTR [r8+-16], rsi + mov QWORD PTR [r8+-8], rbx + sub r8, 128 + cmp r9, r8 + jne L_end_1024_sqr_avx2_16 + vmovdqu xmm0, OWORD PTR [rbp] + vmovups OWORD PTR [r8], xmm0 + vmovdqu xmm0, OWORD PTR [rbp+16] + vmovups OWORD PTR [r8+16], xmm0 + vmovdqu xmm0, OWORD PTR [rbp+32] + vmovups OWORD PTR [r8+32], xmm0 + vmovdqu xmm0, OWORD PTR [rbp+48] + vmovups OWORD PTR [r8+48], xmm0 + vmovdqu xmm0, OWORD PTR [rbp+64] + vmovups OWORD PTR [r8+64], xmm0 + vmovdqu xmm0, OWORD PTR [rbp+80] + vmovups OWORD PTR [r8+80], xmm0 +L_end_1024_sqr_avx2_16: + add rsp, 128 + pop rbx + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + pop rbp + ret +sp_1024_sqr_avx2_16 ENDP +_text ENDS +ENDIF +; /* Add b to a into r. (r = a + b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_1024_add_16 PROC + ; Add + mov r9, QWORD PTR [rdx] + xor rax, rax + add r9, QWORD PTR [r8] + mov r10, QWORD PTR [rdx+8] + mov QWORD PTR [rcx], r9 + adc r10, QWORD PTR [r8+8] + mov r9, QWORD PTR [rdx+16] + mov QWORD PTR [rcx+8], r10 + adc r9, QWORD PTR [r8+16] + mov r10, QWORD PTR [rdx+24] + mov QWORD PTR [rcx+16], r9 + adc r10, QWORD PTR [r8+24] + mov r9, QWORD PTR [rdx+32] + mov QWORD PTR [rcx+24], r10 + adc r9, QWORD PTR [r8+32] + mov r10, QWORD PTR [rdx+40] + mov QWORD PTR [rcx+32], r9 + adc r10, QWORD PTR [r8+40] + mov r9, QWORD PTR [rdx+48] + mov QWORD PTR [rcx+40], r10 + adc r9, QWORD PTR [r8+48] + mov r10, QWORD PTR [rdx+56] + mov QWORD PTR [rcx+48], r9 + adc r10, QWORD PTR [r8+56] + mov r9, QWORD PTR [rdx+64] + mov QWORD PTR [rcx+56], r10 + adc r9, QWORD PTR [r8+64] + mov r10, QWORD PTR [rdx+72] + mov QWORD PTR [rcx+64], r9 + adc r10, QWORD PTR [r8+72] + mov r9, QWORD PTR [rdx+80] + mov QWORD PTR [rcx+72], r10 + adc r9, QWORD PTR [r8+80] + mov r10, QWORD PTR [rdx+88] + mov QWORD PTR [rcx+80], r9 + adc r10, QWORD PTR [r8+88] + mov r9, QWORD PTR [rdx+96] + mov QWORD PTR [rcx+88], r10 + adc r9, QWORD PTR [r8+96] + mov r10, QWORD PTR [rdx+104] + mov QWORD PTR [rcx+96], r9 + adc r10, QWORD PTR [r8+104] + mov r9, QWORD PTR [rdx+112] + mov QWORD PTR [rcx+104], r10 + adc r9, QWORD PTR [r8+112] + mov r10, QWORD PTR [rdx+120] + mov QWORD PTR [rcx+112], r9 + adc r10, QWORD PTR [r8+120] + mov QWORD PTR [rcx+120], r10 + adc rax, 0 + ret +sp_1024_add_16 ENDP +_text ENDS +; /* Sub b from a into a. (a -= b) +; * +; * a A single precision integer and result. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_1024_sub_in_place_16 PROC + mov r8, QWORD PTR [rcx] + xor rax, rax + sub r8, QWORD PTR [rdx] + mov r9, QWORD PTR [rcx+8] + mov QWORD PTR [rcx], r8 + sbb r9, QWORD PTR [rdx+8] + mov r8, QWORD PTR [rcx+16] + mov QWORD PTR [rcx+8], r9 + sbb r8, QWORD PTR [rdx+16] + mov r9, QWORD PTR [rcx+24] + mov QWORD PTR [rcx+16], r8 + sbb r9, QWORD PTR [rdx+24] + mov r8, QWORD PTR [rcx+32] + mov QWORD PTR [rcx+24], r9 + sbb r8, QWORD PTR [rdx+32] + mov r9, QWORD PTR [rcx+40] + mov QWORD PTR [rcx+32], r8 + sbb r9, QWORD PTR [rdx+40] + mov r8, QWORD PTR [rcx+48] + mov QWORD PTR [rcx+40], r9 + sbb r8, QWORD PTR [rdx+48] + mov r9, QWORD PTR [rcx+56] + mov QWORD PTR [rcx+48], r8 + sbb r9, QWORD PTR [rdx+56] + mov r8, QWORD PTR [rcx+64] + mov QWORD PTR [rcx+56], r9 + sbb r8, QWORD PTR [rdx+64] + mov r9, QWORD PTR [rcx+72] + mov QWORD PTR [rcx+64], r8 + sbb r9, QWORD PTR [rdx+72] + mov r8, QWORD PTR [rcx+80] + mov QWORD PTR [rcx+72], r9 + sbb r8, QWORD PTR [rdx+80] + mov r9, QWORD PTR [rcx+88] + mov QWORD PTR [rcx+80], r8 + sbb r9, QWORD PTR [rdx+88] + mov r8, QWORD PTR [rcx+96] + mov QWORD PTR [rcx+88], r9 + sbb r8, QWORD PTR [rdx+96] + mov r9, QWORD PTR [rcx+104] + mov QWORD PTR [rcx+96], r8 + sbb r9, QWORD PTR [rdx+104] + mov r8, QWORD PTR [rcx+112] + mov QWORD PTR [rcx+104], r9 + sbb r8, QWORD PTR [rdx+112] + mov r9, QWORD PTR [rcx+120] + mov QWORD PTR [rcx+112], r8 + sbb r9, QWORD PTR [rdx+120] + mov QWORD PTR [rcx+120], r9 + sbb rax, 0 + ret +sp_1024_sub_in_place_16 ENDP +_text ENDS +; /* Conditionally subtract b from a using the mask m. +; * m is -1 to subtract and 0 when not copying. +; * +; * r A single precision number representing condition subtract result. +; * a A single precision number to subtract from. +; * b A single precision number to subtract. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_1024_cond_sub_16 PROC + sub rsp, 128 + mov rax, 0 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp], r10 + mov QWORD PTR [rsp+8], r11 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+16], r10 + mov QWORD PTR [rsp+24], r11 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+32], r10 + mov QWORD PTR [rsp+40], r11 + mov r10, QWORD PTR [r8+48] + mov r11, QWORD PTR [r8+56] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+48], r10 + mov QWORD PTR [rsp+56], r11 + mov r10, QWORD PTR [r8+64] + mov r11, QWORD PTR [r8+72] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+64], r10 + mov QWORD PTR [rsp+72], r11 + mov r10, QWORD PTR [r8+80] + mov r11, QWORD PTR [r8+88] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+80], r10 + mov QWORD PTR [rsp+88], r11 + mov r10, QWORD PTR [r8+96] + mov r11, QWORD PTR [r8+104] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+96], r10 + mov QWORD PTR [rsp+104], r11 + mov r10, QWORD PTR [r8+112] + mov r11, QWORD PTR [r8+120] + and r10, r9 + and r11, r9 + mov QWORD PTR [rsp+112], r10 + mov QWORD PTR [rsp+120], r11 + mov r10, QWORD PTR [rdx] + mov r8, QWORD PTR [rsp] + sub r10, r8 + mov r11, QWORD PTR [rdx+8] + mov r8, QWORD PTR [rsp+8] + sbb r11, r8 + mov QWORD PTR [rcx], r10 + mov r10, QWORD PTR [rdx+16] + mov r8, QWORD PTR [rsp+16] + sbb r10, r8 + mov QWORD PTR [rcx+8], r11 + mov r11, QWORD PTR [rdx+24] + mov r8, QWORD PTR [rsp+24] + sbb r11, r8 + mov QWORD PTR [rcx+16], r10 + mov r10, QWORD PTR [rdx+32] + mov r8, QWORD PTR [rsp+32] + sbb r10, r8 + mov QWORD PTR [rcx+24], r11 + mov r11, QWORD PTR [rdx+40] + mov r8, QWORD PTR [rsp+40] + sbb r11, r8 + mov QWORD PTR [rcx+32], r10 + mov r10, QWORD PTR [rdx+48] + mov r8, QWORD PTR [rsp+48] + sbb r10, r8 + mov QWORD PTR [rcx+40], r11 + mov r11, QWORD PTR [rdx+56] + mov r8, QWORD PTR [rsp+56] + sbb r11, r8 + mov QWORD PTR [rcx+48], r10 + mov r10, QWORD PTR [rdx+64] + mov r8, QWORD PTR [rsp+64] + sbb r10, r8 + mov QWORD PTR [rcx+56], r11 + mov r11, QWORD PTR [rdx+72] + mov r8, QWORD PTR [rsp+72] + sbb r11, r8 + mov QWORD PTR [rcx+64], r10 + mov r10, QWORD PTR [rdx+80] + mov r8, QWORD PTR [rsp+80] + sbb r10, r8 + mov QWORD PTR [rcx+72], r11 + mov r11, QWORD PTR [rdx+88] + mov r8, QWORD PTR [rsp+88] + sbb r11, r8 + mov QWORD PTR [rcx+80], r10 + mov r10, QWORD PTR [rdx+96] + mov r8, QWORD PTR [rsp+96] + sbb r10, r8 + mov QWORD PTR [rcx+88], r11 + mov r11, QWORD PTR [rdx+104] + mov r8, QWORD PTR [rsp+104] + sbb r11, r8 + mov QWORD PTR [rcx+96], r10 + mov r10, QWORD PTR [rdx+112] + mov r8, QWORD PTR [rsp+112] + sbb r10, r8 + mov QWORD PTR [rcx+104], r11 + mov r11, QWORD PTR [rdx+120] + mov r8, QWORD PTR [rsp+120] + sbb r11, r8 + mov QWORD PTR [rcx+112], r10 + mov QWORD PTR [rcx+120], r11 + sbb rax, 0 + add rsp, 128 + ret +sp_1024_cond_sub_16 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Conditionally subtract b from a using the mask m. +; * m is -1 to subtract and 0 when not copying. +; * +; * r A single precision number representing condition subtract result. +; * a A single precision number to subtract from. +; * b A single precision number to subtract. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_1024_cond_sub_avx2_16 PROC + push r12 + mov rax, 0 + mov r12, QWORD PTR [r8] + mov r10, QWORD PTR [rdx] + pext r12, r12, r9 + sub r10, r12 + mov r12, QWORD PTR [r8+8] + mov r11, QWORD PTR [rdx+8] + pext r12, r12, r9 + mov QWORD PTR [rcx], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+16] + mov r12, QWORD PTR [rdx+16] + pext r10, r10, r9 + mov QWORD PTR [rcx+8], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+24] + mov r10, QWORD PTR [rdx+24] + pext r11, r11, r9 + mov QWORD PTR [rcx+16], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+32] + mov r11, QWORD PTR [rdx+32] + pext r12, r12, r9 + mov QWORD PTR [rcx+24], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+40] + mov r12, QWORD PTR [rdx+40] + pext r10, r10, r9 + mov QWORD PTR [rcx+32], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+48] + mov r10, QWORD PTR [rdx+48] + pext r11, r11, r9 + mov QWORD PTR [rcx+40], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+56] + mov r11, QWORD PTR [rdx+56] + pext r12, r12, r9 + mov QWORD PTR [rcx+48], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+64] + mov r12, QWORD PTR [rdx+64] + pext r10, r10, r9 + mov QWORD PTR [rcx+56], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+72] + mov r10, QWORD PTR [rdx+72] + pext r11, r11, r9 + mov QWORD PTR [rcx+64], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+80] + mov r11, QWORD PTR [rdx+80] + pext r12, r12, r9 + mov QWORD PTR [rcx+72], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+88] + mov r12, QWORD PTR [rdx+88] + pext r10, r10, r9 + mov QWORD PTR [rcx+80], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+96] + mov r10, QWORD PTR [rdx+96] + pext r11, r11, r9 + mov QWORD PTR [rcx+88], r12 + sbb r10, r11 + mov r12, QWORD PTR [r8+104] + mov r11, QWORD PTR [rdx+104] + pext r12, r12, r9 + mov QWORD PTR [rcx+96], r10 + sbb r11, r12 + mov r10, QWORD PTR [r8+112] + mov r12, QWORD PTR [rdx+112] + pext r10, r10, r9 + mov QWORD PTR [rcx+104], r11 + sbb r12, r10 + mov r11, QWORD PTR [r8+120] + mov r10, QWORD PTR [rdx+120] + pext r11, r11, r9 + mov QWORD PTR [rcx+112], r12 + sbb r10, r11 + mov QWORD PTR [rcx+120], r10 + sbb rax, 0 + pop r12 + ret +sp_1024_cond_sub_avx2_16 ENDP +_text ENDS +ENDIF +; /* Mul a by digit b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision digit. +; */ +_text SEGMENT READONLY PARA +sp_1024_mul_d_16 PROC + push r12 + mov r9, rdx + ; A[0] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9] + mov r10, rax + mov r11, rdx + mov QWORD PTR [rcx], r10 + ; A[1] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+8] + add r11, rax + mov QWORD PTR [rcx+8], r11 + adc r12, rdx + adc r10, 0 + ; A[2] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+16] + add r12, rax + mov QWORD PTR [rcx+16], r12 + adc r10, rdx + adc r11, 0 + ; A[3] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+24] + add r10, rax + mov QWORD PTR [rcx+24], r10 + adc r11, rdx + adc r12, 0 + ; A[4] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+32] + add r11, rax + mov QWORD PTR [rcx+32], r11 + adc r12, rdx + adc r10, 0 + ; A[5] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+40] + add r12, rax + mov QWORD PTR [rcx+40], r12 + adc r10, rdx + adc r11, 0 + ; A[6] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+48] + add r10, rax + mov QWORD PTR [rcx+48], r10 + adc r11, rdx + adc r12, 0 + ; A[7] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+56] + add r11, rax + mov QWORD PTR [rcx+56], r11 + adc r12, rdx + adc r10, 0 + ; A[8] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+64] + add r12, rax + mov QWORD PTR [rcx+64], r12 + adc r10, rdx + adc r11, 0 + ; A[9] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+72] + add r10, rax + mov QWORD PTR [rcx+72], r10 + adc r11, rdx + adc r12, 0 + ; A[10] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+80] + add r11, rax + mov QWORD PTR [rcx+80], r11 + adc r12, rdx + adc r10, 0 + ; A[11] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+88] + add r12, rax + mov QWORD PTR [rcx+88], r12 + adc r10, rdx + adc r11, 0 + ; A[12] * B + mov rax, r8 + xor r12, r12 + mul QWORD PTR [r9+96] + add r10, rax + mov QWORD PTR [rcx+96], r10 + adc r11, rdx + adc r12, 0 + ; A[13] * B + mov rax, r8 + xor r10, r10 + mul QWORD PTR [r9+104] + add r11, rax + mov QWORD PTR [rcx+104], r11 + adc r12, rdx + adc r10, 0 + ; A[14] * B + mov rax, r8 + xor r11, r11 + mul QWORD PTR [r9+112] + add r12, rax + mov QWORD PTR [rcx+112], r12 + adc r10, rdx + adc r11, 0 + ; A[15] * B + mov rax, r8 + mul QWORD PTR [r9+120] + add r10, rax + adc r11, rdx + mov QWORD PTR [rcx+120], r10 + mov QWORD PTR [rcx+128], r11 + pop r12 + ret +sp_1024_mul_d_16 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Mul a by digit b into r. (r = a * b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision digit. +; */ +_text SEGMENT READONLY PARA +sp_1024_mul_d_avx2_16 PROC + push r12 + push r13 + mov rax, rdx + ; A[0] * B + mov rdx, r8 + xor r13, r13 + mulx r12, r11, QWORD PTR [rax] + mov QWORD PTR [rcx], r11 + ; A[1] * B + mulx r10, r9, QWORD PTR [rax+8] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+8], r12 + ; A[2] * B + mulx r10, r9, QWORD PTR [rax+16] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+16], r11 + ; A[3] * B + mulx r10, r9, QWORD PTR [rax+24] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+24], r12 + ; A[4] * B + mulx r10, r9, QWORD PTR [rax+32] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+32], r11 + ; A[5] * B + mulx r10, r9, QWORD PTR [rax+40] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+40], r12 + ; A[6] * B + mulx r10, r9, QWORD PTR [rax+48] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+48], r11 + ; A[7] * B + mulx r10, r9, QWORD PTR [rax+56] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+56], r12 + ; A[8] * B + mulx r10, r9, QWORD PTR [rax+64] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+64], r11 + ; A[9] * B + mulx r10, r9, QWORD PTR [rax+72] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+72], r12 + ; A[10] * B + mulx r10, r9, QWORD PTR [rax+80] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+80], r11 + ; A[11] * B + mulx r10, r9, QWORD PTR [rax+88] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+88], r12 + ; A[12] * B + mulx r10, r9, QWORD PTR [rax+96] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+96], r11 + ; A[13] * B + mulx r10, r9, QWORD PTR [rax+104] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + mov QWORD PTR [rcx+104], r12 + ; A[14] * B + mulx r10, r9, QWORD PTR [rax+112] + mov r12, r13 + adcx r11, r9 + adox r12, r10 + mov QWORD PTR [rcx+112], r11 + ; A[15] * B + mulx r10, r9, QWORD PTR [rax+120] + mov r11, r13 + adcx r12, r9 + adox r11, r10 + adcx r11, r13 + mov QWORD PTR [rcx+120], r12 + mov QWORD PTR [rcx+128], r11 + pop r13 + pop r12 + ret +sp_1024_mul_d_avx2_16 ENDP +_text ENDS +ENDIF +IFDEF _WIN64 +; /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) +; * +; * d1 The high order half of the number to divide. +; * d0 The low order half of the number to divide. +; * div The dividend. +; * returns the result of the division. +; */ +_text SEGMENT READONLY PARA +div_1024_word_asm_16 PROC + mov r9, rdx + mov rax, r9 + mov rdx, rcx + div r8 + ret +div_1024_word_asm_16 ENDP +_text ENDS +ENDIF +; /* Compare a with b in constant time. +; * +; * a A single precision integer. +; * b A single precision integer. +; * return -ve, 0 or +ve if a is less than, equal to or greater than b +; * respectively. +; */ +_text SEGMENT READONLY PARA +sp_1024_cmp_16 PROC + push r12 + xor r9, r9 + mov r8, -1 + mov rax, -1 + mov r10, 1 + mov r11, QWORD PTR [rcx+120] + mov r12, QWORD PTR [rdx+120] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+112] + mov r12, QWORD PTR [rdx+112] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+104] + mov r12, QWORD PTR [rdx+104] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+96] + mov r12, QWORD PTR [rdx+96] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+88] + mov r12, QWORD PTR [rdx+88] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+80] + mov r12, QWORD PTR [rdx+80] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+72] + mov r12, QWORD PTR [rdx+72] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+64] + mov r12, QWORD PTR [rdx+64] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+56] + mov r12, QWORD PTR [rdx+56] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+48] + mov r12, QWORD PTR [rdx+48] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+40] + mov r12, QWORD PTR [rdx+40] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+32] + mov r12, QWORD PTR [rdx+32] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+24] + mov r12, QWORD PTR [rdx+24] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+16] + mov r12, QWORD PTR [rdx+16] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx+8] + mov r12, QWORD PTR [rdx+8] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + mov r11, QWORD PTR [rcx] + mov r12, QWORD PTR [rdx] + and r11, r8 + and r12, r8 + sub r11, r12 + cmova rax, r10 + cmovc rax, r8 + cmovnz r8, r9 + xor rax, r8 + pop r12 + ret +sp_1024_cmp_16 ENDP +_text ENDS +; /* Conditionally copy a into r using the mask m. +; * m is -1 to copy and 0 when not. +; * +; * r A single precision number to copy over. +; * a A single precision number to copy. +; * m Mask value to apply. +; */ +_text SEGMENT READONLY PARA +sp_1024_cond_copy_16 PROC + mov rax, QWORD PTR [rcx] + mov r9, QWORD PTR [rcx+8] + mov r10, QWORD PTR [rcx+16] + mov r11, QWORD PTR [rcx+24] + xor rax, QWORD PTR [rdx] + xor r9, QWORD PTR [rdx+8] + xor r10, QWORD PTR [rdx+16] + xor r11, QWORD PTR [rdx+24] + and rax, r8 + and r9, r8 + and r10, r8 + and r11, r8 + xor QWORD PTR [rcx], rax + xor QWORD PTR [rcx+8], r9 + xor QWORD PTR [rcx+16], r10 + xor QWORD PTR [rcx+24], r11 + mov rax, QWORD PTR [rcx+32] + mov r9, QWORD PTR [rcx+40] + mov r10, QWORD PTR [rcx+48] + mov r11, QWORD PTR [rcx+56] + xor rax, QWORD PTR [rdx+32] + xor r9, QWORD PTR [rdx+40] + xor r10, QWORD PTR [rdx+48] + xor r11, QWORD PTR [rdx+56] + and rax, r8 + and r9, r8 + and r10, r8 + and r11, r8 + xor QWORD PTR [rcx+32], rax + xor QWORD PTR [rcx+40], r9 + xor QWORD PTR [rcx+48], r10 + xor QWORD PTR [rcx+56], r11 + mov rax, QWORD PTR [rcx+64] + mov r9, QWORD PTR [rcx+72] + mov r10, QWORD PTR [rcx+80] + mov r11, QWORD PTR [rcx+88] + xor rax, QWORD PTR [rdx+64] + xor r9, QWORD PTR [rdx+72] + xor r10, QWORD PTR [rdx+80] + xor r11, QWORD PTR [rdx+88] + and rax, r8 + and r9, r8 + and r10, r8 + and r11, r8 + xor QWORD PTR [rcx+64], rax + xor QWORD PTR [rcx+72], r9 + xor QWORD PTR [rcx+80], r10 + xor QWORD PTR [rcx+88], r11 + mov rax, QWORD PTR [rcx+96] + mov r9, QWORD PTR [rcx+104] + mov r10, QWORD PTR [rcx+112] + mov r11, QWORD PTR [rcx+120] + xor rax, QWORD PTR [rdx+96] + xor r9, QWORD PTR [rdx+104] + xor r10, QWORD PTR [rdx+112] + xor r11, QWORD PTR [rdx+120] + and rax, r8 + and r9, r8 + and r10, r8 + and r11, r8 + xor QWORD PTR [rcx+96], rax + xor QWORD PTR [rcx+104], r9 + xor QWORD PTR [rcx+112], r10 + xor QWORD PTR [rcx+120], r11 + ret +sp_1024_cond_copy_16 ENDP +_text ENDS +; /* Reduce the number back to 1024 bits using Montgomery reduction. +; * +; * a A single precision number to reduce in place. +; * m The single precision number representing the modulus. +; * mp The digit representing the negative inverse of m mod 2^n. +; */ +_text SEGMENT READONLY PARA +sp_1024_mont_reduce_16 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + mov r9, rdx + xor rsi, rsi + ; i = 16 + mov r10, 16 + mov r15, QWORD PTR [rcx] + mov rdi, QWORD PTR [rcx+8] +L_1024_mont_loop_16: + ; mu = a[i] * mp + mov r13, r15 + imul r13, r8 + ; a[i+0] += m[0] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9] + add r15, rax + adc r12, rdx + ; a[i+1] += m[1] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+8] + mov r15, rdi + add r15, rax + adc r11, rdx + add r15, r12 + adc r11, 0 + ; a[i+2] += m[2] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+16] + mov rdi, QWORD PTR [rcx+16] + add rdi, rax + adc r12, rdx + add rdi, r11 + adc r12, 0 + ; a[i+3] += m[3] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+24] + mov r14, QWORD PTR [rcx+24] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+24], r14 + adc r11, 0 + ; a[i+4] += m[4] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+32] + mov r14, QWORD PTR [rcx+32] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+32], r14 + adc r12, 0 + ; a[i+5] += m[5] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+40] + mov r14, QWORD PTR [rcx+40] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+40], r14 + adc r11, 0 + ; a[i+6] += m[6] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+48] + mov r14, QWORD PTR [rcx+48] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+48], r14 + adc r12, 0 + ; a[i+7] += m[7] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+56] + mov r14, QWORD PTR [rcx+56] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+56], r14 + adc r11, 0 + ; a[i+8] += m[8] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+64] + mov r14, QWORD PTR [rcx+64] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+64], r14 + adc r12, 0 + ; a[i+9] += m[9] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+72] + mov r14, QWORD PTR [rcx+72] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+72], r14 + adc r11, 0 + ; a[i+10] += m[10] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+80] + mov r14, QWORD PTR [rcx+80] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+80], r14 + adc r12, 0 + ; a[i+11] += m[11] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+88] + mov r14, QWORD PTR [rcx+88] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+88], r14 + adc r11, 0 + ; a[i+12] += m[12] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+96] + mov r14, QWORD PTR [rcx+96] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+96], r14 + adc r12, 0 + ; a[i+13] += m[13] * mu + mov rax, r13 + xor r11, r11 + mul QWORD PTR [r9+104] + mov r14, QWORD PTR [rcx+104] + add r14, rax + adc r11, rdx + add r14, r12 + mov QWORD PTR [rcx+104], r14 + adc r11, 0 + ; a[i+14] += m[14] * mu + mov rax, r13 + xor r12, r12 + mul QWORD PTR [r9+112] + mov r14, QWORD PTR [rcx+112] + add r14, rax + adc r12, rdx + add r14, r11 + mov QWORD PTR [rcx+112], r14 + adc r12, 0 + ; a[i+15] += m[15] * mu + mov rax, r13 + mul QWORD PTR [r9+120] + mov r14, QWORD PTR [rcx+120] + add r12, rax + adc rdx, rsi + mov rsi, 0 + adc rsi, 0 + add r14, r12 + mov QWORD PTR [rcx+120], r14 + adc QWORD PTR [rcx+128], rdx + adc rsi, 0 + ; i -= 1 + add rcx, 8 + dec r10 + jnz L_1024_mont_loop_16 + mov r14, QWORD PTR [rcx+120] + mov QWORD PTR [rcx], r15 + sub r14, QWORD PTR [r9+120] + mov QWORD PTR [rcx+8], rdi + sbb r14, r14 + neg rsi + not r14 + or rsi, r14 +IFDEF _WIN64 + mov r8, r9 + mov r9, rsi +ELSE + mov r9, rsi + mov r8, r9 +ENDIF + mov rdx, rcx + mov rcx, rcx + sub rcx, 128 + call sp_1024_cond_sub_16 + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_1024_mont_reduce_16 ENDP +_text ENDS +; /* Add two Montgomery form numbers (r = a + b % m). +; * +; * r Result of addition. +; * a First number to add in Montogmery form. +; * b Second number to add in Montogmery form. +; * m Modulus (prime). +; */ +_text SEGMENT READONLY PARA +sp_1024_mont_add_16 PROC + push r12 + push r13 + sub rsp, 128 + mov rax, QWORD PTR [rdx] + mov r10, QWORD PTR [rdx+8] + mov r11, QWORD PTR [rdx+16] + mov r12, QWORD PTR [rdx+24] + add rax, QWORD PTR [r8] + mov r13, 0 + adc r10, QWORD PTR [r8+8] + adc r11, QWORD PTR [r8+16] + adc r12, QWORD PTR [r8+24] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r10 + mov QWORD PTR [rcx+16], r11 + mov QWORD PTR [rcx+24], r12 + mov rax, QWORD PTR [rdx+32] + mov r10, QWORD PTR [rdx+40] + mov r11, QWORD PTR [rdx+48] + mov r12, QWORD PTR [rdx+56] + adc rax, QWORD PTR [r8+32] + adc r10, QWORD PTR [r8+40] + adc r11, QWORD PTR [r8+48] + adc r12, QWORD PTR [r8+56] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r10 + mov QWORD PTR [rcx+48], r11 + mov QWORD PTR [rcx+56], r12 + mov rax, QWORD PTR [rdx+64] + mov r10, QWORD PTR [rdx+72] + mov r11, QWORD PTR [rdx+80] + mov r12, QWORD PTR [rdx+88] + adc rax, QWORD PTR [r8+64] + adc r10, QWORD PTR [r8+72] + adc r11, QWORD PTR [r8+80] + adc r12, QWORD PTR [r8+88] + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], r10 + mov QWORD PTR [rcx+80], r11 + mov QWORD PTR [rcx+88], r12 + mov rax, QWORD PTR [rdx+96] + mov r10, QWORD PTR [rdx+104] + mov r11, QWORD PTR [rdx+112] + mov r12, QWORD PTR [rdx+120] + adc rax, QWORD PTR [r8+96] + adc r10, QWORD PTR [r8+104] + adc r11, QWORD PTR [r8+112] + adc r12, QWORD PTR [r8+120] + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], r10 + mov QWORD PTR [rcx+112], r11 + mov QWORD PTR [rcx+120], r12 + sbb r13, 0 + sub r12, QWORD PTR [r9+120] + sbb r12, r12 + not r12 + or r13, r12 + mov r11, QWORD PTR [r9] + mov r12, QWORD PTR [r9+8] + and r11, r13 + and r12, r13 + mov QWORD PTR [rsp], r11 + mov QWORD PTR [rsp+8], r12 + mov r11, QWORD PTR [r9+16] + mov r12, QWORD PTR [r9+24] + and r11, r13 + and r12, r13 + mov QWORD PTR [rsp+16], r11 + mov QWORD PTR [rsp+24], r12 + mov r11, QWORD PTR [r9+32] + mov r12, QWORD PTR [r9+40] + and r11, r13 + and r12, r13 + mov QWORD PTR [rsp+32], r11 + mov QWORD PTR [rsp+40], r12 + mov r11, QWORD PTR [r9+48] + mov r12, QWORD PTR [r9+56] + and r11, r13 + and r12, r13 + mov QWORD PTR [rsp+48], r11 + mov QWORD PTR [rsp+56], r12 + mov r11, QWORD PTR [r9+64] + mov r12, QWORD PTR [r9+72] + and r11, r13 + and r12, r13 + mov QWORD PTR [rsp+64], r11 + mov QWORD PTR [rsp+72], r12 + mov r11, QWORD PTR [r9+80] + mov r12, QWORD PTR [r9+88] + and r11, r13 + and r12, r13 + mov QWORD PTR [rsp+80], r11 + mov QWORD PTR [rsp+88], r12 + mov r11, QWORD PTR [r9+96] + mov r12, QWORD PTR [r9+104] + and r11, r13 + and r12, r13 + mov QWORD PTR [rsp+96], r11 + mov QWORD PTR [rsp+104], r12 + mov r11, QWORD PTR [r9+112] + mov r12, QWORD PTR [r9+120] + and r11, r13 + and r12, r13 + mov QWORD PTR [rsp+112], r11 + mov QWORD PTR [rsp+120], r12 + mov rax, QWORD PTR [rcx] + mov r10, QWORD PTR [rcx+8] + sub rax, QWORD PTR [rsp] + sbb r10, QWORD PTR [rsp+8] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r10 + mov rax, QWORD PTR [rcx+16] + mov r10, QWORD PTR [rcx+24] + sbb rax, QWORD PTR [rsp+16] + sbb r10, QWORD PTR [rsp+24] + mov QWORD PTR [rcx+16], rax + mov QWORD PTR [rcx+24], r10 + mov rax, QWORD PTR [rcx+32] + mov r10, QWORD PTR [rcx+40] + sbb rax, QWORD PTR [rsp+32] + sbb r10, QWORD PTR [rsp+40] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r10 + mov rax, QWORD PTR [rcx+48] + mov r10, QWORD PTR [rcx+56] + sbb rax, QWORD PTR [rsp+48] + sbb r10, QWORD PTR [rsp+56] + mov QWORD PTR [rcx+48], rax + mov QWORD PTR [rcx+56], r10 + mov rax, QWORD PTR [rcx+64] + mov r10, QWORD PTR [rcx+72] + sbb rax, QWORD PTR [rsp+64] + sbb r10, QWORD PTR [rsp+72] + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], r10 + mov rax, QWORD PTR [rcx+80] + mov r10, QWORD PTR [rcx+88] + sbb rax, QWORD PTR [rsp+80] + sbb r10, QWORD PTR [rsp+88] + mov QWORD PTR [rcx+80], rax + mov QWORD PTR [rcx+88], r10 + mov rax, QWORD PTR [rcx+96] + mov r10, QWORD PTR [rcx+104] + sbb rax, QWORD PTR [rsp+96] + sbb r10, QWORD PTR [rsp+104] + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], r10 + mov rax, QWORD PTR [rcx+112] + mov r10, QWORD PTR [rcx+120] + sbb rax, QWORD PTR [rsp+112] + sbb r10, QWORD PTR [rsp+120] + mov QWORD PTR [rcx+112], rax + mov QWORD PTR [rcx+120], r10 + add rsp, 128 + pop r13 + pop r12 + ret +sp_1024_mont_add_16 ENDP +_text ENDS +; /* Double a Montgomery form number (r = a + a % m). +; * +; * r Result of addition. +; * a Number to souble in Montogmery form. +; * m Modulus (prime). +; */ +_text SEGMENT READONLY PARA +sp_1024_mont_dbl_16 PROC + push r12 + sub rsp, 128 + mov rax, QWORD PTR [rdx] + mov r9, QWORD PTR [rdx+8] + mov r10, QWORD PTR [rdx+16] + mov r11, QWORD PTR [rdx+24] + add rax, QWORD PTR [rdx] + mov r12, 0 + adc r9, QWORD PTR [rdx+8] + adc r10, QWORD PTR [rdx+16] + adc r11, QWORD PTR [rdx+24] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r9 + mov QWORD PTR [rcx+16], r10 + mov QWORD PTR [rcx+24], r11 + mov rax, QWORD PTR [rdx+32] + mov r9, QWORD PTR [rdx+40] + mov r10, QWORD PTR [rdx+48] + mov r11, QWORD PTR [rdx+56] + adc rax, QWORD PTR [rdx+32] + adc r9, QWORD PTR [rdx+40] + adc r10, QWORD PTR [rdx+48] + adc r11, QWORD PTR [rdx+56] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r9 + mov QWORD PTR [rcx+48], r10 + mov QWORD PTR [rcx+56], r11 + mov rax, QWORD PTR [rdx+64] + mov r9, QWORD PTR [rdx+72] + mov r10, QWORD PTR [rdx+80] + mov r11, QWORD PTR [rdx+88] + adc rax, QWORD PTR [rdx+64] + adc r9, QWORD PTR [rdx+72] + adc r10, QWORD PTR [rdx+80] + adc r11, QWORD PTR [rdx+88] + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], r9 + mov QWORD PTR [rcx+80], r10 + mov QWORD PTR [rcx+88], r11 + mov rax, QWORD PTR [rdx+96] + mov r9, QWORD PTR [rdx+104] + mov r10, QWORD PTR [rdx+112] + mov r11, QWORD PTR [rdx+120] + adc rax, QWORD PTR [rdx+96] + adc r9, QWORD PTR [rdx+104] + adc r10, QWORD PTR [rdx+112] + adc r11, QWORD PTR [rdx+120] + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], r9 + mov QWORD PTR [rcx+112], r10 + mov QWORD PTR [rcx+120], r11 + sbb r12, 0 + sub r11, QWORD PTR [r8+120] + sbb r11, r11 + not r11 + or r12, r11 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp], r10 + mov QWORD PTR [rsp+8], r11 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp+16], r10 + mov QWORD PTR [rsp+24], r11 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp+32], r10 + mov QWORD PTR [rsp+40], r11 + mov r10, QWORD PTR [r8+48] + mov r11, QWORD PTR [r8+56] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp+48], r10 + mov QWORD PTR [rsp+56], r11 + mov r10, QWORD PTR [r8+64] + mov r11, QWORD PTR [r8+72] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp+64], r10 + mov QWORD PTR [rsp+72], r11 + mov r10, QWORD PTR [r8+80] + mov r11, QWORD PTR [r8+88] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp+80], r10 + mov QWORD PTR [rsp+88], r11 + mov r10, QWORD PTR [r8+96] + mov r11, QWORD PTR [r8+104] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp+96], r10 + mov QWORD PTR [rsp+104], r11 + mov r10, QWORD PTR [r8+112] + mov r11, QWORD PTR [r8+120] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp+112], r10 + mov QWORD PTR [rsp+120], r11 + mov rax, QWORD PTR [rcx] + mov r9, QWORD PTR [rcx+8] + sub rax, QWORD PTR [rsp] + sbb r9, QWORD PTR [rsp+8] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r9 + mov rax, QWORD PTR [rcx+16] + mov r9, QWORD PTR [rcx+24] + sbb rax, QWORD PTR [rsp+16] + sbb r9, QWORD PTR [rsp+24] + mov QWORD PTR [rcx+16], rax + mov QWORD PTR [rcx+24], r9 + mov rax, QWORD PTR [rcx+32] + mov r9, QWORD PTR [rcx+40] + sbb rax, QWORD PTR [rsp+32] + sbb r9, QWORD PTR [rsp+40] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r9 + mov rax, QWORD PTR [rcx+48] + mov r9, QWORD PTR [rcx+56] + sbb rax, QWORD PTR [rsp+48] + sbb r9, QWORD PTR [rsp+56] + mov QWORD PTR [rcx+48], rax + mov QWORD PTR [rcx+56], r9 + mov rax, QWORD PTR [rcx+64] + mov r9, QWORD PTR [rcx+72] + sbb rax, QWORD PTR [rsp+64] + sbb r9, QWORD PTR [rsp+72] + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], r9 + mov rax, QWORD PTR [rcx+80] + mov r9, QWORD PTR [rcx+88] + sbb rax, QWORD PTR [rsp+80] + sbb r9, QWORD PTR [rsp+88] + mov QWORD PTR [rcx+80], rax + mov QWORD PTR [rcx+88], r9 + mov rax, QWORD PTR [rcx+96] + mov r9, QWORD PTR [rcx+104] + sbb rax, QWORD PTR [rsp+96] + sbb r9, QWORD PTR [rsp+104] + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], r9 + mov rax, QWORD PTR [rcx+112] + mov r9, QWORD PTR [rcx+120] + sbb rax, QWORD PTR [rsp+112] + sbb r9, QWORD PTR [rsp+120] + mov QWORD PTR [rcx+112], rax + mov QWORD PTR [rcx+120], r9 + add rsp, 128 + pop r12 + ret +sp_1024_mont_dbl_16 ENDP +_text ENDS +; /* Triple a Montgomery form number (r = a + a + a % m). +; * +; * r Result of addition. +; * a Number to souble in Montogmery form. +; * m Modulus (prime). +; */ +_text SEGMENT READONLY PARA +sp_1024_mont_tpl_16 PROC + push r12 + sub rsp, 128 + mov rax, QWORD PTR [rdx] + mov r9, QWORD PTR [rdx+8] + mov r10, QWORD PTR [rdx+16] + mov r11, QWORD PTR [rdx+24] + add rax, QWORD PTR [rdx] + mov r12, 0 + adc r9, QWORD PTR [rdx+8] + adc r10, QWORD PTR [rdx+16] + adc r11, QWORD PTR [rdx+24] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r9 + mov QWORD PTR [rcx+16], r10 + mov QWORD PTR [rcx+24], r11 + mov rax, QWORD PTR [rdx+32] + mov r9, QWORD PTR [rdx+40] + mov r10, QWORD PTR [rdx+48] + mov r11, QWORD PTR [rdx+56] + adc rax, QWORD PTR [rdx+32] + adc r9, QWORD PTR [rdx+40] + adc r10, QWORD PTR [rdx+48] + adc r11, QWORD PTR [rdx+56] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r9 + mov QWORD PTR [rcx+48], r10 + mov QWORD PTR [rcx+56], r11 + mov rax, QWORD PTR [rdx+64] + mov r9, QWORD PTR [rdx+72] + mov r10, QWORD PTR [rdx+80] + mov r11, QWORD PTR [rdx+88] + adc rax, QWORD PTR [rdx+64] + adc r9, QWORD PTR [rdx+72] + adc r10, QWORD PTR [rdx+80] + adc r11, QWORD PTR [rdx+88] + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], r9 + mov QWORD PTR [rcx+80], r10 + mov QWORD PTR [rcx+88], r11 + mov rax, QWORD PTR [rdx+96] + mov r9, QWORD PTR [rdx+104] + mov r10, QWORD PTR [rdx+112] + mov r11, QWORD PTR [rdx+120] + adc rax, QWORD PTR [rdx+96] + adc r9, QWORD PTR [rdx+104] + adc r10, QWORD PTR [rdx+112] + adc r11, QWORD PTR [rdx+120] + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], r9 + mov QWORD PTR [rcx+112], r10 + mov QWORD PTR [rcx+120], r11 + sbb r12, 0 + sub r11, QWORD PTR [r8+120] + sbb r11, r11 + not r11 + or r12, r11 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp], r10 + mov QWORD PTR [rsp+8], r11 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp+16], r10 + mov QWORD PTR [rsp+24], r11 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp+32], r10 + mov QWORD PTR [rsp+40], r11 + mov r10, QWORD PTR [r8+48] + mov r11, QWORD PTR [r8+56] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp+48], r10 + mov QWORD PTR [rsp+56], r11 + mov r10, QWORD PTR [r8+64] + mov r11, QWORD PTR [r8+72] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp+64], r10 + mov QWORD PTR [rsp+72], r11 + mov r10, QWORD PTR [r8+80] + mov r11, QWORD PTR [r8+88] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp+80], r10 + mov QWORD PTR [rsp+88], r11 + mov r10, QWORD PTR [r8+96] + mov r11, QWORD PTR [r8+104] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp+96], r10 + mov QWORD PTR [rsp+104], r11 + mov r10, QWORD PTR [r8+112] + mov r11, QWORD PTR [r8+120] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp+112], r10 + mov QWORD PTR [rsp+120], r11 + mov rax, QWORD PTR [rcx] + mov r9, QWORD PTR [rcx+8] + sub rax, QWORD PTR [rsp] + sbb r9, QWORD PTR [rsp+8] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r9 + mov rax, QWORD PTR [rcx+16] + mov r9, QWORD PTR [rcx+24] + sbb rax, QWORD PTR [rsp+16] + sbb r9, QWORD PTR [rsp+24] + mov QWORD PTR [rcx+16], rax + mov QWORD PTR [rcx+24], r9 + mov rax, QWORD PTR [rcx+32] + mov r9, QWORD PTR [rcx+40] + sbb rax, QWORD PTR [rsp+32] + sbb r9, QWORD PTR [rsp+40] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r9 + mov rax, QWORD PTR [rcx+48] + mov r9, QWORD PTR [rcx+56] + sbb rax, QWORD PTR [rsp+48] + sbb r9, QWORD PTR [rsp+56] + mov QWORD PTR [rcx+48], rax + mov QWORD PTR [rcx+56], r9 + mov rax, QWORD PTR [rcx+64] + mov r9, QWORD PTR [rcx+72] + sbb rax, QWORD PTR [rsp+64] + sbb r9, QWORD PTR [rsp+72] + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], r9 + mov rax, QWORD PTR [rcx+80] + mov r9, QWORD PTR [rcx+88] + sbb rax, QWORD PTR [rsp+80] + sbb r9, QWORD PTR [rsp+88] + mov QWORD PTR [rcx+80], rax + mov QWORD PTR [rcx+88], r9 + mov rax, QWORD PTR [rcx+96] + mov r9, QWORD PTR [rcx+104] + sbb rax, QWORD PTR [rsp+96] + sbb r9, QWORD PTR [rsp+104] + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], r9 + mov rax, QWORD PTR [rcx+112] + mov r9, QWORD PTR [rcx+120] + sbb rax, QWORD PTR [rsp+112] + sbb r9, QWORD PTR [rsp+120] + mov QWORD PTR [rcx+112], rax + mov QWORD PTR [rcx+120], r9 + mov rax, QWORD PTR [rcx] + mov r9, QWORD PTR [rcx+8] + mov r10, QWORD PTR [rcx+16] + mov r11, QWORD PTR [rcx+24] + add rax, QWORD PTR [rdx] + mov r12, 0 + adc r9, QWORD PTR [rdx+8] + adc r10, QWORD PTR [rdx+16] + adc r11, QWORD PTR [rdx+24] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r9 + mov QWORD PTR [rcx+16], r10 + mov QWORD PTR [rcx+24], r11 + mov rax, QWORD PTR [rcx+32] + mov r9, QWORD PTR [rcx+40] + mov r10, QWORD PTR [rcx+48] + mov r11, QWORD PTR [rcx+56] + adc rax, QWORD PTR [rdx+32] + adc r9, QWORD PTR [rdx+40] + adc r10, QWORD PTR [rdx+48] + adc r11, QWORD PTR [rdx+56] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r9 + mov QWORD PTR [rcx+48], r10 + mov QWORD PTR [rcx+56], r11 + mov rax, QWORD PTR [rcx+64] + mov r9, QWORD PTR [rcx+72] + mov r10, QWORD PTR [rcx+80] + mov r11, QWORD PTR [rcx+88] + adc rax, QWORD PTR [rdx+64] + adc r9, QWORD PTR [rdx+72] + adc r10, QWORD PTR [rdx+80] + adc r11, QWORD PTR [rdx+88] + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], r9 + mov QWORD PTR [rcx+80], r10 + mov QWORD PTR [rcx+88], r11 + mov rax, QWORD PTR [rcx+96] + mov r9, QWORD PTR [rcx+104] + mov r10, QWORD PTR [rcx+112] + mov r11, QWORD PTR [rcx+120] + adc rax, QWORD PTR [rdx+96] + adc r9, QWORD PTR [rdx+104] + adc r10, QWORD PTR [rdx+112] + adc r11, QWORD PTR [rdx+120] + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], r9 + mov QWORD PTR [rcx+112], r10 + mov QWORD PTR [rcx+120], r11 + sbb r12, 0 + sub r11, QWORD PTR [r8+120] + sbb r11, r11 + not r11 + or r12, r11 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp], r10 + mov QWORD PTR [rsp+8], r11 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp+16], r10 + mov QWORD PTR [rsp+24], r11 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp+32], r10 + mov QWORD PTR [rsp+40], r11 + mov r10, QWORD PTR [r8+48] + mov r11, QWORD PTR [r8+56] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp+48], r10 + mov QWORD PTR [rsp+56], r11 + mov r10, QWORD PTR [r8+64] + mov r11, QWORD PTR [r8+72] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp+64], r10 + mov QWORD PTR [rsp+72], r11 + mov r10, QWORD PTR [r8+80] + mov r11, QWORD PTR [r8+88] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp+80], r10 + mov QWORD PTR [rsp+88], r11 + mov r10, QWORD PTR [r8+96] + mov r11, QWORD PTR [r8+104] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp+96], r10 + mov QWORD PTR [rsp+104], r11 + mov r10, QWORD PTR [r8+112] + mov r11, QWORD PTR [r8+120] + and r10, r12 + and r11, r12 + mov QWORD PTR [rsp+112], r10 + mov QWORD PTR [rsp+120], r11 + mov rax, QWORD PTR [rcx] + mov r9, QWORD PTR [rcx+8] + sub rax, QWORD PTR [rsp] + sbb r9, QWORD PTR [rsp+8] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r9 + mov rax, QWORD PTR [rcx+16] + mov r9, QWORD PTR [rcx+24] + sbb rax, QWORD PTR [rsp+16] + sbb r9, QWORD PTR [rsp+24] + mov QWORD PTR [rcx+16], rax + mov QWORD PTR [rcx+24], r9 + mov rax, QWORD PTR [rcx+32] + mov r9, QWORD PTR [rcx+40] + sbb rax, QWORD PTR [rsp+32] + sbb r9, QWORD PTR [rsp+40] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r9 + mov rax, QWORD PTR [rcx+48] + mov r9, QWORD PTR [rcx+56] + sbb rax, QWORD PTR [rsp+48] + sbb r9, QWORD PTR [rsp+56] + mov QWORD PTR [rcx+48], rax + mov QWORD PTR [rcx+56], r9 + mov rax, QWORD PTR [rcx+64] + mov r9, QWORD PTR [rcx+72] + sbb rax, QWORD PTR [rsp+64] + sbb r9, QWORD PTR [rsp+72] + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], r9 + mov rax, QWORD PTR [rcx+80] + mov r9, QWORD PTR [rcx+88] + sbb rax, QWORD PTR [rsp+80] + sbb r9, QWORD PTR [rsp+88] + mov QWORD PTR [rcx+80], rax + mov QWORD PTR [rcx+88], r9 + mov rax, QWORD PTR [rcx+96] + mov r9, QWORD PTR [rcx+104] + sbb rax, QWORD PTR [rsp+96] + sbb r9, QWORD PTR [rsp+104] + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], r9 + mov rax, QWORD PTR [rcx+112] + mov r9, QWORD PTR [rcx+120] + sbb rax, QWORD PTR [rsp+112] + sbb r9, QWORD PTR [rsp+120] + mov QWORD PTR [rcx+112], rax + mov QWORD PTR [rcx+120], r9 + add rsp, 128 + pop r12 + ret +sp_1024_mont_tpl_16 ENDP +_text ENDS +; /* Subtract two Montgomery form numbers (r = a - b % m). +; * +; * r Result of addition. +; * a First number to add in Montogmery form. +; * b Second number to add in Montogmery form. +; * m Modulus (prime). +; */ +_text SEGMENT READONLY PARA +sp_1024_mont_sub_16 PROC + push r12 + push r13 + sub rsp, 128 + mov rax, QWORD PTR [rdx] + mov r10, QWORD PTR [rdx+8] + mov r11, QWORD PTR [rdx+16] + mov r12, QWORD PTR [rdx+24] + sub rax, QWORD PTR [r8] + mov r13, 0 + sbb r10, QWORD PTR [r8+8] + sbb r11, QWORD PTR [r8+16] + sbb r12, QWORD PTR [r8+24] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r10 + mov QWORD PTR [rcx+16], r11 + mov QWORD PTR [rcx+24], r12 + mov rax, QWORD PTR [rdx+32] + mov r10, QWORD PTR [rdx+40] + mov r11, QWORD PTR [rdx+48] + mov r12, QWORD PTR [rdx+56] + sbb rax, QWORD PTR [r8+32] + sbb r10, QWORD PTR [r8+40] + sbb r11, QWORD PTR [r8+48] + sbb r12, QWORD PTR [r8+56] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r10 + mov QWORD PTR [rcx+48], r11 + mov QWORD PTR [rcx+56], r12 + mov rax, QWORD PTR [rdx+64] + mov r10, QWORD PTR [rdx+72] + mov r11, QWORD PTR [rdx+80] + mov r12, QWORD PTR [rdx+88] + sbb rax, QWORD PTR [r8+64] + sbb r10, QWORD PTR [r8+72] + sbb r11, QWORD PTR [r8+80] + sbb r12, QWORD PTR [r8+88] + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], r10 + mov QWORD PTR [rcx+80], r11 + mov QWORD PTR [rcx+88], r12 + mov rax, QWORD PTR [rdx+96] + mov r10, QWORD PTR [rdx+104] + mov r11, QWORD PTR [rdx+112] + mov r12, QWORD PTR [rdx+120] + sbb rax, QWORD PTR [r8+96] + sbb r10, QWORD PTR [r8+104] + sbb r11, QWORD PTR [r8+112] + sbb r12, QWORD PTR [r8+120] + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], r10 + mov QWORD PTR [rcx+112], r11 + mov QWORD PTR [rcx+120], r12 + sbb r13, 0 + mov r11, QWORD PTR [r9] + mov r12, QWORD PTR [r9+8] + and r11, r13 + and r12, r13 + mov QWORD PTR [rsp], r11 + mov QWORD PTR [rsp+8], r12 + mov r11, QWORD PTR [r9+16] + mov r12, QWORD PTR [r9+24] + and r11, r13 + and r12, r13 + mov QWORD PTR [rsp+16], r11 + mov QWORD PTR [rsp+24], r12 + mov r11, QWORD PTR [r9+32] + mov r12, QWORD PTR [r9+40] + and r11, r13 + and r12, r13 + mov QWORD PTR [rsp+32], r11 + mov QWORD PTR [rsp+40], r12 + mov r11, QWORD PTR [r9+48] + mov r12, QWORD PTR [r9+56] + and r11, r13 + and r12, r13 + mov QWORD PTR [rsp+48], r11 + mov QWORD PTR [rsp+56], r12 + mov r11, QWORD PTR [r9+64] + mov r12, QWORD PTR [r9+72] + and r11, r13 + and r12, r13 + mov QWORD PTR [rsp+64], r11 + mov QWORD PTR [rsp+72], r12 + mov r11, QWORD PTR [r9+80] + mov r12, QWORD PTR [r9+88] + and r11, r13 + and r12, r13 + mov QWORD PTR [rsp+80], r11 + mov QWORD PTR [rsp+88], r12 + mov r11, QWORD PTR [r9+96] + mov r12, QWORD PTR [r9+104] + and r11, r13 + and r12, r13 + mov QWORD PTR [rsp+96], r11 + mov QWORD PTR [rsp+104], r12 + mov r11, QWORD PTR [r9+112] + mov r12, QWORD PTR [r9+120] + and r11, r13 + and r12, r13 + mov QWORD PTR [rsp+112], r11 + mov QWORD PTR [rsp+120], r12 + mov rax, QWORD PTR [rcx] + mov r10, QWORD PTR [rcx+8] + add rax, QWORD PTR [rsp] + adc r10, QWORD PTR [rsp+8] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r10 + mov rax, QWORD PTR [rcx+16] + mov r10, QWORD PTR [rcx+24] + adc rax, QWORD PTR [rsp+16] + adc r10, QWORD PTR [rsp+24] + mov QWORD PTR [rcx+16], rax + mov QWORD PTR [rcx+24], r10 + mov rax, QWORD PTR [rcx+32] + mov r10, QWORD PTR [rcx+40] + adc rax, QWORD PTR [rsp+32] + adc r10, QWORD PTR [rsp+40] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r10 + mov rax, QWORD PTR [rcx+48] + mov r10, QWORD PTR [rcx+56] + adc rax, QWORD PTR [rsp+48] + adc r10, QWORD PTR [rsp+56] + mov QWORD PTR [rcx+48], rax + mov QWORD PTR [rcx+56], r10 + mov rax, QWORD PTR [rcx+64] + mov r10, QWORD PTR [rcx+72] + adc rax, QWORD PTR [rsp+64] + adc r10, QWORD PTR [rsp+72] + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], r10 + mov rax, QWORD PTR [rcx+80] + mov r10, QWORD PTR [rcx+88] + adc rax, QWORD PTR [rsp+80] + adc r10, QWORD PTR [rsp+88] + mov QWORD PTR [rcx+80], rax + mov QWORD PTR [rcx+88], r10 + mov rax, QWORD PTR [rcx+96] + mov r10, QWORD PTR [rcx+104] + adc rax, QWORD PTR [rsp+96] + adc r10, QWORD PTR [rsp+104] + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], r10 + mov rax, QWORD PTR [rcx+112] + mov r10, QWORD PTR [rcx+120] + adc rax, QWORD PTR [rsp+112] + adc r10, QWORD PTR [rsp+120] + mov QWORD PTR [rcx+112], rax + mov QWORD PTR [rcx+120], r10 + add rsp, 128 + pop r13 + pop r12 + ret +sp_1024_mont_sub_16 ENDP +_text ENDS +; /* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m) +; * +; * r Result of division by 2. +; * a Number to divide. +; * m Modulus (prime). +; */ +_text SEGMENT READONLY PARA +sp_1024_div2_16 PROC + push r12 + push r13 + sub rsp, 128 + mov r13, QWORD PTR [rdx] + xor r12, r12 + mov rax, r13 + and r13, 1 + neg r13 + mov r10, QWORD PTR [r8] + and r10, r13 + mov QWORD PTR [rsp], r10 + mov r10, QWORD PTR [r8+8] + and r10, r13 + mov QWORD PTR [rsp+8], r10 + mov r10, QWORD PTR [r8+16] + and r10, r13 + mov QWORD PTR [rsp+16], r10 + mov r10, QWORD PTR [r8+24] + and r10, r13 + mov QWORD PTR [rsp+24], r10 + mov r10, QWORD PTR [r8+32] + and r10, r13 + mov QWORD PTR [rsp+32], r10 + mov r10, QWORD PTR [r8+40] + and r10, r13 + mov QWORD PTR [rsp+40], r10 + mov r10, QWORD PTR [r8+48] + and r10, r13 + mov QWORD PTR [rsp+48], r10 + mov r10, QWORD PTR [r8+56] + and r10, r13 + mov QWORD PTR [rsp+56], r10 + mov r10, QWORD PTR [r8+64] + and r10, r13 + mov QWORD PTR [rsp+64], r10 + mov r10, QWORD PTR [r8+72] + and r10, r13 + mov QWORD PTR [rsp+72], r10 + mov r10, QWORD PTR [r8+80] + and r10, r13 + mov QWORD PTR [rsp+80], r10 + mov r10, QWORD PTR [r8+88] + and r10, r13 + mov QWORD PTR [rsp+88], r10 + mov r10, QWORD PTR [r8+96] + and r10, r13 + mov QWORD PTR [rsp+96], r10 + mov r10, QWORD PTR [r8+104] + and r10, r13 + mov QWORD PTR [rsp+104], r10 + mov r10, QWORD PTR [r8+112] + and r10, r13 + mov QWORD PTR [rsp+112], r10 + mov r10, QWORD PTR [r8+120] + and r10, r13 + mov QWORD PTR [rsp+120], r10 + add QWORD PTR [rsp], rax + mov rax, QWORD PTR [rdx+8] + adc QWORD PTR [rsp+8], rax + mov rax, QWORD PTR [rdx+16] + adc QWORD PTR [rsp+16], rax + mov rax, QWORD PTR [rdx+24] + adc QWORD PTR [rsp+24], rax + mov rax, QWORD PTR [rdx+32] + adc QWORD PTR [rsp+32], rax + mov rax, QWORD PTR [rdx+40] + adc QWORD PTR [rsp+40], rax + mov rax, QWORD PTR [rdx+48] + adc QWORD PTR [rsp+48], rax + mov rax, QWORD PTR [rdx+56] + adc QWORD PTR [rsp+56], rax + mov rax, QWORD PTR [rdx+64] + adc QWORD PTR [rsp+64], rax + mov rax, QWORD PTR [rdx+72] + adc QWORD PTR [rsp+72], rax + mov rax, QWORD PTR [rdx+80] + adc QWORD PTR [rsp+80], rax + mov rax, QWORD PTR [rdx+88] + adc QWORD PTR [rsp+88], rax + mov rax, QWORD PTR [rdx+96] + adc QWORD PTR [rsp+96], rax + mov rax, QWORD PTR [rdx+104] + adc QWORD PTR [rsp+104], rax + mov rax, QWORD PTR [rdx+112] + adc QWORD PTR [rsp+112], rax + mov rax, QWORD PTR [rdx+120] + adc QWORD PTR [rsp+120], rax + adc r12, 0 + mov rax, QWORD PTR [rsp] + mov r9, QWORD PTR [rsp+8] + shrd rax, r9, 1 + mov QWORD PTR [rcx], rax + mov rax, QWORD PTR [rsp+16] + shrd r9, rax, 1 + mov QWORD PTR [rcx+8], r9 + mov r9, QWORD PTR [rsp+24] + shrd rax, r9, 1 + mov QWORD PTR [rcx+16], rax + mov rax, QWORD PTR [rsp+32] + shrd r9, rax, 1 + mov QWORD PTR [rcx+24], r9 + mov r9, QWORD PTR [rsp+40] + shrd rax, r9, 1 + mov QWORD PTR [rcx+32], rax + mov rax, QWORD PTR [rsp+48] + shrd r9, rax, 1 + mov QWORD PTR [rcx+40], r9 + mov r9, QWORD PTR [rsp+56] + shrd rax, r9, 1 + mov QWORD PTR [rcx+48], rax + mov rax, QWORD PTR [rsp+64] + shrd r9, rax, 1 + mov QWORD PTR [rcx+56], r9 + mov r9, QWORD PTR [rsp+72] + shrd rax, r9, 1 + mov QWORD PTR [rcx+64], rax + mov rax, QWORD PTR [rsp+80] + shrd r9, rax, 1 + mov QWORD PTR [rcx+72], r9 + mov r9, QWORD PTR [rsp+88] + shrd rax, r9, 1 + mov QWORD PTR [rcx+80], rax + mov rax, QWORD PTR [rsp+96] + shrd r9, rax, 1 + mov QWORD PTR [rcx+88], r9 + mov r9, QWORD PTR [rsp+104] + shrd rax, r9, 1 + mov QWORD PTR [rcx+96], rax + mov rax, QWORD PTR [rsp+112] + shrd r9, rax, 1 + mov QWORD PTR [rcx+104], r9 + mov r9, QWORD PTR [rsp+120] + shrd rax, r9, 1 + mov QWORD PTR [rcx+112], rax + shrd r9, r12, 1 + mov QWORD PTR [rcx+120], r9 + add rsp, 128 + pop r13 + pop r12 + ret +sp_1024_div2_16 ENDP +_text ENDS +; /* Sub b from a into r. (r = a - b) +; * +; * r A single precision integer. +; * a A single precision integer. +; * b A single precision integer. +; */ +_text SEGMENT READONLY PARA +sp_1024_sub_16 PROC + mov r9, QWORD PTR [rdx] + xor rax, rax + sub r9, QWORD PTR [r8] + mov r10, QWORD PTR [rdx+8] + mov QWORD PTR [rcx], r9 + sbb r10, QWORD PTR [r8+8] + mov r9, QWORD PTR [rdx+16] + mov QWORD PTR [rcx+8], r10 + sbb r9, QWORD PTR [r8+16] + mov r10, QWORD PTR [rdx+24] + mov QWORD PTR [rcx+16], r9 + sbb r10, QWORD PTR [r8+24] + mov r9, QWORD PTR [rdx+32] + mov QWORD PTR [rcx+24], r10 + sbb r9, QWORD PTR [r8+32] + mov r10, QWORD PTR [rdx+40] + mov QWORD PTR [rcx+32], r9 + sbb r10, QWORD PTR [r8+40] + mov r9, QWORD PTR [rdx+48] + mov QWORD PTR [rcx+40], r10 + sbb r9, QWORD PTR [r8+48] + mov r10, QWORD PTR [rdx+56] + mov QWORD PTR [rcx+48], r9 + sbb r10, QWORD PTR [r8+56] + mov r9, QWORD PTR [rdx+64] + mov QWORD PTR [rcx+56], r10 + sbb r9, QWORD PTR [r8+64] + mov r10, QWORD PTR [rdx+72] + mov QWORD PTR [rcx+64], r9 + sbb r10, QWORD PTR [r8+72] + mov r9, QWORD PTR [rdx+80] + mov QWORD PTR [rcx+72], r10 + sbb r9, QWORD PTR [r8+80] + mov r10, QWORD PTR [rdx+88] + mov QWORD PTR [rcx+80], r9 + sbb r10, QWORD PTR [r8+88] + mov r9, QWORD PTR [rdx+96] + mov QWORD PTR [rcx+88], r10 + sbb r9, QWORD PTR [r8+96] + mov r10, QWORD PTR [rdx+104] + mov QWORD PTR [rcx+96], r9 + sbb r10, QWORD PTR [r8+104] + mov r9, QWORD PTR [rdx+112] + mov QWORD PTR [rcx+104], r10 + sbb r9, QWORD PTR [r8+112] + mov r10, QWORD PTR [rdx+120] + mov QWORD PTR [rcx+112], r9 + sbb r10, QWORD PTR [r8+120] + mov QWORD PTR [rcx+120], r10 + sbb rax, 0 + ret +sp_1024_sub_16 ENDP +_text ENDS +IFDEF HAVE_INTEL_AVX2 +; /* Reduce the number back to 1024 bits using Montgomery reduction. +; * +; * a A single precision number to reduce in place. +; * m The single precision number representing the modulus. +; * mp The digit representing the negative inverse of m mod 2^n. +; */ +_text SEGMENT READONLY PARA +sp_1024_mont_reduce_avx2_16 PROC + push r12 + push r13 + push r14 + push r15 + push rdi + push rsi + push rbx + push rbp + mov r9, rcx + mov r10, rdx + xor rbp, rbp + ; i = 16 + mov r11, 16 + mov r15, QWORD PTR [r9] + mov rdi, QWORD PTR [r9+8] + mov rsi, QWORD PTR [r9+16] + mov rbx, QWORD PTR [r9+24] + add r9, 64 + xor rbp, rbp +L_1024_mont_loop_avx2_16: + ; mu = a[i] * mp + mov rdx, r15 + mov r12, r15 + imul rdx, r8 + xor r14, r14 + ; a[i+0] += m[0] * mu + mulx rcx, rax, QWORD PTR [r10] + mov r15, rdi + adcx r12, rax + adox r15, rcx + ; a[i+1] += m[1] * mu + mulx rcx, rax, QWORD PTR [r10+8] + mov rdi, rsi + adcx r15, rax + adox rdi, rcx + ; a[i+2] += m[2] * mu + mulx rcx, rax, QWORD PTR [r10+16] + mov rsi, rbx + adcx rdi, rax + adox rsi, rcx + ; a[i+3] += m[3] * mu + mulx rcx, rax, QWORD PTR [r10+24] + mov rbx, QWORD PTR [r9+-32] + adcx rsi, rax + adox rbx, rcx + ; a[i+4] += m[4] * mu + mulx rcx, rax, QWORD PTR [r10+32] + mov r13, QWORD PTR [r9+-24] + adcx rbx, rax + adox r13, rcx + ; a[i+5] += m[5] * mu + mulx rcx, rax, QWORD PTR [r10+40] + mov r12, QWORD PTR [r9+-16] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-24], r13 + ; a[i+6] += m[6] * mu + mulx rcx, rax, QWORD PTR [r10+48] + mov r13, QWORD PTR [r9+-8] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-16], r12 + ; a[i+7] += m[7] * mu + mulx rcx, rax, QWORD PTR [r10+56] + mov r12, QWORD PTR [r9] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-8], r13 + ; a[i+8] += m[8] * mu + mulx rcx, rax, QWORD PTR [r10+64] + mov r13, QWORD PTR [r9+8] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9], r12 + ; a[i+9] += m[9] * mu + mulx rcx, rax, QWORD PTR [r10+72] + mov r12, QWORD PTR [r9+16] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+8], r13 + ; a[i+10] += m[10] * mu + mulx rcx, rax, QWORD PTR [r10+80] + mov r13, QWORD PTR [r9+24] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+16], r12 + ; a[i+11] += m[11] * mu + mulx rcx, rax, QWORD PTR [r10+88] + mov r12, QWORD PTR [r9+32] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+24], r13 + ; a[i+12] += m[12] * mu + mulx rcx, rax, QWORD PTR [r10+96] + mov r13, QWORD PTR [r9+40] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+32], r12 + ; a[i+13] += m[13] * mu + mulx rcx, rax, QWORD PTR [r10+104] + mov r12, QWORD PTR [r9+48] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+40], r13 + ; a[i+14] += m[14] * mu + mulx rcx, rax, QWORD PTR [r10+112] + mov r13, QWORD PTR [r9+56] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+48], r12 + ; a[i+15] += m[15] * mu + mulx rcx, rax, QWORD PTR [r10+120] + mov r12, QWORD PTR [r9+64] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+56], r13 + adcx r12, rbp + mov rbp, r14 + mov QWORD PTR [r9+64], r12 + adox rbp, r14 + adcx rbp, r14 + ; mu = a[i] * mp + mov rdx, r15 + mov r12, r15 + imul rdx, r8 + xor r14, r14 + ; a[i+0] += m[0] * mu + mulx rcx, rax, QWORD PTR [r10] + mov r15, rdi + adcx r12, rax + adox r15, rcx + ; a[i+1] += m[1] * mu + mulx rcx, rax, QWORD PTR [r10+8] + mov rdi, rsi + adcx r15, rax + adox rdi, rcx + ; a[i+2] += m[2] * mu + mulx rcx, rax, QWORD PTR [r10+16] + mov rsi, rbx + adcx rdi, rax + adox rsi, rcx + ; a[i+3] += m[3] * mu + mulx rcx, rax, QWORD PTR [r10+24] + mov rbx, QWORD PTR [r9+-24] + adcx rsi, rax + adox rbx, rcx + ; a[i+4] += m[4] * mu + mulx rcx, rax, QWORD PTR [r10+32] + mov r13, QWORD PTR [r9+-16] + adcx rbx, rax + adox r13, rcx + ; a[i+5] += m[5] * mu + mulx rcx, rax, QWORD PTR [r10+40] + mov r12, QWORD PTR [r9+-8] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+-16], r13 + ; a[i+6] += m[6] * mu + mulx rcx, rax, QWORD PTR [r10+48] + mov r13, QWORD PTR [r9] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+-8], r12 + ; a[i+7] += m[7] * mu + mulx rcx, rax, QWORD PTR [r10+56] + mov r12, QWORD PTR [r9+8] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9], r13 + ; a[i+8] += m[8] * mu + mulx rcx, rax, QWORD PTR [r10+64] + mov r13, QWORD PTR [r9+16] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+8], r12 + ; a[i+9] += m[9] * mu + mulx rcx, rax, QWORD PTR [r10+72] + mov r12, QWORD PTR [r9+24] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+16], r13 + ; a[i+10] += m[10] * mu + mulx rcx, rax, QWORD PTR [r10+80] + mov r13, QWORD PTR [r9+32] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+24], r12 + ; a[i+11] += m[11] * mu + mulx rcx, rax, QWORD PTR [r10+88] + mov r12, QWORD PTR [r9+40] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+32], r13 + ; a[i+12] += m[12] * mu + mulx rcx, rax, QWORD PTR [r10+96] + mov r13, QWORD PTR [r9+48] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+40], r12 + ; a[i+13] += m[13] * mu + mulx rcx, rax, QWORD PTR [r10+104] + mov r12, QWORD PTR [r9+56] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+48], r13 + ; a[i+14] += m[14] * mu + mulx rcx, rax, QWORD PTR [r10+112] + mov r13, QWORD PTR [r9+64] + adcx r12, rax + adox r13, rcx + mov QWORD PTR [r9+56], r12 + ; a[i+15] += m[15] * mu + mulx rcx, rax, QWORD PTR [r10+120] + mov r12, QWORD PTR [r9+72] + adcx r13, rax + adox r12, rcx + mov QWORD PTR [r9+64], r13 + adcx r12, rbp + mov rbp, r14 + mov QWORD PTR [r9+72], r12 + adox rbp, r14 + adcx rbp, r14 + ; a += 2 + add r9, 16 + ; i -= 2 + sub r11, 2 + jnz L_1024_mont_loop_avx2_16 + sub r9, 64 + sub r12, QWORD PTR [r10+120] + mov r8, r9 + sbb r12, r12 + neg rbp + not r12 + or rbp, r12 + sub r9, 128 + mov rcx, QWORD PTR [r10] + mov rdx, r15 + pext rcx, rcx, rbp + sub rdx, rcx + mov rcx, QWORD PTR [r10+8] + mov rax, rdi + pext rcx, rcx, rbp + mov QWORD PTR [r9], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+16] + mov rcx, rsi + pext rdx, rdx, rbp + mov QWORD PTR [r9+8], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+24] + mov rdx, rbx + pext rax, rax, rbp + mov QWORD PTR [r9+16], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+32] + mov rax, QWORD PTR [r8+32] + pext rcx, rcx, rbp + mov QWORD PTR [r9+24], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+40] + mov rcx, QWORD PTR [r8+40] + pext rdx, rdx, rbp + mov QWORD PTR [r9+32], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+48] + mov rdx, QWORD PTR [r8+48] + pext rax, rax, rbp + mov QWORD PTR [r9+40], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+56] + mov rax, QWORD PTR [r8+56] + pext rcx, rcx, rbp + mov QWORD PTR [r9+48], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+64] + mov rcx, QWORD PTR [r8+64] + pext rdx, rdx, rbp + mov QWORD PTR [r9+56], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+72] + mov rdx, QWORD PTR [r8+72] + pext rax, rax, rbp + mov QWORD PTR [r9+64], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+80] + mov rax, QWORD PTR [r8+80] + pext rcx, rcx, rbp + mov QWORD PTR [r9+72], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+88] + mov rcx, QWORD PTR [r8+88] + pext rdx, rdx, rbp + mov QWORD PTR [r9+80], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+96] + mov rdx, QWORD PTR [r8+96] + pext rax, rax, rbp + mov QWORD PTR [r9+88], rcx + sbb rdx, rax + mov rcx, QWORD PTR [r10+104] + mov rax, QWORD PTR [r8+104] + pext rcx, rcx, rbp + mov QWORD PTR [r9+96], rdx + sbb rax, rcx + mov rdx, QWORD PTR [r10+112] + mov rcx, QWORD PTR [r8+112] + pext rdx, rdx, rbp + mov QWORD PTR [r9+104], rax + sbb rcx, rdx + mov rax, QWORD PTR [r10+120] + mov rdx, QWORD PTR [r8+120] + pext rax, rax, rbp + mov QWORD PTR [r9+112], rcx + sbb rdx, rax + mov QWORD PTR [r9+120], rdx + pop rbp + pop rbx + pop rsi + pop rdi + pop r15 + pop r14 + pop r13 + pop r12 + ret +sp_1024_mont_reduce_avx2_16 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Add two Montgomery form numbers (r = a + b % m). +; * +; * r Result of addition. +; * a First number to add in Montogmery form. +; * b Second number to add in Montogmery form. +; * m Modulus (prime). +; */ +_text SEGMENT READONLY PARA +sp_1024_mont_add_avx2_16 PROC + push r12 + push r13 + mov rax, QWORD PTR [rdx] + mov r10, QWORD PTR [rdx+8] + mov r11, QWORD PTR [rdx+16] + mov r12, QWORD PTR [rdx+24] + add rax, QWORD PTR [r8] + mov r13, 0 + adc r10, QWORD PTR [r8+8] + adc r11, QWORD PTR [r8+16] + adc r12, QWORD PTR [r8+24] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r10 + mov QWORD PTR [rcx+16], r11 + mov QWORD PTR [rcx+24], r12 + mov rax, QWORD PTR [rdx+32] + mov r10, QWORD PTR [rdx+40] + mov r11, QWORD PTR [rdx+48] + mov r12, QWORD PTR [rdx+56] + adc rax, QWORD PTR [r8+32] + adc r10, QWORD PTR [r8+40] + adc r11, QWORD PTR [r8+48] + adc r12, QWORD PTR [r8+56] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r10 + mov QWORD PTR [rcx+48], r11 + mov QWORD PTR [rcx+56], r12 + mov rax, QWORD PTR [rdx+64] + mov r10, QWORD PTR [rdx+72] + mov r11, QWORD PTR [rdx+80] + mov r12, QWORD PTR [rdx+88] + adc rax, QWORD PTR [r8+64] + adc r10, QWORD PTR [r8+72] + adc r11, QWORD PTR [r8+80] + adc r12, QWORD PTR [r8+88] + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], r10 + mov QWORD PTR [rcx+80], r11 + mov QWORD PTR [rcx+88], r12 + mov rax, QWORD PTR [rdx+96] + mov r10, QWORD PTR [rdx+104] + mov r11, QWORD PTR [rdx+112] + mov r12, QWORD PTR [rdx+120] + adc rax, QWORD PTR [r8+96] + adc r10, QWORD PTR [r8+104] + adc r11, QWORD PTR [r8+112] + adc r12, QWORD PTR [r8+120] + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], r10 + mov QWORD PTR [rcx+112], r11 + mov QWORD PTR [rcx+120], r12 + sbb r13, 0 + sub r12, QWORD PTR [r9+120] + sbb r12, r12 + not r12 + or r13, r12 + mov r11, QWORD PTR [r9] + mov r12, QWORD PTR [r9+8] + mov rax, QWORD PTR [rcx] + mov r10, QWORD PTR [rcx+8] + pext r11, r11, r13 + pext r12, r12, r13 + sub rax, r11 + sbb r10, r12 + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r10 + mov r11, QWORD PTR [r9+16] + mov r12, QWORD PTR [r9+24] + mov rax, QWORD PTR [rcx+16] + mov r10, QWORD PTR [rcx+24] + pext r11, r11, r13 + pext r12, r12, r13 + sbb rax, r11 + sbb r10, r12 + mov QWORD PTR [rcx+16], rax + mov QWORD PTR [rcx+24], r10 + mov r11, QWORD PTR [r9+32] + mov r12, QWORD PTR [r9+40] + mov rax, QWORD PTR [rcx+32] + mov r10, QWORD PTR [rcx+40] + pext r11, r11, r13 + pext r12, r12, r13 + sbb rax, r11 + sbb r10, r12 + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r10 + mov r11, QWORD PTR [r9+48] + mov r12, QWORD PTR [r9+56] + mov rax, QWORD PTR [rcx+48] + mov r10, QWORD PTR [rcx+56] + pext r11, r11, r13 + pext r12, r12, r13 + sbb rax, r11 + sbb r10, r12 + mov QWORD PTR [rcx+48], rax + mov QWORD PTR [rcx+56], r10 + mov r11, QWORD PTR [r9+64] + mov r12, QWORD PTR [r9+72] + mov rax, QWORD PTR [rcx+64] + mov r10, QWORD PTR [rcx+72] + pext r11, r11, r13 + pext r12, r12, r13 + sbb rax, r11 + sbb r10, r12 + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], r10 + mov r11, QWORD PTR [r9+80] + mov r12, QWORD PTR [r9+88] + mov rax, QWORD PTR [rcx+80] + mov r10, QWORD PTR [rcx+88] + pext r11, r11, r13 + pext r12, r12, r13 + sbb rax, r11 + sbb r10, r12 + mov QWORD PTR [rcx+80], rax + mov QWORD PTR [rcx+88], r10 + mov r11, QWORD PTR [r9+96] + mov r12, QWORD PTR [r9+104] + mov rax, QWORD PTR [rcx+96] + mov r10, QWORD PTR [rcx+104] + pext r11, r11, r13 + pext r12, r12, r13 + sbb rax, r11 + sbb r10, r12 + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], r10 + mov r11, QWORD PTR [r9+112] + mov r12, QWORD PTR [r9+120] + mov rax, QWORD PTR [rcx+112] + mov r10, QWORD PTR [rcx+120] + pext r11, r11, r13 + pext r12, r12, r13 + sbb rax, r11 + sbb r10, r12 + mov QWORD PTR [rcx+112], rax + mov QWORD PTR [rcx+120], r10 + pop r13 + pop r12 + ret +sp_1024_mont_add_avx2_16 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Double a Montgomery form number (r = a + a % m). +; * +; * r Result of addition. +; * a Number to souble in Montogmery form. +; * m Modulus (prime). +; */ +_text SEGMENT READONLY PARA +sp_1024_mont_dbl_avx2_16 PROC + push r12 + mov rax, QWORD PTR [rdx] + mov r9, QWORD PTR [rdx+8] + mov r10, QWORD PTR [rdx+16] + mov r11, QWORD PTR [rdx+24] + add rax, QWORD PTR [rdx] + mov r12, 0 + adc r9, QWORD PTR [rdx+8] + adc r10, QWORD PTR [rdx+16] + adc r11, QWORD PTR [rdx+24] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r9 + mov QWORD PTR [rcx+16], r10 + mov QWORD PTR [rcx+24], r11 + mov rax, QWORD PTR [rdx+32] + mov r9, QWORD PTR [rdx+40] + mov r10, QWORD PTR [rdx+48] + mov r11, QWORD PTR [rdx+56] + adc rax, QWORD PTR [rdx+32] + adc r9, QWORD PTR [rdx+40] + adc r10, QWORD PTR [rdx+48] + adc r11, QWORD PTR [rdx+56] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r9 + mov QWORD PTR [rcx+48], r10 + mov QWORD PTR [rcx+56], r11 + mov rax, QWORD PTR [rdx+64] + mov r9, QWORD PTR [rdx+72] + mov r10, QWORD PTR [rdx+80] + mov r11, QWORD PTR [rdx+88] + adc rax, QWORD PTR [rdx+64] + adc r9, QWORD PTR [rdx+72] + adc r10, QWORD PTR [rdx+80] + adc r11, QWORD PTR [rdx+88] + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], r9 + mov QWORD PTR [rcx+80], r10 + mov QWORD PTR [rcx+88], r11 + mov rax, QWORD PTR [rdx+96] + mov r9, QWORD PTR [rdx+104] + mov r10, QWORD PTR [rdx+112] + mov r11, QWORD PTR [rdx+120] + adc rax, QWORD PTR [rdx+96] + adc r9, QWORD PTR [rdx+104] + adc r10, QWORD PTR [rdx+112] + adc r11, QWORD PTR [rdx+120] + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], r9 + mov QWORD PTR [rcx+112], r10 + mov QWORD PTR [rcx+120], r11 + sbb r12, 0 + sub r11, QWORD PTR [r8+120] + sbb r11, r11 + not r11 + or r12, r11 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + mov rax, QWORD PTR [rcx] + mov r9, QWORD PTR [rcx+8] + pext r10, r10, r12 + pext r11, r11, r12 + sub rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r9 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + mov rax, QWORD PTR [rcx+16] + mov r9, QWORD PTR [rcx+24] + pext r10, r10, r12 + pext r11, r11, r12 + sbb rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx+16], rax + mov QWORD PTR [rcx+24], r9 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + mov rax, QWORD PTR [rcx+32] + mov r9, QWORD PTR [rcx+40] + pext r10, r10, r12 + pext r11, r11, r12 + sbb rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r9 + mov r10, QWORD PTR [r8+48] + mov r11, QWORD PTR [r8+56] + mov rax, QWORD PTR [rcx+48] + mov r9, QWORD PTR [rcx+56] + pext r10, r10, r12 + pext r11, r11, r12 + sbb rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx+48], rax + mov QWORD PTR [rcx+56], r9 + mov r10, QWORD PTR [r8+64] + mov r11, QWORD PTR [r8+72] + mov rax, QWORD PTR [rcx+64] + mov r9, QWORD PTR [rcx+72] + pext r10, r10, r12 + pext r11, r11, r12 + sbb rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], r9 + mov r10, QWORD PTR [r8+80] + mov r11, QWORD PTR [r8+88] + mov rax, QWORD PTR [rcx+80] + mov r9, QWORD PTR [rcx+88] + pext r10, r10, r12 + pext r11, r11, r12 + sbb rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx+80], rax + mov QWORD PTR [rcx+88], r9 + mov r10, QWORD PTR [r8+96] + mov r11, QWORD PTR [r8+104] + mov rax, QWORD PTR [rcx+96] + mov r9, QWORD PTR [rcx+104] + pext r10, r10, r12 + pext r11, r11, r12 + sbb rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], r9 + mov r10, QWORD PTR [r8+112] + mov r11, QWORD PTR [r8+120] + mov rax, QWORD PTR [rcx+112] + mov r9, QWORD PTR [rcx+120] + pext r10, r10, r12 + pext r11, r11, r12 + sbb rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx+112], rax + mov QWORD PTR [rcx+120], r9 + pop r12 + ret +sp_1024_mont_dbl_avx2_16 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Triple a Montgomery form number (r = a + a + a % m). +; * +; * r Result of addition. +; * a Number to souble in Montogmery form. +; * m Modulus (prime). +; */ +_text SEGMENT READONLY PARA +sp_1024_mont_tpl_avx2_16 PROC + push r12 + mov rax, QWORD PTR [rdx] + mov r9, QWORD PTR [rdx+8] + mov r10, QWORD PTR [rdx+16] + mov r11, QWORD PTR [rdx+24] + add rax, QWORD PTR [rdx] + mov r12, 0 + adc r9, QWORD PTR [rdx+8] + adc r10, QWORD PTR [rdx+16] + adc r11, QWORD PTR [rdx+24] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r9 + mov QWORD PTR [rcx+16], r10 + mov QWORD PTR [rcx+24], r11 + mov rax, QWORD PTR [rdx+32] + mov r9, QWORD PTR [rdx+40] + mov r10, QWORD PTR [rdx+48] + mov r11, QWORD PTR [rdx+56] + adc rax, QWORD PTR [rdx+32] + adc r9, QWORD PTR [rdx+40] + adc r10, QWORD PTR [rdx+48] + adc r11, QWORD PTR [rdx+56] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r9 + mov QWORD PTR [rcx+48], r10 + mov QWORD PTR [rcx+56], r11 + mov rax, QWORD PTR [rdx+64] + mov r9, QWORD PTR [rdx+72] + mov r10, QWORD PTR [rdx+80] + mov r11, QWORD PTR [rdx+88] + adc rax, QWORD PTR [rdx+64] + adc r9, QWORD PTR [rdx+72] + adc r10, QWORD PTR [rdx+80] + adc r11, QWORD PTR [rdx+88] + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], r9 + mov QWORD PTR [rcx+80], r10 + mov QWORD PTR [rcx+88], r11 + mov rax, QWORD PTR [rdx+96] + mov r9, QWORD PTR [rdx+104] + mov r10, QWORD PTR [rdx+112] + mov r11, QWORD PTR [rdx+120] + adc rax, QWORD PTR [rdx+96] + adc r9, QWORD PTR [rdx+104] + adc r10, QWORD PTR [rdx+112] + adc r11, QWORD PTR [rdx+120] + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], r9 + mov QWORD PTR [rcx+112], r10 + mov QWORD PTR [rcx+120], r11 + sbb r12, 0 + sub r11, QWORD PTR [r8+120] + sbb r11, r11 + not r11 + or r12, r11 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + mov rax, QWORD PTR [rcx] + mov r9, QWORD PTR [rcx+8] + pext r10, r10, r12 + pext r11, r11, r12 + sub rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r9 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + mov rax, QWORD PTR [rcx+16] + mov r9, QWORD PTR [rcx+24] + pext r10, r10, r12 + pext r11, r11, r12 + sbb rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx+16], rax + mov QWORD PTR [rcx+24], r9 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + mov rax, QWORD PTR [rcx+32] + mov r9, QWORD PTR [rcx+40] + pext r10, r10, r12 + pext r11, r11, r12 + sbb rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r9 + mov r10, QWORD PTR [r8+48] + mov r11, QWORD PTR [r8+56] + mov rax, QWORD PTR [rcx+48] + mov r9, QWORD PTR [rcx+56] + pext r10, r10, r12 + pext r11, r11, r12 + sbb rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx+48], rax + mov QWORD PTR [rcx+56], r9 + mov r10, QWORD PTR [r8+64] + mov r11, QWORD PTR [r8+72] + mov rax, QWORD PTR [rcx+64] + mov r9, QWORD PTR [rcx+72] + pext r10, r10, r12 + pext r11, r11, r12 + sbb rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], r9 + mov r10, QWORD PTR [r8+80] + mov r11, QWORD PTR [r8+88] + mov rax, QWORD PTR [rcx+80] + mov r9, QWORD PTR [rcx+88] + pext r10, r10, r12 + pext r11, r11, r12 + sbb rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx+80], rax + mov QWORD PTR [rcx+88], r9 + mov r10, QWORD PTR [r8+96] + mov r11, QWORD PTR [r8+104] + mov rax, QWORD PTR [rcx+96] + mov r9, QWORD PTR [rcx+104] + pext r10, r10, r12 + pext r11, r11, r12 + sbb rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], r9 + mov r10, QWORD PTR [r8+112] + mov r11, QWORD PTR [r8+120] + mov rax, QWORD PTR [rcx+112] + mov r9, QWORD PTR [rcx+120] + pext r10, r10, r12 + pext r11, r11, r12 + sbb rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx+112], rax + mov QWORD PTR [rcx+120], r9 + mov rax, QWORD PTR [rcx] + mov r9, QWORD PTR [rcx+8] + mov r10, QWORD PTR [rcx+16] + mov r11, QWORD PTR [rcx+24] + add rax, QWORD PTR [rdx] + mov r12, 0 + adc r9, QWORD PTR [rdx+8] + adc r10, QWORD PTR [rdx+16] + adc r11, QWORD PTR [rdx+24] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r9 + mov QWORD PTR [rcx+16], r10 + mov QWORD PTR [rcx+24], r11 + mov rax, QWORD PTR [rcx+32] + mov r9, QWORD PTR [rcx+40] + mov r10, QWORD PTR [rcx+48] + mov r11, QWORD PTR [rcx+56] + adc rax, QWORD PTR [rdx+32] + adc r9, QWORD PTR [rdx+40] + adc r10, QWORD PTR [rdx+48] + adc r11, QWORD PTR [rdx+56] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r9 + mov QWORD PTR [rcx+48], r10 + mov QWORD PTR [rcx+56], r11 + mov rax, QWORD PTR [rcx+64] + mov r9, QWORD PTR [rcx+72] + mov r10, QWORD PTR [rcx+80] + mov r11, QWORD PTR [rcx+88] + adc rax, QWORD PTR [rdx+64] + adc r9, QWORD PTR [rdx+72] + adc r10, QWORD PTR [rdx+80] + adc r11, QWORD PTR [rdx+88] + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], r9 + mov QWORD PTR [rcx+80], r10 + mov QWORD PTR [rcx+88], r11 + mov rax, QWORD PTR [rcx+96] + mov r9, QWORD PTR [rcx+104] + mov r10, QWORD PTR [rcx+112] + mov r11, QWORD PTR [rcx+120] + adc rax, QWORD PTR [rdx+96] + adc r9, QWORD PTR [rdx+104] + adc r10, QWORD PTR [rdx+112] + adc r11, QWORD PTR [rdx+120] + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], r9 + mov QWORD PTR [rcx+112], r10 + mov QWORD PTR [rcx+120], r11 + sbb r12, 0 + sub r11, QWORD PTR [r8+120] + sbb r11, r11 + not r11 + or r12, r11 + mov r10, QWORD PTR [r8] + mov r11, QWORD PTR [r8+8] + mov rax, QWORD PTR [rcx] + mov r9, QWORD PTR [rcx+8] + pext r10, r10, r12 + pext r11, r11, r12 + sub rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r9 + mov r10, QWORD PTR [r8+16] + mov r11, QWORD PTR [r8+24] + mov rax, QWORD PTR [rcx+16] + mov r9, QWORD PTR [rcx+24] + pext r10, r10, r12 + pext r11, r11, r12 + sbb rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx+16], rax + mov QWORD PTR [rcx+24], r9 + mov r10, QWORD PTR [r8+32] + mov r11, QWORD PTR [r8+40] + mov rax, QWORD PTR [rcx+32] + mov r9, QWORD PTR [rcx+40] + pext r10, r10, r12 + pext r11, r11, r12 + sbb rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r9 + mov r10, QWORD PTR [r8+48] + mov r11, QWORD PTR [r8+56] + mov rax, QWORD PTR [rcx+48] + mov r9, QWORD PTR [rcx+56] + pext r10, r10, r12 + pext r11, r11, r12 + sbb rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx+48], rax + mov QWORD PTR [rcx+56], r9 + mov r10, QWORD PTR [r8+64] + mov r11, QWORD PTR [r8+72] + mov rax, QWORD PTR [rcx+64] + mov r9, QWORD PTR [rcx+72] + pext r10, r10, r12 + pext r11, r11, r12 + sbb rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], r9 + mov r10, QWORD PTR [r8+80] + mov r11, QWORD PTR [r8+88] + mov rax, QWORD PTR [rcx+80] + mov r9, QWORD PTR [rcx+88] + pext r10, r10, r12 + pext r11, r11, r12 + sbb rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx+80], rax + mov QWORD PTR [rcx+88], r9 + mov r10, QWORD PTR [r8+96] + mov r11, QWORD PTR [r8+104] + mov rax, QWORD PTR [rcx+96] + mov r9, QWORD PTR [rcx+104] + pext r10, r10, r12 + pext r11, r11, r12 + sbb rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], r9 + mov r10, QWORD PTR [r8+112] + mov r11, QWORD PTR [r8+120] + mov rax, QWORD PTR [rcx+112] + mov r9, QWORD PTR [rcx+120] + pext r10, r10, r12 + pext r11, r11, r12 + sbb rax, r10 + sbb r9, r11 + mov QWORD PTR [rcx+112], rax + mov QWORD PTR [rcx+120], r9 + pop r12 + ret +sp_1024_mont_tpl_avx2_16 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Subtract two Montgomery form numbers (r = a - b % m). +; * +; * r Result of addition. +; * a First number to add in Montogmery form. +; * b Second number to add in Montogmery form. +; * m Modulus (prime). +; */ +_text SEGMENT READONLY PARA +sp_1024_mont_sub_avx2_16 PROC + push r12 + push r13 + mov rax, QWORD PTR [rdx] + mov r10, QWORD PTR [rdx+8] + mov r11, QWORD PTR [rdx+16] + mov r12, QWORD PTR [rdx+24] + sub rax, QWORD PTR [r8] + mov r13, 0 + sbb r10, QWORD PTR [r8+8] + sbb r11, QWORD PTR [r8+16] + sbb r12, QWORD PTR [r8+24] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r10 + mov QWORD PTR [rcx+16], r11 + mov QWORD PTR [rcx+24], r12 + mov rax, QWORD PTR [rdx+32] + mov r10, QWORD PTR [rdx+40] + mov r11, QWORD PTR [rdx+48] + mov r12, QWORD PTR [rdx+56] + sbb rax, QWORD PTR [r8+32] + sbb r10, QWORD PTR [r8+40] + sbb r11, QWORD PTR [r8+48] + sbb r12, QWORD PTR [r8+56] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r10 + mov QWORD PTR [rcx+48], r11 + mov QWORD PTR [rcx+56], r12 + mov rax, QWORD PTR [rdx+64] + mov r10, QWORD PTR [rdx+72] + mov r11, QWORD PTR [rdx+80] + mov r12, QWORD PTR [rdx+88] + sbb rax, QWORD PTR [r8+64] + sbb r10, QWORD PTR [r8+72] + sbb r11, QWORD PTR [r8+80] + sbb r12, QWORD PTR [r8+88] + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], r10 + mov QWORD PTR [rcx+80], r11 + mov QWORD PTR [rcx+88], r12 + mov rax, QWORD PTR [rdx+96] + mov r10, QWORD PTR [rdx+104] + mov r11, QWORD PTR [rdx+112] + mov r12, QWORD PTR [rdx+120] + sbb rax, QWORD PTR [r8+96] + sbb r10, QWORD PTR [r8+104] + sbb r11, QWORD PTR [r8+112] + sbb r12, QWORD PTR [r8+120] + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], r10 + mov QWORD PTR [rcx+112], r11 + mov QWORD PTR [rcx+120], r12 + sbb r13, 0 + mov r11, QWORD PTR [r9] + mov r12, QWORD PTR [r9+8] + mov rax, QWORD PTR [rcx] + mov r10, QWORD PTR [rcx+8] + pext r11, r11, r13 + pext r12, r12, r13 + add rax, r11 + adc r10, r12 + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r10 + mov r11, QWORD PTR [r9+16] + mov r12, QWORD PTR [r9+24] + mov rax, QWORD PTR [rcx+16] + mov r10, QWORD PTR [rcx+24] + pext r11, r11, r13 + pext r12, r12, r13 + adc rax, r11 + adc r10, r12 + mov QWORD PTR [rcx+16], rax + mov QWORD PTR [rcx+24], r10 + mov r11, QWORD PTR [r9+32] + mov r12, QWORD PTR [r9+40] + mov rax, QWORD PTR [rcx+32] + mov r10, QWORD PTR [rcx+40] + pext r11, r11, r13 + pext r12, r12, r13 + adc rax, r11 + adc r10, r12 + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r10 + mov r11, QWORD PTR [r9+48] + mov r12, QWORD PTR [r9+56] + mov rax, QWORD PTR [rcx+48] + mov r10, QWORD PTR [rcx+56] + pext r11, r11, r13 + pext r12, r12, r13 + adc rax, r11 + adc r10, r12 + mov QWORD PTR [rcx+48], rax + mov QWORD PTR [rcx+56], r10 + mov r11, QWORD PTR [r9+64] + mov r12, QWORD PTR [r9+72] + mov rax, QWORD PTR [rcx+64] + mov r10, QWORD PTR [rcx+72] + pext r11, r11, r13 + pext r12, r12, r13 + adc rax, r11 + adc r10, r12 + mov QWORD PTR [rcx+64], rax + mov QWORD PTR [rcx+72], r10 + mov r11, QWORD PTR [r9+80] + mov r12, QWORD PTR [r9+88] + mov rax, QWORD PTR [rcx+80] + mov r10, QWORD PTR [rcx+88] + pext r11, r11, r13 + pext r12, r12, r13 + adc rax, r11 + adc r10, r12 + mov QWORD PTR [rcx+80], rax + mov QWORD PTR [rcx+88], r10 + mov r11, QWORD PTR [r9+96] + mov r12, QWORD PTR [r9+104] + mov rax, QWORD PTR [rcx+96] + mov r10, QWORD PTR [rcx+104] + pext r11, r11, r13 + pext r12, r12, r13 + adc rax, r11 + adc r10, r12 + mov QWORD PTR [rcx+96], rax + mov QWORD PTR [rcx+104], r10 + mov r11, QWORD PTR [r9+112] + mov r12, QWORD PTR [r9+120] + mov rax, QWORD PTR [rcx+112] + mov r10, QWORD PTR [rcx+120] + pext r11, r11, r13 + pext r12, r12, r13 + adc rax, r11 + adc r10, r12 + mov QWORD PTR [rcx+112], rax + mov QWORD PTR [rcx+120], r10 + pop r13 + pop r12 + ret +sp_1024_mont_sub_avx2_16 ENDP +_text ENDS +ENDIF +IFDEF HAVE_INTEL_AVX2 +; /* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m) +; * +; * r Result of division by 2. +; * a Number to divide. +; * m Modulus (prime). +; */ +_text SEGMENT READONLY PARA +sp_1024_div2_avx2_16 PROC + push r12 + push r13 + mov r13, QWORD PTR [rdx] + xor r12, r12 + mov r10, r13 + and r13, 1 + neg r13 + mov rax, QWORD PTR [r8] + mov r9, QWORD PTR [r8+8] + mov r10, QWORD PTR [rdx] + mov r11, QWORD PTR [rdx+8] + pext rax, rax, r13 + pext r9, r9, r13 + add r10, rax + adc r11, r9 + mov QWORD PTR [rcx], r10 + mov QWORD PTR [rcx+8], r11 + mov rax, QWORD PTR [r8+16] + mov r9, QWORD PTR [r8+24] + mov r10, QWORD PTR [rdx+16] + mov r11, QWORD PTR [rdx+24] + pext rax, rax, r13 + pext r9, r9, r13 + adc r10, rax + adc r11, r9 + mov QWORD PTR [rcx+16], r10 + mov QWORD PTR [rcx+24], r11 + mov rax, QWORD PTR [r8+32] + mov r9, QWORD PTR [r8+40] + mov r10, QWORD PTR [rdx+32] + mov r11, QWORD PTR [rdx+40] + pext rax, rax, r13 + pext r9, r9, r13 + adc r10, rax + adc r11, r9 + mov QWORD PTR [rcx+32], r10 + mov QWORD PTR [rcx+40], r11 + mov rax, QWORD PTR [r8+48] + mov r9, QWORD PTR [r8+56] + mov r10, QWORD PTR [rdx+48] + mov r11, QWORD PTR [rdx+56] + pext rax, rax, r13 + pext r9, r9, r13 + adc r10, rax + adc r11, r9 + mov QWORD PTR [rcx+48], r10 + mov QWORD PTR [rcx+56], r11 + mov rax, QWORD PTR [r8+64] + mov r9, QWORD PTR [r8+72] + mov r10, QWORD PTR [rdx+64] + mov r11, QWORD PTR [rdx+72] + pext rax, rax, r13 + pext r9, r9, r13 + adc r10, rax + adc r11, r9 + mov QWORD PTR [rcx+64], r10 + mov QWORD PTR [rcx+72], r11 + mov rax, QWORD PTR [r8+80] + mov r9, QWORD PTR [r8+88] + mov r10, QWORD PTR [rdx+80] + mov r11, QWORD PTR [rdx+88] + pext rax, rax, r13 + pext r9, r9, r13 + adc r10, rax + adc r11, r9 + mov QWORD PTR [rcx+80], r10 + mov QWORD PTR [rcx+88], r11 + mov rax, QWORD PTR [r8+96] + mov r9, QWORD PTR [r8+104] + mov r10, QWORD PTR [rdx+96] + mov r11, QWORD PTR [rdx+104] + pext rax, rax, r13 + pext r9, r9, r13 + adc r10, rax + adc r11, r9 + mov QWORD PTR [rcx+96], r10 + mov QWORD PTR [rcx+104], r11 + mov rax, QWORD PTR [r8+112] + mov r9, QWORD PTR [r8+120] + mov r10, QWORD PTR [rdx+112] + mov r11, QWORD PTR [rdx+120] + pext rax, rax, r13 + pext r9, r9, r13 + adc r10, rax + adc r11, r9 + mov QWORD PTR [rcx+112], r10 + mov QWORD PTR [rcx+120], r11 + adc r12, 0 + mov r10, QWORD PTR [rcx] + mov r11, QWORD PTR [rcx+8] + shrd r10, r11, 1 + mov QWORD PTR [rcx], r10 + mov r10, QWORD PTR [rcx+16] + shrd r11, r10, 1 + mov QWORD PTR [rcx+8], r11 + mov r11, QWORD PTR [rcx+24] + shrd r10, r11, 1 + mov QWORD PTR [rcx+16], r10 + mov r10, QWORD PTR [rcx+32] + shrd r11, r10, 1 + mov QWORD PTR [rcx+24], r11 + mov r11, QWORD PTR [rcx+40] + shrd r10, r11, 1 + mov QWORD PTR [rcx+32], r10 + mov r10, QWORD PTR [rcx+48] + shrd r11, r10, 1 + mov QWORD PTR [rcx+40], r11 + mov r11, QWORD PTR [rcx+56] + shrd r10, r11, 1 + mov QWORD PTR [rcx+48], r10 + mov r10, QWORD PTR [rcx+64] + shrd r11, r10, 1 + mov QWORD PTR [rcx+56], r11 + mov r11, QWORD PTR [rcx+72] + shrd r10, r11, 1 + mov QWORD PTR [rcx+64], r10 + mov r10, QWORD PTR [rcx+80] + shrd r11, r10, 1 + mov QWORD PTR [rcx+72], r11 + mov r11, QWORD PTR [rcx+88] + shrd r10, r11, 1 + mov QWORD PTR [rcx+80], r10 + mov r10, QWORD PTR [rcx+96] + shrd r11, r10, 1 + mov QWORD PTR [rcx+88], r11 + mov r11, QWORD PTR [rcx+104] + shrd r10, r11, 1 + mov QWORD PTR [rcx+96], r10 + mov r10, QWORD PTR [rcx+112] + shrd r11, r10, 1 + mov QWORD PTR [rcx+104], r11 + mov r11, QWORD PTR [rcx+120] + shrd r10, r11, 1 + mov QWORD PTR [rcx+112], r10 + shrd r11, r12, 1 + mov QWORD PTR [rcx+120], r11 + pop r13 + pop r12 + ret +sp_1024_div2_avx2_16 ENDP +_text ENDS +ENDIF +; /* Read big endian unsigned byte array into r. +; * Uses the bswap instruction. +; * +; * r A single precision integer. +; * size Maximum number of bytes to convert +; * a Byte array. +; * n Number of bytes in array to read. +; */ +_text SEGMENT READONLY PARA +sp_1024_from_bin_bswap PROC + push r12 + push r13 + mov r11, r8 + mov r12, rcx + add r11, r9 + add r12, 128 + xor r13, r13 + jmp L_1024_from_bin_bswap_64_end +L_1024_from_bin_bswap_64_start: + sub r11, 64 + mov rax, QWORD PTR [r11+56] + mov r10, QWORD PTR [r11+48] + bswap rax + bswap r10 + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r10 + mov rax, QWORD PTR [r11+40] + mov r10, QWORD PTR [r11+32] + bswap rax + bswap r10 + mov QWORD PTR [rcx+16], rax + mov QWORD PTR [rcx+24], r10 + mov rax, QWORD PTR [r11+24] + mov r10, QWORD PTR [r11+16] + bswap rax + bswap r10 + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r10 + mov rax, QWORD PTR [r11+8] + mov r10, QWORD PTR [r11] + bswap rax + bswap r10 + mov QWORD PTR [rcx+48], rax + mov QWORD PTR [rcx+56], r10 + add rcx, 64 + sub r9, 64 +L_1024_from_bin_bswap_64_end: + cmp r9, 63 + jg L_1024_from_bin_bswap_64_start + jmp L_1024_from_bin_bswap_8_end +L_1024_from_bin_bswap_8_start: + sub r11, 8 + mov rax, QWORD PTR [r11] + bswap rax + mov QWORD PTR [rcx], rax + add rcx, 8 + sub r9, 8 +L_1024_from_bin_bswap_8_end: + cmp r9, 7 + jg L_1024_from_bin_bswap_8_start + cmp r9, r13 + je L_1024_from_bin_bswap_hi_end + mov r10, r13 + mov rax, r13 +L_1024_from_bin_bswap_hi_start: + mov al, BYTE PTR [r8] + shl r10, 8 + inc r8 + add r10, rax + dec r9 + jg L_1024_from_bin_bswap_hi_start + mov QWORD PTR [rcx], r10 + add rcx, 8 +L_1024_from_bin_bswap_hi_end: + cmp rcx, r12 + je L_1024_from_bin_bswap_zero_end +L_1024_from_bin_bswap_zero_start: + mov QWORD PTR [rcx], r13 + add rcx, 8 + cmp rcx, r12 + jl L_1024_from_bin_bswap_zero_start +L_1024_from_bin_bswap_zero_end: + pop r13 + pop r12 + ret +sp_1024_from_bin_bswap ENDP +_text ENDS +IFNDEF NO_MOVBE_SUPPORT +; /* Read big endian unsigned byte array into r. +; * Uses the movbe instruction which is an optional instruction. +; * +; * r A single precision integer. +; * size Maximum number of bytes to convert +; * a Byte array. +; * n Number of bytes in array to read. +; */ +_text SEGMENT READONLY PARA +sp_1024_from_bin_movbe PROC + push r12 + push r13 + mov r11, r8 + mov r12, rcx + add r11, r9 + add r12, 128 + xor r13, r13 + jmp L_1024_from_bin_movbe_64_end +L_1024_from_bin_movbe_64_start: + sub r11, 64 + movbe rax, QWORD PTR [r11+56] + movbe r10, QWORD PTR [r11+48] + mov QWORD PTR [rcx], rax + mov QWORD PTR [rcx+8], r10 + movbe rax, QWORD PTR [r11+40] + movbe r10, QWORD PTR [r11+32] + mov QWORD PTR [rcx+16], rax + mov QWORD PTR [rcx+24], r10 + movbe rax, QWORD PTR [r11+24] + movbe r10, QWORD PTR [r11+16] + mov QWORD PTR [rcx+32], rax + mov QWORD PTR [rcx+40], r10 + movbe rax, QWORD PTR [r11+8] + movbe r10, QWORD PTR [r11] + mov QWORD PTR [rcx+48], rax + mov QWORD PTR [rcx+56], r10 + add rcx, 64 + sub r9, 64 +L_1024_from_bin_movbe_64_end: + cmp r9, 63 + jg L_1024_from_bin_movbe_64_start + jmp L_1024_from_bin_movbe_8_end +L_1024_from_bin_movbe_8_start: + sub r11, 8 + movbe rax, QWORD PTR [r11] + mov QWORD PTR [rcx], rax + add rcx, 8 + sub r9, 8 +L_1024_from_bin_movbe_8_end: + cmp r9, 7 + jg L_1024_from_bin_movbe_8_start + cmp r9, r13 + je L_1024_from_bin_movbe_hi_end + mov r10, r13 + mov rax, r13 +L_1024_from_bin_movbe_hi_start: + mov al, BYTE PTR [r8] + shl r10, 8 + inc r8 + add r10, rax + dec r9 + jg L_1024_from_bin_movbe_hi_start + mov QWORD PTR [rcx], r10 + add rcx, 8 +L_1024_from_bin_movbe_hi_end: + cmp rcx, r12 + je L_1024_from_bin_movbe_zero_end +L_1024_from_bin_movbe_zero_start: + mov QWORD PTR [rcx], r13 + add rcx, 8 + cmp rcx, r12 + jl L_1024_from_bin_movbe_zero_start +L_1024_from_bin_movbe_zero_end: + pop r13 + pop r12 + ret +sp_1024_from_bin_movbe ENDP +_text ENDS +ENDIF +ENDIF +END diff --git a/wolfcrypt/src/srp.c b/wolfcrypt/src/srp.c index af047ac3c..a891f588a 100644 --- a/wolfcrypt/src/srp.c +++ b/wolfcrypt/src/srp.c @@ -1,6 +1,6 @@ /* srp.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index 4352567cc..f7fd26ed0 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -1,6 +1,6 @@ /* tfm.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -1468,12 +1468,15 @@ int fp_invmod_mont_ct(fp_int *a, fp_int *b, fp_int *c, fp_digit mp) fp_sub_d(b, 2, e); /* Highest bit is always set. */ - for (i = fp_count_bits(e)-2, j = 1; i >= 0; i--, j++) { + j = 1; + for (i = fp_count_bits(e)-2; i >= 0; i--) { if (!fp_is_bit_set(e, i) || j == CT_INV_MOD_PRE_CNT) break; + j++; } fp_copy(&pre[j-1], t); - for (j = 0; i >= 0; i--) { + j = 0; + for (; i >= 0; i--) { int set = fp_is_bit_set(e, i); if ((j == CT_INV_MOD_PRE_CNT) || (!set && j > 0)) { @@ -3660,10 +3663,11 @@ int fp_read_unsigned_bin(fp_int *a, const unsigned char *b, int c) int fp_to_unsigned_bin_at_pos(int x, fp_int *t, unsigned char *b) { #if DIGIT_BIT == 64 || DIGIT_BIT == 32 - int i, j; + int i; + int j = 0; fp_digit n; - for (j=0,i=0; iused-1; ) { + for (i = 0; i < t->used-1; ) { b[x++] = (unsigned char)(t->dp[i] >> j); j += 8; i += j == DIGIT_BIT; @@ -3713,9 +3717,11 @@ int fp_to_unsigned_bin(fp_int *a, unsigned char *b) int fp_to_unsigned_bin_len(fp_int *a, unsigned char *b, int c) { #if DIGIT_BIT == 64 || DIGIT_BIT == 32 - int i, j, x; + int i = 0; + int j = 0; + int x; - for (x=c-1, j=0, i=0; x >= 0 && i < a->used; x--) { + for (x=c-1; x >= 0 && i < a->used; x--) { b[x] = (unsigned char)(a->dp[i] >> j); j += 8; i += j == DIGIT_BIT; @@ -3755,7 +3761,7 @@ int fp_to_unsigned_bin_len(fp_int *a, unsigned char *b, int c) #endif } -int fp_unsigned_bin_size(fp_int *a) +int fp_unsigned_bin_size(const fp_int *a) { int size = fp_count_bits (a); return (size / 8 + ((size & 7) != 0 ? 1 : 0)); @@ -3843,7 +3849,7 @@ int fp_set_bit (fp_int * a, fp_digit b) return MP_OKAY; } -int fp_count_bits (fp_int * a) +int fp_count_bits (const fp_int * a) { int r; fp_digit q; @@ -4290,7 +4296,7 @@ int mp_cmp_d(mp_int * a, mp_digit b) } /* get the size for an unsigned equivalent */ -int mp_unsigned_bin_size (mp_int * a) +int mp_unsigned_bin_size (const mp_int * a) { return fp_unsigned_bin_size(a); } @@ -4344,7 +4350,7 @@ int mp_div_2d(fp_int* a, int b, fp_int* c, fp_int* d) return MP_OKAY; } -void fp_copy(fp_int *a, fp_int *b) +void fp_copy(const fp_int *a, fp_int *b) { /* if source and destination are different */ if (a != b) { @@ -4390,7 +4396,7 @@ void fp_init_copy(fp_int *a, fp_int* b) } /* fast math wrappers */ -int mp_copy(fp_int* a, fp_int* b) +int mp_copy(const fp_int* a, fp_int* b) { fp_copy(a, b); return MP_OKAY; @@ -4406,7 +4412,7 @@ int mp_iszero(mp_int* a) return fp_iszero(a); } -int mp_count_bits (mp_int* a) +int mp_count_bits (const mp_int* a) { return fp_count_bits(a); } diff --git a/wolfcrypt/src/wc_dsp.c b/wolfcrypt/src/wc_dsp.c index 594ad0489..f69a05f78 100644 --- a/wolfcrypt/src/wc_dsp.c +++ b/wolfcrypt/src/wc_dsp.c @@ -1,6 +1,6 @@ /* wc_dsp.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/wc_encrypt.c b/wolfcrypt/src/wc_encrypt.c index dbed40dad..331367b97 100644 --- a/wolfcrypt/src/wc_encrypt.c +++ b/wolfcrypt/src/wc_encrypt.c @@ -1,6 +1,6 @@ /* wc_encrypt.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -488,6 +488,7 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, byte unicodePasswd[MAX_UNICODE_SZ]; if ( (passwordSz * 2 + 2) > (int)sizeof(unicodePasswd)) { + ForceZero(key, MAX_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif @@ -510,6 +511,7 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, } #endif /* HAVE_PKCS12 */ else { + ForceZero(key, MAX_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif @@ -518,6 +520,7 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, } if (ret != 0) { + ForceZero(key, MAX_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif @@ -543,6 +546,7 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, ret = wc_Des_SetKey(&des, key, desIv, DES_DECRYPTION); } if (ret != 0) { + ForceZero(key, MAX_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif @@ -570,6 +574,7 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, ret = wc_Des3Init(&des, NULL, INVALID_DEVID); if (ret != 0) { + ForceZero(key, MAX_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif @@ -582,6 +587,7 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, ret = wc_Des3_SetKey(&des, key, desIv, DES_DECRYPTION); } if (ret != 0) { + ForceZero(key, MAX_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif @@ -594,6 +600,7 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, ret = wc_Des3_CbcDecrypt(&des, input, input, length); } if (ret != 0) { + ForceZero(key, MAX_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif @@ -648,6 +655,7 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, XFREE(aes, NULL, DYNAMIC_TYPE_AES); #endif if (ret != 0) { + ForceZero(key, MAX_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif @@ -670,6 +678,7 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, ret = wc_Rc2CbcDecrypt(&rc2, input, input, length); } if (ret != 0) { + ForceZero(key, MAX_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif @@ -681,6 +690,7 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, #endif default: + ForceZero(key, MAX_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif @@ -688,6 +698,7 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, return ALGO_ID_E; } + ForceZero(key, MAX_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif diff --git a/wolfcrypt/src/wc_pkcs11.c b/wolfcrypt/src/wc_pkcs11.c index ef4974b5e..3c4600e5e 100644 --- a/wolfcrypt/src/wc_pkcs11.c +++ b/wolfcrypt/src/wc_pkcs11.c @@ -1,6 +1,6 @@ /* wc_pkcs11.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -2584,6 +2584,9 @@ static int Pkcs11ECDSA_Sign(Pkcs11Session* session, wc_CryptoInfo* info) if (ret == 0 && info->pk.eccsign.outlen == NULL) { ret = BAD_FUNC_ARG; } + if (ret == 0 && info->pk.eccsign.out == NULL) { + ret = BAD_FUNC_ARG; + } if (ret == 0) { WOLFSSL_MSG("PKCS#11: EC Signing Operation"); @@ -3508,6 +3511,8 @@ static int Pkcs11RandomBlock(Pkcs11Session* session, wc_CryptoInfo* info) int ret = 0; CK_RV rv; + WOLFSSL_MSG("PKCS#11: Generate Random for Block"); + rv = session->func->C_GenerateRandom(session->handle, info->rng.out, info->rng.sz); #ifdef WOLFSSL_DEBUG_PKCS11 @@ -3533,6 +3538,8 @@ static int Pkcs11RandomSeed(Pkcs11Session* session, wc_CryptoInfo* info) int ret = 0; CK_RV rv; + WOLFSSL_MSG("PKCS#11: Generate Random for Seed"); + rv = session->func->C_GenerateRandom(session->handle, info->seed.seed, info->seed.sz); #ifdef WOLFSSL_DEBUG_PKCS11 diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index bf02950ca..2e6dc17ac 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -1,6 +1,6 @@ /* port.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/wolfevent.c b/wolfcrypt/src/wolfevent.c index 20848cddc..8ae2717d7 100644 --- a/wolfcrypt/src/wolfevent.c +++ b/wolfcrypt/src/wolfevent.c @@ -1,6 +1,6 @@ /* wolfevent.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/src/wolfmath.c b/wolfcrypt/src/wolfmath.c index fd8c224b3..08d0f4642 100644 --- a/wolfcrypt/src/wolfmath.c +++ b/wolfcrypt/src/wolfmath.c @@ -1,6 +1,6 @@ /* wolfmath.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -71,7 +71,7 @@ #endif -int get_digit_count(mp_int* a) +int get_digit_count(const mp_int* a) { if (a == NULL) return 0; @@ -79,7 +79,7 @@ int get_digit_count(mp_int* a) return a->used; } -mp_digit get_digit(mp_int* a, int n) +mp_digit get_digit(const mp_int* a, int n) { if (a == NULL) return 0; @@ -142,7 +142,7 @@ int get_rand_digit(WC_RNG* rng, mp_digit* d) return wc_RNG_GenerateBlock(rng, (byte*)d, sizeof(mp_digit)); } -#ifdef WC_RSA_BLINDING +#if defined(WC_RSA_BLINDING) || defined(WOLFCRYPT_HAVE_SAKKE) int mp_rand(mp_int* a, int digits, WC_RNG* rng) { int ret = 0; @@ -198,7 +198,7 @@ int mp_rand(mp_int* a, int digits, WC_RNG* rng) return ret; } -#endif /* WC_RSA_BLINDING */ +#endif /* WC_RSA_BLINDING || WOLFCRYPT_HAVE_SAKKE */ #endif #if defined(HAVE_ECC) || defined(WOLFSSL_EXPORT_INT) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 44359cbc3..a3e9ee2d5 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -1,6 +1,6 @@ /* test.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -164,6 +164,19 @@ _Pragma("GCC diagnostic ignored \"-Wunused-function\""); int dc_log_printf(char*, ...); #undef printf #define printf dc_log_printf +#elif defined(ANDROID) + #ifdef XMALLOC_USER + #include /* we're using malloc / free direct here */ + #endif + #ifndef STRING_USER + #include + #endif + #include + + #define printf(...) \ + __android_log_print(ANDROID_LOG_DEBUG, "TAG", __VA_ARGS__) + #define fprintf(fp, ...) \ + __android_log_print(ANDROID_LOG_DEBUG, "TAG", __VA_ARGS__) #else #ifdef XMALLOC_USER #include /* we're using malloc / free direct here */ @@ -238,6 +251,12 @@ _Pragma("GCC diagnostic ignored \"-Wunused-function\""); #ifdef HAVE_ED448 #include #endif +#ifdef WOLFCRYPT_HAVE_ECCSI + #include +#endif +#ifdef WOLFCRYPT_HAVE_SAKKE + #include +#endif #if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S) #include #endif @@ -444,6 +463,12 @@ WOLFSSL_TEST_SUBROUTINE int scrypt_test(void); #ifdef HAVE_ED448 WOLFSSL_TEST_SUBROUTINE int ed448_test(void); #endif +#ifdef WOLFCRYPT_HAVE_ECCSI + WOLFSSL_TEST_SUBROUTINE int eccsi_test(void); +#endif +#ifdef WOLFCRYPT_HAVE_SAKKE + WOLFSSL_TEST_SUBROUTINE int sakke_test(void); +#endif #ifdef HAVE_BLAKE2 WOLFSSL_TEST_SUBROUTINE int blake2b_test(void); #endif @@ -1241,9 +1266,22 @@ initDefaultName(); #ifdef HAVE_ED448 if ( (ret = ed448_test()) != 0) - return err_sys("ED448 test failed!\n", ret); + return err_sys("ED448 test failed!\n", ret); else - test_pass("ED448 test passed!\n"); + test_pass("ED448 test passed!\n"); +#endif + +#ifdef WOLFCRYPT_HAVE_ECCSI + if ( (ret = eccsi_test()) != 0) + return err_sys("ECCSI test failed!\n", ret); + else + test_pass("ECCSI test passed!\n"); +#endif +#ifdef WOLFCRYPT_HAVE_SAKKE + if ( (ret = sakke_test()) != 0) + return err_sys("SAKKE test failed!\n", ret); + else + test_pass("SAKKE test passed!\n"); #endif #if defined(WOLFSSL_CMAC) && !defined(NO_AES) @@ -14574,7 +14612,7 @@ WOLFSSL_TEST_SUBROUTINE int rsa_test(void) const word32 inLen = (word32)TEST_STRING_SZ; const word32 outSz = RSA_TEST_BYTES; const word32 plainSz = RSA_TEST_BYTES; - byte* res; + byte* res = NULL; #ifndef NO_SIG_WRAPPER int modLen; #endif @@ -26588,6 +26626,2086 @@ WOLFSSL_TEST_SUBROUTINE int ed448_test(void) } #endif /* HAVE_ED448 */ +#ifdef WOLFCRYPT_HAVE_ECCSI +static int eccsi_api_test(WC_RNG* rng, EccsiKey* key, mp_int* ssk, + ecc_point* pvt) +{ + int ret; + byte id[1] = { 0x00 }; + int valid; + word32 sz; + byte data[256]; + byte hash[WC_MAX_DIGEST_SIZE]; + byte hashSz; + byte sig[257]; + word32 sigSz; + + ret = wc_InitEccsiKey_ex(NULL, 32, ECC_SECP256R1, HEAP_HINT, INVALID_DEVID); + if (ret != BAD_FUNC_ARG) + return -10023; + ret = wc_InitEccsiKey_ex(NULL, 32, ECC_SECP256R1, HEAP_HINT, INVALID_DEVID); + if (ret != BAD_FUNC_ARG) + return -10024; + + ret = wc_InitEccsiKey(NULL, NULL, INVALID_DEVID); + if (ret != BAD_FUNC_ARG) + return -10025; + ret = wc_InitEccsiKey(NULL, HEAP_HINT, INVALID_DEVID); + if (ret != BAD_FUNC_ARG) + return -10026; + + wc_FreeEccsiKey(NULL); + + /* Create a valid key. */ + ret = wc_InitEccsiKey(key, NULL, INVALID_DEVID); + if (ret != 0) + return -10027; + + ret = wc_MakeEccsiKey(NULL, NULL); + if (ret != BAD_FUNC_ARG) + return -10028; + ret = wc_MakeEccsiKey(key, NULL); + if (ret != BAD_FUNC_ARG) + return -10029; + ret = wc_MakeEccsiKey(NULL, rng); + if (ret != BAD_FUNC_ARG) + return -10030; + + ret = wc_MakeEccsiPair(NULL, NULL, WC_HASH_TYPE_SHA256, NULL, 1, NULL, + NULL); + if (ret != BAD_FUNC_ARG) + return -10031; + ret = wc_MakeEccsiPair(key, rng, WC_HASH_TYPE_SHA256, id, 1, ssk, NULL); + if (ret != BAD_FUNC_ARG) + return -10032; + ret = wc_MakeEccsiPair(key, rng, WC_HASH_TYPE_SHA256, id, 1, NULL, pvt); + if (ret != BAD_FUNC_ARG) + return -10033; + ret = wc_MakeEccsiPair(key, rng, WC_HASH_TYPE_SHA256, NULL, 1, ssk, pvt); + if (ret != BAD_FUNC_ARG) + return -10034; + ret = wc_MakeEccsiPair(key, NULL, WC_HASH_TYPE_SHA256, id, 1, ssk, pvt); + if (ret != BAD_FUNC_ARG) + return -10035; + ret = wc_MakeEccsiPair(NULL, rng, WC_HASH_TYPE_SHA256, id, 1, ssk, pvt); + if (ret != BAD_FUNC_ARG) + return -10036; + /* No key set */ + ret = wc_MakeEccsiPair(key, rng, WC_HASH_TYPE_SHA256, id, 1, ssk, pvt); + if (ret != BAD_STATE_E) + return -10037; + + ret = wc_ValidateEccsiPair(NULL, WC_HASH_TYPE_SHA256, NULL, 1, NULL, NULL, + NULL); + if (ret != BAD_FUNC_ARG) + return -10038; + ret = wc_ValidateEccsiPair(key, WC_HASH_TYPE_SHA256, id, 1, ssk, pvt, + NULL); + if (ret != BAD_FUNC_ARG) + return -10039; + ret = wc_ValidateEccsiPair(key, WC_HASH_TYPE_SHA256, id, 1, ssk, NULL, + &valid); + if (ret != BAD_FUNC_ARG) + return -10040; + ret = wc_ValidateEccsiPair(key, WC_HASH_TYPE_SHA256, id, 1, NULL, pvt, + &valid); + if (ret != BAD_FUNC_ARG) + return -10041; + ret = wc_ValidateEccsiPair(key, WC_HASH_TYPE_SHA256, NULL, 1, ssk, pvt, + &valid); + if (ret != BAD_FUNC_ARG) + return -10042; + ret = wc_ValidateEccsiPair(NULL, WC_HASH_TYPE_SHA256, id, 1, ssk, pvt, + &valid); + if (ret != BAD_FUNC_ARG) + return -10043; + /* No key set */ + ret = wc_ValidateEccsiPair(key, WC_HASH_TYPE_SHA256, id, 1, ssk, pvt, + &valid); + if (ret != BAD_STATE_E) + return -10044; + + ret = wc_ValidateEccsiPvt(NULL, NULL, NULL); + if (ret != BAD_FUNC_ARG) + return -10045; + ret = wc_ValidateEccsiPvt(key, NULL, NULL); + if (ret != BAD_FUNC_ARG) + return -10046; + ret = wc_ValidateEccsiPvt(NULL, pvt, NULL); + if (ret != BAD_FUNC_ARG) + return -10047; + ret = wc_ValidateEccsiPvt(NULL, NULL, &valid); + if (ret != BAD_FUNC_ARG) + return -10048; + ret = wc_ValidateEccsiPvt(key, pvt, NULL); + if (ret != BAD_FUNC_ARG) + return -10049; + ret = wc_ValidateEccsiPvt(key, NULL, &valid); + if (ret != BAD_FUNC_ARG) + return -10050; + ret = wc_ValidateEccsiPvt(NULL, pvt, &valid); + if (ret != BAD_FUNC_ARG) + return -10051; + ret = wc_EncodeEccsiPair(NULL, NULL, NULL, data, NULL); + if (ret != BAD_FUNC_ARG) + return -10052; + ret = wc_EncodeEccsiPair(key, ssk, pvt, data, NULL); + if (ret != BAD_FUNC_ARG) + return -10053; + ret = wc_EncodeEccsiPair(key, ssk, NULL, data, &sz); + if (ret != BAD_FUNC_ARG) + return -10054; + ret = wc_EncodeEccsiPair(key, NULL, pvt, data, &sz); + if (ret != BAD_FUNC_ARG) + return -10055; + ret = wc_EncodeEccsiPair(NULL, ssk, pvt, data, &sz); + if (ret != BAD_FUNC_ARG) + return -10056; + /* No key created so no curve information. */ + ret = wc_EncodeEccsiPair(key, ssk, pvt, NULL, &sz); + if (ret != LENGTH_ONLY_E) + return -10057; + + ret = wc_EncodeEccsiSsk(NULL, NULL, data, NULL); + if (ret != BAD_FUNC_ARG) + return -10058; + ret = wc_EncodeEccsiSsk(key, ssk, data, NULL); + if (ret != BAD_FUNC_ARG) + return -10059; + ret = wc_EncodeEccsiSsk(key, NULL, data, &sz); + if (ret != BAD_FUNC_ARG) + return -10060; + ret = wc_EncodeEccsiSsk(NULL, ssk, data, &sz); + if (ret != BAD_FUNC_ARG) + return -10061; + + ret = wc_EncodeEccsiPvt(NULL, NULL, data, NULL, 1); + if (ret != BAD_FUNC_ARG) + return -10058; + ret = wc_EncodeEccsiPvt(key, pvt, data, NULL, 1); + if (ret != BAD_FUNC_ARG) + return -10059; + ret = wc_EncodeEccsiPvt(key, NULL, data, &sz, 1); + if (ret != BAD_FUNC_ARG) + return -10060; + ret = wc_EncodeEccsiPvt(NULL, pvt, data, &sz, 1); + if (ret != BAD_FUNC_ARG) + return -10061; + + ret = wc_DecodeEccsiPair(NULL, NULL, 0, NULL, NULL); + if (ret != BAD_FUNC_ARG) + return -10062; + ret = wc_DecodeEccsiPair(key, data, 0, ssk, NULL); + if (ret != BAD_FUNC_ARG) + return -10063; + ret = wc_DecodeEccsiPair(key, data, 0, NULL, pvt); + if (ret != BAD_FUNC_ARG) + return -10064; + ret = wc_DecodeEccsiPair(key, NULL, 0, ssk, pvt); + if (ret != BAD_FUNC_ARG) + return -10065; + ret = wc_DecodeEccsiPair(NULL, data, 0, ssk, pvt); + if (ret != BAD_FUNC_ARG) + return -10066; + + ret = wc_DecodeEccsiSsk(NULL, NULL, 0, NULL); + if (ret != BAD_FUNC_ARG) + return -10067; + ret = wc_DecodeEccsiSsk(key, data, 0, NULL); + if (ret != BAD_FUNC_ARG) + return -10068; + ret = wc_DecodeEccsiSsk(key, NULL, 0, ssk); + if (ret != BAD_FUNC_ARG) + return -10069; + ret = wc_DecodeEccsiSsk(NULL, data, 0, ssk); + if (ret != BAD_FUNC_ARG) + return -10070; + ret = wc_DecodeEccsiPvt(NULL, NULL, 0, NULL); + if (ret != BAD_FUNC_ARG) + return -10067; + ret = wc_DecodeEccsiPvt(key, data, 0, NULL); + if (ret != BAD_FUNC_ARG) + return -10068; + ret = wc_DecodeEccsiPvt(key, NULL, 0, pvt); + if (ret != BAD_FUNC_ARG) + return -10069; + ret = wc_DecodeEccsiPvt(NULL, data, 0, pvt); + if (ret != BAD_FUNC_ARG) + return -10070; + + ret = wc_DecodeEccsiPvtFromSig(NULL, NULL, 0, NULL); + if (ret != BAD_FUNC_ARG) + return -10067; + ret = wc_DecodeEccsiPvtFromSig(key, data, 0, NULL); + if (ret != BAD_FUNC_ARG) + return -10068; + ret = wc_DecodeEccsiPvtFromSig(key, NULL, 0, pvt); + if (ret != BAD_FUNC_ARG) + return -10069; + ret = wc_DecodeEccsiPvtFromSig(NULL, data, 0, pvt); + if (ret != BAD_FUNC_ARG) + return -10070; + + ret = wc_ExportEccsiKey(NULL, data, NULL); + if (ret != BAD_FUNC_ARG) + return -10071; + ret = wc_ExportEccsiKey(key, data, NULL); + if (ret != BAD_FUNC_ARG) + return -10072; + ret = wc_ExportEccsiKey(NULL, data, &sz); + if (ret != BAD_FUNC_ARG) + return -10073; + /* No key to export */ + ret = wc_ExportEccsiKey(key, NULL, &sz); + if (ret != BAD_STATE_E) + return -10074; + + ret = wc_ImportEccsiKey(NULL, NULL, 0); + if (ret != BAD_FUNC_ARG) + return -10075; + ret = wc_ImportEccsiKey(key, NULL, 0); + if (ret != BAD_FUNC_ARG) + return -10076; + ret = wc_ImportEccsiKey(NULL, data, 0); + if (ret != BAD_FUNC_ARG) + return -10077; + + ret = wc_ExportEccsiPrivateKey(NULL, data, NULL); + if (ret != BAD_FUNC_ARG) + return -10071; + ret = wc_ExportEccsiPrivateKey(key, data, NULL); + if (ret != BAD_FUNC_ARG) + return -10072; + ret = wc_ExportEccsiPrivateKey(NULL, data, &sz); + if (ret != BAD_FUNC_ARG) + return -10073; + /* No key to export */ + ret = wc_ExportEccsiPrivateKey(key, NULL, &sz); + if (ret != BAD_STATE_E) + return -10074; + + ret = wc_ImportEccsiPrivateKey(NULL, NULL, 0); + if (ret != BAD_FUNC_ARG) + return -10075; + ret = wc_ImportEccsiPrivateKey(key, NULL, 0); + if (ret != BAD_FUNC_ARG) + return -10076; + ret = wc_ImportEccsiPrivateKey(NULL, data, 0); + if (ret != BAD_FUNC_ARG) + return -10077; + ret = wc_ExportEccsiPublicKey(NULL, data, NULL, 1); + if (ret != BAD_FUNC_ARG) + return -10078; + ret = wc_ExportEccsiPublicKey(key, data, NULL, 1); + if (ret != BAD_FUNC_ARG) + return -10079; + ret = wc_ExportEccsiPublicKey(NULL, data, &sz, 1); + if (ret != BAD_FUNC_ARG) + return -10080; + /* No key to export */ + ret = wc_ExportEccsiPublicKey(key, data, &sz, 1); + if (ret != BAD_STATE_E) + return -10081; + + ret = wc_ImportEccsiPublicKey(NULL, NULL, 0, 1); + if (ret != BAD_FUNC_ARG) + return -10082; + ret = wc_ImportEccsiPublicKey(key, NULL, 0, 1); + if (ret != BAD_FUNC_ARG) + return -10083; + ret = wc_ImportEccsiPublicKey(NULL, data, 0, 1); + if (ret != BAD_FUNC_ARG) + return -10084; + + ret = wc_HashEccsiId(NULL, WC_HASH_TYPE_SHA256, NULL, 1, NULL, NULL, NULL); + if (ret != BAD_FUNC_ARG) + return -10085; + ret = wc_HashEccsiId(key, WC_HASH_TYPE_SHA256, id, 1, pvt, hash, NULL); + if (ret != BAD_FUNC_ARG) + return -10086; + ret = wc_HashEccsiId(key, WC_HASH_TYPE_SHA256, id, 1, pvt, NULL, &hashSz); + if (ret != BAD_FUNC_ARG) + return -10087; + ret = wc_HashEccsiId(key, WC_HASH_TYPE_SHA256, id, 1, NULL, hash, &hashSz); + if (ret != BAD_FUNC_ARG) + return -10088; + ret = wc_HashEccsiId(key, WC_HASH_TYPE_SHA256, NULL, 1, pvt, hash, + &hashSz); + if (ret != BAD_FUNC_ARG) + return -10089; + ret = wc_HashEccsiId(NULL, WC_HASH_TYPE_SHA256, id, 1, pvt, hash, &hashSz); + if (ret != BAD_FUNC_ARG) + return -10090; + ret = wc_HashEccsiId(key, WC_HASH_TYPE_SHA256, id, 1, pvt, hash, &hashSz); + if (ret != BAD_STATE_E) + return -10091; + + ret = wc_SetEccsiHash(NULL, NULL, 1); + if (ret != BAD_FUNC_ARG) + return -10090; + ret = wc_SetEccsiHash(key, NULL, 1); + if (ret != BAD_FUNC_ARG) + return -10090; + ret = wc_SetEccsiHash(NULL, hash, 1); + if (ret != BAD_FUNC_ARG) + return -10090; + + ret = wc_SetEccsiPair(NULL, NULL, NULL); + if (ret != BAD_FUNC_ARG) + return -10090; + ret = wc_SetEccsiPair(key, NULL, NULL); + if (ret != BAD_FUNC_ARG) + return -10090; + ret = wc_SetEccsiPair(NULL, ssk, NULL); + if (ret != BAD_FUNC_ARG) + return -10090; + ret = wc_SetEccsiPair(NULL, NULL, pvt); + if (ret != BAD_FUNC_ARG) + return -10090; + ret = wc_SetEccsiPair(key, ssk, NULL); + if (ret != BAD_FUNC_ARG) + return -10090; + ret = wc_SetEccsiPair(key, NULL, pvt); + if (ret != BAD_FUNC_ARG) + return -10090; + ret = wc_SetEccsiPair(NULL, ssk, pvt); + if (ret != BAD_FUNC_ARG) + return -10090; + ret = wc_SignEccsiHash(NULL, NULL, WC_HASH_TYPE_SHA256, NULL, 0, sig, NULL); + if (ret != BAD_FUNC_ARG) + return -10092; + ret = wc_SignEccsiHash(key, rng, WC_HASH_TYPE_SHA256, data, 0, sig, NULL); + if (ret != BAD_FUNC_ARG) + return -10093; + ret = wc_SignEccsiHash(key, rng, WC_HASH_TYPE_SHA256, NULL, 0, sig, + &sigSz); + if (ret != BAD_FUNC_ARG) + return -10096; + ret = wc_SignEccsiHash(key, NULL, WC_HASH_TYPE_SHA256, data, 0, sig, + &sigSz); + if (ret != BAD_FUNC_ARG) + return -10098; + ret = wc_SignEccsiHash(NULL, rng, WC_HASH_TYPE_SHA256, data, 0, sig, + &sigSz); + if (ret != BAD_FUNC_ARG) + return -10099; + /* Key not set. */ + ret = wc_SignEccsiHash(key, rng, WC_HASH_TYPE_SHA256, data, 0, NULL, + &sigSz); + if (ret != BAD_STATE_E) + return -10100; + + ret = wc_VerifyEccsiHash(NULL, WC_HASH_TYPE_SHA256, NULL, 0, NULL, 0, NULL); + if (ret != BAD_FUNC_ARG) + return -10101; + ret = wc_VerifyEccsiHash(key, WC_HASH_TYPE_SHA256, NULL, 0, NULL, 0, NULL); + if (ret != BAD_FUNC_ARG) + return -10101; + ret = wc_VerifyEccsiHash(NULL, WC_HASH_TYPE_SHA256, data, 0, NULL, 0, NULL); + if (ret != BAD_FUNC_ARG) + return -10101; + ret = wc_VerifyEccsiHash(NULL, WC_HASH_TYPE_SHA256, NULL, 0, sig, 0, NULL); + if (ret != BAD_FUNC_ARG) + return -10101; + ret = wc_VerifyEccsiHash(NULL, WC_HASH_TYPE_SHA256, NULL, 0, NULL, 0, + &valid); + if (ret != BAD_FUNC_ARG) + return -10101; + ret = wc_VerifyEccsiHash(key, WC_HASH_TYPE_SHA256, data, 0, sig, 0, NULL); + if (ret != BAD_FUNC_ARG) + return -10102; + ret = wc_VerifyEccsiHash(key, WC_HASH_TYPE_SHA256, data, 0, NULL, 0, + &valid); + if (ret != BAD_FUNC_ARG) + return -10103; + ret = wc_VerifyEccsiHash(key, WC_HASH_TYPE_SHA256, NULL, 0, sig, 0, + &valid); + if (ret != BAD_FUNC_ARG) + return -10104; + ret = wc_VerifyEccsiHash(NULL, WC_HASH_TYPE_SHA256, data, 0, sig, 0, + &valid); + if (ret != BAD_FUNC_ARG) + return -10106; + ret = wc_VerifyEccsiHash(key, WC_HASH_TYPE_SHA256, data, 0, sig, 0, + &valid); + if (ret != BAD_STATE_E) + return -10106; + + ret = wc_SetEccsiPair(key, ssk, pvt); + if (ret != 0) + return -10107; + /* Identity hash not set. */ + ret = wc_SignEccsiHash(key, rng, WC_HASH_TYPE_SHA256, data, 0, NULL, + &sigSz); + if (ret != BAD_STATE_E) + return -10108; + + wc_FreeEccsiKey(key); + + return 0; +} + +/* RFC 6507: Appendix A */ +static int eccsi_kat_verify_test(EccsiKey* key, ecc_point* pvt) +{ + int ret; + int verified; + const byte msg[] = { 0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x00 }; + word32 msgSz = sizeof(msg); + byte hash[WC_SHA256_DIGEST_SIZE]; + byte hashSz = WC_SHA256_DIGEST_SIZE; + static const byte id[] = { + 0x32, 0x30, 0x31, 0x31, 0x2D, 0x30, 0x32, 0x00, + 0x74, 0x65, 0x6C, 0x3A, 0x2B, 0x34, 0x34, 0x37, + 0x37, 0x30, 0x30, 0x39, 0x30, 0x30, 0x31, 0x32, + 0x33, 0x00 + }; + word32 idSz = sizeof(id); + static const byte sig[] = { + 0x26, 0x9D, 0x4C, 0x8F, 0xDE, 0xB6, 0x6A, 0x74, + 0xE4, 0xEF, 0x8C, 0x0D, 0x5D, 0xCC, 0x59, 0x7D, + 0xDF, 0xE6, 0x02, 0x9C, 0x2A, 0xFF, 0xC4, 0x93, + 0x60, 0x08, 0xCD, 0x2C, 0xC1, 0x04, 0x5D, 0x81, + 0xE0, 0x9B, 0x52, 0x8D, 0x0E, 0xF8, 0xD6, 0xDF, + 0x1A, 0xA3, 0xEC, 0xBF, 0x80, 0x11, 0x0C, 0xFC, + 0xEC, 0x9F, 0xC6, 0x82, 0x52, 0xCE, 0xBB, 0x67, + 0x9F, 0x41, 0x34, 0x84, 0x69, 0x40, 0xCC, 0xFD, + 0x04, + 0x75, 0x8A, 0x14, 0x27, 0x79, 0xBE, 0x89, 0xE8, + 0x29, 0xE7, 0x19, 0x84, 0xCB, 0x40, 0xEF, 0x75, + 0x8C, 0xC4, 0xAD, 0x77, 0x5F, 0xC5, 0xB9, 0xA3, + 0xE1, 0xC8, 0xED, 0x52, 0xF6, 0xFA, 0x36, 0xD9, + 0xA7, 0x9D, 0x24, 0x76, 0x92, 0xF4, 0xED, 0xA3, + 0xA6, 0xBD, 0xAB, 0x77, 0xD6, 0xAA, 0x64, 0x74, + 0xA4, 0x64, 0xAE, 0x49, 0x34, 0x66, 0x3C, 0x52, + 0x65, 0xBA, 0x70, 0x18, 0xBA, 0x09, 0x1F, 0x79 + }; + word32 sigSz = sizeof(sig); + static const byte pubData[] = { + 0x50, 0xD4, 0x67, 0x0B, 0xDE, 0x75, 0x24, 0x4F, + 0x28, 0xD2, 0x83, 0x8A, 0x0D, 0x25, 0x55, 0x8A, + 0x7A, 0x72, 0x68, 0x6D, 0x45, 0x22, 0xD4, 0xC8, + 0x27, 0x3F, 0xB6, 0x44, 0x2A, 0xEB, 0xFA, 0x93, + 0xDB, 0xDD, 0x37, 0x55, 0x1A, 0xFD, 0x26, 0x3B, + 0x5D, 0xFD, 0x61, 0x7F, 0x39, 0x60, 0xC6, 0x5A, + 0x8C, 0x29, 0x88, 0x50, 0xFF, 0x99, 0xF2, 0x03, + 0x66, 0xDC, 0xE7, 0xD4, 0x36, 0x72, 0x17, 0xF4 + }; + static const byte expHash[] = { + 0x49, 0x0f, 0x3f, 0xeb, 0xbc, 0x1c, 0x90, 0x2f, + 0x62, 0x89, 0x72, 0x3d, 0x7f, 0x8c, 0xbf, 0x79, + 0xdb, 0x88, 0x93, 0x08, 0x49, 0xd1, 0x9f, 0x38, + 0xf0, 0x29, 0x5b, 0x5c, 0x27, 0x6c, 0x14, 0xd1 + }; + + ret = wc_ImportEccsiPublicKey(key, pubData, sizeof(pubData), 0); + if (ret != 0) + return -10108; + + ret = wc_DecodeEccsiPvtFromSig(key, sig, sigSz, pvt); + if (ret != 0) + return -10109; + + ret = wc_HashEccsiId(key, WC_HASH_TYPE_SHA256, id, idSz, pvt, hash, + &hashSz); + if (ret != 0) + return -10112; + if (hashSz != sizeof(expHash)) + return -10113; + if (XMEMCMP(hash, expHash, hashSz) != 0) + return -10114; + + ret = wc_SetEccsiHash(key, hash, hashSz); + if (ret != 0) + return -10112; + + ret = wc_VerifyEccsiHash(key, WC_HASH_TYPE_SHA256, msg, msgSz, sig, sigSz, + &verified); + if (ret != 0) + return -10115; + if (!verified) + return -10116; + + return 0; +} +static int eccsi_enc_dec_pair_test(EccsiKey* priv, mp_int* ssk, ecc_point* pvt) +{ + int ret; + byte data[32 * 3]; + word32 sz; + mp_int decSsk; + ecc_point* decPvt = NULL; + + ret = mp_init(&decSsk); + if (ret != 0) + return -10117; + + decPvt = wc_ecc_new_point(); + if (ret != 0) + return -10118; + + ret = wc_EncodeEccsiPair(priv, ssk, pvt, NULL, &sz); + if (ret != LENGTH_ONLY_E) + return -10119; + if (sz != 32 * 3) + return -10120; + ret = wc_EncodeEccsiPair(priv, ssk, pvt, data, &sz); + if (ret != 0) + return -10121; + if (sz != 32* 3) + return -10122; + ret = wc_DecodeEccsiPair(priv, data, sz, &decSsk, decPvt); + if (ret != 0) + return -10123; + if (mp_cmp(ssk, &decSsk) != MP_EQ) + return -10124; + if (wc_ecc_cmp_point(pvt, decPvt) != MP_EQ) + return -10125; + + ret = wc_EncodeEccsiSsk(priv, ssk, NULL, &sz); + if (ret != LENGTH_ONLY_E) + return -10119; + if (sz != 32) + return -10120; + ret = wc_EncodeEccsiSsk(priv, ssk, data, &sz); + if (ret != 0) + return -10121; + if (sz != 32) + return -10122; + ret = wc_DecodeEccsiSsk(priv, data, sz, &decSsk); + if (ret != 0) + return -10123; + if (mp_cmp(ssk, &decSsk) != MP_EQ) + return -10124; + + ret = wc_EncodeEccsiPvt(priv, pvt, NULL, &sz, 1); + if (ret != LENGTH_ONLY_E) + return -10126; + if (sz != 32 * 2) + return -10127; + ret = wc_EncodeEccsiPvt(priv, pvt, data, &sz, 1); + if (ret != 0) + return -10128; + if (sz != 32 * 2) + return -10129; + ret = wc_DecodeEccsiPvt(priv, data, sz, decPvt); + if (ret != 0) + return -10130; + if (wc_ecc_cmp_point(pvt, decPvt) != MP_EQ) + return -10131; + sz = sizeof(data); + ret = wc_EncodeEccsiPvt(priv, pvt, data, &sz, 0); + if (ret != 0) + return -10128; + if (sz != 32 * 2 + 1) + return -10129; + ret = wc_DecodeEccsiPvt(priv, data, sz, decPvt); + if (ret != 0) + return -10130; + if (wc_ecc_cmp_point(pvt, decPvt) != MP_EQ) + return -10131; + + wc_ecc_del_point(decPvt); + mp_free(&decSsk); + + return 0; +} + +static int eccsi_imp_exp_key_test(EccsiKey* priv) +{ + int ret; + byte data[32 * 3]; + byte out[32 * 3]; + word32 sz; + + ret = wc_ExportEccsiKey(priv, NULL, &sz); + if (ret != LENGTH_ONLY_E) + return -10132; + if (sz != 32 * 3) + return -10133; + ret = wc_ExportEccsiKey(priv, data, &sz); + if (ret != 0) + return -10134; + ret = wc_ImportEccsiKey(priv, data, sz); + if (ret != 0) + return -10135; + ret = wc_ExportEccsiKey(priv, NULL, &sz); + if (ret != LENGTH_ONLY_E) + return -10132; + if (sz != 32 * 3) + return -10143; + ret = wc_ExportEccsiKey(priv, out, &sz); + if (ret != 0) + return -10144; + if (sz != 32 * 3) + return -10145; + if (XMEMCMP(data, out, sz) != 0) + return -10146; + + ret = wc_ExportEccsiPrivateKey(priv, NULL, &sz); + if (ret != LENGTH_ONLY_E) + return -10156; + if (sz != 32) + return -10157; + ret = wc_ExportEccsiPrivateKey(priv, data, &sz); + if (ret != 0) + return -10158; + ret = wc_ImportEccsiPrivateKey(priv, data, sz); + if (ret != 0) + return -10159; + ret = wc_ExportEccsiPrivateKey(priv, NULL, &sz); + if (ret != LENGTH_ONLY_E) + return -10152; + if (sz != 32) + return -10163; + ret = wc_ExportEccsiPrivateKey(priv, out, &sz); + if (ret != 0) + return -10164; + if (sz != 32) + return -10165; + if (XMEMCMP(data, out, sz) != 0) + return -10166; + + return 0; +} + +static int eccsi_imp_exp_pubkey_test(EccsiKey* key1, EccsiKey* key2) +{ + int ret; + byte data[32 * 2 + 1]; + byte pubData[32 * 2 + 1]; + word32 sz; + + ret = wc_ExportEccsiPublicKey(key1, NULL, &sz, 1); + if (ret != LENGTH_ONLY_E) + return -10136; + if (sz != 32 * 2) + return -10137; + + ret = wc_ExportEccsiPublicKey(key1, data, &sz, 1); + if (ret != 0) + return -10138; + + ret = wc_ImportEccsiPublicKey(key2, data, sz, 1); + if (ret != 0) + return -10139; + sz = sizeof(pubData); + ret = wc_ExportEccsiPublicKey(key2, pubData, &sz, 1); + if (ret != 0) + return -10140; + if (sz != 32 * 2) + return -10141; + if (XMEMCMP(data, pubData, sz) != 0) + return -10142; + + sz = sizeof(pubData); + ret = wc_ExportEccsiPublicKey(key2, pubData, &sz, 0); + if (ret != 0) + return -10140; + if (sz != 32 * 2 + 1) + return -10141; + if (pubData[0] != 0x04) + return -10140; + if (XMEMCMP(pubData + 1, data, sz - 1) != 0) + return -10142; + ret = wc_ImportEccsiPublicKey(key2, pubData, sz, 0); + if (ret != 0) + return -10139; + + return 0; +} + +static int eccsi_make_key_test(EccsiKey* priv, EccsiKey* pub, WC_RNG* rng, + mp_int* ssk, ecc_point* pvt) +{ + int ret; + char mail[] = "test@wolfssl.com"; + byte* id = (byte*)mail; + word32 idSz = (word32) XSTRLEN(mail); + int valid; + + ret = wc_MakeEccsiKey(priv, rng); + if (ret != 0) + return -10143; + + ret = eccsi_imp_exp_key_test(priv); + if (ret < 0) + return ret; + + ret = eccsi_imp_exp_pubkey_test(priv, pub); + if (ret < 0) + return ret; + + ret = wc_MakeEccsiPair(priv, rng, WC_HASH_TYPE_SHA256, id, idSz, ssk, pvt); + if (ret != 0) + return -10144; + + ret = wc_ValidateEccsiPair(pub, WC_HASH_TYPE_SHA256, id, idSz, ssk, pvt, + &valid); + if (ret != 0) + return -10145; + if (!valid) + return -10146; + + ret = eccsi_enc_dec_pair_test(priv, ssk, pvt); + if (ret != 0) + return ret; + + return 0; +} + +static int eccsi_sign_verify_test(EccsiKey* priv, EccsiKey* pub, WC_RNG* rng, + mp_int* ssk, ecc_point* pvt) +{ + int ret; + byte hashPriv[WC_MAX_DIGEST_SIZE]; + byte hashPub[WC_MAX_DIGEST_SIZE]; + byte hashSz; + byte sig[144]; + word32 sigSz; + int verified, valid; + char mail[] = "test@wolfssl.com"; + byte* id = (byte*)mail; + word32 idSz = (word32) XSTRLEN(mail); + byte msg[] = { 0x00 }; + word32 msgSz = sizeof(msg); + + ret = wc_HashEccsiId(priv, WC_HASH_TYPE_SHA256, id, idSz, pvt, hashPriv, + &hashSz); + if (ret != 0) + return -10147; + if (hashSz != 32) + return -10148; + ret = wc_HashEccsiId(priv, WC_HASH_TYPE_SHA256, id, idSz, pvt, hashPub, + &hashSz); + if (ret != 0) + return -10149; + if (hashSz != 32) + return -10150; + + if (XMEMCMP(hashPriv, hashPub, hashSz) != 0) + return -10151; + + ret = wc_SetEccsiHash(priv, hashPriv, hashSz); + if (ret != 0) + return -10149; + ret = wc_SetEccsiPair(priv, ssk, pvt); + if (ret != 0) + return -10149; + + ret = wc_SignEccsiHash(priv, rng, WC_HASH_TYPE_SHA256, msg, msgSz, NULL, + &sigSz); + if (ret != LENGTH_ONLY_E) + return -10152; + if (sigSz != 129) + return -10153; + ret = wc_SignEccsiHash(priv, rng, WC_HASH_TYPE_SHA256, msg, msgSz, sig, + &sigSz); + if (ret != 0) + return -10154; + + ret = wc_SetEccsiHash(pub, hashPub, hashSz); + if (ret != 0) + return -10149; + + ret = wc_VerifyEccsiHash(pub, WC_HASH_TYPE_SHA256, msg, msgSz, sig, sigSz, + &verified); + if (ret != 0) + return -10155; + if (!verified) + return -10156; + + /* Check that changing HS results in verification failure. */ + hashPub[0] ^= 0x80; + ret = wc_SetEccsiHash(pub, hashPub, hashSz); + if (ret != 0) + return -10149; + ret = wc_VerifyEccsiHash(pub, WC_HASH_TYPE_SHA256, msg, msgSz, sig, sigSz, + &verified); + if (ret != 0) + return -10157; + if (verified) + return -10158; + hashPub[0] ^= 0x80; + ret = wc_SetEccsiHash(pub, hashPub, hashSz); + if (ret != 0) + return -10149; + + /* Check that changing msg results in verification failure. */ + msg[0] ^= 0x80; + ret = wc_VerifyEccsiHash(pub, WC_HASH_TYPE_SHA256, msg, msgSz, sig, sigSz, + &verified); + if (ret != 0) + return -10159; + if (verified) + return -10160; + msg[0] ^= 0x80; + /* Check that changing signature results in verification failure. */ + sig[0] ^= 0x80; + ret = wc_VerifyEccsiHash(pub, WC_HASH_TYPE_SHA256, msg, msgSz, sig, sigSz, + &verified); + if (ret != 0) + return -10161; + if (verified) + return -10162; + sig[0] ^= 0x80; + + /* Check that key state hasn't been invalidated. */ + ret = wc_VerifyEccsiHash(pub, WC_HASH_TYPE_SHA256, msg, msgSz, sig, sigSz, + &verified); + if (ret != 0) + return -10163; + if (!verified) + return -10164; + + /* Check that verifying with the private key works. */ + ret = wc_VerifyEccsiHash(priv, WC_HASH_TYPE_SHA256, msg, msgSz, sig, sigSz, + &verified); + if (ret != 0) + return -10165; + if (!verified) + return -10166; + + /* Check that the KPAK is converted from montogmery form. */ + ret = eccsi_imp_exp_key_test(priv); + if (ret != 0) + return ret; + + /* Check that KPAK can converted to Montogmery form again. */ + ret = wc_VerifyEccsiHash(priv, WC_HASH_TYPE_SHA256, msg, msgSz, sig, sigSz, + &verified); + if (ret != 0) + return -10167; + if (!verified) + return -10168; + + /* Check that the KPAK is converted from montogmery form. */ + ret = wc_ValidateEccsiPair(pub, WC_HASH_TYPE_SHA256, id, idSz, ssk, pvt, + &valid); + if (ret != 0) + return -10169; + if (!valid) + return -10170; + + /* Check that KPAK can converted to Montogmery form again. */ + ret = wc_VerifyEccsiHash(priv, WC_HASH_TYPE_SHA256, msg, msgSz, sig, sigSz, + &verified); + if (ret != 0) + return -10171; + if (!verified) + return -10172; + + /* Check that the KPAK is converted from montogmery form. */ + ret = eccsi_imp_exp_pubkey_test(priv, pub); + if (ret != 0) + return ret; + + return 0; +} + +int eccsi_test(void) +{ + int ret; + WC_RNG rng; + EccsiKey* priv; + EccsiKey* pub; + mp_int* ssk; + ecc_point* pvt; + + priv = XMALLOC(sizeof(EccsiKey), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (priv == NULL) { + return -10205; + } + pub = XMALLOC(sizeof(EccsiKey), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (pub == NULL) { + XFREE(priv, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + return -10206; + } + ssk = XMALLOC(sizeof(mp_int), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (ssk == NULL) { + XFREE(pub, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(priv, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + return -10207; + } + +#ifndef HAVE_FIPS + ret = wc_InitRng_ex(&rng, HEAP_HINT, devId); +#else + ret = wc_InitRng(&rng); +#endif + if (ret != 0) + return -10200; + + pvt = wc_ecc_new_point(); + if (pvt == NULL) + return -10201; + ret = mp_init(ssk); + if (ret != 0) + return -10202; + + ret = eccsi_api_test(&rng, priv, ssk, pvt); + if (ret != 0) + return ret; + + ret = wc_InitEccsiKey(pub, HEAP_HINT, INVALID_DEVID); + if (ret != 0) + return -10203; + + ret = wc_InitEccsiKey(priv, HEAP_HINT, INVALID_DEVID); + if (ret != 0) + return -10204; + + ret = eccsi_kat_verify_test(pub, pvt); + if (ret != 0) + return ret; + + ret = eccsi_make_key_test(priv, pub, &rng, ssk, pvt); + if (ret != 0) + return ret; + + ret = eccsi_sign_verify_test(priv, pub, &rng, ssk, pvt); + if (ret != 0) + return ret; + + wc_FreeEccsiKey(priv); + wc_FreeEccsiKey(pub); + mp_free(ssk); + wc_ecc_del_point(pvt); + wc_FreeRng(&rng); + XFREE(ssk, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pub, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(priv, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + + return 0; +} +#endif /* WOLFCRYPT_HAVE_ECCSI */ + +#ifdef WOLFCRYPT_HAVE_SAKKE +static int sakke_api_test(WC_RNG* rng, SakkeKey* key, ecc_point* rsk) +{ + int ret; + byte id[1] = { 0x00 }; + int valid; + byte data[256]; + word32 sz; + byte auth[257]; + word16 authSz; + byte ssv[256]; + word16 ssvSz; + word32 len; + + ret = wc_InitSakkeKey_ex(NULL, 128, ECC_SAKKE_1, NULL, INVALID_DEVID); + if (ret != BAD_FUNC_ARG) + return -10205; + ret = wc_InitSakkeKey_ex(NULL, 128, ECC_SAKKE_1, HEAP_HINT, INVALID_DEVID); + if (ret != BAD_FUNC_ARG) + return -10206; + + wc_FreeSakkeKey(NULL); + + XMEMSET(key, 0, sizeof(*key)); + wc_FreeSakkeKey(key); + + ret = wc_InitSakkeKey_ex(key, 128, ECC_SAKKE_1, HEAP_HINT, INVALID_DEVID); + if (ret != 0) + return -10207; + + ret = wc_MakeSakkeKey(NULL, NULL); + if (ret != BAD_FUNC_ARG) + return -10208; + ret = wc_MakeSakkeKey(key, NULL); + if (ret != BAD_FUNC_ARG) + return -10209; + ret = wc_MakeSakkeKey(NULL, rng); + if (ret != BAD_FUNC_ARG) + return -10210; + + ret = wc_MakeSakkePublicKey(NULL, NULL); + if (ret != BAD_FUNC_ARG) + return -10211; + ret = wc_MakeSakkePublicKey(key, NULL); + if (ret != BAD_FUNC_ARG) + return -10212; + ret = wc_MakeSakkePublicKey(NULL, rsk); + if (ret != BAD_FUNC_ARG) + return -10213; + + ret = wc_MakeSakkeRsk(NULL, NULL, 1, NULL); + if (ret != BAD_FUNC_ARG) + return -10214; + ret = wc_MakeSakkeRsk(key, id, 1, NULL); + if (ret != BAD_FUNC_ARG) + return -10215; + ret = wc_MakeSakkeRsk(key, NULL, 1, rsk); + if (ret != BAD_FUNC_ARG) + return -10216; + ret = wc_MakeSakkeRsk(NULL, id, 1, rsk); + if (ret != BAD_FUNC_ARG) + return -10217; + + ret = wc_ValidateSakkeRsk(NULL, NULL, 1, NULL, NULL); + if (ret != BAD_FUNC_ARG) + return -10218; + ret = wc_ValidateSakkeRsk(key, id, 1, rsk, NULL); + if (ret != BAD_FUNC_ARG) + return -10219; + ret = wc_ValidateSakkeRsk(NULL, id, 1, rsk, &valid); + if (ret != BAD_FUNC_ARG) + return -10220; + + ret = wc_ExportSakkeKey(NULL, NULL, NULL); + if (ret != BAD_FUNC_ARG) + return -10221; + ret = wc_ExportSakkeKey(key, data, NULL); + if (ret != BAD_FUNC_ARG) + return -10222; + ret = wc_ExportSakkeKey(NULL, data, &sz); + if (ret != BAD_FUNC_ARG) + return -10223; + + ret = wc_ImportSakkeKey(NULL, NULL, 1); + if (ret != BAD_FUNC_ARG) + return -10224; + ret = wc_ImportSakkeKey(key, NULL, 1); + if (ret != BAD_FUNC_ARG) + return -10225; + ret = wc_ImportSakkeKey(NULL, data, 1); + if (ret != BAD_FUNC_ARG) + return -10226; + + ret = wc_ExportSakkePrivateKey(NULL, NULL, NULL); + if (ret != BAD_FUNC_ARG) + return -10227; + ret = wc_ExportSakkePrivateKey(key, data, NULL); + if (ret != BAD_FUNC_ARG) + return -10228; + ret = wc_ExportSakkePrivateKey(NULL, data, &sz); + if (ret != BAD_FUNC_ARG) + return -10229; + + ret = wc_ImportSakkePrivateKey(NULL, NULL, 1); + if (ret != BAD_FUNC_ARG) + return -10230; + ret = wc_ImportSakkePrivateKey(key, NULL, 1); + if (ret != BAD_FUNC_ARG) + return -10231; + ret = wc_ImportSakkePrivateKey(NULL, data, 1); + if (ret != BAD_FUNC_ARG) + return -10232; + + sz = sizeof(data); + ret = wc_EncodeSakkeRsk(NULL, NULL, data, NULL, 1); + if (ret != BAD_FUNC_ARG) + return -10233; + ret = wc_EncodeSakkeRsk(key, rsk, data, NULL, 1); + if (ret != BAD_FUNC_ARG) + return -10234; + ret = wc_EncodeSakkeRsk(key, NULL, data, &sz, 1); + if (ret != BAD_FUNC_ARG) + return -10235; + ret = wc_EncodeSakkeRsk(NULL, rsk, data, &sz, 1); + if (ret != BAD_FUNC_ARG) + return -10236; + + ret = wc_DecodeSakkeRsk(NULL, NULL, sz, NULL); + if (ret != BAD_FUNC_ARG) + return -10237; + ret = wc_DecodeSakkeRsk(key, data, sz, NULL); + if (ret != BAD_FUNC_ARG) + return -10238; + ret = wc_DecodeSakkeRsk(key, NULL, sz, rsk); + if (ret != BAD_FUNC_ARG) + return -10239; + ret = wc_DecodeSakkeRsk(NULL, data, sz, rsk); + if (ret != BAD_FUNC_ARG) + return -10240; + + ret = wc_ImportSakkeRsk(NULL, NULL, sz); + if (ret != BAD_FUNC_ARG) + return -10237; + ret = wc_ImportSakkeRsk(key, NULL, sz); + if (ret != BAD_FUNC_ARG) + return -10237; + ret = wc_ImportSakkeRsk(NULL, data, sz); + if (ret != BAD_FUNC_ARG) + return -10237; + ret = wc_ImportSakkeRsk(key, data, 1); + if (ret != BUFFER_E) + return -10237; + + ret = wc_GenerateSakkeRskTable(NULL, NULL, data, NULL); + if (ret != BAD_FUNC_ARG) + return -10241; + ret = wc_GenerateSakkeRskTable(key, NULL, data, NULL); + if (ret != BAD_FUNC_ARG) + return -10242; + ret = wc_GenerateSakkeRskTable(NULL, rsk, data, NULL); + if (ret != BAD_FUNC_ARG) + return -10243; + ret = wc_GenerateSakkeRskTable(NULL, NULL, data, &len); + if (ret != BAD_FUNC_ARG) + return -10244; + ret = wc_GenerateSakkeRskTable(key, rsk, data, NULL); + if (ret != BAD_FUNC_ARG) + return -10245; + ret = wc_GenerateSakkeRskTable(key, NULL, data, &len); + if (ret != BAD_FUNC_ARG) + return -10246; + ret = wc_GenerateSakkeRskTable(NULL, rsk, data, &len); + if (ret != BAD_FUNC_ARG) + return -10247; + ret = wc_GenerateSakkeRskTable(key, rsk, NULL, &len); + if (ret != LENGTH_ONLY_E) + return -10248; + len--; + ret = wc_GenerateSakkeRskTable(key, rsk, data, &len); + if (ret != BUFFER_E) + return -10249; + + ret = wc_ExportSakkePublicKey(NULL, data, NULL, 1); + if (ret != BAD_FUNC_ARG) + return -10250; + ret = wc_ExportSakkePublicKey(key, data, NULL, 1); + if (ret != BAD_FUNC_ARG) + return -10251; + ret = wc_ExportSakkePublicKey(NULL, data, &sz, 1); + if (ret != BAD_FUNC_ARG) + return -10252; + + ret = wc_ImportSakkePublicKey(NULL, NULL, sz, 1); + if (ret != BAD_FUNC_ARG) + return -10253; + ret = wc_ImportSakkePublicKey(key, NULL, sz, 1); + if (ret != BAD_FUNC_ARG) + return -10254; + ret = wc_ImportSakkePublicKey(NULL, data, sz, 1); + if (ret != BAD_FUNC_ARG) + return -10255; + + ret = wc_GetSakkeAuthSize(NULL, NULL); + if (ret != BAD_FUNC_ARG) + return -10256; + ret = wc_GetSakkeAuthSize(key, NULL); + if (ret != BAD_FUNC_ARG) + return -10257; + ret = wc_GetSakkeAuthSize(NULL, &authSz); + if (ret != BAD_FUNC_ARG) + return -10258; + + ret = wc_MakeSakkePointI(NULL, NULL, SAKKE_ID_MAX_SIZE + 1); + if (ret != BAD_FUNC_ARG) + return -10259; + ret = wc_MakeSakkePointI(key, NULL, SAKKE_ID_MAX_SIZE + 1); + if (ret != BAD_FUNC_ARG) + return -10260; + ret = wc_MakeSakkePointI(NULL, id, 1); + if (ret != BAD_FUNC_ARG) + return -10261; + ret = wc_MakeSakkePointI(NULL, NULL, 1); + if (ret != BAD_FUNC_ARG) + return -10262; + ret = wc_MakeSakkePointI(key, id, SAKKE_ID_MAX_SIZE + 1); + if (ret != BAD_FUNC_ARG) + return -10263; + ret = wc_MakeSakkePointI(key, NULL, 1); + if (ret != BAD_FUNC_ARG) + return -10264; + ret = wc_MakeSakkePointI(NULL, id, 1); + if (ret != BAD_FUNC_ARG) + return -10265; + + ret = wc_GenerateSakkePointITable(NULL, data, NULL); + if (ret != BAD_FUNC_ARG) + return -10266; + ret = wc_GenerateSakkePointITable(key, data, NULL); + if (ret != BAD_FUNC_ARG) + return -10267; + ret = wc_GenerateSakkePointITable(NULL, data, &len); + if (ret != BAD_FUNC_ARG) + return -10268; + ret = wc_GenerateSakkePointITable(key, NULL, &len); + if (ret != LENGTH_ONLY_E) + return -10269; + len--; + ret = wc_GenerateSakkePointITable(key, data, &len); + if (ret != BUFFER_E) + return -10270; + + ret = wc_SetSakkePointITable(NULL, NULL, 1); + if (ret != BAD_FUNC_ARG) + return -10271; + ret = wc_SetSakkePointITable(key, NULL, 1); + if (ret != BAD_FUNC_ARG) + return -10272; + ret = wc_SetSakkePointITable(NULL, data, 1); + if (ret != BAD_FUNC_ARG) + return -10273; + ret = wc_SetSakkePointITable(key, data, 1); + if (ret != BUFFER_E) + return -10274; + + ret = wc_ClearSakkePointITable(NULL); + if (ret != BAD_FUNC_ARG) + return -10275; + + ret = wc_GetSakkePointI(NULL, data, NULL); + if (ret != BAD_FUNC_ARG) + return -10276; + ret = wc_GetSakkePointI(key, data, NULL); + if (ret != BAD_FUNC_ARG) + return -10277; + ret = wc_GetSakkePointI(NULL, data, &sz); + if (ret != BAD_FUNC_ARG) + return -10278; + sz = 1; + ret = wc_GetSakkePointI(key, data, &sz); + if (ret != BUFFER_E) + return -10279; + + sz = 256; + ret = wc_SetSakkePointI(NULL, NULL, 1, NULL, sz); + if (ret != BAD_FUNC_ARG) + return -10280; + ret = wc_SetSakkePointI(key, NULL, 1, NULL, sz); + if (ret != BAD_FUNC_ARG) + return -10281; + ret = wc_SetSakkePointI(NULL, id, 1, NULL, sz); + if (ret != BAD_FUNC_ARG) + return -10282; + ret = wc_SetSakkePointI(NULL, NULL, 1, data, sz); + if (ret != BAD_FUNC_ARG) + return -10283; + ret = wc_SetSakkePointI(key, id, 1, NULL, sz); + if (ret != BAD_FUNC_ARG) + return -10284; + ret = wc_SetSakkePointI(key, NULL, 1, data, sz); + if (ret != BAD_FUNC_ARG) + return -10285; + ret = wc_SetSakkePointI(NULL, id, 1, data, sz); + if (ret != BAD_FUNC_ARG) + return -10286; + ret = wc_SetSakkePointI(key, id, SAKKE_ID_MAX_SIZE + 1, data, sz); + if (ret != BUFFER_E) + return -10287; + ret = wc_SetSakkePointI(key, id, 1, data, sz - 1); + if (ret != BUFFER_E) + return -10288; + + ret = wc_SetSakkeIdentity(NULL, NULL, 1); + if (ret != BAD_FUNC_ARG) + return -10286; + ret = wc_SetSakkeIdentity(key, NULL, 1); + if (ret != BAD_FUNC_ARG) + return -10286; + ret = wc_SetSakkeIdentity(NULL, id, 1); + if (ret != BAD_FUNC_ARG) + return -10286; + + ssvSz = sizeof(ssv); + ret = wc_MakeSakkeEncapsulatedSSV(NULL, WC_HASH_TYPE_SHA256, NULL, ssvSz, + auth, NULL); + if (ret != BAD_FUNC_ARG) + return -10289; + ret = wc_MakeSakkeEncapsulatedSSV(key, WC_HASH_TYPE_SHA256, NULL, ssvSz, + auth, NULL); + if (ret != BAD_FUNC_ARG) + return -10290; + ret = wc_MakeSakkeEncapsulatedSSV(NULL, WC_HASH_TYPE_SHA256, ssv, ssvSz, + auth, NULL); + if (ret != BAD_FUNC_ARG) + return -10291; + ret = wc_MakeSakkeEncapsulatedSSV(NULL, WC_HASH_TYPE_SHA256, NULL, ssvSz, + auth, &authSz); + if (ret != BAD_FUNC_ARG) + return -10292; + ret = wc_MakeSakkeEncapsulatedSSV(key, WC_HASH_TYPE_SHA256, ssv, ssvSz, + auth, NULL); + if (ret != BAD_FUNC_ARG) + return -10293; + ret = wc_MakeSakkeEncapsulatedSSV(key, WC_HASH_TYPE_SHA256, NULL, ssvSz, + auth, &authSz); + if (ret != BAD_FUNC_ARG) + return -10294; + ret = wc_MakeSakkeEncapsulatedSSV(NULL, WC_HASH_TYPE_SHA256, ssv, ssvSz, + auth, &authSz); + if (ret != BAD_FUNC_ARG) + return -10295; + ret = wc_MakeSakkeEncapsulatedSSV(key, WC_HASH_TYPE_SHA256, ssv, ssvSz, + auth, &authSz); + if (ret != BAD_STATE_E) + return -10295; + + ret = wc_GenerateSakkeSSV(NULL, NULL, data, NULL); + if (ret != BAD_FUNC_ARG) + return -10296; + ret = wc_GenerateSakkeSSV(key, rng, data, NULL); + if (ret != BAD_FUNC_ARG) + return -10297; + ret = wc_GenerateSakkeSSV(key, NULL, data, &ssvSz); + if (ret != BAD_FUNC_ARG) + return -10298; + ret = wc_GenerateSakkeSSV(NULL, rng, data, &ssvSz); + if (ret != BAD_FUNC_ARG) + return -10299; + + ret = wc_SetSakkeRsk(NULL, NULL, data, 1); + if (ret != BAD_FUNC_ARG) + return -10286; + ret = wc_SetSakkeRsk(key, NULL, data, 1); + if (ret != BAD_FUNC_ARG) + return -10286; + ret = wc_SetSakkeRsk(NULL, rsk, data, 1); + if (ret != BAD_FUNC_ARG) + return -10286; + + ssvSz = sizeof(ssv); + authSz = sizeof(auth); + ret = wc_DeriveSakkeSSV(NULL, WC_HASH_TYPE_SHA256, NULL, ssvSz, NULL, + authSz); + if (ret != BAD_FUNC_ARG) + return -10300; + ret = wc_DeriveSakkeSSV(key, WC_HASH_TYPE_SHA256, NULL, ssvSz, NULL, + authSz); + if (ret != BAD_FUNC_ARG) + return -10300; + ret = wc_DeriveSakkeSSV(NULL, WC_HASH_TYPE_SHA256, ssv, ssvSz, NULL, + authSz); + if (ret != BAD_FUNC_ARG) + return -10300; + ret = wc_DeriveSakkeSSV(NULL, WC_HASH_TYPE_SHA256, NULL, ssvSz, auth, + authSz); + if (ret != BAD_FUNC_ARG) + return -10300; + ret = wc_DeriveSakkeSSV(key, WC_HASH_TYPE_SHA256, ssv, ssvSz, NULL, + authSz); + if (ret != BAD_FUNC_ARG) + return -10300; + ret = wc_DeriveSakkeSSV(key, WC_HASH_TYPE_SHA256, NULL, ssvSz, auth, + authSz); + if (ret != BAD_FUNC_ARG) + return -10300; + ret = wc_DeriveSakkeSSV(NULL, WC_HASH_TYPE_SHA256, ssv, ssvSz, auth, + authSz); + if (ret != BAD_FUNC_ARG) + return -10300; + ret = wc_DeriveSakkeSSV(key, WC_HASH_TYPE_SHA256, ssv, ssvSz, auth, + authSz); + if (ret != BAD_STATE_E) + return -10300; + + ret = wc_SetSakkeIdentity(key, id, 1); + if (ret != 0) + return -10286; + ret = wc_DeriveSakkeSSV(key, WC_HASH_TYPE_SHA256, ssv, ssvSz, auth, + authSz); + if (ret != BAD_STATE_E) + return -10300; + ret = wc_SetSakkeIdentity(key, id, 0); + if (ret != 0) + return -10286; + + ret = wc_SetSakkeRsk(key, rsk, data, 1); + if (ret != 0) + return -10286; + ret = wc_DeriveSakkeSSV(key, WC_HASH_TYPE_SHA256, ssv, ssvSz, auth, + authSz); + if (ret != BAD_STATE_E) + return -10300; + + wc_FreeSakkeKey(key); + + return 0; +} + +static int sakke_kat_derive_test(SakkeKey* key, ecc_point* rsk) +{ + static const byte pubData[] = { + 0x59, 0x58, 0xEF, 0x1B, 0x16, 0x79, 0xBF, 0x09, + 0x9B, 0x3A, 0x03, 0x0D, 0xF2, 0x55, 0xAA, 0x6A, + 0x23, 0xC1, 0xD8, 0xF1, 0x43, 0xD4, 0xD2, 0x3F, + 0x75, 0x3E, 0x69, 0xBD, 0x27, 0xA8, 0x32, 0xF3, + 0x8C, 0xB4, 0xAD, 0x53, 0xDD, 0xEF, 0x42, 0x60, + 0xB0, 0xFE, 0x8B, 0xB4, 0x5C, 0x4C, 0x1F, 0xF5, + 0x10, 0xEF, 0xFE, 0x30, 0x03, 0x67, 0xA3, 0x7B, + 0x61, 0xF7, 0x01, 0xD9, 0x14, 0xAE, 0xF0, 0x97, + 0x24, 0x82, 0x5F, 0xA0, 0x70, 0x7D, 0x61, 0xA6, + 0xDF, 0xF4, 0xFB, 0xD7, 0x27, 0x35, 0x66, 0xCD, + 0xDE, 0x35, 0x2A, 0x0B, 0x04, 0xB7, 0xC1, 0x6A, + 0x78, 0x30, 0x9B, 0xE6, 0x40, 0x69, 0x7D, 0xE7, + 0x47, 0x61, 0x3A, 0x5F, 0xC1, 0x95, 0xE8, 0xB9, + 0xF3, 0x28, 0x85, 0x2A, 0x57, 0x9D, 0xB8, 0xF9, + 0x9B, 0x1D, 0x00, 0x34, 0x47, 0x9E, 0xA9, 0xC5, + 0x59, 0x5F, 0x47, 0xC4, 0xB2, 0xF5, 0x4F, 0xF2, + 0x15, 0x08, 0xD3, 0x75, 0x14, 0xDC, 0xF7, 0xA8, + 0xE1, 0x43, 0xA6, 0x05, 0x8C, 0x09, 0xA6, 0xBF, + 0x2C, 0x98, 0x58, 0xCA, 0x37, 0xC2, 0x58, 0x06, + 0x5A, 0xE6, 0xBF, 0x75, 0x32, 0xBC, 0x8B, 0x5B, + 0x63, 0x38, 0x38, 0x66, 0xE0, 0x75, 0x3C, 0x5A, + 0xC0, 0xE7, 0x27, 0x09, 0xF8, 0x44, 0x5F, 0x2E, + 0x61, 0x78, 0xE0, 0x65, 0x85, 0x7E, 0x0E, 0xDA, + 0x10, 0xF6, 0x82, 0x06, 0xB6, 0x35, 0x05, 0xED, + 0x87, 0xE5, 0x34, 0xFB, 0x28, 0x31, 0xFF, 0x95, + 0x7F, 0xB7, 0xDC, 0x61, 0x9D, 0xAE, 0x61, 0x30, + 0x1E, 0xEA, 0xCC, 0x2F, 0xDA, 0x36, 0x80, 0xEA, + 0x49, 0x99, 0x25, 0x8A, 0x83, 0x3C, 0xEA, 0x8F, + 0xC6, 0x7C, 0x6D, 0x19, 0x48, 0x7F, 0xB4, 0x49, + 0x05, 0x9F, 0x26, 0xCC, 0x8A, 0xAB, 0x65, 0x5A, + 0xB5, 0x8B, 0x7C, 0xC7, 0x96, 0xE2, 0x4E, 0x9A, + 0x39, 0x40, 0x95, 0x75, 0x4F, 0x5F, 0x8B, 0xAE + }; + static const byte rskData[] = { + 0x93, 0xAF, 0x67, 0xE5, 0x00, 0x7B, 0xA6, 0xE6, + 0xA8, 0x0D, 0xA7, 0x93, 0xDA, 0x30, 0x0F, 0xA4, + 0xB5, 0x2D, 0x0A, 0x74, 0xE2, 0x5E, 0x6E, 0x7B, + 0x2B, 0x3D, 0x6E, 0xE9, 0xD1, 0x8A, 0x9B, 0x5C, + 0x50, 0x23, 0x59, 0x7B, 0xD8, 0x2D, 0x80, 0x62, + 0xD3, 0x40, 0x19, 0x56, 0x3B, 0xA1, 0xD2, 0x5C, + 0x0D, 0xC5, 0x6B, 0x7B, 0x97, 0x9D, 0x74, 0xAA, + 0x50, 0xF2, 0x9F, 0xBF, 0x11, 0xCC, 0x2C, 0x93, + 0xF5, 0xDF, 0xCA, 0x61, 0x5E, 0x60, 0x92, 0x79, + 0xF6, 0x17, 0x5C, 0xEA, 0xDB, 0x00, 0xB5, 0x8C, + 0x6B, 0xEE, 0x1E, 0x7A, 0x2A, 0x47, 0xC4, 0xF0, + 0xC4, 0x56, 0xF0, 0x52, 0x59, 0xA6, 0xFA, 0x94, + 0xA6, 0x34, 0xA4, 0x0D, 0xAE, 0x1D, 0xF5, 0x93, + 0xD4, 0xFE, 0xCF, 0x68, 0x8D, 0x5F, 0xC6, 0x78, + 0xBE, 0x7E, 0xFC, 0x6D, 0xF3, 0xD6, 0x83, 0x53, + 0x25, 0xB8, 0x3B, 0x2C, 0x6E, 0x69, 0x03, 0x6B, + 0x15, 0x5F, 0x0A, 0x27, 0x24, 0x10, 0x94, 0xB0, + 0x4B, 0xFB, 0x0B, 0xDF, 0xAC, 0x6C, 0x67, 0x0A, + 0x65, 0xC3, 0x25, 0xD3, 0x9A, 0x06, 0x9F, 0x03, + 0x65, 0x9D, 0x44, 0xCA, 0x27, 0xD3, 0xBE, 0x8D, + 0xF3, 0x11, 0x17, 0x2B, 0x55, 0x41, 0x60, 0x18, + 0x1C, 0xBE, 0x94, 0xA2, 0xA7, 0x83, 0x32, 0x0C, + 0xED, 0x59, 0x0B, 0xC4, 0x26, 0x44, 0x70, 0x2C, + 0xF3, 0x71, 0x27, 0x1E, 0x49, 0x6B, 0xF2, 0x0F, + 0x58, 0x8B, 0x78, 0xA1, 0xBC, 0x01, 0xEC, 0xBB, + 0x65, 0x59, 0x93, 0x4B, 0xDD, 0x2F, 0xB6, 0x5D, + 0x28, 0x84, 0x31, 0x8A, 0x33, 0xD1, 0xA4, 0x2A, + 0xDF, 0x5E, 0x33, 0xCC, 0x58, 0x00, 0x28, 0x0B, + 0x28, 0x35, 0x64, 0x97, 0xF8, 0x71, 0x35, 0xBA, + 0xB9, 0x61, 0x2A, 0x17, 0x26, 0x04, 0x24, 0x40, + 0x9A, 0xC1, 0x5F, 0xEE, 0x99, 0x6B, 0x74, 0x4C, + 0x33, 0x21, 0x51, 0x23, 0x5D, 0xEC, 0xB0, 0xF5 + + }; + static const byte id[] = { + 0x32, 0x30, 0x31, 0x31, 0x2D, 0x30, 0x32, 0x00, + 0x74, 0x65, 0x6C, 0x3A, 0x2B, 0x34, 0x34, 0x37, + 0x37, 0x30, 0x30, 0x39, 0x30, 0x30, 0x31, 0x32, + 0x33, 0x00 + }; + static const byte ssv[] = { + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0 + }; + static const byte auth[] = { + 0x04, + 0x44, 0xE8, 0xAD, 0x44, 0xAB, 0x85, 0x92, 0xA6, + 0xA5, 0xA3, 0xDD, 0xCA, 0x5C, 0xF8, 0x96, 0xC7, + 0x18, 0x04, 0x36, 0x06, 0xA0, 0x1D, 0x65, 0x0D, + 0xEF, 0x37, 0xA0, 0x1F, 0x37, 0xC2, 0x28, 0xC3, + 0x32, 0xFC, 0x31, 0x73, 0x54, 0xE2, 0xC2, 0x74, + 0xD4, 0xDA, 0xF8, 0xAD, 0x00, 0x10, 0x54, 0xC7, + 0x6C, 0xE5, 0x79, 0x71, 0xC6, 0xF4, 0x48, 0x6D, + 0x57, 0x23, 0x04, 0x32, 0x61, 0xC5, 0x06, 0xEB, + 0xF5, 0xBE, 0x43, 0x8F, 0x53, 0xDE, 0x04, 0xF0, + 0x67, 0xC7, 0x76, 0xE0, 0xDD, 0x3B, 0x71, 0xA6, + 0x29, 0x01, 0x33, 0x28, 0x37, 0x25, 0xA5, 0x32, + 0xF2, 0x1A, 0xF1, 0x45, 0x12, 0x6D, 0xC1, 0xD7, + 0x77, 0xEC, 0xC2, 0x7B, 0xE5, 0x08, 0x35, 0xBD, + 0x28, 0x09, 0x8B, 0x8A, 0x73, 0xD9, 0xF8, 0x01, + 0xD8, 0x93, 0x79, 0x3A, 0x41, 0xFF, 0x5C, 0x49, + 0xB8, 0x7E, 0x79, 0xF2, 0xBE, 0x4D, 0x56, 0xCE, + 0x55, 0x7E, 0x13, 0x4A, 0xD8, 0x5B, 0xB1, 0xD4, + 0xB9, 0xCE, 0x4F, 0x8B, 0xE4, 0xB0, 0x8A, 0x12, + 0xBA, 0xBF, 0x55, 0xB1, 0xD6, 0xF1, 0xD7, 0xA6, + 0x38, 0x01, 0x9E, 0xA2, 0x8E, 0x15, 0xAB, 0x1C, + 0x9F, 0x76, 0x37, 0x5F, 0xDD, 0x12, 0x10, 0xD4, + 0xF4, 0x35, 0x1B, 0x9A, 0x00, 0x94, 0x86, 0xB7, + 0xF3, 0xED, 0x46, 0xC9, 0x65, 0xDE, 0xD2, 0xD8, + 0x0D, 0xAD, 0xE4, 0xF3, 0x8C, 0x67, 0x21, 0xD5, + 0x2C, 0x3A, 0xD1, 0x03, 0xA1, 0x0E, 0xBD, 0x29, + 0x59, 0x24, 0x8B, 0x4E, 0xF0, 0x06, 0x83, 0x6B, + 0xF0, 0x97, 0x44, 0x8E, 0x61, 0x07, 0xC9, 0xED, + 0xEE, 0x9F, 0xB7, 0x04, 0x82, 0x3D, 0xF1, 0x99, + 0xF8, 0x32, 0xC9, 0x05, 0xAE, 0x45, 0xF8, 0xA2, + 0x47, 0xA0, 0x72, 0xD8, 0xEF, 0x72, 0x9E, 0xAB, + 0xC5, 0xE2, 0x75, 0x74, 0xB0, 0x77, 0x39, 0xB3, + 0x4B, 0xE7, 0x4A, 0x53, 0x2F, 0x74, 0x7B, 0x86 + }; + byte encSsv[] = { + 0x89, 0xE0, 0xBC, 0x66, 0x1A, 0xA1, 0xE9, 0x16, + 0x38, 0xE6, 0xAC, 0xC8, 0x4E, 0x49, 0x65, 0x07 + }; + int ret; + int valid; + byte pubKey[sizeof(pubData) + 1]; + word32 sz = sizeof(pubKey); + byte tmpSsv[sizeof(encSsv)]; + byte* iTable = NULL; + word32 iTableLen; + byte* table = NULL; + word32 len; + + ret = wc_ImportSakkePublicKey(key, pubData, sizeof(pubData), 0); + if (ret != 0) + return -10315; + + ret = wc_DecodeSakkeRsk(key, rskData, sizeof(rskData), rsk); + if (ret != 0) + return -10316; + + ret = wc_ValidateSakkeRsk(key, id, sizeof(id), rsk, &valid); + if (ret != 0) + return -10317; + if (valid != 1) + return -10318; + + ret = wc_SetSakkeRsk(key, rsk, NULL, 0); + if (ret != 0) + return -10319; + ret = wc_SetSakkeIdentity(key, id, sizeof(id)); + if (ret != 0) + return -10319; + + XMEMCPY(tmpSsv, encSsv, sizeof(encSsv)); + ret = wc_DeriveSakkeSSV(key, WC_HASH_TYPE_SHA256, tmpSsv, sizeof(tmpSsv), + auth, sizeof(auth)); + if (ret != 0) + return -10322; + if (XMEMCMP(tmpSsv, ssv, sizeof(ssv)) != 0) + return -10320; + + ret = wc_MakeSakkePointI(key, id, sizeof(id)); + if (ret != 0) + return -10321; + iTableLen = 0; + ret = wc_GenerateSakkePointITable(key, NULL, &iTableLen); + if (ret != LENGTH_ONLY_E) + return -10322; + if (iTableLen != 0) { + iTable = (byte*)XMALLOC(iTableLen, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (iTable == NULL) + return -10323; + ret = wc_GenerateSakkePointITable(key, iTable, &iTableLen); + if (ret != 0) + return -10324; + } + len = 0; + ret = wc_GenerateSakkeRskTable(key, rsk, NULL, &len); + if (ret != LENGTH_ONLY_E) + return -10325; + if (len > 0) { + table = (byte*)XMALLOC(len, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (table == NULL) + return -10326; + ret = wc_GenerateSakkeRskTable(key, rsk, table, &len); + if (ret != 0) + return -10327; + } + + ret = wc_SetSakkeRsk(key, rsk, table, len); + if (ret != 0) + return -10319; + + XMEMCPY(tmpSsv, encSsv, sizeof(encSsv)); + ret = wc_DeriveSakkeSSV(key, WC_HASH_TYPE_SHA256, tmpSsv, sizeof(tmpSsv), + auth, sizeof(auth)); + if (ret != 0) + return -10328; + if (XMEMCMP(tmpSsv, ssv, sizeof(ssv)) != 0) + return -10329; + + /* Don't reference table that is about to be freed. */ + ret = wc_ClearSakkePointITable(key); + if (ret != 0) + return -10330; + /* Dispose of tables */ + if (iTable != NULL) + XFREE(iTable, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (table != NULL) + XFREE(table, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + + /* Make sure the key public key is exportable - convert to Montgomery form + * in Validation. + */ + ret = wc_ExportSakkePublicKey(key, pubKey, &sz, 1); + if (ret != 0) + return -10331; + if (sz != sizeof(pubData)) + return -10332; + if (XMEMCMP(pubKey, pubData, sizeof(pubData)) != 0) + return -10333; + + sz = sizeof(pubData) + 1; + ret = wc_ExportSakkePublicKey(key, pubKey, &sz, 0); + if (ret != 0) + return -10334; + if (sz != sizeof(pubData) + 1) + return -10335; + if (pubKey[0] != 0x04) + return -10336; + if (XMEMCMP(pubKey + 1, pubData, sizeof(pubData)) != 0) + return -10337; + + return 0; +} + +static int sakke_kat_encapsulate_test(SakkeKey* key) +{ + static const byte pubData[] = { + 0x59, 0x58, 0xEF, 0x1B, 0x16, 0x79, 0xBF, 0x09, + 0x9B, 0x3A, 0x03, 0x0D, 0xF2, 0x55, 0xAA, 0x6A, + 0x23, 0xC1, 0xD8, 0xF1, 0x43, 0xD4, 0xD2, 0x3F, + 0x75, 0x3E, 0x69, 0xBD, 0x27, 0xA8, 0x32, 0xF3, + 0x8C, 0xB4, 0xAD, 0x53, 0xDD, 0xEF, 0x42, 0x60, + 0xB0, 0xFE, 0x8B, 0xB4, 0x5C, 0x4C, 0x1F, 0xF5, + 0x10, 0xEF, 0xFE, 0x30, 0x03, 0x67, 0xA3, 0x7B, + 0x61, 0xF7, 0x01, 0xD9, 0x14, 0xAE, 0xF0, 0x97, + 0x24, 0x82, 0x5F, 0xA0, 0x70, 0x7D, 0x61, 0xA6, + 0xDF, 0xF4, 0xFB, 0xD7, 0x27, 0x35, 0x66, 0xCD, + 0xDE, 0x35, 0x2A, 0x0B, 0x04, 0xB7, 0xC1, 0x6A, + 0x78, 0x30, 0x9B, 0xE6, 0x40, 0x69, 0x7D, 0xE7, + 0x47, 0x61, 0x3A, 0x5F, 0xC1, 0x95, 0xE8, 0xB9, + 0xF3, 0x28, 0x85, 0x2A, 0x57, 0x9D, 0xB8, 0xF9, + 0x9B, 0x1D, 0x00, 0x34, 0x47, 0x9E, 0xA9, 0xC5, + 0x59, 0x5F, 0x47, 0xC4, 0xB2, 0xF5, 0x4F, 0xF2, + 0x15, 0x08, 0xD3, 0x75, 0x14, 0xDC, 0xF7, 0xA8, + 0xE1, 0x43, 0xA6, 0x05, 0x8C, 0x09, 0xA6, 0xBF, + 0x2C, 0x98, 0x58, 0xCA, 0x37, 0xC2, 0x58, 0x06, + 0x5A, 0xE6, 0xBF, 0x75, 0x32, 0xBC, 0x8B, 0x5B, + 0x63, 0x38, 0x38, 0x66, 0xE0, 0x75, 0x3C, 0x5A, + 0xC0, 0xE7, 0x27, 0x09, 0xF8, 0x44, 0x5F, 0x2E, + 0x61, 0x78, 0xE0, 0x65, 0x85, 0x7E, 0x0E, 0xDA, + 0x10, 0xF6, 0x82, 0x06, 0xB6, 0x35, 0x05, 0xED, + 0x87, 0xE5, 0x34, 0xFB, 0x28, 0x31, 0xFF, 0x95, + 0x7F, 0xB7, 0xDC, 0x61, 0x9D, 0xAE, 0x61, 0x30, + 0x1E, 0xEA, 0xCC, 0x2F, 0xDA, 0x36, 0x80, 0xEA, + 0x49, 0x99, 0x25, 0x8A, 0x83, 0x3C, 0xEA, 0x8F, + 0xC6, 0x7C, 0x6D, 0x19, 0x48, 0x7F, 0xB4, 0x49, + 0x05, 0x9F, 0x26, 0xCC, 0x8A, 0xAB, 0x65, 0x5A, + 0xB5, 0x8B, 0x7C, 0xC7, 0x96, 0xE2, 0x4E, 0x9A, + 0x39, 0x40, 0x95, 0x75, 0x4F, 0x5F, 0x8B, 0xAE + }; + static const byte id[] = { + 0x32, 0x30, 0x31, 0x31, 0x2D, 0x30, 0x32, 0x00, + 0x74, 0x65, 0x6C, 0x3A, 0x2B, 0x34, 0x34, 0x37, + 0x37, 0x30, 0x30, 0x39, 0x30, 0x30, 0x31, 0x32, + 0x33, 0x00 + }; + static word32 idSz = sizeof(id); + byte ssv[] = { + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0 + }; + static word16 ssvSz = sizeof(ssv); + static const byte expAuth[] = { + 0x04, + 0x44, 0xE8, 0xAD, 0x44, 0xAB, 0x85, 0x92, 0xA6, + 0xA5, 0xA3, 0xDD, 0xCA, 0x5C, 0xF8, 0x96, 0xC7, + 0x18, 0x04, 0x36, 0x06, 0xA0, 0x1D, 0x65, 0x0D, + 0xEF, 0x37, 0xA0, 0x1F, 0x37, 0xC2, 0x28, 0xC3, + 0x32, 0xFC, 0x31, 0x73, 0x54, 0xE2, 0xC2, 0x74, + 0xD4, 0xDA, 0xF8, 0xAD, 0x00, 0x10, 0x54, 0xC7, + 0x6C, 0xE5, 0x79, 0x71, 0xC6, 0xF4, 0x48, 0x6D, + 0x57, 0x23, 0x04, 0x32, 0x61, 0xC5, 0x06, 0xEB, + 0xF5, 0xBE, 0x43, 0x8F, 0x53, 0xDE, 0x04, 0xF0, + 0x67, 0xC7, 0x76, 0xE0, 0xDD, 0x3B, 0x71, 0xA6, + 0x29, 0x01, 0x33, 0x28, 0x37, 0x25, 0xA5, 0x32, + 0xF2, 0x1A, 0xF1, 0x45, 0x12, 0x6D, 0xC1, 0xD7, + 0x77, 0xEC, 0xC2, 0x7B, 0xE5, 0x08, 0x35, 0xBD, + 0x28, 0x09, 0x8B, 0x8A, 0x73, 0xD9, 0xF8, 0x01, + 0xD8, 0x93, 0x79, 0x3A, 0x41, 0xFF, 0x5C, 0x49, + 0xB8, 0x7E, 0x79, 0xF2, 0xBE, 0x4D, 0x56, 0xCE, + 0x55, 0x7E, 0x13, 0x4A, 0xD8, 0x5B, 0xB1, 0xD4, + 0xB9, 0xCE, 0x4F, 0x8B, 0xE4, 0xB0, 0x8A, 0x12, + 0xBA, 0xBF, 0x55, 0xB1, 0xD6, 0xF1, 0xD7, 0xA6, + 0x38, 0x01, 0x9E, 0xA2, 0x8E, 0x15, 0xAB, 0x1C, + 0x9F, 0x76, 0x37, 0x5F, 0xDD, 0x12, 0x10, 0xD4, + 0xF4, 0x35, 0x1B, 0x9A, 0x00, 0x94, 0x86, 0xB7, + 0xF3, 0xED, 0x46, 0xC9, 0x65, 0xDE, 0xD2, 0xD8, + 0x0D, 0xAD, 0xE4, 0xF3, 0x8C, 0x67, 0x21, 0xD5, + 0x2C, 0x3A, 0xD1, 0x03, 0xA1, 0x0E, 0xBD, 0x29, + 0x59, 0x24, 0x8B, 0x4E, 0xF0, 0x06, 0x83, 0x6B, + 0xF0, 0x97, 0x44, 0x8E, 0x61, 0x07, 0xC9, 0xED, + 0xEE, 0x9F, 0xB7, 0x04, 0x82, 0x3D, 0xF1, 0x99, + 0xF8, 0x32, 0xC9, 0x05, 0xAE, 0x45, 0xF8, 0xA2, + 0x47, 0xA0, 0x72, 0xD8, 0xEF, 0x72, 0x9E, 0xAB, + 0xC5, 0xE2, 0x75, 0x74, 0xB0, 0x77, 0x39, 0xB3, + 0x4B, 0xE7, 0x4A, 0x53, 0x2F, 0x74, 0x7B, 0x86 + }; + static const byte encSsv[] = { + 0x89, 0xE0, 0xBC, 0x66, 0x1A, 0xA1, 0xE9, 0x16, + 0x38, 0xE6, 0xAC, 0xC8, 0x4E, 0x49, 0x65, 0x07 + }; + int ret; + byte auth[257]; + word16 authSz = sizeof(auth); + + ret = wc_ImportSakkePublicKey(key, pubData, sizeof(pubData), 0); + if (ret != 0) + return -10334; + + ret = wc_SetSakkeIdentity(key, id, idSz); + if (ret != 0) + return -10335; + + ret = wc_MakeSakkeEncapsulatedSSV(key, WC_HASH_TYPE_SHA256, ssv, ssvSz, + auth, &authSz); + if (ret != 0) + return -10336; + if (authSz != 257) + return -10337; + + if (XMEMCMP(ssv, encSsv, ssvSz) != 0) + return -10338; + if (XMEMCMP(auth, expAuth, authSz) != 0) + return -10339; + + return 0; +} + +static int sakke_make_key_test(SakkeKey* priv, SakkeKey* pub, SakkeKey* key, + WC_RNG* rng, ecc_point* rsk) +{ + int ret; + byte data[440]; + byte pubData[257]; + word32 sz; + char mail[] = "test@wolfssl.com"; + byte* id = (byte*)mail; + word32 idSz = (word32)XSTRLEN(mail); + int valid; + ecc_point* pubKey = rsk; + + ret = wc_InitSakkeKey_ex(key, 128, ECC_SAKKE_1, NULL, INVALID_DEVID); + if (ret != 0) + return -10339; + + ret = wc_MakeSakkeKey(priv, rng); + if (ret != 0) + return -10340; + + ret = wc_ExportSakkeKey(priv, NULL, &sz); + if (ret != LENGTH_ONLY_E) + return -10341; + if (sz != 384) + return -10342; + sz--; + ret = wc_ExportSakkeKey(priv, data, &sz); + if (ret == 0) + return -10343; + sz++; + ret = wc_ExportSakkeKey(priv, data, &sz); + if (ret != 0) + return -10344; + if (sz != 384) + return -10345; + + ret = wc_ImportSakkeKey(key, data, sz - 1); + if (ret == 0) + return -10346; + ret = wc_ImportSakkeKey(key, data, sz); + if (ret != 0) + return -10347; + wc_FreeSakkeKey(key); + ret = wc_InitSakkeKey_ex(key, 128, ECC_SAKKE_1, NULL, INVALID_DEVID); + if (ret != 0) + return -10348; + + ret = wc_ExportSakkePrivateKey(priv, NULL, &sz); + if (ret != LENGTH_ONLY_E) + return -10349; + if (sz != 128) + return -10350; + sz--; + ret = wc_ExportSakkePrivateKey(priv, data, &sz); + if (ret == 0) + return -10351; + sz++; + ret = wc_ExportSakkePrivateKey(priv, data, &sz); + if (ret != 0) + return -10352; + if (sz != 128) + return -10353; + + ret = wc_ImportSakkePrivateKey(key, data, sz - 1); + if (ret == 0) + return -10354; + ret = wc_ImportSakkePrivateKey(key, data, sz); + if (ret != 0) + return -10355; + ret = wc_MakeSakkePublicKey(key, pubKey); + if (ret != 0) + return -10356; + + ret = wc_ExportSakkePublicKey(priv, NULL, &sz, 1); + if (ret != LENGTH_ONLY_E) + return -10357; + if (sz != 256) + return -10358; + sz--; + ret = wc_ExportSakkePublicKey(priv, data, &sz, 1); + if (ret == 0) + return -10359; + sz++; + ret = wc_ExportSakkePublicKey(priv, data, &sz, 1); + if (ret != 0) + return -10360; + if (sz != 256) + return -10361; + + ret = wc_ImportSakkePublicKey(pub, data, sz - 1, 1); + if (ret == 0) + return -10362; + ret = wc_ImportSakkePublicKey(pub, data, sz, 1); + if (ret != 0) + return -10363; + + ret = wc_ExportSakkePublicKey(pub, pubData, &sz, 1); + if (ret != 0) + return -10364; + if (sz != 256) + return -10365; + if (XMEMCMP(data, pubData, sz) != 0) + return -10366; + + ret = wc_MakeSakkeRsk(priv, id, idSz, rsk); + if (ret != 0) + return -10367; + + ret = wc_ValidateSakkeRsk(priv, id, idSz, rsk, &valid); + if (ret != 0) + return -10368; + if (valid != 1) + return -10369; + + ret = wc_ValidateSakkeRsk(pub, id, idSz, rsk, &valid); + if (ret != 0) + return -10370; + if (valid != 1) + return -10371; + + sz = sizeof(data); + ret = wc_EncodeSakkeRsk(priv, rsk, data, &sz, 1); + if (ret != 0) + return -10372; + if (sz != 256) + return -10373; + ret = wc_DecodeSakkeRsk(priv, data, sz, rsk); + if (ret != 0) + return -10374; + + sz = sizeof(pubData); + ret = wc_EncodeSakkeRsk(priv, rsk, pubData, &sz, 0); + if (ret != 0) + return -10375; + if (sz != sizeof(pubData)) + return -10376; + ret = wc_DecodeSakkeRsk(priv, pubData, sz, rsk); + if (ret != 0) + return -10377; + + wc_FreeSakkeKey(key); + + return 0; +} + +static int sakke_op_test(SakkeKey* priv, SakkeKey* pub, WC_RNG* rng, + ecc_point* rsk) +{ + int ret; + byte ssv[16]; + word16 ssvSz; + byte auth[257]; + word16 authSz; + char mail[] = "test@wolfssl.com"; + byte* id = (byte*)mail; + word32 idSz = (word32)XSTRLEN(mail); + byte pointI[256]; + word32 sz; + + ret = wc_GenerateSakkeSSV(pub, rng, NULL, &ssvSz); + if (ret != LENGTH_ONLY_E) + return -10375; + if (ssvSz != 16) + return -10376; + + ssvSz += 128; + ret = wc_GenerateSakkeSSV(pub, rng, ssv, &ssvSz); + if (ret == 0) + return -10377; + ssvSz -= 128; + ret = wc_GenerateSakkeSSV(pub, rng, ssv, &ssvSz); + if (ret != 0) + return -10378; + if (ssvSz != 16) + return -10379; + + ret = wc_GetSakkeAuthSize(pub, &authSz); + if (ret != 0) + return -10380; + + ret = wc_SetSakkeIdentity(pub, id, idSz); + if (ret != 0) + return -10380; + + ret = wc_MakeSakkeEncapsulatedSSV(pub, WC_HASH_TYPE_SHA256, ssv, ssvSz, + NULL, &authSz); + if (ret != LENGTH_ONLY_E) + return -10381; + if (authSz != 257) + return -10382; + + authSz--; + ret = wc_MakeSakkeEncapsulatedSSV(pub, WC_HASH_TYPE_SHA256, ssv, ssvSz, + auth, &authSz); + if (ret == 0) + return -10383; + authSz++; + ret = wc_MakeSakkeEncapsulatedSSV(pub, WC_HASH_TYPE_SHA256, ssv, ssvSz, + auth, &authSz); + if (ret != 0) + return -10384; + if (authSz != 257) + return -10385; + + ret = wc_GetSakkePointI(pub, NULL, &sz); + if (ret != LENGTH_ONLY_E) + return -10386; + if (sz != 256) + return -10387; + ret = wc_GetSakkePointI(pub, pointI, &sz); + if (ret != 0) + return -10388; + if (sz != 256) + return -10389; + + /* Bogus identity - make it check and regenerate I. */ + ret = wc_MakeSakkePointI(pub, ssv, ssvSz); + if (ret != 0) + return -10391; + ret = wc_MakeSakkeEncapsulatedSSV(pub, WC_HASH_TYPE_SHA256, ssv, ssvSz, + auth, &authSz); + if (ret != 0) + return -10392; + if (authSz != 257) + return -10393; + + ret = wc_SetSakkeRsk(priv, rsk, NULL, 0); + if (ret != 0) + return -10392; + ret = wc_SetSakkeIdentity(priv, id, idSz); + if (ret != 0) + return -10392; + + authSz--; + ret = wc_DeriveSakkeSSV(priv, WC_HASH_TYPE_SHA256, ssv, ssvSz, auth, + authSz); + if (ret == 0) + return -10394; + authSz++; + ret = wc_DeriveSakkeSSV(priv, WC_HASH_TYPE_SHA256, ssv, ssvSz, auth, + authSz); + if (ret != 0) + return -10395; + ssv[0] ^= 0x80; + ret = wc_DeriveSakkeSSV(priv, WC_HASH_TYPE_SHA256, ssv, ssvSz, auth, + authSz); + if (ret != SAKKE_VERIFY_FAIL_E) + return -10396; + ssv[0] ^= 0x80; + + /* Bogus identity - make it check and regenerate I. */ + ret = wc_MakeSakkePointI(pub, ssv, idSz); + if (ret != 0) + return -10397; + ret = wc_DeriveSakkeSSV(priv, WC_HASH_TYPE_SHA256, ssv, ssvSz, auth, + authSz); + if (ret != 0) + return -10398; + return 0; +} + +int sakke_test(void) +{ + int ret; + WC_RNG rng; + SakkeKey* priv; + SakkeKey* pub; + SakkeKey* key; + ecc_point* rsk = NULL; + + priv = XMALLOC(sizeof(SakkeKey), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (priv == NULL) { + return -10404; + } + pub = XMALLOC(sizeof(SakkeKey), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (pub == NULL) { + XFREE(priv, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + return -10405; + } + key = XMALLOC(sizeof(SakkeKey), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (key == NULL) { + XFREE(pub, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(priv, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + return -10406; + } + +#ifndef HAVE_FIPS + ret = wc_InitRng_ex(&rng, HEAP_HINT, devId); +#else + ret = wc_InitRng(&rng); +#endif + if (ret != 0) + return -10400; + + rsk = wc_ecc_new_point(); + if (rsk == NULL) + return -10401; + + ret = wc_InitSakkeKey(pub, HEAP_HINT, INVALID_DEVID); + if (ret != 0) + return -10402; + + ret = wc_InitSakkeKey(priv, HEAP_HINT, INVALID_DEVID); + if (ret != 0) + return -10403; + + ret = sakke_api_test(&rng, key, rsk); + if (ret != 0) + return ret; + + ret = sakke_kat_derive_test(pub, rsk); + if (ret != 0) + return ret; + + ret = sakke_kat_encapsulate_test(pub); + if (ret != 0) + return ret; + + ret = sakke_make_key_test(priv, pub, key, &rng, rsk); + if (ret != 0) + return ret; + + ret = sakke_op_test(priv, pub, &rng, rsk); + if (ret != 0) + return ret; + + wc_FreeSakkeKey(priv); + wc_FreeSakkeKey(pub); + wc_ecc_forcezero_point(rsk); + wc_ecc_del_point(rsk); + wc_FreeRng(&rng); + XFREE(key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pub, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(priv, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + + return 0; +} +#endif /* WOLFCRYPT_HAVE_SAKKE */ + + #if defined(WOLFSSL_CMAC) && !defined(NO_AES) typedef struct CMAC_Test_Case { diff --git a/wolfcrypt/test/test.h b/wolfcrypt/test/test.h index 7a6fc7c84..07a0c21b8 100644 --- a/wolfcrypt/test/test.h +++ b/wolfcrypt/test/test.h @@ -1,6 +1,6 @@ /* wolfcrypt/test/test.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/test/test_paths.h.in b/wolfcrypt/test/test_paths.h.in index e4428c459..7a9d3a173 100644 --- a/wolfcrypt/test/test_paths.h.in +++ b/wolfcrypt/test/test_paths.h.in @@ -1,6 +1,6 @@ /* wolfcrypt/test/test_paths.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/user-crypto/README.txt b/wolfcrypt/user-crypto/README.txt index 00b772f7b..6966a1712 100644 --- a/wolfcrypt/user-crypto/README.txt +++ b/wolfcrypt/user-crypto/README.txt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/user-crypto/include/user_rsa.h b/wolfcrypt/user-crypto/include/user_rsa.h index 59fc85d14..f22f87bc5 100644 --- a/wolfcrypt/user-crypto/include/user_rsa.h +++ b/wolfcrypt/user-crypto/include/user_rsa.h @@ -1,6 +1,6 @@ /* user_rsa.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfcrypt/user-crypto/src/rsa.c b/wolfcrypt/user-crypto/src/rsa.c index a9f5afd8b..2a993ade0 100644 --- a/wolfcrypt/user-crypto/src/rsa.c +++ b/wolfcrypt/user-crypto/src/rsa.c @@ -1,6 +1,6 @@ /* rsa.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl.vcproj b/wolfssl.vcproj index ebf0007da..fd40a6b3a 100755 --- a/wolfssl.vcproj +++ b/wolfssl.vcproj @@ -359,6 +359,10 @@ RelativePath=".\wolfcrypt\src\sp_x86_64.c" > + + diff --git a/wolfssl.vcxproj b/wolfssl.vcxproj index 25c22b449..a02d696da 100644 --- a/wolfssl.vcxproj +++ b/wolfssl.vcxproj @@ -361,6 +361,20 @@ $(OutDir)%(Filename).obj $(IntDir)%(Filename).obj + + false + false + ml64.exe /c /Zi /Fo"$(OutDir)%(Filename).obj" %(Identity) + ml64.exe /c /Zi /Fo"$(IntDir)%(Filename).obj" %(Identity) + $(OutDir)%(Filename).obj + $(IntDir)%(Filename).obj + false + false + ml64.exe /c /Zi /Fo"$(OutDir)%(Filename).obj" %(Identity) + ml64.exe /c /Zi /Fo"$(IntDir)%(Filename).obj" %(Identity) + $(OutDir)%(Filename).obj + $(IntDir)%(Filename).obj + diff --git a/wolfssl/callbacks.h b/wolfssl/callbacks.h index eed27293c..a2a691687 100644 --- a/wolfssl/callbacks.h +++ b/wolfssl/callbacks.h @@ -1,6 +1,6 @@ /* callbacks.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/crl.h b/wolfssl/crl.h index 363d77cb9..308f2a8ad 100644 --- a/wolfssl/crl.h +++ b/wolfssl/crl.h @@ -1,6 +1,6 @@ /* crl.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/error-ssl.h b/wolfssl/error-ssl.h index 68ace3053..4e2ab6e38 100644 --- a/wolfssl/error-ssl.h +++ b/wolfssl/error-ssl.h @@ -1,6 +1,6 @@ /* error-ssl.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 7c3491546..9246f66e9 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1,6 +1,6 @@ /* internal.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -1605,11 +1605,11 @@ enum Misc { /* Check chosen encryption is available. */ #if !(defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) && \ defined(WOLFSSL_TICKET_ENC_CHACHA20_POLY1305) - #error "ChaCha20-Poly1305 not availble for default ticket encryption" + #error "ChaCha20-Poly1305 not available for default ticket encryption" #endif #if !defined(HAVE_AESGCM) && (defined(WOLFSSL_TICKET_ENC_AES128_GCM) || \ defined(WOLFSSL_TICKET_ENC_AES256_GCM)) - #error "AES-GCM not availble for default ticket encryption" + #error "AES-GCM not available for default ticket encryption" #endif #ifndef WOLFSSL_TICKET_KEY_LIFETIME @@ -2284,9 +2284,9 @@ WOLFSSL_LOCAL int TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType, word16* pOffset); #endif -WOLFSSL_LOCAL int TLSX_ParseVersion(WOLFSSL* ssl, byte* input, word16 length, - byte msgType, int* found); -WOLFSSL_LOCAL int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, +WOLFSSL_LOCAL int TLSX_ParseVersion(WOLFSSL* ssl, const byte* input, + word16 length, byte msgType, int* found); +WOLFSSL_LOCAL int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType, Suites *suites); #elif defined(HAVE_SNI) \ @@ -2588,7 +2588,7 @@ typedef struct Cookie { byte data; } Cookie; -WOLFSSL_LOCAL int TLSX_Cookie_Use(WOLFSSL* ssl, byte* data, word16 len, +WOLFSSL_LOCAL int TLSX_Cookie_Use(WOLFSSL* ssl, const byte* data, word16 len, byte* mac, byte macSz, int resp); @@ -2642,7 +2642,7 @@ WOLFSSL_LOCAL int TLSX_PreSharedKey_WriteBinders(PreSharedKey* list, word16* pSz); WOLFSSL_LOCAL int TLSX_PreSharedKey_GetSizeBinders(PreSharedKey* list, byte msgType, word16* pSz); -WOLFSSL_LOCAL int TLSX_PreSharedKey_Use(WOLFSSL* ssl, byte* identity, +WOLFSSL_LOCAL int TLSX_PreSharedKey_Use(WOLFSSL* ssl, const byte* identity, word16 len, word32 age, byte hmac, byte cipherSuite0, byte cipherSuite, byte resumption, diff --git a/wolfssl/ocsp.h b/wolfssl/ocsp.h index 61068601b..acdad5120 100644 --- a/wolfssl/ocsp.h +++ b/wolfssl/ocsp.h @@ -1,6 +1,6 @@ /* ocsp.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/aes.h b/wolfssl/openssl/aes.h index da4baa7c6..0899943d5 100644 --- a/wolfssl/openssl/aes.h +++ b/wolfssl/openssl/aes.h @@ -1,6 +1,6 @@ /* aes.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/asn1.h b/wolfssl/openssl/asn1.h index 8085f0c93..3d885defe 100644 --- a/wolfssl/openssl/asn1.h +++ b/wolfssl/openssl/asn1.h @@ -1,6 +1,6 @@ /* asn1.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/asn1t.h b/wolfssl/openssl/asn1t.h index 0ee58a2d5..98c2404db 100644 --- a/wolfssl/openssl/asn1t.h +++ b/wolfssl/openssl/asn1t.h @@ -1,6 +1,6 @@ /* asn1t.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/bio.h b/wolfssl/openssl/bio.h index edafd2152..89ce4597f 100644 --- a/wolfssl/openssl/bio.h +++ b/wolfssl/openssl/bio.h @@ -1,6 +1,6 @@ /* bio.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/bn.h b/wolfssl/openssl/bn.h index 324ae4f5a..0bc288005 100644 --- a/wolfssl/openssl/bn.h +++ b/wolfssl/openssl/bn.h @@ -1,6 +1,6 @@ /* bn.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/buffer.h b/wolfssl/openssl/buffer.h index 5f1946dda..9ffd99e3f 100644 --- a/wolfssl/openssl/buffer.h +++ b/wolfssl/openssl/buffer.h @@ -1,6 +1,6 @@ /* buffer.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/cms.h b/wolfssl/openssl/cms.h index e86a21f0a..a782abbfd 100644 --- a/wolfssl/openssl/cms.h +++ b/wolfssl/openssl/cms.h @@ -1,6 +1,6 @@ /* cms.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/conf.h b/wolfssl/openssl/conf.h index a56983ef1..a71bc07b5 100644 --- a/wolfssl/openssl/conf.h +++ b/wolfssl/openssl/conf.h @@ -1,6 +1,6 @@ /* conf.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/crypto.h b/wolfssl/openssl/crypto.h index 338af64e1..dc8fdf614 100644 --- a/wolfssl/openssl/crypto.h +++ b/wolfssl/openssl/crypto.h @@ -1,6 +1,6 @@ /* crypto.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/des.h b/wolfssl/openssl/des.h index 14d12ec3c..d7a6ef809 100644 --- a/wolfssl/openssl/des.h +++ b/wolfssl/openssl/des.h @@ -1,6 +1,6 @@ /* des.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/dh.h b/wolfssl/openssl/dh.h index 6fb896c84..de21ab7fe 100644 --- a/wolfssl/openssl/dh.h +++ b/wolfssl/openssl/dh.h @@ -1,6 +1,6 @@ /* dh.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/dsa.h b/wolfssl/openssl/dsa.h index 2729c09bd..6d6f5075b 100644 --- a/wolfssl/openssl/dsa.h +++ b/wolfssl/openssl/dsa.h @@ -1,6 +1,6 @@ /* dsa.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/ec.h b/wolfssl/openssl/ec.h index 80cebb5fc..db407610c 100644 --- a/wolfssl/openssl/ec.h +++ b/wolfssl/openssl/ec.h @@ -1,6 +1,6 @@ /* ec.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/ec25519.h b/wolfssl/openssl/ec25519.h index 180eb8e83..f9cf3c9fc 100644 --- a/wolfssl/openssl/ec25519.h +++ b/wolfssl/openssl/ec25519.h @@ -1,6 +1,6 @@ /* ec25519.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/ec448.h b/wolfssl/openssl/ec448.h index fb3b9005d..3f0b1b7b4 100644 --- a/wolfssl/openssl/ec448.h +++ b/wolfssl/openssl/ec448.h @@ -1,6 +1,6 @@ /* ec448.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/ecdh.h b/wolfssl/openssl/ecdh.h index 7d7aa09ec..039e77071 100644 --- a/wolfssl/openssl/ecdh.h +++ b/wolfssl/openssl/ecdh.h @@ -1,6 +1,6 @@ /* ecdh.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/ecdsa.h b/wolfssl/openssl/ecdsa.h index 77c1a18b0..8e5c873ca 100644 --- a/wolfssl/openssl/ecdsa.h +++ b/wolfssl/openssl/ecdsa.h @@ -1,6 +1,6 @@ /* ecdsa.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/ed25519.h b/wolfssl/openssl/ed25519.h index 579c653f6..50683d4b8 100644 --- a/wolfssl/openssl/ed25519.h +++ b/wolfssl/openssl/ed25519.h @@ -1,6 +1,6 @@ /* ed25519.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/ed448.h b/wolfssl/openssl/ed448.h index b9411e92c..4ff184fbf 100644 --- a/wolfssl/openssl/ed448.h +++ b/wolfssl/openssl/ed448.h @@ -1,6 +1,6 @@ /* ed448.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/err.h b/wolfssl/openssl/err.h index cb1acc094..6ddf2d284 100644 --- a/wolfssl/openssl/err.h +++ b/wolfssl/openssl/err.h @@ -1,6 +1,6 @@ /* err.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 5d6261ac4..56ae89be3 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -1,6 +1,6 @@ /* evp.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/hmac.h b/wolfssl/openssl/hmac.h index d708fe1c6..8158afa9a 100644 --- a/wolfssl/openssl/hmac.h +++ b/wolfssl/openssl/hmac.h @@ -1,6 +1,6 @@ /* hmac.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/lhash.h b/wolfssl/openssl/lhash.h index ee0fba18e..98256888a 100644 --- a/wolfssl/openssl/lhash.h +++ b/wolfssl/openssl/lhash.h @@ -1,6 +1,6 @@ /* lhash.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/md4.h b/wolfssl/openssl/md4.h index aafe9cc17..10a6d642b 100644 --- a/wolfssl/openssl/md4.h +++ b/wolfssl/openssl/md4.h @@ -1,6 +1,6 @@ /* md4.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/md5.h b/wolfssl/openssl/md5.h index 08cbd527e..bbbd1ca2f 100644 --- a/wolfssl/openssl/md5.h +++ b/wolfssl/openssl/md5.h @@ -1,6 +1,6 @@ /* md5.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/obj_mac.h b/wolfssl/openssl/obj_mac.h index 6d0f90047..3c5df52f2 100644 --- a/wolfssl/openssl/obj_mac.h +++ b/wolfssl/openssl/obj_mac.h @@ -1,6 +1,6 @@ /* obj_mac.h * - * Copyright (C) 2006-2017 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/objects.h b/wolfssl/openssl/objects.h index cd44b6628..3f975432b 100644 --- a/wolfssl/openssl/objects.h +++ b/wolfssl/openssl/objects.h @@ -1,6 +1,6 @@ /* objects.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/ocsp.h b/wolfssl/openssl/ocsp.h index e934a51de..bc70f72d9 100644 --- a/wolfssl/openssl/ocsp.h +++ b/wolfssl/openssl/ocsp.h @@ -1,6 +1,6 @@ /* ocsp.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/opensslv.h b/wolfssl/openssl/opensslv.h index 4b32dcc7e..0605a3e8b 100644 --- a/wolfssl/openssl/opensslv.h +++ b/wolfssl/openssl/opensslv.h @@ -1,6 +1,6 @@ /* opensslv.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/ossl_typ.h b/wolfssl/openssl/ossl_typ.h index 5e90ffe0c..9b1142e2f 100644 --- a/wolfssl/openssl/ossl_typ.h +++ b/wolfssl/openssl/ossl_typ.h @@ -1,6 +1,6 @@ /* ossl_typ.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/pem.h b/wolfssl/openssl/pem.h index 31c88d619..730fd0d60 100644 --- a/wolfssl/openssl/pem.h +++ b/wolfssl/openssl/pem.h @@ -1,6 +1,6 @@ /* pem.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/pkcs12.h b/wolfssl/openssl/pkcs12.h index 8f4011319..1eb0f3ee9 100644 --- a/wolfssl/openssl/pkcs12.h +++ b/wolfssl/openssl/pkcs12.h @@ -1,6 +1,6 @@ /* pkcs12.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/pkcs7.h b/wolfssl/openssl/pkcs7.h index 53ab4436e..0eb8a1caf 100644 --- a/wolfssl/openssl/pkcs7.h +++ b/wolfssl/openssl/pkcs7.h @@ -1,6 +1,6 @@ /* pkcs7.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/rand.h b/wolfssl/openssl/rand.h index 4b826f8f2..25d1419e2 100644 --- a/wolfssl/openssl/rand.h +++ b/wolfssl/openssl/rand.h @@ -1,6 +1,6 @@ /* rand.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/rc4.h b/wolfssl/openssl/rc4.h index fc11e5a12..9fc3ce1da 100644 --- a/wolfssl/openssl/rc4.h +++ b/wolfssl/openssl/rc4.h @@ -1,6 +1,6 @@ /* rc4.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/ripemd.h b/wolfssl/openssl/ripemd.h index 3f1d26848..f7dea2879 100644 --- a/wolfssl/openssl/ripemd.h +++ b/wolfssl/openssl/ripemd.h @@ -1,6 +1,6 @@ /* ripemd.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/rsa.h b/wolfssl/openssl/rsa.h index af11c7bc3..d62ee9337 100644 --- a/wolfssl/openssl/rsa.h +++ b/wolfssl/openssl/rsa.h @@ -1,6 +1,6 @@ /* rsa.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/sha.h b/wolfssl/openssl/sha.h index c8ee6d4c6..56d1a706f 100644 --- a/wolfssl/openssl/sha.h +++ b/wolfssl/openssl/sha.h @@ -1,6 +1,6 @@ /* sha.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/sha3.h b/wolfssl/openssl/sha3.h index 2039104d2..75bed13cf 100644 --- a/wolfssl/openssl/sha3.h +++ b/wolfssl/openssl/sha3.h @@ -1,6 +1,6 @@ /* sha3.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/srp.h b/wolfssl/openssl/srp.h index 7b5bd96b4..f6aaec2fc 100644 --- a/wolfssl/openssl/srp.h +++ b/wolfssl/openssl/srp.h @@ -1,6 +1,6 @@ /* srp.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 9d8708b96..e9b201720 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -1,6 +1,6 @@ /* ssl.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/stack.h b/wolfssl/openssl/stack.h index 559a79670..8040574fe 100644 --- a/wolfssl/openssl/stack.h +++ b/wolfssl/openssl/stack.h @@ -1,6 +1,6 @@ /* stack.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/tls1.h b/wolfssl/openssl/tls1.h index b73a8b0a2..51923f693 100644 --- a/wolfssl/openssl/tls1.h +++ b/wolfssl/openssl/tls1.h @@ -1,6 +1,6 @@ /* tls1.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/txt_db.h b/wolfssl/openssl/txt_db.h index a3e0fd362..a7459589b 100644 --- a/wolfssl/openssl/txt_db.h +++ b/wolfssl/openssl/txt_db.h @@ -1,6 +1,6 @@ /* txt_db.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/x509_vfy.h b/wolfssl/openssl/x509_vfy.h index 86c995b43..bb61ba0b7 100644 --- a/wolfssl/openssl/x509_vfy.h +++ b/wolfssl/openssl/x509_vfy.h @@ -1,6 +1,6 @@ /* x509_vfy.h * - * Copyright (C) 2006-2017 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/openssl/x509v3.h b/wolfssl/openssl/x509v3.h index 75e128a4f..db471dd8d 100644 --- a/wolfssl/openssl/x509v3.h +++ b/wolfssl/openssl/x509v3.h @@ -1,6 +1,6 @@ /* x509v3.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/options.h.in b/wolfssl/options.h.in index 0a5f45c23..c67095c9c 100644 --- a/wolfssl/options.h.in +++ b/wolfssl/options.h.in @@ -1,6 +1,6 @@ /* options.h.in * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/sniffer.h b/wolfssl/sniffer.h index f18415a9e..fb48498a4 100644 --- a/wolfssl/sniffer.h +++ b/wolfssl/sniffer.h @@ -1,6 +1,6 @@ /* sniffer.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/sniffer_error.h b/wolfssl/sniffer_error.h index f2710522f..e8411af4b 100644 --- a/wolfssl/sniffer_error.h +++ b/wolfssl/sniffer_error.h @@ -1,6 +1,6 @@ /* sniffer_error.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 2608cd9e5..070f56440 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1,6 +1,6 @@ /* ssl.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -3622,7 +3622,7 @@ WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_INFO)* wolfSSL_PEM_X509_INFO_read_bio( WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_PEM_read_X509_CRL(XFILE fp, WOLFSSL_X509_CRL **x, pem_password_cb *cb, void *u); #endif -WOLFSSL_API int wolfSSL_PEM_get_EVP_CIPHER_INFO(char* header, +WOLFSSL_API int wolfSSL_PEM_get_EVP_CIPHER_INFO(const char* header, EncryptedInfo* cipher); WOLFSSL_API int wolfSSL_PEM_do_header(EncryptedInfo* cipher, unsigned char* data, long* len, diff --git a/wolfssl/version.h b/wolfssl/version.h index 0bc820cbf..84e6d30bf 100644 --- a/wolfssl/version.h +++ b/wolfssl/version.h @@ -1,6 +1,6 @@ /* wolfssl_version.h.in * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/version.h.in b/wolfssl/version.h.in index 0a25a3bf6..673203f39 100644 --- a/wolfssl/version.h.in +++ b/wolfssl/version.h.in @@ -1,6 +1,6 @@ /* wolfssl_version.h.in * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index 707e19f06..6ef8352c6 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -1,6 +1,6 @@ /* aes.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/arc4.h b/wolfssl/wolfcrypt/arc4.h index bcdc9076c..2d21f5ced 100644 --- a/wolfssl/wolfcrypt/arc4.h +++ b/wolfssl/wolfcrypt/arc4.h @@ -1,6 +1,6 @@ /* arc4.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 508084111..ddac56b34 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1,6 +1,6 @@ /* asn.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -1272,8 +1272,8 @@ WOLFSSL_LOCAL void FreeSignatureCtx(SignatureCtx* sigCtx); #ifndef NO_CERTS -WOLFSSL_LOCAL int wc_EncryptedInfoParse(EncryptedInfo* info, char** pBuffer, - size_t bufSz); +WOLFSSL_LOCAL int wc_EncryptedInfoParse(EncryptedInfo* info, + const char** pBuffer, size_t bufSz); WOLFSSL_LOCAL int PemToDer(const unsigned char* buff, long sz, int type, DerBuffer** pDer, void* heap, EncryptedInfo* info, diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index 8498a9d03..b7a57b389 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -1,6 +1,6 @@ /* asn_public.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -516,6 +516,7 @@ WOLFSSL_API void wc_FreeDer(DerBuffer** pDer); WOLFSSL_API int wc_EccKeyToDer(ecc_key*, byte* output, word32 inLen); WOLFSSL_API int wc_EccPrivateKeyToDer(ecc_key* key, byte* output, word32 inLen); + WOLFSSL_API int wc_EccKeyDerSize(ecc_key*, int pub); WOLFSSL_API int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output, word32* outLen); WOLFSSL_API int wc_EccKeyToPKCS8(ecc_key* key, byte* output, diff --git a/wolfssl/wolfcrypt/blake2-impl.h b/wolfssl/wolfcrypt/blake2-impl.h index cb4df286c..9806e44de 100644 --- a/wolfssl/wolfcrypt/blake2-impl.h +++ b/wolfssl/wolfcrypt/blake2-impl.h @@ -12,7 +12,7 @@ */ /* blake2-impl.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/blake2-int.h b/wolfssl/wolfcrypt/blake2-int.h index ac093d646..44f0ddf8e 100644 --- a/wolfssl/wolfcrypt/blake2-int.h +++ b/wolfssl/wolfcrypt/blake2-int.h @@ -12,7 +12,7 @@ */ /* blake2-int.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/blake2.h b/wolfssl/wolfcrypt/blake2.h index 620482dac..cdcb0661d 100644 --- a/wolfssl/wolfcrypt/blake2.h +++ b/wolfssl/wolfcrypt/blake2.h @@ -1,6 +1,6 @@ /* blake2.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/camellia.h b/wolfssl/wolfcrypt/camellia.h index 4b86e6c13..7ef0270a3 100644 --- a/wolfssl/wolfcrypt/camellia.h +++ b/wolfssl/wolfcrypt/camellia.h @@ -27,7 +27,7 @@ /* camellia.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/chacha.h b/wolfssl/wolfcrypt/chacha.h index 3e9206002..0d84c5b42 100644 --- a/wolfssl/wolfcrypt/chacha.h +++ b/wolfssl/wolfcrypt/chacha.h @@ -1,6 +1,6 @@ /* chacha.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/chacha20_poly1305.h b/wolfssl/wolfcrypt/chacha20_poly1305.h index 26289d165..44631bf9c 100644 --- a/wolfssl/wolfcrypt/chacha20_poly1305.h +++ b/wolfssl/wolfcrypt/chacha20_poly1305.h @@ -1,6 +1,6 @@ /* chacha20_poly1305.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/cmac.h b/wolfssl/wolfcrypt/cmac.h index 69a14de32..0ae475e41 100644 --- a/wolfssl/wolfcrypt/cmac.h +++ b/wolfssl/wolfcrypt/cmac.h @@ -1,6 +1,6 @@ /* cmac.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/coding.h b/wolfssl/wolfcrypt/coding.h index 88b1caf94..fd5562183 100644 --- a/wolfssl/wolfcrypt/coding.h +++ b/wolfssl/wolfcrypt/coding.h @@ -1,6 +1,6 @@ /* coding.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/compress.h b/wolfssl/wolfcrypt/compress.h index b3a98ac82..985f1e092 100644 --- a/wolfssl/wolfcrypt/compress.h +++ b/wolfssl/wolfcrypt/compress.h @@ -1,6 +1,6 @@ /* compress.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/cpuid.h b/wolfssl/wolfcrypt/cpuid.h index 6e009c4ac..91a725b96 100644 --- a/wolfssl/wolfcrypt/cpuid.h +++ b/wolfssl/wolfcrypt/cpuid.h @@ -1,6 +1,6 @@ /* cpuid.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -32,8 +32,9 @@ extern "C" { #endif -#if defined(WOLFSSL_X86_64_BUILD) || defined(USE_INTEL_SPEEDUP) || \ - defined(WOLFSSL_AESNI) +#if (defined(WOLFSSL_X86_64_BUILD) || defined(USE_INTEL_SPEEDUP) || \ + defined(WOLFSSL_AESNI) || defined(WOLFSSL_SP_X86_64_ASM)) && \ + !defined(WOLFSSL_NO_ASM) #define CPUID_AVX1 0x0001 #define CPUID_AVX2 0x0002 diff --git a/wolfssl/wolfcrypt/cryptocb.h b/wolfssl/wolfcrypt/cryptocb.h index ccb4e9626..15c7f876e 100644 --- a/wolfssl/wolfcrypt/cryptocb.h +++ b/wolfssl/wolfcrypt/cryptocb.h @@ -1,6 +1,6 @@ /* cryptocb.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -15,7 +15,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ #ifndef _WOLF_CRYPTO_CB_H_ diff --git a/wolfssl/wolfcrypt/curve25519.h b/wolfssl/wolfcrypt/curve25519.h index 7883cb58c..8abffa2e8 100644 --- a/wolfssl/wolfcrypt/curve25519.h +++ b/wolfssl/wolfcrypt/curve25519.h @@ -1,6 +1,6 @@ /* curve25519.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/curve448.h b/wolfssl/wolfcrypt/curve448.h index 6a9c495e2..ba2059410 100644 --- a/wolfssl/wolfcrypt/curve448.h +++ b/wolfssl/wolfcrypt/curve448.h @@ -1,6 +1,6 @@ /* curve448.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/des3.h b/wolfssl/wolfcrypt/des3.h index 705b59e63..b87737e4f 100644 --- a/wolfssl/wolfcrypt/des3.h +++ b/wolfssl/wolfcrypt/des3.h @@ -1,6 +1,6 @@ /* des3.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/dh.h b/wolfssl/wolfcrypt/dh.h index 8ee18f0a0..076383c5b 100644 --- a/wolfssl/wolfcrypt/dh.h +++ b/wolfssl/wolfcrypt/dh.h @@ -1,6 +1,6 @@ /* dh.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/dsa.h b/wolfssl/wolfcrypt/dsa.h index acc133e5c..0bb00fbfe 100644 --- a/wolfssl/wolfcrypt/dsa.h +++ b/wolfssl/wolfcrypt/dsa.h @@ -1,6 +1,6 @@ /* dsa.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index 57ad1d0ff..75a86beb3 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -1,6 +1,6 @@ /* ecc.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -85,7 +85,9 @@ /* Determine max ECC bits based on enabled curves */ -#if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) +#if defined(WOLFCRYPT_HAVE_SAKKE) + #define MAX_ECC_BITS 1024 +#elif defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) #define MAX_ECC_BITS 521 #elif defined(HAVE_ECC512) #define MAX_ECC_BITS 512 @@ -128,10 +130,15 @@ enum { ECC_PRIVATEKEY_ONLY = 3, ECC_MAXNAME = 16, /* MAX CURVE NAME LENGTH */ SIG_HEADER_SZ = 7, /* ECC signature header size (30 81 87 02 42 [R] 02 42 [S]) */ - ECC_BUFSIZE = 256, /* for exported keys temp buffer */ + ECC_BUFSIZE = 257, /* for exported keys temp buffer */ ECC_MINSIZE = ECC_MIN_KEY_SZ/8, /* MIN Private Key size */ +#ifdef WOLFCRYPT_HAVE_SAKKE + ECC_MAXSIZE = 128, /* MAX Private Key size */ + ECC_MAXSIZE_GEN = 128, /* MAX Buffer size required when generating ECC keys*/ +#else ECC_MAXSIZE = 66, /* MAX Private Key size */ ECC_MAXSIZE_GEN = 74, /* MAX Buffer size required when generating ECC keys*/ +#endif ECC_MAX_OID_LEN = 16, ECC_MAX_SIG_SIZE= ((MAX_ECC_BYTES * 2) + ECC_MAX_PAD_SZ + SIG_HEADER_SZ), @@ -212,6 +219,10 @@ typedef enum ecc_curve_id { ECC_X448, #endif +#ifdef WOLFCRYPT_HAVE_SAKKE + ECC_SAKKE_1, +#endif + #ifdef WOLFSSL_CUSTOM_CURVES ECC_CURVE_CUSTOM, #endif @@ -442,7 +453,7 @@ struct ecc_key { ecc_context_t ctx; #endif -#ifdef WOLFSSL_ECDSA_SET_K +#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) mp_int *sign_k; #endif @@ -552,7 +563,7 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, WOLFSSL_API int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, ecc_key* key, mp_int *r, mp_int *s); -#ifdef WOLFSSL_ECDSA_SET_K +#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) WOLFSSL_API int wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key); #endif @@ -636,7 +647,9 @@ void wc_ecc_del_point(ecc_point* p); WOLFSSL_API void wc_ecc_del_point_h(ecc_point* p, void* h); WOLFSSL_API -int wc_ecc_copy_point(ecc_point* p, ecc_point *r); +void wc_ecc_forcezero_point(ecc_point* p); +WOLFSSL_API +int wc_ecc_copy_point(const ecc_point* p, ecc_point *r); WOLFSSL_API int wc_ecc_cmp_point(ecc_point* a, ecc_point *b); WOLFSSL_API @@ -646,13 +659,13 @@ int wc_ecc_point_is_on_curve(ecc_point *p, int curve_idx); #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) WOLFSSL_API -int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, +int wc_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, mp_int* modulus, int map); WOLFSSL_LOCAL -int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, +int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, mp_int* modulus, int map, void* heap); WOLFSSL_LOCAL -int wc_ecc_mulmod_ex2(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, +int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, mp_int* modulus, mp_int* order, WC_RNG* rng, int map, void* heap); #endif /* !WOLFSSL_ATECC508A */ @@ -728,10 +741,11 @@ int wc_ecc_export_point_der_compressed(const int curve_idx, ecc_point* point, #ifdef HAVE_ECC_KEY_IMPORT WOLFSSL_API -int wc_ecc_import_point_der_ex(byte* in, word32 inLen, const int curve_idx, - ecc_point* point, int shortKeySize); +int wc_ecc_import_point_der_ex(const byte* in, word32 inLen, + const int curve_idx, ecc_point* point, + int shortKeySize); WOLFSSL_API -int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx, +int wc_ecc_import_point_der(const byte* in, word32 inLen, const int curve_idx, ecc_point* point); #endif /* HAVE_ECC_KEY_IMPORT */ @@ -741,7 +755,7 @@ int wc_ecc_size(ecc_key* key); WOLFSSL_API int wc_ecc_sig_size_calc(int sz); WOLFSSL_API -int wc_ecc_sig_size(ecc_key* key); +int wc_ecc_sig_size(const ecc_key* key); WOLFSSL_API int wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz); diff --git a/wolfssl/wolfcrypt/eccsi.h b/wolfssl/wolfcrypt/eccsi.h new file mode 100644 index 000000000..b563514eb --- /dev/null +++ b/wolfssl/wolfcrypt/eccsi.h @@ -0,0 +1,176 @@ +/* eccsi.h + * + * Copyright (C) 2006-2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL 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. + * + * wolfSSL 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/eccsi.h +*/ + + +#ifndef WOLF_CRYPT_ECCSI_H +#define WOLF_CRYPT_ECCSI_H + +#include + +#ifdef WOLFCRYPT_HAVE_ECCSI + +#include +#include +#include +#include + +#define WOLFCRYPT_ECCSI_KMS +#define WOLFCRYPT_ECCSI_CLIENT + +#define MAX_ECCSI_BYTES (256 / 8) + +/* Maximum number of loops of attempting to generate key pairs and signatures. + */ +#ifndef ECCSI_MAX_GEN_COUNT + #define ECCSI_MAX_GEN_COUNT 10 +#endif + +typedef struct EccsiKeyParams { + /** Order (q) of elliptic curve as an MP integer. */ + mp_int order; +#ifdef WOLFCRYPT_ECCSI_CLIENT + /** A parameter of elliptic curve as an MP integer. */ + mp_int a; + /** P parameter of elliptic curve as an MP integer. */ + mp_int b; + /** Prime of elliptic curve as an MP integer. */ + mp_int prime; +#endif + /** Base point for elliptic curve operations as an ECC point. */ + ecc_point* base; + + /** Bit indicates order (q) is set as an MP integer in ECCSI key. */ + byte haveOrder:1; + /** Bit indicates A is set as an MP integer in ECCSI key. */ + byte haveA:1; + /** Bit indicates B is set as an MP integer in ECCSI key. */ + byte haveB:1; + /** Bit indicates prime is set as an MP integer in ECCSI key. */ + byte havePrime:1; + /** Bit indicates base point is set as an MP integer in ECCSI key. */ + byte haveBase:1; +} EccsiKeyParams; + +/** + * ECCSI key. + */ +typedef struct EccsiKey { + /** ECC key to perform elliptic curve operations with. */ + ecc_key ecc; + /** ECC key to perform public key elliptic curve operations with. */ + ecc_key pubkey; + /** ECC parameter in forms that can be used in computation. */ + EccsiKeyParams params; +#ifdef WOLFCRYPT_ECCSI_CLIENT + /** Temporary MP integer used during operations.. */ + mp_int tmp; + /** Secret Signing Key */ + mp_int ssk; + /** Public Validation Token (PVT) */ + ecc_point* pvt; +#endif + /** Generic hash algorithm object. */ + wc_HashAlg hash; + /** Temporary buffer for use in operations. */ + byte data[(MAX_ECCSI_BYTES * 2) + 1]; +#ifdef WOLFCRYPT_ECCSI_CLIENT + /** Hash of identity - used in signing/verification. */ + byte idHash[WC_MAX_DIGEST_SIZE]; + /** Size of hash of identity in bytes. */ + byte idHashSz; +#endif + /** Heap hint for dynamic memory allocation. */ + void* heap; + /** Bit indicates KPAK (public key) is in montogmery form. */ + word16 kpakMont:1; +} EccsiKey; + +#ifdef __cplusplus + extern "C" { +#endif + +WOLFSSL_API int wc_InitEccsiKey(EccsiKey* key, void* heap, int devId); +WOLFSSL_API int wc_InitEccsiKey_ex(EccsiKey* key, int keySz, int curveId, + void* heap, int devId); +WOLFSSL_API void wc_FreeEccsiKey(EccsiKey* key); + +WOLFSSL_API int wc_MakeEccsiKey(EccsiKey* key, WC_RNG* rng); + +WOLFSSL_API int wc_MakeEccsiPair(EccsiKey* key, WC_RNG* rng, + enum wc_HashType hashType, const byte* id, word32 idSz, mp_int* ssk, + ecc_point* pvt); +WOLFSSL_API int wc_ValidateEccsiPair(EccsiKey* key, enum wc_HashType hashType, + const byte* id, word32 idSz, const mp_int* ssk, ecc_point* pvt, + int* valid); +WOLFSSL_API int wc_ValidateEccsiPvt(EccsiKey* key, const ecc_point* pvt, + int* valid); +WOLFSSL_API int wc_EncodeEccsiPair(const EccsiKey* key, mp_int* ssk, + ecc_point* pvt, byte* data, word32* sz); +WOLFSSL_API int wc_EncodeEccsiSsk(const EccsiKey* key, mp_int* ssk, byte* data, + word32* sz); +WOLFSSL_API int wc_EncodeEccsiPvt(const EccsiKey* key, ecc_point* pvt, + byte* data, word32* sz, int raw); +WOLFSSL_API int wc_DecodeEccsiPair(const EccsiKey* key, const byte* data, + word32 sz, mp_int* ssk, ecc_point* pvt); +WOLFSSL_API int wc_DecodeEccsiSsk(const EccsiKey* key, const byte* data, + word32 sz, mp_int* ssk); +WOLFSSL_API int wc_DecodeEccsiPvt(const EccsiKey* key, const byte* data, + word32 sz, ecc_point* pvt); +WOLFSSL_API int wc_DecodeEccsiPvtFromSig(const EccsiKey* key, const byte* sig, + word32 sz, ecc_point* pvt); + +WOLFSSL_API int wc_ExportEccsiKey(EccsiKey* key, byte* data, word32* sz); +WOLFSSL_API int wc_ImportEccsiKey(EccsiKey* key, const byte* data, word32 sz); + +WOLFSSL_API int wc_ExportEccsiPrivateKey(EccsiKey* key, byte* data, word32* sz); +WOLFSSL_API int wc_ImportEccsiPrivateKey(EccsiKey* key, const byte* data, + word32 sz); + +WOLFSSL_API int wc_ExportEccsiPublicKey(EccsiKey* key, byte* data, word32* sz, + int raw); +WOLFSSL_API int wc_ImportEccsiPublicKey(EccsiKey* key, const byte* data, + word32 sz, int trusted); + +WOLFSSL_API int wc_HashEccsiId(EccsiKey* key, enum wc_HashType hashType, + const byte* id, word32 idSz, ecc_point* pvt, byte* hash, byte* hashSz); +WOLFSSL_API int wc_SetEccsiHash(EccsiKey* key, const byte* hash, byte hashSz); +WOLFSSL_API int wc_SetEccsiPair(EccsiKey* key, const mp_int* ssk, + const ecc_point* pvt); + +WOLFSSL_API int wc_SignEccsiHash(EccsiKey* key, WC_RNG* rng, + enum wc_HashType hashType, const byte* msg, word32 msgSz, byte* sig, + word32* sigSz); +WOLFSSL_API int wc_VerifyEccsiHash(EccsiKey* key, enum wc_HashType hashType, + const byte* msg, word32 msgSz, const byte* sig, word32 sigSz, + int* verified); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLFCRYPT_HAVE_ECCSI */ + +#endif /* WOLF_CRYPT_ECCSI_H */ + diff --git a/wolfssl/wolfcrypt/ed25519.h b/wolfssl/wolfcrypt/ed25519.h index f5487ade5..2efe4eed2 100644 --- a/wolfssl/wolfcrypt/ed25519.h +++ b/wolfssl/wolfcrypt/ed25519.h @@ -1,6 +1,6 @@ /* ed25519.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/ed448.h b/wolfssl/wolfcrypt/ed448.h index 4f868b53d..d45585a3f 100644 --- a/wolfssl/wolfcrypt/ed448.h +++ b/wolfssl/wolfcrypt/ed448.h @@ -1,6 +1,6 @@ /* ed448.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/error-crypt.h b/wolfssl/wolfcrypt/error-crypt.h index 2cf6fcca7..138e3cbe4 100644 --- a/wolfssl/wolfcrypt/error-crypt.h +++ b/wolfssl/wolfcrypt/error-crypt.h @@ -1,6 +1,6 @@ /* error-crypt.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -234,8 +234,9 @@ enum { PSS_SALTLEN_RECOVER_E=-273, /* PSS slat length not recoverable */ CHACHA_POLY_OVERFLOW =-274, /* ChaCha20Poly1305 limit overflow */ ASN_SELF_SIGNED_E = -275, /* ASN self-signed certificate error */ + SAKKE_VERIFY_FAIL_E = -276, /* SAKKE derivation verification error */ - WC_LAST_E = -275, /* Update this to indicate last error */ + WC_LAST_E = -276, /* Update this to indicate last error */ MIN_CODE_E = -300 /* errors -101 - -299 */ /* add new companion error id strings for any new error codes diff --git a/wolfssl/wolfcrypt/fe_448.h b/wolfssl/wolfcrypt/fe_448.h index 0bdcebdfa..6be82cdc3 100644 --- a/wolfssl/wolfcrypt/fe_448.h +++ b/wolfssl/wolfcrypt/fe_448.h @@ -1,6 +1,6 @@ /* fe448_448.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/fe_operations.h b/wolfssl/wolfcrypt/fe_operations.h index 60a1e87ae..03d3afa3a 100644 --- a/wolfssl/wolfcrypt/fe_operations.h +++ b/wolfssl/wolfcrypt/fe_operations.h @@ -1,6 +1,6 @@ /* fe_operations.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/fips_test.h b/wolfssl/wolfcrypt/fips_test.h index a78b074c4..9d139fdc4 100644 --- a/wolfssl/wolfcrypt/fips_test.h +++ b/wolfssl/wolfcrypt/fips_test.h @@ -1,6 +1,6 @@ /* fips_test.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/ge_448.h b/wolfssl/wolfcrypt/ge_448.h index c4fb2293f..befedcee1 100644 --- a/wolfssl/wolfcrypt/ge_448.h +++ b/wolfssl/wolfcrypt/ge_448.h @@ -1,6 +1,6 @@ /* ge_448.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/ge_operations.h b/wolfssl/wolfcrypt/ge_operations.h index 9632e1539..5ad78141d 100644 --- a/wolfssl/wolfcrypt/ge_operations.h +++ b/wolfssl/wolfcrypt/ge_operations.h @@ -1,6 +1,6 @@ /* ge_operations.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/hash.h b/wolfssl/wolfcrypt/hash.h index 44b505da4..0c6bc772f 100644 --- a/wolfssl/wolfcrypt/hash.h +++ b/wolfssl/wolfcrypt/hash.h @@ -1,6 +1,6 @@ /* hash.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/hc128.h b/wolfssl/wolfcrypt/hc128.h index 19906be72..2b93a2407 100644 --- a/wolfssl/wolfcrypt/hc128.h +++ b/wolfssl/wolfcrypt/hc128.h @@ -1,6 +1,6 @@ /* hc128.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/hmac.h b/wolfssl/wolfcrypt/hmac.h index 806475f30..a8d12a7ab 100644 --- a/wolfssl/wolfcrypt/hmac.h +++ b/wolfssl/wolfcrypt/hmac.h @@ -1,6 +1,6 @@ /* hmac.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/idea.h b/wolfssl/wolfcrypt/idea.h index 8dbffb237..16a381789 100644 --- a/wolfssl/wolfcrypt/idea.h +++ b/wolfssl/wolfcrypt/idea.h @@ -1,6 +1,6 @@ /* idea.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index 24465d9c4..d4637af1e 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -23,6 +23,8 @@ nobase_include_HEADERS+= \ wolfssl/wolfcrypt/ed448.h \ wolfssl/wolfcrypt/fe_448.h \ wolfssl/wolfcrypt/ge_448.h \ + wolfssl/wolfcrypt/eccsi.h \ + wolfssl/wolfcrypt/sakke.h \ wolfssl/wolfcrypt/error-crypt.h \ wolfssl/wolfcrypt/fips_test.h \ wolfssl/wolfcrypt/hash.h \ diff --git a/wolfssl/wolfcrypt/integer.h b/wolfssl/wolfcrypt/integer.h index 59a366bb1..8a04000cc 100644 --- a/wolfssl/wolfcrypt/integer.h +++ b/wolfssl/wolfcrypt/integer.h @@ -1,6 +1,6 @@ /* integer.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -286,7 +286,7 @@ MP_API int mp_init (mp_int * a); MP_API void mp_clear (mp_int * a); MP_API void mp_free (mp_int * a); MP_API void mp_forcezero(mp_int * a); -MP_API int mp_unsigned_bin_size(mp_int * a); +MP_API int mp_unsigned_bin_size(const mp_int * a); MP_API int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c); MP_API int mp_to_unsigned_bin_at_pos(int x, mp_int *t, unsigned char *b); MP_API int mp_to_unsigned_bin (mp_int * a, unsigned char *b); @@ -297,10 +297,10 @@ MP_API int mp_exptmod_ex (mp_int * G, mp_int * X, int digits, mp_int * P, /* end functions needed by Rsa */ /* functions added to support above needed, removed TOOM and KARATSUBA */ -MP_API int mp_count_bits (mp_int * a); +MP_API int mp_count_bits (const mp_int * a); MP_API int mp_leading_bit (mp_int * a); MP_API int mp_init_copy (mp_int * a, mp_int * b); -MP_API int mp_copy (mp_int * a, mp_int * b); +MP_API int mp_copy (const mp_int * a, mp_int * b); MP_API int mp_grow (mp_int * a, int size); MP_API int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d); MP_API void mp_zero (mp_int * a); diff --git a/wolfssl/wolfcrypt/logging.h b/wolfssl/wolfcrypt/logging.h index 88514b78e..092186429 100644 --- a/wolfssl/wolfcrypt/logging.h +++ b/wolfssl/wolfcrypt/logging.h @@ -1,6 +1,6 @@ /* logging.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/md2.h b/wolfssl/wolfcrypt/md2.h index 565385e73..8aeb4f483 100644 --- a/wolfssl/wolfcrypt/md2.h +++ b/wolfssl/wolfcrypt/md2.h @@ -1,6 +1,6 @@ /* md2.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/md4.h b/wolfssl/wolfcrypt/md4.h index 1344f8b88..cf203d97d 100644 --- a/wolfssl/wolfcrypt/md4.h +++ b/wolfssl/wolfcrypt/md4.h @@ -1,6 +1,6 @@ /* md4.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/md5.h b/wolfssl/wolfcrypt/md5.h index 527587908..d469147bc 100644 --- a/wolfssl/wolfcrypt/md5.h +++ b/wolfssl/wolfcrypt/md5.h @@ -1,6 +1,6 @@ /* md5.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/mem_track.h b/wolfssl/wolfcrypt/mem_track.h index 1d5ade9d4..362ef3969 100644 --- a/wolfssl/wolfcrypt/mem_track.h +++ b/wolfssl/wolfcrypt/mem_track.h @@ -1,6 +1,6 @@ /* mem_track.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/memory.h b/wolfssl/wolfcrypt/memory.h index d901b2f92..42e36096b 100644 --- a/wolfssl/wolfcrypt/memory.h +++ b/wolfssl/wolfcrypt/memory.h @@ -1,6 +1,6 @@ /* memory.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/misc.h b/wolfssl/wolfcrypt/misc.h index 2fc4e2b11..748688fe9 100644 --- a/wolfssl/wolfcrypt/misc.h +++ b/wolfssl/wolfcrypt/misc.h @@ -1,6 +1,6 @@ /* misc.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/mpi_class.h b/wolfssl/wolfcrypt/mpi_class.h index ae2fa830c..e04acc263 100644 --- a/wolfssl/wolfcrypt/mpi_class.h +++ b/wolfssl/wolfcrypt/mpi_class.h @@ -1,6 +1,6 @@ /* mpi_class.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/mpi_superclass.h b/wolfssl/wolfcrypt/mpi_superclass.h index 186ac7505..91ebad820 100644 --- a/wolfssl/wolfcrypt/mpi_superclass.h +++ b/wolfssl/wolfcrypt/mpi_superclass.h @@ -1,6 +1,6 @@ /* mpi_superclass.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/pkcs11.h b/wolfssl/wolfcrypt/pkcs11.h index bf1cb1ec9..09e2e6846 100644 --- a/wolfssl/wolfcrypt/pkcs11.h +++ b/wolfssl/wolfcrypt/pkcs11.h @@ -1,6 +1,6 @@ /* pkcs11.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/pkcs12.h b/wolfssl/wolfcrypt/pkcs12.h index 362c8bf57..fa8b331ec 100644 --- a/wolfssl/wolfcrypt/pkcs12.h +++ b/wolfssl/wolfcrypt/pkcs12.h @@ -1,6 +1,6 @@ /* pkcs12.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index e6b5fcdcd..4f24e8183 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -1,6 +1,6 @@ /* pkcs7.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/poly1305.h b/wolfssl/wolfcrypt/poly1305.h index d0bb2ff8e..a0e0b3abf 100644 --- a/wolfssl/wolfcrypt/poly1305.h +++ b/wolfssl/wolfcrypt/poly1305.h @@ -1,6 +1,6 @@ /* poly1305.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -109,18 +109,20 @@ typedef struct Poly1305 { /* does init */ WOLFSSL_API int wc_Poly1305SetKey(Poly1305* poly1305, const byte* key, - word32 kySz); + word32 kySz); WOLFSSL_API int wc_Poly1305Update(Poly1305* poly1305, const byte*, word32); WOLFSSL_API int wc_Poly1305Final(Poly1305* poly1305, byte* tag); /* AEAD Functions */ WOLFSSL_API int wc_Poly1305_Pad(Poly1305* ctx, word32 lenToPad); -WOLFSSL_API int wc_Poly1305_EncodeSizes(Poly1305* ctx, word32 aadSz, word32 dataSz); +WOLFSSL_API int wc_Poly1305_EncodeSizes(Poly1305* ctx, word32 aadSz, + word32 dataSz); #ifdef WORD64_AVAILABLE -WOLFSSL_API int wc_Poly1305_EncodeSizes64(Poly1305* ctx, word64 aadSz, word64 dataSz); +WOLFSSL_API int wc_Poly1305_EncodeSizes64(Poly1305* ctx, word64 aadSz, + word64 dataSz); #endif -WOLFSSL_API int wc_Poly1305_MAC(Poly1305* ctx, byte* additional, word32 addSz, - byte* input, word32 sz, byte* tag, word32 tagSz); +WOLFSSL_API int wc_Poly1305_MAC(Poly1305* ctx, const byte* additional, + word32 addSz, const byte* input, word32 sz, byte* tag, word32 tagSz); #if defined(__aarch64__ ) && defined(WOLFSSL_ARMASM) void poly1305_blocks(Poly1305* ctx, const unsigned char *m, diff --git a/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h b/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h index f025deda6..e3d2cc64c 100644 --- a/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h +++ b/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h @@ -1,6 +1,6 @@ /* esp32-crypt.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h b/wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h index 996c8c40e..7902b002d 100644 --- a/wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h +++ b/wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h @@ -1,6 +1,6 @@ /* renesas-tsip-crypt.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/af_alg/afalg_hash.h b/wolfssl/wolfcrypt/port/af_alg/afalg_hash.h index bd02913e2..5fbcb6733 100644 --- a/wolfssl/wolfcrypt/port/af_alg/afalg_hash.h +++ b/wolfssl/wolfcrypt/port/af_alg/afalg_hash.h @@ -1,6 +1,6 @@ /* afalg_hash.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/af_alg/wc_afalg.h b/wolfssl/wolfcrypt/port/af_alg/wc_afalg.h index d9f5b7155..27d712762 100644 --- a/wolfssl/wolfcrypt/port/af_alg/wc_afalg.h +++ b/wolfssl/wolfcrypt/port/af_alg/wc_afalg.h @@ -1,6 +1,6 @@ /* wc_afalg.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/arm/cryptoCell.h b/wolfssl/wolfcrypt/port/arm/cryptoCell.h index 5ca2d8c19..e434054d7 100644 --- a/wolfssl/wolfcrypt/port/arm/cryptoCell.h +++ b/wolfssl/wolfcrypt/port/arm/cryptoCell.h @@ -1,6 +1,6 @@ /* cryptoCell.h * - * Copyright (C) 2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/atmel/atmel.h b/wolfssl/wolfcrypt/port/atmel/atmel.h index b917a8022..bdb4d8302 100644 --- a/wolfssl/wolfcrypt/port/atmel/atmel.h +++ b/wolfssl/wolfcrypt/port/atmel/atmel.h @@ -1,6 +1,6 @@ /* atmel.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/caam/caam_driver.h b/wolfssl/wolfcrypt/port/caam/caam_driver.h index fa9ecc22a..c3252ce43 100644 --- a/wolfssl/wolfcrypt/port/caam/caam_driver.h +++ b/wolfssl/wolfcrypt/port/caam/caam_driver.h @@ -1,6 +1,6 @@ /* caam_driver.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/caam/caam_error.h b/wolfssl/wolfcrypt/port/caam/caam_error.h index 2f3bc3192..28cd325ac 100644 --- a/wolfssl/wolfcrypt/port/caam/caam_error.h +++ b/wolfssl/wolfcrypt/port/caam/caam_error.h @@ -1,6 +1,6 @@ /* caam_error.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/caam/caam_qnx.h b/wolfssl/wolfcrypt/port/caam/caam_qnx.h index 7c1d48bab..b58397e5b 100644 --- a/wolfssl/wolfcrypt/port/caam/caam_qnx.h +++ b/wolfssl/wolfcrypt/port/caam/caam_qnx.h @@ -1,6 +1,6 @@ /* caam_qnx.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/caam/wolfcaam.h b/wolfssl/wolfcrypt/port/caam/wolfcaam.h index 36b783c70..a2f40929b 100644 --- a/wolfssl/wolfcrypt/port/caam/wolfcaam.h +++ b/wolfssl/wolfcrypt/port/caam/wolfcaam.h @@ -1,6 +1,6 @@ /* wolfcaam.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/caam/wolfcaam_cmac.h b/wolfssl/wolfcrypt/port/caam/wolfcaam_cmac.h index 3a015ab9e..d075c9816 100644 --- a/wolfssl/wolfcrypt/port/caam/wolfcaam_cmac.h +++ b/wolfssl/wolfcrypt/port/caam/wolfcaam_cmac.h @@ -1,6 +1,6 @@ /* wolfcaam_cmac.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/caam/wolfcaam_ecdsa.h b/wolfssl/wolfcrypt/port/caam/wolfcaam_ecdsa.h index 213cde18c..36dbe831a 100644 --- a/wolfssl/wolfcrypt/port/caam/wolfcaam_ecdsa.h +++ b/wolfssl/wolfcrypt/port/caam/wolfcaam_ecdsa.h @@ -1,6 +1,6 @@ /* wolfcaam_ecdsa.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/caam/wolfcaam_qnx.h b/wolfssl/wolfcrypt/port/caam/wolfcaam_qnx.h index fe7b21c8e..526d6c486 100644 --- a/wolfssl/wolfcrypt/port/caam/wolfcaam_qnx.h +++ b/wolfssl/wolfcrypt/port/caam/wolfcaam_qnx.h @@ -1,6 +1,6 @@ /* wolfcaam_qnx.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h b/wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h index 9f5eaf8b5..d18a9e1f3 100644 --- a/wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h +++ b/wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h @@ -1,6 +1,6 @@ /* wolfcaam_sha.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h b/wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h index f7914b8e7..6a0d76045 100644 --- a/wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h +++ b/wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h @@ -1,8 +1,8 @@ /* cavium_octeon_sync.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * - * This file is part of wolfSSL. (formerly known as CyaSSL) + * This file is part of wolfSSL. * * wolfSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ #ifndef _CAVIUM_OCTEON_SYNC_H_ diff --git a/wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h b/wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h index 964f22162..53497bb6a 100644 --- a/wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h +++ b/wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h @@ -1,6 +1,6 @@ /* psoc6_crypto.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h b/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h index c8ddbe7b9..a20aae685 100644 --- a/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h +++ b/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h @@ -1,6 +1,6 @@ /* wc_devcrypto.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/intel/quickassist_sync.h b/wolfssl/wolfcrypt/port/intel/quickassist_sync.h index 8eb9421f9..f140f618c 100644 --- a/wolfssl/wolfcrypt/port/intel/quickassist_sync.h +++ b/wolfssl/wolfcrypt/port/intel/quickassist_sync.h @@ -1,8 +1,8 @@ /* quickassist_sync.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * - * This file is part of wolfSSL. (formerly known as CyaSSL) + * This file is part of wolfSSL. * * wolfSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ #ifndef _INTEL_QUICKASSIST_SYNC_H_ diff --git a/wolfssl/wolfcrypt/port/nrf51.h b/wolfssl/wolfcrypt/port/nrf51.h index b18b0400a..169d9cf50 100644 --- a/wolfssl/wolfcrypt/port/nrf51.h +++ b/wolfssl/wolfcrypt/port/nrf51.h @@ -1,6 +1,6 @@ /* nrf51.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/nxp/dcp_port.h b/wolfssl/wolfcrypt/port/nxp/dcp_port.h index 8d7fcd9ea..f8f08d4fc 100644 --- a/wolfssl/wolfcrypt/port/nxp/dcp_port.h +++ b/wolfssl/wolfcrypt/port/nxp/dcp_port.h @@ -1,6 +1,6 @@ /* dcp_port.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/nxp/ksdk_port.h b/wolfssl/wolfcrypt/port/nxp/ksdk_port.h index f73579c2a..4b85f642d 100644 --- a/wolfssl/wolfcrypt/port/nxp/ksdk_port.h +++ b/wolfssl/wolfcrypt/port/nxp/ksdk_port.h @@ -1,6 +1,6 @@ /* ksdk_port.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h b/wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h index bb288c777..4ffd8d144 100644 --- a/wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h +++ b/wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h @@ -1,6 +1,6 @@ /* pic32mz-crypt.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/silabs/silabs_aes.h b/wolfssl/wolfcrypt/port/silabs/silabs_aes.h index 3b9d4f140..798a1ef8f 100644 --- a/wolfssl/wolfcrypt/port/silabs/silabs_aes.h +++ b/wolfssl/wolfcrypt/port/silabs/silabs_aes.h @@ -1,6 +1,6 @@ /* silabs_aes.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/silabs/silabs_ecc.h b/wolfssl/wolfcrypt/port/silabs/silabs_ecc.h index ca13ea451..a55e5f6c4 100644 --- a/wolfssl/wolfcrypt/port/silabs/silabs_ecc.h +++ b/wolfssl/wolfcrypt/port/silabs/silabs_ecc.h @@ -1,6 +1,6 @@ /* silabs_ecc.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/silabs/silabs_hash.h b/wolfssl/wolfcrypt/port/silabs/silabs_hash.h index c0e5887e5..a88da7145 100644 --- a/wolfssl/wolfcrypt/port/silabs/silabs_hash.h +++ b/wolfssl/wolfcrypt/port/silabs/silabs_hash.h @@ -1,6 +1,6 @@ /* silabs_hash.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/silabs/silabs_random.h b/wolfssl/wolfcrypt/port/silabs/silabs_random.h index 3267c4d9e..4475ceff6 100644 --- a/wolfssl/wolfcrypt/port/silabs/silabs_random.h +++ b/wolfssl/wolfcrypt/port/silabs/silabs_random.h @@ -1,6 +1,6 @@ /* silabs_random.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/st/stm32.h b/wolfssl/wolfcrypt/port/st/stm32.h index 3db84c7e9..78112328b 100644 --- a/wolfssl/wolfcrypt/port/st/stm32.h +++ b/wolfssl/wolfcrypt/port/st/stm32.h @@ -1,6 +1,6 @@ /* stm32.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/st/stsafe.h b/wolfssl/wolfcrypt/port/st/stsafe.h index 3cee4461d..cf62a475d 100644 --- a/wolfssl/wolfcrypt/port/st/stsafe.h +++ b/wolfssl/wolfcrypt/port/st/stsafe.h @@ -1,6 +1,6 @@ /* stsafe.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/ti/ti-ccm.h b/wolfssl/wolfcrypt/port/ti/ti-ccm.h index f704d7705..4e47fd6e5 100644 --- a/wolfssl/wolfcrypt/port/ti/ti-ccm.h +++ b/wolfssl/wolfcrypt/port/ti/ti-ccm.h @@ -1,6 +1,6 @@ /* port/ti/ti_ccm.c * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/ti/ti-hash.h b/wolfssl/wolfcrypt/port/ti/ti-hash.h index 1c212458c..7c5d610b0 100644 --- a/wolfssl/wolfcrypt/port/ti/ti-hash.h +++ b/wolfssl/wolfcrypt/port/ti/ti-hash.h @@ -1,6 +1,6 @@ /* port/ti/ti-hash.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/port/xilinx/xil-sha3.h b/wolfssl/wolfcrypt/port/xilinx/xil-sha3.h index 47b462424..edaa4fa46 100644 --- a/wolfssl/wolfcrypt/port/xilinx/xil-sha3.h +++ b/wolfssl/wolfcrypt/port/xilinx/xil-sha3.h @@ -1,6 +1,6 @@ /* xil-sha3.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/pwdbased.h b/wolfssl/wolfcrypt/pwdbased.h index 13860fecb..e142adb98 100644 --- a/wolfssl/wolfcrypt/pwdbased.h +++ b/wolfssl/wolfcrypt/pwdbased.h @@ -1,6 +1,6 @@ /* pwdbased.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/rabbit.h b/wolfssl/wolfcrypt/rabbit.h index 20c269398..836b73705 100644 --- a/wolfssl/wolfcrypt/rabbit.h +++ b/wolfssl/wolfcrypt/rabbit.h @@ -1,6 +1,6 @@ /* rabbit.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/random.h b/wolfssl/wolfcrypt/random.h index f32a39c7e..066eaff49 100644 --- a/wolfssl/wolfcrypt/random.h +++ b/wolfssl/wolfcrypt/random.h @@ -1,6 +1,6 @@ /* random.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/rc2.h b/wolfssl/wolfcrypt/rc2.h index 7a8bc6998..5aa641a82 100644 --- a/wolfssl/wolfcrypt/rc2.h +++ b/wolfssl/wolfcrypt/rc2.h @@ -1,6 +1,6 @@ /* rc2.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/ripemd.h b/wolfssl/wolfcrypt/ripemd.h index 9368648de..1e4c6b3be 100644 --- a/wolfssl/wolfcrypt/ripemd.h +++ b/wolfssl/wolfcrypt/ripemd.h @@ -1,6 +1,6 @@ /* ripemd.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/rsa.h b/wolfssl/wolfcrypt/rsa.h index 769af9ecf..316435147 100644 --- a/wolfssl/wolfcrypt/rsa.h +++ b/wolfssl/wolfcrypt/rsa.h @@ -1,6 +1,6 @@ /* rsa.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -283,7 +283,7 @@ WOLFSSL_API int wc_RsaPSS_VerifyCheck(byte* in, word32 inLen, enum wc_HashType hash, int mgf, RsaKey* key); -WOLFSSL_API int wc_RsaEncryptSize(RsaKey* key); +WOLFSSL_API int wc_RsaEncryptSize(const RsaKey* key); #if !defined(HAVE_FIPS) || \ (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) diff --git a/wolfssl/wolfcrypt/sakke.h b/wolfssl/wolfcrypt/sakke.h new file mode 100644 index 000000000..79fc314e4 --- /dev/null +++ b/wolfssl/wolfcrypt/sakke.h @@ -0,0 +1,228 @@ +/* sakke.h + * + * Copyright (C) 2006-2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL 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. + * + * wolfSSL 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/sakke.h +*/ + + +#ifndef WOLF_CRYPT_SAKKE_H +#define WOLF_CRYPT_SAKKE_H + +#include + +#ifdef WOLFCRYPT_HAVE_SAKKE + +#include +#include +#include +#include + +#define WOLFCRYPT_SAKKE_KMS +#define WOLFCRYPT_SAKKE_CLIENT + +#define SAKKE_ID_MAX_SIZE 128 + +/* Maximum number of loops of attempting to generate a key. */ +#ifndef SAKKE_MAX_GEN_COUNT + #define SAKKE_MAX_GEN_COUNT 10 +#endif + + +/** MP integer in projective form. */ +typedef ecc_point mp_proj; + +/** SAKKE ECC parameters in usable format. */ +typedef struct SakkeKeyParams { + /** Prime as an MP integer. */ + mp_int prime; + /** Q (order) as an MP integer. */ + mp_int q; + /** G (pairing base) as an MP integer. */ + mp_int g; + /** Temporary MP integer used during operations. */ + mp_int a; + /** Base point for elliptic curve operations as an ECC point. */ + ecc_point* base; + + /** Bit indicate prime is set as an MP integer in SAKKE key. */ + byte havePrime:1; + /** Bit indicates q (order) is set as an MP integer in SAKKE key. */ + byte haveQ:1; + /** Bit indicates g (pairing base) is set as an MP integer in SAKKE key. */ + byte haveG:1; + /** Bit indicates a is set as an MP integer in SAKKE key. */ + byte haveA:1; + /** Bit indicates base point is set as an ECC point in SAKKE key. */ + byte haveBase:1; +} SakkeKeyParams; + +/** Temporary values to use in SAKKE calculations. */ +typedef struct SakkeKeyTmp { + /** Temporary MP integer used during operations. */ + mp_int m1; + /** Temporary MP integer used during operations. */ + mp_int m2; + +#ifdef WOLFCRYPT_SAKKE_CLIENT + /** Temporary elliptic curve point for use in operations. */ + ecc_point* p1; + /** Temporary elliptic curve point for use in operations. */ + ecc_point* p2; + /** Temporary MP projective integer for use in operations. */ + mp_proj* p3; +#endif +} SakkeKeyTmp; + +#ifdef WOLFCRYPT_SAKKE_CLIENT +/** SAKKE data for the intermediate point I. */ +typedef struct SakkeKeyPointI { + /** Temporary elliptic curve point for use in operations. */ + ecc_point* i; + /** Table associated with point I. */ + byte* table; + /** Length of table */ + int tableLen; + /** Identity associated with point I. */ + byte id[SAKKE_ID_MAX_SIZE]; + /** Size of identity associated with point I. */ + word16 idSz; +} SakkeKeyPointI; + +/** SAKKE data for the Receiver Secret Key (RSK). */ +typedef struct SakkeKeyRsk { + /** RSK (Receiver Secret Key). */ + ecc_point* rsk; + /** Table associated with point I. */ + byte* table; + /** Length of table */ + int tableLen; + /** Indicates whether an RSK value has been set. */ + byte set:1; +} SakkeKeyRsk; +#endif + +/** + * SAKKE key. + */ +typedef struct SakkeKey { + /** ECC key to perform elliptic curve operations with. */ + ecc_key ecc; + + /** ECC parameter in forms that can be used in computation. */ + SakkeKeyParams params; + /** Temporaries used during calculations. */ + SakkeKeyTmp tmp; + +#ifdef WOLFCRYPT_SAKKE_CLIENT + /** Data relating to the RSK (Receiver Secret Key). */ + SakkeKeyRsk rsk; + /** Identity to perform operations with. */ + byte id[SAKKE_ID_MAX_SIZE]; + /** Size of identity in bytes. */ + word16 idSz; + + /** Data relating to the intermediate point I. */ + SakkeKeyPointI i; + + /** Generic hash algorithm object. */ + wc_HashAlg hash; + /** Temporary buffer for use in operations. */ + byte data[(MAX_ECC_BYTES * 2) + 1]; +#endif + + /** Heap hint for dynamic memory allocation. */ + void* heap; + + /** Bit indicates Z, public key, is in montgomery form. */ + byte zMont:1; + /** Bit indicate MP integers have been initialized. */ + byte mpInit:1; +} SakkeKey; + +#ifdef __cplusplus + extern "C" { +#endif + +WOLFSSL_API int wc_InitSakkeKey(SakkeKey* key, void* heap, int devId); +WOLFSSL_API int wc_InitSakkeKey_ex(SakkeKey* key, int keySize, int curveId, + void* heap, int devId); +WOLFSSL_API void wc_FreeSakkeKey(SakkeKey* key); + +WOLFSSL_API int wc_MakeSakkeKey(SakkeKey* key, WC_RNG* rng); +WOLFSSL_API int wc_MakeSakkePublicKey(SakkeKey* key, ecc_point* pub); + +WOLFSSL_API int wc_MakeSakkeRsk(SakkeKey* key, const byte* id, word16 idSz, + ecc_point* rsk); +WOLFSSL_API int wc_ValidateSakkeRsk(SakkeKey* key, const byte* id, word16 idSz, + ecc_point* rsk, int* valid); + +WOLFSSL_API int wc_ExportSakkeKey(SakkeKey* key, byte* data, word32* sz); +WOLFSSL_API int wc_ImportSakkeKey(SakkeKey* key, const byte* data, word32 sz); +WOLFSSL_API int wc_ExportSakkePrivateKey(SakkeKey* key, byte* data, word32* sz); +WOLFSSL_API int wc_ImportSakkePrivateKey(SakkeKey* key, const byte* data, + word32 sz); +WOLFSSL_API int wc_ExportSakkePublicKey(SakkeKey* key, byte* data, + word32* sz, int raw); +WOLFSSL_API int wc_ImportSakkePublicKey(SakkeKey* key, const byte* data, + word32 sz, int trusted); + +WOLFSSL_API int wc_EncodeSakkeRsk(const SakkeKey* key, ecc_point* rsk, + byte* out, word32* sz, int raw); +WOLFSSL_API int wc_DecodeSakkeRsk(const SakkeKey* key, const byte* data, + word32 sz, ecc_point* rsk); +WOLFSSL_API int wc_ImportSakkeRsk(SakkeKey* key, const byte* data, word32 sz); + +WOLFSSL_API int wc_GetSakkeAuthSize(SakkeKey* key, word16* authSz); + +WOLFSSL_API int wc_SetSakkeIdentity(SakkeKey* key, const byte* id, word16 idSz); +WOLFSSL_API int wc_MakeSakkePointI(SakkeKey* key, const byte* id, word16 idSz); +WOLFSSL_API int wc_GetSakkePointI(SakkeKey* key, byte* data, word32* sz); +WOLFSSL_API int wc_SetSakkePointI(SakkeKey* key, const byte* id, word16 idSz, + const byte* data, word32 sz); +WOLFSSL_API int wc_GenerateSakkePointITable(SakkeKey* key, byte* table, + word32* len); +WOLFSSL_API int wc_SetSakkePointITable(SakkeKey* key, byte* table, word32 len); +WOLFSSL_API int wc_ClearSakkePointITable(SakkeKey* key); + +WOLFSSL_API int wc_MakeSakkeEncapsulatedSSV(SakkeKey* key, + enum wc_HashType hashType, byte* ssv, word16 ssvSz, byte* auth, + word16* authSz); + +WOLFSSL_API int wc_GenerateSakkeRskTable(const SakkeKey* key, + const ecc_point* rsk, byte* table, word32* len); +WOLFSSL_API int wc_SetSakkeRsk(SakkeKey* key, const ecc_point* rsk, byte* table, + word32 len); + +WOLFSSL_API int wc_GenerateSakkeSSV(SakkeKey* key, WC_RNG* rng, byte* ssv, + word16* ssvSz); +WOLFSSL_API int wc_DeriveSakkeSSV(SakkeKey* key, enum wc_HashType hashType, + byte* ssv, word16 ssvSz, const byte* auth, + word16 authSz); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLFCRYPT_HAVE_SAKKE */ + +#endif /* WOLF_CRYPT_SAKKE_H */ + diff --git a/wolfssl/wolfcrypt/selftest.h b/wolfssl/wolfcrypt/selftest.h index 826b90d98..0d675259d 100644 --- a/wolfssl/wolfcrypt/selftest.h +++ b/wolfssl/wolfcrypt/selftest.h @@ -1,6 +1,6 @@ /* selftest.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index ef85523d2..253264a9f 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -1,6 +1,6 @@ /* settings.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/sha.h b/wolfssl/wolfcrypt/sha.h index bdbf45b64..10c447115 100644 --- a/wolfssl/wolfcrypt/sha.h +++ b/wolfssl/wolfcrypt/sha.h @@ -1,6 +1,6 @@ /* sha.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/sha256.h b/wolfssl/wolfcrypt/sha256.h index 13cc682bd..01228834d 100644 --- a/wolfssl/wolfcrypt/sha256.h +++ b/wolfssl/wolfcrypt/sha256.h @@ -1,6 +1,6 @@ /* sha256.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/sha3.h b/wolfssl/wolfcrypt/sha3.h index 7ffef7791..19347b049 100644 --- a/wolfssl/wolfcrypt/sha3.h +++ b/wolfssl/wolfcrypt/sha3.h @@ -1,6 +1,6 @@ /* sha3.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/sha512.h b/wolfssl/wolfcrypt/sha512.h index a2680bc6b..25410a814 100644 --- a/wolfssl/wolfcrypt/sha512.h +++ b/wolfssl/wolfcrypt/sha512.h @@ -1,6 +1,6 @@ /* sha512.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/signature.h b/wolfssl/wolfcrypt/signature.h index afaf2ec6c..d7c4188f2 100644 --- a/wolfssl/wolfcrypt/signature.h +++ b/wolfssl/wolfcrypt/signature.h @@ -1,6 +1,6 @@ /* signature.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/sp.h b/wolfssl/wolfcrypt/sp.h index f26486b47..22870d4a8 100644 --- a/wolfssl/wolfcrypt/sp.h +++ b/wolfssl/wolfcrypt/sp.h @@ -1,6 +1,6 @@ /* sp.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -56,6 +56,8 @@ #ifdef WOLFSSL_HAVE_SP_RSA +#if defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION == 2 + WOLFSSL_LOCAL int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, byte* out, word32* outLen); WOLFSSL_LOCAL int sp_RsaPrivate_2048(const byte* in, word32 inLen, @@ -74,10 +76,37 @@ WOLFSSL_LOCAL int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm, byte* out, word32* outLen); +#else + +WOLFSSL_LOCAL int sp_RsaPublic_2048(const byte* in, word32 inLen, + const mp_int* em, const mp_int* mm, byte* out, word32* outLen); +WOLFSSL_LOCAL int sp_RsaPrivate_2048(const byte* in, word32 inLen, + const mp_int* dm, const mp_int* pm, const mp_int* qm, const mp_int* dpm, + const mp_int* dqm, const mp_int* qim, const mp_int* mm, byte* out, + word32* outLen); + +WOLFSSL_LOCAL int sp_RsaPublic_3072(const byte* in, word32 inLen, + const mp_int* em, const mp_int* mm, byte* out, word32* outLen); +WOLFSSL_LOCAL int sp_RsaPrivate_3072(const byte* in, word32 inLen, + const mp_int* dm, const mp_int* pm, const mp_int* qm, const mp_int* dpm, + const mp_int* dqm, const mp_int* qim, const mp_int* mm, byte* out, + word32* outLen); + +WOLFSSL_LOCAL int sp_RsaPublic_4096(const byte* in, word32 inLen, + const mp_int* em, const mp_int* mm, byte* out, word32* outLen); +WOLFSSL_LOCAL int sp_RsaPrivate_4096(const byte* in, word32 inLen, + const mp_int* dm, const mp_int* pm, const mp_int* qm, const mp_int* dpm, + const mp_int* dqm, const mp_int* qim, const mp_int* mm, byte* out, + word32* outLen); + +#endif /* HAVE_FIPS_VERSION && HAVE_FIPS_VERSION == 2 */ + #endif /* WOLFSSL_HAVE_SP_RSA */ #if defined(WOLFSSL_HAVE_SP_DH) || defined(WOLFSSL_HAVE_SP_RSA) +#if defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION == 2 + WOLFSSL_LOCAL int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res); WOLFSSL_LOCAL int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, @@ -89,10 +118,27 @@ WOLFSSL_LOCAL int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, WOLFSSL_LOCAL int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res); +#else + +WOLFSSL_LOCAL int sp_ModExp_1024(const mp_int* base, const mp_int* exp, + const mp_int* mod, mp_int* res); +WOLFSSL_LOCAL int sp_ModExp_1536(const mp_int* base, const mp_int* exp, + const mp_int* mod, mp_int* res); +WOLFSSL_LOCAL int sp_ModExp_2048(const mp_int* base, const mp_int* exp, + const mp_int* mod, mp_int* res); +WOLFSSL_LOCAL int sp_ModExp_3072(const mp_int* base, const mp_int* exp, + const mp_int* mod, mp_int* res); +WOLFSSL_LOCAL int sp_ModExp_4096(const mp_int* base, const mp_int* exp, + const mp_int* mod, mp_int* res); + +#endif /* HAVE_FIPS_VERSION && HAVE_FIPS_VERSION == 2 */ + #endif #ifdef WOLFSSL_HAVE_SP_DH +#if defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION == 2 + WOLFSSL_LOCAL int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen, mp_int* mod, byte* out, word32* outLen); WOLFSSL_LOCAL int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, @@ -100,10 +146,23 @@ WOLFSSL_LOCAL int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen, WOLFSSL_LOCAL int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, mp_int* mod, byte* out, word32* outLen); +#else + +WOLFSSL_LOCAL int sp_DhExp_2048(const mp_int* base, const byte* exp, + word32 expLen, const mp_int* mod, byte* out, word32* outLen); +WOLFSSL_LOCAL int sp_DhExp_3072(const mp_int* base, const byte* exp, + word32 expLen, const mp_int* mod, byte* out, word32* outLen); +WOLFSSL_LOCAL int sp_DhExp_4096(const mp_int* base, const byte* exp, + word32 expLen, const mp_int* mod, byte* out, word32* outLen); + +#endif /* HAVE_FIPS_VERSION && HAVE_FIPS_VERSION == 2 */ + #endif /* WOLFSSL_HAVE_SP_DH */ #ifdef WOLFSSL_HAVE_SP_ECC +#if defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION == 2 + int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* rm, int map, void* heap); int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* rm, int map, void* heap); @@ -147,15 +206,94 @@ int sp_ecc_proj_dbl_point_384(mp_int* pX, mp_int* pY, mp_int* pZ, int sp_ecc_map_384(mp_int* pX, mp_int* pY, mp_int* pZ); int sp_ecc_uncompress_384(mp_int* xm, int odd, mp_int* ym); +#else + +int sp_ecc_mulmod_256(const mp_int* km, const ecc_point* gm, ecc_point* rm, + int map, void* heap); +int sp_ecc_mulmod_add_256(const mp_int* km, const ecc_point* gm, + const ecc_point* am, int inMont, ecc_point* rm, int map, void* heap); +int sp_ecc_mulmod_base_256(const mp_int* km, ecc_point* rm, int map, + void* heap); +int sp_ecc_mulmod_base_add_256(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* rm, int map, void* heap); + +int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap); +int sp_ecc_secret_gen_256(const mp_int* priv, const ecc_point* pub, byte* out, + word32* outlen, void* heap); +int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, + const mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap); +int sp_ecc_verify_256(const byte* hash, word32 hashLen, const mp_int* pX, + const mp_int* pY, const mp_int* pZ, const mp_int* r, const mp_int* sm, + int* res, void* heap); +int sp_ecc_is_point_256(const mp_int* pX, const mp_int* pY); +int sp_ecc_check_key_256(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap); +int sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, + mp_int* qX, mp_int* qY, mp_int* qZ, mp_int* rX, mp_int* rY, mp_int* rZ); +int sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, + mp_int* rX, mp_int* rY, mp_int* rZ); +int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ); +int sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym); + +int sp_ecc_mulmod_384(const mp_int* km, const ecc_point* gm, ecc_point* rm, + int map, void* heap); +int sp_ecc_mulmod_add_384(const mp_int* km, const ecc_point* gm, + const ecc_point* am, int inMont, ecc_point* rm, int map, void* heap); +int sp_ecc_mulmod_base_384(const mp_int* km, ecc_point* rm, int map, + void* heap); +int sp_ecc_mulmod_base_add_384(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* rm, int map, void* heap); + +int sp_ecc_make_key_384(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap); +int sp_ecc_secret_gen_384(const mp_int* priv, const ecc_point* pub, byte* out, + word32* outlen, void* heap); +int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, + const mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap); +int sp_ecc_verify_384(const byte* hash, word32 hashLen, const mp_int* pX, + const mp_int* pY, const mp_int* pZ, const mp_int* r, const mp_int* sm, + int* res, void* heap); +int sp_ecc_is_point_384(const mp_int* pX, const mp_int* pY); +int sp_ecc_check_key_384(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap); +int sp_ecc_proj_add_point_384(mp_int* pX, mp_int* pY, mp_int* pZ, + mp_int* qX, mp_int* qY, mp_int* qZ, mp_int* rX, mp_int* rY, mp_int* rZ); +int sp_ecc_proj_dbl_point_384(mp_int* pX, mp_int* pY, mp_int* pZ, + mp_int* rX, mp_int* rY, mp_int* rZ); +int sp_ecc_map_384(mp_int* pX, mp_int* pY, mp_int* pZ); +int sp_ecc_uncompress_384(mp_int* xm, int odd, mp_int* ym); + +int sp_ecc_mulmod_1024(const mp_int* km, const ecc_point* gm, ecc_point* rm, + int map, void* heap); +int sp_ecc_mulmod_base_1024(const mp_int* km, ecc_point* rm, int map, + void* heap); +int sp_ecc_mulmod_base_add_1024(const mp_int* km, const ecc_point* am, + int inMont, ecc_point* rm, int map, void* heap); +int sp_ecc_gen_table_1024(const ecc_point* gm, byte* table, word32* len, + void* heap); +int sp_ecc_mulmod_table_1024(const mp_int* km, const ecc_point* gm, byte* table, + ecc_point* r, int map, void* heap); +int sp_ModExp_Fp_star_1024(const mp_int* base, mp_int* exp, mp_int* res); +int sp_Pairing_1024(const ecc_point* p, const ecc_point* q, mp_int* res); +int sp_Pairing_gen_precomp_1024(const ecc_point* p, byte* table, word32* len); +int sp_Pairing_precomp_1024(const ecc_point* p, const ecc_point* q, mp_int* res, + const byte* table, word32 len); +int sp_ecc_is_point_1024(const mp_int* pX, const mp_int* pY); +int sp_ecc_check_key_1024(const mp_int* pX, const mp_int* pY, + const mp_int* privm, void* heap); + +#endif /* HAVE_FIPS_VERSION && HAVE_FIPS_VERSION == 2 */ + #ifdef WOLFSSL_SP_NONBLOCK -int sp_ecc_sign_256_nb(sp_ecc_ctx_t* ctx, const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap); -int sp_ecc_verify_256_nb(sp_ecc_ctx_t* ctx, const byte* hash, word32 hashLen, mp_int* pX, mp_int* pY, - mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap); -int sp_ecc_sign_384_nb(sp_ecc_ctx_t* ctx, const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, - mp_int* rm, mp_int* sm, mp_int* km, void* heap); -int sp_ecc_verify_384_nb(sp_ecc_ctx_t* ctx, const byte* hash, word32 hashLen, mp_int* pX, mp_int* pY, - mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap); +int sp_ecc_sign_256_nb(sp_ecc_ctx_t* ctx, const byte* hash, word32 hashLen, + WC_RNG* rng, mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap); +int sp_ecc_verify_256_nb(sp_ecc_ctx_t* ctx, const byte* hash, word32 hashLen, + const mp_int* pX, const mp_int* pY, const mp_int* pZ, const mp_int* r, + const mp_int* sm, int* res, void* heap); +int sp_ecc_sign_384_nb(sp_ecc_ctx_t* ctx, const byte* hash, word32 hashLen, + WC_RNG* rng, mp_int* priv, mp_int* rm, mp_int* sm, mp_int* km, void* heap); +int sp_ecc_verify_384_nb(sp_ecc_ctx_t* ctx, const byte* hash, word32 hashLen, + const mp_int* pX, const mp_int* pY, const mp_int* pZ, const mp_int* r, + const mp_int* sm, int* res, void* heap); #endif /* WOLFSSL_SP_NONBLOCK */ #endif /* WOLFSSL_HAVE_SP_ECC */ diff --git a/wolfssl/wolfcrypt/sp_int.h b/wolfssl/wolfcrypt/sp_int.h index 163dcdad0..8083e6404 100644 --- a/wolfssl/wolfcrypt/sp_int.h +++ b/wolfssl/wolfcrypt/sp_int.h @@ -1,6 +1,6 @@ /* sp_int.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -30,6 +30,7 @@ This library provides single precision (SP) integer math functions. #ifndef WOLFSSL_LINUXKM #include #endif +#include #ifdef __cplusplus extern "C" { @@ -112,7 +113,7 @@ extern "C" { #error "Size of unsigned long not detected" #endif -#if ULLONG_MAX == 18446744073709551615UL +#if ULLONG_MAX == 18446744073709551615ULL #define SP_ULLONG_BITS 64 #if SP_ULLONG_BITS > SP_ULONG_BITS @@ -155,11 +156,16 @@ extern "C" { #ifdef SP_WORD_SIZE #elif defined(WOLFSSL_DSP_BUILD) #define SP_WORD_SIZE 32 +#elif defined(WOLFSSL_SP_X86_64) && !defined(WOLFSSL_SP_X86_64_ASM) && \ + !defined(HAVE___UINT128_T) + #define SP_WORD_SIZE 32 #elif defined(WOLFSSL_SP_X86_64_ASM) || defined(WOLFSSL_SP_X86_64) - #if SP_ULONG_BITS == 64 + #if SP_ULONG_BITS == 64 || SP_ULLONG_BITS == 64 #define SP_WORD_SIZE 64 #define HAVE_INTEL_AVX1 - #define HAVE_INTEL_AVX2 + #ifndef NO_AVX2_SUPPORT + #define HAVE_INTEL_AVX2 + #endif #elif SP_ULONG_BITS == 32 #define SP_WORD_SIZE 32 #undef WOLFSSL_SP_ASM @@ -250,8 +256,10 @@ extern "C" { #elif SP_WORD_SIZE == 64 typedef sp_uint64 sp_int_digit; typedef sp_int64 sp_sint_digit; +#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) typedef sp_uint128 sp_int_word; typedef sp_int128 sp_int_sword; +#endif #define SP_MASK 0xffffffffffffffffUL #else @@ -335,6 +343,9 @@ typedef struct sp_ecc_ctx { !defined(WOLFSSL_HAVE_SP_ECC) #if !defined(NO_RSA) || !defined(NO_DH) || !defined(NO_DSA) #define SP_INT_DIGITS (((6144 + SP_WORD_SIZE) / SP_WORD_SIZE) + 1) + #elif defined(WOLFCRYPT_HAVE_SAKKE) + #define SP_INT_DIGITS \ + (((2 * (1024 + SP_WORD_SIZE) + SP_WORD_SIZE) / SP_WORD_SIZE) + 1) #elif defined(HAVE_ECC) #define SP_INT_DIGITS \ (((2 * ( 521 + SP_WORD_SIZE) + SP_WORD_SIZE) / SP_WORD_SIZE) + 1) @@ -344,7 +355,10 @@ typedef struct sp_ecc_ctx { #define SP_INT_DIGITS ((( 256 + SP_WORD_SIZE) / SP_WORD_SIZE) + 1) #endif #elif !defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_HAVE_SP_DH) - #ifdef WOLFSSL_SP_MATH_ALL + #if defined(WOLFCRYPT_HAVE_SAKKE) + #define SP_INT_DIGITS \ + (((2 * (1024 + SP_WORD_SIZE) + SP_WORD_SIZE) / SP_WORD_SIZE) + 1) + #elif defined(WOLFSSL_SP_MATH_ALL) #define SP_INT_DIGITS \ (((2 * ( 521 + SP_WORD_SIZE) + SP_WORD_SIZE) / SP_WORD_SIZE) + 1) #elif defined(WOLFSSL_SP_384) @@ -756,7 +770,7 @@ MP_API void sp_clear(sp_int* a); MP_API void sp_forcezero(sp_int* a); MP_API int sp_init_copy (sp_int* r, sp_int* a); -MP_API int sp_copy(sp_int* a, sp_int* r); +MP_API int sp_copy(const sp_int* a, sp_int* r); MP_API int sp_exch(sp_int* a, sp_int* b); MP_API int sp_cond_swap_ct(mp_int * a, mp_int * b, int c, int m); @@ -769,7 +783,7 @@ MP_API int sp_cmp_mag(sp_int* a, sp_int* b); MP_API int sp_cmp(sp_int* a, sp_int* b); MP_API int sp_is_bit_set(sp_int* a, unsigned int b); -MP_API int sp_count_bits(sp_int* a); +MP_API int sp_count_bits(const sp_int* a); #if defined(HAVE_ECC) && defined(HAVE_COMP_KEY) MP_API int sp_cnt_lsb(sp_int* a); #endif @@ -795,8 +809,12 @@ MP_API int sp_div_2(sp_int* a, sp_int* r); MP_API int sp_add(sp_int* a, sp_int* b, sp_int* r); MP_API int sp_sub(sp_int* a, sp_int* b, sp_int* r); -#ifdef WOLFSSL_SP_MATH_ALL +#if (defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \ + (!defined(WOLFSSL_SP_MATH) && defined(WOLFSSL_CUSTOM_CURVES)) || \ + defined(WOLFCRYPT_HAVE_ECCSI) || defined(WOLFCRYPT_HAVE_SAKKE) MP_API int sp_addmod(sp_int* a, sp_int* b, sp_int* m, sp_int* r); +#endif +#if defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY) MP_API int sp_submod(sp_int* a, sp_int* b, sp_int* m, sp_int* r); #endif #if defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC) @@ -841,7 +859,7 @@ MP_API int sp_mont_red(sp_int* a, sp_int* m, sp_int_digit mp); MP_API int sp_mont_setup(sp_int* m, sp_int_digit* rho); MP_API int sp_mont_norm(sp_int* norm, sp_int* m); -MP_API int sp_unsigned_bin_size(sp_int* a); +MP_API int sp_unsigned_bin_size(const sp_int* a); MP_API int sp_read_unsigned_bin(sp_int* a, const byte* in, word32 inSz); MP_API int sp_to_unsigned_bin(sp_int* a, byte* out); MP_API int sp_to_unsigned_bin_len(sp_int* a, byte* out, int outSz); diff --git a/wolfssl/wolfcrypt/srp.h b/wolfssl/wolfcrypt/srp.h index bb6aa203a..fcf1f4a84 100644 --- a/wolfssl/wolfcrypt/srp.h +++ b/wolfssl/wolfcrypt/srp.h @@ -1,6 +1,6 @@ /* srp.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/tfm.h b/wolfssl/wolfcrypt/tfm.h index 3f4c43276..c7fae484e 100644 --- a/wolfssl/wolfcrypt/tfm.h +++ b/wolfssl/wolfcrypt/tfm.h @@ -1,6 +1,6 @@ /* tfm.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -443,7 +443,7 @@ int fp_is_bit_set(fp_int *a, fp_digit b); int fp_set_bit (fp_int * a, fp_digit b); /* copy from a to b */ -void fp_copy(fp_int *a, fp_int *b); +void fp_copy(const fp_int *a, fp_int *b); void fp_init_copy(fp_int *a, fp_int *b); /* clamp digits */ @@ -646,10 +646,10 @@ int fp_exptmod_nb(exptModNb_t* nb, fp_int* G, fp_int* X, fp_int* P, fp_int* Y); /*int fp_prime_random_ex(fp_int *a, int t, int size, int flags, tfm_prime_callback cb, void *dat);*/ /* radix conversions */ -int fp_count_bits(fp_int *a); +int fp_count_bits(const fp_int *a); int fp_leading_bit(fp_int *a); -int fp_unsigned_bin_size(fp_int *a); +int fp_unsigned_bin_size(const fp_int *a); int fp_read_unsigned_bin(fp_int *a, const unsigned char *b, int c); int fp_to_unsigned_bin(fp_int *a, unsigned char *b); int fp_to_unsigned_bin_len(fp_int *a, unsigned char *b, int c); @@ -774,17 +774,17 @@ MP_API int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d); MP_API int mp_cmp(mp_int *a, mp_int *b); MP_API int mp_cmp_d(mp_int *a, mp_digit b); -MP_API int mp_unsigned_bin_size(mp_int * a); +MP_API int mp_unsigned_bin_size(const mp_int * a); MP_API int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c); MP_API int mp_to_unsigned_bin_at_pos(int x, mp_int *t, unsigned char *b); MP_API int mp_to_unsigned_bin (mp_int * a, unsigned char *b); MP_API int mp_to_unsigned_bin_len(mp_int * a, unsigned char *b, int c); MP_API int mp_sub_d(fp_int *a, fp_digit b, fp_int *c); -MP_API int mp_copy(fp_int* a, fp_int* b); +MP_API int mp_copy(const fp_int* a, fp_int* b); MP_API int mp_isodd(mp_int* a); MP_API int mp_iszero(mp_int* a); -MP_API int mp_count_bits(mp_int *a); +MP_API int mp_count_bits(const mp_int *a); MP_API int mp_leading_bit(mp_int *a); MP_API int mp_set_int(mp_int *a, unsigned long b); MP_API int mp_is_bit_set (mp_int * a, mp_digit b); diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 7062e79cf..e1d4aa2da 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -1,6 +1,6 @@ /* types.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/visibility.h b/wolfssl/wolfcrypt/visibility.h index 8ed57fb95..25c429464 100644 --- a/wolfssl/wolfcrypt/visibility.h +++ b/wolfssl/wolfcrypt/visibility.h @@ -1,6 +1,6 @@ /* visibility.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/wc_encrypt.h b/wolfssl/wolfcrypt/wc_encrypt.h index 93a8e7c45..56d921507 100644 --- a/wolfssl/wolfcrypt/wc_encrypt.h +++ b/wolfssl/wolfcrypt/wc_encrypt.h @@ -1,6 +1,6 @@ /* wc_encrypt.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/wc_pkcs11.h b/wolfssl/wolfcrypt/wc_pkcs11.h index 39dd5e34c..9cc4f93f8 100644 --- a/wolfssl/wolfcrypt/wc_pkcs11.h +++ b/wolfssl/wolfcrypt/wc_pkcs11.h @@ -1,6 +1,6 @@ /* wc_pkcs11.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 7e09ae386..8a41f4b99 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -1,6 +1,6 @@ /* wc_port.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/wolfevent.h b/wolfssl/wolfcrypt/wolfevent.h index 8370d5e45..639f548a1 100644 --- a/wolfssl/wolfcrypt/wolfevent.h +++ b/wolfssl/wolfcrypt/wolfevent.h @@ -1,6 +1,6 @@ /* wolfevent.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wolfssl/wolfcrypt/wolfmath.h b/wolfssl/wolfcrypt/wolfmath.h index 68814d3de..20ca975fe 100644 --- a/wolfssl/wolfcrypt/wolfmath.h +++ b/wolfssl/wolfcrypt/wolfmath.h @@ -1,6 +1,6 @@ /* wolfmath.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -55,8 +55,8 @@ This library provides big integer math functions. /* common math functions */ -MP_API int get_digit_count(mp_int* a); -MP_API mp_digit get_digit(mp_int* a, int n); +MP_API int get_digit_count(const mp_int* a); +MP_API mp_digit get_digit(const mp_int* a, int n); MP_API int get_rand_digit(WC_RNG* rng, mp_digit* d); WOLFSSL_API int mp_cond_copy(mp_int* a, int copy, mp_int* b); diff --git a/wolfssl/wolfio.h b/wolfssl/wolfio.h index 77fcf83ff..c92f44b31 100644 --- a/wolfssl/wolfio.h +++ b/wolfssl/wolfio.h @@ -1,6 +1,6 @@ /* io.h * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wrapper/CSharp/wolfSSL-DTLS-PSK-Server/wolfSSL-DTLS-PSK-Server.cs b/wrapper/CSharp/wolfSSL-DTLS-PSK-Server/wolfSSL-DTLS-PSK-Server.cs index 269603045..8e94c4ea5 100644 --- a/wrapper/CSharp/wolfSSL-DTLS-PSK-Server/wolfSSL-DTLS-PSK-Server.cs +++ b/wrapper/CSharp/wolfSSL-DTLS-PSK-Server/wolfSSL-DTLS-PSK-Server.cs @@ -1,6 +1,6 @@ /* wolfSSL-DTLS-PSK-Server.cs * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ + using System; diff --git a/wrapper/CSharp/wolfSSL-DTLS-Server/wolfSSL-DTLS-Server.cs b/wrapper/CSharp/wolfSSL-DTLS-Server/wolfSSL-DTLS-Server.cs index c7cdd43a7..1116ba874 100644 --- a/wrapper/CSharp/wolfSSL-DTLS-Server/wolfSSL-DTLS-Server.cs +++ b/wrapper/CSharp/wolfSSL-DTLS-Server/wolfSSL-DTLS-Server.cs @@ -1,6 +1,6 @@ /* wolfSSL-DTLS-Server.cs * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ + using System; using System.Runtime.InteropServices; diff --git a/wrapper/CSharp/wolfSSL-Example-IOCallbacks/wolfSSL-Example-IOCallbacks.cs b/wrapper/CSharp/wolfSSL-Example-IOCallbacks/wolfSSL-Example-IOCallbacks.cs index 8f0e0e27f..aaeb31a72 100644 --- a/wrapper/CSharp/wolfSSL-Example-IOCallbacks/wolfSSL-Example-IOCallbacks.cs +++ b/wrapper/CSharp/wolfSSL-Example-IOCallbacks/wolfSSL-Example-IOCallbacks.cs @@ -1,6 +1,6 @@ /* wolfSSL-Example-IOCallbacks.cs * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -18,6 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ + using System; diff --git a/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.cs b/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.cs index dcba3568e..dccdc4d3f 100644 --- a/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.cs +++ b/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.cs @@ -1,6 +1,6 @@ /* wolfSSL-TLS-Client.cs * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wrapper/CSharp/wolfSSL-TLS-PSK-Server/wolfSSL-TLS-PSK-Server.cs b/wrapper/CSharp/wolfSSL-TLS-PSK-Server/wolfSSL-TLS-PSK-Server.cs index e8697062a..ff6ce7316 100644 --- a/wrapper/CSharp/wolfSSL-TLS-PSK-Server/wolfSSL-TLS-PSK-Server.cs +++ b/wrapper/CSharp/wolfSSL-TLS-PSK-Server/wolfSSL-TLS-PSK-Server.cs @@ -1,6 +1,6 @@ /* wolfSSL-TLS-PSK-Server.cs * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -18,6 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ + using System; diff --git a/wrapper/CSharp/wolfSSL-TLS-Server/wolfSSL-TLS-Server.cs b/wrapper/CSharp/wolfSSL-TLS-Server/wolfSSL-TLS-Server.cs index 262bd74be..487f7815e 100644 --- a/wrapper/CSharp/wolfSSL-TLS-Server/wolfSSL-TLS-Server.cs +++ b/wrapper/CSharp/wolfSSL-TLS-Server/wolfSSL-TLS-Server.cs @@ -1,6 +1,6 @@ /* wolfSSL-TLS-Server.cs * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -18,6 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ + using System; diff --git a/wrapper/CSharp/wolfSSL-TLS-ServerThreaded/wolfSSL-TLS-ServerThreaded.cs b/wrapper/CSharp/wolfSSL-TLS-ServerThreaded/wolfSSL-TLS-ServerThreaded.cs index 2f9da4e24..a7540508a 100644 --- a/wrapper/CSharp/wolfSSL-TLS-ServerThreaded/wolfSSL-TLS-ServerThreaded.cs +++ b/wrapper/CSharp/wolfSSL-TLS-ServerThreaded/wolfSSL-TLS-ServerThreaded.cs @@ -1,6 +1,6 @@ /* wolfSSL-TLS-ServerThreaded.cs * - * Copyright (C) 2006-2020 wolfSSL Inc. + * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs b/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs index 9947d9b9d..a2019cadb 100644 --- a/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs +++ b/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs @@ -1,23 +1,23 @@ /* wolfSSL.cs * - * Copyright (C) 2006-2020 wolfSSL Inc. - * - * This file is part of wolfSSL. - * - * wolfSSL 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. - * - * wolfSSL 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA - */ + * Copyright (C) 2006-2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL 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. + * + * wolfSSL 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ using System; using System.Runtime.InteropServices; diff --git a/wrapper/python/wolfcrypt/setup.py b/wrapper/python/wolfcrypt/setup.py index c22149a58..b16e02366 100755 --- a/wrapper/python/wolfcrypt/setup.py +++ b/wrapper/python/wolfcrypt/setup.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -19,6 +19,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ # Python 2.7 Standard Library from __future__ import absolute_import diff --git a/wrapper/python/wolfcrypt/test/test_ciphers.py b/wrapper/python/wolfcrypt/test/test_ciphers.py index 24ccb897b..bab8820d6 100644 --- a/wrapper/python/wolfcrypt/test/test_ciphers.py +++ b/wrapper/python/wolfcrypt/test/test_ciphers.py @@ -1,6 +1,6 @@ # test_ciphers.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -18,6 +18,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ import unittest from wolfcrypt.ciphers import * from wolfcrypt.utils import t2b, h2b diff --git a/wrapper/python/wolfcrypt/test/test_hashes.py b/wrapper/python/wolfcrypt/test/test_hashes.py index b9f2ccc20..e926f1b30 100644 --- a/wrapper/python/wolfcrypt/test/test_hashes.py +++ b/wrapper/python/wolfcrypt/test/test_hashes.py @@ -1,6 +1,6 @@ # test_hashes.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -18,6 +18,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ import unittest from wolfcrypt.hashes import * from wolfcrypt.utils import t2b, h2b diff --git a/wrapper/python/wolfcrypt/test/test_random.py b/wrapper/python/wolfcrypt/test/test_random.py index 1425f370c..964ffb5c3 100644 --- a/wrapper/python/wolfcrypt/test/test_random.py +++ b/wrapper/python/wolfcrypt/test/test_random.py @@ -1,6 +1,6 @@ # test_random.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -18,6 +18,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ import unittest from wolfcrypt.random import * diff --git a/wrapper/python/wolfcrypt/wolfcrypt/__about__.py b/wrapper/python/wolfcrypt/wolfcrypt/__about__.py index d3c58086d..d591779da 100644 --- a/wrapper/python/wolfcrypt/wolfcrypt/__about__.py +++ b/wrapper/python/wolfcrypt/wolfcrypt/__about__.py @@ -1,6 +1,6 @@ # __about__.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -18,6 +18,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ metadata = dict( __name__ = "wolfcrypt", diff --git a/wrapper/python/wolfcrypt/wolfcrypt/__init__.py b/wrapper/python/wolfcrypt/wolfcrypt/__init__.py index 31d0235ef..33f5045fc 100644 --- a/wrapper/python/wolfcrypt/wolfcrypt/__init__.py +++ b/wrapper/python/wolfcrypt/wolfcrypt/__init__.py @@ -1,6 +1,6 @@ # __init__.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -18,5 +18,6 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ from .__about__ import * diff --git a/wrapper/python/wolfcrypt/wolfcrypt/build_ffi.py b/wrapper/python/wolfcrypt/wolfcrypt/build_ffi.py index ac03955cc..4787c07e1 100644 --- a/wrapper/python/wolfcrypt/wolfcrypt/build_ffi.py +++ b/wrapper/python/wolfcrypt/wolfcrypt/build_ffi.py @@ -1,6 +1,6 @@ # build_ffi.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -18,6 +18,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ import os from cffi import FFI diff --git a/wrapper/python/wolfcrypt/wolfcrypt/ciphers.py b/wrapper/python/wolfcrypt/wolfcrypt/ciphers.py index c02cdbe33..187d44c7d 100644 --- a/wrapper/python/wolfcrypt/wolfcrypt/ciphers.py +++ b/wrapper/python/wolfcrypt/wolfcrypt/ciphers.py @@ -1,6 +1,6 @@ # ciphers.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -18,6 +18,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ from wolfcrypt._ffi import ffi as _ffi from wolfcrypt._ffi import lib as _lib from wolfcrypt.utils import t2b diff --git a/wrapper/python/wolfcrypt/wolfcrypt/exceptions.py b/wrapper/python/wolfcrypt/wolfcrypt/exceptions.py index 26322b364..e1857c9cb 100644 --- a/wrapper/python/wolfcrypt/wolfcrypt/exceptions.py +++ b/wrapper/python/wolfcrypt/wolfcrypt/exceptions.py @@ -1,6 +1,6 @@ # exceptions.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -18,6 +18,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ class WolfCryptError(Exception): diff --git a/wrapper/python/wolfcrypt/wolfcrypt/hashes.py b/wrapper/python/wolfcrypt/wolfcrypt/hashes.py index 346cb7bc0..217f0eac5 100644 --- a/wrapper/python/wolfcrypt/wolfcrypt/hashes.py +++ b/wrapper/python/wolfcrypt/wolfcrypt/hashes.py @@ -1,6 +1,6 @@ # hashes.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -18,6 +18,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ from wolfcrypt._ffi import ffi as _ffi from wolfcrypt._ffi import lib as _lib from wolfcrypt.utils import t2b, b2h diff --git a/wrapper/python/wolfcrypt/wolfcrypt/random.py b/wrapper/python/wolfcrypt/wolfcrypt/random.py index f32b9b77c..fd6148929 100644 --- a/wrapper/python/wolfcrypt/wolfcrypt/random.py +++ b/wrapper/python/wolfcrypt/wolfcrypt/random.py @@ -1,6 +1,6 @@ # random.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -18,6 +18,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ from wolfcrypt._ffi import ffi as _ffi from wolfcrypt._ffi import lib as _lib from wolfcrypt.utils import t2b diff --git a/wrapper/python/wolfcrypt/wolfcrypt/utils.py b/wrapper/python/wolfcrypt/wolfcrypt/utils.py index 537800f4c..22abab1a2 100644 --- a/wrapper/python/wolfcrypt/wolfcrypt/utils.py +++ b/wrapper/python/wolfcrypt/wolfcrypt/utils.py @@ -1,6 +1,6 @@ # utils.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -18,6 +18,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ # pylint: disable=unused-import, undefined-variable diff --git a/wrapper/python/wolfssl/Makefile b/wrapper/python/wolfssl/Makefile index 5b3f9f869..ce5f691c1 100644 --- a/wrapper/python/wolfssl/Makefile +++ b/wrapper/python/wolfssl/Makefile @@ -1,6 +1,6 @@ # Makefile # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -18,6 +18,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ .PHONY : all clean clean-test clean-build clean-pyc install test check upload diff --git a/wrapper/python/wolfssl/docs/Makefile b/wrapper/python/wolfssl/docs/Makefile index 7d24fb014..2a71ed6e6 100644 --- a/wrapper/python/wolfssl/docs/Makefile +++ b/wrapper/python/wolfssl/docs/Makefile @@ -1,6 +1,6 @@ # Makefile # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -18,6 +18,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ .PHONY : all clean html pdf man diff --git a/wrapper/python/wolfssl/examples/client.py b/wrapper/python/wolfssl/examples/client.py index 0ae7d57ce..68dea10d6 100755 --- a/wrapper/python/wolfssl/examples/client.py +++ b/wrapper/python/wolfssl/examples/client.py @@ -4,7 +4,7 @@ # # client.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -22,6 +22,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ # pylint: disable=missing-docstring, invalid-name, import-error diff --git a/wrapper/python/wolfssl/examples/server.py b/wrapper/python/wolfssl/examples/server.py index a44b7e116..9e0fdf79e 100755 --- a/wrapper/python/wolfssl/examples/server.py +++ b/wrapper/python/wolfssl/examples/server.py @@ -4,7 +4,7 @@ # # server.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -22,6 +22,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ # pylint: disable=missing-docstring, invalid-name, import-error diff --git a/wrapper/python/wolfssl/setup.py b/wrapper/python/wolfssl/setup.py index 217b59700..1eba44b63 100755 --- a/wrapper/python/wolfssl/setup.py +++ b/wrapper/python/wolfssl/setup.py @@ -3,7 +3,7 @@ # # setup.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -21,6 +21,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ # Python 2.7 Standard Library diff --git a/wrapper/python/wolfssl/src/wolfssl/__about__.py b/wrapper/python/wolfssl/src/wolfssl/__about__.py index 35b983ab7..b4b69d808 100644 --- a/wrapper/python/wolfssl/src/wolfssl/__about__.py +++ b/wrapper/python/wolfssl/src/wolfssl/__about__.py @@ -2,7 +2,7 @@ # # __about__.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -20,6 +20,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ # pylint: disable=missing-docstring diff --git a/wrapper/python/wolfssl/src/wolfssl/__init__.py b/wrapper/python/wolfssl/src/wolfssl/__init__.py index decef9595..e66d6cd73 100644 --- a/wrapper/python/wolfssl/src/wolfssl/__init__.py +++ b/wrapper/python/wolfssl/src/wolfssl/__init__.py @@ -2,7 +2,7 @@ # # __init__.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -20,6 +20,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ import sys import errno diff --git a/wrapper/python/wolfssl/src/wolfssl/_memory.py b/wrapper/python/wolfssl/src/wolfssl/_memory.py index 0b6bb9f82..f3af7b8b7 100644 --- a/wrapper/python/wolfssl/src/wolfssl/_memory.py +++ b/wrapper/python/wolfssl/src/wolfssl/_memory.py @@ -2,7 +2,7 @@ # # _memory.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -20,6 +20,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ # pylint: disable=missing-docstring diff --git a/wrapper/python/wolfssl/src/wolfssl/_methods.py b/wrapper/python/wolfssl/src/wolfssl/_methods.py index bde5eb1bf..a119939aa 100644 --- a/wrapper/python/wolfssl/src/wolfssl/_methods.py +++ b/wrapper/python/wolfssl/src/wolfssl/_methods.py @@ -2,7 +2,7 @@ # # _methods.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -20,6 +20,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ # pylint: disable=missing-docstring, invalid-name diff --git a/wrapper/python/wolfssl/src/wolfssl/build_ffi.py b/wrapper/python/wolfssl/src/wolfssl/build_ffi.py index acfe013da..eac1b2709 100644 --- a/wrapper/python/wolfssl/src/wolfssl/build_ffi.py +++ b/wrapper/python/wolfssl/src/wolfssl/build_ffi.py @@ -2,7 +2,7 @@ # # build_ffi.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -20,6 +20,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ # pylint: disable=missing-docstring, invalid-name diff --git a/wrapper/python/wolfssl/src/wolfssl/exceptions.py b/wrapper/python/wolfssl/src/wolfssl/exceptions.py index 748732254..f031e86a5 100644 --- a/wrapper/python/wolfssl/src/wolfssl/exceptions.py +++ b/wrapper/python/wolfssl/src/wolfssl/exceptions.py @@ -2,7 +2,7 @@ # # exceptions.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -20,6 +20,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ # pylint: disable=missing-docstring diff --git a/wrapper/python/wolfssl/src/wolfssl/utils.py b/wrapper/python/wolfssl/src/wolfssl/utils.py index 721f2b96f..d7c2e9642 100644 --- a/wrapper/python/wolfssl/src/wolfssl/utils.py +++ b/wrapper/python/wolfssl/src/wolfssl/utils.py @@ -2,7 +2,7 @@ # # utils.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -20,6 +20,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ # pylint: disable=missing-docstring, unused-import, undefined-variable diff --git a/wrapper/python/wolfssl/test/conftest.py b/wrapper/python/wolfssl/test/conftest.py index d87164325..84fcb88d2 100644 --- a/wrapper/python/wolfssl/test/conftest.py +++ b/wrapper/python/wolfssl/test/conftest.py @@ -2,7 +2,7 @@ # # conftest.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -20,6 +20,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ # pylint: disable=missing-docstring, redefined-outer-name diff --git a/wrapper/python/wolfssl/test/test_client.py b/wrapper/python/wolfssl/test/test_client.py index 7ebf91fee..e67fbe691 100644 --- a/wrapper/python/wolfssl/test/test_client.py +++ b/wrapper/python/wolfssl/test/test_client.py @@ -2,7 +2,7 @@ # # test_client.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -20,6 +20,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ # pylint: disable=missing-docstring, invalid-name, import-error # pylint: disable=redefined-outer-name diff --git a/wrapper/python/wolfssl/test/test_context.py b/wrapper/python/wolfssl/test/test_context.py index 6575ed6da..0769419bd 100644 --- a/wrapper/python/wolfssl/test/test_context.py +++ b/wrapper/python/wolfssl/test/test_context.py @@ -2,7 +2,7 @@ # # test_context.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -20,6 +20,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ # pylint: disable=missing-docstring, invalid-name, import-error # pylint: disable=redefined-outer-name diff --git a/wrapper/python/wolfssl/test/test_methods.py b/wrapper/python/wolfssl/test/test_methods.py index f94038341..339b12841 100644 --- a/wrapper/python/wolfssl/test/test_methods.py +++ b/wrapper/python/wolfssl/test/test_methods.py @@ -2,7 +2,7 @@ # # test_methods.py # -# Copyright (C) 2006-2020 wolfSSL Inc. +# Copyright (C) 2006-2021 wolfSSL Inc. # # This file is part of wolfSSL. # @@ -20,6 +20,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA #/ +#/ # pylint: disable=missing-docstring, redefined-outer-name, import-error